[freeimage] 01/01: Imported Upstream version 3.17.0

Ghislain Vaillant ghisvail-guest at moszumanska.debian.org
Sat Sep 26 22:28:15 UTC 2015


This is an automated email from the git hooks/post-receive script.

ghisvail-guest pushed a commit to annotated tag upstream/3.17.0
in repository freeimage.

commit ef7729b699a74a88137b50f2f9414e60c9722765
Author: Scott Howard <showard314 at gmail.com>
Date:   Sun Sep 13 20:58:54 2015 -0400

    Imported Upstream version 3.17.0
---
 FreeImage.2003.sln                                 |   106 -
 FreeImage.2003.vcproj                              |   504 -
 FreeImage.2005.sln                                 |    71 +-
 FreeImage.2005.vcproj                              |    32 +-
 FreeImage.2008.sln                                 |    24 +
 FreeImage.2008.vcproj                              |    36 +-
 FreeImage.2013.sln                                 |   133 +
 FreeImage.2013.vcxproj                             |   460 +
 FreeImage.2013.vcxproj.filters                     |   365 +
 FreeImage.rc                                       |    63 +-
 Makefile.cygwin                                    |   147 +-
 Makefile.fip                                       |   157 +-
 Makefile.gnu                                       |   157 +-
 Makefile.iphone                                    |   189 +-
 Makefile.mingw                                     |   272 +-
 Makefile.osx                                       |   229 +-
 Makefile.solaris                                   |   131 +-
 Makefile.srcs                                      |     8 +-
 README.iphone                                      |     8 +
 Source/FreeImage.h                                 |  2257 +-
 Source/FreeImage/BitmapAccess.cpp                  |  2840 +-
 Source/FreeImage/ColorLookup.cpp                   |   337 +-
 Source/FreeImage/Conversion.cpp                    |    66 +-
 Source/FreeImage/Conversion24.cpp                  |   504 +-
 Source/FreeImage/Conversion32.cpp                  |   690 +-
 Source/FreeImage/Conversion8.cpp                   |   610 +-
 Source/FreeImage/ConversionFloat.cpp               |   386 +-
 Source/FreeImage/ConversionRGB16.cpp               |   288 +-
 Source/FreeImage/ConversionRGBA16.cpp              |   147 +
 Source/FreeImage/ConversionRGBAF.cpp               |   250 +
 Source/FreeImage/ConversionRGBF.cpp                |   484 +-
 Source/FreeImage/ConversionType.cpp                |    10 +
 Source/FreeImage/ConversionUINT16.cpp              |   268 +-
 Source/FreeImage/FreeImageIO.cpp                   |    49 +-
 Source/FreeImage/J2KHelper.cpp                     |  1091 +-
 Source/FreeImage/J2KHelper.h                       |    36 +
 Source/FreeImage/LFPQuantizer.cpp                  |   208 +
 Source/FreeImage/MNGHelper.cpp                     |    27 +-
 Source/FreeImage/MemoryIO.cpp                      |     4 +-
 Source/FreeImage/MultiPage.cpp                     |  1948 +-
 Source/FreeImage/PSDParser.cpp                     |     4 +
 Source/FreeImage/PixelAccess.cpp                   |   407 +-
 Source/FreeImage/Plugin.cpp                        |    23 +-
 Source/FreeImage/PluginBMP.cpp                     |   118 +-
 Source/FreeImage/PluginEXR.cpp                     |   111 +-
 Source/FreeImage/PluginG3.cpp                      |     2 +-
 Source/FreeImage/PluginGIF.cpp                     |    17 +-
 Source/FreeImage/PluginHDR.cpp                     |     5 +-
 Source/FreeImage/PluginICO.cpp                     |    27 +-
 Source/FreeImage/PluginJ2K.cpp                     |   667 +-
 Source/FreeImage/PluginJP2.cpp                     |   667 +-
 Source/FreeImage/PluginJPEG.cpp                    |   102 +-
 Source/FreeImage/PluginJXR.cpp                     |  1475 +
 Source/FreeImage/PluginPFM.cpp                     |    31 +-
 Source/FreeImage/PluginPICT.cpp                    |    19 +-
 Source/FreeImage/PluginPNG.cpp                     |   444 +-
 Source/FreeImage/PluginPNM.cpp                     |    31 +-
 Source/FreeImage/PluginRAW.cpp                     |   250 +-
 Source/FreeImage/PluginSGI.cpp                     |     2 +-
 Source/FreeImage/PluginTARGA.cpp                   |   140 +-
 Source/FreeImage/PluginTIFF.cpp                    |    70 +-
 Source/FreeImage/PluginWebP.cpp                    |   698 +
 Source/FreeImage/WuQuantizer.cpp                   |    53 +-
 Source/FreeImage/tmoColorConvert.cpp               |   958 +-
 Source/FreeImage/tmoDrago03.cpp                    |   590 +-
 Source/FreeImage/tmoFattal02.cpp                   |  1378 +-
 Source/FreeImageIO.h                               |    31 +-
 Source/FreeImageLib/FreeImageLib.2003.vcproj       |   473 -
 Source/FreeImageLib/FreeImageLib.2005.vcproj       |    32 +-
 Source/FreeImageLib/FreeImageLib.2008.vcproj       |    32 +-
 Source/FreeImageLib/FreeImageLib.2013.vcxproj      |   394 +
 .../FreeImageLib/FreeImageLib.2013.vcxproj.filters |   353 +
 Source/FreeImageToolkit/CopyPaste.cpp              |   116 +-
 Source/FreeImageToolkit/JPEGTransform.cpp          |   551 +-
 Source/FreeImageToolkit/Rescale.cpp                |   361 +-
 Source/FreeImageToolkit/Resize.cpp                 |  4108 +-
 Source/FreeImageToolkit/Resize.h                   |   391 +-
 Source/LibJPEG/LibJPEG.2003.vcproj                 |   306 -
 Source/LibJPEG/LibJPEG.2013.vcxproj                |   258 +
 Source/LibJPEG/LibJPEG.2013.vcxproj.filters        |   188 +
 Source/LibJPEG/README                              |   106 +-
 Source/LibJPEG/change.log                          |    63 +
 Source/LibJPEG/cjpeg.c                             |    29 +-
 Source/LibJPEG/djpeg.c                             |     6 +-
 Source/LibJPEG/filelist.txt                        |     6 +-
 Source/LibJPEG/install.txt                         |    72 +-
 Source/LibJPEG/jcapistd.c                          |     3 +-
 Source/LibJPEG/jcarith.c                           |    61 +-
 Source/LibJPEG/jccolor.c                           |   214 +-
 Source/LibJPEG/jcdctmgr.c                          |    79 +-
 Source/LibJPEG/jchuff.c                            |   119 +-
 Source/LibJPEG/jcinit.c                            |    19 +
 Source/LibJPEG/jcmainct.c                          |   110 +-
 Source/LibJPEG/jcmarker.c                          |    69 +-
 Source/LibJPEG/jcmaster.c                          |    36 +-
 Source/LibJPEG/jconfig.h                           |   130 +-
 Source/LibJPEG/jconfig.txt                         |     9 +-
 Source/LibJPEG/jcparam.c                           |   115 +-
 Source/LibJPEG/jctrans.c                           |    13 +-
 Source/LibJPEG/jdapimin.c                          |    43 +-
 Source/LibJPEG/jdapistd.c                          |     1 +
 Source/LibJPEG/jdarith.c                           |    52 +-
 Source/LibJPEG/jdatadst.c                          |     3 +
 Source/LibJPEG/jdcolor.c                           |   348 +-
 Source/LibJPEG/jddctmgr.c                          |     4 +-
 Source/LibJPEG/jdhuff.c                            |    69 +-
 Source/LibJPEG/jdinput.c                           |    11 +-
 Source/LibJPEG/jdmainct.c                          |   129 +-
 Source/LibJPEG/jdmarker.c                          |   179 +-
 Source/LibJPEG/jdmaster.c                          |    18 +-
 Source/LibJPEG/jdmerge.c                           |    17 +-
 Source/LibJPEG/jerror.c                            |     3 +-
 Source/LibJPEG/jerror.h                            |     4 +-
 Source/LibJPEG/jfdctint.c                          |   622 +-
 Source/LibJPEG/jidctint.c                          |   356 +-
 Source/LibJPEG/jmemmgr.c                           |     4 +-
 Source/LibJPEG/jmorecfg.h                          |   101 +-
 Source/LibJPEG/jpegint.h                           |     6 +-
 Source/LibJPEG/jpeglib.h                           |    54 +-
 Source/LibJPEG/jpegtran.c                          |    25 +-
 Source/LibJPEG/jversion.h                          |     6 +-
 Source/LibJPEG/libjpeg.txt                         |   146 +-
 Source/LibJPEG/structure.txt                       |    33 +-
 Source/LibJPEG/transupp.c                          |   232 +-
 Source/LibJPEG/transupp.h                          |    22 +-
 Source/LibJPEG/usage.txt                           |    64 +-
 Source/LibJXR/LICENCE                              |     9 +
 Source/LibJXR/LibJXR.2005.vcproj                   |   398 +
 Source/LibJXR/LibJXR.2008.vcproj                   |   514 +
 Source/LibJXR/LibJXR.2013.vcxproj                  |   205 +
 Source/LibJXR/LibJXR.2013.vcxproj.filters          |   176 +
 Source/LibJXR/README                               |     1 +
 Source/LibJXR/common/include/guiddef.h             |   230 +
 Source/LibJXR/common/include/wmsal.h               |   757 +
 Source/LibJXR/common/include/wmspecstring.h        |   342 +
 Source/LibJXR/common/include/wmspecstrings_adt.h   |    71 +
 .../LibJXR/common/include/wmspecstrings_strict.h   |  1096 +
 Source/LibJXR/common/include/wmspecstrings_undef.h |   406 +
 Source/LibJXR/image/decode/JXRTranscode.c          |   987 +
 Source/LibJXR/image/decode/decode.c                |   200 +
 Source/LibJXR/image/decode/decode.h                |   143 +
 Source/LibJXR/image/decode/postprocess.c           |   288 +
 Source/LibJXR/image/decode/segdec.c                |  1205 +
 Source/LibJXR/image/decode/strInvTransform.c       |  1888 +
 Source/LibJXR/image/decode/strPredQuantDec.c       |   539 +
 Source/LibJXR/image/decode/strdec.c                |  3628 +
 Source/LibJXR/image/decode/strdec_x86.c            |  1640 +
 Source/LibJXR/image/encode/encode.c                |   144 +
 Source/LibJXR/image/encode/encode.h                |   113 +
 Source/LibJXR/image/encode/segenc.c                |  1186 +
 Source/LibJXR/image/encode/strFwdTransform.c       |  1111 +
 Source/LibJXR/image/encode/strPredQuantEnc.c       |   511 +
 Source/LibJXR/image/encode/strenc.c                |  2370 +
 Source/LibJXR/image/encode/strenc_x86.c            |   409 +
 Source/LibJXR/image/sys/adapthuff.c                |   511 +
 Source/LibJXR/image/sys/ansi.h                     |    61 +
 Source/LibJXR/image/sys/common.h                   |   131 +
 Source/LibJXR/image/sys/image.c                    |   183 +
 Source/LibJXR/image/sys/perfTimer.h                |   115 +
 Source/LibJXR/image/sys/perfTimerANSI.c            |   274 +
 Source/LibJXR/image/sys/strPredQuant.c             |   306 +
 Source/LibJXR/image/sys/strTransform.c             |    85 +
 Source/LibJXR/image/sys/strTransform.h             |    50 +
 Source/LibJXR/image/sys/strcodec.c                 |  1251 +
 Source/LibJXR/image/sys/strcodec.h                 |   681 +
 Source/LibJXR/image/sys/windowsmediaphoto.h        |   515 +
 Source/LibJXR/image/sys/xplatform_image.h          |    84 +
 Source/LibJXR/image/x86/x86.h                      |    58 +
 Source/LibJXR/jxrgluelib/JXRGlue.c                 |   930 +
 Source/LibJXR/jxrgluelib/JXRGlue.h                 |   636 +
 Source/LibJXR/jxrgluelib/JXRGlueJxr.c              |  2246 +
 Source/LibJXR/jxrgluelib/JXRGluePFC.c              |  2338 +
 Source/LibJXR/jxrgluelib/JXRMeta.c                 |   905 +
 Source/LibJXR/jxrgluelib/JXRMeta.h                 |   258 +
 Source/LibMNG/Changes                              |  1447 -
 Source/LibMNG/LICENSE                              |    57 -
 Source/LibMNG/LibMNG.2003.vcproj                   |   520 -
 Source/LibMNG/LibMNG.2005.vcproj                   |   509 -
 Source/LibMNG/LibMNG.2008.vcproj                   |   510 -
 Source/LibMNG/README                               |    36 -
 Source/LibMNG/README.autoconf                      |   213 -
 Source/LibMNG/README.config                        |   104 -
 Source/LibMNG/README.contrib                       |    95 -
 Source/LibMNG/README.examples                      |    48 -
 Source/LibMNG/README.footprint                     |    46 -
 Source/LibMNG/README.packaging                     |    24 -
 Source/LibMNG/_FI_3151_PluginMNG.cpp               |   312 -
 Source/LibMNG/libmng.h                             |  2932 -
 Source/LibMNG/libmng_callback_xs.c                 |  1239 -
 Source/LibMNG/libmng_chunk_descr.c                 |  6090 --
 Source/LibMNG/libmng_chunk_descr.h                 |   146 -
 Source/LibMNG/libmng_chunk_io.c                    | 10740 --
 Source/LibMNG/libmng_chunk_io.h                    |   415 -
 Source/LibMNG/libmng_chunk_prc.c                   |  4452 -
 Source/LibMNG/libmng_chunk_prc.h                   |   381 -
 Source/LibMNG/libmng_chunk_xs.c                    |  7016 --
 Source/LibMNG/libmng_chunks.h                      |  1026 -
 Source/LibMNG/libmng_cms.c                         |   758 -
 Source/LibMNG/libmng_cms.h                         |    92 -
 Source/LibMNG/libmng_conf.h                        |   306 -
 Source/LibMNG/libmng_data.h                        |  1029 -
 Source/LibMNG/libmng_display.c                     |  7135 --
 Source/LibMNG/libmng_display.h                     |   343 -
 Source/LibMNG/libmng_dither.c                      |    58 -
 Source/LibMNG/libmng_dither.h                      |    45 -
 Source/LibMNG/libmng_error.c                       |   326 -
 Source/LibMNG/libmng_error.h                       |   119 -
 Source/LibMNG/libmng_filter.c                      |   978 -
 Source/LibMNG/libmng_filter.h                      |    69 -
 Source/LibMNG/libmng_hlapi.c                       |  2995 -
 Source/LibMNG/libmng_jpeg.c                        |  1088 -
 Source/LibMNG/libmng_jpeg.h                        |    57 -
 Source/LibMNG/libmng_memory.h                      |    64 -
 Source/LibMNG/libmng_object_prc.c                  |  6998 --
 Source/LibMNG/libmng_object_prc.h                  |   690 -
 Source/LibMNG/libmng_objects.h                     |   635 -
 Source/LibMNG/libmng_pixels.c                      | 24610 -----
 Source/LibMNG/libmng_pixels.h                      |  1147 -
 Source/LibMNG/libmng_prop_xs.c                     |  2799 -
 Source/LibMNG/libmng_read.c                        |  1369 -
 Source/LibMNG/libmng_read.h                        |    53 -
 Source/LibMNG/libmng_trace.c                       |  1683 -
 Source/LibMNG/libmng_trace.h                       |  1474 -
 Source/LibMNG/libmng_types.h                       |   574 -
 Source/LibMNG/libmng_write.c                       |   198 -
 Source/LibMNG/libmng_write.h                       |    49 -
 Source/LibMNG/libmng_zlib.c                        |   607 -
 Source/LibMNG/libmng_zlib.h                        |    60 -
 Source/LibOpenJPEG/AUTHORS                         |     2 +
 Source/LibOpenJPEG/CHANGES                         |   425 -
 Source/LibOpenJPEG/INSTALL                         |    73 +-
 Source/LibOpenJPEG/LICENSE                         |     3 +
 Source/LibOpenJPEG/LibOpenJPEG.2003.vcproj         |   558 -
 Source/LibOpenJPEG/LibOpenJPEG.2005.vcproj         |   794 +-
 Source/LibOpenJPEG/LibOpenJPEG.2008.vcproj         |   160 +-
 Source/LibOpenJPEG/LibOpenJPEG.2013.vcxproj        |   360 +
 .../LibOpenJPEG/LibOpenJPEG.2013.vcxproj.filters   |   158 +
 Source/LibOpenJPEG/NEWS                            |    21 +-
 Source/LibOpenJPEG/README                          |    40 +-
 Source/LibOpenJPEG/THANKS                          |     4 +-
 Source/LibOpenJPEG/bio.c                           |   375 +-
 Source/LibOpenJPEG/bio.h                           |   253 +-
 Source/LibOpenJPEG/cidx_manager.c                  |   226 +-
 Source/LibOpenJPEG/cidx_manager.h                  |   124 +-
 Source/LibOpenJPEG/cio.c                           |   835 +-
 Source/LibOpenJPEG/cio.h                           |   486 +-
 Source/LibOpenJPEG/dwt.c                           |  1777 +-
 Source/LibOpenJPEG/dwt.h                           |   229 +-
 Source/LibOpenJPEG/event.c                         |   269 +-
 Source/LibOpenJPEG/event.h                         |   155 +-
 Source/LibOpenJPEG/fix.h                           |    64 -
 Source/LibOpenJPEG/function_list.c                 |   114 +
 Source/LibOpenJPEG/function_list.h                 |   126 +
 Source/LibOpenJPEG/image.c                         |   324 +-
 Source/LibOpenJPEG/image.h                         |   111 +-
 Source/LibOpenJPEG/indexbox_manager.h              |   266 +-
 Source/LibOpenJPEG/int.h                           |   119 -
 Source/LibOpenJPEG/invert.c                        |   289 +
 Source/LibOpenJPEG/invert.h                        |    59 +
 Source/LibOpenJPEG/j2k.c                           | 12854 ++-
 Source/LibOpenJPEG/j2k.h                           |  1284 +-
 Source/LibOpenJPEG/j2k_lib.c                       |    59 -
 Source/LibOpenJPEG/j2k_lib.h                       |    54 -
 Source/LibOpenJPEG/jp2.c                           |  3999 +-
 Source/LibOpenJPEG/jp2.h                           |   724 +-
 Source/LibOpenJPEG/jpt.c                           |   155 -
 Source/LibOpenJPEG/jpt.h                           |    75 -
 Source/LibOpenJPEG/mct.c                           |   509 +-
 Source/LibOpenJPEG/mct.h                           |   247 +-
 Source/LibOpenJPEG/mqc.c                           |  1196 +-
 Source/LibOpenJPEG/mqc.h                           |   401 +-
 Source/LibOpenJPEG/openjpeg.c                      |  1298 +-
 Source/LibOpenJPEG/openjpeg.h                      |  2389 +-
 Source/LibOpenJPEG/opj_clock.c                     |    59 +
 Source/LibOpenJPEG/opj_clock.h                     |    54 +
 Source/LibOpenJPEG/opj_codec.h                     |   160 +
 Source/LibOpenJPEG/opj_config.h                    |    46 +-
 Source/LibOpenJPEG/opj_config_private.h            |    16 +
 Source/LibOpenJPEG/opj_includes.h                  |   315 +-
 Source/LibOpenJPEG/opj_intmath.h                   |   172 +
 Source/LibOpenJPEG/opj_inttypes.h                  |    43 +
 Source/LibOpenJPEG/opj_malloc.h                    |   345 +-
 Source/LibOpenJPEG/opj_stdint.h                    |    47 +
 Source/LibOpenJPEG/phix_manager.c                  |   111 +-
 Source/LibOpenJPEG/pi.c                            |  2833 +-
 Source/LibOpenJPEG/pi.h                            |   338 +-
 Source/LibOpenJPEG/ppix_manager.c                  |   111 +-
 Source/LibOpenJPEG/raw.c                           |   176 +-
 Source/LibOpenJPEG/raw.h                           |   200 +-
 Source/LibOpenJPEG/t1.c                            |  3336 +-
 Source/LibOpenJPEG/t1.h                            |   304 +-
 Source/LibOpenJPEG/t1_generate_luts.c              |    51 +-
 Source/LibOpenJPEG/t1_luts.h                       |    14 +-
 Source/LibOpenJPEG/t2.c                            |  2156 +-
 Source/LibOpenJPEG/t2.h                            |   232 +-
 Source/LibOpenJPEG/tcd.c                           |  3697 +-
 Source/LibOpenJPEG/tcd.h                           |   634 +-
 Source/LibOpenJPEG/tgt.c                           |   544 +-
 Source/LibOpenJPEG/tgt.h                           |   254 +-
 Source/LibOpenJPEG/thix_manager.c                  |   100 +-
 Source/LibOpenJPEG/tpix_manager.c                  |   162 +-
 Source/LibPNG/ANNOUNCE                             |    42 +-
 Source/LibPNG/CHANGES                              |  1377 +-
 Source/LibPNG/CMakeLists.txt                       |   365 +
 Source/LibPNG/INSTALL                              |   309 +-
 Source/LibPNG/LICENSE                              |     6 +-
 Source/LibPNG/LibPNG.2003.vcproj                   |   203 -
 Source/LibPNG/LibPNG.2013.vcxproj                  |   233 +
 Source/LibPNG/LibPNG.2013.vcxproj.filters          |    83 +
 Source/LibPNG/README                               |    63 +-
 Source/LibPNG/TODO                                 |     2 +
 Source/LibPNG/configure                            |     4 +-
 Source/LibPNG/example.c                            |   242 +-
 Source/LibPNG/libpng-manual.txt                    |  1295 +-
 Source/LibPNG/libpng.3                             |  1900 +-
 Source/LibPNG/libpngpf.3                           |    22 +-
 Source/LibPNG/png.5                                |     2 +-
 Source/LibPNG/png.c                                |  7367 +-
 Source/LibPNG/png.h                                |  5956 +-
 Source/LibPNG/pngconf.h                            |  1242 +-
 Source/LibPNG/pngdebug.h                           |   311 +-
 Source/LibPNG/pngerror.c                           |  1648 +-
 Source/LibPNG/pngget.c                             |  2337 +-
 Source/LibPNG/pnginfo.h                            |   529 +-
 Source/LibPNG/pnglibconf.h                         |   191 +-
 Source/LibPNG/pngmem.c                             |   948 +-
 Source/LibPNG/pngpread.c                           |  2483 +-
 Source/LibPNG/pngpriv.h                            |  3619 +-
 Source/LibPNG/pngread.c                            |  5426 +-
 Source/LibPNG/pngrio.c                             |   296 +-
 Source/LibPNG/pngrtran.c                           | 10048 +-
 Source/LibPNG/pngrutil.c                           |  8633 +-
 Source/LibPNG/pngset.c                             |  2922 +-
 Source/LibPNG/pngstruct.h                          |   847 +-
 Source/LibPNG/pngtest.c                            |  1033 +-
 Source/LibPNG/pngtrans.c                           |  1630 +-
 Source/LibPNG/pngwio.c                             |   422 +-
 Source/LibPNG/pngwrite.c                           |  4123 +-
 Source/LibPNG/pngwtran.c                           |  1219 +-
 Source/LibPNG/pngwutil.c                           |  6209 +-
 Source/LibRawLite/COPYRIGHT                        |     7 +-
 Source/LibRawLite/Changelog.txt                    |   341 +-
 Source/LibRawLite/DEVELOPER-NOTES                  |    43 +
 Source/LibRawLite/LibRawLite.2003.vcproj           |   196 -
 Source/LibRawLite/LibRawLite.2005.vcproj           |     4 -
 Source/LibRawLite/LibRawLite.2008.vcproj           |     8 +-
 Source/LibRawLite/LibRawLite.2013.vcxproj          |   203 +
 Source/LibRawLite/LibRawLite.2013.vcxproj.filters  |    81 +
 Source/LibRawLite/dcraw/dcraw.1.html               |   440 +
 Source/LibRawLite/dcraw/dcraw.c                    |  9390 +-
 Source/LibRawLite/internal/aahd_demosaic.cpp       |   706 +
 Source/LibRawLite/internal/dcb_demosaicing.c       |     2 +-
 Source/LibRawLite/internal/dcraw_common.cpp        | 10352 +-
 Source/LibRawLite/internal/dcraw_fileio.cpp        |    30 +-
 Source/LibRawLite/internal/defines.h               |    70 +-
 Source/LibRawLite/internal/demosaic_packs.cpp      |    16 +-
 Source/LibRawLite/internal/dht_demosaic.cpp        |   873 +
 Source/LibRawLite/internal/libraw_bytebuffer.h     |   140 -
 Source/LibRawLite/internal/libraw_internal_funcs.h |    89 +-
 Source/LibRawLite/internal/libraw_x3f.cpp          |  1919 +
 Source/LibRawLite/internal/preprocess.pl           |    99 +
 Source/LibRawLite/internal/var_defines.h           |    16 +-
 Source/LibRawLite/internal/wf_filtering.cpp        |  1950 +
 Source/LibRawLite/libraw/libraw.h                  |    99 +-
 Source/LibRawLite/libraw/libraw_alloc.h            |    12 +-
 Source/LibRawLite/libraw/libraw_const.h            |   117 +-
 Source/LibRawLite/libraw/libraw_datastream.h       |    55 +-
 Source/LibRawLite/libraw/libraw_internal.h         |    27 +-
 Source/LibRawLite/libraw/libraw_types.h            |   288 +-
 Source/LibRawLite/libraw/libraw_version.h          |    10 +-
 Source/LibRawLite/src/libraw_c_api.cpp             |    45 +-
 Source/LibRawLite/src/libraw_cxx.cpp               |  5507 +-
 Source/LibRawLite/src/libraw_datastream.cpp        |   299 +-
 Source/LibTIFF/ChangeLog                           |  4849 -
 Source/LibTIFF/LibTIFF.2003.vcproj                 |   272 -
 Source/LibTIFF/LibTIFF.2005.vcproj                 |   525 -
 Source/LibTIFF/LibTIFF.2008.vcproj                 |   526 -
 Source/LibTIFF/Makefile.am                         |   143 -
 Source/LibTIFF/Makefile.in                         |   884 -
 Source/LibTIFF/SConstruct                          |    73 -
 Source/LibTIFF/_FI_3151_PluginG3.cpp               |   433 -
 Source/LibTIFF/_FI_3151_PluginTIFF.cpp             |  2628 -
 Source/LibTIFF/_FI_3151_XTIFF.cpp                  |   664 -
 Source/LibTIFF/makefile.vc                         |   102 -
 Source/LibTIFF/mkg3states.c                        |   451 -
 Source/LibTIFF/mkspans.c                           |    82 -
 Source/LibTIFF/t4.h                                |   292 -
 Source/LibTIFF/tif_acorn.c                         |   526 -
 Source/LibTIFF/tif_apple.c                         |   281 -
 Source/LibTIFF/tif_atari.c                         |   250 -
 Source/LibTIFF/tif_aux.c                           |   290 -
 Source/LibTIFF/tif_close.c                         |   126 -
 Source/LibTIFF/tif_codec.c                         |   160 -
 Source/LibTIFF/tif_color.c                         |   287 -
 Source/LibTIFF/tif_compress.c                      |   295 -
 Source/LibTIFF/tif_config.h                        |   266 -
 Source/LibTIFF/tif_config.h-vms                    |    46 -
 Source/LibTIFF/tif_config.h.in                     |   309 -
 Source/LibTIFF/tif_config.vc.h                     |    63 -
 Source/LibTIFF/tif_config.wince.h                  |    74 -
 Source/LibTIFF/tif_dir.c                           |  1391 -
 Source/LibTIFF/tif_dir.h                           |   211 -
 Source/LibTIFF/tif_dirinfo.c                       |   884 -
 Source/LibTIFF/tif_dirread.c                       |  2117 -
 Source/LibTIFF/tif_dirwrite.c                      |  1436 -
 Source/LibTIFF/tif_dumpmode.c                      |   126 -
 Source/LibTIFF/tif_error.c                         |    80 -
 Source/LibTIFF/tif_extension.c                     |   118 -
 Source/LibTIFF/tif_fax3.c                          |  1626 -
 Source/LibTIFF/tif_fax3.h                          |   538 -
 Source/LibTIFF/tif_fax3sm.c                        |  1260 -
 Source/LibTIFF/tif_flush.c                         |    74 -
 Source/LibTIFF/tif_getimage.c                      |  2678 -
 Source/LibTIFF/tif_jbig.c                          |   385 -
 Source/LibTIFF/tif_jpeg.c                          |  2078 -
 Source/LibTIFF/tif_luv.c                           |  1629 -
 Source/LibTIFF/tif_lzw.c                           |  1129 -
 Source/LibTIFF/tif_msdos.c                         |   193 -
 Source/LibTIFF/tif_next.c                          |   154 -
 Source/LibTIFF/tif_ojpeg.c                         |  2448 -
 Source/LibTIFF/tif_open.c                          |   695 -
 Source/LibTIFF/tif_packbits.c                      |   300 -
 Source/LibTIFF/tif_pixarlog.c                      |  1371 -
 Source/LibTIFF/tif_predict.c                       |   736 -
 Source/LibTIFF/tif_predict.h                       |    77 -
 Source/LibTIFF/tif_print.c                         |   642 -
 Source/LibTIFF/tif_read.c                          |   750 -
 Source/LibTIFF/tif_stream.cxx                      |   295 -
 Source/LibTIFF/tif_strip.c                         |   366 -
 Source/LibTIFF/tif_swab.c                          |   242 -
 Source/LibTIFF/tif_thunder.c                       |   189 -
 Source/LibTIFF/tif_tile.c                          |   280 -
 Source/LibTIFF/tif_unix.c                          |   300 -
 Source/LibTIFF/tif_version.c                       |    40 -
 Source/LibTIFF/tif_vms.c                           |   595 -
 Source/LibTIFF/tif_warning.c                       |    81 -
 Source/LibTIFF/tif_win3.c                          |   232 -
 Source/LibTIFF/tif_win32.c                         |   408 -
 Source/LibTIFF/tif_wince.c                         |   288 -
 Source/LibTIFF/tif_write.c                         |   718 -
 Source/LibTIFF/tif_zip.c                           |   419 -
 Source/LibTIFF/tiff.h                              |   654 -
 Source/LibTIFF/tiffconf.h-vms                      |    99 -
 Source/LibTIFF/tiffconf.h.in                       |   103 -
 Source/LibTIFF/tiffconf.vc.h                       |   116 -
 Source/LibTIFF/tiffconf.wince.h                    |   136 -
 Source/LibTIFF/tiffio.h                            |   526 -
 Source/LibTIFF/tiffio.hxx                          |    49 -
 Source/LibTIFF/tiffiop.h                           |   353 -
 Source/LibTIFF/tiffvers.h                          |     9 -
 Source/LibTIFF/tiffvers.h.in                       |     9 -
 Source/LibTIFF/uvcode.h                            |   180 -
 Source/LibTIFF4/ChangeLog                          |  1313 +-
 Source/LibTIFF4/LibTIFF4.2003.vcproj               |   279 -
 Source/LibTIFF4/LibTIFF4.2013.vcxproj              |   258 +
 Source/LibTIFF4/LibTIFF4.2013.vcxproj.filters      |   158 +
 Source/LibTIFF4/mkg3states.c                       |     2 +-
 Source/LibTIFF4/mkspans.c                          |     2 +-
 Source/LibTIFF4/t4.h                               |   584 +-
 Source/LibTIFF4/tif_aux.c                          |   716 +-
 Source/LibTIFF4/tif_close.c                        |   280 +-
 Source/LibTIFF4/tif_codec.c                        |   331 +-
 Source/LibTIFF4/tif_color.c                        |   574 +-
 Source/LibTIFF4/tif_compress.c                     |   608 +-
 Source/LibTIFF4/tif_config.h                       |   194 +-
 Source/LibTIFF4/tif_config.h.in                    |     9 +-
 Source/LibTIFF4/tif_config.vc.h                    |   145 +-
 Source/LibTIFF4/tif_config.wince.h                 |   142 +-
 Source/LibTIFF4/tif_dir.c                          |  3359 +-
 Source/LibTIFF4/tif_dir.h                          |   616 +-
 Source/LibTIFF4/tif_dirinfo.c                      |  1916 +-
 Source/LibTIFF4/tif_dirread.c                      | 11253 +--
 Source/LibTIFF4/tif_dirwrite.c                     |  5820 +-
 Source/LibTIFF4/tif_dumpmode.c                     |   286 +-
 Source/LibTIFF4/tif_error.c                        |   160 +-
 Source/LibTIFF4/tif_extension.c                    |   236 +-
 Source/LibTIFF4/tif_fax3.c                         |  3190 +-
 Source/LibTIFF4/tif_fax3.h                         |  1076 +-
 Source/LibTIFF4/tif_fax3sm.c                       |  2520 +-
 Source/LibTIFF4/tif_flush.c                        |   236 +-
 Source/LibTIFF4/tif_getimage.c                     |  5757 +-
 Source/LibTIFF4/tif_jbig.c                         |     2 +-
 Source/LibTIFF4/tif_jpeg.c                         |  4658 +-
 Source/LibTIFF4/tif_luv.c                          |  3366 +-
 Source/LibTIFF4/tif_lzma.c                         |   990 +-
 Source/LibTIFF4/tif_lzw.c                          |  2336 +-
 Source/LibTIFF4/tif_next.c                         |   341 +-
 Source/LibTIFF4/tif_ojpeg.c                        |  4997 +-
 Source/LibTIFF4/tif_open.c                         |  1450 +-
 Source/LibTIFF4/tif_packbits.c                     |   600 +-
 Source/LibTIFF4/tif_pixarlog.c                     |  2868 +-
 Source/LibTIFF4/tif_predict.c                      |  1528 +-
 Source/LibTIFF4/tif_predict.h                      |   154 +-
 Source/LibTIFF4/tif_print.c                        |  1432 +-
 Source/LibTIFF4/tif_read.c                         |  2169 +-
 Source/LibTIFF4/tif_stream.cxx                     |     6 +-
 Source/LibTIFF4/tif_strip.c                        |   766 +-
 Source/LibTIFF4/tif_swab.c                         |   620 +-
 Source/LibTIFF4/tif_thunder.c                      |   414 +-
 Source/LibTIFF4/tif_tile.c                         |   598 +-
 Source/LibTIFF4/tif_unix.c                         |     5 +-
 Source/LibTIFF4/tif_version.c                      |    80 +-
 Source/LibTIFF4/tif_vms.c                          |     5 +-
 Source/LibTIFF4/tif_warning.c                      |   162 +-
 Source/LibTIFF4/tif_win32.c                        |     5 +-
 Source/LibTIFF4/tif_wince.c                        |     2 +-
 Source/LibTIFF4/tif_write.c                        |  1542 +-
 Source/LibTIFF4/tif_zip.c                          |   941 +-
 Source/LibTIFF4/tiff.h                             |  1359 +-
 Source/LibTIFF4/tiffconf.h                         |   344 +-
 Source/LibTIFF4/tiffconf.vc.h                      |   320 +-
 Source/LibTIFF4/tiffconf.wince.h                   |   242 +-
 Source/LibTIFF4/tiffio.h                           |  1114 +-
 Source/LibTIFF4/tiffio.hxx                         |     2 +-
 Source/LibTIFF4/tiffiop.h                          |   734 +-
 Source/LibTIFF4/tiffvers.h                         |    18 +-
 Source/LibTIFF4/uvcode.h                           |   360 +-
 Source/LibWebP/AUTHORS                             |    24 +
 Source/LibWebP/COPYING                             |    30 +
 Source/LibWebP/ChangeLog                           |  2144 +
 Source/LibWebP/LibWebP.2005.vcproj                 |   735 +
 Source/LibWebP/LibWebP.2008.vcproj                 |   883 +
 Source/LibWebP/LibWebP.2013.vcxproj                |   314 +
 Source/LibWebP/LibWebP.2013.vcxproj.filters        |   437 +
 Source/LibWebP/NEWS                                |    96 +
 Source/LibWebP/PATENTS                             |    23 +
 Source/LibWebP/README                              |   612 +
 Source/LibWebP/README.mux                          |   210 +
 Source/LibWebP/src/dec/alphai.h                    |    55 +
 Source/LibWebP/src/dec/dec.alpha.c                 |   167 +
 Source/LibWebP/src/dec/dec.buffer.c                |   249 +
 Source/LibWebP/src/dec/dec.frame.c                 |   827 +
 Source/LibWebP/src/dec/dec.idec.c                  |   857 +
 Source/LibWebP/src/dec/dec.io.c                    |   640 +
 Source/LibWebP/src/dec/dec.quant.c                 |   110 +
 Source/LibWebP/src/dec/dec.tree.c                  |   525 +
 Source/LibWebP/src/dec/dec.vp8.c                   |   663 +
 Source/LibWebP/src/dec/dec.vp8l.c                  |  1584 +
 Source/LibWebP/src/dec/dec.webp.c                  |   834 +
 Source/LibWebP/src/dec/decode_vp8.h                |   185 +
 Source/LibWebP/src/dec/vp8i.h                      |   353 +
 Source/LibWebP/src/dec/vp8li.h                     |   136 +
 Source/LibWebP/src/dec/webpi.h                     |   120 +
 Source/LibWebP/src/demux/demux.demux.c             |   957 +
 Source/LibWebP/src/dsp/dsp.alpha_processing.c      |   377 +
 .../src/dsp/dsp.alpha_processing_mips_dsp_r2.c     |   139 +
 Source/LibWebP/src/dsp/dsp.alpha_processing_sse2.c |   296 +
 Source/LibWebP/src/dsp/dsp.argb.c                  |    68 +
 Source/LibWebP/src/dsp/dsp.argb_mips_dsp_r2.c      |   108 +
 Source/LibWebP/src/dsp/dsp.argb_sse2.c             |    62 +
 Source/LibWebP/src/dsp/dsp.cost.c                  |   412 +
 Source/LibWebP/src/dsp/dsp.cost_mips32.c           |   154 +
 Source/LibWebP/src/dsp/dsp.cost_mips_dsp_r2.c      |   107 +
 Source/LibWebP/src/dsp/dsp.cost_sse2.c             |   121 +
 Source/LibWebP/src/dsp/dsp.cpu.c                   |   138 +
 Source/LibWebP/src/dsp/dsp.dec.c                   |   760 +
 Source/LibWebP/src/dsp/dsp.dec_clip_tables.c       |   366 +
 Source/LibWebP/src/dsp/dsp.dec_mips32.c            |   585 +
 Source/LibWebP/src/dsp/dsp.dec_mips_dsp_r2.c       |   992 +
 Source/LibWebP/src/dsp/dsp.dec_neon.c              |  1489 +
 Source/LibWebP/src/dsp/dsp.dec_sse2.c              |  1284 +
 Source/LibWebP/src/dsp/dsp.enc.c                   |   788 +
 Source/LibWebP/src/dsp/dsp.enc_avx2.c              |    24 +
 Source/LibWebP/src/dsp/dsp.enc_mips32.c            |   670 +
 Source/LibWebP/src/dsp/dsp.enc_mips_dsp_r2.c       |  1510 +
 Source/LibWebP/src/dsp/dsp.enc_neon.c              |   932 +
 Source/LibWebP/src/dsp/dsp.enc_sse2.c              |   940 +
 Source/LibWebP/src/dsp/dsp.filters.c               |   240 +
 Source/LibWebP/src/dsp/dsp.filters_mips_dsp_r2.c   |   404 +
 Source/LibWebP/src/dsp/dsp.filters_sse2.c          |   349 +
 Source/LibWebP/src/dsp/dsp.h                       |   434 +
 Source/LibWebP/src/dsp/dsp.lossless.c              |  1838 +
 Source/LibWebP/src/dsp/dsp.lossless_mips32.c       |   416 +
 Source/LibWebP/src/dsp/dsp.lossless_mips_dsp_r2.c  |   921 +
 Source/LibWebP/src/dsp/dsp.lossless_neon.c         |   357 +
 Source/LibWebP/src/dsp/dsp.lossless_sse2.c         |   535 +
 Source/LibWebP/src/dsp/dsp.rescaler.c              |   115 +
 Source/LibWebP/src/dsp/dsp.rescaler_mips32.c       |   192 +
 Source/LibWebP/src/dsp/dsp.rescaler_mips_dsp_r2.c  |   210 +
 Source/LibWebP/src/dsp/dsp.upsampling.c            |   252 +
 .../LibWebP/src/dsp/dsp.upsampling_mips_dsp_r2.c   |   280 +
 Source/LibWebP/src/dsp/dsp.upsampling_neon.c       |   267 +
 Source/LibWebP/src/dsp/dsp.upsampling_sse2.c       |   214 +
 Source/LibWebP/src/dsp/dsp.yuv.c                   |   166 +
 Source/LibWebP/src/dsp/dsp.yuv_mips32.c            |   100 +
 Source/LibWebP/src/dsp/dsp.yuv_mips_dsp_r2.c       |   131 +
 Source/LibWebP/src/dsp/dsp.yuv_sse2.c              |   322 +
 Source/LibWebP/src/dsp/lossless.h                  |   313 +
 Source/LibWebP/src/dsp/mips_macro.h                |   200 +
 Source/LibWebP/src/dsp/neon.h                      |    82 +
 Source/LibWebP/src/dsp/yuv.h                       |   321 +
 Source/LibWebP/src/dsp/yuv_tables_sse2.h           |   536 +
 Source/LibWebP/src/enc/backward_references.h       |   202 +
 Source/LibWebP/src/enc/cost.h                      |    69 +
 Source/LibWebP/src/enc/enc.alpha.c                 |   440 +
 Source/LibWebP/src/enc/enc.analysis.c              |   501 +
 Source/LibWebP/src/enc/enc.backward_references.c   |  1076 +
 Source/LibWebP/src/enc/enc.config.c                |   163 +
 Source/LibWebP/src/enc/enc.cost.c                  |   355 +
 Source/LibWebP/src/enc/enc.filter.c                |   296 +
 Source/LibWebP/src/enc/enc.frame.c                 |   850 +
 Source/LibWebP/src/enc/enc.histogram.c             |   897 +
 Source/LibWebP/src/enc/enc.iterator.c              |   456 +
 Source/LibWebP/src/enc/enc.near_lossless.c         |   160 +
 Source/LibWebP/src/enc/enc.picture.c               |   290 +
 Source/LibWebP/src/enc/enc.picture_csp.c           |  1100 +
 Source/LibWebP/src/enc/enc.picture_psnr.c          |   150 +
 Source/LibWebP/src/enc/enc.picture_rescale.c       |   285 +
 Source/LibWebP/src/enc/enc.picture_tools.c         |   206 +
 Source/LibWebP/src/enc/enc.quant.c                 |  1191 +
 Source/LibWebP/src/enc/enc.syntax.c                |   383 +
 Source/LibWebP/src/enc/enc.token.c                 |   285 +
 Source/LibWebP/src/enc/enc.tree.c                  |   504 +
 Source/LibWebP/src/enc/enc.vp8l.c                  |  1437 +
 Source/LibWebP/src/enc/enc.webpenc.c               |   379 +
 Source/LibWebP/src/enc/histogram.h                 |   114 +
 Source/LibWebP/src/enc/vp8enci.h                   |   551 +
 Source/LibWebP/src/enc/vp8li.h                     |    78 +
 Source/LibWebP/src/file_rename.bat                 |    75 +
 Source/LibWebP/src/mux/mux.anim_encode.c           |  1241 +
 Source/LibWebP/src/mux/mux.muxedit.c               |   696 +
 Source/LibWebP/src/mux/mux.muxinternal.c           |   551 +
 Source/LibWebP/src/mux/mux.muxread.c               |   544 +
 Source/LibWebP/src/mux/muxi.h                      |   232 +
 Source/LibWebP/src/utils/bit_reader.h              |   168 +
 Source/LibWebP/src/utils/bit_reader_inl.h          |   172 +
 Source/LibWebP/src/utils/bit_writer.h              |   120 +
 Source/LibWebP/src/utils/color_cache.h             |    74 +
 Source/LibWebP/src/utils/endian_inl.h              |   100 +
 Source/LibWebP/src/utils/filters.h                 |    32 +
 Source/LibWebP/src/utils/huffman.h                 |    67 +
 Source/LibWebP/src/utils/huffman_encode.h          |    60 +
 Source/LibWebP/src/utils/quant_levels.h            |    36 +
 Source/LibWebP/src/utils/quant_levels_dec.h        |    35 +
 Source/LibWebP/src/utils/random.h                  |    63 +
 Source/LibWebP/src/utils/rescaler.h                |    78 +
 Source/LibWebP/src/utils/thread.h                  |    93 +
 Source/LibWebP/src/utils/utils.bit_reader.c        |   208 +
 Source/LibWebP/src/utils/utils.bit_writer.c        |   308 +
 Source/LibWebP/src/utils/utils.color_cache.c       |    49 +
 Source/LibWebP/src/utils/utils.filters.c           |    76 +
 Source/LibWebP/src/utils/utils.h                   |   121 +
 Source/LibWebP/src/utils/utils.huffman.c           |   205 +
 Source/LibWebP/src/utils/utils.huffman_encode.c    |   417 +
 Source/LibWebP/src/utils/utils.quant_levels.c      |   140 +
 Source/LibWebP/src/utils/utils.quant_levels_dec.c  |   279 +
 Source/LibWebP/src/utils/utils.random.c            |    43 +
 Source/LibWebP/src/utils/utils.rescaler.c          |    82 +
 Source/LibWebP/src/utils/utils.thread.c            |   309 +
 Source/LibWebP/src/utils/utils.utils.c             |   211 +
 Source/LibWebP/src/webp/decode.h                   |   493 +
 Source/LibWebP/src/webp/demux.h                    |   224 +
 Source/LibWebP/src/webp/encode.h                   |   515 +
 Source/LibWebP/src/webp/format_constants.h         |    88 +
 Source/LibWebP/src/webp/mux.h                      |   507 +
 Source/LibWebP/src/webp/mux_types.h                |    97 +
 Source/LibWebP/src/webp/types.h                    |    52 +
 Source/MapIntrospector.h                           |   212 +
 Source/Metadata/Exif.cpp                           |   516 +-
 Source/Metadata/FreeImageTag.cpp                   |    59 +-
 Source/Metadata/FreeImageTag.h                     |    44 +-
 Source/Metadata/TagConversion.cpp                  |  2188 +-
 Source/Metadata/XTIFF.cpp                          |  1431 +-
 Source/OpenEXR/Copyrights/ilmbase/AUTHORS          |    42 +-
 Source/OpenEXR/Copyrights/ilmbase/COPYING          |    68 +-
 Source/OpenEXR/Copyrights/ilmbase/ChangeLog        |   245 +-
 Source/OpenEXR/Copyrights/ilmbase/INSTALL          |     4 +-
 Source/OpenEXR/Copyrights/ilmbase/LICENSE          |    68 +-
 Source/OpenEXR/Copyrights/ilmbase/NEWS             |     6 +-
 Source/OpenEXR/Copyrights/ilmbase/README           |   130 +-
 Source/OpenEXR/Copyrights/ilmbase/README.CVS       |    32 +-
 Source/OpenEXR/Copyrights/ilmbase/README.OSX       |   169 +-
 Source/OpenEXR/Copyrights/ilmbase/README.git       |    16 +
 .../OpenEXR/Copyrights/ilmbase/README.namespacing  |    83 +
 Source/OpenEXR/Copyrights/ilmbase/README.win32     |     2 +-
 Source/OpenEXR/Copyrights/openexr/AUTHORS          |     6 +
 Source/OpenEXR/Copyrights/openexr/ChangeLog        |    40 +-
 Source/OpenEXR/Copyrights/openexr/PATENTS          |    23 +
 Source/OpenEXR/Copyrights/openexr/README           |    13 +-
 Source/OpenEXR/Copyrights/openexr/README.CVS       |    32 +-
 Source/OpenEXR/Copyrights/openexr/README.OSX       |    36 +
 Source/OpenEXR/Copyrights/openexr/README.git       |    16 +
 .../OpenEXR/Copyrights/openexr/README.namespacing  |    83 +
 Source/OpenEXR/Copyrights/openexr/README.win32     |   197 -
 Source/OpenEXR/Half/Makefile.am                    |    32 -
 Source/OpenEXR/Half/Makefile.in                    |   558 -
 Source/OpenEXR/Half/half.cpp                       |    25 +-
 Source/OpenEXR/Half/half.h                         |    43 +-
 Source/OpenEXR/Half/halfExport.h                   |    27 +
 Source/OpenEXR/Half/halfFunction.h                 |     3 +-
 Source/OpenEXR/Iex/IexBaseExc.cpp                  |    37 +-
 Source/OpenEXR/Iex/IexBaseExc.h                    |   116 +-
 Source/OpenEXR/Iex/IexErrnoExc.h                   |     8 +-
 Source/OpenEXR/Iex/IexExport.h                     |    51 +
 Source/OpenEXR/Iex/IexForward.h                    |   229 +
 Source/OpenEXR/Iex/IexMacros.h                     |    86 +-
 Source/OpenEXR/Iex/IexMathExc.h                    |     9 +-
 Source/OpenEXR/Iex/IexNamespace.h                  |   112 +
 Source/OpenEXR/Iex/IexThrowErrnoExc.cpp            |    20 +-
 Source/OpenEXR/Iex/IexThrowErrnoExc.h              |    15 +-
 Source/OpenEXR/Iex/Makefile.am                     |    16 -
 Source/OpenEXR/Iex/Makefile.in                     |   521 -
 Source/OpenEXR/IexMath/IexMathFloatExc.cpp         |   113 +
 Source/OpenEXR/IexMath/IexMathFloatExc.h           |   146 +
 Source/OpenEXR/IexMath/IexMathFpu.cpp              |   530 +
 Source/OpenEXR/IexMath/IexMathFpu.h                |    91 +
 Source/OpenEXR/IexMath/IexMathIeeeExc.h            |    62 +
 Source/OpenEXR/IlmBaseConfig.h                     |    85 +-
 Source/OpenEXR/IlmImf/ImfAcesFile.cpp              |    32 +-
 Source/OpenEXR/IlmImf/ImfAcesFile.h                |    50 +-
 Source/OpenEXR/IlmImf/ImfArray.h                   |    38 +-
 Source/OpenEXR/IlmImf/ImfAttribute.cpp             |    14 +-
 Source/OpenEXR/IlmImf/ImfAttribute.h               |    68 +-
 Source/OpenEXR/IlmImf/ImfAutoArray.h               |     8 +-
 Source/OpenEXR/IlmImf/ImfB44Compressor.cpp         |   165 +-
 Source/OpenEXR/IlmImf/ImfB44Compressor.h           |    21 +-
 Source/OpenEXR/IlmImf/ImfBoxAttribute.cpp          |    13 +-
 Source/OpenEXR/IlmImf/ImfBoxAttribute.h            |    46 +-
 Source/OpenEXR/IlmImf/ImfCRgbaFile.cpp             |   180 +-
 Source/OpenEXR/IlmImf/ImfCRgbaFile.h               |    88 +
 Source/OpenEXR/IlmImf/ImfChannelList.cpp           |    15 +-
 Source/OpenEXR/IlmImf/ImfChannelList.h             |    19 +-
 Source/OpenEXR/IlmImf/ImfChannelListAttribute.cpp  |    23 +-
 Source/OpenEXR/IlmImf/ImfChannelListAttribute.h    |    31 +-
 Source/OpenEXR/IlmImf/ImfCheckedArithmetic.h       |    22 +-
 Source/OpenEXR/IlmImf/ImfChromaticities.cpp        |    34 +-
 Source/OpenEXR/IlmImf/ImfChromaticities.h          |    37 +-
 .../OpenEXR/IlmImf/ImfChromaticitiesAttribute.cpp  |     9 +-
 Source/OpenEXR/IlmImf/ImfChromaticitiesAttribute.h |    25 +-
 Source/OpenEXR/IlmImf/ImfCompositeDeepScanLine.cpp |   591 +
 Source/OpenEXR/IlmImf/ImfCompositeDeepScanLine.h   |   142 +
 Source/OpenEXR/IlmImf/ImfCompression.h             |    15 +-
 Source/OpenEXR/IlmImf/ImfCompressionAttribute.cpp  |    12 +-
 Source/OpenEXR/IlmImf/ImfCompressionAttribute.h    |    22 +-
 Source/OpenEXR/IlmImf/ImfCompressor.cpp            |    54 +-
 Source/OpenEXR/IlmImf/ImfCompressor.h              |    29 +-
 Source/OpenEXR/IlmImf/ImfConvert.cpp               |    12 +-
 Source/OpenEXR/IlmImf/ImfConvert.h                 |    15 +-
 Source/OpenEXR/IlmImf/ImfDeepCompositing.cpp       |   110 +
 Source/OpenEXR/IlmImf/ImfDeepCompositing.h         |   132 +
 Source/OpenEXR/IlmImf/ImfDeepFrameBuffer.cpp       |   230 +
 Source/OpenEXR/IlmImf/ImfDeepFrameBuffer.h         |   339 +
 Source/OpenEXR/IlmImf/ImfDeepImageState.h          |    96 +
 .../OpenEXR/IlmImf/ImfDeepImageStateAttribute.cpp  |    78 +
 Source/OpenEXR/IlmImf/ImfDeepImageStateAttribute.h |    68 +
 Source/OpenEXR/IlmImf/ImfDeepScanLineInputFile.cpp |  2025 +
 Source/OpenEXR/IlmImf/ImfDeepScanLineInputFile.h   |   276 +
 Source/OpenEXR/IlmImf/ImfDeepScanLineInputPart.cpp |   149 +
 Source/OpenEXR/IlmImf/ImfDeepScanLineInputPart.h   |   181 +
 .../OpenEXR/IlmImf/ImfDeepScanLineOutputFile.cpp   |  1552 +
 Source/OpenEXR/IlmImf/ImfDeepScanLineOutputFile.h  |   244 +
 .../OpenEXR/IlmImf/ImfDeepScanLineOutputPart.cpp   |   107 +
 Source/OpenEXR/IlmImf/ImfDeepScanLineOutputPart.h  |   168 +
 Source/OpenEXR/IlmImf/ImfDeepTiledInputFile.cpp    |  1979 +
 Source/OpenEXR/IlmImf/ImfDeepTiledInputFile.h      |   437 +
 Source/OpenEXR/IlmImf/ImfDeepTiledInputPart.cpp    |   273 +
 Source/OpenEXR/IlmImf/ImfDeepTiledInputPart.h      |   362 +
 Source/OpenEXR/IlmImf/ImfDeepTiledOutputFile.cpp   |  2055 +
 Source/OpenEXR/IlmImf/ImfDeepTiledOutputFile.h     |   475 +
 Source/OpenEXR/IlmImf/ImfDeepTiledOutputPart.cpp   |   250 +
 Source/OpenEXR/IlmImf/ImfDeepTiledOutputPart.h     |   394 +
 Source/OpenEXR/IlmImf/ImfDoubleAttribute.cpp       |     4 +-
 Source/OpenEXR/IlmImf/ImfDoubleAttribute.h         |    14 +-
 Source/OpenEXR/IlmImf/ImfDwaCompressor.cpp         |  3424 +
 Source/OpenEXR/IlmImf/ImfDwaCompressor.h           |   210 +
 Source/OpenEXR/IlmImf/ImfDwaCompressorSimd.h       |  2145 +
 Source/OpenEXR/IlmImf/ImfEnvmap.cpp                |    27 +-
 Source/OpenEXR/IlmImf/ImfEnvmap.h                  |    60 +-
 Source/OpenEXR/IlmImf/ImfEnvmapAttribute.cpp       |     9 +-
 Source/OpenEXR/IlmImf/ImfEnvmapAttribute.h         |    27 +-
 Source/OpenEXR/IlmImf/ImfExport.h                  |    46 +
 Source/OpenEXR/IlmImf/ImfFastHuf.cpp               |   768 +
 Source/OpenEXR/IlmImf/ImfFastHuf.h                 |   148 +
 Source/OpenEXR/IlmImf/ImfFloatAttribute.cpp        |     4 +-
 Source/OpenEXR/IlmImf/ImfFloatAttribute.h          |    13 +-
 Source/OpenEXR/IlmImf/ImfFloatVectorAttribute.cpp  |    84 +
 Source/OpenEXR/IlmImf/ImfFloatVectorAttribute.h    |    76 +
 Source/OpenEXR/IlmImf/ImfForward.h                 |   127 +
 Source/OpenEXR/IlmImf/ImfFrameBuffer.cpp           |    44 +-
 Source/OpenEXR/IlmImf/ImfFrameBuffer.h             |   139 +-
 Source/OpenEXR/IlmImf/ImfFramesPerSecond.cpp       |     7 +-
 Source/OpenEXR/IlmImf/ImfFramesPerSecond.h         |    16 +-
 Source/OpenEXR/IlmImf/ImfGenericInputFile.cpp      |    76 +
 Source/OpenEXR/IlmImf/ImfGenericInputFile.h        |    58 +
 Source/OpenEXR/IlmImf/ImfGenericOutputFile.cpp     |   112 +
 Source/OpenEXR/IlmImf/ImfGenericOutputFile.h       |    62 +
 Source/OpenEXR/IlmImf/ImfHeader.cpp                |   465 +-
 Source/OpenEXR/IlmImf/ImfHeader.h                  |   140 +-
 Source/OpenEXR/IlmImf/ImfHuf.cpp                   |    84 +-
 Source/OpenEXR/IlmImf/ImfHuf.h                     |     9 +-
 Source/OpenEXR/IlmImf/ImfIO.cpp                    |     7 +-
 Source/OpenEXR/IlmImf/ImfIO.h                      |    29 +-
 Source/OpenEXR/IlmImf/ImfInputFile.cpp             |   425 +-
 Source/OpenEXR/IlmImf/ImfInputFile.h               |    53 +-
 Source/OpenEXR/IlmImf/ImfInputPart.cpp             |   114 +
 Source/OpenEXR/IlmImf/ImfInputPart.h               |    84 +
 Source/OpenEXR/IlmImf/ImfInputPartData.cpp         |    51 +
 Source/OpenEXR/IlmImf/ImfInputPartData.h           |    69 +
 Source/OpenEXR/IlmImf/ImfInputStreamMutex.h        |    68 +
 Source/OpenEXR/IlmImf/ImfInt64.h                   |    12 +-
 Source/OpenEXR/IlmImf/ImfIntAttribute.cpp          |     4 +-
 Source/OpenEXR/IlmImf/ImfIntAttribute.h            |    15 +-
 Source/OpenEXR/IlmImf/ImfKeyCode.cpp               |    19 +-
 Source/OpenEXR/IlmImf/ImfKeyCode.h                 |    12 +-
 Source/OpenEXR/IlmImf/ImfKeyCodeAttribute.cpp      |     9 +-
 Source/OpenEXR/IlmImf/ImfKeyCodeAttribute.h        |    25 +-
 Source/OpenEXR/IlmImf/ImfLineOrder.h               |     9 +-
 Source/OpenEXR/IlmImf/ImfLineOrderAttribute.cpp    |    11 +-
 Source/OpenEXR/IlmImf/ImfLineOrderAttribute.h      |    30 +-
 Source/OpenEXR/IlmImf/ImfLut.cpp                   |    10 +-
 Source/OpenEXR/IlmImf/ImfLut.h                     |    19 +-
 Source/OpenEXR/IlmImf/ImfMatrixAttribute.cpp       |    23 +-
 Source/OpenEXR/IlmImf/ImfMatrixAttribute.h         |    44 +-
 Source/OpenEXR/IlmImf/ImfMisc.cpp                  |  1255 +-
 Source/OpenEXR/IlmImf/ImfMisc.h                    |   231 +-
 Source/OpenEXR/IlmImf/ImfMultiPartInputFile.cpp    |   783 +
 Source/OpenEXR/IlmImf/ImfMultiPartInputFile.h      |   128 +
 Source/OpenEXR/IlmImf/ImfMultiPartOutputFile.cpp   |   519 +
 Source/OpenEXR/IlmImf/ImfMultiPartOutputFile.h     |   118 +
 Source/OpenEXR/IlmImf/ImfMultiView.cpp             |    53 +-
 Source/OpenEXR/IlmImf/ImfMultiView.h               |    31 +-
 Source/OpenEXR/IlmImf/ImfName.h                    |     8 +-
 Source/OpenEXR/IlmImf/ImfNamespace.h               |   115 +
 Source/OpenEXR/IlmImf/ImfOpaqueAttribute.cpp       |    11 +-
 Source/OpenEXR/IlmImf/ImfOpaqueAttribute.h         |    20 +-
 Source/OpenEXR/IlmImf/ImfOptimizedPixelReading.h   |   646 +
 Source/OpenEXR/IlmImf/ImfOutputFile.cpp            |   353 +-
 Source/OpenEXR/IlmImf/ImfOutputFile.h              |    44 +-
 Source/OpenEXR/IlmImf/ImfOutputPart.cpp            |   105 +
 Source/OpenEXR/IlmImf/ImfOutputPart.h              |    77 +
 Source/OpenEXR/IlmImf/ImfOutputPartData.cpp        |    52 +
 Source/OpenEXR/IlmImf/ImfOutputPartData.h          |    62 +
 Source/OpenEXR/IlmImf/ImfOutputStreamMutex.h       |    70 +
 Source/OpenEXR/IlmImf/ImfPartHelper.h              |   262 +
 Source/OpenEXR/IlmImf/ImfPartType.cpp              |    63 +
 Source/OpenEXR/IlmImf/ImfPartType.h                |    62 +
 Source/OpenEXR/IlmImf/ImfPixelType.h               |    16 +-
 Source/OpenEXR/IlmImf/ImfPizCompressor.cpp         |    45 +-
 Source/OpenEXR/IlmImf/ImfPizCompressor.h           |    20 +-
 Source/OpenEXR/IlmImf/ImfPreviewImage.cpp          |     9 +-
 Source/OpenEXR/IlmImf/ImfPreviewImage.h            |    12 +-
 Source/OpenEXR/IlmImf/ImfPreviewImageAttribute.cpp |     9 +-
 Source/OpenEXR/IlmImf/ImfPreviewImageAttribute.h   |    25 +-
 Source/OpenEXR/IlmImf/ImfPxr24Compressor.cpp       |    57 +-
 Source/OpenEXR/IlmImf/ImfPxr24Compressor.h         |    21 +-
 Source/OpenEXR/IlmImf/ImfRational.cpp              |     6 +-
 Source/OpenEXR/IlmImf/ImfRational.h                |    11 +-
 Source/OpenEXR/IlmImf/ImfRationalAttribute.cpp     |     9 +-
 Source/OpenEXR/IlmImf/ImfRationalAttribute.h       |    25 +-
 Source/OpenEXR/IlmImf/ImfRgba.h                    |     9 +-
 Source/OpenEXR/IlmImf/ImfRgbaFile.cpp              |    39 +-
 Source/OpenEXR/IlmImf/ImfRgbaFile.h                |    52 +-
 Source/OpenEXR/IlmImf/ImfRgbaYca.cpp               |    12 +-
 Source/OpenEXR/IlmImf/ImfRgbaYca.h                 |    31 +-
 Source/OpenEXR/IlmImf/ImfRle.cpp                   |   157 +
 Source/OpenEXR/IlmImf/ImfRle.h                     |    63 +
 Source/OpenEXR/IlmImf/ImfRleCompressor.cpp         |   129 +-
 Source/OpenEXR/IlmImf/ImfRleCompressor.h           |     9 +-
 Source/OpenEXR/IlmImf/ImfScanLineInputFile.cpp     |   995 +-
 Source/OpenEXR/IlmImf/ImfScanLineInputFile.h       |    52 +-
 Source/OpenEXR/IlmImf/ImfSimd.h                    |    59 +
 Source/OpenEXR/IlmImf/ImfStandardAttributes.cpp    |    29 +-
 Source/OpenEXR/IlmImf/ImfStandardAttributes.h      |    93 +-
 Source/OpenEXR/IlmImf/ImfStdIO.cpp                 |    30 +-
 Source/OpenEXR/IlmImf/ImfStdIO.h                   |    22 +-
 Source/OpenEXR/IlmImf/ImfStringAttribute.cpp       |     9 +-
 Source/OpenEXR/IlmImf/ImfStringAttribute.h         |    27 +-
 Source/OpenEXR/IlmImf/ImfStringVectorAttribute.cpp |    20 +-
 Source/OpenEXR/IlmImf/ImfStringVectorAttribute.h   |    30 +-
 Source/OpenEXR/IlmImf/ImfSystemSpecific.cpp        |   129 +
 Source/OpenEXR/IlmImf/ImfSystemSpecific.h          |   172 +
 Source/OpenEXR/IlmImf/ImfTestFile.cpp              |   109 +-
 Source/OpenEXR/IlmImf/ImfTestFile.h                |    52 +-
 Source/OpenEXR/IlmImf/ImfThreading.cpp             |    10 +-
 Source/OpenEXR/IlmImf/ImfThreading.h               |    11 +-
 Source/OpenEXR/IlmImf/ImfTileDescription.h         |     9 +-
 .../OpenEXR/IlmImf/ImfTileDescriptionAttribute.cpp |     9 +-
 .../OpenEXR/IlmImf/ImfTileDescriptionAttribute.h   |    25 +-
 Source/OpenEXR/IlmImf/ImfTileOffsets.cpp           |   231 +-
 Source/OpenEXR/IlmImf/ImfTileOffsets.h             |    52 +-
 Source/OpenEXR/IlmImf/ImfTiledInputFile.cpp        |   549 +-
 Source/OpenEXR/IlmImf/ImfTiledInputFile.h          |    50 +-
 Source/OpenEXR/IlmImf/ImfTiledInputPart.cpp        |   208 +
 Source/OpenEXR/IlmImf/ImfTiledInputPart.h          |   100 +
 Source/OpenEXR/IlmImf/ImfTiledMisc.cpp             |   102 +-
 Source/OpenEXR/IlmImf/ImfTiledMisc.h               |    41 +-
 Source/OpenEXR/IlmImf/ImfTiledOutputFile.cpp       |   381 +-
 Source/OpenEXR/IlmImf/ImfTiledOutputFile.h         |    54 +-
 Source/OpenEXR/IlmImf/ImfTiledOutputPart.cpp       |   228 +
 Source/OpenEXR/IlmImf/ImfTiledOutputPart.h         |   105 +
 Source/OpenEXR/IlmImf/ImfTiledRgbaFile.cpp         |    57 +-
 Source/OpenEXR/IlmImf/ImfTiledRgbaFile.h           |    73 +-
 Source/OpenEXR/IlmImf/ImfTimeCode.cpp              |    44 +-
 Source/OpenEXR/IlmImf/ImfTimeCode.h                |    24 +-
 Source/OpenEXR/IlmImf/ImfTimeCodeAttribute.cpp     |     9 +-
 Source/OpenEXR/IlmImf/ImfTimeCodeAttribute.h       |    26 +-
 Source/OpenEXR/IlmImf/ImfVecAttribute.cpp          |    29 +-
 Source/OpenEXR/IlmImf/ImfVecAttribute.h            |    59 +-
 Source/OpenEXR/IlmImf/ImfVersion.cpp               |     5 +-
 Source/OpenEXR/IlmImf/ImfVersion.h                 |    24 +-
 Source/OpenEXR/IlmImf/ImfWav.cpp                   |     5 +-
 Source/OpenEXR/IlmImf/ImfWav.h                     |    12 +-
 Source/OpenEXR/IlmImf/ImfXdr.h                     |    21 +-
 Source/OpenEXR/IlmImf/ImfZip.cpp                   |   196 +
 Source/OpenEXR/IlmImf/ImfZip.h                     |    78 +
 Source/OpenEXR/IlmImf/ImfZipCompressor.cpp         |   139 +-
 Source/OpenEXR/IlmImf/ImfZipCompressor.h           |    14 +-
 Source/OpenEXR/IlmImf/Makefile.am                  |   128 -
 Source/OpenEXR/IlmImf/Makefile.in                  |   736 -
 Source/OpenEXR/IlmImf/dwaLookups.cpp               |   573 +
 Source/OpenEXR/IlmImf/dwaLookups.h                 | 98334 +++++++++++++++++++
 Source/OpenEXR/IlmThread/IlmThread.cpp             |    14 +-
 Source/OpenEXR/IlmThread/IlmThread.h               |    20 +-
 Source/OpenEXR/IlmThread/IlmThreadExport.h         |    46 +
 Source/OpenEXR/IlmThread/IlmThreadForward.h        |    52 +
 Source/OpenEXR/IlmThread/IlmThreadMutex.cpp        |     8 +-
 Source/OpenEXR/IlmThread/IlmThreadMutex.h          |    14 +-
 Source/OpenEXR/IlmThread/IlmThreadMutexPosix.cpp   |    12 +-
 Source/OpenEXR/IlmThread/IlmThreadMutexWin32.cpp   |    12 +-
 Source/OpenEXR/IlmThread/IlmThreadNamespace.h      |   114 +
 Source/OpenEXR/IlmThread/IlmThreadPool.cpp         |    41 +-
 Source/OpenEXR/IlmThread/IlmThreadPool.h           |    24 +-
 Source/OpenEXR/IlmThread/IlmThreadPosix.cpp        |     8 +-
 Source/OpenEXR/IlmThread/IlmThreadSemaphore.cpp    |     8 +-
 Source/OpenEXR/IlmThread/IlmThreadSemaphore.h      |    12 +-
 .../OpenEXR/IlmThread/IlmThreadSemaphorePosix.cpp  |    17 +-
 .../IlmThread/IlmThreadSemaphorePosixCompat.cpp    |    24 +-
 .../OpenEXR/IlmThread/IlmThreadSemaphoreWin32.cpp  |    15 +-
 Source/OpenEXR/IlmThread/IlmThreadWin32.cpp        |    13 +-
 Source/OpenEXR/IlmThread/Makefile.am               |    26 -
 Source/OpenEXR/IlmThread/Makefile.in               |   539 -
 Source/OpenEXR/Imath/ImathBox.h                    |    11 +-
 Source/OpenEXR/Imath/ImathBoxAlgo.h                |     9 +-
 Source/OpenEXR/Imath/ImathColor.h                  |    10 +-
 Source/OpenEXR/Imath/ImathColorAlgo.cpp            |     6 +-
 Source/OpenEXR/Imath/ImathColorAlgo.h              |    19 +-
 Source/OpenEXR/Imath/ImathEuler.h                  |    10 +-
 Source/OpenEXR/Imath/ImathExc.h                    |    36 +-
 Source/OpenEXR/Imath/ImathExport.h                 |    46 +
 Source/OpenEXR/Imath/ImathForward.h                |    72 +
 Source/OpenEXR/Imath/ImathFrame.h                  |    16 +-
 Source/OpenEXR/Imath/ImathFrustum.h                |   476 +-
 Source/OpenEXR/Imath/ImathFrustumTest.h            |    51 +-
 Source/OpenEXR/Imath/ImathFun.cpp                  |    10 +-
 Source/OpenEXR/Imath/ImathFun.h                    |    26 +-
 Source/OpenEXR/Imath/ImathGL.h                     |    37 +-
 Source/OpenEXR/Imath/ImathGLU.h                    |     2 +-
 Source/OpenEXR/Imath/ImathHalfLimits.h             |    10 +-
 Source/OpenEXR/Imath/ImathInt64.h                  |     9 +-
 Source/OpenEXR/Imath/ImathInterval.h               |    10 +-
 Source/OpenEXR/Imath/ImathLimits.h                 |     9 +-
 Source/OpenEXR/Imath/ImathLine.h                   |     9 +-
 Source/OpenEXR/Imath/ImathLineAlgo.h               |     9 +-
 Source/OpenEXR/Imath/ImathMath.h                   |    10 +-
 Source/OpenEXR/Imath/ImathMatrix.h                 |    77 +-
 Source/OpenEXR/Imath/ImathMatrixAlgo.cpp           |   193 +-
 Source/OpenEXR/Imath/ImathMatrixAlgo.h             |   106 +-
 Source/OpenEXR/Imath/ImathNamespace.h              |   115 +
 Source/OpenEXR/Imath/ImathPlane.h                  |     9 +-
 Source/OpenEXR/Imath/ImathQuat.h                   |     9 +-
 Source/OpenEXR/Imath/ImathRandom.cpp               |    11 +-
 Source/OpenEXR/Imath/ImathRandom.h                 |    29 +-
 Source/OpenEXR/Imath/ImathRoots.h                  |    12 +-
 Source/OpenEXR/Imath/ImathShear.cpp                |     6 +-
 Source/OpenEXR/Imath/ImathShear.h                  |    17 +-
 Source/OpenEXR/Imath/ImathSphere.h                 |    10 +-
 Source/OpenEXR/Imath/ImathVec.cpp                  |    73 +-
 Source/OpenEXR/Imath/ImathVec.h                    |    69 +-
 Source/OpenEXR/Imath/ImathVecAlgo.h                |     9 +-
 Source/OpenEXR/Imath/Makefile.am                   |    35 -
 Source/OpenEXR/Imath/Makefile.in                   |   547 -
 Source/OpenEXR/OpenEXR.2003.vcproj                 |   746 -
 Source/OpenEXR/OpenEXR.2005.vcproj                 |   356 +-
 Source/OpenEXR/OpenEXR.2008.vcproj                 |   378 +-
 Source/OpenEXR/OpenEXR.2013.vcxproj                |   495 +
 Source/OpenEXR/OpenEXR.2013.vcxproj.filters        |   889 +
 Source/OpenEXR/OpenEXRConfig.h                     |    72 +-
 Source/Plugin.h                                    |     2 +
 Source/Quantizers.h                                |   129 +
 Source/Utilities.h                                 |    60 +-
 Source/ZLib/ChangeLog                              |    65 +-
 Source/ZLib/Makefile.in                            |    20 +-
 Source/ZLib/README                                 |     6 +-
 Source/ZLib/ZLib.2003.vcproj                       |   213 -
 Source/ZLib/ZLib.2008.vcproj                       |     4 +-
 Source/ZLib/ZLib.2013.vcxproj                      |   233 +
 Source/ZLib/ZLib.2013.vcxproj.filters              |    95 +
 Source/ZLib/adler32.c                              |   358 +-
 Source/ZLib/compress.c                             |   160 +-
 Source/ZLib/configure                              |   171 +-
 Source/ZLib/crc32.c                                |   850 +-
 Source/ZLib/deflate.c                              |  3932 +-
 Source/ZLib/deflate.h                              |   692 +-
 Source/ZLib/gzguts.h                               |    22 +-
 Source/ZLib/gzlib.c                                |    40 +-
 Source/ZLib/gzread.c                               |    21 +-
 Source/ZLib/gzwrite.c                              |    64 +-
 Source/ZLib/infback.c                              |     2 +-
 Source/ZLib/inffast.c                              |     6 +-
 Source/ZLib/inflate.c                              |    64 +-
 Source/ZLib/inftrees.c                             |    14 +-
 Source/ZLib/trees.c                                |  2450 +-
 Source/ZLib/uncompr.c                              |   118 +-
 Source/ZLib/zconf.h                                |  1017 +-
 Source/ZLib/zconf.h.in                             |    35 +-
 Source/ZLib/zlib.3                                 |     6 +-
 Source/ZLib/zlib.h                                 |    48 +-
 Source/ZLib/zutil.c                                |   648 +-
 Source/ZLib/zutil.h                                |   505 +-
 TestAPI/MainTestSuite.cpp                          |     4 +
 TestAPI/Test.2003.sln                              |    21 -
 TestAPI/Test.2003.vcproj                           |   180 -
 TestAPI/Test.2008.vcproj                           |     4 +
 TestAPI/Test.2013.sln                              |    27 +
 TestAPI/Test.2013.vcxproj                          |   265 +
 TestAPI/TestSuite.h                                |     4 +
 TestAPI/exif.jxr                                   |   Bin 0 -> 261497 bytes
 TestAPI/testJPEG.cpp                               |   132 +-
 TestAPI/testMemIO.cpp                              |     3 +-
 TestAPI/testThumbnail.cpp                          |     2 +-
 TestAPI/testWrappedBuffer.cpp                      |   114 +
 Whatsnew.txt                                       |    86 +
 Wrapper/Delphi/WhatsNew_Delphi.txt                 |     8 +
 Wrapper/Delphi/src/FreeBitmap.pas                  |    21 +-
 Wrapper/Delphi/src/FreeImage.pas                   |  1433 +-
 Wrapper/Delphi/src/Version.inc                     |   100 +
 Wrapper/FreeImagePlus/FreeImagePlus.2003.sln       |    21 -
 Wrapper/FreeImagePlus/FreeImagePlus.2003.vcproj    |   215 -
 Wrapper/FreeImagePlus/FreeImagePlus.2013.sln       |    21 +
 Wrapper/FreeImagePlus/FreeImagePlus.2013.vcxproj   |   306 +
 .../FreeImagePlus.2013.vcxproj.filters             |    53 +
 Wrapper/FreeImagePlus/FreeImagePlus.h              |    66 +-
 Wrapper/FreeImagePlus/FreeImagePlus.rc             |    63 +-
 Wrapper/FreeImagePlus/WhatsNew_FIP.txt             |     6 +
 Wrapper/FreeImagePlus/clean.bat                    |    18 +-
 Wrapper/FreeImagePlus/src/FreeImagePlus.cpp        |    92 +-
 Wrapper/FreeImagePlus/src/fipImage.cpp             |  1928 +-
 Wrapper/FreeImagePlus/src/fipMemoryIO.cpp          |   190 +-
 Wrapper/FreeImagePlus/src/fipMetadataFind.cpp      |   108 +-
 Wrapper/FreeImagePlus/src/fipMultiPage.cpp         |   280 +-
 Wrapper/FreeImagePlus/src/fipTag.cpp               |   268 +-
 Wrapper/FreeImagePlus/src/fipWinImage.cpp          |   976 +-
 Wrapper/FreeImagePlus/test/fipTest.2003.sln        |    23 -
 Wrapper/FreeImagePlus/test/fipTest.2003.vcproj     |   201 -
 Wrapper/FreeImagePlus/test/fipTest.2008.vcproj     |   109 +-
 Wrapper/FreeImagePlus/test/fipTest.2013.sln        |    28 +
 Wrapper/FreeImagePlus/test/fipTest.2013.vcxproj    |   263 +
 Wrapper/FreeImagePlus/test/fipTestMPage.cpp        |    15 +-
 Wrapper/FreeImagePlus/test/fipTestMPageMemory.cpp  |     1 +
 Wrapper/FreeImagePlus/test/fipTestMemIO.cpp        |    21 +-
 Wrapper/VB6/awk_script/genbas.sh                   |    21 +
 Wrapper/VB6/awk_script/genbasfuncs.awk             |   136 +
 Wrapper/VB6/awk_script/readme.txt                  |    14 +
 Wrapper/VB6/mfreeimage/MFreeImage.bas              |  3852 +-
 Wrapper/VB6/mfreeimage/WhatsNew_VB.txt             |   169 +-
 Wrapper/VB6/modFreeImage.bas                       |   512 +
 clean.bat                                          |   134 +-
 clean.sh                                           |     6 +-
 extra.Debian/FreeImage3154.pdf                     |   Bin 1007480 -> 0 bytes
 fipMakefile.srcs                                   |     6 +-
 genfipsrclist.sh                                   |     4 +-
 gensrclist.sh                                      |     4 +-
 1062 files changed, 402227 insertions(+), 276638 deletions(-)

diff --git a/FreeImage.2003.sln b/FreeImage.2003.sln
deleted file mode 100644
index 8e8b91e..0000000
--- a/FreeImage.2003.sln
+++ /dev/null
@@ -1,106 +0,0 @@
-Microsoft Visual Studio Solution File, Format Version 8.00
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeImage", "FreeImage.2003.vcproj", "{B39ED2B3-D53A-4077-B957-930979A3577D}"
-	ProjectSection(ProjectDependencies) = postProject
-		{E3536C28-A7F1-4B53-8E52-7D2232F9E098} = {E3536C28-A7F1-4B53-8E52-7D2232F9E098}
-		{1B0A722E-A6A5-4DF2-9A7F-DE24E20E6937} = {1B0A722E-A6A5-4DF2-9A7F-DE24E20E6937}
-		{B03A124A-33A7-453B-8DDA-CB4DEF9EB4C9} = {B03A124A-33A7-453B-8DDA-CB4DEF9EB4C9}
-		{17A4874B-0606-4687-90B6-F91F8CB3B8AF} = {17A4874B-0606-4687-90B6-F91F8CB3B8AF}
-		{7DB10B50-CE00-4D7A-B322-6824F05D2FCB} = {7DB10B50-CE00-4D7A-B322-6824F05D2FCB}
-		{5E1D4E5F-E10C-4BA3-B663-F33014FD21D9} = {5E1D4E5F-E10C-4BA3-B663-F33014FD21D9}
-		{33134F61-C1AD-4B6F-9CEA-503A9F140C52} = {33134F61-C1AD-4B6F-9CEA-503A9F140C52}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeImageLib", "SOURCE\FreeImageLib\FreeImageLib.2003.vcproj", "{9E219DF2-315D-478E-8A07-8960C377CE1E}"
-	ProjectSection(ProjectDependencies) = postProject
-		{E3536C28-A7F1-4B53-8E52-7D2232F9E098} = {E3536C28-A7F1-4B53-8E52-7D2232F9E098}
-		{1B0A722E-A6A5-4DF2-9A7F-DE24E20E6937} = {1B0A722E-A6A5-4DF2-9A7F-DE24E20E6937}
-		{B03A124A-33A7-453B-8DDA-CB4DEF9EB4C9} = {B03A124A-33A7-453B-8DDA-CB4DEF9EB4C9}
-		{17A4874B-0606-4687-90B6-F91F8CB3B8AF} = {17A4874B-0606-4687-90B6-F91F8CB3B8AF}
-		{7DB10B50-CE00-4D7A-B322-6824F05D2FCB} = {7DB10B50-CE00-4D7A-B322-6824F05D2FCB}
-		{5E1D4E5F-E10C-4BA3-B663-F33014FD21D9} = {5E1D4E5F-E10C-4BA3-B663-F33014FD21D9}
-		{33134F61-C1AD-4B6F-9CEA-503A9F140C52} = {33134F61-C1AD-4B6F-9CEA-503A9F140C52}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeImagePlus", "Wrapper\FreeImagePlus\FreeImagePlus.2003.vcproj", "{12AAE1F1-E982-49D3-B24E-63FD677FCE77}"
-	ProjectSection(ProjectDependencies) = postProject
-		{B39ED2B3-D53A-4077-B957-930979A3577D} = {B39ED2B3-D53A-4077-B957-930979A3577D}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibJPEG", "Source\LibJPEG\LibJPEG.2003.vcproj", "{5E1D4E5F-E10C-4BA3-B663-F33014FD21D9}"
-	ProjectSection(ProjectDependencies) = postProject
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibPNG", "Source\LibPNG\LibPNG.2003.vcproj", "{7DB10B50-CE00-4D7A-B322-6824F05D2FCB}"
-	ProjectSection(ProjectDependencies) = postProject
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZLib", "Source\ZLib\ZLib.2003.vcproj", "{33134F61-C1AD-4B6F-9CEA-503A9F140C52}"
-	ProjectSection(ProjectDependencies) = postProject
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OpenEXR", "Source\OpenEXR\OpenEXR.2003.vcproj", "{17A4874B-0606-4687-90B6-F91F8CB3B8AF}"
-	ProjectSection(ProjectDependencies) = postProject
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibOpenJPEG", "Source\LibOpenJPEG\LibOpenJPEG.2003.vcproj", "{E3536C28-A7F1-4B53-8E52-7D2232F9E098}"
-	ProjectSection(ProjectDependencies) = postProject
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibRaw", "Source\LibRawLite\LibRawLite.2003.vcproj", "{1B0A722E-A6A5-4DF2-9A7F-DE24E20E6937}"
-	ProjectSection(ProjectDependencies) = postProject
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibTIFF4", "Source\LibTIFF4\LibTIFF4.2003.vcproj", "{B03A124A-33A7-453B-8DDA-CB4DEF9EB4C9}"
-	ProjectSection(ProjectDependencies) = postProject
-	EndProjectSection
-EndProject
-Global
-	GlobalSection(SolutionConfiguration) = preSolution
-		Debug = Debug
-		Release = Release
-	EndGlobalSection
-	GlobalSection(ProjectConfiguration) = postSolution
-		{B39ED2B3-D53A-4077-B957-930979A3577D}.Debug.ActiveCfg = Debug|Win32
-		{B39ED2B3-D53A-4077-B957-930979A3577D}.Debug.Build.0 = Debug|Win32
-		{B39ED2B3-D53A-4077-B957-930979A3577D}.Release.ActiveCfg = Release|Win32
-		{B39ED2B3-D53A-4077-B957-930979A3577D}.Release.Build.0 = Release|Win32
-		{9E219DF2-315D-478E-8A07-8960C377CE1E}.Debug.ActiveCfg = Debug|Win32
-		{9E219DF2-315D-478E-8A07-8960C377CE1E}.Release.ActiveCfg = Release|Win32
-		{12AAE1F1-E982-49D3-B24E-63FD677FCE77}.Debug.ActiveCfg = Debug|Win32
-		{12AAE1F1-E982-49D3-B24E-63FD677FCE77}.Debug.Build.0 = Debug|Win32
-		{12AAE1F1-E982-49D3-B24E-63FD677FCE77}.Release.ActiveCfg = Release|Win32
-		{12AAE1F1-E982-49D3-B24E-63FD677FCE77}.Release.Build.0 = Release|Win32
-		{5E1D4E5F-E10C-4BA3-B663-F33014FD21D9}.Debug.ActiveCfg = Debug|Win32
-		{5E1D4E5F-E10C-4BA3-B663-F33014FD21D9}.Debug.Build.0 = Debug|Win32
-		{5E1D4E5F-E10C-4BA3-B663-F33014FD21D9}.Release.ActiveCfg = Release|Win32
-		{5E1D4E5F-E10C-4BA3-B663-F33014FD21D9}.Release.Build.0 = Release|Win32
-		{7DB10B50-CE00-4D7A-B322-6824F05D2FCB}.Debug.ActiveCfg = Debug|Win32
-		{7DB10B50-CE00-4D7A-B322-6824F05D2FCB}.Debug.Build.0 = Debug|Win32
-		{7DB10B50-CE00-4D7A-B322-6824F05D2FCB}.Release.ActiveCfg = Release|Win32
-		{7DB10B50-CE00-4D7A-B322-6824F05D2FCB}.Release.Build.0 = Release|Win32
-		{33134F61-C1AD-4B6F-9CEA-503A9F140C52}.Debug.ActiveCfg = Debug|Win32
-		{33134F61-C1AD-4B6F-9CEA-503A9F140C52}.Debug.Build.0 = Debug|Win32
-		{33134F61-C1AD-4B6F-9CEA-503A9F140C52}.Release.ActiveCfg = Release|Win32
-		{33134F61-C1AD-4B6F-9CEA-503A9F140C52}.Release.Build.0 = Release|Win32
-		{17A4874B-0606-4687-90B6-F91F8CB3B8AF}.Debug.ActiveCfg = Debug|Win32
-		{17A4874B-0606-4687-90B6-F91F8CB3B8AF}.Debug.Build.0 = Debug|Win32
-		{17A4874B-0606-4687-90B6-F91F8CB3B8AF}.Release.ActiveCfg = Release|Win32
-		{17A4874B-0606-4687-90B6-F91F8CB3B8AF}.Release.Build.0 = Release|Win32
-		{E3536C28-A7F1-4B53-8E52-7D2232F9E098}.Debug.ActiveCfg = Debug|Win32
-		{E3536C28-A7F1-4B53-8E52-7D2232F9E098}.Debug.Build.0 = Debug|Win32
-		{E3536C28-A7F1-4B53-8E52-7D2232F9E098}.Release.ActiveCfg = Release|Win32
-		{E3536C28-A7F1-4B53-8E52-7D2232F9E098}.Release.Build.0 = Release|Win32
-		{1B0A722E-A6A5-4DF2-9A7F-DE24E20E6937}.Debug.ActiveCfg = Debug|Win32
-		{1B0A722E-A6A5-4DF2-9A7F-DE24E20E6937}.Debug.Build.0 = Debug|Win32
-		{1B0A722E-A6A5-4DF2-9A7F-DE24E20E6937}.Release.ActiveCfg = Release|Win32
-		{1B0A722E-A6A5-4DF2-9A7F-DE24E20E6937}.Release.Build.0 = Release|Win32
-		{B03A124A-33A7-453B-8DDA-CB4DEF9EB4C9}.Debug.ActiveCfg = Debug|Win32
-		{B03A124A-33A7-453B-8DDA-CB4DEF9EB4C9}.Debug.Build.0 = Debug|Win32
-		{B03A124A-33A7-453B-8DDA-CB4DEF9EB4C9}.Release.ActiveCfg = Release|Win32
-		{B03A124A-33A7-453B-8DDA-CB4DEF9EB4C9}.Release.Build.0 = Release|Win32
-	EndGlobalSection
-	GlobalSection(ExtensibilityGlobals) = postSolution
-	EndGlobalSection
-	GlobalSection(ExtensibilityAddIns) = postSolution
-	EndGlobalSection
-EndGlobal
diff --git a/FreeImage.2003.vcproj b/FreeImage.2003.vcproj
deleted file mode 100644
index 26fccb2..0000000
--- a/FreeImage.2003.vcproj
+++ /dev/null
@@ -1,504 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="7.10"
-	Name="FreeImage"
-	SccProjectName=""
-	SccLocalPath="">
-	<Platforms>
-		<Platform
-			Name="Win32"/>
-	</Platforms>
-	<Configurations>
-		<Configuration
-			Name="Release|Win32"
-			OutputDirectory=".\Release"
-			IntermediateDirectory=".\Release"
-			ConfigurationType="2"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="FALSE"
-			CharacterSet="2">
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="2"
-				GlobalOptimizations="TRUE"
-				InlineFunctionExpansion="2"
-				EnableIntrinsicFunctions="TRUE"
-				FavorSizeOrSpeed="1"
-				OmitFramePointers="TRUE"
-				OptimizeForProcessor="3"
-				AdditionalIncludeDirectories="Source;Source\ZLib;Source\DeprecationManager;Source\OpenEXR\Half;Source\OpenEXR\Iex;Source\OpenEXR\IlmImf;Source\OpenEXR\Imath;Source\OpenEXR\IlmThread"
-				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;OPJ_STATIC;LIBRAW_NODLL;FREEIMAGE_EXPORTS;_SECURE_NO_DEPRECATE"
-				StringPooling="TRUE"
-				RuntimeLibrary="0"
-				BufferSecurityCheck="FALSE"
-				TreatWChar_tAsBuiltInType="TRUE"
-				PrecompiledHeaderFile=".\Release/FreeImage.pch"
-				AssemblerListingLocation=".\Release/"
-				ObjectFile=".\Release/"
-				ProgramDataBaseFileName=".\Release/"
-				WarningLevel="3"
-				SuppressStartupBanner="TRUE"
-				CompileAs="2"/>
-			<Tool
-				Name="VCCustomBuildTool"/>
-			<Tool
-				Name="VCLinkerTool"
-				OutputFile=".\Release/FreeImage.dll"
-				LinkIncremental="1"
-				SuppressStartupBanner="TRUE"
-				ProgramDatabaseFile=".\Release/FreeImage.pdb"
-				ImportLibrary=".\Release/FreeImage.lib"
-				TargetMachine="1"/>
-			<Tool
-				Name="VCMIDLTool"
-				PreprocessorDefinitions="NDEBUG"
-				MkTypLibCompatible="TRUE"
-				SuppressStartupBanner="TRUE"
-				TargetEnvironment="1"
-				TypeLibraryName=".\Release/FreeImage.tlb"
-				HeaderFileName=""/>
-			<Tool
-				Name="VCPostBuildEventTool"
-				CommandLine="copy Release\FreeImage.dll Dist
-copy Release\FreeImage.lib Dist
-copy Source\FreeImage.h Dist
-"/>
-			<Tool
-				Name="VCPreBuildEventTool"/>
-			<Tool
-				Name="VCPreLinkEventTool"/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="1033"/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"/>
-			<Tool
-				Name="VCWebDeploymentTool"/>
-			<Tool
-				Name="VCManagedWrapperGeneratorTool"/>
-			<Tool
-				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
-		</Configuration>
-		<Configuration
-			Name="Debug|Win32"
-			OutputDirectory=".\Debug"
-			IntermediateDirectory=".\Debug"
-			ConfigurationType="2"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="FALSE"
-			CharacterSet="2">
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="0"
-				AdditionalIncludeDirectories="Source;Source\ZLib;Source\DeprecationManager;Source\OpenEXR\Half;Source\OpenEXR\Iex;Source\OpenEXR\IlmImf;Source\OpenEXR\Imath;Source\OpenEXR\IlmThread"
-				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;OPJ_STATIC;FREEIMAGE_EXPORTS;_SECURE_NO_DEPRECATE;LIBRAW_NODLL"
-				StringPooling="TRUE"
-				BasicRuntimeChecks="3"
-				RuntimeLibrary="1"
-				TreatWChar_tAsBuiltInType="TRUE"
-				PrecompiledHeaderFile=""
-				AssemblerListingLocation=".\Debug/"
-				ObjectFile=".\Debug/"
-				ProgramDataBaseFileName=".\Debug/"
-				WarningLevel="3"
-				SuppressStartupBanner="TRUE"
-				DebugInformationFormat="4"
-				CompileAs="2"/>
-			<Tool
-				Name="VCCustomBuildTool"/>
-			<Tool
-				Name="VCLinkerTool"
-				OutputFile="Debug/FreeImaged.dll"
-				LinkIncremental="2"
-				SuppressStartupBanner="TRUE"
-				GenerateDebugInformation="TRUE"
-				ProgramDatabaseFile=".\Debug/FreeImaged.pdb"
-				ImportLibrary=".\Debug/FreeImaged.lib"
-				TargetMachine="1"/>
-			<Tool
-				Name="VCMIDLTool"
-				PreprocessorDefinitions="_DEBUG"
-				MkTypLibCompatible="TRUE"
-				SuppressStartupBanner="TRUE"
-				TargetEnvironment="1"
-				TypeLibraryName=".\Debug/FreeImage.tlb"
-				HeaderFileName=""/>
-			<Tool
-				Name="VCPostBuildEventTool"
-				CommandLine="copy Debug\FreeImaged.dll Dist
-copy Debug\FreeImaged.lib Dist
-copy Source\FreeImage.h Dist
-"/>
-			<Tool
-				Name="VCPreBuildEventTool"/>
-			<Tool
-				Name="VCPreLinkEventTool"/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="_DEBUG"
-				Culture="1033"/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"/>
-			<Tool
-				Name="VCWebDeploymentTool"/>
-			<Tool
-				Name="VCManagedWrapperGeneratorTool"/>
-			<Tool
-				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Source Files"
-			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
-			<File
-				RelativePath="Source\FreeImage\BitmapAccess.cpp">
-			</File>
-			<File
-				RelativePath="Source\FreeImage\ColorLookup.cpp">
-			</File>
-			<File
-				RelativePath="Source\FreeImage\FreeImage.cpp">
-			</File>
-			<File
-				RelativePath="FreeImage.rc">
-			</File>
-			<File
-				RelativePath="Source\FreeImage\FreeImageC.c">
-			</File>
-			<File
-				RelativePath="Source\FreeImage\FreeImageIO.cpp">
-			</File>
-			<File
-				RelativePath="Source\FreeImage\GetType.cpp">
-			</File>
-			<File
-				RelativePath="Source\FreeImage\MemoryIO.cpp">
-			</File>
-			<File
-				RelativePath="Source\FreeImage\PixelAccess.cpp">
-			</File>
-			<Filter
-				Name="Plugins"
-				Filter="">
-				<File
-					RelativePath=".\Source\FreeImage\J2KHelper.cpp">
-				</File>
-				<File
-					RelativePath=".\Source\FreeImage\MNGHelper.cpp">
-				</File>
-				<File
-					RelativePath="Source\FreeImage\Plugin.cpp">
-				</File>
-				<File
-					RelativePath="Source\FreeImage\PluginBMP.cpp">
-				</File>
-				<File
-					RelativePath="Source\FreeImage\PluginCUT.cpp">
-				</File>
-				<File
-					RelativePath="Source\FreeImage\PluginDDS.cpp">
-				</File>
-				<File
-					RelativePath=".\Source\FreeImage\PluginEXR.cpp">
-				</File>
-				<File
-					RelativePath="Source\FreeImage\PluginG3.cpp">
-				</File>
-				<File
-					RelativePath="Source\FreeImage\PluginGIF.cpp">
-				</File>
-				<File
-					RelativePath="Source\FreeImage\PluginHDR.cpp">
-				</File>
-				<File
-					RelativePath="Source\FreeImage\PluginICO.cpp">
-				</File>
-				<File
-					RelativePath="Source\FreeImage\PluginIFF.cpp">
-				</File>
-				<File
-					RelativePath=".\Source\FreeImage\PluginJ2K.cpp">
-				</File>
-				<File
-					RelativePath=".\Source\FreeImage\PluginJNG.cpp">
-				</File>
-				<File
-					RelativePath=".\Source\FreeImage\PluginJP2.cpp">
-				</File>
-				<File
-					RelativePath="Source\FreeImage\PluginJPEG.cpp">
-				</File>
-				<File
-					RelativePath="Source\FreeImage\PluginKOALA.cpp">
-				</File>
-				<File
-					RelativePath="Source\FreeImage\PluginMNG.cpp">
-				</File>
-				<File
-					RelativePath="Source\FreeImage\PluginPCD.cpp">
-				</File>
-				<File
-					RelativePath="Source\FreeImage\PluginPCX.cpp">
-				</File>
-				<File
-					RelativePath=".\Source\FreeImage\PluginPFM.cpp">
-				</File>
-				<File
-					RelativePath=".\Source\FreeImage\PluginPICT.cpp">
-				</File>
-				<File
-					RelativePath="Source\FreeImage\PluginPNG.cpp">
-				</File>
-				<File
-					RelativePath="Source\FreeImage\PluginPNM.cpp">
-				</File>
-				<File
-					RelativePath="Source\FreeImage\PluginPSD.cpp">
-				</File>
-				<File
-					RelativePath="Source\FreeImage\PluginRAS.cpp">
-				</File>
-				<File
-					RelativePath=".\Source\FreeImage\PluginRAW.cpp">
-				</File>
-				<File
-					RelativePath="Source\FreeImage\PluginSGI.cpp">
-				</File>
-				<File
-					RelativePath="Source\FreeImage\PluginTARGA.cpp">
-				</File>
-				<File
-					RelativePath="Source\FreeImage\PluginTIFF.cpp">
-				</File>
-				<File
-					RelativePath="Source\FreeImage\PluginWBMP.cpp">
-				</File>
-				<File
-					RelativePath="Source\FreeImage\PluginXBM.cpp">
-				</File>
-				<File
-					RelativePath="Source\FreeImage\PluginXPM.cpp">
-				</File>
-				<File
-					RelativePath=".\Source\FreeImage\PSDParser.cpp">
-				</File>
-				<File
-					RelativePath=".\Source\FreeImage\TIFFLogLuv.cpp">
-				</File>
-			</Filter>
-			<Filter
-				Name="Conversion"
-				Filter="">
-				<File
-					RelativePath="Source\FreeImage\Conversion.cpp">
-				</File>
-				<File
-					RelativePath="Source\FreeImage\Conversion16_555.cpp">
-				</File>
-				<File
-					RelativePath="Source\FreeImage\Conversion16_565.cpp">
-				</File>
-				<File
-					RelativePath="Source\FreeImage\Conversion24.cpp">
-				</File>
-				<File
-					RelativePath="Source\FreeImage\Conversion32.cpp">
-				</File>
-				<File
-					RelativePath="Source\FreeImage\Conversion4.cpp">
-				</File>
-				<File
-					RelativePath="Source\FreeImage\Conversion8.cpp">
-				</File>
-				<File
-					RelativePath=".\Source\FreeImage\ConversionFloat.cpp">
-				</File>
-				<File
-					RelativePath=".\Source\FreeImage\ConversionRGB16.cpp">
-				</File>
-				<File
-					RelativePath="Source\FreeImage\ConversionRGBF.cpp">
-				</File>
-				<File
-					RelativePath="Source\FreeImage\ConversionType.cpp">
-				</File>
-				<File
-					RelativePath=".\Source\FreeImage\ConversionUINT16.cpp">
-				</File>
-				<File
-					RelativePath="Source\FreeImage\Halftoning.cpp">
-				</File>
-				<File
-					RelativePath="Source\FreeImage\tmoColorConvert.cpp">
-				</File>
-				<File
-					RelativePath="Source\FreeImage\tmoDrago03.cpp">
-				</File>
-				<File
-					RelativePath=".\Source\FreeImage\tmoFattal02.cpp">
-				</File>
-				<File
-					RelativePath="Source\FreeImage\tmoReinhard05.cpp">
-				</File>
-				<File
-					RelativePath="Source\FreeImage\ToneMapping.cpp">
-				</File>
-			</Filter>
-			<Filter
-				Name="Quantizers"
-				Filter="">
-				<File
-					RelativePath="Source\FreeImage\NNQuantizer.cpp">
-				</File>
-				<File
-					RelativePath="Source\FreeImage\WuQuantizer.cpp">
-				</File>
-			</Filter>
-			<Filter
-				Name="DeprecationMgr"
-				Filter="">
-				<File
-					RelativePath=".\Source\DeprecationManager\Deprecated.cpp">
-				</File>
-				<File
-					RelativePath="Source\DeprecationManager\DeprecationMgr.cpp">
-				</File>
-			</Filter>
-			<Filter
-				Name="MultiPaging"
-				Filter="">
-				<File
-					RelativePath="Source\FreeImage\CacheFile.cpp">
-				</File>
-				<File
-					RelativePath="Source\FreeImage\MultiPage.cpp">
-				</File>
-				<File
-					RelativePath="Source\FreeImage\ZLibInterface.cpp">
-				</File>
-			</Filter>
-			<Filter
-				Name="Metadata"
-				Filter="">
-				<File
-					RelativePath="Source\Metadata\Exif.cpp">
-				</File>
-				<File
-					RelativePath="Source\Metadata\FIRational.cpp">
-				</File>
-				<File
-					RelativePath="Source\Metadata\FreeImageTag.cpp">
-				</File>
-				<File
-					RelativePath="Source\Metadata\IPTC.cpp">
-				</File>
-				<File
-					RelativePath="Source\Metadata\TagConversion.cpp">
-				</File>
-				<File
-					RelativePath="Source\Metadata\TagLib.cpp">
-				</File>
-				<File
-					RelativePath="Source\Metadata\XTIFF.cpp">
-				</File>
-			</Filter>
-		</Filter>
-		<Filter
-			Name="Header Files"
-			Filter="h;hpp;hxx;hm;inl">
-			<File
-				RelativePath="Source\CacheFile.h">
-			</File>
-			<File
-				RelativePath="Source\DeprecationManager\DeprecationMgr.h">
-			</File>
-			<File
-				RelativePath="Source\Metadata\FIRational.h">
-			</File>
-			<File
-				RelativePath="Source\FreeImage.h">
-			</File>
-			<File
-				RelativePath="Source\FreeImageIO.h">
-			</File>
-			<File
-				RelativePath="Source\Metadata\FreeImageTag.h">
-			</File>
-			<File
-				RelativePath="Source\Plugin.h">
-			</File>
-			<File
-				RelativePath=".\Source\FreeImage\PSDParser.h">
-			</File>
-			<File
-				RelativePath="Source\Quantizers.h">
-			</File>
-			<File
-				RelativePath="Source\ToneMapping.h">
-			</File>
-			<File
-				RelativePath="Source\Utilities.h">
-			</File>
-		</Filter>
-		<Filter
-			Name="Toolkit Files"
-			Filter="">
-			<File
-				RelativePath=".\Source\FreeImageToolkit\Background.cpp">
-			</File>
-			<File
-				RelativePath="Source\FreeImageToolkit\BSplineRotate.cpp">
-			</File>
-			<File
-				RelativePath="Source\FreeImageToolkit\Channels.cpp">
-			</File>
-			<File
-				RelativePath="Source\FreeImageToolkit\ClassicRotate.cpp">
-			</File>
-			<File
-				RelativePath="Source\FreeImageToolkit\Colors.cpp">
-			</File>
-			<File
-				RelativePath="Source\FreeImageToolkit\CopyPaste.cpp">
-			</File>
-			<File
-				RelativePath="Source\FreeImageToolkit\Display.cpp">
-			</File>
-			<File
-				RelativePath="Source\FreeImageToolkit\Flip.cpp">
-			</File>
-			<File
-				RelativePath="Source\FreeImageToolkit\JPEGTransform.cpp">
-			</File>
-			<File
-				RelativePath=".\Source\FreeImageToolkit\MultigridPoissonSolver.cpp">
-			</File>
-			<File
-				RelativePath="Source\FreeImageToolkit\Rescale.cpp">
-			</File>
-			<File
-				RelativePath="Source\FreeImageToolkit\Resize.cpp">
-			</File>
-			<File
-				RelativePath="Source\FreeImageToolkit\Resize.h">
-			</File>
-		</Filter>
-		<File
-			RelativePath="Todo.txt">
-		</File>
-		<File
-			RelativePath="Whatsnew.txt">
-		</File>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
diff --git a/FreeImage.2005.sln b/FreeImage.2005.sln
index bfb1429..25f6dc0 100644
--- a/FreeImage.2005.sln
+++ b/FreeImage.2005.sln
@@ -2,24 +2,27 @@ Microsoft Visual Studio Solution File, Format Version 9.00
 # Visual Studio 2005
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeImage", "FreeImage.2005.vcproj", "{B39ED2B3-D53A-4077-B957-930979A3577D}"
 	ProjectSection(ProjectDependencies) = postProject
+		{07F662C1-1323-42AB-B6AF-FBFD34A7437A} = {07F662C1-1323-42AB-B6AF-FBFD34A7437A}
+		{1B021BC6-301D-4FBA-96FF-2A73EE32FBD8} = {1B021BC6-301D-4FBA-96FF-2A73EE32FBD8}
+		{E3536C28-A7F1-4B53-8E52-7D2232F9E098} = {E3536C28-A7F1-4B53-8E52-7D2232F9E098}
+		{097D9F6C-FD0E-4CBC-9676-009012AAECA8} = {097D9F6C-FD0E-4CBC-9676-009012AAECA8}
 		{FCDC055C-2E28-4A2B-AF01-B8874B8951FA} = {FCDC055C-2E28-4A2B-AF01-B8874B8951FA}
 		{17A4874B-0606-4687-90B6-F91F8CB3B8AF} = {17A4874B-0606-4687-90B6-F91F8CB3B8AF}
 		{7DB10B50-CE00-4D7A-B322-6824F05D2FCB} = {7DB10B50-CE00-4D7A-B322-6824F05D2FCB}
 		{5E1D4E5F-E10C-4BA3-B663-F33014FD21D9} = {5E1D4E5F-E10C-4BA3-B663-F33014FD21D9}
 		{33134F61-C1AD-4B6F-9CEA-503A9F140C52} = {33134F61-C1AD-4B6F-9CEA-503A9F140C52}
-		{07F662C1-1323-42AB-B6AF-FBFD34A7437A} = {07F662C1-1323-42AB-B6AF-FBFD34A7437A}
-		{E3536C28-A7F1-4B53-8E52-7D2232F9E098} = {E3536C28-A7F1-4B53-8E52-7D2232F9E098}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeImageLib", "Source\FreeImageLib\FreeImageLib.2005.vcproj", "{9E219DF2-315D-478E-8A07-8960C377CE1E}"
 	ProjectSection(ProjectDependencies) = postProject
+		{E3536C28-A7F1-4B53-8E52-7D2232F9E098} = {E3536C28-A7F1-4B53-8E52-7D2232F9E098}
+		{097D9F6C-FD0E-4CBC-9676-009012AAECA8} = {097D9F6C-FD0E-4CBC-9676-009012AAECA8}
 		{FCDC055C-2E28-4A2B-AF01-B8874B8951FA} = {FCDC055C-2E28-4A2B-AF01-B8874B8951FA}
 		{17A4874B-0606-4687-90B6-F91F8CB3B8AF} = {17A4874B-0606-4687-90B6-F91F8CB3B8AF}
 		{7DB10B50-CE00-4D7A-B322-6824F05D2FCB} = {7DB10B50-CE00-4D7A-B322-6824F05D2FCB}
 		{5E1D4E5F-E10C-4BA3-B663-F33014FD21D9} = {5E1D4E5F-E10C-4BA3-B663-F33014FD21D9}
 		{33134F61-C1AD-4B6F-9CEA-503A9F140C52} = {33134F61-C1AD-4B6F-9CEA-503A9F140C52}
 		{07F662C1-1323-42AB-B6AF-FBFD34A7437A} = {07F662C1-1323-42AB-B6AF-FBFD34A7437A}
-		{E3536C28-A7F1-4B53-8E52-7D2232F9E098} = {E3536C28-A7F1-4B53-8E52-7D2232F9E098}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeImagePlus", "Wrapper\FreeImagePlus\FreeImagePlus.2005.vcproj", "{94F36908-A4E2-4533-939D-64FF6EADA5A1}"
@@ -30,10 +33,16 @@ EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibJPEG", "Source\LibJPEG\LibJPEG.2005.vcproj", "{5E1D4E5F-E10C-4BA3-B663-F33014FD21D9}"
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibPNG", "Source\LibPNG\LibPNG.2005.vcproj", "{7DB10B50-CE00-4D7A-B322-6824F05D2FCB}"
+	ProjectSection(ProjectDependencies) = postProject
+		{33134F61-C1AD-4B6F-9CEA-503A9F140C52} = {33134F61-C1AD-4B6F-9CEA-503A9F140C52}
+	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZLib", "Source\ZLib\ZLib.2005.vcproj", "{33134F61-C1AD-4B6F-9CEA-503A9F140C52}"
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OpenEXR", "Source\OpenEXR\OpenEXR.2005.vcproj", "{17A4874B-0606-4687-90B6-F91F8CB3B8AF}"
+	ProjectSection(ProjectDependencies) = postProject
+		{33134F61-C1AD-4B6F-9CEA-503A9F140C52} = {33134F61-C1AD-4B6F-9CEA-503A9F140C52}
+	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibOpenJPEG", "Source\LibOpenJPEG\LibOpenJPEG.2005.vcproj", "{E3536C28-A7F1-4B53-8E52-7D2232F9E098}"
 EndProject
@@ -43,91 +52,67 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibRawLite", "Source\LibRaw
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibTIFF4", "Source\LibTIFF4\LibTIFF4.2005.vcproj", "{FCDC055C-2E28-4A2B-AF01-B8874B8951FA}"
+	ProjectSection(ProjectDependencies) = postProject
+		{33134F61-C1AD-4B6F-9CEA-503A9F140C52} = {33134F61-C1AD-4B6F-9CEA-503A9F140C52}
+		{5E1D4E5F-E10C-4BA3-B663-F33014FD21D9} = {5E1D4E5F-E10C-4BA3-B663-F33014FD21D9}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibWebP", "Source\LibWebP\LibWebP.2005.vcproj", "{097D9F6C-FD0E-4CBC-9676-009012AAECA8}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibJXR", "Source\LibJXR\LibJXR.2005.vcproj", "{1B021BC6-301D-4FBA-96FF-2A73EE32FBD8}"
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Win32 = Debug|Win32
-		Debug|x64 = Debug|x64
 		Release|Win32 = Release|Win32
-		Release|x64 = Release|x64
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
 		{B39ED2B3-D53A-4077-B957-930979A3577D}.Debug|Win32.ActiveCfg = Debug|Win32
 		{B39ED2B3-D53A-4077-B957-930979A3577D}.Debug|Win32.Build.0 = Debug|Win32
-		{B39ED2B3-D53A-4077-B957-930979A3577D}.Debug|x64.ActiveCfg = Debug|x64
-		{B39ED2B3-D53A-4077-B957-930979A3577D}.Debug|x64.Build.0 = Debug|x64
 		{B39ED2B3-D53A-4077-B957-930979A3577D}.Release|Win32.ActiveCfg = Release|Win32
 		{B39ED2B3-D53A-4077-B957-930979A3577D}.Release|Win32.Build.0 = Release|Win32
-		{B39ED2B3-D53A-4077-B957-930979A3577D}.Release|x64.ActiveCfg = Release|x64
-		{B39ED2B3-D53A-4077-B957-930979A3577D}.Release|x64.Build.0 = Release|x64
 		{9E219DF2-315D-478E-8A07-8960C377CE1E}.Debug|Win32.ActiveCfg = Debug|Win32
-		{9E219DF2-315D-478E-8A07-8960C377CE1E}.Debug|x64.ActiveCfg = Debug|x64
 		{9E219DF2-315D-478E-8A07-8960C377CE1E}.Release|Win32.ActiveCfg = Release|Win32
-		{9E219DF2-315D-478E-8A07-8960C377CE1E}.Release|x64.ActiveCfg = Release|x64
 		{94F36908-A4E2-4533-939D-64FF6EADA5A1}.Debug|Win32.ActiveCfg = Debug|Win32
 		{94F36908-A4E2-4533-939D-64FF6EADA5A1}.Debug|Win32.Build.0 = Debug|Win32
-		{94F36908-A4E2-4533-939D-64FF6EADA5A1}.Debug|x64.ActiveCfg = Debug|x64
-		{94F36908-A4E2-4533-939D-64FF6EADA5A1}.Debug|x64.Build.0 = Debug|x64
 		{94F36908-A4E2-4533-939D-64FF6EADA5A1}.Release|Win32.ActiveCfg = Release|Win32
 		{94F36908-A4E2-4533-939D-64FF6EADA5A1}.Release|Win32.Build.0 = Release|Win32
-		{94F36908-A4E2-4533-939D-64FF6EADA5A1}.Release|x64.ActiveCfg = Release|x64
-		{94F36908-A4E2-4533-939D-64FF6EADA5A1}.Release|x64.Build.0 = Release|x64
 		{5E1D4E5F-E10C-4BA3-B663-F33014FD21D9}.Debug|Win32.ActiveCfg = Debug|Win32
 		{5E1D4E5F-E10C-4BA3-B663-F33014FD21D9}.Debug|Win32.Build.0 = Debug|Win32
-		{5E1D4E5F-E10C-4BA3-B663-F33014FD21D9}.Debug|x64.ActiveCfg = Debug|x64
-		{5E1D4E5F-E10C-4BA3-B663-F33014FD21D9}.Debug|x64.Build.0 = Debug|x64
 		{5E1D4E5F-E10C-4BA3-B663-F33014FD21D9}.Release|Win32.ActiveCfg = Release|Win32
 		{5E1D4E5F-E10C-4BA3-B663-F33014FD21D9}.Release|Win32.Build.0 = Release|Win32
-		{5E1D4E5F-E10C-4BA3-B663-F33014FD21D9}.Release|x64.ActiveCfg = Release|x64
-		{5E1D4E5F-E10C-4BA3-B663-F33014FD21D9}.Release|x64.Build.0 = Release|x64
 		{7DB10B50-CE00-4D7A-B322-6824F05D2FCB}.Debug|Win32.ActiveCfg = Debug|Win32
 		{7DB10B50-CE00-4D7A-B322-6824F05D2FCB}.Debug|Win32.Build.0 = Debug|Win32
-		{7DB10B50-CE00-4D7A-B322-6824F05D2FCB}.Debug|x64.ActiveCfg = Debug|x64
-		{7DB10B50-CE00-4D7A-B322-6824F05D2FCB}.Debug|x64.Build.0 = Debug|x64
 		{7DB10B50-CE00-4D7A-B322-6824F05D2FCB}.Release|Win32.ActiveCfg = Release|Win32
 		{7DB10B50-CE00-4D7A-B322-6824F05D2FCB}.Release|Win32.Build.0 = Release|Win32
-		{7DB10B50-CE00-4D7A-B322-6824F05D2FCB}.Release|x64.ActiveCfg = Release|x64
-		{7DB10B50-CE00-4D7A-B322-6824F05D2FCB}.Release|x64.Build.0 = Release|x64
 		{33134F61-C1AD-4B6F-9CEA-503A9F140C52}.Debug|Win32.ActiveCfg = Debug|Win32
 		{33134F61-C1AD-4B6F-9CEA-503A9F140C52}.Debug|Win32.Build.0 = Debug|Win32
-		{33134F61-C1AD-4B6F-9CEA-503A9F140C52}.Debug|x64.ActiveCfg = Debug|x64
-		{33134F61-C1AD-4B6F-9CEA-503A9F140C52}.Debug|x64.Build.0 = Debug|x64
 		{33134F61-C1AD-4B6F-9CEA-503A9F140C52}.Release|Win32.ActiveCfg = Release|Win32
 		{33134F61-C1AD-4B6F-9CEA-503A9F140C52}.Release|Win32.Build.0 = Release|Win32
-		{33134F61-C1AD-4B6F-9CEA-503A9F140C52}.Release|x64.ActiveCfg = Release|x64
-		{33134F61-C1AD-4B6F-9CEA-503A9F140C52}.Release|x64.Build.0 = Release|x64
 		{17A4874B-0606-4687-90B6-F91F8CB3B8AF}.Debug|Win32.ActiveCfg = Debug|Win32
 		{17A4874B-0606-4687-90B6-F91F8CB3B8AF}.Debug|Win32.Build.0 = Debug|Win32
-		{17A4874B-0606-4687-90B6-F91F8CB3B8AF}.Debug|x64.ActiveCfg = Debug|x64
-		{17A4874B-0606-4687-90B6-F91F8CB3B8AF}.Debug|x64.Build.0 = Debug|x64
 		{17A4874B-0606-4687-90B6-F91F8CB3B8AF}.Release|Win32.ActiveCfg = Release|Win32
 		{17A4874B-0606-4687-90B6-F91F8CB3B8AF}.Release|Win32.Build.0 = Release|Win32
-		{17A4874B-0606-4687-90B6-F91F8CB3B8AF}.Release|x64.ActiveCfg = Release|x64
-		{17A4874B-0606-4687-90B6-F91F8CB3B8AF}.Release|x64.Build.0 = Release|x64
 		{E3536C28-A7F1-4B53-8E52-7D2232F9E098}.Debug|Win32.ActiveCfg = Debug|Win32
 		{E3536C28-A7F1-4B53-8E52-7D2232F9E098}.Debug|Win32.Build.0 = Debug|Win32
-		{E3536C28-A7F1-4B53-8E52-7D2232F9E098}.Debug|x64.ActiveCfg = Debug|x64
-		{E3536C28-A7F1-4B53-8E52-7D2232F9E098}.Debug|x64.Build.0 = Debug|x64
 		{E3536C28-A7F1-4B53-8E52-7D2232F9E098}.Release|Win32.ActiveCfg = Release|Win32
 		{E3536C28-A7F1-4B53-8E52-7D2232F9E098}.Release|Win32.Build.0 = Release|Win32
-		{E3536C28-A7F1-4B53-8E52-7D2232F9E098}.Release|x64.ActiveCfg = Release|x64
-		{E3536C28-A7F1-4B53-8E52-7D2232F9E098}.Release|x64.Build.0 = Release|x64
 		{07F662C1-1323-42AB-B6AF-FBFD34A7437A}.Debug|Win32.ActiveCfg = Debug|Win32
 		{07F662C1-1323-42AB-B6AF-FBFD34A7437A}.Debug|Win32.Build.0 = Debug|Win32
-		{07F662C1-1323-42AB-B6AF-FBFD34A7437A}.Debug|x64.ActiveCfg = Debug|x64
-		{07F662C1-1323-42AB-B6AF-FBFD34A7437A}.Debug|x64.Build.0 = Debug|x64
 		{07F662C1-1323-42AB-B6AF-FBFD34A7437A}.Release|Win32.ActiveCfg = Release|Win32
 		{07F662C1-1323-42AB-B6AF-FBFD34A7437A}.Release|Win32.Build.0 = Release|Win32
-		{07F662C1-1323-42AB-B6AF-FBFD34A7437A}.Release|x64.ActiveCfg = Release|x64
-		{07F662C1-1323-42AB-B6AF-FBFD34A7437A}.Release|x64.Build.0 = Release|x64
 		{FCDC055C-2E28-4A2B-AF01-B8874B8951FA}.Debug|Win32.ActiveCfg = Debug|Win32
 		{FCDC055C-2E28-4A2B-AF01-B8874B8951FA}.Debug|Win32.Build.0 = Debug|Win32
-		{FCDC055C-2E28-4A2B-AF01-B8874B8951FA}.Debug|x64.ActiveCfg = Debug|x64
-		{FCDC055C-2E28-4A2B-AF01-B8874B8951FA}.Debug|x64.Build.0 = Debug|x64
 		{FCDC055C-2E28-4A2B-AF01-B8874B8951FA}.Release|Win32.ActiveCfg = Release|Win32
 		{FCDC055C-2E28-4A2B-AF01-B8874B8951FA}.Release|Win32.Build.0 = Release|Win32
-		{FCDC055C-2E28-4A2B-AF01-B8874B8951FA}.Release|x64.ActiveCfg = Release|x64
-		{FCDC055C-2E28-4A2B-AF01-B8874B8951FA}.Release|x64.Build.0 = Release|x64
+		{097D9F6C-FD0E-4CBC-9676-009012AAECA8}.Debug|Win32.ActiveCfg = Debug|Win32
+		{097D9F6C-FD0E-4CBC-9676-009012AAECA8}.Debug|Win32.Build.0 = Debug|Win32
+		{097D9F6C-FD0E-4CBC-9676-009012AAECA8}.Release|Win32.ActiveCfg = Release|Win32
+		{097D9F6C-FD0E-4CBC-9676-009012AAECA8}.Release|Win32.Build.0 = Release|Win32
+		{1B021BC6-301D-4FBA-96FF-2A73EE32FBD8}.Debug|Win32.ActiveCfg = Debug|Win32
+		{1B021BC6-301D-4FBA-96FF-2A73EE32FBD8}.Debug|Win32.Build.0 = Debug|Win32
+		{1B021BC6-301D-4FBA-96FF-2A73EE32FBD8}.Release|Win32.ActiveCfg = Release|Win32
+		{1B021BC6-301D-4FBA-96FF-2A73EE32FBD8}.Release|Win32.Build.0 = Release|Win32
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
diff --git a/FreeImage.2005.vcproj b/FreeImage.2005.vcproj
index 23639d1..f328880 100644
--- a/FreeImage.2005.vcproj
+++ b/FreeImage.2005.vcproj
@@ -55,7 +55,7 @@
 				EnableIntrinsicFunctions="true"
 				FavorSizeOrSpeed="1"
 				OmitFramePointers="true"
-				AdditionalIncludeDirectories="Source;Source\ZLib;Source\DeprecationManager;Source\OpenEXR\Half;Source\OpenEXR\Iex;Source\OpenEXR\IlmImf;Source\OpenEXR\Imath;Source\OpenEXR\IlmThread"
+				AdditionalIncludeDirectories="Source;Source\ZLib;Source\DeprecationManager;Source\OpenEXR;Source\OpenEXR\Half;Source\OpenEXR\Iex;Source\OpenEXR\IlmImf;Source\OpenEXR\Imath;Source\OpenEXR\IlmThread;Source\LibJXR\image\sys;Source\LibJXR\jxrgluelib"
 				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;OPJ_STATIC;FREEIMAGE_EXPORTS;_CRT_SECURE_NO_DEPRECATE;LIBRAW_NODLL"
 				StringPooling="true"
 				RuntimeLibrary="0"
@@ -150,7 +150,7 @@
 			<Tool
 				Name="VCCLCompilerTool"
 				Optimization="0"
-				AdditionalIncludeDirectories="Source;Source\ZLib;Source\DeprecationManager;Source\OpenEXR\Half;Source\OpenEXR\Iex;Source\OpenEXR\IlmImf;Source\OpenEXR\Imath;Source\OpenEXR\IlmThread"
+				AdditionalIncludeDirectories="Source;Source\ZLib;Source\DeprecationManager;Source\OpenEXR;Source\OpenEXR\Half;Source\OpenEXR\Iex;Source\OpenEXR\IlmImf;Source\OpenEXR\Imath;Source\OpenEXR\IlmThread;Source\LibJXR\image\sys;Source\LibJXR\jxrgluelib"
 				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;OPJ_STATIC;FREEIMAGE_EXPORTS;_CRT_SECURE_NO_DEPRECATE;LIBRAW_NODLL"
 				StringPooling="true"
 				BasicRuntimeChecks="3"
@@ -519,6 +519,10 @@
 					>
 				</File>
 				<File
+					RelativePath=".\Source\FreeImage\PluginJXR.cpp"
+					>
+				</File>
+				<File
 					RelativePath="Source\FreeImage\PluginKOALA.cpp"
 					>
 				</File>
@@ -579,6 +583,10 @@
 					>
 				</File>
 				<File
+					RelativePath=".\Source\FreeImage\PluginWebP.cpp"
+					>
+				</File>
+				<File
 					RelativePath="Source\FreeImage\PluginXBM.cpp"
 					>
 				</File>
@@ -635,6 +643,14 @@
 					>
 				</File>
 				<File
+					RelativePath=".\Source\FreeImage\ConversionRGBA16.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\Source\FreeImage\ConversionRGBAF.cpp"
+					>
+				</File>
+				<File
 					RelativePath="Source\FreeImage\ConversionRGBF.cpp"
 					>
 				</File>
@@ -675,6 +691,10 @@
 				Name="Quantizers"
 				>
 				<File
+					RelativePath=".\Source\FreeImage\LFPQuantizer.cpp"
+					>
+				</File>
+				<File
 					RelativePath="Source\FreeImage\NNQuantizer.cpp"
 					>
 				</File>
@@ -773,6 +793,14 @@
 				>
 			</File>
 			<File
+				RelativePath=".\Source\FreeImage\J2KHelper.h"
+				>
+			</File>
+			<File
+				RelativePath=".\Source\MapIntrospector.h"
+				>
+			</File>
+			<File
 				RelativePath="Source\Plugin.h"
 				>
 			</File>
diff --git a/FreeImage.2008.sln b/FreeImage.2008.sln
index 41df3a4..fc4da85 100644
--- a/FreeImage.2008.sln
+++ b/FreeImage.2008.sln
@@ -7,8 +7,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeImage", "FreeImage.2008
 		{7DB10B50-CE00-4D7A-B322-6824F05D2FCB} = {7DB10B50-CE00-4D7A-B322-6824F05D2FCB}
 		{5E1D4E5F-E10C-4BA3-B663-F33014FD21D9} = {5E1D4E5F-E10C-4BA3-B663-F33014FD21D9}
 		{33134F61-C1AD-4B6F-9CEA-503A9F140C52} = {33134F61-C1AD-4B6F-9CEA-503A9F140C52}
+		{097D9F6C-FD0E-4CBC-9676-009012AAECA8} = {097D9F6C-FD0E-4CBC-9676-009012AAECA8}
 		{EC085CBD-E9C3-477F-9A97-CB9D5DA30E27} = {EC085CBD-E9C3-477F-9A97-CB9D5DA30E27}
 		{07F662C1-1323-42AB-B6AF-FBFD34A7437A} = {07F662C1-1323-42AB-B6AF-FBFD34A7437A}
+		{244455E0-5F25-4451-9540-F317883E52A8} = {244455E0-5F25-4451-9540-F317883E52A8}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeImageLib", "Source\FreeImageLib\FreeImageLib.2008.vcproj", "{9E219DF2-315D-478E-8A07-8960C377CE1E}"
@@ -18,8 +20,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeImageLib", "Source\Free
 		{7DB10B50-CE00-4D7A-B322-6824F05D2FCB} = {7DB10B50-CE00-4D7A-B322-6824F05D2FCB}
 		{5E1D4E5F-E10C-4BA3-B663-F33014FD21D9} = {5E1D4E5F-E10C-4BA3-B663-F33014FD21D9}
 		{33134F61-C1AD-4B6F-9CEA-503A9F140C52} = {33134F61-C1AD-4B6F-9CEA-503A9F140C52}
+		{097D9F6C-FD0E-4CBC-9676-009012AAECA8} = {097D9F6C-FD0E-4CBC-9676-009012AAECA8}
 		{EC085CBD-E9C3-477F-9A97-CB9D5DA30E27} = {EC085CBD-E9C3-477F-9A97-CB9D5DA30E27}
 		{07F662C1-1323-42AB-B6AF-FBFD34A7437A} = {07F662C1-1323-42AB-B6AF-FBFD34A7437A}
+		{244455E0-5F25-4451-9540-F317883E52A8} = {244455E0-5F25-4451-9540-F317883E52A8}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeImagePlus", "Wrapper\FreeImagePlus\FreeImagePlus.2008.vcproj", "{94F36908-A4E2-4533-939D-64FF6EADA5A1}"
@@ -54,6 +58,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibTIFF4", "Source\LibTIFF4
 		{33134F61-C1AD-4B6F-9CEA-503A9F140C52} = {33134F61-C1AD-4B6F-9CEA-503A9F140C52}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibWebP", "Source\LibWebP\LibWebP.2008.vcproj", "{097D9F6C-FD0E-4CBC-9676-009012AAECA8}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibJXR", "Source\LibJXR\LibJXR.2008.vcproj", "{244455E0-5F25-4451-9540-F317883E52A8}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Win32 = Debug|Win32
@@ -138,6 +146,22 @@ Global
 		{EC085CBD-E9C3-477F-9A97-CB9D5DA30E27}.Release|Win32.Build.0 = Release|Win32
 		{EC085CBD-E9C3-477F-9A97-CB9D5DA30E27}.Release|x64.ActiveCfg = Release|x64
 		{EC085CBD-E9C3-477F-9A97-CB9D5DA30E27}.Release|x64.Build.0 = Release|x64
+		{097D9F6C-FD0E-4CBC-9676-009012AAECA8}.Debug|Win32.ActiveCfg = Debug|Win32
+		{097D9F6C-FD0E-4CBC-9676-009012AAECA8}.Debug|Win32.Build.0 = Debug|Win32
+		{097D9F6C-FD0E-4CBC-9676-009012AAECA8}.Debug|x64.ActiveCfg = Debug|x64
+		{097D9F6C-FD0E-4CBC-9676-009012AAECA8}.Debug|x64.Build.0 = Debug|x64
+		{097D9F6C-FD0E-4CBC-9676-009012AAECA8}.Release|Win32.ActiveCfg = Release|Win32
+		{097D9F6C-FD0E-4CBC-9676-009012AAECA8}.Release|Win32.Build.0 = Release|Win32
+		{097D9F6C-FD0E-4CBC-9676-009012AAECA8}.Release|x64.ActiveCfg = Release|x64
+		{097D9F6C-FD0E-4CBC-9676-009012AAECA8}.Release|x64.Build.0 = Release|x64
+		{244455E0-5F25-4451-9540-F317883E52A8}.Debug|Win32.ActiveCfg = Debug|Win32
+		{244455E0-5F25-4451-9540-F317883E52A8}.Debug|Win32.Build.0 = Debug|Win32
+		{244455E0-5F25-4451-9540-F317883E52A8}.Debug|x64.ActiveCfg = Debug|x64
+		{244455E0-5F25-4451-9540-F317883E52A8}.Debug|x64.Build.0 = Debug|x64
+		{244455E0-5F25-4451-9540-F317883E52A8}.Release|Win32.ActiveCfg = Release|Win32
+		{244455E0-5F25-4451-9540-F317883E52A8}.Release|Win32.Build.0 = Release|Win32
+		{244455E0-5F25-4451-9540-F317883E52A8}.Release|x64.ActiveCfg = Release|x64
+		{244455E0-5F25-4451-9540-F317883E52A8}.Release|x64.Build.0 = Release|x64
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
diff --git a/FreeImage.2008.vcproj b/FreeImage.2008.vcproj
index babc751..536686e 100644
--- a/FreeImage.2008.vcproj
+++ b/FreeImage.2008.vcproj
@@ -57,7 +57,7 @@
 				FavorSizeOrSpeed="1"
 				OmitFramePointers="true"
 				WholeProgramOptimization="true"
-				AdditionalIncludeDirectories="Source;Source\ZLib;Source\DeprecationManager;Source\OpenEXR\Half;Source\OpenEXR\Iex;Source\OpenEXR\IlmImf;Source\OpenEXR\Imath;Source\OpenEXR\IlmThread"
+				AdditionalIncludeDirectories="Source;Source\ZLib;Source\DeprecationManager;Source\OpenEXR;Source\OpenEXR\Half;Source\OpenEXR\Iex;Source\OpenEXR\IlmImf;Source\OpenEXR\Imath;Source\OpenEXR\IlmThread;Source\LibJXR\jxrgluelib;Source\LibJXR\image\sys"
 				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;OPJ_STATIC;FREEIMAGE_EXPORTS;_CRT_SECURE_NO_DEPRECATE;LIBRAW_NODLL"
 				StringPooling="true"
 				RuntimeLibrary="0"
@@ -157,7 +157,7 @@
 				FavorSizeOrSpeed="1"
 				OmitFramePointers="true"
 				WholeProgramOptimization="true"
-				AdditionalIncludeDirectories="Source;Source\ZLib;Source\DeprecationManager;Source\OpenEXR\Half;Source\OpenEXR\Iex;Source\OpenEXR\IlmImf;Source\OpenEXR\Imath;Source\OpenEXR\IlmThread"
+				AdditionalIncludeDirectories="Source;Source\ZLib;Source\DeprecationManager;Source\OpenEXR;Source\OpenEXR\Half;Source\OpenEXR\Iex;Source\OpenEXR\IlmImf;Source\OpenEXR\Imath;Source\OpenEXR\IlmThread;Source\LibJXR\jxrgluelib;Source\LibJXR\image\sys"
 				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;OPJ_STATIC;FREEIMAGE_EXPORTS;_CRT_SECURE_NO_DEPRECATE;LIBRAW_NODLL"
 				StringPooling="true"
 				RuntimeLibrary="0"
@@ -253,7 +253,7 @@
 			<Tool
 				Name="VCCLCompilerTool"
 				Optimization="0"
-				AdditionalIncludeDirectories="Source;Source\ZLib;Source\DeprecationManager;Source\OpenEXR\Half;Source\OpenEXR\Iex;Source\OpenEXR\IlmImf;Source\OpenEXR\Imath;Source\OpenEXR\IlmThread"
+				AdditionalIncludeDirectories="Source;Source\ZLib;Source\DeprecationManager;Source\OpenEXR;Source\OpenEXR\Half;Source\OpenEXR\Iex;Source\OpenEXR\IlmImf;Source\OpenEXR\Imath;Source\OpenEXR\IlmThread;Source\LibJXR\jxrgluelib;Source\LibJXR\image\sys"
 				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;OPJ_STATIC;FREEIMAGE_EXPORTS;_CRT_SECURE_NO_DEPRECATE;LIBRAW_NODLL"
 				StringPooling="true"
 				BasicRuntimeChecks="3"
@@ -348,7 +348,7 @@
 			<Tool
 				Name="VCCLCompilerTool"
 				Optimization="0"
-				AdditionalIncludeDirectories="Source;Source\ZLib;Source\DeprecationManager;Source\OpenEXR\Half;Source\OpenEXR\Iex;Source\OpenEXR\IlmImf;Source\OpenEXR\Imath;Source\OpenEXR\IlmThread"
+				AdditionalIncludeDirectories="Source;Source\ZLib;Source\DeprecationManager;Source\OpenEXR;Source\OpenEXR\Half;Source\OpenEXR\Iex;Source\OpenEXR\IlmImf;Source\OpenEXR\Imath;Source\OpenEXR\IlmThread;Source\LibJXR\jxrgluelib;Source\LibJXR\image\sys"
 				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;OPJ_STATIC;FREEIMAGE_EXPORTS;_CRT_SECURE_NO_DEPRECATE;LIBRAW_NODLL"
 				StringPooling="true"
 				BasicRuntimeChecks="3"
@@ -522,6 +522,10 @@
 					>
 				</File>
 				<File
+					RelativePath=".\Source\FreeImage\PluginJXR.cpp"
+					>
+				</File>
+				<File
 					RelativePath="Source\FreeImage\PluginKOALA.cpp"
 					>
 				</File>
@@ -582,6 +586,10 @@
 					>
 				</File>
 				<File
+					RelativePath=".\Source\FreeImage\PluginWebP.cpp"
+					>
+				</File>
+				<File
 					RelativePath="Source\FreeImage\PluginXBM.cpp"
 					>
 				</File>
@@ -638,6 +646,14 @@
 					>
 				</File>
 				<File
+					RelativePath=".\Source\FreeImage\ConversionRGBA16.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\Source\FreeImage\ConversionRGBAF.cpp"
+					>
+				</File>
+				<File
 					RelativePath="Source\FreeImage\ConversionRGBF.cpp"
 					>
 				</File>
@@ -678,6 +694,10 @@
 				Name="Quantizers"
 				>
 				<File
+					RelativePath=".\Source\FreeImage\LFPQuantizer.cpp"
+					>
+				</File>
+				<File
 					RelativePath="Source\FreeImage\NNQuantizer.cpp"
 					>
 				</File>
@@ -776,6 +796,14 @@
 				>
 			</File>
 			<File
+				RelativePath=".\Source\FreeImage\J2KHelper.h"
+				>
+			</File>
+			<File
+				RelativePath=".\Source\MapIntrospector.h"
+				>
+			</File>
+			<File
 				RelativePath="Source\Plugin.h"
 				>
 			</File>
diff --git a/FreeImage.2013.sln b/FreeImage.2013.sln
new file mode 100644
index 0000000..48dcd5d
--- /dev/null
+++ b/FreeImage.2013.sln
@@ -0,0 +1,133 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Express 2013 for Windows Desktop
+VisualStudioVersion = 12.0.21005.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeImage", "FreeImage.2013.vcxproj", "{B39ED2B3-D53A-4077-B957-930979A3577D}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeImageLib", "Source\FreeImageLib\FreeImageLib.2013.vcxproj", "{9E219DF2-315D-478E-8A07-8960C377CE1E}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeImagePlus", "Wrapper\FreeImagePlus\FreeImagePlus.2013.vcxproj", "{94F36908-A4E2-4533-939D-64FF6EADA5A1}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibJPEG", "Source\LibJPEG\LibJPEG.2013.vcxproj", "{5E1D4E5F-E10C-4BA3-B663-F33014FD21D9}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibPNG", "Source\LibPNG\LibPNG.2013.vcxproj", "{7DB10B50-CE00-4D7A-B322-6824F05D2FCB}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZLib", "Source\ZLib\ZLib.2013.vcxproj", "{33134F61-C1AD-4B6F-9CEA-503A9F140C52}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OpenEXR", "Source\OpenEXR\OpenEXR.2013.vcxproj", "{17A4874B-0606-4687-90B6-F91F8CB3B8AF}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibOpenJPEG", "Source\LibOpenJPEG\LibOpenJPEG.2013.vcxproj", "{E3536C28-A7F1-4B53-8E52-7D2232F9E098}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibRaw", "Source\LibRawLite\LibRawLite.2013.vcxproj", "{07F662C1-1323-42AB-B6AF-FBFD34A7437A}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibTIFF4", "Source\LibTIFF4\LibTIFF4.2013.vcxproj", "{EC085CBD-E9C3-477F-9A97-CB9D5DA30E27}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibWebP", "Source\LibWebP\LibWebP.2013.vcxproj", "{097D9F6C-FD0E-4CBC-9676-009012AAECA8}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibJXR", "Source\LibJXR\LibJXR.2013.vcxproj", "{244455E0-5F25-4451-9540-F317883E52A8}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Debug|x64 = Debug|x64
+		Release|Win32 = Release|Win32
+		Release|x64 = Release|x64
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{B39ED2B3-D53A-4077-B957-930979A3577D}.Debug|Win32.ActiveCfg = Debug|Win32
+		{B39ED2B3-D53A-4077-B957-930979A3577D}.Debug|Win32.Build.0 = Debug|Win32
+		{B39ED2B3-D53A-4077-B957-930979A3577D}.Debug|x64.ActiveCfg = Debug|x64
+		{B39ED2B3-D53A-4077-B957-930979A3577D}.Debug|x64.Build.0 = Debug|x64
+		{B39ED2B3-D53A-4077-B957-930979A3577D}.Release|Win32.ActiveCfg = Release|Win32
+		{B39ED2B3-D53A-4077-B957-930979A3577D}.Release|Win32.Build.0 = Release|Win32
+		{B39ED2B3-D53A-4077-B957-930979A3577D}.Release|x64.ActiveCfg = Release|x64
+		{B39ED2B3-D53A-4077-B957-930979A3577D}.Release|x64.Build.0 = Release|x64
+		{9E219DF2-315D-478E-8A07-8960C377CE1E}.Debug|Win32.ActiveCfg = Debug|Win32
+		{9E219DF2-315D-478E-8A07-8960C377CE1E}.Debug|x64.ActiveCfg = Debug|x64
+		{9E219DF2-315D-478E-8A07-8960C377CE1E}.Release|Win32.ActiveCfg = Release|Win32
+		{9E219DF2-315D-478E-8A07-8960C377CE1E}.Release|x64.ActiveCfg = Release|x64
+		{94F36908-A4E2-4533-939D-64FF6EADA5A1}.Debug|Win32.ActiveCfg = Debug|Win32
+		{94F36908-A4E2-4533-939D-64FF6EADA5A1}.Debug|Win32.Build.0 = Debug|Win32
+		{94F36908-A4E2-4533-939D-64FF6EADA5A1}.Debug|x64.ActiveCfg = Debug|x64
+		{94F36908-A4E2-4533-939D-64FF6EADA5A1}.Debug|x64.Build.0 = Debug|x64
+		{94F36908-A4E2-4533-939D-64FF6EADA5A1}.Release|Win32.ActiveCfg = Release|Win32
+		{94F36908-A4E2-4533-939D-64FF6EADA5A1}.Release|Win32.Build.0 = Release|Win32
+		{94F36908-A4E2-4533-939D-64FF6EADA5A1}.Release|x64.ActiveCfg = Release|x64
+		{94F36908-A4E2-4533-939D-64FF6EADA5A1}.Release|x64.Build.0 = Release|x64
+		{5E1D4E5F-E10C-4BA3-B663-F33014FD21D9}.Debug|Win32.ActiveCfg = Debug|Win32
+		{5E1D4E5F-E10C-4BA3-B663-F33014FD21D9}.Debug|Win32.Build.0 = Debug|Win32
+		{5E1D4E5F-E10C-4BA3-B663-F33014FD21D9}.Debug|x64.ActiveCfg = Debug|x64
+		{5E1D4E5F-E10C-4BA3-B663-F33014FD21D9}.Debug|x64.Build.0 = Debug|x64
+		{5E1D4E5F-E10C-4BA3-B663-F33014FD21D9}.Release|Win32.ActiveCfg = Release|Win32
+		{5E1D4E5F-E10C-4BA3-B663-F33014FD21D9}.Release|Win32.Build.0 = Release|Win32
+		{5E1D4E5F-E10C-4BA3-B663-F33014FD21D9}.Release|x64.ActiveCfg = Release|x64
+		{5E1D4E5F-E10C-4BA3-B663-F33014FD21D9}.Release|x64.Build.0 = Release|x64
+		{7DB10B50-CE00-4D7A-B322-6824F05D2FCB}.Debug|Win32.ActiveCfg = Debug|Win32
+		{7DB10B50-CE00-4D7A-B322-6824F05D2FCB}.Debug|Win32.Build.0 = Debug|Win32
+		{7DB10B50-CE00-4D7A-B322-6824F05D2FCB}.Debug|x64.ActiveCfg = Debug|x64
+		{7DB10B50-CE00-4D7A-B322-6824F05D2FCB}.Debug|x64.Build.0 = Debug|x64
+		{7DB10B50-CE00-4D7A-B322-6824F05D2FCB}.Release|Win32.ActiveCfg = Release|Win32
+		{7DB10B50-CE00-4D7A-B322-6824F05D2FCB}.Release|Win32.Build.0 = Release|Win32
+		{7DB10B50-CE00-4D7A-B322-6824F05D2FCB}.Release|x64.ActiveCfg = Release|x64
+		{7DB10B50-CE00-4D7A-B322-6824F05D2FCB}.Release|x64.Build.0 = Release|x64
+		{33134F61-C1AD-4B6F-9CEA-503A9F140C52}.Debug|Win32.ActiveCfg = Debug|Win32
+		{33134F61-C1AD-4B6F-9CEA-503A9F140C52}.Debug|Win32.Build.0 = Debug|Win32
+		{33134F61-C1AD-4B6F-9CEA-503A9F140C52}.Debug|x64.ActiveCfg = Debug|x64
+		{33134F61-C1AD-4B6F-9CEA-503A9F140C52}.Debug|x64.Build.0 = Debug|x64
+		{33134F61-C1AD-4B6F-9CEA-503A9F140C52}.Release|Win32.ActiveCfg = Release|Win32
+		{33134F61-C1AD-4B6F-9CEA-503A9F140C52}.Release|Win32.Build.0 = Release|Win32
+		{33134F61-C1AD-4B6F-9CEA-503A9F140C52}.Release|x64.ActiveCfg = Release|x64
+		{33134F61-C1AD-4B6F-9CEA-503A9F140C52}.Release|x64.Build.0 = Release|x64
+		{17A4874B-0606-4687-90B6-F91F8CB3B8AF}.Debug|Win32.ActiveCfg = Debug|Win32
+		{17A4874B-0606-4687-90B6-F91F8CB3B8AF}.Debug|Win32.Build.0 = Debug|Win32
+		{17A4874B-0606-4687-90B6-F91F8CB3B8AF}.Debug|x64.ActiveCfg = Debug|x64
+		{17A4874B-0606-4687-90B6-F91F8CB3B8AF}.Debug|x64.Build.0 = Debug|x64
+		{17A4874B-0606-4687-90B6-F91F8CB3B8AF}.Release|Win32.ActiveCfg = Release|Win32
+		{17A4874B-0606-4687-90B6-F91F8CB3B8AF}.Release|Win32.Build.0 = Release|Win32
+		{17A4874B-0606-4687-90B6-F91F8CB3B8AF}.Release|x64.ActiveCfg = Release|x64
+		{17A4874B-0606-4687-90B6-F91F8CB3B8AF}.Release|x64.Build.0 = Release|x64
+		{E3536C28-A7F1-4B53-8E52-7D2232F9E098}.Debug|Win32.ActiveCfg = Debug|Win32
+		{E3536C28-A7F1-4B53-8E52-7D2232F9E098}.Debug|Win32.Build.0 = Debug|Win32
+		{E3536C28-A7F1-4B53-8E52-7D2232F9E098}.Debug|x64.ActiveCfg = Debug|x64
+		{E3536C28-A7F1-4B53-8E52-7D2232F9E098}.Debug|x64.Build.0 = Debug|x64
+		{E3536C28-A7F1-4B53-8E52-7D2232F9E098}.Release|Win32.ActiveCfg = Release|Win32
+		{E3536C28-A7F1-4B53-8E52-7D2232F9E098}.Release|Win32.Build.0 = Release|Win32
+		{E3536C28-A7F1-4B53-8E52-7D2232F9E098}.Release|x64.ActiveCfg = Release|x64
+		{E3536C28-A7F1-4B53-8E52-7D2232F9E098}.Release|x64.Build.0 = Release|x64
+		{07F662C1-1323-42AB-B6AF-FBFD34A7437A}.Debug|Win32.ActiveCfg = Debug|Win32
+		{07F662C1-1323-42AB-B6AF-FBFD34A7437A}.Debug|Win32.Build.0 = Debug|Win32
+		{07F662C1-1323-42AB-B6AF-FBFD34A7437A}.Debug|x64.ActiveCfg = Debug|x64
+		{07F662C1-1323-42AB-B6AF-FBFD34A7437A}.Debug|x64.Build.0 = Debug|x64
+		{07F662C1-1323-42AB-B6AF-FBFD34A7437A}.Release|Win32.ActiveCfg = Release|Win32
+		{07F662C1-1323-42AB-B6AF-FBFD34A7437A}.Release|Win32.Build.0 = Release|Win32
+		{07F662C1-1323-42AB-B6AF-FBFD34A7437A}.Release|x64.ActiveCfg = Release|x64
+		{07F662C1-1323-42AB-B6AF-FBFD34A7437A}.Release|x64.Build.0 = Release|x64
+		{EC085CBD-E9C3-477F-9A97-CB9D5DA30E27}.Debug|Win32.ActiveCfg = Debug|Win32
+		{EC085CBD-E9C3-477F-9A97-CB9D5DA30E27}.Debug|Win32.Build.0 = Debug|Win32
+		{EC085CBD-E9C3-477F-9A97-CB9D5DA30E27}.Debug|x64.ActiveCfg = Debug|x64
+		{EC085CBD-E9C3-477F-9A97-CB9D5DA30E27}.Debug|x64.Build.0 = Debug|x64
+		{EC085CBD-E9C3-477F-9A97-CB9D5DA30E27}.Release|Win32.ActiveCfg = Release|Win32
+		{EC085CBD-E9C3-477F-9A97-CB9D5DA30E27}.Release|Win32.Build.0 = Release|Win32
+		{EC085CBD-E9C3-477F-9A97-CB9D5DA30E27}.Release|x64.ActiveCfg = Release|x64
+		{EC085CBD-E9C3-477F-9A97-CB9D5DA30E27}.Release|x64.Build.0 = Release|x64
+		{097D9F6C-FD0E-4CBC-9676-009012AAECA8}.Debug|Win32.ActiveCfg = Debug|Win32
+		{097D9F6C-FD0E-4CBC-9676-009012AAECA8}.Debug|Win32.Build.0 = Debug|Win32
+		{097D9F6C-FD0E-4CBC-9676-009012AAECA8}.Debug|x64.ActiveCfg = Debug|x64
+		{097D9F6C-FD0E-4CBC-9676-009012AAECA8}.Debug|x64.Build.0 = Debug|x64
+		{097D9F6C-FD0E-4CBC-9676-009012AAECA8}.Release|Win32.ActiveCfg = Release|Win32
+		{097D9F6C-FD0E-4CBC-9676-009012AAECA8}.Release|Win32.Build.0 = Release|Win32
+		{097D9F6C-FD0E-4CBC-9676-009012AAECA8}.Release|x64.ActiveCfg = Release|x64
+		{097D9F6C-FD0E-4CBC-9676-009012AAECA8}.Release|x64.Build.0 = Release|x64
+		{244455E0-5F25-4451-9540-F317883E52A8}.Debug|Win32.ActiveCfg = Debug|Win32
+		{244455E0-5F25-4451-9540-F317883E52A8}.Debug|Win32.Build.0 = Debug|Win32
+		{244455E0-5F25-4451-9540-F317883E52A8}.Debug|x64.ActiveCfg = Debug|x64
+		{244455E0-5F25-4451-9540-F317883E52A8}.Debug|x64.Build.0 = Debug|x64
+		{244455E0-5F25-4451-9540-F317883E52A8}.Release|Win32.ActiveCfg = Release|Win32
+		{244455E0-5F25-4451-9540-F317883E52A8}.Release|Win32.Build.0 = Release|Win32
+		{244455E0-5F25-4451-9540-F317883E52A8}.Release|x64.ActiveCfg = Release|x64
+		{244455E0-5F25-4451-9540-F317883E52A8}.Release|x64.Build.0 = Release|x64
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/FreeImage.2013.vcxproj b/FreeImage.2013.vcxproj
new file mode 100644
index 0000000..efb01ae
--- /dev/null
+++ b/FreeImage.2013.vcxproj
@@ -0,0 +1,460 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectName>FreeImage</ProjectName>
+    <ProjectGuid>{B39ED2B3-D53A-4077-B957-930979A3577D}</ProjectGuid>
+    <RootNamespace>FreeImage</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>12.0.21005.1</_ProjectFileVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+    <LinkIncremental>false</LinkIncremental>
+    <GenerateManifest>false</GenerateManifest>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+    <LinkIncremental>false</LinkIncremental>
+    <GenerateManifest>false</GenerateManifest>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+    <GenerateManifest>false</GenerateManifest>
+    <TargetName>$(ProjectName)d</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+    <GenerateManifest>false</GenerateManifest>
+    <TargetName>$(ProjectName)d</TargetName>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Midl>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MkTypLibCompatible>true</MkTypLibCompatible>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <TargetEnvironment>Win32</TargetEnvironment>
+      <TypeLibraryName>$(OutDir)FreeImage.tlb</TypeLibraryName>
+      <HeaderFileName />
+    </Midl>
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <OmitFramePointers>true</OmitFramePointers>
+      <WholeProgramOptimization>true</WholeProgramOptimization>
+      <AdditionalIncludeDirectories>Source;Source\ZLib;Source\DeprecationManager;Source\OpenEXR;Source\OpenEXR\Half;Source\OpenEXR\Iex;Source\OpenEXR\IlmImf;Source\OpenEXR\Imath;Source\OpenEXR\IlmThread;Source\LibJXR\jxrgluelib;Source\LibJXR\image\sys;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;OPJ_STATIC;FREEIMAGE_EXPORTS;_CRT_SECURE_NO_DEPRECATE;LIBRAW_NODLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <CompileAs>Default</CompileAs>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+      <StructMemberAlignment>16Bytes</StructMemberAlignment>
+      <DebugInformationFormat>None</DebugInformationFormat>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0409</Culture>
+    </ResourceCompile>
+    <Link>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention />
+      <TargetMachine>MachineX86</TargetMachine>
+      <Profile>true</Profile>
+      <GenerateDebugInformation>false</GenerateDebugInformation>
+      <IgnoreEmbeddedIDL>true</IgnoreEmbeddedIDL>
+      <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalDependencies />
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+    </Link>
+    <PostBuildEvent>
+      <Command>mkdir Dist\x32
+copy $(OutDir)$(TargetName).dll Dist\x32
+copy $(OutDir)$(TargetName).lib Dist\x32
+copy Source\FreeImage.h Dist\x32
+</Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Midl>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MkTypLibCompatible>true</MkTypLibCompatible>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <TargetEnvironment>X64</TargetEnvironment>
+      <TypeLibraryName>$(OutDir)FreeImage.tlb</TypeLibraryName>
+      <HeaderFileName />
+    </Midl>
+    <ClCompile>
+      <Optimization>Full</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <OmitFramePointers>true</OmitFramePointers>
+      <WholeProgramOptimization>true</WholeProgramOptimization>
+      <AdditionalIncludeDirectories>Source;Source\ZLib;Source\DeprecationManager;Source\OpenEXR;Source\OpenEXR\Half;Source\OpenEXR\Iex;Source\OpenEXR\IlmImf;Source\OpenEXR\Imath;Source\OpenEXR\IlmThread;Source\LibJXR\jxrgluelib;Source\LibJXR\image\sys;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;OPJ_STATIC;FREEIMAGE_EXPORTS;_CRT_SECURE_NO_DEPRECATE;LIBRAW_NODLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <OpenMPSupport>true</OpenMPSupport>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <CompileAs>Default</CompileAs>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+      <StructMemberAlignment>16Bytes</StructMemberAlignment>
+      <DebugInformationFormat>None</DebugInformationFormat>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0409</Culture>
+    </ResourceCompile>
+    <Link>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention />
+      <TargetMachine>MachineX64</TargetMachine>
+      <Profile>true</Profile>
+      <GenerateDebugInformation>false</GenerateDebugInformation>
+      <IgnoreEmbeddedIDL>true</IgnoreEmbeddedIDL>
+      <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalDependencies />
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+    </Link>
+    <PostBuildEvent>
+      <Command>mkdir Dist\x64
+copy $(OutDir)$(TargetName).dll Dist\x64
+copy $(OutDir)$(TargetName).lib Dist\x64
+copy Source\FreeImage.h Dist\x64
+</Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Midl>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MkTypLibCompatible>true</MkTypLibCompatible>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <TargetEnvironment>Win32</TargetEnvironment>
+      <TypeLibraryName>$(OutDir)FreeImage.tlb</TypeLibraryName>
+      <HeaderFileName />
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>Source;Source\ZLib;Source\DeprecationManager;Source\OpenEXR;Source\OpenEXR\Half;Source\OpenEXR\Iex;Source\OpenEXR\IlmImf;Source\OpenEXR\Imath;Source\OpenEXR\IlmThread;Source\LibJXR\jxrgluelib;Source\LibJXR\image\sys;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;OPJ_STATIC;FREEIMAGE_EXPORTS;_CRT_SECURE_NO_DEPRECATE;LIBRAW_NODLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+      <CompileAs>Default</CompileAs>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+      <StructMemberAlignment>16Bytes</StructMemberAlignment>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0409</Culture>
+    </ResourceCompile>
+    <Link>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention />
+      <TargetMachine>MachineX86</TargetMachine>
+      <IgnoreEmbeddedIDL>true</IgnoreEmbeddedIDL>
+      <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalDependencies />
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+    </Link>
+    <PostBuildEvent>
+      <Command>mkdir Dist\x32
+copy $(OutDir)$(TargetName).dll Dist\x32
+copy $(OutDir)$(TargetName).lib Dist\x32
+copy Source\FreeImage.h Dist\x32
+</Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Midl>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MkTypLibCompatible>true</MkTypLibCompatible>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <TargetEnvironment>X64</TargetEnvironment>
+      <TypeLibraryName>$(OutDir)FreeImage.tlb</TypeLibraryName>
+      <HeaderFileName />
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>Source;Source\ZLib;Source\DeprecationManager;Source\OpenEXR;Source\OpenEXR\Half;Source\OpenEXR\Iex;Source\OpenEXR\IlmImf;Source\OpenEXR\Imath;Source\OpenEXR\IlmThread;Source\LibJXR\jxrgluelib;Source\LibJXR\image\sys;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;OPJ_STATIC;FREEIMAGE_EXPORTS;_CRT_SECURE_NO_DEPRECATE;LIBRAW_NODLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <OpenMPSupport>true</OpenMPSupport>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <CompileAs>Default</CompileAs>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+      <StructMemberAlignment>16Bytes</StructMemberAlignment>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0409</Culture>
+    </ResourceCompile>
+    <Link>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention />
+      <TargetMachine>MachineX64</TargetMachine>
+      <IgnoreEmbeddedIDL>true</IgnoreEmbeddedIDL>
+      <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalDependencies />
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+    </Link>
+    <PostBuildEvent>
+      <Command>mkdir Dist\x64
+copy $(OutDir)$(TargetName).dll Dist\x64
+copy $(OutDir)$(TargetName).lib Dist\x64
+copy Source\FreeImage.h Dist\x64
+</Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="Source\FreeImage\BitmapAccess.cpp" />
+    <ClCompile Include="Source\FreeImage\ColorLookup.cpp" />
+    <ClCompile Include="Source\FreeImage\ConversionRGBA16.cpp" />
+    <ClCompile Include="Source\FreeImage\ConversionRGBAF.cpp" />
+    <ClCompile Include="Source\FreeImage\FreeImage.cpp" />
+    <ClCompile Include="Source\FreeImage\FreeImageC.c" />
+    <ClCompile Include="Source\FreeImage\FreeImageIO.cpp" />
+    <ClCompile Include="Source\FreeImage\GetType.cpp" />
+    <ClCompile Include="Source\FreeImage\LFPQuantizer.cpp" />
+    <ClCompile Include="Source\FreeImage\MemoryIO.cpp" />
+    <ClCompile Include="Source\FreeImage\PixelAccess.cpp" />
+    <ClCompile Include="Source\FreeImage\J2KHelper.cpp" />
+    <ClCompile Include="Source\FreeImage\MNGHelper.cpp" />
+    <ClCompile Include="Source\FreeImage\Plugin.cpp" />
+    <ClCompile Include="Source\FreeImage\PluginBMP.cpp" />
+    <ClCompile Include="Source\FreeImage\PluginCUT.cpp" />
+    <ClCompile Include="Source\FreeImage\PluginDDS.cpp" />
+    <ClCompile Include="Source\FreeImage\PluginEXR.cpp" />
+    <ClCompile Include="Source\FreeImage\PluginG3.cpp" />
+    <ClCompile Include="Source\FreeImage\PluginGIF.cpp" />
+    <ClCompile Include="Source\FreeImage\PluginHDR.cpp" />
+    <ClCompile Include="Source\FreeImage\PluginICO.cpp" />
+    <ClCompile Include="Source\FreeImage\PluginIFF.cpp" />
+    <ClCompile Include="Source\FreeImage\PluginJ2K.cpp" />
+    <ClCompile Include="Source\FreeImage\PluginJNG.cpp" />
+    <ClCompile Include="Source\FreeImage\PluginJP2.cpp" />
+    <ClCompile Include="Source\FreeImage\PluginJPEG.cpp" />
+    <ClCompile Include="Source\FreeImage\PluginJXR.cpp" />
+    <ClCompile Include="Source\FreeImage\PluginKOALA.cpp" />
+    <ClCompile Include="Source\FreeImage\PluginMNG.cpp" />
+    <ClCompile Include="Source\FreeImage\PluginPCD.cpp" />
+    <ClCompile Include="Source\FreeImage\PluginPCX.cpp" />
+    <ClCompile Include="Source\FreeImage\PluginPFM.cpp" />
+    <ClCompile Include="Source\FreeImage\PluginPICT.cpp" />
+    <ClCompile Include="Source\FreeImage\PluginPNG.cpp" />
+    <ClCompile Include="Source\FreeImage\PluginPNM.cpp" />
+    <ClCompile Include="Source\FreeImage\PluginPSD.cpp" />
+    <ClCompile Include="Source\FreeImage\PluginRAS.cpp" />
+    <ClCompile Include="Source\FreeImage\PluginRAW.cpp" />
+    <ClCompile Include="Source\FreeImage\PluginSGI.cpp" />
+    <ClCompile Include="Source\FreeImage\PluginTARGA.cpp" />
+    <ClCompile Include="Source\FreeImage\PluginTIFF.cpp" />
+    <ClCompile Include="Source\FreeImage\PluginWBMP.cpp" />
+    <ClCompile Include="Source\FreeImage\PluginWebP.cpp" />
+    <ClCompile Include="Source\FreeImage\PluginXBM.cpp" />
+    <ClCompile Include="Source\FreeImage\PluginXPM.cpp" />
+    <ClCompile Include="Source\FreeImage\PSDParser.cpp" />
+    <ClCompile Include="Source\FreeImage\TIFFLogLuv.cpp" />
+    <ClCompile Include="Source\FreeImage\Conversion.cpp" />
+    <ClCompile Include="Source\FreeImage\Conversion16_555.cpp" />
+    <ClCompile Include="Source\FreeImage\Conversion16_565.cpp" />
+    <ClCompile Include="Source\FreeImage\Conversion24.cpp" />
+    <ClCompile Include="Source\FreeImage\Conversion32.cpp" />
+    <ClCompile Include="Source\FreeImage\Conversion4.cpp" />
+    <ClCompile Include="Source\FreeImage\Conversion8.cpp" />
+    <ClCompile Include="Source\FreeImage\ConversionFloat.cpp" />
+    <ClCompile Include="Source\FreeImage\ConversionRGB16.cpp" />
+    <ClCompile Include="Source\FreeImage\ConversionRGBF.cpp" />
+    <ClCompile Include="Source\FreeImage\ConversionType.cpp" />
+    <ClCompile Include="Source\FreeImage\ConversionUINT16.cpp" />
+    <ClCompile Include="Source\FreeImage\Halftoning.cpp" />
+    <ClCompile Include="Source\FreeImage\tmoColorConvert.cpp" />
+    <ClCompile Include="Source\FreeImage\tmoDrago03.cpp" />
+    <ClCompile Include="Source\FreeImage\tmoFattal02.cpp" />
+    <ClCompile Include="Source\FreeImage\tmoReinhard05.cpp" />
+    <ClCompile Include="Source\FreeImage\ToneMapping.cpp" />
+    <ClCompile Include="Source\FreeImage\NNQuantizer.cpp" />
+    <ClCompile Include="Source\FreeImage\WuQuantizer.cpp" />
+    <ClCompile Include="Source\DeprecationManager\Deprecated.cpp" />
+    <ClCompile Include="Source\DeprecationManager\DeprecationMgr.cpp" />
+    <ClCompile Include="Source\FreeImage\CacheFile.cpp" />
+    <ClCompile Include="Source\FreeImage\MultiPage.cpp" />
+    <ClCompile Include="Source\FreeImage\ZLibInterface.cpp" />
+    <ClCompile Include="Source\Metadata\Exif.cpp" />
+    <ClCompile Include="Source\Metadata\FIRational.cpp" />
+    <ClCompile Include="Source\Metadata\FreeImageTag.cpp" />
+    <ClCompile Include="Source\Metadata\IPTC.cpp" />
+    <ClCompile Include="Source\Metadata\TagConversion.cpp" />
+    <ClCompile Include="Source\Metadata\TagLib.cpp" />
+    <ClCompile Include="Source\Metadata\XTIFF.cpp" />
+    <ClCompile Include="Source\FreeImageToolkit\Background.cpp" />
+    <ClCompile Include="Source\FreeImageToolkit\BSplineRotate.cpp" />
+    <ClCompile Include="Source\FreeImageToolkit\Channels.cpp" />
+    <ClCompile Include="Source\FreeImageToolkit\ClassicRotate.cpp" />
+    <ClCompile Include="Source\FreeImageToolkit\Colors.cpp" />
+    <ClCompile Include="Source\FreeImageToolkit\CopyPaste.cpp" />
+    <ClCompile Include="Source\FreeImageToolkit\Display.cpp" />
+    <ClCompile Include="Source\FreeImageToolkit\Flip.cpp" />
+    <ClCompile Include="Source\FreeImageToolkit\JPEGTransform.cpp" />
+    <ClCompile Include="Source\FreeImageToolkit\MultigridPoissonSolver.cpp" />
+    <ClCompile Include="Source\FreeImageToolkit\Rescale.cpp" />
+    <ClCompile Include="Source\FreeImageToolkit\Resize.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="FreeImage.rc" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="Source\CacheFile.h" />
+    <ClInclude Include="Source\DeprecationManager\DeprecationMgr.h" />
+    <ClInclude Include="Source\MapIntrospector.h" />
+    <ClInclude Include="Source\Metadata\FIRational.h" />
+    <ClInclude Include="Source\FreeImage.h" />
+    <ClInclude Include="Source\FreeImageIO.h" />
+    <ClInclude Include="Source\Metadata\FreeImageTag.h" />
+    <ClInclude Include="Source\FreeImage\J2KHelper.h" />
+    <ClInclude Include="Source\Plugin.h" />
+    <ClInclude Include="Source\FreeImage\PSDParser.h" />
+    <ClInclude Include="Source\Quantizers.h" />
+    <ClInclude Include="Source\ToneMapping.h" />
+    <ClInclude Include="Source\Utilities.h" />
+    <ClInclude Include="Source\FreeImageToolkit\Resize.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <Text Include="Todo.txt" />
+    <Text Include="Whatsnew.txt" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="Source\LibJPEG\LibJPEG.2013.vcxproj">
+      <Project>{5e1d4e5f-e10c-4ba3-b663-f33014fd21d9}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+    <ProjectReference Include="Source\LibJXR\LibJXR.2013.vcxproj">
+      <Project>{244455e0-5f25-4451-9540-f317883e52a8}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+    <ProjectReference Include="Source\LibOpenJPEG\LibOpenJPEG.2013.vcxproj">
+      <Project>{e3536c28-a7f1-4b53-8e52-7d2232f9e098}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+    <ProjectReference Include="Source\LibPNG\LibPNG.2013.vcxproj">
+      <Project>{7db10b50-ce00-4d7a-b322-6824f05d2fcb}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+    <ProjectReference Include="Source\LibRawLite\LibRawLite.2013.vcxproj">
+      <Project>{07f662c1-1323-42ab-b6af-fbfd34a7437a}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+    <ProjectReference Include="Source\LibTIFF4\LibTIFF4.2013.vcxproj">
+      <Project>{ec085cbd-e9c3-477f-9a97-cb9d5da30e27}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+    <ProjectReference Include="Source\LibWebP\LibWebP.2013.vcxproj">
+      <Project>{097d9f6c-fd0e-4cbc-9676-009012aaeca8}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+    <ProjectReference Include="Source\OpenEXR\OpenEXR.2013.vcxproj">
+      <Project>{17a4874b-0606-4687-90b6-f91f8cb3b8af}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+    <ProjectReference Include="Source\ZLib\ZLib.2013.vcxproj">
+      <Project>{33134f61-c1ad-4b6f-9cea-503a9f140c52}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/FreeImage.2013.vcxproj.filters b/FreeImage.2013.vcxproj.filters
new file mode 100644
index 0000000..bca3291
--- /dev/null
+++ b/FreeImage.2013.vcxproj.filters
@@ -0,0 +1,365 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{e986c03f-920f-43c5-91c1-19d1b25e2bd9}</UniqueIdentifier>
+      <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
+    </Filter>
+    <Filter Include="Source Files\Plugins">
+      <UniqueIdentifier>{d31a0480-d01e-45ec-b0b3-78082e005845}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\Conversion">
+      <UniqueIdentifier>{2b44daf4-8804-4c70-a799-8c38f05028e9}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\Quantizers">
+      <UniqueIdentifier>{a31a9907-daf4-49ba-b15d-fa58325e1a93}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\DeprecationMgr">
+      <UniqueIdentifier>{e04705f9-f5dc-4d94-a2b8-e382debdac6c}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\MultiPaging">
+      <UniqueIdentifier>{8e548647-dbf1-4ab0-b9c3-a0b9fd1388c9}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\Metadata">
+      <UniqueIdentifier>{d0812fb1-23ed-41a7-bca7-7b4cc2a6912b}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{dc84ec63-4baa-4793-ae16-298ab73fa716}</UniqueIdentifier>
+      <Extensions>h;hpp;hxx;hm;inl</Extensions>
+    </Filter>
+    <Filter Include="Toolkit Files">
+      <UniqueIdentifier>{65e72023-cd72-4b71-8c5e-a1ca9f38cebd}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="Source\FreeImage\BitmapAccess.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\ColorLookup.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\FreeImage.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\FreeImageC.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\FreeImageIO.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\GetType.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\MemoryIO.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\PixelAccess.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\J2KHelper.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\MNGHelper.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\Plugin.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\PluginBMP.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\PluginCUT.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\PluginDDS.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\PluginEXR.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\PluginG3.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\PluginGIF.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\PluginHDR.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\PluginICO.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\PluginIFF.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\PluginJ2K.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\PluginJNG.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\PluginJP2.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\PluginJPEG.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\PluginJXR.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\PluginKOALA.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\PluginMNG.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\PluginPCD.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\PluginPCX.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\PluginPFM.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\PluginPICT.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\PluginPNG.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\PluginPNM.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\PluginPSD.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\PluginRAS.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\PluginRAW.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\PluginSGI.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\PluginTARGA.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\PluginTIFF.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\PluginWBMP.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\PluginWebP.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\PluginXBM.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\PluginXPM.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\PSDParser.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\TIFFLogLuv.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\Conversion.cpp">
+      <Filter>Source Files\Conversion</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\Conversion16_555.cpp">
+      <Filter>Source Files\Conversion</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\Conversion16_565.cpp">
+      <Filter>Source Files\Conversion</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\Conversion24.cpp">
+      <Filter>Source Files\Conversion</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\Conversion32.cpp">
+      <Filter>Source Files\Conversion</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\Conversion4.cpp">
+      <Filter>Source Files\Conversion</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\Conversion8.cpp">
+      <Filter>Source Files\Conversion</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\ConversionFloat.cpp">
+      <Filter>Source Files\Conversion</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\ConversionRGB16.cpp">
+      <Filter>Source Files\Conversion</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\ConversionRGBF.cpp">
+      <Filter>Source Files\Conversion</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\ConversionType.cpp">
+      <Filter>Source Files\Conversion</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\ConversionUINT16.cpp">
+      <Filter>Source Files\Conversion</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\Halftoning.cpp">
+      <Filter>Source Files\Conversion</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\tmoColorConvert.cpp">
+      <Filter>Source Files\Conversion</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\tmoDrago03.cpp">
+      <Filter>Source Files\Conversion</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\tmoFattal02.cpp">
+      <Filter>Source Files\Conversion</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\tmoReinhard05.cpp">
+      <Filter>Source Files\Conversion</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\ToneMapping.cpp">
+      <Filter>Source Files\Conversion</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\NNQuantizer.cpp">
+      <Filter>Source Files\Quantizers</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\WuQuantizer.cpp">
+      <Filter>Source Files\Quantizers</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\DeprecationManager\Deprecated.cpp">
+      <Filter>Source Files\DeprecationMgr</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\DeprecationManager\DeprecationMgr.cpp">
+      <Filter>Source Files\DeprecationMgr</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\CacheFile.cpp">
+      <Filter>Source Files\MultiPaging</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\MultiPage.cpp">
+      <Filter>Source Files\MultiPaging</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\ZLibInterface.cpp">
+      <Filter>Source Files\MultiPaging</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\Metadata\Exif.cpp">
+      <Filter>Source Files\Metadata</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\Metadata\FIRational.cpp">
+      <Filter>Source Files\Metadata</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\Metadata\FreeImageTag.cpp">
+      <Filter>Source Files\Metadata</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\Metadata\IPTC.cpp">
+      <Filter>Source Files\Metadata</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\Metadata\TagConversion.cpp">
+      <Filter>Source Files\Metadata</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\Metadata\TagLib.cpp">
+      <Filter>Source Files\Metadata</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\Metadata\XTIFF.cpp">
+      <Filter>Source Files\Metadata</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImageToolkit\Background.cpp">
+      <Filter>Toolkit Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImageToolkit\BSplineRotate.cpp">
+      <Filter>Toolkit Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImageToolkit\Channels.cpp">
+      <Filter>Toolkit Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImageToolkit\ClassicRotate.cpp">
+      <Filter>Toolkit Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImageToolkit\Colors.cpp">
+      <Filter>Toolkit Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImageToolkit\CopyPaste.cpp">
+      <Filter>Toolkit Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImageToolkit\Display.cpp">
+      <Filter>Toolkit Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImageToolkit\Flip.cpp">
+      <Filter>Toolkit Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImageToolkit\JPEGTransform.cpp">
+      <Filter>Toolkit Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImageToolkit\MultigridPoissonSolver.cpp">
+      <Filter>Toolkit Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImageToolkit\Rescale.cpp">
+      <Filter>Toolkit Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImageToolkit\Resize.cpp">
+      <Filter>Toolkit Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\LFPQuantizer.cpp">
+      <Filter>Source Files\Quantizers</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\ConversionRGBAF.cpp">
+      <Filter>Source Files\Conversion</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\FreeImage\ConversionRGBA16.cpp">
+      <Filter>Source Files\Conversion</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="FreeImage.rc">
+      <Filter>Source Files</Filter>
+    </ResourceCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="Source\CacheFile.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Source\DeprecationManager\DeprecationMgr.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Source\Metadata\FIRational.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Source\FreeImage.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Source\FreeImageIO.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Source\Metadata\FreeImageTag.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Source\FreeImage\J2KHelper.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Source\Plugin.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Source\FreeImage\PSDParser.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Source\Quantizers.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Source\ToneMapping.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Source\Utilities.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Source\FreeImageToolkit\Resize.h">
+      <Filter>Toolkit Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Source\MapIntrospector.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <Text Include="Todo.txt" />
+    <Text Include="Whatsnew.txt" />
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/FreeImage.rc b/FreeImage.rc
index 7266f1c..3415c11 100644
--- a/FreeImage.rc
+++ b/FreeImage.rc
@@ -1,34 +1,13 @@
-//Microsoft Developer Studio generated resource script.
-//
+#include <windows.h>
 
-#define APSTUDIO_READONLY_SYMBOLS
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 2 resource.
-//
-#include "afxres.h"
-
-/////////////////////////////////////////////////////////////////////////////
-#undef APSTUDIO_READONLY_SYMBOLS
-
-/////////////////////////////////////////////////////////////////////////////
-// English (U.S.) resources
-
-#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
-#ifdef _WIN32
-LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
-#pragma code_page(1252)
-#endif //_WIN32
-
-#ifndef _MAC
 /////////////////////////////////////////////////////////////////////////////
 //
 // Version
 //
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 3,15,4,0
- PRODUCTVERSION 3,15,4,0
+ FILEVERSION 3,17,0,0
+ PRODUCTVERSION 3,17,0,0
  FILEFLAGSMASK 0x3fL
 #ifdef _DEBUG
  FILEFLAGS 0x1L
@@ -46,14 +25,14 @@ BEGIN
             VALUE "Comments", "FreeImage is an Open Source library project for developers who would like to support popular graphics image formats like PNG, BMP, JPEG, TIFF and others as needed by today's multimedia applications.\0"
             VALUE "CompanyName", "FreeImage\0"
             VALUE "FileDescription", "FreeImage library\0"
-            VALUE "FileVersion", "3, 15, 4, 0\0"
+            VALUE "FileVersion", "3, 17, 0, 0\0"
             VALUE "InternalName", "FreeImage\0"
-            VALUE "LegalCopyright", "Copyright � 2003-2012 by FreeImage\0"
+            VALUE "LegalCopyright", "Copyright � 2003-2015 by FreeImage\0"
             VALUE "LegalTrademarks", "See http://freeimage.sourceforge.net\0"
             VALUE "OriginalFilename", "FreeImage.dll\0"
             VALUE "PrivateBuild", "\0"
             VALUE "ProductName", "FreeImage\0"
-            VALUE "ProductVersion", "3, 15, 4, 0\0"
+            VALUE "ProductVersion", "3, 17, 0, 0\0"
             VALUE "SpecialBuild", "\0"
         END
     END
@@ -63,33 +42,3 @@ BEGIN
     END
 END
 
-#endif    // !_MAC
-
-#endif    // English (U.S.) resources
-/////////////////////////////////////////////////////////////////////////////
-
-#ifdef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// TEXTINCLUDE
-//
-
-1 TEXTINCLUDE DISCARDABLE 
-BEGIN
-    "#include ""afxres.h""\r\n"
-    "\0"
-END
-
-2 TEXTINCLUDE DISCARDABLE 
-BEGIN
-    "\r\n"
-    "\0"
-END
-
-#endif    // APSTUDIO_INVOKED
-
-
-/////////////////////////////////////////////////////////////////////////////
-
-
-
diff --git a/Makefile.cygwin b/Makefile.cygwin
index 124f612..c2ea6a0 100644
--- a/Makefile.cygwin
+++ b/Makefile.cygwin
@@ -1,73 +1,74 @@
-# Cygwin makefile for FreeImage
-
-# This file can be generated by ./gensrclist.sh
-include Makefile.srcs
-
-# General configuration variables:
-CC = gcc
-CXX = g++
-AR = ar
-
-INSTALLDIR = /usr
-
-# Converts cr/lf to just lf
-DOS2UNIX = dos2unix
-
-COMPILERFLAGS = -O3 -DNO_LCMS
-LIBRARIES = -lstdc++
-
-MODULES = $(SRCS:.c=.o)
-MODULES := $(MODULES:.cpp=.o)
-CFLAGS = $(COMPILERFLAGS) $(INCLUDE)
-CXXFLAGS = $(COMPILERFLAGS)  -Wno-ctor-dtor-privacy $(INCLUDE)
-
-TARGET  = freeimage
-STATICLIB = lib$(TARGET).a
-SHAREDLIB = cyg$(TARGET)-$(VER_MAJOR).$(VER_MINOR).dll
-LIBNAME = lib$(TARGET).dll.a
-HEADER = Source/FreeImage.h
-
-
-default: all
-
-all: dist
-
-dist: FreeImage
-	cp *.a Dist
-	cp *.dll Dist
-	cp *.dll.a Dist
-	cp $(HEADER) Dist
-
-dos2unix:
-	@$(DOS2UNIX) $(SRCS) $(INCLS)
-
-FreeImage: $(STATICLIB) $(SHAREDLIB)
-
-.c.o:
-	$(CC) $(CFLAGS) -c $< -o $@
-
-.cpp.o:
-	$(CXX) $(CXXFLAGS) -c $< -o $@
-
-$(STATICLIB): $(MODULES)
-	$(AR) r $@ $(MODULES)
-
-$(SHAREDLIB): $(MODULES)
-	$(CC) -s -shared -o $@ \
-	    -Wl,--out-implib=$(LIBNAME) \
-	    -Wl,--export-all-symbols \
-	    -Wl,--enable-auto-import \
-	    -Wl,--enable-auto-image-base \
-	    -Wl,--whole-archive $(STATICLIB) \
-	    -Wl,--no-whole-archive $(LIBRARIES)
-
-
-install:
-	install -m 644 $(STATICLIB) $(INSTALLDIR)/lib
-	install -m 644 $(LIBNAME) $(INSTALLDIR)/lib
-	install -m 755 $(SHAREDLIB) $(INSTALLDIR)/bin
-	install -m 644 $(HEADER) $(INSTALLDIR)/include
-
-clean:
-	rm -f core Dist/*.* u2dtmp* $(MODULES) $(STATICLIB) $(SHAREDLIB) $(LIBNAME)
-
+# Cygwin makefile for FreeImage
+
+# This file can be generated by ./gensrclist.sh
+include Makefile.srcs
+
+# General configuration variables:
+CC = gcc
+CXX = g++
+AR = ar
+
+INSTALLDIR = /usr
+
+# Converts cr/lf to just lf
+DOS2UNIX = dos2unix
+
+COMPILERFLAGS = -O3 -DNO_LCMS
+LIBRARIES = -lstdc++
+
+MODULES = $(SRCS:.c=.o)
+MODULES := $(MODULES:.cpp=.o)
+CFLAGS = $(COMPILERFLAGS) $(INCLUDE)
+CXXFLAGS = $(COMPILERFLAGS)  -Wno-ctor-dtor-privacy $(INCLUDE)
+
+TARGET  = freeimage
+STATICLIB = lib$(TARGET).a
+SHAREDLIB = cyg$(TARGET)-$(VER_MAJOR).$(VER_MINOR).dll
+LIBNAME = lib$(TARGET).dll.a
+HEADER = Source/FreeImage.h
+
+
+default: all
+
+all: dist
+
+dist: FreeImage
+	mkdir -p Dist
+	cp *.a Dist/
+	cp *.dll Dist/
+	cp *.dll.a Dist/
+	cp $(HEADER) Dist/
+
+dos2unix:
+	@$(DOS2UNIX) $(SRCS) $(INCLS)
+
+FreeImage: $(STATICLIB) $(SHAREDLIB)
+
+.c.o:
+	$(CC) $(CFLAGS) -c $< -o $@
+
+.cpp.o:
+	$(CXX) $(CXXFLAGS) -c $< -o $@
+
+$(STATICLIB): $(MODULES)
+	$(AR) r $@ $(MODULES)
+
+$(SHAREDLIB): $(MODULES)
+	$(CC) -s -shared -o $@ \
+	    -Wl,--out-implib=$(LIBNAME) \
+	    -Wl,--export-all-symbols \
+	    -Wl,--enable-auto-import \
+	    -Wl,--enable-auto-image-base \
+	    -Wl,--whole-archive $(STATICLIB) \
+	    -Wl,--no-whole-archive $(LIBRARIES)
+
+
+install:
+	install -m 644 $(STATICLIB) $(INSTALLDIR)/lib
+	install -m 644 $(LIBNAME) $(INSTALLDIR)/lib
+	install -m 755 $(SHAREDLIB) $(INSTALLDIR)/bin
+	install -m 644 $(HEADER) $(INSTALLDIR)/include
+
+clean:
+	rm -f core Dist/*.* u2dtmp* $(MODULES) $(STATICLIB) $(SHAREDLIB) $(LIBNAME)
+
diff --git a/Makefile.fip b/Makefile.fip
index 1c2dee4..b59c419 100644
--- a/Makefile.fip
+++ b/Makefile.fip
@@ -1,73 +1,84 @@
-# Linux makefile for FreeImagePlus
-
-# This file can be generated by ./genfipsrclist.sh
-include fipMakefile.srcs
-
-# General configuration variables:
-DESTDIR ?= /
-INCDIR ?= $(DESTDIR)/usr/include
-INSTALLDIR ?= $(DESTDIR)/usr/lib
-
-# Converts cr/lf to just lf
-DOS2UNIX = dos2unix
-
-LIBRARIES = -lstdc++
-
-MODULES = $(SRCS:.c=.o)
-MODULES := $(MODULES:.cpp=.o)
-CFLAGS ?= -O3 -fPIC -fexceptions -fvisibility=hidden -DNO_LCMS
-CFLAGS += $(INCLUDE)
-CXXFLAGS ?= -O3 -fPIC -fexceptions -fvisibility=hidden -Wno-ctor-dtor-privacy
-CXXFLAGS += $(INCLUDE)
-
-ifeq ($(shell sh -c 'uname -m 2>/dev/null || echo not'),x86_64)
-	CFLAGS += -fPIC
-	CXXFLAGS += -fPIC
-endif
-
-TARGET  = freeimageplus
-STATICLIB = lib$(TARGET).a
-SHAREDLIB = lib$(TARGET)-$(VER_MAJOR).$(VER_MINOR).so
-LIBNAME	= lib$(TARGET).so
-VERLIBNAME = $(LIBNAME).$(VER_MAJOR)
-HEADER = Source/FreeImage.h
-HEADERFIP = Wrapper/FreeImagePlus/FreeImagePlus.h
-
-
-default: all
-
-all: dist
-
-dist: FreeImage
-	cp *.a Dist
-	cp *.so Dist
-	cp Source/FreeImage.h Dist
-	cp Wrapper/FreeImagePlus/FreeImagePlus.h Dist
-
-dos2unix:
-	@$(DOS2UNIX) $(SRCS)
-
-FreeImage: $(STATICLIB) $(SHAREDLIB)
-
-.c.o:
-	$(CC) $(CFLAGS) -c $< -o $@
-
-.cpp.o:
-	$(CXX) $(CXXFLAGS) -c $< -o $@
-
-$(STATICLIB): $(MODULES)
-	$(AR) r $@ $(MODULES)
-
-$(SHAREDLIB): $(MODULES)
-	$(CC) -s -shared -Wl,-soname,$(VERLIBNAME) $(LDFLAGS) -o $@ $(MODULES) $(LIBRARIES)
-
-install:
-	install -d $(INCDIR) $(INSTALLDIR)
-	install -m 644 -o root -g root $(HEADER) $(INCDIR)
-	install -m 644 -o root -g root $(HEADERFIP) $(INCDIR)
-	install -m 644 -o root -g root $(STATICLIB) $(INSTALLDIR)
-	install -m 755 -o root -g root $(SHAREDLIB) $(INSTALLDIR)
-
-clean:
-	rm -f core Dist/*.* u2dtmp* $(MODULES) $(STATICLIB) $(SHAREDLIB) $(LIBNAME)
-
+# Linux makefile for FreeImagePlus
+
+# This file can be generated by ./genfipsrclist.sh
+include fipMakefile.srcs
+
+# General configuration variables:
+DESTDIR ?= /
+INCDIR ?= $(DESTDIR)/usr/include
+INSTALLDIR ?= $(DESTDIR)/usr/lib
+
+# Converts cr/lf to just lf
+DOS2UNIX = dos2unix
+
+LIBRARIES = -lstdc++
+
+MODULES = $(SRCS:.c=.o)
+MODULES := $(MODULES:.cpp=.o)
+CFLAGS ?= -O3 -fPIC -fexceptions -fvisibility=hidden
+# OpenJPEG
+CFLAGS += -DOPJ_STATIC
+# LibRaw
+CFLAGS += -DNO_LCMS
+# LibJXR
+CFLAGS += -DDISABLE_PERF_MEASUREMENT -D__ANSI__
+CFLAGS += $(INCLUDE)
+CXXFLAGS ?= -O3 -fPIC -fexceptions -fvisibility=hidden -Wno-ctor-dtor-privacy
+# LibJXR
+CXXFLAGS += -D__ANSI__
+CXXFLAGS += $(INCLUDE)
+
+ifeq ($(shell sh -c 'uname -m 2>/dev/null || echo not'),x86_64)
+	CFLAGS += -fPIC
+	CXXFLAGS += -fPIC
+endif
+
+TARGET  = freeimageplus
+STATICLIB = lib$(TARGET).a
+SHAREDLIB = lib$(TARGET)-$(VER_MAJOR).$(VER_MINOR).so
+LIBNAME	= lib$(TARGET).so
+VERLIBNAME = $(LIBNAME).$(VER_MAJOR)
+HEADER = Source/FreeImage.h
+HEADERFIP = Wrapper/FreeImagePlus/FreeImagePlus.h
+
+
+default: all
+
+all: dist
+
+dist: FreeImage
+	mkdir -p Dist
+	cp *.a Dist/
+	cp *.so Dist/
+	cp Source/FreeImage.h Dist/
+	cp Wrapper/FreeImagePlus/FreeImagePlus.h Dist/
+
+dos2unix:
+	@$(DOS2UNIX) $(SRCS)
+
+FreeImage: $(STATICLIB) $(SHAREDLIB)
+
+.c.o:
+	$(CC) $(CFLAGS) -c $< -o $@
+
+.cpp.o:
+	$(CXX) $(CXXFLAGS) -c $< -o $@
+
+$(STATICLIB): $(MODULES)
+	$(AR) r $@ $(MODULES)
+
+$(SHAREDLIB): $(MODULES)
+	$(CC) -s -shared -Wl,-soname,$(VERLIBNAME) $(LDFLAGS) -o $@ $(MODULES) $(LIBRARIES)
+
+install:
+	install -d $(INCDIR) $(INSTALLDIR)
+	install -m 644 -o root -g root $(HEADER) $(INCDIR)
+	install -m 644 -o root -g root $(HEADERFIP) $(INCDIR)
+	install -m 644 -o root -g root $(STATICLIB) $(INSTALLDIR)
+	install -m 755 -o root -g root $(SHAREDLIB) $(INSTALLDIR)
+	ln -sf $(SHAREDLIB) $(INSTALLDIR)/$(VERLIBNAME)
+	ln -sf $(VERLIBNAME) $(INSTALLDIR)/$(LIBNAME)	
+
+clean:
+	rm -f core Dist/*.* u2dtmp* $(MODULES) $(STATICLIB) $(SHAREDLIB) $(LIBNAME)
+
diff --git a/Makefile.gnu b/Makefile.gnu
index e6007ae..92f6358 100644
--- a/Makefile.gnu
+++ b/Makefile.gnu
@@ -1,74 +1,83 @@
-# Linux makefile for FreeImage
-
-# This file can be generated by ./gensrclist.sh
-include Makefile.srcs
-
-# General configuration variables:
-DESTDIR ?= /
-INCDIR ?= $(DESTDIR)/usr/include
-INSTALLDIR ?= $(DESTDIR)/usr/lib
-
-# Converts cr/lf to just lf
-DOS2UNIX = dos2unix
-
-LIBRARIES = -lstdc++
-
-MODULES = $(SRCS:.c=.o)
-MODULES := $(MODULES:.cpp=.o)
-CFLAGS ?= -O3 -fPIC -fexceptions -fvisibility=hidden -DNO_LCMS
-CFLAGS += $(INCLUDE)
-CXXFLAGS ?= -O3 -fPIC -fexceptions -fvisibility=hidden -Wno-ctor-dtor-privacy
-CXXFLAGS += $(INCLUDE)
-
-ifeq ($(shell sh -c 'uname -m 2>/dev/null || echo not'),x86_64)
-	CFLAGS += -fPIC
-	CXXFLAGS += -fPIC
-endif
-
-TARGET  = freeimage
-STATICLIB = lib$(TARGET).a
-SHAREDLIB = lib$(TARGET)-$(VER_MAJOR).$(VER_MINOR).so
-LIBNAME	= lib$(TARGET).so
-VERLIBNAME = $(LIBNAME).$(VER_MAJOR)
-HEADER = Source/FreeImage.h
-
-
-
-default: all
-
-all: dist
-
-dist: FreeImage
-	cp *.a Dist
-	cp *.so Dist
-	cp Source/FreeImage.h Dist
-
-dos2unix:
-	@$(DOS2UNIX) $(SRCS) $(INCLS)
-
-FreeImage: $(STATICLIB) $(SHAREDLIB)
-
-.c.o:
-	$(CC) $(CFLAGS) -c $< -o $@
-
-.cpp.o:
-	$(CXX) $(CXXFLAGS) -c $< -o $@
-
-$(STATICLIB): $(MODULES)
-	$(AR) r $@ $(MODULES)
-
-$(SHAREDLIB): $(MODULES)
-	$(CC) -s -shared -Wl,-soname,$(VERLIBNAME) $(LDFLAGS) -o $@ $(MODULES) $(LIBRARIES)
-
-install:
-	install -d $(INCDIR) $(INSTALLDIR)
-	install -m 644 -o root -g root $(HEADER) $(INCDIR)
-	install -m 644 -o root -g root $(STATICLIB) $(INSTALLDIR)
-	install -m 755 -o root -g root $(SHAREDLIB) $(INSTALLDIR)
-	ln -sf $(SHAREDLIB) $(INSTALLDIR)/$(VERLIBNAME)
-	ln -sf $(VERLIBNAME) $(INSTALLDIR)/$(LIBNAME)	
-#	ldconfig
-
-clean:
-	rm -f core Dist/*.* u2dtmp* $(MODULES) $(STATICLIB) $(SHAREDLIB) $(LIBNAME)
-
+# Linux makefile for FreeImage
+
+# This file can be generated by ./gensrclist.sh
+include Makefile.srcs
+
+# General configuration variables:
+DESTDIR ?= /
+INCDIR ?= $(DESTDIR)/usr/include
+INSTALLDIR ?= $(DESTDIR)/usr/lib
+
+# Converts cr/lf to just lf
+DOS2UNIX = dos2unix
+
+LIBRARIES = -lstdc++
+
+MODULES = $(SRCS:.c=.o)
+MODULES := $(MODULES:.cpp=.o)
+CFLAGS ?= -O3 -fPIC -fexceptions -fvisibility=hidden
+# OpenJPEG
+CFLAGS += -DOPJ_STATIC
+# LibRaw
+CFLAGS += -DNO_LCMS
+# LibJXR
+CFLAGS += -DDISABLE_PERF_MEASUREMENT -D__ANSI__
+CFLAGS += $(INCLUDE)
+CXXFLAGS ?= -O3 -fPIC -fexceptions -fvisibility=hidden -Wno-ctor-dtor-privacy
+# LibJXR
+CXXFLAGS += -D__ANSI__
+CXXFLAGS += $(INCLUDE)
+
+ifeq ($(shell sh -c 'uname -m 2>/dev/null || echo not'),x86_64)
+	CFLAGS += -fPIC
+	CXXFLAGS += -fPIC
+endif
+
+TARGET  = freeimage
+STATICLIB = lib$(TARGET).a
+SHAREDLIB = lib$(TARGET)-$(VER_MAJOR).$(VER_MINOR).so
+LIBNAME	= lib$(TARGET).so
+VERLIBNAME = $(LIBNAME).$(VER_MAJOR)
+HEADER = Source/FreeImage.h
+
+
+
+default: all
+
+all: dist
+
+dist: FreeImage
+	mkdir -p Dist
+	cp *.a Dist/
+	cp *.so Dist/
+	cp Source/FreeImage.h Dist/
+
+dos2unix:
+	@$(DOS2UNIX) $(SRCS) $(INCLS)
+
+FreeImage: $(STATICLIB) $(SHAREDLIB)
+
+.c.o:
+	$(CC) $(CFLAGS) -c $< -o $@
+
+.cpp.o:
+	$(CXX) $(CXXFLAGS) -c $< -o $@
+
+$(STATICLIB): $(MODULES)
+	$(AR) r $@ $(MODULES)
+
+$(SHAREDLIB): $(MODULES)
+	$(CC) -s -shared -Wl,-soname,$(VERLIBNAME) $(LDFLAGS) -o $@ $(MODULES) $(LIBRARIES)
+
+install:
+	install -d $(INCDIR) $(INSTALLDIR)
+	install -m 644 -o root -g root $(HEADER) $(INCDIR)
+	install -m 644 -o root -g root $(STATICLIB) $(INSTALLDIR)
+	install -m 755 -o root -g root $(SHAREDLIB) $(INSTALLDIR)
+	ln -sf $(SHAREDLIB) $(INSTALLDIR)/$(VERLIBNAME)
+	ln -sf $(VERLIBNAME) $(INSTALLDIR)/$(LIBNAME)	
+#	ldconfig
+
+clean:
+	rm -f core Dist/*.* u2dtmp* $(MODULES) $(STATICLIB) $(SHAREDLIB) $(LIBNAME)
+
diff --git a/Makefile.iphone b/Makefile.iphone
index b99a630..a39f73f 100644
--- a/Makefile.iphone
+++ b/Makefile.iphone
@@ -1,93 +1,96 @@
-# Configuration for iPhone OS, making static libs
-# this will generate both iPhone (arm) and iPhoneSimulator (i686) libs
-
-include Makefile.srcs
-
-CFLAGS =  -g -O2 -Wall -Wmissing-prototypes -std=c99 -ffast-math -fno-strict-aliasing
-CXXFLAGS =  -g -O2 -Wall -fno-strict-aliasing
-
-GCC_VERSION = 4.2
-IPHONEOS_DEPLOYMENT_TARGET = 4.0
-MACOSX_DEPLOYMENT_TARGET = 10.6
-
-PLATFORM_SIM = iPhoneSimulator
-PLATFORM_PHONE = iPhoneOS
-
-ARCH_SIM = i686
-ARCH_PHONE = armv6
-
-PLATFORM_SIM_DEVELOPER_BIN_DIR = /Developer/Platforms/$(PLATFORM_SIM).platform/Developer/usr/bin
-PLATFORM_PHONE_DEVELOPER_BIN_DIR = /Developer/Platforms/$(PLATFORM_PHONE).platform/Developer/usr/bin
-
-SDKROOT_SIM = /Developer/Platforms/$(PLATFORM_SIM).platform/Developer/SDKs/$(PLATFORM_SIM)$(IPHONEOS_DEPLOYMENT_TARGET).sdk
-SDKROOT_PHONE = /Developer/Platforms/$(PLATFORM_PHONE).platform/Developer/SDKs/$(PLATFORM_PHONE)$(IPHONEOS_DEPLOYMENT_TARGET).sdk
-
-EXTRA_CFLAGS_SIM += -arch $(ARCH_SIM) -pipe -mdynamic-no-pic -fvisibility=hidden $(INCLUDE) -isysroot $(SDKROOT_SIM)
-EXTRA_LDFLAGS_SIM += -arch $(ARCH_SIM) -isysroot $(SDKROOT_SIM) -Wl,-dead_strip
-EXTRA_CFLAGS_SIM += -D__IPHONE_OS_VERSION_MIN_REQUIRED=20000 -mmacosx-version-min=$(MACOSX_DEPLOYMENT_TARGET)
-EXTRA_LDFLAGS_SIM += -mmacosx-version-min=$(MACOSX_DEPLOYMENT_TARGET)
-
-EXTRA_CFLAGS_PHONE += -arch $(ARCH_PHONE) -pipe -mdynamic-no-pic -fvisibility=hidden $(INCLUDE) -isysroot $(SDKROOT_PHONE)
-EXTRA_LDFLAGS_PHONE += -arch $(ARCH_PHONE) -isysroot $(SDKROOT_PHONE) -Wl,-dead_strip
-EXTRA_CFLAGS_PHONE += -miphoneos-version-min=$(IPHONEOS_DEPLOYMENT_TARGET)
-EXTRA_LDFLAGS_PHONE += -miphoneos-version-min=$(IPHONEOS_DEPLOYMENT_TARGET)
-
-AR_SIM = $(PLATFORM_SIM_DEVELOPER_BIN_DIR)/ar
-AR_PHONE = $(PLATFORM_PHONE_DEVELOPER_BIN_DIR)/ar
-
-CC_SIM = $(PLATFORM_SIM_DEVELOPER_BIN_DIR)/gcc-$(GCC_VERSION)
-CC_PHONE = $(PLATFORM_PHONE_DEVELOPER_BIN_DIR)/gcc-$(GCC_VERSION)
-
-CFLAGS_SIM = $(CFLAGS) $(EXTRA_CFLAGS_SIM)
-LDFLAGS_SIM = $(EXTRA_LDFLAGS_SIM)
-CXX_SIM = $(PLATFORM_SIM_DEVELOPER_BIN_DIR)/g++-$(GCC_VERSION)
-CXXFLAGS_SIM += $(EXTRA_CFLAGS_SIM) -fvisibility-inlines-hidden
-LIBTOOL_SIM = /Developer/Platforms/$(PLATFORM_SIM).platform/Developer/usr/bin/libtool
-
-CFLAGS_PHONE = $(CFLAGS) $(EXTRA_CFLAGS_PHONE)
-LDFLAGS_PHONE += $(EXTRA_LDFLAGS_PHONE)
-CXX_PHONE = $(PLATFORM_PHONE_DEVELOPER_BIN_DIR)/g++-$(GCC_VERSION)
-CXXFLAGS_PHONE += $(EXTRA_CFLAGS_PHONE) -fvisibility-inlines-hidden
-LIBTOOL_PHONE = /Developer/Platforms/$(PLATFORM_PHONE).platform/Developer/usr/bin/libtool
-
-TARGET = freeimage
-STATICLIB_SIM = lib$(TARGET)-iphonesimulator.a
-STATICLIB_PHONE = lib$(TARGET)-iphone.a
-HEADER = Source/FreeImage.h
-
-.SUFFIXES: .o-i686 .o-arm
-MODULES_ARM = $(SRCS:.c=.o-arm)
-MODULES_ARM := $(MODULES_ARM:.cpp=.o-arm)
-MODULES_i686 = $(SRCS:.c=.o-i686)
-MODULES_i686 := $(MODULES_i686:.cpp=.o-i686)
-
-default: all
-
-all: dist
-
-dist: FreeImage
-	cp *.a Dist
-	cp Source/FreeImage.h Dist
-
-FreeImage: $(STATICLIB_SIM) $(STATICLIB_PHONE)
-
-$(STATICLIB_SIM): $(MODULES_i686)
-	$(LIBTOOL_SIM) -arch_only i686 -o $@ $(MODULES_i686)
-
-.c.o-i686:
-	$(CC_SIM) $(CFLAGS_SIM) -c $< -o $@
-
-.cpp.o-i686:
-	$(CXX_SIM) $(CXXFLAGS_SIM) -c $< -o $@
-
-$(STATICLIB_PHONE): $(MODULES_ARM)
-	$(LIBTOOL_PHONE) -arch_only armv6 -o $@ $(MODULES_ARM)
-
-.c.o-arm:
-	$(CC_PHONE) $(CFLAGS_PHONE) -c $< -o $@
-
-.cpp.o-arm:
-	$(CXX_PHONE) $(CXXFLAGS_PHONE) -c $< -o $@
-
-clean:
-	rm -f core Dist/*.* u2dtmp* $(MODULES_i686) $(MODULES_ARM) $(STATICLIB_SIM) $(STATICLIB_PHONE)
+# Configuration for iPhone OS, making static libs
+# this will generate both iPhone (arm) and iPhoneSimulator (i686) libs
+
+include Makefile.srcs
+
+CFLAGS =  -g -O2 -Wall -Wmissing-prototypes -std=c99 -ffast-math -fno-strict-aliasing
+CXXFLAGS =  -g -O2 -Wall -fno-strict-aliasing
+
+GCC_VERSION = 4.2
+IPHONEOS_DEPLOYMENT_TARGET = 5.0
+MACOSX_DEPLOYMENT_TARGET = 10.6
+
+PLATFORM_SIM = iPhoneSimulator
+PLATFORM_PHONE = iPhoneOS
+
+ARCH_SIM = i686
+ARCH_PHONE = armv7
+
+PLATFORM_SIM_DEVELOPER_BIN_DIR = /Developer/Platforms/$(PLATFORM_SIM).platform/Developer/usr/bin
+PLATFORM_PHONE_DEVELOPER_BIN_DIR = /Developer/Platforms/$(PLATFORM_PHONE).platform/Developer/usr/bin
+
+SDKROOT_SIM = /Developer/Platforms/$(PLATFORM_SIM).platform/Developer/SDKs/$(PLATFORM_SIM)$(IPHONEOS_DEPLOYMENT_TARGET).sdk
+SDKROOT_PHONE = /Developer/Platforms/$(PLATFORM_PHONE).platform/Developer/SDKs/$(PLATFORM_PHONE)$(IPHONEOS_DEPLOYMENT_TARGET).sdk
+
+EXTRA_CFLAGS_SIM += -arch $(ARCH_SIM) -pipe -mdynamic-no-pic -fvisibility=hidden $(INCLUDE) -isysroot $(SDKROOT_SIM)
+EXTRA_LDFLAGS_SIM += -arch $(ARCH_SIM) -isysroot $(SDKROOT_SIM) -Wl,-dead_strip
+EXTRA_CFLAGS_SIM += -D__IPHONE_OS_VERSION_MIN_REQUIRED=20000 -mmacosx-version-min=$(MACOSX_DEPLOYMENT_TARGET)
+EXTRA_LDFLAGS_SIM += -mmacosx-version-min=$(MACOSX_DEPLOYMENT_TARGET)
+
+# Xcode complains about the -mdynamic-no-pic with an Apple Mach-O Linker Warning, so removed
+#EXTRA_CFLAGS_PHONE += -arch $(ARCH_PHONE) -pipe -mdynamic-no-pic -fvisibility=hidden $(INCLUDE) -isysroot $(SDKROOT_PHONE)
+EXTRA_CFLAGS_PHONE += -arch $(ARCH_PHONE) -pipe -fvisibility=hidden $(INCLUDE) -isysroot $(SDKROOT_PHONE)
+EXTRA_LDFLAGS_PHONE += -arch $(ARCH_PHONE) -isysroot $(SDKROOT_PHONE) -Wl,-dead_strip
+EXTRA_CFLAGS_PHONE += -miphoneos-version-min=$(IPHONEOS_DEPLOYMENT_TARGET)
+EXTRA_LDFLAGS_PHONE += -miphoneos-version-min=$(IPHONEOS_DEPLOYMENT_TARGET)
+
+AR_SIM = $(PLATFORM_SIM_DEVELOPER_BIN_DIR)/ar
+AR_PHONE = $(PLATFORM_PHONE_DEVELOPER_BIN_DIR)/ar
+
+CC_SIM = $(PLATFORM_SIM_DEVELOPER_BIN_DIR)/gcc
+CC_PHONE = $(PLATFORM_PHONE_DEVELOPER_BIN_DIR)/gcc
+
+CFLAGS_SIM = $(CFLAGS) $(EXTRA_CFLAGS_SIM)
+LDFLAGS_SIM = $(EXTRA_LDFLAGS_SIM)
+CXX_SIM = $(PLATFORM_SIM_DEVELOPER_BIN_DIR)/g++
+CXXFLAGS_SIM += $(EXTRA_CFLAGS_SIM) -fvisibility-inlines-hidden
+LIBTOOL_SIM = /Developer/Platforms/$(PLATFORM_SIM).platform/Developer/usr/bin/libtool
+
+CFLAGS_PHONE = $(CFLAGS) $(EXTRA_CFLAGS_PHONE)
+LDFLAGS_PHONE += $(EXTRA_LDFLAGS_PHONE)
+CXX_PHONE = $(PLATFORM_PHONE_DEVELOPER_BIN_DIR)/g++
+CXXFLAGS_PHONE += $(EXTRA_CFLAGS_PHONE) -fvisibility-inlines-hidden
+LIBTOOL_PHONE = /Developer/Platforms/$(PLATFORM_PHONE).platform/Developer/usr/bin/libtool
+
+TARGET = freeimage
+STATICLIB_SIM = lib$(TARGET)-iphonesimulator.a
+STATICLIB_PHONE = lib$(TARGET)-iphone.a
+HEADER = Source/FreeImage.h
+
+.SUFFIXES: .o-i686 .o-arm
+MODULES_ARM = $(SRCS:.c=.o-arm)
+MODULES_ARM := $(MODULES_ARM:.cpp=.o-arm)
+MODULES_i686 = $(SRCS:.c=.o-i686)
+MODULES_i686 := $(MODULES_i686:.cpp=.o-i686)
+
+default: all
+
+all: dist
+
+dist: FreeImage
+	mkdir -p Dist
+	cp *.a Dist/
+	cp Source/FreeImage.h Dist/
+
+FreeImage: $(STATICLIB_SIM) $(STATICLIB_PHONE)
+
+$(STATICLIB_SIM): $(MODULES_i686)
+	$(LIBTOOL_SIM) -arch_only i686 -o $@ $(MODULES_i686)
+
+.c.o-i686:
+	$(CC_SIM) $(CFLAGS_SIM) -c $< -o $@
+
+.cpp.o-i686:
+	$(CXX_SIM) $(CXXFLAGS_SIM) -c $< -o $@
+
+$(STATICLIB_PHONE): $(MODULES_ARM)
+	$(LIBTOOL_PHONE) -arch_only $(ARCH_PHONE) -o $@ $(MODULES_ARM)
+
+.c.o-arm:
+	$(CC_PHONE) $(CFLAGS_PHONE) -c $< -o $@
+
+.cpp.o-arm:
+	$(CXX_PHONE) $(CXXFLAGS_PHONE) -c $< -o $@
+
+clean:
+	rm -f core Dist/*.* u2dtmp* $(MODULES_i686) $(MODULES_ARM) $(STATICLIB_SIM) $(STATICLIB_PHONE)
diff --git a/Makefile.mingw b/Makefile.mingw
index 06a3462..d48fd6e 100644
--- a/Makefile.mingw
+++ b/Makefile.mingw
@@ -1,136 +1,136 @@
-# MinGW makefile for FreeImage
-
-# This file can be generated by ./gensrclist.sh
-include Makefile.srcs
-
-# General configuration variables.
-DESTDIR ?= $(SystemRoot)
-INSTALLDIR ?= $(DESTDIR)/system32
-DISTDIR ?= Dist
-SRCDIR ?= Source
-HEADER = FreeImage.h
-RCFILE = FreeImage.rc
-
-# Uncomment this variable to make a static library. This may
-# also be specified as an environment variable and can hold
-# any of STATIC and SHARED and must be in uppercase letters.
-# Default: SHARED
-#FREEIMAGE_LIBRARY_TYPE = STATIC
-
-# Redefine the compiler (CC defaults to �cc� for MinGW's make,
-# however there's only �gcc� available with MinGW).
-CC = gcc
-
-# Redefine the linker (we use �g++� for linking, since MinGW's
-# command �ld� comes with wrong (Linux) standard library search
-# paths).
-LD = g++
-
-#Define the �dlltool� command.
-DLLTOOL = dlltool
-
-#Define the resource compiler.
-RC = windres
-
-# Define the �copy� command.
-CP = cp
-
-# Define the �mkdir� command.
-MD = mkdir
-
-# Define the �remove� command.
-RM = rm
-
-# Define additional libraries needed.
-# libstdc++ is included by default with MinGW, however for
-# WIN32 based builds, LibRawLite needs the winsock libraries.
-LIBRARIES = -lwsock32 -lws2_32
-
-# Define some additional symboles needed for WIN32 based builds.
-WIN32_CFLAGS = -DWINVER=0x0500 $(LIB_TYPE_FLAGS) -DOPJ_STATIC
-WIN32_CXXFLAGS = $(WIN32_CFLAGS) -DLIBRAW_NODLL
-
-# Workaround for LibRawLite, which does not include C++ header
-# file stdexcept, which is casually included with MSVC but not
-# with MinGW. This can be removed after LibRawLite got control
-# over its includes again.
-WIN32_CXXFLAGS += -include stdexcept 
-
-# Define DLL image header information flags for the linker.
-WIN32_LDFLAGS = -Wl,--subsystem,windows:5.0,--major-os-version,5
-
-WIN32_STATIC_FLAGS = -DFREEIMAGE_LIB
-WIN32_SHARED_FLAGS = -DFREEIMAGE_EXPORTS
-
-MODULES = $(SRCS:.c=.o)
-MODULES := $(MODULES:.cpp=.o)
-RESOURCE = $(RCFILE:.rc=.coff)
-CFLAGS ?= -O3 -fexceptions -DNDEBUG $(WIN32_CFLAGS)
-CFLAGS += $(INCLUDE)
-CXXFLAGS ?= -O3 -fexceptions -Wno-ctor-dtor-privacy -DNDEBUG $(WIN32_CXXFLAGS)
-CXXFLAGS += $(INCLUDE)
-RCFLAGS ?= -DNDEBUG
-LDFLAGS ?= -s -shared -static -Wl,-soname,$(SOLIBNAME) $(WIN32_LDFLAGS)
-DLLTOOLFLAGS ?= --add-stdcall-underscore
-
-TARGET = FreeImage
-STATICLIB = lib$(TARGET).a
-SHAREDLIB = $(TARGET).dll
-IMPORTLIB = $(TARGET).lib
-EXPORTLIB = $(TARGET).exp
-SOLIBNAME = $(SHAREDLIB).$(VER_MAJOR)
-
-DISTSHARED = $(addprefix $(DISTDIR)/, $(SHAREDLIB) $(IMPORTLIB) $(HEADER))
-DISTSTATIC = $(addprefix $(DISTDIR)/, $(STATICLIB) $(HEADER))
-
-# The FreeImage library type defaults to SHARED.
-FREEIMAGE_LIBRARY_TYPE ?= SHARED
-
-TARGETLIB = $($(FREEIMAGE_LIBRARY_TYPE)LIB)
-TARGETDIST = $(DIST$(FREEIMAGE_LIBRARY_TYPE))
-LIB_TYPE_FLAGS = $(WIN32_$(FREEIMAGE_LIBRARY_TYPE)_FLAGS)
-
-default: all
-
-all: mkdist
-
-rebuild: clean all
-
-mkdist: FreeImage $(TARGETDIST)
-
-FreeImage: $(TARGETLIB)
-
-%.o: %.c
-	$(CC) $(CFLAGS) -c $< -o $@
-
-%.o: %.cpp
-	$(CXX) $(CXXFLAGS) -c $< -o $@
-
-%.coff: %.rc
-	$(RC) $(RCFLAGS) -o $@ $<
-
-$(DISTDIR)/%: %
-	$(CP) $< $@
-
-$(DISTDIR)/%: $(SRCDIR)/%
-	$(CP) $< $@
-
-$(STATICLIB): $(MODULES)
-	$(AR) rs $@ $(MODULES)
-
-$(IMPORTLIB) $(EXPORTLIB): $(MODULES) 
-	$(DLLTOOL) -e $(EXPORTLIB) -l $(IMPORTLIB) -D $(SHAREDLIB) $(DLLTOOLFLAGS) $(MODULES)
-
-$(SHAREDLIB): $(EXPORTLIB) $(RESOURCE)
-	$(LD) $(LDFLAGS) -o $@ $(EXPORTLIB) $(MODULES) $(RESOURCE) $(LIBRARIES)
-
-$(DISTDIR):
-	$(MD) $(DISTDIR)
-
-$(TARGETDIST): $(DISTDIR)
-
-install:
-	$(CP) $(SHAREDLIB) $(INSTALLDIR)
-
-clean:
-	$(RM) -f core $(DISTDIR)/*.* $(MODULES) $(RESOURCE) $(STATICLIB) $(SHAREDLIB) $(IMPORTLIB) $(EXPORTLIB)
+# MinGW makefile for FreeImage
+
+# This file can be generated by ./gensrclist.sh
+include Makefile.srcs
+
+# General configuration variables.
+DESTDIR ?= $(SystemRoot)
+INSTALLDIR ?= $(DESTDIR)/system32
+DISTDIR ?= Dist
+SRCDIR ?= Source
+HEADER = FreeImage.h
+RCFILE = FreeImage.rc
+
+# Uncomment this variable to make a static library. This may
+# also be specified as an environment variable and can hold
+# any of STATIC and SHARED and must be in uppercase letters.
+# Default: SHARED
+#FREEIMAGE_LIBRARY_TYPE = STATIC
+
+# Redefine the compiler (CC defaults to �cc� for MinGW's make,
+# however there's only �gcc� available with MinGW).
+CC = gcc
+
+# Redefine the linker (we use �g++� for linking, since MinGW's
+# command �ld� comes with wrong (Linux) standard library search
+# paths).
+LD = g++
+
+#Define the �dlltool� command.
+DLLTOOL = dlltool
+
+#Define the resource compiler.
+RC = windres
+
+# Define the �copy� command.
+CP = cp
+
+# Define the �mkdir� command.
+MD = mkdir
+
+# Define the �remove� command.
+RM = rm
+
+# Define additional libraries needed.
+# libstdc++ is included by default with MinGW, however for
+# WIN32 based builds, LibRawLite needs the winsock libraries.
+LIBRARIES = -lws2_32
+
+# Define some additional symboles needed for WIN32 based builds.
+WIN32_CFLAGS = -DWINVER=0x0500 $(LIB_TYPE_FLAGS) -DOPJ_STATIC
+WIN32_CXXFLAGS = $(WIN32_CFLAGS) -DLIBRAW_NODLL
+
+# Workaround for LibRawLite, which does not include C++ header
+# file stdexcept, which is casually included with MSVC but not
+# with MinGW. This can be removed after LibRawLite got control
+# over its includes again.
+WIN32_CXXFLAGS += -include stdexcept 
+
+# Define DLL image header information flags for the linker.
+WIN32_LDFLAGS = -Wl,--subsystem,windows:5.0,--major-os-version,5
+
+WIN32_STATIC_FLAGS = -DFREEIMAGE_LIB
+WIN32_SHARED_FLAGS = -DFREEIMAGE_EXPORTS
+
+MODULES = $(SRCS:.c=.o)
+MODULES := $(MODULES:.cpp=.o)
+RESOURCE = $(RCFILE:.rc=.coff)
+CFLAGS ?= -O3 -fexceptions -DNDEBUG -DDISABLE_PERF_MEASUREMENT $(WIN32_CFLAGS)
+CFLAGS += $(INCLUDE)
+CXXFLAGS ?= -O3 -fexceptions -Wno-ctor-dtor-privacy -DNDEBUG $(WIN32_CXXFLAGS)
+CXXFLAGS += $(INCLUDE)
+RCFLAGS ?= -DNDEBUG
+LDFLAGS ?= -s -shared -static -Wl,-soname,$(SOLIBNAME) $(WIN32_LDFLAGS)
+DLLTOOLFLAGS ?= --add-stdcall-underscore
+
+TARGET = FreeImage
+STATICLIB = lib$(TARGET).a
+SHAREDLIB = $(TARGET).dll
+IMPORTLIB = $(TARGET).lib
+EXPORTLIB = $(TARGET).exp
+SOLIBNAME = $(SHAREDLIB).$(VER_MAJOR)
+
+DISTSHARED = $(addprefix $(DISTDIR)/, $(SHAREDLIB) $(IMPORTLIB) $(HEADER))
+DISTSTATIC = $(addprefix $(DISTDIR)/, $(STATICLIB) $(HEADER))
+
+# The FreeImage library type defaults to SHARED.
+FREEIMAGE_LIBRARY_TYPE ?= SHARED
+
+TARGETLIB = $($(FREEIMAGE_LIBRARY_TYPE)LIB)
+TARGETDIST = $(DIST$(FREEIMAGE_LIBRARY_TYPE))
+LIB_TYPE_FLAGS = $(WIN32_$(FREEIMAGE_LIBRARY_TYPE)_FLAGS)
+
+default: all
+
+all: mkdist
+
+rebuild: clean all
+
+mkdist: FreeImage $(TARGETDIST)
+
+FreeImage: $(TARGETLIB)
+
+%.o: %.c
+	$(CC) $(CFLAGS) -c $< -o $@
+
+%.o: %.cpp
+	$(CXX) $(CXXFLAGS) -c $< -o $@
+
+%.coff: %.rc
+	$(RC) $(RCFLAGS) -o $@ $<
+
+$(DISTDIR)/%: %
+	$(CP) $< $@
+
+$(DISTDIR)/%: $(SRCDIR)/%
+	$(CP) $< $@
+
+$(STATICLIB): $(MODULES)
+	$(AR) rs $@ $(MODULES)
+
+$(IMPORTLIB) $(EXPORTLIB): $(MODULES) 
+	$(DLLTOOL) -e $(EXPORTLIB) -l $(IMPORTLIB) -D $(SHAREDLIB) $(DLLTOOLFLAGS) $(MODULES)
+
+$(SHAREDLIB): $(EXPORTLIB) $(RESOURCE)
+	$(LD) $(LDFLAGS) -o $@ $(EXPORTLIB) $(MODULES) $(RESOURCE) $(LIBRARIES)
+
+$(DISTDIR):
+	$(MD) $(DISTDIR)
+
+$(TARGETDIST): $(DISTDIR)
+
+install:
+	$(CP) $(SHAREDLIB) $(INSTALLDIR)
+
+clean:
+	$(RM) -f core $(DISTDIR)/*.* $(MODULES) $(RESOURCE) $(STATICLIB) $(SHAREDLIB) $(IMPORTLIB) $(EXPORTLIB)
diff --git a/Makefile.osx b/Makefile.osx
index d8e5a2d..c56dd9b 100644
--- a/Makefile.osx
+++ b/Makefile.osx
@@ -1,114 +1,115 @@
-# -*- Makefile -*-
-# Mac OSX makefile for FreeImage
-
-# This file can be generated by ./gensrclist.sh
-include Makefile.srcs
-
-# General configuration variables:
-CC_PPC = gcc-4.0
-CC_I386 = gcc-4.0
-CC_X86_64 = gcc-4.0
-CPP_PPC = g++-4.0
-CPP_I386 = g++-4.0
-CPP_X86_64 = g++-4.0
-COMPILERFLAGS = -Os -fexceptions -fvisibility=hidden -DNO_LCMS
-COMPILERFLAGS_PPC = -arch ppc
-COMPILERFLAGS_I386 = -arch i386
-COMPILERFLAGS_X86_64 = -arch x86_64
-COMPILERPPFLAGS = -Wno-ctor-dtor-privacy
-INCLUDE += 
-INCLUDE_PPC = -isysroot /Developer/SDKs/MacOSX10.5.sdk
-INCLUDE_I386 = -isysroot /Developer/SDKs/MacOSX10.5.sdk
-INCLUDE_X86_64 = -isysroot /Developer/SDKs/MacOSX10.6.sdk
-CFLAGS_PPC = $(COMPILERFLAGS) $(COMPILERFLAGS_PPC) $(INCLUDE) $(INCLUDE_PPC)
-CFLAGS_I386 = $(COMPILERFLAGS) $(COMPILERFLAGS_I386) $(INCLUDE) $(INCLUDE_I386)
-CFLAGS_X86_64 = $(COMPILERFLAGS) $(COMPILERFLAGS_X86_64) $(INCLUDE) $(INCLUDE_X86_64)
-CPPFLAGS_PPC = $(COMPILERPPFLAGS) $(CFLAGS_PPC)
-CPPFLAGS_I386 = $(COMPILERPPFLAGS) $(CFLAGS_I386)
-CPPFLAGS_X86_64 = $(COMPILERPPFLAGS) $(CFLAGS_X86_64)
-LIBRARIES_PPC = -Wl,-syslibroot /Developer/SDKs/MacOSX10.5.sdk
-LIBRARIES_I386 = -Wl,-syslibroot /Developer/SDKs/MacOSX10.5.sdk
-LIBRARIES_X86_64 = -Wl,-syslibroot /Developer/SDKs/MacOSX10.6.sdk
-LIBTOOL = libtool
-LIPO = lipo
-
-TARGET = freeimage
-STATICLIB = lib$(TARGET).a
-SHAREDLIB = lib$(TARGET)-$(VER_MAJOR).$(VER_MINOR).dylib
-LIBNAME = lib$(TARGET).$(VER_MAJOR).dylib
-HEADER = Source/FreeImage.h
-
-.SUFFIXES: .o-ppc .o-i386 .o-x86_64
-MODULES_PPC = $(SRCS:.c=.o-ppc)
-MODULES_I386 = $(SRCS:.c=.o-i386)
-MODULES_X86_64 = $(SRCS:.c=.o-x86_64)
-MODULES_PPC := $(MODULES_PPC:.cpp=.o-ppc)
-MODULES_I386 := $(MODULES_I386:.cpp=.o-i386)
-MODULES_X86_64 := $(MODULES_X86_64:.cpp=.o-x86_64)
-
-PREFIX = /usr/local
-INSTALLDIR = $(PREFIX)/lib
-INCDIR = $(PREFIX)/include
-
-default: all
-
-all: dist
-
-dist: FreeImage
-	cp *.a Dist
-	cp *.dylib Dist
-	cp Source/FreeImage.h Dist
-
-FreeImage: $(STATICLIB) $(SHAREDLIB)
-
-$(STATICLIB): $(STATICLIB)-ppc $(STATICLIB)-i386 $(STATICLIB)-x86_64
-	$(LIPO) -create $(STATICLIB)-ppc $(STATICLIB)-i386 $(STATICLIB)-x86_64 -output $(STATICLIB)
-
-$(STATICLIB)-ppc: $(MODULES_PPC)
-	$(LIBTOOL) -arch_only ppc -o $@ $(MODULES_PPC)
-
-$(STATICLIB)-i386: $(MODULES_I386)
-	$(LIBTOOL) -arch_only i386 -o $@ $(MODULES_I386)
-
-$(STATICLIB)-x86_64: $(MODULES_X86_64)
-	$(LIBTOOL) -arch_only x86_64 -o $@ $(MODULES_X86_64)
-
-$(SHAREDLIB): $(SHAREDLIB)-ppc $(SHAREDLIB)-i386 $(SHAREDLIB)-x86_64
-	$(LIPO) -create $(SHAREDLIB)-ppc $(SHAREDLIB)-i386 $(SHAREDLIB)-x86_64 -output $(SHAREDLIB)
-
-$(SHAREDLIB)-ppc: $(MODULES_PPC)
-	$(CPP_PPC) -arch ppc -dynamiclib $(LIBRARIES_PPC) -o $@ $(MODULES_PPC)
-
-$(SHAREDLIB)-i386: $(MODULES_I386)
-	$(CPP_I386) -arch i386 -dynamiclib $(LIBRARIES_I386) -o $@ $(MODULES_I386)
-
-$(SHAREDLIB)-x86_64: $(MODULES_X86_64)
-	$(CPP_X86_64) -arch x86_64 -dynamiclib $(LIBRARIES_X86_64) -o $@ $(MODULES_X86_64)
-
-.c.o-ppc:
-	$(CC_PPC) $(CFLAGS_PPC) -c $< -o $@
-
-.c.o-i386:
-	$(CC_I386) $(CFLAGS_I386) -c $< -o $@
-
-.c.o-x86_64:
-	$(CC_X86_64) $(CFLAGS_X86_64) -c $< -o $@
-
-.cpp.o-ppc:
-	$(CPP_PPC) $(CPPFLAGS_PPC) -c $< -o $@
-
-.cpp.o-i386:
-	$(CPP_I386) $(CPPFLAGS_I386) -c $< -o $@
-
-.cpp.o-x86_64:
-	$(CPP_X86_64) $(CPPFLAGS_X86_64) -c $< -o $@
-
-install:
-	install -d -m 755 -o root -g wheel $(INCDIR) $(INSTALLDIR)
-	install -m 644 -o root -g wheel $(HEADER) $(INCDIR)
-	install -m 644 -o root -g wheel $(SHAREDLIB) $(STATICLIB) $(INSTALLDIR)
-	ranlib -sf $(INSTALLDIR)/$(STATICLIB)
-	ln -sf $(SHAREDLIB) $(INSTALLDIR)/$(LIBNAME)
-
-clean:
-	rm -f core Dist/*.* u2dtmp* $(MODULES_PPC) $(MODULES_I386) $(MODULES_X86_64) $(STATICLIB) $(STATICLIB)-ppc $(STATICLIB)-i386 $(SHAREDLIB) $(SHAREDLIB)-ppc $(SHAREDLIB)-i386 $(SHAREDLIB)-x86_64
+# -*- Makefile -*-
+# Mac OSX makefile for FreeImage
+
+# This file can be generated by ./gensrclist.sh
+include Makefile.srcs
+
+# General configuration variables:
+CC_PPC = gcc-4.0
+CC_I386 = gcc-4.0
+CC_X86_64 = gcc-4.0
+CPP_PPC = g++-4.0
+CPP_I386 = g++-4.0
+CPP_X86_64 = g++-4.0
+COMPILERFLAGS = -Os -fexceptions -fvisibility=hidden -DNO_LCMS
+COMPILERFLAGS_PPC = -arch ppc
+COMPILERFLAGS_I386 = -arch i386
+COMPILERFLAGS_X86_64 = -arch x86_64
+COMPILERPPFLAGS = -Wno-ctor-dtor-privacy
+INCLUDE += 
+INCLUDE_PPC = -isysroot /Developer/SDKs/MacOSX10.5.sdk
+INCLUDE_I386 = -isysroot /Developer/SDKs/MacOSX10.5.sdk
+INCLUDE_X86_64 = -isysroot /Developer/SDKs/MacOSX10.6.sdk
+CFLAGS_PPC = $(COMPILERFLAGS) $(COMPILERFLAGS_PPC) $(INCLUDE) $(INCLUDE_PPC)
+CFLAGS_I386 = $(COMPILERFLAGS) $(COMPILERFLAGS_I386) $(INCLUDE) $(INCLUDE_I386)
+CFLAGS_X86_64 = $(COMPILERFLAGS) $(COMPILERFLAGS_X86_64) $(INCLUDE) $(INCLUDE_X86_64)
+CPPFLAGS_PPC = $(COMPILERPPFLAGS) $(CFLAGS_PPC)
+CPPFLAGS_I386 = $(COMPILERPPFLAGS) $(CFLAGS_I386)
+CPPFLAGS_X86_64 = $(COMPILERPPFLAGS) $(CFLAGS_X86_64)
+LIBRARIES_PPC = -Wl,-syslibroot /Developer/SDKs/MacOSX10.5.sdk
+LIBRARIES_I386 = -Wl,-syslibroot /Developer/SDKs/MacOSX10.5.sdk
+LIBRARIES_X86_64 = -Wl,-syslibroot /Developer/SDKs/MacOSX10.6.sdk
+LIBTOOL = libtool
+LIPO = lipo
+
+TARGET = freeimage
+STATICLIB = lib$(TARGET).a
+SHAREDLIB = lib$(TARGET)-$(VER_MAJOR).$(VER_MINOR).dylib
+LIBNAME = lib$(TARGET).$(VER_MAJOR).dylib
+HEADER = Source/FreeImage.h
+
+.SUFFIXES: .o-ppc .o-i386 .o-x86_64
+MODULES_PPC = $(SRCS:.c=.o-ppc)
+MODULES_I386 = $(SRCS:.c=.o-i386)
+MODULES_X86_64 = $(SRCS:.c=.o-x86_64)
+MODULES_PPC := $(MODULES_PPC:.cpp=.o-ppc)
+MODULES_I386 := $(MODULES_I386:.cpp=.o-i386)
+MODULES_X86_64 := $(MODULES_X86_64:.cpp=.o-x86_64)
+
+PREFIX = /usr/local
+INSTALLDIR = $(PREFIX)/lib
+INCDIR = $(PREFIX)/include
+
+default: all
+
+all: dist
+
+dist: FreeImage
+	mkdir -p Dist
+	cp *.a Dist/
+	cp *.dylib Dist/
+	cp Source/FreeImage.h Dist/
+
+FreeImage: $(STATICLIB) $(SHAREDLIB)
+
+$(STATICLIB): $(STATICLIB)-ppc $(STATICLIB)-i386 $(STATICLIB)-x86_64
+	$(LIPO) -create $(STATICLIB)-ppc $(STATICLIB)-i386 $(STATICLIB)-x86_64 -output $(STATICLIB)
+
+$(STATICLIB)-ppc: $(MODULES_PPC)
+	$(LIBTOOL) -arch_only ppc -o $@ $(MODULES_PPC)
+
+$(STATICLIB)-i386: $(MODULES_I386)
+	$(LIBTOOL) -arch_only i386 -o $@ $(MODULES_I386)
+
+$(STATICLIB)-x86_64: $(MODULES_X86_64)
+	$(LIBTOOL) -arch_only x86_64 -o $@ $(MODULES_X86_64)
+
+$(SHAREDLIB): $(SHAREDLIB)-ppc $(SHAREDLIB)-i386 $(SHAREDLIB)-x86_64
+	$(LIPO) -create $(SHAREDLIB)-ppc $(SHAREDLIB)-i386 $(SHAREDLIB)-x86_64 -output $(SHAREDLIB)
+
+$(SHAREDLIB)-ppc: $(MODULES_PPC)
+	$(CPP_PPC) -arch ppc -dynamiclib $(LIBRARIES_PPC) -o $@ $(MODULES_PPC)
+
+$(SHAREDLIB)-i386: $(MODULES_I386)
+	$(CPP_I386) -arch i386 -dynamiclib $(LIBRARIES_I386) -o $@ $(MODULES_I386)
+
+$(SHAREDLIB)-x86_64: $(MODULES_X86_64)
+	$(CPP_X86_64) -arch x86_64 -dynamiclib $(LIBRARIES_X86_64) -o $@ $(MODULES_X86_64)
+
+.c.o-ppc:
+	$(CC_PPC) $(CFLAGS_PPC) -c $< -o $@
+
+.c.o-i386:
+	$(CC_I386) $(CFLAGS_I386) -c $< -o $@
+
+.c.o-x86_64:
+	$(CC_X86_64) $(CFLAGS_X86_64) -c $< -o $@
+
+.cpp.o-ppc:
+	$(CPP_PPC) $(CPPFLAGS_PPC) -c $< -o $@
+
+.cpp.o-i386:
+	$(CPP_I386) $(CPPFLAGS_I386) -c $< -o $@
+
+.cpp.o-x86_64:
+	$(CPP_X86_64) $(CPPFLAGS_X86_64) -c $< -o $@
+
+install:
+	install -d -m 755 -o root -g wheel $(INCDIR) $(INSTALLDIR)
+	install -m 644 -o root -g wheel $(HEADER) $(INCDIR)
+	install -m 644 -o root -g wheel $(SHAREDLIB) $(STATICLIB) $(INSTALLDIR)
+	ranlib -sf $(INSTALLDIR)/$(STATICLIB)
+	ln -sf $(SHAREDLIB) $(INSTALLDIR)/$(LIBNAME)
+
+clean:
+	rm -f core Dist/*.* u2dtmp* $(MODULES_PPC) $(MODULES_I386) $(MODULES_X86_64) $(STATICLIB) $(STATICLIB)-ppc $(STATICLIB)-i386 $(SHAREDLIB) $(SHAREDLIB)-ppc $(SHAREDLIB)-i386 $(SHAREDLIB)-x86_64
diff --git a/Makefile.solaris b/Makefile.solaris
index a17c68e..303c2fc 100644
--- a/Makefile.solaris
+++ b/Makefile.solaris
@@ -1,65 +1,66 @@
-# Solaris9 makefile for FreeImage. Tested on Solaris9 with tools from
-# Sunfreeware.com.
-
-# This file can be generated by ./gensrclist.sh
-include Makefile.srcs
-
-# General configuration variables:
-CC = gcc
-CPP = g++
-AR = ar
-
-INSTALLDIR = /usr/local
-
-# Converts cr/lf to just lf
-DOS2UNIX = dos2unix
-
-COMPILERFLAGS = -O3
-LIBRARIES = -lstdc++
-
-MODULES = $(SRCS:.c=.o)
-MODULES := $(MODULES:.cpp=.o)
-CFLAGS = $(COMPILERFLAGS) $(INCLUDE)
-CPPFLAGS = $(COMPILERFLAGS)  -Wno-ctor-dtor-privacy $(INCLUDE)
-
-TARGET  = freeimage
-STATICLIB = lib$(TARGET).a
-SHAREDLIB = lib$(TARGET)-$(VER_MAJOR).$(VER_MINOR).so
-LIBNAME = lib$(TARGET).so.$(VER_MAJOR)
-
-
-
-default: all
-
-all: dist
-
-dist: FreeImage
-	cp *.a Dist
-	cp *.so Dist
-	cp Source/FreeImage.h Dist
-
-dos2unix:
-	@$(DOS2UNIX) $(SRCS) $(INCLS)
-
-FreeImage: $(STATICLIB) $(SHAREDLIB)
-
-.c.o:
-	$(CC) $(CFLAGS) -c $< -o $@
-
-.cpp.o:
-	$(CPP) $(CPPFLAGS) -c $< -o $@
-
-$(STATICLIB): $(MODULES)
-	$(AR) r $@ $(MODULES)
-
-$(SHAREDLIB): $(MODULES)
-	$(CC) -s -G -Wl,-soname=$(LIBNAME) -o $@ $(MODULES) $(LIBRARIES)
-
-install:
-	install -m 644 -o root -g root Source/FreeImage.h $(INSTALLDIR)/include
-	install -m 644 -o root -g root $(STATICLIB) $(INSTALLDIR)/lib
-	install -m 755 -o root -g root $(SHAREDLIB) $(INSTALLDIR)/lib
-	ln -sf $(SHAREDLIB) $(INSTALLDIR)/lib/$(LIBNAME)
-
-clean:
-	rm -rf core Dist/*.* u2dtmp* $(MODULES) $(STATICLIB) $(SHAREDLIB) $(LIBNAME)
+# Solaris9 makefile for FreeImage. Tested on Solaris9 with tools from
+# Sunfreeware.com.
+
+# This file can be generated by ./gensrclist.sh
+include Makefile.srcs
+
+# General configuration variables:
+CC = gcc
+CPP = g++
+AR = ar
+
+INSTALLDIR = /usr/local
+
+# Converts cr/lf to just lf
+DOS2UNIX = dos2unix
+
+COMPILERFLAGS = -O3
+LIBRARIES = -lstdc++
+
+MODULES = $(SRCS:.c=.o)
+MODULES := $(MODULES:.cpp=.o)
+CFLAGS = $(COMPILERFLAGS) $(INCLUDE)
+CPPFLAGS = $(COMPILERFLAGS)  -Wno-ctor-dtor-privacy $(INCLUDE)
+
+TARGET  = freeimage
+STATICLIB = lib$(TARGET).a
+SHAREDLIB = lib$(TARGET)-$(VER_MAJOR).$(VER_MINOR).so
+LIBNAME = lib$(TARGET).so.$(VER_MAJOR)
+
+
+
+default: all
+
+all: dist
+
+dist: FreeImage
+	mkdir -p Dist
+	cp *.a Dist/
+	cp *.so Dist/
+	cp Source/FreeImage.h Dist/
+
+dos2unix:
+	@$(DOS2UNIX) $(SRCS) $(INCLS)
+
+FreeImage: $(STATICLIB) $(SHAREDLIB)
+
+.c.o:
+	$(CC) $(CFLAGS) -c $< -o $@
+
+.cpp.o:
+	$(CPP) $(CPPFLAGS) -c $< -o $@
+
+$(STATICLIB): $(MODULES)
+	$(AR) r $@ $(MODULES)
+
+$(SHAREDLIB): $(MODULES)
+	$(CC) -s -G -Wl,-soname=$(LIBNAME) -o $@ $(MODULES) $(LIBRARIES)
+
+install:
+	install -m 644 -o root -g root Source/FreeImage.h $(INSTALLDIR)/include
+	install -m 644 -o root -g root $(STATICLIB) $(INSTALLDIR)/lib
+	install -m 755 -o root -g root $(SHAREDLIB) $(INSTALLDIR)/lib
+	ln -sf $(SHAREDLIB) $(INSTALLDIR)/lib/$(LIBNAME)
+
+clean:
+	rm -rf core Dist/*.* u2dtmp* $(MODULES) $(STATICLIB) $(SHAREDLIB) $(LIBNAME)
diff --git a/Makefile.srcs b/Makefile.srcs
index 5648de8..2205fa0 100644
--- a/Makefile.srcs
+++ b/Makefile.srcs
@@ -1,6 +1,6 @@
 VER_MAJOR = 3
-VER_MINOR = 15.4
-SRCS = ./Source/FreeImage/BitmapAccess.cpp ./Source/FreeImage/ColorLookup.cpp ./Source/FreeImage/FreeImage.cpp ./Source/FreeImage/FreeImageC.c ./Source/FreeImage/FreeImageIO.cpp ./Source/FreeImage/GetType.cpp ./Source/FreeImage/MemoryIO.cpp ./Source/FreeImage/PixelAccess.cpp ./Source/FreeImage/J2KHelper.cpp ././Source/FreeImage/MNGHelper.cpp ./Source/FreeImage/Plugin.cpp ./Source/FreeImage/PluginBMP.cpp ./Source/FreeImage/PluginCUT.cpp ./Source/FreeImage/PluginDDS.cpp ./Source/FreeImage/ [...]
-INCLS = ./Examples/OpenGL/TextureManager/TextureManager.h ./Examples/Plugin/PluginCradle.h ./Examples/Generic/FIIO_Mem.h ./Source/CacheFile.h ./Source/LibTIFF/tiffconf.vc.h ./Source/LibTIFF/tif_config.h ./Source/LibTIFF/tif_fax3.h ./Source/LibTIFF/tif_config.vc.h ./Source/LibTIFF/tiffvers.h ./Source/LibTIFF/tiffio.h ./Source/LibTIFF/tif_config.wince.h ./Source/LibTIFF/tiffconf.wince.h ./Source/LibTIFF/tiff.h ./Source/LibTIFF/uvcode.h ./Source/LibTIFF/tif_dir.h ./Source/LibTIFF/t4.h ./Sou [...]
+VER_MINOR = 17.0
+SRCS = ./Source/FreeImage/BitmapAccess.cpp ./Source/FreeImage/ColorLookup.cpp ./Source/FreeImage/FreeImage.cpp ./Source/FreeImage/FreeImageC.c ./Source/FreeImage/FreeImageIO.cpp ./Source/FreeImage/GetType.cpp ./Source/FreeImage/MemoryIO.cpp ./Source/FreeImage/PixelAccess.cpp ./Source/FreeImage/J2KHelper.cpp ././Source/FreeImage/MNGHelper.cpp ./Source/FreeImage/Plugin.cpp ./Source/FreeImage/PluginBMP.cpp ./Source/FreeImage/PluginCUT.cpp ./Source/FreeImage/PluginDDS.cpp ./Source/FreeImage/ [...]
+INCLS = ./Examples/OpenGL/TextureManager/TextureManager.h ./Examples/Plugin/PluginCradle.h ./Examples/Generic/FIIO_Mem.h ./Source/MapIntrospector.h ./Source/FreeImage - Copie.h ./Source/CacheFile.h ./Source/LibTIFF/tiffconf.vc.h ./Source/LibTIFF/tif_config.h ./Source/LibTIFF/tif_fax3.h ./Source/LibTIFF/tif_config.vc.h ./Source/LibTIFF/tiffvers.h ./Source/LibTIFF/tiffio.h ./Source/LibTIFF/tif_config.wince.h ./Source/LibTIFF/tiffconf.wince.h ./Source/LibTIFF/tiff.h ./Source/LibTIFF/uvcode. [...]
 
-INCLUDE = -I. -ISource -ISource/Metadata -ISource/FreeImageToolkit -ISource/LibJPEG -ISource/LibPNG -ISource/LibTIFF4 -ISource/ZLib -ISource/LibOpenJPEG -ISource/OpenEXR -ISource/OpenEXR/Half -ISource/OpenEXR/Iex -ISource/OpenEXR/IlmImf -ISource/OpenEXR/IlmThread -ISource/OpenEXR/Imath -ISource/LibRawLite -ISource/LibRawLite/dcraw -ISource/LibRawLite/internal -ISource/LibRawLite/libraw -ISource/LibRawLite/src
+INCLUDE = -I. -ISource -ISource/Metadata -ISource/FreeImageToolkit -ISource/LibJPEG -ISource/LibPNG -ISource/LibTIFF4 -ISource/ZLib -ISource/LibOpenJPEG -ISource/OpenEXR -ISource/OpenEXR/Half -ISource/OpenEXR/Iex -ISource/OpenEXR/IlmImf -ISource/OpenEXR/IlmThread -ISource/OpenEXR/Imath -ISource/OpenEXR/IexMath -ISource/LibRawLite -ISource/LibRawLite/dcraw -ISource/LibRawLite/internal -ISource/LibRawLite/libraw -ISource/LibRawLite/src -ISource/LibWebP -ISource/LibJXR -ISource/LibJXR/commo [...]
diff --git a/README.iphone b/README.iphone
index 32d41db..181912f 100644
--- a/README.iphone
+++ b/README.iphone
@@ -5,6 +5,14 @@ http://robertcarlsen.net/2009/03/16/openframeworks-iphone-586
 http://robertcarlsen.net/2009/03/25/openframeworks-iphone-libs-593
 http://4u.jeffcrouse.info/of/
 
+See also : 
+
+Makefile for XCode 4.6 and iOS SDK 6.1 
+http://sourceforge.net/p/freeimage/discussion/36109/thread/1f345192/
+
+Building the FreeImage lib for PIE and armv7
+http://forum.openframeworks.cc/t/building-the-freeimage-lib-for-pie-and-armv7/13714
+
 -----------------------------------------------------------------------------
 
 Run "make -f Makefile.iphone". 
diff --git a/Source/FreeImage.h b/Source/FreeImage.h
index fd2092e..e2d1c5a 100644
--- a/Source/FreeImage.h
+++ b/Source/FreeImage.h
@@ -1,1104 +1,1153 @@
-// ==========================================================
-// FreeImage 3
-//
-// Design and implementation by
-// - Floris van den Berg (flvdberg at wxs.nl)
-// - Herv� Drolon (drolon at infonie.fr)
-//
-// Contributors:
-// - see changes log named 'Whatsnew.txt', see header of each .h and .cpp file
-//
-// This file is part of FreeImage 3
-//
-// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
-// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
-// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
-// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
-// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
-// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
-// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
-// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
-// THIS DISCLAIMER.
-//
-// Use at your own risk!
-// ==========================================================
-
-#ifndef FREEIMAGE_H
-#define FREEIMAGE_H
-
-// Version information ------------------------------------------------------
-
-#define FREEIMAGE_MAJOR_VERSION   3
-#define FREEIMAGE_MINOR_VERSION   15
-#define FREEIMAGE_RELEASE_SERIAL  4
-
-// Compiler options ---------------------------------------------------------
-
-#include <wchar.h>	// needed for UNICODE functions
-
-#if defined(FREEIMAGE_LIB)
-	#define DLL_API
-	#define DLL_CALLCONV
-#else
-	#if defined(_WIN32) || defined(__WIN32__)
-		#define DLL_CALLCONV __stdcall
-		// The following ifdef block is the standard way of creating macros which make exporting 
-		// from a DLL simpler. All files within this DLL are compiled with the FREEIMAGE_EXPORTS
-		// symbol defined on the command line. this symbol should not be defined on any project
-		// that uses this DLL. This way any other project whose source files include this file see 
-		// DLL_API functions as being imported from a DLL, wheras this DLL sees symbols
-		// defined with this macro as being exported.
-		#ifdef FREEIMAGE_EXPORTS
-			#define DLL_API __declspec(dllexport)
-		#else
-			#define DLL_API __declspec(dllimport)
-		#endif // FREEIMAGE_EXPORTS
-	#else 
-		// try the gcc visibility support (see http://gcc.gnu.org/wiki/Visibility)
-		#if defined(__GNUC__) && ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
-			#ifndef GCC_HASCLASSVISIBILITY
-				#define GCC_HASCLASSVISIBILITY
-			#endif
-		#endif // __GNUC__
-		#define DLL_CALLCONV
-		#if defined(GCC_HASCLASSVISIBILITY)
-			#define DLL_API __attribute__ ((visibility("default")))
-		#else
-			#define DLL_API
-		#endif		
-	#endif // WIN32 / !WIN32
-#endif // FREEIMAGE_LIB
-
-// Some versions of gcc may have BYTE_ORDER or __BYTE_ORDER defined
-// If your big endian system isn't being detected, add an OS specific check
-#if (defined(BYTE_ORDER) && BYTE_ORDER==BIG_ENDIAN) || \
-	(defined(__BYTE_ORDER) && __BYTE_ORDER==__BIG_ENDIAN) || \
-	defined(__BIG_ENDIAN__)
-#define FREEIMAGE_BIGENDIAN
-#endif // BYTE_ORDER
-
-// This really only affects 24 and 32 bit formats, the rest are always RGB order.
-#define FREEIMAGE_COLORORDER_BGR	0
-#define FREEIMAGE_COLORORDER_RGB	1
-#if defined(FREEIMAGE_BIGENDIAN)
-#define FREEIMAGE_COLORORDER FREEIMAGE_COLORORDER_RGB
-#else
-#define FREEIMAGE_COLORORDER FREEIMAGE_COLORORDER_BGR
-#endif
-
-// Ensure 4-byte enums if we're using Borland C++ compilers
-#if defined(__BORLANDC__)
-#pragma option push -b
-#endif
-
-// For C compatibility --------------------------------------------------------
-
-#ifdef __cplusplus
-#define FI_DEFAULT(x)	= x
-#define FI_ENUM(x)      enum x
-#define FI_STRUCT(x)	struct x
-#else
-#define FI_DEFAULT(x)
-#define FI_ENUM(x)      typedef int x; enum x
-#define FI_STRUCT(x)	typedef struct x x; struct x
-#endif
-
-// Bitmap types -------------------------------------------------------------
-
-FI_STRUCT (FIBITMAP) { void *data; };
-FI_STRUCT (FIMULTIBITMAP) { void *data; };
-
-// Types used in the library (directly copied from Windows) -----------------
-
-#if defined(__MINGW32__) && defined(_WINDOWS_H)
-#define _WINDOWS_	// prevent a bug in MinGW32
-#endif // __MINGW32__
-
-#ifndef _WINDOWS_
-#define _WINDOWS_
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-#ifndef TRUE
-#define TRUE 1
-#endif
-#ifndef NULL
-#define NULL 0
-#endif
-
-#ifndef SEEK_SET
-#define SEEK_SET  0
-#define SEEK_CUR  1
-#define SEEK_END  2
-#endif
-
-#ifndef _MSC_VER
-// define portable types for 32-bit / 64-bit OS
-#include <inttypes.h>
-typedef int32_t BOOL;
-typedef uint8_t BYTE;
-typedef uint16_t WORD;
-typedef uint32_t DWORD;
-typedef int32_t LONG;
-typedef int64_t INT64;
-typedef uint64_t UINT64;
-#else
-// MS is not C99 ISO compliant
-typedef long BOOL;
-typedef unsigned char BYTE;
-typedef unsigned short WORD;
-typedef unsigned long DWORD;
-typedef long LONG;
-typedef signed __int64 INT64;
-typedef unsigned __int64 UINT64;
-#endif // _MSC_VER
-
-#if (defined(_WIN32) || defined(__WIN32__))
-#pragma pack(push, 1)
-#else
-#pragma pack(1)
-#endif // WIN32
-
-typedef struct tagRGBQUAD {
-#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
-  BYTE rgbBlue;
-  BYTE rgbGreen;
-  BYTE rgbRed;
-#else
-  BYTE rgbRed;
-  BYTE rgbGreen;
-  BYTE rgbBlue;
-#endif // FREEIMAGE_COLORORDER
-  BYTE rgbReserved;
-} RGBQUAD;
-
-typedef struct tagRGBTRIPLE {
-#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
-  BYTE rgbtBlue;
-  BYTE rgbtGreen;
-  BYTE rgbtRed;
-#else
-  BYTE rgbtRed;
-  BYTE rgbtGreen;
-  BYTE rgbtBlue;
-#endif // FREEIMAGE_COLORORDER
-} RGBTRIPLE;
-
-#if (defined(_WIN32) || defined(__WIN32__))
-#pragma pack(pop)
-#else
-#pragma pack()
-#endif // WIN32
-
-typedef struct tagBITMAPINFOHEADER{
-  DWORD biSize;
-  LONG  biWidth; 
-  LONG  biHeight; 
-  WORD  biPlanes; 
-  WORD  biBitCount;
-  DWORD biCompression; 
-  DWORD biSizeImage; 
-  LONG  biXPelsPerMeter; 
-  LONG  biYPelsPerMeter; 
-  DWORD biClrUsed; 
-  DWORD biClrImportant;
-} BITMAPINFOHEADER, *PBITMAPINFOHEADER; 
-
-typedef struct tagBITMAPINFO { 
-  BITMAPINFOHEADER bmiHeader; 
-  RGBQUAD          bmiColors[1];
-} BITMAPINFO, *PBITMAPINFO;
-
-#endif // _WINDOWS_
-
-// Types used in the library (specific to FreeImage) ------------------------
-
-#if (defined(_WIN32) || defined(__WIN32__))
-#pragma pack(push, 1)
-#else
-#pragma pack(1)
-#endif // WIN32
-
-/** 48-bit RGB 
-*/
-typedef struct tagFIRGB16 {
-	WORD red;
-	WORD green;
-	WORD blue;
-} FIRGB16;
-
-/** 64-bit RGBA
-*/
-typedef struct tagFIRGBA16 {
-	WORD red;
-	WORD green;
-	WORD blue;
-	WORD alpha;
-} FIRGBA16;
-
-/** 96-bit RGB Float
-*/
-typedef struct tagFIRGBF {
-	float red;
-	float green;
-	float blue;
-} FIRGBF;
-
-/** 128-bit RGBA Float
-*/
-typedef struct tagFIRGBAF {
-	float red;
-	float green;
-	float blue;
-	float alpha;
-} FIRGBAF;
-
-/** Data structure for COMPLEX type (complex number)
-*/
-typedef struct tagFICOMPLEX {
-    /// real part
-	double r;
-	/// imaginary part
-    double i;
-} FICOMPLEX;
-
-#if (defined(_WIN32) || defined(__WIN32__))
-#pragma pack(pop)
-#else
-#pragma pack()
-#endif // WIN32
-
-// Indexes for byte arrays, masks and shifts for treating pixels as words ---
-// These coincide with the order of RGBQUAD and RGBTRIPLE -------------------
-
-#ifndef FREEIMAGE_BIGENDIAN
-#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
-// Little Endian (x86 / MS Windows, Linux) : BGR(A) order
-#define FI_RGBA_RED				2
-#define FI_RGBA_GREEN			1
-#define FI_RGBA_BLUE			0
-#define FI_RGBA_ALPHA			3
-#define FI_RGBA_RED_MASK		0x00FF0000
-#define FI_RGBA_GREEN_MASK		0x0000FF00
-#define FI_RGBA_BLUE_MASK		0x000000FF
-#define FI_RGBA_ALPHA_MASK		0xFF000000
-#define FI_RGBA_RED_SHIFT		16
-#define FI_RGBA_GREEN_SHIFT		8
-#define FI_RGBA_BLUE_SHIFT		0
-#define FI_RGBA_ALPHA_SHIFT		24
-#else
-// Little Endian (x86 / MaxOSX) : RGB(A) order
-#define FI_RGBA_RED				0
-#define FI_RGBA_GREEN			1
-#define FI_RGBA_BLUE			2
-#define FI_RGBA_ALPHA			3
-#define FI_RGBA_RED_MASK		0x000000FF
-#define FI_RGBA_GREEN_MASK		0x0000FF00
-#define FI_RGBA_BLUE_MASK		0x00FF0000
-#define FI_RGBA_ALPHA_MASK		0xFF000000
-#define FI_RGBA_RED_SHIFT		0
-#define FI_RGBA_GREEN_SHIFT		8
-#define FI_RGBA_BLUE_SHIFT		16
-#define FI_RGBA_ALPHA_SHIFT		24
-#endif // FREEIMAGE_COLORORDER
-#else
-#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
-// Big Endian (PPC / none) : BGR(A) order
-#define FI_RGBA_RED				2
-#define FI_RGBA_GREEN			1
-#define FI_RGBA_BLUE			0
-#define FI_RGBA_ALPHA			3
-#define FI_RGBA_RED_MASK		0x0000FF00
-#define FI_RGBA_GREEN_MASK		0x00FF0000
-#define FI_RGBA_BLUE_MASK		0xFF000000
-#define FI_RGBA_ALPHA_MASK		0x000000FF
-#define FI_RGBA_RED_SHIFT		8
-#define FI_RGBA_GREEN_SHIFT		16
-#define FI_RGBA_BLUE_SHIFT		24
-#define FI_RGBA_ALPHA_SHIFT		0
-#else
-// Big Endian (PPC / Linux, MaxOSX) : RGB(A) order
-#define FI_RGBA_RED				0
-#define FI_RGBA_GREEN			1
-#define FI_RGBA_BLUE			2
-#define FI_RGBA_ALPHA			3
-#define FI_RGBA_RED_MASK		0xFF000000
-#define FI_RGBA_GREEN_MASK		0x00FF0000
-#define FI_RGBA_BLUE_MASK		0x0000FF00
-#define FI_RGBA_ALPHA_MASK		0x000000FF
-#define FI_RGBA_RED_SHIFT		24
-#define FI_RGBA_GREEN_SHIFT		16
-#define FI_RGBA_BLUE_SHIFT		8
-#define FI_RGBA_ALPHA_SHIFT		0
-#endif // FREEIMAGE_COLORORDER
-#endif // FREEIMAGE_BIGENDIAN
-
-#define FI_RGBA_RGB_MASK		(FI_RGBA_RED_MASK|FI_RGBA_GREEN_MASK|FI_RGBA_BLUE_MASK)
-
-// The 16bit macros only include masks and shifts, since each color element is not byte aligned
-
-#define FI16_555_RED_MASK		0x7C00
-#define FI16_555_GREEN_MASK		0x03E0
-#define FI16_555_BLUE_MASK		0x001F
-#define FI16_555_RED_SHIFT		10
-#define FI16_555_GREEN_SHIFT	5
-#define FI16_555_BLUE_SHIFT		0
-#define FI16_565_RED_MASK		0xF800
-#define FI16_565_GREEN_MASK		0x07E0
-#define FI16_565_BLUE_MASK		0x001F
-#define FI16_565_RED_SHIFT		11
-#define FI16_565_GREEN_SHIFT	5
-#define FI16_565_BLUE_SHIFT		0
-
-// ICC profile support ------------------------------------------------------
-
-#define FIICC_DEFAULT			0x00
-#define FIICC_COLOR_IS_CMYK		0x01
-
-FI_STRUCT (FIICCPROFILE) { 
-	WORD    flags;	// info flag
-	DWORD	size;	// profile's size measured in bytes
-	void   *data;	// points to a block of contiguous memory containing the profile
-};
-
-// Important enums ----------------------------------------------------------
-
-/** I/O image format identifiers.
-*/
-FI_ENUM(FREE_IMAGE_FORMAT) {
-	FIF_UNKNOWN = -1,
-	FIF_BMP		= 0,
-	FIF_ICO		= 1,
-	FIF_JPEG	= 2,
-	FIF_JNG		= 3,
-	FIF_KOALA	= 4,
-	FIF_LBM		= 5,
-	FIF_IFF = FIF_LBM,
-	FIF_MNG		= 6,
-	FIF_PBM		= 7,
-	FIF_PBMRAW	= 8,
-	FIF_PCD		= 9,
-	FIF_PCX		= 10,
-	FIF_PGM		= 11,
-	FIF_PGMRAW	= 12,
-	FIF_PNG		= 13,
-	FIF_PPM		= 14,
-	FIF_PPMRAW	= 15,
-	FIF_RAS		= 16,
-	FIF_TARGA	= 17,
-	FIF_TIFF	= 18,
-	FIF_WBMP	= 19,
-	FIF_PSD		= 20,
-	FIF_CUT		= 21,
-	FIF_XBM		= 22,
-	FIF_XPM		= 23,
-	FIF_DDS		= 24,
-	FIF_GIF     = 25,
-	FIF_HDR		= 26,
-	FIF_FAXG3	= 27,
-	FIF_SGI		= 28,
-	FIF_EXR		= 29,
-	FIF_J2K		= 30,
-	FIF_JP2		= 31,
-	FIF_PFM		= 32,
-	FIF_PICT	= 33,
-	FIF_RAW		= 34
-};
-
-/** Image type used in FreeImage.
-*/
-FI_ENUM(FREE_IMAGE_TYPE) {
-	FIT_UNKNOWN = 0,	// unknown type
-	FIT_BITMAP  = 1,	// standard image			: 1-, 4-, 8-, 16-, 24-, 32-bit
-	FIT_UINT16	= 2,	// array of unsigned short	: unsigned 16-bit
-	FIT_INT16	= 3,	// array of short			: signed 16-bit
-	FIT_UINT32	= 4,	// array of unsigned long	: unsigned 32-bit
-	FIT_INT32	= 5,	// array of long			: signed 32-bit
-	FIT_FLOAT	= 6,	// array of float			: 32-bit IEEE floating point
-	FIT_DOUBLE	= 7,	// array of double			: 64-bit IEEE floating point
-	FIT_COMPLEX	= 8,	// array of FICOMPLEX		: 2 x 64-bit IEEE floating point
-	FIT_RGB16	= 9,	// 48-bit RGB image			: 3 x 16-bit
-	FIT_RGBA16	= 10,	// 64-bit RGBA image		: 4 x 16-bit
-	FIT_RGBF	= 11,	// 96-bit RGB float image	: 3 x 32-bit IEEE floating point
-	FIT_RGBAF	= 12	// 128-bit RGBA float image	: 4 x 32-bit IEEE floating point
-};
-
-/** Image color type used in FreeImage.
-*/
-FI_ENUM(FREE_IMAGE_COLOR_TYPE) {
-	FIC_MINISWHITE = 0,		// min value is white
-    FIC_MINISBLACK = 1,		// min value is black
-    FIC_RGB        = 2,		// RGB color model
-    FIC_PALETTE    = 3,		// color map indexed
-	FIC_RGBALPHA   = 4,		// RGB color model with alpha channel
-	FIC_CMYK       = 5		// CMYK color model
-};
-
-/** Color quantization algorithms.
-Constants used in FreeImage_ColorQuantize.
-*/
-FI_ENUM(FREE_IMAGE_QUANTIZE) {
-    FIQ_WUQUANT = 0,		// Xiaolin Wu color quantization algorithm
-    FIQ_NNQUANT = 1			// NeuQuant neural-net quantization algorithm by Anthony Dekker
-};
-
-/** Dithering algorithms.
-Constants used in FreeImage_Dither.
-*/
-FI_ENUM(FREE_IMAGE_DITHER) {
-    FID_FS			= 0,	// Floyd & Steinberg error diffusion
-	FID_BAYER4x4	= 1,	// Bayer ordered dispersed dot dithering (order 2 dithering matrix)
-	FID_BAYER8x8	= 2,	// Bayer ordered dispersed dot dithering (order 3 dithering matrix)
-	FID_CLUSTER6x6	= 3,	// Ordered clustered dot dithering (order 3 - 6x6 matrix)
-	FID_CLUSTER8x8	= 4,	// Ordered clustered dot dithering (order 4 - 8x8 matrix)
-	FID_CLUSTER16x16= 5,	// Ordered clustered dot dithering (order 8 - 16x16 matrix)
-	FID_BAYER16x16	= 6		// Bayer ordered dispersed dot dithering (order 4 dithering matrix)
-};
-
-/** Lossless JPEG transformations
-Constants used in FreeImage_JPEGTransform
-*/
-FI_ENUM(FREE_IMAGE_JPEG_OPERATION) {
-	FIJPEG_OP_NONE			= 0,	// no transformation
-	FIJPEG_OP_FLIP_H		= 1,	// horizontal flip
-	FIJPEG_OP_FLIP_V		= 2,	// vertical flip
-	FIJPEG_OP_TRANSPOSE		= 3,	// transpose across UL-to-LR axis
-	FIJPEG_OP_TRANSVERSE	= 4,	// transpose across UR-to-LL axis
-	FIJPEG_OP_ROTATE_90		= 5,	// 90-degree clockwise rotation
-	FIJPEG_OP_ROTATE_180	= 6,	// 180-degree rotation
-	FIJPEG_OP_ROTATE_270	= 7		// 270-degree clockwise (or 90 ccw)
-};
-
-/** Tone mapping operators.
-Constants used in FreeImage_ToneMapping.
-*/
-FI_ENUM(FREE_IMAGE_TMO) {
-    FITMO_DRAGO03	 = 0,	// Adaptive logarithmic mapping (F. Drago, 2003)
-	FITMO_REINHARD05 = 1,	// Dynamic range reduction inspired by photoreceptor physiology (E. Reinhard, 2005)
-	FITMO_FATTAL02	 = 2	// Gradient domain high dynamic range compression (R. Fattal, 2002)
-};
-
-/** Upsampling / downsampling filters. 
-Constants used in FreeImage_Rescale.
-*/
-FI_ENUM(FREE_IMAGE_FILTER) {
-	FILTER_BOX		  = 0,	// Box, pulse, Fourier window, 1st order (constant) b-spline
-	FILTER_BICUBIC	  = 1,	// Mitchell & Netravali's two-param cubic filter
-	FILTER_BILINEAR   = 2,	// Bilinear filter
-	FILTER_BSPLINE	  = 3,	// 4th order (cubic) b-spline
-	FILTER_CATMULLROM = 4,	// Catmull-Rom spline, Overhauser spline
-	FILTER_LANCZOS3	  = 5	// Lanczos3 filter
-};
-
-/** Color channels.
-Constants used in color manipulation routines.
-*/
-FI_ENUM(FREE_IMAGE_COLOR_CHANNEL) {
-	FICC_RGB	= 0,	// Use red, green and blue channels
-	FICC_RED	= 1,	// Use red channel
-	FICC_GREEN	= 2,	// Use green channel
-	FICC_BLUE	= 3,	// Use blue channel
-	FICC_ALPHA	= 4,	// Use alpha channel
-	FICC_BLACK	= 5,	// Use black channel
-	FICC_REAL	= 6,	// Complex images: use real part
-	FICC_IMAG	= 7,	// Complex images: use imaginary part
-	FICC_MAG	= 8,	// Complex images: use magnitude
-	FICC_PHASE	= 9		// Complex images: use phase
-};
-
-// Metadata support ---------------------------------------------------------
-
-/**
-  Tag data type information (based on TIFF specifications)
-
-  Note: RATIONALs are the ratio of two 32-bit integer values.
-*/
-FI_ENUM(FREE_IMAGE_MDTYPE) {
-	FIDT_NOTYPE		= 0,	// placeholder 
-	FIDT_BYTE		= 1,	// 8-bit unsigned integer 
-	FIDT_ASCII		= 2,	// 8-bit bytes w/ last byte null 
-	FIDT_SHORT		= 3,	// 16-bit unsigned integer 
-	FIDT_LONG		= 4,	// 32-bit unsigned integer 
-	FIDT_RATIONAL	= 5,	// 64-bit unsigned fraction 
-	FIDT_SBYTE		= 6,	// 8-bit signed integer 
-	FIDT_UNDEFINED	= 7,	// 8-bit untyped data 
-	FIDT_SSHORT		= 8,	// 16-bit signed integer 
-	FIDT_SLONG		= 9,	// 32-bit signed integer 
-	FIDT_SRATIONAL	= 10,	// 64-bit signed fraction 
-	FIDT_FLOAT		= 11,	// 32-bit IEEE floating point 
-	FIDT_DOUBLE		= 12,	// 64-bit IEEE floating point 
-	FIDT_IFD		= 13,	// 32-bit unsigned integer (offset) 
-	FIDT_PALETTE	= 14,	// 32-bit RGBQUAD 
-	FIDT_LONG8		= 16,	// 64-bit unsigned integer 
-	FIDT_SLONG8		= 17,	// 64-bit signed integer
-	FIDT_IFD8		= 18	// 64-bit unsigned integer (offset)
-};
-
-/**
-  Metadata models supported by FreeImage
-*/
-FI_ENUM(FREE_IMAGE_MDMODEL) {
-	FIMD_NODATA			= -1,
-	FIMD_COMMENTS		= 0,	// single comment or keywords
-	FIMD_EXIF_MAIN		= 1,	// Exif-TIFF metadata
-	FIMD_EXIF_EXIF		= 2,	// Exif-specific metadata
-	FIMD_EXIF_GPS		= 3,	// Exif GPS metadata
-	FIMD_EXIF_MAKERNOTE = 4,	// Exif maker note metadata
-	FIMD_EXIF_INTEROP	= 5,	// Exif interoperability metadata
-	FIMD_IPTC			= 6,	// IPTC/NAA metadata
-	FIMD_XMP			= 7,	// Abobe XMP metadata
-	FIMD_GEOTIFF		= 8,	// GeoTIFF metadata
-	FIMD_ANIMATION		= 9,	// Animation metadata
-	FIMD_CUSTOM			= 10,	// Used to attach other metadata types to a dib
-	FIMD_EXIF_RAW		= 11	// Exif metadata as a raw buffer
-};
-
-/**
-  Handle to a metadata model
-*/
-FI_STRUCT (FIMETADATA) { void *data; };
-
-/**
-  Handle to a FreeImage tag
-*/
-FI_STRUCT (FITAG) { void *data; };
-
-// File IO routines ---------------------------------------------------------
-
-#ifndef FREEIMAGE_IO
-#define FREEIMAGE_IO
-
-typedef void* fi_handle;
-typedef unsigned (DLL_CALLCONV *FI_ReadProc) (void *buffer, unsigned size, unsigned count, fi_handle handle);
-typedef unsigned (DLL_CALLCONV *FI_WriteProc) (void *buffer, unsigned size, unsigned count, fi_handle handle);
-typedef int (DLL_CALLCONV *FI_SeekProc) (fi_handle handle, long offset, int origin);
-typedef long (DLL_CALLCONV *FI_TellProc) (fi_handle handle);
-
-#if (defined(_WIN32) || defined(__WIN32__))
-#pragma pack(push, 1)
-#else
-#pragma pack(1)
-#endif // WIN32
-
-FI_STRUCT(FreeImageIO) {
-	FI_ReadProc  read_proc;     // pointer to the function used to read data
-    FI_WriteProc write_proc;    // pointer to the function used to write data
-    FI_SeekProc  seek_proc;     // pointer to the function used to seek
-    FI_TellProc  tell_proc;     // pointer to the function used to aquire the current position
-};
-
-#if (defined(_WIN32) || defined(__WIN32__))
-#pragma pack(pop)
-#else
-#pragma pack()
-#endif // WIN32
-
-/**
-Handle to a memory I/O stream
-*/
-FI_STRUCT (FIMEMORY) { void *data; };
-
-#endif // FREEIMAGE_IO
-
-// Plugin routines ----------------------------------------------------------
-
-#ifndef PLUGINS
-#define PLUGINS
-
-typedef const char *(DLL_CALLCONV *FI_FormatProc)(void);
-typedef const char *(DLL_CALLCONV *FI_DescriptionProc)(void);
-typedef const char *(DLL_CALLCONV *FI_ExtensionListProc)(void);
-typedef const char *(DLL_CALLCONV *FI_RegExprProc)(void);
-typedef void *(DLL_CALLCONV *FI_OpenProc)(FreeImageIO *io, fi_handle handle, BOOL read);
-typedef void (DLL_CALLCONV *FI_CloseProc)(FreeImageIO *io, fi_handle handle, void *data);
-typedef int (DLL_CALLCONV *FI_PageCountProc)(FreeImageIO *io, fi_handle handle, void *data);
-typedef int (DLL_CALLCONV *FI_PageCapabilityProc)(FreeImageIO *io, fi_handle handle, void *data);
-typedef FIBITMAP *(DLL_CALLCONV *FI_LoadProc)(FreeImageIO *io, fi_handle handle, int page, int flags, void *data);
-typedef BOOL (DLL_CALLCONV *FI_SaveProc)(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void *data);
-typedef BOOL (DLL_CALLCONV *FI_ValidateProc)(FreeImageIO *io, fi_handle handle);
-typedef const char *(DLL_CALLCONV *FI_MimeProc)(void);
-typedef BOOL (DLL_CALLCONV *FI_SupportsExportBPPProc)(int bpp);
-typedef BOOL (DLL_CALLCONV *FI_SupportsExportTypeProc)(FREE_IMAGE_TYPE type);
-typedef BOOL (DLL_CALLCONV *FI_SupportsICCProfilesProc)(void);
-typedef BOOL (DLL_CALLCONV *FI_SupportsNoPixelsProc)(void);
-
-FI_STRUCT (Plugin) {
-	FI_FormatProc format_proc;
-	FI_DescriptionProc description_proc;
-	FI_ExtensionListProc extension_proc;
-	FI_RegExprProc regexpr_proc;
-	FI_OpenProc open_proc;
-	FI_CloseProc close_proc;
-	FI_PageCountProc pagecount_proc;
-	FI_PageCapabilityProc pagecapability_proc;
-	FI_LoadProc load_proc;
-	FI_SaveProc save_proc;
-	FI_ValidateProc validate_proc;
-	FI_MimeProc mime_proc;
-	FI_SupportsExportBPPProc supports_export_bpp_proc;
-	FI_SupportsExportTypeProc supports_export_type_proc;
-	FI_SupportsICCProfilesProc supports_icc_profiles_proc;
-	FI_SupportsNoPixelsProc supports_no_pixels_proc;
-};
-
-typedef void (DLL_CALLCONV *FI_InitProc)(Plugin *plugin, int format_id);
-
-#endif // PLUGINS
-
-
-// Load / Save flag constants -----------------------------------------------
-
-#define FIF_LOAD_NOPIXELS 0x8000 // loading: load the image header only (not supported by all plugins, default to full loading)
-
-#define BMP_DEFAULT         0
-#define BMP_SAVE_RLE        1
-#define CUT_DEFAULT         0
-#define DDS_DEFAULT			0
-#define EXR_DEFAULT			0		// save data as half with piz-based wavelet compression
-#define EXR_FLOAT			0x0001	// save data as float instead of as half (not recommended)
-#define EXR_NONE			0x0002	// save with no compression
-#define EXR_ZIP				0x0004	// save with zlib compression, in blocks of 16 scan lines
-#define EXR_PIZ				0x0008	// save with piz-based wavelet compression
-#define EXR_PXR24			0x0010	// save with lossy 24-bit float compression
-#define EXR_B44				0x0020	// save with lossy 44% float compression - goes to 22% when combined with EXR_LC
-#define EXR_LC				0x0040	// save images with one luminance and two chroma channels, rather than as RGB (lossy compression)
-#define FAXG3_DEFAULT		0
-#define GIF_DEFAULT			0
-#define GIF_LOAD256			1		// Load the image as a 256 color image with ununsed palette entries, if it's 16 or 2 color
-#define GIF_PLAYBACK		2		// 'Play' the GIF to generate each frame (as 32bpp) instead of returning raw frame data when loading
-#define HDR_DEFAULT			0
-#define ICO_DEFAULT         0
-#define ICO_MAKEALPHA		1		// convert to 32bpp and create an alpha channel from the AND-mask when loading
-#define IFF_DEFAULT         0
-#define J2K_DEFAULT			0		// save with a 16:1 rate
-#define JP2_DEFAULT			0		// save with a 16:1 rate
-#define JPEG_DEFAULT        0		// loading (see JPEG_FAST); saving (see JPEG_QUALITYGOOD|JPEG_SUBSAMPLING_420)
-#define JPEG_FAST           0x0001	// load the file as fast as possible, sacrificing some quality
-#define JPEG_ACCURATE       0x0002	// load the file with the best quality, sacrificing some speed
-#define JPEG_CMYK			0x0004	// load separated CMYK "as is" (use | to combine with other load flags)
-#define JPEG_EXIFROTATE		0x0008	// load and rotate according to Exif 'Orientation' tag if available
-#define JPEG_GREYSCALE		0x0010	// load and convert to a 8-bit greyscale image
-#define JPEG_QUALITYSUPERB  0x80	// save with superb quality (100:1)
-#define JPEG_QUALITYGOOD    0x0100	// save with good quality (75:1)
-#define JPEG_QUALITYNORMAL  0x0200	// save with normal quality (50:1)
-#define JPEG_QUALITYAVERAGE 0x0400	// save with average quality (25:1)
-#define JPEG_QUALITYBAD     0x0800	// save with bad quality (10:1)
-#define JPEG_PROGRESSIVE	0x2000	// save as a progressive-JPEG (use | to combine with other save flags)
-#define JPEG_SUBSAMPLING_411 0x1000		// save with high 4x1 chroma subsampling (4:1:1) 
-#define JPEG_SUBSAMPLING_420 0x4000		// save with medium 2x2 medium chroma subsampling (4:2:0) - default value
-#define JPEG_SUBSAMPLING_422 0x8000		// save with low 2x1 chroma subsampling (4:2:2) 
-#define JPEG_SUBSAMPLING_444 0x10000	// save with no chroma subsampling (4:4:4)
-#define JPEG_OPTIMIZE		0x20000		// on saving, compute optimal Huffman coding tables (can reduce a few percent of file size)
-#define JPEG_BASELINE		0x40000		// save basic JPEG, without metadata or any markers
-#define KOALA_DEFAULT       0
-#define LBM_DEFAULT         0
-#define MNG_DEFAULT         0
-#define PCD_DEFAULT         0
-#define PCD_BASE            1		// load the bitmap sized 768 x 512
-#define PCD_BASEDIV4        2		// load the bitmap sized 384 x 256
-#define PCD_BASEDIV16       3		// load the bitmap sized 192 x 128
-#define PCX_DEFAULT         0
-#define PFM_DEFAULT         0
-#define PICT_DEFAULT        0
-#define PNG_DEFAULT         0
-#define PNG_IGNOREGAMMA		1		// loading: avoid gamma correction
-#define PNG_Z_BEST_SPEED			0x0001	// save using ZLib level 1 compression flag (default value is 6)
-#define PNG_Z_DEFAULT_COMPRESSION	0x0006	// save using ZLib level 6 compression flag (default recommended value)
-#define PNG_Z_BEST_COMPRESSION		0x0009	// save using ZLib level 9 compression flag (default value is 6)
-#define PNG_Z_NO_COMPRESSION		0x0100	// save without ZLib compression
-#define PNG_INTERLACED				0x0200	// save using Adam7 interlacing (use | to combine with other save flags)
-#define PNM_DEFAULT         0
-#define PNM_SAVE_RAW        0       // If set the writer saves in RAW format (i.e. P4, P5 or P6)
-#define PNM_SAVE_ASCII      1       // If set the writer saves in ASCII format (i.e. P1, P2 or P3)
-#define PSD_DEFAULT         0
-#define PSD_CMYK			1		// reads tags for separated CMYK (default is conversion to RGB)
-#define PSD_LAB				2		// reads tags for CIELab (default is conversion to RGB)
-#define RAS_DEFAULT         0
-#define RAW_DEFAULT         0		// load the file as linear RGB 48-bit
-#define RAW_PREVIEW			1		// try to load the embedded JPEG preview with included Exif Data or default to RGB 24-bit
-#define RAW_DISPLAY			2		// load the file as RGB 24-bit
-#define RAW_HALFSIZE		4		// output a half-size color image
-#define SGI_DEFAULT			0
-#define TARGA_DEFAULT       0
-#define TARGA_LOAD_RGB888   1       // If set the loader converts RGB555 and ARGB8888 -> RGB888.
-#define TARGA_SAVE_RLE		2		// If set, the writer saves with RLE compression
-#define TIFF_DEFAULT        0
-#define TIFF_CMYK			0x0001	// reads/stores tags for separated CMYK (use | to combine with compression flags)
-#define TIFF_PACKBITS       0x0100  // save using PACKBITS compression
-#define TIFF_DEFLATE        0x0200  // save using DEFLATE compression (a.k.a. ZLIB compression)
-#define TIFF_ADOBE_DEFLATE  0x0400  // save using ADOBE DEFLATE compression
-#define TIFF_NONE           0x0800  // save without any compression
-#define TIFF_CCITTFAX3		0x1000  // save using CCITT Group 3 fax encoding
-#define TIFF_CCITTFAX4		0x2000  // save using CCITT Group 4 fax encoding
-#define TIFF_LZW			0x4000	// save using LZW compression
-#define TIFF_JPEG			0x8000	// save using JPEG compression
-#define TIFF_LOGLUV			0x10000	// save using LogLuv compression
-#define WBMP_DEFAULT        0
-#define XBM_DEFAULT			0
-#define XPM_DEFAULT			0
-
-// Background filling options ---------------------------------------------------------
-// Constants used in FreeImage_FillBackground and FreeImage_EnlargeCanvas
-
-#define FI_COLOR_IS_RGB_COLOR			0x00	// RGBQUAD color is a RGB color (contains no valid alpha channel)
-#define FI_COLOR_IS_RGBA_COLOR			0x01	// RGBQUAD color is a RGBA color (contains a valid alpha channel)
-#define FI_COLOR_FIND_EQUAL_COLOR		0x02	// For palettized images: lookup equal RGB color from palette
-#define FI_COLOR_ALPHA_IS_INDEX			0x04	// The color's rgbReserved member (alpha) contains the palette index to be used
-#define FI_COLOR_PALETTE_SEARCH_MASK	(FI_COLOR_FIND_EQUAL_COLOR | FI_COLOR_ALPHA_IS_INDEX)	// No color lookup is performed
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// Init / Error routines ----------------------------------------------------
-
-DLL_API void DLL_CALLCONV FreeImage_Initialise(BOOL load_local_plugins_only FI_DEFAULT(FALSE));
-DLL_API void DLL_CALLCONV FreeImage_DeInitialise(void);
-
-// Version routines ---------------------------------------------------------
-
-DLL_API const char *DLL_CALLCONV FreeImage_GetVersion(void);
-DLL_API const char *DLL_CALLCONV FreeImage_GetCopyrightMessage(void);
-
-// Message output functions -------------------------------------------------
-
-typedef void (*FreeImage_OutputMessageFunction)(FREE_IMAGE_FORMAT fif, const char *msg);
-typedef void (DLL_CALLCONV *FreeImage_OutputMessageFunctionStdCall)(FREE_IMAGE_FORMAT fif, const char *msg); 
-
-DLL_API void DLL_CALLCONV FreeImage_SetOutputMessageStdCall(FreeImage_OutputMessageFunctionStdCall omf); 
-DLL_API void DLL_CALLCONV FreeImage_SetOutputMessage(FreeImage_OutputMessageFunction omf);
-DLL_API void DLL_CALLCONV FreeImage_OutputMessageProc(int fif, const char *fmt, ...);
-
-// Allocate / Clone / Unload routines ---------------------------------------
-
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Allocate(int width, int height, int bpp, unsigned red_mask FI_DEFAULT(0), unsigned green_mask FI_DEFAULT(0), unsigned blue_mask FI_DEFAULT(0));
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_AllocateT(FREE_IMAGE_TYPE type, int width, int height, int bpp FI_DEFAULT(8), unsigned red_mask FI_DEFAULT(0), unsigned green_mask FI_DEFAULT(0), unsigned blue_mask FI_DEFAULT(0));
-DLL_API FIBITMAP * DLL_CALLCONV FreeImage_Clone(FIBITMAP *dib);
-DLL_API void DLL_CALLCONV FreeImage_Unload(FIBITMAP *dib);
-
-// Header loading routines
-DLL_API BOOL DLL_CALLCONV FreeImage_HasPixels(FIBITMAP *dib);
-
-// Load / Save routines -----------------------------------------------------
-
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Load(FREE_IMAGE_FORMAT fif, const char *filename, int flags FI_DEFAULT(0));
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_LoadU(FREE_IMAGE_FORMAT fif, const wchar_t *filename, int flags FI_DEFAULT(0));
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_LoadFromHandle(FREE_IMAGE_FORMAT fif, FreeImageIO *io, fi_handle handle, int flags FI_DEFAULT(0));
-DLL_API BOOL DLL_CALLCONV FreeImage_Save(FREE_IMAGE_FORMAT fif, FIBITMAP *dib, const char *filename, int flags FI_DEFAULT(0));
-DLL_API BOOL DLL_CALLCONV FreeImage_SaveU(FREE_IMAGE_FORMAT fif, FIBITMAP *dib, const wchar_t *filename, int flags FI_DEFAULT(0));
-DLL_API BOOL DLL_CALLCONV FreeImage_SaveToHandle(FREE_IMAGE_FORMAT fif, FIBITMAP *dib, FreeImageIO *io, fi_handle handle, int flags FI_DEFAULT(0));
-
-// Memory I/O stream routines -----------------------------------------------
-
-DLL_API FIMEMORY *DLL_CALLCONV FreeImage_OpenMemory(BYTE *data FI_DEFAULT(0), DWORD size_in_bytes FI_DEFAULT(0));
-DLL_API void DLL_CALLCONV FreeImage_CloseMemory(FIMEMORY *stream);
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_LoadFromMemory(FREE_IMAGE_FORMAT fif, FIMEMORY *stream, int flags FI_DEFAULT(0));
-DLL_API BOOL DLL_CALLCONV FreeImage_SaveToMemory(FREE_IMAGE_FORMAT fif, FIBITMAP *dib, FIMEMORY *stream, int flags FI_DEFAULT(0));
-DLL_API long DLL_CALLCONV FreeImage_TellMemory(FIMEMORY *stream);
-DLL_API BOOL DLL_CALLCONV FreeImage_SeekMemory(FIMEMORY *stream, long offset, int origin);
-DLL_API BOOL DLL_CALLCONV FreeImage_AcquireMemory(FIMEMORY *stream, BYTE **data, DWORD *size_in_bytes);
-DLL_API unsigned DLL_CALLCONV FreeImage_ReadMemory(void *buffer, unsigned size, unsigned count, FIMEMORY *stream);
-DLL_API unsigned DLL_CALLCONV FreeImage_WriteMemory(const void *buffer, unsigned size, unsigned count, FIMEMORY *stream);
-
-DLL_API FIMULTIBITMAP *DLL_CALLCONV FreeImage_LoadMultiBitmapFromMemory(FREE_IMAGE_FORMAT fif, FIMEMORY *stream, int flags FI_DEFAULT(0));
-DLL_API BOOL DLL_CALLCONV FreeImage_SaveMultiBitmapToMemory(FREE_IMAGE_FORMAT fif, FIMULTIBITMAP *bitmap, FIMEMORY *stream, int flags);
-
-// Plugin Interface ---------------------------------------------------------
-
-DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_RegisterLocalPlugin(FI_InitProc proc_address, const char *format FI_DEFAULT(0), const char *description FI_DEFAULT(0), const char *extension FI_DEFAULT(0), const char *regexpr FI_DEFAULT(0));
-DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_RegisterExternalPlugin(const char *path, const char *format FI_DEFAULT(0), const char *description FI_DEFAULT(0), const char *extension FI_DEFAULT(0), const char *regexpr FI_DEFAULT(0));
-DLL_API int DLL_CALLCONV FreeImage_GetFIFCount(void);
-DLL_API int DLL_CALLCONV FreeImage_SetPluginEnabled(FREE_IMAGE_FORMAT fif, BOOL enable);
-DLL_API int DLL_CALLCONV FreeImage_IsPluginEnabled(FREE_IMAGE_FORMAT fif);
-DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFIFFromFormat(const char *format);
-DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFIFFromMime(const char *mime);
-DLL_API const char *DLL_CALLCONV FreeImage_GetFormatFromFIF(FREE_IMAGE_FORMAT fif);
-DLL_API const char *DLL_CALLCONV FreeImage_GetFIFExtensionList(FREE_IMAGE_FORMAT fif);
-DLL_API const char *DLL_CALLCONV FreeImage_GetFIFDescription(FREE_IMAGE_FORMAT fif);
-DLL_API const char *DLL_CALLCONV FreeImage_GetFIFRegExpr(FREE_IMAGE_FORMAT fif);
-DLL_API const char *DLL_CALLCONV FreeImage_GetFIFMimeType(FREE_IMAGE_FORMAT fif);
-DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFIFFromFilename(const char *filename);
-DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFIFFromFilenameU(const wchar_t *filename);
-DLL_API BOOL DLL_CALLCONV FreeImage_FIFSupportsReading(FREE_IMAGE_FORMAT fif);
-DLL_API BOOL DLL_CALLCONV FreeImage_FIFSupportsWriting(FREE_IMAGE_FORMAT fif);
-DLL_API BOOL DLL_CALLCONV FreeImage_FIFSupportsExportBPP(FREE_IMAGE_FORMAT fif, int bpp);
-DLL_API BOOL DLL_CALLCONV FreeImage_FIFSupportsExportType(FREE_IMAGE_FORMAT fif, FREE_IMAGE_TYPE type);
-DLL_API BOOL DLL_CALLCONV FreeImage_FIFSupportsICCProfiles(FREE_IMAGE_FORMAT fif);
-DLL_API BOOL DLL_CALLCONV FreeImage_FIFSupportsNoPixels(FREE_IMAGE_FORMAT fif);
-
-// Multipaging interface ----------------------------------------------------
-
-DLL_API FIMULTIBITMAP * DLL_CALLCONV FreeImage_OpenMultiBitmap(FREE_IMAGE_FORMAT fif, const char *filename, BOOL create_new, BOOL read_only, BOOL keep_cache_in_memory FI_DEFAULT(FALSE), int flags FI_DEFAULT(0));
-DLL_API FIMULTIBITMAP * DLL_CALLCONV FreeImage_OpenMultiBitmapFromHandle(FREE_IMAGE_FORMAT fif, FreeImageIO *io, fi_handle handle, int flags FI_DEFAULT(0));
-DLL_API BOOL DLL_CALLCONV FreeImage_SaveMultiBitmapToHandle(FREE_IMAGE_FORMAT fif, FIMULTIBITMAP *bitmap, FreeImageIO *io, fi_handle handle, int flags FI_DEFAULT(0));
-DLL_API BOOL DLL_CALLCONV FreeImage_CloseMultiBitmap(FIMULTIBITMAP *bitmap, int flags FI_DEFAULT(0));
-DLL_API int DLL_CALLCONV FreeImage_GetPageCount(FIMULTIBITMAP *bitmap);
-DLL_API void DLL_CALLCONV FreeImage_AppendPage(FIMULTIBITMAP *bitmap, FIBITMAP *data);
-DLL_API void DLL_CALLCONV FreeImage_InsertPage(FIMULTIBITMAP *bitmap, int page, FIBITMAP *data);
-DLL_API void DLL_CALLCONV FreeImage_DeletePage(FIMULTIBITMAP *bitmap, int page);
-DLL_API FIBITMAP * DLL_CALLCONV FreeImage_LockPage(FIMULTIBITMAP *bitmap, int page);
-DLL_API void DLL_CALLCONV FreeImage_UnlockPage(FIMULTIBITMAP *bitmap, FIBITMAP *data, BOOL changed);
-DLL_API BOOL DLL_CALLCONV FreeImage_MovePage(FIMULTIBITMAP *bitmap, int target, int source);
-DLL_API BOOL DLL_CALLCONV FreeImage_GetLockedPageNumbers(FIMULTIBITMAP *bitmap, int *pages, int *count);
-
-// Filetype request routines ------------------------------------------------
-
-DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFileType(const char *filename, int size FI_DEFAULT(0));
-DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFileTypeU(const wchar_t *filename, int size FI_DEFAULT(0));
-DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFileTypeFromHandle(FreeImageIO *io, fi_handle handle, int size FI_DEFAULT(0));
-DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFileTypeFromMemory(FIMEMORY *stream, int size FI_DEFAULT(0));
-
-// Image type request routine -----------------------------------------------
-
-DLL_API FREE_IMAGE_TYPE DLL_CALLCONV FreeImage_GetImageType(FIBITMAP *dib);
-
-// FreeImage helper routines ------------------------------------------------
-
-DLL_API BOOL DLL_CALLCONV FreeImage_IsLittleEndian(void);
-DLL_API BOOL DLL_CALLCONV FreeImage_LookupX11Color(const char *szColor, BYTE *nRed, BYTE *nGreen, BYTE *nBlue);
-DLL_API BOOL DLL_CALLCONV FreeImage_LookupSVGColor(const char *szColor, BYTE *nRed, BYTE *nGreen, BYTE *nBlue);
-
-// Pixel access routines ----------------------------------------------------
-
-DLL_API BYTE *DLL_CALLCONV FreeImage_GetBits(FIBITMAP *dib);
-DLL_API BYTE *DLL_CALLCONV FreeImage_GetScanLine(FIBITMAP *dib, int scanline);
-
-DLL_API BOOL DLL_CALLCONV FreeImage_GetPixelIndex(FIBITMAP *dib, unsigned x, unsigned y, BYTE *value);
-DLL_API BOOL DLL_CALLCONV FreeImage_GetPixelColor(FIBITMAP *dib, unsigned x, unsigned y, RGBQUAD *value);
-DLL_API BOOL DLL_CALLCONV FreeImage_SetPixelIndex(FIBITMAP *dib, unsigned x, unsigned y, BYTE *value);
-DLL_API BOOL DLL_CALLCONV FreeImage_SetPixelColor(FIBITMAP *dib, unsigned x, unsigned y, RGBQUAD *value);
-
-// DIB info routines --------------------------------------------------------
-
-DLL_API unsigned DLL_CALLCONV FreeImage_GetColorsUsed(FIBITMAP *dib);
-DLL_API unsigned DLL_CALLCONV FreeImage_GetBPP(FIBITMAP *dib);
-DLL_API unsigned DLL_CALLCONV FreeImage_GetWidth(FIBITMAP *dib);
-DLL_API unsigned DLL_CALLCONV FreeImage_GetHeight(FIBITMAP *dib);
-DLL_API unsigned DLL_CALLCONV FreeImage_GetLine(FIBITMAP *dib);
-DLL_API unsigned DLL_CALLCONV FreeImage_GetPitch(FIBITMAP *dib);
-DLL_API unsigned DLL_CALLCONV FreeImage_GetDIBSize(FIBITMAP *dib);
-DLL_API RGBQUAD *DLL_CALLCONV FreeImage_GetPalette(FIBITMAP *dib);
-
-DLL_API unsigned DLL_CALLCONV FreeImage_GetDotsPerMeterX(FIBITMAP *dib);
-DLL_API unsigned DLL_CALLCONV FreeImage_GetDotsPerMeterY(FIBITMAP *dib);
-DLL_API void DLL_CALLCONV FreeImage_SetDotsPerMeterX(FIBITMAP *dib, unsigned res);
-DLL_API void DLL_CALLCONV FreeImage_SetDotsPerMeterY(FIBITMAP *dib, unsigned res);
-
-DLL_API BITMAPINFOHEADER *DLL_CALLCONV FreeImage_GetInfoHeader(FIBITMAP *dib);
-DLL_API BITMAPINFO *DLL_CALLCONV FreeImage_GetInfo(FIBITMAP *dib);
-DLL_API FREE_IMAGE_COLOR_TYPE DLL_CALLCONV FreeImage_GetColorType(FIBITMAP *dib);
-
-DLL_API unsigned DLL_CALLCONV FreeImage_GetRedMask(FIBITMAP *dib);
-DLL_API unsigned DLL_CALLCONV FreeImage_GetGreenMask(FIBITMAP *dib);
-DLL_API unsigned DLL_CALLCONV FreeImage_GetBlueMask(FIBITMAP *dib);
-
-DLL_API unsigned DLL_CALLCONV FreeImage_GetTransparencyCount(FIBITMAP *dib);
-DLL_API BYTE * DLL_CALLCONV FreeImage_GetTransparencyTable(FIBITMAP *dib);
-DLL_API void DLL_CALLCONV FreeImage_SetTransparent(FIBITMAP *dib, BOOL enabled);
-DLL_API void DLL_CALLCONV FreeImage_SetTransparencyTable(FIBITMAP *dib, BYTE *table, int count);
-DLL_API BOOL DLL_CALLCONV FreeImage_IsTransparent(FIBITMAP *dib);
-DLL_API void DLL_CALLCONV FreeImage_SetTransparentIndex(FIBITMAP *dib, int index);
-DLL_API int DLL_CALLCONV FreeImage_GetTransparentIndex(FIBITMAP *dib);
-
-DLL_API BOOL DLL_CALLCONV FreeImage_HasBackgroundColor(FIBITMAP *dib);
-DLL_API BOOL DLL_CALLCONV FreeImage_GetBackgroundColor(FIBITMAP *dib, RGBQUAD *bkcolor);
-DLL_API BOOL DLL_CALLCONV FreeImage_SetBackgroundColor(FIBITMAP *dib, RGBQUAD *bkcolor);
-
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_GetThumbnail(FIBITMAP *dib);
-DLL_API BOOL DLL_CALLCONV FreeImage_SetThumbnail(FIBITMAP *dib, FIBITMAP *thumbnail);
-
-// ICC profile routines -----------------------------------------------------
-
-DLL_API FIICCPROFILE *DLL_CALLCONV FreeImage_GetICCProfile(FIBITMAP *dib);
-DLL_API FIICCPROFILE *DLL_CALLCONV FreeImage_CreateICCProfile(FIBITMAP *dib, void *data, long size);
-DLL_API void DLL_CALLCONV FreeImage_DestroyICCProfile(FIBITMAP *dib);
-
-// Line conversion routines -------------------------------------------------
-
-DLL_API void DLL_CALLCONV FreeImage_ConvertLine1To4(BYTE *target, BYTE *source, int width_in_pixels);
-DLL_API void DLL_CALLCONV FreeImage_ConvertLine8To4(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette);
-DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To4_555(BYTE *target, BYTE *source, int width_in_pixels);
-DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To4_565(BYTE *target, BYTE *source, int width_in_pixels);
-DLL_API void DLL_CALLCONV FreeImage_ConvertLine24To4(BYTE *target, BYTE *source, int width_in_pixels);
-DLL_API void DLL_CALLCONV FreeImage_ConvertLine32To4(BYTE *target, BYTE *source, int width_in_pixels);
-DLL_API void DLL_CALLCONV FreeImage_ConvertLine1To8(BYTE *target, BYTE *source, int width_in_pixels);
-DLL_API void DLL_CALLCONV FreeImage_ConvertLine4To8(BYTE *target, BYTE *source, int width_in_pixels);
-DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To8_555(BYTE *target, BYTE *source, int width_in_pixels);
-DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To8_565(BYTE *target, BYTE *source, int width_in_pixels);
-DLL_API void DLL_CALLCONV FreeImage_ConvertLine24To8(BYTE *target, BYTE *source, int width_in_pixels);
-DLL_API void DLL_CALLCONV FreeImage_ConvertLine32To8(BYTE *target, BYTE *source, int width_in_pixels);
-DLL_API void DLL_CALLCONV FreeImage_ConvertLine1To16_555(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette);
-DLL_API void DLL_CALLCONV FreeImage_ConvertLine4To16_555(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette);
-DLL_API void DLL_CALLCONV FreeImage_ConvertLine8To16_555(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette);
-DLL_API void DLL_CALLCONV FreeImage_ConvertLine16_565_To16_555(BYTE *target, BYTE *source, int width_in_pixels);
-DLL_API void DLL_CALLCONV FreeImage_ConvertLine24To16_555(BYTE *target, BYTE *source, int width_in_pixels);
-DLL_API void DLL_CALLCONV FreeImage_ConvertLine32To16_555(BYTE *target, BYTE *source, int width_in_pixels);
-DLL_API void DLL_CALLCONV FreeImage_ConvertLine1To16_565(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette);
-DLL_API void DLL_CALLCONV FreeImage_ConvertLine4To16_565(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette);
-DLL_API void DLL_CALLCONV FreeImage_ConvertLine8To16_565(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette);
-DLL_API void DLL_CALLCONV FreeImage_ConvertLine16_555_To16_565(BYTE *target, BYTE *source, int width_in_pixels);
-DLL_API void DLL_CALLCONV FreeImage_ConvertLine24To16_565(BYTE *target, BYTE *source, int width_in_pixels);
-DLL_API void DLL_CALLCONV FreeImage_ConvertLine32To16_565(BYTE *target, BYTE *source, int width_in_pixels);
-DLL_API void DLL_CALLCONV FreeImage_ConvertLine1To24(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette);
-DLL_API void DLL_CALLCONV FreeImage_ConvertLine4To24(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette);
-DLL_API void DLL_CALLCONV FreeImage_ConvertLine8To24(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette);
-DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To24_555(BYTE *target, BYTE *source, int width_in_pixels);
-DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To24_565(BYTE *target, BYTE *source, int width_in_pixels);
-DLL_API void DLL_CALLCONV FreeImage_ConvertLine32To24(BYTE *target, BYTE *source, int width_in_pixels);
-DLL_API void DLL_CALLCONV FreeImage_ConvertLine1To32(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette);
-DLL_API void DLL_CALLCONV FreeImage_ConvertLine4To32(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette);
-DLL_API void DLL_CALLCONV FreeImage_ConvertLine8To32(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette);
-DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To32_555(BYTE *target, BYTE *source, int width_in_pixels);
-DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To32_565(BYTE *target, BYTE *source, int width_in_pixels);
-DLL_API void DLL_CALLCONV FreeImage_ConvertLine24To32(BYTE *target, BYTE *source, int width_in_pixels);
-
-// Smart conversion routines ------------------------------------------------
-
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertTo4Bits(FIBITMAP *dib);
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertTo8Bits(FIBITMAP *dib);
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToGreyscale(FIBITMAP *dib);
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertTo16Bits555(FIBITMAP *dib);
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertTo16Bits565(FIBITMAP *dib);
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertTo24Bits(FIBITMAP *dib);
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertTo32Bits(FIBITMAP *dib);
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ColorQuantize(FIBITMAP *dib, FREE_IMAGE_QUANTIZE quantize);
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ColorQuantizeEx(FIBITMAP *dib, FREE_IMAGE_QUANTIZE quantize FI_DEFAULT(FIQ_WUQUANT), int PaletteSize FI_DEFAULT(256), int ReserveSize FI_DEFAULT(0), RGBQUAD *ReservePalette FI_DEFAULT(NULL));
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Threshold(FIBITMAP *dib, BYTE T);
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Dither(FIBITMAP *dib, FREE_IMAGE_DITHER algorithm);
-
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertFromRawBits(BYTE *bits, int width, int height, int pitch, unsigned bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask, BOOL topdown FI_DEFAULT(FALSE));
-DLL_API void DLL_CALLCONV FreeImage_ConvertToRawBits(BYTE *bits, FIBITMAP *dib, int pitch, unsigned bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask, BOOL topdown FI_DEFAULT(FALSE));
-
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToFloat(FIBITMAP *dib);
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToRGBF(FIBITMAP *dib);
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToUINT16(FIBITMAP *dib);
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToRGB16(FIBITMAP *dib);
-
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToStandardType(FIBITMAP *src, BOOL scale_linear FI_DEFAULT(TRUE));
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToType(FIBITMAP *src, FREE_IMAGE_TYPE dst_type, BOOL scale_linear FI_DEFAULT(TRUE));
-
-// tone mapping operators
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ToneMapping(FIBITMAP *dib, FREE_IMAGE_TMO tmo, double first_param FI_DEFAULT(0), double second_param FI_DEFAULT(0));
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_TmoDrago03(FIBITMAP *src, double gamma FI_DEFAULT(2.2), double exposure FI_DEFAULT(0));
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_TmoReinhard05(FIBITMAP *src, double intensity FI_DEFAULT(0), double contrast FI_DEFAULT(0));
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_TmoReinhard05Ex(FIBITMAP *src, double intensity FI_DEFAULT(0), double contrast FI_DEFAULT(0), double adaptation FI_DEFAULT(1), double color_correction FI_DEFAULT(0));
-
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_TmoFattal02(FIBITMAP *src, double color_saturation FI_DEFAULT(0.5), double attenuation FI_DEFAULT(0.85));
-
-// ZLib interface -----------------------------------------------------------
-
-DLL_API DWORD DLL_CALLCONV FreeImage_ZLibCompress(BYTE *target, DWORD target_size, BYTE *source, DWORD source_size);
-DLL_API DWORD DLL_CALLCONV FreeImage_ZLibUncompress(BYTE *target, DWORD target_size, BYTE *source, DWORD source_size);
-DLL_API DWORD DLL_CALLCONV FreeImage_ZLibGZip(BYTE *target, DWORD target_size, BYTE *source, DWORD source_size);
-DLL_API DWORD DLL_CALLCONV FreeImage_ZLibGUnzip(BYTE *target, DWORD target_size, BYTE *source, DWORD source_size);
-DLL_API DWORD DLL_CALLCONV FreeImage_ZLibCRC32(DWORD crc, BYTE *source, DWORD source_size);
-
-// --------------------------------------------------------------------------
-// Metadata routines --------------------------------------------------------
-// --------------------------------------------------------------------------
-
-// tag creation / destruction
-DLL_API FITAG *DLL_CALLCONV FreeImage_CreateTag(void);
-DLL_API void DLL_CALLCONV FreeImage_DeleteTag(FITAG *tag);
-DLL_API FITAG *DLL_CALLCONV FreeImage_CloneTag(FITAG *tag);
-
-// tag getters and setters
-DLL_API const char *DLL_CALLCONV FreeImage_GetTagKey(FITAG *tag);
-DLL_API const char *DLL_CALLCONV FreeImage_GetTagDescription(FITAG *tag);
-DLL_API WORD DLL_CALLCONV FreeImage_GetTagID(FITAG *tag);
-DLL_API FREE_IMAGE_MDTYPE DLL_CALLCONV FreeImage_GetTagType(FITAG *tag);
-DLL_API DWORD DLL_CALLCONV FreeImage_GetTagCount(FITAG *tag);
-DLL_API DWORD DLL_CALLCONV FreeImage_GetTagLength(FITAG *tag);
-DLL_API const void *DLL_CALLCONV FreeImage_GetTagValue(FITAG *tag);
-
-DLL_API BOOL DLL_CALLCONV FreeImage_SetTagKey(FITAG *tag, const char *key);
-DLL_API BOOL DLL_CALLCONV FreeImage_SetTagDescription(FITAG *tag, const char *description);
-DLL_API BOOL DLL_CALLCONV FreeImage_SetTagID(FITAG *tag, WORD id);
-DLL_API BOOL DLL_CALLCONV FreeImage_SetTagType(FITAG *tag, FREE_IMAGE_MDTYPE type);
-DLL_API BOOL DLL_CALLCONV FreeImage_SetTagCount(FITAG *tag, DWORD count);
-DLL_API BOOL DLL_CALLCONV FreeImage_SetTagLength(FITAG *tag, DWORD length);
-DLL_API BOOL DLL_CALLCONV FreeImage_SetTagValue(FITAG *tag, const void *value);
-
-// iterator
-DLL_API FIMETADATA *DLL_CALLCONV FreeImage_FindFirstMetadata(FREE_IMAGE_MDMODEL model, FIBITMAP *dib, FITAG **tag);
-DLL_API BOOL DLL_CALLCONV FreeImage_FindNextMetadata(FIMETADATA *mdhandle, FITAG **tag);
-DLL_API void DLL_CALLCONV FreeImage_FindCloseMetadata(FIMETADATA *mdhandle);
-
-// metadata setter and getter
-DLL_API BOOL DLL_CALLCONV FreeImage_SetMetadata(FREE_IMAGE_MDMODEL model, FIBITMAP *dib, const char *key, FITAG *tag);
-DLL_API BOOL DLL_CALLCONV FreeImage_GetMetadata(FREE_IMAGE_MDMODEL model, FIBITMAP *dib, const char *key, FITAG **tag);
-
-// helpers
-DLL_API unsigned DLL_CALLCONV FreeImage_GetMetadataCount(FREE_IMAGE_MDMODEL model, FIBITMAP *dib);
-DLL_API BOOL DLL_CALLCONV FreeImage_CloneMetadata(FIBITMAP *dst, FIBITMAP *src);
-
-// tag to C string conversion
-DLL_API const char* DLL_CALLCONV FreeImage_TagToString(FREE_IMAGE_MDMODEL model, FITAG *tag, char *Make FI_DEFAULT(NULL));
-
-// --------------------------------------------------------------------------
-// Image manipulation toolkit -----------------------------------------------
-// --------------------------------------------------------------------------
-
-// rotation and flipping
-/// @deprecated see FreeImage_Rotate
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_RotateClassic(FIBITMAP *dib, double angle);
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Rotate(FIBITMAP *dib, double angle, const void *bkcolor FI_DEFAULT(NULL));
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_RotateEx(FIBITMAP *dib, double angle, double x_shift, double y_shift, double x_origin, double y_origin, BOOL use_mask);
-DLL_API BOOL DLL_CALLCONV FreeImage_FlipHorizontal(FIBITMAP *dib);
-DLL_API BOOL DLL_CALLCONV FreeImage_FlipVertical(FIBITMAP *dib);
-DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransform(const char *src_file, const char *dst_file, FREE_IMAGE_JPEG_OPERATION operation, BOOL perfect FI_DEFAULT(FALSE));
-DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransformU(const wchar_t *src_file, const wchar_t *dst_file, FREE_IMAGE_JPEG_OPERATION operation, BOOL perfect FI_DEFAULT(FALSE));
-
-// upsampling / downsampling
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Rescale(FIBITMAP *dib, int dst_width, int dst_height, FREE_IMAGE_FILTER filter);
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_MakeThumbnail(FIBITMAP *dib, int max_pixel_size, BOOL convert FI_DEFAULT(TRUE));
-
-// color manipulation routines (point operations)
-DLL_API BOOL DLL_CALLCONV FreeImage_AdjustCurve(FIBITMAP *dib, BYTE *LUT, FREE_IMAGE_COLOR_CHANNEL channel);
-DLL_API BOOL DLL_CALLCONV FreeImage_AdjustGamma(FIBITMAP *dib, double gamma);
-DLL_API BOOL DLL_CALLCONV FreeImage_AdjustBrightness(FIBITMAP *dib, double percentage);
-DLL_API BOOL DLL_CALLCONV FreeImage_AdjustContrast(FIBITMAP *dib, double percentage);
-DLL_API BOOL DLL_CALLCONV FreeImage_Invert(FIBITMAP *dib);
-DLL_API BOOL DLL_CALLCONV FreeImage_GetHistogram(FIBITMAP *dib, DWORD *histo, FREE_IMAGE_COLOR_CHANNEL channel FI_DEFAULT(FICC_BLACK));
-DLL_API int DLL_CALLCONV FreeImage_GetAdjustColorsLookupTable(BYTE *LUT, double brightness, double contrast, double gamma, BOOL invert);
-DLL_API BOOL DLL_CALLCONV FreeImage_AdjustColors(FIBITMAP *dib, double brightness, double contrast, double gamma, BOOL invert FI_DEFAULT(FALSE));
-DLL_API unsigned DLL_CALLCONV FreeImage_ApplyColorMapping(FIBITMAP *dib, RGBQUAD *srccolors, RGBQUAD *dstcolors, unsigned count, BOOL ignore_alpha, BOOL swap);
-DLL_API unsigned DLL_CALLCONV FreeImage_SwapColors(FIBITMAP *dib, RGBQUAD *color_a, RGBQUAD *color_b, BOOL ignore_alpha);
-DLL_API unsigned DLL_CALLCONV FreeImage_ApplyPaletteIndexMapping(FIBITMAP *dib, BYTE *srcindices,	BYTE *dstindices, unsigned count, BOOL swap);
-DLL_API unsigned DLL_CALLCONV FreeImage_SwapPaletteIndices(FIBITMAP *dib, BYTE *index_a, BYTE *index_b);
-
-// channel processing routines
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_GetChannel(FIBITMAP *dib, FREE_IMAGE_COLOR_CHANNEL channel);
-DLL_API BOOL DLL_CALLCONV FreeImage_SetChannel(FIBITMAP *dst, FIBITMAP *src, FREE_IMAGE_COLOR_CHANNEL channel);
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_GetComplexChannel(FIBITMAP *src, FREE_IMAGE_COLOR_CHANNEL channel);
-DLL_API BOOL DLL_CALLCONV FreeImage_SetComplexChannel(FIBITMAP *dst, FIBITMAP *src, FREE_IMAGE_COLOR_CHANNEL channel);
-
-// copy / paste / composite routines
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Copy(FIBITMAP *dib, int left, int top, int right, int bottom);
-DLL_API BOOL DLL_CALLCONV FreeImage_Paste(FIBITMAP *dst, FIBITMAP *src, int left, int top, int alpha);
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Composite(FIBITMAP *fg, BOOL useFileBkg FI_DEFAULT(FALSE), RGBQUAD *appBkColor FI_DEFAULT(NULL), FIBITMAP *bg FI_DEFAULT(NULL));
-DLL_API BOOL DLL_CALLCONV FreeImage_JPEGCrop(const char *src_file, const char *dst_file, int left, int top, int right, int bottom);
-DLL_API BOOL DLL_CALLCONV FreeImage_JPEGCropU(const wchar_t *src_file, const wchar_t *dst_file, int left, int top, int right, int bottom);
-DLL_API BOOL DLL_CALLCONV FreeImage_PreMultiplyWithAlpha(FIBITMAP *dib);
-
-// background filling routines
-DLL_API BOOL DLL_CALLCONV FreeImage_FillBackground(FIBITMAP *dib, const void *color, int options FI_DEFAULT(0));
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_EnlargeCanvas(FIBITMAP *src, int left, int top, int right, int bottom, const void *color, int options FI_DEFAULT(0));
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_AllocateEx(int width, int height, int bpp, const RGBQUAD *color, int options FI_DEFAULT(0), const RGBQUAD *palette FI_DEFAULT(NULL), unsigned red_mask FI_DEFAULT(0), unsigned green_mask FI_DEFAULT(0), unsigned blue_mask FI_DEFAULT(0));
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_AllocateExT(FREE_IMAGE_TYPE type, int width, int height, int bpp, const void *color, int options FI_DEFAULT(0), const RGBQUAD *palette FI_DEFAULT(NULL), unsigned red_mask FI_DEFAULT(0), unsigned green_mask FI_DEFAULT(0), unsigned blue_mask FI_DEFAULT(0));
-
-// miscellaneous algorithms
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_MultigridPoissonSolver(FIBITMAP *Laplacian, int ncycle FI_DEFAULT(3));
-
-// restore the borland-specific enum size option
-#if defined(__BORLANDC__)
-#pragma option pop
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // FREEIMAGE_H
+// ==========================================================
+// FreeImage 3
+//
+// Design and implementation by
+// - Floris van den Berg (flvdberg at wxs.nl)
+// - Herv� Drolon (drolon at infonie.fr)
+//
+// Contributors:
+// - see changes log named 'Whatsnew.txt', see header of each .h and .cpp file
+//
+// This file is part of FreeImage 3
+//
+// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
+// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
+// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
+// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
+// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
+// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
+// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+// THIS DISCLAIMER.
+//
+// Use at your own risk!
+// ==========================================================
+
+#ifndef FREEIMAGE_H
+#define FREEIMAGE_H
+
+// Version information ------------------------------------------------------
+
+#define FREEIMAGE_MAJOR_VERSION   3
+#define FREEIMAGE_MINOR_VERSION   17
+#define FREEIMAGE_RELEASE_SERIAL  0
+
+// Compiler options ---------------------------------------------------------
+
+#include <wchar.h>	// needed for UNICODE functions
+
+#if defined(FREEIMAGE_LIB)
+	#define DLL_API
+	#define DLL_CALLCONV
+#else
+	#if defined(_WIN32) || defined(__WIN32__)
+		#define DLL_CALLCONV __stdcall
+		// The following ifdef block is the standard way of creating macros which make exporting 
+		// from a DLL simpler. All files within this DLL are compiled with the FREEIMAGE_EXPORTS
+		// symbol defined on the command line. this symbol should not be defined on any project
+		// that uses this DLL. This way any other project whose source files include this file see 
+		// DLL_API functions as being imported from a DLL, wheras this DLL sees symbols
+		// defined with this macro as being exported.
+		#ifdef FREEIMAGE_EXPORTS
+			#define DLL_API __declspec(dllexport)
+		#else
+			#define DLL_API __declspec(dllimport)
+		#endif // FREEIMAGE_EXPORTS
+	#else 
+		// try the gcc visibility support (see http://gcc.gnu.org/wiki/Visibility)
+		#if defined(__GNUC__) && ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+			#ifndef GCC_HASCLASSVISIBILITY
+				#define GCC_HASCLASSVISIBILITY
+			#endif
+		#endif // __GNUC__
+		#define DLL_CALLCONV
+		#if defined(GCC_HASCLASSVISIBILITY)
+			#define DLL_API __attribute__ ((visibility("default")))
+		#else
+			#define DLL_API
+		#endif		
+	#endif // WIN32 / !WIN32
+#endif // FREEIMAGE_LIB
+
+// Endianness:
+// Some versions of gcc may have BYTE_ORDER or __BYTE_ORDER defined.
+// If your big endian system isn't being detected, add an OS specific check
+// or define any of FREEIMAGE_BIGENDIAN and FREEIMAGE_LITTLEENDIAN directly
+// to specify the desired endianness.
+#if (!defined(FREEIMAGE_BIGENDIAN) && !defined(FREEIMAGE_LITTLEENDIAN))
+	#if (defined(BYTE_ORDER) && BYTE_ORDER==BIG_ENDIAN) || (defined(__BYTE_ORDER) && __BYTE_ORDER==__BIG_ENDIAN) || defined(__BIG_ENDIAN__)
+		#define FREEIMAGE_BIGENDIAN
+	#endif // BYTE_ORDER
+#endif // !FREEIMAGE_[BIG|LITTLE]ENDIAN
+
+// Color-Order:
+// The specified order of color components red, green and blue affects 24-
+// and 32-bit images of type FIT_BITMAP as well as the colors that are part
+// of a color palette. All other images always use RGB order. By default,
+// color order is coupled to endianness:
+// little-endian -> BGR
+// big-endian    -> RGB
+// However, you can always define FREEIMAGE_COLORORDER to any of the known
+// orders FREEIMAGE_COLORORDER_BGR (0) and FREEIMAGE_COLORORDER_RGB (1) to
+// specify your preferred color order.
+#define FREEIMAGE_COLORORDER_BGR    0
+#define FREEIMAGE_COLORORDER_RGB    1
+#if (!defined(FREEIMAGE_COLORORDER)) || ((FREEIMAGE_COLORORDER != FREEIMAGE_COLORORDER_BGR) && (FREEIMAGE_COLORORDER != FREEIMAGE_COLORORDER_RGB))
+	#if defined(FREEIMAGE_BIGENDIAN)
+		#define FREEIMAGE_COLORORDER FREEIMAGE_COLORORDER_RGB
+	#else
+		#define FREEIMAGE_COLORORDER FREEIMAGE_COLORORDER_BGR
+	#endif // FREEIMAGE_BIGENDIAN
+#endif // FREEIMAGE_COLORORDER
+
+// Ensure 4-byte enums if we're using Borland C++ compilers
+#if defined(__BORLANDC__)
+#pragma option push -b
+#endif
+
+// For C compatibility --------------------------------------------------------
+
+#ifdef __cplusplus
+#define FI_DEFAULT(x)	= x
+#define FI_ENUM(x)      enum x
+#define FI_STRUCT(x)	struct x
+#else
+#define FI_DEFAULT(x)
+#define FI_ENUM(x)      typedef int x; enum x
+#define FI_STRUCT(x)	typedef struct x x; struct x
+#endif
+
+// Bitmap types -------------------------------------------------------------
+
+FI_STRUCT (FIBITMAP) { void *data; };
+FI_STRUCT (FIMULTIBITMAP) { void *data; };
+
+// Types used in the library (directly copied from Windows) -----------------
+
+#if defined(__MINGW32__) && defined(_WINDOWS_H)
+#define _WINDOWS_	// prevent a bug in MinGW32
+#endif // __MINGW32__
+
+#ifndef _WINDOWS_
+#define _WINDOWS_
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef NULL
+#define NULL 0
+#endif
+
+#ifndef SEEK_SET
+#define SEEK_SET  0
+#define SEEK_CUR  1
+#define SEEK_END  2
+#endif
+
+#ifndef _MSC_VER
+// define portable types for 32-bit / 64-bit OS
+#include <inttypes.h>
+typedef int32_t BOOL;
+typedef uint8_t BYTE;
+typedef uint16_t WORD;
+typedef uint32_t DWORD;
+typedef int32_t LONG;
+typedef int64_t INT64;
+typedef uint64_t UINT64;
+#else
+// MS is not C99 ISO compliant
+typedef long BOOL;
+typedef unsigned char BYTE;
+typedef unsigned short WORD;
+typedef unsigned long DWORD;
+typedef long LONG;
+typedef signed __int64 INT64;
+typedef unsigned __int64 UINT64;
+#endif // _MSC_VER
+
+#if (defined(_WIN32) || defined(__WIN32__))
+#pragma pack(push, 1)
+#else
+#pragma pack(1)
+#endif // WIN32
+
+typedef struct tagRGBQUAD {
+#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
+  BYTE rgbBlue;
+  BYTE rgbGreen;
+  BYTE rgbRed;
+#else
+  BYTE rgbRed;
+  BYTE rgbGreen;
+  BYTE rgbBlue;
+#endif // FREEIMAGE_COLORORDER
+  BYTE rgbReserved;
+} RGBQUAD;
+
+typedef struct tagRGBTRIPLE {
+#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
+  BYTE rgbtBlue;
+  BYTE rgbtGreen;
+  BYTE rgbtRed;
+#else
+  BYTE rgbtRed;
+  BYTE rgbtGreen;
+  BYTE rgbtBlue;
+#endif // FREEIMAGE_COLORORDER
+} RGBTRIPLE;
+
+#if (defined(_WIN32) || defined(__WIN32__))
+#pragma pack(pop)
+#else
+#pragma pack()
+#endif // WIN32
+
+typedef struct tagBITMAPINFOHEADER{
+  DWORD biSize;
+  LONG  biWidth; 
+  LONG  biHeight; 
+  WORD  biPlanes; 
+  WORD  biBitCount;
+  DWORD biCompression; 
+  DWORD biSizeImage; 
+  LONG  biXPelsPerMeter; 
+  LONG  biYPelsPerMeter; 
+  DWORD biClrUsed; 
+  DWORD biClrImportant;
+} BITMAPINFOHEADER, *PBITMAPINFOHEADER; 
+
+typedef struct tagBITMAPINFO { 
+  BITMAPINFOHEADER bmiHeader; 
+  RGBQUAD          bmiColors[1];
+} BITMAPINFO, *PBITMAPINFO;
+
+#endif // _WINDOWS_
+
+// Types used in the library (specific to FreeImage) ------------------------
+
+#if (defined(_WIN32) || defined(__WIN32__))
+#pragma pack(push, 1)
+#else
+#pragma pack(1)
+#endif // WIN32
+
+/** 48-bit RGB 
+*/
+typedef struct tagFIRGB16 {
+	WORD red;
+	WORD green;
+	WORD blue;
+} FIRGB16;
+
+/** 64-bit RGBA
+*/
+typedef struct tagFIRGBA16 {
+	WORD red;
+	WORD green;
+	WORD blue;
+	WORD alpha;
+} FIRGBA16;
+
+/** 96-bit RGB Float
+*/
+typedef struct tagFIRGBF {
+	float red;
+	float green;
+	float blue;
+} FIRGBF;
+
+/** 128-bit RGBA Float
+*/
+typedef struct tagFIRGBAF {
+	float red;
+	float green;
+	float blue;
+	float alpha;
+} FIRGBAF;
+
+/** Data structure for COMPLEX type (complex number)
+*/
+typedef struct tagFICOMPLEX {
+    /// real part
+	double r;
+	/// imaginary part
+    double i;
+} FICOMPLEX;
+
+#if (defined(_WIN32) || defined(__WIN32__))
+#pragma pack(pop)
+#else
+#pragma pack()
+#endif // WIN32
+
+// Indexes for byte arrays, masks and shifts for treating pixels as words ---
+// These coincide with the order of RGBQUAD and RGBTRIPLE -------------------
+
+#ifndef FREEIMAGE_BIGENDIAN
+#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
+// Little Endian (x86 / MS Windows, Linux) : BGR(A) order
+#define FI_RGBA_RED				2
+#define FI_RGBA_GREEN			1
+#define FI_RGBA_BLUE			0
+#define FI_RGBA_ALPHA			3
+#define FI_RGBA_RED_MASK		0x00FF0000
+#define FI_RGBA_GREEN_MASK		0x0000FF00
+#define FI_RGBA_BLUE_MASK		0x000000FF
+#define FI_RGBA_ALPHA_MASK		0xFF000000
+#define FI_RGBA_RED_SHIFT		16
+#define FI_RGBA_GREEN_SHIFT		8
+#define FI_RGBA_BLUE_SHIFT		0
+#define FI_RGBA_ALPHA_SHIFT		24
+#else
+// Little Endian (x86 / MaxOSX) : RGB(A) order
+#define FI_RGBA_RED				0
+#define FI_RGBA_GREEN			1
+#define FI_RGBA_BLUE			2
+#define FI_RGBA_ALPHA			3
+#define FI_RGBA_RED_MASK		0x000000FF
+#define FI_RGBA_GREEN_MASK		0x0000FF00
+#define FI_RGBA_BLUE_MASK		0x00FF0000
+#define FI_RGBA_ALPHA_MASK		0xFF000000
+#define FI_RGBA_RED_SHIFT		0
+#define FI_RGBA_GREEN_SHIFT		8
+#define FI_RGBA_BLUE_SHIFT		16
+#define FI_RGBA_ALPHA_SHIFT		24
+#endif // FREEIMAGE_COLORORDER
+#else
+#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
+// Big Endian (PPC / none) : BGR(A) order
+#define FI_RGBA_RED				2
+#define FI_RGBA_GREEN			1
+#define FI_RGBA_BLUE			0
+#define FI_RGBA_ALPHA			3
+#define FI_RGBA_RED_MASK		0x0000FF00
+#define FI_RGBA_GREEN_MASK		0x00FF0000
+#define FI_RGBA_BLUE_MASK		0xFF000000
+#define FI_RGBA_ALPHA_MASK		0x000000FF
+#define FI_RGBA_RED_SHIFT		8
+#define FI_RGBA_GREEN_SHIFT		16
+#define FI_RGBA_BLUE_SHIFT		24
+#define FI_RGBA_ALPHA_SHIFT		0
+#else
+// Big Endian (PPC / Linux, MaxOSX) : RGB(A) order
+#define FI_RGBA_RED				0
+#define FI_RGBA_GREEN			1
+#define FI_RGBA_BLUE			2
+#define FI_RGBA_ALPHA			3
+#define FI_RGBA_RED_MASK		0xFF000000
+#define FI_RGBA_GREEN_MASK		0x00FF0000
+#define FI_RGBA_BLUE_MASK		0x0000FF00
+#define FI_RGBA_ALPHA_MASK		0x000000FF
+#define FI_RGBA_RED_SHIFT		24
+#define FI_RGBA_GREEN_SHIFT		16
+#define FI_RGBA_BLUE_SHIFT		8
+#define FI_RGBA_ALPHA_SHIFT		0
+#endif // FREEIMAGE_COLORORDER
+#endif // FREEIMAGE_BIGENDIAN
+
+#define FI_RGBA_RGB_MASK		(FI_RGBA_RED_MASK|FI_RGBA_GREEN_MASK|FI_RGBA_BLUE_MASK)
+
+// The 16bit macros only include masks and shifts, since each color element is not byte aligned
+
+#define FI16_555_RED_MASK		0x7C00
+#define FI16_555_GREEN_MASK		0x03E0
+#define FI16_555_BLUE_MASK		0x001F
+#define FI16_555_RED_SHIFT		10
+#define FI16_555_GREEN_SHIFT	5
+#define FI16_555_BLUE_SHIFT		0
+#define FI16_565_RED_MASK		0xF800
+#define FI16_565_GREEN_MASK		0x07E0
+#define FI16_565_BLUE_MASK		0x001F
+#define FI16_565_RED_SHIFT		11
+#define FI16_565_GREEN_SHIFT	5
+#define FI16_565_BLUE_SHIFT		0
+
+// ICC profile support ------------------------------------------------------
+
+#define FIICC_DEFAULT			0x00
+#define FIICC_COLOR_IS_CMYK		0x01
+
+FI_STRUCT (FIICCPROFILE) { 
+	WORD    flags;	//! info flag
+	DWORD	size;	//! profile's size measured in bytes
+	void   *data;	//! points to a block of contiguous memory containing the profile
+};
+
+// Important enums ----------------------------------------------------------
+
+/** I/O image format identifiers.
+*/
+FI_ENUM(FREE_IMAGE_FORMAT) {
+	FIF_UNKNOWN = -1,
+	FIF_BMP		= 0,
+	FIF_ICO		= 1,
+	FIF_JPEG	= 2,
+	FIF_JNG		= 3,
+	FIF_KOALA	= 4,
+	FIF_LBM		= 5,
+	FIF_IFF = FIF_LBM,
+	FIF_MNG		= 6,
+	FIF_PBM		= 7,
+	FIF_PBMRAW	= 8,
+	FIF_PCD		= 9,
+	FIF_PCX		= 10,
+	FIF_PGM		= 11,
+	FIF_PGMRAW	= 12,
+	FIF_PNG		= 13,
+	FIF_PPM		= 14,
+	FIF_PPMRAW	= 15,
+	FIF_RAS		= 16,
+	FIF_TARGA	= 17,
+	FIF_TIFF	= 18,
+	FIF_WBMP	= 19,
+	FIF_PSD		= 20,
+	FIF_CUT		= 21,
+	FIF_XBM		= 22,
+	FIF_XPM		= 23,
+	FIF_DDS		= 24,
+	FIF_GIF     = 25,
+	FIF_HDR		= 26,
+	FIF_FAXG3	= 27,
+	FIF_SGI		= 28,
+	FIF_EXR		= 29,
+	FIF_J2K		= 30,
+	FIF_JP2		= 31,
+	FIF_PFM		= 32,
+	FIF_PICT	= 33,
+	FIF_RAW		= 34,
+	FIF_WEBP	= 35,
+	FIF_JXR		= 36
+};
+
+/** Image type used in FreeImage.
+*/
+FI_ENUM(FREE_IMAGE_TYPE) {
+	FIT_UNKNOWN = 0,	//! unknown type
+	FIT_BITMAP  = 1,	//! standard image			: 1-, 4-, 8-, 16-, 24-, 32-bit
+	FIT_UINT16	= 2,	//! array of unsigned short	: unsigned 16-bit
+	FIT_INT16	= 3,	//! array of short			: signed 16-bit
+	FIT_UINT32	= 4,	//! array of unsigned long	: unsigned 32-bit
+	FIT_INT32	= 5,	//! array of long			: signed 32-bit
+	FIT_FLOAT	= 6,	//! array of float			: 32-bit IEEE floating point
+	FIT_DOUBLE	= 7,	//! array of double			: 64-bit IEEE floating point
+	FIT_COMPLEX	= 8,	//! array of FICOMPLEX		: 2 x 64-bit IEEE floating point
+	FIT_RGB16	= 9,	//! 48-bit RGB image			: 3 x 16-bit
+	FIT_RGBA16	= 10,	//! 64-bit RGBA image		: 4 x 16-bit
+	FIT_RGBF	= 11,	//! 96-bit RGB float image	: 3 x 32-bit IEEE floating point
+	FIT_RGBAF	= 12	//! 128-bit RGBA float image	: 4 x 32-bit IEEE floating point
+};
+
+/** Image color type used in FreeImage.
+*/
+FI_ENUM(FREE_IMAGE_COLOR_TYPE) {
+	FIC_MINISWHITE = 0,		//! min value is white
+    FIC_MINISBLACK = 1,		//! min value is black
+    FIC_RGB        = 2,		//! RGB color model
+    FIC_PALETTE    = 3,		//! color map indexed
+	FIC_RGBALPHA   = 4,		//! RGB color model with alpha channel
+	FIC_CMYK       = 5		//! CMYK color model
+};
+
+/** Color quantization algorithms.
+Constants used in FreeImage_ColorQuantize.
+*/
+FI_ENUM(FREE_IMAGE_QUANTIZE) {
+    FIQ_WUQUANT = 0,		//! Xiaolin Wu color quantization algorithm
+    FIQ_NNQUANT = 1,		//! NeuQuant neural-net quantization algorithm by Anthony Dekker
+	FIQ_LFPQUANT = 2		//! Lossless Fast Pseudo-Quantization Algorithm by Carsten Klein
+};
+
+/** Dithering algorithms.
+Constants used in FreeImage_Dither.
+*/
+FI_ENUM(FREE_IMAGE_DITHER) {
+    FID_FS			= 0,	//! Floyd & Steinberg error diffusion
+	FID_BAYER4x4	= 1,	//! Bayer ordered dispersed dot dithering (order 2 dithering matrix)
+	FID_BAYER8x8	= 2,	//! Bayer ordered dispersed dot dithering (order 3 dithering matrix)
+	FID_CLUSTER6x6	= 3,	//! Ordered clustered dot dithering (order 3 - 6x6 matrix)
+	FID_CLUSTER8x8	= 4,	//! Ordered clustered dot dithering (order 4 - 8x8 matrix)
+	FID_CLUSTER16x16= 5,	//! Ordered clustered dot dithering (order 8 - 16x16 matrix)
+	FID_BAYER16x16	= 6		//! Bayer ordered dispersed dot dithering (order 4 dithering matrix)
+};
+
+/** Lossless JPEG transformations
+Constants used in FreeImage_JPEGTransform
+*/
+FI_ENUM(FREE_IMAGE_JPEG_OPERATION) {
+	FIJPEG_OP_NONE			= 0,	//! no transformation
+	FIJPEG_OP_FLIP_H		= 1,	//! horizontal flip
+	FIJPEG_OP_FLIP_V		= 2,	//! vertical flip
+	FIJPEG_OP_TRANSPOSE		= 3,	//! transpose across UL-to-LR axis
+	FIJPEG_OP_TRANSVERSE	= 4,	//! transpose across UR-to-LL axis
+	FIJPEG_OP_ROTATE_90		= 5,	//! 90-degree clockwise rotation
+	FIJPEG_OP_ROTATE_180	= 6,	//! 180-degree rotation
+	FIJPEG_OP_ROTATE_270	= 7		//! 270-degree clockwise (or 90 ccw)
+};
+
+/** Tone mapping operators.
+Constants used in FreeImage_ToneMapping.
+*/
+FI_ENUM(FREE_IMAGE_TMO) {
+    FITMO_DRAGO03	 = 0,	//! Adaptive logarithmic mapping (F. Drago, 2003)
+	FITMO_REINHARD05 = 1,	//! Dynamic range reduction inspired by photoreceptor physiology (E. Reinhard, 2005)
+	FITMO_FATTAL02	 = 2	//! Gradient domain high dynamic range compression (R. Fattal, 2002)
+};
+
+/** Upsampling / downsampling filters. 
+Constants used in FreeImage_Rescale.
+*/
+FI_ENUM(FREE_IMAGE_FILTER) {
+	FILTER_BOX		  = 0,	//! Box, pulse, Fourier window, 1st order (constant) b-spline
+	FILTER_BICUBIC	  = 1,	//! Mitchell & Netravali's two-param cubic filter
+	FILTER_BILINEAR   = 2,	//! Bilinear filter
+	FILTER_BSPLINE	  = 3,	//! 4th order (cubic) b-spline
+	FILTER_CATMULLROM = 4,	//! Catmull-Rom spline, Overhauser spline
+	FILTER_LANCZOS3	  = 5	//! Lanczos3 filter
+};
+
+/** Color channels.
+Constants used in color manipulation routines.
+*/
+FI_ENUM(FREE_IMAGE_COLOR_CHANNEL) {
+	FICC_RGB	= 0,	//! Use red, green and blue channels
+	FICC_RED	= 1,	//! Use red channel
+	FICC_GREEN	= 2,	//! Use green channel
+	FICC_BLUE	= 3,	//! Use blue channel
+	FICC_ALPHA	= 4,	//! Use alpha channel
+	FICC_BLACK	= 5,	//! Use black channel
+	FICC_REAL	= 6,	//! Complex images: use real part
+	FICC_IMAG	= 7,	//! Complex images: use imaginary part
+	FICC_MAG	= 8,	//! Complex images: use magnitude
+	FICC_PHASE	= 9		//! Complex images: use phase
+};
+
+// Metadata support ---------------------------------------------------------
+
+/**
+  Tag data type information (based on TIFF specifications)
+
+  Note: RATIONALs are the ratio of two 32-bit integer values.
+*/
+FI_ENUM(FREE_IMAGE_MDTYPE) {
+	FIDT_NOTYPE		= 0,	//! placeholder 
+	FIDT_BYTE		= 1,	//! 8-bit unsigned integer 
+	FIDT_ASCII		= 2,	//! 8-bit bytes w/ last byte null 
+	FIDT_SHORT		= 3,	//! 16-bit unsigned integer 
+	FIDT_LONG		= 4,	//! 32-bit unsigned integer 
+	FIDT_RATIONAL	= 5,	//! 64-bit unsigned fraction 
+	FIDT_SBYTE		= 6,	//! 8-bit signed integer 
+	FIDT_UNDEFINED	= 7,	//! 8-bit untyped data 
+	FIDT_SSHORT		= 8,	//! 16-bit signed integer 
+	FIDT_SLONG		= 9,	//! 32-bit signed integer 
+	FIDT_SRATIONAL	= 10,	//! 64-bit signed fraction 
+	FIDT_FLOAT		= 11,	//! 32-bit IEEE floating point 
+	FIDT_DOUBLE		= 12,	//! 64-bit IEEE floating point 
+	FIDT_IFD		= 13,	//! 32-bit unsigned integer (offset) 
+	FIDT_PALETTE	= 14,	//! 32-bit RGBQUAD 
+	FIDT_LONG8		= 16,	//! 64-bit unsigned integer 
+	FIDT_SLONG8		= 17,	//! 64-bit signed integer
+	FIDT_IFD8		= 18	//! 64-bit unsigned integer (offset)
+};
+
+/**
+  Metadata models supported by FreeImage
+*/
+FI_ENUM(FREE_IMAGE_MDMODEL) {
+	FIMD_NODATA			= -1,
+	FIMD_COMMENTS		= 0,	//! single comment or keywords
+	FIMD_EXIF_MAIN		= 1,	//! Exif-TIFF metadata
+	FIMD_EXIF_EXIF		= 2,	//! Exif-specific metadata
+	FIMD_EXIF_GPS		= 3,	//! Exif GPS metadata
+	FIMD_EXIF_MAKERNOTE = 4,	//! Exif maker note metadata
+	FIMD_EXIF_INTEROP	= 5,	//! Exif interoperability metadata
+	FIMD_IPTC			= 6,	//! IPTC/NAA metadata
+	FIMD_XMP			= 7,	//! Abobe XMP metadata
+	FIMD_GEOTIFF		= 8,	//! GeoTIFF metadata
+	FIMD_ANIMATION		= 9,	//! Animation metadata
+	FIMD_CUSTOM			= 10,	//! Used to attach other metadata types to a dib
+	FIMD_EXIF_RAW		= 11	//! Exif metadata as a raw buffer
+};
+
+/**
+  Handle to a metadata model
+*/
+FI_STRUCT (FIMETADATA) { void *data; };
+
+/**
+  Handle to a FreeImage tag
+*/
+FI_STRUCT (FITAG) { void *data; };
+
+// File IO routines ---------------------------------------------------------
+
+#ifndef FREEIMAGE_IO
+#define FREEIMAGE_IO
+
+typedef void* fi_handle;
+typedef unsigned (DLL_CALLCONV *FI_ReadProc) (void *buffer, unsigned size, unsigned count, fi_handle handle);
+typedef unsigned (DLL_CALLCONV *FI_WriteProc) (void *buffer, unsigned size, unsigned count, fi_handle handle);
+typedef int (DLL_CALLCONV *FI_SeekProc) (fi_handle handle, long offset, int origin);
+typedef long (DLL_CALLCONV *FI_TellProc) (fi_handle handle);
+
+#if (defined(_WIN32) || defined(__WIN32__))
+#pragma pack(push, 1)
+#else
+#pragma pack(1)
+#endif // WIN32
+
+FI_STRUCT(FreeImageIO) {
+	FI_ReadProc  read_proc;     //! pointer to the function used to read data
+    FI_WriteProc write_proc;    //! pointer to the function used to write data
+    FI_SeekProc  seek_proc;     //! pointer to the function used to seek
+    FI_TellProc  tell_proc;     //! pointer to the function used to aquire the current position
+};
+
+#if (defined(_WIN32) || defined(__WIN32__))
+#pragma pack(pop)
+#else
+#pragma pack()
+#endif // WIN32
+
+/**
+Handle to a memory I/O stream
+*/
+FI_STRUCT (FIMEMORY) { void *data; };
+
+#endif // FREEIMAGE_IO
+
+// Plugin routines ----------------------------------------------------------
+
+#ifndef PLUGINS
+#define PLUGINS
+
+typedef const char *(DLL_CALLCONV *FI_FormatProc)(void);
+typedef const char *(DLL_CALLCONV *FI_DescriptionProc)(void);
+typedef const char *(DLL_CALLCONV *FI_ExtensionListProc)(void);
+typedef const char *(DLL_CALLCONV *FI_RegExprProc)(void);
+typedef void *(DLL_CALLCONV *FI_OpenProc)(FreeImageIO *io, fi_handle handle, BOOL read);
+typedef void (DLL_CALLCONV *FI_CloseProc)(FreeImageIO *io, fi_handle handle, void *data);
+typedef int (DLL_CALLCONV *FI_PageCountProc)(FreeImageIO *io, fi_handle handle, void *data);
+typedef int (DLL_CALLCONV *FI_PageCapabilityProc)(FreeImageIO *io, fi_handle handle, void *data);
+typedef FIBITMAP *(DLL_CALLCONV *FI_LoadProc)(FreeImageIO *io, fi_handle handle, int page, int flags, void *data);
+typedef BOOL (DLL_CALLCONV *FI_SaveProc)(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void *data);
+typedef BOOL (DLL_CALLCONV *FI_ValidateProc)(FreeImageIO *io, fi_handle handle);
+typedef const char *(DLL_CALLCONV *FI_MimeProc)(void);
+typedef BOOL (DLL_CALLCONV *FI_SupportsExportBPPProc)(int bpp);
+typedef BOOL (DLL_CALLCONV *FI_SupportsExportTypeProc)(FREE_IMAGE_TYPE type);
+typedef BOOL (DLL_CALLCONV *FI_SupportsICCProfilesProc)(void);
+typedef BOOL (DLL_CALLCONV *FI_SupportsNoPixelsProc)(void);
+
+FI_STRUCT (Plugin) {
+	FI_FormatProc format_proc;
+	FI_DescriptionProc description_proc;
+	FI_ExtensionListProc extension_proc;
+	FI_RegExprProc regexpr_proc;
+	FI_OpenProc open_proc;
+	FI_CloseProc close_proc;
+	FI_PageCountProc pagecount_proc;
+	FI_PageCapabilityProc pagecapability_proc;
+	FI_LoadProc load_proc;
+	FI_SaveProc save_proc;
+	FI_ValidateProc validate_proc;
+	FI_MimeProc mime_proc;
+	FI_SupportsExportBPPProc supports_export_bpp_proc;
+	FI_SupportsExportTypeProc supports_export_type_proc;
+	FI_SupportsICCProfilesProc supports_icc_profiles_proc;
+	FI_SupportsNoPixelsProc supports_no_pixels_proc;
+};
+
+typedef void (DLL_CALLCONV *FI_InitProc)(Plugin *plugin, int format_id);
+
+#endif // PLUGINS
+
+
+// Load / Save flag constants -----------------------------------------------
+
+#define FIF_LOAD_NOPIXELS 0x8000	//! loading: load the image header only (not supported by all plugins, default to full loading)
+
+#define BMP_DEFAULT         0
+#define BMP_SAVE_RLE        1
+#define CUT_DEFAULT         0
+#define DDS_DEFAULT			0
+#define EXR_DEFAULT			0		//! save data as half with piz-based wavelet compression
+#define EXR_FLOAT			0x0001	//! save data as float instead of as half (not recommended)
+#define EXR_NONE			0x0002	//! save with no compression
+#define EXR_ZIP				0x0004	//! save with zlib compression, in blocks of 16 scan lines
+#define EXR_PIZ				0x0008	//! save with piz-based wavelet compression
+#define EXR_PXR24			0x0010	//! save with lossy 24-bit float compression
+#define EXR_B44				0x0020	//! save with lossy 44% float compression - goes to 22% when combined with EXR_LC
+#define EXR_LC				0x0040	//! save images with one luminance and two chroma channels, rather than as RGB (lossy compression)
+#define FAXG3_DEFAULT		0
+#define GIF_DEFAULT			0
+#define GIF_LOAD256			1		//! load the image as a 256 color image with ununsed palette entries, if it's 16 or 2 color
+#define GIF_PLAYBACK		2		//! 'Play' the GIF to generate each frame (as 32bpp) instead of returning raw frame data when loading
+#define HDR_DEFAULT			0
+#define ICO_DEFAULT         0
+#define ICO_MAKEALPHA		1		//! convert to 32bpp and create an alpha channel from the AND-mask when loading
+#define IFF_DEFAULT         0
+#define J2K_DEFAULT			0		//! save with a 16:1 rate
+#define JP2_DEFAULT			0		//! save with a 16:1 rate
+#define JPEG_DEFAULT        0		//! loading (see JPEG_FAST); saving (see JPEG_QUALITYGOOD|JPEG_SUBSAMPLING_420)
+#define JPEG_FAST           0x0001	//! load the file as fast as possible, sacrificing some quality
+#define JPEG_ACCURATE       0x0002	//! load the file with the best quality, sacrificing some speed
+#define JPEG_CMYK			0x0004	//! load separated CMYK "as is" (use | to combine with other load flags)
+#define JPEG_EXIFROTATE		0x0008	//! load and rotate according to Exif 'Orientation' tag if available
+#define JPEG_GREYSCALE		0x0010	//! load and convert to a 8-bit greyscale image
+#define JPEG_QUALITYSUPERB  0x80	//! save with superb quality (100:1)
+#define JPEG_QUALITYGOOD    0x0100	//! save with good quality (75:1)
+#define JPEG_QUALITYNORMAL  0x0200	//! save with normal quality (50:1)
+#define JPEG_QUALITYAVERAGE 0x0400	//! save with average quality (25:1)
+#define JPEG_QUALITYBAD     0x0800	//! save with bad quality (10:1)
+#define JPEG_PROGRESSIVE	0x2000	//! save as a progressive-JPEG (use | to combine with other save flags)
+#define JPEG_SUBSAMPLING_411 0x1000		//! save with high 4x1 chroma subsampling (4:1:1) 
+#define JPEG_SUBSAMPLING_420 0x4000		//! save with medium 2x2 medium chroma subsampling (4:2:0) - default value
+#define JPEG_SUBSAMPLING_422 0x8000		//! save with low 2x1 chroma subsampling (4:2:2) 
+#define JPEG_SUBSAMPLING_444 0x10000	//! save with no chroma subsampling (4:4:4)
+#define JPEG_OPTIMIZE		0x20000		//! on saving, compute optimal Huffman coding tables (can reduce a few percent of file size)
+#define JPEG_BASELINE		0x40000		//! save basic JPEG, without metadata or any markers
+#define KOALA_DEFAULT       0
+#define LBM_DEFAULT         0
+#define MNG_DEFAULT         0
+#define PCD_DEFAULT         0
+#define PCD_BASE            1		//! load the bitmap sized 768 x 512
+#define PCD_BASEDIV4        2		//! load the bitmap sized 384 x 256
+#define PCD_BASEDIV16       3		//! load the bitmap sized 192 x 128
+#define PCX_DEFAULT         0
+#define PFM_DEFAULT         0
+#define PICT_DEFAULT        0
+#define PNG_DEFAULT         0
+#define PNG_IGNOREGAMMA		1		//! loading: avoid gamma correction
+#define PNG_Z_BEST_SPEED			0x0001	//! save using ZLib level 1 compression flag (default value is 6)
+#define PNG_Z_DEFAULT_COMPRESSION	0x0006	//! save using ZLib level 6 compression flag (default recommended value)
+#define PNG_Z_BEST_COMPRESSION		0x0009	//! save using ZLib level 9 compression flag (default value is 6)
+#define PNG_Z_NO_COMPRESSION		0x0100	//! save without ZLib compression
+#define PNG_INTERLACED				0x0200	//! save using Adam7 interlacing (use | to combine with other save flags)
+#define PNM_DEFAULT         0
+#define PNM_SAVE_RAW        0       //! if set the writer saves in RAW format (i.e. P4, P5 or P6)
+#define PNM_SAVE_ASCII      1       //! if set the writer saves in ASCII format (i.e. P1, P2 or P3)
+#define PSD_DEFAULT         0
+#define PSD_CMYK			1		//! reads tags for separated CMYK (default is conversion to RGB)
+#define PSD_LAB				2		//! reads tags for CIELab (default is conversion to RGB)
+#define RAS_DEFAULT         0
+#define RAW_DEFAULT         0		//! load the file as linear RGB 48-bit
+#define RAW_PREVIEW			1		//! try to load the embedded JPEG preview with included Exif Data or default to RGB 24-bit
+#define RAW_DISPLAY			2		//! load the file as RGB 24-bit
+#define RAW_HALFSIZE		4		//! output a half-size color image
+#define RAW_UNPROCESSED		8		//! output a FIT_UINT16 raw Bayer image
+#define SGI_DEFAULT			0
+#define TARGA_DEFAULT       0
+#define TARGA_LOAD_RGB888   1       //! if set the loader converts RGB555 and ARGB8888 -> RGB888.
+#define TARGA_SAVE_RLE		2		//! if set, the writer saves with RLE compression
+#define TIFF_DEFAULT        0
+#define TIFF_CMYK			0x0001	//! reads/stores tags for separated CMYK (use | to combine with compression flags)
+#define TIFF_PACKBITS       0x0100  //! save using PACKBITS compression
+#define TIFF_DEFLATE        0x0200  //! save using DEFLATE compression (a.k.a. ZLIB compression)
+#define TIFF_ADOBE_DEFLATE  0x0400  //! save using ADOBE DEFLATE compression
+#define TIFF_NONE           0x0800  //! save without any compression
+#define TIFF_CCITTFAX3		0x1000  //! save using CCITT Group 3 fax encoding
+#define TIFF_CCITTFAX4		0x2000  //! save using CCITT Group 4 fax encoding
+#define TIFF_LZW			0x4000	//! save using LZW compression
+#define TIFF_JPEG			0x8000	//! save using JPEG compression
+#define TIFF_LOGLUV			0x10000	//! save using LogLuv compression
+#define WBMP_DEFAULT        0
+#define XBM_DEFAULT			0
+#define XPM_DEFAULT			0
+#define WEBP_DEFAULT		0		//! save with good quality (75:1)
+#define WEBP_LOSSLESS		0x100	//! save in lossless mode
+#define JXR_DEFAULT			0		//! save with quality 80 and no chroma subsampling (4:4:4)
+#define JXR_LOSSLESS		0x0064	//! save lossless
+#define JXR_PROGRESSIVE		0x2000	//! save as a progressive-JXR (use | to combine with other save flags)
+
+// Background filling options ---------------------------------------------------------
+// Constants used in FreeImage_FillBackground and FreeImage_EnlargeCanvas
+
+#define FI_COLOR_IS_RGB_COLOR			0x00	//! RGBQUAD color is a RGB color (contains no valid alpha channel)
+#define FI_COLOR_IS_RGBA_COLOR			0x01	//! RGBQUAD color is a RGBA color (contains a valid alpha channel)
+#define FI_COLOR_FIND_EQUAL_COLOR		0x02	//! For palettized images: lookup equal RGB color from palette
+#define FI_COLOR_ALPHA_IS_INDEX			0x04	//! The color's rgbReserved member (alpha) contains the palette index to be used
+#define FI_COLOR_PALETTE_SEARCH_MASK	(FI_COLOR_FIND_EQUAL_COLOR | FI_COLOR_ALPHA_IS_INDEX)	// No color lookup is performed
+
+// RescaleEx options ---------------------------------------------------------
+// Constants used in FreeImage_RescaleEx
+
+#define FI_RESCALE_DEFAULT			0x00    //! default options; none of the following other options apply
+#define FI_RESCALE_TRUE_COLOR		0x01	//! for non-transparent greyscale images, convert to 24-bit if src bitdepth <= 8 (default is a 8-bit greyscale image). 
+#define FI_RESCALE_OMIT_METADATA	0x02	//! do not copy metadata to the rescaled image
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Init / Error routines ----------------------------------------------------
+
+DLL_API void DLL_CALLCONV FreeImage_Initialise(BOOL load_local_plugins_only FI_DEFAULT(FALSE));
+DLL_API void DLL_CALLCONV FreeImage_DeInitialise(void);
+
+// Version routines ---------------------------------------------------------
+
+DLL_API const char *DLL_CALLCONV FreeImage_GetVersion(void);
+DLL_API const char *DLL_CALLCONV FreeImage_GetCopyrightMessage(void);
+
+// Message output functions -------------------------------------------------
+
+typedef void (*FreeImage_OutputMessageFunction)(FREE_IMAGE_FORMAT fif, const char *msg);
+typedef void (DLL_CALLCONV *FreeImage_OutputMessageFunctionStdCall)(FREE_IMAGE_FORMAT fif, const char *msg); 
+
+DLL_API void DLL_CALLCONV FreeImage_SetOutputMessageStdCall(FreeImage_OutputMessageFunctionStdCall omf); 
+DLL_API void DLL_CALLCONV FreeImage_SetOutputMessage(FreeImage_OutputMessageFunction omf);
+DLL_API void DLL_CALLCONV FreeImage_OutputMessageProc(int fif, const char *fmt, ...);
+
+// Allocate / Clone / Unload routines ---------------------------------------
+
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Allocate(int width, int height, int bpp, unsigned red_mask FI_DEFAULT(0), unsigned green_mask FI_DEFAULT(0), unsigned blue_mask FI_DEFAULT(0));
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_AllocateT(FREE_IMAGE_TYPE type, int width, int height, int bpp FI_DEFAULT(8), unsigned red_mask FI_DEFAULT(0), unsigned green_mask FI_DEFAULT(0), unsigned blue_mask FI_DEFAULT(0));
+DLL_API FIBITMAP * DLL_CALLCONV FreeImage_Clone(FIBITMAP *dib);
+DLL_API void DLL_CALLCONV FreeImage_Unload(FIBITMAP *dib);
+
+// Header loading routines
+DLL_API BOOL DLL_CALLCONV FreeImage_HasPixels(FIBITMAP *dib);
+
+// Load / Save routines -----------------------------------------------------
+
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Load(FREE_IMAGE_FORMAT fif, const char *filename, int flags FI_DEFAULT(0));
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_LoadU(FREE_IMAGE_FORMAT fif, const wchar_t *filename, int flags FI_DEFAULT(0));
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_LoadFromHandle(FREE_IMAGE_FORMAT fif, FreeImageIO *io, fi_handle handle, int flags FI_DEFAULT(0));
+DLL_API BOOL DLL_CALLCONV FreeImage_Save(FREE_IMAGE_FORMAT fif, FIBITMAP *dib, const char *filename, int flags FI_DEFAULT(0));
+DLL_API BOOL DLL_CALLCONV FreeImage_SaveU(FREE_IMAGE_FORMAT fif, FIBITMAP *dib, const wchar_t *filename, int flags FI_DEFAULT(0));
+DLL_API BOOL DLL_CALLCONV FreeImage_SaveToHandle(FREE_IMAGE_FORMAT fif, FIBITMAP *dib, FreeImageIO *io, fi_handle handle, int flags FI_DEFAULT(0));
+
+// Memory I/O stream routines -----------------------------------------------
+
+DLL_API FIMEMORY *DLL_CALLCONV FreeImage_OpenMemory(BYTE *data FI_DEFAULT(0), DWORD size_in_bytes FI_DEFAULT(0));
+DLL_API void DLL_CALLCONV FreeImage_CloseMemory(FIMEMORY *stream);
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_LoadFromMemory(FREE_IMAGE_FORMAT fif, FIMEMORY *stream, int flags FI_DEFAULT(0));
+DLL_API BOOL DLL_CALLCONV FreeImage_SaveToMemory(FREE_IMAGE_FORMAT fif, FIBITMAP *dib, FIMEMORY *stream, int flags FI_DEFAULT(0));
+DLL_API long DLL_CALLCONV FreeImage_TellMemory(FIMEMORY *stream);
+DLL_API BOOL DLL_CALLCONV FreeImage_SeekMemory(FIMEMORY *stream, long offset, int origin);
+DLL_API BOOL DLL_CALLCONV FreeImage_AcquireMemory(FIMEMORY *stream, BYTE **data, DWORD *size_in_bytes);
+DLL_API unsigned DLL_CALLCONV FreeImage_ReadMemory(void *buffer, unsigned size, unsigned count, FIMEMORY *stream);
+DLL_API unsigned DLL_CALLCONV FreeImage_WriteMemory(const void *buffer, unsigned size, unsigned count, FIMEMORY *stream);
+
+DLL_API FIMULTIBITMAP *DLL_CALLCONV FreeImage_LoadMultiBitmapFromMemory(FREE_IMAGE_FORMAT fif, FIMEMORY *stream, int flags FI_DEFAULT(0));
+DLL_API BOOL DLL_CALLCONV FreeImage_SaveMultiBitmapToMemory(FREE_IMAGE_FORMAT fif, FIMULTIBITMAP *bitmap, FIMEMORY *stream, int flags);
+
+// Plugin Interface ---------------------------------------------------------
+
+DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_RegisterLocalPlugin(FI_InitProc proc_address, const char *format FI_DEFAULT(0), const char *description FI_DEFAULT(0), const char *extension FI_DEFAULT(0), const char *regexpr FI_DEFAULT(0));
+DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_RegisterExternalPlugin(const char *path, const char *format FI_DEFAULT(0), const char *description FI_DEFAULT(0), const char *extension FI_DEFAULT(0), const char *regexpr FI_DEFAULT(0));
+DLL_API int DLL_CALLCONV FreeImage_GetFIFCount(void);
+DLL_API int DLL_CALLCONV FreeImage_SetPluginEnabled(FREE_IMAGE_FORMAT fif, BOOL enable);
+DLL_API int DLL_CALLCONV FreeImage_IsPluginEnabled(FREE_IMAGE_FORMAT fif);
+DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFIFFromFormat(const char *format);
+DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFIFFromMime(const char *mime);
+DLL_API const char *DLL_CALLCONV FreeImage_GetFormatFromFIF(FREE_IMAGE_FORMAT fif);
+DLL_API const char *DLL_CALLCONV FreeImage_GetFIFExtensionList(FREE_IMAGE_FORMAT fif);
+DLL_API const char *DLL_CALLCONV FreeImage_GetFIFDescription(FREE_IMAGE_FORMAT fif);
+DLL_API const char *DLL_CALLCONV FreeImage_GetFIFRegExpr(FREE_IMAGE_FORMAT fif);
+DLL_API const char *DLL_CALLCONV FreeImage_GetFIFMimeType(FREE_IMAGE_FORMAT fif);
+DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFIFFromFilename(const char *filename);
+DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFIFFromFilenameU(const wchar_t *filename);
+DLL_API BOOL DLL_CALLCONV FreeImage_FIFSupportsReading(FREE_IMAGE_FORMAT fif);
+DLL_API BOOL DLL_CALLCONV FreeImage_FIFSupportsWriting(FREE_IMAGE_FORMAT fif);
+DLL_API BOOL DLL_CALLCONV FreeImage_FIFSupportsExportBPP(FREE_IMAGE_FORMAT fif, int bpp);
+DLL_API BOOL DLL_CALLCONV FreeImage_FIFSupportsExportType(FREE_IMAGE_FORMAT fif, FREE_IMAGE_TYPE type);
+DLL_API BOOL DLL_CALLCONV FreeImage_FIFSupportsICCProfiles(FREE_IMAGE_FORMAT fif);
+DLL_API BOOL DLL_CALLCONV FreeImage_FIFSupportsNoPixels(FREE_IMAGE_FORMAT fif);
+
+// Multipaging interface ----------------------------------------------------
+
+DLL_API FIMULTIBITMAP * DLL_CALLCONV FreeImage_OpenMultiBitmap(FREE_IMAGE_FORMAT fif, const char *filename, BOOL create_new, BOOL read_only, BOOL keep_cache_in_memory FI_DEFAULT(FALSE), int flags FI_DEFAULT(0));
+DLL_API FIMULTIBITMAP * DLL_CALLCONV FreeImage_OpenMultiBitmapFromHandle(FREE_IMAGE_FORMAT fif, FreeImageIO *io, fi_handle handle, int flags FI_DEFAULT(0));
+DLL_API BOOL DLL_CALLCONV FreeImage_SaveMultiBitmapToHandle(FREE_IMAGE_FORMAT fif, FIMULTIBITMAP *bitmap, FreeImageIO *io, fi_handle handle, int flags FI_DEFAULT(0));
+DLL_API BOOL DLL_CALLCONV FreeImage_CloseMultiBitmap(FIMULTIBITMAP *bitmap, int flags FI_DEFAULT(0));
+DLL_API int DLL_CALLCONV FreeImage_GetPageCount(FIMULTIBITMAP *bitmap);
+DLL_API void DLL_CALLCONV FreeImage_AppendPage(FIMULTIBITMAP *bitmap, FIBITMAP *data);
+DLL_API void DLL_CALLCONV FreeImage_InsertPage(FIMULTIBITMAP *bitmap, int page, FIBITMAP *data);
+DLL_API void DLL_CALLCONV FreeImage_DeletePage(FIMULTIBITMAP *bitmap, int page);
+DLL_API FIBITMAP * DLL_CALLCONV FreeImage_LockPage(FIMULTIBITMAP *bitmap, int page);
+DLL_API void DLL_CALLCONV FreeImage_UnlockPage(FIMULTIBITMAP *bitmap, FIBITMAP *data, BOOL changed);
+DLL_API BOOL DLL_CALLCONV FreeImage_MovePage(FIMULTIBITMAP *bitmap, int target, int source);
+DLL_API BOOL DLL_CALLCONV FreeImage_GetLockedPageNumbers(FIMULTIBITMAP *bitmap, int *pages, int *count);
+
+// Filetype request routines ------------------------------------------------
+
+DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFileType(const char *filename, int size FI_DEFAULT(0));
+DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFileTypeU(const wchar_t *filename, int size FI_DEFAULT(0));
+DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFileTypeFromHandle(FreeImageIO *io, fi_handle handle, int size FI_DEFAULT(0));
+DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFileTypeFromMemory(FIMEMORY *stream, int size FI_DEFAULT(0));
+
+// Image type request routine -----------------------------------------------
+
+DLL_API FREE_IMAGE_TYPE DLL_CALLCONV FreeImage_GetImageType(FIBITMAP *dib);
+
+// FreeImage helper routines ------------------------------------------------
+
+DLL_API BOOL DLL_CALLCONV FreeImage_IsLittleEndian(void);
+DLL_API BOOL DLL_CALLCONV FreeImage_LookupX11Color(const char *szColor, BYTE *nRed, BYTE *nGreen, BYTE *nBlue);
+DLL_API BOOL DLL_CALLCONV FreeImage_LookupSVGColor(const char *szColor, BYTE *nRed, BYTE *nGreen, BYTE *nBlue);
+
+// Pixel access routines ----------------------------------------------------
+
+DLL_API BYTE *DLL_CALLCONV FreeImage_GetBits(FIBITMAP *dib);
+DLL_API BYTE *DLL_CALLCONV FreeImage_GetScanLine(FIBITMAP *dib, int scanline);
+
+DLL_API BOOL DLL_CALLCONV FreeImage_GetPixelIndex(FIBITMAP *dib, unsigned x, unsigned y, BYTE *value);
+DLL_API BOOL DLL_CALLCONV FreeImage_GetPixelColor(FIBITMAP *dib, unsigned x, unsigned y, RGBQUAD *value);
+DLL_API BOOL DLL_CALLCONV FreeImage_SetPixelIndex(FIBITMAP *dib, unsigned x, unsigned y, BYTE *value);
+DLL_API BOOL DLL_CALLCONV FreeImage_SetPixelColor(FIBITMAP *dib, unsigned x, unsigned y, RGBQUAD *value);
+
+// DIB info routines --------------------------------------------------------
+
+DLL_API unsigned DLL_CALLCONV FreeImage_GetColorsUsed(FIBITMAP *dib);
+DLL_API unsigned DLL_CALLCONV FreeImage_GetBPP(FIBITMAP *dib);
+DLL_API unsigned DLL_CALLCONV FreeImage_GetWidth(FIBITMAP *dib);
+DLL_API unsigned DLL_CALLCONV FreeImage_GetHeight(FIBITMAP *dib);
+DLL_API unsigned DLL_CALLCONV FreeImage_GetLine(FIBITMAP *dib);
+DLL_API unsigned DLL_CALLCONV FreeImage_GetPitch(FIBITMAP *dib);
+DLL_API unsigned DLL_CALLCONV FreeImage_GetDIBSize(FIBITMAP *dib);
+DLL_API unsigned DLL_CALLCONV FreeImage_GetMemorySize(FIBITMAP *dib);
+DLL_API RGBQUAD *DLL_CALLCONV FreeImage_GetPalette(FIBITMAP *dib);
+
+DLL_API unsigned DLL_CALLCONV FreeImage_GetDotsPerMeterX(FIBITMAP *dib);
+DLL_API unsigned DLL_CALLCONV FreeImage_GetDotsPerMeterY(FIBITMAP *dib);
+DLL_API void DLL_CALLCONV FreeImage_SetDotsPerMeterX(FIBITMAP *dib, unsigned res);
+DLL_API void DLL_CALLCONV FreeImage_SetDotsPerMeterY(FIBITMAP *dib, unsigned res);
+
+DLL_API BITMAPINFOHEADER *DLL_CALLCONV FreeImage_GetInfoHeader(FIBITMAP *dib);
+DLL_API BITMAPINFO *DLL_CALLCONV FreeImage_GetInfo(FIBITMAP *dib);
+DLL_API FREE_IMAGE_COLOR_TYPE DLL_CALLCONV FreeImage_GetColorType(FIBITMAP *dib);
+
+DLL_API unsigned DLL_CALLCONV FreeImage_GetRedMask(FIBITMAP *dib);
+DLL_API unsigned DLL_CALLCONV FreeImage_GetGreenMask(FIBITMAP *dib);
+DLL_API unsigned DLL_CALLCONV FreeImage_GetBlueMask(FIBITMAP *dib);
+
+DLL_API unsigned DLL_CALLCONV FreeImage_GetTransparencyCount(FIBITMAP *dib);
+DLL_API BYTE * DLL_CALLCONV FreeImage_GetTransparencyTable(FIBITMAP *dib);
+DLL_API void DLL_CALLCONV FreeImage_SetTransparent(FIBITMAP *dib, BOOL enabled);
+DLL_API void DLL_CALLCONV FreeImage_SetTransparencyTable(FIBITMAP *dib, BYTE *table, int count);
+DLL_API BOOL DLL_CALLCONV FreeImage_IsTransparent(FIBITMAP *dib);
+DLL_API void DLL_CALLCONV FreeImage_SetTransparentIndex(FIBITMAP *dib, int index);
+DLL_API int DLL_CALLCONV FreeImage_GetTransparentIndex(FIBITMAP *dib);
+
+DLL_API BOOL DLL_CALLCONV FreeImage_HasBackgroundColor(FIBITMAP *dib);
+DLL_API BOOL DLL_CALLCONV FreeImage_GetBackgroundColor(FIBITMAP *dib, RGBQUAD *bkcolor);
+DLL_API BOOL DLL_CALLCONV FreeImage_SetBackgroundColor(FIBITMAP *dib, RGBQUAD *bkcolor);
+
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_GetThumbnail(FIBITMAP *dib);
+DLL_API BOOL DLL_CALLCONV FreeImage_SetThumbnail(FIBITMAP *dib, FIBITMAP *thumbnail);
+
+// ICC profile routines -----------------------------------------------------
+
+DLL_API FIICCPROFILE *DLL_CALLCONV FreeImage_GetICCProfile(FIBITMAP *dib);
+DLL_API FIICCPROFILE *DLL_CALLCONV FreeImage_CreateICCProfile(FIBITMAP *dib, void *data, long size);
+DLL_API void DLL_CALLCONV FreeImage_DestroyICCProfile(FIBITMAP *dib);
+
+// Line conversion routines -------------------------------------------------
+
+DLL_API void DLL_CALLCONV FreeImage_ConvertLine1To4(BYTE *target, BYTE *source, int width_in_pixels);
+DLL_API void DLL_CALLCONV FreeImage_ConvertLine8To4(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette);
+DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To4_555(BYTE *target, BYTE *source, int width_in_pixels);
+DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To4_565(BYTE *target, BYTE *source, int width_in_pixels);
+DLL_API void DLL_CALLCONV FreeImage_ConvertLine24To4(BYTE *target, BYTE *source, int width_in_pixels);
+DLL_API void DLL_CALLCONV FreeImage_ConvertLine32To4(BYTE *target, BYTE *source, int width_in_pixels);
+DLL_API void DLL_CALLCONV FreeImage_ConvertLine1To8(BYTE *target, BYTE *source, int width_in_pixels);
+DLL_API void DLL_CALLCONV FreeImage_ConvertLine4To8(BYTE *target, BYTE *source, int width_in_pixels);
+DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To8_555(BYTE *target, BYTE *source, int width_in_pixels);
+DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To8_565(BYTE *target, BYTE *source, int width_in_pixels);
+DLL_API void DLL_CALLCONV FreeImage_ConvertLine24To8(BYTE *target, BYTE *source, int width_in_pixels);
+DLL_API void DLL_CALLCONV FreeImage_ConvertLine32To8(BYTE *target, BYTE *source, int width_in_pixels);
+DLL_API void DLL_CALLCONV FreeImage_ConvertLine1To16_555(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette);
+DLL_API void DLL_CALLCONV FreeImage_ConvertLine4To16_555(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette);
+DLL_API void DLL_CALLCONV FreeImage_ConvertLine8To16_555(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette);
+DLL_API void DLL_CALLCONV FreeImage_ConvertLine16_565_To16_555(BYTE *target, BYTE *source, int width_in_pixels);
+DLL_API void DLL_CALLCONV FreeImage_ConvertLine24To16_555(BYTE *target, BYTE *source, int width_in_pixels);
+DLL_API void DLL_CALLCONV FreeImage_ConvertLine32To16_555(BYTE *target, BYTE *source, int width_in_pixels);
+DLL_API void DLL_CALLCONV FreeImage_ConvertLine1To16_565(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette);
+DLL_API void DLL_CALLCONV FreeImage_ConvertLine4To16_565(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette);
+DLL_API void DLL_CALLCONV FreeImage_ConvertLine8To16_565(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette);
+DLL_API void DLL_CALLCONV FreeImage_ConvertLine16_555_To16_565(BYTE *target, BYTE *source, int width_in_pixels);
+DLL_API void DLL_CALLCONV FreeImage_ConvertLine24To16_565(BYTE *target, BYTE *source, int width_in_pixels);
+DLL_API void DLL_CALLCONV FreeImage_ConvertLine32To16_565(BYTE *target, BYTE *source, int width_in_pixels);
+DLL_API void DLL_CALLCONV FreeImage_ConvertLine1To24(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette);
+DLL_API void DLL_CALLCONV FreeImage_ConvertLine4To24(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette);
+DLL_API void DLL_CALLCONV FreeImage_ConvertLine8To24(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette);
+DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To24_555(BYTE *target, BYTE *source, int width_in_pixels);
+DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To24_565(BYTE *target, BYTE *source, int width_in_pixels);
+DLL_API void DLL_CALLCONV FreeImage_ConvertLine32To24(BYTE *target, BYTE *source, int width_in_pixels);
+DLL_API void DLL_CALLCONV FreeImage_ConvertLine1To32(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette);
+DLL_API void DLL_CALLCONV FreeImage_ConvertLine4To32(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette);
+DLL_API void DLL_CALLCONV FreeImage_ConvertLine8To32(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette);
+DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To32_555(BYTE *target, BYTE *source, int width_in_pixels);
+DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To32_565(BYTE *target, BYTE *source, int width_in_pixels);
+DLL_API void DLL_CALLCONV FreeImage_ConvertLine24To32(BYTE *target, BYTE *source, int width_in_pixels);
+
+// Smart conversion routines ------------------------------------------------
+
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertTo4Bits(FIBITMAP *dib);
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertTo8Bits(FIBITMAP *dib);
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToGreyscale(FIBITMAP *dib);
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertTo16Bits555(FIBITMAP *dib);
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertTo16Bits565(FIBITMAP *dib);
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertTo24Bits(FIBITMAP *dib);
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertTo32Bits(FIBITMAP *dib);
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ColorQuantize(FIBITMAP *dib, FREE_IMAGE_QUANTIZE quantize);
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ColorQuantizeEx(FIBITMAP *dib, FREE_IMAGE_QUANTIZE quantize FI_DEFAULT(FIQ_WUQUANT), int PaletteSize FI_DEFAULT(256), int ReserveSize FI_DEFAULT(0), RGBQUAD *ReservePalette FI_DEFAULT(NULL));
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Threshold(FIBITMAP *dib, BYTE T);
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Dither(FIBITMAP *dib, FREE_IMAGE_DITHER algorithm);
+
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertFromRawBits(BYTE *bits, int width, int height, int pitch, unsigned bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask, BOOL topdown FI_DEFAULT(FALSE));
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertFromRawBitsEx(BOOL copySource, BYTE *bits, FREE_IMAGE_TYPE type, int width, int height, int pitch, unsigned bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask, BOOL topdown FI_DEFAULT(FALSE));
+DLL_API void DLL_CALLCONV FreeImage_ConvertToRawBits(BYTE *bits, FIBITMAP *dib, int pitch, unsigned bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask, BOOL topdown FI_DEFAULT(FALSE));
+
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToFloat(FIBITMAP *dib);
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToRGBF(FIBITMAP *dib);
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToRGBAF(FIBITMAP *dib);
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToUINT16(FIBITMAP *dib);
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToRGB16(FIBITMAP *dib);
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToRGBA16(FIBITMAP *dib);
+
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToStandardType(FIBITMAP *src, BOOL scale_linear FI_DEFAULT(TRUE));
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToType(FIBITMAP *src, FREE_IMAGE_TYPE dst_type, BOOL scale_linear FI_DEFAULT(TRUE));
+
+// Tone mapping operators ---------------------------------------------------
+
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ToneMapping(FIBITMAP *dib, FREE_IMAGE_TMO tmo, double first_param FI_DEFAULT(0), double second_param FI_DEFAULT(0));
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_TmoDrago03(FIBITMAP *src, double gamma FI_DEFAULT(2.2), double exposure FI_DEFAULT(0));
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_TmoReinhard05(FIBITMAP *src, double intensity FI_DEFAULT(0), double contrast FI_DEFAULT(0));
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_TmoReinhard05Ex(FIBITMAP *src, double intensity FI_DEFAULT(0), double contrast FI_DEFAULT(0), double adaptation FI_DEFAULT(1), double color_correction FI_DEFAULT(0));
+
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_TmoFattal02(FIBITMAP *src, double color_saturation FI_DEFAULT(0.5), double attenuation FI_DEFAULT(0.85));
+
+// ZLib interface -----------------------------------------------------------
+
+DLL_API DWORD DLL_CALLCONV FreeImage_ZLibCompress(BYTE *target, DWORD target_size, BYTE *source, DWORD source_size);
+DLL_API DWORD DLL_CALLCONV FreeImage_ZLibUncompress(BYTE *target, DWORD target_size, BYTE *source, DWORD source_size);
+DLL_API DWORD DLL_CALLCONV FreeImage_ZLibGZip(BYTE *target, DWORD target_size, BYTE *source, DWORD source_size);
+DLL_API DWORD DLL_CALLCONV FreeImage_ZLibGUnzip(BYTE *target, DWORD target_size, BYTE *source, DWORD source_size);
+DLL_API DWORD DLL_CALLCONV FreeImage_ZLibCRC32(DWORD crc, BYTE *source, DWORD source_size);
+
+// --------------------------------------------------------------------------
+// Metadata routines
+// --------------------------------------------------------------------------
+
+// tag creation / destruction
+DLL_API FITAG *DLL_CALLCONV FreeImage_CreateTag(void);
+DLL_API void DLL_CALLCONV FreeImage_DeleteTag(FITAG *tag);
+DLL_API FITAG *DLL_CALLCONV FreeImage_CloneTag(FITAG *tag);
+
+// tag getters and setters
+DLL_API const char *DLL_CALLCONV FreeImage_GetTagKey(FITAG *tag);
+DLL_API const char *DLL_CALLCONV FreeImage_GetTagDescription(FITAG *tag);
+DLL_API WORD DLL_CALLCONV FreeImage_GetTagID(FITAG *tag);
+DLL_API FREE_IMAGE_MDTYPE DLL_CALLCONV FreeImage_GetTagType(FITAG *tag);
+DLL_API DWORD DLL_CALLCONV FreeImage_GetTagCount(FITAG *tag);
+DLL_API DWORD DLL_CALLCONV FreeImage_GetTagLength(FITAG *tag);
+DLL_API const void *DLL_CALLCONV FreeImage_GetTagValue(FITAG *tag);
+
+DLL_API BOOL DLL_CALLCONV FreeImage_SetTagKey(FITAG *tag, const char *key);
+DLL_API BOOL DLL_CALLCONV FreeImage_SetTagDescription(FITAG *tag, const char *description);
+DLL_API BOOL DLL_CALLCONV FreeImage_SetTagID(FITAG *tag, WORD id);
+DLL_API BOOL DLL_CALLCONV FreeImage_SetTagType(FITAG *tag, FREE_IMAGE_MDTYPE type);
+DLL_API BOOL DLL_CALLCONV FreeImage_SetTagCount(FITAG *tag, DWORD count);
+DLL_API BOOL DLL_CALLCONV FreeImage_SetTagLength(FITAG *tag, DWORD length);
+DLL_API BOOL DLL_CALLCONV FreeImage_SetTagValue(FITAG *tag, const void *value);
+
+// iterator
+DLL_API FIMETADATA *DLL_CALLCONV FreeImage_FindFirstMetadata(FREE_IMAGE_MDMODEL model, FIBITMAP *dib, FITAG **tag);
+DLL_API BOOL DLL_CALLCONV FreeImage_FindNextMetadata(FIMETADATA *mdhandle, FITAG **tag);
+DLL_API void DLL_CALLCONV FreeImage_FindCloseMetadata(FIMETADATA *mdhandle);
+
+// metadata setter and getter
+DLL_API BOOL DLL_CALLCONV FreeImage_SetMetadata(FREE_IMAGE_MDMODEL model, FIBITMAP *dib, const char *key, FITAG *tag);
+DLL_API BOOL DLL_CALLCONV FreeImage_GetMetadata(FREE_IMAGE_MDMODEL model, FIBITMAP *dib, const char *key, FITAG **tag);
+DLL_API BOOL DLL_CALLCONV FreeImage_SetMetadataKeyValue(FREE_IMAGE_MDMODEL model, FIBITMAP *dib, const char *key, const char *value);
+
+// helpers
+DLL_API unsigned DLL_CALLCONV FreeImage_GetMetadataCount(FREE_IMAGE_MDMODEL model, FIBITMAP *dib);
+DLL_API BOOL DLL_CALLCONV FreeImage_CloneMetadata(FIBITMAP *dst, FIBITMAP *src);
+
+// tag to C string conversion
+DLL_API const char* DLL_CALLCONV FreeImage_TagToString(FREE_IMAGE_MDMODEL model, FITAG *tag, char *Make FI_DEFAULT(NULL));
+
+// --------------------------------------------------------------------------
+// JPEG lossless transformation routines
+// --------------------------------------------------------------------------
+
+DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransform(const char *src_file, const char *dst_file, FREE_IMAGE_JPEG_OPERATION operation, BOOL perfect FI_DEFAULT(TRUE));
+DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransformU(const wchar_t *src_file, const wchar_t *dst_file, FREE_IMAGE_JPEG_OPERATION operation, BOOL perfect FI_DEFAULT(TRUE));
+DLL_API BOOL DLL_CALLCONV FreeImage_JPEGCrop(const char *src_file, const char *dst_file, int left, int top, int right, int bottom);
+DLL_API BOOL DLL_CALLCONV FreeImage_JPEGCropU(const wchar_t *src_file, const wchar_t *dst_file, int left, int top, int right, int bottom);
+DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransformFromHandle(FreeImageIO* src_io, fi_handle src_handle, FreeImageIO* dst_io, fi_handle dst_handle, FREE_IMAGE_JPEG_OPERATION operation, int* left, int* top, int* right, int* bottom, BOOL perfect FI_DEFAULT(TRUE));
+DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransformCombined(const char *src_file, const char *dst_file, FREE_IMAGE_JPEG_OPERATION operation, int* left, int* top, int* right, int* bottom, BOOL perfect FI_DEFAULT(TRUE));
+DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransformCombinedU(const wchar_t *src_file, const wchar_t *dst_file, FREE_IMAGE_JPEG_OPERATION operation, int* left, int* top, int* right, int* bottom, BOOL perfect FI_DEFAULT(TRUE));
+DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransformCombinedFromMemory(FIMEMORY* src_stream, FIMEMORY* dst_stream, FREE_IMAGE_JPEG_OPERATION operation, int* left, int* top, int* right, int* bottom, BOOL perfect FI_DEFAULT(TRUE));
+
+
+// --------------------------------------------------------------------------
+// Image manipulation toolkit
+// --------------------------------------------------------------------------
+
+// rotation and flipping
+/// @deprecated see FreeImage_Rotate
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_RotateClassic(FIBITMAP *dib, double angle);
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Rotate(FIBITMAP *dib, double angle, const void *bkcolor FI_DEFAULT(NULL));
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_RotateEx(FIBITMAP *dib, double angle, double x_shift, double y_shift, double x_origin, double y_origin, BOOL use_mask);
+DLL_API BOOL DLL_CALLCONV FreeImage_FlipHorizontal(FIBITMAP *dib);
+DLL_API BOOL DLL_CALLCONV FreeImage_FlipVertical(FIBITMAP *dib);
+
+// upsampling / downsampling
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Rescale(FIBITMAP *dib, int dst_width, int dst_height, FREE_IMAGE_FILTER filter FI_DEFAULT(FILTER_CATMULLROM));
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_MakeThumbnail(FIBITMAP *dib, int max_pixel_size, BOOL convert FI_DEFAULT(TRUE));
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_RescaleRect(FIBITMAP *dib, int dst_width, int dst_height, int left, int top, int right, int bottom, FREE_IMAGE_FILTER filter FI_DEFAULT(FILTER_CATMULLROM), unsigned flags FI_DEFAULT(0));
+
+// color manipulation routines (point operations)
+DLL_API BOOL DLL_CALLCONV FreeImage_AdjustCurve(FIBITMAP *dib, BYTE *LUT, FREE_IMAGE_COLOR_CHANNEL channel);
+DLL_API BOOL DLL_CALLCONV FreeImage_AdjustGamma(FIBITMAP *dib, double gamma);
+DLL_API BOOL DLL_CALLCONV FreeImage_AdjustBrightness(FIBITMAP *dib, double percentage);
+DLL_API BOOL DLL_CALLCONV FreeImage_AdjustContrast(FIBITMAP *dib, double percentage);
+DLL_API BOOL DLL_CALLCONV FreeImage_Invert(FIBITMAP *dib);
+DLL_API BOOL DLL_CALLCONV FreeImage_GetHistogram(FIBITMAP *dib, DWORD *histo, FREE_IMAGE_COLOR_CHANNEL channel FI_DEFAULT(FICC_BLACK));
+DLL_API int DLL_CALLCONV FreeImage_GetAdjustColorsLookupTable(BYTE *LUT, double brightness, double contrast, double gamma, BOOL invert);
+DLL_API BOOL DLL_CALLCONV FreeImage_AdjustColors(FIBITMAP *dib, double brightness, double contrast, double gamma, BOOL invert FI_DEFAULT(FALSE));
+DLL_API unsigned DLL_CALLCONV FreeImage_ApplyColorMapping(FIBITMAP *dib, RGBQUAD *srccolors, RGBQUAD *dstcolors, unsigned count, BOOL ignore_alpha, BOOL swap);
+DLL_API unsigned DLL_CALLCONV FreeImage_SwapColors(FIBITMAP *dib, RGBQUAD *color_a, RGBQUAD *color_b, BOOL ignore_alpha);
+DLL_API unsigned DLL_CALLCONV FreeImage_ApplyPaletteIndexMapping(FIBITMAP *dib, BYTE *srcindices,	BYTE *dstindices, unsigned count, BOOL swap);
+DLL_API unsigned DLL_CALLCONV FreeImage_SwapPaletteIndices(FIBITMAP *dib, BYTE *index_a, BYTE *index_b);
+
+// channel processing routines
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_GetChannel(FIBITMAP *dib, FREE_IMAGE_COLOR_CHANNEL channel);
+DLL_API BOOL DLL_CALLCONV FreeImage_SetChannel(FIBITMAP *dst, FIBITMAP *src, FREE_IMAGE_COLOR_CHANNEL channel);
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_GetComplexChannel(FIBITMAP *src, FREE_IMAGE_COLOR_CHANNEL channel);
+DLL_API BOOL DLL_CALLCONV FreeImage_SetComplexChannel(FIBITMAP *dst, FIBITMAP *src, FREE_IMAGE_COLOR_CHANNEL channel);
+
+// copy / paste / composite routines
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Copy(FIBITMAP *dib, int left, int top, int right, int bottom);
+DLL_API BOOL DLL_CALLCONV FreeImage_Paste(FIBITMAP *dst, FIBITMAP *src, int left, int top, int alpha);
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_CreateView(FIBITMAP *dib, unsigned left, unsigned top, unsigned right, unsigned bottom);
+
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Composite(FIBITMAP *fg, BOOL useFileBkg FI_DEFAULT(FALSE), RGBQUAD *appBkColor FI_DEFAULT(NULL), FIBITMAP *bg FI_DEFAULT(NULL));
+DLL_API BOOL DLL_CALLCONV FreeImage_PreMultiplyWithAlpha(FIBITMAP *dib);
+
+// background filling routines
+DLL_API BOOL DLL_CALLCONV FreeImage_FillBackground(FIBITMAP *dib, const void *color, int options FI_DEFAULT(0));
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_EnlargeCanvas(FIBITMAP *src, int left, int top, int right, int bottom, const void *color, int options FI_DEFAULT(0));
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_AllocateEx(int width, int height, int bpp, const RGBQUAD *color, int options FI_DEFAULT(0), const RGBQUAD *palette FI_DEFAULT(NULL), unsigned red_mask FI_DEFAULT(0), unsigned green_mask FI_DEFAULT(0), unsigned blue_mask FI_DEFAULT(0));
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_AllocateExT(FREE_IMAGE_TYPE type, int width, int height, int bpp, const void *color, int options FI_DEFAULT(0), const RGBQUAD *palette FI_DEFAULT(NULL), unsigned red_mask FI_DEFAULT(0), unsigned green_mask FI_DEFAULT(0), unsigned blue_mask FI_DEFAULT(0));
+
+// miscellaneous algorithms
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_MultigridPoissonSolver(FIBITMAP *Laplacian, int ncycle FI_DEFAULT(3));
+
+// restore the borland-specific enum size option
+#if defined(__BORLANDC__)
+#pragma option pop
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // FREEIMAGE_H
diff --git a/Source/FreeImage/BitmapAccess.cpp b/Source/FreeImage/BitmapAccess.cpp
index 5b90ed8..347ad1f 100644
--- a/Source/FreeImage/BitmapAccess.cpp
+++ b/Source/FreeImage/BitmapAccess.cpp
@@ -1,1269 +1,1573 @@
-// ==========================================================
-// FreeImage implementation
-//
-// Design and implementation by
-// - Floris van den Berg (flvdberg at wxs.nl)
-// - Herv� Drolon (drolon at infonie.fr)
-// - Detlev Vendt (detlev.vendt at brillit.de)
-// - Petr Supina (psup at centrum.cz)
-// - Carsten Klein (c.klein at datagis.com)
-// - Mihail Naydenov (mnaydenov at users.sourceforge.net)
-//
-// This file is part of FreeImage 3
-//
-// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
-// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
-// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
-// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
-// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
-// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
-// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
-// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
-// THIS DISCLAIMER.
-//
-// Use at your own risk!
-// ==========================================================
-
-#ifdef _MSC_VER 
-#pragma warning (disable : 4786) // identifier was truncated to 'number' characters
-#endif 
-
-#include <stdlib.h>
-#if defined(_WIN32) || defined(_WIN64) || defined(__MINGW32__)
-#include <malloc.h>
-#endif // _WIN32 || _WIN64 || __MINGW32__
-
-#include "FreeImage.h"
-#include "FreeImageIO.h"
-#include "Utilities.h"
-
-#include "../Metadata/FreeImageTag.h"
-
-/** Constants for the BITMAPINFOHEADER::biCompression field */
-#ifndef _WINGDI_
-#define BI_RGB       0L
-#define BI_BITFIELDS 3L
-#endif // _WINGDI_
-
-// ----------------------------------------------------------
-//  Metadata definitions
-// ----------------------------------------------------------
-
-// helper for map<key, value> where value is a pointer to a FreeImage tag
-typedef std::map<std::string, FITAG*> TAGMAP;
-
-// helper for map<FREE_IMAGE_MDMODEL, TAGMAP*>
-typedef std::map<int, TAGMAP*> METADATAMAP;
-
-// helper for metadata iterator
-FI_STRUCT (METADATAHEADER) { 
-	long pos;		// current position when iterating the map
-	TAGMAP *tagmap;	// pointer to the tag map
-};
-
-// ----------------------------------------------------------
-//  FIBITMAP definition
-// ----------------------------------------------------------
-
-FI_STRUCT (FREEIMAGEHEADER) {
-	FREE_IMAGE_TYPE type;		// data type - bitmap, array of long, double, complex, etc
-
-	RGBQUAD bkgnd_color;		// background color used for RGB transparency
-
-	BOOL transparent;			// why another table? for easy transparency table retrieval!
-	int  transparency_count;	// transparency could be stored in the palette, which is better
-	BYTE transparent_table[256];// overall, but it requires quite some changes and it will render
-								// FreeImage_GetTransparencyTable obsolete in its current form;
-	FIICCPROFILE iccProfile;	// space to hold ICC profile
-
-	METADATAMAP *metadata;		// contains a list of metadata models attached to the bitmap
-
-	BOOL has_pixels;			// FALSE if the FIBITMAP only contains the header and no pixel data
-
-	FIBITMAP *thumbnail;		// optionally contains a thumbnail attached to the bitmap
-
-	//BYTE filler[1];			 // fill to 32-bit alignment
-};
-
-// ----------------------------------------------------------
-//  FREEIMAGERGBMASKS definition
-// ----------------------------------------------------------
-
-FI_STRUCT (FREEIMAGERGBMASKS) {
-	unsigned red_mask;			// bit layout of the red components
-	unsigned green_mask;		// bit layout of the green components
-	unsigned blue_mask;			// bit layout of the blue components
-};
-
-// ----------------------------------------------------------
-//  Memory allocation on a specified alignment boundary
-// ----------------------------------------------------------
-
-#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
-
-void* FreeImage_Aligned_Malloc(size_t amount, size_t alignment) {
-	assert(alignment == FIBITMAP_ALIGNMENT);
-	return _aligned_malloc(amount, alignment);
-}
-
-void FreeImage_Aligned_Free(void* mem) {
-	_aligned_free(mem);
-}
-
-#elif defined (__MINGW32__)
-
-void* FreeImage_Aligned_Malloc(size_t amount, size_t alignment) {
-	assert(alignment == FIBITMAP_ALIGNMENT);
-	return __mingw_aligned_malloc (amount, alignment);
-}
-
-void FreeImage_Aligned_Free(void* mem) {
-	__mingw_aligned_free (mem);
-}
-
-#else
-
-void* FreeImage_Aligned_Malloc(size_t amount, size_t alignment) {
-	assert(alignment == FIBITMAP_ALIGNMENT);
-	/*
-	In some rare situations, the malloc routines can return misaligned memory. 
-	The routine FreeImage_Aligned_Malloc allocates a bit more memory to do
-	aligned writes.  Normally, it *should* allocate "alignment" extra memory and then writes
-	one dword back the true pointer.  But if the memory manager returns a
-	misaligned block that is less than a dword from the next alignment, 
-	then the writing back one dword will corrupt memory.
-
-	For example, suppose that alignment is 16 and malloc returns the address 0xFFFF.
-
-	16 - 0xFFFF % 16 + 0xFFFF = 16 - 15 + 0xFFFF = 0x10000.
-
-	Now, you subtract one dword from that and write and that will corrupt memory.
-
-	That's why the code below allocates *two* alignments instead of one. 
-	*/
-	void* mem_real = malloc(amount + 2 * alignment);
-	if(!mem_real) return NULL;
-	char* mem_align = (char*)((unsigned long)(2 * alignment - (unsigned long)mem_real % (unsigned long)alignment) + (unsigned long)mem_real);
-	*((long*)mem_align - 1) = (long)mem_real;
-	return mem_align;
-}
-
-void FreeImage_Aligned_Free(void* mem) {
-	free((void*)*((long*)mem - 1));
-}
-
-#endif // _WIN32 || _WIN64
-
-// ----------------------------------------------------------
-//  DIB information functions
-// ----------------------------------------------------------
-
-/**
-Calculate the size of a FreeImage image. 
-Align the palette and the pixels on a FIBITMAP_ALIGNMENT bytes alignment boundary.
-
- at param header_only If TRUE, calculate a 'header only' FIBITMAP size, otherwise calculate a full FIBITMAP size
- at param width
- at param height
- at param bpp
- at param need_masks
- at see FreeImage_AllocateHeaderT
-*/
-static size_t 
-FreeImage_GetImageSizeHeader(BOOL header_only, unsigned width, unsigned height, unsigned bpp, BOOL need_masks) {
-	size_t dib_size = sizeof(FREEIMAGEHEADER); 
-	dib_size += (dib_size % FIBITMAP_ALIGNMENT ? FIBITMAP_ALIGNMENT - dib_size % FIBITMAP_ALIGNMENT : 0);  
-	dib_size += FIBITMAP_ALIGNMENT - sizeof(BITMAPINFOHEADER) % FIBITMAP_ALIGNMENT; 
-	dib_size += sizeof(BITMAPINFOHEADER);  
-	// palette is aligned on a 16 bytes boundary
-	dib_size += sizeof(RGBQUAD) * CalculateUsedPaletteEntries(bpp);
-	// we both add palette size and masks size if need_masks is true, since CalculateUsedPaletteEntries
-	// always returns 0 if need_masks is true (which is only true for 16 bit images).
-	dib_size += need_masks ? sizeof(DWORD) * 3 : 0;
-	dib_size += (dib_size % FIBITMAP_ALIGNMENT ? FIBITMAP_ALIGNMENT - dib_size % FIBITMAP_ALIGNMENT : 0);  
-	if(!header_only) {
-		const size_t header_size = dib_size;
-
-		// pixels are aligned on a 16 bytes boundary
-		dib_size += (size_t)CalculatePitch(CalculateLine(width, bpp)) * (size_t)height; 
-
-		// check for possible malloc overflow using a KISS integer overflow detection mechanism
-		{
-			/*
-			The following constant take into account the additionnal memory used by 
-			aligned malloc functions as well as debug malloc functions. 
-			It is supposed here that using a (8 * FIBITMAP_ALIGNMENT) risk margin will be enough
-			for the target compiler. 
-			*/
-			const double FIBITMAP_MAX_MEMORY = (double)((size_t)-1) - 8 * FIBITMAP_ALIGNMENT;
-			const double dPitch = floor( ((double)bpp * width + 31.0) / 32.0 ) * 4.0;
-			const double dImageSize = (double)header_size + dPitch * height;
-			if(dImageSize != (double)dib_size) {
-				// here, we are sure to encounter a malloc overflow: try to avoid it ...
-				return 0;
-			}
-			if(dImageSize > FIBITMAP_MAX_MEMORY) {
-				// avoid possible overflow inside C allocation functions
-				return 0;
-			}
-		}
-	}
-
-	return dib_size;
-}
-
-/**
+// ==========================================================
+// FreeImage implementation
+//
+// Design and implementation by
+// - Floris van den Berg (flvdberg at wxs.nl)
+// - Herv� Drolon (drolon at infonie.fr)
+// - Detlev Vendt (detlev.vendt at brillit.de)
+// - Petr Supina (psup at centrum.cz)
+// - Carsten Klein (c.klein at datagis.com)
+// - Mihail Naydenov (mnaydenov at users.sourceforge.net)
+//
+// This file is part of FreeImage 3
+//
+// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
+// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
+// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
+// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
+// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
+// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
+// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+// THIS DISCLAIMER.
+//
+// Use at your own risk!
+// ==========================================================
+
+#ifdef _MSC_VER 
+#pragma warning (disable : 4786) // identifier was truncated to 'number' characters
+#endif 
+
+#include <stdlib.h>
+#if defined(_WIN32) || defined(_WIN64) || defined(__MINGW32__)
+#include <malloc.h>
+#endif // _WIN32 || _WIN64 || __MINGW32__
+
+#include "FreeImage.h"
+#include "FreeImageIO.h"
+#include "Utilities.h"
+#include "MapIntrospector.h"
+
+#include "../Metadata/FreeImageTag.h"
+
+/**
+Constants for the BITMAPINFOHEADER::biCompression field
+BI_RGB:
+The bitmap is in uncompressed red green blue (RGB) format that is not compressed and does not use color masks.
+BI_BITFIELDS:
+The bitmap is not compressed and the color table consists of three DWORD color masks that specify the red, green, and blue components, 
+respectively, of each pixel. This is valid when used with 16 and 32-bits per pixel bitmaps.
+*/
+#ifndef _WINGDI_
+#define BI_RGB       0L
+#define BI_BITFIELDS 3L
+#endif // _WINGDI_
+
+// ----------------------------------------------------------
+//  Metadata definitions
+// ----------------------------------------------------------
+
+/** helper for map<key, value> where value is a pointer to a FreeImage tag */
+typedef std::map<std::string, FITAG*> TAGMAP;
+
+/** helper for map<FREE_IMAGE_MDMODEL, TAGMAP*> */
+typedef std::map<int, TAGMAP*> METADATAMAP;
+
+/** helper for metadata iterator */
+FI_STRUCT (METADATAHEADER) { 
+	long pos;		//! current position when iterating the map
+	TAGMAP *tagmap;	//! pointer to the tag map
+};
+
+// ----------------------------------------------------------
+//  FIBITMAP definition
+// ----------------------------------------------------------
+
+/**
+FreeImage header structure
+*/
+FI_STRUCT (FREEIMAGEHEADER) {
+	/** data type - bitmap, array of long, double, complex, etc */
+	FREE_IMAGE_TYPE type;
+
+	/** background color used for RGB transparency */
+	RGBQUAD bkgnd_color;
+
+	/**@name transparency management */
+	//@{
+	/**
+	why another table ? for easy transparency table retrieval !
+	transparency could be stored in the palette, which is better
+	overall, but it requires quite some changes and it will render
+	FreeImage_GetTransparencyTable obsolete in its current form;
+	*/
+	BYTE transparent_table[256];
+	/** number of transparent colors */
+	int  transparency_count;
+	/** TRUE if the image is transparent */
+	BOOL transparent;
+	//@}
+
+	/** space to hold ICC profile */
+	FIICCPROFILE iccProfile;
+
+	/** contains a list of metadata models attached to the bitmap */
+	METADATAMAP *metadata;
+
+	/** FALSE if the FIBITMAP only contains the header and no pixel data */
+	BOOL has_pixels;
+
+	/** optionally contains a thumbnail attached to the bitmap */
+	FIBITMAP *thumbnail;
+
+	/**@name external pixel buffer management */
+	//@{
+	/** pointer to user provided pixels, NULL otherwise */
+	BYTE *external_bits;
+	/** user provided pitch, 0 otherwise */
+	unsigned external_pitch;
+	//@}
+
+	//BYTE filler[1];			 // fill to 32-bit alignment
+};
+
+// ----------------------------------------------------------
+//  FREEIMAGERGBMASKS definition
+// ----------------------------------------------------------
+
+/**
+RGB mask structure - mainly used for 16-bit RGB555 / RGB 565 FIBITMAP
+*/
+FI_STRUCT (FREEIMAGERGBMASKS) {
+	unsigned red_mask;		//! bit layout of the red components
+	unsigned green_mask;	//! bit layout of the green components
+	unsigned blue_mask;		//! bit layout of the blue components
+};
+
+// ----------------------------------------------------------
+//  Memory allocation on a specified alignment boundary
+// ----------------------------------------------------------
+
+#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
+
+void* FreeImage_Aligned_Malloc(size_t amount, size_t alignment) {
+	assert(alignment == FIBITMAP_ALIGNMENT);
+	return _aligned_malloc(amount, alignment);
+}
+
+void FreeImage_Aligned_Free(void* mem) {
+	_aligned_free(mem);
+}
+
+#elif defined (__MINGW32__)
+
+void* FreeImage_Aligned_Malloc(size_t amount, size_t alignment) {
+	assert(alignment == FIBITMAP_ALIGNMENT);
+	return __mingw_aligned_malloc (amount, alignment);
+}
+
+void FreeImage_Aligned_Free(void* mem) {
+	__mingw_aligned_free (mem);
+}
+
+#else
+
+void* FreeImage_Aligned_Malloc(size_t amount, size_t alignment) {
+	assert(alignment == FIBITMAP_ALIGNMENT);
+	/*
+	In some rare situations, the malloc routines can return misaligned memory. 
+	The routine FreeImage_Aligned_Malloc allocates a bit more memory to do
+	aligned writes.  Normally, it *should* allocate "alignment" extra memory and then writes
+	one dword back the true pointer.  But if the memory manager returns a
+	misaligned block that is less than a dword from the next alignment, 
+	then the writing back one dword will corrupt memory.
+
+	For example, suppose that alignment is 16 and malloc returns the address 0xFFFF.
+
+	16 - 0xFFFF % 16 + 0xFFFF = 16 - 15 + 0xFFFF = 0x10000.
+
+	Now, you subtract one dword from that and write and that will corrupt memory.
+
+	That's why the code below allocates *two* alignments instead of one. 
+	*/
+	void* mem_real = malloc(amount + 2 * alignment);
+	if(!mem_real) return NULL;
+	char* mem_align = (char*)((unsigned long)(2 * alignment - (unsigned long)mem_real % (unsigned long)alignment) + (unsigned long)mem_real);
+	*((long*)mem_align - 1) = (long)mem_real;
+	return mem_align;
+}
+
+void FreeImage_Aligned_Free(void* mem) {
+	free((void*)*((long*)mem - 1));
+}
+
+#endif // _WIN32 || _WIN64
+
+// ----------------------------------------------------------
+//  FIBITMAP memory management
+// ----------------------------------------------------------
+
+/**
+Calculate the size of a FreeImage image. 
+Align the palette and the pixels on a FIBITMAP_ALIGNMENT bytes alignment boundary.
+This function includes a protection against malicious images, based on a KISS integer overflow detection mechanism. 
+
+ at param header_only If TRUE, calculate a 'header only' FIBITMAP size, otherwise calculate a full FIBITMAP size
+ at param width Image width
+ at param height Image height
+ at param bpp Number of bits-per-pixel
+ at param need_masks We only store the masks (and allocate memory for them) for 16-bit images of type FIT_BITMAP
+ at return Returns a size in BYTE units
+ at see FreeImage_AllocateBitmap
+*/
+static size_t 
+FreeImage_GetInternalImageSize(BOOL header_only, unsigned width, unsigned height, unsigned bpp, BOOL need_masks) {
+	size_t dib_size = sizeof(FREEIMAGEHEADER);
+	dib_size += (dib_size % FIBITMAP_ALIGNMENT ? FIBITMAP_ALIGNMENT - dib_size % FIBITMAP_ALIGNMENT : 0);
+	dib_size += FIBITMAP_ALIGNMENT - sizeof(BITMAPINFOHEADER) % FIBITMAP_ALIGNMENT;
+	dib_size += sizeof(BITMAPINFOHEADER);
+	// palette is aligned on a 16 bytes boundary
+	dib_size += sizeof(RGBQUAD) * CalculateUsedPaletteEntries(bpp);
+	// we both add palette size and masks size if need_masks is true, since CalculateUsedPaletteEntries
+	// always returns 0 if need_masks is true (which is only true for 16 bit images).
+	dib_size += need_masks ? sizeof(DWORD) * 3 : 0;
+	dib_size += (dib_size % FIBITMAP_ALIGNMENT ? FIBITMAP_ALIGNMENT - dib_size % FIBITMAP_ALIGNMENT : 0);
+
+	if(!header_only) {
+		const size_t header_size = dib_size;
+
+		// pixels are aligned on a 16 bytes boundary
+		dib_size += (size_t)CalculatePitch(CalculateLine(width, bpp)) * (size_t)height;
+
+		// check for possible malloc overflow using a KISS integer overflow detection mechanism
+		{
+			const double dPitch = floor( ((double)bpp * width + 31.0) / 32.0 ) * 4.0;
+			const double dImageSize = (double)header_size + dPitch * height;
+			if(dImageSize != (double)dib_size) {
+				// here, we are sure to encounter a malloc overflow: try to avoid it ...
+				return 0;
+			}
+
+			/*
+			The following constant take into account the additionnal memory used by 
+			aligned malloc functions as well as debug malloc functions. 
+			It is supposed here that using a (8 * FIBITMAP_ALIGNMENT) risk margin will be enough
+			for the target compiler. 
+			*/
+			const double FIBITMAP_MAX_MEMORY = (double)((size_t)-1) - 8 * FIBITMAP_ALIGNMENT;
+
+			if(dImageSize > FIBITMAP_MAX_MEMORY) {
+				// avoid possible overflow inside C allocation functions
+				return 0;
+			}
+		}
+	}
+
+	return dib_size;
+}
+
+/**
 Helper for 16-bit FIT_BITMAP
-Returns a pointer to the bitmap's red-, green- and blue masks.
- at param dib The bitmap to obtain masks from.
- at return Returns a pointer to the bitmap's red-, green- and blue masks
-or NULL, if no masks are present (e.g. for 24 bit images).
-*/
-static FREEIMAGERGBMASKS *
-FreeImage_GetRGBMasks(FIBITMAP *dib) {
-	return FreeImage_HasRGBMasks(dib) ? (FREEIMAGERGBMASKS *)(((BYTE *)FreeImage_GetInfoHeader(dib)) + sizeof(BITMAPINFOHEADER)) : NULL;
-}
-
-FIBITMAP * DLL_CALLCONV
-FreeImage_AllocateHeaderT(BOOL header_only, FREE_IMAGE_TYPE type, int width, int height, int bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask) {
-
-	// check input variables
-	width = abs(width);
-	height = abs(height);
-	if(!((width > 0) && (height > 0))) {
-		return NULL;
-	}
-
-	// we only store the masks (and allocate memory for
-	// them) for 16 images of type FIT_BITMAP
-	BOOL need_masks = FALSE;
-
-	// check pixel bit depth
-	switch(type) {
-		case FIT_BITMAP:
-			switch(bpp) {
-				case 1:
-				case 4:
-				case 8:
-					break;
-				case 16:
-					need_masks = TRUE;
-                    break;
-				case 24:
-				case 32:
-					break;
-				default:
-					bpp = 8;
-					break;
-			}
-			break;
-		case FIT_UINT16:
-			bpp = 8 * sizeof(unsigned short);
-			break;
-		case FIT_INT16:
-			bpp = 8 * sizeof(short);
-			break;
-		case FIT_UINT32:
-			bpp = 8 * sizeof(DWORD);
-			break;
-		case FIT_INT32:
-			bpp = 8 * sizeof(LONG);
-			break;
-		case FIT_FLOAT:
-			bpp = 8 * sizeof(float);
-			break;
-		case FIT_DOUBLE:
-			bpp = 8 * sizeof(double);
-			break;
-		case FIT_COMPLEX:
-			bpp = 8 * sizeof(FICOMPLEX);
-			break;
-		case FIT_RGB16:
-			bpp = 8 * sizeof(FIRGB16);
-			break;
-		case FIT_RGBA16:
-			bpp = 8 * sizeof(FIRGBA16);
-			break;
-		case FIT_RGBF:
-			bpp = 8 * sizeof(FIRGBF);
-			break;
-		case FIT_RGBAF:
-			bpp = 8 * sizeof(FIRGBAF);
-			break;
-		default:
-			return NULL;
-	}
-
-	FIBITMAP *bitmap = (FIBITMAP *)malloc(sizeof(FIBITMAP));
-
-	if (bitmap != NULL) {
-
-		// calculate the size of a FreeImage image
-		// align the palette and the pixels on a FIBITMAP_ALIGNMENT bytes alignment boundary
-		// palette is aligned on a 16 bytes boundary
-		// pixels are aligned on a 16 bytes boundary
-
-		size_t dib_size = FreeImage_GetImageSizeHeader(header_only, width, height, bpp, need_masks);
-
-		if(dib_size == 0) {
-			// memory allocation will fail (probably a malloc overflow)
-			free(bitmap);
-			return NULL;
-		}
-
-		bitmap->data = (BYTE *)FreeImage_Aligned_Malloc(dib_size * sizeof(BYTE), FIBITMAP_ALIGNMENT);
-
-		if (bitmap->data != NULL) {
-			memset(bitmap->data, 0, dib_size);
-
-			// write out the FREEIMAGEHEADER
-
-			FREEIMAGEHEADER *fih    = (FREEIMAGEHEADER *)bitmap->data;
-			fih->type				= type;
-
-			memset(&fih->bkgnd_color, 0, sizeof(RGBQUAD));
-
-			fih->transparent        = FALSE;
-			fih->transparency_count = 0;
-			memset(fih->transparent_table, 0xff, 256);
-
-			fih->has_pixels = header_only ? FALSE : TRUE;
-
-			// initialize FIICCPROFILE link
-
-			FIICCPROFILE *iccProfile = FreeImage_GetICCProfile(bitmap);
-			iccProfile->size		= 0;
-			iccProfile->data		= 0;
-			iccProfile->flags		= 0;
-
-			// initialize metadata models list
-
-			fih->metadata = new(std::nothrow) METADATAMAP;
-
-			// initialize attached thumbnail
-
-			fih->thumbnail = NULL;
-
-			// write out the BITMAPINFOHEADER
-
-			BITMAPINFOHEADER *bih   = FreeImage_GetInfoHeader(bitmap);
-			bih->biSize             = sizeof(BITMAPINFOHEADER);
-			bih->biWidth            = width;
-			bih->biHeight           = height;
-			bih->biPlanes           = 1;
-			bih->biCompression      = need_masks ? BI_BITFIELDS : BI_RGB;
-			bih->biBitCount         = (WORD)bpp;
-			bih->biClrUsed          = CalculateUsedPaletteEntries(bpp);
-			bih->biClrImportant     = bih->biClrUsed;
-			bih->biXPelsPerMeter	= 2835;	// 72 dpi
-			bih->biYPelsPerMeter	= 2835;	// 72 dpi
-
-			if(bpp == 8) {
-				// build a default greyscale palette (very useful for image processing)
-				RGBQUAD *pal = FreeImage_GetPalette(bitmap);
-				for(int i = 0; i < 256; i++) {
-					pal[i].rgbRed	= (BYTE)i;
-					pal[i].rgbGreen = (BYTE)i;
-					pal[i].rgbBlue	= (BYTE)i;
-				}
-			}
-
-			// just setting the masks (only if needed) just like the palette.
-			if (need_masks) {
-				FREEIMAGERGBMASKS *masks = FreeImage_GetRGBMasks(bitmap);
-				masks->red_mask = red_mask;
-				masks->green_mask = green_mask;
-				masks->blue_mask = blue_mask;
-			}
-
-			return bitmap;
-		}
-
-		free(bitmap);
-	}
-
-	return NULL;
-}
-
-FIBITMAP * DLL_CALLCONV
-FreeImage_AllocateHeader(BOOL header_only, int width, int height, int bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask) {
-	return FreeImage_AllocateHeaderT(header_only, FIT_BITMAP, width, height, bpp, red_mask, green_mask, blue_mask);
-}
-
-FIBITMAP * DLL_CALLCONV
-FreeImage_Allocate(int width, int height, int bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask) {
-	return FreeImage_AllocateHeaderT(FALSE, FIT_BITMAP, width, height, bpp, red_mask, green_mask, blue_mask);
-}
-
-FIBITMAP * DLL_CALLCONV
-FreeImage_AllocateT(FREE_IMAGE_TYPE type, int width, int height, int bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask) {
-	return FreeImage_AllocateHeaderT(FALSE, type, width, height, bpp, red_mask, green_mask, blue_mask);
-}
-
-void DLL_CALLCONV
-FreeImage_Unload(FIBITMAP *dib) {
-	if (NULL != dib) {	
-		if (NULL != dib->data) {
-			// delete possible icc profile ...
-			if (FreeImage_GetICCProfile(dib)->data)
-				free(FreeImage_GetICCProfile(dib)->data);
-
-			// delete metadata models
-			METADATAMAP *metadata = ((FREEIMAGEHEADER *)dib->data)->metadata;
-
-			for(METADATAMAP::iterator i = (*metadata).begin(); i != (*metadata).end(); i++) {
-				TAGMAP *tagmap = (*i).second;
-
-				if(tagmap) {
-					for(TAGMAP::iterator j = tagmap->begin(); j != tagmap->end(); j++) {
-						FITAG *tag = (*j).second;
-						FreeImage_DeleteTag(tag);
-					}
-
-					delete tagmap;
-				}
-			}
-
-			delete metadata;
-
-			// delete embedded thumbnail
-			FreeImage_Unload(FreeImage_GetThumbnail(dib));
-
-			// delete bitmap ...
-			FreeImage_Aligned_Free(dib->data);
-		}
-		free(dib);		// ... and the wrapper
-	}
-}
-
-// ----------------------------------------------------------
-
-FIBITMAP * DLL_CALLCONV
-FreeImage_Clone(FIBITMAP *dib) {
-	if(!dib) return NULL;
-
-	FREE_IMAGE_TYPE type = FreeImage_GetImageType(dib);
-	unsigned width       = FreeImage_GetWidth(dib);
-	unsigned height      = FreeImage_GetHeight(dib);
-	unsigned bpp         = FreeImage_GetBPP(dib);
-	
-	// check for pixel availability ...
-	BOOL header_only = FreeImage_HasPixels(dib) ? FALSE : TRUE;
-	// check whether this image has masks defined ...
-	BOOL need_masks  = (bpp == 16 && type == FIT_BITMAP) ? TRUE : FALSE;
-
-	// allocate a new dib
-	FIBITMAP *new_dib = FreeImage_AllocateHeaderT(header_only, type, width, height, bpp,
-			FreeImage_GetRedMask(dib), FreeImage_GetGreenMask(dib), FreeImage_GetBlueMask(dib));
-
-	if (new_dib) {
-		// save ICC profile links
-		FIICCPROFILE *src_iccProfile = FreeImage_GetICCProfile(dib);
-		FIICCPROFILE *dst_iccProfile = FreeImage_GetICCProfile(new_dib);
-
-		// save metadata links
-		METADATAMAP *src_metadata = ((FREEIMAGEHEADER *)dib->data)->metadata;
-		METADATAMAP *dst_metadata = ((FREEIMAGEHEADER *)new_dib->data)->metadata;
-
-		// calculate the size of a FreeImage image
-		// align the palette and the pixels on a FIBITMAP_ALIGNMENT bytes alignment boundary
-		// palette is aligned on a 16 bytes boundary
-		// pixels are aligned on a 16 bytes boundary
-
-		size_t dib_size = FreeImage_GetImageSizeHeader(header_only, width, height, bpp, need_masks);
-
-		// copy the bitmap + internal pointers (remember to restore new_dib internal pointers later)
-		memcpy(new_dib->data, dib->data, dib_size);
-
-		// reset ICC profile link for new_dib
-		memset(dst_iccProfile, 0, sizeof(FIICCPROFILE));
-
-		// restore metadata link for new_dib
-		((FREEIMAGEHEADER *)new_dib->data)->metadata = dst_metadata;
-
-		// reset thumbnail link for new_dib
-		((FREEIMAGEHEADER *)new_dib->data)->thumbnail = NULL;
-
-		// copy possible ICC profile
-		FreeImage_CreateICCProfile(new_dib, src_iccProfile->data, src_iccProfile->size);
-		dst_iccProfile->flags = src_iccProfile->flags;
-
-		// copy metadata models
-		for(METADATAMAP::iterator i = (*src_metadata).begin(); i != (*src_metadata).end(); i++) {
-			int model = (*i).first;
-			TAGMAP *src_tagmap = (*i).second;
-
-			if(src_tagmap) {
-				// create a metadata model
-				TAGMAP *dst_tagmap = new(std::nothrow) TAGMAP();
-
-				if(dst_tagmap) {
-					// fill the model
-					for(TAGMAP::iterator j = src_tagmap->begin(); j != src_tagmap->end(); j++) {
-						std::string dst_key = (*j).first;
-						FITAG *dst_tag = FreeImage_CloneTag( (*j).second );
-
-						// assign key and tag value
-						(*dst_tagmap)[dst_key] = dst_tag;
-					}
-
-					// assign model and tagmap
-					(*dst_metadata)[model] = dst_tagmap;
-				}
-			}
-		}
-
-		// copy the thumbnail
-		FreeImage_SetThumbnail(new_dib, FreeImage_GetThumbnail(dib));
-
-		return new_dib;
-	}
-
-	return NULL;
-}
-
-// ----------------------------------------------------------
-
-FIBITMAP* DLL_CALLCONV
-FreeImage_GetThumbnail(FIBITMAP *dib) {
-	return (dib != NULL) ? ((FREEIMAGEHEADER *)dib->data)->thumbnail : NULL;
-}
-
-BOOL DLL_CALLCONV
-FreeImage_SetThumbnail(FIBITMAP *dib, FIBITMAP *thumbnail) {
-	if(dib == NULL) {
-		return FALSE;
-	}
-	FIBITMAP *currentThumbnail = ((FREEIMAGEHEADER *)dib->data)->thumbnail;
-	if(currentThumbnail == thumbnail) {
-		return TRUE;
-	}
-	FreeImage_Unload(currentThumbnail);
-
-	((FREEIMAGEHEADER *)dib->data)->thumbnail = FreeImage_HasPixels(thumbnail) ? FreeImage_Clone(thumbnail) : NULL;
-
-	return TRUE;
-}
-
-// ----------------------------------------------------------
-
-FREE_IMAGE_COLOR_TYPE DLL_CALLCONV
-FreeImage_GetColorType(FIBITMAP *dib) {
-	RGBQUAD *rgb;
-
-	const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
-
-	// special bitmap type
-	if(image_type != FIT_BITMAP) {
-		switch(image_type) {
-			case FIT_RGB16:
-			case FIT_RGBF:
-				return FIC_RGB;
-			case FIT_RGBA16:
-			case FIT_RGBAF:
-				return FIC_RGBALPHA;
-		}
-
-		return FIC_MINISBLACK;
-	}
-
-	// standard image type
-	switch (FreeImage_GetBPP(dib)) {
-		case 1:
-		{
-			rgb = FreeImage_GetPalette(dib);
-
-			if ((rgb->rgbRed == 0) && (rgb->rgbGreen == 0) && (rgb->rgbBlue == 0)) {
-				rgb++;
-
-				if ((rgb->rgbRed == 255) && (rgb->rgbGreen == 255) && (rgb->rgbBlue == 255))
-					return FIC_MINISBLACK;				
-			}
-
-			if ((rgb->rgbRed == 255) && (rgb->rgbGreen == 255) && (rgb->rgbBlue == 255)) {
-				rgb++;
-
-				if ((rgb->rgbRed == 0) && (rgb->rgbGreen == 0) && (rgb->rgbBlue == 0))
-					return FIC_MINISWHITE;				
-			}
-
-			return FIC_PALETTE;
-		}
-
-		case 4:
-		case 8:	// Check if the DIB has a color or a greyscale palette
-		{
-			int ncolors = FreeImage_GetColorsUsed(dib);
-		    int minisblack = 1;
-			rgb = FreeImage_GetPalette(dib);
-
-			for (int i = 0; i < ncolors; i++) {
-				if ((rgb->rgbRed != rgb->rgbGreen) || (rgb->rgbRed != rgb->rgbBlue))
-					return FIC_PALETTE;
-
-				// The DIB has a color palette if the greyscale isn't a linear ramp
-				// Take care of reversed grey images
-				if (rgb->rgbRed != i) {
-					if ((ncolors-i-1) != rgb->rgbRed)
-						return FIC_PALETTE;
-				    else
-						minisblack = 0;
-				}
-
-				rgb++;
-			}
-
-			return minisblack ? FIC_MINISBLACK : FIC_MINISWHITE;
-		}
-
-		case 16:
-		case 24:
-			return FIC_RGB;
-
-		case 32:
-		{
-			if (FreeImage_GetICCProfile(dib)->flags & FIICC_COLOR_IS_CMYK)
-				return FIC_CMYK;
-
-			if( FreeImage_HasPixels(dib) ) {
-				// check for fully opaque alpha layer
-				for (unsigned y = 0; y < FreeImage_GetHeight(dib); y++) {
-					rgb = (RGBQUAD *)FreeImage_GetScanLine(dib, y);
-
-					for (unsigned x = 0; x < FreeImage_GetWidth(dib); x++)
-						if (rgb[x].rgbReserved != 0xFF)
-							return FIC_RGBALPHA;			
-				}
-				return FIC_RGB;
-			}
-
-			return FIC_RGBALPHA;
-		}
-				
-		default :
-			return FIC_MINISBLACK;
-	}
-}
-
-// ----------------------------------------------------------
-
-FREE_IMAGE_TYPE DLL_CALLCONV 
-FreeImage_GetImageType(FIBITMAP *dib) {
-	return (dib != NULL) ? ((FREEIMAGEHEADER *)dib->data)->type : FIT_UNKNOWN;
-}
-
-// ----------------------------------------------------------
-
-BOOL DLL_CALLCONV 
-FreeImage_HasPixels(FIBITMAP *dib) {
-	return (dib != NULL) ? ((FREEIMAGEHEADER *)dib->data)->has_pixels : FALSE;
-}
-
-// ----------------------------------------------------------
-
-BOOL DLL_CALLCONV
-FreeImage_HasRGBMasks(FIBITMAP *dib) {
-	return dib && FreeImage_GetInfoHeader(dib)->biCompression == BI_BITFIELDS;
-}
-
-unsigned DLL_CALLCONV
-FreeImage_GetRedMask(FIBITMAP *dib) {
-	FREEIMAGERGBMASKS *masks = FreeImage_GetRGBMasks(dib);
-	return masks ? masks->red_mask : 0;
-}
-
-unsigned DLL_CALLCONV
-FreeImage_GetGreenMask(FIBITMAP *dib) {
-	FREEIMAGERGBMASKS *masks = FreeImage_GetRGBMasks(dib);
-	return masks ? masks->green_mask : 0;
-}
-
-unsigned DLL_CALLCONV
-FreeImage_GetBlueMask(FIBITMAP *dib) {
-	FREEIMAGERGBMASKS *masks = FreeImage_GetRGBMasks(dib);
-	return masks ? masks->blue_mask : 0;
-}
-
-// ----------------------------------------------------------
-
-BOOL DLL_CALLCONV
-FreeImage_HasBackgroundColor(FIBITMAP *dib) {
-	if(dib) {
-		RGBQUAD *bkgnd_color = &((FREEIMAGEHEADER *)dib->data)->bkgnd_color;
-		return (bkgnd_color->rgbReserved != 0) ? TRUE : FALSE;
-	}
-	return FALSE;
-}
-
-BOOL DLL_CALLCONV
-FreeImage_GetBackgroundColor(FIBITMAP *dib, RGBQUAD *bkcolor) {
-	if(dib && bkcolor) {
-		if(FreeImage_HasBackgroundColor(dib)) {
-			// get the background color
-			RGBQUAD *bkgnd_color = &((FREEIMAGEHEADER *)dib->data)->bkgnd_color;
-			memcpy(bkcolor, bkgnd_color, sizeof(RGBQUAD));
-			// get the background index
-			if(FreeImage_GetBPP(dib) == 8) {
-				RGBQUAD *pal = FreeImage_GetPalette(dib);
-				for(unsigned i = 0; i < FreeImage_GetColorsUsed(dib); i++) {
-					if(bkgnd_color->rgbRed == pal[i].rgbRed) {
-						if(bkgnd_color->rgbGreen == pal[i].rgbGreen) {
-							if(bkgnd_color->rgbBlue == pal[i].rgbBlue) {
-								bkcolor->rgbReserved = (BYTE)i;
-								return TRUE;
-							}
-						}
-					}
-				}
-			}
-
-			bkcolor->rgbReserved = 0;
-
-			return TRUE;
-		}
-	}
-
-	return FALSE;
-}
-
-BOOL DLL_CALLCONV 
-FreeImage_SetBackgroundColor(FIBITMAP *dib, RGBQUAD *bkcolor) {
-	if(dib) {
-		RGBQUAD *bkgnd_color = &((FREEIMAGEHEADER *)dib->data)->bkgnd_color;
-		if(bkcolor) {
-			// set the background color
-			memcpy(bkgnd_color, bkcolor, sizeof(RGBQUAD));
-			// enable the file background color
-			bkgnd_color->rgbReserved = 1;
-		} else {
-			// clear and disable the file background color
-			memset(bkgnd_color, 0, sizeof(RGBQUAD));
-		}
-		return TRUE;
-	}
-
-	return FALSE;
-}
-
-// ----------------------------------------------------------
-
-BOOL DLL_CALLCONV
-FreeImage_IsTransparent(FIBITMAP *dib) {
-	if(dib) {
-		FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
-		switch(image_type) {
-			case FIT_BITMAP:
-				if(FreeImage_GetBPP(dib) == 32) {
-					if(FreeImage_GetColorType(dib) == FIC_RGBALPHA) {
-						return TRUE;
-					}
-				} else {
-					return ((FREEIMAGEHEADER *)dib->data)->transparent ? TRUE : FALSE;
-				}
-				break;
-			case FIT_RGBA16:
-			case FIT_RGBAF:
-				return TRUE;
-			default:
-				break;
-		}
-	}
-	return FALSE;
-}
-
-BYTE * DLL_CALLCONV
-FreeImage_GetTransparencyTable(FIBITMAP *dib) {
-	return dib ? ((FREEIMAGEHEADER *)dib->data)->transparent_table : NULL;
-}
-
-void DLL_CALLCONV
-FreeImage_SetTransparent(FIBITMAP *dib, BOOL enabled) {
-	if (dib) {
-		if ((FreeImage_GetBPP(dib) <= 8) || (FreeImage_GetBPP(dib) == 32)) {
-			((FREEIMAGEHEADER *)dib->data)->transparent = enabled;
-		} else {
-			((FREEIMAGEHEADER *)dib->data)->transparent = FALSE;
-		}
-	}
-}
-
-unsigned DLL_CALLCONV
-FreeImage_GetTransparencyCount(FIBITMAP *dib) {
-	return dib ? ((FREEIMAGEHEADER *)dib->data)->transparency_count : 0;
-}
-
-void DLL_CALLCONV
-FreeImage_SetTransparencyTable(FIBITMAP *dib, BYTE *table, int count) {
-	if (dib) {
-		count = MAX(0, MIN(count, 256));
-		if (FreeImage_GetBPP(dib) <= 8) {
-			((FREEIMAGEHEADER *)dib->data)->transparent = (count > 0) ? TRUE : FALSE;
-			((FREEIMAGEHEADER *)dib->data)->transparency_count = count;
-
-			if (table) {
-				memcpy(((FREEIMAGEHEADER *)dib->data)->transparent_table, table, count);
-			} else {
-				memset(((FREEIMAGEHEADER *)dib->data)->transparent_table, 0xff, count);
-			}
-		} 
-	}
-}
-
-/** @brief Sets the index of the palette entry to be used as transparent color
- for the image specified. Does nothing on high color images. 
- 
- This method sets the index of the palette entry to be used as single transparent
- color for the image specified. This works on palletised images only and does
- nothing for high color images.
- 
- Although it is possible for palletised images to have more than one transparent
- color, this method sets the palette entry specified as the single transparent
- color for the image. All other colors will be set to be non-transparent by this
- method.
- 
- As with FreeImage_SetTransparencyTable(), this method also sets the image's
- transparency property to TRUE (as it is set and obtained by
- FreeImage_SetTransparent() and FreeImage_IsTransparent() respectively) for
- palletised images.
- 
- @param dib Input image, whose transparent color is to be set.
- @param index The index of the palette entry to be set as transparent color.
- */
-void DLL_CALLCONV
-FreeImage_SetTransparentIndex(FIBITMAP *dib, int index) {
-	if (dib) {
-		int count = FreeImage_GetColorsUsed(dib);
-		if (count) {
-			BYTE *new_tt = (BYTE *)malloc(count * sizeof(BYTE));
-			memset(new_tt, 0xFF, count);
-			if ((index >= 0) && (index < count)) {
-				new_tt[index] = 0x00;
-			}
-			FreeImage_SetTransparencyTable(dib, new_tt, count);
-			free(new_tt);
-		}
-	}
-}
-
-/** @brief Returns the palette entry used as transparent color for the image
- specified. Works for palletised images only and returns -1 for high color
- images or if the image has no color set to be transparent. 
- 
- Although it is possible for palletised images to have more than one transparent
- color, this function always returns the index of the first palette entry, set
- to be transparent. 
- 
- @param dib Input image, whose transparent color is to be returned.
- @return Returns the index of the palette entry used as transparent color for
- the image specified or -1 if there is no transparent color found (e.g. the image
- is a high color image).
- */
-int DLL_CALLCONV
-FreeImage_GetTransparentIndex(FIBITMAP *dib) {
-	int count = FreeImage_GetTransparencyCount(dib);
-	BYTE *tt = FreeImage_GetTransparencyTable(dib);
-	for (int i = 0; i < count; i++) {
-		if (tt[i] == 0) {
-			return i;
-		}
-	}
-	return -1;
-}
-
-// ----------------------------------------------------------
-
-FIICCPROFILE * DLL_CALLCONV
-FreeImage_GetICCProfile(FIBITMAP *dib) {
-	FIICCPROFILE *profile = (dib) ? (FIICCPROFILE *)&((FREEIMAGEHEADER *)dib->data)->iccProfile : NULL;
-	return profile;
-}
-
-FIICCPROFILE * DLL_CALLCONV
-FreeImage_CreateICCProfile(FIBITMAP *dib, void *data, long size) {
-	// clear the profile but preserve profile->flags
-	FreeImage_DestroyICCProfile(dib);
-	// create the new profile
-	FIICCPROFILE *profile = FreeImage_GetICCProfile(dib);
-	if(size && profile) {
-		profile->data = malloc(size);
-		if(profile->data) {
-			memcpy(profile->data, data, profile->size = size);
-		}
-	}
-	return profile;
-}
-
-void DLL_CALLCONV
-FreeImage_DestroyICCProfile(FIBITMAP *dib) {
-	FIICCPROFILE *profile = FreeImage_GetICCProfile(dib);
-	if(profile) {
-		if (profile->data) {
-			free (profile->data);
-		}
-		// clear the profile but preserve profile->flags
-		profile->data = NULL;
-		profile->size = 0;
-	}
-}
-
-// ----------------------------------------------------------
-
-unsigned DLL_CALLCONV
-FreeImage_GetWidth(FIBITMAP *dib) {
-	return dib ? FreeImage_GetInfoHeader(dib)->biWidth : 0;
-}
-
-unsigned DLL_CALLCONV
-FreeImage_GetHeight(FIBITMAP *dib) {
-	return (dib) ? FreeImage_GetInfoHeader(dib)->biHeight : 0;
-}
-
-unsigned DLL_CALLCONV
-FreeImage_GetBPP(FIBITMAP *dib) {
-	return dib ? FreeImage_GetInfoHeader(dib)->biBitCount : 0;
-}
-
-unsigned DLL_CALLCONV
-FreeImage_GetLine(FIBITMAP *dib) {
-	return dib ? ((FreeImage_GetWidth(dib) * FreeImage_GetBPP(dib)) + 7) / 8 : 0;
-}
-
-unsigned DLL_CALLCONV
-FreeImage_GetPitch(FIBITMAP *dib) {
-	return dib ? FreeImage_GetLine(dib) + 3 & ~3 : 0;
-}
-
-unsigned DLL_CALLCONV
-FreeImage_GetColorsUsed(FIBITMAP *dib) {
-	return dib ? FreeImage_GetInfoHeader(dib)->biClrUsed : 0;
-}
-
-unsigned DLL_CALLCONV
-FreeImage_GetDIBSize(FIBITMAP *dib) {
-	return (dib) ? sizeof(BITMAPINFOHEADER) + (FreeImage_GetColorsUsed(dib) * sizeof(RGBQUAD)) + (FreeImage_GetPitch(dib) * FreeImage_GetHeight(dib)) : 0;
-}
-
-RGBQUAD * DLL_CALLCONV
-FreeImage_GetPalette(FIBITMAP *dib) {
-	return (dib && FreeImage_GetBPP(dib) < 16) ? (RGBQUAD *)(((BYTE *)FreeImage_GetInfoHeader(dib)) + sizeof(BITMAPINFOHEADER)) : NULL;
-}
-
-unsigned DLL_CALLCONV
-FreeImage_GetDotsPerMeterX(FIBITMAP *dib) {
-	return (dib) ? FreeImage_GetInfoHeader(dib)->biXPelsPerMeter : 0;
-}
-
-unsigned DLL_CALLCONV
-FreeImage_GetDotsPerMeterY(FIBITMAP *dib) {
-	return (dib) ? FreeImage_GetInfoHeader(dib)->biYPelsPerMeter : 0;
-}
-
-void DLL_CALLCONV
-FreeImage_SetDotsPerMeterX(FIBITMAP *dib, unsigned res) {
-	if(dib) {
-		FreeImage_GetInfoHeader(dib)->biXPelsPerMeter = res;
-	}
-}
-
-void DLL_CALLCONV
-FreeImage_SetDotsPerMeterY(FIBITMAP *dib, unsigned res) {
-	if(dib) {
-		FreeImage_GetInfoHeader(dib)->biYPelsPerMeter = res;
-	}
-}
-
-BITMAPINFOHEADER * DLL_CALLCONV
-FreeImage_GetInfoHeader(FIBITMAP *dib) {
-	if(!dib) return NULL;
-	size_t lp = (size_t)dib->data + sizeof(FREEIMAGEHEADER);
-	lp += (lp % FIBITMAP_ALIGNMENT ? FIBITMAP_ALIGNMENT - lp % FIBITMAP_ALIGNMENT : 0);
-	lp += FIBITMAP_ALIGNMENT - sizeof(BITMAPINFOHEADER) % FIBITMAP_ALIGNMENT;
-	return (BITMAPINFOHEADER *)lp;
-}
-
-BITMAPINFO * DLL_CALLCONV
-FreeImage_GetInfo(FIBITMAP *dib) {
-	return (BITMAPINFO *)FreeImage_GetInfoHeader(dib);
-}
-
-// ----------------------------------------------------------
-//  Metadata routines
-// ----------------------------------------------------------
-
-FIMETADATA * DLL_CALLCONV 
-FreeImage_FindFirstMetadata(FREE_IMAGE_MDMODEL model, FIBITMAP *dib, FITAG **tag) {
-	if(!dib)
-		return NULL;
-
-	// get the metadata model
-	METADATAMAP *metadata = ((FREEIMAGEHEADER *)dib->data)->metadata;
-	TAGMAP *tagmap = NULL;
-	if( (*metadata).find(model) != (*metadata).end() ) {
-		tagmap = (*metadata)[model];
-	}
-	if(tagmap) {
-		// allocate a handle
-		FIMETADATA 	*handle = (FIMETADATA *)malloc(sizeof(FIMETADATA));
-		if(handle) {
-			// calculate the size of a METADATAHEADER
-			int header_size = sizeof(METADATAHEADER);
-
-			handle->data = (BYTE *)malloc(header_size * sizeof(BYTE));
-			
-			if(handle->data) {
-				memset(handle->data, 0, header_size * sizeof(BYTE));
-
-				// write out the METADATAHEADER
-				METADATAHEADER *mdh = (METADATAHEADER *)handle->data;
-
-				mdh->pos = 1;
-				mdh->tagmap = tagmap;
-
-				// get the first element
-				TAGMAP::iterator i = tagmap->begin();
-				*tag = (*i).second;
-
-				return handle;
-			}
-
-			free(handle);
-		}
-	}
-
-	return NULL;
-}
-
-BOOL DLL_CALLCONV 
-FreeImage_FindNextMetadata(FIMETADATA *mdhandle, FITAG **tag) {
-	if(!mdhandle)
-		return FALSE;
-
-	METADATAHEADER *mdh = (METADATAHEADER *)mdhandle->data;
-	TAGMAP *tagmap = mdh->tagmap;
-
-	int current_pos = mdh->pos;
-	int mapsize     = (int)tagmap->size();
-
-	if(current_pos < mapsize) {
-		// get the tag element at position pos
-		int count = 0;
-
-		for(TAGMAP::iterator i = tagmap->begin(); i != tagmap->end(); i++) {
-			if(count == current_pos) {
-				*tag = (*i).second;
-				mdh->pos++;
-				break;
-			}
-			count++;
-		}
-		
-		return TRUE;
-	}
-
-	return FALSE;
-}
-
-void DLL_CALLCONV 
-FreeImage_FindCloseMetadata(FIMETADATA *mdhandle) {
-	if (NULL != mdhandle) {	// delete the handle
-		if (NULL != mdhandle->data) {
-			free(mdhandle->data);
-		}
-		free(mdhandle);		// ... and the wrapper
-	}
-}
-
-
-// ----------------------------------------------------------
-
-BOOL DLL_CALLCONV
-FreeImage_CloneMetadata(FIBITMAP *dst, FIBITMAP *src) {
-	if(!src || !dst) return FALSE;
-
-	// get metadata links
-	METADATAMAP *src_metadata = ((FREEIMAGEHEADER *)src->data)->metadata;
-	METADATAMAP *dst_metadata = ((FREEIMAGEHEADER *)dst->data)->metadata;
-
-	// copy metadata models, *except* the FIMD_ANIMATION model
-	for(METADATAMAP::iterator i = (*src_metadata).begin(); i != (*src_metadata).end(); i++) {
-		int model = (*i).first;
-		if(model == (int)FIMD_ANIMATION) {
-			continue;
-		}
-		TAGMAP *src_tagmap = (*i).second;
-
-		if(src_tagmap) {
-			if( dst_metadata->find(model) != dst_metadata->end() ) {
-				// destroy dst model
-				FreeImage_SetMetadata((FREE_IMAGE_MDMODEL)model, dst, NULL, NULL);
-			}
-
-			// create a metadata model
-			TAGMAP *dst_tagmap = new(std::nothrow) TAGMAP();
-
-			if(dst_tagmap) {
-				// fill the model
-				for(TAGMAP::iterator j = src_tagmap->begin(); j != src_tagmap->end(); j++) {
-					std::string dst_key = (*j).first;
-					FITAG *dst_tag = FreeImage_CloneTag( (*j).second );
-
-					// assign key and tag value
-					(*dst_tagmap)[dst_key] = dst_tag;
-				}
-
-				// assign model and tagmap
-				(*dst_metadata)[model] = dst_tagmap;
-			}
-		}
-	}
-
-	// clone resolution 
-	FreeImage_SetDotsPerMeterX(dst, FreeImage_GetDotsPerMeterX(src)); 
-	FreeImage_SetDotsPerMeterY(dst, FreeImage_GetDotsPerMeterY(src)); 
-
-	return TRUE;
-}
-
-// ----------------------------------------------------------
-
-BOOL DLL_CALLCONV 
-FreeImage_SetMetadata(FREE_IMAGE_MDMODEL model, FIBITMAP *dib, const char *key, FITAG *tag) {
-	if(!dib) 
-		return FALSE;
-
-	TAGMAP *tagmap = NULL;
-
-	// get the metadata model
-	METADATAMAP *metadata = ((FREEIMAGEHEADER *)dib->data)->metadata;
-	METADATAMAP::iterator model_iterator = metadata->find(model);
-	if (model_iterator != metadata->end()) {
-		tagmap = model_iterator->second;
-	}
-
-	if(key != NULL) {
-
-		if(!tagmap) {
-			// this model, doesn't exist: create it 
-			tagmap = new(std::nothrow) TAGMAP();
-			(*metadata)[model] = tagmap;
-		}
-		
-		if(tag) {
-			// first check the tag
-			if(FreeImage_GetTagKey(tag) == NULL) {
-				FreeImage_SetTagKey(tag, key);
-			} else if(strcmp(key, FreeImage_GetTagKey(tag)) != 0) {
-				// set the tag key
-				FreeImage_SetTagKey(tag, key);
-			}
-			if(FreeImage_GetTagCount(tag) * FreeImage_TagDataWidth(FreeImage_GetTagType(tag)) != FreeImage_GetTagLength(tag)) {
-				FreeImage_OutputMessageProc(FIF_UNKNOWN, "Invalid data count for tag '%s'", key);
-				return FALSE;
-			}
-
-			// fill the tag ID if possible and if it's needed
-			TagLib& tag_lib = TagLib::instance();
-			switch(model) {
-				case FIMD_IPTC:
-				{
-					int id = tag_lib.getTagID(TagLib::IPTC, key);
-					/*
-					if(id == -1) {
-						FreeImage_OutputMessageProc(FIF_UNKNOWN, "IPTC: Invalid key '%s'", key);
-					}
-					*/
-					FreeImage_SetTagID(tag, (WORD)id);
-				}
-				break;
-
-				default:
-					break;
-			}
-
-			// delete existing tag
-			FITAG *old_tag = (*tagmap)[key];
-			if(old_tag) {
-				FreeImage_DeleteTag(old_tag);
-			}
-
-			// create a new tag
-			(*tagmap)[key] = FreeImage_CloneTag(tag);
-		}
-		else {
-			// delete existing tag
-			TAGMAP::iterator i = tagmap->find(key);
-			if(i != tagmap->end()) {
-				FITAG *old_tag = (*i).second;
-				FreeImage_DeleteTag(old_tag);
-				tagmap->erase(key);
-			}
-		}
-	}
-	else {
-		// destroy the metadata model
-		if(tagmap) {
-			for(TAGMAP::iterator i = tagmap->begin(); i != tagmap->end(); i++) {
-				FITAG *tag = (*i).second;
-				FreeImage_DeleteTag(tag);
-			}
-
-			delete tagmap;
-			metadata->erase(model_iterator);
-		}
-	}
-
-	return TRUE;
-}
-
-BOOL DLL_CALLCONV 
-FreeImage_GetMetadata(FREE_IMAGE_MDMODEL model, FIBITMAP *dib, const char *key, FITAG **tag) {
-	if(!dib || !key || !tag) 
-		return FALSE;
-
-	TAGMAP *tagmap = NULL;
-	*tag = NULL;
-
-	// get the metadata model
-	METADATAMAP *metadata = ((FREEIMAGEHEADER *)dib->data)->metadata;
-	if(!(*metadata).empty()) {
-		METADATAMAP::iterator model_iterator = metadata->find(model);
-		if (model_iterator != metadata->end() ) {
-			// this model exists : try to get the requested tag
-			tagmap = model_iterator->second;
-			TAGMAP::iterator tag_iterator = tagmap->find(key);
-			if (tag_iterator != tagmap->end() ) {
-				// get the requested tag
-				*tag = tag_iterator->second;
-			} 
-		}
-	}
-
-	return (*tag != NULL) ? TRUE : FALSE;
-}
-
-// ----------------------------------------------------------
-
-unsigned DLL_CALLCONV 
-FreeImage_GetMetadataCount(FREE_IMAGE_MDMODEL model, FIBITMAP *dib) {
-	if(!dib) 
-		return FALSE;
-
-	TAGMAP *tagmap = NULL;
-
-	// get the metadata model
-	METADATAMAP *metadata = ((FREEIMAGEHEADER *)dib->data)->metadata;
-	if( (*metadata).find(model) != (*metadata).end() ) {
-		tagmap = (*metadata)[model];
-	}
-	if(!tagmap) {
-		// this model, doesn't exist: return
-		return 0;
-	}
-
-	// get the tag count
-	return (unsigned)tagmap->size();
-}
-
-// ----------------------------------------------------------
-
-
+Returns a pointer to the bitmap's red-, green- and blue masks.
+ at param dib The bitmap to obtain masks from.
+ at return Returns a pointer to the bitmap's red-, green- and blue masks
+or NULL, if no masks are present (e.g. for 24 bit images).
+*/
+static FREEIMAGERGBMASKS *
+FreeImage_GetRGBMasks(FIBITMAP *dib) {
+	return FreeImage_HasRGBMasks(dib) ? (FREEIMAGERGBMASKS *)(((BYTE *)FreeImage_GetInfoHeader(dib)) + sizeof(BITMAPINFOHEADER)) : NULL;
+}
+
+/**
+Internal FIBITMAP allocation.
+
+This function accepts (ext_bits, ext_pitch) arguments. If these are provided the FIBITMAP 
+will be allocated as "header only", but bits and pitch will be stored within the FREEIMAGEHEADER 
+and the resulting FIBITMAP will have pixels, i.e. HasPixels() will return TRUE.
+- GetBits() and GetPitch return the correct values - either offsets or the stored values (user-provided bits and pitch).
+- Clone() creates a new FIBITMAP with copy of the user pixel data.
+- Unload's implementation does not need to change - it just release a "header only" dib.
+Note that when using external data, the data does not need to have the same alignment as the default 4-byte alignment. 
+This enables the possibility to access buffers with, for instance, stricter alignment,
+like the ones used in low-level APIs like OpenCL or intrinsics.
+
+ at param header_only If TRUE, allocate a 'header only' FIBITMAP, otherwise allocate a full FIBITMAP
+ at param ext_bits Pointer to external user's pixel buffer if using wrapped buffer, NULL otherwise
+ at param ext_pitch Pointer to external user's pixel buffer pitch if using wrapped buffer, 0 otherwise
+ at param type Image type
+ at param width Image width
+ at param height Image height
+ at param bpp Number of bits per pixel
+ at param red_mask Image red mask 
+ at param green_mask Image green mask
+ at param blue_mask Image blue mask
+ at return Returns the allocated FIBITMAP if successful, returns NULL otherwise
+*/
+static FIBITMAP * 
+FreeImage_AllocateBitmap(BOOL header_only, BYTE *ext_bits, unsigned ext_pitch, FREE_IMAGE_TYPE type, int width, int height, int bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask) {
+
+	// check input variables
+	width = abs(width);
+	height = abs(height);
+	if(!((width > 0) && (height > 0))) {
+		return NULL;
+	}
+	if(ext_bits) {
+		if(ext_pitch == 0) {
+			return NULL;
+		}
+		assert(header_only == FALSE);
+	}
+
+	// we only store the masks (and allocate memory for them) for 16-bit images of type FIT_BITMAP
+	BOOL need_masks = FALSE;
+
+	// check pixel bit depth
+	switch(type) {
+		case FIT_BITMAP:
+			switch(bpp) {
+				case 1:
+				case 4:
+				case 8:
+					break;
+				case 16:
+					need_masks = TRUE;
+					break;
+				case 24:
+				case 32:
+					break;
+				default:
+					bpp = 8;
+					break;
+			}
+			break;
+		case FIT_UINT16:
+			bpp = 8 * sizeof(unsigned short);
+			break;
+		case FIT_INT16:
+			bpp = 8 * sizeof(short);
+			break;
+		case FIT_UINT32:
+			bpp = 8 * sizeof(DWORD);
+			break;
+		case FIT_INT32:
+			bpp = 8 * sizeof(LONG);
+			break;
+		case FIT_FLOAT:
+			bpp = 8 * sizeof(float);
+			break;
+		case FIT_DOUBLE:
+			bpp = 8 * sizeof(double);
+			break;
+		case FIT_COMPLEX:
+			bpp = 8 * sizeof(FICOMPLEX);
+			break;
+		case FIT_RGB16:
+			bpp = 8 * sizeof(FIRGB16);
+			break;
+		case FIT_RGBA16:
+			bpp = 8 * sizeof(FIRGBA16);
+			break;
+		case FIT_RGBF:
+			bpp = 8 * sizeof(FIRGBF);
+			break;
+		case FIT_RGBAF:
+			bpp = 8 * sizeof(FIRGBAF);
+			break;
+		default:
+			return NULL;
+	}
+
+	FIBITMAP *bitmap = (FIBITMAP *)malloc(sizeof(FIBITMAP));
+
+	if (bitmap != NULL) {
+
+		// calculate the size of a FreeImage image
+		// align the palette and the pixels on a FIBITMAP_ALIGNMENT bytes alignment boundary
+		// palette is aligned on a 16 bytes boundary
+		// pixels are aligned on a 16 bytes boundary
+
+		// when using a user provided pixel buffer, force a 'header only' allocation
+
+		size_t dib_size = FreeImage_GetInternalImageSize(header_only || ext_bits, width, height, bpp, need_masks);
+
+		if(dib_size == 0) {
+			// memory allocation will fail (probably a malloc overflow)
+			free(bitmap);
+			return NULL;
+		}
+
+		bitmap->data = (BYTE *)FreeImage_Aligned_Malloc(dib_size * sizeof(BYTE), FIBITMAP_ALIGNMENT);
+
+		if (bitmap->data != NULL) {
+			memset(bitmap->data, 0, dib_size);
+
+			// write out the FREEIMAGEHEADER
+
+			FREEIMAGEHEADER *fih = (FREEIMAGEHEADER *)bitmap->data;
+
+			fih->type = type;
+
+			memset(&fih->bkgnd_color, 0, sizeof(RGBQUAD));
+
+			fih->transparent = FALSE;
+			fih->transparency_count = 0;
+			memset(fih->transparent_table, 0xff, 256);
+
+			fih->has_pixels = header_only ? FALSE : TRUE;
+
+			// initialize FIICCPROFILE link
+
+			FIICCPROFILE *iccProfile = FreeImage_GetICCProfile(bitmap);
+			iccProfile->size = 0;
+			iccProfile->data = 0;
+			iccProfile->flags = 0;
+
+			// initialize metadata models list
+
+			fih->metadata = new(std::nothrow) METADATAMAP;
+
+			// initialize attached thumbnail
+
+			fih->thumbnail = NULL;
+
+			// store a pointer to user provided pixel buffer (if any)
+
+			fih->external_bits = ext_bits;
+			fih->external_pitch = ext_pitch;
+
+			// write out the BITMAPINFOHEADER
+
+			BITMAPINFOHEADER *bih   = FreeImage_GetInfoHeader(bitmap);
+			bih->biSize             = sizeof(BITMAPINFOHEADER);
+			bih->biWidth            = width;
+			bih->biHeight           = height;
+			bih->biPlanes           = 1;
+			bih->biCompression      = need_masks ? BI_BITFIELDS : BI_RGB;
+			bih->biBitCount         = (WORD)bpp;
+			bih->biClrUsed          = CalculateUsedPaletteEntries(bpp);
+			bih->biClrImportant     = bih->biClrUsed;
+			bih->biXPelsPerMeter	= 2835;	// 72 dpi
+			bih->biYPelsPerMeter	= 2835;	// 72 dpi
+
+			if(bpp == 8) {
+				// build a default greyscale palette (very useful for image processing)
+				RGBQUAD *pal = FreeImage_GetPalette(bitmap);
+				for(int i = 0; i < 256; i++) {
+					pal[i].rgbRed	= (BYTE)i;
+					pal[i].rgbGreen = (BYTE)i;
+					pal[i].rgbBlue	= (BYTE)i;
+				}
+			}
+
+			// just setting the masks (only if needed) just like the palette.
+			if (need_masks) {
+				FREEIMAGERGBMASKS *masks = FreeImage_GetRGBMasks(bitmap);
+				masks->red_mask = red_mask;
+				masks->green_mask = green_mask;
+				masks->blue_mask = blue_mask;
+			}
+
+			return bitmap;
+		}
+
+		free(bitmap);
+	}
+
+	return NULL;
+}
+
+FIBITMAP * DLL_CALLCONV
+FreeImage_AllocateHeaderForBits(BYTE *ext_bits, unsigned ext_pitch, FREE_IMAGE_TYPE type, int width, int height, int bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask) {
+	return FreeImage_AllocateBitmap(FALSE, ext_bits, ext_pitch, type, width, height, bpp, red_mask, green_mask, blue_mask);
+}
+
+FIBITMAP * DLL_CALLCONV
+FreeImage_AllocateHeaderT(BOOL header_only, FREE_IMAGE_TYPE type, int width, int height, int bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask) {
+	return FreeImage_AllocateBitmap(header_only, NULL, 0, type, width, height, bpp, red_mask, green_mask, blue_mask);
+}
+
+FIBITMAP * DLL_CALLCONV
+FreeImage_AllocateHeader(BOOL header_only, int width, int height, int bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask) {
+	return FreeImage_AllocateBitmap(header_only, NULL, 0, FIT_BITMAP, width, height, bpp, red_mask, green_mask, blue_mask);
+}
+
+FIBITMAP * DLL_CALLCONV
+FreeImage_Allocate(int width, int height, int bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask) {
+	return FreeImage_AllocateBitmap(FALSE, NULL, 0, FIT_BITMAP, width, height, bpp, red_mask, green_mask, blue_mask);
+}
+
+FIBITMAP * DLL_CALLCONV
+FreeImage_AllocateT(FREE_IMAGE_TYPE type, int width, int height, int bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask) {
+	return FreeImage_AllocateBitmap(FALSE, NULL, 0, type, width, height, bpp, red_mask, green_mask, blue_mask);
+}
+
+void DLL_CALLCONV
+FreeImage_Unload(FIBITMAP *dib) {
+	if (NULL != dib) {	
+		if (NULL != dib->data) {
+			// delete possible icc profile ...
+			if (FreeImage_GetICCProfile(dib)->data) {
+				free(FreeImage_GetICCProfile(dib)->data);
+			}
+
+			// delete metadata models
+			METADATAMAP *metadata = ((FREEIMAGEHEADER *)dib->data)->metadata;
+
+			for(METADATAMAP::iterator i = (*metadata).begin(); i != (*metadata).end(); i++) {
+				TAGMAP *tagmap = (*i).second;
+
+				if(tagmap) {
+					for(TAGMAP::iterator j = tagmap->begin(); j != tagmap->end(); j++) {
+						FITAG *tag = (*j).second;
+						FreeImage_DeleteTag(tag);
+					}
+
+					delete tagmap;
+				}
+			}
+
+			delete metadata;
+
+			// delete embedded thumbnail
+			FreeImage_Unload(FreeImage_GetThumbnail(dib));
+
+			// delete bitmap ...
+			FreeImage_Aligned_Free(dib->data);
+		}
+
+		free(dib);		// ... and the wrapper
+	}
+}
+
+// ----------------------------------------------------------
+
+FIBITMAP * DLL_CALLCONV
+FreeImage_Clone(FIBITMAP *dib) {
+	if(!dib) {
+		return NULL;
+	}
+
+	FREE_IMAGE_TYPE type = FreeImage_GetImageType(dib);
+	unsigned width	= FreeImage_GetWidth(dib);
+	unsigned height	= FreeImage_GetHeight(dib);
+	unsigned bpp	= FreeImage_GetBPP(dib);
+
+	const BYTE *ext_bits = ((FREEIMAGEHEADER *)dib->data)->external_bits;
+	
+	// check for pixel availability ...
+	BOOL header_only = FreeImage_HasPixels(dib) ? FALSE : TRUE;
+
+	// check whether this image has masks defined ...
+	BOOL need_masks = (bpp == 16 && type == FIT_BITMAP) ? TRUE : FALSE;
+
+	// allocate a new dib
+	FIBITMAP *new_dib = FreeImage_AllocateHeaderT(header_only, type, width, height, bpp,
+			FreeImage_GetRedMask(dib), FreeImage_GetGreenMask(dib), FreeImage_GetBlueMask(dib));
+
+	if (new_dib) {
+		// save ICC profile links
+		FIICCPROFILE *src_iccProfile = FreeImage_GetICCProfile(dib);
+		FIICCPROFILE *dst_iccProfile = FreeImage_GetICCProfile(new_dib);
+
+		// save metadata links
+		METADATAMAP *src_metadata = ((FREEIMAGEHEADER *)dib->data)->metadata;
+		METADATAMAP *dst_metadata = ((FREEIMAGEHEADER *)new_dib->data)->metadata;
+
+		// calculate the size of the src image
+		// align the palette and the pixels on a FIBITMAP_ALIGNMENT bytes alignment boundary
+		// palette is aligned on a 16 bytes boundary
+		// pixels are aligned on a 16 bytes boundary
+		
+		// when using a user provided pixel buffer, force a 'header only' calculation		
+
+		size_t dib_size = FreeImage_GetInternalImageSize(header_only || ext_bits, width, height, bpp, need_masks);
+
+		// copy the bitmap + internal pointers (remember to restore new_dib internal pointers later)
+		memcpy(new_dib->data, dib->data, dib_size);
+
+		// reset ICC profile link for new_dib
+		memset(dst_iccProfile, 0, sizeof(FIICCPROFILE));
+
+		// restore metadata link for new_dib
+		((FREEIMAGEHEADER *)new_dib->data)->metadata = dst_metadata;
+
+		// reset thumbnail link for new_dib
+		((FREEIMAGEHEADER *)new_dib->data)->thumbnail = NULL;
+
+		// copy possible ICC profile
+		FreeImage_CreateICCProfile(new_dib, src_iccProfile->data, src_iccProfile->size);
+		dst_iccProfile->flags = src_iccProfile->flags;
+
+		// copy metadata models
+		for(METADATAMAP::iterator i = (*src_metadata).begin(); i != (*src_metadata).end(); i++) {
+			int model = (*i).first;
+			TAGMAP *src_tagmap = (*i).second;
+
+			if(src_tagmap) {
+				// create a metadata model
+				TAGMAP *dst_tagmap = new(std::nothrow) TAGMAP();
+
+				if(dst_tagmap) {
+					// fill the model
+					for(TAGMAP::iterator j = src_tagmap->begin(); j != src_tagmap->end(); j++) {
+						std::string dst_key = (*j).first;
+						FITAG *dst_tag = FreeImage_CloneTag( (*j).second );
+
+						// assign key and tag value
+						(*dst_tagmap)[dst_key] = dst_tag;
+					}
+
+					// assign model and tagmap
+					(*dst_metadata)[model] = dst_tagmap;
+				}
+			}
+		}
+
+		// copy the thumbnail
+		FreeImage_SetThumbnail(new_dib, FreeImage_GetThumbnail(dib));
+
+		// copy user provided pixel buffer (if any)
+		if(ext_bits) {
+			const unsigned pitch = FreeImage_GetPitch(dib);
+			const unsigned linesize = FreeImage_GetLine(dib);
+			for(unsigned y = 0; y < height; y++) {
+				memcpy(FreeImage_GetScanLine(new_dib, y), ext_bits, linesize);
+				ext_bits += pitch;
+			}
+		}
+
+		return new_dib;
+	}
+
+	return NULL;
+}
+
+// ----------------------------------------------------------
+
+BYTE * DLL_CALLCONV
+FreeImage_GetBits(FIBITMAP *dib) {
+	if(!FreeImage_HasPixels(dib)) {
+		return NULL;
+	}
+
+	if(((FREEIMAGEHEADER *)dib->data)->external_bits) {
+		return ((FREEIMAGEHEADER *)dib->data)->external_bits;
+	}
+
+	// returns the pixels aligned on a FIBITMAP_ALIGNMENT bytes alignment boundary
+	size_t lp = (size_t)FreeImage_GetInfoHeader(dib);
+	lp += sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * FreeImage_GetColorsUsed(dib);
+	lp += FreeImage_HasRGBMasks(dib) ? sizeof(DWORD) * 3 : 0;
+	lp += (lp % FIBITMAP_ALIGNMENT ? FIBITMAP_ALIGNMENT - lp % FIBITMAP_ALIGNMENT : 0);
+	return (BYTE *)lp;
+}
+
+// ----------------------------------------------------------
+//  DIB information functions
+// ----------------------------------------------------------
+
+FIBITMAP* DLL_CALLCONV
+FreeImage_GetThumbnail(FIBITMAP *dib) {
+	return (dib != NULL) ? ((FREEIMAGEHEADER *)dib->data)->thumbnail : NULL;
+}
+
+BOOL DLL_CALLCONV
+FreeImage_SetThumbnail(FIBITMAP *dib, FIBITMAP *thumbnail) {
+	if(dib == NULL) {
+		return FALSE;
+	}
+	FIBITMAP *currentThumbnail = ((FREEIMAGEHEADER *)dib->data)->thumbnail;
+	if(currentThumbnail == thumbnail) {
+		return TRUE;
+	}
+	FreeImage_Unload(currentThumbnail);
+
+	((FREEIMAGEHEADER *)dib->data)->thumbnail = FreeImage_HasPixels(thumbnail) ? FreeImage_Clone(thumbnail) : NULL;
+
+	return TRUE;
+}
+
+// ----------------------------------------------------------
+
+FREE_IMAGE_COLOR_TYPE DLL_CALLCONV
+FreeImage_GetColorType(FIBITMAP *dib) {
+	RGBQUAD *rgb;
+
+	const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
+
+	// special bitmap type
+	if(image_type != FIT_BITMAP) {
+		switch(image_type) {
+			case FIT_UINT16:
+			{
+				// 16-bit greyscale TIF can be either FIC_MINISBLACK (the most common case) or FIC_MINISWHITE
+				// you can check this using EXIF_MAIN metadata
+				FITAG *photometricTag = NULL;
+				if(FreeImage_GetMetadata(FIMD_EXIF_MAIN, dib, "PhotometricInterpretation", &photometricTag)) {
+					const short *value = (short*)FreeImage_GetTagValue(photometricTag);
+					// PHOTOMETRIC_MINISWHITE = 0 => min value is white
+					// PHOTOMETRIC_MINISBLACK = 1 => min value is black
+					return (*value == 0) ? FIC_MINISWHITE : FIC_MINISBLACK;
+				}
+				return FIC_MINISBLACK;
+			}
+			break;
+			case FIT_RGB16:
+			case FIT_RGBF:
+				return FIC_RGB;
+			case FIT_RGBA16:
+			case FIT_RGBAF:
+				return FIC_RGBALPHA;
+		}
+
+		return FIC_MINISBLACK;
+	}
+
+	// standard image type
+	switch (FreeImage_GetBPP(dib)) {
+		case 1:
+		{
+			rgb = FreeImage_GetPalette(dib);
+
+			if ((rgb->rgbRed == 0) && (rgb->rgbGreen == 0) && (rgb->rgbBlue == 0)) {
+				rgb++;
+
+				if ((rgb->rgbRed == 255) && (rgb->rgbGreen == 255) && (rgb->rgbBlue == 255)) {
+					return FIC_MINISBLACK;
+				}
+			}
+
+			if ((rgb->rgbRed == 255) && (rgb->rgbGreen == 255) && (rgb->rgbBlue == 255)) {
+				rgb++;
+
+				if ((rgb->rgbRed == 0) && (rgb->rgbGreen == 0) && (rgb->rgbBlue == 0)) {
+					return FIC_MINISWHITE;
+				}
+			}
+
+			return FIC_PALETTE;
+		}
+
+		case 4:
+		case 8:	// Check if the DIB has a color or a greyscale palette
+		{
+			int ncolors = FreeImage_GetColorsUsed(dib);
+		    int minisblack = 1;
+			rgb = FreeImage_GetPalette(dib);
+
+			for (int i = 0; i < ncolors; i++) {
+				if ((rgb->rgbRed != rgb->rgbGreen) || (rgb->rgbRed != rgb->rgbBlue)) {
+					return FIC_PALETTE;
+				}
+
+				// The DIB has a color palette if the greyscale isn't a linear ramp
+				// Take care of reversed grey images
+				if (rgb->rgbRed != i) {
+					if ((ncolors-i-1) != rgb->rgbRed) {
+						return FIC_PALETTE;
+					} else {
+						minisblack = 0;
+					}
+				}
+
+				rgb++;
+			}
+
+			return minisblack ? FIC_MINISBLACK : FIC_MINISWHITE;
+		}
+
+		case 16:
+		case 24:
+			return FIC_RGB;
+
+		case 32:
+		{
+			if (FreeImage_GetICCProfile(dib)->flags & FIICC_COLOR_IS_CMYK) {
+				return FIC_CMYK;
+			}
+
+			if( FreeImage_HasPixels(dib) ) {
+				// check for fully opaque alpha layer
+				for (unsigned y = 0; y < FreeImage_GetHeight(dib); y++) {
+					rgb = (RGBQUAD *)FreeImage_GetScanLine(dib, y);
+
+					for (unsigned x = 0; x < FreeImage_GetWidth(dib); x++) {
+						if (rgb[x].rgbReserved != 0xFF) {
+							return FIC_RGBALPHA;
+						}
+					}
+				}
+				return FIC_RGB;
+			}
+
+			return FIC_RGBALPHA;
+		}
+				
+		default :
+			return FIC_MINISBLACK;
+	}
+}
+
+// ----------------------------------------------------------
+
+FREE_IMAGE_TYPE DLL_CALLCONV 
+FreeImage_GetImageType(FIBITMAP *dib) {
+	return (dib != NULL) ? ((FREEIMAGEHEADER *)dib->data)->type : FIT_UNKNOWN;
+}
+
+// ----------------------------------------------------------
+
+BOOL DLL_CALLCONV 
+FreeImage_HasPixels(FIBITMAP *dib) {
+	return (dib != NULL) ? ((FREEIMAGEHEADER *)dib->data)->has_pixels : FALSE;
+}
+
+// ----------------------------------------------------------
+
+BOOL DLL_CALLCONV
+FreeImage_HasRGBMasks(FIBITMAP *dib) {
+	return dib && FreeImage_GetInfoHeader(dib)->biCompression == BI_BITFIELDS;
+}
+
+unsigned DLL_CALLCONV
+FreeImage_GetRedMask(FIBITMAP *dib) {
+	FREEIMAGERGBMASKS *masks = NULL;
+	FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
+	switch(image_type) {
+		case FIT_BITMAP:
+			// check for 16-bit RGB (565 or 555)
+			masks = FreeImage_GetRGBMasks(dib);
+			if (masks) {
+				return masks->red_mask;
+			}
+			return FreeImage_GetBPP(dib) >= 24 ? FI_RGBA_RED_MASK : 0;
+		default:
+			return 0;
+	}
+}
+
+unsigned DLL_CALLCONV
+FreeImage_GetGreenMask(FIBITMAP *dib) {
+	FREEIMAGERGBMASKS *masks = NULL;
+	FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
+	switch(image_type) {
+		case FIT_BITMAP:
+			// check for 16-bit RGB (565 or 555)
+			masks = FreeImage_GetRGBMasks(dib);
+			if (masks) {
+				return masks->green_mask;
+			}
+			return FreeImage_GetBPP(dib) >= 24 ? FI_RGBA_GREEN_MASK : 0;
+		default:
+			return 0;
+	}
+}
+
+unsigned DLL_CALLCONV
+FreeImage_GetBlueMask(FIBITMAP *dib) {
+	FREEIMAGERGBMASKS *masks = NULL;
+	FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
+	switch(image_type) {
+		case FIT_BITMAP:
+			// check for 16-bit RGB (565 or 555)
+			masks = FreeImage_GetRGBMasks(dib);
+			if (masks) {
+				return masks->blue_mask;
+			}
+			return FreeImage_GetBPP(dib) >= 24 ? FI_RGBA_BLUE_MASK : 0;
+		default:
+			return 0;
+	}
+}
+
+// ----------------------------------------------------------
+
+BOOL DLL_CALLCONV
+FreeImage_HasBackgroundColor(FIBITMAP *dib) {
+	if(dib) {
+		RGBQUAD *bkgnd_color = &((FREEIMAGEHEADER *)dib->data)->bkgnd_color;
+		return (bkgnd_color->rgbReserved != 0) ? TRUE : FALSE;
+	}
+	return FALSE;
+}
+
+BOOL DLL_CALLCONV
+FreeImage_GetBackgroundColor(FIBITMAP *dib, RGBQUAD *bkcolor) {
+	if(dib && bkcolor) {
+		if(FreeImage_HasBackgroundColor(dib)) {
+			// get the background color
+			RGBQUAD *bkgnd_color = &((FREEIMAGEHEADER *)dib->data)->bkgnd_color;
+			memcpy(bkcolor, bkgnd_color, sizeof(RGBQUAD));
+			// get the background index
+			if(FreeImage_GetBPP(dib) == 8) {
+				RGBQUAD *pal = FreeImage_GetPalette(dib);
+				for(unsigned i = 0; i < FreeImage_GetColorsUsed(dib); i++) {
+					if(bkgnd_color->rgbRed == pal[i].rgbRed) {
+						if(bkgnd_color->rgbGreen == pal[i].rgbGreen) {
+							if(bkgnd_color->rgbBlue == pal[i].rgbBlue) {
+								bkcolor->rgbReserved = (BYTE)i;
+								return TRUE;
+							}
+						}
+					}
+				}
+			}
+
+			bkcolor->rgbReserved = 0;
+
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
+BOOL DLL_CALLCONV 
+FreeImage_SetBackgroundColor(FIBITMAP *dib, RGBQUAD *bkcolor) {
+	if(dib) {
+		RGBQUAD *bkgnd_color = &((FREEIMAGEHEADER *)dib->data)->bkgnd_color;
+		if(bkcolor) {
+			// set the background color
+			memcpy(bkgnd_color, bkcolor, sizeof(RGBQUAD));
+			// enable the file background color
+			bkgnd_color->rgbReserved = 1;
+		} else {
+			// clear and disable the file background color
+			memset(bkgnd_color, 0, sizeof(RGBQUAD));
+		}
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+// ----------------------------------------------------------
+
+BOOL DLL_CALLCONV
+FreeImage_IsTransparent(FIBITMAP *dib) {
+	if(dib) {
+		FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
+		switch(image_type) {
+			case FIT_BITMAP:
+				if(FreeImage_GetBPP(dib) == 32) {
+					if(FreeImage_GetColorType(dib) == FIC_RGBALPHA) {
+						return TRUE;
+					}
+				} else {
+					return ((FREEIMAGEHEADER *)dib->data)->transparent ? TRUE : FALSE;
+				}
+				break;
+			case FIT_RGBA16:
+			case FIT_RGBAF:
+				return TRUE;
+			default:
+				break;
+		}
+	}
+	return FALSE;
+}
+
+BYTE * DLL_CALLCONV
+FreeImage_GetTransparencyTable(FIBITMAP *dib) {
+	return dib ? ((FREEIMAGEHEADER *)dib->data)->transparent_table : NULL;
+}
+
+void DLL_CALLCONV
+FreeImage_SetTransparent(FIBITMAP *dib, BOOL enabled) {
+	if (dib) {
+		if ((FreeImage_GetBPP(dib) <= 8) || (FreeImage_GetBPP(dib) == 32)) {
+			((FREEIMAGEHEADER *)dib->data)->transparent = enabled;
+		} else {
+			((FREEIMAGEHEADER *)dib->data)->transparent = FALSE;
+		}
+	}
+}
+
+unsigned DLL_CALLCONV
+FreeImage_GetTransparencyCount(FIBITMAP *dib) {
+	return dib ? ((FREEIMAGEHEADER *)dib->data)->transparency_count : 0;
+}
+
+void DLL_CALLCONV
+FreeImage_SetTransparencyTable(FIBITMAP *dib, BYTE *table, int count) {
+	if (dib) {
+		count = MAX(0, MIN(count, 256));
+		if (FreeImage_GetBPP(dib) <= 8) {
+			((FREEIMAGEHEADER *)dib->data)->transparent = (count > 0) ? TRUE : FALSE;
+			((FREEIMAGEHEADER *)dib->data)->transparency_count = count;
+
+			if (table) {
+				memcpy(((FREEIMAGEHEADER *)dib->data)->transparent_table, table, count);
+			} else {
+				memset(((FREEIMAGEHEADER *)dib->data)->transparent_table, 0xff, count);
+			}
+		} 
+	}
+}
+
+/** @brief Sets the index of the palette entry to be used as transparent color
+ for the image specified. Does nothing on high color images. 
+ 
+ This method sets the index of the palette entry to be used as single transparent
+ color for the image specified. This works on palletised images only and does
+ nothing for high color images.
+ 
+ Although it is possible for palletised images to have more than one transparent
+ color, this method sets the palette entry specified as the single transparent
+ color for the image. All other colors will be set to be non-transparent by this
+ method.
+ 
+ As with FreeImage_SetTransparencyTable(), this method also sets the image's
+ transparency property to TRUE (as it is set and obtained by
+ FreeImage_SetTransparent() and FreeImage_IsTransparent() respectively) for
+ palletised images.
+ 
+ @param dib Input image, whose transparent color is to be set.
+ @param index The index of the palette entry to be set as transparent color.
+ */
+void DLL_CALLCONV
+FreeImage_SetTransparentIndex(FIBITMAP *dib, int index) {
+	if (dib) {
+		int count = FreeImage_GetColorsUsed(dib);
+		if (count) {
+			BYTE *new_tt = (BYTE *)malloc(count * sizeof(BYTE));
+			memset(new_tt, 0xFF, count);
+			if ((index >= 0) && (index < count)) {
+				new_tt[index] = 0x00;
+			}
+			FreeImage_SetTransparencyTable(dib, new_tt, count);
+			free(new_tt);
+		}
+	}
+}
+
+/** @brief Returns the palette entry used as transparent color for the image
+ specified. Works for palletised images only and returns -1 for high color
+ images or if the image has no color set to be transparent. 
+ 
+ Although it is possible for palletised images to have more than one transparent
+ color, this function always returns the index of the first palette entry, set
+ to be transparent. 
+ 
+ @param dib Input image, whose transparent color is to be returned.
+ @return Returns the index of the palette entry used as transparent color for
+ the image specified or -1 if there is no transparent color found (e.g. the image
+ is a high color image).
+ */
+int DLL_CALLCONV
+FreeImage_GetTransparentIndex(FIBITMAP *dib) {
+	int count = FreeImage_GetTransparencyCount(dib);
+	BYTE *tt = FreeImage_GetTransparencyTable(dib);
+	for (int i = 0; i < count; i++) {
+		if (tt[i] == 0) {
+			return i;
+		}
+	}
+	return -1;
+}
+
+// ----------------------------------------------------------
+
+FIICCPROFILE * DLL_CALLCONV
+FreeImage_GetICCProfile(FIBITMAP *dib) {
+	FIICCPROFILE *profile = (dib) ? (FIICCPROFILE *)&((FREEIMAGEHEADER *)dib->data)->iccProfile : NULL;
+	return profile;
+}
+
+FIICCPROFILE * DLL_CALLCONV
+FreeImage_CreateICCProfile(FIBITMAP *dib, void *data, long size) {
+	// clear the profile but preserve profile->flags
+	FreeImage_DestroyICCProfile(dib);
+	// create the new profile
+	FIICCPROFILE *profile = FreeImage_GetICCProfile(dib);
+	if(size && profile) {
+		profile->data = malloc(size);
+		if(profile->data) {
+			memcpy(profile->data, data, profile->size = size);
+		}
+	}
+	return profile;
+}
+
+void DLL_CALLCONV
+FreeImage_DestroyICCProfile(FIBITMAP *dib) {
+	FIICCPROFILE *profile = FreeImage_GetICCProfile(dib);
+	if(profile) {
+		if (profile->data) {
+			free (profile->data);
+		}
+		// clear the profile but preserve profile->flags
+		profile->data = NULL;
+		profile->size = 0;
+	}
+}
+
+// ----------------------------------------------------------
+
+unsigned DLL_CALLCONV
+FreeImage_GetWidth(FIBITMAP *dib) {
+	return dib ? FreeImage_GetInfoHeader(dib)->biWidth : 0;
+}
+
+unsigned DLL_CALLCONV
+FreeImage_GetHeight(FIBITMAP *dib) {
+	return (dib) ? FreeImage_GetInfoHeader(dib)->biHeight : 0;
+}
+
+unsigned DLL_CALLCONV
+FreeImage_GetBPP(FIBITMAP *dib) {
+	return dib ? FreeImage_GetInfoHeader(dib)->biBitCount : 0;
+}
+
+unsigned DLL_CALLCONV
+FreeImage_GetLine(FIBITMAP *dib) {
+	return dib ? ((FreeImage_GetWidth(dib) * FreeImage_GetBPP(dib)) + 7) / 8 : 0;
+}
+
+unsigned DLL_CALLCONV
+FreeImage_GetPitch(FIBITMAP *dib) {
+	if(dib) {
+		FREEIMAGEHEADER *fih = (FREEIMAGEHEADER *)dib->data;
+		return fih->external_bits ? fih->external_pitch : (FreeImage_GetLine(dib) + 3 & ~3);
+	}
+	return 0;
+}
+
+unsigned DLL_CALLCONV
+FreeImage_GetColorsUsed(FIBITMAP *dib) {
+	return dib ? FreeImage_GetInfoHeader(dib)->biClrUsed : 0;
+}
+
+unsigned DLL_CALLCONV
+FreeImage_GetDIBSize(FIBITMAP *dib) {
+	return (dib) ? sizeof(BITMAPINFOHEADER) + (FreeImage_GetColorsUsed(dib) * sizeof(RGBQUAD)) + (FreeImage_GetPitch(dib) * FreeImage_GetHeight(dib)) : 0;
+}
+
+RGBQUAD * DLL_CALLCONV
+FreeImage_GetPalette(FIBITMAP *dib) {
+	return (dib && FreeImage_GetBPP(dib) < 16) ? (RGBQUAD *)(((BYTE *)FreeImage_GetInfoHeader(dib)) + sizeof(BITMAPINFOHEADER)) : NULL;
+}
+
+unsigned DLL_CALLCONV
+FreeImage_GetDotsPerMeterX(FIBITMAP *dib) {
+	return (dib) ? FreeImage_GetInfoHeader(dib)->biXPelsPerMeter : 0;
+}
+
+unsigned DLL_CALLCONV
+FreeImage_GetDotsPerMeterY(FIBITMAP *dib) {
+	return (dib) ? FreeImage_GetInfoHeader(dib)->biYPelsPerMeter : 0;
+}
+
+void DLL_CALLCONV
+FreeImage_SetDotsPerMeterX(FIBITMAP *dib, unsigned res) {
+	if(dib) {
+		FreeImage_GetInfoHeader(dib)->biXPelsPerMeter = res;
+	}
+}
+
+void DLL_CALLCONV
+FreeImage_SetDotsPerMeterY(FIBITMAP *dib, unsigned res) {
+	if(dib) {
+		FreeImage_GetInfoHeader(dib)->biYPelsPerMeter = res;
+	}
+}
+
+BITMAPINFOHEADER * DLL_CALLCONV
+FreeImage_GetInfoHeader(FIBITMAP *dib) {
+	if(!dib) {
+		return NULL;
+	}
+	size_t lp = (size_t)dib->data + sizeof(FREEIMAGEHEADER);
+	lp += (lp % FIBITMAP_ALIGNMENT ? FIBITMAP_ALIGNMENT - lp % FIBITMAP_ALIGNMENT : 0);
+	lp += FIBITMAP_ALIGNMENT - sizeof(BITMAPINFOHEADER) % FIBITMAP_ALIGNMENT;
+	return (BITMAPINFOHEADER *)lp;
+}
+
+BITMAPINFO * DLL_CALLCONV
+FreeImage_GetInfo(FIBITMAP *dib) {
+	return (BITMAPINFO *)FreeImage_GetInfoHeader(dib);
+}
+
+// ----------------------------------------------------------
+//  Metadata routines
+// ----------------------------------------------------------
+
+FIMETADATA * DLL_CALLCONV 
+FreeImage_FindFirstMetadata(FREE_IMAGE_MDMODEL model, FIBITMAP *dib, FITAG **tag) {
+	if(!dib) {
+		return NULL;
+	}
+
+	// get the metadata model
+	METADATAMAP *metadata = ((FREEIMAGEHEADER *)dib->data)->metadata;
+	TAGMAP *tagmap = NULL;
+	if( (*metadata).find(model) != (*metadata).end() ) {
+		tagmap = (*metadata)[model];
+	}
+	if(tagmap) {
+		// allocate a handle
+		FIMETADATA 	*handle = (FIMETADATA *)malloc(sizeof(FIMETADATA));
+		if(handle) {
+			// calculate the size of a METADATAHEADER
+			int header_size = sizeof(METADATAHEADER);
+
+			handle->data = (BYTE *)malloc(header_size * sizeof(BYTE));
+			
+			if(handle->data) {
+				memset(handle->data, 0, header_size * sizeof(BYTE));
+
+				// write out the METADATAHEADER
+				METADATAHEADER *mdh = (METADATAHEADER *)handle->data;
+
+				mdh->pos = 1;
+				mdh->tagmap = tagmap;
+
+				// get the first element
+				TAGMAP::iterator i = tagmap->begin();
+				*tag = (*i).second;
+
+				return handle;
+			}
+
+			free(handle);
+		}
+	}
+
+	return NULL;
+}
+
+BOOL DLL_CALLCONV 
+FreeImage_FindNextMetadata(FIMETADATA *mdhandle, FITAG **tag) {
+	if(!mdhandle) {
+		return FALSE;
+	}
+
+	METADATAHEADER *mdh = (METADATAHEADER *)mdhandle->data;
+	TAGMAP *tagmap = mdh->tagmap;
+
+	int current_pos = mdh->pos;
+	int mapsize     = (int)tagmap->size();
+
+	if(current_pos < mapsize) {
+		// get the tag element at position pos
+		int count = 0;
+
+		for(TAGMAP::iterator i = tagmap->begin(); i != tagmap->end(); i++) {
+			if(count == current_pos) {
+				*tag = (*i).second;
+				mdh->pos++;
+				break;
+			}
+			count++;
+		}
+		
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+void DLL_CALLCONV 
+FreeImage_FindCloseMetadata(FIMETADATA *mdhandle) {
+	if (NULL != mdhandle) {	// delete the handle
+		if (NULL != mdhandle->data) {
+			free(mdhandle->data);
+		}
+		free(mdhandle);		// ... and the wrapper
+	}
+}
+
+
+// ----------------------------------------------------------
+
+BOOL DLL_CALLCONV
+FreeImage_CloneMetadata(FIBITMAP *dst, FIBITMAP *src) {
+	if(!src || !dst) {
+		return FALSE;
+	}
+
+	// get metadata links
+	METADATAMAP *src_metadata = ((FREEIMAGEHEADER *)src->data)->metadata;
+	METADATAMAP *dst_metadata = ((FREEIMAGEHEADER *)dst->data)->metadata;
+
+	// copy metadata models, *except* the FIMD_ANIMATION model
+	for(METADATAMAP::iterator i = (*src_metadata).begin(); i != (*src_metadata).end(); i++) {
+		int model = (*i).first;
+		if(model == (int)FIMD_ANIMATION) {
+			continue;
+		}
+		TAGMAP *src_tagmap = (*i).second;
+
+		if(src_tagmap) {
+			if( dst_metadata->find(model) != dst_metadata->end() ) {
+				// destroy dst model
+				FreeImage_SetMetadata((FREE_IMAGE_MDMODEL)model, dst, NULL, NULL);
+			}
+
+			// create a metadata model
+			TAGMAP *dst_tagmap = new(std::nothrow) TAGMAP();
+
+			if(dst_tagmap) {
+				// fill the model
+				for(TAGMAP::iterator j = src_tagmap->begin(); j != src_tagmap->end(); j++) {
+					std::string dst_key = (*j).first;
+					FITAG *dst_tag = FreeImage_CloneTag( (*j).second );
+
+					// assign key and tag value
+					(*dst_tagmap)[dst_key] = dst_tag;
+				}
+
+				// assign model and tagmap
+				(*dst_metadata)[model] = dst_tagmap;
+			}
+		}
+	}
+
+	// clone resolution 
+	FreeImage_SetDotsPerMeterX(dst, FreeImage_GetDotsPerMeterX(src)); 
+	FreeImage_SetDotsPerMeterY(dst, FreeImage_GetDotsPerMeterY(src)); 
+
+	return TRUE;
+}
+
+// ----------------------------------------------------------
+
+BOOL DLL_CALLCONV 
+FreeImage_SetMetadata(FREE_IMAGE_MDMODEL model, FIBITMAP *dib, const char *key, FITAG *tag) {
+	if(!dib) {
+		return FALSE;
+	}
+
+	TAGMAP *tagmap = NULL;
+
+	// get the metadata model
+	METADATAMAP *metadata = ((FREEIMAGEHEADER *)dib->data)->metadata;
+	METADATAMAP::iterator model_iterator = metadata->find(model);
+	if (model_iterator != metadata->end()) {
+		tagmap = model_iterator->second;
+	}
+
+	if(key != NULL) {
+
+		if(!tagmap) {
+			// this model, doesn't exist: create it 
+			tagmap = new(std::nothrow) TAGMAP();
+			(*metadata)[model] = tagmap;
+		}
+		
+		if(tag) {
+			// first check the tag
+			if(FreeImage_GetTagKey(tag) == NULL) {
+				FreeImage_SetTagKey(tag, key);
+			} else if(strcmp(key, FreeImage_GetTagKey(tag)) != 0) {
+				// set the tag key
+				FreeImage_SetTagKey(tag, key);
+			}
+			if(FreeImage_GetTagCount(tag) * FreeImage_TagDataWidth(FreeImage_GetTagType(tag)) != FreeImage_GetTagLength(tag)) {
+				FreeImage_OutputMessageProc(FIF_UNKNOWN, "Invalid data count for tag '%s'", key);
+				return FALSE;
+			}
+
+			// fill the tag ID if possible and if it's needed
+			TagLib& tag_lib = TagLib::instance();
+			switch(model) {
+				case FIMD_IPTC:
+				{
+					int id = tag_lib.getTagID(TagLib::IPTC, key);
+					/*
+					if(id == -1) {
+						FreeImage_OutputMessageProc(FIF_UNKNOWN, "IPTC: Invalid key '%s'", key);
+					}
+					*/
+					FreeImage_SetTagID(tag, (WORD)id);
+				}
+				break;
+
+				default:
+					break;
+			}
+
+			// delete existing tag
+			FITAG *old_tag = (*tagmap)[key];
+			if(old_tag) {
+				FreeImage_DeleteTag(old_tag);
+			}
+
+			// create a new tag
+			(*tagmap)[key] = FreeImage_CloneTag(tag);
+		}
+		else {
+			// delete existing tag
+			TAGMAP::iterator i = tagmap->find(key);
+			if(i != tagmap->end()) {
+				FITAG *old_tag = (*i).second;
+				FreeImage_DeleteTag(old_tag);
+				tagmap->erase(key);
+			}
+		}
+	}
+	else {
+		// destroy the metadata model
+		if(tagmap) {
+			for(TAGMAP::iterator i = tagmap->begin(); i != tagmap->end(); i++) {
+				FITAG *tag = (*i).second;
+				FreeImage_DeleteTag(tag);
+			}
+
+			delete tagmap;
+			metadata->erase(model_iterator);
+		}
+	}
+
+	return TRUE;
+}
+
+BOOL DLL_CALLCONV 
+FreeImage_GetMetadata(FREE_IMAGE_MDMODEL model, FIBITMAP *dib, const char *key, FITAG **tag) {
+	if(!dib || !key || !tag) {
+		return FALSE;
+	}
+
+	TAGMAP *tagmap = NULL;
+	*tag = NULL;
+
+	// get the metadata model
+	METADATAMAP *metadata = ((FREEIMAGEHEADER *)dib->data)->metadata;
+	if(!(*metadata).empty()) {
+		METADATAMAP::iterator model_iterator = metadata->find(model);
+		if (model_iterator != metadata->end() ) {
+			// this model exists : try to get the requested tag
+			tagmap = model_iterator->second;
+			TAGMAP::iterator tag_iterator = tagmap->find(key);
+			if (tag_iterator != tagmap->end() ) {
+				// get the requested tag
+				*tag = tag_iterator->second;
+			} 
+		}
+	}
+
+	return (*tag != NULL) ? TRUE : FALSE;
+}
+
+/**
+Build and set a FITAG whose type is FIDT_ASCII. 
+ at param model Metadata model to be filled
+ at param dib Image to be filled
+ at param key Tag key
+ at param value Tag value as a ASCII string
+ at return Returns TRUE if successful, returns FALSE otherwise
+*/
+BOOL DLL_CALLCONV 
+FreeImage_SetMetadataKeyValue(FREE_IMAGE_MDMODEL model, FIBITMAP *dib, const char *key, const char *value) {
+	if(!dib || !key || !value) {
+		return FALSE;
+	}
+	// create a tag
+	FITAG *tag = FreeImage_CreateTag();
+	if(tag) {
+		BOOL bSuccess = TRUE;
+		// fill the tag
+		DWORD tag_length = (DWORD)(strlen(value) + 1);
+		bSuccess &= FreeImage_SetTagKey(tag, key);
+		bSuccess &= FreeImage_SetTagLength(tag, tag_length);
+		bSuccess &= FreeImage_SetTagCount(tag, tag_length);
+		bSuccess &= FreeImage_SetTagType(tag, FIDT_ASCII);
+		bSuccess &= FreeImage_SetTagValue(tag, value);
+		if(bSuccess) {
+			// set the tag
+			bSuccess &= FreeImage_SetMetadata(model, dib, FreeImage_GetTagKey(tag), tag);
+		}
+		// delete the tag
+		FreeImage_DeleteTag(tag);
+
+		return bSuccess;
+	}
+
+	return FALSE;
+}
+
+// ----------------------------------------------------------
+
+unsigned DLL_CALLCONV 
+FreeImage_GetMetadataCount(FREE_IMAGE_MDMODEL model, FIBITMAP *dib) {
+	if(!dib) {
+		return FALSE;
+	}
+
+	TAGMAP *tagmap = NULL;
+
+	// get the metadata model
+	METADATAMAP *metadata = ((FREEIMAGEHEADER *)dib->data)->metadata;
+	if( (*metadata).find(model) != (*metadata).end() ) {
+		tagmap = (*metadata)[model];
+	}
+	if(!tagmap) {
+		// this model, doesn't exist: return
+		return 0;
+	}
+
+	// get the tag count
+	return (unsigned)tagmap->size();
+}
+
+// ----------------------------------------------------------
+
+unsigned DLL_CALLCONV
+FreeImage_GetMemorySize(FIBITMAP *dib) {
+	if (!dib) {
+		return 0;
+	}
+	FREEIMAGEHEADER *header = (FREEIMAGEHEADER *)dib->data;
+	BITMAPINFOHEADER *bih = FreeImage_GetInfoHeader(dib);
+
+	BOOL header_only = !header->has_pixels || header->external_bits != NULL;
+	BOOL need_masks = bih->biCompression == BI_BITFIELDS;
+	unsigned width = bih->biWidth;
+	unsigned height = bih->biHeight;
+	unsigned bpp = bih->biBitCount;
+	
+	// start off with the size of the FIBITMAP structure
+	size_t size = sizeof(FIBITMAP);
+	
+	// add sizes of FREEIMAGEHEADER, BITMAPINFOHEADER, palette and DIB data
+	size += FreeImage_GetInternalImageSize(header_only, width, height, bpp, need_masks);
+
+	// add ICC profile size
+	size += header->iccProfile.size;
+
+	// add thumbnail image size
+	if (header->thumbnail) {
+		// we assume a thumbnail not having a thumbnail as well, 
+		// so this recursive call should not create an infinite loop
+		size += FreeImage_GetMemorySize(header->thumbnail);
+	}
+
+	// add metadata size
+	METADATAMAP *md = header->metadata;
+	if (!md) {
+		return (unsigned)size;
+	}
+
+	// add size of METADATAMAP
+	size += sizeof(METADATAMAP);
+
+	const size_t models = md->size();
+	if (models == 0) {
+		return (unsigned)size;
+	}
+
+	unsigned tags = 0;
+
+	for (METADATAMAP::iterator i = md->begin(); i != md->end(); i++) {
+		TAGMAP *tm = i->second;
+		if (tm) {
+			for (TAGMAP::iterator j = tm->begin(); j != tm->end(); j++) {
+				++tags;
+				const std::string & key = j->first;
+				size += key.capacity();
+				size += FreeImage_GetTagMemorySize(j->second);
+			}
+		}
+	}
+
+	// add size of all TAGMAP instances
+	size += models * sizeof(TAGMAP);
+	// add size of tree nodes in METADATAMAP
+	size += MapIntrospector<METADATAMAP>::GetNodesMemorySize(models);
+	// add size of tree nodes in TAGMAP
+	size += MapIntrospector<TAGMAP>::GetNodesMemorySize(tags);
+
+	return (unsigned)size;
+}
+
diff --git a/Source/FreeImage/ColorLookup.cpp b/Source/FreeImage/ColorLookup.cpp
index 5f677ee..0f4435a 100644
--- a/Source/FreeImage/ColorLookup.cpp
+++ b/Source/FreeImage/ColorLookup.cpp
@@ -26,10 +26,10 @@
 // RGB color names  ---------------------------------------------------------
 
 typedef struct tagNamedColor {
-        const char *name;     // color name
-        BYTE  r;        // red value
-        BYTE  g;        // green value
-        BYTE  b;        // blue value
+	const char *name;	//! color name
+	BYTE  r;			//! red value
+	BYTE  g;			//! green value
+	BYTE  b;			//! blue value
 } NamedColor;
 
 // --------------------------------------------------------------------------
@@ -43,20 +43,21 @@ Helper function : perform a binary search on a color array
 */
 static int
 binsearch(const char *name, const NamedColor *color_array, int n) {
-    int cond, low, mid, high;
+	int cond, low, mid, high;
 
     low = 0;
     high = n - 1;
     while (low <= high) {
-                mid = (low + high) / 2;
-                if ((cond = strcmp(name, color_array[mid].name)) < 0)
-                        high = mid - 1;
-                else if (cond > 0)
-                        low = mid + 1;
-                else
-                        return mid;
-        }
-    return -1;
+		mid = (low + high) / 2;
+		if ((cond = strcmp(name, color_array[mid].name)) < 0) {
+			high = mid - 1;
+		} else if (cond > 0) {
+			low = mid + 1;
+		} else {
+			return mid;
+		}
+	}
+	return -1;
 }
 
 /**
@@ -68,22 +69,24 @@ Perform a binary search on a color array
 */
 static int
 FreeImage_LookupNamedColor(const char *szColor, const NamedColor *color_array, int ncolors) {
-    int i;
+	int i;
     char color[64];
 
     // make lower case name, squezze white space
 
     for (i = 0; szColor[i] && i < sizeof(color) - 1; i++) {
-        if (isspace(szColor[i]))
+		if (isspace(szColor[i])) {
             continue;
-        if (isupper(szColor[i]))
-            color[i] = (char)tolower(szColor[i]);
-        else
+		}
+		if (isupper(szColor[i])) {
+			color[i] = (char)tolower(szColor[i]);
+		} else {
             color[i] = szColor[i];
+		}
     }
     color[i] = 0;
 
-    return (binsearch(color, color_array, ncolors));
+    return binsearch(color, color_array, ncolors);
 }
 
 // ==========================================================
@@ -595,153 +598,153 @@ FreeImage_LookupX11Color(const char *szColor, BYTE *nRed, BYTE *nGreen, BYTE *nB
  the final recommendation for changes)
 */
 static NamedColor SVGColorMap[] = {
-        { "aliceblue",                  240, 248, 255 },
-        { "antiquewhite",               250, 235, 215 },
-        { "aqua",                         0, 255, 255 },
-        { "aquamarine",                 127, 255, 212 },
-        { "azure",                      240, 255, 255 },
-        { "beige",                      245, 245, 220 },
-        { "bisque",                     255, 228, 196 },
-        { "black",                        0,   0,   0 },
-        { "blanchedalmond",             255, 235, 205 },
-        { "blue",                         0,   0, 255 },
-        { "blueviolet",                 138,  43, 226 },
-        { "brown",                      165,  42,  42 },
-        { "burlywood",                  222, 184, 135 },
-        { "cadetblue",                   95, 158, 160 },
-        { "chartreuse",                 127, 255,   0 },
-        { "chocolate",                  210, 105,  30 },
-        { "coral",                      255, 127,  80 },
-        { "cornflowerblue",             100, 149, 237 },
-        { "cornsilk",                   255, 248, 220 },
-        { "crimson",                    220,  20,  60 },
-        { "cyan",                         0, 255, 255 },
-        { "darkblue",                     0,   0, 139 },
-        { "darkcyan",                     0, 139, 139 },
-        { "darkgoldenrod",              184, 134,  11 },
-        { "darkgray",                   169, 169, 169 },
-        { "darkgreen",                    0, 100,   0 },
-        { "darkgrey",                   169, 169, 169 },
-        { "darkkhaki",                  189, 183, 107 },
-        { "darkmagenta",                139,   0, 139 },
-        { "darkolivegreen",              85, 107,  47 },
-        { "darkorange",                 255, 140,   0 },
-        { "darkorchid",                 153,  50, 204 },
-        { "darkred",                    139,   0,   0 },
-        { "darksalmon",                 233, 150, 122 },
-        { "darkseagreen",               143, 188, 143 },
-        { "darkslateblue",               72,  61, 139 },
-        { "darkslategray",               47,  79,  79 },
-        { "darkslategrey",               47,  79,  79 },
-        { "darkturquoise",                0, 206, 209 },
-        { "darkviolet",                 148,   0, 211 },
-        { "deeppink",                   255,  20, 147 },
-        { "deepskyblue",                  0, 191, 255 },
-        { "dimgray",                    105, 105, 105 },
-        { "dimgrey",                    105, 105, 105 },
-        { "dodgerblue",                  30, 144, 255 },
-        { "firebrick",                  178,  34,  34 },
-        { "floralwhite",                255, 250, 240 },
-        { "forestgreen",                 34, 139,  34 },
-        { "fuchsia",                    255,   0, 255 },
-        { "gainsboro",                  220, 220, 220 },
-        { "ghostwhite",                 248, 248, 255 },
-        { "gold",                       255, 215,   0 },
-        { "goldenrod",                  218, 165,  32 },
-        { "gray",                       128, 128, 128 },
-        { "grey",                       128, 128, 128 },
-        { "green",                        0, 128,   0 },
-        { "greenyellow",                173, 255,  47 },
-        { "honeydew",                   240, 255, 240 },
-        { "hotpink",                    255, 105, 180 },
-        { "indianred",                  205,  92,  92 },
-        { "indigo",                      75,   0, 130 },
-        { "ivory",                      255, 255, 240 },
-        { "khaki",                      240, 230, 140 },
-        { "lavender",                   230, 230, 250 },
-        { "lavenderblush",              255, 240, 245 },
-        { "lawngreen",                  124, 252,   0 },
-        { "lemonchiffon",               255, 250, 205 },
-        { "lightblue",                  173, 216, 230 },
-        { "lightcoral",                 240, 128, 128 },
-        { "lightcyan",                  224, 255, 255 },
-        { "lightgoldenrodyellow",       250, 250, 210 },
-        { "lightgray",                  211, 211, 211 },
-        { "lightgreen",                 144, 238, 144 },
-        { "lightgrey",                  211, 211, 211 },
-        { "lightpink",                  255, 182, 193 },
-        { "lightsalmon",                255, 160, 122 },
-        { "lightseagreen",               32, 178, 170 },
-        { "lightskyblue",               135, 206, 250 },
-        { "lightslategray",             119, 136, 153 },
-        { "lightslategrey",             119, 136, 153 },
-        { "lightsteelblue",             176, 196, 222 },
-        { "lightyellow",                255, 255, 224 },
-        { "lime",                         0, 255,   0 },
-        { "limegreen",                   50, 205,  50 },
-        { "linen",                      250, 240, 230 },
-        { "magenta",                    255,   0, 255 },
-        { "maroon",                     128,   0,   0 },
-        { "mediumaquamarine",           102, 205, 170 },
-        { "mediumblue",                   0,   0, 205 },
-        { "mediumorchid",               186,  85, 211 },
-        { "mediumpurple",               147, 112, 219 },
-        { "mediumseagreen",              60, 179, 113 },
-        { "mediumslateblue",            123, 104, 238 },
-        { "mediumspringgreen",            0, 250, 154 },
-        { "mediumturquoise",             72, 209, 204 },
-        { "mediumvioletred",            199,  21, 133 },
-        { "midnightblue",                25,  25, 112 },
-        { "mintcream",                  245, 255, 250 },
-        { "mistyrose",                  255, 228, 225 },
-        { "moccasin",                   255, 228, 181 },
-        { "navajowhite",                255, 222, 173 },
-        { "navy",                         0,   0, 128 },
-        { "oldlace",                    253, 245, 230 },
-        { "olive",                      128, 128,   0 },
-        { "olivedrab",                  107, 142,  35 },
-        { "orange",                     255, 165,   0 },
-        { "orangered",                  255,  69,   0 },
-        { "orchid",                     218, 112, 214 },
-        { "palegoldenrod",              238, 232, 170 },
-        { "palegreen",                  152, 251, 152 },
-        { "paleturquoise",              175, 238, 238 },
-        { "palevioletred",              219, 112, 147 },
-        { "papayawhip",                 255, 239, 213 },
-        { "peachpuff",                  255, 218, 185 },
-        { "peru",                       205, 133,  63 },
-        { "pink",                       255, 192, 203 },
-        { "plum",                       221, 160, 221 },
-        { "powderblue",                 176, 224, 230 },
-        { "purple",                     128,   0, 128 },
-        { "red",                        255,   0,   0 },
-        { "rosybrown",                  188, 143, 143 },
-        { "royalblue",                   65, 105, 225 },
-        { "saddlebrown",                139,  69,  19 },
-        { "salmon",                     250, 128, 114 },
-        { "sandybrown",                 244, 164,  96 },
-        { "seagreen",                    46, 139,  87 },
-        { "seashell",                   255, 245, 238 },
-        { "sienna",                     160,  82,  45 },
-        { "silver",                     192, 192, 192 },
-        { "skyblue",                    135, 206, 235 },
-        { "slateblue",                  106,  90, 205 },
-        { "slategray",                  112, 128, 144 },
-        { "slategrey",                  112, 128, 144 },
-        { "snow",                       255, 250, 250 },
-        { "springgreen",                  0, 255, 127 },
-        { "steelblue",                   70, 130, 180 },
-        { "tan",                        210, 180, 140 },
-        { "teal",                         0, 128, 128 },
-        { "thistle",                    216, 191, 216 },
-        { "tomato",                     255,  99,  71 },
-        { "turquoise",                   64, 224, 208 },
-        { "violet",                     238, 130, 238 },
-        { "wheat",                      245, 222, 179 },
-        { "white",                      255, 255, 255 },
-        { "whitesmoke",                 245, 245, 245 },
-        { "yellow",                     255, 255,   0 },
-        { "yellowgreen",                154, 205,  50 }
+	{ "aliceblue",                  240, 248, 255 },
+	{ "antiquewhite",               250, 235, 215 },
+	{ "aqua",                         0, 255, 255 },
+	{ "aquamarine",                 127, 255, 212 },
+	{ "azure",                      240, 255, 255 },
+	{ "beige",                      245, 245, 220 },
+	{ "bisque",                     255, 228, 196 },
+	{ "black",                        0,   0,   0 },
+	{ "blanchedalmond",             255, 235, 205 },
+	{ "blue",                         0,   0, 255 },
+	{ "blueviolet",                 138,  43, 226 },
+	{ "brown",                      165,  42,  42 },
+	{ "burlywood",                  222, 184, 135 },
+	{ "cadetblue",                   95, 158, 160 },
+	{ "chartreuse",                 127, 255,   0 },
+	{ "chocolate",                  210, 105,  30 },
+	{ "coral",                      255, 127,  80 },
+	{ "cornflowerblue",             100, 149, 237 },
+	{ "cornsilk",                   255, 248, 220 },
+	{ "crimson",                    220,  20,  60 },
+	{ "cyan",                         0, 255, 255 },
+	{ "darkblue",                     0,   0, 139 },
+	{ "darkcyan",                     0, 139, 139 },
+	{ "darkgoldenrod",              184, 134,  11 },
+	{ "darkgray",                   169, 169, 169 },
+	{ "darkgreen",                    0, 100,   0 },
+	{ "darkgrey",                   169, 169, 169 },
+	{ "darkkhaki",                  189, 183, 107 },
+	{ "darkmagenta",                139,   0, 139 },
+	{ "darkolivegreen",              85, 107,  47 },
+	{ "darkorange",                 255, 140,   0 },
+	{ "darkorchid",                 153,  50, 204 },
+	{ "darkred",                    139,   0,   0 },
+	{ "darksalmon",                 233, 150, 122 },
+	{ "darkseagreen",               143, 188, 143 },
+	{ "darkslateblue",               72,  61, 139 },
+	{ "darkslategray",               47,  79,  79 },
+	{ "darkslategrey",               47,  79,  79 },
+	{ "darkturquoise",                0, 206, 209 },
+	{ "darkviolet",                 148,   0, 211 },
+	{ "deeppink",                   255,  20, 147 },
+	{ "deepskyblue",                  0, 191, 255 },
+	{ "dimgray",                    105, 105, 105 },
+	{ "dimgrey",                    105, 105, 105 },
+	{ "dodgerblue",                  30, 144, 255 },
+	{ "firebrick",                  178,  34,  34 },
+	{ "floralwhite",                255, 250, 240 },
+	{ "forestgreen",                 34, 139,  34 },
+	{ "fuchsia",                    255,   0, 255 },
+	{ "gainsboro",                  220, 220, 220 },
+	{ "ghostwhite",                 248, 248, 255 },
+	{ "gold",                       255, 215,   0 },
+	{ "goldenrod",                  218, 165,  32 },
+	{ "gray",                       128, 128, 128 },
+	{ "green",                        0, 128,   0 },
+	{ "greenyellow",                173, 255,  47 },
+	{ "grey",                       128, 128, 128 },
+	{ "honeydew",                   240, 255, 240 },
+	{ "hotpink",                    255, 105, 180 },
+	{ "indianred",                  205,  92,  92 },
+	{ "indigo",                      75,   0, 130 },
+	{ "ivory",                      255, 255, 240 },
+	{ "khaki",                      240, 230, 140 },
+	{ "lavender",                   230, 230, 250 },
+	{ "lavenderblush",              255, 240, 245 },
+	{ "lawngreen",                  124, 252,   0 },
+	{ "lemonchiffon",               255, 250, 205 },
+	{ "lightblue",                  173, 216, 230 },
+	{ "lightcoral",                 240, 128, 128 },
+	{ "lightcyan",                  224, 255, 255 },
+	{ "lightgoldenrodyellow",       250, 250, 210 },
+	{ "lightgray",                  211, 211, 211 },
+	{ "lightgreen",                 144, 238, 144 },
+	{ "lightgrey",                  211, 211, 211 },
+	{ "lightpink",                  255, 182, 193 },
+	{ "lightsalmon",                255, 160, 122 },
+	{ "lightseagreen",               32, 178, 170 },
+	{ "lightskyblue",               135, 206, 250 },
+	{ "lightslategray",             119, 136, 153 },
+	{ "lightslategrey",             119, 136, 153 },
+	{ "lightsteelblue",             176, 196, 222 },
+	{ "lightyellow",                255, 255, 224 },
+	{ "lime",                         0, 255,   0 },
+	{ "limegreen",                   50, 205,  50 },
+	{ "linen",                      250, 240, 230 },
+	{ "magenta",                    255,   0, 255 },
+	{ "maroon",                     128,   0,   0 },
+	{ "mediumaquamarine",           102, 205, 170 },
+	{ "mediumblue",                   0,   0, 205 },
+	{ "mediumorchid",               186,  85, 211 },
+	{ "mediumpurple",               147, 112, 219 },
+	{ "mediumseagreen",              60, 179, 113 },
+	{ "mediumslateblue",            123, 104, 238 },
+	{ "mediumspringgreen",            0, 250, 154 },
+	{ "mediumturquoise",             72, 209, 204 },
+	{ "mediumvioletred",            199,  21, 133 },
+	{ "midnightblue",                25,  25, 112 },
+	{ "mintcream",                  245, 255, 250 },
+	{ "mistyrose",                  255, 228, 225 },
+	{ "moccasin",                   255, 228, 181 },
+	{ "navajowhite",                255, 222, 173 },
+	{ "navy",                         0,   0, 128 },
+	{ "oldlace",                    253, 245, 230 },
+	{ "olive",                      128, 128,   0 },
+	{ "olivedrab",                  107, 142,  35 },
+	{ "orange",                     255, 165,   0 },
+	{ "orangered",                  255,  69,   0 },
+	{ "orchid",                     218, 112, 214 },
+	{ "palegoldenrod",              238, 232, 170 },
+	{ "palegreen",                  152, 251, 152 },
+	{ "paleturquoise",              175, 238, 238 },
+	{ "palevioletred",              219, 112, 147 },
+	{ "papayawhip",                 255, 239, 213 },
+	{ "peachpuff",                  255, 218, 185 },
+	{ "peru",                       205, 133,  63 },
+	{ "pink",                       255, 192, 203 },
+	{ "plum",                       221, 160, 221 },
+	{ "powderblue",                 176, 224, 230 },
+	{ "purple",                     128,   0, 128 },
+	{ "red",                        255,   0,   0 },
+	{ "rosybrown",                  188, 143, 143 },
+	{ "royalblue",                   65, 105, 225 },
+	{ "saddlebrown",                139,  69,  19 },
+	{ "salmon",                     250, 128, 114 },
+	{ "sandybrown",                 244, 164,  96 },
+	{ "seagreen",                    46, 139,  87 },
+	{ "seashell",                   255, 245, 238 },
+	{ "sienna",                     160,  82,  45 },
+	{ "silver",                     192, 192, 192 },
+	{ "skyblue",                    135, 206, 235 },
+	{ "slateblue",                  106,  90, 205 },
+	{ "slategray",                  112, 128, 144 },
+	{ "slategrey",                  112, 128, 144 },
+	{ "snow",                       255, 250, 250 },
+	{ "springgreen",                  0, 255, 127 },
+	{ "steelblue",                   70, 130, 180 },
+	{ "tan",                        210, 180, 140 },
+	{ "teal",                         0, 128, 128 },
+	{ "thistle",                    216, 191, 216 },
+	{ "tomato",                     255,  99,  71 },
+	{ "turquoise",                   64, 224, 208 },
+	{ "violet",                     238, 130, 238 },
+	{ "wheat",                      245, 222, 179 },
+	{ "white",                      255, 255, 255 },
+	{ "whitesmoke",                 245, 245, 245 },
+	{ "yellow",                     255, 255,   0 },
+	{ "yellowgreen",                154, 205,  50 }
 };
 
 
diff --git a/Source/FreeImage/Conversion.cpp b/Source/FreeImage/Conversion.cpp
index 04cec65..815057a 100644
--- a/Source/FreeImage/Conversion.cpp
+++ b/Source/FreeImage/Conversion.cpp
@@ -6,6 +6,7 @@
 // - Hervé Drolon (drolon at infonie.fr)
 // - Jani Kajala (janik at remedy.fi)
 // - Mihail Naydenov (mnaydenov at users.sourceforge.net)
+// - Carsten Klein (cklein05 at users.sourceforge.net)
 //
 // This file is part of FreeImage 3
 //
@@ -372,7 +373,8 @@ FreeImage_ColorQuantizeEx(FIBITMAP *dib, FREE_IMAGE_QUANTIZE quantize, int Palet
 	if( ReserveSize < 0 ) ReserveSize = 0;
 	if( ReserveSize > PaletteSize ) ReserveSize = PaletteSize;
 	if (FreeImage_HasPixels(dib)) {
-		if (FreeImage_GetBPP(dib) == 24) {
+		const unsigned bpp = FreeImage_GetBPP(dib);
+		if((FreeImage_GetImageType(dib) == FIT_BITMAP) && (bpp == 24 || bpp == 32)) {
 			switch(quantize) {
 				case FIQ_WUQUANT :
 				{
@@ -387,9 +389,14 @@ FreeImage_ColorQuantizeEx(FIBITMAP *dib, FREE_IMAGE_QUANTIZE quantize, int Palet
 					} catch (const char *) {
 						return NULL;
 					}
+					break;
 				}
 				case FIQ_NNQUANT :
 				{
+					if (bpp == 32) {
+						// 32-bit images not supported by NNQUANT
+						return NULL;
+					}
 					// sampling factor in range 1..30. 
 					// 1 => slower (but better), 30 => faster. Default value is 1
 					const int sampling = 1;
@@ -402,6 +409,16 @@ FreeImage_ColorQuantizeEx(FIBITMAP *dib, FREE_IMAGE_QUANTIZE quantize, int Palet
 					}
 					return dst;
 				}
+				case FIQ_LFPQUANT :
+				{
+					LFPQuantizer Q(PaletteSize);
+					FIBITMAP *dst = Q.Quantize(dib, ReserveSize, ReservePalette);
+					if(dst) {
+						// copy metadata from src to dst
+						FreeImage_CloneMetadata(dst, dib);
+					}
+					return dst;
+				}
 			}
 		}
 	}
@@ -412,26 +429,47 @@ FreeImage_ColorQuantizeEx(FIBITMAP *dib, FREE_IMAGE_QUANTIZE quantize, int Palet
 // ==========================================================
 
 FIBITMAP * DLL_CALLCONV
-FreeImage_ConvertFromRawBits(BYTE *bits, int width, int height, int pitch, unsigned bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask, BOOL topdown) {
-	FIBITMAP *dib = FreeImage_Allocate(width, height, bpp, red_mask, green_mask, blue_mask);
+FreeImage_ConvertFromRawBitsEx(BOOL copySource, BYTE *bits, FREE_IMAGE_TYPE type, int width, int height, int pitch, unsigned bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask, BOOL topdown) {
+	FIBITMAP *dib = NULL;
 
-	if (dib != NULL) {
-		if (topdown) {
-			for (int i = height - 1; i >= 0; --i) {
-				memcpy(FreeImage_GetScanLine(dib, i), bits, FreeImage_GetLine(dib));
-				bits += pitch;
-			}
-		} else {
-			for (int i = 0; i < height; ++i) {			
-				memcpy(FreeImage_GetScanLine(dib, i), bits, FreeImage_GetLine(dib));
-				bits += pitch;
-			}
+	if(copySource) {
+		// allocate a FIBITMAP with internally managed pixel buffer
+		dib = FreeImage_AllocateT(type, width, height, bpp, red_mask, green_mask, blue_mask);
+		if(!dib) {
+			return NULL;
+		}
+		// copy user provided pixel buffer into the dib
+		const unsigned linesize = FreeImage_GetLine(dib);
+		for(int y = 0; y < height; y++) {
+			memcpy(FreeImage_GetScanLine(dib, y), bits, linesize);
+			// next line in user's buffer
+			bits += pitch;
+		}
+		// flip pixels vertically if needed
+		if(topdown) {
+			FreeImage_FlipVertical(dib);
+		}
+	}
+	else {
+		// allocate a FIBITMAP using a wrapper to user provided pixel buffer
+		dib = FreeImage_AllocateHeaderForBits(bits, pitch, type, width, height, bpp, red_mask, green_mask, blue_mask);
+		if(!dib) {
+			return NULL;
+		}
+		// flip pixels vertically if needed
+		if(topdown) {
+			FreeImage_FlipVertical(dib);
 		}
 	}
 
 	return dib;
 }
 
+FIBITMAP * DLL_CALLCONV
+FreeImage_ConvertFromRawBits(BYTE *bits, int width, int height, int pitch, unsigned bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask, BOOL topdown) {
+	return FreeImage_ConvertFromRawBitsEx(TRUE /* copySource */, bits, FIT_BITMAP, width, height, pitch, bpp, red_mask, green_mask, blue_mask, topdown);
+}
+
 void DLL_CALLCONV
 FreeImage_ConvertToRawBits(BYTE *bits, FIBITMAP *dib, int pitch, unsigned bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask, BOOL topdown) {
 	if (FreeImage_HasPixels(dib) && (bits != NULL)) {
diff --git a/Source/FreeImage/Conversion24.cpp b/Source/FreeImage/Conversion24.cpp
index 1d5bba7..3b7a800 100644
--- a/Source/FreeImage/Conversion24.cpp
+++ b/Source/FreeImage/Conversion24.cpp
@@ -1,252 +1,252 @@
-// ==========================================================
-// Bitmap conversion routines
-//
-// Design and implementation by
-// - Floris van den Berg (flvdberg at wxs.nl)
-// - Dale Larson (dlarson at norsesoft.com)
-// - Herv� Drolon (drolon at infonie.fr)
-// - Jani Kajala (janik at remedy.fi)
-//
-// This file is part of FreeImage 3
-//
-// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
-// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
-// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
-// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
-// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
-// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
-// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
-// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
-// THIS DISCLAIMER.
-//
-// Use at your own risk!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-
-// ----------------------------------------------------------
-//  internal conversions X to 24 bits
-// ----------------------------------------------------------
-
-void DLL_CALLCONV
-FreeImage_ConvertLine1To24(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette) {
-	for (int cols = 0; cols < width_in_pixels; cols++) {
-		BYTE index = (source[cols >> 3] & (0x80 >> (cols & 0x07))) != 0 ? 1 : 0;
-
-		target[FI_RGBA_BLUE] = palette[index].rgbBlue;
-		target[FI_RGBA_GREEN] = palette[index].rgbGreen;
-		target[FI_RGBA_RED] = palette[index].rgbRed;
-
-		target += 3;
-	}
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine4To24(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette) {
-	BOOL low_nibble = FALSE;
-	int x = 0;
-
-	for (int cols = 0; cols < width_in_pixels; ++cols ) {
-		if (low_nibble) {
-			target[FI_RGBA_BLUE] = palette[LOWNIBBLE(source[x])].rgbBlue;
-			target[FI_RGBA_GREEN] = palette[LOWNIBBLE(source[x])].rgbGreen;
-			target[FI_RGBA_RED] = palette[LOWNIBBLE(source[x])].rgbRed;
-
-			x++;
-		} else {
-			target[FI_RGBA_BLUE] = palette[HINIBBLE(source[x]) >> 4].rgbBlue;
-			target[FI_RGBA_GREEN] = palette[HINIBBLE(source[x]) >> 4].rgbGreen;
-			target[FI_RGBA_RED] = palette[HINIBBLE(source[x]) >> 4].rgbRed;
-		}
-
-		low_nibble = !low_nibble;
-
-		target += 3;
-	}
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine8To24(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette) {
-	for (int cols = 0; cols < width_in_pixels; cols++) {
-		target[FI_RGBA_BLUE] = palette[source[cols]].rgbBlue;
-		target[FI_RGBA_GREEN] = palette[source[cols]].rgbGreen;
-		target[FI_RGBA_RED] = palette[source[cols]].rgbRed;
-
-		target += 3;
-	}
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine16To24_555(BYTE *target, BYTE *source, int width_in_pixels) {
-	WORD *bits = (WORD *)source;
-
-	for (int cols = 0; cols < width_in_pixels; cols++) {
-		target[FI_RGBA_RED]   = (BYTE)((((bits[cols] & FI16_555_RED_MASK) >> FI16_555_RED_SHIFT) * 0xFF) / 0x1F);
-		target[FI_RGBA_GREEN] = (BYTE)((((bits[cols] & FI16_555_GREEN_MASK) >> FI16_555_GREEN_SHIFT) * 0xFF) / 0x1F);
-		target[FI_RGBA_BLUE]  = (BYTE)((((bits[cols] & FI16_555_BLUE_MASK) >> FI16_555_BLUE_SHIFT) * 0xFF) / 0x1F);
-
-		target += 3;
-	}
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine16To24_565(BYTE *target, BYTE *source, int width_in_pixels) {
-	WORD *bits = (WORD *)source;
-
-	for (int cols = 0; cols < width_in_pixels; cols++) {
-		target[FI_RGBA_RED]   = (BYTE)((((bits[cols] & FI16_565_RED_MASK) >> FI16_565_RED_SHIFT) * 0xFF) / 0x1F);
-		target[FI_RGBA_GREEN] = (BYTE)((((bits[cols] & FI16_565_GREEN_MASK) >> FI16_565_GREEN_SHIFT) * 0xFF) / 0x3F);
-		target[FI_RGBA_BLUE]  = (BYTE)((((bits[cols] & FI16_565_BLUE_MASK) >> FI16_565_BLUE_SHIFT) * 0xFF) / 0x1F);
-
-		target += 3;
-	}
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine32To24(BYTE *target, BYTE *source, int width_in_pixels) {
-	for (int cols = 0; cols < width_in_pixels; cols++) {
-		target[FI_RGBA_BLUE] = source[FI_RGBA_BLUE];
-		target[FI_RGBA_GREEN] = source[FI_RGBA_GREEN];
-		target[FI_RGBA_RED] = source[FI_RGBA_RED];
-
-		target += 3;
-		source += 4;
-	}
-}
-
-// ----------------------------------------------------------
-//   smart convert X to 24 bits
-// ----------------------------------------------------------
-
-FIBITMAP * DLL_CALLCONV
-FreeImage_ConvertTo24Bits(FIBITMAP *dib) {
-	if(!FreeImage_HasPixels(dib)) return NULL;
-
-	const unsigned bpp = FreeImage_GetBPP(dib);
-	const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
-
-	if((image_type != FIT_BITMAP) && (image_type != FIT_RGB16) && (image_type != FIT_RGBA16)) {
-		return NULL;
-	}
-	
-	const int width = FreeImage_GetWidth(dib);
-	const int height = FreeImage_GetHeight(dib);
-
-	if(image_type == FIT_BITMAP) {
-		if(bpp == 24) {
-			return FreeImage_Clone(dib);
-		}
-
-		FIBITMAP *new_dib = FreeImage_Allocate(width, height, 24, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
-		if(new_dib == NULL) {
-			return NULL;
-		}
-
-		// copy metadata from src to dst
-		FreeImage_CloneMetadata(new_dib, dib);
-
-		switch(bpp) {
-			case 1 :
-			{
-				for (int rows = 0; rows < height; rows++) {
-					FreeImage_ConvertLine1To24(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib));					
-				}
-				return new_dib;
-			}
-
-			case 4 :
-			{
-				for (int rows = 0; rows < height; rows++) {
-					FreeImage_ConvertLine4To24(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib));
-				}
-				return new_dib;
-			}
-				
-			case 8 :
-			{
-				for (int rows = 0; rows < height; rows++) {
-					FreeImage_ConvertLine8To24(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib));
-				}
-				return new_dib;
-			}
-
-			case 16 :
-			{
-				for (int rows = 0; rows < height; rows++) {
-					if ((FreeImage_GetRedMask(dib) == FI16_565_RED_MASK) && (FreeImage_GetGreenMask(dib) == FI16_565_GREEN_MASK) && (FreeImage_GetBlueMask(dib) == FI16_565_BLUE_MASK)) {
-						FreeImage_ConvertLine16To24_565(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
-					} else {
-						// includes case where all the masks are 0
-						FreeImage_ConvertLine16To24_555(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
-					}
-				}
-				return new_dib;
-			}
-
-			case 32 :
-			{
-				for (int rows = 0; rows < height; rows++) {
-					FreeImage_ConvertLine32To24(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
-				}
-				return new_dib;
-			}
-		}
-	
-	} else if(image_type == FIT_RGB16) {
-		FIBITMAP *new_dib = FreeImage_Allocate(width, height, 24, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
-		if(new_dib == NULL) {
-			return NULL;
-		}
-
-		// copy metadata from src to dst
-		FreeImage_CloneMetadata(new_dib, dib);
-
-		const unsigned src_pitch = FreeImage_GetPitch(dib);
-		const unsigned dst_pitch = FreeImage_GetPitch(new_dib);
-		const BYTE *src_bits = FreeImage_GetBits(dib);
-		BYTE *dst_bits = FreeImage_GetBits(new_dib);
-		for (int rows = 0; rows < height; rows++) {
-			const FIRGB16 *src_pixel = (FIRGB16*)src_bits;
-			RGBTRIPLE *dst_pixel = (RGBTRIPLE*)dst_bits;
-			for(int cols = 0; cols < width; cols++) {
-				dst_pixel[cols].rgbtRed   = (BYTE)(src_pixel[cols].red   >> 8);
-				dst_pixel[cols].rgbtGreen = (BYTE)(src_pixel[cols].green >> 8);
-				dst_pixel[cols].rgbtBlue  = (BYTE)(src_pixel[cols].blue  >> 8);
-			}
-			src_bits += src_pitch;
-			dst_bits += dst_pitch;
-		}
-
-		return new_dib;
-
-	} else if(image_type == FIT_RGBA16) {
-		FIBITMAP *new_dib = FreeImage_Allocate(width, height, 24, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
-		if(new_dib == NULL) {
-			return NULL;
-		}
-
-		// copy metadata from src to dst
-		FreeImage_CloneMetadata(new_dib, dib);
-
-		const unsigned src_pitch = FreeImage_GetPitch(dib);
-		const unsigned dst_pitch = FreeImage_GetPitch(new_dib);
-		const BYTE *src_bits = FreeImage_GetBits(dib);
-		BYTE *dst_bits = FreeImage_GetBits(new_dib);
-		for (int rows = 0; rows < height; rows++) {
-			const FIRGBA16 *src_pixel = (FIRGBA16*)src_bits;
-			RGBTRIPLE *dst_pixel = (RGBTRIPLE*)dst_bits;
-			for(int cols = 0; cols < width; cols++) {
-				dst_pixel[cols].rgbtRed   = (BYTE)(src_pixel[cols].red   >> 8);
-				dst_pixel[cols].rgbtGreen = (BYTE)(src_pixel[cols].green >> 8);
-				dst_pixel[cols].rgbtBlue  = (BYTE)(src_pixel[cols].blue  >> 8);
-			}
-			src_bits += src_pitch;
-			dst_bits += dst_pitch;
-		}		
-
-		return new_dib;
-	}
-
-	return NULL;
-}
+// ==========================================================
+// Bitmap conversion routines
+//
+// Design and implementation by
+// - Floris van den Berg (flvdberg at wxs.nl)
+// - Dale Larson (dlarson at norsesoft.com)
+// - Herv� Drolon (drolon at infonie.fr)
+// - Jani Kajala (janik at remedy.fi)
+//
+// This file is part of FreeImage 3
+//
+// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
+// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
+// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
+// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
+// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
+// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
+// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+// THIS DISCLAIMER.
+//
+// Use at your own risk!
+// ==========================================================
+
+#include "FreeImage.h"
+#include "Utilities.h"
+
+// ----------------------------------------------------------
+//  internal conversions X to 24 bits
+// ----------------------------------------------------------
+
+void DLL_CALLCONV
+FreeImage_ConvertLine1To24(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette) {
+	for (int cols = 0; cols < width_in_pixels; cols++) {
+		BYTE index = (source[cols >> 3] & (0x80 >> (cols & 0x07))) != 0 ? 1 : 0;
+
+		target[FI_RGBA_BLUE] = palette[index].rgbBlue;
+		target[FI_RGBA_GREEN] = palette[index].rgbGreen;
+		target[FI_RGBA_RED] = palette[index].rgbRed;
+
+		target += 3;
+	}
+}
+
+void DLL_CALLCONV
+FreeImage_ConvertLine4To24(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette) {
+	BOOL low_nibble = FALSE;
+	int x = 0;
+
+	for (int cols = 0; cols < width_in_pixels; ++cols ) {
+		if (low_nibble) {
+			target[FI_RGBA_BLUE] = palette[LOWNIBBLE(source[x])].rgbBlue;
+			target[FI_RGBA_GREEN] = palette[LOWNIBBLE(source[x])].rgbGreen;
+			target[FI_RGBA_RED] = palette[LOWNIBBLE(source[x])].rgbRed;
+
+			x++;
+		} else {
+			target[FI_RGBA_BLUE] = palette[HINIBBLE(source[x]) >> 4].rgbBlue;
+			target[FI_RGBA_GREEN] = palette[HINIBBLE(source[x]) >> 4].rgbGreen;
+			target[FI_RGBA_RED] = palette[HINIBBLE(source[x]) >> 4].rgbRed;
+		}
+
+		low_nibble = !low_nibble;
+
+		target += 3;
+	}
+}
+
+void DLL_CALLCONV
+FreeImage_ConvertLine8To24(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette) {
+	for (int cols = 0; cols < width_in_pixels; cols++) {
+		target[FI_RGBA_BLUE] = palette[source[cols]].rgbBlue;
+		target[FI_RGBA_GREEN] = palette[source[cols]].rgbGreen;
+		target[FI_RGBA_RED] = palette[source[cols]].rgbRed;
+
+		target += 3;
+	}
+}
+
+void DLL_CALLCONV
+FreeImage_ConvertLine16To24_555(BYTE *target, BYTE *source, int width_in_pixels) {
+	WORD *bits = (WORD *)source;
+
+	for (int cols = 0; cols < width_in_pixels; cols++) {
+		target[FI_RGBA_RED]   = (BYTE)((((bits[cols] & FI16_555_RED_MASK) >> FI16_555_RED_SHIFT) * 0xFF) / 0x1F);
+		target[FI_RGBA_GREEN] = (BYTE)((((bits[cols] & FI16_555_GREEN_MASK) >> FI16_555_GREEN_SHIFT) * 0xFF) / 0x1F);
+		target[FI_RGBA_BLUE]  = (BYTE)((((bits[cols] & FI16_555_BLUE_MASK) >> FI16_555_BLUE_SHIFT) * 0xFF) / 0x1F);
+
+		target += 3;
+	}
+}
+
+void DLL_CALLCONV
+FreeImage_ConvertLine16To24_565(BYTE *target, BYTE *source, int width_in_pixels) {
+	WORD *bits = (WORD *)source;
+
+	for (int cols = 0; cols < width_in_pixels; cols++) {
+		target[FI_RGBA_RED]   = (BYTE)((((bits[cols] & FI16_565_RED_MASK) >> FI16_565_RED_SHIFT) * 0xFF) / 0x1F);
+		target[FI_RGBA_GREEN] = (BYTE)((((bits[cols] & FI16_565_GREEN_MASK) >> FI16_565_GREEN_SHIFT) * 0xFF) / 0x3F);
+		target[FI_RGBA_BLUE]  = (BYTE)((((bits[cols] & FI16_565_BLUE_MASK) >> FI16_565_BLUE_SHIFT) * 0xFF) / 0x1F);
+
+		target += 3;
+	}
+}
+
+void DLL_CALLCONV
+FreeImage_ConvertLine32To24(BYTE *target, BYTE *source, int width_in_pixels) {
+	for (int cols = 0; cols < width_in_pixels; cols++) {
+		target[FI_RGBA_BLUE] = source[FI_RGBA_BLUE];
+		target[FI_RGBA_GREEN] = source[FI_RGBA_GREEN];
+		target[FI_RGBA_RED] = source[FI_RGBA_RED];
+
+		target += 3;
+		source += 4;
+	}
+}
+
+// ----------------------------------------------------------
+//   smart convert X to 24 bits
+// ----------------------------------------------------------
+
+FIBITMAP * DLL_CALLCONV
+FreeImage_ConvertTo24Bits(FIBITMAP *dib) {
+	if(!FreeImage_HasPixels(dib)) return NULL;
+
+	const unsigned bpp = FreeImage_GetBPP(dib);
+	const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
+
+	if((image_type != FIT_BITMAP) && (image_type != FIT_RGB16) && (image_type != FIT_RGBA16)) {
+		return NULL;
+	}
+	
+	const int width = FreeImage_GetWidth(dib);
+	const int height = FreeImage_GetHeight(dib);
+
+	if(image_type == FIT_BITMAP) {
+		if(bpp == 24) {
+			return FreeImage_Clone(dib);
+		}
+
+		FIBITMAP *new_dib = FreeImage_Allocate(width, height, 24, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
+		if(new_dib == NULL) {
+			return NULL;
+		}
+
+		// copy metadata from src to dst
+		FreeImage_CloneMetadata(new_dib, dib);
+
+		switch(bpp) {
+			case 1 :
+			{
+				for (int rows = 0; rows < height; rows++) {
+					FreeImage_ConvertLine1To24(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib));					
+				}
+				return new_dib;
+			}
+
+			case 4 :
+			{
+				for (int rows = 0; rows < height; rows++) {
+					FreeImage_ConvertLine4To24(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib));
+				}
+				return new_dib;
+			}
+				
+			case 8 :
+			{
+				for (int rows = 0; rows < height; rows++) {
+					FreeImage_ConvertLine8To24(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib));
+				}
+				return new_dib;
+			}
+
+			case 16 :
+			{
+				for (int rows = 0; rows < height; rows++) {
+					if ((FreeImage_GetRedMask(dib) == FI16_565_RED_MASK) && (FreeImage_GetGreenMask(dib) == FI16_565_GREEN_MASK) && (FreeImage_GetBlueMask(dib) == FI16_565_BLUE_MASK)) {
+						FreeImage_ConvertLine16To24_565(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
+					} else {
+						// includes case where all the masks are 0
+						FreeImage_ConvertLine16To24_555(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
+					}
+				}
+				return new_dib;
+			}
+
+			case 32 :
+			{
+				for (int rows = 0; rows < height; rows++) {
+					FreeImage_ConvertLine32To24(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
+				}
+				return new_dib;
+			}
+		}
+	
+	} else if(image_type == FIT_RGB16) {
+		FIBITMAP *new_dib = FreeImage_Allocate(width, height, 24, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
+		if(new_dib == NULL) {
+			return NULL;
+		}
+
+		// copy metadata from src to dst
+		FreeImage_CloneMetadata(new_dib, dib);
+
+		const unsigned src_pitch = FreeImage_GetPitch(dib);
+		const unsigned dst_pitch = FreeImage_GetPitch(new_dib);
+		const BYTE *src_bits = FreeImage_GetBits(dib);
+		BYTE *dst_bits = FreeImage_GetBits(new_dib);
+		for (int rows = 0; rows < height; rows++) {
+			const FIRGB16 *src_pixel = (FIRGB16*)src_bits;
+			RGBTRIPLE *dst_pixel = (RGBTRIPLE*)dst_bits;
+			for(int cols = 0; cols < width; cols++) {
+				dst_pixel[cols].rgbtRed   = (BYTE)(src_pixel[cols].red   >> 8);
+				dst_pixel[cols].rgbtGreen = (BYTE)(src_pixel[cols].green >> 8);
+				dst_pixel[cols].rgbtBlue  = (BYTE)(src_pixel[cols].blue  >> 8);
+			}
+			src_bits += src_pitch;
+			dst_bits += dst_pitch;
+		}
+
+		return new_dib;
+
+	} else if(image_type == FIT_RGBA16) {
+		FIBITMAP *new_dib = FreeImage_Allocate(width, height, 24, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
+		if(new_dib == NULL) {
+			return NULL;
+		}
+
+		// copy metadata from src to dst
+		FreeImage_CloneMetadata(new_dib, dib);
+
+		const unsigned src_pitch = FreeImage_GetPitch(dib);
+		const unsigned dst_pitch = FreeImage_GetPitch(new_dib);
+		const BYTE *src_bits = FreeImage_GetBits(dib);
+		BYTE *dst_bits = FreeImage_GetBits(new_dib);
+		for (int rows = 0; rows < height; rows++) {
+			const FIRGBA16 *src_pixel = (FIRGBA16*)src_bits;
+			RGBTRIPLE *dst_pixel = (RGBTRIPLE*)dst_bits;
+			for(int cols = 0; cols < width; cols++) {
+				dst_pixel[cols].rgbtRed   = (BYTE)(src_pixel[cols].red   >> 8);
+				dst_pixel[cols].rgbtGreen = (BYTE)(src_pixel[cols].green >> 8);
+				dst_pixel[cols].rgbtBlue  = (BYTE)(src_pixel[cols].blue  >> 8);
+			}
+			src_bits += src_pitch;
+			dst_bits += dst_pitch;
+		}		
+
+		return new_dib;
+	}
+
+	return NULL;
+}
diff --git a/Source/FreeImage/Conversion32.cpp b/Source/FreeImage/Conversion32.cpp
index b8bd518..4874dcf 100644
--- a/Source/FreeImage/Conversion32.cpp
+++ b/Source/FreeImage/Conversion32.cpp
@@ -1,345 +1,345 @@
-// ==========================================================
-// Bitmap conversion routines
-//
-// Design and implementation by
-// - Floris van den Berg (flvdberg at wxs.nl)
-// - Herv� Drolon (drolon at infonie.fr)
-// - Jani Kajala (janik at remedy.fi)
-// - Detlev Vendt (detlev.vendt at brillit.de)
-//
-// This file is part of FreeImage 3
-//
-// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
-// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
-// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
-// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
-// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
-// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
-// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
-// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
-// THIS DISCLAIMER.
-//
-// Use at your own risk!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-
-// ----------------------------------------------------------
-//  internal conversions X to 32 bits
-// ----------------------------------------------------------
-
-void DLL_CALLCONV
-FreeImage_ConvertLine1To32(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette) {
-	for (int cols = 0; cols < width_in_pixels; cols++) {
-		int index = (source[cols>>3] & (0x80 >> (cols & 0x07))) != 0 ? 1 : 0;
-
-		target[FI_RGBA_BLUE]	= palette[index].rgbBlue;
-		target[FI_RGBA_GREEN]	= palette[index].rgbGreen;
-		target[FI_RGBA_RED]		= palette[index].rgbRed;
-		target[FI_RGBA_ALPHA]	= 0xFF;
-		target += 4;
-	}	
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine4To32(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette) {
-	BOOL low_nibble = FALSE;
-	int x = 0;
-
-	for (int cols = 0 ; cols < width_in_pixels ; ++cols) {
-		if (low_nibble) {
-			target[FI_RGBA_BLUE]	= palette[LOWNIBBLE(source[x])].rgbBlue;
-			target[FI_RGBA_GREEN]	= palette[LOWNIBBLE(source[x])].rgbGreen;
-			target[FI_RGBA_RED]		= palette[LOWNIBBLE(source[x])].rgbRed;
-
-			x++;
-		} else {
-			target[FI_RGBA_BLUE]	= palette[HINIBBLE(source[x]) >> 4].rgbBlue;
-			target[FI_RGBA_GREEN]	= palette[HINIBBLE(source[x]) >> 4].rgbGreen;
-			target[FI_RGBA_RED]		= palette[HINIBBLE(source[x]) >> 4].rgbRed;
-		}
-
-		low_nibble = !low_nibble;
-
-		target[FI_RGBA_ALPHA] = 0xFF;
-		target += 4;
-	}
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine8To32(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette) {
-	for (int cols = 0; cols < width_in_pixels; cols++) {
-		target[FI_RGBA_BLUE]	= palette[source[cols]].rgbBlue;
-		target[FI_RGBA_GREEN]	= palette[source[cols]].rgbGreen;
-		target[FI_RGBA_RED]		= palette[source[cols]].rgbRed;
-		target[FI_RGBA_ALPHA]	= 0xFF;
-		target += 4;
-	}
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine16To32_555(BYTE *target, BYTE *source, int width_in_pixels) {
-	WORD *bits = (WORD *)source;
-
-	for (int cols = 0; cols < width_in_pixels; cols++) {
-		target[FI_RGBA_RED]   = (BYTE)((((bits[cols] & FI16_555_RED_MASK) >> FI16_555_RED_SHIFT) * 0xFF) / 0x1F);
-		target[FI_RGBA_GREEN] = (BYTE)((((bits[cols] & FI16_555_GREEN_MASK) >> FI16_555_GREEN_SHIFT) * 0xFF) / 0x1F);
-		target[FI_RGBA_BLUE]  = (BYTE)((((bits[cols] & FI16_555_BLUE_MASK) >> FI16_555_BLUE_SHIFT) * 0xFF) / 0x1F);
-		target[FI_RGBA_ALPHA] = 0xFF;
-		target += 4;
-	}
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine16To32_565(BYTE *target, BYTE *source, int width_in_pixels) {
-	WORD *bits = (WORD *)source;
-
-	for (int cols = 0; cols < width_in_pixels; cols++) {
-		target[FI_RGBA_RED]   = (BYTE)((((bits[cols] & FI16_565_RED_MASK) >> FI16_565_RED_SHIFT) * 0xFF) / 0x1F);
-		target[FI_RGBA_GREEN] = (BYTE)((((bits[cols] & FI16_565_GREEN_MASK) >> FI16_565_GREEN_SHIFT) * 0xFF) / 0x3F);
-		target[FI_RGBA_BLUE]  = (BYTE)((((bits[cols] & FI16_565_BLUE_MASK) >> FI16_565_BLUE_SHIFT) * 0xFF) / 0x1F);
-		target[FI_RGBA_ALPHA] = 0xFF;
-		target += 4;
-	}
-}
-/*
-void DLL_CALLCONV
-FreeImage_ConvertLine24To32(BYTE *target, BYTE *source, int width_in_pixels) {
-	for (int cols = 0; cols < width_in_pixels; cols++) {
-		*(DWORD *)target = (*(DWORD *) source & FI_RGBA_RGB_MASK) | FI_RGBA_ALPHA_MASK;
-		target += 4;
-		source += 3;
-	}
-}
-*/
-/**
-This unoptimized version of the conversion function avoid an undetermined bug with VC++ SP6. 
-The bug occurs in release mode only, when the image height is equal to 537 
-(try e.g. a size of 432x537 to reproduce the bug with the optimized function).
-*/
-void DLL_CALLCONV
-FreeImage_ConvertLine24To32(BYTE *target, BYTE *source, int width_in_pixels) {
-	for (int cols = 0; cols < width_in_pixels; cols++) {
-		target[FI_RGBA_RED]   = source[FI_RGBA_RED];
-		target[FI_RGBA_GREEN] = source[FI_RGBA_GREEN];
-		target[FI_RGBA_BLUE]  = source[FI_RGBA_BLUE];
-		target[FI_RGBA_ALPHA] = 0xFF;
-		target += 4;
-		source += 3;
-	}
-}
-
-// ----------------------------------------------------------
-
-inline void 
-FreeImage_ConvertLine1To32MapTransparency(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette, BYTE *table, int transparent_pixels) {
-	for (int cols = 0; cols < width_in_pixels; cols++) {
-		int index = (source[cols>>3] & (0x80 >> (cols & 0x07))) != 0 ? 1 : 0;
-
-		target[FI_RGBA_BLUE]	= palette[index].rgbBlue;
-		target[FI_RGBA_GREEN]	= palette[index].rgbGreen;
-		target[FI_RGBA_RED]		= palette[index].rgbRed;
-		target[FI_RGBA_ALPHA] = (index < transparent_pixels) ? table[index] : 255;		
-		target += 4;
-	}	
-}
-
-inline void 
-FreeImage_ConvertLine4To32MapTransparency(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette, BYTE *table, int transparent_pixels) {
-	BOOL low_nibble = FALSE;
-	int x = 0;
-
-	for (int cols = 0 ; cols < width_in_pixels ; ++cols) {
-		if (low_nibble) {
-			target[FI_RGBA_BLUE]	= palette[LOWNIBBLE(source[x])].rgbBlue;
-			target[FI_RGBA_GREEN]	= palette[LOWNIBBLE(source[x])].rgbGreen;
-			target[FI_RGBA_RED]		= palette[LOWNIBBLE(source[x])].rgbRed;
-			target[FI_RGBA_ALPHA]	= (LOWNIBBLE(source[x]) < transparent_pixels) ? table[LOWNIBBLE(source[x])] : 255;
-
-			x++;
-		} else {
-			target[FI_RGBA_BLUE]	= palette[HINIBBLE(source[x]) >> 4].rgbBlue;
-			target[FI_RGBA_GREEN]	= palette[HINIBBLE(source[x]) >> 4].rgbGreen;
-			target[FI_RGBA_RED]		= palette[HINIBBLE(source[x]) >> 4].rgbRed;
-			target[FI_RGBA_ALPHA]	= (HINIBBLE(source[x] >> 4) < transparent_pixels) ? table[HINIBBLE(source[x]) >> 4] : 255;
-		}
-
-		low_nibble = !low_nibble;
-				
-		target += 4;
-	}
-}
-
-inline void 
-FreeImage_ConvertLine8To32MapTransparency(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette, BYTE *table, int transparent_pixels) {
-	for (int cols = 0; cols < width_in_pixels; cols++) {
-		target[FI_RGBA_BLUE]	= palette[source[cols]].rgbBlue;
-		target[FI_RGBA_GREEN]	= palette[source[cols]].rgbGreen;
-		target[FI_RGBA_RED]		= palette[source[cols]].rgbRed;
-		target[FI_RGBA_ALPHA] = (source[cols] < transparent_pixels) ? table[source[cols]] : 255;
-		target += 4;		
-	}
-}
-
-// ----------------------------------------------------------
-
-FIBITMAP * DLL_CALLCONV
-FreeImage_ConvertTo32Bits(FIBITMAP *dib) {
-	if(!FreeImage_HasPixels(dib)) return NULL;
-
-	const int bpp = FreeImage_GetBPP(dib);
-	const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
-	
-	if((image_type != FIT_BITMAP) && (image_type != FIT_RGB16) && (image_type != FIT_RGBA16)) {
-		return NULL;
-	}
-	
-	const int width = FreeImage_GetWidth(dib);
-	const int height = FreeImage_GetHeight(dib);
-
-	if(image_type == FIT_BITMAP) {
-
-		if(bpp == 32) {
-			return FreeImage_Clone(dib);
-		}
-
-		FIBITMAP *new_dib = FreeImage_Allocate(width, height, 32, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
-		if(new_dib == NULL) {
-			return NULL;
-		}
-
-		// copy metadata from src to dst
-		FreeImage_CloneMetadata(new_dib, dib);
-
-		BOOL bIsTransparent = FreeImage_IsTransparent(dib);
-
-		switch(bpp) {
-			case 1:
-			{
-				if(bIsTransparent) {
-					for (int rows = 0; rows < height; rows++) {
-						FreeImage_ConvertLine1To32MapTransparency(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib), FreeImage_GetTransparencyTable(dib), FreeImage_GetTransparencyCount(dib));
-					}
-				} else {
-					for (int rows = 0; rows < height; rows++) {
-						FreeImage_ConvertLine1To32(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib));
-					}					
-				}
-
-				return new_dib;
-			}
-
-			case 4:
-			{
-				if(bIsTransparent) {
-					for (int rows = 0; rows < height; rows++) {
-						FreeImage_ConvertLine4To32MapTransparency(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib), FreeImage_GetTransparencyTable(dib), FreeImage_GetTransparencyCount(dib));
-					}
-				} else {
-					for (int rows = 0; rows < height; rows++) {
-						FreeImage_ConvertLine4To32(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib));
-					}					
-				}
-
-				return new_dib;
-			}
-				
-			case 8:
-			{
-				if(bIsTransparent) {
-					for (int rows = 0; rows < height; rows++) {
-						FreeImage_ConvertLine8To32MapTransparency(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib), FreeImage_GetTransparencyTable(dib), FreeImage_GetTransparencyCount(dib));
-					}
-				} else {
-					for (int rows = 0; rows < height; rows++) {
-						FreeImage_ConvertLine8To32(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib));
-					}					
-				}
-
-				return new_dib;
-			}
-
-			case 16:
-			{
-				for (int rows = 0; rows < height; rows++) {
-					if ((FreeImage_GetRedMask(dib) == FI16_565_RED_MASK) && (FreeImage_GetGreenMask(dib) == FI16_565_GREEN_MASK) && (FreeImage_GetBlueMask(dib) == FI16_565_BLUE_MASK)) {
-						FreeImage_ConvertLine16To32_565(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
-					} else {
-						// includes case where all the masks are 0
-						FreeImage_ConvertLine16To32_555(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
-					}
-				}
-
-				return new_dib;
-			}
-
-			case 24:
-			{
-				for (int rows = 0; rows < height; rows++) {
-					FreeImage_ConvertLine24To32(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
-				}
-
-				return new_dib;
-			}
-		}
-
-	} else if(image_type == FIT_RGB16) {
-		FIBITMAP *new_dib = FreeImage_Allocate(width, height, 32, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
-		if(new_dib == NULL) {
-			return NULL;
-		}
-
-		// copy metadata from src to dst
-		FreeImage_CloneMetadata(new_dib, dib);
-
-		const unsigned src_pitch = FreeImage_GetPitch(dib);
-		const unsigned dst_pitch = FreeImage_GetPitch(new_dib);
-		const BYTE *src_bits = FreeImage_GetBits(dib);
-		BYTE *dst_bits = FreeImage_GetBits(new_dib);
-		for (int rows = 0; rows < height; rows++) {
-			const FIRGB16 *src_pixel = (FIRGB16*)src_bits;
-			RGBQUAD *dst_pixel = (RGBQUAD*)dst_bits;
-			for(int cols = 0; cols < width; cols++) {
-				dst_pixel[cols].rgbRed		= (BYTE)(src_pixel[cols].red   >> 8);
-				dst_pixel[cols].rgbGreen	= (BYTE)(src_pixel[cols].green >> 8);
-				dst_pixel[cols].rgbBlue		= (BYTE)(src_pixel[cols].blue  >> 8);
-				dst_pixel[cols].rgbReserved = (BYTE)0xFF;
-			}
-			src_bits += src_pitch;
-			dst_bits += dst_pitch;
-		}
-
-		return new_dib;
-
-	} else if(image_type == FIT_RGBA16) {
-		FIBITMAP *new_dib = FreeImage_Allocate(width, height, 32, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
-		if(new_dib == NULL) {
-			return NULL;
-		}
-
-		// copy metadata from src to dst
-		FreeImage_CloneMetadata(new_dib, dib);
-
-		const unsigned src_pitch = FreeImage_GetPitch(dib);
-		const unsigned dst_pitch = FreeImage_GetPitch(new_dib);
-		const BYTE *src_bits = FreeImage_GetBits(dib);
-		BYTE *dst_bits = FreeImage_GetBits(new_dib);
-		for (int rows = 0; rows < height; rows++) {
-			const FIRGBA16 *src_pixel = (FIRGBA16*)src_bits;
-			RGBQUAD *dst_pixel = (RGBQUAD*)dst_bits;
-			for(int cols = 0; cols < width; cols++) {
-				dst_pixel[cols].rgbRed		= (BYTE)(src_pixel[cols].red   >> 8);
-				dst_pixel[cols].rgbGreen	= (BYTE)(src_pixel[cols].green >> 8);
-				dst_pixel[cols].rgbBlue		= (BYTE)(src_pixel[cols].blue  >> 8);
-				dst_pixel[cols].rgbReserved = (BYTE)(src_pixel[cols].alpha >> 8);
-			}
-			src_bits += src_pitch;
-			dst_bits += dst_pitch;
-		}		
-
-		return new_dib;
-	}
-	
-	return NULL;
-}
+// ==========================================================
+// Bitmap conversion routines
+//
+// Design and implementation by
+// - Floris van den Berg (flvdberg at wxs.nl)
+// - Herv� Drolon (drolon at infonie.fr)
+// - Jani Kajala (janik at remedy.fi)
+// - Detlev Vendt (detlev.vendt at brillit.de)
+//
+// This file is part of FreeImage 3
+//
+// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
+// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
+// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
+// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
+// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
+// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
+// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+// THIS DISCLAIMER.
+//
+// Use at your own risk!
+// ==========================================================
+
+#include "FreeImage.h"
+#include "Utilities.h"
+
+// ----------------------------------------------------------
+//  internal conversions X to 32 bits
+// ----------------------------------------------------------
+
+void DLL_CALLCONV
+FreeImage_ConvertLine1To32(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette) {
+	for (int cols = 0; cols < width_in_pixels; cols++) {
+		int index = (source[cols>>3] & (0x80 >> (cols & 0x07))) != 0 ? 1 : 0;
+
+		target[FI_RGBA_BLUE]	= palette[index].rgbBlue;
+		target[FI_RGBA_GREEN]	= palette[index].rgbGreen;
+		target[FI_RGBA_RED]		= palette[index].rgbRed;
+		target[FI_RGBA_ALPHA]	= 0xFF;
+		target += 4;
+	}	
+}
+
+void DLL_CALLCONV
+FreeImage_ConvertLine4To32(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette) {
+	BOOL low_nibble = FALSE;
+	int x = 0;
+
+	for (int cols = 0 ; cols < width_in_pixels ; ++cols) {
+		if (low_nibble) {
+			target[FI_RGBA_BLUE]	= palette[LOWNIBBLE(source[x])].rgbBlue;
+			target[FI_RGBA_GREEN]	= palette[LOWNIBBLE(source[x])].rgbGreen;
+			target[FI_RGBA_RED]		= palette[LOWNIBBLE(source[x])].rgbRed;
+
+			x++;
+		} else {
+			target[FI_RGBA_BLUE]	= palette[HINIBBLE(source[x]) >> 4].rgbBlue;
+			target[FI_RGBA_GREEN]	= palette[HINIBBLE(source[x]) >> 4].rgbGreen;
+			target[FI_RGBA_RED]		= palette[HINIBBLE(source[x]) >> 4].rgbRed;
+		}
+
+		low_nibble = !low_nibble;
+
+		target[FI_RGBA_ALPHA] = 0xFF;
+		target += 4;
+	}
+}
+
+void DLL_CALLCONV
+FreeImage_ConvertLine8To32(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette) {
+	for (int cols = 0; cols < width_in_pixels; cols++) {
+		target[FI_RGBA_BLUE]	= palette[source[cols]].rgbBlue;
+		target[FI_RGBA_GREEN]	= palette[source[cols]].rgbGreen;
+		target[FI_RGBA_RED]		= palette[source[cols]].rgbRed;
+		target[FI_RGBA_ALPHA]	= 0xFF;
+		target += 4;
+	}
+}
+
+void DLL_CALLCONV
+FreeImage_ConvertLine16To32_555(BYTE *target, BYTE *source, int width_in_pixels) {
+	WORD *bits = (WORD *)source;
+
+	for (int cols = 0; cols < width_in_pixels; cols++) {
+		target[FI_RGBA_RED]   = (BYTE)((((bits[cols] & FI16_555_RED_MASK) >> FI16_555_RED_SHIFT) * 0xFF) / 0x1F);
+		target[FI_RGBA_GREEN] = (BYTE)((((bits[cols] & FI16_555_GREEN_MASK) >> FI16_555_GREEN_SHIFT) * 0xFF) / 0x1F);
+		target[FI_RGBA_BLUE]  = (BYTE)((((bits[cols] & FI16_555_BLUE_MASK) >> FI16_555_BLUE_SHIFT) * 0xFF) / 0x1F);
+		target[FI_RGBA_ALPHA] = 0xFF;
+		target += 4;
+	}
+}
+
+void DLL_CALLCONV
+FreeImage_ConvertLine16To32_565(BYTE *target, BYTE *source, int width_in_pixels) {
+	WORD *bits = (WORD *)source;
+
+	for (int cols = 0; cols < width_in_pixels; cols++) {
+		target[FI_RGBA_RED]   = (BYTE)((((bits[cols] & FI16_565_RED_MASK) >> FI16_565_RED_SHIFT) * 0xFF) / 0x1F);
+		target[FI_RGBA_GREEN] = (BYTE)((((bits[cols] & FI16_565_GREEN_MASK) >> FI16_565_GREEN_SHIFT) * 0xFF) / 0x3F);
+		target[FI_RGBA_BLUE]  = (BYTE)((((bits[cols] & FI16_565_BLUE_MASK) >> FI16_565_BLUE_SHIFT) * 0xFF) / 0x1F);
+		target[FI_RGBA_ALPHA] = 0xFF;
+		target += 4;
+	}
+}
+/*
+void DLL_CALLCONV
+FreeImage_ConvertLine24To32(BYTE *target, BYTE *source, int width_in_pixels) {
+	for (int cols = 0; cols < width_in_pixels; cols++) {
+		*(DWORD *)target = (*(DWORD *) source & FI_RGBA_RGB_MASK) | FI_RGBA_ALPHA_MASK;
+		target += 4;
+		source += 3;
+	}
+}
+*/
+/**
+This unoptimized version of the conversion function avoid an undetermined bug with VC++ SP6. 
+The bug occurs in release mode only, when the image height is equal to 537 
+(try e.g. a size of 432x537 to reproduce the bug with the optimized function).
+*/
+void DLL_CALLCONV
+FreeImage_ConvertLine24To32(BYTE *target, BYTE *source, int width_in_pixels) {
+	for (int cols = 0; cols < width_in_pixels; cols++) {
+		target[FI_RGBA_RED]   = source[FI_RGBA_RED];
+		target[FI_RGBA_GREEN] = source[FI_RGBA_GREEN];
+		target[FI_RGBA_BLUE]  = source[FI_RGBA_BLUE];
+		target[FI_RGBA_ALPHA] = 0xFF;
+		target += 4;
+		source += 3;
+	}
+}
+
+// ----------------------------------------------------------
+
+inline void 
+FreeImage_ConvertLine1To32MapTransparency(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette, BYTE *table, int transparent_pixels) {
+	for (int cols = 0; cols < width_in_pixels; cols++) {
+		int index = (source[cols>>3] & (0x80 >> (cols & 0x07))) != 0 ? 1 : 0;
+
+		target[FI_RGBA_BLUE]	= palette[index].rgbBlue;
+		target[FI_RGBA_GREEN]	= palette[index].rgbGreen;
+		target[FI_RGBA_RED]		= palette[index].rgbRed;
+		target[FI_RGBA_ALPHA] = (index < transparent_pixels) ? table[index] : 255;		
+		target += 4;
+	}	
+}
+
+inline void 
+FreeImage_ConvertLine4To32MapTransparency(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette, BYTE *table, int transparent_pixels) {
+	BOOL low_nibble = FALSE;
+	int x = 0;
+
+	for (int cols = 0 ; cols < width_in_pixels ; ++cols) {
+		if (low_nibble) {
+			target[FI_RGBA_BLUE]	= palette[LOWNIBBLE(source[x])].rgbBlue;
+			target[FI_RGBA_GREEN]	= palette[LOWNIBBLE(source[x])].rgbGreen;
+			target[FI_RGBA_RED]		= palette[LOWNIBBLE(source[x])].rgbRed;
+			target[FI_RGBA_ALPHA]	= (LOWNIBBLE(source[x]) < transparent_pixels) ? table[LOWNIBBLE(source[x])] : 255;
+
+			x++;
+		} else {
+			target[FI_RGBA_BLUE]	= palette[HINIBBLE(source[x]) >> 4].rgbBlue;
+			target[FI_RGBA_GREEN]	= palette[HINIBBLE(source[x]) >> 4].rgbGreen;
+			target[FI_RGBA_RED]		= palette[HINIBBLE(source[x]) >> 4].rgbRed;
+			target[FI_RGBA_ALPHA]	= (HINIBBLE(source[x] >> 4) < transparent_pixels) ? table[HINIBBLE(source[x]) >> 4] : 255;
+		}
+
+		low_nibble = !low_nibble;
+				
+		target += 4;
+	}
+}
+
+inline void 
+FreeImage_ConvertLine8To32MapTransparency(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette, BYTE *table, int transparent_pixels) {
+	for (int cols = 0; cols < width_in_pixels; cols++) {
+		target[FI_RGBA_BLUE]	= palette[source[cols]].rgbBlue;
+		target[FI_RGBA_GREEN]	= palette[source[cols]].rgbGreen;
+		target[FI_RGBA_RED]		= palette[source[cols]].rgbRed;
+		target[FI_RGBA_ALPHA] = (source[cols] < transparent_pixels) ? table[source[cols]] : 255;
+		target += 4;		
+	}
+}
+
+// ----------------------------------------------------------
+
+FIBITMAP * DLL_CALLCONV
+FreeImage_ConvertTo32Bits(FIBITMAP *dib) {
+	if(!FreeImage_HasPixels(dib)) return NULL;
+
+	const int bpp = FreeImage_GetBPP(dib);
+	const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
+	
+	if((image_type != FIT_BITMAP) && (image_type != FIT_RGB16) && (image_type != FIT_RGBA16)) {
+		return NULL;
+	}
+	
+	const int width = FreeImage_GetWidth(dib);
+	const int height = FreeImage_GetHeight(dib);
+
+	if(image_type == FIT_BITMAP) {
+
+		if(bpp == 32) {
+			return FreeImage_Clone(dib);
+		}
+
+		FIBITMAP *new_dib = FreeImage_Allocate(width, height, 32, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
+		if(new_dib == NULL) {
+			return NULL;
+		}
+
+		// copy metadata from src to dst
+		FreeImage_CloneMetadata(new_dib, dib);
+
+		BOOL bIsTransparent = FreeImage_IsTransparent(dib);
+
+		switch(bpp) {
+			case 1:
+			{
+				if(bIsTransparent) {
+					for (int rows = 0; rows < height; rows++) {
+						FreeImage_ConvertLine1To32MapTransparency(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib), FreeImage_GetTransparencyTable(dib), FreeImage_GetTransparencyCount(dib));
+					}
+				} else {
+					for (int rows = 0; rows < height; rows++) {
+						FreeImage_ConvertLine1To32(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib));
+					}					
+				}
+
+				return new_dib;
+			}
+
+			case 4:
+			{
+				if(bIsTransparent) {
+					for (int rows = 0; rows < height; rows++) {
+						FreeImage_ConvertLine4To32MapTransparency(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib), FreeImage_GetTransparencyTable(dib), FreeImage_GetTransparencyCount(dib));
+					}
+				} else {
+					for (int rows = 0; rows < height; rows++) {
+						FreeImage_ConvertLine4To32(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib));
+					}					
+				}
+
+				return new_dib;
+			}
+				
+			case 8:
+			{
+				if(bIsTransparent) {
+					for (int rows = 0; rows < height; rows++) {
+						FreeImage_ConvertLine8To32MapTransparency(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib), FreeImage_GetTransparencyTable(dib), FreeImage_GetTransparencyCount(dib));
+					}
+				} else {
+					for (int rows = 0; rows < height; rows++) {
+						FreeImage_ConvertLine8To32(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib));
+					}					
+				}
+
+				return new_dib;
+			}
+
+			case 16:
+			{
+				for (int rows = 0; rows < height; rows++) {
+					if ((FreeImage_GetRedMask(dib) == FI16_565_RED_MASK) && (FreeImage_GetGreenMask(dib) == FI16_565_GREEN_MASK) && (FreeImage_GetBlueMask(dib) == FI16_565_BLUE_MASK)) {
+						FreeImage_ConvertLine16To32_565(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
+					} else {
+						// includes case where all the masks are 0
+						FreeImage_ConvertLine16To32_555(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
+					}
+				}
+
+				return new_dib;
+			}
+
+			case 24:
+			{
+				for (int rows = 0; rows < height; rows++) {
+					FreeImage_ConvertLine24To32(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
+				}
+
+				return new_dib;
+			}
+		}
+
+	} else if(image_type == FIT_RGB16) {
+		FIBITMAP *new_dib = FreeImage_Allocate(width, height, 32, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
+		if(new_dib == NULL) {
+			return NULL;
+		}
+
+		// copy metadata from src to dst
+		FreeImage_CloneMetadata(new_dib, dib);
+
+		const unsigned src_pitch = FreeImage_GetPitch(dib);
+		const unsigned dst_pitch = FreeImage_GetPitch(new_dib);
+		const BYTE *src_bits = FreeImage_GetBits(dib);
+		BYTE *dst_bits = FreeImage_GetBits(new_dib);
+		for (int rows = 0; rows < height; rows++) {
+			const FIRGB16 *src_pixel = (FIRGB16*)src_bits;
+			RGBQUAD *dst_pixel = (RGBQUAD*)dst_bits;
+			for(int cols = 0; cols < width; cols++) {
+				dst_pixel[cols].rgbRed		= (BYTE)(src_pixel[cols].red   >> 8);
+				dst_pixel[cols].rgbGreen	= (BYTE)(src_pixel[cols].green >> 8);
+				dst_pixel[cols].rgbBlue		= (BYTE)(src_pixel[cols].blue  >> 8);
+				dst_pixel[cols].rgbReserved = (BYTE)0xFF;
+			}
+			src_bits += src_pitch;
+			dst_bits += dst_pitch;
+		}
+
+		return new_dib;
+
+	} else if(image_type == FIT_RGBA16) {
+		FIBITMAP *new_dib = FreeImage_Allocate(width, height, 32, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
+		if(new_dib == NULL) {
+			return NULL;
+		}
+
+		// copy metadata from src to dst
+		FreeImage_CloneMetadata(new_dib, dib);
+
+		const unsigned src_pitch = FreeImage_GetPitch(dib);
+		const unsigned dst_pitch = FreeImage_GetPitch(new_dib);
+		const BYTE *src_bits = FreeImage_GetBits(dib);
+		BYTE *dst_bits = FreeImage_GetBits(new_dib);
+		for (int rows = 0; rows < height; rows++) {
+			const FIRGBA16 *src_pixel = (FIRGBA16*)src_bits;
+			RGBQUAD *dst_pixel = (RGBQUAD*)dst_bits;
+			for(int cols = 0; cols < width; cols++) {
+				dst_pixel[cols].rgbRed		= (BYTE)(src_pixel[cols].red   >> 8);
+				dst_pixel[cols].rgbGreen	= (BYTE)(src_pixel[cols].green >> 8);
+				dst_pixel[cols].rgbBlue		= (BYTE)(src_pixel[cols].blue  >> 8);
+				dst_pixel[cols].rgbReserved = (BYTE)(src_pixel[cols].alpha >> 8);
+			}
+			src_bits += src_pitch;
+			dst_bits += dst_pitch;
+		}		
+
+		return new_dib;
+	}
+	
+	return NULL;
+}
diff --git a/Source/FreeImage/Conversion8.cpp b/Source/FreeImage/Conversion8.cpp
index 1c331a6..c4f9b22 100644
--- a/Source/FreeImage/Conversion8.cpp
+++ b/Source/FreeImage/Conversion8.cpp
@@ -1,305 +1,305 @@
-// ==========================================================
-// Bitmap conversion routines
-//
-// Design and implementation by
-// - Floris van den Berg (flvdberg at wxs.nl)
-// - Herv� Drolon (drolon at infonie.fr)
-// - Jani Kajala (janik at remedy.fi)
-// - Karl-Heinz Bussian (khbussian at moss.de)
-// - Carsten Klein (cklein05 at users.sourceforge.net)
-//
-// This file is part of FreeImage 3
-//
-// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
-// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
-// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
-// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
-// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
-// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
-// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
-// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
-// THIS DISCLAIMER.
-//
-// Use at your own risk!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-
-// ----------------------------------------------------------
-//  internal conversions X to 8 bits
-// ----------------------------------------------------------
-
-void DLL_CALLCONV
-FreeImage_ConvertLine1To8(BYTE *target, BYTE *source, int width_in_pixels) {
-	for (unsigned cols = 0; cols < (unsigned)width_in_pixels; cols++)
-		target[cols] = (source[cols >> 3] & (0x80 >> (cols & 0x07))) != 0 ? 255 : 0;	
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine4To8(BYTE *target, BYTE *source, int width_in_pixels) {
-	unsigned count_new = 0;
-	unsigned count_org = 0;
-	BOOL hinibble = TRUE;
-
-	while (count_new < (unsigned)width_in_pixels) {
-		if (hinibble) {
-			target[count_new] = (source[count_org] >> 4);
-		} else {
-			target[count_new] = (source[count_org] & 0x0F);
-			count_org++;
-		}
-		hinibble = !hinibble;
-		count_new++;
-	}
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine16To8_555(BYTE *target, BYTE *source, int width_in_pixels) {
-	const WORD *const bits = (WORD *)source;
-	for (unsigned cols = 0; cols < (unsigned)width_in_pixels; cols++) {
-		target[cols] = GREY((((bits[cols] & FI16_555_RED_MASK) >> FI16_555_RED_SHIFT) * 0xFF) / 0x1F,
-			                (((bits[cols] & FI16_555_GREEN_MASK) >> FI16_555_GREEN_SHIFT) * 0xFF) / 0x1F,
-							(((bits[cols] & FI16_555_BLUE_MASK) >> FI16_555_BLUE_SHIFT) * 0xFF) / 0x1F);
-	}
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine16To8_565(BYTE *target, BYTE *source, int width_in_pixels) {
-	const WORD *const bits = (WORD *)source;
-	for (unsigned cols = 0; cols < (unsigned)width_in_pixels; cols++) {
-		target[cols] = GREY((((bits[cols] & FI16_565_RED_MASK) >> FI16_565_RED_SHIFT) * 0xFF) / 0x1F,
-			        (((bits[cols] & FI16_565_GREEN_MASK) >> FI16_565_GREEN_SHIFT) * 0xFF) / 0x3F,
-					(((bits[cols] & FI16_565_BLUE_MASK) >> FI16_565_BLUE_SHIFT) * 0xFF) / 0x1F);
-	}
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine24To8(BYTE *target, BYTE *source, int width_in_pixels) {
-	for (unsigned cols = 0; cols < (unsigned)width_in_pixels; cols++) {
-		target[cols] = GREY(source[FI_RGBA_RED], source[FI_RGBA_GREEN], source[FI_RGBA_BLUE]);
-		source += 3;
-	}
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine32To8(BYTE *target, BYTE *source, int width_in_pixels) {
-	for (unsigned cols = 0; cols < (unsigned)width_in_pixels; cols++) {
-		target[cols] = GREY(source[FI_RGBA_RED], source[FI_RGBA_GREEN], source[FI_RGBA_BLUE]);
-		source += 4;
-	}
-}
-
-// ----------------------------------------------------------
-//   smart convert X to 8 bits
-// ----------------------------------------------------------
-
-FIBITMAP * DLL_CALLCONV
-FreeImage_ConvertTo8Bits(FIBITMAP *dib) {
-	if (!FreeImage_HasPixels(dib)) {
-		return NULL;
-	}
-
-	const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
-	if (image_type != FIT_BITMAP && image_type != FIT_UINT16) {
-		return NULL;
-	}
-
-	const unsigned bpp = FreeImage_GetBPP(dib);
-
-	if (bpp != 8) {
-
-		const unsigned width = FreeImage_GetWidth(dib);
-		const unsigned height = FreeImage_GetHeight(dib);
-
-		// Allocate a destination image
-		FIBITMAP *new_dib = FreeImage_Allocate(width, height, 8);
-		if (new_dib == NULL) {
-			return NULL;
-		}
-
-		// Copy metadata from src to dst
-		FreeImage_CloneMetadata(new_dib, dib);
-
-		// Palette of destination image has already been initialized
-		RGBQUAD *new_pal = FreeImage_GetPalette(new_dib);
-
-		const FREE_IMAGE_COLOR_TYPE color_type = FreeImage_GetColorType(dib);
-
-		if (image_type == FIT_BITMAP) {
-
-			switch(bpp) {
-				case 1:
-				{
-					if (color_type == FIC_PALETTE) {
-						// Copy the palette
-						RGBQUAD *old_pal = FreeImage_GetPalette(dib);
-						new_pal[0] = old_pal[0];
-						new_pal[255] = old_pal[1];
-
-					} else if (color_type == FIC_MINISWHITE) {
-						// Create a reverse grayscale palette
-						CREATE_GREYSCALE_PALETTE_REVERSE(new_pal, 256);
-					}
-
-					// Expand and copy the bitmap data
-					for (unsigned rows = 0; rows < height; rows++) {
-						FreeImage_ConvertLine1To8(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
-					}
-					return new_dib;
-				}
-
-				case 4 :
-				{
-					if (color_type == FIC_PALETTE) {
-						// Copy the palette
-						memcpy(new_pal, FreeImage_GetPalette(dib), 16 * sizeof(RGBQUAD));
-					}
-
-					// Expand and copy the bitmap data
-					for (unsigned rows = 0; rows < height; rows++) {
-						FreeImage_ConvertLine4To8(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);					
-					}
-					return new_dib;
-				}
-
-				case 16 :
-				{
-					// Expand and copy the bitmap data
-					if (IS_FORMAT_RGB565(dib)) {
-						for (unsigned rows = 0; rows < height; rows++) {
-							FreeImage_ConvertLine16To8_565(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
-						}
-					} else {
-						for (unsigned rows = 0; rows < height; rows++) {
-							FreeImage_ConvertLine16To8_555(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
-						}
-					}
-					return new_dib;
-				}
-
-				case 24 :
-				{
-					// Expand and copy the bitmap data
-					for (unsigned rows = 0; rows < height; rows++) {
-						FreeImage_ConvertLine24To8(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);					
-					}
-					return new_dib;
-				}
-
-				case 32 :
-				{
-					// Expand and copy the bitmap data
-					for (unsigned rows = 0; rows < height; rows++) {
-						FreeImage_ConvertLine32To8(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
-					}
-					return new_dib;
-				}
-			}
-
-		} else if (image_type == FIT_UINT16) {
-
-			const unsigned src_pitch = FreeImage_GetPitch(dib);
-			const unsigned dst_pitch = FreeImage_GetPitch(new_dib);
-			const BYTE *src_bits = FreeImage_GetBits(dib);
-			BYTE *dst_bits = FreeImage_GetBits(new_dib);
-
-			for (unsigned rows = 0; rows < height; rows++) {
-				const WORD *const src_pixel = (WORD*)src_bits;
-				BYTE *dst_pixel = (BYTE*)dst_bits;
-				for(unsigned cols = 0; cols < width; cols++) {
-					dst_pixel[cols] = (BYTE)(src_pixel[cols] >> 8);
-				}
-				src_bits += src_pitch;
-				dst_bits += dst_pitch;
-			}
-			return new_dib;
-		} 
-
-	} // bpp != 8
-
-	return FreeImage_Clone(dib);
-}
-
-FIBITMAP * DLL_CALLCONV
-FreeImage_ConvertToGreyscale(FIBITMAP *dib) {
-	if (!FreeImage_HasPixels(dib)) {
-		return NULL;
-	}
-
-	const FREE_IMAGE_COLOR_TYPE color_type = FreeImage_GetColorType(dib);
-
-	if (color_type == FIC_PALETTE || color_type == FIC_MINISWHITE) {
-
-		const unsigned bpp = FreeImage_GetBPP(dib);
-		const unsigned width  = FreeImage_GetWidth(dib);
-		const unsigned height = FreeImage_GetHeight(dib);
-
-		FIBITMAP *new_dib = FreeImage_Allocate(width, height, 8);
-		if (new_dib == NULL) {
-			return NULL;
-		}
-
-		// Copy metadata from src to dst
-		FreeImage_CloneMetadata(new_dib, dib);
-
-		// Create a greyscale palette
-		BYTE grey_pal[256];
-		const RGBQUAD *pal = FreeImage_GetPalette(dib);
-		const unsigned size = CalculateUsedPaletteEntries(bpp);
-		for (unsigned i = 0; i < size; i++) {
-			grey_pal[i] = GREY(pal->rgbRed, pal->rgbGreen, pal->rgbBlue);
-			pal++;
-		}
-
-		const BYTE *src_bits = FreeImage_GetBits(dib);
-		BYTE *dst_bits = FreeImage_GetBits(new_dib);
-
-		const unsigned src_pitch = FreeImage_GetPitch(dib);
-		const unsigned dst_pitch = FreeImage_GetPitch(new_dib);
-
-		switch(bpp) {
-			case 1:
-			{
-				for (unsigned y = 0; y < height; y++) {
-					for (unsigned x = 0; x < width; x++) {
-						const unsigned pixel = (src_bits[x >> 3] & (0x80 >> (x & 0x07))) != 0;
-						dst_bits[x] = grey_pal[pixel];
-					}
-					src_bits += src_pitch;
-					dst_bits += dst_pitch;
-				}
-			}
-			break;
-
-			case 4:
-			{
-				for (unsigned y = 0; y < height; y++) {
-					for (unsigned x = 0; x < width; x++) {
-						const unsigned pixel = x & 0x01 ? src_bits[x >> 1] & 0x0F : src_bits[x >> 1] >> 4;
-						dst_bits[x] = grey_pal[pixel];
-					}
-					src_bits += src_pitch;
-					dst_bits += dst_pitch;
-				}
-			}
-			break;
-
-			case 8:
-			{
-				for (unsigned y = 0; y < height; y++) {
-					for (unsigned x = 0; x < width; x++) {
-						dst_bits[x] = grey_pal[src_bits[x]];
-					}
-					src_bits += src_pitch;
-					dst_bits += dst_pitch;
-				}
-			}
-			break;
-		}
-		return new_dib;
-	} 
-	
-	// Convert the bitmap to 8-bit greyscale
-	return FreeImage_ConvertTo8Bits(dib);
-}
+// ==========================================================
+// Bitmap conversion routines
+//
+// Design and implementation by
+// - Floris van den Berg (flvdberg at wxs.nl)
+// - Herv� Drolon (drolon at infonie.fr)
+// - Jani Kajala (janik at remedy.fi)
+// - Karl-Heinz Bussian (khbussian at moss.de)
+// - Carsten Klein (cklein05 at users.sourceforge.net)
+//
+// This file is part of FreeImage 3
+//
+// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
+// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
+// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
+// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
+// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
+// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
+// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+// THIS DISCLAIMER.
+//
+// Use at your own risk!
+// ==========================================================
+
+#include "FreeImage.h"
+#include "Utilities.h"
+
+// ----------------------------------------------------------
+//  internal conversions X to 8 bits
+// ----------------------------------------------------------
+
+void DLL_CALLCONV
+FreeImage_ConvertLine1To8(BYTE *target, BYTE *source, int width_in_pixels) {
+	for (unsigned cols = 0; cols < (unsigned)width_in_pixels; cols++)
+		target[cols] = (source[cols >> 3] & (0x80 >> (cols & 0x07))) != 0 ? 255 : 0;	
+}
+
+void DLL_CALLCONV
+FreeImage_ConvertLine4To8(BYTE *target, BYTE *source, int width_in_pixels) {
+	unsigned count_new = 0;
+	unsigned count_org = 0;
+	BOOL hinibble = TRUE;
+
+	while (count_new < (unsigned)width_in_pixels) {
+		if (hinibble) {
+			target[count_new] = (source[count_org] >> 4);
+		} else {
+			target[count_new] = (source[count_org] & 0x0F);
+			count_org++;
+		}
+		hinibble = !hinibble;
+		count_new++;
+	}
+}
+
+void DLL_CALLCONV
+FreeImage_ConvertLine16To8_555(BYTE *target, BYTE *source, int width_in_pixels) {
+	const WORD *const bits = (WORD *)source;
+	for (unsigned cols = 0; cols < (unsigned)width_in_pixels; cols++) {
+		target[cols] = GREY((((bits[cols] & FI16_555_RED_MASK) >> FI16_555_RED_SHIFT) * 0xFF) / 0x1F,
+			                (((bits[cols] & FI16_555_GREEN_MASK) >> FI16_555_GREEN_SHIFT) * 0xFF) / 0x1F,
+							(((bits[cols] & FI16_555_BLUE_MASK) >> FI16_555_BLUE_SHIFT) * 0xFF) / 0x1F);
+	}
+}
+
+void DLL_CALLCONV
+FreeImage_ConvertLine16To8_565(BYTE *target, BYTE *source, int width_in_pixels) {
+	const WORD *const bits = (WORD *)source;
+	for (unsigned cols = 0; cols < (unsigned)width_in_pixels; cols++) {
+		target[cols] = GREY((((bits[cols] & FI16_565_RED_MASK) >> FI16_565_RED_SHIFT) * 0xFF) / 0x1F,
+			        (((bits[cols] & FI16_565_GREEN_MASK) >> FI16_565_GREEN_SHIFT) * 0xFF) / 0x3F,
+					(((bits[cols] & FI16_565_BLUE_MASK) >> FI16_565_BLUE_SHIFT) * 0xFF) / 0x1F);
+	}
+}
+
+void DLL_CALLCONV
+FreeImage_ConvertLine24To8(BYTE *target, BYTE *source, int width_in_pixels) {
+	for (unsigned cols = 0; cols < (unsigned)width_in_pixels; cols++) {
+		target[cols] = GREY(source[FI_RGBA_RED], source[FI_RGBA_GREEN], source[FI_RGBA_BLUE]);
+		source += 3;
+	}
+}
+
+void DLL_CALLCONV
+FreeImage_ConvertLine32To8(BYTE *target, BYTE *source, int width_in_pixels) {
+	for (unsigned cols = 0; cols < (unsigned)width_in_pixels; cols++) {
+		target[cols] = GREY(source[FI_RGBA_RED], source[FI_RGBA_GREEN], source[FI_RGBA_BLUE]);
+		source += 4;
+	}
+}
+
+// ----------------------------------------------------------
+//   smart convert X to 8 bits
+// ----------------------------------------------------------
+
+FIBITMAP * DLL_CALLCONV
+FreeImage_ConvertTo8Bits(FIBITMAP *dib) {
+	if (!FreeImage_HasPixels(dib)) {
+		return NULL;
+	}
+
+	const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
+	if (image_type != FIT_BITMAP && image_type != FIT_UINT16) {
+		return NULL;
+	}
+
+	const unsigned bpp = FreeImage_GetBPP(dib);
+
+	if (bpp != 8) {
+
+		const unsigned width = FreeImage_GetWidth(dib);
+		const unsigned height = FreeImage_GetHeight(dib);
+
+		// Allocate a destination image
+		FIBITMAP *new_dib = FreeImage_Allocate(width, height, 8);
+		if (new_dib == NULL) {
+			return NULL;
+		}
+
+		// Copy metadata from src to dst
+		FreeImage_CloneMetadata(new_dib, dib);
+
+		// Palette of destination image has already been initialized
+		RGBQUAD *new_pal = FreeImage_GetPalette(new_dib);
+
+		const FREE_IMAGE_COLOR_TYPE color_type = FreeImage_GetColorType(dib);
+
+		if (image_type == FIT_BITMAP) {
+
+			switch(bpp) {
+				case 1:
+				{
+					if (color_type == FIC_PALETTE) {
+						// Copy the palette
+						RGBQUAD *old_pal = FreeImage_GetPalette(dib);
+						new_pal[0] = old_pal[0];
+						new_pal[255] = old_pal[1];
+
+					} else if (color_type == FIC_MINISWHITE) {
+						// Create a reverse grayscale palette
+						CREATE_GREYSCALE_PALETTE_REVERSE(new_pal, 256);
+					}
+
+					// Expand and copy the bitmap data
+					for (unsigned rows = 0; rows < height; rows++) {
+						FreeImage_ConvertLine1To8(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
+					}
+					return new_dib;
+				}
+
+				case 4 :
+				{
+					if (color_type == FIC_PALETTE) {
+						// Copy the palette
+						memcpy(new_pal, FreeImage_GetPalette(dib), 16 * sizeof(RGBQUAD));
+					}
+
+					// Expand and copy the bitmap data
+					for (unsigned rows = 0; rows < height; rows++) {
+						FreeImage_ConvertLine4To8(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);					
+					}
+					return new_dib;
+				}
+
+				case 16 :
+				{
+					// Expand and copy the bitmap data
+					if (IS_FORMAT_RGB565(dib)) {
+						for (unsigned rows = 0; rows < height; rows++) {
+							FreeImage_ConvertLine16To8_565(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
+						}
+					} else {
+						for (unsigned rows = 0; rows < height; rows++) {
+							FreeImage_ConvertLine16To8_555(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
+						}
+					}
+					return new_dib;
+				}
+
+				case 24 :
+				{
+					// Expand and copy the bitmap data
+					for (unsigned rows = 0; rows < height; rows++) {
+						FreeImage_ConvertLine24To8(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);					
+					}
+					return new_dib;
+				}
+
+				case 32 :
+				{
+					// Expand and copy the bitmap data
+					for (unsigned rows = 0; rows < height; rows++) {
+						FreeImage_ConvertLine32To8(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
+					}
+					return new_dib;
+				}
+			}
+
+		} else if (image_type == FIT_UINT16) {
+
+			const unsigned src_pitch = FreeImage_GetPitch(dib);
+			const unsigned dst_pitch = FreeImage_GetPitch(new_dib);
+			const BYTE *src_bits = FreeImage_GetBits(dib);
+			BYTE *dst_bits = FreeImage_GetBits(new_dib);
+
+			for (unsigned rows = 0; rows < height; rows++) {
+				const WORD *const src_pixel = (WORD*)src_bits;
+				BYTE *dst_pixel = (BYTE*)dst_bits;
+				for(unsigned cols = 0; cols < width; cols++) {
+					dst_pixel[cols] = (BYTE)(src_pixel[cols] >> 8);
+				}
+				src_bits += src_pitch;
+				dst_bits += dst_pitch;
+			}
+			return new_dib;
+		} 
+
+	} // bpp != 8
+
+	return FreeImage_Clone(dib);
+}
+
+FIBITMAP * DLL_CALLCONV
+FreeImage_ConvertToGreyscale(FIBITMAP *dib) {
+	if (!FreeImage_HasPixels(dib)) {
+		return NULL;
+	}
+
+	const FREE_IMAGE_COLOR_TYPE color_type = FreeImage_GetColorType(dib);
+
+	if (color_type == FIC_PALETTE || color_type == FIC_MINISWHITE) {
+
+		const unsigned bpp = FreeImage_GetBPP(dib);
+		const unsigned width  = FreeImage_GetWidth(dib);
+		const unsigned height = FreeImage_GetHeight(dib);
+
+		FIBITMAP *new_dib = FreeImage_Allocate(width, height, 8);
+		if (new_dib == NULL) {
+			return NULL;
+		}
+
+		// Copy metadata from src to dst
+		FreeImage_CloneMetadata(new_dib, dib);
+
+		// Create a greyscale palette
+		BYTE grey_pal[256];
+		const RGBQUAD *pal = FreeImage_GetPalette(dib);
+		const unsigned size = CalculateUsedPaletteEntries(bpp);
+		for (unsigned i = 0; i < size; i++) {
+			grey_pal[i] = GREY(pal->rgbRed, pal->rgbGreen, pal->rgbBlue);
+			pal++;
+		}
+
+		const BYTE *src_bits = FreeImage_GetBits(dib);
+		BYTE *dst_bits = FreeImage_GetBits(new_dib);
+
+		const unsigned src_pitch = FreeImage_GetPitch(dib);
+		const unsigned dst_pitch = FreeImage_GetPitch(new_dib);
+
+		switch(bpp) {
+			case 1:
+			{
+				for (unsigned y = 0; y < height; y++) {
+					for (unsigned x = 0; x < width; x++) {
+						const unsigned pixel = (src_bits[x >> 3] & (0x80 >> (x & 0x07))) != 0;
+						dst_bits[x] = grey_pal[pixel];
+					}
+					src_bits += src_pitch;
+					dst_bits += dst_pitch;
+				}
+			}
+			break;
+
+			case 4:
+			{
+				for (unsigned y = 0; y < height; y++) {
+					for (unsigned x = 0; x < width; x++) {
+						const unsigned pixel = x & 0x01 ? src_bits[x >> 1] & 0x0F : src_bits[x >> 1] >> 4;
+						dst_bits[x] = grey_pal[pixel];
+					}
+					src_bits += src_pitch;
+					dst_bits += dst_pitch;
+				}
+			}
+			break;
+
+			case 8:
+			{
+				for (unsigned y = 0; y < height; y++) {
+					for (unsigned x = 0; x < width; x++) {
+						dst_bits[x] = grey_pal[src_bits[x]];
+					}
+					src_bits += src_pitch;
+					dst_bits += dst_pitch;
+				}
+			}
+			break;
+		}
+		return new_dib;
+	} 
+	
+	// Convert the bitmap to 8-bit greyscale
+	return FreeImage_ConvertTo8Bits(dib);
+}
diff --git a/Source/FreeImage/ConversionFloat.cpp b/Source/FreeImage/ConversionFloat.cpp
index e72d14c..a36a6d4 100644
--- a/Source/FreeImage/ConversionFloat.cpp
+++ b/Source/FreeImage/ConversionFloat.cpp
@@ -1,192 +1,194 @@
-// ==========================================================
-// Bitmap conversion routines
-//
-// Design and implementation by
-// - Herv� Drolon (drolon at infonie.fr)
-//
-// This file is part of FreeImage 3
-//
-// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
-// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
-// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
-// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
-// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
-// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
-// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
-// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
-// THIS DISCLAIMER.
-//
-// Use at your own risk!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-
-// ----------------------------------------------------------
-//   smart convert X to Float
-// ----------------------------------------------------------
-
-FIBITMAP * DLL_CALLCONV
-FreeImage_ConvertToFloat(FIBITMAP *dib) {
-	FIBITMAP *src = NULL;
-	FIBITMAP *dst = NULL;
-
-	if(!FreeImage_HasPixels(dib)) return NULL;
-
-	FREE_IMAGE_TYPE src_type = FreeImage_GetImageType(dib);
-
-	// check for allowed conversions 
-	switch(src_type) {
-		case FIT_BITMAP:
-		{
-			// allow conversion from 8-bit
-			if((FreeImage_GetBPP(dib) == 8) && (FreeImage_GetColorType(dib) == FIC_MINISBLACK)) {
-				src = dib;
-			} else {
-				src = FreeImage_ConvertToGreyscale(dib);
-				if(!src) return NULL;
-			}
-			break;
-		}
-		case FIT_UINT16:
-		case FIT_RGB16:
-		case FIT_RGBA16:
-		case FIT_RGBF:
-		case FIT_RGBAF:
-			src = dib;
-			break;
-		case FIT_FLOAT:
-			// float type : clone the src
-			return FreeImage_Clone(dib);
-		default:
-			return NULL;
-	}
-
-	// allocate dst image
-
-	const unsigned width = FreeImage_GetWidth(src);
-	const unsigned height = FreeImage_GetHeight(src);
-
-	dst = FreeImage_AllocateT(FIT_FLOAT, width, height);
-	if(!dst) {
-		if(src != dib) {
-			FreeImage_Unload(src);
-		}
-		return NULL;
-	}
-
-	// copy metadata from src to dst
-	FreeImage_CloneMetadata(dst, src);
-
-	// convert from src type to float
-
-	const unsigned src_pitch = FreeImage_GetPitch(src);
-	const unsigned dst_pitch = FreeImage_GetPitch(dst);
-
-	const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
-	BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
-
-	switch(src_type) {
-		case FIT_BITMAP:
-		{
-			for(unsigned y = 0; y < height; y++) {
-				const BYTE *src_pixel = (BYTE*)src_bits;
-				float *dst_pixel = (float*)dst_bits;
-				for(unsigned x = 0; x < width; x++) {
-					// convert and scale to the range [0..1]
-					dst_pixel[x] = (float)(src_pixel[x]) / 255;
-				}
-				src_bits += src_pitch;
-				dst_bits += dst_pitch;
-			}
-		}
-		break;
-
-		case FIT_UINT16:
-		{
-			for(unsigned y = 0; y < height; y++) {
-				const WORD *src_pixel = (WORD*)src_bits;
-				float *dst_pixel = (float*)dst_bits;
-
-				for(unsigned x = 0; x < width; x++) {
-					// convert and scale to the range [0..1]
-					dst_pixel[x] = (float)(src_pixel[x]) / 65535;
-				}
-				src_bits += src_pitch;
-				dst_bits += dst_pitch;
-			}
-		}
-		break;
-
-		case FIT_RGB16:
-		{
-			for(unsigned y = 0; y < height; y++) {
-				const FIRGB16 *src_pixel = (FIRGB16*)src_bits;
-				float *dst_pixel = (float*)dst_bits;
-
-				for(unsigned x = 0; x < width; x++) {
-					// convert and scale to the range [0..1]
-					dst_pixel[x] = LUMA_REC709(src_pixel[x].red, src_pixel[x].green, src_pixel[x].blue) / 65535.0F;
-				}
-				src_bits += src_pitch;
-				dst_bits += dst_pitch;
-			}
-		}
-		break;
-
-		case FIT_RGBA16:
-		{
-			for(unsigned y = 0; y < height; y++) {
-				const FIRGBA16 *src_pixel = (FIRGBA16*)src_bits;
-				float *dst_pixel = (float*)dst_bits;
-
-				for(unsigned x = 0; x < width; x++) {
-					// convert and scale to the range [0..1]
-					dst_pixel[x] = LUMA_REC709(src_pixel[x].red, src_pixel[x].green, src_pixel[x].blue) / 65535.0F;
-				}
-				src_bits += src_pitch;
-				dst_bits += dst_pitch;
-			}
-		}
-		break;
-
-		case FIT_RGBF:
-		{
-			for(unsigned y = 0; y < height; y++) {
-				const FIRGBF *src_pixel = (FIRGBF*)src_bits;
-				float *dst_pixel = (float*)dst_bits;
-
-				for(unsigned x = 0; x < width; x++) {
-					// convert (assume pixel values are in the range [0..1])
-					dst_pixel[x] = LUMA_REC709(src_pixel[x].red, src_pixel[x].green, src_pixel[x].blue);
-				}
-				src_bits += src_pitch;
-				dst_bits += dst_pitch;
-			}
-		}
-		break;
-
-		case FIT_RGBAF:
-		{
-			for(unsigned y = 0; y < height; y++) {
-				const FIRGBAF *src_pixel = (FIRGBAF*)src_bits;
-				float *dst_pixel = (float*)dst_bits;
-
-				for(unsigned x = 0; x < width; x++) {
-					// convert (assume pixel values are in the range [0..1])
-					dst_pixel[x] = LUMA_REC709(src_pixel[x].red, src_pixel[x].green, src_pixel[x].blue);
-				}
-				src_bits += src_pitch;
-				dst_bits += dst_pitch;
-			}
-		}
-		break;
-	}
-
-	if(src != dib) {
-		FreeImage_Unload(src);
-	}
-
-	return dst;
-}
-
+// ==========================================================
+// Bitmap conversion routines
+//
+// Design and implementation by
+// - Herv� Drolon (drolon at infonie.fr)
+//
+// This file is part of FreeImage 3
+//
+// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
+// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
+// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
+// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
+// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
+// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
+// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+// THIS DISCLAIMER.
+//
+// Use at your own risk!
+// ==========================================================
+
+#include "FreeImage.h"
+#include "Utilities.h"
+
+// ----------------------------------------------------------
+//   smart convert X to Float
+// ----------------------------------------------------------
+
+FIBITMAP * DLL_CALLCONV
+FreeImage_ConvertToFloat(FIBITMAP *dib) {
+	FIBITMAP *src = NULL;
+	FIBITMAP *dst = NULL;
+
+	if(!FreeImage_HasPixels(dib)) return NULL;
+
+	FREE_IMAGE_TYPE src_type = FreeImage_GetImageType(dib);
+
+	// check for allowed conversions 
+	switch(src_type) {
+		case FIT_BITMAP:
+		{
+			// allow conversion from 8-bit
+			if((FreeImage_GetBPP(dib) == 8) && (FreeImage_GetColorType(dib) == FIC_MINISBLACK)) {
+				src = dib;
+			} else {
+				src = FreeImage_ConvertToGreyscale(dib);
+				if(!src) return NULL;
+			}
+			break;
+		}
+		case FIT_UINT16:
+		case FIT_RGB16:
+		case FIT_RGBA16:
+		case FIT_RGBF:
+		case FIT_RGBAF:
+			src = dib;
+			break;
+		case FIT_FLOAT:
+			// float type : clone the src
+			return FreeImage_Clone(dib);
+		default:
+			return NULL;
+	}
+
+	// allocate dst image
+
+	const unsigned width = FreeImage_GetWidth(src);
+	const unsigned height = FreeImage_GetHeight(src);
+
+	dst = FreeImage_AllocateT(FIT_FLOAT, width, height);
+	if(!dst) {
+		if(src != dib) {
+			FreeImage_Unload(src);
+		}
+		return NULL;
+	}
+
+	// copy metadata from src to dst
+	FreeImage_CloneMetadata(dst, src);
+
+	// convert from src type to float
+
+	const unsigned src_pitch = FreeImage_GetPitch(src);
+	const unsigned dst_pitch = FreeImage_GetPitch(dst);
+
+	const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
+	BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
+
+	switch(src_type) {
+		case FIT_BITMAP:
+		{
+			for(unsigned y = 0; y < height; y++) {
+				const BYTE *src_pixel = (BYTE*)src_bits;
+				float *dst_pixel = (float*)dst_bits;
+				for(unsigned x = 0; x < width; x++) {
+					// convert and scale to the range [0..1]
+					dst_pixel[x] = (float)(src_pixel[x]) / 255;
+				}
+				src_bits += src_pitch;
+				dst_bits += dst_pitch;
+			}
+		}
+		break;
+
+		case FIT_UINT16:
+		{
+			for(unsigned y = 0; y < height; y++) {
+				const WORD *src_pixel = (WORD*)src_bits;
+				float *dst_pixel = (float*)dst_bits;
+
+				for(unsigned x = 0; x < width; x++) {
+					// convert and scale to the range [0..1]
+					dst_pixel[x] = (float)(src_pixel[x]) / 65535;
+				}
+				src_bits += src_pitch;
+				dst_bits += dst_pitch;
+			}
+		}
+		break;
+
+		case FIT_RGB16:
+		{
+			for(unsigned y = 0; y < height; y++) {
+				const FIRGB16 *src_pixel = (FIRGB16*)src_bits;
+				float *dst_pixel = (float*)dst_bits;
+
+				for(unsigned x = 0; x < width; x++) {
+					// convert and scale to the range [0..1]
+					dst_pixel[x] = LUMA_REC709(src_pixel[x].red, src_pixel[x].green, src_pixel[x].blue) / 65535.0F;
+				}
+				src_bits += src_pitch;
+				dst_bits += dst_pitch;
+			}
+		}
+		break;
+
+		case FIT_RGBA16:
+		{
+			for(unsigned y = 0; y < height; y++) {
+				const FIRGBA16 *src_pixel = (FIRGBA16*)src_bits;
+				float *dst_pixel = (float*)dst_bits;
+
+				for(unsigned x = 0; x < width; x++) {
+					// convert and scale to the range [0..1]
+					dst_pixel[x] = LUMA_REC709(src_pixel[x].red, src_pixel[x].green, src_pixel[x].blue) / 65535.0F;
+				}
+				src_bits += src_pitch;
+				dst_bits += dst_pitch;
+			}
+		}
+		break;
+
+		case FIT_RGBF:
+		{
+			for(unsigned y = 0; y < height; y++) {
+				const FIRGBF *src_pixel = (FIRGBF*)src_bits;
+				float *dst_pixel = (float*)dst_bits;
+
+				for(unsigned x = 0; x < width; x++) {
+					// convert (assume pixel values are in the range [0..1])
+					dst_pixel[x] = LUMA_REC709(src_pixel[x].red, src_pixel[x].green, src_pixel[x].blue);
+					dst_pixel[x] = CLAMP(dst_pixel[x], 0.0F, 1.0F);
+				}
+				src_bits += src_pitch;
+				dst_bits += dst_pitch;
+			}
+		}
+		break;
+
+		case FIT_RGBAF:
+		{
+			for(unsigned y = 0; y < height; y++) {
+				const FIRGBAF *src_pixel = (FIRGBAF*)src_bits;
+				float *dst_pixel = (float*)dst_bits;
+
+				for(unsigned x = 0; x < width; x++) {
+					// convert (assume pixel values are in the range [0..1])
+					dst_pixel[x] = LUMA_REC709(src_pixel[x].red, src_pixel[x].green, src_pixel[x].blue);
+					dst_pixel[x] = CLAMP(dst_pixel[x], 0.0F, 1.0F);
+				}
+				src_bits += src_pitch;
+				dst_bits += dst_pitch;
+			}
+		}
+		break;
+	}
+
+	if(src != dib) {
+		FreeImage_Unload(src);
+	}
+
+	return dst;
+}
+
diff --git a/Source/FreeImage/ConversionRGB16.cpp b/Source/FreeImage/ConversionRGB16.cpp
index bd38504..9e28205 100644
--- a/Source/FreeImage/ConversionRGB16.cpp
+++ b/Source/FreeImage/ConversionRGB16.cpp
@@ -1,144 +1,144 @@
-// ==========================================================
-// Bitmap conversion routines
-//
-// Design and implementation by
-// - Herv� Drolon (drolon at infonie.fr)
-//
-// This file is part of FreeImage 3
-//
-// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
-// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
-// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
-// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
-// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
-// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
-// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
-// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
-// THIS DISCLAIMER.
-//
-// Use at your own risk!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-
-// ----------------------------------------------------------
-//   smart convert X to RGB16
-// ----------------------------------------------------------
-
-FIBITMAP * DLL_CALLCONV
-FreeImage_ConvertToRGB16(FIBITMAP *dib) {
-	FIBITMAP *src = NULL;
-	FIBITMAP *dst = NULL;
-
-	if(!FreeImage_HasPixels(dib)) return NULL;
-
-	const FREE_IMAGE_TYPE src_type = FreeImage_GetImageType(dib);
-
-	// check for allowed conversions 
-	switch(src_type) {
-		case FIT_BITMAP:
-		{
-			// convert to 24-bit if needed
-			if((FreeImage_GetBPP(dib) == 24) || (FreeImage_GetBPP(dib) == 32)) {
-				src = dib;
-			} else {
-				src = FreeImage_ConvertTo24Bits(dib);
-				if(!src) return NULL;
-			}
-			break;
-		}
-		case FIT_UINT16:
-			// allow conversion from unsigned 16-bit
-			src = dib;
-			break;
-		case FIT_RGB16:
-			// RGB16 type : clone the src
-			return FreeImage_Clone(dib);
-			break;
-		case FIT_RGBA16:
-			// allow conversion from 64-bit RGBA (ignore the alpha channel)
-			src = dib;
-			break;
-		default:
-			return NULL;
-	}
-
-	// allocate dst image
-
-	const unsigned width = FreeImage_GetWidth(src);
-	const unsigned height = FreeImage_GetHeight(src);
-
-	dst = FreeImage_AllocateT(FIT_RGB16, width, height);
-	if(!dst) {
-		if(src != dib) {
-			FreeImage_Unload(src);
-		}
-		return NULL;
-	}
-
-	// copy metadata from src to dst
-	FreeImage_CloneMetadata(dst, src);
-
-	// convert from src type to RGB16
-
-	switch(src_type) {
-		case FIT_BITMAP:
-		{
-			// Calculate the number of bytes per pixel (1 for 8-bit, 3 for 24-bit or 4 for 32-bit)
-			const unsigned bytespp = FreeImage_GetLine(src) / FreeImage_GetWidth(src);
-
-			for(unsigned y = 0; y < height; y++) {
-				const BYTE *src_bits = (BYTE*)FreeImage_GetScanLine(src, y);
-				FIRGB16 *dst_bits = (FIRGB16*)FreeImage_GetScanLine(dst, y);
-				for(unsigned x = 0; x < width; x++) {
-					dst_bits[x].red   = src_bits[FI_RGBA_RED] << 8;
-					dst_bits[x].green = src_bits[FI_RGBA_GREEN] << 8;
-					dst_bits[x].blue  = src_bits[FI_RGBA_BLUE] << 8;
-					src_bits += bytespp;
-				}
-			}
-		}
-		break;
-
-		case FIT_UINT16:
-		{
-			for(unsigned y = 0; y < height; y++) {
-				const WORD *src_bits = (WORD*)FreeImage_GetScanLine(src, y);
-				FIRGB16 *dst_bits = (FIRGB16*)FreeImage_GetScanLine(dst, y);
-				for(unsigned x = 0; x < width; x++) {
-					// convert by copying greyscale channel to each R, G, B channels
-					dst_bits[x].red   = src_bits[x];
-					dst_bits[x].green = src_bits[x];
-					dst_bits[x].blue  = src_bits[x];
-				}
-			}
-		}
-		break;
-
-		case FIT_RGBA16:
-		{
-			for(unsigned y = 0; y < height; y++) {
-				const FIRGBA16 *src_bits = (FIRGBA16*)FreeImage_GetScanLine(src, y);
-				FIRGB16 *dst_bits = (FIRGB16*)FreeImage_GetScanLine(dst, y);
-				for(unsigned x = 0; x < width; x++) {
-					// convert and skip alpha channel
-					dst_bits[x].red   = src_bits[x].red;
-					dst_bits[x].green = src_bits[x].green;
-					dst_bits[x].blue  = src_bits[x].blue;
-				}
-			}
-		}
-		break;
-
-		default:
-			break;
-	}
-
-	if(src != dib) {
-		FreeImage_Unload(src);
-	}
-
-	return dst;
-}
-
+// ==========================================================
+// Bitmap conversion routines
+//
+// Design and implementation by
+// - Herv� Drolon (drolon at infonie.fr)
+//
+// This file is part of FreeImage 3
+//
+// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
+// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
+// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
+// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
+// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
+// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
+// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+// THIS DISCLAIMER.
+//
+// Use at your own risk!
+// ==========================================================
+
+#include "FreeImage.h"
+#include "Utilities.h"
+
+// ----------------------------------------------------------
+//   smart convert X to RGB16
+// ----------------------------------------------------------
+
+FIBITMAP * DLL_CALLCONV
+FreeImage_ConvertToRGB16(FIBITMAP *dib) {
+	FIBITMAP *src = NULL;
+	FIBITMAP *dst = NULL;
+
+	if(!FreeImage_HasPixels(dib)) return NULL;
+
+	const FREE_IMAGE_TYPE src_type = FreeImage_GetImageType(dib);
+
+	// check for allowed conversions 
+	switch(src_type) {
+		case FIT_BITMAP:
+		{
+			// convert to 24-bit if needed
+			if((FreeImage_GetBPP(dib) == 24) || (FreeImage_GetBPP(dib) == 32)) {
+				src = dib;
+			} else {
+				src = FreeImage_ConvertTo24Bits(dib);
+				if(!src) return NULL;
+			}
+			break;
+		}
+		case FIT_UINT16:
+			// allow conversion from unsigned 16-bit
+			src = dib;
+			break;
+		case FIT_RGB16:
+			// RGB16 type : clone the src
+			return FreeImage_Clone(dib);
+			break;
+		case FIT_RGBA16:
+			// allow conversion from 64-bit RGBA (ignore the alpha channel)
+			src = dib;
+			break;
+		default:
+			return NULL;
+	}
+
+	// allocate dst image
+
+	const unsigned width = FreeImage_GetWidth(src);
+	const unsigned height = FreeImage_GetHeight(src);
+
+	dst = FreeImage_AllocateT(FIT_RGB16, width, height);
+	if(!dst) {
+		if(src != dib) {
+			FreeImage_Unload(src);
+		}
+		return NULL;
+	}
+
+	// copy metadata from src to dst
+	FreeImage_CloneMetadata(dst, src);
+
+	// convert from src type to RGB16
+
+	switch(src_type) {
+		case FIT_BITMAP:
+		{
+			// Calculate the number of bytes per pixel (1 for 8-bit, 3 for 24-bit or 4 for 32-bit)
+			const unsigned bytespp = FreeImage_GetLine(src) / FreeImage_GetWidth(src);
+
+			for(unsigned y = 0; y < height; y++) {
+				const BYTE *src_bits = (BYTE*)FreeImage_GetScanLine(src, y);
+				FIRGB16 *dst_bits = (FIRGB16*)FreeImage_GetScanLine(dst, y);
+				for(unsigned x = 0; x < width; x++) {
+					dst_bits[x].red   = src_bits[FI_RGBA_RED] << 8;
+					dst_bits[x].green = src_bits[FI_RGBA_GREEN] << 8;
+					dst_bits[x].blue  = src_bits[FI_RGBA_BLUE] << 8;
+					src_bits += bytespp;
+				}
+			}
+		}
+		break;
+
+		case FIT_UINT16:
+		{
+			for(unsigned y = 0; y < height; y++) {
+				const WORD *src_bits = (WORD*)FreeImage_GetScanLine(src, y);
+				FIRGB16 *dst_bits = (FIRGB16*)FreeImage_GetScanLine(dst, y);
+				for(unsigned x = 0; x < width; x++) {
+					// convert by copying greyscale channel to each R, G, B channels
+					dst_bits[x].red   = src_bits[x];
+					dst_bits[x].green = src_bits[x];
+					dst_bits[x].blue  = src_bits[x];
+				}
+			}
+		}
+		break;
+
+		case FIT_RGBA16:
+		{
+			for(unsigned y = 0; y < height; y++) {
+				const FIRGBA16 *src_bits = (FIRGBA16*)FreeImage_GetScanLine(src, y);
+				FIRGB16 *dst_bits = (FIRGB16*)FreeImage_GetScanLine(dst, y);
+				for(unsigned x = 0; x < width; x++) {
+					// convert and skip alpha channel
+					dst_bits[x].red   = src_bits[x].red;
+					dst_bits[x].green = src_bits[x].green;
+					dst_bits[x].blue  = src_bits[x].blue;
+				}
+			}
+		}
+		break;
+
+		default:
+			break;
+	}
+
+	if(src != dib) {
+		FreeImage_Unload(src);
+	}
+
+	return dst;
+}
+
diff --git a/Source/FreeImage/ConversionRGBA16.cpp b/Source/FreeImage/ConversionRGBA16.cpp
new file mode 100644
index 0000000..7924bd9
--- /dev/null
+++ b/Source/FreeImage/ConversionRGBA16.cpp
@@ -0,0 +1,147 @@
+// ==========================================================
+// Bitmap conversion routines
+//
+// Design and implementation by
+// - Herv� Drolon (drolon at infonie.fr)
+//
+// This file is part of FreeImage 3
+//
+// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
+// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
+// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
+// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
+// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
+// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
+// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+// THIS DISCLAIMER.
+//
+// Use at your own risk!
+// ==========================================================
+
+#include "FreeImage.h"
+#include "Utilities.h"
+
+// ----------------------------------------------------------
+//   smart convert X to RGBA16
+// ----------------------------------------------------------
+
+FIBITMAP * DLL_CALLCONV
+FreeImage_ConvertToRGBA16(FIBITMAP *dib) {
+	FIBITMAP *src = NULL;
+	FIBITMAP *dst = NULL;
+
+	if(!FreeImage_HasPixels(dib)) return NULL;
+
+	const FREE_IMAGE_TYPE src_type = FreeImage_GetImageType(dib);
+
+	// check for allowed conversions 
+	switch(src_type) {
+		case FIT_BITMAP:
+		{
+			// convert to 32-bit if needed
+			if(FreeImage_GetBPP(dib) == 32) {
+				src = dib;
+			} else {
+				src = FreeImage_ConvertTo32Bits(dib);
+				if(!src) return NULL;
+			}
+			break;
+		}
+		case FIT_UINT16:
+			// allow conversion from unsigned 16-bit
+			src = dib;
+			break;
+		case FIT_RGB16:
+			// allow conversion from 48-bit RGB
+			src = dib;
+			break;
+		case FIT_RGBA16:
+			// RGBA16 type : clone the src
+			return FreeImage_Clone(dib);
+			break;
+		default:
+			return NULL;
+	}
+
+	// allocate dst image
+
+	const unsigned width = FreeImage_GetWidth(src);
+	const unsigned height = FreeImage_GetHeight(src);
+
+	dst = FreeImage_AllocateT(FIT_RGBA16, width, height);
+	if(!dst) {
+		if(src != dib) {
+			FreeImage_Unload(src);
+		}
+		return NULL;
+	}
+
+	// copy metadata from src to dst
+	FreeImage_CloneMetadata(dst, src);
+
+	// convert from src type to RGBA16
+
+	switch(src_type) {
+		case FIT_BITMAP:
+		{
+			// Calculate the number of bytes per pixel (4 for 32-bit)
+			const unsigned bytespp = FreeImage_GetLine(src) / FreeImage_GetWidth(src);
+
+			for(unsigned y = 0; y < height; y++) {
+				const BYTE *src_bits = (BYTE*)FreeImage_GetScanLine(src, y);
+				FIRGBA16 *dst_bits = (FIRGBA16*)FreeImage_GetScanLine(dst, y);
+				for(unsigned x = 0; x < width; x++) {
+					dst_bits[x].red		= src_bits[FI_RGBA_RED] << 8;
+					dst_bits[x].green	= src_bits[FI_RGBA_GREEN] << 8;
+					dst_bits[x].blue	= src_bits[FI_RGBA_BLUE] << 8;
+					dst_bits[x].alpha	= src_bits[FI_RGBA_ALPHA] << 8;
+					src_bits += bytespp;
+				}
+			}
+		}
+		break;
+
+		case FIT_UINT16:
+		{
+			for(unsigned y = 0; y < height; y++) {
+				const WORD *src_bits = (WORD*)FreeImage_GetScanLine(src, y);
+				FIRGBA16 *dst_bits = (FIRGBA16*)FreeImage_GetScanLine(dst, y);
+				for(unsigned x = 0; x < width; x++) {
+					// convert by copying greyscale channel to each R, G, B channels
+					dst_bits[x].red   = src_bits[x];
+					dst_bits[x].green = src_bits[x];
+					dst_bits[x].blue  = src_bits[x];
+					dst_bits[x].alpha = 0xFFFF;
+				}
+			}
+		}
+		break;
+
+		case FIT_RGB16:
+		{
+			for(unsigned y = 0; y < height; y++) {
+				const FIRGB16 *src_bits = (FIRGB16*)FreeImage_GetScanLine(src, y);
+				FIRGBA16 *dst_bits = (FIRGBA16*)FreeImage_GetScanLine(dst, y);
+				for(unsigned x = 0; x < width; x++) {
+					// convert pixels directly, while adding a "dummy" alpha of 1.0
+					dst_bits[x].red   = src_bits[x].red;
+					dst_bits[x].green = src_bits[x].green;
+					dst_bits[x].blue  = src_bits[x].blue;
+					dst_bits[x].alpha = 0xFFFF;
+				}
+			}
+		}
+		break;
+
+		default:
+			break;
+	}
+
+	if(src != dib) {
+		FreeImage_Unload(src);
+	}
+
+	return dst;
+}
+
diff --git a/Source/FreeImage/ConversionRGBAF.cpp b/Source/FreeImage/ConversionRGBAF.cpp
new file mode 100644
index 0000000..1e23aaa
--- /dev/null
+++ b/Source/FreeImage/ConversionRGBAF.cpp
@@ -0,0 +1,250 @@
+// ==========================================================
+// Bitmap conversion routines
+//
+// Design and implementation by
+// - Tanner Helland (tannerhelland at users.sf.net)
+// - Herv� Drolon (drolon at infonie.fr)
+//
+// This file is part of FreeImage 3
+//
+// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
+// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
+// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
+// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
+// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
+// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
+// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+// THIS DISCLAIMER.
+//
+// Use at your own risk!
+// ==========================================================
+
+#include "FreeImage.h"
+#include "Utilities.h"
+
+// ----------------------------------------------------------
+//   smart convert X to RGBAF
+// ----------------------------------------------------------
+
+FIBITMAP * DLL_CALLCONV
+FreeImage_ConvertToRGBAF(FIBITMAP *dib) {
+	FIBITMAP *src = NULL;
+	FIBITMAP *dst = NULL;
+
+	if(!FreeImage_HasPixels(dib)) return NULL;
+
+	const FREE_IMAGE_TYPE src_type = FreeImage_GetImageType(dib);
+
+	// check for allowed conversions 
+	switch(src_type) {
+		case FIT_BITMAP:
+		{
+			// allow conversion from 32-bit
+			const FREE_IMAGE_COLOR_TYPE color_type = FreeImage_GetColorType(dib);
+			if(color_type != FIC_RGBALPHA) {
+				src = FreeImage_ConvertTo32Bits(dib);
+				if(!src) return NULL;
+			} else {
+				src = dib;
+			}
+			break;
+		}
+		case FIT_UINT16:
+			// allow conversion from 16-bit
+			src = dib;
+			break;
+		case FIT_RGB16:
+			// allow conversion from 48-bit RGB
+			src = dib;
+			break;
+		case FIT_RGBA16:
+			// allow conversion from 64-bit RGBA
+			src = dib;
+			break;
+		case FIT_FLOAT:
+			// allow conversion from 32-bit float
+			src = dib;
+			break;
+		case FIT_RGBF:
+			// allow conversion from 96-bit RGBF
+			src = dib;
+			break;
+		case FIT_RGBAF:
+			// RGBAF type : clone the src
+			return FreeImage_Clone(dib);
+			break;
+		default:
+			return NULL;
+	}
+
+	// allocate dst image
+
+	const unsigned width = FreeImage_GetWidth(src);
+	const unsigned height = FreeImage_GetHeight(src);
+
+	dst = FreeImage_AllocateT(FIT_RGBAF, width, height);
+	if(!dst) {
+		if(src != dib) {
+			FreeImage_Unload(src);
+		}
+		return NULL;
+	}
+
+	// copy metadata from src to dst
+	FreeImage_CloneMetadata(dst, src);
+
+	// convert from src type to RGBAF
+
+	const unsigned src_pitch = FreeImage_GetPitch(src);
+	const unsigned dst_pitch = FreeImage_GetPitch(dst);
+
+	switch(src_type) {
+		case FIT_BITMAP:
+		{
+			// calculate the number of bytes per pixel (4 for 32-bit)
+			const unsigned bytespp = FreeImage_GetLine(src) / FreeImage_GetWidth(src);
+
+			const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
+			BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
+
+			for(unsigned y = 0; y < height; y++) {
+				const BYTE *src_pixel = (BYTE*)src_bits;
+				FIRGBAF *dst_pixel = (FIRGBAF*)dst_bits;
+				for(unsigned x = 0; x < width; x++) {
+					// convert and scale to the range [0..1]
+					dst_pixel->red   = (float)(src_pixel[FI_RGBA_RED])   / 255.0F;
+					dst_pixel->green = (float)(src_pixel[FI_RGBA_GREEN]) / 255.0F;
+					dst_pixel->blue  = (float)(src_pixel[FI_RGBA_BLUE])  / 255.0F;
+					dst_pixel->alpha = (float)(src_pixel[FI_RGBA_ALPHA]) / 255.0F;
+
+					src_pixel += bytespp;
+					dst_pixel++;
+				}
+				src_bits += src_pitch;
+				dst_bits += dst_pitch;
+			}
+		}
+		break;
+
+		case FIT_UINT16:
+		{
+			const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
+			BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
+
+			for(unsigned y = 0; y < height; y++) {
+				const WORD *src_pixel = (WORD*)src_bits;
+				FIRGBAF *dst_pixel = (FIRGBAF*)dst_bits;
+
+				for(unsigned x = 0; x < width; x++) {
+					// convert and scale to the range [0..1]
+					const float dst_value = (float)src_pixel[x] / 65535.0F;
+					dst_pixel[x].red   = dst_value;
+					dst_pixel[x].green = dst_value;
+					dst_pixel[x].blue  = dst_value;
+					dst_pixel[x].alpha = 1.0F;
+				}
+				src_bits += src_pitch;
+				dst_bits += dst_pitch;
+			}
+		}
+		break;
+
+		case FIT_RGB16:
+		{
+			const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
+			BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
+
+			for(unsigned y = 0; y < height; y++) {
+				const FIRGB16 *src_pixel = (FIRGB16*)src_bits;
+				FIRGBAF *dst_pixel = (FIRGBAF*)dst_bits;
+
+				for(unsigned x = 0; x < width; x++) {
+					// convert and scale to the range [0..1]
+					dst_pixel[x].red   = (float)(src_pixel[x].red)   / 65535.0F;
+					dst_pixel[x].green = (float)(src_pixel[x].green) / 65535.0F;
+					dst_pixel[x].blue  = (float)(src_pixel[x].blue)  / 65535.0F;
+					dst_pixel[x].alpha = 1.0F;
+				}
+				src_bits += src_pitch;
+				dst_bits += dst_pitch;
+			}
+		}
+		break;
+
+		case FIT_RGBA16:
+		{
+			const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
+			BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
+
+			for(unsigned y = 0; y < height; y++) {
+				const FIRGBA16 *src_pixel = (FIRGBA16*)src_bits;
+				FIRGBAF *dst_pixel = (FIRGBAF*)dst_bits;
+
+				for(unsigned x = 0; x < width; x++) {
+					// convert and scale to the range [0..1]
+					dst_pixel[x].red   = (float)(src_pixel[x].red)   / 65535.0F;
+					dst_pixel[x].green = (float)(src_pixel[x].green) / 65535.0F;
+					dst_pixel[x].blue  = (float)(src_pixel[x].blue)  / 65535.0F;
+					dst_pixel[x].alpha = (float)(src_pixel[x].alpha) / 65535.0F;
+				}
+				src_bits += src_pitch;
+				dst_bits += dst_pitch;
+			}
+		}
+		break;
+
+		case FIT_FLOAT:
+		{
+			const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
+			BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
+
+			for(unsigned y = 0; y < height; y++) {
+				const float *src_pixel = (float*)src_bits;
+				FIRGBAF *dst_pixel = (FIRGBAF*)dst_bits;
+
+				for(unsigned x = 0; x < width; x++) {
+					// convert by copying greyscale channel to each R, G, B channels
+					// assume float values are in [0..1]
+					const float value = CLAMP(src_pixel[x], 0.0F, 1.0F);
+					dst_pixel[x].red   = value;
+					dst_pixel[x].green = value;
+					dst_pixel[x].blue  = value;
+					dst_pixel[x].alpha = 1.0F;
+				}
+				src_bits += src_pitch;
+				dst_bits += dst_pitch;
+			}
+		}
+		break;
+
+		case FIT_RGBF:
+		{
+			const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
+			BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
+
+			for(unsigned y = 0; y < height; y++) {
+				const FIRGBF *src_pixel = (FIRGBF*)src_bits;
+				FIRGBAF *dst_pixel = (FIRGBAF*)dst_bits;
+
+				for(unsigned x = 0; x < width; x++) {
+					// convert pixels directly, while adding a "dummy" alpha of 1.0
+					dst_pixel[x].red   = CLAMP(src_pixel[x].red, 0.0F, 1.0F);
+					dst_pixel[x].green = CLAMP(src_pixel[x].green, 0.0F, 1.0F);
+					dst_pixel[x].blue  = CLAMP(src_pixel[x].blue, 0.0F, 1.0F);
+					dst_pixel[x].alpha = 1.0F;
+				}
+				src_bits += src_pitch;
+				dst_bits += dst_pitch;
+			}
+		}
+		break;
+	}
+
+	if(src != dib) {
+		FreeImage_Unload(src);
+	}
+
+	return dst;
+}
+
diff --git a/Source/FreeImage/ConversionRGBF.cpp b/Source/FreeImage/ConversionRGBF.cpp
index b5161d5..230dd7b 100644
--- a/Source/FreeImage/ConversionRGBF.cpp
+++ b/Source/FreeImage/ConversionRGBF.cpp
@@ -1,241 +1,243 @@
-// ==========================================================
-// Bitmap conversion routines
-//
-// Design and implementation by
-// - Herv� Drolon (drolon at infonie.fr)
-//
-// This file is part of FreeImage 3
-//
-// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
-// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
-// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
-// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
-// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
-// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
-// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
-// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
-// THIS DISCLAIMER.
-//
-// Use at your own risk!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-
-// ----------------------------------------------------------
-//   smart convert X to RGBF
-// ----------------------------------------------------------
-
-FIBITMAP * DLL_CALLCONV
-FreeImage_ConvertToRGBF(FIBITMAP *dib) {
-	FIBITMAP *src = NULL;
-	FIBITMAP *dst = NULL;
-
-	if(!FreeImage_HasPixels(dib)) return NULL;
-
-	const FREE_IMAGE_TYPE src_type = FreeImage_GetImageType(dib);
-
-	// check for allowed conversions 
-	switch(src_type) {
-		case FIT_BITMAP:
-		{
-			// allow conversion from 24- and 32-bit
-			const FREE_IMAGE_COLOR_TYPE color_type = FreeImage_GetColorType(dib);
-			if((color_type != FIC_RGB) && (color_type != FIC_RGBALPHA)) {
-				src = FreeImage_ConvertTo24Bits(dib);
-				if(!src) return NULL;
-			} else {
-				src = dib;
-			}
-			break;
-		}
-		case FIT_UINT16:
-			// allow conversion from 16-bit
-			src = dib;
-			break;
-		case FIT_RGB16:
-			// allow conversion from 48-bit RGB
-			src = dib;
-			break;
-		case FIT_RGBA16:
-			// allow conversion from 64-bit RGBA (ignore the alpha channel)
-			src = dib;
-			break;
-		case FIT_FLOAT:
-			// allow conversion from 32-bit float
-			src = dib;
-			break;
-		case FIT_RGBAF:
-			// allow conversion from 128-bit RGBAF
-			src = dib;
-			break;
-		case FIT_RGBF:
-			// RGBF type : clone the src
-			return FreeImage_Clone(dib);
-			break;
-		default:
-			return NULL;
-	}
-
-	// allocate dst image
-
-	const unsigned width = FreeImage_GetWidth(src);
-	const unsigned height = FreeImage_GetHeight(src);
-
-	dst = FreeImage_AllocateT(FIT_RGBF, width, height);
-	if(!dst) {
-		if(src != dib) {
-			FreeImage_Unload(src);
-		}
-		return NULL;
-	}
-
-	// copy metadata from src to dst
-	FreeImage_CloneMetadata(dst, src);
-
-	// convert from src type to RGBF
-
-	const unsigned src_pitch = FreeImage_GetPitch(src);
-	const unsigned dst_pitch = FreeImage_GetPitch(dst);
-
-	switch(src_type) {
-		case FIT_BITMAP:
-		{
-			// calculate the number of bytes per pixel (3 for 24-bit or 4 for 32-bit)
-			const unsigned bytespp = FreeImage_GetLine(src) / FreeImage_GetWidth(src);
-
-			const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
-			BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
-
-			for(unsigned y = 0; y < height; y++) {
-				const BYTE   *src_pixel = (BYTE*)src_bits;
-				FIRGBF *dst_pixel = (FIRGBF*)dst_bits;
-				for(unsigned x = 0; x < width; x++) {
-					// convert and scale to the range [0..1]
-					dst_pixel->red   = (float)(src_pixel[FI_RGBA_RED])   / 255.0F;
-					dst_pixel->green = (float)(src_pixel[FI_RGBA_GREEN]) / 255.0F;
-					dst_pixel->blue  = (float)(src_pixel[FI_RGBA_BLUE])  / 255.0F;
-
-					src_pixel += bytespp;
-					dst_pixel ++;
-				}
-				src_bits += src_pitch;
-				dst_bits += dst_pitch;
-			}
-		}
-		break;
-
-		case FIT_UINT16:
-		{
-			const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
-			BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
-
-			for(unsigned y = 0; y < height; y++) {
-				const WORD *src_pixel = (WORD*)src_bits;
-				FIRGBF *dst_pixel = (FIRGBF*)dst_bits;
-
-				for(unsigned x = 0; x < width; x++) {
-					// convert and scale to the range [0..1]
-					const float dst_value = (float)src_pixel[x] / 65535.0F;
-					dst_pixel[x].red   = dst_value;
-					dst_pixel[x].green = dst_value;
-					dst_pixel[x].blue  = dst_value;
-				}
-				src_bits += src_pitch;
-				dst_bits += dst_pitch;
-			}
-		}
-		break;
-
-		case FIT_RGB16:
-		{
-			const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
-			BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
-
-			for(unsigned y = 0; y < height; y++) {
-				const FIRGB16 *src_pixel = (FIRGB16*) src_bits;
-				FIRGBF  *dst_pixel = (FIRGBF*)  dst_bits;
-
-				for(unsigned x = 0; x < width; x++) {
-					// convert and scale to the range [0..1]
-					dst_pixel[x].red   = (float)(src_pixel[x].red)   / 65535.0F;
-					dst_pixel[x].green = (float)(src_pixel[x].green) / 65535.0F;
-					dst_pixel[x].blue  = (float)(src_pixel[x].blue)  / 65535.0F;
-				}
-				src_bits += src_pitch;
-				dst_bits += dst_pitch;
-			}
-		}
-		break;
-
-		case FIT_RGBA16:
-		{
-			const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
-			BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
-
-			for(unsigned y = 0; y < height; y++) {
-				const FIRGBA16 *src_pixel = (FIRGBA16*) src_bits;
-				FIRGBF  *dst_pixel = (FIRGBF*)  dst_bits;
-
-				for(unsigned x = 0; x < width; x++) {
-					// convert and scale to the range [0..1]
-					dst_pixel[x].red   = (float)(src_pixel[x].red)   / 65535.0F;
-					dst_pixel[x].green = (float)(src_pixel[x].green) / 65535.0F;
-					dst_pixel[x].blue  = (float)(src_pixel[x].blue)  / 65535.0F;
-				}
-				src_bits += src_pitch;
-				dst_bits += dst_pitch;
-			}
-		}
-		break;
-
-		case FIT_FLOAT:
-		{
-			const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
-			BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
-
-			for(unsigned y = 0; y < height; y++) {
-				const float *src_pixel = (float*) src_bits;
-				FIRGBF  *dst_pixel = (FIRGBF*)  dst_bits;
-
-				for(unsigned x = 0; x < width; x++) {
-					// convert by copying greyscale channel to each R, G, B channels
-					dst_pixel[x].red   = src_pixel[x];
-					dst_pixel[x].green = src_pixel[x];
-					dst_pixel[x].blue  = src_pixel[x];
-				}
-				src_bits += src_pitch;
-				dst_bits += dst_pitch;
-			}
-		}
-		break;
-
-		case FIT_RGBAF:
-		{
-			const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
-			BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
-
-			for(unsigned y = 0; y < height; y++) {
-				const FIRGBAF *src_pixel = (FIRGBAF*) src_bits;
-				FIRGBF  *dst_pixel = (FIRGBF*)  dst_bits;
-
-				for(unsigned x = 0; x < width; x++) {
-					// convert and skip alpha channel
-					dst_pixel[x].red   = src_pixel[x].red;
-					dst_pixel[x].green = src_pixel[x].green;
-					dst_pixel[x].blue  = src_pixel[x].blue;
-				}
-				src_bits += src_pitch;
-				dst_bits += dst_pitch;
-			}
-		}
-		break;
-	}
-
-	if(src != dib) {
-		FreeImage_Unload(src);
-	}
-
-	return dst;
-}
-
+// ==========================================================
+// Bitmap conversion routines
+//
+// Design and implementation by
+// - Herv� Drolon (drolon at infonie.fr)
+//
+// This file is part of FreeImage 3
+//
+// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
+// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
+// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
+// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
+// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
+// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
+// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+// THIS DISCLAIMER.
+//
+// Use at your own risk!
+// ==========================================================
+
+#include "FreeImage.h"
+#include "Utilities.h"
+
+// ----------------------------------------------------------
+//   smart convert X to RGBF
+// ----------------------------------------------------------
+
+FIBITMAP * DLL_CALLCONV
+FreeImage_ConvertToRGBF(FIBITMAP *dib) {
+	FIBITMAP *src = NULL;
+	FIBITMAP *dst = NULL;
+
+	if(!FreeImage_HasPixels(dib)) return NULL;
+
+	const FREE_IMAGE_TYPE src_type = FreeImage_GetImageType(dib);
+
+	// check for allowed conversions 
+	switch(src_type) {
+		case FIT_BITMAP:
+		{
+			// allow conversion from 24- and 32-bit
+			const FREE_IMAGE_COLOR_TYPE color_type = FreeImage_GetColorType(dib);
+			if((color_type != FIC_RGB) && (color_type != FIC_RGBALPHA)) {
+				src = FreeImage_ConvertTo24Bits(dib);
+				if(!src) return NULL;
+			} else {
+				src = dib;
+			}
+			break;
+		}
+		case FIT_UINT16:
+			// allow conversion from 16-bit
+			src = dib;
+			break;
+		case FIT_RGB16:
+			// allow conversion from 48-bit RGB
+			src = dib;
+			break;
+		case FIT_RGBA16:
+			// allow conversion from 64-bit RGBA (ignore the alpha channel)
+			src = dib;
+			break;
+		case FIT_FLOAT:
+			// allow conversion from 32-bit float
+			src = dib;
+			break;
+		case FIT_RGBAF:
+			// allow conversion from 128-bit RGBAF
+			src = dib;
+			break;
+		case FIT_RGBF:
+			// RGBF type : clone the src
+			return FreeImage_Clone(dib);
+			break;
+		default:
+			return NULL;
+	}
+
+	// allocate dst image
+
+	const unsigned width = FreeImage_GetWidth(src);
+	const unsigned height = FreeImage_GetHeight(src);
+
+	dst = FreeImage_AllocateT(FIT_RGBF, width, height);
+	if(!dst) {
+		if(src != dib) {
+			FreeImage_Unload(src);
+		}
+		return NULL;
+	}
+
+	// copy metadata from src to dst
+	FreeImage_CloneMetadata(dst, src);
+
+	// convert from src type to RGBF
+
+	const unsigned src_pitch = FreeImage_GetPitch(src);
+	const unsigned dst_pitch = FreeImage_GetPitch(dst);
+
+	switch(src_type) {
+		case FIT_BITMAP:
+		{
+			// calculate the number of bytes per pixel (3 for 24-bit or 4 for 32-bit)
+			const unsigned bytespp = FreeImage_GetLine(src) / FreeImage_GetWidth(src);
+
+			const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
+			BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
+
+			for(unsigned y = 0; y < height; y++) {
+				const BYTE   *src_pixel = (BYTE*)src_bits;
+				FIRGBF *dst_pixel = (FIRGBF*)dst_bits;
+				for(unsigned x = 0; x < width; x++) {
+					// convert and scale to the range [0..1]
+					dst_pixel->red   = (float)(src_pixel[FI_RGBA_RED])   / 255.0F;
+					dst_pixel->green = (float)(src_pixel[FI_RGBA_GREEN]) / 255.0F;
+					dst_pixel->blue  = (float)(src_pixel[FI_RGBA_BLUE])  / 255.0F;
+
+					src_pixel += bytespp;
+					dst_pixel ++;
+				}
+				src_bits += src_pitch;
+				dst_bits += dst_pitch;
+			}
+		}
+		break;
+
+		case FIT_UINT16:
+		{
+			const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
+			BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
+
+			for(unsigned y = 0; y < height; y++) {
+				const WORD *src_pixel = (WORD*)src_bits;
+				FIRGBF *dst_pixel = (FIRGBF*)dst_bits;
+
+				for(unsigned x = 0; x < width; x++) {
+					// convert and scale to the range [0..1]
+					const float dst_value = (float)src_pixel[x] / 65535.0F;
+					dst_pixel[x].red   = dst_value;
+					dst_pixel[x].green = dst_value;
+					dst_pixel[x].blue  = dst_value;
+				}
+				src_bits += src_pitch;
+				dst_bits += dst_pitch;
+			}
+		}
+		break;
+
+		case FIT_RGB16:
+		{
+			const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
+			BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
+
+			for(unsigned y = 0; y < height; y++) {
+				const FIRGB16 *src_pixel = (FIRGB16*) src_bits;
+				FIRGBF  *dst_pixel = (FIRGBF*)  dst_bits;
+
+				for(unsigned x = 0; x < width; x++) {
+					// convert and scale to the range [0..1]
+					dst_pixel[x].red   = (float)(src_pixel[x].red)   / 65535.0F;
+					dst_pixel[x].green = (float)(src_pixel[x].green) / 65535.0F;
+					dst_pixel[x].blue  = (float)(src_pixel[x].blue)  / 65535.0F;
+				}
+				src_bits += src_pitch;
+				dst_bits += dst_pitch;
+			}
+		}
+		break;
+
+		case FIT_RGBA16:
+		{
+			const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
+			BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
+
+			for(unsigned y = 0; y < height; y++) {
+				const FIRGBA16 *src_pixel = (FIRGBA16*) src_bits;
+				FIRGBF  *dst_pixel = (FIRGBF*)  dst_bits;
+
+				for(unsigned x = 0; x < width; x++) {
+					// convert and scale to the range [0..1]
+					dst_pixel[x].red   = (float)(src_pixel[x].red)   / 65535.0F;
+					dst_pixel[x].green = (float)(src_pixel[x].green) / 65535.0F;
+					dst_pixel[x].blue  = (float)(src_pixel[x].blue)  / 65535.0F;
+				}
+				src_bits += src_pitch;
+				dst_bits += dst_pitch;
+			}
+		}
+		break;
+
+		case FIT_FLOAT:
+		{
+			const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
+			BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
+
+			for(unsigned y = 0; y < height; y++) {
+				const float *src_pixel = (float*) src_bits;
+				FIRGBF  *dst_pixel = (FIRGBF*)  dst_bits;
+
+				for(unsigned x = 0; x < width; x++) {
+					// convert by copying greyscale channel to each R, G, B channels
+					// assume float values are in [0..1]
+					const float value = CLAMP(src_pixel[x], 0.0F, 1.0F);
+					dst_pixel[x].red   = value;
+					dst_pixel[x].green = value;
+					dst_pixel[x].blue  = value;
+				}
+				src_bits += src_pitch;
+				dst_bits += dst_pitch;
+			}
+		}
+		break;
+
+		case FIT_RGBAF:
+		{
+			const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
+			BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
+
+			for(unsigned y = 0; y < height; y++) {
+				const FIRGBAF *src_pixel = (FIRGBAF*) src_bits;
+				FIRGBF  *dst_pixel = (FIRGBF*)  dst_bits;
+
+				for(unsigned x = 0; x < width; x++) {
+					// convert and skip alpha channel
+					dst_pixel[x].red   = CLAMP(src_pixel[x].red, 0.0F, 1.0F);
+					dst_pixel[x].green = CLAMP(src_pixel[x].green, 0.0F, 1.0F);
+					dst_pixel[x].blue  = CLAMP(src_pixel[x].blue, 0.0F, 1.0F);
+				}
+				src_bits += src_pitch;
+				dst_bits += dst_pitch;
+			}
+		}
+		break;
+	}
+
+	if(src != dib) {
+		FreeImage_Unload(src);
+	}
+
+	return dst;
+}
+
diff --git a/Source/FreeImage/ConversionType.cpp b/Source/FreeImage/ConversionType.cpp
index b537f72..a2ca90f 100644
--- a/Source/FreeImage/ConversionType.cpp
+++ b/Source/FreeImage/ConversionType.cpp
@@ -3,6 +3,7 @@
 //
 // Design and implementation by
 // - Herv� Drolon (drolon at infonie.fr)
+// - Tanner Helland (tannerhelland at users.sf.net)
 //
 // This file is part of FreeImage 3
 //
@@ -346,11 +347,13 @@ FreeImage_ConvertToType(FIBITMAP *src, FREE_IMAGE_TYPE dst_type, BOOL scale_line
 					dst = FreeImage_ConvertToRGB16(src);
 					break;
 				case FIT_RGBA16:
+					dst = FreeImage_ConvertToRGBA16(src);
 					break;
 				case FIT_RGBF:
 					dst = FreeImage_ConvertToRGBF(src);
 					break;
 				case FIT_RGBAF:
+					dst = FreeImage_ConvertToRGBAF(src);
 					break;
 			}
 			break;
@@ -378,11 +381,13 @@ FreeImage_ConvertToType(FIBITMAP *src, FREE_IMAGE_TYPE dst_type, BOOL scale_line
 					dst = FreeImage_ConvertToRGB16(src);
 					break;
 				case FIT_RGBA16:
+					dst = FreeImage_ConvertToRGBA16(src);
 					break;
 				case FIT_RGBF:
 					dst = FreeImage_ConvertToRGBF(src);
 					break;
 				case FIT_RGBAF:
+					dst = FreeImage_ConvertToRGBAF(src);
 					break;
 			}
 			break;
@@ -503,6 +508,7 @@ FreeImage_ConvertToType(FIBITMAP *src, FREE_IMAGE_TYPE dst_type, BOOL scale_line
 					dst = FreeImage_ConvertToRGBF(src);
 					break;
 				case FIT_RGBAF:
+					dst = FreeImage_ConvertToRGBAF(src);
 					break;
 			}
 			break;
@@ -582,11 +588,13 @@ FreeImage_ConvertToType(FIBITMAP *src, FREE_IMAGE_TYPE dst_type, BOOL scale_line
 				case FIT_COMPLEX:
 					break;
 				case FIT_RGBA16:
+					dst = FreeImage_ConvertToRGBA16(src);
 					break;
 				case FIT_RGBF:
 					dst = FreeImage_ConvertToRGBF(src);
 					break;
 				case FIT_RGBAF:
+					dst = FreeImage_ConvertToRGBAF(src);
 					break;
 			}
 			break;
@@ -618,6 +626,7 @@ FreeImage_ConvertToType(FIBITMAP *src, FREE_IMAGE_TYPE dst_type, BOOL scale_line
 					dst = FreeImage_ConvertToRGBF(src);
 					break;
 				case FIT_RGBAF:
+					dst = FreeImage_ConvertToRGBAF(src);
 					break;
 			}
 			break;
@@ -645,6 +654,7 @@ FreeImage_ConvertToType(FIBITMAP *src, FREE_IMAGE_TYPE dst_type, BOOL scale_line
 				case FIT_RGBA16:
 					break;
 				case FIT_RGBAF:
+					dst = FreeImage_ConvertToRGBAF(src);
 					break;
 			}
 			break;
diff --git a/Source/FreeImage/ConversionUINT16.cpp b/Source/FreeImage/ConversionUINT16.cpp
index ed4691f..e6492aa 100644
--- a/Source/FreeImage/ConversionUINT16.cpp
+++ b/Source/FreeImage/ConversionUINT16.cpp
@@ -1,134 +1,134 @@
-// ==========================================================
-// Bitmap conversion routines
-//
-// Design and implementation by
-// - Herv� Drolon (drolon at infonie.fr)
-//
-// This file is part of FreeImage 3
-//
-// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
-// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
-// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
-// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
-// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
-// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
-// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
-// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
-// THIS DISCLAIMER.
-//
-// Use at your own risk!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-
-// ----------------------------------------------------------
-//   smart convert X to UINT16
-// ----------------------------------------------------------
-
-FIBITMAP * DLL_CALLCONV
-FreeImage_ConvertToUINT16(FIBITMAP *dib) {
-	FIBITMAP *src = NULL;
-	FIBITMAP *dst = NULL;
-
-	if(!FreeImage_HasPixels(dib)) return NULL;
-
-	const FREE_IMAGE_TYPE src_type = FreeImage_GetImageType(dib);
-
-	// check for allowed conversions 
-	switch(src_type) {
-		case FIT_BITMAP:
-		{
-			// convert to greyscale if needed
-			if((FreeImage_GetBPP(dib) == 8) && (FreeImage_GetColorType(dib) == FIC_MINISBLACK)) {
-				src = dib;
-			} else {
-				src = FreeImage_ConvertToGreyscale(dib);
-				if(!src) return NULL;
-			}
-			break;
-		}
-		case FIT_UINT16:
-			// UINT16 type : clone the src
-			return FreeImage_Clone(dib);
-			break;
-		case FIT_RGB16:
-			// allow conversion from 48-bit RGB
-			src = dib;
-			break;
-		case FIT_RGBA16:
-			// allow conversion from 64-bit RGBA (ignore the alpha channel)
-			src = dib;
-			break;
-		default:
-			return NULL;
-	}
-
-	// allocate dst image
-
-	const unsigned width = FreeImage_GetWidth(src);
-	const unsigned height = FreeImage_GetHeight(src);
-
-	dst = FreeImage_AllocateT(FIT_UINT16, width, height);
-	if(!dst) {
-		if(src != dib) {
-			FreeImage_Unload(src);
-		}
-		return NULL;
-	}
-
-	// copy metadata from src to dst
-	FreeImage_CloneMetadata(dst, src);
-
-	// convert from src type to UINT16
-
-	switch(src_type) {
-		case FIT_BITMAP:
-		{
-			for(unsigned y = 0; y < height; y++) {
-				const BYTE *src_bits = (BYTE*)FreeImage_GetScanLine(src, y);
-				WORD *dst_bits = (WORD*)FreeImage_GetScanLine(dst, y);
-				for(unsigned x = 0; x < width; x++) {
-					dst_bits[x] = src_bits[x] << 8;
-				}
-			}
-		}
-		break;
-
-		case FIT_RGB16:
-		{
-			for(unsigned y = 0; y < height; y++) {
-				const FIRGB16 *src_bits = (FIRGB16*)FreeImage_GetScanLine(src, y);
-				WORD *dst_bits = (WORD*)FreeImage_GetScanLine(dst, y);
-				for(unsigned x = 0; x < width; x++) {
-					// convert to grey
-					dst_bits[x] = (WORD)LUMA_REC709(src_bits[x].red, src_bits[x].green, src_bits[x].blue);
-				}
-			}
-		}
-		break;
-
-		case FIT_RGBA16:
-		{
-			for(unsigned y = 0; y < height; y++) {
-				const FIRGBA16 *src_bits = (FIRGBA16*)FreeImage_GetScanLine(src, y);
-				WORD *dst_bits = (WORD*)FreeImage_GetScanLine(dst, y);
-				for(unsigned x = 0; x < width; x++) {
-					// convert to grey
-					dst_bits[x] = (WORD)LUMA_REC709(src_bits[x].red, src_bits[x].green, src_bits[x].blue);
-				}
-			}
-		}
-		break;
-
-		default:
-			break;
-	}
-
-	if(src != dib) {
-		FreeImage_Unload(src);
-	}
-
-	return dst;
-}
-
+// ==========================================================
+// Bitmap conversion routines
+//
+// Design and implementation by
+// - Herv� Drolon (drolon at infonie.fr)
+//
+// This file is part of FreeImage 3
+//
+// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
+// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
+// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
+// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
+// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
+// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
+// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+// THIS DISCLAIMER.
+//
+// Use at your own risk!
+// ==========================================================
+
+#include "FreeImage.h"
+#include "Utilities.h"
+
+// ----------------------------------------------------------
+//   smart convert X to UINT16
+// ----------------------------------------------------------
+
+FIBITMAP * DLL_CALLCONV
+FreeImage_ConvertToUINT16(FIBITMAP *dib) {
+	FIBITMAP *src = NULL;
+	FIBITMAP *dst = NULL;
+
+	if(!FreeImage_HasPixels(dib)) return NULL;
+
+	const FREE_IMAGE_TYPE src_type = FreeImage_GetImageType(dib);
+
+	// check for allowed conversions 
+	switch(src_type) {
+		case FIT_BITMAP:
+		{
+			// convert to greyscale if needed
+			if((FreeImage_GetBPP(dib) == 8) && (FreeImage_GetColorType(dib) == FIC_MINISBLACK)) {
+				src = dib;
+			} else {
+				src = FreeImage_ConvertToGreyscale(dib);
+				if(!src) return NULL;
+			}
+			break;
+		}
+		case FIT_UINT16:
+			// UINT16 type : clone the src
+			return FreeImage_Clone(dib);
+			break;
+		case FIT_RGB16:
+			// allow conversion from 48-bit RGB
+			src = dib;
+			break;
+		case FIT_RGBA16:
+			// allow conversion from 64-bit RGBA (ignore the alpha channel)
+			src = dib;
+			break;
+		default:
+			return NULL;
+	}
+
+	// allocate dst image
+
+	const unsigned width = FreeImage_GetWidth(src);
+	const unsigned height = FreeImage_GetHeight(src);
+
+	dst = FreeImage_AllocateT(FIT_UINT16, width, height);
+	if(!dst) {
+		if(src != dib) {
+			FreeImage_Unload(src);
+		}
+		return NULL;
+	}
+
+	// copy metadata from src to dst
+	FreeImage_CloneMetadata(dst, src);
+
+	// convert from src type to UINT16
+
+	switch(src_type) {
+		case FIT_BITMAP:
+		{
+			for(unsigned y = 0; y < height; y++) {
+				const BYTE *src_bits = (BYTE*)FreeImage_GetScanLine(src, y);
+				WORD *dst_bits = (WORD*)FreeImage_GetScanLine(dst, y);
+				for(unsigned x = 0; x < width; x++) {
+					dst_bits[x] = src_bits[x] << 8;
+				}
+			}
+		}
+		break;
+
+		case FIT_RGB16:
+		{
+			for(unsigned y = 0; y < height; y++) {
+				const FIRGB16 *src_bits = (FIRGB16*)FreeImage_GetScanLine(src, y);
+				WORD *dst_bits = (WORD*)FreeImage_GetScanLine(dst, y);
+				for(unsigned x = 0; x < width; x++) {
+					// convert to grey
+					dst_bits[x] = (WORD)LUMA_REC709(src_bits[x].red, src_bits[x].green, src_bits[x].blue);
+				}
+			}
+		}
+		break;
+
+		case FIT_RGBA16:
+		{
+			for(unsigned y = 0; y < height; y++) {
+				const FIRGBA16 *src_bits = (FIRGBA16*)FreeImage_GetScanLine(src, y);
+				WORD *dst_bits = (WORD*)FreeImage_GetScanLine(dst, y);
+				for(unsigned x = 0; x < width; x++) {
+					// convert to grey
+					dst_bits[x] = (WORD)LUMA_REC709(src_bits[x].red, src_bits[x].green, src_bits[x].blue);
+				}
+			}
+		}
+		break;
+
+		default:
+			break;
+	}
+
+	if(src != dib) {
+		FreeImage_Unload(src);
+	}
+
+	return dst;
+}
+
diff --git a/Source/FreeImage/FreeImageIO.cpp b/Source/FreeImage/FreeImageIO.cpp
index f8cf760..83394f0 100644
--- a/Source/FreeImage/FreeImageIO.cpp
+++ b/Source/FreeImage/FreeImageIO.cpp
@@ -68,14 +68,18 @@ _MemoryReadProc(void *buffer, unsigned size, unsigned count, fi_handle handle) {
 	FIMEMORYHEADER *mem_header = (FIMEMORYHEADER*)(((FIMEMORY*)handle)->data);
 
 	for(x = 0; x < count; x++) {
-		//if there isnt size bytes left to read, set pos to eof and return a short count
-		if( (mem_header->filelen - mem_header->curpos) < (long)size ) {
-			mem_header->curpos = mem_header->filelen;
+		long remaining_bytes = mem_header->file_length - mem_header->current_position;
+		//if there isn't size bytes left to read, set pos to eof and return a short count
+		if( remaining_bytes < (long)size ) {
+			if(remaining_bytes > 0) {
+				memcpy( buffer, (char *)mem_header->data + mem_header->current_position, remaining_bytes );
+			}
+			mem_header->current_position = mem_header->file_length;
 			break;
 		}
 		//copy size bytes count times
-		memcpy( buffer, (char *)mem_header->data + mem_header->curpos, size );
-		mem_header->curpos += size;
+		memcpy( buffer, (char *)mem_header->data + mem_header->current_position, size );
+		mem_header->current_position += size;
 		buffer = (char *)buffer + size;
 	}
 	return x;
@@ -89,32 +93,32 @@ _MemoryWriteProc(void *buffer, unsigned size, unsigned count, fi_handle handle)
 	FIMEMORYHEADER *mem_header = (FIMEMORYHEADER*)(((FIMEMORY*)handle)->data);
 
 	//double the data block size if we need to
-	while( (mem_header->curpos + (long)(size*count)) >= mem_header->datalen ) {
+	while( (mem_header->current_position + (long)(size * count)) >= mem_header->data_length ) {
 		//if we are at or above 1G, we cant double without going negative
-		if( mem_header->datalen & 0x40000000 ) {
+		if( mem_header->data_length & 0x40000000 ) {
 			//max 2G
-			if( mem_header->datalen == 0x7FFFFFFF ) {
+			if( mem_header->data_length == 0x7FFFFFFF ) {
 				return 0;
 			}
 			newdatalen = 0x7FFFFFFF;
-		} else if( mem_header->datalen == 0 ) {
+		} else if( mem_header->data_length == 0 ) {
 			//default to 4K if nothing yet
 			newdatalen = 4096;
 		} else {
 			//double size
-			newdatalen = mem_header->datalen << 1;
+			newdatalen = mem_header->data_length << 1;
 		}
 		newdata = realloc( mem_header->data, newdatalen );
 		if( !newdata ) {
 			return 0;
 		}
 		mem_header->data = newdata;
-		mem_header->datalen = newdatalen;
+		mem_header->data_length = newdatalen;
 	}
-	memcpy( (char *)mem_header->data + mem_header->curpos, buffer, size*count );
-	mem_header->curpos += size*count;
-	if( mem_header->curpos > mem_header->filelen ) {
-		mem_header->filelen = mem_header->curpos;
+	memcpy( (char *)mem_header->data + mem_header->current_position, buffer, size * count );
+	mem_header->current_position += size * count;
+	if( mem_header->current_position > mem_header->file_length ) {
+		mem_header->file_length = mem_header->current_position;
 	}
 	return count;
 }
@@ -123,25 +127,28 @@ int DLL_CALLCONV
 _MemorySeekProc(fi_handle handle, long offset, int origin) {
 	FIMEMORYHEADER *mem_header = (FIMEMORYHEADER*)(((FIMEMORY*)handle)->data);
 
+	// you can use _MemorySeekProc to reposition the pointer anywhere in a file
+	// the pointer can also be positioned beyond the end of the file
+
 	switch(origin) { //0 to filelen-1 are 'inside' the file
 		default:
 		case SEEK_SET: //can fseek() to 0-7FFFFFFF always
 			if( offset >= 0 ) {
-				mem_header->curpos = offset;
+				mem_header->current_position = offset;
 				return 0;
 			}
 			break;
 
 		case SEEK_CUR:
-			if( mem_header->curpos + offset >= 0 ) {
-				mem_header->curpos += offset;
+			if( mem_header->current_position + offset >= 0 ) {
+				mem_header->current_position += offset;
 				return 0;
 			}
 			break;
 
 		case SEEK_END:
-			if( mem_header->filelen + offset >= 0 ) {
-				mem_header->curpos = mem_header->filelen + offset;
+			if( mem_header->file_length + offset >= 0 ) {
+				mem_header->current_position = mem_header->file_length + offset;
 				return 0;
 			}
 			break;
@@ -154,7 +161,7 @@ long DLL_CALLCONV
 _MemoryTellProc(fi_handle handle) {
 	FIMEMORYHEADER *mem_header = (FIMEMORYHEADER*)(((FIMEMORY*)handle)->data);
 
-	return mem_header->curpos;
+	return mem_header->current_position;
 }
 
 // ----------------------------------------------------------
diff --git a/Source/FreeImage/J2KHelper.cpp b/Source/FreeImage/J2KHelper.cpp
index c9f8fa5..1776c3b 100644
--- a/Source/FreeImage/J2KHelper.cpp
+++ b/Source/FreeImage/J2KHelper.cpp
@@ -1,500 +1,591 @@
-// ==========================================================
-// JPEG2000 helpers
-//
-// Design and implementation by
-// - Herv� Drolon (drolon at infonie.fr)
-//
-// This file is part of FreeImage 3
-//
-// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
-// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
-// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
-// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
-// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
-// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
-// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
-// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
-// THIS DISCLAIMER.
-//
-// Use at your own risk!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-#include "../LibOpenJPEG/openjpeg.h"
-
-/**
-Divide an integer by a power of 2 and round upwards
- at return Returns a divided by 2^b
-*/
-static int int_ceildivpow2(int a, int b) {
-	return (a + (1 << b) - 1) >> b;
-}
-
-/**
-Convert a OpenJPEG image to a FIBITMAP
- at param format_id Plugin ID
- at param image OpenJPEG image
- at return Returns the converted image if successful, returns NULL otherwise
-*/
-FIBITMAP* J2KImageToFIBITMAP(int format_id, const opj_image_t *image) {
-	FIBITMAP *dib = NULL;
-
-	try {
-		// compute image width and height
-
-		//int w = int_ceildiv(image->x1 - image->x0, image->comps[0].dx);
-		int wr = image->comps[0].w;
-		int wrr = int_ceildivpow2(image->comps[0].w, image->comps[0].factor);
-		
-		//int h = int_ceildiv(image->y1 - image->y0, image->comps[0].dy);
-		//int hr = image->comps[0].h;
-		int hrr = int_ceildivpow2(image->comps[0].h, image->comps[0].factor);
-
-		// check the number of components
-
-		int numcomps = image->numcomps;
-
-		BOOL bIsValid = TRUE;
-		for(int c = 0; c < numcomps - 1; c++) {
-			if(	(image->comps[c].dx == image->comps[c+1].dx) && 
-				(image->comps[c].dy == image->comps[c+1].dy) &&
-				(image->comps[c].prec == image->comps[c+1].prec) ) {
-				continue;
-			} else {
-				bIsValid = FALSE;
-				break;
-			}
-		}
-		bIsValid &= ((numcomps == 1) || (numcomps == 3) || (numcomps == 4));
-		if(!bIsValid) {
-			if(numcomps) {
-				FreeImage_OutputMessageProc(format_id, "Warning: image contains %d greyscale components. Only the first will be loaded.\n", numcomps);
-				numcomps = 1;
-			} else {
-				// unknown type
-				throw FI_MSG_ERROR_UNSUPPORTED_FORMAT;
-			}
-		}
-
-		// create a new DIB
-
-		if(image->comps[0].prec <= 8) {
-			switch(numcomps) {
-				case 1:
-					dib = FreeImage_Allocate(wrr, hrr, 8);
-					break;
-				case 3:
-					dib = FreeImage_Allocate(wrr, hrr, 24, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
-					break;
-				case 4:
-					dib = FreeImage_Allocate(wrr, hrr, 32, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
-					break;
-			}
-		} else if(image->comps[0].prec <= 16) {
-			switch(numcomps) {
-				case 1:
-					dib = FreeImage_AllocateT(FIT_UINT16, wrr, hrr);
-					break;
-				case 3:
-					dib = FreeImage_AllocateT(FIT_RGB16, wrr, hrr);
-					break;
-				case 4:
-					dib = FreeImage_AllocateT(FIT_RGBA16, wrr, hrr);
-					break;
-			}
-		} else {
-			throw FI_MSG_ERROR_UNSUPPORTED_FORMAT;
-		}
-		if(!dib) {
-			throw FI_MSG_ERROR_DIB_MEMORY;
-		}
-		
-		if(image->comps[0].prec <= 8) {
-			if(numcomps == 1) {
-				// 8-bit greyscale
-				// ----------------------------------------------------------
-
-				// build a greyscale palette
-				
-				RGBQUAD *pal = FreeImage_GetPalette(dib);
-				for (int i = 0; i < 256; i++) {
-					pal[i].rgbRed	= (BYTE)i;
-					pal[i].rgbGreen = (BYTE)i;
-					pal[i].rgbBlue	= (BYTE)i;
-				}
-
-				// load pixel data
-
-				unsigned pixel_count = 0;
-
-				for(int y = 0; y < hrr; y++) {		
-					BYTE *bits = FreeImage_GetScanLine(dib, hrr - 1 - y);
-
-					for(int x = 0; x < wrr; x++) {
-						const unsigned pixel_pos = pixel_count / wrr * wr + pixel_count % wrr;
-
-						int index = image->comps[0].data[pixel_pos];
-						index += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
-
-						bits[x] = (BYTE)index;
-
-						pixel_count++;
-					}
-				}
-			}
-			else if(numcomps == 3) {
-
-				// 24-bit RGB
-				// ----------------------------------------------------------	
-				
-				// load pixel data
-
-				unsigned pixel_count = 0;
-
-				for(int y = 0; y < hrr; y++) {		
-					BYTE *bits = FreeImage_GetScanLine(dib, hrr - 1 - y);
-
-					for(int x = 0; x < wrr; x++) {
-						const unsigned pixel_pos = pixel_count / wrr * wr + pixel_count % wrr;
-
-						int r = image->comps[0].data[pixel_pos];
-						r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
-						
-						int g = image->comps[1].data[pixel_pos];
-						g += (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
-						
-						int b = image->comps[2].data[pixel_pos];
-						b += (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0);
-
-						bits[FI_RGBA_RED]   = (BYTE)r;
-						bits[FI_RGBA_GREEN] = (BYTE)g;
-						bits[FI_RGBA_BLUE]  = (BYTE)b;
-						bits += 3;
-
-						pixel_count++;
-					}
-				}
-			}
-			else if(numcomps == 4) {
-
-				// 32-bit RGBA
-				// ----------------------------------------------------------	
-				
-				// load pixel data
-
-				unsigned pixel_count = 0;
-
-				for(int y = 0; y < hrr; y++) {		
-					BYTE *bits = FreeImage_GetScanLine(dib, hrr - 1 - y);
-
-					for(int x = 0; x < wrr; x++) {
-						const unsigned pixel_pos = pixel_count / wrr * wr + pixel_count % wrr;
-
-						int r = image->comps[0].data[pixel_pos];
-						r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
-						
-						int g = image->comps[1].data[pixel_pos];
-						g += (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
-						
-						int b = image->comps[2].data[pixel_pos];
-						b += (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0);
-
-						int a = image->comps[3].data[pixel_pos];
-						a += (image->comps[3].sgnd ? 1 << (image->comps[3].prec - 1) : 0);
-
-						bits[FI_RGBA_RED]   = (BYTE)r;
-						bits[FI_RGBA_GREEN] = (BYTE)g;
-						bits[FI_RGBA_BLUE]  = (BYTE)b;
-						bits[FI_RGBA_ALPHA] = (BYTE)a;
-						bits += 4;
-
-						pixel_count++;
-					}
-				}
-			}
-		}
-		else if(image->comps[0].prec <= 16) {
-			if(numcomps == 1) {
-				// 16-bit greyscale
-				// ----------------------------------------------------------
-
-				// load pixel data
-
-				unsigned pixel_count = 0;
-
-				for(int y = 0; y < hrr; y++) {		
-					unsigned short *bits = (unsigned short*)FreeImage_GetScanLine(dib, hrr - 1 - y);
-
-					for(int x = 0; x < wrr; x++) {
-						const unsigned pixel_pos = pixel_count / wrr * wr + pixel_count % wrr;
-
-						int index = image->comps[0].data[pixel_pos];
-						index += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
-
-						bits[x] = (unsigned short)index;
-
-						pixel_count++;
-					}
-				}
-			}
-			else if(numcomps == 3) {
-
-				// 48-bit RGB
-				// ----------------------------------------------------------	
-				
-				// load pixel data
-
-				unsigned pixel_count = 0;
-
-				for(int y = 0; y < hrr; y++) {		
-					FIRGB16 *bits = (FIRGB16*)FreeImage_GetScanLine(dib, hrr - 1 - y);
-
-					for(int x = 0; x < wrr; x++) {
-						const unsigned pixel_pos = pixel_count / wrr * wr + pixel_count % wrr;
-
-						int r = image->comps[0].data[pixel_pos];
-						r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
-						
-						int g = image->comps[1].data[pixel_pos];
-						g += (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
-						
-						int b = image->comps[2].data[pixel_pos];
-						b += (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0);
-
-						bits[x].red   = (WORD)r;
-						bits[x].green = (WORD)g;
-						bits[x].blue  = (WORD)b;
-
-						pixel_count++;
-					}
-				}
-			}
-			else if(numcomps == 4) {
-
-				// 64-bit RGBA
-				// ----------------------------------------------------------	
-				
-				// load pixel data
-
-				unsigned pixel_count = 0;
-
-				for(int y = 0; y < hrr; y++) {		
-					FIRGBA16 *bits = (FIRGBA16*)FreeImage_GetScanLine(dib, hrr - 1 - y);
-
-					for(int x = 0; x < wrr; x++) {
-						const unsigned pixel_pos = pixel_count / wrr * wr + pixel_count % wrr;
-
-						int r = image->comps[0].data[pixel_pos];
-						r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
-						
-						int g = image->comps[1].data[pixel_pos];
-						g += (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
-						
-						int b = image->comps[2].data[pixel_pos];
-						b += (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0);
-
-						int a = image->comps[3].data[pixel_pos];
-						a += (image->comps[3].sgnd ? 1 << (image->comps[3].prec - 1) : 0);
-
-						bits[x].red   = (WORD)r;
-						bits[x].green = (WORD)g;
-						bits[x].blue  = (WORD)b;
-						bits[x].alpha = (WORD)a;
-
-						pixel_count++;
-					}
-				}
-			}
-		}
-
-		return dib;
-
-	} catch(const char *text) {
-		if(dib) FreeImage_Unload(dib);
-		FreeImage_OutputMessageProc(format_id, text);
-		return NULL;
-	}
-
-}
-
-/**
-Convert a FIBITMAP to a OpenJPEG image
- at param format_id Plugin ID
- at param dib FreeImage image
- at param parameters Compression parameters
- at return Returns the converted image if successful, returns NULL otherwise
-*/
-opj_image_t* FIBITMAPToJ2KImage(int format_id, FIBITMAP *dib, const opj_cparameters_t *parameters) {
-	int prec, numcomps, x, y, index;
-	OPJ_COLOR_SPACE color_space;
-	opj_image_cmptparm_t cmptparm[4];	// maximum of 4 components 
-	opj_image_t *image = NULL;			// image to encode
-
-	try {
-		int w = FreeImage_GetWidth(dib);
-		int h = FreeImage_GetHeight(dib);
-
-		// get image characteristics
-		FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
-
-		if(image_type == FIT_BITMAP) {
-			// standard image ...
-			prec = 8;
-			switch(FreeImage_GetColorType(dib)) {
-				case FIC_MINISBLACK:
-					numcomps = 1;
-					color_space = CLRSPC_GRAY;
-					break;
-				case FIC_RGB:
-					if(FreeImage_GetBPP(dib) == 32) {
-						// 32-bit image with a fully opaque layer
-						numcomps = 4;
-						color_space = CLRSPC_SRGB;
-					} else {
-						// 24-bit image
-						numcomps = 3;
-						color_space = CLRSPC_SRGB;
-					}
-					break;
-				case FIC_RGBALPHA:
-					numcomps = 4;
-					color_space = CLRSPC_SRGB;
-					break;
-				default:
-					return NULL;
-			}
-		} else {
-			// HDR image ...
-			prec = 16;
-			switch(image_type) {
-				case FIT_UINT16:
-					numcomps = 1;
-					color_space = CLRSPC_GRAY;
-					break;
-				case FIT_RGB16:
-					numcomps = 3;
-					color_space = CLRSPC_SRGB;
-					break;
-				case FIT_RGBA16:
-					numcomps = 4;
-					color_space = CLRSPC_SRGB;
-					break;
-				default:
-					return NULL;
-			}
-		}
-
-		// initialize image components 
-		memset(&cmptparm[0], 0, 4 * sizeof(opj_image_cmptparm_t));
-		for(int i = 0; i < numcomps; i++) {
-			cmptparm[i].dx = parameters->subsampling_dx;
-			cmptparm[i].dy = parameters->subsampling_dy;
-			cmptparm[i].w = w;
-			cmptparm[i].h = h;
-			cmptparm[i].prec = prec;
-			cmptparm[i].bpp = prec;
-			cmptparm[i].sgnd = 0;
-		}
-		// create the image 
-		image = opj_image_create(numcomps, &cmptparm[0], color_space);
-		if(!image) {
-			throw FI_MSG_ERROR_DIB_MEMORY;
-		}
-
-		// set image offset and reference grid 
-		image->x0 = parameters->image_offset_x0;
-		image->y0 = parameters->image_offset_y0;
-		image->x1 = parameters->image_offset_x0 + (w - 1) *	parameters->subsampling_dx + 1;
-		image->y1 = parameters->image_offset_y0 + (h - 1) *	parameters->subsampling_dy + 1;
-
-		// set image data 
-		if(prec == 8) {
-			switch(numcomps) {
-				case 1:
-					index = 0;
-					for(y = 0; y < h; y++) {
-						BYTE *bits = FreeImage_GetScanLine(dib, h - 1 - y);
-						for(x = 0; x < w; x++) {
-							image->comps[0].data[index] = bits[x];
-							index++;
-						}
-					}
-					break;
-				case 3:
-					index = 0;
-					for(y = 0; y < h; y++) {
-						BYTE *bits = FreeImage_GetScanLine(dib, h - 1 - y);
-						for(x = 0; x < w; x++) {
-							image->comps[0].data[index] = bits[FI_RGBA_RED];
-							image->comps[1].data[index] = bits[FI_RGBA_GREEN];
-							image->comps[2].data[index] = bits[FI_RGBA_BLUE];
-							bits += 3;
-							index++;
-						}
-					}
-					break;
-				case 4:
-					index = 0;
-					for(y = 0; y < h; y++) {
-						BYTE *bits = FreeImage_GetScanLine(dib, h - 1 - y);
-						for(x = 0; x < w; x++) {
-							image->comps[0].data[index] = bits[FI_RGBA_RED];
-							image->comps[1].data[index] = bits[FI_RGBA_GREEN];
-							image->comps[2].data[index] = bits[FI_RGBA_BLUE];
-							image->comps[3].data[index] = bits[FI_RGBA_ALPHA];
-							bits += 4;
-							index++;
-						}
-					}
-					break;
-			}
-		}
-		else if(prec == 16) {
-			switch(numcomps) {
-				case 1:
-					index = 0;
-					for(y = 0; y < h; y++) {
-						WORD *bits = (WORD*)FreeImage_GetScanLine(dib, h - 1 - y);
-						for(x = 0; x < w; x++) {
-							image->comps[0].data[index] = bits[x];
-							index++;
-						}
-					}
-					break;
-				case 3:
-					index = 0;
-					for(y = 0; y < h; y++) {
-						FIRGB16 *bits = (FIRGB16*)FreeImage_GetScanLine(dib, h - 1 - y);
-						for(x = 0; x < w; x++) {
-							image->comps[0].data[index] = bits[x].red;
-							image->comps[1].data[index] = bits[x].green;
-							image->comps[2].data[index] = bits[x].blue;
-							index++;
-						}
-					}
-					break;
-				case 4:
-					index = 0;
-					for(y = 0; y < h; y++) {
-						FIRGBA16 *bits = (FIRGBA16*)FreeImage_GetScanLine(dib, h - 1 - y);
-						for(x = 0; x < w; x++) {
-							image->comps[0].data[index] = bits[x].red;
-							image->comps[1].data[index] = bits[x].green;
-							image->comps[2].data[index] = bits[x].blue;
-							image->comps[3].data[index] = bits[x].alpha;
-							index++;
-						}
-					}
-					break;
-			}
-		}
-
-		return image;
-
-	} catch (const char *text) {
-		if(image) opj_image_destroy(image);
-		FreeImage_OutputMessageProc(format_id, text);
-		return NULL;
-	}
-}
+// ==========================================================
+// JPEG2000 helpers
+//
+// Design and implementation by
+// - Herv� Drolon (drolon at infonie.fr)
+//
+// This file is part of FreeImage 3
+//
+// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
+// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
+// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
+// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
+// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
+// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
+// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+// THIS DISCLAIMER.
+//
+// Use at your own risk!
+// ==========================================================
+
+#include "FreeImage.h"
+#include "Utilities.h"
+#include "../LibOpenJPEG/openjpeg.h"
+#include "J2KHelper.h"
+
+// --------------------------------------------------------------------------
+
+static OPJ_UINT64 
+_LengthProc(J2KFIO_t *fio) {
+	long start_pos = fio->io->tell_proc(fio->handle);
+	fio->io->seek_proc(fio->handle, 0, SEEK_END);
+	unsigned file_length = fio->io->tell_proc(fio->handle) - start_pos;
+	fio->io->seek_proc(fio->handle, start_pos, SEEK_SET);
+	return (OPJ_UINT64)file_length;
+}
+
+static OPJ_SIZE_T 
+_ReadProc(void *p_buffer, OPJ_SIZE_T p_nb_bytes, void *p_user_data) {
+	J2KFIO_t *fio = (J2KFIO_t*)p_user_data;
+	OPJ_SIZE_T l_nb_read = fio->io->read_proc(p_buffer, 1, (unsigned)p_nb_bytes, fio->handle);
+	return l_nb_read ? l_nb_read : (OPJ_SIZE_T)-1;
+}
+
+static OPJ_SIZE_T 
+_WriteProc(void *p_buffer, OPJ_SIZE_T p_nb_bytes, void *p_user_data) {
+	J2KFIO_t *fio = (J2KFIO_t*)p_user_data;  
+	return fio->io->write_proc(p_buffer, 1, (unsigned)p_nb_bytes, fio->handle);
+}
+
+static OPJ_OFF_T 
+_SkipProc(OPJ_OFF_T p_nb_bytes, void *p_user_data) {
+	J2KFIO_t *fio = (J2KFIO_t*)p_user_data;
+	if( fio->io->seek_proc(fio->handle, (long)p_nb_bytes, SEEK_CUR) ) {
+		return -1;
+	}
+	return p_nb_bytes;
+}
+
+static OPJ_BOOL 
+_SeekProc(OPJ_OFF_T p_nb_bytes, FILE * p_user_data) {
+	J2KFIO_t *fio = (J2KFIO_t*)p_user_data;
+	if( fio->io->seek_proc(fio->handle, (long)p_nb_bytes, SEEK_SET) ) {
+		return OPJ_FALSE;
+	}
+	return OPJ_TRUE;
+}
+
+// --------------------------------------------------------------------------
+
+J2KFIO_t* 
+opj_freeimage_stream_create(FreeImageIO *io, fi_handle handle, BOOL bRead) {
+	if(!handle) {
+		return NULL;
+	}
+	J2KFIO_t *fio = (J2KFIO_t*)malloc(sizeof(J2KFIO_t));
+	if(fio) {
+		fio->io = io;
+		fio->handle = handle;
+
+		opj_stream_t *l_stream = opj_stream_create(OPJ_J2K_STREAM_CHUNK_SIZE, bRead ? OPJ_TRUE : OPJ_FALSE);
+		if (l_stream) {
+			opj_stream_set_user_data(l_stream, fio, NULL);
+			opj_stream_set_user_data_length(l_stream, _LengthProc(fio));
+			opj_stream_set_read_function(l_stream, (opj_stream_read_fn)_ReadProc);
+			opj_stream_set_write_function(l_stream, (opj_stream_write_fn)_WriteProc);
+			opj_stream_set_skip_function(l_stream, (opj_stream_skip_fn)_SkipProc);
+			opj_stream_set_seek_function(l_stream, (opj_stream_seek_fn)_SeekProc);
+			fio->stream = l_stream;
+			return fio;
+		} else {
+			free(fio);
+		}
+	}
+
+	return NULL;		
+}
+
+void 
+opj_freeimage_stream_destroy(J2KFIO_t* fio) {
+	if(fio) {
+		if(fio->stream) {
+			opj_stream_destroy(fio->stream);
+		}
+		free(fio);
+	}
+}
+
+// --------------------------------------------------------------------------
+
+/**
+Divide an integer by a power of 2 and round upwards
+ at return Returns a divided by 2^b
+*/
+static int int_ceildivpow2(int a, int b) {
+	return (a + (1 << b) - 1) >> b;
+}
+
+/**
+Convert a OpenJPEG image to a FIBITMAP
+ at param format_id Plugin ID
+ at param image OpenJPEG image
+ at param header_only If TRUE, allocate a 'header only' FIBITMAP, otherwise allocate a full FIBITMAP
+ at return Returns the converted image if successful, returns NULL otherwise
+*/
+FIBITMAP* J2KImageToFIBITMAP(int format_id, const opj_image_t *image, BOOL header_only) {
+	FIBITMAP *dib = NULL;
+
+	try {
+		// compute image width and height
+
+		//int w = int_ceildiv(image->x1 - image->x0, image->comps[0].dx);
+		int wr = image->comps[0].w;
+		int wrr = int_ceildivpow2(image->comps[0].w, image->comps[0].factor);
+		
+		//int h = int_ceildiv(image->y1 - image->y0, image->comps[0].dy);
+		//int hr = image->comps[0].h;
+		int hrr = int_ceildivpow2(image->comps[0].h, image->comps[0].factor);
+
+		// check the number of components
+
+		int numcomps = image->numcomps;
+
+		BOOL bIsValid = TRUE;
+		for(int c = 0; c < numcomps - 1; c++) {
+			if(	(image->comps[c].dx == image->comps[c+1].dx) && 
+				(image->comps[c].dy == image->comps[c+1].dy) &&
+				(image->comps[c].prec == image->comps[c+1].prec) ) {
+				continue;
+			} else {
+				bIsValid = FALSE;
+				break;
+			}
+		}
+		bIsValid &= ((numcomps == 1) || (numcomps == 3) || (numcomps == 4));
+		if(!bIsValid) {
+			if(numcomps) {
+				FreeImage_OutputMessageProc(format_id, "Warning: image contains %d greyscale components. Only the first will be loaded.\n", numcomps);
+				numcomps = 1;
+			} else {
+				// unknown type
+				throw FI_MSG_ERROR_UNSUPPORTED_FORMAT;
+			}
+		}
+
+		// create a new DIB
+
+		if(image->comps[0].prec <= 8) {
+			switch(numcomps) {
+				case 1:
+					dib = FreeImage_AllocateHeader(header_only, wrr, hrr, 8);
+					break;
+				case 3:
+					dib = FreeImage_AllocateHeader(header_only, wrr, hrr, 24, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
+					break;
+				case 4:
+					dib = FreeImage_AllocateHeader(header_only, wrr, hrr, 32, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
+					break;
+			}
+		} else if(image->comps[0].prec <= 16) {
+			switch(numcomps) {
+				case 1:
+					dib = FreeImage_AllocateHeaderT(header_only, FIT_UINT16, wrr, hrr);
+					break;
+				case 3:
+					dib = FreeImage_AllocateHeaderT(header_only, FIT_RGB16, wrr, hrr);
+					break;
+				case 4:
+					dib = FreeImage_AllocateHeaderT(header_only, FIT_RGBA16, wrr, hrr);
+					break;
+			}
+		} else {
+			throw FI_MSG_ERROR_UNSUPPORTED_FORMAT;
+		}
+		if(!dib) {
+			throw FI_MSG_ERROR_DIB_MEMORY;
+		}
+
+		// "header only" FIBITMAP ?
+		if(header_only) {
+			return dib;
+		}
+		
+		if(image->comps[0].prec <= 8) {
+			if(numcomps == 1) {
+				// 8-bit greyscale
+				// ----------------------------------------------------------
+
+				// build a greyscale palette
+				
+				RGBQUAD *pal = FreeImage_GetPalette(dib);
+				for (int i = 0; i < 256; i++) {
+					pal[i].rgbRed	= (BYTE)i;
+					pal[i].rgbGreen = (BYTE)i;
+					pal[i].rgbBlue	= (BYTE)i;
+				}
+
+				// load pixel data
+
+				unsigned pixel_count = 0;
+
+				for(int y = 0; y < hrr; y++) {		
+					BYTE *bits = FreeImage_GetScanLine(dib, hrr - 1 - y);
+
+					for(int x = 0; x < wrr; x++) {
+						const unsigned pixel_pos = pixel_count / wrr * wr + pixel_count % wrr;
+
+						int index = image->comps[0].data[pixel_pos];
+						index += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
+
+						bits[x] = (BYTE)index;
+
+						pixel_count++;
+					}
+				}
+			}
+			else if(numcomps == 3) {
+
+				// 24-bit RGB
+				// ----------------------------------------------------------	
+				
+				// load pixel data
+
+				unsigned pixel_count = 0;
+
+				for(int y = 0; y < hrr; y++) {		
+					BYTE *bits = FreeImage_GetScanLine(dib, hrr - 1 - y);
+
+					for(int x = 0; x < wrr; x++) {
+						const unsigned pixel_pos = pixel_count / wrr * wr + pixel_count % wrr;
+
+						int r = image->comps[0].data[pixel_pos];
+						r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
+						
+						int g = image->comps[1].data[pixel_pos];
+						g += (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
+						
+						int b = image->comps[2].data[pixel_pos];
+						b += (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0);
+
+						bits[FI_RGBA_RED]   = (BYTE)r;
+						bits[FI_RGBA_GREEN] = (BYTE)g;
+						bits[FI_RGBA_BLUE]  = (BYTE)b;
+						bits += 3;
+
+						pixel_count++;
+					}
+				}
+			}
+			else if(numcomps == 4) {
+
+				// 32-bit RGBA
+				// ----------------------------------------------------------	
+				
+				// load pixel data
+
+				unsigned pixel_count = 0;
+
+				for(int y = 0; y < hrr; y++) {		
+					BYTE *bits = FreeImage_GetScanLine(dib, hrr - 1 - y);
+
+					for(int x = 0; x < wrr; x++) {
+						const unsigned pixel_pos = pixel_count / wrr * wr + pixel_count % wrr;
+
+						int r = image->comps[0].data[pixel_pos];
+						r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
+						
+						int g = image->comps[1].data[pixel_pos];
+						g += (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
+						
+						int b = image->comps[2].data[pixel_pos];
+						b += (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0);
+
+						int a = image->comps[3].data[pixel_pos];
+						a += (image->comps[3].sgnd ? 1 << (image->comps[3].prec - 1) : 0);
+
+						bits[FI_RGBA_RED]   = (BYTE)r;
+						bits[FI_RGBA_GREEN] = (BYTE)g;
+						bits[FI_RGBA_BLUE]  = (BYTE)b;
+						bits[FI_RGBA_ALPHA] = (BYTE)a;
+						bits += 4;
+
+						pixel_count++;
+					}
+				}
+			}
+		}
+		else if(image->comps[0].prec <= 16) {
+			if(numcomps == 1) {
+				// 16-bit greyscale
+				// ----------------------------------------------------------
+
+				// load pixel data
+
+				unsigned pixel_count = 0;
+
+				for(int y = 0; y < hrr; y++) {		
+					WORD *bits = (WORD*)FreeImage_GetScanLine(dib, hrr - 1 - y);
+
+					for(int x = 0; x < wrr; x++) {
+						const unsigned pixel_pos = pixel_count / wrr * wr + pixel_count % wrr;
+
+						int index = image->comps[0].data[pixel_pos];
+						index += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
+
+						bits[x] = (WORD)index;
+
+						pixel_count++;
+					}
+				}
+			}
+			else if(numcomps == 3) {
+
+				// 48-bit RGB
+				// ----------------------------------------------------------	
+				
+				// load pixel data
+
+				unsigned pixel_count = 0;
+
+				for(int y = 0; y < hrr; y++) {		
+					FIRGB16 *bits = (FIRGB16*)FreeImage_GetScanLine(dib, hrr - 1 - y);
+
+					for(int x = 0; x < wrr; x++) {
+						const unsigned pixel_pos = pixel_count / wrr * wr + pixel_count % wrr;
+
+						int r = image->comps[0].data[pixel_pos];
+						r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
+						
+						int g = image->comps[1].data[pixel_pos];
+						g += (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
+						
+						int b = image->comps[2].data[pixel_pos];
+						b += (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0);
+
+						bits[x].red   = (WORD)r;
+						bits[x].green = (WORD)g;
+						bits[x].blue  = (WORD)b;
+
+						pixel_count++;
+					}
+				}
+			}
+			else if(numcomps == 4) {
+
+				// 64-bit RGBA
+				// ----------------------------------------------------------	
+				
+				// load pixel data
+
+				unsigned pixel_count = 0;
+
+				for(int y = 0; y < hrr; y++) {		
+					FIRGBA16 *bits = (FIRGBA16*)FreeImage_GetScanLine(dib, hrr - 1 - y);
+
+					for(int x = 0; x < wrr; x++) {
+						const unsigned pixel_pos = pixel_count / wrr * wr + pixel_count % wrr;
+
+						int r = image->comps[0].data[pixel_pos];
+						r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
+						
+						int g = image->comps[1].data[pixel_pos];
+						g += (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
+						
+						int b = image->comps[2].data[pixel_pos];
+						b += (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0);
+
+						int a = image->comps[3].data[pixel_pos];
+						a += (image->comps[3].sgnd ? 1 << (image->comps[3].prec - 1) : 0);
+
+						bits[x].red   = (WORD)r;
+						bits[x].green = (WORD)g;
+						bits[x].blue  = (WORD)b;
+						bits[x].alpha = (WORD)a;
+
+						pixel_count++;
+					}
+				}
+			}
+		}
+
+		return dib;
+
+	} catch(const char *text) {
+		if(dib) FreeImage_Unload(dib);
+		FreeImage_OutputMessageProc(format_id, text);
+		return NULL;
+	}
+
+}
+
+/**
+Convert a FIBITMAP to a OpenJPEG image
+ at param format_id Plugin ID
+ at param dib FreeImage image
+ at param parameters Compression parameters
+ at return Returns the converted image if successful, returns NULL otherwise
+*/
+opj_image_t* FIBITMAPToJ2KImage(int format_id, FIBITMAP *dib, const opj_cparameters_t *parameters) {
+	int prec, numcomps, x, y, index;
+	OPJ_COLOR_SPACE color_space;
+	opj_image_cmptparm_t cmptparm[4];	// maximum of 4 components 
+	opj_image_t *image = NULL;			// image to encode
+
+	try {
+		int w = FreeImage_GetWidth(dib);
+		int h = FreeImage_GetHeight(dib);
+
+		// get image characteristics
+		FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
+
+		if(image_type == FIT_BITMAP) {
+			// standard image ...
+			prec = 8;
+			switch(FreeImage_GetColorType(dib)) {
+				case FIC_MINISBLACK:
+					numcomps = 1;
+					color_space = OPJ_CLRSPC_GRAY;
+					break;
+				case FIC_RGB:
+					if(FreeImage_GetBPP(dib) == 32) {
+						// 32-bit image with a fully opaque layer
+						numcomps = 4;
+						color_space = OPJ_CLRSPC_SRGB;
+					} else {
+						// 24-bit image
+						numcomps = 3;
+						color_space = OPJ_CLRSPC_SRGB;
+					}
+					break;
+				case FIC_RGBALPHA:
+					numcomps = 4;
+					color_space = OPJ_CLRSPC_SRGB;
+					break;
+				default:
+					return NULL;
+			}
+		} else {
+			// HDR image ...
+			prec = 16;
+			switch(image_type) {
+				case FIT_UINT16:
+					numcomps = 1;
+					color_space = OPJ_CLRSPC_GRAY;
+					break;
+				case FIT_RGB16:
+					numcomps = 3;
+					color_space = OPJ_CLRSPC_SRGB;
+					break;
+				case FIT_RGBA16:
+					numcomps = 4;
+					color_space = OPJ_CLRSPC_SRGB;
+					break;
+				default:
+					return NULL;
+			}
+		}
+
+		// initialize image components 
+		memset(&cmptparm[0], 0, 4 * sizeof(opj_image_cmptparm_t));
+		for(int i = 0; i < numcomps; i++) {
+			cmptparm[i].dx = parameters->subsampling_dx;
+			cmptparm[i].dy = parameters->subsampling_dy;
+			cmptparm[i].w = w;
+			cmptparm[i].h = h;
+			cmptparm[i].prec = prec;
+			cmptparm[i].bpp = prec;
+			cmptparm[i].sgnd = 0;
+		}
+		// create the image 
+		image = opj_image_create(numcomps, &cmptparm[0], color_space);
+		if(!image) {
+			throw FI_MSG_ERROR_DIB_MEMORY;
+		}
+
+		// set image offset and reference grid 
+		image->x0 = parameters->image_offset_x0;
+		image->y0 = parameters->image_offset_y0;
+		image->x1 = parameters->image_offset_x0 + (w - 1) *	parameters->subsampling_dx + 1;
+		image->y1 = parameters->image_offset_y0 + (h - 1) *	parameters->subsampling_dy + 1;
+
+		// set image data 
+		if(prec == 8) {
+			switch(numcomps) {
+				case 1:
+					index = 0;
+					for(y = 0; y < h; y++) {
+						BYTE *bits = FreeImage_GetScanLine(dib, h - 1 - y);
+						for(x = 0; x < w; x++) {
+							image->comps[0].data[index] = bits[x];
+							index++;
+						}
+					}
+					break;
+				case 3:
+					index = 0;
+					for(y = 0; y < h; y++) {
+						BYTE *bits = FreeImage_GetScanLine(dib, h - 1 - y);
+						for(x = 0; x < w; x++) {
+							image->comps[0].data[index] = bits[FI_RGBA_RED];
+							image->comps[1].data[index] = bits[FI_RGBA_GREEN];
+							image->comps[2].data[index] = bits[FI_RGBA_BLUE];
+							bits += 3;
+							index++;
+						}
+					}
+					break;
+				case 4:
+					index = 0;
+					for(y = 0; y < h; y++) {
+						BYTE *bits = FreeImage_GetScanLine(dib, h - 1 - y);
+						for(x = 0; x < w; x++) {
+							image->comps[0].data[index] = bits[FI_RGBA_RED];
+							image->comps[1].data[index] = bits[FI_RGBA_GREEN];
+							image->comps[2].data[index] = bits[FI_RGBA_BLUE];
+							image->comps[3].data[index] = bits[FI_RGBA_ALPHA];
+							bits += 4;
+							index++;
+						}
+					}
+					break;
+			}
+		}
+		else if(prec == 16) {
+			switch(numcomps) {
+				case 1:
+					index = 0;
+					for(y = 0; y < h; y++) {
+						WORD *bits = (WORD*)FreeImage_GetScanLine(dib, h - 1 - y);
+						for(x = 0; x < w; x++) {
+							image->comps[0].data[index] = bits[x];
+							index++;
+						}
+					}
+					break;
+				case 3:
+					index = 0;
+					for(y = 0; y < h; y++) {
+						FIRGB16 *bits = (FIRGB16*)FreeImage_GetScanLine(dib, h - 1 - y);
+						for(x = 0; x < w; x++) {
+							image->comps[0].data[index] = bits[x].red;
+							image->comps[1].data[index] = bits[x].green;
+							image->comps[2].data[index] = bits[x].blue;
+							index++;
+						}
+					}
+					break;
+				case 4:
+					index = 0;
+					for(y = 0; y < h; y++) {
+						FIRGBA16 *bits = (FIRGBA16*)FreeImage_GetScanLine(dib, h - 1 - y);
+						for(x = 0; x < w; x++) {
+							image->comps[0].data[index] = bits[x].red;
+							image->comps[1].data[index] = bits[x].green;
+							image->comps[2].data[index] = bits[x].blue;
+							image->comps[3].data[index] = bits[x].alpha;
+							index++;
+						}
+					}
+					break;
+			}
+		}
+
+		return image;
+
+	} catch (const char *text) {
+		if(image) opj_image_destroy(image);
+		FreeImage_OutputMessageProc(format_id, text);
+		return NULL;
+	}
+}
diff --git a/Source/FreeImage/J2KHelper.h b/Source/FreeImage/J2KHelper.h
new file mode 100644
index 0000000..a8121f1
--- /dev/null
+++ b/Source/FreeImage/J2KHelper.h
@@ -0,0 +1,36 @@
+#ifndef J2K_HELPER_H
+#define J2K_HELPER_H
+
+// ==========================================================
+// Helper functions (see J2KHelper.cpp)
+// ==========================================================
+
+/** 
+FreeImageIO wrapper
+*/
+typedef struct tagJ2KFIO_t {
+	FreeImageIO *io;		//! FreeImage IO
+    fi_handle handle;		//! FreeImage handle
+	opj_stream_t *stream;	//! OpenJPEG stream
+} J2KFIO_t;
+
+/**
+Stream constructor
+*/
+J2KFIO_t* opj_freeimage_stream_create(FreeImageIO *io, fi_handle handle, BOOL bRead);
+
+/**
+Stream destructor
+*/
+void opj_freeimage_stream_destroy(J2KFIO_t* fio);
+
+/**
+Conversion opj_image_t => FIBITMAP
+*/
+FIBITMAP* J2KImageToFIBITMAP(int format_id, const opj_image_t *image, BOOL header_only);
+/**
+Conversion FIBITMAP => opj_image_t
+*/
+opj_image_t* FIBITMAPToJ2KImage(int format_id, FIBITMAP *dib, const opj_cparameters_t *parameters);
+
+#endif // J2K_HELPER_H
\ No newline at end of file
diff --git a/Source/FreeImage/LFPQuantizer.cpp b/Source/FreeImage/LFPQuantizer.cpp
new file mode 100644
index 0000000..8b592c3
--- /dev/null
+++ b/Source/FreeImage/LFPQuantizer.cpp
@@ -0,0 +1,208 @@
+// ==========================================================
+// LFPQuantizer class implementation
+//
+// Design and implementation by
+// - Carsten Klein (cklein05 at users.sourceforge.net)
+//
+// This file is part of FreeImage 3
+//
+// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
+// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
+// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
+// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
+// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
+// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
+// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+// THIS DISCLAIMER.
+//
+// Use at your own risk!
+// ==========================================================
+
+#include "Quantizers.h"
+#include "FreeImage.h"
+#include "Utilities.h"
+
+LFPQuantizer::LFPQuantizer(unsigned PaletteSize) :
+		m_size(0), m_limit(PaletteSize), m_index(0) {
+	m_map = new MapEntry[MAP_SIZE];
+	memset(m_map, 0xFF, MAP_SIZE * sizeof(MapEntry));
+}
+
+LFPQuantizer::~LFPQuantizer() {
+    delete[] m_map;
+}
+
+FIBITMAP* LFPQuantizer::Quantize(FIBITMAP *dib, int ReserveSize, RGBQUAD *ReservePalette) {
+
+	if (ReserveSize > 0 && ReservePalette != NULL) {
+		AddReservePalette(ReservePalette, ReserveSize);
+	}
+
+	const unsigned width = FreeImage_GetWidth(dib);
+	const unsigned height = FreeImage_GetHeight(dib);
+
+	FIBITMAP *dib8 = FreeImage_Allocate(width, height, 8);
+	if (dib8 == NULL) {
+		return NULL;
+	}
+
+	const unsigned src_pitch = FreeImage_GetPitch(dib);
+	const unsigned dst_pitch = FreeImage_GetPitch(dib8);
+
+	const BYTE * const src_bits = FreeImage_GetBits(dib);
+	BYTE * const dst_bits = FreeImage_GetBits(dib8);
+
+	unsigned last_color = -1;
+	int last_index = 0;
+
+	if (FreeImage_GetBPP(dib) == 24) {
+
+		// Getting the source pixel as an unsigned int is much faster than
+		// working with FI_RGBA_xxx and shifting. However, this may fail
+		// for the very last pixel, since its rgbReserved member (alpha)
+		// may actually point to an address beyond the bitmap's memory. So,
+		// we do not process the last scanline in the first loop.
+
+		// Process all but the last scanline.
+		for (unsigned y = 0; y < height - 1; ++y) {
+			BYTE *dst_line = dst_bits + y * dst_pitch;
+			const BYTE *src_line = src_bits + y * src_pitch;
+			for (unsigned x = 0; x < width; ++x) {
+				const unsigned color = *((unsigned *) src_line) & 0x00FFFFFF;
+				if (color != last_color) {
+					last_color = color;
+					last_index = GetIndexForColor(color);
+					if (last_index == -1) {
+						FreeImage_Unload(dib8);
+						return NULL;
+					}
+				}
+				dst_line[x] = last_index;
+				src_line += 3;
+			}
+		}
+
+		// Process all but the last pixel of the last scanline.
+		BYTE *dst_line = dst_bits + (height - 1) * dst_pitch;
+		const BYTE *src_line = src_bits + (height - 1) * src_pitch;
+		for (unsigned x = 0; x < width - 1; ++x) {
+			const unsigned color = *((unsigned *) src_line) & 0x00FFFFFF;
+			if (color != last_color) {
+				last_color = color;
+				last_index = GetIndexForColor(color);
+				if (last_index == -1) {
+					FreeImage_Unload(dib8);
+					return NULL;
+				}
+			}
+			dst_line[x] = last_index;
+			src_line += 3;
+		}
+
+		// Process the last pixel (src_line should already point to it).
+		const unsigned color = 0 | src_line[FI_RGBA_BLUE] << FI_RGBA_BLUE_SHIFT
+				| src_line[FI_RGBA_GREEN] << FI_RGBA_GREEN_SHIFT
+				| src_line[FI_RGBA_RED] << FI_RGBA_RED_SHIFT;
+		if (color != last_color) {
+			last_color = color;
+			last_index = GetIndexForColor(color);
+			if (last_index == -1) {
+				FreeImage_Unload(dib8);
+				return NULL;
+			}
+		}
+		dst_line[width - 1] = last_index;
+
+	} else {
+		for (unsigned y = 0; y < height; ++y) {
+			BYTE *dst_line = dst_bits + y * dst_pitch;
+			const BYTE *src_line = src_bits + y * src_pitch;
+			for (unsigned x = 0; x < width; ++x) {
+				const unsigned color = *((unsigned *) src_line) & 0x00FFFFFF;
+				if (color != last_color) {
+					last_color = color;
+					last_index = GetIndexForColor(color);
+					if (last_index == -1) {
+						FreeImage_Unload(dib8);
+						return NULL;
+					}
+				}
+				dst_line[x] = last_index;
+				src_line += 4;
+			}
+		}
+	}
+
+	WritePalette(FreeImage_GetPalette(dib8));
+	return dib8;
+}
+
+/**
+ * Returns the palette index of the specified color. Tries to put the
+ * color into the map, if it's not already present in the map. In that
+ * case, a new index is used for the color. Returns -1, if adding the
+ * color would exceed the desired maximum number of colors in the
+ * palette.
+ * @param color the color to get the index from
+ * @return the palette index of the specified color or -1, if there
+ * is no space left in the palette
+ */
+inline int LFPQuantizer::GetIndexForColor(unsigned color) {
+	unsigned bucket = hash(color) & (MAP_SIZE - 1);
+	while (m_map[bucket].color != color) {
+		if (m_map[bucket].color == EMPTY_BUCKET) {
+			if (m_size == m_limit) {
+				return -1;
+			}
+			m_map[bucket].color = color;
+			m_map[bucket].index = m_index++;
+			++m_size;
+			break;
+		}
+		bucket = (bucket + 1) % MAP_SIZE;
+	}
+	return m_map[bucket].index;
+}
+
+/**
+ * Adds the specified number of entries of the specified reserve
+ * palette to the newly created palette.
+ * @param *palette a pointer to the reserve palette to copy from
+ * @param size the number of entries to copy
+ */
+void LFPQuantizer::AddReservePalette(const void *palette, unsigned size) {
+	if (size > MAX_SIZE) {
+		size = MAX_SIZE;
+	}
+	unsigned *ppal = (unsigned *) palette;
+	const unsigned offset = m_limit - size;
+	for (unsigned i = 0; i < size; ++i) {
+		const unsigned color = *ppal++;
+		const unsigned index = i + offset;
+		unsigned bucket = hash(color) & (MAP_SIZE - 1);
+		while((m_map[bucket].color != EMPTY_BUCKET) && (m_map[bucket].color != color)) {
+			bucket = (bucket + 1) % MAP_SIZE;
+		}
+		if(m_map[bucket].color != color) {
+			m_map[bucket].color = color;
+			m_map[bucket].index = index;
+		}
+	}
+	m_size += size;
+}
+
+/**
+ * Copies the newly created palette into the specified destination
+ * palette. Although unused palette entries are not overwritten in
+ * the destination palette, it is assumed to have space for at
+ * least 256 entries.
+ * @param palette a pointer to the destination palette
+ */
+void LFPQuantizer::WritePalette(void *palette) {
+	for (unsigned i = 0; i < MAP_SIZE; ++i) {
+		if (m_map[i].color != EMPTY_BUCKET) {
+			((unsigned *) palette)[m_map[i].index] = m_map[i].color;
+		}
+	}
+}
diff --git a/Source/FreeImage/MNGHelper.cpp b/Source/FreeImage/MNGHelper.cpp
index a4c67a2..ed3664c 100644
--- a/Source/FreeImage/MNGHelper.cpp
+++ b/Source/FreeImage/MNGHelper.cpp
@@ -357,7 +357,6 @@ Retrieve the position of a chunk in a PNG stream
 */
 static BOOL 
 mng_FindChunk(FIMEMORY *hPngMemory, BYTE *chunk_name, long offset, DWORD *start_pos, DWORD *next_pos) {
-	BOOL mEnd = FALSE;
 	DWORD mLength = 0;
 
 	BYTE *data = NULL;
@@ -513,10 +512,14 @@ mng_RemoveChunk(FIMEMORY *hPngMemory, BYTE *chunk_name) {
 	DWORD next_pos = 0;
 	
 	bResult = mng_FindChunk(hPngMemory, chunk_name, 8, &start_pos, &next_pos);
-	if(!bResult) return FALSE;
+	if(!bResult) {
+		return FALSE;
+	}
 
 	bResult = mng_CopyRemoveChunks(hPngMemory, start_pos, next_pos);
-	if(!bResult) return FALSE;
+	if(!bResult) {
+		return FALSE;
+	}
 
 	return TRUE;
 }
@@ -529,10 +532,14 @@ mng_InsertChunk(FIMEMORY *hPngMemory, BYTE *inNextChunkName, BYTE *inInsertChunk
 	DWORD next_pos = 0;
 	
 	bResult = mng_FindChunk(hPngMemory, inNextChunkName, 8, &start_pos, &next_pos);
-	if(!bResult) return FALSE;
+	if(!bResult) {
+		return FALSE;
+	}
 
 	bResult = mng_CopyInsertChunks(hPngMemory, inNextChunkName, inInsertChunk, chunk_length, start_pos, next_pos);
-	if(!bResult) return FALSE;
+	if(!bResult) {
+		return FALSE;
+	}
 
 	return TRUE;
 }
@@ -962,7 +969,7 @@ mng_ReadChunks(int format_id, FreeImageIO *io, fi_handle handle, long Offset, in
 						jng_color_type = mChunk[8];
 						jng_image_sample_depth = mChunk[9];
 						jng_image_compression_method = mChunk[10];
-						BYTE jng_image_interlace_method = mChunk[11];
+						//BYTE jng_image_interlace_method = mChunk[11];	// for debug only
 
 						jng_alpha_sample_depth = mChunk[12];
 						jng_alpha_compression_method = mChunk[13];
@@ -1000,7 +1007,9 @@ mng_ReadChunks(int format_id, FreeImageIO *io, fi_handle handle, long Offset, in
 						break;
 					}
 					// load the JPEG
-					if(dib) FreeImage_Unload(dib);
+					if(dib) {
+						FreeImage_Unload(dib);
+					}
 					dib = mng_LoadFromMemoryHandle(hJpegMemory, flags);
 
 					// load the PNG alpha layer
@@ -1017,7 +1026,9 @@ mng_ReadChunks(int format_id, FreeImageIO *io, fi_handle handle, long Offset, in
 							}
 							mng_WritePNGStream(jng_width, jng_height, jng_alpha_sample_depth, data, size_in_bytes, hPngMemory);
 							// load the PNG
-							if(dib_alpha) FreeImage_Unload(dib_alpha);
+							if(dib_alpha) {
+								FreeImage_Unload(dib_alpha);
+							}
 							dib_alpha = mng_LoadFromMemoryHandle(hPngMemory, flags);
 						}
 					}
diff --git a/Source/FreeImage/MemoryIO.cpp b/Source/FreeImage/MemoryIO.cpp
index 6ae3fb2..e099785 100644
--- a/Source/FreeImage/MemoryIO.cpp
+++ b/Source/FreeImage/MemoryIO.cpp
@@ -48,7 +48,7 @@ FreeImage_OpenMemory(BYTE *data, DWORD size_in_bytes) {
 				// wrap a user buffer
 				mem_header->delete_me = FALSE;
 				mem_header->data = (BYTE*)data;
-				mem_header->datalen = mem_header->filelen = size_in_bytes;
+				mem_header->data_length = mem_header->file_length = size_in_bytes;
 			} else {
 				mem_header->delete_me = TRUE;
 			}
@@ -120,7 +120,7 @@ FreeImage_AcquireMemory(FIMEMORY *stream, BYTE **data, DWORD *size_in_bytes) {
 		FIMEMORYHEADER *mem_header = (FIMEMORYHEADER*)(stream->data);
 
 		*data = (BYTE*)mem_header->data;
-		*size_in_bytes = mem_header->filelen;
+		*size_in_bytes = mem_header->file_length;
 		return TRUE;
 	}
 
diff --git a/Source/FreeImage/MultiPage.cpp b/Source/FreeImage/MultiPage.cpp
index 3bc7b70..6db64be 100644
--- a/Source/FreeImage/MultiPage.cpp
+++ b/Source/FreeImage/MultiPage.cpp
@@ -1,974 +1,974 @@
-// ==========================================================
-// Multi-Page functions
-//
-// Design and implementation by
-// - Floris van den Berg (flvdberg at wxs.nl)
-// - Laurent Rocher (rocherl at club-internet.fr)
-// - Steve Johnson (steve at parisgroup.net)
-// - Petr Pytelka (pyta at lightcomp.com)
-// - Herv� Drolon (drolon at infonie.fr)
-// - Vadim Alexandrov (vadimalexandrov at users.sourceforge.net
-// - Martin Dyring-Andersen (mda at spamfighter.com)
-// - Volodymyr Goncharov (volodymyr.goncharov at gmail.com)
-//
-// This file is part of FreeImage 3
-//
-// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
-// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
-// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
-// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
-// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
-// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
-// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
-// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
-// THIS DISCLAIMER.
-//
-// Use at your own risk!
-// ==========================================================
-
-#ifdef _MSC_VER 
-#pragma warning (disable : 4786) // identifier was truncated to 'number' characters
-#endif
-
-#include "CacheFile.h"
-#include "FreeImageIO.h"
-#include "Plugin.h"
-#include "Utilities.h"
-#include "FreeImage.h"
-
-// ----------------------------------------------------------
-
-enum BlockType { BLOCK_CONTINUEUS, BLOCK_REFERENCE };
-
-// ----------------------------------------------------------
-
-struct BlockTypeS {
-	BlockType m_type;
-
-	BlockTypeS(BlockType type) : m_type(type) {
-	}
-	virtual ~BlockTypeS() {}
-};
-
-struct BlockContinueus : public BlockTypeS {
-	int       m_start;
-	int       m_end;
-
-	BlockContinueus(int s, int e) : BlockTypeS(BLOCK_CONTINUEUS),
-	m_start(s),
-	m_end(e) {
-	}	
-};
-
-struct BlockReference : public BlockTypeS {
-	int       m_reference;
-	int       m_size;
-
-	BlockReference(int r, int size) : BlockTypeS(BLOCK_REFERENCE),
-	m_reference(r),
-	m_size(size) {
-	}
-};
-
-// ----------------------------------------------------------
-
-typedef std::list<BlockTypeS *> BlockList;
-typedef std::list<BlockTypeS *>::iterator BlockListIterator;
-
-// ----------------------------------------------------------
-
-FI_STRUCT (MULTIBITMAPHEADER) {
-	PluginNode *node;
-	FREE_IMAGE_FORMAT fif;
-	FreeImageIO *io;
-	fi_handle handle;
-	CacheFile *m_cachefile;
-	std::map<FIBITMAP *, int> locked_pages;
-	BOOL changed;
-	int page_count;
-	BlockList m_blocks;
-	char *m_filename;
-	BOOL read_only;
-	FREE_IMAGE_FORMAT cache_fif;
-	int load_flags;
-};
-
-// =====================================================================
-// Helper functions
-// =====================================================================
-
-inline void
-ReplaceExtension(std::string& dst_filename, const std::string& src_filename, const std::string& dst_extension) {
-	size_t lastDot = src_filename.find_last_of('.');
-	if (lastDot == std::string::npos) {
-		dst_filename = src_filename;
-		dst_filename += ".";
-		dst_filename += dst_extension;
-	}
-	else {
-		dst_filename = src_filename.substr(0, lastDot + 1);
-		dst_filename += dst_extension;
-	}
-}
-
-// =====================================================================
-// Internal Multipage functions
-// =====================================================================
-
-inline MULTIBITMAPHEADER *
-FreeImage_GetMultiBitmapHeader(FIMULTIBITMAP *bitmap) {
-	return (MULTIBITMAPHEADER *)bitmap->data;
-}
-
-static BlockListIterator DLL_CALLCONV
-FreeImage_FindBlock(FIMULTIBITMAP *bitmap, int position) {
-	assert(NULL != bitmap);
-
-	MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
-
-	// step 1: find the block that matches the given position
-
-	int prev_count = 0;
-	int count = 0;
-	BlockListIterator i;
-	BlockTypeS *current_block = NULL;
-
-	for (i = header->m_blocks.begin(); i != header->m_blocks.end(); ++i) {
-		prev_count = count;
-
-		switch((*i)->m_type) {
-			case BLOCK_CONTINUEUS :
-				count += ((BlockContinueus *)(*i))->m_end - ((BlockContinueus *)(*i))->m_start + 1;
-				break;
-
-			case BLOCK_REFERENCE :
-				count++;
-				break;
-		}
-
-		current_block = *i;
-
-		if (count > position)
-			break;
-	}
-
-	// step 2: make sure we found the node. from here it gets a little complicated:
-	// * if the block is there, just return it
-	// * if the block is a series of blocks, split it in max 3 new blocks
-	//   and return the splitted block
-
-	if ((current_block) && (count > position)) {
-		switch(current_block->m_type) {
-			case BLOCK_REFERENCE :
-				return i;
-
-			case BLOCK_CONTINUEUS :
-			{
-				BlockContinueus *block = (BlockContinueus *)current_block;
-
-				if (block->m_start != block->m_end) {
-					int item = block->m_start + (position - prev_count);
-
-					// left part
-
-					if (item != block->m_start) {
-						BlockContinueus *block_a = new BlockContinueus(block->m_start, item - 1);
-						header->m_blocks.insert(i, (BlockTypeS *)block_a);
-					}
-
-					// middle part
-
-					BlockContinueus *block_b = new BlockContinueus(item, item);
-					BlockListIterator block_target = header->m_blocks.insert(i, (BlockTypeS *)block_b);
-
-					// right part
-
-					if (item != block->m_end) {
-						BlockContinueus *block_c = new BlockContinueus(item + 1, block->m_end);
-						header->m_blocks.insert(i, (BlockTypeS *)block_c);
-					}
-
-					// remove the old block that was just splitted
-
-					header->m_blocks.remove((BlockTypeS *)block);
-					delete block;
-
-					// return the splitted block
-					
-					return block_target;
-				}
-
-				return i;
-			}
-		}
-	}
-	// we should never go here ...
-	assert(false);
-	return header->m_blocks.end();
-}
-
-int DLL_CALLCONV
-FreeImage_InternalGetPageCount(FIMULTIBITMAP *bitmap) {	
-	if (bitmap) {
-		if (((MULTIBITMAPHEADER *)bitmap->data)->handle) {
-			MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
-
-			header->io->seek_proc(header->handle, 0, SEEK_SET);
-
-   			void *data = FreeImage_Open(header->node, header->io, header->handle, TRUE);
-
-			int page_count = (header->node->m_plugin->pagecount_proc != NULL) ? header->node->m_plugin->pagecount_proc(header->io, header->handle, data) : 1;
-
-			FreeImage_Close(header->node, header->io, header->handle, data);
-
-			return page_count;
-		}
-	}
-
-	return 0;
-}
-
-// =====================================================================
-// Multipage functions
-// =====================================================================
-
-FIMULTIBITMAP * DLL_CALLCONV
-FreeImage_OpenMultiBitmap(FREE_IMAGE_FORMAT fif, const char *filename, BOOL create_new, BOOL read_only, BOOL keep_cache_in_memory, int flags) {
-
-	FILE *handle = NULL;
-	try {
-		// sanity check on the parameters
-
-		if (create_new) {
-			read_only = FALSE;
-		}
-
-		// retrieve the plugin list to find the node belonging to this plugin
-
-		PluginList *list = FreeImage_GetPluginList();
-
-		if (list) {
-			PluginNode *node = list->FindNodeFromFIF(fif);
-
-			if (node) {
-				std::auto_ptr<FreeImageIO> io (new FreeImageIO);
-
-				SetDefaultIO(io.get());
-
-				if (!create_new) {
-					handle = fopen(filename, "rb");
-					if (handle == NULL) {
-						return NULL;
-					}
-				}
-
-				std::auto_ptr<FIMULTIBITMAP> bitmap (new FIMULTIBITMAP);
-				std::auto_ptr<MULTIBITMAPHEADER> header (new MULTIBITMAPHEADER);
-				header->m_filename = new char[strlen(filename) + 1];
-				strcpy(header->m_filename, filename);
-				header->node = node;
-				header->fif = fif;
-				header->io = io.get ();
-				header->handle = handle;						
-				header->changed = FALSE;						
-				header->read_only = read_only;
-				header->m_cachefile = NULL;
-				header->cache_fif = fif;
-				header->load_flags = flags;
-
-				// store the MULTIBITMAPHEADER in the surrounding FIMULTIBITMAP structure
-
-				bitmap->data = header.get();
-
-				// cache the page count
-
-				header->page_count = FreeImage_InternalGetPageCount(bitmap.get());
-
-				// allocate a continueus block to describe the bitmap
-
-				if (!create_new) {
-					header->m_blocks.push_back((BlockTypeS *)new BlockContinueus(0, header->page_count - 1));
-				}
-
-				// set up the cache
-
-				if (!read_only) {
-					std::string cache_name;
-					ReplaceExtension(cache_name, filename, "ficache");
-
-					std::auto_ptr<CacheFile> cache_file (new CacheFile(cache_name, keep_cache_in_memory));
-
-					if (cache_file->open()) {
-						// we can use release() as std::bad_alloc won't be thrown from here on
-						header->m_cachefile = cache_file.release();
-					} else {
-						// an error occured ...
-						fclose(handle);
-						return NULL;
-					}
-				}
-				// return the multibitmap
-				// std::bad_alloc won't be thrown from here on
-				header.release(); // now owned by bitmap
-				io.release();	  // now owned by bitmap
-				return bitmap.release(); // now owned by caller
-			}
-		}
-	} catch (std::bad_alloc &) {
-		/** @todo report error */
-	}
-	if (handle)
-		fclose(handle);
-	return NULL;
-}
-
-FIMULTIBITMAP * DLL_CALLCONV
-FreeImage_OpenMultiBitmapFromHandle(FREE_IMAGE_FORMAT fif, FreeImageIO *io, fi_handle handle, int flags) {
-	try {
-		BOOL read_only = FALSE;	// modifications (if any) will be stored into the memory cache
-
-		if (io && handle) {
-		
-			// retrieve the plugin list to find the node belonging to this plugin
-			PluginList *list = FreeImage_GetPluginList();
-		
-			if (list) {
-				PluginNode *node = list->FindNodeFromFIF(fif);
-			
-				if (node) {
-					std::auto_ptr<FIMULTIBITMAP> bitmap (new FIMULTIBITMAP);
-					std::auto_ptr<MULTIBITMAPHEADER> header (new MULTIBITMAPHEADER);
-					std::auto_ptr<FreeImageIO> tmp_io (new FreeImageIO (*io));
-					header->io = tmp_io.get();
-					header->m_filename = NULL;
-					header->node = node;
-					header->fif = fif;
-					header->handle = handle;						
-					header->changed = FALSE;						
-					header->read_only = read_only;	
-					header->m_cachefile = NULL;
-					header->cache_fif = fif;
-					header->load_flags = flags;
-							
-					// store the MULTIBITMAPHEADER in the surrounding FIMULTIBITMAP structure
-
-					bitmap->data = header.get();
-
-					// cache the page count
-
-					header->page_count = FreeImage_InternalGetPageCount(bitmap.get());
-
-					// allocate a continueus block to describe the bitmap
-
-					header->m_blocks.push_back((BlockTypeS *)new BlockContinueus(0, header->page_count - 1));
-
-					if (!read_only) {
-						// set up the cache
-						std::auto_ptr<CacheFile> cache_file (new CacheFile("", TRUE));
-						
-						if (cache_file->open()) {
-							header->m_cachefile = cache_file.release();
-						}
-					}
-					tmp_io.release();
-					header.release();
-					return bitmap.release();
-				}
-			}
-		}
-	} catch (std::bad_alloc &) {
-		/** @todo report error */
-	}
-	return NULL;
-}
-
-BOOL DLL_CALLCONV
-FreeImage_SaveMultiBitmapToHandle(FREE_IMAGE_FORMAT fif, FIMULTIBITMAP *bitmap, FreeImageIO *io, fi_handle handle, int flags) {
-	if(!bitmap || !bitmap->data || !io || !handle) {
-		return FALSE;
-	}
-
-	BOOL success = TRUE;
-
-	// retrieve the plugin list to find the node belonging to this plugin
-	PluginList *list = FreeImage_GetPluginList();
-	
-	if (list) {
-		PluginNode *node = list->FindNodeFromFIF(fif);
-
-		if(node) {
-			MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
-			
-			// dst data
-			void *data = FreeImage_Open(node, io, handle, FALSE);
-			// src data
-			void *data_read = NULL;
-			
-			if(header->handle) {
-				// open src
-				header->io->seek_proc(header->handle, 0, SEEK_SET);
-				data_read = FreeImage_Open(header->node, header->io, header->handle, TRUE);
-			}
-			
-			// write all the pages to the file using handle and io
-			
-			int count = 0;
-			
-			for (BlockListIterator i = header->m_blocks.begin(); i != header->m_blocks.end(); i++) {
-				if (success) {
-					switch((*i)->m_type) {
-						case BLOCK_CONTINUEUS:
-						{
-							BlockContinueus *block = (BlockContinueus *)(*i);
-							
-							for (int j = block->m_start; j <= block->m_end; j++) {
-
-								// load the original source data
-								FIBITMAP *dib = header->node->m_plugin->load_proc(header->io, header->handle, j, header->load_flags, data_read);
-								
-								// save the data
-								success = node->m_plugin->save_proc(io, dib, handle, count, flags, data);
-								count++;
-								
-								FreeImage_Unload(dib);
-							}
-							
-							break;
-						}
-						
-						case BLOCK_REFERENCE:
-						{
-							BlockReference *ref = (BlockReference *)(*i);
-							
-							// read the compressed data
-							
-							BYTE *compressed_data = (BYTE*)malloc(ref->m_size * sizeof(BYTE));
-							
-							header->m_cachefile->readFile((BYTE *)compressed_data, ref->m_reference, ref->m_size);
-							
-							// uncompress the data
-							
-							FIMEMORY *hmem = FreeImage_OpenMemory(compressed_data, ref->m_size);
-							FIBITMAP *dib = FreeImage_LoadFromMemory(header->cache_fif, hmem, 0);
-							FreeImage_CloseMemory(hmem);
-							
-							// get rid of the buffer
-							free(compressed_data);
-							
-							// save the data
-							
-							success = node->m_plugin->save_proc(io, dib, handle, count, flags, data);
-							count++;
-							
-							// unload the dib
-
-							FreeImage_Unload(dib);
-
-							break;
-						}
-					}
-				} else {
-					break;
-				}
-			}
-			
-			// close the files
-			
-			FreeImage_Close(header->node, header->io, header->handle, data_read);
-
-			FreeImage_Close(node, io, handle, data); 
-			
-			return success;
-		}
-	}
-
-	return FALSE;
-}
-
-
-BOOL DLL_CALLCONV
-FreeImage_CloseMultiBitmap(FIMULTIBITMAP *bitmap, int flags) {
-	if (bitmap) {
-		BOOL success = TRUE;
-		
-		if (bitmap->data) {
-			MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);			
-			
-			// saves changes only of images loaded directly from a file
-			if (header->changed && header->m_filename) {
-				try {
-					// open a temp file
-
-					std::string spool_name;
-
-					ReplaceExtension(spool_name, header->m_filename, "fispool");
-
-					// open the spool file and the source file
-        
-					FILE *f = fopen(spool_name.c_str(), "w+b");
-				
-					// saves changes
-					if (f == NULL) {
-						FreeImage_OutputMessageProc(header->fif, "Failed to open %s, %s", spool_name.c_str(), strerror(errno));
-						success = FALSE;
-					} else {
-						success = FreeImage_SaveMultiBitmapToHandle(header->fif, bitmap, header->io, (fi_handle)f, flags);
-
-						// close the files
-
-						if (fclose(f) != 0) {
-							success = FALSE;
-							FreeImage_OutputMessageProc(header->fif, "Failed to close %s, %s", spool_name.c_str(), strerror(errno));
-						}
-					}
-					if (header->handle) {
-						fclose((FILE *)header->handle);
-					}
-				
-					// applies changes to the destination file
-
-					if (success) {
-						remove(header->m_filename);
-						success = (rename(spool_name.c_str(), header->m_filename) == 0) ? TRUE:FALSE;
-						if(!success) {
-							FreeImage_OutputMessageProc(header->fif, "Failed to rename %s to %s", spool_name.c_str(), header->m_filename);
-						}
-					} else {
-						remove(spool_name.c_str());
-					}
-				} catch (std::bad_alloc &) {
-					success = FALSE;
-				}
-
-			} else {
-				if (header->handle && header->m_filename) {
-					fclose((FILE *)header->handle);
-				}
-			}
-
-			// clear the blocks list
-
-			for (BlockListIterator i = header->m_blocks.begin(); i != header->m_blocks.end(); ++i) {
-				delete *i;
-			}
-
-			// flush and dispose the cache
-
-			if (header->m_cachefile) {
-				header->m_cachefile->close();
-				delete header->m_cachefile;
-			}
-
-			// delete the last open bitmaps
-
-			while (!header->locked_pages.empty()) {
-				FreeImage_Unload(header->locked_pages.begin()->first);
-
-				header->locked_pages.erase(header->locked_pages.begin()->first);
-			}
-
-			// get rid of the IO structure
-
-			delete header->io;
-
-			// delete the filename
-
-			if(header->m_filename) {
-				delete[] header->m_filename;
-			}
-
-			// delete the FIMULTIBITMAPHEADER
-
-			delete header;
-		}
-
-		delete bitmap;
-
-		return success;
-	}
-
-	return FALSE;
-}
-
-int DLL_CALLCONV
-FreeImage_GetPageCount(FIMULTIBITMAP *bitmap) {
-	if (bitmap) {
-		MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
-
-		if (header->page_count == -1) {
-			header->page_count = 0;
-
-			for (BlockListIterator i = header->m_blocks.begin(); i != header->m_blocks.end(); ++i) {
-				switch((*i)->m_type) {
-					case BLOCK_CONTINUEUS :
-						header->page_count += ((BlockContinueus *)(*i))->m_end - ((BlockContinueus *)(*i))->m_start + 1;
-						break;
-
-					case BLOCK_REFERENCE :
-						header->page_count++;
-						break;
-				}
-			}
-		}
-
-		return header->page_count;
-	}
-
-	return 0;
-}
-
-static BlockReference* 
-FreeImage_SavePageToBlock(MULTIBITMAPHEADER *header, FIBITMAP *data) {
-	if (header->read_only || !header->locked_pages.empty())
-		return NULL;
-
-	DWORD compressed_size = 0;
-	BYTE *compressed_data = NULL;
-
-	// compress the bitmap data
-
-	// open a memory handle
-	FIMEMORY *hmem = FreeImage_OpenMemory();
-	if(hmem==NULL) return NULL;
-	// save the file to memory
-	if(!FreeImage_SaveToMemory(header->cache_fif, data, hmem, 0)) {
-		FreeImage_CloseMemory(hmem);
-		return NULL;
-	}
-	// get the buffer from the memory stream
-	if(!FreeImage_AcquireMemory(hmem, &compressed_data, &compressed_size)) {
-		FreeImage_CloseMemory(hmem);
-		return NULL;
-	}
-
-	// write the compressed data to the cache
-	int ref = header->m_cachefile->writeFile(compressed_data, compressed_size);
-	// get rid of the compressed data
-	FreeImage_CloseMemory(hmem);
-
-	return new(std::nothrow) BlockReference(ref, compressed_size);
-}
-
-void DLL_CALLCONV
-FreeImage_AppendPage(FIMULTIBITMAP *bitmap, FIBITMAP *data) {
-	if (!bitmap || !data) 
-		return;
-
-	MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
-
-	BlockReference *block = FreeImage_SavePageToBlock(header, data);
-	if(block==NULL) return;
-
-	// add the block
-	header->m_blocks.push_back((BlockTypeS *)block);
-	header->changed = TRUE;
-	header->page_count = -1;
-}
-
-void DLL_CALLCONV
-FreeImage_InsertPage(FIMULTIBITMAP *bitmap, int page, FIBITMAP *data) {
-	if (!bitmap || !data) 
-		return;
-
-	if (page >= FreeImage_GetPageCount(bitmap)) 
-		return;
-			
-	MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
-
-	BlockReference *block = FreeImage_SavePageToBlock(header, data);
-	if(block==NULL) return;
-
-	// add a block
-	if (page > 0) {
-		BlockListIterator block_source = FreeImage_FindBlock(bitmap, page);		
-
-		header->m_blocks.insert(block_source, (BlockTypeS *)block);
-	} else {
-		header->m_blocks.push_front((BlockTypeS *)block);
-	}
-
-	header->changed = TRUE;
-	header->page_count = -1;
-}
-
-void DLL_CALLCONV
-FreeImage_DeletePage(FIMULTIBITMAP *bitmap, int page) {
-	if (bitmap) {
-		MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
-
-		if ((!header->read_only) && (header->locked_pages.empty())) {
-			if (FreeImage_GetPageCount(bitmap) > 1) {
-				BlockListIterator i = FreeImage_FindBlock(bitmap, page);
-
-				if (i != header->m_blocks.end()) {
-					switch((*i)->m_type) {
-						case BLOCK_CONTINUEUS :
-							delete *i;
-							header->m_blocks.erase(i);
-							break;
-
-						case BLOCK_REFERENCE :
-							header->m_cachefile->deleteFile(((BlockReference *)(*i))->m_reference);
-							delete *i;
-							header->m_blocks.erase(i);
-							break;
-					}
-
-					header->changed = TRUE;
-					header->page_count = -1;
-				}
-			}
-		}
-	}
-}
-
-
-FIBITMAP * DLL_CALLCONV
-FreeImage_LockPage(FIMULTIBITMAP *bitmap, int page) {
-	if (bitmap) {
-		MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
-
-		// only lock if the page wasn't locked before...
-
-		for (std::map<FIBITMAP *, int>::iterator i = header->locked_pages.begin(); i != header->locked_pages.end(); ++i) {
-			if (i->second == page) {
-				return NULL;
-			}
-		}
-
-		// open the bitmap
-
-		header->io->seek_proc(header->handle, 0, SEEK_SET);
-
-   		void *data = FreeImage_Open(header->node, header->io, header->handle, TRUE);
-
-		// load the bitmap data
-
-		if (data != NULL) {
-			FIBITMAP *dib = (header->node->m_plugin->load_proc != NULL) ? header->node->m_plugin->load_proc(header->io, header->handle, page, header->load_flags, data) : NULL;
-
-			// close the file
-
-			FreeImage_Close(header->node, header->io, header->handle, data);
-
-			// if there was still another bitmap open, get rid of it
-
-			if (dib) {
-				header->locked_pages[dib] = page;
-
-				return dib;
-			}	
-
-			return NULL;
-		}
-	}
-
-	return NULL;
-}
-
-void DLL_CALLCONV
-FreeImage_UnlockPage(FIMULTIBITMAP *bitmap, FIBITMAP *page, BOOL changed) {
-	if ((bitmap) && (page)) {
-		MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
-
-		// find out if the page we try to unlock is actually locked...
-
-		if (header->locked_pages.find(page) != header->locked_pages.end()) {
-			// store the bitmap compressed in the cache for later writing
-
-			if (changed && !header->read_only) {
-				header->changed = TRUE;
-
-				// cut loose the block from the rest
-
-				BlockListIterator i = FreeImage_FindBlock(bitmap, header->locked_pages[page]);
-
-				// compress the data
-
-				DWORD compressed_size = 0;
-				BYTE *compressed_data = NULL;
-
-				// open a memory handle
-				FIMEMORY *hmem = FreeImage_OpenMemory();
-				// save the page to memory
-				FreeImage_SaveToMemory(header->cache_fif, page, hmem, 0);
-				// get the buffer from the memory stream
-				FreeImage_AcquireMemory(hmem, &compressed_data, &compressed_size);
-
-				// write the data to the cache
-
-				switch ((*i)->m_type) {
-					case BLOCK_CONTINUEUS :
-					{
-						int iPage = header->m_cachefile->writeFile(compressed_data, compressed_size);
-
-						delete (*i);
-
-						*i = (BlockTypeS *)new BlockReference(iPage, compressed_size);
-
-						break;
-					}
-
-					case BLOCK_REFERENCE :
-					{
-						BlockReference *reference = (BlockReference *)(*i);
-
-						header->m_cachefile->deleteFile(reference->m_reference);
-
-						delete (*i);
-
-						int iPage = header->m_cachefile->writeFile(compressed_data, compressed_size);
-
-						*i = (BlockTypeS *)new BlockReference(iPage, compressed_size);
-
-						break;
-					}
-				}
-
-				// get rid of the compressed data
-
-				FreeImage_CloseMemory(hmem);
-			}
-
-			// reset the locked page so that another page can be locked
-
-			FreeImage_Unload(page);
-
-			header->locked_pages.erase(page);
-		}
-	}
-}
-
-BOOL DLL_CALLCONV
-FreeImage_MovePage(FIMULTIBITMAP *bitmap, int target, int source) {
-	if (bitmap) {
-		MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
-
-		if ((!header->read_only) && (header->locked_pages.empty())) {
-			if ((target != source) && ((target >= 0) && (target < FreeImage_GetPageCount(bitmap))) && ((source >= 0) && (source < FreeImage_GetPageCount(bitmap)))) {
-				BlockListIterator block_source = FreeImage_FindBlock(bitmap, target);
-				BlockListIterator block_target = FreeImage_FindBlock(bitmap, source);
-
-				header->m_blocks.insert(block_target, *block_source);			
-				header->m_blocks.erase(block_source);
-
-				header->changed = TRUE;
-
-				return TRUE;
-			}
-		}
-	}
-
-	return FALSE;
-}
-
-BOOL DLL_CALLCONV
-FreeImage_GetLockedPageNumbers(FIMULTIBITMAP *bitmap, int *pages, int *count) {
-	if ((bitmap) && (count)) {
-		MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
-
-		if ((pages == NULL) || (*count == 0)) {
-			*count = (int)header->locked_pages.size();
-		} else {
-			int c = 0;
-
-			for (std::map<FIBITMAP *, int>::iterator i = header->locked_pages.begin(); i != header->locked_pages.end(); ++i) {
-				pages[c] = i->second;
-
-				c++;
-
-				if (c == *count)
-					break;
-			}
-		}
-
-		return TRUE;
-	}
-
-	return FALSE;
-}
-
-// =====================================================================
-// Memory IO Multipage functions
-// =====================================================================
-
-FIMULTIBITMAP * DLL_CALLCONV
-FreeImage_LoadMultiBitmapFromMemory(FREE_IMAGE_FORMAT fif, FIMEMORY *stream, int flags) {
-	BOOL read_only = FALSE;	// modifications (if any) will be stored into the memory cache
-
-	// retrieve the plugin list to find the node belonging to this plugin
-
-	PluginList *list = FreeImage_GetPluginList();
-
-	if (list) {
-		PluginNode *node = list->FindNodeFromFIF(fif);
-
-		if (node) {
-			FreeImageIO *io = new(std::nothrow) FreeImageIO;
-
-			if (io) {
-				SetMemoryIO(io);
-
-				FIMULTIBITMAP *bitmap = new(std::nothrow) FIMULTIBITMAP;
-
-				if (bitmap) {
-					MULTIBITMAPHEADER *header = new(std::nothrow) MULTIBITMAPHEADER;
-
-					if (header) {
-						header->m_filename = NULL;
-						header->node = node;
-						header->fif = fif;
-						header->io = io;
-						header->handle = (fi_handle)stream;						
-						header->changed = FALSE;						
-						header->read_only = read_only;
-						header->m_cachefile = NULL;
-						header->cache_fif = fif;
-						header->load_flags = flags;
-
-						// store the MULTIBITMAPHEADER in the surrounding FIMULTIBITMAP structure
-
-						bitmap->data = header;
-
-						// cache the page count
-
-						header->page_count = FreeImage_InternalGetPageCount(bitmap);
-
-						// allocate a continueus block to describe the bitmap
-
-						header->m_blocks.push_back((BlockTypeS *)new BlockContinueus(0, header->page_count - 1));
-						
-						if (!read_only) {
-							// set up the cache
-							CacheFile *cache_file = new(std::nothrow) CacheFile("", TRUE);
-							
-							if (cache_file && cache_file->open()) {
-								header->m_cachefile = cache_file;
-							}
-						}
-
-						return bitmap;
-					}
-					
-					delete bitmap;
-				}
-				
-				delete io;
-			}
-		}
-	}
-
-	return NULL;
-}
-
-BOOL DLL_CALLCONV
-FreeImage_SaveMultiBitmapToMemory(FREE_IMAGE_FORMAT fif, FIMULTIBITMAP *bitmap, FIMEMORY *stream, int flags) {
-	if (stream && stream->data) {
-		FreeImageIO io;
-		SetMemoryIO(&io);
-
-		return FreeImage_SaveMultiBitmapToHandle(fif, bitmap, &io, (fi_handle)stream, flags);
-	}
-
-	return FALSE;
-}
+// ==========================================================
+// Multi-Page functions
+//
+// Design and implementation by
+// - Floris van den Berg (flvdberg at wxs.nl)
+// - Laurent Rocher (rocherl at club-internet.fr)
+// - Steve Johnson (steve at parisgroup.net)
+// - Petr Pytelka (pyta at lightcomp.com)
+// - Herv� Drolon (drolon at infonie.fr)
+// - Vadim Alexandrov (vadimalexandrov at users.sourceforge.net
+// - Martin Dyring-Andersen (mda at spamfighter.com)
+// - Volodymyr Goncharov (volodymyr.goncharov at gmail.com)
+//
+// This file is part of FreeImage 3
+//
+// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
+// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
+// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
+// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
+// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
+// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
+// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+// THIS DISCLAIMER.
+//
+// Use at your own risk!
+// ==========================================================
+
+#ifdef _MSC_VER 
+#pragma warning (disable : 4786) // identifier was truncated to 'number' characters
+#endif
+
+#include "CacheFile.h"
+#include "FreeImageIO.h"
+#include "Plugin.h"
+#include "Utilities.h"
+#include "FreeImage.h"
+
+// ----------------------------------------------------------
+
+enum BlockType { BLOCK_CONTINUEUS, BLOCK_REFERENCE };
+
+// ----------------------------------------------------------
+
+struct BlockTypeS {
+	BlockType m_type;
+
+	BlockTypeS(BlockType type) : m_type(type) {
+	}
+	virtual ~BlockTypeS() {}
+};
+
+struct BlockContinueus : public BlockTypeS {
+	int       m_start;
+	int       m_end;
+
+	BlockContinueus(int s, int e) : BlockTypeS(BLOCK_CONTINUEUS),
+	m_start(s),
+	m_end(e) {
+	}	
+};
+
+struct BlockReference : public BlockTypeS {
+	int       m_reference;
+	int       m_size;
+
+	BlockReference(int r, int size) : BlockTypeS(BLOCK_REFERENCE),
+	m_reference(r),
+	m_size(size) {
+	}
+};
+
+// ----------------------------------------------------------
+
+typedef std::list<BlockTypeS *> BlockList;
+typedef std::list<BlockTypeS *>::iterator BlockListIterator;
+
+// ----------------------------------------------------------
+
+FI_STRUCT (MULTIBITMAPHEADER) {
+	PluginNode *node;
+	FREE_IMAGE_FORMAT fif;
+	FreeImageIO *io;
+	fi_handle handle;
+	CacheFile *m_cachefile;
+	std::map<FIBITMAP *, int> locked_pages;
+	BOOL changed;
+	int page_count;
+	BlockList m_blocks;
+	char *m_filename;
+	BOOL read_only;
+	FREE_IMAGE_FORMAT cache_fif;
+	int load_flags;
+};
+
+// =====================================================================
+// Helper functions
+// =====================================================================
+
+inline void
+ReplaceExtension(std::string& dst_filename, const std::string& src_filename, const std::string& dst_extension) {
+	size_t lastDot = src_filename.find_last_of('.');
+	if (lastDot == std::string::npos) {
+		dst_filename = src_filename;
+		dst_filename += ".";
+		dst_filename += dst_extension;
+	}
+	else {
+		dst_filename = src_filename.substr(0, lastDot + 1);
+		dst_filename += dst_extension;
+	}
+}
+
+// =====================================================================
+// Internal Multipage functions
+// =====================================================================
+
+inline MULTIBITMAPHEADER *
+FreeImage_GetMultiBitmapHeader(FIMULTIBITMAP *bitmap) {
+	return (MULTIBITMAPHEADER *)bitmap->data;
+}
+
+static BlockListIterator DLL_CALLCONV
+FreeImage_FindBlock(FIMULTIBITMAP *bitmap, int position) {
+	assert(NULL != bitmap);
+
+	MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
+
+	// step 1: find the block that matches the given position
+
+	int prev_count = 0;
+	int count = 0;
+	BlockListIterator i;
+	BlockTypeS *current_block = NULL;
+
+	for (i = header->m_blocks.begin(); i != header->m_blocks.end(); ++i) {
+		prev_count = count;
+
+		switch((*i)->m_type) {
+			case BLOCK_CONTINUEUS :
+				count += ((BlockContinueus *)(*i))->m_end - ((BlockContinueus *)(*i))->m_start + 1;
+				break;
+
+			case BLOCK_REFERENCE :
+				count++;
+				break;
+		}
+
+		current_block = *i;
+
+		if (count > position)
+			break;
+	}
+
+	// step 2: make sure we found the node. from here it gets a little complicated:
+	// * if the block is there, just return it
+	// * if the block is a series of blocks, split it in max 3 new blocks
+	//   and return the splitted block
+
+	if ((current_block) && (count > position)) {
+		switch(current_block->m_type) {
+			case BLOCK_REFERENCE :
+				return i;
+
+			case BLOCK_CONTINUEUS :
+			{
+				BlockContinueus *block = (BlockContinueus *)current_block;
+
+				if (block->m_start != block->m_end) {
+					int item = block->m_start + (position - prev_count);
+
+					// left part
+
+					if (item != block->m_start) {
+						BlockContinueus *block_a = new BlockContinueus(block->m_start, item - 1);
+						header->m_blocks.insert(i, (BlockTypeS *)block_a);
+					}
+
+					// middle part
+
+					BlockContinueus *block_b = new BlockContinueus(item, item);
+					BlockListIterator block_target = header->m_blocks.insert(i, (BlockTypeS *)block_b);
+
+					// right part
+
+					if (item != block->m_end) {
+						BlockContinueus *block_c = new BlockContinueus(item + 1, block->m_end);
+						header->m_blocks.insert(i, (BlockTypeS *)block_c);
+					}
+
+					// remove the old block that was just splitted
+
+					header->m_blocks.remove((BlockTypeS *)block);
+					delete block;
+
+					// return the splitted block
+					
+					return block_target;
+				}
+
+				return i;
+			}
+		}
+	}
+	// we should never go here ...
+	assert(false);
+	return header->m_blocks.end();
+}
+
+int DLL_CALLCONV
+FreeImage_InternalGetPageCount(FIMULTIBITMAP *bitmap) {	
+	if (bitmap) {
+		if (((MULTIBITMAPHEADER *)bitmap->data)->handle) {
+			MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
+
+			header->io->seek_proc(header->handle, 0, SEEK_SET);
+
+   			void *data = FreeImage_Open(header->node, header->io, header->handle, TRUE);
+
+			int page_count = (header->node->m_plugin->pagecount_proc != NULL) ? header->node->m_plugin->pagecount_proc(header->io, header->handle, data) : 1;
+
+			FreeImage_Close(header->node, header->io, header->handle, data);
+
+			return page_count;
+		}
+	}
+
+	return 0;
+}
+
+// =====================================================================
+// Multipage functions
+// =====================================================================
+
+FIMULTIBITMAP * DLL_CALLCONV
+FreeImage_OpenMultiBitmap(FREE_IMAGE_FORMAT fif, const char *filename, BOOL create_new, BOOL read_only, BOOL keep_cache_in_memory, int flags) {
+
+	FILE *handle = NULL;
+	try {
+		// sanity check on the parameters
+
+		if (create_new) {
+			read_only = FALSE;
+		}
+
+		// retrieve the plugin list to find the node belonging to this plugin
+
+		PluginList *list = FreeImage_GetPluginList();
+
+		if (list) {
+			PluginNode *node = list->FindNodeFromFIF(fif);
+
+			if (node) {
+				std::auto_ptr<FreeImageIO> io (new FreeImageIO);
+
+				SetDefaultIO(io.get());
+
+				if (!create_new) {
+					handle = fopen(filename, "rb");
+					if (handle == NULL) {
+						return NULL;
+					}
+				}
+
+				std::auto_ptr<FIMULTIBITMAP> bitmap (new FIMULTIBITMAP);
+				std::auto_ptr<MULTIBITMAPHEADER> header (new MULTIBITMAPHEADER);
+				header->m_filename = new char[strlen(filename) + 1];
+				strcpy(header->m_filename, filename);
+				header->node = node;
+				header->fif = fif;
+				header->io = io.get ();
+				header->handle = handle;						
+				header->changed = FALSE;						
+				header->read_only = read_only;
+				header->m_cachefile = NULL;
+				header->cache_fif = fif;
+				header->load_flags = flags;
+
+				// store the MULTIBITMAPHEADER in the surrounding FIMULTIBITMAP structure
+
+				bitmap->data = header.get();
+
+				// cache the page count
+
+				header->page_count = FreeImage_InternalGetPageCount(bitmap.get());
+
+				// allocate a continueus block to describe the bitmap
+
+				if (!create_new) {
+					header->m_blocks.push_back((BlockTypeS *)new BlockContinueus(0, header->page_count - 1));
+				}
+
+				// set up the cache
+
+				if (!read_only) {
+					std::string cache_name;
+					ReplaceExtension(cache_name, filename, "ficache");
+
+					std::auto_ptr<CacheFile> cache_file (new CacheFile(cache_name, keep_cache_in_memory));
+
+					if (cache_file->open()) {
+						// we can use release() as std::bad_alloc won't be thrown from here on
+						header->m_cachefile = cache_file.release();
+					} else {
+						// an error occured ...
+						fclose(handle);
+						return NULL;
+					}
+				}
+				// return the multibitmap
+				// std::bad_alloc won't be thrown from here on
+				header.release(); // now owned by bitmap
+				io.release();	  // now owned by bitmap
+				return bitmap.release(); // now owned by caller
+			}
+		}
+	} catch (std::bad_alloc &) {
+		/** @todo report error */
+	}
+	if (handle)
+		fclose(handle);
+	return NULL;
+}
+
+FIMULTIBITMAP * DLL_CALLCONV
+FreeImage_OpenMultiBitmapFromHandle(FREE_IMAGE_FORMAT fif, FreeImageIO *io, fi_handle handle, int flags) {
+	try {
+		BOOL read_only = FALSE;	// modifications (if any) will be stored into the memory cache
+
+		if (io && handle) {
+		
+			// retrieve the plugin list to find the node belonging to this plugin
+			PluginList *list = FreeImage_GetPluginList();
+		
+			if (list) {
+				PluginNode *node = list->FindNodeFromFIF(fif);
+			
+				if (node) {
+					std::auto_ptr<FIMULTIBITMAP> bitmap (new FIMULTIBITMAP);
+					std::auto_ptr<MULTIBITMAPHEADER> header (new MULTIBITMAPHEADER);
+					std::auto_ptr<FreeImageIO> tmp_io (new FreeImageIO (*io));
+					header->io = tmp_io.get();
+					header->m_filename = NULL;
+					header->node = node;
+					header->fif = fif;
+					header->handle = handle;						
+					header->changed = FALSE;						
+					header->read_only = read_only;	
+					header->m_cachefile = NULL;
+					header->cache_fif = fif;
+					header->load_flags = flags;
+							
+					// store the MULTIBITMAPHEADER in the surrounding FIMULTIBITMAP structure
+
+					bitmap->data = header.get();
+
+					// cache the page count
+
+					header->page_count = FreeImage_InternalGetPageCount(bitmap.get());
+
+					// allocate a continueus block to describe the bitmap
+
+					header->m_blocks.push_back((BlockTypeS *)new BlockContinueus(0, header->page_count - 1));
+
+					if (!read_only) {
+						// set up the cache
+						std::auto_ptr<CacheFile> cache_file (new CacheFile("", TRUE));
+						
+						if (cache_file->open()) {
+							header->m_cachefile = cache_file.release();
+						}
+					}
+					tmp_io.release();
+					header.release();
+					return bitmap.release();
+				}
+			}
+		}
+	} catch (std::bad_alloc &) {
+		/** @todo report error */
+	}
+	return NULL;
+}
+
+BOOL DLL_CALLCONV
+FreeImage_SaveMultiBitmapToHandle(FREE_IMAGE_FORMAT fif, FIMULTIBITMAP *bitmap, FreeImageIO *io, fi_handle handle, int flags) {
+	if(!bitmap || !bitmap->data || !io || !handle) {
+		return FALSE;
+	}
+
+	BOOL success = TRUE;
+
+	// retrieve the plugin list to find the node belonging to this plugin
+	PluginList *list = FreeImage_GetPluginList();
+	
+	if (list) {
+		PluginNode *node = list->FindNodeFromFIF(fif);
+
+		if(node) {
+			MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
+			
+			// dst data
+			void *data = FreeImage_Open(node, io, handle, FALSE);
+			// src data
+			void *data_read = NULL;
+			
+			if(header->handle) {
+				// open src
+				header->io->seek_proc(header->handle, 0, SEEK_SET);
+				data_read = FreeImage_Open(header->node, header->io, header->handle, TRUE);
+			}
+			
+			// write all the pages to the file using handle and io
+			
+			int count = 0;
+			
+			for (BlockListIterator i = header->m_blocks.begin(); i != header->m_blocks.end(); i++) {
+				if (success) {
+					switch((*i)->m_type) {
+						case BLOCK_CONTINUEUS:
+						{
+							BlockContinueus *block = (BlockContinueus *)(*i);
+							
+							for (int j = block->m_start; j <= block->m_end; j++) {
+
+								// load the original source data
+								FIBITMAP *dib = header->node->m_plugin->load_proc(header->io, header->handle, j, header->load_flags, data_read);
+								
+								// save the data
+								success = node->m_plugin->save_proc(io, dib, handle, count, flags, data);
+								count++;
+								
+								FreeImage_Unload(dib);
+							}
+							
+							break;
+						}
+						
+						case BLOCK_REFERENCE:
+						{
+							BlockReference *ref = (BlockReference *)(*i);
+							
+							// read the compressed data
+							
+							BYTE *compressed_data = (BYTE*)malloc(ref->m_size * sizeof(BYTE));
+							
+							header->m_cachefile->readFile((BYTE *)compressed_data, ref->m_reference, ref->m_size);
+							
+							// uncompress the data
+							
+							FIMEMORY *hmem = FreeImage_OpenMemory(compressed_data, ref->m_size);
+							FIBITMAP *dib = FreeImage_LoadFromMemory(header->cache_fif, hmem, 0);
+							FreeImage_CloseMemory(hmem);
+							
+							// get rid of the buffer
+							free(compressed_data);
+							
+							// save the data
+							
+							success = node->m_plugin->save_proc(io, dib, handle, count, flags, data);
+							count++;
+							
+							// unload the dib
+
+							FreeImage_Unload(dib);
+
+							break;
+						}
+					}
+				} else {
+					break;
+				}
+			}
+			
+			// close the files
+			
+			FreeImage_Close(header->node, header->io, header->handle, data_read);
+
+			FreeImage_Close(node, io, handle, data); 
+			
+			return success;
+		}
+	}
+
+	return FALSE;
+}
+
+
+BOOL DLL_CALLCONV
+FreeImage_CloseMultiBitmap(FIMULTIBITMAP *bitmap, int flags) {
+	if (bitmap) {
+		BOOL success = TRUE;
+		
+		if (bitmap->data) {
+			MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);			
+			
+			// saves changes only of images loaded directly from a file
+			if (header->changed && header->m_filename) {
+				try {
+					// open a temp file
+
+					std::string spool_name;
+
+					ReplaceExtension(spool_name, header->m_filename, "fispool");
+
+					// open the spool file and the source file
+        
+					FILE *f = fopen(spool_name.c_str(), "w+b");
+				
+					// saves changes
+					if (f == NULL) {
+						FreeImage_OutputMessageProc(header->fif, "Failed to open %s, %s", spool_name.c_str(), strerror(errno));
+						success = FALSE;
+					} else {
+						success = FreeImage_SaveMultiBitmapToHandle(header->fif, bitmap, header->io, (fi_handle)f, flags);
+
+						// close the files
+
+						if (fclose(f) != 0) {
+							success = FALSE;
+							FreeImage_OutputMessageProc(header->fif, "Failed to close %s, %s", spool_name.c_str(), strerror(errno));
+						}
+					}
+					if (header->handle) {
+						fclose((FILE *)header->handle);
+					}
+				
+					// applies changes to the destination file
+
+					if (success) {
+						remove(header->m_filename);
+						success = (rename(spool_name.c_str(), header->m_filename) == 0) ? TRUE:FALSE;
+						if(!success) {
+							FreeImage_OutputMessageProc(header->fif, "Failed to rename %s to %s", spool_name.c_str(), header->m_filename);
+						}
+					} else {
+						remove(spool_name.c_str());
+					}
+				} catch (std::bad_alloc &) {
+					success = FALSE;
+				}
+
+			} else {
+				if (header->handle && header->m_filename) {
+					fclose((FILE *)header->handle);
+				}
+			}
+
+			// clear the blocks list
+
+			for (BlockListIterator i = header->m_blocks.begin(); i != header->m_blocks.end(); ++i) {
+				delete *i;
+			}
+
+			// flush and dispose the cache
+
+			if (header->m_cachefile) {
+				header->m_cachefile->close();
+				delete header->m_cachefile;
+			}
+
+			// delete the last open bitmaps
+
+			while (!header->locked_pages.empty()) {
+				FreeImage_Unload(header->locked_pages.begin()->first);
+
+				header->locked_pages.erase(header->locked_pages.begin()->first);
+			}
+
+			// get rid of the IO structure
+
+			delete header->io;
+
+			// delete the filename
+
+			if(header->m_filename) {
+				delete[] header->m_filename;
+			}
+
+			// delete the FIMULTIBITMAPHEADER
+
+			delete header;
+		}
+
+		delete bitmap;
+
+		return success;
+	}
+
+	return FALSE;
+}
+
+int DLL_CALLCONV
+FreeImage_GetPageCount(FIMULTIBITMAP *bitmap) {
+	if (bitmap) {
+		MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
+
+		if (header->page_count == -1) {
+			header->page_count = 0;
+
+			for (BlockListIterator i = header->m_blocks.begin(); i != header->m_blocks.end(); ++i) {
+				switch((*i)->m_type) {
+					case BLOCK_CONTINUEUS :
+						header->page_count += ((BlockContinueus *)(*i))->m_end - ((BlockContinueus *)(*i))->m_start + 1;
+						break;
+
+					case BLOCK_REFERENCE :
+						header->page_count++;
+						break;
+				}
+			}
+		}
+
+		return header->page_count;
+	}
+
+	return 0;
+}
+
+static BlockReference* 
+FreeImage_SavePageToBlock(MULTIBITMAPHEADER *header, FIBITMAP *data) {
+	if (header->read_only || !header->locked_pages.empty())
+		return NULL;
+
+	DWORD compressed_size = 0;
+	BYTE *compressed_data = NULL;
+
+	// compress the bitmap data
+
+	// open a memory handle
+	FIMEMORY *hmem = FreeImage_OpenMemory();
+	if(hmem==NULL) return NULL;
+	// save the file to memory
+	if(!FreeImage_SaveToMemory(header->cache_fif, data, hmem, 0)) {
+		FreeImage_CloseMemory(hmem);
+		return NULL;
+	}
+	// get the buffer from the memory stream
+	if(!FreeImage_AcquireMemory(hmem, &compressed_data, &compressed_size)) {
+		FreeImage_CloseMemory(hmem);
+		return NULL;
+	}
+
+	// write the compressed data to the cache
+	int ref = header->m_cachefile->writeFile(compressed_data, compressed_size);
+	// get rid of the compressed data
+	FreeImage_CloseMemory(hmem);
+
+	return new(std::nothrow) BlockReference(ref, compressed_size);
+}
+
+void DLL_CALLCONV
+FreeImage_AppendPage(FIMULTIBITMAP *bitmap, FIBITMAP *data) {
+	if (!bitmap || !data) 
+		return;
+
+	MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
+
+	BlockReference *block = FreeImage_SavePageToBlock(header, data);
+	if(block==NULL) return;
+
+	// add the block
+	header->m_blocks.push_back((BlockTypeS *)block);
+	header->changed = TRUE;
+	header->page_count = -1;
+}
+
+void DLL_CALLCONV
+FreeImage_InsertPage(FIMULTIBITMAP *bitmap, int page, FIBITMAP *data) {
+	if (!bitmap || !data) 
+		return;
+
+	if (page >= FreeImage_GetPageCount(bitmap)) 
+		return;
+			
+	MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
+
+	BlockReference *block = FreeImage_SavePageToBlock(header, data);
+	if(block==NULL) return;
+
+	// add a block
+	if (page > 0) {
+		BlockListIterator block_source = FreeImage_FindBlock(bitmap, page);		
+
+		header->m_blocks.insert(block_source, (BlockTypeS *)block);
+	} else {
+		header->m_blocks.push_front((BlockTypeS *)block);
+	}
+
+	header->changed = TRUE;
+	header->page_count = -1;
+}
+
+void DLL_CALLCONV
+FreeImage_DeletePage(FIMULTIBITMAP *bitmap, int page) {
+	if (bitmap) {
+		MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
+
+		if ((!header->read_only) && (header->locked_pages.empty())) {
+			if (FreeImage_GetPageCount(bitmap) > 1) {
+				BlockListIterator i = FreeImage_FindBlock(bitmap, page);
+
+				if (i != header->m_blocks.end()) {
+					switch((*i)->m_type) {
+						case BLOCK_CONTINUEUS :
+							delete *i;
+							header->m_blocks.erase(i);
+							break;
+
+						case BLOCK_REFERENCE :
+							header->m_cachefile->deleteFile(((BlockReference *)(*i))->m_reference);
+							delete *i;
+							header->m_blocks.erase(i);
+							break;
+					}
+
+					header->changed = TRUE;
+					header->page_count = -1;
+				}
+			}
+		}
+	}
+}
+
+
+FIBITMAP * DLL_CALLCONV
+FreeImage_LockPage(FIMULTIBITMAP *bitmap, int page) {
+	if (bitmap) {
+		MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
+
+		// only lock if the page wasn't locked before...
+
+		for (std::map<FIBITMAP *, int>::iterator i = header->locked_pages.begin(); i != header->locked_pages.end(); ++i) {
+			if (i->second == page) {
+				return NULL;
+			}
+		}
+
+		// open the bitmap
+
+		header->io->seek_proc(header->handle, 0, SEEK_SET);
+
+   		void *data = FreeImage_Open(header->node, header->io, header->handle, TRUE);
+
+		// load the bitmap data
+
+		if (data != NULL) {
+			FIBITMAP *dib = (header->node->m_plugin->load_proc != NULL) ? header->node->m_plugin->load_proc(header->io, header->handle, page, header->load_flags, data) : NULL;
+
+			// close the file
+
+			FreeImage_Close(header->node, header->io, header->handle, data);
+
+			// if there was still another bitmap open, get rid of it
+
+			if (dib) {
+				header->locked_pages[dib] = page;
+
+				return dib;
+			}	
+
+			return NULL;
+		}
+	}
+
+	return NULL;
+}
+
+void DLL_CALLCONV
+FreeImage_UnlockPage(FIMULTIBITMAP *bitmap, FIBITMAP *page, BOOL changed) {
+	if ((bitmap) && (page)) {
+		MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
+
+		// find out if the page we try to unlock is actually locked...
+
+		if (header->locked_pages.find(page) != header->locked_pages.end()) {
+			// store the bitmap compressed in the cache for later writing
+
+			if (changed && !header->read_only) {
+				header->changed = TRUE;
+
+				// cut loose the block from the rest
+
+				BlockListIterator i = FreeImage_FindBlock(bitmap, header->locked_pages[page]);
+
+				// compress the data
+
+				DWORD compressed_size = 0;
+				BYTE *compressed_data = NULL;
+
+				// open a memory handle
+				FIMEMORY *hmem = FreeImage_OpenMemory();
+				// save the page to memory
+				FreeImage_SaveToMemory(header->cache_fif, page, hmem, 0);
+				// get the buffer from the memory stream
+				FreeImage_AcquireMemory(hmem, &compressed_data, &compressed_size);
+
+				// write the data to the cache
+
+				switch ((*i)->m_type) {
+					case BLOCK_CONTINUEUS :
+					{
+						int iPage = header->m_cachefile->writeFile(compressed_data, compressed_size);
+
+						delete (*i);
+
+						*i = (BlockTypeS *)new BlockReference(iPage, compressed_size);
+
+						break;
+					}
+
+					case BLOCK_REFERENCE :
+					{
+						BlockReference *reference = (BlockReference *)(*i);
+
+						header->m_cachefile->deleteFile(reference->m_reference);
+
+						delete (*i);
+
+						int iPage = header->m_cachefile->writeFile(compressed_data, compressed_size);
+
+						*i = (BlockTypeS *)new BlockReference(iPage, compressed_size);
+
+						break;
+					}
+				}
+
+				// get rid of the compressed data
+
+				FreeImage_CloseMemory(hmem);
+			}
+
+			// reset the locked page so that another page can be locked
+
+			FreeImage_Unload(page);
+
+			header->locked_pages.erase(page);
+		}
+	}
+}
+
+BOOL DLL_CALLCONV
+FreeImage_MovePage(FIMULTIBITMAP *bitmap, int target, int source) {
+	if (bitmap) {
+		MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
+
+		if ((!header->read_only) && (header->locked_pages.empty())) {
+			if ((target != source) && ((target >= 0) && (target < FreeImage_GetPageCount(bitmap))) && ((source >= 0) && (source < FreeImage_GetPageCount(bitmap)))) {
+				BlockListIterator block_source = FreeImage_FindBlock(bitmap, target);
+				BlockListIterator block_target = FreeImage_FindBlock(bitmap, source);
+
+				header->m_blocks.insert(block_target, *block_source);			
+				header->m_blocks.erase(block_source);
+
+				header->changed = TRUE;
+
+				return TRUE;
+			}
+		}
+	}
+
+	return FALSE;
+}
+
+BOOL DLL_CALLCONV
+FreeImage_GetLockedPageNumbers(FIMULTIBITMAP *bitmap, int *pages, int *count) {
+	if ((bitmap) && (count)) {
+		MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
+
+		if ((pages == NULL) || (*count == 0)) {
+			*count = (int)header->locked_pages.size();
+		} else {
+			int c = 0;
+
+			for (std::map<FIBITMAP *, int>::iterator i = header->locked_pages.begin(); i != header->locked_pages.end(); ++i) {
+				pages[c] = i->second;
+
+				c++;
+
+				if (c == *count)
+					break;
+			}
+		}
+
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+// =====================================================================
+// Memory IO Multipage functions
+// =====================================================================
+
+FIMULTIBITMAP * DLL_CALLCONV
+FreeImage_LoadMultiBitmapFromMemory(FREE_IMAGE_FORMAT fif, FIMEMORY *stream, int flags) {
+	BOOL read_only = FALSE;	// modifications (if any) will be stored into the memory cache
+
+	// retrieve the plugin list to find the node belonging to this plugin
+
+	PluginList *list = FreeImage_GetPluginList();
+
+	if (list) {
+		PluginNode *node = list->FindNodeFromFIF(fif);
+
+		if (node) {
+			FreeImageIO *io = new(std::nothrow) FreeImageIO;
+
+			if (io) {
+				SetMemoryIO(io);
+
+				FIMULTIBITMAP *bitmap = new(std::nothrow) FIMULTIBITMAP;
+
+				if (bitmap) {
+					MULTIBITMAPHEADER *header = new(std::nothrow) MULTIBITMAPHEADER;
+
+					if (header) {
+						header->m_filename = NULL;
+						header->node = node;
+						header->fif = fif;
+						header->io = io;
+						header->handle = (fi_handle)stream;						
+						header->changed = FALSE;						
+						header->read_only = read_only;
+						header->m_cachefile = NULL;
+						header->cache_fif = fif;
+						header->load_flags = flags;
+
+						// store the MULTIBITMAPHEADER in the surrounding FIMULTIBITMAP structure
+
+						bitmap->data = header;
+
+						// cache the page count
+
+						header->page_count = FreeImage_InternalGetPageCount(bitmap);
+
+						// allocate a continueus block to describe the bitmap
+
+						header->m_blocks.push_back((BlockTypeS *)new BlockContinueus(0, header->page_count - 1));
+						
+						if (!read_only) {
+							// set up the cache
+							CacheFile *cache_file = new(std::nothrow) CacheFile("", TRUE);
+							
+							if (cache_file && cache_file->open()) {
+								header->m_cachefile = cache_file;
+							}
+						}
+
+						return bitmap;
+					}
+					
+					delete bitmap;
+				}
+				
+				delete io;
+			}
+		}
+	}
+
+	return NULL;
+}
+
+BOOL DLL_CALLCONV
+FreeImage_SaveMultiBitmapToMemory(FREE_IMAGE_FORMAT fif, FIMULTIBITMAP *bitmap, FIMEMORY *stream, int flags) {
+	if (stream && stream->data) {
+		FreeImageIO io;
+		SetMemoryIO(&io);
+
+		return FreeImage_SaveMultiBitmapToHandle(fif, bitmap, &io, (fi_handle)stream, flags);
+	}
+
+	return FALSE;
+}
diff --git a/Source/FreeImage/PSDParser.cpp b/Source/FreeImage/PSDParser.cpp
index 57c703a..fba54c2 100644
--- a/Source/FreeImage/PSDParser.cpp
+++ b/Source/FreeImage/PSDParser.cpp
@@ -506,6 +506,10 @@ bool psdParser::ReadImageResources(FreeImageIO *io, fi_handle handle, LONG lengt
 		oResource.Reset();
 		
 		n = (int)io->read_proc(&oResource._OSType, sizeof(oResource._OSType), 1, handle);
+		if(n != 1) {
+			FreeImage_OutputMessageProc(_fi_format_id, "This file contains damaged data causing an unexpected end-of-file - stop reading resources");
+			return false;
+		}
 		nBytes += n * sizeof(oResource._OSType);
 
 		if( (nBytes % 2) != 0 ) {
diff --git a/Source/FreeImage/PixelAccess.cpp b/Source/FreeImage/PixelAccess.cpp
index e3dccfe..b5714b2 100644
--- a/Source/FreeImage/PixelAccess.cpp
+++ b/Source/FreeImage/PixelAccess.cpp
@@ -1,210 +1,197 @@
-// ==========================================================
-// Pixel access functions
-//
-// Design and implementation by
-// - Floris van den Berg (flvdberg at wxs.nl)
-// - Herv� Drolon (drolon at infonie.fr)
-// - Ryan Rubley (ryan at lostreality.org)
-// - Riley McNiff (rmcniff at marexgroup.com)
-//
-// This file is part of FreeImage 3
-//
-// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
-// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
-// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
-// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
-// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
-// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
-// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
-// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
-// THIS DISCLAIMER.
-//
-// Use at your own risk!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-
-// ----------------------------------------------------------
-
-BYTE * DLL_CALLCONV
-FreeImage_GetBits(FIBITMAP *dib) {
-	if(!FreeImage_HasPixels(dib)) {
-		return NULL;
-	}
-	// returns the pixels aligned on a FIBITMAP_ALIGNMENT bytes alignment boundary
-	size_t lp = (size_t)FreeImage_GetInfoHeader(dib);
-	lp += sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * FreeImage_GetColorsUsed(dib);
-	lp += FreeImage_HasRGBMasks(dib) ? sizeof(DWORD) * 3 : 0;
-	lp += (lp % FIBITMAP_ALIGNMENT ? FIBITMAP_ALIGNMENT - lp % FIBITMAP_ALIGNMENT : 0);
-	return (BYTE *)lp;
-}
-
-BYTE * DLL_CALLCONV
-FreeImage_GetScanLine(FIBITMAP *dib, int scanline) {
-	if(!FreeImage_HasPixels(dib)) {
-		return NULL;
-	}
-	return CalculateScanLine(FreeImage_GetBits(dib), FreeImage_GetPitch(dib), scanline);
-}
-
-BOOL DLL_CALLCONV
-FreeImage_GetPixelIndex(FIBITMAP *dib, unsigned x, unsigned y, BYTE *value) {
-	BYTE shift;
-
-	if(!FreeImage_HasPixels(dib) || (FreeImage_GetImageType(dib) != FIT_BITMAP))
-		return FALSE;
-
-	if((x < FreeImage_GetWidth(dib)) && (y < FreeImage_GetHeight(dib))) {
-		BYTE *bits = FreeImage_GetScanLine(dib, y);
-
-		switch(FreeImage_GetBPP(dib)) {
-			case 1:
-				*value = (bits[x >> 3] & (0x80 >> (x & 0x07))) != 0;
-				break;
-			case 4:
-				shift = (BYTE)((1 - x % 2) << 2);
-				*value = (bits[x >> 1] & (0x0F << shift)) >> shift;
-				break;
-			case 8:
-				*value = bits[x];
-				break;
-			default:
-				return FALSE;
-		}
-
-		return TRUE;
-	}
-
-	return FALSE;
-}
-
-BOOL DLL_CALLCONV
-FreeImage_GetPixelColor(FIBITMAP *dib, unsigned x, unsigned y, RGBQUAD *value) {
-	if(!FreeImage_HasPixels(dib) || (FreeImage_GetImageType(dib) != FIT_BITMAP))
-		return FALSE;
-
-	if((x < FreeImage_GetWidth(dib)) && (y < FreeImage_GetHeight(dib))) {
-		BYTE *bits = FreeImage_GetScanLine(dib, y);
-
-		switch(FreeImage_GetBPP(dib)) {
-			case 16:
-			{
-				bits += 2*x;
-				WORD *pixel = (WORD *)bits;
-				if((FreeImage_GetRedMask(dib) == FI16_565_RED_MASK) && (FreeImage_GetGreenMask(dib) == FI16_565_GREEN_MASK) && (FreeImage_GetBlueMask(dib) == FI16_565_BLUE_MASK)) {
-					value->rgbBlue		= (BYTE)((((*pixel & FI16_565_BLUE_MASK) >> FI16_565_BLUE_SHIFT) * 0xFF) / 0x1F);
-					value->rgbGreen		= (BYTE)((((*pixel & FI16_565_GREEN_MASK) >> FI16_565_GREEN_SHIFT) * 0xFF) / 0x3F);
-					value->rgbRed		= (BYTE)((((*pixel & FI16_565_RED_MASK) >> FI16_565_RED_SHIFT) * 0xFF) / 0x1F);
-					value->rgbReserved	= 0;
-				} else {
-					value->rgbBlue		= (BYTE)((((*pixel & FI16_555_BLUE_MASK) >> FI16_555_BLUE_SHIFT) * 0xFF) / 0x1F);
-					value->rgbGreen		= (BYTE)((((*pixel & FI16_555_GREEN_MASK) >> FI16_555_GREEN_SHIFT) * 0xFF) / 0x1F);
-					value->rgbRed		= (BYTE)((((*pixel & FI16_555_RED_MASK) >> FI16_555_RED_SHIFT) * 0xFF) / 0x1F);
-					value->rgbReserved	= 0;
-				}
-				break;
-			}
-			case 24:
-				bits += 3*x;
-				value->rgbBlue		= bits[FI_RGBA_BLUE];	// B
-				value->rgbGreen		= bits[FI_RGBA_GREEN];	// G
-				value->rgbRed		= bits[FI_RGBA_RED];	// R
-				value->rgbReserved	= 0;
-				break;
-			case 32:
-				bits += 4*x;
-				value->rgbBlue		= bits[FI_RGBA_BLUE];	// B
-				value->rgbGreen		= bits[FI_RGBA_GREEN];	// G
-				value->rgbRed		= bits[FI_RGBA_RED];	// R
-				value->rgbReserved	= bits[FI_RGBA_ALPHA];	// A
-				break;
-			default:
-				return FALSE;
-		}
-
-		return TRUE;
-	}
-
-	return FALSE;
-}
-
-BOOL DLL_CALLCONV
-FreeImage_SetPixelIndex(FIBITMAP *dib, unsigned x, unsigned y, BYTE *value) {
-	BYTE shift;
-
-	if(!FreeImage_HasPixels(dib) || (FreeImage_GetImageType(dib) != FIT_BITMAP))
-		return FALSE;
-
-	if((x < FreeImage_GetWidth(dib)) && (y < FreeImage_GetHeight(dib))) {
-		BYTE *bits = FreeImage_GetScanLine(dib, y);
-
-		switch(FreeImage_GetBPP(dib)) {
-			case 1:
-				*value ? bits[x >> 3] |= (0x80 >> (x & 0x7)) : bits[x >> 3] &= (0xFF7F >> (x & 0x7));
-				break;
-			case 4:
-				shift = (BYTE)((1 - x % 2) << 2);
-				bits[x >> 1] &= ~(0x0F << shift);
-				bits[x >> 1] |= ((*value & 0x0F) << shift);
-				break;
-			case 8:
-				bits[x] = *value;
-				break;
-			default:
-				return FALSE;
-		}
-
-		return TRUE;
-	}
-
-	return FALSE;
-}
-
-BOOL DLL_CALLCONV
-FreeImage_SetPixelColor(FIBITMAP *dib, unsigned x, unsigned y, RGBQUAD *value) {
-	if(!FreeImage_HasPixels(dib) || (FreeImage_GetImageType(dib) != FIT_BITMAP))
-		return FALSE;
-
-	if((x < FreeImage_GetWidth(dib)) && (y < FreeImage_GetHeight(dib))) {
-		BYTE *bits = FreeImage_GetScanLine(dib, y);
-
-		switch(FreeImage_GetBPP(dib)) {
-			case 16:
-			{
-				bits += 2*x;
-				WORD *pixel = (WORD *)bits;
-				if((FreeImage_GetRedMask(dib) == FI16_565_RED_MASK) && (FreeImage_GetGreenMask(dib) == FI16_565_GREEN_MASK) && (FreeImage_GetBlueMask(dib) == FI16_565_BLUE_MASK)) {
-					*pixel = ((value->rgbBlue >> 3) << FI16_565_BLUE_SHIFT) |
-						((value->rgbGreen >> 2) << FI16_565_GREEN_SHIFT) |
-						((value->rgbRed >> 3) << FI16_565_RED_SHIFT);
-				} else {
-					*pixel = ((value->rgbBlue >> 3) << FI16_555_BLUE_SHIFT) |
-						((value->rgbGreen >> 3) << FI16_555_GREEN_SHIFT) |
-						((value->rgbRed >> 3) << FI16_555_RED_SHIFT);
-				}
-				break;
-			}
-			case 24:
-				bits += 3*x;
-				bits[FI_RGBA_BLUE]	= value->rgbBlue;	// B
-				bits[FI_RGBA_GREEN] = value->rgbGreen;	// G
-				bits[FI_RGBA_RED]	= value->rgbRed;	// R
-				break;
-			case 32:
-				bits += 4*x;
-				bits[FI_RGBA_BLUE]	= value->rgbBlue;		// B
-				bits[FI_RGBA_GREEN] = value->rgbGreen;		// G
-				bits[FI_RGBA_RED]	= value->rgbRed;		// R
-				bits[FI_RGBA_ALPHA] = value->rgbReserved;	// A
-				break;
-			default:
-				return FALSE;
-		}
-
-		return TRUE;
-	}
-
-	return FALSE;
-}
-
+// ==========================================================
+// Pixel access functions
+//
+// Design and implementation by
+// - Floris van den Berg (flvdberg at wxs.nl)
+// - Herv� Drolon (drolon at infonie.fr)
+// - Ryan Rubley (ryan at lostreality.org)
+// - Riley McNiff (rmcniff at marexgroup.com)
+//
+// This file is part of FreeImage 3
+//
+// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
+// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
+// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
+// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
+// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
+// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
+// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+// THIS DISCLAIMER.
+//
+// Use at your own risk!
+// ==========================================================
+
+#include "FreeImage.h"
+#include "Utilities.h"
+
+// ----------------------------------------------------------
+
+BYTE * DLL_CALLCONV
+FreeImage_GetScanLine(FIBITMAP *dib, int scanline) {
+	if(!FreeImage_HasPixels(dib)) {
+		return NULL;
+	}
+	return CalculateScanLine(FreeImage_GetBits(dib), FreeImage_GetPitch(dib), scanline);
+}
+
+BOOL DLL_CALLCONV
+FreeImage_GetPixelIndex(FIBITMAP *dib, unsigned x, unsigned y, BYTE *value) {
+	BYTE shift;
+
+	if(!FreeImage_HasPixels(dib) || (FreeImage_GetImageType(dib) != FIT_BITMAP))
+		return FALSE;
+
+	if((x < FreeImage_GetWidth(dib)) && (y < FreeImage_GetHeight(dib))) {
+		BYTE *bits = FreeImage_GetScanLine(dib, y);
+
+		switch(FreeImage_GetBPP(dib)) {
+			case 1:
+				*value = (bits[x >> 3] & (0x80 >> (x & 0x07))) != 0;
+				break;
+			case 4:
+				shift = (BYTE)((1 - x % 2) << 2);
+				*value = (bits[x >> 1] & (0x0F << shift)) >> shift;
+				break;
+			case 8:
+				*value = bits[x];
+				break;
+			default:
+				return FALSE;
+		}
+
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+BOOL DLL_CALLCONV
+FreeImage_GetPixelColor(FIBITMAP *dib, unsigned x, unsigned y, RGBQUAD *value) {
+	if(!FreeImage_HasPixels(dib) || (FreeImage_GetImageType(dib) != FIT_BITMAP))
+		return FALSE;
+
+	if((x < FreeImage_GetWidth(dib)) && (y < FreeImage_GetHeight(dib))) {
+		BYTE *bits = FreeImage_GetScanLine(dib, y);
+
+		switch(FreeImage_GetBPP(dib)) {
+			case 16:
+			{
+				bits += 2*x;
+				WORD *pixel = (WORD *)bits;
+				if((FreeImage_GetRedMask(dib) == FI16_565_RED_MASK) && (FreeImage_GetGreenMask(dib) == FI16_565_GREEN_MASK) && (FreeImage_GetBlueMask(dib) == FI16_565_BLUE_MASK)) {
+					value->rgbBlue		= (BYTE)((((*pixel & FI16_565_BLUE_MASK) >> FI16_565_BLUE_SHIFT) * 0xFF) / 0x1F);
+					value->rgbGreen		= (BYTE)((((*pixel & FI16_565_GREEN_MASK) >> FI16_565_GREEN_SHIFT) * 0xFF) / 0x3F);
+					value->rgbRed		= (BYTE)((((*pixel & FI16_565_RED_MASK) >> FI16_565_RED_SHIFT) * 0xFF) / 0x1F);
+					value->rgbReserved	= 0;
+				} else {
+					value->rgbBlue		= (BYTE)((((*pixel & FI16_555_BLUE_MASK) >> FI16_555_BLUE_SHIFT) * 0xFF) / 0x1F);
+					value->rgbGreen		= (BYTE)((((*pixel & FI16_555_GREEN_MASK) >> FI16_555_GREEN_SHIFT) * 0xFF) / 0x1F);
+					value->rgbRed		= (BYTE)((((*pixel & FI16_555_RED_MASK) >> FI16_555_RED_SHIFT) * 0xFF) / 0x1F);
+					value->rgbReserved	= 0;
+				}
+				break;
+			}
+			case 24:
+				bits += 3*x;
+				value->rgbBlue		= bits[FI_RGBA_BLUE];	// B
+				value->rgbGreen		= bits[FI_RGBA_GREEN];	// G
+				value->rgbRed		= bits[FI_RGBA_RED];	// R
+				value->rgbReserved	= 0;
+				break;
+			case 32:
+				bits += 4*x;
+				value->rgbBlue		= bits[FI_RGBA_BLUE];	// B
+				value->rgbGreen		= bits[FI_RGBA_GREEN];	// G
+				value->rgbRed		= bits[FI_RGBA_RED];	// R
+				value->rgbReserved	= bits[FI_RGBA_ALPHA];	// A
+				break;
+			default:
+				return FALSE;
+		}
+
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+BOOL DLL_CALLCONV
+FreeImage_SetPixelIndex(FIBITMAP *dib, unsigned x, unsigned y, BYTE *value) {
+	BYTE shift;
+
+	if(!FreeImage_HasPixels(dib) || (FreeImage_GetImageType(dib) != FIT_BITMAP))
+		return FALSE;
+
+	if((x < FreeImage_GetWidth(dib)) && (y < FreeImage_GetHeight(dib))) {
+		BYTE *bits = FreeImage_GetScanLine(dib, y);
+
+		switch(FreeImage_GetBPP(dib)) {
+			case 1:
+				*value ? bits[x >> 3] |= (0x80 >> (x & 0x7)) : bits[x >> 3] &= (0xFF7F >> (x & 0x7));
+				break;
+			case 4:
+				shift = (BYTE)((1 - x % 2) << 2);
+				bits[x >> 1] &= ~(0x0F << shift);
+				bits[x >> 1] |= ((*value & 0x0F) << shift);
+				break;
+			case 8:
+				bits[x] = *value;
+				break;
+			default:
+				return FALSE;
+		}
+
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+BOOL DLL_CALLCONV
+FreeImage_SetPixelColor(FIBITMAP *dib, unsigned x, unsigned y, RGBQUAD *value) {
+	if(!FreeImage_HasPixels(dib) || (FreeImage_GetImageType(dib) != FIT_BITMAP))
+		return FALSE;
+
+	if((x < FreeImage_GetWidth(dib)) && (y < FreeImage_GetHeight(dib))) {
+		BYTE *bits = FreeImage_GetScanLine(dib, y);
+
+		switch(FreeImage_GetBPP(dib)) {
+			case 16:
+			{
+				bits += 2*x;
+				WORD *pixel = (WORD *)bits;
+				if((FreeImage_GetRedMask(dib) == FI16_565_RED_MASK) && (FreeImage_GetGreenMask(dib) == FI16_565_GREEN_MASK) && (FreeImage_GetBlueMask(dib) == FI16_565_BLUE_MASK)) {
+					*pixel = ((value->rgbBlue >> 3) << FI16_565_BLUE_SHIFT) |
+						((value->rgbGreen >> 2) << FI16_565_GREEN_SHIFT) |
+						((value->rgbRed >> 3) << FI16_565_RED_SHIFT);
+				} else {
+					*pixel = ((value->rgbBlue >> 3) << FI16_555_BLUE_SHIFT) |
+						((value->rgbGreen >> 3) << FI16_555_GREEN_SHIFT) |
+						((value->rgbRed >> 3) << FI16_555_RED_SHIFT);
+				}
+				break;
+			}
+			case 24:
+				bits += 3*x;
+				bits[FI_RGBA_BLUE]	= value->rgbBlue;	// B
+				bits[FI_RGBA_GREEN] = value->rgbGreen;	// G
+				bits[FI_RGBA_RED]	= value->rgbRed;	// R
+				break;
+			case 32:
+				bits += 4*x;
+				bits[FI_RGBA_BLUE]	= value->rgbBlue;		// B
+				bits[FI_RGBA_GREEN] = value->rgbGreen;		// G
+				bits[FI_RGBA_RED]	= value->rgbRed;		// R
+				bits[FI_RGBA_ALPHA] = value->rgbReserved;	// A
+				break;
+			default:
+				return FALSE;
+		}
+
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
diff --git a/Source/FreeImage/Plugin.cpp b/Source/FreeImage/Plugin.cpp
index d688f1a..57ebffd 100644
--- a/Source/FreeImage/Plugin.cpp
+++ b/Source/FreeImage/Plugin.cpp
@@ -219,6 +219,11 @@ void DLL_CALLCONV
 FreeImage_Initialise(BOOL load_local_plugins_only) {
 	if (s_plugin_reference_count++ == 0) {
 		
+		/*
+		Note: initialize all singletons here 
+		in order to avoid race conditions with multi-threading
+		*/
+
 		// initialise the TagLib singleton
 		TagLib& s = TagLib::instance();
 
@@ -266,6 +271,10 @@ FreeImage_Initialise(BOOL load_local_plugins_only) {
 			s_plugins->AddNode(InitPFM);
 			s_plugins->AddNode(InitPICT);
 			s_plugins->AddNode(InitRAW);
+			s_plugins->AddNode(InitWEBP);
+#if !(defined(_MSC_VER) && (_MSC_VER <= 1310))
+			s_plugins->AddNode(InitJXR);
+#endif // unsupported by MS Visual Studio 2003 !!!
 			
 			// external plugin initialization
 
@@ -273,19 +282,19 @@ FreeImage_Initialise(BOOL load_local_plugins_only) {
 			if (!load_local_plugins_only) {
 				int count = 0;
 				char buffer[MAX_PATH + 200];
-				char current_dir[2 * _MAX_PATH], module[2 * _MAX_PATH];
+				wchar_t current_dir[2 * _MAX_PATH], module[2 * _MAX_PATH];
 				BOOL bOk = FALSE;
 
 				// store the current directory. then set the directory to the application location
 
-				if (GetCurrentDirectory(2 * _MAX_PATH, current_dir) != 0) {
-					if (GetModuleFileName(NULL, module, 2 * _MAX_PATH) != 0) {
-						char *last_point = strrchr(module, '\\');
+				if (GetCurrentDirectoryW(2 * _MAX_PATH, current_dir) != 0) {
+					if (GetModuleFileNameW(NULL, module, 2 * _MAX_PATH) != 0) {
+						wchar_t *last_point = wcsrchr(module, L'\\');
 
 						if (last_point) {
-							*last_point = '\0';
+							*last_point = L'\0';
 
-							bOk = SetCurrentDirectory(module);
+							bOk = SetCurrentDirectoryW(module);
 						}
 					}
 				}
@@ -326,7 +335,7 @@ FreeImage_Initialise(BOOL load_local_plugins_only) {
 				// restore the current directory
 
 				if (bOk) {
-					SetCurrentDirectory(current_dir);
+					SetCurrentDirectoryW(current_dir);
 				}
 			}
 #endif // _WIN32
diff --git a/Source/FreeImage/PluginBMP.cpp b/Source/FreeImage/PluginBMP.cpp
index 4041d85..0ee1c5d 100644
--- a/Source/FreeImage/PluginBMP.cpp
+++ b/Source/FreeImage/PluginBMP.cpp
@@ -35,10 +35,13 @@ static const BYTE RLE_ENDOFLINE   = 0;
 static const BYTE RLE_ENDOFBITMAP = 1;
 static const BYTE RLE_DELTA       = 2;
 
-static const BYTE BI_RGB          = 0;
-static const BYTE BI_RLE8         = 1;
-static const BYTE BI_RLE4         = 2;
-static const BYTE BI_BITFIELDS    = 3;
+static const BYTE BI_RGB            = 0;	// compression: none
+static const BYTE BI_RLE8           = 1;	// compression: RLE 8-bit/pixel
+static const BYTE BI_RLE4           = 2;	// compression: RLE 4-bit/pixel
+static const BYTE BI_BITFIELDS      = 3;	// compression: Bit field or Huffman 1D compression for BITMAPCOREHEADER2
+static const BYTE BI_JPEG           = 4;	// compression: JPEG or RLE-24 compression for BITMAPCOREHEADER2
+static const BYTE BI_PNG            = 5;	// compression: PNG
+static const BYTE BI_ALPHABITFIELDS = 6;	// compression: Bit field (this value is valid in Windows CE .NET 4.0 and later)
 
 // ----------------------------------------------------------
 
@@ -65,11 +68,11 @@ typedef struct tagBITMAPINFOOS2_1X_HEADER {
 } BITMAPINFOOS2_1X_HEADER, *PBITMAPINFOOS2_1X_HEADER; 
 
 typedef struct tagBITMAPFILEHEADER {
-  WORD    bfType; 
-  DWORD   bfSize;
-  WORD    bfReserved1; 
-  WORD    bfReserved2;
-  DWORD   bfOffBits; 
+  WORD    bfType;		//! The file type
+  DWORD   bfSize;		//! The size, in bytes, of the bitmap file
+  WORD    bfReserved1;	//! Reserved; must be zero
+  WORD    bfReserved2;	//! Reserved; must be zero
+  DWORD   bfOffBits;	//! The offset, in bytes, from the beginning of the BITMAPFILEHEADER structure to the bitmap bits
 } BITMAPFILEHEADER, *PBITMAPFILEHEADER;
 
 #ifdef _WIN32
@@ -452,7 +455,7 @@ LoadPixelDataRLE8(FreeImageIO *io, fi_handle handle, int width, int height, FIBI
 // --------------------------------------------------------------------------
 
 static FIBITMAP *
-LoadWindowsBMP(FreeImageIO *io, fi_handle handle, int flags, unsigned bitmap_bits_offset) {
+LoadWindowsBMP(FreeImageIO *io, fi_handle handle, int flags, unsigned bitmap_bits_offset, int type) {
 	FIBITMAP *dib = NULL;
 
 	try {
@@ -481,8 +484,9 @@ LoadWindowsBMP(FreeImageIO *io, fi_handle handle, int flags, unsigned bitmap_bit
 			case 4 :
 			case 8 :
 			{
-				if ((used_colors == 0) || (used_colors > CalculateUsedPaletteEntries(bit_count)))
+				if ((used_colors == 0) || (used_colors > CalculateUsedPaletteEntries(bit_count))) {
 					used_colors = CalculateUsedPaletteEntries(bit_count);
+				}
 				
 				// allocate enough memory to hold the bitmap (header, palette, pixels) and read the palette
 
@@ -494,6 +498,19 @@ LoadWindowsBMP(FreeImageIO *io, fi_handle handle, int flags, unsigned bitmap_bit
 				// set resolution information
 				FreeImage_SetDotsPerMeterX(dib, bih.biXPelsPerMeter);
 				FreeImage_SetDotsPerMeterY(dib, bih.biYPelsPerMeter);
+
+				// seek to the end of the header (depending on the BMP header version)
+				// type == sizeof(BITMAPVxINFOHEADER)
+				switch(type) {
+					case 40:	// sizeof(BITMAPINFOHEADER) - all Windows versions since Windows 3.0
+						break;
+					case 52:	// sizeof(BITMAPV2INFOHEADER) (undocumented)
+					case 56:	// sizeof(BITMAPV3INFOHEADER) (undocumented)
+					case 108:	// sizeof(BITMAPV4HEADER) - all Windows versions since Windows 95/NT4 (not supported)
+					case 124:	// sizeof(BITMAPV5HEADER) - Windows 98/2000 and newer (not supported)
+						io->seek_proc(handle, (long)(type - sizeof(BITMAPINFOHEADER)), SEEK_CUR);
+						break;
+				}
 				
 				// load the palette
 
@@ -512,10 +529,8 @@ LoadWindowsBMP(FreeImageIO *io, fi_handle handle, int flags, unsigned bitmap_bit
 
 				// seek to the actual pixel data.
 				// this is needed because sometimes the palette is larger than the entries it contains predicts
+				io->seek_proc(handle, bitmap_bits_offset, SEEK_SET);
 
-				if (bitmap_bits_offset > (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (used_colors * sizeof(RGBQUAD))))
-					io->seek_proc(handle, bitmap_bits_offset, SEEK_SET);
-				
 				// read the pixel data
 
 				switch (compression) {
@@ -551,11 +566,15 @@ LoadWindowsBMP(FreeImageIO *io, fi_handle handle, int flags, unsigned bitmap_bit
 
 			case 16 :
 			{
-				if (bih.biCompression == BI_BITFIELDS) {
-					DWORD bitfields[3];
-
-					io->read_proc(bitfields, 3 * sizeof(DWORD), 1, handle);
-
+				int use_bitfields = 0;
+				if (bih.biCompression == BI_BITFIELDS) use_bitfields = 3;
+				else if (bih.biCompression == BI_ALPHABITFIELDS) use_bitfields = 4;
+				else if (type == 52) use_bitfields = 3;
+				else if (type >= 56) use_bitfields = 4;
+				
+				if (use_bitfields > 0) {
+ 					DWORD bitfields[4];
+					io->read_proc(bitfields, use_bitfields * sizeof(DWORD), 1, handle);
 					dib = FreeImage_AllocateHeader(header_only, width, height, bit_count, bitfields[0], bitfields[1], bitfields[2]);
 				} else {
 					dib = FreeImage_AllocateHeader(header_only, width, height, bit_count, FI16_555_RED_MASK, FI16_555_GREEN_MASK, FI16_555_BLUE_MASK);
@@ -573,14 +592,11 @@ LoadWindowsBMP(FreeImageIO *io, fi_handle handle, int flags, unsigned bitmap_bit
 					// header only mode
 					return dib;
 				}
+				
+				// seek to the actual pixel data
+				io->seek_proc(handle, bitmap_bits_offset, SEEK_SET);
 
 				// load pixel data and swap as needed if OS is Big Endian
-
-				if (bitmap_bits_offset > (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER))) {
-					// seek to the actual pixel data
-					io->seek_proc(handle, bitmap_bits_offset, SEEK_SET);
-				}
-
 				LoadPixelData(io, handle, dib, height, pitch, bit_count);
 
 				return dib;
@@ -590,11 +606,15 @@ LoadWindowsBMP(FreeImageIO *io, fi_handle handle, int flags, unsigned bitmap_bit
 			case 24 :
 			case 32 :
 			{
-				if (bih.biCompression == BI_BITFIELDS) {
-					DWORD bitfields[3];
-
-					io->read_proc(bitfields, 3 * sizeof(DWORD), 1, handle);
-
+				int use_bitfields = 0;
+				if (bih.biCompression == BI_BITFIELDS) use_bitfields = 3;
+				else if (bih.biCompression == BI_ALPHABITFIELDS) use_bitfields = 4;
+				else if (type == 52) use_bitfields = 3;
+				else if (type >= 56) use_bitfields = 4;
+
+ 				if (use_bitfields > 0) {
+					DWORD bitfields[4];
+					io->read_proc(bitfields, use_bitfields * sizeof(DWORD), 1, handle);
 					dib = FreeImage_AllocateHeader(header_only, width, height, bit_count, bitfields[0], bitfields[1], bitfields[2]);
 				} else {
 					if( bit_count == 32 ) {
@@ -619,12 +639,10 @@ LoadWindowsBMP(FreeImageIO *io, fi_handle handle, int flags, unsigned bitmap_bit
 
 				// Skip over the optional palette 
 				// A 24 or 32 bit DIB may contain a palette for faster color reduction
+				// i.e. you can have (FreeImage_GetColorsUsed(dib) > 0)
 
-				if (FreeImage_GetColorsUsed(dib) > 0) {
-				    io->seek_proc(handle, FreeImage_GetColorsUsed(dib) * sizeof(RGBQUAD), SEEK_CUR);
-				} else if ((bih.biCompression != BI_BITFIELDS) && (bitmap_bits_offset > sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER))) {
-					io->seek_proc(handle, bitmap_bits_offset, SEEK_SET);
-				}
+				// seek to the actual pixel data
+				io->seek_proc(handle, bitmap_bits_offset, SEEK_SET);
 
 				// read in the bitmap bits
 				// load pixel data and swap as needed if OS is Big Endian
@@ -735,8 +753,9 @@ LoadOS22XBMP(FreeImageIO *io, fi_handle handle, int flags, unsigned bitmap_bits_
 				// seek to the actual pixel data.
 				// this is needed because sometimes the palette is larger than the entries it contains predicts
 
-				if (bitmap_bits_offset > (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (used_colors * 3)))
+				if (bitmap_bits_offset > (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (used_colors * 3))) {
 					io->seek_proc(handle, bitmap_bits_offset, SEEK_SET);
+				}
 
 				// read the pixel data
 
@@ -827,8 +846,9 @@ LoadOS22XBMP(FreeImageIO *io, fi_handle handle, int flags, unsigned bitmap_bits_
 				// Skip over the optional palette 
 				// A 24 or 32 bit DIB may contain a palette for faster color reduction
 
-				if (bitmap_bits_offset > (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (used_colors * 3)))
+				if (bitmap_bits_offset > (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (used_colors * 3))) {
 					io->seek_proc(handle, bitmap_bits_offset, SEEK_SET);
+				}
 				
 				// read in the bitmap bits
 				// load pixel data and swap as needed if OS is Big Endian
@@ -1101,24 +1121,18 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
 			case 12:
 				// OS/2 and also all Windows versions since Windows 3.0
 				return LoadOS21XBMP(io, handle, flags, offset_in_file + bitmapfileheader.bfOffBits);
+
 			case 64:
 				// OS/2
 				return LoadOS22XBMP(io, handle, flags, offset_in_file + bitmapfileheader.bfOffBits);
-			case 40:
-				// BITMAPINFOHEADER - all Windows versions since Windows 3.0
-				return LoadWindowsBMP(io, handle, flags, offset_in_file + bitmapfileheader.bfOffBits);
-			case 52:
-				// BITMAPV2INFOHEADER (undocumented)
-				break;
-			case 56:
-				// BITMAPV3INFOHEADER (undocumented)
-				break;
-			case 108:
-				// BITMAPV4HEADER - all Windows versions since Windows 95/NT4 (not supported)
-				break;
-			case 124:
-				// BITMAPV5HEADER - Windows 98/2000 and newer (not supported)
-				break;
+
+			case 40:	// BITMAPINFOHEADER - all Windows versions since Windows 3.0
+			case 52:	// BITMAPV2INFOHEADER (undocumented, partially supported)
+			case 56:	// BITMAPV3INFOHEADER (undocumented, partially supported)
+			case 108:	// BITMAPV4HEADER - all Windows versions since Windows 95/NT4 (partially supported)
+			case 124:	// BITMAPV5HEADER - Windows 98/2000 and newer (partially supported)
+				return LoadWindowsBMP(io, handle, flags, offset_in_file + bitmapfileheader.bfOffBits, type);
+
 			default:
 				break;
 		}
diff --git a/Source/FreeImage/PluginEXR.cpp b/Source/FreeImage/PluginEXR.cpp
index 4a19b8b..b286430 100644
--- a/Source/FreeImage/PluginEXR.cpp
+++ b/Source/FreeImage/PluginEXR.cpp
@@ -22,6 +22,12 @@
 
 #include "FreeImage.h"
 #include "Utilities.h"
+
+#ifdef _MSC_VER
+// OpenEXR has many problems with MSVC warnings (why not just correct them ?), just ignore one of them
+#pragma warning (disable : 4800) // ImfVersion.h - 'const int' : forcing value to bool 'true' or 'false' (performance warning)
+#endif 
+
 #include "../OpenEXR/IlmImf/ImfIO.h"
 #include "../OpenEXR/Iex/Iex.h"
 #include "../OpenEXR/IlmImf/ImfOutputFile.h"
@@ -44,72 +50,64 @@ static int s_format_id;
 
 /**
 FreeImage input stream wrapper
+ at see Imf_2_2::IStream
 */
-class C_IStream: public Imf::IStream {
-public:
-	C_IStream (FreeImageIO *io, fi_handle handle):
-	IStream(""), _io (io), _handle(handle) {}
-
-	virtual bool	read (char c[/*n*/], int n);
-	virtual Imf::Int64	tellg ();
-	virtual void	seekg (Imf::Int64 pos);
-	virtual void	clear () {};
-
+class C_IStream : public Imf::IStream {
 private:
     FreeImageIO *_io;
 	fi_handle _handle;
+
+public:
+	C_IStream (FreeImageIO *io, fi_handle handle) : 
+	  Imf::IStream(""), _io (io), _handle(handle) {
+	}
+
+	virtual bool read (char c[/*n*/], int n) {
+		return ((unsigned)n != _io->read_proc(c, 1, n, _handle));
+	}
+
+	virtual Imath::Int64 tellg() {
+		return _io->tell_proc(_handle);
+	}
+
+	virtual void seekg(Imath::Int64 pos) {
+		_io->seek_proc(_handle, (unsigned)pos, SEEK_SET);
+	}
+
+	virtual void clear() {
+	}
 };
 
+// ----------------------------------------------------------
 
 /**
 FreeImage output stream wrapper
+ at see Imf_2_2::OStream
 */
-class C_OStream: public Imf::OStream {
-public:
-	C_OStream (FreeImageIO *io, fi_handle handle):
-	OStream(""), _io (io), _handle(handle) {}
-
-    virtual void	write (const char c[/*n*/], int n);
-	virtual Imf::Int64	tellp ();
-	virtual void	seekp (Imf::Int64 pos);
-
+class C_OStream : public Imf::OStream {
 private:
     FreeImageIO *_io;
 	fi_handle _handle;
-};
-
-
-bool
-C_IStream::read (char c[/*n*/], int n) {
-	return ((unsigned)n != _io->read_proc(c, 1, n, _handle));
-}
-
-Imf::Int64
-C_IStream::tellg () {
-	return _io->tell_proc(_handle);
-}
 
-void
-C_IStream::seekg (Imf::Int64 pos) {
-	_io->seek_proc(_handle, (unsigned)pos, SEEK_SET);
-}
+public:
+	C_OStream (FreeImageIO *io, fi_handle handle) : 
+	  Imf::OStream(""), _io (io), _handle(handle) {
+	}
 
-void
-C_OStream::write (const char c[/*n*/], int n) {
-	if((unsigned)n != _io->write_proc((void*)&c[0], 1, n, _handle)) {
-		Iex::throwErrnoExc();
+	virtual void write(const char c[/*n*/], int n) {
+		if((unsigned)n != _io->write_proc((void*)&c[0], 1, n, _handle)) {
+			Iex::throwErrnoExc();
+		}
 	}
-}
 
-Imf::Int64
-C_OStream::tellp () {
-	return _io->tell_proc(_handle);
-}
+	virtual Imath::Int64 tellp() {
+		return _io->tell_proc(_handle);
+	}
 
-void
-C_OStream::seekp (Imf::Int64 pos) {
-	_io->seek_proc(_handle, (unsigned)pos, SEEK_SET);
-}
+	virtual void seekp(Imath::Int64 pos) {
+		_io->seek_proc(_handle, (unsigned)pos, SEEK_SET);
+	}
+};
 
 // ----------------------------------------------------------
 
@@ -667,7 +665,9 @@ Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void
 		if(pixelType == Imf::HALF) {
 			// convert from float to half
 			halfData = new(std::nothrow) half[width * height * components];
-			if(!halfData) THROW (Iex::NullExc, FI_MSG_ERROR_MEMORY);
+			if(!halfData) {
+				THROW (Iex::NullExc, FI_MSG_ERROR_MEMORY);
+			}
 
 			for(int y = 0; y < height; y++) {
 				float *src_bits = (float*)FreeImage_GetScanLine(dib, height - 1 - y);
@@ -716,7 +716,9 @@ Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void
 		file.setFrameBuffer (frameBuffer);
 		file.writePixels (height);
 
-		if(halfData != NULL) delete[] halfData;
+		if(halfData != NULL) {
+			delete[] halfData;
+		}
 		if(bIsFlipped) {
 			// invert dib scanlines
 			FreeImage_FlipVertical(dib);
@@ -725,7 +727,9 @@ Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void
 		return TRUE;
 
 	} catch(Iex::BaseExc & e) {
-		if(halfData != NULL) delete[] halfData;
+		if(halfData != NULL) {
+			delete[] halfData;
+		}
 		if(bIsFlipped) {
 			// invert dib scanlines
 			FreeImage_FlipVertical(dib);
@@ -745,6 +749,11 @@ void DLL_CALLCONV
 InitEXR(Plugin *plugin, int format_id) {
 	s_format_id = format_id;
 
+	// initialize the OpenEXR library
+	// note that this OpenEXR function produce so called "false memory leaks"
+	// see http://lists.nongnu.org/archive/html/openexr-devel/2013-11/msg00000.html
+	Imf::staticInitialize();
+
 	plugin->format_proc = Format;
 	plugin->description_proc = Description;
 	plugin->extension_proc = Extension;
diff --git a/Source/FreeImage/PluginG3.cpp b/Source/FreeImage/PluginG3.cpp
index d5c08b3..0a083b4 100644
--- a/Source/FreeImage/PluginG3.cpp
+++ b/Source/FreeImage/PluginG3.cpp
@@ -92,7 +92,7 @@ G3GetFileSize(FreeImageIO *io, fi_handle handle) {
 
 static BOOL 
 G3ReadFile(FreeImageIO *io, fi_handle handle, uint8 *tif_rawdata, tmsize_t tif_rawdatasize) {
-	return ((tmsize_t)(io->read_proc(tif_rawdata, tif_rawdatasize, 1, handle) * tif_rawdatasize) == tif_rawdatasize);
+	return ((tmsize_t)(io->read_proc(tif_rawdata, (unsigned)tif_rawdatasize, 1, handle) * tif_rawdatasize) == tif_rawdatasize);
 }
 
 // ==========================================================
diff --git a/Source/FreeImage/PluginGIF.cpp b/Source/FreeImage/PluginGIF.cpp
index e8d84af..0153959 100644
--- a/Source/FreeImage/PluginGIF.cpp
+++ b/Source/FreeImage/PluginGIF.cpp
@@ -4,6 +4,7 @@
 // Design and implementation by
 // - Ryan Rubley <ryan at lostreality.org>
 // - Rapha�l Gaquer <raphael.gaquer at alcer.com>
+// - Aaron Shumate <aaron at shumate.us>
 //
 // This file is part of FreeImage 3
 //
@@ -376,7 +377,7 @@ bool StringTable::Decompress(BYTE *buf, int *len)
 			m_partial >>= m_codeSize;
 			m_partialSize -= m_codeSize;
 
-			if( code > m_nextCode || (m_nextCode == MAX_LZW_CODE && code != m_clearCode) || code == m_endCode ) {
+			if( code > m_nextCode || /*(m_nextCode == MAX_LZW_CODE && code != m_clearCode) || */code == m_endCode ) {
 				m_done = true;
 				*len = (int)(bufpos - buf);
 				return true;
@@ -387,7 +388,7 @@ bool StringTable::Decompress(BYTE *buf, int *len)
 			}
 
 			//add new string to string table, if not the first pass since a clear code
-			if( m_oldCode != MAX_LZW_CODE ) {
+			if( m_oldCode != MAX_LZW_CODE && m_nextCode < MAX_LZW_CODE) {
 				m_strings[m_nextCode] = m_strings[m_oldCode] + m_strings[code == m_nextCode ? m_oldCode : code][0];
 			}
 
@@ -773,7 +774,11 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
 					}
 					if( info.disposal_method == GIF_DISPOSAL_BACKGROUND ) {
 						for( y = 0; y < info.height; y++ ) {
-							scanline = (RGBQUAD *)FreeImage_GetScanLine(dib, logicalheight - (y + info.top) - 1) + info.left;
+							const int scanidx = logicalheight - (y + info.top) - 1;
+							if ( scanidx < 0 ) {
+								break;  // If data is corrupt, don't calculate in invalid scanline
+							}
+							scanline = (RGBQUAD *)FreeImage_GetScanLine(dib, scanidx) + info.left;
 							for( x = 0; x < info.width; x++ ) {
 								*scanline++ = background;
 							}
@@ -800,7 +805,11 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
 					}
 					//copy page data into logical buffer, with full alpha opaqueness
 					for( y = 0; y < info.height; y++ ) {
-						scanline = (RGBQUAD *)FreeImage_GetScanLine(dib, logicalheight - (y + info.top) - 1) + info.left;
+						const int scanidx = logicalheight - (y + info.top) - 1;
+						if ( scanidx < 0 ) {
+							break;  // If data is corrupt, don't calculate in invalid scanline
+						}
+						scanline = (RGBQUAD *)FreeImage_GetScanLine(dib, scanidx) + info.left;
 						BYTE *pageline = FreeImage_GetScanLine(pagedib, info.height - y - 1);
 						for( x = 0; x < info.width; x++ ) {
 							if( !have_transparent || *pageline != transparent_color ) {
diff --git a/Source/FreeImage/PluginHDR.cpp b/Source/FreeImage/PluginHDR.cpp
index d8c24ad..28ce1a5 100644
--- a/Source/FreeImage/PluginHDR.cpp
+++ b/Source/FreeImage/PluginHDR.cpp
@@ -73,7 +73,7 @@ typedef enum {
 	rgbe_read_error,
 	rgbe_write_error,
 	rgbe_format_error,
-	rgbe_memory_error,
+	rgbe_memory_error
 } rgbe_error_code;
 
 // ----------------------------------------------------------
@@ -459,8 +459,9 @@ rgbe_WriteBytes_RLE(FreeImageIO *io, fi_handle handle, BYTE *data, int numbytes)
 			beg_run += run_count;
 			old_run_count = run_count;
 			run_count = 1;
-			while((data[beg_run] == data[beg_run + run_count]) && (beg_run + run_count < numbytes) && (run_count < 127))
+			while((beg_run + run_count < numbytes) && (run_count < 127) && (data[beg_run] == data[beg_run + run_count])) {
 				run_count++;
+			}
 		}
 		// if data before next big run is a short run then write it as such 
 		if ((old_run_count > 1)&&(old_run_count == beg_run - cur)) {
diff --git a/Source/FreeImage/PluginICO.cpp b/Source/FreeImage/PluginICO.cpp
index 7f41a0d..c818379 100644
--- a/Source/FreeImage/PluginICO.cpp
+++ b/Source/FreeImage/PluginICO.cpp
@@ -110,6 +110,23 @@ CalculateImageOffset(std::vector<FIBITMAP*>& vPages, int nIndex ) {
     return dwSize;
 }
 
+/**
+Vista icon support
+ at return Returns TRUE if the bitmap data is stored in PNG format
+*/
+static BOOL
+IsPNG(FreeImageIO *io, fi_handle handle) {
+	BYTE png_signature[8] = { 137, 80, 78, 71, 13, 10, 26, 10 };
+	BYTE signature[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+
+	long tell = io->tell_proc(handle);
+	io->read_proc(&signature, 1, 8, handle);
+	BOOL bIsPNG = (memcmp(png_signature, signature, 8) == 0);
+	io->seek_proc(handle, tell, SEEK_SET);
+
+	return bIsPNG;
+}
+
 #ifdef FREEIMAGE_BIGENDIAN
 static void
 SwapInfoHeader(BITMAPINFOHEADER *header) {
@@ -339,7 +356,8 @@ LoadStandardIcon(FreeImageIO *io, fi_handle handle, int flags, BOOL header_only)
 	// bitmap has been loaded successfully!
 
 	// convert to 32bpp and generate an alpha channel
-	if((flags & ICO_MAKEALPHA) == ICO_MAKEALPHA) {
+	// apply the AND mask only if the image is not 32 bpp
+	if(((flags & ICO_MAKEALPHA) == ICO_MAKEALPHA) && (bit_count < 32)) {
 		FIBITMAP *dib32 = FreeImage_ConvertTo32Bits(dib);
 		FreeImage_Unload(dib);
 
@@ -406,16 +424,17 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
 			// load the requested icon
 			if (page < icon_header->idCount) {
 				// seek to the start of the bitmap data for the icon
-				io->seek_proc(handle, 0, SEEK_SET);
-				io->seek_proc(handle, icon_list[page].dwImageOffset, SEEK_CUR);
+				io->seek_proc(handle, icon_list[page].dwImageOffset, SEEK_SET);
 
-				if((icon_list[page].bWidth == 0) && (icon_list[page].bHeight == 0)) {
+				if( IsPNG(io, handle) ) {
 					// Vista icon support
+					// see http://blogs.msdn.com/b/oldnewthing/archive/2010/10/22/10079192.aspx
 					dib = FreeImage_LoadFromHandle(FIF_PNG, io, handle, header_only ? FIF_LOAD_NOPIXELS : PNG_DEFAULT);
 				}
 				else {
 					// standard icon support
 					// see http://msdn.microsoft.com/en-us/library/ms997538.aspx
+					// see http://blogs.msdn.com/b/oldnewthing/archive/2010/10/18/10077133.aspx
 					dib = LoadStandardIcon(io, handle, flags, header_only);
 				}
 
diff --git a/Source/FreeImage/PluginJ2K.cpp b/Source/FreeImage/PluginJ2K.cpp
index ae8a6ae..b8bcfc8 100644
--- a/Source/FreeImage/PluginJ2K.cpp
+++ b/Source/FreeImage/PluginJ2K.cpp
@@ -1,339 +1,328 @@
-// ==========================================================
-// JPEG2000 J2K codestream Loader and Writer
-//
-// Design and implementation by
-// - Herv� Drolon (drolon at infonie.fr)
-//
-// This file is part of FreeImage 3
-//
-// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
-// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
-// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
-// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
-// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
-// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
-// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
-// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
-// THIS DISCLAIMER.
-//
-// Use at your own risk!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-#include "../LibOpenJPEG/openjpeg.h"
-
-// ==========================================================
-// Plugin Interface
-// ==========================================================
-
-static int s_format_id;
-
-// ==========================================================
-// Helper functions (see J2KHelper.cpp)
-// ==========================================================
-
-FIBITMAP* J2KImageToFIBITMAP(int format_id, const opj_image_t *image);
-opj_image_t* FIBITMAPToJ2KImage(int format_id, FIBITMAP *dib, const opj_cparameters_t *parameters);
-
-// ==========================================================
-// Internal functions
-// ==========================================================
-
-/**
-OpenJPEG Error callback 
-*/
-static void j2k_error_callback(const char *msg, void *client_data) {
-	FreeImage_OutputMessageProc(s_format_id, "Error: %s", msg);
-}
-/**
-OpenJPEG Warning callback 
-*/
-static void j2k_warning_callback(const char *msg, void *client_data) {
-	FreeImage_OutputMessageProc(s_format_id, "Warning: %s", msg);
-}
-
-// ==========================================================
-// Plugin Implementation
-// ==========================================================
-
-static const char * DLL_CALLCONV
-Format() {
-	return "J2K";
-}
-
-static const char * DLL_CALLCONV
-Description() {
-	return "JPEG-2000 codestream";
-}
-
-static const char * DLL_CALLCONV
-Extension() {
-	return "j2k,j2c";
-}
-
-static const char * DLL_CALLCONV
-RegExpr() {
-	return NULL;
-}
-
-static const char * DLL_CALLCONV
-MimeType() {
-	return "image/j2k";
-}
-
-static BOOL DLL_CALLCONV
-Validate(FreeImageIO *io, fi_handle handle) {
-	BYTE jpc_signature[] = { 0xFF, 0x4F };
-	BYTE signature[2] = { 0, 0 };
-
-	long tell = io->tell_proc(handle);
-	io->read_proc(signature, 1, sizeof(jpc_signature), handle);
-	io->seek_proc(handle, tell, SEEK_SET);
-
-	return (memcmp(jpc_signature, signature, sizeof(jpc_signature)) == 0);
-}
-
-static BOOL DLL_CALLCONV
-SupportsExportDepth(int depth) {
-	return (
-		(depth == 8) ||
-		(depth == 24) || 
-		(depth == 32)
-	);
-}
-
-static BOOL DLL_CALLCONV 
-SupportsExportType(FREE_IMAGE_TYPE type) {
-	return (
-		(type == FIT_BITMAP)  ||
-		(type == FIT_UINT16)  ||
-		(type == FIT_RGB16) || 
-		(type == FIT_RGBA16)
-	);
-}
-
-// ----------------------------------------------------------
-
-static void * DLL_CALLCONV
-Open(FreeImageIO *io, fi_handle handle, BOOL read) {
-	return NULL;
-}
-
-static void DLL_CALLCONV
-Close(FreeImageIO *io, fi_handle handle, void *data) {
-}
-
-// ----------------------------------------------------------
-
-static FIBITMAP * DLL_CALLCONV
-Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
-	if (handle) {
-		opj_dparameters_t parameters;	// decompression parameters 
-		opj_event_mgr_t event_mgr;		// event manager 
-		opj_image_t *image = NULL;		// decoded image 
-
-		BYTE *src = NULL; 
-		long file_length;
-
-		opj_dinfo_t* dinfo = NULL;	// handle to a decompressor 
-		opj_cio_t *cio = NULL;
-
-		FIBITMAP *dib = NULL;
-
-		// check the file format
-		if(!Validate(io, handle)) {
-			return NULL;
-		}
-
-		// configure the event callbacks
-		memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
-		event_mgr.error_handler = j2k_error_callback;
-		event_mgr.warning_handler = j2k_warning_callback;
-		event_mgr.info_handler = NULL;
-
-		// set decoding parameters to default values 
-		opj_set_default_decoder_parameters(&parameters);
-
-		try {
-			// read the input file and put it in memory
-
-			long start_pos = io->tell_proc(handle);
-			io->seek_proc(handle, 0, SEEK_END);
-			file_length = io->tell_proc(handle) - start_pos;
-			io->seek_proc(handle, start_pos, SEEK_SET);
-			src = (BYTE*)malloc(file_length * sizeof(BYTE));
-			if(!src) {
-				throw FI_MSG_ERROR_MEMORY;
-			}
-			if(io->read_proc(src, 1, file_length, handle) < 1) {
-				throw "Error while reading input stream";
-			}
-
-			// decode the JPEG-2000 codestream
-
-			// get a decoder handle 
-			dinfo = opj_create_decompress(CODEC_J2K);
-			
-			// catch events using our callbacks
-			opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, NULL);			
-
-			// setup the decoder decoding parameters using user parameters 
-			opj_setup_decoder(dinfo, &parameters);
-
-			// open a byte stream 
-			cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);
-
-			// decode the stream and fill the image structure 
-			image = opj_decode(dinfo, cio);
-			if(!image) {
-				throw "Failed to decode image!\n";
-			}
-			
-			// close the byte stream 
-			opj_cio_close(cio);
-			cio = NULL;
-
-			// free the memory containing the code-stream 
-			free(src);
-			src = NULL;
-
-			// free the codec context
-			opj_destroy_decompress(dinfo);
-
-			// create output image 
-			dib = J2KImageToFIBITMAP(s_format_id, image);
-			if(!dib) throw "Failed to import JPEG2000 image";
-
-			// free image data structure
-			opj_image_destroy(image);
-
-			return dib;
-
-		} catch (const char *text) {
-			if(src) free(src);
-			if(dib) FreeImage_Unload(dib);
-			// free remaining structures
-			opj_destroy_decompress(dinfo);
-			opj_image_destroy(image);
-			// close the byte stream
-			if(cio) opj_cio_close(cio);
-
-			FreeImage_OutputMessageProc(s_format_id, text);
-
-			return NULL;
-		}
-	}
-
-	return NULL;
-}
-
-static BOOL DLL_CALLCONV
-Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void *data) {
-	if ((dib) && (handle)) {
-		BOOL bSuccess;
-		opj_cparameters_t parameters;		// compression parameters 
-		opj_event_mgr_t event_mgr;			// event manager 
-		opj_image_t *image = NULL;			// image to encode
-		opj_cinfo_t* cinfo = NULL;			// codec context
-		opj_cio_t *cio = NULL;				// memory byte stream
-
-		// configure the event callbacks
-		memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
-		event_mgr.error_handler = j2k_error_callback;
-		event_mgr.warning_handler = j2k_warning_callback;
-		event_mgr.info_handler = NULL;
-
-		// set encoding parameters to default values
-		opj_set_default_encoder_parameters(&parameters);
-
-		parameters.tcp_numlayers = 0;
-		// if no rate entered, apply a 16:1 rate by default
-		if(flags == J2K_DEFAULT) {
-			parameters.tcp_rates[0] = (float)16;
-		} else {
-			// for now, the flags parameter is only used to specify the rate
-			parameters.tcp_rates[0] = (float)flags;
-		}
-		parameters.tcp_numlayers++;
-		parameters.cp_disto_alloc = 1;
-
-		try {
-			// convert the dib to a OpenJPEG image
-			image = FIBITMAPToJ2KImage(s_format_id, dib, &parameters);
-			if(!image) return FALSE;
-
-			// decide if MCT should be used
-			parameters.tcp_mct = (image->numcomps == 3) ? 1 : 0;
-
-			// encode the destination image
-
-			// get a J2K compressor handle
-			cinfo = opj_create_compress(CODEC_J2K);
-
-			// catch events using our callbacks
-			opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, NULL);			
-
-			// setup the encoder parameters using the current image and using user parameters
-			opj_setup_encoder(cinfo, &parameters, image);
-
-			// open a byte stream for writing, allocate memory for all tiles
-			cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0);
-
-			// encode the image
-			bSuccess = opj_encode(cinfo, cio, image, NULL/*parameters.index*/);
-			if (!bSuccess) {
-				throw "Failed to encode image";
-			}
-			int codestream_length = cio_tell(cio);
-
-			// write the buffer to user's IO handle
-			io->write_proc(cio->buffer, 1, codestream_length, handle);
-
-			// close and free the byte stream 
-			opj_cio_close(cio);
-
-			// free remaining compression structures
-			opj_destroy_compress(cinfo);
-			
-			// free image data
-			opj_image_destroy(image);
-
-			return TRUE;
-
-		} catch (const char *text) {
-			if(cio) opj_cio_close(cio);
-			if(cinfo) opj_destroy_compress(cinfo);
-			if(image) opj_image_destroy(image);
-			FreeImage_OutputMessageProc(s_format_id, text);
-			return FALSE;
-		}
-	}
-
-	return FALSE;
-}
-
-// ==========================================================
-//   Init
-// ==========================================================
-
-void DLL_CALLCONV
-InitJ2K(Plugin *plugin, int format_id) {
-	s_format_id = format_id;
-
-	plugin->format_proc = Format;
-	plugin->description_proc = Description;
-	plugin->extension_proc = Extension;
-	plugin->regexpr_proc = RegExpr;
-	plugin->open_proc = Open;
-	plugin->close_proc = Close;
-	plugin->pagecount_proc = NULL;
-	plugin->pagecapability_proc = NULL;
-	plugin->load_proc = Load;
-	plugin->save_proc = Save;
-	plugin->validate_proc = Validate;
-	plugin->mime_proc = MimeType;
-	plugin->supports_export_bpp_proc = SupportsExportDepth;
-	plugin->supports_export_type_proc = SupportsExportType;
-	plugin->supports_icc_profiles_proc = NULL;
-}
+// ==========================================================
+// JPEG2000 J2K codestream Loader and Writer
+//
+// Design and implementation by
+// - Herv� Drolon (drolon at infonie.fr)
+//
+// This file is part of FreeImage 3
+//
+// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
+// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
+// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
+// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
+// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
+// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
+// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+// THIS DISCLAIMER.
+//
+// Use at your own risk!
+// ==========================================================
+
+#include "FreeImage.h"
+#include "Utilities.h"
+#include "../LibOpenJPEG/openjpeg.h"
+#include "J2KHelper.h"
+
+// ==========================================================
+// Plugin Interface
+// ==========================================================
+
+static int s_format_id;
+
+// ==========================================================
+// Internal functions
+// ==========================================================
+
+/**
+OpenJPEG Error callback 
+*/
+static void j2k_error_callback(const char *msg, void *client_data) {
+	FreeImage_OutputMessageProc(s_format_id, "Error: %s", msg);
+}
+/**
+OpenJPEG Warning callback 
+*/
+static void j2k_warning_callback(const char *msg, void *client_data) {
+	FreeImage_OutputMessageProc(s_format_id, "Warning: %s", msg);
+}
+
+// ==========================================================
+// Plugin Implementation
+// ==========================================================
+
+static const char * DLL_CALLCONV
+Format() {
+	return "J2K";
+}
+
+static const char * DLL_CALLCONV
+Description() {
+	return "JPEG-2000 codestream";
+}
+
+static const char * DLL_CALLCONV
+Extension() {
+	return "j2k,j2c";
+}
+
+static const char * DLL_CALLCONV
+RegExpr() {
+	return NULL;
+}
+
+static const char * DLL_CALLCONV
+MimeType() {
+	return "image/j2k";
+}
+
+static BOOL DLL_CALLCONV
+Validate(FreeImageIO *io, fi_handle handle) {
+	BYTE jpc_signature[] = { 0xFF, 0x4F };
+	BYTE signature[2] = { 0, 0 };
+
+	long tell = io->tell_proc(handle);
+	io->read_proc(signature, 1, sizeof(jpc_signature), handle);
+	io->seek_proc(handle, tell, SEEK_SET);
+
+	return (memcmp(jpc_signature, signature, sizeof(jpc_signature)) == 0);
+}
+
+static BOOL DLL_CALLCONV
+SupportsExportDepth(int depth) {
+	return (
+		(depth == 8) ||
+		(depth == 24) || 
+		(depth == 32)
+	);
+}
+
+static BOOL DLL_CALLCONV 
+SupportsExportType(FREE_IMAGE_TYPE type) {
+	return (
+		(type == FIT_BITMAP)  ||
+		(type == FIT_UINT16)  ||
+		(type == FIT_RGB16) || 
+		(type == FIT_RGBA16)
+	);
+}
+
+// ----------------------------------------------------------
+
+static void * DLL_CALLCONV
+Open(FreeImageIO *io, fi_handle handle, BOOL read) {
+	// create the stream wrapper
+	J2KFIO_t *fio = opj_freeimage_stream_create(io, handle, read);
+	return fio;
+}
+
+static void DLL_CALLCONV
+Close(FreeImageIO *io, fi_handle handle, void *data) {
+	// destroy the stream wrapper
+	J2KFIO_t *fio = (J2KFIO_t*)data;
+	opj_freeimage_stream_destroy(fio);
+}
+
+// ----------------------------------------------------------
+
+static FIBITMAP * DLL_CALLCONV
+Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
+	J2KFIO_t *fio = (J2KFIO_t*)data;
+	if (handle && fio) {
+		opj_codec_t *d_codec = NULL;	// handle to a decompressor
+		opj_dparameters_t parameters;	// decompression parameters
+		opj_image_t *image = NULL;		// decoded image 
+
+		FIBITMAP *dib = NULL;
+
+		// check the file format
+		if(!Validate(io, handle)) {
+			return NULL;
+		}
+
+		BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS;
+
+		// get the OpenJPEG stream
+		opj_stream_t *d_stream = fio->stream;
+
+		// set decoding parameters to default values 
+		opj_set_default_decoder_parameters(&parameters);
+
+		try {
+			// decode the JPEG-2000 codestream
+
+			// get a decoder handle
+			d_codec = opj_create_decompress(OPJ_CODEC_J2K);
+			
+			// configure the event callbacks
+			// catch events using our callbacks (no local context needed here)
+			opj_set_info_handler(d_codec, NULL, NULL);
+			opj_set_warning_handler(d_codec, j2k_warning_callback, NULL);
+			opj_set_error_handler(d_codec, j2k_error_callback, NULL);
+
+			// setup the decoder decoding parameters using user parameters
+			if( !opj_setup_decoder(d_codec, &parameters) ) {
+				throw "Failed to setup the decoder\n";
+			}
+			
+			// read the main header of the codestream and if necessary the JP2 boxes
+			if( !opj_read_header(d_stream, d_codec, &image)) {
+				throw "Failed to read the header\n";
+			}
+
+			// --- header only mode
+
+			if (header_only) {
+				// create output image 
+				dib = J2KImageToFIBITMAP(s_format_id, image, header_only);
+				if(!dib) {
+					throw "Failed to import JPEG2000 image";
+				}
+				// clean-up and return header data
+				opj_destroy_codec(d_codec);
+				opj_image_destroy(image);
+				return dib;
+			}
+
+			// decode the stream and fill the image structure 
+			if( !( opj_decode(d_codec, d_stream, image) && opj_end_decompress(d_codec, d_stream) ) ) {
+				throw "Failed to decode image!\n";
+			}
+
+			// free the codec context
+			opj_destroy_codec(d_codec);
+			d_codec = NULL;
+
+			// create output image 
+			dib = J2KImageToFIBITMAP(s_format_id, image, header_only);
+			if(!dib) {
+				throw "Failed to import JPEG2000 image";
+			}
+
+			// free image data structure
+			opj_image_destroy(image);
+
+			return dib;
+
+		} catch (const char *text) {
+			if(dib) {
+				FreeImage_Unload(dib);
+			}
+			// free remaining structures
+			opj_destroy_codec(d_codec);
+			opj_image_destroy(image);
+
+			FreeImage_OutputMessageProc(s_format_id, text);
+
+			return NULL;
+		}
+	}
+
+	return NULL;
+}
+
+static BOOL DLL_CALLCONV
+Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void *data) {
+	J2KFIO_t *fio = (J2KFIO_t*)data;
+	if (dib && handle && fio) {
+		BOOL bSuccess;
+		opj_codec_t *c_codec = NULL;	// handle to a compressor
+		opj_cparameters_t parameters;	// compression parameters
+		opj_image_t *image = NULL;		// image to encode
+
+		// get the OpenJPEG stream
+		opj_stream_t *c_stream = fio->stream;
+
+		// set encoding parameters to default values
+		opj_set_default_encoder_parameters(&parameters);
+
+		try {
+			parameters.tcp_numlayers = 0;
+			// if no rate entered, apply a 16:1 rate by default
+			if(flags == J2K_DEFAULT) {
+				parameters.tcp_rates[0] = (float)16;
+			} else {
+				// for now, the flags parameter is only used to specify the rate
+				parameters.tcp_rates[0] = (float)(flags & 0x3FF);
+			}
+			parameters.tcp_numlayers++;
+			parameters.cp_disto_alloc = 1;
+
+			// convert the dib to a OpenJPEG image
+			image = FIBITMAPToJ2KImage(s_format_id, dib, &parameters);
+			if(!image) {
+				return FALSE;
+			}
+
+			// decide if MCT should be used
+			parameters.tcp_mct = (image->numcomps == 3) ? 1 : 0;
+
+			// encode the destination image
+
+			// get a J2K compressor handle
+			c_codec = opj_create_compress(OPJ_CODEC_J2K);
+
+			// configure the event callbacks
+			// catch events using our callbacks (no local context needed here)
+			opj_set_info_handler(c_codec, NULL, NULL);
+			opj_set_warning_handler(c_codec, j2k_warning_callback, NULL);
+			opj_set_error_handler(c_codec, j2k_error_callback, NULL);
+
+			// setup the encoder parameters using the current image and using user parameters
+			opj_setup_encoder(c_codec, &parameters, image);
+
+			// encode the image
+			bSuccess = opj_start_compress(c_codec, image, c_stream);
+			if(bSuccess) {
+				bSuccess = bSuccess && opj_encode(c_codec, c_stream);
+				if(bSuccess) {
+					bSuccess = bSuccess && opj_end_compress(c_codec, c_stream);
+				}
+			}
+			if (!bSuccess) {
+				throw "Failed to encode image";
+			}
+
+			// free remaining compression structures
+			opj_destroy_codec(c_codec);
+			
+			// free image data
+			opj_image_destroy(image);
+
+			return TRUE;
+
+		} catch (const char *text) {
+			if(c_codec) opj_destroy_codec(c_codec);
+			if(image) opj_image_destroy(image);
+			FreeImage_OutputMessageProc(s_format_id, text);
+			return FALSE;
+		}
+	}
+
+	return FALSE;
+}
+
+// ==========================================================
+//   Init
+// ==========================================================
+
+void DLL_CALLCONV
+InitJ2K(Plugin *plugin, int format_id) {
+	s_format_id = format_id;
+
+	plugin->format_proc = Format;
+	plugin->description_proc = Description;
+	plugin->extension_proc = Extension;
+	plugin->regexpr_proc = RegExpr;
+	plugin->open_proc = Open;
+	plugin->close_proc = Close;
+	plugin->pagecount_proc = NULL;
+	plugin->pagecapability_proc = NULL;
+	plugin->load_proc = Load;
+	plugin->save_proc = Save;
+	plugin->validate_proc = Validate;
+	plugin->mime_proc = MimeType;
+	plugin->supports_export_bpp_proc = SupportsExportDepth;
+	plugin->supports_export_type_proc = SupportsExportType;
+	plugin->supports_icc_profiles_proc = NULL;
+}
diff --git a/Source/FreeImage/PluginJP2.cpp b/Source/FreeImage/PluginJP2.cpp
index 261697f..742fe2c 100644
--- a/Source/FreeImage/PluginJP2.cpp
+++ b/Source/FreeImage/PluginJP2.cpp
@@ -1,339 +1,328 @@
-// ==========================================================
-// JPEG2000 JP2 file format Loader and Writer
-//
-// Design and implementation by
-// - Herv� Drolon (drolon at infonie.fr)
-//
-// This file is part of FreeImage 3
-//
-// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
-// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
-// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
-// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
-// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
-// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
-// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
-// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
-// THIS DISCLAIMER.
-//
-// Use at your own risk!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-#include "../LibOpenJPEG/openjpeg.h"
-
-// ==========================================================
-// Plugin Interface
-// ==========================================================
-
-static int s_format_id;
-
-// ==========================================================
-// Helper functions (see J2KHelper.cpp)
-// ==========================================================
-
-FIBITMAP* J2KImageToFIBITMAP(int format_id, const opj_image_t *image);
-opj_image_t* FIBITMAPToJ2KImage(int format_id, FIBITMAP *dib, const opj_cparameters_t *parameters);
-
-// ==========================================================
-// Internal functions
-// ==========================================================
-
-/**
-OpenJPEG Error callback 
-*/
-static void jp2_error_callback(const char *msg, void *client_data) {
-	FreeImage_OutputMessageProc(s_format_id, "Error: %s", msg);
-}
-/**
-OpenJPEG Warning callback 
-*/
-static void jp2_warning_callback(const char *msg, void *client_data) {
-	FreeImage_OutputMessageProc(s_format_id, "Warning: %s", msg);
-}
-
-// ==========================================================
-// Plugin Implementation
-// ==========================================================
-
-static const char * DLL_CALLCONV
-Format() {
-	return "JP2";
-}
-
-static const char * DLL_CALLCONV
-Description() {
-	return "JPEG-2000 File Format";
-}
-
-static const char * DLL_CALLCONV
-Extension() {
-	return "jp2";
-}
-
-static const char * DLL_CALLCONV
-RegExpr() {
-	return NULL;
-}
-
-static const char * DLL_CALLCONV
-MimeType() {
-	return "image/jp2";
-}
-
-static BOOL DLL_CALLCONV
-Validate(FreeImageIO *io, fi_handle handle) {
-	BYTE jp2_signature[] = { 0x00, 0x00, 0x00, 0x0C, 0x6A, 0x50, 0x20, 0x20, 0x0D, 0x0A, 0x87, 0x0A };
-	BYTE signature[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-
-	long tell = io->tell_proc(handle);
-	io->read_proc(signature, 1, sizeof(jp2_signature), handle);
-	io->seek_proc(handle, tell, SEEK_SET);
-
-	return (memcmp(jp2_signature, signature, sizeof(jp2_signature)) == 0);
-}
-
-static BOOL DLL_CALLCONV
-SupportsExportDepth(int depth) {
-	return (
-		(depth == 8) ||
-		(depth == 24) || 
-		(depth == 32)
-	);
-}
-
-static BOOL DLL_CALLCONV 
-SupportsExportType(FREE_IMAGE_TYPE type) {
-	return (
-		(type == FIT_BITMAP)  ||
-		(type == FIT_UINT16)  ||
-		(type == FIT_RGB16) || 
-		(type == FIT_RGBA16)
-	);
-}
-
-// ----------------------------------------------------------
-
-static void * DLL_CALLCONV
-Open(FreeImageIO *io, fi_handle handle, BOOL read) {
-	return NULL;
-}
-
-static void DLL_CALLCONV
-Close(FreeImageIO *io, fi_handle handle, void *data) {
-}
-
-// ----------------------------------------------------------
-
-static FIBITMAP * DLL_CALLCONV
-Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
-	if (handle) {
-		opj_dparameters_t parameters;	// decompression parameters 
-		opj_event_mgr_t event_mgr;		// event manager 
-		opj_image_t *image = NULL;		// decoded image 
-
-		BYTE *src = NULL; 
-		long file_length;
-
-		opj_dinfo_t* dinfo = NULL;	// handle to a decompressor 
-		opj_cio_t *cio = NULL;
-
-		FIBITMAP *dib = NULL;
-
-		// check the file format
-		if(!Validate(io, handle)) {
-			return NULL;
-		}
-
-		// configure the event callbacks
-		memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
-		event_mgr.error_handler = jp2_error_callback;
-		event_mgr.warning_handler = jp2_warning_callback;
-		event_mgr.info_handler = NULL;
-
-		// set decoding parameters to default values 
-		opj_set_default_decoder_parameters(&parameters);
-
-		try {
-			// read the input file and put it in memory
-
-			long start_pos = io->tell_proc(handle);
-			io->seek_proc(handle, 0, SEEK_END);
-			file_length = io->tell_proc(handle) - start_pos;
-			io->seek_proc(handle, start_pos, SEEK_SET);
-			src = (BYTE*)malloc(file_length * sizeof(BYTE));
-			if(!src) {
-				throw FI_MSG_ERROR_MEMORY;
-			}
-			if(io->read_proc(src, 1, file_length, handle) < 1) {
-				throw "Error while reading input stream";
-			}
-
-			// decode the JPEG-2000 file
-
-			// get a decoder handle 
-			dinfo = opj_create_decompress(CODEC_JP2);
-			
-			// catch events using our callbacks
-			opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, NULL);			
-
-			// setup the decoder decoding parameters using user parameters 
-			opj_setup_decoder(dinfo, &parameters);
-
-			// open a byte stream 
-			cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);
-
-			// decode the stream and fill the image structure 
-			image = opj_decode(dinfo, cio);
-			if(!image) {
-				throw "Failed to decode image!\n";
-			}
-			
-			// close the byte stream 
-			opj_cio_close(cio);
-			cio = NULL;
-
-			// free the memory containing the code-stream 
-			free(src);
-			src = NULL;
-
-			// free the codec context
-			opj_destroy_decompress(dinfo);
-
-			// create output image 
-			dib = J2KImageToFIBITMAP(s_format_id, image);
-			if(!dib) throw "Failed to import JPEG2000 image";
-
-			// free image data structure
-			opj_image_destroy(image);
-
-			return dib;
-
-		} catch (const char *text) {
-			if(src) free(src);
-			if(dib) FreeImage_Unload(dib);
-			// free remaining structures
-			opj_destroy_decompress(dinfo);
-			opj_image_destroy(image);
-			// close the byte stream
-			if(cio) opj_cio_close(cio);
-
-			FreeImage_OutputMessageProc(s_format_id, text);
-
-			return NULL;
-		}
-	}
-
-	return NULL;
-}
-
-static BOOL DLL_CALLCONV
-Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void *data) {
-	if ((dib) && (handle)) {
-		BOOL bSuccess;
-		opj_cparameters_t parameters;		// compression parameters 
-		opj_event_mgr_t event_mgr;			// event manager 
-		opj_image_t *image = NULL;			// image to encode
-		opj_cinfo_t* cinfo = NULL;			// codec context
-		opj_cio_t *cio = NULL;				// memory byte stream
-
-		// configure the event callbacks
-		memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
-		event_mgr.error_handler = jp2_error_callback;
-		event_mgr.warning_handler = jp2_warning_callback;
-		event_mgr.info_handler = NULL;
-
-		// set encoding parameters to default values
-		opj_set_default_encoder_parameters(&parameters);
-
-		parameters.tcp_numlayers = 0;
-		// if no rate entered, apply a 16:1 rate by default
-		if(flags == JP2_DEFAULT) {
-			parameters.tcp_rates[0] = (float)16;
-		} else {
-			// for now, the flags parameter is only used to specify the rate
-			parameters.tcp_rates[0] = (float)flags;
-		}
-		parameters.tcp_numlayers++;
-		parameters.cp_disto_alloc = 1;
-
-		try {
-			// convert the dib to a OpenJPEG image
-			image = FIBITMAPToJ2KImage(s_format_id, dib, &parameters);
-			if(!image) return FALSE;
-
-			// decide if MCT should be used
-			parameters.tcp_mct = (image->numcomps == 3) ? 1 : 0;
-
-			// encode the destination image
-
-			// get a J2K compressor handle
-			cinfo = opj_create_compress(CODEC_JP2);
-
-			// catch events using our callbacks
-			opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, NULL);			
-
-			// setup the encoder parameters using the current image and using user parameters
-			opj_setup_encoder(cinfo, &parameters, image);
-
-			// open a byte stream for writing, allocate memory for all tiles
-			cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0);
-
-			// encode the image
-			bSuccess = opj_encode(cinfo, cio, image, NULL/*parameters.index*/);
-			if (!bSuccess) {
-				throw "Failed to encode image";
-			}
-			int codestream_length = cio_tell(cio);
-
-			// write the buffer to user's IO handle
-			io->write_proc(cio->buffer, 1, codestream_length, handle);
-
-			// close and free the byte stream 
-			opj_cio_close(cio);
-
-			// free remaining compression structures
-			opj_destroy_compress(cinfo);
-			
-			// free image data
-			opj_image_destroy(image);
-
-			return TRUE;
-
-		} catch (const char *text) {
-			if(cio) opj_cio_close(cio);
-			if(cinfo) opj_destroy_compress(cinfo);
-			if(image) opj_image_destroy(image);
-			FreeImage_OutputMessageProc(s_format_id, text);
-			return FALSE;
-		}
-	}
-
-	return FALSE;
-}
-
-// ==========================================================
-//   Init
-// ==========================================================
-
-void DLL_CALLCONV
-InitJP2(Plugin *plugin, int format_id) {
-	s_format_id = format_id;
-
-	plugin->format_proc = Format;
-	plugin->description_proc = Description;
-	plugin->extension_proc = Extension;
-	plugin->regexpr_proc = RegExpr;
-	plugin->open_proc = Open;
-	plugin->close_proc = Close;
-	plugin->pagecount_proc = NULL;
-	plugin->pagecapability_proc = NULL;
-	plugin->load_proc = Load;
-	plugin->save_proc = Save;
-	plugin->validate_proc = Validate;
-	plugin->mime_proc = MimeType;
-	plugin->supports_export_bpp_proc = SupportsExportDepth;
-	plugin->supports_export_type_proc = SupportsExportType;
-	plugin->supports_icc_profiles_proc = NULL;
-}
+// ==========================================================
+// JPEG2000 JP2 file format Loader and Writer
+//
+// Design and implementation by
+// - Herv� Drolon (drolon at infonie.fr)
+//
+// This file is part of FreeImage 3
+//
+// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
+// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
+// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
+// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
+// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
+// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
+// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+// THIS DISCLAIMER.
+//
+// Use at your own risk!
+// ==========================================================
+
+#include "FreeImage.h"
+#include "Utilities.h"
+#include "../LibOpenJPEG/openjpeg.h"
+#include "J2KHelper.h"
+
+// ==========================================================
+// Plugin Interface
+// ==========================================================
+
+static int s_format_id;
+
+// ==========================================================
+// Internal functions
+// ==========================================================
+
+/**
+OpenJPEG Error callback 
+*/
+static void jp2_error_callback(const char *msg, void *client_data) {
+	FreeImage_OutputMessageProc(s_format_id, "Error: %s", msg);
+}
+/**
+OpenJPEG Warning callback 
+*/
+static void jp2_warning_callback(const char *msg, void *client_data) {
+	FreeImage_OutputMessageProc(s_format_id, "Warning: %s", msg);
+}
+
+// ==========================================================
+// Plugin Implementation
+// ==========================================================
+
+static const char * DLL_CALLCONV
+Format() {
+	return "JP2";
+}
+
+static const char * DLL_CALLCONV
+Description() {
+	return "JPEG-2000 File Format";
+}
+
+static const char * DLL_CALLCONV
+Extension() {
+	return "jp2";
+}
+
+static const char * DLL_CALLCONV
+RegExpr() {
+	return NULL;
+}
+
+static const char * DLL_CALLCONV
+MimeType() {
+	return "image/jp2";
+}
+
+static BOOL DLL_CALLCONV
+Validate(FreeImageIO *io, fi_handle handle) {
+	BYTE jp2_signature[] = { 0x00, 0x00, 0x00, 0x0C, 0x6A, 0x50, 0x20, 0x20, 0x0D, 0x0A, 0x87, 0x0A };
+	BYTE signature[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+	long tell = io->tell_proc(handle);
+	io->read_proc(signature, 1, sizeof(jp2_signature), handle);
+	io->seek_proc(handle, tell, SEEK_SET);
+
+	return (memcmp(jp2_signature, signature, sizeof(jp2_signature)) == 0);
+}
+
+static BOOL DLL_CALLCONV
+SupportsExportDepth(int depth) {
+	return (
+		(depth == 8) ||
+		(depth == 24) || 
+		(depth == 32)
+	);
+}
+
+static BOOL DLL_CALLCONV 
+SupportsExportType(FREE_IMAGE_TYPE type) {
+	return (
+		(type == FIT_BITMAP)  ||
+		(type == FIT_UINT16)  ||
+		(type == FIT_RGB16) || 
+		(type == FIT_RGBA16)
+	);
+}
+
+// ----------------------------------------------------------
+
+static void * DLL_CALLCONV
+Open(FreeImageIO *io, fi_handle handle, BOOL read) {
+	// create the stream wrapper
+	J2KFIO_t *fio = opj_freeimage_stream_create(io, handle, read);
+	return fio;
+}
+
+static void DLL_CALLCONV
+Close(FreeImageIO *io, fi_handle handle, void *data) {
+	// destroy the stream wrapper
+	J2KFIO_t *fio = (J2KFIO_t*)data;
+	opj_freeimage_stream_destroy(fio);
+}
+
+// ----------------------------------------------------------
+
+static FIBITMAP * DLL_CALLCONV
+Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
+	J2KFIO_t *fio = (J2KFIO_t*)data;
+	if (handle && fio) {
+		opj_codec_t *d_codec = NULL;	// handle to a decompressor
+		opj_dparameters_t parameters;	// decompression parameters
+		opj_image_t *image = NULL;		// decoded image 
+
+		FIBITMAP *dib = NULL;
+
+		// check the file format
+		if(!Validate(io, handle)) {
+			return NULL;
+		}
+		
+		BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS;
+
+		// get the OpenJPEG stream
+		opj_stream_t *d_stream = fio->stream;
+
+		// set decoding parameters to default values 
+		opj_set_default_decoder_parameters(&parameters);
+
+		try {
+			// decode the JPEG-2000 file
+
+			// get a decoder handle
+			d_codec = opj_create_decompress(OPJ_CODEC_JP2);
+			
+			// configure the event callbacks
+			// catch events using our callbacks (no local context needed here)
+			opj_set_info_handler(d_codec, NULL, NULL);
+			opj_set_warning_handler(d_codec, jp2_warning_callback, NULL);
+			opj_set_error_handler(d_codec, jp2_error_callback, NULL);
+
+			// setup the decoder decoding parameters using user parameters
+			if( !opj_setup_decoder(d_codec, &parameters) ) {
+				throw "Failed to setup the decoder\n";
+			}
+			
+			// read the main header of the codestream and if necessary the JP2 boxes
+			if( !opj_read_header(d_stream, d_codec, &image)) {
+				throw "Failed to read the header\n";
+			}
+
+			// --- header only mode
+
+			if (header_only) {
+				// create output image 
+				dib = J2KImageToFIBITMAP(s_format_id, image, header_only);
+				if(!dib) {
+					throw "Failed to import JPEG2000 image";
+				}
+				// clean-up and return header data
+				opj_destroy_codec(d_codec);
+				opj_image_destroy(image);
+				return dib;
+			}
+
+			// decode the stream and fill the image structure 
+			if( !( opj_decode(d_codec, d_stream, image) && opj_end_decompress(d_codec, d_stream) ) ) {
+				throw "Failed to decode image!\n";
+			}
+
+			// free the codec context
+			opj_destroy_codec(d_codec);
+			d_codec = NULL;
+
+			// create output image 
+			dib = J2KImageToFIBITMAP(s_format_id, image, header_only);
+			if(!dib) {
+				throw "Failed to import JPEG2000 image";
+			}
+
+			// free image data structure
+			opj_image_destroy(image);
+
+			return dib;
+
+		} catch (const char *text) {
+			if(dib) {
+				FreeImage_Unload(dib);
+			}
+			// free remaining structures
+			opj_destroy_codec(d_codec);
+			opj_image_destroy(image);
+
+			FreeImage_OutputMessageProc(s_format_id, text);
+
+			return NULL;
+		}
+	}
+
+	return NULL;
+}
+
+static BOOL DLL_CALLCONV
+Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void *data) {
+	J2KFIO_t *fio = (J2KFIO_t*)data;
+	if (dib && handle && fio) {
+		BOOL bSuccess;
+		opj_codec_t *c_codec = NULL;	// handle to a compressor
+		opj_cparameters_t parameters;	// compression parameters
+		opj_image_t *image = NULL;		// image to encode
+
+		// get the OpenJPEG stream
+		opj_stream_t *c_stream = fio->stream;
+
+		// set encoding parameters to default values
+		opj_set_default_encoder_parameters(&parameters);
+
+		try {
+			parameters.tcp_numlayers = 0;
+			// if no rate entered, apply a 16:1 rate by default
+			if(flags == JP2_DEFAULT) {
+				parameters.tcp_rates[0] = (float)16;
+			} else {
+				// for now, the flags parameter is only used to specify the rate
+				parameters.tcp_rates[0] = (float)(flags & 0x3FF);
+			}
+			parameters.tcp_numlayers++;
+			parameters.cp_disto_alloc = 1;
+
+			// convert the dib to a OpenJPEG image
+			image = FIBITMAPToJ2KImage(s_format_id, dib, &parameters);
+			if(!image) {
+				return FALSE;
+			}
+
+			// decide if MCT should be used
+			parameters.tcp_mct = (image->numcomps == 3) ? 1 : 0;
+
+			// encode the destination image
+
+			// get a JP2 compressor handle
+			c_codec = opj_create_compress(OPJ_CODEC_JP2);
+
+			// configure the event callbacks
+			// catch events using our callbacks (no local context needed here)
+			opj_set_info_handler(c_codec, NULL, NULL);
+			opj_set_warning_handler(c_codec, jp2_warning_callback, NULL);
+			opj_set_error_handler(c_codec, jp2_error_callback, NULL);
+
+			// setup the encoder parameters using the current image and using user parameters
+			opj_setup_encoder(c_codec, &parameters, image);
+
+			// encode the image
+			bSuccess = opj_start_compress(c_codec, image, c_stream);
+			if(bSuccess) {
+				bSuccess = bSuccess && opj_encode(c_codec, c_stream);
+				if(bSuccess) {
+					bSuccess = bSuccess && opj_end_compress(c_codec, c_stream);
+				}
+			}
+			if (!bSuccess) {
+				throw "Failed to encode image";
+			}
+
+			// free remaining compression structures
+			opj_destroy_codec(c_codec);
+			
+			// free image data
+			opj_image_destroy(image);
+
+			return TRUE;
+
+		} catch (const char *text) {
+			if(c_codec) opj_destroy_codec(c_codec);
+			if(image) opj_image_destroy(image);
+			FreeImage_OutputMessageProc(s_format_id, text);
+			return FALSE;
+		}
+	}
+
+	return FALSE;
+}
+
+// ==========================================================
+//   Init
+// ==========================================================
+
+void DLL_CALLCONV
+InitJP2(Plugin *plugin, int format_id) {
+	s_format_id = format_id;
+
+	plugin->format_proc = Format;
+	plugin->description_proc = Description;
+	plugin->extension_proc = Extension;
+	plugin->regexpr_proc = RegExpr;
+	plugin->open_proc = Open;
+	plugin->close_proc = Close;
+	plugin->pagecount_proc = NULL;
+	plugin->pagecapability_proc = NULL;
+	plugin->load_proc = Load;
+	plugin->save_proc = Save;
+	plugin->validate_proc = Validate;
+	plugin->mime_proc = MimeType;
+	plugin->supports_export_bpp_proc = SupportsExportDepth;
+	plugin->supports_export_type_proc = SupportsExportType;
+	plugin->supports_icc_profiles_proc = NULL;
+}
diff --git a/Source/FreeImage/PluginJPEG.cpp b/Source/FreeImage/PluginJPEG.cpp
index b3bc9f2..573989c 100644
--- a/Source/FreeImage/PluginJPEG.cpp
+++ b/Source/FreeImage/PluginJPEG.cpp
@@ -656,46 +656,6 @@ jpeg_read_xmp_profile(FIBITMAP *dib, const BYTE *dataptr, unsigned int datalen)
 }
 
 /**
-	Read JPEG_APP1 marker (Exif profile)
-	@param dib Input FIBITMAP
-	@param dataptr Pointer to the APP1 marker
-	@param datalen APP1 marker length
-	@return Returns TRUE if successful, FALSE otherwise
-*/
-static BOOL  
-jpeg_read_exif_profile_raw(FIBITMAP *dib, const BYTE *profile, unsigned int length) {
-    // marker identifying string for Exif = "Exif\0\0"
-    BYTE exif_signature[6] = { 0x45, 0x78, 0x69, 0x66, 0x00, 0x00 };
-
-	// verify the identifying string
-	if(memcmp(exif_signature, profile, sizeof(exif_signature)) != 0) {
-		// not an Exif profile
-		return FALSE;
-	}
-
-	// create a tag
-	FITAG *tag = FreeImage_CreateTag();
-	if(tag) {
-		FreeImage_SetTagID(tag, EXIF_MARKER);	// (JPEG_APP0 + 1) => EXIF marker / Adobe XMP marker
-		FreeImage_SetTagKey(tag, g_TagLib_ExifRawFieldName);
-		FreeImage_SetTagLength(tag, (DWORD)length);
-		FreeImage_SetTagCount(tag, (DWORD)length);
-		FreeImage_SetTagType(tag, FIDT_BYTE);
-		FreeImage_SetTagValue(tag, profile);
-
-		// store the tag
-		FreeImage_SetMetadata(FIMD_EXIF_RAW, dib, FreeImage_GetTagKey(tag), tag);
-
-		// destroy the tag
-		FreeImage_DeleteTag(tag);
-
-		return TRUE;
-	}
-
-	return FALSE;
-}
-
-/**
 	Read JFIF "JFXX" extension APP0 marker
 	@param dib Input FIBITMAP
 	@param dataptr Pointer to the APP0 marker
@@ -1125,66 +1085,6 @@ store_size_info(FIBITMAP *dib, JDIMENSION width, JDIMENSION height) {
 	}
 }
 
-// ------------------------------------------------------------
-//   Rotate a dib according to Exif info
-// ------------------------------------------------------------
-
-static void 
-rotate_exif(FIBITMAP **dib) {
-	// check for Exif rotation
-	if(FreeImage_GetMetadataCount(FIMD_EXIF_MAIN, *dib)) {
-		FIBITMAP *rotated = NULL;
-		// process Exif rotation
-		FITAG *tag = NULL;
-		FreeImage_GetMetadata(FIMD_EXIF_MAIN, *dib, "Orientation", &tag);
-		if(tag != NULL) {
-			if(FreeImage_GetTagID(tag) == TAG_ORIENTATION) {
-				unsigned short orientation = *((unsigned short *)FreeImage_GetTagValue(tag));
-				switch (orientation) {
-					case 1:		// "top, left side" => 0�
-						break;
-					case 2:		// "top, right side" => flip left-right
-						FreeImage_FlipHorizontal(*dib);
-						break;
-					case 3:		// "bottom, right side"; => -180�
-						rotated = FreeImage_Rotate(*dib, 180);
-						FreeImage_Unload(*dib);
-						*dib = rotated;
-						break;
-					case 4:		// "bottom, left side" => flip up-down
-						FreeImage_FlipVertical(*dib);
-						break;
-					case 5:		// "left side, top" => +90� + flip up-down
-						rotated = FreeImage_Rotate(*dib, 90);
-						FreeImage_Unload(*dib);
-						*dib = rotated;
-						FreeImage_FlipVertical(*dib);
-						break;
-					case 6:		// "right side, top" => -90�
-						rotated = FreeImage_Rotate(*dib, -90);
-						FreeImage_Unload(*dib);
-						*dib = rotated;
-						break;
-					case 7:		// "right side, bottom" => -90� + flip up-down
-						rotated = FreeImage_Rotate(*dib, -90);
-						FreeImage_Unload(*dib);
-						*dib = rotated;
-						FreeImage_FlipVertical(*dib);
-						break;
-					case 8:		// "left side, bottom" => +90�
-						rotated = FreeImage_Rotate(*dib, 90);
-						FreeImage_Unload(*dib);
-						*dib = rotated;
-						break;
-					default:
-						break;
-				}
-			}
-		}
-	}
-}
-
-
 // ==========================================================
 // Plugin Implementation
 // ==========================================================
@@ -1472,7 +1372,7 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
 
 			// check for automatic Exif rotation
 			if(!header_only && ((flags & JPEG_EXIFROTATE) == JPEG_EXIFROTATE)) {
-				rotate_exif(&dib);
+				RotateExif(&dib);
 			}
 
 			// everything went well. return the loaded dib
diff --git a/Source/FreeImage/PluginJXR.cpp b/Source/FreeImage/PluginJXR.cpp
new file mode 100644
index 0000000..0e14e09
--- /dev/null
+++ b/Source/FreeImage/PluginJXR.cpp
@@ -0,0 +1,1475 @@
+// ==========================================================
+// JPEG XR Loader & Writer
+//
+// Design and implementation by
+// - Herve Drolon (drolon at infonie.fr)
+//
+// This file is part of FreeImage 3
+//
+// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
+// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
+// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
+// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
+// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
+// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
+// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+// THIS DISCLAIMER.
+//
+// Use at your own risk!
+// ==========================================================
+
+#include "FreeImage.h"
+#include "Utilities.h"
+#include "../Metadata/FreeImageTag.h"
+
+#include "../LibJXR/jxrgluelib/JXRGlue.h"
+
+// ==========================================================
+// Plugin Interface
+// ==========================================================
+
+static int s_format_id;
+
+// ==========================================================
+// FreeImageIO interface (I/O streaming functions)
+// ==========================================================
+
+/**
+JXR wrapper for FreeImage I/O handle
+*/
+typedef struct tagFreeImageJXRIO {
+    FreeImageIO *io;
+	fi_handle handle;
+} FreeImageJXRIO;
+
+static ERR 
+_jxr_io_Read(WMPStream* pWS, void* pv, size_t cb) {
+	FreeImageJXRIO *fio = (FreeImageJXRIO*)pWS->state.pvObj;
+	return (fio->io->read_proc(pv, (unsigned)cb, 1, fio->handle) == 1) ? WMP_errSuccess : WMP_errFileIO;
+}
+
+static ERR 
+_jxr_io_Write(WMPStream* pWS, const void* pv, size_t cb) {
+	FreeImageJXRIO *fio = (FreeImageJXRIO*)pWS->state.pvObj;
+	if(0 != cb) {
+		return (fio->io->write_proc((void*)pv, (unsigned)cb, 1, fio->handle) == 1) ? WMP_errSuccess : WMP_errFileIO;
+	}
+	return WMP_errFileIO;
+}
+
+static ERR 
+_jxr_io_SetPos(WMPStream* pWS, size_t offPos) {
+	FreeImageJXRIO *fio = (FreeImageJXRIO*)pWS->state.pvObj;
+    return (fio->io->seek_proc(fio->handle, (long)offPos, SEEK_SET) == 0) ? WMP_errSuccess : WMP_errFileIO;
+}
+
+static ERR 
+_jxr_io_GetPos(WMPStream* pWS, size_t* poffPos) {
+	FreeImageJXRIO *fio = (FreeImageJXRIO*)pWS->state.pvObj;
+    long lOff = fio->io->tell_proc(fio->handle);
+	if(lOff == -1) {
+		return WMP_errFileIO;
+	}
+    *poffPos = (size_t)lOff;
+	return WMP_errSuccess;
+}
+
+static Bool 
+_jxr_io_EOS(WMPStream* pWS) {
+	FreeImageJXRIO *fio = (FreeImageJXRIO*)pWS->state.pvObj;
+    long currentPos = fio->io->tell_proc(fio->handle);
+    fio->io->seek_proc(fio->handle, 0, SEEK_END);
+    long fileRemaining = fio->io->tell_proc(fio->handle) - currentPos;
+    fio->io->seek_proc(fio->handle, currentPos, SEEK_SET);
+    return (fileRemaining > 0);
+}
+
+static ERR 
+_jxr_io_Close(WMPStream** ppWS) {
+	WMPStream *pWS = *ppWS;
+	// HACK : we use fMem to avoid a stream destruction by the library
+	// because FreeImage MUST HAVE the ownership of the stream
+	// see _jxr_io_Create
+	if(pWS && pWS->fMem) {
+		free(pWS);
+		*ppWS = NULL;
+	}
+	return WMP_errSuccess;
+}
+
+static ERR 
+_jxr_io_Create(WMPStream **ppWS, FreeImageJXRIO *jxr_io) {
+	*ppWS = (WMPStream*)calloc(1, sizeof(**ppWS));
+	if(*ppWS) {
+		WMPStream *pWS = *ppWS;
+
+		pWS->state.pvObj = jxr_io;
+		pWS->Close = _jxr_io_Close;
+		pWS->EOS = _jxr_io_EOS;
+		pWS->Read = _jxr_io_Read;
+		pWS->Write = _jxr_io_Write;
+		pWS->SetPos = _jxr_io_SetPos;
+		pWS->GetPos = _jxr_io_GetPos;
+
+		// HACK : we use fMem to avoid a stream destruction by the library
+		// because FreeImage MUST HAVE the ownership of the stream
+		// see _jxr_io_Close
+		pWS->fMem = FALSE;
+
+		return WMP_errSuccess;
+	}
+	return WMP_errOutOfMemory;
+}
+
+// ==========================================================
+// JPEG XR Error handling
+// ==========================================================
+
+static const char* 
+JXR_ErrorMessage(const int error) {
+	switch(error) {
+		case WMP_errNotYetImplemented:
+		case WMP_errAbstractMethod:
+			return "Not yet implemented";
+		case WMP_errOutOfMemory:
+			return "Out of memory";
+		case WMP_errFileIO:
+			return "File I/O error";
+		case WMP_errBufferOverflow:
+			return "Buffer overflow";
+		case WMP_errInvalidParameter:
+			return "Invalid parameter";
+		case WMP_errInvalidArgument:
+			return "Invalid argument";
+		case WMP_errUnsupportedFormat:
+			return "Unsupported format";
+		case WMP_errIncorrectCodecVersion:
+			return "Incorrect codec version";
+		case WMP_errIndexNotFound:
+			return "Format converter: Index not found";
+		case WMP_errOutOfSequence:
+			return "Metadata: Out of sequence";
+		case WMP_errMustBeMultipleOf16LinesUntilLastCall:
+			return "Must be multiple of 16 lines until last call";
+		case WMP_errPlanarAlphaBandedEncRequiresTempFile:
+			return "Planar alpha banded encoder requires temp files";
+		case WMP_errAlphaModeCannotBeTranscoded:
+			return "Alpha mode cannot be transcoded";
+		case WMP_errIncorrectCodecSubVersion:
+			return "Incorrect codec subversion";
+		case WMP_errFail:
+		case WMP_errNotInitialized:
+		default:
+			return "Invalid instruction - please contact the FreeImage team";
+	}
+}
+
+// ==========================================================
+// Helper functions & macro
+// ==========================================================
+
+#define JXR_CHECK(error_code) \
+	if(error_code < 0) { \
+		const char *error_message = JXR_ErrorMessage(error_code); \
+		throw error_message; \
+	}
+
+// --------------------------------------------------------------------------
+
+/**
+Input conversions natively understood by FreeImage
+ at see GetNativePixelFormat
+*/
+typedef struct tagJXRInputConversion {
+	BITDEPTH_BITS bdBitDepth;
+	U32 cbitUnit;
+	FREE_IMAGE_TYPE image_type;
+	unsigned red_mask;
+	unsigned green_mask;
+	unsigned blue_mask;
+} JXRInputConversion;
+
+/**
+Conversion table for native FreeImage formats
+ at see GetNativePixelFormat
+*/
+static JXRInputConversion s_FreeImagePixelInfo[] = {
+	// 1-bit bitmap
+	{ BD_1, 1, FIT_BITMAP, 0, 0, 0 },
+	// 8-, 24-, 32-bit bitmap
+	{ BD_8, 8, FIT_BITMAP, 0, 0, 0 },
+	{ BD_8, 24, FIT_BITMAP, 0, 0, 0 },
+	{ BD_8, 32, FIT_BITMAP, 0, 0, 0 },
+	// 16-bit RGB 565
+	{ BD_565, 16, FIT_BITMAP, FI16_565_RED_MASK, FI16_565_GREEN_MASK, FI16_565_BLUE_MASK },
+	// 16-bit RGB 555
+	{ BD_5, 16, FIT_BITMAP, FI16_555_RED_MASK, FI16_555_GREEN_MASK, FI16_555_BLUE_MASK },
+	// 16-bit greyscale, RGB16, RGBA16 bitmap
+	{ BD_16, 16, FIT_UINT16, 0, 0, 0 },
+	{ BD_16, 48, FIT_RGB16, 0, 0, 0 },
+	{ BD_16, 64, FIT_RGBA16, 0, 0, 0 },
+	// 32-bit float, RGBF, RGBAF bitmap
+	{ BD_32F, 32, FIT_FLOAT, 0, 0, 0 },
+	{ BD_32F, 96, FIT_RGBF, 0, 0, 0 },
+	{ BD_32F, 128, FIT_RGBAF, 0, 0, 0 }
+};
+
+/**
+Scan input pixelInfo specifications and return the equivalent FreeImage info for loading
+ at param pixelInfo Image specifications
+ at param out_guid_format (returned value) output pixel format
+ at param image_type (returned value) Image type
+ at param bpp (returned value) Image bit depth
+ at param red_mask (returned value) RGB mask
+ at param green_mask (returned value) RGB mask
+ at param blue_mask (returned value) RGB mask
+ at return Returns WMP_errSuccess if successful, returns WMP_errFail otherwise
+ at see GetInputPixelFormat
+*/
+static ERR
+GetNativePixelFormat(const PKPixelInfo *pixelInfo, PKPixelFormatGUID *out_guid_format, FREE_IMAGE_TYPE *image_type, unsigned *bpp, unsigned *red_mask, unsigned *green_mask, unsigned *blue_mask) {
+	const unsigned s_FreeImagePixelInfoSize = (unsigned)sizeof(s_FreeImagePixelInfo) / sizeof(*(s_FreeImagePixelInfo));
+
+	for(unsigned i = 0; i < s_FreeImagePixelInfoSize; i++) {
+		if(pixelInfo->bdBitDepth == s_FreeImagePixelInfo[i].bdBitDepth) {
+			if(pixelInfo->cbitUnit == s_FreeImagePixelInfo[i].cbitUnit) {
+				// found ! now get dst image format specifications
+				memcpy(out_guid_format, pixelInfo->pGUIDPixFmt, sizeof(PKPixelFormatGUID));
+				*image_type = s_FreeImagePixelInfo[i].image_type;
+				*bpp = s_FreeImagePixelInfo[i].cbitUnit;
+				*red_mask	= s_FreeImagePixelInfo[i].red_mask;
+				*green_mask	= s_FreeImagePixelInfo[i].green_mask;
+				*blue_mask	= s_FreeImagePixelInfo[i].blue_mask;
+				return WMP_errSuccess;
+			}
+		}
+	}
+
+	// not found : need pixel format conversion
+	return WMP_errFail;
+}
+
+/**
+Scan input file guid format and return the equivalent FreeImage info & target guid format for loading
+ at param pDecoder Decoder handle
+ at param guid_format (returned value) Output pixel format
+ at param image_type (returned value) Image type
+ at param bpp (returned value) Image bit depth
+ at param red_mask (returned value) RGB mask
+ at param green_mask (returned value) RGB mask
+ at param blue_mask (returned value) RGB mask
+ at return Returns TRUE if successful, returns FALSE otherwise
+*/
+static ERR
+GetInputPixelFormat(PKImageDecode *pDecoder, PKPixelFormatGUID *guid_format, FREE_IMAGE_TYPE *image_type, unsigned *bpp, unsigned *red_mask, unsigned *green_mask, unsigned *blue_mask) {
+	ERR error_code = 0;		// error code as returned by the interface
+	PKPixelInfo pixelInfo;	// image specifications
+
+	try {		
+		// get input file pixel format ...
+		PKPixelFormatGUID pguidSourcePF;
+		error_code = pDecoder->GetPixelFormat(pDecoder, &pguidSourcePF);
+		JXR_CHECK(error_code);
+		pixelInfo.pGUIDPixFmt = &pguidSourcePF;
+		// ... check for a supported format and get the format specifications
+		error_code = PixelFormatLookup(&pixelInfo, LOOKUP_FORWARD);
+		JXR_CHECK(error_code);
+
+		// search for an equivalent native FreeImage format
+		error_code = GetNativePixelFormat(&pixelInfo, guid_format, image_type, bpp, red_mask, green_mask, blue_mask);
+
+		if(error_code != WMP_errSuccess) {
+			// try to find a suitable conversion function ...
+			const PKPixelFormatGUID *ppguidTargetPF = NULL;	// target pixel format
+			unsigned iIndex = 0;	// first available conversion function
+			do {
+				error_code = PKFormatConverter_EnumConversions(&pguidSourcePF, iIndex, &ppguidTargetPF);
+				if(error_code == WMP_errSuccess) {
+					// found a conversion function, is the converted format a native FreeImage format ?
+					pixelInfo.pGUIDPixFmt = ppguidTargetPF;
+					error_code = PixelFormatLookup(&pixelInfo, LOOKUP_FORWARD);
+					JXR_CHECK(error_code);
+					error_code = GetNativePixelFormat(&pixelInfo, guid_format, image_type, bpp, red_mask, green_mask, blue_mask);
+					if(error_code == WMP_errSuccess) {
+						break;
+					}
+				}
+				// try next conversion function
+				iIndex++;
+			} while(error_code != WMP_errIndexNotFound);
+
+		}
+
+		return (error_code == WMP_errSuccess) ? WMP_errSuccess : WMP_errUnsupportedFormat;
+
+	} catch(...) {
+		return error_code;
+	}
+}
+
+// --------------------------------------------------------------------------
+
+/**
+Scan input dib format and return the equivalent PKPixelFormatGUID format for saving
+ at param dib Image to be saved
+ at param guid_format (returned value) GUID format
+ at param bHasAlpha (returned value) TRUE if an alpha layer is present
+ at return Returns TRUE if successful, returns FALSE otherwise
+*/
+static ERR
+GetOutputPixelFormat(FIBITMAP *dib, PKPixelFormatGUID *guid_format, BOOL *bHasAlpha) {
+	const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
+	const unsigned bpp = FreeImage_GetBPP(dib);
+	const FREE_IMAGE_COLOR_TYPE color_type = FreeImage_GetColorType(dib);
+
+	*guid_format = GUID_PKPixelFormatDontCare;
+	*bHasAlpha = FALSE;
+
+	switch(image_type) {
+		case FIT_BITMAP:	// standard image	: 1-, 4-, 8-, 16-, 24-, 32-bit
+			switch(bpp) {
+				case 1:
+					// assume FIC_MINISBLACK
+					if(color_type == FIC_MINISBLACK) {
+						*guid_format = GUID_PKPixelFormatBlackWhite;
+					}
+					break;
+				case 8:
+					// assume FIC_MINISBLACK
+					if(color_type == FIC_MINISBLACK) {
+						*guid_format = GUID_PKPixelFormat8bppGray;
+					}
+					break;
+				case 16:
+					if ((FreeImage_GetRedMask(dib) == FI16_565_RED_MASK) && (FreeImage_GetGreenMask(dib) == FI16_565_GREEN_MASK) && (FreeImage_GetBlueMask(dib) == FI16_565_BLUE_MASK)) {
+						*guid_format = GUID_PKPixelFormat16bppRGB565;
+					} else {
+						// includes case where all the masks are 0
+						*guid_format = GUID_PKPixelFormat16bppRGB555;
+					}
+					break;
+#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
+				case 24:
+					*guid_format = GUID_PKPixelFormat24bppBGR;
+					break;
+				case 32:
+					*guid_format = GUID_PKPixelFormat32bppBGRA;
+					*bHasAlpha = TRUE;
+					break;
+#elif FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB
+				case 24:
+					*guid_format = GUID_PKPixelFormat24bppRGB;
+					break;
+				case 32:
+					*guid_format = GUID_PKPixelFormat32bppRGBA;
+					*bHasAlpha = TRUE;
+					break;
+#endif
+				case 4:
+				default:
+					// not supported
+					break;
+			}
+			break;
+		case FIT_UINT16:	// array of unsigned short	: unsigned 16-bit
+			*guid_format = GUID_PKPixelFormat16bppGray;
+			break;
+		case FIT_FLOAT:		// array of float			: 32-bit IEEE floating point
+			*guid_format = GUID_PKPixelFormat32bppGrayFloat;
+			break;
+		case FIT_RGB16:		// 48-bit RGB image			: 3 x 16-bit
+			*guid_format = GUID_PKPixelFormat48bppRGB;
+			break;
+		case FIT_RGBA16:	// 64-bit RGBA image		: 4 x 16-bit
+			*guid_format = GUID_PKPixelFormat64bppRGBA;
+			*bHasAlpha = TRUE;
+			break;
+		case FIT_RGBF:		// 96-bit RGB float image	: 3 x 32-bit IEEE floating point
+			*guid_format = GUID_PKPixelFormat96bppRGBFloat;
+			break;
+		case FIT_RGBAF:		// 128-bit RGBA float image	: 4 x 32-bit IEEE floating point
+			*guid_format = GUID_PKPixelFormat128bppRGBAFloat;
+			*bHasAlpha = TRUE;
+			break;
+
+		case FIT_INT16:		// array of short			: signed 16-bit
+		case FIT_UINT32:	// array of unsigned long	: unsigned 32-bit
+		case FIT_INT32:		// array of long			: signed 32-bit
+		case FIT_DOUBLE:	// array of double			: 64-bit IEEE floating point
+		case FIT_COMPLEX:	// array of FICOMPLEX		: 2 x 64-bit IEEE floating point
+
+		default:
+			// unsupported format
+			break;
+	}
+
+	return (*guid_format != GUID_PKPixelFormatDontCare) ? WMP_errSuccess : WMP_errUnsupportedFormat;
+}
+
+// ==========================================================
+// Metadata loading
+// ==========================================================
+
+/**
+Read a JPEG-XR IFD as a buffer
+ at see ReadMetadata
+*/
+static ERR
+ReadProfile(WMPStream* pStream, unsigned cbByteCount, unsigned uOffset, BYTE **ppbProfile) {
+	// (re-)allocate profile buffer
+	BYTE *pbProfile = *ppbProfile;
+	pbProfile = (BYTE*)realloc(pbProfile, cbByteCount);
+	if(!pbProfile) {
+		return WMP_errOutOfMemory;
+	}
+	// read the profile
+	if(WMP_errSuccess == pStream->SetPos(pStream, uOffset)) {
+		if(WMP_errSuccess == pStream->Read(pStream, pbProfile, cbByteCount)) {
+			*ppbProfile = pbProfile;
+			return WMP_errSuccess;
+		}
+	}
+	return WMP_errFileIO;
+}
+
+/**
+Convert a DPKPROPVARIANT to a FITAG, then store the tag as FIMD_EXIF_MAIN
+ at see ReadDescriptiveMetadata
+*/
+static BOOL
+ReadPropVariant(WORD tag_id, const DPKPROPVARIANT & varSrc, FIBITMAP *dib) {
+	DWORD dwSize;
+
+	if(varSrc.vt == DPKVT_EMPTY) {
+		return FALSE;
+	}
+
+	// get the tag key
+	TagLib& s = TagLib::instance();
+	const char *key = s.getTagFieldName(TagLib::EXIF_MAIN, tag_id, NULL);
+	if(!key) {
+		return FALSE;
+	}
+
+	// create a tag
+	FITAG *tag = FreeImage_CreateTag();
+	if(tag) {
+		// set tag ID
+		FreeImage_SetTagID(tag, tag_id);
+		// set tag type, count, length and value
+		switch (varSrc.vt) {
+			case DPKVT_LPSTR:
+				FreeImage_SetTagType(tag, FIDT_ASCII);
+				dwSize = (DWORD)strlen(varSrc.VT.pszVal) + 1;
+				FreeImage_SetTagCount(tag, dwSize);
+				FreeImage_SetTagLength(tag, dwSize);
+				FreeImage_SetTagValue(tag, varSrc.VT.pszVal);
+				break;
+			
+			case DPKVT_LPWSTR:
+				FreeImage_SetTagType(tag, FIDT_UNDEFINED);
+				dwSize = (DWORD)(sizeof(U16) * (wcslen((wchar_t *) varSrc.VT.pwszVal) + 1)); // +1 for NULL term
+				FreeImage_SetTagCount(tag, dwSize);
+				FreeImage_SetTagLength(tag, dwSize);
+				FreeImage_SetTagValue(tag, varSrc.VT.pwszVal);
+				break;
+	            
+			case DPKVT_UI2:
+				FreeImage_SetTagType(tag, FIDT_SHORT);
+				FreeImage_SetTagCount(tag, 1);
+				FreeImage_SetTagLength(tag, 2);
+				FreeImage_SetTagValue(tag, &varSrc.VT.uiVal);
+				break;
+
+			case DPKVT_UI4:
+				FreeImage_SetTagType(tag, FIDT_LONG);
+				FreeImage_SetTagCount(tag, 1);
+				FreeImage_SetTagLength(tag, 4);
+				FreeImage_SetTagValue(tag, &varSrc.VT.ulVal);
+				break;
+
+			default:
+				assert(FALSE); // This case is not handled
+				break;
+		}
+		// get the tag desctiption
+		const char *description = s.getTagDescription(TagLib::EXIF_MAIN, tag_id);
+		FreeImage_SetTagDescription(tag, description);
+
+		// store the tag
+		FreeImage_SetMetadata(FIMD_EXIF_MAIN, dib, key, tag);
+
+		FreeImage_DeleteTag(tag);
+	}
+	return TRUE;
+}
+
+/**
+Read JPEG-XR descriptive metadata and store as EXIF_MAIN metadata
+ at see ReadPropVariant
+*/
+static ERR
+ReadDescriptiveMetadata(PKImageDecode *pID, FIBITMAP *dib) {
+	// get Exif TIFF metadata
+	const DESCRIPTIVEMETADATA *pDescMetadata = &pID->WMP.sDescMetadata;
+	// convert metadata to FITAG and store into the EXIF_MAIN metadata model
+	ReadPropVariant(WMP_tagImageDescription, pDescMetadata->pvarImageDescription, dib);
+	ReadPropVariant(WMP_tagCameraMake, pDescMetadata->pvarCameraMake, dib);
+	ReadPropVariant(WMP_tagCameraModel, pDescMetadata->pvarCameraModel, dib);
+	ReadPropVariant(WMP_tagSoftware, pDescMetadata->pvarSoftware, dib);
+	ReadPropVariant(WMP_tagDateTime, pDescMetadata->pvarDateTime, dib);
+	ReadPropVariant(WMP_tagArtist, pDescMetadata->pvarArtist, dib);
+	ReadPropVariant(WMP_tagCopyright, pDescMetadata->pvarCopyright, dib);
+	ReadPropVariant(WMP_tagRatingStars, pDescMetadata->pvarRatingStars, dib);
+	ReadPropVariant(WMP_tagRatingValue, pDescMetadata->pvarRatingValue, dib);
+	ReadPropVariant(WMP_tagCaption, pDescMetadata->pvarCaption, dib);
+	ReadPropVariant(WMP_tagDocumentName, pDescMetadata->pvarDocumentName, dib);
+	ReadPropVariant(WMP_tagPageName, pDescMetadata->pvarPageName, dib);
+	ReadPropVariant(WMP_tagPageNumber, pDescMetadata->pvarPageNumber, dib);
+	ReadPropVariant(WMP_tagHostComputer, pDescMetadata->pvarHostComputer, dib);
+	return WMP_errSuccess;
+}
+
+/**
+Read ICC, XMP, Exif, Exif-GPS, IPTC, descriptive (i.e. Exif-TIFF) metadata
+ at see ReadProfile, ReadDescriptiveMetadata
+*/
+static ERR
+ReadMetadata(PKImageDecode *pID, FIBITMAP *dib) {
+	ERR error_code = 0;		// error code as returned by the interface
+	size_t currentPos = 0;	// current stream position
+	
+	WMPStream *pStream = pID->pStream;
+	WmpDEMisc *wmiDEMisc = &pID->WMP.wmiDEMisc;
+	BYTE *pbProfile = NULL;
+
+	try {
+		// save current position
+		error_code = pStream->GetPos(pStream, &currentPos);
+		JXR_CHECK(error_code);
+
+		// ICC profile
+		if(0 != wmiDEMisc->uColorProfileByteCount) {
+			unsigned cbByteCount = wmiDEMisc->uColorProfileByteCount;
+			unsigned uOffset = wmiDEMisc->uColorProfileOffset;
+			error_code = ReadProfile(pStream, cbByteCount, uOffset, &pbProfile);
+			JXR_CHECK(error_code);
+			FreeImage_CreateICCProfile(dib, pbProfile, cbByteCount);
+		}
+
+		// XMP metadata
+		if(0 != wmiDEMisc->uXMPMetadataByteCount) {
+			unsigned cbByteCount = wmiDEMisc->uXMPMetadataByteCount;
+			unsigned uOffset = wmiDEMisc->uXMPMetadataOffset;
+			error_code = ReadProfile(pStream, cbByteCount, uOffset, &pbProfile);
+			JXR_CHECK(error_code);
+			// store the tag as XMP
+			FITAG *tag = FreeImage_CreateTag();
+			if(tag) {
+				FreeImage_SetTagLength(tag, cbByteCount);
+				FreeImage_SetTagCount(tag, cbByteCount);
+				FreeImage_SetTagType(tag, FIDT_ASCII);
+				FreeImage_SetTagValue(tag, pbProfile);
+				FreeImage_SetTagKey(tag, g_TagLib_XMPFieldName);
+				FreeImage_SetMetadata(FIMD_XMP, dib, FreeImage_GetTagKey(tag), tag);
+				FreeImage_DeleteTag(tag);
+			}
+		}
+
+		// IPTC metadata
+		if(0 != wmiDEMisc->uIPTCNAAMetadataByteCount) {
+			unsigned cbByteCount = wmiDEMisc->uIPTCNAAMetadataByteCount;
+			unsigned uOffset = wmiDEMisc->uIPTCNAAMetadataOffset;
+			error_code = ReadProfile(pStream, cbByteCount, uOffset, &pbProfile);
+			JXR_CHECK(error_code);
+			// decode the IPTC profile
+			read_iptc_profile(dib, pbProfile, cbByteCount);
+		}
+
+		// Exif metadata
+		if(0 != wmiDEMisc->uEXIFMetadataByteCount) {
+			unsigned cbByteCount = wmiDEMisc->uEXIFMetadataByteCount;
+			unsigned uOffset = wmiDEMisc->uEXIFMetadataOffset;
+			error_code = ReadProfile(pStream, cbByteCount, uOffset, &pbProfile);
+			JXR_CHECK(error_code);
+			// decode the Exif profile
+			jpegxr_read_exif_profile(dib, pbProfile, cbByteCount, uOffset);
+		}
+
+		// Exif-GPS metadata
+		if(0 != wmiDEMisc->uGPSInfoMetadataByteCount) {
+			unsigned cbByteCount = wmiDEMisc->uGPSInfoMetadataByteCount;
+			unsigned uOffset = wmiDEMisc->uGPSInfoMetadataOffset;
+			error_code = ReadProfile(pStream, cbByteCount, uOffset, &pbProfile);
+			JXR_CHECK(error_code);
+			// decode the Exif-GPS profile
+			jpegxr_read_exif_gps_profile(dib, pbProfile, cbByteCount, uOffset);
+		}
+
+		// free profile buffer
+		free(pbProfile);
+		// restore initial position
+		error_code = pID->pStream->SetPos(pID->pStream, currentPos);
+		JXR_CHECK(error_code);
+
+		// as a LAST STEP, read descriptive metadata
+		// these metadata overwrite possible identical Exif-TIFF metadata 
+		// that could have been read inside the Exif IFD
+		
+		return ReadDescriptiveMetadata(pID, dib);
+
+	} catch(...) {
+		// free profile buffer
+		free(pbProfile);
+		if(currentPos) {
+			// restore initial position
+			pStream->SetPos(pStream, currentPos);
+		}
+		return error_code;
+	}
+}
+
+// ==========================================================
+// Metadata saving
+// ==========================================================
+
+/**
+Convert a FITAG (coming from FIMD_EXIF_MAIN) to a DPKPROPVARIANT.
+No allocation is needed here, the function just copy pointers when needed. 
+ at see WriteDescriptiveMetadata
+*/
+static BOOL
+WritePropVariant(FIBITMAP *dib, WORD tag_id, DPKPROPVARIANT & varDst) {
+	FITAG *tag = NULL;
+
+	TagLib& s = TagLib::instance();
+	
+	// clear output DPKPROPVARIANT
+	varDst.vt = DPKVT_EMPTY;
+
+	// given the tag id, get the tag key
+	const char *key = s.getTagFieldName(TagLib::EXIF_MAIN, tag_id, NULL);
+	// then, get the tag info
+	if(!FreeImage_GetMetadata(FIMD_EXIF_MAIN, dib, key, &tag)) {
+		return FALSE;
+	}
+
+	// set the tag value
+	switch(FreeImage_GetTagType(tag)) {
+		case FIDT_ASCII:
+			varDst.vt = DPKVT_LPSTR;
+			varDst.VT.pszVal = (char*)FreeImage_GetTagValue(tag);
+			break;
+		case FIDT_BYTE:
+		case FIDT_UNDEFINED:
+			varDst.vt = DPKVT_LPWSTR;
+			varDst.VT.pwszVal = (U16*)FreeImage_GetTagValue(tag);
+			break;
+		case FIDT_SHORT:
+			varDst.vt = DPKVT_UI2;
+			varDst.VT.uiVal = *((U16*)FreeImage_GetTagValue(tag));
+			break;
+		case FIDT_LONG:
+			varDst.vt = DPKVT_UI4;
+			varDst.VT.ulVal = *((U32*)FreeImage_GetTagValue(tag));
+			break;
+		default:
+			break;
+	}
+	
+	return TRUE;
+}
+
+/**
+Write EXIF_MAIN metadata to JPEG-XR descriptive metadata
+ at see WritePropVariant
+*/
+static ERR
+WriteDescriptiveMetadata(PKImageEncode *pIE, FIBITMAP *dib) {
+	ERR error_code = 0;		// error code as returned by the interface
+	DESCRIPTIVEMETADATA DescMetadata;
+
+	// fill the DESCRIPTIVEMETADATA structure (use pointers to arrays when needed)
+	WritePropVariant(dib, WMP_tagImageDescription, DescMetadata.pvarImageDescription);
+	WritePropVariant(dib, WMP_tagCameraMake, DescMetadata.pvarCameraMake);
+	WritePropVariant(dib, WMP_tagCameraModel, DescMetadata.pvarCameraModel);
+	WritePropVariant(dib, WMP_tagSoftware, DescMetadata.pvarSoftware);
+	WritePropVariant(dib, WMP_tagDateTime, DescMetadata.pvarDateTime);
+	WritePropVariant(dib, WMP_tagArtist, DescMetadata.pvarArtist);
+	WritePropVariant(dib, WMP_tagCopyright, DescMetadata.pvarCopyright);
+	WritePropVariant(dib, WMP_tagRatingStars, DescMetadata.pvarRatingStars);
+	WritePropVariant(dib, WMP_tagRatingValue, DescMetadata.pvarRatingValue);
+	WritePropVariant(dib, WMP_tagCaption, DescMetadata.pvarCaption);
+	WritePropVariant(dib, WMP_tagDocumentName, DescMetadata.pvarDocumentName);
+	WritePropVariant(dib, WMP_tagPageName, DescMetadata.pvarPageName);
+	WritePropVariant(dib, WMP_tagPageNumber, DescMetadata.pvarPageNumber);
+	WritePropVariant(dib, WMP_tagHostComputer, DescMetadata.pvarHostComputer);
+
+	// copy the structure to the encoder
+	error_code = pIE->SetDescriptiveMetadata(pIE, &DescMetadata);
+
+	// no need to free anything here
+	return error_code;
+}
+
+/**
+Write ICC, XMP, Exif, Exif-GPS, IPTC, descriptive (i.e. Exif-TIFF) metadata
+*/
+static ERR
+WriteMetadata(PKImageEncode *pIE, FIBITMAP *dib) {
+	ERR error_code = 0;		// error code as returned by the interface
+	BYTE *profile = NULL;
+	unsigned profile_size = 0;
+	
+	try {
+		// write ICC profile
+		{
+			FIICCPROFILE *iccProfile = FreeImage_GetICCProfile(dib);
+			if(iccProfile->data) {
+				error_code = pIE->SetColorContext(pIE, (U8*)iccProfile->data, iccProfile->size);
+				JXR_CHECK(error_code);
+			}
+		}
+		
+		// write descriptive metadata
+		if(FreeImage_GetMetadataCount(FIMD_EXIF_MAIN, dib)) {
+			error_code = WriteDescriptiveMetadata(pIE, dib);
+			JXR_CHECK(error_code);
+		}
+
+		// write IPTC metadata
+		if(FreeImage_GetMetadataCount(FIMD_IPTC, dib)) {
+			// create a binary profile
+			if(write_iptc_profile(dib, &profile, &profile_size)) {
+				// write the profile
+				error_code = PKImageEncode_SetIPTCNAAMetadata_WMP(pIE, profile, profile_size);
+				JXR_CHECK(error_code);
+				// release profile
+				free(profile);
+				profile = NULL;
+			}
+		}
+
+		// write XMP metadata
+		{
+			FITAG *tag_xmp = NULL;
+			if(FreeImage_GetMetadata(FIMD_XMP, dib, g_TagLib_XMPFieldName, &tag_xmp)) {
+				error_code = PKImageEncode_SetXMPMetadata_WMP(pIE, (BYTE*)FreeImage_GetTagValue(tag_xmp), FreeImage_GetTagLength(tag_xmp));
+				JXR_CHECK(error_code);
+			}
+		}
+
+		// write Exif metadata
+		{
+			if(tiff_get_ifd_profile(dib, FIMD_EXIF_EXIF, &profile, &profile_size)) {
+				error_code = PKImageEncode_SetEXIFMetadata_WMP(pIE, profile, profile_size);
+				JXR_CHECK(error_code);
+				// release profile
+				free(profile);
+				profile = NULL;
+			}
+		}
+
+		// write Exif GPS metadata
+		{
+			if(tiff_get_ifd_profile(dib, FIMD_EXIF_GPS, &profile, &profile_size)) {
+				error_code = PKImageEncode_SetGPSInfoMetadata_WMP(pIE, profile, profile_size);
+				JXR_CHECK(error_code);
+				// release profile
+				free(profile);
+				profile = NULL;
+			}
+		}
+
+		return WMP_errSuccess;
+
+	} catch(...) {
+		free(profile);
+		return error_code;
+	}
+}
+
+
+
+// ==========================================================
+// Quantization tables (Y, U, V, YHP, UHP, VHP), 
+// optimized for PSNR
+// ==========================================================
+
+static const int DPK_QPS_420[11][6] = {      // for 8 bit only
+    { 66, 65, 70, 72, 72, 77 },
+    { 59, 58, 63, 64, 63, 68 },
+    { 52, 51, 57, 56, 56, 61 },
+    { 48, 48, 54, 51, 50, 55 },
+    { 43, 44, 48, 46, 46, 49 },
+    { 37, 37, 42, 38, 38, 43 },
+    { 26, 28, 31, 27, 28, 31 },
+    { 16, 17, 22, 16, 17, 21 },
+    { 10, 11, 13, 10, 10, 13 },
+    {  5,  5,  6,  5,  5,  6 },
+    {  2,  2,  3,  2,  2,  2 }
+};
+
+static const int DPK_QPS_8[12][6] = {
+    { 67, 79, 86, 72, 90, 98 },
+    { 59, 74, 80, 64, 83, 89 },
+    { 53, 68, 75, 57, 76, 83 },
+    { 49, 64, 71, 53, 70, 77 },
+    { 45, 60, 67, 48, 67, 74 },
+    { 40, 56, 62, 42, 59, 66 },
+    { 33, 49, 55, 35, 51, 58 },
+    { 27, 44, 49, 28, 45, 50 },
+    { 20, 36, 42, 20, 38, 44 },
+    { 13, 27, 34, 13, 28, 34 },
+    {  7, 17, 21,  8, 17, 21 }, // Photoshop 100%
+    {  2,  5,  6,  2,  5,  6 }
+};
+
+static const int DPK_QPS_16[11][6] = {
+    { 197, 203, 210, 202, 207, 213 },
+    { 174, 188, 193, 180, 189, 196 },
+    { 152, 167, 173, 156, 169, 174 },
+    { 135, 152, 157, 137, 153, 158 },
+    { 119, 137, 141, 119, 138, 142 },
+    { 102, 120, 125, 100, 120, 124 },
+    {  82,  98, 104,  79,  98, 103 },
+    {  60,  76,  81,  58,  76,  81 },
+    {  39,  52,  58,  36,  52,  58 },
+    {  16,  27,  33,  14,  27,  33 },
+    {   5,   8,   9,   4,   7,   8 }
+};
+
+static const int DPK_QPS_16f[11][6] = {
+    { 148, 177, 171, 165, 187, 191 },
+    { 133, 155, 153, 147, 172, 181 },
+    { 114, 133, 138, 130, 157, 167 },
+    {  97, 118, 120, 109, 137, 144 },
+    {  76,  98, 103,  85, 115, 121 },
+    {  63,  86,  91,  62,  96,  99 },
+    {  46,  68,  71,  43,  73,  75 },
+    {  29,  48,  52,  27,  48,  51 },
+    {  16,  30,  35,  14,  29,  34 },
+    {   8,  14,  17,   7,  13,  17 },
+    {   3,   5,   7,   3,   5,   6 }
+};
+
+static const int DPK_QPS_32f[11][6] = {
+    { 194, 206, 209, 204, 211, 217 },
+    { 175, 187, 196, 186, 193, 205 },
+    { 157, 170, 177, 167, 180, 190 },
+    { 133, 152, 156, 144, 163, 168 },
+    { 116, 138, 142, 117, 143, 148 },
+    {  98, 120, 123,  96, 123, 126 },
+    {  80,  99, 102,  78,  99, 102 },
+    {  65,  79,  84,  63,  79,  84 },
+    {  48,  61,  67,  45,  60,  66 },
+    {  27,  41,  46,  24,  40,  45 },
+    {   3,  22,  24,   2,  21,  22 }
+};
+
+// ==========================================================
+// Plugin Implementation
+// ==========================================================
+
+static const char * DLL_CALLCONV
+Format() {
+	return "JPEG-XR";
+}
+
+static const char * DLL_CALLCONV
+Description() {
+	return "JPEG XR image format";
+}
+
+static const char * DLL_CALLCONV
+Extension() {
+	return "jxr,wdp,hdp";
+}
+
+static const char * DLL_CALLCONV
+RegExpr() {
+	return NULL;
+}
+
+static const char * DLL_CALLCONV
+MimeType() {
+	return "image/vnd.ms-photo";
+}
+
+static BOOL DLL_CALLCONV
+Validate(FreeImageIO *io, fi_handle handle) {
+	BYTE jxr_signature[3] = { 0x49, 0x49, 0xBC };
+	BYTE signature[3] = { 0, 0, 0 };
+
+	io->read_proc(&signature, 1, 3, handle);
+
+	return (memcmp(jxr_signature, signature, 3) == 0);
+}
+
+static BOOL DLL_CALLCONV
+SupportsExportDepth(int depth) {
+	return (
+		(depth == 1)  ||
+		(depth == 8)  ||
+		(depth == 16) ||
+		(depth == 24) || 
+		(depth == 32)
+		);
+}
+
+static BOOL DLL_CALLCONV 
+SupportsExportType(FREE_IMAGE_TYPE type) {
+	return (
+		(type == FIT_BITMAP) ||
+		(type == FIT_UINT16) ||
+		(type == FIT_RGB16)  ||
+		(type == FIT_RGBA16) ||
+		(type == FIT_FLOAT)  ||
+		(type == FIT_RGBF)   ||
+		(type == FIT_RGBAF)
+	);
+}
+
+static BOOL DLL_CALLCONV
+SupportsICCProfiles() {
+	return TRUE;
+}
+
+static BOOL DLL_CALLCONV
+SupportsNoPixels() {
+	return TRUE;
+}
+
+// ==========================================================
+//	Open & Close
+// ==========================================================
+
+static void * DLL_CALLCONV
+Open(FreeImageIO *io, fi_handle handle, BOOL read) {
+	WMPStream *pStream = NULL;	// stream interface
+	if(io && handle) {
+		// allocate the FreeImageIO stream wrapper
+		FreeImageJXRIO *jxr_io = (FreeImageJXRIO*)malloc(sizeof(FreeImageJXRIO));
+		if(jxr_io) {
+			jxr_io->io = io;
+			jxr_io->handle = handle;
+			// create a JXR stream wrapper
+			if(_jxr_io_Create(&pStream, jxr_io) != WMP_errSuccess) {
+				free(jxr_io);
+				return NULL;
+			}
+		}
+	}
+	return pStream;
+}
+
+static void DLL_CALLCONV
+Close(FreeImageIO *io, fi_handle handle, void *data) {
+	WMPStream *pStream = (WMPStream*)data;
+	if(pStream) {
+		// free the FreeImageIO stream wrapper
+		FreeImageJXRIO *jxr_io = (FreeImageJXRIO*)pStream->state.pvObj;
+		free(jxr_io);
+		// free the JXR stream wrapper
+		pStream->fMem = TRUE;
+		_jxr_io_Close(&pStream);
+	}
+}
+
+// ==========================================================
+//	Load
+// ==========================================================
+
+/**
+Set decoder parameters
+ at param pDecoder Decoder handle
+ at param flags FreeImage load flags
+*/
+static void 
+SetDecoderParameters(PKImageDecode *pDecoder, int flags) {
+	// load image & alpha for formats with alpha
+	pDecoder->WMP.wmiSCP.uAlphaMode = 2;
+	// more options to come ...
+}
+
+/**
+Copy or convert & copy decoded pixels into the dib
+ at param pDecoder Decoder handle
+ at param out_guid_format Target guid format
+ at param dib Output dib
+ at param width Image width
+ at param height Image height
+ at return Returns 0 if successful, returns ERR otherwise
+*/
+static ERR
+CopyPixels(PKImageDecode *pDecoder, PKPixelFormatGUID out_guid_format, FIBITMAP *dib, int width, int height) {
+	PKFormatConverter *pConverter = NULL;	// pixel format converter
+	ERR error_code = 0;	// error code as returned by the interface
+	BYTE *pb = NULL;	// local buffer used for pixel format conversion
+	
+	// image dimensions
+	const PKRect rect = {0, 0, width, height};
+
+	try {
+		// get input file pixel format ...
+		PKPixelFormatGUID in_guid_format;
+		error_code = pDecoder->GetPixelFormat(pDecoder, &in_guid_format);
+		JXR_CHECK(error_code);
+		
+		// is a format conversion needed ?
+
+		if(IsEqualGUID(out_guid_format, in_guid_format)) {
+			// no conversion, load bytes "as is" ...
+
+			// get a pointer to dst pixel data
+			BYTE *dib_bits = FreeImage_GetBits(dib);
+
+			// get dst pitch (count of BYTE for stride)
+			const unsigned cbStride = FreeImage_GetPitch(dib);			
+
+			// decode and copy bits to dst array
+			error_code = pDecoder->Copy(pDecoder, &rect, dib_bits, cbStride);
+			JXR_CHECK(error_code);		
+		}
+		else {
+			// we need to use the conversion API ...
+			
+			// allocate the pixel format converter
+			error_code = PKCodecFactory_CreateFormatConverter(&pConverter);
+			JXR_CHECK(error_code);
+			
+			// set the conversion function
+			error_code = pConverter->Initialize(pConverter, pDecoder, NULL, out_guid_format);
+			JXR_CHECK(error_code);
+			
+			// get the maximum stride
+			unsigned cbStride = 0;
+			{
+				PKPixelInfo pPIFrom;
+				PKPixelInfo pPITo;
+				
+				pPIFrom.pGUIDPixFmt = &in_guid_format;
+				error_code = PixelFormatLookup(&pPIFrom, LOOKUP_FORWARD);
+				JXR_CHECK(error_code);
+
+				pPITo.pGUIDPixFmt = &out_guid_format;
+				error_code = PixelFormatLookup(&pPITo, LOOKUP_FORWARD);
+				JXR_CHECK(error_code);
+
+				unsigned cbStrideFrom = ((pPIFrom.cbitUnit + 7) >> 3) * width;
+				unsigned cbStrideTo = ((pPITo.cbitUnit + 7) >> 3) * width;
+				cbStride = MAX(cbStrideFrom, cbStrideTo);
+			}
+
+			// allocate a local decoder / encoder buffer
+			error_code = PKAllocAligned((void **) &pb, cbStride * height, 128);
+			JXR_CHECK(error_code);
+
+			// copy / convert pixels
+			error_code = pConverter->Copy(pConverter, &rect, pb, cbStride);
+			JXR_CHECK(error_code);
+
+			// now copy pixels into the dib
+			const size_t line_size = FreeImage_GetLine(dib);
+			for(int y = 0; y < height; y++) {
+				BYTE *src_bits = (BYTE*)(pb + y * cbStride);
+				BYTE *dst_bits = (BYTE*)FreeImage_GetScanLine(dib, y);
+				memcpy(dst_bits, src_bits, line_size);
+			}
+			
+			// free the local buffer
+			PKFreeAligned((void **) &pb);
+
+			// free the pixel format converter
+			PKFormatConverter_Release(&pConverter);
+		}
+
+		// FreeImage DIB are upside-down relative to usual graphic conventions
+		FreeImage_FlipVertical(dib);
+
+		// post-processing ...
+		// -------------------
+
+		// swap RGB as needed
+
+#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
+		if(IsEqualGUID(out_guid_format, GUID_PKPixelFormat24bppRGB) || IsEqualGUID(out_guid_format, GUID_PKPixelFormat32bppRGB)) {
+			SwapRedBlue32(dib);
+		}
+#elif FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB
+		if(IsEqualGUID(out_guid_format, GUID_PKPixelFormat24bppBGR) || IsEqualGUID(out_guid_format, GUID_PKPixelFormat32bppBGR)) {
+			SwapRedBlue32(dib);
+		}
+#endif
+		
+		return WMP_errSuccess;
+
+	} catch(...) {
+		// free the local buffer
+		PKFreeAligned((void **) &pb);
+		// free the pixel format converter
+		PKFormatConverter_Release(&pConverter);
+
+		return error_code;
+	}
+}
+
+// --------------------------------------------------------------------------
+
+static FIBITMAP * DLL_CALLCONV
+Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
+	PKImageDecode *pDecoder = NULL;	// decoder interface
+	ERR error_code = 0;				// error code as returned by the interface
+	PKPixelFormatGUID guid_format;	// loaded pixel format (== input file pixel format if no conversion needed)
+	
+	FREE_IMAGE_TYPE image_type = FIT_UNKNOWN;	// input image type
+	unsigned bpp = 0;							// input image bit depth
+	FIBITMAP *dib = NULL;
+	
+	// get the I/O stream wrapper
+	WMPStream *pDecodeStream = (WMPStream*)data;
+
+	if(!handle || !pDecodeStream) {
+		return NULL;
+	}
+
+	BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS;
+
+	try {
+		int width, height;	// image dimensions (in pixels)
+
+		// create a JXR decoder interface and initialize function pointers with *_WMP functions
+		error_code = PKImageDecode_Create_WMP(&pDecoder);
+		JXR_CHECK(error_code);
+
+		// attach the stream to the decoder ...
+		// ... then read the image container and the metadata
+		error_code = pDecoder->Initialize(pDecoder, pDecodeStream);
+		JXR_CHECK(error_code);
+
+		// set decoder parameters
+		SetDecoderParameters(pDecoder, flags);
+
+		// get dst image format specifications
+		unsigned red_mask = 0, green_mask = 0, blue_mask = 0;
+		error_code = GetInputPixelFormat(pDecoder, &guid_format, &image_type, &bpp, &red_mask, &green_mask, &blue_mask);
+		JXR_CHECK(error_code);
+
+		// get image dimensions
+		pDecoder->GetSize(pDecoder, &width, &height);
+
+		// allocate dst image
+		{			
+			dib = FreeImage_AllocateHeaderT(header_only, image_type, width, height, bpp, red_mask, green_mask, blue_mask);
+			if(!dib) {
+				throw FI_MSG_ERROR_DIB_MEMORY;
+			}
+			if(FreeImage_GetBPP(dib) == 1) {
+				// BD_1 - build a FIC_MINISBLACK palette
+				RGBQUAD *pal = FreeImage_GetPalette(dib);
+				pal[0].rgbRed = pal[0].rgbGreen = pal[0].rgbBlue = 0;
+				pal[1].rgbRed = pal[1].rgbGreen = pal[1].rgbBlue = 255;
+			}
+		}
+
+		// get image resolution
+		{
+			float resX, resY;	// image resolution (in dots per inch)
+			// convert from English units, i.e. dots per inch to universal units, i.e. dots per meter
+			pDecoder->GetResolution(pDecoder, &resX, &resY);
+			FreeImage_SetDotsPerMeterX(dib, (unsigned)(resX / 0.0254F + 0.5F));
+			FreeImage_SetDotsPerMeterY(dib, (unsigned)(resY / 0.0254F + 0.5F));
+		}
+
+		// get metadata & ICC profile
+		error_code = ReadMetadata(pDecoder, dib);
+		JXR_CHECK(error_code);
+
+		if(header_only) {
+			// header only mode ...
+			
+			// free the decoder
+			pDecoder->Release(&pDecoder);
+			assert(pDecoder == NULL);
+
+			return dib;
+		}
+		
+		// copy pixels into the dib, perform pixel conversion if needed
+		error_code = CopyPixels(pDecoder, guid_format, dib, width, height);
+		JXR_CHECK(error_code);
+
+		// free the decoder
+		pDecoder->Release(&pDecoder);
+		assert(pDecoder == NULL);
+
+		return dib;
+
+	} catch (const char *message) {
+		// unload the dib
+		FreeImage_Unload(dib);
+		// free the decoder
+		pDecoder->Release(&pDecoder);
+
+		if(NULL != message) {
+			FreeImage_OutputMessageProc(s_format_id, message);
+		}
+	}
+
+	return NULL;
+}
+
+// ==========================================================
+//	Save
+// ==========================================================
+
+/**
+Configure compression parameters
+
+ImageQuality  Q (BD==1)  Q (BD==8)   Q (BD==16)  Q (BD==32F) Subsample   Overlap
+[0.0, 0.4]    8-IQ*5     (see table) (see table) (see table) 4:4:4       2
+(0.4, 0.8)    8-IQ*5     (see table) (see table) (see table) 4:4:4       1
+[0.8, 1.0)    8-IQ*5     (see table) (see table) (see table) 4:4:4       1
+[1.0, 1.0]    1          1           1           1           4:4:4       0
+
+ at param wmiSCP Encoder parameters
+ at param pixelInfo Image specifications
+ at param fltImageQuality Image output quality in [0..1), 1 means lossless
+*/
+static void 
+SetCompression(CWMIStrCodecParam *wmiSCP, const PKPixelInfo *pixelInfo, float fltImageQuality) {
+    if(fltImageQuality < 1.0F) {
+        // overlap
+		if(fltImageQuality >= 0.5F) {
+			wmiSCP->olOverlap = OL_ONE;
+		} else {
+			wmiSCP->olOverlap = OL_TWO;
+		}
+		// chroma sub-sampling
+		if(fltImageQuality >= 0.5F || pixelInfo->uBitsPerSample > 8) {
+			wmiSCP->cfColorFormat = YUV_444;
+		} else {
+			wmiSCP->cfColorFormat = YUV_420;
+		}
+
+	    // bit depth
+		if(pixelInfo->bdBitDepth == BD_1) {
+			wmiSCP->uiDefaultQPIndex = (U8)(8 - 5.0F * fltImageQuality + 0.5F);
+		}
+		else {
+			// remap [0.8, 0.866, 0.933, 1.0] to [0.8, 0.9, 1.0, 1.1]
+            // to use 8-bit DPK QP table (0.933 == Photoshop JPEG 100)
+            if(fltImageQuality > 0.8F && pixelInfo->bdBitDepth == BD_8 && wmiSCP->cfColorFormat != YUV_420 && wmiSCP->cfColorFormat != YUV_422) {
+				fltImageQuality = 0.8F + (fltImageQuality - 0.8F) * 1.5F;
+			}
+
+            const int qi = (int) (10.0F * fltImageQuality);
+            const float qf = 10.0F * fltImageQuality - (float)qi;
+			
+			const int *pQPs = 
+				(wmiSCP->cfColorFormat == YUV_420 || wmiSCP->cfColorFormat == YUV_422) ?
+				DPK_QPS_420[qi] :
+				(pixelInfo->bdBitDepth == BD_8 ? DPK_QPS_8[qi] :
+				(pixelInfo->bdBitDepth == BD_16 ? DPK_QPS_16[qi] :
+				(pixelInfo->bdBitDepth == BD_16F ? DPK_QPS_16f[qi] :
+				DPK_QPS_32f[qi])));
+				
+			wmiSCP->uiDefaultQPIndex = (U8) (0.5F + (float) pQPs[0] * (1.0F - qf) + (float) (pQPs + 6)[0] * qf);
+			wmiSCP->uiDefaultQPIndexU = (U8) (0.5F + (float) pQPs[1] * (1.0F - qf) + (float) (pQPs + 6)[1] * qf);
+			wmiSCP->uiDefaultQPIndexV = (U8) (0.5F + (float) pQPs[2] * (1.0F - qf) + (float) (pQPs + 6)[2] * qf);
+            wmiSCP->uiDefaultQPIndexYHP = (U8) (0.5F + (float) pQPs[3] * (1.0F - qf) + (float) (pQPs + 6)[3] * qf);
+			wmiSCP->uiDefaultQPIndexUHP = (U8) (0.5F + (float) pQPs[4] * (1.0F - qf) + (float) (pQPs + 6)[4] * qf);
+			wmiSCP->uiDefaultQPIndexVHP = (U8) (0.5F + (float) pQPs[5] * (1.0F - qf) + (float) (pQPs + 6)[5] * qf);
+		}
+	} // fltImageQuality < 1.0F
+    else {
+		// lossless mode
+		wmiSCP->uiDefaultQPIndex = 1;
+	}
+}
+
+/**
+Set encoder parameters
+ at param wmiSCP Encoder parameters
+ at param pixelInfo Image specifications
+ at param flags FreeImage save flags
+ at param bHasAlpha TRUE if an alpha layer is present
+*/
+static void 
+SetEncoderParameters(CWMIStrCodecParam *wmiSCP, const PKPixelInfo *pixelInfo, int flags, BOOL bHasAlpha) {
+	float fltImageQuality = 1.0F;
+
+	// all values have been set to zero by the API
+	// update default values for some attributes
+    wmiSCP->cfColorFormat = YUV_444;		// color format
+    wmiSCP->bdBitDepth = BD_LONG;			// internal bit depth
+    wmiSCP->bfBitstreamFormat = SPATIAL;	// compressed image data in spatial order
+    wmiSCP->bProgressiveMode = FALSE;		// sequential mode
+    wmiSCP->olOverlap = OL_ONE;				// single level overlap processing 
+	wmiSCP->cNumOfSliceMinus1H = 0;			// # of horizontal slices
+	wmiSCP->cNumOfSliceMinus1V = 0;			// # of vertical slices
+    wmiSCP->sbSubband = SB_ALL;				// keep all subbands
+    wmiSCP->uAlphaMode = 0;					// 0:no alpha 1: alpha only else: something + alpha 
+    wmiSCP->uiDefaultQPIndex = 1;			// quantization for grey or rgb layer(s), 1: lossless
+    wmiSCP->uiDefaultQPIndexAlpha = 1;		// quantization for alpha layer, 1: lossless
+
+	// process the flags
+	// -----------------
+
+	// progressive mode
+	if((flags & JXR_PROGRESSIVE) == JXR_PROGRESSIVE) {
+		// turn on progressive mode (instead of sequential mode)
+		wmiSCP->bProgressiveMode = TRUE;
+	}
+
+	// quality in [0.01 - 1.0), 1.0 means lossless - default is 0.80
+	int quality = flags & 0x7F;
+	if(quality == 0) {
+		// defaut to 0.80
+		fltImageQuality = 0.8F;
+	} else if((flags & JXR_LOSSLESS) == JXR_LOSSLESS) {
+		fltImageQuality = 1.0F;
+	} else {
+		quality = (quality >= 100) ? 100 : quality;
+		fltImageQuality = quality / 100.0F;
+	}
+	SetCompression(wmiSCP, pixelInfo, fltImageQuality);
+
+	// alpha compression
+	if(bHasAlpha) {
+		wmiSCP->uAlphaMode = 2;	// encode with a planar alpha channel
+	}
+}
+
+// --------------------------------------------------------------------------
+
+static BOOL DLL_CALLCONV
+Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void *data) {
+	BOOL bIsFlipped = FALSE;		// FreeImage DIB are upside-down relative to usual graphic conventions
+	PKPixelFormatGUID guid_format;	// image format
+	PKPixelInfo pixelInfo;			// image specifications
+	BOOL bHasAlpha = FALSE;			// is alpha layer present ?
+
+	PKImageEncode *pEncoder = NULL;		// encoder interface
+	ERR error_code = 0;					// error code as returned by the interface
+
+	// get the I/O stream wrapper
+	WMPStream *pEncodeStream = (WMPStream*)data;
+
+	if(!dib || !handle || !pEncodeStream) {
+		return FALSE;
+	}
+
+	try {
+		// get image dimensions
+		unsigned width = FreeImage_GetWidth(dib);
+		unsigned height = FreeImage_GetHeight(dib);
+
+		// check JPEG-XR limits
+		if((width < MB_WIDTH_PIXEL) || (height < MB_HEIGHT_PIXEL)) {
+			FreeImage_OutputMessageProc(s_format_id, "Unsupported image size: width x height = %d x %d", width, height);
+			throw (const char*)NULL;
+		}
+
+		// get output pixel format
+		error_code = GetOutputPixelFormat(dib, &guid_format, &bHasAlpha);
+		JXR_CHECK(error_code);
+		pixelInfo.pGUIDPixFmt = &guid_format;
+		error_code = PixelFormatLookup(&pixelInfo, LOOKUP_FORWARD);
+		JXR_CHECK(error_code);
+
+		// create a JXR encoder interface and initialize function pointers with *_WMP functions
+		error_code = PKImageEncode_Create_WMP(&pEncoder);
+		JXR_CHECK(error_code);
+
+		// attach the stream to the encoder and set all encoder parameters to zero ...
+		error_code = pEncoder->Initialize(pEncoder, pEncodeStream, &pEncoder->WMP.wmiSCP, sizeof(CWMIStrCodecParam));
+		JXR_CHECK(error_code);
+
+		// ... then configure the encoder
+		SetEncoderParameters(&pEncoder->WMP.wmiSCP, &pixelInfo, flags, bHasAlpha);
+
+		// set pixel format
+		pEncoder->SetPixelFormat(pEncoder, guid_format);
+
+		// set image size
+		pEncoder->SetSize(pEncoder, width, height);
+		
+		// set resolution (convert from universal units to English units)
+		float resX = (float)(unsigned)(0.5F + 0.0254F * FreeImage_GetDotsPerMeterX(dib));
+		float resY = (float)(unsigned)(0.5F + 0.0254F * FreeImage_GetDotsPerMeterY(dib));
+		pEncoder->SetResolution(pEncoder, resX, resY);
+
+		// set metadata
+		WriteMetadata(pEncoder, dib);
+
+		// write metadata & pixels
+		// -----------------------
+
+		// dib coordinates are upside-down relative to usual conventions
+		bIsFlipped = FreeImage_FlipVertical(dib);
+
+		// get a pointer to dst pixel data
+		BYTE *dib_bits = FreeImage_GetBits(dib);
+
+		// get dst pitch (count of BYTE for stride)
+		const unsigned cbStride = FreeImage_GetPitch(dib);
+
+		// write metadata + pixels on output
+		error_code = pEncoder->WritePixels(pEncoder, height, dib_bits, cbStride);
+		JXR_CHECK(error_code);
+
+		// recover dib coordinates
+		FreeImage_FlipVertical(dib);
+
+		// free the encoder
+		pEncoder->Release(&pEncoder);
+		assert(pEncoder == NULL);
+		
+		return TRUE;
+
+	} catch (const char *message) {
+		if(bIsFlipped) {
+			// recover dib coordinates
+			FreeImage_FlipVertical(dib);
+		}
+		if(pEncoder) {
+			// free the encoder
+			pEncoder->Release(&pEncoder);
+			assert(pEncoder == NULL);
+		}
+		if(NULL != message) {
+			FreeImage_OutputMessageProc(s_format_id, message);
+		}
+	}
+
+	return FALSE;
+}
+
+// ==========================================================
+//	 Init
+// ==========================================================
+
+void DLL_CALLCONV
+InitJXR(Plugin *plugin, int format_id) {
+	s_format_id = format_id;
+
+	plugin->format_proc = Format;
+	plugin->description_proc = Description;
+	plugin->extension_proc = Extension;
+	plugin->regexpr_proc = RegExpr;
+	plugin->open_proc = Open;
+	plugin->close_proc = Close;
+	plugin->pagecount_proc = NULL;
+	plugin->pagecapability_proc = NULL;
+	plugin->load_proc = Load;
+	plugin->save_proc = Save;
+	plugin->validate_proc = Validate;
+	plugin->mime_proc = MimeType;
+	plugin->supports_export_bpp_proc = SupportsExportDepth;
+	plugin->supports_export_type_proc = SupportsExportType;
+	plugin->supports_icc_profiles_proc = SupportsICCProfiles;
+	plugin->supports_no_pixels_proc = SupportsNoPixels;
+}
+
diff --git a/Source/FreeImage/PluginPFM.cpp b/Source/FreeImage/PluginPFM.cpp
index 231e8ba..ea3c46b 100644
--- a/Source/FreeImage/PluginPFM.cpp
+++ b/Source/FreeImage/PluginPFM.cpp
@@ -63,11 +63,13 @@ Get an integer value from the actual position pointed by handle
 static int
 pfm_get_int(FreeImageIO *io, fi_handle handle) {
     char c = 0;
-	BOOL firstchar;
+	BOOL bFirstChar;
 
     // skip forward to start of next number
 
-    if(!io->read_proc(&c, 1, 1, handle)) throw FI_MSG_ERROR_PARSING;
+	if(!io->read_proc(&c, 1, 1, handle)) {
+		throw FI_MSG_ERROR_PARSING;
+	}
 
     while (1) {
         // eat comments
@@ -75,15 +77,16 @@ pfm_get_int(FreeImageIO *io, fi_handle handle) {
         if (c == '#') {
 			// if we're at a comment, read to end of line
 
-            firstchar = TRUE;
+            bFirstChar = TRUE;
 
             while (1) {
-				if(!io->read_proc(&c, 1, 1, handle)) throw FI_MSG_ERROR_PARSING;
+				if(!io->read_proc(&c, 1, 1, handle)) {
+					throw FI_MSG_ERROR_PARSING;
+				}
 
-				if (firstchar && c == ' ') {
+				if (bFirstChar && c == ' ') {
 					// loop off 1 sp after #
-
-					firstchar = FALSE;
+					bFirstChar = FALSE;
 				} else if (c == '\n') {
 					break;
 				}
@@ -92,11 +95,12 @@ pfm_get_int(FreeImageIO *io, fi_handle handle) {
 
         if (c >= '0' && c <='9') {
 			// we've found what we were looking for
-
             break;
 		}
 
-        if(!io->read_proc(&c, 1, 1, handle)) throw FI_MSG_ERROR_PARSING;
+		if(!io->read_proc(&c, 1, 1, handle)) {
+			throw FI_MSG_ERROR_PARSING;
+		}
     }
 
     // we're at the start of a number, continue until we hit a non-number
@@ -106,10 +110,13 @@ pfm_get_int(FreeImageIO *io, fi_handle handle) {
     while (1) {
         i = (i * 10) + (c - '0');
 
-        if(!io->read_proc(&c, 1, 1, handle)) throw FI_MSG_ERROR_PARSING;
+		if(!io->read_proc(&c, 1, 1, handle)) {
+			throw FI_MSG_ERROR_PARSING;
+		}
 
-        if (c < '0' || c > '9')
-            break;
+		if (c < '0' || c > '9') {
+			break;
+		}
     }
 
     return i;
diff --git a/Source/FreeImage/PluginPICT.cpp b/Source/FreeImage/PluginPICT.cpp
index 99958a4..371056d 100644
--- a/Source/FreeImage/PluginPICT.cpp
+++ b/Source/FreeImage/PluginPICT.cpp
@@ -82,21 +82,21 @@ static const int outputMessageSize = 256;
 // Internal functions
 // ==========================================================
 
-static unsigned
+static BYTE
 Read8(FreeImageIO *io, fi_handle handle) {
-	unsigned char i = 0;
+	BYTE i = 0;
 	io->read_proc(&i, 1, 1, handle);
 	return i;
 }
 
-static unsigned
+static WORD
 Read16(FreeImageIO *io, fi_handle handle) {
 	// reads a two-byte big-endian integer from the given file and returns its value.
 	// assumes unsigned.
 	
 	unsigned hi = Read8(io, handle);
 	unsigned lo = Read8(io, handle);
-	return lo + (hi << 8);
+	return (WORD)(lo + (hi << 8));
 }
 
 static unsigned
@@ -388,7 +388,7 @@ ReadColorTable( FreeImageIO *io, fi_handle handle, WORD* pNumColors, RGBQUAD* pP
 			// The indicies in a device colour table are bogus and
 			// usually == 0, so I assume we allocate up the list of
 			// colours in order.
-			val = i;
+			val = (WORD)i;
 		}
 		if (val >= numColors) {
 			throw "pixel value greater than color table size.";
@@ -416,7 +416,7 @@ SkipBits( FreeImageIO *io, fi_handle handle, MacRect* bounds, WORD rowBytes, int
 	if (pixelSize <= 8) {
 		rowBytes &= 0x7fff;
 	}
-	pixwidth = width;
+	pixwidth = (WORD)width;
 	
 	if (pixelSize == 16) {
 		pixwidth *= 2;
@@ -541,6 +541,7 @@ expandBuf8( FreeImageIO *io, fi_handle handle, int width, int bpp, BYTE* dst )
 
 static BYTE* 
 UnpackPictRow( FreeImageIO *io, fi_handle handle, BYTE* pLineBuf, int width, int rowBytes, int srcBytes ) {	
+
 	if (rowBytes < 8) { // Ah-ha!  The bits aren't actually packed.  This will be easy.
 		io->read_proc( pLineBuf, rowBytes, 1, handle );
 	}
@@ -589,7 +590,7 @@ Unpack32Bits( FreeImageIO *io, fi_handle handle, FIBITMAP* dib, MacRect* bounds,
 	int width = bounds->right - bounds->left;
 	
 	if (rowBytes == 0) {
-		rowBytes = width*4;
+		rowBytes = (WORD)( width * 4 );
 	}
 	
 	BYTE* pLineBuf = (BYTE*)malloc( rowBytes ); // Let's allocate enough for 4 bit planes
@@ -656,7 +657,7 @@ Unpack8Bits( FreeImageIO *io, fi_handle handle, FIBITMAP* dib, MacRect* bounds,
 	rowBytes &= 0x7fff;
 	
 	if (rowBytes == 0) {
-		rowBytes = width;
+		rowBytes = (WORD)width;
 	}
 	
 	for ( int i = 0; i < height; i++ ) {
@@ -694,7 +695,7 @@ UnpackBits( FreeImageIO *io, fi_handle handle, FIBITMAP* dib, MacRect* bounds, W
 		rowBytes &= 0x7fff;
 	}
 	
-	pixwidth = width;
+	pixwidth = (WORD)width;
 	pkpixsize = 1;          // RLE unit: one byte for everything...
 	if (pixelSize == 16) {    // ...except 16 bpp.
 		pkpixsize = 2;
diff --git a/Source/FreeImage/PluginPNG.cpp b/Source/FreeImage/PluginPNG.cpp
index 27fb545..ba2ef17 100644
--- a/Source/FreeImage/PluginPNG.cpp
+++ b/Source/FreeImage/PluginPNG.cpp
@@ -6,6 +6,7 @@
 // - Herve Drolon (drolon at infonie.fr)
 // - Detlev Vendt (detlev.vendt at brillit.de)
 // - Aaron Shumate (trek at startreker.com)
+// - Tanner Helland (tannerhelland at users.sf.net)
 //
 // This file is part of FreeImage 3
 //
@@ -35,6 +36,8 @@
 
 #define PNG_BYTES_TO_CHECK 8
 
+#undef PNG_Z_DEFAULT_COMPRESSION	// already used in ../LibPNG/pnglibconf.h
+
 // ----------------------------------------------------------
 
 #include "../ZLib/zlib.h"
@@ -47,9 +50,9 @@ typedef struct {
     fi_handle    s_handle;
 } fi_ioStructure, *pfi_ioStructure;
 
-/////////////////////////////////////////////////////////////////////////////
-// libpng interface 
-// 
+// ==========================================================
+// libpng interface
+// ==========================================================
 
 static void
 _ReadProc(png_structp png_ptr, unsigned char *data, png_size_t size) {
@@ -97,6 +100,7 @@ ReadMetadata(png_structp png_ptr, png_infop info_ptr, FIBITMAP *dib) {
 
 	FITAG *tag = NULL;
 	png_textp text_ptr = NULL;
+	png_timep mod_time = NULL;
 	int num_text = 0;
 
 	// iTXt/tEXt/zTXt chuncks
@@ -128,6 +132,31 @@ ReadMetadata(png_structp png_ptr, png_infop info_ptr, FIBITMAP *dib) {
 		}
 	}
 
+	// timestamp chunk
+	if(png_get_tIME(png_ptr, info_ptr, &mod_time)) {
+		char timestamp[32];
+		// create a tag
+		tag = FreeImage_CreateTag();
+		if(!tag) return FALSE;
+
+		// convert as 'yyyy:MM:dd hh:mm:ss'
+		sprintf(timestamp, "%4d:%02d:%02d %2d:%02d:%02d", mod_time->year, mod_time->month, mod_time->day, mod_time->hour, mod_time->minute, mod_time->second);
+
+		DWORD tag_length = (DWORD)strlen(timestamp) + 1;
+		FreeImage_SetTagLength(tag, tag_length);
+		FreeImage_SetTagCount(tag, tag_length);
+		FreeImage_SetTagType(tag, FIDT_ASCII);
+		FreeImage_SetTagID(tag, TAG_DATETIME);
+		FreeImage_SetTagValue(tag, timestamp);
+
+		// store the tag as Exif-TIFF
+		FreeImage_SetTagKey(tag, "DateTime");
+		FreeImage_SetMetadata(FIMD_EXIF_MAIN, dib, FreeImage_GetTagKey(tag), tag);
+
+		// destroy the tag
+		FreeImage_DeleteTag(tag);
+	}
+
 	return TRUE;
 }
 
@@ -141,6 +170,7 @@ WriteMetadata(png_structp png_ptr, png_infop info_ptr, FIBITMAP *dib) {
 	BOOL bResult = TRUE;
 
 	png_text text_metadata;
+	png_time mod_time;
 
 	// set the 'Comments' metadata as iTXt chuncks
 
@@ -172,7 +202,7 @@ WriteMetadata(png_structp png_ptr, png_infop info_ptr, FIBITMAP *dib) {
 	if(tag && FreeImage_GetTagLength(tag)) {
 		memset(&text_metadata, 0, sizeof(png_text));
 		text_metadata.compression = 1;							// iTXt, none
-		text_metadata.key = (char*)g_png_xmp_keyword;					// keyword, 1-79 character description of "text"
+		text_metadata.key = (char*)g_png_xmp_keyword;			// keyword, 1-79 character description of "text"
 		text_metadata.text = (char*)FreeImage_GetTagValue(tag);	// comment, may be an empty string (ie "")
 		text_metadata.text_length = FreeImage_GetTagLength(tag);// length of the text string
 		text_metadata.itxt_length = FreeImage_GetTagLength(tag);// length of the itxt string
@@ -184,6 +214,23 @@ WriteMetadata(png_structp png_ptr, png_infop info_ptr, FIBITMAP *dib) {
 		bResult &= TRUE;
 	}
 
+	// set the Exif-TIFF 'DateTime' metadata as a tIME chunk
+	tag = NULL;
+	FreeImage_GetMetadata(FIMD_EXIF_MAIN, dib, "DateTime", &tag);
+	if(tag && FreeImage_GetTagLength(tag)) {
+		int year, month, day, hour, minute, second;
+		const char *value = (char*)FreeImage_GetTagValue(tag);
+		if(sscanf(value, "%4d:%02d:%02d %2d:%02d:%02d", &year, &month, &day, &hour, &minute, &second) == 6) {
+			mod_time.year	= (png_uint_16)year;
+			mod_time.month	= (png_byte)month;
+			mod_time.day	= (png_byte)day;
+			mod_time.hour	= (png_byte)hour;
+			mod_time.minute	= (png_byte)minute;
+			mod_time.second	= (png_byte)second;
+			png_set_tIME (png_ptr, info_ptr, &mod_time);
+		}
+	}
+
 	return bResult;
 }
 
@@ -263,21 +310,207 @@ SupportsNoPixels() {
 	return TRUE;
 }
 
-// ----------------------------------------------------------
+// --------------------------------------------------------------------------
+
+/**
+Configure the decoder so that decoded pixels are compatible with a FREE_IMAGE_TYPE format. 
+Set conversion instructions as needed. 
+ at param png_ptr PNG handle
+ at param info_ptr PNG info handle
+ at param flags Decoder flags
+ at param output_image_type Returned FreeImage converted image type
+ at return Returns TRUE if successful, returns FALSE otherwise
+ at see png_read_update_info
+*/
+static BOOL 
+ConfigureDecoder(png_structp png_ptr, png_infop info_ptr, int flags, FREE_IMAGE_TYPE *output_image_type) {
+	// get original image info
+	const int color_type = png_get_color_type(png_ptr, info_ptr);
+	const int bit_depth = png_get_bit_depth(png_ptr, info_ptr);
+	const int pixel_depth = bit_depth * png_get_channels(png_ptr, info_ptr);
+
+	FREE_IMAGE_TYPE image_type = FIT_BITMAP;	// assume standard image type
+
+	// check for transparency table or single transparent color
+	BOOL bIsTransparent = png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) == PNG_INFO_tRNS ? TRUE : FALSE;
+
+	// check allowed combinations of colour type and bit depth
+	// then get converted FreeImage type
+
+	switch(color_type) {
+		case PNG_COLOR_TYPE_GRAY:		// color type '0', bitdepth = 1, 2, 4, 8, 16
+			switch(bit_depth) {
+				case 1:
+				case 2:
+				case 4:
+				case 8:
+					// expand grayscale images to the full 8-bit from 2-bit/pixel
+					if (pixel_depth == 2) {
+						png_set_expand_gray_1_2_4_to_8(png_ptr);
+					}
+
+					// if a tRNS chunk is provided, we must also expand the grayscale data to 8-bits,
+					// this allows us to make use of the transparency table with existing FreeImage methods
+					if (bIsTransparent && (pixel_depth < 8)) {
+						png_set_expand_gray_1_2_4_to_8(png_ptr);
+					}
+					break;
+
+				case 16:
+					image_type = (pixel_depth == 16) ? FIT_UINT16 : FIT_UNKNOWN;
+
+					// 16-bit grayscale images can contain a transparent value (shade)
+					// if found, expand the transparent value to a full alpha channel
+					if (bIsTransparent && (image_type != FIT_UNKNOWN)) {
+						// expand tRNS to a full alpha channel
+						png_set_tRNS_to_alpha(png_ptr);
+						
+						// expand new 16-bit gray + 16-bit alpha to full 64-bit RGBA
+						png_set_gray_to_rgb(png_ptr);
+
+						image_type = FIT_RGBA16;
+					}
+					break;
+
+				default:
+					image_type = FIT_UNKNOWN;
+					break;
+			}
+			break;
+
+		case PNG_COLOR_TYPE_RGB:		// color type '2', bitdepth = 8, 16
+			switch(bit_depth) {
+				case 8:
+					image_type = (pixel_depth == 24) ? FIT_BITMAP : FIT_UNKNOWN;
+					break;
+				case 16:
+					image_type = (pixel_depth == 48) ? FIT_RGB16 : FIT_UNKNOWN;
+					break;
+				default:
+					image_type = FIT_UNKNOWN;
+					break;
+			}
+			// sometimes, 24- or 48-bit images may contain transparency information
+			// check for this use case and convert to an alpha-compatible format
+			if (bIsTransparent && (image_type != FIT_UNKNOWN)) {
+				// if the image is 24-bit RGB, mark it as 32-bit; if it is 48-bit, mark it as 64-bit
+				image_type = (pixel_depth == 24) ? FIT_BITMAP : (pixel_depth == 48) ? FIT_RGBA16 : FIT_UNKNOWN;
+				// expand tRNS chunk to alpha channel
+				png_set_tRNS_to_alpha(png_ptr);
+			}
+			break;
+
+		case PNG_COLOR_TYPE_PALETTE:	// color type '3', bitdepth = 1, 2, 4, 8
+			switch(bit_depth) {
+				case 1:
+				case 2:
+				case 4:
+				case 8:
+					// expand palette images to the full 8 bits from 2 bits/pixel
+					if (pixel_depth == 2) {
+						png_set_packing(png_ptr);
+					}
+
+					// if a tRNS chunk is provided, we must also expand the palletized data to 8-bits,
+					// this allows us to make use of the transparency table with existing FreeImage methods
+					if (bIsTransparent && (pixel_depth < 8)) {
+						png_set_packing(png_ptr);
+					}
+					break;
+
+				default:
+					image_type = FIT_UNKNOWN;
+					break;
+			}
+			break;
+
+		case PNG_COLOR_TYPE_GRAY_ALPHA:	// color type '4', bitdepth = 8, 16
+			switch(bit_depth) {
+				case 8:
+					// 8-bit grayscale + 8-bit alpha => convert to 32-bit RGBA
+					image_type = (pixel_depth == 16) ? FIT_BITMAP : FIT_UNKNOWN;
+					break;
+				case 16:
+					// 16-bit grayscale + 16-bit alpha => convert to 64-bit RGBA
+					image_type = (pixel_depth == 32) ? FIT_RGBA16 : FIT_UNKNOWN;
+					break;
+				default:
+					image_type = FIT_UNKNOWN;
+					break;
+			}
+			// expand 8-bit greyscale + 8-bit alpha to 32-bit
+			// expand 16-bit greyscale + 16-bit alpha to 64-bit
+			png_set_gray_to_rgb(png_ptr);
+			break;
+
+		case PNG_COLOR_TYPE_RGB_ALPHA:	// color type '6', bitdepth = 8, 16
+			switch(bit_depth) {
+				case 8:
+					break;
+				case 16:
+					image_type = (pixel_depth == 64) ? FIT_RGBA16 : FIT_UNKNOWN;
+					break;
+				default:
+					image_type = FIT_UNKNOWN;
+					break;
+			}
+			break;
+	}
+
+	// check for unknown or invalid formats
+	if(image_type == FIT_UNKNOWN) {
+		*output_image_type = image_type;
+		return FALSE;
+	}
+
+#ifndef FREEIMAGE_BIGENDIAN
+	if((image_type == FIT_UINT16) || (image_type == FIT_RGB16) || (image_type == FIT_RGBA16)) {
+		// turn on 16-bit byte swapping
+		png_set_swap(png_ptr);
+	}
+#endif						
+
+#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
+	if((image_type == FIT_BITMAP) && ((color_type == PNG_COLOR_TYPE_RGB) || (color_type == PNG_COLOR_TYPE_RGB_ALPHA))) {
+		// flip the RGB pixels to BGR (or RGBA to BGRA)
+		png_set_bgr(png_ptr);
+	}
+#endif
+
+	// gamma correction
+	// unlike the example in the libpng documentation, we have *no* idea where
+	// this file may have come from--so if it doesn't have a file gamma, don't
+	// do any correction ("do no harm")
+
+	if (png_get_valid(png_ptr, info_ptr, PNG_INFO_gAMA)) {
+		double gamma = 0;
+		double screen_gamma = 2.2;
+
+		if (png_get_gAMA(png_ptr, info_ptr, &gamma) && ( flags & PNG_IGNOREGAMMA ) != PNG_IGNOREGAMMA) {
+			png_set_gamma(png_ptr, screen_gamma, gamma);
+		}
+	}
+
+	// all transformations have been registered; now update info_ptr data		
+	png_read_update_info(png_ptr, info_ptr);
+
+	// return the output image type
+	*output_image_type = image_type;
+
+	return TRUE;
+}
 
 static FIBITMAP * DLL_CALLCONV
 Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
 	png_structp png_ptr = NULL;
-	png_infop info_ptr;
+	png_infop info_ptr = NULL;
 	png_uint_32 width, height;
-	png_colorp png_palette = NULL;
-	int color_type, palette_entries = 0;
-	int bit_depth, pixel_depth;		// pixel_depth = bit_depth * channels
+	int color_type;
+	int bit_depth;
+	int pixel_depth = 0;	// pixel_depth = bit_depth * channels
 
 	FIBITMAP *dib = NULL;
-	RGBQUAD *palette = NULL;		// pointer to dib palette
-	png_bytepp  row_pointers = NULL;
-	int i;
+	png_bytepp row_pointers = NULL;
 
     fi_ioStructure fio;
     fio.s_handle = handle;
@@ -332,154 +565,58 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
 			png_read_info(png_ptr, info_ptr);
 			png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL);
 
-			pixel_depth = png_get_bit_depth(png_ptr, info_ptr) * png_get_channels(png_ptr, info_ptr);
-
-			// get image data type (assume standard image type)
+			// configure the decoder
 
 			FREE_IMAGE_TYPE image_type = FIT_BITMAP;
-			if (bit_depth == 16) {
-				if ((pixel_depth == 16) && (color_type == PNG_COLOR_TYPE_GRAY)) {
-					image_type = FIT_UINT16;
-				} 
-				else if ((pixel_depth == 48) && (color_type == PNG_COLOR_TYPE_RGB)) {
-					image_type = FIT_RGB16;
-				} 
-				else if ((pixel_depth == 64) && (color_type == PNG_COLOR_TYPE_RGB_ALPHA)) {
-					image_type = FIT_RGBA16;
-				} else {
-					// tell libpng to strip 16 bit/color files down to 8 bits/color
-					png_set_strip_16(png_ptr);
-					bit_depth = 8;
-				}
-			}
-
-#ifndef FREEIMAGE_BIGENDIAN
-			if((image_type == FIT_UINT16) || (image_type == FIT_RGB16) || (image_type == FIT_RGBA16)) {
-				// turn on 16 bit byte swapping
-				png_set_swap(png_ptr);
-			}
-#endif						
-
-			// set some additional flags
-
-			switch(color_type) {
-				case PNG_COLOR_TYPE_RGB:
-				case PNG_COLOR_TYPE_RGB_ALPHA:
-#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
-					// flip the RGB pixels to BGR (or RGBA to BGRA)
-
-					if(image_type == FIT_BITMAP) {
-						png_set_bgr(png_ptr);
-					}
-#endif
-					break;
-
-				case PNG_COLOR_TYPE_PALETTE:
-					// expand palette images to the full 8 bits from 2 bits/pixel
-
-					if (pixel_depth == 2) {
-						png_set_packing(png_ptr);
-						pixel_depth = 8;
-					}					
-
-					break;
-
-				case PNG_COLOR_TYPE_GRAY:
-					// expand grayscale images to the full 8 bits from 2 bits/pixel
-					// but *do not* expand fully transparent palette entries to a full alpha channel
-
-					if (pixel_depth == 2) {
-						png_set_expand_gray_1_2_4_to_8(png_ptr);
-						pixel_depth = 8;
-					}
-
-					break;
-
-				case PNG_COLOR_TYPE_GRAY_ALPHA:
-					// expand 8-bit greyscale + 8-bit alpha to 32-bit
 
-					png_set_gray_to_rgb(png_ptr);
-#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
-					// flip the RGBA pixels to BGRA
-
-					png_set_bgr(png_ptr);
-#endif
-					pixel_depth = 32;
-
-					break;
-
-				default:
-					throw FI_MSG_ERROR_UNSUPPORTED_FORMAT;
+			if(!ConfigureDecoder(png_ptr, info_ptr, flags, &image_type)) {
+				throw FI_MSG_ERROR_UNSUPPORTED_FORMAT;
 			}
 
-			// unlike the example in the libpng documentation, we have *no* idea where
-			// this file may have come from--so if it doesn't have a file gamma, don't
-			// do any correction ("do no harm")
-
-			if (png_get_valid(png_ptr, info_ptr, PNG_INFO_gAMA)) {
-				double gamma = 0;
-				double screen_gamma = 2.2;
-
-				if (png_get_gAMA(png_ptr, info_ptr, &gamma) && ( flags & PNG_IGNOREGAMMA ) != PNG_IGNOREGAMMA) {
-					png_set_gamma(png_ptr, screen_gamma, gamma);
-				}
-			}
-
-			// all transformations have been registered; now update info_ptr data
-
-			png_read_update_info(png_ptr, info_ptr);
+			// update image info
 
-			// color type may have changed, due to our transformations
+			color_type = png_get_color_type(png_ptr, info_ptr);
+			bit_depth = png_get_bit_depth(png_ptr, info_ptr);
+			pixel_depth = bit_depth * png_get_channels(png_ptr, info_ptr);
 
-			color_type = png_get_color_type(png_ptr,info_ptr);
-
-			// create a DIB and write the bitmap header
-			// set up the DIB palette, if needed
+			// create a dib and write the bitmap header
+			// set up the dib palette, if needed
 
 			switch (color_type) {
 				case PNG_COLOR_TYPE_RGB:
-					png_set_invert_alpha(png_ptr);
-
-					if(image_type == FIT_BITMAP) {
-						dib = FreeImage_AllocateHeader(header_only, width, height, 24, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
-					} else {
-						dib = FreeImage_AllocateHeaderT(header_only, image_type, width, height, pixel_depth);
-					}
-					break;
-
 				case PNG_COLOR_TYPE_RGB_ALPHA:
-					if(image_type == FIT_BITMAP) {
-						dib = FreeImage_AllocateHeader(header_only, width, height, 32, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
-					} else {
-						dib = FreeImage_AllocateHeaderT(header_only, image_type, width, height, pixel_depth);
-					}
+					dib = FreeImage_AllocateHeaderT(header_only, image_type, width, height, pixel_depth, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
 					break;
 
 				case PNG_COLOR_TYPE_PALETTE:
-					dib = FreeImage_AllocateHeader(header_only, width, height, pixel_depth);
+					dib = FreeImage_AllocateHeaderT(header_only, image_type, width, height, pixel_depth, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
+					if(dib) {
+						png_colorp png_palette = NULL;
+						int palette_entries = 0;
 
-					png_get_PLTE(png_ptr,info_ptr, &png_palette, &palette_entries);
+						png_get_PLTE(png_ptr,info_ptr, &png_palette, &palette_entries);
 
-					palette_entries = MIN((unsigned)palette_entries, FreeImage_GetColorsUsed(dib));
-					palette = FreeImage_GetPalette(dib);
+						palette_entries = MIN((unsigned)palette_entries, FreeImage_GetColorsUsed(dib));
 
-					// store the palette
+						// store the palette
 
-					for (i = 0; i < palette_entries; i++) {
-						palette[i].rgbRed   = png_palette[i].red;
-						palette[i].rgbGreen = png_palette[i].green;
-						palette[i].rgbBlue  = png_palette[i].blue;
+						RGBQUAD *palette = FreeImage_GetPalette(dib);
+						for(int i = 0; i < palette_entries; i++) {
+							palette[i].rgbRed   = png_palette[i].red;
+							palette[i].rgbGreen = png_palette[i].green;
+							palette[i].rgbBlue  = png_palette[i].blue;
+						}
 					}
 					break;
 
 				case PNG_COLOR_TYPE_GRAY:
-					dib = FreeImage_AllocateHeaderT(header_only, image_type, width, height, pixel_depth);
+					dib = FreeImage_AllocateHeaderT(header_only, image_type, width, height, pixel_depth, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
 
-					if(pixel_depth <= 8) {
-						palette = FreeImage_GetPalette(dib);
-						palette_entries = 1 << pixel_depth;
+					if(dib && (pixel_depth <= 8)) {
+						RGBQUAD *palette = FreeImage_GetPalette(dib);
+						const int palette_entries = 1 << pixel_depth;
 
-						for (i = 0; i < palette_entries; i++) {
+						for(int i = 0; i < palette_entries; i++) {
 							palette[i].rgbRed   =
 							palette[i].rgbGreen =
 							palette[i].rgbBlue  = (BYTE)((i * 255) / (palette_entries - 1));
@@ -491,6 +628,10 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
 					throw FI_MSG_ERROR_UNSUPPORTED_FORMAT;
 			}
 
+			if(!dib) {
+				throw FI_MSG_ERROR_DIB_MEMORY;
+			}
+
 			// store the transparency table
 
 			if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
@@ -505,21 +646,26 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
 
 				if((color_type == PNG_COLOR_TYPE_GRAY) && trans_color) {
 					// single transparent color
-					if (trans_color->gray < palette_entries) { 
+					if (trans_color->gray < 256) { 
 						BYTE table[256]; 
-						memset(table, 0xFF, palette_entries); 
+						memset(table, 0xFF, 256); 
 						table[trans_color->gray] = 0; 
-						FreeImage_SetTransparencyTable(dib, table, palette_entries); 
+						FreeImage_SetTransparencyTable(dib, table, 256); 
+					}
+					// check for a full transparency table, too
+					else if ((trans_alpha) && (pixel_depth <= 8)) {
+						FreeImage_SetTransparencyTable(dib, (BYTE *)trans_alpha, num_trans);
 					}
+
 				} else if((color_type == PNG_COLOR_TYPE_PALETTE) && trans_alpha) {
 					// transparency table
 					FreeImage_SetTransparencyTable(dib, (BYTE *)trans_alpha, num_trans);
 				}
 			}
 
-			// store the background color 
+			// store the background color (only supported for FIT_BITMAP types)
 
-			if (png_get_valid(png_ptr, info_ptr, PNG_INFO_bKGD)) {
+			if ((image_type == FIT_BITMAP) && png_get_valid(png_ptr, info_ptr, PNG_INFO_bKGD)) {
 				// Get the background color to draw transparent and alpha images over.
 				// Note that even if the PNG file supplies a background, you are not required to
 				// use it - you should use the (solid) application background if it has one.
@@ -596,7 +742,7 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
 			// allow loading of PNG with minor errors (such as images with several IDAT chunks)
 
 			for (png_uint_32 k = 0; k < height; k++) {
-				row_pointers[height - 1 - k] = FreeImage_GetScanLine(dib, k);			
+				row_pointers[height - 1 - k] = FreeImage_GetScanLine(dib, k);
 			}
 
 			png_set_benign_errors(png_ptr, 1);
@@ -642,7 +788,7 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
 				free(row_pointers);
 			}
 			if (dib) {
-				FreeImage_Unload(dib);			
+				FreeImage_Unload(dib);
 			}
 			FreeImage_OutputMessageProc(s_format_id, text);
 			
@@ -653,6 +799,8 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
 	return NULL;
 }
 
+// --------------------------------------------------------------------------
+
 static BOOL DLL_CALLCONV
 Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void *data) {
 	png_structp png_ptr;
@@ -901,7 +1049,7 @@ Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void
 				// the number of passes is either 1 for non-interlaced images, or 7 for interlaced images
 				for (int pass = 0; pass < number_passes; pass++) {
 					for (png_uint_32 k = 0; k < height; k++) {
-						FreeImage_ConvertLine32To24(buffer, FreeImage_GetScanLine(dib, height - k - 1), width);			
+						FreeImage_ConvertLine32To24(buffer, FreeImage_GetScanLine(dib, height - k - 1), width);
 						png_write_row(png_ptr, buffer);
 					}
 				}
@@ -909,8 +1057,8 @@ Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void
 			} else {
 				// the number of passes is either 1 for non-interlaced images, or 7 for interlaced images
 				for (int pass = 0; pass < number_passes; pass++) {
-					for (png_uint_32 k = 0; k < height; k++) {			
-						png_write_row(png_ptr, FreeImage_GetScanLine(dib, height - k - 1));					
+					for (png_uint_32 k = 0; k < height; k++) {
+						png_write_row(png_ptr, FreeImage_GetScanLine(dib, height - k - 1));
 					}
 				}
 			}
@@ -928,7 +1076,11 @@ Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void
 			png_destroy_write_struct(&png_ptr, &info_ptr);
 
 			return TRUE;
+
 		} catch (const char *text) {
+			if(png_ptr) {
+				png_destroy_write_struct(&png_ptr, &info_ptr);
+			}
 			FreeImage_OutputMessageProc(s_format_id, text);
 		}
 	}
diff --git a/Source/FreeImage/PluginPNM.cpp b/Source/FreeImage/PluginPNM.cpp
index 3155315..3b4d0de 100644
--- a/Source/FreeImage/PluginPNM.cpp
+++ b/Source/FreeImage/PluginPNM.cpp
@@ -33,11 +33,13 @@ Get an integer value from the actual position pointed by handle
 static int
 GetInt(FreeImageIO *io, fi_handle handle) {
     char c = 0;
-	BOOL firstchar;
+	BOOL bFirstChar;
 
     // skip forward to start of next number
 
-    if(!io->read_proc(&c, 1, 1, handle)) throw FI_MSG_ERROR_PARSING;
+	if(!io->read_proc(&c, 1, 1, handle)) {
+		throw FI_MSG_ERROR_PARSING;
+	}
 
     while (1) {
         // eat comments
@@ -45,15 +47,16 @@ GetInt(FreeImageIO *io, fi_handle handle) {
         if (c == '#') {
 			// if we're at a comment, read to end of line
 
-            firstchar = TRUE;
+            bFirstChar = TRUE;
 
             while (1) {
-				if(!io->read_proc(&c, 1, 1, handle)) throw FI_MSG_ERROR_PARSING;
+				if(!io->read_proc(&c, 1, 1, handle)) {
+					throw FI_MSG_ERROR_PARSING;
+				}
 
-				if (firstchar && c == ' ') {
+				if (bFirstChar && c == ' ') {
 					// loop off 1 sp after #
-
-					firstchar = FALSE;
+					bFirstChar = FALSE;
 				} else if (c == '\n') {
 					break;
 				}
@@ -62,11 +65,12 @@ GetInt(FreeImageIO *io, fi_handle handle) {
 
         if (c >= '0' && c <='9') {
 			// we've found what we were looking for
-
             break;
 		}
 
-        if(!io->read_proc(&c, 1, 1, handle)) throw FI_MSG_ERROR_PARSING;
+		if(!io->read_proc(&c, 1, 1, handle)) {
+			throw FI_MSG_ERROR_PARSING;
+		}
     }
 
     // we're at the start of a number, continue until we hit a non-number
@@ -76,10 +80,13 @@ GetInt(FreeImageIO *io, fi_handle handle) {
     while (1) {
         i = (i * 10) + (c - '0');
 
-        if(!io->read_proc(&c, 1, 1, handle)) throw FI_MSG_ERROR_PARSING;
+		if(!io->read_proc(&c, 1, 1, handle)) {
+			throw FI_MSG_ERROR_PARSING;
+		}
 
-        if (c < '0' || c > '9')
-            break;
+		if (c < '0' || c > '9') {
+			break;
+		}
     }
 
     return i;
diff --git a/Source/FreeImage/PluginRAW.cpp b/Source/FreeImage/PluginRAW.cpp
index bf5d821..e9bd5bf 100644
--- a/Source/FreeImage/PluginRAW.cpp
+++ b/Source/FreeImage/PluginRAW.cpp
@@ -140,12 +140,72 @@ public:
 
 /**
 Convert a processed raw data array to a FIBITMAP
+ at param RawProcessor LibRaw handle containing the processed raw image
+ at return Returns the converted dib if successfull, returns NULL otherwise
+*/
+static FIBITMAP * 
+libraw_ConvertProcessedRawToDib(LibRaw *RawProcessor) {
+	FIBITMAP *dib = NULL;
+    int width, height, colors, bpp;
+
+	try {
+		int bgr = 0;	// pixel copy order: RGB if (bgr == 0) and BGR otherwise
+
+		// get image info
+		RawProcessor->get_mem_image_format(&width, &height, &colors, &bpp);
+
+		// only 3-color images supported...
+		if(colors != 3) {
+			throw "LibRaw : only 3-color images supported";
+		}
+
+		if(bpp == 16) {
+			// allocate output dib
+			dib = FreeImage_AllocateT(FIT_RGB16, width, height);
+			if(!dib) {
+				throw FI_MSG_ERROR_DIB_MEMORY;
+			}
+
+		} else if(bpp == 8) {
+#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
+			bgr = 1;	// only useful for FIT_BITMAP types
+#endif
+
+			// allocate output dib
+			dib = FreeImage_AllocateT(FIT_BITMAP, width, height, 24);
+			if(!dib) {
+				throw FI_MSG_ERROR_DIB_MEMORY;
+			}
+		}
+
+		// copy post-processed bitmap data into FIBITMAP buffer
+		if(RawProcessor->copy_mem_image(FreeImage_GetBits(dib), FreeImage_GetPitch(dib), bgr) != LIBRAW_SUCCESS) {
+			throw "LibRaw : failed to copy data into dib";
+		}
+
+		// flip vertically
+		FreeImage_FlipVertical(dib);
+
+		return dib;
+
+	} catch(const char *text) {
+		FreeImage_Unload(dib);
+		FreeImage_OutputMessageProc(s_format_id, text);
+		return NULL;
+	}
+}
+
+
+/**
+Convert a processed raw image to a FIBITMAP
 @param image Processed raw image
 @return Returns the converted dib if successfull, returns NULL otherwise
+ at see libraw_LoadEmbeddedPreview
 */
 static FIBITMAP * 
-libraw_ConvertToDib(libraw_processed_image_t *image) {
+libraw_ConvertProcessedImageToDib(libraw_processed_image_t *image) {
 	FIBITMAP *dib = NULL;
+
 	try {
 		unsigned width = image->width;
 		unsigned height = image->height;
@@ -185,12 +245,14 @@ libraw_ConvertToDib(libraw_processed_image_t *image) {
 				}
 			}
 		}
+		
+		return dib;
 
 	} catch(const char *text) {
+		FreeImage_Unload(dib);
 		FreeImage_OutputMessageProc(s_format_id, text);
+		return NULL;
 	}
-
-	return dib;
 }
 
 /** 
@@ -228,9 +290,9 @@ libraw_LoadEmbeddedPreview(LibRaw *RawProcessor, int flags) {
 				dib = FreeImage_LoadFromMemory(fif, hmem, flags);
 				// close the stream
 				FreeImage_CloseMemory(hmem);
-			} else {
+			} else if((flags & FIF_LOAD_NOPIXELS) != FIF_LOAD_NOPIXELS) {
 				// convert processed data to output dib
-				dib = libraw_ConvertToDib(thumb_image);
+				dib = libraw_ConvertProcessedImageToDib(thumb_image);
 			}
 		} else {
 			throw "LibRaw : failed to run dcraw_make_mem_thumb";
@@ -262,7 +324,6 @@ Load raw data and convert to FIBITMAP
 static FIBITMAP * 
 libraw_LoadRawData(LibRaw *RawProcessor, int bitspersample) {
 	FIBITMAP *dib = NULL;
-	libraw_processed_image_t *processed_image = NULL;
 
 	try {
 		// set decoding parameters
@@ -300,38 +361,119 @@ libraw_LoadRawData(LibRaw *RawProcessor, int bitspersample) {
 		}
 
 		// retrieve processed image
-		int error_code = 0;
-		processed_image = RawProcessor->dcraw_make_mem_image(&error_code);
-		if(processed_image) {
-			// type SHOULD be LIBRAW_IMAGE_BITMAP, but we'll check
-			if(processed_image->type != LIBRAW_IMAGE_BITMAP) {
-				throw "invalid image type";
+		dib = libraw_ConvertProcessedRawToDib(RawProcessor);
+	
+		return dib;
+
+	} catch(const char *text) {
+		FreeImage_OutputMessageProc(s_format_id, text);
+		return NULL;
+	}
+}
+
+/**
+Load the Bayer matrix (unprocessed raw data) as a FIT_UINT16 image. 
+Note that some formats don't have a Bayer matrix (e.g. Foveon, Canon sRAW, demosaiced DNG files). 
+ at param RawProcessor Libraw handle
+ at return Returns the loaded dib if successfull, returns NULL otherwise
+*/
+static FIBITMAP * 
+libraw_LoadUnprocessedData(LibRaw *RawProcessor) {
+	FIBITMAP *dib = NULL;
+
+	try {
+		// unpack data
+		if(RawProcessor->unpack() != LIBRAW_SUCCESS) {
+			throw "LibRaw : failed to unpack data";
+		}
+
+		// check for a supported Bayer format
+		if(!(RawProcessor->imgdata.idata.filters || RawProcessor->imgdata.idata.colors == 1)) {
+			throw "LibRaw : only Bayer-pattern RAW files are supported";
+		}
+
+		// allocate output dib
+		const unsigned width = RawProcessor->imgdata.sizes.raw_width;
+		const unsigned height = RawProcessor->imgdata.sizes.raw_height;
+		const size_t line_size = width * sizeof(WORD);
+		const WORD *src_bits = (WORD*)RawProcessor->imgdata.rawdata.raw_image;
+
+		if(src_bits) {
+			dib = FreeImage_AllocateT(FIT_UINT16, width, height);
+		}
+		if(!dib) {
+			throw FI_MSG_ERROR_DIB_MEMORY;
+		}
+
+		// retrieve the raw image
+		for(unsigned y = 0; y < height; y++) {
+			WORD *dst_bits = (WORD*)FreeImage_GetScanLine(dib, height - 1 - y);
+			memcpy(dst_bits, src_bits, line_size);
+			src_bits += width;
+		}
+
+		// store metadata needed for post-processing
+		{
+			char value[512];
+
+			const libraw_image_sizes_t *sizes = &RawProcessor->imgdata.sizes;
+
+			// image output width & height
+			{
+				sprintf(value, "%d", sizes->iwidth);
+				FreeImage_SetMetadataKeyValue(FIMD_COMMENTS, dib, "Raw.Output.Width", value);
+				
+				sprintf(value, "%d", sizes->iheight);
+				FreeImage_SetMetadataKeyValue(FIMD_COMMENTS, dib, "Raw.Output.Height", value);
 			}
-			// only 3-color images supported...
-			if(processed_image->colors != 3) {
-				throw "only 3-color images supported";
+
+			// image output frame
+			{
+				const unsigned f_left = sizes->left_margin;
+				const unsigned f_top = sizes->top_margin;
+				const unsigned f_width = sizes->width;
+				const unsigned f_height = sizes->height;
+				
+				sprintf(value, "%d", f_left);
+				FreeImage_SetMetadataKeyValue(FIMD_COMMENTS, dib, "Raw.Frame.Left", value);
+
+				sprintf(value, "%d", f_top);
+				FreeImage_SetMetadataKeyValue(FIMD_COMMENTS, dib, "Raw.Frame.Top", value);
+
+				sprintf(value, "%d", f_width);
+				FreeImage_SetMetadataKeyValue(FIMD_COMMENTS, dib, "Raw.Frame.Width", value);
+
+				sprintf(value, "%d", f_height);
+				FreeImage_SetMetadataKeyValue(FIMD_COMMENTS, dib, "Raw.Frame.Height", value);
 			}
-		} else {
-			throw "LibRaw : failed to run dcraw_make_mem_image";
-		}
 
-		// convert processed data to output dib
-		dib = libraw_ConvertToDib(processed_image);
-	
-		// clean-up and return
-		RawProcessor->dcraw_clear_mem(processed_image);
+			// Bayer pattern
+			// Mask describing the order of color pixels in the matrix. 
+			// This field describe 16 pixels (8 rows with two pixels in each, from left to right and from top to bottom). 
+
+			if(RawProcessor->imgdata.idata.filters) {
+				// description of colors numbered from 0 to 3 (RGBG,RGBE,GMCY, or GBTG)
+				char *cdesc = RawProcessor->imgdata.idata.cdesc;
+				if(!cdesc[3]) {
+					cdesc[3] = 'G';
+				}
+				char *pattern = &value[0];
+				for(int i = 0; i < 16; i++) {
+					pattern[i] = cdesc[ RawProcessor->fcol(i >> 1, i & 1) ];
+				}
+				pattern[16] = 0;
 
+				FreeImage_SetMetadataKeyValue(FIMD_COMMENTS, dib, "Raw.BayerPattern", value);
+			}
+		}
+	
 		return dib;
 
 	} catch(const char *text) {
-		// clean-up and return
-		if(processed_image) {
-			RawProcessor->dcraw_clear_mem(processed_image);
-		}
+		FreeImage_Unload(dib);
 		FreeImage_OutputMessageProc(s_format_id, text);
+		return NULL;
 	}
-
-	return NULL;
 }
 
 // ==========================================================
@@ -397,8 +539,8 @@ Extension() {
 		"sr2,"   // Sony Digital Camera Raw Image Format.
 		"srf,"   // Sony Digital Camera Raw Image Format for DSC-F828 8 megapixel digital camera or Sony DSC-R1.
 		"srw,"   // Samsung Raw Image Format.
-		"sti";   // Sinar Capture Shop Raw Image File.
-//		"x3f"   // Sigma Digital Camera Raw Image Format for devices based on Foveon X3 direct image sensor.
+		"sti,"   // Sinar Capture Shop Raw Image File.
+		"x3f";   // Sigma Digital Camera Raw Image Format for devices based on Foveon X3 direct image sensor.
 	return raw_extensions;
 }
 
@@ -416,33 +558,37 @@ static BOOL
 HasMagicHeader(FreeImageIO *io, fi_handle handle) {
 	const unsigned signature_size = 32;
 	BYTE signature[signature_size] = { 0 };
-
-	// Canon (CR2), Intel byte order
+	/*
+	note: classic TIFF signature is
+	{ 0x49, 0x49, 0x2A, 0x00 } Classic TIFF, little-endian
+	{ 0x4D, 0x4D, 0x00, 0x2A } Classic TIFF, big-endian
+	*/
+	// Canon (CR2), little-endian byte order
 	const BYTE CR2_II[] = { 0x49, 0x49, 0x2A, 0x00, 0x10, 0x00, 0x00, 0x00, 0x43, 0x52, 0x02, 0x00 };
-	// Canon (CR2), Motorola byte order
-	const BYTE CR2_MM[] = { 0x4D, 0x4D, 0x2A, 0x00, 0x10, 0x00, 0x00, 0x00, 0x43, 0x52, 0x02, 0x00 };
-	// Canon (CRW), Intel byte order
-	const BYTE CRW_II[] = { 0x49, 0x49, 0x1A, 0x00, 0x00, 0x00, 0x48, 0x45, 0x41, 0x50, 0x43, 0x43, 0x44, 0x52, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+	// Canon (CRW), little-endian byte order
+	const BYTE CRW_II[] = { 0x49, 0x49, 0x1A, 0x00, 0x00, 0x00, 0x48, 0x45, 0x41, 0x50, 0x43, 0x43, 0x44, 0x52, 0x02, 0x00 };
 	// Minolta (MRW)
 	const BYTE MRW[] = { 0x00, 0x4D, 0x52, 0x4D, 0x00 };
-	// Olympus (ORF), Intel byte order
+	// Olympus (ORF), little-endian byte order
 	const BYTE ORF_IIRS[] = { 0x49, 0x49, 0x52, 0x53, 0x08, 0x00, 0x00, 0x00 }; 
 	const BYTE ORF_IIRO[] = { 0x49, 0x49, 0x52, 0x4F, 0x08, 0x00, 0x00, 0x00 }; 
-	// Olympus (ORF), Motorola byte order
+	// Olympus (ORF), big-endian byte order
 	const BYTE ORF_MMOR[] = { 0x4D, 0x4D, 0x4F, 0x52, 0x00, 0x00, 0x00, 0x08 }; 
 	// Fujifilm (RAF)
-	const BYTE RAF[] = { 0x46, 0x55, 0x4A, 0x49, 0x46, 0x49, 0x4C, 0x4D, 0x43, 0x43, 0x44, 0x2D, 0x52, 0x41, 0x57, 0x20, 0x30, 0x32, 0x30, 0x31 };
-	// Panasonic (RW2) or Leica (RWL)
-	const BYTE RW2_II[] = { 0x49, 0x49, 0x55, 0x00, 0x18, 0x00, 0x00, 0x00, 0x88, 0xE7, 0x74, 0xD8, 0xF8, 0x25, 0x1D, 0x4D, 0x94, 0x7A, 0x6E, 0x77, 0x82, 0x2B, 0x5D, 0x6A };
+	const BYTE RAF[] = { 0x46, 0x55, 0x4A, 0x49, 0x46, 0x49, 0x4C, 0x4D, 0x43, 0x43, 0x44, 0x2D, 0x52, 0x41, 0x57, 0x20 };
+	// Panasonic (RW2) or Leica (RWL), little-endian byte order
+	const BYTE RWx_II[] = { 0x49, 0x49, 0x55, 0x00, 0x18, 0x00, 0x00, 0x00, 0x88, 0xE7, 0x74, 0xD8, 0xF8, 0x25, 0x1D, 0x4D, 0x94, 0x7A, 0x6E, 0x77, 0x82, 0x2B, 0x5D, 0x6A };
+	// Panasonic (RAW) or Leica (RAW), little-endian byte order
+	const BYTE RAW_II[] = { 0x49, 0x49, 0x55, 0x00, 0x08, 0x00, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00 };
+	// Foveon (X3F)
+	const BYTE X3F[] = { 0x46, 0x4F, 0x56, 0x62 };
 
 	if(io->read_proc(signature, 1, signature_size, handle) != signature_size) {
 		return FALSE;
 	}
 	if(memcmp(CR2_II, signature, 12) == 0)
 		return TRUE;
-	if(memcmp(CR2_MM, signature, 12) == 0)
-		return TRUE;
-	if(memcmp(CRW_II, signature, 26) == 0)
+	if(memcmp(CRW_II, signature, 16) == 0)
 		return TRUE;
 	if(memcmp(MRW, signature, 5) == 0)
 		return TRUE;
@@ -452,9 +598,13 @@ HasMagicHeader(FreeImageIO *io, fi_handle handle) {
 		return TRUE;
 	if(memcmp(ORF_MMOR, signature, 8) == 0)
 		return TRUE;
-	if(memcmp(RAF, signature, 20) == 0)
+	if(memcmp(RAF, signature, 16) == 0)
 		return TRUE;
-	if(memcmp(RW2_II, signature, 24) == 0)
+	if(memcmp(RWx_II, signature, 24) == 0)
+		return TRUE;
+	if(memcmp(RAW_II, signature, 18) == 0)
+		return TRUE;
+	if(memcmp(X3F, signature, 4) == 0)
 		return TRUE;
 
 	return FALSE;
@@ -547,6 +697,8 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
 		RawProcessor->imgdata.params.shot_select = 0;
 		// (-w) Use camera white balance, if possible (otherwise, fallback to auto_wb)
 		RawProcessor->imgdata.params.use_camera_wb = 1;
+		// (-M) Use any color matrix from the camera metadata. This option only affects Olympus, Leaf, and Phase One cameras.
+		RawProcessor->imgdata.params.use_camera_matrix = 1;
 		// (-h) outputs the image in 50% size
 		RawProcessor->imgdata.params.half_size = ((flags & RAW_HALFSIZE) == RAW_HALFSIZE) ? 1 : 0;
 
@@ -559,6 +711,10 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
 			// header only mode
 			dib = FreeImage_AllocateHeaderT(header_only, FIT_RGB16, RawProcessor->imgdata.sizes.width, RawProcessor->imgdata.sizes.height);
 		}
+		else if((flags & RAW_UNPROCESSED) == RAW_UNPROCESSED) {
+			// load raw data without post-processing (i.e. as a Bayer matrix)
+			dib = libraw_LoadUnprocessedData(RawProcessor);
+		}
 		else if((flags & RAW_PREVIEW) == RAW_PREVIEW) {
 			// try to get the embedded JPEG
 			dib = libraw_LoadEmbeddedPreview(RawProcessor, 0);
diff --git a/Source/FreeImage/PluginSGI.cpp b/Source/FreeImage/PluginSGI.cpp
index 0fd162b..35fd2ec 100644
--- a/Source/FreeImage/PluginSGI.cpp
+++ b/Source/FreeImage/PluginSGI.cpp
@@ -178,7 +178,7 @@ Description() {
 
 static const char * DLL_CALLCONV
 Extension() {
-  return "sgi";
+  return "sgi,rgb,rgba,bw";
 }
 
 static const char * DLL_CALLCONV
diff --git a/Source/FreeImage/PluginTARGA.cpp b/Source/FreeImage/PluginTARGA.cpp
index 5fb1f53..8486430 100644
--- a/Source/FreeImage/PluginTARGA.cpp
+++ b/Source/FreeImage/PluginTARGA.cpp
@@ -39,20 +39,20 @@
 #endif
 
 typedef struct tagTGAHEADER {
-	BYTE id_length;				// ID length
-	BYTE color_map_type;		// color map type
-	BYTE image_type;			// image type
-
-	WORD cm_first_entry;		// first entry index
-	WORD cm_length;				// color map length
-	BYTE cm_size;				// color map entry size, in bits
-
-	WORD is_xorigin;			// X-origin of image
-	WORD is_yorigin;			// Y-origin of image
-	WORD is_width;				// image width
-	WORD is_height;				// image height
-	BYTE is_pixel_depth;		// pixel depth
-	BYTE is_image_descriptor;	// image descriptor
+	BYTE id_length;				//! length of the image ID field
+	BYTE color_map_type;		//! whether a color map is included
+	BYTE image_type;			//! compression and color types
+
+	WORD cm_first_entry;		//! first entry index (offset into the color map table)
+	WORD cm_length;				//! color map length (number of entries)
+	BYTE cm_size;				//! color map entry size, in bits (number of bits per pixel)
+
+	WORD is_xorigin;			//! X-origin of image (absolute coordinate of lower-left corner for displays where origin is at the lower left)
+	WORD is_yorigin;			//! Y-origin of image (as for X-origin)
+	WORD is_width;				//! image width
+	WORD is_height;				//! image height
+	BYTE is_pixel_depth;		//! bits per pixel
+	BYTE is_image_descriptor;	//! image descriptor, bits 3-0 give the alpha channel depth, bits 5-4 give direction
 } TGAHEADER;
 
 typedef struct tagTGAEXTENSIONAREA {
@@ -358,6 +358,7 @@ MimeType() {
 static BOOL 
 isTARGA20(FreeImageIO *io, fi_handle handle) {
 	const unsigned sizeofSig = 18;
+	BYTE signature[sizeofSig];
 	// tga_signature = "TRUEVISION-XFILE." (TGA 2.0 only)
 	BYTE tga_signature[sizeofSig] = { 84, 82, 85, 69, 86, 73, 83, 73, 79, 78, 45, 88, 70, 73, 76, 69, 46, 0 };
 	// get the start offset
@@ -366,13 +367,10 @@ isTARGA20(FreeImageIO *io, fi_handle handle) {
 	io->seek_proc(handle, 0, SEEK_END);
 	const long eof = io->tell_proc(handle);
 	// read the signature
-
 	io->seek_proc(handle, start_offset + eof - sizeofSig, SEEK_SET);
-		BYTE signature[sizeofSig];
-		io->read_proc(&signature, 1, sizeofSig, handle);
-		
-		// rewind
-		io->seek_proc(handle, start_offset, SEEK_SET);
+	io->read_proc(&signature, 1, sizeofSig, handle);
+	// rewind
+	io->seek_proc(handle, start_offset, SEEK_SET);
 		
 	return (memcmp(tga_signature, signature, sizeofSig) == 0);
 }
@@ -384,41 +382,59 @@ Validate(FreeImageIO *io, fi_handle handle) {
 	}
 		
 	// not a 2.0 image, try testing if it's a valid TGA anyway (not robust)
-	BOOL bResult = FALSE;
-
-	const long start_offset = io->tell_proc(handle);
-	
-	TGAHEADER header;
-	io->read_proc(&header, sizeof(tagTGAHEADER), 1, handle);
-	
-	// rewind
-	io->seek_proc(handle, start_offset, SEEK_SET);
+	{
+		const long start_offset = io->tell_proc(handle);
+		
+		// get the header
+		TGAHEADER header;
+		io->read_proc(&header, sizeof(tagTGAHEADER), 1, handle);
+#ifdef FREEIMAGE_BIGENDIAN
+		SwapHeader(&header);
+#endif
+		// rewind
+		io->seek_proc(handle, start_offset, SEEK_SET);
 
-	switch(header.image_type) {
-		case TGA_CMAP	:
-		case TGA_RGB:
-		case TGA_MONO	:
-		case TGA_RLECMAP:
-		case TGA_RLERGB:
-		case TGA_RLEMONO:
-			switch(header.is_pixel_depth) {
-				case 8	:
-				case 16:
-				case 24:
-				case 32:
-					bResult = TRUE;
-					break;
-				default:
-					bResult = FALSE;
-					break;
+		// the color map type should be a 0 or a 1...
+		if(header.color_map_type != 0 && header.color_map_type != 1) {
+			return FALSE;
+		}
+		// if the color map type is 1 then we validate the map entry information...
+		if(header.color_map_type > 0) {
+			// it doesn't make any sense if the first entry is larger than the color map table
+			if(header.cm_first_entry >= header.cm_length) {
+				return FALSE;
 			}
-			break;
-		default:
-			bResult = FALSE;
-			break;
+			// check header.cm_size, don't allow 0 or anything bigger than 32
+			if(header.cm_size == 0 || header.cm_size > 32) {
+				return FALSE;
+			}
+		}
+		// the width/height shouldn't be 0, right ?
+		if(header.is_width == 0 || header.is_height == 0) {
+			return FALSE;
+		}
+		// let's now verify all the types that are supported by FreeImage (this is our final verification)
+		switch(header.image_type) {
+			case TGA_CMAP:
+			case TGA_RGB:
+			case TGA_MONO:
+			case TGA_RLECMAP:
+			case TGA_RLERGB:
+			case TGA_RLEMONO:
+				switch(header.is_pixel_depth) {
+					case 8	:
+					case 16:
+					case 24:
+					case 32:
+						return TRUE;
+					default:
+						return FALSE;
+				}
+				break;
+			default:
+				return FALSE;
+		}
 	}
-		
-	return bResult;
 }
 
 static BOOL DLL_CALLCONV
@@ -731,8 +747,12 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
 
 					// calculate the color map size
 					csize = header.cm_length * header.cm_size / 8;
+					
+					// read the color map
 					BYTE *cmap = (BYTE*)malloc(csize * sizeof(BYTE));
-
+					if (cmap == NULL) {
+						throw FI_MSG_ERROR_DIB_MEMORY;
+					}
 					io->read_proc(cmap, sizeof(BYTE), csize, handle);
 
 					// build the palette
@@ -740,8 +760,10 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
 					switch (header.cm_size) {
 						case 16: {
 							WORD *rgb555 = (WORD*)&cmap[0];
+							unsigned start = (unsigned)header.cm_first_entry;
+							unsigned stop = MIN((unsigned)256, (unsigned)header.cm_length);
 
-							for (count = header.cm_first_entry; count < header.cm_length; count++) {
+							for (count = start; count < stop; count++) {
 								palette[count].rgbRed   = (BYTE)((((*rgb555 & FI16_555_RED_MASK) >> FI16_555_RED_SHIFT) * 0xFF) / 0x1F);
 								palette[count].rgbGreen = (BYTE)((((*rgb555 & FI16_555_GREEN_MASK) >> FI16_555_GREEN_SHIFT) * 0xFF) / 0x1F);
 								palette[count].rgbBlue  = (BYTE)((((*rgb555 & FI16_555_BLUE_MASK) >> FI16_555_BLUE_SHIFT) * 0xFF) / 0x1F);
@@ -752,8 +774,10 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
 
 						case 24: {
 							FILE_BGR *bgr = (FILE_BGR*)&cmap[0];
+							unsigned start = (unsigned)header.cm_first_entry;
+							unsigned stop = MIN((unsigned)256, (unsigned)header.cm_length);
 
-							for (count = header.cm_first_entry; count < header.cm_length; count++) {
+							for (count = start; count < stop; count++) {
 								palette[count].rgbBlue  = bgr->b;
 								palette[count].rgbGreen = bgr->g;
 								palette[count].rgbRed   = bgr->r;
@@ -769,8 +793,10 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
 							memset(trns, 0xFF, 256);
 
 							FILE_BGRA *bgra = (FILE_BGRA*)&cmap[0];
+							unsigned start = (unsigned)header.cm_first_entry;
+							unsigned stop = MIN((unsigned)256, (unsigned)header.cm_length);
 
-							for (count = header.cm_first_entry; count < header.cm_length; count++) {
+							for (count = start; count < stop; count++) {
 								palette[count].rgbBlue  = bgra->b;
 								palette[count].rgbGreen = bgra->g;
 								palette[count].rgbRed   = bgra->r;
@@ -1311,7 +1337,7 @@ Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void
 	header.is_width = (WORD)FreeImage_GetWidth(dib);
 	header.is_height = (WORD)FreeImage_GetHeight(dib);
 	header.is_pixel_depth = (BYTE)bpp;
-	header.is_image_descriptor = 0;
+	header.is_image_descriptor = (bpp == 32 ? 8 : 0);
 
 	if (palette) {
 		header.color_map_type = 1;
diff --git a/Source/FreeImage/PluginTIFF.cpp b/Source/FreeImage/PluginTIFF.cpp
index 72218a2..1b45453 100644
--- a/Source/FreeImage/PluginTIFF.cpp
+++ b/Source/FreeImage/PluginTIFF.cpp
@@ -44,29 +44,22 @@
 #include "FreeImageIO.h"
 #include "PSDParser.h"
 
-// ----------------------------------------------------------
-//   geotiff interface (see XTIFF.cpp)
-// ----------------------------------------------------------
-
-// Extended TIFF Directory GEO Tag Support
+// --------------------------------------------------------------------------
+// GeoTIFF profile (see XTIFF.cpp)
+// --------------------------------------------------------------------------
 void XTIFFInitialize();
+BOOL tiff_read_geotiff_profile(TIFF *tif, FIBITMAP *dib);
+BOOL tiff_write_geotiff_profile(TIFF *tif, FIBITMAP *dib);
 
-// GeoTIFF profile
-void tiff_read_geotiff_profile(TIFF *tif, FIBITMAP *dib);
-void tiff_write_geotiff_profile(TIFF *tif, FIBITMAP *dib);
-
-// ----------------------------------------------------------
-//   exif interface (see XTIFF.cpp)
+// --------------------------------------------------------------------------
+// TIFF Exif profile (see XTIFF.cpp)
 // ----------------------------------------------------------
-
-// TIFF Exif profile
 BOOL tiff_read_exif_tags(TIFF *tif, TagLib::MDMODEL md_model, FIBITMAP *dib);
 BOOL tiff_write_exif_tags(TIFF *tif, TagLib::MDMODEL md_model, FIBITMAP *dib);
 
-// ----------------------------------------------------------
+// --------------------------------------------------------------------------
 //   LogLuv conversion functions interface (see TIFFLogLuv.cpp)
-// ----------------------------------------------------------
-
+// --------------------------------------------------------------------------
 void tiff_ConvertLineXYZToRGB(BYTE *target, BYTE *source, double stonits, int width_in_pixels);
 void tiff_ConvertLineRGBToXYZ(BYTE *target, BYTE *source, int width_in_pixels);
 
@@ -141,13 +134,13 @@ typedef struct {
 static tmsize_t 
 _tiffReadProc(thandle_t handle, void *buf, tmsize_t size) {
 	fi_TIFFIO *fio = (fi_TIFFIO*)handle;
-	return fio->io->read_proc(buf, size, 1, fio->handle) * size;
+	return fio->io->read_proc(buf, (unsigned)size, 1, fio->handle) * size;
 }
 
 static tmsize_t
 _tiffWriteProc(thandle_t handle, void *buf, tmsize_t size) {
 	fi_TIFFIO *fio = (fi_TIFFIO*)handle;
-	return fio->io->write_proc(buf, size, 1, fio->handle) * size;
+	return fio->io->write_proc(buf, (unsigned)size, 1, fio->handle) * size;
 }
 
 static toff_t
@@ -192,24 +185,12 @@ Open a TIFF file descriptor for reading or writing
 TIFF *
 TIFFFdOpen(thandle_t handle, const char *name, const char *mode) {
 	TIFF *tif;
-
-    // Set up the callback for extended TIFF directory tag support
-	// (see XTIFF.cpp)
-    XTIFFInitialize();	
 	
 	// Open the file; the callback will set everything up
 	tif = TIFFClientOpen(name, mode, handle,
 	    _tiffReadProc, _tiffWriteProc, _tiffSeekProc, _tiffCloseProc,
 	    _tiffSizeProc, _tiffMapProc, _tiffUnmapProc);
 
-	// Warning: tif_fd is declared as 'int' currently (see libTIFF), 
-    // may result in incorrect file pointers inside libTIFF on 
-    // 64bit machines (sizeof(int) != sizeof(long)). 
-    // Needs to be fixed within libTIFF.
-	if (tif) {
-		tif->tif_fd = (long)handle;
-	}
-
 	return tif;
 }
 
@@ -936,7 +917,6 @@ tiff_write_xmp_profile(TIFF *tiff, FIBITMAP *dib) {
 static BOOL
 tiff_write_exif_profile(TIFF *tiff, FIBITMAP *dib) {
 	BOOL bResult = FALSE;
-	uint32 exif_offset = 0;
 	
 	// write EXIF_MAIN tags, EXIF_EXIF not supported yet
 	bResult = tiff_write_exif_tags(tiff, TagLib::EXIF_MAIN, dib);
@@ -1065,6 +1045,8 @@ Open(FreeImageIO *io, fi_handle handle, BOOL read) {
 	if (read) {
 		fio->tif = TIFFFdOpen((thandle_t)fio, "", "r");
 	} else {
+		// mode = "w"	: write Classic TIFF
+		// mode = "w8"	: write Big TIFF
 		fio->tif = TIFFFdOpen((thandle_t)fio, "", "w");
 	}
 	if(fio->tif == NULL) {
@@ -1109,11 +1091,10 @@ PageCount(FreeImageIO *io, fi_handle handle, void *data) {
 check for uncommon bitspersample values (e.g. 10, 12, ...)
 @param photometric TIFFTAG_PHOTOMETRIC tiff tag
 @param bitspersample TIFFTAG_BITSPERSAMPLE tiff tag
- at param samplesperpixel TIFFTAG_SAMPLESPERPIXEL tiff tag
 @return Returns FALSE if a uncommon bit-depth is encountered, returns TRUE otherwise
 */
 static BOOL 
-IsValidBitsPerSample(uint16 photometric, uint16 bitspersample, uint16 samplesperpixel) {
+IsValidBitsPerSample(uint16 photometric, uint16 bitspersample) {
 
 	switch(bitspersample) {
 		case 1:
@@ -1134,7 +1115,12 @@ IsValidBitsPerSample(uint16 photometric, uint16 bitspersample, uint16 samplesper
 			}
 			break;
 		case 32:
-			return TRUE;
+			if((photometric == PHOTOMETRIC_MINISWHITE) || (photometric == PHOTOMETRIC_MINISBLACK) || (photometric == PHOTOMETRIC_LOGLUV)) { 
+				return TRUE;
+			} else {
+				return FALSE;
+			}
+			break;
 		case 64:
 		case 128:
 			if(photometric == PHOTOMETRIC_MINISBLACK) { 
@@ -1379,7 +1365,7 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
 		// check for unsupported formats
 		// ---------------------------------------------------------------------------------
 
-		if(IsValidBitsPerSample(photometric, bitspersample, samplesperpixel) == FALSE) {
+		if(IsValidBitsPerSample(photometric, bitspersample) == FALSE) {
 			FreeImage_OutputMessageProc(s_format_id, 
 				"Unable to handle this format: bitspersample = %d, samplesperpixel = %d, photometric = %d", 
 				(int)bitspersample, (int)samplesperpixel, (int)photometric);
@@ -1894,6 +1880,7 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
 				if(buf == NULL) {
 					throw FI_MSG_ERROR_MEMORY;
 				}
+				memset(buf, 0, TIFFStripSize(tif) * sizeof(BYTE));
 				
 				BOOL bThrowMessage = FALSE;
 				
@@ -2031,8 +2018,8 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
 
 				// calculate src line and dst pitch
 				int dst_pitch = FreeImage_GetPitch(dib);
-				int tileRowSize = TIFFTileRowSize(tif);
-				int imageRowSize = TIFFScanlineSize(tif);
+				uint32 tileRowSize = (uint32)TIFFTileRowSize(tif);
+				uint32 imageRowSize = (uint32)TIFFScanlineSize(tif);
 
 
 				// In the tiff file the lines are saved from up to down 
@@ -2040,11 +2027,10 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
 
 				BYTE *bits = FreeImage_GetScanLine(dib, height - 1);
 				
-				uint32 x, y, rowSize;
-				for (y = 0; y < height; y += tileHeight) {						
+				for (uint32 y = 0; y < height; y += tileHeight) {						
 					int32 nrows = (y + tileHeight > height ? height - y : tileHeight);					
 
-					for (x = 0, rowSize = 0; x < width; x += tileWidth, rowSize += tileRowSize) {
+					for (uint32 x = 0, rowSize = 0; x < width; x += tileWidth, rowSize += tileRowSize) {
 						memset(tileBuffer, 0, tileSize);
 
 						// read one tile
@@ -2622,6 +2608,10 @@ void DLL_CALLCONV
 InitTIFF(Plugin *plugin, int format_id) {
 	s_format_id = format_id;
 
+    // Set up the callback for extended TIFF directory tag support (see XTIFF.cpp)
+	// Must be called before using libtiff
+    XTIFFInitialize();	
+
 	plugin->format_proc = Format;
 	plugin->description_proc = Description;
 	plugin->extension_proc = Extension;
diff --git a/Source/FreeImage/PluginWebP.cpp b/Source/FreeImage/PluginWebP.cpp
new file mode 100644
index 0000000..9fb0b69
--- /dev/null
+++ b/Source/FreeImage/PluginWebP.cpp
@@ -0,0 +1,698 @@
+// ==========================================================
+// Google WebP Loader & Writer
+//
+// Design and implementation by
+// - Herve Drolon (drolon at infonie.fr)
+//
+// This file is part of FreeImage 3
+//
+// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
+// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
+// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
+// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
+// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
+// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
+// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+// THIS DISCLAIMER.
+//
+// Use at your own risk!
+// ==========================================================
+
+#include "FreeImage.h"
+#include "Utilities.h"
+
+#include "../Metadata/FreeImageTag.h"
+
+#include "../LibWebP/src/webp/decode.h"
+#include "../LibWebP/src/webp/encode.h"
+#include "../LibWebP/src/enc/vp8enci.h"
+#include "../LibWebP/src/webp/mux.h"
+
+// ==========================================================
+// Plugin Interface
+// ==========================================================
+
+static int s_format_id;
+
+// ----------------------------------------------------------
+//   Helpers for the load function
+// ----------------------------------------------------------
+
+/**
+Read the whole file into memory
+*/
+static BOOL
+ReadFileToWebPData(FreeImageIO *io, fi_handle handle, WebPData * const bitstream) {
+  uint8_t *raw_data = NULL;
+
+  try {
+	  // Read the input file and put it in memory
+	  long start_pos = io->tell_proc(handle);
+	  io->seek_proc(handle, 0, SEEK_END);
+	  size_t file_length = (size_t)(io->tell_proc(handle) - start_pos);
+	  io->seek_proc(handle, start_pos, SEEK_SET);
+	  raw_data = (uint8_t*)malloc(file_length * sizeof(uint8_t));
+	  if(!raw_data) {
+		  throw FI_MSG_ERROR_MEMORY;
+	  }
+	  if(io->read_proc(raw_data, 1, (unsigned)file_length, handle) != file_length) {
+		  throw "Error while reading input stream";
+	  }
+	  
+	  // copy pointers (must be released later using free)
+	  bitstream->bytes = raw_data;
+	  bitstream->size = file_length;
+
+	  return TRUE;
+
+  } catch(const char *text) {
+	  if(raw_data) {
+		  free(raw_data);
+	  }
+	  memset(bitstream, 0, sizeof(WebPData));
+	  if(NULL != text) {
+		  FreeImage_OutputMessageProc(s_format_id, text);
+	  }
+	  return FALSE;
+  }
+}
+
+// ----------------------------------------------------------
+//   Helpers for the save function
+// ----------------------------------------------------------
+
+/**
+Output function. Should return 1 if writing was successful.
+data/data_size is the segment of data to write, and 'picture' is for
+reference (and so one can make use of picture->custom_ptr).
+*/
+static int 
+WebP_MemoryWriter(const BYTE *data, size_t data_size, const WebPPicture* const picture) {
+	FIMEMORY *hmem = (FIMEMORY*)picture->custom_ptr;
+	return data_size ? (FreeImage_WriteMemory(data, 1, (unsigned)data_size, hmem) == data_size) : 0;
+}
+
+// ==========================================================
+// Plugin Implementation
+// ==========================================================
+
+static const char * DLL_CALLCONV
+Format() {
+	return "WebP";
+}
+
+static const char * DLL_CALLCONV
+Description() {
+	return "Google WebP image format";
+}
+
+static const char * DLL_CALLCONV
+Extension() {
+	return "webp";
+}
+
+static const char * DLL_CALLCONV
+RegExpr() {
+	return NULL;
+}
+
+static const char * DLL_CALLCONV
+MimeType() {
+	return "image/webp";
+}
+
+static BOOL DLL_CALLCONV
+Validate(FreeImageIO *io, fi_handle handle) {
+	BYTE riff_signature[4] = { 0x52, 0x49, 0x46, 0x46 };
+	BYTE webp_signature[4] = { 0x57, 0x45, 0x42, 0x50 };
+	BYTE signature[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+	io->read_proc(signature, 1, 12, handle);
+
+	if(memcmp(riff_signature, signature, 4) == 0) {
+		if(memcmp(webp_signature, signature + 8, 4) == 0) {
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
+static BOOL DLL_CALLCONV
+SupportsExportDepth(int depth) {
+	return (
+		(depth == 24) || 
+		(depth == 32)
+		);
+}
+
+static BOOL DLL_CALLCONV 
+SupportsExportType(FREE_IMAGE_TYPE type) {
+	return (type == FIT_BITMAP) ? TRUE : FALSE;
+}
+
+static BOOL DLL_CALLCONV
+SupportsICCProfiles() {
+	return TRUE;
+}
+
+static BOOL DLL_CALLCONV
+SupportsNoPixels() {
+	return TRUE;
+}
+
+// ----------------------------------------------------------
+
+static void * DLL_CALLCONV
+Open(FreeImageIO *io, fi_handle handle, BOOL read) {
+	WebPMux *mux = NULL;
+	int copy_data = 1;	// 1 : copy data into the mux, 0 : keep a link to local data
+
+	if(read) {
+		// create the MUX object from the input stream
+		WebPData bitstream;
+		// read the input file and put it in memory
+		if(!ReadFileToWebPData(io, handle, &bitstream)) {
+			return NULL;
+		}
+		// create the MUX object
+		mux = WebPMuxCreate(&bitstream, copy_data);
+		// no longer needed since copy_data == 1
+		free((void*)bitstream.bytes);
+		if(mux == NULL) {
+			FreeImage_OutputMessageProc(s_format_id, "Failed to create mux object from file");
+			return NULL;
+		}
+	} else {
+		// creates an empty mux object
+		mux = WebPMuxNew();
+		if(mux == NULL) {
+			FreeImage_OutputMessageProc(s_format_id, "Failed to create empty mux object");
+			return NULL;
+		}
+	}
+	
+	return mux;
+}
+
+static void DLL_CALLCONV
+Close(FreeImageIO *io, fi_handle handle, void *data) {
+	WebPMux *mux = (WebPMux*)data;
+	if(mux != NULL) {
+		// free the MUX object
+		WebPMuxDelete(mux);
+	}
+}
+
+// ----------------------------------------------------------
+
+/**
+Decode a WebP image and returns a FIBITMAP image
+ at param webp_image Raw WebP image
+ at param flags FreeImage load flags
+ at return Returns a dib if successfull, returns NULL otherwise
+*/
+static FIBITMAP *
+DecodeImage(WebPData *webp_image, int flags) {
+	FIBITMAP *dib = NULL;
+
+	const uint8_t* data = webp_image->bytes;	// raw image data
+	const size_t data_size = webp_image->size;	// raw image size
+
+    VP8StatusCode webp_status = VP8_STATUS_OK;
+
+	BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS;
+
+	// Main object storing the configuration for advanced decoding
+	WebPDecoderConfig decoder_config;
+	// Output buffer
+	WebPDecBuffer* const output_buffer = &decoder_config.output;
+	// Features gathered from the bitstream
+	WebPBitstreamFeatures* const bitstream = &decoder_config.input;
+
+	try {
+		// Initialize the configuration as empty
+		// This function must always be called first, unless WebPGetFeatures() is to be called
+		if(!WebPInitDecoderConfig(&decoder_config)) {
+			throw "Library version mismatch";
+		}
+
+		// Retrieve features from the bitstream
+		// The bitstream structure is filled with information gathered from the bitstream
+		webp_status = WebPGetFeatures(data, data_size, bitstream);
+		if(webp_status != VP8_STATUS_OK) {
+			throw FI_MSG_ERROR_PARSING;
+		}
+
+		// Allocate output dib
+
+		unsigned bpp = bitstream->has_alpha ? 32 : 24;	
+		unsigned width = (unsigned)bitstream->width;
+		unsigned height = (unsigned)bitstream->height;
+
+		dib = FreeImage_AllocateHeader(header_only, width, height, bpp, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
+		if(!dib) {
+			throw FI_MSG_ERROR_DIB_MEMORY;
+		}
+
+		if(header_only) {
+			WebPFreeDecBuffer(output_buffer);
+			return dib;
+		}
+
+		// --- Set decoding options ---
+
+		// use multi-threaded decoding
+		decoder_config.options.use_threads = 1;
+		// set output color space
+		output_buffer->colorspace = bitstream->has_alpha ? MODE_BGRA : MODE_BGR;
+
+		// ---
+
+		// decode the input stream, taking 'config' into account. 
+		
+		webp_status = WebPDecode(data, data_size, &decoder_config);
+		if(webp_status != VP8_STATUS_OK) {
+			throw FI_MSG_ERROR_PARSING;
+		}
+
+		// fill the dib with the decoded data
+
+		const BYTE *src_bitmap = output_buffer->u.RGBA.rgba;
+		const unsigned src_pitch = (unsigned)output_buffer->u.RGBA.stride;
+
+		switch(bpp) {
+			case 24:
+				for(unsigned y = 0; y < height; y++) {
+					const BYTE *src_bits = src_bitmap + y * src_pitch;						
+					BYTE *dst_bits = (BYTE*)FreeImage_GetScanLine(dib, height-1-y);
+					for(unsigned x = 0; x < width; x++) {
+						dst_bits[FI_RGBA_BLUE]	= src_bits[0];	// B
+						dst_bits[FI_RGBA_GREEN]	= src_bits[1];	// G
+						dst_bits[FI_RGBA_RED]	= src_bits[2];	// R
+						src_bits += 3;
+						dst_bits += 3;
+					}
+				}
+				break;
+			case 32:
+				for(unsigned y = 0; y < height; y++) {
+					const BYTE *src_bits = src_bitmap + y * src_pitch;						
+					BYTE *dst_bits = (BYTE*)FreeImage_GetScanLine(dib, height-1-y);
+					for(unsigned x = 0; x < width; x++) {
+						dst_bits[FI_RGBA_BLUE]	= src_bits[0];	// B
+						dst_bits[FI_RGBA_GREEN]	= src_bits[1];	// G
+						dst_bits[FI_RGBA_RED]	= src_bits[2];	// R
+						dst_bits[FI_RGBA_ALPHA]	= src_bits[3];	// A
+						src_bits += 4;
+						dst_bits += 4;
+					}
+				}
+				break;
+		}
+
+		// Free the decoder
+		WebPFreeDecBuffer(output_buffer);
+
+		return dib;
+
+	} catch (const char *text) {
+		if(dib) {
+			FreeImage_Unload(dib);
+		}
+		WebPFreeDecBuffer(output_buffer);
+
+		if(NULL != text) {
+			FreeImage_OutputMessageProc(s_format_id, text);
+		}
+
+		return NULL;
+	}
+}
+
+static FIBITMAP * DLL_CALLCONV
+Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
+	WebPMux *mux = NULL;
+	WebPMuxFrameInfo webp_frame = { 0 };	// raw image
+	WebPData color_profile;	// ICC raw data
+	WebPData xmp_metadata;	// XMP raw data
+	WebPData exif_metadata;	// EXIF raw data
+	FIBITMAP *dib = NULL;
+	WebPMuxError error_status;
+
+	if(!handle) {
+		return NULL;
+	}
+
+	try {
+		// get the MUX object
+		mux = (WebPMux*)data;
+		if(!mux) {
+			throw (1);
+		}
+		
+		// gets the feature flags from the mux object
+		uint32_t webp_flags = 0;
+		error_status = WebPMuxGetFeatures(mux, &webp_flags);
+		if(error_status != WEBP_MUX_OK) {
+			throw (1);
+		}
+
+		// get image data
+		error_status = WebPMuxGetFrame(mux, 1, &webp_frame);
+
+		if(error_status == WEBP_MUX_OK) {
+			// decode the data (can be limited to the header if flags uses FIF_LOAD_NOPIXELS)
+			dib = DecodeImage(&webp_frame.bitstream, flags);
+			if(!dib) {
+				throw (1);
+			}
+			
+			// get ICC profile
+			if(webp_flags & ICCP_FLAG) {
+				error_status = WebPMuxGetChunk(mux, "ICCP", &color_profile);
+				if(error_status == WEBP_MUX_OK) {
+					FreeImage_CreateICCProfile(dib, (void*)color_profile.bytes, (long)color_profile.size);
+				}
+			}
+
+			// get XMP metadata
+			if(webp_flags & XMP_FLAG) {
+				error_status = WebPMuxGetChunk(mux, "XMP ", &xmp_metadata);
+				if(error_status == WEBP_MUX_OK) {
+					// create a tag
+					FITAG *tag = FreeImage_CreateTag();
+					if(tag) {
+						FreeImage_SetTagKey(tag, g_TagLib_XMPFieldName);
+						FreeImage_SetTagLength(tag, (DWORD)xmp_metadata.size);
+						FreeImage_SetTagCount(tag, (DWORD)xmp_metadata.size);
+						FreeImage_SetTagType(tag, FIDT_ASCII);
+						FreeImage_SetTagValue(tag, xmp_metadata.bytes);
+						
+						// store the tag
+						FreeImage_SetMetadata(FIMD_XMP, dib, FreeImage_GetTagKey(tag), tag);
+
+						// destroy the tag
+						FreeImage_DeleteTag(tag);
+					}
+				}
+			}
+
+			// get Exif metadata
+			if(webp_flags & EXIF_FLAG) {
+				error_status = WebPMuxGetChunk(mux, "EXIF", &exif_metadata);
+				if(error_status == WEBP_MUX_OK) {
+					// read the Exif raw data as a blob
+					jpeg_read_exif_profile_raw(dib, exif_metadata.bytes, (unsigned)exif_metadata.size);
+					// read and decode the Exif data
+					jpeg_read_exif_profile(dib, exif_metadata.bytes, (unsigned)exif_metadata.size);
+				}
+			}
+		}
+
+		WebPDataClear(&webp_frame.bitstream);
+
+		return dib;
+
+	} catch(int) {
+		WebPDataClear(&webp_frame.bitstream);
+		return NULL;
+	}
+}
+
+// --------------------------------------------------------------------------
+
+/**
+Encode a FIBITMAP to a WebP image
+ at param hmem Memory output stream, containing on return the encoded image
+ at param dib The FIBITMAP to encode
+ at param flags FreeImage save flags
+ at return Returns TRUE if successfull, returns FALSE otherwise
+*/
+static BOOL
+EncodeImage(FIMEMORY *hmem, FIBITMAP *dib, int flags) {
+	WebPPicture picture;	// Input buffer
+	WebPConfig config;		// Coding parameters
+
+	BOOL bIsFlipped = FALSE;
+
+	try {
+		const unsigned width = FreeImage_GetWidth(dib);
+		const unsigned height = FreeImage_GetHeight(dib);
+		const unsigned bpp = FreeImage_GetBPP(dib);
+		const unsigned pitch = FreeImage_GetPitch(dib);
+
+		// check image type
+		FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
+
+		if( !((image_type == FIT_BITMAP) && ((bpp == 24) || (bpp == 32))) )  {
+			throw FI_MSG_ERROR_UNSUPPORTED_FORMAT;
+		}
+
+		// check format limits
+		if(MAX(width, height) > WEBP_MAX_DIMENSION) {
+			FreeImage_OutputMessageProc(s_format_id, "Unsupported image size: width x height = %d x %d", width, height);
+			return FALSE;
+		}
+
+		// Initialize output I/O
+		if(WebPPictureInit(&picture) == 1) {
+			picture.writer = WebP_MemoryWriter;
+			picture.custom_ptr = hmem;
+			picture.width = (int)width;
+			picture.height = (int)height;
+		} else {
+			throw "Couldn't initialize WebPPicture";
+		}
+
+		// --- Set encoding parameters ---
+
+		// Initialize encoding parameters to default values
+		WebPConfigInit(&config);
+
+		// quality/speed trade-off (0=fast, 6=slower-better)
+		config.method = 6;
+
+		if((flags & WEBP_LOSSLESS) == WEBP_LOSSLESS) {
+			// lossless encoding
+			config.lossless = 1;
+			picture.use_argb = 1;
+		} else if((flags & 0x7F) > 0) {
+			// lossy encoding
+			config.lossless = 0;
+			// quality is between 1 (smallest file) and 100 (biggest) - default to 75
+			config.quality = (float)(flags & 0x7F);
+			if(config.quality > 100) {
+				config.quality = 100;
+			}
+		}
+
+		// validate encoding parameters
+		if(WebPValidateConfig(&config) == 0) {
+			throw "Failed to initialize encoder";
+		}
+
+		// --- Perform encoding ---
+		
+		// Invert dib scanlines
+		bIsFlipped = FreeImage_FlipVertical(dib);
+
+
+		// convert dib buffer to output stream
+
+		const BYTE *bits = FreeImage_GetBits(dib);
+
+#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
+		switch(bpp) {
+			case 24:
+				WebPPictureImportBGR(&picture, bits, pitch);
+				break;
+			case 32:
+				WebPPictureImportBGRA(&picture, bits, pitch);
+				break;
+		}
+#else
+		switch(bpp) {
+			case 24:
+				WebPPictureImportRGB(&picture, bits, pitch);
+				break;
+			case 32:
+				WebPPictureImportRGBA(&picture, bits, pitch);
+				break;
+		}
+
+#endif // FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
+
+		if(!WebPEncode(&config, &picture)) {
+			throw "Failed to encode image";
+		}
+
+		WebPPictureFree(&picture);
+
+		if(bIsFlipped) {
+			// invert dib scanlines
+			FreeImage_FlipVertical(dib);
+		}
+
+		return TRUE;
+
+	} catch (const char* text) {
+
+		WebPPictureFree(&picture);
+
+		if(bIsFlipped) {
+			// invert dib scanlines
+			FreeImage_FlipVertical(dib);
+		}
+
+		if(NULL != text) {
+			FreeImage_OutputMessageProc(s_format_id, text);
+		}
+	}
+
+	return FALSE;
+}
+
+static BOOL DLL_CALLCONV
+Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void *data) {
+	WebPMux *mux = NULL;
+	FIMEMORY *hmem = NULL;
+	WebPData webp_image;
+	WebPData output_data = { 0 };
+	WebPMuxError error_status;
+
+	int copy_data = 1;	// 1 : copy data into the mux, 0 : keep a link to local data
+
+	if(!dib || !handle || !data) {
+		return FALSE;
+	}
+
+	try {
+
+		// get the MUX object
+		mux = (WebPMux*)data;
+		if(!mux) {
+			return FALSE;
+		}
+
+		// --- prepare image data ---
+
+		// encode image as a WebP blob
+		hmem = FreeImage_OpenMemory();
+		if(!hmem || !EncodeImage(hmem, dib, flags)) {
+			throw (1);
+		}
+		// store the blob into the mux
+		BYTE *data = NULL;
+		DWORD data_size = 0;
+		FreeImage_AcquireMemory(hmem, &data, &data_size);
+		webp_image.bytes = data;
+		webp_image.size = data_size;
+		error_status = WebPMuxSetImage(mux, &webp_image, copy_data);
+		// no longer needed since copy_data == 1
+		FreeImage_CloseMemory(hmem);
+		hmem = NULL;
+		if(error_status != WEBP_MUX_OK) {
+			throw (1);
+		}
+
+		// --- set metadata ---
+		
+		// set ICC color profile
+		{
+			FIICCPROFILE *iccProfile = FreeImage_GetICCProfile(dib);
+			if (iccProfile->size && iccProfile->data) {
+				WebPData icc_profile;
+				icc_profile.bytes = (uint8_t*)iccProfile->data;
+				icc_profile.size = (size_t)iccProfile->size;
+				error_status = WebPMuxSetChunk(mux, "ICCP", &icc_profile, copy_data);
+				if(error_status != WEBP_MUX_OK) {
+					throw (1);
+				}
+			}
+		}
+
+		// set XMP metadata
+		{
+			FITAG *tag = NULL;
+			if(FreeImage_GetMetadata(FIMD_XMP, dib, g_TagLib_XMPFieldName, &tag)) {
+				WebPData xmp_profile;
+				xmp_profile.bytes = (uint8_t*)FreeImage_GetTagValue(tag);
+				xmp_profile.size = (size_t)FreeImage_GetTagLength(tag);
+				error_status = WebPMuxSetChunk(mux, "XMP ", &xmp_profile, copy_data);
+				if(error_status != WEBP_MUX_OK) {
+					throw (1);
+				}
+			}
+		}
+
+		// set Exif metadata
+		{
+			FITAG *tag = NULL;
+			if(FreeImage_GetMetadata(FIMD_EXIF_RAW, dib, g_TagLib_ExifRawFieldName, &tag)) {
+				WebPData exif_profile;
+				exif_profile.bytes = (uint8_t*)FreeImage_GetTagValue(tag);
+				exif_profile.size = (size_t)FreeImage_GetTagLength(tag);
+				error_status = WebPMuxSetChunk(mux, "EXIF", &exif_profile, copy_data);
+				if(error_status != WEBP_MUX_OK) {
+					throw (1);
+				}
+			}
+		}
+		
+		// get data from mux in WebP RIFF format
+		error_status = WebPMuxAssemble(mux, &output_data);
+		if(error_status != WEBP_MUX_OK) {
+			FreeImage_OutputMessageProc(s_format_id, "Failed to create webp output file");
+			throw (1);
+		}
+
+		// write the file to the output stream
+		if(io->write_proc((void*)output_data.bytes, 1, (unsigned)output_data.size, handle) != output_data.size) {
+			FreeImage_OutputMessageProc(s_format_id, "Failed to write webp output file");
+			throw (1);
+		}
+
+		// free WebP output file
+		WebPDataClear(&output_data);
+
+		return TRUE;
+
+	} catch(int) {
+		if(hmem) {
+			FreeImage_CloseMemory(hmem);
+		}
+		
+		WebPDataClear(&output_data);
+
+		return FALSE;
+	}
+}
+
+// ==========================================================
+//	 Init
+// ==========================================================
+
+void DLL_CALLCONV
+InitWEBP(Plugin *plugin, int format_id) {
+	s_format_id = format_id;
+
+	plugin->format_proc = Format;
+	plugin->description_proc = Description;
+	plugin->extension_proc = Extension;
+	plugin->regexpr_proc = RegExpr;
+	plugin->open_proc = Open;
+	plugin->close_proc = Close;
+	plugin->pagecount_proc = NULL;
+	plugin->pagecapability_proc = NULL;
+	plugin->load_proc = Load;
+	plugin->save_proc = Save;
+	plugin->validate_proc = Validate;
+	plugin->mime_proc = MimeType;
+	plugin->supports_export_bpp_proc = SupportsExportDepth;
+	plugin->supports_export_type_proc = SupportsExportType;
+	plugin->supports_icc_profiles_proc = SupportsICCProfiles;
+	plugin->supports_no_pixels_proc = SupportsNoPixels;
+}
+
diff --git a/Source/FreeImage/WuQuantizer.cpp b/Source/FreeImage/WuQuantizer.cpp
index 041eae3..66d3706 100644
--- a/Source/FreeImage/WuQuantizer.cpp
+++ b/Source/FreeImage/WuQuantizer.cpp
@@ -108,22 +108,43 @@ WuQuantizer::Hist3D(LONG *vwt, LONG *vmr, LONG *vmg, LONG *vmb, float *m2, int R
 	for(i = 0; i < 256; i++)
 		table[i] = i * i;
 
-	for(y = 0; y < height; y++) {
-		BYTE *bits = FreeImage_GetScanLine(m_dib, y);
-
-		for(x = 0; x < width; x++)	{
-			inr = (bits[FI_RGBA_RED] >> 3) + 1;
-			ing = (bits[FI_RGBA_GREEN] >> 3) + 1;
-			inb = (bits[FI_RGBA_BLUE] >> 3) + 1;
-			ind = INDEX(inr, ing, inb);
-			Qadd[y*width + x] = (WORD)ind;
-			// [inr][ing][inb]
-			vwt[ind]++;
-			vmr[ind] += bits[FI_RGBA_RED];
-			vmg[ind] += bits[FI_RGBA_GREEN];
-			vmb[ind] += bits[FI_RGBA_BLUE];
-			m2[ind] += (float)(table[bits[FI_RGBA_RED]] + table[bits[FI_RGBA_GREEN]] + table[bits[FI_RGBA_BLUE]]);
-			bits += 3;
+	if (FreeImage_GetBPP(m_dib) == 24) {
+		for(y = 0; y < height; y++) {
+			BYTE *bits = FreeImage_GetScanLine(m_dib, y);
+
+			for(x = 0; x < width; x++)	{
+				inr = (bits[FI_RGBA_RED] >> 3) + 1;
+				ing = (bits[FI_RGBA_GREEN] >> 3) + 1;
+				inb = (bits[FI_RGBA_BLUE] >> 3) + 1;
+				ind = INDEX(inr, ing, inb);
+				Qadd[y*width + x] = (WORD)ind;
+				// [inr][ing][inb]
+				vwt[ind]++;
+				vmr[ind] += bits[FI_RGBA_RED];
+				vmg[ind] += bits[FI_RGBA_GREEN];
+				vmb[ind] += bits[FI_RGBA_BLUE];
+				m2[ind] += (float)(table[bits[FI_RGBA_RED]] + table[bits[FI_RGBA_GREEN]] + table[bits[FI_RGBA_BLUE]]);
+				bits += 3;
+			}
+		}
+	} else {
+		for(y = 0; y < height; y++) {
+			BYTE *bits = FreeImage_GetScanLine(m_dib, y);
+
+			for(x = 0; x < width; x++)	{
+				inr = (bits[FI_RGBA_RED] >> 3) + 1;
+				ing = (bits[FI_RGBA_GREEN] >> 3) + 1;
+				inb = (bits[FI_RGBA_BLUE] >> 3) + 1;
+				ind = INDEX(inr, ing, inb);
+				Qadd[y*width + x] = (WORD)ind;
+				// [inr][ing][inb]
+				vwt[ind]++;
+				vmr[ind] += bits[FI_RGBA_RED];
+				vmg[ind] += bits[FI_RGBA_GREEN];
+				vmb[ind] += bits[FI_RGBA_BLUE];
+				m2[ind] += (float)(table[bits[FI_RGBA_RED]] + table[bits[FI_RGBA_GREEN]] + table[bits[FI_RGBA_BLUE]]);
+				bits += 4;
+			}
 		}
 	}
 
diff --git a/Source/FreeImage/tmoColorConvert.cpp b/Source/FreeImage/tmoColorConvert.cpp
index 66869b2..6b103a0 100644
--- a/Source/FreeImage/tmoColorConvert.cpp
+++ b/Source/FreeImage/tmoColorConvert.cpp
@@ -1,479 +1,479 @@
-// ==========================================================
-// High Dynamic Range bitmap conversion routines
-//
-// Design and implementation by
-// - Herv� Drolon (drolon at infonie.fr)
-// - Mihail Naydenov (mnaydenov at users.sourceforge.net)
-//
-// This file is part of FreeImage 3
-//
-// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
-// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
-// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
-// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
-// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
-// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
-// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
-// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
-// THIS DISCLAIMER.
-//
-// Use at your own risk!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-#include "ToneMapping.h"
-
-// ----------------------------------------------------------
-// Convert RGB to and from Yxy, same as in Reinhard et al. SIGGRAPH 2002
-// References : 
-// [1] Radiance Home Page [Online] http://radsite.lbl.gov/radiance/HOME.html
-// [2] E. Reinhard, M. Stark, P. Shirley, and J. Ferwerda,  
-//     Photographic Tone Reproduction for Digital Images, ACM Transactions on Graphics, 
-//     21(3):267-276, 2002 (Proceedings of SIGGRAPH 2002). 
-// [3] J. Tumblin and H.E. Rushmeier, 
-//     Tone Reproduction for Realistic Images. IEEE Computer Graphics and Applications, 
-//     13(6):42-48, 1993.
-// ----------------------------------------------------------
-
-/**
-nominal CRT primaries 
-*/
-/*
-static const float CIE_x_r = 0.640F;
-static const float CIE_y_r = 0.330F;
-static const float CIE_x_g = 0.290F;
-static const float CIE_y_g = 0.600F;
-static const float CIE_x_b = 0.150F;
-static const float CIE_y_b = 0.060F;
-static const float CIE_x_w = 0.3333F;	// use true white
-static const float CIE_y_w = 0.3333F;
-*/
-/**
-sRGB primaries
-*/
-static const float CIE_x_r = 0.640F;
-static const float CIE_y_r = 0.330F;
-static const float CIE_x_g = 0.300F;
-static const float CIE_y_g = 0.600F;
-static const float CIE_x_b = 0.150F;
-static const float CIE_y_b = 0.060F;
-static const float CIE_x_w = 0.3127F;	// Illuminant D65
-static const float CIE_y_w = 0.3290F;
-
-static const float CIE_D = ( CIE_x_r*(CIE_y_g - CIE_y_b) + CIE_x_g*(CIE_y_b - CIE_y_r) + CIE_x_b*(CIE_y_r - CIE_y_g) );
-static const float CIE_C_rD = ( (1/CIE_y_w) * ( CIE_x_w*(CIE_y_g - CIE_y_b) - CIE_y_w*(CIE_x_g - CIE_x_b) + CIE_x_g*CIE_y_b - CIE_x_b*CIE_y_g) );
-static const float CIE_C_gD = ( (1/CIE_y_w) * ( CIE_x_w*(CIE_y_b - CIE_y_r) - CIE_y_w*(CIE_x_b - CIE_x_r) - CIE_x_r*CIE_y_b + CIE_x_b*CIE_y_r) );
-static const float CIE_C_bD = ( (1/CIE_y_w) * ( CIE_x_w*(CIE_y_r - CIE_y_g) - CIE_y_w*(CIE_x_r - CIE_x_g) + CIE_x_r*CIE_y_g - CIE_x_g*CIE_y_r) );
-
-/**
-RGB to XYZ (no white balance)
-*/
-static const float  RGB2XYZ[3][3] = {
-	{ CIE_x_r*CIE_C_rD / CIE_D, 
-	  CIE_x_g*CIE_C_gD / CIE_D, 
-	  CIE_x_b*CIE_C_bD / CIE_D 
-	},
-	{ CIE_y_r*CIE_C_rD / CIE_D, 
-	  CIE_y_g*CIE_C_gD / CIE_D, 
-	  CIE_y_b*CIE_C_bD / CIE_D 
-	},
-	{ (1 - CIE_x_r-CIE_y_r)*CIE_C_rD / CIE_D,
-	  (1 - CIE_x_g-CIE_y_g)*CIE_C_gD / CIE_D,
-	  (1 - CIE_x_b-CIE_y_b)*CIE_C_bD / CIE_D
-	}
-};
-
-/**
-XYZ to RGB (no white balance)
-*/
-static const float  XYZ2RGB[3][3] = {
-	{(CIE_y_g - CIE_y_b - CIE_x_b*CIE_y_g + CIE_y_b*CIE_x_g) / CIE_C_rD,
-	 (CIE_x_b - CIE_x_g - CIE_x_b*CIE_y_g + CIE_x_g*CIE_y_b) / CIE_C_rD,
-	 (CIE_x_g*CIE_y_b - CIE_x_b*CIE_y_g) / CIE_C_rD
-	},
-	{(CIE_y_b - CIE_y_r - CIE_y_b*CIE_x_r + CIE_y_r*CIE_x_b) / CIE_C_gD,
-	 (CIE_x_r - CIE_x_b - CIE_x_r*CIE_y_b + CIE_x_b*CIE_y_r) / CIE_C_gD,
-	 (CIE_x_b*CIE_y_r - CIE_x_r*CIE_y_b) / CIE_C_gD
-	},
-	{(CIE_y_r - CIE_y_g - CIE_y_r*CIE_x_g + CIE_y_g*CIE_x_r) / CIE_C_bD,
-	 (CIE_x_g - CIE_x_r - CIE_x_g*CIE_y_r + CIE_x_r*CIE_y_g) / CIE_C_bD,
-	 (CIE_x_r*CIE_y_g - CIE_x_g*CIE_y_r) / CIE_C_bD
-	}
-};
-
-/**
-This gives approximately the following matrices : 
-
-static const float RGB2XYZ[3][3] = { 
-	{ 0.41239083F, 0.35758433F, 0.18048081F },
-	{ 0.21263903F, 0.71516865F, 0.072192319F },
-	{ 0.019330820F, 0.11919473F, 0.95053220F }
-};
-static const float XYZ2RGB[3][3] = { 
-	{ 3.2409699F, -1.5373832F, -0.49861079F },
-	{ -0.96924376F, 1.8759676F, 0.041555084F },
-	{ 0.055630036F, -0.20397687F, 1.0569715F }
-};
-*/
-
-// ----------------------------------------------------------
-
-static const float EPSILON = 1e-06F;
-static const float INF = 1e+10F;
-
-/**
-Convert in-place floating point RGB data to Yxy.<br>
-On output, pixel->red == Y, pixel->green == x, pixel->blue == y
- at param dib Input RGBF / Output Yxy image
- at return Returns TRUE if successful, returns FALSE otherwise
-*/
-BOOL 
-ConvertInPlaceRGBFToYxy(FIBITMAP *dib) {
-	float result[3];
-
-	if(FreeImage_GetImageType(dib) != FIT_RGBF)
-		return FALSE;
-
-	const unsigned width  = FreeImage_GetWidth(dib);
-	const unsigned height = FreeImage_GetHeight(dib);
-	const unsigned pitch  = FreeImage_GetPitch(dib);
-	
-	BYTE *bits = (BYTE*)FreeImage_GetBits(dib);
-	for(unsigned y = 0; y < height; y++) {
-		FIRGBF *pixel = (FIRGBF*)bits;
-		for(unsigned x = 0; x < width; x++) {
-			result[0] = result[1] = result[2] = 0;
-			for (int i = 0; i < 3; i++) {
-				result[i] += RGB2XYZ[i][0] * pixel[x].red;
-				result[i] += RGB2XYZ[i][1] * pixel[x].green;
-				result[i] += RGB2XYZ[i][2] * pixel[x].blue;
-			}
-			const float W = result[0] + result[1] + result[2];
-			const float Y = result[1];
-			if(W > 0) { 
-				pixel[x].red   = Y;			    // Y 
-				pixel[x].green = result[0] / W;	// x 
-				pixel[x].blue  = result[1] / W;	// y 	
-			} else {
-				pixel[x].red = pixel[x].green = pixel[x].blue = 0;
-			}
-		}
-		// next line
-		bits += pitch;
-	}
-
-	return TRUE;
-}
-
-/**
-Convert in-place Yxy image to floating point RGB data.<br>
-On input, pixel->red == Y, pixel->green == x, pixel->blue == y
- at param dib Input Yxy / Output RGBF image
- at return Returns TRUE if successful, returns FALSE otherwise
-*/
-BOOL 
-ConvertInPlaceYxyToRGBF(FIBITMAP *dib) {
-	float result[3];
-	float X, Y, Z;
-
-	if(FreeImage_GetImageType(dib) != FIT_RGBF)
-		return FALSE;
-
-	const unsigned width  = FreeImage_GetWidth(dib);
-	const unsigned height = FreeImage_GetHeight(dib);
-	const unsigned pitch  = FreeImage_GetPitch(dib);
-
-	BYTE *bits = (BYTE*)FreeImage_GetBits(dib);
-	for(unsigned y = 0; y < height; y++) {
-		FIRGBF *pixel = (FIRGBF*)bits;
-		for(unsigned x = 0; x < width; x++) {
-			Y = pixel[x].red;	        // Y 
-			result[1] = pixel[x].green;	// x 
-			result[2] = pixel[x].blue;	// y 
-			if ((Y > EPSILON) && (result[1] > EPSILON) && (result[2] > EPSILON)) {
-				X = (result[1] * Y) / result[2];
-				Z = (X / result[1]) - X - Y;
-			} else {
-				X = Z = EPSILON;
-			}
-			pixel[x].red   = X;
-			pixel[x].green = Y;
-			pixel[x].blue  = Z;
-			result[0] = result[1] = result[2] = 0;
-			for (int i = 0; i < 3; i++) {
-				result[i] += XYZ2RGB[i][0] * pixel[x].red;
-				result[i] += XYZ2RGB[i][1] * pixel[x].green;
-				result[i] += XYZ2RGB[i][2] * pixel[x].blue;
-			}
-			pixel[x].red   = result[0];	// R
-			pixel[x].green = result[1];	// G
-			pixel[x].blue  = result[2];	// B
-		}
-		// next line
-		bits += pitch;
-	}
-
-	return TRUE;
-}
-
-/**
-Get the maximum, minimum and average luminance.<br>
-On input, pixel->red == Y, pixel->green == x, pixel->blue == y
- at param Yxy Source Yxy image to analyze
- at param maxLum Maximum luminance
- at param minLum Minimum luminance
- at param worldLum Average luminance (world adaptation luminance)
- at return Returns TRUE if successful, returns FALSE otherwise
-*/
-BOOL 
-LuminanceFromYxy(FIBITMAP *Yxy, float *maxLum, float *minLum, float *worldLum) {
-	if(FreeImage_GetImageType(Yxy) != FIT_RGBF)
-		return FALSE;
-
-	const unsigned width  = FreeImage_GetWidth(Yxy);
-	const unsigned height = FreeImage_GetHeight(Yxy);
-	const unsigned pitch  = FreeImage_GetPitch(Yxy);
-
-	float max_lum = 0, min_lum = 0;
-	double sum = 0;
-
-	BYTE *bits = (BYTE*)FreeImage_GetBits(Yxy);
-	for(unsigned y = 0; y < height; y++) {
-		const FIRGBF *pixel = (FIRGBF*)bits;
-		for(unsigned x = 0; x < width; x++) {
-			const float Y = pixel[x].red;
-			max_lum = (max_lum < Y) ? Y : max_lum;	// max Luminance in the scene
-			min_lum = (min_lum < Y) ? min_lum : Y;	// min Luminance in the scene
-			sum += log(2.3e-5F + Y);				// contrast constant in Tumblin paper
-		}
-		// next line
-		bits += pitch;
-	}
-	// maximum luminance
-	*maxLum = max_lum;
-	// minimum luminance
-	*minLum = min_lum;
-	// average log luminance
-	double avgLogLum = (sum / (width * height));
-	// world adaptation luminance
-	*worldLum = (float)exp(avgLogLum);
-
-	return TRUE;
-}
-
-/**
-Clamp RGBF image highest values to display white, 
-then convert to 24-bit RGB
-*/
-FIBITMAP* 
-ClampConvertRGBFTo24(FIBITMAP *src) {
-	if(FreeImage_GetImageType(src) != FIT_RGBF)
-		return FALSE;
-
-	const unsigned width  = FreeImage_GetWidth(src);
-	const unsigned height = FreeImage_GetHeight(src);
-
-	FIBITMAP *dst = FreeImage_Allocate(width, height, 24, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
-	if(!dst) return NULL;
-
-	const unsigned src_pitch  = FreeImage_GetPitch(src);
-	const unsigned dst_pitch  = FreeImage_GetPitch(dst);
-
-	BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
-	BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
-
-	for(unsigned y = 0; y < height; y++) {
-		const FIRGBF *src_pixel = (FIRGBF*)src_bits;
-		BYTE *dst_pixel = (BYTE*)dst_bits;
-		for(unsigned x = 0; x < width; x++) {
-			const float red   = (src_pixel[x].red > 1)   ? 1 : src_pixel[x].red;
-			const float green = (src_pixel[x].green > 1) ? 1 : src_pixel[x].green;
-			const float blue  = (src_pixel[x].blue > 1)  ? 1 : src_pixel[x].blue;
-			
-			dst_pixel[FI_RGBA_RED]   = (BYTE)(255.0F * red   + 0.5F);
-			dst_pixel[FI_RGBA_GREEN] = (BYTE)(255.0F * green + 0.5F);
-			dst_pixel[FI_RGBA_BLUE]  = (BYTE)(255.0F * blue  + 0.5F);
-			dst_pixel += 3;
-		}
-		src_bits += src_pitch;
-		dst_bits += dst_pitch;
-	}
-
-	return dst;
-}
-
-/**
-Extract the luminance channel L from a RGBF image. 
-Luminance is calculated from the sRGB model (RGB2XYZ matrix) 
-using a D65 white point : 
-L = ( 0.2126 * r ) + ( 0.7152 * g ) + ( 0.0722 * b )
-Reference : 
-A Standard Default Color Space for the Internet - sRGB. 
-[online] http://www.w3.org/Graphics/Color/sRGB
-*/
-FIBITMAP*  
-ConvertRGBFToY(FIBITMAP *src) {
-	if(FreeImage_GetImageType(src) != FIT_RGBF)
-		return FALSE;
-
-	const unsigned width  = FreeImage_GetWidth(src);
-	const unsigned height = FreeImage_GetHeight(src);
-
-	FIBITMAP *dst = FreeImage_AllocateT(FIT_FLOAT, width, height);
-	if(!dst) return NULL;
-
-	const unsigned src_pitch  = FreeImage_GetPitch(src);
-	const unsigned dst_pitch  = FreeImage_GetPitch(dst);
-
-	
-	BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
-	BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
-
-	for(unsigned y = 0; y < height; y++) {
-		const FIRGBF *src_pixel = (FIRGBF*)src_bits;
-		float  *dst_pixel = (float*)dst_bits;
-		for(unsigned x = 0; x < width; x++) {
-			const float L = LUMA_REC709(src_pixel[x].red, src_pixel[x].green, src_pixel[x].blue);
-			dst_pixel[x] = (L > 0) ? L : 0;
-		}
-		// next line
-		src_bits += src_pitch;
-		dst_bits += dst_pitch;
-	}
-
-	return dst;
-}
-
-/**
-Get the maximum, minimum, average luminance and log average luminance from a Y image
- at param dib Source Y image to analyze
- at param maxLum Maximum luminance
- at param minLum Minimum luminance
- at param Lav Average luminance
- at param Llav Log average luminance (also known as 'world adaptation luminance')
- at return Returns TRUE if successful, returns FALSE otherwise
- at see ConvertRGBFToY, FreeImage_TmoReinhard05Ex
-*/
-BOOL 
-LuminanceFromY(FIBITMAP *dib, float *maxLum, float *minLum, float *Lav, float *Llav) {
-	if(FreeImage_GetImageType(dib) != FIT_FLOAT)
-		return FALSE;
-
-	unsigned width  = FreeImage_GetWidth(dib);
-	unsigned height = FreeImage_GetHeight(dib);
-	unsigned pitch  = FreeImage_GetPitch(dib);
-
-	float max_lum = -1e20F, min_lum = 1e20F;
-	double sumLum = 0, sumLogLum = 0;
-
-	BYTE *bits = (BYTE*)FreeImage_GetBits(dib);
-	for(unsigned y = 0; y < height; y++) {
-		const float *pixel = (float*)bits;
-		for(unsigned x = 0; x < width; x++) {
-			const float Y = pixel[x];
-			max_lum = (max_lum < Y) ? Y : max_lum;				// max Luminance in the scene
-			min_lum = ((Y > 0) && (min_lum < Y)) ? min_lum : Y;	// min Luminance in the scene
-			sumLum += Y;										// average luminance
-			sumLogLum += log(2.3e-5F + Y);						// contrast constant in Tumblin paper
-		}
-		// next line
-		bits += pitch;
-	}
-
-	// maximum luminance
-	*maxLum = max_lum;
-	// minimum luminance
-	*minLum = min_lum;
-	// average luminance
-	*Lav = (float)(sumLum / (width * height));
-	// average log luminance, a.k.a. world adaptation luminance
-	*Llav = (float)exp(sumLogLum / (width * height));
-
-	return TRUE;
-}
-// --------------------------------------------------------------------------
-
-static void findMaxMinPercentile(FIBITMAP *Y, float minPrct, float *minLum, float maxPrct, float *maxLum) {
-	int x, y;
-	int width = FreeImage_GetWidth(Y);
-	int height = FreeImage_GetHeight(Y);
-	int pitch = FreeImage_GetPitch(Y);
-
-	std::vector<float> vY(width * height);
-
-	BYTE *bits = (BYTE*)FreeImage_GetBits(Y);
-	for(y = 0; y < height; y++) {
-		float *pixel = (float*)bits;
-		for(x = 0; x < width; x++) {
-			if(pixel[x] != 0) {
-				vY.push_back(pixel[x]);
-			}
-		}
-		bits += pitch;
-	}
-
-	std::sort(vY.begin(), vY.end());
-	
-	*minLum = vY.at( int(minPrct * vY.size()) );
-	*maxLum = vY.at( int(maxPrct * vY.size()) );
-}
-
-/**
-Clipping function<br>
-Remove any extremely bright and/or extremely dark pixels 
-and normalize between 0 and 1. 
- at param Y Input/Output image
- at param minPrct Minimum percentile
- at param maxPrct Maximum percentile
-*/
-void 
-NormalizeY(FIBITMAP *Y, float minPrct, float maxPrct) {
-	int x, y;
-	float maxLum, minLum;
-
-	if(minPrct > maxPrct) {
-		// swap values
-		float t = minPrct; minPrct = maxPrct; maxPrct = t;
-	}
-	if(minPrct < 0) minPrct = 0;
-	if(maxPrct > 1) maxPrct = 1;
-
-	int width = FreeImage_GetWidth(Y);
-	int height = FreeImage_GetHeight(Y);
-	int pitch = FreeImage_GetPitch(Y);
-
-	// find max & min luminance values
-	if((minPrct > 0) || (maxPrct < 1)) {
-		maxLum = 0, minLum = 0;
-		findMaxMinPercentile(Y, minPrct, &minLum, maxPrct, &maxLum);
-	} else {
-		maxLum = -1e20F, minLum = 1e20F;
-		BYTE *bits = (BYTE*)FreeImage_GetBits(Y);
-		for(y = 0; y < height; y++) {
-			const float *pixel = (float*)bits;
-			for(x = 0; x < width; x++) {
-				const float value = pixel[x];
-				maxLum = (maxLum < value) ? value : maxLum;	// max Luminance in the scene
-				minLum = (minLum < value) ? minLum : value;	// min Luminance in the scene
-			}
-			// next line
-			bits += pitch;
-		}
-	}
-	if(maxLum == minLum) return;
-
-	// normalize to range 0..1 
-	const float divider = maxLum - minLum;
-	BYTE *bits = (BYTE*)FreeImage_GetBits(Y);
-	for(y = 0; y < height; y++) {
-		float *pixel = (float*)bits;
-		for(x = 0; x < width; x++) {
-			pixel[x] = (pixel[x] - minLum) / divider;
-			if(pixel[x] <= 0) pixel[x] = EPSILON;
-			if(pixel[x] > 1) pixel[x] = 1;
-		}
-		// next line
-		bits += pitch;
-	}
-}
+// ==========================================================
+// High Dynamic Range bitmap conversion routines
+//
+// Design and implementation by
+// - Herv� Drolon (drolon at infonie.fr)
+// - Mihail Naydenov (mnaydenov at users.sourceforge.net)
+//
+// This file is part of FreeImage 3
+//
+// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
+// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
+// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
+// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
+// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
+// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
+// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+// THIS DISCLAIMER.
+//
+// Use at your own risk!
+// ==========================================================
+
+#include "FreeImage.h"
+#include "Utilities.h"
+#include "ToneMapping.h"
+
+// ----------------------------------------------------------
+// Convert RGB to and from Yxy, same as in Reinhard et al. SIGGRAPH 2002
+// References : 
+// [1] Radiance Home Page [Online] http://radsite.lbl.gov/radiance/HOME.html
+// [2] E. Reinhard, M. Stark, P. Shirley, and J. Ferwerda,  
+//     Photographic Tone Reproduction for Digital Images, ACM Transactions on Graphics, 
+//     21(3):267-276, 2002 (Proceedings of SIGGRAPH 2002). 
+// [3] J. Tumblin and H.E. Rushmeier, 
+//     Tone Reproduction for Realistic Images. IEEE Computer Graphics and Applications, 
+//     13(6):42-48, 1993.
+// ----------------------------------------------------------
+
+/**
+nominal CRT primaries 
+*/
+/*
+static const float CIE_x_r = 0.640F;
+static const float CIE_y_r = 0.330F;
+static const float CIE_x_g = 0.290F;
+static const float CIE_y_g = 0.600F;
+static const float CIE_x_b = 0.150F;
+static const float CIE_y_b = 0.060F;
+static const float CIE_x_w = 0.3333F;	// use true white
+static const float CIE_y_w = 0.3333F;
+*/
+/**
+sRGB primaries
+*/
+static const float CIE_x_r = 0.640F;
+static const float CIE_y_r = 0.330F;
+static const float CIE_x_g = 0.300F;
+static const float CIE_y_g = 0.600F;
+static const float CIE_x_b = 0.150F;
+static const float CIE_y_b = 0.060F;
+static const float CIE_x_w = 0.3127F;	// Illuminant D65
+static const float CIE_y_w = 0.3290F;
+
+static const float CIE_D = ( CIE_x_r*(CIE_y_g - CIE_y_b) + CIE_x_g*(CIE_y_b - CIE_y_r) + CIE_x_b*(CIE_y_r - CIE_y_g) );
+static const float CIE_C_rD = ( (1/CIE_y_w) * ( CIE_x_w*(CIE_y_g - CIE_y_b) - CIE_y_w*(CIE_x_g - CIE_x_b) + CIE_x_g*CIE_y_b - CIE_x_b*CIE_y_g) );
+static const float CIE_C_gD = ( (1/CIE_y_w) * ( CIE_x_w*(CIE_y_b - CIE_y_r) - CIE_y_w*(CIE_x_b - CIE_x_r) - CIE_x_r*CIE_y_b + CIE_x_b*CIE_y_r) );
+static const float CIE_C_bD = ( (1/CIE_y_w) * ( CIE_x_w*(CIE_y_r - CIE_y_g) - CIE_y_w*(CIE_x_r - CIE_x_g) + CIE_x_r*CIE_y_g - CIE_x_g*CIE_y_r) );
+
+/**
+RGB to XYZ (no white balance)
+*/
+static const float  RGB2XYZ[3][3] = {
+	{ CIE_x_r*CIE_C_rD / CIE_D, 
+	  CIE_x_g*CIE_C_gD / CIE_D, 
+	  CIE_x_b*CIE_C_bD / CIE_D 
+	},
+	{ CIE_y_r*CIE_C_rD / CIE_D, 
+	  CIE_y_g*CIE_C_gD / CIE_D, 
+	  CIE_y_b*CIE_C_bD / CIE_D 
+	},
+	{ (1 - CIE_x_r-CIE_y_r)*CIE_C_rD / CIE_D,
+	  (1 - CIE_x_g-CIE_y_g)*CIE_C_gD / CIE_D,
+	  (1 - CIE_x_b-CIE_y_b)*CIE_C_bD / CIE_D
+	}
+};
+
+/**
+XYZ to RGB (no white balance)
+*/
+static const float  XYZ2RGB[3][3] = {
+	{(CIE_y_g - CIE_y_b - CIE_x_b*CIE_y_g + CIE_y_b*CIE_x_g) / CIE_C_rD,
+	 (CIE_x_b - CIE_x_g - CIE_x_b*CIE_y_g + CIE_x_g*CIE_y_b) / CIE_C_rD,
+	 (CIE_x_g*CIE_y_b - CIE_x_b*CIE_y_g) / CIE_C_rD
+	},
+	{(CIE_y_b - CIE_y_r - CIE_y_b*CIE_x_r + CIE_y_r*CIE_x_b) / CIE_C_gD,
+	 (CIE_x_r - CIE_x_b - CIE_x_r*CIE_y_b + CIE_x_b*CIE_y_r) / CIE_C_gD,
+	 (CIE_x_b*CIE_y_r - CIE_x_r*CIE_y_b) / CIE_C_gD
+	},
+	{(CIE_y_r - CIE_y_g - CIE_y_r*CIE_x_g + CIE_y_g*CIE_x_r) / CIE_C_bD,
+	 (CIE_x_g - CIE_x_r - CIE_x_g*CIE_y_r + CIE_x_r*CIE_y_g) / CIE_C_bD,
+	 (CIE_x_r*CIE_y_g - CIE_x_g*CIE_y_r) / CIE_C_bD
+	}
+};
+
+/**
+This gives approximately the following matrices : 
+
+static const float RGB2XYZ[3][3] = { 
+	{ 0.41239083F, 0.35758433F, 0.18048081F },
+	{ 0.21263903F, 0.71516865F, 0.072192319F },
+	{ 0.019330820F, 0.11919473F, 0.95053220F }
+};
+static const float XYZ2RGB[3][3] = { 
+	{ 3.2409699F, -1.5373832F, -0.49861079F },
+	{ -0.96924376F, 1.8759676F, 0.041555084F },
+	{ 0.055630036F, -0.20397687F, 1.0569715F }
+};
+*/
+
+// ----------------------------------------------------------
+
+static const float EPSILON = 1e-06F;
+static const float INF = 1e+10F;
+
+/**
+Convert in-place floating point RGB data to Yxy.<br>
+On output, pixel->red == Y, pixel->green == x, pixel->blue == y
+ at param dib Input RGBF / Output Yxy image
+ at return Returns TRUE if successful, returns FALSE otherwise
+*/
+BOOL 
+ConvertInPlaceRGBFToYxy(FIBITMAP *dib) {
+	float result[3];
+
+	if(FreeImage_GetImageType(dib) != FIT_RGBF)
+		return FALSE;
+
+	const unsigned width  = FreeImage_GetWidth(dib);
+	const unsigned height = FreeImage_GetHeight(dib);
+	const unsigned pitch  = FreeImage_GetPitch(dib);
+	
+	BYTE *bits = (BYTE*)FreeImage_GetBits(dib);
+	for(unsigned y = 0; y < height; y++) {
+		FIRGBF *pixel = (FIRGBF*)bits;
+		for(unsigned x = 0; x < width; x++) {
+			result[0] = result[1] = result[2] = 0;
+			for (int i = 0; i < 3; i++) {
+				result[i] += RGB2XYZ[i][0] * pixel[x].red;
+				result[i] += RGB2XYZ[i][1] * pixel[x].green;
+				result[i] += RGB2XYZ[i][2] * pixel[x].blue;
+			}
+			const float W = result[0] + result[1] + result[2];
+			const float Y = result[1];
+			if(W > 0) { 
+				pixel[x].red   = Y;			    // Y 
+				pixel[x].green = result[0] / W;	// x 
+				pixel[x].blue  = result[1] / W;	// y 	
+			} else {
+				pixel[x].red = pixel[x].green = pixel[x].blue = 0;
+			}
+		}
+		// next line
+		bits += pitch;
+	}
+
+	return TRUE;
+}
+
+/**
+Convert in-place Yxy image to floating point RGB data.<br>
+On input, pixel->red == Y, pixel->green == x, pixel->blue == y
+ at param dib Input Yxy / Output RGBF image
+ at return Returns TRUE if successful, returns FALSE otherwise
+*/
+BOOL 
+ConvertInPlaceYxyToRGBF(FIBITMAP *dib) {
+	float result[3];
+	float X, Y, Z;
+
+	if(FreeImage_GetImageType(dib) != FIT_RGBF)
+		return FALSE;
+
+	const unsigned width  = FreeImage_GetWidth(dib);
+	const unsigned height = FreeImage_GetHeight(dib);
+	const unsigned pitch  = FreeImage_GetPitch(dib);
+
+	BYTE *bits = (BYTE*)FreeImage_GetBits(dib);
+	for(unsigned y = 0; y < height; y++) {
+		FIRGBF *pixel = (FIRGBF*)bits;
+		for(unsigned x = 0; x < width; x++) {
+			Y = pixel[x].red;	        // Y 
+			result[1] = pixel[x].green;	// x 
+			result[2] = pixel[x].blue;	// y 
+			if ((Y > EPSILON) && (result[1] > EPSILON) && (result[2] > EPSILON)) {
+				X = (result[1] * Y) / result[2];
+				Z = (X / result[1]) - X - Y;
+			} else {
+				X = Z = EPSILON;
+			}
+			pixel[x].red   = X;
+			pixel[x].green = Y;
+			pixel[x].blue  = Z;
+			result[0] = result[1] = result[2] = 0;
+			for (int i = 0; i < 3; i++) {
+				result[i] += XYZ2RGB[i][0] * pixel[x].red;
+				result[i] += XYZ2RGB[i][1] * pixel[x].green;
+				result[i] += XYZ2RGB[i][2] * pixel[x].blue;
+			}
+			pixel[x].red   = result[0];	// R
+			pixel[x].green = result[1];	// G
+			pixel[x].blue  = result[2];	// B
+		}
+		// next line
+		bits += pitch;
+	}
+
+	return TRUE;
+}
+
+/**
+Get the maximum, minimum and average luminance.<br>
+On input, pixel->red == Y, pixel->green == x, pixel->blue == y
+ at param Yxy Source Yxy image to analyze
+ at param maxLum Maximum luminance
+ at param minLum Minimum luminance
+ at param worldLum Average luminance (world adaptation luminance)
+ at return Returns TRUE if successful, returns FALSE otherwise
+*/
+BOOL 
+LuminanceFromYxy(FIBITMAP *Yxy, float *maxLum, float *minLum, float *worldLum) {
+	if(FreeImage_GetImageType(Yxy) != FIT_RGBF)
+		return FALSE;
+
+	const unsigned width  = FreeImage_GetWidth(Yxy);
+	const unsigned height = FreeImage_GetHeight(Yxy);
+	const unsigned pitch  = FreeImage_GetPitch(Yxy);
+
+	float max_lum = 0, min_lum = 0;
+	double sum = 0;
+
+	BYTE *bits = (BYTE*)FreeImage_GetBits(Yxy);
+	for(unsigned y = 0; y < height; y++) {
+		const FIRGBF *pixel = (FIRGBF*)bits;
+		for(unsigned x = 0; x < width; x++) {
+			const float Y = MAX(0.0F, pixel[x].red);// avoid negative values
+			max_lum = (max_lum < Y) ? Y : max_lum;	// max Luminance in the scene
+			min_lum = (min_lum < Y) ? min_lum : Y;	// min Luminance in the scene
+			sum += log(2.3e-5F + Y);				// contrast constant in Tumblin paper
+		}
+		// next line
+		bits += pitch;
+	}
+	// maximum luminance
+	*maxLum = max_lum;
+	// minimum luminance
+	*minLum = min_lum;
+	// average log luminance
+	double avgLogLum = (sum / (width * height));
+	// world adaptation luminance
+	*worldLum = (float)exp(avgLogLum);
+
+	return TRUE;
+}
+
+/**
+Clamp RGBF image highest values to display white, 
+then convert to 24-bit RGB
+*/
+FIBITMAP* 
+ClampConvertRGBFTo24(FIBITMAP *src) {
+	if(FreeImage_GetImageType(src) != FIT_RGBF)
+		return FALSE;
+
+	const unsigned width  = FreeImage_GetWidth(src);
+	const unsigned height = FreeImage_GetHeight(src);
+
+	FIBITMAP *dst = FreeImage_Allocate(width, height, 24, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
+	if(!dst) return NULL;
+
+	const unsigned src_pitch  = FreeImage_GetPitch(src);
+	const unsigned dst_pitch  = FreeImage_GetPitch(dst);
+
+	BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
+	BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
+
+	for(unsigned y = 0; y < height; y++) {
+		const FIRGBF *src_pixel = (FIRGBF*)src_bits;
+		BYTE *dst_pixel = (BYTE*)dst_bits;
+		for(unsigned x = 0; x < width; x++) {
+			const float red   = (src_pixel[x].red > 1)   ? 1 : src_pixel[x].red;
+			const float green = (src_pixel[x].green > 1) ? 1 : src_pixel[x].green;
+			const float blue  = (src_pixel[x].blue > 1)  ? 1 : src_pixel[x].blue;
+			
+			dst_pixel[FI_RGBA_RED]   = (BYTE)(255.0F * red   + 0.5F);
+			dst_pixel[FI_RGBA_GREEN] = (BYTE)(255.0F * green + 0.5F);
+			dst_pixel[FI_RGBA_BLUE]  = (BYTE)(255.0F * blue  + 0.5F);
+			dst_pixel += 3;
+		}
+		src_bits += src_pitch;
+		dst_bits += dst_pitch;
+	}
+
+	return dst;
+}
+
+/**
+Extract the luminance channel L from a RGBF image. 
+Luminance is calculated from the sRGB model (RGB2XYZ matrix) 
+using a D65 white point : 
+L = ( 0.2126 * r ) + ( 0.7152 * g ) + ( 0.0722 * b )
+Reference : 
+A Standard Default Color Space for the Internet - sRGB. 
+[online] http://www.w3.org/Graphics/Color/sRGB
+*/
+FIBITMAP*  
+ConvertRGBFToY(FIBITMAP *src) {
+	if(FreeImage_GetImageType(src) != FIT_RGBF)
+		return FALSE;
+
+	const unsigned width  = FreeImage_GetWidth(src);
+	const unsigned height = FreeImage_GetHeight(src);
+
+	FIBITMAP *dst = FreeImage_AllocateT(FIT_FLOAT, width, height);
+	if(!dst) return NULL;
+
+	const unsigned src_pitch  = FreeImage_GetPitch(src);
+	const unsigned dst_pitch  = FreeImage_GetPitch(dst);
+
+	
+	BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
+	BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
+
+	for(unsigned y = 0; y < height; y++) {
+		const FIRGBF *src_pixel = (FIRGBF*)src_bits;
+		float  *dst_pixel = (float*)dst_bits;
+		for(unsigned x = 0; x < width; x++) {
+			const float L = LUMA_REC709(src_pixel[x].red, src_pixel[x].green, src_pixel[x].blue);
+			dst_pixel[x] = (L > 0) ? L : 0;
+		}
+		// next line
+		src_bits += src_pitch;
+		dst_bits += dst_pitch;
+	}
+
+	return dst;
+}
+
+/**
+Get the maximum, minimum, average luminance and log average luminance from a Y image
+ at param dib Source Y image to analyze
+ at param maxLum Maximum luminance
+ at param minLum Minimum luminance
+ at param Lav Average luminance
+ at param Llav Log average luminance (also known as 'world adaptation luminance')
+ at return Returns TRUE if successful, returns FALSE otherwise
+ at see ConvertRGBFToY, FreeImage_TmoReinhard05Ex
+*/
+BOOL 
+LuminanceFromY(FIBITMAP *dib, float *maxLum, float *minLum, float *Lav, float *Llav) {
+	if(FreeImage_GetImageType(dib) != FIT_FLOAT)
+		return FALSE;
+
+	unsigned width  = FreeImage_GetWidth(dib);
+	unsigned height = FreeImage_GetHeight(dib);
+	unsigned pitch  = FreeImage_GetPitch(dib);
+
+	float max_lum = -1e20F, min_lum = 1e20F;
+	double sumLum = 0, sumLogLum = 0;
+
+	BYTE *bits = (BYTE*)FreeImage_GetBits(dib);
+	for(unsigned y = 0; y < height; y++) {
+		const float *pixel = (float*)bits;
+		for(unsigned x = 0; x < width; x++) {
+			const float Y = pixel[x];
+			max_lum = (max_lum < Y) ? Y : max_lum;				// max Luminance in the scene
+			min_lum = ((Y > 0) && (min_lum < Y)) ? min_lum : Y;	// min Luminance in the scene
+			sumLum += Y;										// average luminance
+			sumLogLum += log(2.3e-5F + Y);						// contrast constant in Tumblin paper
+		}
+		// next line
+		bits += pitch;
+	}
+
+	// maximum luminance
+	*maxLum = max_lum;
+	// minimum luminance
+	*minLum = min_lum;
+	// average luminance
+	*Lav = (float)(sumLum / (width * height));
+	// average log luminance, a.k.a. world adaptation luminance
+	*Llav = (float)exp(sumLogLum / (width * height));
+
+	return TRUE;
+}
+// --------------------------------------------------------------------------
+
+static void findMaxMinPercentile(FIBITMAP *Y, float minPrct, float *minLum, float maxPrct, float *maxLum) {
+	int x, y;
+	int width = FreeImage_GetWidth(Y);
+	int height = FreeImage_GetHeight(Y);
+	int pitch = FreeImage_GetPitch(Y);
+
+	std::vector<float> vY(width * height);
+
+	BYTE *bits = (BYTE*)FreeImage_GetBits(Y);
+	for(y = 0; y < height; y++) {
+		float *pixel = (float*)bits;
+		for(x = 0; x < width; x++) {
+			if(pixel[x] != 0) {
+				vY.push_back(pixel[x]);
+			}
+		}
+		bits += pitch;
+	}
+
+	std::sort(vY.begin(), vY.end());
+	
+	*minLum = vY.at( int(minPrct * vY.size()) );
+	*maxLum = vY.at( int(maxPrct * vY.size()) );
+}
+
+/**
+Clipping function<br>
+Remove any extremely bright and/or extremely dark pixels 
+and normalize between 0 and 1. 
+ at param Y Input/Output image
+ at param minPrct Minimum percentile
+ at param maxPrct Maximum percentile
+*/
+void 
+NormalizeY(FIBITMAP *Y, float minPrct, float maxPrct) {
+	int x, y;
+	float maxLum, minLum;
+
+	if(minPrct > maxPrct) {
+		// swap values
+		float t = minPrct; minPrct = maxPrct; maxPrct = t;
+	}
+	if(minPrct < 0) minPrct = 0;
+	if(maxPrct > 1) maxPrct = 1;
+
+	int width = FreeImage_GetWidth(Y);
+	int height = FreeImage_GetHeight(Y);
+	int pitch = FreeImage_GetPitch(Y);
+
+	// find max & min luminance values
+	if((minPrct > 0) || (maxPrct < 1)) {
+		maxLum = 0, minLum = 0;
+		findMaxMinPercentile(Y, minPrct, &minLum, maxPrct, &maxLum);
+	} else {
+		maxLum = -1e20F, minLum = 1e20F;
+		BYTE *bits = (BYTE*)FreeImage_GetBits(Y);
+		for(y = 0; y < height; y++) {
+			const float *pixel = (float*)bits;
+			for(x = 0; x < width; x++) {
+				const float value = pixel[x];
+				maxLum = (maxLum < value) ? value : maxLum;	// max Luminance in the scene
+				minLum = (minLum < value) ? minLum : value;	// min Luminance in the scene
+			}
+			// next line
+			bits += pitch;
+		}
+	}
+	if(maxLum == minLum) return;
+
+	// normalize to range 0..1 
+	const float divider = maxLum - minLum;
+	BYTE *bits = (BYTE*)FreeImage_GetBits(Y);
+	for(y = 0; y < height; y++) {
+		float *pixel = (float*)bits;
+		for(x = 0; x < width; x++) {
+			pixel[x] = (pixel[x] - minLum) / divider;
+			if(pixel[x] <= 0) pixel[x] = EPSILON;
+			if(pixel[x] > 1) pixel[x] = 1;
+		}
+		// next line
+		bits += pitch;
+	}
+}
diff --git a/Source/FreeImage/tmoDrago03.cpp b/Source/FreeImage/tmoDrago03.cpp
index a615344..d46a8c8 100644
--- a/Source/FreeImage/tmoDrago03.cpp
+++ b/Source/FreeImage/tmoDrago03.cpp
@@ -1,295 +1,295 @@
-// ==========================================================
-// Tone mapping operator (Drago, 2003)
-//
-// Design and implementation by
-// - Herv� Drolon (drolon at infonie.fr)
-//
-// This file is part of FreeImage 3
-//
-// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
-// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
-// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
-// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
-// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
-// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
-// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
-// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
-// THIS DISCLAIMER.
-//
-// Use at your own risk!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-#include "ToneMapping.h"
-
-// ----------------------------------------------------------
-// Logarithmic mapping operator
-// Reference: 
-// [1] F. Drago, K. Myszkowski, T. Annen, and N. Chiba, 
-// Adaptive Logarithmic Mapping for Displaying High Contrast Scenes, 
-// Eurographics 2003.
-// ----------------------------------------------------------
-
-/**
-Bias function
-*/
-static inline double 
-biasFunction(const double b, const double x) {
-	return pow (x, b);		// pow(x, log(bias)/log(0.5)
-}
-
-/**
-Pad� approximation of log(x + 1)
-x(6+x)/(6+4x) good if x < 1
-x*(6 + 0.7662x)/(5.9897 + 3.7658x) between 1 and 2
-See http://www.nezumi.demon.co.uk/consult/logx.htm
-*/
-static inline double 
-pade_log(const double x) {
-	if(x < 1) {
-		return (x * (6 + x) / (6 + 4 * x));
-	} else if(x < 2) {
-		return (x * (6 + 0.7662 * x) / (5.9897 + 3.7658 * x));
-	}
-	return log(x + 1);
-}
-
-/**
-Log mapping operator
- at param dib Input / Output Yxy image
- at param maxLum Maximum luminance
- at param avgLum Average luminance (world adaptation luminance)
- at param biasParam Bias parameter (a zero value default to 0.85)
- at param exposure Exposure parameter (default to 0)
- at return Returns TRUE if successful, returns FALSE otherwise
-*/
-static BOOL 
-ToneMappingDrago03(FIBITMAP *dib, const float maxLum, const float avgLum, float biasParam, const float exposure) {
-	const float LOG05 = -0.693147F;	// log(0.5) 
-
-	double Lmax, divider, interpol, biasP;
-	unsigned x, y;
-	double L;
-
-	if(FreeImage_GetImageType(dib) != FIT_RGBF)
-		return FALSE;
-
-	const unsigned width  = FreeImage_GetWidth(dib);
-	const unsigned height = FreeImage_GetHeight(dib);
-	const unsigned pitch  = FreeImage_GetPitch(dib);
-
-
-	// arbitrary Bias Parameter 
-	if(biasParam == 0) 
-		biasParam = 0.85F;
-
-	// normalize maximum luminance by average luminance
-	Lmax = maxLum / avgLum;
-	
-	divider = log10(Lmax+1);
-	biasP = log(biasParam)/LOG05;
-
-#if !defined(DRAGO03_FAST)
-
-	/**
-	Normal tone mapping of every pixel
-	further acceleration is obtained by a Pad� approximation of log(x + 1)
-	*/
-	BYTE *bits = (BYTE*)FreeImage_GetBits(dib);
-	for(y = 0; y < height; y++) {
-		FIRGBF *pixel = (FIRGBF*)bits;
-		for(x = 0; x < width; x++) {
-			double Yw = pixel[x].red / avgLum;
-			Yw *= exposure;
-			interpol = log(2 + biasFunction(biasP, Yw / Lmax) * 8);
-			L = pade_log(Yw);// log(Yw + 1)
-			pixel[x].red = (float)((L / interpol) / divider);
-		}
-		// next line
-		bits += pitch;
-	}
-
-#else
-	unsigned index;
-	int i, j;
-
-	unsigned max_width  = width - (width % 3);
-	unsigned max_height = height - (height % 3); 
-	unsigned fpitch = pitch / sizeof(FIRGBF);
-
-	/**
-	fast tone mapping
-	split the image into 3x3 pixel tiles and perform the computation for each group of 9 pixels
-	further acceleration is obtained by a Pad� approximation of log(x + 1)
-	=> produce artifacts and not so faster, so the code has been disabled
-	*/
-#define PIXEL(x, y)	image[y*fpitch + x].red
-
-	FIRGBF *image = (FIRGBF*)FreeImage_GetBits(dib);
-	for(y = 0; y < max_height; y += 3) {
-		for(x = 0; x < max_width; x += 3) {
-			double average = 0;
-			for(i = 0; i < 3; i++) {
-				for(j = 0; j < 3; j++) {
-					index = (y + i)*fpitch + (x + j);
-					image[index].red /= (float)avgLum;
-					image[index].red *= exposure; 
-					average += image[index].red;
-				}
-			}
-			average = average / 9 - PIXEL(x, y);
-			if(average > -1 && average < 1) {
-				interpol = log(2 + pow(PIXEL(x + 1, y + 1) / Lmax, biasP) * 8);
-				for(i = 0; i < 3; i++) {
-					for(j = 0; j < 3; j++) {
-						index = (y + i)*fpitch + (x + j);
-						L = pade_log(image[index].red);// log(image[index].red + 1)
-						image[index].red = (float)((L / interpol) / divider);
-					}
-				}
-			}
-			else {
-				for(i = 0; i < 3; i++) {
-					for(j = 0; j < 3; j++) {
-						index = (y + i)*fpitch + (x + j);
-						interpol = log(2 + pow(image[index].red / Lmax, biasP) * 8);
-						L = pade_log(image[index].red);// log(image[index].red + 1)
-						image[index].red = (float)((L / interpol) / divider);
-					}
-				}
-			}
-		} //x
-	} // y
-
-	/**
-	Normal tone mapping of every pixel for the remaining right and bottom bands
-	*/
-	BYTE *bits;
-
-	// right band
-	bits = (BYTE*)FreeImage_GetBits(dib);
-	for(y = 0; y < height; y++) {
-		FIRGBF *pixel = (FIRGBF*)bits;
-		for(x = max_width; x < width; x++) {
-			double Yw = pixel[x].red / avgLum;
-			Yw *= exposure;
-			interpol = log(2 + biasFunction(biasP, Yw / Lmax) * 8);
-			L = pade_log(Yw);// log(Yw + 1)
-			pixel[x].red = (float)((L / interpol) / divider);
-		}
-		// next line
-		bits += pitch;
-	}
-	// bottom band
-	bits = (BYTE*)FreeImage_GetBits(dib);
-	for(y = max_height; y < height; y++) {
-		FIRGBF *pixel = (FIRGBF*)bits;
-		for(x = 0; x < max_width; x++) {
-			double Yw = pixel[x].red / avgLum;
-			Yw *= exposure;
-			interpol = log(2 + biasFunction(biasP, Yw / Lmax) * 8);
-			L = pade_log(Yw);// log(Yw + 1)
-			pixel[x].red = (float)((L / interpol) / divider);
-		}
-		// next line
-		bits += pitch;
-	}
-
-#endif	// DRAGO03_FAST
-
-	return TRUE;
-}
-
-/**
-Custom gamma correction based on the ITU-R BT.709 standard
- at param dib RGBF image to be corrected
- at param gammaval Gamma value (2.2 is a good default value)
- at return Returns TRUE if successful, returns FALSE otherwise
-*/
-static BOOL 
-REC709GammaCorrection(FIBITMAP *dib, const float gammaval) {
-	if(FreeImage_GetImageType(dib) != FIT_RGBF)
-		return FALSE;
-
-	float slope = 4.5F;
-	float start = 0.018F;
-	
-	const float fgamma = (float)((0.45 / gammaval) * 2);
-	if(gammaval >= 2.1F) {
-		start = (float)(0.018 / ((gammaval - 2) * 7.5));
-		slope = (float)(4.5 * ((gammaval - 2) * 7.5));
-	} else if (gammaval <= 1.9F) {
-		start = (float)(0.018 * ((2 - gammaval) * 7.5));
-		slope = (float)(4.5 / ((2 - gammaval) * 7.5));
-	}
-
-	const unsigned width  = FreeImage_GetWidth(dib);
-	const unsigned height = FreeImage_GetHeight(dib);
-	const unsigned pitch  = FreeImage_GetPitch(dib);
-
-	BYTE *bits = (BYTE*)FreeImage_GetBits(dib);
-	for(unsigned y = 0; y < height; y++) {
-		float *pixel = (float*)bits;
-		for(unsigned x = 0; x < width; x++) {
-			for(int i = 0; i < 3; i++) {
-				*pixel = (*pixel <= start) ? *pixel * slope : (1.099F * pow(*pixel, fgamma) - 0.099F);
-				pixel++;
-			}
-		}
-		bits += pitch;
-	}
-
-	return TRUE;
-}
-
-// ----------------------------------------------------------
-//  Main algorithm
-// ----------------------------------------------------------
-
-/**
-Apply the Adaptive Logarithmic Mapping operator to a HDR image and convert to 24-bit RGB
- at param src Input RGB16 or RGB[A]F image
- at param gamma Gamma correction (gamma > 0). 1 means no correction, 2.2 in the original paper.
- at param exposure Exposure parameter (0 means no correction, 0 in the original paper)
- at return Returns a 24-bit RGB image if successful, returns NULL otherwise
-*/
-FIBITMAP* DLL_CALLCONV 
-FreeImage_TmoDrago03(FIBITMAP *src, double gamma, double exposure) {
-	float maxLum, minLum, avgLum;
-
-	if(!FreeImage_HasPixels(src)) return NULL;
-
-	// working RGBF variable
-	FIBITMAP *dib = NULL;
-
-	dib = FreeImage_ConvertToRGBF(src);
-	if(!dib) return NULL;
-
-	// default algorithm parameters
-	const float biasParam = 0.85F;
-	const float expoParam = (float)pow(2.0, exposure); //default exposure is 1, 2^0
-
-	// convert to Yxy
-	ConvertInPlaceRGBFToYxy(dib);
-	// get the luminance
-	LuminanceFromYxy(dib, &maxLum, &minLum, &avgLum);
-	// perform the tone mapping
-	ToneMappingDrago03(dib, maxLum, avgLum, biasParam, expoParam);
-	// convert back to RGBF
-	ConvertInPlaceYxyToRGBF(dib);
-	if(gamma != 1) {
-		// perform gamma correction
-		REC709GammaCorrection(dib, (float)gamma);
-	}
-	// clamp image highest values to display white, then convert to 24-bit RGB
-	FIBITMAP *dst = ClampConvertRGBFTo24(dib);
-
-	// clean-up and return
-	FreeImage_Unload(dib);
-
-	// copy metadata from src to dst
-	FreeImage_CloneMetadata(dst, src);
-	
-	return dst;
-}
+// ==========================================================
+// Tone mapping operator (Drago, 2003)
+//
+// Design and implementation by
+// - Herv� Drolon (drolon at infonie.fr)
+//
+// This file is part of FreeImage 3
+//
+// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
+// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
+// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
+// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
+// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
+// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
+// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+// THIS DISCLAIMER.
+//
+// Use at your own risk!
+// ==========================================================
+
+#include "FreeImage.h"
+#include "Utilities.h"
+#include "ToneMapping.h"
+
+// ----------------------------------------------------------
+// Logarithmic mapping operator
+// Reference: 
+// [1] F. Drago, K. Myszkowski, T. Annen, and N. Chiba, 
+// Adaptive Logarithmic Mapping for Displaying High Contrast Scenes, 
+// Eurographics 2003.
+// ----------------------------------------------------------
+
+/**
+Bias function
+*/
+static inline double 
+biasFunction(const double b, const double x) {
+	return pow (x, b);		// pow(x, log(bias)/log(0.5)
+}
+
+/**
+Pad� approximation of log(x + 1)
+x(6+x)/(6+4x) good if x < 1
+x*(6 + 0.7662x)/(5.9897 + 3.7658x) between 1 and 2
+See http://www.nezumi.demon.co.uk/consult/logx.htm
+*/
+static inline double 
+pade_log(const double x) {
+	if(x < 1) {
+		return (x * (6 + x) / (6 + 4 * x));
+	} else if(x < 2) {
+		return (x * (6 + 0.7662 * x) / (5.9897 + 3.7658 * x));
+	}
+	return log(x + 1);
+}
+
+/**
+Log mapping operator
+ at param dib Input / Output Yxy image
+ at param maxLum Maximum luminance
+ at param avgLum Average luminance (world adaptation luminance)
+ at param biasParam Bias parameter (a zero value default to 0.85)
+ at param exposure Exposure parameter (default to 0)
+ at return Returns TRUE if successful, returns FALSE otherwise
+*/
+static BOOL 
+ToneMappingDrago03(FIBITMAP *dib, const float maxLum, const float avgLum, float biasParam, const float exposure) {
+	const float LOG05 = -0.693147F;	// log(0.5) 
+
+	double Lmax, divider, interpol, biasP;
+	unsigned x, y;
+	double L;
+
+	if(FreeImage_GetImageType(dib) != FIT_RGBF)
+		return FALSE;
+
+	const unsigned width  = FreeImage_GetWidth(dib);
+	const unsigned height = FreeImage_GetHeight(dib);
+	const unsigned pitch  = FreeImage_GetPitch(dib);
+
+
+	// arbitrary Bias Parameter 
+	if(biasParam == 0) 
+		biasParam = 0.85F;
+
+	// normalize maximum luminance by average luminance
+	Lmax = maxLum / avgLum;
+	
+	divider = log10(Lmax+1);
+	biasP = log(biasParam)/LOG05;
+
+#if !defined(DRAGO03_FAST)
+
+	/**
+	Normal tone mapping of every pixel
+	further acceleration is obtained by a Pad� approximation of log(x + 1)
+	*/
+	BYTE *bits = (BYTE*)FreeImage_GetBits(dib);
+	for(y = 0; y < height; y++) {
+		FIRGBF *pixel = (FIRGBF*)bits;
+		for(x = 0; x < width; x++) {
+			double Yw = pixel[x].red / avgLum;
+			Yw *= exposure;
+			interpol = log(2 + biasFunction(biasP, Yw / Lmax) * 8);
+			L = pade_log(Yw);// log(Yw + 1)
+			pixel[x].red = (float)((L / interpol) / divider);
+		}
+		// next line
+		bits += pitch;
+	}
+
+#else
+	unsigned index;
+	int i, j;
+
+	unsigned max_width  = width - (width % 3);
+	unsigned max_height = height - (height % 3); 
+	unsigned fpitch = pitch / sizeof(FIRGBF);
+
+	/**
+	fast tone mapping
+	split the image into 3x3 pixel tiles and perform the computation for each group of 9 pixels
+	further acceleration is obtained by a Pad� approximation of log(x + 1)
+	=> produce artifacts and not so faster, so the code has been disabled
+	*/
+#define PIXEL(x, y)	image[y*fpitch + x].red
+
+	FIRGBF *image = (FIRGBF*)FreeImage_GetBits(dib);
+	for(y = 0; y < max_height; y += 3) {
+		for(x = 0; x < max_width; x += 3) {
+			double average = 0;
+			for(i = 0; i < 3; i++) {
+				for(j = 0; j < 3; j++) {
+					index = (y + i)*fpitch + (x + j);
+					image[index].red /= (float)avgLum;
+					image[index].red *= exposure; 
+					average += image[index].red;
+				}
+			}
+			average = average / 9 - PIXEL(x, y);
+			if(average > -1 && average < 1) {
+				interpol = log(2 + pow(PIXEL(x + 1, y + 1) / Lmax, biasP) * 8);
+				for(i = 0; i < 3; i++) {
+					for(j = 0; j < 3; j++) {
+						index = (y + i)*fpitch + (x + j);
+						L = pade_log(image[index].red);// log(image[index].red + 1)
+						image[index].red = (float)((L / interpol) / divider);
+					}
+				}
+			}
+			else {
+				for(i = 0; i < 3; i++) {
+					for(j = 0; j < 3; j++) {
+						index = (y + i)*fpitch + (x + j);
+						interpol = log(2 + pow(image[index].red / Lmax, biasP) * 8);
+						L = pade_log(image[index].red);// log(image[index].red + 1)
+						image[index].red = (float)((L / interpol) / divider);
+					}
+				}
+			}
+		} //x
+	} // y
+
+	/**
+	Normal tone mapping of every pixel for the remaining right and bottom bands
+	*/
+	BYTE *bits;
+
+	// right band
+	bits = (BYTE*)FreeImage_GetBits(dib);
+	for(y = 0; y < height; y++) {
+		FIRGBF *pixel = (FIRGBF*)bits;
+		for(x = max_width; x < width; x++) {
+			double Yw = pixel[x].red / avgLum;
+			Yw *= exposure;
+			interpol = log(2 + biasFunction(biasP, Yw / Lmax) * 8);
+			L = pade_log(Yw);// log(Yw + 1)
+			pixel[x].red = (float)((L / interpol) / divider);
+		}
+		// next line
+		bits += pitch;
+	}
+	// bottom band
+	bits = (BYTE*)FreeImage_GetBits(dib);
+	for(y = max_height; y < height; y++) {
+		FIRGBF *pixel = (FIRGBF*)bits;
+		for(x = 0; x < max_width; x++) {
+			double Yw = pixel[x].red / avgLum;
+			Yw *= exposure;
+			interpol = log(2 + biasFunction(biasP, Yw / Lmax) * 8);
+			L = pade_log(Yw);// log(Yw + 1)
+			pixel[x].red = (float)((L / interpol) / divider);
+		}
+		// next line
+		bits += pitch;
+	}
+
+#endif	// DRAGO03_FAST
+
+	return TRUE;
+}
+
+/**
+Custom gamma correction based on the ITU-R BT.709 standard
+ at param dib RGBF image to be corrected
+ at param gammaval Gamma value (2.2 is a good default value)
+ at return Returns TRUE if successful, returns FALSE otherwise
+*/
+static BOOL 
+REC709GammaCorrection(FIBITMAP *dib, const float gammaval) {
+	if(FreeImage_GetImageType(dib) != FIT_RGBF)
+		return FALSE;
+
+	float slope = 4.5F;
+	float start = 0.018F;
+	
+	const float fgamma = (float)((0.45 / gammaval) * 2);
+	if(gammaval >= 2.1F) {
+		start = (float)(0.018 / ((gammaval - 2) * 7.5));
+		slope = (float)(4.5 * ((gammaval - 2) * 7.5));
+	} else if (gammaval <= 1.9F) {
+		start = (float)(0.018 * ((2 - gammaval) * 7.5));
+		slope = (float)(4.5 / ((2 - gammaval) * 7.5));
+	}
+
+	const unsigned width  = FreeImage_GetWidth(dib);
+	const unsigned height = FreeImage_GetHeight(dib);
+	const unsigned pitch  = FreeImage_GetPitch(dib);
+
+	BYTE *bits = (BYTE*)FreeImage_GetBits(dib);
+	for(unsigned y = 0; y < height; y++) {
+		float *pixel = (float*)bits;
+		for(unsigned x = 0; x < width; x++) {
+			for(int i = 0; i < 3; i++) {
+				*pixel = (*pixel <= start) ? *pixel * slope : (1.099F * pow(*pixel, fgamma) - 0.099F);
+				pixel++;
+			}
+		}
+		bits += pitch;
+	}
+
+	return TRUE;
+}
+
+// ----------------------------------------------------------
+//  Main algorithm
+// ----------------------------------------------------------
+
+/**
+Apply the Adaptive Logarithmic Mapping operator to a HDR image and convert to 24-bit RGB
+ at param src Input RGB16 or RGB[A]F image
+ at param gamma Gamma correction (gamma > 0). 1 means no correction, 2.2 in the original paper.
+ at param exposure Exposure parameter (0 means no correction, 0 in the original paper)
+ at return Returns a 24-bit RGB image if successful, returns NULL otherwise
+*/
+FIBITMAP* DLL_CALLCONV 
+FreeImage_TmoDrago03(FIBITMAP *src, double gamma, double exposure) {
+	float maxLum, minLum, avgLum;
+
+	if(!FreeImage_HasPixels(src)) return NULL;
+
+	// working RGBF variable
+	FIBITMAP *dib = NULL;
+
+	dib = FreeImage_ConvertToRGBF(src);
+	if(!dib) return NULL;
+
+	// default algorithm parameters
+	const float biasParam = 0.85F;
+	const float expoParam = (float)pow(2.0, exposure); //default exposure is 1, 2^0
+
+	// convert to Yxy
+	ConvertInPlaceRGBFToYxy(dib);
+	// get the luminance
+	LuminanceFromYxy(dib, &maxLum, &minLum, &avgLum);
+	// perform the tone mapping
+	ToneMappingDrago03(dib, maxLum, avgLum, biasParam, expoParam);
+	// convert back to RGBF
+	ConvertInPlaceYxyToRGBF(dib);
+	if(gamma != 1) {
+		// perform gamma correction
+		REC709GammaCorrection(dib, (float)gamma);
+	}
+	// clamp image highest values to display white, then convert to 24-bit RGB
+	FIBITMAP *dst = ClampConvertRGBFTo24(dib);
+
+	// clean-up and return
+	FreeImage_Unload(dib);
+
+	// copy metadata from src to dst
+	FreeImage_CloneMetadata(dst, src);
+	
+	return dst;
+}
diff --git a/Source/FreeImage/tmoFattal02.cpp b/Source/FreeImage/tmoFattal02.cpp
index 88f0544..c63f91f 100644
--- a/Source/FreeImage/tmoFattal02.cpp
+++ b/Source/FreeImage/tmoFattal02.cpp
@@ -1,689 +1,689 @@
-// ==========================================================
-// Tone mapping operator (Fattal, 2002)
-//
-// Design and implementation by
-// - Herv� Drolon (drolon at infonie.fr)
-//
-// This file is part of FreeImage 3
-//
-// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
-// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
-// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
-// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
-// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
-// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
-// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
-// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
-// THIS DISCLAIMER.
-//
-// Use at your own risk!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-#include "ToneMapping.h"
-
-// ----------------------------------------------------------
-// Gradient domain HDR compression
-// Reference:
-// [1] R. Fattal, D. Lischinski, and M.Werman, 
-// Gradient domain high dynamic range compression,
-// ACM Transactions on Graphics, special issue on Proc. of ACM SIGGRAPH 2002, 
-// San Antonio, Texas, vol. 21(3), pp. 257-266, 2002.
-// ----------------------------------------------------------
-
-static const float EPSILON = 1e-4F;
-
-/**
-Performs a 5 by 5 gaussian filtering using two 1D convolutions, 
-followed by a subsampling by 2. 
- at param dib Input image
- at return Returns a blurred image of size SIZE(dib)/2
- at see GaussianPyramid
-*/
-static FIBITMAP* GaussianLevel5x5(FIBITMAP *dib) {
-	FIBITMAP *h_dib = NULL, *v_dib = NULL, *dst = NULL;
-	float *src_pixel, *dst_pixel;
-
-	try {
-		const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
-		if(image_type != FIT_FLOAT) throw(1);
-
-		const unsigned width = FreeImage_GetWidth(dib);
-		const unsigned height = FreeImage_GetHeight(dib);
-
-		h_dib = FreeImage_AllocateT(image_type, width, height);
-		v_dib = FreeImage_AllocateT(image_type, width, height);
-		if(!h_dib || !v_dib) throw(1);
-
-		const unsigned pitch = FreeImage_GetPitch(dib) / sizeof(float);
-
-		// horizontal convolution dib -> h_dib
-
-		src_pixel = (float*)FreeImage_GetBits(dib);
-		dst_pixel = (float*)FreeImage_GetBits(h_dib);
-
-		for(unsigned y = 0; y < height; y++) {
-			// work on line y
-			for(unsigned x = 2; x < width - 2; x++) {
-				dst_pixel[x] = src_pixel[x-2] + src_pixel[x+2] + 4 * (src_pixel[x-1] + src_pixel[x+1]) + 6 * src_pixel[x];
-				dst_pixel[x] /= 16;
-			}
-			// boundary mirroring
-			dst_pixel[0] = (2 * src_pixel[2] + 8 * src_pixel[1] + 6 * src_pixel[0]) / 16;
-			dst_pixel[1] = (src_pixel[3] + 4 * (src_pixel[0] + src_pixel[2]) + 7 * src_pixel[1]) / 16;
-			dst_pixel[width-2] = (src_pixel[width-4] + 5 * src_pixel[width-1] + 4 * src_pixel[width-3] + 6 * src_pixel[width-2]) / 16;
-			dst_pixel[width-1] = (src_pixel[width-3] + 5 * src_pixel[width-2] + 10 * src_pixel[width-1]) / 16;
-
-			// next line
-			src_pixel += pitch;
-			dst_pixel += pitch;
-		}
-
-		// vertical convolution h_dib -> v_dib
-
-		src_pixel = (float*)FreeImage_GetBits(h_dib);
-		dst_pixel = (float*)FreeImage_GetBits(v_dib);
-
-		for(unsigned x = 0; x < width; x++) {		
-			// work on column x
-			for(unsigned y = 2; y < height - 2; y++) {
-				const unsigned index = y*pitch + x;
-				dst_pixel[index] = src_pixel[index-2*pitch] + src_pixel[index+2*pitch] + 4 * (src_pixel[index-pitch] + src_pixel[index+pitch]) + 6 * src_pixel[index];
-				dst_pixel[index] /= 16;
-			}
-			// boundary mirroring
-			dst_pixel[x] = (2 * src_pixel[x+2*pitch] + 8 * src_pixel[x+pitch] + 6 * src_pixel[x]) / 16;
-			dst_pixel[x+pitch] = (src_pixel[x+3*pitch] + 4 * (src_pixel[x] + src_pixel[x+2*pitch]) + 7 * src_pixel[x+pitch]) / 16;
-			dst_pixel[(height-2)*pitch+x] = (src_pixel[(height-4)*pitch+x] + 5 * src_pixel[(height-1)*pitch+x] + 4 * src_pixel[(height-3)*pitch+x] + 6 * src_pixel[(height-2)*pitch+x]) / 16;
-			dst_pixel[(height-1)*pitch+x] = (src_pixel[(height-3)*pitch+x] + 5 * src_pixel[(height-2)*pitch+x] + 10 * src_pixel[(height-1)*pitch+x]) / 16;
-		}
-
-		FreeImage_Unload(h_dib); h_dib = NULL;
-
-		// perform downsampling
-
-		dst = FreeImage_Rescale(v_dib, width/2, height/2, FILTER_BILINEAR);
-
-		FreeImage_Unload(v_dib);
-
-		return dst;
-
-	} catch(int) {
-		if(h_dib) FreeImage_Unload(h_dib);
-		if(v_dib) FreeImage_Unload(v_dib);
-		if(dst) FreeImage_Unload(dst);
-		return NULL;
-	}
-}
-
-/**
-Compute a Gaussian pyramid using the specified number of levels. 
- at param H Original bitmap
- at param pyramid Resulting pyramid array 
- at param nlevels Number of resolution levels
- at return Returns TRUE if successful, returns FALSE otherwise
-*/
-static BOOL GaussianPyramid(FIBITMAP *H, FIBITMAP **pyramid, int nlevels) {
-	try {
-		// first level is the original image
-		pyramid[0] = FreeImage_Clone(H);
-		if(pyramid[0] == NULL) throw(1);
-		// compute next levels
-		for(int k = 1; k < nlevels; k++) {
-			pyramid[k] = GaussianLevel5x5(pyramid[k-1]);
-			if(pyramid[k] == NULL) throw(1);
-		}
-		return TRUE;
-	} catch(int) {
-		for(int k = 0; k < nlevels; k++) {
-			if(pyramid[k] != NULL) {
-				FreeImage_Unload(pyramid[k]);
-				pyramid[k] = NULL;
-			}
-		}
-		return FALSE;
-	}
-}
-
-/**
-Compute the gradient magnitude of an input image H using central differences, 
-and returns the average gradient. 
- at param H Input image
- at param avgGrad [out] Average gradient
- at param k Level number
- at return Returns the gradient magnitude if successful, returns NULL otherwise
- at see GradientPyramid
-*/
-static FIBITMAP* GradientLevel(FIBITMAP *H, float *avgGrad, int k) {
-	FIBITMAP *G = NULL;
-
-	try {
-		const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(H);
-		if(image_type != FIT_FLOAT) throw(1);
-
-		const unsigned width = FreeImage_GetWidth(H);
-		const unsigned height = FreeImage_GetHeight(H);
-
-		G = FreeImage_AllocateT(image_type, width, height);
-		if(!G) throw(1);
-		
-		const unsigned pitch = FreeImage_GetPitch(H) / sizeof(float);
-		
-		const float divider = (float)(1 << (k + 1));
-		float average = 0;
-		
-		float *src_pixel = (float*)FreeImage_GetBits(H);
-		float *dst_pixel = (float*)FreeImage_GetBits(G);
-
-		for(unsigned y = 0; y < height; y++) {
-			const unsigned n = (y == 0 ? 0 : y-1);
-			const unsigned s = (y+1 == height ? y : y+1);
-			for(unsigned x = 0; x < width; x++) {
-				const unsigned w = (x == 0 ? 0 : x-1);
-				const unsigned e = (x+1 == width ? x : x+1);		
-				// central difference
-				const float gx = (src_pixel[y*pitch+e] - src_pixel[y*pitch+w]) / divider; // [Hk(x+1, y) - Hk(x-1, y)] / 2**(k+1)
-				const float gy = (src_pixel[s*pitch+x] - src_pixel[n*pitch+x]) / divider; // [Hk(x, y+1) - Hk(x, y-1)] / 2**(k+1)
-				// gradient
-				dst_pixel[x] = sqrt(gx*gx + gy*gy);
-				// average gradient
-				average += dst_pixel[x];
-			}
-			// next line
-			dst_pixel += pitch;
-		}
-		
-		*avgGrad = average / (width * height);
-
-		return G;
-
-	} catch(int) {
-		if(G) FreeImage_Unload(G);
-		return NULL;
-	}
-}
-
-/**
-Calculate gradient magnitude and its average value on each pyramid level
- at param pyramid Gaussian pyramid (nlevels levels)
- at param nlevels Number of levels
- at param gradients [out] Gradient pyramid (nlevels levels)
- at param avgGrad [out] Average gradient on each level (array of size nlevels)
- at return Returns TRUE if successful, returns FALSE otherwise
-*/
-static BOOL GradientPyramid(FIBITMAP **pyramid, int nlevels, FIBITMAP **gradients, float *avgGrad) {
-	try {
-		for(int k = 0; k < nlevels; k++) {
-			FIBITMAP *Hk = pyramid[k];
-			gradients[k] = GradientLevel(Hk, &avgGrad[k], k);
-			if(gradients[k] == NULL) throw(1);
-		}
-		return TRUE;
-	} catch(int) {
-		for(int k = 0; k < nlevels; k++) {
-			if(gradients[k] != NULL) {
-				FreeImage_Unload(gradients[k]);
-				gradients[k] = NULL;
-			}
-		}
-		return FALSE;
-	}
-}
-
-/**
-Compute the gradient attenuation function PHI(x, y)
- at param gradients Gradient pyramid (nlevels levels)
- at param avgGrad Average gradient on each level (array of size nlevels)
- at param nlevels Number of levels
- at param alpha Parameter alpha in the paper
- at param beta Parameter beta in the paper
- at return Returns the attenuation matrix Phi if successful, returns NULL otherwise
-*/
-static FIBITMAP* PhiMatrix(FIBITMAP **gradients, float *avgGrad, int nlevels, float alpha, float beta) {
-	float *src_pixel, *dst_pixel;
-	FIBITMAP **phi = NULL;
-
-	try {
-		phi = (FIBITMAP**)malloc(nlevels * sizeof(FIBITMAP*));
-		if(!phi) throw(1);
-		memset(phi, 0, nlevels * sizeof(FIBITMAP*));
-
-		for(int k = nlevels-1; k >= 0; k--) {
-			// compute phi(k)
-
-			FIBITMAP *Gk = gradients[k];
-
-			const unsigned width = FreeImage_GetWidth(Gk);
-			const unsigned height = FreeImage_GetHeight(Gk);
-			const unsigned pitch = FreeImage_GetPitch(Gk) / sizeof(float);
-
-			// parameter alpha is 0.1 times the average gradient magnitude
-			// also, note the factor of 2**k in the denominator; 
-			// that is there to correct for the fact that an average gradient avgGrad(H) over 2**k pixels 
-			// in the original image will appear as a gradient grad(Hk) = 2**k*avgGrad(H) over a single pixel in Hk. 
-			float ALPHA =  alpha * avgGrad[k] * (float)((int)1 << k);
-			if(ALPHA == 0) ALPHA = EPSILON;
-
-			phi[k] = FreeImage_AllocateT(FIT_FLOAT, width, height);
-			if(!phi[k]) throw(1);
-			
-			src_pixel = (float*)FreeImage_GetBits(Gk);
-			dst_pixel = (float*)FreeImage_GetBits(phi[k]);
-			for(unsigned y = 0; y < height; y++) {
-				for(unsigned x = 0; x < width; x++) {
-					// compute (alpha / grad) * (grad / alpha) ** beta
-					const float v = src_pixel[x] / ALPHA;
-					const float value = (float)pow((float)v, (float)(beta-1));
-					dst_pixel[x] = (value > 1) ? 1 : value;
-				}
-				// next line
-				src_pixel += pitch;
-				dst_pixel += pitch;
-			}
-
-			if(k < nlevels-1) {
-				// compute PHI(k) = L( PHI(k+1) ) * phi(k)
-				FIBITMAP *L = FreeImage_Rescale(phi[k+1], width, height, FILTER_BILINEAR);
-				if(!L) throw(1);
-
-				src_pixel = (float*)FreeImage_GetBits(L);
-				dst_pixel = (float*)FreeImage_GetBits(phi[k]);
-				for(unsigned y = 0; y < height; y++) {
-					for(unsigned x = 0; x < width; x++) {
-						dst_pixel[x] *= src_pixel[x];
-					}
-					// next line
-					src_pixel += pitch;
-					dst_pixel += pitch;
-				}
-
-				FreeImage_Unload(L);
-
-				// PHI(k+1) is no longer needed
-				FreeImage_Unload(phi[k+1]);
-				phi[k+1] = NULL;
-			}
-
-			// next level
-		}
-
-		// get the final result and return
-		FIBITMAP *dst = phi[0];
-
-		free(phi);
-
-		return dst;
-
-	} catch(int) {
-		if(phi) {
-			for(int k = nlevels-1; k >= 0; k--) {
-				if(phi[k]) FreeImage_Unload(phi[k]);
-			}
-			free(phi);
-		}
-		return NULL;
-	}
-}
-
-/**
-Compute gradients in x and y directions, attenuate them with the attenuation matrix, 
-then compute the divergence div G from the attenuated gradient. 
- at param H Normalized luminance
- at param PHI Attenuation matrix
- at return Returns the divergence matrix if successful, returns NULL otherwise
-*/
-static FIBITMAP* Divergence(FIBITMAP *H, FIBITMAP *PHI) {
-	FIBITMAP *Gx = NULL, *Gy = NULL, *divG = NULL;
-	float *phi, *h, *gx, *gy, *divg;
-
-	try {
-		const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(H);
-		if(image_type != FIT_FLOAT) throw(1);
-
-		const unsigned width = FreeImage_GetWidth(H);
-		const unsigned height = FreeImage_GetHeight(H);
-
-		Gx = FreeImage_AllocateT(image_type, width, height);
-		if(!Gx) throw(1);
-		Gy = FreeImage_AllocateT(image_type, width, height);
-		if(!Gy) throw(1);
-		
-		const unsigned pitch = FreeImage_GetPitch(H) / sizeof(float);
-		
-		// perform gradient attenuation
-
-		phi = (float*)FreeImage_GetBits(PHI);
-		h   = (float*)FreeImage_GetBits(H);
-		gx  = (float*)FreeImage_GetBits(Gx);
-		gy  = (float*)FreeImage_GetBits(Gy);
-
-		for(unsigned y = 0; y < height; y++) {
-			const unsigned s = (y+1 == height ? y : y+1);
-			for(unsigned x = 0; x < width; x++) {				
-				const unsigned e = (x+1 == width ? x : x+1);
-				// forward difference
-				const unsigned index = y*pitch + x;
-				const float phi_xy = phi[index];
-				const float h_xy   = h[index];
-				gx[x] = (h[y*pitch+e] - h_xy) * phi_xy; // [H(x+1, y) - H(x, y)] * PHI(x, y)
-				gy[x] = (h[s*pitch+x] - h_xy) * phi_xy; // [H(x, y+1) - H(x, y)] * PHI(x, y)
-			}
-			// next line
-			gx += pitch;
-			gy += pitch;
-		}
-
-		// calculate the divergence
-
-		divG = FreeImage_AllocateT(image_type, width, height);
-		if(!divG) throw(1);
-		
-		gx  = (float*)FreeImage_GetBits(Gx);
-		gy  = (float*)FreeImage_GetBits(Gy);
-		divg = (float*)FreeImage_GetBits(divG);
-
-		for(unsigned y = 0; y < height; y++) {
-			for(unsigned x = 0; x < width; x++) {				
-				// backward difference approximation
-				// divG = Gx(x, y) - Gx(x-1, y) + Gy(x, y) - Gy(x, y-1)
-				const unsigned index = y*pitch + x;
-				divg[index] = gx[index] + gy[index];
-				if(x > 0) divg[index] -= gx[index-1];
-				if(y > 0) divg[index] -= gy[index-pitch];
-			}
-		}
-
-		// no longer needed ... 
-		FreeImage_Unload(Gx);
-		FreeImage_Unload(Gy);
-
-		// return the divergence
-		return divG;
-
-	} catch(int) {
-		if(Gx) FreeImage_Unload(Gx);
-		if(Gy) FreeImage_Unload(Gy);
-		if(divG) FreeImage_Unload(divG);
-		return NULL;
-	}
-}
-
-/**
-Given the luminance channel, find max & min luminance values, 
-normalize to range 0..100 and take the logarithm. 
- at param Y Image luminance
- at return Returns the normalized luminance H if successful, returns NULL otherwise
-*/
-static FIBITMAP* LogLuminance(FIBITMAP *Y) {
-	FIBITMAP *H = NULL;
-
-	try {
-		// get the luminance channel
-		FIBITMAP *H = FreeImage_Clone(Y);
-		if(!H) throw(1);
-
-		const unsigned width  = FreeImage_GetWidth(H);
-		const unsigned height = FreeImage_GetHeight(H);
-		const unsigned pitch  = FreeImage_GetPitch(H);
-
-		// find max & min luminance values
-		float maxLum = -1e20F, minLum = 1e20F;
-
-		BYTE *bits = (BYTE*)FreeImage_GetBits(H);
-		for(unsigned y = 0; y < height; y++) {
-			const float *pixel = (float*)bits;
-			for(unsigned x = 0; x < width; x++) {
-				const float value = pixel[x];
-				maxLum = (maxLum < value) ? value : maxLum;	// max Luminance in the scene
-				minLum = (minLum < value) ? minLum : value;	// min Luminance in the scene
-			}
-			// next line
-			bits += pitch;
-		}
-		if(maxLum == minLum) throw(1);
-
-		// normalize to range 0..100 and take the logarithm
-		const float scale = 100.F / (maxLum - minLum);
-		bits = (BYTE*)FreeImage_GetBits(H);
-		for(unsigned y = 0; y < height; y++) {
-			float *pixel = (float*)bits;
-			for(unsigned x = 0; x < width; x++) {
-				const float value = (pixel[x] - minLum) * scale;
-				pixel[x] = log(value + EPSILON);
-			}
-			// next line
-			bits += pitch;
-		}
-
-		return H;
-
-	} catch(int) {
-		if(H) FreeImage_Unload(H);
-		return NULL;
-	}
-}
-
-/**
-Given a normalized luminance, perform exponentiation and recover the log compressed image 
- at param Y Input/Output luminance image
-*/
-static void ExpLuminance(FIBITMAP *Y) {
-	const unsigned width = FreeImage_GetWidth(Y);
-	const unsigned height = FreeImage_GetHeight(Y);
-	const unsigned pitch = FreeImage_GetPitch(Y);
-
-	BYTE *bits = (BYTE*)FreeImage_GetBits(Y);
-	for(unsigned y = 0; y < height; y++) {
-		float *pixel = (float*)bits;
-		for(unsigned x = 0; x < width; x++) {
-			pixel[x] = exp(pixel[x]) - EPSILON;
-		}
-		bits += pitch;
-	}
-}
-
-// --------------------------------------------------------------------------
-
-/**
-Gradient Domain HDR tone mapping operator
- at param Y Image luminance values
- at param alpha Parameter alpha of the paper (suggested value is 0.1)
- at param beta Parameter beta of the paper (suggested value is between 0.8 and 0.9)
- at return returns the tone mapped luminance
-*/
-static FIBITMAP* tmoFattal02(FIBITMAP *Y, float alpha, float beta) {
-	const unsigned MIN_PYRAMID_SIZE = 32;	// minimun size (width or height) of the coarsest level of the pyramid
-
-	FIBITMAP *H = NULL;
-	FIBITMAP **pyramid = NULL;
-	FIBITMAP **gradients = NULL;
-	FIBITMAP *phy = NULL;
-	FIBITMAP *divG = NULL;
-	FIBITMAP *U = NULL;
-	float *avgGrad = NULL;
-
-	int k;
-	int nlevels = 0;
-
-	try {
-		// get the normalized luminance
-		FIBITMAP *H = LogLuminance(Y);
-		if(!H) throw(1);
-		
-		// get the number of levels for the pyramid
-		const unsigned width = FreeImage_GetWidth(H);
-		const unsigned height = FreeImage_GetHeight(H);
-		unsigned minsize = MIN(width, height);
-		while(minsize >= MIN_PYRAMID_SIZE) {
-			nlevels++;
-			minsize /= 2;
-		}
-
-		// create the Gaussian pyramid
-		pyramid = (FIBITMAP**)malloc(nlevels * sizeof(FIBITMAP*));
-		if(!pyramid) throw(1);
-		memset(pyramid, 0, nlevels * sizeof(FIBITMAP*));
-
-		if(!GaussianPyramid(H, pyramid, nlevels)) throw(1);
-
-		// calculate gradient magnitude and its average value on each pyramid level
-		gradients = (FIBITMAP**)malloc(nlevels * sizeof(FIBITMAP*));
-		if(!gradients) throw(1);
-		memset(gradients, 0, nlevels * sizeof(FIBITMAP*));
-		avgGrad = (float*)malloc(nlevels * sizeof(float));
-		if(!avgGrad) throw(1);
-
-		if(!GradientPyramid(pyramid, nlevels, gradients, avgGrad)) throw(1);
-
-		// free the Gaussian pyramid
-		for(k = 0; k < nlevels; k++) {
-			if(pyramid[k]) FreeImage_Unload(pyramid[k]);
-		}
-		free(pyramid); pyramid = NULL;
-
-		// compute the gradient attenuation function PHI(x, y)
-		phy = PhiMatrix(gradients, avgGrad, nlevels, alpha, beta);
-		if(!phy) throw(1);
-
-		// free the gradient pyramid
-		for(k = 0; k < nlevels; k++) {
-			if(gradients[k]) FreeImage_Unload(gradients[k]);
-		}
-		free(gradients); gradients = NULL;
-		free(avgGrad); avgGrad = NULL;
-
-		// compute gradients in x and y directions, attenuate them with the attenuation matrix, 
-		// then compute the divergence div G from the attenuated gradient. 
-		divG = Divergence(H, phy);
-		if(!divG) throw(1);
-
-		// H & phy no longer needed
-		FreeImage_Unload(H); H = NULL;
-		FreeImage_Unload(phy); phy = NULL;
-
-		// solve the PDE (Poisson equation) using a multigrid solver and 3 cycles
-		FIBITMAP *U = FreeImage_MultigridPoissonSolver(divG, 3);
-		if(!U) throw(1);
-
-		FreeImage_Unload(divG);
-
-		// perform exponentiation and recover the log compressed image
-		ExpLuminance(U);
-
-		return U;
-
-	} catch(int) {
-		if(H) FreeImage_Unload(H);
-		if(pyramid) {
-			for(int i = 0; i < nlevels; i++) {
-				if(pyramid[i]) FreeImage_Unload(pyramid[i]);
-			}
-			free(pyramid);
-		}
-		if(gradients) {
-			for(int i = 0; i < nlevels; i++) {
-				if(gradients[i]) FreeImage_Unload(gradients[i]);
-			}
-			free(gradients);
-		}
-		if(avgGrad) free(avgGrad);
-		if(phy) FreeImage_Unload(phy);
-		if(divG) FreeImage_Unload(divG);
-		if(U) FreeImage_Unload(U);
-
-		return NULL;
-	}
-}
-
-// ----------------------------------------------------------
-//  Main algorithm
-// ----------------------------------------------------------
-
-/**
-Apply the Gradient Domain High Dynamic Range Compression to a RGBF image and convert to 24-bit RGB
- at param dib Input RGBF / RGB16 image
- at param color_saturation Color saturation (s parameter in the paper) in [0.4..0.6]
- at param attenuation Atenuation factor (beta parameter in the paper) in [0.8..0.9]
- at return Returns a 24-bit RGB image if successful, returns NULL otherwise
-*/
-FIBITMAP* DLL_CALLCONV 
-FreeImage_TmoFattal02(FIBITMAP *dib, double color_saturation, double attenuation) {	
-	const float alpha = 0.1F;									// parameter alpha = 0.1
-	const float beta = (float)MAX(0.8, MIN(0.9, attenuation));	// parameter beta = [0.8..0.9]
-	const float s = (float)MAX(0.4, MIN(0.6, color_saturation));// exponent s controls color saturation = [0.4..0.6]
-
-	FIBITMAP *src = NULL;
-	FIBITMAP *Yin = NULL;
-	FIBITMAP *Yout = NULL;
-	FIBITMAP *dst = NULL;
-
-	if(!FreeImage_HasPixels(dib)) return NULL;
-
-	try {
-
-		// convert to RGBF
-		src = FreeImage_ConvertToRGBF(dib);
-		if(!src) throw(1);
-
-		// get the luminance channel
-		Yin = ConvertRGBFToY(src);
-		if(!Yin) throw(1);
-
-		// perform the tone mapping
-		Yout = tmoFattal02(Yin, alpha, beta);
-		if(!Yout) throw(1);
-
-		// clip low and high values and normalize to [0..1]
-		//NormalizeY(Yout, 0.001F, 0.995F);
-		NormalizeY(Yout, 0, 1);
-
-		// compress the dynamic range
-
-		const unsigned width = FreeImage_GetWidth(src);
-		const unsigned height = FreeImage_GetHeight(src);
-
-		const unsigned rgb_pitch = FreeImage_GetPitch(src);
-		const unsigned y_pitch = FreeImage_GetPitch(Yin);
-
-		BYTE *bits      = (BYTE*)FreeImage_GetBits(src);
-		BYTE *bits_yin  = (BYTE*)FreeImage_GetBits(Yin);
-		BYTE *bits_yout = (BYTE*)FreeImage_GetBits(Yout);
-
-		for(unsigned y = 0; y < height; y++) {
-			float *Lin = (float*)bits_yin;
-			float *Lout = (float*)bits_yout;
-			float *color = (float*)bits;
-			for(unsigned x = 0; x < width; x++) {
-				for(unsigned c = 0; c < 3; c++) {
-					*color = (Lin[x] > 0) ? pow(*color/Lin[x], s) * Lout[x] : 0;
-					color++;
-				}
-			}
-			bits += rgb_pitch;
-			bits_yin += y_pitch;
-			bits_yout += y_pitch;
-		}
-
-		// not needed anymore
-		FreeImage_Unload(Yin);  Yin  = NULL;
-		FreeImage_Unload(Yout); Yout = NULL;
-
-		// clamp image highest values to display white, then convert to 24-bit RGB
-		dst = ClampConvertRGBFTo24(src);
-
-		// clean-up and return
-		FreeImage_Unload(src); src = NULL;
-
-		// copy metadata from src to dst
-		FreeImage_CloneMetadata(dst, dib);
-		
-		return dst;
-
-	} catch(int) {
-		if(src) FreeImage_Unload(src);
-		if(Yin) FreeImage_Unload(Yin);
-		if(Yout) FreeImage_Unload(Yout);
-		return NULL;
-	}
-}
+// ==========================================================
+// Tone mapping operator (Fattal, 2002)
+//
+// Design and implementation by
+// - Herv� Drolon (drolon at infonie.fr)
+//
+// This file is part of FreeImage 3
+//
+// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
+// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
+// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
+// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
+// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
+// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
+// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+// THIS DISCLAIMER.
+//
+// Use at your own risk!
+// ==========================================================
+
+#include "FreeImage.h"
+#include "Utilities.h"
+#include "ToneMapping.h"
+
+// ----------------------------------------------------------
+// Gradient domain HDR compression
+// Reference:
+// [1] R. Fattal, D. Lischinski, and M.Werman, 
+// Gradient domain high dynamic range compression,
+// ACM Transactions on Graphics, special issue on Proc. of ACM SIGGRAPH 2002, 
+// San Antonio, Texas, vol. 21(3), pp. 257-266, 2002.
+// ----------------------------------------------------------
+
+static const float EPSILON = 1e-4F;
+
+/**
+Performs a 5 by 5 gaussian filtering using two 1D convolutions, 
+followed by a subsampling by 2. 
+ at param dib Input image
+ at return Returns a blurred image of size SIZE(dib)/2
+ at see GaussianPyramid
+*/
+static FIBITMAP* GaussianLevel5x5(FIBITMAP *dib) {
+	FIBITMAP *h_dib = NULL, *v_dib = NULL, *dst = NULL;
+	float *src_pixel, *dst_pixel;
+
+	try {
+		const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
+		if(image_type != FIT_FLOAT) throw(1);
+
+		const unsigned width = FreeImage_GetWidth(dib);
+		const unsigned height = FreeImage_GetHeight(dib);
+
+		h_dib = FreeImage_AllocateT(image_type, width, height);
+		v_dib = FreeImage_AllocateT(image_type, width, height);
+		if(!h_dib || !v_dib) throw(1);
+
+		const unsigned pitch = FreeImage_GetPitch(dib) / sizeof(float);
+
+		// horizontal convolution dib -> h_dib
+
+		src_pixel = (float*)FreeImage_GetBits(dib);
+		dst_pixel = (float*)FreeImage_GetBits(h_dib);
+
+		for(unsigned y = 0; y < height; y++) {
+			// work on line y
+			for(unsigned x = 2; x < width - 2; x++) {
+				dst_pixel[x] = src_pixel[x-2] + src_pixel[x+2] + 4 * (src_pixel[x-1] + src_pixel[x+1]) + 6 * src_pixel[x];
+				dst_pixel[x] /= 16;
+			}
+			// boundary mirroring
+			dst_pixel[0] = (2 * src_pixel[2] + 8 * src_pixel[1] + 6 * src_pixel[0]) / 16;
+			dst_pixel[1] = (src_pixel[3] + 4 * (src_pixel[0] + src_pixel[2]) + 7 * src_pixel[1]) / 16;
+			dst_pixel[width-2] = (src_pixel[width-4] + 5 * src_pixel[width-1] + 4 * src_pixel[width-3] + 6 * src_pixel[width-2]) / 16;
+			dst_pixel[width-1] = (src_pixel[width-3] + 5 * src_pixel[width-2] + 10 * src_pixel[width-1]) / 16;
+
+			// next line
+			src_pixel += pitch;
+			dst_pixel += pitch;
+		}
+
+		// vertical convolution h_dib -> v_dib
+
+		src_pixel = (float*)FreeImage_GetBits(h_dib);
+		dst_pixel = (float*)FreeImage_GetBits(v_dib);
+
+		for(unsigned x = 0; x < width; x++) {		
+			// work on column x
+			for(unsigned y = 2; y < height - 2; y++) {
+				const unsigned index = y*pitch + x;
+				dst_pixel[index] = src_pixel[index-2*pitch] + src_pixel[index+2*pitch] + 4 * (src_pixel[index-pitch] + src_pixel[index+pitch]) + 6 * src_pixel[index];
+				dst_pixel[index] /= 16;
+			}
+			// boundary mirroring
+			dst_pixel[x] = (2 * src_pixel[x+2*pitch] + 8 * src_pixel[x+pitch] + 6 * src_pixel[x]) / 16;
+			dst_pixel[x+pitch] = (src_pixel[x+3*pitch] + 4 * (src_pixel[x] + src_pixel[x+2*pitch]) + 7 * src_pixel[x+pitch]) / 16;
+			dst_pixel[(height-2)*pitch+x] = (src_pixel[(height-4)*pitch+x] + 5 * src_pixel[(height-1)*pitch+x] + 4 * src_pixel[(height-3)*pitch+x] + 6 * src_pixel[(height-2)*pitch+x]) / 16;
+			dst_pixel[(height-1)*pitch+x] = (src_pixel[(height-3)*pitch+x] + 5 * src_pixel[(height-2)*pitch+x] + 10 * src_pixel[(height-1)*pitch+x]) / 16;
+		}
+
+		FreeImage_Unload(h_dib); h_dib = NULL;
+
+		// perform downsampling
+
+		dst = FreeImage_Rescale(v_dib, width/2, height/2, FILTER_BILINEAR);
+
+		FreeImage_Unload(v_dib);
+
+		return dst;
+
+	} catch(int) {
+		if(h_dib) FreeImage_Unload(h_dib);
+		if(v_dib) FreeImage_Unload(v_dib);
+		if(dst) FreeImage_Unload(dst);
+		return NULL;
+	}
+}
+
+/**
+Compute a Gaussian pyramid using the specified number of levels. 
+ at param H Original bitmap
+ at param pyramid Resulting pyramid array 
+ at param nlevels Number of resolution levels
+ at return Returns TRUE if successful, returns FALSE otherwise
+*/
+static BOOL GaussianPyramid(FIBITMAP *H, FIBITMAP **pyramid, int nlevels) {
+	try {
+		// first level is the original image
+		pyramid[0] = FreeImage_Clone(H);
+		if(pyramid[0] == NULL) throw(1);
+		// compute next levels
+		for(int k = 1; k < nlevels; k++) {
+			pyramid[k] = GaussianLevel5x5(pyramid[k-1]);
+			if(pyramid[k] == NULL) throw(1);
+		}
+		return TRUE;
+	} catch(int) {
+		for(int k = 0; k < nlevels; k++) {
+			if(pyramid[k] != NULL) {
+				FreeImage_Unload(pyramid[k]);
+				pyramid[k] = NULL;
+			}
+		}
+		return FALSE;
+	}
+}
+
+/**
+Compute the gradient magnitude of an input image H using central differences, 
+and returns the average gradient. 
+ at param H Input image
+ at param avgGrad [out] Average gradient
+ at param k Level number
+ at return Returns the gradient magnitude if successful, returns NULL otherwise
+ at see GradientPyramid
+*/
+static FIBITMAP* GradientLevel(FIBITMAP *H, float *avgGrad, int k) {
+	FIBITMAP *G = NULL;
+
+	try {
+		const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(H);
+		if(image_type != FIT_FLOAT) throw(1);
+
+		const unsigned width = FreeImage_GetWidth(H);
+		const unsigned height = FreeImage_GetHeight(H);
+
+		G = FreeImage_AllocateT(image_type, width, height);
+		if(!G) throw(1);
+		
+		const unsigned pitch = FreeImage_GetPitch(H) / sizeof(float);
+		
+		const float divider = (float)(1 << (k + 1));
+		float average = 0;
+		
+		float *src_pixel = (float*)FreeImage_GetBits(H);
+		float *dst_pixel = (float*)FreeImage_GetBits(G);
+
+		for(unsigned y = 0; y < height; y++) {
+			const unsigned n = (y == 0 ? 0 : y-1);
+			const unsigned s = (y+1 == height ? y : y+1);
+			for(unsigned x = 0; x < width; x++) {
+				const unsigned w = (x == 0 ? 0 : x-1);
+				const unsigned e = (x+1 == width ? x : x+1);		
+				// central difference
+				const float gx = (src_pixel[y*pitch+e] - src_pixel[y*pitch+w]) / divider; // [Hk(x+1, y) - Hk(x-1, y)] / 2**(k+1)
+				const float gy = (src_pixel[s*pitch+x] - src_pixel[n*pitch+x]) / divider; // [Hk(x, y+1) - Hk(x, y-1)] / 2**(k+1)
+				// gradient
+				dst_pixel[x] = sqrt(gx*gx + gy*gy);
+				// average gradient
+				average += dst_pixel[x];
+			}
+			// next line
+			dst_pixel += pitch;
+		}
+		
+		*avgGrad = average / (width * height);
+
+		return G;
+
+	} catch(int) {
+		if(G) FreeImage_Unload(G);
+		return NULL;
+	}
+}
+
+/**
+Calculate gradient magnitude and its average value on each pyramid level
+ at param pyramid Gaussian pyramid (nlevels levels)
+ at param nlevels Number of levels
+ at param gradients [out] Gradient pyramid (nlevels levels)
+ at param avgGrad [out] Average gradient on each level (array of size nlevels)
+ at return Returns TRUE if successful, returns FALSE otherwise
+*/
+static BOOL GradientPyramid(FIBITMAP **pyramid, int nlevels, FIBITMAP **gradients, float *avgGrad) {
+	try {
+		for(int k = 0; k < nlevels; k++) {
+			FIBITMAP *Hk = pyramid[k];
+			gradients[k] = GradientLevel(Hk, &avgGrad[k], k);
+			if(gradients[k] == NULL) throw(1);
+		}
+		return TRUE;
+	} catch(int) {
+		for(int k = 0; k < nlevels; k++) {
+			if(gradients[k] != NULL) {
+				FreeImage_Unload(gradients[k]);
+				gradients[k] = NULL;
+			}
+		}
+		return FALSE;
+	}
+}
+
+/**
+Compute the gradient attenuation function PHI(x, y)
+ at param gradients Gradient pyramid (nlevels levels)
+ at param avgGrad Average gradient on each level (array of size nlevels)
+ at param nlevels Number of levels
+ at param alpha Parameter alpha in the paper
+ at param beta Parameter beta in the paper
+ at return Returns the attenuation matrix Phi if successful, returns NULL otherwise
+*/
+static FIBITMAP* PhiMatrix(FIBITMAP **gradients, float *avgGrad, int nlevels, float alpha, float beta) {
+	float *src_pixel, *dst_pixel;
+	FIBITMAP **phi = NULL;
+
+	try {
+		phi = (FIBITMAP**)malloc(nlevels * sizeof(FIBITMAP*));
+		if(!phi) throw(1);
+		memset(phi, 0, nlevels * sizeof(FIBITMAP*));
+
+		for(int k = nlevels-1; k >= 0; k--) {
+			// compute phi(k)
+
+			FIBITMAP *Gk = gradients[k];
+
+			const unsigned width = FreeImage_GetWidth(Gk);
+			const unsigned height = FreeImage_GetHeight(Gk);
+			const unsigned pitch = FreeImage_GetPitch(Gk) / sizeof(float);
+
+			// parameter alpha is 0.1 times the average gradient magnitude
+			// also, note the factor of 2**k in the denominator; 
+			// that is there to correct for the fact that an average gradient avgGrad(H) over 2**k pixels 
+			// in the original image will appear as a gradient grad(Hk) = 2**k*avgGrad(H) over a single pixel in Hk. 
+			float ALPHA =  alpha * avgGrad[k] * (float)((int)1 << k);
+			if(ALPHA == 0) ALPHA = EPSILON;
+
+			phi[k] = FreeImage_AllocateT(FIT_FLOAT, width, height);
+			if(!phi[k]) throw(1);
+			
+			src_pixel = (float*)FreeImage_GetBits(Gk);
+			dst_pixel = (float*)FreeImage_GetBits(phi[k]);
+			for(unsigned y = 0; y < height; y++) {
+				for(unsigned x = 0; x < width; x++) {
+					// compute (alpha / grad) * (grad / alpha) ** beta
+					const float v = src_pixel[x] / ALPHA;
+					const float value = (float)pow((float)v, (float)(beta-1));
+					dst_pixel[x] = (value > 1) ? 1 : value;
+				}
+				// next line
+				src_pixel += pitch;
+				dst_pixel += pitch;
+			}
+
+			if(k < nlevels-1) {
+				// compute PHI(k) = L( PHI(k+1) ) * phi(k)
+				FIBITMAP *L = FreeImage_Rescale(phi[k+1], width, height, FILTER_BILINEAR);
+				if(!L) throw(1);
+
+				src_pixel = (float*)FreeImage_GetBits(L);
+				dst_pixel = (float*)FreeImage_GetBits(phi[k]);
+				for(unsigned y = 0; y < height; y++) {
+					for(unsigned x = 0; x < width; x++) {
+						dst_pixel[x] *= src_pixel[x];
+					}
+					// next line
+					src_pixel += pitch;
+					dst_pixel += pitch;
+				}
+
+				FreeImage_Unload(L);
+
+				// PHI(k+1) is no longer needed
+				FreeImage_Unload(phi[k+1]);
+				phi[k+1] = NULL;
+			}
+
+			// next level
+		}
+
+		// get the final result and return
+		FIBITMAP *dst = phi[0];
+
+		free(phi);
+
+		return dst;
+
+	} catch(int) {
+		if(phi) {
+			for(int k = nlevels-1; k >= 0; k--) {
+				if(phi[k]) FreeImage_Unload(phi[k]);
+			}
+			free(phi);
+		}
+		return NULL;
+	}
+}
+
+/**
+Compute gradients in x and y directions, attenuate them with the attenuation matrix, 
+then compute the divergence div G from the attenuated gradient. 
+ at param H Normalized luminance
+ at param PHI Attenuation matrix
+ at return Returns the divergence matrix if successful, returns NULL otherwise
+*/
+static FIBITMAP* Divergence(FIBITMAP *H, FIBITMAP *PHI) {
+	FIBITMAP *Gx = NULL, *Gy = NULL, *divG = NULL;
+	float *phi, *h, *gx, *gy, *divg;
+
+	try {
+		const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(H);
+		if(image_type != FIT_FLOAT) throw(1);
+
+		const unsigned width = FreeImage_GetWidth(H);
+		const unsigned height = FreeImage_GetHeight(H);
+
+		Gx = FreeImage_AllocateT(image_type, width, height);
+		if(!Gx) throw(1);
+		Gy = FreeImage_AllocateT(image_type, width, height);
+		if(!Gy) throw(1);
+		
+		const unsigned pitch = FreeImage_GetPitch(H) / sizeof(float);
+		
+		// perform gradient attenuation
+
+		phi = (float*)FreeImage_GetBits(PHI);
+		h   = (float*)FreeImage_GetBits(H);
+		gx  = (float*)FreeImage_GetBits(Gx);
+		gy  = (float*)FreeImage_GetBits(Gy);
+
+		for(unsigned y = 0; y < height; y++) {
+			const unsigned s = (y+1 == height ? y : y+1);
+			for(unsigned x = 0; x < width; x++) {				
+				const unsigned e = (x+1 == width ? x : x+1);
+				// forward difference
+				const unsigned index = y*pitch + x;
+				const float phi_xy = phi[index];
+				const float h_xy   = h[index];
+				gx[x] = (h[y*pitch+e] - h_xy) * phi_xy; // [H(x+1, y) - H(x, y)] * PHI(x, y)
+				gy[x] = (h[s*pitch+x] - h_xy) * phi_xy; // [H(x, y+1) - H(x, y)] * PHI(x, y)
+			}
+			// next line
+			gx += pitch;
+			gy += pitch;
+		}
+
+		// calculate the divergence
+
+		divG = FreeImage_AllocateT(image_type, width, height);
+		if(!divG) throw(1);
+		
+		gx  = (float*)FreeImage_GetBits(Gx);
+		gy  = (float*)FreeImage_GetBits(Gy);
+		divg = (float*)FreeImage_GetBits(divG);
+
+		for(unsigned y = 0; y < height; y++) {
+			for(unsigned x = 0; x < width; x++) {				
+				// backward difference approximation
+				// divG = Gx(x, y) - Gx(x-1, y) + Gy(x, y) - Gy(x, y-1)
+				const unsigned index = y*pitch + x;
+				divg[index] = gx[index] + gy[index];
+				if(x > 0) divg[index] -= gx[index-1];
+				if(y > 0) divg[index] -= gy[index-pitch];
+			}
+		}
+
+		// no longer needed ... 
+		FreeImage_Unload(Gx);
+		FreeImage_Unload(Gy);
+
+		// return the divergence
+		return divG;
+
+	} catch(int) {
+		if(Gx) FreeImage_Unload(Gx);
+		if(Gy) FreeImage_Unload(Gy);
+		if(divG) FreeImage_Unload(divG);
+		return NULL;
+	}
+}
+
+/**
+Given the luminance channel, find max & min luminance values, 
+normalize to range 0..100 and take the logarithm. 
+ at param Y Image luminance
+ at return Returns the normalized luminance H if successful, returns NULL otherwise
+*/
+static FIBITMAP* LogLuminance(FIBITMAP *Y) {
+	FIBITMAP *H = NULL;
+
+	try {
+		// get the luminance channel
+		FIBITMAP *H = FreeImage_Clone(Y);
+		if(!H) throw(1);
+
+		const unsigned width  = FreeImage_GetWidth(H);
+		const unsigned height = FreeImage_GetHeight(H);
+		const unsigned pitch  = FreeImage_GetPitch(H);
+
+		// find max & min luminance values
+		float maxLum = -1e20F, minLum = 1e20F;
+
+		BYTE *bits = (BYTE*)FreeImage_GetBits(H);
+		for(unsigned y = 0; y < height; y++) {
+			const float *pixel = (float*)bits;
+			for(unsigned x = 0; x < width; x++) {
+				const float value = pixel[x];
+				maxLum = (maxLum < value) ? value : maxLum;	// max Luminance in the scene
+				minLum = (minLum < value) ? minLum : value;	// min Luminance in the scene
+			}
+			// next line
+			bits += pitch;
+		}
+		if(maxLum == minLum) throw(1);
+
+		// normalize to range 0..100 and take the logarithm
+		const float scale = 100.F / (maxLum - minLum);
+		bits = (BYTE*)FreeImage_GetBits(H);
+		for(unsigned y = 0; y < height; y++) {
+			float *pixel = (float*)bits;
+			for(unsigned x = 0; x < width; x++) {
+				const float value = (pixel[x] - minLum) * scale;
+				pixel[x] = log(value + EPSILON);
+			}
+			// next line
+			bits += pitch;
+		}
+
+		return H;
+
+	} catch(int) {
+		if(H) FreeImage_Unload(H);
+		return NULL;
+	}
+}
+
+/**
+Given a normalized luminance, perform exponentiation and recover the log compressed image 
+ at param Y Input/Output luminance image
+*/
+static void ExpLuminance(FIBITMAP *Y) {
+	const unsigned width = FreeImage_GetWidth(Y);
+	const unsigned height = FreeImage_GetHeight(Y);
+	const unsigned pitch = FreeImage_GetPitch(Y);
+
+	BYTE *bits = (BYTE*)FreeImage_GetBits(Y);
+	for(unsigned y = 0; y < height; y++) {
+		float *pixel = (float*)bits;
+		for(unsigned x = 0; x < width; x++) {
+			pixel[x] = exp(pixel[x]) - EPSILON;
+		}
+		bits += pitch;
+	}
+}
+
+// --------------------------------------------------------------------------
+
+/**
+Gradient Domain HDR tone mapping operator
+ at param Y Image luminance values
+ at param alpha Parameter alpha of the paper (suggested value is 0.1)
+ at param beta Parameter beta of the paper (suggested value is between 0.8 and 0.9)
+ at return returns the tone mapped luminance
+*/
+static FIBITMAP* tmoFattal02(FIBITMAP *Y, float alpha, float beta) {
+	const unsigned MIN_PYRAMID_SIZE = 32;	// minimun size (width or height) of the coarsest level of the pyramid
+
+	FIBITMAP *H = NULL;
+	FIBITMAP **pyramid = NULL;
+	FIBITMAP **gradients = NULL;
+	FIBITMAP *phy = NULL;
+	FIBITMAP *divG = NULL;
+	FIBITMAP *U = NULL;
+	float *avgGrad = NULL;
+
+	int k;
+	int nlevels = 0;
+
+	try {
+		// get the normalized luminance
+		FIBITMAP *H = LogLuminance(Y);
+		if(!H) throw(1);
+		
+		// get the number of levels for the pyramid
+		const unsigned width = FreeImage_GetWidth(H);
+		const unsigned height = FreeImage_GetHeight(H);
+		unsigned minsize = MIN(width, height);
+		while(minsize >= MIN_PYRAMID_SIZE) {
+			nlevels++;
+			minsize /= 2;
+		}
+
+		// create the Gaussian pyramid
+		pyramid = (FIBITMAP**)malloc(nlevels * sizeof(FIBITMAP*));
+		if(!pyramid) throw(1);
+		memset(pyramid, 0, nlevels * sizeof(FIBITMAP*));
+
+		if(!GaussianPyramid(H, pyramid, nlevels)) throw(1);
+
+		// calculate gradient magnitude and its average value on each pyramid level
+		gradients = (FIBITMAP**)malloc(nlevels * sizeof(FIBITMAP*));
+		if(!gradients) throw(1);
+		memset(gradients, 0, nlevels * sizeof(FIBITMAP*));
+		avgGrad = (float*)malloc(nlevels * sizeof(float));
+		if(!avgGrad) throw(1);
+
+		if(!GradientPyramid(pyramid, nlevels, gradients, avgGrad)) throw(1);
+
+		// free the Gaussian pyramid
+		for(k = 0; k < nlevels; k++) {
+			if(pyramid[k]) FreeImage_Unload(pyramid[k]);
+		}
+		free(pyramid); pyramid = NULL;
+
+		// compute the gradient attenuation function PHI(x, y)
+		phy = PhiMatrix(gradients, avgGrad, nlevels, alpha, beta);
+		if(!phy) throw(1);
+
+		// free the gradient pyramid
+		for(k = 0; k < nlevels; k++) {
+			if(gradients[k]) FreeImage_Unload(gradients[k]);
+		}
+		free(gradients); gradients = NULL;
+		free(avgGrad); avgGrad = NULL;
+
+		// compute gradients in x and y directions, attenuate them with the attenuation matrix, 
+		// then compute the divergence div G from the attenuated gradient. 
+		divG = Divergence(H, phy);
+		if(!divG) throw(1);
+
+		// H & phy no longer needed
+		FreeImage_Unload(H); H = NULL;
+		FreeImage_Unload(phy); phy = NULL;
+
+		// solve the PDE (Poisson equation) using a multigrid solver and 3 cycles
+		FIBITMAP *U = FreeImage_MultigridPoissonSolver(divG, 3);
+		if(!U) throw(1);
+
+		FreeImage_Unload(divG);
+
+		// perform exponentiation and recover the log compressed image
+		ExpLuminance(U);
+
+		return U;
+
+	} catch(int) {
+		if(H) FreeImage_Unload(H);
+		if(pyramid) {
+			for(int i = 0; i < nlevels; i++) {
+				if(pyramid[i]) FreeImage_Unload(pyramid[i]);
+			}
+			free(pyramid);
+		}
+		if(gradients) {
+			for(int i = 0; i < nlevels; i++) {
+				if(gradients[i]) FreeImage_Unload(gradients[i]);
+			}
+			free(gradients);
+		}
+		if(avgGrad) free(avgGrad);
+		if(phy) FreeImage_Unload(phy);
+		if(divG) FreeImage_Unload(divG);
+		if(U) FreeImage_Unload(U);
+
+		return NULL;
+	}
+}
+
+// ----------------------------------------------------------
+//  Main algorithm
+// ----------------------------------------------------------
+
+/**
+Apply the Gradient Domain High Dynamic Range Compression to a RGBF image and convert to 24-bit RGB
+ at param dib Input RGBF / RGB16 image
+ at param color_saturation Color saturation (s parameter in the paper) in [0.4..0.6]
+ at param attenuation Atenuation factor (beta parameter in the paper) in [0.8..0.9]
+ at return Returns a 24-bit RGB image if successful, returns NULL otherwise
+*/
+FIBITMAP* DLL_CALLCONV 
+FreeImage_TmoFattal02(FIBITMAP *dib, double color_saturation, double attenuation) {	
+	const float alpha = 0.1F;									// parameter alpha = 0.1
+	const float beta = (float)MAX(0.8, MIN(0.9, attenuation));	// parameter beta = [0.8..0.9]
+	const float s = (float)MAX(0.4, MIN(0.6, color_saturation));// exponent s controls color saturation = [0.4..0.6]
+
+	FIBITMAP *src = NULL;
+	FIBITMAP *Yin = NULL;
+	FIBITMAP *Yout = NULL;
+	FIBITMAP *dst = NULL;
+
+	if(!FreeImage_HasPixels(dib)) return NULL;
+
+	try {
+
+		// convert to RGBF
+		src = FreeImage_ConvertToRGBF(dib);
+		if(!src) throw(1);
+
+		// get the luminance channel
+		Yin = ConvertRGBFToY(src);
+		if(!Yin) throw(1);
+
+		// perform the tone mapping
+		Yout = tmoFattal02(Yin, alpha, beta);
+		if(!Yout) throw(1);
+
+		// clip low and high values and normalize to [0..1]
+		//NormalizeY(Yout, 0.001F, 0.995F);
+		NormalizeY(Yout, 0, 1);
+
+		// compress the dynamic range
+
+		const unsigned width = FreeImage_GetWidth(src);
+		const unsigned height = FreeImage_GetHeight(src);
+
+		const unsigned rgb_pitch = FreeImage_GetPitch(src);
+		const unsigned y_pitch = FreeImage_GetPitch(Yin);
+
+		BYTE *bits      = (BYTE*)FreeImage_GetBits(src);
+		BYTE *bits_yin  = (BYTE*)FreeImage_GetBits(Yin);
+		BYTE *bits_yout = (BYTE*)FreeImage_GetBits(Yout);
+
+		for(unsigned y = 0; y < height; y++) {
+			float *Lin = (float*)bits_yin;
+			float *Lout = (float*)bits_yout;
+			float *color = (float*)bits;
+			for(unsigned x = 0; x < width; x++) {
+				for(unsigned c = 0; c < 3; c++) {
+					*color = (Lin[x] > 0) ? pow(*color/Lin[x], s) * Lout[x] : 0;
+					color++;
+				}
+			}
+			bits += rgb_pitch;
+			bits_yin += y_pitch;
+			bits_yout += y_pitch;
+		}
+
+		// not needed anymore
+		FreeImage_Unload(Yin);  Yin  = NULL;
+		FreeImage_Unload(Yout); Yout = NULL;
+
+		// clamp image highest values to display white, then convert to 24-bit RGB
+		dst = ClampConvertRGBFTo24(src);
+
+		// clean-up and return
+		FreeImage_Unload(src); src = NULL;
+
+		// copy metadata from src to dst
+		FreeImage_CloneMetadata(dst, dib);
+		
+		return dst;
+
+	} catch(int) {
+		if(src) FreeImage_Unload(src);
+		if(Yin) FreeImage_Unload(Yin);
+		if(Yout) FreeImage_Unload(Yout);
+		return NULL;
+	}
+}
diff --git a/Source/FreeImageIO.h b/Source/FreeImageIO.h
index b251d47..c846b5b 100644
--- a/Source/FreeImageIO.h
+++ b/Source/FreeImageIO.h
@@ -29,16 +29,31 @@
 // ----------------------------------------------------------
 
 FI_STRUCT (FIMEMORYHEADER) {
-	/// remember to delete the buffer
+	/**
+	Flag used to remember to delete the 'data' buffer.
+	When the buffer is a wrapped buffer, it is read-only, no need to delete it. 
+	When the buffer is a read/write buffer, it is allocated dynamically and must be deleted when no longer needed.
+	*/
 	BOOL delete_me;
-	/// file length
-	long filelen;
-	/// buffer size
-	long datalen;
-	/// current position
-	long curpos;
-	/// start buffer address
+	/**
+	file_length is equal to the input buffer size when the buffer is a wrapped buffer, i.e. file_length == data_length. 
+	file_length is the amount of the written bytes when the buffer is a read/write buffer.
+	*/
+	long file_length;
+	/**
+	When using read-only input buffers, data_length is equal to the input buffer size, i.e. the file_length.
+	When using read/write buffers, data_length is the size of the allocated buffer, 
+	whose size is greater than or equal to file_length.
+	*/
+	long data_length;
+	/**
+	start buffer address
+	*/
 	void *data;
+	/**
+	Current position into the memory stream
+	*/
+	long current_position;
 };
 
 void SetDefaultIO(FreeImageIO *io);
diff --git a/Source/FreeImageLib/FreeImageLib.2003.vcproj b/Source/FreeImageLib/FreeImageLib.2003.vcproj
deleted file mode 100644
index a3c0a5d..0000000
--- a/Source/FreeImageLib/FreeImageLib.2003.vcproj
+++ /dev/null
@@ -1,473 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="7.10"
-	Name="FreeImageLib"
-	SccProjectName=""
-	SccLocalPath="">
-	<Platforms>
-		<Platform
-			Name="Win32"/>
-	</Platforms>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			OutputDirectory=".\Debug"
-			IntermediateDirectory=".\Debug"
-			ConfigurationType="4"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="FALSE"
-			CharacterSet="2">
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="0"
-				AdditionalIncludeDirectories="..\;..\ZLib;..\DeprecationManager;..\OpenEXR\Half;..\OpenEXR\Iex;..\OpenEXR\IlmImf;..\OpenEXR\Imath;..\OpenEXR\IlmThread"
-				PreprocessorDefinitions="WIN32;_DEBUG;OPJ_STATIC;FREEIMAGE_LIB;_SECURE_NO_DEPRECATE;LIBRAW_NODLL"
-				StringPooling="TRUE"
-				BasicRuntimeChecks="3"
-				RuntimeLibrary="1"
-				TreatWChar_tAsBuiltInType="TRUE"
-				UsePrecompiledHeader="0"
-				PrecompiledHeaderFile=""
-				AssemblerListingLocation=".\Debug/"
-				ObjectFile=".\Debug/"
-				ProgramDataBaseFileName=".\Debug/"
-				WarningLevel="3"
-				SuppressStartupBanner="TRUE"
-				DebugInformationFormat="4"
-				CompileAs="2"/>
-			<Tool
-				Name="VCCustomBuildTool"/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile="Debug\FreeImaged.lib"
-				SuppressStartupBanner="TRUE"/>
-			<Tool
-				Name="VCMIDLTool"/>
-			<Tool
-				Name="VCPostBuildEventTool"
-				CommandLine="copy Debug\FreeImaged.lib ..\..\Dist
-copy ..\FreeImage.h ..\..\Dist
-"/>
-			<Tool
-				Name="VCPreBuildEventTool"/>
-			<Tool
-				Name="VCPreLinkEventTool"/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="_DEBUG"
-				Culture="1043"/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"/>
-			<Tool
-				Name="VCManagedWrapperGeneratorTool"/>
-			<Tool
-				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			OutputDirectory=".\Release"
-			IntermediateDirectory=".\Release"
-			ConfigurationType="4"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="FALSE"
-			CharacterSet="2">
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="2"
-				GlobalOptimizations="TRUE"
-				InlineFunctionExpansion="2"
-				EnableIntrinsicFunctions="TRUE"
-				FavorSizeOrSpeed="1"
-				OmitFramePointers="TRUE"
-				OptimizeForProcessor="3"
-				AdditionalIncludeDirectories="..\;..\ZLib;..\DeprecationManager;..\OpenEXR\Half;..\OpenEXR\Iex;..\OpenEXR\IlmImf;..\OpenEXR\Imath;..\OpenEXR\IlmThread"
-				PreprocessorDefinitions="WIN32;NDEBUG;OPJ_STATIC;FREEIMAGE_LIB;_SECURE_NO_DEPRECATE;LIBRAW_NODLL"
-				StringPooling="TRUE"
-				RuntimeLibrary="0"
-				BufferSecurityCheck="FALSE"
-				TreatWChar_tAsBuiltInType="TRUE"
-				UsePrecompiledHeader="2"
-				PrecompiledHeaderFile=".\Release/FreeImageLib.pch"
-				AssemblerListingLocation=".\Release/"
-				ObjectFile=".\Release/"
-				ProgramDataBaseFileName=".\Release/"
-				WarningLevel="3"
-				SuppressStartupBanner="TRUE"
-				CompileAs="2"/>
-			<Tool
-				Name="VCCustomBuildTool"/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile="Release\FreeImage.lib"
-				SuppressStartupBanner="TRUE"/>
-			<Tool
-				Name="VCMIDLTool"/>
-			<Tool
-				Name="VCPostBuildEventTool"
-				CommandLine="copy Release\FreeImage.lib ..\..\Dist
-copy ..\FreeImage.h ..\..\Dist
-"/>
-			<Tool
-				Name="VCPreBuildEventTool"/>
-			<Tool
-				Name="VCPreLinkEventTool"/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="1033"/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"/>
-			<Tool
-				Name="VCManagedWrapperGeneratorTool"/>
-			<Tool
-				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Source Files"
-			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
-			<File
-				RelativePath="..\FreeImage\BitmapAccess.cpp">
-			</File>
-			<File
-				RelativePath="..\FreeImage\ColorLookup.cpp">
-			</File>
-			<File
-				RelativePath="..\FreeImage\FreeImage.cpp">
-			</File>
-			<File
-				RelativePath="..\FreeImage\FreeImageIO.cpp">
-			</File>
-			<File
-				RelativePath="..\FreeImage\GetType.cpp">
-			</File>
-			<File
-				RelativePath="..\FreeImage\MemoryIO.cpp">
-			</File>
-			<File
-				RelativePath="..\FreeImage\PixelAccess.cpp">
-			</File>
-			<Filter
-				Name="Quantizers"
-				Filter="">
-				<File
-					RelativePath="..\FreeImage\NNQuantizer.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\WuQuantizer.cpp">
-				</File>
-			</Filter>
-			<Filter
-				Name="Conversion"
-				Filter="">
-				<File
-					RelativePath="..\FreeImage\Conversion.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\Conversion16_555.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\Conversion16_565.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\Conversion24.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\Conversion32.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\Conversion4.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\Conversion8.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\ConversionFloat.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\ConversionRGB16.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\ConversionRGBF.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\ConversionType.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\ConversionUINT16.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\Halftoning.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\tmoColorConvert.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\tmoDrago03.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\tmoFattal02.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\tmoReinhard05.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\ToneMapping.cpp">
-				</File>
-			</Filter>
-			<Filter
-				Name="Plugins"
-				Filter="">
-				<File
-					RelativePath="..\FreeImage\J2KHelper.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\MNGHelper.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\Plugin.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\PluginBMP.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\PluginCUT.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\PluginDDS.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\PluginEXR.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\PluginG3.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\PluginGIF.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\PluginHDR.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\PluginICO.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\PluginIFF.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\PluginJ2K.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\PluginJNG.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\PluginJP2.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\PluginJPEG.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\PluginKOALA.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\PluginMNG.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\PluginPCD.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\PluginPCX.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\PluginPFM.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\PluginPICT.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\PluginPNG.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\PluginPNM.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\PluginPSD.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\PluginRAS.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\PluginRAW.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\PluginSGI.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\PluginTARGA.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\PluginTIFF.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\PluginWBMP.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\PluginXBM.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\PluginXPM.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\PSDParser.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\TIFFLogLuv.cpp">
-				</File>
-			</Filter>
-			<Filter
-				Name="DeprecationMgr"
-				Filter="">
-				<File
-					RelativePath="..\DeprecationManager\Deprecated.cpp">
-				</File>
-				<File
-					RelativePath="..\DeprecationManager\DeprecationMgr.cpp">
-				</File>
-			</Filter>
-			<Filter
-				Name="MultiPaging"
-				Filter="">
-				<File
-					RelativePath="..\FreeImage\CacheFile.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\MultiPage.cpp">
-				</File>
-				<File
-					RelativePath="..\FreeImage\ZLibInterface.cpp">
-				</File>
-			</Filter>
-			<Filter
-				Name="Metadata"
-				Filter="">
-				<File
-					RelativePath="..\Metadata\Exif.cpp">
-				</File>
-				<File
-					RelativePath="..\Metadata\FIRational.cpp">
-				</File>
-				<File
-					RelativePath="..\Metadata\FreeImageTag.cpp">
-				</File>
-				<File
-					RelativePath="..\Metadata\IPTC.cpp">
-				</File>
-				<File
-					RelativePath="..\Metadata\TagConversion.cpp">
-				</File>
-				<File
-					RelativePath="..\Metadata\TagLib.cpp">
-				</File>
-				<File
-					RelativePath="..\Metadata\XTIFF.cpp">
-				</File>
-			</Filter>
-		</Filter>
-		<Filter
-			Name="Header Files"
-			Filter="h;hpp;hxx;hm;inl">
-			<File
-				RelativePath="..\CacheFile.h">
-			</File>
-			<File
-				RelativePath="..\DeprecationManager\DeprecationMgr.h">
-			</File>
-			<File
-				RelativePath="..\Metadata\FIRational.h">
-			</File>
-			<File
-				RelativePath="..\FreeImage.h">
-			</File>
-			<File
-				RelativePath="..\FreeImageIO.h">
-			</File>
-			<File
-				RelativePath="..\Metadata\FreeImageTag.h">
-			</File>
-			<File
-				RelativePath="..\Plugin.h">
-			</File>
-			<File
-				RelativePath="..\PoissonSolver.h">
-			</File>
-			<File
-				RelativePath="..\FreeImage\PSDParser.h">
-			</File>
-			<File
-				RelativePath="..\Quantizers.h">
-			</File>
-			<File
-				RelativePath="..\ToneMapping.h">
-			</File>
-			<File
-				RelativePath="..\Utilities.h">
-			</File>
-		</Filter>
-		<Filter
-			Name="Toolkit Files"
-			Filter="">
-			<File
-				RelativePath="..\FreeImageToolkit\Background.cpp">
-			</File>
-			<File
-				RelativePath="..\FreeImageToolkit\BSplineRotate.cpp">
-			</File>
-			<File
-				RelativePath="..\FreeImageToolkit\Channels.cpp">
-			</File>
-			<File
-				RelativePath="..\FreeImageToolkit\ClassicRotate.cpp">
-			</File>
-			<File
-				RelativePath="..\FreeImageToolkit\Colors.cpp">
-			</File>
-			<File
-				RelativePath="..\FreeImageToolkit\CopyPaste.cpp">
-			</File>
-			<File
-				RelativePath="..\FreeImageToolkit\Display.cpp">
-			</File>
-			<File
-				RelativePath="..\FreeImageToolkit\Flip.cpp">
-			</File>
-			<File
-				RelativePath="..\FreeImageToolkit\JPEGTransform.cpp">
-			</File>
-			<File
-				RelativePath="..\FreeImageToolkit\MultigridPoissonSolver.cpp">
-			</File>
-			<File
-				RelativePath="..\FreeImageToolkit\Rescale.cpp">
-			</File>
-			<File
-				RelativePath="..\FreeImageToolkit\Resize.cpp">
-			</File>
-			<File
-				RelativePath="..\FreeImageToolkit\Resize.h">
-			</File>
-		</Filter>
-		<File
-			RelativePath="..\..\Whatsnew.txt">
-		</File>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
diff --git a/Source/FreeImageLib/FreeImageLib.2005.vcproj b/Source/FreeImageLib/FreeImageLib.2005.vcproj
index 5b6390f..affbff7 100644
--- a/Source/FreeImageLib/FreeImageLib.2005.vcproj
+++ b/Source/FreeImageLib/FreeImageLib.2005.vcproj
@@ -45,7 +45,7 @@
 			<Tool
 				Name="VCCLCompilerTool"
 				Optimization="0"
-				AdditionalIncludeDirectories="..\;..\ZLib;..\DeprecationManager;..\OpenEXR\Half;..\OpenEXR\Iex;..\OpenEXR\IlmImf;..\OpenEXR\Imath;..\OpenEXR\IlmThread"
+				AdditionalIncludeDirectories="..\;..\ZLib;..\DeprecationManager;..\OpenEXR\Half;..\OpenEXR\Iex;..\OpenEXR\IlmImf;..\OpenEXR\Imath;..\OpenEXR\IlmThread;..\LibJXR\image\sys;..\LibJXR\jxrgluelib"
 				PreprocessorDefinitions="WIN32;_DEBUG;OPJ_STATIC;FREEIMAGE_LIB;_CRT_SECURE_NO_DEPRECATE;LIBRAW_NODLL"
 				StringPooling="true"
 				BasicRuntimeChecks="3"
@@ -126,7 +126,7 @@
 				EnableIntrinsicFunctions="true"
 				FavorSizeOrSpeed="1"
 				OmitFramePointers="true"
-				AdditionalIncludeDirectories="..\;..\ZLib;..\DeprecationManager;..\OpenEXR\Half;..\OpenEXR\Iex;..\OpenEXR\IlmImf;..\OpenEXR\Imath;..\OpenEXR\IlmThread"
+				AdditionalIncludeDirectories="..\;..\ZLib;..\DeprecationManager;..\OpenEXR\Half;..\OpenEXR\Iex;..\OpenEXR\IlmImf;..\OpenEXR\Imath;..\OpenEXR\IlmThread;..\LibJXR\image\sys;..\LibJXR\jxrgluelib"
 				PreprocessorDefinitions="WIN32;NDEBUG;OPJ_STATIC;FREEIMAGE_LIB;_CRT_SECURE_NO_DEPRECATE;LIBRAW_NODLL"
 				StringPooling="true"
 				RuntimeLibrary="0"
@@ -373,6 +373,10 @@
 				Name="Quantizers"
 				>
 				<File
+					RelativePath="..\FreeImage\LFPQuantizer.cpp"
+					>
+				</File>
+				<File
 					RelativePath="..\FreeImage\NNQuantizer.cpp"
 					>
 				</File>
@@ -421,6 +425,14 @@
 					>
 				</File>
 				<File
+					RelativePath="..\FreeImage\ConversionRGBA16.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\FreeImage\ConversionRGBAF.cpp"
+					>
+				</File>
+				<File
 					RelativePath="..\FreeImage\ConversionRGBF.cpp"
 					>
 				</File>
@@ -525,6 +537,10 @@
 					>
 				</File>
 				<File
+					RelativePath="..\FreeImage\PluginJXR.cpp"
+					>
+				</File>
+				<File
 					RelativePath="..\FreeImage\PluginKOALA.cpp"
 					>
 				</File>
@@ -585,6 +601,10 @@
 					>
 				</File>
 				<File
+					RelativePath="..\FreeImage\PluginWebP.cpp"
+					>
+				</File>
+				<File
 					RelativePath="..\FreeImage\PluginXBM.cpp"
 					>
 				</File>
@@ -691,6 +711,14 @@
 				>
 			</File>
 			<File
+				RelativePath="..\FreeImage\J2KHelper.h"
+				>
+			</File>
+			<File
+				RelativePath="..\MapIntrospector.h"
+				>
+			</File>
+			<File
 				RelativePath="..\Plugin.h"
 				>
 			</File>
diff --git a/Source/FreeImageLib/FreeImageLib.2008.vcproj b/Source/FreeImageLib/FreeImageLib.2008.vcproj
index 13b8a4b..ee66000 100644
--- a/Source/FreeImageLib/FreeImageLib.2008.vcproj
+++ b/Source/FreeImageLib/FreeImageLib.2008.vcproj
@@ -47,7 +47,7 @@
 				Name="VCCLCompilerTool"
 				Optimization="0"
 				WholeProgramOptimization="false"
-				AdditionalIncludeDirectories="..\;..\ZLib;..\DeprecationManager;..\OpenEXR\Half;..\OpenEXR\Iex;..\OpenEXR\IlmImf;..\OpenEXR\Imath;..\OpenEXR\IlmThread"
+				AdditionalIncludeDirectories="..\;..\ZLib;..\DeprecationManager;..\OpenEXR;..\OpenEXR\Half;..\OpenEXR\Iex;..\OpenEXR\IlmImf;..\OpenEXR\Imath;..\OpenEXR\IlmThread;..\LibJXR\jxrgluelib;..\LibJXR\image\sys"
 				PreprocessorDefinitions="WIN32;_DEBUG;OPJ_STATIC;FREEIMAGE_LIB;_CRT_SECURE_NO_DEPRECATE;LIBRAW_NODLL"
 				StringPooling="true"
 				BasicRuntimeChecks="3"
@@ -125,7 +125,7 @@
 			<Tool
 				Name="VCCLCompilerTool"
 				Optimization="0"
-				AdditionalIncludeDirectories="..\;..\ZLib;..\DeprecationManager;..\OpenEXR\Half;..\OpenEXR\Iex;..\OpenEXR\IlmImf;..\OpenEXR\Imath;..\OpenEXR\IlmThread"
+				AdditionalIncludeDirectories="..\;..\ZLib;..\DeprecationManager;..\OpenEXR;..\OpenEXR\Half;..\OpenEXR\Iex;..\OpenEXR\IlmImf;..\OpenEXR\Imath;..\OpenEXR\IlmThread;..\LibJXR\jxrgluelib;..\LibJXR\image\sys"
 				PreprocessorDefinitions="WIN32;_DEBUG;OPJ_STATIC;FREEIMAGE_LIB;_CRT_SECURE_NO_DEPRECATE;LIBRAW_NODLL"
 				StringPooling="true"
 				BasicRuntimeChecks="3"
@@ -208,7 +208,7 @@
 				FavorSizeOrSpeed="1"
 				OmitFramePointers="true"
 				WholeProgramOptimization="true"
-				AdditionalIncludeDirectories="..\;..\ZLib;..\DeprecationManager;..\OpenEXR\Half;..\OpenEXR\Iex;..\OpenEXR\IlmImf;..\OpenEXR\Imath;..\OpenEXR\IlmThread"
+				AdditionalIncludeDirectories="..\;..\ZLib;..\DeprecationManager;..\OpenEXR;..\OpenEXR\Half;..\OpenEXR\Iex;..\OpenEXR\IlmImf;..\OpenEXR\Imath;..\OpenEXR\IlmThread;..\LibJXR\jxrgluelib;..\LibJXR\image\sys"
 				PreprocessorDefinitions="WIN32;NDEBUG;OPJ_STATIC;FREEIMAGE_LIB;_CRT_SECURE_NO_DEPRECATE;LIBRAW_NODLL"
 				StringPooling="true"
 				RuntimeLibrary="0"
@@ -289,7 +289,7 @@
 				EnableIntrinsicFunctions="true"
 				FavorSizeOrSpeed="1"
 				OmitFramePointers="true"
-				AdditionalIncludeDirectories="..\;..\ZLib;..\DeprecationManager;..\OpenEXR\Half;..\OpenEXR\Iex;..\OpenEXR\IlmImf;..\OpenEXR\Imath;..\OpenEXR\IlmThread"
+				AdditionalIncludeDirectories="..\;..\ZLib;..\DeprecationManager;..\OpenEXR;..\OpenEXR\Half;..\OpenEXR\Iex;..\OpenEXR\IlmImf;..\OpenEXR\Imath;..\OpenEXR\IlmThread;..\LibJXR\jxrgluelib;..\LibJXR\image\sys"
 				PreprocessorDefinitions="WIN32;NDEBUG;OPJ_STATIC;FREEIMAGE_LIB;_CRT_SECURE_NO_DEPRECATE;LIBRAW_NODLL"
 				StringPooling="true"
 				RuntimeLibrary="0"
@@ -378,6 +378,10 @@
 				Name="Quantizers"
 				>
 				<File
+					RelativePath="..\FreeImage\LFPQuantizer.cpp"
+					>
+				</File>
+				<File
 					RelativePath="..\FreeImage\NNQuantizer.cpp"
 					>
 				</File>
@@ -426,6 +430,14 @@
 					>
 				</File>
 				<File
+					RelativePath="..\FreeImage\ConversionRGBA16.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\FreeImage\ConversionRGBAF.cpp"
+					>
+				</File>
+				<File
 					RelativePath="..\FreeImage\ConversionRGBF.cpp"
 					>
 				</File>
@@ -530,6 +542,10 @@
 					>
 				</File>
 				<File
+					RelativePath="..\FreeImage\PluginJXR.cpp"
+					>
+				</File>
+				<File
 					RelativePath="..\FreeImage\PluginKOALA.cpp"
 					>
 				</File>
@@ -590,6 +606,10 @@
 					>
 				</File>
 				<File
+					RelativePath="..\FreeImage\PluginWebP.cpp"
+					>
+				</File>
+				<File
 					RelativePath="..\FreeImage\PluginXBM.cpp"
 					>
 				</File>
@@ -696,6 +716,10 @@
 				>
 			</File>
 			<File
+				RelativePath="..\MapIntrospector.h"
+				>
+			</File>
+			<File
 				RelativePath="..\Plugin.h"
 				>
 			</File>
diff --git a/Source/FreeImageLib/FreeImageLib.2013.vcxproj b/Source/FreeImageLib/FreeImageLib.2013.vcxproj
new file mode 100644
index 0000000..6ae619d
--- /dev/null
+++ b/Source/FreeImageLib/FreeImageLib.2013.vcxproj
@@ -0,0 +1,394 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectName>FreeImageLib</ProjectName>
+    <ProjectGuid>{9E219DF2-315D-478E-8A07-8960C377CE1E}</ProjectGuid>
+    <RootNamespace>FreeImageLib</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>12.0.21005.1</_ProjectFileVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <WholeProgramOptimization>false</WholeProgramOptimization>
+      <AdditionalIncludeDirectories>..;..\ZLib;..\DeprecationManager;..\OpenEXR;..\OpenEXR\Half;..\OpenEXR\Iex;..\OpenEXR\IlmImf;..\OpenEXR\Imath;..\OpenEXR\IlmThread;..\LibJXR\jxrgluelib;..\LibJXR\image\sys;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;OPJ_STATIC;FREEIMAGE_LIB;_CRT_SECURE_NO_DEPRECATE;LIBRAW_NODLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+      <CompileAs>Default</CompileAs>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+      <MultiProcessorCompilation>false</MultiProcessorCompilation>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0413</Culture>
+    </ResourceCompile>
+    <ProjectReference>
+      <LinkLibraryDependencies>true</LinkLibraryDependencies>
+    </ProjectReference>
+    <Lib>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </Lib>
+    <PostBuildEvent>
+      <Command>mkdir ..\..\Dist\x32
+copy $(TargetPath) ..\..\Dist\x32\$(ProjectName)d.lib
+copy ..\FreeImage.h ..\..\Dist\x32
+</Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..;..\ZLib;..\DeprecationManager;..\OpenEXR;..\OpenEXR\Half;..\OpenEXR\Iex;..\OpenEXR\IlmImf;..\OpenEXR\Imath;..\OpenEXR\IlmThread;..\LibJXR\jxrgluelib;..\LibJXR\image\sys;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;OPJ_STATIC;FREEIMAGE_LIB;_CRT_SECURE_NO_DEPRECATE;LIBRAW_NODLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <OpenMPSupport>true</OpenMPSupport>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <CompileAs>Default</CompileAs>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+      <MultiProcessorCompilation>false</MultiProcessorCompilation>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0413</Culture>
+    </ResourceCompile>
+    <ProjectReference>
+      <LinkLibraryDependencies>true</LinkLibraryDependencies>
+    </ProjectReference>
+    <Lib>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </Lib>
+    <PostBuildEvent>
+      <Command>mkdir ..\..\Dist\x64
+copy $(TargetPath) ..\..\Dist\x64\$(ProjectName)d.lib
+copy ..\FreeImage.h ..\..\Dist\x64
+</Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <OmitFramePointers>true</OmitFramePointers>
+      <WholeProgramOptimization>true</WholeProgramOptimization>
+      <AdditionalIncludeDirectories>..;..\ZLib;..\DeprecationManager;..\OpenEXR;..\OpenEXR\Half;..\OpenEXR\Iex;..\OpenEXR\IlmImf;..\OpenEXR\Imath;..\OpenEXR\IlmThread;..\LibJXR\jxrgluelib;..\LibJXR\image\sys;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;OPJ_STATIC;FREEIMAGE_LIB;_CRT_SECURE_NO_DEPRECATE;LIBRAW_NODLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <CompileAs>Default</CompileAs>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+      <MultiProcessorCompilation>false</MultiProcessorCompilation>
+      <DebugInformationFormat>None</DebugInformationFormat>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0409</Culture>
+    </ResourceCompile>
+    <ProjectReference>
+      <LinkLibraryDependencies>true</LinkLibraryDependencies>
+    </ProjectReference>
+    <Lib>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <LinkTimeCodeGeneration>true</LinkTimeCodeGeneration>
+    </Lib>
+    <PostBuildEvent>
+      <Command>mkdir ..\..\Dist\x32
+copy $(TargetPath) ..\..\Dist\x32\$(ProjectName).lib
+copy ..\FreeImage.h ..\..\Dist\x32
+</Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>Full</Optimization>
+      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>..;..\ZLib;..\DeprecationManager;..\OpenEXR;..\OpenEXR\Half;..\OpenEXR\Iex;..\OpenEXR\IlmImf;..\OpenEXR\Imath;..\OpenEXR\IlmThread;..\LibJXR\jxrgluelib;..\LibJXR\image\sys;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;OPJ_STATIC;FREEIMAGE_LIB;_CRT_SECURE_NO_DEPRECATE;LIBRAW_NODLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <OpenMPSupport>true</OpenMPSupport>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <CompileAs>Default</CompileAs>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+      <MultiProcessorCompilation>false</MultiProcessorCompilation>
+      <DebugInformationFormat>None</DebugInformationFormat>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0409</Culture>
+    </ResourceCompile>
+    <ProjectReference>
+      <LinkLibraryDependencies>true</LinkLibraryDependencies>
+    </ProjectReference>
+    <Lib>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <LinkTimeCodeGeneration>true</LinkTimeCodeGeneration>
+    </Lib>
+    <PostBuildEvent>
+      <Command>mkdir ..\..\Dist\x64
+copy $(TargetPath) ..\..\Dist\x64\$(ProjectName).lib
+copy ..\FreeImage.h ..\..\Dist\x64
+</Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="..\FreeImage\BitmapAccess.cpp" />
+    <ClCompile Include="..\FreeImage\ColorLookup.cpp" />
+    <ClCompile Include="..\FreeImage\ConversionRGBA16.cpp" />
+    <ClCompile Include="..\FreeImage\ConversionRGBAF.cpp" />
+    <ClCompile Include="..\FreeImage\FreeImage.cpp" />
+    <ClCompile Include="..\FreeImage\FreeImageIO.cpp" />
+    <ClCompile Include="..\FreeImage\GetType.cpp" />
+    <ClCompile Include="..\FreeImage\LFPQuantizer.cpp" />
+    <ClCompile Include="..\FreeImage\MemoryIO.cpp" />
+    <ClCompile Include="..\FreeImage\PixelAccess.cpp" />
+    <ClCompile Include="..\FreeImage\NNQuantizer.cpp" />
+    <ClCompile Include="..\FreeImage\WuQuantizer.cpp" />
+    <ClCompile Include="..\FreeImage\Conversion.cpp" />
+    <ClCompile Include="..\FreeImage\Conversion16_555.cpp" />
+    <ClCompile Include="..\FreeImage\Conversion16_565.cpp" />
+    <ClCompile Include="..\FreeImage\Conversion24.cpp" />
+    <ClCompile Include="..\FreeImage\Conversion32.cpp" />
+    <ClCompile Include="..\FreeImage\Conversion4.cpp" />
+    <ClCompile Include="..\FreeImage\Conversion8.cpp" />
+    <ClCompile Include="..\FreeImage\ConversionFloat.cpp" />
+    <ClCompile Include="..\FreeImage\ConversionRGB16.cpp" />
+    <ClCompile Include="..\FreeImage\ConversionRGBF.cpp" />
+    <ClCompile Include="..\FreeImage\ConversionType.cpp" />
+    <ClCompile Include="..\FreeImage\ConversionUINT16.cpp" />
+    <ClCompile Include="..\FreeImage\Halftoning.cpp" />
+    <ClCompile Include="..\FreeImage\tmoColorConvert.cpp" />
+    <ClCompile Include="..\FreeImage\tmoDrago03.cpp" />
+    <ClCompile Include="..\FreeImage\tmoFattal02.cpp" />
+    <ClCompile Include="..\FreeImage\tmoReinhard05.cpp" />
+    <ClCompile Include="..\FreeImage\ToneMapping.cpp" />
+    <ClCompile Include="..\FreeImage\J2KHelper.cpp" />
+    <ClCompile Include="..\FreeImage\MNGHelper.cpp" />
+    <ClCompile Include="..\FreeImage\Plugin.cpp" />
+    <ClCompile Include="..\FreeImage\PluginBMP.cpp" />
+    <ClCompile Include="..\FreeImage\PluginCUT.cpp" />
+    <ClCompile Include="..\FreeImage\PluginDDS.cpp" />
+    <ClCompile Include="..\FreeImage\PluginEXR.cpp" />
+    <ClCompile Include="..\FreeImage\PluginG3.cpp" />
+    <ClCompile Include="..\FreeImage\PluginGIF.cpp" />
+    <ClCompile Include="..\FreeImage\PluginHDR.cpp" />
+    <ClCompile Include="..\FreeImage\PluginICO.cpp" />
+    <ClCompile Include="..\FreeImage\PluginIFF.cpp" />
+    <ClCompile Include="..\FreeImage\PluginJ2K.cpp" />
+    <ClCompile Include="..\FreeImage\PluginJNG.cpp" />
+    <ClCompile Include="..\FreeImage\PluginJP2.cpp" />
+    <ClCompile Include="..\FreeImage\PluginJPEG.cpp" />
+    <ClCompile Include="..\FreeImage\PluginJXR.cpp" />
+    <ClCompile Include="..\FreeImage\PluginKOALA.cpp" />
+    <ClCompile Include="..\FreeImage\PluginMNG.cpp" />
+    <ClCompile Include="..\FreeImage\PluginPCD.cpp" />
+    <ClCompile Include="..\FreeImage\PluginPCX.cpp" />
+    <ClCompile Include="..\FreeImage\PluginPFM.cpp" />
+    <ClCompile Include="..\FreeImage\PluginPICT.cpp" />
+    <ClCompile Include="..\FreeImage\PluginPNG.cpp" />
+    <ClCompile Include="..\FreeImage\PluginPNM.cpp" />
+    <ClCompile Include="..\FreeImage\PluginPSD.cpp" />
+    <ClCompile Include="..\FreeImage\PluginRAS.cpp" />
+    <ClCompile Include="..\FreeImage\PluginRAW.cpp" />
+    <ClCompile Include="..\FreeImage\PluginSGI.cpp" />
+    <ClCompile Include="..\FreeImage\PluginTARGA.cpp" />
+    <ClCompile Include="..\FreeImage\PluginTIFF.cpp" />
+    <ClCompile Include="..\FreeImage\PluginWBMP.cpp" />
+    <ClCompile Include="..\FreeImage\PluginWebP.cpp" />
+    <ClCompile Include="..\FreeImage\PluginXBM.cpp" />
+    <ClCompile Include="..\FreeImage\PluginXPM.cpp" />
+    <ClCompile Include="..\FreeImage\PSDParser.cpp" />
+    <ClCompile Include="..\FreeImage\TIFFLogLuv.cpp" />
+    <ClCompile Include="..\DeprecationManager\Deprecated.cpp" />
+    <ClCompile Include="..\DeprecationManager\DeprecationMgr.cpp" />
+    <ClCompile Include="..\FreeImage\CacheFile.cpp" />
+    <ClCompile Include="..\FreeImage\MultiPage.cpp" />
+    <ClCompile Include="..\FreeImage\ZLibInterface.cpp" />
+    <ClCompile Include="..\Metadata\Exif.cpp" />
+    <ClCompile Include="..\Metadata\FIRational.cpp" />
+    <ClCompile Include="..\Metadata\FreeImageTag.cpp" />
+    <ClCompile Include="..\Metadata\IPTC.cpp" />
+    <ClCompile Include="..\Metadata\TagConversion.cpp" />
+    <ClCompile Include="..\Metadata\TagLib.cpp" />
+    <ClCompile Include="..\Metadata\XTIFF.cpp" />
+    <ClCompile Include="..\FreeImageToolkit\Background.cpp" />
+    <ClCompile Include="..\FreeImageToolkit\BSplineRotate.cpp" />
+    <ClCompile Include="..\FreeImageToolkit\Channels.cpp" />
+    <ClCompile Include="..\FreeImageToolkit\ClassicRotate.cpp" />
+    <ClCompile Include="..\FreeImageToolkit\Colors.cpp" />
+    <ClCompile Include="..\FreeImageToolkit\CopyPaste.cpp" />
+    <ClCompile Include="..\FreeImageToolkit\Display.cpp" />
+    <ClCompile Include="..\FreeImageToolkit\Flip.cpp" />
+    <ClCompile Include="..\FreeImageToolkit\JPEGTransform.cpp" />
+    <ClCompile Include="..\FreeImageToolkit\MultigridPoissonSolver.cpp" />
+    <ClCompile Include="..\FreeImageToolkit\Rescale.cpp" />
+    <ClCompile Include="..\FreeImageToolkit\Resize.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\CacheFile.h" />
+    <ClInclude Include="..\DeprecationManager\DeprecationMgr.h" />
+    <ClInclude Include="..\MapIntrospector.h" />
+    <ClInclude Include="..\Metadata\FIRational.h" />
+    <ClInclude Include="..\FreeImage.h" />
+    <ClInclude Include="..\FreeImageIO.h" />
+    <ClInclude Include="..\Metadata\FreeImageTag.h" />
+    <ClInclude Include="..\Plugin.h" />
+    <ClInclude Include="..\FreeImage\PSDParser.h" />
+    <ClInclude Include="..\Quantizers.h" />
+    <ClInclude Include="..\ToneMapping.h" />
+    <ClInclude Include="..\Utilities.h" />
+    <ClInclude Include="..\FreeImageToolkit\Resize.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <Text Include="..\..\Whatsnew.txt" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\LibJPEG\LibJPEG.2013.vcxproj">
+      <Project>{5e1d4e5f-e10c-4ba3-b663-f33014fd21d9}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+    <ProjectReference Include="..\LibJXR\LibJXR.2013.vcxproj">
+      <Project>{244455e0-5f25-4451-9540-f317883e52a8}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+    <ProjectReference Include="..\LibOpenJPEG\LibOpenJPEG.2013.vcxproj">
+      <Project>{e3536c28-a7f1-4b53-8e52-7d2232f9e098}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+    <ProjectReference Include="..\LibPNG\LibPNG.2013.vcxproj">
+      <Project>{7db10b50-ce00-4d7a-b322-6824f05d2fcb}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+    <ProjectReference Include="..\LibRawLite\LibRawLite.2013.vcxproj">
+      <Project>{07f662c1-1323-42ab-b6af-fbfd34a7437a}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+    <ProjectReference Include="..\LibTIFF4\LibTIFF4.2013.vcxproj">
+      <Project>{ec085cbd-e9c3-477f-9a97-cb9d5da30e27}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+    <ProjectReference Include="..\LibWebP\LibWebP.2013.vcxproj">
+      <Project>{097d9f6c-fd0e-4cbc-9676-009012aaeca8}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+    <ProjectReference Include="..\OpenEXR\OpenEXR.2013.vcxproj">
+      <Project>{17a4874b-0606-4687-90b6-f91f8cb3b8af}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+    <ProjectReference Include="..\ZLib\ZLib.2013.vcxproj">
+      <Project>{33134f61-c1ad-4b6f-9cea-503a9f140c52}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/Source/FreeImageLib/FreeImageLib.2013.vcxproj.filters b/Source/FreeImageLib/FreeImageLib.2013.vcxproj.filters
new file mode 100644
index 0000000..db021e8
--- /dev/null
+++ b/Source/FreeImageLib/FreeImageLib.2013.vcxproj.filters
@@ -0,0 +1,353 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{7c15da45-1330-439d-bd4d-2dd68052fa6a}</UniqueIdentifier>
+      <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
+    </Filter>
+    <Filter Include="Source Files\Quantizers">
+      <UniqueIdentifier>{e42380d3-5a98-4e9f-8b7b-115a51987c46}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\Conversion">
+      <UniqueIdentifier>{4b791fa0-9f95-4946-b531-97f8ef56d41e}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\Plugins">
+      <UniqueIdentifier>{8220fc03-8784-4a29-b481-e8d9f1e74e3a}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\DeprecationMgr">
+      <UniqueIdentifier>{63c13f97-6b3a-478f-a696-749f3a936e19}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\MultiPaging">
+      <UniqueIdentifier>{0e76c2fb-8cf7-42fb-a86f-ce5d4c472dfa}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\Metadata">
+      <UniqueIdentifier>{469664c9-5f22-4e03-abf6-7fa7d12e2a12}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{e184a9fd-1443-4939-95da-ceb10795ef7f}</UniqueIdentifier>
+      <Extensions>h;hpp;hxx;hm;inl</Extensions>
+    </Filter>
+    <Filter Include="Toolkit Files">
+      <UniqueIdentifier>{12c22d35-0ae9-4ab6-95f5-ace2cb1d01c5}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\FreeImage\BitmapAccess.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\ColorLookup.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\FreeImage.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\FreeImageIO.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\GetType.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\MemoryIO.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\PixelAccess.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\NNQuantizer.cpp">
+      <Filter>Source Files\Quantizers</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\WuQuantizer.cpp">
+      <Filter>Source Files\Quantizers</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\Conversion.cpp">
+      <Filter>Source Files\Conversion</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\Conversion16_555.cpp">
+      <Filter>Source Files\Conversion</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\Conversion16_565.cpp">
+      <Filter>Source Files\Conversion</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\Conversion24.cpp">
+      <Filter>Source Files\Conversion</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\Conversion32.cpp">
+      <Filter>Source Files\Conversion</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\Conversion4.cpp">
+      <Filter>Source Files\Conversion</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\Conversion8.cpp">
+      <Filter>Source Files\Conversion</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\ConversionFloat.cpp">
+      <Filter>Source Files\Conversion</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\ConversionRGB16.cpp">
+      <Filter>Source Files\Conversion</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\ConversionRGBF.cpp">
+      <Filter>Source Files\Conversion</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\ConversionType.cpp">
+      <Filter>Source Files\Conversion</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\ConversionUINT16.cpp">
+      <Filter>Source Files\Conversion</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\Halftoning.cpp">
+      <Filter>Source Files\Conversion</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\tmoColorConvert.cpp">
+      <Filter>Source Files\Conversion</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\tmoDrago03.cpp">
+      <Filter>Source Files\Conversion</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\tmoFattal02.cpp">
+      <Filter>Source Files\Conversion</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\tmoReinhard05.cpp">
+      <Filter>Source Files\Conversion</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\ToneMapping.cpp">
+      <Filter>Source Files\Conversion</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\J2KHelper.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\MNGHelper.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\Plugin.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\PluginBMP.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\PluginCUT.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\PluginDDS.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\PluginEXR.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\PluginG3.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\PluginGIF.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\PluginHDR.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\PluginICO.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\PluginIFF.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\PluginJ2K.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\PluginJNG.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\PluginJP2.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\PluginJPEG.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\PluginJXR.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\PluginKOALA.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\PluginMNG.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\PluginPCD.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\PluginPCX.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\PluginPFM.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\PluginPICT.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\PluginPNG.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\PluginPNM.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\PluginPSD.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\PluginRAS.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\PluginRAW.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\PluginSGI.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\PluginTARGA.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\PluginTIFF.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\PluginWBMP.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\PluginWebP.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\PluginXBM.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\PluginXPM.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\PSDParser.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\TIFFLogLuv.cpp">
+      <Filter>Source Files\Plugins</Filter>
+    </ClCompile>
+    <ClCompile Include="..\DeprecationManager\Deprecated.cpp">
+      <Filter>Source Files\DeprecationMgr</Filter>
+    </ClCompile>
+    <ClCompile Include="..\DeprecationManager\DeprecationMgr.cpp">
+      <Filter>Source Files\DeprecationMgr</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\CacheFile.cpp">
+      <Filter>Source Files\MultiPaging</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\MultiPage.cpp">
+      <Filter>Source Files\MultiPaging</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\ZLibInterface.cpp">
+      <Filter>Source Files\MultiPaging</Filter>
+    </ClCompile>
+    <ClCompile Include="..\Metadata\Exif.cpp">
+      <Filter>Source Files\Metadata</Filter>
+    </ClCompile>
+    <ClCompile Include="..\Metadata\FIRational.cpp">
+      <Filter>Source Files\Metadata</Filter>
+    </ClCompile>
+    <ClCompile Include="..\Metadata\FreeImageTag.cpp">
+      <Filter>Source Files\Metadata</Filter>
+    </ClCompile>
+    <ClCompile Include="..\Metadata\IPTC.cpp">
+      <Filter>Source Files\Metadata</Filter>
+    </ClCompile>
+    <ClCompile Include="..\Metadata\TagConversion.cpp">
+      <Filter>Source Files\Metadata</Filter>
+    </ClCompile>
+    <ClCompile Include="..\Metadata\TagLib.cpp">
+      <Filter>Source Files\Metadata</Filter>
+    </ClCompile>
+    <ClCompile Include="..\Metadata\XTIFF.cpp">
+      <Filter>Source Files\Metadata</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImageToolkit\Background.cpp">
+      <Filter>Toolkit Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImageToolkit\BSplineRotate.cpp">
+      <Filter>Toolkit Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImageToolkit\Channels.cpp">
+      <Filter>Toolkit Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImageToolkit\ClassicRotate.cpp">
+      <Filter>Toolkit Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImageToolkit\Colors.cpp">
+      <Filter>Toolkit Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImageToolkit\CopyPaste.cpp">
+      <Filter>Toolkit Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImageToolkit\Display.cpp">
+      <Filter>Toolkit Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImageToolkit\Flip.cpp">
+      <Filter>Toolkit Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImageToolkit\JPEGTransform.cpp">
+      <Filter>Toolkit Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImageToolkit\MultigridPoissonSolver.cpp">
+      <Filter>Toolkit Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImageToolkit\Rescale.cpp">
+      <Filter>Toolkit Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImageToolkit\Resize.cpp">
+      <Filter>Toolkit Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\LFPQuantizer.cpp">
+      <Filter>Source Files\Quantizers</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\ConversionRGBAF.cpp">
+      <Filter>Source Files\Conversion</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FreeImage\ConversionRGBA16.cpp">
+      <Filter>Source Files\Conversion</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\CacheFile.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\DeprecationManager\DeprecationMgr.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\Metadata\FIRational.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\FreeImage.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\FreeImageIO.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\Metadata\FreeImageTag.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\Plugin.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\FreeImage\PSDParser.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\Quantizers.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\ToneMapping.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\Utilities.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\FreeImageToolkit\Resize.h">
+      <Filter>Toolkit Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\MapIntrospector.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <Text Include="..\..\Whatsnew.txt" />
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/Source/FreeImageToolkit/CopyPaste.cpp b/Source/FreeImageToolkit/CopyPaste.cpp
index e4b8155..d05a5df 100644
--- a/Source/FreeImageToolkit/CopyPaste.cpp
+++ b/Source/FreeImageToolkit/CopyPaste.cpp
@@ -6,6 +6,7 @@
 // - Herv� Drolon (drolon at infonie.fr)
 // - Manfred Tausch (manfred.tausch at t-online.de)
 // - Riley McNiff (rmcniff at marexgroup.com)
+// - Carsten Klein (cklein05 at users.sourceforge.net)
 //
 // This file is part of FreeImage 3
 //
@@ -92,7 +93,6 @@ Combine1(FIBITMAP *dst_dib, FIBITMAP *src_dib, unsigned x, unsigned y, unsigned
 
 static BOOL 
 Combine4(FIBITMAP *dst_dib, FIBITMAP *src_dib, unsigned x, unsigned y, unsigned alpha) {
-
 	int swapTable[16];
 	BOOL bOddStart, bOddEnd;
 
@@ -744,4 +744,118 @@ FreeImage_Paste(FIBITMAP *dst, FIBITMAP *src, int left, int top, int alpha) {
 	return bResult;
 }
 
+// ----------------------------------------------------------
+
+/** @brief Creates a dynamic read/write view into a FreeImage bitmap.
+
+ A dynamic view is a FreeImage bitmap with its own width and height, that,
+ however, shares its bits with another FreeImage bitmap. Typically, views
+ are used to define one or more rectangular sub-images of an existing
+ bitmap. All FreeImage operations, like saving, displaying and all the
+ toolkit functions, when applied to the view, only affect the view's
+ rectangular area.
+
+ Although the view's backing image's bits not need to be copied around,
+ which makes the view much faster than similar solutions using
+ FreeImage_Copy, a view uses some private memory that needs to be freed by
+ calling FreeImage_Unload on the view's handle to prevent memory leaks.
+
+ Only the backing image's pixels are shared by the view. For all other image
+ data, notably for the resolution, background color, color palette,
+ transparency table and for the ICC profile, the view gets a private copy
+ of the data. By default, the backing image's metadata is NOT copied to
+ the view.
+
+ As with all FreeImage functions that take a rectangle region, top and left
+ positions are included, whereas right and bottom positions are excluded
+ from the rectangle area.
+
+ Since the memory block shared by the backing image and the view must start
+ at a byte boundary, the value of parameter left must be a multiple of 8
+ for 1-bit images and a multiple of 2 for 4-bit images.
+
+ @param dib The FreeImage bitmap on which to create the view.
+ @param left The left position of the view's area.
+ @param top The top position of the view's area.
+ @param right The right position of the view's area.
+ @param bottom The bottom position of the view's area.
+ @return Returns a handle to the newly created view or NULL if the view
+ was not created.
+ */
+FIBITMAP * DLL_CALLCONV
+FreeImage_CreateView(FIBITMAP *dib, unsigned left, unsigned top, unsigned right, unsigned bottom) {
+	if (!FreeImage_HasPixels(dib)) {
+		return NULL;
+	}
+
+	// normalize the rectangle
+	if (right < left) {
+		INPLACESWAP(left, right);
+	}
+	if (bottom < top) {
+		INPLACESWAP(top, bottom);
+	}
+
+	// check the size of the sub image
+	unsigned width = FreeImage_GetWidth(dib);
+	unsigned height = FreeImage_GetHeight(dib);
+	if (left < 0 || right > width || top < 0 || bottom > height) {
+		return NULL;
+	}
+
+	unsigned bpp = FreeImage_GetBPP(dib);
+	BYTE *bits = FreeImage_GetScanLine(dib, height - bottom);
+	switch (bpp) {
+		case 1:
+			if (left % 8 != 0) {
+				// view can only start at a byte boundary
+				return NULL;
+			}
+			bits += (left / 8);
+			break;
+		case 4:
+			if (left % 2 != 0) {
+				// view can only start at a byte boundary
+				return NULL;
+				}
+			bits += (left / 2);
+			break;
+		default:
+			bits += left * (bpp / 8);
+			break;
+	}
+
+	FIBITMAP *dst = FreeImage_AllocateHeaderForBits(bits, FreeImage_GetPitch(dib), FreeImage_GetImageType(dib), 
+		right - left, bottom - top, 
+		bpp, 
+		FreeImage_GetRedMask(dib), FreeImage_GetGreenMask(dib), FreeImage_GetBlueMask(dib));
+
+	if (dst == NULL) {
+		return NULL;
+	}
 
+	// copy some basic image properties needed for displaying and saving
+
+	// resolution
+	FreeImage_SetDotsPerMeterX(dst, FreeImage_GetDotsPerMeterX(dib));
+	FreeImage_SetDotsPerMeterY(dst, FreeImage_GetDotsPerMeterY(dib));
+
+	// background color
+	RGBQUAD bkcolor;
+	if (FreeImage_GetBackgroundColor(dib, &bkcolor)) {
+		FreeImage_SetBackgroundColor(dst, &bkcolor);
+	}
+
+	// palette
+	memcpy(FreeImage_GetPalette(dst), FreeImage_GetPalette(dib), FreeImage_GetColorsUsed(dib) * sizeof(RGBQUAD));
+
+	// transparency table
+	FreeImage_SetTransparencyTable(dst, FreeImage_GetTransparencyTable(dib), FreeImage_GetTransparencyCount(dib));
+
+	// ICC profile
+	FIICCPROFILE *src_profile = FreeImage_GetICCProfile(dib);
+	FIICCPROFILE *dst_profile = FreeImage_CreateICCProfile(dst, src_profile->data, src_profile->size);
+	dst_profile->flags = src_profile->flags;
+
+	return dst;
+}
diff --git a/Source/FreeImageToolkit/JPEGTransform.cpp b/Source/FreeImageToolkit/JPEGTransform.cpp
index 5822f74..6f9ba8e 100644
--- a/Source/FreeImageToolkit/JPEGTransform.cpp
+++ b/Source/FreeImageToolkit/JPEGTransform.cpp
@@ -3,7 +3,8 @@
 //
 // Design and implementation by
 // - Petr Pytelka (pyta at lightcomp.com)
-// - Herv� Drolon (drolon at infonie.fr)
+// - Hervé Drolon (drolon at infonie.fr)
+// - Mihail Naydenov (mnaydenov at users.sourceforge.net)
 //
 // This file is part of FreeImage 3
 //
@@ -33,20 +34,19 @@ extern "C" {
 
 #include "FreeImage.h"
 #include "Utilities.h"
+#include "FreeImageIO.h"
 
 // ----------------------------------------------------------
-//   IO filename handling
+//   Source manager & Destination manager setup
+//   (see PluginJPEG.cpp)
 // ----------------------------------------------------------
 
-typedef struct tagFilenameIO {
-	const char *src_file;
-	const char *dst_file;
-	const wchar_t *wsrc_file;
-	const wchar_t *wdst_file;
-} FilenameIO;
+void jpeg_freeimage_src(j_decompress_ptr cinfo, fi_handle infile, FreeImageIO *io);
+void jpeg_freeimage_dst(j_compress_ptr cinfo, fi_handle outfile, FreeImageIO *io);
 
 // ----------------------------------------------------------
 //   Error handling
+//   (see also PluginJPEG.cpp)
 // ----------------------------------------------------------
 
 /**
@@ -62,10 +62,10 @@ ls_jpeg_error_exit (j_common_ptr cinfo) {
 
 	// allow JPEG with a premature end of file
 	if((cinfo)->err->msg_parm.i[0] != 13) {
-	
+
 		// let the memory manager delete any temp files before we die
 		jpeg_destroy(cinfo);
-		
+
 		throw FIF_JPEG;
 	}
 }
@@ -88,14 +88,73 @@ ls_jpeg_output_message (j_common_ptr cinfo) {
 //   Main program
 // ----------------------------------------------------------
 
-static BOOL  
-LosslessTransform(const FilenameIO *filenameIO, FREE_IMAGE_JPEG_OPERATION operation, const char *crop, BOOL perfect) {
-	// We assume all-in-memory processing and can therefore use only a
-	// single file pointer for sequential input and output operation
-	FILE *fp = NULL;
+/**
+Build a crop string. 
+
+ at param crop Output crop string
+ at param left Specifies the left position of the cropped rectangle
+ at param top Specifies the top position of the cropped rectangle
+ at param right Specifies the right position of the cropped rectangle
+ at param bottom Specifies the bottom position of the cropped rectangle
+ at param width Image width
+ at param height Image height
+ at return Returns TRUE if successful, returns FALSE otherwise
+*/
+static BOOL
+getCropString(char* crop, int* left, int* top, int* right, int* bottom, int width, int height) {
+	if(!left || !top || !right || !bottom) {
+		return FALSE;
+	}
+
+	*left = CLAMP(*left, 0, width);
+	*top = CLAMP(*top, 0, height);
+
+	// negative/zero right and bottom count from the edges inwards
+
+	if(*right <= 0) {
+		*right = width + *right;
+	}
+	if(*bottom <= 0) {
+		*bottom = height + *bottom;
+	}
+
+	*right = CLAMP(*right, 0, width);
+	*bottom = CLAMP(*bottom, 0, height);
+
+	// test for empty rect
+
+	if(((*left - *right) == 0) || ((*top - *bottom) == 0)) {
+		return FALSE;
+	}
+
+	// normalize the rectangle
+
+	if(*right < *left) {
+		INPLACESWAP(*left, *right);
+	}
+	if(*bottom < *top) {
+		INPLACESWAP(*top, *bottom);
+	}
+
+	// test for "noop" rect
+
+	if(*left == 0 && *right == width && *top == 0 && *bottom == height) {
+		return FALSE;
+	}
+
+	// build the crop option
+	sprintf(crop, "%dx%d+%d+%d", *right - *left, *bottom - *top, *left, *top);
+
+	return TRUE;
+}
 
-	// check for UNICODE filenames - previous structure filling was done before
-	bool bUseUnicode = filenameIO && filenameIO->wsrc_file && filenameIO->wdst_file;
+static BOOL
+JPEGTransformFromHandle(FreeImageIO* src_io, fi_handle src_handle, FreeImageIO* dst_io, fi_handle dst_handle, FREE_IMAGE_JPEG_OPERATION operation, int* left, int* top, int* right, int* bottom, BOOL perfect) {
+	const BOOL onlyReturnCropRect = (dst_io == NULL) || (dst_handle == NULL);
+	const long stream_start = onlyReturnCropRect ? 0 : dst_io->tell_proc(dst_handle);
+	BOOL swappedDim = FALSE;
+	BOOL trimH = FALSE;
+	BOOL trimV = FALSE;
 
 	// Set up the jpeglib structures
 	jpeg_decompress_struct srcinfo;
@@ -107,17 +166,17 @@ LosslessTransform(const FilenameIO *filenameIO, FREE_IMAGE_JPEG_OPERATION operat
 	JCOPY_OPTION copyoption;
 	// Image transformation options
 	jpeg_transform_info transfoptions;
-	
+
 	// Initialize structures
 	memset(&srcinfo, 0, sizeof(srcinfo));
 	memset(&jsrcerr, 0, sizeof(jsrcerr));
 	memset(&jdsterr, 0, sizeof(jdsterr));
 	memset(&dstinfo, 0, sizeof(dstinfo));
 	memset(&transfoptions, 0, sizeof(transfoptions));
-	
+
 	// Copy all extra markers from source file
 	copyoption = JCOPYOPT_ALL;
-	
+
 	// Set up default JPEG parameters
 	transfoptions.force_grayscale = FALSE;
 	transfoptions.crop = FALSE;
@@ -126,24 +185,36 @@ LosslessTransform(const FilenameIO *filenameIO, FREE_IMAGE_JPEG_OPERATION operat
 	switch(operation) {
 		case FIJPEG_OP_FLIP_H:		// horizontal flip
 			transfoptions.transform = JXFORM_FLIP_H;
+			trimH = TRUE;
 			break;
 		case FIJPEG_OP_FLIP_V:		// vertical flip
 			transfoptions.transform = JXFORM_FLIP_V;
+			trimV = TRUE;
 			break;
 		case FIJPEG_OP_TRANSPOSE:	// transpose across UL-to-LR axis
 			transfoptions.transform = JXFORM_TRANSPOSE;
+			swappedDim = TRUE;
 			break;
 		case FIJPEG_OP_TRANSVERSE:	// transpose across UR-to-LL axis
 			transfoptions.transform = JXFORM_TRANSVERSE;
+			trimH = TRUE;
+			trimV = TRUE;
+			swappedDim = TRUE;
 			break;
 		case FIJPEG_OP_ROTATE_90:	// 90-degree clockwise rotation
 			transfoptions.transform = JXFORM_ROT_90;
+			trimH = TRUE;
+			swappedDim = TRUE;
 			break;
 		case FIJPEG_OP_ROTATE_180:	// 180-degree rotation
+			trimH = TRUE;
+			trimV = TRUE;
 			transfoptions.transform = JXFORM_ROT_180;
 			break;
 		case FIJPEG_OP_ROTATE_270:	// 270-degree clockwise (or 90 ccw)
 			transfoptions.transform = JXFORM_ROT_270;
+			trimV = TRUE;
+			swappedDim = TRUE;
 			break;
 		default:
 		case FIJPEG_OP_NONE:		// no transformation
@@ -169,43 +240,26 @@ LosslessTransform(const FilenameIO *filenameIO, FREE_IMAGE_JPEG_OPERATION operat
 		dstinfo.err->output_message = ls_jpeg_output_message;
 		jpeg_create_compress(&dstinfo);
 
+		// Specify data source for decompression
+		jpeg_freeimage_src(&srcinfo, src_handle, src_io);
+
+		// Enable saving of extra markers that we want to copy
+		jcopy_markers_setup(&srcinfo, copyoption);
+
+		// Read the file header
+		jpeg_read_header(&srcinfo, TRUE);
+
 		// crop option
-		if(crop != NULL) {
+		char crop[64];
+		const BOOL hasCrop = getCropString(crop, left, top, right, bottom, swappedDim ? srcinfo.image_height : srcinfo.image_width, swappedDim ? srcinfo.image_width : srcinfo.image_height);
+
+		if(hasCrop) {
 			if(!jtransform_parse_crop_spec(&transfoptions, crop)) {
 				FreeImage_OutputMessageProc(FIF_JPEG, "Bogus crop argument %s", crop);
 				throw(1);
 			}
 		}
 
-		// Open the input file
-		if(bUseUnicode) {
-#ifdef _WIN32
-			if((fp = _wfopen(filenameIO->wsrc_file, L"rb")) == NULL) {
-				FreeImage_OutputMessageProc(FIF_JPEG, "Cannot open input file for reading");
-			}
-#else
-			fp = NULL;
-#endif // _WIN32
-		} else {
-			if((fp = fopen(filenameIO->src_file, "rb")) == NULL) {
-				FreeImage_OutputMessageProc(FIF_JPEG, "Cannot open %s for reading", filenameIO->src_file);
-			}
-		}
-		if(fp == NULL) {
-			jpeg_destroy_compress(&dstinfo);
-			jpeg_destroy_decompress(&srcinfo);
-			return FALSE;
-		}
-		
-		// Specify data source for decompression
-		jpeg_stdio_src(&srcinfo, fp);
-		
-		// Enable saving of extra markers that we want to copy
-		jcopy_markers_setup(&srcinfo, copyoption);
-		
-		// Read the file header
-		jpeg_read_header(&srcinfo, TRUE);
-		
 		// Any space needed by a transform option must be requested before
 		// jpeg_read_coefficients so that memory allocation will be done right
 
@@ -216,65 +270,90 @@ LosslessTransform(const FilenameIO *filenameIO, FREE_IMAGE_JPEG_OPERATION operat
 			throw(1);
 		}
 
+		if(left || top) {
+			// compute left and top offsets, it's a bit tricky, taking into account both
+			// transform, which might have trimed the image,
+			// and crop itself, which is adjusted to lie on a iMCU boundary
+
+			const int fullWidth = swappedDim ? srcinfo.image_height : srcinfo.image_width;
+			const int fullHeight = swappedDim ? srcinfo.image_width : srcinfo.image_height;
+
+			int transformedFullWidth = fullWidth;
+			int transformedFullHeight = fullHeight;
+
+			if(trimH && transformedFullWidth/transfoptions.iMCU_sample_width > 0) {
+				transformedFullWidth = (transformedFullWidth/transfoptions.iMCU_sample_width) * transfoptions.iMCU_sample_width;
+			}
+			if(trimV && transformedFullHeight/transfoptions.iMCU_sample_height > 0) {
+				transformedFullHeight = (transformedFullHeight/transfoptions.iMCU_sample_height) * transfoptions.iMCU_sample_height;
+			}
+
+			const int trimmedWidth = fullWidth - transformedFullWidth;
+			const int trimmedHeight = fullHeight - transformedFullHeight;
+
+			if(left) {
+				*left = trimmedWidth + transfoptions.x_crop_offset * transfoptions.iMCU_sample_width;
+			}
+			if(top) {
+				*top = trimmedHeight + transfoptions.y_crop_offset * transfoptions.iMCU_sample_height;
+			}
+		}
+
+		if(right) {
+			*right = (left ? *left : 0) + transfoptions.output_width;
+		}
+		if(bottom) {
+			*bottom = (top ? *top : 0) + transfoptions.output_height;
+		}
+
+		// if only the crop rect is requested, we are done
+
+		if(onlyReturnCropRect) {
+			jpeg_destroy_compress(&dstinfo);
+			jpeg_destroy_decompress(&srcinfo);
+			return TRUE;
+		}
+
 		// Read source file as DCT coefficients
 		src_coef_arrays = jpeg_read_coefficients(&srcinfo);
-		
+
 		// Initialize destination compression parameters from source values
 		jpeg_copy_critical_parameters(&srcinfo, &dstinfo);
 
 		// Adjust destination parameters if required by transform options;
 		// also find out which set of coefficient arrays will hold the output
 		dst_coef_arrays = jtransform_adjust_parameters(&srcinfo, &dstinfo, src_coef_arrays, &transfoptions);
-		
-		// Close the input file.
+
 		// Note: we assume that jpeg_read_coefficients consumed all input
 		// until JPEG_REACHED_EOI, and that jpeg_finish_decompress will
 		// only consume more while (! cinfo->inputctl->eoi_reached).
 		// We cannot call jpeg_finish_decompress here since we still need the
 		// virtual arrays allocated from the source object for processing.
-		fclose(fp);
 
-		// Open the output file
-		if(bUseUnicode) {
-#ifdef _WIN32
-			if((fp = _wfopen(filenameIO->wdst_file, L"wb")) == NULL) {
-				FreeImage_OutputMessageProc(FIF_JPEG, "Cannot open output file for writing");
-			}
-#else
-			fp = NULL;
-#endif // _WIN32
-		} else {
-			if((fp = fopen(filenameIO->dst_file, "wb")) == NULL) {
-				FreeImage_OutputMessageProc(FIF_JPEG, "Cannot open %s for writing", filenameIO->dst_file);
-			}
+		if(src_handle == dst_handle) {
+			dst_io->seek_proc(dst_handle, stream_start, SEEK_SET);
 		}
-		if(fp == NULL) {
-			throw(1);
-		}
-		
+
 		// Specify data destination for compression
-		jpeg_stdio_dest(&dstinfo, fp);
-		
+		jpeg_freeimage_dst(&dstinfo, dst_handle, dst_io);
+
 		// Start compressor (note no image data is actually written here)
 		jpeg_write_coefficients(&dstinfo, dst_coef_arrays);
-		
+
 		// Copy to the output file any extra markers that we want to preserve
 		jcopy_markers_execute(&srcinfo, &dstinfo, copyoption);
-		
+
 		// Execute image transformation, if any
 		jtransform_execute_transformation(&srcinfo, &dstinfo, src_coef_arrays, &transfoptions);
-		
+
 		// Finish compression and release memory
 		jpeg_finish_compress(&dstinfo);
 		jpeg_destroy_compress(&dstinfo);
 		jpeg_finish_decompress(&srcinfo);
 		jpeg_destroy_decompress(&srcinfo);
-		
-		// Close output file and return
-		fclose(fp);
+
 	}
 	catch(...) {
-		if(fp) fclose(fp);
 		jpeg_destroy_compress(&dstinfo);
 		jpeg_destroy_decompress(&srcinfo);
 		return FALSE;
@@ -287,124 +366,258 @@ LosslessTransform(const FilenameIO *filenameIO, FREE_IMAGE_JPEG_OPERATION operat
 //   FreeImage interface
 // ----------------------------------------------------------
 
-BOOL DLL_CALLCONV 
-FreeImage_JPEGTransform(const char *src_file, const char *dst_file, FREE_IMAGE_JPEG_OPERATION operation, BOOL perfect) {
-	try {
-		// check the src file format
-		if(FreeImage_GetFileType(src_file) != FIF_JPEG) {
-			throw FI_MSG_ERROR_MAGIC_NUMBER;
-		}
+BOOL DLL_CALLCONV
+FreeImage_JPEGTransformFromHandle(FreeImageIO* src_io, fi_handle src_handle, FreeImageIO* dst_io, fi_handle dst_handle, FREE_IMAGE_JPEG_OPERATION operation, int* left, int* top, int* right, int* bottom, BOOL perfect) {
+	return JPEGTransformFromHandle(src_io, src_handle, dst_io, dst_handle, operation, left, top, right, bottom, perfect);
+}
 
-		// setup IO
-		FilenameIO filenameIO;
-		memset(&filenameIO, 0, sizeof(FilenameIO));
-		filenameIO.src_file = src_file;
-		filenameIO.dst_file = dst_file;
+static void
+closeStdIO(fi_handle src_handle, fi_handle dst_handle) {
+	if(src_handle) {
+		fclose((FILE*)src_handle);
+	}
+	if(dst_handle && (dst_handle != src_handle)) {
+		fclose((FILE*)dst_handle);
+	}
+}
 
-		// perform the transformation
-		return LosslessTransform(&filenameIO, operation, NULL, perfect);
+static BOOL
+openStdIO(const char* src_file, const char* dst_file, FreeImageIO* dst_io, fi_handle* src_handle, fi_handle* dst_handle) {
+	*src_handle = NULL;
+	*dst_handle = NULL;
+	
+	FreeImageIO io;
+	SetDefaultIO (&io);
+	
+	const BOOL isSameFile = (dst_file && (strcmp(src_file, dst_file) == 0)) ? TRUE : FALSE;
+	
+	FILE* srcp = NULL;
+	FILE* dstp = NULL;
+	
+	if(isSameFile) {
+		srcp = fopen(src_file, "r+b");
+		dstp = srcp;
+	}
+	else {
+		srcp = fopen(src_file, "rb");
+		if(dst_file) {
+			dstp = fopen(dst_file, "wb");
+		}
+	}
+	
+	if(!srcp || (dst_file && !dstp)) {
+		if(!srcp) {
+			FreeImage_OutputMessageProc(FIF_JPEG, "Cannot open \"%s\" for reading", src_file);
+		} else {
+			FreeImage_OutputMessageProc(FIF_JPEG, "Cannot open \"%s\" for writing", dst_file);
+		}
+		closeStdIO(srcp, dstp);
+		return FALSE;
+	}
 
-	} catch(const char *text) {
-		FreeImage_OutputMessageProc(FIF_JPEG, text);
+	if(FreeImage_GetFileTypeFromHandle(&io, srcp) != FIF_JPEG) {
+		FreeImage_OutputMessageProc(FIF_JPEG, " Source file \"%s\" is not jpeg", src_file);
+		closeStdIO(srcp, dstp);
 		return FALSE;
 	}
+
+	*dst_io = io;
+	*src_handle = srcp;
+	*dst_handle = dstp;
+
+	return TRUE;
 }
 
-BOOL DLL_CALLCONV 
-FreeImage_JPEGCrop(const char *src_file, const char *dst_file, int left, int top, int right, int bottom) {
-	char crop[64];
+static BOOL
+openStdIOU(const wchar_t* src_file, const wchar_t* dst_file, FreeImageIO* dst_io, fi_handle* src_handle, fi_handle* dst_handle) {
+#ifdef _WIN32
 
-	try {
-		// check the src file format
-		if(FreeImage_GetFileType(src_file) != FIF_JPEG) {
-			throw FI_MSG_ERROR_MAGIC_NUMBER;
-		}
-		
-		// normalize the rectangle
-		if(right < left) {
-			INPLACESWAP(left, right);
+	*src_handle = NULL;
+	*dst_handle = NULL;
+
+	FreeImageIO io;
+	SetDefaultIO (&io);
+	
+	const BOOL isSameFile = (dst_file && (wcscmp(src_file, dst_file) == 0)) ? TRUE : FALSE;
+
+	FILE* srcp = NULL;
+	FILE* dstp = NULL;
+
+	if(isSameFile) {
+		srcp = _wfopen(src_file, L"r+b");
+		dstp = srcp;
+	} else {
+		srcp = _wfopen(src_file, L"rb");
+		if(dst_file) {
+			dstp = _wfopen(dst_file, L"wb");
 		}
-		if(bottom < top) {
-			INPLACESWAP(top, bottom);
+	}
+
+	if(!srcp || (dst_file && !dstp)) {
+		if(!srcp) {
+			FreeImage_OutputMessageProc(FIF_JPEG, "Cannot open source file for reading");
+		} else {
+			FreeImage_OutputMessageProc(FIF_JPEG, "Cannot open destination file for writing");
 		}
+		closeStdIO(srcp, dstp);
+		return FALSE;
+	}
 
-		// build the crop option
-		sprintf(crop, "%dx%d+%d+%d", right - left, bottom - top, left, top);
+	if(FreeImage_GetFileTypeFromHandle(&io, srcp) != FIF_JPEG) {
+		FreeImage_OutputMessageProc(FIF_JPEG, " Source file is not jpeg");
+		closeStdIO(srcp, dstp);
+		return FALSE;
+	}
 
-		// setup IO
-		FilenameIO filenameIO;
-		memset(&filenameIO, 0, sizeof(FilenameIO));
-		filenameIO.src_file = src_file;
-		filenameIO.dst_file = dst_file;
+	*dst_io = io;
+	*src_handle = srcp;
+	*dst_handle = dstp;
 
-		// perform the transformation
-		return LosslessTransform(&filenameIO, FIJPEG_OP_NONE, crop, FALSE);
+	return TRUE;
 
-	} catch(const char *text) {
-		FreeImage_OutputMessageProc(FIF_JPEG, text);
+#else
+	return FALSE;
+#endif // _WIN32
+}
+
+BOOL DLL_CALLCONV
+FreeImage_JPEGTransform(const char *src_file, const char *dst_file, FREE_IMAGE_JPEG_OPERATION operation, BOOL perfect) {
+	FreeImageIO io;
+	fi_handle src;
+	fi_handle dst;
+	
+	if(!openStdIO(src_file, dst_file, &io, &src, &dst)) {
 		return FALSE;
 	}
+	
+	BOOL ret = JPEGTransformFromHandle(&io, src, &io, dst, operation, NULL, NULL, NULL, NULL, perfect);
+
+	closeStdIO(src, dst);
+
+	return ret;
+}
+
+BOOL DLL_CALLCONV
+FreeImage_JPEGCrop(const char *src_file, const char *dst_file, int left, int top, int right, int bottom) {
+	FreeImageIO io;
+	fi_handle src;
+	fi_handle dst;
+	
+	if(!openStdIO(src_file, dst_file, &io, &src, &dst)) {
+		return FALSE;
+	}
+	
+	BOOL ret = FreeImage_JPEGTransformFromHandle(&io, src, &io, dst, FIJPEG_OP_NONE, &left, &top, &right, &bottom, FALSE);
+	
+	closeStdIO(src, dst);
+	
+	return ret;
 }
 
-BOOL DLL_CALLCONV 
+BOOL DLL_CALLCONV
 FreeImage_JPEGTransformU(const wchar_t *src_file, const wchar_t *dst_file, FREE_IMAGE_JPEG_OPERATION operation, BOOL perfect) {
-#ifdef _WIN32
-	try {
-		// check the src file format
-		if(FreeImage_GetFileTypeU(src_file) != FIF_JPEG) {
-			throw FI_MSG_ERROR_MAGIC_NUMBER;
-		}
+	FreeImageIO io;
+	fi_handle src;
+	fi_handle dst;
+	
+	if(!openStdIOU(src_file, dst_file, &io, &src, &dst)) {
+		return FALSE;
+	}
+	
+	BOOL ret = JPEGTransformFromHandle(&io, src, &io, dst, operation, NULL, NULL, NULL, NULL, perfect);
+	
+	closeStdIO(src, dst);
 
-		// setup IO
-		FilenameIO filenameIO;
-		memset(&filenameIO, 0, sizeof(FilenameIO));
-		filenameIO.wsrc_file = src_file;
-		filenameIO.wdst_file = dst_file;
+	return ret;
+}
 
-		// perform the transformation
-		return LosslessTransform(&filenameIO, operation, NULL, perfect);
+BOOL DLL_CALLCONV
+FreeImage_JPEGCropU(const wchar_t *src_file, const wchar_t *dst_file, int left, int top, int right, int bottom) {
+	FreeImageIO io;
+	fi_handle src;
+	fi_handle dst;
+	
+	if(!openStdIOU(src_file, dst_file, &io, &src, &dst)) {
+		return FALSE;
+	}
+	
+	BOOL ret = FreeImage_JPEGTransformFromHandle(&io, src, &io, dst, FIJPEG_OP_NONE, &left, &top, &right, &bottom, FALSE);
+
+	closeStdIO(src, dst);
+
+	return ret;
+}
 
-	} catch(const char *text) {
-		FreeImage_OutputMessageProc(FIF_JPEG, text);
+BOOL DLL_CALLCONV
+FreeImage_JPEGTransformCombined(const char *src_file, const char *dst_file, FREE_IMAGE_JPEG_OPERATION operation, int* left, int* top, int* right, int* bottom, BOOL perfect) {
+	FreeImageIO io;
+	fi_handle src;
+	fi_handle dst;
+	
+	if(!openStdIO(src_file, dst_file, &io, &src, &dst)) {
+		return FALSE;
 	}
-#endif /// _WIN32
-	return FALSE;
+	
+	BOOL ret = FreeImage_JPEGTransformFromHandle(&io, src, &io, dst, operation, left, top, right, bottom, perfect);
+
+	closeStdIO(src, dst);
+
+	return ret;
 }
 
-BOOL DLL_CALLCONV 
-FreeImage_JPEGCropU(const wchar_t *src_file, const wchar_t *dst_file, int left, int top, int right, int bottom) {
-#ifdef _WIN32
-	char crop[64];
+BOOL DLL_CALLCONV
+FreeImage_JPEGTransformCombinedU(const wchar_t *src_file, const wchar_t *dst_file, FREE_IMAGE_JPEG_OPERATION operation, int* left, int* top, int* right, int* bottom, BOOL perfect) {
+	FreeImageIO io;
+	fi_handle src;
+	fi_handle dst;
+	
+	if(!openStdIOU(src_file, dst_file, &io, &src, &dst)) {
+		return FALSE;
+	}
+	
+	BOOL ret = FreeImage_JPEGTransformFromHandle(&io, src, &io, dst, operation, left, top, right, bottom, perfect);
 
-	try {
-		// check the src file format
-		if(FreeImage_GetFileTypeU(src_file) != FIF_JPEG) {
-			throw FI_MSG_ERROR_MAGIC_NUMBER;
-		}
-		
-		// normalize the rectangle
-		if(right < left) {
-			INPLACESWAP(left, right);
-		}
-		if(bottom < top) {
-			INPLACESWAP(top, bottom);
-		}
+	closeStdIO(src, dst);
+
+	return ret;
+}
+
+// --------------------------------------------------------------------------
+
+static BOOL
+getMemIO(FIMEMORY* src_stream, FIMEMORY* dst_stream, FreeImageIO* dst_io, fi_handle* src_handle, fi_handle* dst_handle) {
+	*src_handle = NULL;
+	*dst_handle = NULL;
 
-		// build the crop option
-		sprintf(crop, "%dx%d+%d+%d", right - left, bottom - top, left, top);
+	FreeImageIO io;
+	SetMemoryIO (&io);
 
-		// setup IO
-		FilenameIO filenameIO;
-		memset(&filenameIO, 0, sizeof(FilenameIO));
-		filenameIO.wsrc_file = src_file;
-		filenameIO.wdst_file = dst_file;
+	if(dst_stream) {
+		FIMEMORYHEADER *mem_header = (FIMEMORYHEADER*)(dst_stream->data);
+		if(mem_header->delete_me != TRUE) {
+			// do not save in a user buffer
+			FreeImage_OutputMessageProc(FIF_JPEG, "Destination memory buffer is read only");
+			return FALSE;
+		}
+	}
 
-		// perform the transformation
-		return LosslessTransform(&filenameIO, FIJPEG_OP_NONE, crop, FALSE);
+	*dst_io = io;
+	*src_handle = src_stream;
+	*dst_handle = dst_stream;
+
+	return TRUE;
+}
 
-	} catch(const char *text) {
-		FreeImage_OutputMessageProc(FIF_JPEG, text);
+BOOL DLL_CALLCONV
+FreeImage_JPEGTransformCombinedFromMemory(FIMEMORY* src_stream, FIMEMORY* dst_stream, FREE_IMAGE_JPEG_OPERATION operation, int* left, int* top, int* right, int* bottom, BOOL perfect) {
+	FreeImageIO io;
+	fi_handle src;
+	fi_handle dst;
+	
+	if(!getMemIO(src_stream, dst_stream, &io, &src, &dst)) {
+		return FALSE;
 	}
-#endif // _WIN32
-	return FALSE;
+	
+	return FreeImage_JPEGTransformFromHandle(&io, src, &io, dst, operation, left, top, right, bottom, perfect);
 }
+
diff --git a/Source/FreeImageToolkit/Rescale.cpp b/Source/FreeImageToolkit/Rescale.cpp
index ffe667e..4f885c2 100644
--- a/Source/FreeImageToolkit/Rescale.cpp
+++ b/Source/FreeImageToolkit/Rescale.cpp
@@ -1,169 +1,192 @@
-// ==========================================================
-// Upsampling / downsampling routine
-//
-// Design and implementation by
-// - Herv� Drolon (drolon at infonie.fr)
-// - Carsten Klein (cklein05 at users.sourceforge.net)
-//
-// This file is part of FreeImage 3
-//
-// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
-// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
-// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
-// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
-// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
-// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
-// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
-// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
-// THIS DISCLAIMER.
-//
-// Use at your own risk!
-// ==========================================================
-
-#include "Resize.h"
-
-FIBITMAP * DLL_CALLCONV 
-FreeImage_Rescale(FIBITMAP *src, int dst_width, int dst_height, FREE_IMAGE_FILTER filter) {
-	FIBITMAP *dst = NULL;
-
-	if (!FreeImage_HasPixels(src) || (dst_width <= 0) || (dst_height <= 0) || (FreeImage_GetWidth(src) <= 0) || (FreeImage_GetHeight(src) <= 0)) {
-		return NULL;
-	}
-
-	// select the filter
-	CGenericFilter *pFilter = NULL;
-	switch (filter) {
-		case FILTER_BOX:
-			pFilter = new(std::nothrow) CBoxFilter();
-			break;
-		case FILTER_BICUBIC:
-			pFilter = new(std::nothrow) CBicubicFilter();
-			break;
-		case FILTER_BILINEAR:
-			pFilter = new(std::nothrow) CBilinearFilter();
-			break;
-		case FILTER_BSPLINE:
-			pFilter = new(std::nothrow) CBSplineFilter();
-			break;
-		case FILTER_CATMULLROM:
-			pFilter = new(std::nothrow) CCatmullRomFilter();
-			break;
-		case FILTER_LANCZOS3:
-			pFilter = new(std::nothrow) CLanczos3Filter();
-			break;
-	}
-
-	if (!pFilter) {
-		return NULL;
-	}
-
-	CResizeEngine Engine(pFilter);
-
-	dst = Engine.scale(src, dst_width, dst_height, 0, 0,
-			FreeImage_GetWidth(src), FreeImage_GetHeight(src));
-
-	delete pFilter;
-
-	// copy metadata from src to dst
-	FreeImage_CloneMetadata(dst, src);
-	
-	return dst;
-}
-
-FIBITMAP * DLL_CALLCONV
-FreeImage_MakeThumbnail(FIBITMAP *dib, int max_pixel_size, BOOL convert) {
-	FIBITMAP *thumbnail = NULL;
-	int new_width, new_height;
-
-	if(!FreeImage_HasPixels(dib) || (max_pixel_size <= 0)) return NULL;
-
-	int width	= FreeImage_GetWidth(dib);
-	int height = FreeImage_GetHeight(dib);
-
-	if(max_pixel_size == 0) max_pixel_size = 1;
-
-	if((width < max_pixel_size) && (height < max_pixel_size)) {
-		// image is smaller than the requested thumbnail
-		return FreeImage_Clone(dib);
-	}
-
-	if(width > height) {
-		new_width = max_pixel_size;
-		// change image height with the same ratio
-		double ratio = ((double)new_width / (double)width);
-		new_height = (int)(height * ratio + 0.5);
-		if(new_height == 0) new_height = 1;
-	} else {
-		new_height = max_pixel_size;
-		// change image width with the same ratio
-		double ratio = ((double)new_height / (double)height);
-		new_width = (int)(width * ratio + 0.5);
-		if(new_width == 0) new_width = 1;
-	}
-
-	const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
-
-	// perform downsampling using a bilinear interpolation
-
-	switch(image_type) {
-		case FIT_BITMAP:
-		case FIT_UINT16:
-		case FIT_RGB16:
-		case FIT_RGBA16:
-		case FIT_FLOAT:
-		case FIT_RGBF:
-		case FIT_RGBAF:
-		{
-			FREE_IMAGE_FILTER filter = FILTER_BILINEAR;
-			thumbnail = FreeImage_Rescale(dib, new_width, new_height, filter);
-		}
-		break;
-
-		case FIT_INT16:
-		case FIT_UINT32:
-		case FIT_INT32:
-		case FIT_DOUBLE:
-		case FIT_COMPLEX:
-		default:
-			// cannot rescale this kind of image
-			thumbnail = NULL;
-			break;
-	}
-
-	if((thumbnail != NULL) && (image_type != FIT_BITMAP) && convert) {
-		// convert to a standard bitmap
-		FIBITMAP *bitmap = NULL;
-		switch(image_type) {
-			case FIT_UINT16:
-				bitmap = FreeImage_ConvertTo8Bits(thumbnail);
-				break;
-			case FIT_RGB16:
-				bitmap = FreeImage_ConvertTo24Bits(thumbnail);
-				break;
-			case FIT_RGBA16:
-				bitmap = FreeImage_ConvertTo32Bits(thumbnail);
-				break;
-			case FIT_FLOAT:
-				bitmap = FreeImage_ConvertToStandardType(thumbnail, TRUE);
-				break;
-			case FIT_RGBF:
-				bitmap = FreeImage_ToneMapping(thumbnail, FITMO_DRAGO03);
-				break;
-			case FIT_RGBAF:
-				// no way to keep the transparency yet ...
-				FIBITMAP *rgbf = FreeImage_ConvertToRGBF(thumbnail);
-				bitmap = FreeImage_ToneMapping(rgbf, FITMO_DRAGO03);
-				FreeImage_Unload(rgbf);
-				break;
-		}
-		if(bitmap != NULL) {
-			FreeImage_Unload(thumbnail);
-			thumbnail = bitmap;
-		}
-	}
-
-	// copy metadata from src to dst
-	FreeImage_CloneMetadata(thumbnail, dib);
-	
-	return thumbnail;
-}
+// ==========================================================
+// Upsampling / downsampling routine
+//
+// Design and implementation by
+// - Herv� Drolon (drolon at infonie.fr)
+// - Carsten Klein (cklein05 at users.sourceforge.net)
+//
+// This file is part of FreeImage 3
+//
+// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
+// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
+// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
+// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
+// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
+// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
+// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+// THIS DISCLAIMER.
+//
+// Use at your own risk!
+// ==========================================================
+
+#include "Resize.h"
+
+FIBITMAP * DLL_CALLCONV
+FreeImage_RescaleRect(FIBITMAP *src, int dst_width, int dst_height, int src_left, int src_top, int src_right, int src_bottom, FREE_IMAGE_FILTER filter, unsigned flags) {
+	FIBITMAP *dst = NULL;
+
+	const int src_width = FreeImage_GetWidth(src);
+	const int src_height = FreeImage_GetHeight(src);
+
+	if (!FreeImage_HasPixels(src) || (dst_width <= 0) || (dst_height <= 0) || (src_width <= 0) || (src_height <= 0)) {
+		return NULL;
+	}
+
+	// normalize the rectangle
+	if (src_right < src_left) {
+		INPLACESWAP(src_left, src_right);
+	}
+	if (src_bottom < src_top) {
+		INPLACESWAP(src_top, src_bottom);
+	}
+
+	// check the size of the sub image
+	if((src_left < 0) || (src_right > src_width) || (src_top < 0) || (src_bottom > src_height)) {
+		return NULL;
+	}
+
+	// select the filter
+	CGenericFilter *pFilter = NULL;
+	switch (filter) {
+		case FILTER_BOX:
+			pFilter = new(std::nothrow) CBoxFilter();
+			break;
+		case FILTER_BICUBIC:
+			pFilter = new(std::nothrow) CBicubicFilter();
+			break;
+		case FILTER_BILINEAR:
+			pFilter = new(std::nothrow) CBilinearFilter();
+			break;
+		case FILTER_BSPLINE:
+			pFilter = new(std::nothrow) CBSplineFilter();
+			break;
+		case FILTER_CATMULLROM:
+			pFilter = new(std::nothrow) CCatmullRomFilter();
+			break;
+		case FILTER_LANCZOS3:
+			pFilter = new(std::nothrow) CLanczos3Filter();
+			break;
+	}
+
+	if (!pFilter) {
+		return NULL;
+	}
+
+	CResizeEngine Engine(pFilter);
+
+	dst = Engine.scale(src, dst_width, dst_height, src_left, src_top,
+			src_right - src_left, src_bottom - src_top, flags);
+
+	delete pFilter;
+
+	if ((flags & FI_RESCALE_OMIT_METADATA) != FI_RESCALE_OMIT_METADATA) {
+		// copy metadata from src to dst
+		FreeImage_CloneMetadata(dst, src);
+	}
+
+	return dst;
+}
+
+FIBITMAP * DLL_CALLCONV
+FreeImage_Rescale(FIBITMAP *src, int dst_width, int dst_height, FREE_IMAGE_FILTER filter) {
+	return FreeImage_RescaleRect(src, dst_width, dst_height, 0, 0, FreeImage_GetWidth(src), FreeImage_GetHeight(src), filter, FI_RESCALE_DEFAULT);
+}
+
+FIBITMAP * DLL_CALLCONV
+FreeImage_MakeThumbnail(FIBITMAP *dib, int max_pixel_size, BOOL convert) {
+	FIBITMAP *thumbnail = NULL;
+	int new_width, new_height;
+
+	if(!FreeImage_HasPixels(dib) || (max_pixel_size <= 0)) return NULL;
+
+	int width	= FreeImage_GetWidth(dib);
+	int height = FreeImage_GetHeight(dib);
+
+	if(max_pixel_size == 0) max_pixel_size = 1;
+
+	if((width < max_pixel_size) && (height < max_pixel_size)) {
+		// image is smaller than the requested thumbnail
+		return FreeImage_Clone(dib);
+	}
+
+	if(width > height) {
+		new_width = max_pixel_size;
+		// change image height with the same ratio
+		double ratio = ((double)new_width / (double)width);
+		new_height = (int)(height * ratio + 0.5);
+		if(new_height == 0) new_height = 1;
+	} else {
+		new_height = max_pixel_size;
+		// change image width with the same ratio
+		double ratio = ((double)new_height / (double)height);
+		new_width = (int)(width * ratio + 0.5);
+		if(new_width == 0) new_width = 1;
+	}
+
+	const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
+
+	// perform downsampling using a bilinear interpolation
+
+	switch(image_type) {
+		case FIT_BITMAP:
+		case FIT_UINT16:
+		case FIT_RGB16:
+		case FIT_RGBA16:
+		case FIT_FLOAT:
+		case FIT_RGBF:
+		case FIT_RGBAF:
+		{
+			FREE_IMAGE_FILTER filter = FILTER_BILINEAR;
+			thumbnail = FreeImage_Rescale(dib, new_width, new_height, filter);
+		}
+		break;
+
+		case FIT_INT16:
+		case FIT_UINT32:
+		case FIT_INT32:
+		case FIT_DOUBLE:
+		case FIT_COMPLEX:
+		default:
+			// cannot rescale this kind of image
+			thumbnail = NULL;
+			break;
+	}
+
+	if((thumbnail != NULL) && (image_type != FIT_BITMAP) && convert) {
+		// convert to a standard bitmap
+		FIBITMAP *bitmap = NULL;
+		switch(image_type) {
+			case FIT_UINT16:
+				bitmap = FreeImage_ConvertTo8Bits(thumbnail);
+				break;
+			case FIT_RGB16:
+				bitmap = FreeImage_ConvertTo24Bits(thumbnail);
+				break;
+			case FIT_RGBA16:
+				bitmap = FreeImage_ConvertTo32Bits(thumbnail);
+				break;
+			case FIT_FLOAT:
+				bitmap = FreeImage_ConvertToStandardType(thumbnail, TRUE);
+				break;
+			case FIT_RGBF:
+				bitmap = FreeImage_ToneMapping(thumbnail, FITMO_DRAGO03);
+				break;
+			case FIT_RGBAF:
+				// no way to keep the transparency yet ...
+				FIBITMAP *rgbf = FreeImage_ConvertToRGBF(thumbnail);
+				bitmap = FreeImage_ToneMapping(rgbf, FITMO_DRAGO03);
+				FreeImage_Unload(rgbf);
+				break;
+		}
+		if(bitmap != NULL) {
+			FreeImage_Unload(thumbnail);
+			thumbnail = bitmap;
+		}
+	}
+
+	// copy metadata from src to dst
+	FreeImage_CloneMetadata(thumbnail, dib);
+
+	return thumbnail;
+}
diff --git a/Source/FreeImageToolkit/Resize.cpp b/Source/FreeImageToolkit/Resize.cpp
index f342bb7..dbc738f 100644
--- a/Source/FreeImageToolkit/Resize.cpp
+++ b/Source/FreeImageToolkit/Resize.cpp
@@ -1,1992 +1,2116 @@
-// ==========================================================
-// Upsampling / downsampling classes
-//
-// Design and implementation by
-// - Herv� Drolon (drolon at infonie.fr)
-// - Detlev Vendt (detlev.vendt at brillit.de)
-// - Carsten Klein (cklein05 at users.sourceforge.net)
-//
-// This file is part of FreeImage 3
-//
-// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
-// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
-// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
-// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
-// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
-// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
-// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
-// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
-// THIS DISCLAIMER.
-//
-// Use at your own risk!
-// ==========================================================
-
-#include "Resize.h"
-
-/**
-Returns the color type of a bitmap. In contrast to FreeImage_GetColorType,
-this function optionally supports a boolean OUT parameter, that receives TRUE,
-if the specified bitmap is greyscale, that is, it consists of grey colors only.
-Although it returns the same value as returned by FreeImage_GetColorType for all
-image types, this extended function primarily is intended for palletized images,
-since the boolean pointed to by 'bIsGreyscale' remains unchanged for RGB(A/F)
-images. However, the outgoing boolean is properly maintained for palletized images,
-as well as for any non-RGB image type, like FIT_UINTxx and FIT_DOUBLE, for example.
- at param dib A pointer to a FreeImage bitmap to calculate the extended color type for
- at param bIsGreyscale A pointer to a boolean, that receives TRUE, if the specified bitmap
-is greyscale, that is, it consists of grey colors only. This parameter can be NULL.
- at return the color type of the specified bitmap
-*/
-static FREE_IMAGE_COLOR_TYPE
-GetExtendedColorType(FIBITMAP *dib, BOOL *bIsGreyscale) {
-	const unsigned bpp = FreeImage_GetBPP(dib);
-	const unsigned size = CalculateUsedPaletteEntries(bpp);
-	const RGBQUAD * const pal = FreeImage_GetPalette(dib);
-	FREE_IMAGE_COLOR_TYPE color_type = FIC_MINISBLACK;
-	BOOL bIsGrey = TRUE;
-
-	switch (bpp) {
-		case 1:
-		{
-			for (unsigned i = 0; i < size; i++) {
-				if ((pal[i].rgbRed != pal[i].rgbGreen) || (pal[i].rgbRed != pal[i].rgbBlue)) {
-					color_type = FIC_PALETTE;
-					bIsGrey = FALSE;
-					break;
-				}
-			}
-			if (bIsGrey) {
-				if (pal[0].rgbBlue == 255 && pal[1].rgbBlue == 0) {
-					color_type = FIC_MINISWHITE;
-				} else if (pal[0].rgbBlue != 0 || pal[1].rgbBlue != 255) {
-					color_type = FIC_PALETTE;
-				}
-			}
-			break;
-		}
-
-		case 4:
-		case 8:
-		{
-			for (unsigned i = 0; i < size; i++) {
-				if ((pal[i].rgbRed != pal[i].rgbGreen) || (pal[i].rgbRed != pal[i].rgbBlue)) {
-					color_type = FIC_PALETTE;
-					bIsGrey = FALSE;
-					break;
-				}
-				if (color_type != FIC_PALETTE && pal[i].rgbBlue != i) {
-					if ((size - i - 1) != pal[i].rgbBlue) {
-						color_type = FIC_PALETTE;
-						if (!bIsGreyscale) {
-							// exit loop if we're not setting
-							// bIsGreyscale parameter
-							break;
-						}
-					} else {
-						color_type = FIC_MINISWHITE;
-					}
-				}
-			}
-			break;
-		}
-
-		default:
-		{
-			color_type = FreeImage_GetColorType(dib);
-			bIsGrey = (color_type == FIC_MINISBLACK) ? TRUE : FALSE;
-			break;
-		}
-
-	}
-	if (bIsGreyscale) {
-		*bIsGreyscale = bIsGrey;
-	}
-
-	return color_type;
-}
-
-/**
-Returns a pointer to an RGBA palette, created from the specified bitmap.
-The RGBA palette is a copy of the specified bitmap's palette, that, additionally
-contains the bitmap's transparency information in the rgbReserved member
-of the palette's RGBQUAD elements.
- at param dib A pointer to a FreeImage bitmap to create the RGBA palette from.
- at param buffer A pointer to the buffer to store the RGBA palette.
- at return A pointer to the newly created RGBA palette or NULL, if the specified
-bitmap is no palletized standard bitmap. If non-NULL, the returned value is
-actually the pointer passed in parameter 'buffer'.
-*/
-static inline RGBQUAD *
-GetRGBAPalette(FIBITMAP *dib, RGBQUAD * const buffer) {
-	// clone the palette
-	const unsigned ncolors = FreeImage_GetColorsUsed(dib);
-	if (ncolors == 0) {
-		return NULL;
-	}
-	memcpy(buffer, FreeImage_GetPalette(dib), ncolors * sizeof(RGBQUAD));
-	// merge the transparency table
-	const unsigned ntransp = MIN(ncolors, FreeImage_GetTransparencyCount(dib));
-	const BYTE * const tt = FreeImage_GetTransparencyTable(dib);
-	for (unsigned i = 0; i < ntransp; i++) {
-		buffer[i].rgbReserved = tt[i];
-	}
-	for (unsigned i = ntransp; i < ncolors; i++) {
-		buffer[i].rgbReserved = 255;
-	}
-	return buffer;
-}
-
-// --------------------------------------------------------------------------
-
-CWeightsTable::CWeightsTable(CGenericFilter *pFilter, unsigned uDstSize, unsigned uSrcSize) {
-	unsigned u;
-	double dWidth;
-	double dFScale = 1.0;
-	const double dFilterWidth = pFilter->GetWidth();
-
-	// scale factor
-	const double dScale = double(uDstSize) / double(uSrcSize);
-
-	if(dScale < 1.0) {
-		// minification
-		dWidth = dFilterWidth / dScale; 
-		dFScale = dScale; 
-	} else {
-		// magnification
-		dWidth= dFilterWidth; 
-	}
-
-	// allocate a new line contributions structure
-	//
-	// window size is the number of sampled pixels
-	m_WindowSize = 2 * (int)ceil(dWidth) + 1; 
-	m_LineLength = uDstSize; 
-	 // allocate list of contributions 
-	m_WeightTable = (Contribution*)malloc(m_LineLength * sizeof(Contribution));
-	for(u = 0 ; u < m_LineLength ; u++) {
-		// allocate contributions for every pixel
-		m_WeightTable[u].Weights = (double*)malloc(m_WindowSize * sizeof(double));
-	}
-
-	// offset for discrete to continuous coordinate conversion
-	const double dOffset = (0.5 / dScale) - 0.5;
-
-	for(u = 0; u < m_LineLength; u++) {
-		// scan through line of contributions
-		const double dCenter = (double)u / dScale + dOffset;   // reverse mapping
-		// find the significant edge points that affect the pixel
-		int iLeft = MAX (0, (int)floor (dCenter - dWidth)); 
-		int iRight = MIN ((int)ceil (dCenter + dWidth), int(uSrcSize) - 1); 
-
-		// cut edge points to fit in filter window in case of spill-off
-		if((iRight - iLeft + 1) > int(m_WindowSize)) {
-			if(iLeft < (int(uSrcSize) - 1 / 2)) {
-				iLeft++; 
-			} else {
-				iRight--; 
-			}
-		}
-
-		m_WeightTable[u].Left = iLeft; 
-		m_WeightTable[u].Right = iRight;
-
-		int iSrc = 0;
-		double dTotalWeight = 0;  // zero sum of weights
-		for(iSrc = iLeft; iSrc <= iRight; iSrc++) {
-			// calculate weights
-			const double weight = dFScale * pFilter->Filter(dFScale * (dCenter - (double)iSrc));
-			m_WeightTable[u].Weights[iSrc-iLeft] = weight;
-			dTotalWeight += weight;
-		}
-		if((dTotalWeight > 0) && (dTotalWeight != 1)) {
-			// normalize weight of neighbouring points
-			for(iSrc = iLeft; iSrc <= iRight; iSrc++) {
-				// normalize point
-				m_WeightTable[u].Weights[iSrc-iLeft] /= dTotalWeight; 
-			}
-			// simplify the filter, discarding null weights at the right
-			iSrc = iRight - iLeft;
-			while(m_WeightTable[u].Weights[iSrc] == 0) {
-				m_WeightTable[u].Right--;
-				iSrc--;
-				if(m_WeightTable[u].Right == m_WeightTable[u].Left) {
-					break;
-				}
-			}
-
-		}
-	}
-}
-
-CWeightsTable::~CWeightsTable() {
-	for(unsigned u = 0; u < m_LineLength; u++) {
-		// free contributions for every pixel
-		free(m_WeightTable[u].Weights);
-	}
-	// free list of pixels contributions
-	free(m_WeightTable);
-}
-
-// --------------------------------------------------------------------------
-
-FIBITMAP* CResizeEngine::scale(FIBITMAP *src, unsigned dst_width, unsigned dst_height, unsigned src_left, unsigned src_top, unsigned src_width, unsigned src_height) {
-
-	const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(src);
-	const unsigned src_bpp = FreeImage_GetBPP(src);
-
-	// determine the image's color type
-	BOOL bIsGreyscale = FALSE;
-	FREE_IMAGE_COLOR_TYPE color_type;
-	if (src_bpp <= 8) {
-		color_type = GetExtendedColorType(src, &bIsGreyscale);
-	} else {
-		color_type = FIC_RGB;
-	}
-
-	// determine the required bit depth of the destination image
-	unsigned dst_bpp;
-	if (color_type == FIC_PALETTE && !bIsGreyscale) {
-		// non greyscale FIC_PALETTE images require a high-color destination
-		// image (24- or 32-bits depending on the image's transparent state)
-		dst_bpp = FreeImage_IsTransparent(src) ? 32 : 24;
-	} else if (src_bpp <= 8) {
-		// greyscale images require an 8-bit destination image
-		// (or a 32-bit image if the image is transparent)
-		dst_bpp = FreeImage_IsTransparent(src) ? 32 : 8;
-	} else if (src_bpp == 16 && image_type == FIT_BITMAP) {
-		// 16-bit 555 and 565 RGB images require a high-color destination image
-		// (fixed to 24 bits, since 16-bit RGBs don't support transparency in FreeImage)
-		dst_bpp = 24;
-	} else {
-		// bit depth remains unchanged for all other images
-		dst_bpp = src_bpp;
-	}
-
-	// early exit if destination size is equal to source size
-	if ((src_width == dst_width) && (src_height == dst_height)) {
-		FIBITMAP *out = src;
-		FIBITMAP *tmp = src;
-		if ((src_width != FreeImage_GetWidth(src)) || (src_height != FreeImage_GetHeight(src))) {
-			out = FreeImage_Copy(tmp, src_left, src_top, src_left + src_width, src_top + src_height);
-			tmp = out;
-		}
-		if (src_bpp != dst_bpp) {
-			switch (dst_bpp) {
-				case 8:
-					out = FreeImage_ConvertToGreyscale(tmp);
-					if (tmp != src) {
-						FreeImage_Unload(tmp);
-					}
-					break;
-
-				case 24:
-					out = FreeImage_ConvertTo24Bits(tmp);
-					if (tmp != src) {
-						FreeImage_Unload(tmp);
-					}
-					break;
-
-				case 32:
-					out = FreeImage_ConvertTo32Bits(tmp);
-					if (tmp != src) {
-						FreeImage_Unload(tmp);
-					}
-					break;
-			}
-		}
-
-		return (out != src) ? out : FreeImage_Clone(src);
-	}
-
-	RGBQUAD pal_buffer[256];
-	RGBQUAD *src_pal = NULL;
-
-	// provide the source image's palette to the rescaler for
-	// FIC_PALETTE type images (this includes palletized greyscale
-	// images with an unordered palette)
-	if (color_type == FIC_PALETTE) {
-		if (dst_bpp == 32) {
-			// a 32 bit destination image signals transparency, so
-			// create an RGBA palette from the source palette
-			src_pal = GetRGBAPalette(src, pal_buffer);
-		} else {
-			src_pal = FreeImage_GetPalette(src);
-		}
-	}
-
-	// allocate the dst image
-	FIBITMAP *dst = FreeImage_AllocateT(image_type, dst_width, dst_height, dst_bpp, 0, 0, 0);
-	if (!dst) {
-		return NULL;
-	}
-	
-	if (dst_bpp == 8) {
-		RGBQUAD * const dst_pal = FreeImage_GetPalette(dst);
-		if (color_type == FIC_MINISWHITE) {
-			// build an inverted greyscale palette
-			CREATE_GREYSCALE_PALETTE_REVERSE(dst_pal, 256);
-		} 
-		/*
-		else {
-			// build a default greyscale palette
-			// Currently, FreeImage_AllocateT already creates a default
-			// greyscale palette for 8 bpp images, so we can skip this here.
-			CREATE_GREYSCALE_PALETTE(dst_pal, 256);
-		}
-		*/
-	}
-
-	// calculate x and y offsets; since FreeImage uses bottom-up bitmaps, the
-	// value of src_offset_y is measured from the bottom of the image
-	unsigned src_offset_x = src_left;
-	unsigned src_offset_y;
-	if (src_top > 0) {
-		src_offset_y = FreeImage_GetHeight(src) - src_height - src_top;
-	} else {
-		src_offset_y = 0;
-	}
-
-	/*
-	Decide which filtering order (xy or yx) is faster for this mapping. 
-	--- The theory ---
-	Try to minimize calculations by counting the number of convolution multiplies
-	if(dst_width*src_height <= src_width*dst_height) {
-		// xy filtering
-	} else {
-		// yx filtering
-	}
-	--- The practice ---
-	Try to minimize calculations by counting the number of vertical convolutions (the most time consuming task)
-	if(dst_width*dst_height <= src_width*dst_height) {
-		// xy filtering
-	} else {
-		// yx filtering
-	}
-	*/
-
-	if (dst_width <= src_width) {
-		// xy filtering
-		// -------------
-
-		FIBITMAP *tmp = NULL;
-
-		if (src_width != dst_width) {
-			// source and destination widths are different so, we must
-			// filter horizontally
-			if (src_height != dst_height) {
-				// source and destination heights are also different so, we need
-				// a temporary image
-				tmp = FreeImage_AllocateT(image_type, dst_width, src_height, dst_bpp, 0, 0, 0);
-				if (!tmp) {
-					FreeImage_Unload(dst);
-					return NULL;
-				}
-			} else {
-				// source and destination heights are equal so, we can directly
-				// scale into destination image (second filter method will not
-				// be invoked)
-				tmp = dst;
-			}
-
-			// scale source image horizontally into temporary (or destination) image
-			horizontalFilter(src, src_height, src_width, src_offset_x, src_offset_y, src_pal, tmp, dst_width);
-
-			// set x and y offsets to zero for the second filter method
-			// invocation (the temporary image only contains the portion of
-			// the image to be rescaled with no offsets)
-			src_offset_x = 0;
-			src_offset_y = 0;
-
-			// also ensure, that the second filter method gets no source
-			// palette (the temporary image is palletized only, if it is
-			// greyscale; in that case, it is an 8-bit image with a linear
-			// palette so, the source palette is not needed or will even be
-			// mismatching, if the source palette is unordered)
-			src_pal = NULL;
-		} else {
-			// source and destination widths are equal so, just copy the
-			// image pointer
-			tmp = src;
-		}
-
-		if (src_height != dst_height) {
-			// source and destination heights are different so, scale
-			// temporary (or source) image vertically into destination image
-			verticalFilter(tmp, dst_width, src_height, src_offset_x, src_offset_y, src_pal, dst, dst_height);
-		}
-
-		// free temporary image, if not pointing to either src or dst
-		if (tmp != src && tmp != dst) {
-			FreeImage_Unload(tmp);
-		}
-
-	} else {
-		// yx filtering
-		// -------------
-
-		// Remark:
-		// The yx filtering branch could be more optimized by taking into,
-		// account that (src_width != dst_width) is always true, which
-		// follows from the above condition, which selects filtering order.
-		// Since (dst_width <= src_width) == TRUE selects xy filtering,
-		// both widths must be different when performing yx filtering.
-		// However, to make the code more robust, not depending on that
-		// condition and more symmetric to the xy filtering case, these
-		// (src_width != dst_width) conditions are still in place.
-
-		FIBITMAP *tmp = NULL;
-
-		if (src_height != dst_height) {
-			// source and destination heights are different so, we must
-			// filter vertically
-			if (src_width != dst_width) {
-				// source and destination widths are also different so, we need
-				// a temporary image
-				tmp = FreeImage_AllocateT(image_type, src_width, dst_height, dst_bpp, 0, 0, 0);
-				if (!tmp) {
-					FreeImage_Unload(dst);
-					return NULL;
-				}
-			} else {
-				// source and destination widths are equal so, we can directly
-				// scale into destination image (second filter method will not
-				// be invoked)
-				tmp = dst;
-			}
-
-			// scale source image vertically into temporary (or destination) image
-			verticalFilter(src, src_width, src_height, src_offset_x, src_offset_y, src_pal, tmp, dst_height);
-
-			// set x and y offsets to zero for the second filter method
-			// invocation (the temporary image only contains the portion of
-			// the image to be rescaled with no offsets)
-			src_offset_x = 0;
-			src_offset_y = 0;
-
-			// also ensure, that the second filter method gets no source
-			// palette (the temporary image is palletized only, if it is
-			// greyscale; in that case, it is an 8-bit image with a linear
-			// palette so, the source palette is not needed or will even be
-			// mismatching, if the source palette is unordered)
-			src_pal = NULL;
-
-		} else {
-			// source and destination heights are equal so, just copy the
-			// image pointer
-			tmp = src;
-		}
-
-		if (src_width != dst_width) {
-			// source and destination heights are different so, scale
-			// temporary (or source) image horizontally into destination image
-			horizontalFilter(tmp, dst_height, src_width, src_offset_x, src_offset_y, src_pal, dst, dst_width);
-		}
-
-		// free temporary image, if not pointing to either src or dst
-		if (tmp != src && tmp != dst) {
-			FreeImage_Unload(tmp);
-		}
-	}
-
-	return dst;
-} 
-
-void CResizeEngine::horizontalFilter(FIBITMAP *const src, unsigned height, unsigned src_width, unsigned src_offset_x, unsigned src_offset_y, const RGBQUAD *const src_pal, FIBITMAP *const dst, unsigned dst_width) {
-
-	// allocate and calculate the contributions
-	CWeightsTable weightsTable(m_pFilter, dst_width, src_width);
-
-	// step through rows
-	switch(FreeImage_GetImageType(src)) {
-		case FIT_BITMAP:
-		{
-			switch(FreeImage_GetBPP(src)) {
-				case 1:
-				{
-					switch(FreeImage_GetBPP(dst)) {
-						case 8:
-						{
-							// transparently convert the 1-bit non-transparent greyscale
-							// image to 8 bpp
-							src_offset_x >>= 3;
-							if (src_pal) {
-								// we have got a palette
-								for (unsigned y = 0; y < height; y++) {
-									// scale each row
-									const BYTE * const src_bits = FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x;
-									BYTE * const dst_bits = FreeImage_GetScanLine(dst, y);
-
-									for (unsigned x = 0; x < dst_width; x++) {
-										// loop through row
-										const unsigned iLeft = weightsTable.getLeftBoundary(x);		// retrieve left boundary
-										const unsigned iRight = weightsTable.getRightBoundary(x);	// retrieve right boundary
-										double value = 0;
-
-										for (unsigned i = iLeft; i <= iRight; i++) {
-											// scan between boundaries
-											// accumulate weighted effect of each neighboring pixel
-											const unsigned pixel = (src_bits[i >> 3] & (0x80 >> (i & 0x07))) != 0;
-											value += (weightsTable.getWeight(x, i - iLeft) * (double)*(BYTE *)&src_pal[pixel]);
-										}
-
-										// clamp and place result in destination pixel
-										dst_bits[x] = (BYTE)CLAMP<int>((int)(value + 0.5), 0, 0xFF);
-									}
-								}
-							} else {
-								// we do not have a palette
-								for (unsigned y = 0; y < height; y++) {
-									// scale each row
-									const BYTE * const src_bits = FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x;
-									BYTE * const dst_bits = FreeImage_GetScanLine(dst, y);
-
-									for (unsigned x = 0; x < dst_width; x++) {
-										// loop through row
-										const unsigned iLeft = weightsTable.getLeftBoundary(x);		// retrieve left boundary
-										const unsigned iRight = weightsTable.getRightBoundary(x);	// retrieve right boundary
-										double value = 0;
-
-										for (unsigned i = iLeft; i <= iRight; i++) {
-											// scan between boundaries
-											// accumulate weighted effect of each neighboring pixel
-											const unsigned pixel = (src_bits[i >> 3] & (0x80 >> (i & 0x07))) != 0;
-											value += (weightsTable.getWeight(x, i - iLeft) * (double)pixel);
-										}
-										value *= 0xFF;
-
-										// clamp and place result in destination pixel
-										dst_bits[x] = (BYTE)CLAMP<int>((int)(value + 0.5), 0, 0xFF);
-									}
-								}
-							}
-						}
-						break;
-
-						case 24:
-						{
-							// transparently convert the non-transparent 1-bit image
-							// to 24 bpp; we always have got a palette here
-							src_offset_x >>= 3;
-
-							for (unsigned y = 0; y < height; y++) {
-								// scale each row
-								const BYTE * const src_bits = FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x;
-								BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
-
-								for (unsigned x = 0; x < dst_width; x++) {
-									// loop through row
-									const unsigned iLeft = weightsTable.getLeftBoundary(x);    // retrieve left boundary
-									const unsigned iRight = weightsTable.getRightBoundary(x);  // retrieve right boundary
-									double r = 0, g = 0, b = 0;
-
-									for (unsigned i = iLeft; i <= iRight; i++) {
-										// scan between boundaries
-										// accumulate weighted effect of each neighboring pixel
-										const double weight = weightsTable.getWeight(x, i - iLeft);
-										const unsigned pixel = (src_bits[i >> 3] & (0x80 >> (i & 0x07))) != 0;
-										const BYTE * const entry = (BYTE *)&src_pal[pixel];
-										r += (weight * (double)entry[FI_RGBA_RED]);
-										g += (weight * (double)entry[FI_RGBA_GREEN]);
-										b += (weight * (double)entry[FI_RGBA_BLUE]);
-									}
-
-									// clamp and place result in destination pixel
-									dst_bits[FI_RGBA_RED]	= (BYTE)CLAMP<int>((int)(r + 0.5), 0, 0xFF);
-									dst_bits[FI_RGBA_GREEN]	= (BYTE)CLAMP<int>((int)(g + 0.5), 0, 0xFF);
-									dst_bits[FI_RGBA_BLUE]	= (BYTE)CLAMP<int>((int)(b + 0.5), 0, 0xFF);
-									dst_bits += 3;
-								}
-							}
-						}
-						break;
-
-						case 32:
-						{
-							// transparently convert the transparent 1-bit image
-							// to 32 bpp; we always have got a palette here
-							src_offset_x >>= 3;
-
-							for (unsigned y = 0; y < height; y++) {
-								// scale each row
-								const BYTE * const src_bits = FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x;
-								BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
-
-								for (unsigned x = 0; x < dst_width; x++) {
-									// loop through row
-									const unsigned iLeft = weightsTable.getLeftBoundary(x);    // retrieve left boundary
-									const unsigned iRight = weightsTable.getRightBoundary(x);  // retrieve right boundary
-									double r = 0, g = 0, b = 0, a = 0;
-
-									for (unsigned i = iLeft; i <= iRight; i++) {
-										// scan between boundaries
-										// accumulate weighted effect of each neighboring pixel
-										const double weight = weightsTable.getWeight(x, i - iLeft);
-										const unsigned pixel = (src_bits[i >> 3] & (0x80 >> (i & 0x07))) != 0;
-										const BYTE * const entry = (BYTE *)&src_pal[pixel];
-										r += (weight * (double)entry[FI_RGBA_RED]);
-										g += (weight * (double)entry[FI_RGBA_GREEN]);
-										b += (weight * (double)entry[FI_RGBA_BLUE]);
-										a += (weight * (double)entry[FI_RGBA_ALPHA]);
-									}
-
-									// clamp and place result in destination pixel
-									dst_bits[FI_RGBA_RED]	= (BYTE)CLAMP<int>((int)(r + 0.5), 0, 0xFF);
-									dst_bits[FI_RGBA_GREEN]	= (BYTE)CLAMP<int>((int)(g + 0.5), 0, 0xFF);
-									dst_bits[FI_RGBA_BLUE]	= (BYTE)CLAMP<int>((int)(b + 0.5), 0, 0xFF);
-									dst_bits[FI_RGBA_ALPHA]	= (BYTE)CLAMP<int>((int)(a + 0.5), 0, 0xFF);
-									dst_bits += 4;
-								}
-							}
-						}
-						break;
-					}
-				}
-				break;
-
-				case 4:
-				{
-					switch(FreeImage_GetBPP(dst)) {
-						case 8:
-						{
-							// transparently convert the non-transparent 4-bit greyscale image
-							// to 8 bpp; we always have got a palette for 4-bit images
-							src_offset_x >>= 1;
-
-							for (unsigned y = 0; y < height; y++) {
-								// scale each row
-								const BYTE * const src_bits = FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x;
-								BYTE * const dst_bits = FreeImage_GetScanLine(dst, y);
-
-								for (unsigned x = 0; x < dst_width; x++) {
-									// loop through row
-									const unsigned iLeft = weightsTable.getLeftBoundary(x);    // retrieve left boundary
-									const unsigned iRight = weightsTable.getRightBoundary(x);  // retrieve right boundary
-									double value = 0;
-
-									for (unsigned i = iLeft; i <= iRight; i++) {
-										// scan between boundaries
-										// accumulate weighted effect of each neighboring pixel
-										const unsigned pixel = i & 0x01 ? src_bits[i >> 1] & 0x0F : src_bits[i >> 1] >> 4;
-										value += (weightsTable.getWeight(x, i - iLeft)
-												* (double)*(BYTE *)&src_pal[pixel]);
-									}
-
-									// clamp and place result in destination pixel
-									dst_bits[x] = (BYTE)CLAMP<int>((int)(value + 0.5), 0, 0xFF);
-								}
-							}
-						}
-						break;
-
-						case 24:
-						{
-							// transparently convert the non-transparent 4-bit image
-							// to 24 bpp; we always have got a palette for 4-bit images
-							src_offset_x >>= 1;
-
-							for (unsigned y = 0; y < height; y++) {
-								// scale each row
-								const BYTE * const src_bits = FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x;
-								BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
-
-								for (unsigned x = 0; x < dst_width; x++) {
-									// loop through row
-									const unsigned iLeft = weightsTable.getLeftBoundary(x);    // retrieve left boundary
-									const unsigned iRight = weightsTable.getRightBoundary(x);  // retrieve right boundary
-									double r = 0, g = 0, b = 0;
-
-									for (unsigned i = iLeft; i <= iRight; i++) {
-										// scan between boundaries
-										// accumulate weighted effect of each neighboring pixel
-										const double weight = weightsTable.getWeight(x, i - iLeft);
-										const unsigned pixel = i & 0x01 ? src_bits[i >> 1] & 0x0F : src_bits[i >> 1] >> 4;
-										const BYTE * const entry = (BYTE *)&src_pal[pixel];
-										r += (weight * (double)entry[FI_RGBA_RED]);
-										g += (weight * (double)entry[FI_RGBA_GREEN]);
-										b += (weight * (double)entry[FI_RGBA_BLUE]);
-									}
-
-									// clamp and place result in destination pixel
-									dst_bits[FI_RGBA_RED]	= (BYTE)CLAMP<int>((int)(r + 0.5), 0, 0xFF);
-									dst_bits[FI_RGBA_GREEN]	= (BYTE)CLAMP<int>((int)(g + 0.5), 0, 0xFF);
-									dst_bits[FI_RGBA_BLUE]	= (BYTE)CLAMP<int>((int)(b + 0.5), 0, 0xFF);
-									dst_bits += 3;
-								}
-							}
-						}
-						break;
-
-						case 32:
-						{
-							// transparently convert the transparent 4-bit image
-							// to 32 bpp; we always have got a palette for 4-bit images
-							src_offset_x >>= 1;
-
-							for (unsigned y = 0; y < height; y++) {
-								// scale each row
-								const BYTE * const src_bits = FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x;
-								BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
-
-								for (unsigned x = 0; x < dst_width; x++) {
-									// loop through row
-									const unsigned iLeft = weightsTable.getLeftBoundary(x);    // retrieve left boundary
-									const unsigned iRight = weightsTable.getRightBoundary(x);  // retrieve right boundary
-									double r = 0, g = 0, b = 0, a = 0;
-
-									for (unsigned i = iLeft; i <= iRight; i++) {
-										// scan between boundaries
-										// accumulate weighted effect of each neighboring pixel
-										const double weight = weightsTable.getWeight(x, i - iLeft);
-										const unsigned pixel = i & 0x01 ? src_bits[i >> 1] & 0x0F : src_bits[i >> 1] >> 4;
-										const BYTE * const entry = (BYTE *)&src_pal[pixel];
-										r += (weight * (double)entry[FI_RGBA_RED]);
-										g += (weight * (double)entry[FI_RGBA_GREEN]);
-										b += (weight * (double)entry[FI_RGBA_BLUE]);
-										a += (weight * (double)entry[FI_RGBA_ALPHA]);
-									}
-
-									// clamp and place result in destination pixel
-									dst_bits[FI_RGBA_RED]	= (BYTE)CLAMP<int>((int)(r + 0.5), 0, 0xFF);
-									dst_bits[FI_RGBA_GREEN]	= (BYTE)CLAMP<int>((int)(g + 0.5), 0, 0xFF);
-									dst_bits[FI_RGBA_BLUE]	= (BYTE)CLAMP<int>((int)(b + 0.5), 0, 0xFF);
-									dst_bits[FI_RGBA_ALPHA]	= (BYTE)CLAMP<int>((int)(a + 0.5), 0, 0xFF);
-									dst_bits += 4;
-								}
-							}
-						}
-						break;
-					}
-				}
-				break;
-
-				case 8:
-				{
-					switch(FreeImage_GetBPP(dst)) {
-						case 8:
-						{
-							// scale the 8-bit non-transparent greyscale image
-							// into an 8 bpp destination image
-							if (src_pal) {
-								// we have got a palette
-								for (unsigned y = 0; y < height; y++) {
-									// scale each row
-									const BYTE * const src_bits = FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x;
-									BYTE * const dst_bits = FreeImage_GetScanLine(dst, y);
-
-									for (unsigned x = 0; x < dst_width; x++) {
-										// loop through row
-										const unsigned iLeft = weightsTable.getLeftBoundary(x);				// retrieve left boundary
-										const unsigned iLimit = weightsTable.getRightBoundary(x) - iLeft;	// retrieve right boundary
-										const BYTE * const pixel = src_bits + iLeft;
-										double value = 0;
-
-										// for(i = iLeft to iRight)
-										for (unsigned i = 0; i <= iLimit; i++) {
-											// scan between boundaries
-											// accumulate weighted effect of each neighboring pixel
-											value += (weightsTable.getWeight(x, i)
-													* (double)*(BYTE *)&src_pal[pixel[i]]);
-										}
-
-										// clamp and place result in destination pixel
-										dst_bits[x] = (BYTE)CLAMP<int>((int)(value + 0.5), 0, 0xFF);
-									}
-								}
-							} else {
-								// we do not have a palette
-								for (unsigned y = 0; y < height; y++) {
-									// scale each row
-									const BYTE * const src_bits = FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x;
-									BYTE * const dst_bits = FreeImage_GetScanLine(dst, y);
-
-									for (unsigned x = 0; x < dst_width; x++) {
-										// loop through row
-										const unsigned iLeft = weightsTable.getLeftBoundary(x);				// retrieve left boundary
-										const unsigned iLimit = weightsTable.getRightBoundary(x) - iLeft;	// retrieve right boundary
-										const BYTE * const pixel = src_bits + iLeft;
-										double value = 0;
-
-										// for(i = iLeft to iRight)
-										for (unsigned i = 0; i <= iLimit; i++) {
-											// scan between boundaries
-											// accumulate weighted effect of each neighboring pixel
-											value += (weightsTable.getWeight(x, i) * (double)pixel[i]);
-										}
-
-										// clamp and place result in destination pixel
-										dst_bits[x] = (BYTE)CLAMP<int>((int)(value + 0.5), 0, 0xFF);
-									}
-								}
-							}
-						}
-						break;
-
-						case 24:
-						{
-							// transparently convert the non-transparent 8-bit image
-							// to 24 bpp; we always have got a palette here
-							for (unsigned y = 0; y < height; y++) {
-								// scale each row
-								const BYTE * const src_bits = FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x;
-								BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
-
-								for (unsigned x = 0; x < dst_width; x++) {
-									// loop through row
-									const unsigned iLeft = weightsTable.getLeftBoundary(x);				// retrieve left boundary
-									const unsigned iLimit = weightsTable.getRightBoundary(x) - iLeft;	// retrieve right boundary
-									const BYTE * const pixel = src_bits + iLeft;
-									double r = 0, g = 0, b = 0;
-
-									// for(i = iLeft to iRight)
-									for (unsigned i = 0; i <= iLimit; i++) {
-										// scan between boundaries
-										// accumulate weighted effect of each neighboring pixel
-										const double weight = weightsTable.getWeight(x, i);
-										const BYTE *const entry = (BYTE *)&src_pal[pixel[i]];
-										r += (weight * (double)entry[FI_RGBA_RED]);
-										g += (weight * (double)entry[FI_RGBA_GREEN]);
-										b += (weight * (double)entry[FI_RGBA_BLUE]);
-									}
-
-									// clamp and place result in destination pixel
-									dst_bits[FI_RGBA_RED]	= (BYTE)CLAMP<int>((int)(r + 0.5), 0, 0xFF);
-									dst_bits[FI_RGBA_GREEN]	= (BYTE)CLAMP<int>((int)(g + 0.5), 0, 0xFF);
-									dst_bits[FI_RGBA_BLUE]	= (BYTE)CLAMP<int>((int)(b + 0.5), 0, 0xFF);
-									dst_bits += 3;
-								}
-							}
-						}
-						break;
-
-						case 32:
-						{
-							// transparently convert the transparent 8-bit image
-							// to 32 bpp; we always have got a palette here
-							for (unsigned y = 0; y < height; y++) {
-								// scale each row
-								const BYTE * const src_bits = FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x;
-								BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
-
-								for (unsigned x = 0; x < dst_width; x++) {
-									// loop through row
-									const unsigned iLeft = weightsTable.getLeftBoundary(x);				// retrieve left boundary
-									const unsigned iLimit = weightsTable.getRightBoundary(x) - iLeft;	// retrieve right boundary
-									const BYTE * const pixel = src_bits + iLeft;
-									double r = 0, g = 0, b = 0, a = 0;
-
-									// for(i = iLeft to iRight)
-									for (unsigned i = 0; i <= iLimit; i++) {
-										// scan between boundaries
-										// accumulate weighted effect of each neighboring pixel
-										const double weight = weightsTable.getWeight(x, i);
-										const BYTE * const entry = (BYTE *)&src_pal[pixel[i]];
-										r += (weight * (double)entry[FI_RGBA_RED]);
-										g += (weight * (double)entry[FI_RGBA_GREEN]);
-										b += (weight * (double)entry[FI_RGBA_BLUE]);
-										a += (weight * (double)entry[FI_RGBA_ALPHA]);
-									}
-
-									// clamp and place result in destination pixel
-									dst_bits[FI_RGBA_RED]	= (BYTE)CLAMP<int>((int)(r + 0.5), 0, 0xFF);
-									dst_bits[FI_RGBA_GREEN]	= (BYTE)CLAMP<int>((int)(g + 0.5), 0, 0xFF);
-									dst_bits[FI_RGBA_BLUE]	= (BYTE)CLAMP<int>((int)(b + 0.5), 0, 0xFF);
-									dst_bits[FI_RGBA_ALPHA]	= (BYTE)CLAMP<int>((int)(a + 0.5), 0, 0xFF);
-									dst_bits += 4;
-								}
-							}
-						}
-						break;
-					}
-				}
-				break;
-
-				case 16:
-				{
-					// transparently convert the 16-bit non-transparent image
-					// to 24 bpp
-					if (IS_FORMAT_RGB565(src)) {
-						// image has 565 format
-						for (unsigned y = 0; y < height; y++) {
-							// scale each row
-							const WORD * const src_bits = (WORD *)FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x / sizeof(WORD);
-							BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
-
-							for (unsigned x = 0; x < dst_width; x++) {
-								// loop through row
-								const unsigned iLeft = weightsTable.getLeftBoundary(x);				// retrieve left boundary
-								const unsigned iLimit = weightsTable.getRightBoundary(x) - iLeft;	// retrieve right boundary
-								const WORD *pixel = src_bits + iLeft;
-								double r = 0, g = 0, b = 0;
-
-								// for(i = iLeft to iRight)
-								for (unsigned i = 0; i <= iLimit; i++) {
-									// scan between boundaries
-									// accumulate weighted effect of each neighboring pixel
-									const double weight = weightsTable.getWeight(x, i);
-									r += (weight * (double)((*pixel & FI16_565_RED_MASK) >> FI16_565_RED_SHIFT));
-									g += (weight * (double)((*pixel & FI16_565_GREEN_MASK) >> FI16_565_GREEN_SHIFT));
-									b += (weight * (double)((*pixel & FI16_565_BLUE_MASK) >> FI16_565_BLUE_SHIFT));
-									pixel++;
-								}
-
-								// clamp and place result in destination pixel
-								dst_bits[FI_RGBA_RED]	= (BYTE)CLAMP<int>((int)(((r * 0xFF) / 0x1F) + 0.5), 0, 0xFF);
-								dst_bits[FI_RGBA_GREEN]	= (BYTE)CLAMP<int>((int)(((g * 0xFF) / 0x3F) + 0.5), 0, 0xFF);
-								dst_bits[FI_RGBA_BLUE]	= (BYTE)CLAMP<int>((int)(((b * 0xFF) / 0x1F) + 0.5), 0, 0xFF);
-								dst_bits += 3;
-							}
-						}
-					} else {
-						// image has 555 format
-						for (unsigned y = 0; y < height; y++) {
-							// scale each row
-							const WORD * const src_bits = (WORD *)FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x;
-							BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
-
-							for (unsigned x = 0; x < dst_width; x++) {
-								// loop through row
-								const unsigned iLeft = weightsTable.getLeftBoundary(x);				// retrieve left boundary
-								const unsigned iLimit = weightsTable.getRightBoundary(x) - iLeft;	// retrieve right boundary
-								const WORD *pixel = src_bits + iLeft;
-								double r = 0, g = 0, b = 0;
-
-								// for(i = iLeft to iRight)
-								for (unsigned i = 0; i <= iLimit; i++) {
-									// scan between boundaries
-									// accumulate weighted effect of each neighboring pixel
-									const double weight = weightsTable.getWeight(x, i);
-									r += (weight * (double)((*pixel & FI16_555_RED_MASK) >> FI16_555_RED_SHIFT));
-									g += (weight * (double)((*pixel & FI16_555_GREEN_MASK) >> FI16_555_GREEN_SHIFT));
-									b += (weight * (double)((*pixel & FI16_555_BLUE_MASK) >> FI16_555_BLUE_SHIFT));
-									pixel++;
-								}
-
-								// clamp and place result in destination pixel
-								dst_bits[FI_RGBA_RED]	= (BYTE)CLAMP<int>((int)(((r * 0xFF) / 0x1F) + 0.5), 0, 0xFF);
-								dst_bits[FI_RGBA_GREEN]	= (BYTE)CLAMP<int>((int)(((g * 0xFF) / 0x1F) + 0.5), 0, 0xFF);
-								dst_bits[FI_RGBA_BLUE]	= (BYTE)CLAMP<int>((int)(((b * 0xFF) / 0x1F) + 0.5), 0, 0xFF);
-								dst_bits += 3;
-							}
-						}
-					}
-				}
-				break;
-
-				case 24:
-				{
-					// scale the 24-bit non-transparent image
-					// into a 24 bpp destination image
-					for (unsigned y = 0; y < height; y++) {
-						// scale each row
-						const BYTE * const src_bits = FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x * 3;
-						BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
-
-						for (unsigned x = 0; x < dst_width; x++) {
-							// loop through row
-							const unsigned iLeft = weightsTable.getLeftBoundary(x);				// retrieve left boundary
-							const unsigned iLimit = weightsTable.getRightBoundary(x) - iLeft;	// retrieve right boundary
-							const BYTE * pixel = src_bits + iLeft * 3;
-							double r = 0, g = 0, b = 0;
-
-							// for(i = iLeft to iRight)
-							for (unsigned i = 0; i <= iLimit; i++) {
-								// scan between boundaries
-								// accumulate weighted effect of each neighboring pixel
-								const double weight = weightsTable.getWeight(x, i);
-								r += (weight * (double)pixel[FI_RGBA_RED]);
-								g += (weight * (double)pixel[FI_RGBA_GREEN]);
-								b += (weight * (double)pixel[FI_RGBA_BLUE]);
-								pixel += 3;
-							}
-
-							// clamp and place result in destination pixel
-							dst_bits[FI_RGBA_RED]	= (BYTE)CLAMP<int>((int)(r + 0.5), 0, 0xFF);
-							dst_bits[FI_RGBA_GREEN]	= (BYTE)CLAMP<int>((int)(g + 0.5), 0, 0xFF);
-							dst_bits[FI_RGBA_BLUE]	= (BYTE)CLAMP<int>((int)(b + 0.5), 0, 0xFF);
-							dst_bits += 3;
-						}
-					}
-				}
-				break;
-
-				case 32:
-				{
-					// scale the 32-bit transparent image
-					// into a 32 bpp destination image
-					for (unsigned y = 0; y < height; y++) {
-						// scale each row
-						const BYTE * const src_bits = FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x * 4;
-						BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
-
-						for (unsigned x = 0; x < dst_width; x++) {
-							// loop through row
-							const unsigned iLeft = weightsTable.getLeftBoundary(x);				// retrieve left boundary
-							const unsigned iLimit = weightsTable.getRightBoundary(x) - iLeft;	// retrieve right boundary
-							const BYTE *pixel = src_bits + iLeft * 4;
-							double r = 0, g = 0, b = 0, a = 0;
-
-							// for(i = iLeft to iRight)
-							for (unsigned i = 0; i <= iLimit; i++) {
-								// scan between boundaries
-								// accumulate weighted effect of each neighboring pixel
-								const double weight = weightsTable.getWeight(x, i);
-								r += (weight * (double)pixel[FI_RGBA_RED]);
-								g += (weight * (double)pixel[FI_RGBA_GREEN]);
-								b += (weight * (double)pixel[FI_RGBA_BLUE]);
-								a += (weight * (double)pixel[FI_RGBA_ALPHA]);
-								pixel += 4;
-							}
-
-							// clamp and place result in destination pixel
-							dst_bits[FI_RGBA_RED]	= (BYTE)CLAMP<int>((int)(r + 0.5), 0, 0xFF);
-							dst_bits[FI_RGBA_GREEN]	= (BYTE)CLAMP<int>((int)(g + 0.5), 0, 0xFF);
-							dst_bits[FI_RGBA_BLUE]	= (BYTE)CLAMP<int>((int)(b + 0.5), 0, 0xFF);
-							dst_bits[FI_RGBA_ALPHA]	= (BYTE)CLAMP<int>((int)(a + 0.5), 0, 0xFF);
-							dst_bits += 4;
-						}
-					}
-				}
-				break;
-			}
-		}
-		break;
-
-		case FIT_UINT16:
-		{
-			// Calculate the number of words per pixel (1 for 16-bit, 3 for 48-bit or 4 for 64-bit)
-			const unsigned wordspp = (FreeImage_GetLine(src) / src_width) / sizeof(WORD);
-
-			for (unsigned y = 0; y < height; y++) {
-				// scale each row
-				const WORD *src_bits = (WORD*)FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x / sizeof(WORD);
-				WORD *dst_bits = (WORD*)FreeImage_GetScanLine(dst, y);
-
-				for (unsigned x = 0; x < dst_width; x++) {
-					// loop through row
-					const unsigned iLeft = weightsTable.getLeftBoundary(x);				// retrieve left boundary
-					const unsigned iLimit = weightsTable.getRightBoundary(x) - iLeft;	// retrieve right boundary
-					const WORD *pixel = src_bits + iLeft * wordspp;
-					double value = 0;
-
-					// for(i = iLeft to iRight)
-					for (unsigned i = 0; i <= iLimit; i++) {
-						// scan between boundaries
-						// accumulate weighted effect of each neighboring pixel
-						const double weight = weightsTable.getWeight(x, i);						
-						value += (weight * (double)pixel[0]);
-						pixel++;
-					}
-
-					// clamp and place result in destination pixel
-					dst_bits[0] = (WORD)CLAMP<int>((int)(value + 0.5), 0, 0xFFFF);
-					dst_bits += wordspp;
-				}
-			}
-		}
-		break;
-
-		case FIT_RGB16:
-		{
-			// Calculate the number of words per pixel (1 for 16-bit, 3 for 48-bit or 4 for 64-bit)
-			const unsigned wordspp = (FreeImage_GetLine(src) / src_width) / sizeof(WORD);
-
-			for (unsigned y = 0; y < height; y++) {
-				// scale each row
-				const WORD *src_bits = (WORD*)FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x / sizeof(WORD);
-				WORD *dst_bits = (WORD*)FreeImage_GetScanLine(dst, y);
-
-				for (unsigned x = 0; x < dst_width; x++) {
-					// loop through row
-					const unsigned iLeft = weightsTable.getLeftBoundary(x);				// retrieve left boundary
-					const unsigned iLimit = weightsTable.getRightBoundary(x) - iLeft;	// retrieve right boundary
-					const WORD *pixel = src_bits + iLeft * wordspp;
-					double r = 0, g = 0, b = 0;
-
-					// for(i = iLeft to iRight)
-					for (unsigned i = 0; i <= iLimit; i++) {
-						// scan between boundaries
-						// accumulate weighted effect of each neighboring pixel
-						const double weight = weightsTable.getWeight(x, i);						
-						r += (weight * (double)pixel[0]);
-						g += (weight * (double)pixel[1]);
-						b += (weight * (double)pixel[2]);
-						pixel += wordspp;
-					}
-
-					// clamp and place result in destination pixel
-					dst_bits[0] = (WORD)CLAMP<int>((int)(r + 0.5), 0, 0xFFFF);
-					dst_bits[1] = (WORD)CLAMP<int>((int)(g + 0.5), 0, 0xFFFF);
-					dst_bits[2] = (WORD)CLAMP<int>((int)(b + 0.5), 0, 0xFFFF);
-					dst_bits += wordspp;
-				}
-			}
-		}
-		break;
-
-		case FIT_RGBA16:
-		{
-			// Calculate the number of words per pixel (1 for 16-bit, 3 for 48-bit or 4 for 64-bit)
-			const unsigned wordspp = (FreeImage_GetLine(src) / src_width) / sizeof(WORD);
-
-			for (unsigned y = 0; y < height; y++) {
-				// scale each row
-				const WORD *src_bits = (WORD*)FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x / sizeof(WORD);
-				WORD *dst_bits = (WORD*)FreeImage_GetScanLine(dst, y);
-
-				for (unsigned x = 0; x < dst_width; x++) {
-					// loop through row
-					const unsigned iLeft = weightsTable.getLeftBoundary(x);				// retrieve left boundary
-					const unsigned iLimit = weightsTable.getRightBoundary(x) - iLeft;	// retrieve right boundary
-					const WORD *pixel = src_bits + iLeft * wordspp;
-					double r = 0, g = 0, b = 0, a = 0;
-
-					// for(i = iLeft to iRight)
-					for (unsigned i = 0; i <= iLimit; i++) {
-						// scan between boundaries
-						// accumulate weighted effect of each neighboring pixel
-						const double weight = weightsTable.getWeight(x, i);						
-						r += (weight * (double)pixel[0]);
-						g += (weight * (double)pixel[1]);
-						b += (weight * (double)pixel[2]);
-						a += (weight * (double)pixel[3]);
-						pixel += wordspp;
-					}
-
-					// clamp and place result in destination pixel
-					dst_bits[0] = (WORD)CLAMP<int>((int)(r + 0.5), 0, 0xFFFF);
-					dst_bits[1] = (WORD)CLAMP<int>((int)(g + 0.5), 0, 0xFFFF);
-					dst_bits[2] = (WORD)CLAMP<int>((int)(b + 0.5), 0, 0xFFFF);
-					dst_bits[3] = (WORD)CLAMP<int>((int)(a + 0.5), 0, 0xFFFF);
-					dst_bits += wordspp;
-				}
-			}
-		}
-		break;
-
-		case FIT_FLOAT:
-		case FIT_RGBF:
-		case FIT_RGBAF:
-		{
-			// Calculate the number of floats per pixel (1 for 32-bit, 3 for 96-bit or 4 for 128-bit)
-			const unsigned floatspp = (FreeImage_GetLine(src) / src_width) / sizeof(float);
-
-			for(unsigned y = 0; y < height; y++) {
-				// scale each row
-				const float *src_bits = (float*)FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x / sizeof(float);
-				float *dst_bits = (float*)FreeImage_GetScanLine(dst, y);
-
-				for(unsigned x = 0; x < dst_width; x++) {
-					// loop through row
-					const unsigned iLeft = weightsTable.getLeftBoundary(x);    // retrieve left boundary
-					const unsigned iRight = weightsTable.getRightBoundary(x);  // retrieve right boundary
-					double value[4] = {0, 0, 0, 0};                            // 4 = 128 bpp max
-
-					for(unsigned i = iLeft; i <= iRight; i++) {
-						// scan between boundaries
-						// accumulate weighted effect of each neighboring pixel
-						const double weight = weightsTable.getWeight(x, i-iLeft);
-
-						unsigned index = i * floatspp;	// pixel index
-						for (unsigned j = 0; j < floatspp; j++) {
-							value[j] += (weight * (double)src_bits[index++]);
-						}
-					}
-
-					// place result in destination pixel
-					for (unsigned j = 0; j < floatspp; j++) {
-						dst_bits[j] = (float)value[j];
-					}
-
-					dst_bits += floatspp;
-				}
-			}
-		}
-		break;
-	}
-}
-
-/// Performs vertical image filtering
-void CResizeEngine::verticalFilter(FIBITMAP *const src, unsigned width, unsigned src_height, unsigned src_offset_x, unsigned src_offset_y, const RGBQUAD *const src_pal, FIBITMAP *const dst, unsigned dst_height) {
-
-	// allocate and calculate the contributions
-	CWeightsTable weightsTable(m_pFilter, dst_height, src_height);
-
-	// step through columns
-	switch(FreeImage_GetImageType(src)) {
-		case FIT_BITMAP:
-		{
-			const unsigned dst_pitch = FreeImage_GetPitch(dst);
-			BYTE * const dst_base = FreeImage_GetBits(dst);
-
-			switch(FreeImage_GetBPP(src)) {
-				case 1:
-				{
-					const unsigned src_pitch = FreeImage_GetPitch(src);
-					const BYTE * const src_base = FreeImage_GetBits(src)
-							+ src_offset_y * src_pitch + (src_offset_x >> 3);
-
-					switch(FreeImage_GetBPP(dst)) {
-						case 8:
-						{
-							// transparently convert the 1-bit non-transparent greyscale
-							// image to 8 bpp
-							if (src_pal) {
-								// we have got a palette
-								for (unsigned x = 0; x < width; x++) {
-									// work on column x in dst
-									BYTE *dst_bits = dst_base + x;
-									const unsigned index = x >> 3;
-									const unsigned mask = 0x80 >> (x & 0x07);
-
-									// scale each column
-									for (unsigned y = 0; y < dst_height; y++) {
-										// loop through column
-										const unsigned iLeft = weightsTable.getLeftBoundary(y);				// retrieve left boundary
-										const unsigned iLimit = weightsTable.getRightBoundary(y) - iLeft;	// retrieve right boundary
-										const BYTE *src_bits = src_base + iLeft * src_pitch + index;
-										double value = 0;
-
-										for (unsigned i = 0; i <= iLimit; i++) {
-											// scan between boundaries
-											// accumulate weighted effect of each neighboring pixel
-											const unsigned pixel = (*src_bits & mask) != 0;
-											value += (weightsTable.getWeight(y, i)
-													* (double)*(BYTE *)&src_pal[pixel]);
-											src_bits += src_pitch;
-										}
-										value *= 0xFF;
-
-										// clamp and place result in destination pixel
-										*dst_bits = (BYTE)CLAMP<int>((int)(value + 0.5), 0, 0xFF);
-										dst_bits += dst_pitch;
-									}
-								}
-							} else {
-								// we do not have a palette
-								for (unsigned x = 0; x < width; x++) {
-									// work on column x in dst
-									BYTE *dst_bits = dst_base + x;
-									const unsigned index = x >> 3;
-									const unsigned mask = 0x80 >> (x & 0x07);
-
-									// scale each column
-									for (unsigned y = 0; y < dst_height; y++) {
-										// loop through column
-										const unsigned iLeft = weightsTable.getLeftBoundary(y);				// retrieve left boundary
-										const unsigned iLimit = weightsTable.getRightBoundary(y) - iLeft;	// retrieve right boundary
-										const BYTE *src_bits = src_base + iLeft * src_pitch + index;
-										double value = 0;
-
-										for (unsigned i = 0; i <= iLimit; i++) {
-											// scan between boundaries
-											// accumulate weighted effect of each neighboring pixel
-											value += (weightsTable.getWeight(y, i)
-													* (double)((*src_bits & mask) != 0));
-											src_bits += src_pitch;
-										}
-										value *= 0xFF;
-
-										// clamp and place result in destination pixel
-										*dst_bits = (BYTE)CLAMP<int>((int)(value + 0.5), 0, 0xFF);
-										dst_bits += dst_pitch;
-									}
-								}
-							}
-						}
-						break;
-
-						case 24:
-						{
-							// transparently convert the non-transparent 1-bit image
-							// to 24 bpp; we always have got a palette here
-							for (unsigned x = 0; x < width; x++) {
-								// work on column x in dst
-								BYTE *dst_bits = dst_base + x * 3;
-								const unsigned index = x >> 3;
-								const unsigned mask = 0x80 >> (x & 0x07);
-
-								// scale each column
-								for (unsigned y = 0; y < dst_height; y++) {
-									// loop through column
-									const unsigned iLeft = weightsTable.getLeftBoundary(y);				// retrieve left boundary
-									const unsigned iLimit = weightsTable.getRightBoundary(y) - iLeft;	// retrieve right boundary
-									const BYTE *src_bits = src_base + iLeft * src_pitch + index;
-									double r = 0, g = 0, b = 0;
-
-									for (unsigned i = 0; i <= iLimit; i++) {
-										// scan between boundaries
-										// accumulate weighted effect of each neighboring pixel
-										const double weight = weightsTable.getWeight(y, i);
-										const unsigned pixel = (*src_bits & mask) != 0;
-										const BYTE * const entry = (BYTE *)&src_pal[pixel];
-										r += (weight * (double)entry[FI_RGBA_RED]);
-										g += (weight * (double)entry[FI_RGBA_GREEN]);
-										b += (weight * (double)entry[FI_RGBA_BLUE]);
-										src_bits += src_pitch;
-									}
-
-									// clamp and place result in destination pixel
-									dst_bits[FI_RGBA_RED]	= (BYTE)CLAMP<int>((int)(r + 0.5), 0, 0xFF);
-									dst_bits[FI_RGBA_GREEN]	= (BYTE)CLAMP<int>((int)(g + 0.5), 0, 0xFF);
-									dst_bits[FI_RGBA_BLUE]	= (BYTE)CLAMP<int>((int)(b + 0.5), 0, 0xFF);
-									dst_bits += dst_pitch;
-								}
-							}
-						}
-						break;
-
-						case 32:
-						{
-							// transparently convert the transparent 1-bit image
-							// to 32 bpp; we always have got a palette here
-							for (unsigned x = 0; x < width; x++) {
-								// work on column x in dst
-								BYTE *dst_bits = dst_base + x * 4;
-								const unsigned index = x >> 3;
-								const unsigned mask = 0x80 >> (x & 0x07);
-
-								// scale each column
-								for (unsigned y = 0; y < dst_height; y++) {
-									// loop through column
-									const unsigned iLeft = weightsTable.getLeftBoundary(y);				// retrieve left boundary
-									const unsigned iLimit = weightsTable.getRightBoundary(y) - iLeft;	// retrieve right boundary
-									const BYTE *src_bits = src_base + iLeft * src_pitch + index;
-									double r = 0, g = 0, b = 0, a = 0;
-
-									for (unsigned i = 0; i <= iLimit; i++) {
-										// scan between boundaries
-										// accumulate weighted effect of each neighboring pixel
-										const double weight = weightsTable.getWeight(y, i);
-										const unsigned pixel = (*src_bits & mask) != 0;
-										const BYTE * const entry = (BYTE *)&src_pal[pixel];
-										r += (weight * (double)entry[FI_RGBA_RED]);
-										g += (weight * (double)entry[FI_RGBA_GREEN]);
-										b += (weight * (double)entry[FI_RGBA_BLUE]);
-										a += (weight * (double)entry[FI_RGBA_ALPHA]);
-										src_bits += src_pitch;
-									}
-
-									// clamp and place result in destination pixel
-									dst_bits[FI_RGBA_RED]	= (BYTE)CLAMP<int>((int)(r + 0.5), 0, 0xFF);
-									dst_bits[FI_RGBA_GREEN]	= (BYTE)CLAMP<int>((int)(g + 0.5), 0, 0xFF);
-									dst_bits[FI_RGBA_BLUE]	= (BYTE)CLAMP<int>((int)(b + 0.5), 0, 0xFF);
-									dst_bits[FI_RGBA_ALPHA]	= (BYTE)CLAMP<int>((int)(a + 0.5), 0, 0xFF);
-									dst_bits += dst_pitch;
-								}
-							}
-						}
-						break;
-					}
-				}
-				break;
-
-				case 4:
-				{
-					const unsigned src_pitch = FreeImage_GetPitch(src);
-					const BYTE *const src_base = FreeImage_GetBits(src) + src_offset_y * src_pitch + (src_offset_x >> 1);
-
-					switch(FreeImage_GetBPP(dst)) {
-						case 8:
-						{
-							// transparently convert the non-transparent 4-bit greyscale image
-							// to 8 bpp; we always have got a palette for 4-bit images
-							for (unsigned x = 0; x < width; x++) {
-								// work on column x in dst
-								BYTE *dst_bits = dst_base + x;
-								const unsigned index = x >> 1;
-
-								// scale each column
-								for (unsigned y = 0; y < dst_height; y++) {
-									// loop through column
-									const unsigned iLeft = weightsTable.getLeftBoundary(y);				// retrieve left boundary
-									const unsigned iLimit = weightsTable.getRightBoundary(y) - iLeft;	// retrieve right boundary
-									const BYTE *src_bits = src_base + iLeft * src_pitch + index;
-									double value = 0;
-
-									for (unsigned i = 0; i <= iLimit; i++) {
-										// scan between boundaries
-										// accumulate weighted effect of each neighboring pixel
-										const unsigned pixel = x & 0x01 ? *src_bits & 0x0F : *src_bits >> 4;
-										value += (weightsTable.getWeight(y, i)
-												* (double)*(BYTE *)&src_pal[pixel]);
-										src_bits += src_pitch;
-									}
-
-									// clamp and place result in destination pixel
-									*dst_bits = (BYTE)CLAMP<int>((int)(value + 0.5), 0, 0xFF);
-									dst_bits += dst_pitch;
-								}
-							}
-						}
-						break;
-
-						case 24:
-						{
-							// transparently convert the non-transparent 4-bit image
-							// to 24 bpp; we always have got a palette for 4-bit images
-							for (unsigned x = 0; x < width; x++) {
-								// work on column x in dst
-								BYTE *dst_bits = dst_base + x * 3;
-								const unsigned index = x >> 1;
-
-								// scale each column
-								for (unsigned y = 0; y < dst_height; y++) {
-									// loop through column
-									const unsigned iLeft = weightsTable.getLeftBoundary(y);				// retrieve left boundary
-									const unsigned iLimit = weightsTable.getRightBoundary(y) - iLeft;	// retrieve right boundary
-									const BYTE *src_bits = src_base + iLeft * src_pitch + index;
-									double r = 0, g = 0, b = 0;
-
-									for (unsigned i = 0; i <= iLimit; i++) {
-										// scan between boundaries
-										// accumulate weighted effect of each neighboring pixel
-										const double weight = weightsTable.getWeight(y, i);
-										const unsigned pixel = x & 0x01 ? *src_bits & 0x0F : *src_bits >> 4;
-										const BYTE *const entry = (BYTE *)&src_pal[pixel];
-										r += (weight * (double)entry[FI_RGBA_RED]);
-										g += (weight * (double)entry[FI_RGBA_GREEN]);
-										b += (weight * (double)entry[FI_RGBA_BLUE]);
-										src_bits += src_pitch;
-									}
-
-									// clamp and place result in destination pixel
-									dst_bits[FI_RGBA_RED]	= (BYTE)CLAMP<int>((int)(r + 0.5), 0, 0xFF);
-									dst_bits[FI_RGBA_GREEN]	= (BYTE)CLAMP<int>((int)(g + 0.5), 0, 0xFF);
-									dst_bits[FI_RGBA_BLUE]	= (BYTE)CLAMP<int>((int)(b + 0.5), 0, 0xFF);
-									dst_bits += dst_pitch;
-								}
-							}
-						}
-						break;
-
-						case 32:
-						{
-							// transparently convert the transparent 4-bit image
-							// to 32 bpp; we always have got a palette for 4-bit images
-							for (unsigned x = 0; x < width; x++) {
-								// work on column x in dst
-								BYTE *dst_bits = dst_base + x * 4;
-								const unsigned index = x >> 1;
-
-								// scale each column
-								for (unsigned y = 0; y < dst_height; y++) {
-									// loop through column
-									const unsigned iLeft = weightsTable.getLeftBoundary(y);				// retrieve left boundary
-									const unsigned iLimit = weightsTable.getRightBoundary(y) - iLeft;	// retrieve right boundary
-									const BYTE *src_bits = src_base + iLeft * src_pitch + index;
-									double r = 0, g = 0, b = 0, a = 0;
-
-									for (unsigned i = 0; i <= iLimit; i++) {
-										// scan between boundaries
-										// accumulate weighted effect of each neighboring pixel
-										const double weight = weightsTable.getWeight(y, i);
-										const unsigned pixel = x & 0x01 ? *src_bits & 0x0F : *src_bits >> 4;
-										const BYTE *const entry = (BYTE *)&src_pal[pixel];
-										r += (weight * (double)entry[FI_RGBA_RED]);
-										g += (weight * (double)entry[FI_RGBA_GREEN]);
-										b += (weight * (double)entry[FI_RGBA_BLUE]);
-										a += (weight * (double)entry[FI_RGBA_ALPHA]);
-										src_bits += src_pitch;
-									}
-
-									// clamp and place result in destination pixel
-									dst_bits[FI_RGBA_RED]	= (BYTE)CLAMP<int>((int)(r + 0.5), 0, 0xFF);
-									dst_bits[FI_RGBA_GREEN]	= (BYTE)CLAMP<int>((int)(g + 0.5), 0, 0xFF);
-									dst_bits[FI_RGBA_BLUE]	= (BYTE)CLAMP<int>((int)(b + 0.5), 0, 0xFF);
-									dst_bits[FI_RGBA_ALPHA]	= (BYTE)CLAMP<int>((int)(a + 0.5), 0, 0xFF);
-									dst_bits += dst_pitch;
-								}
-							}
-						}
-						break;
-					}
-				}
-				break;
-
-				case 8:
-				{
-					const unsigned src_pitch = FreeImage_GetPitch(src);
-					const BYTE *const src_base = FreeImage_GetBits(src) + src_offset_y * src_pitch + src_offset_x;
-
-					switch(FreeImage_GetBPP(dst)) {
-						case 8:
-						{
-							// scale the 8-bit non-transparent greyscale image
-							// into an 8 bpp destination image
-							if (src_pal) {
-								// we have got a palette
-								for (unsigned x = 0; x < width; x++) {
-									// work on column x in dst
-									BYTE *dst_bits = dst_base + x;
-
-									// scale each column
-									for (unsigned y = 0; y < dst_height; y++) {
-										// loop through column
-										const unsigned iLeft = weightsTable.getLeftBoundary(y);				// retrieve left boundary
-										const unsigned iLimit = weightsTable.getRightBoundary(y) - iLeft;	// retrieve right boundary
-										const BYTE *src_bits = src_base + iLeft * src_pitch + x;
-										double value = 0;
-
-										for (unsigned i = 0; i <= iLimit; i++) {
-											// scan between boundaries
-											// accumulate weighted effect of each neighboring pixel
-											value += (weightsTable.getWeight(y, i)
-													* (double)*(BYTE *)&src_pal[*src_bits]);
-											src_bits += src_pitch;
-										}
-
-										// clamp and place result in destination pixel
-										*dst_bits = (BYTE)CLAMP<int>((int)(value + 0.5), 0, 0xFF);
-										dst_bits += dst_pitch;
-									}
-								}
-							} else {
-								// we do not have a palette
-								for (unsigned x = 0; x < width; x++) {
-									// work on column x in dst
-									BYTE *dst_bits = dst_base + x;
-
-									// scale each column
-									for (unsigned y = 0; y < dst_height; y++) {
-										// loop through column
-										const unsigned iLeft = weightsTable.getLeftBoundary(y);				// retrieve left boundary
-										const unsigned iLimit = weightsTable.getRightBoundary(y) - iLeft;	// retrieve right boundary
-										const BYTE *src_bits = src_base + iLeft * src_pitch + x;
-										double value = 0;
-
-										for (unsigned i = 0; i <= iLimit; i++) {
-											// scan between boundaries
-											// accumulate weighted effect of each neighboring pixel
-											value += (weightsTable.getWeight(y, i)
-													* (double)*src_bits);
-											src_bits += src_pitch;
-										}
-
-										// clamp and place result in destination pixel
-										*dst_bits = (BYTE)CLAMP<int>((int)(value + 0.5), 0, 0xFF);
-										dst_bits += dst_pitch;
-									}
-								}
-							}
-						}
-						break;
-
-						case 24:
-						{
-							// transparently convert the non-transparent 8-bit image
-							// to 24 bpp; we always have got a palette here
-							for (unsigned x = 0; x < width; x++) {
-								// work on column x in dst
-								BYTE *dst_bits = dst_base + x * 3;
-
-								// scale each column
-								for (unsigned y = 0; y < dst_height; y++) {
-									// loop through column
-									const unsigned iLeft = weightsTable.getLeftBoundary(y);				// retrieve left boundary
-									const unsigned iLimit = weightsTable.getRightBoundary(y) - iLeft;	// retrieve right boundary
-									const BYTE *src_bits = src_base + iLeft * src_pitch + x;
-									double r = 0, g = 0, b = 0;
-
-									for (unsigned i = 0; i <= iLimit; i++) {
-										// scan between boundaries
-										// accumulate weighted effect of each neighboring pixel
-										const double weight = weightsTable.getWeight(y, i);
-										const BYTE * const entry = (BYTE *)&src_pal[*src_bits];
-										r += (weight * (double)entry[FI_RGBA_RED]);
-										g += (weight * (double)entry[FI_RGBA_GREEN]);
-										b += (weight * (double)entry[FI_RGBA_BLUE]);
-										src_bits += src_pitch;
-									}
-
-									// clamp and place result in destination pixel
-									dst_bits[FI_RGBA_RED]	= (BYTE)CLAMP<int>((int)(r + 0.5), 0, 0xFF);
-									dst_bits[FI_RGBA_GREEN]	= (BYTE)CLAMP<int>((int)(g + 0.5), 0, 0xFF);
-									dst_bits[FI_RGBA_BLUE]	= (BYTE)CLAMP<int>((int)(b + 0.5), 0, 0xFF);
-									dst_bits += dst_pitch;
-								}
-							}
-						}
-						break;
-
-						case 32:
-						{
-							// transparently convert the transparent 8-bit image
-							// to 32 bpp; we always have got a palette here
-							for (unsigned x = 0; x < width; x++) {
-								// work on column x in dst
-								BYTE *dst_bits = dst_base + x * 4;
-
-								// scale each column
-								for (unsigned y = 0; y < dst_height; y++) {
-									// loop through column
-									const unsigned iLeft = weightsTable.getLeftBoundary(y);				// retrieve left boundary
-									const unsigned iLimit = weightsTable.getRightBoundary(y) - iLeft;	// retrieve right boundary
-									const BYTE *src_bits = src_base + iLeft * src_pitch + x;
-									double r = 0, g = 0, b = 0, a = 0;
-
-									for (unsigned i = 0; i <= iLimit; i++) {
-										// scan between boundaries
-										// accumulate weighted effect of each neighboring pixel
-										const double weight = weightsTable.getWeight(y, i);
-										const BYTE * const entry = (BYTE *)&src_pal[*src_bits];
-										r += (weight * (double)entry[FI_RGBA_RED]);
-										g += (weight * (double)entry[FI_RGBA_GREEN]);
-										b += (weight * (double)entry[FI_RGBA_BLUE]);
-										a += (weight * (double)entry[FI_RGBA_ALPHA]);
-										src_bits += src_pitch;
-									}
-
-									// clamp and place result in destination pixel
-									dst_bits[FI_RGBA_RED]	= (BYTE)CLAMP<int>((int)(r + 0.5), 0, 0xFF);
-									dst_bits[FI_RGBA_GREEN]	= (BYTE)CLAMP<int>((int)(g + 0.5), 0, 0xFF);
-									dst_bits[FI_RGBA_BLUE]	= (BYTE)CLAMP<int>((int)(b + 0.5), 0, 0xFF);
-									dst_bits[FI_RGBA_ALPHA]	= (BYTE)CLAMP<int>((int)(a + 0.5), 0, 0xFF);
-									dst_bits += dst_pitch;
-								}
-							}
-						}
-						break;
-					}
-				}
-				break;
-
-				case 16:
-				{
-					// transparently convert the 16-bit non-transparent image
-					// to 24 bpp
-					const unsigned src_pitch = FreeImage_GetPitch(src) / sizeof(WORD);
-					const WORD *const src_base = (WORD *)FreeImage_GetBits(src) + src_offset_y * src_pitch + src_offset_x;
-
-					if (IS_FORMAT_RGB565(src)) {
-						// image has 565 format
-						for (unsigned x = 0; x < width; x++) {
-							// work on column x in dst
-							BYTE *dst_bits = dst_base + x * 3;
-
-							// scale each column
-							for (unsigned y = 0; y < dst_height; y++) {
-								// loop through column
-								const unsigned iLeft = weightsTable.getLeftBoundary(y);				// retrieve left boundary
-								const unsigned iLimit = weightsTable.getRightBoundary(y) - iLeft;	// retrieve right boundary
-								const WORD *src_bits = src_base + iLeft * src_pitch + x;
-								double r = 0, g = 0, b = 0;
-
-								for (unsigned i = 0; i <= iLimit; i++) {
-									// scan between boundaries
-									// accumulate weighted effect of each neighboring pixel
-									const double weight = weightsTable.getWeight(y, i);
-									r += (weight * (double)((*src_bits & FI16_565_RED_MASK) >> FI16_565_RED_SHIFT));
-									g += (weight * (double)((*src_bits & FI16_565_GREEN_MASK) >> FI16_565_GREEN_SHIFT));
-									b += (weight * (double)((*src_bits & FI16_565_BLUE_MASK) >> FI16_565_BLUE_SHIFT));
-									src_bits += src_pitch;
-								}
-
-								// clamp and place result in destination pixel
-								dst_bits[FI_RGBA_RED]	= (BYTE)CLAMP<int>((int)(((r * 0xFF) / 0x1F) + 0.5), 0, 0xFF);
-								dst_bits[FI_RGBA_GREEN]	= (BYTE)CLAMP<int>((int)(((g * 0xFF) / 0x3F) + 0.5), 0, 0xFF);
-								dst_bits[FI_RGBA_BLUE]	= (BYTE)CLAMP<int>((int)(((b * 0xFF) / 0x1F) + 0.5), 0, 0xFF);
-								dst_bits += dst_pitch;
-							}
-						}
-					} else {
-						// image has 555 format
-						for (unsigned x = 0; x < width; x++) {
-							// work on column x in dst
-							BYTE *dst_bits = dst_base + x * 3;
-
-							// scale each column
-							for (unsigned y = 0; y < dst_height; y++) {
-								// loop through column
-								const unsigned iLeft = weightsTable.getLeftBoundary(y);				// retrieve left boundary
-								const unsigned iLimit = weightsTable.getRightBoundary(y) - iLeft;	// retrieve right boundary
-								const WORD *src_bits = src_base + iLeft * src_pitch + x;
-								double r = 0, g = 0, b = 0;
-
-								for (unsigned i = 0; i <= iLimit; i++) {
-									// scan between boundaries
-									// accumulate weighted effect of each neighboring pixel
-									const double weight = weightsTable.getWeight(y, i);
-									r += (weight * (double)((*src_bits & FI16_555_RED_MASK) >> FI16_555_RED_SHIFT));
-									g += (weight * (double)((*src_bits & FI16_555_GREEN_MASK) >> FI16_555_GREEN_SHIFT));
-									b += (weight * (double)((*src_bits & FI16_555_BLUE_MASK) >> FI16_555_BLUE_SHIFT));
-									src_bits += src_pitch;
-								}
-
-								// clamp and place result in destination pixel
-								dst_bits[FI_RGBA_RED]	= (BYTE)CLAMP<int>((int)(((r * 0xFF) / 0x1F) + 0.5), 0, 0xFF);
-								dst_bits[FI_RGBA_GREEN]	= (BYTE)CLAMP<int>((int)(((g * 0xFF) / 0x1F) + 0.5), 0, 0xFF);
-								dst_bits[FI_RGBA_BLUE]	= (BYTE)CLAMP<int>((int)(((b * 0xFF) / 0x1F) + 0.5), 0, 0xFF);
-								dst_bits += dst_pitch;
-							}
-						}
-					}
-				}
-				break;
-
-				case 24:
-				{
-					// scale the 24-bit transparent image
-					// into a 24 bpp destination image
-					const unsigned src_pitch = FreeImage_GetPitch(src);
-					const BYTE *const src_base = FreeImage_GetBits(src) + src_offset_y * src_pitch + src_offset_x * 3;
-
-					for (unsigned x = 0; x < width; x++) {
-						// work on column x in dst
-						const unsigned index = x * 3;
-						BYTE *dst_bits = dst_base + index;
-
-						// scale each column
-						for (unsigned y = 0; y < dst_height; y++) {
-							// loop through column
-							const unsigned iLeft = weightsTable.getLeftBoundary(y);				// retrieve left boundary
-							const unsigned iLimit = weightsTable.getRightBoundary(y) - iLeft;	// retrieve right boundary
-							const BYTE *src_bits = src_base + iLeft * src_pitch + index;
-							double r = 0, g = 0, b = 0;
-
-							for (unsigned i = 0; i <= iLimit; i++) {
-								// scan between boundaries
-								// accumulate weighted effect of each neighboring pixel
-								const double weight = weightsTable.getWeight(y, i);
-								r += (weight * (double)src_bits[FI_RGBA_RED]);
-								g += (weight * (double)src_bits[FI_RGBA_GREEN]);
-								b += (weight * (double)src_bits[FI_RGBA_BLUE]);
-								src_bits += src_pitch;
-							}
-
-							// clamp and place result in destination pixel
-							dst_bits[FI_RGBA_RED]	= (BYTE)CLAMP<int>((int) (r + 0.5), 0, 0xFF);
-							dst_bits[FI_RGBA_GREEN]	= (BYTE)CLAMP<int>((int) (g + 0.5), 0, 0xFF);
-							dst_bits[FI_RGBA_BLUE]	= (BYTE)CLAMP<int>((int) (b + 0.5), 0, 0xFF);
-							dst_bits += dst_pitch;
-						}
-					}
-				}
-				break;
-
-				case 32:
-				{
-					// scale the 32-bit transparent image
-					// into a 32 bpp destination image
-					const unsigned src_pitch = FreeImage_GetPitch(src);
-					const BYTE *const src_base = FreeImage_GetBits(src) + src_offset_y * src_pitch + src_offset_x * 4;
-
-					for (unsigned x = 0; x < width; x++) {
-						// work on column x in dst
-						const unsigned index = x * 4;
-						BYTE *dst_bits = dst_base + index;
-
-						// scale each column
-						for (unsigned y = 0; y < dst_height; y++) {
-							// loop through column
-							const unsigned iLeft = weightsTable.getLeftBoundary(y);				// retrieve left boundary
-							const unsigned iLimit = weightsTable.getRightBoundary(y) - iLeft;	// retrieve right boundary
-							const BYTE *src_bits = src_base + iLeft * src_pitch + index;
-							double r = 0, g = 0, b = 0, a = 0;
-
-							for (unsigned i = 0; i <= iLimit; i++) {
-								// scan between boundaries
-								// accumulate weighted effect of each neighboring pixel
-								const double weight = weightsTable.getWeight(y, i);
-								r += (weight * (double)src_bits[FI_RGBA_RED]);
-								g += (weight * (double)src_bits[FI_RGBA_GREEN]);
-								b += (weight * (double)src_bits[FI_RGBA_BLUE]);
-								a += (weight * (double)src_bits[FI_RGBA_ALPHA]);
-								src_bits += src_pitch;
-							}
-
-							// clamp and place result in destination pixel
-							dst_bits[FI_RGBA_RED]	= (BYTE)CLAMP<int>((int) (r + 0.5), 0, 0xFF);
-							dst_bits[FI_RGBA_GREEN]	= (BYTE)CLAMP<int>((int) (g + 0.5), 0, 0xFF);
-							dst_bits[FI_RGBA_BLUE]	= (BYTE)CLAMP<int>((int) (b + 0.5), 0, 0xFF);
-							dst_bits[FI_RGBA_ALPHA]	= (BYTE)CLAMP<int>((int) (a + 0.5), 0, 0xFF);
-							dst_bits += dst_pitch;
-						}
-					}
-				}
-				break;
-			}
-		}
-		break;
-
-		case FIT_UINT16:
-		{
-			// Calculate the number of words per pixel (1 for 16-bit, 3 for 48-bit or 4 for 64-bit)
-			const unsigned wordspp = (FreeImage_GetLine(src) / width) / sizeof(WORD);
-
-			const unsigned dst_pitch = FreeImage_GetPitch(dst) / sizeof(WORD);
-			WORD *const dst_base = (WORD *)FreeImage_GetBits(dst);
-
-			const unsigned src_pitch = FreeImage_GetPitch(src) / sizeof(WORD);
-			const WORD *const src_base = (WORD *)FreeImage_GetBits(src)	+ src_offset_y * src_pitch + src_offset_x * wordspp;
-
-			for (unsigned x = 0; x < width; x++) {
-				// work on column x in dst
-				const unsigned index = x * wordspp;	// pixel index
-				WORD *dst_bits = dst_base + index;
-
-				// scale each column
-				for (unsigned y = 0; y < dst_height; y++) {
-					// loop through column
-					const unsigned iLeft = weightsTable.getLeftBoundary(y);				// retrieve left boundary
-					const unsigned iLimit = weightsTable.getRightBoundary(y) - iLeft;	// retrieve right boundary
-					const WORD *src_bits = src_base + iLeft * src_pitch + index;
-					double value = 0;
-
-					for (unsigned i = 0; i <= iLimit; i++) {
-						// scan between boundaries
-						// accumulate weighted effect of each neighboring pixel
-						const double weight = weightsTable.getWeight(y, i);
-						value += (weight * (double)src_bits[0]);
-						src_bits += src_pitch;
-					}
-
-					// clamp and place result in destination pixel
-					dst_bits[0] = (WORD)CLAMP<int>((int)(value + 0.5), 0, 0xFFFF);
-
-					dst_bits += dst_pitch;
-				}
-			}
-		}
-		break;
-
-		case FIT_RGB16:
-		{
-			// Calculate the number of words per pixel (1 for 16-bit, 3 for 48-bit or 4 for 64-bit)
-			const unsigned wordspp = (FreeImage_GetLine(src) / width) / sizeof(WORD);
-
-			const unsigned dst_pitch = FreeImage_GetPitch(dst) / sizeof(WORD);
-			WORD *const dst_base = (WORD *)FreeImage_GetBits(dst);
-
-			const unsigned src_pitch = FreeImage_GetPitch(src) / sizeof(WORD);
-			const WORD *const src_base = (WORD *)FreeImage_GetBits(src) + src_offset_y * src_pitch + src_offset_x * wordspp;
-
-			for (unsigned x = 0; x < width; x++) {
-				// work on column x in dst
-				const unsigned index = x * wordspp;	// pixel index
-				WORD *dst_bits = dst_base + index;
-
-				// scale each column
-				for (unsigned y = 0; y < dst_height; y++) {
-					// loop through column
-					const unsigned iLeft = weightsTable.getLeftBoundary(y);				// retrieve left boundary
-					const unsigned iLimit = weightsTable.getRightBoundary(y) - iLeft;	// retrieve right boundary
-					const WORD *src_bits = src_base + iLeft * src_pitch + index;
-					double r = 0, g = 0, b = 0;
-
-					for (unsigned i = 0; i <= iLimit; i++) {
-						// scan between boundaries
-						// accumulate weighted effect of each neighboring pixel
-						const double weight = weightsTable.getWeight(y, i);					
-						r += (weight * (double)src_bits[0]);
-						g += (weight * (double)src_bits[1]);
-						b += (weight * (double)src_bits[2]);
-
-						src_bits += src_pitch;
-					}
-
-					// clamp and place result in destination pixel
-					dst_bits[0] = (WORD)CLAMP<int>((int)(r + 0.5), 0, 0xFFFF);
-					dst_bits[1] = (WORD)CLAMP<int>((int)(g + 0.5), 0, 0xFFFF);
-					dst_bits[2] = (WORD)CLAMP<int>((int)(b + 0.5), 0, 0xFFFF);
-
-					dst_bits += dst_pitch;
-				}
-			}
-		}
-		break;
-
-		case FIT_RGBA16:
-		{
-			// Calculate the number of words per pixel (1 for 16-bit, 3 for 48-bit or 4 for 64-bit)
-			const unsigned wordspp = (FreeImage_GetLine(src) / width) / sizeof(WORD);
-
-			const unsigned dst_pitch = FreeImage_GetPitch(dst) / sizeof(WORD);
-			WORD *const dst_base = (WORD *)FreeImage_GetBits(dst);
-
-			const unsigned src_pitch = FreeImage_GetPitch(src) / sizeof(WORD);
-			const WORD *const src_base = (WORD *)FreeImage_GetBits(src) + src_offset_y * src_pitch + src_offset_x * wordspp;
-
-			for (unsigned x = 0; x < width; x++) {
-				// work on column x in dst
-				const unsigned index = x * wordspp;	// pixel index
-				WORD *dst_bits = dst_base + index;
-
-				// scale each column
-				for (unsigned y = 0; y < dst_height; y++) {
-					// loop through column
-					const unsigned iLeft = weightsTable.getLeftBoundary(y);				// retrieve left boundary
-					const unsigned iLimit = weightsTable.getRightBoundary(y) - iLeft;	// retrieve right boundary
-					const WORD *src_bits = src_base + iLeft * src_pitch + index;
-					double r = 0, g = 0, b = 0, a = 0;
-
-					for (unsigned i = 0; i <= iLimit; i++) {
-						// scan between boundaries
-						// accumulate weighted effect of each neighboring pixel
-						const double weight = weightsTable.getWeight(y, i);					
-						r += (weight * (double)src_bits[0]);
-						g += (weight * (double)src_bits[1]);
-						b += (weight * (double)src_bits[2]);
-						a += (weight * (double)src_bits[3]);
-
-						src_bits += src_pitch;
-					}
-
-					// clamp and place result in destination pixel
-					dst_bits[0] = (WORD)CLAMP<int>((int)(r + 0.5), 0, 0xFFFF);
-					dst_bits[1] = (WORD)CLAMP<int>((int)(g + 0.5), 0, 0xFFFF);
-					dst_bits[2] = (WORD)CLAMP<int>((int)(b + 0.5), 0, 0xFFFF);
-					dst_bits[3] = (WORD)CLAMP<int>((int)(a + 0.5), 0, 0xFFFF);
-
-					dst_bits += dst_pitch;
-				}
-			}
-		}
-		break;
-
-		case FIT_FLOAT:
-		case FIT_RGBF:
-		case FIT_RGBAF:
-		{
-			// Calculate the number of floats per pixel (1 for 32-bit, 3 for 96-bit or 4 for 128-bit)
-			const unsigned floatspp = (FreeImage_GetLine(src) / width) / sizeof(float);
-
-			const unsigned dst_pitch = FreeImage_GetPitch(dst) / sizeof(float);
-			float *const dst_base = (float *)FreeImage_GetBits(dst);
-
-			const unsigned src_pitch = FreeImage_GetPitch(src) / sizeof(float);
-			const float *const src_base = (float *)FreeImage_GetBits(src) + src_offset_y * src_pitch + src_offset_x * floatspp;
-
-			for (unsigned x = 0; x < width; x++) {
-				// work on column x in dst
-				const unsigned index = x * floatspp;	// pixel index
-				float *dst_bits = (float *)dst_base + index;
-
-				// scale each column
-				for (unsigned y = 0; y < dst_height; y++) {
-					// loop through column
-					const unsigned iLeft = weightsTable.getLeftBoundary(y);    // retrieve left boundary
-					const unsigned iRight = weightsTable.getRightBoundary(y);  // retrieve right boundary
-					const float *src_bits = src_base + iLeft * src_pitch + index;
-					double value[4] = {0, 0, 0, 0};                            // 4 = 128 bpp max
-
-					for (unsigned i = iLeft; i <= iRight; i++) {
-						// scan between boundaries
-						// accumulate weighted effect of each neighboring pixel
-						const double weight = weightsTable.getWeight(y, i - iLeft);
-						for (unsigned j = 0; j < floatspp; j++) {
-							value[j] += (weight * (double)src_bits[j]);
-						}
-						src_bits += src_pitch;
-					}
-
-					// place result in destination pixel
-					for (unsigned j = 0; j < floatspp; j++) {
-						dst_bits[j] = (float)value[j];
-					}
-					dst_bits += dst_pitch;
-				}
-			}
-		}
-		break;
-	}
-}
+// ==========================================================
+// Upsampling / downsampling classes
+//
+// Design and implementation by
+// - Herv� Drolon (drolon at infonie.fr)
+// - Detlev Vendt (detlev.vendt at brillit.de)
+// - Carsten Klein (cklein05 at users.sourceforge.net)
+//
+// This file is part of FreeImage 3
+//
+// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
+// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
+// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
+// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
+// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
+// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
+// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+// THIS DISCLAIMER.
+//
+// Use at your own risk!
+// ==========================================================
+
+#include "Resize.h"
+
+/**
+Returns the color type of a bitmap. In contrast to FreeImage_GetColorType,
+this function optionally supports a boolean OUT parameter, that receives TRUE,
+if the specified bitmap is greyscale, that is, it consists of grey colors only.
+Although it returns the same value as returned by FreeImage_GetColorType for all
+image types, this extended function primarily is intended for palletized images,
+since the boolean pointed to by 'bIsGreyscale' remains unchanged for RGB(A/F)
+images. However, the outgoing boolean is properly maintained for palletized images,
+as well as for any non-RGB image type, like FIT_UINTxx and FIT_DOUBLE, for example.
+ at param dib A pointer to a FreeImage bitmap to calculate the extended color type for
+ at param bIsGreyscale A pointer to a boolean, that receives TRUE, if the specified bitmap
+is greyscale, that is, it consists of grey colors only. This parameter can be NULL.
+ at return the color type of the specified bitmap
+*/
+static FREE_IMAGE_COLOR_TYPE
+GetExtendedColorType(FIBITMAP *dib, BOOL *bIsGreyscale) {
+	const unsigned bpp = FreeImage_GetBPP(dib);
+	const unsigned size = CalculateUsedPaletteEntries(bpp);
+	const RGBQUAD * const pal = FreeImage_GetPalette(dib);
+	FREE_IMAGE_COLOR_TYPE color_type = FIC_MINISBLACK;
+	BOOL bIsGrey = TRUE;
+
+	switch (bpp) {
+		case 1:
+		{
+			for (unsigned i = 0; i < size; i++) {
+				if ((pal[i].rgbRed != pal[i].rgbGreen) || (pal[i].rgbRed != pal[i].rgbBlue)) {
+					color_type = FIC_PALETTE;
+					bIsGrey = FALSE;
+					break;
+				}
+			}
+			if (bIsGrey) {
+				if (pal[0].rgbBlue == 255 && pal[1].rgbBlue == 0) {
+					color_type = FIC_MINISWHITE;
+				} else if (pal[0].rgbBlue != 0 || pal[1].rgbBlue != 255) {
+					color_type = FIC_PALETTE;
+				}
+			}
+			break;
+		}
+
+		case 4:
+		case 8:
+		{
+			for (unsigned i = 0; i < size; i++) {
+				if ((pal[i].rgbRed != pal[i].rgbGreen) || (pal[i].rgbRed != pal[i].rgbBlue)) {
+					color_type = FIC_PALETTE;
+					bIsGrey = FALSE;
+					break;
+				}
+				if (color_type != FIC_PALETTE && pal[i].rgbBlue != i) {
+					if ((size - i - 1) != pal[i].rgbBlue) {
+						color_type = FIC_PALETTE;
+						if (!bIsGreyscale) {
+							// exit loop if we're not setting
+							// bIsGreyscale parameter
+							break;
+						}
+					} else {
+						color_type = FIC_MINISWHITE;
+					}
+				}
+			}
+			break;
+		}
+
+		default:
+		{
+			color_type = FreeImage_GetColorType(dib);
+			bIsGrey = (color_type == FIC_MINISBLACK) ? TRUE : FALSE;
+			break;
+		}
+
+	}
+	if (bIsGreyscale) {
+		*bIsGreyscale = bIsGrey;
+	}
+
+	return color_type;
+}
+
+/**
+Returns a pointer to an RGBA palette, created from the specified bitmap.
+The RGBA palette is a copy of the specified bitmap's palette, that, additionally
+contains the bitmap's transparency information in the rgbReserved member
+of the palette's RGBQUAD elements.
+ at param dib A pointer to a FreeImage bitmap to create the RGBA palette from.
+ at param buffer A pointer to the buffer to store the RGBA palette.
+ at return A pointer to the newly created RGBA palette or NULL, if the specified
+bitmap is no palletized standard bitmap. If non-NULL, the returned value is
+actually the pointer passed in parameter 'buffer'.
+*/
+static inline RGBQUAD *
+GetRGBAPalette(FIBITMAP *dib, RGBQUAD * const buffer) {
+	// clone the palette
+	const unsigned ncolors = FreeImage_GetColorsUsed(dib);
+	if (ncolors == 0) {
+		return NULL;
+	}
+	memcpy(buffer, FreeImage_GetPalette(dib), ncolors * sizeof(RGBQUAD));
+	// merge the transparency table
+	const unsigned ntransp = MIN(ncolors, FreeImage_GetTransparencyCount(dib));
+	const BYTE * const tt = FreeImage_GetTransparencyTable(dib);
+	for (unsigned i = 0; i < ntransp; i++) {
+		buffer[i].rgbReserved = tt[i];
+	}
+	for (unsigned i = ntransp; i < ncolors; i++) {
+		buffer[i].rgbReserved = 255;
+	}
+	return buffer;
+}
+
+// --------------------------------------------------------------------------
+
+CWeightsTable::CWeightsTable(CGenericFilter *pFilter, unsigned uDstSize, unsigned uSrcSize) {
+	double dWidth;
+	double dFScale;
+	const double dFilterWidth = pFilter->GetWidth();
+
+	// scale factor
+	const double dScale = double(uDstSize) / double(uSrcSize);
+
+	if(dScale < 1.0) {
+		// minification
+		dWidth = dFilterWidth / dScale; 
+		dFScale = dScale; 
+	} else {
+		// magnification
+		dWidth = dFilterWidth; 
+		dFScale = 1.0; 
+	}
+
+	// allocate a new line contributions structure
+	//
+	// window size is the number of sampled pixels
+	m_WindowSize = 2 * (int)ceil(dWidth) + 1; 
+	// length of dst line (no. of rows / cols) 
+	m_LineLength = uDstSize; 
+
+	 // allocate list of contributions 
+	m_WeightTable = (Contribution*)malloc(m_LineLength * sizeof(Contribution));
+	for(unsigned u = 0; u < m_LineLength; u++) {
+		// allocate contributions for every pixel
+		m_WeightTable[u].Weights = (double*)malloc(m_WindowSize * sizeof(double));
+	}
+
+	// offset for discrete to continuous coordinate conversion
+	const double dOffset = (0.5 / dScale);
+
+	for(unsigned u = 0; u < m_LineLength; u++) {
+		// scan through line of contributions
+
+		// inverse mapping (discrete dst 'u' to continous src 'dCenter')
+		const double dCenter = (double)u / dScale + dOffset;
+
+		// find the significant edge points that affect the pixel
+		const int iLeft = MAX(0, (int)(dCenter - dWidth + 0.5));
+		const int iRight = MIN((int)(dCenter + dWidth + 0.5), int(uSrcSize));
+
+		m_WeightTable[u].Left = iLeft; 
+		m_WeightTable[u].Right = iRight;
+
+		double dTotalWeight = 0;  // sum of weights (initialized to zero)
+		for(int iSrc = iLeft; iSrc < iRight; iSrc++) {
+			// calculate weights
+			const double weight = dFScale * pFilter->Filter(dFScale * ((double)iSrc + 0.5 - dCenter));
+			// assert((iSrc-iLeft) < m_WindowSize);
+			m_WeightTable[u].Weights[iSrc-iLeft] = weight;
+			dTotalWeight += weight;
+		}
+		if((dTotalWeight > 0) && (dTotalWeight != 1)) {
+			// normalize weight of neighbouring points
+			for(int iSrc = iLeft; iSrc < iRight; iSrc++) {
+				// normalize point
+				m_WeightTable[u].Weights[iSrc-iLeft] /= dTotalWeight; 
+			}
+		}
+
+		// simplify the filter, discarding null weights at the right
+		{			
+			int iTrailing = iRight - iLeft - 1;
+			while(m_WeightTable[u].Weights[iTrailing] == 0) {
+				m_WeightTable[u].Right--;
+				iTrailing--;
+				if(m_WeightTable[u].Right == m_WeightTable[u].Left) {
+					break;
+				}
+			}
+			
+		}
+
+	} // next dst pixel
+}
+
+CWeightsTable::~CWeightsTable() {
+	for(unsigned u = 0; u < m_LineLength; u++) {
+		// free contributions for every pixel
+		free(m_WeightTable[u].Weights);
+	}
+	// free list of pixels contributions
+	free(m_WeightTable);
+}
+
+// --------------------------------------------------------------------------
+
+FIBITMAP* CResizeEngine::scale(FIBITMAP *src, unsigned dst_width, unsigned dst_height, unsigned src_left, unsigned src_top, unsigned src_width, unsigned src_height, unsigned flags) {
+
+	const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(src);
+	const unsigned src_bpp = FreeImage_GetBPP(src);
+
+	// determine the image's color type
+	BOOL bIsGreyscale = FALSE;
+	FREE_IMAGE_COLOR_TYPE color_type;
+	if (src_bpp <= 8) {
+		color_type = GetExtendedColorType(src, &bIsGreyscale);
+	} else {
+		color_type = FIC_RGB;
+	}
+
+	// determine the required bit depth of the destination image
+	unsigned dst_bpp;
+	unsigned dst_bpp_s1 = 0;
+	if (color_type == FIC_PALETTE && !bIsGreyscale) {
+		// non greyscale FIC_PALETTE images require a high-color destination
+		// image (24- or 32-bits depending on the image's transparent state)
+		dst_bpp = FreeImage_IsTransparent(src) ? 32 : 24;
+	} else if (src_bpp <= 8) {
+		// greyscale images require an 8-bit destination image
+		// (or a 32-bit image if the image is transparent);
+		// however, if flag FI_RESCALE_TRUE_COLOR is set, we will return
+		// a true color (24 bpp) image
+		if (FreeImage_IsTransparent(src)) {
+			dst_bpp = 32;
+			// additionally, for transparent images we always need a
+			// palette including transparency information (an RGBA palette)
+			// so, set color_type accordingly
+			color_type = FIC_PALETTE;
+		} else {
+			dst_bpp = ((flags & FI_RESCALE_TRUE_COLOR) == FI_RESCALE_TRUE_COLOR) ? 24 : 8;
+			// in any case, we use a fast 8-bit temporary image for the
+			// first filter operation (stage 1, either horizontal or
+			// vertical) and implicitly convert to 24 bpp (if requested
+			// by flag FI_RESCALE_TRUE_COLOR) during the second filter
+			// operation
+			dst_bpp_s1 = 8;
+		}
+	} else if (src_bpp == 16 && image_type == FIT_BITMAP) {
+		// 16-bit 555 and 565 RGB images require a high-color destination
+		// image (fixed to 24 bits, since 16-bit RGBs don't support
+		// transparency in FreeImage)
+		dst_bpp = 24;
+	} else {
+		// bit depth remains unchanged for all other images
+		dst_bpp = src_bpp;
+	}
+
+	// make 'stage 1' bpp a copy of the destination bpp if it
+	// was not explicitly set
+	if (dst_bpp_s1 == 0) {
+		dst_bpp_s1 = dst_bpp;
+	}
+
+	// early exit if destination size is equal to source size
+	if ((src_width == dst_width) && (src_height == dst_height)) {
+		FIBITMAP *out = src;
+		FIBITMAP *tmp = src;
+		if ((src_width != FreeImage_GetWidth(src)) || (src_height != FreeImage_GetHeight(src))) {
+			out = FreeImage_Copy(tmp, src_left, src_top, src_left + src_width, src_top + src_height);
+			tmp = out;
+		}
+		if (src_bpp != dst_bpp) {
+			switch (dst_bpp) {
+				case 8:
+					out = FreeImage_ConvertToGreyscale(tmp);
+					break;
+				case 24:
+					out = FreeImage_ConvertTo24Bits(tmp);
+					break;
+				case 32:
+					out = FreeImage_ConvertTo32Bits(tmp);
+					break;
+				default:
+					break;
+			}
+			if (tmp != src) {
+				FreeImage_Unload(tmp);
+				tmp = NULL;
+			}
+		}
+
+		return (out != src) ? out : FreeImage_Clone(src);
+	}
+
+	RGBQUAD pal_buffer[256];
+	RGBQUAD *src_pal = NULL;
+
+	// provide the source image's palette to the rescaler for
+	// FIC_PALETTE type images (this includes palletized greyscale
+	// images with an unordered palette as well as transparent images)
+	if (color_type == FIC_PALETTE) {
+		if (dst_bpp == 32) {
+			// a 32-bit destination image signals transparency, so
+			// create an RGBA palette from the source palette
+			src_pal = GetRGBAPalette(src, pal_buffer);
+		} else {
+			src_pal = FreeImage_GetPalette(src);
+		}
+	}
+
+	// allocate the dst image
+	FIBITMAP *dst = FreeImage_AllocateT(image_type, dst_width, dst_height, dst_bpp, 0, 0, 0);
+	if (!dst) {
+		return NULL;
+	}
+	
+	if (dst_bpp == 8) {
+		RGBQUAD * const dst_pal = FreeImage_GetPalette(dst);
+		if (color_type == FIC_MINISWHITE) {
+			// build an inverted greyscale palette
+			CREATE_GREYSCALE_PALETTE_REVERSE(dst_pal, 256);
+		} 
+		/*
+		else {
+			// build a default greyscale palette
+			// Currently, FreeImage_AllocateT already creates a default
+			// greyscale palette for 8 bpp images, so we can skip this here.
+			CREATE_GREYSCALE_PALETTE(dst_pal, 256);
+		}
+		*/
+	}
+
+	// calculate x and y offsets; since FreeImage uses bottom-up bitmaps, the
+	// value of src_offset_y is measured from the bottom of the image
+	unsigned src_offset_x = src_left;
+	unsigned src_offset_y = FreeImage_GetHeight(src) - src_height - src_top;
+
+	/*
+	Decide which filtering order (xy or yx) is faster for this mapping. 
+	--- The theory ---
+	Try to minimize calculations by counting the number of convolution multiplies
+	if(dst_width*src_height <= src_width*dst_height) {
+		// xy filtering
+	} else {
+		// yx filtering
+	}
+	--- The practice ---
+	Try to minimize calculations by counting the number of vertical convolutions (the most time consuming task)
+	if(dst_width*dst_height <= src_width*dst_height) {
+		// xy filtering
+	} else {
+		// yx filtering
+	}
+	*/
+
+	if (dst_width <= src_width) {
+		// xy filtering
+		// -------------
+
+		FIBITMAP *tmp = NULL;
+
+		if (src_width != dst_width) {
+			// source and destination widths are different so, we must
+			// filter horizontally
+			if (src_height != dst_height) {
+				// source and destination heights are also different so, we need
+				// a temporary image
+				tmp = FreeImage_AllocateT(image_type, dst_width, src_height, dst_bpp_s1, 0, 0, 0);
+				if (!tmp) {
+					FreeImage_Unload(dst);
+					return NULL;
+				}
+			} else {
+				// source and destination heights are equal so, we can directly
+				// scale into destination image (second filter method will not
+				// be invoked)
+				tmp = dst;
+			}
+
+			// scale source image horizontally into temporary (or destination) image
+			horizontalFilter(src, src_height, src_width, src_offset_x, src_offset_y, src_pal, tmp, dst_width);
+
+			// set x and y offsets to zero for the second filter method
+			// invocation (the temporary image only contains the portion of
+			// the image to be rescaled with no offsets)
+			src_offset_x = 0;
+			src_offset_y = 0;
+
+			// also ensure, that the second filter method gets no source
+			// palette (the temporary image is palletized only, if it is
+			// greyscale; in that case, it is an 8-bit image with a linear
+			// palette so, the source palette is not needed or will even be
+			// mismatching, if the source palette is unordered)
+			src_pal = NULL;
+		} else {
+			// source and destination widths are equal so, just copy the
+			// image pointer
+			tmp = src;
+		}
+
+		if (src_height != dst_height) {
+			// source and destination heights are different so, scale
+			// temporary (or source) image vertically into destination image
+			verticalFilter(tmp, dst_width, src_height, src_offset_x, src_offset_y, src_pal, dst, dst_height);
+		}
+
+		// free temporary image, if not pointing to either src or dst
+		if (tmp != src && tmp != dst) {
+			FreeImage_Unload(tmp);
+		}
+
+	} else {
+		// yx filtering
+		// -------------
+
+		// Remark:
+		// The yx filtering branch could be more optimized by taking into,
+		// account that (src_width != dst_width) is always true, which
+		// follows from the above condition, which selects filtering order.
+		// Since (dst_width <= src_width) == TRUE selects xy filtering,
+		// both widths must be different when performing yx filtering.
+		// However, to make the code more robust, not depending on that
+		// condition and more symmetric to the xy filtering case, these
+		// (src_width != dst_width) conditions are still in place.
+
+		FIBITMAP *tmp = NULL;
+
+		if (src_height != dst_height) {
+			// source and destination heights are different so, we must
+			// filter vertically
+			if (src_width != dst_width) {
+				// source and destination widths are also different so, we need
+				// a temporary image
+				tmp = FreeImage_AllocateT(image_type, src_width, dst_height, dst_bpp_s1, 0, 0, 0);
+				if (!tmp) {
+					FreeImage_Unload(dst);
+					return NULL;
+				}
+			} else {
+				// source and destination widths are equal so, we can directly
+				// scale into destination image (second filter method will not
+				// be invoked)
+				tmp = dst;
+			}
+
+			// scale source image vertically into temporary (or destination) image
+			verticalFilter(src, src_width, src_height, src_offset_x, src_offset_y, src_pal, tmp, dst_height);
+
+			// set x and y offsets to zero for the second filter method
+			// invocation (the temporary image only contains the portion of
+			// the image to be rescaled with no offsets)
+			src_offset_x = 0;
+			src_offset_y = 0;
+
+			// also ensure, that the second filter method gets no source
+			// palette (the temporary image is palletized only, if it is
+			// greyscale; in that case, it is an 8-bit image with a linear
+			// palette so, the source palette is not needed or will even be
+			// mismatching, if the source palette is unordered)
+			src_pal = NULL;
+
+		} else {
+			// source and destination heights are equal so, just copy the
+			// image pointer
+			tmp = src;
+		}
+
+		if (src_width != dst_width) {
+			// source and destination heights are different so, scale
+			// temporary (or source) image horizontally into destination image
+			horizontalFilter(tmp, dst_height, src_width, src_offset_x, src_offset_y, src_pal, dst, dst_width);
+		}
+
+		// free temporary image, if not pointing to either src or dst
+		if (tmp != src && tmp != dst) {
+			FreeImage_Unload(tmp);
+		}
+	}
+
+	return dst;
+} 
+
+void CResizeEngine::horizontalFilter(FIBITMAP *const src, unsigned height, unsigned src_width, unsigned src_offset_x, unsigned src_offset_y, const RGBQUAD *const src_pal, FIBITMAP *const dst, unsigned dst_width) {
+
+	// allocate and calculate the contributions
+	CWeightsTable weightsTable(m_pFilter, dst_width, src_width);
+
+	// step through rows
+	switch(FreeImage_GetImageType(src)) {
+		case FIT_BITMAP:
+		{
+			switch(FreeImage_GetBPP(src)) {
+				case 1:
+				{
+					switch(FreeImage_GetBPP(dst)) {
+						case 8:
+						{
+							// transparently convert the 1-bit non-transparent greyscale image to 8 bpp
+							src_offset_x >>= 3;
+							if (src_pal) {
+								// we have got a palette
+								for (unsigned y = 0; y < height; y++) {
+									// scale each row
+									const BYTE * const src_bits = FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x;
+									BYTE * const dst_bits = FreeImage_GetScanLine(dst, y);
+
+									for (unsigned x = 0; x < dst_width; x++) {
+										// loop through row
+										const unsigned iLeft = weightsTable.getLeftBoundary(x);		// retrieve left boundary
+										const unsigned iRight = weightsTable.getRightBoundary(x);	// retrieve right boundary
+										double value = 0;
+
+										for (unsigned i = iLeft; i < iRight; i++) {
+											// scan between boundaries
+											// accumulate weighted effect of each neighboring pixel
+											const unsigned pixel = (src_bits[i >> 3] & (0x80 >> (i & 0x07))) != 0;
+											value += (weightsTable.getWeight(x, i - iLeft) * (double)*(BYTE *)&src_pal[pixel]);
+										}
+
+										// clamp and place result in destination pixel
+										dst_bits[x] = (BYTE)CLAMP<int>((int)(value + 0.5), 0, 0xFF);
+									}
+								}
+							} else {
+								// we do not have a palette
+								for (unsigned y = 0; y < height; y++) {
+									// scale each row
+									const BYTE * const src_bits = FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x;
+									BYTE * const dst_bits = FreeImage_GetScanLine(dst, y);
+
+									for (unsigned x = 0; x < dst_width; x++) {
+										// loop through row
+										const unsigned iLeft = weightsTable.getLeftBoundary(x);		// retrieve left boundary
+										const unsigned iRight = weightsTable.getRightBoundary(x);	// retrieve right boundary
+										double value = 0;
+
+										for (unsigned i = iLeft; i < iRight; i++) {
+											// scan between boundaries
+											// accumulate weighted effect of each neighboring pixel
+											const unsigned pixel = (src_bits[i >> 3] & (0x80 >> (i & 0x07))) != 0;
+											value += (weightsTable.getWeight(x, i - iLeft) * (double)pixel);
+										}
+										value *= 0xFF;
+
+										// clamp and place result in destination pixel
+										dst_bits[x] = (BYTE)CLAMP<int>((int)(value + 0.5), 0, 0xFF);
+									}
+								}
+							}
+						}
+						break;
+
+						case 24:
+						{
+							// transparently convert the non-transparent 1-bit image to 24 bpp
+							src_offset_x >>= 3;
+							if (src_pal) {
+								// we have got a palette
+								for (unsigned y = 0; y < height; y++) {
+									// scale each row
+									const BYTE * const src_bits = FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x;
+									BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
+
+									for (unsigned x = 0; x < dst_width; x++) {
+										// loop through row
+										const unsigned iLeft = weightsTable.getLeftBoundary(x);    // retrieve left boundary
+										const unsigned iRight = weightsTable.getRightBoundary(x);  // retrieve right boundary
+										double r = 0, g = 0, b = 0;
+
+										for (unsigned i = iLeft; i < iRight; i++) {
+											// scan between boundaries
+											// accumulate weighted effect of each neighboring pixel
+											const double weight = weightsTable.getWeight(x, i - iLeft);
+											const unsigned pixel = (src_bits[i >> 3] & (0x80 >> (i & 0x07))) != 0;
+											const BYTE * const entry = (BYTE *)&src_pal[pixel];
+											r += (weight * (double)entry[FI_RGBA_RED]);
+											g += (weight * (double)entry[FI_RGBA_GREEN]);
+											b += (weight * (double)entry[FI_RGBA_BLUE]);
+										}
+
+										// clamp and place result in destination pixel
+										dst_bits[FI_RGBA_RED]	= (BYTE)CLAMP<int>((int)(r + 0.5), 0, 0xFF);
+										dst_bits[FI_RGBA_GREEN]	= (BYTE)CLAMP<int>((int)(g + 0.5), 0, 0xFF);
+										dst_bits[FI_RGBA_BLUE]	= (BYTE)CLAMP<int>((int)(b + 0.5), 0, 0xFF);
+										dst_bits += 3;
+									}
+								}
+							} else {
+								// we do not have a palette
+								for (unsigned y = 0; y < height; y++) {
+									// scale each row
+									const BYTE * const src_bits = FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x;
+									BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
+
+									for (unsigned x = 0; x < dst_width; x++) {
+										// loop through row
+										const unsigned iLeft = weightsTable.getLeftBoundary(x);    // retrieve left boundary
+										const unsigned iRight = weightsTable.getRightBoundary(x);  // retrieve right boundary
+										double value = 0;
+
+										for (unsigned i = iLeft; i < iRight; i++) {
+											// scan between boundaries
+											// accumulate weighted effect of each neighboring pixel
+											const unsigned pixel = (src_bits[i >> 3] & (0x80 >> (i & 0x07))) != 0;
+											value += (weightsTable.getWeight(x, i - iLeft) * (double)pixel);
+										}
+										value *= 0xFF;
+
+										// clamp and place result in destination pixel
+										const BYTE bval = (BYTE)CLAMP<int>((int)(value + 0.5), 0, 0xFF);
+										dst_bits[FI_RGBA_RED]	= bval;
+										dst_bits[FI_RGBA_GREEN]	= bval;
+										dst_bits[FI_RGBA_BLUE]	= bval;
+										dst_bits += 3;
+									}
+								}
+							}
+						}
+						break;
+
+						case 32:
+						{
+							// transparently convert the transparent 1-bit image to 32 bpp; 
+							// we always have got a palette here
+							src_offset_x >>= 3;
+
+							for (unsigned y = 0; y < height; y++) {
+								// scale each row
+								const BYTE * const src_bits = FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x;
+								BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
+
+								for (unsigned x = 0; x < dst_width; x++) {
+									// loop through row
+									const unsigned iLeft = weightsTable.getLeftBoundary(x);    // retrieve left boundary
+									const unsigned iRight = weightsTable.getRightBoundary(x);  // retrieve right boundary
+									double r = 0, g = 0, b = 0, a = 0;
+
+									for (unsigned i = iLeft; i < iRight; i++) {
+										// scan between boundaries
+										// accumulate weighted effect of each neighboring pixel
+										const double weight = weightsTable.getWeight(x, i - iLeft);
+										const unsigned pixel = (src_bits[i >> 3] & (0x80 >> (i & 0x07))) != 0;
+										const BYTE * const entry = (BYTE *)&src_pal[pixel];
+										r += (weight * (double)entry[FI_RGBA_RED]);
+										g += (weight * (double)entry[FI_RGBA_GREEN]);
+										b += (weight * (double)entry[FI_RGBA_BLUE]);
+										a += (weight * (double)entry[FI_RGBA_ALPHA]);
+									}
+
+									// clamp and place result in destination pixel
+									dst_bits[FI_RGBA_RED]	= (BYTE)CLAMP<int>((int)(r + 0.5), 0, 0xFF);
+									dst_bits[FI_RGBA_GREEN]	= (BYTE)CLAMP<int>((int)(g + 0.5), 0, 0xFF);
+									dst_bits[FI_RGBA_BLUE]	= (BYTE)CLAMP<int>((int)(b + 0.5), 0, 0xFF);
+									dst_bits[FI_RGBA_ALPHA]	= (BYTE)CLAMP<int>((int)(a + 0.5), 0, 0xFF);
+									dst_bits += 4;
+								}
+							}
+						}
+						break;
+					}
+				}
+				break;
+
+				case 4:
+				{
+					switch(FreeImage_GetBPP(dst)) {
+						case 8:
+						{
+							// transparently convert the non-transparent 4-bit greyscale image to 8 bpp; 
+							// we always have got a palette for 4-bit images
+							src_offset_x >>= 1;
+
+							for (unsigned y = 0; y < height; y++) {
+								// scale each row
+								const BYTE * const src_bits = FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x;
+								BYTE * const dst_bits = FreeImage_GetScanLine(dst, y);
+
+								for (unsigned x = 0; x < dst_width; x++) {
+									// loop through row
+									const unsigned iLeft = weightsTable.getLeftBoundary(x);    // retrieve left boundary
+									const unsigned iRight = weightsTable.getRightBoundary(x);  // retrieve right boundary
+									double value = 0;
+
+									for (unsigned i = iLeft; i < iRight; i++) {
+										// scan between boundaries
+										// accumulate weighted effect of each neighboring pixel
+										const unsigned pixel = i & 0x01 ? src_bits[i >> 1] & 0x0F : src_bits[i >> 1] >> 4;
+										value += (weightsTable.getWeight(x, i - iLeft) * (double)*(BYTE *)&src_pal[pixel]);
+									}
+
+									// clamp and place result in destination pixel
+									dst_bits[x] = (BYTE)CLAMP<int>((int)(value + 0.5), 0, 0xFF);
+								}
+							}
+						}
+						break;
+
+						case 24:
+						{
+							// transparently convert the non-transparent 4-bit image to 24 bpp; 
+							// we always have got a palette for 4-bit images
+							src_offset_x >>= 1;
+
+							for (unsigned y = 0; y < height; y++) {
+								// scale each row
+								const BYTE * const src_bits = FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x;
+								BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
+
+								for (unsigned x = 0; x < dst_width; x++) {
+									// loop through row
+									const unsigned iLeft = weightsTable.getLeftBoundary(x);    // retrieve left boundary
+									const unsigned iRight = weightsTable.getRightBoundary(x);  // retrieve right boundary
+									double r = 0, g = 0, b = 0;
+
+									for (unsigned i = iLeft; i < iRight; i++) {
+										// scan between boundaries
+										// accumulate weighted effect of each neighboring pixel
+										const double weight = weightsTable.getWeight(x, i - iLeft);
+										const unsigned pixel = i & 0x01 ? src_bits[i >> 1] & 0x0F : src_bits[i >> 1] >> 4;
+										const BYTE * const entry = (BYTE *)&src_pal[pixel];
+										r += (weight * (double)entry[FI_RGBA_RED]);
+										g += (weight * (double)entry[FI_RGBA_GREEN]);
+										b += (weight * (double)entry[FI_RGBA_BLUE]);
+									}
+
+									// clamp and place result in destination pixel
+									dst_bits[FI_RGBA_RED]	= (BYTE)CLAMP<int>((int)(r + 0.5), 0, 0xFF);
+									dst_bits[FI_RGBA_GREEN]	= (BYTE)CLAMP<int>((int)(g + 0.5), 0, 0xFF);
+									dst_bits[FI_RGBA_BLUE]	= (BYTE)CLAMP<int>((int)(b + 0.5), 0, 0xFF);
+									dst_bits += 3;
+								}
+							}
+						}
+						break;
+
+						case 32:
+						{
+							// transparently convert the transparent 4-bit image to 32 bpp; 
+							// we always have got a palette for 4-bit images
+							src_offset_x >>= 1;
+
+							for (unsigned y = 0; y < height; y++) {
+								// scale each row
+								const BYTE * const src_bits = FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x;
+								BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
+
+								for (unsigned x = 0; x < dst_width; x++) {
+									// loop through row
+									const unsigned iLeft = weightsTable.getLeftBoundary(x);    // retrieve left boundary
+									const unsigned iRight = weightsTable.getRightBoundary(x);  // retrieve right boundary
+									double r = 0, g = 0, b = 0, a = 0;
+
+									for (unsigned i = iLeft; i < iRight; i++) {
+										// scan between boundaries
+										// accumulate weighted effect of each neighboring pixel
+										const double weight = weightsTable.getWeight(x, i - iLeft);
+										const unsigned pixel = i & 0x01 ? src_bits[i >> 1] & 0x0F : src_bits[i >> 1] >> 4;
+										const BYTE * const entry = (BYTE *)&src_pal[pixel];
+										r += (weight * (double)entry[FI_RGBA_RED]);
+										g += (weight * (double)entry[FI_RGBA_GREEN]);
+										b += (weight * (double)entry[FI_RGBA_BLUE]);
+										a += (weight * (double)entry[FI_RGBA_ALPHA]);
+									}
+
+									// clamp and place result in destination pixel
+									dst_bits[FI_RGBA_RED]	= (BYTE)CLAMP<int>((int)(r + 0.5), 0, 0xFF);
+									dst_bits[FI_RGBA_GREEN]	= (BYTE)CLAMP<int>((int)(g + 0.5), 0, 0xFF);
+									dst_bits[FI_RGBA_BLUE]	= (BYTE)CLAMP<int>((int)(b + 0.5), 0, 0xFF);
+									dst_bits[FI_RGBA_ALPHA]	= (BYTE)CLAMP<int>((int)(a + 0.5), 0, 0xFF);
+									dst_bits += 4;
+								}
+							}
+						}
+						break;
+					}
+				}
+				break;
+
+				case 8:
+				{
+					switch(FreeImage_GetBPP(dst)) {
+						case 8:
+						{
+							// scale the 8-bit non-transparent greyscale image
+							// into an 8 bpp destination image
+							if (src_pal) {
+								// we have got a palette
+								for (unsigned y = 0; y < height; y++) {
+									// scale each row
+									const BYTE * const src_bits = FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x;
+									BYTE * const dst_bits = FreeImage_GetScanLine(dst, y);
+
+									for (unsigned x = 0; x < dst_width; x++) {
+										// loop through row
+										const unsigned iLeft = weightsTable.getLeftBoundary(x);				// retrieve left boundary
+										const unsigned iLimit = weightsTable.getRightBoundary(x) - iLeft;	// retrieve right boundary
+										const BYTE * const pixel = src_bits + iLeft;
+										double value = 0;
+
+										// for(i = iLeft to iRight)
+										for (unsigned i = 0; i < iLimit; i++) {
+											// scan between boundaries
+											// accumulate weighted effect of each neighboring pixel
+											value += (weightsTable.getWeight(x, i) * (double)*(BYTE *)&src_pal[pixel[i]]);
+										}
+
+										// clamp and place result in destination pixel
+										dst_bits[x] = (BYTE)CLAMP<int>((int)(value + 0.5), 0, 0xFF);
+									}
+								}
+							} else {
+								// we do not have a palette
+								for (unsigned y = 0; y < height; y++) {
+									// scale each row
+									const BYTE * const src_bits = FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x;
+									BYTE * const dst_bits = FreeImage_GetScanLine(dst, y);
+
+									for (unsigned x = 0; x < dst_width; x++) {
+										// loop through row
+										const unsigned iLeft = weightsTable.getLeftBoundary(x);				// retrieve left boundary
+										const unsigned iLimit = weightsTable.getRightBoundary(x) - iLeft;	// retrieve right boundary
+										const BYTE * const pixel = src_bits + iLeft;
+										double value = 0;
+
+										// for(i = iLeft to iRight)
+										for (unsigned i = 0; i < iLimit; i++) {
+											// scan between boundaries
+											// accumulate weighted effect of each neighboring pixel
+											value += (weightsTable.getWeight(x, i) * (double)pixel[i]);
+										}
+
+										// clamp and place result in destination pixel
+										dst_bits[x] = (BYTE)CLAMP<int>((int)(value + 0.5), 0, 0xFF);
+									}
+								}
+							}
+						}
+						break;
+
+						case 24:
+						{
+							// transparently convert the non-transparent 8-bit image to 24 bpp
+							if (src_pal) {
+								// we have got a palette
+								for (unsigned y = 0; y < height; y++) {
+									// scale each row
+									const BYTE * const src_bits = FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x;
+									BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
+
+									for (unsigned x = 0; x < dst_width; x++) {
+										// loop through row
+										const unsigned iLeft = weightsTable.getLeftBoundary(x);				// retrieve left boundary
+										const unsigned iLimit = weightsTable.getRightBoundary(x) - iLeft;	// retrieve right boundary
+										const BYTE * const pixel = src_bits + iLeft;
+										double r = 0, g = 0, b = 0;
+
+										// for(i = iLeft to iRight)
+										for (unsigned i = 0; i < iLimit; i++) {
+											// scan between boundaries
+											// accumulate weighted effect of each neighboring pixel
+											const double weight = weightsTable.getWeight(x, i);
+											const BYTE *const entry = (BYTE *)&src_pal[pixel[i]];
+											r += (weight * (double)entry[FI_RGBA_RED]);
+											g += (weight * (double)entry[FI_RGBA_GREEN]);
+											b += (weight * (double)entry[FI_RGBA_BLUE]);
+										}
+
+										// clamp and place result in destination pixel
+										dst_bits[FI_RGBA_RED]	= (BYTE)CLAMP<int>((int)(r + 0.5), 0, 0xFF);
+										dst_bits[FI_RGBA_GREEN]	= (BYTE)CLAMP<int>((int)(g + 0.5), 0, 0xFF);
+										dst_bits[FI_RGBA_BLUE]	= (BYTE)CLAMP<int>((int)(b + 0.5), 0, 0xFF);
+										dst_bits += 3;
+									}
+								}
+							} else {
+								// we do not have a palette
+								for (unsigned y = 0; y < height; y++) {
+									// scale each row
+									const BYTE * const src_bits = FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x;
+									BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
+
+									for (unsigned x = 0; x < dst_width; x++) {
+										// loop through row
+										const unsigned iLeft = weightsTable.getLeftBoundary(x);				// retrieve left boundary
+										const unsigned iLimit = weightsTable.getRightBoundary(x) - iLeft;	// retrieve right boundary
+										const BYTE * const pixel = src_bits + iLeft;
+										double value = 0;
+
+										// for(i = iLeft to iRight)
+										for (unsigned i = 0; i < iLimit; i++) {
+											// scan between boundaries
+											// accumulate weighted effect of each neighboring pixel
+											const double weight = weightsTable.getWeight(x, i);
+											value += (weight * (double)pixel[i]);
+										}
+
+										// clamp and place result in destination pixel
+										const BYTE bval = (BYTE)CLAMP<int>((int)(value + 0.5), 0, 0xFF);
+										dst_bits[FI_RGBA_RED]	= bval;
+										dst_bits[FI_RGBA_GREEN]	= bval;
+										dst_bits[FI_RGBA_BLUE]	= bval;
+										dst_bits += 3;
+									}
+								}
+							}
+						}
+						break;
+
+						case 32:
+						{
+							// transparently convert the transparent 8-bit image to 32 bpp; 
+							// we always have got a palette here
+							for (unsigned y = 0; y < height; y++) {
+								// scale each row
+								const BYTE * const src_bits = FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x;
+								BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
+
+								for (unsigned x = 0; x < dst_width; x++) {
+									// loop through row
+									const unsigned iLeft = weightsTable.getLeftBoundary(x);				// retrieve left boundary
+									const unsigned iLimit = weightsTable.getRightBoundary(x) - iLeft;	// retrieve right boundary
+									const BYTE * const pixel = src_bits + iLeft;
+									double r = 0, g = 0, b = 0, a = 0;
+
+									// for(i = iLeft to iRight)
+									for (unsigned i = 0; i < iLimit; i++) {
+										// scan between boundaries
+										// accumulate weighted effect of each neighboring pixel
+										const double weight = weightsTable.getWeight(x, i);
+										const BYTE * const entry = (BYTE *)&src_pal[pixel[i]];
+										r += (weight * (double)entry[FI_RGBA_RED]);
+										g += (weight * (double)entry[FI_RGBA_GREEN]);
+										b += (weight * (double)entry[FI_RGBA_BLUE]);
+										a += (weight * (double)entry[FI_RGBA_ALPHA]);
+									}
+
+									// clamp and place result in destination pixel
+									dst_bits[FI_RGBA_RED]	= (BYTE)CLAMP<int>((int)(r + 0.5), 0, 0xFF);
+									dst_bits[FI_RGBA_GREEN]	= (BYTE)CLAMP<int>((int)(g + 0.5), 0, 0xFF);
+									dst_bits[FI_RGBA_BLUE]	= (BYTE)CLAMP<int>((int)(b + 0.5), 0, 0xFF);
+									dst_bits[FI_RGBA_ALPHA]	= (BYTE)CLAMP<int>((int)(a + 0.5), 0, 0xFF);
+									dst_bits += 4;
+								}
+							}
+						}
+						break;
+					}
+				}
+				break;
+
+				case 16:
+				{
+					// transparently convert the 16-bit non-transparent image to 24 bpp
+					if (IS_FORMAT_RGB565(src)) {
+						// image has 565 format
+						for (unsigned y = 0; y < height; y++) {
+							// scale each row
+							const WORD * const src_bits = (WORD *)FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x / sizeof(WORD);
+							BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
+
+							for (unsigned x = 0; x < dst_width; x++) {
+								// loop through row
+								const unsigned iLeft = weightsTable.getLeftBoundary(x);				// retrieve left boundary
+								const unsigned iLimit = weightsTable.getRightBoundary(x) - iLeft;	// retrieve right boundary
+								const WORD *pixel = src_bits + iLeft;
+								double r = 0, g = 0, b = 0;
+
+								// for(i = iLeft to iRight)
+								for (unsigned i = 0; i < iLimit; i++) {
+									// scan between boundaries
+									// accumulate weighted effect of each neighboring pixel
+									const double weight = weightsTable.getWeight(x, i);
+									r += (weight * (double)((*pixel & FI16_565_RED_MASK) >> FI16_565_RED_SHIFT));
+									g += (weight * (double)((*pixel & FI16_565_GREEN_MASK) >> FI16_565_GREEN_SHIFT));
+									b += (weight * (double)((*pixel & FI16_565_BLUE_MASK) >> FI16_565_BLUE_SHIFT));
+									pixel++;
+								}
+
+								// clamp and place result in destination pixel
+								dst_bits[FI_RGBA_RED]	= (BYTE)CLAMP<int>((int)(((r * 0xFF) / 0x1F) + 0.5), 0, 0xFF);
+								dst_bits[FI_RGBA_GREEN]	= (BYTE)CLAMP<int>((int)(((g * 0xFF) / 0x3F) + 0.5), 0, 0xFF);
+								dst_bits[FI_RGBA_BLUE]	= (BYTE)CLAMP<int>((int)(((b * 0xFF) / 0x1F) + 0.5), 0, 0xFF);
+								dst_bits += 3;
+							}
+						}
+					} else {
+						// image has 555 format
+						for (unsigned y = 0; y < height; y++) {
+							// scale each row
+							const WORD * const src_bits = (WORD *)FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x;
+							BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
+
+							for (unsigned x = 0; x < dst_width; x++) {
+								// loop through row
+								const unsigned iLeft = weightsTable.getLeftBoundary(x);				// retrieve left boundary
+								const unsigned iLimit = weightsTable.getRightBoundary(x) - iLeft;	// retrieve right boundary
+								const WORD *pixel = src_bits + iLeft;
+								double r = 0, g = 0, b = 0;
+
+								// for(i = iLeft to iRight)
+								for (unsigned i = 0; i < iLimit; i++) {
+									// scan between boundaries
+									// accumulate weighted effect of each neighboring pixel
+									const double weight = weightsTable.getWeight(x, i);
+									r += (weight * (double)((*pixel & FI16_555_RED_MASK) >> FI16_555_RED_SHIFT));
+									g += (weight * (double)((*pixel & FI16_555_GREEN_MASK) >> FI16_555_GREEN_SHIFT));
+									b += (weight * (double)((*pixel & FI16_555_BLUE_MASK) >> FI16_555_BLUE_SHIFT));
+									pixel++;
+								}
+
+								// clamp and place result in destination pixel
+								dst_bits[FI_RGBA_RED]	= (BYTE)CLAMP<int>((int)(((r * 0xFF) / 0x1F) + 0.5), 0, 0xFF);
+								dst_bits[FI_RGBA_GREEN]	= (BYTE)CLAMP<int>((int)(((g * 0xFF) / 0x1F) + 0.5), 0, 0xFF);
+								dst_bits[FI_RGBA_BLUE]	= (BYTE)CLAMP<int>((int)(((b * 0xFF) / 0x1F) + 0.5), 0, 0xFF);
+								dst_bits += 3;
+							}
+						}
+					}
+				}
+				break;
+
+				case 24:
+				{
+					// scale the 24-bit non-transparent image into a 24 bpp destination image
+					for (unsigned y = 0; y < height; y++) {
+						// scale each row
+						const BYTE * const src_bits = FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x * 3;
+						BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
+
+						for (unsigned x = 0; x < dst_width; x++) {
+							// loop through row
+							const unsigned iLeft = weightsTable.getLeftBoundary(x);				// retrieve left boundary
+							const unsigned iLimit = weightsTable.getRightBoundary(x) - iLeft;	// retrieve right boundary
+							const BYTE * pixel = src_bits + iLeft * 3;
+							double r = 0, g = 0, b = 0;
+
+							// for(i = iLeft to iRight)
+							for (unsigned i = 0; i < iLimit; i++) {
+								// scan between boundaries
+								// accumulate weighted effect of each neighboring pixel
+								const double weight = weightsTable.getWeight(x, i);
+								r += (weight * (double)pixel[FI_RGBA_RED]);
+								g += (weight * (double)pixel[FI_RGBA_GREEN]);
+								b += (weight * (double)pixel[FI_RGBA_BLUE]);
+								pixel += 3;
+							}
+
+							// clamp and place result in destination pixel
+							dst_bits[FI_RGBA_RED]	= (BYTE)CLAMP<int>((int)(r + 0.5), 0, 0xFF);
+							dst_bits[FI_RGBA_GREEN]	= (BYTE)CLAMP<int>((int)(g + 0.5), 0, 0xFF);
+							dst_bits[FI_RGBA_BLUE]	= (BYTE)CLAMP<int>((int)(b + 0.5), 0, 0xFF);
+							dst_bits += 3;
+						}
+					}
+				}
+				break;
+
+				case 32:
+				{
+					// scale the 32-bit transparent image into a 32 bpp destination image
+					for (unsigned y = 0; y < height; y++) {
+						// scale each row
+						const BYTE * const src_bits = FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x * 4;
+						BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
+
+						for (unsigned x = 0; x < dst_width; x++) {
+							// loop through row
+							const unsigned iLeft = weightsTable.getLeftBoundary(x);				// retrieve left boundary
+							const unsigned iLimit = weightsTable.getRightBoundary(x) - iLeft;	// retrieve right boundary
+							const BYTE *pixel = src_bits + iLeft * 4;
+							double r = 0, g = 0, b = 0, a = 0;
+
+							// for(i = iLeft to iRight)
+							for (unsigned i = 0; i < iLimit; i++) {
+								// scan between boundaries
+								// accumulate weighted effect of each neighboring pixel
+								const double weight = weightsTable.getWeight(x, i);
+								r += (weight * (double)pixel[FI_RGBA_RED]);
+								g += (weight * (double)pixel[FI_RGBA_GREEN]);
+								b += (weight * (double)pixel[FI_RGBA_BLUE]);
+								a += (weight * (double)pixel[FI_RGBA_ALPHA]);
+								pixel += 4;
+							}
+
+							// clamp and place result in destination pixel
+							dst_bits[FI_RGBA_RED]	= (BYTE)CLAMP<int>((int)(r + 0.5), 0, 0xFF);
+							dst_bits[FI_RGBA_GREEN]	= (BYTE)CLAMP<int>((int)(g + 0.5), 0, 0xFF);
+							dst_bits[FI_RGBA_BLUE]	= (BYTE)CLAMP<int>((int)(b + 0.5), 0, 0xFF);
+							dst_bits[FI_RGBA_ALPHA]	= (BYTE)CLAMP<int>((int)(a + 0.5), 0, 0xFF);
+							dst_bits += 4;
+						}
+					}
+				}
+				break;
+			}
+		}
+		break;
+
+		case FIT_UINT16:
+		{
+			// Calculate the number of words per pixel (1 for 16-bit, 3 for 48-bit or 4 for 64-bit)
+			const unsigned wordspp = (FreeImage_GetLine(src) / src_width) / sizeof(WORD);
+
+			for (unsigned y = 0; y < height; y++) {
+				// scale each row
+				const WORD *src_bits = (WORD*)FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x / sizeof(WORD);
+				WORD *dst_bits = (WORD*)FreeImage_GetScanLine(dst, y);
+
+				for (unsigned x = 0; x < dst_width; x++) {
+					// loop through row
+					const unsigned iLeft = weightsTable.getLeftBoundary(x);				// retrieve left boundary
+					const unsigned iLimit = weightsTable.getRightBoundary(x) - iLeft;	// retrieve right boundary
+					const WORD *pixel = src_bits + iLeft * wordspp;
+					double value = 0;
+
+					// for(i = iLeft to iRight)
+					for (unsigned i = 0; i < iLimit; i++) {
+						// scan between boundaries
+						// accumulate weighted effect of each neighboring pixel
+						const double weight = weightsTable.getWeight(x, i);						
+						value += (weight * (double)pixel[0]);
+						pixel++;
+					}
+
+					// clamp and place result in destination pixel
+					dst_bits[0] = (WORD)CLAMP<int>((int)(value + 0.5), 0, 0xFFFF);
+					dst_bits += wordspp;
+				}
+			}
+		}
+		break;
+
+		case FIT_RGB16:
+		{
+			// Calculate the number of words per pixel (1 for 16-bit, 3 for 48-bit or 4 for 64-bit)
+			const unsigned wordspp = (FreeImage_GetLine(src) / src_width) / sizeof(WORD);
+
+			for (unsigned y = 0; y < height; y++) {
+				// scale each row
+				const WORD *src_bits = (WORD*)FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x / sizeof(WORD);
+				WORD *dst_bits = (WORD*)FreeImage_GetScanLine(dst, y);
+
+				for (unsigned x = 0; x < dst_width; x++) {
+					// loop through row
+					const unsigned iLeft = weightsTable.getLeftBoundary(x);				// retrieve left boundary
+					const unsigned iLimit = weightsTable.getRightBoundary(x) - iLeft;	// retrieve right boundary
+					const WORD *pixel = src_bits + iLeft * wordspp;
+					double r = 0, g = 0, b = 0;
+
+					// for(i = iLeft to iRight)
+					for (unsigned i = 0; i < iLimit; i++) {
+						// scan between boundaries
+						// accumulate weighted effect of each neighboring pixel
+						const double weight = weightsTable.getWeight(x, i);						
+						r += (weight * (double)pixel[0]);
+						g += (weight * (double)pixel[1]);
+						b += (weight * (double)pixel[2]);
+						pixel += wordspp;
+					}
+
+					// clamp and place result in destination pixel
+					dst_bits[0] = (WORD)CLAMP<int>((int)(r + 0.5), 0, 0xFFFF);
+					dst_bits[1] = (WORD)CLAMP<int>((int)(g + 0.5), 0, 0xFFFF);
+					dst_bits[2] = (WORD)CLAMP<int>((int)(b + 0.5), 0, 0xFFFF);
+					dst_bits += wordspp;
+				}
+			}
+		}
+		break;
+
+		case FIT_RGBA16:
+		{
+			// Calculate the number of words per pixel (1 for 16-bit, 3 for 48-bit or 4 for 64-bit)
+			const unsigned wordspp = (FreeImage_GetLine(src) / src_width) / sizeof(WORD);
+
+			for (unsigned y = 0; y < height; y++) {
+				// scale each row
+				const WORD *src_bits = (WORD*)FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x / sizeof(WORD);
+				WORD *dst_bits = (WORD*)FreeImage_GetScanLine(dst, y);
+
+				for (unsigned x = 0; x < dst_width; x++) {
+					// loop through row
+					const unsigned iLeft = weightsTable.getLeftBoundary(x);				// retrieve left boundary
+					const unsigned iLimit = weightsTable.getRightBoundary(x) - iLeft;	// retrieve right boundary
+					const WORD *pixel = src_bits + iLeft * wordspp;
+					double r = 0, g = 0, b = 0, a = 0;
+
+					// for(i = iLeft to iRight)
+					for (unsigned i = 0; i < iLimit; i++) {
+						// scan between boundaries
+						// accumulate weighted effect of each neighboring pixel
+						const double weight = weightsTable.getWeight(x, i);						
+						r += (weight * (double)pixel[0]);
+						g += (weight * (double)pixel[1]);
+						b += (weight * (double)pixel[2]);
+						a += (weight * (double)pixel[3]);
+						pixel += wordspp;
+					}
+
+					// clamp and place result in destination pixel
+					dst_bits[0] = (WORD)CLAMP<int>((int)(r + 0.5), 0, 0xFFFF);
+					dst_bits[1] = (WORD)CLAMP<int>((int)(g + 0.5), 0, 0xFFFF);
+					dst_bits[2] = (WORD)CLAMP<int>((int)(b + 0.5), 0, 0xFFFF);
+					dst_bits[3] = (WORD)CLAMP<int>((int)(a + 0.5), 0, 0xFFFF);
+					dst_bits += wordspp;
+				}
+			}
+		}
+		break;
+
+		case FIT_FLOAT:
+		case FIT_RGBF:
+		case FIT_RGBAF:
+		{
+			// Calculate the number of floats per pixel (1 for 32-bit, 3 for 96-bit or 4 for 128-bit)
+			const unsigned floatspp = (FreeImage_GetLine(src) / src_width) / sizeof(float);
+
+			for(unsigned y = 0; y < height; y++) {
+				// scale each row
+				const float *src_bits = (float*)FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x / sizeof(float);
+				float *dst_bits = (float*)FreeImage_GetScanLine(dst, y);
+
+				for(unsigned x = 0; x < dst_width; x++) {
+					// loop through row
+					const unsigned iLeft = weightsTable.getLeftBoundary(x);    // retrieve left boundary
+					const unsigned iRight = weightsTable.getRightBoundary(x);  // retrieve right boundary
+					double value[4] = {0, 0, 0, 0};                            // 4 = 128 bpp max
+
+					for(unsigned i = iLeft; i < iRight; i++) {
+						// scan between boundaries
+						// accumulate weighted effect of each neighboring pixel
+						const double weight = weightsTable.getWeight(x, i-iLeft);
+
+						unsigned index = i * floatspp;	// pixel index
+						for (unsigned j = 0; j < floatspp; j++) {
+							value[j] += (weight * (double)src_bits[index++]);
+						}
+					}
+
+					// place result in destination pixel
+					for (unsigned j = 0; j < floatspp; j++) {
+						dst_bits[j] = (float)value[j];
+					}
+
+					dst_bits += floatspp;
+				}
+			}
+		}
+		break;
+	}
+}
+
+/// Performs vertical image filtering
+void CResizeEngine::verticalFilter(FIBITMAP *const src, unsigned width, unsigned src_height, unsigned src_offset_x, unsigned src_offset_y, const RGBQUAD *const src_pal, FIBITMAP *const dst, unsigned dst_height) {
+
+	// allocate and calculate the contributions
+	CWeightsTable weightsTable(m_pFilter, dst_height, src_height);
+
+	// step through columns
+	switch(FreeImage_GetImageType(src)) {
+		case FIT_BITMAP:
+		{
+			const unsigned dst_pitch = FreeImage_GetPitch(dst);
+			BYTE * const dst_base = FreeImage_GetBits(dst);
+
+			switch(FreeImage_GetBPP(src)) {
+				case 1:
+				{
+					const unsigned src_pitch = FreeImage_GetPitch(src);
+					const BYTE * const src_base = FreeImage_GetBits(src) + src_offset_y * src_pitch + (src_offset_x >> 3);
+
+					switch(FreeImage_GetBPP(dst)) {
+						case 8:
+						{
+							// transparently convert the 1-bit non-transparent greyscale image to 8 bpp
+							if (src_pal) {
+								// we have got a palette
+								for (unsigned x = 0; x < width; x++) {
+									// work on column x in dst
+									BYTE *dst_bits = dst_base + x;
+									const unsigned index = x >> 3;
+									const unsigned mask = 0x80 >> (x & 0x07);
+
+									// scale each column
+									for (unsigned y = 0; y < dst_height; y++) {
+										// loop through column
+										const unsigned iLeft = weightsTable.getLeftBoundary(y);				// retrieve left boundary
+										const unsigned iLimit = weightsTable.getRightBoundary(y) - iLeft;	// retrieve right boundary
+										const BYTE *src_bits = src_base + iLeft * src_pitch + index;
+										double value = 0;
+
+										for (unsigned i = 0; i < iLimit; i++) {
+											// scan between boundaries
+											// accumulate weighted effect of each neighboring pixel
+											const unsigned pixel = (*src_bits & mask) != 0;
+											value += (weightsTable.getWeight(y, i) * (double)*(BYTE *)&src_pal[pixel]);
+											src_bits += src_pitch;
+										}
+										value *= 0xFF;
+
+										// clamp and place result in destination pixel
+										*dst_bits = (BYTE)CLAMP<int>((int)(value + 0.5), 0, 0xFF);
+										dst_bits += dst_pitch;
+									}
+								}
+							} else {
+								// we do not have a palette
+								for (unsigned x = 0; x < width; x++) {
+									// work on column x in dst
+									BYTE *dst_bits = dst_base + x;
+									const unsigned index = x >> 3;
+									const unsigned mask = 0x80 >> (x & 0x07);
+
+									// scale each column
+									for (unsigned y = 0; y < dst_height; y++) {
+										// loop through column
+										const unsigned iLeft = weightsTable.getLeftBoundary(y);				// retrieve left boundary
+										const unsigned iLimit = weightsTable.getRightBoundary(y) - iLeft;	// retrieve right boundary
+										const BYTE *src_bits = src_base + iLeft * src_pitch + index;
+										double value = 0;
+
+										for (unsigned i = 0; i < iLimit; i++) {
+											// scan between boundaries
+											// accumulate weighted effect of each neighboring pixel
+											value += (weightsTable.getWeight(y, i) * (double)((*src_bits & mask) != 0));
+											src_bits += src_pitch;
+										}
+										value *= 0xFF;
+
+										// clamp and place result in destination pixel
+										*dst_bits = (BYTE)CLAMP<int>((int)(value + 0.5), 0, 0xFF);
+										dst_bits += dst_pitch;
+									}
+								}
+							}
+						}
+						break;
+
+						case 24:
+						{
+							// transparently convert the non-transparent 1-bit image to 24 bpp
+							if (src_pal) {
+								// we have got a palette
+								for (unsigned x = 0; x < width; x++) {
+									// work on column x in dst
+									BYTE *dst_bits = dst_base + x * 3;
+									const unsigned index = x >> 3;
+									const unsigned mask = 0x80 >> (x & 0x07);
+
+									// scale each column
+									for (unsigned y = 0; y < dst_height; y++) {
+										// loop through column
+										const unsigned iLeft = weightsTable.getLeftBoundary(y);				// retrieve left boundary
+										const unsigned iLimit = weightsTable.getRightBoundary(y) - iLeft;	// retrieve right boundary
+										const BYTE *src_bits = src_base + iLeft * src_pitch + index;
+										double r = 0, g = 0, b = 0;
+
+										for (unsigned i = 0; i < iLimit; i++) {
+											// scan between boundaries
+											// accumulate weighted effect of each neighboring pixel
+											const double weight = weightsTable.getWeight(y, i);
+											const unsigned pixel = (*src_bits & mask) != 0;
+											const BYTE * const entry = (BYTE *)&src_pal[pixel];
+											r += (weight * (double)entry[FI_RGBA_RED]);
+											g += (weight * (double)entry[FI_RGBA_GREEN]);
+											b += (weight * (double)entry[FI_RGBA_BLUE]);
+											src_bits += src_pitch;
+										}
+
+										// clamp and place result in destination pixel
+										dst_bits[FI_RGBA_RED]	= (BYTE)CLAMP<int>((int)(r + 0.5), 0, 0xFF);
+										dst_bits[FI_RGBA_GREEN]	= (BYTE)CLAMP<int>((int)(g + 0.5), 0, 0xFF);
+										dst_bits[FI_RGBA_BLUE]	= (BYTE)CLAMP<int>((int)(b + 0.5), 0, 0xFF);
+										dst_bits += dst_pitch;
+									}
+								}
+							} else {
+								// we do not have a palette
+								for (unsigned x = 0; x < width; x++) {
+									// work on column x in dst
+									BYTE *dst_bits = dst_base + x * 3;
+									const unsigned index = x >> 3;
+									const unsigned mask = 0x80 >> (x & 0x07);
+
+									// scale each column
+									for (unsigned y = 0; y < dst_height; y++) {
+										// loop through column
+										const unsigned iLeft = weightsTable.getLeftBoundary(y);				// retrieve left boundary
+										const unsigned iLimit = weightsTable.getRightBoundary(y) - iLeft;	// retrieve right boundary
+										const BYTE *src_bits = src_base + iLeft * src_pitch + index;
+										double value = 0;
+
+										for (unsigned i = 0; i < iLimit; i++) {
+											// scan between boundaries
+											// accumulate weighted effect of each neighboring pixel
+											value += (weightsTable.getWeight(y, i) * (double)((*src_bits & mask) != 0));
+											src_bits += src_pitch;
+										}
+										value *= 0xFF;
+
+										// clamp and place result in destination pixel
+										const BYTE bval = (BYTE)CLAMP<int>((int)(value + 0.5), 0, 0xFF);
+										dst_bits[FI_RGBA_RED]	= bval;
+										dst_bits[FI_RGBA_GREEN]	= bval;
+										dst_bits[FI_RGBA_BLUE]	= bval;
+										dst_bits += dst_pitch;
+									}
+								}
+							}
+						}
+						break;
+
+						case 32:
+						{
+							// transparently convert the transparent 1-bit image to 32 bpp; 
+							// we always have got a palette here
+							for (unsigned x = 0; x < width; x++) {
+								// work on column x in dst
+								BYTE *dst_bits = dst_base + x * 4;
+								const unsigned index = x >> 3;
+								const unsigned mask = 0x80 >> (x & 0x07);
+
+								// scale each column
+								for (unsigned y = 0; y < dst_height; y++) {
+									// loop through column
+									const unsigned iLeft = weightsTable.getLeftBoundary(y);				// retrieve left boundary
+									const unsigned iLimit = weightsTable.getRightBoundary(y) - iLeft;	// retrieve right boundary
+									const BYTE *src_bits = src_base + iLeft * src_pitch + index;
+									double r = 0, g = 0, b = 0, a = 0;
+
+									for (unsigned i = 0; i < iLimit; i++) {
+										// scan between boundaries
+										// accumulate weighted effect of each neighboring pixel
+										const double weight = weightsTable.getWeight(y, i);
+										const unsigned pixel = (*src_bits & mask) != 0;
+										const BYTE * const entry = (BYTE *)&src_pal[pixel];
+										r += (weight * (double)entry[FI_RGBA_RED]);
+										g += (weight * (double)entry[FI_RGBA_GREEN]);
+										b += (weight * (double)entry[FI_RGBA_BLUE]);
+										a += (weight * (double)entry[FI_RGBA_ALPHA]);
+										src_bits += src_pitch;
+									}
+
+									// clamp and place result in destination pixel
+									dst_bits[FI_RGBA_RED]	= (BYTE)CLAMP<int>((int)(r + 0.5), 0, 0xFF);
+									dst_bits[FI_RGBA_GREEN]	= (BYTE)CLAMP<int>((int)(g + 0.5), 0, 0xFF);
+									dst_bits[FI_RGBA_BLUE]	= (BYTE)CLAMP<int>((int)(b + 0.5), 0, 0xFF);
+									dst_bits[FI_RGBA_ALPHA]	= (BYTE)CLAMP<int>((int)(a + 0.5), 0, 0xFF);
+									dst_bits += dst_pitch;
+								}
+							}
+						}
+						break;
+					}
+				}
+				break;
+
+				case 4:
+				{
+					const unsigned src_pitch = FreeImage_GetPitch(src);
+					const BYTE *const src_base = FreeImage_GetBits(src) + src_offset_y * src_pitch + (src_offset_x >> 1);
+
+					switch(FreeImage_GetBPP(dst)) {
+						case 8:
+						{
+							// transparently convert the non-transparent 4-bit greyscale image to 8 bpp; 
+							// we always have got a palette for 4-bit images
+							for (unsigned x = 0; x < width; x++) {
+								// work on column x in dst
+								BYTE *dst_bits = dst_base + x;
+								const unsigned index = x >> 1;
+
+								// scale each column
+								for (unsigned y = 0; y < dst_height; y++) {
+									// loop through column
+									const unsigned iLeft = weightsTable.getLeftBoundary(y);				// retrieve left boundary
+									const unsigned iLimit = weightsTable.getRightBoundary(y) - iLeft;	// retrieve right boundary
+									const BYTE *src_bits = src_base + iLeft * src_pitch + index;
+									double value = 0;
+
+									for (unsigned i = 0; i < iLimit; i++) {
+										// scan between boundaries
+										// accumulate weighted effect of each neighboring pixel
+										const unsigned pixel = x & 0x01 ? *src_bits & 0x0F : *src_bits >> 4;
+										value += (weightsTable.getWeight(y, i) * (double)*(BYTE *)&src_pal[pixel]);
+										src_bits += src_pitch;
+									}
+
+									// clamp and place result in destination pixel
+									*dst_bits = (BYTE)CLAMP<int>((int)(value + 0.5), 0, 0xFF);
+									dst_bits += dst_pitch;
+								}
+							}
+						}
+						break;
+
+						case 24:
+						{
+							// transparently convert the non-transparent 4-bit image to 24 bpp; 
+							// we always have got a palette for 4-bit images
+							for (unsigned x = 0; x < width; x++) {
+								// work on column x in dst
+								BYTE *dst_bits = dst_base + x * 3;
+								const unsigned index = x >> 1;
+
+								// scale each column
+								for (unsigned y = 0; y < dst_height; y++) {
+									// loop through column
+									const unsigned iLeft = weightsTable.getLeftBoundary(y);				// retrieve left boundary
+									const unsigned iLimit = weightsTable.getRightBoundary(y) - iLeft;	// retrieve right boundary
+									const BYTE *src_bits = src_base + iLeft * src_pitch + index;
+									double r = 0, g = 0, b = 0;
+
+									for (unsigned i = 0; i < iLimit; i++) {
+										// scan between boundaries
+										// accumulate weighted effect of each neighboring pixel
+										const double weight = weightsTable.getWeight(y, i);
+										const unsigned pixel = x & 0x01 ? *src_bits & 0x0F : *src_bits >> 4;
+										const BYTE *const entry = (BYTE *)&src_pal[pixel];
+										r += (weight * (double)entry[FI_RGBA_RED]);
+										g += (weight * (double)entry[FI_RGBA_GREEN]);
+										b += (weight * (double)entry[FI_RGBA_BLUE]);
+										src_bits += src_pitch;
+									}
+
+									// clamp and place result in destination pixel
+									dst_bits[FI_RGBA_RED]	= (BYTE)CLAMP<int>((int)(r + 0.5), 0, 0xFF);
+									dst_bits[FI_RGBA_GREEN]	= (BYTE)CLAMP<int>((int)(g + 0.5), 0, 0xFF);
+									dst_bits[FI_RGBA_BLUE]	= (BYTE)CLAMP<int>((int)(b + 0.5), 0, 0xFF);
+									dst_bits += dst_pitch;
+								}
+							}
+						}
+						break;
+
+						case 32:
+						{
+							// transparently convert the transparent 4-bit image to 32 bpp; 
+							// we always have got a palette for 4-bit images
+							for (unsigned x = 0; x < width; x++) {
+								// work on column x in dst
+								BYTE *dst_bits = dst_base + x * 4;
+								const unsigned index = x >> 1;
+
+								// scale each column
+								for (unsigned y = 0; y < dst_height; y++) {
+									// loop through column
+									const unsigned iLeft = weightsTable.getLeftBoundary(y);				// retrieve left boundary
+									const unsigned iLimit = weightsTable.getRightBoundary(y) - iLeft;	// retrieve right boundary
+									const BYTE *src_bits = src_base + iLeft * src_pitch + index;
+									double r = 0, g = 0, b = 0, a = 0;
+
+									for (unsigned i = 0; i < iLimit; i++) {
+										// scan between boundaries
+										// accumulate weighted effect of each neighboring pixel
+										const double weight = weightsTable.getWeight(y, i);
+										const unsigned pixel = x & 0x01 ? *src_bits & 0x0F : *src_bits >> 4;
+										const BYTE *const entry = (BYTE *)&src_pal[pixel];
+										r += (weight * (double)entry[FI_RGBA_RED]);
+										g += (weight * (double)entry[FI_RGBA_GREEN]);
+										b += (weight * (double)entry[FI_RGBA_BLUE]);
+										a += (weight * (double)entry[FI_RGBA_ALPHA]);
+										src_bits += src_pitch;
+									}
+
+									// clamp and place result in destination pixel
+									dst_bits[FI_RGBA_RED]	= (BYTE)CLAMP<int>((int)(r + 0.5), 0, 0xFF);
+									dst_bits[FI_RGBA_GREEN]	= (BYTE)CLAMP<int>((int)(g + 0.5), 0, 0xFF);
+									dst_bits[FI_RGBA_BLUE]	= (BYTE)CLAMP<int>((int)(b + 0.5), 0, 0xFF);
+									dst_bits[FI_RGBA_ALPHA]	= (BYTE)CLAMP<int>((int)(a + 0.5), 0, 0xFF);
+									dst_bits += dst_pitch;
+								}
+							}
+						}
+						break;
+					}
+				}
+				break;
+
+				case 8:
+				{
+					const unsigned src_pitch = FreeImage_GetPitch(src);
+					const BYTE *const src_base = FreeImage_GetBits(src) + src_offset_y * src_pitch + src_offset_x;
+
+					switch(FreeImage_GetBPP(dst)) {
+						case 8:
+						{
+							// scale the 8-bit non-transparent greyscale image into an 8 bpp destination image
+							if (src_pal) {
+								// we have got a palette
+								for (unsigned x = 0; x < width; x++) {
+									// work on column x in dst
+									BYTE *dst_bits = dst_base + x;
+
+									// scale each column
+									for (unsigned y = 0; y < dst_height; y++) {
+										// loop through column
+										const unsigned iLeft = weightsTable.getLeftBoundary(y);				// retrieve left boundary
+										const unsigned iLimit = weightsTable.getRightBoundary(y) - iLeft;	// retrieve right boundary
+										const BYTE *src_bits = src_base + iLeft * src_pitch + x;
+										double value = 0;
+
+										for (unsigned i = 0; i < iLimit; i++) {
+											// scan between boundaries
+											// accumulate weighted effect of each neighboring pixel
+											value += (weightsTable.getWeight(y, i) * (double)*(BYTE *)&src_pal[*src_bits]);
+											src_bits += src_pitch;
+										}
+
+										// clamp and place result in destination pixel
+										*dst_bits = (BYTE)CLAMP<int>((int)(value + 0.5), 0, 0xFF);
+										dst_bits += dst_pitch;
+									}
+								}
+							} else {
+								// we do not have a palette
+								for (unsigned x = 0; x < width; x++) {
+									// work on column x in dst
+									BYTE *dst_bits = dst_base + x;
+
+									// scale each column
+									for (unsigned y = 0; y < dst_height; y++) {
+										// loop through column
+										const unsigned iLeft = weightsTable.getLeftBoundary(y);				// retrieve left boundary
+										const unsigned iLimit = weightsTable.getRightBoundary(y) - iLeft;	// retrieve right boundary
+										const BYTE *src_bits = src_base + iLeft * src_pitch + x;
+										double value = 0;
+
+										for (unsigned i = 0; i < iLimit; i++) {
+											// scan between boundaries
+											// accumulate weighted effect of each neighboring pixel
+											value += (weightsTable.getWeight(y, i) * (double)*src_bits);
+											src_bits += src_pitch;
+										}
+
+										// clamp and place result in destination pixel
+										*dst_bits = (BYTE)CLAMP<int>((int)(value + 0.5), 0, 0xFF);
+										dst_bits += dst_pitch;
+									}
+								}
+							}
+						}
+						break;
+
+						case 24:
+						{
+							// transparently convert the non-transparent 8-bit image to 24 bpp
+							if (src_pal) {
+								// we have got a palette
+								for (unsigned x = 0; x < width; x++) {
+									// work on column x in dst
+									BYTE *dst_bits = dst_base + x * 3;
+
+									// scale each column
+									for (unsigned y = 0; y < dst_height; y++) {
+										// loop through column
+										const unsigned iLeft = weightsTable.getLeftBoundary(y);				// retrieve left boundary
+										const unsigned iLimit = weightsTable.getRightBoundary(y) - iLeft;	// retrieve right boundary
+										const BYTE *src_bits = src_base + iLeft * src_pitch + x;
+										double r = 0, g = 0, b = 0;
+
+										for (unsigned i = 0; i < iLimit; i++) {
+											// scan between boundaries
+											// accumulate weighted effect of each neighboring pixel
+											const double weight = weightsTable.getWeight(y, i);
+											const BYTE * const entry = (BYTE *)&src_pal[*src_bits];
+											r += (weight * (double)entry[FI_RGBA_RED]);
+											g += (weight * (double)entry[FI_RGBA_GREEN]);
+											b += (weight * (double)entry[FI_RGBA_BLUE]);
+											src_bits += src_pitch;
+										}
+
+										// clamp and place result in destination pixel
+										dst_bits[FI_RGBA_RED]	= (BYTE)CLAMP<int>((int)(r + 0.5), 0, 0xFF);
+										dst_bits[FI_RGBA_GREEN]	= (BYTE)CLAMP<int>((int)(g + 0.5), 0, 0xFF);
+										dst_bits[FI_RGBA_BLUE]	= (BYTE)CLAMP<int>((int)(b + 0.5), 0, 0xFF);
+										dst_bits += dst_pitch;
+									}
+								}
+							} else {
+								// we do not have a palette
+								for (unsigned x = 0; x < width; x++) {
+									// work on column x in dst
+									BYTE *dst_bits = dst_base + x * 3;
+
+									// scale each column
+									for (unsigned y = 0; y < dst_height; y++) {
+										// loop through column
+										const unsigned iLeft = weightsTable.getLeftBoundary(y);				// retrieve left boundary
+										const unsigned iLimit = weightsTable.getRightBoundary(y) - iLeft;	// retrieve right boundary
+										const BYTE *src_bits = src_base + iLeft * src_pitch + x;
+										double value = 0;
+
+										for (unsigned i = 0; i < iLimit; i++) {
+											// scan between boundaries
+											// accumulate weighted effect of each neighboring pixel
+											value += (weightsTable.getWeight(y, i) * (double)*src_bits);
+											src_bits += src_pitch;
+										}
+
+										// clamp and place result in destination pixel
+										const BYTE bval = (BYTE)CLAMP<int>((int)(value + 0.5), 0, 0xFF);
+										dst_bits[FI_RGBA_RED]	= bval;
+										dst_bits[FI_RGBA_GREEN]	= bval;
+										dst_bits[FI_RGBA_BLUE]	= bval;
+										dst_bits += dst_pitch;
+									}
+								}
+							}
+						}
+						break;
+
+						case 32:
+						{
+							// transparently convert the transparent 8-bit image to 32 bpp; 
+							// we always have got a palette here
+							for (unsigned x = 0; x < width; x++) {
+								// work on column x in dst
+								BYTE *dst_bits = dst_base + x * 4;
+
+								// scale each column
+								for (unsigned y = 0; y < dst_height; y++) {
+									// loop through column
+									const unsigned iLeft = weightsTable.getLeftBoundary(y);				// retrieve left boundary
+									const unsigned iLimit = weightsTable.getRightBoundary(y) - iLeft;	// retrieve right boundary
+									const BYTE *src_bits = src_base + iLeft * src_pitch + x;
+									double r = 0, g = 0, b = 0, a = 0;
+
+									for (unsigned i = 0; i < iLimit; i++) {
+										// scan between boundaries
+										// accumulate weighted effect of each neighboring pixel
+										const double weight = weightsTable.getWeight(y, i);
+										const BYTE * const entry = (BYTE *)&src_pal[*src_bits];
+										r += (weight * (double)entry[FI_RGBA_RED]);
+										g += (weight * (double)entry[FI_RGBA_GREEN]);
+										b += (weight * (double)entry[FI_RGBA_BLUE]);
+										a += (weight * (double)entry[FI_RGBA_ALPHA]);
+										src_bits += src_pitch;
+									}
+
+									// clamp and place result in destination pixel
+									dst_bits[FI_RGBA_RED]	= (BYTE)CLAMP<int>((int)(r + 0.5), 0, 0xFF);
+									dst_bits[FI_RGBA_GREEN]	= (BYTE)CLAMP<int>((int)(g + 0.5), 0, 0xFF);
+									dst_bits[FI_RGBA_BLUE]	= (BYTE)CLAMP<int>((int)(b + 0.5), 0, 0xFF);
+									dst_bits[FI_RGBA_ALPHA]	= (BYTE)CLAMP<int>((int)(a + 0.5), 0, 0xFF);
+									dst_bits += dst_pitch;
+								}
+							}
+						}
+						break;
+					}
+				}
+				break;
+
+				case 16:
+				{
+					// transparently convert the 16-bit non-transparent image to 24 bpp
+					const unsigned src_pitch = FreeImage_GetPitch(src) / sizeof(WORD);
+					const WORD *const src_base = (WORD *)FreeImage_GetBits(src) + src_offset_y * src_pitch + src_offset_x;
+
+					if (IS_FORMAT_RGB565(src)) {
+						// image has 565 format
+						for (unsigned x = 0; x < width; x++) {
+							// work on column x in dst
+							BYTE *dst_bits = dst_base + x * 3;
+
+							// scale each column
+							for (unsigned y = 0; y < dst_height; y++) {
+								// loop through column
+								const unsigned iLeft = weightsTable.getLeftBoundary(y);				// retrieve left boundary
+								const unsigned iLimit = weightsTable.getRightBoundary(y) - iLeft;	// retrieve right boundary
+								const WORD *src_bits = src_base + iLeft * src_pitch + x;
+								double r = 0, g = 0, b = 0;
+
+								for (unsigned i = 0; i < iLimit; i++) {
+									// scan between boundaries
+									// accumulate weighted effect of each neighboring pixel
+									const double weight = weightsTable.getWeight(y, i);
+									r += (weight * (double)((*src_bits & FI16_565_RED_MASK) >> FI16_565_RED_SHIFT));
+									g += (weight * (double)((*src_bits & FI16_565_GREEN_MASK) >> FI16_565_GREEN_SHIFT));
+									b += (weight * (double)((*src_bits & FI16_565_BLUE_MASK) >> FI16_565_BLUE_SHIFT));
+									src_bits += src_pitch;
+								}
+
+								// clamp and place result in destination pixel
+								dst_bits[FI_RGBA_RED]	= (BYTE)CLAMP<int>((int)(((r * 0xFF) / 0x1F) + 0.5), 0, 0xFF);
+								dst_bits[FI_RGBA_GREEN]	= (BYTE)CLAMP<int>((int)(((g * 0xFF) / 0x3F) + 0.5), 0, 0xFF);
+								dst_bits[FI_RGBA_BLUE]	= (BYTE)CLAMP<int>((int)(((b * 0xFF) / 0x1F) + 0.5), 0, 0xFF);
+								dst_bits += dst_pitch;
+							}
+						}
+					} else {
+						// image has 555 format
+						for (unsigned x = 0; x < width; x++) {
+							// work on column x in dst
+							BYTE *dst_bits = dst_base + x * 3;
+
+							// scale each column
+							for (unsigned y = 0; y < dst_height; y++) {
+								// loop through column
+								const unsigned iLeft = weightsTable.getLeftBoundary(y);				// retrieve left boundary
+								const unsigned iLimit = weightsTable.getRightBoundary(y) - iLeft;	// retrieve right boundary
+								const WORD *src_bits = src_base + iLeft * src_pitch + x;
+								double r = 0, g = 0, b = 0;
+
+								for (unsigned i = 0; i < iLimit; i++) {
+									// scan between boundaries
+									// accumulate weighted effect of each neighboring pixel
+									const double weight = weightsTable.getWeight(y, i);
+									r += (weight * (double)((*src_bits & FI16_555_RED_MASK) >> FI16_555_RED_SHIFT));
+									g += (weight * (double)((*src_bits & FI16_555_GREEN_MASK) >> FI16_555_GREEN_SHIFT));
+									b += (weight * (double)((*src_bits & FI16_555_BLUE_MASK) >> FI16_555_BLUE_SHIFT));
+									src_bits += src_pitch;
+								}
+
+								// clamp and place result in destination pixel
+								dst_bits[FI_RGBA_RED]	= (BYTE)CLAMP<int>((int)(((r * 0xFF) / 0x1F) + 0.5), 0, 0xFF);
+								dst_bits[FI_RGBA_GREEN]	= (BYTE)CLAMP<int>((int)(((g * 0xFF) / 0x1F) + 0.5), 0, 0xFF);
+								dst_bits[FI_RGBA_BLUE]	= (BYTE)CLAMP<int>((int)(((b * 0xFF) / 0x1F) + 0.5), 0, 0xFF);
+								dst_bits += dst_pitch;
+							}
+						}
+					}
+				}
+				break;
+
+				case 24:
+				{
+					// scale the 24-bit transparent image into a 24 bpp destination image
+					const unsigned src_pitch = FreeImage_GetPitch(src);
+					const BYTE *const src_base = FreeImage_GetBits(src) + src_offset_y * src_pitch + src_offset_x * 3;
+
+					for (unsigned x = 0; x < width; x++) {
+						// work on column x in dst
+						const unsigned index = x * 3;
+						BYTE *dst_bits = dst_base + index;
+
+						// scale each column
+						for (unsigned y = 0; y < dst_height; y++) {
+							// loop through column
+							const unsigned iLeft = weightsTable.getLeftBoundary(y);				// retrieve left boundary
+							const unsigned iLimit = weightsTable.getRightBoundary(y) - iLeft;	// retrieve right boundary
+							const BYTE *src_bits = src_base + iLeft * src_pitch + index;
+							double r = 0, g = 0, b = 0;
+
+							for (unsigned i = 0; i < iLimit; i++) {
+								// scan between boundaries
+								// accumulate weighted effect of each neighboring pixel
+								const double weight = weightsTable.getWeight(y, i);
+								r += (weight * (double)src_bits[FI_RGBA_RED]);
+								g += (weight * (double)src_bits[FI_RGBA_GREEN]);
+								b += (weight * (double)src_bits[FI_RGBA_BLUE]);
+								src_bits += src_pitch;
+							}
+
+							// clamp and place result in destination pixel
+							dst_bits[FI_RGBA_RED]	= (BYTE)CLAMP<int>((int) (r + 0.5), 0, 0xFF);
+							dst_bits[FI_RGBA_GREEN]	= (BYTE)CLAMP<int>((int) (g + 0.5), 0, 0xFF);
+							dst_bits[FI_RGBA_BLUE]	= (BYTE)CLAMP<int>((int) (b + 0.5), 0, 0xFF);
+							dst_bits += dst_pitch;
+						}
+					}
+				}
+				break;
+
+				case 32:
+				{
+					// scale the 32-bit transparent image into a 32 bpp destination image
+					const unsigned src_pitch = FreeImage_GetPitch(src);
+					const BYTE *const src_base = FreeImage_GetBits(src) + src_offset_y * src_pitch + src_offset_x * 4;
+
+					for (unsigned x = 0; x < width; x++) {
+						// work on column x in dst
+						const unsigned index = x * 4;
+						BYTE *dst_bits = dst_base + index;
+
+						// scale each column
+						for (unsigned y = 0; y < dst_height; y++) {
+							// loop through column
+							const unsigned iLeft = weightsTable.getLeftBoundary(y);				// retrieve left boundary
+							const unsigned iLimit = weightsTable.getRightBoundary(y) - iLeft;	// retrieve right boundary
+							const BYTE *src_bits = src_base + iLeft * src_pitch + index;
+							double r = 0, g = 0, b = 0, a = 0;
+
+							for (unsigned i = 0; i < iLimit; i++) {
+								// scan between boundaries
+								// accumulate weighted effect of each neighboring pixel
+								const double weight = weightsTable.getWeight(y, i);
+								r += (weight * (double)src_bits[FI_RGBA_RED]);
+								g += (weight * (double)src_bits[FI_RGBA_GREEN]);
+								b += (weight * (double)src_bits[FI_RGBA_BLUE]);
+								a += (weight * (double)src_bits[FI_RGBA_ALPHA]);
+								src_bits += src_pitch;
+							}
+
+							// clamp and place result in destination pixel
+							dst_bits[FI_RGBA_RED]	= (BYTE)CLAMP<int>((int) (r + 0.5), 0, 0xFF);
+							dst_bits[FI_RGBA_GREEN]	= (BYTE)CLAMP<int>((int) (g + 0.5), 0, 0xFF);
+							dst_bits[FI_RGBA_BLUE]	= (BYTE)CLAMP<int>((int) (b + 0.5), 0, 0xFF);
+							dst_bits[FI_RGBA_ALPHA]	= (BYTE)CLAMP<int>((int) (a + 0.5), 0, 0xFF);
+							dst_bits += dst_pitch;
+						}
+					}
+				}
+				break;
+			}
+		}
+		break;
+
+		case FIT_UINT16:
+		{
+			// Calculate the number of words per pixel (1 for 16-bit, 3 for 48-bit or 4 for 64-bit)
+			const unsigned wordspp = (FreeImage_GetLine(src) / width) / sizeof(WORD);
+
+			const unsigned dst_pitch = FreeImage_GetPitch(dst) / sizeof(WORD);
+			WORD *const dst_base = (WORD *)FreeImage_GetBits(dst);
+
+			const unsigned src_pitch = FreeImage_GetPitch(src) / sizeof(WORD);
+			const WORD *const src_base = (WORD *)FreeImage_GetBits(src)	+ src_offset_y * src_pitch + src_offset_x * wordspp;
+
+			for (unsigned x = 0; x < width; x++) {
+				// work on column x in dst
+				const unsigned index = x * wordspp;	// pixel index
+				WORD *dst_bits = dst_base + index;
+
+				// scale each column
+				for (unsigned y = 0; y < dst_height; y++) {
+					// loop through column
+					const unsigned iLeft = weightsTable.getLeftBoundary(y);				// retrieve left boundary
+					const unsigned iLimit = weightsTable.getRightBoundary(y) - iLeft;	// retrieve right boundary
+					const WORD *src_bits = src_base + iLeft * src_pitch + index;
+					double value = 0;
+
+					for (unsigned i = 0; i < iLimit; i++) {
+						// scan between boundaries
+						// accumulate weighted effect of each neighboring pixel
+						const double weight = weightsTable.getWeight(y, i);
+						value += (weight * (double)src_bits[0]);
+						src_bits += src_pitch;
+					}
+
+					// clamp and place result in destination pixel
+					dst_bits[0] = (WORD)CLAMP<int>((int)(value + 0.5), 0, 0xFFFF);
+
+					dst_bits += dst_pitch;
+				}
+			}
+		}
+		break;
+
+		case FIT_RGB16:
+		{
+			// Calculate the number of words per pixel (1 for 16-bit, 3 for 48-bit or 4 for 64-bit)
+			const unsigned wordspp = (FreeImage_GetLine(src) / width) / sizeof(WORD);
+
+			const unsigned dst_pitch = FreeImage_GetPitch(dst) / sizeof(WORD);
+			WORD *const dst_base = (WORD *)FreeImage_GetBits(dst);
+
+			const unsigned src_pitch = FreeImage_GetPitch(src) / sizeof(WORD);
+			const WORD *const src_base = (WORD *)FreeImage_GetBits(src) + src_offset_y * src_pitch + src_offset_x * wordspp;
+
+			for (unsigned x = 0; x < width; x++) {
+				// work on column x in dst
+				const unsigned index = x * wordspp;	// pixel index
+				WORD *dst_bits = dst_base + index;
+
+				// scale each column
+				for (unsigned y = 0; y < dst_height; y++) {
+					// loop through column
+					const unsigned iLeft = weightsTable.getLeftBoundary(y);				// retrieve left boundary
+					const unsigned iLimit = weightsTable.getRightBoundary(y) - iLeft;	// retrieve right boundary
+					const WORD *src_bits = src_base + iLeft * src_pitch + index;
+					double r = 0, g = 0, b = 0;
+
+					for (unsigned i = 0; i < iLimit; i++) {
+						// scan between boundaries
+						// accumulate weighted effect of each neighboring pixel
+						const double weight = weightsTable.getWeight(y, i);					
+						r += (weight * (double)src_bits[0]);
+						g += (weight * (double)src_bits[1]);
+						b += (weight * (double)src_bits[2]);
+
+						src_bits += src_pitch;
+					}
+
+					// clamp and place result in destination pixel
+					dst_bits[0] = (WORD)CLAMP<int>((int)(r + 0.5), 0, 0xFFFF);
+					dst_bits[1] = (WORD)CLAMP<int>((int)(g + 0.5), 0, 0xFFFF);
+					dst_bits[2] = (WORD)CLAMP<int>((int)(b + 0.5), 0, 0xFFFF);
+
+					dst_bits += dst_pitch;
+				}
+			}
+		}
+		break;
+
+		case FIT_RGBA16:
+		{
+			// Calculate the number of words per pixel (1 for 16-bit, 3 for 48-bit or 4 for 64-bit)
+			const unsigned wordspp = (FreeImage_GetLine(src) / width) / sizeof(WORD);
+
+			const unsigned dst_pitch = FreeImage_GetPitch(dst) / sizeof(WORD);
+			WORD *const dst_base = (WORD *)FreeImage_GetBits(dst);
+
+			const unsigned src_pitch = FreeImage_GetPitch(src) / sizeof(WORD);
+			const WORD *const src_base = (WORD *)FreeImage_GetBits(src) + src_offset_y * src_pitch + src_offset_x * wordspp;
+
+			for (unsigned x = 0; x < width; x++) {
+				// work on column x in dst
+				const unsigned index = x * wordspp;	// pixel index
+				WORD *dst_bits = dst_base + index;
+
+				// scale each column
+				for (unsigned y = 0; y < dst_height; y++) {
+					// loop through column
+					const unsigned iLeft = weightsTable.getLeftBoundary(y);				// retrieve left boundary
+					const unsigned iLimit = weightsTable.getRightBoundary(y) - iLeft;	// retrieve right boundary
+					const WORD *src_bits = src_base + iLeft * src_pitch + index;
+					double r = 0, g = 0, b = 0, a = 0;
+
+					for (unsigned i = 0; i < iLimit; i++) {
+						// scan between boundaries
+						// accumulate weighted effect of each neighboring pixel
+						const double weight = weightsTable.getWeight(y, i);					
+						r += (weight * (double)src_bits[0]);
+						g += (weight * (double)src_bits[1]);
+						b += (weight * (double)src_bits[2]);
+						a += (weight * (double)src_bits[3]);
+
+						src_bits += src_pitch;
+					}
+
+					// clamp and place result in destination pixel
+					dst_bits[0] = (WORD)CLAMP<int>((int)(r + 0.5), 0, 0xFFFF);
+					dst_bits[1] = (WORD)CLAMP<int>((int)(g + 0.5), 0, 0xFFFF);
+					dst_bits[2] = (WORD)CLAMP<int>((int)(b + 0.5), 0, 0xFFFF);
+					dst_bits[3] = (WORD)CLAMP<int>((int)(a + 0.5), 0, 0xFFFF);
+
+					dst_bits += dst_pitch;
+				}
+			}
+		}
+		break;
+
+		case FIT_FLOAT:
+		case FIT_RGBF:
+		case FIT_RGBAF:
+		{
+			// Calculate the number of floats per pixel (1 for 32-bit, 3 for 96-bit or 4 for 128-bit)
+			const unsigned floatspp = (FreeImage_GetLine(src) / width) / sizeof(float);
+
+			const unsigned dst_pitch = FreeImage_GetPitch(dst) / sizeof(float);
+			float *const dst_base = (float *)FreeImage_GetBits(dst);
+
+			const unsigned src_pitch = FreeImage_GetPitch(src) / sizeof(float);
+			const float *const src_base = (float *)FreeImage_GetBits(src) + src_offset_y * src_pitch + src_offset_x * floatspp;
+
+			for (unsigned x = 0; x < width; x++) {
+				// work on column x in dst
+				const unsigned index = x * floatspp;	// pixel index
+				float *dst_bits = (float *)dst_base + index;
+
+				// scale each column
+				for (unsigned y = 0; y < dst_height; y++) {
+					// loop through column
+					const unsigned iLeft = weightsTable.getLeftBoundary(y);    // retrieve left boundary
+					const unsigned iRight = weightsTable.getRightBoundary(y);  // retrieve right boundary
+					const float *src_bits = src_base + iLeft * src_pitch + index;
+					double value[4] = {0, 0, 0, 0};                            // 4 = 128 bpp max
+
+					for (unsigned i = iLeft; i < iRight; i++) {
+						// scan between boundaries
+						// accumulate weighted effect of each neighboring pixel
+						const double weight = weightsTable.getWeight(y, i - iLeft);
+						for (unsigned j = 0; j < floatspp; j++) {
+							value[j] += (weight * (double)src_bits[j]);
+						}
+						src_bits += src_pitch;
+					}
+
+					// place result in destination pixel
+					for (unsigned j = 0; j < floatspp; j++) {
+						dst_bits[j] = (float)value[j];
+					}
+					dst_bits += dst_pitch;
+				}
+			}
+		}
+		break;
+	}
+}
diff --git a/Source/FreeImageToolkit/Resize.h b/Source/FreeImageToolkit/Resize.h
index 7fe1cdb..ce1d732 100644
--- a/Source/FreeImageToolkit/Resize.h
+++ b/Source/FreeImageToolkit/Resize.h
@@ -1,195 +1,196 @@
-// ==========================================================
-// Upsampling / downsampling classes
-//
-// Design and implementation by
-// - Herv� Drolon (drolon at infonie.fr)
-// - Detlev Vendt (detlev.vendt at brillit.de)
-// - Carsten Klein (cklein05 at users.sourceforge.net)
-//
-// This file is part of FreeImage 3
-//
-// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
-// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
-// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
-// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
-// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
-// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
-// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
-// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
-// THIS DISCLAIMER.
-//
-// Use at your own risk!
-// ==========================================================
-
-#ifndef _RESIZE_H_
-#define _RESIZE_H_
-
-#include "FreeImage.h"
-#include "Utilities.h"
-#include "Filters.h" 
-
-/**
-  Filter weights table.<br>
-  This class stores contribution information for an entire line (row or column).
-*/
-class CWeightsTable
-{
-/**
-  Sampled filter weight table.<br>
-  Contribution information for a single pixel
-*/
-typedef struct {
-	/// Normalized weights of neighboring pixels
-	double *Weights;
-	/// Bounds of source pixels window
-	unsigned Left, Right;
-} Contribution;
-
-private:
-	/// Row (or column) of contribution weights 
-	Contribution *m_WeightTable;
-	/// Filter window size (of affecting source pixels) 
-	unsigned m_WindowSize;
-	/// Length of line (no. of rows / cols) 
-	unsigned m_LineLength;
-
-public:
-	/** 
-	Constructor<br>
-	Allocate and compute the weights table
-	@param pFilter Filter used for upsampling or downsampling
-	@param uDstSize Length (in pixels) of the destination line buffer
-	@param uSrcSize Length (in pixels) of the source line buffer
-	*/
-	CWeightsTable(CGenericFilter *pFilter, unsigned uDstSize, unsigned uSrcSize);
-
-	/**
-	Destructor<br>
-	Destroy the weights table
-	*/
-	~CWeightsTable();
-
-	/** Retrieve a filter weight, given source and destination positions
-	@param dst_pos Pixel position in destination line buffer
-	@param src_pos Pixel position in source line buffer
-	@return Returns the filter weight
-	*/
-	double getWeight(unsigned dst_pos, unsigned src_pos) {
-		return m_WeightTable[dst_pos].Weights[src_pos];
-	}
-
-	/** Retrieve left boundary of source line buffer
-	@param dst_pos Pixel position in destination line buffer
-	@return Returns the left boundary of source line buffer
-	*/
-	unsigned getLeftBoundary(unsigned dst_pos) {
-		return m_WeightTable[dst_pos].Left;
-	}
-
-	/** Retrieve right boundary of source line buffer
-	@param dst_pos Pixel position in destination line buffer
-	@return Returns the right boundary of source line buffer
-	*/
-	unsigned getRightBoundary(unsigned dst_pos) {
-		return m_WeightTable[dst_pos].Right;
-	}
-};
-
-// ---------------------------------------------
-
-/**
- CResizeEngine<br>
- This class performs filtered zoom. It scales an image to the desired dimensions with 
- any of the CGenericFilter derived filter class.<br>
- It works with FIT_BITMAP buffers, WORD buffers (FIT_UINT16, FIT_RGB16, FIT_RGBA16) 
- and float buffers (FIT_FLOAT, FIT_RGBF, FIT_RGBAF).<br><br>
-
- <b>References</b> : <br>
- [1] Paul Heckbert, C code to zoom raster images up or down, with nice filtering. 
- UC Berkeley, August 1989. [online] http://www-2.cs.cmu.edu/afs/cs.cmu.edu/Web/People/ph/heckbert.html
- [2] Eran Yariv, Two Pass Scaling using Filters. The Code Project, December 1999. 
- [online] http://www.codeproject.com/bitmap/2_pass_scaling.asp
-
-*/
-class CResizeEngine
-{
-private:
-	/// Pointer to the FIR / IIR filter
-	CGenericFilter* m_pFilter;
-
-public:
-
-	/**
-	Constructor
-	@param filter FIR /IIR filter to be used
-	*/
-	CResizeEngine(CGenericFilter* filter):m_pFilter(filter) {}
-
-	/// Destructor
-	virtual ~CResizeEngine() {}
-
-	/** Scale an image to the desired dimensions.
-
-	Method CResizeEngine::scale, as well as the two filtering methods
-	CResizeEngine::horizontalFilter and CResizeEngine::verticalFilter take
-	four additional parameters, that define a rectangle in the source
-	image to be rescaled.
-
-	These are src_left, src_top, src_width and src_height and should work
-	like these of function FreeImage_Copy. However, src_left and src_top are
-	actually named src_offset_x and src_offset_y in the filtering methods.
-
-	Additionally, since src_height and dst_height are always the same for
-	method horizontalFilter as src_width and dst_width are always the same
-	for verticalFilter, these have been stripped down to a single parameter
-	height and width for horizontalFilter and verticalFilter respectively.
-
-	Currently, method scale is called with the actual size of the source
-	image. However, in a future version, we could provide a new function
-	called FreeImage_RescaleRect that rescales only part of an image. 
-
-	@param src Pointer to the source image
-	@param dst_width Destination image width
-	@param dst_height Destination image height
-	@param src_left Left boundary of the source rectangle to be scaled
-	@param src_top Top boundary of the source rectangle to be scaled
-	@param src_width Width of the source rectangle to be scaled
-	@param src_height Height of the source rectangle to be scaled
-	@return Returns the scaled image if successful, returns NULL otherwise
-	*/
-	FIBITMAP* scale(FIBITMAP *src, unsigned dst_width, unsigned dst_height, unsigned src_left, unsigned src_top, unsigned src_width, unsigned src_height);
-
-private:
-
-	/**
-	Performs horizontal image filtering
-	@param src
-	@param height
-	@param src_width
-	@param src_offset_x
-	@param src_offset_y
-	@param src_pal
-	@param dst
-	@param dst_width
-	*/
-	void horizontalFilter(FIBITMAP * const src, const unsigned height, const unsigned src_width,
-			const unsigned src_offset_x, const unsigned src_offset_y, const RGBQUAD * const src_pal,
-			FIBITMAP * const dst, const unsigned dst_width);
-
-	/**
-	Performs vertical image filtering
-	@param src
-	@param width
-	@param src_height
-	@param src_offset_x
-	@param src_offset_y
-	@param src_pal
-	@param dst
-	@param dst_height
-	*/
-	void verticalFilter(FIBITMAP * const src, const unsigned width, const unsigned src_height,
-			const unsigned src_offset_x, const unsigned src_offset_y, const RGBQUAD * const src_pal,
-			FIBITMAP * const dst, const unsigned dst_height);
-};
-
-#endif //   _RESIZE_H_
+// ==========================================================
+// Upsampling / downsampling classes
+//
+// Design and implementation by
+// - Herv� Drolon (drolon at infonie.fr)
+// - Detlev Vendt (detlev.vendt at brillit.de)
+// - Carsten Klein (cklein05 at users.sourceforge.net)
+//
+// This file is part of FreeImage 3
+//
+// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
+// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
+// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
+// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
+// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
+// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
+// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+// THIS DISCLAIMER.
+//
+// Use at your own risk!
+// ==========================================================
+
+#ifndef _RESIZE_H_
+#define _RESIZE_H_
+
+#include "FreeImage.h"
+#include "Utilities.h"
+#include "Filters.h" 
+
+/**
+  Filter weights table.<br>
+  This class stores contribution information for an entire line (row or column).
+*/
+class CWeightsTable
+{
+/**
+  Sampled filter weight table.<br>
+  Contribution information for a single pixel
+*/
+typedef struct {
+	/// Normalized weights of neighboring pixels
+	double *Weights;
+	/// Bounds of source pixels window
+	unsigned Left, Right;
+} Contribution;
+
+private:
+	/// Row (or column) of contribution weights 
+	Contribution *m_WeightTable;
+	/// Filter window size (of affecting source pixels) 
+	unsigned m_WindowSize;
+	/// Length of line (no. of rows / cols) 
+	unsigned m_LineLength;
+
+public:
+	/** 
+	Constructor<br>
+	Allocate and compute the weights table
+	@param pFilter Filter used for upsampling or downsampling
+	@param uDstSize Length (in pixels) of the destination line buffer
+	@param uSrcSize Length (in pixels) of the source line buffer
+	*/
+	CWeightsTable(CGenericFilter *pFilter, unsigned uDstSize, unsigned uSrcSize);
+
+	/**
+	Destructor<br>
+	Destroy the weights table
+	*/
+	~CWeightsTable();
+
+	/** Retrieve a filter weight, given source and destination positions
+	@param dst_pos Pixel position in destination line buffer
+	@param src_pos Pixel position in source line buffer
+	@return Returns the filter weight
+	*/
+	double getWeight(unsigned dst_pos, unsigned src_pos) {
+		return m_WeightTable[dst_pos].Weights[src_pos];
+	}
+
+	/** Retrieve left boundary of source line buffer
+	@param dst_pos Pixel position in destination line buffer
+	@return Returns the left boundary of source line buffer
+	*/
+	unsigned getLeftBoundary(unsigned dst_pos) {
+		return m_WeightTable[dst_pos].Left;
+	}
+
+	/** Retrieve right boundary of source line buffer
+	@param dst_pos Pixel position in destination line buffer
+	@return Returns the right boundary of source line buffer
+	*/
+	unsigned getRightBoundary(unsigned dst_pos) {
+		return m_WeightTable[dst_pos].Right;
+	}
+};
+
+// ---------------------------------------------
+
+/**
+ CResizeEngine<br>
+ This class performs filtered zoom. It scales an image to the desired dimensions with 
+ any of the CGenericFilter derived filter class.<br>
+ It works with FIT_BITMAP buffers, WORD buffers (FIT_UINT16, FIT_RGB16, FIT_RGBA16) 
+ and float buffers (FIT_FLOAT, FIT_RGBF, FIT_RGBAF).<br><br>
+
+ <b>References</b> : <br>
+ [1] Paul Heckbert, C code to zoom raster images up or down, with nice filtering. 
+ UC Berkeley, August 1989. [online] http://www-2.cs.cmu.edu/afs/cs.cmu.edu/Web/People/ph/heckbert.html
+ [2] Eran Yariv, Two Pass Scaling using Filters. The Code Project, December 1999. 
+ [online] http://www.codeproject.com/bitmap/2_pass_scaling.asp
+
+*/
+class CResizeEngine
+{
+private:
+	/// Pointer to the FIR / IIR filter
+	CGenericFilter* m_pFilter;
+
+public:
+
+	/**
+	Constructor
+	@param filter FIR /IIR filter to be used
+	*/
+	CResizeEngine(CGenericFilter* filter):m_pFilter(filter) {}
+
+	/// Destructor
+	virtual ~CResizeEngine() {}
+
+	/** Scale an image to the desired dimensions.
+
+	Method CResizeEngine::scale, as well as the two filtering methods
+	CResizeEngine::horizontalFilter and CResizeEngine::verticalFilter take
+	four additional parameters, that define a rectangle in the source
+	image to be rescaled.
+
+	These are src_left, src_top, src_width and src_height and should work
+	like these of function FreeImage_Copy. However, src_left and src_top are
+	actually named src_offset_x and src_offset_y in the filtering methods.
+
+	Additionally, since src_height and dst_height are always the same for
+	method horizontalFilter as src_width and dst_width are always the same
+	for verticalFilter, these have been stripped down to a single parameter
+	height and width for horizontalFilter and verticalFilter respectively.
+
+	Currently, method scale is called with the actual size of the source
+	image. However, in a future version, we could provide a new function
+	called FreeImage_RescaleRect that rescales only part of an image. 
+
+	@param src Pointer to the source image
+	@param dst_width Destination image width
+	@param dst_height Destination image height
+	@param src_left Left boundary of the source rectangle to be scaled
+	@param src_top Top boundary of the source rectangle to be scaled
+	@param src_width Width of the source rectangle to be scaled
+	@param src_height Height of the source rectangle to be scaled
+	@return Returns the scaled image if successful, returns NULL otherwise
+	*/
+	FIBITMAP* scale(FIBITMAP *src, unsigned dst_width, unsigned dst_height, unsigned src_left, unsigned src_top, unsigned src_width, unsigned src_height, unsigned flags);
+
+private:
+
+	/**
+	Performs horizontal image filtering
+
+	@param src Source image
+	@param height Source / Destination image height
+	@param src_width Source image width
+	@param src_offset_x
+	@param src_offset_y
+	@param src_pal
+	@param dst Destination image
+	@param dst_width Destination image width
+	*/
+	void horizontalFilter(FIBITMAP * const src, const unsigned height, const unsigned src_width,
+			const unsigned src_offset_x, const unsigned src_offset_y, const RGBQUAD * const src_pal,
+			FIBITMAP * const dst, const unsigned dst_width);
+
+	/**
+	Performs vertical image filtering
+	@param src Source image
+	@param width Source / Destination image width
+	@param src_height Source image height
+	@param src_offset_x
+	@param src_offset_y
+	@param src_pal
+	@param dst Destination image
+	@param dst_height Destination image height
+	*/
+	void verticalFilter(FIBITMAP * const src, const unsigned width, const unsigned src_height,
+			const unsigned src_offset_x, const unsigned src_offset_y, const RGBQUAD * const src_pal,
+			FIBITMAP * const dst, const unsigned dst_height);
+};
+
+#endif //   _RESIZE_H_
diff --git a/Source/LibJPEG/LibJPEG.2003.vcproj b/Source/LibJPEG/LibJPEG.2003.vcproj
deleted file mode 100644
index b071bfd..0000000
--- a/Source/LibJPEG/LibJPEG.2003.vcproj
+++ /dev/null
@@ -1,306 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="7.10"
-	Name="LibJPEG"
-	SccProjectName=""$/FreeImage/LibJPEG", IHAAAAAA"
-	SccLocalPath=".">
-	<Platforms>
-		<Platform
-			Name="Win32"/>
-	</Platforms>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			OutputDirectory=".\Debug"
-			IntermediateDirectory=".\Debug"
-			ConfigurationType="4"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="FALSE"
-			CharacterSet="2">
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="0"
-				PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
-				StringPooling="TRUE"
-				BasicRuntimeChecks="3"
-				RuntimeLibrary="1"
-				UsePrecompiledHeader="2"
-				PrecompiledHeaderFile=".\Debug/LibJPEG.pch"
-				AssemblerListingLocation=".\Debug/"
-				ObjectFile=".\Debug/"
-				ProgramDataBaseFileName=".\Debug/"
-				WarningLevel="3"
-				SuppressStartupBanner="TRUE"
-				DebugInformationFormat="4"/>
-			<Tool
-				Name="VCCustomBuildTool"/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile=".\Debug\LibJPEG.lib"
-				SuppressStartupBanner="TRUE"/>
-			<Tool
-				Name="VCMIDLTool"/>
-			<Tool
-				Name="VCPostBuildEventTool"/>
-			<Tool
-				Name="VCPreBuildEventTool"/>
-			<Tool
-				Name="VCPreLinkEventTool"/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="_DEBUG"
-				Culture="1033"/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"/>
-			<Tool
-				Name="VCManagedWrapperGeneratorTool"/>
-			<Tool
-				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			OutputDirectory=".\Release"
-			IntermediateDirectory=".\Release"
-			ConfigurationType="4"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="FALSE"
-			CharacterSet="2">
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="2"
-				GlobalOptimizations="TRUE"
-				InlineFunctionExpansion="2"
-				EnableIntrinsicFunctions="TRUE"
-				FavorSizeOrSpeed="1"
-				OmitFramePointers="TRUE"
-				OptimizeForProcessor="3"
-				AdditionalIncludeDirectories="..\zlib"
-				PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
-				StringPooling="TRUE"
-				RuntimeLibrary="0"
-				BufferSecurityCheck="FALSE"
-				UsePrecompiledHeader="2"
-				PrecompiledHeaderFile=".\Release/LibJPEG.pch"
-				AssemblerListingLocation=".\Release/"
-				ObjectFile=".\Release/"
-				ProgramDataBaseFileName=".\Release/"
-				WarningLevel="3"
-				SuppressStartupBanner="TRUE"
-				CompileAs="0"/>
-			<Tool
-				Name="VCCustomBuildTool"/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile=".\Release\LibJPEG.lib"
-				SuppressStartupBanner="TRUE"/>
-			<Tool
-				Name="VCMIDLTool"/>
-			<Tool
-				Name="VCPostBuildEventTool"/>
-			<Tool
-				Name="VCPreBuildEventTool"/>
-			<Tool
-				Name="VCPreLinkEventTool"/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="1033"/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"/>
-			<Tool
-				Name="VCManagedWrapperGeneratorTool"/>
-			<Tool
-				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Source Files"
-			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
-			<File
-				RelativePath=".\jaricom.c">
-			</File>
-			<File
-				RelativePath="jcapimin.c">
-			</File>
-			<File
-				RelativePath="jcapistd.c">
-			</File>
-			<File
-				RelativePath=".\jcarith.c">
-			</File>
-			<File
-				RelativePath="jccoefct.c">
-			</File>
-			<File
-				RelativePath="jccolor.c">
-			</File>
-			<File
-				RelativePath="jcdctmgr.c">
-			</File>
-			<File
-				RelativePath="jchuff.c">
-			</File>
-			<File
-				RelativePath="jcinit.c">
-			</File>
-			<File
-				RelativePath="jcmainct.c">
-			</File>
-			<File
-				RelativePath="jcmarker.c">
-			</File>
-			<File
-				RelativePath="jcmaster.c">
-			</File>
-			<File
-				RelativePath="jcomapi.c">
-			</File>
-			<File
-				RelativePath="jcparam.c">
-			</File>
-			<File
-				RelativePath="jcprepct.c">
-			</File>
-			<File
-				RelativePath="jcsample.c">
-			</File>
-			<File
-				RelativePath="jctrans.c">
-			</File>
-			<File
-				RelativePath="jdapimin.c">
-			</File>
-			<File
-				RelativePath="jdapistd.c">
-			</File>
-			<File
-				RelativePath=".\jdarith.c">
-			</File>
-			<File
-				RelativePath="jdatadst.c">
-			</File>
-			<File
-				RelativePath="jdatasrc.c">
-			</File>
-			<File
-				RelativePath="jdcoefct.c">
-			</File>
-			<File
-				RelativePath="jdcolor.c">
-			</File>
-			<File
-				RelativePath="jddctmgr.c">
-			</File>
-			<File
-				RelativePath="jdhuff.c">
-			</File>
-			<File
-				RelativePath="jdinput.c">
-			</File>
-			<File
-				RelativePath="jdmainct.c">
-			</File>
-			<File
-				RelativePath="jdmarker.c">
-			</File>
-			<File
-				RelativePath="jdmaster.c">
-			</File>
-			<File
-				RelativePath="jdmerge.c">
-			</File>
-			<File
-				RelativePath="jdpostct.c">
-			</File>
-			<File
-				RelativePath="jdsample.c">
-			</File>
-			<File
-				RelativePath="jdtrans.c">
-			</File>
-			<File
-				RelativePath="jerror.c">
-			</File>
-			<File
-				RelativePath="jfdctflt.c">
-			</File>
-			<File
-				RelativePath="jfdctfst.c">
-			</File>
-			<File
-				RelativePath="jfdctint.c">
-			</File>
-			<File
-				RelativePath="jidctflt.c">
-			</File>
-			<File
-				RelativePath="jidctfst.c">
-			</File>
-			<File
-				RelativePath="jidctint.c">
-			</File>
-			<File
-				RelativePath="jmemmgr.c">
-			</File>
-			<File
-				RelativePath="jmemnobs.c">
-			</File>
-			<File
-				RelativePath="jquant1.c">
-			</File>
-			<File
-				RelativePath="jquant2.c">
-			</File>
-			<File
-				RelativePath="jutils.c">
-			</File>
-			<File
-				RelativePath="transupp.c">
-			</File>
-		</Filter>
-		<Filter
-			Name="Header Files"
-			Filter="h;hpp;hxx;hm;inl">
-			<File
-				RelativePath="jconfig.h">
-			</File>
-			<File
-				RelativePath="jdct.h">
-			</File>
-			<File
-				RelativePath="jerror.h">
-			</File>
-			<File
-				RelativePath="jinclude.h">
-			</File>
-			<File
-				RelativePath="jmemsys.h">
-			</File>
-			<File
-				RelativePath="jmorecfg.h">
-			</File>
-			<File
-				RelativePath="jpegint.h">
-			</File>
-			<File
-				RelativePath="jpeglib.h">
-			</File>
-			<File
-				RelativePath="jversion.h">
-			</File>
-			<File
-				RelativePath="transupp.h">
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
diff --git a/Source/LibJPEG/LibJPEG.2013.vcxproj b/Source/LibJPEG/LibJPEG.2013.vcxproj
new file mode 100644
index 0000000..be84a7c
--- /dev/null
+++ b/Source/LibJPEG/LibJPEG.2013.vcxproj
@@ -0,0 +1,258 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectName>LibJPEG</ProjectName>
+    <ProjectGuid>{5E1D4E5F-E10C-4BA3-B663-F33014FD21D9}</ProjectGuid>
+    <RootNamespace>LibJPEG</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>12.0.21005.1</_ProjectFileVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0409</Culture>
+    </ResourceCompile>
+    <Lib>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <Optimization>Full</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>..\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <CompileAs>Default</CompileAs>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+      <DebugInformationFormat>None</DebugInformationFormat>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0409</Culture>
+    </ResourceCompile>
+    <Lib>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <LinkTimeCodeGeneration>true</LinkTimeCodeGeneration>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0409</Culture>
+    </ResourceCompile>
+    <Lib>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>Full</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>..\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <CompileAs>Default</CompileAs>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+      <DebugInformationFormat>None</DebugInformationFormat>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0409</Culture>
+    </ResourceCompile>
+    <Lib>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <LinkTimeCodeGeneration>true</LinkTimeCodeGeneration>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="jaricom.c" />
+    <ClCompile Include="jcapimin.c" />
+    <ClCompile Include="jcapistd.c" />
+    <ClCompile Include="jcarith.c" />
+    <ClCompile Include="jccoefct.c" />
+    <ClCompile Include="jccolor.c" />
+    <ClCompile Include="jcdctmgr.c" />
+    <ClCompile Include="jchuff.c" />
+    <ClCompile Include="jcinit.c" />
+    <ClCompile Include="jcmainct.c" />
+    <ClCompile Include="jcmarker.c" />
+    <ClCompile Include="jcmaster.c" />
+    <ClCompile Include="jcomapi.c" />
+    <ClCompile Include="jcparam.c" />
+    <ClCompile Include="jcprepct.c" />
+    <ClCompile Include="jcsample.c" />
+    <ClCompile Include="jctrans.c" />
+    <ClCompile Include="jdapimin.c" />
+    <ClCompile Include="jdapistd.c" />
+    <ClCompile Include="jdarith.c" />
+    <ClCompile Include="jdatadst.c" />
+    <ClCompile Include="jdatasrc.c" />
+    <ClCompile Include="jdcoefct.c" />
+    <ClCompile Include="jdcolor.c" />
+    <ClCompile Include="jddctmgr.c" />
+    <ClCompile Include="jdhuff.c" />
+    <ClCompile Include="jdinput.c" />
+    <ClCompile Include="jdmainct.c" />
+    <ClCompile Include="jdmarker.c" />
+    <ClCompile Include="jdmaster.c" />
+    <ClCompile Include="jdmerge.c" />
+    <ClCompile Include="jdpostct.c" />
+    <ClCompile Include="jdsample.c" />
+    <ClCompile Include="jdtrans.c" />
+    <ClCompile Include="jerror.c" />
+    <ClCompile Include="jfdctflt.c" />
+    <ClCompile Include="jfdctfst.c" />
+    <ClCompile Include="jfdctint.c" />
+    <ClCompile Include="jidctflt.c" />
+    <ClCompile Include="jidctfst.c" />
+    <ClCompile Include="jidctint.c" />
+    <ClCompile Include="jmemmgr.c" />
+    <ClCompile Include="jmemnobs.c" />
+    <ClCompile Include="jquant1.c" />
+    <ClCompile Include="jquant2.c" />
+    <ClCompile Include="jutils.c" />
+    <ClCompile Include="transupp.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="jconfig.h" />
+    <ClInclude Include="jdct.h" />
+    <ClInclude Include="jerror.h" />
+    <ClInclude Include="jinclude.h" />
+    <ClInclude Include="jmemsys.h" />
+    <ClInclude Include="jmorecfg.h" />
+    <ClInclude Include="jpegint.h" />
+    <ClInclude Include="jpeglib.h" />
+    <ClInclude Include="jversion.h" />
+    <ClInclude Include="transupp.h" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/Source/LibJPEG/LibJPEG.2013.vcxproj.filters b/Source/LibJPEG/LibJPEG.2013.vcxproj.filters
new file mode 100644
index 0000000..94ad9ef
--- /dev/null
+++ b/Source/LibJPEG/LibJPEG.2013.vcxproj.filters
@@ -0,0 +1,188 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{2fa193f8-a23e-4078-8ff6-6bf5b443df38}</UniqueIdentifier>
+      <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{66abfe69-3f1d-455a-afad-997a86d09b0b}</UniqueIdentifier>
+      <Extensions>h;hpp;hxx;hm;inl</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="jaricom.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jcapimin.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jcapistd.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jcarith.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jccoefct.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jccolor.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jcdctmgr.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jchuff.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jcinit.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jcmainct.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jcmarker.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jcmaster.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jcomapi.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jcparam.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jcprepct.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jcsample.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jctrans.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jdapimin.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jdapistd.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jdarith.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jdatadst.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jdatasrc.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jdcoefct.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jdcolor.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jddctmgr.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jdhuff.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jdinput.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jdmainct.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jdmarker.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jdmaster.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jdmerge.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jdpostct.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jdsample.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jdtrans.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jerror.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jfdctflt.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jfdctfst.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jfdctint.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jidctflt.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jidctfst.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jidctint.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jmemmgr.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jmemnobs.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jquant1.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jquant2.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jutils.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="transupp.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="jconfig.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="jdct.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="jerror.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="jinclude.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="jmemsys.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="jmorecfg.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="jpegint.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="jpeglib.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="jversion.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="transupp.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/Source/LibJPEG/README b/Source/LibJPEG/README
index 07bb50b..a28ead3 100644
--- a/Source/LibJPEG/README
+++ b/Source/LibJPEG/README
@@ -1,10 +1,10 @@
 The Independent JPEG Group's JPEG software
 ==========================================
 
-README for release 8d of 15-Jan-2012
+README for release 9a of 19-Jan-2014
 ====================================
 
-This distribution contains the eighth public release of the Independent JPEG
+This distribution contains the ninth public release of the Independent JPEG
 Group's free JPEG software.  You are welcome to redistribute this software and
 to use it for any purpose, subject to the conditions under LEGAL ISSUES, below.
 
@@ -14,7 +14,7 @@ Julian Minguillon, Luis Ortiz, George Phillips, Davide Rossi, Ge' Weijers,
 and other members of the Independent JPEG Group.
 
 IJG is not affiliated with the ISO/IEC JTC1/SC29/WG1 standards committee
-(also known as JPEG, together with ITU-T SG16).
+(previously known as JPEG, together with ITU-T SG16).
 
 
 DOCUMENTATION ROADMAP
@@ -115,7 +115,7 @@ with respect to this software, its quality, accuracy, merchantability, or
 fitness for a particular purpose.  This software is provided "AS IS", and you,
 its user, assume the entire risk as to its quality and accuracy.
 
-This software is copyright (C) 1991-2012, Thomas G. Lane, Guido Vollbeding.
+This software is copyright (C) 1991-2014, Thomas G. Lane, Guido Vollbeding.
 All Rights Reserved except as specified below.
 
 Permission is hereby granted to use, copy, modify, and distribute this
@@ -146,15 +146,6 @@ commercial products, provided that all warranty or liability claims are
 assumed by the product vendor.
 
 
-ansi2knr.c is included in this distribution by permission of L. Peter Deutsch,
-sole proprietor of its copyright holder, Aladdin Enterprises of Menlo Park, CA.
-ansi2knr.c is NOT covered by the above copyright and conditions, but instead
-by the usual distribution terms of the Free Software Foundation; principally,
-that you must include source code if you redistribute it.  (See the file
-ansi2knr.c for full details.)  However, since ansi2knr.c is not needed as part
-of any program generated from the IJG code, this does not limit you more than
-the foregoing paragraphs do.
-
 The Unix configuration script "configure" was produced with GNU Autoconf.
 It is copyright by the Free Software Foundation but is freely distributable.
 The same holds for its supporting scripts (config.guess, config.sub,
@@ -162,11 +153,11 @@ ltmain.sh).  Another support script, install-sh, is copyright by X Consortium
 but is also freely distributable.
 
 The IJG distribution formerly included code to read and write GIF files.
-To avoid entanglement with the Unisys LZW patent, GIF reading support has
-been removed altogether, and the GIF writer has been simplified to produce
-"uncompressed GIFs".  This technique does not use the LZW algorithm; the
-resulting GIF files are larger than usual, but are readable by all standard
-GIF decoders.
+To avoid entanglement with the Unisys LZW patent (now expired), GIF reading
+support has been removed altogether, and the GIF writer has been simplified
+to produce "uncompressed GIFs".  This technique does not use the LZW
+algorithm; the resulting GIF files are larger than usual, but are readable
+by all standard GIF decoders.
 
 We are required to state that
     "The Graphics Interchange Format(c) is the Copyright property of
@@ -222,12 +213,16 @@ Part 1: Requirements and guidelines" and has document numbers ISO/IEC IS
 10918-1, ITU-T T.81.  Part 2 is titled "Digital Compression and Coding of
 Continuous-tone Still Images, Part 2: Compliance testing" and has document
 numbers ISO/IEC IS 10918-2, ITU-T T.83.
-IJG JPEG 8 introduces an implementation of the JPEG SmartScale extension
+IJG JPEG 8 introduced an implementation of the JPEG SmartScale extension
 which is specified in two documents:  A contributed document at ITU and ISO
 with title "ITU-T JPEG-Plus Proposal for Extending ITU-T T.81 for Advanced
 Image Coding", April 2006, Geneva, Switzerland.  The latest version of this
 document is Revision 3.  And a contributed document ISO/IEC JTC1/SC29/WG1 N
 5799 with title "Evolution of JPEG", June/July 2011, Berlin, Germany.
+IJG JPEG 9 introduces a reversible color transform for improved lossless
+compression which is described in a contributed document ISO/IEC JTC1/SC29/
+WG1 N 6080 with title "JPEG 9 Lossless Coding", June/July 2012, Paris,
+France.
 
 The JPEG standard does not specify all details of an interchangeable file
 format.  For the omitted details we follow the "JFIF" conventions, revision
@@ -257,8 +252,8 @@ ARCHIVE LOCATIONS
 The "official" archive site for this software is www.ijg.org.
 The most recent released version can always be found there in
 directory "files".  This particular version will be archived as
-http://www.ijg.org/files/jpegsrc.v8d.tar.gz, and in Windows-compatible
-"zip" archive format as http://www.ijg.org/files/jpegsr8d.zip.
+http://www.ijg.org/files/jpegsrc.v9a.tar.gz, and in Windows-compatible
+"zip" archive format as http://www.ijg.org/files/jpegsr9a.zip.
 
 The JPEG FAQ (Frequently Asked Questions) article is a source of some
 general information about JPEG.
@@ -285,7 +280,7 @@ Thank to Thomas Wiegand and Gary Sullivan for inviting me to the
 Joint Video Team (MPEG & ITU) meeting in Geneva, Switzerland.
 
 Thank to Thomas Richter and Daniel Lee for inviting me to the
-ISO/IEC JTC1/SC29/WG1 (also known as JPEG, together with ITU-T SG16)
+ISO/IEC JTC1/SC29/WG1 (previously known as JPEG, together with ITU-T SG16)
 meeting in Berlin, Germany.
 
 Thank to John Korejwa and Massimo Ballerini for inviting me to
@@ -311,10 +306,10 @@ design and development of this singular software package.
 FILE FORMAT WARS
 ================
 
-The ISO/IEC JTC1/SC29/WG1 standards committee (also known as JPEG, together
-with ITU-T SG16) currently promotes different formats containing the name
-"JPEG" which is misleading because these formats are incompatible with
-original DCT-based JPEG and are based on faulty technologies.
+The ISO/IEC JTC1/SC29/WG1 standards committee (previously known as JPEG,
+together with ITU-T SG16) currently promotes different formats containing
+the name "JPEG" which is misleading because these formats are incompatible
+with original DCT-based JPEG and are based on faulty technologies.
 IJG therefore does not and will not support such momentary mistakes
 (see REFERENCES).
 There exist also distributions under the name "OpenJPEG" promoting such
@@ -327,25 +322,60 @@ Don't use an incompatible file format!
 (In any case, our decoder will remain capable of reading existing JPEG
 image files indefinitely.)
 
-Furthermore, the ISO committee pretends to be "responsible for the popular
-JPEG" in their public reports which is not true because they don't respond to
-actual requirements for the maintenance of the original JPEG specification.
-
-There are currently distributions in circulation containing the name
-"libjpeg" which claim to be a "derivative" or "fork" of the original
-libjpeg, but don't have the features and are incompatible with formats
-supported by actual IJG libjpeg distributions.  Furthermore, they
-violate the license conditions as described under LEGAL ISSUES above.
-We have no sympathy for the release of misleading and illegal
+The ISO committee pretends to be "responsible for the popular JPEG" in their
+public reports which is not true because they don't respond to actual
+requirements for the maintenance of the original JPEG specification.
+Furthermore, the ISO committee pretends to "ensure interoperability" with
+their standards which is not true because their "standards" support only
+application-specific and proprietary use cases and contain mathematically
+incorrect code.
+
+There are currently different distributions in circulation containing the
+name "libjpeg" which is misleading because they don't have the features and
+are incompatible with formats supported by actual IJG libjpeg distributions.
+One of those fakes is released by members of the ISO committee and just uses
+the name of libjpeg for misdirection of people, similar to the abuse of the
+name JPEG as described above, while having nothing in common with actual IJG
+libjpeg distributions and containing mathematically incorrect code.
+The other one claims to be a "derivative" or "fork" of the original libjpeg,
+but violates the license conditions as described under LEGAL ISSUES above
+and violates basic C programming properties.
+We have no sympathy for the release of misleading, incorrect and illegal
 distributions derived from obsolete code bases.
 Don't use an obsolete code base!
 
+According to the UCC (Uniform Commercial Code) law, IJG has the lawful and
+legal right to foreclose on certain standardization bodies and other
+institutions or corporations that knowingly perform substantial and
+systematic deceptive acts and practices, fraud, theft, and damaging of the
+value of the people of this planet without their knowing, willing and
+intentional consent.
+The titles, ownership, and rights of these institutions and all their assets
+are now duly secured and held in trust for the free people of this planet.
+People of the planet, on every country, may have a financial interest in
+the assets of these former principals, agents, and beneficiaries of the
+foreclosed institutions and corporations.
+IJG asserts what is: that each man, woman, and child has unalienable value
+and rights granted and deposited in them by the Creator and not any one of
+the people is subordinate to any artificial principality, corporate fiction
+or the special interest of another without their appropriate knowing,
+willing and intentional consent made by contract or accommodation agreement.
+IJG expresses that which already was.
+The people have already determined and demanded that public administration
+entities, national governments, and their supporting judicial systems must
+be fully transparent, accountable, and liable.
+IJG has secured the value for all concerned free people of the planet.
+
+A partial list of foreclosed institutions and corporations ("Hall of Shame")
+is currently prepared and will be published later.
+
 
 TO DO
 =====
 
-Version 8 is the first release of a new generation JPEG standard
-to overcome the limitations of the original JPEG specification.
+Version 9 is the second release of a new generation JPEG standard
+to overcome the limitations of the original JPEG specification,
+and is the first true source reference JPEG codec.
 More features are being prepared for coming releases...
 
 Please send bug reports, offers of help, etc. to jpeg-info at jpegclub.org.
diff --git a/Source/LibJPEG/change.log b/Source/LibJPEG/change.log
index ce71abd..26b628b 100644
--- a/Source/LibJPEG/change.log
+++ b/Source/LibJPEG/change.log
@@ -1,6 +1,69 @@
 CHANGE LOG for Independent JPEG Group's JPEG software
 
 
+Version 9a  19-Jan-2014
+-----------------------
+
+Add support for wide gamut color spaces (JFIF version 2).
+Improve clarity and accuracy in color conversion modules.
+Note: Requires rebuild of test images.
+
+Extend the bit depth support to all values from 8 to 12
+(BITS_IN_JSAMPLE configuration option in jmorecfg.h).
+jpegtran now supports N bits sample data precision with all N from 8 to 12
+in a single instance.  Thank to Roland Fassauer for inspiration.
+
+Try to resolve issues with new boolean type definition.
+Thank also to v4hn for suggestion.
+
+Enable option to use default Huffman tables for lossless compression
+(for hardware solution), and in this case improve lossless RGB compression
+with reversible color transform.  Thank to Benny Alexandar for hint.
+
+Extend the entropy decoding structure, so that extraneous bytes between
+compressed scan data and following marker can be reported correctly.
+Thank to Nigel Tao for hint.
+
+Add jpegtran -wipe option and extension for -crop.
+Thank to Andrew Senior, David Clunie, and Josef Schmid for suggestion.
+
+
+Version 9  13-Jan-2013
+----------------------
+
+Add cjpeg -rgb1 option to create an RGB JPEG file, and insert
+a simple reversible color transform into the processing which
+significantly improves the compression.
+The recommended command for lossless coding of RGB images is now
+cjpeg -rgb1 -block 1 -arithmetic.
+As said, this option improves the compression significantly, but
+the files are not compatible with JPEG decoders prior to IJG v9
+due to the included color transform.
+The used color transform and marker signaling is compatible with
+other JPEG standards (e.g., JPEG-LS part 2).
+
+Remove the automatic de-ANSI-fication support (Automake 1.12).
+Thank also to Nitin A Kamble for suggestion.
+
+Add remark for jpeg_mem_dest() in jdatadst.c.
+Thank to Elie-Gregoire Khoury for the hint.
+
+Support files with invalid component identifiers (created
+by Adobe PDF).  Thank to Robin Watts for the suggestion.
+
+Adapt full buffer case in jcmainct.c for use with scaled DCT.
+Thank to Sergii Biloshytskyi for the suggestion.
+
+Add type identifier for declaration of noreturn functions.
+Thank to Brett L. Moore for the suggestion.
+
+Correct argument type in format string, avoid compiler warnings.
+Thank to Vincent Torri for hint.
+
+Add missing #include directives in configuration checks, avoid
+configuration errors.  Thank to John Spencer for the hint.
+
+
 Version 8d  15-Jan-2012
 -----------------------
 
diff --git a/Source/LibJPEG/cjpeg.c b/Source/LibJPEG/cjpeg.c
index a999eee..b9b65b8 100644
--- a/Source/LibJPEG/cjpeg.c
+++ b/Source/LibJPEG/cjpeg.c
@@ -2,7 +2,7 @@
  * cjpeg.c
  *
  * Copyright (C) 1991-1998, Thomas G. Lane.
- * Modified 2003-2011 by Guido Vollbeding.
+ * Modified 2003-2013 by Guido Vollbeding.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
@@ -172,6 +172,10 @@ usage (void)
 #ifdef DCT_SCALING_SUPPORTED
   fprintf(stderr, "  -block N       DCT block size (1..16; default is 8)\n");
 #endif
+#if JPEG_LIB_VERSION_MAJOR >= 9
+  fprintf(stderr, "  -rgb1          Create RGB JPEG file with reversible color transform\n");
+  fprintf(stderr, "  -bgycc         Create big gamut YCC JPEG file\n");
+#endif
 #ifdef DCT_ISLOW_SUPPORTED
   fprintf(stderr, "  -dct int       Use integer DCT method%s\n",
 	  (JDCT_DEFAULT == JDCT_ISLOW ? " (default)" : ""));
@@ -310,10 +314,27 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
       /* Force a monochrome JPEG file to be generated. */
       jpeg_set_colorspace(cinfo, JCS_GRAYSCALE);
 
-    } else if (keymatch(arg, "rgb", 3)) {
+    } else if (keymatch(arg, "rgb", 3) || keymatch(arg, "rgb1", 4)) {
       /* Force an RGB JPEG file to be generated. */
+#if JPEG_LIB_VERSION_MAJOR >= 9
+      /* Note: Entropy table assignment in jpeg_set_colorspace depends
+       * on color_transform.
+       */
+      cinfo->color_transform = arg[3] ? JCT_SUBTRACT_GREEN : JCT_NONE;
+#endif
       jpeg_set_colorspace(cinfo, JCS_RGB);
 
+    } else if (keymatch(arg, "bgycc", 5)) {
+      /* Force a big gamut YCC JPEG file to be generated. */
+#if JPEG_LIB_VERSION_MAJOR >= 9 && \
+      (JPEG_LIB_VERSION_MAJOR > 9 || JPEG_LIB_VERSION_MINOR >= 1)
+      jpeg_set_colorspace(cinfo, JCS_BG_YCC);
+#else
+      fprintf(stderr, "%s: sorry, BG_YCC colorspace not supported\n",
+	      progname);
+      exit(EXIT_FAILURE);
+#endif
+
     } else if (keymatch(arg, "maxmemory", 3)) {
       /* Maximum memory in Kb (or Mb with 'm'). */
       long lval;
@@ -328,7 +349,7 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
       cinfo->mem->max_memory_to_use = lval * 1000L;
 
     } else if (keymatch(arg, "nosmooth", 3)) {
-      /* Suppress fancy downsampling */
+      /* Suppress fancy downsampling. */
       cinfo->do_fancy_downsampling = FALSE;
 
     } else if (keymatch(arg, "optimize", 1) || keymatch(arg, "optimise", 1)) {
@@ -414,7 +435,7 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
       /* Scale the image by a fraction M/N. */
       if (++argn >= argc)	/* advance to next argument */
 	usage();
-      if (sscanf(argv[argn], "%d/%d",
+      if (sscanf(argv[argn], "%u/%u",
 		 &cinfo->scale_num, &cinfo->scale_denom) != 2)
 	usage();
 
diff --git a/Source/LibJPEG/djpeg.c b/Source/LibJPEG/djpeg.c
index 363c628..77718ce 100644
--- a/Source/LibJPEG/djpeg.c
+++ b/Source/LibJPEG/djpeg.c
@@ -2,7 +2,7 @@
  * djpeg.c
  *
  * Copyright (C) 1991-1997, Thomas G. Lane.
- * Modified 2009 by Guido Vollbeding.
+ * Modified 2009-2013 by Guido Vollbeding.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
@@ -298,7 +298,7 @@ parse_switches (j_decompress_ptr cinfo, int argc, char **argv,
       cinfo->mem->max_memory_to_use = lval * 1000L;
 
     } else if (keymatch(arg, "nosmooth", 3)) {
-      /* Suppress fancy upsampling */
+      /* Suppress fancy upsampling. */
       cinfo->do_fancy_upsampling = FALSE;
 
     } else if (keymatch(arg, "onepass", 3)) {
@@ -327,7 +327,7 @@ parse_switches (j_decompress_ptr cinfo, int argc, char **argv,
       /* Scale the output image by a fraction M/N. */
       if (++argn >= argc)	/* advance to next argument */
 	usage();
-      if (sscanf(argv[argn], "%d/%d",
+      if (sscanf(argv[argn], "%u/%u",
 		 &cinfo->scale_num, &cinfo->scale_denom) < 1)
 	usage();
 
diff --git a/Source/LibJPEG/filelist.txt b/Source/LibJPEG/filelist.txt
index 040abff..62aba52 100644
--- a/Source/LibJPEG/filelist.txt
+++ b/Source/LibJPEG/filelist.txt
@@ -1,6 +1,6 @@
 IJG JPEG LIBRARY:  FILE LIST
 
-Copyright (C) 1994-2009, Thomas G. Lane, Guido Vollbeding.
+Copyright (C) 1994-2013, Thomas G. Lane, Guido Vollbeding.
 This file is part of the Independent JPEG Group's software.
 For conditions of distribution and use, see the accompanying README file.
 
@@ -197,6 +197,8 @@ config.guess
 config.sub
 depcomp
 missing
+ar-lib
+compile
 install-sh	Install shell script for those Unix systems lacking one.
 Makefile.in	Makefile input for configure.
 Makefile.am	Source file for use with Automake to generate Makefile.in.
@@ -206,8 +208,6 @@ mak*.*		Sample makefiles for particular systems.
 jconfig.*	Sample jconfig.h for particular systems.
 libjpeg.map	Script to generate shared library with versioned symbols.
 aclocal.m4	M4 macro definitions for use with Autoconf.
-ansi2knr.c	De-ANSIfier for pre-ANSI C compilers (courtesy of
-		L. Peter Deutsch and Aladdin Enterprises).
 
 Test files (see install.txt for test procedure):
 
diff --git a/Source/LibJPEG/install.txt b/Source/LibJPEG/install.txt
index d8f2495..8e6b721 100644
--- a/Source/LibJPEG/install.txt
+++ b/Source/LibJPEG/install.txt
@@ -1,6 +1,6 @@
 INSTALLATION INSTRUCTIONS for the Independent JPEG Group's JPEG software
 
-Copyright (C) 1991-2011, Thomas G. Lane, Guido Vollbeding.
+Copyright (C) 1991-2013, Thomas G. Lane, Guido Vollbeding.
 This file is part of the Independent JPEG Group's software.
 For conditions of distribution and use, see the accompanying README file.
 
@@ -418,54 +418,58 @@ support as follows:
 	    the directory containing the URT "librle.a" file (typically the
 	    "lib" subdirectory of the URT distribution).
 
-Support for 12-bit-deep pixel data:
+Support for 9-bit to 12-bit deep pixel data:
 
-The JPEG standard allows either 8-bit or 12-bit data precision.  (For color,
-this means 8 or 12 bits per channel, of course.)  If you need to work with
-deeper than 8-bit data, you can compile the IJG code for 12-bit operation.
+The IJG code currently allows 8, 9, 10, 11, or 12 bits sample data precision.
+(For color, this means 8 to 12 bits per channel, of course.)  If you need to
+work with deeper than 8-bit data, you can compile the IJG code for 9-bit to
+12-bit operation.
 To do so:
-  1. In jmorecfg.h, define BITS_IN_JSAMPLE as 12 rather than 8.
+  1. In jmorecfg.h, define BITS_IN_JSAMPLE as 9, 10, 11, or 12 rather than 8.
   2. In jconfig.h, undefine BMP_SUPPORTED, RLE_SUPPORTED, and TARGA_SUPPORTED,
-     because the code for those formats doesn't handle 12-bit data and won't
-     even compile.  (The PPM code does work, as explained below.  The GIF
-     code works too; it scales 8-bit GIF data to and from 12-bit depth
-     automatically.)
+     because the code for those formats doesn't handle deeper than 8-bit data
+     and won't even compile.  (The PPM code does work, as explained below.
+     The GIF code works too; it scales 8-bit GIF data to and from 12-bit
+     depth automatically.)
   3. Compile.  Don't expect "make test" to pass, since the supplied test
      files are for 8-bit data.
 
-Currently, 12-bit support does not work on 16-bit-int machines.
+Currently, 9-bit to 12-bit support does not work on 16-bit-int machines.
 
-Note that a 12-bit version will not read 8-bit JPEG files, nor vice versa;
-so you'll want to keep around a regular 8-bit compilation as well.
-(Run-time selection of data depth, to allow a single copy that does both,
-is possible but would probably slow things down considerably; it's very low
-on our to-do list.)
+Run-time selection and conversion of data precision are currently not
+supported and may be added later.
+Exception:  The transcoding part (jpegtran) supports all settings in a
+single instance, since it operates on the level of DCT coefficients and
+not sample values.
 
-The PPM reader (rdppm.c) can read 12-bit data from either text-format or
-binary-format PPM and PGM files.  Binary-format PPM/PGM files which have a
-maxval greater than 255 are assumed to use 2 bytes per sample, MSB first
-(big-endian order).  As of early 1995, 2-byte binary format is not
+The PPM reader (rdppm.c) can read deeper than 8-bit data from either
+text-format or binary-format PPM and PGM files.  Binary-format PPM/PGM files
+which have a maxval greater than 255 are assumed to use 2 bytes per sample,
+MSB first (big-endian order).  As of early 1995, 2-byte binary format is not
 officially supported by the PBMPLUS library, but it is expected that a
 future release of PBMPLUS will support it.  Note that the PPM reader will
 read files of any maxval regardless of the BITS_IN_JSAMPLE setting; incoming
-data is automatically rescaled to either maxval=255 or maxval=4095 as
-appropriate for the cjpeg bit depth.
+data is automatically rescaled to maxval=MAXJSAMPLE as appropriate for the
+cjpeg bit depth.
 
 The PPM writer (wrppm.c) will normally write 2-byte binary PPM or PGM
-format, maxval 4095, when compiled with BITS_IN_JSAMPLE=12.  Since this
+format, maxval=MAXJSAMPLE, when compiled with BITS_IN_JSAMPLE>8.  Since this
 format is not yet widely supported, you can disable it by compiling wrppm.c
 with PPM_NORAWWORD defined; then the data is scaled down to 8 bits to make a
 standard 1-byte/sample PPM or PGM file.  (Yes, this means still another copy
 of djpeg to keep around.  But hopefully you won't need it for very long.
 Poskanzer's supposed to get that new PBMPLUS release out Real Soon Now.)
 
-Of course, if you are working with 12-bit data, you probably have it stored
-in some other, nonstandard format.  In that case you'll probably want to
-write your own I/O modules to read and write your format.
+Of course, if you are working with 9-bit to 12-bit data, you probably have
+it stored in some other, nonstandard format.  In that case you'll probably
+want to write your own I/O modules to read and write your format.
 
-Note that a 12-bit version of cjpeg always runs in "-optimize" mode, in
-order to generate valid Huffman tables.  This is necessary because our
-default Huffman tables only cover 8-bit data.
+Note:
+The standard Huffman tables are only valid for 8-bit data precision.  If
+you selected more than 8-bit data precision, cjpeg uses arithmetic coding
+by default.  The Huffman encoder normally uses entropy optimization to
+compute usable tables for higher precision.  Otherwise, you'll have to
+supply different default Huffman tables.
 
 Removing code:
 
@@ -848,17 +852,23 @@ with /Oo-.
 Microsoft Windows (all versions), generic comments:
 
 Some Windows system include files define typedef boolean as "unsigned char".
-The IJG code also defines typedef boolean, but we make it "int" by default.
+The IJG code also defines typedef boolean, but we make it an "enum" by default.
 This doesn't affect the IJG programs because we don't import those Windows
 include files.  But if you use the JPEG library in your own program, and some
 of your program's files import one definition of boolean while some import the
 other, you can get all sorts of mysterious problems.  A good preventive step
 is to make the IJG library use "unsigned char" for boolean.  To do that,
 add something like this to your jconfig.h file:
-	/* Define "boolean" as unsigned char, not int, per Windows custom */
+	/* Define "boolean" as unsigned char, not enum, per Windows custom */
 	#ifndef __RPCNDR_H__	/* don't conflict if rpcndr.h already read */
 	typedef unsigned char boolean;
 	#endif
+	#ifndef FALSE		/* in case these macros already exist */
+	#define FALSE	0	/* values of boolean */
+	#endif
+	#ifndef TRUE
+	#define TRUE	1
+	#endif
 	#define HAVE_BOOLEAN	/* prevent jmorecfg.h from redefining it */
 (This is already in jconfig.vc, by the way.)
 
diff --git a/Source/LibJPEG/jcapistd.c b/Source/LibJPEG/jcapistd.c
index c0320b1..0917afa 100644
--- a/Source/LibJPEG/jcapistd.c
+++ b/Source/LibJPEG/jcapistd.c
@@ -2,6 +2,7 @@
  * jcapistd.c
  *
  * Copyright (C) 1994-1996, Thomas G. Lane.
+ * Modified 2013 by Guido Vollbeding.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
@@ -145,7 +146,7 @@ jpeg_write_raw_data (j_compress_ptr cinfo, JSAMPIMAGE data,
     (*cinfo->master->pass_startup) (cinfo);
 
   /* Verify that at least one iMCU row has been passed. */
-  lines_per_iMCU_row = cinfo->max_v_samp_factor * DCTSIZE;
+  lines_per_iMCU_row = cinfo->max_v_samp_factor * cinfo->min_DCT_v_scaled_size;
   if (num_lines < lines_per_iMCU_row)
     ERREXIT(cinfo, JERR_BUFFER_SIZE);
 
diff --git a/Source/LibJPEG/jcarith.c b/Source/LibJPEG/jcarith.c
index 033f670..a64190e 100644
--- a/Source/LibJPEG/jcarith.c
+++ b/Source/LibJPEG/jcarith.c
@@ -1,7 +1,7 @@
 /*
  * jcarith.c
  *
- * Developed 1997-2011 by Guido Vollbeding.
+ * Developed 1997-2013 by Guido Vollbeding.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
@@ -362,7 +362,6 @@ METHODDEF(boolean)
 encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
 {
   arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
-  JBLOCKROW block;
   unsigned char *st;
   int blkn, ci, tbl;
   int v, v2, m;
@@ -381,14 +380,13 @@ encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
 
   /* Encode the MCU data blocks */
   for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
-    block = MCU_data[blkn];
     ci = cinfo->MCU_membership[blkn];
     tbl = cinfo->cur_comp_info[ci]->dc_tbl_no;
 
     /* Compute the DC value after the required point transform by Al.
      * This is simply an arithmetic right shift.
      */
-    m = IRIGHT_SHIFT((int) ((*block)[0]), cinfo->Al);
+    m = IRIGHT_SHIFT((int) (MCU_data[blkn][0][0]), cinfo->Al);
 
     /* Sections F.1.4.1 & F.1.4.4.1: Encoding of DC coefficients */
 
@@ -453,11 +451,11 @@ METHODDEF(boolean)
 encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
 {
   arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
+  const int * natural_order;
   JBLOCKROW block;
   unsigned char *st;
   int tbl, k, ke;
   int v, v2, m;
-  const int * natural_order;
 
   /* Emit restart marker if needed */
   if (cinfo->restart_interval) {
@@ -479,7 +477,8 @@ encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
   /* Sections F.1.4.2 & F.1.4.4.2: Encoding of AC coefficients */
 
   /* Establish EOB (end-of-block) index */
-  for (ke = cinfo->Se; ke > 0; ke--)
+  ke = cinfo->Se;
+  do {
     /* We must apply the point transform by Al.  For AC coefficients this
      * is an integer division with rounding towards 0.  To do this portably
      * in C, we shift after obtaining the absolute value.
@@ -490,13 +489,14 @@ encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
       v = -v;
       if (v >>= cinfo->Al) break;
     }
+  } while (--ke);
 
   /* Figure F.5: Encode_AC_Coefficients */
-  for (k = cinfo->Ss; k <= ke; k++) {
-    st = entropy->ac_stats[tbl] + 3 * (k - 1);
+  for (k = cinfo->Ss - 1; k < ke;) {
+    st = entropy->ac_stats[tbl] + 3 * k;
     arith_encode(cinfo, st, 0);		/* EOB decision */
     for (;;) {
-      if ((v = (*block)[natural_order[k]]) >= 0) {
+      if ((v = (*block)[natural_order[++k]]) >= 0) {
 	if (v >>= cinfo->Al) {
 	  arith_encode(cinfo, st + 1, 1);
 	  arith_encode(cinfo, entropy->fixed_bin, 0);
@@ -510,7 +510,8 @@ encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
 	  break;
 	}
       }
-      arith_encode(cinfo, st + 1, 0); st += 3; k++;
+      arith_encode(cinfo, st + 1, 0);
+      st += 3;
     }
     st += 2;
     /* Figure F.8: Encoding the magnitude category of v */
@@ -537,9 +538,9 @@ encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
     while (m >>= 1)
       arith_encode(cinfo, st, (m & v) ? 1 : 0);
   }
-  /* Encode EOB decision only if k <= cinfo->Se */
-  if (k <= cinfo->Se) {
-    st = entropy->ac_stats[tbl] + 3 * (k - 1);
+  /* Encode EOB decision only if k < cinfo->Se */
+  if (k < cinfo->Se) {
+    st = entropy->ac_stats[tbl] + 3 * k;
     arith_encode(cinfo, st, 1);
   }
 
@@ -549,6 +550,8 @@ encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
 
 /*
  * MCU encoding for DC successive approximation refinement scan.
+ * Note: we assume such scans can be multi-component,
+ * although the spec is not very clear on the point.
  */
 
 METHODDEF(boolean)
@@ -590,11 +593,11 @@ METHODDEF(boolean)
 encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
 {
   arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
+  const int * natural_order;
   JBLOCKROW block;
   unsigned char *st;
   int tbl, k, ke, kex;
   int v;
-  const int * natural_order;
 
   /* Emit restart marker if needed */
   if (cinfo->restart_interval) {
@@ -616,7 +619,8 @@ encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
   /* Section G.1.3.3: Encoding of AC coefficients */
 
   /* Establish EOB (end-of-block) index */
-  for (ke = cinfo->Se; ke > 0; ke--)
+  ke = cinfo->Se;
+  do {
     /* We must apply the point transform by Al.  For AC coefficients this
      * is an integer division with rounding towards 0.  To do this portably
      * in C, we shift after obtaining the absolute value.
@@ -627,6 +631,7 @@ encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
       v = -v;
       if (v >>= cinfo->Al) break;
     }
+  } while (--ke);
 
   /* Establish EOBx (previous stage end-of-block) index */
   for (kex = ke; kex > 0; kex--)
@@ -638,12 +643,12 @@ encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
     }
 
   /* Figure G.10: Encode_AC_Coefficients_SA */
-  for (k = cinfo->Ss; k <= ke; k++) {
-    st = entropy->ac_stats[tbl] + 3 * (k - 1);
-    if (k > kex)
+  for (k = cinfo->Ss - 1; k < ke;) {
+    st = entropy->ac_stats[tbl] + 3 * k;
+    if (k >= kex)
       arith_encode(cinfo, st, 0);	/* EOB decision */
     for (;;) {
-      if ((v = (*block)[natural_order[k]]) >= 0) {
+      if ((v = (*block)[natural_order[++k]]) >= 0) {
 	if (v >>= cinfo->Al) {
 	  if (v >> 1)			/* previously nonzero coef */
 	    arith_encode(cinfo, st + 2, (v & 1));
@@ -665,12 +670,13 @@ encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
 	  break;
 	}
       }
-      arith_encode(cinfo, st + 1, 0); st += 3; k++;
+      arith_encode(cinfo, st + 1, 0);
+      st += 3;
     }
   }
-  /* Encode EOB decision only if k <= cinfo->Se */
-  if (k <= cinfo->Se) {
-    st = entropy->ac_stats[tbl] + 3 * (k - 1);
+  /* Encode EOB decision only if k < cinfo->Se */
+  if (k < cinfo->Se) {
+    st = entropy->ac_stats[tbl] + 3 * k;
     arith_encode(cinfo, st, 1);
   }
 
@@ -686,12 +692,13 @@ METHODDEF(boolean)
 encode_mcu (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
 {
   arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
-  jpeg_component_info * compptr;
+  const int * natural_order;
   JBLOCKROW block;
   unsigned char *st;
-  int blkn, ci, tbl, k, ke;
+  int tbl, k, ke;
   int v, v2, m;
-  const int * natural_order;
+  int blkn, ci;
+  jpeg_component_info * compptr;
 
   /* Emit restart marker if needed */
   if (cinfo->restart_interval) {
@@ -922,7 +929,7 @@ jinit_arith_encoder (j_compress_ptr cinfo)
   entropy = (arith_entropy_ptr)
     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 				SIZEOF(arith_entropy_encoder));
-  cinfo->entropy = (struct jpeg_entropy_encoder *) entropy;
+  cinfo->entropy = &entropy->pub;
   entropy->pub.start_pass = start_pass;
   entropy->pub.finish_pass = finish_pass;
 
diff --git a/Source/LibJPEG/jccolor.c b/Source/LibJPEG/jccolor.c
index 3e2d0e9..f6b4a49 100644
--- a/Source/LibJPEG/jccolor.c
+++ b/Source/LibJPEG/jccolor.c
@@ -2,7 +2,7 @@
  * jccolor.c
  *
  * Copyright (C) 1991-1996, Thomas G. Lane.
- * Modified 2011 by Guido Vollbeding.
+ * Modified 2011-2013 by Guido Vollbeding.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
@@ -29,13 +29,25 @@ typedef my_color_converter * my_cconvert_ptr;
 /**************** RGB -> YCbCr conversion: most common case **************/
 
 /*
- * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
- * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
- * The conversion equations to be implemented are therefore
- *	Y  =  0.29900 * R + 0.58700 * G + 0.11400 * B
- *	Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B  + CENTERJSAMPLE
- *	Cr =  0.50000 * R - 0.41869 * G - 0.08131 * B  + CENTERJSAMPLE
- * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
+ * YCbCr is defined per Recommendation ITU-R BT.601-7 (03/2011),
+ * previously known as Recommendation CCIR 601-1, except that Cb and Cr
+ * are normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
+ * sRGB (standard RGB color space) is defined per IEC 61966-2-1:1999.
+ * sYCC (standard luma-chroma-chroma color space with extended gamut)
+ * is defined per IEC 61966-2-1:1999 Amendment A1:2003 Annex F.
+ * bg-sRGB and bg-sYCC (big gamut standard color spaces)
+ * are defined per IEC 61966-2-1:1999 Amendment A1:2003 Annex G.
+ * Note that the derived conversion coefficients given in some of these
+ * documents are imprecise.  The general conversion equations are
+ *	Y  = Kr * R + (1 - Kr - Kb) * G + Kb * B
+ *	Cb = 0.5 * (B - Y) / (1 - Kb)
+ *	Cr = 0.5 * (R - Y) / (1 - Kr)
+ * With Kr = 0.299 and Kb = 0.114 (derived according to SMPTE RP 177-1993
+ * from the 1953 FCC NTSC primaries and CIE Illuminant C),
+ * the conversion equations to be implemented are therefore
+ *	Y  =  0.299 * R + 0.587 * G + 0.114 * B
+ *	Cb = -0.168735892 * R - 0.331264108 * G + 0.5 * B + CENTERJSAMPLE
+ *	Cr =  0.5 * R - 0.418687589 * G - 0.081312411 * B + CENTERJSAMPLE
  * Note: older versions of the IJG code used a zero offset of MAXJSAMPLE/2,
  * rather than CENTERJSAMPLE, for Cb and Cr.  This gave equal positive and
  * negative swings for Cb/Cr, but meant that grayscale values (Cb=Cr=0)
@@ -49,9 +61,9 @@ typedef my_color_converter * my_cconvert_ptr;
  * For even more speed, we avoid doing any multiplications in the inner loop
  * by precalculating the constants times R,G,B for all possible values.
  * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
- * for 12-bit samples it is still acceptable.  It's not very reasonable for
- * 16-bit samples, but if you want lossless storage you shouldn't be changing
- * colorspace anyway.
+ * for 9-bit to 12-bit samples it is still acceptable.  It's not very
+ * reasonable for 16-bit samples, but if you want lossless storage you
+ * shouldn't be changing colorspace anyway.
  * The CENTERJSAMPLE offsets and the rounding fudge-factor of 0.5 are included
  * in the tables to save adding them separately in the inner loop.
  */
@@ -96,21 +108,21 @@ rgb_ycc_start (j_compress_ptr cinfo)
 				(TABLE_SIZE * SIZEOF(INT32)));
 
   for (i = 0; i <= MAXJSAMPLE; i++) {
-    rgb_ycc_tab[i+R_Y_OFF] = FIX(0.29900) * i;
-    rgb_ycc_tab[i+G_Y_OFF] = FIX(0.58700) * i;
-    rgb_ycc_tab[i+B_Y_OFF] = FIX(0.11400) * i     + ONE_HALF;
-    rgb_ycc_tab[i+R_CB_OFF] = (-FIX(0.16874)) * i;
-    rgb_ycc_tab[i+G_CB_OFF] = (-FIX(0.33126)) * i;
+    rgb_ycc_tab[i+R_Y_OFF] = FIX(0.299) * i;
+    rgb_ycc_tab[i+G_Y_OFF] = FIX(0.587) * i;
+    rgb_ycc_tab[i+B_Y_OFF] = FIX(0.114) * i   + ONE_HALF;
+    rgb_ycc_tab[i+R_CB_OFF] = (-FIX(0.168735892)) * i;
+    rgb_ycc_tab[i+G_CB_OFF] = (-FIX(0.331264108)) * i;
     /* We use a rounding fudge-factor of 0.5-epsilon for Cb and Cr.
      * This ensures that the maximum output will round to MAXJSAMPLE
      * not MAXJSAMPLE+1, and thus that we don't have to range-limit.
      */
-    rgb_ycc_tab[i+B_CB_OFF] = FIX(0.50000) * i    + CBCR_OFFSET + ONE_HALF-1;
+    rgb_ycc_tab[i+B_CB_OFF] = FIX(0.5) * i    + CBCR_OFFSET + ONE_HALF-1;
 /*  B=>Cb and R=>Cr tables are the same
-    rgb_ycc_tab[i+R_CR_OFF] = FIX(0.50000) * i    + CBCR_OFFSET + ONE_HALF-1;
+    rgb_ycc_tab[i+R_CR_OFF] = FIX(0.5) * i    + CBCR_OFFSET + ONE_HALF-1;
 */
-    rgb_ycc_tab[i+G_CR_OFF] = (-FIX(0.41869)) * i;
-    rgb_ycc_tab[i+B_CR_OFF] = (-FIX(0.08131)) * i;
+    rgb_ycc_tab[i+G_CR_OFF] = (-FIX(0.418687589)) * i;
+    rgb_ycc_tab[i+B_CR_OFF] = (-FIX(0.081312411)) * i;
   }
 }
 
@@ -133,8 +145,8 @@ rgb_ycc_convert (j_compress_ptr cinfo,
 		 JDIMENSION output_row, int num_rows)
 {
   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
-  register int r, g, b;
   register INT32 * ctab = cconvert->rgb_ycc_tab;
+  register int r, g, b;
   register JSAMPROW inptr;
   register JSAMPROW outptr0, outptr1, outptr2;
   register JDIMENSION col;
@@ -150,7 +162,6 @@ rgb_ycc_convert (j_compress_ptr cinfo,
       r = GETJSAMPLE(inptr[RGB_RED]);
       g = GETJSAMPLE(inptr[RGB_GREEN]);
       b = GETJSAMPLE(inptr[RGB_BLUE]);
-      inptr += RGB_PIXELSIZE;
       /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
        * must be too; we do not need an explicit range-limiting operation.
        * Hence the value being shifted is never negative, and we don't
@@ -168,6 +179,7 @@ rgb_ycc_convert (j_compress_ptr cinfo,
       outptr2[col] = (JSAMPLE)
 		((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF])
 		 >> SCALEBITS);
+      inptr += RGB_PIXELSIZE;
     }
   }
 }
@@ -189,8 +201,8 @@ rgb_gray_convert (j_compress_ptr cinfo,
 		  JDIMENSION output_row, int num_rows)
 {
   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
-  register int r, g, b;
   register INT32 * ctab = cconvert->rgb_ycc_tab;
+  register int r, g, b;
   register JSAMPROW inptr;
   register JSAMPROW outptr;
   register JDIMENSION col;
@@ -198,17 +210,16 @@ rgb_gray_convert (j_compress_ptr cinfo,
 
   while (--num_rows >= 0) {
     inptr = *input_buf++;
-    outptr = output_buf[0][output_row];
-    output_row++;
+    outptr = output_buf[0][output_row++];
     for (col = 0; col < num_cols; col++) {
       r = GETJSAMPLE(inptr[RGB_RED]);
       g = GETJSAMPLE(inptr[RGB_GREEN]);
       b = GETJSAMPLE(inptr[RGB_BLUE]);
-      inptr += RGB_PIXELSIZE;
       /* Y */
       outptr[col] = (JSAMPLE)
 		((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
 		 >> SCALEBITS);
+      inptr += RGB_PIXELSIZE;
     }
   }
 }
@@ -228,8 +239,8 @@ cmyk_ycck_convert (j_compress_ptr cinfo,
 		   JDIMENSION output_row, int num_rows)
 {
   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
-  register int r, g, b;
   register INT32 * ctab = cconvert->rgb_ycc_tab;
+  register int r, g, b;
   register JSAMPROW inptr;
   register JSAMPROW outptr0, outptr1, outptr2, outptr3;
   register JDIMENSION col;
@@ -248,7 +259,6 @@ cmyk_ycck_convert (j_compress_ptr cinfo,
       b = MAXJSAMPLE - GETJSAMPLE(inptr[2]);
       /* K passes through as-is */
       outptr3[col] = inptr[3];	/* don't need GETJSAMPLE here */
-      inptr += 4;
       /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
        * must be too; we do not need an explicit range-limiting operation.
        * Hence the value being shifted is never negative, and we don't
@@ -266,6 +276,49 @@ cmyk_ycck_convert (j_compress_ptr cinfo,
       outptr2[col] = (JSAMPLE)
 		((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF])
 		 >> SCALEBITS);
+      inptr += 4;
+    }
+  }
+}
+
+
+/*
+ * Convert some rows of samples to the JPEG colorspace.
+ * [R,G,B] to [R-G,G,B-G] conversion with modulo calculation
+ * (forward reversible color transform).
+ * This can be seen as an adaption of the general RGB->YCbCr
+ * conversion equation with Kr = Kb = 0, while replacing the
+ * normalization by modulo calculation.
+ */
+
+METHODDEF(void)
+rgb_rgb1_convert (j_compress_ptr cinfo,
+		  JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+		  JDIMENSION output_row, int num_rows)
+{
+  register int r, g, b;
+  register JSAMPROW inptr;
+  register JSAMPROW outptr0, outptr1, outptr2;
+  register JDIMENSION col;
+  JDIMENSION num_cols = cinfo->image_width;
+
+  while (--num_rows >= 0) {
+    inptr = *input_buf++;
+    outptr0 = output_buf[0][output_row];
+    outptr1 = output_buf[1][output_row];
+    outptr2 = output_buf[2][output_row];
+    output_row++;
+    for (col = 0; col < num_cols; col++) {
+      r = GETJSAMPLE(inptr[RGB_RED]);
+      g = GETJSAMPLE(inptr[RGB_GREEN]);
+      b = GETJSAMPLE(inptr[RGB_BLUE]);
+      /* Assume that MAXJSAMPLE+1 is a power of 2, so that the MOD
+       * (modulo) operator is equivalent to the bitmask operator AND.
+       */
+      outptr0[col] = (JSAMPLE) ((r - g + CENTERJSAMPLE) & MAXJSAMPLE);
+      outptr1[col] = (JSAMPLE) g;
+      outptr2[col] = (JSAMPLE) ((b - g + CENTERJSAMPLE) & MAXJSAMPLE);
+      inptr += RGB_PIXELSIZE;
     }
   }
 }
@@ -274,7 +327,7 @@ cmyk_ycck_convert (j_compress_ptr cinfo,
 /*
  * Convert some rows of samples to the JPEG colorspace.
  * This version handles grayscale output with no conversion.
- * The source can be either plain grayscale or YCbCr (since Y == gray).
+ * The source can be either plain grayscale or YCC (since Y == gray).
  */
 
 METHODDEF(void)
@@ -282,16 +335,15 @@ grayscale_convert (j_compress_ptr cinfo,
 		   JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
 		   JDIMENSION output_row, int num_rows)
 {
+  int instride = cinfo->input_components;
   register JSAMPROW inptr;
   register JSAMPROW outptr;
   register JDIMENSION col;
   JDIMENSION num_cols = cinfo->image_width;
-  int instride = cinfo->input_components;
 
   while (--num_rows >= 0) {
     inptr = *input_buf++;
-    outptr = output_buf[0][output_row];
-    output_row++;
+    outptr = output_buf[0][output_row++];
     for (col = 0; col < num_cols; col++) {
       outptr[col] = inptr[0];	/* don't need GETJSAMPLE() here */
       inptr += instride;
@@ -344,20 +396,20 @@ null_convert (j_compress_ptr cinfo,
 	      JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
 	      JDIMENSION output_row, int num_rows)
 {
+  int ci;
+  register int nc = cinfo->num_components;
   register JSAMPROW inptr;
   register JSAMPROW outptr;
   register JDIMENSION col;
-  register int ci;
-  int nc = cinfo->num_components;
   JDIMENSION num_cols = cinfo->image_width;
 
   while (--num_rows >= 0) {
     /* It seems fastest to make a separate pass for each component. */
     for (ci = 0; ci < nc; ci++) {
-      inptr = *input_buf;
+      inptr = input_buf[0] + ci;
       outptr = output_buf[ci][output_row];
       for (col = 0; col < num_cols; col++) {
-	outptr[col] = inptr[ci]; /* don't need GETJSAMPLE() here */
+	*outptr++ = *inptr;	/* don't need GETJSAMPLE() here */
 	inptr += nc;
       }
     }
@@ -390,7 +442,7 @@ jinit_color_converter (j_compress_ptr cinfo)
   cconvert = (my_cconvert_ptr)
     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 				SIZEOF(my_color_converter));
-  cinfo->cconvert = (struct jpeg_color_converter *) cconvert;
+  cinfo->cconvert = &cconvert->pub;
   /* set start_pass to null method until we find out differently */
   cconvert->pub.start_pass = null_method;
 
@@ -402,11 +454,13 @@ jinit_color_converter (j_compress_ptr cinfo)
     break;
 
   case JCS_RGB:
+  case JCS_BG_RGB:
     if (cinfo->input_components != RGB_PIXELSIZE)
       ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
     break;
 
   case JCS_YCbCr:
+  case JCS_BG_YCC:
     if (cinfo->input_components != 3)
       ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
     break;
@@ -423,40 +477,96 @@ jinit_color_converter (j_compress_ptr cinfo)
     break;
   }
 
+  /* Support color transform only for RGB colorspaces */
+  if (cinfo->color_transform &&
+      cinfo->jpeg_color_space != JCS_RGB &&
+      cinfo->jpeg_color_space != JCS_BG_RGB)
+    ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+
   /* Check num_components, set conversion method based on requested space */
   switch (cinfo->jpeg_color_space) {
   case JCS_GRAYSCALE:
     if (cinfo->num_components != 1)
       ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
-    if (cinfo->in_color_space == JCS_GRAYSCALE ||
-	cinfo->in_color_space == JCS_YCbCr)
+    switch (cinfo->in_color_space) {
+    case JCS_GRAYSCALE:
+    case JCS_YCbCr:
+    case JCS_BG_YCC:
       cconvert->pub.color_convert = grayscale_convert;
-    else if (cinfo->in_color_space == JCS_RGB) {
+      break;
+    case JCS_RGB:
       cconvert->pub.start_pass = rgb_ycc_start;
       cconvert->pub.color_convert = rgb_gray_convert;
-    } else
+      break;
+    default:
       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+    }
     break;
 
   case JCS_RGB:
+  case JCS_BG_RGB:
     if (cinfo->num_components != 3)
       ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
-    if (cinfo->in_color_space == JCS_RGB)
-      cconvert->pub.color_convert = rgb_convert;
-    else
+    if (cinfo->in_color_space == cinfo->jpeg_color_space) {
+      switch (cinfo->color_transform) {
+      case JCT_NONE:
+	cconvert->pub.color_convert = rgb_convert;
+	break;
+      case JCT_SUBTRACT_GREEN:
+	cconvert->pub.color_convert = rgb_rgb1_convert;
+	break;
+      default:
+	ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+      }
+    } else
       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
     break;
 
   case JCS_YCbCr:
     if (cinfo->num_components != 3)
       ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
-    if (cinfo->in_color_space == JCS_RGB) {
+    switch (cinfo->in_color_space) {
+    case JCS_RGB:
       cconvert->pub.start_pass = rgb_ycc_start;
       cconvert->pub.color_convert = rgb_ycc_convert;
-    } else if (cinfo->in_color_space == JCS_YCbCr)
+      break;
+    case JCS_YCbCr:
       cconvert->pub.color_convert = null_convert;
-    else
+      break;
+    default:
+      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+    }
+    break;
+
+  case JCS_BG_YCC:
+    if (cinfo->num_components != 3)
+      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
+    switch (cinfo->in_color_space) {
+    case JCS_RGB:
+      /* For conversion from normal RGB input to BG_YCC representation,
+       * the Cb/Cr values are first computed as usual, and then
+       * quantized further after DCT processing by a factor of
+       * 2 in reference to the nominal quantization factor.
+       */
+      /* need quantization scale by factor of 2 after DCT */
+      cinfo->comp_info[1].component_needed = TRUE;
+      cinfo->comp_info[2].component_needed = TRUE;
+      /* compute normal YCC first */
+      cconvert->pub.start_pass = rgb_ycc_start;
+      cconvert->pub.color_convert = rgb_ycc_convert;
+      break;
+    case JCS_YCbCr:
+      /* need quantization scale by factor of 2 after DCT */
+      cinfo->comp_info[1].component_needed = TRUE;
+      cinfo->comp_info[2].component_needed = TRUE;
+      /*FALLTHROUGH*/
+    case JCS_BG_YCC:
+      /* Pass through for BG_YCC input */
+      cconvert->pub.color_convert = null_convert;
+      break;
+    default:
       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+    }
     break;
 
   case JCS_CMYK:
@@ -471,13 +581,17 @@ jinit_color_converter (j_compress_ptr cinfo)
   case JCS_YCCK:
     if (cinfo->num_components != 4)
       ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
-    if (cinfo->in_color_space == JCS_CMYK) {
+    switch (cinfo->in_color_space) {
+    case JCS_CMYK:
       cconvert->pub.start_pass = rgb_ycc_start;
       cconvert->pub.color_convert = cmyk_ycck_convert;
-    } else if (cinfo->in_color_space == JCS_YCCK)
+      break;
+    case JCS_YCCK:
       cconvert->pub.color_convert = null_convert;
-    else
+      break;
+    default:
       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+    }
     break;
 
   default:			/* allow null conversion of JCS_UNKNOWN */
diff --git a/Source/LibJPEG/jcdctmgr.c b/Source/LibJPEG/jcdctmgr.c
index 0bbdbb6..fafab91 100644
--- a/Source/LibJPEG/jcdctmgr.c
+++ b/Source/LibJPEG/jcdctmgr.c
@@ -2,6 +2,7 @@
  * jcdctmgr.c
  *
  * Copyright (C) 1994-1996, Thomas G. Lane.
+ * Modified 2003-2013 by Guido Vollbeding.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
@@ -25,22 +26,30 @@ typedef struct {
   /* Pointer to the DCT routine actually in use */
   forward_DCT_method_ptr do_dct[MAX_COMPONENTS];
 
-  /* The actual post-DCT divisors --- not identical to the quant table
-   * entries, because of scaling (especially for an unnormalized DCT).
-   * Each table is given in normal array order.
-   */
-  DCTELEM * divisors[NUM_QUANT_TBLS];
-
 #ifdef DCT_FLOAT_SUPPORTED
   /* Same as above for the floating-point case. */
   float_DCT_method_ptr do_float_dct[MAX_COMPONENTS];
-  FAST_FLOAT * float_divisors[NUM_QUANT_TBLS];
 #endif
 } my_fdct_controller;
 
 typedef my_fdct_controller * my_fdct_ptr;
 
 
+/* The allocated post-DCT divisor tables -- big enough for any
+ * supported variant and not identical to the quant table entries,
+ * because of scaling (especially for an unnormalized DCT) --
+ * are pointed to by dct_table in the per-component comp_info
+ * structures.  Each table is given in normal array order.
+ */
+
+typedef union {
+  DCTELEM int_array[DCTSIZE2];
+#ifdef DCT_FLOAT_SUPPORTED
+  FAST_FLOAT float_array[DCTSIZE2];
+#endif
+} divisor_table;
+
+
 /* The current scaled-DCT routines require ISLOW-style divisor tables,
  * so be sure to compile that code if either ISLOW or SCALING is requested.
  */
@@ -71,7 +80,7 @@ forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr,
   /* This routine is heavily used, so it's worth coding it tightly. */
   my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
   forward_DCT_method_ptr do_dct = fdct->do_dct[compptr->component_index];
-  DCTELEM * divisors = fdct->divisors[compptr->quant_tbl_no];
+  DCTELEM * divisors = (DCTELEM *) compptr->dct_table;
   DCTELEM workspace[DCTSIZE2];	/* work area for FDCT subroutine */
   JDIMENSION bi;
 
@@ -134,7 +143,7 @@ forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr,
   /* This routine is heavily used, so it's worth coding it tightly. */
   my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
   float_DCT_method_ptr do_dct = fdct->do_float_dct[compptr->component_index];
-  FAST_FLOAT * divisors = fdct->float_divisors[compptr->quant_tbl_no];
+  FAST_FLOAT * divisors = (FAST_FLOAT *) compptr->dct_table;
   FAST_FLOAT workspace[DCTSIZE2]; /* work area for FDCT subroutine */
   JDIMENSION bi;
 
@@ -352,22 +361,17 @@ start_pass_fdctmgr (j_compress_ptr cinfo)
 	cinfo->quant_tbl_ptrs[qtblno] == NULL)
       ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno);
     qtbl = cinfo->quant_tbl_ptrs[qtblno];
-    /* Compute divisors for this quant table */
-    /* We may do this more than once for same table, but it's not a big deal */
+    /* Create divisor table from quant table */
     switch (method) {
 #ifdef PROVIDE_ISLOW_TABLES
     case JDCT_ISLOW:
       /* For LL&M IDCT method, divisors are equal to raw quantization
        * coefficients multiplied by 8 (to counteract scaling).
        */
-      if (fdct->divisors[qtblno] == NULL) {
-	fdct->divisors[qtblno] = (DCTELEM *)
-	  (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
-				      DCTSIZE2 * SIZEOF(DCTELEM));
-      }
-      dtbl = fdct->divisors[qtblno];
+      dtbl = (DCTELEM *) compptr->dct_table;
       for (i = 0; i < DCTSIZE2; i++) {
-	dtbl[i] = ((DCTELEM) qtbl->quantval[i]) << 3;
+	dtbl[i] =
+	  ((DCTELEM) qtbl->quantval[i]) << (compptr->component_needed ? 4 : 3);
       }
       fdct->pub.forward_DCT[ci] = forward_DCT;
       break;
@@ -395,17 +399,12 @@ start_pass_fdctmgr (j_compress_ptr cinfo)
 	};
 	SHIFT_TEMPS
 
-	if (fdct->divisors[qtblno] == NULL) {
-	  fdct->divisors[qtblno] = (DCTELEM *)
-	    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
-					DCTSIZE2 * SIZEOF(DCTELEM));
-	}
-	dtbl = fdct->divisors[qtblno];
+	dtbl = (DCTELEM *) compptr->dct_table;
 	for (i = 0; i < DCTSIZE2; i++) {
 	  dtbl[i] = (DCTELEM)
 	    DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i],
 				  (INT32) aanscales[i]),
-		    CONST_BITS-3);
+		    compptr->component_needed ? CONST_BITS-4 : CONST_BITS-3);
 	}
       }
       fdct->pub.forward_DCT[ci] = forward_DCT;
@@ -422,25 +421,20 @@ start_pass_fdctmgr (j_compress_ptr cinfo)
 	 * What's actually stored is 1/divisor so that the inner loop can
 	 * use a multiplication rather than a division.
 	 */
-	FAST_FLOAT * fdtbl;
+	FAST_FLOAT * fdtbl = (FAST_FLOAT *) compptr->dct_table;
 	int row, col;
 	static const double aanscalefactor[DCTSIZE] = {
 	  1.0, 1.387039845, 1.306562965, 1.175875602,
 	  1.0, 0.785694958, 0.541196100, 0.275899379
 	};
 
-	if (fdct->float_divisors[qtblno] == NULL) {
-	  fdct->float_divisors[qtblno] = (FAST_FLOAT *)
-	    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
-					DCTSIZE2 * SIZEOF(FAST_FLOAT));
-	}
-	fdtbl = fdct->float_divisors[qtblno];
 	i = 0;
 	for (row = 0; row < DCTSIZE; row++) {
 	  for (col = 0; col < DCTSIZE; col++) {
 	    fdtbl[i] = (FAST_FLOAT)
-	      (1.0 / (((double) qtbl->quantval[i] *
-		       aanscalefactor[row] * aanscalefactor[col] * 8.0)));
+	      (1.0 / ((double) qtbl->quantval[i] *
+		      aanscalefactor[row] * aanscalefactor[col] *
+		      (compptr->component_needed ? 16.0 : 8.0)));
 	    i++;
 	  }
 	}
@@ -464,19 +458,20 @@ GLOBAL(void)
 jinit_forward_dct (j_compress_ptr cinfo)
 {
   my_fdct_ptr fdct;
-  int i;
+  int ci;
+  jpeg_component_info *compptr;
 
   fdct = (my_fdct_ptr)
     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 				SIZEOF(my_fdct_controller));
-  cinfo->fdct = (struct jpeg_forward_dct *) fdct;
+  cinfo->fdct = &fdct->pub;
   fdct->pub.start_pass = start_pass_fdctmgr;
 
-  /* Mark divisor tables unallocated */
-  for (i = 0; i < NUM_QUANT_TBLS; i++) {
-    fdct->divisors[i] = NULL;
-#ifdef DCT_FLOAT_SUPPORTED
-    fdct->float_divisors[i] = NULL;
-#endif
+  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+       ci++, compptr++) {
+    /* Allocate a divisor table for each component */
+    compptr->dct_table =
+      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				  SIZEOF(divisor_table));
   }
 }
diff --git a/Source/LibJPEG/jchuff.c b/Source/LibJPEG/jchuff.c
index 257d7aa..d1313f6 100644
--- a/Source/LibJPEG/jchuff.c
+++ b/Source/LibJPEG/jchuff.c
@@ -2,7 +2,7 @@
  * jchuff.c
  *
  * Copyright (C) 1991-1997, Thomas G. Lane.
- * Modified 2006-2009 by Guido Vollbeding.
+ * Modified 2006-2013 by Guido Vollbeding.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
@@ -308,24 +308,27 @@ emit_bits_s (working_state * state, unsigned int code, int size)
 /* Emit some bits; return TRUE if successful, FALSE if must suspend */
 {
   /* This routine is heavily used, so it's worth coding tightly. */
-  register INT32 put_buffer = (INT32) code;
-  register int put_bits = state->cur.put_bits;
+  register INT32 put_buffer;
+  register int put_bits;
 
   /* if size is 0, caller used an invalid Huffman table entry */
   if (size == 0)
     ERREXIT(state->cinfo, JERR_HUFF_MISSING_CODE);
 
-  put_buffer &= (((INT32) 1)<<size) - 1; /* mask off any extra bits in code */
-  
-  put_bits += size;		/* new number of bits in buffer */
-  
+  /* mask off any extra bits in code */
+  put_buffer = ((INT32) code) & ((((INT32) 1) << size) - 1);
+
+  /* new number of bits in buffer */
+  put_bits = size + state->cur.put_bits;
+
   put_buffer <<= 24 - put_bits; /* align incoming bits */
 
-  put_buffer |= state->cur.put_buffer; /* and merge with old buffer contents */
-  
+  /* and merge with old buffer contents */
+  put_buffer |= state->cur.put_buffer;
+
   while (put_bits >= 8) {
     int c = (int) ((put_buffer >> 16) & 0xFF);
-    
+
     emit_byte_s(state, c, return FALSE);
     if (c == 0xFF) {		/* need to stuff a zero byte? */
       emit_byte_s(state, 0, return FALSE);
@@ -347,8 +350,8 @@ emit_bits_e (huff_entropy_ptr entropy, unsigned int code, int size)
 /* Emit some bits, unless we are in gather mode */
 {
   /* This routine is heavily used, so it's worth coding tightly. */
-  register INT32 put_buffer = (INT32) code;
-  register int put_bits = entropy->saved.put_bits;
+  register INT32 put_buffer;
+  register int put_bits;
 
   /* if size is 0, caller used an invalid Huffman table entry */
   if (size == 0)
@@ -357,9 +360,11 @@ emit_bits_e (huff_entropy_ptr entropy, unsigned int code, int size)
   if (entropy->gather_statistics)
     return;			/* do nothing if we're only getting stats */
 
-  put_buffer &= (((INT32) 1)<<size) - 1; /* mask off any extra bits in code */
-  
-  put_bits += size;		/* new number of bits in buffer */
+  /* mask off any extra bits in code */
+  put_buffer = ((INT32) code) & ((((INT32) 1) << size) - 1);
+
+  /* new number of bits in buffer */
+  put_bits = size + entropy->saved.put_bits;
 
   put_buffer <<= 24 - put_bits; /* align incoming bits */
 
@@ -543,10 +548,7 @@ encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
   huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
   register int temp, temp2;
   register int nbits;
-  int blkn, ci;
-  int Al = cinfo->Al;
-  JBLOCKROW block;
-  jpeg_component_info * compptr;
+  int blkn, ci, tbl;
   ISHIFT_TEMPS
 
   entropy->next_output_byte = cinfo->dest->next_output_byte;
@@ -559,28 +561,27 @@ encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
 
   /* Encode the MCU data blocks */
   for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
-    block = MCU_data[blkn];
     ci = cinfo->MCU_membership[blkn];
-    compptr = cinfo->cur_comp_info[ci];
+    tbl = cinfo->cur_comp_info[ci]->dc_tbl_no;
 
     /* Compute the DC value after the required point transform by Al.
      * This is simply an arithmetic right shift.
      */
-    temp2 = IRIGHT_SHIFT((int) ((*block)[0]), Al);
+    temp = IRIGHT_SHIFT((int) (MCU_data[blkn][0][0]), cinfo->Al);
 
     /* DC differences are figured on the point-transformed values. */
-    temp = temp2 - entropy->saved.last_dc_val[ci];
-    entropy->saved.last_dc_val[ci] = temp2;
+    temp2 = temp - entropy->saved.last_dc_val[ci];
+    entropy->saved.last_dc_val[ci] = temp;
 
     /* Encode the DC coefficient difference per section G.1.2.1 */
-    temp2 = temp;
+    temp = temp2;
     if (temp < 0) {
       temp = -temp;		/* temp is abs value of input */
       /* For a negative input, want temp2 = bitwise complement of abs(input) */
       /* This code assumes we are on a two's complement machine */
       temp2--;
     }
-    
+
     /* Find the number of bits needed for the magnitude of the coefficient */
     nbits = 0;
     while (temp) {
@@ -592,10 +593,10 @@ encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
      */
     if (nbits > MAX_COEF_BITS+1)
       ERREXIT(cinfo, JERR_BAD_DCT_COEF);
-    
+
     /* Count/emit the Huffman-coded symbol for the number of bits */
-    emit_dc_symbol(entropy, compptr->dc_tbl_no, nbits);
-    
+    emit_dc_symbol(entropy, tbl, nbits);
+
     /* Emit that number of bits of the value, if positive, */
     /* or the complement of its magnitude, if negative. */
     if (nbits)			/* emit_bits rejects calls with size 0 */
@@ -628,12 +629,12 @@ METHODDEF(boolean)
 encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
 {
   huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
+  const int * natural_order;
+  JBLOCKROW block;
   register int temp, temp2;
   register int nbits;
   register int r, k;
   int Se, Al;
-  const int * natural_order;
-  JBLOCKROW block;
 
   entropy->next_output_byte = cinfo->dest->next_output_byte;
   entropy->free_in_buffer = cinfo->dest->free_in_buffer;
@@ -731,18 +732,15 @@ encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
 
 /*
  * MCU encoding for DC successive approximation refinement scan.
- * Note: we assume such scans can be multi-component, although the spec
- * is not very clear on the point.
+ * Note: we assume such scans can be multi-component,
+ * although the spec is not very clear on the point.
  */
 
 METHODDEF(boolean)
 encode_mcu_DC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
 {
   huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
-  register int temp;
-  int blkn;
-  int Al = cinfo->Al;
-  JBLOCKROW block;
+  int Al, blkn;
 
   entropy->next_output_byte = cinfo->dest->next_output_byte;
   entropy->free_in_buffer = cinfo->dest->free_in_buffer;
@@ -752,13 +750,12 @@ encode_mcu_DC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
     if (entropy->restarts_to_go == 0)
       emit_restart_e(entropy, entropy->next_restart_num);
 
+  Al = cinfo->Al;
+
   /* Encode the MCU data blocks */
   for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
-    block = MCU_data[blkn];
-
     /* We simply emit the Al'th bit of the DC coefficient value. */
-    temp = (*block)[0];
-    emit_bits_e(entropy, (unsigned int) (temp >> Al), 1);
+    emit_bits_e(entropy, (unsigned int) (MCU_data[blkn][0][0] >> Al), 1);
   }
 
   cinfo->dest->next_output_byte = entropy->next_output_byte;
@@ -786,14 +783,14 @@ METHODDEF(boolean)
 encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
 {
   huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
+  const int * natural_order;
+  JBLOCKROW block;
   register int temp;
   register int r, k;
+  int Se, Al;
   int EOB;
   char *BR_buffer;
   unsigned int BR;
-  int Se, Al;
-  const int * natural_order;
-  JBLOCKROW block;
   int absvalues[DCTSIZE2];
 
   entropy->next_output_byte = cinfo->dest->next_output_byte;
@@ -918,7 +915,7 @@ encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val,
 {
   register int temp, temp2;
   register int nbits;
-  register int k, r, i;
+  register int r, k;
   int Se = state->cinfo->lim_Se;
   const int * natural_order = state->cinfo->natural_order;
 
@@ -960,7 +957,7 @@ encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val,
   r = 0;			/* r = run length of zeros */
 
   for (k = 1; k <= Se; k++) {
-    if ((temp = block[natural_order[k]]) == 0) {
+    if ((temp2 = block[natural_order[k]]) == 0) {
       r++;
     } else {
       /* if run length > 15, must emit special run-length-16 codes (0xF0) */
@@ -970,7 +967,7 @@ encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val,
 	r -= 16;
       }
 
-      temp2 = temp;
+      temp = temp2;
       if (temp < 0) {
 	temp = -temp;		/* temp is abs value of input */
 	/* This code assumes we are on a two's complement machine */
@@ -986,8 +983,8 @@ encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val,
 	ERREXIT(state->cinfo, JERR_BAD_DCT_COEF);
 
       /* Emit Huffman symbol for run length / number of bits */
-      i = (r << 4) + nbits;
-      if (! emit_bits_s(state, actbl->ehufco[i], actbl->ehufsi[i]))
+      temp = (r << 4) + nbits;
+      if (! emit_bits_s(state, actbl->ehufco[temp], actbl->ehufsi[temp]))
 	return FALSE;
 
       /* Emit that number of bits of the value, if positive, */
@@ -1124,16 +1121,16 @@ htest_one_block (j_compress_ptr cinfo, JCOEFPTR block, int last_dc_val,
 {
   register int temp;
   register int nbits;
-  register int k, r;
+  register int r, k;
   int Se = cinfo->lim_Se;
   const int * natural_order = cinfo->natural_order;
-  
+
   /* Encode the DC coefficient difference per section F.1.2.1 */
-  
+
   temp = block[0] - last_dc_val;
   if (temp < 0)
     temp = -temp;
-  
+
   /* Find the number of bits needed for the magnitude of the coefficient */
   nbits = 0;
   while (temp) {
@@ -1148,11 +1145,11 @@ htest_one_block (j_compress_ptr cinfo, JCOEFPTR block, int last_dc_val,
 
   /* Count the Huffman symbol for the number of bits */
   dc_counts[nbits]++;
-  
+
   /* Encode the AC coefficients per section F.1.2.2 */
-  
+
   r = 0;			/* r = run length of zeros */
-  
+
   for (k = 1; k <= Se; k++) {
     if ((temp = block[natural_order[k]]) == 0) {
       r++;
@@ -1162,11 +1159,11 @@ htest_one_block (j_compress_ptr cinfo, JCOEFPTR block, int last_dc_val,
 	ac_counts[0xF0]++;
 	r -= 16;
       }
-      
+
       /* Find the number of bits needed for the magnitude of the coefficient */
       if (temp < 0)
 	temp = -temp;
-      
+
       /* Find the number of bits needed for the magnitude of the coefficient */
       nbits = 1;		/* there must be at least one 1 bit */
       while ((temp >>= 1))
@@ -1174,10 +1171,10 @@ htest_one_block (j_compress_ptr cinfo, JCOEFPTR block, int last_dc_val,
       /* Check for out-of-range coefficient values */
       if (nbits > MAX_COEF_BITS)
 	ERREXIT(cinfo, JERR_BAD_DCT_COEF);
-      
+
       /* Count Huffman symbol for run length / number of bits */
       ac_counts[(r << 4) + nbits]++;
-      
+
       r = 0;
     }
   }
@@ -1562,7 +1559,7 @@ jinit_huff_encoder (j_compress_ptr cinfo)
   entropy = (huff_entropy_ptr)
     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 				SIZEOF(huff_entropy_encoder));
-  cinfo->entropy = (struct jpeg_entropy_encoder *) entropy;
+  cinfo->entropy = &entropy->pub;
   entropy->pub.start_pass = start_pass_huff;
 
   /* Mark tables unallocated */
diff --git a/Source/LibJPEG/jcinit.c b/Source/LibJPEG/jcinit.c
index 0ba310f..1e13e34 100644
--- a/Source/LibJPEG/jcinit.c
+++ b/Source/LibJPEG/jcinit.c
@@ -2,6 +2,7 @@
  * jcinit.c
  *
  * Copyright (C) 1991-1997, Thomas G. Lane.
+ * Modified 2003-2013 by Guido Vollbeding.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
@@ -29,6 +30,24 @@
 GLOBAL(void)
 jinit_compress_master (j_compress_ptr cinfo)
 {
+  long samplesperrow;
+  JDIMENSION jd_samplesperrow;
+
+  /* For now, precision must match compiled-in value... */
+  if (cinfo->data_precision != BITS_IN_JSAMPLE)
+    ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
+
+  /* Sanity check on image dimensions */
+  if (cinfo->image_height <= 0 || cinfo->image_width <= 0 ||
+      cinfo->input_components <= 0)
+    ERREXIT(cinfo, JERR_EMPTY_IMAGE);
+
+  /* Width of an input scanline must be representable as JDIMENSION. */
+  samplesperrow = (long) cinfo->image_width * (long) cinfo->input_components;
+  jd_samplesperrow = (JDIMENSION) samplesperrow;
+  if ((long) jd_samplesperrow != samplesperrow)
+    ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
+
   /* Initialize master control (includes parameter checking/processing) */
   jinit_c_master_control(cinfo, FALSE /* full compression */);
 
diff --git a/Source/LibJPEG/jcmainct.c b/Source/LibJPEG/jcmainct.c
index 7de75d1..39b9790 100644
--- a/Source/LibJPEG/jcmainct.c
+++ b/Source/LibJPEG/jcmainct.c
@@ -2,6 +2,7 @@
  * jcmainct.c
  *
  * Copyright (C) 1994-1996, Thomas G. Lane.
+ * Modified 2003-2012 by Guido Vollbeding.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
@@ -68,32 +69,32 @@ METHODDEF(void) process_data_buffer_main
 METHODDEF(void)
 start_pass_main (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
 {
-  my_main_ptr main = (my_main_ptr) cinfo->main;
+  my_main_ptr mainp = (my_main_ptr) cinfo->main;
 
   /* Do nothing in raw-data mode. */
   if (cinfo->raw_data_in)
     return;
 
-  main->cur_iMCU_row = 0;	/* initialize counters */
-  main->rowgroup_ctr = 0;
-  main->suspended = FALSE;
-  main->pass_mode = pass_mode;	/* save mode for use by process_data */
+  mainp->cur_iMCU_row = 0;	/* initialize counters */
+  mainp->rowgroup_ctr = 0;
+  mainp->suspended = FALSE;
+  mainp->pass_mode = pass_mode;	/* save mode for use by process_data */
 
   switch (pass_mode) {
   case JBUF_PASS_THRU:
 #ifdef FULL_MAIN_BUFFER_SUPPORTED
-    if (main->whole_image[0] != NULL)
+    if (mainp->whole_image[0] != NULL)
       ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
 #endif
-    main->pub.process_data = process_data_simple_main;
+    mainp->pub.process_data = process_data_simple_main;
     break;
 #ifdef FULL_MAIN_BUFFER_SUPPORTED
   case JBUF_SAVE_SOURCE:
   case JBUF_CRANK_DEST:
   case JBUF_SAVE_AND_PASS:
-    if (main->whole_image[0] == NULL)
+    if (mainp->whole_image[0] == NULL)
       ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
-    main->pub.process_data = process_data_buffer_main;
+    mainp->pub.process_data = process_data_buffer_main;
     break;
 #endif
   default:
@@ -114,46 +115,46 @@ process_data_simple_main (j_compress_ptr cinfo,
 			  JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
 			  JDIMENSION in_rows_avail)
 {
-  my_main_ptr main = (my_main_ptr) cinfo->main;
+  my_main_ptr mainp = (my_main_ptr) cinfo->main;
 
-  while (main->cur_iMCU_row < cinfo->total_iMCU_rows) {
+  while (mainp->cur_iMCU_row < cinfo->total_iMCU_rows) {
     /* Read input data if we haven't filled the main buffer yet */
-    if (main->rowgroup_ctr < (JDIMENSION) cinfo->min_DCT_v_scaled_size)
+    if (mainp->rowgroup_ctr < (JDIMENSION) cinfo->min_DCT_v_scaled_size)
       (*cinfo->prep->pre_process_data) (cinfo,
 					input_buf, in_row_ctr, in_rows_avail,
-					main->buffer, &main->rowgroup_ctr,
+					mainp->buffer, &mainp->rowgroup_ctr,
 					(JDIMENSION) cinfo->min_DCT_v_scaled_size);
 
     /* If we don't have a full iMCU row buffered, return to application for
      * more data.  Note that preprocessor will always pad to fill the iMCU row
      * at the bottom of the image.
      */
-    if (main->rowgroup_ctr != (JDIMENSION) cinfo->min_DCT_v_scaled_size)
+    if (mainp->rowgroup_ctr != (JDIMENSION) cinfo->min_DCT_v_scaled_size)
       return;
 
     /* Send the completed row to the compressor */
-    if (! (*cinfo->coef->compress_data) (cinfo, main->buffer)) {
+    if (! (*cinfo->coef->compress_data) (cinfo, mainp->buffer)) {
       /* If compressor did not consume the whole row, then we must need to
        * suspend processing and return to the application.  In this situation
        * we pretend we didn't yet consume the last input row; otherwise, if
        * it happened to be the last row of the image, the application would
        * think we were done.
        */
-      if (! main->suspended) {
+      if (! mainp->suspended) {
 	(*in_row_ctr)--;
-	main->suspended = TRUE;
+	mainp->suspended = TRUE;
       }
       return;
     }
     /* We did finish the row.  Undo our little suspension hack if a previous
      * call suspended; then mark the main buffer empty.
      */
-    if (main->suspended) {
+    if (mainp->suspended) {
       (*in_row_ctr)++;
-      main->suspended = FALSE;
+      mainp->suspended = FALSE;
     }
-    main->rowgroup_ctr = 0;
-    main->cur_iMCU_row++;
+    mainp->rowgroup_ctr = 0;
+    mainp->cur_iMCU_row++;
   }
 }
 
@@ -170,25 +171,27 @@ process_data_buffer_main (j_compress_ptr cinfo,
 			  JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
 			  JDIMENSION in_rows_avail)
 {
-  my_main_ptr main = (my_main_ptr) cinfo->main;
+  my_main_ptr mainp = (my_main_ptr) cinfo->main;
   int ci;
   jpeg_component_info *compptr;
-  boolean writing = (main->pass_mode != JBUF_CRANK_DEST);
+  boolean writing = (mainp->pass_mode != JBUF_CRANK_DEST);
 
-  while (main->cur_iMCU_row < cinfo->total_iMCU_rows) {
+  while (mainp->cur_iMCU_row < cinfo->total_iMCU_rows) {
     /* Realign the virtual buffers if at the start of an iMCU row. */
-    if (main->rowgroup_ctr == 0) {
+    if (mainp->rowgroup_ctr == 0) {
       for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 	   ci++, compptr++) {
-	main->buffer[ci] = (*cinfo->mem->access_virt_sarray)
-	  ((j_common_ptr) cinfo, main->whole_image[ci],
-	   main->cur_iMCU_row * (compptr->v_samp_factor * DCTSIZE),
-	   (JDIMENSION) (compptr->v_samp_factor * DCTSIZE), writing);
+	mainp->buffer[ci] = (*cinfo->mem->access_virt_sarray)
+	  ((j_common_ptr) cinfo, mainp->whole_image[ci], mainp->cur_iMCU_row *
+	   ((JDIMENSION) (compptr->v_samp_factor * cinfo->min_DCT_v_scaled_size)),
+	   (JDIMENSION) (compptr->v_samp_factor * cinfo->min_DCT_v_scaled_size),
+	   writing);
       }
       /* In a read pass, pretend we just read some source data. */
       if (! writing) {
-	*in_row_ctr += cinfo->max_v_samp_factor * DCTSIZE;
-	main->rowgroup_ctr = DCTSIZE;
+	*in_row_ctr += (JDIMENSION)
+	  (cinfo->max_v_samp_factor * cinfo->min_DCT_v_scaled_size);
+	mainp->rowgroup_ctr = (JDIMENSION) cinfo->min_DCT_v_scaled_size;
       }
     }
 
@@ -197,40 +200,40 @@ process_data_buffer_main (j_compress_ptr cinfo,
     if (writing) {
       (*cinfo->prep->pre_process_data) (cinfo,
 					input_buf, in_row_ctr, in_rows_avail,
-					main->buffer, &main->rowgroup_ctr,
-					(JDIMENSION) DCTSIZE);
+					mainp->buffer, &mainp->rowgroup_ctr,
+					(JDIMENSION) cinfo->min_DCT_v_scaled_size);
       /* Return to application if we need more data to fill the iMCU row. */
-      if (main->rowgroup_ctr < DCTSIZE)
+      if (mainp->rowgroup_ctr < (JDIMENSION) cinfo->min_DCT_v_scaled_size)
 	return;
     }
 
     /* Emit data, unless this is a sink-only pass. */
-    if (main->pass_mode != JBUF_SAVE_SOURCE) {
-      if (! (*cinfo->coef->compress_data) (cinfo, main->buffer)) {
+    if (mainp->pass_mode != JBUF_SAVE_SOURCE) {
+      if (! (*cinfo->coef->compress_data) (cinfo, mainp->buffer)) {
 	/* If compressor did not consume the whole row, then we must need to
 	 * suspend processing and return to the application.  In this situation
 	 * we pretend we didn't yet consume the last input row; otherwise, if
 	 * it happened to be the last row of the image, the application would
 	 * think we were done.
 	 */
-	if (! main->suspended) {
+	if (! mainp->suspended) {
 	  (*in_row_ctr)--;
-	  main->suspended = TRUE;
+	  mainp->suspended = TRUE;
 	}
 	return;
       }
       /* We did finish the row.  Undo our little suspension hack if a previous
        * call suspended; then mark the main buffer empty.
        */
-      if (main->suspended) {
+      if (mainp->suspended) {
 	(*in_row_ctr)++;
-	main->suspended = FALSE;
+	mainp->suspended = FALSE;
       }
     }
 
     /* If get here, we are done with this iMCU row.  Mark buffer empty. */
-    main->rowgroup_ctr = 0;
-    main->cur_iMCU_row++;
+    mainp->rowgroup_ctr = 0;
+    mainp->cur_iMCU_row++;
   }
 }
 
@@ -244,15 +247,15 @@ process_data_buffer_main (j_compress_ptr cinfo,
 GLOBAL(void)
 jinit_c_main_controller (j_compress_ptr cinfo, boolean need_full_buffer)
 {
-  my_main_ptr main;
+  my_main_ptr mainp;
   int ci;
   jpeg_component_info *compptr;
 
-  main = (my_main_ptr)
+  mainp = (my_main_ptr)
     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 				SIZEOF(my_main_controller));
-  cinfo->main = (struct jpeg_c_main_controller *) main;
-  main->pub.start_pass = start_pass_main;
+  cinfo->main = &mainp->pub;
+  mainp->pub.start_pass = start_pass_main;
 
   /* We don't need to create a buffer in raw-data mode. */
   if (cinfo->raw_data_in)
@@ -267,11 +270,12 @@ jinit_c_main_controller (j_compress_ptr cinfo, boolean need_full_buffer)
     /* Note we pad the bottom to a multiple of the iMCU height */
     for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 	 ci++, compptr++) {
-      main->whole_image[ci] = (*cinfo->mem->request_virt_sarray)
+      mainp->whole_image[ci] = (*cinfo->mem->request_virt_sarray)
 	((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
-	 compptr->width_in_blocks * compptr->DCT_h_scaled_size,
-	 (JDIMENSION) jround_up((long) compptr->height_in_blocks,
-				(long) compptr->v_samp_factor) * DCTSIZE,
+	 compptr->width_in_blocks * ((JDIMENSION) compptr->DCT_h_scaled_size),
+	 ((JDIMENSION) jround_up((long) compptr->height_in_blocks,
+				 (long) compptr->v_samp_factor)) *
+	 ((JDIMENSION) cinfo->min_DCT_v_scaled_size),
 	 (JDIMENSION) (compptr->v_samp_factor * compptr->DCT_v_scaled_size));
     }
 #else
@@ -279,14 +283,14 @@ jinit_c_main_controller (j_compress_ptr cinfo, boolean need_full_buffer)
 #endif
   } else {
 #ifdef FULL_MAIN_BUFFER_SUPPORTED
-    main->whole_image[0] = NULL; /* flag for no virtual arrays */
+    mainp->whole_image[0] = NULL; /* flag for no virtual arrays */
 #endif
     /* Allocate a strip buffer for each component */
     for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 	 ci++, compptr++) {
-      main->buffer[ci] = (*cinfo->mem->alloc_sarray)
+      mainp->buffer[ci] = (*cinfo->mem->alloc_sarray)
 	((j_common_ptr) cinfo, JPOOL_IMAGE,
-	 compptr->width_in_blocks * compptr->DCT_h_scaled_size,
+	 compptr->width_in_blocks * ((JDIMENSION) compptr->DCT_h_scaled_size),
 	 (JDIMENSION) (compptr->v_samp_factor * compptr->DCT_v_scaled_size));
     }
   }
diff --git a/Source/LibJPEG/jcmarker.c b/Source/LibJPEG/jcmarker.c
index 606c19a..ca2bb39 100644
--- a/Source/LibJPEG/jcmarker.c
+++ b/Source/LibJPEG/jcmarker.c
@@ -2,7 +2,7 @@
  * jcmarker.c
  *
  * Copyright (C) 1991-1998, Thomas G. Lane.
- * Modified 2003-2010 by Guido Vollbeding.
+ * Modified 2003-2013 by Guido Vollbeding.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
@@ -19,24 +19,24 @@ typedef enum {			/* JPEG marker codes */
   M_SOF1  = 0xc1,
   M_SOF2  = 0xc2,
   M_SOF3  = 0xc3,
-  
+
   M_SOF5  = 0xc5,
   M_SOF6  = 0xc6,
   M_SOF7  = 0xc7,
-  
+
   M_JPG   = 0xc8,
   M_SOF9  = 0xc9,
   M_SOF10 = 0xca,
   M_SOF11 = 0xcb,
-  
+
   M_SOF13 = 0xcd,
   M_SOF14 = 0xce,
   M_SOF15 = 0xcf,
-  
+
   M_DHT   = 0xc4,
-  
+
   M_DAC   = 0xcc,
-  
+
   M_RST0  = 0xd0,
   M_RST1  = 0xd1,
   M_RST2  = 0xd2,
@@ -45,7 +45,7 @@ typedef enum {			/* JPEG marker codes */
   M_RST5  = 0xd5,
   M_RST6  = 0xd6,
   M_RST7  = 0xd7,
-  
+
   M_SOI   = 0xd8,
   M_EOI   = 0xd9,
   M_SOS   = 0xda,
@@ -54,7 +54,7 @@ typedef enum {			/* JPEG marker codes */
   M_DRI   = 0xdd,
   M_DHP   = 0xde,
   M_EXP   = 0xdf,
-  
+
   M_APP0  = 0xe0,
   M_APP1  = 0xe1,
   M_APP2  = 0xe2,
@@ -71,13 +71,14 @@ typedef enum {			/* JPEG marker codes */
   M_APP13 = 0xed,
   M_APP14 = 0xee,
   M_APP15 = 0xef,
-  
+
   M_JPG0  = 0xf0,
+  M_JPG8  = 0xf8,
   M_JPG13 = 0xfd,
   M_COM   = 0xfe,
-  
+
   M_TEM   = 0x01,
-  
+
   M_ERROR = 0x100
 } JPEG_MARKER;
 
@@ -282,6 +283,37 @@ emit_dri (j_compress_ptr cinfo)
 
 
 LOCAL(void)
+emit_lse_ict (j_compress_ptr cinfo)
+/* Emit an LSE inverse color transform specification marker */
+{
+  /* Support only 1 transform */
+  if (cinfo->color_transform != JCT_SUBTRACT_GREEN ||
+      cinfo->num_components < 3)
+    ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+
+  emit_marker(cinfo, M_JPG8);
+  
+  emit_2bytes(cinfo, 24);	/* fixed length */
+
+  emit_byte(cinfo, 0x0D);	/* ID inverse transform specification */
+  emit_2bytes(cinfo, MAXJSAMPLE);	/* MAXTRANS */
+  emit_byte(cinfo, 3);		/* Nt=3 */
+  emit_byte(cinfo, cinfo->comp_info[1].component_id);
+  emit_byte(cinfo, cinfo->comp_info[0].component_id);
+  emit_byte(cinfo, cinfo->comp_info[2].component_id);
+  emit_byte(cinfo, 0x80);	/* F1: CENTER1=1, NORM1=0 */
+  emit_2bytes(cinfo, 0);	/* A(1,1)=0 */
+  emit_2bytes(cinfo, 0);	/* A(1,2)=0 */
+  emit_byte(cinfo, 0);		/* F2: CENTER2=0, NORM2=0 */
+  emit_2bytes(cinfo, 1);	/* A(2,1)=1 */
+  emit_2bytes(cinfo, 0);	/* A(2,2)=0 */
+  emit_byte(cinfo, 0);		/* F3: CENTER3=0, NORM3=0 */
+  emit_2bytes(cinfo, 1);	/* A(3,1)=1 */
+  emit_2bytes(cinfo, 0);	/* A(3,2)=0 */
+}
+
+
+LOCAL(void)
 emit_sof (j_compress_ptr cinfo, JPEG_MARKER code)
 /* Emit a SOF marker */
 {
@@ -476,8 +508,8 @@ write_marker_byte (j_compress_ptr cinfo, int val)
  * Write datastream header.
  * This consists of an SOI and optional APPn markers.
  * We recommend use of the JFIF marker, but not the Adobe marker,
- * when using YCbCr or grayscale data.  The JFIF marker should NOT
- * be used for any other JPEG colorspace.  The Adobe marker is helpful
+ * when using YCbCr or grayscale data.  The JFIF marker is also used
+ * for other standard JPEG colorspaces.  The Adobe marker is helpful
  * to distinguish RGB, CMYK, and YCCK colorspaces.
  * Note that an application can write additional header markers after
  * jpeg_start_compress returns.
@@ -502,7 +534,8 @@ write_file_header (j_compress_ptr cinfo)
 
 /*
  * Write frame header.
- * This consists of DQT and SOFn markers, and a conditional pseudo SOS marker.
+ * This consists of DQT and SOFn markers,
+ * a conditional LSE marker and a conditional pseudo SOS marker.
  * Note that we do not emit the SOF until we have emitted the DQT(s).
  * This avoids compatibility problems with incorrect implementations that
  * try to error-check the quant table numbers as soon as they see the SOF.
@@ -560,6 +593,10 @@ write_frame_header (j_compress_ptr cinfo)
       emit_sof(cinfo, M_SOF1);	/* SOF code for non-baseline Huffman file */
   }
 
+  /* Check to emit LSE inverse color transform specification marker */
+  if (cinfo->color_transform)
+    emit_lse_ict(cinfo);
+
   /* Check to emit pseudo SOS marker */
   if (cinfo->progressive_mode && cinfo->block_size != DCTSIZE)
     emit_pseudo_sos(cinfo);
@@ -668,7 +705,7 @@ jinit_marker_writer (j_compress_ptr cinfo)
   marker = (my_marker_ptr)
     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 				SIZEOF(my_marker_writer));
-  cinfo->marker = (struct jpeg_marker_writer *) marker;
+  cinfo->marker = &marker->pub;
   /* Initialize method pointers */
   marker->pub.write_file_header = write_file_header;
   marker->pub.write_frame_header = write_frame_header;
diff --git a/Source/LibJPEG/jcmaster.c b/Source/LibJPEG/jcmaster.c
index caf80a5..2a8ae63 100644
--- a/Source/LibJPEG/jcmaster.c
+++ b/Source/LibJPEG/jcmaster.c
@@ -2,7 +2,7 @@
  * jcmaster.c
  *
  * Copyright (C) 1991-1997, Thomas G. Lane.
- * Modified 2003-2011 by Guido Vollbeding.
+ * Modified 2003-2013 by Guido Vollbeding.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
@@ -222,8 +222,6 @@ initial_setup (j_compress_ptr cinfo, boolean transcode_only)
 {
   int ci, ssize;
   jpeg_component_info *compptr;
-  long samplesperrow;
-  JDIMENSION jd_samplesperrow;
 
   if (transcode_only)
     jpeg_calc_trans_dimensions(cinfo);
@@ -251,7 +249,7 @@ initial_setup (j_compress_ptr cinfo, boolean transcode_only)
 
   /* Sanity check on image dimensions */
   if (cinfo->jpeg_height <= 0 || cinfo->jpeg_width <= 0 ||
-      cinfo->num_components <= 0 || cinfo->input_components <= 0)
+      cinfo->num_components <= 0)
     ERREXIT(cinfo, JERR_EMPTY_IMAGE);
 
   /* Make sure image isn't bigger than I can handle */
@@ -259,14 +257,8 @@ initial_setup (j_compress_ptr cinfo, boolean transcode_only)
       (long) cinfo->jpeg_width > (long) JPEG_MAX_DIMENSION)
     ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION);
 
-  /* Width of an input scanline must be representable as JDIMENSION. */
-  samplesperrow = (long) cinfo->image_width * (long) cinfo->input_components;
-  jd_samplesperrow = (JDIMENSION) samplesperrow;
-  if ((long) jd_samplesperrow != samplesperrow)
-    ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
-
-  /* For now, precision must match compiled-in value... */
-  if (cinfo->data_precision != BITS_IN_JSAMPLE)
+  /* Only 8 to 12 bits data precision are supported for DCT based JPEG */
+  if (cinfo->data_precision < 8 || cinfo->data_precision > 12)
     ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
 
   /* Check that number of components won't exceed internal array sizes */
@@ -339,8 +331,10 @@ initial_setup (j_compress_ptr cinfo, boolean transcode_only)
       jdiv_round_up((long) cinfo->jpeg_height *
 		    (long) (compptr->v_samp_factor * compptr->DCT_v_scaled_size),
 		    (long) (cinfo->max_v_samp_factor * cinfo->block_size));
-    /* Mark component needed (this flag isn't actually used for compression) */
-    compptr->component_needed = TRUE;
+    /* Don't need quantization scale after DCT,
+     * until color conversion says otherwise.
+     */
+    compptr->component_needed = FALSE;
   }
 
   /* Compute number of fully interleaved MCU rows (number of times that
@@ -811,7 +805,7 @@ jinit_c_master_control (j_compress_ptr cinfo, boolean transcode_only)
   master = (my_master_ptr)
       (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 				  SIZEOF(my_comp_master));
-  cinfo->master = (struct jpeg_comp_master *) master;
+  cinfo->master = &master->pub;
   master->pub.prepare_for_pass = prepare_for_pass;
   master->pub.pass_startup = pass_startup;
   master->pub.finish_pass = finish_pass_master;
@@ -833,10 +827,14 @@ jinit_c_master_control (j_compress_ptr cinfo, boolean transcode_only)
     cinfo->num_scans = 1;
   }
 
-  if ((cinfo->progressive_mode || cinfo->block_size < DCTSIZE) &&
-      !cinfo->arith_code)			/*  TEMPORARY HACK ??? */
-    /* assume default tables no good for progressive or downscale mode */
-    cinfo->optimize_coding = TRUE;
+  if (cinfo->optimize_coding)
+    cinfo->arith_code = FALSE; /* disable arithmetic coding */
+  else if (! cinfo->arith_code &&
+	   (cinfo->progressive_mode ||
+	    (cinfo->block_size > 1 && cinfo->block_size < DCTSIZE)))
+    /* TEMPORARY HACK ??? */
+    /* assume default tables no good for progressive or reduced AC mode */
+    cinfo->optimize_coding = TRUE; /* force Huffman optimization */
 
   /* Initialize my private state */
   if (transcode_only) {
diff --git a/Source/LibJPEG/jconfig.h b/Source/LibJPEG/jconfig.h
index 44e5c52..8bbd609 100644
--- a/Source/LibJPEG/jconfig.h
+++ b/Source/LibJPEG/jconfig.h
@@ -1,20 +1,95 @@
-/* jconfig.vc --- jconfig.h for Microsoft Visual C++ on Windows 95 or NT. */
-/* see jconfig.doc for explanations */
+/*
+ * jconfig.txt
+ *
+ * Copyright (C) 1991-1994, Thomas G. Lane.
+ * Modified 2009-2013 by Guido Vollbeding.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file documents the configuration options that are required to
+ * customize the JPEG software for a particular system.
+ *
+ * The actual configuration options for a particular installation are stored
+ * in jconfig.h.  On many machines, jconfig.h can be generated automatically
+ * or copied from one of the "canned" jconfig files that we supply.  But if
+ * you need to generate a jconfig.h file by hand, this file tells you how.
+ *
+ * DO NOT EDIT THIS FILE --- IT WON'T ACCOMPLISH ANYTHING.
+ * EDIT A COPY NAMED JCONFIG.H.
+ */
 
+
+/*
+ * These symbols indicate the properties of your machine or compiler.
+ * #define the symbol if yes, #undef it if no.
+ */
+
+/* Does your compiler support function prototypes?
+ * (If not, you also need to use ansi2knr, see install.txt)
+ */
 #define HAVE_PROTOTYPES
+
+/* Does your compiler support the declaration "unsigned char" ?
+ * How about "unsigned short" ?
+ */
 #define HAVE_UNSIGNED_CHAR
 #define HAVE_UNSIGNED_SHORT
+
+/* Define "void" as "char" if your compiler doesn't know about type void.
+ * NOTE: be sure to define void such that "void *" represents the most general
+ * pointer type, e.g., that returned by malloc().
+ */
 /* #define void char */
+
+/* Define "const" as empty if your compiler doesn't know the "const" keyword.
+ */
 /* #define const */
+
+/* Define this if an ordinary "char" type is unsigned.
+ * If you're not sure, leaving it undefined will work at some cost in speed.
+ * If you defined HAVE_UNSIGNED_CHAR then the speed difference is minimal.
+ */
 #undef CHAR_IS_UNSIGNED
+
+/* Define this if your system has an ANSI-conforming <stddef.h> file.
+ */
 #define HAVE_STDDEF_H
-#ifndef HAVE_STDLIB_H
+
+/* Define this if your system has an ANSI-conforming <stdlib.h> file.
+ */
 #define HAVE_STDLIB_H
-#endif
+
+/* Define this if your system does not have an ANSI/SysV <string.h>,
+ * but does have a BSD-style <strings.h>.
+ */
 #undef NEED_BSD_STRINGS
+
+/* Define this if your system does not provide typedef size_t in any of the
+ * ANSI-standard places (stddef.h, stdlib.h, or stdio.h), but places it in
+ * <sys/types.h> instead.
+ */
 #undef NEED_SYS_TYPES_H
-#undef NEED_FAR_POINTERS	/* we presume a 32-bit flat memory model */
+
+/* For 80x86 machines, you need to define NEED_FAR_POINTERS,
+ * unless you are using a large-data memory model or 80386 flat-memory mode.
+ * On less brain-damaged CPUs this symbol must not be defined.
+ * (Defining this symbol causes large data structures to be referenced through
+ * "far" pointers and to be allocated with a special version of malloc.)
+ */
+#undef NEED_FAR_POINTERS
+
+/* Define this if your linker needs global names to be unique in less
+ * than the first 15 characters.
+ */
 #undef NEED_SHORT_EXTERNAL_NAMES
+
+/* Although a real ANSI C compiler can deal perfectly well with pointers to
+ * unspecified structures (see "incomplete types" in the spec), a few pre-ANSI
+ * and pseudo-ANSI compilers get confused.  To keep one of these bozos happy,
+ * define INCOMPLETE_TYPES_BROKEN.  This is not recommended unless you
+ * actually get "missing structure definition" warnings or errors while
+ * compiling the JPEG code.
+ */
 #undef INCOMPLETE_TYPES_BROKEN
 
 /* Define "boolean" as unsigned char, not int, per Windows custom */
@@ -23,25 +98,64 @@ typedef unsigned char boolean;
 #endif
 #define HAVE_BOOLEAN		/* prevent jmorecfg.h from redefining it */
 
+/*
+ * The following options affect code selection within the JPEG library,
+ * but they don't need to be visible to applications using the library.
+ * To minimize application namespace pollution, the symbols won't be
+ * defined unless JPEG_INTERNALS has been defined.
+ */
 
 #ifdef JPEG_INTERNALS
 
+/* Define this if your compiler implements ">>" on signed values as a logical
+ * (unsigned) shift; leave it undefined if ">>" is a signed (arithmetic) shift,
+ * which is the normal and rational definition.
+ */
 #undef RIGHT_SHIFT_IS_UNSIGNED
 
+
 #endif /* JPEG_INTERNALS */
 
+
+/*
+ * The remaining options do not affect the JPEG library proper,
+ * but only the sample applications cjpeg/djpeg (see cjpeg.c, djpeg.c).
+ * Other applications can ignore these.
+ */
+
 #ifdef JPEG_CJPEG_DJPEG
 
+/* These defines indicate which image (non-JPEG) file formats are allowed. */
+
 #define BMP_SUPPORTED		/* BMP image file format */
 #define GIF_SUPPORTED		/* GIF image file format */
 #define PPM_SUPPORTED		/* PBMPLUS PPM/PGM image file format */
 #undef RLE_SUPPORTED		/* Utah RLE image file format */
 #define TARGA_SUPPORTED		/* Targa image file format */
 
-#define TWO_FILE_COMMANDLINE	/* optional */
-#define USE_SETMODE		/* Microsoft has setmode() */
+/* Define this if you want to name both input and output files on the command
+ * line, rather than using stdout and optionally stdin.  You MUST do this if
+ * your system can't cope with binary I/O to stdin/stdout.  See comments at
+ * head of cjpeg.c or djpeg.c.
+ */
+#undef TWO_FILE_COMMANDLINE
+
+/* Define this if your system needs explicit cleanup of temporary files.
+ * This is crucial under MS-DOS, where the temporary "files" may be areas
+ * of extended memory; on most other systems it's not as important.
+ */
 #undef NEED_SIGNAL_CATCHER
+
+/* By default, we open image files with fopen(...,"rb") or fopen(...,"wb").
+ * This is necessary on systems that distinguish text files from binary files,
+ * and is harmless on most systems that don't.  If you have one of the rare
+ * systems that complains about the "b" spec, define this symbol.
+ */
 #undef DONT_USE_B_MODE
-#undef PROGRESS_REPORT		/* optional */
+
+/* Define this if you want percent-done progress reports from cjpeg/djpeg.
+ */
+#undef PROGRESS_REPORT
+
 
 #endif /* JPEG_CJPEG_DJPEG */
diff --git a/Source/LibJPEG/jconfig.txt b/Source/LibJPEG/jconfig.txt
index 27086a3..6c92b82 100644
--- a/Source/LibJPEG/jconfig.txt
+++ b/Source/LibJPEG/jconfig.txt
@@ -2,6 +2,7 @@
  * jconfig.txt
  *
  * Copyright (C) 1991-1994, Thomas G. Lane.
+ * Modified 2009-2013 by Guido Vollbeding.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
@@ -91,12 +92,18 @@
  */
 #undef INCOMPLETE_TYPES_BROKEN
 
-/* Define "boolean" as unsigned char, not int, on Windows systems.
+/* Define "boolean" as unsigned char, not enum, on Windows systems.
  */
 #ifdef _WIN32
 #ifndef __RPCNDR_H__		/* don't conflict if rpcndr.h already read */
 typedef unsigned char boolean;
 #endif
+#ifndef FALSE			/* in case these macros already exist */
+#define FALSE	0		/* values of boolean */
+#endif
+#ifndef TRUE
+#define TRUE	1
+#endif
 #define HAVE_BOOLEAN		/* prevent jmorecfg.h from redefining it */
 #endif
 
diff --git a/Source/LibJPEG/jcparam.c b/Source/LibJPEG/jcparam.c
index c5e85dd..4b2bee2 100644
--- a/Source/LibJPEG/jcparam.c
+++ b/Source/LibJPEG/jcparam.c
@@ -2,7 +2,7 @@
  * jcparam.c
  *
  * Copyright (C) 1991-1998, Thomas G. Lane.
- * Modified 2003-2008 by Guido Vollbeding.
+ * Modified 2003-2013 by Guido Vollbeding.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
@@ -150,7 +150,7 @@ jpeg_set_quality (j_compress_ptr cinfo, int quality, boolean force_baseline)
 /* Set or change the 'quality' (quantization) setting, using default tables.
  * This is the standard quality-adjusting entry point for typical user
  * interfaces; only those who want detailed control over quantization tables
- * would use the preceding three routines directly.
+ * would use the preceding routines directly.
  */
 {
   /* Convert user 0-100 rating to percentage scaling */
@@ -323,18 +323,17 @@ jpeg_set_defaults (j_compress_ptr cinfo)
   /* Expect normal source image, not raw downsampled data */
   cinfo->raw_data_in = FALSE;
 
-  /* Use Huffman coding, not arithmetic coding, by default */
-  cinfo->arith_code = FALSE;
+  /* The standard Huffman tables are only valid for 8-bit data precision.
+   * If the precision is higher, use arithmetic coding.
+   * (Alternatively, using Huffman coding would be possible with forcing
+   * optimization on so that usable tables will be computed, or by
+   * supplying default tables that are valid for the desired precision.)
+   * Otherwise, use Huffman coding by default.
+   */
+  cinfo->arith_code = cinfo->data_precision > 8 ? TRUE : FALSE;
 
   /* By default, don't do extra passes to optimize entropy coding */
   cinfo->optimize_coding = FALSE;
-  /* The standard Huffman tables are only valid for 8-bit data precision.
-   * If the precision is higher, force optimization on so that usable
-   * tables will be computed.  This test can be removed if default tables
-   * are supplied that are valid for the desired precision.
-   */
-  if (cinfo->data_precision > 8)
-    cinfo->optimize_coding = TRUE;
 
   /* By default, use the simpler non-cosited sampling alignment */
   cinfo->CCIR601_sampling = FALSE;
@@ -360,6 +359,9 @@ jpeg_set_defaults (j_compress_ptr cinfo)
    * JFIF_minor_version to 2.  We could probably get away with just defaulting
    * to 1.02, but there may still be some decoders in use that will complain
    * about that; saying 1.01 should minimize compatibility problems.
+   *
+   * For wide gamut colorspaces (BG_RGB and BG_YCC), the major version will be
+   * overridden by jpeg_set_colorspace and set to 2.
    */
   cinfo->JFIF_major_version = 1; /* Default JFIF version = 1.01 */
   cinfo->JFIF_minor_version = 1;
@@ -367,6 +369,9 @@ jpeg_set_defaults (j_compress_ptr cinfo)
   cinfo->X_density = 1;		/* Pixel aspect ratio is square by default */
   cinfo->Y_density = 1;
 
+  /* No color transform */
+  cinfo->color_transform = JCT_NONE;
+
   /* Choose JPEG colorspace based on input space, set defaults accordingly */
 
   jpeg_default_colorspace(cinfo);
@@ -381,6 +386,9 @@ GLOBAL(void)
 jpeg_default_colorspace (j_compress_ptr cinfo)
 {
   switch (cinfo->in_color_space) {
+  case JCS_UNKNOWN:
+    jpeg_set_colorspace(cinfo, JCS_UNKNOWN);
+    break;
   case JCS_GRAYSCALE:
     jpeg_set_colorspace(cinfo, JCS_GRAYSCALE);
     break;
@@ -396,8 +404,12 @@ jpeg_default_colorspace (j_compress_ptr cinfo)
   case JCS_YCCK:
     jpeg_set_colorspace(cinfo, JCS_YCCK);
     break;
-  case JCS_UNKNOWN:
-    jpeg_set_colorspace(cinfo, JCS_UNKNOWN);
+  case JCS_BG_RGB:
+    /* No translation for now -- conversion to BG_YCC not yet supportet */
+    jpeg_set_colorspace(cinfo, JCS_BG_RGB);
+    break;
+  case JCS_BG_YCC:
+    jpeg_set_colorspace(cinfo, JCS_BG_YCC);
     break;
   default:
     ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
@@ -438,27 +450,40 @@ jpeg_set_colorspace (j_compress_ptr cinfo, J_COLOR_SPACE colorspace)
   cinfo->write_Adobe_marker = FALSE; /* write no Adobe marker by default */
 
   switch (colorspace) {
+  case JCS_UNKNOWN:
+    cinfo->num_components = cinfo->input_components;
+    if (cinfo->num_components < 1 || cinfo->num_components > MAX_COMPONENTS)
+      ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components,
+	       MAX_COMPONENTS);
+    for (ci = 0; ci < cinfo->num_components; ci++) {
+      SET_COMP(ci, ci, 1,1, 0, 0,0);
+    }
+    break;
   case JCS_GRAYSCALE:
     cinfo->write_JFIF_header = TRUE; /* Write a JFIF marker */
     cinfo->num_components = 1;
     /* JFIF specifies component ID 1 */
-    SET_COMP(0, 1, 1,1, 0, 0,0);
+    SET_COMP(0, 0x01, 1,1, 0, 0,0);
     break;
   case JCS_RGB:
     cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag RGB */
     cinfo->num_components = 3;
-    SET_COMP(0, 0x52 /* 'R' */, 1,1, 0, 0,0);
+    SET_COMP(0, 0x52 /* 'R' */, 1,1, 0,
+		cinfo->color_transform == JCT_SUBTRACT_GREEN ? 1 : 0,
+		cinfo->color_transform == JCT_SUBTRACT_GREEN ? 1 : 0);
     SET_COMP(1, 0x47 /* 'G' */, 1,1, 0, 0,0);
-    SET_COMP(2, 0x42 /* 'B' */, 1,1, 0, 0,0);
+    SET_COMP(2, 0x42 /* 'B' */, 1,1, 0,
+		cinfo->color_transform == JCT_SUBTRACT_GREEN ? 1 : 0,
+		cinfo->color_transform == JCT_SUBTRACT_GREEN ? 1 : 0);
     break;
   case JCS_YCbCr:
     cinfo->write_JFIF_header = TRUE; /* Write a JFIF marker */
     cinfo->num_components = 3;
     /* JFIF specifies component IDs 1,2,3 */
     /* We default to 2x2 subsamples of chrominance */
-    SET_COMP(0, 1, 2,2, 0, 0,0);
-    SET_COMP(1, 2, 1,1, 1, 1,1);
-    SET_COMP(2, 3, 1,1, 1, 1,1);
+    SET_COMP(0, 0x01, 2,2, 0, 0,0);
+    SET_COMP(1, 0x02, 1,1, 1, 1,1);
+    SET_COMP(2, 0x03, 1,1, 1, 1,1);
     break;
   case JCS_CMYK:
     cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag CMYK */
@@ -471,19 +496,33 @@ jpeg_set_colorspace (j_compress_ptr cinfo, J_COLOR_SPACE colorspace)
   case JCS_YCCK:
     cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag YCCK */
     cinfo->num_components = 4;
-    SET_COMP(0, 1, 2,2, 0, 0,0);
-    SET_COMP(1, 2, 1,1, 1, 1,1);
-    SET_COMP(2, 3, 1,1, 1, 1,1);
-    SET_COMP(3, 4, 2,2, 0, 0,0);
+    SET_COMP(0, 0x01, 2,2, 0, 0,0);
+    SET_COMP(1, 0x02, 1,1, 1, 1,1);
+    SET_COMP(2, 0x03, 1,1, 1, 1,1);
+    SET_COMP(3, 0x04, 2,2, 0, 0,0);
     break;
-  case JCS_UNKNOWN:
-    cinfo->num_components = cinfo->input_components;
-    if (cinfo->num_components < 1 || cinfo->num_components > MAX_COMPONENTS)
-      ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components,
-	       MAX_COMPONENTS);
-    for (ci = 0; ci < cinfo->num_components; ci++) {
-      SET_COMP(ci, ci, 1,1, 0, 0,0);
-    }
+  case JCS_BG_RGB:
+    cinfo->write_JFIF_header = TRUE; /* Write a JFIF marker */
+    cinfo->JFIF_major_version = 2;   /* Set JFIF major version = 2 */
+    cinfo->num_components = 3;
+    /* Add offset 0x20 to the normal R/G/B component IDs */
+    SET_COMP(0, 0x72 /* 'r' */, 1,1, 0,
+		cinfo->color_transform == JCT_SUBTRACT_GREEN ? 1 : 0,
+		cinfo->color_transform == JCT_SUBTRACT_GREEN ? 1 : 0);
+    SET_COMP(1, 0x67 /* 'g' */, 1,1, 0, 0,0);
+    SET_COMP(2, 0x62 /* 'b' */, 1,1, 0,
+		cinfo->color_transform == JCT_SUBTRACT_GREEN ? 1 : 0,
+		cinfo->color_transform == JCT_SUBTRACT_GREEN ? 1 : 0);
+    break;
+  case JCS_BG_YCC:
+    cinfo->write_JFIF_header = TRUE; /* Write a JFIF marker */
+    cinfo->JFIF_major_version = 2;   /* Set JFIF major version = 2 */
+    cinfo->num_components = 3;
+    /* Add offset 0x20 to the normal Cb/Cr component IDs */
+    /* We default to 2x2 subsamples of chrominance */
+    SET_COMP(0, 0x01, 2,2, 0, 0,0);
+    SET_COMP(1, 0x22, 1,1, 1, 1,1);
+    SET_COMP(2, 0x23, 1,1, 1, 1,1);
     break;
   default:
     ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
@@ -567,8 +606,10 @@ jpeg_simple_progression (j_compress_ptr cinfo)
     ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
 
   /* Figure space needed for script.  Calculation must match code below! */
-  if (ncomps == 3 && cinfo->jpeg_color_space == JCS_YCbCr) {
-    /* Custom script for YCbCr color images. */
+  if (ncomps == 3 &&
+      (cinfo->jpeg_color_space == JCS_YCbCr ||
+       cinfo->jpeg_color_space == JCS_BG_YCC)) {
+    /* Custom script for YCC color images. */
     nscans = 10;
   } else {
     /* All-purpose script for other color spaces. */
@@ -583,7 +624,7 @@ jpeg_simple_progression (j_compress_ptr cinfo)
    * multiple compressions without changing the settings.  To avoid a memory
    * leak if jpeg_simple_progression is called repeatedly for the same JPEG
    * object, we try to re-use previously allocated space, and we allocate
-   * enough space to handle YCbCr even if initially asked for grayscale.
+   * enough space to handle YCC even if initially asked for grayscale.
    */
   if (cinfo->script_space == NULL || cinfo->script_space_size < nscans) {
     cinfo->script_space_size = MAX(nscans, 10);
@@ -595,8 +636,10 @@ jpeg_simple_progression (j_compress_ptr cinfo)
   cinfo->scan_info = scanptr;
   cinfo->num_scans = nscans;
 
-  if (ncomps == 3 && cinfo->jpeg_color_space == JCS_YCbCr) {
-    /* Custom script for YCbCr color images. */
+  if (ncomps == 3 &&
+      (cinfo->jpeg_color_space == JCS_YCbCr ||
+       cinfo->jpeg_color_space == JCS_BG_YCC)) {
+    /* Custom script for YCC color images. */
     /* Initial DC scan */
     scanptr = fill_dc_scans(scanptr, ncomps, 0, 1);
     /* Initial AC scan: get some luma data out in a hurry */
diff --git a/Source/LibJPEG/jctrans.c b/Source/LibJPEG/jctrans.c
index f7d7b81..7cd077e 100644
--- a/Source/LibJPEG/jctrans.c
+++ b/Source/LibJPEG/jctrans.c
@@ -2,7 +2,7 @@
  * jctrans.c
  *
  * Copyright (C) 1995-1998, Thomas G. Lane.
- * Modified 2000-2011 by Guido Vollbeding.
+ * Modified 2000-2013 by Guido Vollbeding.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
@@ -85,7 +85,10 @@ jpeg_copy_critical_parameters (j_decompress_ptr srcinfo,
   jpeg_set_defaults(dstinfo);
   /* jpeg_set_defaults may choose wrong colorspace, eg YCbCr if input is RGB.
    * Fix it to get the right header markers for the image colorspace.
+   * Note: Entropy table assignment in jpeg_set_colorspace depends
+   * on color_transform.
    */
+  dstinfo->color_transform = srcinfo->color_transform;
   jpeg_set_colorspace(dstinfo, srcinfo->jpeg_color_space);
   dstinfo->data_precision = srcinfo->data_precision;
   dstinfo->CCIR601_sampling = srcinfo->CCIR601_sampling;
@@ -130,7 +133,7 @@ jpeg_copy_critical_parameters (j_decompress_ptr srcinfo,
 	  ERREXIT1(dstinfo, JERR_MISMATCHED_QUANT_TABLE, tblno);
       }
     }
-    /* Note: we do not copy the source's Huffman table assignments;
+    /* Note: we do not copy the source's entropy table assignments;
      * instead we rely on jpeg_set_colorspace to have made a suitable choice.
      */
   }
@@ -140,10 +143,10 @@ jpeg_copy_critical_parameters (j_decompress_ptr srcinfo,
    * if the application chooses to copy JFIF 1.02 extension markers from
    * the source file, we need to copy the version to make sure we don't
    * emit a file that has 1.02 extensions but a claimed version of 1.01.
-   * We will *not*, however, copy version info from mislabeled "2.01" files.
    */
   if (srcinfo->saw_JFIF_marker) {
-    if (srcinfo->JFIF_major_version == 1) {
+    if (srcinfo->JFIF_major_version == 1 ||
+	srcinfo->JFIF_major_version == 2) {
       dstinfo->JFIF_major_version = srcinfo->JFIF_major_version;
       dstinfo->JFIF_minor_version = srcinfo->JFIF_minor_version;
     }
@@ -364,7 +367,7 @@ transencode_coef_controller (j_compress_ptr cinfo,
   coef = (my_coef_ptr)
     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 				SIZEOF(my_coef_controller));
-  cinfo->coef = (struct jpeg_c_coef_controller *) coef;
+  cinfo->coef = &coef->pub;
   coef->pub.start_pass = start_pass_coef;
   coef->pub.compress_data = compress_output;
 
diff --git a/Source/LibJPEG/jdapimin.c b/Source/LibJPEG/jdapimin.c
index 7f1ce4c..a6e0dd9 100644
--- a/Source/LibJPEG/jdapimin.c
+++ b/Source/LibJPEG/jdapimin.c
@@ -2,7 +2,7 @@
  * jdapimin.c
  *
  * Copyright (C) 1994-1998, Thomas G. Lane.
- * Modified 2009 by Guido Vollbeding.
+ * Modified 2009-2013 by Guido Vollbeding.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
@@ -114,8 +114,9 @@ jpeg_abort_decompress (j_decompress_ptr cinfo)
 LOCAL(void)
 default_decompress_parms (j_decompress_ptr cinfo)
 {
+  int cid0, cid1, cid2;
+
   /* Guess the input colorspace, and set output colorspace accordingly. */
-  /* (Wish JPEG committee had provided a real way to specify this...) */
   /* Note application may override our guesses. */
   switch (cinfo->num_components) {
   case 1:
@@ -124,9 +125,22 @@ default_decompress_parms (j_decompress_ptr cinfo)
     break;
     
   case 3:
-    if (cinfo->saw_JFIF_marker) {
-      cinfo->jpeg_color_space = JCS_YCbCr; /* JFIF implies YCbCr */
-    } else if (cinfo->saw_Adobe_marker) {
+    cid0 = cinfo->comp_info[0].component_id;
+    cid1 = cinfo->comp_info[1].component_id;
+    cid2 = cinfo->comp_info[2].component_id;
+
+    /* First try to guess from the component IDs */
+    if      (cid0 == 0x01 && cid1 == 0x02 && cid2 == 0x03)
+      cinfo->jpeg_color_space = JCS_YCbCr;
+    else if (cid0 == 0x01 && cid1 == 0x22 && cid2 == 0x23)
+      cinfo->jpeg_color_space = JCS_BG_YCC;
+    else if (cid0 == 0x52 && cid1 == 0x47 && cid2 == 0x42)
+      cinfo->jpeg_color_space = JCS_RGB;	/* ASCII 'R', 'G', 'B' */
+    else if (cid0 == 0x72 && cid1 == 0x67 && cid2 == 0x62)
+      cinfo->jpeg_color_space = JCS_BG_RGB;	/* ASCII 'r', 'g', 'b' */
+    else if (cinfo->saw_JFIF_marker)
+      cinfo->jpeg_color_space = JCS_YCbCr;	/* assume it's YCbCr */
+    else if (cinfo->saw_Adobe_marker) {
       switch (cinfo->Adobe_transform) {
       case 0:
 	cinfo->jpeg_color_space = JCS_RGB;
@@ -136,23 +150,12 @@ default_decompress_parms (j_decompress_ptr cinfo)
 	break;
       default:
 	WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform);
-	cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */
+	cinfo->jpeg_color_space = JCS_YCbCr;	/* assume it's YCbCr */
 	break;
       }
     } else {
-      /* Saw no special markers, try to guess from the component IDs */
-      int cid0 = cinfo->comp_info[0].component_id;
-      int cid1 = cinfo->comp_info[1].component_id;
-      int cid2 = cinfo->comp_info[2].component_id;
-
-      if (cid0 == 1 && cid1 == 2 && cid2 == 3)
-	cinfo->jpeg_color_space = JCS_YCbCr; /* assume JFIF w/out marker */
-      else if (cid0 == 82 && cid1 == 71 && cid2 == 66)
-	cinfo->jpeg_color_space = JCS_RGB; /* ASCII 'R', 'G', 'B' */
-      else {
-	TRACEMS3(cinfo, 1, JTRC_UNKNOWN_IDS, cid0, cid1, cid2);
-	cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */
-      }
+      TRACEMS3(cinfo, 1, JTRC_UNKNOWN_IDS, cid0, cid1, cid2);
+      cinfo->jpeg_color_space = JCS_YCbCr;	/* assume it's YCbCr */
     }
     /* Always guess RGB is proper output colorspace. */
     cinfo->out_color_space = JCS_RGB;
@@ -169,7 +172,7 @@ default_decompress_parms (j_decompress_ptr cinfo)
 	break;
       default:
 	WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform);
-	cinfo->jpeg_color_space = JCS_YCCK; /* assume it's YCCK */
+	cinfo->jpeg_color_space = JCS_YCCK;	/* assume it's YCCK */
 	break;
       }
     } else {
diff --git a/Source/LibJPEG/jdapistd.c b/Source/LibJPEG/jdapistd.c
index 9d74537..7f3a78b 100644
--- a/Source/LibJPEG/jdapistd.c
+++ b/Source/LibJPEG/jdapistd.c
@@ -2,6 +2,7 @@
  * jdapistd.c
  *
  * Copyright (C) 1994-1996, Thomas G. Lane.
+ * Modified 2002-2013 by Guido Vollbeding.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
diff --git a/Source/LibJPEG/jdarith.c b/Source/LibJPEG/jdarith.c
index 092f8af..efdb26d 100644
--- a/Source/LibJPEG/jdarith.c
+++ b/Source/LibJPEG/jdarith.c
@@ -1,7 +1,7 @@
 /*
  * jdarith.c
  *
- * Developed 1997-2011 by Guido Vollbeding.
+ * Developed 1997-2013 by Guido Vollbeding.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
@@ -345,12 +345,15 @@ decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
   /* Sections F.2.4.2 & F.1.4.4.2: Decoding of AC coefficients */
 
   /* Figure F.20: Decode_AC_coefficients */
-  for (k = cinfo->Ss; k <= cinfo->Se; k++) {
-    st = entropy->ac_stats[tbl] + 3 * (k - 1);
+  k = cinfo->Ss - 1;
+  do {
+    st = entropy->ac_stats[tbl] + 3 * k;
     if (arith_decode(cinfo, st)) break;		/* EOB flag */
-    while (arith_decode(cinfo, st + 1) == 0) {
-      st += 3; k++;
-      if (k > cinfo->Se) {
+    for (;;) {
+      k++;
+      if (arith_decode(cinfo, st + 1)) break;
+      st += 3;
+      if (k >= cinfo->Se) {
 	WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
 	entropy->ct = -1;			/* spectral overflow */
 	return TRUE;
@@ -384,7 +387,7 @@ decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
     v += 1; if (sign) v = -v;
     /* Scale and output coefficient in natural (dezigzagged) order */
     (*block)[natural_order[k]] = (JCOEF) (v << cinfo->Al);
-  }
+  } while (k < cinfo->Se);
 
   return TRUE;
 }
@@ -392,6 +395,8 @@ decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
 
 /*
  * MCU decoding for DC successive approximation refinement scan.
+ * Note: we assume such scans can be multi-component,
+ * although the spec is not very clear on the point.
  */
 
 METHODDEF(boolean)
@@ -457,15 +462,18 @@ decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
   m1 = (-1) << cinfo->Al;	/* -1 in the bit position being coded */
 
   /* Establish EOBx (previous stage end-of-block) index */
-  for (kex = cinfo->Se; kex > 0; kex--)
+  kex = cinfo->Se;
+  do {
     if ((*block)[natural_order[kex]]) break;
+  } while (--kex);
 
-  for (k = cinfo->Ss; k <= cinfo->Se; k++) {
-    st = entropy->ac_stats[tbl] + 3 * (k - 1);
-    if (k > kex)
+  k = cinfo->Ss - 1;
+  do {
+    st = entropy->ac_stats[tbl] + 3 * k;
+    if (k >= kex)
       if (arith_decode(cinfo, st)) break;	/* EOB flag */
     for (;;) {
-      thiscoef = *block + natural_order[k];
+      thiscoef = *block + natural_order[++k];
       if (*thiscoef) {				/* previously nonzero coef */
 	if (arith_decode(cinfo, st + 2)) {
 	  if (*thiscoef < 0)
@@ -482,14 +490,14 @@ decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
 	  *thiscoef = p1;
 	break;
       }
-      st += 3; k++;
-      if (k > cinfo->Se) {
+      st += 3;
+      if (k >= cinfo->Se) {
 	WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
 	entropy->ct = -1;			/* spectral overflow */
 	return TRUE;
       }
     }
-  }
+  } while (k < cinfo->Se);
 
   return TRUE;
 }
@@ -738,6 +746,17 @@ start_pass (j_decompress_ptr cinfo)
 
 
 /*
+ * Finish up at the end of an arithmetic-compressed scan.
+ */
+
+METHODDEF(void)
+finish_pass (j_decompress_ptr cinfo)
+{
+  /* no work necessary here */
+}
+
+
+/*
  * Module initialization routine for arithmetic entropy decoding.
  */
 
@@ -750,8 +769,9 @@ jinit_arith_decoder (j_decompress_ptr cinfo)
   entropy = (arith_entropy_ptr)
     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 				SIZEOF(arith_entropy_decoder));
-  cinfo->entropy = (struct jpeg_entropy_decoder *) entropy;
+  cinfo->entropy = &entropy->pub;
   entropy->pub.start_pass = start_pass;
+  entropy->pub.finish_pass = finish_pass;
 
   /* Mark tables unallocated */
   for (i = 0; i < NUM_ARITH_TBLS; i++) {
diff --git a/Source/LibJPEG/jdatadst.c b/Source/LibJPEG/jdatadst.c
index 6981fb7..5c8681c 100644
--- a/Source/LibJPEG/jdatadst.c
+++ b/Source/LibJPEG/jdatadst.c
@@ -226,6 +226,9 @@ jpeg_stdio_dest (j_compress_ptr cinfo, FILE * outfile)
  * larger memory, so the buffer is available to the application after
  * finishing compression, and then the application is responsible for
  * freeing the requested memory.
+ * Note:  An initial buffer supplied by the caller is expected to be
+ * managed by the application.  The library does not free such buffer
+ * when allocating a larger buffer.
  */
 
 GLOBAL(void)
diff --git a/Source/LibJPEG/jdcolor.c b/Source/LibJPEG/jdcolor.c
index 83e4d06..a31c286 100644
--- a/Source/LibJPEG/jdcolor.c
+++ b/Source/LibJPEG/jdcolor.c
@@ -2,7 +2,7 @@
  * jdcolor.c
  *
  * Copyright (C) 1991-1997, Thomas G. Lane.
- * Modified 2011 by Guido Vollbeding.
+ * Modified 2011-2013 by Guido Vollbeding.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
@@ -19,12 +19,15 @@
 typedef struct {
   struct jpeg_color_deconverter pub; /* public fields */
 
-  /* Private state for YCC->RGB conversion */
+  /* Private state for YCbCr->RGB and BG_YCC->RGB conversion */
   int * Cr_r_tab;		/* => table for Cr to R conversion */
   int * Cb_b_tab;		/* => table for Cb to B conversion */
   INT32 * Cr_g_tab;		/* => table for Cr to G conversion */
   INT32 * Cb_g_tab;		/* => table for Cb to G conversion */
 
+  JSAMPLE * range_limit; /* pointer to normal sample range limit table, */
+		     /* or extended sample range limit table for BG_YCC */
+
   /* Private state for RGB->Y conversion */
   INT32 * rgb_y_tab;		/* => table for RGB to Y conversion */
 } my_color_deconverter;
@@ -32,22 +35,44 @@ typedef struct {
 typedef my_color_deconverter * my_cconvert_ptr;
 
 
-/**************** YCbCr -> RGB conversion: most common case **************/
-/****************   RGB -> Y   conversion: less common case **************/
+/***************  YCbCr -> RGB conversion: most common case **************/
+/*************** BG_YCC -> RGB conversion: less common case **************/
+/***************    RGB -> Y   conversion: less common case **************/
 
 /*
- * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
- * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
- * The conversion equations to be implemented are therefore
+ * YCbCr is defined per Recommendation ITU-R BT.601-7 (03/2011),
+ * previously known as Recommendation CCIR 601-1, except that Cb and Cr
+ * are normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
+ * sRGB (standard RGB color space) is defined per IEC 61966-2-1:1999.
+ * sYCC (standard luma-chroma-chroma color space with extended gamut)
+ * is defined per IEC 61966-2-1:1999 Amendment A1:2003 Annex F.
+ * bg-sRGB and bg-sYCC (big gamut standard color spaces)
+ * are defined per IEC 61966-2-1:1999 Amendment A1:2003 Annex G.
+ * Note that the derived conversion coefficients given in some of these
+ * documents are imprecise.  The general conversion equations are
+ *
+ *	R = Y + K * (1 - Kr) * Cr
+ *	G = Y - K * (Kb * (1 - Kb) * Cb + Kr * (1 - Kr) * Cr) / (1 - Kr - Kb)
+ *	B = Y + K * (1 - Kb) * Cb
+ *
+ *	Y = Kr * R + (1 - Kr - Kb) * G + Kb * B
+ *
+ * With Kr = 0.299 and Kb = 0.114 (derived according to SMPTE RP 177-1993
+ * from the 1953 FCC NTSC primaries and CIE Illuminant C), K = 2 for sYCC,
+ * the conversion equations to be implemented are therefore
  *
- *	R = Y                + 1.40200 * Cr
- *	G = Y - 0.34414 * Cb - 0.71414 * Cr
- *	B = Y + 1.77200 * Cb
+ *	R = Y + 1.402 * Cr
+ *	G = Y - 0.344136286 * Cb - 0.714136286 * Cr
+ *	B = Y + 1.772 * Cb
  *
- *	Y = 0.29900 * R + 0.58700 * G + 0.11400 * B
+ *	Y = 0.299 * R + 0.587 * G + 0.114 * B
  *
  * where Cb and Cr represent the incoming values less CENTERJSAMPLE.
- * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
+ * For bg-sYCC, with K = 4, the equations are
+ *
+ *	R = Y + 2.804 * Cr
+ *	G = Y - 0.688272572 * Cb - 1.428272572 * Cr
+ *	B = Y + 3.544 * Cb
  *
  * To avoid floating-point arithmetic, we represent the fractional constants
  * as integers scaled up by 2^16 (about 4 digits precision); we have to divide
@@ -58,9 +83,9 @@ typedef my_color_deconverter * my_cconvert_ptr;
  * For even more speed, we avoid doing any multiplications in the inner loop
  * by precalculating the constants times Cb and Cr for all possible values.
  * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
- * for 12-bit samples it is still acceptable.  It's not very reasonable for
- * 16-bit samples, but if you want lossless storage you shouldn't be changing
- * colorspace anyway.
+ * for 9-bit to 12-bit samples it is still acceptable.  It's not very
+ * reasonable for 16-bit samples, but if you want lossless storage you
+ * shouldn't be changing colorspace anyway.
  * The Cr=>R and Cb=>B values can be rounded to integers in advance; the
  * values for the G calculation are left scaled up, since we must add them
  * together before rounding.
@@ -84,11 +109,12 @@ typedef my_color_deconverter * my_cconvert_ptr;
 
 
 /*
- * Initialize tables for YCC->RGB colorspace conversion.
+ * Initialize tables for YCbCr->RGB and BG_YCC->RGB colorspace conversion.
  */
 
 LOCAL(void)
 build_ycc_rgb_table (j_decompress_ptr cinfo)
+/* Normal case, sYCC */
 {
   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
   int i;
@@ -108,24 +134,84 @@ build_ycc_rgb_table (j_decompress_ptr cinfo)
     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 				(MAXJSAMPLE+1) * SIZEOF(INT32));
 
+  cconvert->range_limit = cinfo->sample_range_limit;
+
   for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
     /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
     /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
-    /* Cr=>R value is nearest int to 1.40200 * x */
+    /* Cr=>R value is nearest int to 1.402 * x */
     cconvert->Cr_r_tab[i] = (int)
-		    RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
-    /* Cb=>B value is nearest int to 1.77200 * x */
+		    RIGHT_SHIFT(FIX(1.402) * x + ONE_HALF, SCALEBITS);
+    /* Cb=>B value is nearest int to 1.772 * x */
     cconvert->Cb_b_tab[i] = (int)
-		    RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
-    /* Cr=>G value is scaled-up -0.71414 * x */
-    cconvert->Cr_g_tab[i] = (- FIX(0.71414)) * x;
-    /* Cb=>G value is scaled-up -0.34414 * x */
+		    RIGHT_SHIFT(FIX(1.772) * x + ONE_HALF, SCALEBITS);
+    /* Cr=>G value is scaled-up -0.714136286 * x */
+    cconvert->Cr_g_tab[i] = (- FIX(0.714136286)) * x;
+    /* Cb=>G value is scaled-up -0.344136286 * x */
     /* We also add in ONE_HALF so that need not do it in inner loop */
-    cconvert->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
+    cconvert->Cb_g_tab[i] = (- FIX(0.344136286)) * x + ONE_HALF;
   }
 }
 
 
+LOCAL(void)
+build_bg_ycc_rgb_table (j_decompress_ptr cinfo)
+/* Wide gamut case, bg-sYCC */
+{
+  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
+  int i;
+  INT32 x;
+  SHIFT_TEMPS
+
+  cconvert->Cr_r_tab = (int *)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				(MAXJSAMPLE+1) * SIZEOF(int));
+  cconvert->Cb_b_tab = (int *)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				(MAXJSAMPLE+1) * SIZEOF(int));
+  cconvert->Cr_g_tab = (INT32 *)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				(MAXJSAMPLE+1) * SIZEOF(INT32));
+  cconvert->Cb_g_tab = (INT32 *)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				(MAXJSAMPLE+1) * SIZEOF(INT32));
+
+  cconvert->range_limit = (JSAMPLE *)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				5 * (MAXJSAMPLE+1) * SIZEOF(JSAMPLE));
+
+  for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
+    /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
+    /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
+    /* Cr=>R value is nearest int to 2.804 * x */
+    cconvert->Cr_r_tab[i] = (int)
+		    RIGHT_SHIFT(FIX(2.804) * x + ONE_HALF, SCALEBITS);
+    /* Cb=>B value is nearest int to 3.544 * x */
+    cconvert->Cb_b_tab[i] = (int)
+		    RIGHT_SHIFT(FIX(3.544) * x + ONE_HALF, SCALEBITS);
+    /* Cr=>G value is scaled-up -1.428272572 * x */
+    cconvert->Cr_g_tab[i] = (- FIX(1.428272572)) * x;
+    /* Cb=>G value is scaled-up -0.688272572 * x */
+    /* We also add in ONE_HALF so that need not do it in inner loop */
+    cconvert->Cb_g_tab[i] = (- FIX(0.688272572)) * x + ONE_HALF;
+  }
+
+  /* Cb and Cr portions can extend to double range in wide gamut case,
+   * so we prepare an appropriate extended range limit table.
+   */
+
+  /* First segment of range limit table: limit[x] = 0 for x < 0 */
+  MEMZERO(cconvert->range_limit, 2 * (MAXJSAMPLE+1) * SIZEOF(JSAMPLE));
+  cconvert->range_limit += 2 * (MAXJSAMPLE+1);
+  /* Main part of range limit table: limit[x] = x */
+  for (i = 0; i <= MAXJSAMPLE; i++)
+    cconvert->range_limit[i] = (JSAMPLE) i;
+  /* End of range limit table: limit[x] = MAXJSAMPLE for x > MAXJSAMPLE */
+  for (; i < 3 * (MAXJSAMPLE+1); i++)
+    cconvert->range_limit[i] = MAXJSAMPLE;
+}
+
+
 /*
  * Convert some rows of samples to the output colorspace.
  *
@@ -149,7 +235,7 @@ ycc_rgb_convert (j_decompress_ptr cinfo,
   register JDIMENSION col;
   JDIMENSION num_cols = cinfo->output_width;
   /* copy these pointers into registers if possible */
-  register JSAMPLE * range_limit = cinfo->sample_range_limit;
+  register JSAMPLE * range_limit = cconvert->range_limit;
   register int * Crrtab = cconvert->Cr_r_tab;
   register int * Cbbtab = cconvert->Cb_b_tab;
   register INT32 * Crgtab = cconvert->Cr_g_tab;
@@ -166,19 +252,21 @@ ycc_rgb_convert (j_decompress_ptr cinfo,
       y  = GETJSAMPLE(inptr0[col]);
       cb = GETJSAMPLE(inptr1[col]);
       cr = GETJSAMPLE(inptr2[col]);
-      /* Range-limiting is essential due to noise introduced by DCT losses. */
-      outptr[RGB_RED] =   range_limit[y + Crrtab[cr]];
+      /* Range-limiting is essential due to noise introduced by DCT losses,
+       * for extended gamut (sYCC) and wide gamut (bg-sYCC) encodings.
+       */
+      outptr[RGB_RED]   = range_limit[y + Crrtab[cr]];
       outptr[RGB_GREEN] = range_limit[y +
 			      ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
 						 SCALEBITS))];
-      outptr[RGB_BLUE] =  range_limit[y + Cbbtab[cb]];
+      outptr[RGB_BLUE]  = range_limit[y + Cbbtab[cb]];
       outptr += RGB_PIXELSIZE;
     }
   }
 }
 
 
-/**************** Cases other than YCbCr -> RGB **************/
+/**************** Cases other than YCC -> RGB ****************/
 
 
 /*
@@ -198,9 +286,9 @@ build_rgb_y_table (j_decompress_ptr cinfo)
 				(TABLE_SIZE * SIZEOF(INT32)));
 
   for (i = 0; i <= MAXJSAMPLE; i++) {
-    rgb_y_tab[i+R_Y_OFF] = FIX(0.29900) * i;
-    rgb_y_tab[i+G_Y_OFF] = FIX(0.58700) * i;
-    rgb_y_tab[i+B_Y_OFF] = FIX(0.11400) * i + ONE_HALF;
+    rgb_y_tab[i+R_Y_OFF] = FIX(0.299) * i;
+    rgb_y_tab[i+G_Y_OFF] = FIX(0.587) * i;
+    rgb_y_tab[i+B_Y_OFF] = FIX(0.114) * i + ONE_HALF;
   }
 }
 
@@ -215,8 +303,86 @@ rgb_gray_convert (j_decompress_ptr cinfo,
 		  JSAMPARRAY output_buf, int num_rows)
 {
   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
+  register INT32 * ctab = cconvert->rgb_y_tab;
+  register int r, g, b;
+  register JSAMPROW outptr;
+  register JSAMPROW inptr0, inptr1, inptr2;
+  register JDIMENSION col;
+  JDIMENSION num_cols = cinfo->output_width;
+
+  while (--num_rows >= 0) {
+    inptr0 = input_buf[0][input_row];
+    inptr1 = input_buf[1][input_row];
+    inptr2 = input_buf[2][input_row];
+    input_row++;
+    outptr = *output_buf++;
+    for (col = 0; col < num_cols; col++) {
+      r = GETJSAMPLE(inptr0[col]);
+      g = GETJSAMPLE(inptr1[col]);
+      b = GETJSAMPLE(inptr2[col]);
+      /* Y */
+      outptr[col] = (JSAMPLE)
+		((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
+		 >> SCALEBITS);
+    }
+  }
+}
+
+
+/*
+ * [R-G,G,B-G] to [R,G,B] conversion with modulo calculation
+ * (inverse color transform).
+ * This can be seen as an adaption of the general YCbCr->RGB
+ * conversion equation with Kr = Kb = 0, while replacing the
+ * normalization by modulo calculation.
+ */
+
+METHODDEF(void)
+rgb1_rgb_convert (j_decompress_ptr cinfo,
+		  JSAMPIMAGE input_buf, JDIMENSION input_row,
+		  JSAMPARRAY output_buf, int num_rows)
+{
   register int r, g, b;
+  register JSAMPROW outptr;
+  register JSAMPROW inptr0, inptr1, inptr2;
+  register JDIMENSION col;
+  JDIMENSION num_cols = cinfo->output_width;
+
+  while (--num_rows >= 0) {
+    inptr0 = input_buf[0][input_row];
+    inptr1 = input_buf[1][input_row];
+    inptr2 = input_buf[2][input_row];
+    input_row++;
+    outptr = *output_buf++;
+    for (col = 0; col < num_cols; col++) {
+      r = GETJSAMPLE(inptr0[col]);
+      g = GETJSAMPLE(inptr1[col]);
+      b = GETJSAMPLE(inptr2[col]);
+      /* Assume that MAXJSAMPLE+1 is a power of 2, so that the MOD
+       * (modulo) operator is equivalent to the bitmask operator AND.
+       */
+      outptr[RGB_RED]   = (JSAMPLE) ((r + g - CENTERJSAMPLE) & MAXJSAMPLE);
+      outptr[RGB_GREEN] = (JSAMPLE) g;
+      outptr[RGB_BLUE]  = (JSAMPLE) ((b + g - CENTERJSAMPLE) & MAXJSAMPLE);
+      outptr += RGB_PIXELSIZE;
+    }
+  }
+}
+
+
+/*
+ * [R-G,G,B-G] to grayscale conversion with modulo calculation
+ * (inverse color transform).
+ */
+
+METHODDEF(void)
+rgb1_gray_convert (j_decompress_ptr cinfo,
+		   JSAMPIMAGE input_buf, JDIMENSION input_row,
+		   JSAMPARRAY output_buf, int num_rows)
+{
+  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
   register INT32 * ctab = cconvert->rgb_y_tab;
+  register int r, g, b;
   register JSAMPROW outptr;
   register JSAMPROW inptr0, inptr1, inptr2;
   register JDIMENSION col;
@@ -232,6 +398,11 @@ rgb_gray_convert (j_decompress_ptr cinfo,
       r = GETJSAMPLE(inptr0[col]);
       g = GETJSAMPLE(inptr1[col]);
       b = GETJSAMPLE(inptr2[col]);
+      /* Assume that MAXJSAMPLE+1 is a power of 2, so that the MOD
+       * (modulo) operator is equivalent to the bitmask operator AND.
+       */
+      r = (r + g - CENTERJSAMPLE) & MAXJSAMPLE;
+      b = (b + g - CENTERJSAMPLE) & MAXJSAMPLE;
       /* Y */
       outptr[col] = (JSAMPLE)
 		((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
@@ -283,19 +454,20 @@ null_convert (j_decompress_ptr cinfo,
 	      JSAMPIMAGE input_buf, JDIMENSION input_row,
 	      JSAMPARRAY output_buf, int num_rows)
 {
-  register JSAMPROW inptr, outptr;
-  register JDIMENSION count;
-  register int num_components = cinfo->num_components;
-  JDIMENSION num_cols = cinfo->output_width;
   int ci;
+  register int nc = cinfo->num_components;
+  register JSAMPROW outptr;
+  register JSAMPROW inptr;
+  register JDIMENSION col;
+  JDIMENSION num_cols = cinfo->output_width;
 
   while (--num_rows >= 0) {
-    for (ci = 0; ci < num_components; ci++) {
+    for (ci = 0; ci < nc; ci++) {
       inptr = input_buf[ci][input_row];
       outptr = output_buf[0] + ci;
-      for (count = num_cols; count > 0; count--) {
+      for (col = 0; col < num_cols; col++) {
 	*outptr = *inptr++;	/* needn't bother with GETJSAMPLE() here */
-	outptr += num_components;
+	outptr += nc;
       }
     }
     input_row++;
@@ -306,7 +478,7 @@ null_convert (j_decompress_ptr cinfo,
 
 /*
  * Color conversion for grayscale: just copy the data.
- * This also works for YCbCr -> grayscale conversion, in which
+ * This also works for YCC -> grayscale conversion, in which
  * we just copy the Y (luminance) component and ignore chrominance.
  */
 
@@ -331,7 +503,8 @@ gray_rgb_convert (j_decompress_ptr cinfo,
 		  JSAMPIMAGE input_buf, JDIMENSION input_row,
 		  JSAMPARRAY output_buf, int num_rows)
 {
-  register JSAMPROW inptr, outptr;
+  register JSAMPROW outptr;
+  register JSAMPROW inptr;
   register JDIMENSION col;
   JDIMENSION num_cols = cinfo->output_width;
 
@@ -384,7 +557,9 @@ ycck_cmyk_convert (j_decompress_ptr cinfo,
       y  = GETJSAMPLE(inptr0[col]);
       cb = GETJSAMPLE(inptr1[col]);
       cr = GETJSAMPLE(inptr2[col]);
-      /* Range-limiting is essential due to noise introduced by DCT losses. */
+      /* Range-limiting is essential due to noise introduced by DCT losses,
+       * and for extended gamut encodings (sYCC).
+       */
       outptr[0] = range_limit[MAXJSAMPLE - (y + Crrtab[cr])];	/* red */
       outptr[1] = range_limit[MAXJSAMPLE - (y +			/* green */
 			      ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
@@ -422,7 +597,7 @@ jinit_color_deconverter (j_decompress_ptr cinfo)
   cconvert = (my_cconvert_ptr)
     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 				SIZEOF(my_color_deconverter));
-  cinfo->cconvert = (struct jpeg_color_deconverter *) cconvert;
+  cinfo->cconvert = &cconvert->pub;
   cconvert->pub.start_pass = start_pass_dcolor;
 
   /* Make sure num_components agrees with jpeg_color_space */
@@ -434,6 +609,8 @@ jinit_color_deconverter (j_decompress_ptr cinfo)
 
   case JCS_RGB:
   case JCS_YCbCr:
+  case JCS_BG_RGB:
+  case JCS_BG_YCC:
     if (cinfo->num_components != 3)
       ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
     break;
@@ -450,6 +627,12 @@ jinit_color_deconverter (j_decompress_ptr cinfo)
     break;
   }
 
+  /* Support color transform only for RGB colorspaces */
+  if (cinfo->color_transform &&
+      cinfo->jpeg_color_space != JCS_RGB &&
+      cinfo->jpeg_color_space != JCS_BG_RGB)
+    ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+
   /* Set out_color_components and conversion method based on requested space.
    * Also clear the component_needed flags for any unused components,
    * so that earlier pipeline stages can avoid useless computation.
@@ -458,41 +641,94 @@ jinit_color_deconverter (j_decompress_ptr cinfo)
   switch (cinfo->out_color_space) {
   case JCS_GRAYSCALE:
     cinfo->out_color_components = 1;
-    if (cinfo->jpeg_color_space == JCS_GRAYSCALE ||
-	cinfo->jpeg_color_space == JCS_YCbCr) {
+    switch (cinfo->jpeg_color_space) {
+    case JCS_GRAYSCALE:
+    case JCS_YCbCr:
+    case JCS_BG_YCC:
       cconvert->pub.color_convert = grayscale_convert;
       /* For color->grayscale conversion, only the Y (0) component is needed */
       for (ci = 1; ci < cinfo->num_components; ci++)
 	cinfo->comp_info[ci].component_needed = FALSE;
-    } else if (cinfo->jpeg_color_space == JCS_RGB) {
-      cconvert->pub.color_convert = rgb_gray_convert;
+      break;
+    case JCS_RGB:
+      switch (cinfo->color_transform) {
+      case JCT_NONE:
+	cconvert->pub.color_convert = rgb_gray_convert;
+	break;
+      case JCT_SUBTRACT_GREEN:
+	cconvert->pub.color_convert = rgb1_gray_convert;
+	break;
+      default:
+	ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+      }
       build_rgb_y_table(cinfo);
-    } else
+      break;
+    default:
       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+    }
     break;
 
   case JCS_RGB:
     cinfo->out_color_components = RGB_PIXELSIZE;
-    if (cinfo->jpeg_color_space == JCS_YCbCr) {
+    switch (cinfo->jpeg_color_space) {
+    case JCS_GRAYSCALE:
+      cconvert->pub.color_convert = gray_rgb_convert;
+      break;
+    case JCS_YCbCr:
       cconvert->pub.color_convert = ycc_rgb_convert;
       build_ycc_rgb_table(cinfo);
-    } else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) {
-      cconvert->pub.color_convert = gray_rgb_convert;
-    } else if (cinfo->jpeg_color_space == JCS_RGB) {
-      cconvert->pub.color_convert = rgb_convert;
+      break;
+    case JCS_BG_YCC:
+      cconvert->pub.color_convert = ycc_rgb_convert;
+      build_bg_ycc_rgb_table(cinfo);
+      break;
+    case JCS_RGB:
+      switch (cinfo->color_transform) {
+      case JCT_NONE:
+	cconvert->pub.color_convert = rgb_convert;
+	break;
+      case JCT_SUBTRACT_GREEN:
+	cconvert->pub.color_convert = rgb1_rgb_convert;
+	break;
+      default:
+	ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+      }
+      break;
+    default:
+      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+    }
+    break;
+
+  case JCS_BG_RGB:
+    cinfo->out_color_components = RGB_PIXELSIZE;
+    if (cinfo->jpeg_color_space == JCS_BG_RGB) {
+      switch (cinfo->color_transform) {
+      case JCT_NONE:
+	cconvert->pub.color_convert = rgb_convert;
+	break;
+      case JCT_SUBTRACT_GREEN:
+	cconvert->pub.color_convert = rgb1_rgb_convert;
+	break;
+      default:
+	ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+      }
     } else
       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
     break;
 
   case JCS_CMYK:
     cinfo->out_color_components = 4;
-    if (cinfo->jpeg_color_space == JCS_YCCK) {
+    switch (cinfo->jpeg_color_space) {
+    case JCS_YCCK:
       cconvert->pub.color_convert = ycck_cmyk_convert;
       build_ycc_rgb_table(cinfo);
-    } else if (cinfo->jpeg_color_space == JCS_CMYK) {
+      break;
+    case JCS_CMYK:
       cconvert->pub.color_convert = null_convert;
-    } else
+      break;
+    default:
       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+    }
     break;
 
   default:
diff --git a/Source/LibJPEG/jddctmgr.c b/Source/LibJPEG/jddctmgr.c
index 0ded9d5..9ecfbb5 100644
--- a/Source/LibJPEG/jddctmgr.c
+++ b/Source/LibJPEG/jddctmgr.c
@@ -2,7 +2,7 @@
  * jddctmgr.c
  *
  * Copyright (C) 1994-1996, Thomas G. Lane.
- * Modified 2002-2010 by Guido Vollbeding.
+ * Modified 2002-2013 by Guido Vollbeding.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
@@ -368,7 +368,7 @@ jinit_inverse_dct (j_decompress_ptr cinfo)
   idct = (my_idct_ptr)
     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 				SIZEOF(my_idct_controller));
-  cinfo->idct = (struct jpeg_inverse_dct *) idct;
+  cinfo->idct = &idct->pub;
   idct->pub.start_pass = start_pass;
 
   for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
diff --git a/Source/LibJPEG/jdhuff.c b/Source/LibJPEG/jdhuff.c
index 06f92fe..6920e20 100644
--- a/Source/LibJPEG/jdhuff.c
+++ b/Source/LibJPEG/jdhuff.c
@@ -2,7 +2,7 @@
  * jdhuff.c
  *
  * Copyright (C) 1991-1997, Thomas G. Lane.
- * Modified 2006-2009 by Guido Vollbeding.
+ * Modified 2006-2013 by Guido Vollbeding.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
@@ -628,6 +628,22 @@ jpeg_huff_decode (bitread_working_state * state,
 
 
 /*
+ * Finish up at the end of a Huffman-compressed scan.
+ */
+
+METHODDEF(void)
+finish_pass_huff (j_decompress_ptr cinfo)
+{
+  huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
+
+  /* Throw away any unused bits remaining in bit buffer; */
+  /* include any full bytes in next_marker's count of discarded bytes */
+  cinfo->marker->discarded_bytes += entropy->bitstate.bits_left / 8;
+  entropy->bitstate.bits_left = 0;
+}
+
+
+/*
  * Check for a restart marker & resynchronize decoder.
  * Returns FALSE if must suspend.
  */
@@ -638,10 +654,7 @@ process_restart (j_decompress_ptr cinfo)
   huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
   int ci;
 
-  /* Throw away any unused bits remaining in bit buffer; */
-  /* include any full bytes in next_marker's count of discarded bytes */
-  cinfo->marker->discarded_bytes += entropy->bitstate.bits_left / 8;
-  entropy->bitstate.bits_left = 0;
+  finish_pass_huff(cinfo);
 
   /* Advance past the RSTn marker */
   if (! (*cinfo->marker->read_restart_marker) (cinfo))
@@ -797,7 +810,7 @@ decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
 
     /* There is always only one block per MCU */
 
-    if (EOBRUN > 0)		/* if it's a band of zeroes... */
+    if (EOBRUN)			/* if it's a band of zeroes... */
       EOBRUN--;			/* ...process it now (we do nothing) */
     else {
       BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
@@ -816,18 +829,17 @@ decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
 	  /* Scale and output coefficient in natural (dezigzagged) order */
 	  (*block)[natural_order[k]] = (JCOEF) (s << Al);
 	} else {
-	  if (r == 15) {	/* ZRL */
-	    k += 15;		/* skip 15 zeroes in band */
-	  } else {		/* EOBr, run length is 2^r + appended bits */
-	    EOBRUN = 1 << r;
+	  if (r != 15) {	/* EOBr, run length is 2^r + appended bits */
 	    if (r) {		/* EOBr, r > 0 */
+	      EOBRUN = 1 << r;
 	      CHECK_BIT_BUFFER(br_state, r, return FALSE);
 	      r = GET_BITS(r);
 	      EOBRUN += r;
+	      EOBRUN--;		/* this band is processed at this moment */
 	    }
-	    EOBRUN--;		/* this band is processed at this moment */
 	    break;		/* force end-of-band */
 	  }
+	  k += 15;		/* ZRL: skip 15 zeroes in band */
 	}
       }
 
@@ -847,17 +859,15 @@ decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
 
 /*
  * MCU decoding for DC successive approximation refinement scan.
- * Note: we assume such scans can be multi-component, although the spec
- * is not very clear on the point.
+ * Note: we assume such scans can be multi-component,
+ * although the spec is not very clear on the point.
  */
 
 METHODDEF(boolean)
 decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
 {   
   huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
-  int p1 = 1 << cinfo->Al;	/* 1 in the bit position being coded */
-  int blkn;
-  JBLOCKROW block;
+  int p1, blkn;
   BITREAD_STATE_VARS;
 
   /* Process restart marker if needed; may have to suspend */
@@ -874,15 +884,15 @@ decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
   /* Load up working state */
   BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
 
+  p1 = 1 << cinfo->Al;		/* 1 in the bit position being coded */
+
   /* Outer loop handles each block in the MCU */
 
   for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
-    block = MCU_data[blkn];
-
     /* Encoded data is simply the next bit of the two's-complement DC value */
     CHECK_BIT_BUFFER(br_state, 1, return FALSE);
     if (GET_BITS(1))
-      (*block)[0] |= p1;
+      MCU_data[blkn][0][0] |= p1;
     /* Note: since we use |=, repeating the assignment later is safe */
   }
 
@@ -951,7 +961,7 @@ decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
     k = cinfo->Ss;
 
     if (EOBRUN == 0) {
-      for (; k <= Se; k++) {
+      do {
 	HUFF_DECODE(s, br_state, tbl, goto undoit, label3);
 	r = s >> 4;
 	s &= 15;
@@ -981,7 +991,7 @@ decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
 	 */
 	do {
 	  thiscoef = *block + natural_order[k];
-	  if (*thiscoef != 0) {
+	  if (*thiscoef) {
 	    CHECK_BIT_BUFFER(br_state, 1, goto undoit);
 	    if (GET_BITS(1)) {
 	      if ((*thiscoef & p1) == 0) { /* do nothing if already set it */
@@ -1004,18 +1014,19 @@ decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
 	  /* Remember its position in case we have to suspend */
 	  newnz_pos[num_newnz++] = pos;
 	}
-      }
+	k++;
+      } while (k <= Se);
     }
 
-    if (EOBRUN > 0) {
+    if (EOBRUN) {
       /* Scan any remaining coefficient positions after the end-of-band
        * (the last newly nonzero coefficient, if any).  Append a correction
        * bit to each already-nonzero coefficient.  A correction bit is 1
        * if the absolute value of the coefficient must be increased.
        */
-      for (; k <= Se; k++) {
+      do {
 	thiscoef = *block + natural_order[k];
-	if (*thiscoef != 0) {
+	if (*thiscoef) {
 	  CHECK_BIT_BUFFER(br_state, 1, goto undoit);
 	  if (GET_BITS(1)) {
 	    if ((*thiscoef & p1) == 0) { /* do nothing if already changed it */
@@ -1026,7 +1037,8 @@ decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
 	    }
 	  }
 	}
-      }
+	k++;
+      } while (k <= Se);
       /* Count one block completed in EOB run */
       EOBRUN--;
     }
@@ -1043,7 +1055,7 @@ decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
 
 undoit:
   /* Re-zero any output coefficients that we made newly nonzero */
-  while (num_newnz > 0)
+  while (num_newnz)
     (*block)[newnz_pos[--num_newnz]] = 0;
 
   return FALSE;
@@ -1514,8 +1526,9 @@ jinit_huff_decoder (j_decompress_ptr cinfo)
   entropy = (huff_entropy_ptr)
     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 				SIZEOF(huff_entropy_decoder));
-  cinfo->entropy = (struct jpeg_entropy_decoder *) entropy;
+  cinfo->entropy = &entropy->pub;
   entropy->pub.start_pass = start_pass_huff_decoder;
+  entropy->pub.finish_pass = finish_pass_huff;
 
   if (cinfo->progressive_mode) {
     /* Create progression status table */
diff --git a/Source/LibJPEG/jdinput.c b/Source/LibJPEG/jdinput.c
index 2c5c717..0199553 100644
--- a/Source/LibJPEG/jdinput.c
+++ b/Source/LibJPEG/jdinput.c
@@ -2,7 +2,7 @@
  * jdinput.c
  *
  * Copyright (C) 1991-1997, Thomas G. Lane.
- * Modified 2002-2009 by Guido Vollbeding.
+ * Modified 2002-2013 by Guido Vollbeding.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
@@ -196,7 +196,7 @@ jpeg_core_output_dimensions (j_decompress_ptr cinfo)
   /* Hardwire it to "no scaling" */
   cinfo->output_width = cinfo->image_width;
   cinfo->output_height = cinfo->image_height;
-  /* jdinput.c has already initialized DCT_scaled_size,
+  /* initial_setup has already initialized DCT_scaled_size,
    * and has computed unscaled downsampled_width and downsampled_height.
    */
 
@@ -216,8 +216,8 @@ initial_setup (j_decompress_ptr cinfo)
       (long) cinfo->image_width > (long) JPEG_MAX_DIMENSION)
     ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION);
 
-  /* For now, precision must match compiled-in value... */
-  if (cinfo->data_precision != BITS_IN_JSAMPLE)
+  /* Only 8 to 12 bits data precision are supported for DCT based JPEG */
+  if (cinfo->data_precision < 8 || cinfo->data_precision > 12)
     ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
 
   /* Check that number of components won't exceed internal array sizes */
@@ -537,6 +537,7 @@ start_input_pass (j_decompress_ptr cinfo)
 METHODDEF(void)
 finish_input_pass (j_decompress_ptr cinfo)
 {
+  (*cinfo->entropy->finish_pass) (cinfo);
   cinfo->inputctl->consume_input = consume_markers;
 }
 
@@ -646,7 +647,7 @@ jinit_input_controller (j_decompress_ptr cinfo)
   inputctl = (my_inputctl_ptr)
     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
 				SIZEOF(my_input_controller));
-  cinfo->inputctl = (struct jpeg_input_controller *) inputctl;
+  cinfo->inputctl = &inputctl->pub;
   /* Initialize method pointers */
   inputctl->pub.consume_input = consume_markers;
   inputctl->pub.reset_input_controller = reset_input_controller;
diff --git a/Source/LibJPEG/jdmainct.c b/Source/LibJPEG/jdmainct.c
index 02723ca..52091fb 100644
--- a/Source/LibJPEG/jdmainct.c
+++ b/Source/LibJPEG/jdmainct.c
@@ -2,6 +2,7 @@
  * jdmainct.c
  *
  * Copyright (C) 1994-1996, Thomas G. Lane.
+ * Modified 2002-2012 by Guido Vollbeding.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
@@ -159,7 +160,7 @@ alloc_funny_pointers (j_decompress_ptr cinfo)
  * This is done only once, not once per pass.
  */
 {
-  my_main_ptr main = (my_main_ptr) cinfo->main;
+  my_main_ptr mainp = (my_main_ptr) cinfo->main;
   int ci, rgroup;
   int M = cinfo->min_DCT_v_scaled_size;
   jpeg_component_info *compptr;
@@ -168,10 +169,10 @@ alloc_funny_pointers (j_decompress_ptr cinfo)
   /* Get top-level space for component array pointers.
    * We alloc both arrays with one call to save a few cycles.
    */
-  main->xbuffer[0] = (JSAMPIMAGE)
+  mainp->xbuffer[0] = (JSAMPIMAGE)
     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 				cinfo->num_components * 2 * SIZEOF(JSAMPARRAY));
-  main->xbuffer[1] = main->xbuffer[0] + cinfo->num_components;
+  mainp->xbuffer[1] = mainp->xbuffer[0] + cinfo->num_components;
 
   for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
        ci++, compptr++) {
@@ -184,9 +185,9 @@ alloc_funny_pointers (j_decompress_ptr cinfo)
       (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 				  2 * (rgroup * (M + 4)) * SIZEOF(JSAMPROW));
     xbuf += rgroup;		/* want one row group at negative offsets */
-    main->xbuffer[0][ci] = xbuf;
+    mainp->xbuffer[0][ci] = xbuf;
     xbuf += rgroup * (M + 4);
-    main->xbuffer[1][ci] = xbuf;
+    mainp->xbuffer[1][ci] = xbuf;
   }
 }
 
@@ -200,7 +201,7 @@ make_funny_pointers (j_decompress_ptr cinfo)
  * This will be repeated at the beginning of each pass.
  */
 {
-  my_main_ptr main = (my_main_ptr) cinfo->main;
+  my_main_ptr mainp = (my_main_ptr) cinfo->main;
   int ci, i, rgroup;
   int M = cinfo->min_DCT_v_scaled_size;
   jpeg_component_info *compptr;
@@ -210,10 +211,10 @@ make_funny_pointers (j_decompress_ptr cinfo)
        ci++, compptr++) {
     rgroup = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) /
       cinfo->min_DCT_v_scaled_size; /* height of a row group of component */
-    xbuf0 = main->xbuffer[0][ci];
-    xbuf1 = main->xbuffer[1][ci];
+    xbuf0 = mainp->xbuffer[0][ci];
+    xbuf1 = mainp->xbuffer[1][ci];
     /* First copy the workspace pointers as-is */
-    buf = main->buffer[ci];
+    buf = mainp->buffer[ci];
     for (i = 0; i < rgroup * (M + 2); i++) {
       xbuf0[i] = xbuf1[i] = buf[i];
     }
@@ -240,7 +241,7 @@ set_wraparound_pointers (j_decompress_ptr cinfo)
  * This changes the pointer list state from top-of-image to the normal state.
  */
 {
-  my_main_ptr main = (my_main_ptr) cinfo->main;
+  my_main_ptr mainp = (my_main_ptr) cinfo->main;
   int ci, i, rgroup;
   int M = cinfo->min_DCT_v_scaled_size;
   jpeg_component_info *compptr;
@@ -250,8 +251,8 @@ set_wraparound_pointers (j_decompress_ptr cinfo)
        ci++, compptr++) {
     rgroup = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) /
       cinfo->min_DCT_v_scaled_size; /* height of a row group of component */
-    xbuf0 = main->xbuffer[0][ci];
-    xbuf1 = main->xbuffer[1][ci];
+    xbuf0 = mainp->xbuffer[0][ci];
+    xbuf1 = mainp->xbuffer[1][ci];
     for (i = 0; i < rgroup; i++) {
       xbuf0[i - rgroup] = xbuf0[rgroup*(M+1) + i];
       xbuf1[i - rgroup] = xbuf1[rgroup*(M+1) + i];
@@ -269,7 +270,7 @@ set_bottom_pointers (j_decompress_ptr cinfo)
  * Also sets rowgroups_avail to indicate number of nondummy row groups in row.
  */
 {
-  my_main_ptr main = (my_main_ptr) cinfo->main;
+  my_main_ptr mainp = (my_main_ptr) cinfo->main;
   int ci, i, rgroup, iMCUheight, rows_left;
   jpeg_component_info *compptr;
   JSAMPARRAY xbuf;
@@ -286,12 +287,12 @@ set_bottom_pointers (j_decompress_ptr cinfo)
      * so we need only do it once.
      */
     if (ci == 0) {
-      main->rowgroups_avail = (JDIMENSION) ((rows_left-1) / rgroup + 1);
+      mainp->rowgroups_avail = (JDIMENSION) ((rows_left-1) / rgroup + 1);
     }
     /* Duplicate the last real sample row rgroup*2 times; this pads out the
      * last partial rowgroup and ensures at least one full rowgroup of context.
      */
-    xbuf = main->xbuffer[main->whichptr][ci];
+    xbuf = mainp->xbuffer[mainp->whichptr][ci];
     for (i = 0; i < rgroup * 2; i++) {
       xbuf[rows_left + i] = xbuf[rows_left-1];
     }
@@ -306,27 +307,27 @@ set_bottom_pointers (j_decompress_ptr cinfo)
 METHODDEF(void)
 start_pass_main (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
 {
-  my_main_ptr main = (my_main_ptr) cinfo->main;
+  my_main_ptr mainp = (my_main_ptr) cinfo->main;
 
   switch (pass_mode) {
   case JBUF_PASS_THRU:
     if (cinfo->upsample->need_context_rows) {
-      main->pub.process_data = process_data_context_main;
+      mainp->pub.process_data = process_data_context_main;
       make_funny_pointers(cinfo); /* Create the xbuffer[] lists */
-      main->whichptr = 0;	/* Read first iMCU row into xbuffer[0] */
-      main->context_state = CTX_PREPARE_FOR_IMCU;
-      main->iMCU_row_ctr = 0;
+      mainp->whichptr = 0;	/* Read first iMCU row into xbuffer[0] */
+      mainp->context_state = CTX_PREPARE_FOR_IMCU;
+      mainp->iMCU_row_ctr = 0;
     } else {
       /* Simple case with no context needed */
-      main->pub.process_data = process_data_simple_main;
+      mainp->pub.process_data = process_data_simple_main;
     }
-    main->buffer_full = FALSE;	/* Mark buffer empty */
-    main->rowgroup_ctr = 0;
+    mainp->buffer_full = FALSE;	/* Mark buffer empty */
+    mainp->rowgroup_ctr = 0;
     break;
 #ifdef QUANT_2PASS_SUPPORTED
   case JBUF_CRANK_DEST:
     /* For last pass of 2-pass quantization, just crank the postprocessor */
-    main->pub.process_data = process_data_crank_post;
+    mainp->pub.process_data = process_data_crank_post;
     break;
 #endif
   default:
@@ -346,14 +347,14 @@ process_data_simple_main (j_decompress_ptr cinfo,
 			  JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
 			  JDIMENSION out_rows_avail)
 {
-  my_main_ptr main = (my_main_ptr) cinfo->main;
+  my_main_ptr mainp = (my_main_ptr) cinfo->main;
   JDIMENSION rowgroups_avail;
 
   /* Read input data if we haven't filled the main buffer yet */
-  if (! main->buffer_full) {
-    if (! (*cinfo->coef->decompress_data) (cinfo, main->buffer))
+  if (! mainp->buffer_full) {
+    if (! (*cinfo->coef->decompress_data) (cinfo, mainp->buffer))
       return;			/* suspension forced, can do nothing more */
-    main->buffer_full = TRUE;	/* OK, we have an iMCU row to work with */
+    mainp->buffer_full = TRUE;	/* OK, we have an iMCU row to work with */
   }
 
   /* There are always min_DCT_scaled_size row groups in an iMCU row. */
@@ -364,14 +365,14 @@ process_data_simple_main (j_decompress_ptr cinfo,
    */
 
   /* Feed the postprocessor */
-  (*cinfo->post->post_process_data) (cinfo, main->buffer,
-				     &main->rowgroup_ctr, rowgroups_avail,
+  (*cinfo->post->post_process_data) (cinfo, mainp->buffer,
+				     &mainp->rowgroup_ctr, rowgroups_avail,
 				     output_buf, out_row_ctr, out_rows_avail);
 
   /* Has postprocessor consumed all the data yet? If so, mark buffer empty */
-  if (main->rowgroup_ctr >= rowgroups_avail) {
-    main->buffer_full = FALSE;
-    main->rowgroup_ctr = 0;
+  if (mainp->rowgroup_ctr >= rowgroups_avail) {
+    mainp->buffer_full = FALSE;
+    mainp->rowgroup_ctr = 0;
   }
 }
 
@@ -386,15 +387,15 @@ process_data_context_main (j_decompress_ptr cinfo,
 			   JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
 			   JDIMENSION out_rows_avail)
 {
-  my_main_ptr main = (my_main_ptr) cinfo->main;
+  my_main_ptr mainp = (my_main_ptr) cinfo->main;
 
   /* Read input data if we haven't filled the main buffer yet */
-  if (! main->buffer_full) {
+  if (! mainp->buffer_full) {
     if (! (*cinfo->coef->decompress_data) (cinfo,
-					   main->xbuffer[main->whichptr]))
+					   mainp->xbuffer[mainp->whichptr]))
       return;			/* suspension forced, can do nothing more */
-    main->buffer_full = TRUE;	/* OK, we have an iMCU row to work with */
-    main->iMCU_row_ctr++;	/* count rows received */
+    mainp->buffer_full = TRUE;	/* OK, we have an iMCU row to work with */
+    mainp->iMCU_row_ctr++;	/* count rows received */
   }
 
   /* Postprocessor typically will not swallow all the input data it is handed
@@ -402,47 +403,47 @@ process_data_context_main (j_decompress_ptr cinfo,
    * to exit and restart.  This switch lets us keep track of how far we got.
    * Note that each case falls through to the next on successful completion.
    */
-  switch (main->context_state) {
+  switch (mainp->context_state) {
   case CTX_POSTPONED_ROW:
     /* Call postprocessor using previously set pointers for postponed row */
-    (*cinfo->post->post_process_data) (cinfo, main->xbuffer[main->whichptr],
-			&main->rowgroup_ctr, main->rowgroups_avail,
+    (*cinfo->post->post_process_data) (cinfo, mainp->xbuffer[mainp->whichptr],
+			&mainp->rowgroup_ctr, mainp->rowgroups_avail,
 			output_buf, out_row_ctr, out_rows_avail);
-    if (main->rowgroup_ctr < main->rowgroups_avail)
+    if (mainp->rowgroup_ctr < mainp->rowgroups_avail)
       return;			/* Need to suspend */
-    main->context_state = CTX_PREPARE_FOR_IMCU;
+    mainp->context_state = CTX_PREPARE_FOR_IMCU;
     if (*out_row_ctr >= out_rows_avail)
       return;			/* Postprocessor exactly filled output buf */
     /*FALLTHROUGH*/
   case CTX_PREPARE_FOR_IMCU:
     /* Prepare to process first M-1 row groups of this iMCU row */
-    main->rowgroup_ctr = 0;
-    main->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_v_scaled_size - 1);
+    mainp->rowgroup_ctr = 0;
+    mainp->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_v_scaled_size - 1);
     /* Check for bottom of image: if so, tweak pointers to "duplicate"
      * the last sample row, and adjust rowgroups_avail to ignore padding rows.
      */
-    if (main->iMCU_row_ctr == cinfo->total_iMCU_rows)
+    if (mainp->iMCU_row_ctr == cinfo->total_iMCU_rows)
       set_bottom_pointers(cinfo);
-    main->context_state = CTX_PROCESS_IMCU;
+    mainp->context_state = CTX_PROCESS_IMCU;
     /*FALLTHROUGH*/
   case CTX_PROCESS_IMCU:
     /* Call postprocessor using previously set pointers */
-    (*cinfo->post->post_process_data) (cinfo, main->xbuffer[main->whichptr],
-			&main->rowgroup_ctr, main->rowgroups_avail,
+    (*cinfo->post->post_process_data) (cinfo, mainp->xbuffer[mainp->whichptr],
+			&mainp->rowgroup_ctr, mainp->rowgroups_avail,
 			output_buf, out_row_ctr, out_rows_avail);
-    if (main->rowgroup_ctr < main->rowgroups_avail)
+    if (mainp->rowgroup_ctr < mainp->rowgroups_avail)
       return;			/* Need to suspend */
     /* After the first iMCU, change wraparound pointers to normal state */
-    if (main->iMCU_row_ctr == 1)
+    if (mainp->iMCU_row_ctr == 1)
       set_wraparound_pointers(cinfo);
     /* Prepare to load new iMCU row using other xbuffer list */
-    main->whichptr ^= 1;	/* 0=>1 or 1=>0 */
-    main->buffer_full = FALSE;
+    mainp->whichptr ^= 1;	/* 0=>1 or 1=>0 */
+    mainp->buffer_full = FALSE;
     /* Still need to process last row group of this iMCU row, */
     /* which is saved at index M+1 of the other xbuffer */
-    main->rowgroup_ctr = (JDIMENSION) (cinfo->min_DCT_v_scaled_size + 1);
-    main->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_v_scaled_size + 2);
-    main->context_state = CTX_POSTPONED_ROW;
+    mainp->rowgroup_ctr = (JDIMENSION) (cinfo->min_DCT_v_scaled_size + 1);
+    mainp->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_v_scaled_size + 2);
+    mainp->context_state = CTX_POSTPONED_ROW;
   }
 }
 
@@ -475,15 +476,15 @@ process_data_crank_post (j_decompress_ptr cinfo,
 GLOBAL(void)
 jinit_d_main_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
 {
-  my_main_ptr main;
+  my_main_ptr mainp;
   int ci, rgroup, ngroups;
   jpeg_component_info *compptr;
 
-  main = (my_main_ptr)
+  mainp = (my_main_ptr)
     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 				SIZEOF(my_main_controller));
-  cinfo->main = (struct jpeg_d_main_controller *) main;
-  main->pub.start_pass = start_pass_main;
+  cinfo->main = &mainp->pub;
+  mainp->pub.start_pass = start_pass_main;
 
   if (need_full_buffer)		/* shouldn't happen */
     ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
@@ -504,9 +505,9 @@ jinit_d_main_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
        ci++, compptr++) {
     rgroup = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) /
       cinfo->min_DCT_v_scaled_size; /* height of a row group of component */
-    main->buffer[ci] = (*cinfo->mem->alloc_sarray)
-			((j_common_ptr) cinfo, JPOOL_IMAGE,
-			 compptr->width_in_blocks * compptr->DCT_h_scaled_size,
-			 (JDIMENSION) (rgroup * ngroups));
+    mainp->buffer[ci] = (*cinfo->mem->alloc_sarray)
+      ((j_common_ptr) cinfo, JPOOL_IMAGE,
+       compptr->width_in_blocks * ((JDIMENSION) compptr->DCT_h_scaled_size),
+       (JDIMENSION) (rgroup * ngroups));
   }
 }
diff --git a/Source/LibJPEG/jdmarker.c b/Source/LibJPEG/jdmarker.c
index f2a9cc4..3fbe5c1 100644
--- a/Source/LibJPEG/jdmarker.c
+++ b/Source/LibJPEG/jdmarker.c
@@ -2,7 +2,7 @@
  * jdmarker.c
  *
  * Copyright (C) 1991-1998, Thomas G. Lane.
- * Modified 2009 by Guido Vollbeding.
+ * Modified 2009-2013 by Guido Vollbeding.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
@@ -23,24 +23,24 @@ typedef enum {			/* JPEG marker codes */
   M_SOF1  = 0xc1,
   M_SOF2  = 0xc2,
   M_SOF3  = 0xc3,
-  
+
   M_SOF5  = 0xc5,
   M_SOF6  = 0xc6,
   M_SOF7  = 0xc7,
-  
+
   M_JPG   = 0xc8,
   M_SOF9  = 0xc9,
   M_SOF10 = 0xca,
   M_SOF11 = 0xcb,
-  
+
   M_SOF13 = 0xcd,
   M_SOF14 = 0xce,
   M_SOF15 = 0xcf,
-  
+
   M_DHT   = 0xc4,
-  
+
   M_DAC   = 0xcc,
-  
+
   M_RST0  = 0xd0,
   M_RST1  = 0xd1,
   M_RST2  = 0xd2,
@@ -49,7 +49,7 @@ typedef enum {			/* JPEG marker codes */
   M_RST5  = 0xd5,
   M_RST6  = 0xd6,
   M_RST7  = 0xd7,
-  
+
   M_SOI   = 0xd8,
   M_EOI   = 0xd9,
   M_SOS   = 0xda,
@@ -58,7 +58,7 @@ typedef enum {			/* JPEG marker codes */
   M_DRI   = 0xdd,
   M_DHP   = 0xde,
   M_EXP   = 0xdf,
-  
+
   M_APP0  = 0xe0,
   M_APP1  = 0xe1,
   M_APP2  = 0xe2,
@@ -75,13 +75,14 @@ typedef enum {			/* JPEG marker codes */
   M_APP13 = 0xed,
   M_APP14 = 0xee,
   M_APP15 = 0xef,
-  
+
   M_JPG0  = 0xf0,
+  M_JPG8  = 0xf8,
   M_JPG13 = 0xfd,
   M_COM   = 0xfe,
-  
+
   M_TEM   = 0x01,
-  
+
   M_ERROR = 0x100
 } JPEG_MARKER;
 
@@ -217,6 +218,7 @@ get_soi (j_decompress_ptr cinfo)
   /* Set initial assumptions for colorspace etc */
 
   cinfo->jpeg_color_space = JCS_UNKNOWN;
+  cinfo->color_transform = JCT_NONE;
   cinfo->CCIR601_sampling = FALSE; /* Assume non-CCIR sampling??? */
 
   cinfo->saw_JFIF_marker = FALSE;
@@ -240,7 +242,7 @@ get_sof (j_decompress_ptr cinfo, boolean is_baseline, boolean is_prog,
 /* Process a SOFn marker */
 {
   INT32 length;
-  int c, ci;
+  int c, ci, i;
   jpeg_component_info * compptr;
   INPUT_VARS(cinfo);
 
@@ -267,8 +269,8 @@ get_sof (j_decompress_ptr cinfo, boolean is_baseline, boolean is_prog,
   /* We don't support files in which the image height is initially specified */
   /* as 0 and is later redefined by DNL.  As long as we have to check that,  */
   /* might as well have a general sanity check. */
-  if (cinfo->image_height <= 0 || cinfo->image_width <= 0
-      || cinfo->num_components <= 0)
+  if (cinfo->image_height <= 0 || cinfo->image_width <= 0 ||
+      cinfo->num_components <= 0)
     ERREXIT(cinfo, JERR_EMPTY_IMAGE);
 
   if (length != (cinfo->num_components * 3))
@@ -278,11 +280,27 @@ get_sof (j_decompress_ptr cinfo, boolean is_baseline, boolean is_prog,
     cinfo->comp_info = (jpeg_component_info *) (*cinfo->mem->alloc_small)
 			((j_common_ptr) cinfo, JPOOL_IMAGE,
 			 cinfo->num_components * SIZEOF(jpeg_component_info));
-  
-  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
-       ci++, compptr++) {
+
+  for (ci = 0; ci < cinfo->num_components; ci++) {
+    INPUT_BYTE(cinfo, c, return FALSE);
+    /* Check to see whether component id has already been seen   */
+    /* (in violation of the spec, but unfortunately seen in some */
+    /* files).  If so, create "fake" component id equal to the   */
+    /* max id seen so far + 1. */
+    for (i = 0, compptr = cinfo->comp_info; i < ci; i++, compptr++) {
+      if (c == compptr->component_id) {
+	compptr = cinfo->comp_info;
+	c = compptr->component_id;
+	compptr++;
+	for (i = 1; i < ci; i++, compptr++) {
+	  if (compptr->component_id > c) c = compptr->component_id;
+	}
+	c++;
+	break;
+      }
+    }
+    compptr->component_id = c;
     compptr->component_index = ci;
-    INPUT_BYTE(cinfo, compptr->component_id, return FALSE);
     INPUT_BYTE(cinfo, c, return FALSE);
     compptr->h_samp_factor = (c >> 4) & 15;
     compptr->v_samp_factor = (c     ) & 15;
@@ -305,12 +323,12 @@ get_sos (j_decompress_ptr cinfo)
 /* Process a SOS marker */
 {
   INT32 length;
-  int i, ci, n, c, cc;
+  int c, ci, i, n;
   jpeg_component_info * compptr;
   INPUT_VARS(cinfo);
 
   if (! cinfo->marker->saw_SOF)
-    ERREXIT(cinfo, JERR_SOS_NO_SOF);
+    ERREXITS(cinfo, JERR_SOF_BEFORE, "SOS");
 
   INPUT_2BYTES(cinfo, length, return FALSE);
 
@@ -328,24 +346,41 @@ get_sos (j_decompress_ptr cinfo)
   /* Collect the component-spec parameters */
 
   for (i = 0; i < n; i++) {
-    INPUT_BYTE(cinfo, cc, return FALSE);
     INPUT_BYTE(cinfo, c, return FALSE);
-    
+
+    /* Detect the case where component id's are not unique, and, if so, */
+    /* create a fake component id using the same logic as in get_sof.   */
+    /* Note:  This also ensures that all of the SOF components are      */
+    /* referenced in the single scan case, which prevents access to     */
+    /* uninitialized memory in later decoding stages. */
+    for (ci = 0; ci < i; ci++) {
+      if (c == cinfo->cur_comp_info[ci]->component_id) {
+	c = cinfo->cur_comp_info[0]->component_id;
+	for (ci = 1; ci < i; ci++) {
+	  compptr = cinfo->cur_comp_info[ci];
+	  if (compptr->component_id > c) c = compptr->component_id;
+	}
+	c++;
+	break;
+      }
+    }
+
     for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 	 ci++, compptr++) {
-      if (cc == compptr->component_id)
+      if (c == compptr->component_id)
 	goto id_found;
     }
 
-    ERREXIT1(cinfo, JERR_BAD_COMPONENT_ID, cc);
+    ERREXIT1(cinfo, JERR_BAD_COMPONENT_ID, c);
 
   id_found:
 
     cinfo->cur_comp_info[i] = compptr;
+    INPUT_BYTE(cinfo, c, return FALSE);
     compptr->dc_tbl_no = (c >> 4) & 15;
     compptr->ac_tbl_no = (c     ) & 15;
-    
-    TRACEMS3(cinfo, 1, JTRC_SOS_COMPONENT, cc,
+
+    TRACEMS3(cinfo, 1, JTRC_SOS_COMPONENT, compptr->component_id,
 	     compptr->dc_tbl_no, compptr->ac_tbl_no);
   }
 
@@ -461,6 +496,8 @@ get_dht (j_decompress_ptr cinfo)
     if (count > 256 || ((INT32) count) > length)
       ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
 
+    MEMZERO(huffval, SIZEOF(huffval)); /* pre-zero array for later copy */
+
     for (i = 0; i < count; i++)
       INPUT_BYTE(cinfo, huffval[i], return FALSE);
 
@@ -605,6 +642,68 @@ get_dri (j_decompress_ptr cinfo)
 }
 
 
+LOCAL(boolean)
+get_lse (j_decompress_ptr cinfo)
+/* Process an LSE marker */
+{
+  INT32 length;
+  unsigned int tmp;
+  int cid;
+  INPUT_VARS(cinfo);
+
+  if (! cinfo->marker->saw_SOF)
+    ERREXITS(cinfo, JERR_SOF_BEFORE, "LSE");
+
+  if (cinfo->num_components < 3) goto bad;
+
+  INPUT_2BYTES(cinfo, length, return FALSE);
+
+  if (length != 24)
+    ERREXIT(cinfo, JERR_BAD_LENGTH);
+
+  INPUT_BYTE(cinfo, tmp, return FALSE);
+  if (tmp != 0x0D)	/* ID inverse transform specification */
+    ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker);
+  INPUT_2BYTES(cinfo, tmp, return FALSE);
+  if (tmp != MAXJSAMPLE) goto bad;		/* MAXTRANS */
+  INPUT_BYTE(cinfo, tmp, return FALSE);
+  if (tmp != 3) goto bad;			/* Nt=3 */
+  INPUT_BYTE(cinfo, cid, return FALSE);
+  if (cid != cinfo->comp_info[1].component_id) goto bad;
+  INPUT_BYTE(cinfo, cid, return FALSE);
+  if (cid != cinfo->comp_info[0].component_id) goto bad;
+  INPUT_BYTE(cinfo, cid, return FALSE);
+  if (cid != cinfo->comp_info[2].component_id) goto bad;
+  INPUT_BYTE(cinfo, tmp, return FALSE);
+  if (tmp != 0x80) goto bad;		/* F1: CENTER1=1, NORM1=0 */
+  INPUT_2BYTES(cinfo, tmp, return FALSE);
+  if (tmp != 0) goto bad;			/* A(1,1)=0 */
+  INPUT_2BYTES(cinfo, tmp, return FALSE);
+  if (tmp != 0) goto bad;			/* A(1,2)=0 */
+  INPUT_BYTE(cinfo, tmp, return FALSE);
+  if (tmp != 0) goto bad;		/* F2: CENTER2=0, NORM2=0 */
+  INPUT_2BYTES(cinfo, tmp, return FALSE);
+  if (tmp != 1) goto bad;			/* A(2,1)=1 */
+  INPUT_2BYTES(cinfo, tmp, return FALSE);
+  if (tmp != 0) goto bad;			/* A(2,2)=0 */
+  INPUT_BYTE(cinfo, tmp, return FALSE);
+  if (tmp != 0) goto bad;		/* F3: CENTER3=0, NORM3=0 */
+  INPUT_2BYTES(cinfo, tmp, return FALSE);
+  if (tmp != 1) goto bad;			/* A(3,1)=1 */
+  INPUT_2BYTES(cinfo, tmp, return FALSE);
+  if (tmp != 0) {				/* A(3,2)=0 */
+    bad:
+    ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+  }
+
+  /* OK, valid transform that we can handle. */
+  cinfo->color_transform = JCT_SUBTRACT_GREEN;
+
+  INPUT_SYNC(cinfo);
+  return TRUE;
+}
+
+
 /*
  * Routines for processing APPn and COM markers.
  * These are either saved in memory or discarded, per application request.
@@ -641,12 +740,13 @@ examine_app0 (j_decompress_ptr cinfo, JOCTET FAR * data,
     cinfo->X_density = (GETJOCTET(data[8]) << 8) + GETJOCTET(data[9]);
     cinfo->Y_density = (GETJOCTET(data[10]) << 8) + GETJOCTET(data[11]);
     /* Check version.
-     * Major version must be 1, anything else signals an incompatible change.
+     * Major version must be 1 or 2, anything else signals an incompatible
+     * change.
      * (We used to treat this as an error, but now it's a nonfatal warning,
      * because some bozo at Hijaak couldn't read the spec.)
      * Minor version should be 0..2, but process anyway if newer.
      */
-    if (cinfo->JFIF_major_version != 1)
+    if (cinfo->JFIF_major_version != 1 && cinfo->JFIF_major_version != 2)
       WARNMS2(cinfo, JWRN_JFIF_MAJOR,
 	      cinfo->JFIF_major_version, cinfo->JFIF_minor_version);
     /* Generate trace messages */
@@ -1059,32 +1159,37 @@ read_markers (j_decompress_ptr cinfo)
 	return JPEG_SUSPENDED;
       cinfo->unread_marker = 0;	/* processed the marker */
       return JPEG_REACHED_SOS;
-    
+
     case M_EOI:
       TRACEMS(cinfo, 1, JTRC_EOI);
       cinfo->unread_marker = 0;	/* processed the marker */
       return JPEG_REACHED_EOI;
-      
+
     case M_DAC:
       if (! get_dac(cinfo))
 	return JPEG_SUSPENDED;
       break;
-      
+
     case M_DHT:
       if (! get_dht(cinfo))
 	return JPEG_SUSPENDED;
       break;
-      
+
     case M_DQT:
       if (! get_dqt(cinfo))
 	return JPEG_SUSPENDED;
       break;
-      
+
     case M_DRI:
       if (! get_dri(cinfo))
 	return JPEG_SUSPENDED;
       break;
-      
+
+    case M_JPG8:
+      if (! get_lse(cinfo))
+	return JPEG_SUSPENDED;
+      break;
+
     case M_APP0:
     case M_APP1:
     case M_APP2:
@@ -1105,7 +1210,7 @@ read_markers (j_decompress_ptr cinfo)
 		cinfo->unread_marker - (int) M_APP0]) (cinfo))
 	return JPEG_SUSPENDED;
       break;
-      
+
     case M_COM:
       if (! (*((my_marker_ptr) cinfo->marker)->process_COM) (cinfo))
 	return JPEG_SUSPENDED;
@@ -1314,7 +1419,7 @@ jinit_marker_reader (j_decompress_ptr cinfo)
   marker = (my_marker_ptr)
     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
 				SIZEOF(my_marker_reader));
-  cinfo->marker = (struct jpeg_marker_reader *) marker;
+  cinfo->marker = &marker->pub;
   /* Initialize public method pointers */
   marker->pub.reset_marker_reader = reset_marker_reader;
   marker->pub.read_markers = read_markers;
diff --git a/Source/LibJPEG/jdmaster.c b/Source/LibJPEG/jdmaster.c
index fef72a2..6f42d3c 100644
--- a/Source/LibJPEG/jdmaster.c
+++ b/Source/LibJPEG/jdmaster.c
@@ -2,7 +2,7 @@
  * jdmaster.c
  *
  * Copyright (C) 1991-1997, Thomas G. Lane.
- * Modified 2002-2011 by Guido Vollbeding.
+ * Modified 2002-2013 by Guido Vollbeding.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
@@ -51,7 +51,8 @@ use_merged_upsample (j_decompress_ptr cinfo)
   /* jdmerge.c only supports YCC=>RGB color conversion */
   if (cinfo->jpeg_color_space != JCS_YCbCr || cinfo->num_components != 3 ||
       cinfo->out_color_space != JCS_RGB ||
-      cinfo->out_color_components != RGB_PIXELSIZE)
+      cinfo->out_color_components != RGB_PIXELSIZE ||
+      cinfo->color_transform)
     return FALSE;
   /* and it only handles 2h1v or 2h2v sampling ratios */
   if (cinfo->comp_info[0].h_samp_factor != 2 ||
@@ -158,9 +159,11 @@ jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
     cinfo->out_color_components = 1;
     break;
   case JCS_RGB:
+  case JCS_BG_RGB:
     cinfo->out_color_components = RGB_PIXELSIZE;
     break;
   case JCS_YCbCr:
+  case JCS_BG_YCC:
     cinfo->out_color_components = 3;
     break;
   case JCS_CMYK:
@@ -273,10 +276,19 @@ master_selection (j_decompress_ptr cinfo)
   long samplesperrow;
   JDIMENSION jd_samplesperrow;
 
+  /* For now, precision must match compiled-in value... */
+  if (cinfo->data_precision != BITS_IN_JSAMPLE)
+    ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
+
   /* Initialize dimensions and other stuff */
   jpeg_calc_output_dimensions(cinfo);
   prepare_range_limit_table(cinfo);
 
+  /* Sanity check on image dimensions */
+  if (cinfo->output_height <= 0 || cinfo->output_width <= 0 ||
+      cinfo->out_color_components <= 0)
+    ERREXIT(cinfo, JERR_EMPTY_IMAGE);
+
   /* Width of an output scanline must be representable as JDIMENSION. */
   samplesperrow = (long) cinfo->output_width * (long) cinfo->out_color_components;
   jd_samplesperrow = (JDIMENSION) samplesperrow;
@@ -521,7 +533,7 @@ jinit_master_decompress (j_decompress_ptr cinfo)
   master = (my_master_ptr)
       (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 				  SIZEOF(my_decomp_master));
-  cinfo->master = (struct jpeg_decomp_master *) master;
+  cinfo->master = &master->pub;
   master->pub.prepare_for_output_pass = prepare_for_output_pass;
   master->pub.finish_output_pass = finish_output_pass;
 
diff --git a/Source/LibJPEG/jdmerge.c b/Source/LibJPEG/jdmerge.c
index 3744446..a6bde33 100644
--- a/Source/LibJPEG/jdmerge.c
+++ b/Source/LibJPEG/jdmerge.c
@@ -2,6 +2,7 @@
  * jdmerge.c
  *
  * Copyright (C) 1994-1996, Thomas G. Lane.
+ * Modified 2013 by Guido Vollbeding.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
@@ -103,17 +104,17 @@ build_ycc_rgb_table (j_decompress_ptr cinfo)
   for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
     /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
     /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
-    /* Cr=>R value is nearest int to 1.40200 * x */
+    /* Cr=>R value is nearest int to 1.402 * x */
     upsample->Cr_r_tab[i] = (int)
-		    RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
-    /* Cb=>B value is nearest int to 1.77200 * x */
+		    RIGHT_SHIFT(FIX(1.402) * x + ONE_HALF, SCALEBITS);
+    /* Cb=>B value is nearest int to 1.772 * x */
     upsample->Cb_b_tab[i] = (int)
-		    RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
-    /* Cr=>G value is scaled-up -0.71414 * x */
-    upsample->Cr_g_tab[i] = (- FIX(0.71414)) * x;
-    /* Cb=>G value is scaled-up -0.34414 * x */
+		    RIGHT_SHIFT(FIX(1.772) * x + ONE_HALF, SCALEBITS);
+    /* Cr=>G value is scaled-up -0.714136286 * x */
+    upsample->Cr_g_tab[i] = (- FIX(0.714136286)) * x;
+    /* Cb=>G value is scaled-up -0.344136286 * x */
     /* We also add in ONE_HALF so that need not do it in inner loop */
-    upsample->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
+    upsample->Cb_g_tab[i] = (- FIX(0.344136286)) * x + ONE_HALF;
   }
 }
 
diff --git a/Source/LibJPEG/jerror.c b/Source/LibJPEG/jerror.c
index 3da7be8..8c0b9e0 100644
--- a/Source/LibJPEG/jerror.c
+++ b/Source/LibJPEG/jerror.c
@@ -2,6 +2,7 @@
  * jerror.c
  *
  * Copyright (C) 1991-1998, Thomas G. Lane.
+ * Modified 2012 by Guido Vollbeding.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
@@ -66,7 +67,7 @@ const char * const jpeg_std_message_table[] = {
  * or jpeg_destroy) at some point.
  */
 
-METHODDEF(void)
+METHODDEF(noreturn_t)
 error_exit (j_common_ptr cinfo)
 {
   /* Always display the message */
diff --git a/Source/LibJPEG/jerror.h b/Source/LibJPEG/jerror.h
index 1cfb2b1..a4b661f 100644
--- a/Source/LibJPEG/jerror.h
+++ b/Source/LibJPEG/jerror.h
@@ -2,7 +2,7 @@
  * jerror.h
  *
  * Copyright (C) 1994-1997, Thomas G. Lane.
- * Modified 1997-2009 by Guido Vollbeding.
+ * Modified 1997-2012 by Guido Vollbeding.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
@@ -106,11 +106,11 @@ JMESSAGE(JERR_QUANT_COMPONENTS,
 	 "Cannot quantize more than %d color components")
 JMESSAGE(JERR_QUANT_FEW_COLORS, "Cannot quantize to fewer than %d colors")
 JMESSAGE(JERR_QUANT_MANY_COLORS, "Cannot quantize to more than %d colors")
+JMESSAGE(JERR_SOF_BEFORE, "Invalid JPEG file structure: %s before SOF")
 JMESSAGE(JERR_SOF_DUPLICATE, "Invalid JPEG file structure: two SOF markers")
 JMESSAGE(JERR_SOF_NO_SOS, "Invalid JPEG file structure: missing SOS marker")
 JMESSAGE(JERR_SOF_UNSUPPORTED, "Unsupported JPEG process: SOF type 0x%02x")
 JMESSAGE(JERR_SOI_DUPLICATE, "Invalid JPEG file structure: two SOI markers")
-JMESSAGE(JERR_SOS_NO_SOF, "Invalid JPEG file structure: SOS before SOF")
 JMESSAGE(JERR_TFILE_CREATE, "Failed to create temporary file %s")
 JMESSAGE(JERR_TFILE_READ, "Read failed on temporary file")
 JMESSAGE(JERR_TFILE_SEEK, "Seek failed on temporary file")
diff --git a/Source/LibJPEG/jfdctint.c b/Source/LibJPEG/jfdctint.c
index 1dde58c..a2ef203 100644
--- a/Source/LibJPEG/jfdctint.c
+++ b/Source/LibJPEG/jfdctint.c
@@ -2,7 +2,7 @@
  * jfdctint.c
  *
  * Copyright (C) 1991-1996, Thomas G. Lane.
- * Modification developed 2003-2009 by Guido Vollbeding.
+ * Modification developed 2003-2013 by Guido Vollbeding.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
@@ -165,16 +165,18 @@ jpeg_fdct_islow (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
   int ctr;
   SHIFT_TEMPS
 
-  /* Pass 1: process rows. */
-  /* Note results are scaled up by sqrt(8) compared to a true DCT; */
-  /* furthermore, we scale the results by 2**PASS1_BITS. */
+  /* Pass 1: process rows.
+   * Note results are scaled up by sqrt(8) compared to a true DCT;
+   * furthermore, we scale the results by 2**PASS1_BITS.
+   * cK represents sqrt(2) * cos(K*pi/16).
+   */
 
   dataptr = data;
   for (ctr = 0; ctr < DCTSIZE; ctr++) {
     elemptr = sample_data[ctr] + start_col;
 
     /* Even part per LL&M figure 1 --- note that published figure is faulty;
-     * rotator "sqrt(2)*c1" should be "sqrt(2)*c6".
+     * rotator "c1" should be "c6".
      */
 
     tmp0 = GETJSAMPLE(elemptr[0]) + GETJSAMPLE(elemptr[7]);
@@ -196,47 +198,49 @@ jpeg_fdct_islow (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
     dataptr[0] = (DCTELEM) ((tmp10 + tmp11 - 8 * CENTERJSAMPLE) << PASS1_BITS);
     dataptr[4] = (DCTELEM) ((tmp10 - tmp11) << PASS1_BITS);
 
-    z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100);
+    z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100);       /* c6 */
     /* Add fudge factor here for final descale. */
     z1 += ONE << (CONST_BITS-PASS1_BITS-1);
-    dataptr[2] = (DCTELEM) RIGHT_SHIFT(z1 + MULTIPLY(tmp12, FIX_0_765366865),
-				       CONST_BITS-PASS1_BITS);
-    dataptr[6] = (DCTELEM) RIGHT_SHIFT(z1 - MULTIPLY(tmp13, FIX_1_847759065),
-				       CONST_BITS-PASS1_BITS);
+
+    dataptr[2] = (DCTELEM)
+      RIGHT_SHIFT(z1 + MULTIPLY(tmp12, FIX_0_765366865), /* c2-c6 */
+		  CONST_BITS-PASS1_BITS);
+    dataptr[6] = (DCTELEM)
+      RIGHT_SHIFT(z1 - MULTIPLY(tmp13, FIX_1_847759065), /* c2+c6 */
+		  CONST_BITS-PASS1_BITS);
 
     /* Odd part per figure 8 --- note paper omits factor of sqrt(2).
-     * cK represents sqrt(2) * cos(K*pi/16).
      * i0..i3 in the paper are tmp0..tmp3 here.
      */
 
-    tmp10 = tmp0 + tmp3;
-    tmp11 = tmp1 + tmp2;
     tmp12 = tmp0 + tmp2;
     tmp13 = tmp1 + tmp3;
-    z1 = MULTIPLY(tmp12 + tmp13, FIX_1_175875602); /*  c3 */
+
+    z1 = MULTIPLY(tmp12 + tmp13, FIX_1_175875602);       /*  c3 */
     /* Add fudge factor here for final descale. */
     z1 += ONE << (CONST_BITS-PASS1_BITS-1);
 
-    tmp0  = MULTIPLY(tmp0,    FIX_1_501321110);    /*  c1+c3-c5-c7 */
-    tmp1  = MULTIPLY(tmp1,    FIX_3_072711026);    /*  c1+c3+c5-c7 */
-    tmp2  = MULTIPLY(tmp2,    FIX_2_053119869);    /*  c1+c3-c5+c7 */
-    tmp3  = MULTIPLY(tmp3,    FIX_0_298631336);    /* -c1+c3+c5-c7 */
-    tmp10 = MULTIPLY(tmp10, - FIX_0_899976223);    /*  c7-c3 */
-    tmp11 = MULTIPLY(tmp11, - FIX_2_562915447);    /* -c1-c3 */
-    tmp12 = MULTIPLY(tmp12, - FIX_0_390180644);    /*  c5-c3 */
-    tmp13 = MULTIPLY(tmp13, - FIX_1_961570560);    /* -c3-c5 */
-
+    tmp12 = MULTIPLY(tmp12, - FIX_0_390180644);          /* -c3+c5 */
+    tmp13 = MULTIPLY(tmp13, - FIX_1_961570560);          /* -c3-c5 */
     tmp12 += z1;
     tmp13 += z1;
 
-    dataptr[1] = (DCTELEM)
-      RIGHT_SHIFT(tmp0 + tmp10 + tmp12, CONST_BITS-PASS1_BITS);
-    dataptr[3] = (DCTELEM)
-      RIGHT_SHIFT(tmp1 + tmp11 + tmp13, CONST_BITS-PASS1_BITS);
-    dataptr[5] = (DCTELEM)
-      RIGHT_SHIFT(tmp2 + tmp11 + tmp12, CONST_BITS-PASS1_BITS);
-    dataptr[7] = (DCTELEM)
-      RIGHT_SHIFT(tmp3 + tmp10 + tmp13, CONST_BITS-PASS1_BITS);
+    z1 = MULTIPLY(tmp0 + tmp3, - FIX_0_899976223);       /* -c3+c7 */
+    tmp0 = MULTIPLY(tmp0, FIX_1_501321110);              /*  c1+c3-c5-c7 */
+    tmp3 = MULTIPLY(tmp3, FIX_0_298631336);              /* -c1+c3+c5-c7 */
+    tmp0 += z1 + tmp12;
+    tmp3 += z1 + tmp13;
+
+    z1 = MULTIPLY(tmp1 + tmp2, - FIX_2_562915447);       /* -c1-c3 */
+    tmp1 = MULTIPLY(tmp1, FIX_3_072711026);              /*  c1+c3+c5-c7 */
+    tmp2 = MULTIPLY(tmp2, FIX_2_053119869);              /*  c1+c3-c5+c7 */
+    tmp1 += z1 + tmp13;
+    tmp2 += z1 + tmp12;
+
+    dataptr[1] = (DCTELEM) RIGHT_SHIFT(tmp0, CONST_BITS-PASS1_BITS);
+    dataptr[3] = (DCTELEM) RIGHT_SHIFT(tmp1, CONST_BITS-PASS1_BITS);
+    dataptr[5] = (DCTELEM) RIGHT_SHIFT(tmp2, CONST_BITS-PASS1_BITS);
+    dataptr[7] = (DCTELEM) RIGHT_SHIFT(tmp3, CONST_BITS-PASS1_BITS);
 
     dataptr += DCTSIZE;		/* advance pointer to next row */
   }
@@ -244,12 +248,13 @@ jpeg_fdct_islow (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
   /* Pass 2: process columns.
    * We remove the PASS1_BITS scaling, but leave the results scaled up
    * by an overall factor of 8.
+   * cK represents sqrt(2) * cos(K*pi/16).
    */
 
   dataptr = data;
   for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
     /* Even part per LL&M figure 1 --- note that published figure is faulty;
-     * rotator "sqrt(2)*c1" should be "sqrt(2)*c6".
+     * rotator "c1" should be "c6".
      */
 
     tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7];
@@ -271,47 +276,49 @@ jpeg_fdct_islow (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
     dataptr[DCTSIZE*0] = (DCTELEM) RIGHT_SHIFT(tmp10 + tmp11, PASS1_BITS);
     dataptr[DCTSIZE*4] = (DCTELEM) RIGHT_SHIFT(tmp10 - tmp11, PASS1_BITS);
 
-    z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100);
+    z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100);       /* c6 */
     /* Add fudge factor here for final descale. */
     z1 += ONE << (CONST_BITS+PASS1_BITS-1);
+
     dataptr[DCTSIZE*2] = (DCTELEM)
-      RIGHT_SHIFT(z1 + MULTIPLY(tmp12, FIX_0_765366865), CONST_BITS+PASS1_BITS);
+      RIGHT_SHIFT(z1 + MULTIPLY(tmp12, FIX_0_765366865), /* c2-c6 */
+		  CONST_BITS+PASS1_BITS);
     dataptr[DCTSIZE*6] = (DCTELEM)
-      RIGHT_SHIFT(z1 - MULTIPLY(tmp13, FIX_1_847759065), CONST_BITS+PASS1_BITS);
+      RIGHT_SHIFT(z1 - MULTIPLY(tmp13, FIX_1_847759065), /* c2+c6 */
+		  CONST_BITS+PASS1_BITS);
 
     /* Odd part per figure 8 --- note paper omits factor of sqrt(2).
-     * cK represents sqrt(2) * cos(K*pi/16).
      * i0..i3 in the paper are tmp0..tmp3 here.
      */
 
-    tmp10 = tmp0 + tmp3;
-    tmp11 = tmp1 + tmp2;
     tmp12 = tmp0 + tmp2;
     tmp13 = tmp1 + tmp3;
-    z1 = MULTIPLY(tmp12 + tmp13, FIX_1_175875602); /*  c3 */
+
+    z1 = MULTIPLY(tmp12 + tmp13, FIX_1_175875602);       /*  c3 */
     /* Add fudge factor here for final descale. */
     z1 += ONE << (CONST_BITS+PASS1_BITS-1);
 
-    tmp0  = MULTIPLY(tmp0,    FIX_1_501321110);    /*  c1+c3-c5-c7 */
-    tmp1  = MULTIPLY(tmp1,    FIX_3_072711026);    /*  c1+c3+c5-c7 */
-    tmp2  = MULTIPLY(tmp2,    FIX_2_053119869);    /*  c1+c3-c5+c7 */
-    tmp3  = MULTIPLY(tmp3,    FIX_0_298631336);    /* -c1+c3+c5-c7 */
-    tmp10 = MULTIPLY(tmp10, - FIX_0_899976223);    /*  c7-c3 */
-    tmp11 = MULTIPLY(tmp11, - FIX_2_562915447);    /* -c1-c3 */
-    tmp12 = MULTIPLY(tmp12, - FIX_0_390180644);    /*  c5-c3 */
-    tmp13 = MULTIPLY(tmp13, - FIX_1_961570560);    /* -c3-c5 */
-
+    tmp12 = MULTIPLY(tmp12, - FIX_0_390180644);          /* -c3+c5 */
+    tmp13 = MULTIPLY(tmp13, - FIX_1_961570560);          /* -c3-c5 */
     tmp12 += z1;
     tmp13 += z1;
 
-    dataptr[DCTSIZE*1] = (DCTELEM)
-      RIGHT_SHIFT(tmp0 + tmp10 + tmp12, CONST_BITS+PASS1_BITS);
-    dataptr[DCTSIZE*3] = (DCTELEM)
-      RIGHT_SHIFT(tmp1 + tmp11 + tmp13, CONST_BITS+PASS1_BITS);
-    dataptr[DCTSIZE*5] = (DCTELEM)
-      RIGHT_SHIFT(tmp2 + tmp11 + tmp12, CONST_BITS+PASS1_BITS);
-    dataptr[DCTSIZE*7] = (DCTELEM)
-      RIGHT_SHIFT(tmp3 + tmp10 + tmp13, CONST_BITS+PASS1_BITS);
+    z1 = MULTIPLY(tmp0 + tmp3, - FIX_0_899976223);       /* -c3+c7 */
+    tmp0 = MULTIPLY(tmp0, FIX_1_501321110);              /*  c1+c3-c5-c7 */
+    tmp3 = MULTIPLY(tmp3, FIX_0_298631336);              /* -c1+c3+c5-c7 */
+    tmp0 += z1 + tmp12;
+    tmp3 += z1 + tmp13;
+
+    z1 = MULTIPLY(tmp1 + tmp2, - FIX_2_562915447);       /* -c1-c3 */
+    tmp1 = MULTIPLY(tmp1, FIX_3_072711026);              /*  c1+c3+c5-c7 */
+    tmp2 = MULTIPLY(tmp2, FIX_2_053119869);              /*  c1+c3-c5+c7 */
+    tmp1 += z1 + tmp13;
+    tmp2 += z1 + tmp12;
+
+    dataptr[DCTSIZE*1] = (DCTELEM) RIGHT_SHIFT(tmp0, CONST_BITS+PASS1_BITS);
+    dataptr[DCTSIZE*3] = (DCTELEM) RIGHT_SHIFT(tmp1, CONST_BITS+PASS1_BITS);
+    dataptr[DCTSIZE*5] = (DCTELEM) RIGHT_SHIFT(tmp2, CONST_BITS+PASS1_BITS);
+    dataptr[DCTSIZE*7] = (DCTELEM) RIGHT_SHIFT(tmp3, CONST_BITS+PASS1_BITS);
 
     dataptr++;			/* advance pointer to next column */
   }
@@ -338,10 +345,11 @@ jpeg_fdct_7x7 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
   /* Pre-zero output coefficient block. */
   MEMZERO(data, SIZEOF(DCTELEM) * DCTSIZE2);
 
-  /* Pass 1: process rows. */
-  /* Note results are scaled up by sqrt(8) compared to a true DCT; */
-  /* furthermore, we scale the results by 2**PASS1_BITS. */
-  /* cK represents sqrt(2) * cos(K*pi/14). */
+  /* Pass 1: process rows.
+   * Note results are scaled up by sqrt(8) compared to a true DCT;
+   * furthermore, we scale the results by 2**PASS1_BITS.
+   * cK represents sqrt(2) * cos(K*pi/14).
+   */
 
   dataptr = data;
   for (ctr = 0; ctr < 7; ctr++) {
@@ -472,10 +480,11 @@ jpeg_fdct_6x6 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
   /* Pre-zero output coefficient block. */
   MEMZERO(data, SIZEOF(DCTELEM) * DCTSIZE2);
 
-  /* Pass 1: process rows. */
-  /* Note results are scaled up by sqrt(8) compared to a true DCT; */
-  /* furthermore, we scale the results by 2**PASS1_BITS. */
-  /* cK represents sqrt(2) * cos(K*pi/12). */
+  /* Pass 1: process rows.
+   * Note results are scaled up by sqrt(8) compared to a true DCT;
+   * furthermore, we scale the results by 2**PASS1_BITS.
+   * cK represents sqrt(2) * cos(K*pi/12).
+   */
 
   dataptr = data;
   for (ctr = 0; ctr < 6; ctr++) {
@@ -585,12 +594,13 @@ jpeg_fdct_5x5 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
   /* Pre-zero output coefficient block. */
   MEMZERO(data, SIZEOF(DCTELEM) * DCTSIZE2);
 
-  /* Pass 1: process rows. */
-  /* Note results are scaled up by sqrt(8) compared to a true DCT; */
-  /* furthermore, we scale the results by 2**PASS1_BITS. */
-  /* We scale the results further by 2 as part of output adaption */
-  /* scaling for different DCT size. */
-  /* cK represents sqrt(2) * cos(K*pi/10). */
+  /* Pass 1: process rows.
+   * Note results are scaled up by sqrt(8) compared to a true DCT;
+   * furthermore, we scale the results by 2**PASS1_BITS.
+   * We scale the results further by 2 as part of output adaption
+   * scaling for different DCT size.
+   * cK represents sqrt(2) * cos(K*pi/10).
+   */
 
   dataptr = data;
   for (ctr = 0; ctr < 5; ctr++) {
@@ -695,11 +705,12 @@ jpeg_fdct_4x4 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
   /* Pre-zero output coefficient block. */
   MEMZERO(data, SIZEOF(DCTELEM) * DCTSIZE2);
 
-  /* Pass 1: process rows. */
-  /* Note results are scaled up by sqrt(8) compared to a true DCT; */
-  /* furthermore, we scale the results by 2**PASS1_BITS. */
-  /* We must also scale the output by (8/4)**2 = 2**2, which we add here. */
-  /* cK represents sqrt(2) * cos(K*pi/16) [refers to 8-point FDCT]. */
+  /* Pass 1: process rows.
+   * Note results are scaled up by sqrt(8) compared to a true DCT;
+   * furthermore, we scale the results by 2**PASS1_BITS.
+   * We must also scale the output by (8/4)**2 = 2**2, which we add here.
+   * cK represents sqrt(2) * cos(K*pi/16) [refers to 8-point FDCT].
+   */
 
   dataptr = data;
   for (ctr = 0; ctr < 4; ctr++) {
@@ -737,6 +748,7 @@ jpeg_fdct_4x4 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
   /* Pass 2: process columns.
    * We remove the PASS1_BITS scaling, but leave the results scaled up
    * by an overall factor of 8.
+   * cK represents sqrt(2) * cos(K*pi/16) [refers to 8-point FDCT].
    */
 
   dataptr = data;
@@ -787,12 +799,13 @@ jpeg_fdct_3x3 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
   /* Pre-zero output coefficient block. */
   MEMZERO(data, SIZEOF(DCTELEM) * DCTSIZE2);
 
-  /* Pass 1: process rows. */
-  /* Note results are scaled up by sqrt(8) compared to a true DCT; */
-  /* furthermore, we scale the results by 2**PASS1_BITS. */
-  /* We scale the results further by 2**2 as part of output adaption */
-  /* scaling for different DCT size. */
-  /* cK represents sqrt(2) * cos(K*pi/6). */
+  /* Pass 1: process rows.
+   * Note results are scaled up by sqrt(8) compared to a true DCT;
+   * furthermore, we scale the results by 2**PASS1_BITS.
+   * We scale the results further by 2**2 as part of output adaption
+   * scaling for different DCT size.
+   * cK represents sqrt(2) * cos(K*pi/6).
+   */
 
   dataptr = data;
   for (ctr = 0; ctr < 3; ctr++) {
@@ -869,8 +882,9 @@ jpeg_fdct_2x2 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
   /* Pre-zero output coefficient block. */
   MEMZERO(data, SIZEOF(DCTELEM) * DCTSIZE2);
 
-  /* Pass 1: process rows. */
-  /* Note results are scaled up by sqrt(8) compared to a true DCT. */
+  /* Pass 1: process rows.
+   * Note results are scaled up by sqrt(8) compared to a true DCT.
+   */
 
   /* Row 0 */
   elemptr = sample_data[0] + start_col;
@@ -935,11 +949,12 @@ jpeg_fdct_9x9 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
   int ctr;
   SHIFT_TEMPS
 
-  /* Pass 1: process rows. */
-  /* Note results are scaled up by sqrt(8) compared to a true DCT; */
-  /* we scale the results further by 2 as part of output adaption */
-  /* scaling for different DCT size. */
-  /* cK represents sqrt(2) * cos(K*pi/18). */
+  /* Pass 1: process rows.
+   * Note results are scaled up by sqrt(8) compared to a true DCT;
+   * we scale the results further by 2 as part of output adaption
+   * scaling for different DCT size.
+   * cK represents sqrt(2) * cos(K*pi/18).
+   */
 
   dataptr = data;
   ctr = 0;
@@ -1084,11 +1099,12 @@ jpeg_fdct_10x10 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
   int ctr;
   SHIFT_TEMPS
 
-  /* Pass 1: process rows. */
-  /* Note results are scaled up by sqrt(8) compared to a true DCT; */
-  /* we scale the results further by 2 as part of output adaption */
-  /* scaling for different DCT size. */
-  /* cK represents sqrt(2) * cos(K*pi/20). */
+  /* Pass 1: process rows.
+   * Note results are scaled up by sqrt(8) compared to a true DCT;
+   * we scale the results further by 2 as part of output adaption
+   * scaling for different DCT size.
+   * cK represents sqrt(2) * cos(K*pi/20).
+   */
 
   dataptr = data;
   ctr = 0;
@@ -1248,11 +1264,12 @@ jpeg_fdct_11x11 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
   int ctr;
   SHIFT_TEMPS
 
-  /* Pass 1: process rows. */
-  /* Note results are scaled up by sqrt(8) compared to a true DCT; */
-  /* we scale the results further by 2 as part of output adaption */
-  /* scaling for different DCT size. */
-  /* cK represents sqrt(2) * cos(K*pi/22). */
+  /* Pass 1: process rows.
+   * Note results are scaled up by sqrt(8) compared to a true DCT;
+   * we scale the results further by 2 as part of output adaption
+   * scaling for different DCT size.
+   * cK represents sqrt(2) * cos(K*pi/22).
+   */
 
   dataptr = data;
   ctr = 0;
@@ -1430,9 +1447,10 @@ jpeg_fdct_12x12 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
   int ctr;
   SHIFT_TEMPS
 
-  /* Pass 1: process rows. */
-  /* Note results are scaled up by sqrt(8) compared to a true DCT. */
-  /* cK represents sqrt(2) * cos(K*pi/24). */
+  /* Pass 1: process rows.
+   * Note results are scaled up by sqrt(8) compared to a true DCT.
+   * cK represents sqrt(2) * cos(K*pi/24).
+   */
 
   dataptr = data;
   ctr = 0;
@@ -1596,9 +1614,10 @@ jpeg_fdct_13x13 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
   int ctr;
   SHIFT_TEMPS
 
-  /* Pass 1: process rows. */
-  /* Note results are scaled up by sqrt(8) compared to a true DCT. */
-  /* cK represents sqrt(2) * cos(K*pi/26). */
+  /* Pass 1: process rows.
+   * Note results are scaled up by sqrt(8) compared to a true DCT.
+   * cK represents sqrt(2) * cos(K*pi/26).
+   */
 
   dataptr = data;
   ctr = 0;
@@ -1794,9 +1813,10 @@ jpeg_fdct_14x14 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
   int ctr;
   SHIFT_TEMPS
 
-  /* Pass 1: process rows. */
-  /* Note results are scaled up by sqrt(8) compared to a true DCT. */
-  /* cK represents sqrt(2) * cos(K*pi/28). */
+  /* Pass 1: process rows.
+   * Note results are scaled up by sqrt(8) compared to a true DCT.
+   * cK represents sqrt(2) * cos(K*pi/28).
+   */
 
   dataptr = data;
   ctr = 0;
@@ -1995,9 +2015,10 @@ jpeg_fdct_15x15 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
   int ctr;
   SHIFT_TEMPS
 
-  /* Pass 1: process rows. */
-  /* Note results are scaled up by sqrt(8) compared to a true DCT. */
-  /* cK represents sqrt(2) * cos(K*pi/30). */
+  /* Pass 1: process rows.
+   * Note results are scaled up by sqrt(8) compared to a true DCT.
+   * cK represents sqrt(2) * cos(K*pi/30).
+   */
 
   dataptr = data;
   ctr = 0;
@@ -2173,10 +2194,11 @@ jpeg_fdct_16x16 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
   int ctr;
   SHIFT_TEMPS
 
-  /* Pass 1: process rows. */
-  /* Note results are scaled up by sqrt(8) compared to a true DCT; */
-  /* furthermore, we scale the results by 2**PASS1_BITS. */
-  /* cK represents sqrt(2) * cos(K*pi/32). */
+  /* Pass 1: process rows.
+   * Note results are scaled up by sqrt(8) compared to a true DCT;
+   * furthermore, we scale the results by 2**PASS1_BITS.
+   * cK represents sqrt(2) * cos(K*pi/32).
+   */
 
   dataptr = data;
   ctr = 0;
@@ -2275,6 +2297,7 @@ jpeg_fdct_16x16 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
    * We remove the PASS1_BITS scaling, but leave the results scaled up
    * by an overall factor of 8.
    * We must also scale the output by (8/16)**2 = 1/2**2.
+   * cK represents sqrt(2) * cos(K*pi/32).
    */
 
   dataptr = data;
@@ -2380,10 +2403,11 @@ jpeg_fdct_16x8 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
   int ctr;
   SHIFT_TEMPS
 
-  /* Pass 1: process rows. */
-  /* Note results are scaled up by sqrt(8) compared to a true DCT; */
-  /* furthermore, we scale the results by 2**PASS1_BITS. */
-  /* 16-point FDCT kernel, cK represents sqrt(2) * cos(K*pi/32). */
+  /* Pass 1: process rows.
+   * Note results are scaled up by sqrt(8) compared to a true DCT;
+   * furthermore, we scale the results by 2**PASS1_BITS.
+   * 16-point FDCT kernel, cK represents sqrt(2) * cos(K*pi/32).
+   */
 
   dataptr = data;
   ctr = 0;
@@ -2475,12 +2499,13 @@ jpeg_fdct_16x8 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
    * We remove the PASS1_BITS scaling, but leave the results scaled up
    * by an overall factor of 8.
    * We must also scale the output by 8/16 = 1/2.
+   * 8-point FDCT kernel, cK represents sqrt(2) * cos(K*pi/16).
    */
 
   dataptr = data;
   for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
     /* Even part per LL&M figure 1 --- note that published figure is faulty;
-     * rotator "sqrt(2)*c1" should be "sqrt(2)*c6".
+     * rotator "c1" should be "c6".
      */
 
     tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7];
@@ -2501,43 +2526,43 @@ jpeg_fdct_16x8 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
     dataptr[DCTSIZE*0] = (DCTELEM) DESCALE(tmp10 + tmp11, PASS1_BITS+1);
     dataptr[DCTSIZE*4] = (DCTELEM) DESCALE(tmp10 - tmp11, PASS1_BITS+1);
 
-    z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100);
-    dataptr[DCTSIZE*2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, FIX_0_765366865),
-					   CONST_BITS+PASS1_BITS+1);
-    dataptr[DCTSIZE*6] = (DCTELEM) DESCALE(z1 - MULTIPLY(tmp13, FIX_1_847759065),
-					   CONST_BITS+PASS1_BITS+1);
+    z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100);   /* c6 */
+    dataptr[DCTSIZE*2] = (DCTELEM)
+      DESCALE(z1 + MULTIPLY(tmp12, FIX_0_765366865), /* c2-c6 */
+	      CONST_BITS+PASS1_BITS+1);
+    dataptr[DCTSIZE*6] = (DCTELEM)
+      DESCALE(z1 - MULTIPLY(tmp13, FIX_1_847759065), /* c2+c6 */
+	      CONST_BITS+PASS1_BITS+1);
 
     /* Odd part per figure 8 --- note paper omits factor of sqrt(2).
-     * 8-point FDCT kernel, cK represents sqrt(2) * cos(K*pi/16).
      * i0..i3 in the paper are tmp0..tmp3 here.
      */
 
-    tmp10 = tmp0 + tmp3;
-    tmp11 = tmp1 + tmp2;
     tmp12 = tmp0 + tmp2;
     tmp13 = tmp1 + tmp3;
-    z1 = MULTIPLY(tmp12 + tmp13, FIX_1_175875602); /*  c3 */
-
-    tmp0  = MULTIPLY(tmp0,    FIX_1_501321110);    /*  c1+c3-c5-c7 */
-    tmp1  = MULTIPLY(tmp1,    FIX_3_072711026);    /*  c1+c3+c5-c7 */
-    tmp2  = MULTIPLY(tmp2,    FIX_2_053119869);    /*  c1+c3-c5+c7 */
-    tmp3  = MULTIPLY(tmp3,    FIX_0_298631336);    /* -c1+c3+c5-c7 */
-    tmp10 = MULTIPLY(tmp10, - FIX_0_899976223);    /*  c7-c3 */
-    tmp11 = MULTIPLY(tmp11, - FIX_2_562915447);    /* -c1-c3 */
-    tmp12 = MULTIPLY(tmp12, - FIX_0_390180644);    /*  c5-c3 */
-    tmp13 = MULTIPLY(tmp13, - FIX_1_961570560);    /* -c3-c5 */
 
+    z1 = MULTIPLY(tmp12 + tmp13, FIX_1_175875602);   /*  c3 */
+    tmp12 = MULTIPLY(tmp12, - FIX_0_390180644);      /* -c3+c5 */
+    tmp13 = MULTIPLY(tmp13, - FIX_1_961570560);      /* -c3-c5 */
     tmp12 += z1;
     tmp13 += z1;
 
-    dataptr[DCTSIZE*1] = (DCTELEM) DESCALE(tmp0 + tmp10 + tmp12,
-					   CONST_BITS+PASS1_BITS+1);
-    dataptr[DCTSIZE*3] = (DCTELEM) DESCALE(tmp1 + tmp11 + tmp13,
-					   CONST_BITS+PASS1_BITS+1);
-    dataptr[DCTSIZE*5] = (DCTELEM) DESCALE(tmp2 + tmp11 + tmp12,
-					   CONST_BITS+PASS1_BITS+1);
-    dataptr[DCTSIZE*7] = (DCTELEM) DESCALE(tmp3 + tmp10 + tmp13,
-					   CONST_BITS+PASS1_BITS+1);
+    z1 = MULTIPLY(tmp0 + tmp3, - FIX_0_899976223);   /* -c3+c7 */
+    tmp0 = MULTIPLY(tmp0, FIX_1_501321110);          /*  c1+c3-c5-c7 */
+    tmp3 = MULTIPLY(tmp3, FIX_0_298631336);          /* -c1+c3+c5-c7 */
+    tmp0 += z1 + tmp12;
+    tmp3 += z1 + tmp13;
+
+    z1 = MULTIPLY(tmp1 + tmp2, - FIX_2_562915447);   /* -c1-c3 */
+    tmp1 = MULTIPLY(tmp1, FIX_3_072711026);          /*  c1+c3+c5-c7 */
+    tmp2 = MULTIPLY(tmp2, FIX_2_053119869);          /*  c1+c3-c5+c7 */
+    tmp1 += z1 + tmp13;
+    tmp2 += z1 + tmp12;
+
+    dataptr[DCTSIZE*1] = (DCTELEM) DESCALE(tmp0, CONST_BITS+PASS1_BITS+1);
+    dataptr[DCTSIZE*3] = (DCTELEM) DESCALE(tmp1, CONST_BITS+PASS1_BITS+1);
+    dataptr[DCTSIZE*5] = (DCTELEM) DESCALE(tmp2, CONST_BITS+PASS1_BITS+1);
+    dataptr[DCTSIZE*7] = (DCTELEM) DESCALE(tmp3, CONST_BITS+PASS1_BITS+1);
 
     dataptr++;			/* advance pointer to next column */
   }
@@ -2564,10 +2589,11 @@ jpeg_fdct_14x7 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
   /* Zero bottom row of output coefficient block. */
   MEMZERO(&data[DCTSIZE*7], SIZEOF(DCTELEM) * DCTSIZE);
 
-  /* Pass 1: process rows. */
-  /* Note results are scaled up by sqrt(8) compared to a true DCT; */
-  /* furthermore, we scale the results by 2**PASS1_BITS. */
-  /* 14-point FDCT kernel, cK represents sqrt(2) * cos(K*pi/28). */
+  /* Pass 1: process rows.
+   * Note results are scaled up by sqrt(8) compared to a true DCT;
+   * furthermore, we scale the results by 2**PASS1_BITS.
+   * 14-point FDCT kernel, cK represents sqrt(2) * cos(K*pi/28).
+   */
 
   dataptr = data;
   for (ctr = 0; ctr < 7; ctr++) {
@@ -2727,10 +2753,11 @@ jpeg_fdct_12x6 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
   /* Zero 2 bottom rows of output coefficient block. */
   MEMZERO(&data[DCTSIZE*6], SIZEOF(DCTELEM) * DCTSIZE * 2);
 
-  /* Pass 1: process rows. */
-  /* Note results are scaled up by sqrt(8) compared to a true DCT; */
-  /* furthermore, we scale the results by 2**PASS1_BITS. */
-  /* 12-point FDCT kernel, cK represents sqrt(2) * cos(K*pi/24). */
+  /* Pass 1: process rows.
+   * Note results are scaled up by sqrt(8) compared to a true DCT;
+   * furthermore, we scale the results by 2**PASS1_BITS.
+   * 12-point FDCT kernel, cK represents sqrt(2) * cos(K*pi/24).
+   */
 
   dataptr = data;
   for (ctr = 0; ctr < 6; ctr++) {
@@ -2866,10 +2893,11 @@ jpeg_fdct_10x5 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
   /* Zero 3 bottom rows of output coefficient block. */
   MEMZERO(&data[DCTSIZE*5], SIZEOF(DCTELEM) * DCTSIZE * 3);
 
-  /* Pass 1: process rows. */
-  /* Note results are scaled up by sqrt(8) compared to a true DCT; */
-  /* furthermore, we scale the results by 2**PASS1_BITS. */
-  /* 10-point FDCT kernel, cK represents sqrt(2) * cos(K*pi/20). */
+  /* Pass 1: process rows.
+   * Note results are scaled up by sqrt(8) compared to a true DCT;
+   * furthermore, we scale the results by 2**PASS1_BITS.
+   * 10-point FDCT kernel, cK represents sqrt(2) * cos(K*pi/20).
+   */
 
   dataptr = data;
   for (ctr = 0; ctr < 5; ctr++) {
@@ -2999,17 +3027,19 @@ jpeg_fdct_8x4 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
   /* Zero 4 bottom rows of output coefficient block. */
   MEMZERO(&data[DCTSIZE*4], SIZEOF(DCTELEM) * DCTSIZE * 4);
 
-  /* Pass 1: process rows. */
-  /* Note results are scaled up by sqrt(8) compared to a true DCT; */
-  /* furthermore, we scale the results by 2**PASS1_BITS. */
-  /* We must also scale the output by 8/4 = 2, which we add here. */
+  /* Pass 1: process rows.
+   * Note results are scaled up by sqrt(8) compared to a true DCT;
+   * furthermore, we scale the results by 2**PASS1_BITS.
+   * We must also scale the output by 8/4 = 2, which we add here.
+   * 8-point FDCT kernel, cK represents sqrt(2) * cos(K*pi/16).
+   */
 
   dataptr = data;
   for (ctr = 0; ctr < 4; ctr++) {
     elemptr = sample_data[ctr] + start_col;
 
     /* Even part per LL&M figure 1 --- note that published figure is faulty;
-     * rotator "sqrt(2)*c1" should be "sqrt(2)*c6".
+     * rotator "c1" should be "c6".
      */
 
     tmp0 = GETJSAMPLE(elemptr[0]) + GETJSAMPLE(elemptr[7]);
@@ -3032,47 +3062,49 @@ jpeg_fdct_8x4 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
       ((tmp10 + tmp11 - 8 * CENTERJSAMPLE) << (PASS1_BITS+1));
     dataptr[4] = (DCTELEM) ((tmp10 - tmp11) << (PASS1_BITS+1));
 
-    z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100);
+    z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100);       /* c6 */
     /* Add fudge factor here for final descale. */
     z1 += ONE << (CONST_BITS-PASS1_BITS-2);
-    dataptr[2] = (DCTELEM) RIGHT_SHIFT(z1 + MULTIPLY(tmp12, FIX_0_765366865),
-				       CONST_BITS-PASS1_BITS-1);
-    dataptr[6] = (DCTELEM) RIGHT_SHIFT(z1 - MULTIPLY(tmp13, FIX_1_847759065),
-				       CONST_BITS-PASS1_BITS-1);
+
+    dataptr[2] = (DCTELEM)
+      RIGHT_SHIFT(z1 + MULTIPLY(tmp12, FIX_0_765366865), /* c2-c6 */
+		  CONST_BITS-PASS1_BITS-1);
+    dataptr[6] = (DCTELEM)
+      RIGHT_SHIFT(z1 - MULTIPLY(tmp13, FIX_1_847759065), /* c2+c6 */
+		  CONST_BITS-PASS1_BITS-1);
 
     /* Odd part per figure 8 --- note paper omits factor of sqrt(2).
-     * 8-point FDCT kernel, cK represents sqrt(2) * cos(K*pi/16).
      * i0..i3 in the paper are tmp0..tmp3 here.
      */
 
-    tmp10 = tmp0 + tmp3;
-    tmp11 = tmp1 + tmp2;
     tmp12 = tmp0 + tmp2;
     tmp13 = tmp1 + tmp3;
-    z1 = MULTIPLY(tmp12 + tmp13, FIX_1_175875602); /*  c3 */
+
+    z1 = MULTIPLY(tmp12 + tmp13, FIX_1_175875602);       /*  c3 */
     /* Add fudge factor here for final descale. */
     z1 += ONE << (CONST_BITS-PASS1_BITS-2);
 
-    tmp0  = MULTIPLY(tmp0,    FIX_1_501321110);    /*  c1+c3-c5-c7 */
-    tmp1  = MULTIPLY(tmp1,    FIX_3_072711026);    /*  c1+c3+c5-c7 */
-    tmp2  = MULTIPLY(tmp2,    FIX_2_053119869);    /*  c1+c3-c5+c7 */
-    tmp3  = MULTIPLY(tmp3,    FIX_0_298631336);    /* -c1+c3+c5-c7 */
-    tmp10 = MULTIPLY(tmp10, - FIX_0_899976223);    /*  c7-c3 */
-    tmp11 = MULTIPLY(tmp11, - FIX_2_562915447);    /* -c1-c3 */
-    tmp12 = MULTIPLY(tmp12, - FIX_0_390180644);    /*  c5-c3 */
-    tmp13 = MULTIPLY(tmp13, - FIX_1_961570560);    /* -c3-c5 */
-
+    tmp12 = MULTIPLY(tmp12, - FIX_0_390180644);          /* -c3+c5 */
+    tmp13 = MULTIPLY(tmp13, - FIX_1_961570560);          /* -c3-c5 */
     tmp12 += z1;
     tmp13 += z1;
 
-    dataptr[1] = (DCTELEM)
-      RIGHT_SHIFT(tmp0 + tmp10 + tmp12, CONST_BITS-PASS1_BITS-1);
-    dataptr[3] = (DCTELEM)
-      RIGHT_SHIFT(tmp1 + tmp11 + tmp13, CONST_BITS-PASS1_BITS-1);
-    dataptr[5] = (DCTELEM)
-      RIGHT_SHIFT(tmp2 + tmp11 + tmp12, CONST_BITS-PASS1_BITS-1);
-    dataptr[7] = (DCTELEM)
-      RIGHT_SHIFT(tmp3 + tmp10 + tmp13, CONST_BITS-PASS1_BITS-1);
+    z1 = MULTIPLY(tmp0 + tmp3, - FIX_0_899976223);       /* -c3+c7 */
+    tmp0 = MULTIPLY(tmp0, FIX_1_501321110);              /*  c1+c3-c5-c7 */
+    tmp3 = MULTIPLY(tmp3, FIX_0_298631336);              /* -c1+c3+c5-c7 */
+    tmp0 += z1 + tmp12;
+    tmp3 += z1 + tmp13;
+
+    z1 = MULTIPLY(tmp1 + tmp2, - FIX_2_562915447);       /* -c1-c3 */
+    tmp1 = MULTIPLY(tmp1, FIX_3_072711026);              /*  c1+c3+c5-c7 */
+    tmp2 = MULTIPLY(tmp2, FIX_2_053119869);              /*  c1+c3-c5+c7 */
+    tmp1 += z1 + tmp13;
+    tmp2 += z1 + tmp12;
+
+    dataptr[1] = (DCTELEM) RIGHT_SHIFT(tmp0, CONST_BITS-PASS1_BITS-1);
+    dataptr[3] = (DCTELEM) RIGHT_SHIFT(tmp1, CONST_BITS-PASS1_BITS-1);
+    dataptr[5] = (DCTELEM) RIGHT_SHIFT(tmp2, CONST_BITS-PASS1_BITS-1);
+    dataptr[7] = (DCTELEM) RIGHT_SHIFT(tmp3, CONST_BITS-PASS1_BITS-1);
 
     dataptr += DCTSIZE;		/* advance pointer to next row */
   }
@@ -3080,7 +3112,8 @@ jpeg_fdct_8x4 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
   /* Pass 2: process columns.
    * We remove the PASS1_BITS scaling, but leave the results scaled up
    * by an overall factor of 8.
-   * 4-point FDCT kernel, cK represents sqrt(2) * cos(K*pi/16).
+   * 4-point FDCT kernel,
+   * cK represents sqrt(2) * cos(K*pi/16) [refers to 8-point FDCT].
    */
 
   dataptr = data;
@@ -3099,7 +3132,7 @@ jpeg_fdct_8x4 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
 
     /* Odd part */
 
-    tmp0 = MULTIPLY(tmp10 + tmp11, FIX_0_541196100);   /* c6 */
+    tmp0 = MULTIPLY(tmp10 + tmp11, FIX_0_541196100);       /* c6 */
     /* Add fudge factor here for final descale. */
     tmp0 += ONE << (CONST_BITS+PASS1_BITS-1);
 
@@ -3134,12 +3167,13 @@ jpeg_fdct_6x3 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
   /* Pre-zero output coefficient block. */
   MEMZERO(data, SIZEOF(DCTELEM) * DCTSIZE2);
 
-  /* Pass 1: process rows. */
-  /* Note results are scaled up by sqrt(8) compared to a true DCT; */
-  /* furthermore, we scale the results by 2**PASS1_BITS. */
-  /* We scale the results further by 2 as part of output adaption */
-  /* scaling for different DCT size. */
-  /* 6-point FDCT kernel, cK represents sqrt(2) * cos(K*pi/12). */
+  /* Pass 1: process rows.
+   * Note results are scaled up by sqrt(8) compared to a true DCT;
+   * furthermore, we scale the results by 2**PASS1_BITS.
+   * We scale the results further by 2 as part of output adaption
+   * scaling for different DCT size.
+   * 6-point FDCT kernel, cK represents sqrt(2) * cos(K*pi/12).
+   */
 
   dataptr = data;
   for (ctr = 0; ctr < 3; ctr++) {
@@ -3234,12 +3268,13 @@ jpeg_fdct_4x2 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
   /* Pre-zero output coefficient block. */
   MEMZERO(data, SIZEOF(DCTELEM) * DCTSIZE2);
 
-  /* Pass 1: process rows. */
-  /* Note results are scaled up by sqrt(8) compared to a true DCT; */
-  /* furthermore, we scale the results by 2**PASS1_BITS. */
-  /* We must also scale the output by (8/4)*(8/2) = 2**3, which we add here. */
-  /* 4-point FDCT kernel, */
-  /* cK represents sqrt(2) * cos(K*pi/16) [refers to 8-point FDCT]. */
+  /* Pass 1: process rows.
+   * Note results are scaled up by sqrt(8) compared to a true DCT;
+   * furthermore, we scale the results by 2**PASS1_BITS.
+   * We must also scale the output by (8/4)*(8/2) = 2**3, which we add here.
+   * 4-point FDCT kernel,
+   * cK represents sqrt(2) * cos(K*pi/16) [refers to 8-point FDCT].
+   */
 
   dataptr = data;
   for (ctr = 0; ctr < 2; ctr++) {
@@ -3323,10 +3358,12 @@ jpeg_fdct_2x1 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
    */
 
   /* Even part */
+
   /* Apply unsigned->signed conversion */
   data[0] = (DCTELEM) ((tmp0 + tmp1 - 2 * CENTERJSAMPLE) << 5);
 
   /* Odd part */
+
   data[1] = (DCTELEM) ((tmp0 - tmp1) << 5);
 }
 
@@ -3350,9 +3387,11 @@ jpeg_fdct_8x16 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
   int ctr;
   SHIFT_TEMPS
 
-  /* Pass 1: process rows. */
-  /* Note results are scaled up by sqrt(8) compared to a true DCT; */
-  /* furthermore, we scale the results by 2**PASS1_BITS. */
+  /* Pass 1: process rows.
+   * Note results are scaled up by sqrt(8) compared to a true DCT;
+   * furthermore, we scale the results by 2**PASS1_BITS.
+   * 8-point FDCT kernel, cK represents sqrt(2) * cos(K*pi/16).
+   */
 
   dataptr = data;
   ctr = 0;
@@ -3360,7 +3399,7 @@ jpeg_fdct_8x16 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
     elemptr = sample_data[ctr] + start_col;
 
     /* Even part per LL&M figure 1 --- note that published figure is faulty;
-     * rotator "sqrt(2)*c1" should be "sqrt(2)*c6".
+     * rotator "c1" should be "c6".
      */
 
     tmp0 = GETJSAMPLE(elemptr[0]) + GETJSAMPLE(elemptr[7]);
@@ -3382,39 +3421,43 @@ jpeg_fdct_8x16 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
     dataptr[0] = (DCTELEM) ((tmp10 + tmp11 - 8 * CENTERJSAMPLE) << PASS1_BITS);
     dataptr[4] = (DCTELEM) ((tmp10 - tmp11) << PASS1_BITS);
 
-    z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100);
-    dataptr[2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, FIX_0_765366865),
-				   CONST_BITS-PASS1_BITS);
-    dataptr[6] = (DCTELEM) DESCALE(z1 - MULTIPLY(tmp13, FIX_1_847759065),
-				   CONST_BITS-PASS1_BITS);
+    z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100);   /* c6 */
+    dataptr[2] = (DCTELEM)
+      DESCALE(z1 + MULTIPLY(tmp12, FIX_0_765366865), /* c2-c6 */
+	      CONST_BITS-PASS1_BITS);
+    dataptr[6] = (DCTELEM)
+      DESCALE(z1 - MULTIPLY(tmp13, FIX_1_847759065), /* c2+c6 */
+	      CONST_BITS-PASS1_BITS);
 
     /* Odd part per figure 8 --- note paper omits factor of sqrt(2).
-     * 8-point FDCT kernel, cK represents sqrt(2) * cos(K*pi/16).
      * i0..i3 in the paper are tmp0..tmp3 here.
      */
 
-    tmp10 = tmp0 + tmp3;
-    tmp11 = tmp1 + tmp2;
     tmp12 = tmp0 + tmp2;
     tmp13 = tmp1 + tmp3;
-    z1 = MULTIPLY(tmp12 + tmp13, FIX_1_175875602); /*  c3 */
-
-    tmp0  = MULTIPLY(tmp0,    FIX_1_501321110);    /*  c1+c3-c5-c7 */
-    tmp1  = MULTIPLY(tmp1,    FIX_3_072711026);    /*  c1+c3+c5-c7 */
-    tmp2  = MULTIPLY(tmp2,    FIX_2_053119869);    /*  c1+c3-c5+c7 */
-    tmp3  = MULTIPLY(tmp3,    FIX_0_298631336);    /* -c1+c3+c5-c7 */
-    tmp10 = MULTIPLY(tmp10, - FIX_0_899976223);    /*  c7-c3 */
-    tmp11 = MULTIPLY(tmp11, - FIX_2_562915447);    /* -c1-c3 */
-    tmp12 = MULTIPLY(tmp12, - FIX_0_390180644);    /*  c5-c3 */
-    tmp13 = MULTIPLY(tmp13, - FIX_1_961570560);    /* -c3-c5 */
 
+    z1 = MULTIPLY(tmp12 + tmp13, FIX_1_175875602);   /*  c3 */
+    tmp12 = MULTIPLY(tmp12, - FIX_0_390180644);      /* -c3+c5 */
+    tmp13 = MULTIPLY(tmp13, - FIX_1_961570560);      /* -c3-c5 */
     tmp12 += z1;
     tmp13 += z1;
 
-    dataptr[1] = (DCTELEM) DESCALE(tmp0 + tmp10 + tmp12, CONST_BITS-PASS1_BITS);
-    dataptr[3] = (DCTELEM) DESCALE(tmp1 + tmp11 + tmp13, CONST_BITS-PASS1_BITS);
-    dataptr[5] = (DCTELEM) DESCALE(tmp2 + tmp11 + tmp12, CONST_BITS-PASS1_BITS);
-    dataptr[7] = (DCTELEM) DESCALE(tmp3 + tmp10 + tmp13, CONST_BITS-PASS1_BITS);
+    z1 = MULTIPLY(tmp0 + tmp3, - FIX_0_899976223);   /* -c3+c7 */
+    tmp0 = MULTIPLY(tmp0, FIX_1_501321110);          /*  c1+c3-c5-c7 */
+    tmp3 = MULTIPLY(tmp3, FIX_0_298631336);          /* -c1+c3+c5-c7 */
+    tmp0 += z1 + tmp12;
+    tmp3 += z1 + tmp13;
+
+    z1 = MULTIPLY(tmp1 + tmp2, - FIX_2_562915447);   /* -c1-c3 */
+    tmp1 = MULTIPLY(tmp1, FIX_3_072711026);          /*  c1+c3+c5-c7 */
+    tmp2 = MULTIPLY(tmp2, FIX_2_053119869);          /*  c1+c3-c5+c7 */
+    tmp1 += z1 + tmp13;
+    tmp2 += z1 + tmp12;
+
+    dataptr[1] = (DCTELEM) DESCALE(tmp0, CONST_BITS-PASS1_BITS);
+    dataptr[3] = (DCTELEM) DESCALE(tmp1, CONST_BITS-PASS1_BITS);
+    dataptr[5] = (DCTELEM) DESCALE(tmp2, CONST_BITS-PASS1_BITS);
+    dataptr[7] = (DCTELEM) DESCALE(tmp3, CONST_BITS-PASS1_BITS);
 
     ctr++;
 
@@ -3541,10 +3584,11 @@ jpeg_fdct_7x14 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
   /* Pre-zero output coefficient block. */
   MEMZERO(data, SIZEOF(DCTELEM) * DCTSIZE2);
 
-  /* Pass 1: process rows. */
-  /* Note results are scaled up by sqrt(8) compared to a true DCT; */
-  /* furthermore, we scale the results by 2**PASS1_BITS. */
-  /* 7-point FDCT kernel, cK represents sqrt(2) * cos(K*pi/14). */
+  /* Pass 1: process rows.
+   * Note results are scaled up by sqrt(8) compared to a true DCT;
+   * furthermore, we scale the results by 2**PASS1_BITS.
+   * 7-point FDCT kernel, cK represents sqrt(2) * cos(K*pi/14).
+   */
 
   dataptr = data;
   ctr = 0;
@@ -3721,10 +3765,11 @@ jpeg_fdct_6x12 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
   /* Pre-zero output coefficient block. */
   MEMZERO(data, SIZEOF(DCTELEM) * DCTSIZE2);
 
-  /* Pass 1: process rows. */
-  /* Note results are scaled up by sqrt(8) compared to a true DCT; */
-  /* furthermore, we scale the results by 2**PASS1_BITS. */
-  /* 6-point FDCT kernel, cK represents sqrt(2) * cos(K*pi/12). */
+  /* Pass 1: process rows.
+   * Note results are scaled up by sqrt(8) compared to a true DCT;
+   * furthermore, we scale the results by 2**PASS1_BITS.
+   * 6-point FDCT kernel, cK represents sqrt(2) * cos(K*pi/12).
+   */
 
   dataptr = data;
   ctr = 0;
@@ -3870,10 +3915,11 @@ jpeg_fdct_5x10 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
   /* Pre-zero output coefficient block. */
   MEMZERO(data, SIZEOF(DCTELEM) * DCTSIZE2);
 
-  /* Pass 1: process rows. */
-  /* Note results are scaled up by sqrt(8) compared to a true DCT; */
-  /* furthermore, we scale the results by 2**PASS1_BITS. */
-  /* 5-point FDCT kernel, cK represents sqrt(2) * cos(K*pi/10). */
+  /* Pass 1: process rows.
+   * Note results are scaled up by sqrt(8) compared to a true DCT;
+   * furthermore, we scale the results by 2**PASS1_BITS.
+   * 5-point FDCT kernel, cK represents sqrt(2) * cos(K*pi/10).
+   */
 
   dataptr = data;
   ctr = 0;
@@ -4015,11 +4061,13 @@ jpeg_fdct_4x8 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
   /* Pre-zero output coefficient block. */
   MEMZERO(data, SIZEOF(DCTELEM) * DCTSIZE2);
 
-  /* Pass 1: process rows. */
-  /* Note results are scaled up by sqrt(8) compared to a true DCT; */
-  /* furthermore, we scale the results by 2**PASS1_BITS. */
-  /* We must also scale the output by 8/4 = 2, which we add here. */
-  /* 4-point FDCT kernel, cK represents sqrt(2) * cos(K*pi/16). */
+  /* Pass 1: process rows.
+   * Note results are scaled up by sqrt(8) compared to a true DCT;
+   * furthermore, we scale the results by 2**PASS1_BITS.
+   * We must also scale the output by 8/4 = 2, which we add here.
+   * 4-point FDCT kernel,
+   * cK represents sqrt(2) * cos(K*pi/16) [refers to 8-point FDCT].
+   */
 
   dataptr = data;
   for (ctr = 0; ctr < DCTSIZE; ctr++) {
@@ -4057,12 +4105,13 @@ jpeg_fdct_4x8 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
   /* Pass 2: process columns.
    * We remove the PASS1_BITS scaling, but leave the results scaled up
    * by an overall factor of 8.
+   * 8-point FDCT kernel, cK represents sqrt(2) * cos(K*pi/16).
    */
 
   dataptr = data;
   for (ctr = 0; ctr < 4; ctr++) {
     /* Even part per LL&M figure 1 --- note that published figure is faulty;
-     * rotator "sqrt(2)*c1" should be "sqrt(2)*c6".
+     * rotator "c1" should be "c6".
      */
 
     tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7];
@@ -4084,47 +4133,49 @@ jpeg_fdct_4x8 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
     dataptr[DCTSIZE*0] = (DCTELEM) RIGHT_SHIFT(tmp10 + tmp11, PASS1_BITS);
     dataptr[DCTSIZE*4] = (DCTELEM) RIGHT_SHIFT(tmp10 - tmp11, PASS1_BITS);
 
-    z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100);
+    z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100);       /* c6 */
     /* Add fudge factor here for final descale. */
     z1 += ONE << (CONST_BITS+PASS1_BITS-1);
+
     dataptr[DCTSIZE*2] = (DCTELEM)
-      RIGHT_SHIFT(z1 + MULTIPLY(tmp12, FIX_0_765366865), CONST_BITS+PASS1_BITS);
+      RIGHT_SHIFT(z1 + MULTIPLY(tmp12, FIX_0_765366865), /* c2-c6 */
+		  CONST_BITS+PASS1_BITS);
     dataptr[DCTSIZE*6] = (DCTELEM)
-      RIGHT_SHIFT(z1 - MULTIPLY(tmp13, FIX_1_847759065), CONST_BITS+PASS1_BITS);
+      RIGHT_SHIFT(z1 - MULTIPLY(tmp13, FIX_1_847759065), /* c2+c6 */
+		  CONST_BITS+PASS1_BITS);
 
     /* Odd part per figure 8 --- note paper omits factor of sqrt(2).
-     * 8-point FDCT kernel, cK represents sqrt(2) * cos(K*pi/16).
      * i0..i3 in the paper are tmp0..tmp3 here.
      */
 
-    tmp10 = tmp0 + tmp3;
-    tmp11 = tmp1 + tmp2;
     tmp12 = tmp0 + tmp2;
     tmp13 = tmp1 + tmp3;
-    z1 = MULTIPLY(tmp12 + tmp13, FIX_1_175875602); /*  c3 */
+
+    z1 = MULTIPLY(tmp12 + tmp13, FIX_1_175875602);       /*  c3 */
     /* Add fudge factor here for final descale. */
     z1 += ONE << (CONST_BITS+PASS1_BITS-1);
 
-    tmp0  = MULTIPLY(tmp0,    FIX_1_501321110);    /*  c1+c3-c5-c7 */
-    tmp1  = MULTIPLY(tmp1,    FIX_3_072711026);    /*  c1+c3+c5-c7 */
-    tmp2  = MULTIPLY(tmp2,    FIX_2_053119869);    /*  c1+c3-c5+c7 */
-    tmp3  = MULTIPLY(tmp3,    FIX_0_298631336);    /* -c1+c3+c5-c7 */
-    tmp10 = MULTIPLY(tmp10, - FIX_0_899976223);    /*  c7-c3 */
-    tmp11 = MULTIPLY(tmp11, - FIX_2_562915447);    /* -c1-c3 */
-    tmp12 = MULTIPLY(tmp12, - FIX_0_390180644);    /*  c5-c3 */
-    tmp13 = MULTIPLY(tmp13, - FIX_1_961570560);    /* -c3-c5 */
-
+    tmp12 = MULTIPLY(tmp12, - FIX_0_390180644);          /* -c3+c5 */
+    tmp13 = MULTIPLY(tmp13, - FIX_1_961570560);          /* -c3-c5 */
     tmp12 += z1;
     tmp13 += z1;
 
-    dataptr[DCTSIZE*1] = (DCTELEM)
-      RIGHT_SHIFT(tmp0 + tmp10 + tmp12, CONST_BITS+PASS1_BITS);
-    dataptr[DCTSIZE*3] = (DCTELEM)
-      RIGHT_SHIFT(tmp1 + tmp11 + tmp13, CONST_BITS+PASS1_BITS);
-    dataptr[DCTSIZE*5] = (DCTELEM)
-      RIGHT_SHIFT(tmp2 + tmp11 + tmp12, CONST_BITS+PASS1_BITS);
-    dataptr[DCTSIZE*7] = (DCTELEM)
-      RIGHT_SHIFT(tmp3 + tmp10 + tmp13, CONST_BITS+PASS1_BITS);
+    z1 = MULTIPLY(tmp0 + tmp3, - FIX_0_899976223);       /* -c3+c7 */
+    tmp0 = MULTIPLY(tmp0, FIX_1_501321110);              /*  c1+c3-c5-c7 */
+    tmp3 = MULTIPLY(tmp3, FIX_0_298631336);              /* -c1+c3+c5-c7 */
+    tmp0 += z1 + tmp12;
+    tmp3 += z1 + tmp13;
+
+    z1 = MULTIPLY(tmp1 + tmp2, - FIX_2_562915447);       /* -c1-c3 */
+    tmp1 = MULTIPLY(tmp1, FIX_3_072711026);              /*  c1+c3+c5-c7 */
+    tmp2 = MULTIPLY(tmp2, FIX_2_053119869);              /*  c1+c3-c5+c7 */
+    tmp1 += z1 + tmp13;
+    tmp2 += z1 + tmp12;
+
+    dataptr[DCTSIZE*1] = (DCTELEM) RIGHT_SHIFT(tmp0, CONST_BITS+PASS1_BITS);
+    dataptr[DCTSIZE*3] = (DCTELEM) RIGHT_SHIFT(tmp1, CONST_BITS+PASS1_BITS);
+    dataptr[DCTSIZE*5] = (DCTELEM) RIGHT_SHIFT(tmp2, CONST_BITS+PASS1_BITS);
+    dataptr[DCTSIZE*7] = (DCTELEM) RIGHT_SHIFT(tmp3, CONST_BITS+PASS1_BITS);
 
     dataptr++;			/* advance pointer to next column */
   }
@@ -4150,12 +4201,13 @@ jpeg_fdct_3x6 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
   /* Pre-zero output coefficient block. */
   MEMZERO(data, SIZEOF(DCTELEM) * DCTSIZE2);
 
-  /* Pass 1: process rows. */
-  /* Note results are scaled up by sqrt(8) compared to a true DCT; */
-  /* furthermore, we scale the results by 2**PASS1_BITS. */
-  /* We scale the results further by 2 as part of output adaption */
-  /* scaling for different DCT size. */
-  /* 3-point FDCT kernel, cK represents sqrt(2) * cos(K*pi/6). */
+  /* Pass 1: process rows.
+   * Note results are scaled up by sqrt(8) compared to a true DCT;
+   * furthermore, we scale the results by 2**PASS1_BITS.
+   * We scale the results further by 2 as part of output adaption
+   * scaling for different DCT size.
+   * 3-point FDCT kernel, cK represents sqrt(2) * cos(K*pi/6).
+   */
 
   dataptr = data;
   for (ctr = 0; ctr < 6; ctr++) {
@@ -4255,9 +4307,10 @@ jpeg_fdct_2x4 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
   /* Pre-zero output coefficient block. */
   MEMZERO(data, SIZEOF(DCTELEM) * DCTSIZE2);
 
-  /* Pass 1: process rows. */
-  /* Note results are scaled up by sqrt(8) compared to a true DCT. */
-  /* We must also scale the output by (8/2)*(8/4) = 2**3, which we add here. */
+  /* Pass 1: process rows.
+   * Note results are scaled up by sqrt(8) compared to a true DCT.
+   * We must also scale the output by (8/2)*(8/4) = 2**3, which we add here.
+   */
 
   dataptr = data;
   for (ctr = 0; ctr < 4; ctr++) {
@@ -4329,18 +4382,23 @@ jpeg_fdct_1x2 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
   /* Pre-zero output coefficient block. */
   MEMZERO(data, SIZEOF(DCTELEM) * DCTSIZE2);
 
-  tmp0 = GETJSAMPLE(sample_data[0][start_col]);
-  tmp1 = GETJSAMPLE(sample_data[1][start_col]);
+  /* Pass 1: empty. */
 
-  /* We leave the results scaled up by an overall factor of 8.
+  /* Pass 2: process columns.
+   * We leave the results scaled up by an overall factor of 8.
    * We must also scale the output by (8/1)*(8/2) = 2**5.
    */
 
   /* Even part */
+
+  tmp0 = GETJSAMPLE(sample_data[0][start_col]);
+  tmp1 = GETJSAMPLE(sample_data[1][start_col]);
+
   /* Apply unsigned->signed conversion */
   data[DCTSIZE*0] = (DCTELEM) ((tmp0 + tmp1 - 2 * CENTERJSAMPLE) << 5);
 
   /* Odd part */
+
   data[DCTSIZE*1] = (DCTELEM) ((tmp0 - tmp1) << 5);
 }
 
diff --git a/Source/LibJPEG/jidctint.c b/Source/LibJPEG/jidctint.c
index dcdf7ce..76fe5d9 100644
--- a/Source/LibJPEG/jidctint.c
+++ b/Source/LibJPEG/jidctint.c
@@ -2,7 +2,7 @@
  * jidctint.c
  *
  * Copyright (C) 1991-1998, Thomas G. Lane.
- * Modification developed 2002-2009 by Guido Vollbeding.
+ * Modification developed 2002-2013 by Guido Vollbeding.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
@@ -165,6 +165,8 @@
 
 /*
  * Perform dequantization and inverse DCT on one block of coefficients.
+ *
+ * cK represents sqrt(2) * cos(K*pi/16).
  */
 
 GLOBAL(void)
@@ -184,9 +186,10 @@ jpeg_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr,
   int workspace[DCTSIZE2];	/* buffers data between passes */
   SHIFT_TEMPS
 
-  /* Pass 1: process columns from input, store into work array. */
-  /* Note results are scaled up by sqrt(8) compared to a true IDCT; */
-  /* furthermore, we scale the results by 2**PASS1_BITS. */
+  /* Pass 1: process columns from input, store into work array.
+   * Note results are scaled up by sqrt(8) compared to a true IDCT;
+   * furthermore, we scale the results by 2**PASS1_BITS.
+   */
 
   inptr = coef_block;
   quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
@@ -223,15 +226,16 @@ jpeg_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr,
       continue;
     }
 
-    /* Even part: reverse the even part of the forward DCT. */
-    /* The rotator is sqrt(2)*c(-6). */
-    
+    /* Even part: reverse the even part of the forward DCT.
+     * The rotator is c(-6).
+     */
+
     z2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
     z3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
 
-    z1 = MULTIPLY(z2 + z3, FIX_0_541196100);
-    tmp2 = z1 + MULTIPLY(z2, FIX_0_765366865);
-    tmp3 = z1 - MULTIPLY(z3, FIX_1_847759065);
+    z1 = MULTIPLY(z2 + z3, FIX_0_541196100);       /* c6 */
+    tmp2 = z1 + MULTIPLY(z2, FIX_0_765366865);     /* c2-c6 */
+    tmp3 = z1 - MULTIPLY(z3, FIX_1_847759065);     /* c2+c6 */
 
     z2 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
     z3 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]);
@@ -256,25 +260,25 @@ jpeg_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr,
     tmp1 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
     tmp2 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
     tmp3 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
-    
+
     z2 = tmp0 + tmp2;
     z3 = tmp1 + tmp3;
 
-    z1 = MULTIPLY(z2 + z3, FIX_1_175875602); /* sqrt(2) * c3 */
-    z2 = MULTIPLY(z2, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
-    z3 = MULTIPLY(z3, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
+    z1 = MULTIPLY(z2 + z3, FIX_1_175875602);       /*  c3 */
+    z2 = MULTIPLY(z2, - FIX_1_961570560);          /* -c3-c5 */
+    z3 = MULTIPLY(z3, - FIX_0_390180644);          /* -c3+c5 */
     z2 += z1;
     z3 += z1;
 
-    z1 = MULTIPLY(tmp0 + tmp3, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
-    tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
-    tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
+    z1 = MULTIPLY(tmp0 + tmp3, - FIX_0_899976223); /* -c3+c7 */
+    tmp0 = MULTIPLY(tmp0, FIX_0_298631336);        /* -c1+c3+c5-c7 */
+    tmp3 = MULTIPLY(tmp3, FIX_1_501321110);        /*  c1+c3-c5-c7 */
     tmp0 += z1 + z2;
     tmp3 += z1 + z3;
 
-    z1 = MULTIPLY(tmp1 + tmp2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
-    tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
-    tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
+    z1 = MULTIPLY(tmp1 + tmp2, - FIX_2_562915447); /* -c1-c3 */
+    tmp1 = MULTIPLY(tmp1, FIX_2_053119869);        /*  c1+c3-c5+c7 */
+    tmp2 = MULTIPLY(tmp2, FIX_3_072711026);        /*  c1+c3+c5-c7 */
     tmp1 += z1 + z3;
     tmp2 += z1 + z2;
 
@@ -288,15 +292,16 @@ jpeg_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr,
     wsptr[DCTSIZE*5] = (int) RIGHT_SHIFT(tmp12 - tmp1, CONST_BITS-PASS1_BITS);
     wsptr[DCTSIZE*3] = (int) RIGHT_SHIFT(tmp13 + tmp0, CONST_BITS-PASS1_BITS);
     wsptr[DCTSIZE*4] = (int) RIGHT_SHIFT(tmp13 - tmp0, CONST_BITS-PASS1_BITS);
-    
+
     inptr++;			/* advance pointers to next column */
     quantptr++;
     wsptr++;
   }
 
-  /* Pass 2: process rows from work array, store into output array. */
-  /* Note that we must descale the results by a factor of 8 == 2**3, */
-  /* and also undo the PASS1_BITS scaling. */
+  /* Pass 2: process rows from work array, store into output array.
+   * Note that we must descale the results by a factor of 8 == 2**3,
+   * and also undo the PASS1_BITS scaling.
+   */
 
   wsptr = workspace;
   for (ctr = 0; ctr < DCTSIZE; ctr++) {
@@ -330,15 +335,16 @@ jpeg_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr,
     }
 #endif
 
-    /* Even part: reverse the even part of the forward DCT. */
-    /* The rotator is sqrt(2)*c(-6). */
-    
+    /* Even part: reverse the even part of the forward DCT.
+     * The rotator is c(-6).
+     */
+
     z2 = (INT32) wsptr[2];
     z3 = (INT32) wsptr[6];
 
-    z1 = MULTIPLY(z2 + z3, FIX_0_541196100);
-    tmp2 = z1 + MULTIPLY(z2, FIX_0_765366865);
-    tmp3 = z1 - MULTIPLY(z3, FIX_1_847759065);
+    z1 = MULTIPLY(z2 + z3, FIX_0_541196100);       /* c6 */
+    tmp2 = z1 + MULTIPLY(z2, FIX_0_765366865);     /* c2-c6 */
+    tmp3 = z1 - MULTIPLY(z3, FIX_1_847759065);     /* c2+c6 */
 
     /* Add fudge factor here for final descale. */
     z2 = (INT32) wsptr[0] + (ONE << (PASS1_BITS+2));
@@ -346,7 +352,7 @@ jpeg_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr,
 
     tmp0 = (z2 + z3) << CONST_BITS;
     tmp1 = (z2 - z3) << CONST_BITS;
-    
+
     tmp10 = tmp0 + tmp2;
     tmp13 = tmp0 - tmp2;
     tmp11 = tmp1 + tmp3;
@@ -364,21 +370,21 @@ jpeg_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr,
     z2 = tmp0 + tmp2;
     z3 = tmp1 + tmp3;
 
-    z1 = MULTIPLY(z2 + z3, FIX_1_175875602); /* sqrt(2) * c3 */
-    z2 = MULTIPLY(z2, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
-    z3 = MULTIPLY(z3, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
+    z1 = MULTIPLY(z2 + z3, FIX_1_175875602);       /*  c3 */
+    z2 = MULTIPLY(z2, - FIX_1_961570560);          /* -c3-c5 */
+    z3 = MULTIPLY(z3, - FIX_0_390180644);          /* -c3+c5 */
     z2 += z1;
     z3 += z1;
 
-    z1 = MULTIPLY(tmp0 + tmp3, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
-    tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
-    tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
+    z1 = MULTIPLY(tmp0 + tmp3, - FIX_0_899976223); /* -c3+c7 */
+    tmp0 = MULTIPLY(tmp0, FIX_0_298631336);        /* -c1+c3+c5-c7 */
+    tmp3 = MULTIPLY(tmp3, FIX_1_501321110);        /*  c1+c3-c5-c7 */
     tmp0 += z1 + z2;
     tmp3 += z1 + z3;
 
-    z1 = MULTIPLY(tmp1 + tmp2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
-    tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
-    tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
+    z1 = MULTIPLY(tmp1 + tmp2, - FIX_2_562915447); /* -c1-c3 */
+    tmp1 = MULTIPLY(tmp1, FIX_2_053119869);        /*  c1+c3-c5+c7 */
+    tmp2 = MULTIPLY(tmp2, FIX_3_072711026);        /*  c1+c3+c5-c7 */
     tmp1 += z1 + z3;
     tmp2 += z1 + z2;
 
@@ -2835,9 +2841,11 @@ jpeg_idct_16x8 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
   int workspace[8*8];	/* buffers data between passes */
   SHIFT_TEMPS
 
-  /* Pass 1: process columns from input, store into work array. */
-  /* Note results are scaled up by sqrt(8) compared to a true IDCT; */
-  /* furthermore, we scale the results by 2**PASS1_BITS. */
+  /* Pass 1: process columns from input, store into work array.
+   * Note results are scaled up by sqrt(8) compared to a true IDCT;
+   * furthermore, we scale the results by 2**PASS1_BITS.
+   * 8-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/16).
+   */
 
   inptr = coef_block;
   quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
@@ -2851,14 +2859,14 @@ jpeg_idct_16x8 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
      * With typical images and quantization tables, half or more of the
      * column DCT calculations can be simplified this way.
      */
-    
+
     if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
 	inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 &&
 	inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 &&
 	inptr[DCTSIZE*7] == 0) {
       /* AC terms all zero */
       int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS;
-      
+
       wsptr[DCTSIZE*0] = dcval;
       wsptr[DCTSIZE*1] = dcval;
       wsptr[DCTSIZE*2] = dcval;
@@ -2867,23 +2875,24 @@ jpeg_idct_16x8 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
       wsptr[DCTSIZE*5] = dcval;
       wsptr[DCTSIZE*6] = dcval;
       wsptr[DCTSIZE*7] = dcval;
-      
+
       inptr++;			/* advance pointers to next column */
       quantptr++;
       wsptr++;
       continue;
     }
-    
-    /* Even part: reverse the even part of the forward DCT. */
-    /* The rotator is sqrt(2)*c(-6). */
-    
+
+    /* Even part: reverse the even part of the forward DCT.
+     * The rotator is c(-6).
+     */
+
     z2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
     z3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
-    
-    z1 = MULTIPLY(z2 + z3, FIX_0_541196100);
-    tmp2 = z1 + MULTIPLY(z2, FIX_0_765366865);
-    tmp3 = z1 - MULTIPLY(z3, FIX_1_847759065);
-    
+
+    z1 = MULTIPLY(z2 + z3, FIX_0_541196100);       /* c6 */
+    tmp2 = z1 + MULTIPLY(z2, FIX_0_765366865);     /* c2-c6 */
+    tmp3 = z1 - MULTIPLY(z3, FIX_1_847759065);     /* c2+c6 */
+
     z2 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
     z3 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]);
     z2 <<= CONST_BITS;
@@ -2893,44 +2902,44 @@ jpeg_idct_16x8 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
 
     tmp0 = z2 + z3;
     tmp1 = z2 - z3;
-    
+
     tmp10 = tmp0 + tmp2;
     tmp13 = tmp0 - tmp2;
     tmp11 = tmp1 + tmp3;
     tmp12 = tmp1 - tmp3;
-    
+
     /* Odd part per figure 8; the matrix is unitary and hence its
      * transpose is its inverse.  i0..i3 are y7,y5,y3,y1 respectively.
      */
-    
+
     tmp0 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
     tmp1 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
     tmp2 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
     tmp3 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
-    
+
     z2 = tmp0 + tmp2;
     z3 = tmp1 + tmp3;
 
-    z1 = MULTIPLY(z2 + z3, FIX_1_175875602); /* sqrt(2) * c3 */
-    z2 = MULTIPLY(z2, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
-    z3 = MULTIPLY(z3, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
+    z1 = MULTIPLY(z2 + z3, FIX_1_175875602);       /*  c3 */
+    z2 = MULTIPLY(z2, - FIX_1_961570560);          /* -c3-c5 */
+    z3 = MULTIPLY(z3, - FIX_0_390180644);          /* -c3+c5 */
     z2 += z1;
     z3 += z1;
 
-    z1 = MULTIPLY(tmp0 + tmp3, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
-    tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
-    tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
+    z1 = MULTIPLY(tmp0 + tmp3, - FIX_0_899976223); /* -c3+c7 */
+    tmp0 = MULTIPLY(tmp0, FIX_0_298631336);        /* -c1+c3+c5-c7 */
+    tmp3 = MULTIPLY(tmp3, FIX_1_501321110);        /*  c1+c3-c5-c7 */
     tmp0 += z1 + z2;
     tmp3 += z1 + z3;
 
-    z1 = MULTIPLY(tmp1 + tmp2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
-    tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
-    tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
+    z1 = MULTIPLY(tmp1 + tmp2, - FIX_2_562915447); /* -c1-c3 */
+    tmp1 = MULTIPLY(tmp1, FIX_2_053119869);        /*  c1+c3-c5+c7 */
+    tmp2 = MULTIPLY(tmp2, FIX_3_072711026);        /*  c1+c3+c5-c7 */
     tmp1 += z1 + z3;
     tmp2 += z1 + z2;
-    
+
     /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
-    
+
     wsptr[DCTSIZE*0] = (int) RIGHT_SHIFT(tmp10 + tmp3, CONST_BITS-PASS1_BITS);
     wsptr[DCTSIZE*7] = (int) RIGHT_SHIFT(tmp10 - tmp3, CONST_BITS-PASS1_BITS);
     wsptr[DCTSIZE*1] = (int) RIGHT_SHIFT(tmp11 + tmp2, CONST_BITS-PASS1_BITS);
@@ -2939,7 +2948,7 @@ jpeg_idct_16x8 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
     wsptr[DCTSIZE*5] = (int) RIGHT_SHIFT(tmp12 - tmp1, CONST_BITS-PASS1_BITS);
     wsptr[DCTSIZE*3] = (int) RIGHT_SHIFT(tmp13 + tmp0, CONST_BITS-PASS1_BITS);
     wsptr[DCTSIZE*4] = (int) RIGHT_SHIFT(tmp13 - tmp0, CONST_BITS-PASS1_BITS);
-    
+
     inptr++;			/* advance pointers to next column */
     quantptr++;
     wsptr++;
@@ -2948,6 +2957,7 @@ jpeg_idct_16x8 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
   /* Pass 2: process 8 rows from work array, store into output array.
    * 16-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/32).
    */
+
   wsptr = workspace;
   for (ctr = 0; ctr < 8; ctr++) {
     outptr = output_buf[ctr] + output_col;
@@ -3109,6 +3119,7 @@ jpeg_idct_14x7 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
   /* Pass 1: process columns from input, store into work array.
    * 7-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/14).
    */
+
   inptr = coef_block;
   quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
   wsptr = workspace;
@@ -3164,6 +3175,7 @@ jpeg_idct_14x7 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
   /* Pass 2: process 7 rows from work array, store into output array.
    * 14-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/28).
    */
+
   wsptr = workspace;
   for (ctr = 0; ctr < 7; ctr++) {
     outptr = output_buf[ctr] + output_col;
@@ -3304,6 +3316,7 @@ jpeg_idct_12x6 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
   /* Pass 1: process columns from input, store into work array.
    * 6-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/12).
    */
+
   inptr = coef_block;
   quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
   wsptr = workspace;
@@ -3346,6 +3359,7 @@ jpeg_idct_12x6 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
   /* Pass 2: process 6 rows from work array, store into output array.
    * 12-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/24).
    */
+
   wsptr = workspace;
   for (ctr = 0; ctr < 6; ctr++) {
     outptr = output_buf[ctr] + output_col;
@@ -3480,6 +3494,7 @@ jpeg_idct_10x5 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
   /* Pass 1: process columns from input, store into work array.
    * 5-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/10).
    */
+
   inptr = coef_block;
   quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
   wsptr = workspace;
@@ -3520,6 +3535,7 @@ jpeg_idct_10x5 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
   /* Pass 2: process 5 rows from work array, store into output array.
    * 10-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/20).
    */
+
   wsptr = workspace;
   for (ctr = 0; ctr < 5; ctr++) {
     outptr = output_buf[ctr] + output_col;
@@ -3639,8 +3655,10 @@ jpeg_idct_8x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
   SHIFT_TEMPS
 
   /* Pass 1: process columns from input, store into work array.
-   * 4-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/16).
+   * 4-point IDCT kernel,
+   * cK represents sqrt(2) * cos(K*pi/16) [refers to 8-point IDCT].
    */
+
   inptr = coef_block;
   quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
   wsptr = workspace;
@@ -3675,31 +3693,34 @@ jpeg_idct_8x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
     wsptr[8*2] = (int) (tmp12 - tmp2);
   }
 
-  /* Pass 2: process rows from work array, store into output array. */
-  /* Note that we must descale the results by a factor of 8 == 2**3, */
-  /* and also undo the PASS1_BITS scaling. */
+  /* Pass 2: process rows from work array, store into output array.
+   * Note that we must descale the results by a factor of 8 == 2**3,
+   * and also undo the PASS1_BITS scaling.
+   * 8-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/16).
+   */
 
   wsptr = workspace;
   for (ctr = 0; ctr < 4; ctr++) {
     outptr = output_buf[ctr] + output_col;
 
-    /* Even part: reverse the even part of the forward DCT. */
-    /* The rotator is sqrt(2)*c(-6). */
+    /* Even part: reverse the even part of the forward DCT.
+     * The rotator is c(-6).
+     */
 
     z2 = (INT32) wsptr[2];
     z3 = (INT32) wsptr[6];
-    
-    z1 = MULTIPLY(z2 + z3, FIX_0_541196100);
-    tmp2 = z1 + MULTIPLY(z2, FIX_0_765366865);
-    tmp3 = z1 - MULTIPLY(z3, FIX_1_847759065);
-    
+
+    z1 = MULTIPLY(z2 + z3, FIX_0_541196100);       /* c6 */
+    tmp2 = z1 + MULTIPLY(z2, FIX_0_765366865);     /* c2-c6 */
+    tmp3 = z1 - MULTIPLY(z3, FIX_1_847759065);     /* c2+c6 */
+
     /* Add fudge factor here for final descale. */
     z2 = (INT32) wsptr[0] + (ONE << (PASS1_BITS+2));
     z3 = (INT32) wsptr[4];
-    
+
     tmp0 = (z2 + z3) << CONST_BITS;
     tmp1 = (z2 - z3) << CONST_BITS;
-    
+
     tmp10 = tmp0 + tmp2;
     tmp13 = tmp0 - tmp2;
     tmp11 = tmp1 + tmp3;
@@ -3717,21 +3738,21 @@ jpeg_idct_8x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
     z2 = tmp0 + tmp2;
     z3 = tmp1 + tmp3;
 
-    z1 = MULTIPLY(z2 + z3, FIX_1_175875602); /* sqrt(2) * c3 */
-    z2 = MULTIPLY(z2, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
-    z3 = MULTIPLY(z3, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
+    z1 = MULTIPLY(z2 + z3, FIX_1_175875602);       /*  c3 */
+    z2 = MULTIPLY(z2, - FIX_1_961570560);          /* -c3-c5 */
+    z3 = MULTIPLY(z3, - FIX_0_390180644);          /* -c3+c5 */
     z2 += z1;
     z3 += z1;
 
-    z1 = MULTIPLY(tmp0 + tmp3, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
-    tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
-    tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
+    z1 = MULTIPLY(tmp0 + tmp3, - FIX_0_899976223); /* -c3+c7 */
+    tmp0 = MULTIPLY(tmp0, FIX_0_298631336);        /* -c1+c3+c5-c7 */
+    tmp3 = MULTIPLY(tmp3, FIX_1_501321110);        /*  c1+c3-c5-c7 */
     tmp0 += z1 + z2;
     tmp3 += z1 + z3;
 
-    z1 = MULTIPLY(tmp1 + tmp2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
-    tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
-    tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
+    z1 = MULTIPLY(tmp1 + tmp2, - FIX_2_562915447); /* -c1-c3 */
+    tmp1 = MULTIPLY(tmp1, FIX_2_053119869);        /*  c1+c3-c5+c7 */
+    tmp2 = MULTIPLY(tmp2, FIX_3_072711026);        /*  c1+c3+c5-c7 */
     tmp1 += z1 + z3;
     tmp2 += z1 + z2;
 
@@ -3793,6 +3814,7 @@ jpeg_idct_6x3 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
   /* Pass 1: process columns from input, store into work array.
    * 3-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/6).
    */
+
   inptr = coef_block;
   quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
   wsptr = workspace;
@@ -3823,6 +3845,7 @@ jpeg_idct_6x3 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
   /* Pass 2: process 3 rows from work array, store into output array.
    * 6-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/12).
    */
+
   wsptr = workspace;
   for (ctr = 0; ctr < 3; ctr++) {
     outptr = output_buf[ctr] + output_col;
@@ -3924,6 +3947,7 @@ jpeg_idct_4x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
    * 4-point IDCT kernel,
    * cK represents sqrt(2) * cos(K*pi/16) [refers to 8-point IDCT].
    */
+
   wsptr = workspace;
   for (ctr = 0; ctr < 2; ctr++) {
     outptr = output_buf[ctr] + output_col;
@@ -3979,7 +4003,7 @@ jpeg_idct_2x1 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
 	       JCOEFPTR coef_block,
 	       JSAMPARRAY output_buf, JDIMENSION output_col)
 {
-  INT32 tmp0, tmp10;
+  INT32 tmp0, tmp1;
   ISLOW_MULT_TYPE * quantptr;
   JSAMPROW outptr;
   JSAMPLE *range_limit = IDCT_range_limit(cinfo);
@@ -3994,18 +4018,18 @@ jpeg_idct_2x1 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
 
   /* Even part */
 
-  tmp10 = DEQUANTIZE(coef_block[0], quantptr[0]);
+  tmp0 = DEQUANTIZE(coef_block[0], quantptr[0]);
   /* Add fudge factor here for final descale. */
-  tmp10 += ONE << 2;
+  tmp0 += ONE << 2;
 
   /* Odd part */
 
-  tmp0 = DEQUANTIZE(coef_block[1], quantptr[1]);
+  tmp1 = DEQUANTIZE(coef_block[1], quantptr[1]);
 
   /* Final output stage */
 
-  outptr[0] = range_limit[(int) RIGHT_SHIFT(tmp10 + tmp0, 3) & RANGE_MASK];
-  outptr[1] = range_limit[(int) RIGHT_SHIFT(tmp10 - tmp0, 3) & RANGE_MASK];
+  outptr[0] = range_limit[(int) RIGHT_SHIFT(tmp0 + tmp1, 3) & RANGE_MASK];
+  outptr[1] = range_limit[(int) RIGHT_SHIFT(tmp0 - tmp1, 3) & RANGE_MASK];
 }
 
 
@@ -4036,6 +4060,7 @@ jpeg_idct_8x16 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
   /* Pass 1: process columns from input, store into work array.
    * 16-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/32).
    */
+
   inptr = coef_block;
   quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
   wsptr = workspace;
@@ -4134,69 +4159,72 @@ jpeg_idct_8x16 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
     wsptr[8*7]  = (int) RIGHT_SHIFT(tmp27 + tmp13, CONST_BITS-PASS1_BITS);
     wsptr[8*8]  = (int) RIGHT_SHIFT(tmp27 - tmp13, CONST_BITS-PASS1_BITS);
   }
-  
-  /* Pass 2: process rows from work array, store into output array. */
-  /* Note that we must descale the results by a factor of 8 == 2**3, */
-  /* and also undo the PASS1_BITS scaling. */
+
+  /* Pass 2: process rows from work array, store into output array.
+   * Note that we must descale the results by a factor of 8 == 2**3,
+   * and also undo the PASS1_BITS scaling.
+   * 8-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/16).
+   */
 
   wsptr = workspace;
   for (ctr = 0; ctr < 16; ctr++) {
     outptr = output_buf[ctr] + output_col;
-    
-    /* Even part: reverse the even part of the forward DCT. */
-    /* The rotator is sqrt(2)*c(-6). */
-    
+
+    /* Even part: reverse the even part of the forward DCT.
+     * The rotator is c(-6).
+     */
+
     z2 = (INT32) wsptr[2];
     z3 = (INT32) wsptr[6];
-    
-    z1 = MULTIPLY(z2 + z3, FIX_0_541196100);
-    tmp2 = z1 + MULTIPLY(z2, FIX_0_765366865);
-    tmp3 = z1 - MULTIPLY(z3, FIX_1_847759065);
-    
+
+    z1 = MULTIPLY(z2 + z3, FIX_0_541196100);       /* c6 */
+    tmp2 = z1 + MULTIPLY(z2, FIX_0_765366865);     /* c2-c6 */
+    tmp3 = z1 - MULTIPLY(z3, FIX_1_847759065);     /* c2+c6 */
+
     /* Add fudge factor here for final descale. */
     z2 = (INT32) wsptr[0] + (ONE << (PASS1_BITS+2));
     z3 = (INT32) wsptr[4];
-    
+
     tmp0 = (z2 + z3) << CONST_BITS;
     tmp1 = (z2 - z3) << CONST_BITS;
-    
+
     tmp10 = tmp0 + tmp2;
     tmp13 = tmp0 - tmp2;
     tmp11 = tmp1 + tmp3;
     tmp12 = tmp1 - tmp3;
-    
+
     /* Odd part per figure 8; the matrix is unitary and hence its
      * transpose is its inverse.  i0..i3 are y7,y5,y3,y1 respectively.
      */
-    
+
     tmp0 = (INT32) wsptr[7];
     tmp1 = (INT32) wsptr[5];
     tmp2 = (INT32) wsptr[3];
     tmp3 = (INT32) wsptr[1];
-    
+
     z2 = tmp0 + tmp2;
     z3 = tmp1 + tmp3;
 
-    z1 = MULTIPLY(z2 + z3, FIX_1_175875602); /* sqrt(2) * c3 */
-    z2 = MULTIPLY(z2, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
-    z3 = MULTIPLY(z3, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
+    z1 = MULTIPLY(z2 + z3, FIX_1_175875602);       /*  c3 */
+    z2 = MULTIPLY(z2, - FIX_1_961570560);          /* -c3-c5 */
+    z3 = MULTIPLY(z3, - FIX_0_390180644);          /* -c3+c5 */
     z2 += z1;
     z3 += z1;
 
-    z1 = MULTIPLY(tmp0 + tmp3, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
-    tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
-    tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
+    z1 = MULTIPLY(tmp0 + tmp3, - FIX_0_899976223); /* -c3+c7 */
+    tmp0 = MULTIPLY(tmp0, FIX_0_298631336);        /* -c1+c3+c5-c7 */
+    tmp3 = MULTIPLY(tmp3, FIX_1_501321110);        /*  c1+c3-c5-c7 */
     tmp0 += z1 + z2;
     tmp3 += z1 + z3;
 
-    z1 = MULTIPLY(tmp1 + tmp2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
-    tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
-    tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
+    z1 = MULTIPLY(tmp1 + tmp2, - FIX_2_562915447); /* -c1-c3 */
+    tmp1 = MULTIPLY(tmp1, FIX_2_053119869);        /*  c1+c3-c5+c7 */
+    tmp2 = MULTIPLY(tmp2, FIX_3_072711026);        /*  c1+c3+c5-c7 */
     tmp1 += z1 + z3;
     tmp2 += z1 + z2;
-    
+
     /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
-    
+
     outptr[0] = range_limit[(int) RIGHT_SHIFT(tmp10 + tmp3,
 					      CONST_BITS+PASS1_BITS+3)
 			    & RANGE_MASK];
@@ -4221,7 +4249,7 @@ jpeg_idct_8x16 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
     outptr[4] = range_limit[(int) RIGHT_SHIFT(tmp13 - tmp0,
 					      CONST_BITS+PASS1_BITS+3)
 			    & RANGE_MASK];
-    
+
     wsptr += DCTSIZE;		/* advance pointer to next row */
   }
 }
@@ -4254,6 +4282,7 @@ jpeg_idct_7x14 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
   /* Pass 1: process columns from input, store into work array.
    * 14-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/28).
    */
+
   inptr = coef_block;
   quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
   wsptr = workspace;
@@ -4341,6 +4370,7 @@ jpeg_idct_7x14 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
   /* Pass 2: process 14 rows from work array, store into output array.
    * 7-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/14).
    */
+
   wsptr = workspace;
   for (ctr = 0; ctr < 14; ctr++) {
     outptr = output_buf[ctr] + output_col;
@@ -4437,6 +4467,7 @@ jpeg_idct_6x12 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
   /* Pass 1: process columns from input, store into work array.
    * 12-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/24).
    */
+
   inptr = coef_block;
   quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
   wsptr = workspace;
@@ -4520,6 +4551,7 @@ jpeg_idct_6x12 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
   /* Pass 2: process 12 rows from work array, store into output array.
    * 6-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/12).
    */
+
   wsptr = workspace;
   for (ctr = 0; ctr < 12; ctr++) {
     outptr = output_buf[ctr] + output_col;
@@ -4601,6 +4633,7 @@ jpeg_idct_5x10 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
   /* Pass 1: process columns from input, store into work array.
    * 10-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/20).
    */
+
   inptr = coef_block;
   quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
   wsptr = workspace;
@@ -4676,6 +4709,7 @@ jpeg_idct_5x10 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
   /* Pass 2: process 10 rows from work array, store into output array.
    * 5-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/10).
    */
+
   wsptr = workspace;
   for (ctr = 0; ctr < 10; ctr++) {
     outptr = output_buf[ctr] + output_col;
@@ -4750,9 +4784,11 @@ jpeg_idct_4x8 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
   int workspace[4*8];	/* buffers data between passes */
   SHIFT_TEMPS
 
-  /* Pass 1: process columns from input, store into work array. */
-  /* Note results are scaled up by sqrt(8) compared to a true IDCT; */
-  /* furthermore, we scale the results by 2**PASS1_BITS. */
+  /* Pass 1: process columns from input, store into work array.
+   * Note results are scaled up by sqrt(8) compared to a true IDCT;
+   * furthermore, we scale the results by 2**PASS1_BITS.
+   * 8-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/16).
+   */
 
   inptr = coef_block;
   quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
@@ -4789,16 +4825,17 @@ jpeg_idct_4x8 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
       continue;
     }
 
-    /* Even part: reverse the even part of the forward DCT. */
-    /* The rotator is sqrt(2)*c(-6). */
+    /* Even part: reverse the even part of the forward DCT.
+     * The rotator is c(-6).
+     */
 
     z2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
     z3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
-    
-    z1 = MULTIPLY(z2 + z3, FIX_0_541196100);
-    tmp2 = z1 + MULTIPLY(z2, FIX_0_765366865);
-    tmp3 = z1 - MULTIPLY(z3, FIX_1_847759065);
-    
+
+    z1 = MULTIPLY(z2 + z3, FIX_0_541196100);       /* c6 */
+    tmp2 = z1 + MULTIPLY(z2, FIX_0_765366865);     /* c2-c6 */
+    tmp3 = z1 - MULTIPLY(z3, FIX_1_847759065);     /* c2+c6 */
+
     z2 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
     z3 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]);
     z2 <<= CONST_BITS;
@@ -4808,7 +4845,7 @@ jpeg_idct_4x8 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
 
     tmp0 = z2 + z3;
     tmp1 = z2 - z3;
-    
+
     tmp10 = tmp0 + tmp2;
     tmp13 = tmp0 - tmp2;
     tmp11 = tmp1 + tmp3;
@@ -4826,21 +4863,21 @@ jpeg_idct_4x8 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
     z2 = tmp0 + tmp2;
     z3 = tmp1 + tmp3;
 
-    z1 = MULTIPLY(z2 + z3, FIX_1_175875602); /* sqrt(2) * c3 */
-    z2 = MULTIPLY(z2, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
-    z3 = MULTIPLY(z3, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
+    z1 = MULTIPLY(z2 + z3, FIX_1_175875602);       /*  c3 */
+    z2 = MULTIPLY(z2, - FIX_1_961570560);          /* -c3-c5 */
+    z3 = MULTIPLY(z3, - FIX_0_390180644);          /* -c3+c5 */
     z2 += z1;
     z3 += z1;
 
-    z1 = MULTIPLY(tmp0 + tmp3, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
-    tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
-    tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
+    z1 = MULTIPLY(tmp0 + tmp3, - FIX_0_899976223); /* -c3+c7 */
+    tmp0 = MULTIPLY(tmp0, FIX_0_298631336);        /* -c1+c3+c5-c7 */
+    tmp3 = MULTIPLY(tmp3, FIX_1_501321110);        /*  c1+c3-c5-c7 */
     tmp0 += z1 + z2;
     tmp3 += z1 + z3;
 
-    z1 = MULTIPLY(tmp1 + tmp2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
-    tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
-    tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
+    z1 = MULTIPLY(tmp1 + tmp2, - FIX_2_562915447); /* -c1-c3 */
+    tmp1 = MULTIPLY(tmp1, FIX_2_053119869);        /*  c1+c3-c5+c7 */
+    tmp2 = MULTIPLY(tmp2, FIX_3_072711026);        /*  c1+c3+c5-c7 */
     tmp1 += z1 + z3;
     tmp2 += z1 + z2;
 
@@ -4861,8 +4898,10 @@ jpeg_idct_4x8 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
   }
 
   /* Pass 2: process 8 rows from work array, store into output array.
-   * 4-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/16).
+   * 4-point IDCT kernel,
+   * cK represents sqrt(2) * cos(K*pi/16) [refers to 8-point IDCT].
    */
+
   wsptr = workspace;
   for (ctr = 0; ctr < 8; ctr++) {
     outptr = output_buf[ctr] + output_col;
@@ -4900,7 +4939,7 @@ jpeg_idct_4x8 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
     outptr[2] = range_limit[(int) RIGHT_SHIFT(tmp12 - tmp2,
 					      CONST_BITS+PASS1_BITS+3)
 			    & RANGE_MASK];
-    
+
     wsptr += 4;		/* advance pointer to next row */
   }
 }
@@ -4932,6 +4971,7 @@ jpeg_idct_3x6 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
   /* Pass 1: process columns from input, store into work array.
    * 6-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/12).
    */
+
   inptr = coef_block;
   quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
   wsptr = workspace;
@@ -4974,6 +5014,7 @@ jpeg_idct_3x6 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
   /* Pass 2: process 6 rows from work array, store into output array.
    * 3-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/6).
    */
+
   wsptr = workspace;
   for (ctr = 0; ctr < 6; ctr++) {
     outptr = output_buf[ctr] + output_col;
@@ -5037,6 +5078,7 @@ jpeg_idct_2x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
    * 4-point IDCT kernel,
    * cK represents sqrt(2) * cos(K*pi/16) [refers to 8-point IDCT].
    */
+
   inptr = coef_block;
   quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
   wsptr = workspace;
@@ -5106,7 +5148,7 @@ jpeg_idct_1x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
 	       JCOEFPTR coef_block,
 	       JSAMPARRAY output_buf, JDIMENSION output_col)
 {
-  INT32 tmp0, tmp10;
+  INT32 tmp0, tmp1;
   ISLOW_MULT_TYPE * quantptr;
   JSAMPLE *range_limit = IDCT_range_limit(cinfo);
   SHIFT_TEMPS
@@ -5117,19 +5159,19 @@ jpeg_idct_1x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
 
   /* Even part */
     
-  tmp10 = DEQUANTIZE(coef_block[DCTSIZE*0], quantptr[DCTSIZE*0]);
+  tmp0 = DEQUANTIZE(coef_block[DCTSIZE*0], quantptr[DCTSIZE*0]);
   /* Add fudge factor here for final descale. */
-  tmp10 += ONE << 2;
+  tmp0 += ONE << 2;
 
   /* Odd part */
 
-  tmp0 = DEQUANTIZE(coef_block[DCTSIZE*1], quantptr[DCTSIZE*1]);
+  tmp1 = DEQUANTIZE(coef_block[DCTSIZE*1], quantptr[DCTSIZE*1]);
 
   /* Final output stage */
 
-  output_buf[0][output_col] = range_limit[(int) RIGHT_SHIFT(tmp10 + tmp0, 3)
+  output_buf[0][output_col] = range_limit[(int) RIGHT_SHIFT(tmp0 + tmp1, 3)
 					  & RANGE_MASK];
-  output_buf[1][output_col] = range_limit[(int) RIGHT_SHIFT(tmp10 - tmp0, 3)
+  output_buf[1][output_col] = range_limit[(int) RIGHT_SHIFT(tmp0 - tmp1, 3)
 					  & RANGE_MASK];
 }
 
diff --git a/Source/LibJPEG/jmemmgr.c b/Source/LibJPEG/jmemmgr.c
index f0e83fb..0a137cd 100644
--- a/Source/LibJPEG/jmemmgr.c
+++ b/Source/LibJPEG/jmemmgr.c
@@ -2,7 +2,7 @@
  * jmemmgr.c
  *
  * Copyright (C) 1991-1997, Thomas G. Lane.
- * Modified 2011 by Guido Vollbeding.
+ * Modified 2011-2012 by Guido Vollbeding.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
@@ -214,7 +214,7 @@ print_mem_stats (j_common_ptr cinfo, int pool_id)
 #endif /* MEM_STATS */
 
 
-LOCAL(void)
+LOCAL(noreturn_t)
 out_of_memory (j_common_ptr cinfo, int which)
 /* Report an out-of-memory error and stop execution */
 /* If we compiled MEM_STATS support, report alloc requests before dying */
diff --git a/Source/LibJPEG/jmorecfg.h b/Source/LibJPEG/jmorecfg.h
index 6c085c3..61949b6 100644
--- a/Source/LibJPEG/jmorecfg.h
+++ b/Source/LibJPEG/jmorecfg.h
@@ -2,7 +2,7 @@
  * jmorecfg.h
  *
  * Copyright (C) 1991-1997, Thomas G. Lane.
- * Modified 1997-2011 by Guido Vollbeding.
+ * Modified 1997-2013 by Guido Vollbeding.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
@@ -15,13 +15,22 @@
 /*
  * Define BITS_IN_JSAMPLE as either
  *   8   for 8-bit sample values (the usual setting)
+ *   9   for 9-bit sample values
+ *   10  for 10-bit sample values
+ *   11  for 11-bit sample values
  *   12  for 12-bit sample values
- * Only 8 and 12 are legal data precisions for lossy JPEG according to the
- * JPEG standard, and the IJG code does not support anything else!
- * We do not support run-time selection of data precision, sorry.
+ * Only 8, 9, 10, 11, and 12 bits sample data precision are supported for
+ * full-feature DCT processing.  Further depths up to 16-bit may be added
+ * later for the lossless modes of operation.
+ * Run-time selection and conversion of data precision will be added later
+ * and are currently not supported, sorry.
+ * Exception:  The transcoding part (jpegtran) supports all settings in a
+ * single instance, since it operates on the level of DCT coefficients and
+ * not sample values.  The DCT coefficients are of the same type (16 bits)
+ * in all cases (see below).
  */
 
-#define BITS_IN_JSAMPLE  8	/* use 8 or 12 */
+#define BITS_IN_JSAMPLE  8	/* use 8, 9, 10, 11, or 12 */
 
 
 /*
@@ -77,6 +86,48 @@ typedef char JSAMPLE;
 #endif /* BITS_IN_JSAMPLE == 8 */
 
 
+#if BITS_IN_JSAMPLE == 9
+/* JSAMPLE should be the smallest type that will hold the values 0..511.
+ * On nearly all machines "short" will do nicely.
+ */
+
+typedef short JSAMPLE;
+#define GETJSAMPLE(value)  ((int) (value))
+
+#define MAXJSAMPLE	511
+#define CENTERJSAMPLE	256
+
+#endif /* BITS_IN_JSAMPLE == 9 */
+
+
+#if BITS_IN_JSAMPLE == 10
+/* JSAMPLE should be the smallest type that will hold the values 0..1023.
+ * On nearly all machines "short" will do nicely.
+ */
+
+typedef short JSAMPLE;
+#define GETJSAMPLE(value)  ((int) (value))
+
+#define MAXJSAMPLE	1023
+#define CENTERJSAMPLE	512
+
+#endif /* BITS_IN_JSAMPLE == 10 */
+
+
+#if BITS_IN_JSAMPLE == 11
+/* JSAMPLE should be the smallest type that will hold the values 0..2047.
+ * On nearly all machines "short" will do nicely.
+ */
+
+typedef short JSAMPLE;
+#define GETJSAMPLE(value)  ((int) (value))
+
+#define MAXJSAMPLE	2047
+#define CENTERJSAMPLE	1024
+
+#endif /* BITS_IN_JSAMPLE == 11 */
+
+
 #if BITS_IN_JSAMPLE == 12
 /* JSAMPLE should be the smallest type that will hold the values 0..4095.
  * On nearly all machines "short" will do nicely.
@@ -210,6 +261,26 @@ typedef unsigned int JDIMENSION;
 #endif
 
 
+/* The noreturn type identifier is used to declare functions
+ * which cannot return.
+ * Compilers can thus create more optimized code and perform
+ * better checks for warnings and errors.
+ * Static analyzer tools can make improved inferences about
+ * execution paths and are prevented from giving false alerts.
+ *
+ * Unfortunately, the proposed specifications of corresponding
+ * extensions in the Dec 2011 ISO C standard revision (C11),
+ * GCC, MSVC, etc. are not viable.
+ * Thus we introduce a user defined type to declare noreturn
+ * functions at least for clarity.  A proper compiler would
+ * have a suitable noreturn type to match in place of void.
+ */
+
+#ifndef HAVE_NORETURN_T
+typedef void noreturn_t;
+#endif
+
+
 /* Here is the pseudo-keyword for declaring pointers that must be "far"
  * on 80x86 machines.  Most of the specialized coding for 80x86 is handled
  * by just saying "FAR *" where such a pointer is needed.  In a few places
@@ -232,15 +303,16 @@ typedef unsigned int JDIMENSION;
  * Defining HAVE_BOOLEAN before including jpeglib.h should make it work.
  */
 
-#ifndef HAVE_BOOLEAN
-typedef int boolean;
-#endif
+#ifdef HAVE_BOOLEAN
 #ifndef FALSE			/* in case these macros already exist */
 #define FALSE	0		/* values of boolean */
 #endif
 #ifndef TRUE
 #define TRUE	1
 #endif
+#else
+typedef enum { FALSE = 0, TRUE = 1 } boolean;
+#endif
 
 
 /*
@@ -278,11 +350,12 @@ typedef int boolean;
 #define C_PROGRESSIVE_SUPPORTED	    /* Progressive JPEG? (Requires MULTISCAN)*/
 #define DCT_SCALING_SUPPORTED	    /* Input rescaling via DCT? (Requires DCT_ISLOW)*/
 #define ENTROPY_OPT_SUPPORTED	    /* Optimization of entropy coding parms? */
-/* Note: if you selected 12-bit data precision, it is dangerous to turn off
- * ENTROPY_OPT_SUPPORTED.  The standard Huffman tables are only good for 8-bit
- * precision, so jchuff.c normally uses entropy optimization to compute
- * usable tables for higher precision.  If you don't want to do optimization,
- * you'll have to supply different default Huffman tables.
+/* Note: if you selected more than 8-bit data precision, it is dangerous to
+ * turn off ENTROPY_OPT_SUPPORTED.  The standard Huffman tables are only
+ * good for 8-bit precision, so arithmetic coding is recommended for higher
+ * precision.  The Huffman encoder normally uses entropy optimization to
+ * compute usable tables for higher precision.  Otherwise, you'll have to
+ * supply different default Huffman tables.
  * The exact same statements apply for progressive JPEG: the default tables
  * don't work for progressive mode.  (This may get fixed, however.)
  */
@@ -293,7 +366,7 @@ typedef int boolean;
 #define D_ARITH_CODING_SUPPORTED    /* Arithmetic coding back end? */
 #define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
 #define D_PROGRESSIVE_SUPPORTED	    /* Progressive JPEG? (Requires MULTISCAN)*/
-#define IDCT_SCALING_SUPPORTED	    /* Output rescaling via IDCT? */
+#define IDCT_SCALING_SUPPORTED	    /* Output rescaling via IDCT? (Requires DCT_ISLOW)*/
 #define SAVE_MARKERS_SUPPORTED	    /* jpeg_save_markers() needed? */
 #define BLOCK_SMOOTHING_SUPPORTED   /* Block smoothing? (Progressive only) */
 #undef  UPSAMPLE_SCALING_SUPPORTED  /* Output rescaling at upsample stage? */
diff --git a/Source/LibJPEG/jpegint.h b/Source/LibJPEG/jpegint.h
index c0d5c14..18bb887 100644
--- a/Source/LibJPEG/jpegint.h
+++ b/Source/LibJPEG/jpegint.h
@@ -2,7 +2,7 @@
  * jpegint.h
  *
  * Copyright (C) 1991-1997, Thomas G. Lane.
- * Modified 1997-2011 by Guido Vollbeding.
+ * Modified 1997-2013 by Guido Vollbeding.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
@@ -211,8 +211,8 @@ struct jpeg_marker_reader {
 /* Entropy decoding */
 struct jpeg_entropy_decoder {
   JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
-  JMETHOD(boolean, decode_mcu, (j_decompress_ptr cinfo,
-				JBLOCKROW *MCU_data));
+  JMETHOD(boolean, decode_mcu, (j_decompress_ptr cinfo, JBLOCKROW *MCU_data));
+  JMETHOD(void, finish_pass, (j_decompress_ptr cinfo));
 };
 
 /* Inverse DCT (also performs dequantization) */
diff --git a/Source/LibJPEG/jpeglib.h b/Source/LibJPEG/jpeglib.h
index 1327cff..f4fbf23 100644
--- a/Source/LibJPEG/jpeglib.h
+++ b/Source/LibJPEG/jpeglib.h
@@ -2,7 +2,7 @@
  * jpeglib.h
  *
  * Copyright (C) 1991-1998, Thomas G. Lane.
- * Modified 2002-2011 by Guido Vollbeding.
+ * Modified 2002-2013 by Guido Vollbeding.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
@@ -34,17 +34,17 @@ extern "C" {
 #endif
 
 /* Version IDs for the JPEG library.
- * Might be useful for tests like "#if JPEG_LIB_VERSION >= 80".
+ * Might be useful for tests like "#if JPEG_LIB_VERSION >= 90".
  */
 
-#define JPEG_LIB_VERSION        80	/* Compatibility version 8.0 */
-#define JPEG_LIB_VERSION_MAJOR  8
-#define JPEG_LIB_VERSION_MINOR  4
+#define JPEG_LIB_VERSION        90	/* Compatibility version 9.0 */
+#define JPEG_LIB_VERSION_MAJOR  9
+#define JPEG_LIB_VERSION_MINOR  1
 
 
 /* Various constants determining the sizes of things.
- * All of these are specified by the JPEG standard, so don't change them
- * if you want to be compatible.
+ * All of these are specified by the JPEG standard,
+ * so don't change them if you want to be compatible.
  */
 
 #define DCTSIZE		    8	/* The basic DCT block is 8x8 coefficients */
@@ -157,16 +157,21 @@ typedef struct {
   /* The downsampled dimensions are the component's actual, unpadded number
    * of samples at the main buffer (preprocessing/compression interface);
    * DCT scaling is included, so
-   * downsampled_width = ceil(image_width * Hi/Hmax * DCT_h_scaled_size/DCTSIZE)
+   * downsampled_width =
+   *   ceil(image_width * Hi/Hmax * DCT_h_scaled_size/block_size)
    * and similarly for height.
    */
   JDIMENSION downsampled_width;	 /* actual width in samples */
   JDIMENSION downsampled_height; /* actual height in samples */
-  /* This flag is used only for decompression.  In cases where some of the
-   * components will be ignored (eg grayscale output from YCbCr image),
-   * we can skip most computations for the unused components.
+  /* For decompression, in cases where some of the components will be
+   * ignored (eg grayscale output from YCbCr image), we can skip most
+   * computations for the unused components.
+   * For compression, some of the components will need further quantization
+   * scale by factor of 2 after DCT (eg BG_YCC output from normal RGB input).
+   * The field is first set TRUE for decompression, FALSE for compression
+   * in initial_setup, and then adapted in color conversion setup.
    */
-  boolean component_needed;	/* do we need the value of this component? */
+  boolean component_needed;
 
   /* These values are computed before starting a scan of the component. */
   /* The decompressor output side may not use these variables. */
@@ -215,12 +220,21 @@ struct jpeg_marker_struct {
 typedef enum {
 	JCS_UNKNOWN,		/* error/unspecified */
 	JCS_GRAYSCALE,		/* monochrome */
-	JCS_RGB,		/* red/green/blue */
-	JCS_YCbCr,		/* Y/Cb/Cr (also known as YUV) */
+	JCS_RGB,		/* red/green/blue, standard RGB (sRGB) */
+	JCS_YCbCr,		/* Y/Cb/Cr (also known as YUV), standard YCC */
 	JCS_CMYK,		/* C/M/Y/K */
-	JCS_YCCK		/* Y/Cb/Cr/K */
+	JCS_YCCK,		/* Y/Cb/Cr/K */
+	JCS_BG_RGB,		/* big gamut red/green/blue, bg-sRGB */
+	JCS_BG_YCC		/* big gamut Y/Cb/Cr, bg-sYCC */
 } J_COLOR_SPACE;
 
+/* Supported color transforms. */
+
+typedef enum {
+	JCT_NONE           = 0,
+	JCT_SUBTRACT_GREEN = 1
+} J_COLOR_TRANSFORM;
+
 /* DCT/IDCT algorithm options. */
 
 typedef enum {
@@ -369,7 +383,10 @@ struct jpeg_compress_struct {
   UINT16 X_density;		/* Horizontal pixel density */
   UINT16 Y_density;		/* Vertical pixel density */
   boolean write_Adobe_marker;	/* should an Adobe marker be written? */
-  
+
+  J_COLOR_TRANSFORM color_transform;
+  /* Color transform identifier, writes LSE marker if nonzero */
+
   /* State variable: index of next scanline to be written to
    * jpeg_write_scanlines().  Application may use this to control its
    * processing loop, e.g., "while (next_scanline < image_height)".
@@ -589,6 +606,9 @@ struct jpeg_decompress_struct {
   boolean saw_Adobe_marker;	/* TRUE iff an Adobe APP14 marker was found */
   UINT8 Adobe_transform;	/* Color transform code from Adobe marker */
 
+  J_COLOR_TRANSFORM color_transform;
+  /* Color transform identifier derived from LSE marker, otherwise zero */
+
   boolean CCIR601_sampling;	/* TRUE=first samples are cosited */
 
   /* Aside from the specific data retained from APPn markers known to the
@@ -681,7 +701,7 @@ struct jpeg_decompress_struct {
 
 struct jpeg_error_mgr {
   /* Error exit handler: does not return to caller */
-  JMETHOD(void, error_exit, (j_common_ptr cinfo));
+  JMETHOD(noreturn_t, error_exit, (j_common_ptr cinfo));
   /* Conditionally emit a trace or warning message */
   JMETHOD(void, emit_message, (j_common_ptr cinfo, int msg_level));
   /* Routine that actually outputs a trace or error message */
diff --git a/Source/LibJPEG/jpegtran.c b/Source/LibJPEG/jpegtran.c
index 2193ffe..f3175ae 100644
--- a/Source/LibJPEG/jpegtran.c
+++ b/Source/LibJPEG/jpegtran.c
@@ -1,7 +1,7 @@
 /*
  * jpegtran.c
  *
- * Copyright (C) 1995-2011, Thomas G. Lane, Guido Vollbeding.
+ * Copyright (C) 1995-2013, Thomas G. Lane, Guido Vollbeding.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
@@ -66,8 +66,8 @@ usage (void)
   fprintf(stderr, "Switches for modifying the image:\n");
 #if TRANSFORMS_SUPPORTED
   fprintf(stderr, "  -crop WxH+X+Y  Crop to a rectangular subarea\n");
-  fprintf(stderr, "  -grayscale     Reduce to grayscale (omit color data)\n");
   fprintf(stderr, "  -flip [horizontal|vertical]  Mirror image (left-right or top-bottom)\n");
+  fprintf(stderr, "  -grayscale     Reduce to grayscale (omit color data)\n");
   fprintf(stderr, "  -perfect       Fail if there is non-transformable edge blocks\n");
   fprintf(stderr, "  -rotate [90|180|270]         Rotate image (degrees clockwise)\n");
 #endif
@@ -76,6 +76,7 @@ usage (void)
   fprintf(stderr, "  -transpose     Transpose image\n");
   fprintf(stderr, "  -transverse    Transverse transpose image\n");
   fprintf(stderr, "  -trim          Drop non-transformable edge blocks\n");
+  fprintf(stderr, "  -wipe WxH+X+Y  Wipe (gray out) a rectangular subarea\n");
 #endif
   fprintf(stderr, "Switches for advanced users:\n");
 #ifdef C_ARITH_CODING_SUPPORTED
@@ -187,7 +188,8 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
 #if TRANSFORMS_SUPPORTED
       if (++argn >= argc)	/* advance to next argument */
 	usage();
-      if (! jtransform_parse_crop_spec(&transformoption, argv[argn])) {
+      if (transformoption.crop /* reject multiple crop/wipe requests */ ||
+	  ! jtransform_parse_crop_spec(&transformoption, argv[argn])) {
 	fprintf(stderr, "%s: bogus -crop argument '%s'\n",
 		progname, argv[argn]);
 	exit(EXIT_FAILURE);
@@ -336,6 +338,21 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
       /* Trim off any partial edge MCUs that the transform can't handle. */
       transformoption.trim = TRUE;
 
+    } else if (keymatch(arg, "wipe", 1)) {
+#if TRANSFORMS_SUPPORTED
+      if (++argn >= argc)	/* advance to next argument */
+	usage();
+      if (transformoption.crop /* reject multiple crop/wipe requests */ ||
+	  ! jtransform_parse_crop_spec(&transformoption, argv[argn])) {
+	fprintf(stderr, "%s: bogus -wipe argument '%s'\n",
+		progname, argv[argn]);
+	exit(EXIT_FAILURE);
+      }
+      select_transform(JXFORM_WIPE);
+#else
+      select_transform(JXFORM_NONE);	/* force an error */
+#endif
+
     } else {
       usage();			/* bogus switch */
     }
@@ -467,7 +484,7 @@ main (int argc, char **argv)
 
   /* Adjust default decompression parameters */
   if (scaleoption != NULL)
-    if (sscanf(scaleoption, "%d/%d",
+    if (sscanf(scaleoption, "%u/%u",
 	&srcinfo.scale_num, &srcinfo.scale_denom) < 1)
       usage();
 
diff --git a/Source/LibJPEG/jversion.h b/Source/LibJPEG/jversion.h
index 5d49151..a6e3ac7 100644
--- a/Source/LibJPEG/jversion.h
+++ b/Source/LibJPEG/jversion.h
@@ -1,7 +1,7 @@
 /*
  * jversion.h
  *
- * Copyright (C) 1991-2012, Thomas G. Lane, Guido Vollbeding.
+ * Copyright (C) 1991-2014, Thomas G. Lane, Guido Vollbeding.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
@@ -9,6 +9,6 @@
  */
 
 
-#define JVERSION	"8d  15-Jan-2012"
+#define JVERSION	"9a  19-Jan-2014"
 
-#define JCOPYRIGHT	"Copyright (C) 2012, Thomas G. Lane, Guido Vollbeding"
+#define JCOPYRIGHT	"Copyright (C) 2014, Thomas G. Lane, Guido Vollbeding"
diff --git a/Source/LibJPEG/libjpeg.txt b/Source/LibJPEG/libjpeg.txt
index 98394c8..b602ab3 100644
--- a/Source/LibJPEG/libjpeg.txt
+++ b/Source/LibJPEG/libjpeg.txt
@@ -1,6 +1,6 @@
 USING THE IJG JPEG LIBRARY
 
-Copyright (C) 1994-2011, Thomas G. Lane, Guido Vollbeding.
+Copyright (C) 1994-2013, Thomas G. Lane, Guido Vollbeding.
 This file is part of the Independent JPEG Group's software.
 For conditions of distribution and use, see the accompanying README file.
 
@@ -95,8 +95,8 @@ use.)  Unsupported ISO options include:
 	* Lossless JPEG
 	* DNL marker
 	* Nonintegral subsampling ratios
-We support both 8- and 12-bit data precision, but this is a compile-time
-choice rather than a run-time choice; hence it is difficult to use both
+We support 8-bit to 12-bit data precision, but this is a compile-time choice
+rather than a run-time choice; hence it is difficult to use different
 precisions in a single application.
 
 By itself, the library handles only interchange JPEG datastreams --- in
@@ -225,7 +225,7 @@ For best results, source data values should have the precision specified by
 BITS_IN_JSAMPLE (normally 8 bits).  For instance, if you choose to compress
 data that's only 6 bits/channel, you should left-justify each value in a
 byte before passing it to the compressor.  If you need to compress data
-that has more than 8 bits/channel, compile with BITS_IN_JSAMPLE = 12.
+that has more than 8 bits/channel, compile with BITS_IN_JSAMPLE = 9 to 12.
 (See "Library compile-time options", later.)
 
 
@@ -876,6 +876,10 @@ jpeg_simple_progression (j_compress_ptr cinfo)
 
 Compression parameters (cinfo fields) include:
 
+boolean arith_code
+	If TRUE, use arithmetic coding.
+	If FALSE, use Huffman coding.
+
 int block_size
 	Set DCT block size.  All N from 1 to 16 are possible.
 	Default is 8 (baseline format).
@@ -916,7 +920,16 @@ J_COLOR_SPACE jpeg_color_space
 int num_components
 	The JPEG color space and corresponding number of components; see
 	"Special color spaces", below, for more info.  We recommend using
-	jpeg_set_color_space() if you want to change these.
+	jpeg_set_colorspace() if you want to change these.
+
+J_COLOR_TRANSFORM color_transform
+	Internal color transform identifier, writes LSE marker if nonzero
+	(requires decoder with inverse color transform support, introduced
+	with IJG JPEG 9).
+	Two values are currently possible: JCT_NONE and JCT_SUBTRACT_GREEN.
+	Set this value for lossless RGB application *before* calling
+	jpeg_set_colorspace(), because entropy table assignment in
+	jpeg_set_colorspace() depends on color_transform.
 
 boolean optimize_coding
 	TRUE causes the compressor to compute optimal Huffman coding tables
@@ -1260,9 +1273,10 @@ Special color spaces
 The JPEG standard itself is "color blind" and doesn't specify any particular
 color space.  It is customary to convert color data to a luminance/chrominance
 color space before compressing, since this permits greater compression.  The
-existing de-facto JPEG file format standards specify YCbCr or grayscale data
-(JFIF), or grayscale, RGB, YCbCr, CMYK, or YCCK (Adobe).  For special
-applications such as multispectral images, other color spaces can be used,
+existing JPEG file interchange format standards specify YCbCr or GRAYSCALE
+data (JFIF version 1), GRAYSCALE, RGB, YCbCr, CMYK, or YCCK (Adobe), or BG_RGB
+or BG_YCC (big gamut color spaces, JFIF version 2).  For special applications
+such as multispectral images, other color spaces can be used,
 but it must be understood that such files will be unportable.
 
 The JPEG library can handle the most common colorspace conversions (namely
@@ -1279,22 +1293,25 @@ jpeg_set_colorspace().  Of course you must select a supported transformation.
 jccolor.c currently supports the following transformations:
 	RGB => YCbCr
 	RGB => GRAYSCALE
+	RGB => BG_YCC
 	YCbCr => GRAYSCALE
+	YCbCr => BG_YCC
 	CMYK => YCCK
 plus the null transforms: GRAYSCALE => GRAYSCALE, RGB => RGB,
-YCbCr => YCbCr, CMYK => CMYK, YCCK => YCCK, and UNKNOWN => UNKNOWN.
-
-The de-facto file format standards (JFIF and Adobe) specify APPn markers that
-indicate the color space of the JPEG file.  It is important to ensure that
-these are written correctly, or omitted if the JPEG file's color space is not
-one of the ones supported by the de-facto standards.  jpeg_set_colorspace()
-will set the compression parameters to include or omit the APPn markers
-properly, so long as it is told the truth about the JPEG color space.
-For example, if you are writing some random 3-component color space without
-conversion, don't try to fake out the library by setting in_color_space and
-jpeg_color_space to JCS_YCbCr; use JCS_UNKNOWN.  You may want to write an
-APPn marker of your own devising to identify the colorspace --- see "Special
-markers", below.
+BG_RGB => BG_RGB, YCbCr => YCbCr, BG_YCC => BG_YCC, CMYK => CMYK,
+YCCK => YCCK, and UNKNOWN => UNKNOWN.
+
+The file interchange format standards (JFIF and Adobe) specify APPn markers
+that indicate the color space of the JPEG file.  It is important to ensure
+that these are written correctly, or omitted if the JPEG file's color space
+is not one of the ones supported by the interchange standards.
+jpeg_set_colorspace() will set the compression parameters to include or omit
+the APPn markers properly, so long as it is told the truth about the JPEG
+color space.  For example, if you are writing some random 3-component color
+space without conversion, don't try to fake out the library by setting
+in_color_space and jpeg_color_space to JCS_YCbCr; use JCS_UNKNOWN.
+You may want to write an APPn marker of your own devising to identify
+the colorspace --- see "Special markers", below.
 
 When told that the color space is UNKNOWN, the library will default to using
 luminance-quality compression parameters for all color components.  You may
@@ -1312,6 +1329,8 @@ set out_color_space to override this.  Again, you must select a supported
 transformation.  jdcolor.c currently supports
 	YCbCr => RGB
 	YCbCr => GRAYSCALE
+	BG_YCC => RGB
+	BG_YCC => GRAYSCALE
 	RGB => GRAYSCALE
 	GRAYSCALE => RGB
 	YCCK => CMYK
@@ -2572,10 +2591,10 @@ different sizes.  If the image dimensions are not a multiple of the MCU size,
 you must also pad the data correctly (usually, this is done by replicating
 the last column and/or row).  The data must be padded to a multiple of a DCT
 block in each component: that is, each downsampled row must contain a
-multiple of 8 valid samples, and there must be a multiple of 8 sample rows
-for each component.  (For applications such as conversion of digital TV
-images, the standard image size is usually a multiple of the DCT block size,
-so that no padding need actually be done.)
+multiple of block_size valid samples, and there must be a multiple of
+block_size sample rows for each component.  (For applications such as
+conversion of digital TV images, the standard image size is usually a
+multiple of the DCT block size, so that no padding need actually be done.)
 
 The procedure for compression of raw data is basically the same as normal
 compression, except that you call jpeg_write_raw_data() in place of
@@ -2601,22 +2620,22 @@ The scanlines count passed to and returned from jpeg_write_raw_data is
 measured in terms of the component with the largest v_samp_factor.
 
 jpeg_write_raw_data() processes one MCU row per call, which is to say
-v_samp_factor*DCTSIZE sample rows of each component.  The passed num_lines
-value must be at least max_v_samp_factor*DCTSIZE, and the return value will
-be exactly that amount (or possibly some multiple of that amount, in future
-library versions).  This is true even on the last call at the bottom of the
-image; don't forget to pad your data as necessary.
+v_samp_factor*block_size sample rows of each component.  The passed num_lines
+value must be at least max_v_samp_factor*block_size, and the return value
+will be exactly that amount (or possibly some multiple of that amount, in
+future library versions).  This is true even on the last call at the bottom
+of the image; don't forget to pad your data as necessary.
 
 The required dimensions of the supplied data can be computed for each
 component as
-	cinfo->comp_info[i].width_in_blocks*DCTSIZE  samples per row
-	cinfo->comp_info[i].height_in_blocks*DCTSIZE rows in image
+	cinfo->comp_info[i].width_in_blocks*block_size  samples per row
+	cinfo->comp_info[i].height_in_blocks*block_size rows in image
 after jpeg_start_compress() has initialized those fields.  If the valid data
 is smaller than this, it must be padded appropriately.  For some sampling
 factors and image sizes, additional dummy DCT blocks are inserted to make
 the image a multiple of the MCU dimensions.  The library creates such dummy
 blocks itself; it does not read them from your supplied data.  Therefore you
-need never pad by more than DCTSIZE samples.  An example may help here.
+need never pad by more than block_size samples.  An example may help here.
 Assume 2h2v downsampling of YCbCr data, that is
 	cinfo->comp_info[0].h_samp_factor = 2		for Y
 	cinfo->comp_info[0].v_samp_factor = 2
@@ -2658,8 +2677,8 @@ Then call jpeg_read_raw_data() in place of jpeg_read_scanlines().  The
 decompression process is otherwise the same as usual.
 
 jpeg_read_raw_data() returns one MCU row per call, and thus you must pass a
-buffer of at least max_v_samp_factor*DCTSIZE scanlines (scanline counting is
-the same as for raw-data compression).  The buffer you pass must be large
+buffer of at least max_v_samp_factor*block_size scanlines (scanline counting
+is the same as for raw-data compression).  The buffer you pass must be large
 enough to hold the actual data plus padding to DCT-block boundaries.  As with
 compression, any entirely dummy DCT blocks are not processed so you need not
 allocate space for them, but the total scanline count includes them.  The
@@ -2915,10 +2934,10 @@ This does not count any memory allocated by the application, such as a
 buffer to hold the final output image.
 
 The above figures are valid for 8-bit JPEG data precision and a machine with
-32-bit ints.  For 12-bit JPEG data, double the size of the strip buffers and
-quantization pixel buffer.  The "fixed-size" data will be somewhat smaller
-with 16-bit ints, larger with 64-bit ints.  Also, CMYK or other unusual
-color spaces will require different amounts of space.
+32-bit ints.  For 9-bit to 12-bit JPEG data, double the size of the strip
+buffers and quantization pixel buffer.  The "fixed-size" data will be
+somewhat smaller with 16-bit ints, larger with 64-bit ints.  Also, CMYK
+or other unusual color spaces will require different amounts of space.
 
 The full-image coefficient and pixel buffers, if needed at all, do not
 have to be fully RAM resident; you can have the library use temporary
@@ -2940,27 +2959,34 @@ Library compile-time options
 
 A number of compile-time options are available by modifying jmorecfg.h.
 
-The JPEG standard provides for both the baseline 8-bit DCT process and
-a 12-bit DCT process.  The IJG code supports 12-bit JPEG if you define
-BITS_IN_JSAMPLE as 12 rather than 8.  Note that this causes JSAMPLE to be
-larger than a char, so it affects the surrounding application's image data.
-The sample applications cjpeg and djpeg can support 12-bit mode only for PPM
-and GIF file formats; you must disable the other file formats to compile a
-12-bit cjpeg or djpeg.  (install.txt has more information about that.)
-At present, a 12-bit library can handle *only* 12-bit images, not both
-precisions.  (If you need to include both 8- and 12-bit libraries in a single
-application, you could probably do it by defining NEED_SHORT_EXTERNAL_NAMES
-for just one of the copies.  You'd have to access the 8-bit and 12-bit copies
-from separate application source files.  This is untested ... if you try it,
-we'd like to hear whether it works!)
-
-Note that a 12-bit library always compresses in Huffman optimization mode,
-in order to generate valid Huffman tables.  This is necessary because our
-default Huffman tables only cover 8-bit data.  If you need to output 12-bit
-files in one pass, you'll have to supply suitable default Huffman tables.
-You may also want to supply your own DCT quantization tables; the existing
-quality-scaling code has been developed for 8-bit use, and probably doesn't
-generate especially good tables for 12-bit.
+The IJG code currently supports 8-bit to 12-bit sample data precision by
+defining BITS_IN_JSAMPLE as 8, 9, 10, 11, or 12.
+Note that a value larger than 8 causes JSAMPLE to be larger than a char,
+so it affects the surrounding application's image data.
+The sample applications cjpeg and djpeg can support deeper than 8-bit data
+only for PPM and GIF file formats; you must disable the other file formats
+to compile a 9-bit to 12-bit cjpeg or djpeg.  (install.txt has more
+information about that.)
+Run-time selection and conversion of data precision are currently not
+supported and may be added later.
+Exception:  The transcoding part (jpegtran) supports all settings in a
+single instance, since it operates on the level of DCT coefficients and
+not sample values.
+(If you need to include an 8-bit library and a 9-bit to 12-bit library for
+compression or decompression in a single application, you could probably do
+it by defining NEED_SHORT_EXTERNAL_NAMES for just one of the copies.  You'd
+have to access the 8-bit and the 9-bit to 12-bit copies from separate
+application source files.  This is untested ... if you try it, we'd like to
+hear whether it works!)
+
+Note that the standard Huffman tables are only valid for 8-bit data precision.
+If you selected more than 8-bit data precision, cjpeg uses arithmetic coding
+by default.  The Huffman encoder normally uses entropy optimization to
+compute usable tables for higher precision.  Otherwise, you'll have to
+supply different default Huffman tables.  You may also want to supply your
+own DCT quantization tables; the existing quality-scaling code has been
+developed for 8-bit use, and probably doesn't generate especially good tables
+for 9-bit to 12-bit.
 
 The maximum number of components (color channels) in the image is determined
 by MAX_COMPONENTS.  The JPEG standard allows up to 255 components, but we
diff --git a/Source/LibJPEG/structure.txt b/Source/LibJPEG/structure.txt
index ae9f89f..04d9577 100644
--- a/Source/LibJPEG/structure.txt
+++ b/Source/LibJPEG/structure.txt
@@ -1,6 +1,6 @@
 IJG JPEG LIBRARY:  SYSTEM ARCHITECTURE
 
-Copyright (C) 1991-2012, Thomas G. Lane, Guido Vollbeding.
+Copyright (C) 1991-2013, Thomas G. Lane, Guido Vollbeding.
 This file is part of the Independent JPEG Group's software.
 For conditions of distribution and use, see the accompanying README file.
 
@@ -170,16 +170,16 @@ can be simplified a little if they work on padded data: it's not necessary to
 have special cases at the right and bottom edges.  Therefore the interface
 buffer is always an integral number of blocks wide and high, and we expect
 compression preprocessing to pad the source data properly.  Padding will occur
-only to the next block (N-sample) boundary.  In an interleaved-scan situation,
-additional dummy blocks may be used to fill out MCUs, but the MCU assembly and
-disassembly logic will create or discard these blocks internally.  (This is
-advantageous for speed reasons, since we avoid DCTing the dummy blocks.
-It also permits a small reduction in file size, because the compressor can
-choose dummy block contents so as to minimize their size in compressed form.
-Finally, it makes the interface buffer specification independent of whether
-the file is actually interleaved or not.)  Applications that wish to deal
-directly with the downsampled data must provide similar buffering and padding
-for odd-sized images.
+only to the next block (block_size-sample) boundary.  In an interleaved-scan
+situation, additional dummy blocks may be used to fill out MCUs, but the MCU
+assembly and disassembly logic will create or discard these blocks internally.
+(This is advantageous for speed reasons, since we avoid DCTing the dummy
+blocks.  It also permits a small reduction in file size, because the
+compressor can choose dummy block contents so as to minimize their size
+in compressed form.  Finally, it makes the interface buffer specification
+independent of whether the file is actually interleaved or not.)
+Applications that wish to deal directly with the downsampled data must
+provide similar buffering and padding for odd-sized images.
 
 
 *** Poor man's object-oriented programming ***
@@ -345,9 +345,10 @@ The objects shown above are:
   require context rows above and below the current row group; the
   preprocessing controller is responsible for supplying these rows via proper
   buffering.  The downsampler is responsible for edge expansion at the right
-  edge (i.e., extending each sample row to a multiple of N samples); but the
-  preprocessing controller is responsible for vertical edge expansion (i.e.,
-  duplicating the bottom sample row as needed to make a multiple of N rows).
+  edge (i.e., extending each sample row to a multiple of block_size samples);
+  but the preprocessing controller is responsible for vertical edge expansion
+  (i.e., duplicating the bottom sample row as needed to make a multiple of
+  block_size rows).
 
 * Coefficient controller: buffer controller for the DCT-coefficient data.
   This controller handles MCU assembly, including insertion of dummy DCT
@@ -651,8 +652,8 @@ contain quantized coefficients everywhere outside the DCT/IDCT subsystems.
 quantization a la JPEG Part 3.)
 
 Notice that the allocation unit is now a row of 8x8 coefficient blocks,
-corresponding to N rows of samples.  Otherwise the structure is much the same
-as for samples, and for the same reasons.
+corresponding to block_size rows of samples.  Otherwise the structure
+is much the same as for samples, and for the same reasons.
 
 On machines where malloc() can't handle a request bigger than 64Kb, this data
 structure limits us to rows of less than 512 JBLOCKs, or a picture width of
diff --git a/Source/LibJPEG/transupp.c b/Source/LibJPEG/transupp.c
index 016f383..525932a 100644
--- a/Source/LibJPEG/transupp.c
+++ b/Source/LibJPEG/transupp.c
@@ -1,7 +1,7 @@
 /*
  * transupp.c
  *
- * Copyright (C) 1997-2011, Thomas G. Lane, Guido Vollbeding.
+ * Copyright (C) 1997-2013, Thomas G. Lane, Guido Vollbeding.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
@@ -114,6 +114,116 @@ do_crop (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
 
 
 LOCAL(void)
+do_crop_ext (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
+	     JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
+	     jvirt_barray_ptr *src_coef_arrays,
+	     jvirt_barray_ptr *dst_coef_arrays)
+/* Crop.  This is only used when no rotate/flip is requested with the crop.
+ * Extension: If the destination size is larger than the source, we fill in
+ * the extra area with zero (neutral gray).  Note we also have to zero partial
+ * iMCUs at the right and bottom edge of the source image area in this case.
+ */
+{
+  JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height;
+  JDIMENSION dst_blk_y, x_crop_blocks, y_crop_blocks;
+  int ci, offset_y;
+  JBLOCKARRAY src_buffer, dst_buffer;
+  jpeg_component_info *compptr;
+
+  MCU_cols = srcinfo->output_width /
+    (dstinfo->max_h_samp_factor * dstinfo->min_DCT_h_scaled_size);
+  MCU_rows = srcinfo->output_height /
+    (dstinfo->max_v_samp_factor * dstinfo->min_DCT_v_scaled_size);
+
+  for (ci = 0; ci < dstinfo->num_components; ci++) {
+    compptr = dstinfo->comp_info + ci;
+    comp_width = MCU_cols * compptr->h_samp_factor;
+    comp_height = MCU_rows * compptr->v_samp_factor;
+    x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
+    y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
+    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
+	 dst_blk_y += compptr->v_samp_factor) {
+      dst_buffer = (*srcinfo->mem->access_virt_barray)
+	((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
+	 (JDIMENSION) compptr->v_samp_factor, TRUE);
+      if (dstinfo->jpeg_height > srcinfo->output_height) {
+	if (dst_blk_y < y_crop_blocks ||
+	    dst_blk_y >= comp_height + y_crop_blocks) {
+	  for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
+	    FMEMZERO(dst_buffer[offset_y],
+		     compptr->width_in_blocks * SIZEOF(JBLOCK));
+	  }
+	  continue;
+	}
+	src_buffer = (*srcinfo->mem->access_virt_barray)
+	  ((j_common_ptr) srcinfo, src_coef_arrays[ci],
+	   dst_blk_y - y_crop_blocks,
+	   (JDIMENSION) compptr->v_samp_factor, FALSE);
+      } else {
+	src_buffer = (*srcinfo->mem->access_virt_barray)
+	  ((j_common_ptr) srcinfo, src_coef_arrays[ci],
+	   dst_blk_y + y_crop_blocks,
+	   (JDIMENSION) compptr->v_samp_factor, FALSE);
+      }
+      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
+	if (dstinfo->jpeg_width > srcinfo->output_width) {
+	  if (x_crop_blocks > 0) {
+	    FMEMZERO(dst_buffer[offset_y],
+		     x_crop_blocks * SIZEOF(JBLOCK));
+	  }
+	  jcopy_block_row(src_buffer[offset_y],
+			  dst_buffer[offset_y] + x_crop_blocks,
+			  comp_width);
+	  if (compptr->width_in_blocks > comp_width + x_crop_blocks) {
+	    FMEMZERO(dst_buffer[offset_y] +
+		       comp_width + x_crop_blocks,
+		     (compptr->width_in_blocks -
+		       comp_width - x_crop_blocks) * SIZEOF(JBLOCK));
+	  }
+	} else {
+	  jcopy_block_row(src_buffer[offset_y] + x_crop_blocks,
+			  dst_buffer[offset_y],
+			  compptr->width_in_blocks);
+	}
+      }
+    }
+  }
+}
+
+
+LOCAL(void)
+do_wipe (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
+	 JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
+	 jvirt_barray_ptr *src_coef_arrays,
+	 JDIMENSION drop_width, JDIMENSION drop_height)
+/* Wipe - drop content of specified area, fill with zero (neutral gray) */
+{
+  JDIMENSION comp_width, comp_height;
+  JDIMENSION blk_y, x_wipe_blocks, y_wipe_blocks;
+  int ci, offset_y;
+  JBLOCKARRAY buffer;
+  jpeg_component_info *compptr;
+
+  for (ci = 0; ci < dstinfo->num_components; ci++) {
+    compptr = dstinfo->comp_info + ci;
+    comp_width = drop_width * compptr->h_samp_factor;
+    comp_height = drop_height * compptr->v_samp_factor;
+    x_wipe_blocks = x_crop_offset * compptr->h_samp_factor;
+    y_wipe_blocks = y_crop_offset * compptr->v_samp_factor;
+    for (blk_y = 0; blk_y < comp_height; blk_y += compptr->v_samp_factor) {
+      buffer = (*srcinfo->mem->access_virt_barray)
+	((j_common_ptr) srcinfo, src_coef_arrays[ci], blk_y + y_wipe_blocks,
+	 (JDIMENSION) compptr->v_samp_factor, TRUE);
+      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
+	FMEMZERO(buffer[offset_y] + x_wipe_blocks,
+		 comp_width * SIZEOF(JBLOCK));
+      }
+    }
+  }
+}
+
+
+LOCAL(void)
 do_flip_h_no_crop (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
 		   JDIMENSION x_crop_offset,
 		   jvirt_barray_ptr *src_coef_arrays)
@@ -888,7 +998,8 @@ jtransform_request_workspace (j_decompress_ptr srcinfo,
 
   /* Determine number of components in output image */
   if (info->force_grayscale &&
-      srcinfo->jpeg_color_space == JCS_YCbCr &&
+      (srcinfo->jpeg_color_space == JCS_YCbCr ||
+       srcinfo->jpeg_color_space == JCS_BG_YCC) &&
       srcinfo->num_components == 3)
     /* We'll only process the first component */
     info->num_components = 1;
@@ -965,39 +1076,81 @@ jtransform_request_workspace (j_decompress_ptr srcinfo,
       info->crop_xoffset = 0;	/* default to +0 */
     if (info->crop_yoffset_set == JCROP_UNSET)
       info->crop_yoffset = 0;	/* default to +0 */
-    if (info->crop_xoffset >= info->output_width ||
-	info->crop_yoffset >= info->output_height)
-      ERREXIT(srcinfo, JERR_BAD_CROP_SPEC);
-    if (info->crop_width_set == JCROP_UNSET)
+    if (info->crop_width_set == JCROP_UNSET) {
+      if (info->crop_xoffset >= info->output_width)
+	ERREXIT(srcinfo, JERR_BAD_CROP_SPEC);
       info->crop_width = info->output_width - info->crop_xoffset;
-    if (info->crop_height_set == JCROP_UNSET)
+    } else {
+      /* Check for crop extension */
+      if (info->crop_width > info->output_width) {
+	/* Crop extension does not work when transforming! */
+	if (info->transform != JXFORM_NONE ||
+	    info->crop_xoffset >= info->crop_width ||
+	    info->crop_xoffset > info->crop_width - info->output_width)
+	  ERREXIT(srcinfo, JERR_BAD_CROP_SPEC);
+      } else {
+	if (info->crop_xoffset >= info->output_width ||
+	    info->crop_width <= 0 ||
+	    info->crop_xoffset > info->output_width - info->crop_width)
+	  ERREXIT(srcinfo, JERR_BAD_CROP_SPEC);
+      }
+    }
+    if (info->crop_height_set == JCROP_UNSET) {
+      if (info->crop_yoffset >= info->output_height)
+	ERREXIT(srcinfo, JERR_BAD_CROP_SPEC);
       info->crop_height = info->output_height - info->crop_yoffset;
-    /* Ensure parameters are valid */
-    if (info->crop_width <= 0 || info->crop_width > info->output_width ||
-	info->crop_height <= 0 || info->crop_height > info->output_height ||
-	info->crop_xoffset > info->output_width - info->crop_width ||
-	info->crop_yoffset > info->output_height - info->crop_height)
-      ERREXIT(srcinfo, JERR_BAD_CROP_SPEC);
+    } else {
+      /* Check for crop extension */
+      if (info->crop_height > info->output_height) {
+	/* Crop extension does not work when transforming! */
+	if (info->transform != JXFORM_NONE ||
+	    info->crop_yoffset >= info->crop_height ||
+	    info->crop_yoffset > info->crop_height - info->output_height)
+	  ERREXIT(srcinfo, JERR_BAD_CROP_SPEC);
+      } else {
+	if (info->crop_yoffset >= info->output_height ||
+	    info->crop_height <= 0 ||
+	    info->crop_yoffset > info->output_height - info->crop_height)
+	  ERREXIT(srcinfo, JERR_BAD_CROP_SPEC);
+      }
+    }
     /* Convert negative crop offsets into regular offsets */
-    if (info->crop_xoffset_set == JCROP_NEG)
-      xoffset = info->output_width - info->crop_width - info->crop_xoffset;
-    else
+    if (info->crop_xoffset_set != JCROP_NEG)
       xoffset = info->crop_xoffset;
-    if (info->crop_yoffset_set == JCROP_NEG)
-      yoffset = info->output_height - info->crop_height - info->crop_yoffset;
+    else if (info->crop_width > info->output_width) /* crop extension */
+      xoffset = info->crop_width - info->output_width - info->crop_xoffset;
     else
+      xoffset = info->output_width - info->crop_width - info->crop_xoffset;
+    if (info->crop_yoffset_set != JCROP_NEG)
       yoffset = info->crop_yoffset;
-    /* Now adjust so that upper left corner falls at an iMCU boundary */
-    if (info->crop_width_set == JCROP_FORCE)
-      info->output_width = info->crop_width;
-    else
-      info->output_width =
-        info->crop_width + (xoffset % info->iMCU_sample_width);
-    if (info->crop_height_set == JCROP_FORCE)
-      info->output_height = info->crop_height;
+    else if (info->crop_height > info->output_height) /* crop extension */
+      yoffset = info->crop_height - info->output_height - info->crop_yoffset;
     else
-      info->output_height =
-        info->crop_height + (yoffset % info->iMCU_sample_height);
+      yoffset = info->output_height - info->crop_height - info->crop_yoffset;
+    /* Now adjust so that upper left corner falls at an iMCU boundary */
+    if (info->transform == JXFORM_WIPE) {
+      /* Ensure the effective wipe region will cover the requested */
+      info->drop_width = (JDIMENSION) jdiv_round_up
+	((long) (info->crop_width + (xoffset % info->iMCU_sample_width)),
+	 (long) info->iMCU_sample_width);
+      info->drop_height = (JDIMENSION) jdiv_round_up
+	((long) (info->crop_height + (yoffset % info->iMCU_sample_height)),
+	 (long) info->iMCU_sample_height);
+    } else {
+      /* Ensure the effective crop region will cover the requested */
+      if (info->crop_width_set == JCROP_FORCE ||
+	  info->crop_width > info->output_width)
+	info->output_width = info->crop_width;
+      else
+	info->output_width =
+	  info->crop_width + (xoffset % info->iMCU_sample_width);
+      if (info->crop_height_set == JCROP_FORCE ||
+	  info->crop_height > info->output_height)
+	info->output_height = info->crop_height;
+      else
+	info->output_height =
+	  info->crop_height + (yoffset % info->iMCU_sample_height);
+    }
     /* Save x/y offsets measured in iMCUs */
     info->x_crop_offset = xoffset / info->iMCU_sample_width;
     info->y_crop_offset = yoffset / info->iMCU_sample_height;
@@ -1013,7 +1166,9 @@ jtransform_request_workspace (j_decompress_ptr srcinfo,
   transpose_it = FALSE;
   switch (info->transform) {
   case JXFORM_NONE:
-    if (info->x_crop_offset != 0 || info->y_crop_offset != 0)
+    if (info->x_crop_offset != 0 || info->y_crop_offset != 0 ||
+	info->output_width > srcinfo->output_width ||
+	info->output_height > srcinfo->output_height)
       need_workspace = TRUE;
     /* No workspace needed if neither cropping nor transforming */
     break;
@@ -1067,6 +1222,8 @@ jtransform_request_workspace (j_decompress_ptr srcinfo,
     need_workspace = TRUE;
     transpose_it = TRUE;
     break;
+  case JXFORM_WIPE:
+    break;
   }
 
   /* Allocate workspace if needed.
@@ -1076,7 +1233,7 @@ jtransform_request_workspace (j_decompress_ptr srcinfo,
   if (need_workspace) {
     coef_arrays = (jvirt_barray_ptr *)
       (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE,
-		SIZEOF(jvirt_barray_ptr) * info->num_components);
+	SIZEOF(jvirt_barray_ptr) * info->num_components);
     width_in_iMCUs = (JDIMENSION)
       jdiv_round_up((long) info->output_width,
 		    (long) info->iMCU_sample_width);
@@ -1327,12 +1484,13 @@ jtransform_adjust_parameters (j_decompress_ptr srcinfo,
 {
   /* If force-to-grayscale is requested, adjust destination parameters */
   if (info->force_grayscale) {
-    /* First, ensure we have YCbCr or grayscale data, and that the source's
+    /* First, ensure we have YCC or grayscale data, and that the source's
      * Y channel is full resolution.  (No reasonable person would make Y
      * be less than full resolution, so actually coping with that case
      * isn't worth extra code space.  But we check it to avoid crashing.)
      */
-    if (((dstinfo->jpeg_color_space == JCS_YCbCr &&
+    if ((((dstinfo->jpeg_color_space == JCS_YCbCr ||
+	   dstinfo->jpeg_color_space == JCS_BG_YCC) &&
 	  dstinfo->num_components == 3) ||
 	 (dstinfo->jpeg_color_space == JCS_GRAYSCALE &&
 	  dstinfo->num_components == 1)) &&
@@ -1427,7 +1585,11 @@ jtransform_execute_transform (j_decompress_ptr srcinfo,
    */
   switch (info->transform) {
   case JXFORM_NONE:
-    if (info->x_crop_offset != 0 || info->y_crop_offset != 0)
+    if (info->output_width > srcinfo->output_width ||
+	info->output_height > srcinfo->output_height)
+      do_crop_ext(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
+		  src_coef_arrays, dst_coef_arrays);
+    else if (info->x_crop_offset != 0 || info->y_crop_offset != 0)
       do_crop(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
 	      src_coef_arrays, dst_coef_arrays);
     break;
@@ -1463,6 +1625,10 @@ jtransform_execute_transform (j_decompress_ptr srcinfo,
     do_rot_270(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
 	       src_coef_arrays, dst_coef_arrays);
     break;
+  case JXFORM_WIPE:
+    do_wipe(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
+	    src_coef_arrays, info->drop_width, info->drop_height);
+    break;
   }
 }
 
diff --git a/Source/LibJPEG/transupp.h b/Source/LibJPEG/transupp.h
index 9aa0af3..eee6931 100644
--- a/Source/LibJPEG/transupp.h
+++ b/Source/LibJPEG/transupp.h
@@ -1,7 +1,7 @@
 /*
  * transupp.h
  *
- * Copyright (C) 1997-2011, Thomas G. Lane, Guido Vollbeding.
+ * Copyright (C) 1997-2013, Thomas G. Lane, Guido Vollbeding.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
@@ -51,14 +51,17 @@
  *
  * We also offer a lossless-crop option, which discards data outside a given
  * image region but losslessly preserves what is inside.  Like the rotate and
- * flip transforms, lossless crop is restricted by the JPEG format: the upper
- * left corner of the selected region must fall on an iMCU boundary.  If this
- * does not hold for the given crop parameters, we silently move the upper left
- * corner up and/or left to make it so, simultaneously increasing the region
- * dimensions to keep the lower right crop corner unchanged.  (Thus, the
+ * flip transforms, lossless crop is restricted by the current JPEG format: the
+ * upper left corner of the selected region must fall on an iMCU boundary.  If
+ * this does not hold for the given crop parameters, we silently move the upper
+ * left corner up and/or left to make it so, simultaneously increasing the
+ * region dimensions to keep the lower right crop corner unchanged.  (Thus, the
  * output image covers at least the requested region, but may cover more.)
  * The adjustment of the region dimensions may be optionally disabled.
  *
+ * A complementary lossless-wipe option is provided to discard (gray out) data
+ * inside a given image region while losslessly preserving what is outside.
+ *
  * We also provide a lossless-resize option, which is kind of a lossless-crop
  * operation in the DCT coefficient block domain - it discards higher-order
  * coefficients and losslessly preserves lower-order coefficients of a
@@ -102,7 +105,8 @@ typedef enum {
 	JXFORM_TRANSVERSE,	/* transpose across UR-to-LL axis */
 	JXFORM_ROT_90,		/* 90-degree clockwise rotation */
 	JXFORM_ROT_180,		/* 180-degree rotation */
-	JXFORM_ROT_270		/* 270-degree clockwise (or 90 ccw) */
+	JXFORM_ROT_270,		/* 270-degree clockwise (or 90 ccw) */
+	JXFORM_WIPE		/* wipe */
 } JXFORM_CODE;
 
 /*
@@ -130,7 +134,7 @@ typedef struct {
   boolean perfect;		/* if TRUE, fail if partial MCUs are requested */
   boolean trim;			/* if TRUE, trim partial MCUs as needed */
   boolean force_grayscale;	/* if TRUE, convert color image to grayscale */
-  boolean crop;			/* if TRUE, crop source image */
+  boolean crop;			/* if TRUE, crop or wipe source image */
 
   /* Crop parameters: application need not set these unless crop is TRUE.
    * These can be filled in by jtransform_parse_crop_spec().
@@ -151,6 +155,8 @@ typedef struct {
   JDIMENSION output_height;
   JDIMENSION x_crop_offset;	/* destination crop offsets measured in iMCUs */
   JDIMENSION y_crop_offset;
+  JDIMENSION drop_width;	/* drop/wipe dimensions measured in iMCUs */
+  JDIMENSION drop_height;
   int iMCU_sample_width;	/* destination iMCU size */
   int iMCU_sample_height;
 } jpeg_transform_info;
diff --git a/Source/LibJPEG/usage.txt b/Source/LibJPEG/usage.txt
index c91ddff..ca9f7d7 100644
--- a/Source/LibJPEG/usage.txt
+++ b/Source/LibJPEG/usage.txt
@@ -80,8 +80,9 @@ The basic command line switches for cjpeg are:
 	-rgb		Create RGB JPEG file.
 			Using this switch suppresses the conversion from RGB
 			colorspace input to the default YCbCr JPEG colorspace.
-			Use this switch in combination with the -block N
-			switch (see below) for lossless JPEG coding.
+			You can use this switch in combination with the
+			-block N switch (see below) for lossless JPEG coding.
+			See also the -rgb1 switch below.
 
 	-optimize	Perform optimization of entropy encoding parameters.
 			Without this, default encoding parameters are used.
@@ -157,10 +158,10 @@ file size is about the same --- often a little smaller.
 
 Switches for advanced users:
 
-	-arithmetic	Use arithmetic coding.  CAUTION: arithmetic coded JPEG
-			is not yet widely implemented, so many decoders will
-			be unable to view an arithmetic coded JPEG file at
-			all.
+	-arithmetic	Use arithmetic coding.
+			CAUTION: arithmetic coded JPEG is not yet widely
+			implemented, so many decoders will be unable to
+			view an arithmetic coded JPEG file at all.
 
 	-block N	Set DCT block size.  All N from 1 to 16 are possible.
 			Default is 8 (baseline format).
@@ -175,6 +176,37 @@ Switches for advanced users:
 			decoders will be unable to view a SmartScale extended
 			JPEG file at all.
 
+	-rgb1		Create RGB JPEG file with reversible color transform.
+			Works like the -rgb switch (see above) and inserts a
+			simple reversible color transform into the processing
+			which significantly improves the compression.
+			Use this switch in combination with the -block N
+			switch (see above) for lossless JPEG coding.
+			CAUTION: A decoder with inverse color transform
+			support is required for this feature.  Reversible
+			color transform support is not yet widely implemented,
+			so many decoders will be unable to view a reversible
+			color transformed JPEG file at all.
+
+	-bgycc		Create big gamut YCC JPEG file.
+			In this type of encoding the color difference
+			components are quantized further by a factor of 2
+			compared to the normal Cb/Cr values, thus creating
+			space to allow larger color values with higher
+			saturation than the normal gamut limits to be encoded.
+			In order to compensate for the loss of color fidelity
+			compared to a normal YCC encoded file, the color
+			quantization tables can be adjusted accordingly.
+			For example, cjpeg -bgycc -quality 80,90 will give
+			similar results as cjpeg -quality 80.
+			CAUTION: For correct decompression a decoder with big
+			gamut YCC support (JFIF version 2) is required.
+			An old decoder may or may not display a big gamut YCC
+			encoded JPEG file, depending on JFIF version check
+			and corresponding warning/error configuration.
+			In case of a granted decompression the old decoder
+			will display the image with half saturated colors.
+
 	-dct int	Use integer DCT method (default).
 	-dct fast	Use fast integer DCT (less accurate).
 	-dct float	Use floating-point DCT method.
@@ -374,7 +406,8 @@ quality settings to make very small JPEG files; the percentage improvement
 is often a lot more than it is on larger files.  (At present, -optimize
 mode is always selected when generating progressive JPEG files.)
 
-GIF input files are no longer supported, to avoid the Unisys LZW patent.
+GIF input files are no longer supported, to avoid the Unisys LZW patent
+(now expired).
 (Conversion of GIF files to JPEG is usually a bad idea anyway.)
 
 
@@ -402,8 +435,9 @@ it may run out of memory even with -maxmemory 0.  In that case you can still
 decompress, with some loss of image quality, by specifying -onepass for
 one-pass quantization.
 
-To avoid the Unisys LZW patent, djpeg produces uncompressed GIF files.  These
-are larger than they should be, but are readable by standard GIF decoders.
+To avoid the Unisys LZW patent (now expired), djpeg produces uncompressed GIF
+files.  These are larger than they should be, but are readable by standard GIF
+decoders.
 
 
 HINTS FOR BOTH PROGRAMS
@@ -520,14 +554,20 @@ image region but losslessly preserves what is inside.  Like the rotate and
 flip transforms, lossless crop is restricted by the current JPEG format: the
 upper left corner of the selected region must fall on an iMCU boundary.  If
 this does not hold for the given crop parameters, we silently move the upper
-left corner up and/or left to make it so, simultaneously increasing the region
-dimensions to keep the lower right crop corner unchanged.  (Thus, the output
-image covers at least the requested region, but may cover more.)
+left corner up and/or left to make it so, simultaneously increasing the
+region dimensions to keep the lower right crop corner unchanged.  (Thus, the
+output image covers at least the requested region, but may cover more.)
+The adjustment of the region dimensions may be optionally disabled.
 
 The image can be losslessly cropped by giving the switch:
 	-crop WxH+X+Y	Crop to a rectangular subarea of width W, height H
 			starting at point X,Y.
 
+A complementary lossless-wipe option is provided to discard (gray out) data
+inside a given image region while losslessly preserving what is outside:
+	-wipe WxH+X+Y	Wipe (gray out) a rectangular subarea of
+			width W, height H starting at point X,Y.
+
 Other not-strictly-lossless transformation switches are:
 
 	-grayscale	Force grayscale output.
diff --git a/Source/LibJXR/LICENCE b/Source/LibJXR/LICENCE
new file mode 100644
index 0000000..e84fcd7
--- /dev/null
+++ b/Source/LibJXR/LICENCE
@@ -0,0 +1,9 @@
+Microsoft Corporation Technical Documentation License Agreement for the specification �JPEG XR Device Porting Kit�
+Copyright � 2013 Microsoft Corp.
+All rights reserved.
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+�	Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+�	Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BELIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFIT [...]
+
+ 
diff --git a/Source/LibJXR/LibJXR.2005.vcproj b/Source/LibJXR/LibJXR.2005.vcproj
new file mode 100644
index 0000000..6448c7e
--- /dev/null
+++ b/Source/LibJXR/LibJXR.2005.vcproj
@@ -0,0 +1,398 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8,00"
+	Name="LibJXR"
+	ProjectGUID="{1B021BC6-301D-4FBA-96FF-2A73EE32FBD8}"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\Debug"
+			IntermediateDirectory=".\Debug"
+			ConfigurationType="4"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="./common/include;./image/sys;./jxrgluelib"
+				AdditionalUsingDirectories=""
+				PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;DISABLE_PERF_MEASUREMENT"
+				StringPooling="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
+				UsePrecompiledHeader="0"
+				PrecompiledHeaderFile=".\Debug/LibJXR.pch"
+				AssemblerListingLocation=".\Debug/"
+				ObjectFile=".\Debug/"
+				ProgramDataBaseFileName=".\Debug/"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="_DEBUG"
+				Culture="1033"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile=".\Debug\LibJXR.lib"
+				SuppressStartupBanner="true"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory=".\Release"
+			IntermediateDirectory=".\Release"
+			ConfigurationType="4"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="2"
+				EnableIntrinsicFunctions="true"
+				FavorSizeOrSpeed="1"
+				OmitFramePointers="true"
+				AdditionalIncludeDirectories="./common/include;./image/sys;./jxrgluelib"
+				PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;DISABLE_PERF_MEASUREMENT"
+				StringPooling="true"
+				RuntimeLibrary="0"
+				BufferSecurityCheck="false"
+				UsePrecompiledHeader="0"
+				PrecompiledHeaderFile=".\Release/LibJXR.pch"
+				AssemblerListingLocation=".\Release/"
+				ObjectFile=".\Release/"
+				ProgramDataBaseFileName=".\Release/"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile=".\Release\LibJXR.lib"
+				SuppressStartupBanner="true"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+			>
+			<Filter
+				Name="image"
+				>
+				<Filter
+					Name="decode"
+					>
+					<File
+						RelativePath=".\image\decode\decode.c"
+						>
+					</File>
+					<File
+						RelativePath=".\image\decode\JXRTranscode.c"
+						>
+					</File>
+					<File
+						RelativePath=".\image\decode\postprocess.c"
+						>
+					</File>
+					<File
+						RelativePath=".\image\decode\segdec.c"
+						>
+					</File>
+					<File
+						RelativePath=".\image\decode\strdec.c"
+						>
+					</File>
+					<File
+						RelativePath=".\image\decode\strdec_x86.c"
+						>
+					</File>
+					<File
+						RelativePath=".\image\decode\strInvTransform.c"
+						>
+					</File>
+					<File
+						RelativePath=".\image\decode\strPredQuantDec.c"
+						>
+					</File>
+				</Filter>
+				<Filter
+					Name="encode"
+					>
+					<File
+						RelativePath=".\image\encode\encode.c"
+						>
+					</File>
+					<File
+						RelativePath=".\image\encode\segenc.c"
+						>
+					</File>
+					<File
+						RelativePath=".\image\encode\strenc.c"
+						>
+					</File>
+					<File
+						RelativePath=".\image\encode\strenc_x86.c"
+						>
+					</File>
+					<File
+						RelativePath=".\image\encode\strFwdTransform.c"
+						>
+					</File>
+					<File
+						RelativePath=".\image\encode\strPredQuantEnc.c"
+						>
+					</File>
+				</Filter>
+				<Filter
+					Name="sys"
+					>
+					<File
+						RelativePath=".\image\sys\adapthuff.c"
+						>
+					</File>
+					<File
+						RelativePath=".\image\sys\image.c"
+						>
+					</File>
+					<File
+						RelativePath=".\image\sys\strcodec.c"
+						>
+					</File>
+					<File
+						RelativePath=".\image\sys\strPredQuant.c"
+						>
+					</File>
+					<File
+						RelativePath=".\image\sys\strTransform.c"
+						>
+					</File>
+				</Filter>
+			</Filter>
+			<Filter
+				Name="jxrgluelib"
+				>
+				<File
+					RelativePath=".\jxrgluelib\JXRGlue.c"
+					>
+				</File>
+				<File
+					RelativePath=".\jxrgluelib\JXRGlueJxr.c"
+					>
+				</File>
+				<File
+					RelativePath=".\jxrgluelib\JXRGluePFC.c"
+					>
+				</File>
+				<File
+					RelativePath=".\jxrgluelib\JXRMeta.c"
+					>
+				</File>
+			</Filter>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl"
+			>
+			<Filter
+				Name="common"
+				>
+				<File
+					RelativePath=".\common\include\guiddef.h"
+					>
+				</File>
+				<File
+					RelativePath=".\common\include\wmsal.h"
+					>
+				</File>
+				<File
+					RelativePath=".\common\include\wmspecstring.h"
+					>
+				</File>
+				<File
+					RelativePath=".\common\include\wmspecstrings_adt.h"
+					>
+				</File>
+				<File
+					RelativePath=".\common\include\wmspecstrings_strict.h"
+					>
+				</File>
+				<File
+					RelativePath=".\common\include\wmspecstrings_undef.h"
+					>
+				</File>
+			</Filter>
+			<Filter
+				Name="image"
+				>
+				<Filter
+					Name="decode"
+					>
+					<File
+						RelativePath=".\image\decode\decode.h"
+						>
+					</File>
+				</Filter>
+				<Filter
+					Name="encode"
+					>
+					<File
+						RelativePath=".\image\encode\encode.h"
+						>
+					</File>
+				</Filter>
+				<Filter
+					Name="sys"
+					>
+					<File
+						RelativePath=".\image\sys\ansi.h"
+						>
+					</File>
+					<File
+						RelativePath=".\image\sys\common.h"
+						>
+					</File>
+					<File
+						RelativePath=".\image\sys\perfTimer.h"
+						>
+					</File>
+					<File
+						RelativePath=".\image\sys\strcodec.h"
+						>
+					</File>
+					<File
+						RelativePath=".\image\sys\strTransform.h"
+						>
+					</File>
+					<File
+						RelativePath=".\image\sys\windowsmediaphoto.h"
+						>
+					</File>
+					<File
+						RelativePath=".\image\sys\xplatform_image.h"
+						>
+					</File>
+				</Filter>
+				<Filter
+					Name="x86"
+					>
+					<File
+						RelativePath=".\image\x86\x86.h"
+						>
+					</File>
+				</Filter>
+			</Filter>
+			<Filter
+				Name="jxrgluelib"
+				>
+				<File
+					RelativePath=".\jxrgluelib\JXRGlue.h"
+					>
+				</File>
+				<File
+					RelativePath=".\jxrgluelib\JXRMeta.h"
+					>
+				</File>
+			</Filter>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/Source/LibJXR/LibJXR.2008.vcproj b/Source/LibJXR/LibJXR.2008.vcproj
new file mode 100644
index 0000000..960fd29
--- /dev/null
+++ b/Source/LibJXR/LibJXR.2008.vcproj
@@ -0,0 +1,514 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9,00"
+	Name="LibJXR"
+	ProjectGUID="{244455E0-5F25-4451-9540-F317883E52A8}"
+	RootNamespace="LibJXR"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="4"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="./image/sys;./jxrgluelib"
+				PreprocessorDefinitions="WIN32;_DEBUG;_LIB;DISABLE_PERF_MEASUREMENT"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile=".\Debug\LibJXR.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+			ConfigurationType="4"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="./image/sys;./jxrgluelib"
+				PreprocessorDefinitions="WIN32;_DEBUG;_LIB;DISABLE_PERF_MEASUREMENT"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile=".\Debug\LibJXR.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="4"
+			CharacterSet="1"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="2"
+				EnableIntrinsicFunctions="true"
+				FavorSizeOrSpeed="1"
+				OmitFramePointers="true"
+				WholeProgramOptimization="false"
+				AdditionalIncludeDirectories="./image/sys;./jxrgluelib"
+				PreprocessorDefinitions="WIN32;NDEBUG;_LIB;DISABLE_PERF_MEASUREMENT"
+				RuntimeLibrary="0"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile=".\Release\LibJXR.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+			ConfigurationType="4"
+			CharacterSet="1"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				EnableIntrinsicFunctions="true"
+				AdditionalIncludeDirectories="./image/sys;./jxrgluelib"
+				PreprocessorDefinitions="WIN32;NDEBUG;_LIB;DISABLE_PERF_MEASUREMENT"
+				RuntimeLibrary="0"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile=".\Release\LibJXR.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<Filter
+				Name="image"
+				>
+				<Filter
+					Name="decode"
+					>
+					<File
+						RelativePath=".\image\decode\decode.c"
+						>
+					</File>
+					<File
+						RelativePath=".\image\decode\JXRTranscode.c"
+						>
+					</File>
+					<File
+						RelativePath=".\image\decode\postprocess.c"
+						>
+					</File>
+					<File
+						RelativePath=".\image\decode\segdec.c"
+						>
+					</File>
+					<File
+						RelativePath=".\image\decode\strdec.c"
+						>
+					</File>
+					<File
+						RelativePath=".\image\decode\strdec_x86.c"
+						>
+					</File>
+					<File
+						RelativePath=".\image\decode\strInvTransform.c"
+						>
+					</File>
+					<File
+						RelativePath=".\image\decode\strPredQuantDec.c"
+						>
+					</File>
+				</Filter>
+				<Filter
+					Name="encode"
+					>
+					<File
+						RelativePath=".\image\encode\encode.c"
+						>
+					</File>
+					<File
+						RelativePath=".\image\encode\segenc.c"
+						>
+					</File>
+					<File
+						RelativePath=".\image\encode\strenc.c"
+						>
+					</File>
+					<File
+						RelativePath=".\image\encode\strenc_x86.c"
+						>
+					</File>
+					<File
+						RelativePath=".\image\encode\strFwdTransform.c"
+						>
+					</File>
+					<File
+						RelativePath=".\image\encode\strPredQuantEnc.c"
+						>
+					</File>
+				</Filter>
+				<Filter
+					Name="sys"
+					>
+					<File
+						RelativePath=".\image\sys\adapthuff.c"
+						>
+					</File>
+					<File
+						RelativePath=".\image\sys\image.c"
+						>
+					</File>
+					<File
+						RelativePath=".\image\sys\strcodec.c"
+						>
+					</File>
+					<File
+						RelativePath=".\image\sys\strPredQuant.c"
+						>
+					</File>
+					<File
+						RelativePath=".\image\sys\strTransform.c"
+						>
+					</File>
+				</Filter>
+			</Filter>
+			<Filter
+				Name="jxrgluelib"
+				>
+				<File
+					RelativePath=".\jxrgluelib\JXRGlue.c"
+					>
+				</File>
+				<File
+					RelativePath=".\jxrgluelib\JXRGlueJxr.c"
+					>
+				</File>
+				<File
+					RelativePath=".\jxrgluelib\JXRGluePFC.c"
+					>
+				</File>
+				<File
+					RelativePath=".\jxrgluelib\JXRMeta.c"
+					>
+				</File>
+			</Filter>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+			<Filter
+				Name="image"
+				>
+				<Filter
+					Name="decode"
+					>
+					<File
+						RelativePath=".\image\decode\decode.h"
+						>
+					</File>
+				</Filter>
+				<Filter
+					Name="encode"
+					>
+					<File
+						RelativePath=".\image\encode\encode.h"
+						>
+					</File>
+				</Filter>
+				<Filter
+					Name="sys"
+					>
+					<File
+						RelativePath=".\image\sys\ansi.h"
+						>
+					</File>
+					<File
+						RelativePath=".\image\sys\common.h"
+						>
+					</File>
+					<File
+						RelativePath=".\image\sys\perfTimer.h"
+						>
+					</File>
+					<File
+						RelativePath=".\image\sys\strcodec.h"
+						>
+					</File>
+					<File
+						RelativePath=".\image\sys\strTransform.h"
+						>
+					</File>
+					<File
+						RelativePath=".\image\sys\windowsmediaphoto.h"
+						>
+					</File>
+					<File
+						RelativePath=".\image\sys\xplatform_image.h"
+						>
+					</File>
+				</Filter>
+				<Filter
+					Name="x86"
+					>
+					<File
+						RelativePath=".\image\x86\x86.h"
+						>
+					</File>
+				</Filter>
+			</Filter>
+			<Filter
+				Name="common"
+				>
+				<File
+					RelativePath=".\common\include\guiddef.h"
+					>
+				</File>
+				<File
+					RelativePath=".\common\include\wmsal.h"
+					>
+				</File>
+				<File
+					RelativePath=".\common\include\wmspecstring.h"
+					>
+				</File>
+				<File
+					RelativePath=".\common\include\wmspecstrings_adt.h"
+					>
+				</File>
+				<File
+					RelativePath=".\common\include\wmspecstrings_strict.h"
+					>
+				</File>
+				<File
+					RelativePath=".\common\include\wmspecstrings_undef.h"
+					>
+				</File>
+			</Filter>
+			<Filter
+				Name="jxrgluelib"
+				>
+				<File
+					RelativePath=".\jxrgluelib\JXRGlue.h"
+					>
+				</File>
+				<File
+					RelativePath=".\jxrgluelib\JXRMeta.h"
+					>
+				</File>
+			</Filter>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/Source/LibJXR/LibJXR.2013.vcxproj b/Source/LibJXR/LibJXR.2013.vcxproj
new file mode 100644
index 0000000..4b207b8
--- /dev/null
+++ b/Source/LibJXR/LibJXR.2013.vcxproj
@@ -0,0 +1,205 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectName>LibJXR</ProjectName>
+    <ProjectGuid>{244455E0-5F25-4451-9540-F317883E52A8}</ProjectGuid>
+    <RootNamespace>LibJXR</RootNamespace>
+    <Keyword>Win32Proj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>12.0.21005.1</_ProjectFileVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>./image/sys;./jxrgluelib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;DISABLE_PERF_MEASUREMENT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+    </ClCompile>
+    <Lib />
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>./image/sys;./jxrgluelib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;DISABLE_PERF_MEASUREMENT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+    </ClCompile>
+    <Lib />
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <Optimization>Full</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <OmitFramePointers>true</OmitFramePointers>
+      <WholeProgramOptimization>false</WholeProgramOptimization>
+      <AdditionalIncludeDirectories>./image/sys;./jxrgluelib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;DISABLE_PERF_MEASUREMENT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>None</DebugInformationFormat>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+    </ClCompile>
+    <Lib />
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>Full</Optimization>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <AdditionalIncludeDirectories>./image/sys;./jxrgluelib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;DISABLE_PERF_MEASUREMENT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>None</DebugInformationFormat>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+    </ClCompile>
+    <Lib />
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="image\decode\decode.c" />
+    <ClCompile Include="image\decode\JXRTranscode.c" />
+    <ClCompile Include="image\decode\postprocess.c" />
+    <ClCompile Include="image\decode\segdec.c" />
+    <ClCompile Include="image\decode\strdec.c" />
+    <ClCompile Include="image\decode\strdec_x86.c" />
+    <ClCompile Include="image\decode\strInvTransform.c" />
+    <ClCompile Include="image\decode\strPredQuantDec.c" />
+    <ClCompile Include="image\encode\encode.c" />
+    <ClCompile Include="image\encode\segenc.c" />
+    <ClCompile Include="image\encode\strenc.c" />
+    <ClCompile Include="image\encode\strenc_x86.c" />
+    <ClCompile Include="image\encode\strFwdTransform.c" />
+    <ClCompile Include="image\encode\strPredQuantEnc.c" />
+    <ClCompile Include="image\sys\adapthuff.c" />
+    <ClCompile Include="image\sys\image.c" />
+    <ClCompile Include="image\sys\strcodec.c" />
+    <ClCompile Include="image\sys\strPredQuant.c" />
+    <ClCompile Include="image\sys\strTransform.c" />
+    <ClCompile Include="jxrgluelib\JXRGlue.c" />
+    <ClCompile Include="jxrgluelib\JXRGlueJxr.c" />
+    <ClCompile Include="jxrgluelib\JXRGluePFC.c" />
+    <ClCompile Include="jxrgluelib\JXRMeta.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="image\decode\decode.h" />
+    <ClInclude Include="image\encode\encode.h" />
+    <ClInclude Include="image\sys\ansi.h" />
+    <ClInclude Include="image\sys\common.h" />
+    <ClInclude Include="image\sys\perfTimer.h" />
+    <ClInclude Include="image\sys\strcodec.h" />
+    <ClInclude Include="image\sys\strTransform.h" />
+    <ClInclude Include="image\sys\windowsmediaphoto.h" />
+    <ClInclude Include="image\sys\xplatform_image.h" />
+    <ClInclude Include="image\x86\x86.h" />
+    <ClInclude Include="common\include\guiddef.h" />
+    <ClInclude Include="common\include\wmsal.h" />
+    <ClInclude Include="common\include\wmspecstring.h" />
+    <ClInclude Include="common\include\wmspecstrings_adt.h" />
+    <ClInclude Include="common\include\wmspecstrings_strict.h" />
+    <ClInclude Include="common\include\wmspecstrings_undef.h" />
+    <ClInclude Include="jxrgluelib\JXRGlue.h" />
+    <ClInclude Include="jxrgluelib\JXRMeta.h" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/Source/LibJXR/LibJXR.2013.vcxproj.filters b/Source/LibJXR/LibJXR.2013.vcxproj.filters
new file mode 100644
index 0000000..ce8c3e4
--- /dev/null
+++ b/Source/LibJXR/LibJXR.2013.vcxproj.filters
@@ -0,0 +1,176 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="Source Files\image">
+      <UniqueIdentifier>{aa1c9186-741f-44c1-a8eb-a123e2b79f67}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\image\decode">
+      <UniqueIdentifier>{162b0a1b-9fae-4718-ae3a-d5e368ccb2d7}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\image\encode">
+      <UniqueIdentifier>{4dd697d6-df80-4191-80e0-b76b283560de}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\image\sys">
+      <UniqueIdentifier>{198485ec-3a16-4413-b83f-fe0ea27b7b03}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\jxrgluelib">
+      <UniqueIdentifier>{18753b94-9bbe-47e7-952a-f77211b8be26}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+    </Filter>
+    <Filter Include="Header Files\image">
+      <UniqueIdentifier>{907228f6-8690-4b5b-8cd1-157334fed2ea}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\image\decode">
+      <UniqueIdentifier>{16fd291f-b1ac-4180-83e0-d1056e06e6a2}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\image\encode">
+      <UniqueIdentifier>{93b19a76-c065-48a3-a98b-23b8004d3003}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\image\sys">
+      <UniqueIdentifier>{22be93aa-6437-4cd1-9dbb-d9260cb0367d}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\image\x86">
+      <UniqueIdentifier>{de3920a0-9a86-442c-87ee-bda8be367c7e}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\common">
+      <UniqueIdentifier>{b3e6fba7-566f-4a9b-949a-57b4ed424c0e}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\jxrgluelib">
+      <UniqueIdentifier>{e086763a-d4af-4f0d-8358-bdd8bea2c79f}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="image\decode\decode.c">
+      <Filter>Source Files\image\decode</Filter>
+    </ClCompile>
+    <ClCompile Include="image\decode\JXRTranscode.c">
+      <Filter>Source Files\image\decode</Filter>
+    </ClCompile>
+    <ClCompile Include="image\decode\postprocess.c">
+      <Filter>Source Files\image\decode</Filter>
+    </ClCompile>
+    <ClCompile Include="image\decode\segdec.c">
+      <Filter>Source Files\image\decode</Filter>
+    </ClCompile>
+    <ClCompile Include="image\decode\strdec.c">
+      <Filter>Source Files\image\decode</Filter>
+    </ClCompile>
+    <ClCompile Include="image\decode\strdec_x86.c">
+      <Filter>Source Files\image\decode</Filter>
+    </ClCompile>
+    <ClCompile Include="image\decode\strInvTransform.c">
+      <Filter>Source Files\image\decode</Filter>
+    </ClCompile>
+    <ClCompile Include="image\decode\strPredQuantDec.c">
+      <Filter>Source Files\image\decode</Filter>
+    </ClCompile>
+    <ClCompile Include="image\encode\encode.c">
+      <Filter>Source Files\image\encode</Filter>
+    </ClCompile>
+    <ClCompile Include="image\encode\segenc.c">
+      <Filter>Source Files\image\encode</Filter>
+    </ClCompile>
+    <ClCompile Include="image\encode\strenc.c">
+      <Filter>Source Files\image\encode</Filter>
+    </ClCompile>
+    <ClCompile Include="image\encode\strenc_x86.c">
+      <Filter>Source Files\image\encode</Filter>
+    </ClCompile>
+    <ClCompile Include="image\encode\strFwdTransform.c">
+      <Filter>Source Files\image\encode</Filter>
+    </ClCompile>
+    <ClCompile Include="image\encode\strPredQuantEnc.c">
+      <Filter>Source Files\image\encode</Filter>
+    </ClCompile>
+    <ClCompile Include="image\sys\adapthuff.c">
+      <Filter>Source Files\image\sys</Filter>
+    </ClCompile>
+    <ClCompile Include="image\sys\image.c">
+      <Filter>Source Files\image\sys</Filter>
+    </ClCompile>
+    <ClCompile Include="image\sys\strcodec.c">
+      <Filter>Source Files\image\sys</Filter>
+    </ClCompile>
+    <ClCompile Include="image\sys\strPredQuant.c">
+      <Filter>Source Files\image\sys</Filter>
+    </ClCompile>
+    <ClCompile Include="image\sys\strTransform.c">
+      <Filter>Source Files\image\sys</Filter>
+    </ClCompile>
+    <ClCompile Include="jxrgluelib\JXRGlue.c">
+      <Filter>Source Files\jxrgluelib</Filter>
+    </ClCompile>
+    <ClCompile Include="jxrgluelib\JXRGlueJxr.c">
+      <Filter>Source Files\jxrgluelib</Filter>
+    </ClCompile>
+    <ClCompile Include="jxrgluelib\JXRGluePFC.c">
+      <Filter>Source Files\jxrgluelib</Filter>
+    </ClCompile>
+    <ClCompile Include="jxrgluelib\JXRMeta.c">
+      <Filter>Source Files\jxrgluelib</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="image\decode\decode.h">
+      <Filter>Header Files\image\decode</Filter>
+    </ClInclude>
+    <ClInclude Include="image\encode\encode.h">
+      <Filter>Header Files\image\encode</Filter>
+    </ClInclude>
+    <ClInclude Include="image\sys\ansi.h">
+      <Filter>Header Files\image\sys</Filter>
+    </ClInclude>
+    <ClInclude Include="image\sys\common.h">
+      <Filter>Header Files\image\sys</Filter>
+    </ClInclude>
+    <ClInclude Include="image\sys\perfTimer.h">
+      <Filter>Header Files\image\sys</Filter>
+    </ClInclude>
+    <ClInclude Include="image\sys\strcodec.h">
+      <Filter>Header Files\image\sys</Filter>
+    </ClInclude>
+    <ClInclude Include="image\sys\strTransform.h">
+      <Filter>Header Files\image\sys</Filter>
+    </ClInclude>
+    <ClInclude Include="image\sys\windowsmediaphoto.h">
+      <Filter>Header Files\image\sys</Filter>
+    </ClInclude>
+    <ClInclude Include="image\sys\xplatform_image.h">
+      <Filter>Header Files\image\sys</Filter>
+    </ClInclude>
+    <ClInclude Include="image\x86\x86.h">
+      <Filter>Header Files\image\x86</Filter>
+    </ClInclude>
+    <ClInclude Include="common\include\guiddef.h">
+      <Filter>Header Files\common</Filter>
+    </ClInclude>
+    <ClInclude Include="common\include\wmsal.h">
+      <Filter>Header Files\common</Filter>
+    </ClInclude>
+    <ClInclude Include="common\include\wmspecstring.h">
+      <Filter>Header Files\common</Filter>
+    </ClInclude>
+    <ClInclude Include="common\include\wmspecstrings_adt.h">
+      <Filter>Header Files\common</Filter>
+    </ClInclude>
+    <ClInclude Include="common\include\wmspecstrings_strict.h">
+      <Filter>Header Files\common</Filter>
+    </ClInclude>
+    <ClInclude Include="common\include\wmspecstrings_undef.h">
+      <Filter>Header Files\common</Filter>
+    </ClInclude>
+    <ClInclude Include="jxrgluelib\JXRGlue.h">
+      <Filter>Header Files\jxrgluelib</Filter>
+    </ClInclude>
+    <ClInclude Include="jxrgluelib\JXRMeta.h">
+      <Filter>Header Files\jxrgluelib</Filter>
+    </ClInclude>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/Source/LibJXR/README b/Source/LibJXR/README
new file mode 100644
index 0000000..a3f08db
--- /dev/null
+++ b/Source/LibJXR/README
@@ -0,0 +1 @@
+see https://jxrlib.codeplex.com/
diff --git a/Source/LibJXR/common/include/guiddef.h b/Source/LibJXR/common/include/guiddef.h
new file mode 100644
index 0000000..17e0ed3
--- /dev/null
+++ b/Source/LibJXR/common/include/guiddef.h
@@ -0,0 +1,230 @@
+//+---------------------------------------------------------------------------
+//
+// Copyright � Microsoft Corp.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+// � Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// � Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//  File:       guiddef.h
+//
+//  Contents:   GUID definition
+//
+//----------------------------------------------------------------------------
+
+#ifndef GUID_DEFINED
+#define GUID_DEFINED
+#if defined(__midl)
+typedef struct {
+    unsigned long  Data1;
+    unsigned short Data2;
+    unsigned short Data3;
+    byte           Data4[ 8 ];
+} GUID;
+#else
+typedef struct _GUID {
+#if defined(_WINDOWS_) || !__LP64__
+    unsigned long  Data1;
+#else
+    unsigned int   Data1;
+#endif
+    unsigned short Data2;
+    unsigned short Data3;
+    unsigned char  Data4[ 8 ];
+} GUID;
+#endif
+#endif
+
+#ifndef FAR
+#if defined(_WIN32) || defined(__ANSI__)
+#define FAR
+#else
+#define FAR _far
+#endif
+#endif
+
+#ifndef DECLSPEC_SELECTANY
+#if (_MSC_VER >= 1100)
+#define DECLSPEC_SELECTANY  __declspec(selectany)
+#else
+#define DECLSPEC_SELECTANY
+#endif
+#endif
+
+#ifndef EXTERN_C
+#ifdef __cplusplus
+#define EXTERN_C    extern "C"
+#else
+#define EXTERN_C    extern
+#endif
+#endif
+
+#ifdef DEFINE_GUID
+#undef DEFINE_GUID
+#endif
+
+#ifdef INITGUID
+#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
+        const GUID DECLSPEC_SELECTANY name \
+                = { l, w1, w2, { b1, b2,  b3,  b4,  b5,  b6,  b7,  b8 } }
+#else
+#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
+    EXTERN_C const GUID FAR name
+#endif // INITGUID
+
+#define DEFINE_OLEGUID(name, l, w1, w2) DEFINE_GUID(name, l, w1, w2, 0xC0,0,0,0,0,0,0,0x46)
+
+#ifndef _GUIDDEF_H_
+#define _GUIDDEF_H_
+
+#ifndef __LPGUID_DEFINED__
+#define __LPGUID_DEFINED__
+typedef GUID *LPGUID;
+#endif
+
+#ifndef __LPCGUID_DEFINED__
+#define __LPCGUID_DEFINED__
+typedef const GUID *LPCGUID;
+#endif
+
+#ifndef __IID_DEFINED__
+#define __IID_DEFINED__
+
+typedef GUID IID;
+typedef IID *LPIID;
+#define IID_NULL            GUID_NULL
+#define IsEqualIID(riid1, riid2) IsEqualGUID(riid1, riid2)
+typedef GUID CLSID;
+typedef CLSID *LPCLSID;
+#define CLSID_NULL          GUID_NULL
+#define IsEqualCLSID(rclsid1, rclsid2) IsEqualGUID(rclsid1, rclsid2)
+typedef GUID FMTID;
+typedef FMTID *LPFMTID;
+#define FMTID_NULL          GUID_NULL
+#define IsEqualFMTID(rfmtid1, rfmtid2) IsEqualGUID(rfmtid1, rfmtid2)
+
+#ifdef __midl_proxy
+#define __MIDL_CONST
+#else
+#define __MIDL_CONST const
+#endif
+
+#ifndef _REFGUID_DEFINED
+#define _REFGUID_DEFINED
+#ifdef __cplusplus
+#define REFGUID const GUID &
+#else
+#define REFGUID const GUID * __MIDL_CONST
+#endif
+#endif
+
+#ifndef _REFIID_DEFINED
+#define _REFIID_DEFINED
+#ifdef __cplusplus
+#define REFIID const IID &
+#else
+#define REFIID const IID * __MIDL_CONST
+#endif
+#endif
+
+#ifndef _REFCLSID_DEFINED
+#define _REFCLSID_DEFINED
+#ifdef __cplusplus
+#define REFCLSID const IID &
+#else
+#define REFCLSID const IID * __MIDL_CONST
+#endif
+#endif
+
+#ifndef _REFFMTID_DEFINED
+#define _REFFMTID_DEFINED
+#ifdef __cplusplus
+#define REFFMTID const IID &
+#else
+#define REFFMTID const IID * __MIDL_CONST
+#endif
+#endif
+
+#endif // !__IID_DEFINED__
+
+#if !defined (__midl)
+#if !defined (_SYS_GUID_OPERATORS_)
+#define _SYS_GUID_OPERATORS_
+#include <string.h>
+
+// Faster (but makes code fatter) inline version...use sparingly
+#ifdef __cplusplus
+__inline int InlineIsEqualGUID(REFGUID rguid1, REFGUID rguid2)
+{
+   return (
+      ((unsigned long *) &rguid1)[0] == ((unsigned long *) &rguid2)[0] &&
+      ((unsigned long *) &rguid1)[1] == ((unsigned long *) &rguid2)[1] &&
+      ((unsigned long *) &rguid1)[2] == ((unsigned long *) &rguid2)[2] &&
+      ((unsigned long *) &rguid1)[3] == ((unsigned long *) &rguid2)[3]);
+}
+
+__inline int IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
+{
+    return !memcmp(&rguid1, &rguid2, sizeof(GUID));
+}
+
+#else   // ! __cplusplus
+
+#define InlineIsEqualGUID(rguid1, rguid2)  \
+        (((unsigned long *) rguid1)[0] == ((unsigned long *) rguid2)[0] &&   \
+        ((unsigned long *) rguid1)[1] == ((unsigned long *) rguid2)[1] &&    \
+        ((unsigned long *) rguid1)[2] == ((unsigned long *) rguid2)[2] &&    \
+        ((unsigned long *) rguid1)[3] == ((unsigned long *) rguid2)[3])
+
+#define IsEqualGUID(rguid1, rguid2) (!memcmp(rguid1, rguid2, sizeof(GUID)))
+
+#endif  // __cplusplus
+
+#ifdef __INLINE_ISEQUAL_GUID
+#undef IsEqualGUID
+#define IsEqualGUID(rguid1, rguid2) InlineIsEqualGUID(rguid1, rguid2)
+#endif
+
+// Same type, different name
+
+#define IsEqualIID(riid1, riid2) IsEqualGUID(riid1, riid2)
+#define IsEqualCLSID(rclsid1, rclsid2) IsEqualGUID(rclsid1, rclsid2)
+
+
+#if !defined _SYS_GUID_OPERATOR_EQ_ && !defined _NO_SYS_GUID_OPERATOR_EQ_
+#define _SYS_GUID_OPERATOR_EQ_
+// A couple of C++ helpers
+
+#ifdef __cplusplus
+__inline int operator==(REFGUID guidOne, REFGUID guidOther)
+{
+    return IsEqualGUID(guidOne,guidOther);
+}
+
+__inline int operator!=(REFGUID guidOne, REFGUID guidOther)
+{
+    return !(guidOne == guidOther);
+}
+#endif
+#endif  // _SYS_GUID_OPERATOR_EQ_
+#endif  // _SYS_GUID_OPERATORS_
+#endif  // __midl
+#endif  // _GUIDDEF_H_
diff --git a/Source/LibJXR/common/include/wmsal.h b/Source/LibJXR/common/include/wmsal.h
new file mode 100644
index 0000000..736ef83
--- /dev/null
+++ b/Source/LibJXR/common/include/wmsal.h
@@ -0,0 +1,757 @@
+/***
+*sal.h - markers for documenting the semantics of APIs
+*
+* Copyright � Microsoft Corp.
+* All rights reserved.
+* 
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+* 
+* � Redistributions of source code must retain the above copyright notice,
+*   this list of conditions and the following disclaimer.
+* � Redistributions in binary form must reproduce the above copyright notice,
+*   this list of conditions and the following disclaimer in the documentation
+*   and/or other materials provided with the distribution.
+* 
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*
+*Purpose:
+*       sal.h provides a set of annotations to describe how a function uses its
+*       parameters - the assumptions it makes about them, and the guarantees it makes
+*       upon finishing.
+*
+*       [Public]
+*
+****/
+
+/* 
+ -------------------------------------------------------------------------------
+ Introduction
+
+ sal.h provides a set of annotations to describe how a function uses its
+ parameters - the assumptions it makes about them, and the guarantees it makes
+ upon finishing.
+
+ Annotations may be placed before either a function parameter's type or its return
+ type, and describe the function's behavior regarding the parameter or return value.
+ There are two classes of annotations: buffer annotations and advanced annotations.
+ Buffer annotations describe how functions use their pointer parameters, and
+ advanced annotations either describe complex/unusual buffer behavior, or provide
+ additional information about a parameter that is not otherwise expressible.
+
+ -------------------------------------------------------------------------------
+ Buffer Annotations
+
+ The most important annotations in sal.h provide a consistent way to annotate
+ buffer parameters or return values for a function. Each of these annotations describes
+ a single buffer (which could be a string, a fixed-length or variable-length array,
+ or just a pointer) that the function interacts with: where it is, how large it is,
+ how much is initialized, and what the function does with it.
+
+ The appropriate macro for a given buffer can be constructed using the table below.
+ Just pick the appropriate values from each category, and combine them together
+ with a leading underscore. Some combinations of values do not make sense as buffer
+ annotations. Only meaningful annotations can be added to your code; for a list of
+ these, see the buffer annotation definitions section.
+
+ Only a single buffer annotation should be used for each parameter.
+
+ |------------|------------|---------|--------|----------|----------|---------------|
+ |   Level    |   Usage    |  Size   | Output | NullTerm | Optional |  Parameters   |
+ |------------|------------|---------|--------|----------|----------|---------------|
+ | <>         | <>         | <>      | <>     | _z       | <>       | <>            |
+ | _deref     | _in        | _ecount | _full  | _nz      | _opt     | (size)        |
+ | _deref_opt | _out       | _bcount | _part  |          |          | (size,length) |
+ |            | _inout     |         |        |          |          |               |
+ |            |            |         |        |          |          |               |
+ |------------|------------|---------|--------|----------|----------|---------------|
+
+ Level: Describes the buffer pointer's level of indirection from the parameter or
+          return value 'p'.
+
+ <>         : p is the buffer pointer.
+ _deref     : *p is the buffer pointer. p must not be NULL.
+ _deref_opt : *p may be the buffer pointer. p may be NULL, in which case the rest of
+                the annotation is ignored.
+
+ Usage: Describes how the function uses the buffer.
+
+ <>     : The buffer is not accessed. If used on the return value or with _deref, the
+            function will provide the buffer, and it will be uninitialized at exit.
+            Otherwise, the caller must provide the buffer. This should only be used
+            for alloc and free functions.
+ _in    : The function will only read from the buffer. The caller must provide the
+            buffer and initialize it. Cannot be used with _deref.
+ _out   : The function will only write to the buffer. If used on the return value or
+            with _deref, the function will provide the buffer and initialize it.
+            Otherwise, the caller must provide the buffer, and the function will
+            initialize it.
+ _inout : The function may freely read from and write to the buffer. The caller must
+            provide the buffer and initialize it. If used with _deref, the buffer may
+            be reallocated by the function.
+
+ Size: Describes the total size of the buffer. This may be less than the space actually
+         allocated for the buffer, in which case it describes the accessible amount.
+
+ <>      : No buffer size is given. If the type specifies the buffer size (such as
+             with LPSTR and LPWSTR), that amount is used. Otherwise, the buffer is one
+             element long. Must be used with _in, _out, or _inout.
+ _ecount : The buffer size is an explicit element count.
+ _bcount : The buffer size is an explicit byte count.
+
+ Output: Describes how much of the buffer will be initialized by the function. For
+           _inout buffers, this also describes how much is initialized at entry. Omit this
+           category for _in buffers; they must be fully initialized by the caller.
+
+ <>    : The type specifies how much is initialized. For instance, a function initializing
+           an LPWSTR must NULL-terminate the string.
+ _full : The function initializes the entire buffer.
+ _part : The function initializes part of the buffer, and explicitly indicates how much.
+
+ NullTerm: States if the present of a '\0' marks the end of valid elements in the buffer.
+ _z    : A '\0' indicated the end of the buffer
+ _nz	 : The buffer may not be null terminated and a '\0' does not indicate the end of the
+          buffer.
+ Optional: Describes if the buffer itself is optional.
+
+ <>   : The pointer to the buffer must not be NULL.
+ _opt : The pointer to the buffer might be NULL. It will be checked before being dereferenced.
+
+ Parameters: Gives explicit counts for the size and length of the buffer.
+
+ <>            : There is no explicit count. Use when neither _ecount nor _bcount is used.
+ (size)        : Only the buffer's total size is given. Use with _ecount or _bcount but not _part.
+ (size,length) : The buffer's total size and initialized length are given. Use with _ecount_part
+                   and _bcount_part.
+
+ -------------------------------------------------------------------------------
+ Buffer Annotation Examples
+
+ LWSTDAPI_(BOOL) StrToIntExA(
+     LPCSTR pszString,                    -- No annotation required, const implies __in.
+     DWORD dwFlags,
+     __out int *piRet                     -- A pointer whose dereference will be filled in.
+ );
+
+ void MyPaintingFunction(
+     __in HWND hwndControl,               -- An initialized read-only parameter.
+     __in_opt HDC hdcOptional,            -- An initialized read-only parameter that might be NULL.
+     __inout IPropertyStore *ppsStore     -- An initialized parameter that may be freely used
+                                          --   and modified.
+ );
+
+ LWSTDAPI_(BOOL) PathCompactPathExA(
+     __out_ecount(cchMax) LPSTR pszOut,   -- A string buffer with cch elements that will
+                                          --   be NULL terminated on exit.
+     LPCSTR pszSrc,                       -- No annotation required, const implies __in.
+     UINT cchMax,
+     DWORD dwFlags
+ );
+
+ HRESULT SHLocalAllocBytes(
+     size_t cb,
+     __deref_bcount(cb) T **ppv           -- A pointer whose dereference will be set to an
+                                          --   uninitialized buffer with cb bytes.
+ );
+
+ __inout_bcount_full(cb) : A buffer with cb elements that is fully initialized at
+     entry and exit, and may be written to by this function.
+
+ __out_ecount_part(count, *countOut) : A buffer with count elements that will be
+     partially initialized by this function. The function indicates how much it
+     initialized by setting *countOut.
+
+ -------------------------------------------------------------------------------
+ Advanced Annotations
+
+ Advanced annotations describe behavior that is not expressible with the regular
+ buffer macros. These may be used either to annotate buffer parameters that involve
+ complex or conditional behavior, or to enrich existing annotations with additional
+ information.
+
+ __success(expr) f :
+     <expr> indicates whether function f succeeded or not. If <expr> is true at exit,
+     all the function's guarantees (as given by other annotations) must hold. If <expr>
+     is false at exit, the caller should not expect any of the function's guarantees
+     to hold. If not used, the function must always satisfy its guarantees. Added
+     automatically to functions that indicate success in standard ways, such as by
+     returning an HRESULT.
+
+ __nullterminated p :
+     Pointer p is a buffer that may be read or written up to and including the first
+     NULL character or pointer. May be used on typedefs, which marks valid (properly
+     initialized) instances of that type as being NULL-terminated.
+
+ __nullnullterminated p :
+     Pointer p is a buffer that may be read or written up to and including the first
+     sequence of two NULL characters or pointers. May be used on typedefs, which marks
+     valid instances of that type as being double-NULL terminated.
+
+ __reserved v :
+     Value v must be 0/NULL, reserved for future use.
+
+ __checkReturn v :
+     Return value v must not be ignored by callers of this function.
+
+ __typefix(ctype) v :
+     Value v should be treated as an instance of ctype, rather than its declared type.
+
+ __override f :
+     Specify C#-style 'override' behaviour for overriding virtual methods.
+
+ __callback f :
+     Function f can be used as a function pointer.
+
+ __format_string p :
+     Pointer p is a string that contains % markers in the style of printf.
+
+ __blocksOn(resource) f :
+     Function f blocks on the resource 'resource'.
+
+ __fallthrough :
+     Annotates switch statement labels where fall-through is desired, to distinguish
+     from forgotten break statements.
+
+ -------------------------------------------------------------------------------
+ Advanced Annotation Examples
+
+ __success(return == TRUE) LWSTDAPI_(BOOL) 
+ PathCanonicalizeA(__out_ecount(MAX_PATH) LPSTR pszBuf, LPCSTR pszPath) :
+     pszBuf is only guaranteed to be NULL-terminated when TRUE is returned.
+
+ typedef __nullterminated WCHAR* LPWSTR : Initialized LPWSTRs are NULL-terminated strings.
+
+ __out_ecount(cch) __typefix(LPWSTR) void *psz : psz is a buffer parameter which will be
+     a NULL-terminated WCHAR string at exit, and which initially contains cch WCHARs.
+
+ -------------------------------------------------------------------------------
+*/
+
+#pragma once
+#ifndef __specstrings
+#define __specstrings
+
+#ifdef  __cplusplus
+#ifndef __nothrow
+# define __nothrow __declspec(nothrow)
+#endif
+extern "C" {
+#else
+#ifndef __nothrow
+# define __nothrow
+#endif
+#endif  /* #ifdef __cplusplus */
+
+/*
+ -------------------------------------------------------------------------------
+ Helper Macro Definitions
+
+ These express behavior common to many of the high-level annotations.
+ DO NOT USE THESE IN YOUR CODE.
+ -------------------------------------------------------------------------------
+*/
+
+/*
+The helper annotations are only understood by the compiler version used by various
+defect detection tools. When the regular compiler is running, they are defined into
+nothing, and do not affect the compiled code.
+*/
+
+#if !defined(__midl) && defined(_PREFAST_) 
+
+    /*
+     In the primitive __declspec("SAL_*") annotations "SAL" stands for Standard
+     Annotation Language.  These __declspec("SAL_*") annotations are the
+     primitives the compiler understands and all high-level SpecString MACROs
+     will decompose into these primivates.
+    */
+
+    #define SPECSTRINGIZE( x ) #x
+
+    /*
+     __null p
+     __notnull p
+     __maybenull p
+    
+     Annotates a pointer p. States that pointer p is null. Commonly used
+     in the negated form __notnull or the possibly null form __maybenull.
+    */
+
+//    #define __null                  __declspec("SAL_null")
+    #define __notnull               __declspec("SAL_notnull")
+    #define __maybenull             __declspec("SAL_maybenull")
+
+    /*
+     __readonly l
+     __notreadonly l
+     __mabyereadonly l
+    
+     Annotates a location l. States that location l is not modified after
+     this point.  If the annotation is placed on the precondition state of
+     a function, the restriction only applies until the postcondition state
+     of the function.  __maybereadonly states that the annotated location
+     may be modified, whereas __notreadonly states that a location must be
+     modified.
+    */
+
+    #define __readonly              __declspec("SAL_readonly")
+    #define __notreadonly           __declspec("SAL_notreadonly")
+    #define __maybereadonly         __declspec("SAL_maybereadonly")
+
+    /*
+     __valid v
+     __notvalid v
+     __maybevalid v
+    
+     Annotates any value v. States that the value satisfies all properties of
+     valid values of its type. For example, for a string buffer, valid means
+     that the buffer pointer is either NULL or points to a NULL-terminated string.
+    */
+
+    #define __valid                 __declspec("SAL_valid")
+    #define __notvalid              __declspec("SAL_notvalid")
+    #define __maybevalid            __declspec("SAL_maybevalid")
+
+    /*
+     __readableTo(extent) p
+    
+     Annotates a buffer pointer p.  If the buffer can be read, extent describes
+     how much of the buffer is readable. For a reader of the buffer, this is
+     an explicit permission to read up to that amount, rather than a restriction to
+     read only up to it.
+    */
+
+    #define __readableTo(extent)    __declspec("SAL_readableTo("SPECSTRINGIZE(extent)")")
+
+    /*
+    
+     __elem_readableTo(size)
+    
+     Annotates a buffer pointer p as being readable to size elements.
+    */
+
+    #define __elem_readableTo(size)   __declspec("SAL_readableTo(elementCount("SPECSTRINGIZE(size)"))")
+    
+    /*
+     __byte_readableTo(size)
+    
+     Annotates a buffer pointer p as being readable to size bytes.
+    */
+    #define __byte_readableTo(size)   __declspec("SAL_readableTo(byteCount("SPECSTRINGIZE(size)"))")
+    
+    /*
+     __writableTo(extent) p
+    
+     Annotates a buffer pointer p. If the buffer can be modified, extent
+     describes how much of the buffer is writable (usually the allocation
+     size). For a writer of the buffer, this is an explicit permission to
+     write up to that amount, rather than a restriction to write only up to it.
+    */
+    #define __writableTo(size)   __declspec("SAL_writableTo("SPECSTRINGIZE(size)")")
+
+    /*
+     __elem_writableTo(size)
+    
+     Annotates a buffer pointer p as being writable to size elements.
+    */
+    #define __elem_writableTo(size)   __declspec("SAL_writableTo(elementCount("SPECSTRINGIZE(size)"))")
+    
+    /*
+     __byte_writableTo(size)
+    
+     Annotates a buffer pointer p as being writable to size bytes.
+    */
+    #define __byte_writableTo(size)   __declspec("SAL_writableTo(byteCount("SPECSTRINGIZE(size)"))")
+
+    /*
+     __deref p
+    
+     Annotates a pointer p. The next annotation applies one dereference down
+     in the type. If readableTo(p, size) then the next annotation applies to
+     all elements *(p+i) for which i satisfies the size. If p is a pointer
+     to a struct, the next annotation applies to all fields of the struct.
+    */
+    #define __deref                 __declspec("SAL_deref")
+    
+    /*
+     __pre __next_annotation
+    
+     The next annotation applies in the precondition state
+    */
+    #define __pre                   __declspec("SAL_pre")
+    
+    /*
+     __post __next_annotation
+    
+     The next annotation applies in the postcondition state
+    */
+    #define __post                  __declspec("SAL_post")
+    
+    /*
+     __precond(<expr>)
+    
+     When <expr> is true, the next annotation applies in the precondition state
+     (currently not enabled)
+    */
+    #define __precond(expr)         __pre
+
+    /*
+     __postcond(<expr>)
+    
+     When <expr> is true, the next annotation applies in the postcondition state
+     (currently not enabled)
+    */
+    #define __postcond(expr)        __post
+
+    /*
+     __exceptthat
+    
+     Given a set of annotations Q containing __exceptthat maybeP, the effect of
+     the except clause is to erase any P or notP annotations (explicit or
+     implied) within Q at the same level of dereferencing that the except
+     clause appears, and to replace it with maybeP.
+    
+      Example 1: __valid __exceptthat __maybenull on a pointer p means that the
+                 pointer may be null, and is otherwise valid, thus overriding
+                 the implicit notnull annotation implied by __valid on
+                 pointers.
+    
+      Example 2: __valid __deref __exceptthat __maybenull on an int **p means
+                 that p is not null (implied by valid), but the elements
+                 pointed to by p could be null, and are otherwise valid. 
+    */
+    #define __exceptthat                __declspec("SAL_except")
+    #define __execeptthat               __exceptthat
+ 
+    /*
+     _refparam
+    
+     Added to all out parameter macros to indicate that they are all reference
+     parameters.
+    */
+    #define __refparam                  __deref __notreadonly
+
+    /*
+     __inner_*
+    
+     Helper macros that directly correspond to certain high-level annotations.
+    
+    */
+
+    /*
+     Macros to classify the entrypoints and indicate their category.
+    
+     Pre-defined control point categories include: RPC, LPC, DeviceDriver, UserToKernel, ISAPI, COM.
+    
+    */
+    #define __inner_control_entrypoint(category) __declspec("SAL_entrypoint(controlEntry, "SPECSTRINGIZE(category)")")
+
+    /*
+     Pre-defined data entry point categories include: Registry, File, Network.
+    */
+    #define __inner_data_entrypoint(category)    __declspec("SAL_entrypoint(dataEntry, "SPECSTRINGIZE(category)")")
+
+    #define __inner_success(expr)               __declspec("SAL_success("SPECSTRINGIZE(expr)")")
+    #define __inner_checkReturn                 __declspec("SAL_checkReturn")
+    #define __inner_typefix(ctype)              __declspec("SAL_typefix("SPECSTRINGIZE(ctype)")")
+    #define __inner_override                    __declspec("__override")
+    #define __inner_callback                    __declspec("__callback")
+    #define __inner_blocksOn(resource)          __declspec("SAL_blocksOn("SPECSTRINGIZE(resource)")")
+    #define __inner_fallthrough_dec             __inline __nothrow void __FallThrough() {}
+    #define __inner_fallthrough                 __FallThrough();
+
+#else
+//  This conflicts with gcc definition of __null.
+//    #define __null
+    #define __notnull
+    #define __maybenull
+    #define __readonly
+    #define __notreadonly
+    #define __maybereadonly
+    #define __valid
+    #define __notvalid
+    #define __maybevalid
+    #define __readableTo(extent)
+    #define __elem_readableTo(size)
+    #define __byte_readableTo(size)
+    #define __writableTo(size)
+    #define __elem_writableTo(size)
+    #define __byte_writableTo(size)
+    #define __deref
+    #define __pre
+    #define __post
+    #define __precond(expr)
+    #define __postcond(expr)
+    #define __exceptthat
+    #define __execeptthat
+    #define __inner_success(expr)
+    #define __inner_checkReturn
+    #define __inner_typefix(ctype)
+    #define __inner_override
+    #define __inner_callback
+    #define __inner_blocksOn(resource)
+    #define __inner_fallthrough_dec
+    #define __inner_fallthrough
+    #define __refparam
+    #define __inner_control_entrypoint(category)
+    #define __inner_data_entrypoint(category)
+#endif /* #if !defined(__midl) && defined(_PREFAST_) */
+
+/* 
+-------------------------------------------------------------------------------
+Buffer Annotation Definitions
+
+Any of these may be used to directly annotate functions, but only one should
+be used for each parameter. To determine which annotation to use for a given
+buffer, use the table in the buffer annotations section.
+-------------------------------------------------------------------------------
+*/
+
+#define __ecount(size)                                          __notnull __elem_writableTo(size)
+#define __bcount(size)                                          __notnull __byte_writableTo(size)
+//#define __in                                                    __pre __valid __pre __deref __readonly
+#define __in_win                                                __pre __valid __pre __deref __readonly
+
+#define __in_ecount(size)                                       __in_win __pre __elem_readableTo(size)
+#define __in_bcount(size)                                       __in_win __pre __byte_readableTo(size)
+#define __in_z                                                  __in_win __pre __nullterminated
+#define __in_ecount_z(size)                                     __in_ecount(size) __pre __nullterminated
+#define __in_bcount_z(size)                                     __in_bcount(size) __pre __nullterminated
+#define __in_nz                                                 __in_win
+#define __in_ecount_nz(size)                                    __in_ecount(size)
+#define __in_bcount_nz(size)                                    __in_bcount(size)
+
+//#define __out                                                   __ecount(1) __post __valid __refparam
+#define __out_win                                                 __ecount(1) __post __valid __refparam
+
+#define __out_ecount(size)                                      __ecount(size) __post __valid __refparam
+#define __out_bcount(size)                                      __bcount(size) __post __valid __refparam
+#define __out_ecount_part(size,length)                          __out_ecount(size) __post __elem_readableTo(length)
+#define __out_bcount_part(size,length)                          __out_bcount(size) __post __byte_readableTo(length)
+#define __out_ecount_full(size)                                 __out_ecount_part(size,size)
+#define __out_bcount_full(size)                                 __out_bcount_part(size,size)
+#define __out_z                                                 __post __valid __refparam __post __nullterminated
+#define __out_z_opt                                             __post __valid __refparam __post __nullterminated __exceptthat __maybenull
+#define __out_ecount_z(size)                                    __ecount(size) __post __valid __refparam __post __nullterminated
+#define __out_bcount_z(size)                                    __bcount(size) __post __valid __refparam __post __nullterminated
+#define __out_ecount_part_z(size,length)                        __out_ecount_part(size,length) __post __nullterminated
+#define __out_bcount_part_z(size,length)                        __out_bcount_part(size,length) __post __nullterminated
+#define __out_ecount_full_z(size)                               __out_ecount_full(size) __post __nullterminated
+#define __out_bcount_full_z(size)                               __out_bcount_full(size) __post __nullterminated
+#define __out_nz                                                __post __valid __refparam __post
+#define __out_nz_opt                                            __post __valid __refparam __post __exceptthat __maybenull
+#define __out_ecount_nz(size)                                   __ecount(size) __post __valid __refparam
+#define __out_bcount_nz(size)                                   __bcount(size) __post __valid __refparam
+#define __inout                                                 __pre __valid __post __valid __refparam
+#define __inout_ecount(size)                                    __out_ecount(size) __pre __valid
+#define __inout_bcount(size)                                    __out_bcount(size) __pre __valid
+#define __inout_ecount_part(size,length)                        __out_ecount_part(size,length) __pre __valid __pre __elem_readableTo(length)
+#define __inout_bcount_part(size,length)                        __out_bcount_part(size,length) __pre __valid __pre __byte_readableTo(length)
+#define __inout_ecount_full(size)                               __inout_ecount_part(size,size)
+#define __inout_bcount_full(size)                               __inout_bcount_part(size,size)
+#define __inout_z                                               __inout __pre __nullterminated __post __nullterminated
+#define __inout_ecount_z(size)                                  __inout_ecount(size) __pre __nullterminated __post __nullterminated
+#define __inout_bcount_z(size)                                  __inout_bcount(size) __pre __nullterminated __post __nullterminated
+#define __inout_nz                                              __inout
+#define __inout_ecount_nz(size)                                 __inout_ecount(size) 
+#define __inout_bcount_nz(size)                                 __inout_bcount(size) 
+#define __ecount_opt(size)                                      __ecount(size)                              __exceptthat __maybenull
+#define __bcount_opt(size)                                      __bcount(size)                              __exceptthat __maybenull
+#define __in_opt                                                __in_win                                        __exceptthat __maybenull
+#define __in_ecount_opt(size)                                   __in_ecount(size)                           __exceptthat __maybenull
+#define __in_bcount_opt(size)                                   __in_bcount(size)                           __exceptthat __maybenull
+#define __in_z_opt                                              __in_opt __pre __nullterminated 
+#define __in_ecount_z_opt(size)                                 __in_ecount_opt(size) __pre __nullterminated 
+#define __in_bcount_z_opt(size)                                 __in_bcount_opt(size) __pre __nullterminated
+#define __in_nz_opt                                             __in_opt                                     
+#define __in_ecount_nz_opt(size)                                __in_ecount_opt(size)                         
+#define __in_bcount_nz_opt(size)                                __in_bcount_opt(size)                         
+#define __out_opt                                               __out_win                                       __exceptthat __maybenull
+#define __out_ecount_opt(size)                                  __out_ecount(size)                          __exceptthat __maybenull
+#define __out_bcount_opt(size)                                  __out_bcount(size)                          __exceptthat __maybenull
+#define __out_ecount_part_opt(size,length)                      __out_ecount_part(size,length)              __exceptthat __maybenull
+#define __out_bcount_part_opt(size,length)                      __out_bcount_part(size,length)              __exceptthat __maybenull
+#define __out_ecount_full_opt(size)                             __out_ecount_full(size)                     __exceptthat __maybenull
+#define __out_bcount_full_opt(size)                             __out_bcount_full(size)                     __exceptthat __maybenull
+#define __out_ecount_z_opt(size)                                __out_ecount_opt(size) __post __nullterminated
+#define __out_bcount_z_opt(size)                                __out_bcount_opt(size) __post __nullterminated
+#define __out_ecount_part_z_opt(size,length)                    __out_ecount_part_opt(size,length) __post __nullterminated
+#define __out_bcount_part_z_opt(size,length)                    __out_bcount_part_opt(size,length) __post __nullterminated
+#define __out_ecount_full_z_opt(size)                           __out_ecount_full_opt(size) __post __nullterminated
+#define __out_bcount_full_z_opt(size)                           __out_bcount_full_opt(size) __post __nullterminated
+#define __out_ecount_nz_opt(size)                               __out_ecount_opt(size) __post __nullterminated                       
+#define __out_bcount_nz_opt(size)                               __out_bcount_opt(size) __post __nullterminated                        
+#define __inout_opt                                             __inout                                     __exceptthat __maybenull
+#define __inout_ecount_opt(size)                                __inout_ecount(size)                        __exceptthat __maybenull
+#define __inout_bcount_opt(size)                                __inout_bcount(size)                        __exceptthat __maybenull
+#define __inout_ecount_part_opt(size,length)                    __inout_ecount_part(size,length)            __exceptthat __maybenull
+#define __inout_bcount_part_opt(size,length)                    __inout_bcount_part(size,length)            __exceptthat __maybenull
+#define __inout_ecount_full_opt(size)                           __inout_ecount_full(size)                   __exceptthat __maybenull
+#define __inout_bcount_full_opt(size)                           __inout_bcount_full(size)                   __exceptthat __maybenull
+#define __inout_z_opt                                           __inout_opt __pre __nullterminated __post __nullterminated
+#define __inout_ecount_z_opt(size)                              __inout_ecount_opt(size) __pre __nullterminated __post __nullterminated
+#define __inout_ecount_z_opt(size)                              __inout_ecount_opt(size) __pre __nullterminated __post __nullterminated
+#define __inout_bcount_z_opt(size)                              __inout_bcount_opt(size) 
+#define __inout_nz_opt                                          __inout_opt
+#define __inout_ecount_nz_opt(size)                             __inout_ecount_opt(size)
+#define __inout_bcount_nz_opt(size)                             __inout_bcount_opt(size)
+#define __deref_ecount(size)                                    __ecount(1) __post __elem_readableTo(1) __post __deref __notnull __post __deref __elem_writableTo(size)
+#define __deref_bcount(size)                                    __ecount(1) __post __elem_readableTo(1) __post __deref __notnull __post __deref __byte_writableTo(size)
+#define __deref_out                                             __deref_ecount(1) __post __deref __valid __refparam
+#define __deref_out_ecount(size)                                __deref_ecount(size) __post __deref __valid __refparam
+#define __deref_out_bcount(size)                                __deref_bcount(size) __post __deref __valid __refparam
+#define __deref_out_ecount_part(size,length)                    __deref_out_ecount(size) __post __deref __elem_readableTo(length)
+#define __deref_out_bcount_part(size,length)                    __deref_out_bcount(size) __post __deref __byte_readableTo(length)
+#define __deref_out_ecount_full(size)                           __deref_out_ecount_part(size,size)
+#define __deref_out_bcount_full(size)                           __deref_out_bcount_part(size,size)
+#define __deref_out_z                                           __post __deref __valid __refparam __post __deref __nullterminated
+#define __deref_out_ecount_z(size)                              __deref_out_ecount(size) __post __deref __nullterminated  
+#define __deref_out_bcount_z(size)                              __deref_out_ecount(size) __post __deref __nullterminated  
+#define __deref_out_nz                                          __deref_out
+#define __deref_out_ecount_nz(size)                             __deref_out_ecount(size)   
+#define __deref_out_bcount_nz(size)                             __deref_out_ecount(size)   
+#define __deref_inout                                           __notnull __elem_readableTo(1) __pre __deref __valid __post __deref __valid __refparam
+#define __deref_inout_z                                         __deref_inout __pre __deref __nullterminated __post __deref __nullterminated
+#define __deref_inout_ecount(size)                              __deref_inout __pre __deref __elem_writableTo(size) __post __deref __elem_writableTo(size)
+#define __deref_inout_bcount(size)                              __deref_inout __pre __deref __byte_writableTo(size) __post __deref __byte_writableTo(size)
+#define __deref_inout_ecount_part(size,length)                  __deref_inout_ecount(size) __pre __deref __elem_readableTo(length) __post __deref __elem_readableTo(length)
+#define __deref_inout_bcount_part(size,length)                  __deref_inout_bcount(size) __pre __deref __byte_readableTo(length) __post __deref __byte_readableTo(length)
+#define __deref_inout_ecount_full(size)                         __deref_inout_ecount_part(size,size)
+#define __deref_inout_bcount_full(size)                         __deref_inout_bcount_part(size,size)
+#define __deref_inout_z                                         __deref_inout __pre __deref __nullterminated __post __deref __nullterminated
+#define __deref_inout_ecount_z(size)                            __deref_inout_ecount(size) __pre __deref __nullterminated __post __deref __nullterminated   
+#define __deref_inout_bcount_z(size)                            __deref_inout_ecount(size) __pre __deref __nullterminated __post __deref __nullterminated  
+#define __deref_inout_nz                                        __deref_inout
+#define __deref_inout_ecount_nz(size)                           __deref_inout_ecount(size)   
+#define __deref_inout_bcount_nz(size)                           __deref_inout_ecount(size)   
+#define __deref_ecount_opt(size)                                __deref_ecount(size)                        __post __deref __exceptthat __maybenull
+#define __deref_bcount_opt(size)                                __deref_bcount(size)                        __post __deref __exceptthat __maybenull
+#define __deref_out_opt                                         __deref_out                                 __post __deref __exceptthat __maybenull
+#define __deref_out_ecount_opt(size)                            __deref_out_ecount(size)                    __post __deref __exceptthat __maybenull
+#define __deref_out_bcount_opt(size)                            __deref_out_bcount(size)                    __post __deref __exceptthat __maybenull
+#define __deref_out_ecount_part_opt(size,length)                __deref_out_ecount_part(size,length)        __post __deref __exceptthat __maybenull
+#define __deref_out_bcount_part_opt(size,length)                __deref_out_bcount_part(size,length)        __post __deref __exceptthat __maybenull
+#define __deref_out_ecount_full_opt(size)                       __deref_out_ecount_full(size)               __post __deref __exceptthat __maybenull
+#define __deref_out_bcount_full_opt(size)                       __deref_out_bcount_full(size)               __post __deref __exceptthat __maybenull
+#define __deref_out_z_opt                                       __post __deref __valid __refparam __execeptthat __maybenull __post __deref __nullterminated
+#define __deref_out_ecount_z_opt(size)                          __deref_out_ecount_opt(size) __post __deref __nullterminated
+#define __deref_out_bcount_z_opt(size)                          __deref_out_bcount_opt(size) __post __deref __nullterminated
+#define __deref_out_nz_opt                                      __deref_out_opt
+#define __deref_out_ecount_nz_opt(size)                         __deref_out_ecount_opt(size)
+#define __deref_out_bcount_nz_opt(size)                         __deref_out_bcount_opt(size)
+#define __deref_inout_opt                                       __deref_inout                               __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull
+#define __deref_inout_ecount_opt(size)                          __deref_inout_ecount(size)                  __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull
+#define __deref_inout_bcount_opt(size)                          __deref_inout_bcount(size)                  __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull
+#define __deref_inout_ecount_part_opt(size,length)              __deref_inout_ecount_part(size,length)      __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull
+#define __deref_inout_bcount_part_opt(size,length)              __deref_inout_bcount_part(size,length)      __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull
+#define __deref_inout_ecount_full_opt(size)                     __deref_inout_ecount_full(size)             __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull
+#define __deref_inout_bcount_full_opt(size)                     __deref_inout_bcount_full(size)             __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull
+#define __deref_inout_z_opt                                     __deref_inout_opt __pre __deref __nullterminated __post __deref __nullterminated
+#define __deref_inout_ecount_z_opt(size)                        __deref_inout_ecount_opt(size) __pre __deref __nullterminated __post __deref __nullterminated
+#define __deref_inout_bcount_z_opt(size)                        __deref_inout_bcount_opt(size) __pre __deref __nullterminated __post __deref __nullterminated
+#define __deref_inout_nz_opt                                    __deref_inout_opt 
+#define __deref_inout_ecount_nz_opt(size)                       __deref_inout_ecount_opt(size)
+#define __deref_inout_bcount_nz_opt(size)                       __deref_inout_bcount_opt(size)
+#define __deref_opt_ecount(size)                                __deref_ecount(size)                        __exceptthat __maybenull
+#define __deref_opt_bcount(size)                                __deref_bcount(size)                        __exceptthat __maybenull
+#define __deref_opt_out                                         __deref_out                                 __exceptthat __maybenull
+#define __deref_opt_out_z                                       __deref_opt_out __post __deref __nullterminated
+#define __deref_opt_out_ecount(size)                            __deref_out_ecount(size)                    __exceptthat __maybenull
+#define __deref_opt_out_bcount(size)                            __deref_out_bcount(size)                    __exceptthat __maybenull
+#define __deref_opt_out_ecount_part(size,length)                __deref_out_ecount_part(size,length)        __exceptthat __maybenull
+#define __deref_opt_out_bcount_part(size,length)                __deref_out_bcount_part(size,length)        __exceptthat __maybenull
+#define __deref_opt_out_ecount_full(size)                       __deref_out_ecount_full(size)               __exceptthat __maybenull
+#define __deref_opt_out_bcount_full(size)                       __deref_out_bcount_full(size)               __exceptthat __maybenull
+#define __deref_opt_inout                                       __deref_inout                               __exceptthat __maybenull
+#define __deref_opt_inout_ecount(size)                          __deref_inout_ecount(size)                  __exceptthat __maybenull
+#define __deref_opt_inout_bcount(size)                          __deref_inout_bcount(size)                  __exceptthat __maybenull
+#define __deref_opt_inout_ecount_part(size,length)              __deref_inout_ecount_part(size,length)      __exceptthat __maybenull
+#define __deref_opt_inout_bcount_part(size,length)              __deref_inout_bcount_part(size,length)      __exceptthat __maybenull
+#define __deref_opt_inout_ecount_full(size)                     __deref_inout_ecount_full(size)             __exceptthat __maybenull
+#define __deref_opt_inout_bcount_full(size)                     __deref_inout_bcount_full(size)             __exceptthat __maybenull
+#define __deref_opt_inout_z                                     __deref_opt_inout __pre __deref __nullterminated __post __deref __nullterminated
+#define __deref_opt_inout_ecount_z(size)                        __deref_opt_inout_ecount(size) __pre __deref __nullterminated __post __deref __nullterminated
+#define __deref_opt_inout_bcount_z(size)                        __deref_opt_inout_bcount(size) __pre __deref __nullterminated __post __deref __nullterminated
+#define __deref_opt_inout_nz                                    __deref_opt_inout
+#define __deref_opt_inout_ecount_nz(size)                       __deref_opt_inout_ecount(size)
+#define __deref_opt_inout_bcount_nz(size)                       __deref_opt_inout_bcount(size)
+#define __deref_opt_ecount_opt(size)                            __deref_ecount_opt(size)                    __exceptthat __maybenull
+#define __deref_opt_bcount_opt(size)                            __deref_bcount_opt(size)                    __exceptthat __maybenull
+#define __deref_opt_out_opt                                     __deref_out_opt                             __exceptthat __maybenull
+#define __deref_opt_out_ecount_opt(size)                        __deref_out_ecount_opt(size)                __exceptthat __maybenull
+#define __deref_opt_out_bcount_opt(size)                        __deref_out_bcount_opt(size)                __exceptthat __maybenull
+#define __deref_opt_out_ecount_part_opt(size,length)            __deref_out_ecount_part_opt(size,length)    __exceptthat __maybenull
+#define __deref_opt_out_bcount_part_opt(size,length)            __deref_out_bcount_part_opt(size,length)    __exceptthat __maybenull
+#define __deref_opt_out_ecount_full_opt(size)                   __deref_out_ecount_full_opt(size)           __exceptthat __maybenull
+#define __deref_opt_out_bcount_full_opt(size)                   __deref_out_bcount_full_opt(size)           __exceptthat __maybenull
+#define __deref_opt_out_z_opt                                   __post __deref __valid __refparam __exceptthat __maybenull __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull __post __deref __nullterminated
+#define __deref_opt_out_ecount_z_opt(size)                      __deref_opt_out_ecount_opt(size) __post __deref __nullterminated
+#define __deref_opt_out_bcount_z_opt(size)                      __deref_opt_out_bcount_opt(size) __post __deref __nullterminated
+#define __deref_opt_out_nz_opt                                  __deref_opt_out_opt
+#define __deref_opt_out_ecount_nz_opt(size)                     __deref_opt_out_ecount_opt(size)    
+#define __deref_opt_out_bcount_nz_opt(size)                     __deref_opt_out_bcount_opt(size)    
+#define __deref_opt_inout_opt                                   __deref_inout_opt                           __exceptthat __maybenull
+#define __deref_opt_inout_ecount_opt(size)                      __deref_inout_ecount_opt(size)              __exceptthat __maybenull
+#define __deref_opt_inout_bcount_opt(size)                      __deref_inout_bcount_opt(size)              __exceptthat __maybenull
+#define __deref_opt_inout_ecount_part_opt(size,length)          __deref_inout_ecount_part_opt(size,length)  __exceptthat __maybenull
+#define __deref_opt_inout_bcount_part_opt(size,length)          __deref_inout_bcount_part_opt(size,length)  __exceptthat __maybenull
+#define __deref_opt_inout_ecount_full_opt(size)                 __deref_inout_ecount_full_opt(size)         __exceptthat __maybenull
+#define __deref_opt_inout_bcount_full_opt(size)                 __deref_inout_bcount_full_opt(size)         __exceptthat __maybenull
+#define __deref_opt_inout_z_opt                                 __deref_opt_inout_opt  __pre __deref __nullterminated __post __deref __nullterminated             
+#define __deref_opt_inout_ecount_z_opt(size)                    __deref_opt_inout_ecount_opt(size)  __pre __deref __nullterminated __post __deref __nullterminated
+#define __deref_opt_inout_bcount_z_opt(size)                    __deref_opt_inout_bcount_opt(size)  __pre __deref __nullterminated __post __deref __nullterminated
+#define __deref_opt_inout_nz_opt                                __deref_opt_inout_opt               
+#define __deref_opt_inout_ecount_nz_opt(size)                   __deref_opt_inout_ecount_opt(size)  
+#define __deref_opt_inout_bcount_nz_opt(size)                   __deref_opt_inout_bcount_opt(size)  
+
+/*
+-------------------------------------------------------------------------------
+Advanced Annotation Definitions
+
+Any of these may be used to directly annotate functions, and may be used in
+combination with each other or with regular buffer macros. For an explanation
+of each annotation, see the advanced annotations section.
+-------------------------------------------------------------------------------
+*/
+
+#define __success(expr)                     __inner_success(expr)
+#define __nullterminated                    __readableTo(sentinel(0))
+#define __nullnullterminated
+#define __reserved                          __pre __null
+#define __checkReturn                       __inner_checkReturn
+#define __typefix(ctype)                    __inner_typefix(ctype)
+#define __override                          __inner_override
+#define __callback                          __inner_callback
+#define __format_string
+#define __blocksOn(resource)                __inner_blocksOn(resource)
+#define __control_entrypoint(category)      __inner_control_entrypoint(category)
+#define __data_entrypoint(category)         __inner_data_entrypoint(category)
+
+#ifndef __fallthrough
+    __inner_fallthrough_dec
+    #define __fallthrough __inner_fallthrough
+#endif
+
+#ifndef __analysis_assume
+#ifdef _PREFAST_
+#define __analysis_assume(expr) __assume(expr)
+#else
+#define __analysis_assume(expr) 
+#endif
+#endif
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif //__specstrings
\ No newline at end of file
diff --git a/Source/LibJXR/common/include/wmspecstring.h b/Source/LibJXR/common/include/wmspecstring.h
new file mode 100644
index 0000000..1b4767e
--- /dev/null
+++ b/Source/LibJXR/common/include/wmspecstring.h
@@ -0,0 +1,342 @@
+//*@@@+++@@@@******************************************************************
+//
+// Copyright � Microsoft Corp.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+// � Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// � Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//*@@@---@@@@******************************************************************
+
+#ifndef _WMSPECSTRING_H_
+#define _WMSPECSTRING_H_
+
+#if (!defined UNDER_CE && !defined NO_WINDOWS && !defined SPECSTRINGS_H)
+#define SPECSTRINGS_H
+/*************************************************************************
+* See specstrings_strict.h for documentation of all user visible macros.
+*************************************************************************/
+#if _MSC_VER
+#pragma once
+#endif
+#include <wmsal.h>  
+
+#ifndef __SAL_H_FULL_VER
+#define __SAL_H_FULL_VER 140050727
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif 
+
+/* version specific fixes to bring sal.h upto date */
+#if __SAL_H_FULL_VER <= 140050727
+
+/* Missing from RTM sal.h */
+#if !defined(__midl) && defined(_PREFAST_) && _MSC_VER >= 1000
+
+#define __inexpressible_readableTo(size)  __declspec("SAL_readableTo(inexpressibleCount('" SPECSTRINGIZE(size) "'))")
+#define __inexpressible_writableTo(size)  __declspec("SAL_writableTo(inexpressibleCount('" SPECSTRINGIZE(size) "'))")
+#define __inner_bound                     __declspec("SAL_bound")
+#define __inner_range(lb,ub)              __declspec("SAL_range(" SPECSTRINGIZE(lb) "," SPECSTRINGIZE(ub) ")")
+#define __inner_assume_bound_dec          __inline __nothrow void __AssumeBoundInt(__post __inner_bound int i) {i;}
+#define __inner_assume_bound(i)           __AssumeBoundInt(i);
+#define __inner_allocator                 __declspec("SAL_allocator")
+#else 
+#define __inexpressible_readableTo(size)
+#define __inexpressible_writableTo(size)
+#define __inner_bound
+#define __inner_range(lb,ub)
+#define __inner_assume_bound_dec
+#define __inner_assume_bound(i)
+#define __inner_allocator
+#endif
+
+#define __xcount(size)                                          __notnull __inexpressible_writableTo(size)
+#define __in_xcount(size)                                       __in __pre __inexpressible_readableTo(size)
+#define __out_xcount(size)                                      __xcount(size) __post __valid __refparam
+#define __out_xcount_part(size,length)                          __out_xcount(size) __post __inexpressible_readableTo(length)
+#define __out_xcount_full(size)                                 __out_xcount_part(size,size)
+#define __inout_xcount(size)                                    __out_xcount(size) __pre __valid
+#define __inout_xcount_part(size,length)                        __out_xcount_part(size,length) __pre __valid __pre __inexpressible_readableTo(length)
+#define __inout_xcount_full(size)                               __inout_xcount_part(size,size)
+#define __xcount_opt(size)                                      __xcount(size)                              __exceptthat __maybenull
+#define __in_xcount_opt(size)                                   __in_xcount(size)                           __exceptthat __maybenull
+#define __out_xcount_opt(size)                                  __out_xcount(size)                          __exceptthat __maybenull
+#define __out_xcount_part_opt(size,length)                      __out_xcount_part(size,length)              __exceptthat __maybenull
+#define __out_xcount_full_opt(size)                             __out_xcount_full(size)                     __exceptthat __maybenull
+#define __inout_xcount_opt(size)                                __inout_xcount(size)                        __exceptthat __maybenull
+#define __inout_xcount_part_opt(size,length)                    __inout_xcount_part(size,length)            __exceptthat __maybenull
+#define __inout_xcount_full_opt(size)                           __inout_xcount_full(size)                   __exceptthat __maybenull
+#define __deref_xcount(size)                                    __ecount(1) __post __elem_readableTo(1) __post __deref __notnull __post __deref __inexpressible_writableTo(size)
+#define __deref_in                                              __in __pre __deref __deref __readonly
+#define __deref_in_ecount(size)                                 __deref_in __pre __deref __elem_readableTo(size)
+#define __deref_in_bcount(size)                                 __deref_in __pre __deref __byte_readableTo(size)
+#define __deref_in_xcount(size)                                 __deref_in __pre __deref __inexpressible_readableTo(size)
+#define __deref_out_xcount(size)                                __deref_xcount(size) __post __deref __valid __refparam
+#define __deref_out_xcount_part(size,length)                    __deref_out_xcount(size) __post __deref __inexpressible_readableTo(length)
+#define __deref_out_xcount_full(size)                           __deref_out_xcount_part(size,size)
+#define __deref_out_xcount(size)                                __deref_xcount(size) __post __deref __valid __refparam
+#define __inout_xcount_opt(size)                                __inout_xcount(size)                        __exceptthat __maybenull
+#define __inout_xcount_part_opt(size,length)                    __inout_xcount_part(size,length)            __exceptthat __maybenull
+#define __inout_xcount_full_opt(size)                           __inout_xcount_full(size)                   __exceptthat __maybenull
+#define __deref_xcount(size)                                    __ecount(1) __post __elem_readableTo(1) __post __deref __notnull __post __deref __inexpressible_writableTo(size)
+#define __deref_in                                              __in __pre __deref __deref __readonly
+#define __deref_in_ecount(size)                                 __deref_in __pre __deref __elem_readableTo(size)
+#define __deref_in_bcount(size)                                 __deref_in __pre __deref __byte_readableTo(size)
+#define __deref_in_xcount(size)                                 __deref_in __pre __deref __inexpressible_readableTo(size)
+#define __deref_out_xcount(size)                                __deref_xcount(size) __post __deref __valid __refparam
+#define __deref_out_xcount_part(size,length)                    __deref_out_xcount(size) __post __deref __inexpressible_readableTo(length)
+#define __deref_out_xcount_full(size)                           __deref_out_xcount_part(size,size)
+#define __deref_out_xcount(size)                                __deref_xcount(size) __post __deref __valid __refparam
+#define __deref_inout_xcount(size)                              __deref_inout __pre __deref __inexpressible_writableTo(size) __post __deref __inexpressible_writableTo(size)
+#define __deref_inout_xcount_part(size,length)                  __deref_inout_xcount(size) __pre __deref __inexpressible_readableTo(length) __post __deref __inexpressible_readableTo(length)
+#define __deref_inout_xcount_full(size)                         __deref_inout_xcount_part(size,size)
+#define __deref_xcount_opt(size)                                __deref_xcount(size)                        __post __deref __exceptthat __maybenull
+#define __deref_in_opt                                          __deref_in                                  __pre __deref __exceptthat __maybenull
+#define __deref_in_ecount_opt(size)                             __deref_in_ecount(size)                     __pre __deref __exceptthat __maybenull
+#define __deref_in_bcount_opt(size)                             __deref_in_bcount(size)                     __pre __deref __exceptthat __maybenull
+#define __deref_in_xcount_opt(size)                             __deref_in_xcount(size)                     __pre __deref __exceptthat __maybenull
+#define __deref_out_xcount_opt(size)                            __deref_out_xcount(size)                    __post __deref __exceptthat __maybenull
+#define __deref_out_xcount_part_opt(size,length)                __deref_out_xcount_part(size,length)        __post __deref __exceptthat __maybenull
+#define __deref_out_xcount_full_opt(size)                       __deref_out_xcount_full(size)               __post __deref __exceptthat __maybenull
+#define __deref_inout_xcount_opt(size)                          __deref_inout_xcount(size)                  __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull
+#define __deref_inout_xcount_part_opt(size,length)              __deref_inout_xcount_part(size,length)      __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull
+#define __deref_inout_xcount_full_opt(size)                     __deref_inout_xcount_full(size)             __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull
+#define __deref_opt_xcount(size)                                __deref_xcount(size)                        __exceptthat __maybenull
+#define __deref_opt_in                                          __deref_in                                  __exceptthat __maybenull
+#define __deref_opt_in_ecount(size)                             __deref_in_ecount(size)                     __exceptthat __maybenull
+#define __deref_opt_in_bcount(size)                             __deref_in_bcount(size)                     __exceptthat __maybenull
+#define __deref_opt_in_xcount(size)                             __deref_in_xcount(size)                     __exceptthat __maybenull
+#define __deref_opt_out_xcount(size)                            __deref_out_xcount(size)                    __exceptthat __maybenull
+#define __deref_opt_out_xcount_part(size,length)                __deref_out_xcount_part(size,length)        __exceptthat __maybenull
+#define __deref_opt_out_xcount_full(size)                       __deref_out_xcount_full(size)               __exceptthat __maybenull
+#define __deref_opt_inout_xcount(size)                          __deref_inout_xcount(size)                  __exceptthat __maybenull
+#define __deref_opt_inout_xcount_part(size,length)              __deref_inout_xcount_part(size,length)      __exceptthat __maybenull
+#define __deref_opt_inout_xcount_full(size)                     __deref_inout_xcount_full(size)             __exceptthat __maybenull
+#define __deref_opt_xcount_opt(size)                            __deref_xcount_opt(size)                    __exceptthat __maybenull
+#define __deref_opt_in_opt                                      __deref_in_opt                              __exceptthat __maybenull
+#define __deref_opt_in_ecount_opt(size)                         __deref_in_ecount_opt(size)                 __exceptthat __maybenull
+#define __deref_opt_in_bcount_opt(size)                         __deref_in_bcount_opt(size)                 __exceptthat __maybenull
+#define __deref_opt_in_xcount_opt(size)                         __deref_in_xcount_opt(size)                 __exceptthat __maybenull
+#define __deref_opt_out_xcount_opt(size)                        __deref_out_xcount_opt(size)                __exceptthat __maybenull
+#define __deref_opt_out_xcount_part_opt(size,length)            __deref_out_xcount_part_opt(size,length)    __exceptthat __maybenull
+#define __deref_opt_out_xcount_full_opt(size)                   __deref_out_xcount_full_opt(size)           __exceptthat __maybenull
+#define __deref_opt_inout_xcount_opt(size)                      __deref_inout_xcount_opt(size)              __exceptthat __maybenull
+#define __deref_opt_inout_xcount_part_opt(size,length)          __deref_inout_xcount_part_opt(size,length)  __exceptthat __maybenull
+#define __deref_opt_inout_xcount_full_opt(size)                 __deref_inout_xcount_full_opt(size)         __exceptthat __maybenull
+/* Must protect redfinitions of macros to workaround rc.exe issues. */
+#ifndef RC_INVOKED
+#undef __nullnullterminated
+#define __nullnullterminated __xcount("string terminated by two nulls")
+#undef __checkReturn
+#define __checkReturn __post __inner_checkReturn
+#endif
+#endif  //__SAL_H_FULL_VER <= 140050727
+
+/************************************************************************
+ New extensions to sal.h follow here.
+*************************************************************************/
+
+#if (_MSC_VER >= 1000) && !defined(__midl) && defined(_PREFAST_)
+#define __file_parser(typ)                  __declspec("SAL_file_parser(function, " #typ ")")    
+#define __file_parser_class(typ)            __declspec("SAL_file_parser(class, " #typ ")")
+#define __file_parser_library(typ)          extern int __declspec("SAL_file_parser(library, " #typ ")") __iSALFileParserLibrary##typ;
+#define __source_code_content(typ)          extern int __declspec("SAL_source_code_content(" #typ ")") __iSAL_Source_Code_Content##typ;
+#define __class_code_content(typ)           __declspec("SAL_class_code_content(" #typ ")")
+#define __analysis_assert(e)                __assume(e)
+#define __analysis_hint(hint)               __declspec("SAL_analysisHint(" #hint ")")   
+/* Internal defintions */
+#define __inner_data_source(src_raw)        __declspec("SAL_untrusted_data_source(" src_raw ")")
+#define __inner_this_data_source(src_raw)   __declspec("SAL_untrusted_data_source_this(" src_raw ")")
+#define __inner_out_validated(typ_raw)      __declspec("SAL_post") __declspec("SAL_validated(" typ_raw ")") 
+#define __inner_this_out_validated(typ_raw) __declspec("SAL_validated_this(" typ_raw ")") 
+#define __inner_assume_validated_dec        __inline __nothrow void __AssumeValidated(__inner_out_validated("BY_DESIGN") const void *p) {p;}
+#define __inner_assume_validated(p)         __AssumeValidated(p)
+#define __inner_transfer(formal)            __declspec("SAL_transfer_adt_property_from(" SPECSTRINGIZE(formal) ")")
+#define __inner_encoded                     __declspec("SAL_encoded")
+
+#define __$adt_prop(adt,prop)               __declspec("SAL_adt("#adt","#prop")")
+#define __$adt_add_prop(adt,prop)           __declspec("SAL_add_adt_property("#adt","#prop")")
+#define __$adt_remove_prop(adt,prop)        __declspec("SAL_remove_adt_property("#adt","#prop")")
+#define __$adt_transfer_prop(arg)           __declspec("SAL_transfer_adt_property_from("#arg")")
+#define __$adt_type_props(typ)              __declspec("SAL_post_type("#typ")")
+#define __$volatile                         __declspec("SAL_volatile")
+#define __$nonvolatile                      __declspec("SAL_nonvolatile")
+#define __$possibly_notnulltermiated        __declspec("SAL_RequiresZeroTermination(sometimes)")
+#else
+#define __file_parser(typ)
+#define __file_parser_class(typ)
+#define __file_parser_library(typ)
+#define __source_code_content(typ)
+#define __class_code_content(typ)
+#define __analysis_assert(e)
+#define __analysis_hint(hint)
+/* Internal defintions */
+#define __inner_data_source(src_raw)
+#define __inner_this_data_source(src_raw)
+#define __inner_out_validated(typ_raw)
+#define __inner_this_out_validated(typ_raw)
+#define __inner_assume_validated_dec
+#define __inner_assume_validated(p)
+#define __inner_transfer(formal)
+#define __inner_encoded
+#define __$adt_prop(adt,prop)   
+#define __$adt_add_prop(adt,prop)   
+#define __$adt_remove_prop(adt,prop)   
+#define __$adt_transfer_prop(arg)   
+#define __$adt_type_props(typ)   
+#define __$volatile 
+#define __$nonvolatile 
+#define __$possibly_notnulltermiated 
+#endif // #if (_MSC_VER >= 1000) && !defined(__midl) && defined(_PREFAST_)
+
+#define __field_ecount(size)                __notnull __elem_writableTo(size)
+#define __field_bcount(size)                __notnull __byte_writableTo(size)
+#define __field_xcount(size)                __notnull __inexpressible_writableTo(size)
+
+#define __field_ecount_opt(size)            __maybenull __elem_writableTo(size)
+#define __field_bcount_opt(size)            __maybenull __byte_writableTo(size)
+#define __field_xcount_opt(size)            __maybenull __inexpressible_writableTo(size)
+
+#define __field_ecount_part(size,init)      __notnull __elem_writableTo(size) __elem_readableTo(init)
+#define __field_bcount_part(size,init)      __notnull __byte_writableTo(size) __byte_readableTo(init)
+#define __field_xcount_part(size,init)      __notnull __inexpressible_writableTo(size) __inexpressible_readableTo(init)
+
+#define __field_ecount_part_opt(size,init)  __maybenull __elem_writableTo(size) __elem_readableTo(init)
+#define __field_bcount_part_opt(size,init)  __maybenull __byte_writableTo(size) __byte_readableTo(init)
+#define __field_xcount_part_opt(size,init)  __maybenull __inexpressible_writableTo(size) __inexpressible_readableTo(init)
+
+#define __field_ecount_full(size)           __field_ecount_part(size,size)  
+#define __field_bcount_full(size)           __field_bcount_part(size,size)  
+#define __field_xcount_full(size)           __field_xcount_part(size,size)      
+
+#define __field_ecount_full_opt(size)       __field_ecount_part_opt(size,size)  
+#define __field_bcount_full_opt(size)       __field_bcount_part_opt(size,size)  
+#define __field_xcount_full_opt(size)       __field_xcount_part_opt(size,size)      
+
+#define __struct_bcount(size)               __field_bcount(size)
+#define __struct_xcount(size)               __field_xcount(size)
+
+#if !defined(__out_awcount)
+#define __out_awcount(expr,size)            __pre __notnull \
+					    __byte_writableTo((expr) ? (size) : (size) * 2) \
+                                            __post __valid __refparam
+#endif
+#if !defined(__in_awcount)
+#define __in_awcount(expr,size)             __pre __valid \
+                                            __pre __deref __readonly \
+				            __byte_readableTo((expr) ? (size) : (size) * 2)
+#endif
+
+/* integer related macros */
+#define __allocator                         __inner_allocator
+#define __bound                             __inner_bound
+#define __range(lb,ub)                      __inner_range(lb,ub)
+#define __in_bound                          __pre __inner_bound
+#define __out_bound                         __post __inner_bound
+#define __deref_out_bound                   __post __deref __inner_bound
+#define __in_range(lb,ub)                   __pre __inner_range(lb,ub)
+#define __out_range(lb,ub)                  __post __inner_range(lb,ub)
+#define __deref_in_range(lb,ub)             __pre __deref __inner_range(lb,ub)
+#define __deref_out_range(lb,ub)            __post __deref __inner_range(lb,ub)
+#define __field_range(lb,ub)                __range(lb,ub)
+#define __field_data_source(src_sym)        __inner_data_source(#src_sym)
+
+/* Pentraion review macros */
+#define __in_data_source(src_sym)           __pre __inner_data_source(#src_sym)
+#define __out_data_source(src_sym)          __post __inner_data_source(#src_sym)
+#define __out_validated(typ_sym)            __inner_out_validated(#typ_sym)
+#define __this_out_data_source(src_sym)     __inner_this_data_source(#src_sym)
+#define __this_out_validated(typ_sym)       __inner_this_out_validated(#typ_sym)
+#define __transfer(formal)                  __post __inner_transfer(formal)
+#define __rpc_entry                         __inner_control_entrypoint(RPC)
+#define __kernel_entry                      __inner_control_entrypoint(UserToKernel)   
+#define __gdi_entry                         __inner_control_entrypoint(GDI)
+#define __encoded_pointer                   __inner_encoded
+#define __encoded_array                     __inner_encoded
+#define __field_encoded_pointer             __inner_encoded
+#define __field_encoded_array               __inner_encoded
+#define __type_has_adt_prop(adt,prop)       __$adt_prop(adt,prop)
+#define __out_has_adt_prop(adt,prop)        __post __$adt_add_prop(adt,prop)
+#define __out_not_has_adt_prop(adt,prop)    __post __$adt_remove_prop(adt,prop)
+#define __out_transfer_adt_prop(arg)        __post __$adt_transfer_prop(arg)
+#define __out_has_type_adt_props(typ)       __post __$adt_type_props(typ)
+
+/* useful PFD related macros */
+#define __possibly_notnulltermiated         __post __$possibly_notnulltermiated
+
+#if defined(_WINDOWS_)
+/* Windows Internal */
+#define __volatile                          __$volatile
+#define __nonvolatile                       __$nonvolatile
+#define __deref_volatile                    __deref __volatile
+#define __deref_nonvolatile                 __deref __nonvolatile
+#endif
+
+/* declare stub functions for macros */
+__inner_assume_validated_dec 
+__inner_assume_bound_dec 
+
+#define __assume_validated(p) __inner_assume_validated(p)
+#define __assume_bound(i) __inner_assume_bound(i)
+#ifdef  __cplusplus
+}
+#endif
+#include <wmspecstrings_adt.h>
+#ifdef _PREFIX_
+/**************************************************************************
+* Defintion of __pfx_assume and __pfx_assert. Thse should be the only
+* defintions of these functions.  
+***************************************************************************/
+#if __cplusplus
+extern "C" void __pfx_assert(bool, const char *);
+extern "C" void __pfx_assume(bool, const char *);
+#else
+void __pfx_assert(int, const char *);
+void __pfx_assume(int, const char *);
+#endif
+/**************************************************************************
+* Redefintion of __analysis_assume and __analysis_assert for PREFIX build
+**************************************************************************/
+#undef  __analysis_assume
+#undef  __analysis_assert
+#define __analysis_assume(e) (__pfx_assume(e,"pfx_assume"),__assume(e));
+#define __analysis_assert(e) (__pfx_assert(e,"pfx_assert"),__assume(e));
+#endif /* ifdef _PREFIX_ */
+
+/**************************************************************************
+* This include should always be the last thing in this file. 
+* Must avoid redfinitions of macros to workaround rc.exe issues. 
+***************************************************************************/
+#if !(defined(RC_INVOKED) || defined(SORTPP_PASS))
+#include <wmspecstrings_strict.h>
+#endif /* if !(defined(RC_INVOKED) || defined(SORTPP_PASS)) */
+#endif /* #ifndef SPECSTRINGS_H */
+
+// Some CE versions don't have specstrings.h, some have very old version without
+// __specstrings defined. So we handle CE separately in wmasalce.h
+#if defined(UNDER_CE) || defined(NO_WINDOWS)
+  #include "wmspecstringce.h"
+#endif
+
+#endif //_WMSPECSTRING_H_
+
diff --git a/Source/LibJXR/common/include/wmspecstrings_adt.h b/Source/LibJXR/common/include/wmspecstrings_adt.h
new file mode 100644
index 0000000..ca7f25f
--- /dev/null
+++ b/Source/LibJXR/common/include/wmspecstrings_adt.h
@@ -0,0 +1,71 @@
+//*@@@+++@@@@******************************************************************
+//
+// Copyright � Microsoft Corp.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+// � Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// � Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//*@@@---@@@@******************************************************************
+
+#pragma once
+/*************************************************************************
+* DEFINITIONS OF NEW TYPES 
+*************************************************************************/
+#if !defined(__midl)
+#define __$compname_props \
+        __type_has_adt_prop(compname,nullterminated) \
+        __type_has_adt_prop(compname,valid_schars) \
+        __type_has_adt_prop(compname,correct_len) \
+        __nullterminated
+#if defined(UNICODE) || defined(_UNICODE)
+#define  __$TCHAR unsigned short
+#else
+#define  __$TCHAR char
+#endif
+typedef __$compname_props char* ValidCompNameA;
+typedef __$compname_props unsigned short* ValidCompNameW;
+typedef __$compname_props const unsigned short* ConstValidCompNameW;
+typedef __$compname_props  __$TCHAR* SAL_ValidCompNameT;
+typedef __$compname_props const  __$TCHAR* SAL_ConstValidCompNameT;
+#undef __$compname_props
+#undef __$TCHAR
+#endif
+
+/*************************************************************************
+* DEFINITIONS OF INLINE FUNCTIONS FOR CASTING TO THE NEW TYPES : USER
+*************************************************************************/
+#if (_MSC_VER >= 1000) && !defined(__midl) && defined(_PREFAST_)
+#ifdef  __cplusplus
+extern "C" {
+#endif
+void __inline __nothrow __SAL_ValidCompNameA(__out_has_type_adt_props(ValidCompNameA) const void *expr) { expr;}
+void __inline __nothrow __SAL_ValidCompNameW(__out_has_type_adt_props(ValidCompNameW) const void *expr) { expr;}
+#ifdef  __cplusplus
+}
+#endif
+#define __assume_ValidCompNameA(expr) __SAL_ValidCompNameA(expr)
+#define __assume_ValidCompNameW(expr) __SAL_ValidCompNameW(expr)
+#else
+#define __assume_ValidCompNameA(expr) 
+#define __assume_ValidCompNameW(expr)
+#endif
+
diff --git a/Source/LibJXR/common/include/wmspecstrings_strict.h b/Source/LibJXR/common/include/wmspecstrings_strict.h
new file mode 100644
index 0000000..46b44c2
--- /dev/null
+++ b/Source/LibJXR/common/include/wmspecstrings_strict.h
@@ -0,0 +1,1096 @@
+//*@@@+++@@@@******************************************************************
+//
+// Copyright � Microsoft Corp.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+// � Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// � Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//*@@@---@@@@******************************************************************
+
+
+/************************************************************************* 
+*  This file documents all the macros approved for use in windows source
+*  code. It includes some experimental macros which should only be used by
+*  experts.
+*
+*  DO NOT include this file directly.  This file is include after
+*  specstrings.h. So we can undefine every possible old definition including
+*  private internal macros people should not be using, as well as macros from
+*  sal.h.  Macros are redefined here in a way to cause syntax errors when used
+*  incorrectly during a normal build when specstrings.h is included and
+*  __SPECSTRINGS_STRICT_LEVEL is defined.
+*
+*  There are several levels of strictness, each level includes the behavior of
+*  all previous levels.
+*
+*  0 - Disable strict checking 
+*  1 - Break on unapproved macros and misuse of statement 
+*      macros such as __fallthrough (default)
+*  2 - Deprecated some old macros that should not be used
+*  3 - Use VS 2005 Source Annotation to make sure every macro 
+*      is used in the right context. For example placing __in on a return 
+*      parameter will result in an error.
+************************************************************************/
+#ifndef __SPECSTRINGS_STRICT_LEVEL
+#define __SPECSTRINGS_STRICT_LEVEL 1
+#endif
+/************************************************************************
+*  Introduction
+*
+*  specstrings.h provides a set of annotations to describe how a function uses
+*  its parameters - the assumptions it makes about them, and the guarantees it
+*  makes upon finishing.
+* 
+*  Annotations must be placed before a function parameter's type or its return
+*  type. There are two basic classes of common annotations buffer annotations
+*  and advanced annotations.  Buffer annotations describe how functions use
+*  their pointer parameters, and advanced annotations either describe
+*  complex/unusual buffer behavior, or provide additional information about a
+*  parameter that is not otherwise expressible.
+* 
+*  Buffer Annotations
+* 
+*  The most important annotations in SpecStrings.h provide a consistent way to
+*  annotate buffer parameters or return values for a function. Each of these
+*  annotations describes a single buffer (which could be a string, a
+*  fixed-length or variable-length array, or just a pointer) that the function
+*  interacts with: where it is, how large it is, how much is initialized, and
+*  what the function does with it.
+* 
+*  The appropriate macro for a given buffer can be constructed using the table
+*  below.  Just pick the appropriate values from each category, and combine
+*  them together with a leading underscore. Some combinations of values do not
+*  make sense as buffer annotations. Only meaningful annotations can be added
+*  to your code; for a list of these, see the buffer annotation definitions
+*  section.
+* 
+*  Only a single buffer annotation should be used for each parameter.
+* 
+*  |------------|------------|---------|--------|----------|---------------|
+*  |   Level    |   Usage    |  Size   | Output | Optional |  Parameters   |
+*  |------------|------------|---------|--------|----------|---------------|
+*  | <>         | <>         | <>      | <>     | <>       | <>            |
+*  | _deref     | _in        | _ecount | _full  | _opt     | (size)        |
+*  | _deref_opt | _out       | _bcount | _part  |          | (size,length) |
+*  |            | _inout     |         |        |          |               |
+*  |            |            |         |        |          |               |
+*  |------------|------------|---------|--------|----------|---------------|
+*
+*  Note: "<>" represents the empty string.
+* 
+*  Level: Describes the buffer pointer's level of indirection from the
+*  parameter or return value 'p'.
+* 
+*  <>         : p is the buffer pointer.
+*  _deref     : *p is the buffer pointer. p must not be NULL.
+*  _deref_opt : *p may be the buffer pointer. p may be NULL, in which case the 
+*               rest of the annotation is ignored.
+* 
+*  Usage: Describes how the function uses the buffer.
+* 
+*  <> : The buffer is not accessed. If used on the return value or with
+*  _deref, the function will provide the buffer, and it will be uninitialized
+*  at exit.  Otherwise, the caller must provide the buffer. This should only
+*  be used for alloc and free functions.
+*
+*  _in : The function will only read from the buffer. The caller must provide
+*  the buffer and initialize it.
+*
+*  _out : The function will only write to the buffer. If used on the return
+*  value or with _deref, the function will provide the buffer and initialize
+*  it.  Otherwise, the caller must provide the buffer, and the function will
+*  initialize it.
+*
+*  _inout : The function may freely read from and write to the buffer. The
+*  caller must provide the buffer and initialize it. If used with _deref, the
+*  buffer may be reallocated by the function.
+*
+*  Size: Describes the total size of the buffer. This may be less than the
+*  space actually allocated for the buffer, in which case it describes the
+*  accessible amount.
+* 
+*  <> : No buffer size is given. If the type specifies the buffer size (such
+*  as with LPSTR and LPWSTR), that amount is used. Otherwise, the buffer is
+*  one element long. Must be used with _in, _out, or _inout.
+*
+*  _ecount : The buffer size is an explicit element count.
+*
+*  _bcount : The buffer size is an explicit byte count.
+* 
+*  Output: Describes how much of the buffer will be initialized by the
+*  function. For _inout buffers, this also describes how much is initialized
+*  at entry. Omit this category for _in buffers; they must be fully
+*  initialized by the caller.
+* 
+*  <> : The type specifies how much is initialized. For instance, a function
+*  initializing an LPWSTR must NULL-terminate the string.
+*
+*  _full : The function initializes the entire buffer.
+*
+*  _part : The function initializes part of the buffer, and explicitly
+*  indicates how much.
+* 
+*  Optional: Describes if the buffer itself is optional.
+* 
+*  <>   : The pointer to the buffer must not be NULL.
+*
+*  _opt : The pointer to the buffer might be NULL. It will be checked before
+*  being dereferenced.
+* 
+*  Parameters: Gives explicit counts for the size and length of the buffer.
+* 
+*  <> : There is no explicit count. Use when neither _ecount nor _bcount is
+*  used.
+*
+*  (size) : Only the buffer's total size is given. Use with _ecount or _bcount
+*  but not _part.
+*
+*  (size,length) : The buffer's total size and initialized length are
+*  given. Use with _ecount_part and _bcount_part.
+* 
+*  ----------------------------------------------------------------------------
+*  Buffer Annotation Examples
+* 
+*  LWSTDAPI_(BOOL) StrToIntExA(
+*      LPCSTR pszString,  //  No annotation required, const implies __in.
+*      DWORD dwFlags,
+*      __out int *piRet   // A pointer whose dereference will be filled in.
+*  );
+* 
+*  void MyPaintingFunction(
+*      __in HWND hwndControl,     //  An initialized read-only parameter.
+*      __in_opt HDC hdcOptional,  //  An initialized read-only parameter that 
+*                                 //  might be NULL.
+*      __inout IPropertyStore *ppsStore // An initialized parameter that 
+*                                       // may be freely used and modified.
+*  );
+* 
+*  LWSTDAPI_(BOOL) PathCompactPathExA(
+*      __out_ecount(cchMax) LPSTR pszOut, //  A string buffer with cch elements
+*                                         //  that will be '\0' terminated 
+*                                         //  on exit.
+*      LPCSTR pszSrc,                     //  No annotation required, 
+*                                         //  const implies __in.
+*      UINT cchMax,                              
+*      DWORD dwFlags
+*  );
+* 
+*  HRESULT SHLocalAllocBytes(
+*      size_t cb,
+*      __deref_bcount(cb) T **ppv //  A pointer whose dereference will be set
+*                                 //  to an uninitialized buffer with cb bytes.
+*  );
+* 
+*  __inout_bcount_full(cb) : A buffer with cb elements that is fully
+*  initialized at entry and exit, and may be written to by this function.
+* 
+*  __out_ecount_part(count, *countOut) : A buffer with count elements that
+*  will be partially initialized by this function. The function indicates how
+*  much it initialized by setting *countOut.
+* 
+************************************************************************/
+#if (_MSC_VER >= 1400) && !defined(__midl) && !defined(_PREFAST_) && (__SPECSTRINGS_STRICT_LEVEL > 0)
+#pragma once
+#include <wmspecstrings_undef.h>
+#define __ecount(size)                                __allowed(on_return)
+#define __bcount(size)                                __allowed(on_return)
+#define __xcount(size)                                __allowed(on_return)
+#define __in                                          __allowed(on_parameter)
+#define __in_ecount(size)                             __allowed(on_parameter)
+#define __in_bcount(size)                             __allowed(on_parameter)
+#define __in_xcount(size)                             __allowed(on_parameter)
+#define __in_z                                        __allowed(on_parameter)
+#define __in_ecount_z(size)                           __allowed(on_parameter)
+#define __in_bcount_z(size)                           __allowed(on_parameter)
+#define __out                                         __allowed(on_parameter)
+#define __out_ecount(size)                            __allowed(on_parameter)
+#define __out_bcount(size)                            __allowed(on_parameter)
+#define __out_xcount(size)                            __allowed(on_parameter)
+#define __out_ecount_part(size,len)                   __allowed(on_parameter)
+#define __out_bcount_part(size,len)                   __allowed(on_parameter)
+#define __out_xcount_part(size,len)                   __allowed(on_parameter)
+#define __out_ecount_full(size)                       __allowed(on_parameter)
+#define __out_bcount_full(size)                       __allowed(on_parameter)
+#define __out_xcount_full(size)                       __allowed(on_parameter)
+#define __out_z				              __allowed(on_parameter)
+#define __out_ecount_z(size)                          __allowed(on_parameter)
+#define __out_bcount_z(size)                          __allowed(on_parameter)
+#define __inout                                       __allowed(on_parameter)
+#define __inout_ecount(size)                          __allowed(on_parameter)
+#define __inout_bcount(size)                          __allowed(on_parameter)
+#define __inout_xcount(size)                          __allowed(on_parameter)
+#define __inout_ecount_part(size,len)                 __allowed(on_parameter)
+#define __inout_bcount_part(size,len)                 __allowed(on_parameter)
+#define __inout_xcount_part(size,len)                 __allowed(on_parameter)
+#define __inout_ecount_full(size)                     __allowed(on_parameter)
+#define __inout_bcount_full(size)                     __allowed(on_parameter)
+#define __inout_xcount_full(size)                     __allowed(on_parameter)
+#define __inout_z                                     __allowed(on_parameter)
+#define __inout_ecount_z(size)                        __allowed(on_parameter)
+#define __inout_bcount_z(size)                        __allowed(on_parameter)
+#define __ecount_opt(size)                            __allowed(on_parameter)
+#define __bcount_opt(size)                            __allowed(on_parameter)
+#define __xcount_opt(size)                            __allowed(on_parameter)
+#define __in_opt                                      __allowed(on_parameter)
+#define __in_ecount_opt(size)                         __allowed(on_parameter)
+#define __in_bcount_opt(size)                         __allowed(on_parameter)
+#define __in_z_opt                                    __allowed(on_parameter)
+#define __in_ecount_z_opt(size)                       __allowed(on_parameter)
+#define __in_bcount_z_opt(size)                       __allowed(on_parameter)
+#define __in_xcount_opt(size)                         __allowed(on_parameter)
+#define __out_opt                                     __allowed(on_parameter)
+#define __out_ecount_opt(size)                        __allowed(on_parameter)
+#define __out_bcount_opt(size)                        __allowed(on_parameter)
+#define __out_xcount_opt(size)                        __allowed(on_parameter)
+#define __out_ecount_part_opt(size,len)               __allowed(on_parameter)
+#define __out_bcount_part_opt(size,len)               __allowed(on_parameter)
+#define __out_xcount_part_opt(size,len)               __allowed(on_parameter)
+#define __out_ecount_full_opt(size)                   __allowed(on_parameter)
+#define __out_bcount_full_opt(size)                   __allowed(on_parameter)
+#define __out_xcount_full_opt(size)                   __allowed(on_parameter)
+#define __out_ecount_z_opt(size)                      __allowed(on_parameter)
+#define __out_bcount_z_opt(size)                      __allowed(on_parameter)
+#define __inout_opt                                   __allowed(on_parameter)
+#define __inout_ecount_opt(size)                      __allowed(on_parameter)
+#define __inout_bcount_opt(size)                      __allowed(on_parameter)
+#define __inout_xcount_opt(size)                      __allowed(on_parameter)
+#define __inout_ecount_part_opt(size,len)             __allowed(on_parameter)
+#define __inout_bcount_part_opt(size,len)             __allowed(on_parameter)
+#define __inout_xcount_part_opt(size,len)             __allowed(on_parameter)
+#define __inout_ecount_full_opt(size)                 __allowed(on_parameter)
+#define __inout_bcount_full_opt(size)                 __allowed(on_parameter)
+#define __inout_xcount_full_opt(size)                 __allowed(on_parameter)
+#define __inout_z_opt                                 __allowed(on_parameter)
+#define __inout_ecount_z_opt(size)                    __allowed(on_parameter)
+#define __inout_ecount_z_opt(size)                    __allowed(on_parameter)
+#define __inout_bcount_z_opt(size)                    __allowed(on_parameter)
+#define __deref_ecount(size)                          __allowed(on_parameter)
+#define __deref_bcount(size)                          __allowed(on_parameter)
+#define __deref_xcount(size)                          __allowed(on_parameter)
+#define __deref_in                                    __allowed(on_parameter)
+#define __deref_in_ecount(size)                       __allowed(on_parameter)
+#define __deref_in_bcount(size)                       __allowed(on_parameter)
+#define __deref_in_xcount(size)                       __allowed(on_parameter)
+#define __deref_out                                   __allowed(on_parameter)
+#define __deref_out_ecount(size)                      __allowed(on_parameter)
+#define __deref_out_bcount(size)                      __allowed(on_parameter)
+#define __deref_out_xcount(size)                      __allowed(on_parameter)
+#define __deref_out_ecount_part(size,len)             __allowed(on_parameter)
+#define __deref_out_bcount_part(size,len)             __allowed(on_parameter)
+#define __deref_out_xcount_part(size,len)             __allowed(on_parameter)
+#define __deref_out_ecount_full(size)                 __allowed(on_parameter)
+#define __deref_out_bcount_full(size)                 __allowed(on_parameter)
+#define __deref_out_xcount_full(size)                 __allowed(on_parameter)
+#define __deref_out_z                                 __allowed(on_parameter)
+#define __deref_out_ecount_z(size)                    __allowed(on_parameter)
+#define __deref_out_bcount_z(size)                    __allowed(on_parameter)
+#define __deref_out_xcount(size)                      __allowed(on_parameter)
+#define __deref_inout                                 __allowed(on_parameter)
+#define __deref_inout_ecount(size)                    __allowed(on_parameter)
+#define __deref_inout_bcount(size)                    __allowed(on_parameter)
+#define __deref_inout_xcount(size)                    __allowed(on_parameter)
+#define __deref_inout_ecount_part(size,len)           __allowed(on_parameter)
+#define __deref_inout_bcount_part(size,len)           __allowed(on_parameter)
+#define __deref_inout_xcount_part(size,len)           __allowed(on_parameter)
+#define __deref_inout_ecount_full(size)               __allowed(on_parameter)
+#define __deref_inout_bcount_full(size)               __allowed(on_parameter)
+#define __deref_inout_xcount_full(size)               __allowed(on_parameter)
+#define __deref_inout_z                               __allowed(on_parameter)
+#define __deref_inout_ecount_z(size)                  __allowed(on_parameter)
+#define __deref_inout_bcount_z(size)                  __allowed(on_parameter)
+#define __deref_ecount_opt(size)                      __allowed(on_parameter)
+#define __deref_bcount_opt(size)                      __allowed(on_parameter)
+#define __deref_xcount_opt(size)                      __allowed(on_parameter)
+#define __deref_in_opt                                __allowed(on_parameter)
+#define __deref_in_ecount_opt(size)                   __allowed(on_parameter)
+#define __deref_in_bcount_opt(size)                   __allowed(on_parameter)
+#define __deref_in_xcount_opt(size)                   __allowed(on_parameter)
+#define __deref_out_opt                               __allowed(on_parameter)
+#define __deref_out_ecount_opt(size)                  __allowed(on_parameter)
+#define __deref_out_bcount_opt(size)                  __allowed(on_parameter)
+#define __deref_out_xcount_opt(size)                  __allowed(on_parameter)
+#define __deref_out_ecount_part_opt(size,len)         __allowed(on_parameter)
+#define __deref_out_bcount_part_opt(size,len)         __allowed(on_parameter)
+#define __deref_out_xcount_part_opt(size,len)         __allowed(on_parameter)
+#define __deref_out_ecount_full_opt(size)             __allowed(on_parameter)
+#define __deref_out_bcount_full_opt(size)             __allowed(on_parameter)
+#define __deref_out_xcount_full_opt(size)             __allowed(on_parameter)
+#define __deref_out_z_opt                             __allowed(on_parameter)
+#define __deref_out_ecount_z_opt(size)                __allowed(on_parameter)
+#define __deref_out_bcount_z_opt(size)                __allowed(on_parameter)
+#define __deref_inout_opt                             __allowed(on_parameter)
+#define __deref_inout_ecount_opt(size)                __allowed(on_parameter)
+#define __deref_inout_bcount_opt(size)                __allowed(on_parameter)
+#define __deref_inout_xcount_opt(size)                __allowed(on_parameter)
+#define __deref_inout_ecount_part_opt(size,len)       __allowed(on_parameter)
+#define __deref_inout_bcount_part_opt(size,len)       __allowed(on_parameter)
+#define __deref_inout_xcount_part_opt(size,len)       __allowed(on_parameter)
+#define __deref_inout_ecount_full_opt(size)           __allowed(on_parameter)
+#define __deref_inout_bcount_full_opt(size)           __allowed(on_parameter)
+#define __deref_inout_xcount_full_opt(size)           __allowed(on_parameter)
+#define __deref_inout_z_opt                           __allowed(on_parameter)
+#define __deref_inout_ecount_z_opt(size)              __allowed(on_parameter)
+#define __deref_inout_bcount_z_opt(size)              __allowed(on_parameter)
+#define __deref_opt_ecount(size)                      __allowed(on_parameter)
+#define __deref_opt_bcount(size)                      __allowed(on_parameter)
+#define __deref_opt_xcount(size)                      __allowed(on_parameter)
+#define __deref_opt_in                                __allowed(on_parameter)
+#define __deref_opt_in_ecount(size)                   __allowed(on_parameter)
+#define __deref_opt_in_bcount(size)                   __allowed(on_parameter)
+#define __deref_opt_in_xcount(size)                   __allowed(on_parameter)
+#define __deref_opt_out                               __allowed(on_parameter)
+#define __deref_opt_out_ecount(size)                  __allowed(on_parameter)
+#define __deref_opt_out_bcount(size)                  __allowed(on_parameter)
+#define __deref_opt_out_xcount(size)                  __allowed(on_parameter)
+#define __deref_opt_out_ecount_part(size,len)         __allowed(on_parameter)
+#define __deref_opt_out_bcount_part(size,len)         __allowed(on_parameter)
+#define __deref_opt_out_xcount_part(size,len)         __allowed(on_parameter)
+#define __deref_opt_out_ecount_full(size)             __allowed(on_parameter)
+#define __deref_opt_out_bcount_full(size)             __allowed(on_parameter)
+#define __deref_opt_out_xcount_full(size)             __allowed(on_parameter)
+#define __deref_opt_inout                             __allowed(on_parameter)
+#define __deref_opt_inout_ecount(size)                __allowed(on_parameter)
+#define __deref_opt_inout_bcount(size)                __allowed(on_parameter)
+#define __deref_opt_inout_xcount(size)                __allowed(on_parameter)
+#define __deref_opt_inout_ecount_part(size,len)       __allowed(on_parameter)
+#define __deref_opt_inout_bcount_part(size,len)       __allowed(on_parameter)
+#define __deref_opt_inout_xcount_part(size,len)       __allowed(on_parameter)
+#define __deref_opt_inout_ecount_full(size)           __allowed(on_parameter)
+#define __deref_opt_inout_bcount_full(size)           __allowed(on_parameter)
+#define __deref_opt_inout_xcount_full(size)           __allowed(on_parameter)
+#define __deref_opt_inout_z                           __allowed(on_parameter)
+#define __deref_opt_inout_ecount_z(size)              __allowed(on_parameter)
+#define __deref_opt_inout_bcount_z(size)              __allowed(on_parameter)
+#define __deref_opt_ecount_opt(size)                  __allowed(on_parameter)
+#define __deref_opt_bcount_opt(size)                  __allowed(on_parameter)
+#define __deref_opt_xcount_opt(size)                  __allowed(on_parameter)
+#define __deref_opt_in_opt                            __allowed(on_parameter)
+#define __deref_opt_in_ecount_opt(size)               __allowed(on_parameter)
+#define __deref_opt_in_bcount_opt(size)               __allowed(on_parameter)
+#define __deref_opt_in_xcount_opt(size)               __allowed(on_parameter)
+#define __deref_opt_out_opt                           __allowed(on_parameter)
+#define __deref_opt_out_ecount_opt(size)              __allowed(on_parameter)
+#define __deref_opt_out_bcount_opt(size)              __allowed(on_parameter)
+#define __deref_opt_out_xcount_opt(size)              __allowed(on_parameter)
+#define __deref_opt_out_ecount_part_opt(size,len)     __allowed(on_parameter)
+#define __deref_opt_out_bcount_part_opt(size,len)     __allowed(on_parameter)
+#define __deref_opt_out_xcount_part_opt(size,len)     __allowed(on_parameter)
+#define __deref_opt_out_ecount_full_opt(size)         __allowed(on_parameter)
+#define __deref_opt_out_bcount_full_opt(size)         __allowed(on_parameter)
+#define __deref_opt_out_xcount_full_opt(size)         __allowed(on_parameter)  
+#define __deref_opt_out_z_opt                         __allowed(on_parameter)
+#define __deref_opt_out_ecount_z_opt(size)            __allowed(on_parameter)
+#define __deref_opt_out_bcount_z_opt(size)            __allowed(on_parameter)
+#define __deref_opt_inout_opt                         __allowed(on_parameter)
+#define __deref_opt_inout_ecount_opt(size)            __allowed(on_parameter)
+#define __deref_opt_inout_bcount_opt(size)            __allowed(on_parameter)
+#define __deref_opt_inout_xcount_opt(size)            __allowed(on_parameter)
+#define __deref_opt_inout_ecount_part_opt(size,len)   __allowed(on_parameter) 
+#define __deref_opt_inout_bcount_part_opt(size,len)   __allowed(on_parameter)
+#define __deref_opt_inout_xcount_part_opt(size,len)   __allowed(on_parameter)
+#define __deref_opt_inout_ecount_full_opt(size)       __allowed(on_parameter)
+#define __deref_opt_inout_bcount_full_opt(size)       __allowed(on_parameter)
+#define __deref_opt_inout_xcount_full_opt(size)       __allowed(on_parameter)
+#define __deref_opt_inout_z_opt                       __allowed(on_parameter)
+#define __deref_opt_inout_ecount_z_opt(size)          __allowed(on_parameter)
+#define __deref_opt_inout_bcount_z_opt(size)          __allowed(on_parameter)
+/************************************************************************
+*  Advanced Annotations
+* 
+*  Advanced annotations describe behavior that is not expressible with the
+*  regular buffer macros. These may be used either to annotate buffer
+*  parameters that involve complex or conditional behavior, or to enrich
+*  existing annotations with additional information.
+* 
+*  __success(expr) T f() : <expr> indicates whether function f succeeded or
+*  not. If <expr> is true at exit, all the function's guarantees (as given
+*  by other annotations) must hold. If <expr> is false at exit, the caller
+*  should not expect any of the function's guarantees to hold. If not used,
+*  the function must always satisfy its guarantees. Added automatically to
+*  functions that indicate success in standard ways, such as by returning an
+*  HRESULT.
+* 
+*  __out_awcount(expr, size) T *p : Pointer p is a buffer whose size may be
+*  given in either bytes or elements. If <expr> is true, this acts like
+*  __out_bcount. If <expr> is false, this acts like __out_ecount. This
+*  should only be used to annotate old APIs.
+* 
+*  __in_awcount(expr, size) T* p : Pointer p is a buffer whose size may be given
+*  in either bytes or elements. If <expr> is true, this acts like
+*  __in_bcount. If <expr> is false, this acts like __in_ecount. This should
+*  only be used to annotate old APIs.
+* 
+*  __nullterminated T* p : Pointer p is a buffer that may be read or written
+*  up to and including the first '\0' character or pointer. May be used on
+*  typedefs, which marks valid (properly initialized) instances of that type
+*  as being null-terminated.
+* 
+*  __nullnullterminated T* p : Pointer p is a buffer that may be read or
+*  written up to and including the first sequence of two '\0' characters or
+*  pointers. May be used on typedefs, which marks valid instances of that
+*  type as being double-null terminated.
+* 
+*  __reserved T v : Value v must be 0/NULL, reserved for future use.
+* 
+*  __checkReturn T f(); : Return value of f must not be ignored by callers
+*  of this function.
+* 
+*  __typefix(ctype) T v : Value v should be treated as an instance of ctype,
+*  rather than its declared type when considering validity.
+* 
+*  __override T f(); : Specify C#-style 'override' behaviour for overriding
+*  virtual methods.
+* 
+*  __callback T f(); : Function f can be used as a function pointer.
+* 
+*  __format_string T p : Pointer p is a string that contains % markers in
+*  the style of printf.
+* 
+*  __blocksOn(resource) f(); : Function f blocks on the resource 'resource'.
+* 
+*  __fallthrough : Annotates switch statement labels where fall-through is
+*  desired, to distinguish from forgotten break statements.
+* 
+*  __range(low_bnd, up_bnd) int f(): The return from the function "f" must
+*  be in the inclusive numeric range [low_bnd, up_bnd].
+*
+*  __in_range(low_bnd, up_bnd) int i : Precondition that integer i must be
+*  in the inclusive numeric range [low_bnd, up_bnd].
+* 
+*  __out_range(low_bnd, up_bnd) int i : Postcondition that integer i must be
+*  in the inclusive numeric range [low_bnd, up_bnd].
+* 
+*  __deref_in_range(low_bnd, up_bnd) int* pi : Precondition that integer *pi
+*  must be in the inclusive numeric range [low_bnd, up_bnd].
+*
+*  __deref_out_range(low_bnd, up_bnd) int* pi : Postcondition that integer
+*  *pi must be in the inclusive numeric range [low_bnd, up_bnd].
+*
+*  The first argument of a range macro may also be a C relational operator
+*  (<,>,!=, ==, <=, >=).
+*  
+*  __range(rel_op, j) int f(): Postcondition that "f() rel_op j" must be
+*  true.  Note that j may be a expression known only at runtime.
+*
+*  __in_range(rel_op, j) int i : Precondition that "i rel_op j" must be
+*  true.  Note that j may be a expression known only at runtime.
+* 
+*  __out_range(rel_op, j) int i : Postcondition that integer "i rel_op j"
+*  must be true.  Note that j may be a expression known only at runtime.
+* 
+*  __deref_in_range(rel_op, j) int *pi : Precondition that "*pi rel_op j"
+*  must be true.  Note that j may be a expression known only at runtime.
+*
+*  __deref_out_range(rel_op, j) int *pi : Postcondition that "*pi rel_op j"
+*  must be true.  Note that j may be a expression known only at runtime.
+*
+*  __in_bound int i : Precondition that integer i must be bound, but the
+*  exact range can't be specified at compile time.  __in_range should be
+*  used if the range can be explicitly stated.
+*
+*  __out_bound int i : Postcondition that integer i must be bound, but the
+*  exact range can't be specified at compile time.  __out_range should be
+*  used if the range can be explicitly stated.
+* 
+*  __deref_out_bound int pi : Postcondition that integer *pi must be bound,
+*  but the exact range can't be specified at compile time.
+*  __deref_out_range should be used if the range can be explicitly stated.
+* 
+*  __assume_bound(expr); : Assume that the expression is bound to some known
+*  range. This can be used to suppress integer overflow warnings on integral
+*  expressions that are known to be bound due to reasons not explicit in the
+*  code. Use as a statement in the body of a function.
+* 
+*  __allocator void f(): Function allocates memory using an integral size
+*  argument
+*
+*  ----------------------------------------------------------------------------
+*  Advanced Annotation Examples
+* 
+*  __success(return == TRUE) LWSTDAPI_(BOOL) 
+*  PathCanonicalizeA(__out_ecount(MAX_PATH) LPSTR pszBuf, LPCSTR pszPath);
+*  //  pszBuf is only guaranteed to be null-terminated when TRUE is returned.
+* 
+*  // Initialized LPWSTRs are null-terminated strings.
+*  typedef __nullterminated WCHAR* LPWSTR;
+* 
+*  __out_ecount(cch) __typefix(LPWSTR) void *psz;
+*  // psz is a buffer parameter which will be a null-terminated WCHAR string 
+*  // at exit, and which initially contains cch WCHARs.
+* 
+************************************************************************/
+#define __success(expr)          __allowed(on_function_or_typedecl)
+#define __out_awcount(expr,size) __allowed(on_parameter) 
+#define __in_awcount(expr,size)  __allowed(on_parameter)   
+#define __nullterminated         __allowed(on_typedecl)
+#define __nullnullterminated     __allowed(on_typedecl)
+#define __reserved               __allowed(on_parameter)
+#define __checkReturn            __allowed(on_function)
+#define __typefix(ctype)         __allowed(on_parameter_or_return) 
+#define __override               __allowed(on_function) 
+#define __callback               __allowed(on_function) 
+#define __format_string          __allowed(on_parameter_or_return) 
+#define __blocksOn(resource)     __allowed(on_function) 
+#define __fallthrough            __allowed(as_statement)
+#define __range(lb,ub)           __allowed(on_return) 
+#define __in_range(lb,ub)        __allowed(on_parameter) 
+#define __out_range(lb,ub)       __allowed(on_parameter) 
+#define __deref_in_range(lb,ub)  __allowed(on_parameter) 
+#define __deref_out_range(lb,ub) __allowed(on_parameter) 
+#define __field_range(lb,ub)     __allowed(on_field)
+#define __bound                  __allowed(on_return) 
+#define __in_bound               __allowed(on_parameter) 
+#define __out_bound              __allowed(on_parameter) 
+#define __deref_out_bound        __allowed(on_parameter) 
+#define __assume_bound(i)        __allowed(as_statement_with_arg(i))
+#define __allocator              __allowed(on_function) 
+/*************************************************************************** 
+* Expert Macros
+***************************************************************************/
+#define __null                  __allowed(on_typedecl)
+#define __notnull               __allowed(on_typedecl)
+#define __maybenull             __allowed(on_typedecl)
+#define __exceptthat            __allowed(on_typedecl)
+/*************************************************************************** 
+* Macros to classify fields of structures.
+*                          Structure Annotations
+*
+*   The buffer annotations are a convenient way of describing
+*   relationships between buffers and their size on a function by
+*   function basis. Very often struct or class data members have similar
+*   invariants, which can be expressed directly on the type.
+*
+*   Similar to our buffer annotations we can summarize all the various
+*   structure annotations by one choosing an element from each column of
+*   this table to build a composite annotation.
+*
+*           +--------------------------------------------------+
+*           | Selector |  Units  |    Size/Init     | Optional |
+*           |----------+---------+------------------+----------|
+*           | __field  | _ecount | (size)           | empty    |
+*           |----------+---------+------------------+----------|
+*           | __struct | _bcount | _full(size)      | _opt     |
+*           |----------+---------+------------------+----------|
+*           |          | _xcount | _part(size,init) |          |
+*           +--------------------------------------------------+
+*
+*   Note that empty represents the empty string. Sometime arguments need
+*   to be "floated" to the left to give us a valid annotation name. For
+*   example the naive combination __field_ecount(size)_opt is actually
+*   written as __field_ecount_opt(size). Not all possible combinations
+*   are currently supported or sensible. See specstrings_strict.h for
+*   the currently supported set. Those that are supported are documented
+*   below.
+*
+*Summary of Elements
+*
+*   Selector
+*
+*                __field
+*                        The annotation should only be placed in front
+*                        of data members of structures and classes. The
+*                        data members are pointers to a block of data.
+*                        The annotations describe properties about the
+*                        size of the block of data. This can be used for
+*
+*                __struct
+*                        The annotation should only be placed at the
+*                        beginning of the definition of a structure or
+*                        class. These annotations are used when a struct
+*                        or class is used as a "header" that is
+*                        allocated inline with a block of data and there
+*                        is no apparent field that represents the tail
+*                        end of the structure.
+*
+*   Units
+*
+*                _ecount
+*                        All size and initialization values are in terms
+*                        of elements of the appropriate type
+*
+*                _bcount
+*                        All size and initialization values are in terms
+*                        of raw byte sizes.
+*
+*                _xcount
+*                        The size or initialization values cannot be
+*                        properly expressed as a simple byte or element
+*                        count, and instead a place holder is used to
+*                        document the relationship.
+*
+*   Size/Init
+*           All the size/init expressions can contain references to
+*           other fields in the struct or class.
+*
+*                (size)
+*                        The size of the buffer is determined by the
+*                        expression size. Unless, the type of the buffer
+*                        provides more information nothing is know about
+*                        how much of this data is initialized. For
+*                        example, if the data member happens to be a
+*                        string type such as LPSTR. It is assumed that
+*                        the data is initialized to the first '\0'.
+*
+*                _full(size)
+*                        The size of the buffer is determined by the
+*                        expression size and all the data in the buffer
+*                        is guaranteed to be initialized.
+*
+*                _part(size,init)
+*                        The size of the buffer is determined by the
+*                        expression size and all the data in the buffer
+*                        is guaranteed to be initialized up to init
+*                        elements or bytes.
+*
+*   Optional
+*
+*                empty
+*                        The pointer to the block of memory is never
+*                        NULL
+*
+*                _opt
+*                        The pointer to the block of memory is may be
+*                        NULL
+*
+*     
+*   // Basic Usage of Struct Annotations                         
+*   #include <stdio.h>                                           
+*   #include <stdlib.h>                                          
+*   struct buf_s {                                               
+*    int sz;                                                     
+*    __field_bcount_full(sz)                                     
+*    char *buf;                                                  
+*   };                                                           
+*   void InitBuf(__out struct *buf_s b,int sz) {                 
+*        b->buf = calloc(sz,sizeof(char));                       
+*        b->sz = sz;                                             
+*   }                                                            
+*   void WriteBuf(__in FILE *fp,__in struct *buf_s b) {          
+*     fwrite(b->buf,b->sz,sizeof(char),fp);                      
+*   }                                                            
+*   void ReadBuf(__in FILE *fp,__inout struct *buf_s b) {        
+*     fread(b->buf,b->sz,sizeof(char),fp);                       
+*   }                                                            
+*                                                                 
+*                                                                 
+*                                                                 
+*   // Inline Allocated Buffer                                   
+*   struct buf_s {                                               
+*    int sz;                                                     
+*    __field_bcount(sz)                                          
+*    char buf[1];                                                
+*   };                                                           
+*   void WriteBuf(__in FILE *fp,__in struct *buf_s b) {          
+*     fwrite(&(b->buf),b->sz,sizeof(char),fp);                   
+*   }                                                            
+*   void ReadBuf(__in FILE *fp,__inout struct *buf_s b) {        
+*     fread(&(b->buf),b->sz,sizeof(char),fp);                    
+*   }                                                            
+*                                                                 
+*                                                                 
+*                                                                 
+*   // Embedded Header Structure                                 
+*   __struct_bcount(sz)                                          
+*   struct buf_s {                                               
+*    int sz;                                                     
+*   };                                                           
+*   void WriteBuf(__in FILE *fp,__in struct *buf_s b) {          
+*     fwrite(&b,b->sz,sizeof(char),fp);                          
+*   }                                                            
+*   void ReadBuf(__in FILE *fp,__inout struct *buf_s b) {        
+*     fread(&b,b->sz,sizeof(char),fp);                           
+*   }                                                            
+*
+*
+****************************************************************************/
+#define __field_ecount(size)               __allowed(on_field)
+#define __field_bcount(size)               __allowed(on_field)
+#define __field_xcount(size)               __allowed(on_field)
+#define __field_ecount_opt(size)           __allowed(on_field)
+#define __field_bcount_opt(size)           __allowed(on_field)
+#define __field_xcount_opt(size)           __allowed(on_field)
+#define __field_ecount_part(size,init)     __allowed(on_field)
+#define __field_bcount_part(size,init)     __allowed(on_field)
+#define __field_xcount_part(size,init)     __allowed(on_field)
+#define __field_ecount_part_opt(size,init) __allowed(on_field)
+#define __field_bcount_part_opt(size,init) __allowed(on_field)
+#define __field_xcount_part_opt(size,init) __allowed(on_field)
+#define __field_ecount_full(size)          __allowed(on_field)
+#define __field_bcount_full(size)          __allowed(on_field)
+#define __field_xcount_full(size)          __allowed(on_field)
+#define __field_ecount_full_opt(size)      __allowed(on_field)
+#define __field_bcount_full_opt(size)      __allowed(on_field) 
+#define __field_xcount_full_opt(size)      __allowed(on_field)
+#define __struct_bcount(size)              __allowed(on_struct) 
+#define __struct_xcount(size)              __allowed(on_struct) 
+
+/*************************************************************************** 
+* Macros to classify the entrypoints and indicate their category.
+*
+* Pre-defined control point categories include: RPC, KERNEL, GDI.
+*
+* Pre-defined control point macros include:
+*  __rpc_entry, __kernel_entry, __gdi_entry.
+***************************************************************************/
+#define __control_entrypoint(category)     __allowed(on_function) 
+#define __rpc_entry                        __allowed(on_function) 
+#define __kernel_entry                     __allowed(on_function) 
+#define __gdi_entry                        __allowed(on_function)  
+
+/*************************************************************************** 
+* Macros to track untrusted data and their validation. The list of untrusted
+* sources include:
+*
+* FILE                     - File reading stream or API
+* NETWORK                  - Socket readers
+* INTERNET                 - WinInet and WinHttp readers
+* USER_REGISTRY            - HKCU portions of the registry
+* USER_MODE                - Parameters to kernel entry points
+* RPC                      - Parameters to RPC entry points 
+* DRIVER                   - Device driver 
+***************************************************************************/
+#define __in_data_source(src_sym)       __allowed(on_parameter) 
+#define __out_data_source(src_sym)      __allowed(on_parameter) 
+#define __field_data_source(src_sym)    __allowed(on_field)
+#define __this_out_data_source(src_syn) __allowed(on_function)
+
+/************************************************************************** 
+* Macros to tag file parsing code. Predefined formats include:
+*  PNG                     - Portable Network Graphics
+*  JPEG                    - Joint Photographic Experts Group
+*  BMP                     - Bitmap
+*  RC_BMP                  - Resource bitmap
+*  WMF                     - Windows Metafile
+*  EMF                     - Windows Enhanced Metafile
+*  GIF                     - Graphics Interchange Format
+*  MIME_TYPE               - MIME type from header tokens
+*  MAIL_MONIKER            - MAIL information refered by URL moniker
+*  HTML                    - HyperText Markup Language
+*  WMPHOTO                 - Windows media photo
+*  OE_VCARD                - Outlook Express virtual card
+*  OE_CONTACT              - Outlook Express contact
+*  MIDI                    - Musical Instrument Digital Interface
+*  LDIF                    - LDAP Data Interchange Format
+*  AVI                     - Audio Visual Interchange
+*  ACM                     - Audio Compression Manager
+**************************************************************************/
+#define __out_validated(filetype_sym)         __allowed(on_parameter) 
+#define __this_out_validated(filetype_sym)    __allowed(on_function)   
+#define __file_parser(filetype_sym)           __allowed(on_function) 
+#define __file_parser_class(filetype_sym)     __allowed(on_struct)  
+#define __file_parser_library(filetype_sym)   __allowed(as_global_decl)  
+
+/*************************************************************************** 
+* Macros to track the code content in the file. The type of code
+* contents currently tracked:
+*
+* NDIS_DRIVER                   - NDIS Device driver 
+***************************************************************************/
+#define __source_code_content(codetype_sym)     __allowed(as_global_decl) 
+
+/*************************************************************************** 
+* Macros to track the code content in the class. The type of code
+* contents currently tracked:
+*
+* DCOM                          - Class implementing DCOM
+***************************************************************************/
+#define __class_code_content(codetype_sym)    __allowed(on_struct) 
+
+/*************************************************************************
+* Macros to tag encoded function pointers
+**************************************************************************/
+#define __encoded_pointer                 
+#define __encoded_array                   
+#define __field_encoded_pointer           __allowed(on_field)
+#define __field_encoded_array             __allowed(on_field)
+
+#define __transfer(formal)                __allowed(on_parameter_or_return) 
+#define __assume_validated(exp)           __allowed(as_statement_with_arg(exp))
+
+/************************************************************************* 
+* __analysis_assume(expr) : Expert macro use only when directed. Use this to
+* tell static analysis tools like PREfix and PREfast about a non-coded
+* assumption that you wish the tools to assume. The assumption will be
+* understood by those tools. By default there is no dynamic checking or
+* static checking of the assumption in any build.
+*
+* To obtain dynamic checking wrap this macro in your local version of a debug
+* assert.
+* Please do not put function calls in the expression because this is not
+* supported by all tools:
+*  __analysis_assume(GetObject () != NULL); // DO NOT DO THIS
+*
+*************************************************************************/
+#define __analysis_assume(expr) __allowed(as_statement_with_arg(expr))
+#define __analysis_assert(expr) __allowed(as_statement_with_arg(expr))
+
+/************************************************************************* 
+* __analysis_hint(hint_sym) : Expert macro use only when
+* directed. Use this to influence certain analysis heuristics
+* used by the tools. These hints do not describe the semantics
+* of functions but simply direct the tools to act in a certain
+* way.
+*
+* Current hints that are supported are:
+*
+* INLINE   - inline this function during analysis overrides any
+*            default heuristics 
+* NOINLINE - do not inline this function during analysis overrides 
+*            and default heuristics
+*************************************************************************/
+#define __analysis_hint(hint) __allowed(on_function)
+
+/************************************************************************* 
+* Macros to encode abstract properties of values. Used by SALadt.h
+*************************************************************************/
+#define __type_has_adt_prop(adt,prop)     __allowed(on_typdecl)
+#define __out_has_adt_prop(adt,prop)      __allowed(on_parameter)
+#define __out_not_has_adt_prop(adt,prop)  __allowed(on_parameter)
+#define __out_transfer_adt_prop(arg)      __allowed(on_parameter)
+#define __out_has_type_adt_props(typ)     __allowed(on_parameter)
+#define __assume_ValidCompNameA(expr)     __allowed(as_statement_with_arg(expr))
+#define __assume_ValidCompNameW(expr)     __allowed(as_statement_with_arg(expr))
+
+/************************************************************************* 
+* Macros used by Prefast for Drivers 
+* 
+*  __possibly_notnulltermiated :
+*
+*  Used for return values of parameters or functions that do not
+*  guarantee nullterimination in all cases.
+*
+*************************************************************************/
+#define __possibly_notnulltermiated     __allowed(on_parameter_or_return)
+
+/************************************************************************* 
+* Advanced macros
+* 
+*  __volatile 
+* The __volatile annotation identifies a global variable or
+* structure field that: 
+*   1) is not declared volatile; 
+*   2) is accessed concurrently by multiple threads.
+*
+* The __deref_volatile annotation identifies a global variable
+* or structure field that stores a pointer to some data that:
+*   1) is not declared volatile; 
+*   2) is accessed concurrently by multiple threads.
+*
+* Prefast uses these annotations to find patterns of code that
+* may result in unexpected re-fetching of the global variable
+* into a local variable.
+*
+* We also provide two complimentary annotations __nonvolatile
+* and __deref_nonvolatile that could be used to suppress Prefast
+*
+* re-fetching warnings on variables that are known either:
+*   1) not to be in danger of being re-fetched or,
+*   2) not to lead to incorrect results if they are re-fetched
+*
+*************************************************************************/
+#define __volatile                       __allowed(on_global_or_field)
+#define __deref_volatile                 __allowed(on_global_or_field)
+#define __nonvolatile                    __allowed(on_global_or_field)
+#define __deref_nonvolatile              __allowed(on_global_or_field)
+
+/************************************************************************* 
+* Macros deprecated with strict level greater then 1.
+**************************************************************************/
+#if (__SPECSTRINGS_STRICT_LEVEL > 1)
+/* Must come before macro defintions */
+#pragma deprecated(__in_nz)
+#pragma deprecated(__in_ecount_nz)
+#pragma deprecated(__in_bcount_nz)
+#pragma deprecated(__out_nz)
+#pragma deprecated(__out_nz_opt)
+#pragma deprecated(__out_ecount_nz)
+#pragma deprecated(__out_bcount_nz)
+#pragma deprecated(__inout_nz)
+#pragma deprecated(__inout_ecount_nz)
+#pragma deprecated(__inout_bcount_nz)
+#pragma deprecated(__in_nz_opt)          
+#pragma deprecated(__in_ecount_nz_opt)
+#pragma deprecated(__in_bcount_nz_opt)
+#pragma deprecated(__out_ecount_nz_opt)
+#pragma deprecated(__out_bcount_nz_opt)
+#pragma deprecated(__inout_nz_opt)       
+#pragma deprecated(__inout_ecount_nz_opt)
+#pragma deprecated(__inout_bcount_nz_opt)
+#pragma deprecated(__deref_out_nz)                 
+#pragma deprecated(__deref_out_ecount_nz)
+#pragma deprecated(__deref_out_bcount_nz)
+#pragma deprecated(__deref_inout_nz)               
+#pragma deprecated(__deref_inout_ecount_nz)
+#pragma deprecated(__deref_inout_bcount_nz)
+#pragma deprecated(__deref_out_nz_opt)             
+#pragma deprecated(__deref_out_ecount_nz_opt)
+#pragma deprecated(__deref_out_bcount_nz_opt)
+#pragma deprecated(__deref_inout_nz_opt)           
+#pragma deprecated(__deref_inout_ecount_nz_opt)
+#pragma deprecated(__deref_inout_bcount_nz_opt)
+#pragma deprecated(__deref_opt_inout_nz)           
+#pragma deprecated(__deref_opt_inout_ecount_nz)
+#pragma deprecated(__deref_opt_inout_bcount_nz)
+#pragma deprecated(__deref_opt_out_nz_opt)         
+#pragma deprecated(__deref_opt_out_ecount_nz_opt)
+#pragma deprecated(__deref_opt_out_bcount_nz_opt)
+#pragma deprecated(__deref_opt_inout_nz_opt)       
+#pragma deprecated(__deref_opt_inout_ecount_nz_opt)
+#pragma deprecated(__deref_opt_inout_bcount_nz_opt)
+#pragma deprecated(__deref)
+#pragma deprecated(__pre)
+#pragma deprecated(__post)
+#pragma deprecated(__readableTo)
+#pragma deprecated(__writableTo)
+#pragma deprecated(__maybevalid)
+#pragma deprecated(__data_entrypoint)
+#pragma deprecated(__inexpressible_readableTo)
+#pragma deprecated(__readonly)
+#pragma deprecated(__byte_writableTo)
+#pragma deprecated(__byte_readableTo)
+#pragma deprecated(__elem_readableTo)
+#pragma deprecated(__elem_writableTo)
+#pragma deprecated(__valid)
+#pragma deprecated(__notvalid)
+#pragma deprecated(__refparam)
+#pragma deprecated(__precond)
+#endif
+/* Define soon to be deprecated macros to nops. */
+#define __in_nz                                       
+#define __in_ecount_nz(size)                          
+#define __in_bcount_nz(size)                          
+#define __out_nz                                      
+#define __out_nz_opt                                  
+#define __out_ecount_nz(size)                         
+#define __out_bcount_nz(size)                         
+#define __inout_nz                                    
+#define __inout_ecount_nz(size)                       
+#define __inout_bcount_nz(size)                       
+#define __in_nz_opt                                   
+#define __in_ecount_nz_opt(size)                      
+#define __in_bcount_nz_opt(size)                      
+#define __out_ecount_nz_opt(size)                     
+#define __out_bcount_nz_opt(size)                     
+#define __inout_nz_opt                                
+#define __inout_ecount_nz_opt(size)                   
+#define __inout_bcount_nz_opt(size)                   
+#define __deref_out_nz                                
+#define __deref_out_ecount_nz(size)                   
+#define __deref_out_bcount_nz(size)                   
+#define __deref_inout_nz                              
+#define __deref_inout_ecount_nz(size)                 
+#define __deref_inout_bcount_nz(size)                 
+#define __deref_out_nz_opt                            
+#define __deref_out_ecount_nz_opt(size)               
+#define __deref_out_bcount_nz_opt(size)               
+#define __deref_inout_nz_opt                          
+#define __deref_inout_ecount_nz_opt(size)             
+#define __deref_inout_bcount_nz_opt(size)             
+#define __deref_opt_inout_nz                          
+#define __deref_opt_inout_ecount_nz(size)             
+#define __deref_opt_inout_bcount_nz(size)             
+#define __deref_opt_out_nz_opt                        
+#define __deref_opt_out_ecount_nz_opt(size)           
+#define __deref_opt_out_bcount_nz_opt(size)           
+#define __deref_opt_inout_nz_opt                      
+#define __deref_opt_inout_ecount_nz_opt(size)         
+#define __deref_opt_inout_bcount_nz_opt(size)         
+#define __deref             
+#define __pre               
+#define __post              
+#define __readableTo(count) 
+#define __writableTo(count) 
+#define __maybevalid        
+#define __inexpressible_readableTo(string) 
+#define __data_entrypoint(category)
+#define __readonly
+#define __byte_writableTo(count)
+#define __byte_readableTo(count)
+#define __elem_readableTo(count)
+#define __elem_writableTo(count)
+#define __valid
+#define __notvalid
+#define __refparam
+#define __precond(condition)
+
+/************************************************************************* 
+* Definitions to force a compile error when macros are used improperly.
+* Relies on VS 2005 source annotations.
+*************************************************************************/
+#define __allowed(p) __$allowed_##p
+#define __$allowed_as_global_decl /* empty */
+#define __$allowed_as_statement_with_arg(x) \
+    __pragma(warning(push)) __pragma(warning(disable : 4548)) \
+        do {__noop(x);} while((0,0) __pragma(warning(pop)) )
+#define __$allowed_as_statement __$allowed_as_statement_with_arg(1)
+
+/**************************************************************************
+*  This should go away. It's only for __success which we should split into.
+*  __success and __typdecl_sucess
+***************************************************************************/
+#define __$allowed_on_function_or_typedecl /* empty */
+#if (__SPECSTRINGS_STRICT_LEVEL == 1) || (__SPECSTRINGS_STRICT_LEVEL == 2)
+#define __$allowed_on_typedecl /* empty */
+#define __$allowed_on_return /* empty */
+#define __$allowed_on_parameter /* empty */
+#define __$allowed_on_function /* empty */
+#define __$allowed_on_struct /* empty */
+#define __$allowed_on_field /* empty */
+#define __$allowed_on_parameter_or_return /* empty */
+#define __$allowed_on_global_or_field /* empty */
+#elif __SPECSTRINGS_STRICT_LEVEL == 3
+#define __$allowed_on_typedecl /* empty */
+/* Define dummy source attributes. Still needs more testing */
+#define __$allowed_on_return [returnvalue: OnReturnOnly]
+#define __$allowed_on_parameter [OnParameterOnly]
+#define __$allowed_on_function [method: OnFunctionOnly]
+#define __$allowed_on_struct [OnStructOnly]
+#define __$allowed_on_field [OnFieldOnly]
+#define __$allowed_on_parameter_or_return [OnParameterOrReturnOnly] 
+#define __$allowed_on_global_or_field /* empty */
+#pragma push_macro( "DECL_SA" )
+#pragma push_macro( "SA" )
+#ifdef __cplusplus
+#define SA(x) x
+#define DECL_SA(name,loc) \
+  [repeatable] \
+  [source_annotation_attribute( loc )] \
+  struct name##Attribute { name##Attribute(); const char* ignored; }; 
+#else
+#define SA(x) SA_##x
+#define DECL_SA(name,loc) \
+  [source_annotation_attribute( loc )] \
+  struct name { const char* ignored; };\
+  typedef struct name name;
+#endif  /* #endif  __cplusplus */
+DECL_SA(OnParameterOnly,SA(Parameter));
+DECL_SA(OnReturnOnly,SA(ReturnValue));
+DECL_SA(OnFunctionOnly,SA(Method));
+DECL_SA(OnStructOnly,SA(Struct));
+DECL_SA(OnFieldOnly,SA(Field));
+DECL_SA(OnParameterOrReturnOnly,SA(Parameter) | SA(ReturnValue));
+#pragma pop_macro( "SA" )
+#pragma pop_macro( "DECL_SA" )
+#endif 
+#endif 
+
+
diff --git a/Source/LibJXR/common/include/wmspecstrings_undef.h b/Source/LibJXR/common/include/wmspecstrings_undef.h
new file mode 100644
index 0000000..86e6159
--- /dev/null
+++ b/Source/LibJXR/common/include/wmspecstrings_undef.h
@@ -0,0 +1,406 @@
+//*@@@+++@@@@******************************************************************
+//
+// Copyright � Microsoft Corp.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+// � Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// � Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//*@@@---@@@@******************************************************************
+
+
+#undef __$adt_add_prop
+#undef __$adt_prop
+#undef __$adt_remove_prop
+#undef __$adt_transfer_prop
+#undef __$adt_type_props
+#undef __$nonvolatile
+#undef __$possibly_notnulltermiated
+#undef __$volatile
+#undef __allocator
+#undef __analysis_assert
+#undef __analysis_assume
+#undef __analysis_hint
+#undef __assume_ValidCompNameA
+#undef __assume_ValidCompNameW
+#undef __assume_bound
+#undef __assume_validated
+#undef __bcount
+#undef __bcount_opt
+#undef __blocksOn
+#undef __bound
+#undef __byte_readableTo
+#undef __byte_writableTo
+#undef __callback
+#undef __checkReturn
+#undef __class_code_content
+#undef __control_entrypoint
+#undef __data_entrypoint
+#undef __deref
+#undef __deref_bcount
+#undef __deref_bcount_opt
+#undef __deref_ecount
+#undef __deref_ecount_opt
+#undef __deref_in
+#undef __deref_in_bcount
+#undef __deref_in_bcount_opt
+#undef __deref_in_ecount
+#undef __deref_in_ecount_opt
+#undef __deref_in_opt
+#undef __deref_in_range
+#undef __deref_in_xcount
+#undef __deref_in_xcount_opt
+#undef __deref_inout
+#undef __deref_inout_bcount
+#undef __deref_inout_bcount_full
+#undef __deref_inout_bcount_full_opt
+#undef __deref_inout_bcount_nz
+#undef __deref_inout_bcount_nz_opt
+#undef __deref_inout_bcount_opt
+#undef __deref_inout_bcount_part
+#undef __deref_inout_bcount_part_opt
+#undef __deref_inout_bcount_z
+#undef __deref_inout_bcount_z_opt
+#undef __deref_inout_ecount
+#undef __deref_inout_ecount_full
+#undef __deref_inout_ecount_full_opt
+#undef __deref_inout_ecount_nz
+#undef __deref_inout_ecount_nz_opt
+#undef __deref_inout_ecount_opt
+#undef __deref_inout_ecount_part
+#undef __deref_inout_ecount_part_opt
+#undef __deref_inout_ecount_z
+#undef __deref_inout_ecount_z_opt
+#undef __deref_inout_nz
+#undef __deref_inout_nz_opt
+#undef __deref_inout_opt
+#undef __deref_inout_xcount
+#undef __deref_inout_xcount_full
+#undef __deref_inout_xcount_full_opt
+#undef __deref_inout_xcount_opt
+#undef __deref_inout_xcount_part
+#undef __deref_inout_xcount_part_opt
+#undef __deref_inout_z
+#undef __deref_inout_z_opt
+#undef __deref_nonvolatile
+#undef __deref_opt_bcount
+#undef __deref_opt_bcount_opt
+#undef __deref_opt_ecount
+#undef __deref_opt_ecount_opt
+#undef __deref_opt_in
+#undef __deref_opt_in_bcount
+#undef __deref_opt_in_bcount_opt
+#undef __deref_opt_in_ecount
+#undef __deref_opt_in_ecount_opt
+#undef __deref_opt_in_opt
+#undef __deref_opt_in_xcount
+#undef __deref_opt_in_xcount_opt
+#undef __deref_opt_inout
+#undef __deref_opt_inout_bcount
+#undef __deref_opt_inout_bcount_full
+#undef __deref_opt_inout_bcount_full_opt
+#undef __deref_opt_inout_bcount_nz
+#undef __deref_opt_inout_bcount_nz_opt
+#undef __deref_opt_inout_bcount_opt
+#undef __deref_opt_inout_bcount_part
+#undef __deref_opt_inout_bcount_part_opt
+#undef __deref_opt_inout_bcount_z
+#undef __deref_opt_inout_bcount_z_opt
+#undef __deref_opt_inout_ecount
+#undef __deref_opt_inout_ecount_full
+#undef __deref_opt_inout_ecount_full_opt
+#undef __deref_opt_inout_ecount_nz
+#undef __deref_opt_inout_ecount_nz_opt
+#undef __deref_opt_inout_ecount_opt
+#undef __deref_opt_inout_ecount_part
+#undef __deref_opt_inout_ecount_part_opt
+#undef __deref_opt_inout_ecount_z
+#undef __deref_opt_inout_ecount_z_opt
+#undef __deref_opt_inout_nz
+#undef __deref_opt_inout_nz_opt
+#undef __deref_opt_inout_opt
+#undef __deref_opt_inout_xcount
+#undef __deref_opt_inout_xcount_full
+#undef __deref_opt_inout_xcount_full_opt
+#undef __deref_opt_inout_xcount_opt
+#undef __deref_opt_inout_xcount_part
+#undef __deref_opt_inout_xcount_part_opt
+#undef __deref_opt_inout_z
+#undef __deref_opt_inout_z_opt
+#undef __deref_opt_out
+#undef __deref_opt_out_bcount
+#undef __deref_opt_out_bcount_full
+#undef __deref_opt_out_bcount_full_opt
+#undef __deref_opt_out_bcount_nz_opt
+#undef __deref_opt_out_bcount_opt
+#undef __deref_opt_out_bcount_part
+#undef __deref_opt_out_bcount_part_opt
+#undef __deref_opt_out_bcount_z_opt
+#undef __deref_opt_out_ecount
+#undef __deref_opt_out_ecount_full
+#undef __deref_opt_out_ecount_full_opt
+#undef __deref_opt_out_ecount_nz_opt
+#undef __deref_opt_out_ecount_opt
+#undef __deref_opt_out_ecount_part
+#undef __deref_opt_out_ecount_part_opt
+#undef __deref_opt_out_ecount_z_opt
+#undef __deref_opt_out_nz_opt
+#undef __deref_opt_out_opt
+#undef __deref_opt_out_xcount
+#undef __deref_opt_out_xcount_full
+#undef __deref_opt_out_xcount_full_opt
+#undef __deref_opt_out_xcount_opt
+#undef __deref_opt_out_xcount_part
+#undef __deref_opt_out_xcount_part_opt
+#undef __deref_opt_out_z_opt
+#undef __deref_opt_xcount
+#undef __deref_opt_xcount_opt
+#undef __deref_out
+#undef __deref_out_bcount
+#undef __deref_out_bcount_full
+#undef __deref_out_bcount_full_opt
+#undef __deref_out_bcount_nz
+#undef __deref_out_bcount_nz_opt
+#undef __deref_out_bcount_opt
+#undef __deref_out_bcount_part
+#undef __deref_out_bcount_part_opt
+#undef __deref_out_bcount_z
+#undef __deref_out_bcount_z_opt
+#undef __deref_out_bound
+#undef __deref_out_ecount
+#undef __deref_out_ecount_full
+#undef __deref_out_ecount_full_opt
+#undef __deref_out_ecount_nz
+#undef __deref_out_ecount_nz_opt
+#undef __deref_out_ecount_opt
+#undef __deref_out_ecount_part
+#undef __deref_out_ecount_part_opt
+#undef __deref_out_ecount_z
+#undef __deref_out_ecount_z_opt
+#undef __deref_out_nz
+#undef __deref_out_nz_opt
+#undef __deref_out_opt
+#undef __deref_out_range
+#undef __deref_out_range
+#undef __deref_out_xcount
+#undef __deref_out_xcount
+#undef __deref_out_xcount_full
+#undef __deref_out_xcount_full_opt
+#undef __deref_out_xcount_opt
+#undef __deref_out_xcount_part
+#undef __deref_out_xcount_part_opt
+#undef __deref_out_z
+#undef __deref_out_z_opt
+#undef __deref_volatile
+#undef __deref_xcount
+#undef __deref_xcount_opt
+#undef __ecount
+#undef __ecount_opt
+#undef __elem_readableTo
+#undef __elem_writableTo
+#undef __encoded_array
+#undef __encoded_pointer
+#undef __exceptthat
+#undef __fallthrough
+#undef __field_bcount
+#undef __field_bcount_full
+#undef __field_bcount_full_opt
+#undef __field_bcount_opt
+#undef __field_bcount_part
+#undef __field_bcount_part_opt
+#undef __field_data_source
+#undef __field_ecount
+#undef __field_ecount_full
+#undef __field_ecount_full_opt
+#undef __field_ecount_opt
+#undef __field_ecount_part
+#undef __field_ecount_part_opt
+#undef __field_encoded_array
+#undef __field_encoded_pointer
+#undef __field_range
+#undef __field_xcount
+#undef __field_xcount_full
+#undef __field_xcount_full_opt
+#undef __field_xcount_opt
+#undef __field_xcount_part
+#undef __field_xcount_part_opt
+#undef __file_parser
+#undef __file_parser_class
+#undef __file_parser_library
+#undef __format_string
+#undef __format_string
+#undef __gdi_entry
+#undef __in
+#undef __in_awcount
+#undef __in_bcount
+#undef __in_bcount_nz
+#undef __in_bcount_nz_opt
+#undef __in_bcount_opt
+#undef __in_bcount_z
+#undef __in_bcount_z_opt
+#undef __in_bound
+#undef __in_data_source
+#undef __in_ecount
+#undef __in_ecount_nz
+#undef __in_ecount_nz_opt
+#undef __in_ecount_opt
+#undef __in_ecount_z
+#undef __in_ecount_z_opt
+#undef __in_nz
+#undef __in_nz_opt
+#undef __in_opt
+#undef __in_range
+#undef __in_xcount
+#undef __in_xcount_opt
+#undef __in_z
+#undef __in_z_opt
+#undef __inexpressible_readableTo
+#undef __inexpressible_writableTo
+#undef __inner_assume_bound
+#undef __inner_assume_bound_dec
+#undef __inner_assume_validated
+#undef __inner_assume_validated_dec
+#undef __inner_blocksOn
+#undef __inner_bound
+#undef __inner_callback
+#undef __inner_checkReturn
+#undef __inner_control_entrypoint
+#undef __inner_data_entrypoint
+#undef __inner_data_source
+#undef __inner_encoded
+#undef __inner_fallthrough
+#undef __inner_fallthrough_dec
+#undef __inner_out_validated
+#undef __inner_override
+#undef __inner_range
+#undef __inner_success
+#undef __inner_transfer
+#undef __inner_typefix
+#undef __inout
+#undef __inout_bcount
+#undef __inout_bcount_full
+#undef __inout_bcount_full_opt
+#undef __inout_bcount_nz
+#undef __inout_bcount_nz_opt
+#undef __inout_bcount_opt
+#undef __inout_bcount_part
+#undef __inout_bcount_part_opt
+#undef __inout_bcount_z
+#undef __inout_bcount_z_opt
+#undef __inout_ecount
+#undef __inout_ecount_full
+#undef __inout_ecount_full_opt
+#undef __inout_ecount_nz
+#undef __inout_ecount_nz_opt
+#undef __inout_ecount_opt
+#undef __inout_ecount_part
+#undef __inout_ecount_part_opt
+#undef __inout_ecount_z
+#undef __inout_ecount_z_opt
+#undef __inout_ecount_z_opt
+#undef __inout_nz
+#undef __inout_nz_opt
+#undef __inout_opt
+#undef __inout_xcount
+#undef __inout_xcount_full
+#undef __inout_xcount_full_opt
+#undef __inout_xcount_opt
+#undef __inout_xcount_part
+#undef __inout_xcount_part_opt
+#undef __inout_z
+#undef __inout_z_opt
+#undef __kernel_entry
+#undef __maybenull
+#undef __maybereadonly
+#undef __maybevalid
+#undef __nonvolatile
+#undef __notnull
+#undef __notreadonly
+#undef __notvalid
+#undef __null
+#undef __nullnullterminated
+#undef __nullterminated
+#undef __out
+#undef __out_awcount
+#undef __out_bcount
+#undef __out_bcount_full
+#undef __out_bcount_full_opt
+#undef __out_bcount_nz
+#undef __out_bcount_nz_opt
+#undef __out_bcount_opt
+#undef __out_bcount_part
+#undef __out_bcount_part_opt
+#undef __out_bcount_z
+#undef __out_bcount_z_opt
+#undef __out_bound
+#undef __out_data_source
+#undef __out_ecount
+#undef __out_ecount_full
+#undef __out_ecount_full_opt
+#undef __out_ecount_nz
+#undef __out_ecount_nz_opt
+#undef __out_ecount_opt
+#undef __out_ecount_part
+#undef __out_ecount_part_opt
+#undef __out_ecount_z
+#undef __out_ecount_z_opt
+#undef __out_has_adt_prop
+#undef __out_has_type_adt_props
+#undef __out_not_has_adt_prop
+#undef __out_nz
+#undef __out_nz_opt
+#undef __out_opt
+#undef __out_range
+#undef __out_transfer_adt_prop
+#undef __out_validated
+#undef __out_xcount
+#undef __out_xcount_full
+#undef __out_xcount_full_opt
+#undef __out_xcount_opt
+#undef __out_xcount_part
+#undef __out_xcount_part_opt
+#undef __out_z
+#undef __override
+#undef __possibly_notnulltermiated
+#undef __post
+#undef __postcond
+#undef __pre
+#undef __precond
+#undef __range
+#undef __readableTo
+#undef __readonly
+#undef __refparam
+#undef __reserved
+#undef __rpc_entry
+#undef __source_code_content
+#undef __struct_bcount
+#undef __struct_xcount
+#undef __success
+#undef __this_out_data_source
+#undef __this_out_validated
+#undef __transfer
+#undef __type_has_adt_prop
+#undef __typefix
+#undef __valid
+#undef __volatile
+#undef __writableTo
+#undef __xcount
+#undef __xcount_opt
\ No newline at end of file
diff --git a/Source/LibJXR/image/decode/JXRTranscode.c b/Source/LibJXR/image/decode/JXRTranscode.c
new file mode 100644
index 0000000..1c72aa8
--- /dev/null
+++ b/Source/LibJXR/image/decode/JXRTranscode.c
@@ -0,0 +1,987 @@
+//*@@@+++@@@@******************************************************************
+//
+// Copyright � Microsoft Corp.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+// � Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// � Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//*@@@---@@@@******************************************************************
+
+#include "windowsmediaphoto.h"
+#include "strcodec.h"
+#include "decode.h"
+
+EXTERN_C Void freePredInfo(CWMImageStrCodec *);
+
+EXTERN_C Int ReadWMIHeader(CWMImageInfo *, CWMIStrCodecParam *, CCoreParameters *);
+EXTERN_C Int StrIODecInit(CWMImageStrCodec *);
+EXTERN_C Int StrDecInit(CWMImageStrCodec *);
+EXTERN_C Int readPackets(CWMImageStrCodec *);
+EXTERN_C Int DecodeMacroblockDC(CWMImageStrCodec *, CCodingContext *, Int, Int);
+EXTERN_C Int DecodeMacroblockLowpass(CWMImageStrCodec *, CCodingContext *, Int, Int);
+EXTERN_C Int DecodeMacroblockHighpass(CWMImageStrCodec *, CCodingContext *, Int, Int);
+EXTERN_C Void predDCACDec(CWMImageStrCodec *);
+EXTERN_C Void predACDec(CWMImageStrCodec *);
+EXTERN_C Void StrIODecTerm(CWMImageStrCodec *);
+EXTERN_C Void FreeCodingContextDec(CWMImageStrCodec *);
+
+EXTERN_C Int StrEncInit(CWMImageStrCodec *);
+EXTERN_C Void StrIOEncTerm(CWMImageStrCodec *);
+EXTERN_C Void FreeCodingContextEnc(CWMImageStrCodec *);
+EXTERN_C Void encodeMB(CWMImageStrCodec *, Int, Int);
+EXTERN_C Int  writeIndexTableNull(CWMImageStrCodec *);
+EXTERN_C Void writePacketHeader(BitIOInfo *, U8, U8);
+
+EXTERN_C Int WriteWMIHeader(CWMImageStrCodec *);
+EXTERN_C Int ReadImagePlaneHeader(CWMImageInfo *, CWMIStrCodecParam *, CCoreParameters *, SimpleBitIO *);
+EXTERN_C Int WriteImagePlaneHeader(CWMImageStrCodec *);
+EXTERN_C Int writeIndexTable(CWMImageStrCodec *);
+EXTERN_C Int copyTo(struct WMPStream *, struct WMPStream *, size_t);
+
+const static Bool bFlipV[O_MAX] = {FALSE, TRUE , FALSE, TRUE, TRUE , TRUE, FALSE, FALSE};
+const static Bool bFlipH[O_MAX] = {FALSE, FALSE, TRUE , TRUE, FALSE, TRUE, FALSE, TRUE};
+
+typedef struct CTileQPInfo
+{
+    U8 dcMode;
+    U8 dcIndex[MAX_CHANNELS];
+
+    Bool bUseDC;
+    U8 lpNum;
+    Bool bUseDCAlpha;
+    U8 lpNumAlpha;
+    U8 lpMode[16];
+    U8 lpIndex[16][MAX_CHANNELS];
+
+    Bool bUseLP;
+    U8 hpNum;
+    Bool bUseLPAlpha;
+    U8 hpNumAlpha;
+    U8 hpMode[16];
+    U8 hpIndex[16][MAX_CHANNELS];
+} CTileQPInfo;
+
+Void transcodeQuantizer(BitIOInfo * pIO, U8 cIndex[MAX_CHANNELS], U8 cChMode, size_t cChannel)
+{
+    if(cChMode > 2)
+        cChMode = 2;
+
+    if(cChannel > 1)
+        putBit16(pIO, cChMode, 2); // Channel mode
+    else
+        cChMode = 0;
+
+    putBit16(pIO, cIndex[0], 8); // Y
+
+    if(cChMode == 1)  // MIXED
+        putBit16(pIO, cIndex[1], 8); // UV
+    else if(cChMode > 0){ // INDEPENDENT
+        size_t i;
+
+        for(i = 1; i < cChannel; i ++)
+            putBit16(pIO, cIndex[i], 8); // UV
+    }
+}
+
+Void transcodeQuantizers(BitIOInfo * pIO, U8 cIndex[16][MAX_CHANNELS], U8 cChMode[16], U32 cNum, size_t cChannel, Bool bCopy)
+{
+    putBit16(pIO, bCopy == TRUE ? 1 : 0, 1);
+    if(bCopy == FALSE){
+        U32 i;
+
+        putBit16(pIO, cNum - 1, 4);
+
+        for(i = 0; i < cNum; i ++)
+            transcodeQuantizer(pIO, cIndex[i], cChMode[i], cChannel);
+    }
+}
+
+Void transcodeQuantizersAlpha(BitIOInfo * pIO, U8 cIndex[16][MAX_CHANNELS], U32 cNum, size_t iChannel, Bool bCopy)
+{
+    putBit16(pIO, bCopy == TRUE ? 1 : 0, 1);
+    if(bCopy == FALSE){
+        U32 i;
+
+        putBit16(pIO, cNum - 1, 4);
+
+        for(i = 0; i < cNum; i ++)
+            putBit16(pIO, cIndex[i][iChannel], 8);
+    }
+}
+
+Void transcodeTileHeader(CWMImageStrCodec * pSC, CTileQPInfo * pTileQPInfo)
+{
+    if(pSC->m_bCtxLeft && pSC->m_bCtxTop && pSC->m_bSecondary == FALSE){ // write packet headers
+        CCodingContext * pContext = &pSC->m_pCodingContext[pSC->cTileColumn];
+        CWMITile * pTile = pSC->pTile + pSC->cTileColumn;
+        U8 pID = (U8)((pSC->cTileRow * (pSC->WMISCP.cNumOfSliceMinus1V + 1) + pSC->cTileColumn) & 0x1F);
+        CWMImageStrCodec * pSCAlpha = (pSC->m_param.bAlphaChannel ? pSC->m_pNextSC : NULL);
+        const size_t iAlphaPos = pSC->m_param.cNumChannels;
+
+        writePacketHeader(pContext->m_pIODC, pSC->WMISCP.bfBitstreamFormat == SPATIAL ? 0 : 1, pID);
+        if (pSC->m_param.bTrimFlexbitsFlag && pSC->WMISCP.bfBitstreamFormat == SPATIAL)
+            putBit16(pContext->m_pIODC, pContext->m_iTrimFlexBits, 4);
+        
+        if((pSC->m_param.uQPMode & 1) != 0) // not DC uniform
+            transcodeQuantizer(pContext->m_pIODC, pTileQPInfo->dcIndex, pTileQPInfo->dcMode, pSC->WMISCP.cChannel);
+        if(pSCAlpha != NULL && (pSCAlpha->m_param.uQPMode & 1) != 0) // not DC uniform
+            putBit16(pContext->m_pIODC, pTileQPInfo->dcIndex[iAlphaPos], 8);
+
+        if(pSC->WMISCP.bfBitstreamFormat == SPATIAL) {
+            if(pSC->WMISCP.sbSubband != SB_DC_ONLY){
+                if((pSC->m_param.uQPMode & 2) != 0) // not LP uniform
+                    transcodeQuantizers(pContext->m_pIODC, pTileQPInfo->lpIndex, pTileQPInfo->lpMode, pTileQPInfo->lpNum, pSC->WMISCP.cChannel, pTileQPInfo->bUseDC);
+                if(pSCAlpha != NULL && (pSCAlpha->m_param.uQPMode & 2) != 0) // not LP uniform
+                    transcodeQuantizersAlpha(pContext->m_pIODC, pTileQPInfo->lpIndex, pTileQPInfo->lpNumAlpha, iAlphaPos, pTileQPInfo->bUseDCAlpha);
+                if(pSC->WMISCP.sbSubband != SB_NO_HIGHPASS){
+                    if((pSC->m_param.uQPMode & 4) != 0) // not HP uniform
+                        transcodeQuantizers(pContext->m_pIODC, pTileQPInfo->hpIndex, pTileQPInfo->hpMode, pTileQPInfo->hpNum, pSC->WMISCP.cChannel, pTileQPInfo->bUseLP);
+                    if(pSCAlpha != NULL && (pSCAlpha->m_param.uQPMode & 4) != 0) // not HP uniform
+                        transcodeQuantizersAlpha(pContext->m_pIODC, pTileQPInfo->hpIndex, pTileQPInfo->hpNumAlpha, iAlphaPos, pTileQPInfo->bUseLPAlpha);
+                }
+            }
+        }
+        else{
+            if(pSC->WMISCP.sbSubband != SB_DC_ONLY){
+                writePacketHeader(pContext->m_pIOLP, 2, pID);
+                if((pSC->m_param.uQPMode & 2) != 0) // not LP uniform
+                    transcodeQuantizers(pContext->m_pIOLP, pTileQPInfo->lpIndex, pTileQPInfo->lpMode, pTileQPInfo->lpNum, pSC->WMISCP.cChannel, pTileQPInfo->bUseDC);
+                if(pSCAlpha != NULL && (pSCAlpha->m_param.uQPMode & 2) != 0) // not LP uniform
+                    transcodeQuantizersAlpha(pContext->m_pIOLP, pTileQPInfo->lpIndex, pTileQPInfo->lpNumAlpha, iAlphaPos, pTileQPInfo->bUseDCAlpha);
+
+                if(pSC->WMISCP.sbSubband != SB_NO_HIGHPASS){
+                    writePacketHeader(pContext->m_pIOAC, 3, pID);
+                    if((pSC->m_param.uQPMode & 4) != 0) // not HP uniform
+                        transcodeQuantizers(pContext->m_pIOAC, pTileQPInfo->hpIndex, pTileQPInfo->hpMode, pTileQPInfo->hpNum, pSC->WMISCP.cChannel, pTileQPInfo->bUseLP);
+                    if(pSCAlpha != NULL && (pSCAlpha->m_param.uQPMode & 4) != 0) // not HP uniform
+                        transcodeQuantizersAlpha(pContext->m_pIOAC, pTileQPInfo->hpIndex, pTileQPInfo->hpNumAlpha, iAlphaPos, pTileQPInfo->bUseLPAlpha);
+
+                    if(pSC->WMISCP.sbSubband != SB_NO_FLEXBITS){
+                        writePacketHeader(pContext->m_pIOFL, 4, pID);
+                        if (pSC->m_param.bTrimFlexbitsFlag)
+                            putBit16(pContext->m_pIOFL, pContext->m_iTrimFlexBits, 4);
+                    }
+                }
+            }
+        }
+        pTile->cBitsLP = (pTileQPInfo->bUseDC ? 0 : dquantBits(pTileQPInfo->lpNum));
+        pTile->cBitsHP = (pTileQPInfo->bUseLP ? 0 : dquantBits(pTileQPInfo->hpNum));
+        if(pSCAlpha != NULL){
+            pTile = pSCAlpha->pTile + pSC->cTileColumn;
+            pTile->cBitsLP = (pTileQPInfo->bUseDCAlpha ? 0 : dquantBits(pTileQPInfo->lpNumAlpha));
+            pTile->cBitsHP = (pTileQPInfo->bUseLPAlpha ? 0 : dquantBits(pTileQPInfo->hpNumAlpha));
+        }
+    }
+}
+
+Void transformDCBlock(PixelI * pOrg, PixelI * pDst, ORIENTATION oOrientation)
+{
+    size_t i;
+
+    if(bFlipV[oOrientation])
+        for(i = 0; i < 16; i += 4)
+            pOrg[i + 1] = -pOrg[i + 1], pOrg[i + 3] = -pOrg[i + 3];
+
+    if(bFlipH[oOrientation])
+        for(i = 0; i < 4; i ++)
+            pOrg[i + 4] = -pOrg[i + 4], pOrg[i + 12] = -pOrg[i + 12];
+
+    if(oOrientation < O_RCW)
+        memcpy(pDst, pOrg, 16 * sizeof(PixelI));
+    else
+        for(i = 0; i < 16; i ++)
+            pDst[i] = pOrg[(i >> 2) + ((i & 3) << 2)];
+}
+
+Void transformDCBlock422(PixelI * pOrg, PixelI * pDst, ORIENTATION oOrientation)
+{
+    assert(oOrientation < O_RCW);
+
+    if(bFlipV[oOrientation])
+        pOrg[1] = -pOrg[1], pOrg[3] = -pOrg[3], pOrg[4] = -pOrg[4], pOrg[5] = -pOrg[5], pOrg[7] = -pOrg[7];
+
+    if(bFlipH[oOrientation])
+        pOrg[2] = -pOrg[2], pOrg[3] = -pOrg[3], pOrg[6] = -pOrg[6], pOrg[7] = -pOrg[7];
+
+    if(bFlipV[oOrientation])
+        pDst[0] = pOrg[0], pDst[1] = pOrg[5], pDst[2] = pOrg[6], pDst[3] = pOrg[7], pDst[4] = pOrg[4], pDst[5] = pOrg[1], pDst[6] = pOrg[2], pDst[7] = pOrg[3];
+    else
+        memcpy(pDst, pOrg, 8 * sizeof(PixelI));
+}
+
+Void transformDCBlock420(PixelI * pOrg, PixelI * pDst, ORIENTATION oOrientation)
+{
+    if(bFlipV[oOrientation])
+        pOrg[1] = -pOrg[1], pOrg[3] = -pOrg[3];
+
+    if(bFlipH[oOrientation])
+        pOrg[2] = -pOrg[2], pOrg[3] = -pOrg[3];
+
+    pDst[0] = pOrg[0], pDst[3] = pOrg[3];
+    if(oOrientation < O_RCW)
+        pDst[1] = pOrg[1], pDst[2] = pOrg[2];
+    else
+        pDst[1] = pOrg[2], pDst[2] = pOrg[1];
+}
+
+Void transformACBlocks(PixelI * pOrg, PixelI * pDst, ORIENTATION oOrientation)
+{
+    PixelI * pO, * pD;
+    const Int * pT = dctIndex[0];
+    size_t i, j, k;
+
+    for(j = 0, pO = pOrg; j < 16; j ++, pO += 16){
+        if(bFlipV[oOrientation])
+            for(i = 0; i < 16; i += 4)
+                pO[pT[i + 1]] = -pO[pT[i + 1]], pO[pT[i + 3]] = -pO[pT[i + 3]];
+        
+        if(bFlipH[oOrientation])
+            for(i = 0; i < 4; i ++)
+                pO[pT[i + 4]] = -pO[pT[i + 4]], pO[pT[i + 12]] = -pO[pT[i + 12]];
+    }
+
+    for(j = 0; j < 4; j ++)
+        for(i = 0; i < 4; i ++){
+            size_t ii = (bFlipV[oOrientation] ? 3 - i : i);
+            size_t jj = (bFlipH[oOrientation] ? 3 - j : j);
+
+            if(oOrientation < O_RCW)
+                memcpy(pDst + (jj * 4 + ii) * 16, pOrg + (j * 4 + i) * 16, 16 * sizeof(PixelI));
+            else{
+                pO = pOrg + (j * 4 + i) * 16;
+                pD = pDst + (ii * 4 + jj) * 16;
+                for(k = 1; k < 16; k ++)
+                    pD[pT[k]] = pO[pT[(k >> 2) + ((k & 3) << 2)]];
+            }
+        }
+}
+
+Void transformACBlocks422(PixelI * pOrg, PixelI * pDst, ORIENTATION oOrientation)
+{
+    PixelI * pO;
+    const Int * pT = dctIndex[0];
+    size_t i, j;
+
+    assert(oOrientation < O_RCW);
+
+    for(j = 0, pO = pOrg; j < 8; j ++, pO += 16){
+        if(bFlipV[oOrientation])
+            for(i = 0; i < 16; i += 4)
+                pO[pT[i + 1]] = -pO[pT[i + 1]], pO[pT[i + 3]] = -pO[pT[i + 3]];
+        
+        if(bFlipH[oOrientation])
+            for(i = 0; i < 4; i ++)
+                pO[pT[i + 4]] = -pO[pT[i + 4]], pO[pT[i + 12]] = -pO[pT[i + 12]];
+    }
+
+    for(j = 0; j < 2; j ++)
+        for(i = 0; i < 4; i ++){
+            size_t ii = (bFlipV[oOrientation] ? 3 - i : i);
+            size_t jj = (bFlipH[oOrientation] ? 1 - j : j);
+
+            memcpy(pDst + (jj * 4 + ii) * 16, pOrg + (j * 4 + i) * 16, 16 * sizeof(PixelI));
+        }
+}
+
+Void transformACBlocks420(PixelI * pOrg, PixelI * pDst, ORIENTATION oOrientation)
+{
+    PixelI * pO, * pD;
+    const Int * pT = dctIndex[0];
+    size_t i, j, k;
+
+    for(j = 0, pO = pOrg; j < 4; j ++, pO += 16){
+        if(bFlipV[oOrientation])
+            for(i = 0; i < 16; i += 4)
+                pO[pT[i + 1]] = -pO[pT[i + 1]], pO[pT[i + 3]] = -pO[pT[i + 3]];
+        
+        if(bFlipH[oOrientation])
+            for(i = 0; i < 4; i ++)
+                pO[pT[i + 4]] = -pO[pT[i + 4]], pO[pT[i + 12]] = -pO[pT[i + 12]];
+    }
+
+    for(j = 0; j < 2; j ++)
+        for(i = 0; i < 2; i ++){
+            size_t ii = (bFlipV[oOrientation] ? 1 - i : i);
+            size_t jj = (bFlipH[oOrientation] ? 1 - j : j);
+
+            if(oOrientation < O_RCW)
+                memcpy(pDst + (jj * 2 + ii) * 16, pOrg + (j * 2 + i) * 16, 16 * sizeof(PixelI));
+            else{
+                pO = pOrg + (j * 2 + i) * 16;
+                pD = pDst + (ii * 2 + jj) * 16;
+                for(k = 1; k < 16; k ++)
+                    pD[pT[k]] = pO[pT[(k >> 2) + ((k & 3) << 2)]];
+            }
+        }
+}
+
+Int getROI(CWMImageInfo * pII, CCoreParameters * pCore, CWMIStrCodecParam * pSCP, CWMTranscodingParam * pParam)
+{
+    const ORIENTATION oO = pParam->oOrientation;
+    size_t iLeft, iTop, cWidth, cHeight, i, j;
+    size_t mbLeft, mbRight, mbTop, mbBottom;
+    size_t * iTile = (size_t *)malloc(MAX_TILES * sizeof(size_t));
+
+    if(iTile == NULL)
+        return ICERR_ERROR;
+    
+    if(pParam->cLeftX + pParam->cWidth > pII->cWidth || pParam->cTopY + pParam->cHeight > pII->cHeight) // invalid region
+        return ICERR_ERROR;
+
+    cWidth = pParam->cWidth, cHeight = pParam->cHeight;
+    iLeft = pParam->cLeftX + pCore->cExtraPixelsLeft, iTop = pParam->cTopY + pCore->cExtraPixelsTop;
+    if(pSCP->olOverlap != OL_NONE && pParam->bIgnoreOverlap == FALSE){ // include pixels borrowed
+        size_t cBlurred = (pSCP->olOverlap == OL_TWO ? 10 : 2);
+
+        if(iLeft > cBlurred)
+            iLeft -= cBlurred, cWidth += cBlurred;
+        else
+            cWidth += iLeft, iLeft = 0;
+        if(iTop > cBlurred)
+            iTop -= cBlurred, cHeight += cBlurred;
+        else
+            cHeight += iTop, iTop = 0;
+        cWidth += cBlurred, cHeight += cBlurred;
+        if(iLeft + cWidth > pII->cWidth + pCore->cExtraPixelsLeft + pCore->cExtraPixelsRight)
+            cWidth = pII->cWidth  + pCore->cExtraPixelsLeft + pCore->cExtraPixelsRight - iLeft;
+        if(iTop + cHeight > pII->cHeight + pCore->cExtraPixelsTop + pCore->cExtraPixelsBottom)
+            cHeight = pII->cHeight + pCore->cExtraPixelsTop + pCore->cExtraPixelsBottom - iTop;
+    }
+
+    mbTop = (iTop >> 4), mbLeft = (iLeft >> 4);
+    mbBottom = (iTop + cHeight + 15) >> 4, mbRight = (iLeft + cWidth + 15) >> 4;
+    pCore->cExtraPixelsLeft += pParam->cLeftX - (mbLeft << 4);
+    pCore->cExtraPixelsRight = ((mbRight - mbLeft) << 4) - pParam->cWidth - pCore->cExtraPixelsLeft;
+    pCore->cExtraPixelsTop += pParam->cTopY - (mbTop << 4);
+    pCore->cExtraPixelsBottom = ((mbBottom - mbTop) << 4) - pParam->cHeight - pCore->cExtraPixelsTop;
+
+    pII->cWidth = ((mbRight - mbLeft) << 4) - pCore->cExtraPixelsLeft - pCore->cExtraPixelsRight;
+    pII->cHeight = ((mbBottom - mbTop) << 4) - pCore->cExtraPixelsTop - pCore->cExtraPixelsBottom;
+    pParam->cLeftX = iLeft, pParam->cTopY = iTop;
+    pParam->cWidth = cWidth, pParam->cHeight = cHeight;
+
+    // extra pixels in transformed space
+#define SWAP(a, b) i = a, a = b, b = i
+    if(oO == O_FLIPH || oO == O_FLIPVH || oO == O_RCW_FLIPV || oO == O_RCW_FLIPVH)
+        SWAP(pCore->cExtraPixelsLeft, pCore->cExtraPixelsRight);
+    if(oO == O_FLIPV || oO == O_FLIPVH || oO == O_RCW || oO == O_RCW_FLIPV)
+        SWAP(pCore->cExtraPixelsTop, pCore->cExtraPixelsBottom);
+    if(oO >= O_RCW){
+        SWAP(pCore->cExtraPixelsLeft, pCore->cExtraPixelsTop);
+        SWAP(pCore->cExtraPixelsRight, pCore->cExtraPixelsBottom);
+    }
+
+    // adjust tiling
+    for(i = 0, j = 0, iTile[0] = 0; i <= (size_t)pSCP->cNumOfSliceMinus1V; i ++)
+        if((size_t)pSCP->uiTileX[i] >= mbLeft && (size_t)pSCP->uiTileX[i] < mbRight){
+            if(j >= MAX_TILES)
+                j = MAX_TILES - 1;
+            iTile[j] = (size_t)pSCP->uiTileX[i] - mbLeft, j ++;
+        }
+    if(iTile[0] == 0)
+        for(i = 0, pSCP->cNumOfSliceMinus1V = (j == 0 ? 0 : (U32)(j - 1)); i < j; i ++)
+            pSCP->uiTileX[i] = (U32)iTile[i];
+    else
+        for(i = 1, pSCP->uiTileX[0] = 0, pSCP->cNumOfSliceMinus1V = (U32)j; i <= j; i ++)
+            pSCP->uiTileX[i] = (U32)iTile[i - 1];
+    if(oO == O_FLIPH || oO == O_FLIPVH || oO == O_RCW_FLIPV || oO == O_RCW_FLIPVH){ // reverse order
+        for(i = 0; i <= (size_t)pSCP->cNumOfSliceMinus1V; i ++)
+            iTile[i] = mbRight - mbLeft - (size_t)pSCP->uiTileX[i];
+        for(i = 1, pSCP->uiTileX[0] = 0; i <= (size_t)pSCP->cNumOfSliceMinus1V; i ++)
+            pSCP->uiTileX[i] = (U32)(iTile[(size_t)pSCP->cNumOfSliceMinus1V - i + 1]);
+    }
+    for(i = 0, j = 0, iTile[0] = 0; i <= (size_t)pSCP->cNumOfSliceMinus1H; i ++)
+        if(pSCP->uiTileY[i] >= mbTop && pSCP->uiTileY[i] < mbBottom){
+            if(j >= MAX_TILES)
+                j = MAX_TILES - 1;
+            iTile[j] = (size_t)pSCP->uiTileY[i] - mbTop, j ++;
+        }
+    if(iTile[0] == 0)
+        for(i = 0, pSCP->cNumOfSliceMinus1H = (j == 0 ? 0 : (U32)(j - 1)); i < j; i ++)
+            pSCP->uiTileY[i] = (U32)iTile[i];
+    else
+        for(i = 1, pSCP->uiTileY[0] = 0, pSCP->cNumOfSliceMinus1H = (U32)j; i <= j; i ++)
+            pSCP->uiTileY[i] = (U32)iTile[i - 1];
+    if(oO == O_FLIPV || oO == O_FLIPVH || oO == O_RCW || oO == O_RCW_FLIPV){ // reverse order
+        for(i = 0; i <= (size_t)pSCP->cNumOfSliceMinus1H; i ++)
+            iTile[i] = mbBottom - mbTop - (size_t)pSCP->uiTileY[i];
+        for(i = 1, pSCP->uiTileY[0] = 0; i <= (size_t)pSCP->cNumOfSliceMinus1H; i ++)
+            pSCP->uiTileY[i] = (U32)(iTile[(size_t)pSCP->cNumOfSliceMinus1H - i + 1]);
+    }
+    if(oO >= O_RCW){ // switch X & Y
+        for(i = 0; i <= (size_t)pSCP->cNumOfSliceMinus1V; i ++)
+            iTile[i] = (size_t)pSCP->uiTileX[i];
+        for(i = 0; i <= (size_t)pSCP->cNumOfSliceMinus1H; i ++)
+            pSCP->uiTileX[i] = pSCP->uiTileY[i];
+        for(i = 0; i <= (size_t)pSCP->cNumOfSliceMinus1V; i ++)
+            pSCP->uiTileY[i] = (U32)iTile[i];
+        i = (size_t)pSCP->cNumOfSliceMinus1H, pSCP->cNumOfSliceMinus1H = pSCP->cNumOfSliceMinus1V, pSCP->cNumOfSliceMinus1V = (U32)i;
+    }
+
+    free(iTile);
+
+    return ICERR_OK;
+}
+
+Bool isTileBoundary(U32 * pTilePos, U32 cTiles, U32 cMBs, U32 iPos)
+{
+    U32 i;
+    
+    for(i = 0; i < cTiles; i ++)
+        if(iPos == pTilePos[i] * 16)
+            break;
+
+    return ((i < cTiles || (iPos + 15) / 16 >= cMBs) ? TRUE : FALSE);
+}
+
+Bool isTileExtraction(CWMImageStrCodec * pSC, CWMTranscodingParam * pParam)
+{
+    if(pParam->bIgnoreOverlap == FALSE && pSC->WMISCP.olOverlap == OL_NONE)
+        pParam->bIgnoreOverlap = TRUE;
+
+    if(pParam->bIgnoreOverlap == TRUE && pParam->oOrientation == O_NONE && pParam->bfBitstreamFormat == pSC->WMISCP.bfBitstreamFormat){
+        if(pParam->bfBitstreamFormat == SPATIAL && pParam->sbSubband != pSC->WMISCP.sbSubband)
+            return FALSE;
+
+        return (isTileBoundary(pSC->WMISCP.uiTileX, pSC->WMISCP.cNumOfSliceMinus1V + 1, (U32)pSC->cmbWidth, (U32)(pParam->cLeftX + pSC->m_param.cExtraPixelsLeft)) &&
+            isTileBoundary(pSC->WMISCP.uiTileY, pSC->WMISCP.cNumOfSliceMinus1H + 1, (U32)pSC->cmbHeight, (U32)(pParam->cTopY + pSC->m_param.cExtraPixelsTop)) &&
+            isTileBoundary(pSC->WMISCP.uiTileX, pSC->WMISCP.cNumOfSliceMinus1V + 1, (U32)pSC->cmbWidth, (U32)(pParam->cLeftX + pParam->cWidth + pSC->m_param.cExtraPixelsLeft)) &&
+            isTileBoundary(pSC->WMISCP.uiTileY, pSC->WMISCP.cNumOfSliceMinus1H + 1, (U32)pSC->cmbHeight, (U32)(pParam->cTopY + pParam->cHeight + pSC->m_param.cExtraPixelsTop)));
+    }
+
+    return FALSE;
+}
+
+Int WMPhotoTranscode(struct WMPStream * pStreamIn, struct WMPStream * pStreamOut, CWMTranscodingParam * pParam)
+{
+    PixelI * pMBBuf, MBBufAlpha[256]; // shared buffer, decoder <=> encoder bridge
+    PixelI * pFrameBuf = NULL, * pFrameBufAlpha = NULL;
+    CWMIMBInfo * pMBInfo = NULL, * pMBInfoAlpha = NULL;
+    CWMImageStrCodec * pSCDec, * pSCEnc, * pSC;
+    CWMDecoderParameters aDecoderParam = {0};
+    U8 * pIOHeaderDec, * pIOHeaderEnc;
+    CCodingContext * pContext;
+    CTileQPInfo * pTileQPInfo = NULL;
+    ORIENTATION oO = pParam->oOrientation;
+    size_t iAlphaPos = 0;
+    size_t cUnit;
+    size_t i, j, mbLeft, mbRight, mbTop, mbBottom, mbWidth, mbHeight;
+
+    if(pStreamIn == NULL || pStreamOut == NULL || pParam == NULL)
+        return ICERR_ERROR;
+
+    // initialize decoder
+    if((pSCDec = (CWMImageStrCodec *)malloc(sizeof(CWMImageStrCodec))) == NULL)
+        return ICERR_ERROR;
+    memset(pSCDec, 0, sizeof(CWMImageStrCodec));
+
+    pSCDec->WMISCP.pWStream = pStreamIn;
+    if(ReadWMIHeader(&pSCDec->WMII, &pSCDec->WMISCP, &pSCDec->m_param) != ICERR_OK)
+        return ICERR_ERROR;
+
+    if(pSCDec->WMISCP.cfColorFormat == YUV_422 && oO >= O_RCW)
+        pParam->oOrientation = oO = O_NONE; // Can not rotate 422 in compressed domain!
+
+    pSCDec->cmbWidth = (pSCDec->WMII.cWidth + pSCDec->m_param.cExtraPixelsLeft + pSCDec->m_param.cExtraPixelsRight + 15) / 16;
+    pSCDec->cmbHeight = (pSCDec->WMII.cHeight + pSCDec->m_param.cExtraPixelsTop + pSCDec->m_param.cExtraPixelsBottom + 15) / 16;
+    pSCDec->m_param.cNumChannels = pSCDec->WMISCP.cChannel;
+    pSCDec->m_Dparam = &aDecoderParam;
+    pSCDec->m_Dparam->bSkipFlexbits = (pSCDec->WMISCP.sbSubband == SB_NO_FLEXBITS);
+    pSCDec->m_param.bTranscode = TRUE;
+
+    pParam->bIgnoreOverlap = isTileExtraction(pSCDec, pParam);
+
+    cUnit = (pSCDec->m_param.cfColorFormat == YUV_420 ? 384 : (pSCDec->m_param.cfColorFormat == YUV_422 ? 512 : 256 * pSCDec->m_param.cNumChannels));
+    if(cUnit > 256 * MAX_CHANNELS)
+        return ICERR_ERROR;
+    pSCDec->p1MBbuffer[0] = pMBBuf = (PixelI *)malloc(cUnit * sizeof(PixelI));
+    if(pMBBuf == NULL)
+        return ICERR_ERROR;
+    pSCDec->p1MBbuffer[1] = pSCDec->p1MBbuffer[0] + 256;
+    for(i = 2; i < pSCDec->m_param.cNumChannels; i ++)
+        pSCDec->p1MBbuffer[i] = pSCDec->p1MBbuffer[i - 1] + (pSCDec->m_param.cfColorFormat == YUV_420 ? 64 : (pSCDec->m_param.cfColorFormat == YUV_422 ? 128 : 256));
+
+    if(pSCDec->m_param.bAlphaChannel){ // alpha channel
+        SimpleBitIO SB = {0};
+
+        iAlphaPos = pSCDec->m_param.cNumChannels;
+        if((pSCDec->m_pNextSC = (CWMImageStrCodec *)malloc(sizeof(CWMImageStrCodec))) == NULL)
+            return ICERR_ERROR;
+        *pSCDec->m_pNextSC = *pSCDec;
+        pSCDec->m_pNextSC->p1MBbuffer[0] = MBBufAlpha;
+        pSCDec->m_pNextSC->WMISCP.cfColorFormat = pSCDec->m_pNextSC->WMII.cfColorFormat = pSCDec->m_pNextSC->m_param.cfColorFormat = Y_ONLY;
+        pSCDec->m_pNextSC->WMISCP.cChannel  = pSCDec->m_pNextSC->m_param.cNumChannels = 1;
+        pSCDec->m_pNextSC->m_bSecondary = TRUE;
+        pSCDec->m_pNextSC->m_pNextSC = pSCDec;
+ 
+        // read plane header of second image plane
+        if(attach_SB(&SB, pSCDec->WMISCP.pWStream) != ICERR_OK)
+            return ICERR_ERROR;
+        ReadImagePlaneHeader(&pSCDec->m_pNextSC->WMII, &pSCDec->m_pNextSC->WMISCP, &pSCDec->m_pNextSC->m_param, &SB);
+        detach_SB(&SB);
+
+        if(StrDecInit(pSCDec->m_pNextSC) != ICERR_OK)
+            return ICERR_ERROR;
+    }
+    else
+        pParam->uAlphaMode = 0;
+
+    pIOHeaderDec = (U8 *)malloc((PACKETLENGTH * 4 - 1) + PACKETLENGTH * 4 + sizeof(BitIOInfo));
+    if(pIOHeaderDec == NULL)
+        return ICERR_ERROR;
+    memset(pIOHeaderDec, 0, (PACKETLENGTH * 4 - 1) + PACKETLENGTH * 4 + sizeof(BitIOInfo));
+    pSCDec->pIOHeader = (BitIOInfo *)((U8 *)ALIGNUP(pIOHeaderDec, PACKETLENGTH * 4) + PACKETLENGTH * 2);
+    
+    if(StrIODecInit(pSCDec) != ICERR_OK)
+        return ICERR_ERROR;
+
+    if(StrDecInit(pSCDec) != ICERR_OK)
+        return ICERR_ERROR;
+
+    if(pSCDec->m_param.bAlphaChannel){ // alpha channel
+        if(StrDecInit(pSCDec->m_pNextSC) != ICERR_OK)
+            return ICERR_ERROR;
+    }
+
+    // initialize encoder
+    if((pSCEnc = (CWMImageStrCodec *)malloc(sizeof(CWMImageStrCodec))) == NULL)
+        return ICERR_ERROR;
+    memset(pSCEnc, 0, sizeof(CWMImageStrCodec));
+
+    pSCEnc->WMII = pSCDec->WMII;
+    pSCEnc->WMISCP = pSCDec->WMISCP;
+    pSCEnc->m_param = pSCDec->m_param;
+    pSCEnc->WMISCP.pWStream = pStreamOut;
+    pSCEnc->WMISCP.bfBitstreamFormat = pParam->bfBitstreamFormat;
+//    pSCEnc->m_param.cfColorFormat = pSCEnc->WMISCP.cfColorFormat = pParam->cfColorFormat;
+    pSCEnc->m_param.cfColorFormat = pSCEnc->WMISCP.cfColorFormat;
+    pSCEnc->m_param.cNumChannels = (pSCEnc->WMISCP.cfColorFormat == Y_ONLY ? 1 : (pSCEnc->WMISCP.cfColorFormat == YUV_444 ? 3 : pSCEnc->WMISCP.cChannel));
+    pSCEnc->m_param.bAlphaChannel = (pParam->uAlphaMode > 0);
+    pSCEnc->m_param.bTranscode = TRUE;
+    if(pParam->sbSubband >= SB_MAX)
+        pParam->sbSubband = SB_ALL;
+    if(pParam->sbSubband > pSCEnc->WMISCP.sbSubband)
+        pSCEnc->WMISCP.sbSubband = pParam->sbSubband;
+    pSCEnc->m_bSecondary = FALSE;
+
+    pIOHeaderEnc = (U8 *)malloc((PACKETLENGTH * 4 - 1) + PACKETLENGTH * 4 + sizeof(BitIOInfo));
+    if(pIOHeaderEnc == NULL)
+        return ICERR_ERROR;
+    memset(pIOHeaderEnc, 0, (PACKETLENGTH * 4 - 1) + PACKETLENGTH * 4 + sizeof(BitIOInfo));
+    pSCEnc->pIOHeader = (BitIOInfo *)((U8 *)ALIGNUP(pIOHeaderEnc, PACKETLENGTH * 4) + PACKETLENGTH * 2);
+    
+    for(i = 0; i < pSCEnc->m_param.cNumChannels; i ++)
+        pSCEnc->pPlane[i] = pSCDec->p1MBbuffer[i];
+    
+    for(i = 1; i < pSCDec->cNumBitIO * (pSCDec->WMISCP.cNumOfSliceMinus1H + 1); i ++){
+        if(pSCDec->pIndexTable[i] == 0 && i + 1 != pSCDec->cNumBitIO * (pSCDec->WMISCP.cNumOfSliceMinus1H + 1)) // empty packet
+            pSCDec->pIndexTable[i] = pSCDec->pIndexTable[i + 1];
+        if(pSCDec->pIndexTable[i] != 0 && pSCDec->pIndexTable[i] < pSCDec->pIndexTable[i - 1]) // out of order bitstream, can not do fast tile extraction!
+            pParam->bIgnoreOverlap = FALSE;
+    }
+
+    if(getROI(&pSCEnc->WMII, &pSCEnc->m_param, &pSCEnc->WMISCP, pParam) != ICERR_OK)
+        return ICERR_ERROR;
+
+    mbLeft = (pParam->cLeftX >> 4);
+    mbRight = ((pParam->cLeftX + pParam->cWidth + 15) >> 4);
+    mbTop = (pParam->cTopY >> 4);
+    mbBottom = ((pParam->cTopY + pParam->cHeight + 15) >> 4);
+
+    if(pSCDec->WMISCP.uiTileX[pSCDec->WMISCP.cNumOfSliceMinus1V] >= mbLeft && pSCDec->WMISCP.uiTileX[pSCDec->WMISCP.cNumOfSliceMinus1V] <= mbRight &&
+        pSCDec->WMISCP.uiTileY[pSCDec->WMISCP.cNumOfSliceMinus1H] >= mbTop && pSCDec->WMISCP.uiTileY[pSCDec->WMISCP.cNumOfSliceMinus1H] <= mbBottom)
+        pParam->bIgnoreOverlap = FALSE;
+
+    pSCEnc->bTileExtraction = pParam->bIgnoreOverlap;
+
+    mbWidth = pSCEnc->cmbWidth = mbRight - mbLeft;
+    mbHeight = pSCEnc->cmbHeight = mbBottom - mbTop;
+    if(oO >= O_RCW){
+        SWAP(pSCEnc->WMII.cWidth, pSCEnc->WMII.cHeight);
+        SWAP(pSCEnc->cmbWidth, pSCEnc->cmbHeight);
+    }
+
+    if(oO != O_NONE){
+        pFrameBuf = (PixelI *)malloc(pSCEnc->cmbWidth * pSCEnc->cmbHeight * cUnit * sizeof(PixelI));
+        if(pFrameBuf == NULL || (pSCEnc->cmbWidth * pSCEnc->cmbHeight * cUnit * sizeof(PixelI) < pSCEnc->cmbWidth * pSCEnc->cmbHeight * cUnit))
+            return ICERR_ERROR;
+        pMBInfo = (CWMIMBInfo *)malloc(pSCEnc->cmbWidth * pSCEnc->cmbHeight * sizeof(CWMIMBInfo));
+        if(pMBInfo == NULL || (pSCEnc->cmbWidth * pSCEnc->cmbHeight * sizeof(CWMIMBInfo) < pSCEnc->cmbWidth * pSCEnc->cmbHeight))
+            return ICERR_ERROR;
+        if(pParam->uAlphaMode > 0){ // alpha channel
+            pFrameBufAlpha = (PixelI *)malloc(pSCEnc->cmbWidth * pSCEnc->cmbHeight * 256 * sizeof(PixelI));
+            if(pFrameBufAlpha == NULL || (pSCEnc->cmbWidth * pSCEnc->cmbHeight * 256 * sizeof(PixelI) < pSCEnc->cmbWidth * pSCEnc->cmbHeight * 256))
+                return ICERR_ERROR;
+            pMBInfoAlpha = (CWMIMBInfo *)malloc(pSCEnc->cmbWidth * pSCEnc->cmbHeight * sizeof(CWMIMBInfo));
+            if(pMBInfoAlpha == NULL || (pSCEnc->cmbWidth * pSCEnc->cmbHeight * sizeof(CWMIMBInfo) < pSCEnc->cmbWidth * pSCEnc->cmbHeight))
+                return ICERR_ERROR;
+        }
+    }
+
+    if(oO < O_RCW && pSCEnc->WMII.oOrientation < O_RCW)
+        pSCEnc->WMII.oOrientation ^= oO;
+    else if(oO >= O_RCW && pSCEnc->WMII.oOrientation >= O_RCW){
+        pSCEnc->WMII.oOrientation ^= oO;
+        pSCEnc->WMII.oOrientation = (pSCEnc->WMII.oOrientation & 1) * 2 + (pSCEnc->WMII.oOrientation >> 1);
+    }
+    else if(oO >= O_RCW && pSCEnc->WMII.oOrientation < O_RCW)
+        pSCEnc->WMII.oOrientation = oO ^ ((pSCEnc->WMII.oOrientation & 1) * 2 + (pSCEnc->WMII.oOrientation >> 1));
+    else
+        pSCEnc->WMII.oOrientation ^= ((oO & 1) * 2 + (oO >> 1));
+    
+//    pSCEnc->WMISCP.nExpBias += 128;
+
+    if(pParam->bIgnoreOverlap == TRUE){
+        attachISWrite(pSCEnc->pIOHeader, pSCEnc->WMISCP.pWStream);
+        pSCEnc->pTile = pSCDec->pTile;
+        if(pSCEnc->WMISCP.cNumOfSliceMinus1H + pSCEnc->WMISCP.cNumOfSliceMinus1V == 0 && pSCEnc->WMISCP.bfBitstreamFormat == SPATIAL)
+            pSCEnc->m_param.bIndexTable = FALSE;
+        WriteWMIHeader(pSCEnc);
+    }
+    else{
+        pTileQPInfo = (CTileQPInfo *)malloc((oO == O_NONE ? 1 : (pSCEnc->WMISCP.cNumOfSliceMinus1H + 1) * (pSCEnc->WMISCP.cNumOfSliceMinus1V + 1)) * sizeof( CTileQPInfo));
+        if(pTileQPInfo == NULL || ((oO == O_NONE ? 1 : (pSCEnc->WMISCP.cNumOfSliceMinus1H + 1) * (pSCEnc->WMISCP.cNumOfSliceMinus1V + 1)) * sizeof( CTileQPInfo) < (oO == O_NONE ? 1 : (pSCEnc->WMISCP.cNumOfSliceMinus1H + 1) * (pSCEnc->WMISCP.cNumOfSliceMinus1V + 1))))
+            return ICERR_ERROR;
+        
+        if(StrEncInit(pSCEnc) != ICERR_OK)
+            return ICERR_ERROR;
+    }
+
+    if(pParam->uAlphaMode > 0){ // alpha channel
+//        pSCEnc->WMISCP.nExpBias -= 128;
+        if((pSCEnc->m_pNextSC = (CWMImageStrCodec *)malloc(sizeof(CWMImageStrCodec))) == NULL)
+            return ICERR_ERROR;
+        *pSCEnc->m_pNextSC = *pSCEnc;
+        pSCEnc->m_pNextSC->pPlane[0] = pSCDec->m_pNextSC->p1MBbuffer[0];
+        pSCEnc->m_pNextSC->WMISCP.cfColorFormat = pSCEnc->m_pNextSC->WMII.cfColorFormat = pSCEnc->m_pNextSC->m_param.cfColorFormat = Y_ONLY;
+        pSCEnc->m_pNextSC->WMISCP.cChannel  = pSCEnc->m_pNextSC->m_param.cNumChannels = 1;
+        pSCEnc->m_pNextSC->m_bSecondary = TRUE;
+        pSCEnc->m_pNextSC->m_pNextSC = pSCEnc;
+        pSCEnc->m_pNextSC->m_param = pSCDec->m_pNextSC->m_param;
+        pSCEnc->m_param.bAlphaChannel = TRUE;
+
+        if(pParam->bIgnoreOverlap == TRUE)
+            pSCEnc->m_pNextSC->pTile = pSCDec->m_pNextSC->pTile;
+        else if(StrEncInit(pSCEnc->m_pNextSC) != ICERR_OK)
+                return ICERR_ERROR;
+
+        WriteImagePlaneHeader(pSCEnc->m_pNextSC);
+    }
+
+    if(pParam->bIgnoreOverlap == TRUE){
+        SUBBAND sbEnc = pSCEnc->WMISCP.sbSubband, sbDec = pSCDec->WMISCP.sbSubband;
+        size_t cfEnc = ((pSCEnc->WMISCP.bfBitstreamFormat == SPATIAL || sbEnc == SB_DC_ONLY) ? 1 : (sbEnc == SB_NO_HIGHPASS ? 2 : (sbEnc == SB_NO_FLEXBITS ? 3 : 4)));
+        size_t cfDec = ((pSCDec->WMISCP.bfBitstreamFormat == SPATIAL || sbDec == SB_DC_ONLY) ? 1 : (sbDec == SB_NO_HIGHPASS ? 2 : (sbDec == SB_NO_FLEXBITS ? 3 : 4)));
+        size_t k, l = 0;
+
+        pSCEnc->pIndexTable = (size_t *)malloc(sizeof(size_t) * (pSCEnc->WMISCP.cNumOfSliceMinus1H + 1) * (pSCEnc->WMISCP.cNumOfSliceMinus1V + 1) * cfEnc);
+
+        if(pSCEnc->pIndexTable == NULL || cfEnc > cfDec)
+            return ICERR_ERROR;
+
+        pSCEnc->cNumBitIO = cfEnc * (pSCEnc->WMISCP.cNumOfSliceMinus1V + 1);
+        
+        for(j = 0; j <= pSCDec->WMISCP.cNumOfSliceMinus1H; j ++){
+            for(i = 0; i <= pSCDec->WMISCP.cNumOfSliceMinus1V; i ++)
+                if(pSCDec->WMISCP.uiTileX[i] >= mbLeft && pSCDec->WMISCP.uiTileX[i] < mbRight && 
+                    pSCDec->WMISCP.uiTileY[j] >= mbTop && pSCDec->WMISCP.uiTileY[j] < mbBottom){
+                        for(k = 0; k < cfEnc; k ++, l ++)
+                            pSCEnc->pIndexTable[l] = pSCDec->pIndexTable[(j * (pSCDec->WMISCP.cNumOfSliceMinus1V + 1) + i) * cfDec + k + 1] - pSCDec->pIndexTable[(j * (pSCDec->WMISCP.cNumOfSliceMinus1V + 1) + i) * cfDec + k];
+                }
+        }
+
+        if(pSCEnc->WMISCP.cNumOfSliceMinus1H + pSCEnc->WMISCP.cNumOfSliceMinus1V == 0 && pSCEnc->WMISCP.bfBitstreamFormat == SPATIAL){
+            pSCEnc->m_param.bIndexTable = FALSE;
+            pSCEnc->cNumBitIO = 0;
+            writeIndexTableNull(pSCEnc);
+        }
+        else
+            writeIndexTable(pSCEnc);
+                
+        detachISWrite(pSCEnc, pSCEnc->pIOHeader);
+
+        for(j = l = 0; j <= pSCDec->WMISCP.cNumOfSliceMinus1H; j ++){
+            for(i = 0; i <= pSCDec->WMISCP.cNumOfSliceMinus1V; i ++)
+                if(pSCDec->WMISCP.uiTileX[i] >= mbLeft && pSCDec->WMISCP.uiTileX[i] < mbRight && 
+                    pSCDec->WMISCP.uiTileY[j] >= mbTop && pSCDec->WMISCP.uiTileY[j] < mbBottom){
+                        for(k = 0; k < cfEnc; k ++){
+                            pSCDec->WMISCP.pWStream->SetPos(pSCDec->WMISCP.pWStream, pSCDec->pIndexTable[(j * (pSCDec->WMISCP.cNumOfSliceMinus1V + 1) + i) * cfDec + k] + pSCDec->cHeaderSize);
+                            copyTo(pSCDec->WMISCP.pWStream, pSCEnc->WMISCP.pWStream, pSCEnc->pIndexTable[l++]);
+                        }
+                }
+        }
+
+        free(pSCEnc->pIndexTable);
+    }
+    else
+        writeIndexTableNull(pSCEnc);
+
+    for(pSCDec->cRow = 0; pSCDec->cRow < mbBottom && pParam->bIgnoreOverlap == FALSE; pSCDec->cRow ++){
+        for(pSCDec->cColumn = 0; pSCDec->cColumn < pSCDec->cmbWidth; pSCDec->cColumn ++){
+            Int cRow = (Int)pSCDec->cRow, cColumn = (Int)pSCDec->cColumn;
+            CWMITile * pTile;
+            
+            memset(pMBBuf, 0, sizeof(PixelI) * cUnit);
+            if(pSCDec->m_param.bAlphaChannel){ // alpha channel
+                memset(pSCDec->m_pNextSC->p1MBbuffer[0], 0, sizeof(PixelI) * 256);
+                pSCDec->m_pNextSC->cRow = pSCDec->cRow;
+                pSCDec->m_pNextSC->cColumn = pSCDec->cColumn;
+            }
+
+            // decode
+            pSC = pSCDec;
+            for(i = (pSCDec->m_param.bAlphaChannel ? 2 : 1); i > 0; i --){
+                getTilePos(pSCDec, cColumn, cRow);
+                if(i == 2){
+                    pSCDec->m_pNextSC->cTileColumn = pSCDec->cTileColumn;
+                    pSCDec->m_pNextSC->cTileRow = pSCDec->cTileRow;
+                }
+                
+                if(readPackets(pSCDec) != ICERR_OK)
+                    return ICERR_ERROR;
+
+                pContext = &pSCDec->m_pCodingContext[pSCDec->cTileColumn];
+                
+                if(DecodeMacroblockDC(pSCDec, pContext, cColumn, cRow) != ICERR_OK)
+                    return ICERR_ERROR;
+                
+                if(pSCDec->cSB > 1)
+                    if(DecodeMacroblockLowpass(pSCDec, pContext, cColumn, cRow) != ICERR_OK)
+                        return ICERR_ERROR;
+
+                predDCACDec(pSCDec);
+
+                if(pSCDec->cSB > 2)
+                    if(DecodeMacroblockHighpass(pSCDec, pContext, cColumn, cRow) != ICERR_OK)
+                        return ICERR_ERROR;
+
+                predACDec(pSCDec);
+                
+                updatePredInfo(pSCDec, &pSCDec->MBInfo, cColumn, pSCDec->WMISCP.cfColorFormat);
+
+                pSCDec = pSCDec->m_pNextSC;
+            }
+            pSCDec = pSC;
+
+            if(pSCDec->cRow >= mbTop && pSCDec->cColumn >= mbLeft && pSCDec->cColumn < mbRight){
+                cRow = (Int)(pSCDec->cRow - mbTop);
+                if(bFlipV[oO])
+                    cRow = (Int)mbHeight - cRow - 1;
+                cColumn = (Int)(pSCDec->cColumn - mbLeft);
+                if(bFlipH[oO])
+                    cColumn = (Int)mbWidth - cColumn - 1;
+
+                pSCEnc->m_bCtxLeft = pSCEnc->m_bCtxTop = FALSE;
+                for(i = 0; i <= pSCEnc->WMISCP.cNumOfSliceMinus1H; i ++)
+                    if(pSCEnc->WMISCP.uiTileY[i] == (U32)(oO < O_RCW ? cRow : cColumn)){
+                        pSCEnc->cTileRow = i;
+                        pSCEnc->m_bCtxTop = TRUE;
+                        break;
+                    }
+                for(i = 0; i <= pSCEnc->WMISCP.cNumOfSliceMinus1V; i ++)
+                    if(pSCEnc->WMISCP.uiTileX[i] == (U32)(oO < O_RCW ? cColumn : cRow)){
+                        pSCEnc->cTileColumn = i;
+                        pSCEnc->m_bCtxLeft = TRUE;
+                        break;
+                    }
+
+                if(pSCEnc->m_bCtxLeft && pSCEnc->m_bCtxTop){ // a new tile, buffer tile DQuant info
+                    CTileQPInfo * pTmp = pTileQPInfo;
+                    
+                    pTile = pSCDec->pTile + pSCDec->cTileColumn;
+                    
+                    if(oO != O_NONE)
+                        pTmp += pSCEnc->cTileRow * (pSCEnc->WMISCP.cNumOfSliceMinus1V + 1) + pSCEnc->cTileColumn;
+                    
+                    pTmp->dcMode = pTile->cChModeDC;
+                    for(i = 0; i < pSCEnc->WMISCP.cChannel; i ++)
+                        pTmp->dcIndex[i] = pTile->pQuantizerDC[i][0].iIndex;
+                    
+                    if(pSCEnc->WMISCP.sbSubband != SB_DC_ONLY){
+                        pTmp->bUseDC = pTile->bUseDC;
+                        pTmp->lpNum = pTile->cNumQPLP;
+                        if(pTmp->bUseDC == FALSE)
+                            for(j = 0; j < pTmp->lpNum; j ++){
+                                pTmp->lpMode[j] = pTile->cChModeLP[j];
+                                for(i = 0; i < pSCEnc->WMISCP.cChannel; i ++)
+                                    pTmp->lpIndex[j][i] = pTile->pQuantizerLP[i][j].iIndex;
+                            }
+                            
+                            if(pSCEnc->WMISCP.sbSubband != SB_NO_HIGHPASS){
+                                pTmp->bUseLP = pTile->bUseLP;
+                                pTmp->hpNum = pTile->cNumQPHP;
+                                if(pTmp->bUseLP == FALSE)
+                                    for(j = 0; j < pTmp->hpNum; j ++){
+                                        pTmp->hpMode[j] = pTile->cChModeHP[j];
+                                        for(i = 0; i < pSCEnc->WMISCP.cChannel; i ++)
+                                            pTmp->hpIndex[j][i] = pTile->pQuantizerHP[i][j].iIndex;
+                                    }
+                            }
+                    }
+
+                    if(pParam->uAlphaMode > 0){
+                        pTile = pSCDec->m_pNextSC->pTile + pSCDec->cTileColumn;
+
+                        pTmp->dcIndex[iAlphaPos] = pTile->pQuantizerDC[0][0].iIndex;
+
+                        if(pSCEnc->WMISCP.sbSubband != SB_DC_ONLY){
+                            pTmp->bUseDCAlpha = pTile->bUseDC;
+                            pTmp->lpNumAlpha = pTile->cNumQPLP;
+                            if(pTmp->bUseDCAlpha == FALSE)
+                                for(j = 0; j < pTmp->lpNumAlpha; j ++)
+                                    pTmp->lpIndex[j][iAlphaPos] = pTile->pQuantizerLP[0][j].iIndex;
+                            if(pSCEnc->WMISCP.sbSubband != SB_NO_HIGHPASS){
+                                pTmp->bUseLPAlpha = pTile->bUseLP;
+                                pTmp->hpNumAlpha = pTile->cNumQPHP;
+                                if(pTmp->bUseLPAlpha == FALSE)
+                                    for(j = 0; j < pTmp->hpNumAlpha; j ++)
+                                        pTmp->hpIndex[j][iAlphaPos] = pTile->pQuantizerHP[0][j].iIndex;
+                            }
+                        }
+                    }
+                }
+
+                if(oO == O_NONE){
+                    // encode
+                    pSCEnc->cColumn = pSCDec->cColumn - mbLeft + 1;
+                    pSCEnc->cRow = pSCDec->cRow + 1 - mbTop;
+                    pSCEnc->MBInfo = pSCDec->MBInfo;
+
+                    getTilePos(pSCEnc, cColumn, cRow);
+                    
+                    if(pSCEnc->m_bCtxLeft && pSCEnc->m_bCtxTop)
+                        transcodeTileHeader(pSCEnc, pTileQPInfo);
+
+                    encodeMB(pSCEnc, cColumn, cRow);
+                    if(pParam->uAlphaMode > 0){
+                        pSCEnc->m_pNextSC->cColumn = pSCDec->cColumn - mbLeft + 1;
+                        pSCEnc->m_pNextSC->cRow = pSCDec->cRow + 1 - mbTop;
+                        getTilePos(pSCEnc->m_pNextSC, cColumn, cRow);
+                        pSCEnc->m_pNextSC->MBInfo = pSCDec->m_pNextSC->MBInfo;
+                        encodeMB(pSCEnc->m_pNextSC, cColumn, cRow);
+                    }
+                }
+                else{
+                    size_t cOff = (oO < O_RCW ? (size_t)cRow * mbWidth + (size_t)cColumn : (size_t)cRow + mbHeight * (size_t)cColumn);
+
+                    pMBInfo[cOff] = pSCDec->MBInfo;
+
+                    memcpy(&pFrameBuf[cOff * cUnit], pMBBuf, cUnit * sizeof(PixelI));
+
+                    if(pParam->uAlphaMode > 0){
+                        pMBInfoAlpha[cOff] = pSCDec->m_pNextSC->MBInfo;
+                        
+                        memcpy(&pFrameBufAlpha[cOff * 256], MBBufAlpha, 256 * sizeof(PixelI));
+                    }
+                }
+            }
+        }
+
+        advanceOneMBRow(pSCDec);
+
+        if(oO == O_NONE)
+            advanceOneMBRow(pSCEnc);
+    }
+
+    if(oO != O_NONE){
+        for(pSCEnc->cRow = 1; pSCEnc->cRow <= pSCEnc->cmbHeight; pSCEnc->cRow ++){
+            for(pSCEnc->cColumn = 1; pSCEnc->cColumn <= pSCEnc->cmbWidth; pSCEnc->cColumn ++){
+                Int cRow, cColumn;
+                size_t cOff = (pSCEnc->cRow - 1) * pSCEnc->cmbWidth + pSCEnc->cColumn - 1;
+                
+                for(i = 0; i < ((pSCEnc->m_param.cfColorFormat == YUV_420 || pSCEnc->m_param.cfColorFormat == YUV_422) ? 1 : pSCEnc->m_param.cNumChannels); i ++){
+                    transformDCBlock(pMBInfo[cOff].iBlockDC[i], pSCEnc->MBInfo.iBlockDC[i], oO);
+                    transformACBlocks(pFrameBuf + cOff * cUnit + i * 256, pMBBuf + 256 * i, oO);
+                }
+                if(pSCEnc->WMISCP.cfColorFormat == YUV_420)
+                    for(i = 0; i < 2; i ++){
+                        transformDCBlock420(pMBInfo[cOff].iBlockDC[i + 1], pSCEnc->MBInfo.iBlockDC[i + 1], oO);
+                        transformACBlocks420(pFrameBuf + cOff * cUnit + 256 + i * 64, pMBBuf + 256 + i * 64, oO);
+                    }
+                else if(pSCEnc->WMISCP.cfColorFormat == YUV_422)
+                    for(i = 0; i < 2; i ++){
+                        transformDCBlock422(pMBInfo[cOff].iBlockDC[i + 1], pSCEnc->MBInfo.iBlockDC[i + 1], oO);
+                        transformACBlocks422(pFrameBuf + cOff * cUnit + 256 + i * 128, pMBBuf + 256 + i * 128, oO);
+                    }
+
+                    pSCEnc->MBInfo.iQIndexLP = pMBInfo[cOff].iQIndexLP;
+                    pSCEnc->MBInfo.iQIndexHP = pMBInfo[cOff].iQIndexHP;
+
+                cRow = (Int)pSCEnc->cRow - 1;
+                cColumn = (Int)pSCEnc->cColumn - 1;
+                getTilePos(pSCEnc, cColumn, cRow);
+
+                if(pSCEnc->m_bCtxLeft && pSCEnc->m_bCtxTop)
+                    transcodeTileHeader(pSCEnc, pTileQPInfo + pSCEnc->cTileRow * (pSCEnc->WMISCP.cNumOfSliceMinus1V + 1) + pSCEnc->cTileColumn);
+                encodeMB(pSCEnc, cColumn, cRow);
+                
+                if(pParam->uAlphaMode > 0){
+                    pSCEnc->m_pNextSC->cColumn = pSCEnc->cColumn;
+                    pSCEnc->m_pNextSC->cRow = pSCEnc->cRow;
+                    getTilePos(pSCEnc->m_pNextSC, cColumn, cRow);
+                    pSCEnc->m_pNextSC->MBInfo = pSCDec->m_pNextSC->MBInfo;
+
+                    transformDCBlock(pMBInfoAlpha[cOff].iBlockDC[0], pSCEnc->m_pNextSC->MBInfo.iBlockDC[0], oO);
+                    transformACBlocks(pFrameBufAlpha + cOff * 256, MBBufAlpha, oO);
+
+                    pSCEnc->m_pNextSC->MBInfo.iQIndexLP = pMBInfoAlpha[cOff].iQIndexLP;
+                    pSCEnc->m_pNextSC->MBInfo.iQIndexHP = pMBInfoAlpha[cOff].iQIndexHP;
+
+                    encodeMB(pSCEnc->m_pNextSC, cColumn, cRow);
+                }
+            }
+
+            advanceOneMBRow(pSCEnc);
+        }
+    }
+
+    free(pMBBuf);
+    if(oO != O_NONE){
+        free(pFrameBuf);
+        free(pMBInfo);
+        if(pParam->uAlphaMode > 0){ // alpha channel
+            free(pFrameBufAlpha);
+            free(pMBInfoAlpha);
+        }
+    }
+
+    freePredInfo(pSCDec);
+    freeTileInfo(pSCDec);
+    StrIODecTerm(pSCDec);
+    FreeCodingContextDec(pSCDec);
+    if(pSCDec->m_param.bAlphaChannel)
+        free(pSCDec->m_pNextSC);
+    free(pSCDec);
+    free(pIOHeaderDec);
+
+    if(pParam->bIgnoreOverlap == FALSE){
+        freePredInfo(pSCEnc);
+        freeTileInfo(pSCEnc);
+        StrIOEncTerm(pSCEnc);
+        free(pTileQPInfo);
+        FreeCodingContextEnc(pSCEnc);
+    }
+    free(pSCEnc);
+    free(pIOHeaderEnc);
+
+    return ICERR_OK;
+}
diff --git a/Source/LibJXR/image/decode/decode.c b/Source/LibJXR/image/decode/decode.c
new file mode 100644
index 0000000..c52f678
--- /dev/null
+++ b/Source/LibJXR/image/decode/decode.c
@@ -0,0 +1,200 @@
+//*@@@+++@@@@******************************************************************
+//
+// Copyright � Microsoft Corp.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+// � Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// � Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//*@@@---@@@@******************************************************************
+/******************************************************************************
+
+Module Name:
+    decode.c 
+    
+Abstract:    
+    Defines the entry point for the console application.
+
+Author:
+
+Revision History:
+*******************************************************************************/
+#include "strcodec.h"
+#include "decode.h"
+
+#ifdef MEM_TRACE
+#define TRACE_MALLOC    1
+#define TRACE_NEW       0
+#define TRACE_HEAP      0
+#include "memtrace.h"
+#endif
+
+/******************************************************************
+Free Adaptive Huffman Table
+******************************************************************/
+static Void CleanAH(CAdaptiveHuffman **ppAdHuff)
+{
+    CAdaptiveHuffman *pAdHuff;
+    
+    if (NULL != ppAdHuff) {
+        pAdHuff = *ppAdHuff;
+        if (NULL != pAdHuff) {
+            free(pAdHuff);
+        }
+        *ppAdHuff = NULL;
+    }
+}
+
+static Void CleanAHDec(CCodingContext * pSC)
+{
+    Int kk;
+
+    for (kk = 0; kk < NUMVLCTABLES; kk++) {
+        CleanAH(&(pSC->m_pAHexpt[kk]));
+    }
+    CleanAH(&(pSC->m_pAdaptHuffCBPCY));
+    CleanAH(&(pSC->m_pAdaptHuffCBPCY1));
+}
+
+/*************************************************************************
+    Initialize an adaptive huffman table
+*************************************************************************/
+static Int InitializeAH(CAdaptiveHuffman **ppAdHuff, Int iSym)
+{
+    Int iMemStatus = 0;
+
+    CAdaptiveHuffman *pAdHuff = Allocate(iSym, DECODER);
+    if (pAdHuff == NULL) {
+        iMemStatus = -1;    // out of memory
+        goto ErrorExit;
+    }
+
+    //Adapt(pAdHuff, bFixedTables);
+    //InitHuffman(pAdHuff->m_pHuffman);
+    //if (ICERR_OK != initHuff(pAdHuff->m_pHuffman, 1, pAdHuff->m_pTable, NULL)) {
+    //    goto ErrorExit;
+    //}
+    *ppAdHuff = pAdHuff;
+    return ICERR_OK;
+
+ErrorExit:
+    if (pAdHuff) {
+        free(pAdHuff);
+    }
+    *ppAdHuff = NULL;
+    if (-1 == iMemStatus) {
+        printf("Insufficient memory to init decoder.\n");
+    }
+    return ICERR_ERROR;
+}
+
+
+/*************************************************************************
+    Context allocation
+*************************************************************************/
+Int AllocateCodingContextDec(CWMImageStrCodec *pSC, Int iNumContexts)
+{
+    Int i, iCBPSize, k;
+    static const Int aAlphabet[] = {5,4,8,7,7,  12,6,6,12,6,6,7,7,  12,6,6,12,6,6,7,7};
+
+    if (iNumContexts > MAX_TILES || iNumContexts < 1)  // only between 1 and MAX_TILES allowed
+        return ICERR_ERROR;
+
+    if (pSC == NULL)
+        return ICERR_ERROR;
+
+    pSC->m_pCodingContext = malloc (iNumContexts * sizeof (CCodingContext));
+    if (pSC->m_pCodingContext == NULL) {
+        pSC->cNumCodingContext = 0;
+        return ICERR_ERROR;
+    }
+    memset (pSC->m_pCodingContext, 0, iNumContexts * sizeof (CCodingContext));
+
+    pSC->cNumCodingContext = iNumContexts;
+    iCBPSize = (pSC->m_param.cfColorFormat == Y_ONLY || pSC->m_param.cfColorFormat == NCOMPONENT
+        || pSC->m_param.cfColorFormat == CMYK) ? 5 : 9;
+
+    /** allocate / initialize members **/
+    for (i = 0; i < iNumContexts; i++) {
+        CCodingContext *pContext = &(pSC->m_pCodingContext[i]);
+
+        /** allocate adaptive Huffman encoder **/    
+        if (InitializeAH(&pContext->m_pAdaptHuffCBPCY, iCBPSize) != ICERR_OK) {
+            return ICERR_ERROR;
+        }
+        if (InitializeAH(&pContext->m_pAdaptHuffCBPCY1, 5) != ICERR_OK) {
+            return ICERR_ERROR;
+        }
+
+        for(k = 0; k < NUMVLCTABLES; k ++){
+            if (InitializeAH(&pContext->m_pAHexpt[k], aAlphabet[k]) != ICERR_OK) {
+                return ICERR_ERROR;
+            }
+        }
+
+        ResetCodingContextDec(pContext);
+    }
+
+    return ICERR_OK;
+}
+
+/*************************************************************************
+    Context reset on encoder
+*************************************************************************/
+Void ResetCodingContextDec(CCodingContext *pContext)
+{
+    Int k;
+    /** set flags **/
+    pContext->m_pAdaptHuffCBPCY->m_bInitialize = FALSE;
+    pContext->m_pAdaptHuffCBPCY1->m_bInitialize = FALSE;
+    for(k = 0; k < NUMVLCTABLES; k ++)
+        pContext->m_pAHexpt[k]->m_bInitialize = FALSE;
+
+    // reset VLC tables
+    AdaptLowpassDec (pContext);
+    AdaptHighpassDec (pContext);
+
+    // reset zigzag patterns, totals
+    InitZigzagScan(pContext);
+    // reset bit reduction and cbp models
+    ResetCodingContext(pContext);
+}
+
+/*************************************************************************
+    Context deletion
+*************************************************************************/
+Void FreeCodingContextDec(CWMImageStrCodec *pSC)
+{
+    Int iContexts = (Int)(pSC->cNumCodingContext), i, k;
+
+    if (iContexts > 0 && pSC->m_pCodingContext) {
+
+        for (i = 0; i < iContexts; i++) {
+            CCodingContext *pContext = &(pSC->m_pCodingContext[i]);
+            CleanAH (&pContext->m_pAdaptHuffCBPCY);
+            CleanAH (&pContext->m_pAdaptHuffCBPCY1);
+            for (k = 0; k < NUMVLCTABLES; k++)
+                CleanAH (&pContext->m_pAHexpt[k]);
+        }
+        free (pSC->m_pCodingContext);
+    }
+}
+
diff --git a/Source/LibJXR/image/decode/decode.h b/Source/LibJXR/image/decode/decode.h
new file mode 100644
index 0000000..404fe47
--- /dev/null
+++ b/Source/LibJXR/image/decode/decode.h
@@ -0,0 +1,143 @@
+//*@@@+++@@@@******************************************************************
+//
+// Copyright � Microsoft Corp.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+// � Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// � Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//*@@@---@@@@******************************************************************
+
+#ifndef WMI_DECODE_H
+#define WMI_DECODE_H
+
+typedef struct CWMDecoderParameters {
+    /** ROI decode **/
+    Bool bDecodeFullFrame;
+    Bool bDecodeFullWidth;
+
+    /** thumbnail decode **/
+    Bool bSkipFlexbits;
+    size_t cThumbnailScale;    // 1: cThumbnailScale thumbnail, only supports cThumbnailScale = 2^m for now
+    Bool bDecodeHP;
+    Bool bDecodeLP;
+
+    // Region of interest decoding
+    size_t cROILeftX;
+    size_t cROIRightX;
+    size_t cROITopY;
+    size_t cROIBottomY;
+
+    // table lookups for rotation and flip
+    size_t * pOffsetX;
+    size_t * pOffsetY;
+} CWMDecoderParameters;
+
+Void predCBPDec(CWMImageStrCodec *, CCodingContext *);
+Void predDCACDec(CWMImageStrCodec *);
+Void predACDec(CWMImageStrCodec *);
+
+Int dequantizeMacroblock(CWMImageStrCodec *);
+Int invTransformMacroblock(CWMImageStrCodec * pSC);
+Int invTransformMacroblock_alteredOperators_hard(CWMImageStrCodec * pSC);
+
+Int DecodeMacroblockDC(CWMImageStrCodec * pSC, CCodingContext *pContext, Int iMBX, Int iMBY);
+Int DecodeMacroblockLowpass(CWMImageStrCodec * pSC, CCodingContext *pContext, Int iMBX, Int iMBY);
+Int DecodeMacroblockHighpass(CWMImageStrCodec * pSC, CCodingContext *pContext, Int iMBX, Int iMBY);
+
+Int AdaptLowpassDec(struct CCodingContext *);
+Int AdaptHighpassDec(struct CCodingContext *);
+
+Void ResetCodingContextDec(CCodingContext *pContext);
+Void FreeCodingContextDec(struct CWMImageStrCodec *pSC);
+
+/*************************************************************************/
+// Inverse transform functions
+// 2-point post filter for boundaries (only used in 420 UV DC subband)
+Void strPost2(PixelI *, PixelI *);
+
+// 2x2 post filter (only used in 420 UV DC subband)
+Void strPost2x2(PixelI *, PixelI *, PixelI *, PixelI *);
+
+/** 4-point post filter for boundaries **/
+Void strPost4(PixelI *, PixelI *, PixelI *, PixelI *);
+
+/** data allocation in working buffer (first stage) **/
+
+/** Y, 444 U and V **/
+/**  0  1  2  3 **/
+/** 32 33 34 35 **/
+/** 64 65 66 67 **/
+/** 96 97 98 99 **/
+
+/** 420 U and V **/
+/**   0   2   4   6 **/
+/**  64  66  68  70 **/
+/** 128 130 132 134 **/
+/** 192 194 196 198 **/
+
+/** 4x4 inverse DCT for first stage **/
+Void strIDCT4x4FirstStage(PixelI *);
+Void strIDCT4x4Stage1(PixelI*);
+Void strIDCT4x4FirstStage420UV(PixelI *);
+
+/** 4x4 post filter for first stage **/
+Void strPost4x4FirstStage(PixelI *);
+Void strPost4x4Stage1Split(PixelI*, PixelI*, Int, Int, Bool);
+Void strPost4x4Stage1(PixelI*, Int, Int, Bool);
+Void strPost4x4Stage1Split_alternate(PixelI*, PixelI*, Int);
+Void strPost4x4Stage1_alternate(PixelI*, Int);
+//Void strPost4x4Stage1Split_420(PixelI*, PixelI*);
+//Void strPost4x4Stage1_420(PixelI*);
+
+Void strPost4x4FirstStage420UV(PixelI *);
+
+/** data allocation in working buffer (second stage)**/
+
+/** Y, 444 U and V **/
+/**   0   4   8  12 **/
+/** 128 132 136 140 **/
+/** 256 260 264 268 **/
+/** 384 388 392 396 **/
+
+/** 420 U and V **/
+/**   0   8 **/
+/** 256 264 **/
+
+/** 4x4 invesr DCT for second stage **/
+//Void strIDCT4x4SecondStage(PixelI *);
+Void strIDCT4x4Stage2(PixelI*);
+Void strNormalizeDec(PixelI*, Bool);
+Void strDCT2x2dnDec(PixelI *, PixelI *, PixelI *, PixelI *);
+
+/** 4x4 post filter for second stage **/
+Void strPost4x4SecondStage(PixelI *);
+Void strPost4x4Stage2Split(PixelI*, PixelI*);
+Void strPost4x4Stage2Split_alternate(PixelI*, PixelI*);
+
+/** Huffman decode related defines **/
+#define HUFFMAN_DECODE_ROOT_BITS_LOG    3
+#define HUFFMAN_DECODE_ROOT_BITS    (5)   
+
+Int getHuff(const short *pDecodeTable, BitIOInfo* pIO);
+
+#endif // WMI_DECODE_H
+
diff --git a/Source/LibJXR/image/decode/postprocess.c b/Source/LibJXR/image/decode/postprocess.c
new file mode 100644
index 0000000..252d11f
--- /dev/null
+++ b/Source/LibJXR/image/decode/postprocess.c
@@ -0,0 +1,288 @@
+//*@@@+++@@@@******************************************************************
+//
+// Copyright � Microsoft Corp.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+// � Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// � Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//*@@@---@@@@******************************************************************
+
+#include "windowsmediaphoto.h"
+#include "strcodec.h"
+
+Void smoothMB(PixelI * p1, PixelI * p0, PixelI * q0, PixelI * q1)
+{
+    //  p1 p0 | q0 q1
+    PixelI delta = ((((*q0 - *p0) << 2) + (*p1 - *q1)) >> 3);
+    
+    *q0 -= delta;
+    *p0 += delta;
+}
+
+Void smooth(PixelI * p2, PixelI * p1, PixelI * p0, PixelI * q0, PixelI * q1, PixelI * q2)
+{
+    //    p2 p1 p0 | q0 q1 q2
+    PixelI delta = ((((*q0 - *p0) << 2) + (*p1 - *q1)) >> 3);
+
+    *q0 -= delta;
+    *p0 += delta;
+
+    *p1 = (*p1 >> 1) + ((*p0 + *p2) >> 2);
+    *q1 = (*q1 >> 1) + ((*q0 + *q2) >> 2);
+}
+
+Int initPostProc(struct tagPostProcInfo * strPostProcInfo[MAX_CHANNELS][2], size_t mbWidth, size_t iNumChannels)
+{
+    size_t i, j, k, l;
+    Bool b32bit = sizeof(int) == 4;
+    
+    for(j = 0; j < iNumChannels; j ++){
+        for(i = 0; i < 2; i ++){
+            // 2 more are allocated to avoid boundary check
+            if(b32bit) // integer overlow/underflow check for 32-bit system
+                if((((mbWidth + 2) >> 16) * sizeof(struct tagPostProcInfo)) & 0xffff0000)
+                    return ICERR_ERROR;
+            strPostProcInfo[j][i] = (struct tagPostProcInfo *)malloc((mbWidth + 2) * sizeof(struct tagPostProcInfo));
+            assert(strPostProcInfo[j][i] != NULL);
+            if(strPostProcInfo[j][i] == NULL){
+                return ICERR_ERROR;
+            }
+            strPostProcInfo[j][i] ++;
+            
+            // initialize out-of-bound MBs as bumpy (no post at all) to avoid boundary check
+            // left boundary
+            strPostProcInfo[j][i][-1].ucMBTexture = 3;
+            for(l = 0; l < 4; l ++){
+                for(k = 0; k < 4; k ++){
+                    strPostProcInfo[j][i][-1].ucBlockTexture[l][k] = 3;
+                }
+            }
+            // right boundary
+            strPostProcInfo[j][i][mbWidth] = strPostProcInfo[j][i][-1];
+        }
+    }
+
+    return ICERR_OK;
+}
+
+Void termPostProc(struct tagPostProcInfo * strPostProcInfo[MAX_CHANNELS][2], size_t iNumChannels)
+{
+    size_t i, j;
+
+    for(j = 0; j < iNumChannels; j ++){
+        for(i = 0; i < 2; i ++){
+            if(strPostProcInfo[j][i] != NULL){
+                free(strPostProcInfo[j][i] - 1);
+            }
+        }
+    }
+}
+
+Void slideOneMBRow(struct tagPostProcInfo * strPostProcInfo[MAX_CHANNELS][2], size_t iNumChannels, size_t mbWidth, Bool top, Bool bottom)
+{
+    size_t i, j;
+    struct tagPostProcInfo * bar;
+
+    for(i = 0; i < iNumChannels; i ++){
+        // swap previous row and current row
+        bar = strPostProcInfo[i][0];
+        strPostProcInfo[i][0] = strPostProcInfo[i][1];
+        strPostProcInfo[i][1] = bar;
+
+        if(top){ // if top row, previous row is out of boundary
+            for(j = 0; j < mbWidth; j ++){
+                strPostProcInfo[i][0][j] = strPostProcInfo[i][0][-1]; // set as bumpy
+            }
+        }
+        
+        if(bottom){ // if bottom bottom row, set current row of MBs (out of boundary) as bumpy
+            for(j = 0; j < mbWidth; j ++){
+                strPostProcInfo[i][1][j] = strPostProcInfo[i][1][-1]; // set as bumpy
+            }
+        }
+    }
+}
+
+// get DC and texture infomation right before transform
+Void updatePostProcInfo(struct tagPostProcInfo * strPostProcInfo[MAX_CHANNELS][2], PixelI * pMB, size_t mbX, size_t cc)
+{
+    size_t i, j;
+    struct tagPostProcInfo * pMBInfo = strPostProcInfo[cc][1] + mbX;
+
+    // DC of MB
+    pMBInfo->iMBDC = pMB[0];
+
+    // texture of MB
+    pMBInfo->ucMBTexture = 0; // smooth
+    for(i = 16; i < 256; i += 16){
+        if(pMB[i] != 0){
+            pMBInfo->ucMBTexture = 3; // bumpy
+            break;
+        }
+    }
+
+    // DCs of blocks not available yet, will collect after demacroblocking
+
+    // textures of blocks
+    for(j = 0; j < 4; j ++)
+        for(i = 0; i < 4; i ++){
+            PixelI * p = pMB + i * 64 + j * 16;
+            size_t k;
+
+            for(k = 1, pMBInfo->ucBlockTexture[j][i] = 0; k < 16; k ++){
+                if(p[k] != 0){
+                    pMBInfo->ucBlockTexture[j][i] = 3;
+                    break;
+                }
+            }
+        }
+}
+
+// demacroblock critirion: two MBs have same texture other than bumpy and DCs differ less than 1
+#define DMB(a, b) (a->ucMBTexture + b->ucMBTexture == 0) && (abs(a->iMBDC - b->iMBDC) <= threshold)
+
+// demacroblock and get DCs of blocks
+Void postProcMB(struct tagPostProcInfo * strPostProcInfo[MAX_CHANNELS][2], PixelI * p0, PixelI * p1, size_t mbX, size_t cc, Int threshold)
+{
+    /* 4 MBs involved, current MB is d, we have 4 2-pixel boundary segments */
+    /*    |     */
+    /*  a | b   */
+    /* - - + +  */
+    /*  c ! d   */
+    /*    !     */
+    struct tagPostProcInfo * pMBb = strPostProcInfo[cc][0] + mbX, * pMBa = pMBb - 1, * pMBd = strPostProcInfo[cc][1] + mbX, * pMBc = pMBd - 1;
+
+    // demacroblock segment --
+   if(DMB(pMBa, pMBc)){
+        smoothMB(p0 - 256 + 10 * 16, p0 - 256 + 11 * 16, p1 - 256 +  8 * 16, p1 - 256 +  9 * 16);
+        smoothMB(p0 - 256 + 14 * 16, p0 - 256 + 15 * 16, p1 - 256 + 12 * 16, p1 - 256 + 13 * 16);
+    }
+
+    // demacroblock segment ++
+    if(DMB(pMBb, pMBd)){
+        smoothMB(p0 + 2 * 16, p0 + 3 * 16, p1 + 0 * 16, p1 + 1 * 16);
+        smoothMB(p0 + 6 * 16, p0 + 7 * 16, p1 + 4 * 16, p1 + 5 * 16);
+    }
+
+    // demacroblock segment |
+    if(DMB(pMBa, pMBb)){
+        smoothMB(p0 - 256 + 10 * 16, p0 - 256 + 14 * 16, p0 + 2 * 16, p0 + 6 * 16);
+        smoothMB(p0 - 256 + 11 * 16, p0 - 256 + 15 * 16, p0 + 3 * 16, p0 + 7 * 16);
+    }
+
+    // demacroblock segment !
+    if(DMB(pMBc, pMBd)){
+        smoothMB(p1 - 256 + 8 * 16, p1 - 256 + 12 * 16, p1 + 0 * 16, p1 + 4 * 16);
+        smoothMB(p1 - 256 + 9 * 16, p1 - 256 + 13 * 16, p1 + 1 * 16, p1 + 5 * 16);
+    }
+
+    /* update DCs of blocks */
+    // MB d 
+    pMBd->iBlockDC[0][0] = p1[0 * 16];
+    pMBd->iBlockDC[0][1] = p1[4 * 16];
+    pMBd->iBlockDC[1][0] = p1[1 * 16];
+    pMBd->iBlockDC[1][1] = p1[5 * 16];
+    
+    // MB b
+    pMBb->iBlockDC[2][0] = p0[2 * 16];
+    pMBb->iBlockDC[2][1] = p0[6 * 16];
+    pMBb->iBlockDC[3][0] = p0[3 * 16];
+    pMBb->iBlockDC[3][1] = p0[7 * 16];
+
+    // MB c
+    pMBc->iBlockDC[0][2] = p1[ 8 * 16 - 256];
+    pMBc->iBlockDC[0][3] = p1[12 * 16 - 256];
+    pMBc->iBlockDC[1][2] = p1[ 9 * 16 - 256];
+    pMBc->iBlockDC[1][3] = p1[13 * 16 - 256];
+
+    // MB a
+    pMBa->iBlockDC[2][2] = p0[10 * 16 - 256];
+    pMBa->iBlockDC[2][3] = p0[14 * 16 - 256];
+    pMBa->iBlockDC[3][2] = p0[11 * 16 - 256];
+    pMBa->iBlockDC[3][3] = p0[15 * 16 - 256];
+}
+
+/* deblock and destair blocks */
+/* 4 MBs involved, need to process 16 blocks of a */
+/*    |     */
+/*  a | b   */
+/* - - - -  */
+/*  c | d   */
+/*    |     */
+Void postProcBlock(struct tagPostProcInfo * strPostProcInfo[MAX_CHANNELS][2], PixelI * p0, PixelI * p1, size_t mbX, size_t cc, Int threshold)
+{
+    size_t i, j, k;
+    Int dc[5][5];
+    U8 texture[5][5];
+    struct tagPostProcInfo * pMBb = strPostProcInfo[cc][0] + mbX, * pMBa = pMBb - 1, * pMBd = strPostProcInfo[cc][1] + mbX, * pMBc = pMBd - 1;
+    PixelI * pc, * pt;
+
+    /* copy DC and Texture info, can be optimized out */
+    for(j = 0; j < 4; j ++){
+        // from MB a
+        for(i = 0; i < 4; i ++){
+            dc[j][i] = pMBa->iBlockDC[j][i];
+            texture[j][i] = pMBa->ucBlockTexture[j][i];
+        }
+        
+        // 4 blocks from MB c
+        dc[4][j] = pMBc->iBlockDC[0][j];
+        texture[4][j] = pMBc->ucBlockTexture[0][j];
+
+        // 4 blocks from MB b
+        dc[j][4] = pMBb->iBlockDC[j][0];
+        texture[j][4] = pMBb->ucBlockTexture[j][0];
+    }
+    // 1 block from MB d
+    dc[4][4] = pMBd->iBlockDC[0][0];
+    texture[4][4] = pMBd->ucBlockTexture[0][0];
+
+    /* block boundaries */
+    /*     | */
+    /*     | */
+    /*  ---  */
+
+    for(j = 0; j < 4; j ++){
+        for(i = 0; i < 4; i ++){
+            pc = p0 - 256 + i * 64 + j * 16;
+
+            // deblock
+            if(texture[j][i] + texture[j + 1][i] < 3 && abs(dc[j][i] - dc[j + 1][i]) <= threshold){
+                // smooth horizontal boundary ----
+                pt = (j < 3 ? pc + 16 : p1 - 256 + i * 64);
+                for(k = 0; k < 4; k ++){
+                    smooth(pc + idxCC[1][k], pc + idxCC[2][k], pc + idxCC[3][k], pt + idxCC[0][k], pt + idxCC[1][k], pt + idxCC[2][k]);
+                }
+            }
+
+            // two horizontally adjacent blocks have same texture and similiar DCs
+            if(texture[j][i] + texture[j][i + 1] < 3 && abs(dc[j][i] - dc[j][i + 1]) <= threshold){
+                // smooth vertical boundary |
+                pt = pc + 64;
+                for(k = 0; k < 4; k ++){
+                    smooth(pc + idxCC[k][1], pc + idxCC[k][2], pc + idxCC[k][3], pt + idxCC[k][0], pt + idxCC[k][1], pt + idxCC[k][2]);
+                }
+            }
+        }
+    }
+}
+
diff --git a/Source/LibJXR/image/decode/segdec.c b/Source/LibJXR/image/decode/segdec.c
new file mode 100644
index 0000000..fb83f2b
--- /dev/null
+++ b/Source/LibJXR/image/decode/segdec.c
@@ -0,0 +1,1205 @@
+//*@@@+++@@@@******************************************************************
+//
+// Copyright � Microsoft Corp.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+// � Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// � Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//*@@@---@@@@******************************************************************
+
+#include "strcodec.h"
+#include "decode.h"
+
+#ifdef MEM_TRACE
+#define TRACE_MALLOC    1
+#define TRACE_NEW       0
+#define TRACE_HEAP      0
+#include "memtrace.h"
+#endif
+
+extern const int dctIndex[3][16];
+extern const int blkOffset[16];
+extern const int blkOffsetUV[4];
+static Int DecodeSignificantAbsLevel (struct CAdaptiveHuffman *pAHexpt, BitIOInfo* pIO);
+
+//#undef X86OPT_INLINE
+
+#ifdef X86OPT_INLINE
+#define _FORCEINLINE __forceinline
+#else // X86OPT_INLINE
+#define _FORCEINLINE
+#endif // X86OPT_INLINE
+
+//================================================================
+// Memory access functions
+//================================================================
+static U32 _FORCEINLINE _load4(void* pv)
+{
+#ifdef _BIG__ENDIAN_
+    return (*(U32*)pv);
+#else // _BIG__ENDIAN_
+#if defined(_M_IA64) || defined(_ARM_)
+    U32  v;
+    v = ((U16 *) pv)[0];
+    v |= ((U32)((U16 *) pv)[1]) << 16;
+    return _byteswap_ulong(v);
+#else // _M_IA64
+    return _byteswap_ulong(*(U32*)pv);
+#endif // _M_IA64
+#endif // _BIG__ENDIAN_
+}
+
+static _FORCEINLINE U32 _peekBit16(BitIOInfo* pIO, U32 cBits)
+{
+    PEEKBIT16(pIO, cBits);
+    // masking is not needed here because shift of unsigned int is implemented as a logical shift (SHR)!
+}
+
+#define LOAD16 _load4
+static _FORCEINLINE U32 _flushBit16(BitIOInfo* pIO, U32 cBits)
+{
+    FLUSHBIT16(pIO, cBits);
+}
+
+static _FORCEINLINE U32 _getBit16(BitIOInfo* pIO, U32 cBits)
+{
+    U32 uiRet = _peekBit16(pIO, cBits);
+    _flushBit16(pIO, cBits);
+
+    return uiRet;
+}
+
+#define SIGN_BIT(TypeOrValue) (((UInt) 1) << (8 * sizeof (TypeOrValue) - 1))
+/***********************************************************************************************************
+  Huffman decode (input is a fully built Huffman table)
+***********************************************************************************************************/
+Int getHuff(const short *pDecodeTable, BitIOInfo* pIO)
+{
+    Int iSymbol, iSymbolHuff;
+    iSymbol = pDecodeTable[peekBit16(pIO, HUFFMAN_DECODE_ROOT_BITS)];
+
+    flushBit16(pIO, iSymbol < 0 ? HUFFMAN_DECODE_ROOT_BITS : iSymbol & ((1 << HUFFMAN_DECODE_ROOT_BITS_LOG) - 1));
+	iSymbolHuff = iSymbol >> HUFFMAN_DECODE_ROOT_BITS_LOG;
+
+	if (iSymbolHuff < 0) {
+		iSymbolHuff = iSymbol;
+        while ((iSymbolHuff = pDecodeTable[iSymbolHuff + SIGN_BIT (pDecodeTable[0]) + getBit16(pIO, 1)]) < 0);
+	}
+    return (iSymbolHuff);
+}
+
+#if 1
+static _FORCEINLINE U32 _getBool16(BitIOInfo* pIO)
+{
+    U32 uiRet = pIO->uiAccumulator >> 31;//_peekBit16(pIO, 1);
+    //_flushBit16(pIO, 1);
+    pIO->cBitsUsed++;
+    if (pIO->cBitsUsed < 16) {
+        pIO->uiAccumulator <<= 1;
+    }
+    else {
+        pIO->pbCurrent = MASKPTR(pIO->pbCurrent + ((pIO->cBitsUsed >> 3)/* & 2*/), pIO->iMask);
+        pIO->cBitsUsed &= 16 - 1;
+        pIO->uiAccumulator = LOAD16(pIO->pbCurrent) << pIO->cBitsUsed;
+    }
+
+    return uiRet;
+}
+
+static _FORCEINLINE I32 _getSign(BitIOInfo* pIO)
+{
+    I32 uiRet = (int) pIO->uiAccumulator >> 31;//_peekBit16(pIO, 1);
+    //_flushBit16(pIO, 1);
+    pIO->cBitsUsed++;
+    if (pIO->cBitsUsed < 16) {
+        pIO->uiAccumulator <<= 1;
+    }
+    else {
+        pIO->pbCurrent = MASKPTR(pIO->pbCurrent + ((pIO->cBitsUsed >> 3)/* & 2*/), pIO->iMask);
+        pIO->cBitsUsed &= 16 - 1;
+        pIO->uiAccumulator = LOAD16(pIO->pbCurrent) << pIO->cBitsUsed;
+    }
+
+    return uiRet;
+}
+#else
+#define _getBool16(x)   _getBit16((x),1)
+#define _getSign(x)   (-_getBit16((x),1))
+#endif
+
+/** this function returns cBits if zero is read, or a signed value if first cBits are not all zero **/
+static _FORCEINLINE I32 _getBit16s(BitIOInfo* pIO, U32 cBits)
+{
+    I32 iRet = (I32)_peekBit16(pIO, cBits + 1);
+    iRet = ((iRet >> 1) ^ (-(iRet & 1))) + (iRet & 1);
+    _flushBit16(pIO, cBits + (iRet != 0));
+    return iRet;
+}
+
+/*************************************************************************
+    Huffman decoding with short tables
+*************************************************************************/
+static _FORCEINLINE Int _getHuffShort(const short *pDecodeTable, BitIOInfo* pIO)
+{
+    Int iSymbol = pDecodeTable[_peekBit16(pIO, HUFFMAN_DECODE_ROOT_BITS)];
+    assert(iSymbol >= 0);
+    // for some strange reason, inlining flushBit doesn't work well
+    flushBit16(pIO, iSymbol & ((1 << HUFFMAN_DECODE_ROOT_BITS_LOG) - 1));
+    return (iSymbol >> HUFFMAN_DECODE_ROOT_BITS_LOG);
+}
+/*************************************************************************
+    Adapt + Huffman init
+*************************************************************************/
+static Int AdaptDecFixed (CAdaptiveHuffman *pAH)
+{
+    AdaptDiscriminant (pAH);
+    return ICERR_OK;
+}
+
+/*************************************************************************
+    DecodeCBP
+*************************************************************************/
+static Void DecodeCBP(CWMImageStrCodec * pSC, CCodingContext *pContext)
+{
+    BitIOInfo* pIO = pContext->m_pIOAC;
+    const COLORFORMAT cf = pSC->m_param.cfColorFormat;
+    const Int iChannel = (cf == NCOMPONENT || cf == CMYK) ? (Int) pSC->m_param.cNumChannels : 1;
+    Int iCBPCY, iCBPCU , iCBPCV;
+    Int k, iBlock, i;
+    Int iNumCBP;
+    Bool bIsChroma;
+    CAdaptiveHuffman *pAHCBP = pContext->m_pAdaptHuffCBPCY;
+    CAdaptiveHuffman *pAHCBP1 = pContext->m_pAdaptHuffCBPCY1;
+    CAdaptiveHuffman *pAHex1 = pContext->m_pAHexpt[1];
+        
+    readIS_L1(pSC, pIO);
+
+    for (i = 0; i < iChannel; i++) {
+
+        iCBPCY = iCBPCU = iCBPCV = 0;
+        iNumCBP = _getHuffShort(pAHCBP1->m_hufDecTable, pIO);
+        pAHCBP1->m_iDiscriminant += pAHCBP1->m_pDelta[iNumCBP];
+
+        switch (iNumCBP) {
+            case 2:
+                iNumCBP = _getBit16(pIO, 2);
+                if (iNumCBP == 0)
+                    iNumCBP = 3;
+                else if (iNumCBP == 1)
+                    iNumCBP = 5;
+                else {
+                    static const Int aTab[] = { 6, 9, 10, 12 };
+                    iNumCBP = aTab[iNumCBP * 2 + _getBool16 (pIO) - 4];
+                }
+                break;
+            case 1:
+                iNumCBP = 1 << _getBit16(pIO, 2);
+                break;
+            case 3:
+                iNumCBP = 0xf ^ (1 << _getBit16(pIO, 2));
+                break;
+            case 4:
+                iNumCBP = 0xf;
+        }
+
+        for (iBlock = 0; iBlock < 4; iBlock++) {
+            if (iNumCBP & (1 << iBlock)) {
+                static const UInt gFLC0[] = { 0,2,1,2,2,0 };
+                static const UInt gOff0[] = { 0,4,2,8,12,1 };
+                static const UInt gOut0[] = { 0,15,3,12, 1,2,4,8, 5,6,9,10, 7,11,13,14 };
+                Int iNumBlockCBP = getHuff(pAHCBP->m_hufDecTable, pIO);
+                unsigned int val = (unsigned int) iNumBlockCBP + 1, iCode1;
+
+                pAHCBP->m_iDiscriminant += pAHCBP->m_pDelta[iNumBlockCBP];
+                iNumBlockCBP = 0;
+
+                if (val >= 6) { // chroma present
+                    if (_getBool16 (pIO)) {
+                        iNumBlockCBP = 0x10;
+                    }
+                    else if (_getBool16 (pIO)) {
+                        iNumBlockCBP = 0x20;
+                    }
+                    else {
+                        iNumBlockCBP = 0x30;
+                    }
+                    if (val == 9) {
+                        if (_getBool16 (pIO)) {
+                            // do nothing
+                        }
+                        else if (_getBool16 (pIO)) {
+                            val = 10;
+                        }
+                        else {
+                            val = 11;
+                        }
+                    }
+                    val -= 6;
+                }
+                iCode1 = gOff0[val];
+                if (gFLC0[val]) {
+                    iCode1 += _getBit16(pIO, gFLC0[val]);
+                }
+                iNumBlockCBP += gOut0[iCode1];
+
+                switch (cf) {
+                    case YUV_444:
+                        iCBPCY |= ((iNumBlockCBP & 0xf) << (iBlock * 4));
+                        for (k = 0; k < 2; k++) {
+                            bIsChroma = ((iNumBlockCBP>>(k+4)) & 0x01);
+                            if (bIsChroma) { // U is present in block
+                                Int iCode = _getHuffShort(pAHex1->m_hufDecTable, pIO);
+                                switch (iCode) { 
+                            case 1:
+                                iCode = _getBit16(pIO, 2);
+                                if (iCode == 0)
+                                    iCode = 3;
+                                else if (iCode == 1)
+                                    iCode = 5;
+                                else {
+                                    static const Int aTab[] = { 6, 9, 10, 12 };
+                                    iCode = aTab[iCode * 2 + _getBool16 (pIO) - 4];
+                                }
+                                break;
+                            case 0:
+                                iCode = 1 << _getBit16(pIO, 2);
+                                break;
+                            case 2:
+                                iCode = 0xf ^ (1 << _getBit16(pIO, 2));
+                                break;
+                            case 3:
+                                iCode = 0xf;
+                                }
+                                if (k == 0)
+                                    iCBPCU |= (iCode << (iBlock * 4));
+                                else 
+                                    iCBPCV |= (iCode << (iBlock * 4));
+                            }
+                        }
+                        break;
+
+                    case YUV_420:
+                        iCBPCY |= ((iNumBlockCBP & 0xf) << (iBlock * 4));
+                        iCBPCU |= ((iNumBlockCBP >> 4) & 0x1) << (iBlock);
+                        iCBPCV |= ((iNumBlockCBP >> 5) & 0x1) << (iBlock);
+                        break;
+
+                    case YUV_422:
+                        iCBPCY |= ((iNumBlockCBP & 0xf) << (iBlock * 4));
+                        for (k = 0; k < 2; k ++) {
+                            Int iCode = 5;
+                            const Int iShift[4] = {0, 1, 4, 5};
+                            if((iNumBlockCBP >> (k + 4)) & 0x01) {
+                                if(_getBool16(pIO)) {
+                                    iCode = 1;
+                                }
+                                else if(_getBool16(pIO)){
+                                    iCode = 4;
+                                }
+                                iCode <<= iShift[iBlock];
+                                if(k == 0) iCBPCU |= iCode;
+                                else iCBPCV |= iCode;
+                            }
+                        }
+                        break;
+
+                    default:
+                        iCBPCY |= (iNumBlockCBP << (iBlock * 4));
+                }
+            }
+        }
+
+        pSC->MBInfo.iDiffCBP[i] = iCBPCY;
+        if (cf == YUV_420 || cf == YUV_444 || cf == YUV_422) {
+            pSC->MBInfo.iDiffCBP[1] = iCBPCU;
+            pSC->MBInfo.iDiffCBP[2] = iCBPCV;
+        }
+    }
+}
+
+/*************************************************************************
+    Experimental code -- decodeBlock
+    SR = <0 1 2> == <last, nonsignificant, significant run>
+    alphabet 12:
+        pAHexpt[0] == <SR', SL, SR | first symbol>
+    alphabet 6:
+        pAHexpt[1] == <SR', SL | continuous>
+        pAHexpt[2] == <SR', SL | continuous>
+    alphabet 4:
+        pAHexpt[3] == <SR', SL | 2 free slots> (SR may be last or insignificant only)
+    alphabet f(run) (this can be extended to 6 contexts - SL and SR')
+        pAHexpt[4] == <run | continuous>
+    alphabet f(lev) (this can be extended to 9 contexts)
+        pAHexpt[5-6] == <lev | continuous> first symbol
+        pAHexpt[7-8] == <lev | continuous> condition on SRn no use
+*************************************************************************/
+
+Int _FORCEINLINE DecodeSignificantRun (Int iMaxRun, struct CAdaptiveHuffman *pAHexpt, BitIOInfo* pIO)
+{
+    Int iIndex;
+    static const Int aRemap[] = {1,2,3,5,7,   1,2,3,5,7,   /*1,2,3,4,6,  */1,2,3,4,5 };
+    Int iBin = gSignificantRunBin[iMaxRun];
+    Int iRun = 0, iFLC = 0;
+
+    if (iMaxRun < 5) {
+        if (iMaxRun == 1) {
+            return 1;
+        }
+        else if (_getBool16 (pIO)) {
+            return 1;
+        }
+        else if (iMaxRun == 2 || _getBool16 (pIO)) {
+            return 2;
+        }
+        else if (iMaxRun == 3 || _getBool16 (pIO)) {
+            return 3;
+        }
+        return 4;
+    }
+    iIndex = _getHuffShort (pAHexpt->m_hufDecTable, pIO);
+    iIndex += iBin * 5;
+    iRun = aRemap[iIndex];
+    iFLC = gSignificantRunFixedLength[iIndex];
+    if (iFLC) {
+        iRun += _getBit16 (pIO, iFLC);
+    }
+    return iRun;
+}
+
+#ifndef X86OPT_INLINE
+static Void DecodeFirstIndex (Int *pIndex, struct CAdaptiveHuffman *pAHexpt, 
+                      BitIOInfo* pIO)
+#else
+static __forceinline Void DecodeFirstIndex (Int *pIndex, struct CAdaptiveHuffman *pAHexpt, 
+                      BitIOInfo* pIO)
+#endif
+{
+    Int iIndex;
+    iIndex = getHuff (pAHexpt->m_hufDecTable, pIO);
+    pAHexpt->m_iDiscriminant += pAHexpt->m_pDelta[iIndex];
+    pAHexpt->m_iDiscriminant1 += pAHexpt->m_pDelta1[iIndex];
+    *pIndex = iIndex;
+}
+
+#ifndef X86OPT_INLINE
+static Void DecodeIndex (Int *pIndex, Int iLoc, struct CAdaptiveHuffman *pAHexpt, 
+                 BitIOInfo* pIO)
+#else
+static __forceinline Void DecodeIndex (Int *pIndex, Int iLoc,
+                                       struct CAdaptiveHuffman *pAHexpt, BitIOInfo* pIO)
+#endif
+{
+    Int iIndex;
+    if (iLoc < 15) {
+        iIndex = _getHuffShort (pAHexpt->m_hufDecTable, pIO);
+        pAHexpt->m_iDiscriminant += pAHexpt->m_pDelta[iIndex];
+        pAHexpt->m_iDiscriminant1 += pAHexpt->m_pDelta1[iIndex];
+        *pIndex = iIndex;
+    }
+    else if (iLoc == 15) {
+        if (_getBool16 (pIO) == 0) {
+            iIndex = 0;
+        }
+        else if (_getBool16 (pIO) == 0) {
+            iIndex = 2;
+        }
+        else {
+            iIndex = 1 + 2 * _getBool16 (pIO);
+        }
+        *pIndex = iIndex;
+    }
+    else { //if (iLoc == 16) { /* deterministic */
+        Int iSL = _getBit16 (pIO, 1/* + 1*/);
+        *pIndex = iSL;// >> 1;
+    }
+}
+
+static _FORCEINLINE Int DecodeBlock (Bool bChroma, Int *aLocalCoef, struct CAdaptiveHuffman **pAHexpt,
+                        const Int iContextOffset, BitIOInfo* pIO, Int iLocation)
+{
+    Int iSR, iSRn, iIndex, iNumNonzero = 1, iCont, iSign;
+    struct CAdaptiveHuffman **pAH1 = pAHexpt + iContextOffset + bChroma * 3;
+
+    /** first symbol **/
+    DecodeFirstIndex (&iIndex, /*&iSign, */pAH1[0], pIO);
+    iSR = (iIndex & 1);
+    iSRn = iIndex >> 2;
+
+    iCont = iSR & iSRn;
+    iSign = _getSign(pIO);
+
+    if (iIndex & 2 /* iSL */) {
+        aLocalCoef[1] = (DecodeSignificantAbsLevel (pAHexpt[6 + iContextOffset + iCont], pIO) ^ iSign) - iSign;
+    }
+    else {
+        aLocalCoef[1] = (1 | iSign); // 0 -> 1; -1 -> -1
+    }
+    aLocalCoef[0] = 0;
+    if (iSR == 0) {
+        aLocalCoef[0] = DecodeSignificantRun (15 - iLocation, pAHexpt[0], pIO);
+    }
+    iLocation += aLocalCoef[0] + 1;
+
+    while (iSRn != 0) {
+        iSR = iSRn & 1;
+        aLocalCoef[iNumNonzero * 2] = 0;
+        if (iSR == 0) {
+            aLocalCoef[iNumNonzero * 2] = DecodeSignificantRun (15 - iLocation, pAHexpt[0], pIO);
+        }
+        iLocation += aLocalCoef[iNumNonzero * 2] + 1;
+        DecodeIndex (&iIndex, /*&iSign, */iLocation, pAH1[iCont + 1], pIO);
+        iSRn = iIndex >> 1;
+
+        assert (iSRn >= 0 && iSRn < 3);
+        iCont &= iSRn;  /** huge difference! **/
+        iSign = _getSign(pIO);
+
+        if (iIndex & 1 /* iSL */) {
+            aLocalCoef[iNumNonzero * 2 + 1] = 
+                (DecodeSignificantAbsLevel (pAHexpt[6 + iContextOffset + iCont], pIO) ^ iSign) - iSign;
+        }
+        else {
+            aLocalCoef[iNumNonzero * 2 + 1] = (1 | iSign); // 0 -> 1; -1 -> -1 (was 1 + (iSign * 2))
+        }
+        iNumNonzero++;
+    }
+    return iNumNonzero;
+}
+
+/*************************************************************************
+    DecodeBlockHighpass : 
+*************************************************************************/
+static _FORCEINLINE Int DecodeBlockHighpass (const Bool bChroma, struct CAdaptiveHuffman **pAHexpt,
+                       BitIOInfo* pIO, const Int iQP, Int *pCoef, CAdaptiveScan *pScan)
+{
+    const Int iContextOffset = CTDC + CONTEXTX;
+    UInt  iLoc = 1;
+    Int iSR, iSRn, iIndex, iNumNonzero = 1, iCont, iSign, iLevel;
+    struct CAdaptiveHuffman **pAH1 = pAHexpt + iContextOffset + bChroma * 3;
+    const CAdaptiveScan *pConstScan = (const CAdaptiveScan *) pScan;
+
+    /** first symbol **/
+    DecodeFirstIndex (&iIndex, /*&iSign, */pAH1[0], pIO);
+    iSR = (iIndex & 1);
+    iSRn = iIndex >> 2;
+
+    iCont = iSR & iSRn;
+    iSign = _getSign(pIO);
+
+    iLevel = (iQP ^ iSign) - iSign;
+    if (iIndex & 2 /* iSL */) {
+        iLevel *= DecodeSignificantAbsLevel (pAHexpt[6 + iContextOffset + iCont], pIO);// ^ iSign) - iSign;
+    }
+    //else {
+    //    iLevel = (1 | iSign); // 0 -> 1; -1 -> -1
+    //}
+    if (iSR == 0) {
+       iLoc += DecodeSignificantRun (15 - iLoc, pAHexpt[0], pIO);
+    }
+    iLoc &= 0xf;
+	pCoef[pConstScan[iLoc].uScan] = (PixelI) iLevel;//(PixelI)(iQP * iLevel);
+    pScan[iLoc].uTotal++;
+	if (iLoc && pScan[iLoc].uTotal > pScan[iLoc - 1].uTotal) {
+		CAdaptiveScan cTemp = pScan[iLoc];
+		pScan[iLoc] = pScan[iLoc - 1];
+		pScan[iLoc - 1] = cTemp;
+    }
+    iLoc = (iLoc + 1) & 0xf;
+    //iLoc++;
+
+    while (iSRn != 0) {
+        iSR = iSRn & 1;
+        if (iSR == 0) {
+            iLoc += DecodeSignificantRun (15 - iLoc, pAHexpt[0], pIO);
+            if (iLoc >= 16)
+                return 16;
+        }
+        DecodeIndex (&iIndex, /*&iSign, */iLoc + 1, pAH1[iCont + 1], pIO);
+        iSRn = iIndex >> 1;
+
+        assert (iSRn >= 0 && iSRn < 3);
+        iCont &= iSRn;  /** huge difference! **/
+        iSign = _getSign(pIO);
+
+        iLevel = (iQP ^ iSign) - iSign;
+        if (iIndex & 1 /* iSL */) {
+            iLevel *= DecodeSignificantAbsLevel (pAHexpt[6 + iContextOffset + iCont], pIO);// ^ iSign) - iSign;
+            //iLevel = (DecodeSignificantAbsLevel (pAHexpt[6 + iContextOffset + iCont], pIO) ^ iSign) - iSign;
+        }
+        //else {
+        //    iLevel = (1 | iSign); // 0 -> 1; -1 -> -1 (was 1 + (iSign * 2))
+        //}
+       
+	    pCoef[pConstScan[iLoc].uScan] = (PixelI) iLevel;//(PixelI)(iQP * iLevel);
+        pScan[iLoc].uTotal++;
+	    if (iLoc && pScan[iLoc].uTotal > pScan[iLoc - 1].uTotal) {
+		    CAdaptiveScan cTemp = pScan[iLoc];
+		    pScan[iLoc] = pScan[iLoc - 1];
+		    pScan[iLoc - 1] = cTemp;
+        }
+
+        iLoc = (iLoc + 1) & 0xf;
+        iNumNonzero++;
+    }
+    return iNumNonzero;
+}
+
+/*************************************************************************
+    DecodeBlockAdaptive
+*************************************************************************/
+static _FORCEINLINE Int DecodeBlockAdaptive (Bool bNoSkip, Bool bChroma, CAdaptiveHuffman **pAdHuff,
+                                BitIOInfo *pIO, BitIOInfo *pIOFL,
+                                PixelI *pCoeffs, CAdaptiveScan *pScan,
+                                const Int iModelBits, const Int iTrim, const Int iQP,
+                                const Int *pOrder, const Bool bSkipFlexbits)
+{
+    // const Int iLocation = 1;
+    // const Int iContextOffset = CTDC + CONTEXTX;
+    Int kk, iNumNonzero = 0, iFlex = iModelBits - iTrim;
+
+    if (iFlex < 0 || bSkipFlexbits)
+        iFlex = 0;
+
+    if (bNoSkip) {
+        const Int iQP1 = (iQP << iModelBits);
+        iNumNonzero = DecodeBlockHighpass (bChroma, pAdHuff, pIO, iQP1, pCoeffs, pScan);
+    }
+    if (iFlex) {
+        UInt k;
+        if (iQP + iTrim == 1) { // only iTrim = 0, iQP = 1 is legal
+            assert (iTrim == 0);
+            assert (iQP == 1);
+
+            for (k = 1; k < 16; k++) {
+                PixelI *pk = pCoeffs + pOrder[k];
+                if (*pk < 0) {
+                    Int fine = _getBit16(pIOFL, iFlex);
+                    *pk -= (PixelI)(fine);
+                }
+                else if (*pk > 0) {
+                    Int fine = _getBit16(pIOFL, iFlex);
+                    *pk += (PixelI)(fine);
+                }
+                else {
+                    *pk = (PixelI)(_getBit16s(pIOFL, iFlex));
+                }
+            }
+        }
+        else {
+            const Int iQP1 = iQP << iTrim;
+            for (k = 1; k < 16; k++) {
+                kk = pCoeffs[pOrder[k]];
+                if (kk < 0) {
+                    Int fine = _getBit16(pIOFL, iFlex);
+                    pCoeffs[pOrder[k]] -= (PixelI)(iQP1 * fine);
+                }
+                else if (kk > 0) {
+                    Int fine = _getBit16(pIOFL, iFlex);
+                    pCoeffs[pOrder[k]] += (PixelI)(iQP1 * fine);
+                }
+                else {
+                    pCoeffs[pOrder[k]] = (PixelI)(iQP1 * _getBit16s(pIOFL, iFlex));
+                }
+            }
+        }
+    }
+
+    return iNumNonzero;
+}
+
+
+/*************************************************************************
+    GetCoeffs
+*************************************************************************/
+static _FORCEINLINE Int DecodeCoeffs (CWMImageStrCodec * pSC, CCodingContext *pContext,
+                         Int iMBX, Int iMBY,
+                         BitIOInfo* pIO, BitIOInfo *pIOFL)
+{
+    CWMITile * pTile = pSC->pTile + pSC->cTileColumn;
+    const COLORFORMAT cf = pSC->m_param.cfColorFormat;
+    const Int iChannels = (Int) pSC->m_param.cNumChannels;
+    const Int iPlanes = (cf == YUV_420 || cf == YUV_422) ? 1 : iChannels;
+    Int  iQP;
+    CAdaptiveScan *pScan;
+    PixelI  *pCoeffs;
+    Int i, iBlock, iSubblock, iNBlocks = 4;
+    Int iModelBits = pContext->m_aModelAC.m_iFlcBits[0];
+    Int aLaplacianMean[2] = { 0, 0}, *pLM = aLaplacianMean + 0;
+    const Int *pOrder = dctIndex[0];
+    const Int iOrient = pSC->MBInfo.iOrientation;
+    Bool bChroma = FALSE;
+
+    Int iCBPCU = pSC->MBInfo.iCBP[1];
+    Int iCBPCV = pSC->MBInfo.iCBP[2];
+    Int iCBPCY = pSC->MBInfo.iCBP[0];
+
+    UNREFERENCED_PARAMETER( iMBX );
+    UNREFERENCED_PARAMETER( iMBY );
+
+    /** set scan arrays and other MB level constants **/
+    if (iOrient == 1) {
+        pScan = pContext->m_aScanVert;
+    }
+    else {
+        pScan = pContext->m_aScanHoriz;
+    }
+
+    if (cf == YUV_420) {
+        iNBlocks = 6;
+        iCBPCY += (iCBPCU << 16) + (iCBPCV << 20);
+    }
+    else if (cf == YUV_422) {
+        iNBlocks = 8;
+        iCBPCY += (iCBPCU << 16) + (iCBPCV << 24);
+    }
+
+    for (i = 0; i < iPlanes; i++) {
+        Int iIndex = 0, iNumNonZero;
+
+        if(pSC->WMISCP.sbSubband != SB_NO_FLEXBITS)
+            readIS_L1(pSC, pIOFL);
+
+        for (iBlock = 0; iBlock < iNBlocks; iBlock++) {
+
+            readIS_L2(pSC, pIO);
+            if (pIO != pIOFL)
+                readIS_L2(pSC, pIOFL);
+
+            iQP = (pSC->m_param.bTranscode ? 1 : pTile->pQuantizerHP[iPlanes > 1 ? i : (iBlock > 3 ? (cf == YUV_420 ? iBlock - 3 : iBlock / 2 - 1) : 0)][pSC->MBInfo.iQIndexHP].iQP);
+
+            for (iSubblock = 0; iSubblock < 4; iSubblock++, iIndex++, iCBPCY >>= 1) {
+                pCoeffs = pSC->p1MBbuffer[i] + blkOffset[iIndex & 0xf];
+
+                //if (iBlock < 4) {//(cf == YUV_444) {
+                    //bBlockNoSkip = ((iTempCBPC & (1 << iIndex1)) != 0);
+                    //pCoeffs = pSC->p1MBbuffer[iBlock >> 2] + blkOffset[iIndex & 0xf];
+                //}
+                //else {
+                if (iBlock >= 4) {
+                    if(cf == YUV_420) {
+                        pCoeffs = pSC->p1MBbuffer[iBlock - 3] + blkOffsetUV[iSubblock];
+                    }
+                    else { // YUV_422
+                        pCoeffs = pSC->p1MBbuffer[1 + (1 & (iBlock >> 1))] + ((iBlock & 1) * 32) + blkOffsetUV_422[iSubblock];
+                    }
+                }
+
+                /** read AC values **/
+                assert (pSC->m_Dparam->bSkipFlexbits == 0 || pSC->WMISCP.bfBitstreamFormat == FREQUENCY || pSC->WMISCP.sbSubband == SB_NO_FLEXBITS);
+                iNumNonZero = DecodeBlockAdaptive ((iCBPCY & 1), bChroma, pContext->m_pAHexpt,
+                    pIO, pIOFL, pCoeffs, pScan, iModelBits, pContext->m_iTrimFlexBits,
+                    iQP, pOrder, pSC->m_Dparam->bSkipFlexbits);
+                if(iNumNonZero > 16) // something is wrong!
+                    return ICERR_ERROR;
+                // shouldn't this be > 15?
+                (*pLM) += iNumNonZero;
+            }
+            if (iBlock == 3) {
+                iModelBits = pContext->m_aModelAC.m_iFlcBits[1];
+                pLM = aLaplacianMean + 1;
+                bChroma = TRUE;
+            }
+        }
+
+        iCBPCY = pSC->MBInfo.iCBP[(i + 1) & 0xf];
+        assert (MAX_CHANNELS == 16);
+    }
+
+    /** update model at end of MB **/
+    UpdateModelMB (cf, iChannels, aLaplacianMean, &(pContext->m_aModelAC));
+    return ICERR_OK;
+}
+
+/*************************************************************************
+    DecodeSignificantAbsLevel
+*************************************************************************/
+#ifndef X86OPT_INLINE
+static Int DecodeSignificantAbsLevel (struct CAdaptiveHuffman *pAHexpt, BitIOInfo* pIO)
+#else
+static __forceinline Int DecodeSignificantAbsLevel (struct CAdaptiveHuffman *pAHexpt, BitIOInfo* pIO)
+#endif
+{
+    UInt iIndex;
+    Int iFixed, iLevel;
+    static const Int aRemap[] = { 2, 3, 4, 6, 10, 14 };
+    static const Int aFixedLength[] = { 0, 0, 1, 2, 2, 2 };
+
+    iIndex = (UInt)getHuff (pAHexpt->m_hufDecTable, pIO);
+    assert(iIndex <= 6);
+    pAHexpt->m_iDiscriminant += pAHexpt->m_pDelta[iIndex];
+    if (iIndex < 2) {
+        iLevel = iIndex + 2; // = aRemap[iIndex]
+    }
+    else if (iIndex < 6) {
+        iFixed = aFixedLength[iIndex];
+        iLevel = aRemap[iIndex] + _getBit16 (pIO, iFixed);
+    }
+    else{
+        iFixed = _getBit16 (pIO, 4) + 4;
+        if (iFixed == 19) {
+            iFixed += _getBit16 (pIO, 2);
+            if (iFixed == 22) {
+                iFixed += _getBit16 (pIO, 3);
+            }
+        }
+        iLevel = 2 + (1 << iFixed);
+        iIndex = getBit32 (pIO, iFixed);
+        iLevel += iIndex;
+    }
+    return iLevel;
+}
+
+U8 decodeQPIndex(BitIOInfo* pIO,U8 cBits)
+{
+    if(_getBit16(pIO, 1) == 0)
+        return 0;
+    return (U8)(_getBit16(pIO, cBits) + 1);
+}
+
+/*************************************************************************
+    DecodeSecondStageCoeff
+*************************************************************************/
+Int DecodeMacroblockLowpass (CWMImageStrCodec * pSC, CCodingContext *pContext,
+        Int iMBX, Int iMBYdummy)
+{
+    const COLORFORMAT cf = pSC->m_param.cfColorFormat;
+    const Int iChannels = (Int) pSC->m_param.cNumChannels;
+    const Int iFullPlanes = (cf == YUV_420 || cf == YUV_422) ? 2 : iChannels;
+    Int k;
+	CAdaptiveScan *pScan = pContext->m_aScanLowpass;
+    BitIOInfo* pIO = pContext->m_pIOLP;
+    Int iModelBits = pContext->m_aModelLP.m_iFlcBits[0];
+    Int aRLCoeffs[32], iNumNonzero = 0, iIndex = 0;
+    Int aLaplacianMean[2] = { 0, 0}, *pLM = aLaplacianMean;
+    Int iChannel, iCBP = 0;
+#ifndef ARMOPT_BITIO    // ARM opt always uses 32-bit version of getBits
+    U32 (*getBits)(BitIOInfo* pIO, U32 cBits) = _getBit16;
+#endif
+    CWMIMBInfo * pMBInfo = &pSC->MBInfo;
+    I32 *aDC[MAX_CHANNELS];
+
+    UNREFERENCED_PARAMETER( iMBX );
+    UNREFERENCED_PARAMETER( iMBYdummy );
+
+    readIS_L1(pSC, pIO);
+    if((pSC->WMISCP.bfBitstreamFormat != SPATIAL) && (pSC->pTile[pSC->cTileColumn].cBitsLP > 0))  // MB-based LP QP index
+        pMBInfo->iQIndexLP = decodeQPIndex(pIO, pSC->pTile[pSC->cTileColumn].cBitsLP);
+    
+    // set arrays
+    for (k = 0; k < (Int) pSC->m_param.cNumChannels; k++) {
+        aDC[k & 15] = pMBInfo->iBlockDC[k];
+    }
+
+    /** reset adaptive scan totals **/
+    if (pSC->m_bResetRGITotals) {
+        int iScale = 2;
+        int iWeight = iScale * 16;
+		pScan[0].uTotal = MAXTOTAL;
+        for (k = 1; k < 16; k++) {
+			pScan[k].uTotal = iWeight;
+            iWeight -= iScale;
+        }
+    }
+
+    /** in raw mode, this can take 6% of the bits in the extreme low rate case!!! **/
+    if (cf == YUV_420 || cf == YUV_422 || cf == YUV_444) {
+        int iCountM = pContext->m_iCBPCountMax, iCountZ = pContext->m_iCBPCountZero;
+        int iMax = iFullPlanes * 4 - 5; /* actually (1 << iNChannels) - 1 **/
+        if (iCountZ <= 0 || iCountM < 0) {
+            iCBP = 0;
+            if (_getBool16 (pIO)) {
+                iCBP = 1;
+                k = _getBit16 (pIO, iFullPlanes - 1);
+                if (k) {
+                    iCBP = k * 2 + _getBit16(pIO, 1);
+                }
+            }
+            if (iCountM < iCountZ)
+                iCBP = iMax - iCBP;
+        }
+        else {
+            iCBP = _getBit16(pIO, iFullPlanes);
+        }
+
+        iCountM += 1 - 4 * (iCBP == iMax);//(b + c - 2*a);
+        iCountZ += 1 - 4 * (iCBP == 0);//(a + b - 2*c);
+        if (iCountM < -8)
+            iCountM = -8;
+        else if (iCountM > 7)
+            iCountM = 7;
+        pContext->m_iCBPCountMax = iCountM;
+
+        if (iCountZ < -8)
+            iCountZ = -8;
+        else if (iCountZ > 7)
+            iCountZ = 7;
+        pContext->m_iCBPCountZero = iCountZ;
+    }
+    else { /** 1 or N channel **/
+        for (iChannel = 0; iChannel < iChannels; iChannel++)
+            iCBP |= (getBits (pIO, 1) << iChannel);
+    }
+
+#ifndef ARMOPT_BITIO    // ARM opt always uses 32-bit version of getBits
+    if (pContext->m_aModelLP.m_iFlcBits[0] > 14 || pContext->m_aModelLP.m_iFlcBits[1] > 14) {
+        getBits = getBit32;
+    }
+#endif
+
+    for (iChannel = 0; iChannel < iFullPlanes; iChannel++) {
+        PixelI *pCoeffs = aDC[iChannel];
+
+        if (iCBP & 1) {
+            iNumNonzero = DecodeBlock (iChannel > 0, aRLCoeffs, pContext->m_pAHexpt,
+                CTDC, pIO, 1 + 9 * ((cf == YUV_420) && (iChannel == 1))
+                + ((cf == YUV_422) && (iChannel == 1)));
+
+            if ((cf == YUV_420 || cf == YUV_422) && iChannel) {
+                Int aTemp[16]; //14 required, 16 for security
+                static const Int aRemap[] = { 4,  1,2,3,  5,6,7 };
+                const Int *pRemap = aRemap + (cf == YUV_420);
+                const Int iCount = (cf == YUV_420) ? 6 : 14;
+
+                (*pLM) += iNumNonzero;
+                iIndex = 0;
+                memset (aTemp, 0, sizeof(aTemp));
+
+                for (k = 0; k < iNumNonzero; k++) {
+                    iIndex += aRLCoeffs[k * 2];
+                    aTemp[iIndex & 0xf] = aRLCoeffs[k * 2 + 1];
+                    iIndex++;
+                }
+
+                for (k = 0; k < iCount; k++) {
+                    aDC[(k & 1) + 1][pRemap[k >> 1]] = aTemp[k];
+                }
+            }
+            else {
+                (*pLM) += iNumNonzero;
+                iIndex = 1;
+
+                for (k = 0; k < iNumNonzero; k++) {
+                    iIndex += aRLCoeffs[k * 2];
+					pCoeffs[pScan[iIndex].uScan] = aRLCoeffs[k * 2 + 1];
+					pScan[iIndex].uTotal++;
+					if (pScan[iIndex].uTotal > pScan[iIndex - 1].uTotal) {
+						CAdaptiveScan cTemp = pScan[iIndex];
+						pScan[iIndex] = pScan[iIndex - 1];
+						pScan[iIndex - 1] = cTemp;
+					}
+                    iIndex++;
+                }
+            }
+        }
+
+        if (iModelBits) {
+            if ((cf == YUV_420 || cf == YUV_422) && iChannel) {
+                for (k = 1; k < (cf == YUV_420 ? 4 : 8); k++) {
+                    if (aDC[1][k] > 0) {
+                        aDC[1][k] <<= iModelBits;
+                        aDC[1][k] += getBits (pIO, iModelBits);
+                    }
+                    else if (aDC[1][k] < 0) {
+                        aDC[1][k] <<= iModelBits;
+                        aDC[1][k] -= getBits (pIO, iModelBits);
+                    }
+                    else {
+                        aDC[1][k] = getBits (pIO, iModelBits);
+                        if (aDC[1][k] && _getBool16 (pIO))
+                            aDC[1][k] = -aDC[1][k];
+                    }
+
+                    if (aDC[2][k] > 0) {
+                        aDC[2][k] <<= iModelBits;
+                        aDC[2][k] += getBits (pIO, iModelBits);
+                    }
+                    else if (aDC[2][k] < 0) {
+                        aDC[2][k] <<= iModelBits;
+                        aDC[2][k] -= getBits (pIO, iModelBits);
+                    }
+                    else {
+                        aDC[2][k] = getBits (pIO, iModelBits);
+                        if (aDC[2][k] && _getBool16 (pIO))
+                            aDC[2][k] = -aDC[2][k];
+                    }
+                }
+            }
+            else {
+#ifdef WIN32
+                const Int iMask = (1 << iModelBits) - 1;
+#endif // WIN32
+                for (k = 1; k < 16; k++) {
+#ifdef WIN32
+                    if (pCoeffs[k]) {
+                        Int r1 = _rotl(pCoeffs[k], iModelBits);
+                        pCoeffs[k] = (r1 ^ getBits(pIO, iModelBits)) - (r1 & iMask);
+                    }
+#else // WIN32
+                    if (pCoeffs[k] > 0) {
+                        pCoeffs[k] <<= iModelBits;
+                        pCoeffs[k] += getBits (pIO, iModelBits);
+                    }
+                    else if (pCoeffs[k] < 0) {
+                        pCoeffs[k] <<= iModelBits;
+                        pCoeffs[k] -= getBits (pIO, iModelBits);
+                    }
+#endif // WIN32
+                    else {
+                        //pCoeffs[k] = getBits (pIO, iModelBits);
+                        //if (pCoeffs[k] && _getBool16 (pIO))
+                        //    pCoeffs[k] = -pCoeffs[k];
+                        Int r1 = _peekBit16 (pIO, iModelBits + 1);
+                        pCoeffs[k] = ((r1 >> 1) ^ (-(r1 & 1))) + (r1 & 1);
+                        _flushBit16 (pIO, iModelBits + (pCoeffs[k] != 0));
+                    }
+                }
+            }
+        }
+        pLM = aLaplacianMean + 1;
+        iModelBits = pContext->m_aModelLP.m_iFlcBits[1];
+
+        iCBP >>= 1;
+    }
+
+    UpdateModelMB (cf, iChannels, aLaplacianMean, &(pContext->m_aModelLP));
+
+    if (pSC->m_bResetContext) {
+        AdaptLowpassDec(pContext);
+    }
+
+    return ICERR_OK;
+}
+
+/*************************************************************************
+    8 bit YUV 420 macroblock decode function with 4x4 transform
+    Index order is as follows:
+    Y:              U:      V:
+     0  1  4  5     16 17   20 21
+     2  3  6  7     18 19   22 23
+     8  9 12 13
+    10 11 14 15
+
+    DCAC coefficients stored for 4x4 - offsets (x == no storage)
+    Y:
+    x x x [0..3]
+    x x x [4..7]
+    x x x [8..11]
+    [16..19] [20..23] [24..27] [28..31,12..15]
+
+    U, V:
+    x [0..3]
+    [8..11] [4..7,12..15]
+*************************************************************************/
+Int DecodeMacroblockDC(CWMImageStrCodec * pSC, CCodingContext *pContext, Int iMBX, Int iMBY)
+{
+    CWMITile * pTile = pSC->pTile + pSC->cTileColumn;
+    CWMIMBInfo * pMBInfo = &pSC->MBInfo;
+    const COLORFORMAT cf = pSC->m_param.cfColorFormat;
+    const Int iChannels = (Int) pSC->m_param.cNumChannels;
+    BitIOInfo* pIO = pContext->m_pIODC;
+    Int iIndex, i;
+    Int aLaplacianMean[2] = { 0, 0}, *pLM = aLaplacianMean;
+    Int iModelBits = pContext->m_aModelDC.m_iFlcBits[0];
+    struct CAdaptiveHuffman *pAH;
+    Int iQDCY, iQDCU, iQDCV;
+    // const Int iChromaElements = (cf == YUV_420) ? 8 * 8 : ((cf == YUV_422) ? 8 * 16 : 16 * 16);
+
+    UNREFERENCED_PARAMETER( iMBX );
+    UNREFERENCED_PARAMETER( iMBY );
+
+    for (i = 0; i < iChannels; i++)
+        memset (pMBInfo->iBlockDC[i], 0, 16 * sizeof (I32));
+
+    readIS_L1(pSC, pIO);
+
+    pMBInfo->iQIndexLP = pMBInfo->iQIndexHP = 0;
+
+    if(pSC->WMISCP.bfBitstreamFormat == SPATIAL && pSC->WMISCP.sbSubband != SB_DC_ONLY){
+        if(pTile->cBitsLP > 0)  // MB-based LP QP index
+            pMBInfo->iQIndexLP = decodeQPIndex(pIO, pTile->cBitsLP);
+        if( pSC->WMISCP.sbSubband != SB_NO_HIGHPASS && pTile->cBitsHP > 0)  // MB-based HP QP index
+            pMBInfo->iQIndexHP = decodeQPIndex(pIO, pTile->cBitsHP);
+    }
+    if(pTile->cBitsHP == 0 && pTile->cNumQPHP > 1) // use LP QP
+        pMBInfo->iQIndexHP = pMBInfo->iQIndexLP;
+    if (pMBInfo->iQIndexLP >= pTile->cNumQPLP || pMBInfo->iQIndexHP >= pTile->cNumQPHP)
+        return ICERR_ERROR;
+
+    if(cf == Y_ONLY || cf == CMYK || cf == NCOMPONENT) {
+        for (i = 0; i < iChannels; i++) {
+            iQDCY = 0;
+            /** get luminance DC **/
+            if (_getBool16 (pIO)) {
+                iQDCY = DecodeSignificantAbsLevel(pContext->m_pAHexpt[3], pIO) - 1;
+                *pLM += 1;
+            }
+            if (iModelBits) {
+                iQDCY = (iQDCY << iModelBits) | _getBit16(pIO, iModelBits);
+            }
+            if (iQDCY && _getBool16 (pIO))
+                iQDCY = -iQDCY;
+            pMBInfo->iBlockDC[i][0] = iQDCY;
+
+            pLM = aLaplacianMean + 1;
+            iModelBits = pContext->m_aModelDC.m_iFlcBits[1];
+        }
+    }
+    else {
+        /** find significant level in 3D **/
+        pAH = pContext->m_pAHexpt[2];
+        iIndex = getHuff (pAH->m_hufDecTable, pIO);
+        iQDCY = iIndex >> 2;
+        iQDCU = (iIndex >> 1) & 1;
+        iQDCV = iIndex & 1;
+
+        /** get luminance DC **/
+        if (iQDCY) {
+            iQDCY = DecodeSignificantAbsLevel(pContext->m_pAHexpt[3], pIO) - 1;
+            *pLM += 1;
+        }
+        if (iModelBits) {
+            iQDCY = (iQDCY << iModelBits) | _getBit16(pIO, iModelBits);
+        }
+        if (iQDCY && _getBool16 (pIO))
+            iQDCY = -iQDCY;
+        pMBInfo->iBlockDC[0][0] = iQDCY;
+
+        /** get chrominance DC **/        
+        pLM = aLaplacianMean + 1;
+        iModelBits = pContext->m_aModelDC.m_iFlcBits[1];
+
+        if (iQDCU) {
+            iQDCU = DecodeSignificantAbsLevel(pContext->m_pAHexpt[4], pIO) - 1;
+            *pLM += 1;
+        }
+        if (iModelBits) {
+            iQDCU = (iQDCU << iModelBits) | _getBit16(pIO, iModelBits);
+        }
+        if (iQDCU && _getBool16 (pIO))
+            iQDCU = -iQDCU;
+        pMBInfo->iBlockDC[1][0] = iQDCU;
+
+        if (iQDCV) {
+            iQDCV = DecodeSignificantAbsLevel(pContext->m_pAHexpt[4], pIO) - 1;
+            *pLM += 1;
+        }
+        if (iModelBits) {
+            iQDCV = (iQDCV << iModelBits) | _getBit16(pIO, iModelBits);
+        }
+        if (iQDCV && _getBool16 (pIO))
+            iQDCV = -iQDCV;
+        pMBInfo->iBlockDC[2][0] = iQDCV;
+    }
+
+    UpdateModelMB (cf, iChannels, aLaplacianMean, &(pContext->m_aModelDC));
+    
+    if(((!(pSC->WMISCP.bfBitstreamFormat != FREQUENCY || pSC->m_Dparam->cThumbnailScale < 16)) || pSC->WMISCP.sbSubband == SB_DC_ONLY) && pSC->m_bResetContext){
+        Int kk;
+        for (kk = 2; kk < 5; kk++) {
+            if (ICERR_OK != AdaptDecFixed (pContext->m_pAHexpt[kk])) {
+                return ICERR_ERROR;
+            }
+        }
+    }
+
+    return ICERR_OK;
+}
+
+/*************************************************************************
+    DecodeMacroblockHighpass
+*************************************************************************/
+Int DecodeMacroblockHighpass (CWMImageStrCodec *pSC, CCodingContext *pContext, 
+                      Int iMBX, Int iMBY)
+{   
+    /** reset adaptive scan totals **/
+    if (pSC->m_bResetRGITotals) {
+        int iScale = 2, k;
+        int iWeight = iScale * 16;
+        pContext->m_aScanHoriz[0].uTotal = pContext->m_aScanVert[0].uTotal = MAXTOTAL;
+        for (k = 1; k < 16; k++) {
+            pContext->m_aScanHoriz[k].uTotal = pContext->m_aScanVert[k].uTotal = iWeight;
+            iWeight -= iScale;
+        }
+    }
+    if((pSC->WMISCP.bfBitstreamFormat != SPATIAL) && (pSC->pTile[pSC->cTileColumn].cBitsHP > 0)) { // MB-based HP QP index
+        pSC->MBInfo.iQIndexHP = decodeQPIndex(pContext->m_pIOAC, pSC->pTile[pSC->cTileColumn].cBitsHP);
+        if (pSC->MBInfo.iQIndexHP >= pSC->pTile[pSC->cTileColumn].cNumQPHP)
+            goto ErrorExit;
+    }
+    else if(pSC->pTile[pSC->cTileColumn].cBitsHP == 0 && pSC->pTile[pSC->cTileColumn].cNumQPHP > 1) // use LP QP
+        pSC->MBInfo.iQIndexHP = pSC->MBInfo.iQIndexLP;
+
+
+    DecodeCBP (pSC, pContext);
+    predCBPDec(pSC, pContext);
+
+    if (DecodeCoeffs (pSC, pContext, iMBX, iMBY, 
+        pContext->m_pIOAC, pContext->m_pIOFL) != ICERR_OK)
+        goto ErrorExit;
+
+    if (pSC->m_bResetContext) {
+        AdaptHighpassDec(pContext);
+    }
+
+    return ICERR_OK;
+ErrorExit:
+    return ICERR_ERROR;
+}
+
+/*************************************************************************
+    Adapt
+*************************************************************************/
+Int AdaptLowpassDec(CCodingContext * pSC)
+{
+    Int kk;
+    for (kk = 0; kk < CONTEXTX + CTDC; kk++) {
+        if (ICERR_OK != AdaptDecFixed (pSC->m_pAHexpt[kk])) {
+            goto ErrorExit;
+        }
+    }
+    return ICERR_OK;
+
+ErrorExit:
+    return ICERR_ERROR;
+
+}
+
+Int AdaptHighpassDec(CCodingContext * pSC)
+{
+    Int kk;
+    if (ICERR_OK != AdaptDecFixed (pSC->m_pAdaptHuffCBPCY)) {
+        goto ErrorExit;
+    }
+    if (ICERR_OK != AdaptDecFixed (pSC->m_pAdaptHuffCBPCY1)) {
+        goto ErrorExit;
+    }
+    for (kk = 0; kk < CONTEXTX; kk++) {
+        if (ICERR_OK != AdaptDecFixed (pSC->m_pAHexpt[kk + CONTEXTX + CTDC])) {
+            goto ErrorExit;
+        }
+    }
+
+    return ICERR_OK;
+    
+ErrorExit:
+    return ICERR_ERROR;
+}
diff --git a/Source/LibJXR/image/decode/strInvTransform.c b/Source/LibJXR/image/decode/strInvTransform.c
new file mode 100644
index 0000000..7cd982a
--- /dev/null
+++ b/Source/LibJXR/image/decode/strInvTransform.c
@@ -0,0 +1,1888 @@
+//*@@@+++@@@@******************************************************************
+//
+// Copyright � Microsoft Corp.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+// � Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// � Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//*@@@---@@@@******************************************************************
+
+#include "strTransform.h"
+#include "strcodec.h"
+#include "decode.h"
+
+/** rotation by -pi/8 **/
+#define IROTATE1(a, b) (a) -= (((b) + 1) >> 1), (b) += (((a) + 1) >> 1)  // this works well too
+#define IROTATE2(a, b) (a) -= (((b)*3 + 4) >> 3), (b) += (((a)*3 + 4) >> 3)  // this works well too
+
+/** local functions **/
+static Void invOddOdd(PixelI *, PixelI *, PixelI *, PixelI *);
+static Void invOddOddPost(PixelI *, PixelI *, PixelI *, PixelI *);
+static Void invOdd(PixelI *, PixelI *, PixelI *, PixelI *);
+static Void strHSTdec(PixelI *, PixelI *, PixelI *, PixelI *);
+static Void strHSTdec1(PixelI *, PixelI *);
+static Void strHSTdec1_alternate(PixelI *, PixelI *);
+static Void strHSTdec1_edge(PixelI *pa, PixelI *pd);
+
+/** IDCT stuff **/
+/** reordering should be combined with zigzag scan **/
+/** data order before IDCT **/
+/** 0  8  4  6 **/
+/** 2 10 14 12 **/
+/** 1 11 15 13 **/
+/** 9  3  7  5 **/
+/** data order after IDCT **/
+/**  0  1  2  3 **/
+/**  4  5  6  7 **/
+/**  8  9 10 11 **/
+/** 12 13 14 15 **/
+Void strIDCT4x4Stage1(PixelI* p)
+{
+    /** top left corner, butterfly => butterfly **/
+    strDCT2x2up(p + 0, p + 1, p + 2, p + 3);
+
+    /** top right corner, -pi/8 rotation => butterfly **/
+    invOdd(p + 5, p + 4, p + 7, p + 6);
+
+    /** bottom left corner, butterfly => -pi/8 rotation **/
+    invOdd(p + 10, p + 8, p + 11, p + 9);
+
+    /** bottom right corner, -pi/8 rotation => -pi/8 rotation **/
+    invOddOdd(p + 15, p + 14, p + 13, p + 12);
+    
+    /** butterfly **/
+    //FOURBUTTERFLY(p, 0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15);
+    FOURBUTTERFLY_HARDCODED1(p);
+}
+
+Void strIDCT4x4Stage2(PixelI* p)
+{
+    /** bottom left corner, butterfly => -pi/8 rotation **/
+    invOdd(p + 32, p + 48, p + 96, p + 112);
+    
+    /** top right corner, -pi/8 rotation => butterfly **/
+    invOdd(p + 128, p + 192, p + 144, p + 208);
+    
+    /** bottom right corner, -pi/8 rotation => -pi/8 rotation **/
+    invOddOdd(p + 160, p + 224, p + 176, p + 240);
+
+    /** top left corner, butterfly => butterfly **/
+    strDCT2x2up(p + 0, p + 64, p + 16, p + 80);
+    
+    /** butterfly **/
+    FOURBUTTERFLY(p, 0, 192, 48, 240, 64, 128, 112, 176, 16, 208, 32, 224, 80, 144, 96, 160);
+}
+
+Void strNormalizeDec(PixelI* p, Bool bChroma)
+{
+    int i;
+    if (!bChroma) {
+        //for (i = 0; i < 256; i += 16) {
+        //    p[i] <<= 2;
+        //}
+    }
+    else {
+        for (i = 0; i < 256; i += 16) {
+            p[i] += p[i];
+        }
+    }
+}
+
+/** 2x2 DCT with post-scaling - for use on decoder side **/
+Void strDCT2x2dnDec(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd)
+{
+    PixelI a, b, c, d, C, t;
+    a = *pa;
+    b = *pb;
+    C = *pc;
+    d = *pd;
+  
+    a += d;
+    b -= C;
+    t = ((a - b) >> 1);
+    c = t - d;
+    d = t - C;
+    a -= d;
+    b += c;
+
+    *pa = a * 2;
+    *pb = b * 2;
+    *pc = c * 2;
+    *pd = d * 2;
+}
+
+
+/** post filter stuff **/
+/** 2-point post for boundaries **/
+Void strPost2(PixelI * a, PixelI * b)
+{
+    *b += ((*a + 4) >> 3);
+    *a += ((*b + 2) >> 2);
+    *b += ((*a + 4) >> 3);
+}
+
+Void strPost2_alternate(PixelI * pa, PixelI * pb)
+{
+    PixelI a, b;
+    a = *pa;
+    b = *pb;
+
+    /** rotate **/
+    b += ((a + 2) >> 2);
+    a += ((b + 1) >> 1);
+    a += (b >> 5);
+    a += (b >> 9);
+    a += (b >> 13);
+
+    b += ((a + 2) >> 2);
+
+    *pa = a;
+    *pb = b;
+}
+
+Void strPost2x2(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd)
+{
+    PixelI a, b, c, d;
+    a = *pa;
+    b = *pb;
+    c = *pc;
+    d = *pd;
+
+    /** butterflies **/
+    a += d;
+    b += c;
+    d -= (a + 1) >> 1;
+    c -= (b + 1) >> 1;
+
+    /** rotate **/
+    b += ((a + 2) >> 2);
+    a += ((b + 1) >> 1);
+    b += ((a + 2) >> 2);
+
+    /** butterflies **/
+    d += (a + 1) >> 1;
+    c += (b + 1) >> 1;
+    a -= d;
+    b -= c;
+
+    *pa = a;
+    *pb = b;
+    *pc = c;
+    *pd = d;
+}
+
+Void strPost2x2_alternate(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd)
+{
+    PixelI a, b, c, d;
+    a = *pa;
+    b = *pb;
+    c = *pc;
+    d = *pd;
+
+    /** butterflies **/
+    a += d;
+    b += c;
+    d -= (a + 1) >> 1;
+    c -= (b + 1) >> 1;
+
+    /** rotate **/
+    b += ((a + 2) >> 2);
+    a += ((b + 1) >> 1);
+    a += (b >> 5);
+    a += (b >> 9);
+    a += (b >> 13);
+    b += ((a + 2) >> 2);
+
+    /** butterflies **/
+    d += (a + 1) >> 1;
+    c += (b + 1) >> 1;
+    a -= d;
+    b -= c;
+
+    *pa = a;
+    *pb = b;
+    *pc = c;
+    *pd = d;
+}
+
+/** 4-point post for boundaries **/
+Void strPost4(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd)
+{
+    PixelI a, b, c, d;
+    a = *pa;
+    b = *pb;
+    c = *pc;
+    d = *pd;
+
+    a += d, b += c;
+    d -= ((a + 1) >> 1), c -= ((b + 1) >> 1);
+    
+    IROTATE1(c, d);
+
+    d += ((a + 1) >> 1), c += ((b + 1) >> 1);
+    a -= d - ((d * 3 + 16) >> 5), b -= c - ((c * 3 + 16) >> 5);
+    d += ((a * 3 + 8) >> 4), c += ((b * 3 + 8) >> 4);
+    a += ((d * 3 + 16) >> 5), b += ((c * 3 + 16) >> 5);
+
+    *pa = a;
+    *pb = b;
+    *pc = c;
+    *pd = d;
+}
+
+Void strPost4_alternate(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd)
+{
+    PixelI a, b, c, d;
+    a = *pa;
+    b = *pb;
+    c = *pc;
+    d = *pd;
+
+    a += d, b += c;
+    d -= ((a + 1) >> 1), c -= ((b + 1) >> 1);
+    
+    strHSTdec1_edge(&a, &d); strHSTdec1_edge(&b, &c);
+    IROTATE1(c, d);
+    d += ((a + 1) >> 1), c += ((b + 1) >> 1);
+
+    a -= d, b -= c;
+
+    *pa = a;
+    *pb = b;
+    *pc = c;
+    *pd = d;
+}
+
+/*****************************************************************************************
+  Input data offsets:
+  (15)(14)|(10+64)(11+64) p0 (15)(14)|(74)(75)
+  (13)(12)|( 8+64)( 9+64)    (13)(12)|(72)(73)
+  --------+--------------    --------+--------
+  ( 5)( 4)|( 0+64) (1+64) p1 ( 5)( 4)|(64)(65)
+  ( 7)( 6)|( 2+64) (3+64)    ( 7)( 6)|(66)(67)
+*****************************************************************************************/
+Void DCCompensate (PixelI *a, PixelI *b, PixelI *c, PixelI *d, int iDC)
+{
+    iDC = iDC>>1;
+    *a -= iDC;
+    *d -= iDC;
+    *b += iDC;
+    *c += iDC;
+}
+
+#ifndef max
+#define max(a,b)            (((a) > (b)) ? (a) : (b))
+#endif
+
+#ifndef min
+#define min(a,b)            (((a) < (b)) ? (a) : (b))
+#endif
+
+int ClipDCL(int iDCL, int iAltDCL)
+{
+    int iClipDCL = 0;
+    if (iDCL > 0) {
+        if (iAltDCL > 0)
+            iClipDCL = min(iDCL, iAltDCL);
+        else
+            iClipDCL = 0;
+    }
+    else if (iDCL < 0) {
+        if (iAltDCL < 0)
+            iClipDCL = max(iDCL, iAltDCL);
+        else
+            iClipDCL = 0;
+    }
+    return iClipDCL;
+}
+
+Void strPost4x4Stage1Split(PixelI *p0, PixelI *p1, Int iOffset, Int iHPQP, Bool bHPAbsent)
+{
+    int iDCLAlt1, iDCLAlt2, iDCLAlt3, iDCLAlt0;
+    int iDCL1, iDCL2, iDCL3, iDCL0;
+    int iTmp1, iTmp2, iTmp3, iTmp0;
+
+    PixelI *p2 = p0 + 72 - iOffset;
+    PixelI *p3 = p1 + 64 - iOffset;
+    p0 += 12;
+    p1 += 4;
+
+    /** buttefly **/
+    strDCT2x2dn(p0 + 0, p2 + 0, p1 + 0, p3 + 0);
+    strDCT2x2dn(p0 + 1, p2 + 1, p1 + 1, p3 + 1);
+    strDCT2x2dn(p0 + 2, p2 + 2, p1 + 2, p3 + 2);
+    strDCT2x2dn(p0 + 3, p2 + 3, p1 + 3, p3 + 3);
+
+    /** bottom right corner: -pi/8 rotation => -pi/8 rotation **/
+    invOddOddPost(p3 + 0, p3 + 1, p3 + 2, p3 + 3);
+    
+    /** anti diagonal corners: rotation by -pi/8 **/
+    IROTATE1(p1[2], p1[3]);
+    IROTATE1(p1[0], p1[1]);
+    IROTATE1(p2[1], p2[3]);
+    IROTATE1(p2[0], p2[2]);
+
+    /** butterfly **/
+    strHSTdec1(p0 + 0, p3 + 0);
+    strHSTdec1(p0 + 1, p3 + 1);
+    strHSTdec1(p0 + 2, p3 + 2);
+    strHSTdec1(p0 + 3, p3 + 3);
+    strHSTdec(p0 + 0, p2 + 0, p1 + 0, p3 + 0);
+    strHSTdec(p0 + 1, p2 + 1, p1 + 1, p3 + 1);
+    strHSTdec(p0 + 2, p2 + 2, p1 + 2, p3 + 2);
+    strHSTdec(p0 + 3, p2 + 3, p1 + 3, p3 + 3);
+
+    iTmp0 = (*(p0 +0) + *(p1 +0) + *(p2 +0) + *(p3 +0))>>1;
+    iTmp1 = (*(p0 +1) + *(p1 +1) + *(p2 +1) + *(p3 +1))>>1;
+    iTmp2 = (*(p0 +2) + *(p1 +2) + *(p2 +2) + *(p3 +2))>>1;
+    iTmp3 = (*(p0 +3) + *(p1 +3) + *(p2 +3) + *(p3 +3))>>1;
+    iDCL0 = (iTmp0 * 595 + 65536)>>17; //Approximating 27/5947
+    iDCL1 = (iTmp1 * 595 + 65536)>>17; 
+    iDCL2 = (iTmp2 * 595 + 65536)>>17; 
+    iDCL3 = (iTmp3 * 595 + 65536)>>17; 
+    if ((abs(iDCL0) < iHPQP && iHPQP > 20) || bHPAbsent) {
+        iDCLAlt0 = (*(p0 +0) - *(p1 +0) - *(p2 +0) + *(p3 +0))>>1;
+        iDCL0 = ClipDCL (iDCL0, iDCLAlt0);
+        DCCompensate (p0 + 0, p2 + 0, p1 + 0, p3 + 0, iDCL0);
+    }
+    if ((abs(iDCL1) < iHPQP && iHPQP > 20) || bHPAbsent) {
+            iDCLAlt1 = (*(p0 +1) - *(p1 +1) - *(p2 +1) + *(p3 +1))>>1;
+            iDCL1 = ClipDCL (iDCL1, iDCLAlt1);
+        DCCompensate (p0 + 1, p2 + 1, p1 + 1, p3 + 1, iDCL1);
+    }
+    if ((abs(iDCL2) < iHPQP && iHPQP > 20) || bHPAbsent) {
+            iDCLAlt2 = (*(p0 +2) - *(p1 +2) - *(p2 +2) + *(p3 +2))>>1;
+            iDCL2 = ClipDCL (iDCL2, iDCLAlt2);
+        DCCompensate (p0 + 2, p2 + 2, p1 + 2, p3 + 2, iDCL2);
+    }
+    if ((abs(iDCL3) < iHPQP && iHPQP > 20) || bHPAbsent) {
+            iDCLAlt3 = (*(p0 +3) - *(p1 +3) - *(p2 +3) + *(p3 +3))>>1;
+            iDCL3 = ClipDCL (iDCL3, iDCLAlt3);
+        DCCompensate (p0 + 3, p2 + 3, p1 + 3, p3 + 3, iDCL3);
+    }
+}
+
+Void strPost4x4Stage1(PixelI* p, Int iOffset, Int iHPQP, Bool bHPAbsent)
+{
+    strPost4x4Stage1Split(p, p + 16, iOffset, iHPQP, bHPAbsent);
+}
+
+Void strPost4x4Stage1Split_alternate(PixelI *p0, PixelI *p1, Int iOffset)
+{
+    PixelI *p2 = p0 + 72 - iOffset;
+    PixelI *p3 = p1 + 64 - iOffset;
+    p0 += 12;
+    p1 += 4;
+
+    /** buttefly **/
+    strDCT2x2dn(p0 + 0, p2 + 0, p1 + 0, p3 + 0);
+    strDCT2x2dn(p0 + 1, p2 + 1, p1 + 1, p3 + 1);
+    strDCT2x2dn(p0 + 2, p2 + 2, p1 + 2, p3 + 2);
+    strDCT2x2dn(p0 + 3, p2 + 3, p1 + 3, p3 + 3);
+
+    /** bottom right corner: -pi/8 rotation => -pi/8 rotation **/
+    invOddOddPost(p3 + 0, p3 + 1, p3 + 2, p3 + 3);
+    
+    /** anti diagonal corners: rotation by -pi/8 **/
+    IROTATE1(p1[2], p1[3]);
+    IROTATE1(p1[0], p1[1]);
+    IROTATE1(p2[1], p2[3]);
+    IROTATE1(p2[0], p2[2]);
+
+    /** butterfly **/
+    strHSTdec1_alternate(p0 + 0, p3 + 0);
+    strHSTdec1_alternate(p0 + 1, p3 + 1);
+    strHSTdec1_alternate(p0 + 2, p3 + 2);
+    strHSTdec1_alternate(p0 + 3, p3 + 3);
+    strHSTdec(p0 + 0, p2 + 0, p1 + 0, p3 + 0);
+    strHSTdec(p0 + 1, p2 + 1, p1 + 1, p3 + 1);
+    strHSTdec(p0 + 2, p2 + 2, p1 + 2, p3 + 2);
+    strHSTdec(p0 + 3, p2 + 3, p1 + 3, p3 + 3);
+}
+
+Void strPost4x4Stage1_alternate(PixelI* p, Int iOffset)
+{
+    strPost4x4Stage1Split_alternate(p, p + 16, iOffset);
+}
+
+/*****************************************************************************************
+  Input data offsets:
+  (15)(14)|(10+32)(11+32) p0 (15)(14)|(42)(43)
+  (13)(12)|( 8+32)( 9+32)    (13)(12)|(40)(41)
+  --------+--------------    --------+--------
+  ( 5)( 4)|( 0+32) (1+32) p1 ( 5)( 4)|(32)(33)
+  ( 7)( 6)|( 2+32) (3+32)    ( 7)( 6)|(34)(35)
+*****************************************************************************************/
+
+/*****************************************************************************************
+  Input data offsets:
+  ( -96)(-32)|(32)( 96) p0
+  ( -80)(-16)|(48)(112)
+  -----------+------------
+  (-128)(-64)|( 0)( 64) p1
+  (-112)(-48)|(16)( 80)
+*****************************************************************************************/
+Void strPost4x4Stage2Split(PixelI* p0, PixelI* p1)
+{
+    /** buttefly **/
+    strDCT2x2dn(p0 - 96, p0 +  96, p1 - 112, p1 + 80);
+    strDCT2x2dn(p0 - 32, p0 +  32, p1 -  48, p1 + 16);
+    strDCT2x2dn(p0 - 80, p0 + 112, p1 - 128, p1 + 64);
+    strDCT2x2dn(p0 - 16, p0 +  48, p1 -  64, p1 +  0);
+
+    /** bottom right corner: -pi/8 rotation => -pi/8 rotation **/
+    invOddOddPost(p1 + 0, p1 + 64, p1 + 16, p1 + 80);
+    
+    /** anti diagonal corners: rotation by -pi/8 **/
+    IROTATE1(p0[ 48], p0[  32]);
+    IROTATE1(p0[112], p0[  96]);
+    IROTATE1(p1[-64], p1[-128]);
+    IROTATE1(p1[-48], p1[-112]);
+    
+    /** butterfly **/
+    strHSTdec1(p0 - 96, p1 + 80);
+    strHSTdec1(p0 - 32, p1 + 16);
+    strHSTdec1(p0 - 80, p1 + 64);
+    strHSTdec1(p0 - 16, p1 +  0);
+
+    strHSTdec(p0 - 96, p1 - 112, p0 +  96, p1 + 80);
+    strHSTdec(p0 - 32, p1 -  48, p0 +  32, p1 + 16);
+    strHSTdec(p0 - 80, p1 - 128, p0 + 112, p1 + 64);
+    strHSTdec(p0 - 16, p1 -  64, p0 +  48, p1 +  0);
+}
+
+Void strPost4x4Stage2Split_alternate(PixelI* p0, PixelI* p1)
+{
+    /** buttefly **/
+    strDCT2x2dn(p0 - 96, p0 +  96, p1 - 112, p1 + 80);
+    strDCT2x2dn(p0 - 32, p0 +  32, p1 -  48, p1 + 16);
+    strDCT2x2dn(p0 - 80, p0 + 112, p1 - 128, p1 + 64);
+    strDCT2x2dn(p0 - 16, p0 +  48, p1 -  64, p1 +  0);
+
+    /** bottom right corner: -pi/8 rotation => -pi/8 rotation **/
+    invOddOddPost(p1 + 0, p1 + 64, p1 + 16, p1 + 80);
+    
+    /** anti diagonal corners: rotation by -pi/8 **/
+    IROTATE1(p0[ 48], p0[  32]);
+    IROTATE1(p0[112], p0[  96]);
+    IROTATE1(p1[-64], p1[-128]);
+    IROTATE1(p1[-48], p1[-112]);
+    
+    /** butterfly **/
+    strHSTdec1_alternate(p0 - 96, p1 + 80);
+    strHSTdec1_alternate(p0 - 32, p1 + 16);
+    strHSTdec1_alternate(p0 - 80, p1 + 64);
+    strHSTdec1_alternate(p0 - 16, p1 +  0);
+
+    strHSTdec(p0 - 96, p1 - 112, p0 +  96, p1 + 80);
+    strHSTdec(p0 - 32, p1 -  48, p0 +  32, p1 + 16);
+    strHSTdec(p0 - 80, p1 - 128, p0 + 112, p1 + 64);
+    strHSTdec(p0 - 16, p1 -  64, p0 +  48, p1 +  0);
+}
+
+/** 
+    Hadamard+Scale transform
+    for some strange reason, breaking up the function into two blocks, strHSTdec1 and strHSTdec
+    seems to work faster
+**/
+static Void strHSTdec1(PixelI *pa, PixelI *pd)
+{
+    /** different realization : does rescaling as well! **/
+    PixelI a, d;
+    a = *pa;
+    d = *pd;
+
+    a += d;
+    d = (a >> 1) - d;
+    a += (d * 3 + 0) >> 3;
+    d += (a * 3 + 0) >> 4;
+    //a += (d * 3 + 4) >> 3;
+
+    *pa = a;
+    *pd = d;
+}
+
+static Void strHSTdec1_alternate(PixelI *pa, PixelI *pd)
+{
+    /** different realization : does rescaling as well! **/
+    PixelI a, d;
+    a = *pa;
+    d = *pd;
+
+    a += d;
+    d = (a >> 1) - d;
+    a += (d * 3 + 0) >> 3;
+    d += (a * 3 + 0) >> 4;
+    //a += (d * 3 + 4) >> 3;
+
+    d += (a >> 7);
+    d -= (a >> 10);
+
+    *pa = a;
+    *pd = d;
+}
+
+static Void strHSTdec1_edge (PixelI *pa, PixelI *pd)
+{
+    /** different realization as compared to scaling operator for 2D case **/
+    PixelI a, d;
+    a = *pa;
+    d = *pd;
+
+    a += d;
+    d = (a >> 1) - d;
+    a += (d * 3 + 0) >> 3;
+    d += (a * 3 + 0) >> 4;
+
+    //Scaling modification of adding 7/1024 in 2 steps (without multiplication by 7).
+    d += (a >> 7);
+    d -= (a >> 10);
+
+    a += (d * 3 + 4) >> 3;
+    d -= (a >> 1);
+    a += d;
+    // End new operations
+
+    *pa = a;
+    *pd = -d; // Negative sign needed here for 1D scaling case to ensure correct scaling.
+}
+
+static Void strHSTdec(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd)
+{
+    /** different realization : does rescaling as well! **/
+    PixelI a, b, c, d;
+    a = *pa;
+    b = *pb;
+    c = *pc;
+    d = *pd;
+
+    b -= c;
+    a += (d * 3 + 4) >> 3;
+
+    d -= (b >> 1);
+    c = ((a - b) >> 1) - c;
+    *pc = d;
+    *pd = c;
+    *pa = a - c, *pb = b + d;
+}
+
+/** Kron(Rotate(pi/8), Rotate(pi/8)) **/
+static Void invOddOdd(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd)
+{
+    PixelI a, b, c, d, t1, t2;
+    a = *pa;
+    b = *pb;
+    c = *pc;
+    d = *pd;
+
+    /** butterflies **/
+    d += a;
+    c -= b;
+    a -= (t1 = d >> 1);
+    b += (t2 = c >> 1);
+
+    /** rotate pi/4 **/
+    a -= (b * 3 + 3) >> 3;
+    b += (a * 3 + 3) >> 2;
+    a -= (b * 3 + 4) >> 3;
+
+    /** butterflies **/
+    b -= t2;
+    a += t1;
+    c += b;
+    d -= a;
+
+    /** sign flips **/
+    *pa = a;
+    *pb = -b;
+    *pc = -c;
+    *pd = d;
+}
+
+/** Kron(Rotate(pi/8), Rotate(pi/8)) **/
+static Void invOddOddPost(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd)
+{
+    PixelI a, b, c, d, t1, t2;
+    a = *pa;
+    b = *pb;
+    c = *pc;
+    d = *pd;
+
+    /** butterflies **/
+    d += a;
+    c -= b;
+    a -= (t1 = d >> 1);
+    b += (t2 = c >> 1);
+
+    /** rotate pi/4 **/
+    a -= (b * 3 + 6) >> 3;
+    b += (a * 3 + 2) >> 2;
+    a -= (b * 3 + 4) >> 3;
+
+    /** butterflies **/
+    b -= t2;
+    a += t1;
+    c += b;
+    d -= a;
+
+    *pa = a;
+    *pb = b;
+    *pc = c;
+    *pd = d;
+}
+
+
+/** Kron(Rotate(-pi/8), [1 1; 1 -1]/sqrt(2)) **/
+/** [D C A B] => [a b c d] **/
+Void invOdd(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd)
+{
+    PixelI a, b, c, d;
+    a = *pa;
+    b = *pb;
+    c = *pc;
+    d = *pd;
+
+    /** butterflies **/
+    b += d;
+    a -= c;
+    d -= (b) >> 1;
+    c += (a + 1) >> 1;
+
+    /** rotate pi/8 **/
+    IROTATE2(a, b);
+    IROTATE2(c, d);
+
+    /** butterflies **/
+    c -= (b + 1) >> 1;
+    d = ((a + 1) >> 1) - d;
+    b += c;
+    a -= d;
+
+    *pa = a;
+    *pb = b;
+    *pc = c;
+    *pd = d;
+}
+
+/*************************************************************************
+  Top-level function to inverse tranform possible part of a macroblock
+*************************************************************************/
+Int  invTransformMacroblock(CWMImageStrCodec * pSC)
+{
+    const OVERLAP olOverlap = pSC->WMISCP.olOverlap;
+    const COLORFORMAT cfColorFormat = pSC->m_param.cfColorFormat;
+    // const BITDEPTH_BITS bdBitDepth = pSC->WMII.bdBitDepth;
+    const Bool left = (pSC->cColumn == 0), right = (pSC->cColumn == pSC->cmbWidth);
+    const Bool top = (pSC->cRow == 0), bottom = (pSC->cRow == pSC->cmbHeight);
+    const Bool topORbottom = (top || bottom), leftORright = (left || right);
+    const Bool topORleft = (top || left), bottomORright = (bottom || right);
+    const size_t mbWidth = pSC->cmbWidth, mbX = pSC->cColumn;
+    PixelI * p = NULL;// * pt = NULL;
+    size_t i;
+    const size_t iChannels = (cfColorFormat == YUV_420 || cfColorFormat == YUV_422) ? 1 : pSC->m_param.cNumChannels;
+    const size_t tScale = pSC->m_Dparam->cThumbnailScale;
+    Int j = 0;
+
+    Int qp[MAX_CHANNELS], dcqp[MAX_CHANNELS], iStrength = (1 << pSC->WMII.cPostProcStrength);
+    // ERR_CODE result = ICERR_OK;
+
+    Bool bHPAbsent = (pSC->WMISCP.sbSubband == SB_NO_HIGHPASS || pSC->WMISCP.sbSubband == SB_DC_ONLY);
+
+    if(pSC->WMII.cPostProcStrength > 0){
+        // threshold for post processing
+        for(i = 0; i < iChannels; i ++){
+            qp[i] = pSC->pTile[pSC->cTileColumn].pQuantizerLP[i][pSC->MBInfo.iQIndexLP].iQP * iStrength * (olOverlap == OL_NONE ? 2 : 1);
+            dcqp[i] = pSC->pTile[pSC->cTileColumn].pQuantizerDC[i][0].iQP * iStrength;
+        }
+
+        if(left) // a new MB row
+            slideOneMBRow(pSC->pPostProcInfo, pSC->m_param.cNumChannels, mbWidth, top, bottom);  // previous current row becomes previous row
+    }
+
+    //================================================================
+    // 400_Y, 444_YUV
+    for (i = 0; i < iChannels && tScale < 16; ++i)
+    {
+        PixelI* const p0 = pSC->p0MBbuffer[i];
+        PixelI* const p1 = pSC->p1MBbuffer[i];
+
+        Int iHPQP = 255;
+        if (!bHPAbsent)
+            iHPQP = pSC->pTile[pSC->cTileColumn].pQuantizerHP[i][pSC->MBInfo.iQIndexHP].iQP;
+
+        //================================
+        // second level inverse transform
+        if (!bottomORright)
+        {
+            if(pSC->WMII.cPostProcStrength > 0)
+                updatePostProcInfo(pSC->pPostProcInfo, p1, mbX, i); // update postproc info before IDCT
+
+            strIDCT4x4Stage2(p1);
+            if (pSC->m_param.bScaledArith) {
+                strNormalizeDec(p1, (i != 0));
+            }
+        }
+
+        //================================
+        // second level inverse overlap
+        if (OL_TWO == olOverlap)
+        {
+            if (leftORright && (!topORbottom))
+            {
+                j = left ? 0 : -128;
+                strPost4(p0 + j + 32, p0 + j +  48, p1 + j +  0, p1 + j + 16);
+                strPost4(p0 + j + 96, p0 + j + 112, p1 + j + 64, p1 + j + 80);
+            }
+
+            if (!leftORright)
+            {
+                if (topORbottom)
+                {
+                    p = top ? p1 : p0 + 32;
+                    strPost4(p - 128, p - 64, p +  0, p + 64);
+                    strPost4(p - 112, p - 48, p + 16, p + 80);
+                    p = NULL;
+                }
+                else
+                {
+                    strPost4x4Stage2Split(p0, p1);
+                }
+            }
+        }
+
+        if(pSC->WMII.cPostProcStrength > 0)
+            postProcMB(pSC->pPostProcInfo, p0, p1, mbX, i, dcqp[i]); // second stage deblocking
+
+        //================================
+        // first level inverse transform
+        if(tScale >= 4) // bypass first level transform for 4:1 and smaller thumbnail
+            continue;
+
+        if (!top)
+        {
+            for (j = (left ? 32 : -96); j < (right ? 32 : 160); j += 64)
+            {
+                strIDCT4x4Stage1(p0 + j +  0);
+                strIDCT4x4Stage1(p0 + j + 16);
+            }
+        }
+
+        if (!bottom)
+        {
+            for (j = (left ? 0 : -128); j < (right ? 0 : 128); j += 64)
+            {
+                strIDCT4x4Stage1(p1 + j +  0);
+                strIDCT4x4Stage1(p1 + j + 16);
+            }
+        }
+
+        //================================
+        // first level inverse overlap
+        if (OL_NONE != olOverlap)
+        {
+            if (leftORright)
+            {
+                j = left ? 0 + 10 : -64 + 14;
+                if (!top)
+                {
+                    p = p0 + 16 + j;
+                    strPost4(p +  0, p -  2, p +  6, p +  8);
+                    strPost4(p +  1, p -  1, p +  7, p +  9);
+                    strPost4(p + 16, p + 14, p + 22, p + 24);
+                    strPost4(p + 17, p + 15, p + 23, p + 25);
+                    p = NULL;
+                }
+                if (!bottom)
+                {
+                    p = p1 + j;
+                    strPost4(p + 0, p - 2, p + 6, p + 8);
+                    strPost4(p + 1, p - 1, p + 7, p + 9);
+                    p = NULL;
+                }
+                if (!topORbottom)
+                {
+                    strPost4(p0 + 48 + j + 0, p0 + 48 + j - 2, p1 - 10 + j, p1 - 8 + j);
+                    strPost4(p0 + 48 + j + 1, p0 + 48 + j - 1, p1 -  9 + j, p1 - 7 + j);
+                }
+            }
+
+            if (top)
+            {
+                for (j = (left ? 0 : -192); j < (right ? -64 : 64); j += 64)
+                {
+                    p = p1 + j;
+                    strPost4(p + 5, p + 4, p + 64, p + 65);
+                    strPost4(p + 7, p + 6, p + 66, p + 67);
+                    p = NULL;
+
+                    strPost4x4Stage1(p1 + j, 0, iHPQP, bHPAbsent);
+                }
+            }
+            else if (bottom)
+            {
+                for (j = (left ? 0 : -192); j < (right ? -64 : 64); j += 64)
+                {
+                    strPost4x4Stage1(p0 + 16 + j, 0, iHPQP, bHPAbsent);
+                    strPost4x4Stage1(p0 + 32 + j, 0, iHPQP, bHPAbsent);
+
+                    p = p0 + 48 + j;
+                    strPost4(p + 15, p + 14, p + 74, p + 75);
+                    strPost4(p + 13, p + 12, p + 72, p + 73);
+                    p = NULL;
+                }
+            }
+            else
+            {
+                for (j = (left ? 0 : -192); j < (right ? -64 : 64); j += 64)
+                {
+                    strPost4x4Stage1(p0 + 16 + j, 0, iHPQP, bHPAbsent);
+                    strPost4x4Stage1(p0 + 32 + j, 0, iHPQP, bHPAbsent);
+                    strPost4x4Stage1Split(p0 + 48 + j, p1 + j, 0, iHPQP, bHPAbsent);
+                    strPost4x4Stage1(p1 + j, 0, iHPQP, bHPAbsent);
+                }
+            }
+        }
+        
+        if(pSC->WMII.cPostProcStrength > 0 && (!topORleft))
+            postProcBlock(pSC->pPostProcInfo, p0, p1, mbX, i, qp[i]); // destairing and first stage deblocking
+    }
+
+    //================================================================
+    // 420_UV
+    for (i = 0; i < (YUV_420 == cfColorFormat? 2U : 0U) && tScale < 16; ++i)
+    {
+        PixelI* const p0 = pSC->p0MBbuffer[1 + i];//(0 == i ? pSC->pU0 : pSC->pV0);
+        PixelI* const p1 = pSC->p1MBbuffer[1 + i];//(0 == i ? pSC->pU1 : pSC->pV1);
+
+        Int iHPQP = 255;
+        if (!bHPAbsent)
+            iHPQP = pSC->pTile[pSC->cTileColumn].pQuantizerHP[i][pSC->MBInfo.iQIndexHP].iQP;
+
+        //========================================
+        // second level inverse transform (420_UV)
+        if (!bottomORright)
+        {
+            if (!pSC->m_param.bScaledArith) {
+                strDCT2x2dn(p1, p1 + 32, p1 + 16, p1 + 48);
+            }
+            else {
+                strDCT2x2dnDec(p1, p1 + 32, p1 + 16, p1 + 48);
+            }
+        }
+        
+        //========================================
+        // second level inverse overlap (420_UV)
+        if (OL_TWO == olOverlap)
+        {
+            if (leftORright && !topORbottom)
+            {
+                j = (left ? 0 : -32);
+                strPost2(p0 + j + 16, p1 + j);
+            }
+
+            if (!leftORright)
+            {
+                if (topORbottom)
+                {
+                    p = (top ? p1 : p0 + 16);
+                    strPost2(p - 32, p);
+                    p = NULL;
+                }
+                else{
+                    strPost2x2(p0 - 16, p0 + 16, p1 - 32, p1);
+                }
+            }
+        }
+
+        //========================================
+        // first level inverse transform (420_UV)
+        if(tScale >= 4) // bypass first level transform for 4:1 and smaller thumbnail
+            continue;
+
+        if (!top)
+        {
+            for (j = (left ? 16 : -16); j < (right ? 16 : 48); j += 32)
+            {
+                strIDCT4x4Stage1(p0 + j);
+            }
+        }
+
+        if (!bottom)
+        {
+            for (j = (left ? 0 : -32); j < (right ? 0 : 32); j += 32)
+            {
+                strIDCT4x4Stage1(p1 + j);
+            }
+        }
+
+        //========================================
+        // first level inverse overlap (420_UV)
+        if (OL_NONE != olOverlap)
+        {
+            if(!left && !top)
+            {
+                if (bottom)
+                {
+                    for (j = -48; j < (right ? -16 : 16); j += 32)
+                    {
+                        p = p0 + j;
+                        strPost4(p + 15, p + 14, p + 42, p + 43);
+                        strPost4(p + 13, p + 12, p + 40, p + 41);
+                        p = NULL;
+                    }
+                }
+                else
+                {
+                    for (j = -48; j < (right ? -16 : 16); j += 32)
+                    {
+                        strPost4x4Stage1Split(p0 + j, p1 - 16 + j, 32, iHPQP, bHPAbsent);
+                    }
+                }
+
+                if (right)
+                {
+                    if (!bottom)
+                    {
+                        strPost4(p0 - 2 , p0 - 4 , p1 - 28, p1 - 26);
+                        strPost4(p0 - 1 , p0 - 3 , p1 - 27, p1 - 25);
+                    }
+
+                    strPost4(p0 - 18, p0 - 20, p0 - 12, p0 - 10);
+                    strPost4(p0 - 17, p0 - 19, p0 - 11, p0 -  9);
+                }
+                else
+                {
+                    strPost4x4Stage1(p0 - 32, 32, iHPQP, bHPAbsent);
+                }
+
+                strPost4x4Stage1(p0 - 64, 32, iHPQP, bHPAbsent);
+            }
+            else if (top)
+            {
+                for (j = (left ? 0: -64); j < (right ? -32: 0); j += 32)
+                {
+                    p = p1 + j + 4;
+                    strPost4(p + 1, p + 0, p + 28, p + 29);
+                    strPost4(p + 3, p + 2, p + 30, p + 31);
+                    p = NULL;
+                }
+            }
+            else if (left)
+            {
+                if (!bottom)
+                {
+                    strPost4(p0 + 26, p0 + 24, p1 + 0, p1 + 2);
+                    strPost4(p0 + 27, p0 + 25, p1 + 1, p1 + 3);
+                }
+
+                strPost4(p0 + 10, p0 + 8, p0 + 16, p0 + 18);
+                strPost4(p0 + 11, p0 + 9, p0 + 17, p0 + 19);
+            }
+        }
+    }
+
+    //================================================================
+    // 422_UV
+    for (i = 0; i < (YUV_422 == cfColorFormat? 2U : 0U) && tScale < 16; ++i)
+    {
+        PixelI* const p0 = pSC->p0MBbuffer[1 + i];//(0 == i ? pSC->pU0 : pSC->pV0);
+        PixelI* const p1 = pSC->p1MBbuffer[1 + i];//(0 == i ? pSC->pU1 : pSC->pV1);
+
+        Int iHPQP = 255;
+        if (!bHPAbsent)
+            iHPQP = pSC->pTile[pSC->cTileColumn].pQuantizerHP[i][pSC->MBInfo.iQIndexHP].iQP;
+
+        //========================================
+        // second level inverse transform (422_UV)
+        if ((!bottomORright) && pSC->m_Dparam->cThumbnailScale < 16)
+        {
+            // 1D lossless HT
+            p1[0]  -= ((p1[32] + 1) >> 1);
+            p1[32] += p1[0];
+
+            if (!pSC->m_param.bScaledArith) {
+                strDCT2x2dn(p1 +  0, p1 + 64, p1 + 16, p1 +  80);
+                strDCT2x2dn(p1 + 32, p1 + 96, p1 + 48, p1 + 112);
+            }
+            else {
+                strDCT2x2dnDec(p1 +  0, p1 + 64, p1 + 16, p1 +  80);
+                strDCT2x2dnDec(p1 + 32, p1 + 96, p1 + 48, p1 + 112);
+            }
+        }
+        
+        //========================================
+        // second level inverse overlap (422_UV)
+        if (OL_TWO == olOverlap)
+        {
+            if (!bottom)
+            {
+                if (leftORright)
+                {
+                    if (!top)
+                    {
+                        j = (left ? 0 : -64);
+                        strPost2(p0 + 48 + j, p1 + j);
+                    }
+
+                    j = (left ? 16 : -48);
+                    strPost2(p1 + j, p1 + j + 16);
+                }
+                else
+                {
+                    if (top)
+                    {
+                        strPost2(p1 - 64, p1);
+                    }
+                    else
+                    {
+                        strPost2x2(p0 - 16, p0 + 48, p1 - 64, p1);
+                    }
+
+                    strPost2x2(p1 - 48, p1 + 16, p1 - 32, p1 + 32);
+                }
+            }
+            else if (!leftORright)
+            {
+                strPost2(p0 - 16, p0 + 48);
+            }
+        }
+
+        //========================================
+        // first level inverse transform (422_UV)
+        if(tScale >= 4) // bypass first level transform for 4:1 and smaller thumbnail
+            continue;
+
+        if (!top)
+        {
+            for (j = (left ? 48 : -16); j < (right ? 48 : 112); j += 64)
+            {
+                strIDCT4x4Stage1(p0 + j);
+            }
+        }
+
+        if (!bottom)
+        {
+            for (j = (left ? 0 : -64); j < (right ? 0 : 64); j += 64)
+            {
+                strIDCT4x4Stage1(p1 + j + 0);
+                strIDCT4x4Stage1(p1 + j + 16);
+                strIDCT4x4Stage1(p1 + j + 32);
+            }
+        }
+        
+        //========================================
+        // first level inverse overlap (422_UV)
+        if (OL_NONE != olOverlap)
+        {
+            if (!top)
+            {
+                if (leftORright)
+                {
+                    j = (left ? 32 + 10 : -32 + 14);
+
+                    p = p0 + j;
+                    strPost4(p + 0, p - 2, p + 6, p + 8);
+                    strPost4(p + 1, p - 1, p + 7, p + 9);
+
+                    p = NULL;
+                }
+
+                for (j = (left ? 0 : -128); j < (right ? -64 : 0); j += 64)
+                {
+                    strPost4x4Stage1(p0 + j + 32, 0, iHPQP, bHPAbsent);
+                }
+            }
+
+            if (!bottom)
+            {
+                if (leftORright)
+                {
+                    j = (left ? 0 + 10 : -64 + 14);
+
+                    p = p1 + j;
+                    strPost4(p + 0, p - 2, p + 6, p + 8);
+                    strPost4(p + 1, p - 1, p + 7, p + 9);
+
+                    p += 16;
+                    strPost4(p + 0, p - 2, p + 6, p + 8);
+                    strPost4(p + 1, p - 1, p + 7, p + 9);
+
+                    p = NULL;
+                }
+
+                for (j = (left ? 0 : -128); j < (right ? -64 : 0); j += 64)
+                {
+                    strPost4x4Stage1(p1 + j +  0, 0, iHPQP, bHPAbsent);
+                    strPost4x4Stage1(p1 + j + 16, 0, iHPQP, bHPAbsent);
+                }
+            }
+
+            if (topORbottom)
+            {
+                p = (top ? p1 + 5 : p0 + 48 + 13);
+                for (j = (left ? 0 : -128); j < (right ? -64 : 0); j += 64)
+                {
+                    strPost4(p + j + 0, p + j - 1, p + j + 59, p + j + 60);
+                    strPost4(p + j + 2, p + j + 1, p + j + 61, p + j + 62);
+                }
+                p = NULL;
+            }
+            else
+            {
+                if (leftORright)
+                {
+                    j = (left ? 0 + 0 : -64 + 4);
+                    strPost4(p0 + j + 48 + 10 + 0, p0 + j + 48 + 10 - 2, p1 + j + 0, p1 + j + 2);
+                    strPost4(p0 + j + 48 + 10 + 1, p0 + j + 48 + 10 - 1, p1 + j + 1, p1 + j + 3);
+                }
+
+                for (j = (left ? 0 : -128); j < (right ? -64 : 0); j += 64)
+                {
+                    strPost4x4Stage1Split(p0 + j + 48, p1 + j + 0, 0, iHPQP, bHPAbsent);
+                }
+            }
+        }
+    }    
+
+    return ICERR_OK;
+}
+
+Int  invTransformMacroblock_alteredOperators_hard(CWMImageStrCodec * pSC)
+{
+    const OVERLAP olOverlap = pSC->WMISCP.olOverlap;
+    const COLORFORMAT cfColorFormat = pSC->m_param.cfColorFormat;
+    // const BITDEPTH_BITS bdBitDepth = pSC->WMII.bdBitDepth;
+    const Bool left = (pSC->cColumn == 0), right = (pSC->cColumn == pSC->cmbWidth);
+    const Bool top = (pSC->cRow == 0), bottom = (pSC->cRow == pSC->cmbHeight);
+    const Bool topORbottom = (top || bottom), leftORright = (left || right);
+    const Bool topORleft = (top || left), bottomORright = (bottom || right);
+    Bool leftAdjacentColumn = (pSC->cColumn == 1), rightAdjacentColumn = (pSC->cColumn == pSC->cmbWidth - 1);
+    // Bool topAdjacentRow =  (pSC->cRow == 1), bottomAdjacentRow = (pSC->cRow == pSC->cmbHeight - 1);
+    const size_t mbWidth = pSC->cmbWidth;
+    PixelI * p = NULL;// * pt = NULL;
+    size_t i;
+    const size_t iChannels = (cfColorFormat == YUV_420 || cfColorFormat == YUV_422) ? 1 : pSC->m_param.cNumChannels;
+    const size_t tScale = pSC->m_Dparam->cThumbnailScale;
+    Int j = 0;
+
+    Int qp[MAX_CHANNELS], dcqp[MAX_CHANNELS], iStrength = (1 << pSC->WMII.cPostProcStrength);
+    // ERR_CODE result = ICERR_OK;
+
+#define mbX               pSC->mbX
+#define mbY               pSC->mbY
+#define tileX             pSC->tileX
+#define tileY             pSC->tileY
+#define bVertTileBoundary pSC->bVertTileBoundary
+#define bHoriTileBoundary pSC->bHoriTileBoundary
+#define bOneMBLeftVertTB  pSC->bOneMBLeftVertTB
+#define bOneMBRightVertTB pSC->bOneMBRightVertTB
+#define iPredBefore       pSC->iPredBefore
+#define iPredAfter        pSC->iPredAfter
+
+    if (pSC->WMISCP.bUseHardTileBoundaries) {
+        //Add tile location information
+        if (pSC->cColumn == 0) {
+            bVertTileBoundary = FALSE;
+            tileY = 0;
+        }
+        bOneMBLeftVertTB = bOneMBRightVertTB = FALSE;
+        if(tileY > 0 && tileY <= pSC->WMISCP.cNumOfSliceMinus1H && (pSC->cColumn - 1) == pSC->WMISCP.uiTileY[tileY]) 
+            bOneMBRightVertTB = TRUE;
+        if(tileY < pSC->WMISCP.cNumOfSliceMinus1H && pSC->cColumn == pSC->WMISCP.uiTileY[tileY + 1]) {
+            bVertTileBoundary = TRUE;
+            tileY++; 
+        }
+        else 
+            bVertTileBoundary = FALSE;
+        if(tileY < pSC->WMISCP.cNumOfSliceMinus1H && (pSC->cColumn + 1) == pSC->WMISCP.uiTileY[tileY + 1]) 
+            bOneMBLeftVertTB = TRUE;
+
+        if (pSC->cRow == 0) {
+            bHoriTileBoundary = FALSE;
+            tileX = 0;
+        }
+        else if(mbY != pSC->cRow && tileX < pSC->WMISCP.cNumOfSliceMinus1V && pSC->cRow == pSC->WMISCP.uiTileX[tileX + 1]) {
+            bHoriTileBoundary = TRUE;
+            tileX++; 
+        }
+        else if(mbY != pSC->cRow)
+            bHoriTileBoundary = FALSE;
+    }
+    else {
+        bVertTileBoundary = FALSE;
+        bHoriTileBoundary = FALSE;
+        bOneMBLeftVertTB = FALSE;
+        bOneMBRightVertTB = FALSE;
+    }
+    mbX = pSC->cColumn, mbY = pSC->cRow;
+
+    if(pSC->WMII.cPostProcStrength > 0){
+        // threshold for post processing
+        for(i = 0; i < iChannels; i ++){
+            qp[i] = pSC->pTile[pSC->cTileColumn].pQuantizerLP[i][pSC->MBInfo.iQIndexLP].iQP * iStrength * (olOverlap == OL_NONE ? 2 : 1);
+            dcqp[i] = pSC->pTile[pSC->cTileColumn].pQuantizerDC[i][0].iQP * iStrength;
+        }
+
+        if(left) // a new MB row
+            slideOneMBRow(pSC->pPostProcInfo, pSC->m_param.cNumChannels, mbWidth, top, bottom);  // previous current row becomes previous row
+    }
+
+    //================================================================
+    // 400_Y, 444_YUV
+    for (i = 0; i < iChannels && tScale < 16; ++i)
+    {
+        PixelI* const p0 = pSC->p0MBbuffer[i];
+        PixelI* const p1 = pSC->p1MBbuffer[i];
+
+        //================================
+        // second level inverse transform
+        if (!bottomORright)
+        {
+            if(pSC->WMII.cPostProcStrength > 0)
+                updatePostProcInfo(pSC->pPostProcInfo, p1, mbX, i); // update postproc info before IDCT
+
+            strIDCT4x4Stage2(p1);
+            if (pSC->m_param.bScaledArith) {
+                strNormalizeDec(p1, (i != 0));
+            }
+        }
+
+        //================================
+        // second level inverse overlap
+        if (OL_TWO == olOverlap)
+        {
+            /* Corner operations */
+            if ((top || bHoriTileBoundary) && (left || bVertTileBoundary))
+                strPost4_alternate(p1 + 0, p1 + 64, p1 + 0 + 16, p1 + 64 + 16);
+            if ((top || bHoriTileBoundary) && (right || bVertTileBoundary))
+                strPost4_alternate(p1 - 128, p1 - 64, p1 - 128 + 16, p1 - 64 + 16); 
+            if ((bottom || bHoriTileBoundary) && (left || bVertTileBoundary))
+                strPost4_alternate(p0 + 32, p0 + 96, p0 + 32 + 16, p0 + 96 + 16);
+            if ((bottom || bHoriTileBoundary) && (right || bVertTileBoundary))
+                strPost4_alternate(p0 - 96, p0 - 32, p0 - 96 + 16, p0 - 32 + 16);
+            if ((leftORright || bVertTileBoundary) && (!topORbottom  && !bHoriTileBoundary))
+            {
+                if (left || bVertTileBoundary) {
+                    j = 0;
+                    strPost4_alternate(p0 + j + 32, p0 + j +  48, p1 + j +  0, p1 + j + 16);
+                    strPost4_alternate(p0 + j + 96, p0 + j + 112, p1 + j + 64, p1 + j + 80);
+                }
+                if (right || bVertTileBoundary) {
+                    j = -128;
+                    strPost4_alternate(p0 + j + 32, p0 + j +  48, p1 + j +  0, p1 + j + 16);
+                    strPost4_alternate(p0 + j + 96, p0 + j + 112, p1 + j + 64, p1 + j + 80);
+                }
+            }
+
+            if (!leftORright)
+            {
+                if ((topORbottom || bHoriTileBoundary) && !bVertTileBoundary)
+                {
+                    if (top || bHoriTileBoundary) {
+                        p = p1;
+                        strPost4_alternate(p - 128, p - 64, p +  0, p + 64);
+                        strPost4_alternate(p - 112, p - 48, p + 16, p + 80);
+                        p = NULL;
+                    }
+                    if (bottom || bHoriTileBoundary) {
+                        p = p0 + 32;
+                        strPost4_alternate(p - 128, p - 64, p +  0, p + 64);
+                        strPost4_alternate(p - 112, p - 48, p + 16, p + 80);
+                        p = NULL;
+                    }
+                }
+                
+                if (!topORbottom && !bHoriTileBoundary && !bVertTileBoundary)
+                    strPost4x4Stage2Split_alternate(p0, p1);
+            }
+        }
+
+        if(pSC->WMII.cPostProcStrength > 0)
+            postProcMB(pSC->pPostProcInfo, p0, p1, mbX, i, dcqp[i]); // second stage deblocking
+
+        //================================
+        // first level inverse transform
+        if(tScale >= 4) // bypass first level transform for 4:1 and smaller thumbnail
+            continue;
+
+        if (!top)
+        {
+            for (j = (left ? 32 : -96); j < (right ? 32 : 160); j += 64)
+            {
+                strIDCT4x4Stage1(p0 + j +  0);
+                strIDCT4x4Stage1(p0 + j + 16);
+            }
+        }
+
+        if (!bottom)
+        {
+            for (j = (left ? 0 : -128); j < (right ? 0 : 128); j += 64)
+            {
+//                if(tScale == 2  && bdBitDepth != BD_1){
+//                    MIPgen(p1 + j + 0);
+//                    MIPgen(p1 + j + 16);
+//                }
+                strIDCT4x4Stage1(p1 + j +  0);
+                strIDCT4x4Stage1(p1 + j + 16);
+            }
+        }
+
+        //================================
+        // first level inverse overlap
+        if (OL_NONE != olOverlap)
+        {
+            if (leftORright || bVertTileBoundary)
+            {
+                /* Corner operations */
+                if ((top || bHoriTileBoundary) && (left || bVertTileBoundary))
+                    strPost4_alternate(p1 + 0, p1 + 1, p1 + 2, p1 + 3);
+                if ((top || bHoriTileBoundary) && (right || bVertTileBoundary))
+                    strPost4_alternate(p1 - 59, p1 - 60, p1 - 57, p1 - 58); 
+                if ((bottom || bHoriTileBoundary) && (left || bVertTileBoundary))
+                    strPost4_alternate(p0 + 48 + 10, p0 + 48 + 11, p0 + 48 + 8, p0 + 48 + 9);
+                if ((bottom || bHoriTileBoundary) && (right || bVertTileBoundary))
+                    strPost4_alternate(p0 - 1, p0 - 2, p0 - 3, p0 - 4);
+                if (left || bVertTileBoundary) {
+                    j = 0 + 10;
+                    if (!top)
+                    {
+                        p = p0 + 16 + j;
+                        strPost4_alternate(p +  0, p -  2, p +  6, p +  8);
+                        strPost4_alternate(p +  1, p -  1, p +  7, p +  9);
+                        strPost4_alternate(p + 16, p + 14, p + 22, p + 24);
+                        strPost4_alternate(p + 17, p + 15, p + 23, p + 25);
+                        p = NULL;
+                    }
+                    if (!bottom)
+                    {
+                        p = p1 + j;
+                        strPost4_alternate(p + 0, p - 2, p + 6, p + 8);
+                        strPost4_alternate(p + 1, p - 1, p + 7, p + 9);
+                        p = NULL;
+                    }
+                    if (!topORbottom && !bHoriTileBoundary)
+                    {
+                        strPost4_alternate(p0 + 48 + j + 0, p0 + 48 + j - 2, p1 - 10 + j, p1 - 8 + j);
+                        strPost4_alternate(p0 + 48 + j + 1, p0 + 48 + j - 1, p1 -  9 + j, p1 - 7 + j);
+                    }
+                }
+                if (right || bVertTileBoundary) {
+                    j = -64 + 14;
+                    if (!top)
+                    {
+                        p = p0 + 16 + j;
+                        strPost4_alternate(p +  0, p -  2, p +  6, p +  8);
+                        strPost4_alternate(p +  1, p -  1, p +  7, p +  9);
+                        strPost4_alternate(p + 16, p + 14, p + 22, p + 24);
+                        strPost4_alternate(p + 17, p + 15, p + 23, p + 25);
+                        p = NULL;
+                    }
+                    if (!bottom)
+                    {
+                        p = p1 + j;
+                        strPost4_alternate(p + 0, p - 2, p + 6, p + 8);
+                        strPost4_alternate(p + 1, p - 1, p + 7, p + 9);
+                        p = NULL;
+                    }
+                    if (!topORbottom && !bHoriTileBoundary)
+                    {
+                        strPost4_alternate(p0 + 48 + j + 0, p0 + 48 + j - 2, p1 - 10 + j, p1 - 8 + j);
+                        strPost4_alternate(p0 + 48 + j + 1, p0 + 48 + j - 1, p1 -  9 + j, p1 - 7 + j);
+                    }
+                }
+            }
+
+            if (top || bHoriTileBoundary)
+            {
+                for (j = (left ? 0 : -192); j < (right ? -64 : 64); j += 64)
+                {
+                    if (!bVertTileBoundary || j != -64) {
+                        p = p1 + j;
+                        strPost4_alternate(p + 5, p + 4, p + 64, p + 65);
+                        strPost4_alternate(p + 7, p + 6, p + 66, p + 67);
+                        p = NULL;
+
+                        strPost4x4Stage1_alternate(p1 + j, 0);
+                    }
+                }
+            }
+
+            if (bottom || bHoriTileBoundary)
+            {
+                for (j = (left ? 0 : -192); j < (right ? -64 : 64); j += 64)
+                {
+                    if (!bVertTileBoundary || j != -64) {
+                        strPost4x4Stage1_alternate(p0 + 16 + j, 0);
+                        strPost4x4Stage1_alternate(p0 + 32 + j, 0);
+
+                        p = p0 + 48 + j;
+                        strPost4_alternate(p + 15, p + 14, p + 74, p + 75);
+                        strPost4_alternate(p + 13, p + 12, p + 72, p + 73);
+                        p = NULL;
+                    }
+                }
+            }
+
+            if (!top && !bottom && !bHoriTileBoundary)
+            {
+                for (j = (left ? 0 : -192); j < (right ? -64 : 64); j += 64)
+                {
+                    if (!bVertTileBoundary || j != -64) {
+                        strPost4x4Stage1_alternate(p0 + 16 + j, 0);
+                        strPost4x4Stage1_alternate(p0 + 32 + j, 0);
+                        strPost4x4Stage1Split_alternate(p0 + 48 + j, p1 + j, 0);
+                        strPost4x4Stage1_alternate(p1 + j, 0);
+                    }
+                }
+            }
+        }
+        
+        if(pSC->WMII.cPostProcStrength > 0 && (!topORleft))
+            postProcBlock(pSC->pPostProcInfo, p0, p1, mbX, i, qp[i]); // destairing and first stage deblocking
+    }
+
+    //================================================================
+    // 420_UV
+    for (i = 0; i < (YUV_420 == cfColorFormat? 2U : 0U) && tScale < 16; ++i)
+    {
+        PixelI* const p0 = pSC->p0MBbuffer[1 + i];//(0 == i ? pSC->pU0 : pSC->pV0);
+        PixelI* const p1 = pSC->p1MBbuffer[1 + i];//(0 == i ? pSC->pU1 : pSC->pV1);
+
+        //========================================
+        // second level inverse transform (420_UV)
+        if (!bottomORright)
+        {
+            if (!pSC->m_param.bScaledArith) {
+                strDCT2x2dn(p1, p1 + 32, p1 + 16, p1 + 48);
+            }
+            else {
+                strDCT2x2dnDec(p1, p1 + 32, p1 + 16, p1 + 48);
+            }
+        }
+        
+        //========================================
+        // second level inverse overlap (420_UV)
+        if (OL_TWO == olOverlap)
+        {
+            if ((leftAdjacentColumn || bOneMBRightVertTB) && (top || bHoriTileBoundary)) 
+                COMPUTE_CORNER_PRED_DIFF(p1 - 64 + 0, *(p1 - 64 + 32));
+            if ((rightAdjacentColumn || bOneMBLeftVertTB) && (top || bHoriTileBoundary))
+                iPredBefore[i][0] = *(p1 + 0);
+            if ((right || bVertTileBoundary) && (top || bHoriTileBoundary))
+                COMPUTE_CORNER_PRED_DIFF(p1 - 64 + 32, iPredBefore[i][0]);
+            if ((leftAdjacentColumn || bOneMBRightVertTB) && (bottom || bHoriTileBoundary)) 
+                COMPUTE_CORNER_PRED_DIFF(p0 - 64 + 16, *(p0 - 64 + 48));
+            if ((rightAdjacentColumn || bOneMBLeftVertTB) && (bottom || bHoriTileBoundary)) 
+                iPredBefore[i][1] = *(p0 + 16);
+            if ((right || bVertTileBoundary) && (bottom || bHoriTileBoundary))
+                COMPUTE_CORNER_PRED_DIFF(p0 - 64 + 48, iPredBefore[i][1]);
+
+            if ((leftORright || bVertTileBoundary) && !topORbottom && !bHoriTileBoundary)
+            {
+                if (left || bVertTileBoundary)
+                    strPost2_alternate(p0 +   0 + 16, p1 +   0);
+                if (right || bVertTileBoundary)
+                    strPost2_alternate(p0 + -32 + 16, p1 + -32);
+            }
+
+            if (!leftORright)
+            {
+                if ((topORbottom || bHoriTileBoundary) && !bVertTileBoundary)
+                {
+                    if (top || bHoriTileBoundary) 
+                        strPost2_alternate(p1 - 32, p1);
+                    if (bottom || bHoriTileBoundary) 
+                        strPost2_alternate(p0 + 16 - 32, p0 + 16);
+                }
+                else if (!topORbottom && !bHoriTileBoundary && !bVertTileBoundary) { 
+                    strPost2x2_alternate(p0 - 16, p0 + 16, p1 - 32, p1);
+                }
+            }
+            if ((leftAdjacentColumn || bOneMBRightVertTB) && (top || bHoriTileBoundary)) 
+                COMPUTE_CORNER_PRED_ADD(p1 - 64 + 0, *(p1 - 64 + 32));
+            if ((rightAdjacentColumn || bOneMBLeftVertTB) && (top || bHoriTileBoundary))
+                iPredAfter[i][0] = *(p1 + 0);
+            if ((right || bVertTileBoundary) && (top || bHoriTileBoundary))
+                COMPUTE_CORNER_PRED_ADD(p1 - 64 + 32, iPredAfter[i][0]);
+            if ((leftAdjacentColumn || bOneMBRightVertTB) && (bottom || bHoriTileBoundary)) 
+                COMPUTE_CORNER_PRED_ADD(p0 - 64 + 16, *(p0 - 64 + 48));
+            if ((rightAdjacentColumn || bOneMBLeftVertTB) && (bottom || bHoriTileBoundary)) 
+                iPredAfter[i][1] = *(p0 + 16);
+            if ((right || bVertTileBoundary) && (bottom || bHoriTileBoundary))
+                COMPUTE_CORNER_PRED_ADD(p0 - 64 + 48, iPredAfter[i][1]);
+        }
+
+        //========================================
+        // first level inverse transform (420_UV)
+        if(tScale >= 4) // bypass first level transform for 4:1 and smaller thumbnail
+            continue;
+
+        if (!top)
+        {
+            // In order to allow correction operation of corner chroma overlap operators (fixed)
+            // processing of left most MB column must be delayed by one MB 
+            // Thus left MB not processed until leftAdjacentColumn = 1
+            for (j = ((left) ? 48 : ((leftAdjacentColumn || bOneMBRightVertTB) ? -48 : -16)); j < ((right || bVertTileBoundary) ? 16 : 48); j += 32)
+            {
+                strIDCT4x4Stage1(p0 + j);
+            }
+        }
+
+        if (!bottom)
+        {
+            // In order to allow correction operation of corner chroma overlap operators (fixed)
+            // processing of left most MB column must be delayed by one MB 
+            // Thus left MB not processed until leftAdjacentColumn = 1
+            for (j = ((left) ? 32 : ((leftAdjacentColumn || bOneMBRightVertTB) ? -64 : -32)); j < ((right || bVertTileBoundary) ? 0 : 32); j += 32)
+            {
+                strIDCT4x4Stage1(p1 + j);
+            }
+        }
+
+        //========================================
+        // first level inverse overlap (420_UV)
+        if (OL_NONE != olOverlap)
+        {
+            /* Corner operations */
+            /* Change because the top-left corner ICT will not have happened until leftAdjacentColumn ==1 */
+            if ((top || bHoriTileBoundary) && (leftAdjacentColumn || bOneMBRightVertTB)) 
+                strPost4_alternate(p1 - 64 + 0, p1 - 64 + 1, p1 - 64 + 2, p1 - 64 + 3);
+            if ((top || bHoriTileBoundary) && (right || bVertTileBoundary)) 
+                strPost4_alternate(p1 - 27, p1 - 28, p1 - 25, p1 - 26);
+            /* Change because the bottom-left corner ICT will not have happened until leftAdjacentColumn ==1 */
+            if ((bottom || bHoriTileBoundary) && (leftAdjacentColumn || bOneMBRightVertTB)) 
+                strPost4_alternate(p0 - 64 + 16 + 10, p0 - 64 + 16 + 11, p0 - 64 + 16 + 8, p0 - 64 + 16 + 9);
+            if ((bottom || bHoriTileBoundary) && (right || bVertTileBoundary)) 
+                strPost4_alternate(p0 - 1, p0 - 2, p0 - 3, p0 - 4);
+            if(!left && !top)
+            {
+                /* Change because the vertical 1-D overlap operations of the left edge pixels cannot be performed until leftAdjacentColumn ==1 */
+                if (leftAdjacentColumn || bOneMBRightVertTB)
+                {
+                    if (!bottom && !bHoriTileBoundary)
+                    {
+                        strPost4_alternate(p0 - 64 + 26, p0 - 64 + 24, p1 - 64 + 0, p1 - 64 + 2);
+                        strPost4_alternate(p0 - 64 + 27, p0 - 64 + 25, p1 - 64 + 1, p1 - 64 + 3);
+                    }
+
+                    strPost4_alternate(p0 - 64 + 10, p0 - 64 + 8, p0 - 64 + 16, p0 - 64 + 18);
+                    strPost4_alternate(p0 - 64 + 11, p0 - 64 + 9, p0 - 64 + 17, p0 - 64 + 19);
+                }
+                if (bottom || bHoriTileBoundary)
+                {
+                    p = p0 + -48;
+                    strPost4_alternate(p + 15, p + 14, p + 42, p + 43);
+                    strPost4_alternate(p + 13, p + 12, p + 40, p + 41);
+                    p = NULL;
+
+                    if (!right && !bVertTileBoundary)
+                    {
+                        p = p0 + -16;
+                        strPost4_alternate(p + 15, p + 14, p + 42, p + 43);
+                        strPost4_alternate(p + 13, p + 12, p + 40, p + 41);
+                        p = NULL;
+                    }
+                }
+                else
+                {
+                    strPost4x4Stage1Split_alternate(p0 + -48, p1 - 16 + -48, 32);
+
+                    if (!right && !bVertTileBoundary)
+                        strPost4x4Stage1Split_alternate(p0 + -16, p1 - 16 + -16, 32);
+                }
+
+                if (right || bVertTileBoundary)
+                {
+                    if (!bottom && !bHoriTileBoundary)
+                    {
+                        strPost4_alternate(p0 - 2 , p0 - 4 , p1 - 28, p1 - 26);
+                        strPost4_alternate(p0 - 1 , p0 - 3 , p1 - 27, p1 - 25);
+                    }
+
+                    strPost4_alternate(p0 - 18, p0 - 20, p0 - 12, p0 - 10);
+                    strPost4_alternate(p0 - 17, p0 - 19, p0 - 11, p0 -  9);
+                }
+                else
+                {
+                    strPost4x4Stage1_alternate(p0 - 32, 32);
+                }
+
+                strPost4x4Stage1_alternate(p0 - 64, 32);
+            }
+
+            if (top || bHoriTileBoundary)
+            {
+                if (!left)
+                {
+                    p = p1 + -64 + 4;
+                    strPost4_alternate(p + 1, p + 0, p + 28, p + 29);
+                    strPost4_alternate(p + 3, p + 2, p + 30, p + 31);
+                    p = NULL;
+                }
+
+                if (!left && !right && !bVertTileBoundary)
+                {
+                    p = p1 + -32 + 4;
+                    strPost4_alternate(p + 1, p + 0, p + 28, p + 29);
+                    strPost4_alternate(p + 3, p + 2, p + 30, p + 31);
+                    p = NULL;
+                }
+            }
+        }
+    }
+
+    //================================================================
+    // 422_UV
+    for (i = 0; i < (YUV_422 == cfColorFormat? 2U : 0U) && tScale < 16; ++i)
+    {
+        PixelI* const p0 = pSC->p0MBbuffer[1 + i];//(0 == i ? pSC->pU0 : pSC->pV0);
+        PixelI* const p1 = pSC->p1MBbuffer[1 + i];//(0 == i ? pSC->pU1 : pSC->pV1);
+
+        //========================================
+        // second level inverse transform (422_UV)
+        if ((!bottomORright) && pSC->m_Dparam->cThumbnailScale < 16)
+        {
+            // 1D lossless HT
+            p1[0]  -= ((p1[32] + 1) >> 1);
+            p1[32] += p1[0];
+
+            if (!pSC->m_param.bScaledArith) {
+                strDCT2x2dn(p1 +  0, p1 + 64, p1 + 16, p1 +  80);
+                strDCT2x2dn(p1 + 32, p1 + 96, p1 + 48, p1 + 112);
+            }
+            else {
+                strDCT2x2dnDec(p1 +  0, p1 + 64, p1 + 16, p1 +  80);
+                strDCT2x2dnDec(p1 + 32, p1 + 96, p1 + 48, p1 + 112);
+            }
+        }
+        
+        //========================================
+        // second level inverse overlap (422_UV)
+        if (OL_TWO == olOverlap)
+        {
+            if ((leftAdjacentColumn || bOneMBRightVertTB) && (top || bHoriTileBoundary)) 
+                COMPUTE_CORNER_PRED_DIFF(p1 - 128 + 0, *(p1 - 128 + 64));
+
+            if ((rightAdjacentColumn || bOneMBLeftVertTB) && (top || bHoriTileBoundary))
+                iPredBefore[i][0] = *(p1 + 0);
+            if ((right || bVertTileBoundary) && (top || bHoriTileBoundary))
+                COMPUTE_CORNER_PRED_DIFF(p1 - 128 + 64, iPredBefore[i][0]);
+
+            if ((leftAdjacentColumn || bOneMBRightVertTB) && (bottom || bHoriTileBoundary)) 
+                COMPUTE_CORNER_PRED_DIFF(p0 - 128 + 48, *(p0 - 128 + 112));
+
+            if ((rightAdjacentColumn || bOneMBLeftVertTB) && (bottom || bHoriTileBoundary)) 
+                iPredBefore[i][1] = *(p0 + 48);
+            if ((right || bVertTileBoundary) && (bottom || bHoriTileBoundary))
+                COMPUTE_CORNER_PRED_DIFF(p0 - 128 + 112, iPredBefore[i][1]);
+
+            if (!bottom)
+            {
+                if (leftORright || bVertTileBoundary)
+                {
+                    if (!top && !bHoriTileBoundary)
+                    {
+                        if (left || bVertTileBoundary)
+                            strPost2_alternate(p0 + 48 + 0, p1 + 0);
+
+                        if (right || bVertTileBoundary)
+                            strPost2_alternate(p0 + 48 + -64, p1 + -64);
+                    }
+
+                    if (left || bVertTileBoundary)
+                        strPost2_alternate(p1 + 16, p1 + 16 + 16);
+
+                    if (right || bVertTileBoundary)
+                        strPost2_alternate(p1 + -48, p1 + -48 + 16);
+                }
+
+                if (!leftORright && !bVertTileBoundary)
+                {
+                    if (top || bHoriTileBoundary)
+                        strPost2_alternate(p1 - 64, p1);
+                    else
+                        strPost2x2_alternate(p0 - 16, p0 + 48, p1 - 64, p1);
+
+                    strPost2x2_alternate(p1 - 48, p1 + 16, p1 - 32, p1 + 32);
+                }
+            }
+            
+            if ((bottom || bHoriTileBoundary) && (!leftORright && !bVertTileBoundary))
+                strPost2_alternate(p0 - 16, p0 + 48);
+
+            if ((leftAdjacentColumn || bOneMBRightVertTB) && (top || bHoriTileBoundary)) 
+                COMPUTE_CORNER_PRED_ADD(p1 - 128 + 0, *(p1 - 128 + 64));
+
+            if ((rightAdjacentColumn || bOneMBLeftVertTB) && (top || bHoriTileBoundary))
+                iPredAfter[i][0] = *(p1 + 0);
+            if ((right || bVertTileBoundary) && (top || bHoriTileBoundary))
+                COMPUTE_CORNER_PRED_ADD(p1 - 128 + 64, iPredAfter[i][0]);
+
+            if ((leftAdjacentColumn || bOneMBRightVertTB) && (bottom || bHoriTileBoundary)) 
+                COMPUTE_CORNER_PRED_ADD(p0 - 128 + 48, *(p0 - 128 + 112));
+
+            if ((rightAdjacentColumn || bOneMBLeftVertTB) && (bottom || bHoriTileBoundary)) 
+                iPredAfter[i][1] = *(p0 + 48);
+            if ((right || bVertTileBoundary) && (bottom || bHoriTileBoundary))
+                COMPUTE_CORNER_PRED_ADD(p0 - 128 + 112, iPredAfter[i][1]);
+        }
+
+        //========================================
+        // first level inverse transform (422_UV)
+        if(tScale >= 4) // bypass first level transform for 4:1 and smaller thumbnail
+            continue;
+
+        if (!top)
+        {
+            // Need to delay processing of left column until leftAdjacentColumn = 1 for corner overlap operators
+            // Since 422 has no vertical downsampling, no top MB delay of processing is necessary
+            for (j = (left ? 112 : ((leftAdjacentColumn || bOneMBRightVertTB) ? -80 : -16)); j < ((right || bVertTileBoundary) ? 48 : 112); j += 64)
+            {
+                strIDCT4x4Stage1(p0 + j);
+            }
+        }
+
+        if (!bottom)
+        {
+            // Need to delay processing of left column until leftAdjacentColumn = 1 for corner overlap operators
+            // Since 422 has no vertical downsampling, no top MB delay of processing is necessary
+            for (j = (left ? 64 : ((leftAdjacentColumn || bOneMBRightVertTB) ? -128 : -64)); j < ((right || bVertTileBoundary) ? 0 : 64); j += 64)
+            {
+                strIDCT4x4Stage1(p1 + j + 0);
+                strIDCT4x4Stage1(p1 + j + 16);
+                strIDCT4x4Stage1(p1 + j + 32);
+            }
+        }
+        
+        //========================================
+        // first level inverse overlap (422_UV)
+        if (OL_NONE != olOverlap)
+        {
+            /* Corner operations */
+            if ((top || bHoriTileBoundary) && (leftAdjacentColumn || bOneMBRightVertTB))
+                strPost4_alternate(p1 - 128 + 0, p1 - 128 + 1, p1 - 128 + 2, p1 - 128 + 3);
+            if ((top || bHoriTileBoundary) && (right || bVertTileBoundary))
+                strPost4_alternate(p1 - 59, p1 - 60, p1 - 57, p1 - 58);
+            if ((bottom || bHoriTileBoundary) && (leftAdjacentColumn || bOneMBRightVertTB))
+                strPost4_alternate(p0 - 128 + 48 + 10, p0 - 128 + 48 + 11, p0 - 128 + 48 + 8, p0 - 128 + 48 + 9);
+            if ((bottom || bHoriTileBoundary) && (right || bVertTileBoundary))
+                strPost4_alternate(p0 - 1, p0 - 2, p0 - 3, p0 - 4);
+            if (!top)
+            {
+                // Need to delay processing of left column until leftAdjacentColumn = 1 for corner overlap operators
+                if (leftAdjacentColumn || bOneMBRightVertTB) {
+                    p = p0 + 32 + 10 - 128;
+                    strPost4_alternate(p + 0, p - 2, p + 6, p + 8);
+                    strPost4_alternate(p + 1, p - 1, p + 7, p + 9);
+                    p = NULL;
+                }
+
+                if (right || bVertTileBoundary) {
+                    p = p0 + -32 + 14;
+                    strPost4_alternate(p + 0, p - 2, p + 6, p + 8);
+                    strPost4_alternate(p + 1, p - 1, p + 7, p + 9);
+                    p = NULL;
+                }
+
+                for (j = (left ? 0 : -128); j < ((right || bVertTileBoundary) ? -64 : 0); j += 64)
+                    strPost4x4Stage1_alternate(p0 + j + 32, 0);
+            }
+
+            if (!bottom)
+            {
+                // Need to delay processing of left column until leftAdjacentColumn = 1 for corner overlap operators
+                if (leftAdjacentColumn || bOneMBRightVertTB)
+                {
+                    p = p1 + 0 + 10 - 128;
+                    strPost4_alternate(p + 0, p - 2, p + 6, p + 8);
+                    strPost4_alternate(p + 1, p - 1, p + 7, p + 9);
+                    p += 16;
+                    strPost4_alternate(p + 0, p - 2, p + 6, p + 8);
+                    strPost4_alternate(p + 1, p - 1, p + 7, p + 9);
+                    p = NULL;
+                }
+
+                if (right || bVertTileBoundary)
+                {
+                    p = p1 + -64 + 14;
+                    strPost4_alternate(p + 0, p - 2, p + 6, p + 8);
+                    strPost4_alternate(p + 1, p - 1, p + 7, p + 9);
+                    p += 16;
+                    strPost4_alternate(p + 0, p - 2, p + 6, p + 8);
+                    strPost4_alternate(p + 1, p - 1, p + 7, p + 9);
+                    p = NULL;
+                }
+
+                for (j = (left ? 0 : -128); j < ((right || bVertTileBoundary) ? -64 : 0); j += 64)
+                {
+                    strPost4x4Stage1_alternate(p1 + j +  0, 0);
+                    strPost4x4Stage1_alternate(p1 + j + 16, 0);
+                }
+            }
+
+            if (topORbottom || bHoriTileBoundary)
+            {
+                if (top || bHoriTileBoundary) {
+                    p = p1 + 5;
+                    for (j = (left ? 0 : -128); j < ((right || bVertTileBoundary) ? -64 : 0); j += 64)
+                    {
+                        strPost4_alternate(p + j + 0, p + j - 1, p + j + 59, p + j + 60);
+                        strPost4_alternate(p + j + 2, p + j + 1, p + j + 61, p + j + 62);
+                    }
+                    p = NULL;
+                }
+
+                if (bottom || bHoriTileBoundary) {
+                    p = p0 + 48 + 13;
+                    for (j = (left ? 0 : -128); j < ((right || bVertTileBoundary) ? -64 : 0); j += 64)
+                    {
+                        strPost4_alternate(p + j + 0, p + j - 1, p + j + 59, p + j + 60);
+                        strPost4_alternate(p + j + 2, p + j + 1, p + j + 61, p + j + 62);
+                    }
+                    p = NULL;
+                }
+            }
+            else
+            {
+                // Need to delay processing of left column until leftAdjacentColumn = 1 for corner overlap operators
+                if (leftAdjacentColumn || bOneMBRightVertTB)
+                {
+                    j = 0 + 0 - 128;
+                    strPost4_alternate(p0 + j + 48 + 10 + 0, p0 + j + 48 + 10 - 2, p1 + j + 0, p1 + j + 2);
+                    strPost4_alternate(p0 + j + 48 + 10 + 1, p0 + j + 48 + 10 - 1, p1 + j + 1, p1 + j + 3);
+                }
+
+                if (right || bVertTileBoundary)
+                {
+                    j = -64 + 4;
+                    strPost4_alternate(p0 + j + 48 + 10 + 0, p0 + j + 48 + 10 - 2, p1 + j + 0, p1 + j + 2);
+                    strPost4_alternate(p0 + j + 48 + 10 + 1, p0 + j + 48 + 10 - 1, p1 + j + 1, p1 + j + 3);
+                }
+
+                for (j = (left ? 0 : -128); j < ((right || bVertTileBoundary) ? -64 : 0); j += 64)
+                    strPost4x4Stage1Split_alternate(p0 + j + 48, p1 + j + 0, 0);
+            }
+        }
+    }    
+
+    return ICERR_OK;
+}
diff --git a/Source/LibJXR/image/decode/strPredQuantDec.c b/Source/LibJXR/image/decode/strPredQuantDec.c
new file mode 100644
index 0000000..d7e294b
--- /dev/null
+++ b/Source/LibJXR/image/decode/strPredQuantDec.c
@@ -0,0 +1,539 @@
+//*@@@+++@@@@******************************************************************
+//
+// Copyright � Microsoft Corp.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+// � Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// � Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//*@@@---@@@@******************************************************************
+
+#include "strcodec.h"
+
+#define DEQUANT(iRaw, iQP) ((iRaw) * (iQP))
+
+Void dequantizeBlock4x4(PixelI * pRec, Int * pOrg, const Int * pIndex, Int iQPLP)
+{
+    Int i;
+    
+    for(i = 1; i < 16; i ++)
+        pRec[pIndex[i]] = DEQUANT(pOrg[i], iQPLP);
+}
+
+Void dequantizeBlock2x2(PixelI * pRec, Int * pOrg, Int iQPLP)
+{
+    pRec[32] = DEQUANT(pOrg[1], iQPLP);
+    pRec[16] = DEQUANT(pOrg[2], iQPLP);
+    pRec[48] = DEQUANT(pOrg[3], iQPLP);
+}
+
+Void dequantizeBlock4x2(PixelI * pRec, Int * pOrg, Int iQPLP)
+{
+    pRec[ 64] = DEQUANT(pOrg[1], iQPLP);
+    pRec[ 16] = DEQUANT(pOrg[2], iQPLP);
+    pRec[ 80] = DEQUANT(pOrg[3], iQPLP);
+    pRec[ 32] = DEQUANT(pOrg[4], iQPLP);
+    pRec[ 96] = DEQUANT(pOrg[5], iQPLP);
+    pRec[ 48] = DEQUANT(pOrg[6], iQPLP);
+    pRec[112] = DEQUANT(pOrg[7], iQPLP);
+}
+
+
+Int dequantizeMacroblock(CWMImageStrCodec * pSC)
+{
+    const COLORFORMAT cf = pSC->m_param.cfColorFormat;
+    CWMIMBInfo *pMBInfo = &pSC->MBInfo;
+    CWMITile * pTile = pSC->pTile + pSC->cTileColumn;
+    const size_t iChannels = pSC->m_param.cNumChannels;
+    size_t i;
+
+    for(i = 0; i < iChannels; i ++){
+        //dequantize DC
+        pSC->p1MBbuffer[i][0] = DEQUANT(pMBInfo->iBlockDC[i][0], pTile->pQuantizerDC[i]->iQP);
+
+        // dequantize LP
+        if(pSC->WMISCP.sbSubband != SB_DC_ONLY)
+            if(i == 0 || (cf != YUV_422 && cf != YUV_420))
+                dequantizeBlock4x4(pSC->p1MBbuffer[i] , pMBInfo->iBlockDC[i], dctIndex[2], pTile->pQuantizerLP[i][pMBInfo->iQIndexLP].iQP);
+            else if(cf == YUV_422)
+                dequantizeBlock4x2(pSC->p1MBbuffer[i], pMBInfo->iBlockDC[i], pTile->pQuantizerLP[i][pMBInfo->iQIndexLP].iQP);
+            else // 420
+                dequantizeBlock2x2(pSC->p1MBbuffer[i], pMBInfo->iBlockDC[i], pTile->pQuantizerLP[i][pMBInfo->iQIndexLP].iQP);
+    }
+
+    return ICERR_OK;
+}
+
+/* frequency domain inverse DCAC prediction */
+Void predDCACDec(CWMImageStrCodec * pSC)
+{
+    const COLORFORMAT cf = pSC->m_param.cfColorFormat;
+    const Int iChannels = (cf == YUV_420 || cf == YUV_422) ? 1 : (Int) pSC->m_param.cNumChannels;
+    CWMIMBInfo *pMBInfo = &(pSC->MBInfo);
+    size_t mbX = pSC->cColumn;// mbY = pSC->cRow;
+    Int iDCACPredMode = getDCACPredMode(pSC, mbX);
+    Int iDCPredMode = (iDCACPredMode & 0x3);
+    Int iADPredMode = (iDCACPredMode & 0xC);
+    PixelI * pOrg, * pRef;
+    Int ii;
+
+    for(ii = 0; ii < iChannels; ii ++){
+        pOrg = pMBInfo->iBlockDC[ii];//[dcBlkIdx + (i >> 4)]; // current DC block
+
+        /* DC prediction */
+        if(iDCPredMode == 1){ // predict DC from top
+            pOrg[0] += pSC->PredInfoPrevRow[ii][mbX].iDC;
+        }
+        else if(iDCPredMode == 0){ // predict DC from left
+            pOrg[0] += (pSC->PredInfo[ii] + mbX - 1)->iDC;
+        }
+        else if(iDCPredMode == 2){// predict DC from top&left
+            pOrg[0] += ((pSC->PredInfo[ii] + mbX - 1)->iDC + (pSC->PredInfoPrevRow[ii] + mbX)->iDC) >> 1;
+        }
+
+        /* AD prediction */
+        if(iADPredMode == 4){// predict AD from top
+            pRef = (pSC->PredInfoPrevRow[ii] + mbX)->piAD;
+            pOrg[4] += pRef[3], pOrg[8] += pRef[4], pOrg[12] += pRef[5];
+        }
+        else if(iADPredMode == 0){// predict AD from left
+            pRef = (pSC->PredInfo[ii] + mbX - 1)->piAD;
+            pOrg[1] += pRef[0], pOrg[2] += pRef[1], pOrg[3] += pRef[2];
+        }
+    }
+
+    if(cf == YUV_420){
+        for(ii = 1; ii < 3; ii ++){
+            pOrg = pMBInfo->iBlockDC[ii];//dcBlkIdx + ii]; // current DC block
+
+            /* DC prediction */
+            if(iDCPredMode == 1){ // predict DC from top
+                pOrg[0] += (pSC->PredInfoPrevRow[ii] + mbX)->iDC;
+            }
+            else if(iDCPredMode == 0){ // predict DC from left
+                pOrg[0] += (pSC->PredInfo[ii] + mbX - 1)->iDC;
+            }
+            else if(iDCPredMode == 2){ // predict DC from top&left
+                pOrg[0] += (((pSC->PredInfo[ii] + mbX - 1)->iDC + (pSC->PredInfoPrevRow[ii] + mbX)->iDC + 1) >> 1);
+            }
+
+            /* AD prediciton */
+            if(iADPredMode == 4){// predict AD from top
+                pOrg[2] += (pSC->PredInfoPrevRow[ii] + mbX)->piAD[1];
+            }
+            else if(iADPredMode == 0){// predict AD from left
+                pOrg[1] += (pSC->PredInfo[ii] + mbX - 1)->piAD[0];
+            }
+        }
+    }
+    else if(cf == YUV_422){
+        for(ii = 1; ii < 3; ii ++){
+            pOrg = pMBInfo->iBlockDC[ii];//[dcBlkIdx + ii]; // current DC block
+
+            /* DC prediciton */
+            if(iDCPredMode == 1){ // predict DC from top
+                pOrg[0] += (pSC->PredInfoPrevRow[ii] + mbX)->iDC;
+            }
+            else if(iDCPredMode == 0){ // predict DC from left
+                pOrg[0] += (pSC->PredInfo[ii] + mbX - 1)->iDC;
+            }
+            else if(iDCPredMode == 2){ // predict DC from top&left
+                pOrg[0] += (((pSC->PredInfo[ii] + mbX - 1)->iDC + (pSC->PredInfoPrevRow[ii] + mbX)->iDC + 1) >> 1);
+            }
+
+            /* AD prediction */
+            if(iADPredMode == 4){// predict AD from top
+                pOrg[4] += (pSC->PredInfoPrevRow[ii] + mbX)->piAD[4]; // AC of HT !!!
+                pOrg[2] += (pSC->PredInfoPrevRow[ii] + mbX)->piAD[3];
+                pOrg[6] += pOrg[2];
+            }
+            else if(iADPredMode == 0){// predict AD from left
+                pOrg[4] += (pSC->PredInfo[ii] + mbX - 1)->piAD[4];  // AC of HT !!!
+                pOrg[1] += (pSC->PredInfo[ii] + mbX - 1)->piAD[0];
+                pOrg[5] += (pSC->PredInfo[ii] + mbX - 1)->piAD[2];
+            }
+            else if(iDCPredMode == 1){
+                pOrg[6] += pOrg[2];
+            }
+        }
+    }
+
+    pMBInfo->iOrientation = 2 - getACPredMode(pMBInfo, cf);
+}
+
+/*************************************************************************
+    Frequency domain inverse AC prediction
+*************************************************************************/
+Void predACDec(CWMImageStrCodec * pSC)
+{
+    const COLORFORMAT cf = pSC->m_param.cfColorFormat;
+    const Int iChannels = (cf == YUV_420 || cf == YUV_422) ? 1 : (Int) pSC->m_param.cNumChannels;
+    // size_t mbX = pSC->cColumn, mbY = pSC->cRow;
+    CWMIMBInfo *pMBInfo = &pSC->MBInfo;
+    Int iACPredMode = 2 - pMBInfo->iOrientation;
+    PixelI * pOrg, * pRef;
+    Int i, j;
+
+    /* AC prediction */
+    for(i = 0; i < iChannels; i++){
+        // prediction only happens inside MB
+        PixelI* pSrc = pSC->p1MBbuffer[i];//0 == i ? pSC->pY1 : (1 == i ? pSC->pU1 : pSC->pV1);
+
+        switch (iACPredMode)
+        {
+            case 1:
+            {
+                // predict from top
+                static U8 blkIdx[] = {1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15};
+
+                for (j = 0; j < sizeof(blkIdx) / sizeof(*blkIdx); ++j)
+                {
+                    pOrg = pSrc + 16 * blkIdx[j];
+                    pRef = pOrg - 16;
+
+                    pOrg[ 2] += pRef[ 2];
+                    pOrg[10] += pRef[10];
+                    pOrg[ 9] += pRef[ 9];
+                }
+                break;
+            }
+
+            case 0:
+                // predict from left
+                for (j = 64; j < 256; j += 16)
+                {
+                    pOrg = pSrc + j;
+                    pRef = pOrg - 64;
+
+                    pOrg[1] += pRef[1];
+                    pOrg[5] += pRef[5];
+                    pOrg[6] += pRef[6];
+                }
+                break;
+
+            default:
+                // no prediction
+                break;
+        }
+    }
+
+    if(cf == YUV_420){
+        for(i = 16; i <= 20; i += 4){
+            PixelI* pSrc = pSC->p1MBbuffer[(i >> 2) - 3];//16 == i ? pSC->pU1 : pSC->pV1;
+
+            switch (iACPredMode)
+            {
+                case 1:
+                {
+                    // predict from top
+                    for (j = 1; j <= 3; j += 2)
+                    {
+                        pOrg = pSrc + 16 * j;
+                        pRef = pOrg - 16;
+
+                        pOrg[ 2] += pRef[ 2];
+                        pOrg[10] += pRef[10];
+                        pOrg[ 9] += pRef[ 9];
+                    }
+                    break;
+                }
+
+                case 0:
+                    // predict from left
+                    for (j = 2; j <= 3; ++j)
+                    {
+                        pOrg = pSrc + 16 * j;
+                        pRef = pOrg - 32;
+
+                        pOrg[1] += pRef[1];
+                        pOrg[5] += pRef[5];
+                        pOrg[6] += pRef[6];
+                    }
+                    break;
+
+                default:
+                    // no prediction
+                    break;
+            }
+        }
+    }
+    else if(cf == YUV_422){
+        for(i = 16; i < 32; i += 8){
+            PixelI* pSrc = pSC->p1MBbuffer[(i >> 3) - 1];//16 == i ? pSC->pU1 : pSC->pV1;
+
+            switch (iACPredMode)
+            {
+                case 1:
+                {
+                    // predict from top
+                    for (j = 2; j < 8; j ++)
+                    {
+                        pOrg = pSrc + blkOffsetUV_422[j];
+                        pRef = pOrg - 16;
+
+                        pOrg[10] += pRef[10];
+                        pOrg[ 2] += pRef[ 2];
+                        pOrg[ 9] += pRef[ 9];
+                    }
+                    break;
+                }
+
+                case 0:
+                    // predict from left
+                    for (j = 1; j < 8; j += 2)
+                    {
+                        pOrg = pSrc + blkOffsetUV_422[j];
+                        pRef = pOrg - 64;
+
+                        pOrg[1] += pRef[1];
+                        pOrg[5] += pRef[5];
+                        pOrg[6] += pRef[6];
+                    }
+                    break;
+
+                default:
+                    // no prediction
+                    break;
+            }
+        }
+    }    
+}
+
+/*************************************************************************
+    CBP
+*************************************************************************/
+static int NumOnes(int i)
+{
+    int retval = 0;
+    static const int g_Count[] = { 0,1,1,2, 1,2,2,3, 1,2,2,3, 2,3,3,4 };
+    i = i & 0xffff;
+    while (i) {
+        retval += g_Count[i & 0xf];
+        i >>= 4;
+    }
+    return retval;
+}
+
+#define SATURATE32(x) if((unsigned int)(x + 16) >= 32) { if (x < 0) x = -16; else x = 15; }
+
+/* CBP prediction for 16 x 16 MB */
+/* block index */
+/*  0  1  4  5 */
+/*  2  3  6  7 */
+/*  8  9 12 13 */
+/* 10 11 14 15 */
+static Int predCBPCDec(CWMImageStrCodec * pSC, Int iCBP, size_t mbX, size_t mbY, size_t c, CCBPModel *pModel)
+{
+    Int iNOrig;
+    const int iNDiff = AVG_NDIFF;
+    size_t c1 = c ? 1 : 0;
+
+    UNREFERENCED_PARAMETER( mbY );
+
+    if (pModel->m_iState[c1] == 0) {
+        if(pSC->m_bCtxLeft) {
+            if (pSC->m_bCtxTop) {
+                iCBP ^= 1;
+            }
+            else {
+                Int iTopCBP  = (pSC->PredInfoPrevRow[c] + mbX)->iCBP;
+                iCBP ^= (iTopCBP >> 10) & 1; // left: top(10) => 0
+            }
+        }
+        else {
+            Int iLeftCBP = (pSC->PredInfo[c] + mbX - 1)->iCBP;
+            iCBP ^= ((iLeftCBP >> 5) & 1); // left(5) => 0
+        }
+
+        iCBP ^= (0x02 & (iCBP << 1)); // 0 => 1
+        iCBP ^= (0x10 & (iCBP << 3)); // 1 => 4
+        iCBP ^= (0x20 & (iCBP << 1)); // 4 => 5
+
+        iCBP ^= ((iCBP & 0x33) << 2);
+        iCBP ^= ((iCBP & 0xcc) << 6);
+        iCBP ^= ((iCBP & 0x3300) << 2);
+
+    }
+    else if (pModel->m_iState[c1] == 2) {
+        iCBP ^= 0xffff;
+    }
+
+    iNOrig = NumOnes(iCBP);
+
+    pModel->m_iCount0[c1] += iNOrig - iNDiff;
+    SATURATE32(pModel->m_iCount0[c1]);
+
+    pModel->m_iCount1[c1] += 16 - iNOrig - iNDiff;
+    SATURATE32(pModel->m_iCount1[c1]);
+
+    if (pModel->m_iCount0[c1] < 0) {
+        if (pModel->m_iCount0[c1] < pModel->m_iCount1[c1]) {
+            pModel->m_iState[c1] = 1;
+        }
+        else {
+            pModel->m_iState[c1] = 2;
+        }
+    }
+    else if (pModel->m_iCount1[c1] < 0) {
+        pModel->m_iState[c1] = 2;
+    }
+    else {
+        pModel->m_iState[c1] = 0;
+    }
+    return iCBP;
+}
+
+static Int predCBPC420Dec(CWMImageStrCodec * pSC, Int iCBP, size_t mbX, size_t mbY, size_t c, CCBPModel *pModel)
+{
+    Int iNOrig;
+    const int iNDiff = AVG_NDIFF;
+
+    UNREFERENCED_PARAMETER( mbY );
+
+    if (pModel->m_iState[1] == 0) {
+        if(pSC->m_bCtxLeft) {
+            if (pSC->m_bCtxTop) {
+                iCBP ^= 1;
+            }
+            else {
+                Int iTopCBP  = (pSC->PredInfoPrevRow[c] + mbX)->iCBP;
+                iCBP ^= (iTopCBP >> 2) & 1; // left: top(2) => 0
+            }
+        }
+        else {
+            Int iLeftCBP = (pSC->PredInfo[c] + mbX - 1)->iCBP;
+            iCBP ^= ((iLeftCBP >> 1) & 1); // left(1) => 0
+        }
+
+        iCBP ^= (0x02 & (iCBP << 1)); // 0 => 1
+        iCBP ^= ((iCBP & 0x3) << 2); // [0 1] -> [2 3]
+    }
+    else if (pModel->m_iState[1] == 2) {
+        iCBP ^= 0xf;
+    }
+
+    iNOrig = NumOnes(iCBP) * 4;
+
+    pModel->m_iCount0[1] += iNOrig - iNDiff;
+    SATURATE32(pModel->m_iCount0[1]);
+
+    pModel->m_iCount1[1] += 16 - iNOrig - iNDiff;
+    SATURATE32(pModel->m_iCount1[1]);
+
+    if (pModel->m_iCount0[1] < 0) {
+        if (pModel->m_iCount0[1] < pModel->m_iCount1[1]) {
+            pModel->m_iState[1] = 1;
+        }
+        else {
+            pModel->m_iState[1] = 2;
+        }
+    }
+    else if (pModel->m_iCount1[1] < 0) {
+        pModel->m_iState[1] = 2;
+    }
+    else {
+        pModel->m_iState[1] = 0;
+    }
+
+    return iCBP;
+}
+
+static Int predCBPC422Dec(CWMImageStrCodec * pSC, Int iCBP, size_t mbX, size_t mbY, size_t c, CCBPModel *pModel)
+{
+    Int iNOrig;
+    const int iNDiff = AVG_NDIFF;
+
+    UNREFERENCED_PARAMETER( mbY );
+
+    if (pModel->m_iState[1] == 0) {
+        if(pSC->m_bCtxLeft) {
+            if (pSC->m_bCtxTop) {
+                iCBP ^= 1;
+            }
+            else {
+                Int iTopCBP  = (pSC->PredInfoPrevRow[c] + mbX)->iCBP;
+                iCBP ^= (iTopCBP >> 6) & 1; // left: top(6) => 0
+            }
+        }
+        else {
+            Int iLeftCBP = (pSC->PredInfo[c] + mbX - 1)->iCBP;
+            iCBP ^= ((iLeftCBP >> 1) & 1); // left(1) => 0
+        }
+        
+        iCBP ^= (iCBP & 0x1) << 1; // [0]->[1]
+        iCBP ^= (iCBP & 0x3) << 2; // [0 1]->[2 3]
+        iCBP ^= (iCBP & 0xc) << 2; // [2 3]->[4 5]
+        iCBP ^= (iCBP & 0x30) << 2; // [4 5]->[6 7]
+    }
+    else if (pModel->m_iState[1] == 2) {
+        iCBP ^= 0xff;
+    }
+
+    iNOrig = NumOnes(iCBP) * 2;
+
+    pModel->m_iCount0[1] += iNOrig - iNDiff;
+    SATURATE32(pModel->m_iCount0[1]);
+
+    pModel->m_iCount1[1] += 16 - iNOrig - iNDiff;
+    SATURATE32(pModel->m_iCount1[1]);
+
+    if (pModel->m_iCount0[1] < 0) {
+        if (pModel->m_iCount0[1] < pModel->m_iCount1[1]) {
+            pModel->m_iState[1] = 1;
+        }
+        else {
+            pModel->m_iState[1] = 2;
+        }
+    }
+    else if (pModel->m_iCount1[1] < 0) {
+        pModel->m_iState[1] = 2;
+    }
+    else {
+        pModel->m_iState[1] = 0;
+    }
+
+    return iCBP;
+}
+
+
+/* Coded Block Pattern (CBP) prediction */
+Void predCBPDec(CWMImageStrCodec *pSC, CCodingContext *pContext)
+{
+    const COLORFORMAT cf = pSC->m_param.cfColorFormat;
+    const size_t iChannels = (cf == YUV_420 || cf == YUV_422) ? 1 : pSC->m_param.cNumChannels;
+    size_t i, mbX = pSC->cColumn, mbY = pSC->cRow;
+    CWMIMBInfo *pMBInfo = &(pSC->MBInfo);
+
+    for (i = 0; i < iChannels; i++) {
+        (pSC->PredInfo[i] + mbX)->iCBP = pMBInfo->iCBP[i] = predCBPCDec(pSC, pMBInfo->iDiffCBP[i], mbX, mbY, i, &pContext->m_aCBPModel); // Y Channel
+    }
+
+    if (cf == YUV_422){
+        (pSC->PredInfo[1] + mbX)->iCBP = pMBInfo->iCBP[1] = predCBPC422Dec(pSC, pMBInfo->iDiffCBP[1], mbX, mbY, 1, &pContext->m_aCBPModel);
+        (pSC->PredInfo[2] + mbX)->iCBP = pMBInfo->iCBP[2] = predCBPC422Dec(pSC, pMBInfo->iDiffCBP[2], mbX, mbY, 2, &pContext->m_aCBPModel);
+    }
+    else if (cf == YUV_420) {
+        (pSC->PredInfo[1] + mbX)->iCBP = pMBInfo->iCBP[1] = predCBPC420Dec(pSC, pMBInfo->iDiffCBP[1], mbX, mbY, 1, &pContext->m_aCBPModel);
+        (pSC->PredInfo[2] + mbX)->iCBP = pMBInfo->iCBP[2] = predCBPC420Dec(pSC, pMBInfo->iDiffCBP[2], mbX, mbY, 2, &pContext->m_aCBPModel);
+    }
+    //}
+}
+
diff --git a/Source/LibJXR/image/decode/strdec.c b/Source/LibJXR/image/decode/strdec.c
new file mode 100644
index 0000000..f926c7e
--- /dev/null
+++ b/Source/LibJXR/image/decode/strdec.c
@@ -0,0 +1,3628 @@
+//*@@@+++@@@@******************************************************************
+//
+// Copyright � Microsoft Corp.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+// � Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// � Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//*@@@---@@@@******************************************************************
+#include "strcodec.h"
+#include "decode.h"
+#include "strTransform.h"
+#include <math.h>
+#include "perfTimer.h"
+
+#ifdef MEM_TRACE
+#define TRACE_MALLOC    1
+#define TRACE_NEW       0
+#define TRACE_HEAP      0
+#include "memtrace.h"
+#endif
+
+#ifdef X86OPT_INLINE
+#define _FORCEINLINE __forceinline
+#else // X86OPT_INLINE
+#define _FORCEINLINE
+#endif // X86OPT_INLINE
+
+#if defined(WMP_OPT_SSE2) || defined(WMP_OPT_CC_DEC) || defined(WMP_OPT_TRFM_DEC)
+void StrDecOpt(CWMImageStrCodec* pSC);
+#endif // OPT defined
+
+Int processMacroblockDec(CWMImageStrCodec *);
+
+U8 readQuantizerSB(U8 pQPIndex[MAX_CHANNELS], SimpleBitIO * pIO, size_t cChannel)
+{
+    U8 cChMode = 0;
+    
+    if(cChannel >= MAX_CHANNELS)
+        return 0;
+
+    if(cChannel > 1)
+        cChMode = (U8)getBit32_SB(pIO, 2); // Channel mode
+
+    pQPIndex[0] = (U8)getBit32_SB(pIO, 8); // Y
+
+    if(cChMode == 1)  // MIXED
+        pQPIndex[1] = (U8)getBit32_SB(pIO, 8); // UV
+    else if(cChMode > 0){ // INDEPENDENT
+        size_t i;
+
+        for(i = 1; i < cChannel; i ++)
+#pragma prefast(suppress: __WARNING_UNRELATED_LOOP_TERMINATION_NO_SIZEEXPR, "PREfast false alarm: 1 <= i < MAX_CHANNELS, no buffer over/underrun!")
+            pQPIndex[i] = (U8)getBit32_SB(pIO, 8); // UV
+    }
+
+    return cChMode;
+}
+
+U8 readQuantizer(CWMIQuantizer * pQuantizer[MAX_CHANNELS], BitIOInfo * pIO, size_t cChannel, size_t iPos)
+{
+    U8 cChMode = 0;
+
+    if(cChannel > 1)
+        cChMode = (U8)getBit16(pIO, 2); // Channel mode
+
+    pQuantizer[0][iPos].iIndex = (U8)getBit16(pIO, 8); // Y
+
+    if(cChMode == 1)  // MIXED
+        pQuantizer[1][iPos].iIndex = (U8)getBit16(pIO, 8); // UV
+    else if(cChMode > 0){ // INDEPENDENT
+        size_t i;
+
+        for(i = 1; i < cChannel; i ++)
+            pQuantizer[i][iPos].iIndex = (U8)getBit16(pIO, 8); // UV
+    }
+
+    return cChMode;
+}
+
+// packet header: 00000000 00000000 00000001 ?????xxx
+// xxx:           000(spatial) 001(DC) 010(AD) 011(AC) 100(FL) 101-111(reserved)
+// ?????:         (iTileY * cNumOfSliceV + iTileX) % 32
+Int readPacketHeader(BitIOInfo * pIO, U8 ptPacketType, U8 pID)
+{
+    UNREFERENCED_PARAMETER( ptPacketType );
+    UNREFERENCED_PARAMETER( pID );
+    if(getBit16(pIO, 8) != 0 || getBit16(pIO, 8) != 0 || getBit16(pIO, 8) != 1)
+        return ICERR_ERROR;
+    getBit16(pIO, 8);
+    return ICERR_OK;
+}
+
+Int readTileHeaderDC(CWMImageStrCodec * pSC, BitIOInfo * pIO)
+{
+    if((pSC->m_param.uQPMode & 1) != 0){ // not DC uniform
+        size_t iTile;
+        CWMITile * pTile = pSC->pTile + pSC->cTileColumn;
+
+        if(pSC->cTileRow + pSC->cTileColumn == 0) // allocate DC QP info
+            for(iTile = 0; iTile <= pSC->WMISCP.cNumOfSliceMinus1V; iTile ++)
+                if(allocateQuantizer(pSC->pTile[iTile].pQuantizerDC, pSC->m_param.cNumChannels, 1) != ICERR_OK)
+                    return ICERR_ERROR;
+
+        pTile->cChModeDC = readQuantizer(pTile->pQuantizerDC, pIO, pSC->m_param.cNumChannels, 0);
+        formatQuantizer(pTile->pQuantizerDC, pTile->cChModeDC, pSC->m_param.cNumChannels, 0, TRUE, pSC->m_param.bScaledArith);
+    }
+
+    return ICERR_OK;
+}
+
+Int readTileHeaderLP(CWMImageStrCodec * pSC, BitIOInfo * pIO)
+{
+    if(pSC->WMISCP.sbSubband != SB_DC_ONLY && (pSC->m_param.uQPMode & 2) != 0){ // not LP uniform
+        CWMITile * pTile = pSC->pTile + pSC->cTileColumn;
+        U8 i;
+
+        pTile->bUseDC = (getBit16(pIO, 1) == 1 ? TRUE : FALSE);
+        pTile->cBitsLP = 0;
+        pTile->cNumQPLP = 1;
+
+        if(pSC->cTileRow > 0)
+            freeQuantizer(pTile->pQuantizerLP);
+        
+        if(pTile->bUseDC == TRUE){
+            if(allocateQuantizer(pTile->pQuantizerLP, pSC->m_param.cNumChannels, pTile->cNumQPLP) != ICERR_OK)
+                return ICERR_ERROR;
+            useDCQuantizer(pSC, pSC->cTileColumn);
+        }
+        else{
+            pTile->cNumQPLP = (U8)getBit16(pIO, 4) + 1;
+            pTile->cBitsLP = dquantBits(pTile->cNumQPLP);
+            
+            if(allocateQuantizer(pTile->pQuantizerLP, pSC->m_param.cNumChannels, pTile->cNumQPLP) != ICERR_OK)
+                return ICERR_ERROR;
+
+            for(i = 0; i < pTile->cNumQPLP; i ++){
+                pTile->cChModeLP[i] = readQuantizer(pTile->pQuantizerLP, pIO, pSC->m_param.cNumChannels, i);
+                formatQuantizer(pTile->pQuantizerLP, pTile->cChModeLP[i], pSC->m_param.cNumChannels, i, TRUE, pSC->m_param.bScaledArith);
+            }
+        }
+    }
+
+    return ICERR_OK;
+}
+
+Int readTileHeaderHP(CWMImageStrCodec * pSC, BitIOInfo * pIO)
+{
+    if(pSC->WMISCP.sbSubband != SB_DC_ONLY && pSC->WMISCP.sbSubband != SB_NO_HIGHPASS && (pSC->m_param.uQPMode & 4) != 0){ // not HP uniform
+        CWMITile * pTile = pSC->pTile + pSC->cTileColumn;
+        U8 i;
+
+        pTile->bUseLP = (getBit16(pIO, 1) == 1 ? TRUE : FALSE);
+        pTile->cBitsHP = 0;
+        pTile->cNumQPHP = 1;
+
+        if(pSC->cTileRow > 0)
+            freeQuantizer(pTile->pQuantizerHP);
+        
+        if(pTile->bUseLP == TRUE){
+            pTile->cNumQPHP = pTile->cNumQPLP;
+            if(allocateQuantizer(pTile->pQuantizerHP, pSC->m_param.cNumChannels, pTile->cNumQPHP) != ICERR_OK)
+                return ICERR_ERROR;
+            useLPQuantizer(pSC, pTile->cNumQPHP, pSC->cTileColumn);
+        }
+        else{
+            pTile->cNumQPHP = (U8)getBit16(pIO, 4) + 1;
+            pTile->cBitsHP = dquantBits(pTile->cNumQPHP);
+
+            if(allocateQuantizer(pTile->pQuantizerHP, pSC->m_param.cNumChannels, pTile->cNumQPHP) != ICERR_OK)
+                return ICERR_ERROR;
+
+            for(i = 0; i < pTile->cNumQPHP; i ++){
+                pTile->cChModeHP[i] = readQuantizer(pTile->pQuantizerHP, pIO, pSC->m_param.cNumChannels, i);
+                formatQuantizer(pTile->pQuantizerHP, pTile->cChModeHP[i], pSC->m_param.cNumChannels, i, FALSE, pSC->m_param.bScaledArith);
+            }
+        }
+    }
+
+    return ICERR_OK;
+}
+
+Int readPackets(CWMImageStrCodec * pSC)
+{
+    if(pSC->cColumn == 0 && pSC->cRow == pSC->WMISCP.uiTileY[pSC->cTileRow]){ // start of a new horizontal slice
+        size_t k;
+        
+        if (pSC->m_bSecondary) {
+             if(pSC->cNumBitIO > 0){
+                for(k = 0; k <= pSC->WMISCP.cNumOfSliceMinus1V; k ++){
+                    // reset coding contexts
+                    ResetCodingContextDec(&pSC->m_pCodingContext[k]);
+                }
+            }
+            else{ // for multiple decoding calls!
+                ResetCodingContextDec(&pSC->m_pCodingContext[0]);
+            }
+        }
+        else {
+            // get sizes of each packet and update index table
+            for(k = 0; k < pSC->cNumBitIO; k ++){
+                if(pSC->ppWStream != NULL){ // new API
+                    unsigned cBands = (pSC->WMISCP.bfBitstreamFormat == SPATIAL ? 1 : pSC->cSB);
+                    struct WMPStream ** ppWS = pSC->ppWStream + (pSC->WMISCP.cNumOfSliceMinus1V + 1) * pSC->cTileRow * cBands
+                        + k / cBands * cBands + (k % cBands);
+
+                    if(pSC->cTileRow > 0 && pSC->m_ppBitIO[k]->pWS != NULL)     // attached to the same packet of the tile on top
+                        detachISRead(pSC, pSC->m_ppBitIO[k]);    // detach it
+                    
+                    if(ppWS[0] != NULL)
+                        attachISRead(pSC->m_ppBitIO[k], ppWS[0], pSC); // need to attach it
+                }
+                else{
+                    if(pSC->cTileRow > 0)
+                        detachISRead(pSC, pSC->m_ppBitIO[k]);
+                    pSC->WMISCP.pWStream->SetPos(pSC->WMISCP.pWStream, pSC->pIndexTable[pSC->cNumBitIO * pSC->cTileRow + k] + pSC->cHeaderSize);
+                    attachISRead(pSC->m_ppBitIO[k], pSC->WMISCP.pWStream, pSC);
+                }
+            }
+            
+            if(pSC->cNumBitIO == 0){
+                detachISRead(pSC, pSC->pIOHeader);
+                if(pSC->ppWStream != NULL){// new API
+                    attachISRead(pSC->pIOHeader, pSC->ppWStream[0], pSC); // need to attach it
+                }
+                else{
+                    pSC->WMISCP.pWStream->SetPos(pSC->WMISCP.pWStream, pSC->cHeaderSize);
+                    attachISRead(pSC->pIOHeader, pSC->WMISCP.pWStream, pSC);
+                }
+            }
+            
+            for(k = 0; k <= pSC->WMISCP.cNumOfSliceMinus1V; k ++){
+                U8 pID = (U8)((pSC->cTileRow * (pSC->WMISCP.cNumOfSliceMinus1V + 1) + k) & 0x1F);
+                
+                // read packet header
+                if(pSC->WMISCP.bfBitstreamFormat == SPATIAL){
+                    BitIOInfo * pIO = (pSC->cNumBitIO == 0 ? pSC->pIOHeader : pSC->m_ppBitIO[k]);
+
+                    if(pIO->pWS == NULL || readPacketHeader(pIO, 0, pID) != ICERR_OK)
+                        return ICERR_ERROR;
+                    pSC->m_pCodingContext[k].m_iTrimFlexBits = (pSC->m_param.bTrimFlexbitsFlag) ? getBit16(pIO, 4) : 0;
+                }
+                else{
+                    if(pSC->m_ppBitIO[k * pSC->cSB + 0] == NULL || readPacketHeader(pSC->m_ppBitIO[k * pSC->cSB + 0], 1, pID) != ICERR_OK)
+                        return ICERR_ERROR;
+                    if(pSC->cSB > 1){
+                        if(pSC->m_ppBitIO[k * pSC->cSB + 1] == NULL || readPacketHeader(pSC->m_ppBitIO[k * pSC->cSB + 1], 2, pID) != ICERR_OK)
+                            return ICERR_ERROR;
+                    }
+                    if(pSC->cSB > 2){
+                        if(pSC->m_ppBitIO[k * pSC->cSB + 2] == NULL || readPacketHeader(pSC->m_ppBitIO[k * pSC->cSB + 2], 3, pID) != ICERR_OK)
+                            return ICERR_ERROR;
+//                        readTileHeaderHP(pSC, pSC->m_ppBitIO[k * pSC->cSB + 2]);
+                    }
+                    if(pSC->cSB > 3){
+                        if(pSC->m_ppBitIO[k * pSC->cSB + 3] == NULL)
+                            return ICERR_ERROR;
+                        readPacketHeader(pSC->m_ppBitIO[k * pSC->cSB + 3], 4, pID);  // bad flexbits packet doesn't generate an error
+                        pSC->m_pCodingContext[k].m_iTrimFlexBits = (pSC->m_param.bTrimFlexbitsFlag) ? getBit16(pSC->m_ppBitIO[k * pSC->cSB + 3], 4) : 0;
+                    }
+                }
+
+                // reset coding contexts
+                ResetCodingContextDec(&pSC->m_pCodingContext[k]);
+            }
+        }
+    }
+    
+    if(pSC->m_bCtxLeft && pSC->m_bCtxTop && pSC->m_bSecondary == FALSE){
+        CCodingContext *pContext = &pSC->m_pCodingContext[pSC->cTileColumn];
+        
+        readTileHeaderDC(pSC, pContext->m_pIODC);
+        if(pSC->m_pNextSC != NULL)
+            readTileHeaderDC(pSC->m_pNextSC, pContext->m_pIODC);
+        if(pSC->cSB > 1){
+            readTileHeaderLP(pSC, pContext->m_pIOLP);
+            if(pSC->m_pNextSC != NULL)
+                readTileHeaderLP(pSC->m_pNextSC, pContext->m_pIOLP);
+        }
+        if(pSC->cSB > 2){
+            readTileHeaderHP(pSC, pContext->m_pIOAC);
+            if(pSC->m_pNextSC != NULL)
+                readTileHeaderHP(pSC->m_pNextSC, pContext->m_pIOAC);
+        }
+    }
+
+    return ICERR_OK;
+}
+
+/* inverse transform and overlap possible part of a macroblock */
+Int processMacroblockDec(CWMImageStrCodec * pSC)
+{
+    const OVERLAP olOverlap = pSC->WMISCP.olOverlap;
+    // const Bool left = (pSC->cColumn == 0);
+    const Bool /*top = (pSC->cRow == 0),*/ bottom = (pSC->cRow == pSC->cmbHeight);
+    const Bool bottomORright = (bottom || pSC->cColumn == pSC->cmbWidth);
+    // const size_t mbWidth = pSC->cmbWidth, mbX = pSC->cColumn;
+    // Int iQIndex = 0;
+    ERR_CODE result = ICERR_OK;
+    size_t j, jend = (pSC->m_pNextSC != NULL);
+
+    for (j = 0; j <= jend; j++) {
+        if(!bottomORright){
+            CCodingContext *pContext;
+            
+            getTilePos(pSC, pSC->cColumn, pSC->cRow);
+            
+            if(jend){
+                pSC->m_pNextSC->cTileColumn = pSC->cTileColumn;
+                pSC->m_pNextSC->cTileRow = pSC->cTileRow;
+            }
+
+            pContext = &pSC->m_pCodingContext[pSC->cTileColumn];
+           
+            if(readPackets(pSC) != ICERR_OK)
+                return ICERR_ERROR;
+         
+            // check if we need to do entropy decode
+			if(!pSC->m_Dparam->bDecodeFullFrame){
+				if(pSC->cColumn == pSC->WMISCP.uiTileX[pSC->cTileColumn]){ // switching to a new tile
+					size_t rLeft = pSC->m_Dparam->cROILeftX, rRight = pSC->m_Dparam->cROIRightX;
+					size_t rTop = pSC->m_Dparam->cROITopY, rBottom = pSC->m_Dparam->cROIBottomY;
+					size_t rExt = (olOverlap == OL_NONE ? 0 : olOverlap == OL_ONE ? 2 : 10);
+					size_t tLeft = pSC->cColumn * 16, tTop = pSC->WMISCP.uiTileY[pSC->cTileRow] * 16;
+					size_t tRight = (pSC->cTileColumn != pSC->WMISCP.cNumOfSliceMinus1V ? pSC->WMISCP.uiTileX[pSC->cTileColumn + 1] : pSC->cmbWidth) * 16;
+					size_t tBottom = (pSC->cTileRow != pSC->WMISCP.cNumOfSliceMinus1H ? pSC->WMISCP.uiTileY[pSC->cTileRow + 1] : pSC->cmbHeight) * 16;
+
+					// tile overlaps with ROI?
+					pContext->m_bInROI = ((rLeft >= tRight + rExt || rTop >= tBottom + rExt || tLeft > rRight + rExt ||
+						tTop > rBottom + rExt || pSC->cRow * 16 > rBottom + rExt) ? FALSE : TRUE);
+				}
+			}
+
+            if(pSC->m_Dparam->bDecodeFullFrame || pContext->m_bInROI){                
+                if ((result = DecodeMacroblockDC(pSC, pContext, (Int)pSC->cColumn, (Int)pSC->cRow)) != ICERR_OK)
+                    return result;
+
+                if(pSC->m_Dparam->bDecodeLP){
+                    if ((result = DecodeMacroblockLowpass(pSC, pContext, (Int)pSC->cColumn, (Int)pSC->cRow)) != ICERR_OK)
+                        return result;
+                }
+
+                predDCACDec(pSC);
+                                
+                dequantizeMacroblock(pSC);
+
+                if(pSC->m_Dparam->bDecodeHP){
+                    if ((result = DecodeMacroblockHighpass(pSC, pContext, (Int)pSC->cColumn, (Int)pSC->cRow)) != ICERR_OK)
+                        return result;
+                    predACDec(pSC);
+                }
+           
+                /* keep necessary info for future prediction */
+                updatePredInfo(pSC, &pSC->MBInfo, (Int)pSC->cColumn, pSC->m_param.cfColorFormat);
+            }
+        }
+
+        if((!pSC->m_Dparam->bDecodeFullFrame) &&
+            ((pSC->cColumn * 16 > pSC->m_Dparam->cROIRightX  + 25) || (pSC->cColumn * 16 + 25 < pSC->m_Dparam->cROILeftX)
+            || (pSC->cRow * 16 > pSC->m_Dparam->cROIBottomY + 25) || (pSC->cRow * 16 + 25 < pSC->m_Dparam->cROITopY)))
+        {
+            // do nothing
+        }
+        else {
+            pSC->Transform(pSC);
+        }
+
+        if (jend) {
+            pSC->m_pNextSC->cRow = pSC->cRow;
+            pSC->m_pNextSC->cColumn = pSC->cColumn;
+            pSC = pSC->m_pNextSC;
+        }
+    }
+
+    return result;
+}
+
+//================================================================
+// Inverse Color Conversion 
+//#define _ICC1(r, g, b) (g^=b^=g^=b, r^=g^=r^=g, b += ((g) >> 1), r += ((g) >> 1), g -= (b+3*r+2) >> 2) 
+//#define _ICC(r, g, b) (g^=b^=g^=b, r^=g^=r^=g, b += ((g) >> 1), r += ((g) >> 1), g -= (b+3*r+2) >> 2) 
+//================================================================
+//#define _ICC1(r, g, b) r -= (g >> 1), g += r, r -= ((b + 1) >> 1), b += r
+//#define _ICC(r, g, b) r -= (g >> 1), g += r, r -= (b >> 1), b += r
+
+#define _ICC(r, g, b)  (g -= ((r + 0) >> 1), r -= ((b + 1) >> 1) - g, b += r)
+#define _ICC_CMYK(c, m, y, k) (k -= ((m + 1) >> 1), m -= (c >> 1) - k, c -= ((y + 1) >> 1) - m, y += c)
+
+#define _CLIP2(l, v, h) ((v) < (l) ? (l) : ((h) < (v) ? (h) : (v)))
+#define _CLIP8(v) ((U8)_CLIP2(0, v, 255))
+#define _CLIP16(v) ((I16)_CLIP2(-32768, v, 32767))
+#define _CLIPU16(v) ((U16)_CLIP2(0, v, 65535))
+
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+
+//inverseConvert: Inverse conversion from float RGB to RGBE
+static _FORCEINLINE void inverseConvert (PixelI iF, U8 *pRGB, U8 *pE)
+{
+    if (iF <= 0) {
+        *pRGB = *pE = 0;
+    }
+    else if ((iF >> 7) > 1) {
+        /** normal form **/
+        *pE = (U8) (iF >> 7); //+ 1;
+        *pRGB = (iF & 0x7f) | 0x80;
+    }
+    else {  
+        /** denormal form **/
+        *pE = 1;
+        *pRGB = (U8) iF;
+    }
+}
+
+#ifdef __ANSI__
+#define max(a,b) ((a) > (b) ? (a) : (b))
+#endif // __ANSI__
+
+static _FORCEINLINE void inverseConvertRGBE (PixelI iFr, PixelI iFg, PixelI iFb, U8 *pR, U8 *pG, U8 *pB, U8 *pE)
+{
+    U8 iShift;
+
+    U8 pR_E, pG_E, pB_E;
+
+    inverseConvert (iFr, pR, &pR_E);
+    inverseConvert (iFg, pG, &pG_E);
+    inverseConvert (iFb, pB, &pB_E);
+
+    *pE = max(max(pR_E, pG_E), pB_E); 
+
+    if(*pE > pR_E){
+            iShift = (*pE - pR_E);
+            *pR = (U8)((((int)*pR) * 2 + 1) >> (iShift + 1));
+    }
+    if(*pE > pG_E){
+            iShift = (*pE - pG_E);
+            *pG = (U8)((((int)*pG) * 2 + 1) >> (iShift + 1));
+    }
+    if(*pE > pB_E){
+            iShift = (*pE - pB_E);
+            *pB = (U8)((((int)*pB) * 2 + 1) >> (iShift + 1));
+    }
+}
+
+
+//pixel to float 32!
+static _FORCEINLINE float pixel2float(PixelI _h, const char _c, const unsigned char _lm)
+{
+    union uif
+    {
+        I32   i;
+        float f;
+    } x;
+
+    I32 s, iTempH, m, e, lmshift = (1 << _lm);
+
+    // assert (_c <= 127);
+
+    iTempH = (I32) _h ;
+    s = (iTempH >> 31);
+    iTempH = (iTempH ^ s) - s; // abs(iTempH)
+
+    e = (U32) iTempH >> _lm;// & ((1 << (31 - _lm)) - 1);
+    m = (iTempH & (lmshift - 1)) | lmshift; // actual mantissa, with normalizer
+    if (e == 0) { // denormal land
+        m ^= lmshift; // normalizer removed
+        e = 1; // actual exponent
+    }
+
+    e += (127 - _c);
+    while (m < lmshift && e > 1 && m > 0) { // denormal originally, see if normal is possible
+        e--;
+        m <<= 1;
+    }
+    if (m < lmshift) // truly denormal
+        e = 0;
+    else
+        m ^= lmshift;
+    m <<= (23 - _lm);
+
+    x.i = (s & 0x80000000) | (e << 23) | m;
+
+    return x.f;
+}
+
+//convert Half-16 to internal format, only need to handle sign bit
+static _FORCEINLINE U16 backwardHalf (PixelI hHalf)
+{
+    PixelI s;
+    s = hHalf >> 31;
+    hHalf = ((hHalf & 0x7fff) ^ s) - s; // don't worry about overflow
+    return (U16) hHalf;
+}
+
+
+Void interpolateUV(CWMImageStrCodec * pSC)
+{
+    const COLORFORMAT cfExt = pSC->WMII.cfColorFormat;
+    const size_t cWidth = pSC->cmbWidth * 16;
+    PixelI * pSrcU = pSC->a0MBbuffer[1], * pSrcV = pSC->a0MBbuffer[2];
+    PixelI * pDstU = pSC->pResU, * pDstV = pSC->pResV;
+    size_t iRow, iColumn;
+    size_t iIdxS = 0, iIdxD = 0;
+
+    if(pSC->m_param.cfColorFormat == YUV_422){  // 422 => 444, interpolate horizontally
+        for(iRow = 0; iRow < 16; iRow ++){
+            for(iColumn = 0; iColumn < cWidth; iColumn += 2){
+                iIdxS = ((iColumn >> 4) << 7) + idxCC[iRow][(iColumn >> 1) & 7];
+                iIdxD = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
+
+                // copy over
+                pDstU[iIdxD] = pSrcU[iIdxS];
+                pDstV[iIdxD] = pSrcV[iIdxS];
+
+                if(iColumn > 0){
+                    size_t iL = iColumn - 2, iIdxL = ((iL >> 4) << 8) + idxCC[iRow][iL & 15];
+                    size_t iC = iColumn - 1, iIdxC = ((iC >> 4) << 8) + idxCC[iRow][iC & 15];
+                    
+                    // interpolate
+                    pDstU[iIdxC] = ((pDstU[iIdxL] + pDstU[iIdxD] + 1) >> 1);
+                    pDstV[iIdxC] = ((pDstV[iIdxL] + pDstV[iIdxD] + 1) >> 1);
+                }
+            }
+
+            //last pixel
+            iIdxS = (((iColumn - 1) >> 4) << 8) + idxCC[iRow][(iColumn - 1) & 15];
+            pDstU[iIdxS] = pDstU[iIdxD];
+            pDstV[iIdxS] = pDstV[iIdxD];
+        }
+    }
+    else{ // 420 => 422 or 444, interpolate vertically
+        const size_t cShift = (cfExt == YUV_422 ? 3 : 4);
+        
+        for(iColumn = 0; iColumn < cWidth; iColumn += 2){
+            const size_t cMB = ((iColumn >> 4) << (4 + cShift)), cPix = (iColumn >> (4 - cShift)) & ((1 << cShift) - 1);
+            
+            for(iRow = 0; iRow < 16; iRow += 2){
+                iIdxS = ((iColumn >> 4) << 6) + idxCC_420[iRow >> 1][(iColumn >> 1) & 7];
+                iIdxD = cMB + idxCC[iRow][cPix];
+                
+                // copy over
+                pDstU[iIdxD] = pSrcU[iIdxS];
+                pDstV[iIdxD] = pSrcV[iIdxS];
+
+                if(iRow > 0){
+                    size_t iIdxT = cMB + idxCC[iRow - 2][cPix];
+                    size_t iIdxC = cMB + idxCC[iRow - 1][cPix];
+                    
+                    // interpolate
+                    pDstU[iIdxC] = ((pDstU[iIdxT] + pDstU[iIdxD] + 1) >> 1);
+                    pDstV[iIdxC] = ((pDstV[iIdxT] + pDstV[iIdxD] + 1) >> 1);
+                }
+            }
+
+            //last row
+            iIdxS = cMB + idxCC[15][cPix];
+            if(pSC->cRow == pSC->cmbHeight){ // image boundary
+                pDstU[iIdxS] = pDstU[iIdxD];
+                pDstV[iIdxS] = pDstV[iIdxD];
+            }
+            else{ // need next MB row
+                size_t iIdxB = ((iColumn >> 4) << 6) + idxCC_420[0][(iColumn >> 1) & 7];
+
+                pDstU[iIdxS] = ((pSC->a1MBbuffer[1][iIdxB] + pDstU[iIdxD] + 1) >> 1);
+                pDstV[iIdxS] = ((pSC->a1MBbuffer[2][iIdxB] + pDstV[iIdxD] + 1) >> 1);
+            }
+        }
+
+        if(cfExt != YUV_422){ // 420 => 444, interpolate horizontally
+            for(iRow = 0; iRow < 16; iRow ++){
+                for(iColumn = 1; iColumn < cWidth - 2; iColumn += 2){
+                    size_t iIdxL = (((iColumn - 1) >> 4) << 8) + idxCC[iRow][(iColumn - 1) & 15];
+
+                    iIdxD = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
+                    iIdxS = (((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15];
+                    
+                    pDstU[iIdxD] = ((pDstU[iIdxS] + pDstU[iIdxL] + 1) >> 1);
+                    pDstV[iIdxD] = ((pDstV[iIdxS] + pDstV[iIdxL] + 1) >> 1);
+                }
+
+                // last pixel
+                iIdxD = (((cWidth - 1) >> 4) << 8) + idxCC[iRow][(cWidth - 1) & 15];
+                pDstU[iIdxD] = pDstU[iIdxS];
+                pDstV[iIdxD] = pDstV[iIdxS];
+            }
+        }
+    }
+}
+
+// write one MB row of Y_ONLY/CF_ALPHA/YUV_444/N_CHANNEL to output buffer
+Void outputNChannel(CWMImageStrCodec * pSC, size_t iFirstRow, size_t iFirstColumn, size_t cWidth, size_t cHeight, size_t iShift, PixelI iBias)
+{
+    const CWMImageInfo* pII = &pSC->WMII;
+    const size_t cChannel = pII->cfColorFormat == Y_ONLY ? 1 : pSC->WMISCP.cChannel;
+    // const U8 cbChannels[BDB_MAX] = {-1, 1, 2, 2, 2, 4, 4, -1, -1, };
+    const U8 nLen = pSC->WMISCP.nLenMantissaOrShift;
+    const I8 nExpBias = pSC->WMISCP.nExpBias;
+
+    PixelI * pChannel[16];
+    size_t iChannel, iRow, iColumn;
+    size_t * pOffsetX = pSC->m_Dparam->pOffsetX, * pOffsetY = pSC->m_Dparam->pOffsetY + (pSC->cRow - 1) * 16, iY;
+
+    assert(cChannel <= 16);
+
+    for(iChannel = 0; iChannel < cChannel; iChannel ++)
+        pChannel[iChannel & 15] = pSC->a0MBbuffer[iChannel];
+
+    if(pSC->m_bUVResolutionChange)
+        pChannel[1] = pSC->pResU, pChannel[2] = pSC->pResV;
+
+    switch(pSC->WMII.bdBitDepth){
+        case BD_8:
+            for(iRow = iFirstRow; iRow < cHeight; iRow ++){
+                for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
+                    U8 * pDst = (U8 *)pSC->WMIBI.pv + iY + pOffsetX[iColumn];
+
+                    for(iChannel = 0; iChannel < cChannel; iChannel ++){
+                        PixelI p = ((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift);
+                        
+                        pDst[iChannel] = _CLIP8(p);
+                    }
+                }
+            }
+            break;
+
+        case BD_16:
+            for(iRow = iFirstRow; iRow < cHeight; iRow ++){
+                for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
+                    U16 * pDst = (U16 *)pSC->WMIBI.pv + iY + pOffsetX[iColumn];
+
+                    for(iChannel = 0; iChannel < cChannel; iChannel ++){
+                        PixelI p = ((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift);
+                        
+                        p <<= nLen;
+                        pDst[iChannel] = _CLIPU16(p);
+                    }
+                }
+            }
+            break;
+
+        case BD_16S:
+            for(iRow = iFirstRow; iRow < cHeight; iRow ++){
+                for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
+                    I16 * pDst = (I16 *)pSC->WMIBI.pv + iY + pOffsetX[iColumn];
+
+                    for(iChannel = 0; iChannel < cChannel; iChannel ++){
+                        PixelI p = ((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift);
+
+                        p <<= nLen;                        
+                        pDst[iChannel] = _CLIP16(p);
+                    }
+                }
+            }
+            break;
+
+        case BD_16F:
+            for(iRow = iFirstRow; iRow < cHeight; iRow ++){
+                for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
+                    U16 * pDst = (U16 *)pSC->WMIBI.pv + iY + pOffsetX[iColumn];
+
+                    for(iChannel = 0; iChannel < cChannel; iChannel ++){
+                        PixelI p = ((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] + iBias) >> iShift);
+                        
+                        pDst[iChannel] = backwardHalf(p);
+                    }
+                }
+            }
+            break;
+
+        case BD_32:
+            for(iRow = iFirstRow; iRow < cHeight; iRow ++){
+                for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
+                    U32 * pDst = (U32 *)pSC->WMIBI.pv + iY + pOffsetX[iColumn];
+
+                    for(iChannel = 0; iChannel < cChannel; iChannel ++){
+                        PixelI p = ((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] + iBias) >> iShift);
+
+                        p <<= nLen;
+                        pDst[iChannel] = (U32)(p);
+                    }
+                }
+            }
+            break;
+
+        case BD_32S:
+            for(iRow = iFirstRow; iRow < cHeight; iRow ++){
+                for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
+                    I32 * pDst = (I32 *)pSC->WMIBI.pv + iY + pOffsetX[iColumn];
+
+                    for(iChannel = 0; iChannel < cChannel; iChannel ++){
+                        PixelI p = ((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] + iBias) >> iShift);
+
+                        p <<= nLen;
+                        pDst[iChannel] = (I32)(p);
+                    }
+                }
+            }
+            break;
+
+        case BD_32F:
+            for(iRow = iFirstRow; iRow < cHeight; iRow ++){
+                for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
+                    float * pDst = (float *)pSC->WMIBI.pv + iY + pOffsetX[iColumn];
+
+                    for(iChannel = 0; iChannel < cChannel; iChannel ++){
+                        PixelI p = ((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] + iBias) >> iShift);                       
+                        
+                        pDst[iChannel] = pixel2float (p, nExpBias, nLen);
+                    }
+                }
+            }
+            break;
+
+        default:
+            assert(0);
+            break;
+    }
+}
+
+static void fixup_Y_ONLY_to_Others(
+    const CWMImageStrCodec* pSC,
+    const CWMImageBufferInfo* pBI)
+{
+    const CWMImageInfo* pII = &pSC->WMII;
+    const CWMIStrCodecParam* pSCP = &pSC->WMISCP;
+    size_t cWidth = 0, cHeight = 0;
+    size_t idxY = 0, idxX = 0;
+
+    if (CF_RGB != pII->cfColorFormat || Y_ONLY != pSCP->cfColorFormat)
+        return;
+
+    cWidth = 0 != pII->cROIWidth ? pII->cROIWidth : pII->cWidth;
+    cHeight = 0 != pII->cROIHeight ? pII->cROIHeight : pII->cHeight;
+
+#define fixup(type, nCh) \
+for (idxY = 0; idxY < cHeight; ++idxY) \
+{ \
+    type * pT = (type *)((U8*)pBI->pv + pBI->cbStride * idxY); \
+    for (idxX = 0; idxX < cWidth; ++idxX) \
+    { \
+        pT[2] = pT[1] = pT[0]; \
+        pT += nCh; \
+    } \
+} \
+break
+
+    switch (pII->bdBitDepth)
+    {
+        case BD_8:
+            fixup(U8, (pII->cBitsPerUnit >> 3));
+            break;
+
+        case BD_16:
+        case BD_16S:
+        case BD_16F:
+            fixup(U16, (pII->cBitsPerUnit >> 3) / sizeof(U16));
+            break;
+
+        case BD_32:
+        case BD_32S:
+        case BD_32F:
+            fixup(U32, (pII->cBitsPerUnit >> 3) / sizeof(float));
+            break;
+
+        case BD_5:
+        case BD_10:
+        case BD_565:
+        default:
+            break;
+    }
+}
+
+// centralized alpha channel color conversion, small perf penalty
+Int outputMBRowAlpha(CWMImageStrCodec * pSC)
+{
+    if(pSC->WMII.bdBitDepth == BD_8 && pSC->WMISCP.cfColorFormat == CF_RGB)  // has been taken care of and optimized out
+        return ICERR_OK;
+
+    if(pSC->m_bSecondary == FALSE && pSC->m_pNextSC != NULL){ // with alpha channel
+        const BITDEPTH_BITS bd = pSC->WMII.bdBitDepth;
+        const PixelI iShift = (pSC->m_param.bScaledArith ? SHIFTZERO + QPFRACBITS : 0);
+        const size_t cHeight = min((pSC->m_Dparam->cROIBottomY + 1) - (pSC->cRow - 1) * 16, 16);
+        const size_t cWidth = (pSC->m_Dparam->cROIRightX + 1);
+        const size_t iFirstRow = ((pSC->cRow - 1) * 16 > pSC->m_Dparam->cROITopY ? 0 : (pSC->m_Dparam->cROITopY & 0xf)), iFirstColumn = pSC->m_Dparam->cROILeftX;
+        const size_t iAlphaPos = pSC->WMII.cLeadingPadding + (pSC->WMII.cfColorFormat == CMYK ? 4 : 3);//only RGB and CMYK may have interleaved alpha
+        const PixelI * pA = pSC->m_pNextSC->a0MBbuffer[0];
+        const U8 nLen = pSC->WMISCP.nLenMantissaOrShift;
+        const I8 nExpBias = pSC->WMISCP.nExpBias;
+        size_t iRow, iColumn;
+        size_t * pOffsetX = pSC->m_Dparam->pOffsetX, * pOffsetY = pSC->m_Dparam->pOffsetY + (pSC->cRow - 1) * 16, iY;
+        
+        if (CF_RGB != pSC->WMII.cfColorFormat && CMYK != pSC->WMII.cfColorFormat)
+            return ICERR_ERROR;
+
+        if(bd == BD_8){
+            const PixelI iBias = (1 << (iShift + 7)) + (iShift == 0 ? 0 : (1 << (iShift - 1)));
+            
+            for(iRow = iFirstRow; iRow < cHeight; iRow ++)
+                for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
+                    PixelI a = ((pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift);
+                    ((U8 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY)[iAlphaPos] = _CLIP8(a);
+                }
+        }
+        else if(bd == BD_16){
+            const PixelI iBias = (1 << (iShift + 15)) + (iShift == 0 ? 0 : (1 << (iShift - 1)));
+
+            for(iRow = iFirstRow; iRow < cHeight; iRow ++)
+                for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
+                    PixelI a = (((pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift) << nLen);
+                    ((U16 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY)[iAlphaPos] = _CLIPU16(a);
+                }
+        }
+        else if(bd == BD_16S){
+            const PixelI iBias = (iShift == 0 ? 0 : (1 << (iShift - 1)));
+            
+            for(iRow = iFirstRow; iRow < cHeight; iRow ++)
+                for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
+                    PixelI a = (((pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift) << nLen);
+                    ((I16 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY)[iAlphaPos] = _CLIP16(a);
+                }
+        }
+        else if(bd == BD_16F){
+            const PixelI iBias = (iShift == 0 ? 0 : (1 << (iShift - 1)));
+
+            for(iRow = iFirstRow; iRow < cHeight; iRow ++)
+                for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
+                    PixelI a = ((pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift);
+                    ((U16 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY)[iAlphaPos] = backwardHalf(a);
+                }
+        }
+        else if(bd == BD_32S){
+            const PixelI iBias = (iShift == 0 ? 0 : (1 << (iShift - 1)));
+            
+            for(iRow = iFirstRow; iRow < cHeight; iRow ++)
+                for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
+                    PixelI a = (((pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift) << nLen);
+                    ((I32 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY)[iAlphaPos] = a;
+                }
+        }
+        else if(bd == BD_32F){
+            const PixelI iBias = (iShift == 0 ? 0 : (1 << (iShift - 1)));
+            
+            for(iRow = iFirstRow; iRow < cHeight; iRow ++)
+                for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
+                    PixelI a = ((pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift);
+                    ((float *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY)[iAlphaPos] = pixel2float (a, nExpBias, nLen);
+                }
+        }
+        else // not supported
+            return ICERR_ERROR;
+    }
+
+    return ICERR_OK;
+}
+
+Int outputMBRow(CWMImageStrCodec * pSC)
+{
+    const COLORFORMAT cfExt = (pSC->m_param.cfColorFormat == Y_ONLY ? Y_ONLY : pSC->WMII.cfColorFormat);
+    const BITDEPTH_BITS bd = pSC->WMII.bdBitDepth;
+    const PixelI iShift = (pSC->m_param.bScaledArith ? SHIFTZERO + QPFRACBITS : 0);
+    const size_t cHeight = min((pSC->m_Dparam->cROIBottomY + 1) - (pSC->cRow - 1) * 16, 16);
+    const size_t cWidth = (pSC->m_Dparam->cROIRightX + 1);
+    const size_t iFirstRow = ((pSC->cRow - 1) * 16 > pSC->m_Dparam->cROITopY ? 0 : (pSC->m_Dparam->cROITopY & 0xf)), iFirstColumn = pSC->m_Dparam->cROILeftX;
+    const PixelI *pY = pSC->a0MBbuffer[0];
+    const PixelI *pU = (pSC->m_bUVResolutionChange ? pSC->pResU : pSC->a0MBbuffer[1]);
+    const PixelI *pV = (pSC->m_bUVResolutionChange ? pSC->pResV : pSC->a0MBbuffer[2]);
+    const PixelI *pA = NULL;
+	const size_t iB = (pSC->WMII.bRGB ? 2 : 0);
+	const size_t iR = 2 - iB;
+    const U8 nLen = pSC->WMISCP.nLenMantissaOrShift;
+    const I8 nExpBias = pSC->WMISCP.nExpBias;
+    size_t iRow, iColumn, iIdx;
+    size_t * pOffsetX = pSC->m_Dparam->pOffsetX, * pOffsetY = pSC->m_Dparam->pOffsetY + (pSC->cRow - 1) * (cfExt == YUV_420 ? 8 : 16), iY;
+
+
+    if (pSC->m_pNextSC) {
+        assert (pSC->m_param.bScaledArith == pSC->m_pNextSC->m_param.bScaledArith);  // will be relaxed later
+    }
+
+    // guard output buffer
+    if(checkImageBuffer(pSC, pSC->WMII.oOrientation >= O_RCW ? pSC->WMII.cROIHeight : pSC->WMII.cROIWidth, cHeight - iFirstRow) != ICERR_OK)
+        return ICERR_ERROR;
+
+    if(pSC->m_bUVResolutionChange)
+        interpolateUV(pSC);
+
+    if(pSC->WMISCP.bYUVData){
+        I32 * pDst = (I32 *)pSC->WMIBI.pv + (pSC->cRow - 1) *
+            (pSC->m_param.cfColorFormat == YUV_420 ? 8 : 16) * pSC->WMIBI.cbStride / sizeof(I32);
+
+        switch(pSC->m_param.cfColorFormat){
+        case Y_ONLY:
+        case YUV_444:
+        case NCOMPONENT:
+            {
+                PixelI * pChannel[16];
+                size_t iChannel;
+
+                const size_t cChannel = pSC->WMII.cfColorFormat == Y_ONLY ? 1 : pSC->WMISCP.cChannel;
+                assert(cChannel <= 16);
+
+                for(iChannel = 0; iChannel < cChannel; iChannel ++)
+                    pChannel[iChannel & 15] = pSC->a0MBbuffer[iChannel];
+
+                for(iRow = iFirstRow; iRow < cHeight; iRow ++){
+                    I32 * pRow = pDst;
+                    for(iColumn = iFirstColumn; iColumn < cWidth; iColumn ++){
+                        for(iChannel = 0; iChannel < cChannel; iChannel ++){
+                            PixelI p = pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]];
+
+                            *pRow++ = p;
+                        }
+                    }
+                    pDst += pSC->WMIBI.cbStride / sizeof(I32);
+                }
+            }
+            break;
+
+        case YUV_422:
+            {
+				PixelI y0, y1, u, v;
+	
+				for(iRow = iFirstRow; iRow < cHeight; iRow ++){
+                    I32 * pRow = pDst;
+					for(iColumn = iFirstColumn; iColumn < cWidth; iColumn += 2){
+						iIdx = ((iColumn >> 4) << 7) + idxCC[iRow][(iColumn >> 1) & 7];
+						u = pU[iIdx], v = pV[iIdx];
+	
+						y0 = pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]];
+						y1 = pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]];
+						
+						pRow[0] = u, pRow[1] = y0, pRow[2] = v, pRow[3] = y1;
+                        pRow += 4;
+					}
+                    pDst += pSC->WMIBI.cbStride / sizeof(I32);
+				}
+			}
+            break;
+
+        case YUV_420:
+			{
+				PixelI y0, y1, y2, y3, u, v;
+				// const size_t iS4[8][4] = {{0, 1, 2, 3}, {2, 3, 0, 1}, {1, 0, 3, 2}, {3, 2, 1, 0}, {1, 3, 0, 2}, {3, 1, 2, 0}, {0, 2, 1, 3}, {2, 0, 3, 1}};
+	
+				for(iRow = iFirstRow; iRow < cHeight; iRow += 2){
+                    I32 * pRow = pDst;
+					for(iColumn = iFirstColumn; iColumn < cWidth; iColumn += 2){
+						iIdx = ((iColumn >> 4) << 6) + idxCC_420[iRow >> 1][(iColumn >> 1) & 7];
+						u = pU[iIdx], v = pV[iIdx];
+	
+						y0 = pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]];
+						y1 = pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]];
+						y2 = pY[((iColumn >> 4) << 8) + idxCC[iRow + 1][iColumn & 15]];
+						y3 = pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow + 1][(iColumn + 1) & 15]];
+	
+						pRow[0] = y0, pRow[1] = y1, pRow[2] = y2, pRow[3] = y3, pRow[4] = u, pRow[5] = v;
+                        pRow += 6;
+					}
+                    pDst += pSC->WMIBI.cbStride / sizeof(I32);
+				}
+			}
+            break;
+
+        default:
+            assert(0);
+            break;
+        }
+    }
+    else if(bd == BD_8){
+        U8 * pDst;
+        const PixelI iBias1 = 128 << iShift;
+        const PixelI iBias2 = pSC->m_param.bScaledArith ? ((1 << (SHIFTZERO + QPFRACBITS - 1)) - 1) : 0;
+        const PixelI iBias = iBias1 + iBias2;
+
+        switch(cfExt){
+        case CF_RGB:
+        {
+            PixelI r, g, b, a;
+
+            if (pSC->m_pNextSC && pSC->WMISCP.uAlphaMode > 0) { // RGBA
+
+                pA = pSC->m_pNextSC->a0MBbuffer[0];
+
+                if (pSC->m_param.bScaledArith == FALSE) {
+                    for(iRow = iFirstRow; iRow < cHeight; iRow ++)
+                        for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
+                            iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
+                            
+                            g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx];
+                            a = pA[iIdx] + iBias;
+
+                            _ICC(r, g, b);
+                            
+                            pDst = (U8 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY;
+                            if ((g | b | r | a) & ~0xff)
+                                pDst[iR] = _CLIP8(r), pDst[1] = _CLIP8(g), pDst[iB] = _CLIP8(b), pDst[3] = _CLIP8(a);
+                            else
+                                pDst[iR] = (U8)r, pDst[1] = (U8)g, pDst[iB] = (U8)b, pDst[3] = (U8)(a);
+                        }
+                }
+                else{
+                    for(iRow = iFirstRow; iRow < cHeight; iRow ++)
+                        for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
+                            iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
+                            
+                            g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx];
+                            a = pA[iIdx] + iBias;
+
+                            _ICC(r, g, b);
+
+                            g >>= iShift, b >>= iShift, r >>= iShift, a >>= iShift;
+                            pDst = (U8 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY;
+                            if ((g | b | r | a) & ~0xff)
+                                pDst[iR] = _CLIP8(r), pDst[1] = _CLIP8(g), pDst[iB] = _CLIP8(b), pDst[3] = _CLIP8(a);
+                            else
+                                pDst[iR] = (U8)r, pDst[1] = (U8)g, pDst[iB] = (U8)b, pDst[3] = (U8)(a);
+                        }
+                }
+            }
+            else {
+                if (pSC->m_param.bScaledArith == FALSE) {
+                    for(iRow = iFirstRow; iRow < cHeight; iRow ++)
+                        for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
+                            iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
+                            
+                            g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx];
+
+                            _ICC(r, g, b);
+                            
+                            pDst = (U8 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY;
+                            if ((g | b | r) & ~0xff)
+                                pDst[iR] = _CLIP8(r), pDst[1] = _CLIP8(g), pDst[iB] = _CLIP8(b);
+                            else
+                                pDst[iR] = (U8)r, pDst[1] = (U8)g, pDst[iB] = (U8)b;
+                        }
+                }
+                else{
+                    for(iRow = iFirstRow; iRow < cHeight; iRow ++)
+                        for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
+                            iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
+                            
+                            g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx];
+
+                            _ICC(r, g, b);
+
+                            g >>= iShift, b >>= iShift, r >>= iShift;
+                            pDst = (U8 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY;
+                            if ((g | b | r) & ~0xff)
+                                pDst[iR] = _CLIP8(r), pDst[1] = _CLIP8(g), pDst[iB] = _CLIP8(b);
+                            else
+                                pDst[iR] = (U8)r, pDst[1] = (U8)g, pDst[iB] = (U8)b;
+                        }
+                }
+            }
+            break;
+        }
+
+        case Y_ONLY:
+        case YUV_444:
+        case NCOMPONENT:
+            outputNChannel(pSC, iFirstRow, iFirstColumn, cWidth, cHeight, iShift, iBias);
+            break;
+
+        case YUV_422:
+			{
+				PixelI y0, y1, u, v;
+				// const ORIENTATION oO = pSC->WMII.oOrientation;
+				// const size_t i0 = ((oO > O_FLIPV && oO <= O_RCW_FLIPVH) ? 1 : 0), i1 = 1 - i0;
+	
+				for(iRow = iFirstRow; iRow < cHeight; iRow ++){
+					for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn += 2){
+						iIdx = ((iColumn >> 4) << 7) + idxCC[iRow][(iColumn >> 1) & 7];
+						u = ((pU[iIdx] + iBias) >> iShift), v = ((pV[iIdx] + iBias) >> iShift);
+	
+						y0 = ((pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift);
+						y1 = ((pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]] + iBias) >> iShift);
+						
+						pDst = (U8 *)pSC->WMIBI.pv + pOffsetX[iColumn >> 1] + iY;
+						if ((y0 | y1 | u | v) & ~0xff)//UYVY
+							pDst[0] = _CLIP8(u), pDst[1] = _CLIP8(y0), pDst[2] = _CLIP8(v), pDst[3] = _CLIP8(y1);
+						else
+							pDst[0] = (U8)u, pDst[1] = (U8)y0, pDst[2] = (U8)v, pDst[3] = (U8)y1;
+					}
+				}
+			}
+			break;
+
+        case YUV_420:
+			{
+				PixelI y0, y1, y2, y3, u, v;
+				const size_t iS4[8][4] = {{0, 1, 2, 3}, {2, 3, 0, 1}, {1, 0, 3, 2}, {3, 2, 1, 0}, {1, 3, 0, 2}, {3, 1, 2, 0}, {0, 2, 1, 3}, {2, 0, 3, 1}};
+				const ORIENTATION oO = pSC->WMII.oOrientation;
+				const size_t i0 = iS4[oO][0], i1 = iS4[oO][1], i2 = iS4[oO][2], i3 = iS4[oO][3];
+	
+				for(iRow = iFirstRow; iRow < cHeight; iRow += 2){
+					for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> 1]; iColumn < cWidth; iColumn += 2){
+						iIdx = ((iColumn >> 4) << 6) + idxCC_420[iRow >> 1][(iColumn >> 1) & 7];
+						u = ((pU[iIdx] + iBias) >> iShift), v = ((pV[iIdx] + iBias) >> iShift);
+	
+						y0 = ((pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift);
+						y1 = ((pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]] + iBias) >> iShift);
+						y2 = ((pY[((iColumn >> 4) << 8) + idxCC[iRow + 1][iColumn & 15]] + iBias) >> iShift);
+						y3 = ((pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow + 1][(iColumn + 1) & 15]] + iBias) >> iShift);
+	
+						pDst = (U8 *)pSC->WMIBI.pv + pOffsetX[iColumn >> 1] + iY;
+						if ((y0 | y1 | y2 | y3 | u | v) & ~0xff)
+							pDst[i0] = _CLIP8(y0), pDst[i1] = _CLIP8(y1), pDst[i2] = _CLIP8(y2), pDst[i3] = _CLIP8(y3), pDst[4] = _CLIP8(u), pDst[5] = _CLIP8(v);
+						else
+							pDst[i0] = (U8)y0, pDst[i1] = (U8)y1, pDst[i2] = (U8)y2, pDst[i3] = (U8)y3, pDst[4] = (U8)u, pDst[5] = (U8)v;
+					}
+				}
+			}
+			break;
+
+        case CMYK:
+			{
+				PixelI c, m, y, k;
+				PixelI * pK = pSC->a0MBbuffer[3];
+	
+				for(iRow = iFirstRow; iRow < cHeight; iRow++){
+					for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn++){
+						iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
+	
+						m = -pY[iIdx] + iBias1, c = pU[iIdx], y = -pV[iIdx], k = pK[iIdx] + iBias2;
+						
+						_ICC_CMYK(c, m, y, k); // color conversion
+	
+						c >>= iShift, m >>= iShift, y >>= iShift, k >>= iShift;
+	
+						pDst = (U8 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY;
+						if ((c | m | y | k) & ~0xff)
+							pDst[0] = _CLIP8(c), pDst[1] = _CLIP8(m), pDst[2] = _CLIP8(y), pDst[3] = _CLIP8(k);
+						else
+							pDst[0] = (U8)c, pDst[1] = (U8)m, pDst[2] = (U8)y, pDst[3] = (U8)k;
+					}
+				}
+			}
+			break;
+
+        case CF_RGBE:
+			{
+				PixelI r, g, b;
+				
+				for(iRow = iFirstRow; iRow < cHeight; iRow ++){
+					for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
+							iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
+							
+							g = pY[iIdx] + iBias2, r = -pU[iIdx], b = pV[iIdx];
+	
+							_ICC(r, g, b);
+	
+							pDst = (U8 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY;
+	
+							inverseConvertRGBE (r >> iShift, g >> iShift, b >> iShift, pDst, pDst + 1, pDst + 2, pDst + 3);
+						}
+				}
+			}
+			break;
+
+        default:
+            assert(0);
+            break;
+    }
+    }
+    else if(bd == BD_16){
+        const PixelI iBias = (((1 << 15) >> nLen) << iShift) + (iShift == 0 ? 0 : (1 << (iShift - 1)));
+        U16 * pDst;
+
+        switch(cfExt){
+        case CF_RGB:
+        {
+            PixelI r, g, b;
+			if (pSC->m_param.bScaledArith == FALSE) {
+				for(iRow = iFirstRow; iRow < cHeight; iRow ++)
+					for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
+						iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
+						
+						g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx];
+
+						_ICC(r, g, b);
+
+						g <<= nLen, b <<= nLen, r <<= nLen;
+						
+						pDst = (U16 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY;
+						
+						if ((g | b | r) & ~0xffff)
+							pDst[0] = _CLIPU16(r),  pDst[1] = _CLIPU16(g), pDst[2] = _CLIPU16(b);
+						else
+							pDst[0] = (U16)r, pDst[1] = (U16)g, pDst[2] = (U16)b;
+					}
+			}
+			else{
+				for(iRow = iFirstRow; iRow < cHeight; iRow ++)
+					for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
+						iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
+						
+						g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx];
+
+						_ICC(r, g, b);
+
+						g = (g >> iShift) << nLen, b = (b >> iShift) << nLen, r = (r >> iShift) << nLen;
+						pDst = (U16 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY;
+						if ((g | b | r) & ~0xffff)
+							pDst[0] = _CLIPU16(r),  pDst[1] = _CLIPU16(g), pDst[2] = _CLIPU16(b);
+						else
+							pDst[0] = (U16)r, pDst[1] = (U16)g, pDst[2] = (U16)b;
+					}
+			}
+            break;
+        }
+
+        case Y_ONLY:
+        case YUV_444:
+        case NCOMPONENT:
+            outputNChannel(pSC, iFirstRow, iFirstColumn, cWidth, cHeight, iShift, iBias);
+            break;
+
+        case YUV_422:
+			{
+				PixelI y0, y1, u, v;
+				const ORIENTATION oO = pSC->WMII.oOrientation;
+				const size_t i0 = ((oO == O_FLIPH || oO == O_FLIPVH || oO == O_RCW_FLIPV || oO == O_RCW_FLIPVH) ? 1 : 0), i1 = 1 - i0;
+	
+				for(iRow = iFirstRow; iRow < cHeight; iRow ++){
+					for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn += 2){
+						iIdx = ((iColumn >> 4) << 7) + idxCC[iRow][(iColumn >> 1) & 7];
+						u = ((pU[iIdx] + iBias) >> iShift) << nLen, v = ((pV[iIdx] + iBias) >> iShift) << nLen;
+	
+						y0 = ((pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift) << nLen;
+						y1 = ((pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]] + iBias) >> iShift) << nLen;
+						
+						pDst = (U16 *)pSC->WMIBI.pv + pOffsetX[iColumn >> 1] + iY;
+						if ((y0 | y1 | u | v) & ~0xffff)
+							{
+								pDst[i0] = _CLIPU16(u);
+								pDst[i1] = _CLIPU16(y0); 
+								pDst[2] = _CLIPU16(v); 
+								pDst[3] = _CLIPU16(y1);
+							}
+						else
+							{
+								pDst[i0] = (U16)(u);
+								pDst[i1] = (U16)(y0);
+								pDst[2] = (U16)(v); 
+								pDst[3] = (U16)(y1);
+							}
+					}
+				}
+			}
+			break;
+
+        case YUV_420:
+			{
+				PixelI y0, y1, y2, y3, u, v;
+				const size_t iS4[8][4] = {{0, 1, 2, 3}, {2, 3, 0, 1}, {1, 0, 3, 2}, {3, 2, 1, 0}, {1, 3, 0, 2}, {3, 1, 2, 0}, {0, 2, 1, 3}, {2, 0, 3, 1}};
+				const ORIENTATION oO = pSC->WMII.oOrientation;
+				const size_t i0 = iS4[oO][0], i1 = iS4[oO][1], i2 = iS4[oO][2], i3 = iS4[oO][3];
+	
+				for(iRow = iFirstRow; iRow < cHeight; iRow += 2){
+					for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> 1]; iColumn < cWidth; iColumn += 2){
+						iIdx = ((iColumn >> 3) << 6) + idxCC[iRow][(iColumn >> 1) & 7];
+						u = ((pU[iIdx] + iBias) >> iShift) << nLen, v = ((pV[iIdx] + iBias) >> iShift) << nLen;
+	
+						y0 = ((pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift) << nLen;
+						y1 = ((pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]] + iBias) >> iShift) << nLen;
+						y2 = ((pY[((iColumn >> 4) << 8) + idxCC[iRow + 1][iColumn & 15]] + iBias) >> iShift) << nLen;
+						y3 = ((pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow + 1][(iColumn + 1) & 15]] + iBias) >> iShift) << nLen;
+	
+						pDst = (U16 *)pSC->WMIBI.pv + pOffsetX[iColumn >> 1] + iY;
+						if ((y0 | y1 | y2 | y3 | u | v) & ~0xffff)
+							{
+								pDst[i0] = _CLIPU16(y0); 
+								pDst[i1] = _CLIPU16(y1); 
+								pDst[i2] = _CLIPU16(y2); 
+								pDst[i3] = _CLIPU16(y3); 
+								pDst[4] = _CLIPU16(u);
+								pDst[5] = _CLIPU16(v);
+							}
+						else
+							{
+								pDst[i0] = (U16)(y0);
+								pDst[i1] = (U16)(y1);
+								pDst[i2] = (U16)(y2);
+								pDst[i3] = (U16)(y3);
+								pDst[4] = (U16)(u);
+								pDst[5] = (U16)(v);
+							}
+					}
+				}
+			}
+			break;
+
+        case CMYK:
+			{
+				PixelI c, m, y, k;
+				PixelI * pK = pSC->a0MBbuffer[3];
+				const PixelI iBias1 = (32768 >> nLen) << iShift;
+				const PixelI iBias2 = iBias - iBias1;
+	
+				for(iRow = iFirstRow; iRow < cHeight; iRow++){
+					for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn++){
+						iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
+	
+						m = -pY[iIdx] + iBias1, c = pU[iIdx], y = -pV[iIdx], k = pK[iIdx] + iBias2;
+						
+						_ICC_CMYK(c, m, y, k); // color conversion
+	
+						c = (c >> iShift) << nLen, m = (m >> iShift) << nLen, y = (y >> iShift) << nLen, k = (k >> iShift) << nLen;
+	
+						pDst = (U16 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY;
+						if ((c | m | y | k) & ~0xffff)
+							pDst[0] = _CLIPU16(c), pDst[1] = _CLIPU16(m), pDst[2] = _CLIPU16(y), pDst[3] = _CLIPU16(k);
+						else
+							pDst[0] = (U16)(c), pDst[1] = (U16)(m), pDst[2] = (U16)(y), pDst[3] = (U16)(k);
+						}
+				}
+			}
+			break; 
+        default:
+            assert(0);
+            break;
+    }
+    }
+    else if(bd == BD_16S){
+        const PixelI iBias = pSC->m_param.bScaledArith ? ((1 << (SHIFTZERO + QPFRACBITS - 1)) - 1) : 0;
+        I16 * pDst;
+
+        switch(cfExt){
+        case CF_RGB:
+        {
+            PixelI r, g, b;
+            
+            for(iRow = iFirstRow; iRow < cHeight; iRow ++)
+                for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
+                    iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
+
+                    g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx];
+                    
+                    _ICC(r, g, b);
+                    
+                    r = (r >> iShift) << nLen, g = (g >> iShift) << nLen, b = (b >> iShift) << nLen;
+                    
+                    pDst = (I16 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY;
+                    pDst[0] = _CLIP16(r), pDst[1] = _CLIP16(g), pDst[2] = _CLIP16(b);
+                }
+            break;
+        }
+
+        case Y_ONLY:
+        case YUV_444:
+        case NCOMPONENT:
+            outputNChannel(pSC, iFirstRow, iFirstColumn, cWidth, cHeight, iShift, iBias);
+            break;
+
+        case CMYK:
+			{
+				PixelI c, m, y, k;
+				PixelI * pK = pSC->a0MBbuffer[3];
+	
+				for(iRow = iFirstRow; iRow < cHeight; iRow++){
+					for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn++){
+						iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
+	
+						m = -pY[iIdx], c = pU[iIdx], y = -pV[iIdx], k = pK[iIdx] + iBias;
+						
+						_ICC_CMYK(c, m, y, k); // color conversion
+	
+						c = (c >> iShift) << nLen, m = (m >> iShift) << nLen, y = (y >> iShift) << nLen, k = (k >> iShift) << nLen;
+	
+						pDst = (I16 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY;
+						pDst[0] = (I16)(c), pDst[1] = (I16)(m), pDst[2] = (I16)(y), pDst[3] = (I16)(k);
+					}
+				}
+			}
+			break;
+
+        default:
+            assert(0);
+            break;
+    }
+    }
+    else if(bd == BD_16F){
+        const PixelI iBias = pSC->m_param.bScaledArith ? ((1 << (SHIFTZERO + QPFRACBITS - 1)) - 1) : 0;
+        U16 *pDst;
+
+        switch (cfExt)
+        {
+        case CF_RGB:
+        {
+            PixelI r, g, b;
+            
+            for(iRow = iFirstRow; iRow < cHeight; iRow ++){
+                for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
+                    iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
+                    
+                    g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx];
+                    
+                    _ICC(r, g, b);
+                                        
+                    pDst = (U16 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY;
+                    pDst[0] = backwardHalf(r >> iShift);
+                    pDst[1] = backwardHalf(g >> iShift);
+                    pDst[2] = backwardHalf(b >> iShift);
+                }
+            }
+            break;
+        }
+
+        case Y_ONLY:
+        case YUV_444:
+        case NCOMPONENT:
+            outputNChannel(pSC, iFirstRow, iFirstColumn, cWidth, cHeight, iShift, iBias);
+            break;
+
+        default:
+            assert(0);
+            break;
+        }
+    }
+    else if(bd == BD_32){
+        const PixelI iBias = (((1 << 31) >> nLen) << iShift) + (iShift == 0 ? 0 : (1 << (iShift - 1)));
+        U32 * pDst;
+
+        switch (cfExt)
+        {
+        case CF_RGB:
+			{
+				PixelI r, g, b;
+				
+				for(iRow = iFirstRow; iRow < cHeight; iRow ++){
+					for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
+						iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
+						
+						g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx];
+	
+						_ICC(r, g, b);
+						
+						pDst = (U32 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY;
+						pDst[0] = ((r >> iShift) << nLen);
+						pDst[1] = ((g >> iShift) << nLen);
+						pDst[2] = ((b >> iShift) << nLen);
+					}
+				}
+			}
+			break;
+
+        case Y_ONLY:
+        case YUV_444:
+        case NCOMPONENT:
+        {
+            outputNChannel(pSC, iFirstRow, iFirstColumn, cWidth, cHeight, iShift, iBias);
+            break;    
+        }
+        default:
+            assert(0);
+            break;
+        }
+    }
+    else if(bd == BD_32S){
+        const PixelI iBias = pSC->m_param.bScaledArith ? ((1 << (SHIFTZERO + QPFRACBITS - 1)) - 1) : 0;
+        int * pDst;
+
+        switch (cfExt)
+        {
+        case CF_RGB:
+        {
+            PixelI r, g, b;
+            
+            for(iRow = iFirstRow; iRow < cHeight; iRow ++){
+                for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
+                    iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
+                    
+                    g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx];
+                    
+                    _ICC(r, g, b);
+                                        
+                    pDst = (int *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY;
+                    pDst[0] = ((r >> iShift) << nLen);
+                    pDst[1] = ((g >> iShift) << nLen);
+                    pDst[2] = ((b >> iShift) << nLen);
+                }
+            }
+            break;
+        }
+
+        case Y_ONLY:
+        case YUV_444:
+        case NCOMPONENT:
+            outputNChannel(pSC, iFirstRow, iFirstColumn, cWidth, cHeight, iShift, iBias);
+            break;    
+
+		default:
+            assert(0);
+            break;
+        }
+    }
+    else if(bd == BD_32F){
+        const PixelI iBias = pSC->m_param.bScaledArith ? ((1 << (SHIFTZERO + QPFRACBITS - 1)) - 1) : 0;
+        float * pDst;
+
+        switch (cfExt)
+        {
+        case CF_RGB:
+        {
+            PixelI r, g, b;
+            
+            for(iRow = iFirstRow; iRow < cHeight; iRow ++){
+                for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
+                    iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
+                    
+                    g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx];
+                    
+                    _ICC(r, g, b);
+                                        
+                    pDst = (float *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY;
+                    pDst[0] = pixel2float (r >> iShift, nExpBias, nLen);
+                    pDst[1] = pixel2float (g >> iShift, nExpBias, nLen);
+                    pDst[2] = pixel2float (b >> iShift, nExpBias, nLen);
+                }
+            }
+            break;
+        }
+        case Y_ONLY:
+        case YUV_444:
+        case NCOMPONENT:
+            outputNChannel(pSC, iFirstRow, iFirstColumn, cWidth, cHeight, iShift, iBias);
+            break;    
+
+        default:
+            assert(0);
+            break;
+        }
+    }
+    else if(bd == BD_5){
+        const PixelI iBias = (16 << iShift) + (pSC->m_param.bScaledArith ? ((1 << (SHIFTZERO + QPFRACBITS - 1)) - 1) : 0);
+        PixelI r, g, b;
+        U16 * pDst;
+
+        assert(cfExt == CF_RGB);
+
+        for(iRow = iFirstRow; iRow < cHeight; iRow ++)
+            for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
+                iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
+                
+                g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx];
+
+                _ICC(r, g, b);
+                
+                g >>= iShift, b >>= iShift, r >>= iShift;
+                pDst = (U16 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY;
+                if (pSC->m_param.bRBSwapped)
+                    pDst[0] = (U16)_CLIP2(0, b, 31) + (((U16)_CLIP2(0, g, 31)) << 5) + (((U16)_CLIP2(0, r, 31)) << 10);
+                else
+                    pDst[0] = (U16)_CLIP2(0, r, 31) + (((U16)_CLIP2(0, g, 31)) << 5) + (((U16)_CLIP2(0, b, 31)) << 10);
+            }
+    }
+    else if(bd == BD_565){
+        const PixelI iBias = (32 << iShift) + (pSC->m_param.bScaledArith ? ((1 << (SHIFTZERO + QPFRACBITS - 1)) - 1) : 0);
+        PixelI r, g, b;
+        U16 * pDst;
+
+        assert(cfExt == CF_RGB);
+
+        for(iRow = iFirstRow; iRow < cHeight; iRow ++)
+            for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
+                iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
+                
+                g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx];
+
+                _ICC(r, g, b);
+                
+                g >>= iShift, b >>= iShift + 1, r >>= iShift + 1;
+                pDst = (U16 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY;
+                if (pSC->m_param.bRBSwapped)
+                    pDst[0] = (U16)_CLIP2(0, b, 31) + (((U16)_CLIP2(0, g, 63)) << 5) + (((U16)_CLIP2(0, r, 31)) << 11);
+                else
+                    pDst[0] = (U16)_CLIP2(0, r, 31) + (((U16)_CLIP2(0, g, 63)) << 5) + (((U16)_CLIP2(0, b, 31)) << 11);
+            }
+    }
+    else if(bd == BD_10){
+        const PixelI iBias = (512 << iShift) + (pSC->m_param.bScaledArith ? ((1 << (SHIFTZERO + QPFRACBITS - 1)) - 1) : 0);
+        PixelI r, g, b;
+        U32 * pDst;
+
+        assert(cfExt == CF_RGB);
+
+        for(iRow = iFirstRow; iRow < cHeight; iRow ++)
+            for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
+                iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
+                
+                g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx];
+
+                _ICC(r, g, b);
+                
+                g >>= iShift, b >>= iShift, r >>= iShift;
+
+                pDst = (U32 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY;
+                if (pSC->m_param.bRBSwapped)
+                    pDst[0] = (U32)_CLIP2(0, b, 1023) + 
+                        (((U32)_CLIP2(0, g, 1023)) << 10) + 
+                        (((U32)_CLIP2(0, r, 1023)) << 20);
+                else
+                    pDst[0] = (U32)_CLIP2(0, r, 1023) + 
+                        (((U32)_CLIP2(0, g, 1023)) << 10) + 
+                        (((U32)_CLIP2(0, b, 1023)) << 20);
+            }
+    }
+    else if(bd == BD_1){
+        const size_t iPos = pSC->WMII.cLeadingPadding;
+        const Int iTh = (iShift > 0) ? (1 << (iShift - 1)) : 1;
+        assert(cfExt == Y_ONLY && pSC->m_param.cfColorFormat == Y_ONLY);
+        
+        if(pSC->WMII.oOrientation < O_RCW)
+            for(iRow = iFirstRow; iRow < cHeight; iRow ++) {
+                iY = pOffsetY[iRow] + iPos;
+                for(iColumn = iFirstColumn; iColumn < cWidth; iColumn ++) {
+                    U8 cByte = ((U8 *)pSC->WMIBI.pv + (pOffsetX[iColumn] >> 3) + iY)[0];
+                    U8 cShift = (U8)(7 - (pOffsetX[iColumn] & 7));
+                    ((U8 *)pSC->WMIBI.pv + (pOffsetX[iColumn] >> 3) + iY)[0] ^= // exor is used because we can't assume the byte was originally zero
+                    (((pSC->WMISCP.bBlackWhite + (pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] >= iTh)
+                    + (cByte >> cShift)) & 0x1) << cShift);
+                }
+            }
+        else
+            for(iRow = iFirstRow; iRow < cHeight; iRow ++) {
+                iY = pOffsetY[iRow] + iPos;
+                for(iColumn = iFirstColumn; iColumn < cWidth; iColumn ++) {
+                    U8 cByte = ((U8 *)pSC->WMIBI.pv + pOffsetX[iColumn] + (iY >> 3))[0];
+                    U8 cShift = (U8)(7 - (iY & 7));  // should be optimized out
+                    ((U8 *)pSC->WMIBI.pv + pOffsetX[iColumn] + (iY >> 3))[0] ^= // exor is used because we can't assume the byte was originally zero
+                    (((pSC->WMISCP.bBlackWhite + (pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] >= iTh)
+                    + (cByte >> cShift)) & 0x1) << cShift);
+                }
+            }
+    }
+
+    if(pSC->WMISCP.uAlphaMode > 0)
+        if(outputMBRowAlpha(pSC) != ICERR_OK)
+            return ICERR_ERROR;
+
+#ifdef REENTRANT_MODE
+    pSC->WMIBI.cLinesDecoded = cHeight - iFirstRow;
+
+    if (CF_RGB == pSC->WMII.cfColorFormat && Y_ONLY == pSC->WMISCP.cfColorFormat)
+    {
+        const CWMImageInfo* pII = &pSC->WMII;
+
+#define fixupFullSize(type, nCh) \
+for(iRow = iFirstRow; iRow < cHeight; iRow ++) {\
+    size_t iY;\
+    for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){\
+        type *pT = (type*)(U8 *)pSC->WMIBI.pv + iY + pOffsetX[iColumn];\
+        pT[2] = pT[1] = pT[0]; \
+        pT += nCh; \
+    } \
+} \
+break
+
+        switch (pII->bdBitDepth)
+        {
+            case BD_8:
+                fixupFullSize(U8, (pII->cBitsPerUnit >> 3));
+                break;
+
+            case BD_16:
+            case BD_16S:
+            case BD_16F:
+                fixupFullSize(U16, (pII->cBitsPerUnit >> 3) / sizeof(U16));
+                break;
+
+            case BD_32:
+            case BD_32S:
+            case BD_32F:
+                fixupFullSize(U32, (pII->cBitsPerUnit >> 3) / sizeof(float));
+                break;
+
+            case BD_5:
+            case BD_10:
+            case BD_565:
+            default:
+                break;
+        }
+    }
+#endif
+
+    return ICERR_OK;
+}
+
+// Y_ONLY/CF_ALPHA/YUV_444/N_CHANNEL thumbnail decode
+Void outputNChannelThumbnail(CWMImageStrCodec * pSC, const PixelI cMul, const size_t rShiftY, size_t iFirstRow, size_t iFirstColumn)
+{
+    const size_t tScale = pSC->m_Dparam->cThumbnailScale;
+    const size_t cWidth = (pSC->m_Dparam->cROIRightX + 1);
+    const size_t cHeight = min((pSC->m_Dparam->cROIBottomY + 1) - (pSC->cRow - 1) * 16, 16);
+    const size_t cChannel = pSC->WMISCP.cChannel;
+    const U8 nLen = pSC->WMISCP.nLenMantissaOrShift;
+    const I8 nExpBias = pSC->WMISCP.nExpBias;
+    size_t nBits = 0;
+    PixelI iOffset;
+    PixelI * pChannel[16];
+    size_t iChannel, iRow, iColumn;
+    size_t * pOffsetX = pSC->m_Dparam->pOffsetX, * pOffsetY = pSC->m_Dparam->pOffsetY + (pSC->cRow - 1) * 16 / tScale, iY;
+
+    while((size_t)(1U << nBits) < tScale)
+        nBits ++;
+
+    assert(cChannel <= 16);
+
+    for(iChannel = 0; iChannel < cChannel; iChannel ++)
+        pChannel[iChannel & 15] = pSC->a0MBbuffer[iChannel];
+
+    if(pSC->m_bUVResolutionChange)
+        pChannel[1] = pSC->pResU, pChannel[2] = pSC->pResV;
+
+    switch(pSC->WMII.bdBitDepth){
+        case BD_8:
+            for(iOffset = (128 << rShiftY) / cMul, iRow = iFirstRow; iRow < cHeight; iRow += tScale){
+                for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
+                    U8 * pDst = (U8 *)pSC->WMIBI.pv + iY + pOffsetX[iColumn >> nBits];
+
+                    for(iChannel = 0; iChannel < cChannel; iChannel ++){
+                        PixelI p = ((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iOffset) * cMul) >> rShiftY;
+                        
+                        pDst[iChannel] = _CLIP8(p);
+                    }
+                }
+            }
+            break;
+
+        case BD_16:
+            for(iOffset = (32768 << rShiftY) / cMul, iRow = iFirstRow; iRow < cHeight; iRow += tScale){
+                for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
+                    U16 * pDst = (U16 *)pSC->WMIBI.pv + iY + pOffsetX[iColumn >> nBits];
+
+                    for(iChannel = 0; iChannel < cChannel; iChannel ++){
+                        PixelI p = (((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iOffset) * cMul) >> rShiftY) << nLen;
+                        
+                        pDst[iChannel] = _CLIPU16(p);
+                    }
+                }
+            }
+            break;
+
+        case BD_16S:
+            for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){
+                for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
+                    I16 * pDst = (I16 *)pSC->WMIBI.pv + iY + pOffsetX[iColumn >> nBits];
+
+                    for(iChannel = 0; iChannel < cChannel; iChannel ++){
+                        PixelI p = ((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] * cMul) >> rShiftY) << nLen;
+                        
+                        pDst[iChannel] = _CLIP16(p);
+                    }
+                }
+            }
+            break;
+
+        case BD_16F:
+            for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){
+                for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
+                    U16 * pDst = (U16 *)pSC->WMIBI.pv + iY + pOffsetX[iColumn >> nBits];
+
+                    for(iChannel = 0; iChannel < cChannel; iChannel ++){
+                        PixelI p = (pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] * cMul) >> rShiftY;
+                        
+                        pDst[iChannel] = backwardHalf(p);
+                    }
+                }
+            }
+            break;
+        case BD_32:
+            for(iOffset = (((1 << 31) >> nLen) << rShiftY) / cMul, iRow = iFirstRow; iRow < cHeight; iRow += tScale){
+                for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
+                    U32 * pDst = (U32 *)pSC->WMIBI.pv + iY + pOffsetX[iColumn >> nBits];
+
+                    for(iChannel = 0; iChannel < cChannel; iChannel ++){
+                        PixelI p = (((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iOffset) * cMul) >> rShiftY) << nLen;
+                        
+                        pDst[iChannel] = (U32)(p);
+                    }
+                }
+            }
+            break;
+        case BD_32S:
+            for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){
+                for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
+                    I32 * pDst = (I32 *)pSC->WMIBI.pv + iY + pOffsetX[iColumn >> nBits];
+
+                    for(iChannel = 0; iChannel < cChannel; iChannel ++){
+                        PixelI p = ((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] * cMul) >> rShiftY) << nLen;
+                        
+                        pDst[iChannel] = (I32)(p);
+                    }
+                }
+            }
+            break;
+        case BD_32F:
+            for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){
+                for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
+                    float * pDst = (float *)pSC->WMIBI.pv + iY + pOffsetX[iColumn >> nBits];
+
+                    for(iChannel = 0; iChannel < cChannel; iChannel ++){
+                        PixelI p = (pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] * cMul) >> rShiftY;
+                        
+                        pDst[iChannel] = pixel2float (p, nExpBias, nLen);
+                    }
+                }
+            }
+            break;
+
+        default:
+            assert(0);
+            break;
+    }
+}
+
+// centralized alpha channel thumbnail, small perf penalty
+Int decodeThumbnailAlpha(CWMImageStrCodec * pSC, const size_t nBits, const PixelI cMul, const size_t rShiftY)
+{
+    if(pSC->m_bSecondary == FALSE && pSC->m_pNextSC != NULL){ // with alpha channel
+        const size_t tScale = (size_t)(1U << nBits);
+        const size_t cHeight = min((pSC->m_Dparam->cROIBottomY + 1) - (pSC->cRow - 1) * 16, 16);
+        const size_t cWidth = (pSC->m_Dparam->cROIRightX + 1);
+        const size_t iFirstRow = ((((pSC->cRow - 1) * 16 > pSC->m_Dparam->cROITopY ? 0 : (pSC->m_Dparam->cROITopY & 0xf)) + tScale - 1) / tScale * tScale);
+        const size_t iFirstColumn = (pSC->m_Dparam->cROILeftX + tScale - 1) / tScale * tScale;
+        const size_t iAlphaPos = pSC->WMII.cLeadingPadding + (pSC->WMII.cfColorFormat == CMYK ? 4 : 3);//only RGB and CMYK may have interleaved alpha
+        const BITDEPTH_BITS bd = pSC->WMII.bdBitDepth;
+        const PixelI * pSrc = pSC->m_pNextSC->a0MBbuffer[0];
+        const U8 nLen = pSC->m_pNextSC->WMISCP.nLenMantissaOrShift;
+        const I8 nExpBias = pSC->m_pNextSC->WMISCP.nExpBias;
+        size_t iRow, iColumn;
+        size_t * pOffsetX = pSC->m_Dparam->pOffsetX, * pOffsetY = pSC->m_Dparam->pOffsetY + (pSC->cRow - 1) * 16 / tScale, iY;
+        
+        if (CF_RGB != pSC->WMII.cfColorFormat && CMYK != pSC->WMII.cfColorFormat)
+            return ICERR_ERROR;
+
+        if(bd == BD_8){
+            const PixelI offset = (128 << rShiftY) / cMul;
+
+            for(iRow = iFirstRow; iRow < cHeight; iRow += tScale)
+                for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
+                    PixelI a = ((pSrc[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] + offset) * cMul) >> rShiftY;
+                    
+                    ((U8 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY)[iAlphaPos] = _CLIP8(a);
+                }
+        }
+        else if(bd == BD_16){
+            const PixelI offset = (32768 << rShiftY) / cMul;
+
+            for(iRow = iFirstRow; iRow < cHeight; iRow += tScale)
+                for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
+                    PixelI a = (((pSrc[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] + offset) * cMul) >> rShiftY) << nLen;
+
+                    ((U16 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY)[iAlphaPos] = _CLIPU16(a);
+                }
+        }
+        else if(bd == BD_16S){
+            for(iRow = iFirstRow; iRow < cHeight; iRow += tScale)
+                for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
+                    PixelI a = ((pSrc[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] * cMul) >> rShiftY) << nLen;
+
+                    ((I16 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY)[iAlphaPos] = _CLIP16(a);
+                }
+        }
+        else if(bd == BD_16F){
+            for(iRow = iFirstRow; iRow < cHeight; iRow += tScale)
+                for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
+                    PixelI a = (pSrc[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] * cMul) >> rShiftY;
+
+                    ((U16 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY)[iAlphaPos] = backwardHalf(a);
+                }
+        }
+        else if(bd == BD_32S){
+            for(iRow = iFirstRow; iRow < cHeight; iRow += tScale)
+                for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
+                    PixelI a = ((pSrc[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] * cMul) >> rShiftY) << nLen;
+
+                    ((I32 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY)[iAlphaPos] = a;
+                }
+        }
+        else if(bd == BD_32F){
+            for(iRow = iFirstRow; iRow < cHeight; iRow += tScale)
+                for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
+                    PixelI a = (pSrc[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] * cMul) >> rShiftY;
+
+                    ((float *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY)[iAlphaPos] = pixel2float (a, nExpBias, nLen);
+                }
+        }
+        else // not supported
+            return ICERR_ERROR;
+    }
+
+    return ICERR_OK;
+}
+
+Int decodeThumbnail(CWMImageStrCodec * pSC)
+{
+    const size_t tScale = pSC->m_Dparam->cThumbnailScale;
+    const size_t cHeight = min((pSC->m_Dparam->bDecodeFullFrame ? pSC->WMII.cHeight : pSC->m_Dparam->cROIBottomY + 1) - (pSC->cRow - 1) * 16, 16);
+    const size_t cWidth = (pSC->m_Dparam->bDecodeFullFrame ? pSC->WMII.cWidth : pSC->m_Dparam->cROIRightX + 1);
+    const size_t iFirstRow = ((((pSC->cRow - 1) * 16 > pSC->m_Dparam->cROITopY ? 0 : (pSC->m_Dparam->cROITopY & 0xf)) + tScale - 1) / tScale * tScale);
+    const size_t iFirstColumn = (pSC->m_Dparam->cROILeftX + tScale - 1) / tScale * tScale;
+    const COLORFORMAT cfInt = pSC->m_param.cfColorFormat;
+    const COLORFORMAT cfExt = (pSC->m_param.cfColorFormat == Y_ONLY ? Y_ONLY : pSC->WMII.cfColorFormat);
+    const BITDEPTH_BITS bd = pSC->WMII.bdBitDepth;
+    const OVERLAP ol = pSC->WMISCP.olOverlap;
+	const size_t iB = (pSC->WMII.bRGB ? 2 : 0);
+    const size_t iR = 2 - iB;
+
+    const U8 nLen = pSC->WMISCP.nLenMantissaOrShift;
+    const I8 nExpBias = pSC->WMISCP.nExpBias;
+    PixelI offset;
+    size_t iRow, iColumn, iIdx1, iIdx2, iIdx3 = 0, nBits = 0;
+    PixelI * pSrcY = pSC->a0MBbuffer[0];
+    PixelI * pSrcU = pSC->a0MBbuffer[1], * pSrcV = pSC->a0MBbuffer[2];
+    size_t * pOffsetX = pSC->m_Dparam->pOffsetX, * pOffsetY = pSC->m_Dparam->pOffsetY + (pSC->cRow - 1) * 16 / tScale, iY;
+    const PixelI cMul = (tScale >= 16 ? (ol == OL_NONE ? 16 : (ol == OL_ONE ? 23 : 34)) : (tScale >= 4 ? (ol == OL_NONE ? 64 : 93) : 258));
+    const size_t rShiftY = 8 + (pSC->m_param.bScaledArith ? (SHIFTZERO + QPFRACBITS) : 0);
+    const size_t rShiftUV = rShiftY - ((pSC->m_param.bScaledArith && tScale >= 16) ? ((cfInt == YUV_420 || cfInt == YUV_422) ? 2 : 1) : 0);
+
+    while((size_t)(1U << nBits) < tScale)
+        nBits ++;
+
+    assert(tScale == (size_t)(1U << nBits));
+
+    // guard output buffer
+    if(checkImageBuffer(pSC, pSC->WMII.oOrientation < O_RCW ? pSC->WMII.cROIWidth : pSC->WMII.cROIHeight, (cHeight - iFirstRow) / pSC->m_Dparam->cThumbnailScale) != ICERR_OK)
+        return ICERR_ERROR;
+
+    if((((pSC->cRow - 1) * 16) % tScale) != 0)
+        return ICERR_OK;
+
+    if(pSC->cRow * 16 <= pSC->m_Dparam->cROITopY || pSC->cRow * 16 > pSC->m_Dparam->cROIBottomY + 16)
+        return ICERR_OK;
+    
+    if((cfInt == YUV_422 || cfInt == YUV_420) && cfExt != Y_ONLY){
+        PixelI * pDstU = pSC->pResU, * pDstV = pSC->pResV;
+
+        for(iRow = 0; iRow < 16; iRow += tScale){
+            for(iColumn = 0; iColumn < cWidth; iColumn += tScale){
+                iIdx1 = (cfInt == YUV_422 ? ((iColumn >> 4) << 7) + idxCC[iRow][(iColumn >> 1) & 7] : ((iColumn >> 4) << 6) + idxCC_420[iRow >> 1][(iColumn >> 1) & 7]);
+                iIdx2 = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
+
+                // copy over
+                pDstU[iIdx2] = pSrcU[iIdx1];
+                pDstV[iIdx2] = pSrcV[iIdx1];
+            }
+        }
+
+        if(tScale == 4){
+            if(cfInt == YUV_420){
+                for(iColumn = 0; iColumn < cWidth; iColumn += 8){
+                    iIdx1 = ((iColumn >> 4) << 8) + idxCC[0][iColumn & 15];
+                    iIdx2 = ((iColumn >> 4) << 8) + idxCC[4][iColumn & 15];
+                    iIdx3 = ((iColumn >> 4) << 8) + idxCC[8][iColumn & 15];
+
+                    pDstU[iIdx2] = ((pDstU[iIdx1] + pDstU[iIdx3] + 1) >> 1);
+                    pDstV[iIdx2] = ((pDstV[iIdx1] + pDstV[iIdx3] + 1) >> 1);
+
+                    iIdx1 = ((iColumn >> 4) << 8) + idxCC[12][iColumn & 15];
+                    pDstU[iIdx1] = pDstU[iIdx3];
+                    pDstV[iIdx1] = pDstV[iIdx3];
+                }
+            }
+
+            for(iRow = 0; iRow < 16; iRow += 4){
+                for(iColumn = 0; iColumn < cWidth - 8; iColumn += 8){
+                    iIdx1 = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
+                    iIdx2 = ((iColumn >> 4) << 8) + idxCC[iRow][(iColumn + 4) & 15];
+                    iIdx3 = ((iColumn >> 4) << 8) + idxCC[iRow][(iColumn + 8) & 15];
+
+                    pDstU[iIdx2] = ((pDstU[iIdx1] + pDstU[iIdx3] + 1) >> 1);
+                    pDstV[iIdx2] = ((pDstV[iIdx1] + pDstV[iIdx3] + 1) >> 1);
+                }
+
+                iIdx2 = ((iColumn >> 4) << 8) + idxCC[iRow][(iColumn + 4) & 15];
+                pDstU[iIdx2] = pDstU[iIdx3];
+                pDstV[iIdx2] = pDstV[iIdx3];
+            }
+        }
+
+        pSrcU = pDstU, pSrcV = pDstV;
+    }
+
+    if(bd == BD_8){
+        U8 * pDst;
+
+        offset = (128 << rShiftY) / cMul;
+
+        switch(cfExt){
+            case CF_RGB:
+                for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){
+                    for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
+                        size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
+                        PixelI g = ((pSrcY[iPos] + offset) * cMul) >> rShiftY, r = -(pSrcU[iPos] * cMul) >> rShiftUV, b = (pSrcV[iPos] * cMul) >> rShiftUV;
+
+                        _ICC(r, g, b);
+
+                        pDst = (U8 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY;
+                        pDst[iB] = _CLIP8(b), pDst[1] = _CLIP8(g), pDst[iR] = _CLIP8(r);
+                }
+            }
+            break;
+
+        case Y_ONLY:
+        case YUV_444:
+        case NCOMPONENT:
+            outputNChannelThumbnail(pSC, cMul, rShiftY, iFirstRow, iFirstColumn);
+            break;
+
+        case CF_RGBE:
+            for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){
+                for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
+                    size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
+                    PixelI g = ((pSrcY[iPos] * cMul) >> rShiftY), r = - ((pSrcU[iPos] * cMul) >> rShiftUV), b = ((pSrcV[iPos] * cMul) >> rShiftUV);
+                    
+                    _ICC(r, g, b);
+                    
+                    pDst = (U8 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY;
+                    inverseConvertRGBE (r, g, b, pDst, pDst + 1, pDst + 2, pDst + 3);
+                }
+            }
+            break;
+
+        case CMYK:
+        {
+            PixelI * pSrcK = pSC->a0MBbuffer[3];
+            PixelI iBias1 = (128 << rShiftY) / cMul, iBias2 = (((128 << rShiftUV) / cMul) >> 1);
+
+            for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){
+                for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
+                    size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
+                    PixelI m = ((-pSrcY[iPos] + iBias1) * cMul) >> rShiftY, c = (pSrcU[iPos] * cMul) >> rShiftUV, y = -(pSrcV[iPos] * cMul) >> rShiftUV, k = ((pSrcK[iPos] + iBias2) * cMul) >> rShiftUV;
+                    
+                    _ICC_CMYK(c, m, y, k);
+                    
+                    pDst = (U8 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY;
+                    pDst[0] = _CLIP8(c), pDst[1] = _CLIP8(m), pDst[2] = _CLIP8(y), pDst[3] = _CLIP8(k);
+                }
+            }
+            break;
+        }
+        default:
+            assert(0);
+            break;
+        }
+    }
+    if(bd == BD_16){
+        U16 * pDst;
+
+        offset = (((1 << 15) >> nLen) << rShiftY) / cMul;
+
+        switch(cfExt){
+            case CF_RGB:
+                for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){
+                    for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
+                        size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
+                        PixelI g = ((pSrcY[iPos] + offset) * cMul) >> rShiftY, r = -(pSrcU[iPos] * cMul) >> rShiftUV, b = (pSrcV[iPos] * cMul) >> rShiftUV;
+
+                        _ICC(r, g, b);
+                                                
+                        pDst = (U16 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY;
+                        r <<= nLen, g <<= nLen, b <<= nLen;
+                        pDst[0] = _CLIPU16(r);
+                        pDst[1] = _CLIPU16(g);
+                        pDst[2] = _CLIPU16(b);
+                }
+            }
+            break;
+
+        case Y_ONLY:
+        case YUV_444:
+        case NCOMPONENT:
+            outputNChannelThumbnail(pSC, cMul, rShiftY, iFirstRow, iFirstColumn);
+            break;
+
+        case CMYK:
+        {
+            PixelI * pSrcK = pSC->a0MBbuffer[3];
+            PixelI iBias1 = (32768 << rShiftY) / cMul, iBias2 = (((32768 << rShiftUV) / cMul) >> 1);
+
+            for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){
+                for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
+                    size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
+                    PixelI m = ((-pSrcY[iPos] + iBias1) * cMul) >> rShiftY, c = (pSrcU[iPos] * cMul) >> rShiftUV, y = -(pSrcV[iPos] * cMul) >> rShiftUV, k = ((pSrcK[iPos] + iBias2) * cMul) >> rShiftUV;
+                    
+                    _ICC_CMYK(c, m, y, k);
+                    
+                    pDst = (U16 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY;
+                    c <<= nLen, m <<= nLen, y <<= nLen, k <<= nLen;
+                    pDst[0] = _CLIPU16(c);
+                    pDst[1] = _CLIPU16(m);
+                    pDst[2] = _CLIPU16(y);
+                    pDst[3] = _CLIPU16(k);
+                }
+            }
+            break;
+        }
+        default:
+            assert(0);
+            break;
+        }
+    }
+    if(bd == BD_16S){
+        I16 * pDst;
+
+        switch(cfExt){
+            case CF_RGB:
+                for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){
+                    for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
+                        size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
+                        PixelI g = (pSrcY[iPos] * cMul) >> rShiftY, r = -(pSrcU[iPos] * cMul) >> rShiftUV, b = (pSrcV[iPos] * cMul) >> rShiftUV;
+
+                        _ICC(r, g, b);
+                                                
+                        pDst = (I16 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY;
+                        r <<= nLen, g <<= nLen, b <<= nLen;
+                        pDst[0] = _CLIP16(r);
+                        pDst[1] = _CLIP16(g);
+                        pDst[2] = _CLIP16(b);
+                }
+            }
+            break;
+
+        case Y_ONLY:
+        case YUV_444:
+        case NCOMPONENT:
+            outputNChannelThumbnail(pSC, cMul, rShiftY, iFirstRow, iFirstColumn);
+            break;
+
+        case CMYK:
+			{
+				PixelI * pSrcK = pSC->a0MBbuffer[3];
+	
+				for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){
+					for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
+						size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
+						PixelI m = -(pSrcY[iPos] * cMul) >> rShiftY, c = (pSrcU[iPos] * cMul) >> rShiftUV, y = -(pSrcV[iPos] * cMul) >> rShiftUV, k = (pSrcK[iPos] * cMul) >> rShiftUV;
+						
+						_ICC_CMYK(c, m, y, k);
+	
+						pDst = (I16 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY;
+						c <<= nLen, m <<= nLen, y <<= nLen, k <<= nLen;
+						pDst[0] = _CLIP16(c); 
+						pDst[1] = _CLIP16(m);
+						pDst[2] = _CLIP16(y);
+						pDst[3] = _CLIP16(k);
+					}
+				}
+			}
+			break;
+
+        default:
+            assert(0);
+            break;
+        }
+    }
+    else if(bd == BD_16F){
+        U16 * pDst;
+
+        switch(cfExt){
+            case CF_RGB:
+                for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){
+                    for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
+                        size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
+                        PixelI g = (pSrcY[iPos] * cMul) >> rShiftY, r = -(pSrcU[iPos] * cMul) >> rShiftUV, b = (pSrcV[iPos] * cMul) >> rShiftUV;
+
+                        _ICC(r, g, b);
+                        
+                        pDst = (U16 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY;
+                        pDst[0] = backwardHalf (r);
+                        pDst[1] = backwardHalf (g);
+                        pDst[2] = backwardHalf (b);
+                    }
+                }
+                break;
+
+            case Y_ONLY:
+            case YUV_444:
+            case NCOMPONENT:
+                outputNChannelThumbnail(pSC, cMul, rShiftY, iFirstRow, iFirstColumn);
+            break;
+
+            default:
+                assert(0);
+                break;
+        }        
+    }
+    else if(bd == BD_32){
+        U32 * pDst;
+
+        offset = (((1 << 31) >> nLen) << rShiftY) / cMul;
+
+        switch(cfExt){
+            case CF_RGB:
+                for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){
+                    for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
+                        size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
+                        PixelI g = ((pSrcY[iPos] + offset) * cMul) >> rShiftY, r = -(pSrcU[iPos] * cMul) >> rShiftUV, b = (pSrcV[iPos] * cMul) >> rShiftUV;
+
+                        _ICC(r, g, b);
+                        
+                        pDst = (U32 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY;
+
+                        pDst[0] = (U32)(r << nLen);
+                        pDst[1] = (U32)(g << nLen);
+                        pDst[2] = (U32)(b << nLen);
+                    }
+                }
+                break;
+
+            case Y_ONLY:
+            case YUV_444:
+            case NCOMPONENT:
+                outputNChannelThumbnail(pSC, cMul, rShiftY, iFirstRow, iFirstColumn);
+            break;
+
+            default:
+                assert(0);
+                break;
+        }    
+    }
+    else if(bd == BD_32S){
+        I32 * pDst;
+
+        switch(cfExt){
+            case CF_RGB:
+                for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){
+                    for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
+                        size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
+                        PixelI g = (pSrcY[iPos] * cMul) >> rShiftY, r = -(pSrcU[iPos] * cMul) >> rShiftUV, b = (pSrcV[iPos] * cMul) >> rShiftUV;
+
+                        _ICC(r, g, b);
+                        
+                        pDst = (I32 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY;
+                        pDst[0] = (I32)(r << nLen);
+                        pDst[1] = (I32)(g << nLen);
+                        pDst[2] = (I32)(b << nLen);
+                    }
+                }
+                break;
+
+            case Y_ONLY:
+            case YUV_444:
+            case NCOMPONENT:
+                outputNChannelThumbnail(pSC, cMul, rShiftY, iFirstRow, iFirstColumn);
+            break;
+
+            default:
+                assert(0);
+                break;
+        }        
+    }
+
+    else if(bd == BD_32F){
+        float * pDst;
+
+        switch(cfExt){
+            case CF_RGB:
+                for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){
+                    for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
+                        size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
+                        PixelI g = (pSrcY[iPos] * cMul) >> rShiftY, r = -(pSrcU[iPos] * cMul) >> rShiftUV, b = (pSrcV[iPos] * cMul) >> rShiftUV;
+
+                        _ICC(r, g, b);
+                        
+                        pDst = (float *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY;
+                        pDst[0] = pixel2float (r, nExpBias, nLen);
+                        pDst[1] = pixel2float (g, nExpBias, nLen);
+                        pDst[2] = pixel2float (b, nExpBias, nLen);
+                    }
+                }
+                break;
+
+            case Y_ONLY:
+            case YUV_444:
+            case NCOMPONENT:
+                outputNChannelThumbnail(pSC, cMul, rShiftY, iFirstRow, iFirstColumn);
+                break;
+
+            default:
+                assert(0);
+                break;
+        }        
+    }
+    else if(bd == BD_1){
+        const size_t iPos = pSC->WMII.cLeadingPadding;
+        Bool bBW; 
+        U8 cByte, cShift;
+        assert(cfExt == Y_ONLY && pSC->m_param.cfColorFormat == Y_ONLY);        
+
+        if(pSC->WMII.oOrientation < O_RCW){
+            for(iRow = iFirstRow; iRow < cHeight; iRow += tScale)
+                for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits] + iPos; iColumn < cWidth; iColumn += tScale){
+                    bBW = (pSC->WMISCP.bBlackWhite ^ (pSrcY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] > 0));
+                    cByte = ((U8 *)pSC->WMIBI.pv + (pOffsetX[iColumn >> nBits] >> 3) + iY)[0];
+                    cShift = (U8)(7 - (pOffsetX[iColumn >> nBits] & 7)); 
+                    ((U8 *)pSC->WMIBI.pv + (pOffsetX[iColumn >> nBits] >> 3) + iY)[0] ^= ((((bBW + (cByte >> cShift)) & 0x1)) << cShift);
+                }
+        }
+        else{
+            for(iRow = iFirstRow; iRow < cHeight; iRow += tScale)
+                for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits] + iPos; iColumn < cWidth; iColumn += tScale){
+                    bBW = (pSC->WMISCP.bBlackWhite ^ (pSrcY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] > 0));
+                    cByte = ((U8 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + (iY >> 3))[0];
+                    cShift = (U8)(7 - (iY & 7));
+                    ((U8 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + (iY >> 3))[0] ^= ((((bBW + (cByte >> cShift)) & 0x1)) << cShift);
+                }
+        }
+    }
+    else if(bd == BD_5){
+        U16 * pDst;
+
+        offset = (16 << rShiftY) / cMul;
+        
+        for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){
+            for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
+                size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
+                PixelI g = ((pSrcY[iPos] + offset) * cMul) >> rShiftY, r = -(pSrcU[iPos] * cMul) >> rShiftUV, b = (pSrcV[iPos] * cMul) >> rShiftUV;
+
+                _ICC(r, g, b);
+                pDst = (U16 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY;
+                pDst[0] = (U16)_CLIP2(0, r, 31) + (((U16)_CLIP2(0, g, 31)) << 5) + (((U16)_CLIP2(0, b, 31)) << 10);
+            }
+        }
+    }
+    else if(bd == BD_565){
+        U16 * pDst;
+
+        offset = (32 << rShiftY) / cMul;
+        
+        for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){
+            for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
+                size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
+                PixelI g = ((pSrcY[iPos] + offset) * cMul) >> rShiftY, r = -(pSrcU[iPos] * cMul) >> rShiftUV, b = (pSrcV[iPos] * cMul) >> rShiftUV;
+
+                _ICC(r, g, b);
+                r /= 2, b /= 2;
+                pDst = (U16 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY;
+                pDst[0] = (U16)_CLIP2(0, r, 31) + (((U16)_CLIP2(0, g, 63)) << 5) + (((U16)_CLIP2(0, b, 31)) << 11);
+            }
+        }
+    }
+    else if(bd == BD_10){
+        U32 * pDst;
+
+        offset = (512 << rShiftY) / cMul;
+        
+        for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){
+            for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
+                size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
+                PixelI g = ((pSrcY[iPos] + offset) * cMul) >> rShiftY, r = -(pSrcU[iPos] * cMul) >> rShiftUV, b = (pSrcV[iPos] * cMul) >> rShiftUV;
+
+                _ICC(r, g, b);
+                pDst = (U32 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY;
+                pDst[0] = (U32)_CLIP2(0, r, 1023) + 
+                    (((U32)_CLIP2(0, g, 1023)) << 10) + 
+                    (((U32)_CLIP2(0, b, 1023)) << 20);
+            }
+        }
+    }
+
+    if(pSC->WMISCP.uAlphaMode > 0)
+        if(decodeThumbnailAlpha(pSC, nBits, cMul, rShiftY) != ICERR_OK)
+            return ICERR_ERROR;
+
+#ifdef REENTRANT_MODE
+    pSC->WMIBI.cLinesDecoded = ( cHeight - iFirstRow + tScale - 1 ) / tScale;
+    if (CF_RGB == pSC->WMII.cfColorFormat && Y_ONLY == pSC->WMISCP.cfColorFormat)
+    {
+        const CWMImageInfo* pII = &pSC->WMII;
+
+#define fixupThumb(type, nCh) \
+for(iRow = iFirstRow; iRow < cHeight; iRow += tScale) {\
+    size_t iY;\
+    for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){\
+        type *pT = (type*)((U8 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY);\
+        pT[iB] = pT[1] = pT[iR]; \
+    } \
+} \
+break
+
+        switch (pII->bdBitDepth)
+        {
+            case BD_8:
+                fixupThumb(U8, (pII->cBitsPerUnit >> 3));
+                break;
+
+            case BD_16:
+            case BD_16S:
+            case BD_16F:
+                fixupThumb(U16, (pII->cBitsPerUnit >> 3) / sizeof(U16));
+                break;
+
+            case BD_32:
+            case BD_32S:
+            case BD_32F:
+                fixupThumb(U32, (pII->cBitsPerUnit >> 3) / sizeof(float));
+                break;
+
+            case BD_5:
+            case BD_10:
+            case BD_565:
+            default:
+                break;
+        }
+    }
+#endif
+
+    return ICERR_OK;
+}
+
+/*************************************************************************
+    Read variable length byte aligned integer
+*************************************************************************/
+static size_t GetVLWordEsc(BitIOInfo* pIO, Int *iEscape)
+{
+    size_t s;
+
+    if (iEscape)
+        *iEscape = 0;
+
+    s = getBit32(pIO, 8);
+    if (s == 0xfd || s == 0xfe || s == 0xff) {
+        if (iEscape)
+            *iEscape = (Int) s;
+        s = 0;
+    }
+    else if (s < 0xfb) {
+        s = (s << 8) | getBit32(pIO, 8);
+    }
+    else {
+        s -= 0xfb;
+        if (s) {
+            s = getBit32(pIO, 16) << 16;
+            s = (s | getBit32(pIO, 16)) << 16;
+            s <<= 16;
+        }
+        s |= (getBit32(pIO, 16) << 16);
+        s |= getBit32(pIO, 16);
+    }
+    return s;
+}
+
+//================================================================
+Int readIndexTable(CWMImageStrCodec * pSC)
+{
+    BitIOInfo* pIO = pSC->pIOHeader;
+    readIS_L1(pSC, pIO);
+
+    if(pSC->cNumBitIO > 0){
+        size_t *pTable = pSC->pIndexTable;
+        U32 iEntry = (U32)pSC->cNumBitIO * (pSC->WMISCP.cNumOfSliceMinus1H + 1), i;
+
+        // read index table header [0x0001] - 2 bytes
+        if (getBit32(pIO, 16) != 1)
+            return ICERR_ERROR;
+
+        //iBits = getBit16(pIO, 5) + 1; // how many bits per entry
+        for(i = 0; i < iEntry; i ++){
+            readIS_L1(pSC, pIO);
+            pTable[i] = GetVLWordEsc(pIO, NULL);  // escape handling is not important since the respective band is not accessed
+        }
+    }
+
+    pSC->cHeaderSize = GetVLWordEsc(pIO, NULL);  // escape handling is not important
+    flushToByte(pIO);    
+    
+    pSC->cHeaderSize += getPosRead(pSC->pIOHeader); // get header length
+
+    return ICERR_OK;
+}
+
+Int StrIODecInit(CWMImageStrCodec* pSC)
+{
+    if(allocateBitIOInfo(pSC) != ICERR_OK){
+        return ICERR_ERROR;
+    }
+    
+    attachISRead(pSC->pIOHeader, pSC->WMISCP.pWStream, pSC);
+
+    readIndexTable(pSC);
+
+    if(pSC->WMISCP.bVerbose){
+        U32 i, j;
+
+        printf("\n%d horizontal tiles:\n", pSC->WMISCP.cNumOfSliceMinus1H + 1);
+        for(i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1H; i ++){
+            printf("    offset of tile %d in MBs: %d\n", i, pSC->WMISCP.uiTileY[i]);
+        }
+
+        printf("\n%d vertical tiles:\n", pSC->WMISCP.cNumOfSliceMinus1V + 1);
+        for(i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1V; i ++){
+            printf("    offset of tile %d in MBs: %d\n", i, pSC->WMISCP.uiTileX[i]);
+        }
+
+        if(pSC->WMISCP.bfBitstreamFormat == SPATIAL){
+            printf("\nSpatial order bitstream\n");
+        }
+        else{
+            printf("\nFrequency order bitstream\n");
+        }
+
+        if(!pSC->m_param.bIndexTable){
+            printf("\nstreaming mode, no index table.\n");
+        }
+        else if(pSC->WMISCP.bfBitstreamFormat == SPATIAL){
+            for(j = 0; j <= pSC->WMISCP.cNumOfSliceMinus1H; j ++){
+                for(i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1V; i ++){
+                    size_t * p = &pSC->pIndexTable[j * (pSC->WMISCP.cNumOfSliceMinus1V + 1) + i];
+                    if(i + j != pSC->WMISCP.cNumOfSliceMinus1H + pSC->WMISCP.cNumOfSliceMinus1V){
+                        printf("bitstream size for tile (%d, %d): %d.\n", j, i, (int) (p[1] - p[0]));
+                    }
+                    else{
+                        printf("bitstream size for tile (%d, %d): unknown.\n", j, i);
+                    }
+                }
+            }
+        }
+        else{
+            for(j = 0; j <= pSC->WMISCP.cNumOfSliceMinus1H; j ++){
+                for(i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1V; i ++){
+                    size_t * p = &pSC->pIndexTable[(j * (pSC->WMISCP.cNumOfSliceMinus1V + 1) + i) * 4];
+                    if(i + j != pSC->WMISCP.cNumOfSliceMinus1H + pSC->WMISCP.cNumOfSliceMinus1V){
+                        printf("bitstream size of (DC, LP, AC, FL) for tile (%d, %d): %d %d %d %d.\n", j, i,
+                            (int) (p[1] - p[0]), (int) (p[2] - p[1]), (int) (p[3] - p[2]), (int) (p[4] - p[3]));
+                    }
+                    else{
+                        printf("bitstream size of (DC, LP, AC, FL) for tile (%d, %d): %d %d %d unknown.\n", j, i,
+                            (int) (p[1] - p[0]), (int) (p[2] - p[1]), (int) (p[3] - p[2]));
+                    }
+                }
+            }
+        }
+    }
+
+    return 0;
+}
+
+Int StrIODecTerm(CWMImageStrCodec* pSC)
+{
+    detachISRead(pSC, pSC->pIOHeader);
+
+    free(pSC->m_ppBitIO);
+    free(pSC->pIndexTable);
+
+    return 0;
+}
+
+Int initLookupTables(CWMImageStrCodec* pSC)
+{
+    static const U8 cbChannels[BDB_MAX] = {1, 1, 2, 2, 2, 4, 4, 4, (U8) -1, (U8) -1, (U8) -1 };
+
+    CWMImageInfo * pII = &pSC->WMII;
+    size_t cStrideX, cStrideY;
+    size_t w, h, i, iFirst = 0;
+    Bool bReverse;
+
+    // lookup tables for rotation and flipping
+    if(pSC->m_Dparam->cThumbnailScale > 1) // thumbnail
+        w = pII->cThumbnailWidth, h = pII->cThumbnailHeight;
+    else
+        w = pII->cWidth, h = pII->cHeight;
+    w += (pSC->m_Dparam->cROILeftX + pSC->m_Dparam->cThumbnailScale - 1) / pSC->m_Dparam->cThumbnailScale;
+    h += (pSC->m_Dparam->cROITopY + pSC->m_Dparam->cThumbnailScale - 1) / pSC->m_Dparam->cThumbnailScale;
+
+    switch(pII->bdBitDepth){
+        case BD_16:
+        case BD_16S:
+        case BD_5:
+        case BD_565:
+        case BD_16F:
+            cStrideY = pSC->WMIBI.cbStride / 2;
+            break;
+
+        case BD_32:
+        case BD_32S:
+        case BD_32F:
+        case BD_10:
+            cStrideY = pSC->WMIBI.cbStride / 4;
+            break;
+
+        default: //BD_8, BD_1
+            cStrideY = pSC->WMIBI.cbStride;
+            break;
+    }
+
+    switch(pII->cfColorFormat){
+        case YUV_420:
+            cStrideX = 6;
+            w >>= 1, h >>= 1;
+            break;
+
+        case YUV_422:
+            cStrideX = 4;
+            w >>= 1;
+            break;
+
+        default:
+            cStrideX = (pII->cBitsPerUnit >> 3) / cbChannels[pII->bdBitDepth];
+            break;
+    }
+
+    if(pII->bdBitDepth == BD_1 || pII->bdBitDepth == BD_5 || pII->bdBitDepth == BD_10 ||  pII->bdBitDepth == BD_565)
+        cStrideX = 1;
+
+    if(pII->oOrientation > O_FLIPVH) // rotated !!
+        i =cStrideX, cStrideX = cStrideY, cStrideY = i;
+
+    pSC->m_Dparam->pOffsetX = (size_t *)malloc(w * sizeof(size_t));
+    if(pSC->m_Dparam->pOffsetX == NULL || w * sizeof(size_t) < w)
+        return ICERR_ERROR;
+    /*
+    consider a row in the source image. if it becomes a reversed row in the target, or a reversed (upside-down)column 
+    in the target, we have to reverse the offsets. bReverse here tells us when this happened.
+    */
+    bReverse = (pII->oOrientation == O_FLIPH || pII->oOrientation == O_FLIPVH || 
+        pII->oOrientation == O_RCW_FLIPV || pII->oOrientation == O_RCW_FLIPVH);
+    if(!pSC->m_Dparam->bDecodeFullFrame) // take care of region decode here!
+        iFirst = (pSC->m_Dparam->cROILeftX + pSC->m_Dparam->cThumbnailScale - 1) / pSC->m_Dparam->cThumbnailScale;
+    for(i = 0; i + iFirst < w; i ++){
+        pSC->m_Dparam->pOffsetX[i + iFirst] = pII->cLeadingPadding + (bReverse ? (pSC->m_Dparam->bDecodeFullFrame ? w : 
+    (pSC->m_Dparam->cROIRightX - pSC->m_Dparam->cROILeftX + pSC->m_Dparam->cThumbnailScale) / pSC->m_Dparam->cThumbnailScale / ((pII->cfColorFormat == YUV_420 || pII->cfColorFormat == YUV_422) ? 2 : 1)) - 1 - i : i) * cStrideX;
+    }
+
+    pSC->m_Dparam->pOffsetY = (size_t *)malloc(h * sizeof(size_t));
+    if(pSC->m_Dparam->pOffsetY == NULL || h * sizeof(size_t) < h)
+        return ICERR_ERROR;
+    /*
+    consider a column in the source image. if it becomes an upside-down column in the target, or a reversed row 
+    in the target, we have to reverse the offsets. bReverse here tells us when this happened.
+    */
+    bReverse = (pII->oOrientation == O_FLIPV || pII->oOrientation == O_FLIPVH || 
+        pII->oOrientation == O_RCW || pII->oOrientation == O_RCW_FLIPV);
+    if(!pSC->m_Dparam->bDecodeFullFrame) // take care of region decode here!
+        iFirst = (pSC->m_Dparam->cROITopY + pSC->m_Dparam->cThumbnailScale - 1) / pSC->m_Dparam->cThumbnailScale;
+    for(i = 0; i + iFirst < h; i ++){
+        pSC->m_Dparam->pOffsetY[i + iFirst] = (bReverse ? (pSC->m_Dparam->bDecodeFullFrame ? h : 
+    (pSC->m_Dparam->cROIBottomY - pSC->m_Dparam->cROITopY + pSC->m_Dparam->cThumbnailScale) / pSC->m_Dparam->cThumbnailScale / (pII->cfColorFormat == YUV_420 ? 2 : 1)) - 1 - i : i) * cStrideY;
+    }
+
+    return ICERR_OK;
+}
+
+Void setROI(CWMImageStrCodec* pSC)
+{
+    CWMImageInfo * pWMII = &pSC->WMII;
+    CWMIStrCodecParam * pSCP = &pSC->WMISCP;
+
+    // inscribed image size
+    pWMII->cWidth -= pSC->m_param.cExtraPixelsLeft + pSC->m_param.cExtraPixelsRight;
+    pWMII->cHeight -= pSC->m_param.cExtraPixelsTop + pSC->m_param.cExtraPixelsBottom;
+
+    pSC->m_Dparam->bSkipFlexbits = (pSCP->sbSubband == SB_NO_FLEXBITS);
+    pSC->m_Dparam->bDecodeHP = (pSCP->sbSubband == SB_ALL || pSCP->sbSubband == SB_NO_FLEXBITS);
+    pSC->m_Dparam->bDecodeLP = (pSCP->sbSubband != SB_DC_ONLY);
+    pSC->m_Dparam->cThumbnailScale = 1;
+    while(pSC->m_Dparam->cThumbnailScale * pWMII->cThumbnailWidth < pWMII->cWidth)
+        pSC->m_Dparam->cThumbnailScale <<= 1;
+    if(pSC->WMISCP.bfBitstreamFormat == FREQUENCY){
+        if(pSC->m_Dparam->cThumbnailScale >= 4)
+            pSC->m_Dparam->bDecodeHP = FALSE;  // no need to decode HP
+        if(pSC->m_Dparam->cThumbnailScale >= 16)
+            pSC->m_Dparam->bDecodeLP = FALSE; // only need to decode DC
+    }
+
+    // original image size
+    pWMII->cWidth += pSC->m_param.cExtraPixelsLeft + pSC->m_param.cExtraPixelsRight;
+    pWMII->cHeight += pSC->m_param.cExtraPixelsTop + pSC->m_param.cExtraPixelsBottom;
+
+    /** region decode stuff */
+    pSC->m_Dparam->cROILeftX = pWMII->cROILeftX * pSC->m_Dparam->cThumbnailScale + pSC->m_param.cExtraPixelsLeft;
+    pSC->m_Dparam->cROIRightX = pSC->m_Dparam->cROILeftX + pWMII->cROIWidth * pSC->m_Dparam->cThumbnailScale - 1;
+    pSC->m_Dparam->cROITopY = pWMII->cROITopY * pSC->m_Dparam->cThumbnailScale + pSC->m_param.cExtraPixelsTop;
+    pSC->m_Dparam->cROIBottomY = pSC->m_Dparam->cROITopY + pWMII->cROIHeight * pSC->m_Dparam->cThumbnailScale - 1;
+    if(pSC->m_Dparam->cROIRightX >= pWMII->cWidth)
+        pSC->m_Dparam->cROIRightX = pWMII->cWidth - 1;
+    if(pSC->m_Dparam->cROIBottomY >= pWMII->cHeight)
+        pSC->m_Dparam->cROIBottomY = pWMII->cHeight - 1;
+
+    pSC->m_Dparam->bDecodeFullFrame = (pSC->m_Dparam->cROILeftX + pSC->m_Dparam->cROITopY == 0 &&
+        ((pSC->m_Dparam->cROIRightX + 15) / 16 >= (pWMII->cWidth + 14) / 16) && ((pSC->m_Dparam->cROIBottomY + 15) / 16 >= (pWMII->cHeight + 14) / 16));
+
+    pSC->m_Dparam->bDecodeFullWidth = (pSC->m_Dparam->cROILeftX == 0 && ((pSC->m_Dparam->cROIRightX + 15) / 16 >= (pWMII->cWidth + 14) / 16));
+
+    // inscribed image size
+    pWMII->cWidth -= pSC->m_param.cExtraPixelsLeft + pSC->m_param.cExtraPixelsRight;
+    pWMII->cHeight -= pSC->m_param.cExtraPixelsTop + pSC->m_param.cExtraPixelsBottom;
+
+    if(pSC->WMISCP.bfBitstreamFormat == FREQUENCY && pWMII->bSkipFlexbits == TRUE)
+        pSC->m_Dparam->bSkipFlexbits = TRUE;
+
+    pSC->cTileColumn = pSC->cTileRow = 0;
+}
+
+Int StrDecInit(CWMImageStrCodec* pSC)
+{
+    // CWMImageInfo * pWMII = &pSC->WMII;
+    COLORFORMAT cfInt = pSC->m_param.cfColorFormat;
+    COLORFORMAT cfExt = pSC->WMII.cfColorFormat;
+    size_t i;
+
+    /** color transcoding with resolution change **/
+    pSC->m_bUVResolutionChange = ((cfExt != Y_ONLY) && ((cfInt == YUV_420 && cfExt != YUV_420) || 
+        (cfInt == YUV_422 && cfExt != YUV_422))) && !pSC->WMISCP.bYUVData;
+    if(pSC->m_bUVResolutionChange){
+        pSC->pResU = (PixelI *)malloc((cfExt == YUV_422 ? 128 : 256) * pSC->cmbWidth * sizeof(PixelI));
+        pSC->pResV = (PixelI *)malloc((cfExt == YUV_422 ? 128 : 256) * pSC->cmbWidth * sizeof(PixelI));
+        if(pSC->pResU == NULL || pSC->pResV == NULL || (cfExt == YUV_422 ? 128 : 256) * pSC->cmbWidth * sizeof(PixelI) < pSC->cmbWidth){
+            return ICERR_ERROR;
+        }
+    }
+
+    if(allocatePredInfo(pSC) != ICERR_OK){
+        return ICERR_ERROR;
+    }
+
+    if(allocateTileInfo(pSC) != ICERR_OK)
+        return ICERR_ERROR;
+
+    if((pSC->m_param.uQPMode & 1) == 0){ // DC frame uniform quantization
+        if(allocateQuantizer(pSC->pTile[0].pQuantizerDC, pSC->m_param.cNumChannels, 1) != ICERR_OK)
+            return ICERR_ERROR;
+        setUniformQuantizer(pSC, 0);
+        for(i = 0; i < pSC->m_param.cNumChannels; i ++)
+            pSC->pTile[0].pQuantizerDC[i]->iIndex = pSC->m_param.uiQPIndexDC[i];
+        formatQuantizer(pSC->pTile[0].pQuantizerDC, (pSC->m_param.uQPMode >> 3) & 3, pSC->m_param.cNumChannels, 0, TRUE, pSC->m_param.bScaledArith);
+    }
+
+    if(pSC->WMISCP.sbSubband != SB_DC_ONLY){
+        if((pSC->m_param.uQPMode & 2) == 0){ // LP frame uniform quantization
+            if(allocateQuantizer(pSC->pTile[0].pQuantizerLP, pSC->m_param.cNumChannels, 1) != ICERR_OK)
+                return ICERR_ERROR;
+            setUniformQuantizer(pSC, 1);
+            if((pSC->m_param.uQPMode & 0x200) == 0) // use DC quantizer
+                useDCQuantizer(pSC, 0);
+            else{
+                for(i = 0; i < pSC->m_param.cNumChannels; i ++)
+                    pSC->pTile[0].pQuantizerLP[i]->iIndex = pSC->m_param.uiQPIndexLP[i];
+                formatQuantizer(pSC->pTile[0].pQuantizerLP, (pSC->m_param.uQPMode >> 5) & 3, pSC->m_param.cNumChannels, 0, TRUE, pSC->m_param.bScaledArith);
+            }
+        }
+
+        if(pSC->WMISCP.sbSubband != SB_NO_HIGHPASS){
+            if((pSC->m_param.uQPMode & 4) == 0){ // HP frame uniform quantization
+                if(allocateQuantizer(pSC->pTile[0].pQuantizerHP, pSC->m_param.cNumChannels, 1) != ICERR_OK)
+                    return ICERR_ERROR;
+                setUniformQuantizer(pSC, 2);
+
+                if((pSC->m_param.uQPMode & 0x400) == 0) // use LP quantizer
+                    useLPQuantizer(pSC, 1, 0);
+                else{
+                    for(i = 0; i < pSC->m_param.cNumChannels; i ++)
+                        pSC->pTile[0].pQuantizerHP[i]->iIndex = pSC->m_param.uiQPIndexHP[i];
+                    formatQuantizer(pSC->pTile[0].pQuantizerHP, (pSC->m_param.uQPMode >> 7) & 3, pSC->m_param.cNumChannels, 0, FALSE, pSC->m_param.bScaledArith);
+                }
+            }
+        }
+    }
+
+    if(pSC->WMISCP.cNumOfSliceMinus1V >= MAX_TILES || AllocateCodingContextDec(pSC, pSC->WMISCP.cNumOfSliceMinus1V + 1) != ICERR_OK){
+        return ICERR_ERROR;
+    }
+
+    if (pSC->m_bSecondary) {
+        pSC->pIOHeader = pSC->m_pNextSC->pIOHeader;
+        pSC->m_ppBitIO = pSC->m_pNextSC->m_ppBitIO;
+        pSC->cNumBitIO = pSC->m_pNextSC->cNumBitIO;
+        pSC->cSB = pSC->m_pNextSC->cSB;
+    }
+
+    setBitIOPointers(pSC);
+
+    return ICERR_OK;
+}
+
+Int StrDecTerm(CWMImageStrCodec* pSC)
+{
+    size_t j, jend = (pSC->m_pNextSC != NULL);
+
+    for (j = 0; j <= jend; j++) {
+        if(pSC->m_bUVResolutionChange){        
+            if(pSC->pResU != NULL)
+                free(pSC->pResU);
+            if(pSC->pResV != NULL)
+                free(pSC->pResV);
+        }
+
+        freePredInfo(pSC);
+
+        freeTileInfo(pSC);
+
+        FreeCodingContextDec(pSC);
+
+        if (j == 0) {
+            StrIODecTerm(pSC);
+
+            // free lookup tables for rotation and flipping
+            if(pSC->m_Dparam->pOffsetX != NULL)
+                free(pSC->m_Dparam->pOffsetX);
+            if(pSC->m_Dparam->pOffsetY != NULL)
+                free(pSC->m_Dparam->pOffsetY);
+        }
+
+        pSC = pSC->m_pNextSC;
+    }
+
+    return 0;
+}
+
+/*************************************************************************
+    Read header of image plane
+*************************************************************************/
+Int ReadImagePlaneHeader(CWMImageInfo* pII, CWMIStrCodecParam *pSCP,
+    CCoreParameters *pSC, SimpleBitIO* pSB)
+{
+    ERR err = WMP_errSuccess;
+
+    pSC->cfColorFormat = getBit32_SB(pSB, 3); // internal color format
+    FailIf((pSC->cfColorFormat < Y_ONLY || pSC->cfColorFormat > NCOMPONENT), WMP_errUnsupportedFormat);
+    pSCP->cfColorFormat = pSC->cfColorFormat;  // this should be removed later
+    pSC->bScaledArith = getBit32_SB(pSB, 1); // lossless mode
+
+    // subbands
+    pSCP->sbSubband = getBit32_SB(pSB, 4);
+
+// color parameters
+    switch (pSC->cfColorFormat) {
+        case Y_ONLY:
+            pSC->cNumChannels = 1;
+            break;
+        case YUV_420:
+            pSC->cNumChannels = 3;
+            getBit32_SB(pSB, 1);
+            pII->cChromaCenteringX = (U8) getBit32_SB(pSB, 3);
+            getBit32_SB(pSB, 1);
+            pII->cChromaCenteringY = (U8) getBit32_SB(pSB, 3);
+            break; 
+        case YUV_422:
+            pSC->cNumChannels = 3;
+            getBit32_SB(pSB, 1);
+            pII->cChromaCenteringX = (U8) getBit32_SB(pSB, 3);
+            getBit32_SB(pSB, 4);
+            break; 
+        case YUV_444:
+            pSC->cNumChannels = 3;
+            getBit32_SB(pSB, 4);
+            getBit32_SB(pSB, 4);
+            break;
+        case NCOMPONENT:
+            pSC->cNumChannels = (Int) getBit32_SB(pSB, 4) + 1;
+            getBit32_SB(pSB, 4);
+            break;
+        case CMYK:
+            pSC->cNumChannels = 4;
+            break;
+        default:
+            break;
+    }
+
+// float and 32s additional parameters
+    switch (pII->bdBitDepth) {
+        case BD_16:
+        case BD_16S:
+        case BD_32:
+        case BD_32S:
+            pSCP->nLenMantissaOrShift = (U8) getBit32_SB(pSB, 8);
+            break;
+        case BD_32F:
+            pSCP->nLenMantissaOrShift = (U8) getBit32_SB(pSB, 8);//float conversion parameters
+            pSCP->nExpBias = (I8) getBit32_SB(pSB, 8);
+            break;
+        default:
+            break;
+    }
+
+        // quantization
+    pSC->uQPMode = 0;
+    if(getBit32_SB(pSB, 1) == 1) // DC uniform
+        pSC->uQPMode += (readQuantizerSB(pSC->uiQPIndexDC, pSB, pSC->cNumChannels) << 3);
+    else
+        pSC->uQPMode ++;
+    if(pSCP->sbSubband != SB_DC_ONLY){
+        if(getBit32_SB(pSB, 1) == 0){ // don't use DC QP
+            pSC->uQPMode += 0x200;
+            if(getBit32_SB(pSB, 1) == 1) // LP uniform
+                pSC->uQPMode += (readQuantizerSB(pSC->uiQPIndexLP, pSB, pSC->cNumChannels) << 5);
+            else
+                pSC->uQPMode += 2;
+        }
+        else
+            pSC->uQPMode += ((pSC->uQPMode & 1) << 1) + ((pSC->uQPMode & 0x18) << 2);
+
+        if(pSCP->sbSubband != SB_NO_HIGHPASS){
+            if(getBit32_SB(pSB, 1) == 0){ // don't use LP QP
+                pSC->uQPMode += 0x400;
+                if(getBit32_SB(pSB, 1) == 1) // HP uniform
+                    pSC->uQPMode += (readQuantizerSB(pSC->uiQPIndexHP, pSB, pSC->cNumChannels) << 7);
+                else
+                    pSC->uQPMode += 4;
+            }
+            else
+                pSC->uQPMode += ((pSC->uQPMode & 2) << 1) + ((pSC->uQPMode & 0x60) << 2);
+        }
+    }
+
+    if(pSCP->sbSubband == SB_DC_ONLY)
+        pSC->uQPMode |= 0x200;
+    else if(pSCP->sbSubband == SB_NO_HIGHPASS)
+        pSC->uQPMode |= 0x400;
+    
+
+    FailIf((pSC->uQPMode & 0x600) == 0, WMP_errInvalidParameter); // frame level QPs must be specified independently!
+
+    flushToByte_SB(pSB);  // remove this later
+
+Cleanup:
+    return WMP_errSuccess == err ? ICERR_OK : ICERR_ERROR;
+}
+
+/*************************************************************************
+    Read header of image, and header of FIRST PLANE only
+*************************************************************************/
+Int ReadWMIHeader(
+    CWMImageInfo* pII,
+    CWMIStrCodecParam *pSCP,
+    CCoreParameters *pSC)
+{
+    U32 i;
+    ERR err = WMP_errSuccess;
+    Bool bTilingPresent, bInscribed, bTileStretch, bAbbreviatedHeader;
+    struct WMPStream* pWS = pSCP->pWStream;
+
+    SimpleBitIO SB = {0};
+    SimpleBitIO* pSB = &SB;
+
+    U8 szMS[8] = {0};
+    U32 cbStream = 0;
+
+    // U32 bits = 0;
+    // Int HEADERSIZE = 0;
+
+    assert(pSC != NULL);
+    //================================
+// 0
+    /** signature **/
+    Call(pWS->Read(pWS, szMS, sizeof(szMS)));
+    FailIf(szMS != (U8 *) strstr((char *) szMS, "WMPHOTO"), WMP_errUnsupportedFormat);
+    //================================
+    Call(attach_SB(pSB, pWS));
+
+// 8
+    /** codec version and subversion **/
+    i = getBit32_SB(pSB, 4);
+    FailIf((i != CODEC_VERSION), WMP_errIncorrectCodecVersion);
+    pSC->cVersion = i;
+    i = getBit32_SB(pSB, 4); // subversion
+    FailIf((i != CODEC_SUBVERSION &&
+        i != CODEC_SUBVERSION_NEWSCALING_SOFT_TILES && i != CODEC_SUBVERSION_NEWSCALING_HARD_TILES),
+        WMP_errIncorrectCodecSubVersion);
+    pSC->cSubVersion = i;
+
+    pSC->bUseHardTileBoundaries = FALSE;
+    if (pSC->cSubVersion == CODEC_SUBVERSION_NEWSCALING_HARD_TILES) 
+        pSC->bUseHardTileBoundaries = TRUE;
+
+    pSCP->bUseHardTileBoundaries = pSC->bUseHardTileBoundaries;
+
+// 9 primary parameters
+    bTilingPresent = (Bool) getBit32_SB(pSB, 1); // tiling present
+    pSCP->bfBitstreamFormat = getBit32_SB(pSB, 1); // bitstream layout
+    pII->oOrientation = (ORIENTATION)getBit32_SB(pSB, 3); // presentation orientation
+    pSC->bIndexTable = getBit32_SB(pSB, 1);
+    i = getBit32_SB(pSB, 2); // overlap
+    FailIf((i == 3), WMP_errInvalidParameter);
+    pSCP->olOverlap = i;
+
+// 11 some other parameters
+    bAbbreviatedHeader = (Bool) getBit32_SB(pSB, 1); // short words for size and tiles
+    pSCP->bdBitDepth = (BITDEPTH) getBit32_SB(pSB, 1); // long word
+pSCP->bdBitDepth = BD_LONG; // remove when optimization is done
+    bInscribed = (Bool) getBit32_SB(pSB, 1); // windowing
+    pSC->bTrimFlexbitsFlag = (Bool) getBit32_SB(pSB, 1); // trim flexbits flag
+    bTileStretch = (Bool) getBit32_SB(pSB, 1); // tile stretching flag
+    pSC->bRBSwapped = (Bool) getBit32_SB(pSB, 1); // red-blue swap flag
+    getBit32_SB(pSB, 1);  // padding / reserved bit
+    pSC->bAlphaChannel = (Bool) getBit32_SB(pSB, 1); // alpha channel present
+
+// 10 - informational
+    pII->cfColorFormat = getBit32_SB(pSB, 4); // source color format
+    pII->bdBitDepth = getBit32_SB(pSB, 4); // source bit depth
+
+    if(BD_1alt == pII->bdBitDepth)
+    {
+        pII->bdBitDepth = BD_1;
+        pSCP->bBlackWhite = 1;
+    }
+
+// 12 - Variable length fields
+// size
+    pII->cWidth = getBit32_SB(pSB, bAbbreviatedHeader ? 16 : 32) + 1;
+    pII->cHeight = getBit32_SB(pSB, bAbbreviatedHeader ? 16 : 32) + 1;
+    pSC->cExtraPixelsTop = pSC->cExtraPixelsLeft = pSC->cExtraPixelsBottom = pSC->cExtraPixelsRight = 0;
+    if (bInscribed == FALSE && (pII->cWidth & 0xf) != 0)
+        pSC->cExtraPixelsRight = 0x10 - (pII->cWidth & 0xF);
+    if (bInscribed == FALSE && (pII->cHeight & 0xf) != 0)
+        pSC->cExtraPixelsBottom = 0x10 - (pII->cHeight & 0xF);
+
+// tiling
+    pSCP->cNumOfSliceMinus1V = pSCP->cNumOfSliceMinus1H = 0;
+    if (bTilingPresent) {
+        pSCP->cNumOfSliceMinus1V = getBit32_SB(pSB, LOG_MAX_TILES); // # of vertical slices along X axis
+        pSCP->cNumOfSliceMinus1H = getBit32_SB(pSB, LOG_MAX_TILES); // # of horizontal slices along Y axis
+    }
+    FailIf((pSC->bIndexTable == FALSE) && (pSCP->bfBitstreamFormat == FREQUENCY || pSCP->cNumOfSliceMinus1V + pSCP->cNumOfSliceMinus1H > 0),
+        WMP_errUnsupportedFormat);
+
+// tile sizes
+    pSCP->uiTileX[0] = pSCP->uiTileY[0] = 0;
+    for(i = 0; i < pSCP->cNumOfSliceMinus1V; i ++){ // width in MB of vertical slices, not needed for last slice!
+        pSCP->uiTileX[i + 1] = (U32) getBit32_SB(pSB, bAbbreviatedHeader ? 8 : 16) + pSCP->uiTileX[i];
+    }
+    for(i = 0; i < pSCP->cNumOfSliceMinus1H; i ++){ // width in MB of vertical slices, not needed for last slice!
+        pSCP->uiTileY[i + 1] = (U32) getBit32_SB(pSB, bAbbreviatedHeader ? 8 : 16) + pSCP->uiTileY[i];
+    }
+    if (bTileStretch) {  // no handling of tile stretching enabled as of now
+        for (i = 0; i < (pSCP->cNumOfSliceMinus1V + 1) * (pSCP->cNumOfSliceMinus1H + 1); i++)
+            getBit32_SB(pSB, 8);
+    }
+
+// window due to compressed domain processing
+    if (bInscribed) {
+        pSC->cExtraPixelsTop = (U8)getBit32_SB(pSB, 6);
+        pSC->cExtraPixelsLeft = (U8)getBit32_SB(pSB, 6);
+        pSC->cExtraPixelsBottom = (U8)getBit32_SB(pSB, 6);
+        pSC->cExtraPixelsRight = (U8)getBit32_SB(pSB, 6);
+    }
+    
+    if(((pII->cWidth + pSC->cExtraPixelsLeft + pSC->cExtraPixelsRight) & 0xf) + ((pII->cHeight + pSC->cExtraPixelsTop + pSC->cExtraPixelsBottom) & 0xf) != 0){
+        FailIf((pII->cWidth & 0xf) + (pII->cHeight & 0xf) + pSC->cExtraPixelsLeft + pSC->cExtraPixelsTop != 0, WMP_errInvalidParameter);
+        FailIf(pII->cWidth <= pSC->cExtraPixelsRight || pII->cHeight <= pSC->cExtraPixelsBottom, WMP_errInvalidParameter);
+        pII->cWidth -= pSC->cExtraPixelsRight, pII->cHeight -= pSC->cExtraPixelsBottom;
+    }
+
+    flushToByte_SB(pSB);  // redundant
+
+    // read header of first image plane
+    FailIf(ReadImagePlaneHeader(pII, pSCP, pSC, pSB), WMP_errUnsupportedFormat);
+
+    // maybe UNALIGNED!!!
+
+    //================================
+    detach_SB(pSB);
+    pSCP->cbStream = cbStream - getByteRead_SB(pSB);
+
+    pSCP->uAlphaMode = (pSC->bAlphaChannel ? pSCP->uAlphaMode : 0);
+    pSCP->cChannel = pSC->cNumChannels;
+
+    if((pII->bdBitDepth == BD_5 || pII->bdBitDepth == BD_10 || pII->bdBitDepth == BD_565) && 
+        (pSCP->cfColorFormat != YUV_444 && pSCP->cfColorFormat != YUV_422 && pSCP->cfColorFormat != YUV_420 && pSCP->cfColorFormat != Y_ONLY))
+        return ICERR_ERROR;
+    
+Cleanup:
+    return WMP_errSuccess == err ? ICERR_OK : ICERR_ERROR;
+}
+
+//----------------------------------------------------------------
+// streaming api init/decode/term
+EXTERN_C Int ImageStrDecGetInfo(
+    CWMImageInfo* pII,
+    CWMIStrCodecParam *pSCP)
+{
+    ERR err = WMP_errSuccess;
+    size_t cMarker;
+    CCoreParameters aDummy;
+    // mark position of start of data
+    Call(pSCP->pWStream->GetPos(pSCP->pWStream, &cMarker));
+    Call(ReadWMIHeader(pII, pSCP, &aDummy));
+    // rewind to start of data
+    Call(pSCP->pWStream->SetPos(pSCP->pWStream, cMarker));
+    return ICERR_OK;
+
+Cleanup:
+    return ICERR_ERROR;
+}
+
+EXTERN_C Int WMPhotoValidate(
+    CWMImageInfo * pII,
+    CWMIStrCodecParam * pSCP)
+{
+    CWMImageInfo cII;
+    CWMIStrCodecParam cSCP = *pSCP;
+    size_t cScale = 1;
+
+    if(ImageStrDecGetInfo(&cII, pSCP) != ICERR_OK)
+        return ICERR_ERROR;
+
+    // copy over un-overwritable ImageInfo parameters
+    pII->bdBitDepth = cII.bdBitDepth;
+    pII->cWidth = cII.cWidth;
+    pII->cHeight = cII.cHeight;
+
+    if(pII->cWidth == 0 || pII->cHeight == 0)
+        return ICERR_ERROR;
+
+    // copy over overwritable CodecParam parameters
+    pSCP->bVerbose = cSCP.bVerbose;
+    pSCP->cbStream = cSCP.cbStream;
+    pSCP->pWStream = cSCP.pWStream;
+    if(pSCP->uAlphaMode > 1) // something + alpha
+        pSCP->uAlphaMode = cSCP.uAlphaMode; // something + alpha to alpha or something transcoding!
+
+    // validate color transcoding
+    if(pSCP->cfColorFormat == NCOMPONENT)
+        pII->cfColorFormat = NCOMPONENT;
+    if(pSCP->cfColorFormat == CMYK && pII->cfColorFormat != Y_ONLY && pII->cfColorFormat != CF_RGB)
+        pII->cfColorFormat = CMYK;
+    if(pSCP->cfColorFormat == YUV_422 && pII->cfColorFormat == YUV_420)
+        pII->cfColorFormat = YUV_422;
+    if(pSCP->cfColorFormat == YUV_444 && (pII->cfColorFormat == YUV_422 || pII->cfColorFormat == YUV_420))
+        pII->cfColorFormat = YUV_444;
+    if(cII.cfColorFormat == CF_RGB && pII->cfColorFormat != Y_ONLY && 
+        pII->cfColorFormat != NCOMPONENT)  // no guarantee that number of channels will be >= 3
+        pII->cfColorFormat = cII.cfColorFormat;
+    if(cII.cfColorFormat == CF_RGBE)
+        pII->cfColorFormat = CF_RGBE;
+
+    // validate thumbnail parameters
+    if(pII->cThumbnailWidth == 0 || pII->cThumbnailWidth > pII->cWidth)
+        pII->cThumbnailWidth = pII->cWidth;
+    if(pII->cThumbnailHeight == 0 || pII->cThumbnailHeight > pII->cHeight)
+        pII->cThumbnailHeight = pII->cHeight;
+    if((pII->cWidth + pII->cThumbnailWidth - 1) / pII->cThumbnailWidth != (pII->cHeight + pII->cThumbnailHeight - 1) / pII->cThumbnailHeight) {
+        while((pII->cWidth + cScale - 1) / cScale > pII->cThumbnailWidth &&
+            (pII->cHeight + cScale - 1) / cScale > pII->cThumbnailHeight && (cScale << 1))
+            cScale <<= 1;
+    }
+    else {
+        cScale = (pII->cWidth + pII->cThumbnailWidth - 1) / pII->cThumbnailWidth;    
+        if (cScale == 0)
+            cScale = 1;
+    }
+    pII->cThumbnailWidth = (pII->cWidth + cScale - 1) / cScale;
+    pII->cThumbnailHeight = (pII->cHeight + cScale - 1) / cScale;
+
+    // validate region decode parameters
+    if(pII->cROIHeight == 0 || pII->cROIWidth == 0){
+        pII->cROILeftX = pII->cROITopY = 0;
+        pII->cROIWidth = pII->cThumbnailWidth;
+        pII->cROIHeight = pII->cThumbnailHeight;
+    }
+    if(pII->cROILeftX >= pII->cThumbnailWidth)
+        pII->cROILeftX = 0;
+    if(pII->cROITopY >= pII->cThumbnailHeight)
+        pII->cROITopY = 0;
+    if(pII->cROILeftX + pII->cROIWidth > pII->cThumbnailWidth)
+        pII->cROIWidth = pII->cThumbnailWidth - pII->cROILeftX;
+    if(pII->cROITopY + pII->cROIHeight > pII->cThumbnailHeight)
+        pII->cROIHeight = pII->cThumbnailHeight - pII->cROITopY;
+
+    return ICERR_OK;
+}
+
+/*************************************************************************
+  Initialization of CWMImageStrCodec struct
+*************************************************************************/
+static Void InitializeStrDec(CWMImageStrCodec *pSC,
+  const CCoreParameters *pParams, const CWMImageStrCodec *pSCIn)
+{
+    // copy core parameters
+    memcpy (&(pSC->m_param), pParams, sizeof (CCoreParameters));
+
+    pSC->cbStruct = sizeof(*pSC);
+    pSC->WMII = pSCIn->WMII;
+    pSC->WMISCP = pSCIn->WMISCP;
+
+    pSC->cRow = 0;
+    pSC->cColumn = 0;
+    
+    pSC->cmbWidth = (pSC->WMII.cWidth + 15) / 16;
+    pSC->cmbHeight = (pSC->WMII.cHeight + 15) / 16;
+
+    pSC->Load = outputMBRow; // output decoding result (ICC, etc)
+    pSC->Transform = pParams->cSubVersion == CODEC_SUBVERSION ?
+        invTransformMacroblock : invTransformMacroblock_alteredOperators_hard;
+    pSC->TransformCenter = pSC->Transform;
+
+    pSC->ProcessTopLeft = processMacroblockDec;
+    pSC->ProcessTop = processMacroblockDec;
+    pSC->ProcessTopRight = processMacroblockDec;
+    pSC->ProcessLeft = processMacroblockDec;
+    pSC->ProcessCenter = processMacroblockDec;
+    pSC->ProcessRight = processMacroblockDec;
+    pSC->ProcessBottomLeft = processMacroblockDec;
+    pSC->ProcessBottom = processMacroblockDec;
+    pSC->ProcessBottomRight = processMacroblockDec;
+
+    pSC->m_pNextSC = NULL;
+    pSC->m_bSecondary = FALSE;
+}
+
+/*************************************************************************
+  ImageStrDecInit
+*************************************************************************/
+Int ImageStrDecInit(
+    CWMImageInfo* pII,
+    CWMIStrCodecParam *pSCP,
+    CTXSTRCODEC* pctxSC)
+{
+    static size_t cbChannels[BD_MAX] = {2, 4};
+    ERR err = WMP_errSuccess;
+
+    size_t cbChannel = 0, cblkChroma = 0;
+    size_t cbMacBlockStride = 0, cbMacBlockChroma = 0, cMacBlock = 0;
+
+    CWMImageStrCodec SC = {0};
+    CWMImageStrCodec *pSC = NULL, *pNextSC = NULL;
+    char* pb = NULL;
+    size_t cb = 0, i;
+    Bool bLossyTranscoding = FALSE;
+    Bool bUseHardTileBoundaries = FALSE; //default is soft tile boundaries
+    Bool bLessThan64Bit = sizeof(void *) < 8;
+
+    *pctxSC = NULL;
+
+    if(WMPhotoValidate(pII, pSCP) != ICERR_OK)
+        return ICERR_ERROR;
+
+    if(pSCP->sbSubband == SB_ISOLATED) // can not do anything with isolated bitstream
+        return ICERR_ERROR;
+
+    //================================================
+    SC.WMISCP.pWStream = pSCP->pWStream;
+    if (ReadWMIHeader(&SC.WMII, &SC.WMISCP, &SC.m_param) != ICERR_OK) {
+        return ICERR_ERROR;
+    }
+
+    bUseHardTileBoundaries = SC.WMISCP.bUseHardTileBoundaries;
+    if(SC.WMII.cfColorFormat == CMYK && pII->cfColorFormat == CF_RGB)
+        bLossyTranscoding = TRUE;
+    if(pSCP->cfColorFormat != CMYK && (pII->cfColorFormat == CMYK))
+        return ICERR_ERROR;
+
+    //================================================
+    SC.WMISCP = *pSCP;
+    SC.WMII   = *pII;
+
+    // original image size
+    SC.WMII.cWidth += SC.m_param.cExtraPixelsLeft + SC.m_param.cExtraPixelsRight;
+    SC.WMII.cHeight += SC.m_param.cExtraPixelsTop + SC.m_param.cExtraPixelsBottom;
+    pII->cROILeftX += SC.m_param.cExtraPixelsLeft;
+    pII->cROITopY += SC.m_param.cExtraPixelsTop;
+    
+    //================================================
+    cbChannel = cbChannels[SC.WMISCP.bdBitDepth];
+    cblkChroma = cblkChromas[SC.m_param.cfColorFormat];
+
+    cbMacBlockStride = cbChannel * 16 * 16;
+    cbMacBlockChroma = cbChannel * 16 * cblkChroma;
+    cMacBlock = (SC.WMII.cWidth + 15) / 16;
+
+    //================================================
+    cb = sizeof(*pSC) + (128 - 1) + sizeof(CWMDecoderParameters);
+    cb += (PACKETLENGTH * 4 - 1) + (PACKETLENGTH * 2 ) + sizeof(*pSC->pIOHeader);
+
+    i = (cbMacBlockStride + cbMacBlockChroma * (SC.m_param.cNumChannels - 1)) * 2; // i <= 2^15
+    if (bLessThan64Bit && ((i * (cMacBlock >> 16)) & 0xffffc000)) {
+        /** potential overflow - 32 bit pointers insufficient to address cache **/
+        return ICERR_ERROR;
+    }
+    cb += i * cMacBlock;
+
+    pb = malloc(cb);
+    if(pb == NULL)
+        return WMP_errOutOfMemory;
+    memset(pb, 0, cb);
+
+    //================================================
+    pSC = (CWMImageStrCodec*)pb; pb += sizeof(*pSC);
+    if(pSC == NULL)
+        return ICERR_ERROR;
+
+    // Set up perf timers
+    PERFTIMER_ONLY(pSC->m_fMeasurePerf = pSCP->fMeasurePerf);
+    PERFTIMER_NEW(pSC->m_fMeasurePerf, &pSC->m_ptEndToEndPerf);
+    PERFTIMER_NEW(pSC->m_fMeasurePerf, &pSC->m_ptEncDecPerf);
+    PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEndToEndPerf);
+    PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
+    PERFTIMER_COPYSTARTTIME(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf, pSC->m_ptEndToEndPerf);
+
+    pSC->m_Dparam = (CWMDecoderParameters*)pb; pb += sizeof(CWMDecoderParameters);
+    pSC->cbChannel = cbChannel;
+    //pSC->cNumChannels = SC.WMISCP.cChannel;
+    pSC->bUseHardTileBoundaries = bUseHardTileBoundaries;
+
+    //================================================
+    InitializeStrDec(pSC, &SC.m_param, &SC);
+
+    //================================================
+    // 2 Macro Row buffers for each channel
+    pb = ALIGNUP(pb, 128);
+    for (i = 0; i < pSC->m_param.cNumChannels; i++) {
+        pSC->a0MBbuffer[i] = (PixelI*)pb; pb += cbMacBlockStride * pSC->cmbWidth;
+        pSC->a1MBbuffer[i] = (PixelI*)pb; pb += cbMacBlockStride * pSC->cmbWidth;
+        cbMacBlockStride = cbMacBlockChroma;
+    }
+
+    //================================================
+    // lay 2 aligned IO buffers just below pIO struct
+    pb = (char*)ALIGNUP(pb, PACKETLENGTH * 4) + PACKETLENGTH * 2;
+    pSC->pIOHeader = (BitIOInfo*)pb; pb += sizeof(*pSC->pIOHeader);
+
+    // if interleaved alpha is needed
+    if (pSC->m_param.bAlphaChannel) {
+        SimpleBitIO SB = {0};
+        cbMacBlockStride = cbChannel * 16 * 16;
+
+        // 1. allocate new pNextSC info
+        //================================================
+        cb = sizeof(*pNextSC) + (128 - 1) + cbMacBlockStride * cMacBlock * 2;
+        // if primary image is safe to allocate, alpha channel is certainly safe
+        pb = malloc(cb);
+        if(pb == NULL)
+            return WMP_errOutOfMemory;
+        memset(pb, 0, cb);
+        //================================================
+        pNextSC = (CWMImageStrCodec*)pb; pb += sizeof(*pNextSC);
+
+        // read plane header of second image plane
+        Call(attach_SB(&SB, pSCP->pWStream));
+        InitializeStrDec(pNextSC, &SC.m_param, &SC);
+        ReadImagePlaneHeader(&pNextSC->WMII, &pNextSC->WMISCP, &pNextSC->m_param, &SB);
+        detach_SB(&SB);
+
+        // 2. initialize pNextSC
+        if(pNextSC == NULL)
+            return ICERR_ERROR;
+        pNextSC->m_Dparam = pSC->m_Dparam;
+        pNextSC->cbChannel = cbChannel;
+        //================================================
+
+        // 3. initialize arrays
+//        InitializeStrDec(pNextSC, &SC.m_param, &SC);
+        pNextSC->m_param.cfColorFormat = Y_ONLY;
+        pNextSC->m_param.cNumChannels = 1;
+        pNextSC->m_param.bAlphaChannel = TRUE;
+        //================================================
+
+        // 2 Macro Row buffers for each channel
+        pb = ALIGNUP(pb, 128);
+        pNextSC->a0MBbuffer[0] = (PixelI*)pb; pb += cbMacBlockStride * pNextSC->cmbWidth;
+        pNextSC->a1MBbuffer[0] = (PixelI*)pb;
+        //================================================
+        pNextSC->pIOHeader = pSC->pIOHeader;
+        //================================================
+
+        // 4. link pSC->pNextSC = pNextSC
+        pNextSC->m_pNextSC = pSC;
+        pNextSC->m_bSecondary = TRUE;
+
+    }
+    else
+        pSC->WMISCP.uAlphaMode = 0;
+
+    //================================================
+    FailIf((StrIODecInit(pSC) != ICERR_OK), WMP_errOutOfMemory);
+    FailIf((StrDecInit(pSC) != ICERR_OK), WMP_errOutOfMemory);
+    if (pNextSC) {
+        // 5. StrEncInit
+        FailIf((StrDecInit(pNextSC) != ICERR_OK), WMP_errOutOfMemory);
+    }
+
+    pSC->m_pNextSC = pNextSC;
+    //================================================
+    *pII = pSC->WMII;
+    *pSCP = pSC->WMISCP;
+    *pctxSC = (CTXSTRCODEC)pSC;
+
+    if(pSC->WMII.cPostProcStrength){
+        initPostProc(pSC->pPostProcInfo, pSC->cmbWidth, pSC->m_param.cNumChannels);
+        if (pSC->m_param.bAlphaChannel) 
+            initPostProc(pNextSC->pPostProcInfo, pNextSC->cmbWidth, pNextSC->m_param.cNumChannels);
+    }
+
+    PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
+
+Cleanup:
+    return WMP_errSuccess == err ? ICERR_OK : ICERR_ERROR;
+}
+
+Int ImageStrDecDecode(
+    CTXSTRCODEC ctxSC,
+    const CWMImageBufferInfo* pBI
+#ifdef REENTRANT_MODE
+    , size_t *pcDecodedLines
+#endif
+    )
+{
+    CWMImageStrCodec* pSC = (CWMImageStrCodec*)ctxSC;
+    CWMImageStrCodec* pNextSC = pSC->m_pNextSC;
+    size_t cMBRow, k;
+
+    ImageDataProc ProcessLeft, ProcessCenter, ProcessRight;
+    ImageDataProc Transform = NULL;
+    const size_t iChromaElements = (pSC->m_param.cfColorFormat == YUV_420) ? 8 * 8 
+        : ((pSC->m_param.cfColorFormat == YUV_422) ? 8 * 16 : 16 * 16);
+
+    if (sizeof(*pSC) != pSC->cbStruct)
+    {
+        return ICERR_ERROR;
+    }
+
+    //================================
+    PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
+
+    pSC->WMIBI = *pBI;
+
+#ifdef REENTRANT_MODE
+    if (0 == pSC->WMIBI.uiFirstMBRow)
+    {
+        setROI(pSC);
+        if (pNextSC) {
+            pNextSC->WMIBI = pSC->WMIBI;
+            setROI(pNextSC);
+        }
+    }
+#else
+    setROI(pSC);
+    if (pNextSC) {
+        pNextSC->WMIBI = pSC->WMIBI;
+        setROI(pNextSC);
+    }
+#endif // REENTRANT_MODE
+
+// optimization flags can be defined only after ROI is set!
+#if defined(WMP_OPT_SSE2) || defined(WMP_OPT_CC_DEC) || defined(WMP_OPT_TRFM_DEC)
+    StrDecOpt(pSC);
+#endif // OPT defined
+
+
+
+    cMBRow = (pSC->m_Dparam->bDecodeFullFrame ? pSC->cmbHeight : ((pSC->m_Dparam->cROIBottomY + 16) >> 4));
+
+#ifdef REENTRANT_MODE
+    if (0 == pSC->WMIBI.uiFirstMBRow)
+    {
+        if(initLookupTables(pSC) != ICERR_OK)
+            return ICERR_ERROR;
+        if (pNextSC && initLookupTables(pNextSC) != ICERR_OK)
+            return ICERR_ERROR;
+    }
+#else
+    if(initLookupTables(pSC) != ICERR_OK)
+        return ICERR_ERROR;
+    if (pNextSC && initLookupTables(pNextSC) != ICERR_OK)
+        return ICERR_ERROR;
+#endif // REENTRANT_MODE
+
+#ifndef REENTRANT_MODE
+    if(pSC->WMII.bdBitDepth == BD_1){
+        size_t i;
+
+
+        for(i = 0; i < pSC->WMIBI.cLine; i ++)
+            memset(pSC->WMIBI.pv, 0, pSC->WMIBI.cbStride);
+    }
+#endif
+
+    //================================
+    // top row
+#ifdef REENTRANT_MODE
+#else
+    pSC->cRow = 0;
+    ProcessLeft = pSC->ProcessTopLeft;
+    ProcessCenter = pSC->ProcessTop;
+    ProcessRight = pSC->ProcessTopRight;
+    Transform = pSC->m_param.cSubVersion == CODEC_SUBVERSION ?
+        invTransformMacroblock : invTransformMacroblock_alteredOperators_hard;
+#endif // REENTRANT_MODE
+
+#ifdef REENTRANT_MODE
+    for (pSC->cRow = pSC->WMIBI.uiFirstMBRow; pSC->cRow <= pSC->WMIBI.uiLastMBRow; pSC->cRow++)
+    {
+        // const COLORFORMAT cfExt = (pSC->m_param.cfColorFormat == Y_ONLY ? Y_ONLY : pSC->WMII.cfColorFormat);
+
+        if (0 == pSC->cRow)
+        {
+            ProcessLeft = pSC->ProcessTopLeft;
+            ProcessCenter = pSC->ProcessTop;
+            ProcessRight = pSC->ProcessTopRight;
+            Transform = pSC->m_param.cSubVersion == CODEC_SUBVERSION ?
+                invTransformMacroblock : invTransformMacroblock_alteredOperators_hard;
+        }
+        else if (cMBRow == pSC->cRow)
+        {
+            //================================
+            // bottom row
+            ProcessLeft = pSC->ProcessBottomLeft;
+            ProcessCenter = pSC->ProcessBottom;
+            ProcessRight = pSC->ProcessBottomRight;
+            Transform = pSC->m_param.cSubVersion == CODEC_SUBVERSION ?
+                invTransformMacroblock : invTransformMacroblock_alteredOperators_hard;
+        }
+        else { // middle rows
+            ProcessLeft = pSC->ProcessLeft;
+            ProcessCenter = pSC->ProcessCenter;
+            ProcessRight = pSC->ProcessRight;
+            Transform = pSC->TransformCenter;
+        }
+#else
+    //================================
+    // central rows
+    for(pSC->cRow = 0; pSC->cRow <= cMBRow; pSC->cRow++)
+    {
+#endif // REENTRANT_MODE
+        pSC->cColumn = 0;
+        initMRPtr(pSC);
+        /** zero out the transform coefficients (pull this out to once per MB row) **/
+        memset(pSC->p1MBbuffer[0], 0, sizeof(PixelI) * 16 * 16 * pSC->cmbWidth);
+        for (k = 1; k < pSC->m_param.cNumChannels; k++) {
+            memset(pSC->p1MBbuffer[k], 0, sizeof(PixelI) * iChromaElements * pSC->cmbWidth);
+        }
+        if (pSC->m_pNextSC != NULL) {  // alpha channel
+            memset(pSC->m_pNextSC->p1MBbuffer[0], 0, sizeof(PixelI) * 16 * 16 * pSC->m_pNextSC->cmbWidth);
+        }
+
+        if(ProcessLeft(pSC) != ICERR_OK)
+            return ICERR_ERROR;
+        advanceMRPtr(pSC);
+
+        pSC->Transform = Transform;
+        for (pSC->cColumn = 1; pSC->cColumn < pSC->cmbWidth; ++pSC->cColumn)
+        {
+            if(ProcessCenter(pSC) != ICERR_OK)
+                return ICERR_ERROR;
+            advanceMRPtr(pSC);
+        }
+        pSC->Transform = pSC->m_param.cSubVersion == CODEC_SUBVERSION ?
+            invTransformMacroblock : invTransformMacroblock_alteredOperators_hard;
+
+        if(ProcessRight(pSC) != ICERR_OK)
+            return ICERR_ERROR;
+
+        if (pSC->cRow) {
+            if(pSC->m_Dparam->cThumbnailScale < 2 && (pSC->m_Dparam->bDecodeFullFrame || 
+                ((pSC->cRow * 16 > pSC->m_Dparam->cROITopY) && (pSC->cRow * 16 <= pSC->m_Dparam->cROIBottomY + 16)))) {
+                if( pSC->Load(pSC) != ICERR_OK ) // bypass CC for thumbnail decode
+            		return ICERR_ERROR;
+            }
+
+            if(pSC->m_Dparam->cThumbnailScale >= 2) // decode thumbnail
+                decodeThumbnail(pSC);
+        }
+
+        advanceOneMBRow(pSC);
+        swapMRPtr(pSC);
+#ifdef REENTRANT_MODE
+        *pcDecodedLines = pSC->WMIBI.cLinesDecoded;
+#else
+        if (pSC->cRow == cMBRow - 1) {
+        //================================
+        // bottom row
+            ProcessLeft = pSC->ProcessBottomLeft;
+            ProcessCenter = pSC->ProcessBottom;
+            ProcessRight = pSC->ProcessBottomRight;
+            Transform = pSC->m_param.cSubVersion == CODEC_SUBVERSION ?
+                invTransformMacroblock : invTransformMacroblock_alteredOperators_hard;
+        }
+        else {
+            ProcessLeft = pSC->ProcessLeft;
+            ProcessCenter = pSC->ProcessCenter;
+            ProcessRight = pSC->ProcessRight;
+            Transform = pSC->TransformCenter;
+        }
+#endif // REENTRANT_MODE
+    }
+
+#ifndef REENTRANT_MODE
+    fixup_Y_ONLY_to_Others(pSC, pBI);
+#endif // REENTRANT_MODE
+
+    PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
+    return ICERR_OK;
+}
+
+Int ImageStrDecTerm(
+    CTXSTRCODEC ctxSC)
+{
+    CWMImageStrCodec* pSC = (CWMImageStrCodec*)ctxSC;
+    if (NULL == pSC)
+    {
+        return ICERR_OK;
+    }
+    if (sizeof(*pSC) != pSC->cbStruct)
+    {
+        return ICERR_ERROR;
+    }
+
+    PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
+
+    StrDecTerm(pSC);
+    PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
+    PERFTIMER_REPORT(pSC->m_fMeasurePerf, pSC);
+    PERFTIMER_DELETE(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
+    PERFTIMER_DELETE(pSC->m_fMeasurePerf, pSC->m_ptEndToEndPerf);
+
+    free(pSC);
+
+    return ICERR_OK;
+}
+
diff --git a/Source/LibJXR/image/decode/strdec_x86.c b/Source/LibJXR/image/decode/strdec_x86.c
new file mode 100644
index 0000000..161d0a2
--- /dev/null
+++ b/Source/LibJXR/image/decode/strdec_x86.c
@@ -0,0 +1,1640 @@
+//*@@@+++@@@@******************************************************************
+//
+// Copyright � Microsoft Corp.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+// � Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// � Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//*@@@---@@@@******************************************************************
+#include "strcodec.h"
+#include "decode.h"
+
+#if defined(WMP_OPT_SSE2)
+#include <emmintrin.h>
+#include <windows.h>
+
+//================================================================
+static __m128i g_const_d0;
+static __m128i g_const_d1;
+
+__m128i g_const_d3;
+__m128i g_const_d4;
+__m128i g_const_d0x80;
+__m128i g_const_w0x80;
+__m128i g_const_b0x80;
+
+//================================================================
+#if defined(WMP_OPT_CC_DEC)
+__declspec(naked) void __stdcall storeRGB24_5(
+    U8* pbYCoCg,
+    size_t cbYCoCg,
+    const U8* pbRGB,
+    size_t cbRGB,
+    size_t cmb)
+{
+#define DISP 8
+    UNREFERENCED_PARAMETER( pbYCoCg );
+    UNREFERENCED_PARAMETER( cbYCoCg );
+    UNREFERENCED_PARAMETER( pbRGB );
+    UNREFERENCED_PARAMETER( cbRGB );
+    UNREFERENCED_PARAMETER( cmb );
+    __asm {
+        push ebp
+        push ebx    
+        push esi
+        push edi
+
+        mov ebx, [esp + 36]         // $ebx = cmb
+        mov edi, [esp + 28]         // $edi = pbRGB
+        lea ebx, [ebx + ebx * 2]    // $ebx = cmb * 3
+        mov edx, [esp + 32]         // $edx = cbRGB
+        shl ebx, 4                  // $ebx = cmb * 3 * 16
+        mov esi, [esp + 20]         // $esi = pbYCoCg
+        add edi, ebx                // $edi = pbRGB + 3 * 16 * cmb
+        mov ebp, [esp + 24]         // $ebp = cbYCoCg
+        neg ebx
+
+        mov eax, esp
+        and esp, 0xffffff80
+        sub esp, 64 * 4 + DISP
+
+        mov [esp], eax              // original $esp
+        mov [esp + 4], edi
+    }
+Loop0:
+    __asm {
+        mov edi, [esp + 4]          // $edi = pbRGB + 3 * 16 * cmb
+
+            // first 8 pixels
+            pxor xmm1, xmm1
+            pxor xmm5, xmm5
+            movdqa xmm0, [esi]
+            movdqa xmm4, [esi + 16]
+            psubd xmm1, [esi + ebp]
+            psubd xmm5, [esi + ebp + 16]
+            movdqa xmm2, [esi + ebp * 2]
+            movdqa xmm6, [esi + ebp * 2 + 16]
+
+            paddd xmm0, [g_const_d0x80]
+            paddd xmm4, [g_const_d0x80]
+
+            // ICC
+            movdqa xmm3, xmm1           // g -= r >> 1
+            movdqa xmm7, xmm5
+            psrad xmm3, 1
+            psrad xmm7, 1
+            psubd xmm0, xmm3
+            psubd xmm4, xmm7
+
+            movdqa xmm3, [g_const_d1]   // r -= ((b + 1) >> 1) - g
+            movdqa xmm7, [g_const_d1]
+            paddd xmm3, xmm2
+            paddd xmm7, xmm6
+            paddd xmm1, xmm0
+            paddd xmm5, xmm4
+            psrad xmm3, 1
+            psrad xmm7, 1
+            psubd xmm1, xmm3
+            psubd xmm5, xmm7
+
+            paddd xmm2, xmm1            // b += r
+            paddd xmm6, xmm5
+
+            pslld xmm0, 8
+            pslld xmm2, 16
+            pslld xmm4, 8
+            pslld xmm6, 16
+            por xmm0, xmm1
+            por xmm4, xmm5
+            por xmm0, xmm2
+            por xmm4, xmm6
+
+            movdqa [esp + DISP + 64 * 0 + 16 * 0], xmm0
+            pslld xmm0, 8
+            movdqa [esp + DISP + 64 * 0 + 16 * 1], xmm4
+            pslld xmm4, 8
+            movdqa [esp + DISP + 64 * 0 + 16 * 2], xmm0
+            movdqa [esp + DISP + 64 * 0 + 16 * 3], xmm4
+
+            // second 8 pixels
+            pxor xmm1, xmm1
+            pxor xmm5, xmm5
+            movdqa xmm0, [esi + 32]
+            movdqa xmm4, [esi + 48]
+            psubd xmm1, [esi + ebp + 32]
+            psubd xmm5, [esi + ebp + 48]
+            movdqa xmm2, [esi + ebp * 2 + 32]
+            movdqa xmm6, [esi + ebp * 2 + 48]
+
+            paddd xmm0, [g_const_d0x80]
+            paddd xmm4, [g_const_d0x80]
+
+            // ICC
+            movdqa xmm3, xmm1           // g -= r >> 1
+            movdqa xmm7, xmm5
+            psrad xmm3, 1
+            psrad xmm7, 1
+            psubd xmm0, xmm3
+            psubd xmm4, xmm7
+
+            movdqa xmm3, [g_const_d1]   // r -= ((b + 1) >> 1) - g
+            movdqa xmm7, [g_const_d1]
+            paddd xmm3, xmm2
+            paddd xmm7, xmm6
+            paddd xmm1, xmm0
+            paddd xmm5, xmm4
+            psrad xmm3, 1
+            psrad xmm7, 1
+            psubd xmm1, xmm3
+            psubd xmm5, xmm7
+
+            paddd xmm2, xmm1            // b += r
+            paddd xmm6, xmm5
+
+            pslld xmm0, 8
+            pslld xmm2, 16
+            pslld xmm4, 8
+            pslld xmm6, 16
+            por xmm0, xmm1
+            por xmm4, xmm5
+            por xmm0, xmm2
+            por xmm4, xmm6
+
+            movdqa [esp + DISP + 64 * 1 + 16 * 0], xmm0
+            pslld xmm0, 8
+            movdqa [esp + DISP + 64 * 1 + 16 * 1], xmm4
+            pslld xmm4, 8
+            movdqa [esp + DISP + 64 * 1 + 16 * 2], xmm0
+            movdqa [esp + DISP + 64 * 1 + 16 * 3], xmm4
+
+            //================
+            add esi, 64
+
+            // first 8 pixels
+            pxor xmm1, xmm1
+            pxor xmm5, xmm5
+            movdqa xmm0, [esi]
+            movdqa xmm4, [esi + 16]
+            psubd xmm1, [esi + ebp]
+            psubd xmm5, [esi + ebp + 16]
+            movdqa xmm2, [esi + ebp * 2]
+            movdqa xmm6, [esi + ebp * 2 + 16]
+
+            paddd xmm0, [g_const_d0x80]
+            paddd xmm4, [g_const_d0x80]
+
+            // ICC
+            movdqa xmm3, xmm1           // g -= r >> 1
+            movdqa xmm7, xmm5
+            psrad xmm3, 1
+            psrad xmm7, 1
+            psubd xmm0, xmm3
+            psubd xmm4, xmm7
+
+            movdqa xmm3, [g_const_d1]   // r -= ((b + 1) >> 1) - g
+            movdqa xmm7, [g_const_d1]
+            paddd xmm3, xmm2
+            paddd xmm7, xmm6
+            paddd xmm1, xmm0
+            paddd xmm5, xmm4
+            psrad xmm3, 1
+            psrad xmm7, 1
+            psubd xmm1, xmm3
+            psubd xmm5, xmm7
+
+            paddd xmm2, xmm1            // b += r
+            paddd xmm6, xmm5
+
+            pslld xmm0, 8
+            pslld xmm2, 16
+            pslld xmm4, 8
+            pslld xmm6, 16
+
+            por xmm0, xmm1
+            por xmm4, xmm5
+            por xmm0, xmm2
+            por xmm4, xmm6
+
+            movdqa [esp + DISP + 64 * 2 + 16 * 0], xmm0
+            pslld xmm0, 8
+            movdqa [esp + DISP + 64 * 2 + 16 * 1], xmm4
+            pslld xmm4, 8
+            movdqa [esp + DISP + 64 * 2 + 16 * 2], xmm0
+            movdqa [esp + DISP + 64 * 2 + 16 * 3], xmm4
+
+            // second 8 pixels
+            pxor xmm1, xmm1
+            pxor xmm5, xmm5
+            movdqa xmm0, [esi + 32]
+            movdqa xmm4, [esi + 48]
+            psubd xmm1, [esi + ebp + 32]
+            psubd xmm5, [esi + ebp + 48]
+            movdqa xmm2, [esi + ebp * 2 + 32]
+            movdqa xmm6, [esi + ebp * 2 + 48]
+
+            paddd xmm0, [g_const_d0x80]
+            paddd xmm4, [g_const_d0x80]
+
+            // ICC
+            movdqa xmm3, xmm1           // g -= r >> 1
+            movdqa xmm7, xmm5
+            psrad xmm3, 1
+            psrad xmm7, 1
+            psubd xmm0, xmm3
+            psubd xmm4, xmm7
+
+            movdqa xmm3, [g_const_d1]   // r -= ((b + 1) >> 1) - g
+            movdqa xmm7, [g_const_d1]
+            paddd xmm3, xmm2
+            paddd xmm7, xmm6
+            paddd xmm1, xmm0
+            paddd xmm5, xmm4
+            psrad xmm3, 1
+            psrad xmm7, 1
+            psubd xmm1, xmm3
+            psubd xmm5, xmm7
+
+            paddd xmm2, xmm1            // b += r
+            paddd xmm6, xmm5
+
+            pslld xmm0, 8
+            pslld xmm2, 16
+            pslld xmm4, 8
+            pslld xmm6, 16
+            por xmm0, xmm1
+            por xmm4, xmm5
+            por xmm0, xmm2
+            por xmm4, xmm6
+
+            movdqa [esp + DISP + 64 * 3 + 16 * 0], xmm0
+            pslld xmm0, 8
+            movdqa [esp + DISP + 64 * 3 + 16 * 1], xmm4
+            pslld xmm4, 8
+            movdqa [esp + DISP + 64 * 3 + 16 * 2], xmm0
+            movdqa [esp + DISP + 64 * 3 + 16 * 3], xmm4
+
+            //================================
+            // RGBX32 -> RGB24
+            mov eax, [esp + DISP + 64 * 0 + 4]      // ..B1G1R1
+            mov ecx, [esp + DISP + 64 * 0 + 32]     // B0G0R0..
+            shld eax, ecx, 24                       // R1B0G0R0
+            mov [edi + ebx + 0], eax
+            mov eax, [esp + DISP + 64 * 0 + 20]     // ..B5G5R5
+            mov ecx, [esp + DISP + 64 * 0 + 36]     // B1G1R1..
+            shld eax, ecx, 16                       // G5R5B1G1
+            mov [edi + ebx + 4], eax
+            mov eax, [esp + DISP + 64 * 0 + 16]     // ..B4G4R4
+            mov ecx, [esp + DISP + 64 * 0 + 52]     // B5G5R5..
+            shld eax, ecx, 8                        // B4G4R4B5
+            mov [edi + ebx + 8], eax
+            add edi, edx                // $edi = pbRGB += cbRGB
+
+            mov eax, [esp + DISP + 64 * 0 + 4 + 8]  // ..B3G3R3
+            mov ecx, [esp + DISP + 64 * 0 + 32 + 8] // B2G2R2..
+            shld eax, ecx, 24                       // R3B2G2R2
+            mov [edi + ebx + 0], eax
+            mov eax, [esp + DISP + 64 * 0 + 20 + 8] // ..B7G7R7
+            mov ecx, [esp + DISP + 64 * 0 + 36 + 8] // B3G3R3..
+            shld eax, ecx, 16                       // G7R7B3G3
+            mov [edi + ebx + 4], eax
+            mov eax, [esp + DISP + 64 * 0 + 16 + 8] // ..B6G6R6
+            mov ecx, [esp + DISP + 64 * 0 + 52 + 8] // B7G7R7..
+            shld eax, ecx, 8                        // B6G6R6B7
+            mov [edi + ebx + 8], eax
+            add edi, edx                // $edi = pbRGB += cbRGB
+
+            // RGBX32 -> RGB24
+            mov eax, [esp + DISP + 64 * 1 + 4 + 8]  // ..B3G3R3
+            mov ecx, [esp + DISP + 64 * 1 + 32 + 8] // B2G2R2..
+            shld eax, ecx, 24                       // R3B2G2R2
+            mov [edi + ebx + 0], eax
+            mov eax, [esp + DISP + 64 * 1 + 20 + 8] // ..B7G7R7
+            mov ecx, [esp + DISP + 64 * 1 + 36 + 8] // B3G3R3..
+            shld eax, ecx, 16                       // G7R7B3G3
+            mov [edi + ebx + 4], eax
+            mov eax, [esp + DISP + 64 * 1 + 16 + 8] // ..B6G6R6
+            mov ecx, [esp + DISP + 64 * 1 + 52 + 8] // B7G7R7..
+            shld eax, ecx, 8                        // B6G6R6B7
+            mov [edi + ebx + 8], eax
+            add edi, edx                // $edi = pbRGB += cbRGB
+
+            mov eax, [esp + DISP + 64 * 1 + 4]  // ..B1G1R1
+            mov ecx, [esp + DISP + 64 * 1 + 32] // B0G0R0..
+            shld eax, ecx, 24                   // R1B0G0R0
+            mov [edi + ebx + 0], eax
+            mov eax, [esp + DISP + 64 * 1 + 20] // ..B5G5R5
+            mov ecx, [esp + DISP + 64 * 1 + 36] // B1G1R1..
+            shld eax, ecx, 16                   // G5R5B1G1
+            mov [edi + ebx + 4], eax
+            mov eax, [esp + DISP + 64 * 1 + 16] // ..B4G4R4
+            mov ecx, [esp + DISP + 64 * 1 + 52] // B5G5R5..
+            shld eax, ecx, 8                    // B4G4R4B5
+            mov [edi + ebx + 8], eax
+            add edi, edx                // $edi = pbRGB += cbRGB
+
+            // RGBX32 -> RGB24
+            mov eax, [esp + DISP + 64 * 2 + 4]  // ..B1G1R1
+            mov ecx, [esp + DISP + 64 * 2 + 32] // B0G0R0..
+            shld eax, ecx, 24                   // R1B0G0R0
+            mov [edi + ebx + 0], eax
+            mov eax, [esp + DISP + 64 * 2 + 20] // ..B5G5R5
+            mov ecx, [esp + DISP + 64 * 2 + 36] // B1G1R1..
+            shld eax, ecx, 16                   // G5R5B1G1
+            mov [edi + ebx + 4], eax
+            mov eax, [esp + DISP + 64 * 2 + 16] // ..B4G4R4
+            mov ecx, [esp + DISP + 64 * 2 + 52] // B5G5R5..
+            shld eax, ecx, 8                    // B4G4R4B5
+            mov [edi + ebx + 8], eax
+            add edi, edx                // $edi = pbRGB += cbRGB
+
+            mov eax, [esp + DISP + 64 * 2 + 4 + 8]  // ..B3G3R3
+            mov ecx, [esp + DISP + 64 * 2 + 32 + 8] // B2G2R2..
+            shld eax, ecx, 24                       // R3B2G2R2
+            mov [edi + ebx + 0], eax
+            mov eax, [esp + DISP + 64 * 2 + 20 + 8] // ..B7G7R7
+            mov ecx, [esp + DISP + 64 * 2 + 36 + 8] // B3G3R3..
+            shld eax, ecx, 16                       // G7R7B3G3
+            mov [edi + ebx + 4], eax
+            mov eax, [esp + DISP + 64 * 2 + 16 + 8] // ..B6G6R6
+            mov ecx, [esp + DISP + 64 * 2 + 52 + 8] // B7G7R7..
+            shld eax, ecx, 8                        // B6G6R6B7
+            mov [edi + ebx + 8], eax
+            add edi, edx                // $edi = pbRGB += cbRGB
+
+            // RGBX32 -> RGB24
+            mov eax, [esp + DISP + 64 * 3 + 4 + 8]  // ..B3G3R3
+            mov ecx, [esp + DISP + 64 * 3 + 32 + 8] // B2G2R2..
+            shld eax, ecx, 24                       // R3B2G2R2
+            mov [edi + ebx + 0], eax
+            mov eax, [esp + DISP + 64 * 3 + 20 + 8] // ..B7G7R7
+            mov ecx, [esp + DISP + 64 * 3 + 36 + 8] // B3G3R3..
+            shld eax, ecx, 16                       // G7R7B3G3
+            mov [edi + ebx + 4], eax
+            mov eax, [esp + DISP + 64 * 3 + 16 + 8] // ..B6G6R6
+            mov ecx, [esp + DISP + 64 * 3 + 52 + 8] // B7G7R7..
+            shld eax, ecx, 8                        // B6G6R6B7
+            mov [edi + ebx + 8], eax
+            add edi, edx                // $edi = pbRGB += cbRGB
+
+            mov eax, [esp + DISP + 64 * 3 + 4]      // ..B1G1R1
+            mov ecx, [esp + DISP + 64 * 3 + 32]     // B0G0R0..
+            shld eax, ecx, 24                       // R1B0G0R0
+            mov [edi + ebx + 0], eax
+            mov eax, [esp + DISP + 64 * 3 + 20]     // ..B5G5R5
+            mov ecx, [esp + DISP + 64 * 3 + 36]     // B1G1R1..
+            shld eax, ecx, 16                       // G5R5B1G1
+            mov [edi + ebx + 4], eax
+            mov eax, [esp + DISP + 64 * 3 + 16]     // ..B4G4R4
+            mov ecx, [esp + DISP + 64 * 3 + 52]     // B5G5R5..
+            shld eax, ecx, 8                        // B4G4R4B5
+            mov [edi + ebx + 8], eax
+
+        //================================
+        add esi, 256 - 64
+        add ebx, 12
+        jnz Loop0
+
+        //================
+        pop esp
+        pop edi
+        pop esi
+        pop ebx
+        pop ebp
+        ret 20
+    }
+}
+
+Int outputMBRow_RGB24_Lossless_1(CWMImageStrCodec* pSC)
+{
+#ifdef REENTRANT_MODE
+    const size_t cHeight = min((pSC->m_Dparam->cROIBottomY + 1) - (pSC->cRow - 1) * 16, 16);
+    const size_t iFirstRow = ((pSC->cRow - 1) * 16 > pSC->m_Dparam->cROITopY ? 0 : (pSC->m_Dparam->cROITopY & 0xf));
+#endif
+    const size_t cbRGB = pSC->WMIBI.cbStride;
+    const U8* const pbRGB = (U8*)pSC->WMIBI.pv + cbRGB * (pSC->cRow - 1) * 16;
+
+    U8* const pbY = (U8*)pSC->a0MBbuffer[0];
+    U8* const pbU = (U8*)pSC->a0MBbuffer[1];
+    // U8* const pbV = (U8*)pSC->a0MBbuffer[2];
+
+    const size_t cmbColumn = (pSC->WMII.cWidth + 15) / 16;
+
+    assert(BD_8 == pSC->WMII.bdBitDepth);
+    assert(CF_RGB == pSC->WMII.cfColorFormat);
+    assert(24 == pSC->WMII.cBitsPerUnit);
+    assert(pSC->WMII.bRGB);
+    assert(O_NONE == pSC->WMII.oOrientation);
+
+    assert(YUV_444 == pSC->m_param.cfColorFormat);
+    assert(!pSC->m_param.bScaledArith);
+
+    assert(pSC->m_Dparam->bDecodeFullFrame);
+
+    storeRGB24_5(pbY + 64 * 0, pbU - pbY, pbRGB + cbRGB *  0, cbRGB, cmbColumn);
+    storeRGB24_5(pbY + 64 * 2, pbU - pbY, pbRGB + cbRGB *  8, cbRGB, cmbColumn);
+
+#ifdef REENTRANT_MODE
+    pSC->WMIBI.cLinesDecoded = cHeight - iFirstRow;
+#endif
+    return ICERR_OK;
+}
+
+
+__declspec(naked) void __stdcall storeRGB24_3(
+    U8* pbYCoCg,
+    size_t cbYCoCg,
+    const U8* pbRGB,
+    size_t cbRGB,
+    size_t cmb,
+    const U8* Shift)
+{
+    UNREFERENCED_PARAMETER( pbYCoCg );
+    UNREFERENCED_PARAMETER( cbYCoCg );
+    UNREFERENCED_PARAMETER( pbRGB );
+    UNREFERENCED_PARAMETER( cbRGB );
+    UNREFERENCED_PARAMETER( cmb );
+    UNREFERENCED_PARAMETER( Shift );
+    __asm {
+        push ebp
+        push ebx    
+        push esi
+        push edi
+
+        mov ecx, [esp + 40]         // $ecx = Shift
+        mov ebx, [esp + 36]         // $ebx = cmb
+        mov edi, [esp + 28]         // $edi = pbRGB
+        lea ebx, [ebx + ebx * 2]    // $ebx = cmb * 3
+        mov edx, [esp + 32]         // $edx = cbRGB
+        shl ebx, 4                  // $ebx = cmb * 3 * 16
+        mov esi, [esp + 20]         // $esi = pbYCoCg
+        add edi, ebx                // $edi = pbRGB + 3 * 16 * cmb
+        mov ebp, [esp + 24]         // $ebp = cbYCoCg
+        neg ebx
+
+        mov eax, esp
+        and esp, 0xffffff80
+        sub esp, 320
+
+        mov [esp], eax              // original $esp
+        mov [esp + 4], edi
+        mov [esp + 8], ecx
+    }
+Loop0:
+    __asm {
+        mov edi, [esp + 4]          // $edi = pbRGB + 3 * 16 * cmb
+
+            //================
+            // first 8 pixels
+            movdqa xmm0, [esi]
+            movdqa xmm4, [esi + 16]
+            movdqa xmm3, [esi + ebp]
+            movdqa xmm7, [esi + ebp + 16]
+            movdqa xmm2, [esi + ebp * 2]
+            movdqa xmm6, [esi + ebp * 2 + 16]
+
+            mov ecx, [esp + 8]
+            movdqa xmm1, [ecx]
+            movdqa xmm5, [g_const_d0x80]
+            pslld xmm5, xmm1
+            paddd xmm5, xmm1
+            paddd xmm0, xmm5            // bias
+            paddd xmm4, xmm5            // bias
+            pxor xmm1, xmm1
+            pxor xmm5, xmm5
+            psubd xmm1, xmm3
+            psubd xmm5, xmm7
+
+            // ICC
+            movdqa xmm3, xmm1           // g -= r >> 1
+            movdqa xmm7, xmm5
+            psrad xmm3, 1
+            psrad xmm7, 1
+            psubd xmm0, xmm3
+            psubd xmm4, xmm7
+
+            movdqa xmm3, [g_const_d1]   // r -= ((b + 1) >> 1) - g
+            movdqa xmm7, [g_const_d1]
+            paddd xmm3, xmm2
+            paddd xmm7, xmm6
+            paddd xmm1, xmm0
+            paddd xmm5, xmm4
+            psrad xmm3, 1
+            psrad xmm7, 1
+            psubd xmm1, xmm3
+            psubd xmm5, xmm7
+
+            paddd xmm2, xmm1            // b += r
+            paddd xmm6, xmm5
+
+            // clip
+            movdqa xmm3, [g_const_w0x80]
+            packssdw xmm0, xmm4
+            packssdw xmm1, xmm5
+            packssdw xmm2, xmm6
+
+            mov ecx, [esp + 8]
+            movdqa xmm4, [ecx]
+            psraw xmm0, xmm4
+            psraw xmm1, xmm4
+            psraw xmm2, xmm4
+
+            psubw xmm0, xmm3
+            psubw xmm1, xmm3
+            psubw xmm2, xmm3
+
+            movdqa [esp + 16], xmm0
+            movdqa [esp + 32], xmm1
+            movdqa [esp + 48], xmm2
+
+            //================
+            // second 8 pixels
+            movdqa xmm0, [esi + 32]
+            movdqa xmm4, [esi + 48]
+            movdqa xmm3, [esi + ebp + 32]
+            movdqa xmm7, [esi + ebp + 48]
+            movdqa xmm2, [esi + ebp * 2 + 32]
+            movdqa xmm6, [esi + ebp * 2 + 48]
+
+            mov ecx, [esp + 8]
+            movdqa xmm1, [ecx]
+            movdqa xmm5, [g_const_d0x80]
+            pslld xmm5, xmm1
+            paddd xmm5, xmm1
+            paddd xmm0, xmm5            // bias
+            paddd xmm4, xmm5            // bias
+            pxor xmm1, xmm1
+            pxor xmm5, xmm5
+            psubd xmm1, xmm3
+            psubd xmm5, xmm7
+
+            // ICC
+            movdqa xmm3, xmm1           // g -= r >> 1
+            movdqa xmm7, xmm5
+            psrad xmm3, 1
+            psrad xmm7, 1
+            psubd xmm0, xmm3
+            psubd xmm4, xmm7
+
+            movdqa xmm3, [g_const_d1]   // r -= ((b + 1) >> 1) - g
+            movdqa xmm7, [g_const_d1]
+            paddd xmm3, xmm2
+            paddd xmm7, xmm6
+            paddd xmm1, xmm0
+            paddd xmm5, xmm4
+            psrad xmm3, 1
+            psrad xmm7, 1
+            psubd xmm1, xmm3
+            psubd xmm5, xmm7
+
+            paddd xmm2, xmm1            // b += r
+            paddd xmm6, xmm5
+
+            // clip
+            movdqa xmm3, [g_const_w0x80]
+            packssdw xmm0, xmm4
+            packssdw xmm1, xmm5
+            packssdw xmm2, xmm6
+
+            mov ecx, [esp + 8]
+            movdqa xmm4, [ecx]
+            psraw xmm0, xmm4
+            psraw xmm1, xmm4
+            psraw xmm2, xmm4
+
+            psubw xmm0, xmm3
+            psubw xmm1, xmm3
+            psubw xmm2, xmm3
+
+            //================
+            // 16 pixels
+            movdqa xmm3, [g_const_b0x80]
+            packsswb xmm0, [esp + 16]
+            packsswb xmm1, [esp + 32]
+            packsswb xmm2, [esp + 48]
+
+            psubb xmm0, xmm3
+            psubb xmm1, xmm3
+            psubb xmm2, xmm3
+
+            pxor xmm7, xmm7
+            movdqa xmm4, xmm0
+            movdqa xmm5, xmm1
+            movdqa xmm6, xmm2
+
+            punpckhbw xmm0, xmm7
+            punpckhbw xmm1, xmm7
+            punpckhbw xmm2, xmm7
+            punpcklbw xmm4, xmm7
+            punpcklbw xmm5, xmm7
+            punpcklbw xmm6, xmm7
+
+            // spill second 8 pixels
+            movdqa [esp + 16], xmm4
+            movdqa [esp + 32], xmm5
+            movdqa [esp + 48], xmm6
+
+            // first 8 pixels
+            movdqa xmm4, xmm0
+            movdqa xmm5, xmm1
+            movdqa xmm6, xmm2
+
+            punpcklwd xmm0, xmm7
+            punpcklwd xmm1, xmm7
+            punpcklwd xmm2, xmm7
+
+            punpckhwd xmm4, xmm7
+            punpckhwd xmm5, xmm7
+            punpckhwd xmm6, xmm7
+
+            pslld xmm0, 8
+            pslld xmm2, 16
+            pslld xmm4, 8
+            pslld xmm6, 16
+
+            por xmm0, xmm1
+            por xmm4, xmm5
+            por xmm0, xmm2
+            por xmm4, xmm6
+
+            movdqa [esp + 64], xmm0
+            pslld xmm0, 8
+            movdqa [esp + 80], xmm4
+            pslld xmm4, 8
+            movdqa [esp + 96], xmm0
+            movdqa [esp + 112], xmm4
+
+            // second 8 pixels
+            movdqa xmm0, [esp + 16]
+            movdqa xmm1, [esp + 32]
+            movdqa xmm2, [esp + 48]
+            movdqa xmm4, xmm0
+            movdqa xmm5, xmm1
+            movdqa xmm6, xmm2
+
+            punpcklwd xmm0, xmm7
+            punpcklwd xmm1, xmm7
+            punpcklwd xmm2, xmm7
+            punpckhwd xmm4, xmm7
+            punpckhwd xmm5, xmm7
+            punpckhwd xmm6, xmm7
+
+            pslld xmm0, 8
+            pslld xmm2, 16
+            pslld xmm4, 8
+            pslld xmm6, 16
+            por xmm0, xmm1
+            por xmm4, xmm5
+            por xmm0, xmm2
+            por xmm4, xmm6
+
+            movdqa [esp + 128], xmm0
+            pslld xmm0, 8
+            movdqa [esp + 144], xmm4
+            pslld xmm4, 8
+            movdqa [esp + 160], xmm0
+            movdqa [esp + 176], xmm4
+
+        //================================
+        add esi, 64
+
+            //================
+            // first 8 pixels
+            movdqa xmm0, [esi]
+            movdqa xmm4, [esi + 16]
+            movdqa xmm3, [esi + ebp]
+            movdqa xmm7, [esi + ebp + 16]
+            movdqa xmm2, [esi + ebp * 2]
+            movdqa xmm6, [esi + ebp * 2 + 16]
+
+            mov ecx, [esp + 8]
+            movdqa xmm1, [ecx]
+            movdqa xmm5, [g_const_d0x80]
+            pslld xmm5, xmm1
+            paddd xmm5, xmm1
+            paddd xmm0, xmm5            // bias
+            paddd xmm4, xmm5            // bias
+            pxor xmm1, xmm1
+            pxor xmm5, xmm5
+            psubd xmm1, xmm3
+            psubd xmm5, xmm7
+
+            // ICC
+            movdqa xmm3, xmm1           // g -= r >> 1
+            movdqa xmm7, xmm5
+            psrad xmm3, 1
+            psrad xmm7, 1
+            psubd xmm0, xmm3
+            psubd xmm4, xmm7
+
+            movdqa xmm3, [g_const_d1]   // r -= ((b + 1) >> 1) - g
+            movdqa xmm7, [g_const_d1]
+            paddd xmm3, xmm2
+            paddd xmm7, xmm6
+            paddd xmm1, xmm0
+            paddd xmm5, xmm4
+            psrad xmm3, 1
+            psrad xmm7, 1
+            psubd xmm1, xmm3
+            psubd xmm5, xmm7
+
+            paddd xmm2, xmm1            // b += r
+            paddd xmm6, xmm5
+
+            // clip
+            movdqa xmm3, [g_const_w0x80]
+            packssdw xmm0, xmm4
+            packssdw xmm1, xmm5
+            packssdw xmm2, xmm6
+
+            mov ecx, [esp + 8]
+            movdqa xmm4, [ecx]
+            psraw xmm0, xmm4
+            psraw xmm1, xmm4
+            psraw xmm2, xmm4
+
+            psubw xmm0, xmm3
+            psubw xmm1, xmm3
+            psubw xmm2, xmm3
+
+            movdqa [esp + 16], xmm0
+            movdqa [esp + 32], xmm1
+            movdqa [esp + 48], xmm2
+
+            //================
+            // second 8 pixels
+            movdqa xmm0, [esi + 32]
+            movdqa xmm4, [esi + 48]
+            movdqa xmm3, [esi + ebp + 32]
+            movdqa xmm7, [esi + ebp + 48]
+            movdqa xmm2, [esi + ebp * 2 + 32]
+            movdqa xmm6, [esi + ebp * 2 + 48]
+
+            mov ecx, [esp + 8]
+            movdqa xmm1, [ecx]
+            movdqa xmm5, [g_const_d0x80]
+            pslld xmm5, xmm1
+            paddd xmm5, xmm1
+            paddd xmm0, xmm5            // bias
+            paddd xmm4, xmm5            // bias
+            pxor xmm1, xmm1
+            pxor xmm5, xmm5
+            psubd xmm1, xmm3
+            psubd xmm5, xmm7
+
+            // ICC
+            movdqa xmm3, xmm1           // g -= r >> 1
+            movdqa xmm7, xmm5
+            psrad xmm3, 1
+            psrad xmm7, 1
+            psubd xmm0, xmm3
+            psubd xmm4, xmm7
+
+            movdqa xmm3, [g_const_d1]   // r -= ((b + 1) >> 1) - g
+            movdqa xmm7, [g_const_d1]
+            paddd xmm3, xmm2
+            paddd xmm7, xmm6
+            paddd xmm1, xmm0
+            paddd xmm5, xmm4
+            psrad xmm3, 1
+            psrad xmm7, 1
+            psubd xmm1, xmm3
+            psubd xmm5, xmm7
+
+            paddd xmm2, xmm1            // b += r
+            paddd xmm6, xmm5
+
+            // clip
+            movdqa xmm3, [g_const_w0x80]
+            packssdw xmm0, xmm4
+            packssdw xmm1, xmm5
+            packssdw xmm2, xmm6
+
+            mov ecx, [esp + 8]
+            movdqa xmm4, [ecx]
+            psraw xmm0, xmm4
+            psraw xmm1, xmm4
+            psraw xmm2, xmm4
+
+            psubw xmm0, xmm3
+            psubw xmm1, xmm3
+            psubw xmm2, xmm3
+
+            //================
+            // 16 pixels
+            movdqa xmm3, [g_const_b0x80]
+            packsswb xmm0, [esp + 16]
+            packsswb xmm1, [esp + 32]
+            packsswb xmm2, [esp + 48]
+
+            psubb xmm0, xmm3
+            psubb xmm1, xmm3
+            psubb xmm2, xmm3
+
+            pxor xmm7, xmm7
+            movdqa xmm4, xmm0
+            movdqa xmm5, xmm1
+            movdqa xmm6, xmm2
+
+            punpckhbw xmm0, xmm7
+            punpckhbw xmm1, xmm7
+            punpckhbw xmm2, xmm7
+            punpcklbw xmm4, xmm7
+            punpcklbw xmm5, xmm7
+            punpcklbw xmm6, xmm7
+
+            // spill second 8 pixels
+            movdqa [esp + 16], xmm4
+            movdqa [esp + 32], xmm5
+            movdqa [esp + 48], xmm6
+
+            // first 8 pixels
+            movdqa xmm4, xmm0
+            movdqa xmm5, xmm1
+            movdqa xmm6, xmm2
+
+            punpcklwd xmm0, xmm7
+            punpcklwd xmm1, xmm7
+            punpcklwd xmm2, xmm7
+
+            punpckhwd xmm4, xmm7
+            punpckhwd xmm5, xmm7
+            punpckhwd xmm6, xmm7
+
+            pslld xmm0, 8
+            pslld xmm2, 16
+            pslld xmm4, 8
+            pslld xmm6, 16
+
+            por xmm0, xmm1
+            por xmm4, xmm5
+            por xmm0, xmm2
+            por xmm4, xmm6
+
+            movdqa [esp + 192], xmm0
+            pslld xmm0, 8
+            movdqa [esp + 208], xmm4
+            pslld xmm4, 8
+            movdqa [esp + 224], xmm0
+            movdqa [esp + 240], xmm4
+
+            // second 8 pixels
+            movdqa xmm0, [esp + 16]
+            movdqa xmm1, [esp + 32]
+            movdqa xmm2, [esp + 48]
+            movdqa xmm4, xmm0
+            movdqa xmm5, xmm1
+            movdqa xmm6, xmm2
+
+            punpcklwd xmm0, xmm7
+            punpcklwd xmm1, xmm7
+            punpcklwd xmm2, xmm7
+            punpckhwd xmm4, xmm7
+            punpckhwd xmm5, xmm7
+            punpckhwd xmm6, xmm7
+
+            pslld xmm0, 8
+            pslld xmm2, 16
+            pslld xmm4, 8
+            pslld xmm6, 16
+            por xmm0, xmm1
+            por xmm4, xmm5
+            por xmm0, xmm2
+            por xmm4, xmm6
+
+            movdqa [esp + 256], xmm0
+            pslld xmm0, 8
+            movdqa [esp + 272], xmm4
+            pslld xmm4, 8
+            movdqa [esp + 288], xmm0
+            movdqa [esp + 304], xmm4
+
+            // RGBX32 -> RGB24
+            mov eax, [esp + 68]         // ..B1G1R1
+            mov ecx, [esp + 96]         // B0G0R0..
+            shld eax, ecx, 24           // R1B0G0R0
+            mov [edi + ebx + 0], eax
+            mov eax, [esp + 84]         // ..B5G5R5
+            mov ecx, [esp + 100]        // B1G1R1..
+            shld eax, ecx, 16           // G5R5B1G1
+            mov [edi + ebx + 4], eax
+            mov eax, [esp + 80]         // ..B4G4R4
+            mov ecx, [esp + 116]        // B5G5R5..
+            shld eax, ecx, 8            // B4G4R4B5
+            mov [edi + ebx + 8], eax
+            add edi, edx                // $edi = pbRGB += cbRGB
+
+            mov eax, [esp + 76]         // ..B3G3R3
+            mov ecx, [esp + 104]        // B2G2R2..
+            shld eax, ecx, 24           // R3B2G2R2
+            mov [edi + ebx + 0], eax
+            mov eax, [esp + 92]         // ..B7G7R7
+            mov ecx, [esp + 108]        // B3G3R3..
+            shld eax, ecx, 16           // G7R7B3G3
+            mov [edi + ebx + 4], eax
+            mov eax, [esp + 88]         // ..B6G6R6
+            mov ecx, [esp + 124]        // B7G7R7..
+            shld eax, ecx, 8            // B6G6R6B7
+            mov [edi + ebx + 8], eax
+            add edi, edx                // $edi = pbRGB += cbRGB
+
+            // RGBX32 -> RGB24
+            mov eax, [esp + 140]        // ..B3G3R3
+            mov ecx, [esp + 168]        // B2G2R2..
+            shld eax, ecx, 24           // R3B2G2R2
+            mov [edi + ebx + 0], eax
+            mov eax, [esp + 156]        // ..B7G7R7
+            mov ecx, [esp + 172]        // B3G3R3..
+            shld eax, ecx, 16           // G7R7B3G3
+            mov [edi + ebx + 4], eax
+            mov eax, [esp + 152]        // ..B6G6R6
+            mov ecx, [esp + 188]        // B7G7R7..
+            shld eax, ecx, 8            // B6G6R6B7
+            mov [edi + ebx + 8], eax
+            add edi, edx                // $edi = pbRGB += cbRGB
+
+            mov eax, [esp + 132]        // ..B1G1R1
+            mov ecx, [esp + 160]        // B0G0R0..
+            shld eax, ecx, 24           // R1B0G0R0
+            mov [edi + ebx + 0], eax
+            mov eax, [esp + 148]        // ..B5G5R5
+            mov ecx, [esp + 164]        // B1G1R1..
+            shld eax, ecx, 16           // G5R5B1G1
+            mov [edi + ebx + 4], eax
+            mov eax, [esp + 144]        // ..B4G4R4
+            mov ecx, [esp + 180]        // B5G5R5..
+            shld eax, ecx, 8            // B4G4R4B5
+            mov [edi + ebx + 8], eax
+            add edi, edx                // $edi = pbRGB += cbRGB
+
+            // RGBX32 -> RGB24
+            mov eax, [esp + 196]        // ..B1G1R1
+            mov ecx, [esp + 224]        // B0G0R0..
+            shld eax, ecx, 24           // R1B0G0R0
+            mov [edi + ebx + 0], eax
+            mov eax, [esp + 212]        // ..B5G5R5
+            mov ecx, [esp + 228]        // B1G1R1..
+            shld eax, ecx, 16           // G5R5B1G1
+            mov [edi + ebx + 4], eax
+            mov eax, [esp + 208]        // ..B4G4R4
+            mov ecx, [esp + 244]        // B5G5R5..
+            shld eax, ecx, 8            // B4G4R4B5
+            mov [edi + ebx + 8], eax
+            add edi, edx                // $edi = pbRGB += cbRGB
+
+            mov eax, [esp + 204]        // ..B3G3R3
+            mov ecx, [esp + 232]        // B2G2R2..
+            shld eax, ecx, 24           // R3B2G2R2
+            mov [edi + ebx + 0], eax
+            mov eax, [esp + 220]        // ..B7G7R7
+            mov ecx, [esp + 236]        // B3G3R3..
+            shld eax, ecx, 16           // G7R7B3G3
+            mov [edi + ebx + 4], eax
+            mov eax, [esp + 216]        // ..B6G6R6
+            mov ecx, [esp + 252]        // B7G7R7..
+            shld eax, ecx, 8            // B6G6R6B7
+            mov [edi + ebx + 8], eax
+            add edi, edx                // $edi = pbRGB += cbRGB
+
+            // RGBX32 -> RGB24
+            mov eax, [esp + 268]         // ..B3G3R3
+            mov ecx, [esp + 296]        // B2G2R2..
+            shld eax, ecx, 24           // R3B2G2R2
+            mov [edi + ebx + 0], eax
+            mov eax, [esp + 284]         // ..B7G7R7
+            mov ecx, [esp + 300]        // B3G3R3..
+            shld eax, ecx, 16           // G7R7B3G3
+            mov [edi + ebx + 4], eax
+            mov eax, [esp + 280]         // ..B6G6R6
+            mov ecx, [esp + 316]        // B7G7R7..
+            shld eax, ecx, 8            // B6G6R6B7
+            mov [edi + ebx + 8], eax
+            add edi, edx                // $edi = pbRGB += cbRGB
+
+            mov eax, [esp + 260]         // ..B1G1R1
+            mov ecx, [esp + 288]         // B0G0R0..
+            shld eax, ecx, 24           // R1B0G0R0
+            mov [edi + ebx + 0], eax
+            mov eax, [esp + 276]         // ..B5G5R5
+            mov ecx, [esp + 292]        // B1G1R1..
+            shld eax, ecx, 16           // G5R5B1G1
+            mov [edi + ebx + 4], eax
+            mov eax, [esp + 272]         // ..B4G4R4
+            mov ecx, [esp + 308]        // B5G5R5..
+            shld eax, ecx, 8            // B4G4R4B5
+            mov [edi + ebx + 8], eax
+            add edi, edx                // $edi = pbRGB += cbRGB
+
+        //================================
+        add esi, 256 - 64
+        add ebx, 12
+        jnz Loop0
+
+        //================
+        pop esp
+        pop edi
+        pop esi
+        pop ebx
+        pop ebp
+        ret 24
+    }
+}
+
+Int outputMBRow_RGB24_Lossy_3(CWMImageStrCodec* pSC)
+{
+#ifdef REENTRANT_MODE
+    const size_t cHeight = min((pSC->m_Dparam->cROIBottomY + 1) - (pSC->cRow - 1) * 16, 16);
+    const size_t iFirstRow = ((pSC->cRow - 1) * 16 > pSC->m_Dparam->cROITopY ? 0 : (pSC->m_Dparam->cROITopY & 0xf));
+#endif
+    const size_t cbRGB = pSC->WMIBI.cbStride;
+    const U8* const pbRGB = (U8*)pSC->WMIBI.pv + cbRGB * (pSC->cRow - 1) * 16;
+
+    U8* const pbY = (U8*)pSC->a0MBbuffer[0];
+    U8* const pbU = (U8*)pSC->a0MBbuffer[1];
+    // U8* const pbV = (U8*)pSC->a0MBbuffer[2];
+
+    const size_t cmbColumn = (pSC->WMII.cWidth + 15) / 16;
+
+    __declspec(align(16)) U8 Shift[16];
+
+    assert(BD_8 == pSC->WMII.bdBitDepth);
+    assert(CF_RGB == pSC->WMII.cfColorFormat);
+    assert(24 == pSC->WMII.cBitsPerUnit);
+    assert(pSC->WMII.bRGB);
+    assert(O_NONE == pSC->WMII.oOrientation);
+
+    assert(YUV_444 == pSC->m_param.cfColorFormat);
+
+    assert(pSC->m_Dparam->bDecodeFullFrame);
+
+    _mm_store_si128((__m128i *) Shift, pSC->m_param.bScaledArith ? g_const_d3 : g_const_d0);
+    storeRGB24_3(pbY + 64 * 0, pbU - pbY, pbRGB + cbRGB *  0, cbRGB, cmbColumn,
+        Shift);
+    storeRGB24_3(pbY + 64 * 2, pbU - pbY, pbRGB + cbRGB *  8, cbRGB, cmbColumn,
+        Shift);
+
+#ifdef REENTRANT_MODE
+    pSC->WMIBI.cLinesDecoded = cHeight - iFirstRow;
+#endif
+    return ICERR_OK;
+}
+#endif
+
+//================================================================
+#if defined(WMP_OPT_TRFM_DEC)
+FORCE_INLINE Void strDCT2x2up_OPT(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd)
+{
+    PixelI a, b, c, d, C, t;
+    a = *pa;
+    b = *pb;
+    C = *pc;
+    d = *pd;
+
+    a += d;
+    b -= C;
+    t = ((a - b + 1) >> 1);
+    c = t - d;
+    d = t - C;
+    a -= d;
+    b += c;
+
+    *pa = a;
+    *pb = b;
+    *pc = c;
+    *pd = d;
+}
+
+FORCE_INLINE Void invOdd_OPT(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd)
+{
+    PixelI a, b, c, d;
+    a = *pa;
+    b = *pb;
+    c = *pc;
+    d = *pd;
+
+    /** butterflies **/
+    b += d;
+    a -= c;
+    d -= (b) >> 1;
+    c += (a + 1) >> 1;
+
+    /** rotate pi/8 **/
+#define IROTATE2(a, b) (a) -= (((b)*3 + 4) >> 3), (b) += (((a)*3 + 4) >> 3)
+    IROTATE2(a, b);
+    IROTATE2(c, d);
+
+    /** butterflies **/
+    c -= (b + 1) >> 1;
+    d = ((a + 1) >> 1) - d;
+    b += c;
+    a -= d;
+
+    *pa = a;
+    *pb = b;
+    *pc = c;
+    *pd = d;
+}
+
+FORCE_INLINE Void invOddOdd_OPT(PixelI* pa, PixelI* pb, PixelI* pc, PixelI* pd)
+{
+    PixelI a, b, c, d, t1, t2;
+    a = *pa;
+    b = *pb;
+    c = *pc;
+    d = *pd;
+
+    /** butterflies **/
+    d += a;
+    c -= b;
+    a -= (t1 = d >> 1);
+    b += (t2 = c >> 1);
+
+    /** rotate pi/4 **/
+    a -= (b * 3 + 3) >> 3;
+    b += (a * 3 + 3) >> 2;
+    a -= (b * 3 + 4) >> 3;
+
+    /** butterflies **/
+    b -= t2;
+    a += t1;
+    c += b;
+    d -= a;
+
+    /** sign flips **/
+    *pa = a;
+    *pb = -b;
+    *pc = -c;
+    *pd = d;
+}
+
+FORCE_INLINE Void strDCT2x2dn_SSE2_1(PixelI* p)
+{
+    __m128i* const pdq = (__m128i*)p;
+    __m128i a = pdq[0];
+    __m128i b = pdq[1];
+    const __m128i C = pdq[2];
+    __m128i d = pdq[3];
+    __m128i t;
+    __m128i c;
+
+    a = _mm_add_epi32(a, d);
+    b = _mm_sub_epi32(b, C);
+    t = _mm_sub_epi32(a, b);
+    t = _mm_srai_epi32(t, 1);
+    c = _mm_sub_epi32(t, d);
+    d = _mm_sub_epi32(t, C);
+    a = _mm_sub_epi32(a, d);
+    b = _mm_add_epi32(b, c);
+
+    pdq[0] = a;
+    pdq[1] = b;
+    pdq[2] = c;
+    pdq[3] = d;
+}
+
+Void strIDCT4x4Stage1_OPT_H1(PixelI* p)
+{
+    /** top left corner, butterfly => butterfly **/
+    strDCT2x2up_OPT(p + 0, p + 1, p + 2, p + 3);
+
+    /** top right corner, -pi/8 rotation => butterfly **/
+    invOdd_OPT(p + 5, p + 4, p + 7, p + 6);
+
+    /** bottom left corner, butterfly => -pi/8 rotation **/
+    invOdd_OPT(p + 10, p + 8, p + 11, p + 9);
+
+    /** bottom right corner, -pi/8 rotation => -pi/8 rotation **/
+    invOddOdd_OPT(p + 15, p + 14, p + 13, p + 12);
+}
+
+FORCE_INLINE Void strIDCT4x4Stage1_OPT_H2(PixelI* p)
+{
+    /** butterfly **/
+    strDCT2x2dn_SSE2_1(p);
+}
+
+Void strIDCT4x4Stage1_OPT5(PixelI* p0, PixelI* p1)
+{
+    _mm_prefetch((char*)(p0 - 96 + 256), _MM_HINT_T0);
+    strIDCT4x4Stage1_OPT_H1(p0 - 96);
+    strIDCT4x4Stage1_OPT_H1(p0 - 80);
+    strIDCT4x4Stage1_OPT_H1(p0 - 32);
+    strIDCT4x4Stage1_OPT_H1(p0 - 16);
+
+    _mm_prefetch((char*)(p0 - 32 + 256), _MM_HINT_T0);
+    strIDCT4x4Stage1_OPT_H1(p0 + 32);
+    strIDCT4x4Stage1_OPT_H1(p0 + 48);
+    strIDCT4x4Stage1_OPT_H1(p0 + 96);
+    strIDCT4x4Stage1_OPT_H1(p0 + 112);
+
+    _mm_prefetch((char*)(p0 + 32 + 256), _MM_HINT_T0);
+    strIDCT4x4Stage1_OPT_H1(p1 - 128);
+    strIDCT4x4Stage1_OPT_H1(p1 - 112);
+    strIDCT4x4Stage1_OPT_H1(p1 - 64);
+    strIDCT4x4Stage1_OPT_H1(p1 - 48);
+
+    _mm_prefetch((char*)(p0 + 96 + 256), _MM_HINT_T0);
+    strIDCT4x4Stage1_OPT_H1(p1 + 0);
+    strIDCT4x4Stage1_OPT_H1(p1 + 16);
+    strIDCT4x4Stage1_OPT_H1(p1 + 64);
+    strIDCT4x4Stage1_OPT_H1(p1 + 80);
+
+    strIDCT4x4Stage1_OPT_H2(p0 - 96);
+    strIDCT4x4Stage1_OPT_H2(p0 - 80);
+    strIDCT4x4Stage1_OPT_H2(p0 - 32);
+    strIDCT4x4Stage1_OPT_H2(p0 - 16);
+    strIDCT4x4Stage1_OPT_H2(p0 + 32);
+    strIDCT4x4Stage1_OPT_H2(p0 + 48);
+    strIDCT4x4Stage1_OPT_H2(p0 + 96);
+    strIDCT4x4Stage1_OPT_H2(p0 + 112);
+
+    strIDCT4x4Stage1_OPT_H2(p1 - 128);
+    strIDCT4x4Stage1_OPT_H2(p1 - 112);
+    strIDCT4x4Stage1_OPT_H2(p1 - 64);
+    strIDCT4x4Stage1_OPT_H2(p1 - 48);
+    strIDCT4x4Stage1_OPT_H2(p1 + 0);
+    strIDCT4x4Stage1_OPT_H2(p1 + 16);
+    strIDCT4x4Stage1_OPT_H2(p1 + 64);
+    strIDCT4x4Stage1_OPT_H2(p1 + 80);
+}
+
+//================================
+__declspec(naked) void __stdcall strPost4x4Stage1_alternate_ASM5(PixelI* p0, PixelI* p1)
+{
+    UNREFERENCED_PARAMETER( p0 );
+    UNREFERENCED_PARAMETER( p1 );
+    __asm {
+        push ebp
+        push ebx
+        push esi
+        push edi
+
+        //================
+        // pointer array
+        mov eax, [esp + 20]     // $esi = p0
+        mov edx, [esp + 24]     // $edi = p1
+        mov ecx, 4 * 16
+        mov ebx, 4 * 48
+
+        prefetcht0 [eax + 512]
+        prefetcht0 [eax + 768]
+        prefetcht0 [eax + 1024]
+        prefetcht0 [eax + 1280]
+
+        add edx, ecx
+        add eax, ebx
+
+        push edx
+        sub edx, ecx
+        push edx
+        push edx
+        sub edx, ebx
+        push eax
+        push eax
+        sub eax, ecx
+        push eax
+        push eax
+        sub eax, ecx
+        push eax
+        sub eax, ecx
+
+        push edx
+        sub edx, ecx
+        push edx
+        sub eax, ecx
+        push edx
+        sub edx, ebx
+        push eax
+        push eax
+        sub eax, ecx
+        push eax
+        push eax
+        sub eax, ecx
+        push eax
+        sub eax, ecx
+        
+        push edx
+        sub edx, ecx
+        push edx
+        sub eax, ecx
+        push edx
+        sub edx, ebx
+        push eax
+        push eax
+        sub eax, ecx
+        push eax
+        push eax
+        sub eax, ecx
+        push eax
+        sub eax, ecx
+                
+        push edx
+        sub edx, ecx
+        push edx
+        sub eax, ecx
+        push edx
+        push eax
+        push eax
+        sub eax, ecx
+        push eax
+        push eax
+        sub eax, ecx
+        push eax
+
+        mov ebp, (4 + 4) * -16
+        push ebp
+    }
+Loop0:        
+    __asm {
+        mov esi, [esp + (4 + 4) * 16 + 4 + ebp ]    // $esi = p0
+        mov edi, [esp + (4 + 4) * 16 + 4 + ebp + 4] // $edi = p1
+
+        //================
+        movdqa xmm2, [esi + 4 * 12] // a = xmm2
+        movdqa xmm1, [esi + 4 * 72] // b = xmm1
+        movdqa xmm6, [edi + 4 * 4]  // c = xmm6
+        movdqa xmm7, [edi + 4 * 64] // d = xmm7
+
+        //================
+        // buttefly
+        paddd xmm2, xmm7
+        psubd xmm1, xmm6
+
+        movdqa xmm0, xmm2           // a = xmm0
+        psubd xmm2, xmm1
+        psrad xmm2, 1
+        movdqa xmm3, xmm2
+
+        psubd xmm2, xmm7            // c = xmm2
+        psubd xmm3, xmm6            // d = xmm3
+        paddd xmm1, xmm2
+        psubd xmm0, xmm3
+
+        //================
+        // bottom right corner: -pi/8 rotation => -pi/8 rotation
+        pshufd xmm7, xmm3, 0x3
+        movd eax, xmm3
+        movd edx, xmm7
+        pshufd xmm7, xmm3, 0x1
+        movd ebx, xmm7
+        pshufd xmm7, xmm3, 0x2
+        movd ecx, xmm7
+
+        add edx, eax
+        sub ecx, ebx
+        mov esi, edx
+        sar esi, 1
+        mov edi, ecx
+        sar edi, 1
+        sub eax, esi
+        add ebx, edi
+
+        lea ebp, [ebx + ebx * 2 + 6]
+        sar ebp, 3
+        sub eax, ebp
+        lea ebp, [eax + eax * 2 + 2]
+        sar ebp, 2
+        add ebx, ebp
+        lea ebp, [ebx + ebx * 2 + 4]
+        sar ebp, 3
+        sub eax, ebp
+
+        mov ebp, [esp]
+
+        sub ebx, edi
+        add eax, esi
+        add ecx, ebx
+        sub edx, eax
+
+        mov esi, [esp + (4 + 4) * 16 + 4 + ebp ]    // $esi = p0
+        mov edi, [esp + (4 + 4) * 16 + 4 + ebp + 4] // $edi = p1
+
+        movd xmm3, eax
+        movd xmm4, ebx
+        movd xmm5, ecx
+        movd xmm6, edx
+        punpckldq xmm3, xmm4
+        punpckldq xmm5, xmm6
+        punpcklqdq xmm3, xmm5
+
+        //================
+        // anti diagonal corners: rotation by -pi/8
+        movdqa xmm5, g_const_d1
+        movdqa xmm6, g_const_d1
+
+        pshufd xmm2, xmm2, 0xd8 //  7,  5,  6,  4
+        movdqa xmm4, xmm1       // 75, 74, 73, 72
+        punpckhqdq xmm1, xmm2   //  7,  5, 75, 74
+        punpcklqdq xmm4, xmm2   //  6,  4, 73, 72
+
+        paddd xmm5, xmm1
+        psrad xmm5, 1
+        psubd xmm4, xmm5
+
+        paddd xmm6, xmm4
+        psrad xmm6, 1
+        paddd xmm1, xmm6
+
+        movdqa xmm2, xmm4       //  6,  4, 73, 72
+        punpckhqdq xmm4, xmm1   //  7,  5,  6,  4
+        punpcklqdq xmm2, xmm1   // 75, 74, 73, 72
+        pshufd xmm4, xmm4, 0xd8 //  7,  6,  5,  4
+
+        //================
+        // butterfly
+        // a = xmm0, b = xmm2, c = xmm4, d = xmm3
+        paddd xmm0, xmm3
+        movdqa xmm1, xmm0   // a = xmm1
+        psrad xmm0, 1
+        psubd xmm0, xmm3    // d = xmm0
+
+        movdqa xmm3, xmm0   // d = xmm3
+        paddd xmm0, xmm0
+        paddd xmm0, xmm3
+        psrad xmm0, 3
+        paddd xmm1, xmm0
+
+        movdqa xmm0, xmm1   // a = xmm0
+        paddd xmm1, xmm1
+        paddd xmm1, xmm0
+        psrad xmm1, 4
+        paddd xmm3, xmm1
+
+        movdqa xmm5, xmm0   // a
+        psrad xmm5, 7
+        paddd xmm3, xmm5    // d += (a >> 7)
+        psrad xmm5, 3
+        psubd xmm3, xmm5    // d -= (a >> 10)
+
+        movdqa xmm5, [g_const_d4]
+        movdqa xmm1, xmm3   // d = xmm1
+        psubd xmm2, xmm4
+        paddd xmm5, xmm3
+        paddd xmm3, xmm3
+        paddd xmm3, xmm5
+        psrad xmm3, 3
+        paddd xmm0, xmm3
+
+        movdqa xmm3, xmm2   // b = xmm3
+        psrad xmm2, 1
+        psubd xmm1, xmm2
+
+        movdqa xmm2, xmm0   // a = xmm2
+        psubd xmm0, xmm3
+        psrad xmm0, 1
+        psubd xmm0, xmm4    // c = xmm0
+
+        paddd xmm3, xmm1
+        psubd xmm2, xmm0
+
+        //================
+        movdqa [edi + 4 * 4], xmm1
+        movdqa [edi + 4 * 64], xmm0
+        movdqa [esi + 4 * 12], xmm2
+        movdqa [esi + 4 * 72], xmm3
+
+        add ebp, 8
+        mov [esp], ebp
+        jnz Loop0
+
+        //================
+        add esp, (4 + 4) * 16 + 4
+        pop edi
+        pop esi
+        pop ebx
+        pop ebp
+        ret 4 * 2
+    }
+}
+
+Int invTransformMacroblock_YUV444_Center5(CWMImageStrCodec * pSC)
+{
+    const OVERLAP olOverlap = pSC->WMISCP.olOverlap;
+    int i = 0;
+
+    assert(0 < pSC->cRow && pSC->cRow < pSC->cmbHeight);
+    assert(0 < pSC->cColumn && pSC->cColumn < pSC->cmbWidth);
+
+    assert(0 == pSC->WMII.cPostProcStrength);
+
+    assert(YUV_444 == pSC->m_param.cfColorFormat);
+    assert(3 == pSC->m_param.cNumChannels);
+
+    assert(pSC->m_Dparam->bDecodeFullWidth);
+    assert(1 == pSC->m_Dparam->cThumbnailScale);
+
+    for (i = 0; i < 3; ++i)
+    {
+        PixelI* const p0 = pSC->p0MBbuffer[i];
+        PixelI* const p1 = pSC->p1MBbuffer[i];
+
+        //================================
+        // second level inverse transform
+        strIDCT4x4Stage2(p1);
+        if (pSC->m_param.bScaledArith) {
+            strNormalizeDec(p1, (i != 0));
+        }
+
+        //================================
+        // second level inverse overlap
+        if (OL_TWO <= olOverlap)
+        {
+            strPost4x4Stage2Split_alternate(p0, p1);
+        }
+
+        //================================
+        // first level inverse transform
+        strIDCT4x4Stage1_OPT5(p0, p1);
+
+        //================================
+        // first level inverse overlap
+        if (OL_ONE <= olOverlap)
+        {
+            strPost4x4Stage1_alternate_ASM5(p0, p1);
+        }
+    }
+
+    return ICERR_OK;
+}
+#endif
+#endif
+
+//================================================================
+void StrDecOpt(CWMImageStrCodec* pSC)
+{
+#if defined(WMP_OPT_SSE2)
+    if (IsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE))
+    {
+        CWMImageInfo* pII = &pSC->WMII;
+        // CWMIStrCodecParam* pSCP = &pSC->WMISCP;
+
+        g_const_d0 = _mm_setzero_si128();
+        g_const_d3 = _mm_set1_epi32(3);
+        g_const_d1 = _mm_set_epi32(1, 1, 1, 1);
+        g_const_d4 = _mm_set_epi32(4, 4, 4, 4);
+
+        g_const_d0x80 = _mm_set_epi32(0x80, 0x80, 0x80, 0x80);
+        g_const_w0x80 = _mm_set_epi16(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80);
+        g_const_b0x80 = _mm_set_epi8(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80);
+
+        if (pSC->WMII.fPaddedUserBuffer &&
+            //pSC->m_Dparam->bDecodeFullFrame &&
+            //((pII->cWidth & 0xf) == 0) &&
+            //(((int) pSC->WMIBI.pv & 0xf) == 0) &&
+            BD_8 == pII->bdBitDepth &&
+            CF_RGB == pII->cfColorFormat &&
+            24 == pII->cBitsPerUnit &&
+            pII->bRGB &&
+            O_NONE == pII->oOrientation &&
+            YUV_444 == pSC->m_param.cfColorFormat &&
+            pSC->p1MBbuffer[1] - pSC->p1MBbuffer[0] == pSC->p1MBbuffer[2] - pSC->p1MBbuffer[1] &&
+            pSC->m_Dparam->bDecodeFullFrame &&
+            1)
+        {
+#if defined(WMP_OPT_CC_DEC)
+            if (pSC->m_param.bScaledArith || pSC->WMISCP.olOverlap != OL_NONE)
+            {
+                pSC->Load = outputMBRow_RGB24_Lossy_3;
+            }
+            else
+            {
+                pSC->Load = outputMBRow_RGB24_Lossless_1;
+            }
+#endif // WMP_OPT_CC_DEC
+        }
+
+        if (YUV_444 == pSC->m_param.cfColorFormat &&
+            pSC->p1MBbuffer[1] - pSC->p1MBbuffer[0] == pSC->p1MBbuffer[2] - pSC->p1MBbuffer[1] &&
+            pSC->m_Dparam->bDecodeFullWidth &&
+            pSC->m_param.cSubVersion == CODEC_SUBVERSION_NEWSCALING_SOFT_TILES &&
+            1 == pSC->m_Dparam->cThumbnailScale)
+        {
+#if defined(WMP_OPT_TRFM_DEC)
+            pSC->TransformCenter = invTransformMacroblock_YUV444_Center5;
+#endif
+        }
+
+    }
+#else
+    UNREFERENCED_PARAMETER( pSC );
+#endif    
+}
+
diff --git a/Source/LibJXR/image/encode/encode.c b/Source/LibJXR/image/encode/encode.c
new file mode 100644
index 0000000..bd4fceb
--- /dev/null
+++ b/Source/LibJXR/image/encode/encode.c
@@ -0,0 +1,144 @@
+//*@@@+++@@@@******************************************************************
+//
+// Copyright � Microsoft Corp.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+// � Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// � Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//*@@@---@@@@******************************************************************
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "encode.h"
+#include "strcodec.h"
+#include "common.h"
+
+#ifdef MEM_TRACE
+#define TRACE_MALLOC    1
+#define TRACE_NEW       0
+#define TRACE_HEAP      0
+#include "memtrace.h"
+#endif
+
+/*************************************************************************
+    Context allocation
+    In theory it is possible to independently set uiTrimFlexBits for
+    each tile, but for now we assume only one user specified value is
+    used for the entire image
+*************************************************************************/
+Int AllocateCodingContextEnc(CWMImageStrCodec *pSC, Int iNumContexts, Int iTrimFlexBits)
+{
+    Int i, iCBPSize, k;
+    static const Int aAlphabet[] = {5,4,8,7,7,  12,6,6,12,6,6,7,7,  12,6,6,12,6,6,7,7};
+
+    if (iTrimFlexBits < 0)
+        iTrimFlexBits = 0;
+    else if (iTrimFlexBits > 15)
+        iTrimFlexBits = 15;    
+    pSC->m_param.bTrimFlexbitsFlag = (iTrimFlexBits > 0);
+
+    if (iNumContexts < 1 || iNumContexts > MAX_TILES)  // only between 1 and 256 allowed
+        return ICERR_ERROR;
+
+    if (pSC == NULL)
+        return ICERR_ERROR;
+
+    pSC->m_pCodingContext = malloc (iNumContexts * sizeof (CCodingContext));
+    if (pSC->m_pCodingContext == NULL) {
+        pSC->cNumCodingContext = 0;
+        return ICERR_ERROR;
+    }
+    memset (pSC->m_pCodingContext, 0, iNumContexts * sizeof (CCodingContext));
+
+    pSC->cNumCodingContext = iNumContexts;
+    iCBPSize = (pSC->m_param.cfColorFormat == Y_ONLY || pSC->m_param.cfColorFormat == NCOMPONENT
+        || pSC->m_param.cfColorFormat == CMYK) ? 5 : 9;
+
+    /** allocate / initialize members **/
+    for (i = 0; i < iNumContexts; i++) {
+        CCodingContext *pContext = &(pSC->m_pCodingContext[i]);
+
+        /** allocate adaptive Huffman encoder **/    
+        pContext->m_pAdaptHuffCBPCY = Allocate (iCBPSize, ENCODER);
+        if(pContext->m_pAdaptHuffCBPCY == NULL) {
+            return ICERR_ERROR;
+        }
+        pContext->m_pAdaptHuffCBPCY1 = Allocate(5, ENCODER);
+        if(pContext->m_pAdaptHuffCBPCY1 == NULL){
+            return ICERR_ERROR;
+        }
+
+        for(k = 0; k < NUMVLCTABLES; k ++){
+            pContext->m_pAHexpt[k] = Allocate(aAlphabet[k], ENCODER);
+            if(pContext->m_pAHexpt[k] == NULL){
+                return ICERR_ERROR;
+            }
+        }
+
+        ResetCodingContextEnc(pContext);
+        pContext->m_iTrimFlexBits = iTrimFlexBits;
+    }
+
+    return ICERR_OK;
+}
+
+/*************************************************************************
+    Context reset on encoder
+*************************************************************************/
+Void ResetCodingContextEnc(CCodingContext *pContext)
+{
+    Int k;
+    /** set flags **/
+    pContext->m_pAdaptHuffCBPCY->m_bInitialize = FALSE;
+    pContext->m_pAdaptHuffCBPCY1->m_bInitialize = FALSE;
+    for(k = 0; k < NUMVLCTABLES; k ++)
+        pContext->m_pAHexpt[k]->m_bInitialize = FALSE;
+
+    // reset VLC tables
+    AdaptLowpassEnc (pContext);
+    AdaptHighpassEnc (pContext);
+
+    // reset zigzag patterns, totals
+    InitZigzagScan(pContext);
+    // reset bit reduction and cbp models
+    ResetCodingContext(pContext);
+}
+
+/*************************************************************************
+    Context deletion
+*************************************************************************/
+Void FreeCodingContextEnc(CWMImageStrCodec *pSC)
+{
+    Int iContexts = (Int)(pSC->cNumCodingContext), i, k;
+    if (iContexts > 0 && pSC->m_pCodingContext) {
+
+        for (i = 0; i < iContexts; i++) {
+            CCodingContext *pContext = &(pSC->m_pCodingContext[i]);
+            Clean (pContext->m_pAdaptHuffCBPCY);
+            Clean (pContext->m_pAdaptHuffCBPCY1);
+            for (k = 0; k < NUMVLCTABLES; k++)
+                Clean (pContext->m_pAHexpt[k]);
+        }
+        free (pSC->m_pCodingContext);
+    }
+}
+
diff --git a/Source/LibJXR/image/encode/encode.h b/Source/LibJXR/image/encode/encode.h
new file mode 100644
index 0000000..db9e7bb
--- /dev/null
+++ b/Source/LibJXR/image/encode/encode.h
@@ -0,0 +1,113 @@
+//*@@@+++@@@@******************************************************************
+//
+// Copyright � Microsoft Corp.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+// � Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// � Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//*@@@---@@@@******************************************************************
+
+#ifndef WMI_ENCODE_H
+#define WMI_ENCODE_H
+
+#include "strcodec.h"
+
+/*************************************************************************
+    struct / class definitions
+*************************************************************************/
+
+Int EncodeMacroblockDC(CWMImageStrCodec*, CCodingContext *, Int, Int);
+Int EncodeMacroblockLowpass(CWMImageStrCodec*, CCodingContext *, Int, Int);
+Int EncodeMacroblockHighpass(CWMImageStrCodec*, CCodingContext *, Int, Int);
+
+Int quantizeMacroblock(CWMImageStrCodec *);
+Void transformMacroblock(CWMImageStrCodec *);
+Void predMacroblockEnc(CWMImageStrCodec *);
+
+Void AdaptLowpassEnc(CCodingContext *pContext);
+Void AdaptHighpassEnc(CCodingContext *pContext);
+Void ResetCodingContextEnc(CCodingContext *pContext);
+Int  AllocateCodingContextEnc(struct CWMImageStrCodec *pSC, Int iNumContexts, Int iTrimFlexBits);
+Void FreeCodingContextEnc(struct CWMImageStrCodec *pSC);
+Void predCBPEnc(CWMImageStrCodec *pSC, CCodingContext *pContext);
+
+/*************************************************************************
+    Forward transform definitions
+*************************************************************************/
+/** 2-point pre filter for boundaries (only used in 420 UV DC subband) **/
+Void strPre2(PixelI *, PixelI *);
+
+/** 2x2 pre filter (only used in 420 UV DC subband) **/
+Void strPre2x2(PixelI *, PixelI *, PixelI *, PixelI *);
+
+/** 4-point pre filter for boundaries **/
+Void strPre4(PixelI *, PixelI *, PixelI *, PixelI *);
+
+/** data allocation in working buffer (first stage) **/
+
+/** Y, 444 U and V **/
+/**  0  1  2  3 **/
+/** 32 33 34 35 **/
+/** 64 65 66 67 **/
+/** 96 97 98 99 **/
+
+/** 420 U and V **/
+/**   0   2   4   6 **/
+/**  64  66  68  70 **/
+/** 128 130 132 134 **/
+/** 192 194 196 198 **/
+
+/** 4x4 foward DCT for first stage **/
+Void strDCT4x4FirstStage(PixelI *);
+Void strDCT4x4FirstStage420UV(PixelI *);
+
+Void strDCT4x4Stage1(PixelI*);
+
+/** 4x4 pre filter for first stage **/
+Void strPre4x4FirstStage(PixelI *);
+Void strPre4x4FirstStage420UV(PixelI *);
+
+Void strPre4x4Stage1Split(PixelI* p0, PixelI* p1, Int iOffset);
+Void strPre4x4Stage1(PixelI* p, Int iOffset);
+
+/** data allocation in working buffer (second stage)**/
+
+/** Y, 444 U and V **/
+/**   0   4   8  12 **/
+/** 128 132 136 140 **/
+/** 256 260 264 268 **/
+/** 384 388 392 396 **/
+
+/** 420 U and V **/
+/**   0  8 **/
+/** 256 264 **/
+
+/** 4x4 foward DCT for second stage **/
+Void strDCT4x4SecondStage(PixelI *);
+Void strNormalizeEnc(PixelI *, Bool);
+Void strDCT2x2dnEnc(PixelI *, PixelI *, PixelI *, PixelI *);
+
+/** 4x4 pre filter for second stage **/
+Void strPre4x4Stage2Split(PixelI* p0, PixelI* p1);
+    
+#endif // ENCODE_H
+
diff --git a/Source/LibJXR/image/encode/segenc.c b/Source/LibJXR/image/encode/segenc.c
new file mode 100644
index 0000000..229719a
--- /dev/null
+++ b/Source/LibJXR/image/encode/segenc.c
@@ -0,0 +1,1186 @@
+//*@@@+++@@@@******************************************************************
+//
+// Copyright � Microsoft Corp.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+// � Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// � Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//*@@@---@@@@******************************************************************
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "strcodec.h"
+#include "encode.h"
+
+#ifdef MEM_TRACE
+#define TRACE_MALLOC    1
+#define TRACE_NEW       0
+#define TRACE_HEAP      0
+#include "memtrace.h"
+#endif
+
+/** local function definitions **/
+#ifdef X86OPT_INLINE
+__forceinline
+#endif
+static Int EncodeBlock (Bool bChroma, const Int *aLocalCoef, Int iNumNonzero,
+                         struct CAdaptiveHuffman **pAHexpt,
+                         Int iContextOffset, BitIOInfo* pOut, UInt iLocation);
+
+/*************************************************************************
+    EncodeSignificantAbsLevel
+*************************************************************************/
+#ifdef X86OPT_INLINE
+//__forceinline
+#endif
+static Void EncodeSignificantAbsLevel (UInt iAbsLevel, struct CAdaptiveHuffman *pAHexpt, BitIOInfo* pOut)
+{
+    Int iIndex, iFixed, aIndex[] = { 0,1,2,2, 3,3,3,3, 4,4,4,4, 5,5,5,5 };
+    Int aFixedLength[] = { 0, 0, 1, 2, 2, 2 };
+
+    assert(iAbsLevel > 0);
+    iAbsLevel--;
+    if (iAbsLevel >= 16) {
+        Int i = iAbsLevel;
+        iIndex = 6;
+        /** find leftmost bit **/
+        i >>= 5;
+        iFixed = 4;
+        while (i) { /** caution - infinite loop if not careful **/
+            iFixed++;
+            assert (iFixed < 30);
+            i >>= 1;
+        }
+        
+        pAHexpt->m_iDiscriminant += pAHexpt->m_pDelta[iIndex];
+        putBit16z(pOut, pAHexpt->m_pTable[iIndex * 2 + 1], pAHexpt->m_pTable[iIndex * 2 + 2]);
+        if (iFixed > 18) {
+            putBit16z (pOut, 15, 4);
+            if (iFixed > 21) {
+                putBit16z (pOut, 3, 2);
+                putBit16 (pOut, iFixed - 22, 3); // 22 - 29
+            }
+            else
+                putBit16z (pOut, iFixed - 19, 2); // 19 20 21
+        }
+        else {
+            putBit16z(pOut, (iFixed - 4), 4);
+        }
+        putBit32(pOut, iAbsLevel, iFixed);
+    }
+    else {
+        iIndex = aIndex[iAbsLevel];
+        iFixed = aFixedLength[iIndex];
+
+        pAHexpt->m_iDiscriminant += pAHexpt->m_pDelta[iIndex];
+        putBit16z(pOut, pAHexpt->m_pTable[iIndex * 2 + 1], pAHexpt->m_pTable[iIndex * 2 + 2]);
+        putBit32(pOut, iAbsLevel, iFixed);
+    }
+}
+
+/*************************************************************************
+    EncodeMacroblockDC
+*************************************************************************/
+
+Void encodeQPIndex(BitIOInfo* pIO, U8 iIndex,U8 cBits)
+{
+    if(iIndex == 0)
+        putBit16z(pIO, 0, 1);
+    else{
+        putBit16z(pIO, 1, 1);
+        putBit16z(pIO, iIndex - 1, cBits);
+    }
+}
+
+Int EncodeMacroblockDC (CWMImageStrCodec *pSC, CCodingContext *pContext, Int iMBX, Int iMBY)
+{
+    CWMITile * pTile = pSC->pTile + pSC->cTileColumn;
+    BitIOInfo* pIO = pContext->m_pIODC;
+    CWMIMBInfo *pMBInfo = &pSC->MBInfo;
+    Int iIndex, j = 0;
+    struct CAdaptiveHuffman *pAH;
+    Int aLaplacianMean[2] = { 0, 0}, *pLM = aLaplacianMean;
+    Int iModelBits = pContext->m_aModelDC.m_iFlcBits[0];
+    COLORFORMAT cf = pSC->m_param.cfColorFormat;
+    const Int iChannels = (Int) pSC->m_param.cNumChannels;
+
+    UNREFERENCED_PARAMETER( iMBX );
+    UNREFERENCED_PARAMETER( iMBY );
+
+    writeIS_L1(pSC, pIO);
+
+    if(pSC->m_param.bTranscode == FALSE){
+        pMBInfo->iQIndexLP = (U8)(pTile->cNumQPLP > 1 ? (rand() % pTile->cNumQPLP) : 0);
+        pMBInfo->iQIndexHP = (U8)(pTile->cNumQPHP > 1 ? (rand() % pTile->cNumQPHP) : 0);
+    }
+    if(pTile->cBitsHP == 0 && pTile->cNumQPHP > 1) // use LP QP
+        pMBInfo->iQIndexHP = pMBInfo->iQIndexLP;
+
+    if(pSC->WMISCP.bfBitstreamFormat == SPATIAL && pSC->WMISCP.sbSubband != SB_DC_ONLY){
+        if(pTile->cBitsLP > 0)  // MB-based LP QP index
+            encodeQPIndex(pIO, pMBInfo->iQIndexLP, pTile->cBitsLP);
+        if( pSC->WMISCP.sbSubband != SB_NO_HIGHPASS && pTile->cBitsHP > 0)  // MB-based HP QP index
+            encodeQPIndex(pIO, pMBInfo->iQIndexHP, pTile->cBitsHP);
+    }
+
+    if(pSC->m_param.bTranscode == FALSE)
+        pSC->Quantize(pSC);
+
+    predMacroblockEnc(pSC);
+
+    /** code path for Y_ONLY, CMYK and N_CHANNEL DC **/
+    if(cf == Y_ONLY || cf == CMYK || cf == NCOMPONENT) {
+        Int iQDC, iDC, iSign;
+        for (j = 0; j < iChannels; j++) {
+            iDC = pMBInfo->iBlockDC[j][0];
+            iSign = (iDC < 0);
+            iDC = abs(iDC);
+            iQDC = iDC >> iModelBits;
+
+            /** send luminance DC **/
+            if (iQDC) {
+                putBit16z(pIO, 1, 1);
+                EncodeSignificantAbsLevel((UInt) iQDC, pContext->m_pAHexpt[3], pIO);
+                *pLM += 1;
+            }
+            else {
+                putBit16z(pIO, 0, 1);
+            }
+
+            putBit16(pIO, iDC, iModelBits);
+            if (iDC) {
+                putBit16z(pIO, iSign, 1);
+            }
+
+            pLM = aLaplacianMean + 1;
+            iModelBits = pContext->m_aModelDC.m_iFlcBits[1];
+        }
+    }
+    else {  /** code path for YUV DC **/
+        Int iDCY, iDCU, iDCV, iQDCY, iQDCU, iQDCV;
+
+        pAH = pContext->m_pAHexpt[2];
+        iQDCY = abs(iDCY = pMBInfo->iBlockDC[0][0]);
+        iQDCU = abs(iDCU = pMBInfo->iBlockDC[1][0]);
+        iQDCV = abs(iDCV = pMBInfo->iBlockDC[2][0]);
+        if (iModelBits) {
+            iQDCY >>= iModelBits;
+        }
+
+        iModelBits = pContext->m_aModelDC.m_iFlcBits[1];
+        if (iModelBits) {
+            iQDCU >>= iModelBits;
+            iQDCV >>= iModelBits;
+        }
+        iModelBits = pContext->m_aModelDC.m_iFlcBits[0];
+
+        iIndex = (iQDCY != 0) * 4 + (iQDCU != 0) * 2 + (iQDCV != 0);
+        putBit16z(pIO, pAH->m_pTable[iIndex * 2 + 1], pAH->m_pTable[iIndex * 2 + 2]);
+
+        /** send luminance DC **/
+        if (iQDCY) {
+            EncodeSignificantAbsLevel((UInt) iQDCY, pContext->m_pAHexpt[3], pIO);
+            *pLM += 1;
+        }
+        putBit16(pIO, abs(iDCY), iModelBits);
+        if (iDCY) {
+            putBit16z(pIO, (iDCY < 0), 1);
+        }
+
+        /** send chroma DC **/
+        pLM = aLaplacianMean + 1;
+        iModelBits = pContext->m_aModelDC.m_iFlcBits[1];
+
+        if (iQDCU) {
+            EncodeSignificantAbsLevel((UInt) iQDCU, pContext->m_pAHexpt[4], pIO);
+            *pLM += 1;
+        }
+        putBit16(pIO, abs(iDCU), iModelBits);
+        if (iDCU) {
+            putBit16z(pIO, (iDCU < 0), 1);
+        }
+
+        if (iQDCV) {
+            EncodeSignificantAbsLevel((UInt) iQDCV, pContext->m_pAHexpt[4], pIO);
+            *pLM += 1;
+        }
+        putBit16(pIO, abs(iDCV), iModelBits);
+        if (iDCV) {
+            putBit16z(pIO, (iDCV < 0), 1);
+        }
+    }
+
+    UpdateModelMB (cf, iChannels, aLaplacianMean, &(pContext->m_aModelDC));
+
+    if (pSC->m_bResetContext && pSC->WMISCP.sbSubband == SB_DC_ONLY) {
+        AdaptDiscriminant(pContext->m_pAHexpt[2]);
+        AdaptDiscriminant(pContext->m_pAHexpt[3]);
+        AdaptDiscriminant(pContext->m_pAHexpt[4]);
+    }
+
+    return ICERR_OK;
+}
+
+/*************************************************************************
+    Scan block with zero model bits
+*************************************************************************/
+#ifdef X86OPT_INLINE
+__forceinline
+#endif
+static Int AdaptiveScanZero (const PixelI *pCoeffs, CAdaptiveScan *pScan,
+                             Int *pRLCoeffs, const Int iCount)
+{
+    Int k, iRun = 1, iLevel, iNumNonzero = 0; 
+
+	iLevel = pCoeffs[pScan[1].uScan];
+    if (iLevel) {
+        pScan[1].uTotal++;
+        pRLCoeffs[iNumNonzero * 2] = 0;
+        pRLCoeffs[iNumNonzero * 2 + 1] = iLevel;
+        iNumNonzero++;
+        iRun = 0;
+    }
+    for (k = 2; k < iCount; k++) {
+        iLevel = pCoeffs[pScan[k].uScan];
+        iRun++;
+        if (iLevel) {
+            pScan[k].uTotal++;
+            if (pScan[k].uTotal > pScan[k - 1].uTotal) {
+                CAdaptiveScan cTemp = pScan[k];
+                pScan[k] = pScan[k - 1];
+                pScan[k - 1] = cTemp;
+            }
+            pRLCoeffs[iNumNonzero * 2] = iRun - 1;
+            pRLCoeffs[iNumNonzero * 2 + 1] = iLevel;
+            iNumNonzero++;
+            iRun = 0;
+        }
+    }
+    return iNumNonzero;
+}
+
+/*************************************************************************
+    Scan block with nonzero model bits, all trimmed
+*************************************************************************/
+#ifdef X86OPT_INLINE
+__forceinline
+#endif
+static Int AdaptiveScanTrim (const PixelI *pCoeffs, CAdaptiveScan *pScan,
+                             const Int iModelBits, Int *pRLCoeffs, const Int iCount)
+{
+    Int k, iRun = 1, iLevel, iNumNonzero = 0;
+    Int iTemp; 
+    unsigned int iThOff = (1 << iModelBits) - 1, iTh = iThOff * 2 + 1;
+
+    iLevel = pCoeffs[pScan[1].uScan];
+
+    if ((unsigned int)(iLevel + iThOff) >= iTh) {
+        iTemp = abs (iLevel) >> iModelBits;
+        pScan[1].uTotal++;
+        pRLCoeffs[iNumNonzero * 2] = 0;
+        pRLCoeffs[iNumNonzero * 2 + 1] = (iLevel < 0) ? -iTemp : iTemp;
+        iNumNonzero++;
+        iRun = 0;
+    }
+    for (k = 2; k < iCount; k++) {
+        iRun++;
+        iLevel = pCoeffs[pScan[k].uScan];
+        if ((unsigned int)(iLevel + iThOff) >= iTh) {
+            iTemp = abs (iLevel) >> iModelBits;
+            pScan[k].uTotal++;
+            if (pScan[k].uTotal > pScan[k - 1].uTotal) {
+                CAdaptiveScan cTemp = pScan[k];
+                pScan[k] = pScan[k - 1];
+                pScan[k - 1] = cTemp;
+            }
+            pRLCoeffs[iNumNonzero * 2] = iRun - 1;
+            pRLCoeffs[iNumNonzero * 2 + 1] =  (iLevel < 0) ? -iTemp : iTemp;
+            iNumNonzero++;
+            iRun = 0;
+        }
+    }
+    return iNumNonzero;
+}
+
+/*************************************************************************
+    Scan block with nonzero model bits
+*************************************************************************/
+/** saves around 1.5% at QP=1 (no SIMD opt) **/
+#define USE_GRES_LUT
+#ifdef USE_GRES_LUT
+static const Int gRes[] = {
+65*2+1, 63*2+1, 61*2+1, 59*2+1, 57*2+1, 55*2+1, 53*2+1, 51*2+1, 49*2+1, 47*2+1, 45*2+1, 43*2+1, 41*2+1,
+39*2+1, 37*2+1, 35*2+1, 33*2+1, 31*2+1, 29*2+1, 27*2+1, 25*2+1, 23*2+1, 21*2+1, 19*2+1, 17*2+1, 15*2+1,
+13*2+1, 11*2+1,  9*2+1,  7*2+1,  5*2+1,  3*2+1,
+0,
+2*2+1,  4*2+1,  6*2+1,  8*2+1, 10*2+1, 12*2+1, 14*2+1, 16*2+1, 18*2+1, 20*2+1, 22*2+1, 24*2+1,
+26*2+1, 28*2+1, 30*2+1, 32*2+1, 34*2+1, 36*2+1, 38*2+1, 40*2+1, 42*2+1, 44*2+1, 46*2+1, 48*2+1, 50*2+1,
+52*2+1, 54*2+1, 56*2+1, 58*2+1, 60*2+1, 62*2+1, 64*2+1 };
+#endif // USE_GRES_LUT
+
+#ifdef X86OPT_INLINE
+//__forceinline
+#endif
+static Int AdaptiveScan (const PixelI *pCoeffs, Int *pResidual,
+                         CAdaptiveScan *pScan,
+                         const Int iModelBits, const Int iTrimBits,
+                         Int *pRLCoeffs, const Int iCount)
+{
+    if (iModelBits == 0) {
+        return AdaptiveScanZero (pCoeffs, pScan, pRLCoeffs, iCount);
+    }
+    else if (iModelBits <= iTrimBits) {
+        return AdaptiveScanTrim (pCoeffs, pScan, iModelBits, pRLCoeffs, iCount);
+    }
+    else if (iTrimBits == 0
+#ifdef USE_GRES_LUT
+        && iModelBits < 6
+#endif // USE_GRES_LUT
+        ) {
+        Int k, iRun = 0, iLevel, iNumNonzero = 0;
+        Int iTemp, iTemp1; 
+        const unsigned int iThOff = (1 << iModelBits) - 1, iTh = iThOff * 2 + 1;
+
+        iLevel = pCoeffs[pScan[1].uScan];
+
+        if ((unsigned int)(iLevel + iThOff) >= iTh) {
+            iTemp1 = abs (iLevel);
+            iTemp = iTemp1 >> iModelBits;
+            pResidual[pScan[1].uScan] = (iTemp1 & iThOff) * 2;
+            pScan[1].uTotal++;
+            pRLCoeffs[iNumNonzero * 2] = iRun;
+            pRLCoeffs[iNumNonzero * 2 + 1] = (iLevel < 0) ? -iTemp : iTemp;
+            iNumNonzero++;
+            iRun = 0;
+        }
+        else {
+            iRun++;
+#ifdef USE_GRES_LUT
+            pResidual[pScan[1].uScan] = gRes[(iLevel + 32)];
+#else // USE_GRES_LUT
+            iTemp = -(iLevel < 0);
+            pResidual[pScan[1].uScan] = (iLevel ^ iTemp) * 4 + (6 & iTemp) + (iLevel != 0);
+#endif // USE_GRES_LUT
+        }
+        for (k = 2; k < iCount; k++) {
+            const Int sk = pScan[k].uScan;
+            //pResidual++;
+            iLevel = pCoeffs[sk];
+            if ((unsigned int)(iLevel + iThOff) >= iTh) {
+                const Int iSign = -(iLevel < 0);
+                iTemp1 = (iSign ^ iLevel) - iSign;
+                iTemp = iTemp1 >> iModelBits;
+                pResidual[sk] = (iTemp1 & iThOff) * 2;
+                pScan[k].uTotal++;
+                if (pScan[k].uTotal > pScan[k - 1].uTotal) {
+                    CAdaptiveScan cTemp = pScan[k];
+                    pScan[k] = pScan[k - 1];
+                    pScan[k - 1] = cTemp;
+                }
+                pRLCoeffs[iNumNonzero * 2] = iRun;
+                pRLCoeffs[iNumNonzero * 2 + 1] =  (iTemp ^ iSign) - iSign;
+                iNumNonzero++;
+                iRun = 0;
+            }
+            else {
+                iRun++;
+#ifdef USE_GRES_LUT
+                pResidual[sk] = gRes[(iLevel + 32)];
+#else // USE_GRES_LUT
+                iTemp = -(iLevel < 0);
+                pResidual[sk] = (iLevel ^ iTemp) * 4 + (6 & iTemp) + (iLevel != 0);
+#endif // USE_GRES_LUT
+                 ////(abs(iLevel) * 4) + ((iLevel < 0) * 2) + (iLevel != 0);
+            }
+        }
+        return iNumNonzero;
+    }
+    else {
+        Int k, iRun = 0, iLevel, iNumNonzero = 0;
+        Int iTemp, iTemp1; 
+        const unsigned int iThOff = (1 << iModelBits) - 1, iTh = iThOff * 2 + 1;
+
+        iLevel = pCoeffs[pScan[1].uScan];
+        //pResidual++;
+        if ((unsigned int)(iLevel + iThOff) >= iTh) {
+            iTemp1 = abs (iLevel);
+            iTemp = iTemp1 >> iModelBits;
+            pResidual[pScan[1].uScan] = ((iTemp1 & iThOff) >> iTrimBits) * 2;
+            pScan[1].uTotal++;
+            pRLCoeffs[iNumNonzero * 2] = iRun;
+            pRLCoeffs[iNumNonzero * 2 + 1] = (iLevel < 0) ? -iTemp : iTemp;
+            iNumNonzero++;
+            iRun = 0;
+        }
+        else {
+            iRun++;
+            iTemp = -(iLevel < 0);
+            iLevel = ((iLevel + iTemp) >> iTrimBits) - iTemp;  // round towards zero
+            iTemp = -(iLevel < 0);
+            pResidual[pScan[1].uScan] = (iLevel ^ iTemp) * 4 + (6 & iTemp) + (iLevel != 0);
+        }
+        for (k = 2; k < iCount; k++) {
+            const Int sk = pScan[k].uScan;
+            //pResidual++;
+			iLevel = pCoeffs[sk];
+            if ((unsigned int)(iLevel + iThOff) >= iTh) {
+                iTemp1 = abs (iLevel);
+                iTemp = iTemp1 >> iModelBits;
+                pResidual[sk] = ((iTemp1 & iThOff) >> iTrimBits) * 2;
+                pScan[k].uTotal++;
+                if (pScan[k].uTotal > pScan[k - 1].uTotal) {
+                    CAdaptiveScan cTemp = pScan[k];
+                    pScan[k] = pScan[k - 1];
+                    pScan[k - 1] = cTemp;
+                }
+                pRLCoeffs[iNumNonzero * 2] = iRun;
+                pRLCoeffs[iNumNonzero * 2 + 1] =  (iLevel < 0) ? -iTemp : iTemp;
+                iNumNonzero++;
+                iRun = 0;
+            }
+            else {
+                iRun++;
+                iTemp = -(iLevel < 0);
+                iLevel = ((iLevel + iTemp) >> iTrimBits) - iTemp;  // round towards zero
+                iTemp = -(iLevel < 0);
+                pResidual[sk] = (iLevel ^ iTemp) * 4 + (6 & iTemp) + (iLevel != 0);
+            }
+        }
+        return iNumNonzero;
+    }
+}
+
+/*************************************************************************
+    EncodeMacroblockLowpass
+*************************************************************************/
+Int EncodeMacroblockLowpass (CWMImageStrCodec *pSC, CCodingContext *pContext, Int iMBX, Int iMBY)
+{
+    const COLORFORMAT cf = pSC->m_param.cfColorFormat;
+    const Int iChannels = (Int) pSC->m_param.cNumChannels;
+    Int iFullChannels = (cf == YUV_420 || cf == YUV_422) ? 1 : iChannels;
+    CWMIMBInfo *pMBInfo = &pSC->MBInfo;
+    BitIOInfo* pIO = pContext->m_pIOLP;
+
+    CAdaptiveScan *pScan = pContext->m_aScanLowpass;
+    Int  k, /*iPrevRun = -1,*/ iRun = 0;// iLastIndex = 0;
+    Int iModelBits = pContext->m_aModelLP.m_iFlcBits[0];
+    PixelI aBuf[2][8];
+    Int aLaplacianMean[2] = {0, 0}, *pLM = aLaplacianMean;
+    Int iChannel, iVal;
+    Int aRLCoeffs[MAX_CHANNELS][32], iNumCoeffs[MAX_CHANNELS];
+    const I32 *aDC[MAX_CHANNELS];
+    Int aResidual[MAX_CHANNELS][16];
+    Void (*putBits)(BitIOInfo* pIO, U32 uiBits, U32 cBits) = putBit16;
+
+    UNREFERENCED_PARAMETER( iMBX );
+    UNREFERENCED_PARAMETER( iMBY );
+
+    if (iChannels > MAX_CHANNELS)
+        return ICERR_ERROR;
+
+    if((pSC->WMISCP.bfBitstreamFormat != SPATIAL) && (pSC->pTile[pSC->cTileColumn].cBitsLP > 0))  // MB-based LP QP index
+        encodeQPIndex(pIO, pMBInfo->iQIndexLP, pSC->pTile[pSC->cTileColumn].cBitsLP);
+
+    // set arrays
+    for (k = 0; k < iChannels; k++) {
+        aDC[k] = pMBInfo->iBlockDC[k];
+    }
+
+    /** reset adaptive scan totals **/
+    if (pSC->m_bResetRGITotals) {
+        int iScale = 2;
+        int iWeight = iScale * 16;
+        pScan[0].uTotal = MAXTOTAL;
+        for (k = 1; k < 16; k++) {
+            pScan[k].uTotal = iWeight;
+            iWeight -= iScale;
+        }
+    }
+
+    /** scan 4x4 transform **/
+    for (iChannel = 0; iChannel < iFullChannels; iChannel++) {
+        iNumCoeffs[iChannel] = AdaptiveScan (aDC[iChannel], aResidual[iChannel],
+            pScan, iModelBits, 0, aRLCoeffs[iChannel], 16);
+
+        iModelBits = pContext->m_aModelLP.m_iFlcBits[1];
+    }
+
+    if (cf == YUV_420 || cf == YUV_422) {  /** interleave U and V **/
+        static const Int aRemap[] = { 4,  1,2,3,  5,6,7 };
+        const Int *pRemap = aRemap + (cf == YUV_420);
+        const Int iCount = (cf == YUV_420) ? 6 : 14;
+        Int iCoef = 0;
+
+        iRun = 0;
+        iModelBits = pContext->m_aModelLP.m_iFlcBits[1];
+
+        for (k = 0; k < iCount; k++) {
+            Int iIndex = pRemap[k >> 1];
+            Int iDC = aDC[(k & 1) + 1][iIndex];
+            aBuf[k & 1][iIndex] = iVal = abs (iDC) >> iModelBits;
+
+            if (iVal) {
+                aRLCoeffs[1][iCoef * 2] = iRun;
+                aRLCoeffs[1][iCoef * 2 + 1] = (iDC < 0) ? -iVal : iVal;
+                iCoef++;
+                iRun = 0;
+            }
+            else {
+                iRun++;
+            }
+        }
+        iNumCoeffs[1] = iCoef;
+    }
+
+    /** in raw mode, this can take 6% of the bits in the extreme low rate case!!! **/
+    if (cf == YUV_420 || cf == YUV_422)
+        iFullChannels = 2;
+
+    if (cf == YUV_420 || cf == YUV_422 || cf == YUV_444) {
+        int iCBP, iMax = iFullChannels * 4 - 5; /* actually (1 << iNChannels) - 1 **/
+        int iCountM = pContext->m_iCBPCountMax, iCountZ = pContext->m_iCBPCountZero;
+        iCBP = (iNumCoeffs[0] > 0) + (iNumCoeffs[1] > 0) * 2;
+        if (iFullChannels == 3)
+            iCBP += (iNumCoeffs[2] > 0) * 4;
+
+        if (iCountZ <= 0 || iCountM < 0) {
+            iVal = iCBP;
+            if (iCountM < iCountZ) {
+                iVal = iMax - iCBP;
+            }
+            if (iVal == 0)
+                putBit16z(pIO, 0, 1);
+            else if (iVal == 1)
+                putBit16z(pIO, (iFullChannels + 1) & 0x6, iFullChannels);  // 2 or 4
+            else
+                putBit16z(pIO, iVal + iMax + 1, iFullChannels + 1);  // cbp + 4 or cbp + 8
+        }
+        else {
+            putBit16z(pIO, iCBP, iFullChannels);
+        }
+
+        iCountM += 1 - 4 * (iCBP == iMax);//(b + c - 2*a);
+        iCountZ += 1 - 4 * (iCBP == 0);//(a + b - 2*c);
+        if (iCountM < -8)
+            iCountM = -8;
+        else if (iCountM > 7)
+            iCountM = 7;
+        pContext->m_iCBPCountMax = iCountM;
+
+        if (iCountZ < -8)
+            iCountZ = -8;
+        else if (iCountZ > 7)
+            iCountZ = 7;
+        pContext->m_iCBPCountZero = iCountZ;
+    }
+    else { /** 1 or N channel **/
+        for (iChannel = 0; iChannel < iChannels; iChannel++) {
+            putBit16z(pIO, (iNumCoeffs[iChannel] > 0), 1);
+        }
+    }
+
+    // set appropriate function pointer
+    if (pContext->m_aModelLP.m_iFlcBits[0] > 14 || pContext->m_aModelLP.m_iFlcBits[1] > 14) {
+        putBits = putBit32;
+    }
+
+    iModelBits = pContext->m_aModelLP.m_iFlcBits[0];
+
+    for (iChannel = 0; iChannel < iFullChannels; iChannel++) {
+        const Int *pRL = aRLCoeffs[iChannel];
+        Int iCoef = iNumCoeffs[iChannel];
+
+        if (iCoef) {
+            (*pLM) += iCoef;
+            if(EncodeBlock (iChannel > 0, pRL, iCoef, pContext->m_pAHexpt, CTDC,
+                pIO, 1 + 9 * ((cf == YUV_420) && (iChannel == 1)) + ((cf == YUV_422) && (iChannel == 1))) != ICERR_OK)
+                return ICERR_ERROR;
+        }
+
+        if (iModelBits) {
+            if ((cf == YUV_420 || cf == YUV_422) && iChannel) {  // 420/422 chroma
+                for (k = 1; k < ((cf == YUV_420) ? 4 : 8); k++) {
+                    putBits(pIO, abs(aDC[1][k]), iModelBits);
+                    if (aBuf[0][k] == 0 && aDC[1][k]) {
+                        putBit16z(pIO, (aDC[1][k] < 0), 1);
+                    }                      
+                    putBits(pIO, abs(aDC[2][k]), iModelBits);
+                    if (aBuf[1][k] == 0 && aDC[2][k]) {
+                        putBit16z(pIO, (aDC[2][k] < 0), 1);
+                    }
+                }
+            }
+            else {  // normal case
+                for (k = 1; k < 16; k++) {
+                    putBit16z(pIO, aResidual[iChannel][k] >> 1, iModelBits + (aResidual[iChannel][k] & 1));
+                }
+            }
+        }
+
+        pLM = aLaplacianMean + 1;
+        iModelBits = pContext->m_aModelLP.m_iFlcBits[1];
+    }
+
+    writeIS_L1(pSC, pIO);
+
+    UpdateModelMB (cf, iChannels, aLaplacianMean, &pContext->m_aModelLP);
+
+    if (pSC->m_bResetContext) {
+        AdaptLowpassEnc(pContext);
+    }
+
+    return ICERR_OK;
+}
+
+/*************************************************************************
+    Adapt
+*************************************************************************/
+Void AdaptLowpassEnc(CCodingContext *pSC)
+{
+    Int kk;
+    for (kk = 0; kk < CONTEXTX + CTDC; kk++) { /** adapt fixed code (index 0 and 1) as well **/
+        AdaptDiscriminant (pSC->m_pAHexpt[kk]);
+    }
+}
+
+Void AdaptHighpassEnc(CCodingContext *pSC)
+{
+    Int kk;
+    //Adapt (pSC->m_pAdaptHuffCBPCY, FALSE);
+    AdaptDiscriminant (pSC->m_pAdaptHuffCBPCY);
+    AdaptDiscriminant (pSC->m_pAdaptHuffCBPCY1);
+    for (kk = 0; kk < CONTEXTX; kk++) { /** adapt fixed code **/
+        AdaptDiscriminant (pSC->m_pAHexpt[kk + CONTEXTX + CTDC]);
+    }
+}
+
+/*************************************************************************
+    Experimental code -- encodeBlock
+    SR = <0 1 2> == <last, nonsignificant, significant run>
+    alphabet 12:
+        pAHexpt[0] == <SR', SL, SR | first symbol>
+    alphabet 6:
+        pAHexpt[1] == <SR', SL | continuous>
+        pAHexpt[2] == <SR', SL | continuous>
+    alphabet 4:
+        pAHexpt[3] == <SR', SL | 1 free slot> (SR may be last or insignificant only)
+    alphabet f(run) (this can be extended to 6 contexts - SL and SR')
+        pAHexpt[4] == <run | continuous>
+    alphabet f(lev) (this can be extended to 9 contexts)
+        pAHexpt[5-6] == <lev | continuous> first symbol
+        pAHexpt[7-8] == <lev | continuous> condition on SRn no use
+*************************************************************************/
+#ifdef X86OPT_INLINE
+__forceinline
+#endif
+static Void EncodeSignificantRun (Int iRun, Int iMaxRun, struct CAdaptiveHuffman *pAHexpt, BitIOInfo* pOut)
+{
+    Int iIndex, iFLC, iBin;
+    static const Int aIndex[] = {
+        0,1,2,2,3,3,4,4,4,4,4,4,4,4,
+        0,1,2,2,3,3,4,4,4,4,0,0,0,0,
+        0,1,2,3,4,4 
+    };
+
+    if (iMaxRun < 5) {
+        //if (iMaxRun == 4) {
+            //static const Int gCode[] = { 0, 1, 1, 1 };
+            static const Int gLen[] = { 3, 3, 2, 1 };
+            if (iMaxRun > 1)
+                putBit16z(pOut, (iMaxRun != iRun), gLen[iMaxRun - iRun] - (4 - iMaxRun));
+        //}
+        //else if (iMaxRun == 3) {
+        //    if (iRun == 1) {
+        //        putBit16z(pOut, 1, 1);
+        //    }
+        //    else {
+        //        putBit16z(pOut, 3 ^ iRun, 2);
+        //    }
+        //}
+        //else if (iMaxRun == 2) {
+        //    putBit16z(pOut, 2 - iRun, 1);
+        //}
+        return;
+    }
+
+    iBin = gSignificantRunBin[iMaxRun];
+    iIndex = aIndex[iRun + iBin * 14 - 1];
+    iFLC = gSignificantRunFixedLength[iIndex + iBin * 5];
+    putBit16z(pOut, pAHexpt->m_pTable[iIndex * 2 + 1], pAHexpt->m_pTable[iIndex * 2 + 2]);
+    //this always uses table 0
+    //pAHexpt->m_iDiscriminant += pAHexpt->m_pDelta[iIndex];
+    putBit16(pOut, iRun + 1, iFLC);
+}
+
+#ifdef X86OPT_INLINE
+__forceinline
+#endif
+static Void EncodeFirstIndex (Bool bChroma, Int iLoc, Int iCont, Int iIndex, Int iSign,
+                  struct CAdaptiveHuffman **ppAHexpt, BitIOInfo* pOut)
+{
+    // Int iContext = iCont + 1 + bChroma * 3;
+    struct CAdaptiveHuffman *pAHexpt = ppAHexpt[bChroma * 3];
+    UNREFERENCED_PARAMETER( iLoc );
+    UNREFERENCED_PARAMETER( iCont );
+    pAHexpt->m_iDiscriminant += pAHexpt->m_pDelta[iIndex];
+    pAHexpt->m_iDiscriminant1 += pAHexpt->m_pDelta1[iIndex];
+    putBit16z(pOut, pAHexpt->m_pTable[iIndex * 2 + 1] * 2 + iSign, pAHexpt->m_pTable[iIndex * 2 + 2] + 1);
+    return;
+}
+
+#ifdef X86OPT_INLINE
+__forceinline
+#endif
+static Void EncodeIndex (Bool bChroma, Int iLoc, Int iCont, Int iIndex, Int  iSign,
+                         struct CAdaptiveHuffman **ppAHexpt, BitIOInfo* pOut)
+{
+    Int iContext = iCont + 1 + bChroma * 3;
+
+    if (iLoc < 15) {
+        struct CAdaptiveHuffman *pAHexpt = ppAHexpt[iContext];
+        pAHexpt->m_iDiscriminant += pAHexpt->m_pDelta[iIndex];
+        pAHexpt->m_iDiscriminant1 += pAHexpt->m_pDelta1[iIndex];
+        putBit16z(pOut, pAHexpt->m_pTable[iIndex * 2 + 1] * 2 + iSign, pAHexpt->m_pTable[iIndex * 2 + 2] + 1);
+    }
+    else if (iLoc == 15) {
+        static const U32 gCode[] = { 0, 6, 2, 7 };
+        static const U32 gLen[] = { 1, 3, 2, 3 };
+        putBit16z(pOut, gCode[iIndex] * 2 + iSign, gLen[iIndex] + 1);
+        return;
+    }
+    else {//if (iLoc == 16) {
+        putBit16z(pOut, iIndex * 2 + iSign, 1 + 1);
+        return;
+    }
+}
+
+#ifdef X86OPT_INLINE
+__forceinline
+#endif
+static Int EncodeBlock (Bool bChroma, const Int *aLocalCoef, Int iNumNonzero,
+                         struct CAdaptiveHuffman **pAHexpt, Int iContextOffset,
+                         BitIOInfo* pOut, UInt iLocation)
+{
+    Int iSR, iSL, iSRn, iIndex, k, iCont, iLev;
+
+    /** first symbol **/
+    iLev = aLocalCoef[1];
+    iSR = (aLocalCoef[0] == 0);
+    iSL = ((unsigned int) (iLev + 1) > 2U);
+    iSRn = 1;
+    if (iNumNonzero == 1) {
+        iSRn = 0;
+    }
+    else if (aLocalCoef[2] > 0) {
+        iSRn = 2;
+    }
+    iIndex = iSRn * 4 + iSL * 2 + iSR;
+    EncodeFirstIndex (bChroma, iLocation, 0, iIndex, (iLev < 0), pAHexpt + iContextOffset, pOut);
+    iCont = iSR & iSRn;
+    if (iSL) {
+        EncodeSignificantAbsLevel ((UInt)(abs(iLev) - 1), pAHexpt[6 + iContextOffset + iCont], pOut);
+    }
+    if (iSR == 0) {
+        EncodeSignificantRun (aLocalCoef[0], 15 - iLocation, pAHexpt[0], pOut);
+    }
+    iLocation += aLocalCoef[0] + 1;
+
+    for (k = 1; k < iNumNonzero; k++) {
+        if (iSRn == 2) {
+            EncodeSignificantRun (aLocalCoef[k * 2], 15 - iLocation, pAHexpt[0], pOut);
+        }
+        iLocation += aLocalCoef[k * 2] + 1;
+        iSRn = 1;
+        if (k == iNumNonzero - 1) {
+            iSRn = 0;
+        }
+        else if (aLocalCoef[k * 2 + 2] > 0) {
+            iSRn = 2;
+        }
+        //iSL = (abs(aLocalCoef[k * 2 + 1]) > 1);
+        iLev = aLocalCoef[k * 2 + 1];
+        iSL = ((unsigned int) (iLev + 1) > 2U);
+        iIndex = iSRn * 2 + iSL;
+        EncodeIndex (bChroma, iLocation, iCont, iIndex, (iLev < 0), pAHexpt + iContextOffset, pOut);
+
+        iCont &= iSRn;  /** big difference! **/
+        if (iSL) {
+            EncodeSignificantAbsLevel ((UInt)(abs(iLev) - 1), pAHexpt[6 + iContextOffset + iCont], pOut);
+        }
+        //else {
+        //    putBit16z(pOut, (iLev < 0), 1);
+        //}
+    }
+
+    return ICERR_OK;
+}
+
+/*************************************************************************
+    CodeCoeffs
+*************************************************************************/
+#ifdef X86OPT_INLINE
+__forceinline
+#endif
+static Int CodeCoeffs (CWMImageStrCodec * pSC, CCodingContext *pContext,
+                        Int iMBX, Int iMBY, BitIOInfo* pIO, BitIOInfo* pIOFL)
+{
+    const COLORFORMAT cf = pSC->m_param.cfColorFormat;
+    const Int iChannels = (Int) pSC->m_param.cNumChannels;
+    const Int iPlanes = (cf == YUV_420 || cf == YUV_422) ? 1 : iChannels;
+    CWMIMBInfo * pMBInfo = &pSC->MBInfo;
+    CAdaptiveScan *pScan;
+    Int iBlock, iNBlocks = 4;
+    Int iSubblock, iIndex = 0;
+    Int i, k;
+    const Int iNumCoeffs = 16;
+    Int iModelBits = pContext->m_aModelAC.m_iFlcBits[0], iFlex = 0, iTrim = 0, iMask = 0;
+    Int aLaplacianMean[2] = { 0, 0}, *pLM = aLaplacianMean;
+    Bool bChroma = FALSE;
+
+    UNREFERENCED_PARAMETER( iMBX );
+    UNREFERENCED_PARAMETER( iMBY );
+
+    assert (iModelBits < 16);
+    if (pContext->m_iTrimFlexBits <= iModelBits && pSC->WMISCP.sbSubband != SB_NO_FLEXBITS) {
+        iTrim = pContext->m_iTrimFlexBits;
+        iFlex = iModelBits - pContext->m_iTrimFlexBits;
+        iMask = (1 << iFlex) - 1;
+    }
+
+    if(pSC->WMISCP.sbSubband != SB_NO_FLEXBITS)
+        writeIS_L1(pSC, pIOFL);
+
+    /** set scan arrays **/
+    if (pMBInfo->iOrientation == 1) {
+        pScan = pContext->m_aScanVert;
+    }
+    else {
+        pScan = pContext->m_aScanHoriz;
+    }
+
+    /** write out coefficients **/
+    for (i = 0; i < iPlanes; i++) {
+        Int iPattern = pMBInfo->iCBP[i];
+
+        if (cf == YUV_420) {
+            iNBlocks = 6;
+            iPattern += (pMBInfo->iCBP[1] << 16) + (pMBInfo->iCBP[2] << 20);
+        }
+        else if (cf == YUV_422) {
+            iNBlocks = 8;
+            iPattern += (pMBInfo->iCBP[1] << 16) + (pMBInfo->iCBP[2] << 24);
+        }
+
+        for (iBlock = iIndex = 0; iBlock < iNBlocks; iBlock++) {
+            writeIS_L2(pSC, pIO);
+            if (pIO != pIOFL)
+                writeIS_L2(pSC, pIOFL);
+            
+            for (iSubblock = 0; iSubblock < 4; iSubblock++, iPattern >>= 1, iIndex ++) {
+                const PixelI *pCoeffs = NULL;
+
+                if(iBlock < 4){
+                    pCoeffs = pSC->pPlane[i] + blkOffset[iIndex];
+                }
+                else if(cf == YUV_420){
+                    pCoeffs = pSC->pPlane[iBlock - 3] + blkOffsetUV[iSubblock];
+                }
+                else if(cf == YUV_422){
+                    pCoeffs = pSC->pPlane[1 + ((iBlock - 4) >> 1)] + blkOffsetUV_422[(iBlock & 1) * 4 + iSubblock];
+                }
+
+                /** put AC bits **/
+
+                if ((iPattern & 1) == 0) {
+                    if (iFlex) {
+                      /**  FLC only, all else is skipped **/
+                        for (k = 1; k < iNumCoeffs; k++) {
+                            Int data = pCoeffs[dctIndex[0][k]];
+                            Int atdata = (abs(data) >> iTrim);
+                            Int word = atdata & iMask, len = iFlex;
+                            if (atdata) {
+                                word += word + (data < 0);
+                                len++;
+                            }
+                            putBit16z(pIOFL, word, len);
+                        }
+                    }
+                }
+                else {
+// WARNING!!! interaction between lowpass coefficients and highpass scan ordering - may lead to break in decoding when model bits is nonzero!
+// Fix is to use same scan order in model bits transmission, and defer update of scan order to end of block
+                /** collect coefficients **/
+                    Int aLocalCoef[32], iNumNonzero = 0;
+                    Int aResidual[16];
+
+                    iNumNonzero = AdaptiveScan (pCoeffs, aResidual,
+                        pScan, iModelBits, iTrim, aLocalCoef, 16);
+                    (*pLM) += iNumNonzero;
+                    EncodeBlock (bChroma, aLocalCoef, iNumNonzero, pContext->m_pAHexpt, CTDC + CONTEXTX, pIO, 1);
+
+                    if (iFlex) {
+                        for (k = 1; k < iNumCoeffs; k++) {
+                            putBit16z(pIOFL, aResidual[dctIndex[0][k]] >> 1, iFlex + (aResidual[dctIndex[0][k]] & 1));
+                        }
+                    }
+                }
+            }
+            if (iBlock == 3) {
+                iModelBits = pContext->m_aModelAC.m_iFlcBits[1];
+                assert (iModelBits < 16);
+                pLM = aLaplacianMean + 1;
+                bChroma = TRUE;
+                iTrim = iFlex = iMask = 0;
+                if (pContext->m_iTrimFlexBits <= iModelBits && pSC->WMISCP.sbSubband != SB_NO_FLEXBITS) {
+                    iTrim = pContext->m_iTrimFlexBits;
+                    iFlex = iModelBits - iTrim;
+                    iMask = (1 << iFlex) - 1;
+                }
+            }
+        }
+    }
+
+    /** update model at end of MB **/
+    UpdateModelMB (cf, iChannels, aLaplacianMean, &pContext->m_aModelAC);
+
+    return ICERR_OK;
+}
+
+
+/*************************************************************************
+    CodeCBP
+*************************************************************************/
+static Void CodeCBP (CWMImageStrCodec * pSC, CCodingContext *pContext, 
+                     Int iMBX, Int iMBY, BitIOInfo *pIO)
+{
+    const COLORFORMAT cf = pSC->m_param.cfColorFormat;
+    const Int iChannel = (cf == NCOMPONENT || cf == CMYK) ? (Int) pSC->m_param.cNumChannels : 1;
+    Int iDiffCBPCY, iDiffCBPCU = 0, iDiffCBPCV = 0, iDY;
+    Int iBlock, i, k;
+    static const Int aNumOnes[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
+    static const Int aTabLen[] =  { 0, 2, 2, 2, 2, 2, 3, 2, 2, 3, 3, 2, 3, 2, 2, 0 };
+    static const Int aTabCode[] = { 0, 0, 1, 0, 2, 1, 4, 3, 3, 5, 6, 2, 7, 1, 0, 0 };
+    CAdaptiveHuffman *pAH;
+    Int iCount, iPattern, iCode, iCodeU = 0, iCodeV = 0;
+
+    UNREFERENCED_PARAMETER( iMBX );
+    UNREFERENCED_PARAMETER( iMBY );
+
+    predCBPEnc(pSC, pContext);
+    writeIS_L1(pSC, pIO);
+
+    iDiffCBPCU = pSC->MBInfo.iDiffCBP[1];
+    iDiffCBPCV = pSC->MBInfo.iDiffCBP[2];
+
+    for (i = 0; i < iChannel; i++) {
+        iDiffCBPCY = pSC->MBInfo.iDiffCBP[i];
+
+        if(cf == YUV_420){ // PackCBP420
+            iDiffCBPCY = (iDiffCBPCY & 0xf) + ((iDiffCBPCU & 1) <<  4) + ((iDiffCBPCV & 1) <<  5) +
+                ((iDiffCBPCY & 0x00f0) << 2) + ((iDiffCBPCU & 2) <<  9) + ((iDiffCBPCV & 2) << 10) +
+                ((iDiffCBPCY & 0x0f00) << 4) + ((iDiffCBPCU & 4) << 14) + ((iDiffCBPCV & 4) << 15) +
+                ((iDiffCBPCY & 0xf000) << 6) + ((iDiffCBPCU & 8) << 19) + ((iDiffCBPCV & 8) << 20);
+        }
+        else if(cf == YUV_422){// PackCBP422
+            iDiffCBPCY = (iDiffCBPCY & 0xf) + ((iDiffCBPCU & 1) <<  4) + ((iDiffCBPCU & 4) <<  3) +
+                ((iDiffCBPCV & 1) << 6) + ((iDiffCBPCV & 4) <<  5) +
+                ((iDiffCBPCY & 0x00f0) << 4) + ((iDiffCBPCU & 2) <<  11) + ((iDiffCBPCU & 8) << 10) +
+                ((iDiffCBPCV & 2) <<  13) + ((iDiffCBPCV & 8) <<  12) +
+                ((iDiffCBPCY & 0x0f00) << 8) + ((iDiffCBPCU & 16) << 16) + ((iDiffCBPCU & 64) << 15) +
+                ((iDiffCBPCV & 16) <<  18) + ((iDiffCBPCV & 64) <<  17) +
+                ((iDiffCBPCY & 0xf000) << 12) + ((iDiffCBPCU & 32) << 23) + ((iDiffCBPCU & 128) << 22) +
+                ((iDiffCBPCV & 32) <<  25) + ((iDiffCBPCV & 128) <<  24);
+        }
+
+        /** send CBPCY **/
+        iPattern = 0;
+        iDY = iDiffCBPCY;
+        if (cf == YUV_444) {
+            iDY |= (iDiffCBPCU | iDiffCBPCV);
+        }
+
+        for (iBlock = 0; iBlock < 4; iBlock++) {
+            if(cf == YUV_422) {
+                iPattern |= ((iDY & 0xff) != 0) * 0x10;
+                iDY >>= 8;
+            }
+            else if (cf == YUV_420) {
+                iPattern |= ((iDY & 0x3f) != 0) * 0x10;
+                iDY >>= 6;
+            }
+            else {
+                iPattern |= ((iDY & 0xf) != 0) * 0x10;
+                iDY >>= 4;
+            }
+            iPattern >>= 1;
+        }
+
+        pAH = pContext->m_pAdaptHuffCBPCY1;
+        iCount = aNumOnes[iPattern];
+        putBit16z(pIO, pAH->m_pTable[iCount * 2 + 1], pAH->m_pTable[iCount * 2 + 2]);
+        pAH->m_iDiscriminant += pAH->m_pDelta[iCount];
+        if (aTabLen[iPattern]) {
+            putBit16z(pIO, aTabCode[iPattern], aTabLen[iPattern]);
+        }
+
+        for (iBlock = 0; iBlock < 4; iBlock++) {
+            switch (cf) {
+                case YUV_444:
+                    iCode = iDiffCBPCY & 0xf;
+                    iCodeU = iDiffCBPCU & 0xf;
+                    iCodeV = iDiffCBPCV & 0xf;
+                    iCode |= ((iCodeU != 0) << 4);
+                    iCode |= ((iCodeV != 0) << 5);
+                    iDiffCBPCY >>= 4;
+                    iDiffCBPCU >>= 4;
+                    iDiffCBPCV >>= 4;
+                    break;
+
+                case YUV_422:
+                    iCode = iDiffCBPCY & 0xff;
+                    iDiffCBPCY >>= 8;
+                    break;
+
+                case YUV_420:
+                    iCode = iDiffCBPCY & 0x3f;
+                    iDiffCBPCY >>= 6;
+                    break;
+
+                default:
+                    iCode = iDiffCBPCY & 0xf;
+                    iDiffCBPCY >>= 4;
+            }
+
+            if (iCode) {
+                static const Int gTab0[16]  = { 0,1,1,2, 1,3,3,4, 1,3,3,4, 2,4,4,5 };
+                static const Int gFL0[16]   = { 0,2,2,1, 2,2,2,2, 2,2,2,2, 1,2,2,0 };
+                static const Int gCode0[16] = { 0,0,1,0, 2,0,1,0, 3,2,3,1, 1,2,3,0 };
+                int val, iChroma = (iCode >> 4);
+                iCode &= 0xf;
+                
+                if(cf == YUV_422) {
+                    iCodeU = (iChroma & 3);
+                    iCodeV = ((iChroma >> 2) & 3);
+                    iChroma = (iCodeU == 0 ? 0 : 1);
+                    if(iCodeV != 0) {
+                        iChroma += 2;
+                    }
+                }
+
+                if (iChroma) {
+                    if (gTab0[iCode] > 2) {
+                        val = 8;
+                    }
+                    else {
+                        val = gTab0[iCode] + 6 - 1;
+                    }
+                }
+                else {
+                    val = gTab0[iCode] - 1;
+                }
+                pAH = pContext->m_pAdaptHuffCBPCY;
+                putBit16z(pIO, pAH->m_pTable[val * 2 + 1], pAH->m_pTable[val * 2 + 2]);
+                pAH->m_iDiscriminant += pAH->m_pDelta[val];
+
+                if (iChroma) {
+                    if (iChroma == 1)
+                        putBit16z(pIO, 1, 1);
+                    else
+                        putBit16z(pIO, 3 - iChroma, 2);
+                }
+                if (val == 8) {
+                    if (gTab0[iCode] == 3) {
+                        putBit16z(pIO, 1, 1);
+                    }
+                    else {
+                        putBit16z(pIO, 5 - gTab0[iCode], 2);
+                    }
+                }
+                if (gFL0[iCode]) {
+                    putBit16z(pIO, gCode0[iCode], gFL0[iCode]);
+                }
+
+                if (cf == YUV_444) {
+                    pAH = pContext->m_pAHexpt[1];
+                    iPattern = iCodeU;
+                    for (k = 0; k < 2; k++) {
+                        if (iPattern) {
+                            iCount = aNumOnes[iPattern];
+                            iCount--;
+                            putBit16z(pIO, pAH->m_pTable[iCount * 2 + 1], pAH->m_pTable[iCount * 2 + 2]);
+                            if (aTabLen[iPattern]) {
+                                putBit16z(pIO, aTabCode[iPattern], aTabLen[iPattern]);
+                            }
+                        }
+                        iPattern = iCodeV;
+                    }
+                }
+                else if (cf == YUV_422){
+                    iPattern = iCodeU;
+                    for(k = 0; k < 2; k ++) {
+                        if(iPattern) {
+                            if (iPattern == 1)
+                                putBit16z(pIO, 1, 1);
+                            else {
+                                putBit16z(pIO, 3 - iPattern, 2);
+                            }
+                        }
+                        iPattern = iCodeV;
+                    }
+                }
+            }
+        }
+    }
+}
+
+/*************************************************************************
+    macroblock encode function using 4x4 transforms
+*************************************************************************/
+Int EncodeMacroblockHighpass(CWMImageStrCodec * pSC, CCodingContext *pContext, Int iMBX, Int iMBY)
+{
+    BitIOInfo* pIO = pContext->m_pIOAC;
+    BitIOInfo* pIOFL = pContext->m_pIOFL;
+
+    if((pSC->WMISCP.bfBitstreamFormat != SPATIAL) && (pSC->pTile[pSC->cTileColumn].cBitsHP > 0))  // MB-based HP QP index
+        encodeQPIndex(pIO, pSC->MBInfo.iQIndexHP, pSC->pTile[pSC->cTileColumn].cBitsHP);
+
+    /** reset adaptive scan totals **/
+    if (pSC->m_bResetRGITotals) {
+        Int iScale = 2;
+        Int iWeight = iScale * 16;
+        Int k;
+        pContext->m_aScanHoriz[0].uTotal = pContext->m_aScanVert[0].uTotal = MAXTOTAL;
+        for (k = 1; k < 16; k++) {
+            pContext->m_aScanHoriz[k].uTotal = pContext->m_aScanVert[k].uTotal = iWeight;
+            iWeight -= iScale;
+        }
+    }
+    CodeCBP(pSC, pContext, iMBX, iMBY, pIO);
+    if(CodeCoeffs(pSC, pContext, iMBX, iMBY, pIO, pIOFL) != ICERR_OK)
+        return ICERR_ERROR;
+
+    if (pSC->m_bResetContext) {
+        AdaptHighpassEnc(pContext);
+    }
+
+    return ICERR_OK;
+}
diff --git a/Source/LibJXR/image/encode/strFwdTransform.c b/Source/LibJXR/image/encode/strFwdTransform.c
new file mode 100644
index 0000000..968e010
--- /dev/null
+++ b/Source/LibJXR/image/encode/strFwdTransform.c
@@ -0,0 +1,1111 @@
+//*@@@+++@@@@******************************************************************
+//
+// Copyright � Microsoft Corp.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+// � Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// � Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//*@@@---@@@@******************************************************************
+
+#include "strTransform.h"
+#include "encode.h"
+
+/** rotation by pi/8 **/
+#define ROTATE1(a, b) (b) -= (((a) + 1) >> 1), (a) += (((b) + 1) >> 1)  // this works well too
+#define ROTATE2(a, b) (b) -= (((a)*3 + 4) >> 3), (a) += (((b)*3 + 4) >> 3)  // this works well too
+
+/** local functions **/
+static Void fwdOddOdd(PixelI *, PixelI *, PixelI *, PixelI *);
+static Void fwdOddOddPre(PixelI *, PixelI *, PixelI *, PixelI *);
+static Void fwdOdd(PixelI *, PixelI *, PixelI *, PixelI *);
+static Void strDCT2x2alt(PixelI * a, PixelI * b, PixelI * c, PixelI * d);
+static Void strHSTenc1(PixelI *, PixelI *);
+static Void strHSTenc(PixelI *, PixelI *, PixelI *, PixelI *);
+static Void strHSTenc1_edge (PixelI *pa, PixelI *pd);
+
+//static Void scaleDownUp0(PixelI *, PixelI *);
+//static Void scaleDownUp1(PixelI *, PixelI *);
+//static Void scaleDownUp2(PixelI *, PixelI *);
+//#define FOURBUTTERFLY_ENC_ALT(p, i00, i01, i02, i03, i10, i11, i12, i13,	\
+//    i20, i21, i22, i23, i30, i31, i32, i33)		\
+//    strHSTenc(&p[i00], &p[i01], &p[i02], &p[i03]);			\
+//    strHSTenc(&p[i10], &p[i11], &p[i12], &p[i13]);			\
+//    strHSTenc(&p[i20], &p[i21], &p[i22], &p[i23]);			\
+//    strHSTenc(&p[i30], &p[i31], &p[i32], &p[i33]);          \
+//    strHSTenc1(&p[i00], &p[i03]);			\
+//    strHSTenc1(&p[i10], &p[i13]);			\
+//    strHSTenc1(&p[i20], &p[i23]);			\
+//    strHSTenc1(&p[i30], &p[i33])
+
+/** DCT stuff **/
+/** data order before DCT **/
+/**  0  1  2  3 **/
+/**  4  5  6  7 **/
+/**  8  9 10 11 **/
+/** 12 13 14 15 **/
+/** data order after DCT **/
+/** 0  8  4  6 **/
+/** 2 10 14 12 **/
+/** 1 11 15 13 **/
+/** 9  3  7  5 **/
+/** reordering should be combined with zigzag scan **/
+
+Void strDCT4x4Stage1(PixelI * p)
+{
+    /** butterfly **/
+    //FOURBUTTERFLY(p, 0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15);
+    FOURBUTTERFLY_HARDCODED1(p);
+
+    /** top left corner, butterfly => butterfly **/
+    strDCT2x2up(&p[0], &p[1], &p[2], &p[3]);
+
+    /** bottom right corner, pi/8 rotation => pi/8 rotation **/
+    fwdOddOdd(&p[15], &p[14], &p[13], &p[12]);
+
+    /** top right corner, butterfly => pi/8 rotation **/
+    fwdOdd(&p[5], &p[4], &p[7], &p[6]);
+
+    /** bottom left corner, pi/8 rotation => butterfly **/
+    fwdOdd(&p[10], &p[8], &p[11], &p[9]);
+}
+
+Void strDCT4x4SecondStage(PixelI * p)
+{
+    /** butterfly **/
+    FOURBUTTERFLY(p, 0, 192, 48, 240, 64, 128, 112, 176,16, 208, 32, 224,  80, 144, 96, 160);
+    
+    /** top left corner, butterfly => butterfly **/
+    strDCT2x2up(&p[0], &p[64], &p[16], &p[80]);
+    
+    /** bottom right corner, pi/8 rotation => pi/8 rotation **/
+    fwdOddOdd(&p[160], &p[224], &p[176], &p[240]);
+    
+    /** top right corner, butterfly => pi/8 rotation **/
+    fwdOdd(&p[128], &p[192], &p[144], &p[208]);
+    
+    /** bottom left corner, pi/8 rotation => butterfly **/
+    fwdOdd(&p[32], &p[48], &p[96], &p[112]);
+}
+
+Void strNormalizeEnc(PixelI* p, Bool bChroma)
+{
+    int i;
+    if (!bChroma) {
+        //for (i = 0; i < 256; i += 16) {
+        //    p[i] = (p[i] + 1) >> 2;
+        //}
+    }
+    else {
+        for (i = 0; i < 256; i += 16) {
+            p[i] >>= 1;
+        }
+    }
+}
+
+/** 2x2 DCT with pre-scaling - for use on encoder side **/
+Void strDCT2x2dnEnc(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd)
+{
+    PixelI a, b, c, d, C, t;
+    a = (*pa + 0) >> 1;
+    b = (*pb + 0) >> 1;
+    C = (*pc + 0) >> 1;
+    d = (*pd + 0) >> 1;
+    //PixelI t1, t2;
+  
+    a += d;
+    b -= C;
+    t = ((a - b) >> 1);
+    c = t - d;
+    d = t - C;
+    a -= d;
+    b += c;
+
+    *pa = a;
+    *pb = b;
+    *pc = c;
+    *pd = d;
+}
+
+/** pre filter stuff **/
+/** 2-point pre for boundaries **/
+Void strPre2(PixelI * pa, PixelI * pb)
+{
+    PixelI a, b;
+    a = *pa;
+    b = *pb;
+
+    /** rotate **/
+    b -= ((a + 2) >> 2);
+    a -= ((b + 1) >> 1);
+
+    a -= (b >> 5);
+    a -= (b >> 9);
+    a -= (b >> 13);
+
+    b -= ((a + 2) >> 2);
+
+    *pa = a;
+    *pb = b;
+}
+
+Void strPre2x2(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd)
+{
+    PixelI a, b, c, d;
+    a = *pa;
+    b = *pb;
+    c = *pc;
+    d = *pd;
+
+    /** butterflies **/
+    a += d;
+    b += c;
+    d -= (a + 1) >> 1;
+    c -= (b + 1) >> 1;
+
+    /** rotate **/
+    b -= ((a + 2) >> 2);
+    a -= ((b + 1) >> 1);
+    a -= (b >> 5);
+    a -= (b >> 9);
+    a -= (b >> 13);
+    b -= ((a + 2) >> 2);
+
+    /** butterflies **/
+    d += (a + 1) >> 1;
+    c += (b + 1) >> 1;
+    a -= d;
+    b -= c;
+
+    *pa = a;
+    *pb = b;
+    *pc = c;
+    *pd = d;
+}
+
+/** 4-point pre for boundaries **/
+Void strPre4(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd)
+{
+    PixelI a, b, c, d;
+    a = *pa;
+    b = *pb;
+    c = *pc;
+    d = *pd;
+
+    a += d, b += c;
+    d -= ((a + 1) >> 1), c -= ((b + 1) >> 1);
+    
+    ROTATE1(c, d);
+    
+    strHSTenc1_edge(&a, &d); strHSTenc1_edge(&b, &c);
+    
+    d += ((a + 1) >> 1), c += ((b + 1) >> 1);
+    a -= d, b -= c;
+
+    *pa = a;
+    *pb = b;
+    *pc = c;
+    *pd = d;
+}
+
+/*****************************************************************************************
+  Input data offsets:
+  (15)(14)|(10+64)(11+64) p0 (15)(14)|(74)(75)
+  (13)(12)|( 8+64)( 9+64)    (13)(12)|(72)(73)
+  --------+--------------    --------+--------
+  ( 5)( 4)|( 0+64) (1+64) p1 ( 5)( 4)|(64)(65)
+  ( 7)( 6)|( 2+64) (3+64)    ( 7)( 6)|(66)(67)
+*****************************************************************************************/
+Void strPre4x4Stage1Split(PixelI *p0, PixelI *p1, Int iOffset)
+{
+    PixelI *p2 = p0 + 72 - iOffset;
+    PixelI *p3 = p1 + 64 - iOffset;
+    p0 += 12;
+    p1 += 4;
+
+    /** butterfly & scaling **/
+    strHSTenc(p0 + 0, p2 + 0, p1 + 0, p3 + 0);
+    strHSTenc(p0 + 1, p2 + 1, p1 + 1, p3 + 1);
+    strHSTenc(p0 + 2, p2 + 2, p1 + 2, p3 + 2);
+    strHSTenc(p0 + 3, p2 + 3, p1 + 3, p3 + 3);
+    strHSTenc1(p0 + 0, p3 + 0);
+    strHSTenc1(p0 + 1, p3 + 1);
+    strHSTenc1(p0 + 2, p3 + 2);
+    strHSTenc1(p0 + 3, p3 + 3);
+
+    /** anti diagonal corners: rotation by pi/8 **/
+    ROTATE1(p1[2], p1[3]);
+    ROTATE1(p1[0], p1[1]);
+    ROTATE1(p2[1], p2[3]);
+    ROTATE1(p2[0], p2[2]);
+
+    /** bottom right corner: pi/8 rotation => pi/8 rotation **/
+    fwdOddOddPre(p3 + 0, p3 + 1, p3 + 2, p3 + 3);
+
+    /** butterfly **/
+    strDCT2x2dn(p0 + 0, p2 + 0, p1 + 0, p3 + 0);
+    strDCT2x2dn(p0 + 1, p2 + 1, p1 + 1, p3 + 1);
+    strDCT2x2dn(p0 + 2, p2 + 2, p1 + 2, p3 + 2);
+    strDCT2x2dn(p0 + 3, p2 + 3, p1 + 3, p3 + 3);
+}
+
+Void strPre4x4Stage1(PixelI* p, Int iOffset)
+{
+    strPre4x4Stage1Split(p, p + 16, iOffset);
+}
+
+/*****************************************************************************************
+  Input data offsets:
+  (15)(14)|(10+32)(11+32) p0 (15)(14)|(42)(43)
+  (13)(12)|( 8+32)( 9+32)    (13)(12)|(40)(41)
+  --------+--------------    --------+--------
+  ( 5)( 4)|( 0+32)( 1+32) p1 ( 5)( 4)|(32)(33)
+  ( 7)( 6)|( 2+32)( 3+32)    ( 7)( 6)|(34)(35)
+*****************************************************************************************/
+Void strPre4x4Stage2Split(PixelI* p0, PixelI* p1)
+{
+    /** butterfly **/
+    strHSTenc(p0 - 96, p0 +  96, p1 - 112, p1 + 80);
+    strHSTenc(p0 - 32, p0 +  32, p1 -  48, p1 + 16);
+    strHSTenc(p0 - 80, p0 + 112, p1 - 128, p1 + 64);
+    strHSTenc(p0 - 16, p0 +  48, p1 -  64, p1 +  0);
+    strHSTenc1(p0 - 96, p1 + 80);
+    strHSTenc1(p0 - 32, p1 + 16);
+    strHSTenc1(p0 - 80, p1 + 64);
+    strHSTenc1(p0 - 16, p1 +  0);
+
+    /** anti diagonal corners: rotation **/
+    ROTATE1(p1[-48], p1[-112]);
+    ROTATE1(p1[-64], p1[-128]);
+    ROTATE1(p0[112], p0[  96]);
+    ROTATE1(p0[ 48], p0[  32]);
+
+    /** bottom right corner: pi/8 rotation => pi/8 rotation **/
+    fwdOddOddPre(p1 + 0, p1 + 64, p1 + 16, p1 + 80);
+
+    /** butterfly **/
+    strDCT2x2dn(p0 - 96, p1 - 112, p0 +  96, p1 + 80);
+    strDCT2x2dn(p0 - 32, p1 -  48, p0 +  32, p1 + 16);
+    strDCT2x2dn(p0 - 80, p1 - 128, p0 + 112, p1 + 64);
+    strDCT2x2dn(p0 - 16, p1 -  64, p0 +  48, p1 +  0);
+}
+
+
+/** 
+    Hadamard+Scale transform
+    for some strange reason, breaking up the function into two blocks, strHSTenc1 and strHSTenc
+    seems to work faster
+**/
+static Void strHSTenc(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd)
+{
+    /** different realization : does rescaling as well! **/
+    PixelI a, b, c, d;
+    a = *pa;
+    b = *pb;
+    d = *pc;
+    c = *pd;
+
+    a += c;
+    b -= d;
+    c = ((a - b) >> 1) - c;
+    d += (b >> 1);
+    b += c;
+
+    a -= (d * 3 + 4) >> 3;
+
+    *pa = a;
+    *pb = b;
+    *pc = c;
+    *pd = d;
+}
+
+static Void strHSTenc1(PixelI *pa, PixelI *pd)
+{
+    /** different realization : does rescaling as well! **/
+    PixelI a, d;
+    a = *pa;
+    d = *pd;
+
+    d -= (a >> 7);
+    d += (a >> 10);
+
+    //a -= (d * 3 + 4) >> 3;
+    d -= (a * 3 + 0) >> 4;
+    a -= (d * 3 + 0) >> 3;
+    d = (a >> 1) - d;
+    a -= d;
+
+    *pa = a;
+    *pd = d;
+}
+
+static Void strHSTenc1_edge (PixelI *pa, PixelI *pd)
+{
+    /** different realizion as compared to scaling operator for 2D case **/
+    PixelI a, d;
+    a = *pa;
+    d = -(*pd); // Negative sign needed here for 1D scaling case to ensure correct scaling.
+
+    a -= d;
+    d += (a >> 1);
+    a -= (d * 3 + 4) >> 3;
+    // End new operations
+
+    //Scaling modification of adding 7/1024 in two steps (without multiplication by 7).
+    d -= (a >> 7);
+    d += (a >> 10);
+
+    d -= (a * 3 + 0) >> 4;
+    a -= (d * 3 + 0) >> 3;
+    d = (a >> 1) - d;
+    a -= d;
+
+    *pa = a;
+    *pd = d;
+}
+
+/** Kron(Rotate(pi/8), Rotate(pi/8)) **/\
+static Void fwdOddOdd(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd)
+{
+    PixelI a, b, c, d, t1, t2;
+
+    a = *pa;
+    b = -*pb;
+    c = -*pc;
+    d = *pd;
+
+    /** butterflies **/
+    d += a;
+    c -= b;
+    a -= (t1 = d >> 1);
+    b += (t2 = c >> 1);
+
+    /** rotate pi/4 **/
+    a += (b * 3 + 4) >> 3;
+    b -= (a * 3 + 3) >> 2;
+    a += (b * 3 + 3) >> 3;
+
+    /** butterflies **/
+    b -= t2;
+    a += t1;
+    c += b;
+    d -= a;
+
+    *pa = a;
+    *pb = b;
+    *pc = c;
+    *pd = d;
+}
+/** Kron(Rotate(pi/8), Rotate(pi/8)) **/
+static Void fwdOddOddPre(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd)
+{
+    PixelI a, b, c, d, t1, t2;
+    a = *pa;
+    b = *pb;
+    c = *pc;
+    d = *pd;
+
+    /** butterflies **/
+    d += a;
+    c -= b;
+    a -= (t1 = d >> 1);
+    b += (t2 = c >> 1);
+
+    /** rotate pi/4 **/
+    a += (b * 3 + 4) >> 3;
+    b -= (a * 3 + 2) >> 2;
+    a += (b * 3 + 6) >> 3;
+
+    /** butterflies **/
+    b -= t2;
+    a += t1;
+    c += b;
+    d -= a;
+
+    *pa = a;
+    *pb = b;
+    *pc = c;
+    *pd = d;
+}
+
+/** Kron(Rotate(pi/8), [1 1; 1 -1]/sqrt(2)) **/
+/** [a b c d] => [D C A B] **/
+Void fwdOdd(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd)
+{
+    PixelI a, b, c, d;
+    a = *pa;
+    b = *pb;
+    c = *pc;
+    d = *pd;
+
+    /** butterflies **/
+    b -= c;
+    a += d;
+    c += (b + 1) >> 1;
+    d = ((a + 1) >> 1) - d;
+
+    /** rotate pi/8 **/
+    ROTATE2(a, b);
+    ROTATE2(c, d);
+
+    /** butterflies **/
+    d += (b) >> 1;
+    c -= (a + 1) >> 1;
+    b -= d;
+    a += c;
+
+    *pa = a;
+    *pb = b;
+    *pc = c;
+    *pd = d;
+}
+
+/*************************************************************************
+  Top-level function to tranform possible part of a macroblock
+*************************************************************************/
+Void transformMacroblock(CWMImageStrCodec * pSC)
+{
+    OVERLAP olOverlap = pSC->WMISCP.olOverlap;
+    COLORFORMAT cfColorFormat = pSC->m_param.cfColorFormat;
+    Bool left = (pSC->cColumn == 0), right = (pSC->cColumn == pSC->cmbWidth);
+    Bool top = (pSC->cRow == 0), bottom = (pSC->cRow == pSC->cmbHeight);
+    Bool leftORright = (left || right), topORbottom = (top || bottom);
+    Bool topORleft = (left || top);// rightORbottom = (right || bottom);
+    Bool leftAdjacentColumn = (pSC->cColumn == 1), rightAdjacentColumn = (pSC->cColumn == pSC->cmbWidth - 1);
+    // Bool topAdjacentRow =  (pSC->cRow == 1), bottomAdjacentRow = (pSC->cRow == pSC->cmbHeight - 1);
+    PixelI * p = NULL;// * pt = NULL;
+    Int i, j;
+    Int iNumChromaFullPlanes = (Int)((YUV_420 == cfColorFormat || YUV_422 == cfColorFormat) ?
+        1 : pSC->m_param.cNumChannels);
+
+#define mbX               pSC->mbX
+#define mbY               pSC->mbY
+#define tileX             pSC->tileX
+#define tileY             pSC->tileY
+#define bVertTileBoundary pSC->bVertTileBoundary
+#define bHoriTileBoundary pSC->bHoriTileBoundary
+#define bOneMBLeftVertTB  pSC->bOneMBLeftVertTB
+#define bOneMBRightVertTB pSC->bOneMBRightVertTB
+#define iPredBefore       pSC->iPredBefore
+#define iPredAfter        pSC->iPredAfter
+
+    if (pSC->WMISCP.bUseHardTileBoundaries) {
+        //Add tile location information
+        if (pSC->cColumn == 0) {
+            bVertTileBoundary = FALSE;
+            tileY = 0;
+        }
+        bOneMBLeftVertTB = bOneMBRightVertTB = FALSE;
+        if(tileY > 0 && tileY <= pSC->WMISCP.cNumOfSliceMinus1H && (pSC->cColumn - 1) == pSC->WMISCP.uiTileY[tileY]) 
+            bOneMBRightVertTB = TRUE;
+        if(tileY < pSC->WMISCP.cNumOfSliceMinus1H && pSC->cColumn == pSC->WMISCP.uiTileY[tileY + 1]) {
+            bVertTileBoundary = TRUE;
+            tileY++; 
+        }
+        else 
+            bVertTileBoundary = FALSE;
+        if(tileY < pSC->WMISCP.cNumOfSliceMinus1H && (pSC->cColumn + 1) == pSC->WMISCP.uiTileY[tileY + 1]) 
+            bOneMBLeftVertTB = TRUE;
+
+        if (pSC->cRow == 0) {
+            bHoriTileBoundary = FALSE;
+            tileX = 0;
+        }
+        else if(mbY != pSC->cRow && tileX < pSC->WMISCP.cNumOfSliceMinus1V && pSC->cRow == pSC->WMISCP.uiTileX[tileX + 1]) {
+            bHoriTileBoundary = TRUE;
+            tileX++; 
+        }
+        else if(mbY != pSC->cRow)
+            bHoriTileBoundary = FALSE;
+    }
+    else {
+        bVertTileBoundary = FALSE;
+        bHoriTileBoundary = FALSE;
+        bOneMBLeftVertTB = FALSE;
+        bOneMBRightVertTB = FALSE;
+    }
+    mbX = pSC->cColumn, mbY = pSC->cRow;
+
+    //================================================================
+    // 400_Y, 444_YUV
+    for(i = 0; i < iNumChromaFullPlanes; ++i)
+    {
+        PixelI* const p0 = pSC->p0MBbuffer[i];//(0 == i ? pSC->pY0 : (1 == i ? pSC->pU0 : pSC->pV0));
+        PixelI* const p1 = pSC->p1MBbuffer[i];//(0 == i ? pSC->pY1 : (1 == i ? pSC->pU1 : pSC->pV1));
+
+        //================================
+        // first level overlap
+        if(OL_NONE != olOverlap)
+        {
+            /* Corner operations */
+            if ((top || bHoriTileBoundary) && (left || bVertTileBoundary))
+                strPre4(p1 + 0, p1 + 1, p1 + 2, p1 + 3);
+            if ((top || bHoriTileBoundary) && (right || bVertTileBoundary))
+                strPre4(p1 - 59, p1 - 60, p1 - 57, p1 - 58);
+            if ((bottom || bHoriTileBoundary) && (left || bVertTileBoundary))
+                strPre4(p0 + 48 + 10, p0 + 48 + 11, p0 + 48 + 8, p0 + 48 + 9);
+            if ((bottom || bHoriTileBoundary) && (right || bVertTileBoundary))
+                strPre4(p0 - 1, p0 - 2, p0 - 3, p0 - 4);
+            if(!right && !bottom)
+            {
+                if (top || bHoriTileBoundary)
+                {
+
+                    for (j = ((left || bVertTileBoundary) ? 0 : -64); j < 192; j += 64)
+                    {
+                        p = p1 + j;
+                        strPre4(p + 5, p + 4, p + 64, p + 65);
+                        strPre4(p + 7, p + 6, p + 66, p + 67);
+                        p = NULL;
+                    }
+                }
+                else
+                {
+                    for (j = ((left || bVertTileBoundary) ? 0 : -64); j < 192; j += 64)
+                    {
+                        strPre4x4Stage1Split(p0 + 48 + j, p1 + j, 0);
+                    }
+                }
+
+                if (left || bVertTileBoundary)
+                {
+                    if (!top && !bHoriTileBoundary)
+                    {
+                        strPre4(p0 + 58, p0 + 56, p1 + 0, p1 + 2);
+                        strPre4(p0 + 59, p0 + 57, p1 + 1, p1 + 3);
+                    }
+
+                    for (j = -64; j < -16; j += 16)
+                    {
+                        p = p1 + j;
+                        strPre4(p + 74, p + 72, p + 80, p + 82);
+                        strPre4(p + 75, p + 73, p + 81, p + 83);
+                        p = NULL;
+                    }
+                }
+                else
+                {
+                    for (j = -64; j < -16; j += 16)
+                    {
+                        strPre4x4Stage1(p1 + j, 0);
+                    }
+                }
+
+                strPre4x4Stage1(p1 +   0, 0);
+                strPre4x4Stage1(p1 +  16, 0);
+                strPre4x4Stage1(p1 +  32, 0);
+                strPre4x4Stage1(p1 +  64, 0);
+                strPre4x4Stage1(p1 +  80, 0);
+                strPre4x4Stage1(p1 +  96, 0);
+                strPre4x4Stage1(p1 + 128, 0);
+                strPre4x4Stage1(p1 + 144, 0);
+                strPre4x4Stage1(p1 + 160, 0);
+            }
+            
+            if (bottom || bHoriTileBoundary)
+            {
+                for (j = ((left || bVertTileBoundary) ? 48 : -16); j < (right ? -16 : 240); j += 64)
+                {
+                    p = p0 + j;
+                    strPre4(p + 15, p + 14, p + 74, p + 75);
+                    strPre4(p + 13, p + 12, p + 72, p + 73);
+                    p = NULL;
+                }
+            }
+
+            if ((right || bVertTileBoundary) && !bottom)
+            {
+                if (!top && !bHoriTileBoundary)
+                {
+                    strPre4(p0 - 1, p0 - 3, p1 - 59, p1 - 57);
+                    strPre4(p0 - 2, p0 - 4, p1 - 60, p1 - 58);
+                }
+                for (j = -64; j < -16; j += 16)
+                {
+                    p = p1 + j;
+                    strPre4(p + 15, p + 13, p + 21, p + 23);
+                    strPre4(p + 14, p + 12, p + 20, p + 22);
+                    p = NULL;
+                }
+            }
+        }
+
+        //================================
+        // first level transform
+        if (!top)
+        {
+            for (j = (left ? 48 : -16); j < (right ? 48 : 240); j += 64)
+            {
+                strDCT4x4Stage1(p0 + j);
+            }
+        }
+
+        if (!bottom)
+        {
+            for (j = (left ? 0 : -64); j < (right ? 0 : 192); j += 64)
+            {
+                strDCT4x4Stage1(p1 + j + 0);
+                strDCT4x4Stage1(p1 + j + 16);
+                strDCT4x4Stage1(p1 + j + 32);
+            }
+        }
+        
+        //================================
+        // second level overlap
+        if (OL_TWO == olOverlap)
+        {
+            /* Corner operations */
+            if ((top || bHoriTileBoundary) && (left || bVertTileBoundary))
+                strPre4(p1 + 0, p1 + 64, p1 + 0 + 16, p1 + 64 + 16);
+            if ((top || bHoriTileBoundary) && (right || bVertTileBoundary))
+                strPre4(p1 - 128, p1 - 64, p1 - 128 + 16, p1 - 64 + 16); 
+            if ((bottom || bHoriTileBoundary) && (left || bVertTileBoundary))
+                strPre4(p0 + 32, p0 + 96, p0 + 32 + 16, p0 + 96 + 16);
+            if ((bottom || bHoriTileBoundary) && (right || bVertTileBoundary))
+                strPre4(p0 - 96, p0 - 32, p0 - 96 + 16, p0 - 32 + 16);
+            if ((leftORright || bVertTileBoundary) && (!topORbottom && !bHoriTileBoundary))
+            {
+                if (left || bVertTileBoundary) {
+                    j = 0;
+                    strPre4(p0 + j + 32, p0 + j +  48, p1 + j +  0, p1 + j + 16);
+                    strPre4(p0 + j + 96, p0 + j + 112, p1 + j + 64, p1 + j + 80);
+                }
+                if (right || bVertTileBoundary) {
+                    j = -128;
+                    strPre4(p0 + j + 32, p0 + j +  48, p1 + j +  0, p1 + j + 16);
+                    strPre4(p0 + j + 96, p0 + j + 112, p1 + j + 64, p1 + j + 80);
+                }
+            }
+
+            if (!leftORright && !bVertTileBoundary)
+            {
+                if (topORbottom || bHoriTileBoundary)
+                {
+                    if (top || bHoriTileBoundary) {
+                        p = p1;
+                        strPre4(p - 128, p - 64, p +  0, p + 64);
+                        strPre4(p - 112, p - 48, p + 16, p + 80);
+                        p = NULL;
+                    }
+                    if (bottom || bHoriTileBoundary) {
+                        p = p0 + 32;
+                        strPre4(p - 128, p - 64, p +  0, p + 64);
+                        strPre4(p - 112, p - 48, p + 16, p + 80);
+                        p = NULL;
+                    }
+                }
+                else
+                {
+                    strPre4x4Stage2Split(p0, p1);
+                }
+            }
+        }
+
+        //================================
+        // second level transform
+        if (!topORleft){
+            if (pSC->m_param.bScaledArith) {
+                strNormalizeEnc(p0 - 256, (i != 0));
+            }
+            strDCT4x4SecondStage(p0 - 256);
+        }
+    }
+
+    //================================================================
+    // 420_UV
+    for(i = 0; i < (YUV_420 == cfColorFormat? 2 : 0); ++i)
+    {
+        PixelI* const p0 = pSC->p0MBbuffer[1 + i];//(0 == i ? pSC->pU0 : pSC->pV0);
+        PixelI* const p1 = pSC->p1MBbuffer[1 + i];//(0 == i ? pSC->pU1 : pSC->pV1);
+
+        //================================
+        // first level overlap (420_UV)
+        if (OL_NONE != olOverlap)
+        {
+            /* Corner operations */
+            if ((top || bHoriTileBoundary) && (left || bVertTileBoundary))
+                strPre4(p1 + 0, p1 + 1, p1 + 2, p1 + 3);
+            if ((top || bHoriTileBoundary) && (right || bVertTileBoundary)) 
+                strPre4(p1 - 27, p1 - 28, p1 - 25, p1 - 26);
+            if ((bottom || bHoriTileBoundary) && (left || bVertTileBoundary))
+                strPre4(p0 + 16 + 10, p0 + 16 + 11, p0 + 16 + 8, p0 + 16 + 9);
+            if ((bottom || bHoriTileBoundary) && (right || bVertTileBoundary))               
+                strPre4(p0 - 1, p0 - 2, p0 - 3, p0 - 4);
+            if(!right && !bottom)
+            {
+                if (top || bHoriTileBoundary)
+                {
+
+                    for (j = ((left || bVertTileBoundary) ? 0 : -32); j < 32; j += 32)
+                    {
+                        p = p1 + j;
+                        strPre4(p + 5, p + 4, p + 32, p + 33);
+                        strPre4(p + 7, p + 6, p + 34, p + 35);
+                        p = NULL;
+                    }
+                }
+                else
+                {
+                    for (j = ((left || bVertTileBoundary) ? 0: -32); j < 32; j += 32)
+                    {
+                        strPre4x4Stage1Split(p0 + 16 + j, p1 + j, 32);
+                    }
+                }
+
+                if (left || bVertTileBoundary)
+                {
+                    if (!top && !bHoriTileBoundary)
+                    {
+                        strPre4(p0 + 26, p0 + 24, p1 + 0, p1 + 2);
+                        strPre4(p0 + 27, p0 + 25, p1 + 1, p1 + 3);
+                    }
+
+                    strPre4(p1 + 10, p1 + 8, p1 + 16, p1 + 18);
+                    strPre4(p1 + 11, p1 + 9, p1 + 17, p1 + 19);
+                }
+                else if (!bVertTileBoundary)
+                {
+                    strPre4x4Stage1(p1 - 32, 32);
+                }
+
+                strPre4x4Stage1(p1, 32);
+            }
+
+            if (bottom || bHoriTileBoundary)
+            {
+                for (j = ((left || bVertTileBoundary) ? 16: -16); j < (right ? -16: 32); j += 32)
+                {
+                    p = p0 + j;
+                    strPre4(p + 15, p + 14, p + 42, p + 43);
+                    strPre4(p + 13, p + 12, p + 40, p + 41);
+                    p = NULL;
+                }
+            }
+
+            if ((right || bVertTileBoundary) && !bottom)
+            {
+                if (!top && !bHoriTileBoundary)
+                {
+                    strPre4(p0 - 1, p0 - 3, p1 - 27, p1 - 25);
+                    strPre4(p0 - 2, p0 - 4, p1 - 28, p1 - 26);
+                }
+
+                strPre4(p1 - 17, p1 - 19, p1 - 11, p1 -  9);
+                strPre4(p1 - 18, p1 - 20, p1 - 12, p1 - 10);
+            }
+        }    
+
+        //================================
+        // first level transform (420_UV)
+        if (!top)
+        {
+            for (j = (left ? 16 : -16); j < (right ? 16 : 48); j += 32)
+            {
+                strDCT4x4Stage1(p0 + j);
+            }
+        }
+
+        if (!bottom)
+        {
+            for (j = (left ? 0 : -32); j < (right ? 0 : 32); j += 32)
+            {
+                strDCT4x4Stage1(p1 + j);
+            }
+        }
+        
+        //================================
+        // second level overlap (420_UV)
+        if (OL_TWO == olOverlap)
+        {
+            if ((leftAdjacentColumn || bOneMBRightVertTB) && (top || bHoriTileBoundary))
+                COMPUTE_CORNER_PRED_DIFF(p1 - 64 + 0, *(p1 - 64 + 32));
+
+            if ((rightAdjacentColumn || bOneMBLeftVertTB) && (top || bHoriTileBoundary))
+                iPredBefore[i][0] = *(p1 + 0);
+            if ((right || bVertTileBoundary) && (top || bHoriTileBoundary))
+                COMPUTE_CORNER_PRED_DIFF(p1 - 64 + 32, iPredBefore[i][0]);
+
+            if ((leftAdjacentColumn || bOneMBRightVertTB) && (bottom || bHoriTileBoundary)) 
+                COMPUTE_CORNER_PRED_DIFF(p0 - 64 + 16, *(p0 - 64 + 48));
+
+            if ((rightAdjacentColumn || bOneMBLeftVertTB) && (bottom || bHoriTileBoundary)) 
+                iPredBefore[i][1] = *(p0 + 16);
+            if ((right || bVertTileBoundary) && (bottom || bHoriTileBoundary))
+                COMPUTE_CORNER_PRED_DIFF(p0 - 64 + 48, iPredBefore[i][1]);
+
+            if ((leftORright || bVertTileBoundary) && !topORbottom && !bHoriTileBoundary)
+            {
+                if (left || bVertTileBoundary)
+                    strPre2(p0 + 0 + 16, p1 + 0);
+                if (right || bVertTileBoundary)
+                    strPre2(p0 + -32 + 16, p1 + -32);
+            }
+
+            if (!leftORright)
+            {
+                if ((topORbottom || bHoriTileBoundary) && !bVertTileBoundary)
+                {
+                    if (top || bHoriTileBoundary) 
+                        strPre2(p1 - 32, p1);
+                    if (bottom || bHoriTileBoundary) 
+                        strPre2(p0 + 16 - 32, p0 + 16);
+                }
+                else if (!topORbottom && !bHoriTileBoundary && !bVertTileBoundary)
+                    strPre2x2(p0 - 16, p0 + 16, p1 - 32, p1);
+            }
+            if ((leftAdjacentColumn || bOneMBRightVertTB) && (top || bHoriTileBoundary)) 
+                COMPUTE_CORNER_PRED_ADD(p1 - 64 + 0, *(p1 - 64 + 32));
+            if ((rightAdjacentColumn || bOneMBLeftVertTB) && (top || bHoriTileBoundary))
+                iPredAfter[i][0] = *(p1 + 0);
+            if ((right || bVertTileBoundary) && (top || bHoriTileBoundary))
+                COMPUTE_CORNER_PRED_ADD(p1 - 64 + 32, iPredAfter[i][0]);
+            if ((leftAdjacentColumn || bOneMBRightVertTB) && (bottom || bHoriTileBoundary)) 
+                COMPUTE_CORNER_PRED_ADD(p0 - 64 + 16, *(p0 - 64 + 48));
+            if ((rightAdjacentColumn || bOneMBLeftVertTB) && (bottom || bHoriTileBoundary)) 
+                iPredAfter[i][1] = *(p0 + 16);
+            if ((right || bVertTileBoundary) && (bottom || bHoriTileBoundary))
+                COMPUTE_CORNER_PRED_ADD(p0 - 64 + 48, iPredAfter[i][1]);
+        }
+
+        //================================
+        // second level transform (420_UV)
+        if (!topORleft)
+        {
+            if (!pSC->m_param.bScaledArith) {
+                strDCT2x2dn(p0 - 64, p0 - 32, p0 - 48, p0 - 16);
+            }
+            else {
+                strDCT2x2dnEnc(p0 - 64, p0 - 32, p0 - 48, p0 - 16);
+            }
+        }
+    }
+
+    //================================================================
+    //  422_UV
+    for(i = 0; i < (YUV_422 == cfColorFormat? 2 : 0); ++i)
+    {
+        PixelI* const p0 = pSC->p0MBbuffer[1 + i];//(0 == i ? pSC->pU0 : pSC->pV0);
+        PixelI* const p1 = pSC->p1MBbuffer[1 + i];//(0 == i ? pSC->pU1 : pSC->pV1);
+
+        //================================
+        // first level overlap (422_UV)
+        if (OL_NONE != olOverlap)
+        {
+            /* Corner operations */
+            if ((top || bHoriTileBoundary) && (left || bVertTileBoundary))
+                strPre4(p1 + 0, p1 + 1, p1 + 2, p1 + 3);
+            if ((top || bHoriTileBoundary) && (right || bVertTileBoundary))    
+                strPre4(p1 - 59, p1 - 60, p1 - 57, p1 - 58);
+            if ((bottom || bHoriTileBoundary) && (left || bVertTileBoundary))
+                strPre4(p0 + 48 + 10, p0 + 48 + 11, p0 + 48 + 8, p0 + 48 + 9);
+            if ((bottom || bHoriTileBoundary) && (right || bVertTileBoundary))
+                strPre4(p0 - 1, p0 - 2, p0 - 3, p0 - 4);
+            if(!right && !bottom)
+            {
+                if (top || bHoriTileBoundary)
+                {
+
+                    for (j = ((left || bVertTileBoundary) ? 0 : -64); j < 64; j += 64)
+                    {
+                        p = p1 + j;
+                        strPre4(p + 5, p + 4, p + 64, p + 65);
+                        strPre4(p + 7, p + 6, p + 66, p + 67);
+                        p = NULL;
+                    }
+                }
+                else
+                {
+                    for (j = ((left || bVertTileBoundary) ? 0: -64); j < 64; j += 64)
+                    {
+                        strPre4x4Stage1Split(p0 + 48 + j, p1 + j, 0);
+                    }
+                }
+
+                if (left || bVertTileBoundary)
+                {
+                    if (!top && !bHoriTileBoundary)
+                    {
+                        strPre4(p0 + 58, p0 + 56, p1 + 0, p1 + 2);
+                        strPre4(p0 + 59, p0 + 57, p1 + 1, p1 + 3);
+                    }
+
+                    for (j = 0; j < 48; j += 16)
+                    {
+                        p = p1 + j;
+                        strPre4(p + 10, p + 8, p + 16, p + 18);
+                        strPre4(p + 11, p + 9, p + 17, p + 19);
+                        p = NULL;
+                    }
+                }
+                else if (!bVertTileBoundary)
+                {
+                    for (j = -64; j < -16; j += 16)
+                    {
+                        strPre4x4Stage1(p1 + j, 0);
+                    }
+                }
+
+                strPre4x4Stage1(p1 +  0, 0);
+                strPre4x4Stage1(p1 + 16, 0);
+                strPre4x4Stage1(p1 + 32, 0);
+            }
+
+            if (bottom || bHoriTileBoundary)
+            {
+                for (j = ((left || bVertTileBoundary) ? 48: -16); j < (right ? -16: 112); j += 64)
+                {
+                    p = p0 + j;
+                    strPre4(p + 15, p + 14, p + 74, p + 75);
+                    strPre4(p + 13, p + 12, p + 72, p + 73);
+                    p = NULL;
+                }
+            }
+
+            if ((right || bVertTileBoundary) && !bottom)
+            {
+                if (!top && !bHoriTileBoundary)
+                {
+                    strPre4(p0 - 1, p0 - 3, p1 - 59, p1 - 57);
+                    strPre4(p0 - 2, p0 - 4, p1 - 60, p1 - 58);
+                }
+
+                for (j = -64; j < -16; j += 16)
+                {
+                    p = p1 + j;
+                    strPre4(p + 15, p + 13, p + 21, p + 23);
+                    strPre4(p + 14, p + 12, p + 20, p + 22);
+                    p = NULL;
+                }
+            }
+        }    
+
+        //================================
+        // first level transform (422_UV)
+        if (!top)
+        {
+            for (j = (left ? 48 : -16); j < (right ? 48 : 112); j += 64)
+            {
+                strDCT4x4Stage1(p0 + j);
+            }
+        }
+
+        if (!bottom)
+        {
+            for (j = (left ? 0 : -64); j < (right ? 0 : 64); j += 64)
+            {
+                strDCT4x4Stage1(p1 + j + 0);
+                strDCT4x4Stage1(p1 + j + 16);
+                strDCT4x4Stage1(p1 + j + 32);
+            }
+        }
+        
+        //================================
+        // second level overlap (422_UV)
+        if (OL_TWO == olOverlap)
+        {
+            if ((leftAdjacentColumn || bOneMBRightVertTB) && (top || bHoriTileBoundary)) 
+                COMPUTE_CORNER_PRED_DIFF(p1 - 128 + 0, *(p1 - 128 + 64));
+
+            if ((rightAdjacentColumn || bOneMBLeftVertTB) && (top || bHoriTileBoundary))
+                iPredBefore[i][0] = *(p1 + 0);
+            if ((right || bVertTileBoundary) && (top || bHoriTileBoundary))
+                COMPUTE_CORNER_PRED_DIFF(p1 - 128 + 64, iPredBefore[i][0]);
+
+            if ((leftAdjacentColumn || bOneMBRightVertTB) && (bottom || bHoriTileBoundary)) 
+                COMPUTE_CORNER_PRED_DIFF(p0 - 128 + 48, *(p0 - 128 + 112));
+
+            if ((rightAdjacentColumn || bOneMBLeftVertTB) && (bottom || bHoriTileBoundary)) 
+                iPredBefore[i][1] = *(p0 + 48);
+            if ((right || bVertTileBoundary) && (bottom || bHoriTileBoundary))
+                COMPUTE_CORNER_PRED_DIFF(p0 - 128 + 112, iPredBefore[i][1]);
+
+            if (!bottom)
+            {
+                if (leftORright || bVertTileBoundary)
+                {
+                    if (!top && !bHoriTileBoundary)
+                    {
+                        if (left || bVertTileBoundary) 
+                            strPre2(p0 + 48 + 0, p1 + 0);
+
+                        if (right || bVertTileBoundary) 
+                            strPre2(p0 + 48 + -64, p1 + -64);
+                    }
+
+                    if (left || bVertTileBoundary)
+                        strPre2(p1 + 16, p1 + 16 + 16);
+
+                    if (right || bVertTileBoundary)
+                        strPre2(p1 + -48, p1 + -48 + 16);
+                }
+
+                if (!leftORright && !bVertTileBoundary)
+                {
+                    if (top || bHoriTileBoundary)
+                        strPre2(p1 - 64, p1);
+                    else
+                        strPre2x2(p0 - 16, p0 + 48, p1 - 64, p1);
+
+                    strPre2x2(p1 - 48, p1 + 16, p1 - 32, p1 + 32);
+                }
+            }
+
+            if ((bottom || bHoriTileBoundary) && (!leftORright && !bVertTileBoundary))
+                strPre2(p0 - 16, p0 + 48);
+
+            if ((leftAdjacentColumn || bOneMBRightVertTB) && (top || bHoriTileBoundary)) 
+                COMPUTE_CORNER_PRED_ADD(p1 - 128 + 0, *(p1 - 128 + 64));
+
+            if ((rightAdjacentColumn || bOneMBLeftVertTB) && (top || bHoriTileBoundary))
+                iPredAfter[i][0] = *(p1 + 0);
+            if ((right || bVertTileBoundary) && (top || bHoriTileBoundary))
+                COMPUTE_CORNER_PRED_ADD(p1 - 128 + 64, iPredAfter[i][0]);
+
+            if ((leftAdjacentColumn || bOneMBRightVertTB) && (bottom || bHoriTileBoundary)) 
+                COMPUTE_CORNER_PRED_ADD(p0 - 128 + 48, *(p0 - 128 + 112));
+
+            if ((rightAdjacentColumn || bOneMBLeftVertTB) && (bottom || bHoriTileBoundary)) 
+                iPredAfter[i][1] = *(p0 + 48);
+            if ((right || bVertTileBoundary) && (bottom || bHoriTileBoundary))
+                COMPUTE_CORNER_PRED_ADD(p0 - 128 + 112, iPredAfter[i][1]);
+        }
+
+        //================================
+        // second level transform (422_UV)
+        if (!topORleft)
+        {
+            if (!pSC->m_param.bScaledArith) {
+                strDCT2x2dn(p0 - 128, p0 - 64, p0 - 112, p0 - 48);
+                strDCT2x2dn(p0 -  96, p0 - 32, p0 -  80, p0 - 16);
+            }
+            else {
+                strDCT2x2dnEnc(p0 - 128, p0 - 64, p0 - 112, p0 - 48);
+                strDCT2x2dnEnc(p0 -  96, p0 - 32, p0 -  80, p0 - 16);
+            }
+
+            // 1D lossless HT
+            p0[- 96] -= p0[-128];
+            p0[-128] += ((p0[-96] + 1) >> 1);
+        }
+    }
+    assert(NULL == p);
+}
+
diff --git a/Source/LibJXR/image/encode/strPredQuantEnc.c b/Source/LibJXR/image/encode/strPredQuantEnc.c
new file mode 100644
index 0000000..73970ce
--- /dev/null
+++ b/Source/LibJXR/image/encode/strPredQuantEnc.c
@@ -0,0 +1,511 @@
+//*@@@+++@@@@******************************************************************
+//
+// Copyright � Microsoft Corp.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+// � Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// � Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//*@@@---@@@@******************************************************************
+
+#include "strcodec.h"
+#include "encode.h"
+
+I32 QUANT_Mulless(PixelI v, PixelI o, I32 r)
+{
+    const I32 m = v >> 31;
+
+    assert(sizeof(PixelI) == sizeof(U32));
+    return ((((v ^ m) - m + o) >> r) ^ m) - m;
+}
+
+I32 MUL32HR(U32 a, U32 b, U32 r)
+{
+    return (I32)((U32)((U64)a * b >> 32) >> r);
+}
+
+I32 QUANT(PixelI v, PixelI o, I32 man, I32 exp)
+{
+    const I32 m = v >> 31;
+
+    assert(sizeof(PixelI) == sizeof(U32));
+    return (MUL32HR((v ^ m) - m + o, man, exp) ^ m) - m;
+}
+
+Int quantizeMacroblock(CWMImageStrCodec* pSC)
+{
+    CWMITile * pTile = pSC->pTile + pSC->cTileColumn;
+    CWMIMBInfo * pMBInfo = &pSC->MBInfo;
+    const COLORFORMAT cf = pSC->m_param.cfColorFormat;
+    int iChannel, i, j;
+
+    if(/*pSC->m_param.bScaledArith && */pSC->m_param.bTranscode == FALSE)
+        for(iChannel = 0; iChannel < (int)pSC->m_param.cNumChannels; iChannel ++){
+            const Bool bUV = (iChannel > 0 && (cf == YUV_444 || cf == YUV_422 || cf == YUV_420));
+            const int iNumBlock = (bUV ? (cf == YUV_422 ? 8 : (cf == YUV_420 ? 4 : 16)) : 16);
+            const int * pOffset = (iNumBlock == 4 ? blkOffsetUV : (iNumBlock == 8 ? blkOffsetUV_422 : blkOffset));
+            CWMIQuantizer * pQPDC = pTile->pQuantizerDC[iChannel];
+            CWMIQuantizer * pQPLP = pTile->pQuantizerLP[iChannel] + pMBInfo->iQIndexLP;
+            CWMIQuantizer * pQPHP = pTile->pQuantizerHP[iChannel] + pMBInfo->iQIndexHP;
+
+            for(j = 0; j < iNumBlock; j ++){
+                PixelI * pData = pSC->pPlane[iChannel] + pOffset[j];
+
+                if(j == 0) // DC
+                    pData[0] = (pQPDC->iMan == 0 ? QUANT_Mulless(pData[0], pQPDC->iOffset, pQPDC->iExp) : QUANT(pData[0], pQPDC->iOffset, pQPDC->iMan, pQPDC->iExp));
+                else if(pSC->WMISCP.sbSubband != SB_DC_ONLY) // LP
+                    pData[0] = (pQPLP->iMan == 0 ? QUANT_Mulless(pData[0], pQPLP->iOffset, pQPLP->iExp) : QUANT(pData[0], pQPLP->iOffset, pQPLP->iMan, pQPLP->iExp));
+
+                // quantize HP
+                if(pSC->WMISCP.sbSubband != SB_DC_ONLY && pSC->WMISCP.sbSubband != SB_NO_HIGHPASS)
+                    for(i = 1; i < 16; i ++)
+                        pData[i] = (pQPHP->iMan == 0 ? QUANT_Mulless(pData[i], pQPHP->iOffset, pQPHP->iExp) : QUANT(pData[i], pQPHP->iOffset, pQPHP->iMan, pQPHP->iExp));
+            }
+        }
+    
+    for(iChannel = 0; iChannel < (int)pSC->m_param.cNumChannels; iChannel ++){
+        I32 * pDC = pSC->MBInfo.iBlockDC[iChannel];
+        PixelI * pData = pSC->pPlane[iChannel];
+
+        if(iChannel > 0 && cf == YUV_422){
+            for(i = 0; i < 8; i ++){
+                pDC[i] = pData[blkOffsetUV_422[i]];
+            }
+        }
+        else if(iChannel > 0 && cf == YUV_420){
+            for(i = 0; i < 4; i ++){
+                pDC[i] = pData[blkOffsetUV[i]];
+            }
+        }
+        else{
+            for(i = 0; i < 16; i ++){
+                pDC[i] = pData[dctIndex[2][i]];
+            }
+        }
+    }
+
+    return 0;
+}
+
+/* frequency domain prediction */
+Void predMacroblockEnc(CWMImageStrCodec * pSC)
+{
+    const COLORFORMAT cf = pSC->m_param.cfColorFormat;
+    const Int iChannels = (cf == YUV_420 || cf == YUV_422) ? 1 : (Int) pSC->m_param.cNumChannels;
+    size_t mbX = pSC->cColumn - 1;// mbY = pSC->cRow - 1;
+    CWMIMBInfo *pMBInfo = &(pSC->MBInfo);
+    Int iDCACPredMode = getDCACPredMode(pSC, mbX);
+    Int iDCPredMode = (iDCACPredMode & 0x3);
+    Int iADPredMode = (iDCACPredMode & 0xC);
+    Int iACPredMode = getACPredMode(pMBInfo, cf);
+    PixelI * pOrg, * pRef;
+    Int i, j, k;
+
+    pMBInfo->iOrientation = 2 - iACPredMode;
+
+    /* keep necessary info for future prediction */
+    updatePredInfo(pSC, pMBInfo, mbX, cf);
+
+    for(i = 0; i < iChannels; i ++){
+        pOrg = pMBInfo->iBlockDC[i]; // current DC block
+        
+        /* DC prediction */
+        if(iDCPredMode == 1){ // predict DC from top
+            pOrg[0] -= (pSC->PredInfoPrevRow[i] + mbX)->iDC;
+        }
+        else if(iDCPredMode == 0){ // predict DC from left
+            pOrg[0] -= (pSC->PredInfo[i] + mbX - 1)->iDC;
+        }
+        else if(iDCPredMode == 2){// predict DC from top&left
+            pOrg[0] -= ((pSC->PredInfo[i] + mbX - 1)->iDC + (pSC->PredInfoPrevRow[i] + mbX)->iDC) >> 1;
+        }
+
+        /* AD prediction */
+        if(iADPredMode == 4){// predict AD from top
+            pRef = (pSC->PredInfoPrevRow[i] + mbX)->piAD;
+            pOrg[4] -= pRef[3], pOrg[8] -= pRef[4], pOrg[12] -= pRef[5];
+        }
+        else if(iADPredMode == 0){// predict AD from left
+            pRef = (pSC->PredInfo[i] + mbX - 1)->piAD;
+            pOrg[1] -= pRef[0], pOrg[2] -= pRef[1], pOrg[3] -= pRef[2];
+        }
+        
+        pOrg = pSC->pPlane[i];
+        /* AC prediction */
+        if(iACPredMode == 1){ // predict from top
+            for(k = 0; k <= 192; k += 64){
+                /* inside macroblock, in reverse order */
+                for(j = 48; j > 0; j -= 16){
+                    pOrg[k + j + 10] -= pOrg[k + j + 10 - 16];
+                    pOrg[k + j +  2] -= pOrg[k + j +  2 - 16];
+                    pOrg[k + j +  9] -= pOrg[k + j +  9 - 16];
+                }
+            }
+        }
+        else if(iACPredMode == 0){ // predict from left
+            for(k = 0; k < 64; k += 16){
+                /* inside macroblock, in reverse order */
+                for(j = 192; j > 0; j -= 64){
+                    pOrg[k + j + 5] -= pOrg[k + j + 5 - 64];
+                    pOrg[k + j + 1] -= pOrg[k + j + 1 - 64];
+                    pOrg[k + j + 6] -= pOrg[k + j + 6 - 64];
+                }
+            }
+        }
+    }
+
+    if(cf == YUV_420){
+        for(i = 1; i < 3; i ++){
+            pOrg = pMBInfo->iBlockDC[i]; // current DC block
+
+            /* DC prediciton */
+            if(iDCPredMode == 1){ // predict DC from top
+                pOrg[0] -= (pSC->PredInfoPrevRow[i] + mbX)->iDC;
+            }
+            else if(iDCPredMode == 0){ // predict DC from left
+                pOrg[0] -= (pSC->PredInfo[i] + mbX - 1)->iDC;
+            }
+            else if(iDCPredMode == 2){ // predict DC from top&left
+                pOrg[0] -= (((pSC->PredInfo[i] + mbX - 1)->iDC + (pSC->PredInfoPrevRow[i] + mbX)->iDC + 1) >> 1);
+            }
+
+            /* AD prediction */
+            if(iADPredMode == 4){// predict AD from top
+                pOrg[2] -= (pSC->PredInfoPrevRow[i] + mbX)->piAD[1];
+            }
+            else if(iADPredMode == 0){// predict AD from left
+                pOrg[1] -= (pSC->PredInfo[i] + mbX - 1)->piAD[0];
+            }
+
+            pOrg = pSC->pPlane[i];
+            /* AC prediction */
+            if(iACPredMode == 1){ // predict from top
+                for(j = 16; j <= 48; j += 32){
+                    /* inside macroblock */
+                    pOrg[j + 10] -= pOrg[j + 10 - 16];
+                    pOrg[j +  2] -= pOrg[j +  2 - 16];
+                    pOrg[j +  9] -= pOrg[j +  9 - 16];
+                }
+            }
+            else if(iACPredMode == 0){ // predict from left
+                for(j = 32; j <= 48; j += 16){
+                    /* inside macroblock */
+                    pOrg[j + 5] -= pOrg[j + 5 - 32];
+                    pOrg[j + 1] -= pOrg[j + 1 - 32];
+                    pOrg[j + 6] -= pOrg[j + 6 - 32];
+                }
+            }
+        }
+    }
+    else if(cf == YUV_422){
+        for(i = 1; i < 3; i ++){
+            pOrg = pMBInfo->iBlockDC[i]; // current DC block
+
+            /* DC prediciton */
+            if(iDCPredMode == 1){ // predict DC from top
+                pOrg[0] -= (pSC->PredInfoPrevRow[i] + mbX)->iDC;
+            }
+            else if(iDCPredMode == 0){ // predict DC from left
+                pOrg[0] -= (pSC->PredInfo[i] + mbX - 1)->iDC;
+            }
+            else if(iDCPredMode == 2){ // predict DC from top&left
+                pOrg[0] -= (((pSC->PredInfo[i] + mbX - 1)->iDC + (pSC->PredInfoPrevRow[i] + mbX)->iDC + 1) >> 1);
+            }
+
+            /* AD prediction */
+            if(iADPredMode == 4){// predict AD from top
+                pOrg[4] -= (pSC->PredInfoPrevRow[i] + mbX)->piAD[4]; // AC of HT !!!
+                pOrg[6] -= pOrg[2];
+                pOrg[2] -= (pSC->PredInfoPrevRow[i] + mbX)->piAD[3];
+            }
+            else if(iADPredMode == 0){// predict AD from left
+                pOrg[4] -= (pSC->PredInfo[i] + mbX - 1)->piAD[4];  // AC of HT !!!
+                pOrg[1] -= (pSC->PredInfo[i] + mbX - 1)->piAD[0];
+                pOrg[5] -= (pSC->PredInfo[i] + mbX - 1)->piAD[2];
+            }
+            else if(iDCPredMode == 1){
+                pOrg[6] -= pOrg[2];
+            }
+
+            pOrg = pSC->pPlane[i]; // current MB
+            /* AC prediction */
+            if(iACPredMode == 1){ // predict from top
+                for(j = 48; j > 0; j -= 16){
+                    for(k = 0; k <= 64; k += 64){
+                        /* inside macroblock */
+                        pOrg[j + k + 10] -= pOrg[j + k + 10 - 16];
+                        pOrg[j + k +  2] -= pOrg[j + k +  2 - 16];
+                        pOrg[j + k +  9] -= pOrg[j + k +  9 - 16];
+                    }
+                }
+            }
+            else if(iACPredMode == 0){ // predict from left
+                for(j = 64; j <= 112; j += 16){
+                    /* inside macroblock */
+                    pOrg[j + 5] -= pOrg[j + 5 - 64];
+                    pOrg[j + 1] -= pOrg[j + 1 - 64];
+                    pOrg[j + 6] -= pOrg[j + 6 - 64];
+                }
+            }
+        }
+    }
+}
+
+
+/* CBP prediction for 16 x 16 MB */
+/* block index */
+/*  0  1  4  5 */
+/*  2  3  6  7 */
+/*  8  9 12 13 */
+/* 10 11 14 15 */
+
+static int NumOnes(int i)
+{
+    int retval = 0;
+    static const int g_Count[] = { 0,1,1,2, 1,2,2,3, 1,2,2,3, 2,3,3,4 };
+    i = i & 0xffff;
+    while (i) {
+        retval += g_Count[i & 0xf];
+        i >>= 4;
+    }
+    return retval;
+}
+
+#define SATURATE32(x) if((unsigned int)(x + 16) >= 32) { if (x < 0) x = -16; else x = 15; }
+
+static Int predCBPCEnc(CWMImageStrCodec *pSC, Int iCBP, size_t mbX, size_t mbY, size_t c, CCBPModel *pModel)
+{
+    Int iPredCBP = 0, iRetval = 0;
+    Int iNOrig = NumOnes(iCBP), iNDiff = AVG_NDIFF;//NumOnes(iPredCBP ^ iCBP);
+
+    UNREFERENCED_PARAMETER( mbY );
+
+    /* only top left block pattern is predicted from neighbour */
+    if(pSC->m_bCtxLeft) {
+        if (pSC->m_bCtxTop) {
+            iPredCBP = 1;
+        }
+        else {
+            Int iTopCBP  = (pSC->PredInfoPrevRow[c] + mbX)->iCBP;
+            iPredCBP = (iTopCBP >> 10) & 1; // left: top(10) => 0
+        }
+    }
+    else {
+        Int iLeftCBP = (pSC->PredInfo[c] + mbX - 1)->iCBP;
+        iPredCBP = ((iLeftCBP >> 5) & 1); // left(5) => 0
+    }
+
+    iPredCBP |= (iCBP & 0x3300) << 2; // [8 9 12 13]->[10 11 14 15]
+    iPredCBP |= (iCBP & 0xcc) << 6; // [2 3 6 7]->[8 9 12 13]
+    iPredCBP |= (iCBP & 0x33) << 2; // [0 1 4 5]->[2 3 6 7]
+    iPredCBP |= (iCBP & 0x11) << 1; // [0 4]->[1 5]
+    iPredCBP |= (iCBP & 0x2) << 3; // [1]->[4]
+
+    if (c) c = 1;
+    if (pModel->m_iState[c] == 0) {
+        iRetval = iPredCBP ^ iCBP;
+    }
+    else if (pModel->m_iState[c] == 1) {
+        iRetval = iCBP;
+    }
+    else {
+        iRetval = iCBP ^ 0xffff;
+    }
+
+    pModel->m_iCount0[c] += iNOrig - iNDiff;
+    SATURATE32(pModel->m_iCount0[c]);
+
+    pModel->m_iCount1[c] += 16 - iNOrig - iNDiff;
+    SATURATE32(pModel->m_iCount1[c]);
+
+    if (pModel->m_iCount0[c] < 0) {
+        if (pModel->m_iCount0[c] < pModel->m_iCount1[c]) {
+            pModel->m_iState[c] = 1;
+        }
+        else {
+            pModel->m_iState[c] = 2;
+        }
+    }
+    else if (pModel->m_iCount1[c] < 0) {
+        pModel->m_iState[c] = 2;
+    }
+    else {
+        pModel->m_iState[c] = 0;
+    }
+    return iRetval;
+}
+
+static Int predCBPC420Enc(CWMImageStrCodec *pSC, Int iCBP, size_t mbX, size_t mbY, size_t c, CCBPModel *pModel)
+{
+    Int iPredCBP = 0, iRetval = 0;
+    Int iNOrig = NumOnes(iCBP) * 4, iNDiff = AVG_NDIFF;//NumOnes(iPredCBP ^ iCBP);
+
+    UNREFERENCED_PARAMETER( mbY );
+
+    /* only top left block pattern is predicted from neighbour */
+    if(pSC->m_bCtxLeft) {
+        if (pSC->m_bCtxTop) {
+            iPredCBP = 1;
+        }
+        else {
+            Int iTopCBP  = (pSC->PredInfoPrevRow[c] + mbX)->iCBP;
+            iPredCBP = (iTopCBP >> 2) & 1; // left: top(2) => 0
+        }
+    }
+    else {
+        Int iLeftCBP = (pSC->PredInfo[c] + mbX - 1)->iCBP;
+        iPredCBP = ((iLeftCBP >> 1) & 1); // left(1) => 0
+    }
+
+    iPredCBP |= (iCBP & 0x1) << 1; // [0]->[1]
+    iPredCBP |= (iCBP & 0x3) << 2; // [0 1]->[2 3]
+
+    if (pModel->m_iState[1] == 0) {
+        iRetval = iPredCBP ^ iCBP;
+    }
+    else if (pModel->m_iState[1] == 1) {
+        iRetval = iCBP;
+    }
+    else {
+        iRetval = iCBP ^ 0xf;
+    }
+
+    pModel->m_iCount0[1] += iNOrig - iNDiff;
+    SATURATE32(pModel->m_iCount0[1]);
+
+    pModel->m_iCount1[1] += 16 - iNOrig - iNDiff;
+    SATURATE32(pModel->m_iCount1[1]);
+
+    if (pModel->m_iCount0[1] < 0) {
+        if (pModel->m_iCount0[1] < pModel->m_iCount1[1]) {
+            pModel->m_iState[1] = 1;
+        }
+        else {
+            pModel->m_iState[1] = 2;
+        }
+    }
+    else if (pModel->m_iCount1[1] < 0) {
+        pModel->m_iState[1] = 2;
+    }
+    else {
+        pModel->m_iState[1] = 0;
+    }
+    return iRetval;
+}
+
+static Int predCBPC422Enc(CWMImageStrCodec *pSC, Int iCBP, size_t mbX, size_t mbY, size_t c, CCBPModel *pModel)
+{
+    Int iPredCBP = 0, iRetval = 0;
+    Int iNOrig = NumOnes(iCBP) * 2, iNDiff = AVG_NDIFF;//NumOnes(iPredCBP ^ iCBP);
+
+    UNREFERENCED_PARAMETER( mbY );
+
+    /* only top left block pattern is predicted from neighbour */
+    if(pSC->m_bCtxLeft) {
+        if (pSC->m_bCtxTop) {
+            iPredCBP = 1;
+        }
+        else {
+            Int iTopCBP  = (pSC->PredInfoPrevRow[c] + mbX)->iCBP;
+            iPredCBP = (iTopCBP >> 6) & 1; // left: top(6) => 0
+        }
+    }
+    else {
+        Int iLeftCBP = (pSC->PredInfo[c] + mbX - 1)->iCBP;
+        iPredCBP = ((iLeftCBP >> 1) & 1); // left(1) => 0
+    }
+
+    iPredCBP |= (iCBP & 0x1) << 1; // [0]->[1]
+    iPredCBP |= (iCBP & 0x3) << 2; // [0 1]->[2 3]
+    iPredCBP |= (iCBP & 0xc) << 2; // [2 3]->[4 5]
+    iPredCBP |= (iCBP & 0x30) << 2; // [4 5]->[6 7]
+
+    if (pModel->m_iState[1] == 0) {
+        iRetval = iPredCBP ^ iCBP;
+    }
+    else if (pModel->m_iState[1] == 1) {
+        iRetval = iCBP;
+    }
+    else {
+        iRetval = iCBP ^ 0xff;
+    }
+
+    pModel->m_iCount0[1] += iNOrig - iNDiff;
+    SATURATE32(pModel->m_iCount0[1]);
+
+    pModel->m_iCount1[1] += 16 - iNOrig - iNDiff;
+    SATURATE32(pModel->m_iCount1[1]);
+
+    if (pModel->m_iCount0[1] < 0) {
+        if (pModel->m_iCount0[1] < pModel->m_iCount1[1]) {
+            pModel->m_iState[1] = 1;
+        }
+        else {
+            pModel->m_iState[1] = 2;
+        }
+    }
+    else if (pModel->m_iCount1[1] < 0) {
+        pModel->m_iState[1] = 2;
+    }
+    else {
+        pModel->m_iState[1] = 0;
+    }
+    return iRetval;
+}
+
+Void predCBPEnc(CWMImageStrCodec* pSC, CCodingContext *pContext)
+{
+    size_t mbX = pSC->cColumn - 1, mbY = pSC->cRow - 1;
+    CWMIMBInfo * pMBInfo = &(pSC->MBInfo);
+    int iChannel, i, j;
+
+    for(iChannel = 0; iChannel < (int)pSC->m_param.cNumChannels; iChannel ++){
+        const COLORFORMAT cf = pSC->m_param.cfColorFormat;
+        const Bool bUV = (iChannel > 0);
+        const int iNumBlock = (bUV ? (cf == YUV_422 ? 8 : (cf == YUV_420 ? 4 : 16)) : 16);
+        const int * pOffset = (iNumBlock == 4 ? blkOffsetUV : (iNumBlock == 8 ? blkOffsetUV_422 : blkOffset));
+        const Int threshold = (1 << pContext->m_aModelAC.m_iFlcBits[bUV ? 1 : 0]) - 1, threshold2 = threshold * 2 + 1;
+        Int iCBP = 0;
+
+        for(j = 0; j < iNumBlock; j ++){
+            PixelI * pData = pSC->pPlane[iChannel] + pOffset[j];
+            for(i = 1; i < 16; i ++){
+                if((unsigned int)(pData[i] + threshold) >= (unsigned int) threshold2){ // significant coeff
+                    iCBP |= (1 << j); // update CBP
+                    break;
+                }
+            }
+        }
+        
+        pMBInfo->iCBP[iChannel] = (pSC->PredInfo[iChannel] + mbX)->iCBP = iCBP;
+
+        if(iNumBlock == 16){
+            pMBInfo->iDiffCBP[iChannel] = predCBPCEnc(pSC, pMBInfo->iCBP[iChannel], mbX, mbY, iChannel, &pContext->m_aCBPModel);
+        }
+        else if(iNumBlock == 8){
+            pSC->MBInfo.iDiffCBP[iChannel] = predCBPC422Enc(pSC, pMBInfo->iCBP[iChannel], mbX, mbY, iChannel, &pContext->m_aCBPModel);
+        }
+        else{
+            pSC->MBInfo.iDiffCBP[iChannel] = predCBPC420Enc(pSC, pMBInfo->iCBP[iChannel], mbX, mbY, iChannel, &pContext->m_aCBPModel);
+        }
+    }
+}
+
diff --git a/Source/LibJXR/image/encode/strenc.c b/Source/LibJXR/image/encode/strenc.c
new file mode 100644
index 0000000..d6e970e
--- /dev/null
+++ b/Source/LibJXR/image/encode/strenc.c
@@ -0,0 +1,2370 @@
+//*@@@+++@@@@******************************************************************
+//
+// Copyright � Microsoft Corp.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+// � Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// � Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//*@@@---@@@@******************************************************************
+#include "strcodec.h"
+#include "encode.h"
+#include "strTransform.h"
+#include <math.h>
+#include "perfTimer.h"
+
+#ifdef MEM_TRACE
+#define TRACE_MALLOC    1
+#define TRACE_NEW       0
+#define TRACE_HEAP      0
+#include "memtrace.h"
+#endif
+
+#ifdef ADI_SYS_OPT
+extern char L1WW[];
+#endif
+
+#ifdef X86OPT_INLINE
+#define _FORCEINLINE __forceinline
+#else // X86OPT_INLINE
+#define _FORCEINLINE
+#endif // X86OPT_INLINE
+
+Int inputMBRow(CWMImageStrCodec *);
+
+#if defined(WMP_OPT_SSE2) || defined(WMP_OPT_CC_ENC) || defined(WMP_OPT_TRFM_ENC)
+void StrEncOpt(CWMImageStrCodec* pSC);
+#endif // OPT defined
+
+#define MINIMUM_PACKET_LENGTH 4  // as long as packet header - skipped if data is not accessed (happens only for flexbits)
+
+Void writeQuantizer(CWMIQuantizer * pQuantizer[MAX_CHANNELS], BitIOInfo * pIO, U8 cChMode, size_t cChannel, size_t iPos)
+{
+    if(cChMode > 2)
+        cChMode = 2;
+
+    if(cChannel > 1)
+        putBit16(pIO, cChMode, 2); // Channel mode
+    else
+        cChMode = 0;
+
+    putBit16(pIO, pQuantizer[0][iPos].iIndex, 8); // Y
+
+    if(cChMode == 1)  // MIXED
+        putBit16(pIO, pQuantizer[1][iPos].iIndex, 8); // UV
+    else if(cChMode > 0){ // INDEPENDENT
+        size_t i;
+
+        for(i = 1; i < cChannel; i ++)
+            putBit16(pIO, pQuantizer[i][iPos].iIndex, 8); // UV
+    }
+}
+
+// packet header: 00000000 00000000 00000001 ?????xxx
+// xxx:           000(spatial) 001(DC) 010(AD) 011(AC) 100(FL) 101-111(reserved)
+// ?????:         (iTileY * cNumOfSliceV + iTileX)
+Void writePacketHeader(BitIOInfo * pIO, U8 ptPacketType, U8 pID)
+{
+    putBit16(pIO, 0, 8);
+    putBit16(pIO, 0, 8);
+    putBit16(pIO, 1, 8);
+    putBit16(pIO, (pID << 3) + (ptPacketType & 7), 8);
+}
+
+Int writeTileHeaderDC(CWMImageStrCodec * pSC, BitIOInfo * pIO)
+{
+    size_t iTile, j = (pSC->m_pNextSC == NULL ? 1U : 2U);
+
+    for(; j > 0; j --){
+        if((pSC->m_param.uQPMode & 1) != 0){ // not DC uniform
+            CWMITile * pTile = pSC->pTile + pSC->cTileColumn;
+            size_t i;
+            
+            pTile->cChModeDC = (U8)(rand() & 3); // channel mode, just for concept proofing!
+            
+            if(pSC->cTileRow + pSC->cTileColumn == 0) // allocate DC QP info
+                for(iTile = 0; iTile <= pSC->WMISCP.cNumOfSliceMinus1V; iTile ++)
+                    if(allocateQuantizer(pSC->pTile[iTile].pQuantizerDC, pSC->m_param.cNumChannels, 1) != ICERR_OK)
+                        return ICERR_ERROR;
+            
+            for(i = 0; i < pSC->m_param.cNumChannels; i ++)
+                pTile->pQuantizerDC[i]->iIndex = (U8)((rand() & 0x2f) + 1); // QP indexes, just for concept proofing!
+            
+            formatQuantizer(pTile->pQuantizerDC, pTile->cChModeDC, pSC->m_param.cNumChannels, 0, TRUE, pSC->m_param.bScaledArith);
+
+            for(i = 0; i < pSC->m_param.cNumChannels; i ++)
+                pTile->pQuantizerDC[i]->iOffset = (pTile->pQuantizerDC[i]->iQP >> 1);
+            
+            writeQuantizer(pTile->pQuantizerDC, pIO, pTile->cChModeDC, pSC->m_param.cNumChannels, 0);
+        }
+
+        pSC = pSC->m_pNextSC;
+    }
+
+    return ICERR_OK;
+}
+
+Int writeTileHeaderLP(CWMImageStrCodec * pSC, BitIOInfo * pIO)
+{
+    size_t k = (pSC->m_pNextSC == NULL ? 1U : 2U);
+    
+    for(; k > 0; k --){
+        if(pSC->WMISCP.sbSubband != SB_DC_ONLY && (pSC->m_param.uQPMode & 2) != 0){ // not LP uniform
+            CWMITile * pTile = pSC->pTile + pSC->cTileColumn;
+            U8 i, j;
+
+            pTile->bUseDC = ((rand() & 1) == 0 ? TRUE : FALSE); // use DC quantizer?
+            putBit16(pIO, pTile->bUseDC == TRUE ? 1 : 0, 1);
+            pTile->cBitsLP = 0;
+            
+            pTile->cNumQPLP = (pTile->bUseDC == TRUE ? 1 : (U8)((rand() & 0xf) + 1)); // # of LP QPs
+            
+            if(pSC->cTileRow > 0)
+                freeQuantizer(pTile->pQuantizerLP);
+            
+            if(allocateQuantizer(pTile->pQuantizerLP, pSC->m_param.cNumChannels, pTile->cNumQPLP) != ICERR_OK)
+                return ICERR_ERROR;
+
+            if(pTile->bUseDC == TRUE)
+                useDCQuantizer(pSC, pSC->cTileColumn);
+            else{
+                putBit16(pIO, pTile->cNumQPLP - 1, 4);
+                
+                pTile->cBitsLP = dquantBits(pTile->cNumQPLP);
+                
+                for(i = 0; i < pTile->cNumQPLP; i ++){
+                    pTile->cChModeLP[i] = (U8)(rand() & 3); // channel mode, just for concept proofing!
+                    
+                    for(j = 0; j < pSC->m_param.cNumChannels; j ++)
+                        pTile->pQuantizerLP[j][i].iIndex = (U8)((rand() & 0xfe) + 1); // QP indexes, just for concept proofing!
+                    formatQuantizer(pTile->pQuantizerLP, pTile->cChModeLP[i], pSC->m_param.cNumChannels, i, TRUE, pSC->m_param.bScaledArith);
+                    writeQuantizer(pTile->pQuantizerLP, pIO, pTile->cChModeLP[i], pSC->m_param.cNumChannels, i);
+                }
+            }
+        }
+        pSC = pSC->m_pNextSC;
+    }
+
+    return ICERR_OK;
+}
+
+Int writeTileHeaderHP(CWMImageStrCodec * pSC, BitIOInfo * pIO)
+{
+    size_t k = (pSC->m_pNextSC == NULL ? 1U : 2U);
+    
+    for(; k > 0; k --){
+        if(pSC->WMISCP.sbSubband != SB_DC_ONLY && pSC->WMISCP.sbSubband != SB_NO_HIGHPASS && (pSC->m_param.uQPMode & 4) != 0){ // not HP uniform
+            CWMITile * pTile = pSC->pTile + pSC->cTileColumn;
+            U8 i, j;
+
+            pTile->bUseLP = ((rand() & 1) == 0 ? TRUE : FALSE); // use LP quantizer?
+            putBit16(pIO, pTile->bUseLP == TRUE ? 1 : 0, 1);
+            pTile->cBitsHP = 0;
+            
+            pTile->cNumQPHP = (pTile->bUseLP == TRUE ? pTile->cNumQPLP : (U8)((rand() & 0xf) + 1)); // # of LP QPs
+            
+            if(pSC->cTileRow > 0)
+                freeQuantizer(pTile->pQuantizerHP);
+            
+            if(allocateQuantizer(pTile->pQuantizerHP, pSC->m_param.cNumChannels, pTile->cNumQPHP) != ICERR_OK)
+                return ICERR_ERROR;
+            
+            if(pTile->bUseLP == TRUE)
+                useLPQuantizer(pSC, pTile->cNumQPHP, pSC->cTileColumn);
+            else{
+                putBit16(pIO, pTile->cNumQPHP - 1, 4);
+                pTile->cBitsHP = dquantBits(pTile->cNumQPHP);
+                
+                for(i = 0; i < pTile->cNumQPHP; i ++){
+                    pTile->cChModeHP[i] = (U8)(rand() & 3); // channel mode, just for concept proofing!
+                    
+                    for(j = 0; j < pSC->m_param.cNumChannels; j ++)
+                        pTile->pQuantizerHP[j][i].iIndex = (U8)((rand() & 0xfe) + 1); // QP indexes, just for concept proofing!
+                    formatQuantizer(pTile->pQuantizerHP, pTile->cChModeHP[i], pSC->m_param.cNumChannels, i, FALSE, pSC->m_param.bScaledArith);
+                    writeQuantizer(pTile->pQuantizerHP, pIO, pTile->cChModeHP[i], pSC->m_param.cNumChannels, i);
+                }
+            }
+        }
+        pSC = pSC->m_pNextSC;
+    }
+
+    return ICERR_OK;
+}
+
+Int encodeMB(CWMImageStrCodec * pSC, Int iMBX, Int iMBY)
+{
+    CCodingContext * pContext = &pSC->m_pCodingContext[pSC->cTileColumn];
+    
+    if(pSC->m_bCtxLeft && pSC->m_bCtxTop && pSC->m_bSecondary == FALSE && pSC->m_param.bTranscode == FALSE){ // write packet headers
+        U8 pID = (U8)((pSC->cTileRow * (pSC->WMISCP.cNumOfSliceMinus1V + 1) + pSC->cTileColumn) & 0x1F);
+        
+        if(pSC->WMISCP.bfBitstreamFormat == SPATIAL) {
+            writePacketHeader(pContext->m_pIODC, 0, pID);
+            if (pSC->m_param.bTrimFlexbitsFlag)
+                putBit16(pContext->m_pIODC, pContext->m_iTrimFlexBits, 4);
+            writeTileHeaderDC(pSC, pContext->m_pIODC);
+            writeTileHeaderLP(pSC, pContext->m_pIODC);
+            writeTileHeaderHP(pSC, pContext->m_pIODC);
+        }
+        else{
+            writePacketHeader(pContext->m_pIODC, 1, pID);
+            writeTileHeaderDC(pSC, pContext->m_pIODC);
+            if(pSC->cSB > 1){
+                writePacketHeader(pContext->m_pIOLP, 2, pID);
+                writeTileHeaderLP(pSC, pContext->m_pIOLP);
+            }
+            if(pSC->cSB > 2){
+                writePacketHeader(pContext->m_pIOAC, 3, pID);
+                writeTileHeaderHP(pSC, pContext->m_pIOAC);
+            }
+            if(pSC->cSB > 3) {
+                writePacketHeader(pContext->m_pIOFL, 4, pID);
+                if (pSC->m_param.bTrimFlexbitsFlag)
+                    putBit16(pContext->m_pIOFL, pContext->m_iTrimFlexBits, 4);
+            }
+        }
+    }
+    
+    if(EncodeMacroblockDC(pSC, pContext, iMBX, iMBY) != ICERR_OK)
+        return ICERR_ERROR;
+    
+    if(pSC->WMISCP.sbSubband != SB_DC_ONLY)
+        if(EncodeMacroblockLowpass(pSC, pContext, iMBX, iMBY) != ICERR_OK)
+            return ICERR_ERROR;
+
+    if(pSC->WMISCP.sbSubband != SB_DC_ONLY && pSC->WMISCP.sbSubband != SB_NO_HIGHPASS)
+        if(EncodeMacroblockHighpass(pSC, pContext, iMBX, iMBY) != ICERR_OK)
+            return ICERR_ERROR;
+    
+    if(iMBX + 1 == (int) pSC->cmbWidth && (iMBY + 1 == (int) pSC->cmbHeight || 
+        (pSC->cTileRow < pSC->WMISCP.cNumOfSliceMinus1H && iMBY == (int) pSC->WMISCP.uiTileY[pSC->cTileRow + 1] - 1)))
+    { // end of a horizontal slice
+        size_t k, l;
+
+        // get sizes of each packet and update index table
+        if (pSC->m_pNextSC == NULL || pSC->m_bSecondary) {
+            for(k = 0; k < pSC->cNumBitIO; k ++){
+                fillToByte(pSC->m_ppBitIO[k]);
+                pSC->ppWStream[k]->GetPos(pSC->ppWStream[k], &l);
+                pSC->pIndexTable[pSC->cNumBitIO * pSC->cTileRow + k] = l + getSizeWrite(pSC->m_ppBitIO[k]); // offset
+            }
+        }
+        
+        // reset coding contexts
+        if(iMBY + 1 != (int) pSC->cmbHeight){
+            for(k = 0; k <= pSC->WMISCP.cNumOfSliceMinus1V; k ++)
+                ResetCodingContextEnc(&pSC->m_pCodingContext[k]);
+        }
+    }
+
+    return ICERR_OK;
+}
+
+/*************************************************************************
+    Top level function for processing a macroblock worth of input
+*************************************************************************/
+Int processMacroblock(CWMImageStrCodec *pSC)
+{
+    Bool topORleft = (pSC->cColumn == 0 || pSC->cRow == 0);
+    ERR_CODE result = ICERR_OK;
+    size_t j, jend = (pSC->m_pNextSC != NULL);
+
+    for (j = 0; j <= jend; j++) {
+        transformMacroblock(pSC);
+        if(!topORleft){
+            getTilePos(pSC, (Int)pSC->cColumn - 1, (Int)pSC->cRow - 1);
+            if(jend){
+                pSC->m_pNextSC->cTileRow = pSC->cTileRow;
+                pSC->m_pNextSC->cTileColumn = pSC->cTileColumn;
+            }
+            if ((result = encodeMB(pSC, (Int)pSC->cColumn - 1, (Int)pSC->cRow - 1)) != ICERR_OK)
+                return result;
+        }
+
+        if (jend) {
+            pSC->m_pNextSC->cRow = pSC->cRow;
+            pSC->m_pNextSC->cColumn = pSC->cColumn;
+            pSC = pSC->m_pNextSC;
+        }
+    }
+
+    return ICERR_OK;
+}
+
+/*************************************************************************
+  forwardRGBE: forward conversion from RGBE to RGB
+*************************************************************************/
+static _FORCEINLINE PixelI forwardRGBE (PixelI RGB, PixelI E)
+{
+    PixelI iResult = 0, iAppend = 1;
+
+    if (E == 0)
+        return 0;
+
+    assert (E!=0);
+
+    E--;
+    while (((RGB & 0x80) == 0) && (E > 0)) {
+        RGB = (RGB << 1) + iAppend;
+        iAppend = 0;
+        E--;    
+    }
+
+    // result will always be one of 3 cases
+    // E  RGB       convert to
+    // 0  [0.x]      [0   x]
+    // 0  [1.x]      [1   x]
+    // e  [1.x]      [e+1 x]
+    if (E == 0) {
+        iResult = RGB;
+    }
+    else {
+        E++;
+        iResult = (RGB & 0x7f) + (E << 7);
+    }
+
+    return iResult;
+}
+
+/*************************************************************************
+  convert float-32 into float with (c, lm)!!
+*************************************************************************/
+static _FORCEINLINE PixelI float2pixel (float f, const char _c, const unsigned char _lm)
+{
+    union uif
+    {
+        I32   i;
+        float f;
+    } x;
+
+    PixelI _h, e, e1, m, s;
+
+    if (f == 0)
+    {
+        _h = 0;
+    }
+    else
+    {
+        x.f = f;
+
+        e = (x.i >> 23) & 0x000000ff;//here set e as e, not s! e includes s: [s e] 9 bits [31..23]
+        m = (x.i & 0x007fffff) | 0x800000; // actual mantissa, with normalizer
+        if (e == 0) { // denormal-land
+            m ^= 0x800000;  // actual mantissa, removing normalizer
+            e++; // actual exponent -126
+        }
+
+        e1 = e - 127 + _c;  // this is basically a division or quantization to a different exponent
+                            // note: _c cannot be greater than 127, so e1 cannot be greater than e
+        //assert (_c <= 127);
+        if (e1 <= 1) {  // denormal-land
+            if (e1 < 1)
+                m >>= (1 - e1);  // shift mantissa right to make exponent 1
+            e1 = 1;
+            if ((m & 0x800000) == 0) // if denormal, set e1 to zero else to 1
+                e1 = 0;
+        }
+        m &= 0x007fffff;
+
+        //for float-22:	    
+        _h = (e1 << _lm) + ((m + (1 << (23 - _lm - 1))) >> (23 - _lm));//take 23-bit m, shift (23-lm), get lm-bit m for float22
+        s = ((PixelI) x.i) >> 31;
+        //padding to int-32: 
+        _h = (_h ^ s) - s;	
+    }
+
+    return _h;
+}
+
+/*************************************************************************
+  convert Half-16 to internal format, only need to handle sign bit
+*************************************************************************/
+static _FORCEINLINE PixelI forwardHalf (PixelI hHalf)
+{
+    PixelI s;
+    s = hHalf >> 31;
+    hHalf = ((hHalf & 0x7fff) ^ s) - s;
+    return hHalf;
+}
+
+
+//================================================================
+// Color Conversion 
+// functions to get image data from input buffer
+// this inlcudes necessary color conversion and boundary padding
+//================================================================
+#define _CC(r, g, b) (b -= r, r += ((b + 1) >> 1) - g, g += ((r + 0) >> 1))
+#define _CC_CMYK(c, m, y, k) (y -= c, c += ((y + 1) >> 1) - m, m += (c >> 1) - k, k += ((m + 1) >> 1))
+
+//================================================================
+// BitIOInfo init/term for encoding
+const size_t MAX_MEMORY_SIZE_IN_WORDS = 64 << 20; // 1 << 20 \approx 1 million
+
+Int StrIOEncInit(CWMImageStrCodec* pSC)
+{
+    pSC->m_param.bIndexTable = !(pSC->WMISCP.bfBitstreamFormat == SPATIAL && pSC->WMISCP.cNumOfSliceMinus1H + pSC->WMISCP.cNumOfSliceMinus1V == 0);
+    if(allocateBitIOInfo(pSC) != ICERR_OK){
+        return ICERR_ERROR;
+    }
+
+    attachISWrite(pSC->pIOHeader, pSC->WMISCP.pWStream);
+
+    if(pSC->cNumBitIO > 0){
+        size_t i;
+#if defined(_WINDOWS_) || defined(UNDER_CE)  // tmpnam does not exist in VS2005 WinCE CRT
+        TCHAR szPath[MAX_PATH];
+        DWORD cSize, j, k;
+#endif
+        char * pFilename;
+
+        pSC->ppWStream = (struct WMPStream **)malloc(pSC->cNumBitIO * sizeof(struct WMPStream *));
+        if(pSC->ppWStream == NULL) return ICERR_ERROR;
+        memset(pSC->ppWStream, 0, pSC->cNumBitIO * sizeof(struct WMPStream *));
+
+        if (pSC->cmbHeight * pSC->cmbWidth * pSC->WMISCP.cChannel >= MAX_MEMORY_SIZE_IN_WORDS) {
+#ifdef _WINDOWS_
+            pSC->ppTempFile = (TCHAR **)malloc(pSC->cNumBitIO * sizeof(TCHAR *));
+            if(pSC->ppTempFile == NULL) return ICERR_ERROR;
+            memset(pSC->ppTempFile, 0, pSC->cNumBitIO * sizeof(TCHAR *)); 
+#else
+            pSC->ppTempFile = (char **)malloc(pSC->cNumBitIO * sizeof(char *));
+            if(pSC->ppTempFile == NULL) return ICERR_ERROR;
+            memset(pSC->ppTempFile, 0, pSC->cNumBitIO * sizeof(char *));
+#endif
+        }
+
+        for(i = 0; i < pSC->cNumBitIO; i ++){
+            if (pSC->cmbHeight * pSC->cmbWidth * pSC->WMISCP.cChannel >= MAX_MEMORY_SIZE_IN_WORDS) {
+#if defined(_WINDOWS_) || defined(UNDER_CE)  // tmpnam does not exist in VS2005 WinCE CRT              
+                Bool bUnicode = sizeof(TCHAR) == 2;
+                pSC->ppTempFile[i] = (TCHAR *)malloc(MAX_PATH * sizeof(TCHAR));
+                if(pSC->ppTempFile[i] == NULL) return ICERR_ERROR;
+
+                pFilename = (char *)pSC->ppTempFile[i];
+
+                cSize = GetTempPath(MAX_PATH, szPath);
+                if(cSize == 0 || cSize >= MAX_PATH)
+                    return ICERR_ERROR;
+                if(!GetTempFileName(szPath, TEXT("wdp"), 0, pSC->ppTempFile[i]))
+                    return ICERR_ERROR;
+
+                if(bUnicode){ // unicode file name
+                    for(k = j = cSize = 0; cSize < MAX_PATH; cSize ++, j += 2){
+                        if(pSC->ppTempFile[i][cSize] == '\0')
+                            break;
+                        if(pFilename[j] != '\0')
+                            pFilename[k ++] = pFilename[j];
+                        if(pFilename[j + 1] != '\0')
+                            pFilename[k ++] = pFilename[j + 1];
+                    }
+                    pFilename[cSize] = '\0';
+                }
+
+#else //DPK needs to support ANSI 
+                pSC->ppTempFile[i] = (char *)malloc(FILENAME_MAX * sizeof(char));
+                if(pSC->ppTempFile[i] == NULL) return ICERR_ERROR;
+
+                if ((pFilename = tmpnam(NULL)) == NULL)
+                    return ICERR_ERROR;                
+                strcpy(pSC->ppTempFile[i], pFilename);
+#endif
+                if(CreateWS_File(pSC->ppWStream + i, pFilename, "w+b") != ICERR_OK) return ICERR_ERROR;                
+
+            }
+            else {
+                if(CreateWS_List(pSC->ppWStream + i) != ICERR_OK) return ICERR_ERROR;
+            }
+            attachISWrite(pSC->m_ppBitIO[i], pSC->ppWStream[i]);
+        }
+    }
+
+    return ICERR_OK;
+}
+
+#define PUTBITS putBit16
+/*************************************************************************
+    Write variable length byte aligned integer
+*************************************************************************/
+static Void PutVLWordEsc(BitIOInfo* pIO, Int iEscape, size_t s)
+{
+    if (iEscape) {
+        assert(iEscape <= 0xff && iEscape > 0xfc); // fd,fe,ff are the only valid escapes
+        PUTBITS(pIO, iEscape, 8);
+    }
+    else if (s < 0xfb00) {
+        PUTBITS(pIO, (U32) s, 16);
+    }
+    else {
+        size_t t = s >> 16;
+        if ((t >> 16) == 0) {
+            PUTBITS(pIO, 0xfb, 8);
+        }
+        else {
+            t >>= 16;
+            PUTBITS(pIO, 0xfc, 8);
+            PUTBITS(pIO, (U32)(t >> 16) & 0xffff, 16);
+            PUTBITS(pIO, (U32) t & 0xffff, 16);
+        }
+        PUTBITS(pIO, (U32) t & 0xffff, 16);
+        PUTBITS(pIO, (U32) s & 0xffff, 16);
+    }
+}
+
+/*************************************************************************
+    Write index table at start (null index table)
+*************************************************************************/
+Int writeIndexTableNull(CWMImageStrCodec * pSC)
+{
+    if(pSC->cNumBitIO == 0){
+        BitIOInfo* pIO = pSC->pIOHeader;
+        fillToByte(pIO);
+
+        /* Profile / Level info */
+        PutVLWordEsc(pIO, 0, 4);    // 4 bytes
+        PUTBITS(pIO, 111, 8);       // default profile idc
+        PUTBITS(pIO, 255, 8);       // default level idc
+        PUTBITS(pIO, 1, 16);        // LAST_FLAG
+    }
+
+    return ICERR_OK;
+}
+
+/*************************************************************************
+    Write index table
+*************************************************************************/
+Int writeIndexTable(CWMImageStrCodec * pSC)
+{
+    if(pSC->cNumBitIO > 0){
+        BitIOInfo* pIO = pSC->pIOHeader;
+        size_t *pTable = pSC->pIndexTable, iSize[4] = { 0 };
+        I32 iEntry = (I32)pSC->cNumBitIO * (pSC->WMISCP.cNumOfSliceMinus1H + 1), i, k, l;
+        
+        // write index table header [0x0001] - 2 bytes
+        PUTBITS(pIO, 1, 16);
+
+        for(i = pSC->WMISCP.cNumOfSliceMinus1H; i>= 0 && pSC->bTileExtraction == FALSE; i --){
+            for(k = 0; k < (int)pSC->cNumBitIO; ){
+                for(l = 0; l < (pSC->WMISCP.bfBitstreamFormat == FREQUENCY && pSC->WMISCP.bProgressiveMode ? pSC->cSB : 1); l ++, k ++)
+                {
+                if (i > 0)
+                pTable[pSC->cNumBitIO * i + k] -= pSC->pIndexTable[pSC->cNumBitIO * (i - 1) + k]; // packet length
+                iSize[l] += pTable[pSC->cNumBitIO * i + k];
+                }
+            }
+        }
+
+        iSize[3] = iSize[2] + iSize[1] + iSize[0];
+        iSize[2] = iSize[1] + iSize[0];
+        iSize[1] = iSize[0];
+        iSize[0] = 0;
+
+        for(i = 0; i < iEntry; ){
+        for(l = 0; l < (pSC->WMISCP.bfBitstreamFormat == FREQUENCY && pSC->WMISCP.bProgressiveMode ? pSC->cSB : 1); l ++, i ++)
+        {
+            writeIS_L1(pSC, pIO);
+            PutVLWordEsc(pIO, (pTable[i] <= MINIMUM_PACKET_LENGTH) ? 0xff : 0, iSize[l]);
+            iSize[l] += (pTable[i] <= MINIMUM_PACKET_LENGTH) ? 0 : pTable[i];
+        }
+        }
+
+        writeIS_L1(pSC, pIO);
+        PutVLWordEsc(pIO, 0xff, 0); // escape to end
+        fillToByte(pIO);
+    }
+
+    return ICERR_OK;
+}
+
+Int copyTo(struct WMPStream * pSrc, struct WMPStream * pDst, size_t iBytes)
+{
+    char pData[PACKETLENGTH];
+
+    if (iBytes <= MINIMUM_PACKET_LENGTH){
+        pSrc->Read(pSrc, pData, iBytes);
+        return ICERR_OK;
+    }
+
+    while(iBytes > PACKETLENGTH){
+        pSrc->Read(pSrc, pData, PACKETLENGTH);
+        pDst->Write(pDst, pData, PACKETLENGTH);
+        iBytes -= PACKETLENGTH;
+    }
+    pSrc->Read(pSrc, pData, iBytes);
+    pDst->Write(pDst, pData, iBytes);
+
+    return ICERR_OK;
+}
+
+Int StrIOEncTerm(CWMImageStrCodec* pSC)
+{
+    BitIOInfo * pIO = pSC->pIOHeader;
+
+    fillToByte(pIO);
+
+    if(pSC->WMISCP.bVerbose){
+        U32 i, j;
+
+        printf("\n%d horizontal tiles:\n", pSC->WMISCP.cNumOfSliceMinus1H + 1);
+        for(i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1H; i ++){
+            printf("    offset of tile %d in MBs: %d\n", i, pSC->WMISCP.uiTileY[i]);
+        }
+
+        printf("\n%d vertical tiles:\n", pSC->WMISCP.cNumOfSliceMinus1V + 1);
+        for(i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1V; i ++){
+            printf("    offset of tile %d in MBs: %d\n", i, pSC->WMISCP.uiTileX[i]);
+        }
+
+        if(pSC->WMISCP.bfBitstreamFormat == SPATIAL){
+            printf("\nSpatial order bitstream\n");
+        }
+        else{
+            printf("\nFrequency order bitstream\n");
+        }
+
+        if(!pSC->m_param.bIndexTable){
+            printf("\nstreaming mode, no index table.\n");
+        }
+        else if(pSC->WMISCP.bfBitstreamFormat == SPATIAL){
+            for(j = 0; j <= pSC->WMISCP.cNumOfSliceMinus1H; j ++){
+                for(i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1V; i ++){
+                    printf("bitstream size for tile (%d, %d): %d.\n", j, i, (int) pSC->pIndexTable[j * (pSC->WMISCP.cNumOfSliceMinus1V + 1) + i]);
+                }
+            }
+        }
+        else{
+            for(j = 0; j <= pSC->WMISCP.cNumOfSliceMinus1H; j ++){
+                for(i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1V; i ++){
+                    size_t * p = &pSC->pIndexTable[(j * (pSC->WMISCP.cNumOfSliceMinus1V + 1) + i) * 4];
+                    printf("bitstream size of (DC, LP, AC, FL) for tile (%d, %d): %d %d %d %d.\n", j, i,
+                        (int) p[0], (int) p[1], (int) p[2], (int) p[3]);
+                }
+            }
+        }
+    }
+    
+    writeIndexTable(pSC); // write index table to the header
+
+    detachISWrite(pSC, pIO);
+
+    if(pSC->cNumBitIO > 0){
+        size_t i, j, k, l;
+        struct WMPStream * pDst = pSC->WMISCP.pWStream;
+        size_t * pTable = pSC->pIndexTable;
+
+        for(i = 0; i < pSC->cNumBitIO; i ++){
+            detachISWrite(pSC, pSC->m_ppBitIO[i]);
+        }
+
+        for(i = 0; i < pSC->cNumBitIO; i ++){
+            pSC->ppWStream[i]->SetPos(pSC->ppWStream[i], 0); // seek back for read
+        }
+
+        for(l = 0; l < (size_t)(pSC->WMISCP.bfBitstreamFormat == FREQUENCY && pSC->WMISCP.bProgressiveMode ? pSC->cSB : 1); l ++){
+			for(i = 0, k = l; i <= pSC->WMISCP.cNumOfSliceMinus1H; i ++){ // loop through tiles
+				for(j = 0; j <= pSC->WMISCP.cNumOfSliceMinus1V; j ++){
+
+					if(pSC->WMISCP.bfBitstreamFormat == SPATIAL)
+						copyTo(pSC->ppWStream[j], pDst, pTable[k ++]);
+					else if (!pSC->WMISCP.bProgressiveMode){
+						copyTo(pSC->ppWStream[j * pSC->cSB + 0], pDst, pTable[k ++]);
+						if(pSC->cSB > 1)
+							copyTo(pSC->ppWStream[j * pSC->cSB + 1], pDst, pTable[k ++]);
+						if(pSC->cSB > 2)
+							copyTo(pSC->ppWStream[j * pSC->cSB + 2], pDst, pTable[k ++]);
+						if(pSC->cSB > 3)
+							copyTo(pSC->ppWStream[j * pSC->cSB + 3], pDst, pTable[k ++]);
+					}
+					else{
+						copyTo(pSC->ppWStream[j * pSC->cSB + l], pDst, pTable[k]);
+						k += pSC->cSB;
+					}
+				}
+			}
+        }
+
+        if (pSC->cmbHeight * pSC->cmbWidth * pSC->WMISCP.cChannel >= MAX_MEMORY_SIZE_IN_WORDS){           
+            for(i = 0; i < pSC->cNumBitIO; i ++){
+                if(pSC->ppWStream && pSC->ppWStream[i]){
+                    if((*(pSC->ppWStream + i))->state.file.pFile){
+                        fclose((*(pSC->ppWStream + i))->state.file.pFile);
+#ifdef _WINDOWS_
+                        if(DeleteFileA((LPCSTR)pSC->ppTempFile[i]) == 0)
+                            return ICERR_ERROR;
+#else
+                        if (remove(pSC->ppTempFile[i]) == -1)
+                            return ICERR_ERROR;
+#endif
+                    }
+
+                    if (*(pSC->ppWStream + i))
+                        free(*(pSC->ppWStream + i));
+                }
+                if(pSC->ppTempFile){
+                    if(pSC->ppTempFile[i])
+                        free(pSC->ppTempFile[i]);
+                }
+            }
+
+            if(pSC->ppTempFile)
+                free(pSC->ppTempFile);
+        }
+        else{
+            for(i = 0; i < pSC->cNumBitIO; i ++){
+                if(pSC->ppWStream && pSC->ppWStream[i])
+                    pSC->ppWStream[i]->Close(pSC->ppWStream + i);
+            }
+        }
+
+        free(pSC->ppWStream);
+
+        free(pSC->m_ppBitIO);
+        free(pSC->pIndexTable);
+    }
+
+    return 0;
+}
+
+/*************************************************************************
+    Write header of image plane
+*************************************************************************/
+Int WriteImagePlaneHeader(CWMImageStrCodec * pSC)
+{
+    CWMImageInfo * pII = &pSC->WMII;
+    CWMIStrCodecParam * pSCP = &pSC->WMISCP;
+    BitIOInfo* pIO = pSC->pIOHeader;
+
+    PUTBITS(pIO, (Int) pSC->m_param.cfColorFormat, 3); // internal color format
+    PUTBITS(pIO, (Int) pSC->m_param.bScaledArith, 1); // lossless mode
+
+// subbands
+    PUTBITS(pIO, (U32)pSCP->sbSubband, 4);
+
+// color parameters
+    switch (pSC->m_param.cfColorFormat) {
+        case YUV_420:
+        case YUV_422:
+        case YUV_444:
+            PUTBITS(pIO, 0, 4);
+            PUTBITS(pIO, 0, 4);
+            break;
+        case NCOMPONENT:
+            PUTBITS(pIO, (Int) pSC->m_param.cNumChannels - 1, 4);
+            PUTBITS(pIO, 0, 4);
+            break;
+        default:
+            break;
+    }
+
+// float and 32s additional parameters
+    switch (pII->bdBitDepth) {
+        case BD_16:
+        case BD_16S:
+            PUTBITS(pIO, pSCP->nLenMantissaOrShift, 8);
+            break;
+        case BD_32:
+        case BD_32S:
+            if(pSCP->nLenMantissaOrShift == 0)
+                pSCP->nLenMantissaOrShift = 10;//default
+            PUTBITS(pIO, pSCP->nLenMantissaOrShift, 8);
+            break;
+        case BD_32F:
+            if(pSCP->nLenMantissaOrShift == 0)
+                pSCP->nLenMantissaOrShift = 13;//default
+            PUTBITS(pIO, pSCP->nLenMantissaOrShift, 8);//float conversion parameters
+            PUTBITS(pIO, pSCP->nExpBias, 8);
+            break;
+        default:
+            break;
+    }
+
+        // quantization
+    PUTBITS(pIO, (pSC->m_param.uQPMode & 1) == 1 ? 0 : 1, 1); // DC frame uniform quantization?
+    if((pSC->m_param.uQPMode & 1) == 0)
+        writeQuantizer(pSC->pTile[0].pQuantizerDC, pIO, (pSC->m_param.uQPMode >> 3) & 3, pSC->m_param.cNumChannels, 0);
+    if(pSC->WMISCP.sbSubband != SB_DC_ONLY){
+        PUTBITS(pIO, (pSC->m_param.uQPMode & 0x200) == 0 ? 1 : 0, 1); // use DC quantization?
+        if((pSC->m_param.uQPMode & 0x200) != 0){
+            PUTBITS(pIO, (pSC->m_param.uQPMode & 2) == 2 ? 0 : 1, 1); // LP frame uniform quantization?
+            if((pSC->m_param.uQPMode & 2) == 0)
+                writeQuantizer(pSC->pTile[0].pQuantizerLP, pIO, (pSC->m_param.uQPMode >> 5) & 3,  pSC->m_param.cNumChannels, 0);
+        }
+
+        if(pSC->WMISCP.sbSubband != SB_NO_HIGHPASS){
+            PUTBITS(pIO, (pSC->m_param.uQPMode & 0x400) == 0 ? 1 : 0, 1); // use LP quantization?
+            if((pSC->m_param.uQPMode & 0x400) != 0){
+                PUTBITS(pIO, (pSC->m_param.uQPMode & 4) == 4 ? 0 : 1, 1); // HP frame uniform quantization?
+                if((pSC->m_param.uQPMode & 4) == 0)
+                    writeQuantizer(pSC->pTile[0].pQuantizerHP, pIO, (pSC->m_param.uQPMode >> 7) & 3,  pSC->m_param.cNumChannels, 0);
+            }
+        }
+    }
+
+    fillToByte(pIO);  // remove this later
+    return ICERR_OK;
+}
+
+/*************************************************************************
+    Write header to buffer
+*************************************************************************/
+Int WriteWMIHeader(CWMImageStrCodec * pSC)
+{
+    CWMImageInfo * pII = &pSC->WMII;
+    CWMIStrCodecParam * pSCP = &pSC->WMISCP;
+    CCoreParameters * pCoreParam = &pSC->m_param;
+    BitIOInfo* pIO = pSC->pIOHeader;
+    U32 /*iSizeOfSize = 2,*/ i;
+    // temporary assignments / reserved words
+    // const Int HEADERSIZE = 0;
+    Bool bInscribed = FALSE;
+    Bool bAbbreviatedHeader = (((pII->cWidth + 15) / 16 > 255 || (pII->cHeight + 15) / 16 > 255) ? FALSE : TRUE);
+
+    if(pCoreParam->bTranscode == FALSE)
+        pCoreParam->cExtraPixelsTop = pCoreParam->cExtraPixelsLeft = pCoreParam->cExtraPixelsRight = pCoreParam->cExtraPixelsBottom = 0;
+
+    // num of extra boundary pixels due to compressed domain processing
+    bInscribed = (pCoreParam->cExtraPixelsTop || pCoreParam->cExtraPixelsLeft || pCoreParam->cExtraPixelsBottom || pCoreParam->cExtraPixelsRight);
+
+// 0
+    /** signature **/
+    for (i = 0; i < 8; PUTBITS(pSC->pIOHeader, gGDISignature[i++], 8));
+
+// 8
+    /** codec version and subversion **/
+    PUTBITS(pIO, CODEC_VERSION, 4);  // this should be changed to "profile" in RTM
+    if (pSC->WMISCP.bUseHardTileBoundaries)
+        PUTBITS(pIO, CODEC_SUBVERSION_NEWSCALING_HARD_TILES, 4);
+    else
+        PUTBITS(pIO, CODEC_SUBVERSION_NEWSCALING_SOFT_TILES, 4);
+
+// 9 primary parameters
+    PUTBITS(pIO, (pSCP->cNumOfSliceMinus1V || pSCP->cNumOfSliceMinus1H) ? 1 : 0, 1); // tiling present
+    PUTBITS(pIO, (Int) pSCP->bfBitstreamFormat, 1); // bitstream layout
+    PUTBITS(pIO, pII->oOrientation, 3);        // m_iRotateFlip
+    PUTBITS(pIO, pSC->m_param.bIndexTable, 1); // index table present
+    PUTBITS(pIO, pSCP->olOverlap, 2); // overlap
+
+// 10
+    PUTBITS(pIO, bAbbreviatedHeader, 1); // short words for size and tiles
+    PUTBITS(pIO, 1, 1); // long word length (use intelligence later)
+    PUTBITS(pIO, bInscribed, 1); // windowing
+    PUTBITS(pIO, pSC->m_param.bTrimFlexbitsFlag, 1); // trim flexbits flag sent
+    PUTBITS(pIO, 0, 1); // tile stretching parameters (not enabled)
+    PUTBITS(pIO, 0, 2); // reserved bits
+    PUTBITS(pIO, (Int) pSC->m_param.bAlphaChannel, 1); // alpha channel present
+
+// 11 - informational
+    PUTBITS(pIO, (Int) pII->cfColorFormat, 4); // source color format
+    if(BD_1 == pII->bdBitDepth && pSCP->bBlackWhite)
+        PUTBITS(pIO, (Int) BD_1alt, 4); // source bit depth
+    else 
+        PUTBITS(pIO, (Int) pII->bdBitDepth, 4); // source bit depth
+
+// 12 - Variable length fields
+// size
+    putBit32(pIO, (U32)(pII->cWidth - 1), bAbbreviatedHeader ? 16 : 32);
+    putBit32(pIO, (U32)(pII->cHeight - 1), bAbbreviatedHeader ? 16 : 32);
+
+// tiling
+    if (pSCP->cNumOfSliceMinus1V || pSCP->cNumOfSliceMinus1H) {
+        PUTBITS(pIO, pSCP->cNumOfSliceMinus1V, LOG_MAX_TILES); // # of vertical slices
+        PUTBITS(pIO, pSCP->cNumOfSliceMinus1H, LOG_MAX_TILES); // # of horizontal slices
+    }
+
+// tile sizes
+    for(i = 0; i < pSCP->cNumOfSliceMinus1V; i ++){ // width in MB of vertical slices, not needed for last slice!
+        PUTBITS(pIO, pSCP->uiTileX[i + 1] - pSCP->uiTileX[i], bAbbreviatedHeader ? 8 : 16);
+    }
+    for(i = 0; i < pSCP->cNumOfSliceMinus1H; i ++){ // width in MB of horizontal slices, not needed for last slice!
+        PUTBITS(pIO, pSCP->uiTileY[i + 1] - pSCP->uiTileY[i], bAbbreviatedHeader ? 8 : 16);
+    }
+
+// window due to compressed domain processing
+    if (bInscribed) {
+        PUTBITS(pIO, (U32)pCoreParam->cExtraPixelsTop, 6);
+        PUTBITS(pIO, (U32)pCoreParam->cExtraPixelsLeft, 6);
+        PUTBITS(pIO, (U32)pCoreParam->cExtraPixelsBottom, 6);
+        PUTBITS(pIO, (U32)pCoreParam->cExtraPixelsRight, 6);
+    }    
+    fillToByte(pIO);  // redundant
+
+    // write image plane headers
+    WriteImagePlaneHeader(pSC);
+
+    return ICERR_OK;
+}
+
+// streaming codec init/term
+Int StrEncInit(CWMImageStrCodec* pSC)
+{
+    COLORFORMAT cf = pSC->m_param.cfColorFormat;
+    COLORFORMAT cfE = pSC->WMII.cfColorFormat;
+    U16 iQPIndexY = 0, iQPIndexYLP = 0, iQPIndexYHP = 0;
+	U16 iQPIndexU = 0, iQPIndexULP = 0, iQPIndexUHP = 0;
+    U16 iQPIndexV = 0, iQPIndexVLP = 0, iQPIndexVHP = 0; 
+    size_t i;
+    Bool b32bit = sizeof(size_t) == 4;
+
+    /** color transcoding with resolution change **/
+    pSC->m_bUVResolutionChange = (((cfE == CF_RGB || cfE == YUV_444 || cfE == CMYK || cfE == CF_RGBE) && 
+								   (cf == YUV_422 || cf == YUV_420))
+								  || (cfE == YUV_422 && cf == YUV_420)) && !pSC->WMISCP.bYUVData;
+
+    if(pSC->m_bUVResolutionChange){
+        size_t cSize = ((cfE == YUV_422 ? 128 : 256) + (cf == YUV_420 ? 32 : 0)) * pSC->cmbWidth + 256;
+
+        if(b32bit){ // integer overlow/underflow check for 32-bit system
+            if(((pSC->cmbWidth >> 16) * ((cfE == YUV_422 ? 128 : 256) + (cf == YUV_420 ? 32 : 0))) & 0xffff0000)
+                return ICERR_ERROR;
+            if(cSize >= 0x3fffffff)
+                return ICERR_ERROR;
+        }
+        pSC->pResU = (PixelI *)malloc(cSize * sizeof(PixelI));
+        pSC->pResV = (PixelI *)malloc(cSize * sizeof(PixelI));
+        if(pSC->pResU == NULL || pSC->pResV == NULL){
+            return ICERR_ERROR;
+        }
+    }
+
+    pSC->cTileColumn = pSC->cTileRow = 0;
+
+    if(allocateTileInfo(pSC) != ICERR_OK)
+        return ICERR_ERROR;
+
+    if(pSC->m_param.bTranscode == FALSE){
+        pSC->m_param.uQPMode = 0x150;   // 101010 000
+                                        // 000    == uniform (not per tile) DC, LP, HP
+                                        // 101010 == cChMode == 2 == independent (not same) DC, LP, HP
+
+        /** lossless or Y component lossless condition: all subbands present, uniform quantization with QPIndex 1 **/
+        pSC->m_param.bScaledArith = !((pSC->m_param.uQPMode & 7) == 0 && 
+									  1 == pSC->WMISCP.uiDefaultQPIndex <= 1 && 
+									  pSC->WMISCP.sbSubband == SB_ALL && 
+									  pSC->m_bUVResolutionChange == FALSE) &&
+                                     !pSC->WMISCP.bUnscaledArith;
+        if (BD_32 == pSC->WMII.bdBitDepth || BD_32S == pSC->WMII.bdBitDepth || BD_32F == pSC->WMII.bdBitDepth) {
+            pSC->m_param.bScaledArith = FALSE;
+        }
+        pSC->m_param.uQPMode |= 0x600;  // don't use DC QP for LP, LP QP for HP
+
+        // default QPs
+        iQPIndexY = pSC->m_param.bAlphaChannel && pSC->m_param.cNumChannels == 1?
+            pSC->WMISCP.uiDefaultQPIndexAlpha : pSC->WMISCP.uiDefaultQPIndex;
+
+		// determine the U,V index
+        iQPIndexU = pSC->WMISCP.uiDefaultQPIndexU!=0? 
+			pSC->WMISCP.uiDefaultQPIndexU: iQPIndexY; 
+        iQPIndexV = pSC->WMISCP.uiDefaultQPIndexV!=0? 
+			pSC->WMISCP.uiDefaultQPIndexV: iQPIndexY; 
+
+		// determine the QPIndexYLP
+        iQPIndexYLP = pSC->m_param.bAlphaChannel && pSC->m_param.cNumChannels == 1 ?
+            pSC->WMISCP.uiDefaultQPIndexAlpha :
+            (pSC->WMISCP.uiDefaultQPIndexYLP == 0 ? 
+			 pSC->WMISCP.uiDefaultQPIndex : pSC->WMISCP.uiDefaultQPIndexYLP); // default to QPIndex if not set
+
+		// determine the QPIndexYHP
+        iQPIndexYHP = pSC->m_param.bAlphaChannel && pSC->m_param.cNumChannels == 1 ?
+            pSC->WMISCP.uiDefaultQPIndexAlpha :
+            (pSC->WMISCP.uiDefaultQPIndexYHP == 0 ? 
+			 pSC->WMISCP.uiDefaultQPIndex : pSC->WMISCP.uiDefaultQPIndexYHP); // default to QPIndex if not set
+
+		// determine the U,V LP index
+        iQPIndexULP = pSC->WMISCP.uiDefaultQPIndexULP!=0? 
+			pSC->WMISCP.uiDefaultQPIndexULP: iQPIndexU; 
+        iQPIndexVLP = pSC->WMISCP.uiDefaultQPIndexVLP!=0? 
+			pSC->WMISCP.uiDefaultQPIndexVLP: iQPIndexV; 
+
+		// determine the U,V HP index
+        iQPIndexUHP = pSC->WMISCP.uiDefaultQPIndexUHP!=0? 
+			pSC->WMISCP.uiDefaultQPIndexUHP: iQPIndexU; 
+        iQPIndexVHP = pSC->WMISCP.uiDefaultQPIndexVHP!=0? 
+			pSC->WMISCP.uiDefaultQPIndexVHP: iQPIndexV; 
+
+		// clamp the QPIndex - 0 is lossless mode
+        if(iQPIndexY < 2)
+            iQPIndexY = 0;
+        if (iQPIndexYLP < 2)
+            iQPIndexYLP = 0;
+        if (iQPIndexYHP < 2)
+            iQPIndexYHP = 0;
+		if(iQPIndexU < 2)
+            iQPIndexU = 0;
+        if (iQPIndexULP < 2)
+            iQPIndexULP = 0;
+        if (iQPIndexUHP < 2)
+            iQPIndexUHP = 0;
+		if(iQPIndexV < 2)
+            iQPIndexV = 0;
+		if (iQPIndexVLP < 2)
+            iQPIndexVLP = 0;
+		if (iQPIndexVHP < 2)
+            iQPIndexVHP = 0;
+    }
+
+    if((pSC->m_param.uQPMode & 1) == 0){ // DC frame uniform quantization
+        if(allocateQuantizer(pSC->pTile[0].pQuantizerDC, pSC->m_param.cNumChannels, 1) != ICERR_OK)
+            return ICERR_ERROR;
+        setUniformQuantizer(pSC, 0);
+        for(i = 0; i < pSC->m_param.cNumChannels; i ++)
+            if(pSC->m_param.bTranscode)
+                pSC->pTile[0].pQuantizerDC[i]->iIndex = pSC->m_param.uiQPIndexDC[i];
+            else
+                pSC->pTile[0].pQuantizerDC[i]->iIndex = pSC->m_param.uiQPIndexDC[i] = (U8)(((i == 0 ? iQPIndexY : (i == 1) ? iQPIndexU: iQPIndexV)) & 0xff);
+        formatQuantizer(pSC->pTile[0].pQuantizerDC, (pSC->m_param.uQPMode >> 3) & 3, pSC->m_param.cNumChannels, 0, TRUE, pSC->m_param.bScaledArith);
+
+        for(i = 0; i < pSC->m_param.cNumChannels; i ++)
+            pSC->pTile[0].pQuantizerDC[i]->iOffset = (pSC->pTile[0].pQuantizerDC[i]->iQP >> 1);
+    }
+
+    if(pSC->WMISCP.sbSubband != SB_DC_ONLY){
+        if((pSC->m_param.uQPMode & 2) == 0){ // LP frame uniform quantization
+            if(allocateQuantizer(pSC->pTile[0].pQuantizerLP, pSC->m_param.cNumChannels, 1) != ICERR_OK)
+                return ICERR_ERROR;
+            setUniformQuantizer(pSC, 1);
+            for(i = 0; i < pSC->m_param.cNumChannels; i ++)
+                if(pSC->m_param.bTranscode)
+                    pSC->pTile[0].pQuantizerLP[i]->iIndex = pSC->m_param.uiQPIndexLP[i];
+                else
+                    pSC->pTile[0].pQuantizerLP[i]->iIndex = pSC->m_param.uiQPIndexLP[i] = (U8)(((i == 0 ? iQPIndexYLP : (i == 1) ? iQPIndexULP: iQPIndexVLP)) & 0xff);
+            formatQuantizer(pSC->pTile[0].pQuantizerLP, (pSC->m_param.uQPMode >> 5) & 3, pSC->m_param.cNumChannels, 0, TRUE, pSC->m_param.bScaledArith);
+        }
+
+        if(pSC->WMISCP.sbSubband != SB_NO_HIGHPASS){
+            if((pSC->m_param.uQPMode & 4) == 0){ // HP frame uniform quantization
+                if(allocateQuantizer(pSC->pTile[0].pQuantizerHP, pSC->m_param.cNumChannels, 1) != ICERR_OK)
+                    return ICERR_ERROR;
+                setUniformQuantizer(pSC, 2);
+                for(i = 0; i < pSC->m_param.cNumChannels; i ++)
+                    if(pSC->m_param.bTranscode)
+                        pSC->pTile[0].pQuantizerHP[i]->iIndex = pSC->m_param.uiQPIndexHP[i];
+                    else
+                        pSC->pTile[0].pQuantizerHP[i]->iIndex = pSC->m_param.uiQPIndexHP[i] = (U8)(((i == 0 ? iQPIndexYHP : (i == 1) ? iQPIndexUHP: iQPIndexVHP)) & 0xff);
+                formatQuantizer(pSC->pTile[0].pQuantizerHP, (pSC->m_param.uQPMode >> 7) & 3, pSC->m_param.cNumChannels, 0, FALSE, pSC->m_param.bScaledArith);
+            }
+        }
+    }
+
+    if(allocatePredInfo(pSC) != ICERR_OK){
+        return ICERR_ERROR;
+    }
+
+    if(pSC->WMISCP.cNumOfSliceMinus1V >= MAX_TILES || AllocateCodingContextEnc (pSC, pSC->WMISCP.cNumOfSliceMinus1V + 1, pSC->WMISCP.uiTrimFlexBits) != ICERR_OK){
+        return ICERR_ERROR;
+    }
+    
+    if (pSC->m_bSecondary) {
+        pSC->pIOHeader = pSC->m_pNextSC->pIOHeader;
+        pSC->m_ppBitIO = pSC->m_pNextSC->m_ppBitIO;
+        pSC->cNumBitIO = pSC->m_pNextSC->cNumBitIO;
+        pSC->cSB = pSC->m_pNextSC->cSB;
+        pSC->ppWStream = pSC->m_pNextSC->ppWStream;
+        pSC->pIndexTable = pSC->m_pNextSC->pIndexTable;
+        setBitIOPointers(pSC);
+    }
+    else {
+        StrIOEncInit(pSC);
+        setBitIOPointers(pSC);
+        WriteWMIHeader(pSC);
+    }
+
+    return ICERR_OK;
+}
+
+static Int StrEncTerm(CTXSTRCODEC ctxSC)
+{
+    CWMImageStrCodec* pSC = (CWMImageStrCodec*)ctxSC;
+    size_t j, jend = (pSC->m_pNextSC != NULL);
+
+    for (j = 0; j <= jend; j++) {
+        if (sizeof(*pSC) != pSC->cbStruct) {
+            return ICERR_ERROR;
+        }
+
+        if(pSC->m_bUVResolutionChange){
+            if(pSC->pResU != NULL)
+                free(pSC->pResU);
+            if(pSC->pResV != NULL)
+                free(pSC->pResV);
+        }
+
+        freePredInfo(pSC);
+
+        if (j == 0)
+            StrIOEncTerm(pSC);
+
+        FreeCodingContextEnc(pSC);
+        
+        freeTileInfo(pSC);
+
+        pSC->WMISCP.nExpBias -= 128; // reset
+
+        pSC = pSC->m_pNextSC;
+    }
+
+    return 0;
+}
+
+U32 setUniformTiling(U32 * pTile, U32 cNumTile, U32 cNumMB)
+{
+    U32 i, j;
+
+    while((cNumMB + cNumTile - 1) / cNumTile > 65535) // too few tiles
+        cNumTile ++;
+
+    for(i = cNumTile, j = cNumMB; i > 1; i --){
+        pTile[cNumTile - i] = (j + i - 1) / i;
+        j -= pTile[cNumTile - i];
+    }
+
+    return cNumTile;
+}
+
+U32 validateTiling(U32 * pTile, U32 cNumTile, U32 cNumMB)
+{
+    U32 i, cMBs;
+
+    if(cNumTile == 0)
+        cNumTile = 1;
+    if(cNumTile > cNumMB) // too many tiles
+        cNumTile = 1;
+    if(cNumTile > MAX_TILES)
+        cNumTile = MAX_TILES;
+
+    for(i = cMBs = 0; i + 1 < cNumTile; i ++){
+        if(pTile[i] == 0 || pTile[i] > 65535){ // invalid tile setting, resetting to uniform tiling
+            cNumTile = setUniformTiling(pTile, cNumTile, cNumMB);
+            break;
+        }
+        
+        cMBs += pTile[i];
+
+        if(cMBs >= cNumMB){
+            cNumTile = i + 1;
+            break;
+        }
+    }
+
+    // last tile
+    if(cNumMB - cMBs > 65536)
+        cNumTile = setUniformTiling(pTile, cNumTile, cNumMB);
+
+    for(i = 1; i < cNumTile; i ++)
+        pTile[i] += pTile[i - 1];
+    for(i = cNumTile - 1; i > 0; i --)
+        pTile[i] = pTile[i - 1];
+    pTile[0] = 0;
+
+    return cNumTile;
+}
+
+/*************************************************************************
+  Validate and adjust input params here
+*************************************************************************/
+Int ValidateArgs(CWMImageInfo* pII, CWMIStrCodecParam *pSCP)
+{
+    int i;
+    Bool bTooNarrowTile = FALSE;
+
+    if(pII->cWidth > (1 << 28) || pII->cHeight > (1 << 28) || pII->cWidth == 0 || pII->cHeight == 0){
+        printf("Unsurpported image size!\n");
+        return ICERR_ERROR; // unsurpported image size
+    }
+
+    if (((pSCP->cfColorFormat == YUV_420) || (pSCP->cfColorFormat == YUV_422)) && (pSCP->olOverlap == OL_TWO) && ((Int)(((U32)pII->cWidth + 15) >> 4) < 2)) {
+        printf("Image width must be at least 2 MB wide for subsampled chroma and two levels of overlap!\n");
+        return ICERR_ERROR;
+    }
+
+    if(pSCP->sbSubband == SB_ISOLATED || pSCP->sbSubband >= SB_MAX) // not allowed
+        pSCP->sbSubband = SB_ALL;
+
+    if(pII->bdBitDepth == BD_5 && (pII->cfColorFormat != CF_RGB || pII->cBitsPerUnit != 16 || pII->cLeadingPadding != 0)){
+        printf("Unsupported BD_5 image format!\n");
+        return ICERR_ERROR; // BD_5 must be compact RGB!
+    }   
+    if(pII->bdBitDepth == BD_565 && (pII->cfColorFormat != CF_RGB || pII->cBitsPerUnit != 16 || pII->cLeadingPadding != 0)){
+        printf("Unsupported BD_565 image format!\n");
+        return ICERR_ERROR; // BD_5 must be compact RGB!
+    }   
+    if(pII->bdBitDepth == BD_10 && (pII->cfColorFormat != CF_RGB || pII->cBitsPerUnit != 32 || pII->cLeadingPadding != 0)){
+        printf("Unsupported BD_10 image format!\n");
+        return ICERR_ERROR; // BD_10 must be compact RGB!
+    }
+
+    if((pII->bdBitDepth == BD_5 || pII->bdBitDepth == BD_565 || pII->bdBitDepth == BD_10) && 
+        (pSCP->cfColorFormat != YUV_420 && pSCP->cfColorFormat != YUV_422 && pSCP->cfColorFormat != Y_ONLY))
+            pSCP->cfColorFormat = YUV_444;
+
+    if(BD_1 == pII->bdBitDepth){ // binary image
+        if(pII->cfColorFormat != Y_ONLY){
+            printf("BD_1 image must be black-and white!\n");
+            return ICERR_ERROR;
+        }
+        pSCP->cfColorFormat = Y_ONLY; // can only be black white
+    }
+
+    if(pSCP->bdBitDepth != BD_LONG)
+        pSCP->bdBitDepth = BD_LONG; // currently only support 32 bit internally
+
+    if(pSCP->uAlphaMode > 1 && (pII->cfColorFormat == YUV_420 || pII->cfColorFormat == YUV_422 
+								|| pII->bdBitDepth == BD_5 || pII->bdBitDepth == BD_10 
+								|| pII->bdBitDepth == BD_1))
+    {
+        printf("Alpha is not supported for this pixel format!\n");
+        return ICERR_ERROR;
+    }
+
+    if((pSCP->cfColorFormat == YUV_420 || pSCP->cfColorFormat == YUV_422) && (pII->bdBitDepth == BD_16F || pII->bdBitDepth == BD_32F || pII->cfColorFormat == CF_RGBE))
+    {
+        printf("Float or RGBE images must be encoded with YUV 444!\n");
+        return ICERR_ERROR;
+    }
+
+    // adjust tiling
+    pSCP->cNumOfSliceMinus1V = validateTiling(pSCP->uiTileX, pSCP->cNumOfSliceMinus1V + 1, (((U32)pII->cWidth + 15) >> 4)) - 1;
+    pSCP->cNumOfSliceMinus1H = validateTiling(pSCP->uiTileY, pSCP->cNumOfSliceMinus1H + 1, (((U32)pII->cHeight + 15) >> 4)) - 1;
+
+    if (pSCP->bUseHardTileBoundaries && ((pSCP->cfColorFormat == YUV_420) || (pSCP->cfColorFormat == YUV_422)) && (pSCP->olOverlap == OL_TWO)) {
+        for (i = 1; i < (int) (pSCP->cNumOfSliceMinus1H + 1); i++) {
+            if ((Int)(pSCP->uiTileY[i] - pSCP->uiTileY[i - 1]) < 2) {
+                bTooNarrowTile = TRUE;
+                break;
+            }
+        }
+        if ((Int)((((U32)pII->cWidth + 15) >> 4) - pSCP->uiTileY[pSCP->cNumOfSliceMinus1H]) < 2) 
+            bTooNarrowTile = TRUE;
+    }
+    if (bTooNarrowTile) {
+        printf("Tile width must be at least 2 MB wide for hard tiles, subsampled chroma, and two levels of overlap!\n");
+        return ICERR_ERROR;
+    }
+
+    if(pSCP->cChannel > MAX_CHANNELS)
+        return ICERR_ERROR;
+
+    /** supported color transcoding **/
+    /** ARGB, RGB => YUV_444, YUV_422, YUV_420, Y_ONLY **/
+    /** YUV_444   =>          YUV_422, YUV_420, Y_ONLY **/
+    /** YUV_422   =>                   YUV_420, Y_ONLY **/
+    /** YUV_420   =>                            Y_ONLY **/
+
+    /** unsupported color transcoding       **/
+    /** Y_ONLY, YUV_420, YUV_422 => YUV_444 **/
+    /** Y_ONLY, YUV_420          => YUV_422 **/
+    /** Y_ONLY                   => YUV_420 **/
+    if((pII->cfColorFormat == Y_ONLY &&  pSCP->cfColorFormat != Y_ONLY) || 
+        (pSCP->cfColorFormat == YUV_422 && (pII->cfColorFormat == YUV_420 || pII->cfColorFormat == Y_ONLY)) || 
+        (pSCP->cfColorFormat == YUV_444 && (pII->cfColorFormat == YUV_422 || pII->cfColorFormat == YUV_420 || pII->cfColorFormat == Y_ONLY))){
+		pSCP->cfColorFormat = pII->cfColorFormat; // force not to do color transcoding!
+    }
+    else if (pII->cfColorFormat == NCOMPONENT) {
+		pSCP->cfColorFormat = NCOMPONENT; // force not to do color transcoding!
+    }
+    if (CMYK == pII->cfColorFormat && pSCP->cfColorFormat == NCOMPONENT) 
+    {
+        pSCP->cfColorFormat = CMYK;
+    }
+
+    if(pSCP->cfColorFormat != NCOMPONENT){
+        if(pSCP->cfColorFormat == Y_ONLY)
+            pSCP->cChannel = 1;
+        else if(pSCP->cfColorFormat == CMYK)
+            pSCP->cChannel = 4;
+        else
+            pSCP->cChannel = 3;
+    }
+
+    if(pSCP->sbSubband >= SB_MAX)
+        pSCP->sbSubband = SB_ALL;
+
+
+    pII->cChromaCenteringX = 0;
+    pII->cChromaCenteringY = 0;
+
+    return ICERR_OK;
+}
+
+/*************************************************************************
+  Initialization of CWMImageStrCodec struct
+*************************************************************************/
+static Void InitializeStrEnc(CWMImageStrCodec *pSC,
+    const CWMImageInfo* pII, const CWMIStrCodecParam *pSCP)
+{
+    pSC->cbStruct = sizeof(*pSC);
+    pSC->WMII = *pII;
+    pSC->WMISCP = *pSCP;
+
+    // set nExpBias
+    if (pSC->WMISCP.nExpBias == 0)
+        pSC->WMISCP.nExpBias = 4 + 128;//default
+    pSC->WMISCP.nExpBias += 128; // rollover arithmetic
+
+    pSC->cRow = 0;
+    pSC->cColumn = 0;
+    
+    pSC->cmbWidth = (pSC->WMII.cWidth + 15) / 16;
+    pSC->cmbHeight = (pSC->WMII.cHeight + 15) / 16;
+
+    pSC->Load = inputMBRow;
+    pSC->Quantize = quantizeMacroblock;
+    pSC->ProcessTopLeft = processMacroblock;
+    pSC->ProcessTop = processMacroblock;
+    pSC->ProcessTopRight = processMacroblock;
+    pSC->ProcessLeft = processMacroblock;
+    pSC->ProcessCenter = processMacroblock;
+    pSC->ProcessRight = processMacroblock;
+    pSC->ProcessBottomLeft = processMacroblock;
+    pSC->ProcessBottom = processMacroblock;
+    pSC->ProcessBottomRight = processMacroblock;
+
+    pSC->m_pNextSC = NULL;
+    pSC->m_bSecondary = FALSE;
+}
+
+/*************************************************************************
+   Streaming API init
+*************************************************************************/
+Int ImageStrEncInit(
+    CWMImageInfo* pII,
+    CWMIStrCodecParam *pSCP,
+    CTXSTRCODEC* pctxSC)
+{
+    static size_t cbChannels[BD_MAX] = {2, 4};
+
+    size_t cbChannel = 0, cblkChroma = 0, i;
+    size_t cbMacBlockStride = 0, cbMacBlockChroma = 0, cMacBlock = 0;
+
+    CWMImageStrCodec* pSC = NULL, *pNextSC = NULL;
+    char* pb = NULL;
+    size_t cb = 0;
+    Bool b32bit = sizeof(size_t) == 4;
+
+    Int err;
+
+    if(ValidateArgs(pII, pSCP) != ICERR_OK){
+        goto ErrorExit;
+    }
+
+    //================================================
+    *pctxSC = NULL;
+
+    //================================================
+    cbChannel = cbChannels[pSCP->bdBitDepth];
+    cblkChroma = cblkChromas[pSCP->cfColorFormat];
+    cbMacBlockStride = cbChannel * 16 * 16;
+    cbMacBlockChroma = cbChannel * 16 * cblkChroma;
+    cMacBlock = (pII->cWidth + 15) / 16;
+
+    //================================================
+    cb = sizeof(*pSC) + (128 - 1) + (PACKETLENGTH * 4 - 1) + (PACKETLENGTH * 2 ) + sizeof(*pSC->pIOHeader);
+    i = cbMacBlockStride + cbMacBlockChroma * (pSCP->cChannel - 1);
+    if(b32bit) // integer overlow/underflow check for 32-bit system
+        if(((cMacBlock >> 15) * i) & 0xffff0000)
+            return ICERR_ERROR;
+    i *= cMacBlock * 2;
+    cb += i;
+
+    pb = malloc(cb);
+    if (NULL == pb)
+    {
+        goto ErrorExit;
+    }
+    memset(pb, 0, cb);
+
+    //================================================
+    pSC = (CWMImageStrCodec*)pb; pb += sizeof(*pSC);
+
+    // Set up perf timers
+    PERFTIMER_ONLY(pSC->m_fMeasurePerf = pSCP->fMeasurePerf);
+    PERFTIMER_NEW(pSC->m_fMeasurePerf, &pSC->m_ptEndToEndPerf);
+    PERFTIMER_NEW(pSC->m_fMeasurePerf, &pSC->m_ptEncDecPerf);
+    PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEndToEndPerf);
+    PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
+    PERFTIMER_COPYSTARTTIME(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf, pSC->m_ptEndToEndPerf);
+
+    pSC->m_param.cfColorFormat = pSCP->cfColorFormat;
+    pSC->m_param.bAlphaChannel = (pSCP->uAlphaMode == 3);
+    pSC->m_param.cNumChannels = pSCP->cChannel;
+    pSC->m_param.cExtraPixelsTop = pSC->m_param.cExtraPixelsBottom
+        = pSC->m_param.cExtraPixelsLeft = pSC->m_param.cExtraPixelsRight = 0;
+
+    pSC->cbChannel = cbChannel;
+
+    pSC->m_param.bTranscode = pSC->bTileExtraction = FALSE;
+
+    //================================================
+    InitializeStrEnc(pSC, pII, pSCP);
+
+    //================================================
+    // 2 Macro Row buffers for each channel
+    pb = ALIGNUP(pb, 128);
+    for (i = 0; i < pSC->m_param.cNumChannels; i++) {
+        pSC->a0MBbuffer[i] = (PixelI*)pb; pb += cbMacBlockStride * pSC->cmbWidth;
+        pSC->a1MBbuffer[i] = (PixelI*)pb; pb += cbMacBlockStride * pSC->cmbWidth;
+        cbMacBlockStride = cbMacBlockChroma;
+    }
+
+    //================================================
+    // lay 2 aligned IO buffers just below pIO struct
+    pb = (char*)ALIGNUP(pb, PACKETLENGTH * 4) + PACKETLENGTH * 2;
+    pSC->pIOHeader = (BitIOInfo*)pb;
+
+    //================================================
+    err = StrEncInit(pSC);
+    if (ICERR_OK != err)
+        goto ErrorExit;
+
+    // if interleaved alpha is needed
+    if (pSC->m_param.bAlphaChannel) {
+        cbMacBlockStride = cbChannel * 16 * 16;
+        // 1. allocate new pNextSC info
+        //================================================
+        cb = sizeof(*pNextSC) + (128 - 1) + cbMacBlockStride * cMacBlock * 2;
+        pb = malloc(cb);
+        if (NULL == pb)
+        {
+            goto ErrorExit;
+        }
+        memset(pb, 0, cb);
+        //================================================
+        pNextSC = (CWMImageStrCodec*)pb; pb += sizeof(*pNextSC);
+
+        // 2. initialize pNextSC
+        pNextSC->m_param.cfColorFormat = Y_ONLY;
+        pNextSC->m_param.cNumChannels = 1;
+        pNextSC->m_param.bAlphaChannel = TRUE;
+        pNextSC->cbChannel = cbChannel;
+        //================================================
+
+        // 3. initialize arrays
+        InitializeStrEnc(pNextSC, pII, pSCP);
+        //================================================
+
+        // 2 Macro Row buffers for each channel
+        pb = ALIGNUP(pb, 128);
+        pNextSC->a0MBbuffer[0] = (PixelI*)pb; pb += cbMacBlockStride * pNextSC->cmbWidth;
+        pNextSC->a1MBbuffer[0] = (PixelI*)pb; pb += cbMacBlockStride * pNextSC->cmbWidth;
+        //================================================
+        pNextSC->pIOHeader = pSC->pIOHeader;
+        //================================================
+
+        // 4. link pSC->pNextSC = pNextSC
+        pNextSC->m_pNextSC = pSC;
+        pNextSC->m_bSecondary = TRUE;
+
+        // 5. StrEncInit
+        StrEncInit(pNextSC);
+
+        // 6. Write header of image plane
+        WriteImagePlaneHeader(pNextSC);
+    }
+
+    pSC->m_pNextSC = pNextSC;
+    //================================================
+    *pctxSC = (CTXSTRCODEC)pSC;
+
+    writeIndexTableNull(pSC);
+#if defined(WMP_OPT_SSE2) || defined(WMP_OPT_CC_ENC) || defined(WMP_OPT_TRFM_ENC)
+    StrEncOpt(pSC);
+#endif // OPT defined
+
+    PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
+    return ICERR_OK;
+
+ErrorExit:
+    return ICERR_ERROR;
+}
+
+/*************************************************************************
+   Streaming API encode
+*************************************************************************/
+Int ImageStrEncEncode(
+    CTXSTRCODEC ctxSC,
+    const CWMImageBufferInfo* pBI)
+{
+    CWMImageStrCodec* pSC = (CWMImageStrCodec*)ctxSC;
+    CWMImageStrCodec* pNextSC = pSC->m_pNextSC;
+    ImageDataProc ProcessLeft, ProcessCenter, ProcessRight;
+
+    if (sizeof(*pSC) != pSC->cbStruct)
+    {
+        return ICERR_ERROR;
+    }
+
+    //================================
+    PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
+
+    pSC->WMIBI = *pBI;
+    pSC->cColumn = 0;
+    initMRPtr(pSC);
+    if (pNextSC)
+        pNextSC->WMIBI = *pBI;
+
+    if (0 == pSC->cRow) {
+        ProcessLeft = pSC->ProcessTopLeft;
+        ProcessCenter = pSC->ProcessTop;
+        ProcessRight = pSC->ProcessTopRight;
+    }
+    else {
+        ProcessLeft = pSC->ProcessLeft;
+        ProcessCenter = pSC->ProcessCenter;
+        ProcessRight = pSC->ProcessRight;
+    }
+
+    if( pSC->Load(pSC) != ICERR_OK )
+		return ICERR_ERROR;
+    if(ProcessLeft(pSC) != ICERR_OK)
+        return ICERR_ERROR;
+    advanceMRPtr(pSC);
+
+    //================================
+    for (pSC->cColumn = 1; pSC->cColumn < pSC->cmbWidth; ++pSC->cColumn) {
+        if(ProcessCenter(pSC) != ICERR_OK)
+            return ICERR_ERROR;
+        advanceMRPtr(pSC);
+    }
+
+    //================================
+    if(ProcessRight(pSC) != ICERR_OK)
+        return ICERR_ERROR;
+    if (pSC->cRow)
+        advanceOneMBRow(pSC);
+
+    ++pSC->cRow;
+    swapMRPtr(pSC);
+
+    PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
+    return ICERR_OK;
+}
+
+/*************************************************************************
+   Streaming API term
+*************************************************************************/
+Int ImageStrEncTerm(
+    CTXSTRCODEC ctxSC)
+{
+    CWMImageStrCodec* pSC = (CWMImageStrCodec*)ctxSC;
+    // CWMImageStrCodec *pNextSC = pSC->m_pNextSC;
+
+    if (sizeof(*pSC) != pSC->cbStruct)
+    {
+        return ICERR_ERROR;
+    }
+
+    //================================
+    PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
+    pSC->cColumn = 0;
+    initMRPtr(pSC);
+
+    pSC->ProcessBottomLeft(pSC);
+    advanceMRPtr(pSC);
+
+    //================================
+    for (pSC->cColumn = 1; pSC->cColumn < pSC->cmbWidth; ++pSC->cColumn) {
+        pSC->ProcessBottom(pSC);
+        advanceMRPtr(pSC);
+    }
+
+    //================================
+    pSC->ProcessBottomRight(pSC);
+
+    //================================
+    StrEncTerm(pSC);
+
+    PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
+    PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEndToEndPerf);
+    PERFTIMER_REPORT(pSC->m_fMeasurePerf, pSC);
+    PERFTIMER_DELETE(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
+    PERFTIMER_DELETE(pSC->m_fMeasurePerf, pSC->m_ptEndToEndPerf);
+
+    free(pSC);
+    return ICERR_OK;
+}
+
+// centralized UV downsampling
+#define DF_ODD ((((d1 + d2 + d3) << 2) + (d2 << 1) + d0 + d4 + 8) >> 4)
+Void downsampleUV(CWMImageStrCodec * pSC)
+{
+    const COLORFORMAT cfInt = pSC->m_param.cfColorFormat;
+    const COLORFORMAT cfExt = pSC->WMII.cfColorFormat;
+    PixelI * pSrc, * pDst;
+    PixelI d0, d1, d2, d3, d4;
+    size_t iChannel, iRow, iColumn;
+
+    for(iChannel = 1; iChannel < 3; iChannel ++){
+        if(cfExt != YUV_422){ // need to do horizontal downsampling, 444 => 422
+            const size_t cShift = (cfInt == YUV_422 ? 1 : 0);
+
+            pSrc = (iChannel == 1 ? pSC->pResU : pSC->pResV);
+            pDst = (cfInt == YUV_422 ? pSC->p1MBbuffer[iChannel] : pSrc);
+            
+            for(iRow = 0; iRow < 16; iRow ++){
+                d0 = d4 = pSrc[idxCC[iRow][2]], d1 = d3 = pSrc[idxCC[iRow][1]], d2 = pSrc[idxCC[iRow][0]]; // left boundary
+                
+                for(iColumn = 0; iColumn + 2 < pSC->cmbWidth * 16; iColumn += 2){
+                    pDst[((iColumn >> 4) << (8 - cShift)) + idxCC[iRow][(iColumn & 15) >> cShift]] = DF_ODD;
+                    d0 = d2, d1 = d3, d2 = d4;
+                    d3 = pSrc[(((iColumn + 3) >> 4) << 8) + idxCC[iRow][(iColumn + 3) & 0xf]];
+                    d4 = pSrc[(((iColumn + 4) >> 4) << 8) + idxCC[iRow][(iColumn + 4) & 0xf]];
+                }
+
+                d4 = d2; // right boundary
+                pDst[((iColumn >> 4) << (8 - cShift)) + idxCC[iRow][(iColumn & 15) >> cShift]] = DF_ODD;
+            }
+        }
+
+        if(cfInt == YUV_420){ // need to do vertical downsampling
+            const size_t cShift = (cfExt == YUV_422 ? 0 : 1);
+            PixelI * pBuf[4];
+            size_t mbOff, pxOff;
+            
+            pDst = pSC->p1MBbuffer[iChannel];
+            pSrc = (iChannel == 1 ? pSC->pResU : pSC->pResV);
+            pBuf[0] = pSrc + (pSC->cmbWidth << (cfExt == YUV_422 ? 7 : 8));
+            pBuf[1] = pBuf[0] + pSC->cmbWidth * 8, pBuf[2] = pBuf[1] + pSC->cmbWidth * 8, pBuf[3] = pBuf[2] + pSC->cmbWidth * 8;
+
+            for(iColumn = 0; iColumn < pSC->cmbWidth * 8; iColumn ++){
+                mbOff = (iColumn >> 3) << (7 + cShift);
+                pxOff = (iColumn & 7) << cShift;
+
+                if(pSC->cRow == 0) // top image boundary
+                    d0 = d4 = pSrc[mbOff + idxCC[2][pxOff]], d1 = d3 = pSrc[mbOff + idxCC[1][pxOff]], d2 = pSrc[mbOff + idxCC[0][pxOff]]; // top MB boundary
+                else{
+                    // last row of previous MB row
+                    d0 = pBuf[0][iColumn], d1 = pBuf[1][iColumn], d2 = pBuf[2][iColumn], d3 = pBuf[3][iColumn], d4 = pSrc[mbOff + idxCC[0][pxOff]];
+                    pSC->p0MBbuffer[iChannel][((iColumn >> 3) << 6) + idxCC_420[7][iColumn & 7]] = DF_ODD;
+
+                    // for first row of current MB
+                    d0 = pBuf[2][iColumn], d1 = pBuf[3][iColumn];
+                    d2 = pSrc[mbOff + idxCC[0][pxOff]], d3 = pSrc[mbOff + idxCC[1][pxOff]], d4 = pSrc[mbOff + idxCC[2][pxOff]];
+                }
+
+                for(iRow = 0; iRow < 12; iRow += 2){
+                    pDst[((iColumn >> 3) << 6) + idxCC_420[iRow >> 1][iColumn & 7]] = DF_ODD;
+                    d0 = d2, d1 = d3, d2 = d4;
+                    d3 = pSrc[mbOff + idxCC[iRow + 3][pxOff]];
+                    d4 = pSrc[mbOff + idxCC[iRow + 4][pxOff]];
+                }
+                
+                //last row of current MB
+                pDst[((iColumn >> 3) << 6) + idxCC_420[6][iColumn & 7]] = DF_ODD;
+                d0 = d2, d1 = d3, d2 = d4;
+                d3 = pSrc[mbOff + idxCC[iRow + 3][pxOff]];
+
+                if(pSC->cRow + 1 == pSC->cmbHeight){ // bottom image boundary
+                    d4 = d2;
+                    pDst[((iColumn >> 3) << 6) + idxCC_420[7][iColumn & 7]] = DF_ODD;
+                }
+                else{
+                    for(iRow = 0; iRow < 4; iRow ++)
+                        pBuf[iRow][iColumn] = pSrc[mbOff + idxCC[iRow + 12][pxOff]];
+                }
+            }
+        }
+    }
+}
+
+// centralized horizontal padding
+Void padHorizontally(CWMImageStrCodec * pSC)
+{
+    if(pSC->WMII.cWidth != pSC->cmbWidth * 16){ // horizontal padding is necessary!
+        const COLORFORMAT cfExt = pSC->WMISCP.bYUVData ?
+            pSC->m_param.cfColorFormat : pSC->WMII.cfColorFormat;
+        size_t cFullChannel = pSC->WMISCP.cChannel;
+        size_t iLast = pSC->WMII.cWidth - 1;
+        PixelI * pCh[16];
+        size_t iChannel, iColumn, iRow;
+
+        if(cfExt == YUV_420 || cfExt == YUV_422 || cfExt == Y_ONLY)
+            cFullChannel = 1;
+
+        assert(cFullChannel <= 16);
+
+        assert(pSC->WMISCP.cChannel <= 16);
+        for(iChannel = 0; iChannel < pSC->WMISCP.cChannel; iChannel ++)
+            pCh[iChannel & 15] = pSC->p1MBbuffer[iChannel & 15];
+
+        if(pSC->m_bUVResolutionChange)
+            pCh[1] = pSC->pResU, pCh[2] = pSC->pResV;
+
+        // pad full resoluton channels
+        for(iRow = 0; iRow < 16; iRow ++){
+            const size_t iPosLast = ((iLast >> 4) << 8) + idxCC[iRow][iLast & 0xf];
+            for(iColumn = iLast + 1; iColumn < pSC->cmbWidth * 16; iColumn ++){
+                const size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
+                for(iChannel = 0; iChannel < cFullChannel; iChannel ++)
+                    pCh[iChannel & 15][iPos] = pCh[iChannel & 15][iPosLast];
+            }
+        }
+
+        if(cfExt == YUV_422) // pad YUV_422 UV
+            for(iLast >>= 1, iRow = 0; iRow < 16; iRow ++){
+                const size_t iPosLast = ((iLast >> 3) << 7) + idxCC[iRow][iLast & 7];
+                for(iColumn = iLast + 1; iColumn < pSC->cmbWidth * 8; iColumn ++){
+                    const size_t iPos = ((iColumn >> 3) << 7) + idxCC[iRow][iColumn & 7];
+                    for(iChannel = 1; iChannel < 3; iChannel ++)
+                        pCh[iChannel][iPos] = pCh[iChannel][iPosLast];
+                }
+            }
+        else if(cfExt == YUV_420) // pad YUV_420 UV
+            for(iLast >>= 1, iRow = 0; iRow < 8; iRow ++){
+                const size_t iPosLast = ((iLast >> 3) << 6) + idxCC_420[iRow][iLast & 7];
+                for(iColumn = iLast + 1; iColumn < pSC->cmbWidth * 8; iColumn ++){
+                    const size_t iPos = ((iColumn >> 3) << 6) + idxCC_420[iRow][iColumn & 7];
+                    for(iChannel = 1; iChannel < 3; iChannel ++)
+                        pCh[iChannel][iPos] = pCh[iChannel][iPosLast];
+                }
+            }
+    }
+}
+
+// centralized alpha channel color conversion, small perf penalty
+Int inputMBRowAlpha(CWMImageStrCodec* pSC)
+{
+    if(pSC->m_bSecondary == FALSE && pSC->m_pNextSC != NULL){ // alpha channel is present
+        const size_t cShift = (pSC->m_pNextSC->m_param.bScaledArith ? (SHIFTZERO + QPFRACBITS) : 0);
+        const BITDEPTH_BITS bdExt = pSC->WMII.bdBitDepth;
+        const size_t iAlphaPos = pSC->WMII.cLeadingPadding + (pSC->WMII.cfColorFormat == CMYK ? 4 : 3);//only RGB and CMYK may have interleaved alpha
+        const size_t cRow = pSC->WMIBI.cLine;
+        const size_t cColumn = pSC->WMII.cWidth;
+        const U8 * pSrc0 = (U8 *)pSC->WMIBI.pv;
+        PixelI * pA = pSC->m_pNextSC->p1MBbuffer[0];
+        size_t iRow, iColumn;
+
+        for(iRow = 0; iRow < 16; iRow ++){
+            if(bdExt == BD_8){
+                const size_t cStride = (pSC->WMII.cBitsPerUnit >> 3);
+                const U8 * pSrc = pSrc0;
+                
+                for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cStride)
+                    pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] = ((PixelI)pSrc[iAlphaPos] - (1 << 7)) << cShift;
+            }
+            else if(bdExt == BD_16){
+                const size_t cStride = (pSC->WMII.cBitsPerUnit >> 3) / sizeof(U16);
+                const U8 nLenMantissaOrShift = pSC->m_pNextSC->WMISCP.nLenMantissaOrShift;
+                const U16 * pSrc = (U16 *)pSrc0;
+
+                for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cStride)
+                    pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] = ((((PixelI)pSrc[iAlphaPos] - (1 << 15)) >> nLenMantissaOrShift) << cShift);
+            }
+            else if(bdExt == BD_16S){
+                const size_t cStride = (pSC->WMII.cBitsPerUnit >> 3) / sizeof(I16);
+                const U8 nLenMantissaOrShift = pSC->m_pNextSC->WMISCP.nLenMantissaOrShift;
+                const I16 * pSrc = (I16 *)pSrc0;
+            
+                for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cStride)
+                    pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] = (((PixelI)pSrc[iAlphaPos] >> nLenMantissaOrShift) << cShift);
+            }
+            else if(bdExt == BD_16F){
+                const size_t cStride = (pSC->WMII.cBitsPerUnit >> 3) / sizeof(U16);
+                const I16 * pSrc = (I16 *)pSrc0;
+
+                for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cStride)
+                    pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] = forwardHalf (pSrc[iAlphaPos]) << cShift;
+            }
+            else if(bdExt == BD_32S){
+                const size_t cStride = (pSC->WMII.cBitsPerUnit >> 3) / sizeof(I32);
+                const U8 nLenMantissaOrShift = pSC->m_pNextSC->WMISCP.nLenMantissaOrShift;
+                const I32 * pSrc = (I32 *)pSrc0;
+            
+                for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cStride)
+                    pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] = (((PixelI)pSrc[iAlphaPos] >> nLenMantissaOrShift) << cShift);
+            }
+            else if(bdExt == BD_32F){
+                const size_t cStride = (pSC->WMII.cBitsPerUnit >> 3) / sizeof(float);
+                const U8 nLen = pSC->m_pNextSC->WMISCP.nLenMantissaOrShift;
+                const I8 nExpBias = pSC->m_pNextSC->WMISCP.nExpBias;
+                const float * pSrc = (float *)pSrc0;
+            
+                for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cStride)
+                    pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] = float2pixel (pSrc[iAlphaPos], nExpBias, nLen) << cShift;
+            }
+            else // not supported
+                return ICERR_ERROR;
+
+            if(iRow + 1 < cRow) // vertical padding!
+                pSrc0 += pSC->WMIBI.cbStride;
+
+            for(iColumn = cColumn; iColumn < pSC->cmbWidth * 16; iColumn ++) // horizontal padding
+                pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] =  pA[(((cColumn - 1) >> 4) << 8) + idxCC[iRow][(cColumn - 1) & 0xf]];
+        }
+    }
+    
+    return ICERR_OK;
+}
+
+// input one MB row of image data from input buffer
+Int inputMBRow(CWMImageStrCodec* pSC)
+{
+    const size_t cShift = (pSC->m_param.bScaledArith ? (SHIFTZERO + QPFRACBITS) : 0);
+    const BITDEPTH_BITS bdExt = pSC->WMII.bdBitDepth;
+    COLORFORMAT cfExt = pSC->WMII.cfColorFormat;
+    const COLORFORMAT cfInt = pSC->m_param.cfColorFormat;
+    const size_t cPixelStride = (pSC->WMII.cBitsPerUnit >> 3);
+    const size_t iRowStride = 
+		(cfExt == YUV_420 || (pSC->WMISCP.bYUVData && pSC->m_param.cfColorFormat==YUV_420)) ? 2 : 1;
+    const size_t cRow = pSC->WMIBI.cLine;
+    const size_t cColumn = pSC->WMII.cWidth;
+	const size_t iB = (pSC->WMII.bRGB ? 2 : 0);
+    const size_t iR = 2 - iB;
+    const U8 * pSrc0 = (U8 *)pSC->WMIBI.pv;
+    const U8 nLen = pSC->WMISCP.nLenMantissaOrShift;
+    const I8 nExpBias = pSC->WMISCP.nExpBias;
+
+    PixelI *pY = pSC->p1MBbuffer[0], *pU = pSC->p1MBbuffer[1], *pV = pSC->p1MBbuffer[2];
+    size_t iRow, iColumn, iPos;
+
+    // guard input buffer
+    if(checkImageBuffer(pSC, cColumn, cRow) != ICERR_OK)
+        return ICERR_ERROR;
+
+    if(pSC->m_bUVResolutionChange)  // will do downsampling somewhere else!
+        pU = pSC->pResU, pV = pSC->pResV;
+    else if(cfInt == Y_ONLY) // xxx to Y_ONLY transcoding!
+        pU = pV = pY; // write pY AFTER pU and pV so Y will overwrite U&V
+
+    for(iRow = 0; iRow < 16; iRow += iRowStride){
+        if (pSC->WMISCP.bYUVData){
+            I32 * pSrc = (I32 *)pSrc0 + pSC->WMII.cLeadingPadding;
+
+            switch(pSC->m_param.cfColorFormat){
+            case Y_ONLY:
+            case YUV_444:
+            case NCOMPONENT:
+                {
+                    const size_t cChannel = pSC->m_param.cNumChannels;
+                    PixelI * pChannel[16];
+                    size_t iChannel;
+
+                    assert(cChannel <= 16);
+                    for(iChannel = 0; iChannel < cChannel; iChannel ++)
+                        pChannel[iChannel & 15] = pSC->p1MBbuffer[iChannel & 15];
+                    if(pSC->m_bUVResolutionChange)
+                        pChannel[1] = pSC->pResU, pChannel[2] = pSC->pResV;
+
+                    for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cChannel){
+                        iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
+                        for(iChannel = 0; iChannel < cChannel; iChannel ++)
+                            pChannel[iChannel & 15][iPos] = (PixelI)pSrc[iChannel & 15];
+                    }
+                }
+                break;
+
+            case YUV_422:
+                for(iColumn = 0; iColumn < cColumn; iColumn += 2, pSrc += 4){
+                    if(cfInt != Y_ONLY){
+                        iPos = ((iColumn >> 4) << 7) + idxCC[iRow][(iColumn >> 1) & 7];
+                        pU[iPos] = (PixelI)pSrc[0];
+                        pV[iPos] = (PixelI)pSrc[2];
+                    }
+
+                    pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] = (PixelI)pSrc[1];
+                    pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]] = (PixelI)pSrc[3];
+                }
+                break;
+
+            case YUV_420:
+                for(iColumn = 0; iColumn < cColumn; iColumn += 2, pSrc += 6){
+                    if(cfInt != Y_ONLY){
+                        iPos = ((iColumn >> 4) << 6) + idxCC_420[iRow >> 1][(iColumn >> 1) & 7];
+                        pU[iPos] = (PixelI)pSrc[4];
+                        pV[iPos] = (PixelI)pSrc[5];
+                    }
+
+                    pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] = (PixelI)pSrc[0];
+                    pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]] = (PixelI)pSrc[1];
+                    pY[((iColumn >> 4) << 8) + idxCC[iRow + 1][iColumn & 15]] = (PixelI)pSrc[2];
+                    pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow + 1][(iColumn + 1) & 15]] = (PixelI)pSrc[3];
+                }
+                break;
+
+            default:
+                assert(0);
+                break;
+            }
+        }
+        else if(bdExt == BD_8){
+            const U8 * pSrc = pSrc0 + pSC->WMII.cLeadingPadding;
+            const PixelI iOffset = (128 << cShift);
+
+            switch(cfExt){
+                case CF_RGB:
+                    assert (pSC->m_bSecondary == FALSE);
+					for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cPixelStride){
+						PixelI r = ((PixelI)pSrc[iR]) << cShift, g = ((PixelI)pSrc[1]) << cShift, b = ((PixelI)pSrc[iB]) << cShift;   
+
+						_CC(r, g, b); // color conversion
+				   
+						iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
+						pU[iPos] = -r, pV[iPos] = b, pY[iPos] = g - iOffset;
+					}
+                    break;
+
+                case Y_ONLY:
+                case YUV_444:
+                case NCOMPONENT:
+                {
+                    const size_t cChannel = pSC->m_param.cNumChannels;
+                    PixelI * pChannel[16];
+                    size_t iChannel;
+
+                    assert(cChannel <= 16);
+                    for(iChannel = 0; iChannel < cChannel; iChannel ++)
+                        pChannel[iChannel & 15] = pSC->p1MBbuffer[iChannel & 15];
+                    if(pSC->m_bUVResolutionChange)
+                        pChannel[1] = pSC->pResU, pChannel[2] = pSC->pResV;
+
+                    for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cPixelStride){
+                        iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
+                        for(iChannel = 0; iChannel < cChannel; iChannel ++)
+                            pChannel[iChannel & 15][iPos] = (((PixelI)pSrc[iChannel & 15]) << cShift) - iOffset;
+                    }
+                    break;
+                }
+
+                case CF_RGBE:
+                    for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cPixelStride){
+                        PixelI iExp = (PixelI)pSrc[3];
+                        PixelI r = forwardRGBE (pSrc[0], iExp) << cShift;
+                        PixelI g = forwardRGBE (pSrc[1], iExp) << cShift;
+                        PixelI b = forwardRGBE (pSrc[2], iExp) << cShift;
+
+                        _CC(r, g, b);
+
+                        iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
+                        pU[iPos] = -r, pV[iPos] = b, pY[iPos] = g;
+                    }
+                    break;
+
+                case CMYK:
+                {
+                    PixelI * pK = (cfInt == CMYK ? pSC->p1MBbuffer[3] : pY); // CMYK -> YUV_xxx transcoding!
+
+                    for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cPixelStride){
+                        PixelI c = ((PixelI)pSrc[0]) << cShift;
+                        PixelI m = ((PixelI)pSrc[1]) << cShift;
+                        PixelI y = ((PixelI)pSrc[2]) << cShift;
+                        PixelI k = ((PixelI)pSrc[3]) << cShift;
+
+                        _CC_CMYK(c, m, y, k);
+                        
+                        iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
+                        pU[iPos] = c, pV[iPos] = -y, pK[iPos] = k, pY[iPos] = iOffset - m;
+                    }
+                    break;
+                }
+
+                case YUV_422:
+                    for(iColumn = 0; iColumn < cColumn; iColumn += 2, pSrc += cPixelStride){
+                        if(cfInt != Y_ONLY){
+                            iPos = ((iColumn >> 4) << 7) + idxCC[iRow][(iColumn >> 1) & 7];
+                            pU[iPos] = (((PixelI)pSrc[0]) << cShift) - iOffset;
+                            pV[iPos] = (((PixelI)pSrc[2]) << cShift) - iOffset;
+                        }
+
+                        pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] = (((PixelI)pSrc[1]) << cShift) - iOffset;
+                        pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]] = (((PixelI)pSrc[3]) << cShift) - iOffset;
+                    }
+                    break;
+
+                case YUV_420:
+                    for(iColumn = 0; iColumn < cColumn; iColumn += 2, pSrc += cPixelStride){
+                        if(cfInt != Y_ONLY){
+                            iPos = ((iColumn >> 4) << 6) + idxCC_420[iRow >> 1][(iColumn >> 1) & 7];
+                            pU[iPos] = (((PixelI)pSrc[4]) << cShift) - iOffset;
+                            pV[iPos] = (((PixelI)pSrc[5]) << cShift) - iOffset;
+                        }
+
+                        pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] = (((PixelI)pSrc[0]) << cShift) - iOffset;
+                        pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]] = (((PixelI)pSrc[1]) << cShift) - iOffset;
+                        pY[((iColumn >> 4) << 8) + idxCC[iRow + 1][iColumn & 15]] = (((PixelI)pSrc[2]) << cShift) - iOffset;
+                        pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow + 1][(iColumn + 1) & 15]] = (((PixelI)pSrc[3]) << cShift) - iOffset;
+                    }
+                    break;
+
+                default:
+                    assert(0);
+                    break;
+            }
+        }
+        else if(bdExt == BD_16){
+            const U16 * pSrc = (U16 *)pSrc0 + pSC->WMII.cLeadingPadding;
+            const size_t cStride = cPixelStride / sizeof(U16);
+            const PixelI iOffset = ((1 << 15) >> nLen) << cShift;
+
+            switch(cfExt){
+                case CF_RGB:
+                    for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cStride){
+                        PixelI r = ((PixelI)pSrc[0] >> nLen) << cShift, g = ((PixelI)pSrc[1] >> nLen) << cShift, b = ((PixelI)pSrc[2] >> nLen) << cShift;
+                        
+                        _CC(r, g, b); // color conversion
+
+                        iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
+                        pU[iPos] = -r, pV[iPos] = b, pY[iPos] = g - iOffset;
+                    }
+                    break;
+
+                case Y_ONLY:
+                case YUV_444:
+                case NCOMPONENT:
+                {
+                    const size_t cChannel = pSC->WMISCP.cChannel;
+                    size_t iChannel;
+
+                    for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cStride){
+                        iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
+                        for(iChannel = 0; iChannel < cChannel; iChannel ++)
+                            pSC->p1MBbuffer[iChannel][iPos] = (((PixelI)pSrc[iChannel] >> nLen) << cShift) - iOffset;
+                    }
+                    break;
+                }
+
+                case CMYK:
+                {
+                    PixelI * pK = (cfInt == CMYK ? pSC->p1MBbuffer[3] : pY); // CMYK -> YUV_xxx transcoding!
+
+                    for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cStride){
+                        PixelI c = ((PixelI)pSrc[0] >> nLen) << cShift;
+                        PixelI m = ((PixelI)pSrc[1] >> nLen) << cShift;
+                        PixelI y = ((PixelI)pSrc[2] >> nLen) << cShift;
+                        PixelI k = ((PixelI)pSrc[3] >> nLen) << cShift;
+
+                        _CC_CMYK(c, m, y, k);
+                        
+                        iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
+                        pU[iPos] = c, pV[iPos] = -y, pK[iPos] = k, pY[iPos] = iOffset - m;
+                    }
+                    break;
+                }
+
+                case YUV_422:
+                    for(iColumn = 0; iColumn < cColumn; iColumn += 2, pSrc += cStride){
+                        if(cfInt != Y_ONLY){
+                            iPos = ((iColumn >> 4) << 7) + idxCC[iRow][(iColumn >> 1) & 7];
+                            pU[iPos] = (((PixelI)pSrc[0]) << cShift) - iOffset;
+                            pV[iPos] = (((PixelI)pSrc[2]) << cShift) - iOffset;
+                        }
+
+                        pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] = (((PixelI)pSrc[1]) << cShift) - iOffset;
+                        pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]] = (((PixelI)pSrc[3]) << cShift) - iOffset;
+                    }
+                    break;
+
+                case YUV_420:
+                    for(iColumn = 0; iColumn < cColumn; iColumn += 2, pSrc += cStride){
+                        if(cfInt != Y_ONLY){
+                            iPos = ((iColumn >> 4) << 6) + idxCC_420[iRow >> 1][(iColumn >> 1) & 7];
+                            pU[iPos] = (((PixelI)pSrc[4]) << cShift) - iOffset;
+                            pV[iPos] = (((PixelI)pSrc[5]) << cShift) - iOffset;
+                        }
+
+                        pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] = (((PixelI)pSrc[0]) << cShift) - iOffset;
+                        pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]] = (((PixelI)pSrc[1]) << cShift) - iOffset;
+                        pY[((iColumn >> 4) << 8) + idxCC[iRow + 1][iColumn & 15]] = (((PixelI)pSrc[2]) << cShift) - iOffset;
+                        pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow + 1][(iColumn + 1) & 15]] = (((PixelI)pSrc[3]) << cShift) - iOffset;
+                    }
+                    break;
+
+                default:
+                    assert(0);
+                    break;
+            }
+        }
+        else if(bdExt == BD_16S){
+            const I16 * pSrc = (I16 *)pSrc0 + pSC->WMII.cLeadingPadding;
+            const size_t cStride = cPixelStride / sizeof(I16);
+
+            switch(cfExt){
+                case CF_RGB:
+                    for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cStride){
+                        PixelI r = ((PixelI)pSrc[0] >> nLen) << cShift, g = ((PixelI)pSrc[1] >> nLen) << cShift, b = ((PixelI)pSrc[2] >> nLen) << cShift;
+                        
+                        _CC(r, g, b); // color conversion
+
+                        iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
+                        pU[iPos] = -r, pV[iPos] = b, pY[iPos] = g;
+                    }
+                    break;
+
+                case Y_ONLY:
+                case YUV_444:
+                case NCOMPONENT:
+					{
+						const size_t cChannel = pSC->WMISCP.cChannel;
+						size_t iChannel;
+	
+						for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cStride){
+							iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
+							for(iChannel = 0; iChannel < cChannel; iChannel ++)
+								pSC->p1MBbuffer[iChannel][iPos] = (((PixelI)pSrc[iChannel] >> nLen) << cShift);
+						}
+					}
+				    break;
+
+                case CMYK:
+					{
+						PixelI * pK = (cfInt == CMYK ? pSC->p1MBbuffer[3] : pY); // CMYK -> YUV_xxx transcoding!
+	
+						for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cStride){
+							PixelI c = ((PixelI)pSrc[0] >> nLen) << cShift;
+							PixelI m = ((PixelI)pSrc[1] >> nLen) << cShift;
+							PixelI y = ((PixelI)pSrc[2] >> nLen) << cShift;
+							PixelI k = ((PixelI)pSrc[3] >> nLen) << cShift;
+	
+							_CC_CMYK(c, m, y, k);
+							
+							iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
+							pU[iPos] = c, pV[iPos] = -y, pK[iPos] = k, pY[iPos] = -m;
+						}
+					}
+					break;
+
+                default:
+                    assert(0);
+                    break;
+            }
+        }
+        else if(bdExt == BD_16F){
+            const I16 * pSrc = (I16 *)pSrc0 + pSC->WMII.cLeadingPadding;
+            const size_t cStride = cPixelStride / sizeof(U16);
+
+            switch(cfExt){
+                case CF_RGB:
+                    for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cStride){
+                        PixelI r = forwardHalf (pSrc[0]) << cShift;
+                        PixelI g = forwardHalf (pSrc[1]) << cShift;
+                        PixelI b = forwardHalf (pSrc[2]) << cShift;
+                        
+                        _CC(r, g, b); // color conversion
+
+                        iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
+                        pU[iPos] = -r, pV[iPos] = b, pY[iPos] = g;
+                    }
+                    break;
+
+                case Y_ONLY:
+                case YUV_444:
+                case NCOMPONENT:
+					{
+						const size_t cChannel = pSC->WMISCP.cChannel; // check xxx => Y_ONLY transcoding!
+						size_t iChannel;
+	
+						for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cStride){
+							iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
+							for(iChannel = 0; iChannel < cChannel; iChannel ++)
+								pSC->p1MBbuffer[iChannel][iPos] = forwardHalf (pSrc[iChannel]) << cShift;
+						}
+					}
+					break;
+
+                default:
+                    assert(0);
+                    break;
+            }
+        }
+        else if(bdExt == BD_32){
+            const U32 * pSrc = (U32 *)pSrc0 + pSC->WMII.cLeadingPadding;
+            const size_t cStride = cPixelStride / sizeof(U32);
+            const PixelI iOffset = ((1 << 31) >> nLen) << cShift;
+
+            switch(cfExt){
+                case CF_RGB:
+                    for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cStride){
+                        PixelI r = (pSrc[0] >> nLen) << cShift, g = (pSrc[1] >> nLen) << cShift, b = (pSrc[2] >> nLen) << cShift;
+                        
+                        _CC(r, g, b); // color conversion
+
+                        iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
+                        pU[iPos] = -r, pV[iPos] = b, pY[iPos] = g - iOffset;
+                    }
+                    break;
+
+                case Y_ONLY:
+                case YUV_444:
+                case NCOMPONENT:
+                {
+                    const size_t cChannel = pSC->WMISCP.cChannel;
+                    size_t iChannel;
+
+                    for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cStride){
+                        iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
+                        for(iChannel = 0; iChannel < cChannel; iChannel ++)
+                            pSC->p1MBbuffer[iChannel][iPos] = (pSrc[iChannel] >> nLen) << cShift;
+                    }
+                    break;
+                }
+
+                default:
+                    assert(0);
+                    break;
+            }
+        }
+        else if(bdExt == BD_32S){
+            const I32 * pSrc = (I32 *)pSrc0 + pSC->WMII.cLeadingPadding;
+            const size_t cStride = cPixelStride / sizeof(I32);
+
+            switch(cfExt){
+                case CF_RGB:
+                    for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cStride){
+                        PixelI r = (pSrc[0] >> nLen)<< cShift, g = (pSrc[1] >> nLen)<< cShift, b = (pSrc[2] >> nLen)<< cShift;
+                        
+                        _CC(r, g, b); // color conversion
+
+                        iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
+                        pU[iPos] = -r, pV[iPos] = b, pY[iPos] = g;
+                    }
+                    break;
+
+                case Y_ONLY:
+                case YUV_444:
+                case NCOMPONENT:
+					{
+						const size_t cChannel = pSC->WMISCP.cChannel; // check xxx => Y_ONLY transcoding!
+						size_t iChannel;
+	
+						for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cStride){
+							iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
+							for(iChannel = 0; iChannel < cChannel; iChannel ++)
+								pSC->p1MBbuffer[iChannel][iPos] = (pSrc[iChannel] >> nLen) << cShift;
+						}
+					}
+					break;
+
+                default:
+                    assert(0);
+                    break;
+            }
+        }
+        else if(bdExt == BD_32F){
+            const float * pSrc = (float *)pSrc0 + pSC->WMII.cLeadingPadding;
+            const size_t cStride = cPixelStride / sizeof(float);
+
+            switch(cfExt){
+                case CF_RGB:
+                    for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cStride){
+                        PixelI r = float2pixel (pSrc[0], nExpBias, nLen) << cShift;
+                        PixelI g = float2pixel (pSrc[1], nExpBias, nLen) << cShift;
+                        PixelI b = float2pixel (pSrc[2], nExpBias, nLen) << cShift;
+
+                        _CC(r, g, b); // color conversion
+
+                        iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
+                        pU[iPos] = -r, pV[iPos] = b, pY[iPos] = g;
+                    }
+                    break;
+
+                case Y_ONLY:
+                case YUV_444:
+                case NCOMPONENT:
+					{
+						const size_t cChannel = pSC->WMISCP.cChannel;
+						size_t iChannel;
+	
+						for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cStride){
+							iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
+							for(iChannel = 0; iChannel < cChannel; iChannel ++)
+								pSC->p1MBbuffer[iChannel][iPos] = float2pixel (pSrc[iChannel], nExpBias, nLen) << cShift;
+						}
+					}
+					break;
+                default:
+                    assert(0);
+                    break;
+            }
+        }
+        else if(bdExt == BD_5){ // RGB 555, work for both big endian and small endian!
+            const U8 * pSrc = pSrc0;
+            const PixelI iOffset = (16 << cShift);
+
+            assert(cfExt == CF_RGB);
+            
+            for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cPixelStride){
+                PixelI r = (PixelI)pSrc[0], g = (PixelI)pSrc[1], b = ((g >> 2) & 0x1F) << cShift;
+
+                g = ((r >> 5) + ((g & 3) << 3)) << cShift, r = (r & 0x1F) << cShift;
+
+                _CC(r, g, b); // color conversion
+                
+                iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
+                pU[iPos] = -r, pV[iPos] = b, pY[iPos] = g - iOffset;
+            }
+        }
+        else if(bdExt == BD_565){ // RGB 555, work for both big endian and small endian!
+            const U8 * pSrc = pSrc0;
+            const PixelI iOffset = (32 << cShift);
+
+            assert(cfExt == CF_RGB);
+            
+            for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cPixelStride){
+                PixelI r = (PixelI)pSrc[0], g = (PixelI)pSrc[1], b = (g >> 3) << (cShift + 1);
+
+                g = ((r >> 5) + ((g & 7) << 3)) << cShift, r = (r & 0x1F) << (cShift + 1);
+
+                _CC(r, g, b); // color conversion
+                
+                iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
+                pU[iPos] = -r, pV[iPos] = b, pY[iPos] = g - iOffset;
+            }
+        }
+        else if(bdExt == BD_10){ //RGB 101010, work for both big endian and small endian!
+            const U8 * pSrc = pSrc0;
+            const PixelI iOffset = (512 << cShift);
+
+            assert(cfExt == CF_RGB);
+            
+            for(iColumn = 0; iColumn < cColumn; iColumn ++, pSrc += cPixelStride){
+                PixelI r = (PixelI)pSrc[0], g = (PixelI)pSrc[1], b = (PixelI)pSrc[2];
+
+                r = (r + ((g & 3) << 8)) << cShift, g = ((g >> 2) + ((b & 0xF) << 6)) << cShift;
+                b = ((b >> 4) + (((PixelI)pSrc[3] & 0x3F) << 4)) << cShift;
+
+                _CC(r, g, b); // color conversion
+                
+                iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
+                pU[iPos] = -r, pV[iPos] = b, pY[iPos] = g - iOffset;
+            }
+        }
+        else if(bdExt == BD_1){
+            assert(cfExt == Y_ONLY);
+            for(iColumn = 0; iColumn < cColumn; iColumn ++) {
+                pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] = ((pSC->WMISCP.bBlackWhite + (pSrc0[iColumn >> 3] >> (7 - (iColumn & 7)))) & 1) << cShift;
+            }
+        }
+
+        if(iRow + iRowStride < cRow) // centralized vertical padding!
+            pSrc0 += pSC->WMIBI.cbStride;
+    }
+
+    padHorizontally(pSC); // centralized horizontal padding
+
+    // centralized down-sampling
+    if(pSC->m_bUVResolutionChange)
+        downsampleUV(pSC);
+
+    // centralized alpha channel handdling
+    if (pSC->WMISCP.uAlphaMode == 3)
+        if(inputMBRowAlpha(pSC) != ICERR_OK)
+            return ICERR_ERROR;
+
+    return ICERR_OK;
+}
+
+
diff --git a/Source/LibJXR/image/encode/strenc_x86.c b/Source/LibJXR/image/encode/strenc_x86.c
new file mode 100644
index 0000000..a552fec
--- /dev/null
+++ b/Source/LibJXR/image/encode/strenc_x86.c
@@ -0,0 +1,409 @@
+//*@@@+++@@@@******************************************************************
+//
+// Copyright � Microsoft Corp.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+// � Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// � Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//*@@@---@@@@******************************************************************
+#include "strcodec.h"
+
+#if defined(WMP_OPT_SSE2)
+#include <emmintrin.h>
+#include <windows.h>
+
+//================================
+__m128i g_const_d1;
+__m128i g_const_d0x400;
+__m128i g_const_d0x7f8;
+
+//================================
+#if defined(WMP_OPT_CC_ENC)
+__declspec(naked) void __stdcall RGB24_6(
+    const U8* pbRGB,
+    size_t cbRGB,
+    U8* pbYCoCg,
+    size_t cbYCoCg,
+    size_t cmb)
+{
+    UNREFERENCED_PARAMETER( pbRGB );
+    UNREFERENCED_PARAMETER( cbRGB );
+    UNREFERENCED_PARAMETER( pbYCoCg );
+    UNREFERENCED_PARAMETER( cbYCoCg );
+    UNREFERENCED_PARAMETER( cmb );
+    __asm {
+         push ebp
+         push ebx
+         push esi
+         push edi
+
+         mov ebp, [esp + 36]           // $ebp = cmb
+         mov edx, [esp + 20]           // $edx = pbRGB
+         lea ebp, [ebp + ebp * 2]      // $ebp = cmb * 3
+         mov ecx, [esp + 24]           // $ecx = cbRGB
+         shl ebp, 4                    // $ebp = cmb * 3 * 16
+         mov edi, [esp + 28]           // $edi = pbYCoCg
+         add edx, ebp                  // $edx = pbRGB + 3 * 16 * cmb
+         mov ebx, [esp + 32]           // $ebx = cbYCoCg
+         neg ebp
+
+         mov eax, esp
+         and esp, 0xffffff80
+         sub esp, 64 + 4 * 6
+
+         mov [esp], ecx                // cbRGB
+         mov [esp + 4], edx            // pbRGB + 3 * 16 * cmb
+         mov [esp + 8], edi            // pbYCoCg
+         mov dword ptr [esp + 12], 4   // cLoop0 = 4
+         mov [esp + 16], ebp           // -3 * 16 * cmb
+         mov [esp + 20], eax           // original $esp
+         movdqa xmm3, [g_const_d1]
+    }
+Loop0:
+    __asm mov edi, [esp + 8]            // $edi = pbYCoCg
+    __asm mov ebp, [esp + 16]           // $ebp = -3 * 16 * cmb
+
+Loop1:
+    __asm {
+        mov esi, [esp + 4]              // $esi = pbRGB + 3 * 16 * cmb
+
+        //================
+        // scanline 0
+        mov eax, [esi + ebp]
+        mov edx, [esi + ebp + 4]
+        mov ecx, [esi + ebp + 8]
+        add esi, [esp]                  // $esi += cbRGB
+
+        mov [esp + 24], eax
+        shrd eax, edx, 24
+        shrd edx, ecx, 16
+        shr ecx, 8
+        mov [esp + 24 + 4], eax
+        mov [esp + 24 + 20], edx
+        mov [esp + 24 + 16], ecx
+
+        // scanline 1
+        mov eax, [esi + ebp]
+        mov edx, [esi + ebp + 4]
+        mov ecx, [esi + ebp + 8]
+        add esi, [esp]
+
+        mov [esp + 24 + 8], eax
+        shrd eax, edx, 24
+        shrd edx, ecx, 16
+        shr ecx, 8
+        mov [esp + 24 + 12], eax
+        mov [esp + 24 + 28], edx
+        mov [esp + 24 + 24], ecx
+
+        // scanline 2
+        mov eax, [esi + ebp]
+        mov edx, [esi + ebp + 4]
+        mov ecx, [esi + ebp + 8]
+        add esi, [esp]
+
+        mov [esp + 24 + 40], eax
+        shrd eax, edx, 24
+        shrd edx, ecx, 16
+        shr ecx, 8
+        mov [esp + 24 + 44], eax
+        mov [esp + 24 + 60], edx
+        mov [esp + 24 + 56], ecx
+
+        // scanline 3
+        mov eax, [esi + ebp]
+        mov edx, [esi + ebp + 4]
+        mov ecx, [esi + ebp + 8]
+        add esi, [esp]
+
+        mov [esp + 24 + 32], eax
+        shrd eax, edx, 24
+        shrd edx, ecx, 16
+        shr ecx, 8
+        mov [esp + 24 + 36], eax
+        mov [esp + 24 + 52], edx
+        mov [esp + 24 + 48], ecx
+
+        //================
+        // CC 0,1
+        movdqa xmm0, [esp + 24]
+        movdqa xmm4, [esp + 24 + 16]
+        movdqa xmm7, [g_const_d0x7f8]
+        movdqa xmm1, xmm0
+        movdqa xmm5, xmm4
+        movdqa xmm2, xmm0
+        movdqa xmm6, xmm4
+
+        pslld xmm0, 3
+        pslld xmm4, 3
+        psrad xmm5, 5
+        psrad xmm1, 5
+        psrad xmm2, 13
+        psrad xmm6, 13
+        pand xmm0, xmm7     // R
+        pand xmm4, xmm7
+        pand xmm1, xmm7     // G
+        pand xmm5, xmm7
+        pand xmm2, xmm7     // B
+        pand xmm6, xmm7
+
+        psubd xmm2, xmm0    // b -= r
+        psubd xmm6, xmm4
+        movntdq [edi + ebx * 2], xmm2
+        movntdq [edi + ebx * 2 + 16], xmm6
+
+        paddd xmm2, xmm3    // r += ((b + 1) >> 1) - g
+        paddd xmm6, xmm3
+        psubd xmm0, xmm1
+        psubd xmm4, xmm5
+        psrad xmm2, 1
+        psrad xmm6, 1
+        paddd xmm0, xmm2
+        paddd xmm4, xmm6
+
+        movdqa xmm2, xmm0   // g += r >> 1
+        movdqa xmm6, xmm4
+        movdqa xmm7, [g_const_d0x400]
+        psrad xmm2, 1
+        psrad xmm6, 1
+        paddd xmm1, xmm2
+        paddd xmm5, xmm6
+
+        pxor xmm2, xmm2
+        pxor xmm6, xmm6
+        psubd xmm1, xmm7    // g -= offset
+        psubd xmm5, xmm7
+        psubd xmm2, xmm0    // r = -r
+        psubd xmm6, xmm4
+
+        movntdq [edi], xmm1
+        movntdq [edi + 16], xmm5
+        movntdq [edi + ebx], xmm2
+        movntdq [edi + ebx + 16], xmm6
+
+        //================
+        // CC 2,3
+        movdqa xmm4, [esp + 24 + 48]
+        movdqa xmm0, [esp + 24 + 32]
+        movdqa xmm7, [g_const_d0x7f8]
+        movdqa xmm1, xmm0
+        movdqa xmm5, xmm4
+        movdqa xmm2, xmm0
+        movdqa xmm6, xmm4
+
+        pslld xmm0, 3
+        pslld xmm4, 3
+        psrad xmm1, 5
+        psrad xmm5, 5
+        psrad xmm2, 13
+        psrad xmm6, 13
+        pand xmm0, xmm7     // R
+        pand xmm4, xmm7
+        pand xmm1, xmm7     // G
+        pand xmm5, xmm7
+        pand xmm2, xmm7     // B
+        pand xmm6, xmm7
+
+        psubd xmm2, xmm0    // b -= r
+        psubd xmm6, xmm4
+        movntdq [edi + ebx * 2 + 32], xmm2
+        movntdq [edi + ebx * 2 + 48], xmm6
+
+        paddd xmm2, xmm3    // r += ((b + 1) >> 1) - g
+        paddd xmm6, xmm3
+        psubd xmm0, xmm1
+        psubd xmm4, xmm5
+        psrad xmm2, 1
+        psrad xmm6, 1
+        paddd xmm0, xmm2
+        paddd xmm4, xmm6
+
+        movdqa xmm2, xmm0   // g += r >> 1
+        movdqa xmm6, xmm4
+        movdqa xmm7, [g_const_d0x400]
+        psrad xmm2, 1
+        psrad xmm6, 1
+        paddd xmm1, xmm2
+        paddd xmm5, xmm6
+
+        pxor xmm2, xmm2
+        pxor xmm6, xmm6
+        psubd xmm1, xmm7    // g -= offset
+        psubd xmm5, xmm7
+        psubd xmm2, xmm0    // r = -r
+        psubd xmm6, xmm4
+
+        movntdq [edi + 32], xmm1
+        movntdq [edi + 48], xmm5
+        movntdq [edi + ebx + 32], xmm2
+        movntdq [edi + ebx + 48], xmm6
+
+        //================
+        add edi, 256                    // pbYCoCg += 256
+        add ebp, 12                     // pbRGB += 12
+        jnz Loop1
+
+        //================
+        add dword ptr [esp + 8], 64     // pbYCoCg += 64
+        sub dword ptr [esp + 12], 1     // --cLoop0
+        mov [esp + 4], esi              // pbRGB += cbRGB * 4
+        jnz Loop0
+
+        //================
+        mov esp, [esp + 20]
+        pop edi
+        pop esi
+        pop ebx
+        pop ebp
+        ret 20
+    }
+}
+
+Int inputMBRow_RGB24_6(CWMImageStrCodec* pSC)
+{
+    const U8* const pbRGB = (U8*)pSC->WMIBI.pv;
+    const size_t cbRGB = pSC->WMIBI.cbStride;
+
+    U8* const pbY = (U8*)pSC->p1MBbuffer[0];
+    U8* const pbU = (U8*)pSC->p1MBbuffer[1];
+    // U8* const pbV = (U8*)pSC->p1MBbuffer[2];
+
+    const size_t cmbColumn = (pSC->WMII.cWidth + 15) / 16;
+
+    assert(BD_8 == pSC->WMII.bdBitDepth);
+    assert(CF_RGB == pSC->WMII.cfColorFormat);
+    assert(24 == pSC->WMII.cBitsPerUnit);
+    assert(pSC->WMII.bRGB);
+    assert(pSC->m_param.bScaledArith);
+    assert(pbU - pbY == pbV - pbU);
+
+    RGB24_6(pbRGB + cbRGB * 0, cbRGB, pbY, pbU - pbY, cmbColumn);
+    return ICERR_OK;
+}
+#endif
+
+//================================
+#if defined(WMP_OPT_QT)
+#if 0
+Int quantizeMacroblock(CWMImageStrCodec* pSC)
+{
+    assert(BD_8 == pSC->WMII.bdBitDepth);
+    assert(YUV_444 == pSC->m_param.cfColorFormat);
+    assert(pSC->m_param.bScaledArith);
+    assert(3 == pSC->m_param.cNumChannels);
+    assert(SB_ALL == pSC->WMISCP.sbSubband);
+
+    CWMITile* pTile = pSC->pTile + pSC->cTileColumn;
+    CWMIMBInfo* pMBInfo = &pSC->MBInfo;
+    int iChannel, i, j;
+
+    __m128 owQT[2];
+
+    
+
+    for (iChannel = 0; iChannel < 3; iChannel ++) {
+        CWMIQuantizer* pQPDC = pTile->pQuantizerDC[iChannel];
+        CWMIQuantizer* pQPLP = pTile->pQuantizerLP[iChannel] + pMBInfo->iQIndexLP;
+        CWMIQuantizer* pQPHP = pTile->pQuantizerHP[iChannel] + pMBInfo->iQIndexHP;
+
+        __m128 owQT[4] = {
+            {pQPDC->f1_QP, pQPHP->f1_QP, pQPHP->f1_QP, pQPHP->f1_QP,},
+            {pQPLP->f1_QP, pQPHP->f1_QP, pQPHP->f1_QP, pQPHP->f1_QP,},
+        };
+
+        owQT[0].m128_f32[0] = pQPDC->f1_QP;
+        owQT[0].m128_f32[1] = pQPHP->f1_QP;
+        owQT[0].m128_f32[2] = pQPHP->f1_QP;
+        owQT[0].m128_f32[3] = pQPHP->f1_QP;
+        owQT[1].m128_f32[0] = pQPDC->f1_QP;
+        owQT[1].m128_f32[1] = pQPHP->f1_QP;
+        owQT[1].m128_f32[2] = pQPHP->f1_QP;
+        owQT[1].m128_f32[3] = pQPHP->f1_QP;
+        
+        
+        
+
+        for(j = 0; j < 16; j ++){
+            PixelI* pData = pSC->pPlane[iChannel] + blkOffset[j];
+
+            if(j == 0) // DC
+                pData[0] = (pQPDC->iMan == 0 ? QUANT_Mulless(pData[0], pQPDC->iOffset, pQPDC->iExp) : QUANT(pData[0], pQPDC->iOffset, pQPDC->iMan, pQPDC->iExp));
+            else // LP
+                pData[0] = (pQPLP->iMan == 0 ? QUANT_Mulless(pData[0], pQPLP->iOffset, pQPLP->iExp) : QUANT(pData[0], pQPLP->iOffset, pQPLP->iMan, pQPLP->iExp));
+
+            // quantize HP
+            for(i = 1; i < 16; i ++)
+                pData[i] = (pQPHP->iMan == 0 ? QUANT_Mulless(pData[i], pQPHP->iOffset, pQPHP->iExp) : QUANT(pData[i], pQPHP->iOffset, pQPHP->iMan, pQPHP->iExp));
+        }
+    }
+    
+    for (iChannel = 0; iChannel < 3; iChannel ++) {
+        I32* pDC = pSC->MBInfo.iBlockDC[iChannel];
+        PixelI* pData = pSC->pPlane[iChannel];
+
+        for(i = 0; i < 16; i ++){
+            pDC[i] = pData[dctIndex[2][i]];
+        }
+    }
+
+    return 0;
+}
+#endif
+#endif
+#endif
+
+
+//================================
+void StrEncOpt(CWMImageStrCodec* pSC)
+{
+#if defined(WMP_OPT_SSE2)
+    if (IsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE) &&
+        pSC->WMII.fPaddedUserBuffer &&
+        1)
+    {
+        CWMImageInfo* pII = &pSC->WMII;
+        // CWMIStrCodecParam* pSCP = &pSC->WMISCP;
+
+        g_const_d1 = _mm_set_epi32(1, 1, 1, 1);
+        g_const_d0x400 = _mm_set_epi32(0x400, 0x400, 0x400, 0x400);
+        g_const_d0x7f8 = _mm_set_epi32(0x7f8, 0x7f8, 0x7f8, 0x7f8);
+
+        if (BD_8 == pII->bdBitDepth &&
+            CF_RGB == pII->cfColorFormat &&
+            YUV_444 == pSC->m_param.cfColorFormat &&
+            24 == pII->cBitsPerUnit &&
+            pII->bRGB &&
+            pSC->m_param.bScaledArith &&
+            pSC->p1MBbuffer[1] - pSC->p1MBbuffer[0] == pSC->p1MBbuffer[2] - pSC->p1MBbuffer[1] &&
+            1)
+        {
+#if defined(WMP_OPT_CC_ENC)
+            pSC->Load = inputMBRow_RGB24_6;
+#endif
+        }
+
+    }
+#else
+    UNREFERENCED_PARAMETER( pSC );
+#endif    
+}
+
diff --git a/Source/LibJXR/image/sys/adapthuff.c b/Source/LibJXR/image/sys/adapthuff.c
new file mode 100644
index 0000000..a690889
--- /dev/null
+++ b/Source/LibJXR/image/sys/adapthuff.c
@@ -0,0 +1,511 @@
+//*@@@+++@@@@******************************************************************
+//
+// Copyright � Microsoft Corp.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+// � Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// � Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//*@@@---@@@@******************************************************************
+
+#include "strcodec.h"
+
+#ifdef MEM_TRACE
+#define TRACE_MALLOC    1
+#define TRACE_NEW       0
+#define TRACE_HEAP      0
+#include "memtrace.h"
+#endif
+
+// Huffman lookup tables
+static const short g4HuffLookupTable[40] = {
+  19,19,19,19,27,27,27,27,10,10,10,10,10,10,10,10,
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,0 };
+
+static const short g5HuffLookupTable[2][42] = {{
+  28,28,36,36,19,19,19,19,10,10,10,10,10,10,10,10,
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,0,0,0 },
+  {
+  11,11,11,11,19,19,19,19,27,27,27,27,35,35,35,35,
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,0,0,0 }};
+
+static const short g6HuffLookupTable[4][44] = {{
+  13,29,44,44,19,19,19,19,34,34,34,34,34,34,34,34,
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,0,0,0,0,0 },
+  {
+  12,12,28,28,43,43,43,43,2,2,2,2,2,2,2,2,
+  18,18,18,18,18,18,18,18,34,34,34,34,34,34,34,34,
+  0,0,0,0,0,0,0,0,0,0,0,0 },
+  {
+  4,4,12,12,43,43,43,43,18,18,18,18,18,18,18,18,
+  26,26,26,26,26,26,26,26,34,34,34,34,34,34,34,34,
+  0,0,0,0,0,0,0,0,0,0,0,0 },
+  {
+  5,13,36,36,43,43,43,43,18,18,18,18,18,18,18,18,
+  25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+  0,0,0,0,0,0,0,0,0,0,0,0 }};
+
+static const short g7HuffLookupTable[2][46] = {{
+  45,53,36,36,27,27,27,27,2,2,2,2,2,2,2,2,
+  10,10,10,10,10,10,10,10,18,18,18,18,18,18,18,18,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
+  {
+  -32736,37,28,28,19,19,19,19,10,10,10,10,10,10,10,10,
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  5,6,0,0,0,0,0,0,0,0,0,0,0,0 }};
+
+static const short g8HuffLookupTable[2][48] = {{
+  53,21,28,28,11,11,11,11,43,43,43,43,59,59,59,59,
+  2,2,2,2,2,2,2,2,34,34,34,34,34,34,34,34,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
+  {
+  52,52,20,20,3,3,3,3,11,11,11,11,27,27,27,27,
+  35,35,35,35,43,43,43,43,58,58,58,58,58,58,58,58,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }};
+
+static const short g9HuffLookupTable[2][50] = {{
+  13,29,37,61,20,20,68,68,3,3,3,3,51,51,51,51,
+  41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0 },
+  {
+  -32736,53,28,28,11,11,11,11,19,19,19,19,43,43,43,43,
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  -32734,4,7,8,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0 }};
+
+static const short g12HuffLookupTable[5][56] = {{
+  -32736,5,76,76,37,53,69,85,43,43,43,43,91,91,91,91,
+  57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,
+  -32734,1,2,3,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0 },
+  {
+  -32736,85,13,53,4,4,36,36,43,43,43,43,67,67,67,67,
+  75,75,75,75,91,91,91,91,58,58,58,58,58,58,58,58,
+  2,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0 },
+  {
+  -32736,37,92,92,11,11,11,11,43,43,43,43,59,59,59,59,
+  67,67,67,67,75,75,75,75,2,2,2,2,2,2,2,2,
+  -32734,-32732,2,3,6,10,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0 },
+  {
+  -32736,29,37,69,3,3,3,3,43,43,43,43,59,59,59,59,
+  75,75,75,75,91,91,91,91,10,10,10,10,10,10,10,10,
+  -32734,10,2,6,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0 },
+  {
+  -32736,93,28,28,60,60,76,76,3,3,3,3,43,43,43,43,
+  9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
+  -32734,-32732,-32730,2,4,8,6,10,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0 }};
+
+/**********************************************************************
+  Allocation and dellocation
+**********************************************************************/
+Void Clean (CAdaptiveHuffman *pAdHuff)
+{
+    if (pAdHuff == NULL)
+        return;
+    free (pAdHuff);
+}
+
+CAdaptiveHuffman *Allocate (Int iNSymbols, CODINGMODE cm)
+{
+    CAdaptiveHuffman *pAdHuff = (CAdaptiveHuffman *) malloc (sizeof (CAdaptiveHuffman));
+
+    UNREFERENCED_PARAMETER(cm);
+
+    if (pAdHuff == NULL)
+        return NULL;
+    if (iNSymbols > 255 || iNSymbols <= 0)
+        goto ErrorExit;
+
+    memset (pAdHuff, 0, sizeof (CAdaptiveHuffman));
+    pAdHuff->m_iNSymbols = iNSymbols;
+
+    pAdHuff->m_pDelta = NULL;
+    pAdHuff->m_iDiscriminant = pAdHuff->m_iUpperBound = pAdHuff->m_iLowerBound = 0;
+
+    return pAdHuff;
+
+ErrorExit:
+    Clean (pAdHuff);
+    return NULL;
+}
+
+/**********************************************************************
+  Adapt Huffman table
+**********************************************************************/
+// Alphabet size = 4
+static const Int g_Index4Table[] = {
+    1,2,3,3
+};
+static const Int g4CodeTable[] = {
+    4,
+    1, 1,
+    1, 2,
+    0, 3,
+    1, 3
+};
+
+// Alphabet size = 5
+static const Int g_Index5Table[] = {
+    1,2,3,4,4,
+    1,3,3,3,3
+};
+static const Int g5CodeTable[] = {
+    5,
+    1, 1,
+    1, 2,
+    1, 3,
+    0, 4,
+    1, 4,
+
+    5,
+    1, 1,
+    0, 3,
+    1, 3,
+    2, 3,
+    3, 3,
+};
+static const Int g5DeltaTable[] = { 0,-1,0,1,1 };
+
+// Alphabet size = 6
+static const Int g_Index6Table[] = {
+    1,5,3,5,2,4,
+    2,4,2,4,2,3,
+    4,4,2,2,2,3,
+    5,5,2,1,4,3,
+};
+static const Int g6CodeTable[] = {
+    6,
+    1, 1,
+    0, 5,
+    1, 3,
+    1, 5,
+    1, 2,
+    1, 4,
+
+    6,
+    1,  2,
+    0,  4,
+    2,  2,
+    1,  4,
+    3,  2,
+    1,  3,
+
+    6,
+    0,  4,
+    1,  4,
+    1,  2,
+    2,  2,
+    3,  2,
+    1,  3,
+
+    6,
+    0, 5,
+    1, 5,
+    1, 2,
+    1, 1,
+    1, 4,
+    1, 3
+};
+static const Int g6DeltaTable[] = {
+    -1, 1, 1, 1, 0, 1,
+    -2, 0, 0, 2, 0, 0,
+    -1,-1, 0, 1,-2, 0
+};
+
+// Alphabet size = 7
+static const Int g_Index7Table[] = { 2,2,2,3,4,5,5,
+                        1,2,3,4,5,6,6 };
+static const Int g7CodeTable[] = {
+    7,
+    1, 2,
+    2, 2,
+    3, 2,
+    1, 3,
+    1, 4,
+    0, 5,
+    1, 5,
+
+    7,
+    1, 1,
+    1, 2,
+    1, 3,
+    1, 4,
+    1, 5,
+    0, 6,
+    1, 6
+};
+static const Int g7DeltaTable[] = { 1,0,-1,-1,-1,-1,-1 };
+
+// Alphabet size = 8
+static const Int g_Index8Table[] = { 2,3,5,4,2,3,5,3,
+                        3,3,4,3,3,3,4,2};
+static const Int g8CodeTable[] = {
+    8,
+    2, 2,
+    1, 3,
+    1, 5,
+    1, 4,
+    3, 2,
+    2, 3,
+    0, 5,
+    3, 3,
+
+    8,
+    1, 3,
+    2, 3,
+    1, 4,
+    3, 3,
+    4, 3,
+    5, 3,
+    0, 4,
+    3, 2
+};
+static const Int g8DeltaTable[] = { -1,0,1,1,-1,0,1,1 };
+
+static const Int g_Index9Table[] = {
+    3,5,4,5,5,1,3,5,4,
+    1,3,3,4,6,3,5,7,7,
+};
+static const Int g9CodeTable[] = {
+    9,
+    2, 3,
+    0, 5,
+    2, 4,
+    1, 5,
+    2, 5,
+    1, 1,
+    3, 3,
+    3, 5,
+    3, 4,
+
+    9,
+    1, 1,
+    1, 3,
+    2, 3,
+    1, 4,
+    1, 6,
+    3, 3,
+    1, 5,
+    0, 7,
+    1, 7,
+};
+static const Int g9DeltaTable[] = { 2,2,1,1,-1,-2,-2,-2,-3 };
+
+// Alphabet size = 12
+static const Int g_Index12Table[] = {  // index12 is the most critical symbol
+    5,6,7,7,5,3,5,1,5,4,5,3,
+    4,5,6,6,4,3,5,2,3,3,5,3,
+    2,3,7,7,5,3,7,3,3,3,7,4,
+    3,2,7,5,5,3,7,3,5,3,6,3,
+    3,1,7,4,7,3,8,4,7,4,8,5,
+};
+static const Int g12CodeTable[] = {
+    12,  
+    1, 5,
+    1, 6,
+    0, 7,
+    1, 7,
+    4, 5,
+    2, 3,
+    5, 5,
+    1, 1,
+    6, 5,
+    1, 4,
+    7, 5,
+    3, 3,
+
+    12,
+    2, 4,
+    2, 5,
+    0, 6,
+    1, 6,
+    3, 4,
+    2, 3,
+    3, 5,
+    3, 2,
+    3, 3,
+    4, 3,
+    1, 5,
+    5, 3,
+
+    12,
+    3, 2,
+    1, 3,
+    0, 7,
+    1, 7,
+    1, 5,
+    2, 3,
+    2, 7,
+    3, 3,
+    4, 3,
+    5, 3,
+    3, 7,
+    1, 4,
+
+    12,
+    1, 3,
+    3, 2,
+    0, 7,
+    1, 5,
+    2, 5,
+    2, 3,
+    1, 7,
+    3, 3,
+    3, 5,
+    4, 3,
+    1, 6,
+    5, 3,
+
+    12,
+    2, 3,
+    1, 1,
+    1, 7,
+    1, 4,
+    2, 7,
+    3, 3,
+    0, 8,
+    2, 4,
+    3, 7,
+    3, 4,
+    1, 8,
+    1, 5
+};
+static const Int g12DeltaTable[] = {
+    1, 1, 1, 1, 1, 0, 0,-1, 2, 1, 0, 0,
+    2, 2,-1,-1,-1, 0,-2,-1, 0, 0,-2,-1,
+   -1, 1, 0, 2, 0, 0, 0, 0,-2, 0, 1, 1,
+    0, 1, 0, 1,-2, 0,-1,-1,-2,-1,-2,-2
+};
+
+/**********************************************************************
+  Adapt fixed length codes based on discriminant
+**********************************************************************/
+static const Int THRESHOLD = 8;
+static const Int MEMORY = 8;
+ 
+Void AdaptDiscriminant (CAdaptiveHuffman *pAdHuff)
+{
+    Int iSym = pAdHuff->m_iNSymbols, t, dL, dH;
+    const Int *pCodes, *pDelta = NULL;
+    Bool bChange = FALSE;
+    static const Int gMaxTables[] = { 0,0,0,0, 1,2, 4,2, 2,2, 0,0,5 };
+    static const Int gSecondDisc[]= { 0,0,0,0, 0,0, 1,0, 0,0, 0,0,1 };
+
+    if (!pAdHuff->m_bInitialize) {
+        pAdHuff->m_bInitialize = 1;
+        pAdHuff->m_iDiscriminant = pAdHuff->m_iDiscriminant1 = 0;
+        pAdHuff->m_iTableIndex = gSecondDisc[iSym];//(gMaxTables[iSym] - 1) >> 1;
+    }
+
+    dL = dH = pAdHuff->m_iDiscriminant;
+    if (gSecondDisc[iSym]) {
+        dH = pAdHuff->m_iDiscriminant1;
+    }
+
+    if (dL < pAdHuff->m_iLowerBound) {
+        pAdHuff->m_iTableIndex--;
+        bChange = TRUE;
+    }
+    else if (dH > pAdHuff->m_iUpperBound) {
+        pAdHuff->m_iTableIndex++;
+        bChange = TRUE;
+    }
+    if (bChange) {
+    /** if initialization is fixed, we can exit on !bChange **/
+        pAdHuff->m_iDiscriminant = 0;
+        pAdHuff->m_iDiscriminant1 = 0;
+    }
+    {
+        if (pAdHuff->m_iDiscriminant < -THRESHOLD * MEMORY)
+            pAdHuff->m_iDiscriminant = -THRESHOLD * MEMORY;
+        else if (pAdHuff->m_iDiscriminant > THRESHOLD * MEMORY)
+            pAdHuff->m_iDiscriminant = THRESHOLD * MEMORY;
+
+        if (pAdHuff->m_iDiscriminant1 < -THRESHOLD * MEMORY)
+            pAdHuff->m_iDiscriminant1 = -THRESHOLD * MEMORY;
+        else if (pAdHuff->m_iDiscriminant1 > THRESHOLD * MEMORY)
+            pAdHuff->m_iDiscriminant1 = THRESHOLD * MEMORY;
+    }
+
+    t = pAdHuff->m_iTableIndex;
+    assert (t >= 0);
+    assert (t < gMaxTables[iSym]);
+
+    //pAdHuff->m_iDiscriminant >>= 1;
+    pAdHuff->m_iLowerBound = (t == 0) ? (-1 << 31) : -THRESHOLD;
+    pAdHuff->m_iUpperBound = (t == gMaxTables[iSym] - 1) ? (1 << 30) : THRESHOLD;
+
+    switch (iSym) {
+        case 4:
+            pCodes = g4CodeTable;
+            pAdHuff->m_hufDecTable = (short *) g4HuffLookupTable;
+            break;
+        case 5:
+            pCodes = g5CodeTable + (iSym * 2 + 1) * t;
+            pDelta = g5DeltaTable;
+            pAdHuff->m_hufDecTable = g5HuffLookupTable[t];
+            break;
+        case 6:
+            pCodes = g6CodeTable + (iSym * 2 + 1) * t;
+            pAdHuff->m_pDelta1 = g6DeltaTable + iSym * (t - (t + 1 == gMaxTables[iSym]));
+            pDelta = g6DeltaTable + (t - 1 + (t == 0)) * iSym;
+            pAdHuff->m_hufDecTable = g6HuffLookupTable[t];
+            break;
+        case 7:
+            pCodes = g7CodeTable + (iSym * 2 + 1) * t;
+            pDelta = g7DeltaTable;
+            pAdHuff->m_hufDecTable = g7HuffLookupTable[t];
+            break;
+        case 8:
+            //printf ("%d ", t);
+            pCodes = g8CodeTable;// + (iSym * 2 + 1) * t;
+            //pDelta = g8DeltaTable;
+            pAdHuff->m_hufDecTable = g8HuffLookupTable[0];
+            break;
+        case 9:
+            pCodes = g9CodeTable + (iSym * 2 + 1) * t;
+            pDelta = g9DeltaTable;
+            pAdHuff->m_hufDecTable = g9HuffLookupTable[t];
+            break;
+        case 12:
+            pCodes = g12CodeTable + (iSym * 2 + 1) * t;
+            pAdHuff->m_pDelta1 = g12DeltaTable + iSym * (t - (t + 1 == gMaxTables[iSym]));
+            pDelta = g12DeltaTable + (t - 1 + (t == 0)) * iSym;
+            pAdHuff->m_hufDecTable = g12HuffLookupTable[t];
+            break;
+        default:
+            assert (0); // undefined fixed length table
+            return;
+    }
+
+    pAdHuff->m_pTable = pCodes;
+    pAdHuff->m_pDelta = pDelta;
+}
+
diff --git a/Source/LibJXR/image/sys/ansi.h b/Source/LibJXR/image/sys/ansi.h
new file mode 100644
index 0000000..74900c9
--- /dev/null
+++ b/Source/LibJXR/image/sys/ansi.h
@@ -0,0 +1,61 @@
+//*@@@+++@@@@******************************************************************
+//
+// Copyright � Microsoft Corp.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+// � Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// � Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//*@@@---@@@@******************************************************************
+#pragma once
+
+//================================
+// bitio functions
+//================================
+#define PACKETLENGTH (1U<<12)   // 4kB
+
+#define readIS_L1(pSC, pIO) readIS(pSC, pIO)
+#define readIS_L2(pSC, pIO) (void)(pSC, pIO)
+
+#define writeIS_L1(pSC, pIO) writeIS(pSC, pIO)
+#define writeIS_L2(pSC, pIO) (void)(pSC, pIO)
+
+
+//================================
+// common defines
+//================================
+#define FORCE_INLINE
+#define CDECL
+#if __LP64__
+#define UINTPTR_T unsigned long long
+#define INTPTR_T long long
+#else
+#define UINTPTR_T unsigned int
+#define INTPTR_T int
+#endif
+
+
+//================================
+// quantization optimization
+//================================
+//#define RECIP_QUANT_OPT
+
+
diff --git a/Source/LibJXR/image/sys/common.h b/Source/LibJXR/image/sys/common.h
new file mode 100644
index 0000000..2d7dd2a
--- /dev/null
+++ b/Source/LibJXR/image/sys/common.h
@@ -0,0 +1,131 @@
+//*@@@+++@@@@******************************************************************
+//
+// Copyright � Microsoft Corp.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+// � Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// � Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//*@@@---@@@@******************************************************************
+
+#ifndef WMI_COMMON_H
+#define WMI_COMMON_H
+
+/*************************************************************************
+// Common typedef's
+*************************************************************************/
+typedef enum  { ENCODER = 0, DECODER = 1 } CODINGMODE;
+
+typedef enum tagBand
+{
+    BAND_HEADER = 0,
+    BAND_DC = 1,
+    BAND_LP = 2,
+    BAND_AC = 3,
+    BAND_FL = 4
+} BAND;
+
+/*************************************************************************
+    struct / class definitions
+*************************************************************************/
+//#define SIGNATURE_BYTES 8   // Bytes for GDI+ signature
+#define CODEC_VERSION 1
+#define CODEC_SUBVERSION 0
+#define CODEC_SUBVERSION_NEWSCALING_SOFT_TILES 1
+#define CODEC_SUBVERSION_NEWSCALING_HARD_TILES 9
+
+#define CONTEXTX 8
+#define CTDC 5
+#define NUMVLCTABLES 21 // CONTEXTX * 2 + CTDC
+#define AVG_NDIFF 3
+
+#define MAXTOTAL 32767 // 511 should be enough
+
+/** Quantization related defines **/
+#define SHIFTZERO 1 /* >= 0 */
+#define QPFRACBITS 2  /* or 0 only supported */
+
+/** adaptive huffman encoding / decoding struct **/
+typedef struct CAdaptiveHuffman
+{
+    Int     m_iNSymbols;
+    const Int *m_pTable;
+    const Int *m_pDelta, *m_pDelta1;
+    Int     m_iTableIndex;
+    const short *m_hufDecTable;
+    Bool    m_bInitialize;
+    //Char    m_pLabel[8]; // for debugging - label attached to constructor
+
+    Int     m_iDiscriminant, m_iDiscriminant1;
+    Int     m_iUpperBound;
+    Int     m_iLowerBound;
+} CAdaptiveHuffman;
+
+
+/************************************************************************************
+  Context structures
+************************************************************************************/
+typedef struct CAdaptiveModel {
+    Int     m_iFlcState[2];
+    Int     m_iFlcBits[2];
+    BAND    m_band;
+} CAdaptiveModel;
+
+typedef struct CCBPModel {
+    Int     m_iCount0[2];
+    Int     m_iCount1[2];
+    Int     m_iState[2];
+} CCBPModel;
+
+/*************************************************************************
+    globals
+*************************************************************************/
+extern Int grgiZigzagInv4x4_lowpass[];
+extern Int grgiZigzagInv4x4H[];
+extern Int grgiZigzagInv4x4V[];
+extern const Int gSignificantRunBin[];
+extern const Int gSignificantRunFixedLength[];
+static const Int cblkChromas[] = {0,4,8,16, 16,16,16, 0,0};
+/*************************************************************************
+    function declarations
+*************************************************************************/
+// common utilities
+Void Clean (CAdaptiveHuffman *pAdHuff);
+CAdaptiveHuffman *Allocate (Int iNSymbols, CODINGMODE cm);
+
+/* Timing functions */
+void    reset_timing(double *time);
+void    report_timing(const char *s, double time);
+// static double   timeperclock;
+
+/** adaptive model functions **/
+Void UpdateModelMB (COLORFORMAT cf, Int iChannels, Int iLaplacianMean[], CAdaptiveModel *m_pModel);
+
+/** adaptive huffman encoder / decoder functions **/
+Void Adapt (CAdaptiveHuffman *pAdHuff, Bool bFixedTables);
+Void AdaptFixed (CAdaptiveHuffman *pAdHuff);
+Void AdaptDiscriminant (CAdaptiveHuffman *pAdHuff);
+
+#ifndef _PREFAST_
+#pragma warning(disable:4068)
+#endif
+
+#endif  // WMI_COMMON_H
diff --git a/Source/LibJXR/image/sys/image.c b/Source/LibJXR/image/sys/image.c
new file mode 100644
index 0000000..c819cbc
--- /dev/null
+++ b/Source/LibJXR/image/sys/image.c
@@ -0,0 +1,183 @@
+//*@@@+++@@@@******************************************************************
+//
+// Copyright � Microsoft Corp.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+// � Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// � Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//*@@@---@@@@******************************************************************
+
+#include "strcodec.h"
+// #include "xplatform_image.h"
+
+#ifdef MEM_TRACE
+#define TRACE_MALLOC    1
+#define TRACE_NEW       0
+#define TRACE_HEAP      0
+#include "memtrace.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#if !(defined(__ANSI__))
+// Desktop
+#include <windows.h>
+#else
+// ANSI
+#include <time.h>
+#endif  
+
+Int grgiZigzagInv4x4_lowpass [] = {
+    0, 1, 4, 5, 2, 8, 6, 9,
+    3, 12, 10, 7, 13, 11, 14, 15
+};
+
+Int grgiZigzagInv4x4H [] = {
+    0, 1, 4, 5, 2, 8, 6, 9,
+    3, 12, 10, 7, 13, 11, 14, 15
+};
+Int grgiZigzagInv4x4V [] = {
+    0, 4, 8, 5,  1, 12, 9, 6,  2, 13, 3, 15,  7, 10, 14, 11
+};
+    
+const Int gSignificantRunBin[] = { 
+    -1,-1,-1,-1,
+    2,2,2,
+    1,1,1,1,
+    0,0,0,0    
+};
+
+const Int gSignificantRunFixedLength[] = {
+    0,0,1,1,3,
+    0,0,1,1,2,
+    0,0,0,0,1,
+};
+
+/*************************************************************************
+    UpdateModelMB : update adaptive model at end of macroblock
+    (for lowest resolution only)
+*************************************************************************/
+#define MODELWEIGHT 70//90
+
+Void UpdateModelMB (COLORFORMAT cf, Int iChannels, Int iLaplacianMean[], CAdaptiveModel *pModel)
+{
+    Int j;
+    static const Int aWeight0[3] = { 240/*DC*/, 12/*LP*/, 1 };
+    static const Int aWeight1[3][MAX_CHANNELS] = {
+        { 0,240,120,80, 60,48,40,34, 30,27,24,22, 20,18,17,16 },
+        { 0,12,6,4,     3,2,2,2,     2,1,1,1,     1,1,1,1 },
+        { 0,16,8,5,     4,3,3,2,     2,2,2,1,     1,1,1,1 }
+    };
+    static const Int aWeight2[6] = { 120,37,2,/*420*/ 120,18,1/*422*/ };
+
+    iLaplacianMean[0] *= aWeight0[pModel->m_band - BAND_DC];
+    if (cf == YUV_420) {
+        iLaplacianMean[1] *= aWeight2[pModel->m_band - BAND_DC];
+    }
+    else if (cf == YUV_422) {
+        iLaplacianMean[1] *= aWeight2[3 + (pModel->m_band) - BAND_DC];
+    }
+    else {
+        iLaplacianMean[1] *= aWeight1[pModel->m_band - BAND_DC][iChannels - 1];
+        if (pModel->m_band == BAND_AC)
+            iLaplacianMean[1] >>= 4;
+    }
+
+    for (j = 0; j < 2; j++) {
+        Int iLM = iLaplacianMean[j];
+        Int iMS = pModel->m_iFlcState[j];
+        Int iDelta = (iLM - MODELWEIGHT) >> 2;
+
+        if (iDelta <= -8) {
+            iDelta += 4;
+            if (iDelta < -16)
+                iDelta = -16;
+            iMS += iDelta;
+            if (iMS < -8) {
+                if (pModel->m_iFlcBits[j] == 0)
+                    iMS = -8;
+                else {
+                    iMS = 0;
+                    pModel->m_iFlcBits[j]--;
+                }
+            }
+        }
+        else if (iDelta >= 8) {
+            iDelta -= 4;
+            if (iDelta > 15)
+                iDelta = 15;
+            iMS += iDelta;
+            if (iMS > 8) {
+                if (pModel->m_iFlcBits[j] >= 15) {
+                    pModel->m_iFlcBits[j] = 15;
+                    iMS = 8;
+                }
+                else {
+                    iMS = 0;
+                    pModel->m_iFlcBits[j]++;
+                }
+            }
+        }
+        pModel->m_iFlcState[j] = iMS;
+        if (cf == Y_ONLY)
+            break;
+    }
+}
+
+
+Void ResetCodingContext(CCodingContext *pContext)
+{
+    // reset bit reduction models
+    memset (&(pContext->m_aModelAC), 0, sizeof(CAdaptiveModel));  
+    pContext->m_aModelAC.m_band = BAND_AC;
+
+    memset (&(pContext->m_aModelLP), 0, sizeof(CAdaptiveModel));  
+    pContext->m_aModelLP.m_band = BAND_LP;
+    pContext->m_aModelLP.m_iFlcBits[0] = pContext->m_aModelLP.m_iFlcBits[1] = 4;
+
+    memset (&(pContext->m_aModelDC), 0, sizeof(CAdaptiveModel));  
+    pContext->m_aModelDC.m_band = BAND_DC;
+    pContext->m_aModelDC.m_iFlcBits[0] = pContext->m_aModelDC.m_iFlcBits[1] = 8;
+
+    // reset CBP models
+    pContext->m_iCBPCountMax = pContext->m_iCBPCountZero = 1;
+
+    pContext->m_aCBPModel.m_iCount0[0] = pContext->m_aCBPModel.m_iCount0[1] = -4;
+    pContext->m_aCBPModel.m_iCount1[0] = pContext->m_aCBPModel.m_iCount1[1] = 4;
+    pContext->m_aCBPModel.m_iState[0] = pContext->m_aCBPModel.m_iState[1] = 0;
+}
+
+/*************************************************************************
+    Initialize zigzag scan parameters
+*************************************************************************/
+Void InitZigzagScan(CCodingContext * pContext)
+{
+    if (NULL != pContext) {
+        Int i;
+        for (i=0; i<16; i++) {
+            pContext->m_aScanLowpass[i].uScan = grgiZigzagInv4x4_lowpass[i];
+            pContext->m_aScanHoriz[i].uScan = dctIndex[0][grgiZigzagInv4x4H[i]];
+            pContext->m_aScanVert[i].uScan  = dctIndex[0][grgiZigzagInv4x4V[i]];
+        }
+    }
+}
diff --git a/Source/LibJXR/image/sys/perfTimer.h b/Source/LibJXR/image/sys/perfTimer.h
new file mode 100644
index 0000000..af7eac2
--- /dev/null
+++ b/Source/LibJXR/image/sys/perfTimer.h
@@ -0,0 +1,115 @@
+//*@@@+++@@@@******************************************************************
+//
+// Copyright � Microsoft Corp.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+// � Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// � Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//*@@@---@@@@******************************************************************
+
+#ifndef __PERFTIMER_H_
+#define __PERFTIMER_H_
+
+//***************************************************************************
+// Description
+//
+//   Performance timer API used to measure codec performance. The underlying
+// implementation of this API may vary - from ANSI-C implementation via clock,
+// Win32 implementation via QueryPerformanceCounter or GetProcessTimes. At
+// present we only support one implementation of this PerfTimer "object".
+// You choose the implementation by choosing which one of the many files
+// to compile and link with your application.
+//***************************************************************************
+
+#ifdef DISABLE_PERF_MEASUREMENT
+
+#define PERFTIMER_ONLY(code)
+#define PERFTIMER_NEW(fPerf, ppPerfTimer)
+#define PERFTIMER_DELETE(fPerf, ppPerfTimer)
+#define PERFTIMER_START(fPerf, pPerfTimer)
+#define PERFTIMER_STOP(fPerf, pPerfTimer)
+#define PERFTIMER_GETRESULTS(fPerf, pPerfTimer, pResults)
+#define PERFTIMER_COPYSTARTTIME(fPerf, pDst, pSrc)
+#define PERFTIMER_REPORT(fPerf, pCodec)
+
+#else // DISABLE_PERF_MEASUREMENT
+
+#define PERFTIMER_ONLY(code) code
+#define PERFTIMER_NEW(fPerf, ppPerfTimer)    if (fPerf) {Bool b = b = PerfTimerNew(ppPerfTimer); assert(b);};
+#define PERFTIMER_DELETE(fPerf, pPerfTimer)  if (fPerf) {PerfTimerDelete(pPerfTimer);};
+#define PERFTIMER_START(fPerf, pPerfTimer)   if (fPerf) {Bool b = b = PerfTimerStart(pPerfTimer); assert(b);};
+#define PERFTIMER_STOP(fPerf, pPerfTimer)    if (fPerf) {Bool b = b = PerfTimerStop(pPerfTimer); assert(b);};
+#define PERFTIMER_GETRESULTS(fPerf, pPerfTimer, pResults) \
+    if (fPerf) {Bool b = b = PerfTimerGetResults((pPerfTimer), (pResults)); assert(b);};
+#define PERFTIMER_COPYSTARTTIME(fPerf, pDst, pSrc) \
+    if (fPerf) {Bool b = b = PerfTimerCopyStartTime((pDst), (pSrc)); assert(b);};
+#define PERFTIMER_REPORT(fPerf, pCodec) \
+    if (fPerf) {OutputPerfTimerReport(pCodec);};
+#endif // DISABLE_PERF_MEASUREMENT
+
+//***************************************************************************
+// Data Types
+//***************************************************************************
+typedef U64 PERFTIMERTIME;
+typedef struct PERFTIMERRESULTS
+{
+    PERFTIMERTIME   iElapsedTime;       // In nanoseconds or CPU cycles
+    PERFTIMERTIME   iTicksPerSecond;    // Number of ticks per second (clock frequency)
+    PERFTIMERTIME   iZeroTimeIntervals; // Number of zero-time intervals.
+        // Presence of zero-time intervals may indicate insufficient clock precision
+} PERFTIMERRESULTS;
+
+#define NANOSECONDS_PER_SECOND  1000000000
+
+
+//***************************************************************************
+// Data Declarations
+//***************************************************************************
+typedef enum
+{
+    CS_UNINIT,
+    CS_RUNNING,
+    CS_STOPPED,
+} CLOCKSTATE;
+
+typedef struct PERFTIMERSTATE
+{
+    CLOCKSTATE          eState;
+    PERFTIMERTIME       iElapsedTime;
+    PERFTIMERTIME       iPrevStartTime;
+    PERFTIMERTIME       iZeroTimeIntervals;
+} PERFTIMERSTATE;
+
+
+//***************************************************************************
+// Functions and Macros
+//***************************************************************************
+Bool PerfTimerNew(PERFTIMERSTATE **ppNewPerfTimer);
+void PerfTimerDelete(PERFTIMERSTATE *pThisPerfTimer);
+Bool PerfTimerStart(PERFTIMERSTATE *pThisPerfTimer);
+Bool PerfTimerStop(PERFTIMERSTATE *pThisPerfTimer);
+Bool PerfTimerGetResults(PERFTIMERSTATE *pThisPerfTimer,
+                         PERFTIMERRESULTS *pPerfTimerResults);
+Bool PerfTimerCopyStartTime(PERFTIMERSTATE *pDestPerfTimer,
+                            PERFTIMERSTATE *pSrcPerfTimer);
+
+#endif // __PERFTIMER_H_
diff --git a/Source/LibJXR/image/sys/perfTimerANSI.c b/Source/LibJXR/image/sys/perfTimerANSI.c
new file mode 100644
index 0000000..2f7209a
--- /dev/null
+++ b/Source/LibJXR/image/sys/perfTimerANSI.c
@@ -0,0 +1,274 @@
+//*@@@+++@@@@******************************************************************
+//
+// Copyright � Microsoft Corp.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+// � Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// � Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//*@@@---@@@@******************************************************************
+
+//***************************************************************************
+// Includes
+//***************************************************************************
+#include <time.h>
+#include "strcodec.h"
+#include "perfTimer.h"
+
+
+#ifndef DISABLE_PERF_MEASUREMENT
+
+
+//***************************************************************************
+// Private Functions
+//***************************************************************************
+
+Bool AccumulateTime(PERFTIMERSTATE *pState, PERFTIMERTIME *ptAccumulator)
+{
+    Bool        fResult = FALSE;
+    clock_t     iStopTime;
+    clock_t     iIntervalTime;
+    iStopTime = clock();
+
+    // Check clock result
+    if ((clock_t)-1 == iStopTime)
+    {
+        TraceResult(WM_E_CLOCKFAILURE);
+        goto exit;
+    }
+
+    iIntervalTime = (iStopTime - (clock_t) pState->iPrevStartTime);
+
+    // Check for zero-time interval
+    if (0 == iIntervalTime)
+        pState->iZeroTimeIntervals += 1;
+
+    // Accumulate current interval's time
+    *ptAccumulator += iIntervalTime;
+    fResult = TRUE;
+
+exit:
+    return fResult;
+}
+
+
+//***************************************************************************
+// Public Functions
+//***************************************************************************
+
+
+Bool PerfTimerNew(PERFTIMERSTATE **ppNewPerfTimer)
+{
+    Bool            fResult = FALSE;
+    PERFTIMERSTATE *pState = NULL;
+    clock_t         ctResult;
+
+    // Check if this clock works
+    ctResult = clock();
+    if ((clock_t)-1 == ctResult)
+    {
+        TraceResult(WM_E_CLOCKFAILURE);
+        goto exit;
+    }
+
+    pState = malloc(sizeof(*pState));
+    if (NULL == pState)
+    {
+        TraceResult(E_OUTOFMEMORY);
+        goto exit;
+    }
+    memset(pState, 0, sizeof(*pState));
+    pState->eState = CS_STOPPED;
+    pState->iElapsedTime = 0;
+    pState->iPrevStartTime = 0;
+    pState->iZeroTimeIntervals = 0;
+
+    *ppNewPerfTimer = pState;
+    fResult = TRUE;
+
+exit:
+    assert(fResult || NULL == pState); // If error, we need to free pState
+    return fResult;
+} // PerfTimerNew
+
+
+
+void PerfTimerDelete(PERFTIMERSTATE *pState)
+{
+    free(pState);
+} // PerfTimerDelete
+
+
+
+Bool PerfTimerStart(PERFTIMERSTATE *pState)
+{
+    Bool fResult = FALSE;
+
+    if (NULL == pState)
+    {
+        // Can happen because we typically ignore errors and use a single bool to
+        // control all perf timing (some of which can fail to init)
+        goto exit;
+    }
+
+    // Make sure we are in the right state
+    if (CS_STOPPED != pState->eState)
+    {
+        assert(FALSE);
+        goto exit;
+    }
+
+    pState->iPrevStartTime = clock();
+
+    // Check clock result
+    if ((clock_t)-1 == pState->iPrevStartTime)
+    {
+        TraceResult(WM_E_CLOCKFAILURE);
+        goto exit;
+    }
+
+    pState->eState = CS_RUNNING;
+    fResult = TRUE;
+
+exit:
+    return fResult;
+} // PerfTimerStart
+
+
+
+Bool PerfTimerStop(PERFTIMERSTATE *pState)
+{
+    Bool        fResult = FALSE;
+
+    if (NULL == pState)
+    {
+        // Can happen because we typically ignore errors and use a single bool to
+        // control all perf timing (some of which can fail to init)
+        goto exit;
+    }
+
+    // Make sure we are in the right state
+    if (CS_RUNNING != pState->eState)
+    {
+        assert(FALSE);
+        goto exit;
+    }
+
+    fResult = AccumulateTime(pState, &pState->iElapsedTime);
+    pState->eState = CS_STOPPED;
+    fResult = TRUE;
+
+exit:
+    return fResult;
+} // PerfTimerStop
+
+
+
+Bool PerfTimerGetResults(PERFTIMERSTATE *pState, PERFTIMERRESULTS *pResults)
+{
+    Bool            fResult = FALSE;
+    PERFTIMERTIME   iElapsedTime;
+
+    if (NULL == pState)
+    {
+        // Can happen because we typically ignore errors and use a single bool to
+        // control all perf timing (some of which can fail to init)
+        goto exit;
+    }
+
+    // Make sure we are in the right state
+    if (CS_STOPPED != pState->eState && CS_RUNNING != pState->eState)
+    {
+        assert(FALSE);
+        goto exit;
+    }
+
+    iElapsedTime = pState->iElapsedTime;
+    if (CS_RUNNING == pState->eState)
+    {
+        // Must take a "checkpoint" time reading
+        fResult = AccumulateTime(pState, &iElapsedTime);
+        if (FALSE == fResult)
+            goto exit;
+    }
+
+    // Convert clock ticks to nanoseconds.
+    // Use floating point for ease of math. If your platform really blows
+    // with floating point, replace this with appropriate integer calculation
+    // based on your clock interval.
+    pResults->iElapsedTime = (PERFTIMERTIME)((float)iElapsedTime *
+        ((float)NANOSECONDS_PER_SECOND / (float)CLOCKS_PER_SEC));
+    pResults->iTicksPerSecond = CLOCKS_PER_SEC;
+    pResults->iZeroTimeIntervals = pState->iZeroTimeIntervals;
+    fResult = TRUE;
+
+exit:
+    return fResult;
+} // PerfTimerGetResults
+
+
+
+Bool PerfTimerCopyStartTime(PERFTIMERSTATE *pDestPerfTimer,
+                            PERFTIMERSTATE *pSrcPerfTimer)
+{
+    Bool    fResult = FALSE;
+
+    if (NULL == pDestPerfTimer)
+    {
+        TraceResult(E_INVALIDARG);
+        goto exit;
+    }
+
+    if (NULL == pSrcPerfTimer)
+    {
+        TraceResult(E_INVALIDARG);
+        goto exit;
+    }
+
+    // Check that both timers are in proper state - both must be running
+    if (CS_RUNNING != pDestPerfTimer->eState)
+    {
+        TraceResult(WM_E_INVALIDSTATE);
+        goto exit;
+    }
+
+    if (CS_RUNNING != pSrcPerfTimer->eState)
+    {
+        TraceResult(WM_E_INVALIDSTATE);
+        goto exit;
+    }
+
+    if (0 != pDestPerfTimer->iElapsedTime)
+    {
+        // If iElapsedTime is non-zero, caller won't get what he is expecting
+        // when he calls PerfTimerGetResults
+        TraceResult(WM_E_INVALIDSTATE);
+        goto exit;
+    }
+
+    pDestPerfTimer->iPrevStartTime = pSrcPerfTimer->iPrevStartTime;
+    fResult = TRUE;
+
+exit:
+    return fResult;
+} // PerfTimerCopyStartTime
+
+#endif // DISABLE_PERF_MEASUREMENT
diff --git a/Source/LibJXR/image/sys/strPredQuant.c b/Source/LibJXR/image/sys/strPredQuant.c
new file mode 100644
index 0000000..6ff8167
--- /dev/null
+++ b/Source/LibJXR/image/sys/strPredQuant.c
@@ -0,0 +1,306 @@
+//*@@@+++@@@@******************************************************************
+//
+// Copyright � Microsoft Corp.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+// � Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// � Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//*@@@---@@@@******************************************************************
+
+#include "strcodec.h"
+
+#define ORIENT_WEIGHT 4
+
+/* reciprocal (pMantissa, exponent) lookup table */
+typedef struct tagQPManExp
+{
+    int iMan;
+    int iExp;
+} QPManExp;
+
+static QPManExp gs_QPRecipTable[32] = {
+    {0x0, 0}, // 0, invalid
+    {0x0, 0}, // 1, lossless
+    {0x0, 1}, // 2
+    {0xaaaaaaab, 1},
+    {0x0, 2}, // 4
+    {0xcccccccd, 2},
+    {0xaaaaaaab, 2},
+    {0x92492493, 2},
+    {0x0, 3}, // 8
+    {0xe38e38e4, 3},
+    {0xcccccccd, 3},
+    {0xba2e8ba3, 3},
+    {0xaaaaaaab, 3},
+    {0x9d89d89e, 3},
+    {0x92492493, 3},
+    {0x88888889, 3},
+    {0x0, 4}, // 16
+    {0xf0f0f0f1, 4},
+    {0xe38e38e4, 4},
+    {0xd79435e6, 4},
+    {0xcccccccd, 4},
+    {0xc30c30c4, 4},
+    {0xba2e8ba3, 4},
+    {0xb21642c9, 4},
+    {0xaaaaaaab, 4},
+    {0xa3d70a3e, 4},
+    {0x9d89d89e, 4},
+    {0x97b425ee, 4},
+    {0x92492493, 4},
+    {0x8d3dcb09, 4},
+    {0x88888889, 4},
+    {0x84210843, 4},
+};
+
+/*************************************************************************
+    QPRemapping
+*************************************************************************/
+
+Void remapQP(CWMIQuantizer * pQP, I32 iShift, Bool bScaledArith)
+{
+    U8 uiQPIndex = pQP->iIndex;
+
+    if(uiQPIndex == 0) // Lossless mode!
+        pQP->iQP = 1, pQP->iMan = pQP->iExp = pQP->iOffset = 0;
+    else if (!bScaledArith) {
+        I32 man = 0, exp = 0;
+        const I32 ciShift = SHIFTZERO - (SHIFTZERO + QPFRACBITS); // == -QPFRACBITS
+
+        if (pQP->iIndex < 32)
+            man = (pQP->iIndex + 3) >> 2, exp = ciShift + 2;
+        else if (pQP->iIndex < 48)
+            man = (16 + (pQP->iIndex & 0xf) + 1) >> 1, exp = ((pQP->iIndex >> 4) - 1) + 1 + ciShift;
+        else
+            man = 16 + (pQP->iIndex & 0xf), exp = ((pQP->iIndex >> 4) - 1) + ciShift;
+
+        pQP->iQP = man << exp;
+        pQP->iMan = gs_QPRecipTable[man].iMan;
+        pQP->iExp = gs_QPRecipTable[man].iExp + exp;
+        pQP->iOffset = ((pQP->iQP * 3 + 1) >> 3);
+#if defined(WMP_OPT_QT)
+        pQP->f1_QP = 1.0f / pQP->iQP;
+        pQP->d1_QP = 1.0 / pQP->iQP;
+#endif    
+    }
+    else {
+        I32 man = 0, exp = 0;
+
+        if(pQP->iIndex < 16)
+            man = pQP->iIndex, exp = iShift;
+        else
+            man = 16 + (pQP->iIndex & 0xf), exp = ((pQP->iIndex >> 4) - 1) + iShift;
+        
+        pQP->iQP = man << exp;
+        pQP->iMan = gs_QPRecipTable[man].iMan;
+        pQP->iExp = gs_QPRecipTable[man].iExp + exp;
+        pQP->iOffset = ((pQP->iQP * 3 + 1) >> 3);
+#if defined(WMP_OPT_QT)
+        pQP->f1_QP = 1.0f / pQP->iQP;
+        pQP->d1_QP = 1.0 / pQP->iQP;
+#endif    
+    }
+}
+
+/* allocate PredInfo buffers */
+Int allocatePredInfo(CWMImageStrCodec *pSC)
+{
+    size_t i, j;
+    // COLORFORMAT cf = pSC->m_param.cfColorFormat;
+    const size_t mbWidth = pSC->cmbWidth;
+    const size_t iChannels = pSC->m_param.cNumChannels;
+    CWMIPredInfo* pMemory;
+    Bool b32Bit = sizeof(size_t) == 4;
+    
+    if(b32Bit) // integer overlow/underflow check for 32-bit system
+        if(((mbWidth >> 16) * iChannels * 2 * sizeof(CWMIPredInfo)) & 0xffff0000)
+            return ICERR_ERROR;    
+    pMemory = (CWMIPredInfo *)malloc(mbWidth * iChannels * 2 * sizeof(CWMIPredInfo));
+    if (pMemory == NULL)
+        return ICERR_ERROR;
+
+    pSC->pPredInfoMemory = pMemory;
+    for(i = 0; i < iChannels; i ++){
+        pSC->PredInfo[i] = pMemory;
+        pMemory += mbWidth;
+        pSC->PredInfoPrevRow[i] = pMemory;
+        pMemory += mbWidth;
+        
+        for(j = 0; j < mbWidth; j ++){
+            pSC->PredInfo[i][j].piAD = pSC->PredInfo[i][j].iAD;
+            pSC->PredInfoPrevRow[i][j].piAD = pSC->PredInfoPrevRow[i][j].iAD;
+        }
+    }
+    
+    return ICERR_OK;
+}
+
+/* clear PredInfo buffers */
+Void freePredInfo(CWMImageStrCodec *pSC)
+{
+    if (pSC->pPredInfoMemory)
+        free (pSC->pPredInfoMemory);
+    pSC->pPredInfoMemory = NULL;
+}
+
+/* get AC prediction mode: 0(from left) 1(from top) 2(none) */
+Int getACPredMode(CWMIMBInfo * pMBInfo, COLORFORMAT cf)
+{
+    //Int blkIdx = (cf == Y_ONLY ? 16 : (cf == YUV_420 ? 24 : (cf == YUV_422 ? 32 : 48)));
+    PixelI * pCoeffs = pMBInfo->iBlockDC[0];
+    Int StrH = abs(pCoeffs[1]) + abs(pCoeffs[2]) + abs(pCoeffs[3]);
+    Int StrV = abs(pCoeffs[4]) + abs(pCoeffs[8]) + abs(pCoeffs[12]);
+
+    if(cf != Y_ONLY && cf != NCOMPONENT){
+        PixelI * pCoeffsU = pMBInfo->iBlockDC[1];
+        PixelI * pCoeffsV = pMBInfo->iBlockDC[2];
+
+        StrH += abs(pCoeffsU[1]) + abs(pCoeffsV[1]);
+        if(cf == YUV_420){
+            StrV += abs(pCoeffsU[2]) + abs(pCoeffsV[2]);
+        }
+        else if (cf == YUV_422){
+            StrV += abs(pCoeffsU[2]) + abs(pCoeffsV[2]) + abs(pCoeffsU[6]) + abs(pCoeffsV[6]);
+            StrH += abs(pCoeffsU[5]) + abs(pCoeffsV[5]);
+        }
+        else { // YUV_444 or CMYK
+            StrV += abs(pCoeffsU[4]) + abs(pCoeffsV[4]);
+        }
+    }
+
+    return (StrH * ORIENT_WEIGHT < StrV ? 1 : (StrV * ORIENT_WEIGHT < StrH ? 0 : 2));
+}
+
+/* get DCAC prediction mode: 0(from left) 1(from top) 2(none) */
+Int getDCACPredMode(CWMImageStrCodec *pSC, size_t mbX)
+{
+    Int iDCMode, iADMode = 2;  // DC: 0(left) 1(top) 2(mean) 3(no)
+                               // AD: 0(left) 1(top) 2(no)
+
+    if(pSC->m_bCtxLeft && pSC->m_bCtxTop){ // topleft corner, no prediction
+        iDCMode = 3;
+    }
+    else if(pSC->m_bCtxLeft){
+        iDCMode = 1; // left column, predict from top
+    }
+    else if(pSC->m_bCtxTop){
+        iDCMode = 0; // top row, predict from left
+    }
+    else{
+        COLORFORMAT cf = pSC->m_param.cfColorFormat;
+        Int iL = pSC->PredInfo[0][mbX - 1].iDC, iT = pSC->PredInfoPrevRow[0][mbX].iDC, iTL = pSC->PredInfoPrevRow[0][mbX - 1].iDC;
+        Int StrH, StrV;
+
+        if(cf == Y_ONLY || cf == NCOMPONENT){ // CMYK uses YUV metric
+            StrH = abs(iTL - iL);
+            StrV = abs(iTL - iT);
+        }
+        else{
+            CWMIPredInfo * pTU = pSC->PredInfoPrevRow[1] + mbX, * pLU = pSC->PredInfo[1] + mbX - 1, * pTLU = pTU - 1;
+            CWMIPredInfo * pTV = pSC->PredInfoPrevRow[2] + mbX, * pLV = pSC->PredInfo[2] + mbX - 1, * pTLV = pTV - 1;
+            Int scale = (cf == YUV_420 ? 8 : (cf == YUV_422 ? 4 : 2));
+
+            StrH = abs(iTL - iL) * scale + abs(pTLU->iDC - pLU->iDC) + abs(pTLV->iDC - pLV->iDC);
+            StrV = abs(iTL - iT) * scale + abs(pTLU->iDC - pTU->iDC) + abs(pTLV->iDC - pTV->iDC);
+        }
+        iDCMode = (StrH * ORIENT_WEIGHT < StrV ? 1 : (StrV * ORIENT_WEIGHT < StrH ? 0 : 2));
+    }
+
+    if(iDCMode == 1 && pSC->MBInfo.iQIndexLP == pSC->PredInfoPrevRow[0][mbX].iQPIndex)
+        iADMode = 1;
+    if(iDCMode == 0 && pSC->MBInfo.iQIndexLP == pSC->PredInfo[0][mbX - 1].iQPIndex)
+        iADMode = 0;
+
+    return (iDCMode + (iADMode << 2));
+}
+
+Void copyAC(PixelI * src, PixelI * dst)
+{
+    /* first row of ACs */
+    dst[0] = src[1];
+    dst[1] = src[2];
+    dst[2] = src[3];
+
+    /* first column of ACs */
+    dst[3] = src[4];
+    dst[4] = src[8];
+    dst[5] = src[12];
+}
+
+/* info of current MB to be saved for future prediction */
+Void updatePredInfo(CWMImageStrCodec *pSC, CWMIMBInfo * pMBInfo, size_t mbX, COLORFORMAT cf)
+{
+    CWMIPredInfo *pPredInfo;
+    PixelI * p;
+    Int  i, iChannels = (cf == YUV_420 || cf == YUV_422) ? 1 : (Int) pSC->m_param.cNumChannels;
+
+    for(i = 0; i < iChannels; i ++){
+        pPredInfo = pSC->PredInfo[i] + mbX;
+        p = pMBInfo->iBlockDC[i];//[dcBlkIdx + i];
+
+        /* DC of DC block */
+        pPredInfo->iDC = p[0];
+
+        /* QP Index */
+        pPredInfo->iQPIndex = pMBInfo->iQIndexLP;
+        
+        /* first row and first column of ACs of DC block */
+        copyAC(p, pPredInfo->piAD);
+    }
+
+    if(cf == YUV_420){ // 420 UV channels
+        for(i = 1U; i < 3U; i ++){
+            pPredInfo = pSC->PredInfo[i] + mbX;
+            p = pMBInfo->iBlockDC[i];//[dcBlkIdx + i];
+            
+            /* DC of DC block */
+            pPredInfo->iDC = p[0];
+            
+            /* QP Index */
+            pPredInfo->iQPIndex = pMBInfo->iQIndexLP;
+            /* first row and first column of ACs of DC block */
+            pPredInfo->piAD[0] = p[1];
+            pPredInfo->piAD[1] = p[2];
+        }
+    }
+    else if(cf == YUV_422){ // 420 UV channels
+        for(i = 1U; i < 3U; i ++){
+            pPredInfo = pSC->PredInfo[i] + mbX;
+
+            /* QP Index */
+            pPredInfo->iQPIndex = pMBInfo->iQIndexLP;
+
+            p = pMBInfo->iBlockDC[i];//[dcBlkIdx + i];
+
+            /* DC of DC block */
+            pPredInfo->iDC = p[0];
+            
+            /* first row and first column of ACs of first DC block */
+            pPredInfo->piAD[0] = p[1];
+            pPredInfo->piAD[1] = p[2];
+            /* first row and first column of ACs of second DC block */
+            pPredInfo->piAD[2] = p[5];
+            pPredInfo->piAD[3] = p[6];
+            pPredInfo->piAD[4] = p[4]; //AC of 1D HT!!!
+        }
+    }
+}
diff --git a/Source/LibJXR/image/sys/strTransform.c b/Source/LibJXR/image/sys/strTransform.c
new file mode 100644
index 0000000..0d73d3a
--- /dev/null
+++ b/Source/LibJXR/image/sys/strTransform.c
@@ -0,0 +1,85 @@
+//*@@@+++@@@@******************************************************************
+//
+// Copyright � Microsoft Corp.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+// � Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// � Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//*@@@---@@@@******************************************************************
+
+#include "strTransform.h"
+
+/** need to swap b and c **/
+/** rounding behavior: [0 0 0 0] <-> [+ - - -]
+    [+ + + +] <-> [+3/4 - - -]
+    [- - - -] <-> [- - - -] **/
+Void strDCT2x2dn(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd)
+{
+    PixelI a, b, c, d, C, t;
+    a = *pa;
+    b = *pb;
+    C = *pc;
+    d = *pd;
+  
+    a += d;
+    b -= C;
+    t = ((a - b) >> 1);
+    c = t - d;
+    d = t - C;
+    a -= d;
+    b += c;
+
+    *pa = a;
+    *pb = b;
+    *pc = c;
+    *pd = d;
+}
+
+Void strDCT2x2up(PixelI *pa, PixelI *pb, PixelI *pc, PixelI *pd)
+{
+    PixelI a, b, c, d, C, t;
+    a = *pa;
+    b = *pb;
+    C = *pc;
+    d = *pd;
+  
+    a += d;
+    b -= C;
+    t = ((a - b + 1) >> 1);
+    c = t - d;
+    d = t - C;
+    a -= d;
+    b += c;
+
+    *pa = a;
+    *pb = b;
+    *pc = c;
+    *pd = d;
+}
+
+Void FOURBUTTERFLY_HARDCODED1(PixelI *p)
+{
+    strDCT2x2dn(&p[0], &p[4], &p[8], &p[12]);
+    strDCT2x2dn(&p[1], &p[5], &p[9], &p[13]);
+    strDCT2x2dn(&p[2], &p[6], &p[10], &p[14]);
+    strDCT2x2dn(&p[3], &p[7], &p[11], &p[15]);
+}
diff --git a/Source/LibJXR/image/sys/strTransform.h b/Source/LibJXR/image/sys/strTransform.h
new file mode 100644
index 0000000..1e1a7cf
--- /dev/null
+++ b/Source/LibJXR/image/sys/strTransform.h
@@ -0,0 +1,50 @@
+//*@@@+++@@@@******************************************************************
+//
+// Copyright � Microsoft Corp.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+// � Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// � Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//*@@@---@@@@******************************************************************
+
+#ifndef WMI_STRTRANSFORM_H
+#define WMI_STRTRANSFORM_H
+
+#include "windowsmediaphoto.h"
+
+#define COMPUTE_CORNER_PRED_DIFF(a, b) (*(a) -= (b))
+#define COMPUTE_CORNER_PRED_ADD(a, b) (*(a) += (b))
+
+/** 2x2 foward DCT == 2x2 inverse DCT **/
+Void strDCT2x2dn(PixelI *, PixelI *, PixelI *, PixelI *);
+Void strDCT2x2up(PixelI *, PixelI *, PixelI *, PixelI *);
+Void FOURBUTTERFLY_HARDCODED1(PixelI *p);
+
+/** 2x2 dct of a group of 4**/
+#define FOURBUTTERFLY(p, i00, i01, i02, i03, i10, i11, i12, i13,\
+    i20, i21, i22, i23, i30, i31, i32, i33)		                \
+    strDCT2x2dn(&p[i00], &p[i01], &p[i02], &p[i03]);			\
+    strDCT2x2dn(&p[i10], &p[i11], &p[i12], &p[i13]);			\
+    strDCT2x2dn(&p[i20], &p[i21], &p[i22], &p[i23]);			\
+    strDCT2x2dn(&p[i30], &p[i31], &p[i32], &p[i33])
+
+#endif // WMI_STRTRANSFORM_H
\ No newline at end of file
diff --git a/Source/LibJXR/image/sys/strcodec.c b/Source/LibJXR/image/sys/strcodec.c
new file mode 100644
index 0000000..2312aac
--- /dev/null
+++ b/Source/LibJXR/image/sys/strcodec.c
@@ -0,0 +1,1251 @@
+//*@@@+++@@@@******************************************************************
+//
+// Copyright � Microsoft Corp.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+// � Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// � Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//*@@@---@@@@******************************************************************
+#include "strcodec.h"
+#include "perfTimer.h"
+
+#ifdef MEM_TRACE
+#define TRACE_MALLOC    1
+#define TRACE_NEW       0
+#define TRACE_HEAP      0
+#include "memtrace.h"
+#endif
+
+//================================================================
+// Quantization index tables
+//================================================================
+const int blkOffset[16] = {0, 64, 16, 80, 128, 192, 144, 208, 32, 96, 48, 112, 160, 224, 176, 240};
+const int blkOffsetUV[4] = {0, 32, 16, 48};
+const int blkOffsetUV_422[8] = {0, 64, 16, 80, 32, 96, 48, 112};
+
+const int dctIndex[3][16] = { /** permutation matrix tailored to the transform, nothing to do with ZZS **/
+    {0,5,1,6, 10,12,8,14, 2,4,3,7, 9,13,11,15}, //AC 444
+    {0,5,1,6, 10,12,8,14, 2,4,3,7, 9,13,11,15}, //AC 420
+    {0,128,64,208, 32,240,48,224, 16,192,80,144, 112,176,96,160 }, //DC 444
+};
+
+//================================================================
+// Color conversion index table
+//================================================================
+const U8 idxCC[16][16] =
+{
+    {0x00, 0x01, 0x05, 0x04,  0x40, 0x41, 0x45, 0x44,  0x80, 0x81, 0x85, 0x84,  0xc0, 0xc1, 0xc5, 0xc4, },
+    {0x02, 0x03, 0x07, 0x06,  0x42, 0x43, 0x47, 0x46,  0x82, 0x83, 0x87, 0x86,  0xc2, 0xc3, 0xc7, 0xc6, },
+    {0x0a, 0x0b, 0x0f, 0x0e,  0x4a, 0x4b, 0x4f, 0x4e,  0x8a, 0x8b, 0x8f, 0x8e,  0xca, 0xcb, 0xcf, 0xce, },
+    {0x08, 0x09, 0x0d, 0x0c,  0x48, 0x49, 0x4d, 0x4c,  0x88, 0x89, 0x8d, 0x8c,  0xc8, 0xc9, 0xcd, 0xcc, },
+
+    {0x10, 0x11, 0x15, 0x14,  0x50, 0x51, 0x55, 0x54,  0x90, 0x91, 0x95, 0x94,  0xd0, 0xd1, 0xd5, 0xd4, },
+    {0x12, 0x13, 0x17, 0x16,  0x52, 0x53, 0x57, 0x56,  0x92, 0x93, 0x97, 0x96,  0xd2, 0xd3, 0xd7, 0xd6, },
+    {0x1a, 0x1b, 0x1f, 0x1e,  0x5a, 0x5b, 0x5f, 0x5e,  0x9a, 0x9b, 0x9f, 0x9e,  0xda, 0xdb, 0xdf, 0xde, },
+    {0x18, 0x19, 0x1d, 0x1c,  0x58, 0x59, 0x5d, 0x5c,  0x98, 0x99, 0x9d, 0x9c,  0xd8, 0xd9, 0xdd, 0xdc, },
+
+    {0x20, 0x21, 0x25, 0x24,  0x60, 0x61, 0x65, 0x64,  0xa0, 0xa1, 0xa5, 0xa4,  0xe0, 0xe1, 0xe5, 0xe4, },
+    {0x22, 0x23, 0x27, 0x26,  0x62, 0x63, 0x67, 0x66,  0xa2, 0xa3, 0xa7, 0xa6,  0xe2, 0xe3, 0xe7, 0xe6, },
+    {0x2a, 0x2b, 0x2f, 0x2e,  0x6a, 0x6b, 0x6f, 0x6e,  0xaa, 0xab, 0xaf, 0xae,  0xea, 0xeb, 0xef, 0xee, },
+    {0x28, 0x29, 0x2d, 0x2c,  0x68, 0x69, 0x6d, 0x6c,  0xa8, 0xa9, 0xad, 0xac,  0xe8, 0xe9, 0xed, 0xec, },
+
+    {0x30, 0x31, 0x35, 0x34,  0x70, 0x71, 0x75, 0x74,  0xb0, 0xb1, 0xb5, 0xb4,  0xf0, 0xf1, 0xf5, 0xf4, },
+    {0x32, 0x33, 0x37, 0x36,  0x72, 0x73, 0x77, 0x76,  0xb2, 0xb3, 0xb7, 0xb6,  0xf2, 0xf3, 0xf7, 0xf6, },
+    {0x3a, 0x3b, 0x3f, 0x3e,  0x7a, 0x7b, 0x7f, 0x7e,  0xba, 0xbb, 0xbf, 0xbe,  0xfa, 0xfb, 0xff, 0xfe, },
+    {0x38, 0x39, 0x3d, 0x3c,  0x78, 0x79, 0x7d, 0x7c,  0xb8, 0xb9, 0xbd, 0xbc,  0xf8, 0xf9, 0xfd, 0xfc, },
+};
+
+const U8 idxCC_420[8][8] =
+{
+    {0x00, 0x01, 0x05, 0x04,  0x20, 0x21, 0x25, 0x24, },
+    {0x02, 0x03, 0x07, 0x06,  0x22, 0x23, 0x27, 0x26, },
+    {0x0a, 0x0b, 0x0f, 0x0e,  0x2a, 0x2b, 0x2f, 0x2e, },
+    {0x08, 0x09, 0x0d, 0x0c,  0x28, 0x29, 0x2d, 0x2c, },
+
+    {0x10, 0x11, 0x15, 0x14,  0x30, 0x31, 0x35, 0x34, },
+    {0x12, 0x13, 0x17, 0x16,  0x32, 0x33, 0x37, 0x36, },
+    {0x1a, 0x1b, 0x1f, 0x1e,  0x3a, 0x3b, 0x3f, 0x3e, },
+    {0x18, 0x19, 0x1d, 0x1c,  0x38, 0x39, 0x3d, 0x3c, },
+};
+
+/*************************************************************************
+    gGDISignature
+*************************************************************************/
+const Char gGDISignature[] = {'W', 'M', 'P', 'H', 'O', 'T', 'O', '\0'};
+
+// check if enough memory allocated for the image buffer
+Int checkImageBuffer(CWMImageStrCodec * pSC, size_t cWidth, size_t cRows)
+{
+    const BITDEPTH_BITS bd = pSC->WMISCP.bYUVData ?
+        BD_32S : pSC->WMII.bdBitDepth;
+    const COLORFORMAT cf = pSC->WMISCP.bYUVData ?
+        pSC->m_param.cfColorFormat : pSC->WMII.cfColorFormat;
+    size_t cBytes;
+    Bool bLessThan64Bit = sizeof(void *) < 8;
+
+    if(cf == YUV_420)
+        cRows = (cRows + 1) / 2;
+    if(cRows > pSC->WMIBI.cLine)
+        return ICERR_ERROR;
+
+    if(cf == YUV_422 || cf == YUV_420)
+        cWidth = (cWidth + 1) / 2;
+
+    if (bLessThan64Bit && (cWidth >> ((sizeof(size_t) * 8 - 5)))) {
+        /** potential overflow - 32 bit pointers insufficient to address cache **/
+        /** this uses 2 macroblock row constraint, which is tighter than ensuring rollover doesn't occur below **/
+        return ICERR_ERROR;
+    }
+
+    cBytes = pSC->WMISCP.bYUVData ? cWidth * sizeof(PixelI) *
+        (cf == YUV_420 ? 6 : (cf == YUV_422 ? 4 : (cf == YUV_444 ? 3 : 1))) :
+        (bd == BD_1 ? (pSC->WMII.cBitsPerUnit * cWidth + 7) / 8 : (pSC->WMII.cBitsPerUnit + 7) / 8 * cWidth);
+
+    return (cBytes > pSC->WMIBI.cbStride ? ICERR_ERROR : ICERR_OK);
+}
+
+Void writeQPIndex(BitIOInfo * pIO, U8 uiIndex, U32 cBits)
+{
+    if(uiIndex == 0)
+        putBit16(pIO, 1, 1); // default QP
+    else{
+        putBit16(pIO, 0, 1); // non default QP
+        putBit16(pIO, uiIndex - 1, cBits);
+    }
+}
+
+U8 readQPIndex(BitIOInfo * pIO, U32 cBits)
+{
+    if(getBit16(pIO, 1))
+        return 0; // default QP
+
+    return (U8) getBit16(pIO, cBits) + 1;
+}
+
+Void getTilePos(CWMImageStrCodec* pSC, size_t mbX, size_t mbY)
+{   
+    if(mbX == 0){ // left image boundary
+        pSC->cTileColumn = 0;
+    }
+    else if(pSC->cTileColumn < pSC->WMISCP.cNumOfSliceMinus1V && mbX == pSC->WMISCP.uiTileX[pSC->cTileColumn + 1]){ // left tile boundary
+        pSC->cTileColumn ++;
+    }
+
+    if(mbY == 0){ // top image boundary
+        pSC->cTileRow = 0;
+    }
+    else if(pSC->cTileRow < pSC->WMISCP.cNumOfSliceMinus1H && mbY == pSC->WMISCP.uiTileY[pSC->cTileRow + 1]){ // top tile boundary
+        pSC->cTileRow ++;
+    }
+
+    pSC->m_bCtxLeft = (mbX == pSC->WMISCP.uiTileX[pSC->cTileColumn]);
+    pSC->m_bCtxTop  = (mbY == pSC->WMISCP.uiTileY[pSC->cTileRow]);
+
+    pSC->m_bResetContext = pSC->m_bResetRGITotals = (((mbX - pSC->WMISCP.uiTileX[pSC->cTileColumn]) & 0xf) == 0);
+    if(pSC->cTileColumn == pSC->WMISCP.cNumOfSliceMinus1V){ // last tile column
+        if(mbX + 1 == pSC->cmbWidth)
+            pSC->m_bResetContext = TRUE;
+    }
+    else if(mbX + 1 == pSC->WMISCP.uiTileX[pSC->cTileColumn + 1])
+        pSC->m_bResetContext = TRUE;
+}
+
+//================================================================
+// utility functions for 2 macro block rows
+//================================================================
+Void initMRPtr(CWMImageStrCodec* pSC)
+{
+    size_t j, jend = (pSC->m_pNextSC != NULL);
+
+    for (j = 0; j <= jend; j++) {
+        memcpy (pSC->p0MBbuffer, pSC->a0MBbuffer, sizeof (pSC->p0MBbuffer));
+        memcpy (pSC->p1MBbuffer, pSC->a1MBbuffer, sizeof (pSC->p1MBbuffer));
+        pSC = pSC->m_pNextSC;
+    }
+}
+
+Void advanceMRPtr(CWMImageStrCodec* pSC)
+{
+    const COLORFORMAT cf = pSC->m_param.cfColorFormat;
+    const int cpChroma = cblkChromas[cf] * 16;
+    size_t i, j, jend = (pSC->m_pNextSC != NULL);
+
+    assert(pSC->m_bSecondary == FALSE);
+    for (j = 0; j <= jend; j++) {
+        int cpStride = 16 * 16;
+        for (i = 0; i < pSC->m_param.cNumChannels; i++) {
+            pSC->pPlane[i] = pSC->p0MBbuffer[i];
+
+            pSC->p0MBbuffer[i] += cpStride;
+            pSC->p1MBbuffer[i] += cpStride;
+
+            cpStride = cpChroma;
+        }
+        pSC = pSC->m_pNextSC;
+    }
+}
+
+/* advance to next MB row */
+Void advanceOneMBRow(CWMImageStrCodec *pSC)
+{
+    size_t i, j, jend = (pSC->m_pNextSC != NULL);
+    CWMIPredInfo *pPredInfo;
+
+    for (j = 0; j <= jend; j++) {
+        for(i = 0; i < pSC->m_param.cNumChannels; i ++){  // swap current row and previous row
+            pPredInfo = pSC->PredInfo[i];
+            pSC->PredInfo[i] = pSC->PredInfoPrevRow[i];
+            pSC->PredInfoPrevRow[i] = pPredInfo;
+        }
+        pSC = pSC->m_pNextSC;
+    }
+}
+
+Void swapMRPtr(CWMImageStrCodec* pSC)
+{
+    PixelI *pTemp[MAX_CHANNELS];
+    size_t j, jend = (pSC->m_pNextSC != NULL);
+
+    for (j = 0; j <= jend; j++) {
+        memcpy (pTemp, pSC->a0MBbuffer, sizeof (pSC->a0MBbuffer));
+        memcpy (pSC->a0MBbuffer, pSC->a1MBbuffer, sizeof (pSC->a0MBbuffer));
+        memcpy (pSC->a1MBbuffer, pTemp, sizeof (pSC->a0MBbuffer));
+        pSC = pSC->m_pNextSC;
+    }
+}
+
+//================================================================
+// Empty function to fill slot
+//================================================================
+Int IDPEmpty(CWMImageStrCodec* pSC)
+{
+    UNREFERENCED_PARAMETER( pSC );
+
+    return ICERR_OK;
+}
+
+ERR WMPAlloc(void** ppv, size_t cb)
+{
+    *ppv = calloc(1, cb);
+    return *ppv ? WMP_errSuccess : WMP_errOutOfMemory;
+}
+
+ERR WMPFree(void** ppv)
+{
+    if (*ppv)
+    {
+        free(*ppv);
+        *ppv = NULL;
+    }
+
+    return WMP_errSuccess;
+}
+
+//================================================================
+// Streaming I/O functions
+//================================================================
+ERR CreateWS_File(struct WMPStream** ppWS, const char* szFilename, const char* szMode)
+{
+    ERR err = WMP_errSuccess;
+    struct WMPStream* pWS = NULL;
+
+    Call(WMPAlloc((void** )ppWS, sizeof(**ppWS)));
+    pWS = *ppWS;
+
+    pWS->Close = CloseWS_File;
+    pWS->EOS = EOSWS_File;
+
+    pWS->Read = ReadWS_File;
+    pWS->Write = WriteWS_File;
+    //pWS->GetLine = GetLineWS_File;
+
+    pWS->SetPos = SetPosWS_File;
+    pWS->GetPos = GetPosWS_File;
+
+#if defined(WIN32) && !defined(__MINGW32__)
+    FailIf(0 != fopen_s(&pWS->state.file.pFile, szFilename, szMode), WMP_errFileIO);
+#else
+    pWS->state.file.pFile = fopen(szFilename, szMode);
+    FailIf(NULL == pWS->state.file.pFile, WMP_errFileIO);
+#endif
+
+Cleanup:    
+    return err;
+}
+
+ERR CloseWS_File(struct WMPStream** ppWS)
+{
+    ERR err = WMP_errSuccess;
+    struct WMPStream* pWS = *ppWS;
+
+    fclose(pWS->state.file.pFile);
+    Call(WMPFree((void**)ppWS));
+
+Cleanup:
+    return err;
+}
+
+Bool EOSWS_File(struct WMPStream* pWS)
+{
+    return feof(pWS->state.file.pFile);
+}
+
+ERR ReadWS_File(struct WMPStream* pWS, void* pv, size_t cb)
+{
+    // ERR err = WMP_errSuccess;
+
+    return (fread(pv, cb, 1, pWS->state.file.pFile) == 1) ? WMP_errSuccess : WMP_errFileIO;
+}
+
+ERR WriteWS_File(struct WMPStream* pWS, const void* pv, size_t cb)
+{
+    ERR err = WMP_errSuccess;
+
+    if(0 != cb)
+    {
+        FailIf(1 != fwrite(pv, cb, 1, pWS->state.file.pFile), WMP_errFileIO);
+    }
+
+Cleanup:
+    return err;
+}
+
+ERR SetPosWS_File(struct WMPStream* pWS, size_t offPos)
+{
+    ERR err = WMP_errSuccess;
+
+    FailIf(0 != fseek(pWS->state.file.pFile, (long)offPos, SEEK_SET), WMP_errFileIO);
+
+Cleanup:
+    return err;
+}
+
+ERR GetPosWS_File(struct WMPStream* pWS, size_t* poffPos)
+{
+    ERR err = WMP_errSuccess;
+    long lOff = 0;
+
+    FailIf(-1 == (lOff = ftell(pWS->state.file.pFile)), WMP_errFileIO);
+    *poffPos = (size_t)lOff;
+
+Cleanup:
+    return err;
+}
+
+//----------------------------------------------------------------
+ERR CreateWS_Memory(struct WMPStream** ppWS, void* pv, size_t cb)
+{
+    ERR err = WMP_errSuccess;
+    struct WMPStream* pWS = NULL;
+
+    Call(WMPAlloc((void** )ppWS, sizeof(**ppWS)));
+    pWS = *ppWS;
+
+    pWS->state.buf.pbBuf = pv;
+    pWS->state.buf.cbBuf = cb;
+    pWS->state.buf.cbCur = 0;
+
+    pWS->Close = CloseWS_Memory;
+    pWS->EOS = EOSWS_Memory;
+
+    pWS->Read = ReadWS_Memory;
+    pWS->Write = WriteWS_Memory;
+
+    pWS->SetPos = SetPosWS_Memory;
+    pWS->GetPos = GetPosWS_Memory;
+
+Cleanup:    
+    return err;
+}
+
+ERR CloseWS_Memory(struct WMPStream** ppWS)
+{
+    ERR err = WMP_errSuccess;
+
+    Call(WMPFree((void**)ppWS));
+    
+Cleanup:    
+    return err;
+}
+
+Bool EOSWS_Memory(struct WMPStream* pWS)
+{
+    return pWS->state.buf.cbBuf <= pWS->state.buf.cbCur;
+}
+
+ERR ReadWS_Memory(struct WMPStream* pWS, void* pv, size_t cb)
+{
+    ERR err = WMP_errSuccess;
+
+//    FailIf(pWS->state.buf.cbBuf < pWS->state.buf.cbCur, WMP_errBufferOverflow);
+    if(pWS->state.buf.cbBuf < pWS->state.buf.cbCur)
+        return err;
+
+    FailIf(pWS->state.buf.cbCur + cb < pWS->state.buf.cbCur, WMP_errBufferOverflow);
+    if (pWS->state.buf.cbBuf < pWS->state.buf.cbCur + cb)
+    {
+        cb = pWS->state.buf.cbBuf - pWS->state.buf.cbCur;
+    }
+
+    memcpy(pv, pWS->state.buf.pbBuf + pWS->state.buf.cbCur, cb);
+    pWS->state.buf.cbCur += cb;
+
+Cleanup:
+    return err;
+}
+
+ERR WriteWS_Memory(struct WMPStream* pWS, const void* pv, size_t cb)
+{
+    ERR err = WMP_errSuccess;
+
+    FailIf(pWS->state.buf.cbCur + cb < pWS->state.buf.cbCur, WMP_errBufferOverflow);
+    FailIf(pWS->state.buf.cbBuf < pWS->state.buf.cbCur + cb, WMP_errBufferOverflow);
+
+    memcpy(pWS->state.buf.pbBuf + pWS->state.buf.cbCur, pv, cb);
+    pWS->state.buf.cbCur += cb;
+
+Cleanup:
+    return err;
+}
+
+ERR SetPosWS_Memory(struct WMPStream* pWS, size_t offPos)
+{
+    ERR err = WMP_errSuccess;
+
+    //While the following condition is possibly useful, failure occurs
+    //at the end of a file since packets beyond the end may be accessed
+    //FailIf(pWS->state.buf.cbBuf < offPos, WMP_errBufferOverflow);
+    pWS->state.buf.cbCur = offPos;
+
+//Cleanup:
+    return err;
+}
+
+ERR GetPosWS_Memory(struct WMPStream* pWS, size_t* poffPos)
+{
+    *poffPos = pWS->state.buf.cbCur;
+
+    return WMP_errSuccess;
+}
+
+//=================================================================
+// Linked list based WMPStream
+// - for indefinite size, multiple stream out
+// - reads not supported in this mode
+//=================================================================
+ERR CreateWS_List(struct WMPStream** ppWS)
+{
+    ERR err = WMP_errSuccess;
+    struct WMPStream* pWS = NULL;
+
+    Call(WMPAlloc((void** )ppWS, sizeof(**ppWS) + PACKETLENGTH + sizeof(void *)));
+    pWS = *ppWS;
+
+    pWS->state.buf.pbBuf = (U8 *)pWS + sizeof(**ppWS) + sizeof(void *); // first buffer points here
+
+    memset(pWS->state.buf.pbBuf - sizeof(void *), 0, sizeof(void *));
+    pWS->state.buf.cbBuf = PACKETLENGTH;
+    pWS->state.buf.cbCur = 0;
+    pWS->state.buf.cbBufCount = 0;
+
+    pWS->Close = CloseWS_List;
+    pWS->EOS = NULL; // doesn't get called
+
+    pWS->Read = ReadWS_List;
+    pWS->Write = WriteWS_List;
+
+    pWS->SetPos = SetPosWS_List;
+    pWS->GetPos = GetPosWS_List;
+
+    //printf ("create buffer %d: %x\n", pWS->state.buf.cbBufCount, pWS->state.buf.pbBuf);
+
+Cleanup:    
+    return err;
+}
+
+ERR CloseWS_List(struct WMPStream** ppWS)
+{
+    ERR err = WMP_errSuccess;
+
+    if (ppWS) {
+        U8 *pBuf = (U8 *)(ppWS[0] + 1); // pointer to buffer
+        U8 *pNext = (U8 *)(((void **)pBuf)[0]);
+        while (pNext) {
+//struct WMPStream *pWS = ppWS[0];
+            pBuf = pNext;
+            pNext = (U8 *)(((void **)(pBuf))[0]);
+//printf ("delete buffer    %x\n", pBuf);
+            Call(WMPFree((void**)&pBuf));
+        }
+    }
+    Call(WMPFree((void**)ppWS));
+    
+Cleanup:    
+    return err;
+}
+
+ERR ReadWS_List(struct WMPStream* pWS, void* pv, size_t cb)
+{
+    ERR err = WMP_errSuccess;
+
+    FailIf(pWS->state.buf.cbCur + cb < pWS->state.buf.cbCur, WMP_errBufferOverflow);
+    if (pWS->state.buf.cbBuf < pWS->state.buf.cbCur + PACKETLENGTH * pWS->state.buf.cbBufCount + cb)
+    {
+        cb = pWS->state.buf.cbBuf - pWS->state.buf.cbCur - PACKETLENGTH * pWS->state.buf.cbBufCount;
+    }
+
+    while (cb) {
+        size_t cl = PACKETLENGTH - pWS->state.buf.cbCur;
+        if (cl > cb)
+            cl = cb;
+        memcpy(pv, pWS->state.buf.pbBuf + pWS->state.buf.cbCur, cl);
+        pWS->state.buf.cbCur += cl;
+        pv = (void *)((U8 *)pv + cl);
+        cb -= cl;
+        if (pWS->state.buf.cbCur == PACKETLENGTH) {
+            pWS->state.buf.pbBuf = (U8 *)((void **)(pWS->state.buf.pbBuf - sizeof(void *)))[0] + sizeof(void *);
+            pWS->state.buf.cbCur = 0;
+            pWS->state.buf.cbBufCount++;
+
+    //printf ("read buffer %d: %x\n", pWS->state.buf.cbBufCount, pWS->state.buf.pbBuf);
+        }
+    }
+
+Cleanup:
+    return err;
+}
+
+ERR WriteWS_List(struct WMPStream* pWS, const void* pv, size_t cb)
+{
+    ERR err = WMP_errSuccess;
+
+    FailIf(pWS->state.buf.cbCur + cb < pWS->state.buf.cbCur, WMP_errBufferOverflow);
+    FailIf(pWS->state.buf.cbBuf < pWS->state.buf.cbCur + cb, WMP_errBufferOverflow);
+
+    while (cb) {
+        size_t cl = PACKETLENGTH - pWS->state.buf.cbCur;
+        if (cl > cb)
+            cl = cb;
+        memcpy(pWS->state.buf.pbBuf + pWS->state.buf.cbCur, pv, cl);
+        pWS->state.buf.cbCur += cl;
+        pv = (const void *)((U8 *)pv + cl);
+        cb -= cl;
+        if (pWS->state.buf.cbCur == PACKETLENGTH) { // allocate next packet in list
+            U8 *pBuf  = NULL;
+            void **pPtrLoc = (void **)(pWS->state.buf.pbBuf - sizeof(void *));
+            Call(WMPAlloc((void **)&pBuf, PACKETLENGTH + sizeof(void *)));
+            pPtrLoc[0] = (void *)pBuf;
+            pWS->state.buf.pbBuf = pBuf + sizeof(void *);
+            pWS->state.buf.cbBuf += PACKETLENGTH;
+            memset(pBuf, 0, sizeof(void *));
+            pWS->state.buf.cbCur = 0;
+            pWS->state.buf.cbBufCount++;
+
+    //printf ("create buffer %d: %x\n", pWS->state.buf.cbBufCount, pWS->state.buf.pbBuf);
+        }
+    }
+
+Cleanup:
+    return err;
+}
+
+ERR SetPosWS_List(struct WMPStream* pWS, size_t offPos)
+{
+    ERR err = WMP_errSuccess;
+
+    // get the first buffer
+    U8 *pBuf = (U8 *)(pWS + 1); // pointer to buffer
+    pWS->state.buf.cbCur = 0;
+    pWS->state.buf.cbBufCount = 0;
+
+    while (offPos >= PACKETLENGTH && pBuf != NULL) {
+        pBuf = (U8 *)(((void **)pBuf)[0]);
+        offPos -= PACKETLENGTH;
+        pWS->state.buf.cbBufCount++;
+    }
+
+    if (pBuf == NULL)
+        goto Cleanup;
+
+    pWS->state.buf.cbCur = offPos;
+    pWS->state.buf.pbBuf = pBuf + sizeof(void *);
+    //printf ("seek buffer %d: %x\n", pWS->state.buf.cbBufCount, pWS->state.buf.pbBuf);
+
+Cleanup:
+    return err;
+}
+
+ERR GetPosWS_List(struct WMPStream* pWS, size_t* poffPos)
+{
+    *poffPos = pWS->state.buf.cbCur + PACKETLENGTH * pWS->state.buf.cbBufCount;
+
+    return WMP_errSuccess;
+}
+
+//================================================================
+// Simple BitIO access functions
+//================================================================
+// init SimpleBitIO
+ERR attach_SB(SimpleBitIO* pSB, struct WMPStream* pWS)
+{
+    pSB->pWS = pWS;
+    pSB->cbRead = 0;
+    pSB->bAccumulator = 0;
+    pSB->cBitLeft = 0;
+
+    return WMP_errSuccess;
+}
+
+// extract upto 32bit from input stream
+U32 getBit32_SB(SimpleBitIO* pSB, U32 cBits)
+{
+    U32 rc = 0;
+
+    while (pSB->cBitLeft < cBits)
+    {
+        rc <<= pSB->cBitLeft;
+        rc |= pSB->bAccumulator >> (8 - pSB->cBitLeft);
+
+        cBits -= pSB->cBitLeft;
+
+        pSB->pWS->Read(pSB->pWS, &pSB->bAccumulator, 1);
+        pSB->cbRead++;
+        pSB->cBitLeft = 8;
+    }
+
+    rc <<= cBits;
+    rc |= pSB->bAccumulator >> (8 - cBits);
+    pSB->bAccumulator <<= cBits;
+    pSB->cBitLeft -= cBits;
+
+    return rc;
+}
+
+// ignore input to byte boundary
+Void flushToByte_SB(SimpleBitIO* pSB)
+{
+    pSB->bAccumulator = 0;
+    pSB->cBitLeft = 0;
+}
+
+// return read byte count
+U32 getByteRead_SB(SimpleBitIO* pSB)
+{
+    return pSB->cbRead;
+}
+
+ERR detach_SB(SimpleBitIO* pSB)
+{
+    assert(0 == pSB->cBitLeft);
+    pSB->pWS = NULL;
+
+    return WMP_errSuccess;
+}
+
+//================================================================
+// Memory access functions
+//================================================================
+#if (defined(WIN32) && !defined(UNDER_CE) && (!defined(__MINGW32__) || defined(__MINGW64_TOOLCHAIN__))) || (defined(UNDER_CE) && defined(_ARM_))
+// WinCE ARM and Desktop x86
+#else
+// other platform
+#ifdef _BIG__ENDIAN_
+#define _byteswap_ulong(x)  (x)
+#else // _BIG__ENDIAN_
+U32 _byteswap_ulong(U32 bits)
+{
+    U32 r = (bits & 0xffu) << 24;
+    r |= (bits << 8) & 0xff0000u;
+    r |= ((bits >> 8) & 0xff00u);
+    r |= ((bits >> 24) & 0xffu);
+
+    return r;
+}
+#endif // _BIG__ENDIAN_
+#endif
+
+U32 load4BE(void* pv)
+{
+#ifdef _BIG__ENDIAN_
+    return (*(U32*)pv);
+#else // _BIG__ENDIAN_
+#if defined(_M_IA64) || defined(_ARM_)
+    U32  v;
+    v = ((U16 *) pv)[0];
+    v |= ((U32)((U16 *) pv)[1]) << 16;
+    return _byteswap_ulong(v);
+#else // _M_IA64
+    return _byteswap_ulong(*(U32*)pv);
+#endif // _M_IA64
+#endif // _BIG__ENDIAN_
+}
+
+#define LOAD16 load4BE
+
+#ifdef _BIG__ENDIAN_
+#define WRITESWAP_ENDIAN(a) ((a)>>16)
+#else // _BIG__ENDIAN_
+#define WRITESWAP_ENDIAN(a)	_byteswap_ulong(a)
+#endif // _BIG__ENDIAN_
+
+//================================================================
+// Bit I/O functions 
+//================================================================
+Int allocateBitIOInfo(CWMImageStrCodec* pSC)
+{
+    U32 cNumBitIO;
+    SUBBAND sbSubband = pSC->WMISCP.sbSubband;
+
+    pSC->cSB = (sbSubband == SB_DC_ONLY ? 1 : (sbSubband == SB_NO_HIGHPASS ? 2 : (sbSubband == SB_NO_FLEXBITS ? 3 : 4)));
+
+    // # of additional BitIOs other than pSC->pIOHeader
+    if (!pSC->m_param.bIndexTable) { // pure streaming mode, no index table, no additional BitIO!
+        assert (pSC->WMISCP.bfBitstreamFormat == SPATIAL && pSC->WMISCP.cNumOfSliceMinus1H + pSC->WMISCP.cNumOfSliceMinus1V == 0);
+        cNumBitIO = 0;
+    }
+    else if(pSC->WMISCP.bfBitstreamFormat == SPATIAL)
+        cNumBitIO = pSC->WMISCP.cNumOfSliceMinus1V + 1;
+    else
+        cNumBitIO = (pSC->WMISCP.cNumOfSliceMinus1V + 1) * pSC->cSB;
+
+    if(cNumBitIO > MAX_TILES * 4)
+        return ICERR_ERROR;
+
+    // allocate additional BitIos
+    if(cNumBitIO > 0){
+        U32 i = 0;
+        size_t cb = sizeof(BitIOInfo) * cNumBitIO + (PACKETLENGTH * 4 - 1) + PACKETLENGTH * 4 * cNumBitIO;
+        U8* pb = (U8*)malloc(cb);
+
+        if (NULL == pb) return ICERR_ERROR;
+        memset(pb, 0, cb);
+
+        pSC->m_ppBitIO = (BitIOInfo**)pb;
+        pb += sizeof(BitIOInfo) * cNumBitIO;
+
+        pb = (U8*)ALIGNUP(pb, PACKETLENGTH * 4) + PACKETLENGTH * 2;
+        for (i = 0; i < cNumBitIO; ++i){
+            pSC->m_ppBitIO[i] = (BitIOInfo*)pb;
+            pb += PACKETLENGTH * 4;
+        }
+
+        // allocate index table
+        if(cNumBitIO > MAX_TILES * 4 || pSC->WMISCP.cNumOfSliceMinus1H >= MAX_TILES)
+            return ICERR_ERROR;
+        pSC->pIndexTable = malloc(cNumBitIO * (pSC->WMISCP.cNumOfSliceMinus1H + 1) * sizeof(size_t));
+        if(NULL == pSC->pIndexTable) return ICERR_ERROR;
+    }
+
+    pSC->cNumBitIO = cNumBitIO;
+
+    return ICERR_OK;
+}
+
+Int setBitIOPointers(CWMImageStrCodec* pSC)
+{
+    if(pSC->cNumBitIO > 0){
+        U32 i;
+
+        for(i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1V; i ++){
+            CCodingContext * pContext = &pSC->m_pCodingContext[i];
+            if(pSC->WMISCP.bfBitstreamFormat == SPATIAL){
+                pContext->m_pIODC = pContext->m_pIOLP = pContext->m_pIOAC = pContext->m_pIOFL = pSC->m_ppBitIO[i];
+            }
+            else{
+                U32 j = pSC->cSB;
+
+                pContext->m_pIODC = pSC->m_ppBitIO[i * j];
+                if(j > 1)
+                    pContext->m_pIOLP = pSC->m_ppBitIO[i * j + 1];
+                if(j > 2)
+                    pContext->m_pIOAC = pSC->m_ppBitIO[i * j + 2];
+                if(j > 3)
+                    pContext->m_pIOFL = pSC->m_ppBitIO[i * j + 3];
+            }
+        }
+    }
+    else{ // streamimg mode
+        CCodingContext * pContext = &pSC->m_pCodingContext[0];
+        pContext->m_pIODC = pContext->m_pIOLP = pContext->m_pIOAC = pContext->m_pIOFL = pSC->pIOHeader;
+    }
+
+    return ICERR_OK;
+}
+
+Int allocateTileInfo(CWMImageStrCodec * pSC)
+{
+    size_t i;
+
+    if(pSC->WMISCP.cNumOfSliceMinus1V >= MAX_TILES)
+        return ICERR_ERROR;
+    pSC->pTile = (CWMITile *)malloc((pSC->WMISCP.cNumOfSliceMinus1V + 1) * sizeof(CWMITile));
+    if(pSC->pTile == NULL)
+        return ICERR_ERROR;
+    memset(pSC->pTile, 0, (pSC->WMISCP.cNumOfSliceMinus1V + 1) * sizeof(CWMITile));
+
+    for(i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1V; i ++)
+        pSC->pTile[i].cNumQPHP = pSC->pTile[i].cNumQPLP = 1, pSC->pTile[i].cBitsHP = pSC->pTile[i].cBitsLP = 0;
+
+    return ICERR_OK;
+}
+
+Void freeTileInfo(CWMImageStrCodec * pSC)
+{
+    size_t iTile;
+
+    if((pSC->m_param.uQPMode & 1) != 0) // not DC uniform
+        for(iTile = 0; iTile <= pSC->WMISCP.cNumOfSliceMinus1V; iTile ++)
+            freeQuantizer(pSC->pTile[iTile].pQuantizerDC);
+    else
+        freeQuantizer(pSC->pTile[0].pQuantizerDC);
+
+    if(pSC->WMISCP.sbSubband != SB_DC_ONLY)
+        if((pSC->m_param.uQPMode & 2) != 0) // not LP uniform
+            for(iTile = 0; iTile <= pSC->WMISCP.cNumOfSliceMinus1V; iTile ++)
+                freeQuantizer(pSC->pTile[iTile].pQuantizerLP);
+        else
+            freeQuantizer(pSC->pTile[0].pQuantizerLP);
+
+    if(pSC->WMISCP.sbSubband != SB_DC_ONLY && pSC->WMISCP.sbSubband != SB_NO_HIGHPASS)
+        if((pSC->m_param.uQPMode & 4) != 0) // not HP uniform
+            for(iTile = 0; iTile <= pSC->WMISCP.cNumOfSliceMinus1V; iTile ++)
+                freeQuantizer(pSC->pTile[iTile].pQuantizerHP);
+        else
+            freeQuantizer(pSC->pTile[0].pQuantizerHP);
+
+    if(pSC->pTile != NULL)
+        free(pSC->pTile);
+}
+
+Int allocateQuantizer(CWMIQuantizer * pQuantizer[MAX_CHANNELS], size_t cChannel, size_t cQP)
+{
+    size_t iCh;
+    
+    if(cQP > 16 || cChannel > MAX_CHANNELS)
+        return ICERR_ERROR;
+    pQuantizer[0] = (CWMIQuantizer *)malloc(cQP * sizeof(CWMIQuantizer) * cChannel);
+    if(pQuantizer[0] == NULL)
+        return ICERR_ERROR;
+
+    for(iCh = 1; iCh < cChannel; iCh ++)
+        pQuantizer[iCh] = pQuantizer[iCh - 1] + cQP;
+
+    return ICERR_OK;
+}
+
+Void freeQuantizer(CWMIQuantizer * pQuantizer[MAX_CHANNELS])
+{
+    if(pQuantizer[0] != NULL)
+        free(pQuantizer[0]);
+}
+
+Void formatQuantizer(CWMIQuantizer * pQuantizer[MAX_CHANNELS], U8 cChMode, size_t cCh, size_t iPos, Bool bShiftedUV,
+                     Bool bScaledArith)
+{
+    size_t iCh;
+    
+    for(iCh = 0; iCh < cCh; iCh ++){
+        if(iCh > 0)
+            if(cChMode == 0) // uniform
+                pQuantizer[iCh][iPos] = pQuantizer[0][iPos];
+            else if(cChMode == 1) // mixed
+                pQuantizer[iCh][iPos] = pQuantizer[1][iPos];
+        remapQP(pQuantizer[iCh] + iPos, (iCh > 0 && bShiftedUV == TRUE) ? SHIFTZERO - 1 : SHIFTZERO, bScaledArith);
+    }
+}
+
+Void setUniformQuantizer(CWMImageStrCodec * pSC, size_t sb)
+{
+    size_t iCh, iTile;
+
+    for(iCh = 0; iCh < pSC->m_param.cNumChannels; iCh ++)
+        for(iTile = 1; iTile <= pSC->WMISCP.cNumOfSliceMinus1V; iTile ++)
+            if(sb == 0) // DC
+                pSC->pTile[iTile].pQuantizerDC[iCh] = pSC->pTile[0].pQuantizerDC[iCh];
+            else if(sb == 1) // LP
+                pSC->pTile[iTile].pQuantizerLP[iCh] = pSC->pTile[0].pQuantizerLP[iCh];
+            else // HP
+                pSC->pTile[iTile].pQuantizerHP[iCh] = pSC->pTile[0].pQuantizerHP[iCh];
+}
+
+Void useDCQuantizer(CWMImageStrCodec * pSC, size_t iTile)
+{
+   size_t iCh;
+
+    for(iCh = 0; iCh < pSC->m_param.cNumChannels; iCh ++)
+        pSC->pTile[iTile].pQuantizerLP[iCh][0] = *pSC->pTile[iTile].pQuantizerDC[iCh];
+}
+
+Void useLPQuantizer(CWMImageStrCodec * pSC, size_t cQP, size_t iTile)
+{
+   size_t iCh, iQP;
+
+    for(iCh = 0; iCh < pSC->m_param.cNumChannels; iCh ++)
+        for(iQP = 0; iQP < cQP; iQP ++)
+            pSC->pTile[iTile].pQuantizerHP[iCh][iQP] = pSC->pTile[iTile].pQuantizerLP[iCh][iQP];
+}
+
+U8 dquantBits(U8 cQP)
+{
+    return (cQP < 2 ? 0 : (cQP < 4 ? 1 : (cQP < 6 ? 2 : (cQP < 10 ? 3 : 4))));
+}
+
+#ifndef ARMOPT_BITIO
+U32 peekBit16(BitIOInfo* pIO, U32 cBits)
+{
+    PEEKBIT16(pIO, cBits);
+}
+
+U32 flushBit16(BitIOInfo* pIO, U32 cBits)
+{
+    FLUSHBIT16(pIO, cBits);
+}
+
+U32 getBit16(BitIOInfo* pIO, U32 cBits)
+{
+    U32 uiRet = peekBit16(pIO, cBits);
+    flushBit16(pIO, cBits);
+
+    return uiRet;
+}
+
+U32 getBool16(BitIOInfo* pIO)
+{
+    U32 uiRet = peekBit16(pIO, 1);
+    flushBit16(pIO, 1);
+    return uiRet;
+}
+
+/** this function returns cBits if zero is read, or a signed value if first cBits are not all zero **/
+I32 getBit16s(BitIOInfo* pIO, U32 cBits)
+{
+    U32 uiRet = peekBit16(pIO, cBits + 1);
+    if (uiRet < 2) {
+        flushBit16(pIO, cBits);
+        return 0;
+    }
+    else {
+        flushBit16(pIO, cBits + 1);
+        if (uiRet & 1)
+            return (-(I32)(uiRet >> 1));
+        else
+            return (I32)(uiRet >> 1);
+    }
+}
+
+U32 getBit32(BitIOInfo* pIO, U32 cBits)
+{
+    U32 uiRet = 0;
+
+    assert(0 <= (I32)cBits && cBits <= 32);
+
+    if (16 < cBits)
+    {
+        uiRet = getBit16(pIO, 16);
+        cBits -= 16;
+        uiRet <<= cBits;
+    }
+
+    uiRet |= getBit16(pIO, cBits);
+
+    return uiRet;
+}
+
+U32 flushToByte(BitIOInfo* pIO)
+{
+    return flushBit16(pIO, (16 - pIO->cBitsUsed) & 7);
+}
+#endif  // ARMOPT_BITIO
+
+//----------------------------------------------------------------
+Void putBit16z(BitIOInfo* pIO, U32 uiBits, U32 cBits)
+{
+    assert(cBits <= 16);
+    assert(0 == uiBits >> cBits);
+
+    pIO->uiAccumulator = (pIO->uiAccumulator << cBits) | uiBits;
+    pIO->cBitsUsed += cBits;
+
+    *(U16*)pIO->pbCurrent = (U16)WRITESWAP_ENDIAN(pIO->uiAccumulator << (32 - pIO->cBitsUsed));
+
+    pIO->pbCurrent = MASKPTR(pIO->pbCurrent + ((pIO->cBitsUsed >> 3) & 2), pIO->iMask);
+    pIO->cBitsUsed &= 16 - 1;
+}
+
+Void putBit16(BitIOInfo* pIO, U32 uiBits, U32 cBits)
+{
+    assert(cBits <= 16);
+
+    uiBits &= ~(-1 << cBits);
+    putBit16z(pIO, uiBits, cBits);
+}
+
+Void putBit32(BitIOInfo* pIO, U32 uiBits, U32 cBits)
+{
+    assert(0 <= (I32)cBits && cBits <= 32);
+
+    if (16 < cBits)
+    {
+        putBit16(pIO, uiBits >> (cBits - 16), 16);
+        cBits -= 16;
+    }
+
+    putBit16(pIO, uiBits, cBits);
+}
+
+Void fillToByte(BitIOInfo* pIO)
+{
+    putBit16z(pIO, 0, (16 - pIO->cBitsUsed) & 7);
+}
+
+//----------------------------------------------------------------
+U32 getBit16_S(CWMImageStrCodec* pSC, BitIOInfo* pIO, U32 cBits)
+{
+    U32 rc = getBit16(pIO, cBits);
+    readIS_L1(pSC, pIO);
+
+    return rc;
+}
+
+U32 putBit16_S(CWMImageStrCodec* pSC, BitIOInfo* pIO, U32 uiBits, U32 cBits)
+{
+    putBit16(pIO, uiBits, cBits);
+    writeIS_L1(pSC, pIO);
+
+    return 0;
+}
+
+
+//----------------------------------------------------------------
+// Query buffered data size held in BitIOInfo
+// Write() for Enc, Read() for Dec
+//----------------------------------------------------------------
+U32 getSizeRead(BitIOInfo* pIO)
+{
+    return (U32)(UINTPTR_T)(pIO->pbStart + PACKETLENGTH * 2 - pIO->pbCurrent) - pIO->cBitsUsed / 8;
+}
+
+U32 getSizeWrite(BitIOInfo* pIO)
+{
+    return (U32)(UINTPTR_T)(pIO->pbCurrent + (pIO->pbStart <= pIO->pbCurrent ? 0 : PACKETLENGTH * 2) - pIO->pbStart) + pIO->cBitsUsed / 8;
+}
+
+//----------------------------------------------------------------
+// Query stream offset from attached BitIO object for dec
+//----------------------------------------------------------------
+U32 getPosRead(BitIOInfo* pIO)
+{
+    size_t cbCached = (pIO->pbStart + PACKETLENGTH * 2 - pIO->pbCurrent) - pIO->cBitsUsed / 8;
+    return (U32)(pIO->offRef - cbCached);
+}
+
+//================================================================
+// Block I/O functions
+//================================================================
+#ifndef ARMOPT_BITIO
+ERR attachISRead(BitIOInfo* pIO, struct WMPStream* pWS, CWMImageStrCodec* pSC)
+{
+    UNREFERENCED_PARAMETER( pSC );
+
+    pWS->GetPos(pWS, &pIO->offRef);
+
+    pIO->pbStart = (U8*)pIO - PACKETLENGTH * 2;
+    pIO->pbCurrent = pIO->pbStart;
+
+    PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
+    pWS->SetPos(pWS, pIO->offRef);
+    pWS->Read(pWS, pIO->pbStart, PACKETLENGTH * 2);
+    PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
+    pIO->offRef += PACKETLENGTH * 2;
+
+    pIO->uiAccumulator = load4BE(pIO->pbStart);
+    
+    pIO->cBitsUsed = 0;
+    pIO->iMask = ~(PACKETLENGTH * 2);
+    pIO->iMask &= ~1;
+
+    pIO->pWS = pWS;
+    return WMP_errSuccess;
+}
+
+ERR readIS(CWMImageStrCodec* pSC, BitIOInfo* pIO)
+{
+    ERR err = WMP_errSuccess;
+
+    UNREFERENCED_PARAMETER( pSC );
+
+    if (PACKET1(pIO->pbStart, pIO->pbCurrent, PACKETLENGTH))
+    {
+        struct WMPStream *pWS = pIO->pWS;
+
+        PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
+        //Call(0 != pIO->pWS->Read(pIO->pWS, pIO->pbStart, PACKETLENGTH));
+        // TODO: add error checking code
+        pWS->SetPos(pWS, pIO->offRef);
+        pWS->Read(pWS, pIO->pbStart, PACKETLENGTH);
+        pIO->offRef += PACKETLENGTH;
+        PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
+
+        // make shadow copy for first 4B
+        pIO->uiShadow = *(U32*)pIO->pbStart;
+
+        // reposition pbPacket pointer
+        pIO->pbStart = MASKPTR(pIO->pbStart + PACKETLENGTH, pIO->iMask);
+    }
+
+//Cleanup:
+    return err;
+}
+
+ERR detachISRead(CWMImageStrCodec* pSC, BitIOInfo* pIO)
+{
+    ERR err = WMP_errSuccess;
+
+    struct WMPStream* pWS = pIO->pWS;
+    size_t cbRemain = 0;
+
+    // we can ONLY detach IStream at byte boundary
+    flushToByte(pIO);
+    assert(0 == (pIO->cBitsUsed % 8));
+    Call(readIS_L1(pSC, pIO));
+
+    // set stream to right offset, undo buffering
+    cbRemain = (pIO->pbStart + PACKETLENGTH * 2) - (pIO->pbCurrent + pIO->cBitsUsed / 8);
+    pWS->SetPos(pWS, pIO->offRef - cbRemain);
+
+    pIO->pWS = NULL;
+Cleanup:
+    return err;
+}
+#endif  // ARMOPT_BITIO
+
+//----------------------------------------------------------------
+ERR attachISWrite(BitIOInfo* pIO, struct WMPStream* pWS)
+{
+    pWS->GetPos(pWS, &pIO->offRef);
+
+    pIO->pbStart = (U8*)pIO - PACKETLENGTH * 2;
+    pIO->pbCurrent = pIO->pbStart;
+
+    pIO->uiAccumulator = 0;
+    pIO->cBitsUsed = 0;
+    pIO->iMask = ~(PACKETLENGTH * 2);
+
+    pIO->pWS = pWS;
+    return WMP_errSuccess;
+}
+
+// write out packet if we have >=1 packet data filled
+ERR writeIS(CWMImageStrCodec* pSC, BitIOInfo* pIO)
+{
+    ERR err = WMP_errSuccess;
+
+    UNREFERENCED_PARAMETER( pSC );
+
+    if (PACKET1(pIO->pbStart, pIO->pbCurrent, PACKETLENGTH))
+    {
+        PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
+        err = pIO->pWS->Write(pIO->pWS, pIO->pbStart, PACKETLENGTH);
+        PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
+        Call(err);
+
+        // reposition pbStart pointer
+        pIO->pbStart = MASKPTR(pIO->pbStart + PACKETLENGTH, pIO->iMask);
+    }
+
+Cleanup:
+    return err;
+}
+
+// write out partially filled buffer and detach bitIO from IStream
+ERR detachISWrite(CWMImageStrCodec* pSC, BitIOInfo* pIO)
+{
+    ERR err = WMP_errSuccess;
+
+    // we can ONLY detach IStream at byte boundary
+    assert(0 == (pIO->cBitsUsed % 8));
+    Call(writeIS_L1(pSC, pIO));
+
+    PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
+    err = pIO->pWS->Write(pIO->pWS, pIO->pbStart, pIO->pbCurrent + pIO->cBitsUsed / 8 - pIO->pbStart);
+    PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
+    Call(err);
+
+    pIO->pWS = NULL;
+Cleanup:
+    return err;
+}
+
+//=========================
+// Performance Measurement
+//=========================
+#ifndef DISABLE_PERF_MEASUREMENT
+
+void OutputIndivPerfTimer(struct PERFTIMERSTATE *pPerfTimer,
+                          char *pszTimerName,
+                          char *pszDescription,
+                          float fltMegaPixels)
+{
+    PERFTIMERRESULTS    rResults;
+    Bool                fResult;
+
+    fResult = FALSE;
+    printf("%s (%s): ", pszTimerName, pszDescription);
+    if (pPerfTimer)
+    {
+        fResult = PerfTimerGetResults(pPerfTimer, &rResults);
+        if (fResult)
+        {
+            printf("%.3f milliseconds, %.6f MP/sec\n", (float)rResults.iElapsedTime / 1000000,
+                1000000000 * fltMegaPixels / rResults.iElapsedTime);
+            if (rResults.iZeroTimeIntervals > 0)
+            {
+                printf("   *** WARNING: %d time intervals were measured as zero. "
+                    "This perf timer has insufficient precision!\n\n",
+                    (int) rResults.iZeroTimeIntervals);
+            }
+        }
+    }
+    if (FALSE == fResult)
+        printf("Results not available!\n");
+}
+
+
+void OutputPerfTimerReport(CWMImageStrCodec *pState)
+{
+    float               fltMegaPixels;
+
+    assert(pState->m_fMeasurePerf);
+
+    printf("***************************************************************************\n");
+    printf("* Perf Report\n");
+    printf("***************************************************************************\n\n");
+    
+    fltMegaPixels = (float)pState->WMII.cWidth * pState->WMII.cHeight / 1000000;
+    printf("Image Width = %d, Height = %d, total MegaPixels = %.1f MP\n",
+        (int) pState->WMII.cWidth, (int) pState->WMII.cHeight, fltMegaPixels);
+
+    OutputIndivPerfTimer(pState->m_ptEncDecPerf, "m_ptEncDecPerf", "excl I/O", fltMegaPixels);
+    OutputIndivPerfTimer(pState->m_ptEndToEndPerf, "m_ptEndToEndPerf", "incl I/O", fltMegaPixels);
+}
+
+#endif // DISABLE_PERF_MEASUREMENT
diff --git a/Source/LibJXR/image/sys/strcodec.h b/Source/LibJXR/image/sys/strcodec.h
new file mode 100644
index 0000000..4715b6b
--- /dev/null
+++ b/Source/LibJXR/image/sys/strcodec.h
@@ -0,0 +1,681 @@
+//*@@@+++@@@@******************************************************************
+//
+// Copyright � Microsoft Corp.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+// � Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// � Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//*@@@---@@@@******************************************************************
+#pragma once
+
+#include <stddef.h>
+#if defined(__MINGW32__)
+#include <stdint.h>
+#endif
+
+#include "windowsmediaphoto.h"
+#include "common.h"
+// #include "xplatform_image.h"
+
+// added for Xcode PK universal binary
+#ifdef __ppc__
+#define _BIG__ENDIAN_
+#endif
+
+//================================================================
+#ifdef ENABLE_OPTIMIZATIONS
+#if defined(WIN32) && !defined(_WIN64)
+#define WMP_OPT_SSE2
+
+#define WMP_OPT_CC_ENC
+//#define WMP_OPT_TRFM_ENC
+//#define WMP_OPT_QT
+
+#define WMP_OPT_CC_DEC
+#define WMP_OPT_TRFM_DEC
+
+#define X86OPT_INLINE
+
+#endif
+#endif // ENABLE_OPTIMIZATIONS
+
+//================================================================
+//#ifdef WIN32
+#if defined(WIN32) && !defined(UNDER_CE)   // WIN32 seems to be defined always in VS2005 for ARM platform
+#define PLATFORM_X86
+#include "../x86/x86.h"
+#endif
+
+#ifndef UNREFERENCED_PARAMETER
+#define UNREFERENCED_PARAMETER(P) { (P) = (P); }
+#endif // UNREFERENCED_PARAMETER
+
+#ifdef UNDER_CE
+#define PLATFORM_WCE
+#include "arm.h"
+#endif
+
+#ifdef __ANSI__
+#define PLATFORM_ANSI
+#include "ansi.h"
+#endif
+
+//================================================================
+
+#ifdef PLATFORM_ANSI
+typedef unsigned long long U64;
+#else // PLATFORM_ANSI
+typedef unsigned __int64 U64;
+#endif // PLATFORM_ANSI
+
+//================================================================
+#define MARKERCOUNT (PACKETLENGTH * 2)
+
+// The following macros depend on UINTPTR_T and INTPTR_T being properly defined
+// so that they are equal to pointer width. Confirm and fail if our assumptions are wrong.
+CT_ASSERT(sizeof(UINTPTR_T) == sizeof(void*), strcodec1);
+CT_ASSERT(sizeof(INTPTR_T) == sizeof(void*), strcodec2);
+
+// wrap around pointer, s=pow(2,n), p wraps aligned to s
+#define WRAPPTR(p, s) ((void*)((UINTPTR_T)(p) & ~(UINTPTR_T)(s)))
+
+// mask certain bit inside a pointer, simulate wrap around
+#define MASKPTR(p, m) ((void*)((UINTPTR_T)(p) & (INTPTR_T)(m)))
+
+// test for more than 1 packet data
+#define PACKET1(ps, pc, s) (((INTPTR_T)(ps) ^ (INTPTR_T)(pc)) & ((UINTPTR_T)(s)))
+
+// alternate pointer p between 2 values aligned to s, s=pow(2,n)
+//#define ALTPTR(p, s) ((void*)((uintptr_t)(p) ^ (s)))
+
+// align point, s=pow(2,n), p aligns to s
+#define ALIGNUP(p, s) ((void*)(((UINTPTR_T)(p) + ((UINTPTR_T)(s) - 1)) & ~((UINTPTR_T)(s) - 1)))
+#define ALIGNDOWN(p, s) ((void*)((UINTPTR_T)(p) & ~((UINTPTR_T)(s) - 1)))
+
+//================================================================
+// timer support
+//================================================================
+
+#define TraceResult(a)
+
+//================================================================
+typedef enum tagPacketType
+{
+    PK_NULL = 0,
+    PK_DC = 1, PK_AD, PK_AC, PK_CP,
+    PK_MAX,
+} PACKETTYPE;
+
+typedef struct tagIOContext
+{
+    U8 P0[PACKETLENGTH];        // packet circular buffer 0
+    U8 P1[PACKETLENGTH];        // packet circular buffer 1
+
+    union
+    {
+        U8 P2[PACKETLENGTH];
+        struct
+        {
+            U32 uiShadow;   // shadow of P0[0]-P0[3]
+
+            U32 uiAccumulator;  // 32bit acc as bit field cache
+            U32 cBitsUsed;  // # of bits used of acc, [0,16)
+
+            U8* pbPacket;   // packet pointer
+            U8* pbCurrent;  // current pointer
+
+            struct WMPStream* pWS;    // pointer to WMPStream
+            long offPacket; // byte offset into stream
+
+            //ULARGE_INTEGER u64Acc; 
+
+    //========================================
+    // index packet, used for packet retrieval
+    //========================================
+            U32 cIndex; // current index for index packet
+            long offIndex;  // byte offset into stream for index packet
+        }State;
+    }P2Info;
+    U8 P3[PACKETLENGTH];    // index packet buffer
+} IOContext;
+
+typedef struct tagMemReadState
+{    
+    U8* pbBuf;
+    size_t cbBuf;
+    size_t cbCur;
+} MemReadState;
+
+typedef struct tagBitIOInfo
+{
+    U32 uiShadow;   // shadow of first 4B of circular buffer
+
+    U32 uiAccumulator;  // 32bit acc as bit field cache
+    U32 cBitsUsed;  // # of bits used of acc, [0,16)
+#ifdef ARMOPT_BITIO
+    U32 cBitsUnused;  // # of bits remain unused in acc, [0,32]
+#endif
+
+    I32 iMask;  // mask used simulate pointer wrap around
+
+    U8* pbStart;    // start pointer
+#ifndef ARMOPT_BITIO
+    U8* pbCurrent;  // current pointer
+#else
+    U32* pbCurrent;  // current pointer
+#endif
+
+    struct WMPStream* pWS;  // pointer to WMPStream
+    size_t offRef;  // reference offset on IStream,
+                            // for read, it moves along the stream
+                            // for write, it stays at the attach point
+} BitIOInfo;
+
+//================================================================
+typedef struct tagCWMIQuantizer {
+    U8 iIndex;
+    I32 iQP;
+    I32 iOffset;
+    I32 iMan;
+    I32 iExp;
+#if defined(WMP_OPT_QT)
+    float f1_QP;
+    double d1_QP;
+#endif    
+} CWMIQuantizer;
+
+/* temporary bridge between old APIs and streaming APIs */
+typedef struct tagCWMIMBInfo {
+    I32 iBlockDC[MAX_CHANNELS][16];
+    I32 iOrientation;
+    Int iCBP[MAX_CHANNELS];
+    Int iDiffCBP[MAX_CHANNELS];
+    U8 iQIndexLP; // 0 - 15
+    U8 iQIndexHP; // 0 - 15
+} CWMIMBInfo;
+
+struct CWMImageStrCodec;
+
+typedef Int (*ImageDataProc)(struct CWMImageStrCodec*);
+
+/** scan model **/
+typedef struct CAdaptiveScan {
+    U32		uTotal;
+    U32		uScan;
+} CAdaptiveScan;
+
+/** Adaptive context model **/
+typedef struct CCodingContext {
+    BitIOInfo * m_pIODC;
+    BitIOInfo * m_pIOLP;
+    BitIOInfo * m_pIOAC;
+    BitIOInfo * m_pIOFL;
+
+    /** adaptive huffman structs **/
+    CAdaptiveHuffman *m_pAdaptHuffCBPCY;
+    CAdaptiveHuffman *m_pAdaptHuffCBPCY1;
+    CAdaptiveHuffman *m_pAHexpt[NUMVLCTABLES];
+
+    /** 4x4 zigzag patterns */
+    CAdaptiveScan m_aScanLowpass[16];
+    CAdaptiveScan m_aScanHoriz[16];
+    CAdaptiveScan m_aScanVert[16];
+
+    /** Adaptive bit reduction model **/
+    CAdaptiveModel m_aModelAC;
+    CAdaptiveModel m_aModelLP;
+    CAdaptiveModel m_aModelDC;
+
+    /** Adaptive lowpass CBP model **/
+    Int     m_iCBPCountZero;
+    Int     m_iCBPCountMax;
+
+    /** Adaptive AC CBP model **/
+    CCBPModel m_aCBPModel;
+
+    /** Trim flex bits - externally set **/
+    Int     m_iTrimFlexBits;
+
+    Bool m_bInROI;  // inside ROI (for region decode and compressed domain cropping)?
+} CCodingContext;
+
+// Following stuff used to be in strPredQuant.h
+/* circulant buffer for 2 MB rows: current row and previous row */
+typedef struct tagCWMIPredInfo {
+    Int iQPIndex;     // QP Index
+    Int iCBP;      // coded block pattern
+    PixelI iDC;    // DC of MB
+    PixelI iAD[6];
+    PixelI * piAD; // AC of DC block: [2] 420UV [4] 422UV [6] elsewhere
+}CWMIPredInfo;
+
+// the following is used on decode side while reading image info
+typedef struct CWMImageStrCodecParameters {
+    size_t cVersion;
+    size_t cSubVersion;
+    COLORFORMAT cfColorFormat; // color format
+    Bool bRBSwapped; // blue and red shall be swapped in BGR555,565,101010
+    Bool bAlphaChannel; // alpha channel present
+    Bool bScaledArith; // lossless mode
+    Bool bIndexTable; // index table present
+    Bool bTrimFlexbitsFlag; // trimmed flexbits indicated in packet header
+    Bool bUseHardTileBoundaries; //default is soft tile boundaries
+    size_t cNumChannels;
+    size_t cExtraPixelsTop;
+    size_t cExtraPixelsLeft;
+    size_t cExtraPixelsBottom;
+    size_t cExtraPixelsRight;
+    Bool bTranscode;  // transcoding flag
+    U32 uQPMode;       // 0/1: no dquant/with dquant, first bit for DC, second bit for LP, third bit for HP
+    U8 uiQPIndexDC[MAX_CHANNELS];
+    U8 uiQPIndexLP[MAX_CHANNELS];
+    U8 uiQPIndexHP[MAX_CHANNELS];
+}CCoreParameters;
+
+typedef struct CWMITile
+{
+    CWMIQuantizer * pQuantizerDC[MAX_CHANNELS];
+    CWMIQuantizer * pQuantizerLP[MAX_CHANNELS];
+    CWMIQuantizer * pQuantizerHP[MAX_CHANNELS];
+    U8 cNumQPLP;
+    U8 cNumQPHP;
+    U8 cBitsLP;
+    U8 cBitsHP;
+
+    Bool bUseDC;
+    Bool bUseLP;
+    U8 cChModeDC;
+    U8 cChModeLP[16];
+    U8 cChModeHP[16];
+} CWMITile;
+
+#ifdef ARMOPT_COLORCONVERSION_C
+#include "ARM_InvColorConversion.h"
+#endif
+
+struct tagPostProcInfo{
+    Int iMBDC;                  // DC of MB
+    U8 ucMBTexture;             // MB texture   : 0(flat) 1(horizontal) 2(vertical) 3(bumpy)
+    Int iBlockDC[4][4];         // DC of block
+    U8 ucBlockTexture[4][4];    // block texture: 0(flat) 1(horizontal) 2(vertical) 3(bumpy)
+};
+
+typedef struct CWMImageStrCodec {
+#ifdef ARMOPT_COLORCONVERSION_C
+    CWMImageStrInvCCParam InvCCParam;
+#endif
+
+    size_t cbStruct;
+
+    CWMImageInfo WMII;
+    CWMIStrCodecParam WMISCP;
+    CWMImageBufferInfo WMIBI;
+    CWMIMBInfo MBInfo;
+
+    /** core parameters **/
+    CCoreParameters m_param;
+
+    struct CWMDecoderParameters *m_Dparam;  // this is specified thru pointer because the same set of parameters may be used by multiple image planes
+
+    U8 cSB;
+
+    Bool m_bUVResolutionChange;
+
+    Bool bTileExtraction;
+
+    BitIOInfo * pIOHeader;
+
+    Bool bUseHardTileBoundaries; //default is soft tile boundaries
+
+    PixelI * pInterU;
+    PixelI * pInterV;
+
+    //============== tile related info begins here ===========
+    // index table
+    size_t *pIndexTable;
+  
+    // current tile position
+    size_t cTileRow;
+    size_t cTileColumn;
+
+    // tile boundary
+    Bool m_bCtxLeft;
+    Bool m_bCtxTop;
+
+    Bool m_bResetRGITotals;
+    Bool m_bResetContext;
+
+    CWMITile * pTile;
+    
+    // BitIOs
+    BitIOInfo ** m_ppBitIO;
+    size_t cNumBitIO;
+    size_t cHeaderSize;
+
+    // coding contexts
+    struct CCodingContext *m_pCodingContext;
+    size_t cNumCodingContext;
+
+    //============== tile related info ends here  ===========
+
+    size_t cNumOfQPIndex;        // number of QP indexes
+    U8 cBitsDQUANT;              // number of bits to encode DQUANT
+
+    size_t cRow;        // row for current macro block
+    size_t cColumn;     // column for current macro block
+
+    size_t cmbWidth;    // macro block/image width
+    size_t cmbHeight;   // macro block/image height
+
+    size_t cbChannel;   // byte/channel
+
+    size_t mbX, mbY;
+    size_t tileX, tileY;
+    Bool bVertTileBoundary, bHoriTileBoundary;
+    Bool bOneMBLeftVertTB, bOneMBRightVertTB; //Macroblock to the left and to the right of tile boundaries
+
+    PixelI iPredBefore[2][2];
+    PixelI iPredAfter[2][2];
+
+    //================================
+    // input data into
+    // macro block 3 of 2x2 working widow
+    //================================
+    ImageDataProc Load;
+    //ImageDataProc Load2;
+    ImageDataProc Transform;
+    ImageDataProc TransformCenter;
+
+    //================================
+    ImageDataProc Quantize;
+    //ImageDataProc QuantizeLuma;
+    //ImageDataProc QuantizeChroma;
+
+    //================================
+    // process and store data from
+    // macro block 0 of 2x2 working window
+    //================================
+    ImageDataProc ProcessTopLeft;
+    ImageDataProc ProcessTop;
+    ImageDataProc ProcessTopRight;
+    ImageDataProc ProcessLeft;
+    ImageDataProc ProcessCenter;
+    ImageDataProc ProcessRight;
+    ImageDataProc ProcessBottomLeft;
+    ImageDataProc ProcessBottom;
+    ImageDataProc ProcessBottomRight;
+    
+
+    //================================
+    // 2 MB working window for encoder
+    //================================
+    PixelI *pPlane[MAX_CHANNELS];
+
+    //================================
+    // 2 rows of MB buffer
+    //================================
+    PixelI *a0MBbuffer[MAX_CHANNELS];  // pointer to start of previous MB row
+    PixelI *a1MBbuffer[MAX_CHANNELS];  // pointer to start of current MB row
+    PixelI *p0MBbuffer[MAX_CHANNELS];  // working pointer to start of previous row MB
+    PixelI *p1MBbuffer[MAX_CHANNELS];  // working pointer to start of current row MB
+
+    //================================
+    // downsampling buffer for UV
+    //================================
+    PixelI * pResU;
+    PixelI * pResV;
+
+    //================================
+    // circular buffer for 2 MB rows: current row and previous row
+    //================================
+    CWMIPredInfo *PredInfo[MAX_CHANNELS];
+    CWMIPredInfo *PredInfoPrevRow[MAX_CHANNELS];
+    CWMIPredInfo *pPredInfoMemory;
+
+    struct WMPStream ** ppWStream;
+
+#ifdef WIN32
+    TCHAR **ppTempFile;
+#else
+    char **ppTempFile;
+#endif
+
+    // interleaved alpha support - linked structure for Alpha channel
+    struct CWMImageStrCodec *m_pNextSC;
+    Bool   m_bSecondary;
+
+    //================================
+    // Perf Timers
+    //================================
+#ifndef DISABLE_PERF_MEASUREMENT
+    Bool            m_fMeasurePerf;
+    struct PERFTIMERSTATE *m_ptEndToEndPerf;   // Measures from Init to Term, including I/O
+    struct PERFTIMERSTATE *m_ptEncDecPerf;     // Measures time spent in ImageStrEncEncode/ImageStrDecDecode, excluding I/O
+#endif // DISABLE_PERF_MEASUREMENT
+
+    // postproc information for 2 MB rows: 0(previous row) 1(current row)
+    struct tagPostProcInfo * pPostProcInfo[MAX_CHANNELS][2];
+} CWMImageStrCodec;
+
+
+//================================================================
+ERR WMPAlloc(void** ppv, size_t cb);
+ERR WMPFree(void** ppv);
+
+//================================================================
+Void initMRPtr(CWMImageStrCodec*);
+Void advanceMRPtr(CWMImageStrCodec*);
+Void swapMRPtr(CWMImageStrCodec*);
+
+Int IDPEmpty(CWMImageStrCodec*);
+
+//================================================================
+extern const int dctIndex[3][16];
+extern const int blkOffset[16];
+extern const int blkOffsetUV[4];
+extern const int blkOffsetUV_422[8];
+
+extern const U8 idxCC[16][16];
+extern const U8 idxCC_420[8][8];
+
+extern const Char gGDISignature[];
+
+//================================================================
+Int allocatePredInfo(CWMImageStrCodec*);
+Void freePredInfo(CWMImageStrCodec*);
+Void advanceOneMBRow(CWMImageStrCodec*);
+
+//================================================================
+// bit I/O
+//================================================================
+Int allocateBitIOInfo(CWMImageStrCodec*);
+Int setBitIOPointers(CWMImageStrCodec* pSC);
+
+#ifndef ARMOPT_BITIO
+U32 peekBit16(BitIOInfo* pIO, U32 cBits);
+U32 flushBit16(BitIOInfo* pIO, U32 cBits);
+U32 getBit16(BitIOInfo* pIO, U32 cBits);
+U32 getBool16(BitIOInfo* pIO);
+I32 getBit16s(BitIOInfo* pIO, U32 cBits);
+U32 getBit32(BitIOInfo* pIO, U32 cBits);
+U32 flushToByte(BitIOInfo* pIO);
+#endif  // ARMOPT_BITIO
+
+Void putBit16z(BitIOInfo* pIO, U32 uiBits, U32 cBits);
+Void putBit16(BitIOInfo* pIO, U32 uiBits, U32 cBits);
+Void putBit32(BitIOInfo* pIO, U32 uiBits, U32 cBits);
+Void fillToByte(BitIOInfo* pIO);
+
+U32 getSizeRead(BitIOInfo* pIO);
+U32 getSizeWrite(BitIOInfo* pIO);
+
+U32 getPosRead(BitIOInfo* pIO);
+
+// safe function, solely for the convenience of test code
+#ifndef ARMOPT_BITIO
+U32 getBit16_S(CWMImageStrCodec* pSC, BitIOInfo* pIO, U32 cBits);
+#endif  // ARMOPT_BITIO
+
+//================================================================
+// packet I/O
+//================================================================
+ERR attachISRead(BitIOInfo* pIO, struct WMPStream* pWS, CWMImageStrCodec* pSC);
+ERR readIS(CWMImageStrCodec* pSC, BitIOInfo* pIO);
+ERR detachISRead(CWMImageStrCodec* pSC, BitIOInfo* pIO);
+
+ERR attachISWrite(BitIOInfo* pIO, struct WMPStream* pWS);
+ERR writeIS(CWMImageStrCodec* pSC, BitIOInfo* pIO);
+ERR detachISWrite(CWMImageStrCodec* pSC, BitIOInfo* pIO);
+
+
+//================================================================
+// post processing for decoder
+//================================================================
+Int initPostProc(struct tagPostProcInfo * strPostProcInfo[MAX_CHANNELS][2], size_t mbWidth, size_t iNumChannels);
+Void termPostProc(struct tagPostProcInfo * strPostProcInfo[MAX_CHANNELS][2], size_t iNumChannels);
+Void slideOneMBRow(struct tagPostProcInfo * strPostProcInfo[MAX_CHANNELS][2], size_t iNumChannels, size_t mbWidth, Bool top, Bool bottom);
+Void updatePostProcInfo(struct tagPostProcInfo * strPostProcInfo[MAX_CHANNELS][2], PixelI * p, size_t mbX, size_t cc);
+Void postProcMB(struct tagPostProcInfo * strPostProcInfo[MAX_CHANNELS][2], PixelI * p0, PixelI * p1, size_t mbX, size_t cc, Int threshold);
+Void postProcBlock(struct tagPostProcInfo * strPostProcInfo[MAX_CHANNELS][2], PixelI * p0, PixelI * p1, size_t mbX, size_t cc, Int threshold);
+
+//================================================================
+// Simple BitIO access functions
+//================================================================
+typedef struct tagSimpleBitIO
+{
+    struct WMPStream* pWS;
+    U32 cbRead;
+    U8 bAccumulator;
+    U32 cBitLeft;
+} SimpleBitIO;
+
+ERR attach_SB(SimpleBitIO* pSB, struct WMPStream* pWS);
+U32 getBit32_SB(SimpleBitIO* pSB, U32 cBits);
+Void flushToByte_SB(SimpleBitIO* pSB);
+U32 getByteRead_SB(SimpleBitIO* pSB);
+ERR detach_SB(SimpleBitIO* pSB);
+
+//----------------------------------------------------------------
+EXTERN_C Bool EOSWS_File(struct WMPStream* pWS);
+
+EXTERN_C ERR ReadWS_File(struct WMPStream* pWS, void* pv, size_t cb);
+EXTERN_C ERR WriteWS_File(struct WMPStream* pWS, const void* pv, size_t cb);
+//EXTERN_C ERR GetLineWS_File(struct WMPStream* pWS, void* pv, size_t cb);
+
+EXTERN_C ERR SetPosWS_File(struct WMPStream* pWS, size_t offPos);
+EXTERN_C ERR GetPosWS_File(struct WMPStream* pWS, size_t* poffPos);
+
+//----------------------------------------------------------------
+EXTERN_C Bool EOSWS_Memory(struct WMPStream* pWS);
+
+EXTERN_C ERR ReadWS_Memory(struct WMPStream* pWS, void* pv, size_t cb);
+EXTERN_C ERR WriteWS_Memory(struct WMPStream* pWS, const void* pv, size_t cb);
+//EXTERN_C ERR GetLineWS_Memory(struct WMPStream* pWS, void* pv, size_t cb);
+
+EXTERN_C ERR SetPosWS_Memory(struct WMPStream* pWS, size_t offPos);
+EXTERN_C ERR GetPosWS_Memory(struct WMPStream* pWS, size_t* poffPos);
+
+//EXTERN_C ERR GetPtrWS_Memory(struct WMPStream* pWS, size_t align, U8** ppb);
+//----------------------------------------------------------------
+EXTERN_C Bool EOSWS_List(struct WMPStream* pWS);
+
+EXTERN_C ERR ReadWS_List(struct WMPStream* pWS, void* pv, size_t cb);
+EXTERN_C ERR WriteWS_List(struct WMPStream* pWS, const void* pv, size_t cb);
+
+EXTERN_C ERR SetPosWS_List(struct WMPStream* pWS, size_t offPos);
+EXTERN_C ERR GetPosWS_List(struct WMPStream* pWS, size_t* poffPos);
+
+EXTERN_C ERR CreateWS_List(struct WMPStream** ppWS);
+EXTERN_C ERR CloseWS_List(struct WMPStream** ppWS);
+
+/********************************************************************/
+// Stuff related to scale/spatial ordering
+typedef struct PacketInfo
+{
+    BAND    m_iBand;
+    size_t  m_iSize;
+    size_t  m_iOffset;
+    struct PacketInfo *m_pNext;
+} PacketInfo;
+/********************************************************************/
+
+/********************************************************************/
+const static Int blkIdxByRow[4][4] = {{0, 1, 4, 5}, {2, 3, 6, 7}, {8, 9, 12, 13}, {10, 11, 14, 15}};
+const static Int blkIdxByColumn[4][4] = {{0, 2, 8, 10}, {1, 3, 9, 11},{4, 6, 12, 14},{5, 7, 13, 15}};
+
+Int getACPredMode(CWMIMBInfo *, COLORFORMAT);
+Int getDCACPredMode(CWMImageStrCodec *, size_t);
+Void updatePredInfo(CWMImageStrCodec* pSC, CWMIMBInfo *, size_t, COLORFORMAT);
+
+Int AllocateCodingContextDec(struct CWMImageStrCodec *pSC, Int iNumContexts);
+Void ResetCodingContext(CCodingContext *pContext);
+Void getTilePos(CWMImageStrCodec* pSC, size_t mbX, size_t mbY);
+Void InitZigzagScan(CCodingContext * pSC);
+Int checkImageBuffer(CWMImageStrCodec *, size_t, size_t);
+
+//U32 log2(U32);
+
+//DQUANT stuff
+EXTERN_C Void remapQP(CWMIQuantizer *, I32, Bool);
+Int allocateTileInfo(CWMImageStrCodec *);
+Void freeTileInfo(CWMImageStrCodec *);
+Int allocateQuantizer(CWMIQuantizer * pQuantizer[MAX_CHANNELS], size_t, size_t);
+Void freeQuantizer(CWMIQuantizer * pQuantizer[MAX_CHANNELS]);
+Void setUniformQuantizer(CWMImageStrCodec *, size_t);
+Void useDCQuantizer(CWMImageStrCodec *, size_t);
+Void useLPQuantizer(CWMImageStrCodec *, size_t, size_t);
+Void formatQuantizer(CWMIQuantizer * pQuantizer[MAX_CHANNELS], U8, size_t, size_t, Bool, Bool);
+U8 dquantBits(U8);
+
+#ifdef ARMOPT_BITIO
+#define peekBit16   peekBits
+#define flushBit16  flushBits
+#define getBit16    getBits
+#define getBit32    getBits
+#define getBit16s   getBitsS
+#define getBool16(pIO) getBits(pIO, 1)   
+
+U32 peekBits(BitIOInfo* pIO, U32 cBits);
+void flushBits(BitIOInfo* pIO, U32 cBits);
+U32 getBits(BitIOInfo* pIO, U32 cBits);
+U32 getBitsS(BitIOInfo* pIO, U32 cBits);
+void flushToByte(BitIOInfo* pIO);
+#endif // ARMOPT_BITIO
+
+/*************************************************************************
+    Bitio defines
+*************************************************************************/
+#define PEEKBIT16(pIO, cBits) \
+    assert(0 <= (I32)cBits && cBits <= 16);\
+    return (pIO->uiAccumulator >> (32 - cBits/* - pIO->cBitsUsed*/));
+
+#define FLUSHBIT16(pIO, cBits) \
+    assert(0 <= (I32)cBits && cBits <= 16);\
+    assert((pIO->iMask & 1) == 0);\
+    pIO->cBitsUsed += cBits;\
+    pIO->pbCurrent = MASKPTR(pIO->pbCurrent + ((pIO->cBitsUsed >> 3)/* & 2*/), pIO->iMask);\
+    pIO->cBitsUsed &= 16 - 1;\
+    pIO->uiAccumulator = LOAD16(pIO->pbCurrent) << pIO->cBitsUsed;\
+    return 0;
+//    pIO->uiAccumulator = LOAD16(pIO->pbCurrent) & ((U32)(-1) >> pIO->cBitsUsed);\
+
+void OutputPerfTimerReport(CWMImageStrCodec *pState);
diff --git a/Source/LibJXR/image/sys/windowsmediaphoto.h b/Source/LibJXR/image/sys/windowsmediaphoto.h
new file mode 100644
index 0000000..fad7ad7
--- /dev/null
+++ b/Source/LibJXR/image/sys/windowsmediaphoto.h
@@ -0,0 +1,515 @@
+//*@@@+++@@@@******************************************************************
+//
+// Copyright � Microsoft Corp.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+// � Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// � Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//*@@@---@@@@******************************************************************
+
+#ifndef WMI_WINDOWSMEDIAPHOTO_H
+#define WMI_WINDOWSMEDIAPHOTO_H
+
+//================================================================
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if defined(__cplusplus) && !defined(EXTERN_C)
+#define EXTERN_C extern "C"
+#elif !defined(EXTERN_C)// __cplusplus
+#define EXTERN_C extern
+#endif // __cplusplus
+
+/********************************************************************************
+  Type definitions
+********************************************************************************/
+typedef int Bool;
+typedef char Char;
+typedef double Double;
+typedef int Int;
+typedef signed char I8;
+typedef short I16; // 16 bit int
+typedef int I32;
+typedef long Long;
+typedef unsigned char  PixelC;
+typedef int PixelI;
+typedef unsigned int UInt;
+typedef unsigned long ULong;
+typedef unsigned char U8; // 8 bit uint
+typedef unsigned short U16;
+typedef unsigned int U32; // 32 bit uint
+typedef void Void;
+
+typedef void* CTXSTRCODEC;
+
+
+#define REENTRANT_MODE 1
+/*
+    DESCRIPTION OF COMPILER FLAG REENTRANT_MODE:
+
+    //#define REENTRANT_MODE 1
+
+    This compiler flag is related to the capability of banded decode 
+    (decoding only one MB row of the source JPEG XR image at a time). 
+	
+    With REENTRANT_MODE defined, the decoder decodes one MB row on each call to 
+    ImageStrDecDecode().
+    
+    The decoder acts as if it can only write to the single MBRow whose pointer was passed to it. 
+    This acts as a proof of concept that the API would work if you passed it a small buffer 
+    on each call to ImageStrDecDecode(). 
+	
+    The REENTRANT_MODE flag only works when the output image is in Orientations 0, 1 
+    (vertically	flipped) or 2 (horizontally flipped).
+
+    With REENTRANT_MODE defined, the function PKImageDecode_Copy_WMP()
+    decodes only as far as the pRect parameter indicates. The width of the rectangle must be the width
+    of the image, but on each call, this function will decode the image up to the end of the MB Row 
+    which contains the i-th pixel row, where i = pRect->Y. 
+
+    A target use of this version would be to have PKImageDecode_Copy_WMP() called in a loop, once for
+    each MB row. On each call, pRect would specify a 1-MB-Row-tall rectangle that is the width of the 
+    image. The decoder state is preserved until the Decoder finishes decoding the image.
+
+    If, at a certain point, a request is made for a rectangle _above_ the last row decoded, then the
+    decoder instance is terminated and re-initiated, and decoding re-starts, going from the beginning 
+    of the image to the end of the current rectangle.
+
+    ***
+
+    We've chosen to uncomment-out this definition in this header file.  An alternate method would be
+    to allow the user to define this in the PREPROCESSOR DEFINITIONS section of the properties page
+    for each of the following projects: CommonLib, DecodeLib, JXRDecApp and JXRGlueLib.
+
+*/
+/*************************************************************************
+    enums
+*************************************************************************/
+typedef enum {
+    ICERR_OK = 0, ICERR_ERROR = -1
+} ERR_CODE;
+
+typedef enum BITDEPTH {
+    BD_SHORT, BD_LONG,
+
+    /* add new BITDEPTH here */ BD_MAX
+} BITDEPTH;
+
+typedef enum BITDEPTH_BITS {
+    // regular ones
+    BD_1, //White is foreground
+    BD_8, BD_16, BD_16S, BD_16F, BD_32, BD_32S, BD_32F,
+
+    // irregular ones
+    BD_5, BD_10, BD_565,
+
+    /* add new BITDEPTH_BITS here */ BDB_MAX,
+
+    BD_1alt = 0xf, //Black is foreground
+} BITDEPTH_BITS;
+
+typedef enum OVERLAP {
+    OL_NONE = 0, OL_ONE, OL_TWO,
+
+    /* add new OVERLAP here */ OL_MAX
+} OVERLAP;
+
+typedef enum BITSTREAMFORMAT {
+    SPATIAL = 0,     // spatial order
+    FREQUENCY,       // frequency order
+} BITSTREAMFORMAT;
+
+typedef enum COLORFORMAT {
+    Y_ONLY  = 0, 
+	YUV_420 = 1,
+	YUV_422 = 2,
+	YUV_444 = 3,
+	CMYK    = 4, 
+	//CMYKDIRECT = 5,
+	NCOMPONENT = 6,
+
+    // these are external-only
+    CF_RGB  = 7,
+	CF_RGBE = 8,
+
+    /* add new COLORFORMAT here */ CFT_MAX
+} COLORFORMAT;
+
+// rotation and flip
+typedef enum ORIENTATION {
+    // CRW: Clock Wise 90% Rotation; FlipH: Flip Horizontally;  FlipV: Flip Vertically
+    // Peform rotation FIRST!
+    //                CRW FlipH FlipV
+    O_NONE = 0,    // 0    0     0
+    O_FLIPV,       // 0    0     1
+    O_FLIPH,       // 0    1     0
+    O_FLIPVH,      // 0    1     1
+    O_RCW,         // 1    0     0
+    O_RCW_FLIPV,   // 1    0     1
+    O_RCW_FLIPH,   // 1    1     0
+    O_RCW_FLIPVH,  // 1    1     1
+    /* add new ORIENTATION here */ O_MAX
+} ORIENTATION;
+
+typedef enum SUBBAND {
+    SB_ALL = 0,             // keep all subbands
+    SB_NO_FLEXBITS,     // skip flex bits
+    SB_NO_HIGHPASS,     // skip highpass
+    SB_DC_ONLY,         // skip lowpass and highpass, DC only
+    SB_ISOLATED,        // not decodable
+    /* add new SUBBAND here */ SB_MAX
+} SUBBAND;
+
+enum { RAW = 0, BMP = 1, PPM = 2, TIF = 3, HDR = 4, IYUV = 5, YUV422 = 6, YUV444 = 7};
+
+typedef enum {ERROR_FAIL = -1, SUCCESS_DONE, PRE_READ_HDR, PRE_SETUP, PRE_DECODE, POST_READ_HDR } WMIDecoderStatus;
+
+#ifndef FALSE
+#define FALSE 0
+#endif // FALSE
+
+#ifndef TRUE
+#define TRUE 1
+#endif // TRUE
+
+#define MAX_CHANNELS 16
+#define LOG_MAX_TILES 12
+#define MAX_TILES (1 << LOG_MAX_TILES)
+
+
+//================================================================
+// Codec-specific constants
+#define MB_WIDTH_PIXEL 16
+#define MB_HEIGHT_PIXEL 16
+
+#define BLK_WIDTH_PIXEL 4
+#define BLK_HEIGHT_PIXEL 4
+
+#define MB_WIDTH_BLK 4
+#define MB_HEIGHT_BLK 4
+
+// The codec operates most efficiently when the framebuffers for encoder input
+// and decoder output are: 1) aligned on a particular boundary, and 2) the stride
+// is also aligned to this boundary (so that each scanline is also aligned).
+// This boundary is defined below.
+#define FRAMEBUFFER_ALIGNMENT 128
+
+
+//================================================================
+#define WMP_errSuccess 0
+
+#define WMP_errFail -1
+#define WMP_errNotYetImplemented -2
+#define WMP_errAbstractMethod -3
+
+#define WMP_errOutOfMemory -101
+#define WMP_errFileIO -102
+#define WMP_errBufferOverflow -103
+#define WMP_errInvalidParameter -104
+#define WMP_errInvalidArgument -105
+#define WMP_errUnsupportedFormat -106
+#define WMP_errIncorrectCodecVersion -107
+#define WMP_errIndexNotFound -108
+#define WMP_errOutOfSequence -109
+#define WMP_errNotInitialized -110
+#define WMP_errMustBeMultipleOf16LinesUntilLastCall -111
+#define WMP_errPlanarAlphaBandedEncRequiresTempFile -112
+#define WMP_errAlphaModeCannotBeTranscoded -113
+#define WMP_errIncorrectCodecSubVersion -114
+
+
+//================================================================
+typedef long ERR;
+
+#define Failed(err) ((err)<0)
+
+#define CRLF "\r\n"
+
+#define CT_ASSERT(exp, uniq) typedef char __CT_ASSERT__##uniq[(exp) ? 1 : -1] // Caller must provide a unique tag, or this fails to compile under GCC
+
+#if defined(_DEBUG) || defined(DBG)
+#define Report(err, szExp, szFile, nLine) \
+    fprintf(stderr, "FAILED: %ld=%s" CRLF, (err), (szExp)); \
+    fprintf(stderr, "        %s:%ld" CRLF, (szFile), (nLine));  \
+
+#else
+#define Report(err, szExp, szFile, lLine) err = err
+#endif
+
+#define Call(exp) \
+    if (Failed(err = (exp))) \
+    { \
+        Report(err, #exp, __FILE__, (long)__LINE__); \
+        goto Cleanup; \
+    } \
+    else err = err
+
+#define CallIgnoreError(errTmp, exp) \
+    if (Failed(errTmp = (exp))) \
+    { \
+        Report(errTmp, #exp, __FILE__, (long)__LINE__); \
+    } \
+    else errTmp = errTmp
+
+
+#define Test(exp, err) Call((exp) ? WMP_errSuccess : (err))
+#define FailIf(exp, err) Call((exp) ? (err) : WMP_errSuccess)
+
+//================================================================
+// WMPStream interface
+//================================================================
+struct WMPStream
+{
+    union
+    {
+        struct tagFile
+        {
+            FILE* pFile;
+        } file;
+
+        struct tagBuf
+        {
+            U8* pbBuf;
+            size_t cbBuf;
+            size_t cbCur;
+            size_t cbBufCount;
+        } buf;
+
+        void* pvObj;
+    } state;
+
+    Bool fMem;
+
+    ERR (*Close)(struct WMPStream** pme);
+
+    Bool (*EOS)(struct WMPStream* me);
+    
+    ERR (*Read)(struct WMPStream* me, void* pv, size_t cb);
+    ERR (*Write)(struct WMPStream* me, const void* pv, size_t cb);
+    //ERR (*GetLine)(struct WMPStream* me, void* pv, size_t cb);
+
+    ERR (*SetPos)(struct WMPStream* me, size_t offPos);
+    ERR (*GetPos)(struct WMPStream* me, size_t* poffPos);
+};
+
+EXTERN_C ERR CreateWS_File(struct WMPStream** ppWS, const char* szFilename, const char* szMode);
+EXTERN_C ERR CloseWS_File(struct WMPStream** ppWS);
+
+EXTERN_C ERR CreateWS_Memory(struct WMPStream** ppWS, void* pv, size_t cb);
+EXTERN_C ERR CloseWS_Memory(struct WMPStream** ppWS);
+
+
+//================================================================
+// Enc/Dec data structure
+//================================================================
+typedef struct tagCWMImageInfo {
+    size_t cWidth;
+    size_t cHeight;
+    COLORFORMAT cfColorFormat;
+    BITDEPTH_BITS bdBitDepth;
+    size_t cBitsPerUnit;
+    size_t cLeadingPadding; // number of leading padding
+    Bool bRGB; // true: RGB;  false: BGR
+    U8 cChromaCenteringX; // Relative location of Chroma w.r.t Luma
+    U8 cChromaCenteringY; // Relative location of Chroma w.r.t Luma
+
+    // Region of interest decoding
+    size_t cROILeftX;
+    size_t cROIWidth;
+    size_t cROITopY;
+    size_t cROIHeight;
+
+    // thumbnail decode
+    Bool   bSkipFlexbits;
+    size_t cThumbnailWidth;
+    size_t cThumbnailHeight;
+
+    // image orientation
+    ORIENTATION oOrientation;
+
+    // post processing
+    U8 cPostProcStrength; // 0(none) 1(light) 2(medium) 3(strong) 4(very strong)
+
+    // user buffer is always padded to whole MB
+    Bool fPaddedUserBuffer;
+} CWMImageInfo;
+
+typedef struct tagCWMIStrCodecParam {
+    Bool bVerbose;
+
+    // for macroblock quantization (DQUANT)
+    U8 uiDefaultQPIndex;
+    U8 uiDefaultQPIndexYLP;
+    U8 uiDefaultQPIndexYHP;
+    U8 uiDefaultQPIndexU;
+    U8 uiDefaultQPIndexULP;
+    U8 uiDefaultQPIndexUHP;
+    U8 uiDefaultQPIndexV;
+    U8 uiDefaultQPIndexVLP;
+    U8 uiDefaultQPIndexVHP;
+    U8 uiDefaultQPIndexAlpha;
+
+    COLORFORMAT cfColorFormat; 
+    BITDEPTH bdBitDepth;
+    OVERLAP olOverlap;
+    BITSTREAMFORMAT bfBitstreamFormat;
+    size_t cChannel; // number of color channels including alpha
+    U8 uAlphaMode; // 0:no alpha 1: alpha only else: something + alpha 
+    SUBBAND sbSubband;  // which subbands to keep
+    U8  uiTrimFlexBits;
+
+    struct WMPStream* pWStream;
+    size_t cbStream;
+
+    // tiling info
+    U32  cNumOfSliceMinus1V;     // # of vertical slices
+    U32 uiTileX[MAX_TILES]; // width in MB of each veritical slice
+    U32  cNumOfSliceMinus1H;     // # of horizontal slices
+    U32 uiTileY[MAX_TILES]; // height in MB of each horizontal slice
+
+    //32f and 32s conversion parameters
+    U8 nLenMantissaOrShift;
+    I8 nExpBias;
+
+    Bool bBlackWhite;
+
+    Bool bUseHardTileBoundaries; //default is soft tile boundaries
+ 
+    Bool bProgressiveMode; //default is sequential mode
+
+    Bool bYUVData; //default is cfColorFormat data
+
+    Bool bUnscaledArith; //force unscaled arithmetic
+   
+    // Perf measurement
+    Bool fMeasurePerf;
+} CWMIStrCodecParam;
+
+typedef struct tagCWMImageBufferInfo {
+    void* pv;           // pointer to scanline buffer
+    size_t cLine;       // count of scanlines
+    size_t cbStride;    // count of BYTE for stride
+#ifdef REENTRANT_MODE
+    unsigned int uiFirstMBRow;     // Current First MB Row being decoded
+    unsigned int uiLastMBRow;     // Current Last MB Row being decoded
+    size_t cLinesDecoded;         // Number of lines decoded and returned in low-mem mode
+#endif // REENTRANT_MODE
+} CWMImageBufferInfo;
+
+
+
+
+/****************************************************************/
+/* Encode API                                                   */
+/****************************************************************/
+EXTERN_C Int ImageStrEncInit(
+    CWMImageInfo* pII,
+    CWMIStrCodecParam *pSCP,
+    CTXSTRCODEC* pctxSC);
+
+EXTERN_C Int ImageStrEncEncode(
+    CTXSTRCODEC ctxSC,
+    const CWMImageBufferInfo* pBI);
+
+EXTERN_C Int ImageStrEncTerm(
+    CTXSTRCODEC ctxSC);
+
+
+/****************************************************************/
+/* Decode API                                                   */
+/****************************************************************/
+struct CWMImageStrCodec;
+
+EXTERN_C Int ImageStrDecGetInfo(
+    CWMImageInfo* pII,
+    CWMIStrCodecParam *pSCP);
+
+EXTERN_C Int ImageStrDecInit(
+    CWMImageInfo* pII,
+    CWMIStrCodecParam *pSCP,
+    CTXSTRCODEC* pctxSC);
+
+EXTERN_C Int ImageStrDecDecode(
+    CTXSTRCODEC ctxSC,
+    const CWMImageBufferInfo* pBI
+#ifdef REENTRANT_MODE
+    , size_t *pcDecodedLines
+#endif    
+    );
+
+EXTERN_C Int ImageStrDecTerm(
+    CTXSTRCODEC ctxSC);
+
+EXTERN_C Int WMPhotoValidate(
+    CWMImageInfo * pII,
+    CWMIStrCodecParam * pSCP);
+
+
+/****************************************************************/
+/* Transcoding API                                              */
+/****************************************************************/
+typedef struct tagCWMTranscodingParam {
+    size_t cLeftX;
+    size_t cWidth;
+    size_t cTopY;
+    size_t cHeight;  // interested region
+
+    BITSTREAMFORMAT bfBitstreamFormat; // desired bitstream format
+//    COLORFORMAT cfColorFormat; // desired color format
+    U8 uAlphaMode; // 0:no alpha 1: alpha only else: something + alpha 
+    SUBBAND sbSubband;  // which subbands to keep
+    ORIENTATION oOrientation; // flip / right angle rotation
+    Bool bIgnoreOverlap;
+} CWMTranscodingParam;
+
+EXTERN_C Int WMPhotoTranscode(
+    struct WMPStream* pStreamDec,   // input bitstrean
+    struct WMPStream* pStreamEnc,   // output bitstream
+    CWMTranscodingParam* pParam     // transcoding parameters
+);
+
+typedef struct tagCWMDetilingParam {
+    size_t cWidth;
+    size_t cHeight;  // image size
+    size_t cChannel; // # of channels
+    OVERLAP olOverlap; // overlap
+    BITDEPTH_BITS bdBitdepth; // bit depth
+
+    // tiling info
+    U32  cNumOfSliceMinus1V;     // # of vertical slices
+    U32 uiTileX[MAX_TILES]; // position in MB of each veritical slice
+    U32  cNumOfSliceMinus1H;     // # of horizontal slices
+    U32 uiTileY[MAX_TILES]; // position in MB of each horizontal slice
+
+    // image info
+    void * pImage;
+    size_t cbStride;
+} CWMDetilingParam;
+
+EXTERN_C Int WMPhotoDetile(
+    CWMDetilingParam * pParam   // detiling parameters
+);
+
+#endif // WMI_WINDOWSMEDIAPHOTO_H
+
diff --git a/Source/LibJXR/image/sys/xplatform_image.h b/Source/LibJXR/image/sys/xplatform_image.h
new file mode 100644
index 0000000..cf58230
--- /dev/null
+++ b/Source/LibJXR/image/sys/xplatform_image.h
@@ -0,0 +1,84 @@
+//*@@@+++@@@@******************************************************************
+//
+// Copyright � Microsoft Corp.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+// � Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// � Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//*@@@---@@@@******************************************************************
+
+#ifndef XPLATFORM_IMAGE_H
+#define XPLATFORM_IMAGE_H
+
+#ifdef __ANSI__
+// ANSI
+#define FORCE_INLINE 
+#define CDECL
+#define UINTPTR_T unsigned int
+#define INTPTR_T int
+#define DECLSPEC_ALIGN(bytes)
+#endif	// __ANSI__
+
+
+//#if defined(WIN32)
+#if defined(WIN32) && !defined(UNDER_CE)  // WIN32 seems to be defined always in VS2005 for ARM platform
+// x86
+//#define CDECL __cdecl
+#define DECLSPEC_ALIGN(bytes) __declspec(align(bytes))
+#endif	// x86
+
+
+#if defined(_ARM_) || defined(UNDER_CE)
+// ARM, WinCE
+#define FORCE_INLINE inline
+#define CDECL
+#define UINTPTR_T unsigned int
+#define INTPTR_T int
+#define DECLSPEC_ALIGN(bytes)
+
+// parser
+#define FULL_PATH_CONFIG_FILE_ENCODE    "\\ConfigFile_encode.txt"
+#define FULL_PATH_CONFIG_FILE_DECODE    "\\ConfigFile_decode.txt"
+#define MAX_ARGC 14
+#define MaxCharReadCount 10
+#define MAX_FNAME 256
+#define DELIMITER "filelist:"
+#define CODEC_ENCODE "encode"
+#define CODEC_DECODE "decode"
+#define PHOTON "ptn"
+#define OUTRAW "raw"
+#define OUTBMP "bmp"
+#define OUTPPM "ppm"
+#define OUTTIF "tif"
+#define OUTHDR "hdr"
+#define OUTIYUV "iyuv"
+#define OUTYUV422 "yuv422"
+#define OUTYUV444 "yuv444"
+int XPLATparser(char *pcARGV[], char *pcCodec);
+void freeXPLATparser(int iARGC, char *pcARGV[]);
+
+// WinCE intrinsic
+#include <Cmnintrin.h>
+#endif  // ARM, WinCE
+
+#endif      // XPLATFORM_IMAGE_H
+
diff --git a/Source/LibJXR/image/x86/x86.h b/Source/LibJXR/image/x86/x86.h
new file mode 100644
index 0000000..c182fc9
--- /dev/null
+++ b/Source/LibJXR/image/x86/x86.h
@@ -0,0 +1,58 @@
+//*@@@+++@@@@******************************************************************
+//
+// Copyright � Microsoft Corp.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+// � Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// � Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//*@@@---@@@@******************************************************************
+#pragma once
+
+#include <assert.h>
+#include <windows.h>
+
+//================================
+// bitio functions
+//================================
+#define PACKETLENGTH (1U<<12)   // 4kB
+
+#define readIS_L1(pSC, pIO) readIS(pSC, pIO)
+#define readIS_L2(pSC, pIO) (void)(pSC, pIO)
+
+#define writeIS_L1(pSC, pIO) writeIS(pSC, pIO)
+#define writeIS_L2(pSC, pIO) (void)(pSC, pIO)
+
+
+//================================
+// common defines
+//================================
+#define FORCE_INLINE __forceinline
+#define UINTPTR_T uintptr_t
+#define INTPTR_T intptr_t
+
+
+//================================
+// quantization optimization
+//================================
+#define RECIP_QUANT_OPT
+
+
diff --git a/Source/LibJXR/jxrgluelib/JXRGlue.c b/Source/LibJXR/jxrgluelib/JXRGlue.c
new file mode 100644
index 0000000..028d0c5
--- /dev/null
+++ b/Source/LibJXR/jxrgluelib/JXRGlue.c
@@ -0,0 +1,930 @@
+//*@@@+++@@@@******************************************************************
+//
+// Copyright � Microsoft Corp.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+// � Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// � Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//*@@@---@@@@******************************************************************
+#include <stdlib.h>
+#include <ctype.h>
+
+#define INITGUID
+#include <JXRGlue.h>
+
+//================================================================
+const PKIID IID_PKImageScanEncode = 1;
+const PKIID IID_PKImageFrameEncode = 2;
+
+const PKIID IID_PKImageUnsupported = 100;
+const PKIID IID_PKImageWmpEncode = 101;
+
+const PKIID IID_PKImageWmpDecode = 201;
+
+//================================================================
+// Misc supporting functions
+//================================================================
+ERR PKAlloc(void** ppv, size_t cb)
+{
+    *ppv = calloc(1, cb);
+    return *ppv ? WMP_errSuccess : WMP_errOutOfMemory;
+}
+
+
+ERR PKFree(void** ppv)
+{
+    if (ppv)
+    {
+        free(*ppv);
+        *ppv = NULL;
+    }
+
+    return WMP_errSuccess;
+}
+
+ERR PKAllocAligned(void** ppv, size_t cb, size_t iAlign)
+{
+    U8          *pOrigPtr;
+    U8          *pReturnedPtr;
+    size_t       iAlignmentCorrection;
+    const size_t c_cbBlockSize = cb + sizeof(void*) + iAlign - 1;
+
+    *ppv = NULL;
+    pOrigPtr = calloc(1, c_cbBlockSize);
+    if (NULL == pOrigPtr)
+        return WMP_errOutOfMemory;
+
+    iAlignmentCorrection = iAlign - ((size_t)pOrigPtr % iAlign);
+    if (iAlignmentCorrection < sizeof(void*))
+        // Alignment correction won't leave us enough space to store pOrigPtr - advance to next block
+        iAlignmentCorrection += iAlign;
+
+    assert(iAlignmentCorrection >= sizeof(void*)); // Alignment correction must have space for pOrigPtr
+    assert(iAlignmentCorrection + cb <= c_cbBlockSize); // Don't exceed right edge of memory block
+
+    pReturnedPtr = pOrigPtr + iAlignmentCorrection;
+    *(void**)(pReturnedPtr - sizeof(void*)) = pOrigPtr;
+
+    assert(0 == ((size_t)pReturnedPtr % iAlign)); // Are we in fact aligned?
+    *ppv = pReturnedPtr;
+    return WMP_errSuccess;
+}
+
+ERR PKFreeAligned(void** ppv)
+{
+    if (ppv && *ppv)
+    {
+        U8 **ppOrigPtr = (U8**)((U8*)(*ppv) - sizeof(void*));
+        assert(*ppOrigPtr <= (U8*)ppOrigPtr); // Something's wrong if pOrigPtr points forward
+        free(*ppOrigPtr);
+        *ppv = NULL;
+    }
+    return WMP_errSuccess;
+}
+
+
+
+int PKStrnicmp(const char* s1, const char* s2, size_t c)
+{
+    for(; tolower(*s1) == tolower(*s2) && *s1 && *s2 && c; ++s1, ++s2, --c);
+    return c ? *s1 - *s2 : 0;
+}
+
+static const PKPixelInfo pixelInfo[] =
+{
+    {&GUID_PKPixelFormatDontCare, 1, Y_ONLY, BD_8, 8, PK_pixfmtNul, 0, 0, 0, 0},
+
+    // Gray
+    //{&GUID_PKPixelFormat2bppGray, 1, Y_ONLY, BD_8, 2, PK_pixfmtNul},
+    //{&GUID_PKPixelFormat4bppGray, 1, Y_ONLY, BD_8, 4, PK_pixfmtNul},
+
+    {&GUID_PKPixelFormatBlackWhite, 1, Y_ONLY, BD_1, 1, PK_pixfmtNul,               1, 1, 1, 1},//BlackIsZero is default for GUID_PKPixelFormatBlackWhite
+    {&GUID_PKPixelFormatBlackWhite, 1, Y_ONLY, BD_1, 1, PK_pixfmtNul,               0, 1, 1, 1},//WhiteIsZero
+    {&GUID_PKPixelFormat8bppGray, 1, Y_ONLY, BD_8, 8, PK_pixfmtNul,                 1, 1, 8, 1},
+    {&GUID_PKPixelFormat16bppGray, 1, Y_ONLY, BD_16, 16, PK_pixfmtNul,              1, 1, 16, 1},
+    {&GUID_PKPixelFormat16bppGrayFixedPoint, 1, Y_ONLY, BD_16S, 16, PK_pixfmtNul,   1, 1, 16, 2},
+    {&GUID_PKPixelFormat16bppGrayHalf, 1, Y_ONLY, BD_16F, 16, PK_pixfmtNul,         1, 1, 16, 3},
+    //{&GUID_PKPixelFormat32bppGray, 1, Y_ONLY, BD_32, 32, PK_pixfmtNul,              1, 1, 32, 1},
+    {&GUID_PKPixelFormat32bppGrayFixedPoint, 1, Y_ONLY, BD_32S, 32, PK_pixfmtNul,   1, 1, 32, 2},
+    {&GUID_PKPixelFormat32bppGrayFloat, 1, Y_ONLY, BD_32F, 32, PK_pixfmtNul,        1, 1, 32, 3},
+
+    // RGB
+    {&GUID_PKPixelFormat24bppRGB, 3, CF_RGB, BD_8, 24, PK_pixfmtNul,                2, 3, 8, 1},
+    {&GUID_PKPixelFormat24bppBGR, 3, CF_RGB, BD_8, 24, PK_pixfmtBGR,                2, 3, 8, 1},
+    {&GUID_PKPixelFormat32bppRGB, 3, CF_RGB, BD_8, 32, PK_pixfmtNul,                2, 3, 8, 1},
+    {&GUID_PKPixelFormat32bppBGR, 3, CF_RGB, BD_8, 32, PK_pixfmtBGR,                2, 3, 8, 1},
+    {&GUID_PKPixelFormat48bppRGB, 3, CF_RGB, BD_16, 48, PK_pixfmtNul,               2, 3, 16, 1},
+    {&GUID_PKPixelFormat48bppRGBFixedPoint, 3, CF_RGB, BD_16S, 48, PK_pixfmtNul,    2, 3, 16, 2},
+    {&GUID_PKPixelFormat48bppRGBHalf, 3, CF_RGB, BD_16F, 48, PK_pixfmtNul,          2, 3, 16, 3},
+    {&GUID_PKPixelFormat64bppRGBFixedPoint, 3, CF_RGB, BD_16S, 64, PK_pixfmtNul,    2, 3, 16, 2},
+    {&GUID_PKPixelFormat64bppRGBHalf, 3, CF_RGB, BD_16F, 64, PK_pixfmtNul,          2, 3, 16, 3},
+    //{&GUID_PKPixelFormat96bppRGB, 3, CF_RGB, BD_32, 96, PK_pixfmtNul,               2, 3, 32, 1},
+    {&GUID_PKPixelFormat96bppRGBFixedPoint, 3, CF_RGB, BD_32S, 96, PK_pixfmtNul,    2, 3, 32, 2},
+    {&GUID_PKPixelFormat96bppRGBFloat, 3, CF_RGB, BD_32F, 96, PK_pixfmtNul,         2, 3, 32, 3},
+    {&GUID_PKPixelFormat128bppRGBFixedPoint, 3, CF_RGB, BD_32S, 128, PK_pixfmtNul,  2, 3, 32, 2},
+    {&GUID_PKPixelFormat128bppRGBFloat, 3, CF_RGB, BD_32F, 128, PK_pixfmtNul,       2, 3, 32, 3},
+
+    // RGBA
+    {&GUID_PKPixelFormat32bppBGRA, 4, CF_RGB, BD_8, 32, PK_pixfmtHasAlpha | PK_pixfmtBGR,  2, 4, 8, 1},
+    {&GUID_PKPixelFormat32bppRGBA, 4, CF_RGB, BD_8, 32, PK_pixfmtHasAlpha,                 2, 4, 8, 1},
+    {&GUID_PKPixelFormat64bppRGBA, 4, CF_RGB, BD_16, 64, PK_pixfmtHasAlpha,                2, 4, 16, 1},
+    {&GUID_PKPixelFormat64bppRGBAFixedPoint, 4, CF_RGB, BD_16S, 64, PK_pixfmtHasAlpha,     2, 4, 16, 2},
+    {&GUID_PKPixelFormat64bppRGBAHalf, 4, CF_RGB, BD_16F, 64, PK_pixfmtHasAlpha,           2, 4, 16, 3},
+    //{&GUID_PKPixelFormat128bppRGBA, 4, CF_RGB, BD_32, 128, PK_pixfmtHasAlpha,              2, 4, 32, 1},
+    {&GUID_PKPixelFormat128bppRGBAFixedPoint, 4, CF_RGB, BD_32S, 128, PK_pixfmtHasAlpha,   2, 4, 32, 2},
+    {&GUID_PKPixelFormat128bppRGBAFloat, 4, CF_RGB, BD_32F, 128, PK_pixfmtHasAlpha,        2, 4, 32, 3},
+
+    // PRGBA
+    {&GUID_PKPixelFormat32bppPBGRA, 4, CF_RGB, BD_8, 32, PK_pixfmtHasAlpha | PK_pixfmtPreMul | PK_pixfmtBGR,   2, 4, 8, 1},
+    {&GUID_PKPixelFormat32bppPRGBA, 4, CF_RGB, BD_8, 32, PK_pixfmtHasAlpha | PK_pixfmtPreMul,                  2, 4, 8, 1},
+    {&GUID_PKPixelFormat64bppPRGBA, 4, CF_RGB, BD_16, 64, PK_pixfmtHasAlpha | PK_pixfmtPreMul,                 2, 4, 16, 1},
+    //{&GUID_PKPixelFormat64bppPRGBAFixedPoint, 4, CF_RGB, BD_16S, 64, PK_pixfmtHasAlpha,      2, 4, 16, 2},
+    //{&GUID_PKPixelFormat64bppPRGBAHalf, 4, CF_RGB, BD_16F, 64, PK_pixfmtHasAlpha,            2, 4, 16, 3},
+    //{&GUID_PKPixelFormat128bppPRGBAFixedPoint, 4, CF_RGB, BD_32S, 128, PK_pixfmtHasAlpha,    2, 4, 32, 2},
+    {&GUID_PKPixelFormat128bppPRGBAFloat, 4, CF_RGB, BD_32F, 128, PK_pixfmtHasAlpha | PK_pixfmtPreMul,         2, 4, 32, 3},
+
+    // Packed formats
+    {&GUID_PKPixelFormat16bppRGB555, 3, CF_RGB,  BD_5, 16, PK_pixfmtNul,      2, 3, 5, 1},
+    {&GUID_PKPixelFormat16bppRGB565, 3, CF_RGB, BD_565, 16, PK_pixfmtNul,     2, 3, 6, 1},
+    {&GUID_PKPixelFormat32bppRGB101010, 3, CF_RGB, BD_10, 32, PK_pixfmtNul,   2, 3, 10, 1},
+
+    // CMYK
+    {&GUID_PKPixelFormat32bppCMYK, 4, CMYK, BD_8, 32, PK_pixfmtNul,               5, 4, 8, 1},
+    {&GUID_PKPixelFormat40bppCMYKAlpha, 5, CMYK, BD_8, 40, PK_pixfmtHasAlpha,     5, 5, 8, 1},
+
+    {&GUID_PKPixelFormat64bppCMYK, 4, CMYK, BD_16, 64, PK_pixfmtNul,              5, 4, 16, 1},
+    {&GUID_PKPixelFormat80bppCMYKAlpha, 5, CMYK, BD_16, 80, PK_pixfmtHasAlpha,    5, 5, 16, 1},
+
+    // N_CHANNEL
+    {&GUID_PKPixelFormat24bpp3Channels, 3, NCOMPONENT, BD_8, 24, PK_pixfmtNul, PK_PI_NCH, 3, 8, 1},//the N channel TIF by PS has PhotometricInterpretation of PK_PI_RGB
+    {&GUID_PKPixelFormat32bpp4Channels, 4, NCOMPONENT, BD_8, 32, PK_pixfmtNul, PK_PI_NCH, 4, 8, 1},
+    {&GUID_PKPixelFormat40bpp5Channels, 5, NCOMPONENT, BD_8, 40, PK_pixfmtNul, PK_PI_NCH, 5, 8, 1},
+    {&GUID_PKPixelFormat48bpp6Channels, 6, NCOMPONENT, BD_8, 48, PK_pixfmtNul, PK_PI_NCH, 6, 8, 1},
+    {&GUID_PKPixelFormat56bpp7Channels, 7, NCOMPONENT, BD_8, 56, PK_pixfmtNul, PK_PI_NCH, 7, 8, 1},
+    {&GUID_PKPixelFormat64bpp8Channels, 8, NCOMPONENT, BD_8, 64, PK_pixfmtNul, PK_PI_NCH, 8, 8, 1},
+    
+    {&GUID_PKPixelFormat32bpp3ChannelsAlpha, 4, NCOMPONENT, BD_8, 32, PK_pixfmtHasAlpha, PK_PI_NCH, 4, 8, 1},
+    {&GUID_PKPixelFormat40bpp4ChannelsAlpha, 5, NCOMPONENT, BD_8, 40, PK_pixfmtHasAlpha, PK_PI_NCH, 5, 8, 1},
+    {&GUID_PKPixelFormat48bpp5ChannelsAlpha, 6, NCOMPONENT, BD_8, 48, PK_pixfmtHasAlpha, PK_PI_NCH, 6, 8, 1},
+    {&GUID_PKPixelFormat56bpp6ChannelsAlpha, 7, NCOMPONENT, BD_8, 56, PK_pixfmtHasAlpha, PK_PI_NCH, 7, 8, 1},
+    {&GUID_PKPixelFormat64bpp7ChannelsAlpha, 8, NCOMPONENT, BD_8, 64, PK_pixfmtHasAlpha, PK_PI_NCH, 8, 8, 1},
+    {&GUID_PKPixelFormat72bpp8ChannelsAlpha, 9, NCOMPONENT, BD_8, 72, PK_pixfmtHasAlpha, PK_PI_NCH, 9, 8, 1},
+
+    {&GUID_PKPixelFormat48bpp3Channels, 3, NCOMPONENT, BD_16, 48, PK_pixfmtNul, PK_PI_NCH, 3, 16, 1},
+    {&GUID_PKPixelFormat64bpp4Channels, 4, NCOMPONENT, BD_16, 64, PK_pixfmtNul, PK_PI_NCH, 4, 16, 1},
+    {&GUID_PKPixelFormat80bpp5Channels, 5, NCOMPONENT, BD_16, 80, PK_pixfmtNul, PK_PI_NCH, 5, 16, 1},
+    {&GUID_PKPixelFormat96bpp6Channels, 6, NCOMPONENT, BD_16, 96, PK_pixfmtNul, PK_PI_NCH, 6, 16, 1},
+    {&GUID_PKPixelFormat112bpp7Channels, 7, NCOMPONENT, BD_16, 112, PK_pixfmtNul, PK_PI_NCH, 7, 16, 1},
+    {&GUID_PKPixelFormat128bpp8Channels, 8, NCOMPONENT, BD_16, 128, PK_pixfmtNul, PK_PI_NCH, 8, 16, 1},
+
+    {&GUID_PKPixelFormat64bpp3ChannelsAlpha, 4, NCOMPONENT, BD_16, 64, PK_pixfmtHasAlpha, PK_PI_NCH, 4, 16, 1},
+    {&GUID_PKPixelFormat80bpp4ChannelsAlpha, 5, NCOMPONENT, BD_16, 80, PK_pixfmtHasAlpha, PK_PI_NCH, 5, 16, 1},
+    {&GUID_PKPixelFormat96bpp5ChannelsAlpha, 6, NCOMPONENT, BD_16, 96, PK_pixfmtHasAlpha, PK_PI_NCH, 6, 16, 1},
+    {&GUID_PKPixelFormat112bpp6ChannelsAlpha, 7, NCOMPONENT, BD_16, 112, PK_pixfmtHasAlpha, PK_PI_NCH, 7, 16, 1},
+    {&GUID_PKPixelFormat128bpp7ChannelsAlpha, 8, NCOMPONENT, BD_16, 128, PK_pixfmtHasAlpha, PK_PI_NCH, 8, 16, 1},
+    {&GUID_PKPixelFormat144bpp8ChannelsAlpha, 9, NCOMPONENT, BD_16, 144, PK_pixfmtHasAlpha, PK_PI_NCH, 9, 16, 1},
+
+    //RGBE
+    {&GUID_PKPixelFormat32bppRGBE, 4, CF_RGBE, BD_8, 32, PK_pixfmtNul, PK_PI_RGBE, 4, 8, 1},
+
+    //YUV
+    {&GUID_PKPixelFormat12bppYUV420, 3, YUV_420, BD_8, 48, PK_pixfmtNul},
+    {&GUID_PKPixelFormat16bppYUV422, 3, YUV_422, BD_8, 32, PK_pixfmtNul},
+    {&GUID_PKPixelFormat24bppYUV444, 3, YUV_444, BD_8, 24, PK_pixfmtNul},
+};
+
+//----------------------------------------------------------------
+//ERR GetPixelInfo(PKPixelFormatGUID enPixelFormat, const PKPixelInfo** ppPI)
+ERR PixelFormatLookup(PKPixelInfo* pPI, U8 uLookupType)
+{
+    ERR err = WMP_errSuccess;
+    size_t i;
+
+    for (i = 0; i < sizeof2(pixelInfo); ++i)
+    {
+        if (LOOKUP_FORWARD == uLookupType)
+        {
+            if (IsEqualGUID(pPI->pGUIDPixFmt, pixelInfo[i].pGUIDPixFmt))
+            {
+                *pPI = pixelInfo[i];
+                goto Cleanup;
+            }
+        }
+        else if (LOOKUP_BACKWARD_TIF == uLookupType)
+        {
+            if (pPI->uSamplePerPixel == pixelInfo[i].uSamplePerPixel &&
+                pPI->uBitsPerSample == pixelInfo[i].uBitsPerSample &&
+                pPI->uSampleFormat == pixelInfo[i].uSampleFormat &&
+                pPI->uInterpretation == pixelInfo[i].uInterpretation)
+            {
+                // match alpha & premult
+                if ((pPI->grBit & (PK_pixfmtHasAlpha | PK_pixfmtPreMul)) ==
+                    (pixelInfo[i].grBit & (PK_pixfmtHasAlpha | PK_pixfmtPreMul)))
+                {
+                    *pPI = pixelInfo[i];
+                    goto Cleanup;
+                }
+            }
+        }
+    }
+    Call(WMP_errUnsupportedFormat);
+
+Cleanup:
+    return err;        
+}
+
+
+const PKPixelFormatGUID* GetPixelFormatFromHash(const U8 uPFHash)
+{
+    int i;
+
+    for (i = 0; i < sizeof2(pixelInfo); i++)
+    {
+        if (pixelInfo[i].pGUIDPixFmt->Data4[7] == uPFHash)
+            return pixelInfo[i].pGUIDPixFmt;
+    }
+
+    // If we reached this point, we did not find anything which matched the hash
+    return NULL;
+}
+
+//----------------------------------------------------------------
+typedef struct tagPKIIDInfo
+{
+    const char* szExt;
+    const PKIID* pIIDEnc;
+    const PKIID* pIIDDec;
+} PKIIDInfo;
+
+static ERR GetIIDInfo(const char* szExt, const PKIIDInfo** ppInfo)
+{
+    ERR err = WMP_errSuccess;
+
+    static PKIIDInfo iidInfo[] = {
+        {".jxr", &IID_PKImageWmpEncode, &IID_PKImageWmpDecode},
+        {".wdp", &IID_PKImageUnsupported, &IID_PKImageWmpDecode},
+        {".hdp", &IID_PKImageUnsupported, &IID_PKImageWmpDecode},
+    };
+    size_t i = 0;
+
+    *ppInfo = NULL;
+    for (i = 0; i < sizeof2(iidInfo); ++i)
+    {
+        if (0 == PKStrnicmp(szExt, iidInfo[i].szExt, strlen(iidInfo[i].szExt)))
+        {
+            *ppInfo = &iidInfo[i];
+            goto Cleanup;
+        }
+    }
+
+    Call(WMP_errUnsupportedFormat);
+
+Cleanup:
+    return err;
+}
+
+ERR GetImageEncodeIID(const char* szExt, const PKIID** ppIID)
+{
+    ERR err = WMP_errSuccess;
+
+    const PKIIDInfo* pInfo = NULL;
+
+    Call(GetIIDInfo(szExt, &pInfo));
+    *ppIID = pInfo->pIIDEnc;
+
+Cleanup:
+    return err;
+}
+
+ERR GetImageDecodeIID(const char* szExt, const PKIID** ppIID)
+{
+    ERR err = WMP_errSuccess;
+
+    const PKIIDInfo* pInfo = NULL;
+
+    Call(GetIIDInfo(szExt, &pInfo));
+    *ppIID = pInfo->pIIDDec;
+
+Cleanup:
+    return err;
+}
+
+//================================================================
+// PKFactory
+//================================================================
+ERR PKCreateFactory_CreateStream(PKStream** ppStream)
+{
+    ERR err = WMP_errSuccess;
+
+    Call(PKAlloc((void **) ppStream, sizeof(**ppStream)));
+
+Cleanup:
+    return err;
+}
+
+ERR PKCreateFactory_Release(PKFactory** ppFactory)
+{
+    ERR err = WMP_errSuccess;
+
+    Call(PKFree((void **) ppFactory));
+
+Cleanup: 
+    return err;
+}
+
+//----------------------------------------------------------------
+ERR PKCreateFactory(PKFactory** ppFactory, U32 uVersion)
+{
+    ERR err = WMP_errSuccess;
+    PKFactory* pFactory = NULL;
+
+    UNREFERENCED_PARAMETER( uVersion );
+
+    Call(PKAlloc((void **) ppFactory, sizeof(**ppFactory)));
+    pFactory = *ppFactory;
+
+    pFactory->CreateStream = PKCreateFactory_CreateStream;
+
+    pFactory->CreateStreamFromFilename = CreateWS_File;
+    pFactory->CreateStreamFromMemory = CreateWS_Memory;
+    
+    pFactory->Release = PKCreateFactory_Release;
+
+Cleanup:
+    return err;
+}
+
+
+//================================================================
+// PKCodecFactory
+//================================================================
+ERR PKCodecFactory_CreateCodec(const PKIID* iid, void** ppv)
+{
+    ERR err = WMP_errSuccess;
+
+    if (IID_PKImageWmpEncode == *iid)
+    {
+        Call(PKImageEncode_Create_WMP((PKImageEncode**)ppv));
+    }
+    else if (IID_PKImageWmpDecode == *iid)
+    {
+        Call(PKImageDecode_Create_WMP((PKImageDecode**)ppv));
+    }
+    else
+    {
+        Call(WMP_errUnsupportedFormat);
+    }
+
+Cleanup:
+    return err;
+}
+
+ERR PKCodecFactory_CreateDecoderFromFile(const char* szFilename, PKImageDecode** ppDecoder)
+{
+    ERR err = WMP_errSuccess;
+
+    char *pExt = NULL;
+    const PKIID* pIID = NULL;
+
+    struct WMPStream* pStream = NULL;
+    PKImageDecode* pDecoder = NULL;
+
+    // get file extension
+    pExt = strrchr(szFilename, '.');
+    FailIf(NULL == pExt, WMP_errUnsupportedFormat);
+
+    // get decode PKIID
+    Call(GetImageDecodeIID(pExt, &pIID));
+
+    // create stream
+    Call(CreateWS_File(&pStream, szFilename, "rb"));
+
+    // Create decoder
+    Call(PKCodecFactory_CreateCodec(pIID, (void **) ppDecoder));
+    pDecoder = *ppDecoder;
+
+    // attach stream to decoder
+    Call(pDecoder->Initialize(pDecoder, pStream));
+    pDecoder->fStreamOwner = !0;
+
+Cleanup:
+    return err;
+}
+
+ERR PKCodecFactory_CreateFormatConverter(PKFormatConverter** ppFConverter)
+{
+    ERR err = WMP_errSuccess;
+    PKFormatConverter* pFC = NULL;
+
+    Call(PKAlloc((void **) ppFConverter, sizeof(**ppFConverter)));
+    pFC = *ppFConverter;
+
+    pFC->Initialize = PKFormatConverter_Initialize;
+    pFC->InitializeConvert = PKFormatConverter_InitializeConvert;
+    pFC->GetPixelFormat = PKFormatConverter_GetPixelFormat;
+    pFC->GetSourcePixelFormat = PKFormatConverter_GetSourcePixelFormat;
+    pFC->GetSize = PKFormatConverter_GetSize;
+    pFC->GetResolution = PKFormatConverter_GetResolution;
+    pFC->Copy = PKFormatConverter_Copy;
+    pFC->Convert = PKFormatConverter_Convert;
+    pFC->Release = PKFormatConverter_Release;
+
+Cleanup:
+    return err;
+}
+
+ERR PKCreateCodecFactory_Release(PKCodecFactory** ppCFactory)
+{
+    ERR err = WMP_errSuccess;
+
+    Call(PKFree((void **) ppCFactory));
+
+Cleanup:
+    return err;
+}
+
+ERR PKCreateCodecFactory(PKCodecFactory** ppCFactory, U32 uVersion)
+{
+    ERR err = WMP_errSuccess;
+    PKCodecFactory* pCFactory = NULL;
+
+    UNREFERENCED_PARAMETER( uVersion );
+
+    Call(PKAlloc((void **) ppCFactory, sizeof(**ppCFactory)));
+    pCFactory = *ppCFactory;
+
+    pCFactory->CreateCodec = PKCodecFactory_CreateCodec;
+    pCFactory->CreateDecoderFromFile = PKCodecFactory_CreateDecoderFromFile;
+    pCFactory->CreateFormatConverter = PKCodecFactory_CreateFormatConverter;
+    pCFactory->Release = PKCreateCodecFactory_Release;
+
+Cleanup:
+    return err;
+}
+
+
+//================================================================
+// PKImageEncode
+//================================================================
+ERR PKImageEncode_Initialize(
+    PKImageEncode* pIE,
+    struct WMPStream* pStream,
+    void* pvParam,
+    size_t cbParam)
+{
+    ERR err = WMP_errSuccess;
+
+    UNREFERENCED_PARAMETER( pIE );
+    UNREFERENCED_PARAMETER( pvParam );
+    UNREFERENCED_PARAMETER( cbParam );
+
+    pIE->pStream = pStream;
+    pIE->guidPixFormat = GUID_PKPixelFormatDontCare;
+    pIE->fResX = 96;
+    pIE->fResY = 96;
+    pIE->cFrame = 1;
+
+    Call(pIE->pStream->GetPos(pIE->pStream, &pIE->offStart));
+
+Cleanup:
+    return err;
+}
+
+ERR PKImageEncode_Terminate(
+    PKImageEncode* pIE)
+{
+    UNREFERENCED_PARAMETER( pIE );
+    return WMP_errSuccess;
+}
+
+ERR PKImageEncode_SetPixelFormat(
+    PKImageEncode* pIE,
+    PKPixelFormatGUID enPixelFormat)
+{
+    pIE->guidPixFormat = enPixelFormat;
+
+    return WMP_errSuccess;
+}
+
+ERR PKImageEncode_SetSize(
+    PKImageEncode* pIE,
+    I32 iWidth,
+    I32 iHeight)
+{
+    ERR err = WMP_errSuccess;
+
+    pIE->uWidth = (U32)iWidth;
+    pIE->uHeight = (U32)iHeight;
+
+    return err;
+}
+
+ERR PKImageEncode_SetResolution(
+    PKImageEncode* pIE,
+    Float fResX, 
+    Float fResY)
+{
+    pIE->fResX = fResX;
+    pIE->fResY = fResY;
+
+    return WMP_errSuccess;
+}
+
+ERR PKImageEncode_SetColorContext(PKImageEncode *pIE,
+                                  const U8 *pbColorContext,
+                                  U32 cbColorContext)
+{
+    UNREFERENCED_PARAMETER( pIE );
+    UNREFERENCED_PARAMETER( pbColorContext );
+    UNREFERENCED_PARAMETER( cbColorContext );
+    return WMP_errNotYetImplemented;
+}
+
+
+ERR PKImageEncode_SetDescriptiveMetadata(PKImageEncode *pIE, const DESCRIPTIVEMETADATA *pDescMetadata)
+{
+    UNREFERENCED_PARAMETER( pIE );
+    UNREFERENCED_PARAMETER( pDescMetadata );
+    return WMP_errNotYetImplemented;
+}
+
+ERR PKImageEncode_WritePixels(
+    PKImageEncode* pIE,
+    U32 cLine,
+    U8* pbPixels,
+    U32 cbStride)
+{
+    UNREFERENCED_PARAMETER( pIE );
+    UNREFERENCED_PARAMETER( cLine );
+    UNREFERENCED_PARAMETER( pbPixels );
+    UNREFERENCED_PARAMETER( cbStride );
+    return WMP_errAbstractMethod;
+}
+
+ERR PKImageEncode_WriteSource(
+    PKImageEncode* pIE,
+    PKFormatConverter* pFC,
+    PKRect* pRect)
+{
+    ERR err = WMP_errSuccess;
+
+    PKPixelFormatGUID enPFFrom = GUID_PKPixelFormatDontCare;
+    PKPixelFormatGUID enPFTo = GUID_PKPixelFormatDontCare;
+
+    PKPixelInfo pPIFrom;
+    PKPixelInfo pPITo;
+
+    U32 cbStrideTo = 0;
+    U32 cbStrideFrom = 0;
+    U32 cbStride = 0;
+
+    U8* pb = NULL;
+
+	// CWMTranscodingParam* pParam = NULL; 
+
+    // get pixel format
+    Call(pFC->GetSourcePixelFormat(pFC, &enPFFrom));
+    Call(pFC->GetPixelFormat(pFC, &enPFTo));
+    FailIf(!IsEqualGUID(&pIE->guidPixFormat, &enPFTo), WMP_errUnsupportedFormat);
+
+    // calc common stride
+//    Call(GetPixelInfo(enPFFrom, &pPIFrom));
+    pPIFrom.pGUIDPixFmt = &enPFFrom;
+    PixelFormatLookup(&pPIFrom, LOOKUP_FORWARD);
+
+//    Call(GetPixelInfo(enPFTo, &pPITo));
+    pPITo.pGUIDPixFmt = &enPFTo;
+    PixelFormatLookup(&pPITo, LOOKUP_FORWARD);
+
+//    cbStrideFrom = (pPIFrom->cbPixel * pRect->Width + pPIFrom->cbPixelDenom - 1) / pPIFrom->cbPixelDenom;
+    cbStrideFrom = (BD_1 == pPIFrom.bdBitDepth ? ((pPIFrom.cbitUnit * pRect->Width + 7) >> 3) : (((pPIFrom.cbitUnit + 7) >> 3) * pRect->Width)); 
+    if (&GUID_PKPixelFormat12bppYUV420 == pPIFrom.pGUIDPixFmt 
+        || &GUID_PKPixelFormat16bppYUV422 == pPIFrom.pGUIDPixFmt) 
+        cbStrideFrom >>= 1;
+
+//    cbStrideTo = (pPITo->cbPixel * pIE->uWidth + pPITo->cbPixelDenom - 1) / pPITo->cbPixelDenom;
+    cbStrideTo = (BD_1 == pPITo.bdBitDepth ? ((pPITo.cbitUnit * pIE->uWidth + 7) >> 3) : (((pPITo.cbitUnit + 7) >> 3) * pIE->uWidth)); 
+    if (&GUID_PKPixelFormat12bppYUV420 == pPITo.pGUIDPixFmt
+        || &GUID_PKPixelFormat16bppYUV422 == pPITo.pGUIDPixFmt) 
+        cbStrideTo >>= 1;
+
+    cbStride = max(cbStrideFrom, cbStrideTo);
+
+    // actual dec/enc with local buffer
+    Call(PKAllocAligned((void **) &pb, cbStride * pRect->Height, 128));
+
+    Call(pFC->Copy(pFC, pRect, pb, cbStride));
+
+	Call(pIE->WritePixels(pIE, pRect->Height, pb, cbStride));
+
+Cleanup:
+    PKFreeAligned((void **) &pb);
+    return err;
+}
+
+ERR PKImageEncode_WritePixelsBandedBegin(PKImageEncode* pEncoder, struct WMPStream *pPATempFile)
+{
+    UNREFERENCED_PARAMETER( pEncoder );
+    UNREFERENCED_PARAMETER( pPATempFile );
+    return WMP_errAbstractMethod;
+}
+
+ERR PKImageEncode_WritePixelsBanded(PKImageEncode* pEncoder, U32 cLines, U8* pbPixels, U32 cbStride, Bool fLastCall)
+{
+    UNREFERENCED_PARAMETER( pEncoder );
+    UNREFERENCED_PARAMETER( cLines );
+    UNREFERENCED_PARAMETER( pbPixels );
+    UNREFERENCED_PARAMETER( cbStride );
+    UNREFERENCED_PARAMETER( fLastCall );
+    return WMP_errAbstractMethod;
+}
+
+ERR PKImageEncode_WritePixelsBandedEnd(PKImageEncode* pEncoder)
+{
+    UNREFERENCED_PARAMETER( pEncoder );
+    return WMP_errAbstractMethod;
+}
+
+
+ERR PKImageEncode_Transcode(
+    PKImageEncode* pIE,
+    PKFormatConverter* pFC,
+    PKRect* pRect)
+{
+    ERR err = WMP_errSuccess;
+
+    PKPixelFormatGUID enPFFrom = GUID_PKPixelFormatDontCare;
+    PKPixelFormatGUID enPFTo = GUID_PKPixelFormatDontCare;
+
+    PKPixelInfo pPIFrom;
+    PKPixelInfo pPITo;
+
+    U32 cbStrideTo = 0;
+    U32 cbStrideFrom = 0;
+    U32 cbStride = 0;
+
+    U8* pb = NULL;
+
+    CWMTranscodingParam cParam = {0}; 
+
+    // get pixel format
+    Call(pFC->GetSourcePixelFormat(pFC, &enPFFrom));
+    Call(pFC->GetPixelFormat(pFC, &enPFTo));
+    FailIf(!IsEqualGUID(&pIE->guidPixFormat, &enPFTo), WMP_errUnsupportedFormat);
+
+    // calc common stride
+//    Call(GetPixelInfo(enPFFrom, &pPIFrom));
+    pPIFrom.pGUIDPixFmt = &enPFFrom;
+    PixelFormatLookup(&pPIFrom, LOOKUP_FORWARD);
+
+//    Call(GetPixelInfo(enPFTo, &pPITo));
+    pPITo.pGUIDPixFmt = &enPFTo;
+    PixelFormatLookup(&pPITo, LOOKUP_FORWARD);
+
+//    cbStrideFrom = (pPIFrom->cbPixel * pRect->Width + pPIFrom->cbPixelDenom - 1) / pPIFrom->cbPixelDenom;
+    cbStrideFrom = (BD_1 == pPIFrom.bdBitDepth ? ((pPIFrom.cbitUnit * pRect->Width + 7) >> 3) : (((pPIFrom.cbitUnit + 7) >> 3) * pRect->Width)); 
+    if (&GUID_PKPixelFormat12bppYUV420 == pPIFrom.pGUIDPixFmt 
+        || &GUID_PKPixelFormat16bppYUV422 == pPIFrom.pGUIDPixFmt) 
+        cbStrideFrom >>= 1;
+
+//    cbStrideTo = (pPITo->cbPixel * pIE->uWidth + pPITo->cbPixelDenom - 1) / pPITo->cbPixelDenom;
+    cbStrideTo = (BD_1 == pPITo.bdBitDepth ? ((pPITo.cbitUnit * pIE->uWidth + 7) >> 3) : (((pPITo.cbitUnit + 7) >> 3) * pIE->uWidth)); 
+    if (&GUID_PKPixelFormat12bppYUV420 == pPITo.pGUIDPixFmt
+        || &GUID_PKPixelFormat16bppYUV422 == pPITo.pGUIDPixFmt) 
+        cbStrideTo >>= 1;
+
+    cbStride = max(cbStrideFrom, cbStrideTo);
+
+    if(pIE->bWMP){
+        cParam.cLeftX = pFC->pDecoder->WMP.wmiI.cROILeftX;
+        cParam.cTopY = pFC->pDecoder->WMP.wmiI.cROITopY;
+        cParam.cWidth = pFC->pDecoder->WMP.wmiI.cROIWidth;
+        cParam.cHeight = pFC->pDecoder->WMP.wmiI.cROIHeight;
+        cParam.oOrientation = pFC->pDecoder->WMP.wmiI.oOrientation;
+//        cParam.cfColorFormat = pFC->pDecoder->WMP.wmiI.cfColorFormat;
+        cParam.uAlphaMode = pFC->pDecoder->WMP.wmiSCP.uAlphaMode;
+        cParam.bfBitstreamFormat = pFC->pDecoder->WMP.wmiSCP.bfBitstreamFormat;
+        cParam.sbSubband = pFC->pDecoder->WMP.wmiSCP.sbSubband;
+        cParam.bIgnoreOverlap = pFC->pDecoder->WMP.bIgnoreOverlap;
+        
+        Call(pIE->Transcode(pIE, pFC->pDecoder, &cParam));
+    }
+	else 
+	{
+		// actual dec/enc with local buffer
+	    Call(PKAllocAligned((void **) &pb, cbStride * pRect->Height, 128));
+		Call(pFC->Copy(pFC, pRect, pb, cbStride));
+		Call(pIE->WritePixels(pIE, pRect->Height, pb, cbStride));
+	}
+
+Cleanup:
+    PKFreeAligned((void **) &pb);
+    return err;
+}
+
+ERR PKImageEncode_CreateNewFrame(
+    PKImageEncode* pIE,
+    void* pvParam,
+    size_t cbParam)
+{
+    UNREFERENCED_PARAMETER( pIE );
+    UNREFERENCED_PARAMETER( pvParam );
+    UNREFERENCED_PARAMETER( cbParam );
+    // NYI
+    return WMP_errSuccess;
+}
+
+ERR PKImageEncode_Release(
+    PKImageEncode** ppIE)
+{
+    PKImageEncode *pIE = *ppIE;
+    pIE->pStream->Close(&pIE->pStream);
+
+    return PKFree((void **) ppIE);
+}
+
+ERR PKImageEncode_Create(PKImageEncode** ppIE)
+{
+    ERR err = WMP_errSuccess;
+    PKImageEncode* pIE = NULL;
+
+    Call(PKAlloc((void **) ppIE, sizeof(**ppIE)));
+
+    pIE = *ppIE;
+    pIE->Initialize = PKImageEncode_Initialize;
+    pIE->Terminate = PKImageEncode_Terminate;
+    pIE->SetPixelFormat = PKImageEncode_SetPixelFormat;
+    pIE->SetSize = PKImageEncode_SetSize;
+    pIE->SetResolution = PKImageEncode_SetResolution;
+    pIE->SetColorContext = PKImageEncode_SetColorContext;
+    pIE->SetDescriptiveMetadata = PKImageEncode_SetDescriptiveMetadata;
+    pIE->WritePixels = PKImageEncode_WritePixels;
+//    pIE->WriteSource = PKImageEncode_WriteSource;
+
+    pIE->WritePixelsBandedBegin = PKImageEncode_WritePixelsBandedBegin;
+    pIE->WritePixelsBanded = PKImageEncode_WritePixelsBanded;
+    pIE->WritePixelsBandedEnd = PKImageEncode_WritePixelsBandedEnd;
+
+    pIE->CreateNewFrame = PKImageEncode_CreateNewFrame;
+    pIE->Release = PKImageEncode_Release;
+	pIE->bWMP = FALSE; 
+
+Cleanup:
+    return err;
+}
+  
+
+//================================================================
+// PKImageDecode
+//================================================================
+ERR PKImageDecode_Initialize(
+    PKImageDecode* pID,
+    struct WMPStream* pStream)
+{
+    ERR err = WMP_errSuccess;
+
+    pID->pStream = pStream;
+    pID->guidPixFormat = GUID_PKPixelFormatDontCare;
+    pID->fResX = 96;
+    pID->fResY = 96;
+    pID->cFrame = 1;
+
+    Call(pID->pStream->GetPos(pID->pStream, &pID->offStart));
+
+    memset(&pID->WMP.wmiDEMisc, 0, sizeof(pID->WMP.wmiDEMisc));
+
+Cleanup:
+    return WMP_errSuccess;
+}
+
+ERR PKImageDecode_GetPixelFormat(
+    PKImageDecode* pID,
+    PKPixelFormatGUID* pPF)
+{
+    *pPF = pID->guidPixFormat;
+
+    return WMP_errSuccess;
+}
+
+ERR PKImageDecode_GetSize(
+    PKImageDecode* pID,
+    I32* piWidth,
+    I32* piHeight)
+{
+    *piWidth = (I32)pID->uWidth;
+    *piHeight = (I32)pID->uHeight;
+
+    return WMP_errSuccess;
+}
+
+ERR PKImageDecode_GetResolution(
+    PKImageDecode* pID,
+    Float* pfResX,
+    Float* pfResY)
+{
+    *pfResX = pID->fResX;
+    *pfResY = pID->fResY;
+
+    return WMP_errSuccess;
+}
+
+ERR PKImageDecode_GetColorContext(PKImageDecode *pID, U8 *pbColorContext, U32 *pcbColorContext)
+{
+    UNREFERENCED_PARAMETER( pID );
+    UNREFERENCED_PARAMETER( pbColorContext );
+    UNREFERENCED_PARAMETER( pcbColorContext );
+    return WMP_errNotYetImplemented;
+}
+
+ERR PKImageDecode_GetDescriptiveMetadata(PKImageDecode *pIE, DESCRIPTIVEMETADATA *pDescMetadata)
+{
+    UNREFERENCED_PARAMETER( pIE );
+    UNREFERENCED_PARAMETER( pDescMetadata );
+    return WMP_errNotYetImplemented;
+}
+
+ERR PKImageDecode_Copy(
+    PKImageDecode* pID,
+    const PKRect* pRect,
+    U8* pb,
+    U32 cbStride)
+{
+    UNREFERENCED_PARAMETER( pID );
+    UNREFERENCED_PARAMETER( pRect );
+    UNREFERENCED_PARAMETER( pb );
+    UNREFERENCED_PARAMETER( cbStride );
+    return WMP_errAbstractMethod;
+}
+
+ERR PKImageDecode_GetFrameCount(
+    PKImageDecode* pID,
+    U32* puCount)
+{
+    *puCount = pID->cFrame;
+
+    return WMP_errSuccess;
+}
+
+ERR PKImageDecode_SelectFrame(
+    PKImageDecode* pID,
+    U32 uFrame)
+{
+    UNREFERENCED_PARAMETER( pID );
+    UNREFERENCED_PARAMETER( uFrame );
+    // NYI
+    return WMP_errSuccess;
+}
+
+ERR PKImageDecode_Release(
+    PKImageDecode** ppID)
+{
+    PKImageDecode* pID = *ppID;
+
+    pID->fStreamOwner && pID->pStream->Close(&pID->pStream);
+
+    return PKFree((void **) ppID);
+}
+
+ERR PKImageDecode_Create(
+    PKImageDecode** ppID)
+{
+    ERR err = WMP_errSuccess;
+    PKImageDecode* pID = NULL;
+
+    Call(PKAlloc((void **) ppID, sizeof(**ppID)));
+
+    pID = *ppID;
+    pID->Initialize = PKImageDecode_Initialize;
+    pID->GetPixelFormat = PKImageDecode_GetPixelFormat;
+    pID->GetSize = PKImageDecode_GetSize;
+    pID->GetResolution = PKImageDecode_GetResolution;
+    pID->GetColorContext = PKImageDecode_GetColorContext;
+    pID->GetDescriptiveMetadata = PKImageDecode_GetDescriptiveMetadata;
+    pID->Copy = PKImageDecode_Copy;
+    pID->GetFrameCount = PKImageDecode_GetFrameCount;
+    pID->SelectFrame = PKImageDecode_SelectFrame;
+    pID->Release = PKImageDecode_Release;
+
+Cleanup:
+    return err;
+}
+
diff --git a/Source/LibJXR/jxrgluelib/JXRGlue.h b/Source/LibJXR/jxrgluelib/JXRGlue.h
new file mode 100644
index 0000000..dfdbdf5
--- /dev/null
+++ b/Source/LibJXR/jxrgluelib/JXRGlue.h
@@ -0,0 +1,636 @@
+//*@@@+++@@@@******************************************************************
+//
+// Copyright � Microsoft Corp.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+// � Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// � Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//*@@@---@@@@******************************************************************
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <JXRMeta.h>
+#include <guiddef.h>
+
+//================================================================
+#define WMP_SDK_VERSION 0x0101
+#define PK_SDK_VERSION 0x0101
+
+#define sizeof2(array) (sizeof(array)/sizeof(*(array)))
+#ifndef max
+#define max(a,b) ((a) > (b) ? (a) : (b))
+#endif
+#ifndef min
+#define min(b,a) ((a) < (b) ? (a) : (b))
+#endif
+#if defined(__ANSI__) || defined(__MINGW32__)
+#define STRCPY_SAFE(pszDest, cbDest, pszSrc)    (strncpy((pszDest), (pszSrc), (cbDest)) == (pszDest) ? 0 : 1)
+#else
+#define STRCPY_SAFE(pszDest, cbDest, pszSrc)    (strcpy_s((pszDest), (cbDest), (pszSrc)))
+#endif // __ANSI__
+
+//================================================================
+typedef struct tagPKRect
+{
+    I32 X;
+    I32 Y;
+    I32 Width;
+    I32 Height;
+} PKRect;
+
+//================================================================
+typedef U32 PKIID;
+
+EXTERN_C const PKIID IID_PKImageScanEncode;
+EXTERN_C const PKIID IID_PKImageFrameEncode;
+
+EXTERN_C const PKIID IID_PKImageWmpEncode;
+
+EXTERN_C const PKIID IID_PKImageWmpDecode;
+
+struct IFDEntry
+{
+    U16 uTag;
+    U16 uType;
+    U32 uCount;
+    U32 uValue;
+};
+EXTERN_C const U32 IFDEntryTypeSizes[13];
+EXTERN_C const U32 SizeofIFDEntry;
+
+//================================================================
+typedef float Float;
+
+typedef enum tagPKStreamFlags
+{
+    PKStreamOpenRead = 0x00000000UL,
+    PKStreamOpenWrite = 0x00000001UL,
+    PKStreamOpenReadWrite = 0x00000002UL,
+    PKStreamNoLock = 0x00010000UL,
+    PKStreamNoSeek = 0x00020000UL,
+    PKStreamCompress = 0x00040000UL,
+} PKStreamFlags;
+
+/* Undefined formats */
+#define GUID_PKPixelFormatUndefined GUID_PKPixelFormatDontCare
+
+DEFINE_GUID(GUID_PKPixelFormatDontCare, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x00);
+
+/* Indexed formats */
+//DEFINE_GUID(GUID_PKPixelFormat1bppIndexed, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x01);
+//DEFINE_GUID(GUID_PKPixelFormat2bppIndexed, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x02);
+//DEFINE_GUID(GUID_PKPixelFormat4bppIndexed, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x03);
+//DEFINE_GUID(GUID_PKPixelFormat8bppIndexed, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x04);
+
+DEFINE_GUID(GUID_PKPixelFormatBlackWhite, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x05);
+//DEFINE_GUID(GUID_PKPixelFormat2bppGray,   0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x06);
+//DEFINE_GUID(GUID_PKPixelFormat4bppGray,   0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x07);
+DEFINE_GUID(GUID_PKPixelFormat8bppGray,   0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x08);
+
+/* sRGB formats (gamma is approx. 2.2) */
+/* For a full definition, see the sRGB spec */
+
+/* 16bpp formats */
+DEFINE_GUID(GUID_PKPixelFormat16bppRGB555, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x09);
+DEFINE_GUID(GUID_PKPixelFormat16bppRGB565, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0a);
+DEFINE_GUID(GUID_PKPixelFormat16bppGray,   0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0b);
+
+/* 24bpp formats */
+DEFINE_GUID(GUID_PKPixelFormat24bppBGR, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0c);
+DEFINE_GUID(GUID_PKPixelFormat24bppRGB, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0d);
+
+/* 32bpp format */
+DEFINE_GUID(GUID_PKPixelFormat32bppBGR,   0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0e);
+DEFINE_GUID(GUID_PKPixelFormat32bppBGRA,  0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0f);
+DEFINE_GUID(GUID_PKPixelFormat32bppPBGRA, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x10);
+DEFINE_GUID(GUID_PKPixelFormat32bppGrayFloat,  0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x11);
+DEFINE_GUID(GUID_PKPixelFormat32bppRGB,   0xd98c6b95, 0x3efe, 0x47d6, 0xbb, 0x25, 0xeb, 0x17, 0x48, 0xab, 0x0c, 0xf1);
+DEFINE_GUID(GUID_PKPixelFormat32bppRGBA,  0xf5c7ad2d, 0x6a8d, 0x43dd, 0xa7, 0xa8, 0xa2, 0x99, 0x35, 0x26, 0x1a, 0xe9);
+DEFINE_GUID(GUID_PKPixelFormat32bppPRGBA, 0x3cc4a650, 0xa527, 0x4d37, 0xa9, 0x16, 0x31, 0x42, 0xc7, 0xeb, 0xed, 0xba);
+
+/* 48bpp format */
+DEFINE_GUID(GUID_PKPixelFormat48bppRGBFixedPoint, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x12);
+
+/* scRGB formats. Gamma is 1.0 */
+/* For a full definition, see the scRGB spec */
+
+/* 16bpp format */
+DEFINE_GUID(GUID_PKPixelFormat16bppGrayFixedPoint, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x13);
+
+/* 32bpp format */
+DEFINE_GUID(GUID_PKPixelFormat32bppRGB101010, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x14);
+
+/* 48bpp format */
+DEFINE_GUID(GUID_PKPixelFormat48bppRGB, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x15);
+
+/* 64bpp format */
+DEFINE_GUID(GUID_PKPixelFormat64bppRGBA,  0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x16);
+DEFINE_GUID(GUID_PKPixelFormat64bppPRGBA, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x17);
+
+/* 96bpp format */
+DEFINE_GUID(GUID_PKPixelFormat96bppRGBFixedPoint, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x18);
+DEFINE_GUID(GUID_PKPixelFormat96bppRGBFloat, 0xe3fed78f, 0xe8db, 0x4acf, 0x84, 0xc1, 0xe9, 0x7f, 0x61, 0x36, 0xb3, 0x27);
+
+ /* Floating point scRGB formats */
+DEFINE_GUID(GUID_PKPixelFormat128bppRGBAFloat,  0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x19);
+DEFINE_GUID(GUID_PKPixelFormat128bppPRGBAFloat, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x1a);
+DEFINE_GUID(GUID_PKPixelFormat128bppRGBFloat,   0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x1b);
+
+ /* CMYK formats. */
+DEFINE_GUID(GUID_PKPixelFormat32bppCMYK, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x1c);
+
+ /* Photon formats */
+DEFINE_GUID(GUID_PKPixelFormat64bppRGBAFixedPoint, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x1d);
+DEFINE_GUID(GUID_PKPixelFormat64bppRGBFixedPoint, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x40);
+DEFINE_GUID(GUID_PKPixelFormat128bppRGBAFixedPoint, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x1e);
+DEFINE_GUID(GUID_PKPixelFormat128bppRGBFixedPoint, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x41);
+
+DEFINE_GUID(GUID_PKPixelFormat64bppRGBAHalf, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x3a);
+DEFINE_GUID(GUID_PKPixelFormat64bppRGBHalf, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x42);
+DEFINE_GUID(GUID_PKPixelFormat48bppRGBHalf, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x3b);
+
+DEFINE_GUID(GUID_PKPixelFormat32bppRGBE, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x3d);
+
+DEFINE_GUID(GUID_PKPixelFormat16bppGrayHalf, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x3e);
+DEFINE_GUID(GUID_PKPixelFormat32bppGrayFixedPoint, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x3f);
+
+
+/* More CMYK formats and n-Channel formats */
+DEFINE_GUID(GUID_PKPixelFormat64bppCMYK, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x1f);
+
+DEFINE_GUID(GUID_PKPixelFormat24bpp3Channels, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x20);
+DEFINE_GUID(GUID_PKPixelFormat32bpp4Channels, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x21);
+DEFINE_GUID(GUID_PKPixelFormat40bpp5Channels, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x22);
+DEFINE_GUID(GUID_PKPixelFormat48bpp6Channels, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x23);
+DEFINE_GUID(GUID_PKPixelFormat56bpp7Channels, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x24);
+DEFINE_GUID(GUID_PKPixelFormat64bpp8Channels, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x25);
+
+DEFINE_GUID(GUID_PKPixelFormat48bpp3Channels, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x26);
+DEFINE_GUID(GUID_PKPixelFormat64bpp4Channels, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x27);
+DEFINE_GUID(GUID_PKPixelFormat80bpp5Channels, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x28);
+DEFINE_GUID(GUID_PKPixelFormat96bpp6Channels, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x29);
+DEFINE_GUID(GUID_PKPixelFormat112bpp7Channels, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x2a);
+DEFINE_GUID(GUID_PKPixelFormat128bpp8Channels, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x2b);
+
+DEFINE_GUID(GUID_PKPixelFormat40bppCMYKAlpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x2c);
+DEFINE_GUID(GUID_PKPixelFormat80bppCMYKAlpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x2d);
+
+DEFINE_GUID(GUID_PKPixelFormat32bpp3ChannelsAlpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x2e);
+DEFINE_GUID(GUID_PKPixelFormat40bpp4ChannelsAlpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x2f);
+DEFINE_GUID(GUID_PKPixelFormat48bpp5ChannelsAlpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x30);
+DEFINE_GUID(GUID_PKPixelFormat56bpp6ChannelsAlpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x31);
+DEFINE_GUID(GUID_PKPixelFormat64bpp7ChannelsAlpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x32);
+DEFINE_GUID(GUID_PKPixelFormat72bpp8ChannelsAlpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x33);
+
+DEFINE_GUID(GUID_PKPixelFormat64bpp3ChannelsAlpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x34);
+DEFINE_GUID(GUID_PKPixelFormat80bpp4ChannelsAlpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x35);
+DEFINE_GUID(GUID_PKPixelFormat96bpp5ChannelsAlpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x36);
+DEFINE_GUID(GUID_PKPixelFormat112bpp6ChannelsAlpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x37);
+DEFINE_GUID(GUID_PKPixelFormat128bpp7ChannelsAlpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x38);
+DEFINE_GUID(GUID_PKPixelFormat144bpp8ChannelsAlpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x39);
+
+/* YCrCb  from Advanced Profile */
+DEFINE_GUID(GUID_PKPixelFormat12bppYCC420, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x44);
+DEFINE_GUID(GUID_PKPixelFormat16bppYCC422, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x45);
+DEFINE_GUID(GUID_PKPixelFormat20bppYCC422, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x46);
+DEFINE_GUID(GUID_PKPixelFormat32bppYCC422, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x47);
+DEFINE_GUID(GUID_PKPixelFormat24bppYCC444, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x48);
+DEFINE_GUID(GUID_PKPixelFormat30bppYCC444, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x49);
+DEFINE_GUID(GUID_PKPixelFormat48bppYCC444, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x4a);
+DEFINE_GUID(GUID_PKPixelFormat16bpp48bppYCC444FixedPoint, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x4b);
+DEFINE_GUID(GUID_PKPixelFormat20bppYCC420Alpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x4c);
+DEFINE_GUID(GUID_PKPixelFormat24bppYCC422Alpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x4d);
+DEFINE_GUID(GUID_PKPixelFormat30bppYCC422Alpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x4e);
+DEFINE_GUID(GUID_PKPixelFormat48bppYCC422Alpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x4f);
+DEFINE_GUID(GUID_PKPixelFormat32bppYCC444Alpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x50);
+DEFINE_GUID(GUID_PKPixelFormat40bppYCC444Alpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x51);
+DEFINE_GUID(GUID_PKPixelFormat64bppYCC444Alpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x52);
+DEFINE_GUID(GUID_PKPixelFormat64bppYCC444AlphaFixedPoint, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x53);
+
+//YUV
+#define GUID_PKPixelFormat12bppYUV420 GUID_PKPixelFormat12bppYCC420
+#define GUID_PKPixelFormat16bppYUV422 GUID_PKPixelFormat16bppYCC422
+#define GUID_PKPixelFormat24bppYUV444 GUID_PKPixelFormat24bppYCC444
+
+/* CMYKDIRECT from Advanced Profile */
+DEFINE_GUID(GUID_PKPixelFormat32bppCMYKDIRECT, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x54);
+DEFINE_GUID(GUID_PKPixelFormat64bppCMYKDIRECT, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x55);
+DEFINE_GUID(GUID_PKPixelFormat40bppCMYKDIRECTAlpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x56);
+DEFINE_GUID(GUID_PKPixelFormat80bppCMYKDIRECTAlpha, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x43);
+
+// PhotometricInterpretation
+#define PK_PI_W0 0 // WhiteIsZero
+#define PK_PI_B0 1 // BlackIsZero
+#define PK_PI_RGB 2
+#define PK_PI_RGBPalette 3
+#define PK_PI_TransparencyMask 4
+#define PK_PI_CMYK 5
+#define PK_PI_YCbCr 6
+#define PK_PI_CIELab 8
+
+#define PK_PI_NCH  100
+#define PK_PI_RGBE 101
+
+#define PK_pixfmtNul           0x00000000
+#define PK_pixfmtHasAlpha      0x00000010
+#define PK_pixfmtPreMul        0x00000020
+#define PK_pixfmtBGR           0x00000040
+#define PK_pixfmtNeedConvert   0x80000000
+
+#define LOOKUP_FORWARD         0
+#define LOOKUP_BACKWARD_TIF    1
+
+typedef unsigned long WMP_GRBIT;
+typedef GUID PKPixelFormatGUID;
+
+typedef struct tagPKPixelInfo
+{
+    const PKPixelFormatGUID* pGUIDPixFmt;
+
+    size_t cChannel;
+    COLORFORMAT cfColorFormat;
+    BITDEPTH_BITS bdBitDepth;
+    U32 cbitUnit;
+    
+    WMP_GRBIT grBit;
+
+    // TIFF
+    U32 uInterpretation;
+    U32 uSamplePerPixel;
+    U32 uBitsPerSample;
+    U32 uSampleFormat;
+} PKPixelInfo;
+
+//================================================================
+ERR PKAlloc(void** ppv, size_t cb);
+ERR PKFree(void** ppv);
+
+//----------------------------------------------------------------
+//ERR GetPixelInfo(PKPixelFormatGUID enPixelFormat, const PKPixelInfo** ppPI);
+ERR PixelFormatLookup(PKPixelInfo* pPI, U8 uLookupType);
+const PKPixelFormatGUID* GetPixelFormatFromHash(const U8 uPFHash);
+
+ERR GetImageEncodeIID(const char* szExt, const PKIID** ppIID);
+ERR GetImageDecodeIID(const char* szExt, const PKIID** ppIID);
+
+
+//================================================================
+#ifdef __ANSI__
+struct tagPKFactory;
+struct tagPKCodecFactory;
+struct tagPKImageDecode;
+struct tagPKImageEncode;
+struct tagPKFormatConverter;
+#define PKFactory           struct tagPKFactory
+#define PKCodecFactory      struct tagPKCodecFactory
+#define PKImageDecode       struct tagPKImageDecode
+#define PKImageEncode       struct tagPKImageEncode
+#define PKFormatConverter   struct tagPKFormatConverter
+#else // __ANSI__
+typedef struct tagPKFactory PKFactory;
+typedef struct tagPKCodecFactory PKCodecFactory;
+typedef struct tagPKImageDecode PKImageDecode;
+typedef struct tagPKImageEncode PKImageEncode;
+typedef struct tagPKFormatConverter PKFormatConverter;
+#endif // __ANSI__
+//================================================================
+typedef struct tagPKStream
+{
+    ERR (*InitializeFromFilename)(const char*, ULong);
+
+    ERR (*Release)(void);
+
+    FILE* fp;
+} PKStream;
+
+
+//================================================================
+typedef struct tagPKFactory
+{
+    ERR (*CreateStream)(PKStream**);
+
+    ERR (*CreateStreamFromFilename)(struct WMPStream**, const char*, const char*);
+    ERR (*CreateStreamFromMemory)(struct WMPStream**, void*, size_t);
+
+    ERR (*Release)(PKFactory**);
+#ifdef __ANSI__
+#undef PKFactory
+#endif // __ANSI__
+} PKFactory;
+
+//----------------------------------------------------------------
+ERR PKCreateFactory_CreateStream(PKStream** ppStream);
+ERR PKCreateFactory_Release(PKFactory** ppFactory);
+
+EXTERN_C ERR PKCreateFactory(PKFactory**, U32);
+
+
+//================================================================
+typedef struct tagPKCodecFactory
+{
+    ERR (*CreateCodec)(const PKIID*, void**);
+    ERR (*CreateDecoderFromFile)(const char*, PKImageDecode**);
+    ERR (*CreateFormatConverter)(PKFormatConverter**);
+
+    ERR (*Release)(PKCodecFactory**);
+#ifdef __ANSI__
+#undef PKCodecFactory
+#endif // __ANSI__
+} PKCodecFactory;
+
+//----------------------------------------------------------------
+ERR PKCodecFactory_CreateCodec(const PKIID* iid, void** ppv);
+ERR PKCreateCodecFactory_Release(PKCodecFactory** ppCFactory);
+
+EXTERN_C ERR PKCreateCodecFactory(PKCodecFactory**, U32);
+
+//================================================================
+
+typedef enum BANDEDENCSTATE
+{
+    BANDEDENCSTATE_UNINITIALIZED = 0,
+    BANDEDENCSTATE_INIT,
+    BANDEDENCSTATE_ENCODING,
+    BANDEDENCSTATE_TERMINATED,
+    BANDEDENCSTATE_NONBANDEDENCODE,
+} BANDEDENCSTATE;
+
+typedef struct tagPKImageEncode
+{
+    //ERR (*GetPixelFormat)(MILPixelFormat*));
+    ERR (*Initialize)(PKImageEncode*, struct WMPStream*, void*, size_t);
+    ERR (*Terminate)(PKImageEncode*);
+
+    ERR (*SetPixelFormat)(PKImageEncode*, PKPixelFormatGUID);
+    ERR (*SetSize)(PKImageEncode*, I32, I32);
+    ERR (*SetResolution)(PKImageEncode*, Float, Float);
+    ERR (*SetColorContext)(PKImageEncode *pIE, const U8 *pbColorContext,
+        U32 cbColorContext);
+    ERR (*SetDescriptiveMetadata)(PKImageEncode *pIE,
+        const DESCRIPTIVEMETADATA *pDescMetadata);
+
+    ERR (*WritePixels)(PKImageEncode*, U32, U8*, U32);
+    ERR (*WriteSource)(PKImageEncode*, PKFormatConverter*, PKRect*);
+
+    // Banded encode API - currently only implemented for WMP encoder
+    ERR (*WritePixelsBandedBegin)(PKImageEncode* pEncoder, struct WMPStream *pPlanarAlphaTempFile);
+    ERR (*WritePixelsBanded)(PKImageEncode* pEncoder, U32 cLines, U8* pbPixels, U32 cbStride, Bool fLastCall);
+    ERR (*WritePixelsBandedEnd)(PKImageEncode* pEncoder);
+#define TEMPFILE_COPYBUF_SIZE 8192  // Means when using tempfile for planar alpha banded encode, copy this many bytes at a time
+
+    ERR (*Transcode)(PKImageEncode*, PKImageDecode*, CWMTranscodingParam*);
+
+    ERR (*CreateNewFrame)(PKImageEncode*, void*, size_t);
+
+    ERR (*Release)(PKImageEncode**);
+
+    struct WMPStream* pStream;
+    size_t offStart;
+
+    PKPixelFormatGUID guidPixFormat;
+
+    U32 uWidth;
+    U32 uHeight;
+    U32 idxCurrentLine;
+
+    Float fResX;
+    Float fResY;
+
+    U32 cFrame;
+
+    Bool fHeaderDone;
+    size_t offPixel;
+    size_t cbPixel;
+    U8 *pbColorContext;
+    U32 cbColorContext;
+    U8 *pbEXIFMetadata;
+    U32 cbEXIFMetadataByteCount;
+    U8 *pbGPSInfoMetadata;
+    U32 cbGPSInfoMetadataByteCount;
+    U8 *pbIPTCNAAMetadata;
+    U32 cbIPTCNAAMetadataByteCount;
+    U8 *pbXMPMetadata;
+    U32 cbXMPMetadataByteCount;
+    U8 *pbPhotoshopMetadata;
+    U32 cbPhotoshopMetadataByteCount;
+    DESCRIPTIVEMETADATA sDescMetadata;
+
+	Bool bWMP;//for the encoder in decoding
+
+    struct
+    {
+        WmpDEMisc wmiDEMisc;
+        CWMImageInfo wmiI;
+        CWMIStrCodecParam wmiSCP;
+        CTXSTRCODEC ctxSC;
+        CWMImageInfo wmiI_Alpha;
+        CWMIStrCodecParam wmiSCP_Alpha;
+        CTXSTRCODEC ctxSC_Alpha;
+
+        Bool bHasAlpha;
+        Long nOffImage;
+        Long nCbImage;
+        Long nOffAlpha;
+        Long nCbAlpha;
+
+        ORIENTATION oOrientation;
+
+        // Banded encode state variables
+        BANDEDENCSTATE      eBandedEncState;
+        struct WMPStream   *pPATempFile;
+    } WMP;
+
+#ifdef __ANSI__
+#undef PKImageEncode
+#endif // __ANSI__
+} PKImageEncode;
+
+//----------------------------------------------------------------
+ERR PKImageEncode_Create_WMP(PKImageEncode** ppIE);
+
+ERR PKImageEncode_Initialize(PKImageEncode* pIE, struct WMPStream* pStream, void* pvParam, size_t cbParam);
+ERR PKImageEncode_Terminate(PKImageEncode* pIE);
+ERR PKImageEncode_SetPixelFormat(PKImageEncode* pIE, PKPixelFormatGUID enPixelFormat);
+ERR PKImageEncode_SetSize(PKImageEncode* pIE, I32 iWidth, I32 iHeight);
+ERR PKImageEncode_SetResolution(PKImageEncode* pIE, Float rX, Float rY);
+ERR PKImageEncode_SetColorContext(PKImageEncode *pIE, const U8 *pbColorContext, U32 cbColorContext);
+ERR PKImageEncode_SetDescriptiveMetadata(PKImageEncode *pIE, const DESCRIPTIVEMETADATA *pDescMetadata);
+ERR PKImageEncode_WritePixels(PKImageEncode* pIE, U32 cLine, U8* pbPixel, U32 cbStride);
+ERR PKImageEncode_CreateNewFrame(PKImageEncode* pIE, void* pvParam, size_t cbParam);
+ERR PKImageEncode_Release(PKImageEncode** ppIE);
+
+ERR PKImageEncode_SetXMPMetadata_WMP(PKImageEncode *pIE, const U8 *pbXMPMetadata, U32 cbXMPMetadata);
+ERR PKImageEncode_SetEXIFMetadata_WMP(PKImageEncode *pIE, const U8 *pbEXIFMetadata, U32 cbEXIFMetadata);
+ERR PKImageEncode_SetGPSInfoMetadata_WMP(PKImageEncode *pIE, const U8 *pbGPSInfoMetadata, U32 cbGPSInfoMetadata);
+ERR PKImageEncode_SetIPTCNAAMetadata_WMP(PKImageEncode *pIE, const U8 *pbIPTCNAAMetadata, U32 cbIPTCNAAMetadata);
+ERR PKImageEncode_SetPhotoshopMetadata_WMP(PKImageEncode *pIE, const U8 *pbPhotoshopMetadata, U32 cbPhotoshopMetadata);
+
+void FreeDescMetadata(DPKPROPVARIANT *pvar);
+
+ERR PKImageEncode_Create(PKImageEncode** ppIE);
+
+//================================================================
+typedef struct tagPKImageDecode
+{
+    ERR (*Initialize)(PKImageDecode*, struct WMPStream* pStream);
+
+    ERR (*GetPixelFormat)(PKImageDecode*, PKPixelFormatGUID*);
+    ERR (*GetSize)(PKImageDecode*, I32*, I32*);
+    ERR (*GetResolution)(PKImageDecode*, Float*, Float*);
+    ERR (*GetColorContext)(PKImageDecode *pID, U8 *pbColorContext,
+        U32 *pcbColorContext);
+    ERR (*GetDescriptiveMetadata)(PKImageDecode *pIE,
+        DESCRIPTIVEMETADATA *pDescMetadata);
+
+    ERR (*GetRawStream)(PKImageDecode*, struct WMPStream**);
+
+    ERR (*Copy)(PKImageDecode*, const PKRect*, U8*, U32);
+
+    ERR (*GetFrameCount)(PKImageDecode*, U32*);
+    ERR (*SelectFrame)(PKImageDecode*, U32);
+
+    ERR (*Release)(PKImageDecode**);
+
+    struct WMPStream* pStream;
+    Bool fStreamOwner;
+    size_t offStart;
+    
+    PKPixelFormatGUID guidPixFormat;
+
+    U32 uWidth;
+    U32 uHeight;
+    U32 idxCurrentLine;
+
+    Float fResX;
+    Float fResY;
+
+    U32 cFrame;
+
+    struct
+    {
+        WmpDEMisc wmiDEMisc;
+        CWMImageInfo wmiI;
+        CWMIStrCodecParam wmiSCP;
+        CTXSTRCODEC ctxSC;
+        CWMImageInfo wmiI_Alpha;
+        CWMIStrCodecParam wmiSCP_Alpha;
+        CTXSTRCODEC ctxSC_Alpha;
+
+        Bool bHasAlpha;
+        Long nOffImage;
+        Long nCbImage;
+        Long nOffAlpha;
+        Long nCbAlpha;
+        Bool bIgnoreOverlap;
+        size_t DecoderCurrMBRow;
+        size_t DecoderCurrAlphaMBRow;
+        size_t cMarker;
+        size_t cLinesDecoded;
+        size_t cLinesCropped; // Lines may be cropped from the top - buffer for subsequent decodes must be adjusted
+        Bool fFirstNonZeroDecode;
+
+        Bool fOrientationFromContainer;
+        ORIENTATION oOrientationFromContainer; // Tag 0xBC02 in HD Photo container
+            
+        DESCRIPTIVEMETADATA sDescMetadata;
+    } WMP;
+
+#ifdef __ANSI__
+#undef PKImageDecode
+#endif // __ANSI__
+} PKImageDecode;
+
+//----------------------------------------------------------------
+ERR PKImageDecode_Create_WMP(PKImageDecode** ppID);
+
+ERR PKImageDecode_Initialize(PKImageDecode* pID, struct WMPStream* pStream);
+ERR PKImageDecode_GetPixelFormat(PKImageDecode* pID, PKPixelFormatGUID* pPF);
+ERR PKImageDecode_GetSize(PKImageDecode* pID, I32* piWidth, I32* piHeight);
+ERR PKImageDecode_GetResolution(PKImageDecode* pID, Float* pfrX, Float* pfrY);
+ERR PKImageDecode_GetColorContext(PKImageDecode *pID, U8 *pbColorContext, U32 *pcbColorContext);
+ERR PKImageDecode_GetDescriptiveMetadata(PKImageDecode *pID, DESCRIPTIVEMETADATA *pDescMetadata);
+ERR PKImageDecode_Copy(PKImageDecode* pID, const PKRect* pRect, U8* pb, U32 cbStride);
+ERR PKImageDecode_GetFrameCount(PKImageDecode* pID, U32* puCount);
+ERR PKImageDecode_SelectFrame(PKImageDecode* pID, U32 uFrame);
+ERR PKImageDecode_Release(PKImageDecode** ppID);
+
+ERR PKImageDecode_Create(PKImageDecode** ppID);
+ERR PKCodecFactory_CreateDecoderFromFile(const char* szFilename, PKImageDecode** ppDecoder);
+
+//================================================================
+typedef struct tagPKFormatConverter
+{
+    ERR (*Initialize)(PKFormatConverter*, PKImageDecode*, char *pExt, PKPixelFormatGUID);
+    ERR (*InitializeConvert)(PKFormatConverter* pFC, const PKPixelFormatGUID enPFFrom,
+                             char *pExt, PKPixelFormatGUID enPFTTo);
+
+    ERR (*GetPixelFormat)(PKFormatConverter*, PKPixelFormatGUID*);
+    ERR (*GetSourcePixelFormat)(PKFormatConverter*, PKPixelFormatGUID*);
+    ERR (*GetSize)(PKFormatConverter*, I32*, I32*);
+    ERR (*GetResolution)(PKFormatConverter*, Float*, Float*);
+
+    ERR (*Copy)(PKFormatConverter*, const PKRect*, U8*, U32);
+    ERR (*Convert)(PKFormatConverter*, const PKRect*, U8*, U32);
+
+    ERR (*Release)(PKFormatConverter**);
+
+    PKImageDecode* pDecoder;
+    PKPixelFormatGUID enPixelFormat;
+#ifdef __ANSI__
+#undef PKFormatConverter
+#endif // __ANSI__
+} PKFormatConverter;
+
+//----------------------------------------------------------------
+ERR PKImageEncode_Transcode(PKImageEncode* pIE, PKFormatConverter* pFC, PKRect* pRect);
+ERR PKImageEncode_WriteSource(PKImageEncode* pIE, PKFormatConverter* pFC, PKRect* pRect);
+ERR PKFormatConverter_Initialize(PKFormatConverter* pFC, PKImageDecode* pID, char *pExt, PKPixelFormatGUID enPF);
+ERR PKFormatConverter_InitializeConvert(PKFormatConverter* pFC, const PKPixelFormatGUID enPFFrom,
+                                        char *pExt, PKPixelFormatGUID enPFTo);
+ERR PKFormatConverter_GetPixelFormat(PKFormatConverter* pFC, PKPixelFormatGUID* pPF);
+ERR PKFormatConverter_GetSourcePixelFormat(PKFormatConverter* pFC, PKPixelFormatGUID* pPF);
+ERR PKFormatConverter_GetSize(PKFormatConverter* pFC, I32* piWidth, I32* piHeight);
+ERR PKFormatConverter_GetResolution(PKFormatConverter* pFC, Float* pfrX, Float* pfrY);
+ERR PKFormatConverter_Copy(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride);
+ERR PKFormatConverter_Convert(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride);
+ERR PKFormatConverter_Release(PKFormatConverter** ppFC);
+
+// Think of this as static member of PKFormatConverter "class"
+ERR PKFormatConverter_EnumConversions(const PKPixelFormatGUID *pguidSourcePF,
+                                      const U32 iIndex,
+                                      const PKPixelFormatGUID **ppguidTargetPF);
+
+ERR PKCodecFactory_CreateFormatConverter(PKFormatConverter** ppFConverter);
+
+//----------------------------------------------------------------
+ERR PKAlloc(void** ppv, size_t cb);
+ERR PKFree(void** ppv);
+ERR PKAllocAligned(void** ppv, size_t cb, size_t iAlign);
+ERR PKFreeAligned(void** ppv);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
diff --git a/Source/LibJXR/jxrgluelib/JXRGlueJxr.c b/Source/LibJXR/jxrgluelib/JXRGlueJxr.c
new file mode 100644
index 0000000..6e96a19
--- /dev/null
+++ b/Source/LibJXR/jxrgluelib/JXRGlueJxr.c
@@ -0,0 +1,2246 @@
+
+//*@@@+++@@@@******************************************************************
+//
+// Copyright � Microsoft Corp.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+// � Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// � Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//*@@@---@@@@******************************************************************
+#include <limits.h>
+#include <JXRGlue.h>
+
+
+static const char szHDPhotoFormat[] = "<dc:format>image/vnd.ms-photo</dc:format>";
+const U32 IFDEntryTypeSizes[] = { 0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8 };
+const U32 SizeofIFDEntry = sizeof(struct IFDEntry);
+
+
+void CalcMetadataSizeLPSTR(const DPKPROPVARIANT var,
+                           U16 *pcInactiveMetadata,
+                           U32 *pcbOffsetSize,
+                           U32 *pcbCount)
+{
+    if (DPKVT_EMPTY != var.vt)
+    {
+        U32 uiLenWithNull = (U32)strlen(var.VT.pszVal) + 1; // +1 for NULL;
+        assert(DPKVT_LPSTR == var.vt);
+
+        // We only use offset if size > 4
+        if (uiLenWithNull > 4)
+            *pcbOffsetSize += uiLenWithNull;
+
+        if (pcbCount)
+            *pcbCount = uiLenWithNull;
+    }
+    else
+        *pcInactiveMetadata += 1;
+}
+
+void CalcMetadataSizeLPWSTR(const DPKPROPVARIANT var,
+                            U16 *pcInactiveMetadata,
+                            U32 *pcbOffsetSize,
+                            U32 *pcbCount)
+{
+    if (DPKVT_EMPTY != var.vt)
+    {
+        U32 uiCBWithNull = sizeof(U16) * ((U32)wcslen((wchar_t *) var.VT.pwszVal) + 1); // +1 for NULL term;
+        assert(DPKVT_LPWSTR == var.vt);
+
+        // We only use offset if size > 4
+        if (uiCBWithNull > 4)
+            *pcbOffsetSize += uiCBWithNull;
+
+        if (pcbCount)
+            *pcbCount = uiCBWithNull;
+    }
+    else
+        *pcInactiveMetadata += 1;
+}
+
+void CalcMetadataSizeUI2(const DPKPROPVARIANT var,
+                         U16 *pcInactiveMetadata,
+                         U32 *pcbMetadataSize)
+{
+    UNREFERENCED_PARAMETER( pcbMetadataSize );
+    if (DPKVT_EMPTY != var.vt)
+    {
+        assert(DPKVT_UI2 == var.vt);
+        // This is a single UI2, so it will not be written via offset, but rather as value
+    }
+    else
+        *pcInactiveMetadata += 1;
+}
+
+void CalcMetadataSizeUI4(const DPKPROPVARIANT var,
+                         U16 *pcInactiveMetadata,
+                         U32 *pcbContainer)
+{
+    UNREFERENCED_PARAMETER( pcbContainer );
+    if (DPKVT_EMPTY != var.vt)
+    {
+        assert(DPKVT_UI4 == var.vt);
+        // This is a single UI4, so it will not be written via offset, but rather as value
+    }
+    else
+        *pcInactiveMetadata += 1;
+}
+
+ERR CalcMetadataOffsetSize(PKImageEncode* pIE,
+                           U16 *pcInactiveMetadata,
+                           U32 *pcbMetadataSize)
+{
+    ERR err = WMP_errSuccess;
+
+    CalcMetadataSizeLPSTR(pIE->sDescMetadata.pvarImageDescription, pcInactiveMetadata, pcbMetadataSize, NULL);
+    CalcMetadataSizeLPSTR(pIE->sDescMetadata.pvarCameraMake, pcInactiveMetadata, pcbMetadataSize, NULL);
+    CalcMetadataSizeLPSTR(pIE->sDescMetadata.pvarCameraModel, pcInactiveMetadata, pcbMetadataSize, NULL);
+    CalcMetadataSizeLPSTR(pIE->sDescMetadata.pvarSoftware, pcInactiveMetadata, pcbMetadataSize, NULL);
+    CalcMetadataSizeLPSTR(pIE->sDescMetadata.pvarDateTime, pcInactiveMetadata, pcbMetadataSize, NULL);
+    CalcMetadataSizeLPSTR(pIE->sDescMetadata.pvarArtist, pcInactiveMetadata, pcbMetadataSize, NULL);
+    CalcMetadataSizeLPSTR(pIE->sDescMetadata.pvarCopyright, pcInactiveMetadata, pcbMetadataSize, NULL);
+    CalcMetadataSizeUI2(pIE->sDescMetadata.pvarRatingStars, pcInactiveMetadata, pcbMetadataSize);
+    CalcMetadataSizeUI2(pIE->sDescMetadata.pvarRatingValue, pcInactiveMetadata, pcbMetadataSize);
+    CalcMetadataSizeLPWSTR(pIE->sDescMetadata.pvarCaption, pcInactiveMetadata, pcbMetadataSize, NULL);
+    CalcMetadataSizeLPSTR(pIE->sDescMetadata.pvarDocumentName, pcInactiveMetadata, pcbMetadataSize, NULL);
+    CalcMetadataSizeLPSTR(pIE->sDescMetadata.pvarPageName, pcInactiveMetadata, pcbMetadataSize, NULL);
+    CalcMetadataSizeUI4(pIE->sDescMetadata.pvarPageNumber, pcInactiveMetadata, pcbMetadataSize);
+    CalcMetadataSizeLPSTR(pIE->sDescMetadata.pvarHostComputer, pcInactiveMetadata, pcbMetadataSize, NULL);
+
+    return err;
+}
+
+
+ERR CopyDescMetadata(DPKPROPVARIANT *pvarDst,
+                     const DPKPROPVARIANT varSrc)
+{
+    ERR err = WMP_errSuccess;
+    size_t  uiSize;
+
+    pvarDst->vt = varSrc.vt;
+    switch (varSrc.vt)
+    {
+        case DPKVT_LPSTR:
+            pvarDst->vt = DPKVT_LPSTR;
+            uiSize = strlen(varSrc.VT.pszVal) + 1;
+            Call(PKAlloc((void **) &pvarDst->VT.pszVal, uiSize));
+            memcpy(pvarDst->VT.pszVal, varSrc.VT.pszVal, uiSize);
+            break;
+            
+        case DPKVT_LPWSTR:
+            pvarDst->vt = DPKVT_LPWSTR;
+            uiSize = sizeof(U16) * (wcslen((wchar_t *) varSrc.VT.pwszVal) + 1); // +1 for NULL term
+            Call(PKAlloc((void **) &pvarDst->VT.pszVal, uiSize));
+            memcpy(pvarDst->VT.pwszVal, varSrc.VT.pwszVal, uiSize);
+            break;
+
+        case DPKVT_UI2:
+            pvarDst->VT.uiVal = varSrc.VT.uiVal;
+            break;
+
+        case DPKVT_UI4:
+            pvarDst->VT.ulVal = varSrc.VT.ulVal;
+            break;
+
+        default:
+            assert(FALSE); // This case is not handled
+            FailIf(TRUE, WMP_errNotYetImplemented);
+
+            // *** FALL THROUGH ***
+
+        case DPKVT_EMPTY:
+            memset(pvarDst, 0, sizeof(*pvarDst));
+            assert(DPKVT_EMPTY == pvarDst->vt);
+            break;
+    }
+
+Cleanup:
+    return err;
+}
+
+
+void FreeDescMetadata(DPKPROPVARIANT *pvar)
+{
+    switch (pvar->vt)
+    {
+        case DPKVT_LPSTR:
+            PKFree((void **) &pvar->VT.pszVal);
+            break;
+
+        case DPKVT_LPWSTR:
+            PKFree((void **) &pvar->VT.pwszVal);
+            break;
+
+        default:
+            assert(FALSE); // This case is not handled
+            break;
+
+        case DPKVT_EMPTY:
+        case DPKVT_UI2:
+        case DPKVT_UI4:
+            break;
+    }
+}
+
+
+ERR WriteDescMetadata(PKImageEncode *pIE,
+                      const DPKPROPVARIANT var,
+                      WmpDE *pwmpDE,
+                      U32 *puiCurrDescMetadataOffset,
+                      size_t *poffPos)
+{
+    ERR err = WMP_errSuccess;
+    WmpDEMisc* pDEMisc = &pIE->WMP.wmiDEMisc;
+    struct WMPStream* pWS = pIE->pStream;
+    U32 uiMetadataOffsetSize = 0;
+    U32 uiCount = 0;
+    U32 uiDataWrittenToOffset = 0;
+    U16 uiTemp = 0;
+
+    if (0 == pDEMisc->uDescMetadataOffset || 0 == pDEMisc->uDescMetadataByteCount)
+        goto Cleanup; // Nothing to do here
+
+    // Sanity check before - can be equal due to remaining metadata being DPKVT_EMPTY
+    assert(*puiCurrDescMetadataOffset <= pDEMisc->uDescMetadataByteCount);
+
+    switch (var.vt)
+    {
+        case DPKVT_EMPTY:
+            break;
+
+        case DPKVT_LPSTR:
+            CalcMetadataSizeLPSTR(var, &uiTemp, &uiMetadataOffsetSize, &uiCount);
+            pwmpDE->uCount = uiCount;
+            pwmpDE->uValueOrOffset = pDEMisc->uDescMetadataOffset + *puiCurrDescMetadataOffset;
+            Call(WriteWmpDE(pWS, poffPos, pwmpDE, (U8*)var.VT.pszVal, &uiDataWrittenToOffset));
+            break;
+
+        case DPKVT_LPWSTR:
+            CalcMetadataSizeLPWSTR(var, &uiTemp, &uiMetadataOffsetSize, &uiCount);
+            pwmpDE->uCount = uiCount;
+            pwmpDE->uValueOrOffset = pDEMisc->uDescMetadataOffset + *puiCurrDescMetadataOffset;
+            Call(WriteWmpDE(pWS, poffPos, pwmpDE, (U8*)var.VT.pwszVal, &uiDataWrittenToOffset));
+            break;
+
+        case DPKVT_UI2:
+            CalcMetadataSizeUI2(var, &uiTemp, &uiMetadataOffsetSize);
+            pwmpDE->uCount = 1;
+            pwmpDE->uValueOrOffset = var.VT.uiVal;
+            Call(WriteWmpDE(pWS, poffPos, pwmpDE, NULL, NULL));
+            break;
+
+        case DPKVT_UI4:
+            CalcMetadataSizeUI4(var, &uiTemp, &uiMetadataOffsetSize);
+            pwmpDE->uCount = 1;
+            pwmpDE->uValueOrOffset = var.VT.ulVal;
+            Call(WriteWmpDE(pWS, poffPos, pwmpDE, NULL, NULL));
+            break;
+
+        default:
+            assert(FALSE); // This case is not handled
+            FailIf(TRUE, WMP_errNotYetImplemented);
+            break;
+    }
+
+    *puiCurrDescMetadataOffset += uiDataWrittenToOffset;
+
+    // Sanity check after
+    assert(*puiCurrDescMetadataOffset <= pDEMisc->uDescMetadataByteCount); // Can be equal
+
+Cleanup:
+    return err;
+}
+
+
+
+//================================================================
+// PKImageEncode_WMP
+//================================================================
+ERR WriteContainerPre(
+    PKImageEncode* pIE)
+{
+    ERR err = WMP_errSuccess;
+    const U32 OFFSET_OF_PFD = 0x20;
+    struct WMPStream* pWS = pIE->pStream;
+    WmpDEMisc* pDEMisc = &pIE->WMP.wmiDEMisc;
+    PKPixelInfo PI;
+    size_t offPos = 0;
+
+    U8 IIMM[2] = {'\x49', '\x49'};
+    // const U32 cbWmpDEMisc = OFFSET_OF_PFD;
+    U32 cbMetadataOffsetSize = 0;
+    U16 cInactiveMetadata = 0;
+    U32 uiCurrDescMetadataOffset = 0;
+
+    static WmpDE wmpDEs[] =
+    {
+        {WMP_tagDocumentName, WMP_typASCII, 1, (U32) -1},     // Descriptive metadata
+        {WMP_tagImageDescription, WMP_typASCII, 1, (U32) -1}, // Descriptive metadata
+        {WMP_tagCameraMake, WMP_typASCII, 1, (U32) -1},       // Descriptive metadata
+        {WMP_tagCameraModel, WMP_typASCII, 1, (U32) -1},      // Descriptive metadata
+        {WMP_tagPageName, WMP_typASCII, 1, (U32) -1},         // Descriptive metadata
+        {WMP_tagPageNumber, WMP_typSHORT, 2, (U32) -1},       // Descriptive metadata
+        {WMP_tagSoftware, WMP_typASCII, 1, (U32) -1},         // Descriptive metadata
+        {WMP_tagDateTime, WMP_typASCII, 1, (U32) -1},         // Descriptive metadata
+        {WMP_tagArtist, WMP_typASCII, 1, (U32) -1},           // Descriptive metadata
+        {WMP_tagHostComputer, WMP_typASCII, 1, (U32) -1},     // Descriptive metadata
+        {WMP_tagRatingStars, WMP_typSHORT, 1, (U32) -1},      // Descriptive metadata
+        {WMP_tagRatingValue, WMP_typSHORT, 1, (U32) -1},      // Descriptive metadata
+        {WMP_tagCopyright, WMP_typASCII, 1, (U32) -1},        // Descriptive metadata
+        {WMP_tagCaption, WMP_typBYTE, 1, (U32) -1},           // Descriptive metadata
+
+        {WMP_tagXMPMetadata, WMP_typBYTE, 1, (U32) -1},
+        {WMP_tagIPTCNAAMetadata, WMP_typBYTE, 1, (U32) -1},
+        {WMP_tagPhotoshopMetadata, WMP_typBYTE, 1, (U32) -1},
+        {WMP_tagEXIFMetadata, WMP_typLONG, 1, (U32) -1},
+        {WMP_tagIccProfile, WMP_typUNDEFINED, 1, (U32) -1},
+        {WMP_tagGPSInfoMetadata, WMP_typLONG, 1, (U32) -1},
+
+        {WMP_tagPixelFormat, WMP_typBYTE, 16, (U32) -1},
+        {WMP_tagTransformation, WMP_typLONG, 1, (U32) -1},
+        {WMP_tagImageWidth, WMP_typLONG, 1, (U32) -1},
+        {WMP_tagImageHeight, WMP_typLONG, 1, (U32) -1},
+        {WMP_tagWidthResolution, WMP_typFLOAT, 1, (U32) -1},
+        {WMP_tagHeightResolution, WMP_typFLOAT, 1, (U32) -1},
+        {WMP_tagImageOffset, WMP_typLONG, 1, (U32) -1},
+        {WMP_tagImageByteCount, WMP_typLONG, 1, (U32) -1},
+        {WMP_tagAlphaOffset, WMP_typLONG, 1, (U32) -1},
+        {WMP_tagAlphaByteCount, WMP_typLONG, 1, (U32) -1},
+    };
+    U16 cWmpDEs = sizeof(wmpDEs) / sizeof(wmpDEs[0]);
+    WmpDE wmpDE = {0};
+    size_t i = 0;
+
+    U8* pbEXIFMetadata = NULL;
+    U8* pbGPSInfoMetadata = NULL;
+
+    // const unsigned char Zero[0x20] = { 0 };
+    const unsigned char Zero[sizeof(struct IFDEntry) * sizeof(wmpDEs) / sizeof(wmpDEs[0]) + sizeof(U32)] = { 0 };
+    assert(SizeofIFDEntry * sizeof(wmpDEs) / sizeof(wmpDEs[0]) + sizeof(U32) > 0x20);
+
+    //================
+    Call(pWS->GetPos(pWS, &offPos));
+    FailIf(0 != offPos, WMP_errUnsupportedFormat);
+
+    //================
+    // Header (8 bytes)
+    Call(pWS->Write(pWS, IIMM, sizeof(IIMM))); offPos += 2;
+    Call(PutUShort(pWS, offPos, 0x01bc)); offPos += 2;
+    Call(PutULong(pWS, offPos, (U32)OFFSET_OF_PFD)); offPos += 4;
+
+    //================
+    // Write overflow area
+    pDEMisc->uOffPixelFormat = (U32)offPos;
+    PI.pGUIDPixFmt = &pIE->guidPixFormat;
+    PixelFormatLookup(&PI, LOOKUP_FORWARD);
+
+    //Call(pWS->Write(pWS, PI.pGUIDPixFmt, sizeof(*PI.pGUIDPixFmt))); offPos += 16;
+    /** following code is endian-agnostic **/
+    {
+        unsigned char *pGuid = (unsigned char *) &pIE->guidPixFormat;
+        Call(PutULong(pWS, offPos, ((U32 *)pGuid)[0]));
+        Call(PutUShort(pWS, offPos + 4, ((U16 *)(pGuid + 4))[0]));
+        Call(PutUShort(pWS, offPos + 6, ((U16 *)(pGuid + 6))[0]));
+        Call(pWS->Write(pWS, pGuid + 8, 8));
+        offPos += 16;
+    }
+
+    //================
+    // Tally up space required for descriptive metadata 
+    Call(CalcMetadataOffsetSize(pIE, &cInactiveMetadata, &cbMetadataOffsetSize));
+    cWmpDEs -= cInactiveMetadata;
+
+    //================
+    // PFD
+    assert (offPos <= OFFSET_OF_PFD); // otherwise stuff is overwritten
+    if (offPos < OFFSET_OF_PFD)
+        Call(pWS->Write(pWS, Zero, OFFSET_OF_PFD - offPos));
+    offPos = (size_t)OFFSET_OF_PFD;
+
+    if (!pIE->WMP.bHasAlpha || pIE->WMP.wmiSCP.uAlphaMode != 2) //no planar alpha
+        cWmpDEs -= 2;
+
+    if (0 == pIE->cbXMPMetadataByteCount)
+        cWmpDEs -= 1; // No XMP metadata
+
+    if (0 == pIE->cbIPTCNAAMetadataByteCount)
+        cWmpDEs -= 1; // No IPTCNAA metadata
+
+    if (0 == pIE->cbPhotoshopMetadataByteCount)
+        cWmpDEs -= 1; // No Photoshop metadata
+
+    if (0 == pIE->cbEXIFMetadataByteCount)
+        cWmpDEs -= 1; // No EXIF metadata
+
+    if (0 == pIE->cbColorContext)
+        cWmpDEs -= 1; // No color context
+
+    if (0 == pIE->cbGPSInfoMetadataByteCount)
+        cWmpDEs -= 1; // No GPSInfo metadata
+
+    pDEMisc->uImageOffset = (U32)(offPos + sizeof(U16) + SizeofIFDEntry * cWmpDEs + sizeof(U32));
+    
+    if (cbMetadataOffsetSize > 0)
+    {
+        pDEMisc->uDescMetadataByteCount = cbMetadataOffsetSize;
+        pDEMisc->uDescMetadataOffset = pDEMisc->uImageOffset;
+        pDEMisc->uImageOffset += cbMetadataOffsetSize;
+    }
+
+    if (pIE->cbXMPMetadataByteCount > 0)
+    {
+        pDEMisc->uXMPMetadataOffset = pDEMisc->uImageOffset;
+        pDEMisc->uImageOffset += pIE->cbXMPMetadataByteCount;
+    }
+
+    if (pIE->cbIPTCNAAMetadataByteCount > 0)
+    {
+        pDEMisc->uIPTCNAAMetadataOffset = pDEMisc->uImageOffset;
+        pDEMisc->uImageOffset += pIE->cbIPTCNAAMetadataByteCount;
+    }
+
+    if (pIE->cbPhotoshopMetadataByteCount > 0)
+    {
+        pDEMisc->uPhotoshopMetadataOffset = pDEMisc->uImageOffset;
+        pDEMisc->uImageOffset += pIE->cbPhotoshopMetadataByteCount;
+    }
+
+    if (pIE->cbEXIFMetadataByteCount > 0)
+    {
+        pDEMisc->uEXIFMetadataOffset = pDEMisc->uImageOffset;
+        pDEMisc->uImageOffset += (pDEMisc->uImageOffset & 1);
+        pDEMisc->uImageOffset += pIE->cbEXIFMetadataByteCount;
+    }
+
+    if (pIE->cbColorContext > 0)
+    {
+        pDEMisc->uColorProfileOffset = pDEMisc->uImageOffset;
+        pDEMisc->uImageOffset += pIE->cbColorContext;
+    }
+
+    if (pIE->cbGPSInfoMetadataByteCount > 0)
+    {
+        pDEMisc->uGPSInfoMetadataOffset = pDEMisc->uImageOffset;
+        pDEMisc->uImageOffset += (pDEMisc->uImageOffset & 1);
+        pDEMisc->uImageOffset += pIE->cbGPSInfoMetadataByteCount;
+    }
+
+    Call(PutUShort(pWS, offPos, cWmpDEs)); offPos += 2;
+    Call(pWS->Write(pWS, Zero, SizeofIFDEntry * cWmpDEs + sizeof(U32)));
+
+    //================
+    wmpDE = wmpDEs[i++];
+    assert(WMP_tagDocumentName == wmpDE.uTag);
+    Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarDocumentName, &wmpDE,
+        &uiCurrDescMetadataOffset, &offPos));
+
+    wmpDE = wmpDEs[i++];
+    assert(WMP_tagImageDescription == wmpDE.uTag);
+    Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarImageDescription, &wmpDE,
+        &uiCurrDescMetadataOffset, &offPos));
+
+    wmpDE = wmpDEs[i++];
+    assert(WMP_tagCameraMake == wmpDE.uTag);
+    Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarCameraMake, &wmpDE,
+        &uiCurrDescMetadataOffset, &offPos));
+
+    wmpDE = wmpDEs[i++];
+    assert(WMP_tagCameraModel == wmpDE.uTag);
+    Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarCameraModel, &wmpDE,
+        &uiCurrDescMetadataOffset, &offPos));
+
+    wmpDE = wmpDEs[i++];
+    assert(WMP_tagPageName == wmpDE.uTag);
+    Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarPageName, &wmpDE,
+        &uiCurrDescMetadataOffset, &offPos));
+
+    wmpDE = wmpDEs[i++];
+    assert(WMP_tagPageNumber == wmpDE.uTag);
+    Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarPageNumber, &wmpDE,
+        &uiCurrDescMetadataOffset, &offPos));
+
+    wmpDE = wmpDEs[i++];
+    assert(WMP_tagSoftware == wmpDE.uTag);
+    Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarSoftware, &wmpDE,
+        &uiCurrDescMetadataOffset, &offPos));
+
+    wmpDE = wmpDEs[i++];
+    assert(WMP_tagDateTime == wmpDE.uTag);
+    Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarDateTime, &wmpDE,
+        &uiCurrDescMetadataOffset, &offPos));
+
+    wmpDE = wmpDEs[i++];
+    assert(WMP_tagArtist == wmpDE.uTag);
+    Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarArtist, &wmpDE,
+        &uiCurrDescMetadataOffset, &offPos));
+
+    wmpDE = wmpDEs[i++];
+    assert(WMP_tagHostComputer == wmpDE.uTag);
+    Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarHostComputer, &wmpDE,
+        &uiCurrDescMetadataOffset, &offPos));
+
+    wmpDE = wmpDEs[i++];
+    assert(WMP_tagRatingStars == wmpDE.uTag);
+    Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarRatingStars, &wmpDE,
+        &uiCurrDescMetadataOffset, &offPos));
+
+    wmpDE = wmpDEs[i++];
+    assert(WMP_tagRatingValue == wmpDE.uTag);
+    Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarRatingValue, &wmpDE,
+        &uiCurrDescMetadataOffset, &offPos));
+
+    wmpDE = wmpDEs[i++];
+    assert(WMP_tagCopyright == wmpDE.uTag);
+    Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarCopyright, &wmpDE,
+        &uiCurrDescMetadataOffset, &offPos));
+
+    wmpDE = wmpDEs[i++];
+    assert(WMP_tagCaption == wmpDE.uTag);
+    Call(WriteDescMetadata(pIE, pIE->sDescMetadata.pvarCaption, &wmpDE,
+        &uiCurrDescMetadataOffset, &offPos));
+
+    // XMP Metadata
+    wmpDE = wmpDEs[i++];
+    assert(WMP_tagXMPMetadata == wmpDE.uTag);
+    if (pIE->cbXMPMetadataByteCount > 0)
+    {
+        U32 uiTemp;
+        wmpDE.uCount = pIE->cbXMPMetadataByteCount;
+        wmpDE.uValueOrOffset = pDEMisc->uXMPMetadataOffset;
+        Call(WriteWmpDE(pWS, &offPos, &wmpDE, pIE->pbXMPMetadata, &uiTemp));
+    }
+
+    // IPTCNAA Metadata
+    wmpDE = wmpDEs[i++];
+    assert(WMP_tagIPTCNAAMetadata == wmpDE.uTag);
+    if (pIE->cbIPTCNAAMetadataByteCount > 0)
+    {
+        U32 uiTemp;
+        wmpDE.uCount = pIE->cbIPTCNAAMetadataByteCount;
+        wmpDE.uValueOrOffset = pDEMisc->uIPTCNAAMetadataOffset;
+        Call(WriteWmpDE(pWS, &offPos, &wmpDE, pIE->pbIPTCNAAMetadata, &uiTemp));
+    }
+
+    // Photoshop Metadata
+    wmpDE = wmpDEs[i++];
+    assert(WMP_tagPhotoshopMetadata == wmpDE.uTag);
+    if (pIE->cbPhotoshopMetadataByteCount > 0)
+    {
+        U32 uiTemp;
+        wmpDE.uCount = pIE->cbPhotoshopMetadataByteCount;
+        wmpDE.uValueOrOffset = pDEMisc->uPhotoshopMetadataOffset;
+        Call(WriteWmpDE(pWS, &offPos, &wmpDE, pIE->pbPhotoshopMetadata, &uiTemp));
+    }
+
+    // EXIF Metadata
+    wmpDE = wmpDEs[i++];
+    assert(WMP_tagEXIFMetadata == wmpDE.uTag);
+    if (pIE->cbEXIFMetadataByteCount > 0)
+    {
+        U32 uiTemp;
+        if ((pDEMisc->uEXIFMetadataOffset & 1) != 0)
+        {
+            Call(pWS->SetPos(pWS, pDEMisc->uEXIFMetadataOffset));
+            Call(pWS->Write(pWS, Zero, 1));
+        }
+        pDEMisc->uEXIFMetadataOffset += (pDEMisc->uEXIFMetadataOffset & 1);
+        wmpDE.uValueOrOffset = pDEMisc->uEXIFMetadataOffset;
+        Call(WriteWmpDE(pWS, &offPos, &wmpDE, NULL, NULL));
+
+        Call(PKAlloc((void **) &pbEXIFMetadata, pIE->cbEXIFMetadataByteCount));
+        uiTemp = pDEMisc->uEXIFMetadataOffset;
+        Call(BufferCopyIFD(pIE->pbEXIFMetadata, pIE->cbEXIFMetadataByteCount, 0, WMP_INTEL_ENDIAN,
+            pbEXIFMetadata - uiTemp, uiTemp + pIE->cbEXIFMetadataByteCount, &uiTemp));
+        Call(pWS->SetPos(pWS, pDEMisc->uEXIFMetadataOffset));
+        Call(pWS->Write(pWS, pbEXIFMetadata, pIE->cbEXIFMetadataByteCount));
+    }
+
+    // ICC Profile
+    wmpDE = wmpDEs[i++];
+    assert(WMP_tagIccProfile == wmpDE.uTag);
+    if (pIE->cbColorContext > 0)
+    {
+        U32 uiTemp;
+        wmpDE.uCount = pIE->cbColorContext;
+        wmpDE.uValueOrOffset = pDEMisc->uColorProfileOffset;
+        Call(WriteWmpDE(pWS, &offPos, &wmpDE, pIE->pbColorContext, &uiTemp));
+    }
+
+    // GPSInfo Metadata
+    wmpDE = wmpDEs[i++];
+    assert(WMP_tagGPSInfoMetadata == wmpDE.uTag);
+    if (pIE->cbGPSInfoMetadataByteCount > 0)
+    {
+        U32 uiTemp;
+        if ((pDEMisc->uGPSInfoMetadataOffset & 1) != 0)
+        {
+            Call(pWS->SetPos(pWS, pDEMisc->uGPSInfoMetadataOffset));
+            Call(pWS->Write(pWS, Zero, 1));
+        }
+        pDEMisc->uGPSInfoMetadataOffset += (pDEMisc->uGPSInfoMetadataOffset & 1);
+        wmpDE.uValueOrOffset = pDEMisc->uGPSInfoMetadataOffset;
+        Call(WriteWmpDE(pWS, &offPos, &wmpDE, NULL, NULL));
+
+        Call(PKAlloc((void **) &pbGPSInfoMetadata, pIE->cbGPSInfoMetadataByteCount));
+        uiTemp = pDEMisc->uGPSInfoMetadataOffset;
+        Call(BufferCopyIFD(pIE->pbGPSInfoMetadata, pIE->cbGPSInfoMetadataByteCount, 0, WMP_INTEL_ENDIAN,
+            pbGPSInfoMetadata - uiTemp, uiTemp + pIE->cbGPSInfoMetadataByteCount, &uiTemp));
+        Call(pWS->SetPos(pWS, pDEMisc->uGPSInfoMetadataOffset));
+        Call(pWS->Write(pWS, pbGPSInfoMetadata, pIE->cbGPSInfoMetadataByteCount));
+    }
+
+    wmpDE = wmpDEs[i++];
+    assert(WMP_tagPixelFormat == wmpDE.uTag);
+    wmpDE.uValueOrOffset = pDEMisc->uOffPixelFormat;
+    Call(WriteWmpDE(pWS, &offPos, &wmpDE, NULL, NULL));
+
+    wmpDE = wmpDEs[i++];
+    assert(WMP_tagTransformation == wmpDE.uTag);
+    wmpDE.uValueOrOffset = pIE->WMP.oOrientation;
+    Call(WriteWmpDE(pWS, &offPos, &wmpDE, NULL, NULL));
+
+    wmpDE = wmpDEs[i++];
+    assert(WMP_tagImageWidth == wmpDE.uTag);
+    wmpDE.uValueOrOffset = pIE->uWidth;
+    Call(WriteWmpDE(pWS, &offPos, &wmpDE, NULL, NULL));
+
+    wmpDE = wmpDEs[i++];
+    assert(WMP_tagImageHeight == wmpDE.uTag);
+    wmpDE.uValueOrOffset = pIE->uHeight;
+    Call(WriteWmpDE(pWS, &offPos, &wmpDE, NULL, NULL));
+    
+    wmpDE = wmpDEs[i++];
+    assert(WMP_tagWidthResolution == wmpDE.uTag);
+    *((float *) &wmpDE.uValueOrOffset) = pIE->fResX;
+    Call(WriteWmpDE(pWS, &offPos, &wmpDE, NULL, NULL));
+
+    wmpDE = wmpDEs[i++];
+    assert(WMP_tagHeightResolution == wmpDE.uTag);
+    *((float *) &wmpDE.uValueOrOffset) = pIE->fResY;
+    Call(WriteWmpDE(pWS, &offPos, &wmpDE, NULL, NULL));
+   
+    wmpDE = wmpDEs[i++];
+    assert(WMP_tagImageOffset == wmpDE.uTag);
+    wmpDE.uValueOrOffset = pDEMisc->uImageOffset;
+    Call(WriteWmpDE(pWS, &offPos, &wmpDE, NULL, NULL));
+
+    // fix up in WriteContainerPost()
+    wmpDE = wmpDEs[i++];
+    assert(WMP_tagImageByteCount == wmpDE.uTag);
+    pDEMisc->uOffImageByteCount = (U32)offPos;
+    wmpDE.uValueOrOffset = 0;
+    Call(WriteWmpDE(pWS, &offPos, &wmpDE, NULL, NULL));
+
+    if (pIE->WMP.bHasAlpha && pIE->WMP.wmiSCP.uAlphaMode == 2)
+    {
+        // fix up in WriteContainerPost()
+        wmpDE = wmpDEs[i++];
+        assert(WMP_tagAlphaOffset == wmpDE.uTag);
+        pDEMisc->uOffAlphaOffset = (U32)offPos;
+        wmpDE.uValueOrOffset = 0;
+        Call(WriteWmpDE(pWS, &offPos, &wmpDE, NULL, NULL));
+
+        // fix up in WriteContainerPost()
+        wmpDE = wmpDEs[i++];
+        assert(WMP_tagAlphaByteCount == wmpDE.uTag);
+        pDEMisc->uOffAlphaByteCount = (U32)offPos;
+        wmpDE.uValueOrOffset = 0;
+        Call(WriteWmpDE(pWS, &offPos, &wmpDE, NULL, NULL));
+    }
+
+    //================
+    Call(PutULong(pWS, offPos, 0)); offPos += 4;
+
+    assert(0 == (offPos & 1));
+    if (pDEMisc->uColorProfileOffset > 0 || pDEMisc->uDescMetadataOffset > 0 ||
+        pDEMisc->uXMPMetadataOffset > 0 || pDEMisc->uIPTCNAAMetadataOffset > 0 ||
+        pDEMisc->uPhotoshopMetadataOffset > 0 || pDEMisc->uEXIFMetadataOffset > 0 ||
+        pDEMisc->uGPSInfoMetadataOffset > 0)
+    {
+        assert(pDEMisc->uColorProfileOffset == offPos ||
+               pDEMisc->uDescMetadataOffset == offPos ||
+               pDEMisc->uXMPMetadataOffset == offPos ||
+               pDEMisc->uIPTCNAAMetadataOffset == offPos ||
+               pDEMisc->uPhotoshopMetadataOffset == offPos ||
+               pDEMisc->uEXIFMetadataOffset == offPos ||
+               pDEMisc->uGPSInfoMetadataOffset == offPos);
+
+        // OK, now skip to image offset
+        Call(pWS->SetPos(pWS, pDEMisc->uImageOffset));
+        offPos = pDEMisc->uImageOffset;
+    }
+    assert(pDEMisc->uImageOffset == offPos);
+
+Cleanup:
+    if (pbEXIFMetadata != NULL)
+        PKFree((void **) &pbEXIFMetadata);
+    if (pbGPSInfoMetadata != NULL)
+        PKFree((void **) &pbGPSInfoMetadata);
+    return err;
+}
+
+
+
+ERR WriteContainerPost(
+    PKImageEncode* pIE)
+{
+    ERR err = WMP_errSuccess;
+
+    struct WMPStream* pWS = pIE->pStream;
+    WmpDEMisc* pDEMisc = &pIE->WMP.wmiDEMisc;
+    size_t offPos;
+
+    WmpDE deImageByteCount = {WMP_tagImageByteCount, WMP_typLONG,  1, 0};
+    WmpDE deAlphaOffset     = {WMP_tagAlphaOffset, WMP_typLONG,  1, 0};
+    WmpDE deAlphaByteCount  = {WMP_tagAlphaByteCount, WMP_typLONG,  1, 0};
+
+    deImageByteCount.uValueOrOffset = pIE->WMP.nCbImage;
+    offPos = pDEMisc->uOffImageByteCount;
+    Call(WriteWmpDE(pWS, &offPos, &deImageByteCount, NULL, NULL));
+
+    //Alpha
+    if (pIE->WMP.bHasAlpha && pIE->WMP.wmiSCP.uAlphaMode == 2)
+    {                
+        deAlphaOffset.uValueOrOffset = pIE->WMP.nOffAlpha;
+        offPos = pDEMisc->uOffAlphaOffset;
+        Call(WriteWmpDE(pWS, &offPos, &deAlphaOffset, NULL, NULL));
+
+        deAlphaByteCount.uValueOrOffset = pIE->WMP.nCbAlpha + pIE->WMP.nOffAlpha;
+        offPos = pDEMisc->uOffAlphaByteCount;
+        Call(WriteWmpDE(pWS, &offPos, &deAlphaByteCount, NULL, NULL));
+    }
+
+Cleanup:
+    return err;
+}
+
+
+//================================================
+ERR PKImageEncode_Initialize_WMP(
+    PKImageEncode* pIE,
+    struct WMPStream* pStream,
+    void* pvParam,
+    size_t cbParam)
+{
+    ERR err = WMP_errSuccess;
+
+    FailIf(sizeof(pIE->WMP.wmiSCP) != cbParam, WMP_errInvalidArgument);
+
+    pIE->WMP.wmiSCP = *(CWMIStrCodecParam*)pvParam;
+    pIE->WMP.wmiSCP_Alpha = *(CWMIStrCodecParam*)pvParam;
+    pIE->pStream = pStream;
+
+    pIE->WMP.wmiSCP.pWStream = pIE->pStream;
+    pIE->WMP.wmiSCP_Alpha.pWStream = pIE->pStream;
+
+Cleanup:
+    return err;
+}
+
+ERR PKImageEncode_Terminate_WMP(
+    PKImageEncode* pIE)
+{
+    ERR err = WMP_errSuccess;
+    UNREFERENCED_PARAMETER( pIE );
+    return err;
+}
+
+
+ERR PKImageEncode_EncodeContent_Init(
+    PKImageEncode* pIE, 
+    PKPixelInfo PI,
+    U32 cLine,
+    U8* pbPixels,
+    U32 cbStride)
+{
+    ERR err = WMP_errSuccess;
+
+    // init codec
+    pIE->WMP.wmiI.cWidth = pIE->uWidth;
+    pIE->WMP.wmiI.cHeight = pIE->uHeight;
+    pIE->WMP.wmiI.bdBitDepth = PI.bdBitDepth;
+    pIE->WMP.wmiI.cBitsPerUnit = PI.cbitUnit;
+    pIE->WMP.wmiI.bRGB = !(PI.grBit & PK_pixfmtBGR);
+    pIE->WMP.wmiI.cfColorFormat = PI.cfColorFormat;
+    pIE->WMP.wmiI.oOrientation = pIE->WMP.oOrientation;
+    
+    // Set the fPaddedUserBuffer if the following conditions are met
+    if (0 == ((size_t)pbPixels % 128) &&        // Frame buffer is aligned to 128-byte boundary
+        0 == (pIE->uWidth % 16) &&              // Horizontal resolution is multiple of 16
+        0 == (cLine % 16) &&                    // Vertical resolution is multiple of 16
+        0 == (cbStride % 128))                  // Stride is a multiple of 128 bytes
+    {
+        pIE->WMP.wmiI.fPaddedUserBuffer = TRUE;
+        // Note that there are additional conditions in strenc_x86.c's strEncOpt
+        // which could prevent optimization from being engaged
+    }
+
+    //if (pIE->WMP.bHasAlpha)
+    //{
+    //    pIE->WMP.wmiSCP.cChannel = PI.cChannel - 1;
+    //    pIE->WMP.wmiI.cfColorFormat = PI.cfStripAlpha;
+    //}
+    //else
+
+    if(PI.cfColorFormat == NCOMPONENT && (!(PI.grBit & PK_pixfmtHasAlpha)))//N-channel without Alpha
+        pIE->WMP.wmiSCP.cChannel = PI.cChannel;
+    else 
+        pIE->WMP.wmiSCP.cChannel = PI.cChannel - 1;//other formats and (N-channel + Alpha)
+
+    pIE->idxCurrentLine = 0;
+    
+    pIE->WMP.wmiSCP.fMeasurePerf = TRUE;
+    FailIf(ICERR_OK != ImageStrEncInit(&pIE->WMP.wmiI, &pIE->WMP.wmiSCP, &pIE->WMP.ctxSC), WMP_errFail);
+
+Cleanup:
+    return err;
+}
+
+ERR PKImageEncode_EncodeContent_Encode(
+    PKImageEncode* pIE, 
+    U32 cLine,
+    U8* pbPixels,
+    U32 cbStride)
+{
+    ERR err = WMP_errSuccess;
+    U32 i = 0;
+
+    //================================
+    for (i = 0; i < cLine; i += 16)
+    {
+		Bool f420 = ( pIE->WMP.wmiI.cfColorFormat == YUV_420 || 
+					  (pIE->WMP.wmiSCP.bYUVData && pIE->WMP.wmiSCP.cfColorFormat==YUV_420) );
+        CWMImageBufferInfo wmiBI = { 0 };
+        wmiBI.pv = pbPixels + cbStride * i / (f420 ? 2 : 1);
+        wmiBI.cLine = min(16, cLine - i);
+        wmiBI.cbStride = cbStride;
+        FailIf(ICERR_OK != ImageStrEncEncode(pIE->WMP.ctxSC, &wmiBI), WMP_errFail);
+    }
+    pIE->idxCurrentLine += cLine;
+
+Cleanup:
+    return err;
+}
+
+ERR PKImageEncode_EncodeContent_Term(PKImageEncode* pIE)
+{
+    ERR err = WMP_errSuccess;
+
+    FailIf(ICERR_OK != ImageStrEncTerm(pIE->WMP.ctxSC), WMP_errFail);
+
+Cleanup:
+    return err;
+}
+
+ERR PKImageEncode_EncodeContent(
+    PKImageEncode* pIE, 
+    PKPixelInfo PI,
+    U32 cLine,
+    U8* pbPixels,
+    U32 cbStride)
+{
+    ERR err = WMP_errSuccess;
+    size_t offPos = 0;
+
+    Call(pIE->pStream->GetPos(pIE->pStream, &offPos));
+    pIE->WMP.nOffImage = (Long)offPos;
+
+    Call(PKImageEncode_EncodeContent_Init(pIE, PI, cLine, pbPixels, cbStride));
+    Call(PKImageEncode_EncodeContent_Encode(pIE, cLine, pbPixels, cbStride));
+    Call(PKImageEncode_EncodeContent_Term(pIE));
+
+    Call(pIE->pStream->GetPos(pIE->pStream, &offPos));
+    pIE->WMP.nCbImage = (Long)offPos - pIE->WMP.nOffImage;
+
+Cleanup:
+    return err;
+}
+
+
+ERR PKImageEncode_EncodeAlpha_Init(
+    PKImageEncode* pIE, 
+    PKPixelInfo PI,
+    U32 cLine,
+    U8* pbPixels,
+    U32 cbStride)
+{
+    ERR err = WMP_errSuccess;
+
+    UNREFERENCED_PARAMETER( cLine );
+    UNREFERENCED_PARAMETER( pbPixels );
+    UNREFERENCED_PARAMETER( cbStride );
+
+    pIE->WMP.wmiI_Alpha = pIE->WMP.wmiI;
+
+    pIE->WMP.wmiI_Alpha.cWidth = pIE->uWidth;
+    pIE->WMP.wmiI_Alpha.cHeight = pIE->uHeight;
+    pIE->WMP.wmiI_Alpha.bdBitDepth = PI.bdBitDepth;
+    pIE->WMP.wmiI_Alpha.cBitsPerUnit = PI.cbitUnit;
+    pIE->WMP.wmiI_Alpha.bRGB = !(PI.grBit & PK_pixfmtBGR);
+    pIE->WMP.wmiI.oOrientation = pIE->WMP.oOrientation;
+//    pIE->WMP.wmiI_Alpha.cLeadingPadding += pIE->WMP.wmiSCP.cChannel;
+//    pIE->WMP.wmiI_Alpha.cLeadingPadding += PI.cChannel - 1;
+
+    switch (pIE->WMP.wmiI.bdBitDepth)
+    {
+        case BD_8:
+            pIE->WMP.wmiI_Alpha.cLeadingPadding += (pIE->WMP.wmiI.cBitsPerUnit >> 3) - 1;
+            break;
+        
+        case BD_16:
+        case BD_16S:
+        case BD_16F:
+            pIE->WMP.wmiI_Alpha.cLeadingPadding += (pIE->WMP.wmiI.cBitsPerUnit >> 3) / sizeof(U16) - 1;
+            break;
+        
+        case BD_32:
+        case BD_32S:
+        case BD_32F:
+            pIE->WMP.wmiI_Alpha.cLeadingPadding += (pIE->WMP.wmiI.cBitsPerUnit >> 3) / sizeof(float) - 1;
+            break;
+        
+        case BD_5:
+        case BD_10:
+        case BD_565:
+        default:
+            break;
+    }
+
+//    pIE->WMP.wmiSCP_Alpha.uAlphaMode = 1;
+
+
+    //assert(pIE->WMP.wmiI_Alpha.cfColorFormat == CF_RGB); // only RGBA is supported for now!
+    pIE->WMP.wmiI_Alpha.cfColorFormat = Y_ONLY;
+    
+    pIE->WMP.wmiSCP_Alpha.cfColorFormat = Y_ONLY;
+
+    pIE->idxCurrentLine = 0;
+    pIE->WMP.wmiSCP_Alpha.fMeasurePerf = TRUE;
+    FailIf(ICERR_OK != ImageStrEncInit(&pIE->WMP.wmiI_Alpha, &pIE->WMP.wmiSCP_Alpha, &pIE->WMP.ctxSC_Alpha), WMP_errFail);
+
+Cleanup:
+    return err;
+}
+
+ERR PKImageEncode_EncodeAlpha_Encode(
+    PKImageEncode* pIE, 
+    U32 cLine,
+    U8* pbPixels,
+    U32 cbStride)
+{
+    ERR err = WMP_errSuccess;
+    U32 i = 0;
+
+    //================================
+    for (i = 0; i < cLine; i += 16)
+    {
+        CWMImageBufferInfo wmiBI = { 0 };
+        wmiBI.pv = pbPixels + cbStride * i;
+        wmiBI.cLine = min(16, cLine - i);
+        wmiBI.cbStride = cbStride;
+        FailIf(ICERR_OK != ImageStrEncEncode(pIE->WMP.ctxSC_Alpha, &wmiBI), WMP_errFail);
+    }
+    pIE->idxCurrentLine += cLine;
+
+Cleanup:
+    return err;
+}
+
+ERR PKImageEncode_EncodeAlpha_Term(PKImageEncode* pIE)
+{
+    ERR err = WMP_errSuccess;
+
+    FailIf(ICERR_OK != ImageStrEncTerm(pIE->WMP.ctxSC_Alpha), WMP_errFail);
+
+Cleanup:
+    return err;
+}
+
+ERR PKImageEncode_EncodeAlpha(
+    PKImageEncode* pIE, 
+    PKPixelInfo PI,
+    U32 cLine,
+    U8* pbPixels,
+    U32 cbStride)
+{
+    ERR err = WMP_errSuccess;
+    size_t offPos = 0;
+
+    Call(pIE->pStream->GetPos(pIE->pStream, &offPos));
+    if ((offPos & 1) != 0)
+    {
+        // Make the mark even if it is odd by inserting a pad byte
+        char zero = 0;
+        Call(pIE->pStream->Write(pIE->pStream, &zero, 1));
+        offPos++;
+    }
+    pIE->WMP.nOffAlpha = (Long)offPos;
+
+    Call(PKImageEncode_EncodeAlpha_Init(pIE, PI, cLine, pbPixels, cbStride));
+    Call(PKImageEncode_EncodeAlpha_Encode(pIE, cLine, pbPixels, cbStride));
+    Call(PKImageEncode_EncodeAlpha_Term(pIE));
+
+    Call(pIE->pStream->GetPos(pIE->pStream, &offPos));
+    pIE->WMP.nCbAlpha = (Long)offPos - pIE->WMP.nOffAlpha;
+
+Cleanup:
+    return err;
+}
+
+
+
+static ERR SetMetadata(PKImageEncode *pIE, const U8 *pbMetadata, U32 cbMetadata, U8** pbSet, U32* pcbSet)
+{
+    ERR err = WMP_errSuccess;
+
+    // Fail if the caller called us after we've already written the header out
+    if (pIE->fHeaderDone)
+    {
+        assert(FALSE); // Message to programmer
+        err = WMP_errOutOfSequence;
+        goto Cleanup;
+    }
+
+    // Make a copy of the metadata
+    PKFree((void **) pbSet);
+    *pcbSet = 0;
+
+    Call(PKAlloc((void **) pbSet, cbMetadata));
+    memcpy(*pbSet, pbMetadata, cbMetadata);
+    *pcbSet = cbMetadata;
+
+Cleanup:
+    return err;
+}
+
+
+
+ERR PKImageEncode_SetColorContext_WMP(PKImageEncode *pIE,
+                                      const U8 *pbColorContext,
+                                      U32 cbColorContext)
+{
+    return SetMetadata(pIE, pbColorContext, cbColorContext, &pIE->pbColorContext, &pIE->cbColorContext);
+}
+
+
+
+ERR PKImageEncode_SetXMPMetadata_WMP(PKImageEncode *pIE, const U8 *pbXMPMetadata, U32 cbXMPMetadata)
+{   // same as the other Set's, but make sure dc:format is <dc:format>image/vnd.ms-photo</dc:format>
+    ERR err = WMP_errSuccess;
+    char* pbTemp = 0;
+    U32 cbTemp;
+    char* pszFormatBegin;
+    // const char* pszXMPMetadata = (const char*)pbXMPMetadata;
+    size_t cbBuffer;
+
+    // Fail if the caller called us after we've already written the header out
+    FailIf(pIE->fHeaderDone, WMP_errOutOfSequence);
+    
+    // Free any previously set XMP metadata
+    PKFree((void **) &pIE->pbXMPMetadata);
+    pIE->cbXMPMetadataByteCount = 0;
+
+    // allocate a block big enough for data passed in plus added trailing null plus added HD Photo dc:format
+    // there may already be a trailing null (but ps doesn't seem to)
+    // there may already be a dc:format we will replace with HD Photo's
+    // but anyway this block will be large enough guaranteed
+    cbBuffer = cbXMPMetadata + 1 + sizeof("<dc:format>") - 1 + sizeof("</dc:format>") - 1 + sizeof(szHDPhotoFormat) - 1;
+    Call(PKAlloc((void **) &pbTemp, cbBuffer));
+    memcpy(pbTemp, pbXMPMetadata, cbXMPMetadata); // Make a copy of the metadata
+    pbTemp[cbXMPMetadata] = '\0';
+    cbXMPMetadata = (U32)strlen(pbTemp);
+    pszFormatBegin = strstr(pbTemp, "<dc:format>");
+    if ( pszFormatBegin != 0 )
+    {
+        char* pszFormatEnd;
+        const char* pszLessThan;
+
+        pszFormatEnd = strstr(pszFormatBegin, "</dc:format>");
+        FailIf(pszFormatEnd == 0, WMP_errFail);
+        pszLessThan = strchr(pszFormatBegin + sizeof("<dc:format>") - 1, '<');
+        FailIf(pszLessThan != pszFormatEnd, WMP_errFail);
+        pszFormatEnd += sizeof("</dc:format>") - 1;
+
+        // photoshop doesn't put a trailing null, so we don't either
+        // hd and tiff don't put a trailing null, so we don't either
+        cbTemp = cbXMPMetadata - (U32) ( pszFormatEnd - pszFormatBegin ) + sizeof(szHDPhotoFormat) - 1;
+        assert(cbTemp <= cbBuffer);
+        FailIf(0 != STRCPY_SAFE(pszFormatBegin,
+            cbBuffer - (pszFormatBegin - pbTemp),
+            szHDPhotoFormat),
+            WMP_errBufferOverflow);
+        memcpy(pszFormatBegin + sizeof(szHDPhotoFormat) - 1, pbXMPMetadata + ( pszFormatEnd - pbTemp ),
+            cbXMPMetadata - ( pszFormatEnd - pbTemp ));
+    }
+    else
+    {
+        cbTemp = cbXMPMetadata;
+    }
+
+    pIE->pbXMPMetadata = (U8 *) pbTemp;
+    pIE->cbXMPMetadataByteCount = cbTemp;
+    return ( err );
+
+Cleanup:
+    PKFree((void **) &pbTemp);
+    pIE->cbXMPMetadataByteCount = 0;
+    return err;
+}
+
+
+
+ERR PKImageEncode_SetEXIFMetadata_WMP(PKImageEncode *pIE, const U8 *pbEXIFMetadata, U32 cbEXIFMetadata)
+{
+    return SetMetadata(pIE, pbEXIFMetadata, cbEXIFMetadata,
+        &pIE->pbEXIFMetadata, &pIE->cbEXIFMetadataByteCount);
+}
+
+
+
+ERR PKImageEncode_SetGPSInfoMetadata_WMP(PKImageEncode *pIE, const U8 *pbGPSInfoMetadata, U32 cbGPSInfoMetadata)
+{
+    return SetMetadata(pIE, pbGPSInfoMetadata, cbGPSInfoMetadata,
+        &pIE->pbGPSInfoMetadata, &pIE->cbGPSInfoMetadataByteCount);
+}
+
+
+
+ERR PKImageEncode_SetIPTCNAAMetadata_WMP(PKImageEncode *pIE, const U8 *pbIPTCNAAMetadata, U32 cbIPTCNAAMetadata)
+{
+    return SetMetadata(pIE, pbIPTCNAAMetadata, cbIPTCNAAMetadata,
+        &pIE->pbIPTCNAAMetadata, &pIE->cbIPTCNAAMetadataByteCount);
+}
+
+
+
+ERR PKImageEncode_SetPhotoshopMetadata_WMP(PKImageEncode *pIE, const U8 *pbPhotoshopMetadata, U32 cbPhotoshopMetadata)
+{
+    return SetMetadata(pIE, pbPhotoshopMetadata, cbPhotoshopMetadata,
+        &pIE->pbPhotoshopMetadata, &pIE->cbPhotoshopMetadataByteCount);
+}
+
+
+
+ERR PKImageEncode_SetDescriptiveMetadata_WMP(PKImageEncode *pIE, const DESCRIPTIVEMETADATA *pSrcMeta)
+{
+    ERR                     err = WMP_errSuccess;
+    DESCRIPTIVEMETADATA    *pDstMeta = &pIE->sDescMetadata;
+
+    // Fail if the caller called us after we've already written the header out
+    if (pIE->fHeaderDone)
+    {
+        assert(FALSE); // Message to programmer
+        FailIf(TRUE, WMP_errOutOfSequence);
+    }
+
+    // Make a copy of the descriptive metadata
+    Call(CopyDescMetadata(&pDstMeta->pvarImageDescription, pSrcMeta->pvarImageDescription));
+    Call(CopyDescMetadata(&pDstMeta->pvarCameraMake, pSrcMeta->pvarCameraMake));
+    Call(CopyDescMetadata(&pDstMeta->pvarCameraModel, pSrcMeta->pvarCameraModel));
+    Call(CopyDescMetadata(&pDstMeta->pvarSoftware, pSrcMeta->pvarSoftware));
+    Call(CopyDescMetadata(&pDstMeta->pvarDateTime, pSrcMeta->pvarDateTime));
+    Call(CopyDescMetadata(&pDstMeta->pvarArtist, pSrcMeta->pvarArtist));
+    Call(CopyDescMetadata(&pDstMeta->pvarCopyright, pSrcMeta->pvarCopyright));
+    Call(CopyDescMetadata(&pDstMeta->pvarRatingStars, pSrcMeta->pvarRatingStars));
+    Call(CopyDescMetadata(&pDstMeta->pvarRatingValue, pSrcMeta->pvarRatingValue));
+    Call(CopyDescMetadata(&pDstMeta->pvarCaption, pSrcMeta->pvarCaption));
+    Call(CopyDescMetadata(&pDstMeta->pvarDocumentName, pSrcMeta->pvarDocumentName));
+    Call(CopyDescMetadata(&pDstMeta->pvarPageName, pSrcMeta->pvarPageName));
+    Call(CopyDescMetadata(&pDstMeta->pvarPageNumber, pSrcMeta->pvarPageNumber));
+    Call(CopyDescMetadata(&pDstMeta->pvarHostComputer, pSrcMeta->pvarHostComputer));
+
+Cleanup:
+    return err;
+}
+
+
+
+ERR PKImageEncode_WritePixels_WMP(
+    PKImageEncode* pIE,
+    U32 cLine,
+    U8* pbPixels,
+    U32 cbStride)
+{
+    ERR err = WMP_errSuccess;
+    // U32 i = 0;
+    PKPixelInfo PI;
+
+    // Performing non-banded encode
+    assert(BANDEDENCSTATE_UNINITIALIZED == pIE->WMP.eBandedEncState);
+    pIE->WMP.eBandedEncState = BANDEDENCSTATE_NONBANDEDENCODE;
+
+    PI.pGUIDPixFmt = &pIE->guidPixFormat;
+    PixelFormatLookup(&PI, LOOKUP_FORWARD);
+    pIE->WMP.bHasAlpha = !!(PI.grBit & PK_pixfmtHasAlpha);
+
+    if (!pIE->fHeaderDone)
+    {
+        // write metadata
+        Call(WriteContainerPre(pIE));
+
+        pIE->fHeaderDone = !FALSE;
+    }
+
+/*    if (pIE->WMP.bHasAlpha && pIE->WMP.wmiSCP.uAlphaMode == 2){
+        pIE->WMP.wmiSCP_Alpha = pIE->WMP.wmiSCP;
+    }
+*/
+    Call(PKImageEncode_EncodeContent(pIE, PI, cLine, pbPixels, cbStride));
+    if (pIE->WMP.bHasAlpha && pIE->WMP.wmiSCP.uAlphaMode == 2){//planar alpha
+        Call(PKImageEncode_EncodeAlpha(pIE, PI, cLine, pbPixels, cbStride));
+    }
+    
+    Call(WriteContainerPost(pIE));
+
+Cleanup:
+    return err;
+}
+
+
+ERR PKImageEncode_WritePixelsBandedBegin_WMP(PKImageEncode* pIE, struct WMPStream *pPATempFile)
+{
+    ERR err = WMP_errSuccess;
+
+    // Just make sure that we are in the correct state to begin a banded decode
+    assert(BANDEDENCSTATE_UNINITIALIZED == pIE->WMP.eBandedEncState);
+    pIE->WMP.eBandedEncState = BANDEDENCSTATE_INIT;
+
+    // Save the planar alpha tempfile for future use
+    pIE->WMP.pPATempFile = pPATempFile;
+
+//Cleanup:
+    return err;
+}
+
+ERR PKImageEncode_WritePixelsBanded_WMP(PKImageEncode* pIE, U32 cLine, U8* pbPixels, U32 cbStride, Bool fLastCall)
+{
+    ERR err = WMP_errSuccess;
+    PKPixelInfo PI = {0};
+    Bool fPI = FALSE;
+    BANDEDENCSTATE eEncStateOrig = pIE->WMP.eBandedEncState;
+    struct WMPStream *pPATempFile = pIE->WMP.pPATempFile;
+
+    // Unless this is the last call, reject inputs which are not multiples of 16
+    FailIf(!fLastCall && 0 != cLine % 16, WMP_errMustBeMultipleOf16LinesUntilLastCall);
+
+    if (!pIE->fHeaderDone || BANDEDENCSTATE_INIT == pIE->WMP.eBandedEncState)
+    {
+        PI.pGUIDPixFmt = &pIE->guidPixFormat;
+        PixelFormatLookup(&PI, LOOKUP_FORWARD);
+        pIE->WMP.bHasAlpha = !!(PI.grBit & PK_pixfmtHasAlpha);
+        fPI = TRUE;
+
+        // Check if this is planar alpha: banded encode requires temp file
+        if (pIE->WMP.bHasAlpha && pIE->WMP.wmiSCP.uAlphaMode == 2)
+        {
+            FailIf(NULL == pPATempFile, WMP_errPlanarAlphaBandedEncRequiresTempFile);
+        }
+    }
+
+    if (!pIE->fHeaderDone)
+    {
+        // write metadata
+        assert(fPI);
+        Call(WriteContainerPre(pIE));
+        pIE->fHeaderDone = !FALSE;
+    }
+
+    if (BANDEDENCSTATE_INIT == pIE->WMP.eBandedEncState)
+    {
+        // Record start of main content for future call to WriteContainerPost
+        size_t offPos;
+        Call(pIE->pStream->GetPos(pIE->pStream, &offPos));
+        pIE->WMP.nOffImage = (Long)offPos;
+
+        assert(fPI);
+        Call(PKImageEncode_EncodeContent_Init(pIE, PI, cLine, pbPixels, cbStride));
+        pIE->WMP.eBandedEncState = BANDEDENCSTATE_ENCODING;
+    }
+
+    Call(PKImageEncode_EncodeContent_Encode(pIE, cLine, pbPixels, cbStride));
+    if (pIE->WMP.bHasAlpha && pIE->WMP.wmiSCP.uAlphaMode == 2)
+    {
+        //planar alpha
+        if (BANDEDENCSTATE_INIT == eEncStateOrig)
+        {
+            size_t  offStart;
+
+            // We assume the following which allows us to avoid saving state
+            Call(pPATempFile->GetPos(pPATempFile, &offStart));
+            assert(0 == offStart);
+            assert(pIE->WMP.wmiSCP_Alpha.pWStream == pIE->WMP.wmiSCP.pWStream);
+
+            // For planar alpha, we write the file to a temp file
+            pIE->WMP.wmiSCP_Alpha.pWStream = pPATempFile;
+            Call(PKImageEncode_EncodeAlpha_Init(pIE, PI, cLine, pbPixels, cbStride));
+        }
+
+        Call(PKImageEncode_EncodeAlpha_Encode(pIE, cLine, pbPixels, cbStride));
+    }
+
+Cleanup:
+    return err;
+}
+
+ERR PKImageEncode_WritePixelsBandedEnd_WMP(PKImageEncode* pIE)
+{
+    ERR err = WMP_errSuccess;
+    struct WMPStream *pMainStream = pIE->WMP.wmiSCP.pWStream;
+    size_t offAlpha;
+
+    assert(BANDEDENCSTATE_ENCODING == pIE->WMP.eBandedEncState);
+
+    // Finish off main content, update its length ptr for WriteContainerPost
+    Call(PKImageEncode_EncodeContent_Term(pIE));
+    Call(pMainStream->GetPos(pIE->pStream, &offAlpha));
+    pIE->WMP.nCbImage = (Long)offAlpha - pIE->WMP.nOffImage;
+
+    if (pIE->WMP.bHasAlpha && pIE->WMP.wmiSCP.uAlphaMode == 2)
+    {
+        size_t cbAlpha;
+        size_t cbBytesCopied;
+        struct WMPStream *pAlphaStream = pIE->WMP.wmiSCP_Alpha.pWStream;
+
+        assert(pAlphaStream != pMainStream); // Otherwise we didn't use a temp file
+
+        // Close it up - this causes write to temp file
+        Call(PKImageEncode_EncodeAlpha_Term(pIE));
+
+        // Calculate size of alpha bitstream and its new offset
+        Call(pAlphaStream->GetPos(pAlphaStream, &cbAlpha));
+
+        // Copy alpha bitstream to end of main stream
+        cbBytesCopied = 0;
+        Call(pAlphaStream->SetPos(pAlphaStream, 0));
+        while (cbBytesCopied < cbAlpha)
+        {
+            char rgbBuf[TEMPFILE_COPYBUF_SIZE];
+            size_t cbCopy;
+
+            cbCopy = min(sizeof(rgbBuf), cbAlpha - cbBytesCopied);
+            Call(pAlphaStream->Read(pAlphaStream, rgbBuf, cbCopy));
+            Call(pMainStream->Write(pMainStream, rgbBuf, cbCopy));
+
+            cbBytesCopied += cbCopy;
+        }
+        assert(cbBytesCopied == cbAlpha);
+
+        // Update alpha offset/length for WriteContainerPost
+        pIE->WMP.nOffAlpha = (Long)offAlpha;
+        pIE->WMP.nCbAlpha = (Long)cbAlpha;
+    }
+
+    Call(WriteContainerPost(pIE));
+
+Cleanup:
+    return err;
+}
+
+
+ERR PKImageEncode_Transcode_WMP(
+    PKImageEncode* pIE,
+    PKImageDecode* pID,
+    CWMTranscodingParam* pParam)
+{
+    ERR err = WMP_errSuccess;
+    Float fResX = 0, fResY = 0;
+    PKPixelFormatGUID pixGUID = {0};
+    CWMTranscodingParam tcParamAlpha;
+    size_t offPos = 0;
+    Bool fPlanarAlpha;
+    PKPixelInfo PI;
+
+    struct WMPStream* pWSDec = NULL;
+    struct WMPStream* pWSEnc= pIE->pStream;
+
+    // pass through metadata
+    Call(pID->GetPixelFormat(pID, &pixGUID));
+    Call(pIE->SetPixelFormat(pIE, pixGUID));
+
+    Call(pIE->SetSize(pIE, (I32)pParam->cWidth, (I32)pParam->cHeight));
+
+    Call(pID->GetResolution(pID, &fResX, &fResY));
+    Call(pIE->SetResolution(pIE, fResX, fResY));
+
+    PI.pGUIDPixFmt = &pIE->guidPixFormat;
+    PixelFormatLookup(&PI, LOOKUP_FORWARD);
+    pIE->WMP.bHasAlpha = !!(PI.grBit & PK_pixfmtHasAlpha) && (2 == pParam->uAlphaMode);
+    assert(0 == pIE->WMP.bHasAlpha || (pParam->uAlphaMode == 2)); // Decode alpha mode does not match encode alpha mode!
+
+    // Check for any situations where transcoder is being asked to convert alpha - we can't do this
+    // NOTE: Decoder's bHasAlpha parameter really means, "has PLANAR alpha"
+    PI.pGUIDPixFmt = &pixGUID;
+    PixelFormatLookup(&PI, LOOKUP_FORWARD);
+    FailIf(0 == (PI.grBit & PK_pixfmtHasAlpha) && pParam->uAlphaMode != 0,
+        WMP_errAlphaModeCannotBeTranscoded); // Destination is planar/interleaved, src has no alpha
+    FailIf(!!(PI.grBit & PK_pixfmtHasAlpha) && 2 == pParam->uAlphaMode &&
+        FALSE == pID->WMP.bHasAlpha, WMP_errAlphaModeCannotBeTranscoded);  // Destination is planar, src is interleaved
+    FailIf(!!(PI.grBit & PK_pixfmtHasAlpha) && 3 == pParam->uAlphaMode &&
+        pID->WMP.bHasAlpha, WMP_errAlphaModeCannotBeTranscoded);  // Destination is interleaved, src is planar
+    assert(/*pParam->uAlphaMode >= 0 &&*/ pParam->uAlphaMode <= 3); // All the above statements make this assumption
+
+    fPlanarAlpha = pIE->WMP.bHasAlpha && (2 == pParam->uAlphaMode);
+
+    // write matadata
+    Call(WriteContainerPre(pIE));
+
+    // Copy transcoding params for alpha (codec changes the struct)
+    if (fPlanarAlpha)
+        tcParamAlpha = *pParam;
+
+    // write compressed bitstream
+    Call(pID->GetRawStream(pID, &pWSDec));
+
+    FailIf(ICERR_OK != WMPhotoTranscode(pWSDec, pWSEnc, pParam), WMP_errFail);
+    Call(pIE->pStream->GetPos(pIE->pStream, &offPos));
+    pIE->WMP.nCbImage = (Long)offPos - pIE->WMP.nOffImage;
+
+    if (fPlanarAlpha)
+    {
+        pIE->WMP.nOffAlpha = (Long)offPos;
+
+        // Cue the stream to alpha block
+        assert(pID->WMP.wmiDEMisc.uAlphaOffset > 0);
+        Call(pWSDec->SetPos(pWSDec, pID->WMP.wmiDEMisc.uAlphaOffset));
+
+        FailIf(ICERR_OK != WMPhotoTranscode(pWSDec, pWSEnc, &tcParamAlpha), WMP_errFail);
+        Call(pIE->pStream->GetPos(pIE->pStream, &offPos));
+        pIE->WMP.nCbAlpha = (Long)offPos - pIE->WMP.nOffAlpha;
+    }
+
+    // fixup matadata
+    Call(WriteContainerPost(pIE));
+
+Cleanup:
+    return err;
+}
+
+ERR PKImageEncode_CreateNewFrame_WMP(
+    PKImageEncode* pIE,
+    void* pvParam,
+    size_t cbParam)
+{
+    ERR err = WMP_errSuccess;
+
+    UNREFERENCED_PARAMETER( pIE );
+    UNREFERENCED_PARAMETER( pvParam );
+    UNREFERENCED_PARAMETER( cbParam );
+
+    Call(WMP_errNotYetImplemented);
+    
+Cleanup:
+    return err;
+}
+
+ERR PKImageEncode_Release_WMP(
+    PKImageEncode** ppIE)
+{
+    ERR err = WMP_errSuccess;
+
+    PKImageEncode *pIE = *ppIE;
+    pIE->pStream->Close(&pIE->pStream);
+
+    PKFree((void **) &pIE->pbColorContext);
+    pIE->cbColorContext = 0;
+    PKFree((void **) &pIE->pbXMPMetadata);
+    pIE->cbXMPMetadataByteCount = 0;
+    PKFree((void **) &pIE->pbEXIFMetadata);
+    pIE->cbEXIFMetadataByteCount = 0;
+    PKFree((void **) &pIE->pbGPSInfoMetadata);
+    pIE->cbGPSInfoMetadataByteCount = 0;
+    PKFree((void **) &pIE->pbIPTCNAAMetadata);
+    pIE->cbIPTCNAAMetadataByteCount = 0;
+    PKFree((void **) &pIE->pbPhotoshopMetadata);
+    pIE->cbPhotoshopMetadataByteCount = 0;
+
+    // Free descriptive metadata
+    FreeDescMetadata(&pIE->sDescMetadata.pvarImageDescription);
+    FreeDescMetadata(&pIE->sDescMetadata.pvarCameraMake);
+    FreeDescMetadata(&pIE->sDescMetadata.pvarCameraModel);
+    FreeDescMetadata(&pIE->sDescMetadata.pvarSoftware);
+    FreeDescMetadata(&pIE->sDescMetadata.pvarDateTime);
+    FreeDescMetadata(&pIE->sDescMetadata.pvarArtist);
+    FreeDescMetadata(&pIE->sDescMetadata.pvarCopyright);
+    FreeDescMetadata(&pIE->sDescMetadata.pvarRatingStars);
+    FreeDescMetadata(&pIE->sDescMetadata.pvarRatingValue);
+    FreeDescMetadata(&pIE->sDescMetadata.pvarCaption);
+    FreeDescMetadata(&pIE->sDescMetadata.pvarDocumentName);
+    FreeDescMetadata(&pIE->sDescMetadata.pvarPageName);
+    FreeDescMetadata(&pIE->sDescMetadata.pvarPageNumber);
+    FreeDescMetadata(&pIE->sDescMetadata.pvarHostComputer);
+
+    Call(PKFree((void **) ppIE));
+
+Cleanup:
+    return err;
+}
+
+//----------------------------------------------------------------
+ERR PKImageEncode_Create_WMP(PKImageEncode** ppIE)
+{
+    ERR err = WMP_errSuccess;
+
+    PKImageEncode* pIE = NULL;
+
+    Call(PKImageEncode_Create(ppIE));
+
+    pIE = *ppIE;
+    pIE->Initialize = PKImageEncode_Initialize_WMP;
+    pIE->Terminate = PKImageEncode_Terminate_WMP;
+    pIE->SetColorContext = PKImageEncode_SetColorContext_WMP;
+    pIE->SetDescriptiveMetadata = PKImageEncode_SetDescriptiveMetadata_WMP;
+    pIE->WritePixels = PKImageEncode_WritePixels_WMP;
+
+    pIE->WritePixelsBandedBegin = PKImageEncode_WritePixelsBandedBegin_WMP;
+    pIE->WritePixelsBanded = PKImageEncode_WritePixelsBanded_WMP;
+    pIE->WritePixelsBandedEnd = PKImageEncode_WritePixelsBandedEnd_WMP;
+
+    pIE->Transcode = PKImageEncode_Transcode_WMP;
+    pIE->CreateNewFrame = PKImageEncode_CreateNewFrame_WMP;
+    pIE->Release = PKImageEncode_Release_WMP;
+	pIE->bWMP = TRUE; 
+
+Cleanup:
+    return err;
+}
+
+
+//================================================================
+// PKImageDecode_WMP
+//================================================================
+ERR ParsePFDEntry(
+    PKImageDecode* pID,
+    U16 uTag,
+    U16 uType,
+    U32 uCount,
+    U32 uValue)
+{
+    ERR err = WMP_errSuccess;
+    ERR errTmp = WMP_errSuccess;
+    PKPixelInfo PI;
+    struct WMPStream* pWS = pID->pStream;
+    // size_t offPos = 0;
+
+    union uf{
+        U32 uVal;
+        Float fVal;
+    }ufValue = {0};
+
+    //================================
+    switch (uTag)
+    {
+        case WMP_tagPixelFormat:
+        {
+            unsigned char *pGuid = (unsigned char *) &pID->guidPixFormat;
+            /** following code is endian-agnostic **/
+            Call(GetULong(pWS, uValue, (U32 *)pGuid));
+            Call(GetUShort(pWS, uValue + 4, (unsigned short *)(pGuid + 4)));
+            Call(GetUShort(pWS, uValue + 6, (unsigned short *)(pGuid + 6)));
+            Call(pWS->Read(pWS, pGuid + 8, 8));
+                
+            PI.pGUIDPixFmt = &pID->guidPixFormat;
+            PixelFormatLookup(&PI, LOOKUP_FORWARD);
+
+            pID->WMP.bHasAlpha = !!(PI.grBit & PK_pixfmtHasAlpha);
+            pID->WMP.wmiI.cBitsPerUnit = PI.cbitUnit;
+            pID->WMP.wmiI.bRGB = !(PI.grBit & PK_pixfmtBGR);
+
+            break;
+        }
+
+        case WMP_tagTransformation:
+            FailIf(1 != uCount, WMP_errUnsupportedFormat);
+            assert(uValue < O_MAX);
+            pID->WMP.fOrientationFromContainer = TRUE;
+            pID->WMP.oOrientationFromContainer = uValue;
+            break;
+
+        case WMP_tagImageWidth:
+            FailIf(0 == uValue, WMP_errUnsupportedFormat);
+            break;
+
+        case WMP_tagImageHeight:
+            FailIf(0 == uValue, WMP_errUnsupportedFormat);
+            break;
+
+        case WMP_tagImageOffset:
+            FailIf(1 != uCount, WMP_errUnsupportedFormat);
+            pID->WMP.wmiDEMisc.uImageOffset = uValue;
+            break;
+
+        case WMP_tagImageByteCount:
+            FailIf(1 != uCount, WMP_errUnsupportedFormat);
+            pID->WMP.wmiDEMisc.uImageByteCount = uValue;
+            break;
+
+        case WMP_tagAlphaOffset:
+            FailIf(1 != uCount, WMP_errUnsupportedFormat);
+            pID->WMP.wmiDEMisc.uAlphaOffset = uValue;
+            break;
+
+        case WMP_tagAlphaByteCount:
+            FailIf(1 != uCount, WMP_errUnsupportedFormat);
+            pID->WMP.wmiDEMisc.uAlphaByteCount = uValue;
+            break;
+
+        case WMP_tagWidthResolution:
+            FailIf(1 != uCount, WMP_errUnsupportedFormat);
+            ufValue.uVal = uValue; 
+            pID->fResX = ufValue.fVal;
+            break;
+
+        case WMP_tagHeightResolution:
+            FailIf(1 != uCount, WMP_errUnsupportedFormat);
+            ufValue.uVal = uValue; 
+            pID->fResY = ufValue.fVal;
+            break;
+
+        case WMP_tagIccProfile:
+            pID->WMP.wmiDEMisc.uColorProfileByteCount = uCount;
+            pID->WMP.wmiDEMisc.uColorProfileOffset = uValue;
+            break;
+
+        case WMP_tagXMPMetadata:
+            pID->WMP.wmiDEMisc.uXMPMetadataByteCount = uCount;
+            pID->WMP.wmiDEMisc.uXMPMetadataOffset = uValue;
+            break;
+
+        case WMP_tagEXIFMetadata:
+            pID->WMP.wmiDEMisc.uEXIFMetadataOffset = uValue;
+            CallIgnoreError(errTmp, StreamCalcIFDSize(pWS, uValue, &pID->WMP.wmiDEMisc.uEXIFMetadataByteCount));
+            break;
+
+        case WMP_tagGPSInfoMetadata:
+            pID->WMP.wmiDEMisc.uGPSInfoMetadataOffset = uValue;
+            CallIgnoreError(errTmp, StreamCalcIFDSize(pWS, uValue, &pID->WMP.wmiDEMisc.uGPSInfoMetadataByteCount));
+            break;
+
+        case WMP_tagIPTCNAAMetadata:
+            pID->WMP.wmiDEMisc.uIPTCNAAMetadataByteCount = uCount;
+            pID->WMP.wmiDEMisc.uIPTCNAAMetadataOffset = uValue;
+            break;
+
+        case WMP_tagPhotoshopMetadata:
+            pID->WMP.wmiDEMisc.uPhotoshopMetadataByteCount = uCount;
+            pID->WMP.wmiDEMisc.uPhotoshopMetadataOffset = uValue;
+            break;
+
+        case WMP_tagCompression:
+        case WMP_tagImageType:
+        case WMP_tagImageDataDiscard:
+        case WMP_tagAlphaDataDiscard:
+            break;
+
+        // Descriptive Metadata
+        case WMP_tagImageDescription:
+            CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue,
+                &pID->WMP.sDescMetadata.pvarImageDescription));
+            assert(DPKVT_LPSTR == pID->WMP.sDescMetadata.pvarImageDescription.vt);
+            break;
+
+        case WMP_tagCameraMake:
+            CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue,
+                &pID->WMP.sDescMetadata.pvarCameraMake));
+            assert(DPKVT_LPSTR == pID->WMP.sDescMetadata.pvarCameraMake.vt);
+            break;
+
+        case WMP_tagCameraModel:
+            CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue,
+                &pID->WMP.sDescMetadata.pvarCameraModel));
+            assert(DPKVT_LPSTR == pID->WMP.sDescMetadata.pvarCameraModel.vt);
+            break;
+
+        case WMP_tagSoftware:
+            CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue,
+                &pID->WMP.sDescMetadata.pvarSoftware));
+            assert(DPKVT_LPSTR == pID->WMP.sDescMetadata.pvarSoftware.vt);
+            break;
+
+        case WMP_tagDateTime:
+            CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue,
+                &pID->WMP.sDescMetadata.pvarDateTime));
+            assert(DPKVT_LPSTR == pID->WMP.sDescMetadata.pvarDateTime.vt);
+            break;
+
+        case WMP_tagArtist:
+            CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue,
+                &pID->WMP.sDescMetadata.pvarArtist));
+            assert(DPKVT_LPSTR == pID->WMP.sDescMetadata.pvarArtist.vt);
+            break;
+
+        case WMP_tagCopyright:
+            CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue,
+                &pID->WMP.sDescMetadata.pvarCopyright));
+            assert(DPKVT_LPSTR == pID->WMP.sDescMetadata.pvarCopyright.vt);
+            break;
+
+        case WMP_tagRatingStars:
+            CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue,
+                &pID->WMP.sDescMetadata.pvarRatingStars));
+            assert(DPKVT_UI2 == pID->WMP.sDescMetadata.pvarRatingStars.vt);
+            break;
+
+        case WMP_tagRatingValue:
+            CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue,
+                &pID->WMP.sDescMetadata.pvarRatingValue));
+            assert(DPKVT_UI2 == pID->WMP.sDescMetadata.pvarRatingValue.vt);
+            break;
+
+        case WMP_tagCaption:
+            CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue,
+                &pID->WMP.sDescMetadata.pvarCaption));
+            assert((DPKVT_BYREF | DPKVT_UI1) == pID->WMP.sDescMetadata.pvarCaption.vt);
+
+            // Change type from C-style byte array to LPWSTR
+            assert((U8*)pID->WMP.sDescMetadata.pvarCaption.VT.pwszVal ==
+                pID->WMP.sDescMetadata.pvarCaption.VT.pbVal);
+            assert(0 == pID->WMP.sDescMetadata.pvarCaption.VT.pwszVal[uCount/sizeof(U16) - 1]); // Confirm null-term
+            //  make sure null term (ReadPropvar allocated enough space for this)
+            pID->WMP.sDescMetadata.pvarCaption.VT.pwszVal[uCount/sizeof(U16)] = 0;
+            pID->WMP.sDescMetadata.pvarCaption.vt = DPKVT_LPWSTR;
+            break;
+
+        case WMP_tagDocumentName:
+            CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue,
+                &pID->WMP.sDescMetadata.pvarDocumentName));
+            assert(DPKVT_LPSTR == pID->WMP.sDescMetadata.pvarDocumentName.vt);
+            break;
+
+        case WMP_tagPageName:
+            CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue,
+                &pID->WMP.sDescMetadata.pvarPageName));
+            assert(DPKVT_LPSTR == pID->WMP.sDescMetadata.pvarPageName.vt);
+            break;
+
+        case WMP_tagPageNumber:
+            CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue,
+                &pID->WMP.sDescMetadata.pvarPageNumber));
+            assert(DPKVT_UI4 == pID->WMP.sDescMetadata.pvarPageNumber.vt);
+            break;
+
+        case WMP_tagHostComputer:
+            CallIgnoreError(errTmp, ReadPropvar(pWS, uType, uCount, uValue,
+                &pID->WMP.sDescMetadata.pvarHostComputer));
+            assert(DPKVT_LPSTR == pID->WMP.sDescMetadata.pvarHostComputer.vt);
+            break;
+
+        default:
+            fprintf(stderr, "Unrecognized WMPTag: %d(%#x), %d, %d, %#x" CRLF,
+                (int)uTag, (int)uTag, (int)uType, (int)uCount, (int)uValue);
+            break;
+    }
+
+Cleanup:
+    return err;
+}
+
+ERR ParsePFD(
+    PKImageDecode* pID,
+    size_t offPos,
+    U16 cEntry)
+{
+    ERR err = WMP_errSuccess;
+    struct WMPStream* pWS = pID->pStream;
+    U16 i = 0;
+
+    for (i = 0; i < cEntry; ++i)
+    {
+        U16 uTag = 0;
+        U16 uType = 0;
+        U32 uCount = 0;
+        U32 uValue = 0;
+
+        Call(GetUShort(pWS, offPos, &uTag)); offPos += 2;
+        Call(GetUShort(pWS, offPos, &uType)); offPos += 2;
+        Call(GetULong(pWS, offPos, &uCount)); offPos += 4;
+        Call(GetULong(pWS, offPos, &uValue)); offPos += 4;
+
+        Call(ParsePFDEntry(pID, uTag, uType, uCount, uValue)); 
+    }
+
+    pID->WMP.bHasAlpha = ((pID->WMP.bHasAlpha) && (pID->WMP.wmiDEMisc.uAlphaOffset != 0) && (pID->WMP.wmiDEMisc.uAlphaByteCount != 0));//has planar alpha
+
+Cleanup:
+    return err;
+}
+
+ERR ReadContainer(
+    PKImageDecode* pID)
+{
+    ERR err = WMP_errSuccess;
+
+    struct WMPStream* pWS = pID->pStream;
+    size_t offPos = 0;
+
+    char szSig[2] = {0};
+    U16 uWmpID = 0;
+    U32 offPFD = 0;
+    U16 cPFDEntry = 0;
+    U8 bVersion;
+    
+    //================================
+    Call(pWS->GetPos(pWS, &offPos));
+    FailIf(0 != offPos, WMP_errUnsupportedFormat);
+
+    //================================
+    // Header
+    Call(pWS->Read(pWS, szSig, sizeof(szSig))); offPos += 2;
+    FailIf(szSig != strstr(szSig, "II"), WMP_errUnsupportedFormat);
+
+    Call(GetUShort(pWS, offPos, &uWmpID)); offPos += 2;
+    FailIf(WMP_valWMPhotoID != (0x00FF & uWmpID), WMP_errUnsupportedFormat);
+
+    // We accept version 00 and version 01 bitstreams - all others rejected
+    bVersion = (0xFF00 & uWmpID) >> 8;
+    FailIf(bVersion != 0 && bVersion != 1, WMP_errUnsupportedFormat);
+
+    Call(GetULong(pWS, offPos, &offPFD)); offPos += 4;
+
+    //================================
+    // PFD
+    offPos = (size_t)offPFD;
+    Call(GetUShort(pWS, offPos, &cPFDEntry)); offPos += 2;
+    FailIf(0 == cPFDEntry || USHRT_MAX == cPFDEntry, WMP_errUnsupportedFormat);
+    Call(ParsePFD(pID, offPos, cPFDEntry));
+
+    //================================
+    Call(pWS->SetPos(pWS, pID->WMP.wmiDEMisc.uImageOffset));
+
+Cleanup:
+    return err;
+}
+
+
+//================================================
+ERR PKImageDecode_Initialize_WMP(
+    PKImageDecode* pID,
+    struct WMPStream* pWS)
+{
+    ERR err = WMP_errSuccess;
+
+    CWMImageInfo* pII = NULL;
+
+    //================================
+    Call(PKImageDecode_Initialize(pID, pWS));
+
+    //================================
+    Call(ReadContainer(pID));
+
+    //================================
+    pID->WMP.wmiSCP.pWStream = pWS;
+    pID->WMP.DecoderCurrMBRow = 0;
+    pID->WMP.cLinesDecoded = 0;
+    pID->WMP.cLinesCropped = 0;
+    pID->WMP.fFirstNonZeroDecode = FALSE;
+
+    FailIf(ICERR_OK != ImageStrDecGetInfo(&pID->WMP.wmiI, &pID->WMP.wmiSCP), WMP_errFail);
+    assert(Y_ONLY <= pID->WMP.wmiSCP.cfColorFormat && pID->WMP.wmiSCP.cfColorFormat < CFT_MAX);
+    assert(BD_SHORT == pID->WMP.wmiSCP.bdBitDepth || BD_LONG == pID->WMP.wmiSCP.bdBitDepth);
+
+    // If HD Photo container provided an orientation, this should override bitstream orientation
+    // If container did NOT provide an orientation, force O_NONE. This is to be consistent with
+    // Vista behaviour, which is to ignore bitstream orientation (only looks at container).
+    if (pID->WMP.fOrientationFromContainer)
+    {
+        pID->WMP.wmiI.oOrientation = pID->WMP.oOrientationFromContainer;
+    }
+    else
+    {
+        // Force to O_NONE to match Vista decode behaviour
+        pID->WMP.wmiI.oOrientation = O_NONE;
+    }
+
+    pII = &pID->WMP.wmiI;
+    pID->uWidth = (U32)pII->cWidth;
+    pID->uHeight = (U32)pII->cHeight;
+
+Cleanup:
+    return err;
+}
+
+
+ERR PKImageDecode_GetSize_WMP(
+    PKImageDecode* pID,
+    I32* piWidth,
+    I32* piHeight)
+{
+    if (pID->WMP.wmiI.oOrientation >= O_RCW)
+    {
+        *piWidth = (I32)pID->uHeight;
+        *piHeight = (I32)pID->uWidth;
+    }
+    else
+    {
+        *piWidth = (I32)pID->uWidth;
+        *piHeight = (I32)pID->uHeight;
+    }
+    return WMP_errSuccess;
+}
+
+
+ERR PKImageDecode_GetRawStream_WMP(
+    PKImageDecode* pID,
+    struct WMPStream** ppWS)
+{
+    ERR err = WMP_errSuccess;
+    struct WMPStream* pWS = pID->pStream;
+
+    *ppWS = NULL;
+    Call(pWS->SetPos(pWS, pID->WMP.wmiDEMisc.uImageOffset));
+    *ppWS = pWS;
+
+Cleanup:
+    return err;
+}
+
+ERR PKImageDecode_Copy_WMP(
+    PKImageDecode* pID,
+    const PKRect* pRect,
+    U8* pb,
+    U32 cbStride)
+{
+    ERR err = WMP_errSuccess;
+    U32 cThumbnailScale;
+    U32 linesperMBRow;
+    CWMImageBufferInfo wmiBI = { 0 };
+#ifdef REENTRANT_MODE
+    U8 *pbLowMemAdj = NULL;
+    U32 i, cMBRow;
+    U32 cMBRowStart;
+#endif // REENTRANT_MODE
+    struct WMPStream* pWS = pID->pStream;
+    U8 tempAlphaMode = 0;
+    wmiBI.pv = pb;
+    wmiBI.cLine = pRect->Height;
+    wmiBI.cbStride = cbStride;
+#ifdef REENTRANT_MODE
+    // In REENTRANT_MODE, we allow rectangles with any top left corner (not just (0,0))
+#else
+    FailIf(0 != pRect->X, WMP_errInvalidParameter);
+    FailIf(0 != pRect->Y, WMP_errInvalidParameter);
+#endif // REENTRANT_MODE
+
+    cThumbnailScale = 1;
+	if (pID->WMP.wmiI.cThumbnailWidth > 0)
+	{
+		while(cThumbnailScale * pID->WMP.wmiI.cThumbnailWidth < pID->uWidth)
+			cThumbnailScale <<= 1;
+	}
+    // note the following implementation can't handle fractional linesperMBRow limiting
+    // us to >= 1/256 thumbnail which is unfortunate, but all the PS plugin needs is 1/256
+    // and I didn't care to get into floating point or a bunch of conditional tests or
+    // other rewrite for a case not needed nor tested by PS plugin.  sorry.
+    linesperMBRow = 16 / cThumbnailScale;
+
+#ifdef REENTRANT_MODE
+    if (0 == pID->WMP.DecoderCurrMBRow) 
+    {
+#endif // REENTRANT_MODE
+    // Set the fPaddedUserBuffer if the following conditions are met
+    if (0 == ((size_t)pb % 128) &&    // Frame buffer is aligned to 128-byte boundary
+        0 == (pRect->Height % 16) &&        // Horizontal resolution is multiple of 16
+        0 == (pRect->Width % 16) &&        // Vertical resolution is multiple of 16
+        0 == (cbStride % 128))              // Stride is a multiple of 128 bytes
+    {
+        pID->WMP.wmiI.fPaddedUserBuffer = TRUE;
+        // Note that there are additional conditions in strdec_x86.c's strDecOpt
+        // which could prevent optimization from being engaged
+    }
+#ifdef REENTRANT_MODE
+    }
+#endif // REENTRANT_MODE
+    //if(pID->WMP.wmiSCP.uAlphaMode != 1)
+    if((!pID->WMP.bHasAlpha) || (pID->WMP.wmiSCP.uAlphaMode != 1))
+    {
+        if(pID->WMP.bHasAlpha)//planar alpha
+        {
+            tempAlphaMode = pID->WMP.wmiSCP.uAlphaMode;
+            pID->WMP.wmiSCP.uAlphaMode = 0;
+        }
+        pID->WMP.wmiSCP.fMeasurePerf = TRUE;
+#ifdef REENTRANT_MODE
+        if (0 == pID->WMP.DecoderCurrMBRow) 
+        {
+            Call(pID->WMP.wmiSCP.pWStream->GetPos(pID->WMP.wmiSCP.pWStream, &(pID->WMP.cMarker)));
+            FailIf(ICERR_OK != ImageStrDecInit(&pID->WMP.wmiI, &pID->WMP.wmiSCP, &pID->WMP.ctxSC), WMP_errFail);
+        }
+        // Re-entrant mode incurs 1 MBR delay, so to get 0th MBR, we have to ask for 1st MBR
+        cMBRow = ((U32) pID->WMP.cLinesCropped + pRect->Y + pRect->Height +          
+            (pRect->Y + pRect->Height >= (I32) pID->WMP.wmiI.cROIHeight ? linesperMBRow - 1 : 0)) / // round up if last MBR
+            linesperMBRow + 1;
+        cMBRowStart = ((U32) pID->WMP.cLinesCropped + pRect->Y) / linesperMBRow + 1;
+        // if current request starts before current state, then rewind.
+        if (cMBRowStart < pID->WMP.DecoderCurrMBRow) 
+        {
+            pID->WMP.DecoderCurrMBRow = 0;
+            pID->WMP.cLinesDecoded = 0;
+            pID->WMP.cLinesCropped = 0;
+            pID->WMP.fFirstNonZeroDecode = FALSE;
+            FailIf(ICERR_OK != ImageStrDecTerm(pID->WMP.ctxSC), WMP_errFail);   
+            Call(pID->WMP.wmiSCP.pWStream->SetPos(pID->WMP.wmiSCP.pWStream, pID->WMP.cMarker));
+            FailIf(ICERR_OK != ImageStrDecInit(&pID->WMP.wmiI, &pID->WMP.wmiSCP, &pID->WMP.ctxSC), WMP_errFail);
+        }
+
+        // In "Low Memory mode", we don't have full frame buffer. We therefore cannot rotate the image.
+        // We can flip H, V and HV, but no rotations.
+        FailIf(pID->WMP.wmiI.oOrientation >= O_RCW, WMP_errFail);
+
+        // In low-memory mode, the full frame buffer is unavailable. This doesn't seem to
+        // matter in O_NONE and O_FLIPH, but for O_FLIPV and O_FLIPVH, outputMBRow tries to write to
+        // the bottom of full-frame buffer. Adjust the buffer pointer to compensate.
+        if (O_FLIPV == pID->WMP.wmiI.oOrientation || O_FLIPVH == pID->WMP.wmiI.oOrientation)
+        {
+            I32 iActualY2 = pRect->Y + pRect->Height;
+            pbLowMemAdj = pb - (pID->WMP.wmiI.cROIHeight - (iActualY2 - pID->WMP.cLinesCropped)) * cbStride;
+        }
+        else
+        {
+            pbLowMemAdj = pb - pRect->Y * cbStride;
+        }
+        wmiBI.pv = pbLowMemAdj;
+
+        for (i = (U32)pID->WMP.DecoderCurrMBRow; i < cMBRow; i++)
+        {
+            size_t cLinesDecoded;
+            wmiBI.uiFirstMBRow = i;
+            wmiBI.uiLastMBRow = i;
+            FailIf(ICERR_OK != ImageStrDecDecode(pID->WMP.ctxSC, &wmiBI, &cLinesDecoded), WMP_errFail);
+            pID->WMP.cLinesDecoded = cLinesDecoded;
+            if (FALSE == pID->WMP.fFirstNonZeroDecode && cLinesDecoded > 0)
+            {
+                pID->WMP.cLinesCropped += (linesperMBRow - cLinesDecoded);
+                pID->WMP.fFirstNonZeroDecode = TRUE;
+                // update cMBRow if partial MB row cropped
+                cMBRow = ((U32) pID->WMP.cLinesCropped + pRect->Y + pRect->Height +          
+                    (pRect->Y + pRect->Height >= (I32) pID->WMP.wmiI.cROIHeight ? linesperMBRow - 1 : 0)) / // round up if last MBR
+                    linesperMBRow + 1;
+            }
+
+            if (0 == cLinesDecoded && i > 0)
+            {
+                pID->WMP.cLinesCropped += linesperMBRow;
+                // update cMBRow if whole MB row cropped
+                cMBRow++;
+            }
+        }
+        wmiBI.pv = pbLowMemAdj;
+
+        // If we're past the top of the image, then we're done, so terminate.
+        if (linesperMBRow * (cMBRow - 1) >= (U32) pID->WMP.cLinesCropped + pID->WMP.wmiI.cROIHeight) {
+            FailIf(ICERR_OK != ImageStrDecTerm(pID->WMP.ctxSC), WMP_errFail);        
+        }
+        pID->WMP.DecoderCurrMBRow = cMBRow; // Set to next possible MBRow that is decodable
+
+#else
+        FailIf(ICERR_OK != ImageStrDecInit(&pID->WMP.wmiI, &pID->WMP.wmiSCP, &pID->WMP.ctxSC), WMP_errFail);
+        FailIf(ICERR_OK != ImageStrDecDecode(pID->WMP.ctxSC, &wmiBI), WMP_errFail);
+        FailIf(ICERR_OK != ImageStrDecTerm(pID->WMP.ctxSC), WMP_errFail);
+#endif //REENTRANT_MODE
+
+        if(pID->WMP.bHasAlpha)//planar alpha
+        {
+            pID->WMP.wmiSCP.uAlphaMode = tempAlphaMode;
+        }
+    }
+
+//    if(pID->WMP.bHasAlpha && pID->WMP.wmiSCP.uAlphaMode == 2)
+//    if(pID->WMP.bHasAlpha && pID->WMP.wmiSCP.uAlphaMode != 1)
+    if(pID->WMP.bHasAlpha && pID->WMP.wmiSCP.uAlphaMode != 0)
+    {
+        pID->WMP.wmiI_Alpha = pID->WMP.wmiI;
+        pID->WMP.wmiSCP_Alpha = pID->WMP.wmiSCP;
+
+//        assert(pID->WMP.wmiI_Alpha.cfColorFormat == CF_RGB); // only RGBA is supported for now!
+        pID->WMP.wmiI_Alpha.cfColorFormat = Y_ONLY;
+
+        switch (pID->WMP.wmiI.bdBitDepth)
+        {
+            case BD_8:
+                pID->WMP.wmiI_Alpha.cLeadingPadding += (pID->WMP.wmiI.cBitsPerUnit >> 3) - 1;
+                break;
+            
+            case BD_16:
+            case BD_16S:
+            case BD_16F:
+                pID->WMP.wmiI_Alpha.cLeadingPadding += (pID->WMP.wmiI.cBitsPerUnit >> 3) / sizeof(U16) - 1;
+                break;
+            
+            case BD_32:
+            case BD_32S:
+            case BD_32F:
+                pID->WMP.wmiI_Alpha.cLeadingPadding += (pID->WMP.wmiI.cBitsPerUnit >> 3) / sizeof(float) - 1;
+                break;
+            
+            case BD_5:
+            case BD_10:
+            case BD_565:
+            default:
+                break;
+        }
+
+        pID->WMP.wmiSCP_Alpha.fMeasurePerf = TRUE;
+        Call(pWS->SetPos(pWS, pID->WMP.wmiDEMisc.uAlphaOffset));
+#ifdef REENTRANT_MODE
+        if (0 == pID->WMP.DecoderCurrAlphaMBRow) // add this to WMP struct!
+        {
+            FailIf(ICERR_OK != ImageStrDecInit(&pID->WMP.wmiI_Alpha, &pID->WMP.wmiSCP_Alpha, &pID->WMP.ctxSC_Alpha), WMP_errFail);
+        }
+        
+        // Re-entrant mode incurs 1 MBR delay, so to get 0th MBR, we have to ask for 1st MBR
+        cMBRow = ((U32) pID->WMP.cLinesCropped + pRect->Y + pRect->Height +          
+            (pRect->Y + pRect->Height >= (I32) pID->WMP.wmiI.cROIHeight ? linesperMBRow - 1 : 0)) / // round up if last MBR
+            linesperMBRow + 1;
+        cMBRowStart = ((U32) pID->WMP.cLinesCropped + pRect->Y) / linesperMBRow + 1;
+        // if current request starts before current state, then rewind.
+        if (cMBRowStart < pID->WMP.DecoderCurrAlphaMBRow) 
+        {
+            pID->WMP.DecoderCurrAlphaMBRow = 0;
+            FailIf(ICERR_OK != ImageStrDecTerm(pID->WMP.ctxSC_Alpha), WMP_errFail);
+            FailIf(ICERR_OK != ImageStrDecInit(&pID->WMP.wmiI_Alpha, &pID->WMP.wmiSCP_Alpha, &pID->WMP.ctxSC_Alpha), WMP_errFail);
+        }
+
+        for (i = (U32)pID->WMP.DecoderCurrAlphaMBRow; i < cMBRow; i++)
+        {
+            size_t cLinesDecoded;
+            wmiBI.uiFirstMBRow = i;
+            wmiBI.uiLastMBRow = i;
+            FailIf(ICERR_OK != ImageStrDecDecode(pID->WMP.ctxSC_Alpha, &wmiBI, &cLinesDecoded), WMP_errFail);
+        }
+
+        // If we're past the top of the image, then we're done, so terminate
+        if (linesperMBRow * (cMBRow - 1) >= (U32) pID->WMP.cLinesCropped + pID->WMP.wmiI.cROIHeight) {
+            FailIf(ICERR_OK != ImageStrDecTerm(pID->WMP.ctxSC_Alpha), WMP_errFail);
+        }
+        pID->WMP.DecoderCurrAlphaMBRow = cMBRow; // Set to next possible MBRow that is decodable
+        wmiBI.pv = pb;
+#else
+        FailIf(ICERR_OK != ImageStrDecInit(&pID->WMP.wmiI_Alpha, &pID->WMP.wmiSCP_Alpha, &pID->WMP.ctxSC_Alpha), WMP_errFail);
+        FailIf(ICERR_OK != ImageStrDecDecode(pID->WMP.ctxSC_Alpha, &wmiBI), WMP_errFail);
+        FailIf(ICERR_OK != ImageStrDecTerm(pID->WMP.ctxSC_Alpha), WMP_errFail);
+#endif //REENTRANT_MODE
+    }
+
+    pID->idxCurrentLine += pRect->Height;
+
+Cleanup:
+    return err;
+}
+
+
+ERR PKImageDecode_GetMetadata_WMP(PKImageDecode *pID, U32 uOffset, U32 uByteCount, U8 *pbGot, U32 *pcbGot)
+{
+    ERR err = WMP_errSuccess;
+
+    if (pbGot && uOffset)
+    {
+        struct WMPStream* pWS = pID->pStream;
+        size_t iCurrPos;
+
+        FailIf(*pcbGot < uByteCount, WMP_errBufferOverflow);
+        Call(pWS->GetPos(pWS, &iCurrPos));
+        Call(pWS->SetPos(pWS, uOffset));
+        Call(pWS->Read(pWS, pbGot, uByteCount));
+        Call(pWS->SetPos(pWS, iCurrPos));
+    }
+
+Cleanup:
+    if (Failed(err))
+        *pcbGot = 0;
+    else
+        *pcbGot = uByteCount;
+
+    return err;
+}
+
+
+
+ERR PKImageDecode_GetColorContext_WMP(PKImageDecode *pID, U8 *pbColorContext, U32 *pcbColorContext)
+{
+    return PKImageDecode_GetMetadata_WMP(pID, pID->WMP.wmiDEMisc.uColorProfileOffset,
+        pID->WMP.wmiDEMisc.uColorProfileByteCount, pbColorContext, pcbColorContext);
+}
+
+
+
+ERR PKImageDecode_GetDescriptiveMetadata_WMP(PKImageDecode *pID, DESCRIPTIVEMETADATA *pDescMetadata)
+{
+    ERR err = WMP_errSuccess;
+    *pDescMetadata = pID->WMP.sDescMetadata;
+    return err;
+}
+
+
+ERR PKImageDecode_Release_WMP(PKImageDecode** ppID)
+{
+    ERR             err = WMP_errSuccess;
+    PKImageDecode  *pID;
+
+    if (NULL == ppID)
+        goto Cleanup;
+
+    pID = *ppID;
+
+    // Free descriptive metadata
+    FreeDescMetadata(&pID->WMP.sDescMetadata.pvarImageDescription);
+    FreeDescMetadata(&pID->WMP.sDescMetadata.pvarCameraMake);
+    FreeDescMetadata(&pID->WMP.sDescMetadata.pvarCameraModel);
+    FreeDescMetadata(&pID->WMP.sDescMetadata.pvarSoftware);
+    FreeDescMetadata(&pID->WMP.sDescMetadata.pvarDateTime);
+    FreeDescMetadata(&pID->WMP.sDescMetadata.pvarArtist);
+    FreeDescMetadata(&pID->WMP.sDescMetadata.pvarCopyright);
+    FreeDescMetadata(&pID->WMP.sDescMetadata.pvarRatingStars);
+    FreeDescMetadata(&pID->WMP.sDescMetadata.pvarRatingValue);
+    FreeDescMetadata(&pID->WMP.sDescMetadata.pvarCaption);
+    FreeDescMetadata(&pID->WMP.sDescMetadata.pvarDocumentName);
+    FreeDescMetadata(&pID->WMP.sDescMetadata.pvarPageName);
+    FreeDescMetadata(&pID->WMP.sDescMetadata.pvarPageNumber);
+    FreeDescMetadata(&pID->WMP.sDescMetadata.pvarHostComputer);
+
+    // Release base class
+    Call(PKImageDecode_Release(ppID));
+
+Cleanup:
+    return err;
+}
+
+
+
+ERR PKImageDecode_Create_WMP(PKImageDecode** ppID)
+{
+    ERR err = WMP_errSuccess;
+    PKImageDecode* pID = NULL;
+
+    Call(PKImageDecode_Create(ppID));
+
+    pID = *ppID;
+    pID->Initialize = PKImageDecode_Initialize_WMP;
+    pID->GetSize = PKImageDecode_GetSize_WMP;
+    pID->GetRawStream = PKImageDecode_GetRawStream_WMP;
+    pID->Copy = PKImageDecode_Copy_WMP;
+    pID->GetColorContext = PKImageDecode_GetColorContext_WMP;
+    pID->GetDescriptiveMetadata = PKImageDecode_GetDescriptiveMetadata_WMP;
+    pID->Release = PKImageDecode_Release_WMP;
+
+Cleanup:
+    return err;
+}
+
diff --git a/Source/LibJXR/jxrgluelib/JXRGluePFC.c b/Source/LibJXR/jxrgluelib/JXRGluePFC.c
new file mode 100644
index 0000000..716dc7f
--- /dev/null
+++ b/Source/LibJXR/jxrgluelib/JXRGluePFC.c
@@ -0,0 +1,2338 @@
+//*@@@+++@@@@******************************************************************
+//
+// Copyright � Microsoft Corp.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+// � Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// � Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//*@@@---@@@@******************************************************************
+#include <stdlib.h>
+
+#include <JXRGlue.h>
+#include <math.h>
+
+//================================================================
+// PKFormatConverter
+//================================================================
+#define HLF_MIN 0.00006103515625f
+#define HLF_MAX 65504.0f
+
+#define HLF_MIN_BITS 0x0400
+#define HLF_MAX_BITS 0x7bff
+
+#define HLF_MIN_BITS_NEG (HLF_MIN_BITS | 0x8000)
+#define HLF_MAX_BITS_NEG (HLF_MAX_BITS | 0x8000)
+
+#define HLF_QNaN_BITZS 0x7fff
+
+// simple and slow implementation of half <-> float conversion
+static U32 Convert_Half_To_Float(U16 u16)
+{
+    // 1s5e10m -> 1s8e23m
+    const U32 s = (u16 >> 15) & 0x0001;
+    const U32 e = (u16 >> 10) & 0x001f;
+    const U32 m = (u16 >>  0) & 0x03ff;
+
+    if (0 == e) // 0, denorm
+    {
+        return s << 31;
+    }
+    else if (~(~0 << 5) == e) // inf, snan, qnan
+    {
+        return (s << 31) | ~(~0 << 8) << 23| (m << 13);
+    }
+
+    return (s << 31) | ((e - 15 + 127) << 23) | (m << 13); // norm
+}
+
+
+static U16 Convert_Float_To_Half(float f)
+{
+    // 1s5e10m -> 1s8e23m
+    const U32 iFloat = *(U32*)&f; // Convert float to U32
+
+    if (f != f)
+    {
+        return (U16)(iFloat | HLF_QNaN_BITZS); // +QNaN, -QNaN
+    }
+    else if (f < -HLF_MAX)
+    {
+        return HLF_MAX_BITS_NEG;
+    }
+    else if (HLF_MAX < f)
+    {
+        return HLF_MAX_BITS;
+    }
+    else if (-HLF_MIN < f && f < HLF_MIN)
+    {
+        return (U16)((iFloat >> 16) & 0x8000); // +0, -0
+    }
+
+    // Cut-and-paste from C++, introduce scope so we can decl more vars
+    {
+    const U32 s = (iFloat >> 31) & 0x00000001;
+    const U32 e = (iFloat >> 23) & 0x000000ff;
+    const U32 m = (iFloat >>  0) & 0x007fffff;
+
+    return (U16) ((s << 15) | ((e - 127 + 15) << 10) | (m >> 13));
+    }
+}
+
+
+static U8 Convert_Float_To_U8(float f)
+{
+    // convert from linear scRGB to non-linear sRGB
+    if (f <= 0)
+    {
+        return 0;
+    }
+    else if (f <= 0.0031308f)
+    {
+        return (U8)((255.0f * f * 12.92f) + 0.5f);
+    }
+    else if (f < 1.0f)
+    {
+        return (U8)((255.0f * ((1.055f * (float)pow(f, 1.0f / 2.4f)) - 0.055f)) + 0.5f);
+    }
+    else
+    {
+        return 255;
+    }
+}
+
+static U8 Convert_AlphaFloat_To_U8(float f)
+{
+    // alpha is converted differently than RGB in scRGB
+    if (f <= 0)
+    {
+        return 0;
+    }
+    else if (f < 1.0f)
+    {
+        return (U8)((255.0f * f) + 0.5f);
+    }
+    else
+    {
+        return 255;
+    }
+}
+
+
+ERR RGB24_BGR24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    I32 i = 0, j = 0;
+
+    UNREFERENCED_PARAMETER( pFC );
+   
+    for (i = 0; i < pRect->Height; ++i)
+    {
+        for (j = 0; j < pRect->Width * 3; j += 3)
+        {
+            // swap red with blue
+            U8 t = pb[j];
+            pb[j] = pb[j + 2];
+            pb[j + 2] = t;
+        }
+
+        pb += cbStride;
+    }
+
+    return WMP_errSuccess;
+}
+
+ERR BGR24_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    return RGB24_BGR24(pFC, pRect, pb, cbStride);
+}
+
+ERR RGB24_BGR32(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    I32 i = 0, j = 0;
+
+    UNREFERENCED_PARAMETER( pFC );
+   
+    for (i = 0; i < pRect->Height; ++i)
+    {
+        for (j = 0; j < pRect->Width; j++)
+        {
+            // swap red with blue
+            U8 t = pb[3*j];
+            pb[4*j] = pb[3*j + 2];
+            pb[4*j + 1] = pb[3*j + 1];
+            pb[4*j + 2] = t;
+        }
+
+        pb += cbStride;
+    }
+
+    return WMP_errSuccess;
+}
+
+ERR BGR32_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    I32 i = 0, j = 0;
+
+    UNREFERENCED_PARAMETER( pFC );
+   
+    for (i = 0; i < pRect->Height; ++i)
+    {
+        for (j = 0; j < pRect->Width; j++)
+        {
+            // swap red with blue
+            U8 t = pb[4*j];
+            pb[3*j] = pb[4*j + 2];
+            pb[3*j + 1] = pb[4*j + 1];
+            pb[3*j + 2] = t;
+        }
+
+        pb += cbStride;
+    }
+
+    return WMP_errSuccess;
+}
+
+ERR RGB24_Gray8(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    I32 i = 0, j = 0, k = 0;
+
+    UNREFERENCED_PARAMETER( pFC );
+    
+    for (i = 0; i < pRect->Height; ++i)
+    {
+        for (j = 0, k = 0; j < pRect->Width * 3; j += 3, ++k)
+        {
+            U8 r = pb[j];
+            U8 g = pb[j + 1];
+            U8 b = pb[j + 2];
+            
+            pb[k] = r / 4 + g / 2 + b / 8 + 16;
+        }
+
+        pb += cbStride;
+    }
+
+    return WMP_errSuccess;
+}
+
+ERR BGR24_Gray8(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    ERR err = WMP_errSuccess;
+
+    Call(BGR24_RGB24(pFC, pRect, pb, cbStride));
+    Call(RGB24_Gray8(pFC, pRect, pb, cbStride));
+
+Cleanup:
+    return err;
+}
+
+ERR Gray8_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    I32 i = 0, j = 0, k = 0;
+
+    UNREFERENCED_PARAMETER( pFC );
+    
+    for (i = 0; i < pRect->Height; ++i)
+    {
+        for (j = pRect->Width - 1, k = 3 * j; 0 <= j; j--, k -= 3)
+        {
+            U8 v = pb[j];
+
+            pb[k] = v;
+            pb[k + 1] = v;
+            pb[k + 2] = v;
+        }
+        
+        pb += cbStride;
+    }
+
+    return WMP_errSuccess;
+}
+
+ERR Gray8_BGR24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    return Gray8_RGB24(pFC, pRect, pb, cbStride);
+}
+
+#if 0
+ERR RGB48_BGR48(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    ERR err = WMP_errSuccess;
+
+    I32 i = 0, j = 0;
+
+    UNREFERENCED_PARAMETER( pFC );
+    
+    Call(PKFormatConverter_Copy(pFC, pRect, pb, cbStride));
+
+    for (i = 0; i < pRect->Height; ++i)
+    {
+        for (j = 0; j < pRect->Width; j += 3)
+        {
+            U16* ps = (U16*)pb;
+            
+            // swap red with blue
+            U16 t = ps[j];
+            ps[j] = ps[j + 2];
+            ps[j + 2] = t;
+        }
+
+        pb += cbStride;
+    }
+
+Cleanup:
+    return err;
+}
+
+ERR BGR48_RGB48(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    return RGB48_BGR48(pFC, pRect, pb, cbStride);
+}
+
+ERR RGB48_Gray16(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    ERR err = WMP_errSuccess;
+
+    I32 i = 0, j = 0, k = 0;
+ 
+    UNREFERENCED_PARAMETER( pFC );
+   
+    Call(PKFormatConverter_Copy(pFC, pRect, pb, cbStride));
+
+    for (i = 0; i < pRect->Height; ++i)
+    {
+        for (j = 0, k = 0; j < pRect->Width; j += 3, ++k)
+        {
+            U16* ps = (U16*)pb;
+
+            // Y = r / 4 + g / 2 + b / 8 + 16
+            U16 r = ps[j];
+            U16 g = ps[j + 1];
+            U16 b = ps[j + 2];
+            
+            ps[k] = r / 4 + g / 2 + b / 8 + 16;
+        }
+
+        pb += cbStride;
+    }
+
+Cleanup:
+    return err;
+}
+#endif
+
+ERR RGBA128Fixed_RGBA128Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidthX4 = 4 * pRect->Width; // 4 == R, G, B, A
+    const float fltCvtFactor = 1.0F / (1 << 24);
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        float *pfltDstPixel = (float*)(pb + cbStride*y);
+        const I32 *piSrcPixel = (I32*)pfltDstPixel;
+
+        for (x = 0; x < iWidthX4; x++)
+            pfltDstPixel[x] = piSrcPixel[x] * fltCvtFactor;
+    }
+    
+    return WMP_errSuccess;
+}
+
+
+ERR RGBA128Float_RGBA128Fixed(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidthX4 = 4 * pRect->Width; // 4 == R, G, B, A
+    const float fltCvtFactor = (float)(1 << 24);
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        I32 *piDstPixel = (I32*)(pb + cbStride*y);
+        const float *pfltSrcPixel = (float*)piDstPixel;
+
+        for (x = 0; x < iWidthX4; x++)
+            piDstPixel[x] = (I32) (pfltSrcPixel[x] * fltCvtFactor + 0.5F);
+    }
+    
+    return WMP_errSuccess;
+}
+
+
+
+ERR RGB96Fixed_RGB96Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidthX3 = 3 * pRect->Width; // 3 == R, G, B
+    const float fltCvtFactor = 1.0F / (1 << 24);
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        float *pfltDstPixel = (float*)(pb + cbStride*y);
+        const I32 *piSrcPixel = (I32*)pfltDstPixel;
+
+        for (x = 0; x < iWidthX3; x++)
+            pfltDstPixel[x] = piSrcPixel[x] * fltCvtFactor;
+    }
+    
+    return WMP_errSuccess;
+}
+
+
+ERR RGB128Fixed_RGB96Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    const float fltCvtFactor = 1.0F / (1 << 24);
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        float *pfltDstPixel = (float*)(pb + cbStride*y);
+        const I32 *piSrcPixel = (I32*)pfltDstPixel;
+
+        for (x = 0; x < iWidth; x++)
+        {
+            pfltDstPixel[3*x] = piSrcPixel[4*x] * fltCvtFactor;
+            pfltDstPixel[3*x+1] = piSrcPixel[4*x+1] * fltCvtFactor;
+            pfltDstPixel[3*x+2] = piSrcPixel[4*x+2] * fltCvtFactor;
+        }
+    }
+    
+    return WMP_errSuccess;
+}
+
+
+
+ERR RGB96Float_RGB96Fixed(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidthX3 = 3 * pRect->Width; // 3 == R, G, B
+    const float fltCvtFactor = (float) (1 << 24);
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        I32 *piDstPixel = (I32*)(pb + cbStride*y);
+        const float *pfltSrcPixel = (float*)piDstPixel;
+
+        for (x = 0; x < iWidthX3; x++)
+            piDstPixel[x] = (I32)(pfltSrcPixel[x] * fltCvtFactor + 0.5F);
+    }
+    
+    return WMP_errSuccess;
+}
+
+
+ERR RGB96Float_RGB128Fixed(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    const float fltCvtFactor = (float) (1 << 24);
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    assert(iWidth > 2); // Otherwise, we corrupt source data in inner loop
+    for (y = iHeight - 1; y >= 0; y--)
+    {
+        I32 x;
+        I32 *piDstPixel = (I32*)(pb + cbStride*y);
+        const float *pfltSrcPixel = (float*)piDstPixel;
+
+        for (x = iWidth - 1; x >= 0; x--)
+        {
+            piDstPixel[4*x] = (I32)(pfltSrcPixel[3*x] * fltCvtFactor + 0.5F);
+            piDstPixel[4*x+1] = (I32)(pfltSrcPixel[3*x+1] * fltCvtFactor + 0.5F);
+            piDstPixel[4*x+2] = (I32)(pfltSrcPixel[3*x+2] * fltCvtFactor + 0.5F);
+            piDstPixel[4*x+3] = 0; // Zero out the alpha channel
+        }
+    }
+    
+    return WMP_errSuccess;
+}
+
+
+ERR RGB96Float_RGB128Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    assert(iWidth > 2); // Otherwise, we corrupt source data in inner loop
+    for (y = iHeight - 1; y >= 0; y--)
+    {
+        I32 x;
+        float *pfltDstPixel = (float*)(pb + cbStride*y);
+        const float *pfltSrcPixel = (float*)pfltDstPixel;
+
+        for (x = iWidth - 1; x >= 0; x--)
+        {
+            pfltDstPixel[4*x] = pfltSrcPixel[3*x];
+            pfltDstPixel[4*x+1] = pfltSrcPixel[3*x+1];
+            pfltDstPixel[4*x+2] = pfltSrcPixel[3*x+2];
+            pfltDstPixel[4*x+3] = 0.0F; // Zero out the alpha channel
+        }
+    }
+    
+    return WMP_errSuccess;
+}
+
+
+ERR RGB128Float_RGB96Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        float *pfltDstPixel = (float*)(pb + cbStride*y);
+        const float *pfltSrcPixel = (float*)pfltDstPixel;
+
+        for (x = 0; x < iWidth; x++)
+        {
+            pfltDstPixel[3*x] = pfltSrcPixel[4*x];
+            pfltDstPixel[3*x+1] = pfltSrcPixel[4*x+1];
+            pfltDstPixel[3*x+2] = pfltSrcPixel[4*x+2];
+        }
+    }
+    
+    return WMP_errSuccess;
+}
+
+
+ERR RGB48Half_RGB64Half(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    assert(iWidth > 2); // Otherwise, we corrupt source data in inner loop
+    for (y = iHeight - 1; y >= 0; y--)
+    {
+        I32 x;
+        I16 *piDstPixel = (I16*)(pb + cbStride*y);
+        const I16 *piSrcPixel = (I16*)piDstPixel;
+
+        for (x = iWidth - 1; x >= 0; x--)
+        {
+            piDstPixel[4*x] = piSrcPixel[3*x];
+            piDstPixel[4*x+1] = piSrcPixel[3*x+1];
+            piDstPixel[4*x+2] = piSrcPixel[3*x+2];
+            piDstPixel[4*x+3] = 0; // Zero out the alpha channel
+        }
+    }
+    
+    return WMP_errSuccess;
+}
+
+
+ERR RGB64Half_RGB48Half(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        I16 *piDstPixel = (I16*)(pb + cbStride*y);
+        const short *piSrcPixel = (I16*)piDstPixel;
+
+        for (x = 0; x < iWidth; x++)
+        {
+            piDstPixel[3*x] = piSrcPixel[4*x];
+            piDstPixel[3*x+1] = piSrcPixel[4*x+1];
+            piDstPixel[3*x+2] = piSrcPixel[4*x+2];
+        }
+    }
+    
+    return WMP_errSuccess;
+}
+
+
+ERR BGR24_BGR32(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    assert(iWidth > 2); // Otherwise, we corrupt source data in inner loop
+    for (y = iHeight - 1; y >= 0; y--)
+    {
+        I32 x;
+        U8 *piDstPixel = pb + cbStride*y;
+        const U8 *piSrcPixel = piDstPixel;
+
+        for (x = iWidth - 1; x >= 0; x--)
+        {
+            piDstPixel[4*x] = piSrcPixel[3*x];
+            piDstPixel[4*x+1] = piSrcPixel[3*x+1];
+            piDstPixel[4*x+2] = piSrcPixel[3*x+2];
+            piDstPixel[4*x+3] = 0; // Zero out the alpha channel
+        }
+    }
+    
+    return WMP_errSuccess;
+}
+
+
+ERR BGR32_BGR24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        U8 *piDstPixel = pb + cbStride*y;
+        const U8 *piSrcPixel = piDstPixel;
+
+        for (x = 0; x < iWidth; x++)
+        {
+            piDstPixel[3*x] = piSrcPixel[4*x];
+            piDstPixel[3*x+1] = piSrcPixel[4*x+1];
+            piDstPixel[3*x+2] = piSrcPixel[4*x+2];
+        }
+    }
+    
+    return WMP_errSuccess;
+}
+
+
+ERR Gray32Fixed_Gray32Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    const float fltCvtFactor = 1.0F / (1 << 24);
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        float *pfltDstPixel = (float*)(pb + cbStride*y);
+        const I32 *piSrcPixel = (I32*)pfltDstPixel;
+
+        for (x = 0; x < iWidth; x++)
+            pfltDstPixel[x] = piSrcPixel[x] * fltCvtFactor;
+    }
+    
+    return WMP_errSuccess;
+}
+
+
+ERR Gray32Float_Gray32Fixed(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    const float fltCvtFactor = (float) (1 << 24);
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        I32 *piDstPixel = (I32*)(pb + cbStride*y);
+        const float *pfltSrcPixel = (float*)piDstPixel;
+
+        for (x = 0; x < iWidth; x++)
+            piDstPixel[x] = (I32)(pfltSrcPixel[x] * fltCvtFactor + 0.5F);
+    }
+    
+    return WMP_errSuccess;
+}
+
+
+
+ERR Gray16Fixed_Gray32Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    const float fltCvtFactor = 1.0F / (1 << 13);
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    // Stride is assumed to be same for src/dst
+    for (y = iHeight - 1; y >= 0; y--)
+    {
+        I32 x;
+        float *pfltDstPixel = (float*)(pb + cbStride*y);
+        const I16 *piSrcPixel = (I16*)pfltDstPixel;
+
+        for (x = iWidth - 1; x >= 0; x--)
+            pfltDstPixel[x] = piSrcPixel[x] * fltCvtFactor;
+    }
+    
+    return WMP_errSuccess;
+}
+
+
+ERR Gray32Float_Gray16Fixed(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    const float fltCvtFactor = (float) (1 << 13);
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    // Stride is assumed to be same for src/dst
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        I16 *piDstPixel = (I16*)(pb + cbStride*y);
+        const float *pfltSrcPixel = (float*)piDstPixel;
+
+        for (x = 0; x < iWidth; x++)
+            piDstPixel[x] = (I16)(pfltSrcPixel[x] * fltCvtFactor + 0.5F);
+    }
+    
+    return WMP_errSuccess;
+}
+
+
+ERR RGB48Fixed_RGB96Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidthX3 = 3 * pRect->Width;
+    const float fltCvtFactor = 1.0F / (1 << 13);
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    // Stride is assumed to be same for src/dst
+    for (y = iHeight - 1; y >= 0; y--)
+    {
+        I32 x;
+        float *pfltDstPixel = (float*)(pb + cbStride*y);
+        const I16 *piSrcPixel = (I16*)pfltDstPixel;
+
+        for (x = iWidthX3 - 1; x >= 0; x--)
+            pfltDstPixel[x] = piSrcPixel[x] * fltCvtFactor;
+    }
+    
+    return WMP_errSuccess;
+}
+
+
+ERR RGB96Float_RGB48Fixed(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidthX3 = 3 * pRect->Width;
+    const float fltCvtFactor = (float)(1 << 13);
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    // Stride is assumed to be same for src/dst
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        I16 *piDstPixel = (I16*)(pb + cbStride*y);
+        const float *pfltSrcPixel = (float*)piDstPixel;
+
+        for (x = 0; x < iWidthX3; x++)
+            piDstPixel[x] = (I16)(pfltSrcPixel[x] * fltCvtFactor + 0.5F);
+    }
+    
+    return WMP_errSuccess;
+}
+
+
+ERR RGB64Fixed_RGB96Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    const float fltCvtFactor = 1.0F / (1 << 13);
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    // Stride is assumed to be same for src/dst
+    for (y = iHeight - 1; y >= 0; y--)
+    {
+        I32 x;
+        float *pfltDstPixel = (float*)(pb + cbStride*y);
+        const I16 *piSrcPixel = (I16*)pfltDstPixel;
+
+        for (x = iWidth - 1; x >= 0; x--)
+        {
+            pfltDstPixel[3*x] = piSrcPixel[4*x] * fltCvtFactor;
+            pfltDstPixel[3*x+1] = piSrcPixel[4*x+1] * fltCvtFactor;
+            pfltDstPixel[3*x+2] = piSrcPixel[4*x+2] * fltCvtFactor;
+        }
+    }
+    
+    return WMP_errSuccess;
+}
+
+
+ERR RGB96Float_RGB64Fixed(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    const float fltCvtFactor = (float)(1 << 13);
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    // Stride is assumed to be same for src/dst
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        I16 *piDstPixel = (I16*)(pb + cbStride*y);
+        const float *pfltSrcPixel = (float*)piDstPixel;
+
+        for (x = 0; x < iWidth; x++)
+        {
+            piDstPixel[4*x] = (I16)(pfltSrcPixel[3*x] * fltCvtFactor + 0.5F);
+            piDstPixel[4*x+1] = (I16)(pfltSrcPixel[3*x+1] * fltCvtFactor + 0.5F);
+            piDstPixel[4*x+2] = (I16)(pfltSrcPixel[3*x+2] * fltCvtFactor + 0.5F);
+            piDstPixel[4*x+3] = 0; // Zero out the alpha channel
+        }
+    }
+    
+    return WMP_errSuccess;
+}
+
+
+ERR RGBA64Fixed_RGBA128Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidthX4 = 4 * pRect->Width;
+    const float fltCvtFactor = 1.0F / (1 << 13);
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    // Stride is assumed to be same for src/dst
+    for (y = iHeight - 1; y >= 0; y--)
+    {
+        I32 x;
+        float *pfltDstPixel = (float*)(pb + cbStride*y);
+        const I16 *piSrcPixel = (I16*)pfltDstPixel;
+
+        for (x = iWidthX4 - 1; x >= 0; x--)
+            pfltDstPixel[x] = piSrcPixel[x] * fltCvtFactor;
+    }
+    
+    return WMP_errSuccess;
+}
+
+
+
+ERR RGBA128Float_RGBA64Fixed(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidthX4 = 4 * pRect->Width;
+    const float fltCvtFactor = (float)(1 << 13);
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    // Stride is assumed to be same for src/dst
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        I16 *piDstPixel = (I16*)(pb + cbStride*y);
+        const float *pfltSrcPixel = (float*)piDstPixel;
+
+        for (x = 0; x < iWidthX4; x++)
+            piDstPixel[x] = (I16)(pfltSrcPixel[x] * fltCvtFactor + 0.5F);
+    }
+    
+    return WMP_errSuccess;
+}
+
+
+
+ERR RGBE_RGB96Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    // Stride is assumed to be same for src/dst
+    for (y = iHeight - 1; y >= 0; y--)
+    {
+        I32 x;
+        float *pfltDstPixel = (float*)(pb + cbStride*y);
+        const U8 *piSrcPixel = (U8*)pfltDstPixel;
+
+        for (x = iWidth - 1; x >= 0; x--)
+        {
+            // First read the exponent
+            const U8 rawExp = piSrcPixel[4*x+3];
+
+            if (0 == rawExp)
+            {
+                pfltDstPixel[3*x] = 0.0F;
+                pfltDstPixel[3*x+1] = 0.0F;
+                pfltDstPixel[3*x+2] = 0.0F;
+            }
+            else
+            {
+                const I32 adjExp = (I32)rawExp - 128 - 8; // Can be negative
+                float fltExp;
+
+                if (adjExp > -32 && adjExp < 32)
+                {
+                    fltExp = (float) (((U32)1) << abs(adjExp));
+                    if (adjExp < 0)
+                        fltExp = 1.0F / fltExp;
+                }
+                else
+                {
+                    fltExp = (float)ldexp(1.0F, adjExp);
+                }
+
+                pfltDstPixel[3*x] = piSrcPixel[4*x] * fltExp;
+                pfltDstPixel[3*x + 1] = piSrcPixel[4*x + 1] * fltExp;
+                pfltDstPixel[3*x + 2] = piSrcPixel[4*x + 2] * fltExp;
+            }
+        }
+    }
+    
+    return WMP_errSuccess;
+}
+
+
+ERR RGB96Float_RGBE(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    assert(iWidth > 2); // Otherwise, we corrupt source data in inner loop
+
+    // Stride is assumed to be same for src/dst
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        U8 *piDstPixel = (U8*)(pb + cbStride*y);
+        const float *pfltSrcPixel = (float*)piDstPixel;
+
+        for (x = 0; x < iWidth; x++)
+        {
+            // We clamp source RGB values at zero (don't allow negative numbers)
+            const float fltRed = max(pfltSrcPixel[3*x], 0.0F);
+            const float fltGreen = max(pfltSrcPixel[3*x+1], 0.0F);
+            const float fltBlue = max(pfltSrcPixel[3*x+2], 0.0F);
+            float fltMaxPos = fltRed;
+
+            if (fltGreen > fltMaxPos)
+                fltMaxPos = fltGreen;
+
+            if (fltBlue > fltMaxPos)
+                fltMaxPos = fltBlue;
+
+            if (fltMaxPos < 1e-32)
+            {
+                piDstPixel[4*x] = 0;    // R
+                piDstPixel[4*x+1] = 0;  // G
+                piDstPixel[4*x+2] = 0;  // B
+                piDstPixel[4*x+3] = 0;  // E
+            }
+            else
+            {
+                int e;
+                const float fltScale = (float)frexp(fltMaxPos, &e) * 256 / fltMaxPos;
+
+                // rounding SHOULD NOT be added - it has the potential to roll over to zero (and yes, 256 is the correct multiplier above)
+                piDstPixel[4*x] = (U8)(fltRed * fltScale);       // R
+                piDstPixel[4*x+1] = (U8)(fltGreen * fltScale);   // G
+                piDstPixel[4*x+2] = (U8)(fltBlue * fltScale);    // B
+                piDstPixel[4*x+3] = (U8)(e + 128);               // E
+            }
+        }
+    }
+    
+    return WMP_errSuccess;
+}
+
+
+ERR RGBA64Half_RGBA128Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidthX4 = 4 * pRect->Width;
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    // Stride is assumed to be same for src/dst
+    for (y = iHeight - 1; y >= 0; y--)
+    {
+        I32 x;
+        U32 *pfltDstPixel = (U32*)(pb + cbStride*y); // It's really float, but use U32 ptr
+        const I16 *piSrcPixel = (I16*)pfltDstPixel;
+
+        for (x = iWidthX4 - 1; x >= 0; x--)
+            pfltDstPixel[x] = Convert_Half_To_Float(piSrcPixel[x]);
+    }
+    
+    return WMP_errSuccess;
+}
+
+
+ERR RGBA128Float_RGBA64Half(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidthX4 = 4 * pRect->Width;
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    // Stride is assumed to be same for src/dst
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        I16 *piDstPixel = (I16*)(pb + cbStride*y);
+        const float *pfltSrcPixel = (float*)piDstPixel;
+
+        for (x = 0; x < iWidthX4; x++)
+            piDstPixel[x] = Convert_Float_To_Half(pfltSrcPixel[x]);
+    }
+    
+    return WMP_errSuccess;
+}
+
+
+ERR RGB64Half_RGB96Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    // Stride is assumed to be same for src/dst
+    for (y = iHeight - 1; y >= 0; y--)
+    {
+        I32 x;
+        U32 *pfltDstPixel = (U32*)(pb + cbStride*y); // It's really float, but use U32 ptr
+        const I16 *piSrcPixel = (I16*)pfltDstPixel;
+
+        for (x = iWidth - 1; x >= 0; x--)
+        {
+            pfltDstPixel[3*x] = Convert_Half_To_Float(piSrcPixel[4*x]);
+            pfltDstPixel[3*x+1] = Convert_Half_To_Float(piSrcPixel[4*x+1]);
+            pfltDstPixel[3*x+2] = Convert_Half_To_Float(piSrcPixel[4*x+2]);
+        }
+    }
+    
+    return WMP_errSuccess;
+}
+
+
+ERR RGB96Float_RGB64Half(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    // Stride is assumed to be same for src/dst
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        I16 *piDstPixel = (I16*)(pb + cbStride*y);
+        const float *pfltSrcPixel = (float*)piDstPixel;
+
+        for (x = 0; x < iWidth; x++)
+        {
+            piDstPixel[4*x] = Convert_Float_To_Half(pfltSrcPixel[3*x]);
+            piDstPixel[4*x+1] = Convert_Float_To_Half(pfltSrcPixel[3*x+1]);
+            piDstPixel[4*x+2] = Convert_Float_To_Half(pfltSrcPixel[3*x+2]);
+            piDstPixel[4*x+3] = 0; // Zero out the alpha channel
+        }
+    }
+    
+    return WMP_errSuccess;
+}
+
+
+ERR RGB48Half_RGB96Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidthX3 = 3*pRect->Width;
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    // Stride is assumed to be same for src/dst
+    for (y = iHeight - 1; y >= 0; y--)
+    {
+        I32 x;
+        U32 *pfltDstPixel = (U32*)(pb + cbStride*y); // It's really float, but use U32 ptr
+        const I16 *piSrcPixel = (I16*)pfltDstPixel;
+
+        for (x = iWidthX3 - 1; x >= 0; x--)
+            pfltDstPixel[x] = Convert_Half_To_Float(piSrcPixel[x]);
+    }
+    
+    return WMP_errSuccess;
+}
+
+
+ERR RGB96Float_RGB48Half(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidthX3 = 3*pRect->Width;
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    // Stride is assumed to be same for src/dst
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        I16 *piDstPixel = (I16*)(pb + cbStride*y);
+        const float *pfltSrcPixel = (float*)piDstPixel;
+
+        for (x = 0; x < iWidthX3; x++)
+            piDstPixel[x] = Convert_Float_To_Half(pfltSrcPixel[x]);
+    }
+    
+    return WMP_errSuccess;
+}
+
+
+ERR Gray16Half_Gray32Float(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    // Stride is assumed to be same for src/dst
+    for (y = iHeight - 1; y >= 0; y--)
+    {
+        I32 x;
+        U32 *pfltDstPixel = (U32*)(pb + cbStride*y); // It's really float, but use U32 ptr
+        const I16 *piSrcPixel = (I16*)pfltDstPixel;
+
+        for (x = iWidth - 1; x >= 0; x--)
+            pfltDstPixel[x] = Convert_Half_To_Float(piSrcPixel[x]);
+    }
+    
+    return WMP_errSuccess;
+}
+
+
+ERR Gray32Float_Gray16Half(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    // Stride is assumed to be same for src/dst
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        I16 *piDstPixel = (I16*)(pb + cbStride*y);
+        const float *pfltSrcPixel = (float*)piDstPixel;
+
+        for (x = 0; x < iWidth; x++)
+            piDstPixel[x] = Convert_Float_To_Half(pfltSrcPixel[x]);
+    }
+    
+    return WMP_errSuccess;
+}
+
+ERR RGB555_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    // Stride is assumed to be same for src/dst
+    for (y = iHeight - 1; y >= 0; y--)
+    {
+        I32 x;
+        U8 *piDstPixel = (pb + cbStride*y);
+        const U16 *piSrcPixel = (U16*)piDstPixel;
+
+        for (x = iWidth - 1; x >= 0; x--)
+        {
+            const U16 v = piSrcPixel[x];
+            const unsigned int r = ((v >> 10) & 0x1f);
+            const unsigned int g = ((v >> 5) & 0x1f);
+            const unsigned int b = (v & 0x1f);
+
+            piDstPixel[3*x] = (U8)(r << 3);    // R
+            piDstPixel[3*x+1] = (U8)(g << 3);  // G
+            piDstPixel[3*x+2] = (U8)(b << 3);  // B
+        }
+    }
+    
+    return WMP_errSuccess;
+}
+
+
+ERR RGB101010_RGB48(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    // Stride is assumed to be same for src/dst
+    for (y = iHeight - 1; y >= 0; y--)
+    {
+        I32 x;
+        U16 *piDstPixel = (U16*)(pb + cbStride*y);
+        const U32 *piSrcPixel = (U32*)piDstPixel;
+
+        for (x = iWidth - 1; x >= 0; x--)
+        {
+            const U32 v = piSrcPixel[x];
+            const unsigned int r = ((v >> 20) & 0x3FF);
+            const unsigned int g = ((v >> 10) & 0x3FF);
+            const unsigned int b = (v & 0x3FF);
+
+            piDstPixel[3*x] = (U16)(r << 6);    // R
+            piDstPixel[3*x+1] = (U16)(g << 6);  // G
+            piDstPixel[3*x+2] = (U16)(b << 6);  // B
+        }
+    }
+    
+    return WMP_errSuccess;
+}
+
+
+ERR RGB24_RGB555(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    // Stride is assumed to be same for src/dst
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        U16 *piDstPixel = (U16*)(pb + cbStride*y);
+        const U8 *piSrcPixel = (U8*)piDstPixel;
+
+        for (x = 0; x < iWidth; x++)
+        {
+            const unsigned int r = piSrcPixel[3*x];
+            const unsigned int g = piSrcPixel[3*x+1];
+            const unsigned int b = piSrcPixel[3*x+2];
+
+            piDstPixel[x] = (U16) (
+                            ((r & 0xF8) << 7) |
+                            ((g & 0xF8) << 2) |
+                             (b >> 3));
+        }
+    }
+
+    return WMP_errSuccess;
+}
+
+
+
+ERR RGB48_RGB101010(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    // Stride is assumed to be same for src/dst
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        U32 *piDstPixel = (U32*)(pb + cbStride*y);
+        const U16 *piSrcPixel = (U16*)piDstPixel;
+
+        for (x = 0; x < iWidth; x++)
+        {
+            const unsigned int r = piSrcPixel[3*x];
+            const unsigned int g = piSrcPixel[3*x+1];
+            const unsigned int b = piSrcPixel[3*x+2];
+
+            piDstPixel[x] = (3 << 30) | // For compatibility with D3D's 2-10-10-10 format.
+                            ((r & 0x0000FFC0) << 14) |
+                            ((g & 0x0000FFC0) << 4) |
+                             (b >> 6);
+        }
+    }
+
+    return WMP_errSuccess;
+}
+
+
+
+ERR RGB565_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    // Stride is assumed to be same for src/dst
+    for (y = iHeight - 1; y >= 0; y--)
+    {
+        I32 x;
+        U8 *piDstPixel = (pb + cbStride*y);
+        const U16 *piSrcPixel = (U16*)piDstPixel;
+
+        for (x = iWidth - 1; x >= 0; x--)
+        {
+            const U16 v = piSrcPixel[x];
+            const unsigned int r = ((v >> 11) & 0x1f);
+            const unsigned int g = ((v >> 5) & 0x3f);
+            const unsigned int b = (v & 0x1f);
+
+            piDstPixel[3*x] = (U8)(r << 3);    // R
+            piDstPixel[3*x+1] = (U8)(g << 2);  // G
+            piDstPixel[3*x+2] = (U8)(b << 3);  // B
+        }
+    }
+    
+    return WMP_errSuccess;
+}
+
+
+
+ERR RGB24_RGB565(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    // Stride is assumed to be same for src/dst
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        U16 *piDstPixel = (U16*)(pb + cbStride*y);
+        const U8 *piSrcPixel = (U8*)piDstPixel;
+
+        for (x = 0; x < iWidth; x++)
+        {
+            const unsigned int r = piSrcPixel[3*x];
+            const unsigned int g = piSrcPixel[3*x+1];
+            const unsigned int b = piSrcPixel[3*x+2];
+
+            piDstPixel[x] = (U16) (
+                            ((r & 0xF8) << 8) |
+                            ((g & 0xFC) << 3) |
+                             (b >> 3));
+        }
+    }
+
+    return WMP_errSuccess;
+}
+
+
+ERR RGBA32_BGRA32(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidthX4 = 4 * pRect->Width; // 4 == R, G, B, A
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        U8 *piPixel = (U8*)(pb + cbStride*y);
+
+        for (x = 0; x < iWidthX4; x += 4)
+        {
+            // Swap R and B
+            U8 bTemp = piPixel[x];
+            piPixel[x] = piPixel[x+2];
+            piPixel[x+2] = bTemp;
+        }
+    }
+    
+    return WMP_errSuccess;
+}
+
+
+ERR BGRA32_RGBA32(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    return RGBA32_BGRA32(pFC, pRect, pb, cbStride);
+}
+
+
+ERR BlackWhite_Gray8(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+	Bool bBlackWhite = pFC->pDecoder->WMP.wmiSCP.bBlackWhite;
+    I32 y;
+
+    // Stride is assumed to be same for src/dst
+    for (y = iHeight - 1; y >= 0; y--)
+    {
+        I32 x;
+		I32 n;
+        U8 *piDstPixel = (pb + cbStride*y);
+        const U8 *piSrcPixel = (U8*)piDstPixel;
+
+		if (iWidth % 8 != 0)
+		{
+			const U8 v = piSrcPixel[iWidth / 8];
+
+			for (n = 0; n < iWidth % 8; n++)
+			{
+				piDstPixel[iWidth/8*8+n] = (((v >> (7 - n)) & 0x1) != 0) ^ bBlackWhite ? 0xFF : 0x00;
+			}
+		}
+
+        for (x = iWidth / 8 - 1; x >= 0; x--)
+        {
+            const U8 v = piSrcPixel[x];
+
+			for (n = 0; n < 8; n++)
+			{
+                piDstPixel[8*x+n] = (((v >> (7 - n)) & 0x1) != 0) ^ bBlackWhite ? 0xFF : 0x00;
+			}
+        }
+    }
+    
+    return WMP_errSuccess;
+}
+
+
+ERR Gray16_Gray8(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    I32 i = 0, j = 0;
+
+    UNREFERENCED_PARAMETER( pFC );
+    
+    for (i = 0; i < pRect->Height; ++i)
+    {
+        for (j = 0; j < pRect->Width; ++j)
+        {
+            U16 v = ((U16*)pb)[j];
+            
+            pb[j] = v >> 8;
+        }
+
+        pb += cbStride;
+    }
+
+    return WMP_errSuccess;
+}
+
+ERR RGB48_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    // Stride is assumed to be same for src/dst
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        U8 *piDstPixel = (U8*)(pb + cbStride*y);
+        const U16 *piSrcPixel = (U16*)piDstPixel;
+
+        for (x = 0; x < iWidth; x++)
+        {
+            const U16 r = piSrcPixel[3*x];
+            const U16 g = piSrcPixel[3*x+1];
+            const U16 b = piSrcPixel[3*x+2];
+
+            piDstPixel[3*x] = r >> 8;
+            piDstPixel[3*x+1] = g >> 8;
+            piDstPixel[3*x+2] = b >> 8;
+        }
+    }
+
+    return WMP_errSuccess;
+}
+
+ERR RGBA64_RGBA32(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    // Stride is assumed to be same for src/dst
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        U8 *piDstPixel = (U8*)(pb + cbStride*y);
+        const U16 *piSrcPixel = (U16*)piDstPixel;
+
+        for (x = 0; x < iWidth; x++)
+        {
+            const U16 r = piSrcPixel[4*x];
+            const U16 g = piSrcPixel[4*x+1];
+            const U16 b = piSrcPixel[4*x+2];
+            const U16 a = piSrcPixel[4*x+3];
+
+            piDstPixel[4*x] = r >> 8;
+            piDstPixel[4*x+1] = g >> 8;
+            piDstPixel[4*x+2] = b >> 8;
+            piDstPixel[4*x+3] = a >> 8;
+        }
+    }
+
+    return WMP_errSuccess;
+}
+
+ERR Gray32Float_Gray8(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    // Stride is assumed to be same for src/dst
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        U8 *piDstPixel = (U8*)(pb + cbStride*y);
+        const float *piSrcPixel = (float*)piDstPixel;
+
+        for (x = 0; x < iWidth; x++)
+        {
+            const float v = piSrcPixel[x];
+                
+            piDstPixel[x] = Convert_Float_To_U8(v);
+        }
+    }
+
+    return WMP_errSuccess;
+}
+
+ERR RGB96Float_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    // Stride is assumed to be same for src/dst
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        U8 *piDstPixel = (U8*)(pb + cbStride*y);
+        const float *piSrcPixel = (float*)piDstPixel;
+
+        for (x = 0; x < iWidth; x++)
+        {
+            const float r = piSrcPixel[3*x];
+            const float g = piSrcPixel[3*x+1];
+            const float b = piSrcPixel[3*x+2];
+                
+            piDstPixel[3*x] = Convert_Float_To_U8(r);
+            piDstPixel[3*x+1] = Convert_Float_To_U8(g);
+            piDstPixel[3*x+2] = Convert_Float_To_U8(b);
+        }
+    }
+
+    return WMP_errSuccess;
+}
+
+ERR RGB128Float_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    // Stride is assumed to be same for src/dst
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        U8 *piDstPixel = (U8*)(pb + cbStride*y);
+        const float *piSrcPixel = (float*)piDstPixel;
+
+        for (x = 0; x < iWidth; x++)
+        {
+            const float r = piSrcPixel[4*x];
+            const float g = piSrcPixel[4*x+1];
+            const float b = piSrcPixel[4*x+2];
+                
+            piDstPixel[3*x] = Convert_Float_To_U8(r);
+            piDstPixel[3*x+1] = Convert_Float_To_U8(g);
+            piDstPixel[3*x+2] = Convert_Float_To_U8(b);
+        }
+    }
+
+    return WMP_errSuccess;
+}
+
+ERR RGBA128Float_RGBA32(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    // Stride is assumed to be same for src/dst
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        U8 *piDstPixel = (U8*)(pb + cbStride*y);
+        const float *piSrcPixel = (float*)piDstPixel;
+
+        for (x = 0; x < iWidth; x++)
+        {
+            const float r = piSrcPixel[4*x];
+            const float g = piSrcPixel[4*x+1];
+            const float b = piSrcPixel[4*x+2];
+            const float a = piSrcPixel[4*x+3];
+                
+            piDstPixel[4*x] = Convert_Float_To_U8(r);
+            piDstPixel[4*x+1] = Convert_Float_To_U8(g);
+            piDstPixel[4*x+2] = Convert_Float_To_U8(b);
+            piDstPixel[4*x+3] = Convert_AlphaFloat_To_U8(a);
+        }
+    }
+
+    return WMP_errSuccess;
+}
+
+ERR Gray16Fixed_Gray8(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    const float fltCvtFactor = 1.0F / (1 << 13);
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    // Stride is assumed to be same for src/dst
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        U8 *piDstPixel = (U8*)(pb + cbStride*y);
+        const I16 *piSrcPixel = (I16*)piDstPixel;
+
+        for (x = 0; x < iWidth; x++)
+        {
+            piDstPixel[x] = Convert_Float_To_U8(piSrcPixel[x] * fltCvtFactor);
+        }
+    }
+
+    return WMP_errSuccess;
+}
+
+ERR Gray32Fixed_Gray8(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    const float fltCvtFactor = 1.0F / (1 << 24);
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    // Stride is assumed to be same for src/dst
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        U8 *piDstPixel = (U8*)(pb + cbStride*y);
+        const I32 *piSrcPixel = (I32*)piDstPixel;
+
+        for (x = 0; x < iWidth; x++)
+        {
+            piDstPixel[x] = Convert_Float_To_U8(piSrcPixel[x] * fltCvtFactor);
+        }
+    }
+
+    return WMP_errSuccess;
+}
+
+ERR RGB48Fixed_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    const float fltCvtFactor = 1.0F / (1 << 13);
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        U8 *pfltDstPixel = (U8*)(pb + cbStride*y);
+        const I16 *piSrcPixel = (I16*)pfltDstPixel;
+
+        for (x = 0; x < iWidth; x++)
+        {
+            pfltDstPixel[3*x] = Convert_Float_To_U8(piSrcPixel[3*x] * fltCvtFactor);
+            pfltDstPixel[3*x+1] = Convert_Float_To_U8(piSrcPixel[3*x+1] * fltCvtFactor);
+            pfltDstPixel[3*x+2] = Convert_Float_To_U8(piSrcPixel[3*x+2] * fltCvtFactor);
+        }
+    }
+    
+    return WMP_errSuccess;
+}
+
+ERR RGB64Fixed_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    const float fltCvtFactor = 1.0F / (1 << 13);
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        U8 *pfltDstPixel = (U8*)(pb + cbStride*y);
+        const I16 *piSrcPixel = (I16*)pfltDstPixel;
+
+        for (x = 0; x < iWidth; x++)
+        {
+            pfltDstPixel[3*x] = Convert_Float_To_U8(piSrcPixel[4*x] * fltCvtFactor);
+            pfltDstPixel[3*x+1] = Convert_Float_To_U8(piSrcPixel[4*x+1] * fltCvtFactor);
+            pfltDstPixel[3*x+2] = Convert_Float_To_U8(piSrcPixel[4*x+2] * fltCvtFactor);
+        }
+    }
+    
+    return WMP_errSuccess;
+}
+
+ERR RGB96Fixed_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    const float fltCvtFactor = 1.0F / (1 << 24);
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        U8 *pfltDstPixel = (U8*)(pb + cbStride*y);
+        const I32 *piSrcPixel = (I32*)pfltDstPixel;
+
+        for (x = 0; x < iWidth; x++)
+        {
+            pfltDstPixel[3*x] = Convert_Float_To_U8(piSrcPixel[3*x] * fltCvtFactor);
+            pfltDstPixel[3*x+1] = Convert_Float_To_U8(piSrcPixel[3*x+1] * fltCvtFactor);
+            pfltDstPixel[3*x+2] = Convert_Float_To_U8(piSrcPixel[3*x+2] * fltCvtFactor);
+        }
+    }
+    
+    return WMP_errSuccess;
+}
+
+ERR RGB128Fixed_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    const float fltCvtFactor = 1.0F / (1 << 24);
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        U8 *pfltDstPixel = (U8*)(pb + cbStride*y);
+        const I32 *piSrcPixel = (I32*)pfltDstPixel;
+
+        for (x = 0; x < iWidth; x++)
+        {
+            pfltDstPixel[3*x] = Convert_Float_To_U8(piSrcPixel[4*x] * fltCvtFactor);
+            pfltDstPixel[3*x+1] = Convert_Float_To_U8(piSrcPixel[4*x+1] * fltCvtFactor);
+            pfltDstPixel[3*x+2] = Convert_Float_To_U8(piSrcPixel[4*x+2] * fltCvtFactor);
+        }
+    }
+    
+    return WMP_errSuccess;
+}
+
+ERR RGBA64Fixed_RGBA32(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    const float fltCvtFactor = 1.0F / (1 << 13);
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        U8 *pfltDstPixel = (U8*)(pb + cbStride*y);
+        const I16 *piSrcPixel = (I16*)pfltDstPixel;
+
+        for (x = 0; x < iWidth; x++)
+        {
+            pfltDstPixel[4*x] = Convert_Float_To_U8(piSrcPixel[4*x] * fltCvtFactor);
+            pfltDstPixel[4*x+1] = Convert_Float_To_U8(piSrcPixel[4*x+1] * fltCvtFactor);
+            pfltDstPixel[4*x+2] = Convert_Float_To_U8(piSrcPixel[4*x+2] * fltCvtFactor);
+            pfltDstPixel[4*x+3] = Convert_AlphaFloat_To_U8(piSrcPixel[4*x+3] * fltCvtFactor);
+        }
+    }
+    
+    return WMP_errSuccess;
+}
+
+ERR RGBA128Fixed_RGBA32(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    const float fltCvtFactor = 1.0F / (1 << 24);
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        U8 *pfltDstPixel = (U8*)(pb + cbStride*y);
+        const I32 *piSrcPixel = (I32*)pfltDstPixel;
+
+        for (x = 0; x < iWidth; x++)
+        {
+            pfltDstPixel[4*x] = Convert_Float_To_U8(piSrcPixel[4*x] * fltCvtFactor);
+            pfltDstPixel[4*x+1] = Convert_Float_To_U8(piSrcPixel[4*x+1] * fltCvtFactor);
+            pfltDstPixel[4*x+2] = Convert_Float_To_U8(piSrcPixel[4*x+2] * fltCvtFactor);
+            pfltDstPixel[4*x+3] = Convert_AlphaFloat_To_U8(piSrcPixel[4*x+3] * fltCvtFactor);
+        }
+    }
+    
+    return WMP_errSuccess;
+}
+
+ERR Gray16Half_Gray8(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    // Stride is assumed to be same for src/dst
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        U8 *piDstPixel = (U8*)(pb + cbStride*y);
+        const U16 *piSrcPixel = (U16*)piDstPixel;
+
+        for (x = 0; x < iWidth; x++)
+        {
+            const U32 v = Convert_Half_To_Float(piSrcPixel[x]);
+                
+            piDstPixel[x] = Convert_Float_To_U8(*(float*)&v);
+        }
+    }
+
+    return WMP_errSuccess;
+}
+
+ERR RGB48Half_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        U8 *pfltDstPixel = (U8*)(pb + cbStride*y);
+        const U16 *piSrcPixel = (U16*)pfltDstPixel;
+
+        for (x = 0; x < iWidth; x++)
+        {
+            const U32 r = Convert_Half_To_Float(piSrcPixel[3*x]);
+            const U32 g = Convert_Half_To_Float(piSrcPixel[3*x+1]);
+            const U32 b = Convert_Half_To_Float(piSrcPixel[3*x+2]);
+        
+            pfltDstPixel[3*x] = Convert_Float_To_U8(*(float*)&r);
+            pfltDstPixel[3*x+1] = Convert_Float_To_U8(*(float*)&g);
+            pfltDstPixel[3*x+2] = Convert_Float_To_U8(*(float*)&b);
+        }
+    }
+    
+    return WMP_errSuccess;
+}
+
+ERR RGB64Half_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        U8 *pfltDstPixel = (U8*)(pb + cbStride*y);
+        const U16 *piSrcPixel = (U16*)pfltDstPixel;
+
+        for (x = 0; x < iWidth; x++)
+        {
+            const U32 r = Convert_Half_To_Float(piSrcPixel[4*x]);
+            const U32 g = Convert_Half_To_Float(piSrcPixel[4*x+1]);
+            const U32 b = Convert_Half_To_Float(piSrcPixel[4*x+2]);
+        
+            pfltDstPixel[3*x] = Convert_Float_To_U8(*(float*)&r);
+            pfltDstPixel[3*x+1] = Convert_Float_To_U8(*(float*)&g);
+            pfltDstPixel[3*x+2] = Convert_Float_To_U8(*(float*)&b);
+        }
+    }
+    
+    return WMP_errSuccess;
+}
+
+ERR RGBA64Half_RGBA32(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        U8 *pfltDstPixel = (U8*)(pb + cbStride*y);
+        const U16 *piSrcPixel = (U16*)pfltDstPixel;
+
+        for (x = 0; x < iWidth; x++)
+        {
+            const U32 r = Convert_Half_To_Float(piSrcPixel[4*x]);
+            const U32 g = Convert_Half_To_Float(piSrcPixel[4*x+1]);
+            const U32 b = Convert_Half_To_Float(piSrcPixel[4*x+2]);
+            const U32 a = Convert_Half_To_Float(piSrcPixel[4*x+3]);
+        
+            pfltDstPixel[4*x] = Convert_Float_To_U8(*(float*)&r);
+            pfltDstPixel[4*x+1] = Convert_Float_To_U8(*(float*)&g);
+            pfltDstPixel[4*x+2] = Convert_Float_To_U8(*(float*)&b);
+            pfltDstPixel[4*x+3] = Convert_AlphaFloat_To_U8(*(float*)&a);
+        }
+    }
+    
+    return WMP_errSuccess;
+}
+
+ERR RGB101010_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    const I32 iHeight = pRect->Height;
+    const I32 iWidth = pRect->Width;
+    I32 y;
+
+    UNREFERENCED_PARAMETER( pFC );
+
+    // Stride is assumed to be same for src/dst
+    for (y = 0; y < iHeight; y++)
+    {
+        I32 x;
+        U8 *piDstPixel = (U8*)(pb + cbStride*y);
+        const U32 *piSrcPixel = (U32*)piDstPixel;
+
+        for (x = 0; x < iWidth; x++)
+        {
+            const U32 v = piSrcPixel[x];
+            const unsigned int r = ((v >> 20) & 0x3FF);
+            const unsigned int g = ((v >> 10) & 0x3FF);
+            const unsigned int b = (v & 0x3FF);
+
+            piDstPixel[3*x] = (U8) (r >> 2);
+            piDstPixel[3*x+1] = (U8) (g >> 2);
+            piDstPixel[3*x+2] = (U8) (b >> 2);
+        }
+    }
+
+    return WMP_errSuccess;
+}
+
+ERR RGBE_RGB24(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    I32 i = 0, j = 0;
+
+    UNREFERENCED_PARAMETER( pFC );
+   
+    for (i = 0; i < pRect->Height; ++i)
+    {
+        for (j = 0; j < pRect->Width; j++)
+        {
+            // First read the exponent
+            const U8 rawExp = pb[4*j+3];
+
+            if (0 == rawExp)
+            {
+                pb[3*j] = 0;
+                pb[3*j+1] = 0;
+                pb[3*j+2] = 0;
+            }
+            else
+            {
+                const I32 adjExp = (I32)rawExp - 128 - 8; // Can be negative
+                float fltExp;
+
+                if (adjExp > -32 && adjExp < 32)
+                {
+                    fltExp = (float) (((U32)1) << abs(adjExp));
+                    if (adjExp < 0)
+                        fltExp = 1.0F / fltExp;
+                }
+                else
+                {
+                    fltExp = (float)ldexp(1.0F, adjExp);
+                }
+
+                pb[3*j] = Convert_Float_To_U8(pb[4*j] * fltExp);
+                pb[3*j + 1] = Convert_Float_To_U8(pb[4*j + 1] * fltExp);
+                pb[3*j + 2] = Convert_Float_To_U8(pb[4*j + 2] * fltExp);
+            }
+        }
+
+        pb += cbStride;
+    }
+
+    return WMP_errSuccess;
+}
+
+//================================================================
+typedef struct tagPKPixelConverterInfo
+{
+    const PKPixelFormatGUID* pGUIDPixFmtFrom;
+    const PKPixelFormatGUID* pGUIDPixFmtTo;
+
+    ERR (*Convert)(PKFormatConverter*, const PKRect*, U8*, U32);
+} PKPixelConverterInfo;
+
+static PKPixelConverterInfo s_pcInfo[] = {
+    {&GUID_PKPixelFormat24bppRGB, &GUID_PKPixelFormat24bppBGR, RGB24_BGR24}, // Fwd
+    {&GUID_PKPixelFormat24bppBGR, &GUID_PKPixelFormat24bppRGB, BGR24_RGB24}, // Rev
+    {&GUID_PKPixelFormat24bppRGB, &GUID_PKPixelFormat32bppBGR, RGB24_BGR32}, // Fwd
+    {&GUID_PKPixelFormat32bppBGR, &GUID_PKPixelFormat24bppRGB, BGR32_RGB24}, // Rev
+
+    // The following are not to be exposed when building the Adobe Photoshop plugin
+#ifndef ADOBE_PS_PLUGIN
+    {&GUID_PKPixelFormat24bppRGB, &GUID_PKPixelFormat8bppGray, RGB24_Gray8}, // Fwd
+    {&GUID_PKPixelFormat8bppGray, &GUID_PKPixelFormat24bppRGB, Gray8_RGB24}, // Rev
+    {&GUID_PKPixelFormat24bppBGR, &GUID_PKPixelFormat8bppGray, BGR24_Gray8}, // Fwd
+    {&GUID_PKPixelFormat8bppGray, &GUID_PKPixelFormat24bppBGR, Gray8_BGR24}, // Rev
+#endif // ADOBE_PS_PLUGIN
+
+    {&GUID_PKPixelFormat128bppRGBAFixedPoint, &GUID_PKPixelFormat128bppRGBAFloat, RGBA128Fixed_RGBA128Float}, // Fwd
+    {&GUID_PKPixelFormat128bppRGBAFloat, &GUID_PKPixelFormat128bppRGBAFixedPoint, RGBA128Float_RGBA128Fixed}, // Rev
+    {&GUID_PKPixelFormat96bppRGBFixedPoint, &GUID_PKPixelFormat96bppRGBFloat, RGB96Fixed_RGB96Float}, // Fwd
+    {&GUID_PKPixelFormat96bppRGBFloat, &GUID_PKPixelFormat96bppRGBFixedPoint, RGB96Float_RGB96Fixed}, // Rev
+    {&GUID_PKPixelFormat96bppRGBFloat, &GUID_PKPixelFormat128bppRGBFloat, RGB96Float_RGB128Float}, // Fwd
+    {&GUID_PKPixelFormat128bppRGBFloat, &GUID_PKPixelFormat96bppRGBFloat, RGB128Float_RGB96Float}, // Rev
+    {&GUID_PKPixelFormat96bppRGBFixedPoint, &GUID_PKPixelFormat128bppRGBFixedPoint, RGB96Float_RGB128Float}, // Fwd
+    {&GUID_PKPixelFormat128bppRGBFixedPoint, &GUID_PKPixelFormat96bppRGBFixedPoint, RGB128Float_RGB96Float}, // Rev
+    {&GUID_PKPixelFormat64bppRGBHalf, &GUID_PKPixelFormat48bppRGBHalf, RGB64Half_RGB48Half}, // Fwd
+    {&GUID_PKPixelFormat48bppRGBHalf, &GUID_PKPixelFormat64bppRGBHalf, RGB48Half_RGB64Half}, // Rev
+    {&GUID_PKPixelFormat64bppRGBFixedPoint, &GUID_PKPixelFormat48bppRGBFixedPoint, RGB64Half_RGB48Half}, // Fwd
+    {&GUID_PKPixelFormat48bppRGBFixedPoint, &GUID_PKPixelFormat64bppRGBFixedPoint, RGB48Half_RGB64Half}, // Rev
+    {&GUID_PKPixelFormat32bppBGR, &GUID_PKPixelFormat24bppBGR, BGR32_BGR24}, // Fwd
+    {&GUID_PKPixelFormat24bppBGR, &GUID_PKPixelFormat32bppBGR, BGR24_BGR32}, // Rev
+    {&GUID_PKPixelFormat96bppRGBFloat, &GUID_PKPixelFormat128bppRGBFixedPoint, RGB96Float_RGB128Fixed}, // Fwd
+    {&GUID_PKPixelFormat128bppRGBFixedPoint, &GUID_PKPixelFormat96bppRGBFloat, RGB128Fixed_RGB96Float}, // Rev
+    {&GUID_PKPixelFormat32bppGrayFixedPoint, &GUID_PKPixelFormat32bppGrayFloat, Gray32Fixed_Gray32Float}, // Fwd
+    {&GUID_PKPixelFormat32bppGrayFloat, &GUID_PKPixelFormat32bppGrayFixedPoint, Gray32Float_Gray32Fixed}, // Rev
+    {&GUID_PKPixelFormat16bppGrayFixedPoint, &GUID_PKPixelFormat32bppGrayFloat, Gray16Fixed_Gray32Float}, // Fwd
+    {&GUID_PKPixelFormat32bppGrayFloat, &GUID_PKPixelFormat16bppGrayFixedPoint, Gray32Float_Gray16Fixed}, // Rev
+    {&GUID_PKPixelFormat48bppRGBFixedPoint, &GUID_PKPixelFormat96bppRGBFloat, RGB48Fixed_RGB96Float}, // Fwd
+    {&GUID_PKPixelFormat96bppRGBFloat, &GUID_PKPixelFormat48bppRGBFixedPoint, RGB96Float_RGB48Fixed}, // Rev
+    {&GUID_PKPixelFormat64bppRGBFixedPoint, &GUID_PKPixelFormat96bppRGBFloat, RGB64Fixed_RGB96Float}, // Fwd
+    {&GUID_PKPixelFormat96bppRGBFloat, &GUID_PKPixelFormat64bppRGBFixedPoint, RGB96Float_RGB64Fixed}, // Rev
+    {&GUID_PKPixelFormat64bppRGBAFixedPoint, &GUID_PKPixelFormat128bppRGBAFloat, RGBA64Fixed_RGBA128Float}, // Fwd
+    {&GUID_PKPixelFormat128bppRGBAFloat, &GUID_PKPixelFormat64bppRGBAFixedPoint, RGBA128Float_RGBA64Fixed}, // Rev
+    {&GUID_PKPixelFormat32bppRGBE, &GUID_PKPixelFormat96bppRGBFloat, RGBE_RGB96Float}, // Fwd
+    {&GUID_PKPixelFormat96bppRGBFloat, &GUID_PKPixelFormat32bppRGBE, RGB96Float_RGBE}, // Rev
+    {&GUID_PKPixelFormat64bppRGBAHalf, &GUID_PKPixelFormat128bppRGBAFloat, RGBA64Half_RGBA128Float}, // Fwd
+    {&GUID_PKPixelFormat128bppRGBAFloat, &GUID_PKPixelFormat64bppRGBAHalf, RGBA128Float_RGBA64Half}, // Rev
+    {&GUID_PKPixelFormat64bppRGBHalf, &GUID_PKPixelFormat96bppRGBFloat, RGB64Half_RGB96Float}, // Fwd
+    {&GUID_PKPixelFormat96bppRGBFloat, &GUID_PKPixelFormat64bppRGBHalf, RGB96Float_RGB64Half}, // Rev
+    {&GUID_PKPixelFormat48bppRGBHalf, &GUID_PKPixelFormat96bppRGBFloat, RGB48Half_RGB96Float}, // Fwd
+    {&GUID_PKPixelFormat96bppRGBFloat, &GUID_PKPixelFormat48bppRGBHalf, RGB96Float_RGB48Half}, // Rev
+    {&GUID_PKPixelFormat16bppGrayHalf, &GUID_PKPixelFormat32bppGrayFloat, Gray16Half_Gray32Float}, // Fwd
+    {&GUID_PKPixelFormat32bppGrayFloat, &GUID_PKPixelFormat16bppGrayHalf, Gray32Float_Gray16Half}, // Rev
+    {&GUID_PKPixelFormat16bppRGB555, &GUID_PKPixelFormat24bppRGB, RGB555_RGB24}, // Fwd
+    {&GUID_PKPixelFormat24bppRGB, &GUID_PKPixelFormat16bppRGB555, RGB24_RGB555}, // Rev
+    {&GUID_PKPixelFormat16bppRGB565, &GUID_PKPixelFormat24bppRGB, RGB565_RGB24}, // Fwd
+    {&GUID_PKPixelFormat24bppRGB, &GUID_PKPixelFormat16bppRGB565, RGB24_RGB565}, // Rev
+    {&GUID_PKPixelFormat32bppRGB101010, &GUID_PKPixelFormat48bppRGB, RGB101010_RGB48}, // Fwd
+    {&GUID_PKPixelFormat48bppRGB, &GUID_PKPixelFormat32bppRGB101010, RGB48_RGB101010}, // Rev
+    {&GUID_PKPixelFormat32bppRGBA, &GUID_PKPixelFormat32bppBGRA, RGBA32_BGRA32}, // Fwd
+    {&GUID_PKPixelFormat32bppBGRA, &GUID_PKPixelFormat32bppRGBA, BGRA32_RGBA32}, // Rev
+    {&GUID_PKPixelFormat32bppPRGBA, &GUID_PKPixelFormat32bppPBGRA, RGBA32_BGRA32}, // Fwd
+    {&GUID_PKPixelFormat32bppPBGRA, &GUID_PKPixelFormat32bppPRGBA, BGRA32_RGBA32}, // Rev
+
+	// conversions to 8bppGray / 24bppRGB / 32bppRGBA
+	{&GUID_PKPixelFormatBlackWhite, &GUID_PKPixelFormat8bppGray, BlackWhite_Gray8},
+    {&GUID_PKPixelFormat16bppGray, &GUID_PKPixelFormat8bppGray, Gray16_Gray8},
+    {&GUID_PKPixelFormat48bppRGB, &GUID_PKPixelFormat24bppRGB, RGB48_RGB24},
+    {&GUID_PKPixelFormat64bppRGBA, &GUID_PKPixelFormat32bppRGBA, RGBA64_RGBA32},
+    {&GUID_PKPixelFormat32bppGrayFloat, &GUID_PKPixelFormat8bppGray, Gray32Float_Gray8},     
+    {&GUID_PKPixelFormat96bppRGBFloat, &GUID_PKPixelFormat24bppRGB, RGB96Float_RGB24},
+    {&GUID_PKPixelFormat128bppRGBFloat, &GUID_PKPixelFormat24bppRGB, RGB128Float_RGB24},
+    {&GUID_PKPixelFormat128bppRGBAFloat, &GUID_PKPixelFormat32bppRGBA, RGBA128Float_RGBA32},
+    {&GUID_PKPixelFormat16bppGrayFixedPoint, &GUID_PKPixelFormat8bppGray, Gray16Fixed_Gray8}, 
+    {&GUID_PKPixelFormat32bppGrayFixedPoint, &GUID_PKPixelFormat8bppGray, Gray32Fixed_Gray8},  
+    {&GUID_PKPixelFormat48bppRGBFixedPoint, &GUID_PKPixelFormat24bppRGB, RGB48Fixed_RGB24},
+    {&GUID_PKPixelFormat64bppRGBFixedPoint, &GUID_PKPixelFormat24bppRGB, RGB64Fixed_RGB24},
+    {&GUID_PKPixelFormat96bppRGBFixedPoint, &GUID_PKPixelFormat24bppRGB, RGB96Fixed_RGB24},
+    {&GUID_PKPixelFormat128bppRGBFixedPoint, &GUID_PKPixelFormat24bppRGB, RGB128Fixed_RGB24},   
+    {&GUID_PKPixelFormat64bppRGBAFixedPoint, &GUID_PKPixelFormat32bppRGBA, RGBA64Fixed_RGBA32},
+    {&GUID_PKPixelFormat128bppRGBAFixedPoint, &GUID_PKPixelFormat32bppRGBA, RGBA128Fixed_RGBA32},    
+    {&GUID_PKPixelFormat16bppGrayHalf, &GUID_PKPixelFormat8bppGray, Gray16Half_Gray8},     
+    {&GUID_PKPixelFormat48bppRGBHalf, &GUID_PKPixelFormat24bppRGB, RGB48Half_RGB24},
+    {&GUID_PKPixelFormat64bppRGBHalf, &GUID_PKPixelFormat24bppRGB, RGB64Half_RGB24},
+    {&GUID_PKPixelFormat64bppRGBAHalf, &GUID_PKPixelFormat32bppRGBA, RGBA64Half_RGBA32},
+    {&GUID_PKPixelFormat32bppRGB101010, &GUID_PKPixelFormat24bppRGB, RGB101010_RGB24},    
+    {&GUID_PKPixelFormat32bppRGBE, &GUID_PKPixelFormat24bppRGB, RGBE_RGB24}
+};
+
+/* auxiliary data structure and hack to support valid encoding from/to configurations that 
+// don't actually require any color conversion. This is a conservative approach, where we
+// include as few formats as necessary to encode situations that we're currently aware of.
+*/
+typedef struct tagPKPixelConverter2Info
+{
+    const PKPixelFormatGUID* pGUIDPixFmtFrom;
+    const PKPixelFormatGUID* pGUIDPixFmtTo;
+
+} PKPixelConverter2Info;
+
+static PKPixelConverter2Info s_pcInfo2[] = {
+	// This allows us to view an RGBA input file as RGB, for when we create a planar alpha file
+	{&GUID_PKPixelFormat128bppRGBFloat, &GUID_PKPixelFormat128bppRGBAFloat},
+	// 16- and 32-bpp RGB input files are given the "DontCare" GUID, so the next three 
+	// from/to combinations are ok, and allowed on encoding: 
+	{&GUID_PKPixelFormatDontCare, &GUID_PKPixelFormat16bppRGB555},
+	{&GUID_PKPixelFormatDontCare, &GUID_PKPixelFormat16bppRGB565},
+	{&GUID_PKPixelFormatDontCare, &GUID_PKPixelFormat32bppBGRA}
+};
+
+ERR PKFormatConverter_Initialize(PKFormatConverter* pFC, PKImageDecode* pID, char *pExt, PKPixelFormatGUID enPF)
+{
+    ERR err;
+    PKPixelFormatGUID   enPFFrom;
+
+    Call(pID->GetPixelFormat(pID, &enPFFrom));
+    Call(PKFormatConverter_InitializeConvert(pFC, enPFFrom, pExt, enPF));
+
+    pFC->pDecoder = pID;
+
+Cleanup:
+    return err;
+}
+
+
+extern int PKStrnicmp(const char* s1, const char* s2, size_t c);
+
+ERR PKFormatConverter_InitializeConvert(PKFormatConverter* pFC, const PKPixelFormatGUID enPFFrom,
+                                        char *pExt, PKPixelFormatGUID enPFTo)
+{
+    ERR err = WMP_errSuccess;
+
+    //================================
+    pFC->enPixelFormat = enPFTo;
+
+    if (pExt != NULL && IsEqualGUID(&enPFTo, &GUID_PKPixelFormat24bppRGB) &&
+        0 == PKStrnicmp(pExt, ".bmp", strlen(pExt)))
+        enPFTo = GUID_PKPixelFormat24bppBGR;
+    if (pExt != NULL && (0 == PKStrnicmp(pExt, ".tif", strlen(pExt)) || 0 == PKStrnicmp(pExt, ".tiff", strlen(pExt))))
+    {
+        if (IsEqualGUID(&enPFTo, &GUID_PKPixelFormat32bppBGRA))
+            enPFTo = GUID_PKPixelFormat32bppRGBA;
+        if (IsEqualGUID(&enPFTo, &GUID_PKPixelFormat32bppPBGRA))
+            enPFTo = GUID_PKPixelFormat32bppPRGBA;
+    }
+
+    //================================
+    if (!IsEqualGUID(&enPFFrom, &enPFTo))
+    {
+        size_t i = 0;
+        for (i = 0; i < sizeof2(s_pcInfo); ++i)
+        {
+            PKPixelConverterInfo* pPCI = s_pcInfo + i;
+
+            if (IsEqualGUID(&enPFFrom, pPCI->pGUIDPixFmtFrom) && IsEqualGUID(&enPFTo, pPCI->pGUIDPixFmtTo))
+            {
+                pFC->Convert= pPCI->Convert;
+                goto Cleanup;
+            }
+        }
+        // Bugfix to allow legitimate encoding from/to combinations that don't actually 
+        // involve color conversions. 
+        for (i = 0; i < sizeof2(s_pcInfo2); ++i)
+        {
+            PKPixelConverter2Info* pPCI = s_pcInfo2 + i;
+
+            if (IsEqualGUID(&enPFFrom, pPCI->pGUIDPixFmtFrom) && IsEqualGUID(&enPFTo, pPCI->pGUIDPixFmtTo))
+            {
+                goto Cleanup;
+            }
+        }
+        // If we failed the original check, and this bugfix check, then exit with error
+        Call(WMP_errUnsupportedFormat);
+    }
+
+Cleanup:
+    return err;
+}
+
+ERR PKFormatConverter_EnumConversions(const PKPixelFormatGUID *pguidSourcePF,
+                                      const U32 iIndex,
+                                      const PKPixelFormatGUID **ppguidTargetPF)
+{
+    U32 iCurrIdx = 0;
+    U32 i;
+    ERR errResult = WMP_errIndexNotFound;
+
+    *ppguidTargetPF = &GUID_PKPixelFormatDontCare; // Init return value
+    for (i = 0; i < sizeof2(s_pcInfo); i++)
+    {
+        if (IsEqualGUID(s_pcInfo[i].pGUIDPixFmtFrom, pguidSourcePF))
+        {
+            if (iCurrIdx == iIndex)
+            {
+                // Found our target
+                errResult = WMP_errSuccess;
+                *ppguidTargetPF = s_pcInfo[i].pGUIDPixFmtTo;
+                break;
+            }
+            iCurrIdx += 1;
+        }
+    }
+
+    return errResult;
+}
+
+ERR PKFormatConverter_GetPixelFormat(PKFormatConverter* pFC, PKPixelFormatGUID* pPF)
+{
+    *pPF = pFC->enPixelFormat;
+
+    return WMP_errSuccess;
+}
+
+ERR PKFormatConverter_GetSourcePixelFormat(PKFormatConverter* pFC, PKPixelFormatGUID* pPF)
+{
+    return pFC->pDecoder->GetPixelFormat(pFC->pDecoder, pPF);
+}
+
+ERR PKFormatConverter_GetSize(PKFormatConverter* pFC, I32* piWidth, I32* piHeight)
+{
+    return pFC->pDecoder->GetSize(pFC->pDecoder, piWidth, piHeight);
+}
+
+ERR PKFormatConverter_GetResolution(PKFormatConverter* pFC, Float* pfrX, Float* pfrY)
+{
+    return pFC->pDecoder->GetResolution(pFC->pDecoder, pfrX, pfrY);
+}
+
+ERR PKFormatConverter_Copy(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    ERR err = WMP_errSuccess;
+
+    Call(pFC->pDecoder->Copy(pFC->pDecoder, pRect, pb, cbStride));
+    Call(pFC->Convert(pFC, pRect, pb, cbStride));
+
+Cleanup:
+    return err;
+}
+
+ERR PKFormatConverter_Convert(PKFormatConverter* pFC, const PKRect* pRect, U8* pb, U32 cbStride)
+{
+    UNREFERENCED_PARAMETER( pFC );
+    UNREFERENCED_PARAMETER( pRect );
+    UNREFERENCED_PARAMETER( pb );
+    UNREFERENCED_PARAMETER( cbStride );
+
+    return WMP_errSuccess;
+}
+
+ERR PKFormatConverter_Release(PKFormatConverter** ppFC)
+{
+    ERR err = WMP_errSuccess;
+
+    Call(PKFree((void **) ppFC));
+
+Cleanup:
+    return err;
+}
+
diff --git a/Source/LibJXR/jxrgluelib/JXRMeta.c b/Source/LibJXR/jxrgluelib/JXRMeta.c
new file mode 100644
index 0000000..3fd2f79
--- /dev/null
+++ b/Source/LibJXR/jxrgluelib/JXRMeta.c
@@ -0,0 +1,905 @@
+//*@@@+++@@@@******************************************************************
+//
+// Copyright � Microsoft Corp.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+// � Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// � Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//*@@@---@@@@******************************************************************
+#include "JXRMeta.h"
+#include "JXRGlue.h"
+
+
+
+// read and write big and little endian words/dwords from a buffer on both big and little endian cpu's
+// with full buffer overflow checking
+
+
+
+ERR getbfcpy(U8* pbdest, const U8* pb, size_t cb, size_t ofs, U32 n)
+{
+    ERR err = WMP_errSuccess;
+    FailIf(ofs + n > cb, WMP_errBufferOverflow);
+    memcpy(pbdest, &pb[ofs], n);
+Cleanup:
+    return err;
+}
+
+
+
+ERR getbfw(const U8* pb, size_t cb, size_t ofs, U16* pw)
+{
+    ERR err = WMP_errSuccess;
+    FailIf(ofs + sizeof(U16) > cb, WMP_errBufferOverflow);
+    *pw = (U16)( pb[ofs] + ( pb[ofs + 1] << 8 ) );
+Cleanup:
+    return err;
+}
+
+
+
+ERR getbfdw(const U8* pb, size_t cb, size_t ofs, U32* pdw)
+{
+    ERR err = WMP_errSuccess;
+    FailIf(ofs + sizeof(U32) > cb, WMP_errBufferOverflow);
+    *pdw = pb[ofs] + ( pb[ofs + 1] << 8 ) + ( pb[ofs + 2] << 16UL ) + ( pb[ofs + 3] << 24UL );
+Cleanup:
+    return err;
+}
+
+
+
+ERR getbfwbig(const U8* pb, size_t cb, size_t ofs, U16* pw)
+{
+    ERR err = WMP_errSuccess;
+    FailIf(ofs + sizeof(U16) > cb, WMP_errBufferOverflow);
+    *pw = (U16)( pb[ofs + 1] + ( pb[ofs] << 8 ) );
+Cleanup:
+    return err;
+}
+
+
+
+ERR getbfdwbig(const U8* pb, size_t cb, size_t ofs, U32* pdw)
+{
+    ERR err = WMP_errSuccess;
+    FailIf(ofs + sizeof(U32) > cb, WMP_errBufferOverflow);
+    *pdw = pb[ofs + 3] + ( pb[ofs + 2] << 8 ) + ( pb[ofs + 1] << 16UL ) + ( pb[ofs] << 24UL );
+Cleanup:
+    return err;
+}
+
+
+
+ERR getbfwe(const U8* pb, size_t cb, size_t ofs, U16* pw, U8 endian)
+{
+    if ( endian == WMP_INTEL_ENDIAN )
+        return ( getbfw(pb, cb, ofs, pw) );
+    else
+        return ( getbfwbig(pb, cb, ofs, pw) );
+}
+
+
+
+ERR getbfdwe(const U8* pb, size_t cb, size_t ofs, U32* pdw, U8 endian)
+{
+    if ( endian == WMP_INTEL_ENDIAN )
+        return ( getbfdw(pb, cb, ofs, pdw) );
+    else
+        return ( getbfdwbig(pb, cb, ofs, pdw) );
+}
+
+
+
+ERR setbfcpy(U8* pb, size_t cb, size_t ofs, const U8* pbset, size_t cbset)
+{
+    ERR err = WMP_errSuccess;
+    FailIf(ofs + cbset > cb, WMP_errBufferOverflow);
+    memcpy(&pb[ofs], pbset, cbset);
+Cleanup:
+    return err;
+}
+
+
+
+ERR setbfw(U8* pb, size_t cb, size_t ofs, U16 dw)
+{
+    ERR err = WMP_errSuccess;
+    FailIf(ofs + sizeof(U16) > cb, WMP_errBufferOverflow);
+    pb[ofs] = (U8)dw;
+    pb[ofs + 1] = (U8)( dw >> 8 );
+Cleanup:
+    return err;
+}
+
+
+
+ERR setbfdw(U8* pb, size_t cb, size_t ofs, U32 dw)
+{
+    ERR err = WMP_errSuccess;
+    FailIf(ofs + sizeof(U32) > cb, WMP_errBufferOverflow);
+    pb[ofs] = (U8)dw;
+    pb[ofs + 1] = (U8)( dw >> 8 );
+    pb[ofs + 2] = (U8)( dw >> 16 );
+    pb[ofs + 3] = (U8)( dw >> 24 );
+Cleanup:
+    return err;
+}
+
+
+
+ERR setbfwbig(U8* pb, size_t cb, size_t ofs, U16 dw)
+{
+    ERR err = WMP_errSuccess;
+    FailIf(ofs + sizeof(U16) > cb, WMP_errBufferOverflow);
+    pb[ofs + 1] = (U8)dw;
+    pb[ofs] = (U8)( dw >> 8 );
+Cleanup:
+    return err;
+}
+
+
+
+ERR setbfdwbig(U8* pb, size_t cb, size_t ofs, U32 dw)
+{
+    ERR err = WMP_errSuccess;
+    FailIf(ofs + sizeof(U32) > cb, WMP_errBufferOverflow);
+    pb[ofs + 3] = (U8)dw;
+    pb[ofs + 2] = (U8)( dw >> 8 );
+    pb[ofs + 1] = (U8)( dw >> 16 );
+    pb[ofs] = (U8)( dw >> 24 );
+Cleanup:
+    return err;
+}
+
+
+
+//================================================================
+// BufferCalcIFDSize (arbitrary endian)
+// StreamCalcIFDSize (little endian)
+//
+// count up the number of bytes needed to store the IFD and all
+// associated data including a subordinate interoperability IFD if any
+//================================================================
+
+
+
+ERR BufferCalcIFDSize(const U8* pbdata, size_t cbdata, U32 ofsifd, U8 endian, U32* pcbifd)
+{
+    ERR err = WMP_errSuccess;
+    U16 cDir;
+    U16 i;
+    U32 ofsdir;
+    U32 cbifd = 0;
+    U32 cbEXIFIFD = 0;
+    U32 cbGPSInfoIFD = 0;
+    U32 cbInteroperabilityIFD = 0;
+
+    *pcbifd = 0;
+    Call(getbfwe(pbdata, cbdata, ofsifd, &cDir, endian));
+
+    cbifd = sizeof(U16) + cDir * SizeofIFDEntry + sizeof(U32);
+    ofsdir = ofsifd + sizeof(U16);
+    for ( i = 0; i < cDir; i++ )
+    {
+        U16 tag;
+        U16 type;
+        U32 count;
+        U32 value;
+        U32 datasize;
+
+        Call(getbfwe(pbdata, cbdata, ofsdir, &tag, endian));
+        Call(getbfwe(pbdata, cbdata, ofsdir + sizeof(U16), &type, endian));
+        Call(getbfdwe(pbdata, cbdata, ofsdir + 2 * sizeof(U16), &count, endian));
+        Call(getbfdwe(pbdata, cbdata, ofsdir + 2 * sizeof(U16) + sizeof(U32), &value, endian));
+        FailIf(type == 0 || type >= sizeof(IFDEntryTypeSizes) / sizeof(IFDEntryTypeSizes[0]), WMP_errFail);
+        if ( tag == WMP_tagEXIFMetadata )
+        {
+            Call(BufferCalcIFDSize(pbdata, cbdata, value, endian, &cbEXIFIFD));
+        }
+        else if ( tag == WMP_tagGPSInfoMetadata )
+        {
+            Call(BufferCalcIFDSize(pbdata, cbdata, value, endian, &cbGPSInfoIFD));
+        }
+        else if ( tag == WMP_tagInteroperabilityIFD )
+        {
+            Call(BufferCalcIFDSize(pbdata, cbdata, value, endian, &cbInteroperabilityIFD));
+        }
+        else
+        {
+            datasize = IFDEntryTypeSizes[type] * count;
+            if ( datasize > 4 )
+                cbifd += datasize;
+        }
+        ofsdir += SizeofIFDEntry;
+    }
+    if ( cbEXIFIFD != 0 )
+        cbifd += ( cbifd & 1 ) + cbEXIFIFD;
+    if ( cbGPSInfoIFD != 0 )
+        cbifd += ( cbifd & 1 ) + cbGPSInfoIFD;
+    if ( cbInteroperabilityIFD != 0 )
+        cbifd += ( cbifd & 1 ) + cbInteroperabilityIFD;
+
+    *pcbifd = cbifd;
+
+Cleanup:
+    return err;
+}
+
+
+ERR StreamCalcIFDSize(struct WMPStream* pWS, U32 uIFDOfs, U32 *pcbifd)
+{
+    ERR err = WMP_errSuccess;
+    size_t offCurPos = 0;
+    Bool GetPosOK = FALSE;
+    U16 cDir;
+    U32 i;
+    U32 ofsdir;
+    U32 cbifd = 0;
+    U32 cbEXIFIFD = 0;
+    U32 cbGPSInfoIFD = 0;
+    U32 cbInteroperabilityIFD = 0;
+
+    *pcbifd = 0;
+    Call(pWS->GetPos(pWS, &offCurPos));
+    GetPosOK = TRUE;
+
+    Call(GetUShort(pWS, uIFDOfs, &cDir));
+    cbifd = sizeof(U16) + cDir * SizeofIFDEntry + sizeof(U32);
+    ofsdir = uIFDOfs + sizeof(U16);
+    for ( i = 0; i < cDir; i++ )
+    {
+        U16 tag;
+        U16 type;
+        U32 count;
+        U32 value;
+        U32 datasize;
+
+        Call(GetUShort(pWS, ofsdir, &tag));
+        Call(GetUShort(pWS, ofsdir + sizeof(U16), &type));
+        Call(GetULong(pWS, ofsdir + 2 * sizeof(U16), &count));
+        Call(GetULong(pWS, ofsdir + 2 * sizeof(U16) + sizeof(U32), &value));
+        FailIf(type == 0 || type >= sizeof(IFDEntryTypeSizes) / sizeof(IFDEntryTypeSizes[0]), WMP_errUnsupportedFormat);
+        if ( tag == WMP_tagEXIFMetadata )
+        {
+            Call(StreamCalcIFDSize(pWS, value, &cbEXIFIFD));
+        }
+        else if ( tag == WMP_tagGPSInfoMetadata )
+        {
+            Call(StreamCalcIFDSize(pWS, value, &cbGPSInfoIFD));
+        }
+        else if ( tag == WMP_tagInteroperabilityIFD )
+        {
+            Call(StreamCalcIFDSize(pWS, value, &cbInteroperabilityIFD));
+        }
+        else
+        {
+            datasize = IFDEntryTypeSizes[type] * count;
+            if ( datasize > 4 )
+                cbifd += datasize;
+        }
+        ofsdir += SizeofIFDEntry;
+    }
+    if ( cbEXIFIFD != 0 )
+        cbifd += ( cbifd & 1 ) + cbEXIFIFD;
+    if ( cbGPSInfoIFD != 0 )
+        cbifd += ( cbifd & 1 ) + cbGPSInfoIFD;
+    if ( cbInteroperabilityIFD != 0 )
+        cbifd += ( cbifd & 1 ) + cbInteroperabilityIFD;
+    *pcbifd = cbifd;
+
+Cleanup:
+    if ( GetPosOK )
+        Call(pWS->SetPos(pWS, offCurPos));
+    return ( err );
+}
+
+
+
+// src IFD copied to dst IFD with any nested IFD's
+// src IFD is arbitrary endian, arbitrary data arrangement
+// dst IFD is little endian, data arranged in tag order
+// dst IFD tags are ordered the same as src IFD so src IFD tags must be in order
+ERR BufferCopyIFD(const U8* pbsrc, U32 cbsrc, U32 ofssrc, U8 endian, U8* pbdst, U32 cbdst, U32* pofsdst)
+{
+    ERR err = WMP_errSuccess;
+    U16 cDir;
+    U16 i;
+    U16 ofsEXIFIFDEntry = 0;
+    U16 ofsGPSInfoIFDEntry = 0;
+    U16 ofsInteroperabilityIFDEntry = 0;
+    U32 ofsEXIFIFD = 0;
+    U32 ofsGPSInfoIFD = 0;
+    U32 ofsInteroperabilityIFD = 0;
+    U32 ofsdstnextdata;
+    U32 ofsdst = *pofsdst;
+    U32 ofssrcdir;
+    U32 ofsdstdir;
+    U32 ofsnextifd;
+
+    Call(getbfwe(pbsrc, cbsrc, ofssrc, &cDir, endian));
+    Call(setbfw(pbdst, cbdst, ofsdst, cDir));
+    ofsnextifd = ofsdst + sizeof(U16) + SizeofIFDEntry * cDir;
+    ofsdstnextdata = ofsnextifd + sizeof(U32);
+
+    ofssrcdir = ofssrc + sizeof(U16);
+    ofsdstdir = ofsdst + sizeof(U16);
+    for ( i = 0; i < cDir; i++ )
+    {
+        U16 tag;
+        U16 type;
+        U32 count;
+        U32 value;
+        U32 size;
+
+        Call(getbfwe(pbsrc, cbsrc, ofssrcdir, &tag, endian));
+        Call(setbfw(pbdst, cbdst, ofsdstdir, tag));
+
+        Call(getbfwe(pbsrc, cbsrc, ofssrcdir + sizeof(U16), &type, endian));
+        Call(setbfw(pbdst, cbdst, ofsdstdir + sizeof(U16), type));
+
+        Call(getbfdwe(pbsrc, cbsrc, ofssrcdir + 2 * sizeof(U16), &count, endian));
+        Call(setbfdw(pbdst, cbdst, ofsdstdir + 2 * sizeof(U16), count));
+
+        Call(getbfdwe(pbsrc, cbsrc, ofssrcdir + 2 * sizeof(U16) + sizeof(U32), &value, endian));
+        Call(setbfdw(pbdst, cbdst, ofsdstdir + 2 * sizeof(U16) + sizeof(U32), 0));
+
+        FailIf(type == 0 || type >= sizeof(IFDEntryTypeSizes) / sizeof(IFDEntryTypeSizes[0]), WMP_errFail);
+        if ( tag == WMP_tagEXIFMetadata )
+        {
+            ofsEXIFIFDEntry = (U16) ofsdstdir;
+            ofsEXIFIFD = value;
+        }
+        else if ( tag == WMP_tagGPSInfoMetadata )
+        {
+            ofsGPSInfoIFDEntry = (U16) ofsdstdir;
+            ofsGPSInfoIFD = value;
+        }
+        else if ( tag == WMP_tagInteroperabilityIFD )
+        {
+            ofsInteroperabilityIFDEntry = (U16) ofsdstdir;
+            ofsInteroperabilityIFD = value;
+        }
+        else
+        {
+            U32 ofsdstdata = ofsdstdir + 2 * sizeof(U16) + sizeof(U32);
+            U32 ofssrcdata = ofssrcdir + 2 * sizeof(U16) + sizeof(U32);
+            size = count * IFDEntryTypeSizes[type];
+            if ( size > 4 )
+            {
+                ofssrcdata = value;
+                Call(setbfdw(pbdst, cbdst, ofsdstdata, ofsdstnextdata));
+                ofsdstdata = ofsdstnextdata;
+                ofsdstnextdata += size;
+            }
+            FailIf(ofssrcdata + size > cbsrc || ofsdstdata + size > cbdst, WMP_errBufferOverflow);
+            if ( size == count || endian == WMP_INTEL_ENDIAN )
+                // size == count means 8-bit data means endian doesn't matter
+                memcpy(&pbdst[ofsdstdata], &pbsrc[ofssrcdata], size);
+            else
+            {   // big endian source and endian matters
+                U32 j;
+
+                switch ( IFDEntryTypeSizes[type] )
+                {
+                case 2:
+                    for ( j = 0; j < count; j++ )
+                    {
+                        U16 w;
+                        getbfwbig(pbsrc, cbsrc, ofssrcdata + j * sizeof(U16), &w);
+                        setbfw(pbdst, cbdst, ofsdstdata + j * sizeof(U16), w);
+                    }
+                    break;
+                case 8:
+                    if ( type == WMP_typDOUBLE )
+                    {
+                        for ( j = 0; j < count; j++ )
+                        {
+                            U32 dwlo;
+                            U32 dwhi;
+                            getbfdwbig(pbsrc, cbsrc, ofssrcdata + j * 8, &dwhi);
+                            getbfdwbig(pbsrc, cbsrc, ofssrcdata + j * 8 + sizeof(U32), &dwlo);
+                            setbfdw(pbdst, cbdst, ofsdstdata + j * 8, dwlo);
+                            setbfdw(pbdst, cbdst, ofsdstdata + j * 8 + sizeof(U32), dwhi);
+                        }
+                        break;
+                    }
+                    count *= 2;
+                    // RATIONAL's fall through to be handled as LONG's
+                case 4:
+                    for ( j = 0; j < count; j++ )
+                    {
+                        U32 dw;
+                        getbfdwbig(pbsrc, cbsrc, ofssrcdata + j * sizeof(U32), &dw);
+                        setbfdw(pbdst, cbdst, ofsdstdata + j * sizeof(U32), dw);
+                    }
+                    break;
+                }
+            }
+        }
+        ofssrcdir += SizeofIFDEntry;
+        ofsdstdir += SizeofIFDEntry;
+    }
+    Call(setbfdw(pbdst, cbdst, ofsnextifd, 0));    // no nextIFD
+
+    if ( ofsEXIFIFDEntry != 0 )
+    {
+        ofsdstnextdata += ( ofsdstnextdata & 1 );
+        Call(setbfdw(pbdst, cbdst, ofsEXIFIFDEntry + 2 * sizeof(U16) + sizeof(U32), ofsdstnextdata));
+        Call(BufferCopyIFD(pbsrc, cbsrc, ofsEXIFIFD, endian, pbdst, cbdst, &ofsdstnextdata));
+    }
+    if ( ofsGPSInfoIFDEntry != 0 )
+    {
+        ofsdstnextdata += ( ofsdstnextdata & 1 );
+        Call(setbfdw(pbdst, cbdst, ofsGPSInfoIFDEntry + 2 * sizeof(U16) + sizeof(U32), ofsdstnextdata));
+        Call(BufferCopyIFD(pbsrc, cbsrc, ofsGPSInfoIFD, endian, pbdst, cbdst, &ofsdstnextdata));
+    }
+    if ( ofsInteroperabilityIFDEntry != 0 )
+    {
+        ofsdstnextdata += ( ofsdstnextdata & 1 );
+        Call(setbfdw(pbdst, cbdst, ofsInteroperabilityIFDEntry + 2 * sizeof(U16) + sizeof(U32), ofsdstnextdata));
+        Call(BufferCopyIFD(pbsrc, cbsrc, ofsInteroperabilityIFD, endian, pbdst, cbdst, &ofsdstnextdata));
+    }
+    *pofsdst = ofsdstnextdata;
+
+Cleanup:
+    return err;
+}
+
+
+
+// src IFD copied to dst IFD with any nested IFD's
+// src IFD is little endian, arbitrary data arrangement
+// dst IFD is little endian, data arranged in tag order
+// dst IFD tags are ordered the same as src IFD so src IFD tags must be in order
+ERR StreamCopyIFD(struct WMPStream* pWS, U32 ofssrc, U8* pbdst, U32 cbdst, U32* pofsdst)
+{
+    ERR err = WMP_errSuccess;
+    size_t offCurPos = 0;
+    Bool GetPosOK = FALSE;
+    U16 cDir;
+    U16 i;
+    U16 ofsEXIFIFDEntry = 0;
+    U16 ofsGPSInfoIFDEntry = 0;
+    U16 ofsInteroperabilityIFDEntry = 0;
+    U32 ofsEXIFIFD = 0;
+    U32 ofsGPSInfoIFD = 0;
+    U32 ofsInteroperabilityIFD = 0;
+    U32 ofsdstnextdata;
+    U32 ofsdst = *pofsdst;
+    U32 ofssrcdir;
+    U32 ofsdstdir;
+    U32 ofsnextifd;
+
+    Call(pWS->GetPos(pWS, &offCurPos));
+    GetPosOK = TRUE;
+
+    Call(GetUShort(pWS, ofssrc, &cDir));
+    Call(setbfw(pbdst, cbdst, ofsdst, cDir));
+
+    ofsnextifd = ofsdst + sizeof(U16) + SizeofIFDEntry * cDir;
+    ofsdstnextdata = ofsnextifd + sizeof(U32);
+
+    ofssrcdir = ofssrc + sizeof(U16);
+    ofsdstdir = ofsdst + sizeof(U16);
+    for ( i = 0; i < cDir; i++ )
+    {
+        U16 tag;
+        U16 type;
+        U32 count;
+        U32 value;
+        U32 size;
+
+        Call(GetUShort(pWS, ofssrcdir, &tag));
+        Call(setbfw(pbdst, cbdst, ofsdstdir, tag));
+
+        Call(GetUShort(pWS, ofssrcdir + sizeof(U16), &type));
+        Call(setbfw(pbdst, cbdst, ofsdstdir + sizeof(U16), type));
+
+        Call(GetULong(pWS, ofssrcdir + 2 * sizeof(U16), &count));
+        Call(setbfdw(pbdst, cbdst, ofsdstdir + 2 * sizeof(U16), count));
+
+        Call(GetULong(pWS, ofssrcdir + 2 * sizeof(U16) + sizeof(U32), &value));
+        Call(setbfdw(pbdst, cbdst, ofsdstdir + 2 * sizeof(U16) + sizeof(U32), 0));
+
+        FailIf(type == 0 || type >= sizeof(IFDEntryTypeSizes) / sizeof(IFDEntryTypeSizes[0]), WMP_errFail);
+        if ( tag == WMP_tagEXIFMetadata )
+        {
+            ofsEXIFIFDEntry = (U16) ofsdstdir;
+            ofsEXIFIFD = value;
+        }
+        else if ( tag == WMP_tagGPSInfoMetadata )
+        {
+            ofsGPSInfoIFDEntry = (U16) ofsdstdir;
+            ofsGPSInfoIFD = value;
+        }
+        else if ( tag == WMP_tagInteroperabilityIFD )
+        {
+            ofsInteroperabilityIFDEntry = (U16) ofsdstdir;
+            ofsInteroperabilityIFD = value;
+        }
+        else
+        {
+            U32 ofsdstdata = ofsdstdir + 2 * sizeof(U16) + sizeof(U32);
+            U32 ofssrcdata = ofssrcdir + 2 * sizeof(U16) + sizeof(U32);
+            size = count * IFDEntryTypeSizes[type];
+            if ( size > 4 )
+            {
+                ofssrcdata = value;
+                Call(setbfdw(pbdst, cbdst, ofsdstdata, ofsdstnextdata));
+                ofsdstdata = ofsdstnextdata;
+                ofsdstnextdata += size;
+            }
+            FailIf(ofsdstdata + size > cbdst, WMP_errBufferOverflow);
+            Call(pWS->SetPos(pWS, ofssrcdata));
+            Call(pWS->Read(pWS, &pbdst[ofsdstdata], size));
+        }
+        ofssrcdir += SizeofIFDEntry;
+        ofsdstdir += SizeofIFDEntry;
+    }
+    Call(setbfdw(pbdst, cbdst, ofsnextifd, 0));    // no nextIFD
+
+    if ( ofsEXIFIFDEntry != 0 )
+    {
+        ofsdstnextdata += ( ofsdstnextdata & 1 );
+        Call(setbfdw(pbdst, cbdst, ofsEXIFIFDEntry + 2 * sizeof(U16) + sizeof(U32), ofsdstnextdata));
+        Call(StreamCopyIFD(pWS, ofsEXIFIFD, pbdst, cbdst, &ofsdstnextdata));
+    }
+    if ( ofsGPSInfoIFDEntry != 0 )
+    {
+        ofsdstnextdata += ( ofsdstnextdata & 1 );
+        Call(setbfdw(pbdst, cbdst, ofsGPSInfoIFDEntry + 2 * sizeof(U16) + sizeof(U32), ofsdstnextdata));
+        Call(StreamCopyIFD(pWS, ofsGPSInfoIFD, pbdst, cbdst, &ofsdstnextdata));
+    }
+    if ( ofsInteroperabilityIFDEntry != 0 )
+    {
+        ofsdstnextdata += ( ofsdstnextdata & 1 );
+        Call(setbfdw(pbdst, cbdst, ofsInteroperabilityIFDEntry + 2 * sizeof(U16) + sizeof(U32), ofsdstnextdata));
+        Call(StreamCopyIFD(pWS, ofsInteroperabilityIFD, pbdst, cbdst, &ofsdstnextdata));
+    }
+    *pofsdst = ofsdstnextdata;
+
+Cleanup:
+    if ( GetPosOK )
+        Call(pWS->SetPos(pWS, offCurPos));
+    return err;
+}
+
+
+
+//================================================================
+ERR GetUShort(
+    __in_ecount(1) struct WMPStream* pWS,
+    size_t offPos,
+    __out_ecount(1) U16* puValue)
+{
+    ERR err = WMP_errSuccess;
+    U8  cVal;
+
+    Call(pWS->SetPos(pWS, offPos));
+    Call(pWS->Read(pWS, &cVal, sizeof(cVal)));
+    puValue[0] = (U16) cVal;
+    Call(pWS->Read(pWS, &cVal, sizeof(cVal)));
+    puValue[0] += ((U16) cVal) << 8;
+
+Cleanup:
+    return err;
+}
+
+ERR PutUShort(
+    __in_ecount(1) struct WMPStream* pWS,
+    size_t offPos,
+    U16 uValue)
+{
+    ERR err = WMP_errSuccess;
+    U8  cVal = (U8) uValue;
+
+    Call(pWS->SetPos(pWS, offPos));
+    Call(pWS->Write(pWS, &cVal, sizeof(cVal)));
+    cVal = (U8) (uValue >> 8);
+    Call(pWS->Write(pWS, &cVal, sizeof(cVal)));
+
+Cleanup:
+    return err;
+}
+
+ERR GetULong(
+    __in_ecount(1) struct WMPStream* pWS,
+    size_t offPos,
+    __out_ecount(1) U32* puValue)
+{
+    ERR err = WMP_errSuccess;
+    U8  cVal;
+
+    Call(pWS->SetPos(pWS, offPos));
+    Call(pWS->Read(pWS, &cVal, sizeof(cVal)));
+    puValue[0] = (U32) cVal;
+    Call(pWS->Read(pWS, &cVal, sizeof(cVal)));
+    puValue[0] += ((U32) cVal) << 8;
+    Call(pWS->Read(pWS, &cVal, sizeof(cVal)));
+    puValue[0] += ((U32) cVal) << 16;
+    Call(pWS->Read(pWS, &cVal, sizeof(cVal)));
+    puValue[0] += ((U32) cVal) << 24;
+ 
+Cleanup:
+    return err;
+}
+
+ERR PutULong(
+    __in_ecount(1) struct WMPStream* pWS,
+    size_t offPos,
+    U32 uValue)
+{
+    ERR err = WMP_errSuccess;
+    U8  cVal = (U8) uValue;
+
+    Call(pWS->SetPos(pWS, offPos));
+    Call(pWS->Write(pWS, &cVal, sizeof(cVal)));
+    cVal = (U8) (uValue >> 8);
+    Call(pWS->Write(pWS, &cVal, sizeof(cVal)));
+    cVal = (U8) (uValue >> 16);
+    Call(pWS->Write(pWS, &cVal, sizeof(cVal)));
+    cVal = (U8) (uValue >> 24);
+    Call(pWS->Write(pWS, &cVal, sizeof(cVal)));
+
+Cleanup:
+    return err;
+}
+
+
+ERR ReadBinaryData(__in_ecount(1) struct WMPStream* pWS,
+                   const __in_win U32 uCount,
+                   const __in_win U32 uValue,
+                   U8 **ppbData)
+{
+    ERR err = WMP_errSuccess;
+    U8 *pbData = NULL;
+
+    Call(PKAlloc((void **) &pbData, uCount + 2)); // Allocate buffer to store data with space for an added ascii or unicode null
+    if (uCount <= 4)
+    {
+        unsigned int i;
+        for (i = 0; i < uCount; i++)
+            pbData[i] = ((U8*)&uValue)[i]; // Copy least sig bytes - we assume 'II' type TIFF files
+    }
+    else
+    {
+        size_t offPosPrev;
+
+        Call(pWS->GetPos(pWS, &offPosPrev));
+        Call(pWS->SetPos(pWS, uValue));
+        Call(pWS->Read(pWS, pbData, uCount));
+        Call(pWS->SetPos(pWS, offPosPrev));
+    }
+
+    *ppbData = pbData;
+
+Cleanup:
+    if (Failed(err))
+    {
+        if (pbData)
+            PKFree((void **) &pbData);
+    }
+    return err;
+}
+
+
+ERR ReadPropvar(__in_ecount(1) struct WMPStream* pWS,
+                const __in_win U16 uType,
+                const __in_win U32 uCount,
+                const __in_win U32 uValue,
+                __out_win DPKPROPVARIANT *pvar)
+{
+    ERR err = WMP_errSuccess;
+    // U8 *pbData = NULL;
+
+    memset(pvar, 0, sizeof(*pvar));
+    if (uCount == 0)
+        goto Cleanup; // Nothing to read in here
+
+    switch (uType)
+    {
+        case WMP_typASCII:
+            pvar->vt = DPKVT_LPSTR;
+            Call(ReadBinaryData(pWS, uCount, uValue, (U8 **) &pvar->VT.pszVal));
+            assert(0 == pvar->VT.pszVal[uCount - 1]); // Check that it's null-terminated
+            // make sure (ReadBinaryData allocated uCount + 2 so this and unicode can have forced nulls)
+            pvar->VT.pszVal[uCount] = 0;
+            break;
+
+        case WMP_typBYTE:
+        case WMP_typUNDEFINED:
+            // Return as regular C array rather than safearray, as this type is sometimes
+            // used to convey unicode (which does not require a count field). Caller knows
+            // uCount and can convert to safearray if necessary.
+            pvar->vt = (DPKVT_BYREF | DPKVT_UI1);
+            Call(ReadBinaryData(pWS, uCount, uValue, &pvar->VT.pbVal));
+            break;
+
+        case WMP_typSHORT:
+            if (1 == uCount)
+            {
+                pvar->vt = DPKVT_UI2;
+                pvar->VT.uiVal = (U16)(uValue & 0x0000FFFF);
+            }
+            else if (2 == uCount)
+            {
+                pvar->vt = DPKVT_UI4;
+                pvar->VT.ulVal = uValue;
+            }
+            else
+            {
+                assert(FALSE); // NYI
+                FailIf(TRUE, WMP_errNotYetImplemented);
+            }
+            break;
+
+        default:
+            assert(FALSE); // Unhandled type
+            FailIf(TRUE, WMP_errNotYetImplemented);
+            break;
+    }
+
+Cleanup:
+    return err;
+}
+
+
+ERR WriteWmpDE(
+    __in_ecount(1) struct WMPStream* pWS,
+    size_t *pOffPos,
+    const __in_ecount(1) WmpDE* pDE,
+    const U8 *pbData,
+    U32 *pcbDataWrittenToOffset)
+{
+    ERR err = WMP_errSuccess;
+    size_t offPos = *pOffPos;
+
+    assert(-1 != pDE->uCount);
+    assert(-1 != pDE->uValueOrOffset);
+
+    if (pcbDataWrittenToOffset)
+    {
+        assert(pbData); // Makes no sense to provide this arg without pbData
+        *pcbDataWrittenToOffset = 0;
+    }
+
+    Call(PutUShort(pWS, offPos, pDE->uTag)); offPos += 2;
+    Call(PutUShort(pWS, offPos, pDE->uType)); offPos += 2;
+    Call(PutULong(pWS, offPos, pDE->uCount)); offPos += 4;
+
+    switch (pDE->uType)
+    {
+
+        case WMP_typASCII:
+        case WMP_typUNDEFINED:
+        case WMP_typBYTE:
+            if (pDE->uCount <= 4)
+            {
+                U8 pad[4] = {0};
+                Call(pWS->SetPos(pWS, offPos));
+
+                if (NULL == pbData)
+                    pbData = (U8*)&pDE->uValueOrOffset;
+
+                Call(pWS->Write(pWS, pbData, pDE->uCount));
+                Call(pWS->Write(pWS, pad, 4 - pDE->uCount)); offPos += 4;
+            }
+            else
+            {
+                Call(PutULong(pWS, offPos, pDE->uValueOrOffset)); offPos += 4;
+
+                // Write the data if requested to do so
+                if (pbData)
+                {
+                    Call(pWS->SetPos(pWS, pDE->uValueOrOffset));
+                    Call(pWS->Write(pWS, pbData, pDE->uCount));
+                    Call(pWS->SetPos(pWS, offPos));
+                    *pcbDataWrittenToOffset = pDE->uCount;
+                }
+            }
+            break;
+
+        case WMP_typSHORT:
+            if (pDE->uCount <= 2)
+            {
+                U16 uiShrt1 = 0;
+                U16 uiShrt2 = 0;
+
+                if (NULL == pbData)
+                    pbData = (U8*)&pDE->uValueOrOffset;
+
+                if (pDE->uCount > 0)
+                    uiShrt1 = *((U16*)pbData);
+
+                if (pDE->uCount > 1)
+                {
+                    assert(FALSE); // Untested - remove this assert after this has been tested
+                    uiShrt2 = *(U16*)(pbData + 2);
+                }
+
+                Call(PutUShort(pWS, offPos, uiShrt1)); offPos += 2;
+                Call(PutUShort(pWS, offPos, uiShrt2)); offPos += 2;
+            }
+            else
+            {
+                assert(FALSE); // Untested - remove this assert after this has been tested
+                Call(PutULong(pWS, offPos, pDE->uValueOrOffset)); offPos += 4;
+
+                // Write the data if requested to do so
+                if (pbData)
+                {
+                    U32 i;
+                    Call(pWS->SetPos(pWS, pDE->uValueOrOffset));
+                    for (i = 0; i < pDE->uCount; i++)
+                    {
+                        const U16 uiShort = *(U16*)(pbData + i*sizeof(U16));
+                        Call(PutUShort(pWS, offPos, uiShort)); // Write one at a time for endian purposes - but inefficient
+                    }
+                    Call(pWS->SetPos(pWS, offPos));
+                    *pcbDataWrittenToOffset = pDE->uCount * sizeof(U16);
+                }
+
+            }
+            break;
+
+        case WMP_typFLOAT:
+        case WMP_typLONG:
+            if (pDE->uCount <= 1)
+            {
+                if (NULL == pbData)
+                    pbData = (U8*)&pDE->uValueOrOffset;
+
+                Call(PutULong(pWS, offPos, *(U32*)pbData)); offPos += 4;
+            }
+            else
+            {
+                assert(FALSE); // Untested - remove this assert after this has been tested
+                Call(PutULong(pWS, offPos, pDE->uValueOrOffset)); offPos += 4;
+
+                // Write the data if requested to do so
+                if (pbData)
+                {
+                    U32 i;
+                    Call(pWS->SetPos(pWS, pDE->uValueOrOffset));
+                    for (i = 0; i < pDE->uCount; i++)
+                    {
+                        const U32 uLong = *(U32*)(pbData + i*sizeof(U32));
+                        Call(PutULong(pWS, offPos, uLong)); // Write one at a time for endian purposes - but inefficient
+                    }
+                    Call(pWS->SetPos(pWS, offPos));
+                    *pcbDataWrittenToOffset = pDE->uCount * sizeof(U32);
+                }
+            }
+            break;
+
+        default:
+            assert(FALSE); // Alert the programmer
+            Call(WMP_errInvalidParameter);
+            break;
+    }
+
+Cleanup:
+    *pOffPos = offPos;
+    return err;
+}
+
diff --git a/Source/LibJXR/jxrgluelib/JXRMeta.h b/Source/LibJXR/jxrgluelib/JXRMeta.h
new file mode 100644
index 0000000..050b2cd
--- /dev/null
+++ b/Source/LibJXR/jxrgluelib/JXRMeta.h
@@ -0,0 +1,258 @@
+//*@@@+++@@@@******************************************************************
+//
+// Copyright � Microsoft Corp.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+// � Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// � Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//*@@@---@@@@******************************************************************
+#pragma once
+
+#include <windowsmediaphoto.h>
+#if !defined(WIN32) || defined(__MINGW32__)
+#include <wmspecstring.h>
+#endif
+
+#ifndef UNREFERENCED_PARAMETER
+#define UNREFERENCED_PARAMETER(P) { (P) = (P); }
+#endif // UNREFERENCED_PARAMETER
+
+//================================================================
+// Container
+//================================================================
+
+// Keep these in sort order so that we can easily confirm we are outputting tags in ascending order
+#define WMP_tagNull 0
+
+#define WMP_tagDocumentName         0x010d  // Descriptive metadata tag
+#define WMP_tagImageDescription     0x010e  // Descriptive metadata tag
+#define WMP_tagCameraMake           0x010f  // Descriptive metadata tag
+#define WMP_tagCameraModel          0x0110  // Descriptive metadata tag
+#define WMP_tagPageName             0x011d  // Descriptive metadata tag
+#define WMP_tagPageNumber           0x0129  // Descriptive metadata tag
+#define WMP_tagSoftware             0x0131  // Descriptive metadata tag
+#define WMP_tagDateTime             0x0132  // Descriptive metadata tag
+#define WMP_tagArtist               0x013b  // Descriptive metadata tag
+#define WMP_tagHostComputer         0x013c  // Descriptive metadata tag
+
+#define WMP_tagXMPMetadata 0x02bc
+
+#define WMP_tagRatingStars          0x4746  // Descriptive metadata tag
+#define WMP_tagRatingValue          0x4749  // Descriptive metadata tag
+#define WMP_tagCopyright            0x8298  // Descriptive metadata tag
+
+#define WMP_tagEXIFMetadata 0x8769
+#define WMP_tagGPSInfoMetadata 0x8825
+#define WMP_tagIPTCNAAMetadata 0x83bb
+#define WMP_tagPhotoshopMetadata 0x8649
+#define WMP_tagInteroperabilityIFD 0xa005
+#define WMP_tagIccProfile 0x8773 // Need to use same tag as TIFF!!
+
+#define WMP_tagCaption              0x9c9b  // Descriptive metadata tag
+
+#define WMP_tagPixelFormat 0xbc01
+#define WMP_tagTransformation 0xbc02
+#define WMP_tagCompression 0xbc03
+#define WMP_tagImageType 0xbc04
+
+#define WMP_tagImageWidth 0xbc80
+#define WMP_tagImageHeight 0xbc81
+
+#define WMP_tagWidthResolution 0xbc82
+#define WMP_tagHeightResolution 0xbc83
+
+#define WMP_tagImageOffset 0xbcc0
+#define WMP_tagImageByteCount 0xbcc1
+#define WMP_tagAlphaOffset 0xbcc2
+#define WMP_tagAlphaByteCount 0xbcc3
+#define WMP_tagImageDataDiscard 0xbcc4
+#define WMP_tagAlphaDataDiscard 0xbcc5
+
+
+#define WMP_typBYTE 1
+#define WMP_typASCII 2
+#define WMP_typSHORT 3
+#define WMP_typLONG 4
+#define WMP_typRATIONAL 5
+#define WMP_typSBYTE 6
+#define WMP_typUNDEFINED 7
+#define WMP_typSSHORT 8
+#define WMP_typSLONG 9
+#define WMP_typSRATIONAL 10
+#define WMP_typFLOAT 11
+#define WMP_typDOUBLE 12
+
+
+#define WMP_valCompression 0xbc
+#define WMP_valWMPhotoID WMP_valCompression
+
+
+#if defined(WIN32) && !defined(__MINGW32__)
+#define __in_win    __in
+#define __out_win   __out
+#endif
+
+
+//================================================================
+
+typedef enum
+{
+    DPKVT_EMPTY = 0,
+    DPKVT_UI1 = 17,
+    DPKVT_UI2 = 18,
+    DPKVT_UI4 = 19,
+    DPKVT_LPSTR = 30,
+    DPKVT_LPWSTR = 31,
+    DPKVT_BYREF = 0x4000,
+} DPKVARTYPE;
+
+typedef struct DPKPROPVARIANT
+{
+    DPKVARTYPE  vt;
+    union
+    {
+        U8 bVal;        // DPKVT_UI1
+        U16 uiVal;      // DPKVT_UI2
+        U32 ulVal;      // DPKVT_UI4
+        char *pszVal;   // DPKVT_LPSTR
+        U16 *pwszVal;   // DPKVT_LPWSTR
+        U8 *pbVal;      // DPKVT_BYREF | DPKVT_UI1
+    } VT;
+} DPKPROPVARIANT;
+
+typedef struct DESCRIPTIVEMETADATA
+{
+    DPKPROPVARIANT  pvarImageDescription;   // WMP_tagImageDescription
+    DPKPROPVARIANT  pvarCameraMake;         // WMP_tagCameraMake
+    DPKPROPVARIANT  pvarCameraModel;        // WMP_tagCameraModel
+    DPKPROPVARIANT  pvarSoftware;           // WMP_tagSoftware
+    DPKPROPVARIANT  pvarDateTime;           // WMP_tagDateTime
+    DPKPROPVARIANT  pvarArtist;             // WMP_tagArtist
+    DPKPROPVARIANT  pvarCopyright;          // WMP_tagCopyright
+    DPKPROPVARIANT  pvarRatingStars;        // WMP_tagRatingStars
+    DPKPROPVARIANT  pvarRatingValue;        // WMP_tagRatingValue
+    DPKPROPVARIANT  pvarCaption;            // WMP_tagCaption
+    DPKPROPVARIANT  pvarDocumentName;       // WMP_tagDocumentName
+    DPKPROPVARIANT  pvarPageName;           // WMP_tagPageName
+    DPKPROPVARIANT  pvarPageNumber;         // WMP_tagPageNumber
+    DPKPROPVARIANT  pvarHostComputer;       // WMP_tagHostComputer
+} DESCRIPTIVEMETADATA;
+
+typedef struct tagWmpDE
+{
+    U16 uTag;
+    U16 uType;
+    U32 uCount;
+    U32 uValueOrOffset;
+} WmpDE;
+
+typedef struct tagWmpDEMisc
+{
+    U32 uImageOffset;
+    U32 uImageByteCount;
+    U32 uAlphaOffset;
+    U32 uAlphaByteCount;
+
+    U32 uOffPixelFormat;
+    U32 uOffImageByteCount;
+    U32 uOffAlphaOffset;
+    U32 uOffAlphaByteCount;
+    U32 uColorProfileOffset;
+    U32 uColorProfileByteCount;
+    U32 uXMPMetadataOffset;
+    U32 uXMPMetadataByteCount;
+    U32 uEXIFMetadataOffset;
+    U32 uEXIFMetadataByteCount;
+    U32 uGPSInfoMetadataOffset;
+    U32 uGPSInfoMetadataByteCount;
+    U32 uIPTCNAAMetadataOffset;
+    U32 uIPTCNAAMetadataByteCount;
+    U32 uPhotoshopMetadataOffset;
+    U32 uPhotoshopMetadataByteCount;
+    U32 uDescMetadataOffset;
+    U32 uDescMetadataByteCount;
+} WmpDEMisc;
+
+
+//================================================================
+EXTERN_C ERR GetUShort(
+    __in_ecount(1) struct WMPStream* pWS,
+    size_t offPos,
+    __out_ecount(1) U16* puValue
+);
+
+EXTERN_C ERR PutUShort(
+    __in_ecount(1) struct WMPStream* pWS,
+    size_t offPos,
+    U16 uValue
+);
+
+EXTERN_C ERR GetULong(
+    __in_ecount(1) struct WMPStream* pWS,
+    size_t offPos,
+    __out_ecount(1) U32* puValue
+);
+
+EXTERN_C ERR PutULong(
+    __in_ecount(1) struct WMPStream* pWS,
+    size_t offPos,
+    U32 uValue
+);
+
+EXTERN_C ERR WriteWmpDE(
+    __in_ecount(1) struct WMPStream* pWS,
+    size_t *pOffPos,
+    const __in_ecount(1) WmpDE* pDE,
+    const U8 *pbData,
+    U32 *pcbDataWrittenToOffset
+);
+
+
+EXTERN_C ERR ReadPropvar(__in_ecount(1) struct WMPStream* pWS,
+                         const __in_win U16 uType,
+                         const __in_win U32 uCount,
+                         const __in_win U32 uValue,
+                         __out_win DPKPROPVARIANT *pvar);
+
+
+
+// read and write little endian words/dwords from a buffer on both big and little endian cpu's
+// with full buffer overflow checking
+
+#define WMP_INTEL_ENDIAN    ('I')
+
+EXTERN_C ERR getbfcpy(U8* pbdest, const U8* pb, size_t cb, size_t ofs, U32 n);
+EXTERN_C ERR getbfw(const U8* pb, size_t cb, size_t ofs, U16* pw);
+EXTERN_C ERR getbfdw(const U8* pb, size_t cb, size_t ofs, U32* pdw);
+EXTERN_C ERR getbfwbig(const U8* pb, size_t cb, size_t ofs, U16* pw);
+EXTERN_C ERR getbfdwbig(const U8* pb, size_t cb, size_t ofs, U32* pdw);
+EXTERN_C ERR getbfwe(const U8* pb, size_t cb, size_t ofs, U16* pw, U8 endian);
+EXTERN_C ERR getbfdwe(const U8* pb, size_t cb, size_t ofs, U32* pdw, U8 endian);
+EXTERN_C ERR setbfcpy(U8* pb, size_t cb, size_t ofs, const U8* pbset, size_t cbset);
+EXTERN_C ERR setbfw(U8* pb, size_t cb, size_t ofs, U16 dw);
+EXTERN_C ERR setbfdw(U8* pb, size_t cb, size_t ofs, U32 dw);
+EXTERN_C ERR setbfwbig(U8* pb, size_t cb, size_t ofs, U16 dw);
+EXTERN_C ERR setbfdwbig(U8* pb, size_t cb, size_t ofs, U32 dw);
+EXTERN_C ERR BufferCalcIFDSize(const U8* pb, size_t cb, U32 uIFDOfs, U8 endian, U32 *pcbifd);
+EXTERN_C ERR StreamCalcIFDSize(struct WMPStream* pWS, U32 uIFDOfs, U32 *pcbifd);
+EXTERN_C ERR BufferCopyIFD(const U8* pbsrc, U32 cbsrc, U32 ofssrc, U8 endian, U8* pbdest, U32 cbdest, U32* pofsdest);
+EXTERN_C ERR StreamCopyIFD(struct WMPStream* pWS, U32 ofssrc, U8* pbdest, U32 cbdest, U32* pofsdest);
diff --git a/Source/LibMNG/Changes b/Source/LibMNG/Changes
deleted file mode 100644
index fbf2ac5..0000000
--- a/Source/LibMNG/Changes
+++ /dev/null
@@ -1,1447 +0,0 @@
------------------------------------------------------------
-
-1.0.10 (Jul 13th 2007)
-----------------------
-
-in short:
-
-intermediate CVS
-
--------------------
-
-bugfixes:
-
-core:
-- fixed some compiler-warnings
-- fixed display routines called twice for FULL_MNG support in mozlibmngconf.h
-- standard windows dll upgraded to zlib 1.2.3
-- fixed problem with CLON object during readdisplay() (thanks Winfried!)
-- added typecast to appease the compiler (G R-P)
-- added more SKIPCHUNK conditionals (G R-P)
-- added MORE MNG_NO_1_2_4BIT_SUPPORT (G R-P)
-- added provisional support for anIM(mpNG) proposal
-- added provisional support for ANG proposal
-
-samples:
-- xmngview upgraded to 0.6 (thanks Winfried!)
-
-contrib:
-
-doc:
-
-makefiles:
-
-autoconf:
-
------------------------------------------------------------
-
-1.0.9 (jan 30th 2005)
----------------------
-
-in short:
-
-New optimizations save over 20KB on footprint.
-Also a few bugfixes and several patches.
-
-Thanks to those sending in their additions and for testing!
-
-To turn on the optimizations do:
-
-#DEFINE MNG_OPTIMIZE_CHUNKINITFREE
-#DEFINE MNG_OPTIMIZE_OBJCLEANUP
-#DEFINE MNG_OPTIMIZE_CHUNKASSIGN
-#DEFINE MNG_OPTIMIZE_CHUNKREADER
-
-(eg. they're not on by default (yet) !)
-
--------------------
-
-bugfixes:
-- fixed chunk pushing mechanism
-- fixed bug in writing sBIT for indexed color
-- fixed PPLT getchunk/putchunk routines
-- fixed MNG_NO_1_2_4BIT_SUPPORT for TBBN1G04.PNG
-- cleaned up macro-invocations (thanks to D. Airlie)
-
-core:
-- added more SKIPCHUNK conditionals
-- replaced MNG_TWEAK_LARGE_FILES with permanent solution
-- improved handling of cheap transparency when 16-bit support is disabled
-- added some MNG_SUPPORT_WRITE conditionals
-- added function to retrieve current FRAM delay
-- added MNG_NO_1_2_4BIT_SUPPORT
-- added bgr565_a8 canvas-style (thanks to J. Elvander)
-- standard windows dll upgraded to zlib 1.2.2
-- added LITTLEENDIAN/BIGENDIAN fixtures (thanks J.Stiles)
-- inclusion of zlib/lcms/ijgsrc6b with <> instead of ""
-- added conditional MNG_OPTIMIZE_CHUNKINITFREE
-- added conditional MNG_OPTIMIZE_OBJCLEANUP
-- added conditional MNG_OPTIMIZE_CHUNKASSIGN
-- added conditional MNG_OPTIMIZE_CHUNKREADER
-- fixed problem with global PLTE/tRNS
-
-samples:
-
-contrib:
-
-doc:
-- patched jng & mng manual pages (Thanks Peter Breitenlohner)
-
-makefiles:
-
-autoconf:
-- patched makefile.am & configure.in (Thanks Peter Breitenlohner)
-
------------------------------------------------------------
-
-1.0.8 (aug 5th 2004)
---------------------
-
-in short:
-
-added special data-pushing mechanisms and a few other tid-bits
-
--------------------
-
-bugfixes:
-- fixed problem with PAST usage where source > dest
-
-core:
-- added missing get-/put-chunk-jdaa
-- added CRC existence & checking flags
-- added data-push mechanisms for specialized decoders
-- some speed optimizations (thanks to John Stiles)
-- defend against using undefined closestream function
-- defend against using undefined openstream function
-- added check for extreme chunk-lengths
-- change worst-case iAlphadepth to 1 for standalone PNGs
-- added support for 3+byte pixelsize for JPEG's
-- added conditional to allow easier writing of large MNG's
-
-samples:
-
-contrib:
-
-doc:
-
-makefiles:
-
-autoconf:
-
------------------------------------------------------------
-
-1.0.7 (March 21st 2004)
------------------------
-
-in short:
-
-A bunch of new canvas-styles, some bug-fixes, upgraded to latest zlib/lcms
-and yet more work to please the Mozilla crowd.
-Releasing beta's doesn't seem very responsive, and this one's hardly changed
-much anyway. I just wanted to bump to a regular version for Mozilla
-re-integration.
-
--------------------
-
-bugfixes:
-- fixed inclusion of IJNG chunk for non-JNG use (J.S)
-- fixed bug in chunk-storage of SHOW chunk (where from == to)
-- fixed bug in promote_g8_g8 with 16bit support off
-
-core:
-- added CANVAS_RGB565 and CANVAS_BGR565 (big thanx to Raphael Assenat!!)
-- added CANVAS_RGBA565 and CANVAS_BGRA565 ( -- ditto -- )
-- upgraded to zlib 1.2.1
-- upgraded to lcms 1.11
-- added premultiplied alpha canvas' for RGBA, ARGB, ABGR (thx to John Stiles)
-- more optimizations with 16bit support off
-- put conditionals around openstream/closestream callbacks.
-- fixed typo (MNG_SKIPCHUNK_SAVE -> MNG_SKIPCHUNK_nEED)
-- fixed some 64-bit platform compiler warnings
-
-samples:
-
-contrib:
-- fixed mngtree sample (Raphael)
-- added 5-6-5 canvas to SDL sample (Raphael)
-
-doc:
-
-makefiles:
-
-autoconf:
-
------------------------------------------------------------
-
-1.0.6 (oct 19th 2003)
----------------------
-
-in short:
-
-Final release from beta1. No feedback is good feedback I presume,
-so here's 1.0.6-final!
-
-
--------------------
-
-bugfixes:
-
-core:
-
-samples:
-
-contrib:
-
-doc:
-
-makefiles:
-
-autoconf:
-
------------------------------------------------------------
-
-1.0.6-beta1 (sep 14th 2003)
----------------------------
-
-in short:
-
-further footprint-reductions
-removing email-addresses
-
-1.0.6 (final) will be out shortly
-
--------------------
-
-bugfixes:
-
-core:
-- added support for reducing the footprint of libmng by macros that optionally
-  skip unused chunks, remove 16-bit sample support, remove Delta support, and
-  remove JNG support, to accomodate Mozilla/Firebird.
-- further optional removal of unused functions
-- added MNG_NO_SUPPORT_FUNCQUERY conditional
-- added iPNGdepth member to pData structure
-- added conditionals around MAGN chunk support
-- added conditionals around non-VLC chunk support
-- added conditionals around "mng_display_go*" and other unused functions
-- added more conditionals around "promote" functions
-- removed email references as appropriate
-
-samples:
-
-contrib:
-
-doc:
-
-makefiles:
-
-autoconf:
-
------------------------------------------------------------
-
-1.0.6-alpha1 (aug 2nd 2003)
----------------------------
-
-in short:
-
-This is mostly in the light of footprint-reduction to please the Mozilla
-crew with a leaner and meaner libmng. See bug 18574 if you're interested:
-http://bugzilla.mozilla.org/show_bug.cgi?id=18574
-
--------------------
-
-bugfixes:
-- B719420 - fixed several MNG_APP_CMS problems
-
-core:
-- removed some compiler-warnings
-- hiding 12-bit JPEG stuff
-- fixed problem with infinite loops during readdisplay()
-- added size-optimiation COMPOSE routine usage
-- added conditionals around canvas update routines
-- added MNG_SKIPCHUNK_cHNK footprint optimizations
-- added conditionals around some JNG-supporting code      
-- added conditionals around 16-bit supporting code        
-- combined init functions into one function
-- replaced nested switches with simple init setup function
-- added conditionals zlib and jpeg property accessors
-- added size-optimization DIV255B8 routine usage
-- added conditionals around 8-bit magn routines
-- removed conditionals around 8-bit magn routines
-- added MNG_NO_16BIT_SUPPORT and MNG_NO_DELTA_PNG conditionals
-- reversed many loops to use decrementing counter
-- converted some switches to array references
-- removed some redundant checks for iRawlen==0
-- optionally use zlib's crc32 function instead of local mng_update_crc
-- bugfix empty "if" statement when 16-bit code is enabled
-- restored two misplaced #else/#endif blocks
-- added conditionals around "mng_display_go*" and other unused functions
-- added MNG_NO_LOOP_SIGNALS_SUPPORTED conditional
-- fixed duplicate for-loop
-- fixed invalid test in promote_imageobject
-- added conditionals around PAST chunk support
-- fixed "FOOTPRINT_COMPOSEIV" typo (now "FOOTPRINT_DIV")
-
-samples:
-
-contrib:
-- updated xmngview
-- added MSVC project for creating delta-MNGs: makemng (thanks Alex!)
-- added MSVC lib-file for use with the standard libmng.dll (again thanks Alex)
-
-doc:
-- updated readme.contrib
-
-makefiles:
-
-autoconf:
-
------------------------------------------------------------
-
-1.0.5 (mar 1st 2003)
---------------------
-
-in short:
-
-Only a small fix for progressive jpeg suspension problem.
-
-This is the long-awaited final release containing the new 'dynamic MNG' feature
-and bringing MNG compliance to near 100%!
-
--------------------
-
-bugfixes:
-- B683152 - libjpeg suspension not always honored correctly
-
-core:
-
-samples:
-
-contrib:
-
-doc:
-
-makefiles:
-
-autoconf:
-
------------------------------------------------------------
-
-1.0.5-rc3 (jan 20th 2003)
--------------------------
-
-in short:
-
-Third release-candidate for the upcoming 1.0.5 version.
-
-Minor bug-fixes and finalizing the accepted proposal (by official vote) for
-the TERM/frame_delay changes on mng-list (nov-dec/2002).
-
--------------------
-
-bugfixes:
-- B654627 - fixed SEGV when no gettickcount callback (thanks Adam!)
-- B664383 - fixed typo (thanks Dimitri)
-- B664911 - fixed buffer overflow during init (thanks Alex!)
-
-core:
-- finalized changes in TERM/final_delay to elected proposal (positive vote)
-
-samples:
-
-contrib:
-
-doc:
-
-makefiles:
-
-autoconf:
-
------------------------------------------------------------
-
-1.0.5-rc2 (dec 9th 2002)
-------------------------
-
-in short:
-
-Second release-candidate for the upcoming 1.0.5 version.
-This contains fixes for a few minor details reported by the loyal testers.
-It fixes some issues with the goframe/golayer/gotime processing and related
-stuff. And it adds a way to disable playback-caching from within the MNG,
-which is very useful for streaming-MNG encoders (such as gserver!).
-
--------------------
-
-bugfixes:
-
-core:
-- fixed layer- & frame-counting during read()
-- changed FRAMECOUNT/LAYERCOUNT/PLAYTIME error to warning
-- fixed goframe/golayer/gotime processing
-- added support for nEED "MNG 1.1"
-- added support for nEED "CACHEOFF"; turn playback caching off for streaming MNG
-- fixed magnification bug with object 0
-- added support to get totals for frames/layers/playtime after mng_read()
-- fixed some issues in init_app_cms()
-- fixed goxxxxx() support for zero values
-
-samples:
-
-contrib:
-
-doc:
-
-makefiles:
-
-autoconf:
-
------------------------------------------------------------
-
-1.0.5-rc1 (nov 1st 2002)
-------------------------
-
-in short:
-
-First release-candidate for the upcoming 1.0.5 version.
-This fixes a few small problems and brings the TERM/MEND processing, with
-respect to interframe_delay as per the current discussion on MNG-list,
-up-to-date with the latest proposal.
-
--------------------
-
-bugfixes:
-
-core:
-- fixed initialization of pIds in dISC read routine (Thanks Winfried!)
-- fixed issue in freeing evNT chunk (Thanks Winfried!)
-- fixed clipping-problem with BACK tiling (Thanks Sakura!)
-- fixed processing for multiple objects in MAGN (Thanks Sakura!)
-- fixed display of visible target of PAST operation (Thanks Sakura!)
-- modified TERM/MEND processing for max(1, TERM_delay, interframe_delay)
-
-samples:
-
-contrib:
-- fixed typo in Makefile for gtk-mng-view sample
-
-doc:
-
-makefiles:
-
-autoconf:
-
------------------------------------------------------------
-
-1.0.5-b3 (oct 15th 2002)
-------------------------
-
-in short:
-
-Fairly quick after beta2, since that introduced a couple of unfortunate
-booboo's and wasn't very workable. It also changes the standard configure
-script to build a standard shared object similar to what I intended.
-
--------------------
-
-bugfixes:
-
-core:
-- fixed support for condition=2 in TERM chunk
-- fixed trace-constants for PAST chunk
-- added mng_status_dynamic to supports function
-
-samples:
-
-contrib:
-
-doc:
-- small cosmetic changes in man/libmng.3
-
-makefiles:
-
-autoconf:
-- fixed configure.in to build a 'standard' SO primarily
-
------------------------------------------------------------
-
-1.0.5-b2 (oct 9th 2002)
-------------------------
-
-in short:
-
-Second beta for next 1.0.5 release. This addresses some minor problems
-detected during testing. It adds the proposed change to the MNG spec as
-discussed on the "mng-list" recently; eg. Adam's option 4.
-And it adds a little function to check at run-time if the lib is a beta or not.
-
--------------------
-
-bugfixes:
-
-core:
-- fixed chunk-storage for evNT chunk
-- fixed dropping mix of frozen/unfrozen objects
-- fixed problem with cloned objects marked as invalid
-- fixed problem cloning frozen object_buffers
-- fixed DISC support
-- added proposed change in handling of TERM- & interframe-delay
-- added another fix for misplaced TERM chunk
-- added check for TERM placement during create/write
-- completed support for condition=2 in TERM chunk
-- added beta version function & constant
-
-samples:
-
-contrib:
-
-doc:
-
-makefiles:
-
-autoconf:
-
------------------------------------------------------------
-
-1.0.5-b1 (sep 24th 2002)
-------------------------
-
-in short:
-
-First beta of a large maintenance release. This completes support of the MNG
-specification to nearly 100% (PAST, PROM, delta-images, BACK image+tile).
-It adds "dynamic" MNG and a few other neat routines as well as fixes several
-bugs reported through SourceForge or to me directly.
-
--------------------
-
-bugfixes:
-- B575832 - library has wrong patch version number
-- B578572 - remove in 1.0.0!
-- B578940 - some functions not implemented
-- B581625 - large chunks fail with suspension reads
-- B597134 - libmng pollutes the linker namespace
-
-core:
-- added sanity check for improbable chunklengths
-- removed eMNGma hack (thanks Dimitri!)
-- unimplemented functions return an errorcode now
-- added test-option for PNG filter method 192 (= levelling)
-- added test-option for PNG filter method 193 (= no filtering)
-  (both are conditional and only for testing purposes!!!)
-- completed PROM support
-- completed delta-image support
-- completed MAGN support (16-bit functions)
-- added HLAPI function to copy a chunk from a read MNG to a newly created MNG
-- added option for soft-handling of errors (only for repair software!!!)
-- fixed some routine inclusion/exclusion for undefined conditionals 
-- pre-fixed all internal routines with mng_
-- added symbol MNG_LOCAL (= static) to really local functions
-- fixed reading of FRAM with just frame_mode and name
-- fixed read/write of MAGN chunk
-- added event handling for dynamic MNG
-- added 'supports' call to check function availability
-- fixed copyright notice in the headers of all libmng modules
-- fixed LOOP iteration=0 special case
-- re-compiled standard Windows dll with lcms-1.0.9
-- added warning for too much IDAT data
-- warnings are ignored by default now
-- misplaced TERM is now treated as warning
-- fixed color-correction for restore-background handling
-- optimized restore-background for bKGD cases
-- cleaned up some old stuff
-- completed support for BACK image & tiling
-- completed support for PAST
-- added bgrx8 canvas (filler byte)
-- fixed reset_object_detail to clear old buffer
-- added in-memory color-correction of abstract images
-- added compose over/under routines for PAST processing
-- added flip & tile routines for PAST processing
-
-samples:
-- Added new BCB sample for fixing invalid JASC Animation Shop files
-  (shows new copy_chunks function; use of MNG_SOFTERRORS & static linking)
-
-contrib:
-- added xmngview by Winfried Szukalski (Vielen dank!)
-- Updated the Delphi mngview sample to handle dynamic MNGs
-- Added Kylix example (simplified port of the Delphi mngview sample)
-
-doc:
-- added diff to add MNG&JNG to a systems 'magic' file (Thanks Winfried)
-- fixed docs about using mng_display_resume after display_reset
-  (should read to use mng_display!)
-
-makefiles:
-- added makefile to build a libmng.dll for MingW
-  (makefile.mingwdll - thanks to Frank Richter!)
-
-autoconf:
-- fixing libtool version-number to be in line with what it should be
-
------------------------------------------------------------
-
-1.0.4 (Jun 23rd 2002)
----------------------
-
-in short:
-
-Just some small fixes
-Standard dll now compiled with zlib 1.1.4 and lcms 1.0.8
-
--------------------
-
-bugfixes:
-- B495442 - invalid returnvalue in mng_get_suspensionmode
-- B495443 - incorrect suspend check in read_databuffer
-- B526138 - returned IJGSRC6B calling convention to default for MSVC
-- B558212 - off by one error
-- B557677 - can't find lcms.h
-
-core:
-- fixed possible compile-problem in cleanup_rowproc
-- MNG subimage alpha composite wrong for rgba8 images
-
-samples:
-
-contrib:
-
-doc:
-
-makefiles:
-- fixed check for lcms.h in configure.in
-
-autoconf:
-
------------------------------------------------------------
-
-1.0.3 (Sep 18th 2001)
----------------------
-
-in short:
-
-Small cosmetic changes. Cleaning up the contributions.
-New makefile for mingw32, and new fbcon example.
-Major thanks to Greg for helping out with the *nix stuff!
-Note that there's also a separate download for ASM programmers now.
-Check http://www.libmng.com for details (download/ports&packages page).
-
-It may be a while for the next release. I'm "off duty" for the next 8 or
-so months...
-
-Gerard
-
--------------------
-
-bugfixes:
-- B459058 - wrong include for lcms headers
-
-core:
-- changed inclusion of lcms.h header for Linux platforms (suggested by Greg)
-- added get function for last processed BACK chunk
-
-samples:
-- replaced the gtk & sdl viewer apps with updates by Greg Roelofs
-
-contrib:
-
-doc:
-
-makefiles:
-- changed makefile.linux & makefile.unix as suggested by Greg Roelofs
-  (makefile.linux now compiles with lcms by default)
-- added makefile.mingw for mingw32 by Benoit Blanchon (thanks Mate!)
-
-autoconf:
-
------------------------------------------------------------
-
-1.0.2 (Jul 7th 2001)
---------------------
-
-in short:
-
-Another maintenance release with a few added extra's.
-
--------------------
-
-bugfixes:
-- B421427 - writes wrong format in bKGD and tRNS
-- B434583 - compiler-warning if MNG_STORE_CHUNKS undefined
-
-core:
-- added optimization option for MNG-video playback
-- added processterm callback
-- added late binding errorcode (not used internally)
-- fixed memory-leak with delta-images (Thanks Michael!)
-- added option to turn off progressive refresh for large images
-
-samples:
-
-contrib:
-
-doc:
-
-makefiles:
-
-autoconf:
-
------------------------------------------------------------
-
-1.0.1 (May 2nd 2001)
---------------------
-
-in short:
-
-Maintenance release.
-Fixed several memory-leaks with the help of Gregg Kelly, added/fixed some CMS
-handling, exported JPEG functions from standard DLL, and some other minor fixes.
-
-The CMS fix now makes libmng automagically work in MNG_FULL_CMS mode as a
-sRGB compliant system. YOU WILL NEED TO CHANGE THIS IF YOU ARE NOT ON AN sRGB
-COMPLIANT SYSTEM AND WANT TO USE CMS!!!!
-(look in libmng.h for the proper function-calls)
-
--------------------
-
-bugfixes:
-
-core:
-- added MEND processing callback
-- fixed first FRAM_MODE=4 timing problem
-- added handle status-copy function (use with care)
-- exported JPEG functions from standard DLL
-- added BGRA8 canvas with premultiplied alpha (contrib by Gregg Kelly)
-- fixed problem with display_reset/display_resume (Thanks Gregg!)
-- fixed several memory-leaks (Thanks Gregg!)
-- fixed reset_rundata to drop all objects (Thanks again, Gregg!)
-- fixed problem with cms profile being created multiple times when both
-  iCCP & cHRM/gAMA are present (And again... Gregg)
-- moved mng_clear_cms to libmng_cms
-- added "default" sRGB generation (Thanks Marti!)
-
-samples:
-
-contrib:
-
-doc:
-
-makefiles:
-
-autoconf:
-
------------------------------------------------------------
-
-1.0.0 (Feb 6th 2001)
---------------------
-
-in short:
-
-First public release. Finally(!)
-
-This is the 0.9.5 CVS version, which will never be released, because I feel it
-is now ready for a public release. So apart from the version-numbers here and
-there, all other changes are listed under 0.9.5.
-
-This library will work with every MNG/JNG known and available to me. Note that
-there are still parts that need to be coded, and that MNG support is around
-90-95% (JNG at 100%). It is however compliant with the latest and greatest
-MNG 1.0 specification.
-
-I hope to dedicate a bit more time this year to finish up full support and fill
-in the remaining blanks. But this is coming out of my spare time. And extra
-help is always appreciated.
-
-Please enjoy!
-
-Gerard
-
------------------------------------------------------------
-
-0.9.5 (no release)
-------------------
-
-in short:
-
-intermediate CVS
-
--------------------
-
-bugfixes:
-B129681 - fixed compiler warnings SGI/Irix (thanks Dimitri)
-
-core:
-- fixed compiler-warnings Mozilla (thanks Tim)
-- fixed timing-problem with switching framing_modes
-- fixed some small compiler warnings (thanks Nikki)
-
-samples:
-
-contrib:
-- fixed library-paths for MSVC DLL project (thanks Chad)
-
-doc:
-
-makefiles:
-- added makefile for DJGPP (thanks Silvio)
-
-autoconf:
-
------------------------------------------------------------
-
-0.9.4 (Jan 19th 2001)
-----------------------
-
-in short:
-
-Now that the MNG spec is at 1.0, this should be the last beta. There's a few
-small changes to make it inline with the spec, and a couple of bug-fixes.
-This is a serious release-candidate for libmng-1.0!!
-Please... test test test test!!
-
--------------------
-
-bugfixes:
-B123314 - fixed number of TERM related problems
-B123322 - fixed unwanted repetition in mng_readdisplay()
-B123443 - fixed by Ralph
-B124910 - fixed definition for WIN32_LEAN_AND_MEAN (thanks Chad)
-B125750 - fixed by Ralph
-B125756 - fixed mixup of data- & function-pointers (thanks Dimitri)
-B127517 - changed inclusion of the lcms header file for non-windows platforms
-
-core:
-- version numbers
-- fixed possible loop in display_resume() (Thanks Vova!)
-- fixed unwanted repetition in mng_readdisplay()
-- changed inclusion of the lcms header file for non-windows platforms
-- changed IHDR filter_method check for PNGs
-- moved restore of object 0 to libmng_display
-- added restore of object 0 to TERM processing (B123314)
-- fixed TERM delay processing (B123314)
-- fixed TERM end processing when count = 0 (B123314)
-- changed callback convention for MSVC (Thanks Chad)
-- fixed mixup of data- & function-pointers (thanks Dimitri)
-- added support for "nEED MNG-1.0"
-- added errorcode for MAGN methods
-- added errorchecking for MAGN methods
-- removed "old" MAGN methods 3 & 4
-- added "new" MAGN methods 3, 4 & 5
-- removed test filter-methods 1 & 65
-- set default level-set for filtertype=64 to all zeroes
-
-samples:
-
-contrib:
-- added GTK mng-view example by Vova Babin
-- added MSVC MNGview sample by Nikolaus Brennig
-- updated Jason Summer's mngplg to version 0.9.2
-  (that's mngplg-0.9.2 based on libmng-0.9.3 !!!)
-- rearranged contrib directory slightly
-- added MSVC project to build libmng.dll by Chad Austin
-
-doc:
-- added README.dll
-- added README.config
-
-makefiles:
-- added a makefile for MS Visual C++ (Thanks to Atsushi Matsuda)
-
-autoconf:
-- fixed configure.in for lcms (FreeBSD port by Mikhail Teterin)
-- by default configure includes CMS support if lcms is present
-
------------------------------------------------------------
-
-0.9.3 (October 29th 2000)
--------------------------
-
-in short:
-
-Another beta release. The number of changes in the MNG specification have
-resulted in a lot of new code and some changed code. At the same time I saw
-no need to withhold some new functionality as it was pretty clear there was
-going to be another beta-round. If things go well, I'm going to try to release
-libmng 1.0.0 very shortly after this one.
-
-Many thanks to a lot of people for helping out, sending contributions, making
-suggestions and testing this little baby. This would get nowhere without YOU!!!
-
-- fixed bug 111300/117103
-- added workaround for faulty PhotoShop iCCP chunk
-- added MAGN/JDAA chunks
-- added support for new filter_types
-- added PNG/MNG spec version indicators
-- added BCB mngview contribution by Andy Protano
-- added BCB mngdump; a GUI-based MNG dumping utility (Andy Protano)
-- implemented support for nEED "draft nn"
-- implemented app-defined support for bKGD for PNG images
-- removed trace-options from default SO/DLL builds (!!!)
-- raised initial maximum canvas size to 10000x10000 (!!!)
-  (an App that wants to protect from overly large images should call
-   mng_set_maxcanvassize() with appropriate values)
-- fixed other assorted stuff
-
--------------------
-
-bugfixes:
-B111300 - fixup for improved portability
-B117103 - fixed compilation errors on *nix with lcms (thanks Ralph!)
-
-core:
-- fixed compiler-warnings from Mozilla
-- added check for simplicity-bits in MHDR
-- added workaround for faulty PhotoShop iCCP chunk
-- fixed app-supplied background restore
-- fixed TERM processing delay of 0 msecs
-- fixed write-code for zTXt & iTXt
-- fixed read-code for iTXt
-- added MAGN chunk
-- fixed sRGB precedence for gamma_only corection
-- added support for new filter_types
-- fixed problem with no refresh after TERM
-- fixed DEFI behavior
-- fixed inclusion parameters to make the external libs work together
-- added export of zlib functions from windows dll
-- fixed timing & refresh behavior for single PNG/JNG
-- removed trace-options from default SO/DLL builds (!!!)
-- fixed MAGN rounding errors (thanks Matthias!)
-- fixed small timing problem when FRAM delay = 0
-- fixed simplicity-check in compliance with draft 81/0.98a
-- fixed alpha-blending for all alpha-canvasstyles
-- added support for alpha-depth prediction
-- fixed processing of unknown critical chunks
-- removed test-MaGN
-- added PNG/MNG spec version indicators
-- implemented support for nEED
-- added support for JDAA
-- added functions to retrieve PNG/JNG specific header-info
-- added optional support for bKGD for PNG images
-- raised initial maximum canvas size to 10000x10000
-- added support for delta-JNG
-- added callback to process non-critical unknown chunks
-- fixed support for delta-images during read() / display()
-- added closestream() processing for mng_cleanup()
-- fixed delta-processing behavior
-- added storage for pixel-/alpha-sampledepth for delta's
-- implemented delayed delta-processing
-- fixed putchunk_plte() to set bEmpty parameter (thanks Ben!)
-- added errorcode for delayed delta-processing
-- added get/set for bKGD preference setting
-- added get function for interlace/progressive display
-- fixed bug in empty PLTE handling
-- fixed seperate read() & display() processing
-- fixed tRNS processing for gray-image < 8-bits
-
-samples:
-- added BCB mngview contribution by Andy Protano
-
-contrib:
-- added BCB mngdump; a GUI-based MNG dumping utility (Andy Protano)
-
-doc:
-- updated RPM spec-file by MATSUURA Takanori
-- updated README.contrib
-
-makefiles:
-- fixed some stuff in automake/autoconf/libtool
-- fixed auto* for bug B117103
-
------------------------------------------------------------
-
-0.9.2 (August 7th 2000)
------------------------
-
-in short:
-
-Third beta release! Last one???
-
-!!IMPORTANT!! All file-names are now prefixed with "libmng_" !!IMPORTANT!!
-
-Many thanks to Albert Chin-A-Young for his contribution of the
-autoconf/automake/libtool stuff and to Ralph Giles for helping me
-put it in the right places.
-
-There's a special README.autoconf so please read it!
-
-- fixed bug 110320/110546/110547/111096
-- added several status retrieval functions
-- fixed other small bugs in display processing
-- fixed number of small problems and documentation typos
-- added autoconf/automake/libtool
-- added latest MNG plugin (0.9.0) by Jason Summers
-
--------------------
-
-bugfixes:
-B110320 - fixed GCC warning about mix-sized pointer math
-B110546 - fixed for improperly returning UNEXPECTEDEOF
-B110547 - fixed bug in interlace code
-B111096 - fixed large-buffer read-suspension
-
-core:
-- version numbers
-- fixed small bugs in display processing
-- removed Nextbackxxx fields (no longer used)
-- fixed problem with trace-functions improperly wrapped
-- put specific code in add_chunk() inside MNG_SUPPORT_WRITE wrapper
-- fixed documentation typos
-- fixed wrapping of suspension parameters
-- added status_xxxx functions
-- added trace-codes/-strings for status_xxxxx functions
-- changed file-prefixes
-- added function to set simplicity field
-- added trace-code/-string for updatemngsimplicity
-- fixed putchunk_unknown() function
-
-samples:
-
-contrib:
-- added latest MNG plugin (0.9.0) by Jason Summers
-
-doc:
-- version numbers
-- added autoconf readme
-- version numbers in RPM stuff
-
-makefiles:
-- fixed for new file-prefix
-- added autoconf/automake/libtool
-
------------------------------------------------------------
-
-0.9.1 (July 26th 2000)
-----------------------
-
-in short:
-
-Second beta release.
-
-Given the enormous amount of bug-reports (not ;-), this will most likely
-be one of the last betas. If things remain upright, the first public release
-(1.0.0) is fairly eminent in the weeks to come...
-
-- added SDL mng player by Ralph Giles to contributions
-- fixed timing and added internal buffering for I/O-suspension scenarios
-- added get routines for internal display-state variables (frame/layer/playtime)
-- changed read-processing for improved I/O-suspension (internal buffering)
-- fixed several problems with create- & write-support
-- added a load of documentation
-- lots of small stuff
-
--------------------
-
-bugfixes:
-
-core:
-- fixed mandatory BACK color to be opaque
-- changed mng_display_resume to allow to be called after a suspension
-  return with MNG_NEEDMOREDATA
-- changed comments to indicate modified behavior for timer & suspension breaks
-- added variables for go_xxxx processing
-- implemented support for freeze/reset/resume & go_xxxx
-- added trace-codes/-strings for special display processing
-- added variables for improved timing support
-- added support for improved timing
-- added get routines for internal display variables
-- added get/set routines for suspensionmode variable
-- added trace-code/-string for get/set suspensionmode
-- added trace-codes/-strings for get/set display variables
-- added support for improved I/O-suspension
-- changed read-processing for improved I/O-suspension
-- added trace-code/-string for read_databuffer (I/O-suspension)
-- added suspendbuffer constants
-- changed EOF processing behavior
-- fixed TERM delay processing
-- changed pre-draft48 frame_mode=3 to frame_mode=1
-- added callbacks for SAVE/SEEK processing
-- added trace-codes/-strings for SAVE/SEEK callbacks
-- added variable for NEEDSECTIONWAIT breaks
-- added trace-codes/-strings for get/set sectionbreaks
-- added NEEDSECTIONWAIT error-code/-string
-- added macro + routine to set returncode without calling error callback
-- added trace-code/-string for special error routine
-- changed default readbuffer size from 1024 to 4200
-- added variable for freeze & reset processing
-- fixed storage of images during mng_read()
-- fixed support for mng_display() after mng_read()
-- added error cleanup processing
-- fixed support for mng_display_reset()
-- fixed suspension-buffering for 32K+ chunks
-- added function to set frame-/layer-count & playtime
-- added trace-code/-string for updatemngheader
-- added error-code/-string for updatemngheader if not a MNG
-- fixed creation-code
-- fixed writing of signature
-- fixed several chunk-writing routines
-
-samples:
-- fixed the libmng.pas module in line with libmng.h
-
-contrib:
-- added the SDL based mngplay viewer by Ralph Giles
-
-doc:
-- extended the RPM contribution by MATSUURA Takanori
-- added libmng.txt, a full description of the library and its usage
-- added man-pages for mng(5), jng(5) and libmng(3)
-
-makefiles:
-
------------------------------------------------------------
-
-0.9.0 (June 30th 2000)
-----------------------
-
-in short:
-
-This is the first beta!!! Yippee!!!
-
-Thanks to all the people who helped to guide me in the right direction.
-You know who you are!
-
-A special thanks to the guys with early implementations, who stood by and
-put up with my whims :-)
-
-changes over 0.5.3:
-
-- updated mngplg to 0.4.1 (the latest & greatest)
-- changed refresh parameters to 'x,y,width,height'
-
------------------------------------------------------------
-
-0.5.3 (never released)
-----------------------
-
-in short:
-
-This is a working version only; the next release will be 0.9.0 (first Beta!)
-
-There are a few incompatible changes with previous versions. The userdata
-variable has been changed from mng_uint32 to mng_ptr to accomodate 64-bit
-systems. For the same reason memory allocation size parameters have been
-changed to a mng_size_t type which is a typedef of size_t.
-
-Thanks to Aleks Jakulin for helping to iron out some 64-bit platform issues!
-
-- implemented the update-region parameters of the refresh callback
-- added support for most common delta-image options
-- added an animation-speed modifier
-- added an image-level parameter for the processtext callback
-- updated mngplg to 0.4.0 (supports JNG, full CMS, and other enhancements!)
-- fixed a lot of small things
-- added support for PPLT chunk
-- fixed to support 64-bit platforms
-
--------------------
-
-bugfixes:
-
-core:
-- added processing of color-info on delta-image
-- fixed handling of empty SAVE chunk
-- fixed display of stored JNG images
-- fixed problem with BASI-IEND as object 0
-- changed the version parameters (obviously)
-- added update-region parms for refresh calback
-- added Needrefresh parameter
-- added initialization of update-region for refresh
-- added initialization of Needrefresh parameter
-- changed progressive-display processing                  
-- added tracecodes for tracing JPEG progression           
-- added tracing of JPEG calls
-- added Deltaimmediate parm for faster delta-processing
-- added extra checks for delta-images                     
-- many changes to support delta-images
-- optimized some store_xxx routines                       
-- fixed some small things (as precaution)                 
-- fixed possible trouble if IEND display-processing got broken up
-- fixed nasty bug with embedded PNG after delta-image    
-- added processing of PLTE & tRNS for delta-images
-- added processing of PLTE/tRNS & color-info for delta-images in the
-  ani_objects chain
-- fixed problem with color-correction for stored images   
-- added get/set for speedtype to facilitate testing
-- added trace-codes & -strings for get/set speedtype
-- added speed-modifier to timing routine       
-- added get-routine of imagelevel for processtext callback
-- added trace-code & -string for get imagelevel
-- added administration of imagelevel parameter            
-- added support for PPLT chunk                         
-- added trace-codes & -strings for PPLT chunk processing
-- fixed problem with incorrect gamma-correction
-- fixed inclusion of IJG read/write code
-- fixed problem with 16-bit GA format
-- fixed problem with cheap transparency for 4-bit gray
-- fixed display_xxxx routines for interlaced images
-- added precaution against faulty iCCP chunks from PS
-- changed userdata variable to mng_ptr
-- added typedef for mng_size_t
-- changed size parameter for memory allocation to mng_size_t
-- fixed compiler-warning for non-initialized iB variable
-- changed definition for 32-bit ints (64-bit platforms)
-- changed definition for mng_handle (64-bit platforms)
-- swapped refresh parameters
-- fixed initialization routine for new mng_handle type
-- added inclusion of stdlib.h for abs()
-- fixed some 64-bit warnings
-- fixed incompatible return-types
-
-samples:
-
-contrib:
-- updated mngplg to 0.3.0 (supports JNG & full color-correction!)
-- updated mngplg to 0.4.0 (Jason is picking up the pace ;-)
-
-doc:
-- added rpm directory with rpm spec-file (contributed by MATSUURA Takanori)
-
-makefiles:
-- changed makefile.linux to reflect versionnr for shared-lib
-- changed makefile.linux to depend on mng_conf.h & mng_types.h
-
------------------------------------------------------------
-
-0.5.2 (June 10th 2000)
-----------------------
-
-in short:
-
-This is the third release for developers
-Another milestone since JNG is now fully supported
-The next release will most likely be numbered 0.9.0 as the first Beta!!
-
-Fixed bug 106017 & 106019
-Added many constants regarding chunk-property values
-Implemented full JNG support
-Added all the error- & trace-strings
-Added get/set routines for default ZLIB/IJG parameters
-Added a generic makefile for Unix platforms (contributed by Tim Rowley)
-Added canvasstyle for separate RGB + A canvas (eg. mozilla-style)
-Separated configuration-options into a separate file: "mng_conf.h"
-Fixed stuff for generic Unix compilation (contributed by Tim Rowley)
-Upgraded to lcms1.0.6 (now supports 16-bit endian-peculiarities)
-Added a makefile for Linux ELF & fixed some code-issues to go along with gcc
-Added support for suspended input-buffer processing
-Implemented the display-routines for RGBA/ARGB/BGRA/ABGR canvasstyles
-Implemented the application background-restore functionality
-Fixed & tested the mngtree Unix-sample (runs on Linux-RH6.2 with libmng.so)
-Upgraded mngplg to v0.2.2 (based on the latest code including JNG)
-Fixed a lot of other assorted stuff
-
--------------------
-
-bugfixes:
-B003(106017) - fixed problem with <mem.h> being proprietary to BCB
-B004(106019) - fixed problem when MNG_SUPPORT_WRITE not defined
-
-core:
-- bumped version-numbers up to 0.5.2 (yeah, really)
-- fixed support for IJGSRC6B
-- cleaned up some code regarding mixed support-options
-- complemented constants for chunk-property values
-- fixed MNG_UINT_pHYg value
-- implemented JNG support
-- fixed problem with DEFI clipping
-- added error telltale strings & support
-- added trace telltale strings & support
-- added support for global color-chunks inside TERM/LOOP
-- added support for global PLTE,tRNS,bKGD inside TERM/LOOP
-- added default IJG compression parameters and such
-- moved init of default zlib parms to "mng_hlapi.c"
-- added init of default IJG parms
-- added support for get/set of zlib/IJG default parms
-- added tracestrings for global animation color-chunks
-- added tracestrings for get/set of default ZLIB/IJG parms
-- added tracestrings for global PLTE,tRNS,bKGD             
-- added framenr/layernr/playtime to object header          
-- added initialization of framenr/layernr/playtime        
-- changed ani_create calls not returning object pointer
-- create ani objects always (not just inside TERM/LOOP)
-- fixed inconsistancy with freeing global iCCP profile    
-- fixed minor bugs 16-bit pixel-handling                    
-- added object promotion routine (PROM handling)           
-- added trace-codes & -strings for image-object promotion
-- added trace-codes & -strings for delta-image processing
-- added error-codes & -strings for delta-image processing              
-- added support for delta-image processing
-- added ani-object routines for delta-image processing
-- added delta-image fields
-- added compression/filter/interlace fields to object-buffer for
-  delta-image processing                
-- added delta-image row-processing routines
-- fixed up punctuation in several files (contributed by Tim Rowley)       
-- removed useless definition in "mng_chunks.h" (contributed by Tim Rowley)
-- fixed pointer confusion in "mng_display.c" (contributed by Tim Rowley)
-- fixed inclusion for memcpy (contributed by Tim Rowley)
-- added mng_int32p (contributed by Tim Rowley)
-- added internal delta-image processing callbacks
-- separated configuration-options into "mng_conf.h"
-- changed to most likely configuration
-- added RGB8_A8 canvasstyle
-- added getalphaline callback for RGB8_A8 canvasstyle
-- fixed some makeup for Linux gcc compile
-- implemented app bkgd restore routines                   
-- implemented RGBA8, ARGB8, BGRA8 & ABGR8 display routines
-- added support for RGB8_A8 canvasstyle
-- added support for suspended input-buffer processing                   
-- added mng_read_resume HLAPI function to support read-suspension
-- fixed timer-handling to run with Mozilla (Tim Rowley)
-- fixed alpha-handling for alpha canvasstyles             
-- fixed some compilation-warnings (contrib Jason Morris)
-
-samples:
-- fixed mngview(delphi) to work with the new core
-- synchronized libmng.pas(delphi) with the new libmng.h header
-- removed the error- & trace-strings from libmng.pas(delphi)
-- fixed mngtree(Unix) to compile on Linux (runs with libmng.so)
-- added makefile.linux for mngtree(Unix) (tested on RedHat6.2)
-
-contrib:
-- updated mngplg to 0.2.2 (based on latest code; supports JNG!)
-
-doc:
-- this file obviously
-- added Tim Rowley as contributing author
-- changed the examples.readme doc
-- updated the design-schematics in line with the current code
-
-makefiles:
-- changed the directory to "makefiles" to avoid name-conflicts
-- added generic Unix makefile (thanks to Tim Rowley)
-- added Linux ELF makefile (tested on RedHat6.2)
-
------------------------------------------------------------
-
-0.5.1 May 16th 2000
--------------------
-
-in short:
-
-This is the second release for developers
-It's a bit of a milestone since all the chunk functionality is in place and
-functioning (read, examine, create & write)
-This version is incompatible with 0.5.0 since some of the callback prototypes
-have changed (should be the last time that happens!)
-There are a few more samples and even a real contribution!
-
-Fixed bug 105795 & 105797
-Fixed a mis-alignment in animation-timing
-Added chunk-access functions
-Finished all chunk-storage routine-bits
-Finished all chunk-write routines
-Changed the callback prototypes to allow error-reporting back to the library
-Fixed some routines to allow for callback error-reporting
-Added version-control functions & constants
-Added two functions to set display- & sRGB-profile from memory
-Moved CRC table to dynamic structure (for improved thread-safety)
-Added SAVE & SEEK save&restore functionality
-Finished the application-based CMS-callbacks
-Fixed a few BCB specifics
-Changed the Win32 DLL and samples to use __stdcall
-Did some more assorted little changes
-Added 2 BCB samples
-Added 1 Unix sample
-Added the MNG plugin by Jason Summers in the contrib section
-Changed some documents to reflect these changes
-
--------------------
-
-bugfixes:
-B001(105795) - fixed wrong lcms call & memory-leak for gammatables
-B002(105797) - fixed problem with missing sRGB profile
-
-core:
-- changed chunk iteration function
-- added chunk access functions
-- added version control constants & functions
-- changed strict-ANSI stuff
-- added set_outputprofile2 & set_srgbprofile2
-- added empty-chunk put-routines
-- added version_dll & VERSION_DLL (for consistency)
-- added version control explanatory text & samples
-- added iteratechunk callback definition
-- improved definitions for DLL support
-- added 8-bit palette definition
-- added general array definitions
-- added MNG_NULL definition
-- changed most callback prototypes to allow the app
-  to report errors during callback processing
-- added CRC table to main structure (for thread-safety)
-- added iPLTEentries for checking hIST-length
-- changed palette definition to exported palette-type
-- removed frozen indicator
-- added create/write indicators
-- added eMNGma hack (will be removed in 1.0.0 !!!)
-- added TERM animation object pointer (easier reference)
-- added saved-data structure for SAVE/SEEK processing
-- added some errorcodes
-- added application errorcodes (used with callbacks)
-- moved chunk-access errorcodes to severity 5
-- added chunk-access function trace-codes
-- changed trace to macro for callback error-reporting
-- added save_state & restore_state trace-codes
-- put in some extra comments
-- fixed layout for sBIT, PPLT
-- changed write callback definition
-- fixed layout for PPLT again (missed deltatype ?!?)
-- cleaned up left-over teststuff in the BACK chunk routine
-- changed CRC initialization to use dynamic structure
-  (wasn't thread-safe the old way !)
-- filled in many missing sequence&length checks
-- filled in many missing chunk-store snippets
-- added checks for running animations
-- filled remaining write routines
-- fixed read_pplt with regard to deltatype
-- added callback error-reporting support
-- added pre-draft48 support (short MHDR, frame_mode, LOOP)
-- fixed chunk-storage bit in several routines
-- supplemented the SAVE & SEEK display processing
-- added init of iPLTEcount
-- changed calling-convention definition
-- changed status-handling of display-routines
-- added versioning-control routines
-- filled the write routine
-- fixed frame_delay misalignment
-- added sanity check for frozen status
-- changed display_mend to reset state to initial or SAVE
-- added save_state and restore_state for SAVE/SEEK/TERM
-  processing
-- added process_save & process_seek routines
-- changed and filled iterate-chunk function
-- added getchunk functions
-- added putchunk functions
-- added empty-chunk put-routines
-- filled application-based color-management routines
-- added creatememprofile
-- filled the deflatedata routine
-- added cleanup of saved-data (SAVE/SEEK processing)
-- moved the actual write_graphic functionality from mng_hlapi.c
-  to it's appropriate function in the mng_write.c module
-- moved standard header includes into mng_types.h
-  (stdlib/mem for mem-mngmt & math for fp gamma-calc)
-- added getimgdata & putimgdata functions
-
-samples:
-- fixed mngview(delphi) to work with the new core
-- synchronized libmng.pas(delphi) with the new libmng.h header
-- added mngtree(bcb) sample
-- added bogus(bcb) sample
-- added mngtree(unix) sample
-
-contrib:
-- added mngplg 0.1.0 / a MNG plugin for Win32 by Jason Summers
-
-doc:
-- added this changes.readme file
-- changed the samples.readme doc accordingly
-- changed the contrib.readme doc accordingly
-
------------------------------------------------------------
-
-0.5.0 May 1st 2000
-------------------
-
-in short:
-
-This is the first developers release.
-It's roughly about 60% done.
diff --git a/Source/LibMNG/LICENSE b/Source/LibMNG/LICENSE
deleted file mode 100644
index 5878e32..0000000
--- a/Source/LibMNG/LICENSE
+++ /dev/null
@@ -1,57 +0,0 @@
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * COPYRIGHT NOTICE:                                                      * */
-/* *                                                                        * */
-/* * Copyright (c) 2000-2007 Gerard Juyn (gerard at libmng.com)                     * */
-/* * [You may insert additional notices after this sentence if you modify   * */
-/* *  this source]                                                          * */
-/* *                                                                        * */
-/* * For the purposes of this copyright and license, "Contributing Authors" * */
-/* * is defined as the following set of individuals:                        * */
-/* *                                                                        * */
-/* *    Gerard Juyn                                                         * */
-/* *    Glenn Randers-Pehrson                                               * */
-/* *                                                                        * */
-/* * The MNG Library is supplied "AS IS".  The Contributing Authors         * */
-/* * disclaim all warranties, expressed or implied, including, without      * */
-/* * limitation, the warranties of merchantability and of fitness for any   * */
-/* * purpose.  The Contributing Authors assume no liability for direct,     * */
-/* * indirect, incidental, special, exemplary, or consequential damages,    * */
-/* * which may result from the use of the MNG Library, even if advised of   * */
-/* * the possibility of such damage.                                        * */
-/* *                                                                        * */
-/* * Permission is hereby granted to use, copy, modify, and distribute this * */
-/* * source code, or portions hereof, for any purpose, without fee, subject * */
-/* * to the following restrictions:                                         * */
-/* *                                                                        * */
-/* * 1. The origin of this source code must not be misrepresented;          * */
-/* *    you must not claim that you wrote the original software.            * */
-/* *                                                                        * */
-/* * 2. Altered versions must be plainly marked as such and must not be     * */
-/* *    misrepresented as being the original source.                        * */
-/* *                                                                        * */
-/* * 3. This Copyright notice may not be removed or altered from any source * */
-/* *    or altered source distribution.                                     * */
-/* *                                                                        * */
-/* * The Contributing Authors specifically permit, without fee, and         * */
-/* * encourage the use of this source code as a component to supporting     * */
-/* * the MNG and JNG file format in commercial products.  If you use this   * */
-/* * source code in a product, acknowledgment would be highly appreciated.  * */
-/* *                                                                        * */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Parts of this software have been adapted from the libpng package.      * */
-/* * Although this library supports all features from the PNG specification * */
-/* * (as MNG descends from it) it does not require the libpng package.      * */
-/* * It does require the zlib library and optionally the IJG jpeg library,  * */
-/* * and/or the "little-cms" library by Marti Maria (depending on the       * */
-/* * inclusion of support for JNG and Full-Color-Management respectively.   * */
-/* *                                                                        * */
-/* * This library's function is primarily to read and display MNG           * */
-/* * animations. It is not meant as a full-featured image-editing           * */
-/* * component! It does however offer creation and editing functionality    * */
-/* * at the chunk level.                                                    * */
-/* * (future modifications may include some more support for creation       * */
-/* *  and or editing)                                                       * */
-/* *                                                                        * */
-/* ************************************************************************** */
diff --git a/Source/LibMNG/LibMNG.2003.vcproj b/Source/LibMNG/LibMNG.2003.vcproj
deleted file mode 100644
index 6536fb3..0000000
--- a/Source/LibMNG/LibMNG.2003.vcproj
+++ /dev/null
@@ -1,520 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-
-<VisualStudioProject
-
-	ProjectType="Visual C++"
-
-	Version="7.10"
-
-	Name="LibMNG"
-
-	SccProjectName=""
-
-	SccLocalPath="">
-
-	<Platforms>
-
-		<Platform
-
-			Name="Win32"/>
-
-	</Platforms>
-
-	<Configurations>
-
-		<Configuration
-
-			Name="Release|Win32"
-
-			OutputDirectory=".\Release"
-
-			IntermediateDirectory=".\Release"
-
-			ConfigurationType="4"
-
-			UseOfMFC="0"
-
-			ATLMinimizesCRunTimeLibraryUsage="FALSE"
-
-			CharacterSet="2">
-
-			<Tool
-
-				Name="VCCLCompilerTool"
-
-				Optimization="2"
-
-				GlobalOptimizations="TRUE"
-
-				InlineFunctionExpansion="2"
-
-				EnableIntrinsicFunctions="TRUE"
-
-				FavorSizeOrSpeed="1"
-
-				OmitFramePointers="TRUE"
-
-				OptimizeForProcessor="3"
-
-				AdditionalIncludeDirectories="..\Zlib,..\libjpeg"
-
-				PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
-
-				StringPooling="TRUE"
-
-				RuntimeLibrary="0"
-
-				BufferSecurityCheck="FALSE"
-
-				UsePrecompiledHeader="2"
-
-				PrecompiledHeaderFile=".\Release/LibMNG.pch"
-
-				AssemblerListingLocation=".\Release/"
-
-				ObjectFile=".\Release/"
-
-				ProgramDataBaseFileName=".\Release/"
-
-				WarningLevel="3"
-
-				SuppressStartupBanner="TRUE"
-
-				CompileAs="0"/>
-
-			<Tool
-
-				Name="VCCustomBuildTool"/>
-
-			<Tool
-
-				Name="VCLibrarianTool"
-
-				OutputFile=".\Release\LibMNG.lib"
-
-				SuppressStartupBanner="TRUE"/>
-
-			<Tool
-
-				Name="VCMIDLTool"/>
-
-			<Tool
-
-				Name="VCPostBuildEventTool"/>
-
-			<Tool
-
-				Name="VCPreBuildEventTool"/>
-
-			<Tool
-
-				Name="VCPreLinkEventTool"/>
-
-			<Tool
-
-				Name="VCResourceCompilerTool"
-
-				PreprocessorDefinitions="NDEBUG"
-
-				Culture="1043"/>
-
-			<Tool
-
-				Name="VCWebServiceProxyGeneratorTool"/>
-
-			<Tool
-
-				Name="VCXMLDataGeneratorTool"/>
-
-			<Tool
-
-				Name="VCManagedWrapperGeneratorTool"/>
-
-			<Tool
-
-				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
-
-		</Configuration>
-
-		<Configuration
-
-			Name="Debug|Win32"
-
-			OutputDirectory=".\Debug"
-
-			IntermediateDirectory=".\Debug"
-
-			ConfigurationType="4"
-
-			UseOfMFC="0"
-
-			ATLMinimizesCRunTimeLibraryUsage="FALSE"
-
-			CharacterSet="2">
-
-			<Tool
-
-				Name="VCCLCompilerTool"
-
-				Optimization="0"
-
-				AdditionalIncludeDirectories="..\ZLib,..\LibJPEG"
-
-				PreprocessorDefinitions="WIN32;_DEBUG;_LIB;MNG_BUILD_SO"
-
-				StringPooling="TRUE"
-
-				BasicRuntimeChecks="3"
-
-				RuntimeLibrary="1"
-
-				UsePrecompiledHeader="2"
-
-				PrecompiledHeaderFile=".\Debug/LibMNG.pch"
-
-				AssemblerListingLocation=".\Debug/"
-
-				ObjectFile=".\Debug/"
-
-				ProgramDataBaseFileName=".\Debug/"
-
-				WarningLevel="3"
-
-				SuppressStartupBanner="TRUE"
-
-				DebugInformationFormat="4"
-
-				CompileAs="0"/>
-
-			<Tool
-
-				Name="VCCustomBuildTool"/>
-
-			<Tool
-
-				Name="VCLibrarianTool"
-
-				OutputFile=".\Debug\LibMNG.lib"
-
-				SuppressStartupBanner="TRUE"/>
-
-			<Tool
-
-				Name="VCMIDLTool"/>
-
-			<Tool
-
-				Name="VCPostBuildEventTool"/>
-
-			<Tool
-
-				Name="VCPreBuildEventTool"/>
-
-			<Tool
-
-				Name="VCPreLinkEventTool"/>
-
-			<Tool
-
-				Name="VCResourceCompilerTool"
-
-				PreprocessorDefinitions="_DEBUG"
-
-				Culture="1043"/>
-
-			<Tool
-
-				Name="VCWebServiceProxyGeneratorTool"/>
-
-			<Tool
-
-				Name="VCXMLDataGeneratorTool"/>
-
-			<Tool
-
-				Name="VCManagedWrapperGeneratorTool"/>
-
-			<Tool
-
-				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
-
-		</Configuration>
-
-	</Configurations>
-
-	<References>
-
-	</References>
-
-	<Files>
-
-		<Filter
-
-			Name="Source Files"
-
-			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
-
-			<File
-
-				RelativePath="libmng_callback_xs.c">
-
-			</File>
-
-			<File
-
-				RelativePath="libmng_chunk_descr.c">
-
-			</File>
-
-			<File
-
-				RelativePath="libmng_chunk_io.c">
-
-			</File>
-
-			<File
-
-				RelativePath="libmng_chunk_prc.c">
-
-			</File>
-
-			<File
-
-				RelativePath="libmng_chunk_xs.c">
-
-			</File>
-
-			<File
-
-				RelativePath="libmng_cms.c">
-
-			</File>
-
-			<File
-
-				RelativePath="libmng_display.c">
-
-			</File>
-
-			<File
-
-				RelativePath="libmng_dither.c">
-
-			</File>
-
-			<File
-
-				RelativePath="libmng_error.c">
-
-			</File>
-
-			<File
-
-				RelativePath="libmng_filter.c">
-
-			</File>
-
-			<File
-
-				RelativePath="libmng_hlapi.c">
-
-			</File>
-
-			<File
-
-				RelativePath="libmng_jpeg.c">
-
-			</File>
-
-			<File
-
-				RelativePath="libmng_object_prc.c">
-
-			</File>
-
-			<File
-
-				RelativePath="libmng_pixels.c">
-
-			</File>
-
-			<File
-
-				RelativePath="libmng_prop_xs.c">
-
-			</File>
-
-			<File
-
-				RelativePath="libmng_read.c">
-
-			</File>
-
-			<File
-
-				RelativePath="libmng_trace.c">
-
-			</File>
-
-			<File
-
-				RelativePath="libmng_write.c">
-
-			</File>
-
-			<File
-
-				RelativePath="libmng_zlib.c">
-
-			</File>
-
-		</Filter>
-
-		<Filter
-
-			Name="Header Files"
-
-			Filter="h;hpp;hxx;hm;inl">
-
-			<File
-
-				RelativePath="libmng.h">
-
-			</File>
-
-			<File
-
-				RelativePath="libmng_chunk_descr.h">
-
-			</File>
-
-			<File
-
-				RelativePath="libmng_chunk_io.h">
-
-			</File>
-
-			<File
-
-				RelativePath="libmng_chunk_prc.h">
-
-			</File>
-
-			<File
-
-				RelativePath="libmng_chunks.h">
-
-			</File>
-
-			<File
-
-				RelativePath="libmng_cms.h">
-
-			</File>
-
-			<File
-
-				RelativePath="libmng_conf.h">
-
-			</File>
-
-			<File
-
-				RelativePath="libmng_data.h">
-
-			</File>
-
-			<File
-
-				RelativePath="libmng_display.h">
-
-			</File>
-
-			<File
-
-				RelativePath="libmng_dither.h">
-
-			</File>
-
-			<File
-
-				RelativePath="libmng_error.h">
-
-			</File>
-
-			<File
-
-				RelativePath="libmng_filter.h">
-
-			</File>
-
-			<File
-
-				RelativePath="libmng_jpeg.h">
-
-			</File>
-
-			<File
-
-				RelativePath="libmng_memory.h">
-
-			</File>
-
-			<File
-
-				RelativePath="libmng_object_prc.h">
-
-			</File>
-
-			<File
-
-				RelativePath="libmng_objects.h">
-
-			</File>
-
-			<File
-
-				RelativePath="libmng_pixels.h">
-
-			</File>
-
-			<File
-
-				RelativePath="libmng_read.h">
-
-			</File>
-
-			<File
-
-				RelativePath="libmng_trace.h">
-
-			</File>
-
-			<File
-
-				RelativePath="libmng_types.h">
-
-			</File>
-
-			<File
-
-				RelativePath="libmng_write.h">
-
-			</File>
-
-			<File
-
-				RelativePath="libmng_zlib.h">
-
-			</File>
-
-		</Filter>
-
-	</Files>
-
-	<Globals>
-
-	</Globals>
-
-</VisualStudioProject>
-
diff --git a/Source/LibMNG/LibMNG.2005.vcproj b/Source/LibMNG/LibMNG.2005.vcproj
deleted file mode 100644
index f00a2d8..0000000
--- a/Source/LibMNG/LibMNG.2005.vcproj
+++ /dev/null
@@ -1,509 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="8,00"
-	Name="LibMNG"
-	ProjectGUID="{912A2D43-35A3-4AF2-B2EB-0D81EFFDA6DC}"
-	RootNamespace="LibMNG"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-		<Platform
-			Name="x64"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Release|Win32"
-			OutputDirectory=".\Release"
-			IntermediateDirectory=".\Release"
-			ConfigurationType="4"
-			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="2"
-				InlineFunctionExpansion="2"
-				EnableIntrinsicFunctions="true"
-				FavorSizeOrSpeed="1"
-				OmitFramePointers="true"
-				AdditionalIncludeDirectories="..\Zlib,..\libjpeg"
-				PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE"
-				StringPooling="true"
-				RuntimeLibrary="0"
-				BufferSecurityCheck="false"
-				UsePrecompiledHeader="0"
-				PrecompiledHeaderFile=".\Release/LibMNG.pch"
-				AssemblerListingLocation=".\Release/"
-				ObjectFile=".\Release/"
-				ProgramDataBaseFileName=".\Release/"
-				WarningLevel="3"
-				SuppressStartupBanner="true"
-				CompileAs="0"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="1043"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile=".\Release\LibMNG.lib"
-				SuppressStartupBanner="true"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|Win32"
-			OutputDirectory=".\Debug"
-			IntermediateDirectory=".\Debug"
-			ConfigurationType="4"
-			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="0"
-				AdditionalIncludeDirectories="..\ZLib,..\LibJPEG"
-				PreprocessorDefinitions="WIN32;_DEBUG;_LIB;MNG_BUILD_SO;_CRT_SECURE_NO_DEPRECATE"
-				StringPooling="true"
-				BasicRuntimeChecks="3"
-				RuntimeLibrary="1"
-				UsePrecompiledHeader="0"
-				PrecompiledHeaderFile=".\Debug/LibMNG.pch"
-				AssemblerListingLocation=".\Debug/"
-				ObjectFile=".\Debug/"
-				ProgramDataBaseFileName=".\Debug/"
-				WarningLevel="3"
-				SuppressStartupBanner="true"
-				DebugInformationFormat="4"
-				CompileAs="0"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="_DEBUG"
-				Culture="1043"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile=".\Debug\LibMNG.lib"
-				SuppressStartupBanner="true"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|x64"
-			OutputDirectory="$(PlatformName)\$(ConfigurationName)"
-			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
-			ConfigurationType="4"
-			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="2"
-				InlineFunctionExpansion="2"
-				EnableIntrinsicFunctions="true"
-				FavorSizeOrSpeed="1"
-				OmitFramePointers="true"
-				AdditionalIncludeDirectories="..\Zlib,..\libjpeg"
-				PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE"
-				StringPooling="true"
-				RuntimeLibrary="0"
-				BufferSecurityCheck="false"
-				UsePrecompiledHeader="0"
-				PrecompiledHeaderFile=".\Release/LibMNG.pch"
-				AssemblerListingLocation=".\Release/"
-				ObjectFile=".\Release/"
-				ProgramDataBaseFileName=".\Release/"
-				WarningLevel="3"
-				SuppressStartupBanner="true"
-				CompileAs="0"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="1043"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile=".\Release\LibMNG.lib"
-				SuppressStartupBanner="true"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|x64"
-			OutputDirectory="$(PlatformName)\$(ConfigurationName)"
-			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
-			ConfigurationType="4"
-			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="0"
-				AdditionalIncludeDirectories="..\ZLib,..\LibJPEG"
-				PreprocessorDefinitions="WIN32;_DEBUG;_LIB;MNG_BUILD_SO;_CRT_SECURE_NO_DEPRECATE"
-				StringPooling="true"
-				BasicRuntimeChecks="3"
-				RuntimeLibrary="1"
-				UsePrecompiledHeader="0"
-				PrecompiledHeaderFile=".\Debug/LibMNG.pch"
-				AssemblerListingLocation=".\Debug/"
-				ObjectFile=".\Debug/"
-				ProgramDataBaseFileName=".\Debug/"
-				WarningLevel="3"
-				SuppressStartupBanner="true"
-				DebugInformationFormat="3"
-				CompileAs="0"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="_DEBUG"
-				Culture="1043"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile=".\Debug\LibMNG.lib"
-				SuppressStartupBanner="true"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Source Files"
-			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-			>
-			<File
-				RelativePath="libmng_callback_xs.c"
-				>
-			</File>
-			<File
-				RelativePath="libmng_chunk_descr.c"
-				>
-			</File>
-			<File
-				RelativePath="libmng_chunk_io.c"
-				>
-			</File>
-			<File
-				RelativePath="libmng_chunk_prc.c"
-				>
-			</File>
-			<File
-				RelativePath="libmng_chunk_xs.c"
-				>
-			</File>
-			<File
-				RelativePath="libmng_cms.c"
-				>
-			</File>
-			<File
-				RelativePath="libmng_display.c"
-				>
-			</File>
-			<File
-				RelativePath="libmng_dither.c"
-				>
-			</File>
-			<File
-				RelativePath="libmng_error.c"
-				>
-			</File>
-			<File
-				RelativePath="libmng_filter.c"
-				>
-			</File>
-			<File
-				RelativePath="libmng_hlapi.c"
-				>
-			</File>
-			<File
-				RelativePath="libmng_jpeg.c"
-				>
-			</File>
-			<File
-				RelativePath="libmng_object_prc.c"
-				>
-			</File>
-			<File
-				RelativePath="libmng_pixels.c"
-				>
-			</File>
-			<File
-				RelativePath="libmng_prop_xs.c"
-				>
-			</File>
-			<File
-				RelativePath="libmng_read.c"
-				>
-			</File>
-			<File
-				RelativePath="libmng_trace.c"
-				>
-			</File>
-			<File
-				RelativePath="libmng_write.c"
-				>
-			</File>
-			<File
-				RelativePath="libmng_zlib.c"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="Header Files"
-			Filter="h;hpp;hxx;hm;inl"
-			>
-			<File
-				RelativePath="libmng.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_chunk_descr.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_chunk_io.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_chunk_prc.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_chunks.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_cms.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_conf.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_data.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_display.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_dither.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_error.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_filter.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_jpeg.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_memory.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_object_prc.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_objects.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_pixels.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_read.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_trace.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_types.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_write.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_zlib.h"
-				>
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
diff --git a/Source/LibMNG/LibMNG.2008.vcproj b/Source/LibMNG/LibMNG.2008.vcproj
deleted file mode 100644
index 80af6b9..0000000
--- a/Source/LibMNG/LibMNG.2008.vcproj
+++ /dev/null
@@ -1,510 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="9,00"
-	Name="LibMNG"
-	ProjectGUID="{912A2D43-35A3-4AF2-B2EB-0D81EFFDA6DC}"
-	RootNamespace="LibMNG"
-	TargetFrameworkVersion="131072"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-		<Platform
-			Name="x64"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Release|Win32"
-			OutputDirectory=".\Release"
-			IntermediateDirectory=".\Release"
-			ConfigurationType="4"
-			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="2"
-				InlineFunctionExpansion="2"
-				EnableIntrinsicFunctions="true"
-				FavorSizeOrSpeed="1"
-				OmitFramePointers="true"
-				AdditionalIncludeDirectories="..\Zlib,..\libjpeg"
-				PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE"
-				StringPooling="true"
-				RuntimeLibrary="0"
-				BufferSecurityCheck="false"
-				UsePrecompiledHeader="0"
-				PrecompiledHeaderFile=".\Release/LibMNG.pch"
-				AssemblerListingLocation=".\Release/"
-				ObjectFile=".\Release/"
-				ProgramDataBaseFileName=".\Release/"
-				WarningLevel="3"
-				SuppressStartupBanner="true"
-				CompileAs="0"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="1043"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile=".\Release\LibMNG.lib"
-				SuppressStartupBanner="true"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|Win32"
-			OutputDirectory=".\Debug"
-			IntermediateDirectory=".\Debug"
-			ConfigurationType="4"
-			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="0"
-				AdditionalIncludeDirectories="..\ZLib,..\LibJPEG"
-				PreprocessorDefinitions="WIN32;_DEBUG;_LIB;MNG_BUILD_SO;_CRT_SECURE_NO_DEPRECATE"
-				StringPooling="true"
-				BasicRuntimeChecks="3"
-				RuntimeLibrary="1"
-				UsePrecompiledHeader="0"
-				PrecompiledHeaderFile=".\Debug/LibMNG.pch"
-				AssemblerListingLocation=".\Debug/"
-				ObjectFile=".\Debug/"
-				ProgramDataBaseFileName=".\Debug/"
-				WarningLevel="3"
-				SuppressStartupBanner="true"
-				DebugInformationFormat="4"
-				CompileAs="0"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="_DEBUG"
-				Culture="1043"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile=".\Debug\LibMNG.lib"
-				SuppressStartupBanner="true"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|x64"
-			OutputDirectory="$(PlatformName)\$(ConfigurationName)"
-			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
-			ConfigurationType="4"
-			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="2"
-				InlineFunctionExpansion="2"
-				EnableIntrinsicFunctions="true"
-				FavorSizeOrSpeed="1"
-				OmitFramePointers="true"
-				AdditionalIncludeDirectories="..\Zlib,..\libjpeg"
-				PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE"
-				StringPooling="true"
-				RuntimeLibrary="0"
-				BufferSecurityCheck="false"
-				UsePrecompiledHeader="0"
-				PrecompiledHeaderFile=".\Release/LibMNG.pch"
-				AssemblerListingLocation=".\Release/"
-				ObjectFile=".\Release/"
-				ProgramDataBaseFileName=".\Release/"
-				WarningLevel="3"
-				SuppressStartupBanner="true"
-				CompileAs="0"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="1043"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile=".\Release\LibMNG.lib"
-				SuppressStartupBanner="true"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|x64"
-			OutputDirectory="$(PlatformName)\$(ConfigurationName)"
-			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
-			ConfigurationType="4"
-			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="0"
-				AdditionalIncludeDirectories="..\ZLib,..\LibJPEG"
-				PreprocessorDefinitions="WIN32;_DEBUG;_LIB;MNG_BUILD_SO;_CRT_SECURE_NO_DEPRECATE"
-				StringPooling="true"
-				BasicRuntimeChecks="3"
-				RuntimeLibrary="1"
-				UsePrecompiledHeader="0"
-				PrecompiledHeaderFile=".\Debug/LibMNG.pch"
-				AssemblerListingLocation=".\Debug/"
-				ObjectFile=".\Debug/"
-				ProgramDataBaseFileName=".\Debug/"
-				WarningLevel="3"
-				SuppressStartupBanner="true"
-				DebugInformationFormat="3"
-				CompileAs="0"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="_DEBUG"
-				Culture="1043"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile=".\Debug\LibMNG.lib"
-				SuppressStartupBanner="true"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Source Files"
-			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-			>
-			<File
-				RelativePath="libmng_callback_xs.c"
-				>
-			</File>
-			<File
-				RelativePath="libmng_chunk_descr.c"
-				>
-			</File>
-			<File
-				RelativePath="libmng_chunk_io.c"
-				>
-			</File>
-			<File
-				RelativePath="libmng_chunk_prc.c"
-				>
-			</File>
-			<File
-				RelativePath="libmng_chunk_xs.c"
-				>
-			</File>
-			<File
-				RelativePath="libmng_cms.c"
-				>
-			</File>
-			<File
-				RelativePath="libmng_display.c"
-				>
-			</File>
-			<File
-				RelativePath="libmng_dither.c"
-				>
-			</File>
-			<File
-				RelativePath="libmng_error.c"
-				>
-			</File>
-			<File
-				RelativePath="libmng_filter.c"
-				>
-			</File>
-			<File
-				RelativePath="libmng_hlapi.c"
-				>
-			</File>
-			<File
-				RelativePath="libmng_jpeg.c"
-				>
-			</File>
-			<File
-				RelativePath="libmng_object_prc.c"
-				>
-			</File>
-			<File
-				RelativePath="libmng_pixels.c"
-				>
-			</File>
-			<File
-				RelativePath="libmng_prop_xs.c"
-				>
-			</File>
-			<File
-				RelativePath="libmng_read.c"
-				>
-			</File>
-			<File
-				RelativePath="libmng_trace.c"
-				>
-			</File>
-			<File
-				RelativePath="libmng_write.c"
-				>
-			</File>
-			<File
-				RelativePath="libmng_zlib.c"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="Header Files"
-			Filter="h;hpp;hxx;hm;inl"
-			>
-			<File
-				RelativePath="libmng.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_chunk_descr.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_chunk_io.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_chunk_prc.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_chunks.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_cms.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_conf.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_data.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_display.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_dither.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_error.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_filter.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_jpeg.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_memory.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_object_prc.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_objects.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_pixels.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_read.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_trace.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_types.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_write.h"
-				>
-			</File>
-			<File
-				RelativePath="libmng_zlib.h"
-				>
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
diff --git a/Source/LibMNG/README b/Source/LibMNG/README
deleted file mode 100644
index 35b1259..0000000
--- a/Source/LibMNG/README
+++ /dev/null
@@ -1,36 +0,0 @@
-libmng 1.0.10
--------------
-
-Added provisional ANG and anIM support, and made some minor bugfixes.
-
-libmng 1.0.9
-------------
-
-A number of optimizations in the chunk handling and reader/writer code.
-This saves over 20KB on binary footprint!
-
-Also several bugfixes and a couple of patches bring it another step
-closer to perfection.... :-)
-
-See CHANGELOG for details.
-
-
-Y.T.
-
-Gerard
-
-
-For more information please visit:
-
-The official libmng web-site:
-  http://www.libmng.com/
-
-Libmng's community on SourceForge:
-  https://sourceforge.net/project/?group_id=5635
-
-The official MNG homepage:
-  http://www.libpng.org/pub/mng/
-
-The official PNG homepage:
-  http://www.libpng.org/pub/png/
-
diff --git a/Source/LibMNG/README.autoconf b/Source/LibMNG/README.autoconf
deleted file mode 100644
index 97167b7..0000000
--- a/Source/LibMNG/README.autoconf
+++ /dev/null
@@ -1,213 +0,0 @@
-**********************************************************************
-**********************************************************************
-
-                ***** this is unmaintained *****
-
-If you happen to find problems with autoconfiguration and building,
-I simply cannot help you. I'm looking for a maintainer that doesn't mind
-spending a few minutes every now and then on the next release to make sure
-things are still in working order.
-
-For the moment all autoconf stuff ahs been moved into unmaintained!!
-
-**********************************************************************
-**********************************************************************
-
-
-
-
-Configuration from CVS
-======================
-
-If you're using source checked out from CVS, rather than a source
-distribution tarball, please be aware that you can use ./autogen.sh in
-place of ./configure below.
-
-Because this is a cross-platform project, the source templates for
-the autoconf scripts are sequestered in the 'makefiles' directory.
-Running './autogen.sh' will copy them into their conventional places at
-the lop level. If you already see the files there, you don't need to
-worry about this step.
-
-Basic Installation
-==================
-
-   These are generic installation instructions.
-
-   The `configure' shell script attempts to guess correct values for
-various system-dependent variables used during compilation.  It uses
-those values to create a `Makefile' in each directory of the package.
-It may also create one or more `.h' files containing system-dependent
-definitions.  Finally, it creates a shell script `config.status' that
-you can run in the future to recreate the current configuration, a file
-`config.cache' that saves the results of its tests to speed up
-reconfiguring, and a file `config.log' containing compiler output
-(useful mainly for debugging `configure').
-
-   If you need to do unusual things to compile the package, please try
-to figure out how `configure' could check whether to do them, and mail
-diffs or instructions to the address given in the `README' so they can
-be considered for the next release.  If at some point `config.cache'
-contains results you don't want to keep, you may remove or edit it.
-
-   The file `configure.in' is used to create `configure' by a program
-called `autoconf'.  You only need `configure.in' if you want to change
-it or regenerate `configure' using a newer version of `autoconf'.
-
-The simplest way to compile this package is:
-
-  1. `cd' to the directory containing the package's source code and type
-     `./configure' to configure the package for your system.  If you're
-     using `csh' on an old version of System V, you might need to type
-     `sh ./configure' instead to prevent `csh' from trying to execute
-     `configure' itself.
-
-     Running `configure' takes awhile.  While running, it prints some
-     messages telling which features it is checking for.
-
-  2. Type `make' to compile the package.
-
-  3. Optionally, type `make check' to run any self-tests that come with
-     the package.
-
-  4. Type `make install' to install the programs and any data files and
-     documentation.
-
-  5. You can remove the program binaries and object files from the
-     source code directory by typing `make clean'.  To also remove the
-     files that `configure' created (so you can compile the package for
-     a different kind of computer), type `make distclean'.  There is
-     also a `make maintainer-clean' target, but that is intended mainly
-     for the package's developers.  If you use it, you may have to get
-     all sorts of other programs in order to regenerate files that came
-     with the distribution.
-
-Compilers and Options
-=====================
-
-   Some systems require unusual options for compilation or linking that
-the `configure' script does not know about.  You can give `configure'
-initial values for variables by setting them in the environment.  Using
-a Bourne-compatible shell, you can do that on the command line like
-this:
-     CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
-
-Or on systems that have the `env' program, you can do it like this:
-     env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
-
-Compiling For Multiple Architectures
-====================================
-
-   You can compile the package for more than one kind of computer at the
-same time, by placing the object files for each architecture in their
-own directory.  To do this, you must use a version of `make' that
-supports the `VPATH' variable, such as GNU `make'.  `cd' to the
-directory where you want the object files and executables to go and run
-the `configure' script.  `configure' automatically checks for the
-source code in the directory that `configure' is in and in `..'.
-
-   If you have to use a `make' that does not supports the `VPATH'
-variable, you have to compile the package for one architecture at a time
-in the source code directory.  After you have installed the package for
-one architecture, use `make distclean' before reconfiguring for another
-architecture.
-
-Installation Names
-==================
-
-   By default, `make install' will install the package's files in
-`/usr/local/bin', `/usr/local/man', etc.  You can specify an
-installation prefix other than `/usr/local' by giving `configure' the
-option `--prefix=PATH'.
-
-   You can specify separate installation prefixes for
-architecture-specific files and architecture-independent files.  If you
-give `configure' the option `--exec-prefix=PATH', the package will use
-PATH as the prefix for installing programs and libraries.
-Documentation and other data files will still use the regular prefix.
-
-   In addition, if you use an unusual directory layout you can give
-options like `--bindir=PATH' to specify different values for particular
-kinds of files.  Run `configure --help' for a list of the directories
-you can set and what kinds of files go in them.
-
-   If the package supports it, you can cause programs to be installed
-with an extra prefix or suffix on their names by giving `configure' the
-option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
-
-Optional Features
-=================
-
-   Some packages pay attention to `--enable-FEATURE' options to
-`configure', where FEATURE indicates an optional part of the package.
-They may also pay attention to `--with-PACKAGE' options, where PACKAGE
-is something like `gnu-as' or `x' (for the X Window System).  The
-`README' should mention any `--enable-' and `--with-' options that the
-package recognizes.
-
-   For packages that use the X Window System, `configure' can usually
-find the X include and library files automatically, but if it doesn't,
-you can use the `configure' options `--x-includes=DIR' and
-`--x-libraries=DIR' to specify their locations.
-
-Specifying the System Type
-==========================
-
-   There may be some features `configure' can not figure out
-automatically, but needs to determine by the type of host the package
-will run on.  Usually `configure' can figure that out, but if it prints
-a message saying it can not guess the host type, give it the
-`--host=TYPE' option.  TYPE can either be a short name for the system
-type, such as `sun4', or a canonical name with three fields:
-     CPU-COMPANY-SYSTEM
-
-See the file `config.sub' for the possible values of each field.  If
-`config.sub' isn't included in this package, then this package doesn't
-need to know the host type.
-
-   If you are building compiler tools for cross-compiling, you can also
-use the `--target=TYPE' option to select the type of system they will
-produce code for and the `--build=TYPE' option to select the type of
-system on which you are compiling the package.
-
-Sharing Defaults
-================
-
-   If you want to set default values for `configure' scripts to share,
-you can create a site shell script called `config.site' that gives
-default values for variables like `CC', `cache_file', and `prefix'.
-`configure' looks for `PREFIX/share/config.site' if it exists, then
-`PREFIX/etc/config.site' if it exists.  Or, you can set the
-`CONFIG_SITE' environment variable to the location of the site script.
-A warning: not all `configure' scripts look for a site script.
-
-Operation Controls
-==================
-
-   `configure' recognizes the following options to control how it
-operates.
-
-`--cache-file=FILE'
-     Use and save the results of the tests in FILE instead of
-     `./config.cache'.  Set FILE to `/dev/null' to disable caching, for
-     debugging `configure'.
-
-`--help'
-     Print a summary of the options to `configure', and exit.
-
-`--quiet'
-`--silent'
-`-q'
-     Do not print messages saying which checks are being made.  To
-     suppress all normal output, redirect it to `/dev/null' (any error
-     messages will still be shown).
-
-`--srcdir=DIR'
-     Look for the package's source code in directory DIR.  Usually
-     `configure' can determine that directory automatically.
-
-`--version'
-     Print the version of Autoconf used to generate the `configure'
-     script, and exit.
-
-`configure' also accepts some other, not widely useful, options.
diff --git a/Source/LibMNG/README.config b/Source/LibMNG/README.config
deleted file mode 100644
index 97fcb31..0000000
--- a/Source/LibMNG/README.config
+++ /dev/null
@@ -1,104 +0,0 @@
-Configuration options in libmng
-===============================
-
-The library is fairly configurable through the use of a number of defines.
-Please note however that certain defines are for internal use only.
-The following list gives a summary of options that can be used externally to
-define the functionality of the library:
-
-========================================
-
-#define MNG_BUILD_DLL
-
-This is used to indicate that a "standard" DLL should result from compiling
-the library. Please note the remarks in README.dll if you intend to work
-with the library as a DLL. The purpose of this option is to ensure that
-DLL builds have the same set of functions.
-
-#define MNG_BUILD_SO
-
-This is used to indicate that a "standard" shared library (SO) should result
-from a compilation. The purpose of this option is to ensure that all
-shared libraries generated this way will have the same set of functions.
-
-#define MNG_USE_DLL / #define MNG_USE_SO
-
-These should be used when including the library header in the compilation
-of an application to indicate that the compiler/linker must take the
-necessary steps to make the binary executable to use the standard DLL
-or shared library (SO).
-
-#define MNG_SKIP_ZLIB / #define MNG_SKIP_LCMS / #define MNG_SKIP_IJG6B
-
-Use these in conjunction with MNG_USE_DLL / MNG_USE_SO. This is useful if
-you only need the external definitions of the MNG library and not the others,
-which will speed up the compilation process.
-
-#define MNG_SUPPORT_FULL / #define MNG_SUPPORT_LC / #define MNG_SUPPORT_VLC
-
-These can be used to indicate the level of MNG spec compliance required.
-Currently only full MNG compliance is supported.
-
-#define MNG_SUPPORT_IJG6B
-
-This can be used to indicate if JNG support is required. This option will
-include the IJG JPEG-library. Note that MNG_SUPPORT_FULL will automatically
-set this option. Use this only if you need JNG support with MNG-(V)LC.
-
-#define MNG_FULL_CMS / #define MNG_GAMMA_ONLY / #define MNG_NO_CMS /
-#define MNG_APP_CMS
-
-These indicate the color-correction support level of the library.
-If you are on a platform that supports lcms (Little CMS by Marti Maria Saguar)
-then it is highly recommended to define MNG_FULL_CMS.
-If your platform has it's own CMS then select MNG_APP_CMS and be sure to
-include the appropriate callbacks in your app.
-In all other cases it is recommended to define MNG_GAMMA_ONLY.
-
-#define MNG_SUPPORT_READ / #define MNG_SUPPORT_WRITE /
-#define MNG_SUPPORT_DISPLAY
-
-These indicate the high-level support for reading, writing and/or
-displaying files. Note that in order to display a file, you'll need to read
-it first. (yes, really!)
-
-#define MNG_STORE_CHUNKS
-
-This indicates that the library should store chunk-information when reading
-a file. This information can then be processed through the
-MNG_ITERATE_CHUNKS() function. Note that you must specify this option if
-you want to create and write a new file.
-
-#define MNG_ACCESS_CHUNKS
-
-This is used to indicate that the app may need access to internally stored
-chunk information. MNG_STORE_CHUNKS must be defined as well for this option
-to function properly.
-
-#define MNG_INTERNAL_MEMMNGMT
-
-You can use this to have the library handle it's own memory allocation and
-deallocation through the "standard" memory functions. This option is turned
-off by default, which means your app must define the memory callbacks.
-
-#define MNG_ERROR_TELLTALE
-
-Set this on to allow human-readable error-messages to be included in the
-library and the error function and callback.
-
-#define MNG_BIGENDIAN_SUPPORTED
-
-This option should be used to indicate the hardware is based on big endian
-integers.
-
-#define MNG_SUPPORT_TRACE / #define MNG_TRACE_TELLTALE
-
-These two can be used when debugging an app. You'll need to have the trace
-callback setup also. This allows for a rather thorough investigation of the
-libraries function paths.
-
-========================================
-
-Any other optional defines you may encounter are for internal use only.
-please do not specify them externally. In case of doubt, consult the
-support email lists. More info can be found on http://www.libmng.com
diff --git a/Source/LibMNG/README.contrib b/Source/LibMNG/README.contrib
deleted file mode 100644
index 2d51ac5..0000000
--- a/Source/LibMNG/README.contrib
+++ /dev/null
@@ -1,95 +0,0 @@
-The contrib directory contains contributions made by fellow
-enthousiasts. (Check respective web-sites for the latest version)
-
-----------------------------------------------------------------------
-
-mngplg - A Netscape plugin for MNG - by Jason Summers
-
-http://pobox.com/~jason1/imaging/mngplg/
-
-The very first contribution, and what a start!
-GIF look out, MNG is on the prowl and ready to swat you like a fly!
-
-----------------------------------------------------------------------
-
-mngplay - An SDL based MNG viewer - by Ralph Giles
-
-http://snow.ashlu.bc.ca/~giles/mng/
-
-Another nice contribution. View MNG files on practically any platform
-with this standalone viewer.
-Source-code only; Requires SDL library and libmng.so
-
-(Modified by Greg Roelofs)
-
-----------------------------------------------------------------------
-
-mngview - A BCB port of the Delphi sample - by Andy Protano
-
-I have added this nice little port to the BCB samples directory.
-It adds a nifty progressbar while reading a file. Excellent work!
-Requires libmng.dll
-(note: this is in the BCB samples directory)
-
-----------------------------------------------------------------------
-
-mngdump - A BCB GUI-based dump utility - by Andy Protano
-
-Andy has sent me this fully functional MNG dump utility, that gives
-detailed information of the contents of any MNG file.
-Requires libmng.dll
-
-----------------------------------------------------------------------
-
-mng-view - A GTK-based MNG viewer - by Vova Babin
-
-Vova has been hacking away with the libmng code and has come up with
-this nice little sample how to write a MNG viewer using GTK.
-Thanks mate!
-Source-code only
-Requires GTK+ (1.2 or higher) and libmng (0.9.2 or higher)
-
-(Modified by Greg Roelofs)
-
-----------------------------------------------------------------------
-
-mngview - Another MNG viewer; this one for MSVC - by Nicholaus Brennig
-
-A welcome contribution from Nicholaus. Author of SlowView. A very nice
-image-handling utility for Windows. A welcome contribution since there
-have been numerous questions about linking libmng with MSVC.
-Well, look no further. Here it is!
-
-----------------------------------------------------------------------
-
-MSVC libmng project - An MSVC project to build libmng.dll
-                    - by Chad Austin
-
-Chad has contributed some project-files that you could use to build
-libmng.dll with MSVC. Please be sure to read the README file included.
-
-----------------------------------------------------------------------
-
-fbmngplay - A simple fbcon based mng player - by Stefan Reinauer
-
-Stefan has contributed this little example, based on Ralph's
-SDL player. It uses the kernel framebuffer device to display mng
-animations through the libmng interface.
-(currently for 16-bit buffers only)
-
-----------------------------------------------------------------------
-
-xmngview - Lesstif/Motif standalone player for MNG files
-         - by Winfried Szukalski
-
-Winfried contributed this MNG player for X-based systems.
-(recently updated)
-
-----------------------------------------------------------------------
-
-makemng - A delta-MNG creation utility for MSVC - by Alex Volkov
-
-Alex sent me this nice utility that will allow you to create highly
-optmized MNGs using the delta-PNG capabilities of MNG.
-
-----------------------------------------------------------------------
diff --git a/Source/LibMNG/README.examples b/Source/LibMNG/README.examples
deleted file mode 100644
index 9f23b50..0000000
--- a/Source/LibMNG/README.examples
+++ /dev/null
@@ -1,48 +0,0 @@
-The samples are in platform-specific directories.
-
-!!! contributions are very welcome !!!
-
-
-bcb - Borland C++ Builder (3.0) (found under bcb/xxx)
------------------------------------------------------
-
-win32dll - sample project to create a Windows dll. Requires zlib1.2.1,
-           IJG jpgsrc6b and lcms1.0.14. The directories containing these
-           libraries must be at the same level as the libmng directory.
-           So if you're in the directory with this file and the libmng
-           sources, they should be in ..\zlib , ..\jpgsrc6b and ..\lcms
-           respectively.
-
-!!!        To run the other Win32 samples you need to copy the libmng.dll
-           file from here into the sample's directory !!!
-
-mngtree  - sample project to create a little command-line tool that dumps
-           the chunk-structure of a given file onto stdout.
-
-bogus    - a completely bogus example on how to create a perfectly valid
-           (though slightly biased) MNG.
-
-mngview  - port of the Delphi mngview sample. contributed by Andy Protano.
-           see also README.contrib
-
-mngrepair- an example on how to fix invalid MNG files
-           uses the new mng_copy_chunks() function and MNG_SOFTERRORS to
-           'ignore' certain input-errors. This conditional *MUST* only be used
-           for exactly this kind of software; eg. repair utilities.
-
-
-delphi - Borland Delphi (3.0+) (found under contrib/delphi/xxx)
----------------------------------------------------------------
-
-mngview  - sample project for a simple mng-viewer. The general unit in
-           the delphi directory was translated from libmng.h It can be
-           used in other projects to access libmng.dll created with the
-           win32dll example above.
-
-
-unix - Unix (found under contrib/gcc/xxx)
------------------------------------------
-
-mngtree  - basically a copy of the BCB sample. It includes a makefile for
-           Linux and it's been tested on RedHat6.2
-
diff --git a/Source/LibMNG/README.footprint b/Source/LibMNG/README.footprint
deleted file mode 100644
index ae47da2..0000000
--- a/Source/LibMNG/README.footprint
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
-   You can use one or more of the following defines to
-   reduce the size of the compiled library.  Define the
-   SKIPCANVAS macros for any canvas configurations that
-   your application doesn't use.  Define the SKIPCHUNK
-   macros for any chunks that your application doesn't
-   process.  Define MNG_OPTIMIZE_FOOTPRINT to choose
-   smaller code size over faster execution and less memory
-   usage.  These macros became available in version 1.0.6.
-*/
-
-/* eliminate unused features from libmng */
-#define MNG_OPTIMIZE_FOOTPRINT
-#define MNG_OPTIMIZE_OBJCLEANUP
-#define MNG_OPTIMIZE_CHUNKINITFREE
-#define MNG_OPTIMIZE_CHUNKASSIGN
-#define MNG_OPTIMIZE_CHUNKREADER
-
-#define MNG_SKIPCANVAS_ABGR8
-#define MNG_SKIPCANVAS_ARGB8
-#define MNG_SKIPCANVAS_BGR8
-#define MNG_SKIPCANVAS_BGRA8
-#define MNG_SKIPCANVAS_BGRA8_PM
-#define MNG_SKIPCANVAS_BGRX8
-#define MNG_SKIPCANVAS_RGBA8
-#define MNG_SKIPCANVAS_BGR565
-#define MNG_SKIPCANVAS_RGB565
-#define MNG_SKIPCANVAS_BGRA565
-#define MNG_SKIPCANVAS_RGBA565
-
-#define MNG_SKIPCHUNK_iCCP
-#define MNG_SKIPCHUNK_tEXt
-#define MNG_SKIPCHUNK_zTXt
-#define MNG_SKIPCHUNK_iTXt
-#define MNG_SKIPCHUNK_bKGD
-#define MNG_SKIPCHUNK_pHYs
-#define MNG_SKIPCHUNK_sBIT
-#define MNG_SKIPCHUNK_sPLT
-#define MNG_SKIPCHUNK_hIST
-#define MNG_SKIPCHUNK_tIME
-#define MNG_SKIPCHUNK_eXPI
-#define MNG_SKIPCHUNK_fPRI
-#define MNG_SKIPCHUNK_nEED
-#define MNG_SKIPCHUNK_pHYg
-
-
diff --git a/Source/LibMNG/README.packaging b/Source/LibMNG/README.packaging
deleted file mode 100644
index 32fb2da..0000000
--- a/Source/LibMNG/README.packaging
+++ /dev/null
@@ -1,24 +0,0 @@
-Packaging Libmng for distribution
----------------------------------
-
-These are some notes for those building binaries for distribution.
-
-We're interested to hear about anywhere libmng is helpful, so let us
-know if you're including it with your application or OS. Also, if your
-build is publicly accessible, we'd be happy to link to it from
-the libmng site.
-
-However, We respectfully request that you *not* distribute binaries as a
-shared library (DLL) with any of the major features disabled. While
-there is support for this in terms of #ifdef directives (in
-libmng_conf.h) and autoconf switches they are intended for embedded
-application and testing. The default compilation options support the
-full MNG specification, and we wish to avoid the confusion among
-general users that partial support would engender.
-
-
-Platform specific notes:
-
-We have a basic .spec file for generating rpms. Send us a note if you'd
-like to clean it up.
-
diff --git a/Source/LibMNG/_FI_3151_PluginMNG.cpp b/Source/LibMNG/_FI_3151_PluginMNG.cpp
deleted file mode 100644
index 775b126..0000000
--- a/Source/LibMNG/_FI_3151_PluginMNG.cpp
+++ /dev/null
@@ -1,312 +0,0 @@
-// ==========================================================
-// MNG Loader
-//
-// Design and implementation by
-// - Floris van den Berg (flvdberg at wxs.nl)
-//
-// This file is part of FreeImage 3
-//
-// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
-// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
-// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
-// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
-// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
-// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
-// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
-// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
-// THIS DISCLAIMER.
-//
-// Use at your own risk!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-
-#include "../LibMNG/libmng.h"
-//#include "../LibMNG/libmng_data.h"
-
-// ==========================================================
-// Plugin Interface
-// ==========================================================
-
-static int s_format_id;
-
-// ----------------------------------------------------------
-//   Constants + headers
-// ----------------------------------------------------------
-
-typedef struct {
-	FIBITMAP    *bitmap;    // pointer to the bitmap data
-	FreeImageIO *io;        // pointer to the io functions
-	fi_handle   file;	    // pointer to the file we're decoding
-} mngstuff;
-
-// ----------------------------------------------------------
-//   Callbacks for the mng decoder
-// ----------------------------------------------------------
-
-mng_ptr
-mymngalloc(mng_size_t size) {
-	return (mng_ptr)calloc(1, size);
-}
-
-void
-mymngfree(mng_ptr p, mng_size_t size) {
-	free(p);
-}
-
-mng_bool
-mymngopenstream(mng_handle mng) {
-	// since the user is responsible for opening and closing the file,
-	// we leave the default implementation open
-
-	return MNG_TRUE;
-}
-
-mng_bool
-mymngclosestream(mng_handle mng) {
-	// since the user is responsible for opening and closing the file,
-	// we leave the default implementation open
-
-	return MNG_TRUE;
-}
-
-mng_bool
-mymngreadstream(mng_handle mng, mng_ptr buffer, mng_uint32 size, mng_uint32 *bytesread) {
-	mngstuff *mymng = (mngstuff *)mng_get_userdata(mng);
-
-	*bytesread = mymng->io->read_proc(buffer, 1, size, mymng->file);
-
-	return MNG_TRUE;
-}
-
-mng_bool
-mymngprocessheader(mng_handle mng, mng_uint32 width, mng_uint32 height) {
-	mngstuff *client_data = (mngstuff *)mng_get_userdata(mng);
-	BYTE bHasAlpha = mng_get_alphadepth(mng);
-
-#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB
-	if(bHasAlpha) {
-		// allocate a bitmap with the given dimensions
-		FIBITMAP *bitmap = FreeImage_Allocate(width, height, 32, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
-		client_data->bitmap = bitmap;
-		// tell the mng decoder about our bit-depth choice
-		mng_set_canvasstyle(mng, MNG_CANVAS_RGBA8);
-	} else {
-		// allocate a bitmap with the given dimensions
-		FIBITMAP *bitmap = FreeImage_Allocate(width, height, 24, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
-		client_data->bitmap = bitmap;
-		// tell the mng decoder about our bit-depth choice
-		mng_set_canvasstyle(mng, MNG_CANVAS_RGB8);
-	}
-#else
-	if(bHasAlpha) {
-		// allocate a bitmap with the given dimensions
-		FIBITMAP *bitmap = FreeImage_Allocate(width, height, 32, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
-		client_data->bitmap = bitmap;
-		// tell the mng decoder about our bit-depth choice
-		mng_set_canvasstyle(mng, MNG_CANVAS_BGRA8);
-	} else {
-		// allocate a bitmap with the given dimensions
-		FIBITMAP *bitmap = FreeImage_Allocate(width, height, 24, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
-		client_data->bitmap = bitmap;
-		// tell the mng decoder about our bit-depth choice
-		mng_set_canvasstyle(mng, MNG_CANVAS_BGR8);
-	}
-#endif // FREEIMAGE_COLORORDER_RGB
-
-	return client_data->bitmap ? MNG_TRUE : MNG_FALSE;
-}
-
-mng_ptr
-mymnggetcanvasline(mng_handle mng, mng_uint32 line) {
-	FIBITMAP *bitmap = ((mngstuff *)mng_get_userdata(mng))->bitmap;
-
-	return FreeImage_GetScanLine(bitmap, FreeImage_GetHeight(bitmap) - line - 1);
-}
-
-mng_bool
-mymngrefresh(mng_handle mng, mng_uint32 x, mng_uint32 y, mng_uint32 w, mng_uint32 h) {
-	return MNG_TRUE;
-}
-
-mng_uint32
-mymnggetticks(mng_handle mng) {
-	return 0;
-}
-
-mng_bool
-mymngsettimer(mng_handle mng, mng_uint32 msecs) {
-	return MNG_TRUE;
-}
-
-mng_bool
-mymngerror(mng_handle mng, mng_int32 code, mng_int8 severity, mng_chunkid chunktype, mng_uint32 chunkseq, mng_int32 extra1, mng_int32 extra2, mng_pchar text) {
-	char msg[256];
-	if((code == MNG_SEQUENCEERROR) && (chunktype == MNG_UINT_TERM)) {
-		// ignore sequence error for TERM
-		return MNG_TRUE;
-	}
-	if(text) {
-		// text can be null depending on compiler options
-		sprintf(msg, "Error reported by libmng (%d)\r\n\r\n%s", code, text);
-	} else {
-		sprintf(msg, "Error %d reported by libmng", code);
-	}
-	FreeImage_OutputMessageProc(s_format_id, msg);
-	return MNG_FALSE;
-}
-
-// ==========================================================
-// Plugin Implementation
-// ==========================================================
-
-static const char * DLL_CALLCONV
-Format() {
-	return "MNG";
-}
-
-static const char * DLL_CALLCONV
-Description() {
-	return "Multiple Network Graphics";
-}
-
-static const char * DLL_CALLCONV
-Extension() {
-	return "mng";
-}
-
-static const char * DLL_CALLCONV
-RegExpr() {
-	return NULL;
-}
-
-static const char * DLL_CALLCONV
-MimeType() {
-	return "video/x-mng";
-}
-
-static BOOL DLL_CALLCONV
-SupportsExportDepth(int depth) {
-	return FALSE;
-}
-
-static BOOL DLL_CALLCONV 
-SupportsExportType(FREE_IMAGE_TYPE type) {
-	return FALSE;
-}
-
-// ----------------------------------------------------------
-
-static void * DLL_CALLCONV
-Open(FreeImageIO *io, fi_handle handle, BOOL read) {
-	mngstuff *mymng = (mngstuff *)calloc(1, sizeof(*mymng));
-	mymng->io = io;
-	mymng->file = handle;	
-
-	return mymng;
-}
-
-static void DLL_CALLCONV
-Close(FreeImageIO *io, fi_handle handle, void *data) {
-	free((mngstuff *)data);
-}
-
-// ----------------------------------------------------------
-
-static FIBITMAP * DLL_CALLCONV
-Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
-	mng_handle hmng = NULL;
-
-	if (handle != NULL) {
-		try {
-			// allocate our stream data structure
-			mngstuff *mymng = (mngstuff *)data;
-
-			// set up the mng decoder for our stream
-			hmng = mng_initialize(mymng, mymngalloc, mymngfree, MNG_NULL);
-
-			if (hmng == MNG_NULL) {
-				throw "could not initialize libmng";			
-			}
-			
-			// set the colorprofile, lcms uses this
-			mng_set_srgb(hmng, MNG_TRUE );
-			// set white as background color
-			WORD wRed, wGreen, wBlue;
-			wRed = wGreen = wBlue = (255 << 8) + 255;
-			mng_set_bgcolor(hmng, wRed, wGreen, wBlue);
-			// if PNG Background is available, use it
-			mng_set_usebkgd(hmng, MNG_TRUE );
-			// no need to store chunks
-			mng_set_storechunks(hmng, MNG_FALSE);
-			// no need to wait: straight reading
-			mng_set_suspensionmode(hmng, MNG_FALSE);
-
-			// set the callbacks
-			mng_setcb_errorproc(hmng, mymngerror);
-			mng_setcb_openstream(hmng, mymngopenstream);
-			mng_setcb_closestream(hmng, mymngclosestream);
-			mng_setcb_readdata(hmng, mymngreadstream);
-			mng_setcb_processheader(hmng, mymngprocessheader);
-			mng_setcb_getcanvasline(hmng, mymnggetcanvasline);
-			mng_setcb_refresh(hmng, mymngrefresh);
-			mng_setcb_gettickcount(hmng, mymnggetticks);
-			mng_setcb_settimer(hmng, mymngsettimer);
-	
-			// read in the bitmap
-			mng_readdisplay(hmng);
-
-			// read all bitmaps
-			int retval = MNG_NOERROR;
-			while(mng_status_reading(hmng)) {
-				retval = mng_display_resume(hmng);
-				if((mng_get_imagetype(hmng) != mng_it_jng) && (retval == MNG_NEEDTIMERWAIT) || (retval == MNG_FUNCTIONINVALID))
-					break;
-			}
-
-			// temp store the newly created bitmap
-			FIBITMAP *bitmap = mymng->bitmap;
-
-			// cleanup and return the temp stored bitmap
-			mng_cleanup(&hmng);
-
-			return bitmap;
-
-		} catch (const char *message) {
-			FIBITMAP *bitmap = ((mngstuff *)mng_get_userdata(hmng))->bitmap;
-			if(bitmap) {
-				FreeImage_Unload(bitmap);
-			}
-			mng_cleanup(&hmng);
-			FreeImage_OutputMessageProc(s_format_id, message);
-		}
-	}
-
-	return NULL;
-}	
-
-// ==========================================================
-//   Init
-// ==========================================================
-
-void DLL_CALLCONV
-InitMNG(Plugin *plugin, int format_id) {
-	s_format_id = format_id;
-
-	plugin->format_proc = Format;
-	plugin->description_proc = Description;
-	plugin->extension_proc = Extension;
-	plugin->regexpr_proc = RegExpr;
-	plugin->open_proc = Open;
-	plugin->close_proc = Close;
-	plugin->pagecount_proc = NULL;
-	plugin->pagecapability_proc = NULL;
-	plugin->load_proc = Load;
-	plugin->save_proc = NULL;
-	plugin->validate_proc = NULL;
-	plugin->mime_proc = MimeType;
-	plugin->supports_export_bpp_proc = SupportsExportDepth;
-	plugin->supports_export_type_proc = SupportsExportType;
-	plugin->supports_icc_profiles_proc = NULL;	// not implemented yet;
-}
diff --git a/Source/LibMNG/libmng.h b/Source/LibMNG/libmng.h
deleted file mode 100644
index b3b1ab1..0000000
--- a/Source/LibMNG/libmng.h
+++ /dev/null
@@ -1,2932 +0,0 @@
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * COPYRIGHT NOTICE:                                                      * */
-/* *                                                                        * */
-/* * Copyright (c) 2000-2007 Gerard Juyn                                    * */
-/* * [You may insert additional notices after this sentence if you modify   * */
-/* *  this source]                                                          * */
-/* *                                                                        * */
-/* * For the purposes of this copyright and license, "Contributing Authors" * */
-/* * is defined as the following set of individuals:                        * */
-/* *                                                                        * */
-/* *    Gerard Juyn                 - gjuyn :at: users.sourceforge.net      * */
-/* *    Glenn Randers-Pehrson       - glennrp :at: users.sourceforge.net    * */
-/* *    Raphael Assenat             - raph :at: raphnet.net                 * */
-/* *    John Stiles                 -                                       * */
-/* *                                                                        * */
-/* * The MNG Library is supplied "AS IS".  The Contributing Authors         * */
-/* * disclaim all warranties, expressed or implied, including, without      * */
-/* * limitation, the warranties of merchantability and of fitness for any   * */
-/* * purpose.  The Contributing Authors assume no liability for direct,     * */
-/* * indirect, incidental, special, exemplary, or consequential damages,    * */
-/* * which may result from the use of the MNG Library, even if advised of   * */
-/* * the possibility of such damage.                                        * */
-/* *                                                                        * */
-/* * Permission is hereby granted to use, copy, modify, and distribute this * */
-/* * source code, or portions hereof, for any purpose, without fee, subject * */
-/* * to the following restrictions:                                         * */
-/* *                                                                        * */
-/* * 1. The origin of this source code must not be misrepresented;          * */
-/* *    you must not claim that you wrote the original software.            * */
-/* *                                                                        * */
-/* * 2. Altered versions must be plainly marked as such and must not be     * */
-/* *    misrepresented as being the original source.                        * */
-/* *                                                                        * */
-/* * 3. This Copyright notice may not be removed or altered from any source * */
-/* *    or altered source distribution.                                     * */
-/* *                                                                        * */
-/* * The Contributing Authors specifically permit, without fee, and         * */
-/* * encourage the use of this source code as a component to supporting     * */
-/* * the MNG and JNG file format in commercial products.  If you use this   * */
-/* * source code in a product, acknowledgment would be highly appreciated.  * */
-/* *                                                                        * */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Parts of this software have been adapted from the libpng package.      * */
-/* * Although this library supports all features from the PNG specification * */
-/* * (as MNG descends from it) it does not require the libpng package.      * */
-/* * It does require the zlib library and optionally the IJG jpeg library,  * */
-/* * and/or the "little-cms" library by Marti Maria (depending on the       * */
-/* * inclusion of support for JNG and Full-Color-Management respectively.   * */
-/* *                                                                        * */
-/* * This library's function is primarily to read and display MNG           * */
-/* * animations. It is not meant as a full-featured image-editing           * */
-/* * component! It does however offer creation and editing functionality    * */
-/* * at the chunk level.                                                    * */
-/* * (future modifications may include some more support for creation       * */
-/* *  and or editing)                                                       * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Version numbering                                                      * */
-/* *                                                                        * */
-/* * X.Y.Z : X = release (0 = initial build)                                * */
-/* *         Y = major version (uneven = test; even = production)           * */
-/* *         Z = minor version (bugfixes; 2 is older than 10)               * */
-/* *                                                                        * */
-/* * production versions only appear when a test-version is extensively     * */
-/* * tested and found stable or for intermediate bug-fixes (recognized by   * */
-/* * a change in the Z number)                                              * */
-/* *                                                                        * */
-/* * x.1.x      = test version                                              * */
-/* * x.2.x      = production version                                        * */
-/* * x.3.x      = test version                                              * */
-/* * x.4.x      = production version                                        * */
-/* *  etc.                                                                  * */
-/* *                                                                        * */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Identifier naming conventions throughout this library                  * */
-/* *                                                                        * */
-/* * iXxxx      = an integer                                                * */
-/* * dXxxx      = a float                                                   * */
-/* * pXxxx      = a pointer                                                 * */
-/* * bXxxx      = a boolean                                                 * */
-/* * eXxxx      = an enumeration                                            * */
-/* * hXxxx      = a handle                                                  * */
-/* * zXxxx      = a zero-terminated string (pchar)                          * */
-/* * fXxxx      = a pointer to a function (callback)                        * */
-/* * aXxxx      = an array                                                  * */
-/* * sXxxx      = a structure                                               * */
-/* *                                                                        * */
-/* * Macros & defines are in all uppercase.                                 * */
-/* * Functions & typedefs in all lowercase.                                 * */
-/* * Exported stuff is prefixed with MNG_ or mng_ respectively.             * */
-/* *                                                                        * */
-/* * (I may have missed a couple; don't hesitate to let me know!)           * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * project   : libmng                                                     * */
-/* * file      : libmng.h                  copyright (c) 2000-2007 G.Juyn   * */
-/* * version   : 1.0.10                                                     * */
-/* *                                                                        * */
-/* * purpose   : main application interface                                 * */
-/* *                                                                        * */
-/* * author    : G.Juyn                                                     * */
-/* *                                                                        * */
-/* * comment   : The main application interface. An application should not  * */
-/* *             need access to any of the other modules!                   * */
-/* *                                                                        * */
-/* * changes   : 0.5.1 - 05/06/2000 - G.Juyn                                * */
-/* *             - changed chunk iteration function                         * */
-/* *             0.5.1 - 05/08/2000 - G.Juyn                                * */
-/* *             - added chunk access functions                             * */
-/* *             - added version control constants & functions              * */
-/* *             - changed strict-ANSI stuff                                * */
-/* *             0.5.1 - 05/11/2000 - G.Juyn                                * */
-/* *             - added set_outputprofile2 & set_srgbprofile2              * */
-/* *             - added empty-chunk put-routines                           * */
-/* *             0.5.1 - 05/12/2000 - G.Juyn                                * */
-/* *             - added version_dll & VERSION_DLL (for consistency)        * */
-/* *             - added version control explanatory text & samples         * */
-/* *             0.5.1 - 05/15/2000 - G.Juyn                                * */
-/* *             - added getimgdata & putimgdata functions                  * */
-/* *                                                                        * */
-/* *             0.5.2 - 05/16/2000 - G.Juyn                                * */
-/* *             - changed the version parameters (obviously)               * */
-/* *             0.5.2 - 05/18/2000 - G.Juyn                                * */
-/* *             - complimented constants for chunk-property values         * */
-/* *             0.5.2 - 05/23/2000 - G.Juyn                                * */
-/* *             - fixed MNG_UINT_pHYg value                                * */
-/* *             0.5.2 - 05/24/2000 - G.Juyn                                * */
-/* *             - added support for get/set default zlib/IJG parms         * */
-/* *             0.5.2 - 06/02/2000 - G.Juyn                                * */
-/* *             - added MNG_BIGENDIAN_SUPPORT (contributed by Tim Rowley)  * */
-/* *             - separated configuration-options into "mng_conf.h"        * */
-/* *             - added RGB8_A8 canvasstyle                                * */
-/* *             - added getalphaline callback for RGB8_A8 canvasstyle      * */
-/* *             0.5.2 - 06/06/2000 - G.Juyn                                * */
-/* *             - moved errorcodes from "mng_error.h"                      * */
-/* *             - added mng_read_resume function to support                * */
-/* *               read-suspension                                          * */
-/* *                                                                        * */
-/* *             0.5.3 - 06/16/2000 - G.Juyn                                * */
-/* *             - changed the version parameters (obviously)               * */
-/* *             0.5.3 - 06/21/2000 - G.Juyn                                * */
-/* *             - added get/set for speedtype to facilitate testing        * */
-/* *             - added get for imagelevel during processtext callback     * */
-/* *             0.5.3 - 06/24/2000 - G.Juyn                                * */
-/* *             - fixed inclusion of IJG read/write code                   * */
-/* *             0.5.3 - 06/26/2000 - G.Juyn                                * */
-/* *             - changed userdata variable to mng_ptr                     * */
-/* *                                                                        * */
-/* *             0.9.0 - 06/30/2000 - G.Juyn                                * */
-/* *             - changed refresh parameters to 'x,y,width,height'         * */
-/* *                                                                        * */
-/* *             0.9.1 - 07/06/2000 - G.Juyn                                * */
-/* *             - added MNG_NEEDTIMERWAIT errorcode                        * */
-/* *             - changed comments to indicate modified behavior for       * */
-/* *               timer & suspension breaks                                * */
-/* *             0.9.1 - 07/08/2000 - G.Juyn                                * */
-/* *             - added get routines for internal display variables        * */
-/* *             - added get/set routines for suspensionmode variable       * */
-/* *             0.9.1 - 07/15/2000 - G.Juyn                                * */
-/* *             - added callbacks for SAVE/SEEK processing                 * */
-/* *             - added get/set routines for sectionbreak variable         * */
-/* *             - added NEEDSECTIONWAIT errorcode                          * */
-/* *             0.9.1 - 07/19/2000 - G.Juyn                                * */
-/* *             - added function to set frame-/layer-count & playtime      * */
-/* *             - added errorcode for updatemngheader if not a MNG         * */
-/* *                                                                        * */
-/* *             0.9.2 - 07/31/2000 - G.Juyn                                * */
-/* *             - fixed problem with trace-functions improperly wrapped    * */
-/* *             - added status_xxxx functions                              * */
-/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
-/* *             - changed file-prefixes                                    * */
-/* *             - added function to set simplicity field                   * */
-/* *                                                                        * */
-/* *             0.9.3 - 08/09/2000 - G.Juyn                                * */
-/* *             - added check for simplicity-bits in MHDR                  * */
-/* *             0.9.3 - 08/12/2000 - G.Juyn                                * */
-/* *             - added workaround for faulty PhotoShop iCCP chunk         * */
-/* *             0.9.3 - 08/26/2000 - G.Juyn                                * */
-/* *             - added MAGN chunk                                         * */
-/* *             0.9.3 - 09/07/2000 - G.Juyn                                * */
-/* *             - added support for new filter_types                       * */
-/* *             0.9.3 - 10/10/2000 - G.Juyn                                * */
-/* *             - added support for alpha-depth prediction                 * */
-/* *             0.9.3 - 10/11/2000 - G.Juyn                                * */
-/* *             - fixed processing of unknown critical chunks              * */
-/* *             - removed test-MaGN                                        * */
-/* *             - added PNG/MNG spec version indicators                    * */
-/* *             - added support for nEED                                   * */
-/* *             0.9.3 - 10/16/2000 - G.Juyn                                * */
-/* *             - added functions to retrieve PNG/JNG specific header-info * */
-/* *             - added JDAA chunk                                         * */
-/* *             0.9.3 - 10/17/2000 - G.Juyn                                * */
-/* *             - added callback to process non-critical unknown chunks    * */
-/* *             0.9.3 - 10/20/2000 - G.Juyn                                * */
-/* *             - added errocode for delayed delta-processing              * */
-/* *             - added get/set for bKGD preference setting                * */
-/* *             0.9.3 - 10/21/2000 - G.Juyn                                * */
-/* *             - added get function for interlace/progressive display     * */
-/* *                                                                        * */
-/* *             0.9.4 - 01/18/2001 - G.Juyn                                * */
-/* *             - added errorcode for MAGN methods                         * */
-/* *             - removed test filter-methods 1 & 65                       * */
-/* *                                                                        * */
-/* *             1.0.0 - 02/05/2001 - G.Juyn                                * */
-/* *             - version numbers (obviously)                              * */
-/* *                                                                        * */
-/* *             1.0.1 - 02/08/2001 - G.Juyn                                * */
-/* *             - added MEND processing callback                           * */
-/* *             1.0.1 - 04/21/2001 - G.Juyn (code by G.Kelly)              * */
-/* *             - added BGRA8 canvas with premultiplied alpha              * */
-/* *             1.0.1 - 05/02/2001 - G.Juyn                                * */
-/* *             - added "default" sRGB generation (Thanks Marti!)          * */
-/* *                                                                        * */
-/* *             1.0.2 - 06/23/2001 - G.Juyn                                * */
-/* *             - added optimization option for MNG-video playback         * */
-/* *             - added processterm callback                               * */
-/* *             1.0.2 - 06/25/2001 - G.Juyn                                * */
-/* *             - added late binding errorcode (not used internally)       * */
-/* *             - added option to turn off progressive refresh             * */
-/* *                                                                        * */
-/* *             1.0.3 - 08/06/2001 - G.Juyn                                * */
-/* *             - added get function for last processed BACK chunk         * */
-/* *                                                                        * */
-/* *             1.0.5 - 07/04/2002 - G.Juyn                                * */
-/* *             - added errorcode for extreme chunk-sizes                  * */
-/* *             1.0.5 - 08/07/2002 - G.Juyn                                * */
-/* *             - added test-option for PNG filter method 193 (=no filter) * */
-/* *             1.0.5 - 08/15/2002 - G.Juyn                                * */
-/* *             - completed PROM support                                   * */
-/* *             - completed delta-image support                            * */
-/* *             1.0.5 - 08/19/2002 - G.Juyn                                * */
-/* *             - added HLAPI function to copy chunks                      * */
-/* *             1.0.5 - 09/14/2002 - G.Juyn                                * */
-/* *             - added event handling for dynamic MNG                     * */
-/* *             - added 'supports' call to check function availability     * */
-/* *             1.0.5 - 09/15/2002 - G.Juyn                                * */
-/* *             - fixed LOOP iteration=0 special case                      * */
-/* *             1.0.5 - 09/20/2002 - G.Juyn                                * */
-/* *             - added support for PAST                                   * */
-/* *             1.0.5 - 09/22/2002 - G.Juyn                                * */
-/* *             - added bgrx8 canvas (filler byte)                         * */
-/* *             1.0.5 - 10/07/2002 - G.Juyn                                * */
-/* *             - added check for TERM placement during create/write       * */
-/* *             - added beta version function & constant                   * */
-/* *             1.0.5 - 11/07/2002 - G.Juyn                                * */
-/* *             - added support to get totals after mng_read()             * */
-/* *                                                                        * */
-/* *             1.0.6 - 07/07/2003 - G. Randers-Pehrson                    * */
-/* *             - added support for reducing the footprint of libmng       * */
-/* *               by macros that optionally skip unused chunks, remove     * */
-/* *               16-bit sample support, remove Delta support, and         * */
-/* *               remove JNG support, to accomodate Mozilla/Firebird.      * */
-/* *             1.0.6 - 07/14/2003 - G. Randers-Pehrson                    * */
-/* *             - further optional removal of unused functions             * */
-/* *                                                                        * */
-/* *             1.0.7 - 11/27/2003 - R.A                                   * */
-/* *             - added CANVAS_RGB565 and CANVAS_BGR565                    * */
-/* *             1.0.7 - 12/06/2003 - R.A                                   * */
-/* *             - added CANVAS_RGBA565 and CANVAS_BGRA565                  * */
-/* *             1.0.7 - 01/25/2004 - J.S                                   * */
-/* *             - added premultiplied alpha canvas' for RGBA, ARGB, ABGR   * */
-/* *             1.0.7 - 03/07/2004 - G. Randers-Pehrson                    * */
-/* *             - put gamma, cms-related declarations inside #ifdef        * */
-/* *             1.0.7 - 03/10/2004 - G.R-P                                 * */
-/* *             - added conditionals around openstream/closestream         * */
-/* *                                                                        * */
-/* *             1.0.8 - 04/02/2004 - G.Juyn                                * */
-/* *             - added CRC existence & checking flags                     * */
-/* *             1.0.8 - 04/12/2004 - G.Juyn                                * */
-/* *             - added data-push mechanisms for specialized decoders      * */
-/* *             1.0.8 - 06/05/2004 - G.R-P                                 * */
-/* *             - define MNG_INCLUDE_ZLIB when MNG_USE_ZLIB_CRC is defined * */
-/* *                                                                        * */
-/* *             1.0.9 - 10/03/2004 - G.Juyn                                * */
-/* *             - added function to retrieve current FRAM delay            * */
-/* *             1.0.9 - 10/14/2004 - G.Juyn                                * */
-/* *             - added bgr565_a8 canvas-style (thanks to J. Elvander)     * */
-/* *             1.0.9 - 10/17/2004 - G.Juyn                                * */
-/* *             - fixed PPLT getchunk/putchunk routines                    * */
-/* *                                                                        * */
-/* *             1.0.10 - 03/07/2006 - (thanks to W. Manthey)               * */
-/* *             - added CANVAS_RGB555 and CANVAS_BGR555                    * */
-/* *             1.0.10 - 04/08/2007 - G.Juyn                               * */
-/* *             - added support for mPNG proposal                          * */
-/* *             1.0.10 - 04/12/2007 - G.Juyn                               * */
-/* *             - added support for ANG proposal                           * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
-#pragma option -A                      /* force ANSI-C */
-#endif
-
-#ifndef _libmng_h_
-#define _libmng_h_
-
-/* ************************************************************************** */
-
-#include "libmng_conf.h"               /* user-specific configuration options */
-
-/* ************************************************************************** */
-
-#define MNG_CHECK_BAD_ICCP             /* let's catch that sucker !!! */
-
-#ifdef MNG_SUPPORT_READ                /* dependencies based on user-configuration */
-#define MNG_INCLUDE_READ_PROCS
-#endif
-
-#ifdef MNG_SUPPORT_WRITE
-#define MNG_INCLUDE_WRITE_PROCS
-#endif
-
-#ifdef MNG_USE_ZLIB_CRC
-#define MNG_INCLUDE_ZLIB
-#endif
-
-#ifdef MNG_SUPPORT_DISPLAY
-#define MNG_INCLUDE_FILTERS
-#define MNG_INCLUDE_INTERLACE
-#define MNG_INCLUDE_OBJECTS
-#define MNG_INCLUDE_DISPLAY_PROCS
-#define MNG_INCLUDE_TIMING_PROCS
-#define MNG_INCLUDE_ZLIB
-#endif
-
-#ifdef MNG_STORE_CHUNKS
-#define MNG_INCLUDE_ZLIB
-#endif
-
-#ifdef MNG_SUPPORT_IJG6B
-#define MNG_INCLUDE_JNG
-#define MNG_INCLUDE_IJG6B
-#define MNG_USE_SETJMP
-#endif
-
-#ifdef MNG_INCLUDE_JNG
-#if defined(MNG_SUPPORT_DISPLAY) || defined(MNG_ACCESS_CHUNKS)
-#define MNG_INCLUDE_JNG_READ
-#endif
-#if defined(MNG_SUPPORT_WRITE) || defined(MNG_ACCESS_CHUNKS)
-#define MNG_INCLUDE_JNG_WRITE
-#endif
-#endif
-
-#ifdef MNG_FULL_CMS
-#define MNG_INCLUDE_LCMS
-#endif
-
-#ifdef MNG_AUTO_DITHER
-#define MNG_INCLUDE_DITHERING
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-#define MNG_INCLUDE_TRACE_PROCS
-#ifdef MNG_TRACE_TELLTALE
-#define MNG_INCLUDE_TRACE_STRINGS
-#endif
-#endif
-
-#ifdef MNG_ERROR_TELLTALE
-#define MNG_INCLUDE_ERROR_STRINGS
-#endif
-
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-#ifndef MNG_OPTIMIZE_CHUNKACCESS
-#define MNG_OPTIMIZE_CHUNKACCESS
-#endif
-#else
-#ifdef MNG_OPTIMIZE_CHUNKACCESS
-#undef MNG_OPTIMIZE_CHUNKACCESS
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#include "libmng_types.h"              /* platform-specific definitions
-                                          and other assorted stuff */
-
-/* ************************************************************************** */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* *  Versioning control                                                    * */
-/* *                                                                        * */
-/* *  version_so and version_dll will NOT reflect version_major;            * */
-/* *  these will only change for binary incompatible changes (which will    * */
-/* *  hopefully never occur)                                                * */
-/* *  note: they will be set to 1 on the first public release !!!           * */
-/* *                                                                        * */
-/* *  first public release:                                                 * */
-/* *  #define MNG_VERSION_TEXT    "1.0.0"                                   * */
-/* *  #define MNG_VERSION_SO      1       eg. libmng.so.1                   * */
-/* *  #define MNG_VERSION_DLL     1       eg. libmng.dll                    * */
-/* *  #define MNG_VERSION_MAJOR   1                                         * */
-/* *  #define MNG_VERSION_MINOR   0                                         * */
-/* *  #define MNG_VERSION_RELEASE 0                                         * */
-/* *                                                                        * */
-/* *  bug fix & cosmetics :                                                 * */
-/* *  #define MNG_VERSION_TEXT    "1.0.1"                                   * */
-/* *  #define MNG_VERSION_SO      1       eg. libmng.so.1                   * */
-/* *  #define MNG_VERSION_DLL     1       eg. libmng.dll                    * */
-/* *  #define MNG_VERSION_MAJOR   1                                         * */
-/* *  #define MNG_VERSION_MINOR   0                                         * */
-/* *  #define MNG_VERSION_RELEASE 1                                         * */
-/* *                                                                        * */
-/* *  feature change :                                                      * */
-/* *  #define MNG_VERSION_TEXT    "1.2.0"                                   * */
-/* *  #define MNG_VERSION_SO      1       eg. libmng.so.1                   * */
-/* *  #define MNG_VERSION_DLL     1       eg. libmng.dll                    * */
-/* *  #define MNG_VERSION_MAJOR   1                                         * */
-/* *  #define MNG_VERSION_MINOR   2                                         * */
-/* *  #define MNG_VERSION_RELEASE 0                                         * */
-/* *                                                                        * */
-/* *  major rewrite (still binary compatible) :                             * */
-/* *  #define MNG_VERSION_TEXT    "2.0.0"                                   * */
-/* *  #define MNG_VERSION_SO      1       eg. libmng.so.1                   * */
-/* *  #define MNG_VERSION_DLL     1       eg. libmng.dll                    * */
-/* *  #define MNG_VERSION_MAJOR   2                                         * */
-/* *  #define MNG_VERSION_MINOR   0                                         * */
-/* *  #define MNG_VERSION_RELEASE 0                                         * */
-/* *                                                                        * */
-/* *  binary incompatible change:                                           * */
-/* *  #define MNG_VERSION_TEXT    "13.0.0"                                  * */
-/* *  #define MNG_VERSION_SO      2       eg. libmng.so.2                   * */
-/* *  #define MNG_VERSION_DLL     2       eg. libmng2.dll                   * */
-/* *  #define MNG_VERSION_MAJOR   13                                        * */
-/* *  #define MNG_VERSION_MINOR   0                                         * */
-/* *  #define MNG_VERSION_RELEASE 0                                         * */
-/* *                                                                        * */
-/* *  note that version_so & version_dll will always remain equal so it     * */
-/* *  doesn't matter which one is called to do version-checking; they are   * */
-/* *  just provided for their target platform                               * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#define MNG_VERSION_TEXT    "1.0.10"
-#define MNG_VERSION_SO      1          /* eg. libmng.so.1  */
-#define MNG_VERSION_DLL     1          /* but: libmng.dll (!) */
-#define MNG_VERSION_MAJOR   1
-#define MNG_VERSION_MINOR   0
-#define MNG_VERSION_RELEASE 10
-#define MNG_VERSION_BETA    MNG_FALSE
-
-MNG_EXT mng_pchar MNG_DECL mng_version_text      (void);
-MNG_EXT mng_uint8 MNG_DECL mng_version_so        (void);
-MNG_EXT mng_uint8 MNG_DECL mng_version_dll       (void);
-MNG_EXT mng_uint8 MNG_DECL mng_version_major     (void);
-MNG_EXT mng_uint8 MNG_DECL mng_version_minor     (void);
-MNG_EXT mng_uint8 MNG_DECL mng_version_release   (void);
-MNG_EXT mng_bool  MNG_DECL mng_version_beta      (void);
-
-/* use the following call to check wether the version of libmng your app
-   is using supports the given function; this is useful in apps that dynamically
-   load the library to make sure a certain function will work; the result will
-   be MNG_TRUE if the given function is implemented in this version of the library;
-   Major/Minor/Version indicate the version the function became available;
-   (if these fields are zero the function is not yet implemented!) */
-#ifdef MNG_SUPPORT_FUNCQUERY
-MNG_EXT mng_bool  MNG_DECL mng_supports_func     (mng_pchar  zFunction,
-                                                  mng_uint8* iMajor,
-                                                  mng_uint8* iMinor,
-                                                  mng_uint8* iRelease);
-#endif
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* *  MNG/PNG specification level conformance                               * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#define MNG_PNG_VERSION     "1.2"
-#define MNG_PNG_VERSION_MAJ 1
-#define MNG_PNG_VERSION_MIN 2
-
-#define MNG_MNG_VERSION     "1.1"
-#define MNG_MNG_VERSION_MAJ 1
-#define MNG_MNG_VERSION_MIN 1
-#define MNG_MNG_DRAFT       99         /* deprecated;
-                                          only used for nEED "MNG DRAFT nn" */
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* *  High-level application functions                                      * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-/* library initialization function */
-/* must be the first called before anything can be done at all */
-/* initializes internal datastructure(s) */
-MNG_EXT mng_handle  MNG_DECL mng_initialize      (mng_ptr       pUserdata,
-                                                  mng_memalloc  fMemalloc,
-                                                  mng_memfree   fMemfree,
-                                                  mng_traceproc fTraceproc);
-
-/* library reset function */
-/* can be used to re-initialize the library, so another image can be
-   processed. there's absolutely no harm in calling it, even when it's not
-   really necessary */
-MNG_EXT mng_retcode MNG_DECL mng_reset           (mng_handle    hHandle);
-
-/* library cleanup function */
-/* must be the last called to clean up internal datastructure(s) */
-MNG_EXT mng_retcode MNG_DECL mng_cleanup         (mng_handle*   hHandle);
-
-/* high-level read functions */
-/* use mng_read if you simply want to read a Network Graphic */
-/* mng_read_resume is used in I/O-read-suspension scenarios, where the
-   "readdata" callback may return FALSE & length=0 indicating its buffer is
-   depleted or too short to supply the required bytes, and the buffer needs
-   to be refilled; libmng will return the errorcode MNG_NEEDMOREDATA telling
-   the app to refill its read-buffer after which it must call mng_read_resume
-   (or mng_display_resume if it also displaying the image simultaneously) */
-#ifdef MNG_SUPPORT_READ
-MNG_EXT mng_retcode MNG_DECL mng_read            (mng_handle    hHandle);
-MNG_EXT mng_retcode MNG_DECL mng_read_resume     (mng_handle    hHandle);
-#endif
-
-/* high-level "data push" functions */
-/* these functions can be used in situations where data is streaming into the
-   application and needs to be buffered by libmng before it is actually
-   requested by libmng itself. the pushing complements the normal reading
-   mechanism, but applications can decide to always return "0 bytes read" to
-   make libmng go into suspension mode with the returncode MNG_NEEDMOREDATA */
-/* mng_read_pushdata can be used to push blobs of data of arbitrary size;
-   mng_read_pushsig and mng_read_pushchunk can be used if the application
-   has already done some low-level decoding (eg. at the chunk level) */
-/* the data being pushed into libmng with mng_read_pushdata *must* contain
-   the regular 4-byte chunklength, but *must not* contain it with
-   mng_read_pushchunk!!! */
-/* mng_read_pushsig is used to prevent libmng from trying to parse the regular
-   PNG/JNG/MNG signature bytes; the application must have done this itself
-   and *must* indicate the proper type in the function call or things will
-   go amiss!!
-   also you *must* call this first, so pretty much right after mng_initialize
-   and certainly before any call to mng_read or mng_readdisplay !!!! */
-/* IMPORTANT!!! data can only be safely pushed when libmng is in a
-   "wait" state; eg. during MNG_NEEDTIMERWAIT, MNG_NEEDSECTIONWAIT or
-   MNG_NEEDMOREDATA !!! this just means you can't have one thread displaying
-   and another thread pushing data !!! */
-/* if bOwnership = MNG_TRUE, libmng will retain the supplied pointer and
-   *will* expect the buffer to remain available until libmng is finished
-   with it; what happens then depends on whether or not you have set the
-   releasedata() callback; if this is set than the supplied buffer will
-   be returned through this callback and your application can take care of
-   cleaning it up, otherwise libmng will use its internal freeing mechanism
-   (which, depending on compile-options, will be the standard C free() call,
-   or the memfree() callback */
-/* if bOwnership = MNG_FALSE, libmng will just copy the data into its own
-   buffers and dispose of it in the normal way */
-#ifdef MNG_SUPPORT_READ
-MNG_EXT mng_retcode MNG_DECL mng_read_pushdata   (mng_handle    hHandle,
-                                                  mng_ptr       pData,
-                                                  mng_size_t    iLength,
-                                                  mng_bool      bTakeownership);
-MNG_EXT mng_retcode MNG_DECL mng_read_pushsig    (mng_handle    hHandle,
-                                                  mng_imgtype   eSigtype);
-MNG_EXT mng_retcode MNG_DECL mng_read_pushchunk  (mng_handle    hHandle,
-                                                  mng_ptr       pChunk,
-                                                  mng_size_t    iLength,
-                                                  mng_bool      bTakeownership);
-#endif
-
-/* high-level write & create functions */
-/* use this if you want to write a previously read Network Graphic or
-   if you want to create a new graphic and write it */
-/* to write a previously read graphic you must have defined MNG_STORE_CHUNKS */
-/* to create a new graphic you'll also need access to the chunks
-   (eg. #define MNG_ACCESS_CHUNKS !) */
-#ifdef MNG_SUPPORT_WRITE
-MNG_EXT mng_retcode MNG_DECL mng_write           (mng_handle    hHandle);
-MNG_EXT mng_retcode MNG_DECL mng_create          (mng_handle    hHandle);
-#endif
-
-/* high-level display functions */
-/* use these to display a previously read or created graphic or
-   to read & display a graphic simultaneously */
-/* mng_display_resume should be called after a timer-interval
-   expires that was set through the settimer-callback, after a
-   read suspension-break, or, to resume an animation after a call
-   to mng_display_freeze/mng_display_reset */
-/* mng_display_freeze thru mng_display_gotime can be used to influence
-   the display of an image, BUT ONLY if it has been completely read! */
-#ifdef MNG_SUPPORT_DISPLAY
-#ifdef MNG_SUPPORT_READ
-MNG_EXT mng_retcode MNG_DECL mng_readdisplay     (mng_handle    hHandle);
-#endif
-MNG_EXT mng_retcode MNG_DECL mng_display         (mng_handle    hHandle);
-MNG_EXT mng_retcode MNG_DECL mng_display_resume  (mng_handle    hHandle);
-MNG_EXT mng_retcode MNG_DECL mng_display_freeze  (mng_handle    hHandle);
-MNG_EXT mng_retcode MNG_DECL mng_display_reset   (mng_handle    hHandle);
-#ifndef MNG_NO_DISPLAY_GO_SUPPORTED
-MNG_EXT mng_retcode MNG_DECL mng_display_goframe (mng_handle    hHandle,
-                                                  mng_uint32    iFramenr);
-MNG_EXT mng_retcode MNG_DECL mng_display_golayer (mng_handle    hHandle,
-                                                  mng_uint32    iLayernr);
-MNG_EXT mng_retcode MNG_DECL mng_display_gotime  (mng_handle    hHandle,
-                                                  mng_uint32    iPlaytime);
-#endif
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* event processing function */
-/* this needs to be called by the app when dynamic MNG is enabled and
-   a specific event occurs in the user-interface */
-#if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_SUPPORT_DYNAMICMNG)
-MNG_EXT mng_retcode MNG_DECL mng_trapevent       (mng_handle    hHandle,
-                                                  mng_uint8     iEventtype,
-                                                  mng_int32     iX,
-                                                  mng_int32     iY);
-#endif
-
-/* error reporting function */
-/* use this if you need more detailed info on the last error */
-/* iExtra1 & iExtra2 may contain errorcodes from zlib, jpeg, etc... */
-/* zErrortext will only be filled if you #define MNG_ERROR_TELLTALE */
-MNG_EXT mng_retcode MNG_DECL mng_getlasterror    (mng_handle    hHandle,
-                                                  mng_int8*     iSeverity,
-                                                  mng_chunkid*  iChunkname,
-                                                  mng_uint32*   iChunkseq,
-                                                  mng_int32*    iExtra1,
-                                                  mng_int32*    iExtra2,
-                                                  mng_pchar*    zErrortext);
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* *  Callback set functions                                                * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-/* memory callbacks */
-/* called to allocate and release internal datastructures */
-#ifndef MNG_INTERNAL_MEMMNGMT
-MNG_EXT mng_retcode MNG_DECL mng_setcb_memalloc      (mng_handle        hHandle,
-                                                      mng_memalloc      fProc);
-MNG_EXT mng_retcode MNG_DECL mng_setcb_memfree       (mng_handle        hHandle,
-                                                      mng_memfree       fProc);
-#endif /* MNG_INTERNAL_MEMMNGMT */
-
-/* open- & close-stream callbacks */
-/* called to open & close streams for input or output */
-#if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
-#ifndef MNG_NO_OPEN_CLOSE_STREAM
-MNG_EXT mng_retcode MNG_DECL mng_setcb_openstream    (mng_handle        hHandle,
-                                                      mng_openstream    fProc);
-MNG_EXT mng_retcode MNG_DECL mng_setcb_closestream   (mng_handle        hHandle,
-                                                      mng_closestream   fProc);
-#endif
-#endif
-
-/* read callback */
-/* called to get data from the inputstream */
-#ifdef MNG_SUPPORT_READ
-MNG_EXT mng_retcode MNG_DECL mng_setcb_readdata      (mng_handle        hHandle,
-                                                      mng_readdata      fProc);
-#endif
-
-/* write callback */
-/* called to put data into the outputstream */
-#ifdef MNG_SUPPORT_WRITE
-MNG_EXT mng_retcode MNG_DECL mng_setcb_writedata     (mng_handle        hHandle,
-                                                      mng_writedata     fProc);
-#endif
-
-/* error callback */
-/* called when an error occurs */
-/* the application can determine if the error is recoverable,
-   and may inform the library by setting specific returncodes */
-MNG_EXT mng_retcode MNG_DECL mng_setcb_errorproc     (mng_handle        hHandle,
-                                                      mng_errorproc     fProc);
-
-/* trace callback */
-/* called to show the currently executing function */
-#ifdef MNG_SUPPORT_TRACE
-MNG_EXT mng_retcode MNG_DECL mng_setcb_traceproc     (mng_handle        hHandle,
-                                                      mng_traceproc     fProc);
-#endif
-
-/* callbacks for read processing */
-/* processheader is called when all header information has been gathered
-   from the inputstream */
-/* processtext is called for every tEXt, zTXt and iTXt chunk in the
-   inputstream (iType=0 for tEXt, 1 for zTXt and 2 for iTXt);
-   you can call get_imagelevel to check at what nesting-level the chunk is
-   encountered (eg. tEXt inside an embedded image inside a MNG -> level == 2;
-                in most other case -> level == 1) */
-/* processsave & processseek are called for SAVE/SEEK chunks */
-/* processneed is called for the nEED chunk; you should specify a callback
-   for this as the default behavior will be to abort processing, unless
-   the requirement is one of:
-   - a supported chunk
-   - the text "draft nn" where nn is a numeric value
-   - the text "MNG-1.0" or "MNG-1.1"
-   - the text "CACHEOFF" */
-/* processmend is called at the very end of the animation-stream;
-   note that this may not be the end of the animation though! */
-/* processterm is called when a TERM chunk is encountered; there can be only
-   1 in the stream (or none) */
-/* processunknown is called after reading each non-critical unknown chunk */
-#ifdef MNG_SUPPORT_READ
-MNG_EXT mng_retcode MNG_DECL mng_setcb_processheader (mng_handle        hHandle,
-                                                      mng_processheader fProc);
-MNG_EXT mng_retcode MNG_DECL mng_setcb_processtext   (mng_handle        hHandle,
-                                                      mng_processtext   fProc);
-MNG_EXT mng_retcode MNG_DECL mng_setcb_processsave   (mng_handle        hHandle,
-                                                      mng_processsave   fProc);
-MNG_EXT mng_retcode MNG_DECL mng_setcb_processseek   (mng_handle        hHandle,
-                                                      mng_processseek   fProc);
-MNG_EXT mng_retcode MNG_DECL mng_setcb_processneed   (mng_handle        hHandle,
-                                                      mng_processneed   fProc);
-MNG_EXT mng_retcode MNG_DECL mng_setcb_processmend   (mng_handle        hHandle,
-                                                      mng_processmend   fProc);
-MNG_EXT mng_retcode MNG_DECL mng_setcb_processterm   (mng_handle        hHandle,
-                                                      mng_processterm   fProc);
-MNG_EXT mng_retcode MNG_DECL mng_setcb_processunknown(mng_handle        hHandle,
-                                                      mng_processunknown fProc);
-#endif
-
-/* callbacks for display processing */
-/* getcanvasline is called to get an access-pointer to a line on the
-   drawing-canvas */
-/* getbkgdline is called to get an access-pointer to a line from the
-   background-canvas */
-/* refresh is called to inform the GUI to redraw the current canvas onto
-   its output device (eg. in Win32 this would mean sending an
-   invalidate message for the specified region */
-/* NOTE that the update-region is specified as x,y,width,height; eg. the
-   invalidate message for Windows requires left,top,right,bottom parameters
-   where the bottom-right is exclusive of the region!!
-   to get these correctly is as simple as:
-   left   = x;
-   top    = y;
-   right  = x + width;
-   bottom = y + height;
-   if your implementation requires inclusive points, simply subtract 1 from
-   both the right & bottom values calculated above.
-   */
-#ifdef MNG_SUPPORT_DISPLAY
-MNG_EXT mng_retcode MNG_DECL mng_setcb_getcanvasline (mng_handle        hHandle,
-                                                      mng_getcanvasline fProc);
-MNG_EXT mng_retcode MNG_DECL mng_setcb_getbkgdline   (mng_handle        hHandle,
-                                                      mng_getbkgdline   fProc);
-MNG_EXT mng_retcode MNG_DECL mng_setcb_getalphaline  (mng_handle        hHandle,
-                                                      mng_getalphaline  fProc);
-MNG_EXT mng_retcode MNG_DECL mng_setcb_refresh       (mng_handle        hHandle,
-                                                      mng_refresh       fProc);
-
-/* timing callbacks */
-/* gettickcount is called to get the system tickcount (milliseconds);
-   this is used to determine the remaining interval between frames */
-/* settimer is called to inform the application that it should set a timer;
-   when the timer is triggered the app must call mng_display_resume */
-MNG_EXT mng_retcode MNG_DECL mng_setcb_gettickcount  (mng_handle        hHandle,
-                                                      mng_gettickcount  fProc);
-MNG_EXT mng_retcode MNG_DECL mng_setcb_settimer      (mng_handle        hHandle,
-                                                      mng_settimer      fProc);
-
-/* color management callbacks */
-/* called to transmit color management information to the application */
-/* these are only used when you #define MNG_APP_CMS */
-#ifdef MNG_APP_CMS
-MNG_EXT mng_retcode MNG_DECL mng_setcb_processgamma  (mng_handle        hHandle,
-                                                      mng_processgamma  fProc);
-MNG_EXT mng_retcode MNG_DECL mng_setcb_processchroma (mng_handle        hHandle,
-                                                      mng_processchroma fProc);
-MNG_EXT mng_retcode MNG_DECL mng_setcb_processsrgb   (mng_handle        hHandle,
-                                                      mng_processsrgb   fProc);
-MNG_EXT mng_retcode MNG_DECL mng_setcb_processiccp   (mng_handle        hHandle,
-                                                      mng_processiccp   fProc);
-MNG_EXT mng_retcode MNG_DECL mng_setcb_processarow   (mng_handle        hHandle,
-                                                      mng_processarow   fProc);
-#endif /* MNG_APP_CMS */
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* release push data callback */
-/* used when the app pushes data into libmng (as opposed to libmng pulling it)
-   and relinquishes ownership of the pushed data-buffer, but *does* want to
-   release (free) the buffer itself once libmng has finished processing it */
-#ifdef MNG_SUPPORT_READ
-MNG_EXT mng_retcode MNG_DECL mng_setcb_releasedata   (mng_handle        hHandle,
-                                                      mng_releasedata   fProc);
-#endif
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* *  Callback get functions                                                * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-/* see _setcb_ */
-#ifndef MNG_INTERNAL_MEMMNGMT
-MNG_EXT mng_memalloc      MNG_DECL mng_getcb_memalloc      (mng_handle hHandle);
-MNG_EXT mng_memfree       MNG_DECL mng_getcb_memfree       (mng_handle hHandle);
-#endif
-
-/* see _setcb_ */
-#ifdef MNG_SUPPORT_READ
-MNG_EXT mng_releasedata   MNG_DECL mng_getcb_releasedata   (mng_handle hHandle);
-#endif
-
-/* see _setcb_ */
-#if defined(MNG_SUPPORT_READ) || defined(MNG_WRITE_SUPPORT)
-#ifndef MNG_NO_OPEN_CLOSE_STREAM
-MNG_EXT mng_openstream    MNG_DECL mng_getcb_openstream    (mng_handle hHandle);
-MNG_EXT mng_closestream   MNG_DECL mng_getcb_closestream   (mng_handle hHandle);
-#endif
-#endif
-
-/* see _setcb_ */
-#ifdef MNG_SUPPORT_READ
-MNG_EXT mng_readdata      MNG_DECL mng_getcb_readdata      (mng_handle hHandle);
-#endif
-
-/* see _setcb_ */
-#ifdef MNG_SUPPORT_WRITE
-MNG_EXT mng_writedata     MNG_DECL mng_getcb_writedata     (mng_handle hHandle);
-#endif
-
-/* see _setcb_ */
-MNG_EXT mng_errorproc     MNG_DECL mng_getcb_errorproc     (mng_handle hHandle);
-
-/* see _setcb_ */
-#ifdef MNG_SUPPORT_TRACE
-MNG_EXT mng_traceproc     MNG_DECL mng_getcb_traceproc     (mng_handle hHandle);
-#endif
-
-/* see _setcb_ */
-#ifdef MNG_SUPPORT_READ
-MNG_EXT mng_processheader MNG_DECL mng_getcb_processheader (mng_handle hHandle);
-MNG_EXT mng_processtext   MNG_DECL mng_getcb_processtext   (mng_handle hHandle);
-MNG_EXT mng_processsave   MNG_DECL mng_getcb_processsave   (mng_handle hHandle);
-MNG_EXT mng_processseek   MNG_DECL mng_getcb_processseek   (mng_handle hHandle);
-MNG_EXT mng_processneed   MNG_DECL mng_getcb_processneed   (mng_handle hHandle);
-MNG_EXT mng_processunknown MNG_DECL mng_getcb_processunknown (mng_handle hHandle);
-MNG_EXT mng_processterm   MNG_DECL mng_getcb_processterm   (mng_handle hHandle);
-#endif
-
-/* see _setcb_ */
-#ifdef MNG_SUPPORT_DISPLAY
-MNG_EXT mng_getcanvasline MNG_DECL mng_getcb_getcanvasline (mng_handle hHandle);
-MNG_EXT mng_getbkgdline   MNG_DECL mng_getcb_getbkgdline   (mng_handle hHandle);
-MNG_EXT mng_getalphaline  MNG_DECL mng_getcb_getalphaline  (mng_handle hHandle);
-MNG_EXT mng_refresh       MNG_DECL mng_getcb_refresh       (mng_handle hHandle);
-
-/* see _setcb_ */
-MNG_EXT mng_gettickcount  MNG_DECL mng_getcb_gettickcount  (mng_handle hHandle);
-MNG_EXT mng_settimer      MNG_DECL mng_getcb_settimer      (mng_handle hHandle);
-
-/* see _setcb_ */
-#ifdef MNG_APP_CMS
-MNG_EXT mng_processgamma  MNG_DECL mng_getcb_processgamma  (mng_handle hHandle);
-MNG_EXT mng_processchroma MNG_DECL mng_getcb_processchroma (mng_handle hHandle);
-MNG_EXT mng_processsrgb   MNG_DECL mng_getcb_processsrgb   (mng_handle hHandle);
-MNG_EXT mng_processiccp   MNG_DECL mng_getcb_processiccp   (mng_handle hHandle);
-MNG_EXT mng_processarow   MNG_DECL mng_getcb_processarow   (mng_handle hHandle);
-#endif /* MNG_APP_CMS */
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* *  Property set functions                                                * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-/* Application data pointer */
-/* provided for application use; not used by the library */
-MNG_EXT mng_retcode MNG_DECL mng_set_userdata        (mng_handle        hHandle,
-                                                      mng_ptr           pUserdata);
-
-/* The style of the drawing- & background-canvas */
-/* only used for displaying images */
-/* both are initially set to 24-bit RGB (eg. 8-bit per channel) */
-MNG_EXT mng_retcode MNG_DECL mng_set_canvasstyle     (mng_handle        hHandle,
-                                                      mng_uint32        iStyle);
-MNG_EXT mng_retcode MNG_DECL mng_set_bkgdstyle       (mng_handle        hHandle,
-                                                      mng_uint32        iStyle);
-
-/* The default background color */
-/* only used if the getbkgdline callback is not defined */
-/* for initially painting the canvas and restoring (part of) the background */
-MNG_EXT mng_retcode MNG_DECL mng_set_bgcolor         (mng_handle        hHandle,
-                                                      mng_uint16        iRed,
-                                                      mng_uint16        iGreen,
-                                                      mng_uint16        iBlue);
-
-/* Indicates preferred use of the bKGD chunk for PNG images */
-MNG_EXT mng_retcode MNG_DECL mng_set_usebkgd         (mng_handle        hHandle,
-                                                      mng_bool          bUseBKGD);
-
-/* Indicates storage of read chunks */
-/* only useful if you #define mng_store_chunks */
-/* can be used to dynamically change storage management */
-MNG_EXT mng_retcode MNG_DECL mng_set_storechunks     (mng_handle        hHandle,
-                                                      mng_bool          bStorechunks);
-
-/* Indicates breaks requested when processing SAVE/SEEK */
-/* set this to let the app handle section breaks; the library will return
-   MNG_NEEDSECTIONWAIT return-codes for each SEEK chunk */
-MNG_EXT mng_retcode MNG_DECL mng_set_sectionbreaks   (mng_handle        hHandle,
-                                                      mng_bool          bSectionbreaks);
-
-/* Indicates storage of playback info (ON by default!) */
-/* can be used to turn off caching of playback info; this is useful to
-   specifically optimize MNG-video playback; note that if caching is turned off
-   LOOP chunks will be flagged as errors! TERM chunks will be ignored and only
-   passed to the processterm() callback if it is defined by the app; also, this
-   feature can only be used with mng_readdisplay(); mng_read(),
-   mng_display_reset() and mng_display_goxxxx() will return an error;
-   once this option is turned off it can't be turned on for the same stream!!! */
-MNG_EXT mng_retcode MNG_DECL mng_set_cacheplayback   (mng_handle        hHandle,
-                                                      mng_bool          bCacheplayback);
-
-/* Indicates automatic progressive refreshes for large images (ON by default!) */
-/* turn this off if you do not want intermittent painting while a large image
-   is being read. useful if the input-stream comes from a fast medium, such
-   as a local harddisk */
-MNG_EXT mng_retcode MNG_DECL mng_set_doprogressive   (mng_handle        hHandle,
-                                                      mng_bool          bDoProgressive);
-
-/* Indicates existence and required checking of the CRC in input streams,
-   and generation in output streams */
-/* !!!! Use this ONLY if you know what you are doing !!!! */
-/* The value is a combination of the following flags:
-   0x0000001 = CRC is present in the input stream
-   0x0000002 = CRC must be generated in the output stream
-   0x0000010 = CRC should be checked for ancillary chunks
-   0x0000020 = a faulty CRC for ancillary chunks generates a warning only
-   0x0000040 = a faulty CRC for ancillary chunks generates an error
-   0x0000100 = CRC should be checked for critical chunks
-   0x0000200 = a faulty CRC for critical chunks generates a warning only
-   0x0000400 = a faulty CRC for critical chunks generates an error
-
-   The default is 0x00000533 = CRC present in input streams; should be checked;
-                               warning for ancillary chunks; error for critical
-                               chunks; generate CRC for output streams
-
-   Note that some combinations are meaningless; eg. if the CRC is not present
-   it won't do any good to turn the checking flags on; if a checking flag
-   is off, it doesn't do any good to ask for generation of warnings or errors.
-   Also libmng will generate either an error or a warning, not both,
-   so if you specify both the default will be to generate an error!
-   The only useful combinations for input are 331, 551, 351, 531, 0, 301, 501
-   and optionally 031 and 051, but only checking ancillary chunks and not
-   critical chunks is generally not a very good idea!!!
-   If you've also writing these values should be combined with 0x02 if
-   CRC's are required in the output stream
-   */
-MNG_EXT mng_retcode MNG_DECL mng_set_crcmode         (mng_handle        hHandle,
-                                                      mng_uint32        iCrcmode);
-
-/* Color-management necessaries */
-/*
-    *************************************************************************
-                 !!!!!!!! THIS NEXT BIT IS IMPORTANT !!!!!!!!!
-    *************************************************************************
-
-    If you have defined MNG_FULL_CMS (and are using lcms), you will have to
-    think hard about the following routines.
-
-    lcms requires 2 profiles to work off the differences in the input-image
-    and the output-device. The ICC profile for the input-image will be
-    embedded within it to reflect its color-characteristics, but the output
-    profile depends on the output-device, which is something only *YOU* know
-    about. sRGB (standard RGB) is common for x86 compatible environments
-    (eg. Windows, Linux and some others)
-
-    If you are compiling for a sRGB compliant system you probably won't have
-    to do anything special. (unless you want to of course)
-
-    If you are compiling for a non-sRGB compliant system
-    (eg. SGI, Mac, Next, others...)
-    you *MUST* define a proper ICC profile for the generic output-device
-    associated with that platform.
-
-    In either event, you may also want to offer an option to your users to
-    set the profile manually, or, if you know how, set it from a
-    system-defined default.
-
-    TO RECAP: for sRGB systems (Windows, Linux) no action required!
-              for non-sRGB systems (SGI, Mac, Next) ACTION REQUIRED!
-
-    Please visit http://www.srgb.com, http://www.color.org and
-    http://www.littlecms.com for more info.
-
-    *************************************************************************
-                 !!!!!!!! THE BIT ABOVE IS IMPORTANT !!!!!!!!!
-    *************************************************************************
-*/
-/* mng_set_srgb tells libmng if it's running on a sRGB compliant system or not
-   the default is already set to MNG_TRUE */
-/* mng_set_outputprofile, mng_set_outputprofile2, mng_set_outputsrgb
-   are used to set the default profile describing the output-device
-   by default it is already initialized with an sRGB profile */
-/* mng_set_srgbprofile, mng_set_srgbprofile2, mng_set_srgbimplicit
-   are used to set the default profile describing a standard sRGB device
-   this is used when the input-image is tagged only as being sRGB, but the
-   output-device is defined as not being sRGB compliant
-   by default it is already initialized with a standard sRGB profile */
-#if defined(MNG_SUPPORT_DISPLAY)
-MNG_EXT mng_retcode MNG_DECL mng_set_srgb            (mng_handle        hHandle,
-                                                      mng_bool          bIssRGB);
-MNG_EXT mng_retcode MNG_DECL mng_set_outputprofile   (mng_handle        hHandle,
-                                                      mng_pchar         zFilename);
-MNG_EXT mng_retcode MNG_DECL mng_set_outputprofile2  (mng_handle        hHandle,
-                                                      mng_uint32        iProfilesize,
-                                                      mng_ptr           pProfile);
-MNG_EXT mng_retcode MNG_DECL mng_set_outputsrgb      (mng_handle        hHandle);
-MNG_EXT mng_retcode MNG_DECL mng_set_srgbprofile     (mng_handle        hHandle,
-                                                      mng_pchar         zFilename);
-MNG_EXT mng_retcode MNG_DECL mng_set_srgbprofile2    (mng_handle        hHandle,
-                                                      mng_uint32        iProfilesize,
-                                                      mng_ptr           pProfile);
-MNG_EXT mng_retcode MNG_DECL mng_set_srgbimplicit    (mng_handle        hHandle);
-#endif
-
-#if defined(MNG_FULL_CMS) || defined(MNG_GAMMA_ONLY) || defined(MNG_APP_CMS)
-/* Gamma settings */
-/* ... blabla (explain gamma processing a little; eg. formula & stuff) ... */
-MNG_EXT mng_retcode MNG_DECL mng_set_viewgamma       (mng_handle        hHandle,
-                                                      mng_float         dGamma);
-MNG_EXT mng_retcode MNG_DECL mng_set_displaygamma    (mng_handle        hHandle,
-                                                      mng_float         dGamma);
-MNG_EXT mng_retcode MNG_DECL mng_set_dfltimggamma    (mng_handle        hHandle,
-                                                      mng_float         dGamma);
-MNG_EXT mng_retcode MNG_DECL mng_set_viewgammaint    (mng_handle        hHandle,
-                                                      mng_uint32        iGamma);
-MNG_EXT mng_retcode MNG_DECL mng_set_displaygammaint (mng_handle        hHandle,
-                                                      mng_uint32        iGamma);
-MNG_EXT mng_retcode MNG_DECL mng_set_dfltimggammaint (mng_handle        hHandle,
-                                                      mng_uint32        iGamma);
-#endif
-
-#ifndef MNG_SKIP_MAXCANVAS
-/* Ultimate clipping size */
-/* used to limit extreme graphics from overloading the system */
-/* if a graphic exceeds these limits a warning is issued, which can
-   be ignored by the app (using the errorproc callback). in that case
-   the library will use these settings to clip the input graphic, and
-   the app's canvas must account for this */
-MNG_EXT mng_retcode MNG_DECL mng_set_maxcanvaswidth  (mng_handle        hHandle,
-                                                      mng_uint32        iMaxwidth);
-MNG_EXT mng_retcode MNG_DECL mng_set_maxcanvasheight (mng_handle        hHandle,
-                                                      mng_uint32        iMaxheight);
-MNG_EXT mng_retcode MNG_DECL mng_set_maxcanvassize   (mng_handle        hHandle,
-                                                      mng_uint32        iMaxwidth,
-                                                      mng_uint32        iMaxheight);
-#endif
-
-/* ZLIB default compression parameters */
-/* these are used when writing out chunks */
-/* they are also used when compressing PNG image-data or JNG alpha-data;
-   in this case you can set them just before calling mng_putimgdata_ihdr */
-/* set to your liking; usually the defaults will suffice though! */
-/* check the documentation for ZLIB for details on these parameters */
-#ifdef MNG_INCLUDE_ZLIB
-MNG_EXT mng_retcode MNG_DECL mng_set_zlib_level      (mng_handle        hHandle,
-                                                      mng_int32         iZlevel);
-MNG_EXT mng_retcode MNG_DECL mng_set_zlib_method     (mng_handle        hHandle,
-                                                      mng_int32         iZmethod);
-MNG_EXT mng_retcode MNG_DECL mng_set_zlib_windowbits (mng_handle        hHandle,
-                                                      mng_int32         iZwindowbits);
-MNG_EXT mng_retcode MNG_DECL mng_set_zlib_memlevel   (mng_handle        hHandle,
-                                                      mng_int32         iZmemlevel);
-MNG_EXT mng_retcode MNG_DECL mng_set_zlib_strategy   (mng_handle        hHandle,
-                                                      mng_int32         iZstrategy);
-
-MNG_EXT mng_retcode MNG_DECL mng_set_zlib_maxidat    (mng_handle        hHandle,
-                                                      mng_uint32        iMaxIDAT);
-#endif /* MNG_INCLUDE_ZLIB */
-
-/* JNG default compression parameters (based on IJG code) */
-/* these are used when compressing JNG image-data; so you can set them
-   just before calling mng_putimgdata_jhdr */
-/* set to your liking; usually the defaults will suffice though! */
-/* check the documentation for IJGSRC6B for details on these parameters */
-#ifdef MNG_INCLUDE_JNG
-#ifdef MNG_INCLUDE_IJG6B
-MNG_EXT mng_retcode MNG_DECL mng_set_jpeg_dctmethod  (mng_handle        hHandle,
-                                                      mngjpeg_dctmethod eJPEGdctmethod);
-#endif
-MNG_EXT mng_retcode MNG_DECL mng_set_jpeg_quality    (mng_handle        hHandle,
-                                                      mng_int32         iJPEGquality);
-MNG_EXT mng_retcode MNG_DECL mng_set_jpeg_smoothing  (mng_handle        hHandle,
-                                                      mng_int32         iJPEGsmoothing);
-MNG_EXT mng_retcode MNG_DECL mng_set_jpeg_progressive(mng_handle        hHandle,
-                                                      mng_bool          bJPEGprogressive);
-MNG_EXT mng_retcode MNG_DECL mng_set_jpeg_optimized  (mng_handle        hHandle,
-                                                      mng_bool          bJPEGoptimized);
-
-MNG_EXT mng_retcode MNG_DECL mng_set_jpeg_maxjdat    (mng_handle        hHandle,
-                                                      mng_uint32        iMaxJDAT);
-#endif /* MNG_INCLUDE_JNG */
-
-/* Suspension-mode setting */
-/* use this to activate the internal suspension-buffer to improve
-   read-suspension processing */
-/* TODO: write-suspension ??? */   
-#if defined(MNG_SUPPORT_READ)
-MNG_EXT mng_retcode MNG_DECL mng_set_suspensionmode  (mng_handle        hHandle,
-                                                      mng_bool          bSuspensionmode);
-#endif
-
-/* Speed setting */
-/* use this to influence the display-speed of animations */
-#if defined(MNG_SUPPORT_DISPLAY)
-MNG_EXT mng_retcode MNG_DECL mng_set_speed           (mng_handle        hHandle,
-                                                      mng_speedtype     iSpeed);
-#endif
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* *  Property get functions                                                * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-/* see _set_ */
-MNG_EXT mng_ptr     MNG_DECL mng_get_userdata        (mng_handle        hHandle);
-
-/* Network Graphic header details */
-/* these get filled once the graphics header is processed,
-   so they are available in the processheader callback; before that
-   they are zeroed out and imagetype is set to it_unknown */
-/* this might be a good point for the app to initialize the drawing-canvas! */
-/* note that some fields are only set for the first(!) header-chunk:
-   MNG/MHDR (imagetype = mng_it_mng) - ticks thru simplicity
-   PNG/IHDR (imagetype = mng_it_png) - bitdepth thru interlace
-   JNG/JHDR (imagetype = mng_it_jng) - bitdepth thru compression &
-                                       interlace thru alphainterlace */
-MNG_EXT mng_imgtype MNG_DECL mng_get_sigtype         (mng_handle        hHandle);
-MNG_EXT mng_imgtype MNG_DECL mng_get_imagetype       (mng_handle        hHandle);
-MNG_EXT mng_uint32  MNG_DECL mng_get_imagewidth      (mng_handle        hHandle);
-MNG_EXT mng_uint32  MNG_DECL mng_get_imageheight     (mng_handle        hHandle);
-
-MNG_EXT mng_uint32  MNG_DECL mng_get_ticks           (mng_handle        hHandle);
-MNG_EXT mng_uint32  MNG_DECL mng_get_framecount      (mng_handle        hHandle);
-MNG_EXT mng_uint32  MNG_DECL mng_get_layercount      (mng_handle        hHandle);
-MNG_EXT mng_uint32  MNG_DECL mng_get_playtime        (mng_handle        hHandle);
-MNG_EXT mng_uint32  MNG_DECL mng_get_simplicity      (mng_handle        hHandle);
-
-MNG_EXT mng_uint8   MNG_DECL mng_get_bitdepth        (mng_handle        hHandle);
-MNG_EXT mng_uint8   MNG_DECL mng_get_colortype       (mng_handle        hHandle);
-MNG_EXT mng_uint8   MNG_DECL mng_get_compression     (mng_handle        hHandle);
-MNG_EXT mng_uint8   MNG_DECL mng_get_filter          (mng_handle        hHandle);
-MNG_EXT mng_uint8   MNG_DECL mng_get_interlace       (mng_handle        hHandle);
-MNG_EXT mng_uint8   MNG_DECL mng_get_alphabitdepth   (mng_handle        hHandle);
-MNG_EXT mng_uint8   MNG_DECL mng_get_alphacompression(mng_handle        hHandle);
-MNG_EXT mng_uint8   MNG_DECL mng_get_alphafilter     (mng_handle        hHandle);
-MNG_EXT mng_uint8   MNG_DECL mng_get_alphainterlace  (mng_handle        hHandle);
-
-/* indicates the predicted alpha-depth required to properly display the image */
-/* gets set once the graphics header is processed and is available in the
-   processheader callback for any type of input-image (PNG, JNG or MNG) */
-/* possible values are 0,1,2,4,8,16
-   0  = no transparency required
-   1  = on/off transparency required (alpha-values are 0 or 2^bit_depth-1)
-   2+ = semi-transparency required (values will be scaled to the bitdepth of the
-                                    canvasstyle supplied by the application) */
-MNG_EXT mng_uint8   MNG_DECL mng_get_alphadepth      (mng_handle        hHandle);
-
-/* defines whether a refresh() callback is called for an interlace pass (PNG)
-   or progressive scan (JNG) */
-/* returns the interlace pass number for PNG or a fabricated pass number for JNG;
-   returns 0 in all other cases */
-/* only useful if the image_type = mng_it_png or mng_it_jng and if the image
-   is actually interlaced (PNG) or progressive (JNG) */
-#ifdef MNG_SUPPORT_DISPLAY
-MNG_EXT mng_uint8   MNG_DECL mng_get_refreshpass     (mng_handle        hHandle);
-#endif
-
-/* see _set_ */
-MNG_EXT mng_uint32  MNG_DECL mng_get_canvasstyle     (mng_handle        hHandle);
-MNG_EXT mng_uint32  MNG_DECL mng_get_bkgdstyle       (mng_handle        hHandle);
-
-/* see _set_ */
-MNG_EXT mng_retcode MNG_DECL mng_get_bgcolor         (mng_handle        hHandle,
-                                                      mng_uint16*       iRed,
-                                                      mng_uint16*       iGreen,
-                                                      mng_uint16*       iBlue);
-
-/* see _set_ */
-MNG_EXT mng_bool    MNG_DECL mng_get_usebkgd         (mng_handle        hHandle);
-
-/* see _set_ */
-MNG_EXT mng_bool    MNG_DECL mng_get_storechunks     (mng_handle        hHandle);
-
-/* see _set_ */
-MNG_EXT mng_bool    MNG_DECL mng_get_sectionbreaks   (mng_handle        hHandle);
-
-/* see _set_ */
-MNG_EXT mng_bool    MNG_DECL mng_get_cacheplayback   (mng_handle        hHandle);
-
-/* see _set_ */
-MNG_EXT mng_bool    MNG_DECL mng_get_doprogressive   (mng_handle        hHandle);
-
-/* see _set_ */
-MNG_EXT mng_uint32  MNG_DECL mng_get_crcmode         (mng_handle        hHandle);
-
-/* see _set_ */
-#if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_FULL_CMS)
-MNG_EXT mng_bool    MNG_DECL mng_get_srgb            (mng_handle        hHandle);
-#endif
-
-/* see _set_ */
-MNG_EXT mng_float   MNG_DECL mng_get_viewgamma       (mng_handle        hHandle);
-MNG_EXT mng_float   MNG_DECL mng_get_displaygamma    (mng_handle        hHandle);
-MNG_EXT mng_float   MNG_DECL mng_get_dfltimggamma    (mng_handle        hHandle);
-MNG_EXT mng_uint32  MNG_DECL mng_get_viewgammaint    (mng_handle        hHandle);
-MNG_EXT mng_uint32  MNG_DECL mng_get_displaygammaint (mng_handle        hHandle);
-MNG_EXT mng_uint32  MNG_DECL mng_get_dfltimggammaint (mng_handle        hHandle);
-
-#ifndef MNG_SKIP_MAXCANVAS
-/* see _set_ */
-MNG_EXT mng_uint32  MNG_DECL mng_get_maxcanvaswidth  (mng_handle        hHandle);
-MNG_EXT mng_uint32  MNG_DECL mng_get_maxcanvasheight (mng_handle        hHandle);
-#endif
-
-/* see _set_ */
-#ifdef MNG_INCLUDE_ZLIB
-MNG_EXT mng_int32   MNG_DECL mng_get_zlib_level      (mng_handle        hHandle);
-MNG_EXT mng_int32   MNG_DECL mng_get_zlib_method     (mng_handle        hHandle);
-MNG_EXT mng_int32   MNG_DECL mng_get_zlib_windowbits (mng_handle        hHandle);
-MNG_EXT mng_int32   MNG_DECL mng_get_zlib_memlevel   (mng_handle        hHandle);
-MNG_EXT mng_int32   MNG_DECL mng_get_zlib_strategy   (mng_handle        hHandle);
-
-MNG_EXT mng_uint32  MNG_DECL mng_get_zlib_maxidat    (mng_handle        hHandle);
-#endif /* MNG_INCLUDE_ZLIB */
-
-/* see _set_ */
-#ifdef MNG_INCLUDE_JNG
-#ifdef MNG_INCLUDE_IJG6B
-MNG_EXT mngjpeg_dctmethod
-                    MNG_DECL mng_get_jpeg_dctmethod  (mng_handle        hHandle);
-#endif
-MNG_EXT mng_int32   MNG_DECL mng_get_jpeg_quality    (mng_handle        hHandle);
-MNG_EXT mng_int32   MNG_DECL mng_get_jpeg_smoothing  (mng_handle        hHandle);
-MNG_EXT mng_bool    MNG_DECL mng_get_jpeg_progressive(mng_handle        hHandle);
-MNG_EXT mng_bool    MNG_DECL mng_get_jpeg_optimized  (mng_handle        hHandle);
-
-MNG_EXT mng_uint32  MNG_DECL mng_get_jpeg_maxjdat    (mng_handle        hHandle);
-#endif /* MNG_INCLUDE_JNG */
-
-/* see _set_  */
-#if defined(MNG_SUPPORT_READ)
-MNG_EXT mng_bool    MNG_DECL mng_get_suspensionmode  (mng_handle        hHandle);
-#endif
-
-/* see _set_  */
-#if defined(MNG_SUPPORT_DISPLAY)
-MNG_EXT mng_speedtype
-                    MNG_DECL mng_get_speed           (mng_handle        hHandle);
-#endif
-
-/* Image-level */
-/* this can be used inside the processtext callback to determine the level of
-   text of the image being processed; the value 1 is returned for top-level
-   texts, and the value 2 for a text inside an embedded image inside a MNG */
-MNG_EXT mng_uint32  MNG_DECL mng_get_imagelevel      (mng_handle        hHandle);
-
-/* BACK info */
-/* can be used to retrieve the color & mandatory values for the last processed
-   BACK chunk of a MNG (will fail for other image-types);
-   if no BACK chunk was processed yet, it will return all zeroes */
-#ifdef MNG_SUPPORT_DISPLAY
-MNG_EXT mng_retcode MNG_DECL mng_get_lastbackchunk   (mng_handle        hHandle,
-                                                      mng_uint16*       iRed,
-                                                      mng_uint16*       iGreen,
-                                                      mng_uint16*       iBlue,
-                                                      mng_uint8*        iMandatory);
-#endif
-
-/* SEEK info */
-/* can be used to retrieve the segmentname of the last processed SEEK chunk;
-   if no SEEK chunk was processed or its segmentname was empty, the function
-   will return an empty string; the provided buffer must be at least 80 bytes!! */
-#ifdef MNG_SUPPORT_DISPLAY
-MNG_EXT mng_retcode MNG_DECL mng_get_lastseekname    (mng_handle        hHandle,
-                                                      mng_pchar         zSegmentname);
-#endif
-
-/* FRAM info */
-/* can be used to retrieve the current FRAM delay; this may be useful when
-   retrieving a stream of frames with their corresponding delays by "fake"
-   reading and displaying the file */
-#ifdef MNG_SUPPORT_DISPLAY
-MNG_EXT mng_uint32 MNG_DECL mng_get_currframdelay    (mng_handle        hHandle);
-#endif
-
-/* Display status variables */
-/* these get filled & updated during display processing */
-/* starttime is the tickcount at the start of displaying the animation */
-/* runtime is the actual number of millisecs since the start of the animation */
-/* currentframe, currentlayer & currentplaytime indicate the current
-   frame/layer/playtime(msecs) in the animation (these keep increasing;
-   even after the animation loops back to the TERM chunk) */
-/* totalframes, totallayers & totalplaytime are filled after a complete run
-   of an animation (eg. at MEND); they are also valid after just reading the MNG */
-#ifdef MNG_SUPPORT_DISPLAY
-MNG_EXT mng_uint32  MNG_DECL mng_get_starttime       (mng_handle        hHandle);
-MNG_EXT mng_uint32  MNG_DECL mng_get_runtime         (mng_handle        hHandle);
-#ifndef MNG_NO_CURRENT_INFO
-MNG_EXT mng_uint32  MNG_DECL mng_get_currentframe    (mng_handle        hHandle);
-MNG_EXT mng_uint32  MNG_DECL mng_get_currentlayer    (mng_handle        hHandle);
-MNG_EXT mng_uint32  MNG_DECL mng_get_currentplaytime (mng_handle        hHandle);
-MNG_EXT mng_uint32  MNG_DECL mng_get_totalframes     (mng_handle        hHandle);
-MNG_EXT mng_uint32  MNG_DECL mng_get_totallayers     (mng_handle        hHandle);
-MNG_EXT mng_uint32  MNG_DECL mng_get_totalplaytime   (mng_handle        hHandle);
-#endif
-#endif
-
-/* Status variables */
-/* these indicate the internal state of the library */
-/* most indicate exactly what you would expect -
-   status_error:        true if the last function call returned an errorcode
-   status_reading:      true if the library is (still) reading an image
-   status_suspendbreak: true if the library has suspended for "I/O"
-   status_creating:     true if the library is in the middle of creating an image
-   status_writing:      true if the library is in the middle of writing an image
-   status_displaying:   true if the library is displaying an image
-   status_running:      true if display processing is active (eg. not frozen or reset)
-   status_timerbreak:   true if the library has suspended for a "timer-break"
-   status_dynamic:      true if the library encountered an evNT chunk in the MNG
-   status_runningevent: true if the library is processing an external event */
-/* eg. mng_readdisplay() will turn the reading, displaying and running status on;
-   when EOF is reached the reading status will be turned off */   
-MNG_EXT mng_bool    MNG_DECL mng_status_error        (mng_handle        hHandle);
-#ifdef MNG_SUPPORT_READ
-MNG_EXT mng_bool    MNG_DECL mng_status_reading      (mng_handle        hHandle);
-MNG_EXT mng_bool    MNG_DECL mng_status_suspendbreak (mng_handle        hHandle);
-#endif
-#ifdef MNG_SUPPORT_WRITE
-MNG_EXT mng_bool    MNG_DECL mng_status_creating     (mng_handle        hHandle);
-MNG_EXT mng_bool    MNG_DECL mng_status_writing      (mng_handle        hHandle);
-#endif
-#ifdef MNG_SUPPORT_DISPLAY
-MNG_EXT mng_bool    MNG_DECL mng_status_displaying   (mng_handle        hHandle);
-MNG_EXT mng_bool    MNG_DECL mng_status_running      (mng_handle        hHandle);
-MNG_EXT mng_bool    MNG_DECL mng_status_timerbreak   (mng_handle        hHandle);
-#endif
-#ifdef MNG_SUPPORT_DYNAMICMNG
-MNG_EXT mng_bool    MNG_DECL mng_status_dynamic      (mng_handle        hHandle);
-MNG_EXT mng_bool    MNG_DECL mng_status_runningevent (mng_handle        hHandle);
-#endif
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* *  Chunk access functions                                                * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifdef MNG_ACCESS_CHUNKS
-
-/* ************************************************************************** */
-
-/* use this to iterate the stored chunks */
-/* requires MNG_ACCESS_CHUNKS & MNG_STORE_CHUNKS */
-/* starts from the supplied chunk-index-nr; the first chunk has index 0!! */
-MNG_EXT mng_retcode MNG_DECL mng_iterate_chunks      (mng_handle       hHandle,
-                                                      mng_uint32       iChunkseq,
-                                                      mng_iteratechunk fProc);
-
-/* use the next function inside your 'iteratechunk' callback to copy
-   the given chunk to a new mng you are creating */
-/* the 'out' handle should be in 'create' status! */
-#ifdef MNG_SUPPORT_WRITE
-MNG_EXT mng_retcode MNG_DECL mng_copy_chunk          (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_handle       hHandleOut);
-#endif
-
-/* ************************************************************************** */
-
-/* use these to get chunk data from within the callback in iterate_chunks */
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_ihdr       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_uint32       *iWidth,
-                                                      mng_uint32       *iHeight,
-                                                      mng_uint8        *iBitdepth,
-                                                      mng_uint8        *iColortype,
-                                                      mng_uint8        *iCompression,
-                                                      mng_uint8        *iFilter,
-                                                      mng_uint8        *iInterlace);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_plte       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_uint32       *iCount,
-                                                      mng_palette8     *aPalette);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_idat       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_uint32       *iRawlen,
-                                                      mng_ptr          *pRawdata);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_trns       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_bool         *bEmpty,
-                                                      mng_bool         *bGlobal,
-                                                      mng_uint8        *iType,
-                                                      mng_uint32       *iCount,
-                                                      mng_uint8arr     *aAlphas,
-                                                      mng_uint16       *iGray,
-                                                      mng_uint16       *iRed,
-                                                      mng_uint16       *iGreen,
-                                                      mng_uint16       *iBlue,
-                                                      mng_uint32       *iRawlen,
-                                                      mng_uint8arr     *aRawdata);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_gama       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_bool         *bEmpty,
-                                                      mng_uint32       *iGamma);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_chrm       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_bool         *bEmpty,
-                                                      mng_uint32       *iWhitepointx,
-                                                      mng_uint32       *iWhitepointy,
-                                                      mng_uint32       *iRedx,
-                                                      mng_uint32       *iRedy,
-                                                      mng_uint32       *iGreenx,
-                                                      mng_uint32       *iGreeny,
-                                                      mng_uint32       *iBluex,
-                                                      mng_uint32       *iBluey);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_srgb       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_bool         *bEmpty,
-                                                      mng_uint8        *iRenderingintent);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_iccp       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_bool         *bEmpty,
-                                                      mng_uint32       *iNamesize,
-                                                      mng_pchar        *zName,
-                                                      mng_uint8        *iCompression,
-                                                      mng_uint32       *iProfilesize,
-                                                      mng_ptr          *pProfile);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_text       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_uint32       *iKeywordsize,
-                                                      mng_pchar        *zKeyword,
-                                                      mng_uint32       *iTextsize,
-                                                      mng_pchar        *zText);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_ztxt       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_uint32       *iKeywordsize,
-                                                      mng_pchar        *zKeyword,
-                                                      mng_uint8        *iCompression,
-                                                      mng_uint32       *iTextsize,
-                                                      mng_pchar        *zText);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_itxt       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_uint32       *iKeywordsize,
-                                                      mng_pchar        *zKeyword,
-                                                      mng_uint8        *iCompressionflag,
-                                                      mng_uint8        *iCompressionmethod,
-                                                      mng_uint32       *iLanguagesize,
-                                                      mng_pchar        *zLanguage,
-                                                      mng_uint32       *iTranslationsize,
-                                                      mng_pchar        *zTranslation,
-                                                      mng_uint32       *iTextsize,
-                                                      mng_pchar        *zText);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_bkgd       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_bool         *bEmpty,
-                                                      mng_uint8        *iType,
-                                                      mng_uint8        *iIndex,
-                                                      mng_uint16       *iGray,
-                                                      mng_uint16       *iRed,
-                                                      mng_uint16       *iGreen,
-                                                      mng_uint16       *iBlue);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_phys       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_bool         *bEmpty,
-                                                      mng_uint32       *iSizex,
-                                                      mng_uint32       *iSizey,
-                                                      mng_uint8        *iUnit);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_sbit       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_bool         *bEmpty,
-                                                      mng_uint8        *iType,
-                                                      mng_uint8arr4    *aBits);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_splt       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_bool         *bEmpty,
-                                                      mng_uint32       *iNamesize,
-                                                      mng_pchar        *zName,
-                                                      mng_uint8        *iSampledepth,
-                                                      mng_uint32       *iEntrycount,
-                                                      mng_ptr          *pEntries);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_hist       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_uint32       *iEntrycount,
-                                                      mng_uint16arr    *aEntries);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_time       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_uint16       *iYear,
-                                                      mng_uint8        *iMonth,
-                                                      mng_uint8        *iDay,
-                                                      mng_uint8        *iHour,
-                                                      mng_uint8        *iMinute,
-                                                      mng_uint8        *iSecond);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_mhdr       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_uint32       *iWidth,
-                                                      mng_uint32       *iHeight,
-                                                      mng_uint32       *iTicks,
-                                                      mng_uint32       *iLayercount,
-                                                      mng_uint32       *iFramecount,
-                                                      mng_uint32       *iPlaytime,
-                                                      mng_uint32       *iSimplicity);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_loop       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_uint8        *iLevel,
-                                                      mng_uint32       *iRepeat,
-                                                      mng_uint8        *iTermination,
-                                                      mng_uint32       *iItermin,
-                                                      mng_uint32       *iItermax,
-                                                      mng_uint32       *iCount,
-                                                      mng_uint32p      *pSignals);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_endl       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_uint8        *iLevel);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_defi       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_uint16       *iObjectid,
-                                                      mng_uint8        *iDonotshow,
-                                                      mng_uint8        *iConcrete,
-                                                      mng_bool         *bHasloca,
-                                                      mng_int32        *iXlocation,
-                                                      mng_int32        *iYlocation,
-                                                      mng_bool         *bHasclip,
-                                                      mng_int32        *iLeftcb,
-                                                      mng_int32        *iRightcb,
-                                                      mng_int32        *iTopcb,
-                                                      mng_int32        *iBottomcb);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_basi       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_uint32       *iWidth,
-                                                      mng_uint32       *iHeight,
-                                                      mng_uint8        *iBitdepth,
-                                                      mng_uint8        *iColortype,
-                                                      mng_uint8        *iCompression,
-                                                      mng_uint8        *iFilter,
-                                                      mng_uint8        *iInterlace,
-                                                      mng_uint16       *iRed,
-                                                      mng_uint16       *iGreen,
-                                                      mng_uint16       *iBlue,
-                                                      mng_uint16       *iAlpha,
-                                                      mng_uint8        *iViewable);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_clon       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_uint16       *iSourceid,
-                                                      mng_uint16       *iCloneid,
-                                                      mng_uint8        *iClonetype,
-                                                      mng_uint8        *iDonotshow,
-                                                      mng_uint8        *iConcrete,
-                                                      mng_bool         *bHasloca,
-                                                      mng_uint8        *iLocationtype,
-                                                      mng_int32        *iLocationx,
-                                                      mng_int32        *iLocationy);
-
-#ifndef MNG_SKIPCHUNK_PAST
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_past       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_uint16       *iDestid,
-                                                      mng_uint8        *iTargettype,
-                                                      mng_int32        *iTargetx,
-                                                      mng_int32        *iTargety,
-                                                      mng_uint32       *iCount);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_past_src   (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_uint32       iEntry,
-                                                      mng_uint16       *iSourceid,
-                                                      mng_uint8        *iComposition,
-                                                      mng_uint8        *iOrientation,
-                                                      mng_uint8        *iOffsettype,
-                                                      mng_int32        *iOffsetx,
-                                                      mng_int32        *iOffsety,
-                                                      mng_uint8        *iBoundarytype,
-                                                      mng_int32        *iBoundaryl,
-                                                      mng_int32        *iBoundaryr,
-                                                      mng_int32        *iBoundaryt,
-                                                      mng_int32        *iBoundaryb);
-#endif
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_disc       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_uint32       *iCount,
-                                                      mng_uint16p      *pObjectids);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_back       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_uint16       *iRed,
-                                                      mng_uint16       *iGreen,
-                                                      mng_uint16       *iBlue,
-                                                      mng_uint8        *iMandatory,
-                                                      mng_uint16       *iImageid,
-                                                      mng_uint8        *iTile);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_fram       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_bool         *bEmpty,
-                                                      mng_uint8        *iMode,
-                                                      mng_uint32       *iNamesize,
-                                                      mng_pchar        *zName,
-                                                      mng_uint8        *iChangedelay,
-                                                      mng_uint8        *iChangetimeout,
-                                                      mng_uint8        *iChangeclipping,
-                                                      mng_uint8        *iChangesyncid,
-                                                      mng_uint32       *iDelay,
-                                                      mng_uint32       *iTimeout,
-                                                      mng_uint8        *iBoundarytype,
-                                                      mng_int32        *iBoundaryl,
-                                                      mng_int32        *iBoundaryr,
-                                                      mng_int32        *iBoundaryt,
-                                                      mng_int32        *iBoundaryb,
-                                                      mng_uint32       *iCount,
-                                                      mng_uint32p      *pSyncids);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_move       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_uint16       *iFirstid,
-                                                      mng_uint16       *iLastid,
-                                                      mng_uint8        *iMovetype,
-                                                      mng_int32        *iMovex,
-                                                      mng_int32        *iMovey);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_clip       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_uint16       *iFirstid,
-                                                      mng_uint16       *iLastid,
-                                                      mng_uint8        *iCliptype,
-                                                      mng_int32        *iClipl,
-                                                      mng_int32        *iClipr,
-                                                      mng_int32        *iClipt,
-                                                      mng_int32        *iClipb);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_show       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_bool         *bEmpty,
-                                                      mng_uint16       *iFirstid,
-                                                      mng_uint16       *iLastid,
-                                                      mng_uint8        *iMode);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_term       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_uint8        *iTermaction,
-                                                      mng_uint8        *iIteraction,
-                                                      mng_uint32       *iDelay,
-                                                      mng_uint32       *iItermax);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_save       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_bool         *bEmpty,
-                                                      mng_uint8        *iOffsettype,
-                                                      mng_uint32       *iCount);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_save_entry (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_uint32       iEntry,
-                                                      mng_uint8        *iEntrytype,
-                                                      mng_uint32arr2   *iOffset,
-                                                      mng_uint32arr2   *iStarttime,
-                                                      mng_uint32       *iLayernr,
-                                                      mng_uint32       *iFramenr,
-                                                      mng_uint32       *iNamesize,
-                                                      mng_pchar        *zName);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_seek       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_uint32       *iNamesize,
-                                                      mng_pchar        *zName);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_expi       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_uint16       *iSnapshotid,
-                                                      mng_uint32       *iNamesize,
-                                                      mng_pchar        *zName);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_fpri       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_uint8        *iDeltatype,
-                                                      mng_uint8        *iPriority);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_need       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_uint32       *iKeywordssize,
-                                                      mng_pchar        *zKeywords);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_phyg       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_bool         *bEmpty,
-                                                      mng_uint32       *iSizex,
-                                                      mng_uint32       *iSizey,
-                                                      mng_uint8        *iUnit);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_jhdr       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_uint32       *iWidth,
-                                                      mng_uint32       *iHeight,
-                                                      mng_uint8        *iColortype,
-                                                      mng_uint8        *iImagesampledepth,
-                                                      mng_uint8        *iImagecompression,
-                                                      mng_uint8        *iImageinterlace,
-                                                      mng_uint8        *iAlphasampledepth,
-                                                      mng_uint8        *iAlphacompression,
-                                                      mng_uint8        *iAlphafilter,
-                                                      mng_uint8        *iAlphainterlace);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_jdat       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_uint32       *iRawlen,
-                                                      mng_ptr          *pRawdata);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_jdaa       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_uint32       *iRawlen,
-                                                      mng_ptr          *pRawdata);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_dhdr       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_uint16       *iObjectid,
-                                                      mng_uint8        *iImagetype,
-                                                      mng_uint8        *iDeltatype,
-                                                      mng_uint32       *iBlockwidth,
-                                                      mng_uint32       *iBlockheight,
-                                                      mng_uint32       *iBlockx,
-                                                      mng_uint32       *iBlocky);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_prom       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_uint8        *iColortype,
-                                                      mng_uint8        *iSampledepth,
-                                                      mng_uint8        *iFilltype);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_pplt       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_uint8        *iDeltatype,
-                                                      mng_uint32       *iCount);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_pplt_entry (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_uint32       iEntry,
-                                                      mng_uint16       *iRed,
-                                                      mng_uint16       *iGreen,
-                                                      mng_uint16       *iBlue,
-                                                      mng_uint16       *iAlpha,
-                                                      mng_bool         *bUsed);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_drop       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_uint32       *iCount,
-                                                      mng_chunkidp     *pChunknames);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_dbyk       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_chunkid      *iChunkname,
-                                                      mng_uint8        *iPolarity,
-                                                      mng_uint32       *iKeywordssize,
-                                                      mng_pchar        *zKeywords);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_ordr       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_uint32       *iCount);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_ordr_entry (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_uint32       iEntry,
-                                                      mng_chunkid      *iChunkname,
-                                                      mng_uint8        *iOrdertype);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_magn       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_uint16       *iFirstid,
-                                                      mng_uint16       *iLastid,
-                                                      mng_uint16       *iMethodX,
-                                                      mng_uint16       *iMX,
-                                                      mng_uint16       *iMY,
-                                                      mng_uint16       *iML,
-                                                      mng_uint16       *iMR,
-                                                      mng_uint16       *iMT,
-                                                      mng_uint16       *iMB,
-                                                      mng_uint16       *iMethodY);
-
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_mpng       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_uint32       *iFramewidth,
-                                                      mng_uint32       *iFrameheight,
-                                                      mng_uint16       *iNumplays,
-                                                      mng_uint16       *iTickspersec,
-                                                      mng_uint8        *iCompressionmethod,
-                                                      mng_uint32       *iCount);
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_mpng_frame (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_uint32       iEntry,
-                                                      mng_uint32       *iX,
-                                                      mng_uint32       *iY,
-                                                      mng_uint32       *iWidth,
-                                                      mng_uint32       *iHeight,
-                                                      mng_int32        *iXoffset,
-                                                      mng_int32        *iYoffset,
-                                                      mng_uint16       *iTicks);
-#endif
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_evnt       (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_uint32       *iCount);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_evnt_entry (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_uint32       iEntry,
-                                                      mng_uint8        *iEventtype,
-                                                      mng_uint8        *iMasktype,
-                                                      mng_int32        *iLeft,
-                                                      mng_int32        *iRight,
-                                                      mng_int32        *iTop,
-                                                      mng_int32        *iBottom,
-                                                      mng_uint16       *iObjectid,
-                                                      mng_uint8        *iIndex,
-                                                      mng_uint32       *iSegmentnamesize,
-                                                      mng_pchar        *zSegmentname);
-
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_unknown    (mng_handle       hHandle,
-                                                      mng_handle       hChunk,
-                                                      mng_chunkid      *iChunkname,
-                                                      mng_uint32       *iRawlen,
-                                                      mng_ptr          *pRawdata);
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_WRITE_PROCS
-
-/* use these to create new chunks at the end of the chunk-list */
-/* requires at least MNG_ACCESS_CHUNKS (MNG_SUPPORT_WRITE may be nice too) */
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_ihdr       (mng_handle       hHandle,
-                                                      mng_uint32       iWidth,
-                                                      mng_uint32       iHeight,
-                                                      mng_uint8        iBitdepth,
-                                                      mng_uint8        iColortype,
-                                                      mng_uint8        iCompression,
-                                                      mng_uint8        iFilter,
-                                                      mng_uint8        iInterlace);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_plte       (mng_handle       hHandle,
-                                                      mng_uint32       iCount,
-                                                      mng_palette8     aPalette);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_idat       (mng_handle       hHandle,
-                                                      mng_uint32       iRawlen,
-                                                      mng_ptr          pRawdata);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_iend       (mng_handle       hHandle);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_trns       (mng_handle       hHandle,
-                                                      mng_bool         bEmpty,
-                                                      mng_bool         bGlobal,
-                                                      mng_uint8        iType,
-                                                      mng_uint32       iCount,
-                                                      mng_uint8arr     aAlphas,
-                                                      mng_uint16       iGray,
-                                                      mng_uint16       iRed,
-                                                      mng_uint16       iGreen,
-                                                      mng_uint16       iBlue,
-                                                      mng_uint32       iRawlen,
-                                                      mng_uint8arr     aRawdata);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_gama       (mng_handle       hHandle,
-                                                      mng_bool         bEmpty,
-                                                      mng_uint32       iGamma);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_chrm       (mng_handle       hHandle,
-                                                      mng_bool         bEmpty,
-                                                      mng_uint32       iWhitepointx,
-                                                      mng_uint32       iWhitepointy,
-                                                      mng_uint32       iRedx,
-                                                      mng_uint32       iRedy,
-                                                      mng_uint32       iGreenx,
-                                                      mng_uint32       iGreeny,
-                                                      mng_uint32       iBluex,
-                                                      mng_uint32       iBluey);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_srgb       (mng_handle       hHandle,
-                                                      mng_bool         bEmpty,
-                                                      mng_uint8        iRenderingintent);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_iccp       (mng_handle       hHandle,
-                                                      mng_bool         bEmpty,
-                                                      mng_uint32       iNamesize,
-                                                      mng_pchar        zName,
-                                                      mng_uint8        iCompression,
-                                                      mng_uint32       iProfilesize,
-                                                      mng_ptr          pProfile);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_text       (mng_handle       hHandle,
-                                                      mng_uint32       iKeywordsize,
-                                                      mng_pchar        zKeyword,
-                                                      mng_uint32       iTextsize,
-                                                      mng_pchar        zText);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_ztxt       (mng_handle       hHandle,
-                                                      mng_uint32       iKeywordsize,
-                                                      mng_pchar        zKeyword,
-                                                      mng_uint8        iCompression,
-                                                      mng_uint32       iTextsize,
-                                                      mng_pchar        zText);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_itxt       (mng_handle       hHandle,
-                                                      mng_uint32       iKeywordsize,
-                                                      mng_pchar        zKeyword,
-                                                      mng_uint8        iCompressionflag,
-                                                      mng_uint8        iCompressionmethod,
-                                                      mng_uint32       iLanguagesize,
-                                                      mng_pchar        zLanguage,
-                                                      mng_uint32       iTranslationsize,
-                                                      mng_pchar        zTranslation,
-                                                      mng_uint32       iTextsize,
-                                                      mng_pchar        zText);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_bkgd       (mng_handle       hHandle,
-                                                      mng_bool         bEmpty,
-                                                      mng_uint8        iType,
-                                                      mng_uint8        iIndex,
-                                                      mng_uint16       iGray,
-                                                      mng_uint16       iRed,
-                                                      mng_uint16       iGreen,
-                                                      mng_uint16       iBlue);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_phys       (mng_handle       hHandle,
-                                                      mng_bool         bEmpty,
-                                                      mng_uint32       iSizex,
-                                                      mng_uint32       iSizey,
-                                                      mng_uint8        iUnit);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_sbit       (mng_handle       hHandle,
-                                                      mng_bool         bEmpty,
-                                                      mng_uint8        iType,
-                                                      mng_uint8arr4    aBits);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_splt       (mng_handle       hHandle,
-                                                      mng_bool         bEmpty,
-                                                      mng_uint32       iNamesize,
-                                                      mng_pchar        zName,
-                                                      mng_uint8        iSampledepth,
-                                                      mng_uint32       iEntrycount,
-                                                      mng_ptr          pEntries);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_hist       (mng_handle       hHandle,
-                                                      mng_uint32       iEntrycount,
-                                                      mng_uint16arr    aEntries);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_time       (mng_handle       hHandle,
-                                                      mng_uint16       iYear,
-                                                      mng_uint8        iMonth,
-                                                      mng_uint8        iDay,
-                                                      mng_uint8        iHour,
-                                                      mng_uint8        iMinute,
-                                                      mng_uint8        iSecond);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_mhdr       (mng_handle       hHandle,
-                                                      mng_uint32       iWidth,
-                                                      mng_uint32       iHeight,
-                                                      mng_uint32       iTicks,
-                                                      mng_uint32       iLayercount,
-                                                      mng_uint32       iFramecount,
-                                                      mng_uint32       iPlaytime,
-                                                      mng_uint32       iSimplicity);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_mend       (mng_handle       hHandle);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_loop       (mng_handle       hHandle,
-                                                      mng_uint8        iLevel,
-                                                      mng_uint32       iRepeat,
-                                                      mng_uint8        iTermination,
-                                                      mng_uint32       iItermin,
-                                                      mng_uint32       iItermax,
-                                                      mng_uint32       iCount,
-                                                      mng_uint32p      pSignals);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_endl       (mng_handle       hHandle,
-                                                      mng_uint8        iLevel);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_defi       (mng_handle       hHandle,
-                                                      mng_uint16       iObjectid,
-                                                      mng_uint8        iDonotshow,
-                                                      mng_uint8        iConcrete,
-                                                      mng_bool         bHasloca,
-                                                      mng_int32        iXlocation,
-                                                      mng_int32        iYlocation,
-                                                      mng_bool         bHasclip,
-                                                      mng_int32        iLeftcb,
-                                                      mng_int32        iRightcb,
-                                                      mng_int32        iTopcb,
-                                                      mng_int32        iBottomcb);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_basi       (mng_handle       hHandle,
-                                                      mng_uint32       iWidth,
-                                                      mng_uint32       iHeight,
-                                                      mng_uint8        iBitdepth,
-                                                      mng_uint8        iColortype,
-                                                      mng_uint8        iCompression,
-                                                      mng_uint8        iFilter,
-                                                      mng_uint8        iInterlace,
-                                                      mng_uint16       iRed,
-                                                      mng_uint16       iGreen,
-                                                      mng_uint16       iBlue,
-                                                      mng_uint16       iAlpha,
-                                                      mng_uint8        iViewable);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_clon       (mng_handle       hHandle,
-                                                      mng_uint16       iSourceid,
-                                                      mng_uint16       iCloneid,
-                                                      mng_uint8        iClonetype,
-                                                      mng_uint8        iDonotshow,
-                                                      mng_uint8        iConcrete,
-                                                      mng_bool         bHasloca,
-                                                      mng_uint8        iLocationtype,
-                                                      mng_int32        iLocationx,
-                                                      mng_int32        iLocationy);
-
-#ifndef MNG_SKIPCHUNK_PAST
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_past       (mng_handle       hHandle,
-                                                      mng_uint16       iDestid,
-                                                      mng_uint8        iTargettype,
-                                                      mng_int32        iTargetx,
-                                                      mng_int32        iTargety,
-                                                      mng_uint32       iCount);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_past_src   (mng_handle       hHandle,
-                                                      mng_uint32       iEntry,
-                                                      mng_uint16       iSourceid,
-                                                      mng_uint8        iComposition,
-                                                      mng_uint8        iOrientation,
-                                                      mng_uint8        iOffsettype,
-                                                      mng_int32        iOffsetx,
-                                                      mng_int32        iOffsety,
-                                                      mng_uint8        iBoundarytype,
-                                                      mng_int32        iBoundaryl,
-                                                      mng_int32        iBoundaryr,
-                                                      mng_int32        iBoundaryt,
-                                                      mng_int32        iBoundaryb);
-#endif
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_disc       (mng_handle       hHandle,
-                                                      mng_uint32       iCount,
-                                                      mng_uint16p      pObjectids);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_back       (mng_handle       hHandle,
-                                                      mng_uint16       iRed,
-                                                      mng_uint16       iGreen,
-                                                      mng_uint16       iBlue,
-                                                      mng_uint8        iMandatory,
-                                                      mng_uint16       iImageid,
-                                                      mng_uint8        iTile);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_fram       (mng_handle       hHandle,
-                                                      mng_bool         bEmpty,
-                                                      mng_uint8        iMode,
-                                                      mng_uint32       iNamesize,
-                                                      mng_pchar        zName,
-                                                      mng_uint8        iChangedelay,
-                                                      mng_uint8        iChangetimeout,
-                                                      mng_uint8        iChangeclipping,
-                                                      mng_uint8        iChangesyncid,
-                                                      mng_uint32       iDelay,
-                                                      mng_uint32       iTimeout,
-                                                      mng_uint8        iBoundarytype,
-                                                      mng_int32        iBoundaryl,
-                                                      mng_int32        iBoundaryr,
-                                                      mng_int32        iBoundaryt,
-                                                      mng_int32        iBoundaryb,
-                                                      mng_uint32       iCount,
-                                                      mng_uint32p      pSyncids);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_move       (mng_handle       hHandle,
-                                                      mng_uint16       iFirstid,
-                                                      mng_uint16       iLastid,
-                                                      mng_uint8        iMovetype,
-                                                      mng_int32        iMovex,
-                                                      mng_int32        iMovey);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_clip       (mng_handle       hHandle,
-                                                      mng_uint16       iFirstid,
-                                                      mng_uint16       iLastid,
-                                                      mng_uint8        iCliptype,
-                                                      mng_int32        iClipl,
-                                                      mng_int32        iClipr,
-                                                      mng_int32        iClipt,
-                                                      mng_int32        iClipb);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_show       (mng_handle       hHandle,
-                                                      mng_bool         bEmpty,
-                                                      mng_uint16       iFirstid,
-                                                      mng_uint16       iLastid,
-                                                      mng_uint8        iMode);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_term       (mng_handle       hHandle,
-                                                      mng_uint8        iTermaction,
-                                                      mng_uint8        iIteraction,
-                                                      mng_uint32       iDelay,
-                                                      mng_uint32       iItermax);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_save       (mng_handle       hHandle,
-                                                      mng_bool         bEmpty,
-                                                      mng_uint8        iOffsettype,
-                                                      mng_uint32       iCount);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_save_entry (mng_handle       hHandle,
-                                                      mng_uint32       iEntry,
-                                                      mng_uint8        iEntrytype,
-                                                      mng_uint32arr2   iOffset,
-                                                      mng_uint32arr2   iStarttime,
-                                                      mng_uint32       iLayernr,
-                                                      mng_uint32       iFramenr,
-                                                      mng_uint32       iNamesize,
-                                                      mng_pchar        zName);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_seek       (mng_handle       hHandle,
-                                                      mng_uint32       iNamesize,
-                                                      mng_pchar        zName);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_expi       (mng_handle       hHandle,
-                                                      mng_uint16       iSnapshotid,
-                                                      mng_uint32       iNamesize,
-                                                      mng_pchar        zName);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_fpri       (mng_handle       hHandle,
-                                                      mng_uint8        iDeltatype,
-                                                      mng_uint8        iPriority);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_need       (mng_handle       hHandle,
-                                                      mng_uint32       iKeywordssize,
-                                                      mng_pchar        zKeywords);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_phyg       (mng_handle       hHandle,
-                                                      mng_bool         bEmpty,
-                                                      mng_uint32       iSizex,
-                                                      mng_uint32       iSizey,
-                                                      mng_uint8        iUnit);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_jhdr       (mng_handle       hHandle,
-                                                      mng_uint32       iWidth,
-                                                      mng_uint32       iHeight,
-                                                      mng_uint8        iColortype,
-                                                      mng_uint8        iImagesampledepth,
-                                                      mng_uint8        iImagecompression,
-                                                      mng_uint8        iImageinterlace,
-                                                      mng_uint8        iAlphasampledepth,
-                                                      mng_uint8        iAlphacompression,
-                                                      mng_uint8        iAlphafilter,
-                                                      mng_uint8        iAlphainterlace);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_jdat       (mng_handle       hHandle,
-                                                      mng_uint32       iRawlen,
-                                                      mng_ptr          pRawdata);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_jdaa       (mng_handle       hHandle,
-                                                      mng_uint32       iRawlen,
-                                                      mng_ptr          pRawdata);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_jsep       (mng_handle       hHandle);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_dhdr       (mng_handle       hHandle,
-                                                      mng_uint16       iObjectid,
-                                                      mng_uint8        iImagetype,
-                                                      mng_uint8        iDeltatype,
-                                                      mng_uint32       iBlockwidth,
-                                                      mng_uint32       iBlockheight,
-                                                      mng_uint32       iBlockx,
-                                                      mng_uint32       iBlocky);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_prom       (mng_handle       hHandle,
-                                                      mng_uint8        iColortype,
-                                                      mng_uint8        iSampledepth,
-                                                      mng_uint8        iFilltype);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_ipng       (mng_handle       hHandle);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_pplt       (mng_handle       hHandle,
-                                                      mng_uint8        iDeltatype,
-                                                      mng_uint32       iCount);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_pplt_entry (mng_handle       hHandle,
-                                                      mng_uint32       iEntry,
-                                                      mng_uint16       iRed,
-                                                      mng_uint16       iGreen,
-                                                      mng_uint16       iBlue,
-                                                      mng_uint16       iAlpha);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_jpng       (mng_handle       hHandle);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_drop       (mng_handle       hHandle,
-                                                      mng_uint32       iCount,
-                                                      mng_chunkidp     pChunknames);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_dbyk       (mng_handle       hHandle,
-                                                      mng_chunkid      iChunkname,
-                                                      mng_uint8        iPolarity,
-                                                      mng_uint32       iKeywordssize,
-                                                      mng_pchar        zKeywords);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_ordr       (mng_handle       hHandle,
-                                                      mng_uint32       iCount);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_ordr_entry (mng_handle       hHandle,
-                                                      mng_uint32       iEntry,
-                                                      mng_chunkid      iChunkname,
-                                                      mng_uint8        iOrdertype);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_magn       (mng_handle       hHandle,
-                                                      mng_uint16       iFirstid,
-                                                      mng_uint16       iLastid,
-                                                      mng_uint16       iMethodX,
-                                                      mng_uint16       iMX,
-                                                      mng_uint16       iMY,
-                                                      mng_uint16       iML,
-                                                      mng_uint16       iMR,
-                                                      mng_uint16       iMT,
-                                                      mng_uint16       iMB,
-                                                      mng_uint16       iMethodY);
-
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_mpng       (mng_handle       hHandle,
-                                                      mng_uint32       iFramewidth,
-                                                      mng_uint32       iFrameheight,
-                                                      mng_uint16       iNumplays,
-                                                      mng_uint16       iTickspersec,
-                                                      mng_uint8        iCompressionmethod,
-                                                      mng_uint32       iCount);
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_mpng_frame (mng_handle       hHandle,
-                                                      mng_uint32       iEntry,
-                                                      mng_uint32       iX,
-                                                      mng_uint32       iY,
-                                                      mng_uint32       iWidth,
-                                                      mng_uint32       iHeight,
-                                                      mng_int32        iXoffset,
-                                                      mng_int32        iYoffset,
-                                                      mng_uint16       iTicks);
-#endif
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_evnt       (mng_handle       hHandle,
-                                                      mng_uint32       iCount);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_evnt_entry (mng_handle       hHandle,
-                                                      mng_uint32       iEntry,
-                                                      mng_uint8        iEventtype,
-                                                      mng_uint8        iMasktype,
-                                                      mng_int32        iLeft,
-                                                      mng_int32        iRight,
-                                                      mng_int32        iTop,
-                                                      mng_int32        iBottom,
-                                                      mng_uint16       iObjectid,
-                                                      mng_uint8        iIndex,
-                                                      mng_uint32       iSegmentnamesize,
-                                                      mng_pchar        zSegmentname);
-
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_unknown    (mng_handle       hHandle,
-                                                      mng_chunkid      iChunkname,
-                                                      mng_uint32       iRawlen,
-                                                      mng_ptr          pRawdata);
-
-#endif /* MNG_INCLUDE_WRITE_PROCS */
-
-/* ************************************************************************** */
-
-/* use these functions to access the actual image-data in stored chunks,
-   as opposed to the IDAT/JDAT data */
-/* to get accurate pixel-data the canvasstyle should seriously reflect the
-   bitdepth/colortype combination of the preceding IHDR/JHDR/BASI/DHDR;
-   all input can be converted to rgb(a)8 (rgb(a)16 for 16-bit images), but
-   there are only limited conversions back (see below for putimgdata)  */
-
-/* call this function if you want to extract the nth image from the list;
-   the first image is designated seqnr 0! */
-/* this function finds the IHDR/JHDR/BASI/DHDR with the appropriate seqnr,
-   starting from the beginning of the chunk-list; this may tend to get a little
-   slow for animations with a large number of chunks for images near the end */
-/* supplying a seqnr past the last image in the animation will return with
-   an errorcode */   
-MNG_EXT mng_retcode MNG_DECL mng_getimgdata_seq      (mng_handle        hHandle,
-                                                      mng_uint32        iSeqnr,
-                                                      mng_uint32        iCanvasstyle,
-                                                      mng_getcanvasline fGetcanvasline);
-
-/* both the following functions will search forward to find the first IDAT/JDAT,
-   and then traverse back to find the start of the image (IHDR,JHDR,DHDR,BASI);
-   note that this is very fast compared to decoding the IDAT/JDAT, so there's
-   not really a need for optimization; either can be called from the
-   iterate_chunks callback when a IHDR/JHDR is encountered; for BASI/DHDR there
-   may not be real image-data so it's wisest to keep iterating till the IEND,
-   and then call either of these functions if necessary (remember the correct seqnr!) */
-
-/* call this function if you want to extract the image starting at or after the nth
-   position in the chunk-list; this number is returned in the iterate_chunks callback */
-MNG_EXT mng_retcode MNG_DECL mng_getimgdata_chunkseq (mng_handle        hHandle,
-                                                      mng_uint32        iSeqnr,
-                                                      mng_uint32        iCanvasstyle,
-                                                      mng_getcanvasline fGetcanvasline);
-
-/* call this function if you want to extract the image starting at or after the
-   indicated chunk; the handle of a chunk is returned in the iterate_chunks callback */
-MNG_EXT mng_retcode MNG_DECL mng_getimgdata_chunk    (mng_handle        hHandle,
-                                                      mng_handle        hChunk,
-                                                      mng_uint32        iCanvasstyle,
-                                                      mng_getcanvasline fGetcanvasline);
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_WRITE_PROCS
-
-/* use the following functions to add image-data to the list of stored chunks */
-/* note that this only adds the IDAT or JDAT chunks and no others; you must call
-   one of these functions after you 'put' the initial chunks of the image and
-   before you 'put' the closing chunks */
-/* the canvasstyle should seriously reflect the bitdepth/colortype combination;
-   eg. bitdepth=16 would expect a 16-bit canvasstyle,
-   colortype=g or ga would expect a gray or gray+alpha style respectively
-   and so on, and so forth ...
-   (nb. the number of conversions will be extremely limited for the moment!) */
-
-MNG_EXT mng_retcode MNG_DECL mng_putimgdata_ihdr     (mng_handle        hHandle,
-                                                      mng_uint32        iWidth,
-                                                      mng_uint32        iHeight,
-                                                      mng_uint8         iColortype,
-                                                      mng_uint8         iBitdepth,
-                                                      mng_uint8         iCompression,
-                                                      mng_uint8         iFilter,
-                                                      mng_uint8         iInterlace,
-                                                      mng_uint32        iCanvasstyle,
-                                                      mng_getcanvasline fGetcanvasline);
-
-MNG_EXT mng_retcode MNG_DECL mng_putimgdata_jhdr     (mng_handle        hHandle,
-                                                      mng_uint32        iWidth,
-                                                      mng_uint32        iHeight,
-                                                      mng_uint8         iColortype,
-                                                      mng_uint8         iBitdepth,
-                                                      mng_uint8         iCompression,
-                                                      mng_uint8         iInterlace,
-                                                      mng_uint8         iAlphaBitdepth,
-                                                      mng_uint8         iAlphaCompression,
-                                                      mng_uint8         iAlphaFilter,
-                                                      mng_uint8         iAlphaInterlace,
-                                                      mng_uint32        iCanvasstyle,
-                                                      mng_getcanvasline fGetcanvasline);
-
-/* ************************************************************************** */
-
-/* use the following functions to set the framecount/layercount/playtime or
-   simplicity of an animation you are creating; this may be useful if these
-   variables are calculated during the creation-process */
-
-MNG_EXT mng_retcode MNG_DECL mng_updatemngheader     (mng_handle        hHandle,
-                                                      mng_uint32        iFramecount,
-                                                      mng_uint32        iLayercount,
-                                                      mng_uint32        iPlaytime);
-
-MNG_EXT mng_retcode MNG_DECL mng_updatemngsimplicity (mng_handle        hHandle,
-                                                      mng_uint32        iSimplicity);
-
-/* ************************************************************************** */
-
-#endif /* MNG_INCLUDE_WRITE_PROCS */
-
-#endif /* MNG_ACCESS_CHUNKS */
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Error-code structure                                                   * */
-/* *                                                                        * */
-/* * 0b0000 00xx xxxx xxxx - basic errors; severity 9 (environment)         * */
-/* * 0b0000 01xx xxxx xxxx - chunk errors; severity 9 (image induced)       * */
-/* * 0b0000 10xx xxxx xxxx - severity 5 errors (application induced)        * */
-/* * 0b0001 00xx xxxx xxxx - severity 2 warnings (recoverable)              * */
-/* * 0b0010 00xx xxxx xxxx - severity 1 warnings (recoverable)              * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#define MNG_NOERROR          (mng_retcode)0    /* er.. indicates all's well   */
-
-#define MNG_OUTOFMEMORY      (mng_retcode)1    /* oops, buy some megabytes!   */
-#define MNG_INVALIDHANDLE    (mng_retcode)2    /* call mng_initialize first   */
-#define MNG_NOCALLBACK       (mng_retcode)3    /* set the callbacks please    */
-#define MNG_UNEXPECTEDEOF    (mng_retcode)4    /* what'd ya do with the data? */
-#define MNG_ZLIBERROR        (mng_retcode)5    /* zlib burped                 */
-#define MNG_JPEGERROR        (mng_retcode)6    /* jpglib complained           */
-#define MNG_LCMSERROR        (mng_retcode)7    /* little cms stressed out     */
-#define MNG_NOOUTPUTPROFILE  (mng_retcode)8    /* no output-profile defined   */
-#define MNG_NOSRGBPROFILE    (mng_retcode)9    /* no sRGB-profile defined     */
-#define MNG_BUFOVERFLOW      (mng_retcode)10   /* zlib output-buffer overflow */
-#define MNG_FUNCTIONINVALID  (mng_retcode)11   /* ay, totally inappropriate   */
-#define MNG_OUTPUTERROR      (mng_retcode)12   /* disk full ?                 */
-#define MNG_JPEGBUFTOOSMALL  (mng_retcode)13   /* can't handle buffer overflow*/
-#define MNG_NEEDMOREDATA     (mng_retcode)14   /* I'm hungry, give me more    */
-#define MNG_NEEDTIMERWAIT    (mng_retcode)15   /* Sleep a while then wake me  */
-#define MNG_NEEDSECTIONWAIT  (mng_retcode)16   /* just processed a SEEK       */
-#define MNG_LOOPWITHCACHEOFF (mng_retcode)17   /* LOOP when playback info off */
-
-#define MNG_DLLNOTLOADED     (mng_retcode)99   /* late binding failed         */
-
-#define MNG_APPIOERROR       (mng_retcode)901  /* application I/O error       */
-#define MNG_APPTIMERERROR    (mng_retcode)902  /* application timing error    */
-#define MNG_APPCMSERROR      (mng_retcode)903  /* application CMS error       */
-#define MNG_APPMISCERROR     (mng_retcode)904  /* application other error     */
-#define MNG_APPTRACEABORT    (mng_retcode)905  /* application aborts on trace */
-
-#define MNG_INTERNALERROR    (mng_retcode)999  /* internal inconsistancy      */
-
-#define MNG_INVALIDSIG       (mng_retcode)1025 /* invalid graphics file       */
-#define MNG_INVALIDCRC       (mng_retcode)1027 /* crc check failed            */
-#define MNG_INVALIDLENGTH    (mng_retcode)1028 /* chunklength mystifies me    */
-#define MNG_SEQUENCEERROR    (mng_retcode)1029 /* invalid chunk sequence      */
-#define MNG_CHUNKNOTALLOWED  (mng_retcode)1030 /* completely out-of-place     */
-#define MNG_MULTIPLEERROR    (mng_retcode)1031 /* only one occurence allowed  */
-#define MNG_PLTEMISSING      (mng_retcode)1032 /* indexed-color requires PLTE */
-#define MNG_IDATMISSING      (mng_retcode)1033 /* IHDR-block requires IDAT    */
-#define MNG_CANNOTBEEMPTY    (mng_retcode)1034 /* must contain some data      */
-#define MNG_GLOBALLENGTHERR  (mng_retcode)1035 /* global data incorrect       */
-#define MNG_INVALIDBITDEPTH  (mng_retcode)1036 /* bitdepth out-of-range       */
-#define MNG_INVALIDCOLORTYPE (mng_retcode)1037 /* colortype out-of-range      */
-#define MNG_INVALIDCOMPRESS  (mng_retcode)1038 /* compression method invalid  */
-#define MNG_INVALIDFILTER    (mng_retcode)1039 /* filter method invalid       */
-#define MNG_INVALIDINTERLACE (mng_retcode)1040 /* interlace method invalid    */
-#define MNG_NOTENOUGHIDAT    (mng_retcode)1041 /* ran out of compressed data  */
-#define MNG_PLTEINDEXERROR   (mng_retcode)1042 /* palette-index out-of-range  */
-#define MNG_NULLNOTFOUND     (mng_retcode)1043 /* couldn't find null-separator*/
-#define MNG_KEYWORDNULL      (mng_retcode)1044 /* keyword cannot be empty     */
-#define MNG_OBJECTUNKNOWN    (mng_retcode)1045 /* the object can't be found   */
-#define MNG_OBJECTEXISTS     (mng_retcode)1046 /* the object already exists   */
-#define MNG_TOOMUCHIDAT      (mng_retcode)1047 /* got too much compressed data*/
-#define MNG_INVSAMPLEDEPTH   (mng_retcode)1048 /* sampledepth out-of-range    */
-#define MNG_INVOFFSETSIZE    (mng_retcode)1049 /* invalid offset-size         */
-#define MNG_INVENTRYTYPE     (mng_retcode)1050 /* invalid entry-type          */
-#define MNG_ENDWITHNULL      (mng_retcode)1051 /* may not end with NULL       */
-#define MNG_INVIMAGETYPE     (mng_retcode)1052 /* invalid image_type          */
-#define MNG_INVDELTATYPE     (mng_retcode)1053 /* invalid delta_type          */
-#define MNG_INVALIDINDEX     (mng_retcode)1054 /* index-value invalid         */
-#define MNG_TOOMUCHJDAT      (mng_retcode)1055 /* got too much compressed data*/
-#define MNG_JPEGPARMSERR     (mng_retcode)1056 /* JHDR/JPEG parms do not match*/
-#define MNG_INVFILLMETHOD    (mng_retcode)1057 /* invalid fill_method         */
-#define MNG_OBJNOTCONCRETE   (mng_retcode)1058 /* object must be concrete     */
-#define MNG_TARGETNOALPHA    (mng_retcode)1059 /* object has no alpha-channel */
-#define MNG_MNGTOOCOMPLEX    (mng_retcode)1060 /* can't handle complexity     */
-#define MNG_UNKNOWNCRITICAL  (mng_retcode)1061 /* unknown critical chunk found*/
-#define MNG_UNSUPPORTEDNEED  (mng_retcode)1062 /* nEED requirement unsupported*/
-#define MNG_INVALIDDELTA     (mng_retcode)1063 /* Delta operation illegal     */
-#define MNG_INVALIDMETHOD    (mng_retcode)1064 /* invalid MAGN method         */
-#define MNG_IMPROBABLELENGTH (mng_retcode)1065 /* impropable chunk length     */
-#define MNG_INVALIDBLOCK     (mng_retcode)1066 /* invalid delta block         */
-#define MNG_INVALIDEVENT     (mng_retcode)1067 /* invalid event_type          */
-#define MNG_INVALIDMASK      (mng_retcode)1068 /* invalid mask_type           */
-#define MNG_NOMATCHINGLOOP   (mng_retcode)1069 /* ENDL without matching LOOP  */
-#define MNG_SEEKNOTFOUND     (mng_retcode)1070 /* EvNT points to unknown SEEK */
-#define MNG_OBJNOTABSTRACT   (mng_retcode)1071 /* object must be abstract     */
-#define MNG_TERMSEQERROR     (mng_retcode)1072 /* TERM in wrong place         */
-#define MNG_INVALIDFIELDVAL  (mng_retcode)1073 /* invalid fieldvalue (generic)*/
-#define MNG_INVALIDWIDTH     (mng_retcode)1074 /* invalid frame/image width   */
-#define MNG_INVALIDHEIGHT    (mng_retcode)1075 /* invalid frame/image height  */
-
-#define MNG_INVALIDCNVSTYLE  (mng_retcode)2049 /* can't make anything of this */
-#define MNG_WRONGCHUNK       (mng_retcode)2050 /* accessing the wrong chunk   */
-#define MNG_INVALIDENTRYIX   (mng_retcode)2051 /* accessing the wrong entry   */
-#define MNG_NOHEADER         (mng_retcode)2052 /* must have had header first  */
-#define MNG_NOCORRCHUNK      (mng_retcode)2053 /* can't find parent chunk     */
-#define MNG_NOMHDR           (mng_retcode)2054 /* no MNG header available     */
-
-#define MNG_IMAGETOOLARGE    (mng_retcode)4097 /* input-image way too big     */
-#define MNG_NOTANANIMATION   (mng_retcode)4098 /* file not a MNG              */
-#define MNG_FRAMENRTOOHIGH   (mng_retcode)4099 /* frame-nr out-of-range       */
-#define MNG_LAYERNRTOOHIGH   (mng_retcode)4100 /* layer-nr out-of-range       */
-#define MNG_PLAYTIMETOOHIGH  (mng_retcode)4101 /* playtime out-of-range       */
-#define MNG_FNNOTIMPLEMENTED (mng_retcode)4102 /* function not yet available  */
-
-#define MNG_IMAGEFROZEN      (mng_retcode)8193 /* stopped displaying          */
-
-#define MNG_LCMS_NOHANDLE    1                 /* LCMS returned NULL handle   */
-#define MNG_LCMS_NOMEM       2                 /* LCMS returned NULL gammatab */
-#define MNG_LCMS_NOTRANS     3                 /* LCMS returned NULL transform*/
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* *  Canvas styles                                                         * */
-/* *                                                                        * */
-/* *  Note that the intentions are pretty darn good, but that the focus     * */
-/* *  is currently on 8-bit color support                                   * */
-/* *                                                                        * */
-/* *  The RGB8_A8 style is defined for apps that require a separate         * */
-/* *  canvas for the color-planes and the alpha-plane (eg. mozilla)         * */
-/* *  This requires for the app to supply the "getalphaline" callback!!!    * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#define MNG_CANVAS_RGB8      0x00000000L
-#define MNG_CANVAS_RGBA8     0x00001000L
-#define MNG_CANVAS_RGBA8_PM  0x00009000L
-#define MNG_CANVAS_ARGB8     0x00003000L
-#define MNG_CANVAS_ARGB8_PM  0x0000B000L
-#define MNG_CANVAS_RGB8_A8   0x00005000L
-#define MNG_CANVAS_BGR8      0x00000001L
-#define MNG_CANVAS_BGRX8     0x00010001L
-#define MNG_CANVAS_BGRA8     0x00001001L
-#define MNG_CANVAS_BGRA8PM   0x00009001L         /* backward compatibility */
-#define MNG_CANVAS_BGRA8_PM  0x00009001L
-#define MNG_CANVAS_ABGR8     0x00003001L
-#define MNG_CANVAS_ABGR8_PM  0x0000B001L
-#define MNG_CANVAS_RGB16     0x00000100L         /* not supported yet */
-#define MNG_CANVAS_RGBA16    0x00001100L         /* not supported yet */
-#define MNG_CANVAS_ARGB16    0x00003100L         /* not supported yet */
-#define MNG_CANVAS_BGR16     0x00000101L         /* not supported yet */
-#define MNG_CANVAS_BGRA16    0x00001101L         /* not supported yet */
-#define MNG_CANVAS_ABGR16    0x00003101L         /* not supported yet */
-#define MNG_CANVAS_GRAY8     0x00000002L         /* not supported yet */
-#define MNG_CANVAS_GRAY16    0x00000102L         /* not supported yet */
-#define MNG_CANVAS_GRAYA8    0x00001002L         /* not supported yet */
-#define MNG_CANVAS_GRAYA16   0x00001102L         /* not supported yet */
-#define MNG_CANVAS_AGRAY8    0x00003002L         /* not supported yet */
-#define MNG_CANVAS_AGRAY16   0x00003102L         /* not supported yet */
-#define MNG_CANVAS_DX15      0x00000003L         /* not supported yet */
-#define MNG_CANVAS_DX16      0x00000004L         /* not supported yet */
-
-#define MNG_CANVAS_RGB565    0x00000005L
-#define MNG_CANVAS_RGBA565   0x00001005L
-#define MNG_CANVAS_BGR565    0x00000006L
-#define MNG_CANVAS_BGRA565   0x00001006L
-#define MNG_CANVAS_BGR565_A8 0x00004006L
-
-#define MNG_CANVAS_RGB555    0x00000007L
-#define MNG_CANVAS_BGR555    0x00000008L
-
-#define MNG_CANVAS_PIXELTYPE(C)  (C & 0x000000FFL)
-#define MNG_CANVAS_BITDEPTH(C)   (C & 0x00000100L)
-#define MNG_CANVAS_HASALPHA(C)   (C & 0x00001000L)
-#define MNG_CANVAS_ALPHAFIRST(C) (C & 0x00002000L)
-#define MNG_CANVAS_ALPHASEPD(C)  (C & 0x00004000L)
-#define MNG_CANVAS_ALPHAPM(C)    (C & 0x00008000L)
-#define MNG_CANVAS_HASFILLER(C)  (C & 0x00010000L)
-
-#define MNG_CANVAS_RGB(C)        (MNG_CANVAS_PIXELTYPE (C) == 0)
-#define MNG_CANVAS_BGR(C)        (MNG_CANVAS_PIXELTYPE (C) == 1)
-#define MNG_CANVAS_GRAY(C)       (MNG_CANVAS_PIXELTYPE (C) == 2)
-#define MNG_CANVAS_DIRECTX15(C)  (MNG_CANVAS_PIXELTYPE (C) == 3)
-#define MNG_CANVAS_DIRECTX16(C)  (MNG_CANVAS_PIXELTYPE (C) == 4)
-#define MNG_CANVAS_RGB_565(C)    (MNG_CANVAS_PIXELTYPE (C) == 5)
-#define MNG_CANVAS_BGR_565(C)    (MNG_CANVAS_PIXELTYPE (C) == 6)
-#define MNG_CANVAS_8BIT(C)       (!MNG_CANVAS_BITDEPTH (C))
-#define MNG_CANVAS_16BIT(C)      (MNG_CANVAS_BITDEPTH (C))
-#define MNG_CANVAS_PIXELFIRST(C) (!MNG_CANVAS_ALPHAFIRST (C))
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* *  Chunk names (idea adapted from libpng 1.1.0 - png.h)                  * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#define MNG_UINT_HUH  0x40404040L
-
-#define MNG_UINT_BACK 0x4241434bL
-#define MNG_UINT_BASI 0x42415349L
-#define MNG_UINT_CLIP 0x434c4950L
-#define MNG_UINT_CLON 0x434c4f4eL
-#define MNG_UINT_DBYK 0x4442594bL
-#define MNG_UINT_DEFI 0x44454649L
-#define MNG_UINT_DHDR 0x44484452L
-#define MNG_UINT_DISC 0x44495343L
-#define MNG_UINT_DROP 0x44524f50L
-#define MNG_UINT_ENDL 0x454e444cL
-#define MNG_UINT_FRAM 0x4652414dL
-#define MNG_UINT_IDAT 0x49444154L
-#define MNG_UINT_IEND 0x49454e44L
-#define MNG_UINT_IHDR 0x49484452L
-#define MNG_UINT_IJNG 0x494a4e47L
-#define MNG_UINT_IPNG 0x49504e47L
-#define MNG_UINT_JDAA 0x4a444141L
-#define MNG_UINT_JDAT 0x4a444154L
-#define MNG_UINT_JHDR 0x4a484452L
-#define MNG_UINT_JSEP 0x4a534550L
-#define MNG_UINT_JdAA 0x4a644141L
-#define MNG_UINT_LOOP 0x4c4f4f50L
-#define MNG_UINT_MAGN 0x4d41474eL
-#define MNG_UINT_MEND 0x4d454e44L
-#define MNG_UINT_MHDR 0x4d484452L
-#define MNG_UINT_MOVE 0x4d4f5645L
-#define MNG_UINT_ORDR 0x4f524452L
-#define MNG_UINT_PAST 0x50415354L
-#define MNG_UINT_PLTE 0x504c5445L
-#define MNG_UINT_PPLT 0x50504c54L
-#define MNG_UINT_PROM 0x50524f4dL
-#define MNG_UINT_SAVE 0x53415645L
-#define MNG_UINT_SEEK 0x5345454bL
-#define MNG_UINT_SHOW 0x53484f57L
-#define MNG_UINT_TERM 0x5445524dL
-#define MNG_UINT_adAT 0x61644154L
-#define MNG_UINT_ahDR 0x61684452L
-#define MNG_UINT_bKGD 0x624b4744L
-#define MNG_UINT_cHRM 0x6348524dL
-#define MNG_UINT_eXPI 0x65585049L
-#define MNG_UINT_evNT 0x65764e54L
-#define MNG_UINT_fPRI 0x66505249L
-#define MNG_UINT_gAMA 0x67414d41L
-#define MNG_UINT_hIST 0x68495354L
-#define MNG_UINT_iCCP 0x69434350L
-#define MNG_UINT_iTXt 0x69545874L
-#define MNG_UINT_mpNG 0x6d704e47L
-#define MNG_UINT_nEED 0x6e454544L
-#define MNG_UINT_oFFs 0x6f464673L
-#define MNG_UINT_pCAL 0x7043414cL
-#define MNG_UINT_pHYg 0x70444167L
-#define MNG_UINT_pHYs 0x70485973L
-#define MNG_UINT_sBIT 0x73424954L
-#define MNG_UINT_sCAL 0x7343414cL
-#define MNG_UINT_sPLT 0x73504c54L
-#define MNG_UINT_sRGB 0x73524742L
-#define MNG_UINT_tEXt 0x74455874L
-#define MNG_UINT_tIME 0x74494d45L
-#define MNG_UINT_tRNS 0x74524e53L
-#define MNG_UINT_zTXt 0x7a545874L
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* *  Chunk property values                                                 * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#define MNG_BITDEPTH_1                   1       /* IHDR, BASI, JHDR, PROM */
-#define MNG_BITDEPTH_2                   2
-#define MNG_BITDEPTH_4                   4
-#define MNG_BITDEPTH_8                   8       /* sPLT */
-#define MNG_BITDEPTH_16                 16
-
-#define MNG_COLORTYPE_GRAY               0       /* IHDR, BASI, PROM */
-#define MNG_COLORTYPE_RGB                2
-#define MNG_COLORTYPE_INDEXED            3
-#define MNG_COLORTYPE_GRAYA              4
-#define MNG_COLORTYPE_RGBA               6
-
-#define MNG_COMPRESSION_DEFLATE          0       /* IHDR, zTXt, iTXt, iCCP,
-                                                    BASI, JHDR */
-
-#define MNG_FILTER_ADAPTIVE              0       /* IHDR, BASI, JHDR */
-/* #define MNG_FILTER_NO_ADAPTIVE           1
-#define MNG_FILTER_NO_DIFFERING          0
-#define MNG_FILTER_DIFFERING             0x40
-#define MNG_FILTER_MASK                  (MNG_FILTER_NO_ADAPTIVE | MNG_FILTER_DIFFERING) */
-#ifdef FILTER192
-#define MNG_FILTER_DIFFERING             0xC0
-#endif
-#ifdef FILTER193
-#define MNG_FILTER_NOFILTER              0xC1
-#endif
-
-#define MNG_INTERLACE_NONE               0       /* IHDR, BASI, JHDR */
-#define MNG_INTERLACE_ADAM7              1
-
-#define MNG_FILTER_NONE                  0       /* IDAT */
-#define MNG_FILTER_SUB                   1
-#define MNG_FILTER_UP                    2
-#define MNG_FILTER_AVERAGE               3
-#define MNG_FILTER_PAETH                 4
-
-#define MNG_INTENT_PERCEPTUAL            0       /* sRGB */
-#define MNG_INTENT_RELATIVECOLORIMETRIC  1
-#define MNG_INTENT_SATURATION            2
-#define MNG_INTENT_ABSOLUTECOLORIMETRIC  3
-                                                 /* tEXt, zTXt, iTXt */
-#define MNG_TEXT_TITLE                   "Title"
-#define MNG_TEXT_AUTHOR                  "Author"
-#define MNG_TEXT_DESCRIPTION             "Description"
-#define MNG_TEXT_COPYRIGHT               "Copyright"
-#define MNG_TEXT_CREATIONTIME            "Creation Time"
-#define MNG_TEXT_SOFTWARE                "Software"
-#define MNG_TEXT_DISCLAIMER              "Disclaimer"
-#define MNG_TEXT_WARNING                 "Warning"
-#define MNG_TEXT_SOURCE                  "Source"
-#define MNG_TEXT_COMMENT                 "Comment"
-
-#define MNG_FLAG_UNCOMPRESSED            0       /* iTXt */
-#define MNG_FLAG_COMPRESSED              1
-
-#define MNG_UNIT_UNKNOWN                 0       /* pHYs, pHYg */
-#define MNG_UNIT_METER                   1
-                                                 /* MHDR */
-#define MNG_SIMPLICITY_VALID             0x00000001
-#define MNG_SIMPLICITY_SIMPLEFEATURES    0x00000002
-#define MNG_SIMPLICITY_COMPLEXFEATURES   0x00000004
-#define MNG_SIMPLICITY_TRANSPARENCY      0x00000008
-#define MNG_SIMPLICITY_JNG               0x00000010
-#define MNG_SIMPLICITY_DELTAPNG          0x00000020
-
-#define MNG_TERMINATION_DECODER_NC       0       /* LOOP */
-#define MNG_TERMINATION_USER_NC          1
-#define MNG_TERMINATION_EXTERNAL_NC      2
-#define MNG_TERMINATION_DETERMINISTIC_NC 3
-#define MNG_TERMINATION_DECODER_C        4
-#define MNG_TERMINATION_USER_C           5
-#define MNG_TERMINATION_EXTERNAL_C       6
-#define MNG_TERMINATION_DETERMINISTIC_C  7
-
-#define MNG_DONOTSHOW_VISIBLE            0       /* DEFI */
-#define MNG_DONOTSHOW_NOTVISIBLE         1
-
-#define MNG_ABSTRACT                     0       /* DEFI */
-#define MNG_CONCRETE                     1
-
-#define MNG_NOTVIEWABLE                  0       /* BASI */
-#define MNG_VIEWABLE                     1
-
-#define MNG_FULL_CLONE                   0       /* CLON */
-#define MNG_PARTIAL_CLONE                1
-#define MNG_RENUMBER                     2
-
-#define MNG_CONCRETE_ASPARENT            0       /* CLON */
-#define MNG_CONCRETE_MAKEABSTRACT        1
-
-#define MNG_LOCATION_ABSOLUTE            0       /* CLON, MOVE */
-#define MNG_LOCATION_RELATIVE            1
-
-#ifndef MNG_SKIPCHUNK_PAST
-#define MNG_TARGET_ABSOLUTE              0       /* PAST */
-#define MNG_TARGET_RELATIVE_SAMEPAST     1
-#define MNG_TARGET_RELATIVE_PREVPAST     2
-
-#define MNG_COMPOSITE_OVER               0       /* PAST */
-#define MNG_COMPOSITE_REPLACE            1
-#define MNG_COMPOSITE_UNDER              2
-
-#define MNG_ORIENTATION_SAME             0       /* PAST */
-#define MNG_ORIENTATION_180DEG           2
-#define MNG_ORIENTATION_FLIPHORZ         4
-#define MNG_ORIENTATION_FLIPVERT         6
-#define MNG_ORIENTATION_TILED            8
-
-#define MNG_OFFSET_ABSOLUTE              0       /* PAST */
-#define MNG_OFFSET_RELATIVE              1
-#endif
-
-#define MNG_BOUNDARY_ABSOLUTE            0       /* PAST, FRAM */
-#define MNG_BOUNDARY_RELATIVE            1
-
-#define MNG_BACKGROUNDCOLOR_MANDATORY    0x01    /* BACK */
-#define MNG_BACKGROUNDIMAGE_MANDATORY    0x02    /* BACK */
-
-#define MNG_BACKGROUNDIMAGE_NOTILE       0       /* BACK */
-#define MNG_BACKGROUNDIMAGE_TILE         1
-
-#define MNG_FRAMINGMODE_NOCHANGE         0       /* FRAM */
-#define MNG_FRAMINGMODE_1                1
-#define MNG_FRAMINGMODE_2                2
-#define MNG_FRAMINGMODE_3                3
-#define MNG_FRAMINGMODE_4                4
-
-#define MNG_CHANGEDELAY_NO               0       /* FRAM */
-#define MNG_CHANGEDELAY_NEXTSUBFRAME     1
-#define MNG_CHANGEDELAY_DEFAULT          2
-
-#define MNG_CHANGETIMOUT_NO              0       /* FRAM */
-#define MNG_CHANGETIMOUT_DETERMINISTIC_1 1
-#define MNG_CHANGETIMOUT_DETERMINISTIC_2 2
-#define MNG_CHANGETIMOUT_DECODER_1       3
-#define MNG_CHANGETIMOUT_DECODER_2       4
-#define MNG_CHANGETIMOUT_USER_1          5
-#define MNG_CHANGETIMOUT_USER_2          6
-#define MNG_CHANGETIMOUT_EXTERNAL_1      7
-#define MNG_CHANGETIMOUT_EXTERNAL_2      8
-
-#define MNG_CHANGECLIPPING_NO            0       /* FRAM */
-#define MNG_CHANGECLIPPING_NEXTSUBFRAME  1
-#define MNG_CHANGECLIPPING_DEFAULT       2
-
-#define MNG_CHANGESYNCID_NO              0       /* FRAM */
-#define MNG_CHANGESYNCID_NEXTSUBFRAME    1
-#define MNG_CHANGESYNCID_DEFAULT         2
-
-#define MNG_CLIPPING_ABSOLUTE            0       /* CLIP */
-#define MNG_CLIPPING_RELATIVE            1
-
-#define MNG_SHOWMODE_0                   0       /* SHOW */
-#define MNG_SHOWMODE_1                   1
-#define MNG_SHOWMODE_2                   2
-#define MNG_SHOWMODE_3                   3
-#define MNG_SHOWMODE_4                   4
-#define MNG_SHOWMODE_5                   5
-#define MNG_SHOWMODE_6                   6
-#define MNG_SHOWMODE_7                   7
-
-#define MNG_TERMACTION_LASTFRAME         0       /* TERM */
-#define MNG_TERMACTION_CLEAR             1
-#define MNG_TERMACTION_FIRSTFRAME        2
-#define MNG_TERMACTION_REPEAT            3
-
-#define MNG_ITERACTION_LASTFRAME         0       /* TERM */
-#define MNG_ITERACTION_CLEAR             1
-#define MNG_ITERACTION_FIRSTFRAME        2
-
-#define MNG_SAVEOFFSET_4BYTE             4       /* SAVE */
-#define MNG_SAVEOFFSET_8BYTE             8
-
-#define MNG_SAVEENTRY_SEGMENTFULL        0       /* SAVE */
-#define MNG_SAVEENTRY_SEGMENT            1
-#define MNG_SAVEENTRY_SUBFRAME           2
-#define MNG_SAVEENTRY_EXPORTEDIMAGE      3
-
-#define MNG_PRIORITY_ABSOLUTE            0       /* fPRI */
-#define MNG_PRIORITY_RELATIVE            1
-
-#ifdef MNG_INCLUDE_JNG
-#define MNG_COLORTYPE_JPEGGRAY           8       /* JHDR */
-#define MNG_COLORTYPE_JPEGCOLOR         10
-#define MNG_COLORTYPE_JPEGGRAYA         12
-#define MNG_COLORTYPE_JPEGCOLORA        14
-
-#define MNG_BITDEPTH_JPEG8               8       /* JHDR */
-#define MNG_BITDEPTH_JPEG12             12
-#define MNG_BITDEPTH_JPEG8AND12         20
-
-#define MNG_COMPRESSION_BASELINEJPEG     8       /* JHDR */
-
-#define MNG_INTERLACE_SEQUENTIAL         0       /* JHDR */
-#define MNG_INTERLACE_PROGRESSIVE        8
-#endif /* MNG_INCLUDE_JNG */
-
-#define MNG_IMAGETYPE_UNKNOWN            0       /* DHDR */
-#define MNG_IMAGETYPE_PNG                1
-#define MNG_IMAGETYPE_JNG                2
-
-#define MNG_DELTATYPE_REPLACE            0       /* DHDR */
-#define MNG_DELTATYPE_BLOCKPIXELADD      1
-#define MNG_DELTATYPE_BLOCKALPHAADD      2
-#define MNG_DELTATYPE_BLOCKCOLORADD      3
-#define MNG_DELTATYPE_BLOCKPIXELREPLACE  4
-#define MNG_DELTATYPE_BLOCKALPHAREPLACE  5
-#define MNG_DELTATYPE_BLOCKCOLORREPLACE  6
-#define MNG_DELTATYPE_NOCHANGE           7
-
-#define MNG_FILLMETHOD_LEFTBITREPLICATE  0       /* PROM */
-#define MNG_FILLMETHOD_ZEROFILL          1
-
-#define MNG_DELTATYPE_REPLACERGB         0       /* PPLT */
-#define MNG_DELTATYPE_DELTARGB           1
-#define MNG_DELTATYPE_REPLACEALPHA       2
-#define MNG_DELTATYPE_DELTAALPHA         3
-#define MNG_DELTATYPE_REPLACERGBA        4
-#define MNG_DELTATYPE_DELTARGBA          5
-
-#define MNG_POLARITY_ONLY                0       /* DBYK */
-#define MNG_POLARITY_ALLBUT              1
-
-#define MNG_EVENT_NONE                   0       /* evNT */
-#define MNG_EVENT_MOUSEENTER             1
-#define MNG_EVENT_MOUSEMOVE              2
-#define MNG_EVENT_MOUSEEXIT              3
-#define MNG_EVENT_MOUSEDOWN              4
-#define MNG_EVENT_MOUSEUP                5
-
-#define MNG_MASK_NONE                    0       /* evNT */
-#define MNG_MASK_BOX                     1
-#define MNG_MASK_OBJECT                  2
-#define MNG_MASK_OBJECTIX                3
-#define MNG_MASK_BOXOBJECT               4
-#define MNG_MASK_BOXOBJECTIX             5
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* *  Processtext callback types                                            * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#define MNG_TYPE_TEXT 0
-#define MNG_TYPE_ZTXT 1
-#define MNG_TYPE_ITXT 2
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* *  CRC processing masks                                                  * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#define MNG_CRC_INPUT              0x0000000f
-#define MNG_CRC_INPUT_NONE         0x00000000
-#define MNG_CRC_INPUT_PRESENT      0x00000001
-#define MNG_CRC_OUTPUT             0x000000f0
-#define MNG_CRC_OUTPUT_NONE        0x00000000
-#define MNG_CRC_OUTPUT_GENERATE    0x00000020
-#define MNG_CRC_OUTPUT_DUMMY       0x00000040
-#define MNG_CRC_ANCILLARY          0x00000f00
-#define MNG_CRC_ANCILLARY_IGNORE   0x00000000
-#define MNG_CRC_ANCILLARY_DISCARD  0x00000100
-#define MNG_CRC_ANCILLARY_WARNING  0x00000200
-#define MNG_CRC_ANCILLARY_ERROR    0x00000300
-#define MNG_CRC_CRITICAL           0x0000f000
-#define MNG_CRC_CRITICAL_IGNORE    0x00000000
-#define MNG_CRC_CRITICAL_WARNING   0x00002000
-#define MNG_CRC_CRITICAL_ERROR     0x00003000
-#define MNG_CRC_DEFAULT            0x00002121
-
-/* ************************************************************************** */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _libmng_h_ */
-
-/* ************************************************************************** */
-/* * end of file                                                            * */
-/* ************************************************************************** */
-
diff --git a/Source/LibMNG/libmng_callback_xs.c b/Source/LibMNG/libmng_callback_xs.c
deleted file mode 100644
index e8f1efe..0000000
--- a/Source/LibMNG/libmng_callback_xs.c
+++ /dev/null
@@ -1,1239 +0,0 @@
-/* ************************************************************************** */
-/* *             For conditions of distribution and use,                    * */
-/* *                see copyright notice in libmng.h                        * */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * project   : libmng                                                     * */
-/* * file      : libmng_callback_xs.c      copyright (c) 2000-2004 G.Juyn   * */
-/* * version   : 1.0.9                                                      * */
-/* *                                                                        * */
-/* * purpose   : callback get/set interface (implementation)                * */
-/* *                                                                        * */
-/* * author    : G.Juyn                                                     * */
-/* *                                                                        * */
-/* * comment   : implementation of the callback get/set functions           * */
-/* *                                                                        * */
-/* * changes   : 0.5.1 - 05/08/2000 - G.Juyn                                * */
-/* *             - fixed calling convention                                 * */
-/* *             - changed strict-ANSI stuff                                * */
-/* *             0.5.1 - 05/12/2000 - G.Juyn                                * */
-/* *             - changed trace to macro for callback error-reporting      * */
-/* *                                                                        * */
-/* *             0.5.2 - 05/31/2000 - G.Juyn                                * */
-/* *             - fixed up punctuation (contribution by Tim Rowley)        * */
-/* *             0.5.2 - 06/02/2000 - G.Juyn                                * */
-/* *             - added getalphaline callback for RGB8_A8 canvasstyle      * */
-/* *                                                                        * */
-/* *             0.9.1 - 07/15/2000 - G.Juyn                                * */
-/* *             - added callbacks for SAVE/SEEK processing                 * */
-/* *                                                                        * */
-/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
-/* *             - changed file-prefixes                                    * */
-/* *                                                                        * */
-/* *             0.9.3 - 10/11/2000 - G.Juyn                                * */
-/* *             - added support for nEED                                   * */
-/* *             0.9.3 - 10/17/2000 - G.Juyn                                * */
-/* *             - added callback to process non-critical unknown chunks    * */
-/* *                                                                        * */
-/* *             1.0.1 - 02/08/2001 - G.Juyn                                * */
-/* *             - added MEND processing callback                           * */
-/* *                                                                        * */
-/* *             1.0.2 - 06/23/2001 - G.Juyn                                * */
-/* *             - added processterm callback                               * */
-/* *                                                                        * */
-/* *             1.0.6 - 07/07/2003 - G. R-P                                * */
-/* *             - added SKIPCHUNK feature                                  * */
-/* *                                                                        * */
-/* *             1.0.7 - 03/10/2004 - G.R-P                                 * */
-/* *             - added conditionals around openstream/closestream         * */
-/* *             1.0.7 - 03/19/2004 - G.R-P                                 * */
-/* *             - fixed typo (MNG_SKIPCHUNK_SAVE -> MNG_SKIPCHUNK_nEED     * */
-/* *                                                                        * */
-/* *             1.0.8 - 04/10/2004 - G.Juyn                                * */
-/* *             - added data-push mechanisms for specialized decoders      * */
-/* *                                                                        * */
-/* *             1.0.9 - 09/18/2004 - G.R-P.                                * */
-/* *             - added two SKIPCHUNK_TERM conditionals                    * */
-/* *             1.0.9 - 12/20/2004 - G.Juyn                                * */
-/* *             - cleaned up macro-invocations (thanks to D. Airlie)       * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#include "libmng.h"
-#include "libmng_data.h"
-#include "libmng_error.h"
-#include "libmng_trace.h"
-#ifdef __BORLANDC__
-#pragma hdrstop
-#endif
-
-#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
-#pragma option -A                      /* force ANSI-C */
-#endif
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* *  Callback set functions                                                * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifndef MNG_INTERNAL_MEMMNGMT
-mng_retcode MNG_DECL mng_setcb_memalloc (mng_handle   hHandle,
-                                         mng_memalloc fProc)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_MEMALLOC, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->fMemalloc = fProc;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_MEMALLOC, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_INTERNAL_MEMMNGMT */
-
-/* ************************************************************************** */
-
-#ifndef MNG_INTERNAL_MEMMNGMT
-mng_retcode MNG_DECL mng_setcb_memfree (mng_handle  hHandle,
-                                        mng_memfree fProc)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_MEMFREE, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->fMemfree = fProc;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_MEMFREE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_INTERNAL_MEMMNGMT */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_READ
-mng_retcode MNG_DECL mng_setcb_releasedata (mng_handle      hHandle,
-                                            mng_releasedata fProc)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_RELEASEDATA, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->fReleasedata = fProc;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_RELEASEDATA, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_READ */
-
-/* ************************************************************************** */
-
-#if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
-#ifndef MNG_NO_OPEN_CLOSE_STREAM
-mng_retcode MNG_DECL mng_setcb_openstream (mng_handle     hHandle,
-                                           mng_openstream fProc)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_OPENSTREAM, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->fOpenstream = fProc;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_OPENSTREAM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif /* MNG_SUPPORT_READ || MNG_SUPPORT_WRITE */
-
-/* ************************************************************************** */
-
-#if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
-#ifndef MNG_NO_OPEN_CLOSE_STREAM
-mng_retcode MNG_DECL mng_setcb_closestream (mng_handle      hHandle,
-                                            mng_closestream fProc)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_CLOSESTREAM, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->fClosestream = fProc;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_CLOSESTREAM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif /* MNG_SUPPORT_READ || MNG_SUPPORT_WRITE */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_READ
-mng_retcode MNG_DECL mng_setcb_readdata (mng_handle   hHandle,
-                                         mng_readdata fProc)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_READDATA, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->fReaddata = fProc;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_READDATA, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_READ */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_WRITE
-mng_retcode MNG_DECL mng_setcb_writedata (mng_handle    hHandle,
-                                          mng_writedata fProc)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_WRITEDATA, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->fWritedata = fProc;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_WRITEDATA, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_WRITE */
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_setcb_errorproc (mng_handle    hHandle,
-                                          mng_errorproc fProc)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_ERRORPROC, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->fErrorproc = fProc;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_ERRORPROC, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_TRACE
-mng_retcode MNG_DECL mng_setcb_traceproc (mng_handle    hHandle,
-                                          mng_traceproc fProc)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_TRACEPROC, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->fTraceproc = fProc;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_TRACEPROC, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_TRACE */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_READ
-mng_retcode MNG_DECL mng_setcb_processheader (mng_handle        hHandle,
-                                              mng_processheader fProc)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSHEADER, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->fProcessheader = fProc;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSHEADER, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_READ */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_READ
-#ifndef MNG_SKIPCHUNK_tEXt
-mng_retcode MNG_DECL mng_setcb_processtext (mng_handle      hHandle,
-                                            mng_processtext fProc)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSTEXT, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->fProcesstext = fProc;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSTEXT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif /* MNG_SUPPORT_READ */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_READ
-#ifndef MNG_SKIPCHUNK_SAVE
-mng_retcode MNG_DECL mng_setcb_processsave (mng_handle      hHandle,
-                                            mng_processsave fProc)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSSAVE, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->fProcesssave = fProc;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSSAVE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif /* MNG_SUPPORT_READ */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_READ
-#ifndef MNG_SKIPCHUNK_SEEK
-mng_retcode MNG_DECL mng_setcb_processseek (mng_handle      hHandle,
-                                            mng_processseek fProc)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSSEEK, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->fProcessseek = fProc;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSSEEK, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif /* MNG_SUPPORT_READ */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_READ
-#ifndef MNG_SKIPCHUNK_nEED
-mng_retcode MNG_DECL mng_setcb_processneed (mng_handle      hHandle,
-                                            mng_processneed fProc)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSNEED, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->fProcessneed = fProc;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSNEED, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif /* MNG_SUPPORT_READ */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_READ
-mng_retcode MNG_DECL mng_setcb_processmend (mng_handle      hHandle,
-                                            mng_processmend fProc)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSMEND, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->fProcessmend = fProc;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSMEND, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_READ */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_READ
-mng_retcode MNG_DECL mng_setcb_processunknown (mng_handle         hHandle,
-                                               mng_processunknown fProc)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSUNKNOWN, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->fProcessunknown = fProc;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSUNKNOWN, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_READ */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_READ
-#ifndef MNG_SKIPCHUNK_TERM
-mng_retcode MNG_DECL mng_setcb_processterm (mng_handle      hHandle,
-                                            mng_processterm fProc)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSTERM, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->fProcessterm = fProc;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSTERM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif /* MNG_SUPPORT_READ */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-mng_retcode MNG_DECL mng_setcb_getcanvasline (mng_handle        hHandle,
-                                              mng_getcanvasline fProc)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_GETCANVASLINE, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->fGetcanvasline = fProc;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_GETCANVASLINE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-mng_retcode MNG_DECL mng_setcb_getbkgdline (mng_handle      hHandle,
-                                            mng_getbkgdline fProc)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_GETBKGDLINE, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->fGetbkgdline = fProc;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_GETBKGDLINE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-mng_retcode MNG_DECL mng_setcb_getalphaline (mng_handle       hHandle,
-                                             mng_getalphaline fProc)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_GETALPHALINE, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->fGetalphaline = fProc;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_GETALPHALINE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-mng_retcode MNG_DECL mng_setcb_refresh (mng_handle  hHandle,
-                                        mng_refresh fProc)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_REFRESH, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->fRefresh = fProc;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_REFRESH, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-mng_retcode MNG_DECL mng_setcb_gettickcount (mng_handle       hHandle,
-                                             mng_gettickcount fProc)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_GETTICKCOUNT, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->fGettickcount = fProc;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_GETTICKCOUNT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-mng_retcode MNG_DECL mng_setcb_settimer (mng_handle   hHandle,
-                                         mng_settimer fProc)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_SETTIMER, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->fSettimer = fProc;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_SETTIMER, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-
-#if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_APP_CMS)
-mng_retcode MNG_DECL mng_setcb_processgamma (mng_handle        hHandle,
-                                             mng_processgamma  fProc)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSGAMA, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->fProcessgamma = fProc;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSGAMA, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_DISPLAY && MNG_APP_CMS */
-
-/* ************************************************************************** */
-
-#if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_APP_CMS)
-#ifndef MNG_SKIPCHUNK_cHRM
-mng_retcode MNG_DECL mng_setcb_processchroma (mng_handle        hHandle,
-                                              mng_processchroma fProc)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSCHROMA, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->fProcesschroma = fProc;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSCHROMA, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif /* MNG_SUPPORT_DISPLAY && MNG_APP_CMS */
-
-/* ************************************************************************** */
-
-#if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_APP_CMS)
-mng_retcode MNG_DECL mng_setcb_processsrgb (mng_handle      hHandle,
-                                            mng_processsrgb fProc)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSSRGB, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->fProcesssrgb = fProc;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSSRGB, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_DISPLAY && MNG_APP_CMS */
-
-/* ************************************************************************** */
-
-#if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_APP_CMS)
-#ifndef MNG_SKIPCHUNK_iCCP
-mng_retcode MNG_DECL mng_setcb_processiccp (mng_handle      hHandle,
-                                            mng_processiccp fProc)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSICCP, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->fProcessiccp = fProc;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSICCP, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif /* MNG_SUPPORT_DISPLAY && MNG_APP_CMS */
-
-/* ************************************************************************** */
-
-#if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_APP_CMS)
-mng_retcode MNG_DECL mng_setcb_processarow (mng_handle      hHandle,
-                                            mng_processarow fProc)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSAROW, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->fProcessarow = fProc;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSAROW, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_DISPLAY && MNG_APP_CMS */
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* *  Callback get functions                                                * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifndef MNG_INTERNAL_MEMMNGMT
-mng_memalloc MNG_DECL mng_getcb_memalloc (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_MEMALLOC, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_MEMALLOC, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->fMemalloc;
-}
-#endif /* MNG_INTERNAL_MEMMNGMT */
-
-/* ************************************************************************** */
-
-#ifndef MNG_INTERNAL_MEMMNGMT
-mng_memfree MNG_DECL mng_getcb_memfree (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_MEMFREE, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_MEMFREE, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->fMemfree;
-}
-#endif /* MNG_INTERNAL_MEMMNGMT */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_READ
-mng_releasedata MNG_DECL mng_getcb_releasedata (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_RELEASEDATA, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_RELEASEDATA, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->fReleasedata;
-}
-#endif /* MNG_SUPPORT_READ */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_READ
-mng_readdata MNG_DECL mng_getcb_readdata (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_READDATA, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_READDATA, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->fReaddata;
-}
-#endif /* MNG_SUPPORT_READ */
-
-/* ************************************************************************** */
-
-#if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
-#ifndef MNG_NO_OPEN_CLOSE_STREAM
-mng_openstream MNG_DECL mng_getcb_openstream (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_OPENSTREAM, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_OPENSTREAM, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->fOpenstream;
-}
-#endif
-#endif /* MNG_SUPPORT_READ || MNG_SUPPORT_WRITE */
-
-/* ************************************************************************** */
-
-#if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
-#ifndef MNG_NO_OPEN_CLOSE_STREAM
-mng_closestream MNG_DECL mng_getcb_closestream (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_CLOSESTREAM, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_CLOSESTREAM, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->fClosestream;
-}
-#endif
-#endif /* MNG_SUPPORT_READ || MNG_SUPPORT_WRITE */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_WRITE
-mng_writedata MNG_DECL mng_getcb_writedata (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_WRITEDATA, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_WRITEDATA, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->fWritedata;
-}
-#endif /* MNG_SUPPORT_WRITE */
-
-/* ************************************************************************** */
-
-mng_errorproc MNG_DECL mng_getcb_errorproc (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_ERRORPROC, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_ERRORPROC, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->fErrorproc;
-}
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_TRACE
-mng_traceproc MNG_DECL mng_getcb_traceproc (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_TRACEPROC, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_TRACEPROC, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->fTraceproc;
-}
-#endif /* MNG_SUPPORT_TRACE */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_READ
-mng_processheader MNG_DECL mng_getcb_processheader (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSHEADER, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSHEADER, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->fProcessheader;
-}
-#endif /* MNG_SUPPORT_READ */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_READ
-#ifndef MNG_SKIPCHUNK_tEXt
-mng_processtext MNG_DECL mng_getcb_processtext (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSTEXT, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSTEXT, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->fProcesstext;
-}
-#endif
-#endif /* MNG_SUPPORT_READ */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_READ
-#ifndef MNG_SKIPCHUNK_SAVE
-mng_processsave MNG_DECL mng_getcb_processsave (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSSAVE, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSSAVE, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->fProcesssave;
-}
-#endif
-#endif /* MNG_SUPPORT_READ */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_READ
-#ifndef MNG_SKIPCHUNK_SEEK
-mng_processseek MNG_DECL mng_getcb_processseek (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSSEEK, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSSEEK, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->fProcessseek;
-}
-#endif
-#endif /* MNG_SUPPORT_READ */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_READ
-#ifndef MNG_SKIPCHUNK_nEED
-mng_processneed MNG_DECL mng_getcb_processneed (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSNEED, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSNEED, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->fProcessneed;
-}
-#endif
-#endif /* MNG_SUPPORT_READ */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_READ
-mng_processmend MNG_DECL mng_getcb_processmend (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSMEND, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSMEND, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->fProcessmend;
-}
-#endif /* MNG_SUPPORT_READ */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_READ
-mng_processunknown MNG_DECL mng_getcb_processunknown (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSUNKNOWN, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSUNKNOWN, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->fProcessunknown;
-}
-#endif /* MNG_SUPPORT_READ */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_READ
-#ifndef MNG_SKIPCHUNK_TERM
-mng_processterm MNG_DECL mng_getcb_processterm (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSTERM, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSTERM, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->fProcessterm;
-}
-#endif
-#endif /* MNG_SUPPORT_READ */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-mng_getcanvasline MNG_DECL mng_getcb_getcanvasline (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_GETCANVASLINE, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_GETCANVASLINE, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->fGetcanvasline;
-}
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-mng_getbkgdline MNG_DECL mng_getcb_getbkgdline (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_GETBKGDLINE, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_GETBKGDLINE, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->fGetbkgdline;
-}
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-mng_getalphaline MNG_DECL mng_getcb_getalphaline (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_GETALPHALINE, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_GETALPHALINE, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->fGetalphaline;
-}
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-mng_refresh MNG_DECL mng_getcb_refresh (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_REFRESH, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_REFRESH, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->fRefresh;
-}
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-mng_gettickcount MNG_DECL mng_getcb_gettickcount (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_GETTICKCOUNT, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_GETTICKCOUNT, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->fGettickcount;
-}
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-mng_settimer MNG_DECL mng_getcb_settimer (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_SETTIMER, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_SETTIMER, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->fSettimer;
-}
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-
-#if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_APP_CMS)
-mng_processgamma MNG_DECL mng_getcb_processgamma (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSGAMMA, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSGAMMA, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->fProcessgamma;
-}
-#endif /* MNG_SUPPORT_DISPLAY && MNG_APP_CMS */
-
-/* ************************************************************************** */
-
-#if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_APP_CMS)
-#ifndef MNG_SKIPCHUNK_cHRM
-mng_processchroma MNG_DECL mng_getcb_processchroma (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSCHROMA, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSCHROMA, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->fProcesschroma;
-}
-#endif
-#endif /* MNG_SUPPORT_DISPLAY && MNG_APP_CMS */
-
-/* ************************************************************************** */
-
-#if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_APP_CMS)
-mng_processsrgb MNG_DECL mng_getcb_processsrgb (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSSRGB, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSSRGB, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->fProcesssrgb;
-}
-#endif /* MNG_SUPPORT_DISPLAY && MNG_APP_CMS */
-
-/* ************************************************************************** */
-
-#if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_APP_CMS)
-#ifndef MNG_SKIPCHUNK_iCCP
-mng_processiccp MNG_DECL mng_getcb_processiccp (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSICCP, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSICCP, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->fProcessiccp;
-}
-#endif
-#endif /* MNG_SUPPORT_DISPLAY && MNG_APP_CMS */
-
-/* ************************************************************************** */
-
-#if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_APP_CMS)
-mng_processarow MNG_DECL mng_getcb_processarow (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSAROW, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSAROW, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->fProcessarow;
-}
-#endif /* MNG_SUPPORT_DISPLAY && MNG_APP_CMS */
-
-/* ************************************************************************** */
-/* * end of file                                                            * */
-/* ************************************************************************** */
-
-
-
diff --git a/Source/LibMNG/libmng_chunk_descr.c b/Source/LibMNG/libmng_chunk_descr.c
deleted file mode 100644
index 5a4bfa0..0000000
--- a/Source/LibMNG/libmng_chunk_descr.c
+++ /dev/null
@@ -1,6090 +0,0 @@
-/* ************************************************************************** */
-/* *             For conditions of distribution and use,                    * */
-/* *                see copyright notice in libmng.h                        * */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * project   : libmng                                                     * */
-/* * file      : libmng_chunk_descr.c      copyright (c) 2005-2007 G.Juyn   * */
-/* * version   : 1.0.10                                                     * */
-/* *                                                                        * */
-/* * purpose   : Chunk descriptor functions (implementation)                * */
-/* *                                                                        * */
-/* * author    : G.Juyn                                                     * */
-/* *                                                                        * */
-/* * comment   : implementation of the chunk- anf field-descriptor          * */
-/* *             routines                                                   * */
-/* *                                                                        * */
-/* * changes   : 1.0.9 - 12/06/2004 - G.Juyn                                * */
-/* *             - added conditional MNG_OPTIMIZE_CHUNKREADER               * */
-/* *             1.0.9 - 12/11/2004 - G.Juyn                                * */
-/* *             - made all constants 'static'                              * */
-/* *             1.0.9 - 12/20/2004 - G.Juyn                                * */
-/* *             - cleaned up macro-invocations (thanks to D. Airlie)       * */
-/* *             1.0.9 - 01/17/2005 - G.Juyn                                * */
-/* *             - fixed problem with global PLTE/tRNS                      * */
-/* *                                                                        * */
-/* *             1.0.10 - 01/17/2005 - G.R-P.                               * */
-/* *             - added typecast to appease the compiler                   * */
-/* *             1.0.10 - 04/08/2007 - G.Juyn                               * */
-/* *             - added support for mPNG proposal                          * */
-/* *             1.0.10 - 04/12/2007 - G.Juyn                               * */
-/* *             - added support for ANG proposal                           * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#include <stddef.h>                    /* needed for offsetof() */
-
-#include "libmng.h"
-#include "libmng_data.h"
-#include "libmng_error.h"
-#include "libmng_trace.h"
-#ifdef __BORLANDC__
-#pragma hdrstop
-#endif
-#include "libmng_memory.h"
-#include "libmng_objects.h"
-#include "libmng_chunks.h"
-#include "libmng_chunk_descr.h"
-#include "libmng_object_prc.h"
-#include "libmng_chunk_prc.h"
-#include "libmng_chunk_io.h"
-#include "libmng_display.h"
-
-#ifdef MNG_INCLUDE_ANG_PROPOSAL
-#include "libmng_pixels.h"
-#include "libmng_filter.h"
-#endif
-
-#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
-#pragma option -A                      /* force ANSI-C */
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_OPTIMIZE_CHUNKREADER
-#if defined(MNG_INCLUDE_READ_PROCS) || defined(MNG_INCLUDE_WRITE_PROCS)
-
-/* ************************************************************************** */
-/* ************************************************************************** */
-/* PNG chunks */
-
-MNG_LOCAL mng_field_descriptor mng_fields_ihdr [] =
-  {
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_NOHIGHBIT,
-     1, 0, 4, 4,
-     offsetof(mng_ihdr, iWidth), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_NOHIGHBIT,
-     1, 0, 4, 4,
-     offsetof(mng_ihdr, iHeight), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     1, 16, 1, 1,
-     offsetof(mng_ihdr, iBitdepth), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 6, 1, 1,
-     offsetof(mng_ihdr, iColortype), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0, 1, 1,
-     offsetof(mng_ihdr, iCompression), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0, 1, 1,
-     offsetof(mng_ihdr, iFilter), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 1, 1, 1,
-     offsetof(mng_ihdr, iInterlace), MNG_NULL, MNG_NULL}
-  };
-
-/* ************************************************************************** */
-
-MNG_LOCAL mng_field_descriptor mng_fields_plte [] =
-  {
-    {mng_debunk_plte,
-     MNG_NULL,
-     0, 0, 0, 0,
-     MNG_NULL, MNG_NULL, MNG_NULL}
-  };
-
-/* ************************************************************************** */
-
-MNG_LOCAL mng_field_descriptor mng_fields_idat [] =
-  {
-    {MNG_NULL,
-     MNG_NULL,
-     0, 0, 0, 0,
-     offsetof(mng_idat, pData), MNG_NULL, offsetof(mng_idat, iDatasize)}
-  };
-
-/* ************************************************************************** */
-
-MNG_LOCAL mng_field_descriptor mng_fields_trns [] =
-  {
-    {mng_debunk_trns,
-     MNG_NULL,
-     0, 0, 0, 0,
-     MNG_NULL, MNG_NULL, MNG_NULL}
-  };
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_gAMA
-MNG_LOCAL mng_field_descriptor mng_fields_gama [] =
-  {
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0, 4, 4,
-     offsetof(mng_gama, iGamma), MNG_NULL, MNG_NULL}
-  };
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_cHRM
-MNG_LOCAL mng_field_descriptor mng_fields_chrm [] =
-  {
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0, 4, 4,
-     offsetof(mng_chrm, iWhitepointx), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0, 4, 4,
-     offsetof(mng_chrm, iWhitepointy), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0, 4, 4,
-     offsetof(mng_chrm, iRedx), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0, 4, 4,
-     offsetof(mng_chrm, iRedy), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0, 4, 4,
-     offsetof(mng_chrm, iGreeny), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0, 4, 4,
-     offsetof(mng_chrm, iGreeny), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0, 4, 4,
-     offsetof(mng_chrm, iBluex), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0, 4, 4,
-     offsetof(mng_chrm, iBluey), MNG_NULL, MNG_NULL}
-  };
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_sRGB
-MNG_LOCAL mng_field_descriptor mng_fields_srgb [] =
-  {
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 4, 1, 1,
-     offsetof(mng_srgb, iRenderingintent), MNG_NULL, MNG_NULL}
-  };
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_iCCP
-MNG_LOCAL mng_field_descriptor mng_fields_iccp [] =
-  {
-    {MNG_NULL,
-     MNG_FIELD_TERMINATOR,
-     0, 0, 1, 79,
-     offsetof(mng_iccp, zName), MNG_NULL, offsetof(mng_iccp, iNamesize)},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0, 1, 1,
-     offsetof(mng_iccp, iCompression), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_DEFLATED,
-     0, 0, 0, 0,
-     offsetof(mng_iccp, pProfile), MNG_NULL, offsetof(mng_iccp, iProfilesize)}
-  };
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_tEXt
-MNG_LOCAL mng_field_descriptor mng_fields_text [] =
-  {
-    {MNG_NULL,
-     MNG_FIELD_TERMINATOR,
-     0, 0, 1, 79,
-     offsetof(mng_text, zKeyword), MNG_NULL, offsetof(mng_text, iKeywordsize)},
-    {MNG_NULL,
-     MNG_NULL,
-     0, 0, 0, 0,
-     offsetof(mng_text, zText), MNG_NULL, offsetof(mng_text, iTextsize)}
-  };
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_zTXt
-MNG_LOCAL mng_field_descriptor mng_fields_ztxt [] =
-  {
-    {MNG_NULL,
-     MNG_FIELD_TERMINATOR,
-     0, 0, 1, 79,
-     offsetof(mng_ztxt, zKeyword), MNG_NULL, offsetof(mng_ztxt, iKeywordsize)},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0, 1, 1,
-     offsetof(mng_ztxt, iCompression), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_DEFLATED,
-     0, 0, 0, 0,
-     offsetof(mng_ztxt, zText), MNG_NULL, offsetof(mng_ztxt, iTextsize)}
-  };
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_iTXt
-MNG_LOCAL mng_field_descriptor mng_fields_itxt [] =
-  {
-    {MNG_NULL,
-     MNG_FIELD_TERMINATOR,
-     0, 0, 1, 79,
-     offsetof(mng_itxt, zKeyword), MNG_NULL, offsetof(mng_itxt, iKeywordsize)},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 1, 1, 1,
-     offsetof(mng_itxt, iCompressionflag), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0, 1, 1,
-     offsetof(mng_itxt, iCompressionmethod), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_TERMINATOR,
-     0, 0, 0, 0,
-     offsetof(mng_itxt, zLanguage), MNG_NULL, offsetof(mng_itxt, iLanguagesize)},
-    {MNG_NULL,
-     MNG_FIELD_TERMINATOR,
-     0, 0, 0, 0,
-     offsetof(mng_itxt, zTranslation), MNG_NULL, offsetof(mng_itxt, iTranslationsize)},
-    {mng_deflate_itxt,
-     MNG_NULL,
-     0, 0, 0, 0,
-     MNG_NULL, MNG_NULL, MNG_NULL}
-  };
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_bKGD
-MNG_LOCAL mng_field_descriptor mng_fields_bkgd [] =
-  {
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_PUTIMGTYPE,
-     0, 0, 0, 0,
-     offsetof(mng_bkgd, iType), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_IFIMGTYPE3,
-     0, 0xFF, 1, 1,
-     offsetof(mng_bkgd, iIndex), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_IFIMGTYPE0 | MNG_FIELD_IFIMGTYPE4,
-     0, 0xFFFF, 2, 2,
-     offsetof(mng_bkgd, iGray), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_IFIMGTYPE2 | MNG_FIELD_IFIMGTYPE6,
-     0, 0xFFFF, 2, 2,
-     offsetof(mng_bkgd, iRed), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_IFIMGTYPE2 | MNG_FIELD_IFIMGTYPE6,
-     0, 0xFFFF, 2, 2,
-     offsetof(mng_bkgd, iGreen), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_IFIMGTYPE2 | MNG_FIELD_IFIMGTYPE6,
-     0, 0xFFFF, 2, 2,
-     offsetof(mng_bkgd, iBlue), MNG_NULL, MNG_NULL}
-  };
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_pHYs
-MNG_LOCAL mng_field_descriptor mng_fields_phys [] =
-  {
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0, 4, 4,
-     offsetof(mng_phys, iSizex), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0, 4, 4,
-     offsetof(mng_phys, iSizey), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 1, 1, 1,
-     offsetof(mng_phys, iUnit), MNG_NULL, MNG_NULL}
-  };
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_sBIT
-MNG_LOCAL mng_field_descriptor mng_fields_sbit [] =
-  {
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_PUTIMGTYPE,
-     0, 0, 0, 0,
-     offsetof(mng_sbit, iType), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_IFIMGTYPES,
-     0, 0xFF, 1, 1,
-     offsetof(mng_sbit, aBits[0]), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_IFIMGTYPE2 | MNG_FIELD_IFIMGTYPE3 | MNG_FIELD_IFIMGTYPE4 | MNG_FIELD_IFIMGTYPE6,
-     0, 0xFF, 1, 1,
-     offsetof(mng_sbit, aBits[1]), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_IFIMGTYPE2 | MNG_FIELD_IFIMGTYPE3 | MNG_FIELD_IFIMGTYPE6,
-     0, 0xFF, 1, 1,
-     offsetof(mng_sbit, aBits[2]), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_IFIMGTYPE6,
-     0, 0xFF, 1, 1,
-     offsetof(mng_sbit, aBits[3]), MNG_NULL, MNG_NULL}
-  };
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_sPLT
-MNG_LOCAL mng_field_descriptor mng_fields_splt [] =
-  {
-    {MNG_NULL,
-     MNG_NULL,
-     0, 0, 1, 79,
-     offsetof(mng_splt, zName), MNG_NULL, offsetof(mng_splt, iNamesize)},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     8, 16, 1, 1,
-     offsetof(mng_splt, iSampledepth), MNG_NULL, MNG_NULL},
-    {mng_splt_entries,
-     MNG_NULL,
-     0, 0, 0, 0,
-     MNG_NULL, MNG_NULL, MNG_NULL}
-  };
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_hIST
-MNG_LOCAL mng_field_descriptor mng_fields_hist [] =
-  {
-    {mng_hist_entries,
-     MNG_NULL,
-     0, 0, 0, 0,
-     MNG_NULL, MNG_NULL, MNG_NULL}
-  };
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_tIME
-MNG_LOCAL mng_field_descriptor mng_fields_time [] =
-  {
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0xFFFF, 2, 2,
-     offsetof(mng_time, iYear), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     1, 12, 1, 1,
-     offsetof(mng_time, iMonth), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     1, 31, 1, 1,
-     offsetof(mng_time, iDay), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 24, 1, 1,
-     offsetof(mng_time, iHour), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 60, 1, 1,
-     offsetof(mng_time, iMinute), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 60, 1, 1,
-     offsetof(mng_time, iSecond), MNG_NULL, MNG_NULL}
-  };
-#endif
-
-/* ************************************************************************** */
-/* ************************************************************************** */
-/* JNG chunks */
-
-#ifdef MNG_INCLUDE_JNG
-MNG_LOCAL mng_field_descriptor mng_fields_jhdr [] =
-  {
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_NOHIGHBIT,
-     1, 0, 4, 4,
-     offsetof(mng_jhdr, iWidth), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_NOHIGHBIT,
-     1, 0, 4, 4,
-     offsetof(mng_jhdr, iHeight), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     8, 16, 1, 1,
-     offsetof(mng_jhdr, iColortype), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     8, 20, 1, 1,
-     offsetof(mng_jhdr, iImagesampledepth), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     8, 8, 1, 1,
-     offsetof(mng_jhdr, iImagecompression), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 8, 1, 1,
-     offsetof(mng_jhdr, iImageinterlace), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 16, 1, 1,
-     offsetof(mng_jhdr, iAlphasampledepth), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 8, 1, 1,
-     offsetof(mng_jhdr, iAlphacompression), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0, 1, 1,
-     offsetof(mng_jhdr, iAlphafilter), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 1, 1, 1,
-     offsetof(mng_jhdr, iAlphainterlace), MNG_NULL, MNG_NULL}
-  };
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-#define mng_fields_jdaa mng_fields_idat
-#define mng_fields_jdat mng_fields_idat
-#endif
-
-/* ************************************************************************** */
-/* ************************************************************************** */
-/* MNG chunks */
-
-MNG_LOCAL mng_field_descriptor mng_fields_mhdr [] =
-  {
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0, 4, 4,
-     offsetof(mng_mhdr, iWidth), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0, 4, 4,
-     offsetof(mng_mhdr, iHeight), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0, 4, 4,
-     offsetof(mng_mhdr, iTicks), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0, 4, 4,
-     offsetof(mng_mhdr, iLayercount), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0, 4, 4,
-     offsetof(mng_mhdr, iFramecount), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0, 4, 4,
-     offsetof(mng_mhdr, iPlaytime), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0, 4, 4,
-     offsetof(mng_mhdr, iSimplicity), MNG_NULL, MNG_NULL}
-  };
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_LOOP
-MNG_LOCAL mng_field_descriptor mng_fields_loop [] =
-  {
-    {mng_debunk_loop,
-     MNG_NULL,
-     0, 0, 0, 0,
-     MNG_NULL, MNG_NULL, MNG_NULL}
-  };
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_LOOP
-MNG_LOCAL mng_field_descriptor mng_fields_endl [] =
-  {
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0xFF, 1, 1,
-     offsetof(mng_endl, iLevel), MNG_NULL, MNG_NULL}
-  };
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_DEFI
-MNG_LOCAL mng_field_descriptor mng_fields_defi [] =
-  {
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0xFFFF, 2, 2,
-     offsetof(mng_defi, iObjectid), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_OPTIONAL,
-     0, 0xFF, 1, 1,
-     offsetof(mng_defi, iDonotshow), offsetof(mng_defi, bHasdonotshow), MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_OPTIONAL,
-     0, 0xFF, 1, 1,
-     offsetof(mng_defi, iConcrete), offsetof(mng_defi, bHasconcrete), MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_OPTIONAL | MNG_FIELD_GROUP1,
-     0, 0, 4, 4,
-     offsetof(mng_defi, iXlocation), offsetof(mng_defi, bHasloca), MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_OPTIONAL | MNG_FIELD_GROUP1,
-     0, 0, 4, 4,
-     offsetof(mng_defi, iYlocation), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_OPTIONAL | MNG_FIELD_GROUP2,
-     0, 0, 4, 4,
-     offsetof(mng_defi, iLeftcb), offsetof(mng_defi, bHasclip), MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_OPTIONAL | MNG_FIELD_GROUP2,
-     0, 0, 4, 4,
-     offsetof(mng_defi, iRightcb), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_OPTIONAL | MNG_FIELD_GROUP2,
-     0, 0, 4, 4,
-     offsetof(mng_defi, iTopcb), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_OPTIONAL | MNG_FIELD_GROUP2,
-     0, 0, 4, 4,
-     offsetof(mng_defi, iBottomcb), MNG_NULL, MNG_NULL}
-  };
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_BASI
-MNG_LOCAL mng_field_descriptor mng_fields_basi [] =
-  {
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0, 4, 4,
-     offsetof(mng_basi, iWidth), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0, 4, 4,
-     offsetof(mng_basi, iHeight), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     1, 16, 1, 1,
-     offsetof(mng_basi, iBitdepth), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 6, 1, 1,
-     offsetof(mng_basi, iColortype), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0, 1, 1,
-     offsetof(mng_basi, iCompression), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0, 1, 1,
-     offsetof(mng_basi, iFilter), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 1, 1, 1,
-     offsetof(mng_basi, iInterlace), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_OPTIONAL | MNG_FIELD_GROUP1,
-     0, 0xFFFF, 2, 2,
-     offsetof(mng_basi, iRed), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_OPTIONAL | MNG_FIELD_GROUP1,
-     0, 0xFFFF, 2, 2,
-     offsetof(mng_basi, iGreen), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_OPTIONAL | MNG_FIELD_GROUP1,
-     0, 0xFFFF, 2, 2,
-     offsetof(mng_basi, iBlue), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_OPTIONAL,
-     0, 0xFFFF, 2, 2,
-     offsetof(mng_basi, iAlpha), offsetof(mng_basi, bHasalpha), MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_OPTIONAL,
-     0, 1, 1, 1,
-     offsetof(mng_basi, iViewable), MNG_NULL, MNG_NULL}
-  };
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_CLON
-MNG_LOCAL mng_field_descriptor mng_fields_clon [] =
-  {
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0xFFFF, 2, 2,
-     offsetof(mng_clon, iSourceid), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0xFFFF, 2, 2,
-     offsetof(mng_clon, iCloneid), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_OPTIONAL,
-     0, 2, 1, 1,
-     offsetof(mng_clon, iClonetype), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_OPTIONAL,
-     0, 1, 1, 1,
-     offsetof(mng_clon, iDonotshow), offsetof(mng_clon, bHasdonotshow), MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_OPTIONAL,
-     0, 1, 1, 1,
-     offsetof(mng_clon, iConcrete), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_OPTIONAL | MNG_FIELD_GROUP1,
-     0, 2, 1, 1,
-     offsetof(mng_clon, iLocationtype), offsetof(mng_clon, bHasloca), MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_OPTIONAL | MNG_FIELD_GROUP1,
-     0, 0, 4, 4,
-     offsetof(mng_clon, iLocationx), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_OPTIONAL | MNG_FIELD_GROUP1,
-     0, 0, 4, 4,
-     offsetof(mng_clon, iLocationy), MNG_NULL, MNG_NULL}
-  };
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_PAST
-MNG_LOCAL mng_field_descriptor mng_fields_past [] =
-  {
-    {mng_debunk_past,
-     MNG_NULL,
-     0, 0, 0, 0,
-     MNG_NULL, MNG_NULL, MNG_NULL}
-  };
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_DISC
-MNG_LOCAL mng_field_descriptor mng_fields_disc [] =
-  {
-    {mng_disc_entries,
-     MNG_NULL,
-     0, 0, 0, 0,
-     MNG_NULL, MNG_NULL, MNG_NULL}
-  };
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_BACK
-MNG_LOCAL mng_field_descriptor mng_fields_back [] =
-  {
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0xFFFF, 2, 2,
-     offsetof(mng_back, iRed), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0xFFFF, 2, 2,
-     offsetof(mng_back, iGreen), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0xFFFF, 2, 2,
-     offsetof(mng_back, iBlue), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_OPTIONAL,
-     0, 3, 1, 1,
-     offsetof(mng_back, iMandatory), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_OPTIONAL,
-     0, 0xFFFF, 2, 2,
-     offsetof(mng_back, iImageid), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_OPTIONAL,
-     0, 1, 1, 1,
-     offsetof(mng_back, iTile), MNG_NULL, MNG_NULL}
-  };
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_FRAM
-MNG_LOCAL mng_field_descriptor mng_fields_fram [] =
-  {
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_OPTIONAL,
-     0, 4, 1, 1,
-     offsetof(mng_fram, iMode), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_TERMINATOR | MNG_FIELD_OPTIONAL,
-     0, 0, 1, 79,
-     offsetof(mng_fram, zName), MNG_NULL, offsetof(mng_fram, iNamesize)},
-    {mng_fram_remainder,
-     MNG_FIELD_OPTIONAL,
-     0, 0, 0, 0,
-     MNG_NULL, MNG_NULL, MNG_NULL}
-  };
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_MOVE
-MNG_LOCAL mng_field_descriptor mng_fields_move [] =
-  {
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0xFFFF, 2, 2,
-     offsetof(mng_move, iFirstid), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0xFFFF, 2, 2,
-     offsetof(mng_move, iLastid), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 1, 1, 1,
-     offsetof(mng_move, iMovetype), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0, 4, 4,
-     offsetof(mng_move, iMovex), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0, 4, 4,
-     offsetof(mng_move, iMovey), MNG_NULL, MNG_NULL}
-  };
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_CLIP
-MNG_LOCAL mng_field_descriptor mng_fields_clip [] =
-  {
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0xFFFF, 2, 2,
-     offsetof(mng_clip, iFirstid), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0xFFFF, 2, 2,
-     offsetof(mng_clip, iLastid), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 1, 1, 1,
-     offsetof(mng_clip, iCliptype), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0, 4, 4,
-     offsetof(mng_clip, iClipl), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0, 4, 4,
-     offsetof(mng_clip, iClipr), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0, 4, 4,
-     offsetof(mng_clip, iClipt), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0, 4, 4,
-     offsetof(mng_clip, iClipb), MNG_NULL, MNG_NULL}
-  };
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_SHOW
-MNG_LOCAL mng_field_descriptor mng_fields_show [] =
-  {
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     1, 0xFFFF, 2, 2,
-     offsetof(mng_show, iFirstid), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_OPTIONAL,
-     1, 0xFFFF, 2, 2,
-     offsetof(mng_show, iLastid), offsetof(mng_show, bHaslastid), MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_OPTIONAL,
-     0, 7, 1, 1,
-     offsetof(mng_show, iMode), MNG_NULL, MNG_NULL}
-  };
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_TERM
-MNG_LOCAL mng_field_descriptor mng_fields_term [] =
-  {
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 3, 1, 1,
-     offsetof(mng_term, iTermaction), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_OPTIONAL | MNG_FIELD_GROUP1,
-     0, 2, 1, 1,
-     offsetof(mng_term, iIteraction), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_OPTIONAL | MNG_FIELD_GROUP1,
-     0, 0, 4, 4,
-     offsetof(mng_term, iDelay), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_OPTIONAL | MNG_FIELD_GROUP1,
-     0, 0, 4, 4,
-     offsetof(mng_term, iItermax), MNG_NULL, MNG_NULL}
-  };
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_SAVE
-MNG_LOCAL mng_field_descriptor mng_fields_save [] =
-  {
-    {mng_save_entries,
-     MNG_NULL,
-     0, 0, 0, 0,
-     MNG_NULL, MNG_NULL, MNG_NULL}
-  };
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_SEEK
-MNG_LOCAL mng_field_descriptor mng_fields_seek [] =
-  {
-    {MNG_NULL,
-     MNG_NULL,
-     0, 0, 1, 79,
-     offsetof(mng_seek, zName), MNG_NULL, offsetof(mng_seek, iNamesize)}
-  };
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_eXPI
-MNG_LOCAL mng_field_descriptor mng_fields_expi [] =
-  {
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0xFFFF, 2, 2,
-     offsetof(mng_expi, iSnapshotid), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_NULL,
-     0, 0, 1, 79,
-     offsetof(mng_expi, zName), MNG_NULL, offsetof(mng_expi, iNamesize)}
-  };
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_fPRI
-MNG_LOCAL mng_field_descriptor mng_fields_fpri [] =
-  {
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 1, 1, 1,
-     offsetof(mng_fpri, iDeltatype), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0xFF, 1, 1,
-     offsetof(mng_fpri, iPriority), MNG_NULL, MNG_NULL}
-  };
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_nEED
-MNG_LOCAL mng_field_descriptor mng_fields_need [] =
-  {
-    {MNG_NULL,
-     MNG_NULL,
-     0, 0, 1, 0,
-     offsetof(mng_need, zKeywords), MNG_NULL, offsetof(mng_need, iKeywordssize)}
-  };
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_pHYg
-#define mng_fields_phyg mng_fields_phys
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-MNG_LOCAL mng_field_descriptor mng_fields_dhdr [] =
-  {
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0xFFFF, 2, 2,
-     offsetof(mng_dhdr, iObjectid), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 2, 1, 1,
-     offsetof(mng_dhdr, iImagetype), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 7, 1, 1,
-     offsetof(mng_dhdr, iDeltatype), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_OPTIONAL | MNG_FIELD_GROUP1,
-     0, 0, 4, 4,
-     offsetof(mng_dhdr, iBlockwidth), offsetof(mng_dhdr, bHasblocksize), MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_OPTIONAL | MNG_FIELD_GROUP1,
-     0, 0, 4, 4,
-     offsetof(mng_dhdr, iBlockheight), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_OPTIONAL | MNG_FIELD_GROUP2,
-     0, 0, 4, 4,
-     offsetof(mng_dhdr, iBlockx), offsetof(mng_dhdr, bHasblockloc), MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT | MNG_FIELD_OPTIONAL | MNG_FIELD_GROUP2,
-     0, 0, 4, 4,
-     offsetof(mng_dhdr, iBlocky), MNG_NULL, MNG_NULL}
-  };
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-MNG_LOCAL mng_field_descriptor mng_fields_prom [] =
-  {
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 14, 1, 1,
-     offsetof(mng_prom, iColortype), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 16, 1, 1,
-     offsetof(mng_prom, iSampledepth), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 1, 1, 1,
-     offsetof(mng_prom, iFilltype), MNG_NULL, MNG_NULL}
-  };
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-MNG_LOCAL mng_field_descriptor mng_fields_pplt [] =
-  {
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 5, 1, 1,
-     offsetof(mng_pplt, iDeltatype), MNG_NULL, MNG_NULL},
-    {mng_pplt_entries,
-     MNG_NULL,
-     0, 0, 0, 0,
-     MNG_NULL, MNG_NULL, MNG_NULL}
-  };
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-MNG_LOCAL mng_field_descriptor mng_fields_drop [] =
-  {
-    {mng_drop_entries,
-     MNG_NULL,
-     0, 0, 0, 0,
-     MNG_NULL, MNG_NULL, MNG_NULL}
-  };
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_SKIPCHUNK_DBYK
-MNG_LOCAL mng_field_descriptor mng_fields_dbyk [] =
-  {
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0, 4, 4,
-     offsetof(mng_dbyk, iChunkname), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 1, 1, 1,
-     offsetof(mng_dbyk, iPolarity), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_NULL,
-     0, 0, 1, 0,
-     offsetof(mng_dbyk, zKeywords), MNG_NULL, offsetof(mng_dbyk, iKeywordssize)}
-  };
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_SKIPCHUNK_ORDR
-MNG_LOCAL mng_field_descriptor mng_fields_ordr [] =
-  {
-    {mng_drop_entries,
-     MNG_NULL,
-     0, 0, 0, 0,
-     MNG_NULL, MNG_NULL, MNG_NULL}
-  };
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_MAGN
-MNG_LOCAL mng_field_descriptor mng_fields_magn [] =
-  {
-    {mng_debunk_magn,
-     MNG_NULL,
-     0, 0, 0, 0,
-     MNG_NULL, MNG_NULL, MNG_NULL}
-  };
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-MNG_LOCAL mng_field_descriptor mng_fields_mpng [] =
-  {
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     1, 0, 4, 4,
-     offsetof(mng_mpng, iFramewidth), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     1, 0, 4, 4,
-     offsetof(mng_mpng, iFrameheight), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0xFFFF, 2, 2,
-     offsetof(mng_mpng, iNumplays), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     1, 0xFFFF, 2, 2,
-     offsetof(mng_mpng, iTickspersec), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0, 1, 1,
-     offsetof(mng_mpng, iCompressionmethod), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_DEFLATED,
-     0, 0, 1, 0,
-     offsetof(mng_mpng, pFrames), MNG_NULL, offsetof(mng_mpng, iFramessize)}
-  };
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_ANG_PROPOSAL
-MNG_LOCAL mng_field_descriptor mng_fields_ahdr [] =
-  {
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     1, 0, 4, 4,
-     offsetof(mng_ahdr, iNumframes), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0, 4, 4,
-     offsetof(mng_ahdr, iTickspersec), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 0, 4, 4,
-     offsetof(mng_ahdr, iNumplays), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     1, 0, 4, 4,
-     offsetof(mng_ahdr, iTilewidth), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     1, 0, 4, 4,
-     offsetof(mng_ahdr, iTileheight), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 1, 1, 1,
-     offsetof(mng_ahdr, iInterlace), MNG_NULL, MNG_NULL},
-    {MNG_NULL,
-     MNG_FIELD_INT,
-     0, 1, 1, 1,
-     offsetof(mng_ahdr, iStillused), MNG_NULL, MNG_NULL}
-  };
-
-MNG_LOCAL mng_field_descriptor mng_fields_adat [] =
-  {
-    {mng_adat_tiles,
-     MNG_NULL,
-     0, 0, 0, 0,
-     MNG_NULL, MNG_NULL, MNG_NULL}
-  };
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_evNT
-MNG_LOCAL mng_field_descriptor mng_fields_evnt [] =
-  {
-    {mng_evnt_entries,
-     MNG_NULL,
-     0, 0, 0, 0,
-     MNG_NULL, MNG_NULL, MNG_NULL}
-  };
-#endif
-
-/* ************************************************************************** */
-
-MNG_LOCAL mng_field_descriptor mng_fields_unknown [] =
-  {
-    {MNG_NULL,
-     MNG_NULL,
-     0, 0, 1, 0,
-     offsetof(mng_unknown_chunk, pData), MNG_NULL, offsetof(mng_unknown_chunk, iDatasize)}
-  };
-
-/* ************************************************************************** */
-/* ************************************************************************** */
-/* PNG chunks */
-
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_ihdr =
-    {mng_it_png, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_ihdr,
-     mng_fields_ihdr, (sizeof(mng_fields_ihdr) / sizeof(mng_field_descriptor)),
-     MNG_DESCR_GLOBAL,
-     MNG_NULL,
-     MNG_DESCR_NOIHDR | MNG_DESCR_NOJHDR | MNG_DESCR_NOBASI | MNG_DESCR_NOIDAT | MNG_DESCR_NOPLTE};
-
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_plte =
-    {mng_it_png, mng_create_none, 0, offsetof(mng_plte, bEmpty),
-     MNG_NULL, MNG_NULL, mng_special_plte,
-     mng_fields_plte, (sizeof(mng_fields_plte) / sizeof(mng_field_descriptor)),
-     MNG_DESCR_GLOBAL | MNG_DESCR_EMPTYEMBED,
-     MNG_DESCR_GenHDR,
-     MNG_DESCR_NOIDAT | MNG_DESCR_NOJDAT | MNG_DESCR_NOJDAA};
-
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_idat =
-    {mng_it_png, mng_create_none, 0, offsetof(mng_idat, bEmpty),
-     MNG_NULL, MNG_NULL, mng_special_idat,
-     mng_fields_idat, (sizeof(mng_fields_idat) / sizeof(mng_field_descriptor)),
-     MNG_DESCR_EMPTYEMBED,
-     MNG_DESCR_GenHDR,
-     MNG_DESCR_NOJSEP};
-
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_iend =
-    {mng_it_png, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_iend,
-     MNG_NULL, 0,
-     MNG_DESCR_EMPTY | MNG_DESCR_EMPTYEMBED,
-     MNG_DESCR_GenHDR,
-     MNG_NULL};
-
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_trns =
-    {mng_it_png, mng_create_none, 0, offsetof(mng_trns, bEmpty),
-     MNG_NULL, MNG_NULL, mng_special_trns,
-     mng_fields_trns, (sizeof(mng_fields_trns) / sizeof(mng_field_descriptor)),
-     MNG_DESCR_GLOBAL | MNG_DESCR_EMPTYEMBED,
-     MNG_DESCR_GenHDR,
-     MNG_DESCR_NOIDAT | MNG_DESCR_NOJDAT | MNG_DESCR_NOJDAA};
-
-#ifndef MNG_SKIPCHUNK_gAMA
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_gama =
-    {mng_it_png, mng_create_none, 0, offsetof(mng_gama, bEmpty),
-     MNG_NULL, MNG_NULL, mng_special_gama,
-     mng_fields_gama, (sizeof(mng_fields_gama) / sizeof(mng_field_descriptor)),
-     MNG_DESCR_GLOBAL | MNG_DESCR_EMPTYEMBED | MNG_DESCR_EMPTYGLOBAL,
-     MNG_DESCR_GenHDR,
-     MNG_DESCR_NOPLTE | MNG_DESCR_NOIDAT | MNG_DESCR_NOJDAT | MNG_DESCR_NOJDAA};
-#endif
-
-#ifndef MNG_SKIPCHUNK_cHRM
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_chrm =
-    {mng_it_png, mng_create_none, 0, offsetof(mng_chrm, bEmpty),
-     MNG_NULL, MNG_NULL, mng_special_chrm,
-     mng_fields_chrm, (sizeof(mng_fields_chrm) / sizeof(mng_field_descriptor)),
-     MNG_DESCR_GLOBAL | MNG_DESCR_EMPTYEMBED | MNG_DESCR_EMPTYGLOBAL,
-     MNG_DESCR_GenHDR,
-     MNG_DESCR_NOPLTE | MNG_DESCR_NOIDAT | MNG_DESCR_NOJDAT | MNG_DESCR_NOJDAA};
-#endif
-
-#ifndef MNG_SKIPCHUNK_sRGB
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_srgb =
-    {mng_it_png, mng_create_none, 0, offsetof(mng_srgb, bEmpty),
-     MNG_NULL, MNG_NULL, mng_special_srgb,
-     mng_fields_srgb, (sizeof(mng_fields_srgb) / sizeof(mng_field_descriptor)),
-     MNG_DESCR_GLOBAL | MNG_DESCR_EMPTYEMBED | MNG_DESCR_EMPTYGLOBAL,
-     MNG_DESCR_GenHDR,
-     MNG_DESCR_NOPLTE | MNG_DESCR_NOIDAT | MNG_DESCR_NOJDAT | MNG_DESCR_NOJDAA};
-#endif
-
-#ifndef MNG_SKIPCHUNK_iCCP
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_iccp =
-    {mng_it_png, mng_create_none, 0, offsetof(mng_iccp, bEmpty),
-     MNG_NULL, MNG_NULL, mng_special_iccp,
-     mng_fields_iccp, (sizeof(mng_fields_iccp) / sizeof(mng_field_descriptor)),
-     MNG_DESCR_GLOBAL | MNG_DESCR_EMPTYEMBED | MNG_DESCR_EMPTYGLOBAL,
-     MNG_DESCR_GenHDR,
-     MNG_DESCR_NOPLTE | MNG_DESCR_NOIDAT | MNG_DESCR_NOJDAT | MNG_DESCR_NOJDAA};
-#endif
-
-#ifndef MNG_SKIPCHUNK_tEXt
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_text =
-    {mng_it_png, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_text,
-     mng_fields_text, (sizeof(mng_fields_text) / sizeof(mng_field_descriptor)),
-     MNG_DESCR_GLOBAL,
-     MNG_DESCR_GenHDR,
-     MNG_NULL};
-#endif
-
-#ifndef MNG_SKIPCHUNK_zTXt
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_ztxt =
-    {mng_it_png, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_ztxt,
-     mng_fields_ztxt, (sizeof(mng_fields_ztxt) / sizeof(mng_field_descriptor)),
-     MNG_DESCR_GLOBAL,
-     MNG_DESCR_GenHDR,
-     MNG_NULL};
-#endif
-
-#ifndef MNG_SKIPCHUNK_iTXt
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_itxt =
-    {mng_it_png, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_itxt,
-     mng_fields_itxt, (sizeof(mng_fields_itxt) / sizeof(mng_field_descriptor)),
-     MNG_DESCR_GLOBAL,
-     MNG_DESCR_GenHDR,
-     MNG_NULL};
-#endif
-
-#ifndef MNG_SKIPCHUNK_bKGD
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_bkgd =
-    {mng_it_png, mng_create_none, 0, offsetof(mng_bkgd, bEmpty),
-     MNG_NULL, MNG_NULL, mng_special_bkgd,
-     mng_fields_bkgd, (sizeof(mng_fields_bkgd) / sizeof(mng_field_descriptor)),
-     MNG_DESCR_GLOBAL | MNG_DESCR_EMPTYEMBED | MNG_DESCR_EMPTYGLOBAL,
-     MNG_DESCR_GenHDR,
-     MNG_DESCR_NOIDAT | MNG_DESCR_NOJDAT | MNG_DESCR_NOJDAA};
-#endif
-
-#ifndef MNG_SKIPCHUNK_pHYs
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_phys =
-    {mng_it_png, mng_create_none, 0, offsetof(mng_phys, bEmpty),
-     MNG_NULL, MNG_NULL, mng_special_phys,
-     mng_fields_phys, (sizeof(mng_fields_phys) / sizeof(mng_field_descriptor)),
-     MNG_DESCR_GLOBAL | MNG_DESCR_EMPTYEMBED | MNG_DESCR_EMPTYGLOBAL,
-     MNG_DESCR_GenHDR,
-     MNG_DESCR_NOIDAT | MNG_DESCR_NOJDAT | MNG_DESCR_NOJDAA};
-#endif
-
-#ifndef MNG_SKIPCHUNK_sBIT
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_sbit =
-    {mng_it_png, mng_create_none, 0, offsetof(mng_sbit, bEmpty),
-     MNG_NULL, MNG_NULL, mng_special_sbit,
-     mng_fields_sbit, (sizeof(mng_fields_sbit) / sizeof(mng_field_descriptor)),
-     MNG_DESCR_GLOBAL | MNG_DESCR_EMPTYEMBED | MNG_DESCR_EMPTYGLOBAL,
-     MNG_DESCR_GenHDR,
-     MNG_DESCR_NOIDAT | MNG_DESCR_NOJDAT | MNG_DESCR_NOJDAA};
-#endif
-
-#ifndef MNG_SKIPCHUNK_sPLT
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_splt =
-    {mng_it_png, mng_create_none, 0, offsetof(mng_splt, bEmpty),
-     MNG_NULL, MNG_NULL, mng_special_splt,
-     mng_fields_splt, (sizeof(mng_fields_splt) / sizeof(mng_field_descriptor)),
-     MNG_DESCR_GLOBAL | MNG_DESCR_EMPTYEMBED | MNG_DESCR_EMPTYGLOBAL,
-     MNG_DESCR_GenHDR,
-     MNG_DESCR_NOIDAT | MNG_DESCR_NOJDAT | MNG_DESCR_NOJDAA};
-#endif
-
-#ifndef MNG_SKIPCHUNK_hIST
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_hist =
-    {mng_it_png, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_hist,
-     mng_fields_hist, (sizeof(mng_fields_hist) / sizeof(mng_field_descriptor)),
-     MNG_NULL,
-     MNG_DESCR_GenHDR | MNG_DESCR_PLTE,
-     MNG_DESCR_NOIDAT | MNG_DESCR_NOJDAT | MNG_DESCR_NOJDAA};
-#endif
-
-#ifndef MNG_SKIPCHUNK_tIME
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_time =
-    {mng_it_png, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_time,
-     mng_fields_time, (sizeof(mng_fields_time) / sizeof(mng_field_descriptor)),
-     MNG_DESCR_GLOBAL,
-     MNG_DESCR_GenHDR,
-     MNG_NULL};
-#endif
-
-/* ************************************************************************** */
-/* JNG chunks */
-
-#ifdef MNG_INCLUDE_JNG
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_jhdr =
-    {mng_it_jng, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_jhdr,
-     mng_fields_jhdr, (sizeof(mng_fields_jhdr) / sizeof(mng_field_descriptor)),
-     MNG_NULL,
-     MNG_NULL,
-     MNG_DESCR_NOIHDR | MNG_DESCR_NOBASI | MNG_DESCR_NODHDR | MNG_DESCR_NOJHDR};
-#endif
-
-#ifdef MNG_INCLUDE_JNG
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_jdaa =
-    {mng_it_jng, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_jdaa,
-     mng_fields_jdaa, (sizeof(mng_fields_jdaa) / sizeof(mng_field_descriptor)),
-     MNG_NULL,
-     MNG_DESCR_JngHDR,
-     MNG_DESCR_NOJSEP};
-#endif
-
-#ifdef MNG_INCLUDE_JNG
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_jdat =
-    {mng_it_jng, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_jdat,
-     mng_fields_jdat, (sizeof(mng_fields_jdat) / sizeof(mng_field_descriptor)),
-     MNG_DESCR_EMPTYEMBED,
-     MNG_DESCR_JngHDR,
-     MNG_NULL};
-#endif
-
-#ifdef MNG_INCLUDE_JNG
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_jsep =
-    {mng_it_jng, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_jsep,
-     MNG_NULL, 0,
-     MNG_DESCR_EMPTY | MNG_DESCR_EMPTYEMBED,
-     MNG_DESCR_JngHDR,
-     MNG_DESCR_NOJSEP};
-#endif
-
-/* ************************************************************************** */
-/* MNG chunks */
-
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_mhdr =
-    {mng_it_mng, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_mhdr,
-     mng_fields_mhdr, (sizeof(mng_fields_mhdr) / sizeof(mng_field_descriptor)),
-     MNG_NULL,
-     MNG_NULL,
-     MNG_DESCR_NOMHDR | MNG_DESCR_NOIHDR | MNG_DESCR_NOJHDR};
-
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_mend =
-    {mng_it_mng, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_mend,
-     MNG_NULL, 0,
-     MNG_DESCR_EMPTY | MNG_DESCR_EMPTYGLOBAL,
-     MNG_DESCR_MHDR,
-     MNG_NULL};
-
-#ifndef MNG_SKIPCHUNK_LOOP
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_loop =
-    {mng_it_mng, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_loop,
-     mng_fields_loop, (sizeof(mng_fields_loop) / sizeof(mng_field_descriptor)),
-     MNG_NULL,
-     MNG_DESCR_MHDR,
-     MNG_DESCR_NOIHDR | MNG_DESCR_NOBASI | MNG_DESCR_NODHDR | MNG_DESCR_NOJHDR};
-
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_endl =
-    {mng_it_mng, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_endl,
-     mng_fields_endl, (sizeof(mng_fields_endl) / sizeof(mng_field_descriptor)),
-     MNG_NULL,
-     MNG_DESCR_MHDR,
-     MNG_DESCR_NOIHDR | MNG_DESCR_NOBASI | MNG_DESCR_NODHDR | MNG_DESCR_NOJHDR};
-#endif
-
-#ifndef MNG_SKIPCHUNK_DEFI
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_defi =
-    {mng_it_mng, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_defi,
-     mng_fields_defi, (sizeof(mng_fields_defi) / sizeof(mng_field_descriptor)),
-     MNG_NULL,
-     MNG_DESCR_MHDR,
-     MNG_DESCR_NOIHDR | MNG_DESCR_NOBASI | MNG_DESCR_NODHDR | MNG_DESCR_NOJHDR};
-#endif
-
-#ifndef MNG_SKIPCHUNK_BASI
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_basi =
-    {mng_it_mng, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_basi,
-     mng_fields_basi, (sizeof(mng_fields_basi) / sizeof(mng_field_descriptor)),
-     MNG_NULL,
-     MNG_DESCR_MHDR,
-     MNG_DESCR_NOIHDR | MNG_DESCR_NOBASI | MNG_DESCR_NODHDR | MNG_DESCR_NOJHDR};
-#endif
-
-#ifndef MNG_SKIPCHUNK_CLON
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_clon =
-    {mng_it_mng, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_clon,
-     mng_fields_clon, (sizeof(mng_fields_clon) / sizeof(mng_field_descriptor)),
-     MNG_NULL,
-     MNG_DESCR_MHDR,
-     MNG_DESCR_NOIHDR | MNG_DESCR_NOBASI | MNG_DESCR_NODHDR | MNG_DESCR_NOJHDR};
-#endif
-
-#ifndef MNG_SKIPCHUNK_PAST
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_past =
-    {mng_it_mng, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_past,
-     mng_fields_past, (sizeof(mng_fields_past) / sizeof(mng_field_descriptor)),
-     MNG_NULL,
-     MNG_DESCR_MHDR,
-     MNG_DESCR_NOIHDR | MNG_DESCR_NOBASI | MNG_DESCR_NODHDR | MNG_DESCR_NOJHDR};
-#endif
-
-#ifndef MNG_SKIPCHUNK_DISC
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_disc =
-    {mng_it_mng, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_disc,
-     mng_fields_disc, (sizeof(mng_fields_disc) / sizeof(mng_field_descriptor)),
-     MNG_NULL,
-     MNG_DESCR_MHDR,
-     MNG_DESCR_NOIHDR | MNG_DESCR_NOBASI | MNG_DESCR_NODHDR | MNG_DESCR_NOJHDR};
-#endif
-
-#ifndef MNG_SKIPCHUNK_BACK
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_back =
-    {mng_it_mng, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_back,
-     mng_fields_back, (sizeof(mng_fields_back) / sizeof(mng_field_descriptor)),
-     MNG_NULL,
-     MNG_DESCR_MHDR,
-     MNG_DESCR_NOIHDR | MNG_DESCR_NOBASI | MNG_DESCR_NODHDR | MNG_DESCR_NOJHDR};
-#endif
-
-#ifndef MNG_SKIPCHUNK_FRAM
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_fram =
-    {mng_it_mng, mng_create_none, 0, offsetof(mng_fram, bEmpty),
-     MNG_NULL, MNG_NULL, mng_special_fram,
-     mng_fields_fram, (sizeof(mng_fields_fram) / sizeof(mng_field_descriptor)),
-     MNG_DESCR_EMPTY | MNG_DESCR_EMPTYGLOBAL,
-     MNG_DESCR_MHDR,
-     MNG_DESCR_NOIHDR | MNG_DESCR_NOBASI | MNG_DESCR_NODHDR | MNG_DESCR_NOJHDR};
-#endif
-
-#ifndef MNG_SKIPCHUNK_MOVE
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_move =
-    {mng_it_mng, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_move,
-     mng_fields_move, (sizeof(mng_fields_move) / sizeof(mng_field_descriptor)),
-     MNG_NULL,
-     MNG_DESCR_MHDR,
-     MNG_DESCR_NOIHDR | MNG_DESCR_NOBASI | MNG_DESCR_NODHDR | MNG_DESCR_NOJHDR};
-#endif
-
-#ifndef MNG_SKIPCHUNK_CLIP
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_clip =
-    {mng_it_mng, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_clip,
-     mng_fields_clip, (sizeof(mng_fields_clip) / sizeof(mng_field_descriptor)),
-     MNG_NULL,
-     MNG_DESCR_MHDR,
-     MNG_DESCR_NOIHDR | MNG_DESCR_NOBASI | MNG_DESCR_NODHDR | MNG_DESCR_NOJHDR};
-#endif
-
-#ifndef MNG_SKIPCHUNK_SHOW
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_show =
-    {mng_it_mng, mng_create_none, 0, offsetof(mng_show, bEmpty),
-     MNG_NULL, MNG_NULL, mng_special_show,
-     mng_fields_show, (sizeof(mng_fields_show) / sizeof(mng_field_descriptor)),
-     MNG_DESCR_EMPTY | MNG_DESCR_EMPTYGLOBAL,
-     MNG_DESCR_MHDR,
-     MNG_DESCR_NOIHDR | MNG_DESCR_NOBASI | MNG_DESCR_NODHDR | MNG_DESCR_NOJHDR};
-#endif
-
-#ifndef MNG_SKIPCHUNK_TERM
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_term =
-    {mng_it_mng, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_term,
-     mng_fields_term, (sizeof(mng_fields_term) / sizeof(mng_field_descriptor)),
-     MNG_NULL,
-     MNG_DESCR_MHDR,
-     MNG_DESCR_NOIHDR | MNG_DESCR_NOBASI | MNG_DESCR_NODHDR | MNG_DESCR_NOJHDR | MNG_DESCR_NOTERM | MNG_DESCR_NOLOOP};
-#endif
-
-#ifndef MNG_SKIPCHUNK_SAVE
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_save =
-    {mng_it_mng, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_save,
-     mng_fields_save, (sizeof(mng_fields_save) / sizeof(mng_field_descriptor)),
-     MNG_DESCR_EMPTY | MNG_DESCR_EMPTYGLOBAL,
-     MNG_DESCR_MHDR,
-     MNG_DESCR_NOSAVE | MNG_DESCR_NOIHDR | MNG_DESCR_NOBASI | MNG_DESCR_NODHDR | MNG_DESCR_NOJHDR};
-#endif
-
-#ifndef MNG_SKIPCHUNK_SEEK
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_seek =
-    {mng_it_mng, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_seek,
-     mng_fields_seek, (sizeof(mng_fields_seek) / sizeof(mng_field_descriptor)),
-     MNG_DESCR_EMPTY | MNG_DESCR_EMPTYGLOBAL,
-     MNG_DESCR_MHDR | MNG_DESCR_SAVE,
-     MNG_DESCR_NOIHDR | MNG_DESCR_NOBASI | MNG_DESCR_NODHDR | MNG_DESCR_NOJHDR};
-#endif
-
-#ifndef MNG_SKIPCHUNK_eXPI
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_expi =
-    {mng_it_mng, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_expi,
-     mng_fields_expi, (sizeof(mng_fields_expi) / sizeof(mng_field_descriptor)),
-     MNG_NULL,
-     MNG_DESCR_MHDR,
-     MNG_DESCR_NOIHDR | MNG_DESCR_NOBASI | MNG_DESCR_NODHDR | MNG_DESCR_NOJHDR};
-#endif
-
-#ifndef MNG_SKIPCHUNK_fPRI
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_fpri =
-    {mng_it_mng, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_fpri,
-     mng_fields_fpri, (sizeof(mng_fields_fpri) / sizeof(mng_field_descriptor)),
-     MNG_NULL,
-     MNG_DESCR_MHDR,
-     MNG_DESCR_NOIHDR | MNG_DESCR_NOBASI | MNG_DESCR_NODHDR | MNG_DESCR_NOJHDR};
-#endif
-
-#ifndef MNG_SKIPCHUNK_nEED
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_need =
-    {mng_it_mng, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_need,
-     mng_fields_need, (sizeof(mng_fields_need) / sizeof(mng_field_descriptor)),
-     MNG_NULL,
-     MNG_DESCR_MHDR,
-     MNG_DESCR_NOIHDR | MNG_DESCR_NOBASI | MNG_DESCR_NODHDR | MNG_DESCR_NOJHDR};
-#endif
-
-#ifndef MNG_SKIPCHUNK_pHYg
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_phyg =
-    {mng_it_mng, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_phyg,
-     mng_fields_phyg, (sizeof(mng_fields_phyg) / sizeof(mng_field_descriptor)),
-     MNG_NULL,
-     MNG_DESCR_MHDR,
-     MNG_DESCR_NOIHDR | MNG_DESCR_NOBASI | MNG_DESCR_NODHDR | MNG_DESCR_NOJHDR};
-#endif
-
-#ifndef MNG_NO_DELTA_PNG
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_dhdr =
-    {mng_it_mng, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_dhdr,
-     mng_fields_dhdr, (sizeof(mng_fields_dhdr) / sizeof(mng_field_descriptor)),
-     MNG_NULL,
-     MNG_DESCR_MHDR,
-     MNG_DESCR_NOIHDR | MNG_DESCR_NOBASI | MNG_DESCR_NODHDR | MNG_DESCR_NOJHDR};
-#endif
-
-#ifndef MNG_NO_DELTA_PNG
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_prom =
-    {mng_it_mng, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_prom,
-     mng_fields_prom, (sizeof(mng_fields_prom) / sizeof(mng_field_descriptor)),
-     MNG_NULL,
-     MNG_DESCR_MHDR | MNG_DESCR_DHDR,
-     MNG_NULL};
-#endif
-
-#ifndef MNG_NO_DELTA_PNG
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_ipng =
-    {mng_it_mng, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_ipng,
-     MNG_NULL, 0,
-     MNG_DESCR_EMPTY | MNG_DESCR_EMPTYEMBED,
-     MNG_DESCR_MHDR | MNG_DESCR_DHDR,
-     MNG_NULL};
-#endif
-
-#ifndef MNG_NO_DELTA_PNG
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_pplt =
-    {mng_it_mng, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_pplt,
-     mng_fields_pplt, (sizeof(mng_fields_pplt) / sizeof(mng_field_descriptor)),
-     MNG_NULL,
-     MNG_DESCR_MHDR | MNG_DESCR_DHDR,
-     MNG_NULL};
-#endif
-
-#ifndef MNG_NO_DELTA_PNG
-#ifdef MNG_INCLUDE_JNG
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_ijng =
-    {mng_it_mng, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_ijng,
-     MNG_NULL, 0,
-     MNG_DESCR_EMPTY | MNG_DESCR_EMPTYEMBED,
-     MNG_DESCR_MHDR | MNG_DESCR_DHDR,
-     MNG_NULL};
-#endif
-#endif
-
-#ifndef MNG_NO_DELTA_PNG
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_drop =
-    {mng_it_mng, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_drop,
-     mng_fields_drop, (sizeof(mng_fields_drop) / sizeof(mng_field_descriptor)),
-     MNG_NULL,
-     MNG_DESCR_MHDR | MNG_DESCR_DHDR,
-     MNG_NULL};
-#endif
-
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_SKIPCHUNK_DBYK
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_dbyk =
-    {mng_it_mng, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_dbyk,
-     mng_fields_dbyk, (sizeof(mng_fields_dbyk) / sizeof(mng_field_descriptor)),
-     MNG_DESCR_EMPTY | MNG_DESCR_EMPTYEMBED,
-     MNG_DESCR_MHDR | MNG_DESCR_DHDR,
-     MNG_NULL};
-#endif
-#endif
-
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_SKIPCHUNK_ORDR
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_ordr =
-    {mng_it_mng, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_ordr,
-     mng_fields_ordr, (sizeof(mng_fields_ordr) / sizeof(mng_field_descriptor)),
-     MNG_NULL,
-     MNG_DESCR_MHDR | MNG_DESCR_DHDR,
-     MNG_NULL};
-#endif
-#endif
-
-#ifndef MNG_SKIPCHUNK_MAGN
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_magn =
-    {mng_it_mng, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_magn,
-     mng_fields_magn, (sizeof(mng_fields_magn) / sizeof(mng_field_descriptor)),
-     MNG_NULL,
-     MNG_DESCR_MHDR,
-     MNG_DESCR_NOIHDR | MNG_DESCR_NOBASI | MNG_DESCR_NODHDR | MNG_DESCR_NOJHDR};
-#endif
-
-#ifndef MNG_SKIPCHUNK_evNT
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_evnt =
-    {mng_it_mng, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_evnt,
-     mng_fields_evnt, (sizeof(mng_fields_evnt) / sizeof(mng_field_descriptor)),
-     MNG_NULL,
-     MNG_DESCR_MHDR,
-     MNG_DESCR_NOSAVE};
-#endif
-
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_mpng =
-    {mng_it_mpng, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_mpng,
-     mng_fields_mpng, (sizeof(mng_fields_mpng) / sizeof(mng_field_descriptor)),
-     MNG_NULL,
-     MNG_NULL,
-     MNG_DESCR_NOMHDR | MNG_DESCR_NOIDAT | MNG_DESCR_NOJDAT};
-#endif
-
-#ifdef MNG_INCLUDE_ANG_PROPOSAL
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_ahdr =
-    {mng_it_ang, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_ahdr,
-     mng_fields_ahdr, (sizeof(mng_fields_ahdr) / sizeof(mng_field_descriptor)),
-     MNG_NULL,
-     MNG_DESCR_IHDR,
-     MNG_DESCR_NOMHDR | MNG_DESCR_NOJHDR | MNG_DESCR_NOIDAT};
-
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_adat =
-    {mng_it_ang, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_adat,
-     mng_fields_adat, (sizeof(mng_fields_adat) / sizeof(mng_field_descriptor)),
-     MNG_NULL,
-     MNG_DESCR_IHDR,
-     MNG_DESCR_NOMHDR | MNG_DESCR_NOJHDR};
-#endif
-
-/* ************************************************************************** */
-/* ************************************************************************** */
-/* the good ol' unknown babe */
-
-MNG_LOCAL mng_chunk_descriptor mng_chunk_descr_unknown =
-    {mng_it_png, mng_create_none, 0, 0,
-     MNG_NULL, MNG_NULL, mng_special_unknown,
-     mng_fields_unknown, (sizeof(mng_fields_unknown) / sizeof(mng_field_descriptor)),
-     MNG_DESCR_EMPTY | MNG_DESCR_EMPTYEMBED,
-     MNG_NULL,
-     MNG_NULL};
-
-/* ************************************************************************** */
-/* ************************************************************************** */
-
-MNG_LOCAL mng_chunk_header mng_chunk_unknown =
-    {MNG_UINT_HUH, mng_init_general, mng_free_unknown,
-     mng_read_general, mng_write_unknown, mng_assign_unknown,
-     0, 0, sizeof(mng_unknown_chunk), &mng_chunk_descr_unknown};
-
-/* ************************************************************************** */
-
-  /* the table-idea & binary search code was adapted from
-     libpng 1.1.0 (pngread.c) */
-  /* NOTE1: the table must remain sorted by chunkname, otherwise the binary
-     search will break !!! (ps. watch upper-/lower-case chunknames !!) */
-  /* NOTE2: the layout must remain equal to the header part of all the
-     chunk-structures (yes, that means even the pNext and pPrev fields;
-     it's wasting a bit of space, but hey, the code is a lot easier) */
-
-MNG_LOCAL mng_chunk_header mng_chunk_table [] =
-  {
-#ifndef MNG_SKIPCHUNK_BACK
-    {MNG_UINT_BACK, mng_init_general, mng_free_general, mng_read_general, mng_write_back, mng_assign_general, 0, 0, sizeof(mng_back), &mng_chunk_descr_back},
-#endif
-#ifndef MNG_SKIPCHUNK_BASI
-    {MNG_UINT_BASI, mng_init_general, mng_free_general, mng_read_general, mng_write_basi, mng_assign_general, 0, 0, sizeof(mng_basi), &mng_chunk_descr_basi},
-#endif
-#ifndef MNG_SKIPCHUNK_CLIP
-    {MNG_UINT_CLIP, mng_init_general, mng_free_general, mng_read_general, mng_write_clip, mng_assign_general, 0, 0, sizeof(mng_clip), &mng_chunk_descr_clip},
-#endif
-#ifndef MNG_SKIPCHUNK_CLON
-    {MNG_UINT_CLON, mng_init_general, mng_free_general, mng_read_general, mng_write_clon, mng_assign_general, 0, 0, sizeof(mng_clon), &mng_chunk_descr_clon},
-#endif
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_SKIPCHUNK_DBYK
-    {MNG_UINT_DBYK, mng_init_general, mng_free_dbyk,    mng_read_general, mng_write_dbyk, mng_assign_dbyk,    0, 0, sizeof(mng_dbyk), &mng_chunk_descr_dbyk},
-#endif
-#endif
-#ifndef MNG_SKIPCHUNK_DEFI
-    {MNG_UINT_DEFI, mng_init_general, mng_free_general, mng_read_general, mng_write_defi, mng_assign_general, 0, 0, sizeof(mng_defi), &mng_chunk_descr_defi},
-#endif
-#ifndef MNG_NO_DELTA_PNG
-    {MNG_UINT_DHDR, mng_init_general, mng_free_general, mng_read_general, mng_write_dhdr, mng_assign_general, 0, 0, sizeof(mng_dhdr), &mng_chunk_descr_dhdr},
-#endif
-#ifndef MNG_SKIPCHUNK_DISC
-    {MNG_UINT_DISC, mng_init_general, mng_free_disc,    mng_read_general, mng_write_disc, mng_assign_disc,    0, 0, sizeof(mng_disc), &mng_chunk_descr_disc},
-#endif
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_SKIPCHUNK_DROP
-    {MNG_UINT_DROP, mng_init_general, mng_free_drop,    mng_read_general, mng_write_drop, mng_assign_drop,    0, 0, sizeof(mng_drop), &mng_chunk_descr_drop},
-#endif
-#endif
-#ifndef MNG_SKIPCHUNK_LOOP
-    {MNG_UINT_ENDL, mng_init_general, mng_free_general, mng_read_general, mng_write_endl, mng_assign_general, 0, 0, sizeof(mng_endl), &mng_chunk_descr_endl},
-#endif
-#ifndef MNG_SKIPCHUNK_FRAM
-    {MNG_UINT_FRAM, mng_init_general, mng_free_fram,    mng_read_general, mng_write_fram, mng_assign_fram,    0, 0, sizeof(mng_fram), &mng_chunk_descr_fram},
-#endif
-    {MNG_UINT_IDAT, mng_init_general, mng_free_idat,    mng_read_general, mng_write_idat, mng_assign_idat,    0, 0, sizeof(mng_idat), &mng_chunk_descr_idat},  /* 12-th element! */
-    {MNG_UINT_IEND, mng_init_general, mng_free_general, mng_read_general, mng_write_iend, mng_assign_general, 0, 0, sizeof(mng_iend), &mng_chunk_descr_iend},
-    {MNG_UINT_IHDR, mng_init_general, mng_free_general, mng_read_general, mng_write_ihdr, mng_assign_general, 0, 0, sizeof(mng_ihdr), &mng_chunk_descr_ihdr},
-#ifndef MNG_NO_DELTA_PNG
-#ifdef MNG_INCLUDE_JNG
-    {MNG_UINT_IJNG, mng_init_general, mng_free_general, mng_read_general, mng_write_ijng, mng_assign_general, 0, 0, sizeof(mng_ijng), &mng_chunk_descr_ijng},
-#endif
-    {MNG_UINT_IPNG, mng_init_general, mng_free_general, mng_read_general, mng_write_ipng, mng_assign_general, 0, 0, sizeof(mng_ipng), &mng_chunk_descr_ipng},
-#endif
-#ifdef MNG_INCLUDE_JNG
-    {MNG_UINT_JDAA, mng_init_general, mng_free_jdaa,    mng_read_general, mng_write_jdaa, mng_assign_jdaa,    0, 0, sizeof(mng_jdaa), &mng_chunk_descr_jdaa},
-    {MNG_UINT_JDAT, mng_init_general, mng_free_jdat,    mng_read_general, mng_write_jdat, mng_assign_jdat,    0, 0, sizeof(mng_jdat), &mng_chunk_descr_jdat},
-    {MNG_UINT_JHDR, mng_init_general, mng_free_general, mng_read_general, mng_write_jhdr, mng_assign_general, 0, 0, sizeof(mng_jhdr), &mng_chunk_descr_jhdr},
-    {MNG_UINT_JSEP, mng_init_general, mng_free_general, mng_read_general, mng_write_jsep, mng_assign_general, 0, 0, sizeof(mng_jsep), &mng_chunk_descr_jsep},
-    {MNG_UINT_JdAA, mng_init_general, mng_free_jdaa,    mng_read_general, mng_write_jdaa, mng_assign_jdaa,    0, 0, sizeof(mng_jdaa), &mng_chunk_descr_jdaa},
-#endif
-#ifndef MNG_SKIPCHUNK_LOOP
-    {MNG_UINT_LOOP, mng_init_general, mng_free_loop,    mng_read_general, mng_write_loop, mng_assign_loop,    0, 0, sizeof(mng_loop), &mng_chunk_descr_loop},
-#endif
-#ifndef MNG_SKIPCHUNK_MAGN
-    {MNG_UINT_MAGN, mng_init_general, mng_free_general, mng_read_general, mng_write_magn, mng_assign_general, 0, 0, sizeof(mng_magn), &mng_chunk_descr_magn},
-#endif
-    {MNG_UINT_MEND, mng_init_general, mng_free_general, mng_read_general, mng_write_mend, mng_assign_general, 0, 0, sizeof(mng_mend), &mng_chunk_descr_mend},
-    {MNG_UINT_MHDR, mng_init_general, mng_free_general, mng_read_general, mng_write_mhdr, mng_assign_general, 0, 0, sizeof(mng_mhdr), &mng_chunk_descr_mhdr},
-#ifndef MNG_SKIPCHUNK_MOVE
-    {MNG_UINT_MOVE, mng_init_general, mng_free_general, mng_read_general, mng_write_move, mng_assign_general, 0, 0, sizeof(mng_move), &mng_chunk_descr_move},
-#endif
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_SKIPCHUNK_ORDR
-    {MNG_UINT_ORDR, mng_init_general, mng_free_ordr,    mng_read_general, mng_write_ordr, mng_assign_ordr,    0, 0, sizeof(mng_ordr), &mng_chunk_descr_ordr},
-#endif
-#endif
-#ifndef MNG_SKIPCHUNK_PAST
-    {MNG_UINT_PAST, mng_init_general, mng_free_past,    mng_read_general, mng_write_past, mng_assign_past,    0, 0, sizeof(mng_past), &mng_chunk_descr_past},
-#endif
-    {MNG_UINT_PLTE, mng_init_general, mng_free_general, mng_read_general, mng_write_plte, mng_assign_general, 0, 0, sizeof(mng_plte), &mng_chunk_descr_plte},
-#ifndef MNG_NO_DELTA_PNG
-    {MNG_UINT_PPLT, mng_init_general, mng_free_general, mng_read_general, mng_write_pplt, mng_assign_general, 0, 0, sizeof(mng_pplt), &mng_chunk_descr_pplt},
-    {MNG_UINT_PROM, mng_init_general, mng_free_general, mng_read_general, mng_write_prom, mng_assign_general, 0, 0, sizeof(mng_prom), &mng_chunk_descr_prom},
-#endif
-#ifndef MNG_SKIPCHUNK_SAVE
-    {MNG_UINT_SAVE, mng_init_general, mng_free_save,    mng_read_general, mng_write_save, mng_assign_save,    0, 0, sizeof(mng_save), &mng_chunk_descr_save},
-#endif
-#ifndef MNG_SKIPCHUNK_SEEK
-    {MNG_UINT_SEEK, mng_init_general, mng_free_seek,    mng_read_general, mng_write_seek, mng_assign_seek,    0, 0, sizeof(mng_seek), &mng_chunk_descr_seek},
-#endif
-#ifndef MNG_SKIPCHUNK_SHOW
-    {MNG_UINT_SHOW, mng_init_general, mng_free_general, mng_read_general, mng_write_show, mng_assign_general, 0, 0, sizeof(mng_show), &mng_chunk_descr_show},
-#endif
-#ifndef MNG_SKIPCHUNK_TERM
-    {MNG_UINT_TERM, mng_init_general, mng_free_general, mng_read_general, mng_write_term, mng_assign_general, 0, 0, sizeof(mng_term), &mng_chunk_descr_term},
-#endif
-#ifdef MNG_INCLUDE_ANG_PROPOSAL
-    {MNG_UINT_adAT, mng_init_general, mng_free_adat,    mng_read_general, mng_write_adat, mng_assign_adat,    0, 0, sizeof(mng_adat), &mng_chunk_descr_adat},
-    {MNG_UINT_ahDR, mng_init_general, mng_free_general, mng_read_general, mng_write_ahdr, mng_assign_ahdr,    0, 0, sizeof(mng_ahdr), &mng_chunk_descr_ahdr},
-#endif
-#ifndef MNG_SKIPCHUNK_bKGD
-    {MNG_UINT_bKGD, mng_init_general, mng_free_general, mng_read_general, mng_write_bkgd, mng_assign_general, 0, 0, sizeof(mng_bkgd), &mng_chunk_descr_bkgd},
-#endif
-#ifndef MNG_SKIPCHUNK_cHRM
-    {MNG_UINT_cHRM, mng_init_general, mng_free_general, mng_read_general, mng_write_chrm, mng_assign_general, 0, 0, sizeof(mng_chrm), &mng_chunk_descr_chrm},
-#endif
-#ifndef MNG_SKIPCHUNK_eXPI
-    {MNG_UINT_eXPI, mng_init_general, mng_free_expi,    mng_read_general, mng_write_expi, mng_assign_expi,    0, 0, sizeof(mng_expi), &mng_chunk_descr_expi},
-#endif
-#ifndef MNG_SKIPCHUNK_evNT
-    {MNG_UINT_evNT, mng_init_general, mng_free_evnt,    mng_read_general, mng_write_evnt, mng_assign_evnt,    0, 0, sizeof(mng_evnt), &mng_chunk_descr_evnt},
-#endif
-#ifndef MNG_SKIPCHUNK_fPRI
-    {MNG_UINT_fPRI, mng_init_general, mng_free_general, mng_read_general, mng_write_fpri, mng_assign_general, 0, 0, sizeof(mng_fpri), &mng_chunk_descr_fpri},
-#endif
-#ifndef MNG_SKIPCHUNK_gAMA
-    {MNG_UINT_gAMA, mng_init_general, mng_free_general, mng_read_general, mng_write_gama, mng_assign_general, 0, 0, sizeof(mng_gama), &mng_chunk_descr_gama},
-#endif
-#ifndef MNG_SKIPCHUNK_hIST
-    {MNG_UINT_hIST, mng_init_general, mng_free_general, mng_read_general, mng_write_hist, mng_assign_general, 0, 0, sizeof(mng_hist), &mng_chunk_descr_hist},
-#endif
-#ifndef MNG_SKIPCHUNK_iCCP
-    {MNG_UINT_iCCP, mng_init_general, mng_free_iccp,    mng_read_general, mng_write_iccp, mng_assign_iccp,    0, 0, sizeof(mng_iccp), &mng_chunk_descr_iccp},
-#endif
-#ifndef MNG_SKIPCHUNK_iTXt
-    {MNG_UINT_iTXt, mng_init_general, mng_free_itxt,    mng_read_general, mng_write_itxt, mng_assign_itxt,    0, 0, sizeof(mng_itxt), &mng_chunk_descr_itxt},
-#endif
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-    {MNG_UINT_mpNG, mng_init_general, mng_free_mpng,    mng_read_general, mng_write_mpng, mng_assign_mpng,    0, 0, sizeof(mng_mpng), &mng_chunk_descr_mpng},
-#endif
-#ifndef MNG_SKIPCHUNK_nEED
-    {MNG_UINT_nEED, mng_init_general, mng_free_need,    mng_read_general, mng_write_need, mng_assign_need,    0, 0, sizeof(mng_need), &mng_chunk_descr_need},
-#endif
-/* TODO:     {MNG_UINT_oFFs, 0, 0, 0, 0, 0, 0},  */
-/* TODO:     {MNG_UINT_pCAL, 0, 0, 0, 0, 0, 0},  */
-#ifndef MNG_SKIPCHUNK_pHYg
-    {MNG_UINT_pHYg, mng_init_general, mng_free_general, mng_read_general, mng_write_phyg, mng_assign_general, 0, 0, sizeof(mng_phyg), &mng_chunk_descr_phyg},
-#endif
-#ifndef MNG_SKIPCHUNK_pHYs
-    {MNG_UINT_pHYs, mng_init_general, mng_free_general, mng_read_general, mng_write_phys, mng_assign_general, 0, 0, sizeof(mng_phys), &mng_chunk_descr_phys},
-#endif
-#ifndef MNG_SKIPCHUNK_sBIT
-    {MNG_UINT_sBIT, mng_init_general, mng_free_general, mng_read_general, mng_write_sbit, mng_assign_general, 0, 0, sizeof(mng_sbit), &mng_chunk_descr_sbit},
-#endif
-/* TODO:     {MNG_UINT_sCAL, 0, 0, 0, 0, 0, 0},  */
-#ifndef MNG_SKIPCHUNK_sPLT
-    {MNG_UINT_sPLT, mng_init_general, mng_free_splt,    mng_read_general, mng_write_splt, mng_assign_splt,    0, 0, sizeof(mng_splt), &mng_chunk_descr_splt},
-#endif
-    {MNG_UINT_sRGB, mng_init_general, mng_free_general, mng_read_general, mng_write_srgb, mng_assign_general, 0, 0, sizeof(mng_srgb), &mng_chunk_descr_srgb},
-#ifndef MNG_SKIPCHUNK_tEXt
-    {MNG_UINT_tEXt, mng_init_general, mng_free_text,    mng_read_general, mng_write_text, mng_assign_text,    0, 0, sizeof(mng_text), &mng_chunk_descr_text},
-#endif
-#ifndef MNG_SKIPCHUNK_tIME
-    {MNG_UINT_tIME, mng_init_general, mng_free_general, mng_read_general, mng_write_time, mng_assign_general, 0, 0, sizeof(mng_time), &mng_chunk_descr_time},
-#endif
-    {MNG_UINT_tRNS, mng_init_general, mng_free_general, mng_read_general, mng_write_trns, mng_assign_general, 0, 0, sizeof(mng_trns), &mng_chunk_descr_trns},
-#ifndef MNG_SKIPCHUNK_zTXt
-    {MNG_UINT_zTXt, mng_init_general, mng_free_ztxt,    mng_read_general, mng_write_ztxt, mng_assign_ztxt,    0, 0, sizeof(mng_ztxt), &mng_chunk_descr_ztxt},
-#endif
-  };
-
-/* ************************************************************************** */
-/* ************************************************************************** */
-
-void mng_get_chunkheader (mng_chunkid       iChunkname,
-                          mng_chunk_headerp pResult)
-{
-                                       /* binary search variables */
-  mng_int32         iTop, iLower, iUpper, iMiddle;
-  mng_chunk_headerp pEntry;            /* pointer to found entry */
-                                       /* determine max index of table */
-  iTop = (sizeof (mng_chunk_table) / sizeof (mng_chunk_table [0])) - 1;
-
-  /* binary search; with 54 chunks, worst-case is 7 comparisons */
-  iLower  = 0;
-#ifndef MNG_NO_DELTA_PNG
-  iMiddle = 11;                        /* start with the IDAT entry */
-#else
-  iMiddle = 8;
-#endif
-  iUpper  = iTop;
-  pEntry  = 0;                         /* no goods yet! */
-
-  do                                   /* the binary search itself */
-    {
-      if (mng_chunk_table [iMiddle].iChunkname < iChunkname)
-        iLower = iMiddle + 1;
-      else if (mng_chunk_table [iMiddle].iChunkname > iChunkname)
-        iUpper = iMiddle - 1;
-      else
-      {
-        pEntry = &mng_chunk_table [iMiddle];
-        break;
-      }
-      iMiddle = (iLower + iUpper) >> 1;
-    }
-  while (iLower <= iUpper);
-
-  if (!pEntry)                         /* unknown chunk ? */
-    pEntry = &mng_chunk_unknown;       /* make it so! */
-
-  MNG_COPY (pResult, pEntry, sizeof(mng_chunk_header));
-
-  return;
-}
-
-/* ************************************************************************** */
-/* ************************************************************************** */
-/* PNG chunks */
-
-MNG_C_SPECIALFUNC (mng_special_ihdr)
-{
-  pData->bHasIHDR      = MNG_TRUE;     /* indicate IHDR is present */
-                                       /* and store interesting fields */
-  if ((!pData->bHasDHDR) || (pData->iDeltatype == MNG_DELTATYPE_NOCHANGE))
-  {
-    pData->iDatawidth  = ((mng_ihdrp)pChunk)->iWidth;
-    pData->iDataheight = ((mng_ihdrp)pChunk)->iHeight;
-  }
-
-  pData->iBitdepth     = ((mng_ihdrp)pChunk)->iBitdepth;
-  pData->iColortype    = ((mng_ihdrp)pChunk)->iColortype;
-  pData->iCompression  = ((mng_ihdrp)pChunk)->iCompression;
-  pData->iFilter       = ((mng_ihdrp)pChunk)->iFilter;
-  pData->iInterlace    = ((mng_ihdrp)pChunk)->iInterlace;
-
-#if defined(MNG_NO_1_2_4BIT_SUPPORT) || defined(MNG_NO_16BIT_SUPPORT)
-  pData->iPNGmult = 1;
-  pData->iPNGdepth = pData->iBitdepth;
-#endif
-
-#ifdef MNG_NO_1_2_4BIT_SUPPORT
-  if (pData->iBitdepth < 8)
-      pData->iBitdepth = 8;
-#endif
-
-#ifdef MNG_NO_16BIT_SUPPORT
-  if (pData->iBitdepth > 8)
-    {
-      pData->iBitdepth = 8;
-      pData->iPNGmult = 2;
-    }
-#endif
-
-  if ((pData->iBitdepth !=  8)      /* parameter validity checks */
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-      && (pData->iBitdepth !=  1) &&
-      (pData->iBitdepth !=  2) &&
-      (pData->iBitdepth !=  4)
-#endif
-#ifndef MNG_NO_16BIT_SUPPORT
-      && (pData->iBitdepth != 16)   
-#endif
-      )
-    MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
-
-  if ((pData->iColortype != MNG_COLORTYPE_GRAY   ) &&
-      (pData->iColortype != MNG_COLORTYPE_RGB    ) &&
-      (pData->iColortype != MNG_COLORTYPE_INDEXED) &&
-      (pData->iColortype != MNG_COLORTYPE_GRAYA  ) &&
-      (pData->iColortype != MNG_COLORTYPE_RGBA   )    )
-    MNG_ERROR (pData, MNG_INVALIDCOLORTYPE);
-
-  if ((pData->iColortype == MNG_COLORTYPE_INDEXED) && (pData->iBitdepth > 8))
-    MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
-
-  if (((pData->iColortype == MNG_COLORTYPE_RGB    ) ||
-       (pData->iColortype == MNG_COLORTYPE_GRAYA  ) ||
-       (pData->iColortype == MNG_COLORTYPE_RGBA   )    ) &&
-      (pData->iBitdepth < 8                            )    )
-    MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
-
-  if (pData->iCompression != MNG_COMPRESSION_DEFLATE)
-    MNG_ERROR (pData, MNG_INVALIDCOMPRESS);
-
-#if defined(FILTER192) || defined(FILTER193)
-  if ((pData->iFilter != MNG_FILTER_ADAPTIVE ) &&
-#if defined(FILTER192) && defined(FILTER193)
-      (pData->iFilter != MNG_FILTER_DIFFERING) &&
-      (pData->iFilter != MNG_FILTER_NOFILTER )    )
-#else
-#ifdef FILTER192
-      (pData->iFilter != MNG_FILTER_DIFFERING)    )
-#else
-      (pData->iFilter != MNG_FILTER_NOFILTER )    )
-#endif
-#endif
-    MNG_ERROR (pData, MNG_INVALIDFILTER);
-#else
-  if (pData->iFilter)
-    MNG_ERROR (pData, MNG_INVALIDFILTER);
-#endif
-
-  if ((pData->iInterlace != MNG_INTERLACE_NONE ) &&
-      (pData->iInterlace != MNG_INTERLACE_ADAM7)    )
-    MNG_ERROR (pData, MNG_INVALIDINTERLACE);
-
-#ifdef MNG_SUPPORT_DISPLAY 
-#ifndef MNG_NO_DELTA_PNG
-  if (pData->bHasDHDR)                 /* check the colortype for delta-images ! */
-  {
-    mng_imagedatap pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
-
-    if (pData->iColortype != pBuf->iColortype)
-    {
-      if ( ( (pData->iColortype != MNG_COLORTYPE_INDEXED) ||
-             (pBuf->iColortype  == MNG_COLORTYPE_GRAY   )    ) &&
-           ( (pData->iColortype != MNG_COLORTYPE_GRAY   ) ||
-             (pBuf->iColortype  == MNG_COLORTYPE_INDEXED)    )    )
-        MNG_ERROR (pData, MNG_INVALIDCOLORTYPE);
-    }
-  }
-#endif
-#endif
-
-  if (!pData->bHasheader)              /* first chunk ? */
-  {
-    pData->bHasheader = MNG_TRUE;      /* we've got a header */
-    pData->eImagetype = mng_it_png;    /* then this must be a PNG */
-    pData->iWidth     = pData->iDatawidth;
-    pData->iHeight    = pData->iDataheight;
-                                       /* predict alpha-depth ! */
-    if ((pData->iColortype == MNG_COLORTYPE_GRAYA  ) ||
-        (pData->iColortype == MNG_COLORTYPE_RGBA   )    )
-      pData->iAlphadepth = pData->iBitdepth;
-    else
-    if (pData->iColortype == MNG_COLORTYPE_INDEXED)
-      pData->iAlphadepth = 8;          /* worst case scenario */
-    else
-      pData->iAlphadepth = 1;  /* Possible tRNS cheap binary transparency */
-                                       /* fits on maximum canvas ? */
-    if ((pData->iWidth > pData->iMaxwidth) || (pData->iHeight > pData->iMaxheight))
-      MNG_WARNING (pData, MNG_IMAGETOOLARGE);
-
-#if !defined(MNG_INCLUDE_MPNG_PROPOSAL) || !defined(MNG_SUPPORT_DISPLAY)
-    if (pData->fProcessheader)         /* inform the app ? */
-      if (!pData->fProcessheader (((mng_handle)pData), pData->iWidth, pData->iHeight))
-        MNG_ERROR (pData, MNG_APPMISCERROR);
-#endif
-  }
-
-  if (!pData->bHasDHDR)
-    pData->iImagelevel++;              /* one level deeper */
-
-#ifdef MNG_SUPPORT_DISPLAY
-  return mng_process_display_ihdr (pData);
-#else
-  return MNG_NOERROR;                 
-#endif /* MNG_SUPPORT_DISPLAY */
-}
-
-/* ************************************************************************** */
-
-MNG_F_SPECIALFUNC (mng_debunk_plte)
-{
-  mng_pltep  pPLTE    = (mng_pltep)pChunk;
-  mng_uint32 iRawlen  = *piRawlen;
-  mng_uint8p pRawdata = *ppRawdata;
-                                       /* length must be multiple of 3 */
-  if (((iRawlen % 3) != 0) || (iRawlen > 768))
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-                                       /* this is the exact length */
-  pPLTE->iEntrycount = iRawlen / 3;
-
-  MNG_COPY (pPLTE->aEntries, pRawdata, iRawlen);
-
-  *piRawlen = 0;
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-MNG_C_SPECIALFUNC (mng_special_plte)
-{                                      /* multiple PLTE only inside BASI */
-  if ((pData->bHasPLTE) && (!pData->bHasBASI))
-    MNG_ERROR (pData, MNG_MULTIPLEERROR);
-
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-  {                                    /* only allowed for indexed-color or
-                                          rgb(a)-color! */
-    if ((pData->iColortype != MNG_COLORTYPE_RGB    ) &&
-        (pData->iColortype != MNG_COLORTYPE_INDEXED) &&
-        (pData->iColortype != MNG_COLORTYPE_RGBA   )   )
-      MNG_ERROR (pData, MNG_CHUNKNOTALLOWED);
-                                       /* empty only allowed if global present */
-    if ((((mng_pltep)pChunk)->bEmpty) && (!pData->bHasglobalPLTE))
-      MNG_ERROR (pData, MNG_CANNOTBEEMPTY);
-  }
-  else
-  {
-    if (((mng_pltep)pChunk)->bEmpty)   /* cannot be empty as global! */
-      MNG_ERROR (pData, MNG_CANNOTBEEMPTY);
-  }
-
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-    pData->bHasPLTE = MNG_TRUE;        /* got it! */
-  else
-    pData->bHasglobalPLTE = MNG_TRUE;
-
-  pData->iPLTEcount = ((mng_pltep)pChunk)->iEntrycount;
-
-#ifdef MNG_SUPPORT_DISPLAY
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-  {
-    mng_imagep     pImage;
-    mng_imagedatap pBuf;
-
-#ifndef MNG_NO_DELTA_PNG
-    if (pData->bHasDHDR)               /* processing delta-image ? */
-    {                                  /* store in object 0 !!! */
-      pImage           = (mng_imagep)pData->pObjzero;
-      pBuf             = pImage->pImgbuf;
-      pBuf->bHasPLTE   = MNG_TRUE;     /* it's definitely got a PLTE now */
-      pBuf->iPLTEcount = ((mng_pltep)pChunk)->iEntrycount;
-      MNG_COPY (pBuf->aPLTEentries, ((mng_pltep)pChunk)->aEntries,
-                sizeof (pBuf->aPLTEentries));
-    }
-    else
-#endif
-    {                                  /* get the current object */
-      pImage = (mng_imagep)pData->pCurrentobj;
-      if (!pImage)                     /* no object then dump it in obj 0 */
-        pImage = (mng_imagep)pData->pObjzero;
-
-      pBuf = pImage->pImgbuf;          /* address the object buffer */
-      pBuf->bHasPLTE = MNG_TRUE;       /* and tell it it's got a PLTE now */
-
-      if (((mng_pltep)pChunk)->bEmpty) /* if empty, inherit from global */
-      {
-        pBuf->iPLTEcount = pData->iGlobalPLTEcount;
-        MNG_COPY (pBuf->aPLTEentries, pData->aGlobalPLTEentries,
-                  sizeof (pBuf->aPLTEentries));
-
-        if (pData->bHasglobalTRNS)     /* also copy global tRNS ? */
-        {
-          mng_uint32 iRawlen2  = pData->iGlobalTRNSrawlen;
-          mng_uint8p pRawdata2 = (mng_uint8p)(pData->aGlobalTRNSrawdata);
-                                       /* indicate tRNS available */
-          pBuf->bHasTRNS = MNG_TRUE;
-                                       /* global length oke ? */
-          if ((iRawlen2 == 0) || (iRawlen2 > pBuf->iPLTEcount))
-            MNG_ERROR (pData, MNG_GLOBALLENGTHERR);
-                                       /* copy it */
-          pBuf->iTRNScount = iRawlen2;
-          MNG_COPY (pBuf->aTRNSentries, pRawdata2, iRawlen2);
-        }
-      }
-      else
-      {                                /* store fields for future reference */
-        pBuf->iPLTEcount = ((mng_pltep)pChunk)->iEntrycount;
-        MNG_COPY (pBuf->aPLTEentries, ((mng_pltep)pChunk)->aEntries,
-                  sizeof (pBuf->aPLTEentries));
-      }
-    }
-  }
-  else                                 /* store as global */
-  {
-    pData->iGlobalPLTEcount = ((mng_pltep)pChunk)->iEntrycount;
-    MNG_COPY (pData->aGlobalPLTEentries, ((mng_pltep)pChunk)->aEntries,
-              sizeof (pData->aGlobalPLTEentries));
-                                       /* create an animation object */
-    return mng_create_ani_plte (pData);
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-  return MNG_NOERROR;                  /* done */
-}
-
-/* ************************************************************************** */
-
-MNG_C_SPECIALFUNC (mng_special_idat)
-{
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasJHDR) &&
-      (pData->iJHDRalphacompression != MNG_COMPRESSION_DEFLATE))
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-#endif
-                                       /* not allowed for deltatype NO_CHANGE */
-#ifndef MNG_NO_DELTA_PNG
-  if ((pData->bHasDHDR) && ((pData->iDeltatype == MNG_DELTATYPE_NOCHANGE)))
-    MNG_ERROR (pData, MNG_CHUNKNOTALLOWED);
-#endif
-                                       /* can only be empty in BASI-block! */
-  if ((((mng_idatp)pChunk)->bEmpty) && (!pData->bHasBASI))
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-                                       /* indexed-color requires PLTE */
-  if ((pData->bHasIHDR) && (pData->iColortype == 3) && (!pData->bHasPLTE))
-    MNG_ERROR (pData, MNG_PLTEMISSING);
-
-  pData->bHasIDAT = MNG_TRUE;          /* got some IDAT now, don't we */
-
-  return MNG_NOERROR;                  /* done */
-}
-
-/* ************************************************************************** */
-
-MNG_C_SPECIALFUNC (mng_special_iend)
-{                                      /* IHDR-block requires IDAT */
-  if ((pData->bHasIHDR) && (!pData->bHasIDAT))
-    MNG_ERROR (pData, MNG_IDATMISSING);
-
-  pData->iImagelevel--;                /* one level up */
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {                                    /* create an animation object */
-    mng_retcode iRetcode = mng_create_ani_image (pData);
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* display processing */
-    iRetcode = mng_process_display_iend (pData);
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_SUPPORT_DISPLAY
-  if (!pData->bTimerset)               /* reset only if not broken !!! */
-  {
-#endif
-                                       /* IEND signals the end for most ... */
-    pData->bHasIHDR         = MNG_FALSE;
-    pData->bHasBASI         = MNG_FALSE;
-    pData->bHasDHDR         = MNG_FALSE;
-#ifdef MNG_INCLUDE_JNG
-    pData->bHasJHDR         = MNG_FALSE;
-    pData->bHasJSEP         = MNG_FALSE;
-    pData->bHasJDAA         = MNG_FALSE;
-    pData->bHasJDAT         = MNG_FALSE;
-#endif
-    pData->bHasPLTE         = MNG_FALSE;
-    pData->bHasTRNS         = MNG_FALSE;
-    pData->bHasGAMA         = MNG_FALSE;
-    pData->bHasCHRM         = MNG_FALSE;
-    pData->bHasSRGB         = MNG_FALSE;
-    pData->bHasICCP         = MNG_FALSE;
-    pData->bHasBKGD         = MNG_FALSE;
-    pData->bHasIDAT         = MNG_FALSE;
-#ifdef MNG_SUPPORT_DISPLAY
-  }
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-
-/* ************************************************************************** */
-
-MNG_F_SPECIALFUNC (mng_debunk_trns)
-{
-  mng_trnsp  pTRNS    = (mng_trnsp)pChunk;
-  mng_uint32 iRawlen  = *piRawlen;
-  mng_uint8p pRawdata = *ppRawdata;
-
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-  {                                  /* not global! */
-    pTRNS->bGlobal = MNG_FALSE;
-    pTRNS->iType   = pData->iColortype;
-
-    if (iRawlen != 0)
-    {
-      switch (pData->iColortype)     /* store fields */
-      {
-        case 0: {                    /* gray */
-                  if (iRawlen != 2)
-                    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-                  pTRNS->iGray  = mng_get_uint16 (pRawdata);
-                  break;
-                }
-        case 2: {                    /* rgb */
-                  if (iRawlen != 6)
-                    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-                  pTRNS->iRed   = mng_get_uint16 (pRawdata);
-                  pTRNS->iGreen = mng_get_uint16 (pRawdata+2);
-                  pTRNS->iBlue  = mng_get_uint16 (pRawdata+4);
-                  break;
-                }
-        case 3: {                    /* indexed */
-                  if (iRawlen > 256)
-                    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-                  pTRNS->iCount = iRawlen;
-                  MNG_COPY (pTRNS->aEntries, pRawdata, iRawlen);
-                  break;
-                }
-      }
-    }
-  }
-  else                               /* it's global! */
-  {
-    if (iRawlen == 0)
-      MNG_ERROR (pData, MNG_INVALIDLENGTH);
-    pTRNS->bGlobal = MNG_TRUE;
-    pTRNS->iType   = 0;
-    pTRNS->iRawlen = iRawlen;
-    MNG_COPY (pTRNS->aRawdata, pRawdata, iRawlen);
-
-    pData->iGlobalTRNSrawlen = iRawlen;
-    MNG_COPY (pData->aGlobalTRNSrawdata, pRawdata, iRawlen);
-  }
-
-  *piRawlen = 0;
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-MNG_C_SPECIALFUNC (mng_special_trns)
-{                                      /* multiple tRNS only inside BASI */
-  if ((pData->bHasTRNS) && (!pData->bHasBASI))
-    MNG_ERROR (pData, MNG_MULTIPLEERROR);
-
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-  {                                    /* not allowed with full alpha-channel */
-    if ((pData->iColortype == 4) || (pData->iColortype == 6))
-      MNG_ERROR (pData, MNG_CHUNKNOTALLOWED);
-
-    if (!((mng_trnsp)pChunk)->bEmpty)  /* filled ? */
-    {                                
-#ifdef MNG_SUPPORT_DISPLAY
-      if (pData->iColortype == 3)
-      {
-        mng_imagep     pImage = (mng_imagep)pData->pCurrentobj;
-        mng_imagedatap pBuf;
-
-        if (!pImage)                   /* no object then check obj 0 */
-          pImage = (mng_imagep)pData->pObjzero;
-
-        pBuf = pImage->pImgbuf;        /* address object buffer */
-
-        if (((mng_trnsp)pChunk)->iCount > pBuf->iPLTEcount)
-          MNG_ERROR (pData, MNG_INVALIDLENGTH);
-      }
-#endif
-    }
-    else                               /* if empty there must be global stuff! */
-    {
-      if (!pData->bHasglobalTRNS)
-        MNG_ERROR (pData, MNG_CANNOTBEEMPTY);
-    }
-  }
-
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-    pData->bHasTRNS = MNG_TRUE;        /* indicate tRNS available */
-  else
-    pData->bHasglobalTRNS = MNG_TRUE;
-
-#ifdef MNG_SUPPORT_DISPLAY
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-  {
-    mng_imagep     pImage;
-    mng_imagedatap pBuf;
-    mng_uint8p     pRawdata2;
-    mng_uint32     iRawlen2;
-
-#ifndef MNG_NO_DELTA_PNG
-    if (pData->bHasDHDR)               /* processing delta-image ? */
-    {                                  /* store in object 0 !!! */
-#if defined(MNG_NO_1_2_4BIT_SUPPORT)
-      mng_uint8 multiplier[]={0,255,85,0,17,0,0,0,1,0,0,0,0,0,0,0,1};
-#endif
-      pImage = (mng_imagep)pData->pObjzero;
-      pBuf   = pImage->pImgbuf;        /* address object buffer */
-      pBuf->bHasTRNS   = MNG_TRUE;     /* tell it it's got a tRNS now */
-      pBuf->iTRNSgray  = 0;
-      pBuf->iTRNSred   = 0;
-      pBuf->iTRNSgreen = 0;
-      pBuf->iTRNSblue  = 0;
-      pBuf->iTRNScount = 0;
-
-      switch (pData->iColortype)       /* store fields for future reference */
-      {
-        case 0: {                      /* gray */
-                  pBuf->iTRNSgray  = ((mng_trnsp)pChunk)->iGray;
-#if defined(MNG_NO_1_2_4BIT_SUPPORT)
-                  pBuf->iTRNSgray *= multiplier[pData->iPNGdepth];
-#endif
-#if defined(MNG_NO_16BIT_SUPPORT)
-                  if (pData->iPNGmult == 2)
-                     pBuf->iTRNSgray >>= 8;
-#endif
-                  break;
-                }
-        case 2: {                      /* rgb */
-                  pBuf->iTRNSred   = ((mng_trnsp)pChunk)->iRed;
-                  pBuf->iTRNSgreen = ((mng_trnsp)pChunk)->iGreen;
-                  pBuf->iTRNSblue  = ((mng_trnsp)pChunk)->iBlue;
-#if defined(MNG_NO_16BIT_SUPPORT)
-                  if (pData->iPNGmult == 2)
-                  {
-                     pBuf->iTRNSred   >>= 8;
-                     pBuf->iTRNSgreen >>= 8;
-                     pBuf->iTRNSblue  >>= 8;
-                  }
-#endif
-                  break;
-                }
-        case 3: {                      /* indexed */
-                  pBuf->iTRNScount = ((mng_trnsp)pChunk)->iCount;
-                  MNG_COPY (pBuf->aTRNSentries,
-                            ((mng_trnsp)pChunk)->aEntries,
-                            ((mng_trnsp)pChunk)->iCount);
-                  break;
-                }
-      }
-    }
-    else
-#endif
-    {                                  /* address current object */
-      pImage = (mng_imagep)pData->pCurrentobj;
-
-      if (!pImage)                     /* no object then dump it in obj 0 */
-        pImage = (mng_imagep)pData->pObjzero;
-
-      pBuf = pImage->pImgbuf;          /* address object buffer */
-      pBuf->bHasTRNS   = MNG_TRUE;     /* and tell it it's got a tRNS now */
-      pBuf->iTRNSgray  = 0;
-      pBuf->iTRNSred   = 0;
-      pBuf->iTRNSgreen = 0;
-      pBuf->iTRNSblue  = 0;
-      pBuf->iTRNScount = 0;
-
-      if (((mng_trnsp)pChunk)->bEmpty) /* if empty, inherit from global */
-      {
-        iRawlen2  = pData->iGlobalTRNSrawlen;
-        pRawdata2 = (mng_ptr)(pData->aGlobalTRNSrawdata);
-                                       /* global length oke ? */
-        if ((pData->iColortype == 0) && (iRawlen2 != 2))
-          MNG_ERROR (pData, MNG_GLOBALLENGTHERR);
-
-        if ((pData->iColortype == 2) && (iRawlen2 != 6))
-          MNG_ERROR (pData, MNG_GLOBALLENGTHERR);
-
-        if ((pData->iColortype == 3) && ((iRawlen2 == 0) || (iRawlen2 > pBuf->iPLTEcount)))
-          MNG_ERROR (pData, MNG_GLOBALLENGTHERR);
-
-        switch (pData->iColortype)     /* store fields for future reference */
-        {
-          case 0: {                    /* gray */
-                    pBuf->iTRNSgray = mng_get_uint16 (pRawdata2);
-#if defined(MNG_NO_16BIT_SUPPORT)
-                    if (pData->iPNGmult == 2)
-                       pBuf->iTRNSgray >>= 8;
-#endif
-                    break;
-                  }
-          case 2: {                    /* rgb */
-                    pBuf->iTRNSred   = mng_get_uint16 (pRawdata2);
-                    pBuf->iTRNSgreen = mng_get_uint16 (pRawdata2+2);
-                    pBuf->iTRNSblue  = mng_get_uint16 (pRawdata2+4);
-#if defined(MNG_NO_16BIT_SUPPORT)
-                    if (pData->iPNGmult == 2)
-                    {
-                       pBuf->iTRNSred   >>= 8;
-                       pBuf->iTRNSgreen >>= 8;
-                       pBuf->iTRNSblue  >>= 8;
-                    }
-#endif
-                    break;
-                  }
-          case 3: {                    /* indexed */
-                    pBuf->iTRNScount = iRawlen2;
-                    MNG_COPY (pBuf->aTRNSentries, pRawdata2, iRawlen2);
-                    break;
-                  }
-        }
-      }
-      else
-      {
-        switch (pData->iColortype)     /* store fields for future reference */
-        {
-          case 0: {                    /* gray */
-                    pBuf->iTRNSgray = ((mng_trnsp)pChunk)->iGray;
-#if defined(MNG_NO_16BIT_SUPPORT)
-                    if (pData->iPNGmult == 2)
-                       pBuf->iTRNSgray >>= 8;
-#endif
-                    break;
-                  }
-          case 2: {                    /* rgb */
-                    pBuf->iTRNSred   = ((mng_trnsp)pChunk)->iRed;
-                    pBuf->iTRNSgreen = ((mng_trnsp)pChunk)->iGreen;
-                    pBuf->iTRNSblue  = ((mng_trnsp)pChunk)->iBlue;
-#if defined(MNG_NO_16BIT_SUPPORT)
-                    if (pData->iPNGmult == 2)
-                    {
-                       pBuf->iTRNSred   >>= 8;
-                       pBuf->iTRNSgreen >>= 8;
-                       pBuf->iTRNSblue  >>= 8;
-                    }
-#endif
-                    break;
-                  }
-          case 3: {                    /* indexed */
-                    pBuf->iTRNScount = ((mng_trnsp)pChunk)->iCount;
-                    MNG_COPY (pBuf->aTRNSentries,
-                              ((mng_trnsp)pChunk)->aEntries,
-                              ((mng_trnsp)pChunk)->iCount);
-                    break;
-                  }
-        }
-      }
-    }
-  }
-  else
-  {                                    /* create an animation object */
-    return mng_create_ani_trns (pData);
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-  return MNG_NOERROR;                  /* done */
-}
-
-/* ************************************************************************** */
-
-MNG_C_SPECIALFUNC (mng_special_gama)
-{
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-    pData->bHasGAMA = MNG_TRUE;        /* indicate we've got it */
-  else
-    pData->bHasglobalGAMA = (mng_bool)!((mng_gamap)pChunk)->bEmpty;
-
-#ifdef MNG_SUPPORT_DISPLAY
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-  {
-    mng_imagep pImage;
-
-#ifndef MNG_NO_DELTA_PNG
-    if (pData->bHasDHDR)               /* update delta image ? */
-      pImage = (mng_imagep)pData->pObjzero;
-    else
-#endif
-    {
-      pImage = (mng_imagep)pData->pCurrentobj;
-      if (!pImage)                     /* no object then dump it in obj 0 */
-        pImage = (mng_imagep)pData->pObjzero;
-    }
-                                       /* store for color-processing routines */
-    pImage->pImgbuf->iGamma   = ((mng_gamap)pChunk)->iGamma;
-    pImage->pImgbuf->bHasGAMA = MNG_TRUE;
-  }
-  else
-  {                                    /* store as global */
-    if (!((mng_gamap)pChunk)->bEmpty)
-      pData->iGlobalGamma = ((mng_gamap)pChunk)->iGamma;
-                                       /* create an animation object */
-    return mng_create_ani_gama (pData, pChunk);
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-  return MNG_NOERROR;                  /* done */
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_cHRM
-MNG_C_SPECIALFUNC (mng_special_chrm)
-{
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-    pData->bHasCHRM = MNG_TRUE;        /* indicate we've got it */
-  else
-    pData->bHasglobalCHRM = (mng_bool)!((mng_chrmp)pChunk)->bEmpty;
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-#ifdef MNG_INCLUDE_JNG
-    if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-    if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-    {
-      mng_imagep     pImage;
-      mng_imagedatap pBuf;
-
-#ifndef MNG_NO_DELTA_PNG
-      if (pData->bHasDHDR)             /* update delta image ? */
-        pImage = (mng_imagep)pData->pObjzero;
-      else
-#endif
-      {
-        pImage = (mng_imagep)pData->pCurrentobj;
-        if (!pImage)                   /* no object then dump it in obj 0 */
-          pImage = (mng_imagep)pData->pObjzero;
-      }
-
-      pBuf = pImage->pImgbuf;          /* address object buffer */
-      pBuf->bHasCHRM = MNG_TRUE;       /* and tell it it's got a CHRM now */
-                                       /* store for color-processing routines */
-      pBuf->iWhitepointx   = ((mng_chrmp)pChunk)->iWhitepointx;
-      pBuf->iWhitepointy   = ((mng_chrmp)pChunk)->iWhitepointy;
-      pBuf->iPrimaryredx   = ((mng_chrmp)pChunk)->iRedx;
-      pBuf->iPrimaryredy   = ((mng_chrmp)pChunk)->iRedy;
-      pBuf->iPrimarygreenx = ((mng_chrmp)pChunk)->iGreenx;
-      pBuf->iPrimarygreeny = ((mng_chrmp)pChunk)->iGreeny;
-      pBuf->iPrimarybluex  = ((mng_chrmp)pChunk)->iBluex;
-      pBuf->iPrimarybluey  = ((mng_chrmp)pChunk)->iBluey;
-    }
-    else
-    {                                  /* store as global */
-      if (!((mng_chrmp)pChunk)->bEmpty)
-      {
-        pData->iGlobalWhitepointx   = ((mng_chrmp)pChunk)->iWhitepointx;
-        pData->iGlobalWhitepointy   = ((mng_chrmp)pChunk)->iWhitepointy;
-        pData->iGlobalPrimaryredx   = ((mng_chrmp)pChunk)->iRedx;
-        pData->iGlobalPrimaryredy   = ((mng_chrmp)pChunk)->iRedy;
-        pData->iGlobalPrimarygreenx = ((mng_chrmp)pChunk)->iGreenx;
-        pData->iGlobalPrimarygreeny = ((mng_chrmp)pChunk)->iGreeny;
-        pData->iGlobalPrimarybluex  = ((mng_chrmp)pChunk)->iBluex;
-        pData->iGlobalPrimarybluey  = ((mng_chrmp)pChunk)->iBluey;
-      }
-                                       /* create an animation object */
-      return mng_create_ani_chrm (pData, pChunk);
-    }
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-
-/* ************************************************************************** */
-
-MNG_C_SPECIALFUNC (mng_special_srgb)
-{
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-    pData->bHasSRGB = MNG_TRUE;        /* indicate we've got it */
-  else
-    pData->bHasglobalSRGB = (mng_bool)!((mng_srgbp)pChunk)->bEmpty;
-
-#ifdef MNG_SUPPORT_DISPLAY
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-  {
-    mng_imagep pImage;
-
-#ifndef MNG_NO_DELTA_PNG
-    if (pData->bHasDHDR)               /* update delta image ? */
-      pImage = (mng_imagep)pData->pObjzero;
-    else
-#endif
-    {
-      pImage = (mng_imagep)pData->pCurrentobj;
-      if (!pImage)                     /* no object then dump it in obj 0 */
-        pImage = (mng_imagep)pData->pObjzero;
-    }
-                                       /* store for color-processing routines */
-    pImage->pImgbuf->iRenderingintent = ((mng_srgbp)pChunk)->iRenderingintent;
-    pImage->pImgbuf->bHasSRGB         = MNG_TRUE;
-  }
-  else
-  {                                    /* store as global */
-    if (!((mng_srgbp)pChunk)->bEmpty)
-      pData->iGlobalRendintent = ((mng_srgbp)pChunk)->iRenderingintent;
-                                       /* create an animation object */
-    return mng_create_ani_srgb (pData, pChunk);
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-  return MNG_NOERROR;                  /* done */
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_iCCP
-MNG_C_SPECIALFUNC (mng_special_iccp)
-{
-  mng_retcode       iRetcode;
-  mng_chunk_headerp pDummy;
-
-#ifdef MNG_CHECK_BAD_ICCP              /* Check for bad iCCP chunk */
-  if (!strncmp (((mng_iccpp)pChunk)->zName, "Photoshop ICC profile", 21))
-  {
-    if (((mng_iccpp)pChunk)->iProfilesize == 2615) /* is it the sRGB profile ? */
-    {
-      mng_chunk_header chunk_srgb;
-      mng_get_chunkheader (MNG_UINT_sRGB, &chunk_srgb);
-                                       /* pretend it's an sRGB chunk then ! */
-      iRetcode = mng_read_general (pData, &chunk_srgb, 1, (mng_ptr)"0", &pDummy);
-      if (iRetcode)                    /* on error bail out */
-        return iRetcode;
-
-      pDummy->fCleanup (pData, pDummy);  
-    }
-  }
-  else
-  {
-#endif /* MNG_CHECK_BAD_ICCP */
-
-#ifdef MNG_INCLUDE_JNG
-    if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-    if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-      pData->bHasICCP = MNG_TRUE;      /* indicate we've got it */
-    else
-      pData->bHasglobalICCP = (mng_bool)!((mng_iccpp)pChunk)->bEmpty;
-
-#ifdef MNG_SUPPORT_DISPLAY
-#ifdef MNG_INCLUDE_JNG
-    if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-    if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-    {
-      mng_imagep pImage;
-
-#ifndef MNG_NO_DELTA_PNG
-      if (pData->bHasDHDR)             /* update delta image ? */
-      {                                /* store in object 0 ! */
-        pImage = (mng_imagep)pData->pObjzero;
-
-        if (pImage->pImgbuf->pProfile) /* profile existed ? */
-          MNG_FREEX (pData, pImage->pImgbuf->pProfile, pImage->pImgbuf->iProfilesize);
-                                       /* allocate a buffer & copy it */
-        MNG_ALLOC (pData, pImage->pImgbuf->pProfile, ((mng_iccpp)pChunk)->iProfilesize);
-        MNG_COPY  (pImage->pImgbuf->pProfile, ((mng_iccpp)pChunk)->pProfile, ((mng_iccpp)pChunk)->iProfilesize);
-                                       /* store its length as well */
-        pImage->pImgbuf->iProfilesize = ((mng_iccpp)pChunk)->iProfilesize;
-        pImage->pImgbuf->bHasICCP     = MNG_TRUE;
-      }
-      else
-#endif
-      {
-        pImage = (mng_imagep)pData->pCurrentobj;
-
-        if (!pImage)                   /* no object then dump it in obj 0 */
-          pImage = (mng_imagep)pData->pObjzero;
-
-        if (pImage->pImgbuf->pProfile) /* profile existed ? */
-          MNG_FREEX (pData, pImage->pImgbuf->pProfile, pImage->pImgbuf->iProfilesize);
-                                       /* allocate a buffer & copy it */
-        MNG_ALLOC (pData, pImage->pImgbuf->pProfile, ((mng_iccpp)pChunk)->iProfilesize);
-        MNG_COPY  (pImage->pImgbuf->pProfile, ((mng_iccpp)pChunk)->pProfile, ((mng_iccpp)pChunk)->iProfilesize);
-                                       /* store its length as well */
-        pImage->pImgbuf->iProfilesize = ((mng_iccpp)pChunk)->iProfilesize;
-        pImage->pImgbuf->bHasICCP     = MNG_TRUE;
-      }
-    }
-    else
-    {                                  /* store as global */
-      if (pData->pGlobalProfile)     /* did we have a global profile ? */
-        MNG_FREEX (pData, pData->pGlobalProfile, pData->iGlobalProfilesize);
-
-      if (((mng_iccpp)pChunk)->bEmpty) /* empty chunk ? */
-      {
-        pData->iGlobalProfilesize = 0; /* reset to null */
-        pData->pGlobalProfile     = MNG_NULL;
-      }
-      else
-      {                                /* allocate a global buffer & copy it */
-        MNG_ALLOC (pData, pData->pGlobalProfile, ((mng_iccpp)pChunk)->iProfilesize);
-        MNG_COPY  (pData->pGlobalProfile, ((mng_iccpp)pChunk)->pProfile, ((mng_iccpp)pChunk)->iProfilesize);
-                                       /* store its length as well */
-        pData->iGlobalProfilesize = ((mng_iccpp)pChunk)->iProfilesize;
-      }
-                                       /* create an animation object */
-      return mng_create_ani_iccp (pData, pChunk);
-    }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_CHECK_BAD_ICCP
-  }
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_tEXt
-MNG_C_SPECIALFUNC (mng_special_text)
-{
-  if (pData->fProcesstext)             /* inform the application ? */
-  {
-    mng_bool bOke = pData->fProcesstext ((mng_handle)pData, MNG_TYPE_TEXT,
-                                         ((mng_textp)pChunk)->zKeyword,
-                                         ((mng_textp)pChunk)->zText, 0, 0);
-    if (!bOke)
-      MNG_ERROR (pData, MNG_APPMISCERROR);
-  }
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_zTXt
-MNG_C_SPECIALFUNC (mng_special_ztxt)
-{
-  if (pData->fProcesstext)             /* inform the application ? */
-  {
-    mng_bool bOke = pData->fProcesstext ((mng_handle)pData, MNG_TYPE_ZTXT,
-                                         ((mng_ztxtp)pChunk)->zKeyword,
-                                         ((mng_ztxtp)pChunk)->zText, 0, 0);
-    if (!bOke)
-      MNG_ERROR (pData, MNG_APPMISCERROR);
-  }
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_iTXt
-MNG_F_SPECIALFUNC (mng_deflate_itxt)
-{
-  mng_itxtp  pITXT    = (mng_itxtp)pChunk;
-  mng_uint32 iBufsize = 0;
-  mng_uint8p pBuf     = 0;
-  mng_uint32 iTextlen = 0;
-
-  if (pITXT->iCompressionflag)         /* decompress the text ? */
-  {
-    mng_retcode iRetcode = mng_inflate_buffer (pData, *ppRawdata, *piRawlen,
-                                               &pBuf, &iBufsize, &iTextlen);
-
-    if (iRetcode)                      /* on error bail out */
-    {                                  /* don't forget to drop the temp buffer */
-      MNG_FREEX (pData, pBuf, iBufsize);
-      return iRetcode;
-    }
-
-    MNG_ALLOC (pData, pITXT->zText, iTextlen+1);
-    MNG_COPY (pITXT->zText, pBuf, iTextlen);
-
-    pITXT->iTextsize = iTextlen;
-
-    MNG_FREEX (pData, pBuf, iBufsize);
-
-  } else {
-
-    MNG_ALLOC (pData, pITXT->zText, (*piRawlen)+1);
-    MNG_COPY (pITXT->zText, *ppRawdata, *piRawlen);
-
-    pITXT->iTextsize = *piRawlen;
-  }
-
-  *piRawlen = 0;
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_iTXt
-MNG_C_SPECIALFUNC (mng_special_itxt)
-{
-  if (pData->fProcesstext)             /* inform the application ? */
-  {
-    mng_bool bOke = pData->fProcesstext ((mng_handle)pData, MNG_TYPE_ITXT,
-                                         ((mng_itxtp)pChunk)->zKeyword,
-                                         ((mng_itxtp)pChunk)->zText,
-                                         ((mng_itxtp)pChunk)->zLanguage,
-                                         ((mng_itxtp)pChunk)->zTranslation);
-    if (!bOke)
-      MNG_ERROR (pData, MNG_APPMISCERROR);
-  }
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_bKGD
-MNG_C_SPECIALFUNC (mng_special_bkgd)
-{
-#ifdef MNG_SUPPORT_DISPLAY
-  mng_imagep     pImage = (mng_imagep)pData->pCurrentobj;
-  mng_imagedatap pBuf;
-#endif
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-    pData->bHasBKGD = MNG_TRUE;        /* indicate bKGD available */
-  else
-    pData->bHasglobalBKGD = (mng_bool)!(((mng_bkgdp)pChunk)->bEmpty);
-
-#ifdef MNG_SUPPORT_DISPLAY
-  if (!pImage)                         /* if no object dump it in obj 0 */
-    pImage = (mng_imagep)pData->pObjzero;
-  pBuf = pImage->pImgbuf;              /* address object buffer */
-
-#ifdef MNG_INCLUDE_JNG
-  if (pData->bHasJHDR)
-  {
-    pBuf->bHasBKGD = MNG_TRUE;         /* tell the object it's got bKGD now */
-
-    switch (pData->iJHDRcolortype)     /* store fields for future reference */
-    {
-      case  8 : ;                      /* gray */
-      case 12 : {                      /* graya */
-                  pBuf->iBKGDgray  = ((mng_bkgdp)pChunk)->iGray;
-                  break;
-                }
-      case 10 : ;                      /* rgb */
-      case 14 : {                      /* rgba */
-                  pBuf->iBKGDred   = ((mng_bkgdp)pChunk)->iRed;
-                  pBuf->iBKGDgreen = ((mng_bkgdp)pChunk)->iGreen;
-                  pBuf->iBKGDblue  = ((mng_bkgdp)pChunk)->iBlue;
-                  break;
-                }
-    }
-  }
-  else
-#endif /* MNG_INCLUDE_JNG */
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-  {
-    pBuf->bHasBKGD = MNG_TRUE;         /* tell the object it's got bKGD now */
-
-    switch (pData->iColortype)         /* store fields for future reference */
-    {
-      case 0 : ;                        /* gray */
-      case 4 : {                        /* graya */
-                 pBuf->iBKGDgray  = ((mng_bkgdp)pChunk)->iGray;
-                 break;
-               }
-      case 2 : ;                        /* rgb */
-      case 6 : {                        /* rgba */
-                 pBuf->iBKGDred   = ((mng_bkgdp)pChunk)->iRed;
-                 pBuf->iBKGDgreen = ((mng_bkgdp)pChunk)->iGreen;
-                 pBuf->iBKGDblue  = ((mng_bkgdp)pChunk)->iBlue;
-                 break;
-               }
-      case 3 : {                        /* indexed */
-                 pBuf->iBKGDindex = ((mng_bkgdp)pChunk)->iIndex;
-                 break;
-               }
-    }
-  }
-  else                                 /* store as global */
-  {
-    if (!(((mng_bkgdp)pChunk)->bEmpty))
-    {
-      pData->iGlobalBKGDred   = ((mng_bkgdp)pChunk)->iRed;
-      pData->iGlobalBKGDgreen = ((mng_bkgdp)pChunk)->iGreen;
-      pData->iGlobalBKGDblue  = ((mng_bkgdp)pChunk)->iBlue;
-    }
-                                       /* create an animation object */
-    return mng_create_ani_bkgd (pData);
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_pHYs
-MNG_C_SPECIALFUNC (mng_special_phys)
-{
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-
-
-    /* TODO: something !!! */
-
-
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_sBIT
-MNG_C_SPECIALFUNC (mng_special_sbit)
-{
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-
-
-    /* TODO: something !!! */
-
-
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_sPLT
-MNG_F_SPECIALFUNC (mng_splt_entries)
-{
-  mng_spltp  pSPLT    = (mng_spltp)pChunk;
-  mng_uint32 iRawlen  = *piRawlen;
-  mng_uint8p pRawdata = *ppRawdata;
-
-  if ((pSPLT->iSampledepth != MNG_BITDEPTH_8 ) &&
-      (pSPLT->iSampledepth != MNG_BITDEPTH_16)   )
-    MNG_ERROR (pData, MNG_INVSAMPLEDEPTH);
-                                       /* check remaining length */
-  if ( ((pSPLT->iSampledepth == MNG_BITDEPTH_8 ) && (iRawlen %  6 != 0)) ||
-       ((pSPLT->iSampledepth == MNG_BITDEPTH_16) && (iRawlen % 10 != 0))    )
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-  if (pSPLT->iSampledepth == MNG_BITDEPTH_8)
-    pSPLT->iEntrycount = iRawlen / 6;
-  else
-    pSPLT->iEntrycount = iRawlen / 10;
-
-  if (iRawlen)
-  {
-    MNG_ALLOC (pData, pSPLT->pEntries, iRawlen);
-    MNG_COPY (pSPLT->pEntries, pRawdata, iRawlen);
-  }
-
-  *piRawlen = 0;
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_sPLT
-MNG_C_SPECIALFUNC (mng_special_splt)
-{
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-
-
-    /* TODO: something !!! */
-
-
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_hIST
-MNG_F_SPECIALFUNC (mng_hist_entries)
-{
-  mng_histp  pHIST    = (mng_histp)pChunk;
-  mng_uint32 iRawlen  = *piRawlen;
-  mng_uint8p pRawdata = *ppRawdata;
-  mng_uint32 iX;
-
-  if ( ((iRawlen & 0x01) != 0) || ((iRawlen >> 1) != pData->iPLTEcount) )
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-  pHIST->iEntrycount = iRawlen >> 1;
-
-  for (iX = 0; iX < pHIST->iEntrycount; iX++)
-  {
-    pHIST->aEntries[iX] = mng_get_uint16 (pRawdata);
-    pRawdata += 2;
-  }
-
-  *piRawlen = 0;
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_hIST
-MNG_C_SPECIALFUNC (mng_special_hist)
-{
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-
-
-    /* TODO: something !!! */
-
-
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_tIME
-MNG_C_SPECIALFUNC (mng_special_time)
-{
-/*  if (pData->fProcesstime) */            /* inform the application ? */
-/*  {
-
-    pData->fProcesstime ((mng_handle)pData, );
-  } */
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-
-/* ************************************************************************** */
-/* ************************************************************************** */
-/* JNG chunks */
-
-#ifdef MNG_INCLUDE_JNG
-MNG_C_SPECIALFUNC (mng_special_jhdr)
-{
-  if ((pData->eSigtype == mng_it_jng) && (pData->iChunkseq > 1))
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-                                       /* inside a JHDR-IEND block now */
-  pData->bHasJHDR              = MNG_TRUE;
-                                       /* and store interesting fields */
-  pData->iDatawidth            = ((mng_jhdrp)pChunk)->iWidth;
-  pData->iDataheight           = ((mng_jhdrp)pChunk)->iHeight;
-  pData->iJHDRcolortype        = ((mng_jhdrp)pChunk)->iColortype;
-  pData->iJHDRimgbitdepth      = ((mng_jhdrp)pChunk)->iImagesampledepth;
-  pData->iJHDRimgcompression   = ((mng_jhdrp)pChunk)->iImagecompression;
-  pData->iJHDRimginterlace     = ((mng_jhdrp)pChunk)->iImageinterlace;
-  pData->iJHDRalphabitdepth    = ((mng_jhdrp)pChunk)->iAlphasampledepth;
-  pData->iJHDRalphacompression = ((mng_jhdrp)pChunk)->iAlphacompression;
-  pData->iJHDRalphafilter      = ((mng_jhdrp)pChunk)->iAlphafilter;
-  pData->iJHDRalphainterlace   = ((mng_jhdrp)pChunk)->iAlphainterlace;
-
-#if defined(MNG_NO_1_2_4BIT_SUPPORT) || defined(MNG_NO_16BIT_SUPPORT)
-  pData->iPNGmult = 1;
-  pData->iPNGdepth = pData->iJHDRalphabitdepth;
-#endif
-
-#ifdef MNG_NO_1_2_4BIT_SUPPORT
-  if (pData->iJHDRalphabitdepth < 8)
-    pData->iJHDRalphabitdepth = 8;
-#endif
-
-#ifdef MNG_NO_16BIT_SUPPORT
-  if (pData->iJHDRalphabitdepth > 8)
-  {
-    pData->iPNGmult = 2;
-    pData->iJHDRalphabitdepth = 8;
-  }
-#endif
-                                       /* parameter validity checks */
-  if ((pData->iJHDRcolortype != MNG_COLORTYPE_JPEGGRAY  ) &&
-      (pData->iJHDRcolortype != MNG_COLORTYPE_JPEGCOLOR ) &&
-      (pData->iJHDRcolortype != MNG_COLORTYPE_JPEGGRAYA ) &&
-      (pData->iJHDRcolortype != MNG_COLORTYPE_JPEGCOLORA)    )
-    MNG_ERROR (pData, MNG_INVALIDCOLORTYPE);
-
-  if ((pData->iJHDRimgbitdepth != MNG_BITDEPTH_JPEG8     ) &&
-      (pData->iJHDRimgbitdepth != MNG_BITDEPTH_JPEG12    ) &&
-      (pData->iJHDRimgbitdepth != MNG_BITDEPTH_JPEG8AND12)    )
-    MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
-
-  if ((pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA ) ||
-      (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA)    )
-  {
-    if ((pData->iJHDRalphabitdepth != MNG_BITDEPTH_8 )
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-        && (pData->iJHDRalphabitdepth != MNG_BITDEPTH_1 ) &&
-        (pData->iJHDRalphabitdepth != MNG_BITDEPTH_2 ) &&
-        (pData->iJHDRalphabitdepth != MNG_BITDEPTH_4 )
-#endif
-#ifndef MNG_NO_16BIT_SUPPORT
-        && (pData->iJHDRalphabitdepth != MNG_BITDEPTH_16)
-#endif
-        )
-      MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
-
-    if ((pData->iJHDRalphacompression != MNG_COMPRESSION_DEFLATE     ) &&
-        (pData->iJHDRalphacompression != MNG_COMPRESSION_BASELINEJPEG)    )
-      MNG_ERROR (pData, MNG_INVALIDCOMPRESS);
-
-    if ((pData->iJHDRalphacompression == MNG_COMPRESSION_BASELINEJPEG) &&
-        (pData->iJHDRalphabitdepth    !=  MNG_BITDEPTH_8             )    )
-      MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
-
-#if defined(FILTER192) || defined(FILTER193)
-    if ((pData->iJHDRalphafilter != MNG_FILTER_ADAPTIVE ) &&
-#if defined(FILTER192) && defined(FILTER193)
-        (pData->iJHDRalphafilter != MNG_FILTER_DIFFERING) &&
-        (pData->iJHDRalphafilter != MNG_FILTER_NOFILTER )    )
-#else
-#ifdef FILTER192
-        (pData->iJHDRalphafilter != MNG_FILTER_DIFFERING)    )
-#else
-        (pData->iJHDRalphafilter != MNG_FILTER_NOFILTER )    )
-#endif
-#endif
-      MNG_ERROR (pData, MNG_INVALIDFILTER);
-#else
-    if (pData->iJHDRalphafilter)
-      MNG_ERROR (pData, MNG_INVALIDFILTER);
-#endif
-
-  }
-  else
-  {
-    if (pData->iJHDRalphabitdepth)
-      MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
-    if (pData->iJHDRalphacompression)
-      MNG_ERROR (pData, MNG_INVALIDCOMPRESS);
-    if (pData->iJHDRalphafilter)
-      MNG_ERROR (pData, MNG_INVALIDFILTER);
-    if (pData->iJHDRalphainterlace)
-      MNG_ERROR (pData, MNG_INVALIDINTERLACE);
-  }
-
-  if (!pData->bHasheader)              /* first chunk ? */
-  {
-    pData->bHasheader = MNG_TRUE;      /* we've got a header */
-    pData->eImagetype = mng_it_jng;    /* then this must be a JNG */
-    pData->iWidth     = ((mng_jhdrp)pChunk)->iWidth;
-    pData->iHeight    = ((mng_jhdrp)pChunk)->iHeight;
-                                       /* predict alpha-depth ! */
-    if ((pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA ) ||
-        (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA)    )
-      pData->iAlphadepth = pData->iJHDRalphabitdepth;
-    else
-      pData->iAlphadepth = 0;
-                                       /* fits on maximum canvas ? */
-    if ((pData->iWidth > pData->iMaxwidth) || (pData->iHeight > pData->iMaxheight))
-      MNG_WARNING (pData, MNG_IMAGETOOLARGE);
-
-    if (pData->fProcessheader)         /* inform the app ? */
-      if (!pData->fProcessheader (((mng_handle)pData), pData->iWidth, pData->iHeight))
-        MNG_ERROR (pData, MNG_APPMISCERROR);
-
-  }
-
-  pData->iColortype = 0;               /* fake grayscale for other routines */
-  pData->iImagelevel++;                /* one level deeper */
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-    mng_retcode iRetcode = mng_process_display_jhdr (pData);
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_NO_16BIT_SUPPORT
-  if (((mng_jhdrp)pChunk)->iAlphasampledepth > 8)
-    ((mng_jhdrp)pChunk)->iAlphasampledepth = 8;
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif /* MNG_INCLUDE_JNG */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-MNG_C_SPECIALFUNC (mng_special_jdaa)
-{
-  if (pData->iJHDRalphacompression != MNG_COMPRESSION_BASELINEJPEG)
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-  pData->bHasJDAA = MNG_TRUE;          /* got some JDAA now, don't we */
-  return MNG_NOERROR;
-}
-#endif /* MNG_INCLUDE_JNG */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-MNG_C_SPECIALFUNC (mng_special_jdat)
-{
-  pData->bHasJDAT = MNG_TRUE;          /* got some JDAT now, don't we */
-  return MNG_NOERROR;
-}
-#endif /* MNG_INCLUDE_JNG */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-MNG_C_SPECIALFUNC (mng_special_jsep)
-{
-  pData->bHasJSEP = MNG_TRUE;          /* indicate we've had the 8-/12-bit separator */
-  return MNG_NOERROR;
-}
-#endif /* MNG_INCLUDE_JNG */
-
-/* ************************************************************************** */
-/* ************************************************************************** */
-/* MNG chunks */
-
-MNG_C_SPECIALFUNC (mng_special_mhdr)
-{
-  if (pData->bHasheader)               /* can only be the first chunk! */
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-  pData->bHasMHDR     = MNG_TRUE;      /* oh boy, a real MNG */
-  pData->bHasheader   = MNG_TRUE;      /* we've got a header */
-  pData->eImagetype   = mng_it_mng;    /* fill header fields */
-  pData->iWidth       = ((mng_mhdrp)pChunk)->iWidth;
-  pData->iHeight      = ((mng_mhdrp)pChunk)->iHeight;
-  pData->iTicks       = ((mng_mhdrp)pChunk)->iTicks;
-  pData->iLayercount  = ((mng_mhdrp)pChunk)->iLayercount;
-  pData->iFramecount  = ((mng_mhdrp)pChunk)->iFramecount;
-  pData->iPlaytime    = ((mng_mhdrp)pChunk)->iPlaytime;
-  pData->iSimplicity  = ((mng_mhdrp)pChunk)->iSimplicity;
-#ifndef MNG_NO_OLD_VERSIONS
-  pData->bPreDraft48  = MNG_FALSE;
-#endif
-                                       /* predict alpha-depth */
-  if ((pData->iSimplicity & 0x00000001) == 0)
-#ifndef MNG_NO_16BIT_SUPPORT
-    pData->iAlphadepth = 16;           /* no indicators = assume the worst */
-#else
-    pData->iAlphadepth = 8;            /* anything else = assume the worst */
-#endif
-  else
-  if ((pData->iSimplicity & 0x00000008) == 0)
-    pData->iAlphadepth = 0;            /* no transparency at all */
-  else
-  if ((pData->iSimplicity & 0x00000140) == 0x00000040)
-    pData->iAlphadepth = 1;            /* no semi-transparency guaranteed */
-  else
-#ifndef MNG_NO_16BIT_SUPPORT
-    pData->iAlphadepth = 16;           /* anything else = assume the worst */
-#else
-    pData->iAlphadepth = 8;            /* anything else = assume the worst */
-#endif
-
-#ifdef MNG_INCLUDE_JNG                 /* can we handle the complexity ? */
-  if (pData->iSimplicity & 0x0000FC00)
-#else
-  if (pData->iSimplicity & 0x0000FC10)
-#endif
-    MNG_ERROR (pData, MNG_MNGTOOCOMPLEX);
-                                       /* fits on maximum canvas ? */
-  if ((pData->iWidth > pData->iMaxwidth) || (pData->iHeight > pData->iMaxheight))
-    MNG_WARNING (pData, MNG_IMAGETOOLARGE);
-
-  if (pData->fProcessheader)           /* inform the app ? */
-    if (!pData->fProcessheader (((mng_handle)pData), pData->iWidth, pData->iHeight))
-      MNG_ERROR (pData, MNG_APPMISCERROR);
-
-  pData->iImagelevel++;                /* one level deeper */
-
-  return MNG_NOERROR;                  /* done */
-}
-
-/* ************************************************************************** */
-
-MNG_C_SPECIALFUNC (mng_special_mend)
-{
-#ifdef MNG_SUPPORT_DISPLAY
-  {                                    /* do something */
-    mng_retcode iRetcode = mng_process_display_mend (pData);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-
-    if (!pData->iTotalframes)          /* save totals */
-      pData->iTotalframes   = pData->iFrameseq;
-    if (!pData->iTotallayers)
-      pData->iTotallayers   = pData->iLayerseq;
-    if (!pData->iTotalplaytime)
-      pData->iTotalplaytime = pData->iFrametime;
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-  pData->bHasMHDR = MNG_FALSE;         /* end of the line, bro! */
-
-  return MNG_NOERROR;                  /* done */
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_LOOP
-MNG_F_SPECIALFUNC (mng_debunk_loop)
-{
-  mng_loopp  pLOOP    = (mng_loopp)pChunk;
-  mng_uint32 iRawlen  = *piRawlen;
-  mng_uint8p pRawdata = *ppRawdata;
-
-  if (iRawlen >= 5)                    /* length checks */
-  {
-    if (iRawlen >= 6)
-    {
-      if ((iRawlen - 6) % 4 != 0)
-        MNG_ERROR (pData, MNG_INVALIDLENGTH);
-    }
-  }
-  else
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-  if (iRawlen >= 5)                  /* store the fields */
-  {
-    pLOOP->iLevel  = *pRawdata;
-
-#ifndef MNG_NO_OLD_VERSIONS
-    if (pData->bPreDraft48)
-    {
-      pLOOP->iTermination = *(pRawdata+1);
-      pLOOP->iRepeat = mng_get_uint32 (pRawdata+2);
-    }
-    else
-#endif
-    {
-      pLOOP->iRepeat = mng_get_uint32 (pRawdata+1);
-    }
-
-    if (iRawlen >= 6)
-    {
-#ifndef MNG_NO_OLD_VERSIONS
-      if (!pData->bPreDraft48)
-#endif
-        pLOOP->iTermination = *(pRawdata+5);
-
-      if (iRawlen >= 10)
-      {
-        pLOOP->iItermin = mng_get_uint32 (pRawdata+6);
-
-#ifndef MNG_NO_LOOP_SIGNALS_SUPPORTED
-        if (iRawlen >= 14)
-        {
-          pLOOP->iItermax = mng_get_uint32 (pRawdata+10);
-          pLOOP->iCount   = (iRawlen - 14) / 4;
-
-          if (pLOOP->iCount)
-          {
-            MNG_ALLOC (pData, pLOOP->pSignals, pLOOP->iCount << 2);
-
-#ifndef MNG_BIGENDIAN_SUPPORTED
-            {
-              mng_uint32  iX;
-              mng_uint8p  pIn  = pRawdata + 14;
-              mng_uint32p pOut = (mng_uint32p)pLOOP->pSignals;
-
-              for (iX = 0; iX < pLOOP->iCount; iX++)
-              {
-                *pOut++ = mng_get_uint32 (pIn);
-                pIn += 4;
-              }
-            }
-#else
-            MNG_COPY (pLOOP->pSignals, pRawdata + 14, pLOOP->iCount << 2);
-#endif /* !MNG_BIGENDIAN_SUPPORTED */
-          }
-        }
-#endif
-      }
-    }
-  }
-
-  *piRawlen = 0;
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_LOOP
-MNG_C_SPECIALFUNC (mng_special_loop)
-{
-  if (!pData->bCacheplayback)          /* must store playback info to work!! */
-    MNG_ERROR (pData, MNG_LOOPWITHCACHEOFF);
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-    mng_retcode iRetcode;
-
-    pData->bHasLOOP = MNG_TRUE;        /* indicate we're inside a loop */
-                                       /* create the LOOP ani-object */
-    iRetcode = mng_create_ani_loop (pData, pChunk);
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* skip till matching ENDL if iteration=0 */
-    if ((!pData->bSkipping) && (((mng_loopp)pChunk)->iRepeat == 0))
-      pData->bSkipping = MNG_TRUE;
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_LOOP
-MNG_C_SPECIALFUNC (mng_special_endl)
-{
-#ifdef MNG_SUPPORT_DISPLAY
-  if (pData->bHasLOOP)                 /* are we really processing a loop ? */
-  {
-    mng_uint8 iLevel = ((mng_endlp)pChunk)->iLevel;
-                                       /* create an ENDL animation object */
-    return mng_create_ani_endl (pData, iLevel);
-  }
-  else
-    MNG_ERROR (pData, MNG_NOMATCHINGLOOP);
-#endif /* MNG_SUPPORT_DISPLAY */
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_DEFI
-MNG_C_SPECIALFUNC (mng_special_defi)
-{
-#ifdef MNG_SUPPORT_DISPLAY
-  mng_retcode iRetcode;
-
-  pData->iDEFIobjectid     = ((mng_defip)pChunk)->iObjectid;
-  pData->bDEFIhasdonotshow = ((mng_defip)pChunk)->bHasdonotshow;
-  pData->iDEFIdonotshow    = ((mng_defip)pChunk)->iDonotshow;
-  pData->bDEFIhasconcrete  = ((mng_defip)pChunk)->bHasconcrete;
-  pData->iDEFIconcrete     = ((mng_defip)pChunk)->iConcrete;
-  pData->bDEFIhasloca      = ((mng_defip)pChunk)->bHasloca;
-  pData->iDEFIlocax        = ((mng_defip)pChunk)->iXlocation;
-  pData->iDEFIlocay        = ((mng_defip)pChunk)->iYlocation;
-  pData->bDEFIhasclip      = ((mng_defip)pChunk)->bHasclip;
-  pData->iDEFIclipl        = ((mng_defip)pChunk)->iLeftcb;
-  pData->iDEFIclipr        = ((mng_defip)pChunk)->iRightcb;
-  pData->iDEFIclipt        = ((mng_defip)pChunk)->iTopcb;
-  pData->iDEFIclipb        = ((mng_defip)pChunk)->iBottomcb;
-                                       /* create an animation object */
-  iRetcode = mng_create_ani_defi (pData);
-  if (!iRetcode)                       /* do display processing */
-    iRetcode = mng_process_display_defi (pData);
-  return iRetcode;
-#else
-  return MNG_NOERROR;                  /* done */
-#endif /* MNG_SUPPORT_DISPLAY */
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_BASI
-MNG_C_SPECIALFUNC (mng_special_basi)
-{
-  pData->bHasBASI     = MNG_TRUE;      /* inside a BASI-IEND block now */
-                                       /* store interesting fields */
-  pData->iDatawidth   = ((mng_basip)pChunk)->iWidth;
-  pData->iDataheight  = ((mng_basip)pChunk)->iHeight;
-  pData->iBitdepth    = ((mng_basip)pChunk)->iBitdepth;   
-  pData->iColortype   = ((mng_basip)pChunk)->iColortype;
-  pData->iCompression = ((mng_basip)pChunk)->iCompression;
-  pData->iFilter      = ((mng_basip)pChunk)->iFilter;
-  pData->iInterlace   = ((mng_basip)pChunk)->iInterlace;
-
-#if defined(MNG_NO_1_2_4BIT_SUPPORT) || defined(MNG_NO_16BIT_SUPPORT)
-  pData->iPNGmult = 1;
-  pData->iPNGdepth = pData->iBitdepth;
-#endif
-
-#ifdef MNG_NO_1_2_4BIT_SUPPORT
-  if (pData->iBitdepth < 8)
-    pData->iBitdepth = 8;
-#endif
-#ifdef MNG_NO_16BIT_SUPPORT
-  if (pData->iBitdepth > 8)
-    {
-      pData->iBitdepth = 8;
-      pData->iPNGmult = 2;
-    }
-#endif
-
-  if ((pData->iBitdepth !=  8)      /* parameter validity checks */
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-      && (pData->iBitdepth !=  1) &&
-      (pData->iBitdepth !=  2) &&
-      (pData->iBitdepth !=  4)
-#endif
-#ifndef MNG_NO_16BIT_SUPPORT
-      && (pData->iBitdepth != 16)
-#endif
-      )
-    MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
-
-  if ((pData->iColortype != MNG_COLORTYPE_GRAY   ) &&
-      (pData->iColortype != MNG_COLORTYPE_RGB    ) &&
-      (pData->iColortype != MNG_COLORTYPE_INDEXED) &&
-      (pData->iColortype != MNG_COLORTYPE_GRAYA  ) &&
-      (pData->iColortype != MNG_COLORTYPE_RGBA   )    )
-    MNG_ERROR (pData, MNG_INVALIDCOLORTYPE);
-
-  if ((pData->iColortype == MNG_COLORTYPE_INDEXED) && (pData->iBitdepth > 8))
-    MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
-
-  if (((pData->iColortype == MNG_COLORTYPE_RGB    ) ||
-       (pData->iColortype == MNG_COLORTYPE_GRAYA  ) ||
-       (pData->iColortype == MNG_COLORTYPE_RGBA   )    ) &&
-      (pData->iBitdepth < 8                            )    )
-    MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
-
-#if defined(FILTER192) || defined(FILTER193)
-  if ((pData->iFilter != MNG_FILTER_ADAPTIVE ) &&
-#if defined(FILTER192) && defined(FILTER193)
-      (pData->iFilter != MNG_FILTER_DIFFERING) &&
-      (pData->iFilter != MNG_FILTER_NOFILTER )    )
-#else
-#ifdef FILTER192
-      (pData->iFilter != MNG_FILTER_DIFFERING)    )
-#else
-      (pData->iFilter != MNG_FILTER_NOFILTER )    )
-#endif
-#endif
-    MNG_ERROR (pData, MNG_INVALIDFILTER);
-#else
-  if (pData->iFilter)
-    MNG_ERROR (pData, MNG_INVALIDFILTER);
-#endif
-
-  pData->iImagelevel++;                /* one level deeper */
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {                                    /* create an animation object */
-    mng_retcode iRetcode = mng_create_ani_basi (pData, pChunk);
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_NO_16BIT_SUPPORT
-  if (((mng_basip)pChunk)->iBitdepth > 8)
-    ((mng_basip)pChunk)->iBitdepth = 8;
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_CLON
-MNG_C_SPECIALFUNC (mng_special_clon)
-{
-#ifdef MNG_SUPPORT_DISPLAY
-  return mng_create_ani_clon (pData, pChunk);
-#else
-  return MNG_NOERROR;                  /* done */
-#endif /* MNG_SUPPORT_DISPLAY */
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_PAST
-MNG_F_SPECIALFUNC (mng_debunk_past)
-{
-  mng_pastp        pPAST    = (mng_pastp)pChunk;
-  mng_uint32       iRawlen  = *piRawlen;
-  mng_uint8p       pRawdata = *ppRawdata;
-  mng_uint32       iSize;
-  mng_uint32       iX;
-  mng_past_sourcep pSource;
-                                       /* check the length */
-  if ((iRawlen < 41) || (((iRawlen - 11) % 30) != 0))
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-  pPAST->iDestid     = mng_get_uint16 (pRawdata);
-  pPAST->iTargettype = *(pRawdata+2);
-  pPAST->iTargetx    = mng_get_int32  (pRawdata+3);
-  pPAST->iTargety    = mng_get_int32  (pRawdata+7);
-  pPAST->iCount      = ((iRawlen - 11) / 30); /* how many entries again? */
-  iSize              = pPAST->iCount * sizeof (mng_past_source);
-
-  pRawdata += 11;
-                                       /* get a buffer for all the source blocks */
-  MNG_ALLOC (pData, pPAST->pSources, iSize);
-
-  pSource = (mng_past_sourcep)(pPAST->pSources);
-
-  for (iX = pPAST->iCount; iX > 0; iX--)
-  {                                    /* now copy the source blocks */
-    pSource->iSourceid     = mng_get_uint16 (pRawdata);
-    pSource->iComposition  = *(pRawdata+2);
-    pSource->iOrientation  = *(pRawdata+3);
-    pSource->iOffsettype   = *(pRawdata+4);
-    pSource->iOffsetx      = mng_get_int32 (pRawdata+5);
-    pSource->iOffsety      = mng_get_int32 (pRawdata+9);
-    pSource->iBoundarytype = *(pRawdata+13);
-    pSource->iBoundaryl    = mng_get_int32 (pRawdata+14);
-    pSource->iBoundaryr    = mng_get_int32 (pRawdata+18);
-    pSource->iBoundaryt    = mng_get_int32 (pRawdata+22);
-    pSource->iBoundaryb    = mng_get_int32 (pRawdata+26);
-
-    pSource++;
-    pRawdata += 30;
-  }
-
-  *piRawlen = 0;
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_PAST
-MNG_C_SPECIALFUNC (mng_special_past)
-{
-#ifdef MNG_SUPPORT_DISPLAY
-  return mng_create_ani_past (pData, pChunk);
-#else
-  return MNG_NOERROR;
-#endif /* MNG_SUPPORT_DISPLAY */
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_DISC
-MNG_F_SPECIALFUNC (mng_disc_entries)
-{
-  mng_discp   pDISC    = (mng_discp)pChunk;
-  mng_uint32  iRawlen  = *piRawlen;
-  mng_uint8p  pRawdata = *ppRawdata;
-
-  if ((iRawlen % 2) != 0)              /* check the length */
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-  pDISC->iCount = (iRawlen / sizeof (mng_uint16));
-
-  if (pDISC->iCount)
-  {
-    MNG_ALLOC (pData, pDISC->pObjectids, iRawlen);
-
-#ifndef MNG_BIGENDIAN_SUPPORTED
-    {
-      mng_uint32  iX;
-      mng_uint8p  pIn  = pRawdata;
-      mng_uint16p pOut = pDISC->pObjectids;
-
-      for (iX = pDISC->iCount; iX > 0; iX--)
-      {
-        *pOut++ = mng_get_uint16 (pIn);
-        pIn += 2;
-      }
-    }
-#else
-    MNG_COPY (pDISC->pObjectids, pRawdata, iRawlen);
-#endif /* !MNG_BIGENDIAN_SUPPORTED */
-  }
-
-  *piRawlen = 0;
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_DISC
-MNG_C_SPECIALFUNC (mng_special_disc)
-{
-#ifdef MNG_SUPPORT_DISPLAY
-  return mng_create_ani_disc (pData, pChunk);
-#else
-  return MNG_NOERROR;                  
-#endif /* MNG_SUPPORT_DISPLAY */
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_BACK
-MNG_C_SPECIALFUNC (mng_special_back)
-{
-#ifdef MNG_SUPPORT_DISPLAY
-                                       /* retrieve the fields */
-  pData->bHasBACK       = MNG_TRUE;
-  pData->iBACKred       = ((mng_backp)pChunk)->iRed;
-  pData->iBACKgreen     = ((mng_backp)pChunk)->iGreen;
-  pData->iBACKblue      = ((mng_backp)pChunk)->iBlue;
-  pData->iBACKmandatory = ((mng_backp)pChunk)->iMandatory;
-  pData->iBACKimageid   = ((mng_backp)pChunk)->iImageid;
-  pData->iBACKtile      = ((mng_backp)pChunk)->iTile;
-
-  return mng_create_ani_back (pData);
-#else
-  return MNG_NOERROR;
-#endif /* MNG_SUPPORT_DISPLAY */
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_FRAM
-MNG_F_SPECIALFUNC (mng_fram_remainder)
-{
-  mng_framp  pFRAM     = (mng_framp)pChunk;
-  mng_uint32 iRawlen   = *piRawlen;
-  mng_uint8p pRawdata  = *ppRawdata;
-  mng_uint32 iRequired = 0;
-
-  if (iRawlen < 4)                     /* must have at least 4 bytes */
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-  iRequired = 4;                       /* calculate and check required remaining length */
-
-  pFRAM->iChangedelay    = *pRawdata;
-  pFRAM->iChangetimeout  = *(pRawdata+1);
-  pFRAM->iChangeclipping = *(pRawdata+2);
-  pFRAM->iChangesyncid   = *(pRawdata+3);
-
-  if (pFRAM->iChangedelay   ) { iRequired +=  4; }
-  if (pFRAM->iChangetimeout ) { iRequired +=  4; }
-  if (pFRAM->iChangeclipping) { iRequired += 17; }
-
-  if (pFRAM->iChangesyncid)
-  {
-    if ((iRawlen - iRequired) % 4 != 0)
-      MNG_ERROR (pData, MNG_INVALIDLENGTH);
-  }
-  else
-  {
-    if (iRawlen != iRequired)
-      MNG_ERROR (pData, MNG_INVALIDLENGTH);
-  }
-
-  pRawdata += 4;
-
-  if (pFRAM->iChangedelay)              /* delay changed ? */
-  {
-    pFRAM->iDelay = mng_get_uint32 (pRawdata);
-    pRawdata += 4;
-  }
-
-  if (pFRAM->iChangetimeout)            /* timeout changed ? */
-  {
-    pFRAM->iTimeout = mng_get_uint32 (pRawdata);
-    pRawdata += 4;
-  }
-
-  if (pFRAM->iChangeclipping)           /* clipping changed ? */
-  {
-    pFRAM->iBoundarytype = *pRawdata;
-    pFRAM->iBoundaryl    = mng_get_int32 (pRawdata+1);
-    pFRAM->iBoundaryr    = mng_get_int32 (pRawdata+5);
-    pFRAM->iBoundaryt    = mng_get_int32 (pRawdata+9);
-    pFRAM->iBoundaryb    = mng_get_int32 (pRawdata+13);
-    pRawdata += 17;
-  }
-
-  if (pFRAM->iChangesyncid)
-  {
-    pFRAM->iCount    = (iRawlen - iRequired) / 4;
-
-    if (pFRAM->iCount)
-    {
-      MNG_ALLOC (pData, pFRAM->pSyncids, pFRAM->iCount * 4);
-
-#ifndef MNG_BIGENDIAN_SUPPORTED
-      {
-        mng_uint32 iX;
-        mng_uint32p pOut = pFRAM->pSyncids;
-
-        for (iX = pFRAM->iCount; iX > 0; iX--)
-        {
-          *pOut++ = mng_get_uint32 (pRawdata);
-          pRawdata += 4;
-        }
-      }
-#else
-      MNG_COPY (pFRAM->pSyncids, pRawdata, pFRAM->iCount * 4);
-#endif /* !MNG_BIGENDIAN_SUPPORTED */
-    }
-  }
-
-#ifndef MNG_NO_OLD_VERSIONS
-  if (pData->bPreDraft48)              /* old style input-stream ? */
-  {
-    switch (pFRAM->iMode)              /* fix the framing mode then */
-    {
-      case  0: { break; }
-      case  1: { pFRAM->iMode = 3; break; }
-      case  2: { pFRAM->iMode = 4; break; }
-      case  3: { pFRAM->iMode = 1; break; }
-      case  4: { pFRAM->iMode = 1; break; }
-      case  5: { pFRAM->iMode = 2; break; }
-      default: { pFRAM->iMode = 1; break; }
-    }
-  }
-#endif
-
-  *piRawlen = 0;
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_FRAM
-MNG_C_SPECIALFUNC (mng_special_fram)
-{
-#ifdef MNG_SUPPORT_DISPLAY
-  return mng_create_ani_fram (pData, pChunk);
-#else
-  return MNG_NOERROR;
-#endif /* MNG_SUPPORT_DISPLAY */
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_MOVE
-MNG_C_SPECIALFUNC (mng_special_move)
-{
-#ifdef MNG_SUPPORT_DISPLAY
-  return mng_create_ani_move (pData, pChunk);
-#else
-  return MNG_NOERROR;
-#endif /* MNG_SUPPORT_DISPLAY */
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_CLIP
-MNG_C_SPECIALFUNC (mng_special_clip)
-{
-#ifdef MNG_SUPPORT_DISPLAY
-  return mng_create_ani_clip (pData, pChunk);
-#else
-  return MNG_NOERROR;                  
-#endif /* MNG_SUPPORT_DISPLAY */
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_SHOW
-MNG_C_SPECIALFUNC (mng_special_show)
-{
-#ifdef MNG_SUPPORT_DISPLAY
-  mng_retcode iRetcode;
-
-  if (!((mng_showp)pChunk)->bEmpty)    /* any data ? */
-  {
-    if (!((mng_showp)pChunk)->bHaslastid)
-      ((mng_showp)pChunk)->iLastid = ((mng_showp)pChunk)->iFirstid;
-
-    pData->iSHOWfromid = ((mng_showp)pChunk)->iFirstid;
-    pData->iSHOWtoid   = ((mng_showp)pChunk)->iLastid;
-    pData->iSHOWmode   = ((mng_showp)pChunk)->iMode;
-  }
-  else                                 /* use defaults then */
-  {
-    pData->iSHOWfromid = 1;
-    pData->iSHOWtoid   = 65535;
-    pData->iSHOWmode   = 2;
-  }
-                                       /* create a SHOW animation object */
-  iRetcode = mng_create_ani_show (pData);
-  if (!iRetcode)                       /* go and do it! */
-    iRetcode = mng_process_display_show (pData);
-
-#endif /* MNG_SUPPORT_DISPLAY */
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_TERM
-MNG_C_SPECIALFUNC (mng_special_term)
-{
-                                       /* should be behind MHDR or SAVE !! */
-  if ((!pData->bHasSAVE) && (pData->iChunkseq > 2))
-  {
-    pData->bMisplacedTERM = MNG_TRUE;  /* indicate we found a misplaced TERM */
-                                       /* and send a warning signal!!! */
-    MNG_WARNING (pData, MNG_SEQUENCEERROR);
-  }
-
-  pData->bHasTERM = MNG_TRUE;
-
-  if (pData->fProcessterm)             /* inform the app ? */
-    if (!pData->fProcessterm (((mng_handle)pData),
-                              ((mng_termp)pChunk)->iTermaction,
-                              ((mng_termp)pChunk)->iIteraction,
-                              ((mng_termp)pChunk)->iDelay,
-                              ((mng_termp)pChunk)->iItermax))
-      MNG_ERROR (pData, MNG_APPMISCERROR);
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {                                    /* create the TERM ani-object */
-    mng_retcode iRetcode = mng_create_ani_term (pData, pChunk);
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* save for future reference */
-    pData->pTermaniobj = pData->pLastaniobj;
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_SAVE
-MNG_F_SPECIALFUNC (mng_save_entries)
-{
-  mng_savep       pSAVE     = (mng_savep)pChunk;
-  mng_uint32      iRawlen   = *piRawlen;
-  mng_uint8p      pRawdata  = *ppRawdata;
-  mng_save_entryp pEntry    = MNG_NULL;
-  mng_uint32      iCount    = 0;
-  mng_uint8       iOtype    = *pRawdata;
-  mng_uint8       iEtype;
-  mng_uint8p      pTemp;
-  mng_uint8p      pNull;
-  mng_uint32      iLen;
-  mng_uint32      iOffset[2];
-  mng_uint32      iStarttime[2];
-  mng_uint32      iFramenr;
-  mng_uint32      iLayernr;
-  mng_uint32      iX;
-  mng_uint32      iNamesize;
-
-  if ((iOtype != 4) && (iOtype != 8))
-    MNG_ERROR (pData, MNG_INVOFFSETSIZE);
-
-  pSAVE->iOffsettype = iOtype;
-
-  for (iX = 0; iX < 2; iX++)       /* do this twice to get the count first ! */
-  {
-    pTemp = pRawdata + 1;
-    iLen  = iRawlen  - 1;
-
-    if (iX)                        /* second run ? */
-    {
-      MNG_ALLOC (pData, pEntry, (iCount * sizeof (mng_save_entry)));
-
-      pSAVE->iCount   = iCount;
-      pSAVE->pEntries = pEntry;
-    }
-
-    while (iLen)                   /* anything left ? */
-    {
-      iEtype = *pTemp;             /* entrytype */
-
-      if ((iEtype != 0) && (iEtype != 1) && (iEtype != 2) && (iEtype != 3))
-        MNG_ERROR (pData, MNG_INVENTRYTYPE);
-
-      pTemp++;
-
-      if (iEtype > 1)
-      {
-        iOffset    [0] = 0;
-        iOffset    [1] = 0;
-        iStarttime [0] = 0;
-        iStarttime [1] = 0;
-        iLayernr       = 0;
-        iFramenr       = 0;
-      }
-      else
-      {
-        if (iOtype == 4)
-        {
-          iOffset [0] = 0;
-          iOffset [1] = mng_get_uint32 (pTemp);
-
-          pTemp += 4;
-        }
-        else
-        {
-          iOffset [0] = mng_get_uint32 (pTemp);
-          iOffset [1] = mng_get_uint32 (pTemp+4);
-
-          pTemp += 8;
-        }
-
-        if (iEtype > 0)
-        {
-          iStarttime [0] = 0;
-          iStarttime [1] = 0;
-          iLayernr       = 0;
-          iFramenr       = 0;
-        }
-        else
-        {
-          if (iOtype == 4)
-          {
-            iStarttime [0] = 0;
-            iStarttime [1] = mng_get_uint32 (pTemp+0);
-            iLayernr       = mng_get_uint32 (pTemp+4);
-            iFramenr       = mng_get_uint32 (pTemp+8);
-
-            pTemp += 12;
-          }
-          else
-          {
-            iStarttime [0] = mng_get_uint32 (pTemp+0);
-            iStarttime [1] = mng_get_uint32 (pTemp+4);
-            iLayernr       = mng_get_uint32 (pTemp+8);
-            iFramenr       = mng_get_uint32 (pTemp+12);
-
-            pTemp += 16;
-          }
-        }
-      }
-
-      pNull = pTemp;               /* get the name length */
-      while (*pNull)
-        pNull++;
-
-      if ((pNull - pRawdata) > (mng_int32)iRawlen)
-      {
-        iNamesize = iLen;          /* no null found; so end of SAVE */
-        iLen      = 0;
-      }
-      else
-      {
-        iNamesize = pNull - pTemp; /* should be another entry */
-        iLen     -= iNamesize;
-
-        if (!iLen)                 /* must not end with a null ! */
-          MNG_ERROR (pData, MNG_ENDWITHNULL);
-      }
-
-      if (!pEntry)
-      {
-        iCount++;
-      }
-      else
-      {
-        pEntry->iEntrytype     = iEtype;
-        pEntry->iOffset    [0] = iOffset    [0];
-        pEntry->iOffset    [1] = iOffset    [1];
-        pEntry->iStarttime [0] = iStarttime [0];
-        pEntry->iStarttime [1] = iStarttime [1];
-        pEntry->iLayernr       = iLayernr;
-        pEntry->iFramenr       = iFramenr;
-        pEntry->iNamesize      = iNamesize;
-
-        if (iNamesize)
-        {
-          MNG_ALLOC (pData, pEntry->zName, iNamesize+1);
-          MNG_COPY (pEntry->zName, pTemp, iNamesize);
-        }
-
-        pEntry++;
-      }
-
-      pTemp += iNamesize;
-    }
-  }
-
-  *piRawlen = 0;
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_SAVE
-MNG_C_SPECIALFUNC (mng_special_save)
-{
-  pData->bHasSAVE = MNG_TRUE;
-
-  if (pData->fProcesssave)             /* inform the application ? */
-  {
-    mng_bool bOke = pData->fProcesssave ((mng_handle)pData);
-    if (!bOke)
-      MNG_ERROR (pData, MNG_APPMISCERROR);
-  }
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-    mng_retcode iRetcode;
-
-    /* TODO: something with the parameters */
-
-                                       /* create a SAVE animation object */
-    iRetcode = mng_create_ani_save (pData);
-    if (!iRetcode)                     /* process it */
-      iRetcode = mng_process_display_save (pData);
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_SEEK
-MNG_C_SPECIALFUNC (mng_special_seek)
-{
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_DISPLAY
-                                       /* create a SEEK animation object */
-  iRetcode = mng_create_ani_seek (pData, pChunk);
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-
-#endif /* MNG_SUPPORT_DISPLAY */
-
-  if (pData->fProcessseek)             /* inform the app ? */
-    if (!pData->fProcessseek ((mng_handle)pData, ((mng_seekp)pChunk)->zName))
-      MNG_ERROR (pData, MNG_APPMISCERROR);
-
-#ifdef MNG_SUPPORT_DISPLAY
-  return mng_process_display_seek (pData);
-#else
-  return MNG_NOERROR;                  
-#endif /* MNG_SUPPORT_DISPLAY */
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_eXPI
-MNG_C_SPECIALFUNC (mng_special_expi)
-{
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-
-
-    /* TODO: something !!! */
-
-
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_fPRI
-MNG_C_SPECIALFUNC (mng_special_fpri)
-{
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-
-
-    /* TODO: something !!! */
-
-
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_nEED
-MNG_LOCAL mng_bool CheckKeyword (mng_datap  pData,
-                                 mng_uint8p pKeyword)
-{
-  mng_chunkid handled_chunks [] =
-  {
-    MNG_UINT_BACK,                     /* keep it sorted !!!! */
-    MNG_UINT_BASI,
-    MNG_UINT_CLIP,
-    MNG_UINT_CLON,
-#ifndef MNG_NO_DELTA_PNG
-/* TODO:    MNG_UINT_DBYK,  */
-#endif
-    MNG_UINT_DEFI,
-#ifndef MNG_NO_DELTA_PNG
-    MNG_UINT_DHDR,
-#endif
-    MNG_UINT_DISC,
-#ifndef MNG_NO_DELTA_PNG
-/* TODO:    MNG_UINT_DROP,  */
-#endif
-    MNG_UINT_ENDL,
-    MNG_UINT_FRAM,
-    MNG_UINT_IDAT,
-    MNG_UINT_IEND,
-    MNG_UINT_IHDR,
-#ifndef MNG_NO_DELTA_PNG
-#ifdef MNG_INCLUDE_JNG
-    MNG_UINT_IJNG,
-#endif    
-    MNG_UINT_IPNG,
-#endif
-#ifdef MNG_INCLUDE_JNG
-    MNG_UINT_JDAA,
-    MNG_UINT_JDAT,
-    MNG_UINT_JHDR,
-/* TODO:    MNG_UINT_JSEP,  */
-    MNG_UINT_JdAA,
-#endif
-    MNG_UINT_LOOP,
-    MNG_UINT_MAGN,
-    MNG_UINT_MEND,
-    MNG_UINT_MHDR,
-    MNG_UINT_MOVE,
-/* TODO:    MNG_UINT_ORDR,  */
-    MNG_UINT_PAST,
-    MNG_UINT_PLTE,
-#ifndef MNG_NO_DELTA_PNG
-    MNG_UINT_PPLT,
-    MNG_UINT_PROM,
-#endif
-    MNG_UINT_SAVE,
-    MNG_UINT_SEEK,
-    MNG_UINT_SHOW,
-    MNG_UINT_TERM,
-    MNG_UINT_bKGD,
-    MNG_UINT_cHRM,
-/* TODO:    MNG_UINT_eXPI,  */
-    MNG_UINT_evNT,
-/* TODO:    MNG_UINT_fPRI,  */
-    MNG_UINT_gAMA,
-/* TODO:    MNG_UINT_hIST,  */
-    MNG_UINT_iCCP,
-    MNG_UINT_iTXt,
-    MNG_UINT_nEED,
-/* TODO:    MNG_UINT_oFFs,  */
-/* TODO:    MNG_UINT_pCAL,  */
-/* TODO:    MNG_UINT_pHYg,  */
-/* TODO:    MNG_UINT_pHYs,  */
-/* TODO:    MNG_UINT_sBIT,  */
-/* TODO:    MNG_UINT_sCAL,  */
-/* TODO:    MNG_UINT_sPLT,  */
-    MNG_UINT_sRGB,
-    MNG_UINT_tEXt,
-    MNG_UINT_tIME,
-    MNG_UINT_tRNS,
-    MNG_UINT_zTXt,
-  };
-
-  mng_bool bOke = MNG_FALSE;
-
-  if (pData->fProcessneed)             /* does the app handle it ? */
-    bOke = pData->fProcessneed ((mng_handle)pData, (mng_pchar)pKeyword);
-
-  if (!bOke)
-  {                                    /* find the keyword length */
-    mng_uint8p pNull = pKeyword;
-    while (*pNull)
-      pNull++;
-
-    if ((pNull - pKeyword) == 4)       /* test a chunk ? */
-    {                                  /* get the chunk-id */
-      mng_chunkid iChunkid = (*pKeyword     << 24) + (*(pKeyword+1) << 16) +
-                             (*(pKeyword+2) <<  8) + (*(pKeyword+3)      );
-                                       /* binary search variables */
-      mng_int32   iTop, iLower, iUpper, iMiddle;
-                                       /* determine max index of table */
-      iTop = (sizeof (handled_chunks) / sizeof (handled_chunks [0])) - 1;
-
-      /* binary search; with 52 chunks, worst-case is 7 comparisons */
-      iLower  = 0;
-      iMiddle = iTop >> 1;
-      iUpper  = iTop;
-
-      do                                   /* the binary search itself */
-        {
-          if (handled_chunks [iMiddle] < iChunkid)
-            iLower = iMiddle + 1;
-          else if (handled_chunks [iMiddle] > iChunkid)
-            iUpper = iMiddle - 1;
-          else
-          {
-            bOke = MNG_TRUE;
-            break;
-          }
-
-          iMiddle = (iLower + iUpper) >> 1;
-        }
-      while (iLower <= iUpper);
-    }
-                                       /* test draft ? */
-    if ((!bOke) && ((pNull - pKeyword) == 8) &&
-        (*pKeyword     == 'd') && (*(pKeyword+1) == 'r') &&
-        (*(pKeyword+2) == 'a') && (*(pKeyword+3) == 'f') &&
-        (*(pKeyword+4) == 't') && (*(pKeyword+5) == ' '))
-    {
-      mng_uint32 iDraft;
-
-      iDraft = (*(pKeyword+6) - '0') * 10 + (*(pKeyword+7) - '0');
-      bOke   = (mng_bool)(iDraft <= MNG_MNG_DRAFT);
-    }
-                                       /* test MNG 1.0/1.1 ? */
-    if ((!bOke) && ((pNull - pKeyword) == 7) &&
-        (*pKeyword     == 'M') && (*(pKeyword+1) == 'N') &&
-        (*(pKeyword+2) == 'G') && (*(pKeyword+3) == '-') &&
-        (*(pKeyword+4) == '1') && (*(pKeyword+5) == '.') &&
-        ((*(pKeyword+6) == '0') || (*(pKeyword+6) == '1')))
-      bOke   = MNG_TRUE;
-                                       /* test CACHEOFF ? */
-    if ((!bOke) && ((pNull - pKeyword) == 8) &&
-        (*pKeyword     == 'C') && (*(pKeyword+1) == 'A') &&
-        (*(pKeyword+2) == 'C') && (*(pKeyword+3) == 'H') &&
-        (*(pKeyword+4) == 'E') && (*(pKeyword+5) == 'O') &&
-        (*(pKeyword+6) == 'F') && (*(pKeyword+7) == 'F'))
-    {
-      if (!pData->pFirstaniobj)        /* only if caching hasn't started yet ! */
-      {
-        bOke                  = MNG_TRUE;
-        pData->bCacheplayback = MNG_FALSE;
-        pData->bStorechunks   = MNG_FALSE;
-      }
-    }
-  }
-
-  return bOke;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_nEED
-MNG_C_SPECIALFUNC (mng_special_need)
-{
-                                       /* let's check it */
-  mng_bool   bOke = MNG_TRUE;
-  mng_uint8p pNull, pTemp, pMax;
-
-  pTemp = (mng_uint8p)((mng_needp)pChunk)->zKeywords;
-  pMax  = (mng_uint8p)(pTemp + ((mng_needp)pChunk)->iKeywordssize);
-  pNull = pTemp;
-  while (*pNull)
-    pNull++;
-
-  while ((bOke) && (pNull < pMax))
-  {
-    bOke  = CheckKeyword (pData, pTemp);
-    pTemp = pNull + 1;
-    pNull = pTemp;
-    while (*pNull)
-      pNull++;
-  }
-
-  if (bOke)
-    bOke = CheckKeyword (pData, pTemp);
-
-  if (!bOke)
-    MNG_ERROR (pData, MNG_UNSUPPORTEDNEED);
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_pHYg
-MNG_C_SPECIALFUNC (mng_special_phyg)
-{
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-
-
-    /* TODO: something !!! */
-
-
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-MNG_C_SPECIALFUNC (mng_special_dhdr)
-{
-  if ((((mng_dhdrp)pChunk)->iDeltatype == MNG_DELTATYPE_REPLACE) && (((mng_dhdrp)pChunk)->bHasblockloc))
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-  if ((((mng_dhdrp)pChunk)->iDeltatype == MNG_DELTATYPE_NOCHANGE) && (((mng_dhdrp)pChunk)->bHasblocksize))
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-  pData->bHasDHDR   = MNG_TRUE;        /* inside a DHDR-IEND block now */
-  pData->iDeltatype = ((mng_dhdrp)pChunk)->iDeltatype;
-
-  pData->iImagelevel++;                /* one level deeper */
-
-#ifdef MNG_SUPPORT_DISPLAY
-  return mng_create_ani_dhdr (pData, pChunk);
-#else
-  return MNG_NOERROR;                  
-#endif /* MNG_SUPPORT_DISPLAY */
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-MNG_C_SPECIALFUNC (mng_special_prom)
-{
-  if ((((mng_promp)pChunk)->iColortype != MNG_COLORTYPE_GRAY   ) &&
-      (((mng_promp)pChunk)->iColortype != MNG_COLORTYPE_RGB    ) &&
-      (((mng_promp)pChunk)->iColortype != MNG_COLORTYPE_INDEXED) &&
-      (((mng_promp)pChunk)->iColortype != MNG_COLORTYPE_GRAYA  ) &&
-      (((mng_promp)pChunk)->iColortype != MNG_COLORTYPE_RGBA   )    )
-    MNG_ERROR (pData, MNG_INVALIDCOLORTYPE);
-
-#ifdef MNG_NO_16BIT_SUPPORT
-  if (((mng_promp)pChunk)->iSampledepth == MNG_BITDEPTH_16 )
-      ((mng_promp)pChunk)->iSampledepth = MNG_BITDEPTH_8;
-#endif
-
-  if ((((mng_promp)pChunk)->iSampledepth != MNG_BITDEPTH_1 ) &&
-      (((mng_promp)pChunk)->iSampledepth != MNG_BITDEPTH_2 ) &&
-      (((mng_promp)pChunk)->iSampledepth != MNG_BITDEPTH_4 ) &&
-      (((mng_promp)pChunk)->iSampledepth != MNG_BITDEPTH_8 )
-#ifndef MNG_NO_16BIT_SUPPORT
-      && (((mng_promp)pChunk)->iSampledepth != MNG_BITDEPTH_16)
-#endif
-    )
-    MNG_ERROR (pData, MNG_INVSAMPLEDEPTH);
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-    mng_retcode iRetcode = mng_create_ani_prom (pData, pChunk);
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-MNG_C_SPECIALFUNC (mng_special_ipng)
-{
-#ifdef MNG_SUPPORT_DISPLAY
-  mng_retcode iRetcode = mng_create_ani_ipng (pData);
-  if (!iRetcode)                       /* process it */
-    iRetcode = mng_process_display_ipng (pData);
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-#endif /* MNG_SUPPORT_DISPLAY */
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-MNG_F_SPECIALFUNC (mng_pplt_entries)
-{
-  mng_ppltp     pPPLT      = (mng_ppltp)pChunk;
-  mng_uint32    iRawlen    = *piRawlen;
-  mng_uint8p    pRawdata   = *ppRawdata;
-  mng_uint8     iDeltatype = pPPLT->iDeltatype;
-  mng_uint32    iMax       = 0;
-  mng_int32     iX, iY, iM;
-  mng_rgbpaltab aIndexentries;
-  mng_uint8arr  aAlphaentries;
-  mng_uint8arr  aUsedentries;
-                                       /* must be indexed color ! */
-  if (pData->iColortype != MNG_COLORTYPE_INDEXED)
-    MNG_ERROR (pData, MNG_INVALIDCOLORTYPE);
-
-  for (iY = 255; iY >= 0; iY--)        /* reset arrays */
-  {
-    aIndexentries [iY].iRed   = 0;
-    aIndexentries [iY].iGreen = 0;
-    aIndexentries [iY].iBlue  = 0;
-    aAlphaentries [iY]        = 255;
-    aUsedentries  [iY]        = 0;
-  }
-
-  while (iRawlen)                      /* as long as there are entries left ... */
-  {
-    mng_uint32 iDiff;
-
-    if (iRawlen < 2)
-      MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-    iX = (mng_int32)(*pRawdata);      /* get start and end index */
-    iM = (mng_int32)(*(pRawdata+1));
-
-    if (iM < iX)
-      MNG_ERROR (pData, MNG_INVALIDINDEX);
-
-    if (iM >= (mng_int32) iMax)       /* determine highest used index */
-      iMax = iM + 1;
-
-    pRawdata += 2;
-    iRawlen  -= 2;
-    iDiff = (iM - iX + 1);
-    if ((iDeltatype == MNG_DELTATYPE_REPLACERGB  ) ||
-        (iDeltatype == MNG_DELTATYPE_DELTARGB    )    )
-      iDiff = iDiff * 3;
-    else
-    if ((iDeltatype == MNG_DELTATYPE_REPLACERGBA) ||
-        (iDeltatype == MNG_DELTATYPE_DELTARGBA  )    )
-      iDiff = iDiff * 4;
-
-    if (iRawlen < iDiff)
-      MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-    if ((iDeltatype == MNG_DELTATYPE_REPLACERGB  ) ||
-        (iDeltatype == MNG_DELTATYPE_DELTARGB    )    )
-    {
-      for (iY = iX; iY <= iM; iY++)
-      {
-        aIndexentries [iY].iRed   = *pRawdata;
-        aIndexentries [iY].iGreen = *(pRawdata+1);
-        aIndexentries [iY].iBlue  = *(pRawdata+2);
-        aUsedentries  [iY]        = 1;
-
-        pRawdata += 3;
-        iRawlen  -= 3;
-      }
-    }
-    else
-    if ((iDeltatype == MNG_DELTATYPE_REPLACEALPHA) ||
-        (iDeltatype == MNG_DELTATYPE_DELTAALPHA  )    )
-    {
-      for (iY = iX; iY <= iM; iY++)
-      {
-        aAlphaentries [iY]        = *pRawdata;
-        aUsedentries  [iY]        = 1;
-
-        pRawdata++;
-        iRawlen--;
-      }
-    }
-    else
-    {
-      for (iY = iX; iY <= iM; iY++)
-      {
-        aIndexentries [iY].iRed   = *pRawdata;
-        aIndexentries [iY].iGreen = *(pRawdata+1);
-        aIndexentries [iY].iBlue  = *(pRawdata+2);
-        aAlphaentries [iY]        = *(pRawdata+3);
-        aUsedentries  [iY]        = 1;
-
-        pRawdata += 4;
-        iRawlen  -= 4;
-      }
-    }
-  }
-
-  switch (pData->iBitdepth)            /* check maximum allowed entries for bitdepth */
-  {
-    case MNG_BITDEPTH_1 : {
-                            if (iMax > 2)
-                              MNG_ERROR (pData, MNG_INVALIDINDEX);
-                            break;
-                          }
-    case MNG_BITDEPTH_2 : {
-                            if (iMax > 4)
-                              MNG_ERROR (pData, MNG_INVALIDINDEX);
-                            break;
-                          }
-    case MNG_BITDEPTH_4 : {
-                            if (iMax > 16)
-                              MNG_ERROR (pData, MNG_INVALIDINDEX);
-                            break;
-                          }
-  }
-
-  pPPLT->iCount = iMax;
-
-  for (iY = 255; iY >= 0; iY--)        
-  {
-    pPPLT->aEntries [iY].iRed   = aIndexentries [iY].iRed;
-    pPPLT->aEntries [iY].iGreen = aIndexentries [iY].iGreen;
-    pPPLT->aEntries [iY].iBlue  = aIndexentries [iY].iBlue;
-    pPPLT->aEntries [iY].iAlpha = aAlphaentries [iY];
-    pPPLT->aEntries [iY].bUsed  = (mng_bool)(aUsedentries [iY]);
-  }
-
-  {                                    /* create animation object */
-    mng_retcode iRetcode = mng_create_ani_pplt (pData, iDeltatype, iMax,
-                                                aIndexentries, aAlphaentries,
-                                                aUsedentries);
-    if (iRetcode)
-      return iRetcode;
-  }
-
-  *piRawlen = 0;
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-MNG_C_SPECIALFUNC (mng_special_pplt)
-{
-  return MNG_NOERROR;                 
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-#ifdef MNG_INCLUDE_JNG
-MNG_C_SPECIALFUNC (mng_special_ijng)
-{
-#ifdef MNG_SUPPORT_DISPLAY
-  mng_retcode iRetcode = mng_create_ani_ijng (pData);
-  if (!iRetcode)                       /* process it */
-    iRetcode = mng_process_display_ijng (pData);
-  return iRetcode;
-#else
-  return MNG_NOERROR;                  /* done */
-#endif /* MNG_SUPPORT_DISPLAY */
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-MNG_F_SPECIALFUNC (mng_drop_entries)
-{
-  mng_dropp   pDROP    = (mng_dropp)pChunk;
-  mng_uint32  iRawlen  = *piRawlen;
-  mng_uint8p  pRawdata = *ppRawdata;
-  mng_uint32  iX;
-  mng_uint32p pEntry;
-                                       /* check length */
-  if ((iRawlen < 4) || ((iRawlen % 4) != 0))
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-  MNG_ALLOC (pData, pEntry, iRawlen);
-  pDROP->iCount      = iRawlen / 4;
-  pDROP->pChunknames = (mng_ptr)pEntry;
-
-  for (iX = pDROP->iCount; iX > 0; iX--)
-  {
-    *pEntry++ = mng_get_uint32 (pRawdata);
-    pRawdata += 4;
-  }
-
-  *piRawlen = 0;
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-MNG_C_SPECIALFUNC (mng_special_drop)
-{
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-
-
-    /* TODO: something !!! */
-
-
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_SKIPCHUNK_DBYK
-MNG_C_SPECIALFUNC (mng_special_dbyk)
-{
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-
-
-    /* TODO: something !!! */
-
-
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_SKIPCHUNK_ORDR
-MNG_F_SPECIALFUNC (mng_ordr_entries)
-{
-  mng_ordrp       pORDR    = (mng_ordrp)pChunk;
-  mng_uint32      iRawlen  = *piRawlen;
-  mng_uint8p      pRawdata = *ppRawdata;
-  mng_uint32      iX;
-  mng_ordr_entryp pEntry;
-                                       /* check length */
-  if ((iRawlen < 5) || ((iRawlen % 5) != 0))
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-  MNG_ALLOC (pData, pEntry, iRawlen);
-  pORDR->iCount   = iRawlen / 5;
-  pORDR->pEntries = (mng_ptr)pEntry;
-
-  for (iX = pORDR->iCount; iX > 0; iX--)
-  {
-    pEntry->iChunkname = mng_get_uint32 (pRawdata);
-    pEntry->iOrdertype = *(pRawdata+4);
-    pEntry++;
-    pRawdata += 5;
-  }
-
-  *piRawlen = 0;
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_SKIPCHUNK_ORDR
-MNG_C_SPECIALFUNC (mng_special_ordr)
-{
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-
-
-    /* TODO: something !!! */
-
-
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_MAGN
-MNG_F_SPECIALFUNC (mng_debunk_magn)
-{
-  mng_magnp  pMAGN    = (mng_magnp)pChunk;
-  mng_uint32 iRawlen  = *piRawlen;
-  mng_uint8p pRawdata = *ppRawdata;
-  mng_bool   bFaulty;
-                                       /* check length */
-  if (iRawlen > 20)
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-  /* following is an ugly hack to allow faulty layout caused by previous
-     versions of libmng and MNGeye, which wrote MAGN with a 16-bit
-     MethodX/MethodY (as opposed to the proper 8-bit as defined in the spec!) */
-
-  if ((iRawlen ==  6) || (iRawlen ==  8) || (iRawlen == 10) || (iRawlen == 12) ||
-      (iRawlen == 14) || (iRawlen == 16) || (iRawlen == 20))
-    bFaulty = MNG_TRUE;                /* these lengths are all wrong */
-  else                                 /* length 18 can be right or wrong !!! */
-  if ((iRawlen ==  18) && (mng_get_uint16 (pRawdata+4) <= 5) &&
-      (mng_get_uint16 (pRawdata+6)  < 256) &&
-      (mng_get_uint16 (pRawdata+8)  < 256) &&
-      (mng_get_uint16 (pRawdata+10) < 256) &&
-      (mng_get_uint16 (pRawdata+12) < 256) &&
-      (mng_get_uint16 (pRawdata+14) < 256) &&
-      (mng_get_uint16 (pRawdata+16) < 256))
-    bFaulty = MNG_TRUE;                /* this is very likely the wrong layout */
-  else
-    bFaulty = MNG_FALSE;               /* all other cases are handled as right */
-
-  if (bFaulty)                         /* wrong layout ? */
-  {
-    if (iRawlen > 0)                   /* get the fields */
-      pMAGN->iFirstid = mng_get_uint16 (pRawdata);
-    else
-      pMAGN->iFirstid = 0;
-
-    if (iRawlen > 2)
-      pMAGN->iLastid  = mng_get_uint16 (pRawdata+2);
-    else
-      pMAGN->iLastid  = pMAGN->iFirstid;
-
-    if (iRawlen > 4)
-      pMAGN->iMethodX = (mng_uint8)(mng_get_uint16 (pRawdata+4));
-    else
-      pMAGN->iMethodX = 0;
-
-    if (iRawlen > 6)
-      pMAGN->iMX      = mng_get_uint16 (pRawdata+6);
-    else
-      pMAGN->iMX      = 1;
-
-    if (iRawlen > 8)
-      pMAGN->iMY      = mng_get_uint16 (pRawdata+8);
-    else
-      pMAGN->iMY      = pMAGN->iMX;
-
-    if (iRawlen > 10)
-      pMAGN->iML      = mng_get_uint16 (pRawdata+10);
-    else
-      pMAGN->iML      = pMAGN->iMX;
-
-    if (iRawlen > 12)
-      pMAGN->iMR      = mng_get_uint16 (pRawdata+12);
-    else
-      pMAGN->iMR      = pMAGN->iMX;
-
-    if (iRawlen > 14)
-      pMAGN->iMT      = mng_get_uint16 (pRawdata+14);
-    else
-      pMAGN->iMT      = pMAGN->iMY;
-
-    if (iRawlen > 16)
-      pMAGN->iMB      = mng_get_uint16 (pRawdata+16);
-    else
-      pMAGN->iMB      = pMAGN->iMY;
-
-    if (iRawlen > 18)
-      pMAGN->iMethodY = (mng_uint8)(mng_get_uint16 (pRawdata+18));
-    else
-      pMAGN->iMethodY = pMAGN->iMethodX;
-  }
-  else                                 /* proper layout !!!! */
-  {
-    if (iRawlen > 0)                   /* get the fields */
-      pMAGN->iFirstid = mng_get_uint16 (pRawdata);
-    else
-      pMAGN->iFirstid = 0;
-
-    if (iRawlen > 2)
-      pMAGN->iLastid  = mng_get_uint16 (pRawdata+2);
-    else
-      pMAGN->iLastid  = pMAGN->iFirstid;
-
-    if (iRawlen > 4)
-      pMAGN->iMethodX = *(pRawdata+4);
-    else
-      pMAGN->iMethodX = 0;
-
-    if (iRawlen > 5)
-      pMAGN->iMX      = mng_get_uint16 (pRawdata+5);
-    else
-      pMAGN->iMX      = 1;
-
-    if (iRawlen > 7)
-      pMAGN->iMY      = mng_get_uint16 (pRawdata+7);
-    else
-      pMAGN->iMY      = pMAGN->iMX;
-
-    if (iRawlen > 9)
-      pMAGN->iML      = mng_get_uint16 (pRawdata+9);
-    else
-      pMAGN->iML      = pMAGN->iMX;
-
-    if (iRawlen > 11)
-      pMAGN->iMR      = mng_get_uint16 (pRawdata+11);
-    else
-      pMAGN->iMR      = pMAGN->iMX;
-
-    if (iRawlen > 13)
-      pMAGN->iMT      = mng_get_uint16 (pRawdata+13);
-    else
-      pMAGN->iMT      = pMAGN->iMY;
-
-    if (iRawlen > 15)
-      pMAGN->iMB      = mng_get_uint16 (pRawdata+15);
-    else
-      pMAGN->iMB      = pMAGN->iMY;
-
-    if (iRawlen > 17)
-      pMAGN->iMethodY = *(pRawdata+17);
-    else
-      pMAGN->iMethodY = pMAGN->iMethodX;
-  }
-                                       /* check field validity */
-  if ((pMAGN->iMethodX > 5) || (pMAGN->iMethodY > 5))
-    MNG_ERROR (pData, MNG_INVALIDMETHOD);
-
-  *piRawlen = 0;
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_MAGN
-MNG_C_SPECIALFUNC (mng_special_magn)
-{
-#ifdef MNG_SUPPORT_DISPLAY
-  return mng_create_ani_magn (pData, pChunk);
-#else
-  return MNG_NOERROR;                  
-#endif /* MNG_SUPPORT_DISPLAY */
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_evNT
-MNG_F_SPECIALFUNC (mng_evnt_entries)
-{
-  mng_evntp       pEVNT = (mng_evntp)pChunk;
-  mng_uint32      iRawlen;
-  mng_uint8p      pRawdata;
-#if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_SUPPORT_DYNAMICMNG)
-  mng_retcode     iRetcode;
-#endif
-  mng_uint8p      pNull;
-  mng_uint8       iEventtype;
-  mng_uint8       iMasktype;
-  mng_int32       iLeft;
-  mng_int32       iRight;
-  mng_int32       iTop;
-  mng_int32       iBottom;
-  mng_uint16      iObjectid;
-  mng_uint8       iIndex;
-  mng_uint32      iNamesize;
-  mng_uint32      iCount = 0;
-  mng_evnt_entryp pEntry = MNG_NULL;
-  mng_uint32      iX;
-
-  for (iX = 0; iX < 2; iX++)
-  {
-    iRawlen  = *piRawlen;
-    pRawdata = *ppRawdata;
-
-    if (iX)                            /* second run ? */
-    {
-      MNG_ALLOC (pData, pEntry, (iCount * sizeof (mng_evnt_entry)));
-      pEVNT->iCount   = iCount;
-      pEVNT->pEntries = pEntry;
-    }
-
-    while (iRawlen)                    /* anything left ? */
-    {
-      if (iRawlen < 2)                 /* must have at least 2 bytes ! */
-        MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-      iEventtype = *pRawdata;          /* eventtype */
-      if (iEventtype > 5)
-        MNG_ERROR (pData, MNG_INVALIDEVENT);
-
-      pRawdata++;
-
-      iMasktype  = *pRawdata;          /* masktype */
-      if (iMasktype > 5)
-        MNG_ERROR (pData, MNG_INVALIDMASK);
-
-      pRawdata++;
-      iRawlen -= 2;
-
-      iLeft     = 0;
-      iRight    = 0;
-      iTop      = 0;
-      iBottom   = 0;
-      iObjectid = 0;
-      iIndex    = 0;
-
-      switch (iMasktype)
-      {
-        case 1 :
-          {
-            if (iRawlen > 16)
-            {
-              iLeft     = mng_get_int32 (pRawdata);
-              iRight    = mng_get_int32 (pRawdata+4);
-              iTop      = mng_get_int32 (pRawdata+8);
-              iBottom   = mng_get_int32 (pRawdata+12);
-              pRawdata += 16;
-              iRawlen -= 16;
-            }
-            else
-              MNG_ERROR (pData, MNG_INVALIDLENGTH);
-            break;
-          }
-        case 2 :
-          {
-            if (iRawlen > 2)
-            {
-              iObjectid = mng_get_uint16 (pRawdata);
-              pRawdata += 2;
-              iRawlen -= 2;
-            }
-            else
-              MNG_ERROR (pData, MNG_INVALIDLENGTH);
-            break;
-          }
-        case 3 :
-          {
-            if (iRawlen > 3)
-            {
-              iObjectid = mng_get_uint16 (pRawdata);
-              iIndex    = *(pRawdata+2);
-              pRawdata += 3;
-              iRawlen -= 3;
-            }
-            else
-              MNG_ERROR (pData, MNG_INVALIDLENGTH);
-            break;
-          }
-        case 4 :
-          {
-            if (iRawlen > 18)
-            {
-              iLeft     = mng_get_int32 (pRawdata);
-              iRight    = mng_get_int32 (pRawdata+4);
-              iTop      = mng_get_int32 (pRawdata+8);
-              iBottom   = mng_get_int32 (pRawdata+12);
-              iObjectid = mng_get_uint16 (pRawdata+16);
-              pRawdata += 18;
-              iRawlen -= 18;
-            }
-            else
-              MNG_ERROR (pData, MNG_INVALIDLENGTH);
-            break;
-          }
-        case 5 :
-          {
-            if (iRawlen > 19)
-            {
-              iLeft     = mng_get_int32 (pRawdata);
-              iRight    = mng_get_int32 (pRawdata+4);
-              iTop      = mng_get_int32 (pRawdata+8);
-              iBottom   = mng_get_int32 (pRawdata+12);
-              iObjectid = mng_get_uint16 (pRawdata+16);
-              iIndex    = *(pRawdata+18);
-              pRawdata += 19;
-              iRawlen -= 19;
-            }
-            else
-              MNG_ERROR (pData, MNG_INVALIDLENGTH);
-            break;
-          }
-      }
-
-      pNull = pRawdata;                /* get the name length */
-      while (*pNull)
-        pNull++;
-
-      if ((pNull - pRawdata) > (mng_int32)iRawlen)
-      {
-        iNamesize = iRawlen;           /* no null found; so end of evNT */
-        iRawlen   = 0;
-      }
-      else
-      {
-        iNamesize = pNull - pRawdata;  /* should be another entry */
-        iRawlen   = iRawlen - iNamesize - 1;
-
-        if (!iRawlen)                  /* must not end with a null ! */
-          MNG_ERROR (pData, MNG_ENDWITHNULL);
-      }
-
-      if (!iX)
-      {
-        iCount++;
-      }
-      else
-      {
-        pEntry->iEventtype       = iEventtype;
-        pEntry->iMasktype        = iMasktype;
-        pEntry->iLeft            = iLeft;
-        pEntry->iRight           = iRight;
-        pEntry->iTop             = iTop;
-        pEntry->iBottom          = iBottom;
-        pEntry->iObjectid        = iObjectid;
-        pEntry->iIndex           = iIndex;
-        pEntry->iSegmentnamesize = iNamesize;
-
-        if (iNamesize)
-        {
-          MNG_ALLOC (pData, pEntry->zSegmentname, iNamesize+1);
-          MNG_COPY (pEntry->zSegmentname, pRawdata, iNamesize);
-        }
-
-#if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_SUPPORT_DYNAMICMNG)
-        iRetcode = mng_create_event (pData, (mng_ptr)pEntry);
-        if (iRetcode)                    /* on error bail out */
-          return iRetcode;
-#endif
-
-        pEntry++;
-      }
-
-      pRawdata = pRawdata + iNamesize + 1;
-    }
-  }
-
-  *piRawlen = 0;
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_evNT
-MNG_C_SPECIALFUNC (mng_special_evnt)
-{
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-MNG_C_SPECIALFUNC (mng_special_mpng)
-{
-  if ((pData->eImagetype != mng_it_png) && (pData->eImagetype != mng_it_jng))
-    MNG_ERROR (pData, MNG_CHUNKNOTALLOWED);
-    
-#ifdef MNG_SUPPORT_DISPLAY
-  return mng_create_mpng_obj (pData, pChunk);
-#else
-  return MNG_NOERROR;
-#endif
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_ANG_PROPOSAL
-MNG_C_SPECIALFUNC (mng_special_ahdr)
-{
-#ifdef MNG_SUPPORT_DISPLAY
-  return mng_create_ang_obj (pData, pChunk);
-#else
-  return MNG_NOERROR;
-#endif
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_ANG_PROPOSAL
-MNG_F_SPECIALFUNC (mng_adat_tiles)
-{
-  if ((pData->eImagetype != mng_it_ang) || (!pData->pANG))
-    MNG_ERROR (pData, MNG_CHUNKNOTALLOWED);
-
-  {
-    mng_adatp      pADAT = (mng_adatp)pChunk;
-    mng_ang_objp   pANG  = (mng_ang_objp)pData->pANG;
-    mng_uint32     iRawlen  = *piRawlen;
-    mng_uint8p     pRawdata = *ppRawdata;
-    mng_retcode    iRetcode;
-    mng_uint8p     pBuf;
-    mng_uint32     iBufsize;
-    mng_uint32     iRealsize;
-    mng_uint8p     pTemp;
-    mng_uint8p     pTemp2;
-    mng_int32      iX;
-    mng_int32      iSize;
-
-#ifdef MNG_SUPPORT_DISPLAY
-    mng_imagep     pImage;
-    mng_int32      iTemplen;
-    mng_uint8p     pSwap;
-
-    mng_processobject pProcess;
-
-    mng_uint32     iSavedatawidth;
-    mng_uint32     iSavedataheight;
-
-    mng_fptr       fSaveinitrowproc;
-    mng_fptr       fSavestorerow;
-    mng_fptr       fSaveprocessrow;
-    mng_fptr       fSavedifferrow;
-    mng_imagep     fSavestoreobj;
-    mng_imagedatap fSavestorebuf;
-
-#ifdef MNG_OPTIMIZE_FOOTPRINT_INIT
-    png_imgtype    eSavepngimgtype;
-#endif
-
-    mng_uint8      iSaveinterlace;
-    mng_int8       iSavepass;
-    mng_int32      iSaverow;
-    mng_int32      iSaverowinc;
-    mng_int32      iSavecol;
-    mng_int32      iSavecolinc;
-    mng_int32      iSaverowsamples;
-    mng_int32      iSavesamplemul;
-    mng_int32      iSavesampleofs;
-    mng_int32      iSavesamplediv;
-    mng_int32      iSaverowsize;
-    mng_int32      iSaverowmax;
-    mng_int32      iSavefilterofs;
-    mng_int32      iSavepixelofs;
-    mng_uint32     iSavelevel0;
-    mng_uint32     iSavelevel1;
-    mng_uint32     iSavelevel2;
-    mng_uint32     iSavelevel3;
-    mng_uint8p     pSaveworkrow;
-    mng_uint8p     pSaveprevrow;
-    mng_uint8p     pSaverGBArow;
-    mng_bool       bSaveisRGBA16;
-    mng_bool       bSaveisOpaque;
-    mng_int32      iSavefilterbpp;
-
-    mng_int32      iSavedestl;
-    mng_int32      iSavedestt;
-    mng_int32      iSavedestr;
-    mng_int32      iSavedestb;
-    mng_int32      iSavesourcel;
-    mng_int32      iSavesourcet;
-    mng_int32      iSavesourcer;
-    mng_int32      iSavesourceb;
-#endif /* MNG_SUPPORT_DISPLAY */
-
-    iRetcode = mng_inflate_buffer (pData, pRawdata, iRawlen,
-                                   &pBuf, &iBufsize, &iRealsize);
-    if (iRetcode)                      /* on error bail out */
-    {                                  /* don't forget to drop the temp buffer */
-      MNG_FREEX (pData, pBuf, iBufsize);
-      return iRetcode;
-    }
-                                       /* get buffer for tile info in ADAT chunk */
-    pADAT->iTilessize = pANG->iNumframes * sizeof(mng_adat_tile);
-    MNG_ALLOCX (pData, pADAT->pTiles, pADAT->iTilessize);
-    if (!pADAT->pTiles)
-    {
-      pADAT->iTilessize = 0;
-      MNG_FREEX (pData, pBuf, iBufsize);
-      MNG_ERROR (pData, MNG_OUTOFMEMORY);
-    }
-
-    pTemp  = pBuf;
-    pTemp2 = (mng_uint8p)pADAT->pTiles;
-
-    if (!pANG->iStillused)
-      iSize = 12;
-    else
-      iSize = 13;
-
-    for (iX = 0; iX < pANG->iNumframes; iX++)
-    {
-      MNG_COPY (pTemp2, pTemp, iSize);
-      pTemp  += iSize;
-      pTemp2 += sizeof(mng_adat_tile);
-    }
-
-#ifdef MNG_SUPPORT_DISPLAY
-                                       /* get buffer for tile info in ANG object */
-    pANG->iTilessize = pADAT->iTilessize;
-    MNG_ALLOCX (pData, pANG->pTiles, pANG->iTilessize);
-    if (!pANG->pTiles)
-    {
-      pANG->iTilessize = 0;
-      MNG_FREEX (pData, pBuf, iBufsize);
-      MNG_ERROR (pData, MNG_OUTOFMEMORY);
-    }
-                                       /* copy it from the ADAT object */
-    MNG_COPY (pANG->pTiles, pADAT->pTiles, pANG->iTilessize);
-
-                                       /* save IDAT work-parms */
-    fSaveinitrowproc    = pData->fInitrowproc;
-    fSavestorerow       = pData->fDisplayrow;
-    fSaveprocessrow     = pData->fProcessrow;
-    fSavedifferrow      = pData->fDifferrow;
-    fSavestoreobj       = pData->pStoreobj;
-    fSavestorebuf       = pData->pStorebuf;
-
-#ifdef MNG_OPTIMIZE_FOOTPRINT_INIT
-    eSavepngimgtype     = pData->ePng_imgtype;
-#endif
-
-    iSavedatawidth      = pData->iDatawidth;
-    iSavedataheight     = pData->iDataheight;
-    iSaveinterlace      = pData->iInterlace;
-    iSavepass           = pData->iPass;
-    iSaverow            = pData->iRow;
-    iSaverowinc         = pData->iRowinc;
-    iSavecol            = pData->iCol;
-    iSavecolinc         = pData->iColinc;
-    iSaverowsamples     = pData->iRowsamples;
-    iSavesamplemul      = pData->iSamplemul;
-    iSavesampleofs      = pData->iSampleofs;
-    iSavesamplediv      = pData->iSamplediv;
-    iSaverowsize        = pData->iRowsize;
-    iSaverowmax         = pData->iRowmax;
-    iSavefilterofs      = pData->iFilterofs;
-    iSavepixelofs       = pData->iPixelofs;
-    iSavelevel0         = pData->iLevel0;
-    iSavelevel1         = pData->iLevel1;
-    iSavelevel2         = pData->iLevel2;
-    iSavelevel3         = pData->iLevel3;
-    pSaveworkrow        = pData->pWorkrow;
-    pSaveprevrow        = pData->pPrevrow;
-    pSaverGBArow        = pData->pRGBArow;
-    bSaveisRGBA16       = pData->bIsRGBA16;
-    bSaveisOpaque       = pData->bIsOpaque;
-    iSavefilterbpp      = pData->iFilterbpp;
-    iSavedestl          = pData->iDestl;
-    iSavedestt          = pData->iDestt;
-    iSavedestr          = pData->iDestr;
-    iSavedestb          = pData->iDestb;
-    iSavesourcel        = pData->iSourcel;
-    iSavesourcet        = pData->iSourcet;
-    iSavesourcer        = pData->iSourcer;
-    iSavesourceb        = pData->iSourceb;
-
-    pData->iDatawidth   = pANG->iTilewidth;
-    pData->iDataheight  = pANG->iTileheight;
-
-    pData->iDestl       = 0;
-    pData->iDestt       = 0;
-    pData->iDestr       = pANG->iTilewidth;
-    pData->iDestb       = pANG->iTileheight;
-    pData->iSourcel     = 0;
-    pData->iSourcet     = 0;
-    pData->iSourcer     = pANG->iTilewidth;
-    pData->iSourceb     = pANG->iTileheight;
-
-    pData->fInitrowproc = MNG_NULL;
-    pData->fStorerow    = MNG_NULL;
-    pData->fProcessrow  = MNG_NULL;
-    pData->fDifferrow   = MNG_NULL;
-
-    /* clone image object to store the pixel-data from object 0 */
-    iRetcode = mng_clone_imageobject (pData, 1, MNG_FALSE, MNG_FALSE, MNG_FALSE,
-                                      MNG_FALSE, 0, 0, 0, pData->pObjzero, &pImage);
-    if (iRetcode)                      /* on error, drop temp buffer and bail */
-    {
-      MNG_FREEX (pData, pBuf, iBufsize);
-      return iRetcode;
-    }
-
-    /* make sure we got the right dimensions and interlacing */
-    iRetcode = mng_reset_object_details (pData, pImage, pANG->iTilewidth, pANG->iTileheight,
-                                         pImage->pImgbuf->iBitdepth, pImage->pImgbuf->iColortype,
-                                         pImage->pImgbuf->iCompression, pImage->pImgbuf->iFilter,
-                                         pANG->iInterlace, MNG_FALSE);
-    if (iRetcode)                      /* on error, drop temp buffer and bail */
-    {
-      MNG_FREEX (pData, pBuf, iBufsize);
-      return iRetcode;
-    }
-
-    pData->pStoreobj    = pImage;
-
-#ifdef MNG_OPTIMIZE_FOOTPRINT_INIT
-    pData->fInitrowproc = (mng_fptr)mng_init_rowproc;
-    pData->ePng_imgtype = mng_png_imgtype(pData->iColortype,pData->iBitdepth);
-#else
-    switch (pData->iColortype)         /* determine row initialization routine */
-    {
-      case 0 : {                       /* gray */
-                 switch (pData->iBitdepth)
-                 {
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-                   case  1 : {
-                               if (!pData->iInterlace)
-                                 pData->fInitrowproc = (mng_fptr)mng_init_g1_ni;
-                               else
-                                 pData->fInitrowproc = (mng_fptr)mng_init_g1_i;
-
-                               break;
-                             }
-                   case  2 : {
-                               if (!pData->iInterlace)
-                                 pData->fInitrowproc = (mng_fptr)mng_init_g2_ni;
-                               else
-                                 pData->fInitrowproc = (mng_fptr)mng_init_g2_i;
-
-                               break;
-                             }
-                   case  4 : {
-                               if (!pData->iInterlace)
-                                 pData->fInitrowproc = (mng_fptr)mng_init_g4_ni;
-                               else
-                                 pData->fInitrowproc = (mng_fptr)mng_init_g4_i;
-                               break;
-                             }
-#endif /* MNG_NO_1_2_4BIT_SUPPORT */
-                   case  8 : {
-                               if (!pData->iInterlace)
-                                 pData->fInitrowproc = (mng_fptr)mng_init_g8_ni;
-                               else
-                                 pData->fInitrowproc = (mng_fptr)mng_init_g8_i;
-
-                               break;
-                             }
-#ifndef MNG_NO_16BIT_SUPPORT
-                   case 16 : {
-                               if (!pData->iInterlace)
-                                 pData->fInitrowproc = (mng_fptr)mng_init_g16_ni;
-                               else
-                                 pData->fInitrowproc = (mng_fptr)mng_init_g16_i;
-
-                               break;
-                             }
-#endif
-                 }
-
-                 break;
-               }
-      case 2 : {                       /* rgb */
-                 switch (pData->iBitdepth)
-                 {
-                   case  8 : {
-                               if (!pData->iInterlace)
-                                 pData->fInitrowproc = (mng_fptr)mng_init_rgb8_ni;
-                               else
-                                 pData->fInitrowproc = (mng_fptr)mng_init_rgb8_i;
-                               break;
-                             }
-#ifndef MNG_NO_16BIT_SUPPORT
-                   case 16 : {
-                               if (!pData->iInterlace)
-                                 pData->fInitrowproc = (mng_fptr)mng_init_rgb16_ni;
-                               else
-                                 pData->fInitrowproc = (mng_fptr)mng_init_rgb16_i;
-
-                               break;
-                             }
-#endif
-                 }
-
-                 break;
-               }
-      case 3 : {                       /* indexed */
-                 switch (pData->iBitdepth)
-                 {
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-                   case  1 : {
-                               if (!pData->iInterlace)
-                                 pData->fInitrowproc = (mng_fptr)mng_init_idx1_ni;
-                               else
-                                 pData->fInitrowproc = (mng_fptr)mng_init_idx1_i;
-
-                               break;
-                             }
-                   case  2 : {
-                               if (!pData->iInterlace)
-                                 pData->fInitrowproc = (mng_fptr)mng_init_idx2_ni;
-                               else
-                                 pData->fInitrowproc = (mng_fptr)mng_init_idx2_i;
-
-                               break;
-                             }
-                   case  4 : {
-                               if (!pData->iInterlace)
-                                 pData->fInitrowproc = (mng_fptr)mng_init_idx4_ni;
-                               else
-                                 pData->fInitrowproc = (mng_fptr)mng_init_idx4_i;
-
-                               break;
-                             }
-#endif /* MNG_NO_1_2_4BIT_SUPPORT */
-                   case  8 : {
-                               if (!pData->iInterlace)
-                                 pData->fInitrowproc = (mng_fptr)mng_init_idx8_ni;
-                               else
-                                 pData->fInitrowproc = (mng_fptr)mng_init_idx8_i;
-
-                               break;
-                             }
-                 }
-
-                 break;
-               }
-      case 4 : {                       /* gray+alpha */
-                 switch (pData->iBitdepth)
-                 {
-                   case  8 : {
-                               if (!pData->iInterlace)
-                                 pData->fInitrowproc = (mng_fptr)mng_init_ga8_ni;
-                               else
-                                 pData->fInitrowproc = (mng_fptr)mng_init_ga8_i;
-
-                               break;
-                             }
-#ifndef MNG_NO_16BIT_SUPPORT
-                   case 16 : {
-                               if (!pData->iInterlace)
-                                 pData->fInitrowproc = (mng_fptr)mng_init_ga16_ni;
-                               else
-                                 pData->fInitrowproc = (mng_fptr)mng_init_ga16_i;
-                               break;
-                             }
-#endif
-                 }
-
-                 break;
-               }
-      case 6 : {                       /* rgb+alpha */
-                 switch (pData->iBitdepth)
-                 {
-                   case  8 : {
-                               if (!pData->iInterlace)
-                                 pData->fInitrowproc = (mng_fptr)mng_init_rgba8_ni;
-                               else
-                                 pData->fInitrowproc = (mng_fptr)mng_init_rgba8_i;
-
-                               break;
-                             }
-#ifndef MNG_NO_16BIT_SUPPORT
-                   case 16 : {
-                               if (!pData->iInterlace)
-                                 pData->fInitrowproc = (mng_fptr)mng_init_rgba16_ni;
-                               else
-                                 pData->fInitrowproc = (mng_fptr)mng_init_rgba16_i;
-
-                               break;
-                             }
-#endif
-                 }
-
-                 break;
-               }
-    }
-#endif /* MNG_OPTIMIZE_FOOTPRINT_INIT */
-
-    pData->iFilterofs = 0;             /* determine filter characteristics */
-    pData->iLevel0    = 0;             /* default levels */
-    pData->iLevel1    = 0;    
-    pData->iLevel2    = 0;
-    pData->iLevel3    = 0;
-
-#ifdef FILTER192                       /* leveling & differing ? */
-    if (pData->iFilter == MNG_FILTER_DIFFERING)
-    {
-      switch (pData->iColortype)
-      {
-        case 0 : {
-                   if (pData->iBitdepth <= 8)
-                     pData->iFilterofs = 1;
-                   else
-                     pData->iFilterofs = 2;
-
-                   break;
-                 }
-        case 2 : {
-                   if (pData->iBitdepth <= 8)
-                     pData->iFilterofs = 3;
-                   else
-                     pData->iFilterofs = 6;
-
-                   break;
-                 }
-        case 3 : {
-                   pData->iFilterofs = 1;
-                   break;
-                 }
-        case 4 : {
-                   if (pData->iBitdepth <= 8)
-                     pData->iFilterofs = 2;
-                   else
-                     pData->iFilterofs = 4;
-
-                   break;
-                 }
-        case 6 : {
-                   if (pData->iBitdepth <= 8)
-                     pData->iFilterofs = 4;
-                   else
-                     pData->iFilterofs = 8;
-
-                   break;
-                 }
-      }
-    }
-#endif
-
-#ifdef FILTER193                       /* no adaptive filtering ? */
-    if (pData->iFilter == MNG_FILTER_NOFILTER)
-      pData->iPixelofs = pData->iFilterofs;
-    else
-#endif
-      pData->iPixelofs = pData->iFilterofs + 1;
-
-    if (pData->fInitrowproc)           /* need to initialize row processing? */
-    {
-      iRetcode = ((mng_initrowproc)pData->fInitrowproc) (pData);
-      if (iRetcode)
-      {
-         MNG_FREEX (pData, pBuf, iBufsize);
-         return iRetcode;
-      }
-    }
-                                       /* calculate remainder of buffer */
-    pTemp    = pBuf + (mng_int32)(pANG->iNumframes * iSize);
-    iTemplen = iRealsize - (mng_int32)(pANG->iNumframes * iSize);
-
-    do
-    {
-      if (iTemplen > pData->iRowmax)   /* get a pixel-row from the temp buffer */
-      {
-        MNG_COPY (pData->pWorkrow, pTemp, pData->iRowmax);
-      }
-      else
-      {
-        MNG_COPY (pData->pWorkrow, pTemp, iTemplen);
-      }
-
-      {                                /* image not completed yet ? */
-        if (pData->iRow < (mng_int32)pData->iDataheight)
-        {
-#ifdef MNG_NO_1_2_4BIT_SUPPORT
-          if (pData->iPNGdepth == 1)
-          {
-            /* Inflate Workrow to 8-bit */
-            mng_int32  iX;
-            mng_uint8p pSrc = pData->pWorkrow+1;
-            mng_uint8p pDest = pSrc + pData->iRowsize - (pData->iRowsize+7)/8;
-
-            for (iX = ((pData->iRowsize+7)/8) ; iX > 0 ; iX--)
-              *pDest++ = *pSrc++;
-
-            pDest = pData->pWorkrow+1;
-            pSrc = pDest + pData->iRowsize - (pData->iRowsize+7)/8;
-            for (iX = pData->iRowsize; ;)
-            {
-              *pDest++ = (((*pSrc)>>7)&1);
-              if (iX-- <= 0)
-                break;
-              *pDest++ = (((*pSrc)>>6)&1);
-              if (iX-- <= 0)
-                break;
-              *pDest++ = (((*pSrc)>>5)&1);
-              if (iX-- <= 0)
-                break;
-              *pDest++ = (((*pSrc)>>4)&1);
-              if (iX-- <= 0)
-                break;
-              *pDest++ = (((*pSrc)>>3)&1);
-              if (iX-- <= 0)
-                break;
-              *pDest++ = (((*pSrc)>>2)&1);
-              if (iX-- <= 0)
-                break;
-              *pDest++ = (((*pSrc)>>1)&1);
-              if (iX-- <= 0)
-                break;
-              *pDest++ = (((*pSrc)   )&1);
-              if (iX-- <= 0)
-                break;
-              pSrc++;
-            }
-          }
-          else if (pData->iPNGdepth == 2)
-          {
-            /* Inflate Workrow to 8-bit */
-            mng_int32  iX;
-            mng_uint8p pSrc = pData->pWorkrow+1;
-            mng_uint8p pDest = pSrc + pData->iRowsize - (2*pData->iRowsize+7)/8;
-
-            for (iX = ((2*pData->iRowsize+7)/8) ; iX > 0 ; iX--)
-               *pDest++ = *pSrc++;
-
-            pDest = pData->pWorkrow+1;
-            pSrc = pDest + pData->iRowsize - (2*pData->iRowsize+7)/8;
-            for (iX = pData->iRowsize; ;)
-            {
-              *pDest++ = (((*pSrc)>>6)&3);
-              if (iX-- <= 0)
-                break;
-              *pDest++ = (((*pSrc)>>4)&3);
-              if (iX-- <= 0)
-                break;
-              *pDest++ = (((*pSrc)>>2)&3);
-              if (iX-- <= 0)
-                break;
-              *pDest++ = (((*pSrc)   )&3);
-              if (iX-- <= 0)
-                break;
-              pSrc++;
-            }
-          }
-          else if (pData->iPNGdepth == 4)
-          {
-            /* Inflate Workrow to 8-bit */
-            mng_int32  iX;
-            mng_uint8p pSrc = pData->pWorkrow+1;
-            mng_uint8p pDest = pSrc + pData->iRowsize - (4*pData->iRowsize+7)/8;
-
-            for (iX = ((4*pData->iRowsize+7)/8) ; iX > 0 ; iX--)
-               *pDest++ = *pSrc++;
-
-            pDest = pData->pWorkrow+1;
-            pSrc = pDest + pData->iRowsize - (4*pData->iRowsize+7)/8;
-            for (iX = pData->iRowsize; ;)
-            {
-              *pDest++ = (((*pSrc)>>4)&0x0f);
-              if (iX-- <= 0)
-                break;
-              *pDest++ = (((*pSrc)   )&0x0f);
-              if (iX-- <= 0)
-                break;
-              pSrc++;
-            }
-          }
-          if (pData->iPNGdepth < 8 && pData->iColortype == 0)
-          {
-            /* Expand samples to 8-bit by LBR */
-            mng_int32  iX;
-            mng_uint8p pSrc = pData->pWorkrow+1;
-            mng_uint8 multiplier[]={0,255,85,0,17,0,0,0,1};
-
-            for (iX = pData->iRowsize; iX > 0; iX--)
-                *pSrc++ *= multiplier[pData->iPNGdepth];
-          }
-#endif
-#ifdef MNG_NO_16BIT_SUPPORT
-          if (pData->iPNGdepth > 8)
-          {
-            /* Reduce Workrow to 8-bit */
-            mng_int32  iX;
-            mng_uint8p pSrc = pData->pWorkrow+1;
-            mng_uint8p pDest = pSrc;
-
-            for (iX = pData->iRowsize; iX > 0; iX--)
-            {
-              *pDest = *pSrc;
-              pDest++;
-              pSrc+=2;
-            }
-          }
-#endif
-
-#ifdef FILTER192                       /* has leveling info ? */
-          if (pData->iFilterofs == MNG_FILTER_DIFFERING)
-            iRetcode = init_rowdiffering (pData);
-          else
-#endif
-            iRetcode = MNG_NOERROR;
-                                       /* filter the row if necessary */
-          if ((!iRetcode) && (pData->iFilterofs < pData->iPixelofs  ) &&
-                             (*(pData->pWorkrow + pData->iFilterofs))    )
-            iRetcode = mng_filter_a_row (pData);
-
-                                       /* additional leveling/differing ? */
-          if ((!iRetcode) && (pData->fDifferrow))
-          {
-            iRetcode = ((mng_differrow)pData->fDifferrow) (pData);
-
-            pSwap           = pData->pWorkrow;
-            pData->pWorkrow = pData->pPrevrow;
-            pData->pPrevrow = pSwap;   /* make sure we're processing the right data */
-          }
-
-          if (!iRetcode)
-          {
-            {                          /* process this row */
-              if ((!iRetcode) && (pData->fProcessrow))
-                iRetcode = ((mng_processrow)pData->fProcessrow) (pData);
-                                       /* store in object ? */
-              if ((!iRetcode) && (pData->fStorerow))
-                iRetcode = ((mng_storerow)pData->fStorerow)     (pData);
-            }
-          }
-
-          if (iRetcode)                   /* on error bail out */
-          {
-            MNG_FREEX (pData, pBuf, iBufsize);
-            MNG_ERROR (pData, iRetcode);
-          }
-
-          if (!pData->fDifferrow)      /* swap row-pointers */
-          {
-            pSwap           = pData->pWorkrow;
-            pData->pWorkrow = pData->pPrevrow;
-            pData->pPrevrow = pSwap;   /* so prev points to the processed row! */
-          }
-                                       /* adjust variables for next row */
-          iRetcode = mng_next_row (pData);
-
-          if (iRetcode)                   /* on error bail out */
-          {
-            MNG_FREEX (pData, pBuf, iBufsize);
-            MNG_ERROR (pData, iRetcode);
-          }
-        }
-      }
-
-      pTemp    += pData->iRowmax;
-      iTemplen -= pData->iRowmax;
-    }                                  /* until some error or EOI
-                                          or all pixels received */
-    while ( (iTemplen > 0)  &&
-            ( (pData->iRow < (mng_int32)pData->iDataheight) ||
-              ( (pData->iPass >= 0) && (pData->iPass < 7) )    )    );
-
-    mng_cleanup_rowproc (pData);       /* cleanup row processing buffers !! */
-
-                                       /* restore saved work-parms */
-    pData->iDatawidth   = iSavedatawidth;
-    pData->iDataheight  = iSavedataheight;
-
-    pData->fInitrowproc = fSaveinitrowproc;
-    pData->fDisplayrow  = fSavestorerow;
-    pData->fProcessrow  = fSaveprocessrow;
-    pData->fDifferrow   = fSavedifferrow;
-    pData->pStoreobj    = fSavestoreobj;
-    pData->pStorebuf    = fSavestorebuf;
-
-#ifdef MNG_OPTIMIZE_FOOTPRINT_INIT
-    pData->ePng_imgtype = eSavepngimgtype;
-#endif
-
-    pData->iInterlace   = iSaveinterlace;
-    pData->iPass        = iSavepass;
-    pData->iRow         = iSaverow;
-    pData->iRowinc      = iSaverowinc;
-    pData->iCol         = iSavecol;
-    pData->iColinc      = iSavecolinc;
-    pData->iRowsamples  = iSaverowsamples;
-    pData->iSamplemul   = iSavesamplemul;
-    pData->iSampleofs   = iSavesampleofs;
-    pData->iSamplediv   = iSavesamplediv;
-    pData->iRowsize     = iSaverowsize;
-    pData->iRowmax      = iSaverowmax;
-    pData->iFilterofs   = iSavefilterofs;
-    pData->iPixelofs    = iSavepixelofs;
-    pData->iLevel0      = iSavelevel0;
-    pData->iLevel1      = iSavelevel1;
-    pData->iLevel2      = iSavelevel2;
-    pData->iLevel3      = iSavelevel3;
-    pData->pWorkrow     = pSaveworkrow;
-    pData->pPrevrow     = pSaveprevrow;
-    pData->pRGBArow     = pSaverGBArow;
-    pData->bIsRGBA16    = bSaveisRGBA16;
-    pData->bIsOpaque    = bSaveisOpaque;
-    pData->iFilterbpp   = iSavefilterbpp;
-    pData->iDestl       = iSavedestl;
-    pData->iDestt       = iSavedestt;
-    pData->iDestr       = iSavedestr;
-    pData->iDestb       = iSavedestb;
-    pData->iSourcel     = iSavesourcel;
-    pData->iSourcet     = iSavesourcet;
-    pData->iSourcer     = iSavesourcer;
-    pData->iSourceb     = iSavesourceb;
-
-                                       /* create the animation directives ! */
-    pProcess = (mng_processobject)pANG->sHeader.fProcess;
-    iRetcode = pProcess (pData, (mng_objectp)pData->pANG);
-    if (iRetcode)
-      return iRetcode;
-
-#endif /* MNG_SUPPORT_DISPLAY */
-
-    MNG_FREE (pData, pBuf, iBufsize);  /* always free the temp buffer ! */
-  }
-
-  *piRawlen = 0;
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_ANG_PROPOSAL
-MNG_C_SPECIALFUNC (mng_special_adat)
-{
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-MNG_C_SPECIALFUNC (mng_special_unknown)
-{
-                                       /* critical chunk ? */
-  if ((((mng_uint32)pData->iChunkname & 0x20000000) == 0)
-#ifdef MNG_SKIPCHUNK_SAVE
-    && (pData->iChunkname != MNG_UINT_SAVE)
-#endif
-#ifdef MNG_SKIPCHUNK_SEEK
-    && (pData->iChunkname != MNG_UINT_SEEK)
-#endif
-#ifdef MNG_SKIPCHUNK_DBYK
-    && (pData->iChunkname != MNG_UINT_DBYK)
-#endif
-#ifdef MNG_SKIPCHUNK_ORDR
-    && (pData->iChunkname != MNG_UINT_ORDR)
-#endif
-      )
-    MNG_ERROR (pData, MNG_UNKNOWNCRITICAL);
-
-  if (pData->fProcessunknown)          /* let the app handle it ? */
-  {
-    mng_bool bOke = pData->fProcessunknown ((mng_handle)pData, pData->iChunkname,
-                                            ((mng_unknown_chunkp)pChunk)->iDatasize,
-                                            ((mng_unknown_chunkp)pChunk)->pData);
-    if (!bOke)
-      MNG_ERROR (pData, MNG_APPMISCERROR);
-  }
-
-  return MNG_NOERROR;                  /* done */
-}
-
-/* ************************************************************************** */
-
-#endif /* MNG_INCLUDE_READ_PROCS || MNG_INCLUDE_WRITE_PROCS */
-#endif /* MNG_OPTIMIZE_CHUNKREADER */
-
-/* ************************************************************************** */
-/* * end of file                                                            * */
-/* ************************************************************************** */
-
-
-
-
-
diff --git a/Source/LibMNG/libmng_chunk_descr.h b/Source/LibMNG/libmng_chunk_descr.h
deleted file mode 100644
index 3781ab0..0000000
--- a/Source/LibMNG/libmng_chunk_descr.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/* ************************************************************************** */
-/* *             For conditions of distribution and use,                    * */
-/* *                see copyright notice in libmng.h                        * */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * project   : libmng                                                     * */
-/* * file      : libmng_chunk_descr.h      copyright (c) 2007 G.Juyn        * */
-/* * version   : 1.0.10                                                     * */
-/* *                                                                        * */
-/* * purpose   : Chunk descriptor functions (implementation)                * */
-/* *                                                                        * */
-/* * author    : G.Juyn                                                     * */
-/* *                                                                        * */
-/* * comment   : definition of the chunk- anf field-descriptor routines     * */
-/* *                                                                        * */
-/* * changes   : 1.0.9 - 12/06/2004 - G.Juyn                                * */
-/* *             - added conditional MNG_OPTIMIZE_CHUNKREADER               * */
-/* *                                                                        * */
-/* *             1.0.10 - 04/08/2007 - G.Juyn                               * */
-/* *             - added support for mPNG proposal                          * */
-/* *             1.0.10 - 04/12/2007 - G.Juyn                               * */
-/* *             - added support for ANG proposal                           * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
-#pragma option -A                      /* force ANSI-C */
-#endif
-
-#ifndef _libmng_chunk_descr_h_
-#define _libmng_chunk_descr_h_
-
-/* ************************************************************************** */
-
-#ifdef MNG_OPTIMIZE_CHUNKREADER
-#if defined(MNG_INCLUDE_READ_PROCS) || defined(MNG_INCLUDE_WRITE_PROCS)
-
-/* ************************************************************************** */
-
-void mng_get_chunkheader (mng_chunkid       iChunkname,
-                          mng_chunk_headerp pResult);
-
-/* ************************************************************************** */
-
-#define MNG_F_SPECIALFUNC(n) mng_retcode n (mng_datap   pData,    \
-                                            mng_chunkp  pChunk,   \
-                                            mng_uint32* piRawlen, \
-                                            mng_uint8p* ppRawdata)
-
-MNG_F_SPECIALFUNC (mng_debunk_plte) ;
-MNG_F_SPECIALFUNC (mng_debunk_trns) ;
-MNG_F_SPECIALFUNC (mng_deflate_itxt) ;
-MNG_F_SPECIALFUNC (mng_splt_entries) ;
-MNG_F_SPECIALFUNC (mng_hist_entries) ;
-
-MNG_F_SPECIALFUNC (mng_debunk_loop) ;
-MNG_F_SPECIALFUNC (mng_debunk_past) ;
-MNG_F_SPECIALFUNC (mng_disc_entries) ;
-MNG_F_SPECIALFUNC (mng_fram_remainder) ;
-MNG_F_SPECIALFUNC (mng_save_entries) ;
-MNG_F_SPECIALFUNC (mng_pplt_entries) ;
-MNG_F_SPECIALFUNC (mng_drop_entries) ;
-MNG_F_SPECIALFUNC (mng_ordr_entries) ;
-MNG_F_SPECIALFUNC (mng_debunk_magn) ;
-MNG_F_SPECIALFUNC (mng_evnt_entries) ;
-MNG_F_SPECIALFUNC (mng_adat_tiles) ;
-
-/* ************************************************************************** */
-
-#define MNG_C_SPECIALFUNC(n) mng_retcode n (mng_datap  pData,   \
-                                            mng_chunkp pChunk)
-
-MNG_C_SPECIALFUNC (mng_special_ihdr) ;
-MNG_C_SPECIALFUNC (mng_special_plte) ;
-MNG_C_SPECIALFUNC (mng_special_idat) ;
-MNG_C_SPECIALFUNC (mng_special_iend) ;
-MNG_C_SPECIALFUNC (mng_special_trns) ;
-MNG_C_SPECIALFUNC (mng_special_gama) ;
-MNG_C_SPECIALFUNC (mng_special_chrm) ;
-MNG_C_SPECIALFUNC (mng_special_srgb) ;
-MNG_C_SPECIALFUNC (mng_special_iccp) ;
-MNG_C_SPECIALFUNC (mng_special_text) ;
-MNG_C_SPECIALFUNC (mng_special_ztxt) ;
-MNG_C_SPECIALFUNC (mng_special_itxt) ;
-MNG_C_SPECIALFUNC (mng_special_bkgd) ;
-MNG_C_SPECIALFUNC (mng_special_phys) ;
-MNG_C_SPECIALFUNC (mng_special_sbit) ;
-MNG_C_SPECIALFUNC (mng_special_splt) ;
-MNG_C_SPECIALFUNC (mng_special_hist) ;
-MNG_C_SPECIALFUNC (mng_special_time) ;
-
-MNG_C_SPECIALFUNC (mng_special_jhdr) ;
-MNG_C_SPECIALFUNC (mng_special_jdaa) ;
-MNG_C_SPECIALFUNC (mng_special_jdat) ;
-MNG_C_SPECIALFUNC (mng_special_jsep) ;
-
-MNG_C_SPECIALFUNC (mng_special_mhdr) ;
-MNG_C_SPECIALFUNC (mng_special_mend) ;
-MNG_C_SPECIALFUNC (mng_special_loop) ;
-MNG_C_SPECIALFUNC (mng_special_endl) ;
-MNG_C_SPECIALFUNC (mng_special_defi) ;
-MNG_C_SPECIALFUNC (mng_special_basi) ;
-MNG_C_SPECIALFUNC (mng_special_clon) ;
-MNG_C_SPECIALFUNC (mng_special_past) ;
-MNG_C_SPECIALFUNC (mng_special_disc) ;
-MNG_C_SPECIALFUNC (mng_special_back) ;
-MNG_C_SPECIALFUNC (mng_special_fram) ;
-MNG_C_SPECIALFUNC (mng_special_move) ;
-MNG_C_SPECIALFUNC (mng_special_clip) ;
-MNG_C_SPECIALFUNC (mng_special_show) ;
-MNG_C_SPECIALFUNC (mng_special_term) ;
-MNG_C_SPECIALFUNC (mng_special_save) ;
-MNG_C_SPECIALFUNC (mng_special_seek) ;
-MNG_C_SPECIALFUNC (mng_special_expi) ;
-MNG_C_SPECIALFUNC (mng_special_fpri) ;
-MNG_C_SPECIALFUNC (mng_special_need) ;
-MNG_C_SPECIALFUNC (mng_special_phyg) ;
-
-MNG_C_SPECIALFUNC (mng_special_dhdr) ;
-MNG_C_SPECIALFUNC (mng_special_prom) ;
-MNG_C_SPECIALFUNC (mng_special_ipng) ;
-MNG_C_SPECIALFUNC (mng_special_pplt) ;
-MNG_C_SPECIALFUNC (mng_special_ijng) ;
-MNG_C_SPECIALFUNC (mng_special_drop) ;
-MNG_C_SPECIALFUNC (mng_special_dbyk) ;
-MNG_C_SPECIALFUNC (mng_special_ordr) ;
-
-MNG_C_SPECIALFUNC (mng_special_magn) ;
-MNG_C_SPECIALFUNC (mng_special_evnt) ;
-MNG_C_SPECIALFUNC (mng_special_mpng) ;
-MNG_C_SPECIALFUNC (mng_special_ahdr) ;
-MNG_C_SPECIALFUNC (mng_special_adat) ;
-MNG_C_SPECIALFUNC (mng_special_unknown) ;
-
-/* ************************************************************************** */
-
-#endif /* MNG_INCLUDE_READ_PROCS) || MNG_INCLUDE_WRITE_PROCS */
-#endif /* MNG_OPTIMIZE_CHUNKREADER */
-
-/* ************************************************************************** */
-
-#endif /* _libmng_chunk_descr_h_ */
-
-/* ************************************************************************** */
-/* * end of file                                                            * */
-/* ************************************************************************** */
diff --git a/Source/LibMNG/libmng_chunk_io.c b/Source/LibMNG/libmng_chunk_io.c
deleted file mode 100644
index a75945f..0000000
--- a/Source/LibMNG/libmng_chunk_io.c
+++ /dev/null
@@ -1,10740 +0,0 @@
-/** ************************************************************************* */
-/* *             For conditions of distribution and use,                    * */
-/* *                see copyright notice in libmng.h                        * */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * project   : libmng                                                     * */
-/* * file      : libmng_chunk_io.c         copyright (c) 2000-2007 G.Juyn   * */
-/* * version   : 1.0.10                                                     * */
-/* *                                                                        * */
-/* * purpose   : Chunk I/O routines (implementation)                        * */
-/* *                                                                        * */
-/* * author    : G.Juyn                                                     * */
-/* *                                                                        * */
-/* * comment   : implementation of chunk input/output routines              * */
-/* *                                                                        * */
-/* * changes   : 0.5.1 - 05/01/2000 - G.Juyn                                * */
-/* *             - cleaned up left-over teststuff in the BACK chunk routine * */
-/* *             0.5.1 - 05/04/2000 - G.Juyn                                * */
-/* *             - changed CRC initialization to use dynamic structure      * */
-/* *               (wasn't thread-safe the old way !)                       * */
-/* *             0.5.1 - 05/06/2000 - G.Juyn                                * */
-/* *             - filled in many missing sequence&length checks            * */
-/* *             - filled in many missing chunk-store snippets              * */
-/* *             0.5.1 - 05/08/2000 - G.Juyn                                * */
-/* *             - added checks for running animations                      * */
-/* *             - filled some write routines                               * */
-/* *             - changed strict-ANSI stuff                                * */
-/* *             0.5.1 - 05/10/2000 - G.Juyn                                * */
-/* *             - filled some more write routines                          * */
-/* *             0.5.1 - 05/11/2000 - G.Juyn                                * */
-/* *             - filled remaining write routines                          * */
-/* *             - fixed read_pplt with regard to deltatype                 * */
-/* *             - added callback error-reporting support                   * */
-/* *             - added pre-draft48 support (short MHDR, frame_mode, LOOP) * */
-/* *             0.5.1 - 05/12/2000 - G.Juyn                                * */
-/* *             - changed trace to macro for callback error-reporting      * */
-/* *             - fixed chunk-storage bit in several routines              * */
-/* *             0.5.1 - 05/13/2000 - G.Juyn                                * */
-/* *             - added eMNGma hack (will be removed in 1.0.0 !!!)         * */
-/* *             - added TERM animation object pointer (easier reference)   * */
-/* *             - supplemented the SAVE & SEEK display processing          * */
-/* *                                                                        * */
-/* *             0.5.2 - 05/18/2000 - G.Juyn                                * */
-/* *             - B004 - fixed problem with MNG_SUPPORT_WRITE not defined  * */
-/* *               also for MNG_SUPPORT_WRITE without MNG_INCLUDE_JNG       * */
-/* *             0.5.2 - 05/19/2000 - G.Juyn                                * */
-/* *             - cleaned up some code regarding mixed support             * */
-/* *             0.5.2 - 05/20/2000 - G.Juyn                                * */
-/* *             - implemented JNG support                                  * */
-/* *             0.5.2 - 05/24/2000 - G.Juyn                                * */
-/* *             - added support for global color-chunks in animation       * */
-/* *             - added support for global PLTE,tRNS,bKGD in animation     * */
-/* *             - added support for SAVE & SEEK in animation               * */
-/* *             0.5.2 - 05/29/2000 - G.Juyn                                * */
-/* *             - changed ani_create calls not returning object pointer    * */
-/* *             - create ani objects always (not just inside TERM/LOOP)    * */
-/* *             0.5.2 - 05/30/2000 - G.Juyn                                * */
-/* *             - added support for delta-image processing                 * */
-/* *             0.5.2 - 05/31/2000 - G.Juyn                                * */
-/* *             - fixed up punctuation (contributed by Tim Rowley)         * */
-/* *             0.5.2 - 06/02/2000 - G.Juyn                                * */
-/* *             - changed SWAP_ENDIAN to BIGENDIAN_SUPPORTED               * */
-/* *             0.5.2 - 06/03/2000 - G.Juyn                                * */
-/* *             - fixed makeup for Linux gcc compile                       * */
-/* *                                                                        * */
-/* *             0.5.3 - 06/12/2000 - G.Juyn                                * */
-/* *             - added processing of color-info on delta-image            * */
-/* *             0.5.3 - 06/13/2000 - G.Juyn                                * */
-/* *             - fixed handling of empty SAVE chunk                       * */
-/* *             0.5.3 - 06/17/2000 - G.Juyn                                * */
-/* *             - changed to support delta-images                          * */
-/* *             - added extra checks for delta-images                      * */
-/* *             0.5.3 - 06/20/2000 - G.Juyn                                * */
-/* *             - fixed possible trouble if IEND display-process got       * */
-/* *               broken up                                                * */
-/* *             0.5.3 - 06/21/2000 - G.Juyn                                * */
-/* *             - added processing of PLTE & tRNS for delta-images         * */
-/* *             - added administration of imagelevel parameter             * */
-/* *             0.5.3 - 06/22/2000 - G.Juyn                                * */
-/* *             - implemented support for PPLT chunk                       * */
-/* *             0.5.3 - 06/26/2000 - G.Juyn                                * */
-/* *             - added precaution against faulty iCCP chunks from PS      * */
-/* *             0.5.3 - 06/29/2000 - G.Juyn                                * */
-/* *             - fixed some 64-bit warnings                               * */
-/* *                                                                        * */
-/* *             0.9.1 - 07/14/2000 - G.Juyn                                * */
-/* *             - changed pre-draft48 frame_mode=3 to frame_mode=1         * */
-/* *             0.9.1 - 07/16/2000 - G.Juyn                                * */
-/* *             - fixed storage of images during mng_read()                * */
-/* *             - fixed support for mng_display() after mng_read()         * */
-/* *             0.9.1 - 07/19/2000 - G.Juyn                                * */
-/* *             - fixed several chunk-writing routines                     * */
-/* *             0.9.1 - 07/24/2000 - G.Juyn                                * */
-/* *             - fixed reading of still-images                            * */
-/* *                                                                        * */
-/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
-/* *             - changed file-prefixes                                    * */
-/* *                                                                        * */
-/* *             0.9.3 - 08/07/2000 - G.Juyn                                * */
-/* *             - B111300 - fixup for improved portability                 * */
-/* *             0.9.3 - 08/08/2000 - G.Juyn                                * */
-/* *             - fixed compiler-warnings from Mozilla                     * */
-/* *             0.9.3 - 08/09/2000 - G.Juyn                                * */
-/* *             - added check for simplicity-bits in MHDR                  * */
-/* *             0.9.3 - 08/12/2000 - G.Juyn                                * */
-/* *             - fixed check for simplicity-bits in MHDR (JNG)            * */
-/* *             0.9.3 - 08/12/2000 - G.Juyn                                * */
-/* *             - added workaround for faulty PhotoShop iCCP chunk         * */
-/* *             0.9.3 - 08/22/2000 - G.Juyn                                * */
-/* *             - fixed write-code for zTXt & iTXt                         * */
-/* *             - fixed read-code for iTXt                                 * */
-/* *             0.9.3 - 08/26/2000 - G.Juyn                                * */
-/* *             - added MAGN chunk                                         * */
-/* *             0.9.3 - 09/07/2000 - G.Juyn                                * */
-/* *             - added support for new filter_types                       * */
-/* *             0.9.3 - 09/10/2000 - G.Juyn                                * */
-/* *             - fixed DEFI behavior                                      * */
-/* *             0.9.3 - 10/02/2000 - G.Juyn                                * */
-/* *             - fixed simplicity-check in compliance with draft 81/0.98a * */
-/* *             0.9.3 - 10/10/2000 - G.Juyn                                * */
-/* *             - added support for alpha-depth prediction                 * */
-/* *             0.9.3 - 10/11/2000 - G.Juyn                                * */
-/* *             - added support for nEED                                   * */
-/* *             0.9.3 - 10/16/2000 - G.Juyn                                * */
-/* *             - added support for JDAA                                   * */
-/* *             0.9.3 - 10/17/2000 - G.Juyn                                * */
-/* *             - fixed support for MAGN                                   * */
-/* *             - implemented nEED "xxxx" (where "xxxx" is a chunkid)      * */
-/* *             - added callback to process non-critical unknown chunks    * */
-/* *             - fixed support for bKGD                                   * */
-/* *             0.9.3 - 10/23/2000 - G.Juyn                                * */
-/* *             - fixed bug in empty PLTE handling                         * */
-/* *                                                                        * */
-/* *             0.9.4 - 11/20/2000 - G.Juyn                                * */
-/* *             - changed IHDR filter_method check for PNGs                * */
-/* *             0.9.4 -  1/18/2001 - G.Juyn                                * */
-/* *             - added errorchecking for MAGN methods                     * */
-/* *             - removed test filter-methods 1 & 65                       * */
-/* *                                                                        * */
-/* *             0.9.5 -  1/25/2001 - G.Juyn                                * */
-/* *             - fixed some small compiler warnings (thanks Nikki)        * */
-/* *                                                                        * */
-/* *             1.0.2 - 05/05/2000 - G.Juyn                                * */
-/* *             - B421427 - writes wrong format in bKGD and tRNS           * */
-/* *             1.0.2 - 06/20/2000 - G.Juyn                                * */
-/* *             - B434583 - compiler-warning if MNG_STORE_CHUNKS undefined * */
-/* *                                                                        * */
-/* *             1.0.5 - 07/08/2002 - G.Juyn                                * */
-/* *             - B578572 - removed eMNGma hack (thanks Dimitri!)          * */
-/* *             1.0.5 - 08/07/2002 - G.Juyn                                * */
-/* *             - added test-option for PNG filter method 193 (=no filter) * */
-/* *             1.0.5 - 08/15/2002 - G.Juyn                                * */
-/* *             - completed PROM support                                   * */
-/* *             1.0.5 - 08/19/2002 - G.Juyn                                * */
-/* *             - B597134 - libmng pollutes the linker namespace           * */
-/* *             1.0.5 - 09/07/2002 - G.Juyn                                * */
-/* *             - fixed reading of FRAM with just frame_mode and name      * */
-/* *             1.0.5 - 09/13/2002 - G.Juyn                                * */
-/* *             - fixed read/write of MAGN chunk                           * */
-/* *             1.0.5 - 09/14/2002 - G.Juyn                                * */
-/* *             - added event handling for dynamic MNG                     * */
-/* *             1.0.5 - 09/15/2002 - G.Juyn                                * */
-/* *             - fixed LOOP iteration=0 special case                      * */
-/* *             1.0.5 - 09/19/2002 - G.Juyn                                * */
-/* *             - misplaced TERM is now treated as warning                 * */
-/* *             1.0.5 - 09/20/2002 - G.Juyn                                * */
-/* *             - added support for PAST                                   * */
-/* *             1.0.5 - 10/03/2002 - G.Juyn                                * */
-/* *             - fixed chunk-storage for evNT chunk                       * */
-/* *             1.0.5 - 10/07/2002 - G.Juyn                                * */
-/* *             - fixed DISC support                                       * */
-/* *             - added another fix for misplaced TERM chunk               * */
-/* *             1.0.5 - 10/17/2002 - G.Juyn                                * */
-/* *             - fixed initializtion of pIds in dISC read routine         * */
-/* *             1.0.5 - 11/06/2002 - G.Juyn                                * */
-/* *             - added support for nEED "MNG 1.1"                         * */
-/* *             - added support for nEED "CACHEOFF"                        * */
-/* *                                                                        * */
-/* *             1.0.6 - 05/25/2003 - G.R-P                                 * */
-/* *             - added MNG_SKIPCHUNK_cHNK footprint optimizations         * */
-/* *             1.0.6 - 06/02/2003 - G.R-P                                 * */
-/* *             - removed some redundant checks for iRawlen==0             * */
-/* *             1.0.6 - 06/22/2003 - G.R-P                                 * */
-/* *             - added MNG_NO_16BIT_SUPPORT, MNG_NO_DELTA_PNG reductions  * */
-/* *             - optionally use zlib's crc32 function instead of          * */
-/* *               local mng_update_crc                                     * */
-/* *             1.0.6 - 07/14/2003 - G.R-P                                 * */
-/* *             - added MNG_NO_LOOP_SIGNALS_SUPPORTED conditional          * */
-/* *             1.0.6 - 07/29/2003 - G.R-P                                 * */
-/* *             - added conditionals around PAST chunk support             * */
-/* *             1.0.6 - 08/17/2003 - G.R-P                                 * */
-/* *             - added conditionals around non-VLC chunk support          * */
-/* *                                                                        * */
-/* *             1.0.7 - 10/29/2003 - G.R-P                                 * */
-/* *             - revised JDAA and JDAT readers to avoid compiler bug      * */
-/* *             1.0.7 - 01/25/2004 - J.S                                   * */
-/* *             - added premultiplied alpha canvas' for RGBA, ARGB, ABGR   * */
-/* *             1.0.7 - 01/27/2004 - J.S                                   * */
-/* *             - fixed inclusion of IJNG chunk for non-JNG use            * */
-/* *             1.0.7 - 02/26/2004 - G.Juyn                                * */
-/* *             - fixed bug in chunk-storage of SHOW chunk (from == to)    * */
-/* *                                                                        * */
-/* *             1.0.8 - 04/02/2004 - G.Juyn                                * */
-/* *             - added CRC existence & checking flags                     * */
-/* *             1.0.8 - 07/07/2004 - G.R-P                                 * */
-/* *             - change worst-case iAlphadepth to 1 for standalone PNGs   * */
-/* *                                                                        * */
-/* *             1.0.9 - 09/28/2004 - G.R-P                                 * */
-/* *             - improved handling of cheap transparency when 16-bit      * */
-/* *               support is disabled                                      * */
-/* *             1.0.9 - 10/04/2004 - G.Juyn                                * */
-/* *             - fixed bug in writing sBIT for indexed color              * */
-/* *             1.0.9 - 10/10/2004 - G.R-P.                                * */
-/* *             - added MNG_NO_1_2_4BIT_SUPPORT                            * */
-/* *             1.0.9 - 12/05/2004 - G.Juyn                                * */
-/* *             - added conditional MNG_OPTIMIZE_CHUNKINITFREE             * */
-/* *             1.0.9 - 12/06/2004 - G.Juyn                                * */
-/* *             - added conditional MNG_OPTIMIZE_CHUNKASSIGN               * */
-/* *             1.0.9 - 12/07/2004 - G.Juyn                                * */
-/* *             - added conditional MNG_OPTIMIZE_CHUNKREADER               * */
-/* *             1.0.9 - 12/11/2004 - G.Juyn                                * */
-/* *             - added conditional MNG_OPTIMIZE_DISPLAYCALLS              * */
-/* *             1.0.9 - 12/20/2004 - G.Juyn                                * */
-/* *             - cleaned up macro-invocations (thanks to D. Airlie)       * */
-/* *             1.0.9 - 01/17/2005 - G.Juyn                                * */
-/* *             - fixed problem with global PLTE/tRNS                      * */
-/* *                                                                        * */
-/* *             1.0.10 - 02/07/2005 - G.Juyn                               * */
-/* *             - fixed display routines called twice for FULL_MNG         * */
-/* *               support in mozlibmngconf.h                               * */
-/* *             1.0.10 - 12/04/2005 - G.R-P.                               * */
-/* *             - #ifdef out use of mng_inflate_buffer when it is not      * */
-/* *               available.                                               * */
-/* *             1.0.10 - 04/08/2007 - G.Juyn                               * */
-/* *             - added support for mPNG proposal                          * */
-/* *             1.0.10 - 04/12/2007 - G.Juyn                               * */
-/* *             - added support for ANG proposal                           * */
-/* *             1.0.10 - 05/02/2007 - G.Juyn                               * */
-/* *             - fixed inflate_buffer for extreme compression ratios      * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#include "libmng.h"
-#include "libmng_data.h"
-#include "libmng_error.h"
-#include "libmng_trace.h"
-#ifdef __BORLANDC__
-#pragma hdrstop
-#endif
-#include "libmng_objects.h"
-#include "libmng_object_prc.h"
-#include "libmng_chunks.h"
-#ifdef MNG_CHECK_BAD_ICCP
-#include "libmng_chunk_prc.h"
-#endif
-#include "libmng_memory.h"
-#include "libmng_display.h"
-#include "libmng_zlib.h"
-#include "libmng_pixels.h"
-#include "libmng_chunk_io.h"
-
-#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
-#pragma option -A                      /* force ANSI-C */
-#endif
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * CRC - Cyclic Redundancy Check                                          * */
-/* *                                                                        * */
-/* * The code below is taken directly from the sample provided with the     * */
-/* * PNG specification.                                                     * */
-/* * (it is only adapted to the library's internal data-definitions)        * */
-/* *                                                                        * */
-/* ************************************************************************** */
-/* Make the table for a fast CRC. */
-#ifndef MNG_USE_ZLIB_CRC
-MNG_LOCAL void make_crc_table (mng_datap pData)
-{
-  mng_uint32 iC;
-  mng_int32  iN, iK;
-
-  for (iN = 0; iN < 256; iN++)
-  {
-    iC = (mng_uint32) iN;
-
-    for (iK = 0; iK < 8; iK++)
-    {
-      if (iC & 1)
-        iC = 0xedb88320U ^ (iC >> 1);
-      else
-        iC = iC >> 1;
-    }
-
-    pData->aCRCtable [iN] = iC;
-  }
-
-  pData->bCRCcomputed = MNG_TRUE;
-}
-#endif
-
-/* Update a running CRC with the bytes buf[0..len-1]--the CRC
-   should be initialized to all 1's, and the transmitted value
-   is the 1's complement of the final running CRC (see the
-   crc() routine below). */
-
-MNG_LOCAL mng_uint32 update_crc (mng_datap  pData,
-                                 mng_uint32 iCrc,
-                                 mng_uint8p pBuf,
-                                 mng_int32  iLen)
-{
-#ifdef MNG_USE_ZLIB_CRC
-  return crc32 (iCrc, pBuf, iLen);
-#else
-  mng_uint32 iC = iCrc;
-  mng_int32 iN;
-
-  if (!pData->bCRCcomputed)
-    make_crc_table (pData);
-
-  for (iN = 0; iN < iLen; iN++)
-    iC = pData->aCRCtable [(iC ^ pBuf [iN]) & 0xff] ^ (iC >> 8);
-
-  return iC;
-#endif
-}
-
-/* Return the CRC of the bytes buf[0..len-1]. */
-mng_uint32 mng_crc (mng_datap  pData,
-                    mng_uint8p pBuf,
-                    mng_int32  iLen)
-{
-#ifdef MNG_USE_ZLIB_CRC
-  return update_crc (pData, 0, pBuf, iLen);
-#else
-  return update_crc (pData, 0xffffffffU, pBuf, iLen) ^ 0xffffffffU;
-#endif
-}
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Routines for swapping byte-order from and to graphic files             * */
-/* * (This code is adapted from the libpng package)                         * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifndef MNG_BIGENDIAN_SUPPORTED
-
-/* ************************************************************************** */
-
-mng_uint32 mng_get_uint32 (mng_uint8p pBuf)
-{
-   mng_uint32 i = ((mng_uint32)(*pBuf)       << 24) +
-                  ((mng_uint32)(*(pBuf + 1)) << 16) +
-                  ((mng_uint32)(*(pBuf + 2)) <<  8) +
-                   (mng_uint32)(*(pBuf + 3));
-   return (i);
-}
-
-/* ************************************************************************** */
-
-mng_int32 mng_get_int32 (mng_uint8p pBuf)
-{
-   mng_int32 i = ((mng_int32)(*pBuf)       << 24) +
-                 ((mng_int32)(*(pBuf + 1)) << 16) +
-                 ((mng_int32)(*(pBuf + 2)) <<  8) +
-                  (mng_int32)(*(pBuf + 3));
-   return (i);
-}
-
-/* ************************************************************************** */
-
-mng_uint16 mng_get_uint16 (mng_uint8p pBuf)
-{
-   mng_uint16 i = (mng_uint16)(((mng_uint16)(*pBuf) << 8) +
-                                (mng_uint16)(*(pBuf + 1)));
-   return (i);
-}
-
-/* ************************************************************************** */
-
-void mng_put_uint32 (mng_uint8p pBuf,
-                     mng_uint32 i)
-{
-   *pBuf     = (mng_uint8)((i >> 24) & 0xff);
-   *(pBuf+1) = (mng_uint8)((i >> 16) & 0xff);
-   *(pBuf+2) = (mng_uint8)((i >> 8) & 0xff);
-   *(pBuf+3) = (mng_uint8)(i & 0xff);
-}
-
-/* ************************************************************************** */
-
-void mng_put_int32 (mng_uint8p pBuf,
-                    mng_int32  i)
-{
-   *pBuf     = (mng_uint8)((i >> 24) & 0xff);
-   *(pBuf+1) = (mng_uint8)((i >> 16) & 0xff);
-   *(pBuf+2) = (mng_uint8)((i >> 8) & 0xff);
-   *(pBuf+3) = (mng_uint8)(i & 0xff);
-}
-
-/* ************************************************************************** */
-
-void mng_put_uint16 (mng_uint8p pBuf,
-                     mng_uint16 i)
-{
-   *pBuf     = (mng_uint8)((i >> 8) & 0xff);
-   *(pBuf+1) = (mng_uint8)(i & 0xff);
-}
-
-/* ************************************************************************** */
-
-#endif /* !MNG_BIGENDIAN_SUPPORTED */
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Helper routines to simplify chunk-data extraction                      * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_READ_PROCS
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-MNG_LOCAL mng_uint8p find_null (mng_uint8p pIn)
-{
-  mng_uint8p pOut = pIn;
-  while (*pOut)                        /* the read_graphic routine has made sure there's */
-    pOut++;                            /* always at least 1 zero-byte in the buffer */
-  return pOut;
-}
-#endif
-
-/* ************************************************************************** */
-
-#if !defined(MNG_SKIPCHUNK_iCCP) || !defined(MNG_SKIPCHUNK_zTXt) || \
-    !defined(MNG_SKIPCHUNK_iTXt) || defined(MNG_INCLUDE_MPNG_PROPOSAL) || \
-    defined(MNG_INCLUDE_ANG_PROPOSAL)
-mng_retcode mng_inflate_buffer (mng_datap  pData,
-                                mng_uint8p pInbuf,
-                                mng_uint32 iInsize,
-                                mng_uint8p *pOutbuf,
-                                mng_uint32 *iOutsize,
-                                mng_uint32 *iRealsize)
-{
-  mng_retcode iRetcode = MNG_NOERROR;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INFLATE_BUFFER, MNG_LC_START);
-#endif
-
-  if (iInsize)                         /* anything to do ? */
-  {
-    *iOutsize = iInsize * 3;           /* estimate uncompressed size */
-                                       /* and allocate a temporary buffer */
-    MNG_ALLOC (pData, *pOutbuf, *iOutsize);
-
-    do
-    {
-      mngzlib_inflateinit (pData);     /* initialize zlib */
-                                       /* let zlib know where to store the output */
-      pData->sZlib.next_out  = *pOutbuf;
-                                       /* "size - 1" so we've got space for the
-                                          zero-termination of a possible string */
-      pData->sZlib.avail_out = *iOutsize - 1;
-                                       /* ok; let's inflate... */
-      iRetcode = mngzlib_inflatedata (pData, iInsize, pInbuf);
-                                       /* determine actual output size */
-      *iRealsize = (mng_uint32)pData->sZlib.total_out;
-
-      mngzlib_inflatefree (pData);     /* zlib's done */
-
-      if (iRetcode == MNG_BUFOVERFLOW) /* not enough space ? */
-      {                                /* then get some more */
-        MNG_FREEX (pData, *pOutbuf, *iOutsize);
-        *iOutsize = *iOutsize + *iOutsize;
-        MNG_ALLOC (pData, *pOutbuf, *iOutsize);
-      }
-    }                                  /* repeat if we didn't have enough space */
-    while ((iRetcode == MNG_BUFOVERFLOW) &&
-           (*iOutsize < 200 * iInsize));
-
-    if (!iRetcode)                     /* if oke ? */
-      *((*pOutbuf) + *iRealsize) = 0;  /* then put terminator zero */
-
-  }
-  else
-  {
-    *pOutbuf   = 0;                    /* nothing to do; then there's no output */
-    *iOutsize  = 0;
-    *iRealsize = 0;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INFLATE_BUFFER, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-
-#endif /* MNG_INCLUDE_READ_PROCS */
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Helper routines to simplify chunk writing                              * */
-/* *                                                                        * */
-/* ************************************************************************** */
-#ifdef MNG_INCLUDE_WRITE_PROCS
-/* ************************************************************************** */
-
-#if !defined(MNG_SKIPCHUNK_iCCP) || !defined(MNG_SKIPCHUNK_zTXt) || !defined(MNG_SKIPCHUNK_iTXt)
-MNG_LOCAL mng_retcode deflate_buffer (mng_datap  pData,
-                                      mng_uint8p pInbuf,
-                                      mng_uint32 iInsize,
-                                      mng_uint8p *pOutbuf,
-                                      mng_uint32 *iOutsize,
-                                      mng_uint32 *iRealsize)
-{
-  mng_retcode iRetcode = MNG_NOERROR;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DEFLATE_BUFFER, MNG_LC_START);
-#endif
-
-  if (iInsize)                         /* anything to do ? */
-  {
-    *iOutsize = (iInsize * 5) >> 2;    /* estimate compressed size */
-                                       /* and allocate a temporary buffer */
-    MNG_ALLOC (pData, *pOutbuf, *iOutsize);
-
-    do
-    {
-      mngzlib_deflateinit (pData);     /* initialize zlib */
-                                       /* let zlib know where to store the output */
-      pData->sZlib.next_out  = *pOutbuf;
-      pData->sZlib.avail_out = *iOutsize;
-                                       /* ok; let's deflate... */
-      iRetcode = mngzlib_deflatedata (pData, iInsize, pInbuf);
-                                       /* determine actual output size */
-      *iRealsize = pData->sZlib.total_out;
-
-      mngzlib_deflatefree (pData);     /* zlib's done */
-
-      if (iRetcode == MNG_BUFOVERFLOW) /* not enough space ? */
-      {                                /* then get some more */
-        MNG_FREEX (pData, *pOutbuf, *iOutsize);
-        *iOutsize = *iOutsize + (iInsize >> 1);
-        MNG_ALLOC (pData, *pOutbuf, *iOutsize);
-      }
-    }                                  /* repeat if we didn't have enough space */
-    while (iRetcode == MNG_BUFOVERFLOW);
-  }
-  else
-  {
-    *pOutbuf   = 0;                    /* nothing to do; then there's no output */
-    *iOutsize  = 0;
-    *iRealsize = 0;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DEFLATE_BUFFER, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-
-MNG_LOCAL mng_retcode write_raw_chunk (mng_datap   pData,
-                                       mng_chunkid iChunkname,
-                                       mng_uint32  iRawlen,
-                                       mng_uint8p  pRawdata)
-{
-  mng_uint32 iCrc;
-  mng_uint32 iWritten;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_RAW_CHUNK, MNG_LC_START);
-#endif
-                                       /* temporary buffer ? */
-  if ((pRawdata != 0) && (pRawdata != pData->pWritebuf+8))
-  {                                    /* store length & chunktype in default buffer */
-    mng_put_uint32 (pData->pWritebuf,   iRawlen);
-    mng_put_uint32 (pData->pWritebuf+4, (mng_uint32)iChunkname);
-
-    if (pData->iCrcmode & MNG_CRC_OUTPUT)
-    {
-      if ((pData->iCrcmode & MNG_CRC_OUTPUT) == MNG_CRC_OUTPUT_GENERATE)
-      {                                /* calculate the crc */
-        iCrc = update_crc (pData, 0xffffffffL, pData->pWritebuf+4, 4);
-        iCrc = update_crc (pData, iCrc, pRawdata, iRawlen) ^ 0xffffffffL;
-      } else {
-        iCrc = 0;                      /* dummy crc */
-      }                                /* store in default buffer */
-      mng_put_uint32 (pData->pWritebuf+8, iCrc);
-    }
-                                       /* write the length & chunktype */
-    if (!pData->fWritedata ((mng_handle)pData, pData->pWritebuf, 8, &iWritten))
-      MNG_ERROR (pData, MNG_APPIOERROR);
-
-    if (iWritten != 8)                 /* disk full ? */
-      MNG_ERROR (pData, MNG_OUTPUTERROR);
-                                       /* write the temporary buffer */
-    if (!pData->fWritedata ((mng_handle)pData, pRawdata, iRawlen, &iWritten))
-      MNG_ERROR (pData, MNG_APPIOERROR);
-
-    if (iWritten != iRawlen)           /* disk full ? */
-      MNG_ERROR (pData, MNG_OUTPUTERROR);
-
-    if (pData->iCrcmode & MNG_CRC_OUTPUT)
-    {                                  /* write the crc */
-      if (!pData->fWritedata ((mng_handle)pData, pData->pWritebuf+8, 4, &iWritten))
-        MNG_ERROR (pData, MNG_APPIOERROR);
-
-      if (iWritten != 4)               /* disk full ? */
-        MNG_ERROR (pData, MNG_OUTPUTERROR);
-    }
-  }
-  else
-  {                                    /* prefix with length & chunktype */
-    mng_put_uint32 (pData->pWritebuf,   iRawlen);
-    mng_put_uint32 (pData->pWritebuf+4, (mng_uint32)iChunkname);
-
-    if (pData->iCrcmode & MNG_CRC_OUTPUT)
-    {
-      if ((pData->iCrcmode & MNG_CRC_OUTPUT) == MNG_CRC_OUTPUT_GENERATE)
-                                       /* calculate the crc */
-        iCrc = mng_crc (pData, pData->pWritebuf+4, iRawlen + 4);
-      else
-        iCrc = 0;                      /* dummy crc */
-                                       /* add it to the buffer */
-      mng_put_uint32 (pData->pWritebuf + iRawlen + 8, iCrc);
-                                       /* write it in a single pass */
-      if (!pData->fWritedata ((mng_handle)pData, pData->pWritebuf, iRawlen + 12, &iWritten))
-        MNG_ERROR (pData, MNG_APPIOERROR);
-
-      if (iWritten != iRawlen + 12)    /* disk full ? */
-        MNG_ERROR (pData, MNG_OUTPUTERROR);
-    } else {
-      if (!pData->fWritedata ((mng_handle)pData, pData->pWritebuf, iRawlen + 8, &iWritten))
-        MNG_ERROR (pData, MNG_APPIOERROR);
-
-      if (iWritten != iRawlen + 8)     /* disk full ? */
-        MNG_ERROR (pData, MNG_OUTPUTERROR);
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_RAW_CHUNK, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-/* B004 */
-#endif /* MNG_INCLUDE_WRITE_PROCS */
-/* B004 */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * chunk read functions                                                   * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_READ_PROCS
-
-/* ************************************************************************** */
-
-#ifdef MNG_OPTIMIZE_CHUNKREADER
-
-/* ************************************************************************** */
-
-MNG_LOCAL mng_retcode create_chunk_storage (mng_datap       pData,
-                                            mng_chunkp      pHeader,
-                                            mng_uint32      iRawlen,
-                                            mng_uint8p      pRawdata,
-                                            mng_field_descp pField,
-                                            mng_uint16      iFields,
-                                            mng_chunkp*     ppChunk,
-                                            mng_bool        bWorkcopy)
-{
-  mng_field_descp pTempfield  = pField;
-  mng_uint16      iFieldcount = iFields;
-  mng_uint8p      pTempdata   = pRawdata;
-  mng_uint32      iTemplen    = iRawlen;
-  mng_uint16      iLastgroup  = 0;
-  mng_uint8p      pChunkdata;
-  mng_uint32      iDatalen;
-  mng_uint8       iColortype;
-  mng_bool        bProcess;
-                                       /* initialize storage */
-  mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-
-  if (((mng_chunk_headerp)(*ppChunk))->iChunkname == MNG_UINT_HUH)
-    ((mng_chunk_headerp)(*ppChunk))->iChunkname = pData->iChunkname;
-
-  if ((!bWorkcopy) ||
-      ((((mng_chunk_headerp)pHeader)->iChunkname != MNG_UINT_IDAT) &&
-       (((mng_chunk_headerp)pHeader)->iChunkname != MNG_UINT_JDAT) &&
-       (((mng_chunk_headerp)pHeader)->iChunkname != MNG_UINT_JDAA)   ))
-  {
-    pChunkdata = (mng_uint8p)(*ppChunk);
-
-#ifdef MNG_INCLUDE_JNG                 /* determine current colortype */
-    if (pData->bHasJHDR)
-      iColortype = (mng_uint8)(pData->iJHDRcolortype - 8);
-    else
-#endif /* MNG_INCLUDE_JNG */
-    if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-      iColortype = pData->iColortype;
-    else
-      iColortype = 6;
-
-    if (iTemplen)                      /* not empty ? */
-    {                                  /* then go fill the fields */
-      while ((iFieldcount) && (iTemplen))
-      {
-        if (pTempfield->iOffsetchunk)
-        {
-          if (pTempfield->iFlags & MNG_FIELD_PUTIMGTYPE)
-          {
-            *(pChunkdata+pTempfield->iOffsetchunk) = iColortype;
-            bProcess = MNG_FALSE;
-          }
-          else
-          if (pTempfield->iFlags & MNG_FIELD_IFIMGTYPES)
-            bProcess = (mng_bool)(((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE0) && (iColortype == 0)) ||
-                                  ((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE2) && (iColortype == 2)) ||
-                                  ((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE3) && (iColortype == 3)) ||
-                                  ((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE4) && (iColortype == 4)) ||
-                                  ((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE6) && (iColortype == 6))   );
-          else
-            bProcess = MNG_TRUE;
-
-          if (bProcess)
-          {
-            iLastgroup = (mng_uint16)(pTempfield->iFlags & MNG_FIELD_GROUPMASK);
-                                      /* numeric field ? */
-            if (pTempfield->iFlags & MNG_FIELD_INT)
-            {
-              if (iTemplen < pTempfield->iLengthmax)
-                MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-              switch (pTempfield->iLengthmax)
-              {
-                case 1 : { mng_uint8 iNum = *pTempdata;
-                           if (((mng_uint16)iNum < pTempfield->iMinvalue) ||
-                               ((mng_uint16)iNum > pTempfield->iMaxvalue)    )
-                             MNG_ERROR (pData, MNG_INVALIDFIELDVAL);
-                           *(pChunkdata+pTempfield->iOffsetchunk) = iNum;
-                           break; }
-                case 2 : { mng_uint16 iNum = mng_get_uint16 (pTempdata);
-                           if ((iNum < pTempfield->iMinvalue) || (iNum > pTempfield->iMaxvalue))
-                             MNG_ERROR (pData, MNG_INVALIDFIELDVAL);
-                           *((mng_uint16p)(pChunkdata+pTempfield->iOffsetchunk)) = iNum;
-                           break; }
-                case 4 : { mng_uint32 iNum = mng_get_uint32 (pTempdata);
-                           if ((iNum < pTempfield->iMinvalue) ||
-                               ((pTempfield->iFlags & MNG_FIELD_NOHIGHBIT) && (iNum & 0x80000000)) )
-                             MNG_ERROR (pData, MNG_INVALIDFIELDVAL);
-                           *((mng_uint32p)(pChunkdata+pTempfield->iOffsetchunk)) = iNum;
-                           break; }
-              }
-
-              pTempdata += pTempfield->iLengthmax;
-              iTemplen  -= pTempfield->iLengthmax;
-
-            } else {                   /* not numeric so it's a bunch of bytes */
-
-              if (!pTempfield->iOffsetchunklen)    /* big fat NONO */
-                MNG_ERROR (pData, MNG_INTERNALERROR);
-                                       /* with terminating 0 ? */
-              if (pTempfield->iFlags & MNG_FIELD_TERMINATOR)
-              {
-                mng_uint8p pWork = pTempdata;
-                while (*pWork)         /* find the zero */
-                  pWork++;
-                iDatalen = (mng_uint32)(pWork - pTempdata);
-              } else {                 /* no terminator, so everything that's left ! */
-                iDatalen = iTemplen;
-              }
-
-              if ((pTempfield->iLengthmax) && (iDatalen > pTempfield->iLengthmax))
-                MNG_ERROR (pData, MNG_INVALIDLENGTH);
-#if !defined(MNG_SKIPCHUNK_iCCP) || !defined(MNG_SKIPCHUNK_zTXt) || \
-    !defined(MNG_SKIPCHUNK_iTXt) || defined(MNG_INCLUDE_MPNG_PROPOSAL) || \
-    defined(MNG_INCLUDE_ANG_PROPOSAL)
-                                       /* needs decompression ? */
-              if (pTempfield->iFlags & MNG_FIELD_DEFLATED)
-              {
-                mng_uint8p pBuf = 0;
-                mng_uint32 iBufsize = 0;
-                mng_uint32 iRealsize;
-                mng_ptr    pWork;
-
-                iRetcode = mng_inflate_buffer (pData, pTempdata, iDatalen,
-                                               &pBuf, &iBufsize, &iRealsize);
-
-#ifdef MNG_CHECK_BAD_ICCP              /* Check for bad iCCP chunk */
-                if ((iRetcode) && (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_iCCP))
-                {
-                  *((mng_ptr *)(pChunkdata+pTempfield->iOffsetchunk))      = MNG_NULL;
-                  *((mng_uint32p)(pChunkdata+pTempfield->iOffsetchunklen)) = iDatalen;
-                }
-                else
-#endif
-                {
-                  if (iRetcode)
-                    return iRetcode;
-
-#if defined(MNG_INCLUDE_MPNG_PROPOSAL) || defined(MNG_INCLUDE_ANG_PROPOSAL)
-                  if ( (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_mpNG) ||
-                       (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_adAT)    )
-                  {
-                    MNG_ALLOC (pData, pWork, iRealsize);
-                  }
-                  else
-                  {
-#endif
-                                       /* don't forget to generate null terminator */
-                    MNG_ALLOC (pData, pWork, iRealsize+1);
-#if defined(MNG_INCLUDE_MPNG_PROPOSAL) || defined(MNG_INCLUDE_ANG_PROPOSAL)
-                  }
-#endif
-                  MNG_COPY (pWork, pBuf, iRealsize);
-
-                  *((mng_ptr *)(pChunkdata+pTempfield->iOffsetchunk))      = pWork;
-                  *((mng_uint32p)(pChunkdata+pTempfield->iOffsetchunklen)) = iRealsize;
-                }
-
-                if (pBuf)              /* free the temporary buffer */
-                  MNG_FREEX (pData, pBuf, iBufsize);
-
-              } else
-#endif
-                     {                 /* no decompression, so just copy */
-
-                mng_ptr pWork;
-                                       /* don't forget to generate null terminator */
-                MNG_ALLOC (pData, pWork, iDatalen+1);
-                MNG_COPY (pWork, pTempdata, iDatalen);
-
-                *((mng_ptr *)(pChunkdata+pTempfield->iOffsetchunk))      = pWork;
-                *((mng_uint32p)(pChunkdata+pTempfield->iOffsetchunklen)) = iDatalen;
-              }
-
-              if (pTempfield->iFlags & MNG_FIELD_TERMINATOR)
-                iDatalen++;            /* skip the terminating zero as well !!! */
-
-              iTemplen  -= iDatalen;
-              pTempdata += iDatalen;
-            }
-                                       /* need to set an indicator ? */
-            if (pTempfield->iOffsetchunkind)
-              *((mng_uint8p)(pChunkdata+pTempfield->iOffsetchunkind)) = MNG_TRUE;
-          }
-        }
-
-        if (pTempfield->pSpecialfunc)  /* special function required ? */
-        {
-          iRetcode = pTempfield->pSpecialfunc(pData, *ppChunk, &iTemplen, &pTempdata);
-          if (iRetcode)                /* on error bail out */
-            return iRetcode;
-        }
-
-        pTempfield++;                  /* Neeeeeeexxxtt */
-        iFieldcount--;
-      }
-
-      if (iTemplen)                    /* extra data ??? */
-        MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-      while (iFieldcount)              /* not enough data ??? */
-      {
-        if (pTempfield->iFlags & MNG_FIELD_IFIMGTYPES)
-          bProcess = (mng_bool)(((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE0) && (iColortype == 0)) ||
-                                ((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE2) && (iColortype == 2)) ||
-                                ((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE3) && (iColortype == 3)) ||
-                                ((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE4) && (iColortype == 4)) ||
-                                ((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE6) && (iColortype == 6))   );
-        else
-          bProcess = MNG_TRUE;
-
-        if (bProcess)
-        {
-          if (!(pTempfield->iFlags & MNG_FIELD_OPTIONAL))
-            MNG_ERROR (pData, MNG_INVALIDLENGTH);
-          if ((pTempfield->iFlags & MNG_FIELD_GROUPMASK) &&
-              ((mng_uint16)(pTempfield->iFlags & MNG_FIELD_GROUPMASK) == iLastgroup))
-            MNG_ERROR (pData, MNG_INVALIDLENGTH);
-        }
-
-        pTempfield++;
-        iFieldcount--;
-      }
-    }
-  }
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-READ_CHUNK (mng_read_general)
-{
-  mng_retcode     iRetcode = MNG_NOERROR;
-  mng_chunk_descp pDescr   = ((mng_chunk_headerp)pHeader)->pChunkdescr;
-  mng_field_descp pField;
-  mng_uint16      iFields;
-
-  if (!pDescr)                         /* this is a bad booboo !!! */
-    MNG_ERROR (pData, MNG_INTERNALERROR);
-
-  pField  = pDescr->pFielddesc;
-  iFields = pDescr->iFielddesc;
-                                       /* check chunk against signature */
-  if ((pDescr->eImgtype == mng_it_mng) && (pData->eSigtype != mng_it_mng))
-    MNG_ERROR (pData, MNG_CHUNKNOTALLOWED);
-
-  if ((pDescr->eImgtype == mng_it_jng) && (pData->eSigtype == mng_it_png))
-    MNG_ERROR (pData, MNG_CHUNKNOTALLOWED);
-                                       /* empties allowed ? */
-  if ((iRawlen == 0) && (!(pDescr->iAllowed & MNG_DESCR_EMPTY)))
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-  if ((pData->eImagetype != mng_it_mng) || (!(pDescr->iAllowed & MNG_DESCR_GLOBAL)))
-  {                                    /* *a* header required ? */
-    if ((pDescr->iMusthaves & MNG_DESCR_GenHDR) &&
-#ifdef MNG_INCLUDE_JNG
-        (!pData->bHasIHDR) && (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
-#else
-        (!pData->bHasIHDR) && (!pData->bHasBASI) && (!pData->bHasDHDR))
-#endif
-      MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-#ifdef MNG_INCLUDE_JNG
-    if ((pDescr->iMusthaves & MNG_DESCR_JngHDR) &&
-        (!pData->bHasDHDR) && (!pData->bHasJHDR))
-      MNG_ERROR (pData, MNG_SEQUENCEERROR);
-#endif
-  }
-                                       /* specific chunk pre-requisite ? */
-  if (((pDescr->iMusthaves & MNG_DESCR_IHDR) && (!pData->bHasIHDR)) ||
-#ifdef MNG_INCLUDE_JNG
-      ((pDescr->iMusthaves & MNG_DESCR_JHDR) && (!pData->bHasJHDR)) ||
-#endif
-      ((pDescr->iMusthaves & MNG_DESCR_DHDR) && (!pData->bHasDHDR)) ||
-      ((pDescr->iMusthaves & MNG_DESCR_LOOP) && (!pData->bHasLOOP)) ||
-      ((pDescr->iMusthaves & MNG_DESCR_PLTE) && (!pData->bHasPLTE)) ||
-      ((pDescr->iMusthaves & MNG_DESCR_MHDR) && (!pData->bHasMHDR)) ||
-      ((pDescr->iMusthaves & MNG_DESCR_SAVE) && (!pData->bHasSAVE))   )
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-                                       /* specific chunk undesired ? */
-  if (((pDescr->iMustNOThaves & MNG_DESCR_NOIHDR) && (pData->bHasIHDR)) ||
-      ((pDescr->iMustNOThaves & MNG_DESCR_NOBASI) && (pData->bHasBASI)) ||
-      ((pDescr->iMustNOThaves & MNG_DESCR_NODHDR) && (pData->bHasDHDR)) ||
-      ((pDescr->iMustNOThaves & MNG_DESCR_NOIDAT) && (pData->bHasIDAT)) ||
-      ((pDescr->iMustNOThaves & MNG_DESCR_NOPLTE) && (pData->bHasPLTE)) ||
-#ifdef MNG_INCLUDE_JNG
-      ((pDescr->iMustNOThaves & MNG_DESCR_NOJHDR) && (pData->bHasJHDR)) ||
-      ((pDescr->iMustNOThaves & MNG_DESCR_NOJDAT) && (pData->bHasJDAT)) ||
-      ((pDescr->iMustNOThaves & MNG_DESCR_NOJDAA) && (pData->bHasJDAA)) ||
-      ((pDescr->iMustNOThaves & MNG_DESCR_NOJSEP) && (pData->bHasJSEP)) ||
-#endif
-      ((pDescr->iMustNOThaves & MNG_DESCR_NOMHDR) && (pData->bHasMHDR)) ||
-      ((pDescr->iMustNOThaves & MNG_DESCR_NOLOOP) && (pData->bHasLOOP)) ||
-      ((pDescr->iMustNOThaves & MNG_DESCR_NOTERM) && (pData->bHasTERM)) ||
-      ((pDescr->iMustNOThaves & MNG_DESCR_NOSAVE) && (pData->bHasSAVE))   )
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-  if (pData->eSigtype == mng_it_mng)   /* check global and embedded empty chunks */
-  {
-#ifdef MNG_INCLUDE_JNG
-    if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-    if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-    {
-      if ((iRawlen == 0) && (!(pDescr->iAllowed & MNG_DESCR_EMPTYEMBED)))
-        MNG_ERROR (pData, MNG_INVALIDLENGTH);
-    } else {
-      if ((iRawlen == 0) && (!(pDescr->iAllowed & MNG_DESCR_EMPTYGLOBAL)))
-        MNG_ERROR (pData, MNG_INVALIDLENGTH);
-    }
-  }
-
-  if (pDescr->pSpecialfunc)            /* need special processing ? */
-  {
-    iRetcode = create_chunk_storage (pData, pHeader, iRawlen, pRawdata,
-                                     pField, iFields, ppChunk, MNG_TRUE);
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* empty indicator ? */
-    if ((!iRawlen) && (pDescr->iOffsetempty))
-      *(((mng_uint8p)*ppChunk)+pDescr->iOffsetempty) = MNG_TRUE;
-
-    iRetcode = pDescr->pSpecialfunc(pData, *ppChunk);
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-
-    if ((((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_IDAT) ||
-        (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_JDAT) ||
-        (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_JDAA)    )
-    {
-      iRetcode = ((mng_chunk_headerp)*ppChunk)->fCleanup (pData, *ppChunk);
-      if (iRetcode)                    /* on error bail out */
-        return iRetcode;
-      *ppChunk = MNG_NULL;
-    } else {
-#ifdef MNG_STORE_CHUNKS
-      if (!pData->bStorechunks)
-#endif
-      {
-        iRetcode = ((mng_chunk_headerp)*ppChunk)->fCleanup (pData, *ppChunk);
-        if (iRetcode)                  /* on error bail out */
-          return iRetcode;
-        *ppChunk = MNG_NULL;
-      }
-    }
-  }
-
-#ifdef MNG_SUPPORT_DISPLAY
-  if (iRawlen)
-  {
-#ifdef MNG_OPTIMIZE_DISPLAYCALLS
-    pData->iRawlen  = iRawlen;
-    pData->pRawdata = pRawdata;
-#endif
-
-                                       /* display processing */
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-    if (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_IDAT)
-      iRetcode = mng_process_display_idat (pData, iRawlen, pRawdata);
-#ifdef MNG_INCLUDE_JNG
-    else
-    if (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_JDAT)
-      iRetcode = mng_process_display_jdat (pData, iRawlen, pRawdata);
-    else
-    if (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_JDAA)
-      iRetcode = mng_process_display_jdaa (pData, iRawlen, pRawdata);
-#endif
-#else
-    if (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_IDAT)
-      iRetcode = mng_process_display_idat (pData);
-#ifdef MNG_INCLUDE_JNG
-    else
-    if (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_JDAT)
-      iRetcode = mng_process_display_jdat (pData);
-    else
-    if (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_JDAA)
-      iRetcode = mng_process_display_jdaa (pData);
-#endif
-#endif
-
-    if (iRetcode)
-      return iRetcode;
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if ((pData->bStorechunks) && (!(*ppChunk)))
-  {
-    iRetcode = create_chunk_storage (pData, pHeader, iRawlen, pRawdata,
-                                     pField, iFields, ppChunk, MNG_FALSE);
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* empty indicator ? */
-    if ((!iRawlen) && (pDescr->iOffsetempty))
-      *(((mng_uint8p)*ppChunk)+pDescr->iOffsetempty) = MNG_TRUE;
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#endif /* MNG_OPTIMIZE_CHUNKREADER */
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-READ_CHUNK (mng_read_ihdr)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_IHDR, MNG_LC_START);
-#endif
-
-  if (iRawlen != 13)                   /* length oke ? */
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-                                       /* only allowed inside PNG or MNG */
-  if ((pData->eSigtype != mng_it_png) && (pData->eSigtype != mng_it_mng))
-    MNG_ERROR (pData, MNG_CHUNKNOTALLOWED);
-                                       /* sequence checks */
-  if ((pData->eSigtype == mng_it_png) && (pData->iChunkseq > 1))
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasIDAT) || (pData->bHasJHDR))
-#else
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasIDAT))
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-  pData->bHasIHDR      = MNG_TRUE;     /* indicate IHDR is present */
-                                       /* and store interesting fields */
-  if ((!pData->bHasDHDR) || (pData->iDeltatype == MNG_DELTATYPE_NOCHANGE))
-  {
-    pData->iDatawidth  = mng_get_uint32 (pRawdata);
-    pData->iDataheight = mng_get_uint32 (pRawdata+4);
-  }
-
-  pData->iBitdepth     = *(pRawdata+8);
-  pData->iColortype    = *(pRawdata+9);
-  pData->iCompression  = *(pRawdata+10);
-  pData->iFilter       = *(pRawdata+11);
-  pData->iInterlace    = *(pRawdata+12);
-
-#if defined(MNG_NO_1_2_4BIT_SUPPORT) || defined(MNG_NO_16BIT_SUPPORT)
-  pData->iPNGmult = 1;
-  pData->iPNGdepth = pData->iBitdepth;
-#endif
-
-#ifdef MNG_NO_1_2_4BIT_SUPPORT
-  if (pData->iBitdepth < 8)
-      pData->iBitdepth = 8;
-#endif
-
-#ifdef MNG_NO_16BIT_SUPPORT
-  if (pData->iBitdepth > 8)
-    {
-      pData->iBitdepth = 8;
-      pData->iPNGmult = 2;
-    }
-#endif
-
-  if ((pData->iBitdepth !=  8)      /* parameter validity checks */
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-      && (pData->iBitdepth !=  1) &&
-      (pData->iBitdepth !=  2) &&
-      (pData->iBitdepth !=  4)
-#endif
-#ifndef MNG_NO_16BIT_SUPPORT
-      && (pData->iBitdepth != 16)   
-#endif
-      )
-    MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
-
-  if ((pData->iColortype != MNG_COLORTYPE_GRAY   ) &&
-      (pData->iColortype != MNG_COLORTYPE_RGB    ) &&
-      (pData->iColortype != MNG_COLORTYPE_INDEXED) &&
-      (pData->iColortype != MNG_COLORTYPE_GRAYA  ) &&
-      (pData->iColortype != MNG_COLORTYPE_RGBA   )    )
-    MNG_ERROR (pData, MNG_INVALIDCOLORTYPE);
-
-  if ((pData->iColortype == MNG_COLORTYPE_INDEXED) && (pData->iBitdepth > 8))
-    MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
-
-  if (((pData->iColortype == MNG_COLORTYPE_RGB    ) ||
-       (pData->iColortype == MNG_COLORTYPE_GRAYA  ) ||
-       (pData->iColortype == MNG_COLORTYPE_RGBA   )    ) &&
-      (pData->iBitdepth < 8                            )    )
-    MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
-
-  if (pData->iCompression != MNG_COMPRESSION_DEFLATE)
-    MNG_ERROR (pData, MNG_INVALIDCOMPRESS);
-
-#if defined(FILTER192) || defined(FILTER193)
-  if ((pData->iFilter != MNG_FILTER_ADAPTIVE ) &&
-#if defined(FILTER192) && defined(FILTER193)
-      (pData->iFilter != MNG_FILTER_DIFFERING) &&
-      (pData->iFilter != MNG_FILTER_NOFILTER )    )
-#else
-#ifdef FILTER192
-      (pData->iFilter != MNG_FILTER_DIFFERING)    )
-#else
-      (pData->iFilter != MNG_FILTER_NOFILTER )    )
-#endif
-#endif
-    MNG_ERROR (pData, MNG_INVALIDFILTER);
-#else
-  if (pData->iFilter)
-    MNG_ERROR (pData, MNG_INVALIDFILTER);
-#endif
-
-  if ((pData->iInterlace != MNG_INTERLACE_NONE ) &&
-      (pData->iInterlace != MNG_INTERLACE_ADAM7)    )
-    MNG_ERROR (pData, MNG_INVALIDINTERLACE);
-
-#ifdef MNG_SUPPORT_DISPLAY 
-#ifndef MNG_NO_DELTA_PNG
-  if (pData->bHasDHDR)                 /* check the colortype for delta-images ! */
-  {
-    mng_imagedatap pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
-
-    if (pData->iColortype != pBuf->iColortype)
-    {
-      if ( ( (pData->iColortype != MNG_COLORTYPE_INDEXED) ||
-             (pBuf->iColortype  == MNG_COLORTYPE_GRAY   )    ) &&
-           ( (pData->iColortype != MNG_COLORTYPE_GRAY   ) ||
-             (pBuf->iColortype  == MNG_COLORTYPE_INDEXED)    )    )
-        MNG_ERROR (pData, MNG_INVALIDCOLORTYPE);
-    }
-  }
-#endif
-#endif
-
-  if (!pData->bHasheader)              /* first chunk ? */
-  {
-    pData->bHasheader = MNG_TRUE;      /* we've got a header */
-    pData->eImagetype = mng_it_png;    /* then this must be a PNG */
-    pData->iWidth     = pData->iDatawidth;
-    pData->iHeight    = pData->iDataheight;
-                                       /* predict alpha-depth ! */
-    if ((pData->iColortype == MNG_COLORTYPE_GRAYA  ) ||
-        (pData->iColortype == MNG_COLORTYPE_RGBA   )    )
-      pData->iAlphadepth = pData->iBitdepth;
-    else
-    if (pData->iColortype == MNG_COLORTYPE_INDEXED)
-      pData->iAlphadepth = 8;          /* worst case scenario */
-    else
-      pData->iAlphadepth = 1;  /* Possible tRNS cheap binary transparency */
-                                       /* fits on maximum canvas ? */
-    if ((pData->iWidth > pData->iMaxwidth) || (pData->iHeight > pData->iMaxheight))
-      MNG_WARNING (pData, MNG_IMAGETOOLARGE);
-
-#if !defined(MNG_INCLUDE_MPNG_PROPOSAL) || !defined(MNG_SUPPORT_DISPLAY)
-    if (pData->fProcessheader)         /* inform the app ? */
-      if (!pData->fProcessheader (((mng_handle)pData), pData->iWidth, pData->iHeight))
-        MNG_ERROR (pData, MNG_APPMISCERROR);
-#endif        
-  }
-
-  if (!pData->bHasDHDR)
-    pData->iImagelevel++;              /* one level deeper */
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-    mng_retcode iRetcode = mng_process_display_ihdr (pData);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* fill the fields */
-    ((mng_ihdrp)*ppChunk)->iWidth       = mng_get_uint32 (pRawdata);
-    ((mng_ihdrp)*ppChunk)->iHeight      = mng_get_uint32 (pRawdata+4);
-    ((mng_ihdrp)*ppChunk)->iBitdepth    = pData->iBitdepth;
-    ((mng_ihdrp)*ppChunk)->iColortype   = pData->iColortype;
-    ((mng_ihdrp)*ppChunk)->iCompression = pData->iCompression;
-    ((mng_ihdrp)*ppChunk)->iFilter      = pData->iFilter;
-    ((mng_ihdrp)*ppChunk)->iInterlace   = pData->iInterlace;
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_IHDR, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif /* MNG_OPTIMIZE_CHUNKREADER */
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-READ_CHUNK (mng_read_plte)
-{
-#if defined(MNG_SUPPORT_DISPLAY) || defined(MNG_STORE_CHUNKS)
-  mng_uint32  iX;
-  mng_uint8p  pRawdata2;
-#endif
-#ifdef MNG_SUPPORT_DISPLAY
-  mng_uint32  iRawlen2;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_PLTE, MNG_LC_START);
-#endif
-                                       /* sequence checks */
-  if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
-      (!pData->bHasBASI) && (!pData->bHasDHDR)    )
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIDAT) || (pData->bHasJHDR))
-#else
-  if (pData->bHasIDAT)
-#endif  
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-                                       /* multiple PLTE only inside BASI */
-  if ((pData->bHasPLTE) && (!pData->bHasBASI))
-    MNG_ERROR (pData, MNG_MULTIPLEERROR);
-                                       /* length must be multiple of 3 */
-  if (((iRawlen % 3) != 0) || (iRawlen > 768))
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-  {                                    /* only allowed for indexed-color or
-                                          rgb(a)-color! */
-    if ((pData->iColortype != 2) && (pData->iColortype != 3) && (pData->iColortype != 6))
-      MNG_ERROR (pData, MNG_CHUNKNOTALLOWED);
-                                       /* empty only allowed if global present */
-    if ((iRawlen == 0) && (!pData->bHasglobalPLTE))
-        MNG_ERROR (pData, MNG_CANNOTBEEMPTY);
-  }
-  else
-  {
-    if (iRawlen == 0)                  /* cannot be empty as global! */
-      MNG_ERROR (pData, MNG_CANNOTBEEMPTY);
-  }
-
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-    pData->bHasPLTE = MNG_TRUE;        /* got it! */
-  else
-    pData->bHasglobalPLTE = MNG_TRUE;
-
-  pData->iPLTEcount = iRawlen / 3;  
-
-#ifdef MNG_SUPPORT_DISPLAY
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-  {
-    mng_imagep     pImage;
-    mng_imagedatap pBuf;
-
-#ifndef MNG_NO_DELTA_PNG
-    if (pData->bHasDHDR)               /* processing delta-image ? */
-    {                                  /* store in object 0 !!! */
-      pImage           = (mng_imagep)pData->pObjzero;
-      pBuf             = pImage->pImgbuf;
-      pBuf->bHasPLTE   = MNG_TRUE;     /* it's definitely got a PLTE now */
-      pBuf->iPLTEcount = iRawlen / 3;  /* this is the exact length */
-      pRawdata2        = pRawdata;     /* copy the entries */
-
-      for (iX = 0; iX < iRawlen / 3; iX++)
-      {
-        pBuf->aPLTEentries[iX].iRed   = *pRawdata2;
-        pBuf->aPLTEentries[iX].iGreen = *(pRawdata2+1);
-        pBuf->aPLTEentries[iX].iBlue  = *(pRawdata2+2);
-
-        pRawdata2 += 3;
-      }
-    }
-    else
-#endif
-    {                                  /* get the current object */
-      pImage = (mng_imagep)pData->pCurrentobj;
-
-      if (!pImage)                     /* no object then dump it in obj 0 */
-        pImage = (mng_imagep)pData->pObjzero;
-
-      pBuf = pImage->pImgbuf;          /* address the object buffer */
-      pBuf->bHasPLTE = MNG_TRUE;       /* and tell it it's got a PLTE now */
-
-      if (!iRawlen)                    /* if empty, inherit from global */
-      {
-        pBuf->iPLTEcount = pData->iGlobalPLTEcount;
-        MNG_COPY (pBuf->aPLTEentries, pData->aGlobalPLTEentries,
-                  sizeof (pBuf->aPLTEentries));
-
-        if (pData->bHasglobalTRNS)     /* also copy global tRNS ? */
-        {                              /* indicate tRNS available */
-          pBuf->bHasTRNS = MNG_TRUE;
-
-          iRawlen2  = pData->iGlobalTRNSrawlen;
-          pRawdata2 = (mng_uint8p)(pData->aGlobalTRNSrawdata);
-                                       /* global length oke ? */
-          if ((iRawlen2 == 0) || (iRawlen2 > pBuf->iPLTEcount))
-            MNG_ERROR (pData, MNG_GLOBALLENGTHERR);
-                                       /* copy it */
-          pBuf->iTRNScount = iRawlen2;
-          MNG_COPY (pBuf->aTRNSentries, pRawdata2, iRawlen2);
-        }
-      }
-      else
-      {                                /* store fields for future reference */
-        pBuf->iPLTEcount = iRawlen / 3;
-        pRawdata2        = pRawdata;
-
-        for (iX = 0; iX < pBuf->iPLTEcount; iX++)
-        {
-          pBuf->aPLTEentries[iX].iRed   = *pRawdata2;
-          pBuf->aPLTEentries[iX].iGreen = *(pRawdata2+1);
-          pBuf->aPLTEentries[iX].iBlue  = *(pRawdata2+2);
-
-          pRawdata2 += 3;
-        }
-      }
-    }
-  }
-  else                                 /* store as global */
-  {
-    pData->iGlobalPLTEcount = iRawlen / 3;
-    pRawdata2               = pRawdata;
-
-    for (iX = 0; iX < pData->iGlobalPLTEcount; iX++)
-    {
-      pData->aGlobalPLTEentries[iX].iRed   = *pRawdata2;
-      pData->aGlobalPLTEentries[iX].iGreen = *(pRawdata2+1);
-      pData->aGlobalPLTEentries[iX].iBlue  = *(pRawdata2+2);
-
-      pRawdata2 += 3;
-    }
-
-    {                                  /* create an animation object */
-      mng_retcode iRetcode = mng_create_ani_plte (pData, pData->iGlobalPLTEcount,
-                                                  pData->aGlobalPLTEentries);
-      if (iRetcode)                    /* on error bail out */
-        return iRetcode;
-    }
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the fields */
-    ((mng_pltep)*ppChunk)->bEmpty      = (mng_bool)(iRawlen == 0);
-    ((mng_pltep)*ppChunk)->iEntrycount = iRawlen / 3;
-    pRawdata2                          = pRawdata;
-
-    for (iX = 0; iX < ((mng_pltep)*ppChunk)->iEntrycount; iX++)
-    {
-      ((mng_pltep)*ppChunk)->aEntries[iX].iRed   = *pRawdata2;
-      ((mng_pltep)*ppChunk)->aEntries[iX].iGreen = *(pRawdata2+1);
-      ((mng_pltep)*ppChunk)->aEntries[iX].iBlue  = *(pRawdata2+2);
-
-      pRawdata2 += 3;
-    }
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_PLTE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif /* MNG_OPTIMIZE_CHUNKREADER */
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-READ_CHUNK (mng_read_idat)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_IDAT, MNG_LC_START);
-#endif
-
-#ifdef MNG_INCLUDE_JNG                 /* sequence checks */
-  if ((!pData->bHasIHDR) && (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
-#else
-  if ((!pData->bHasIHDR) && (!pData->bHasBASI) && (!pData->bHasDHDR))
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasJHDR) &&
-      (pData->iJHDRalphacompression != MNG_COMPRESSION_DEFLATE))
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-  if (pData->bHasJSEP)
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-#endif
-                                       /* not allowed for deltatype NO_CHANGE */
-#ifndef MNG_NO_DELTA_PNG
-  if ((pData->bHasDHDR) && ((pData->iDeltatype == MNG_DELTATYPE_NOCHANGE)))
-    MNG_ERROR (pData, MNG_CHUNKNOTALLOWED);
-#endif
-                                       /* can only be empty in BASI-block! */
-  if ((iRawlen == 0) && (!pData->bHasBASI))
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-                                       /* indexed-color requires PLTE */
-  if ((pData->bHasIHDR) && (pData->iColortype == 3) && (!pData->bHasPLTE))
-    MNG_ERROR (pData, MNG_PLTEMISSING);
-
-  pData->bHasIDAT = MNG_TRUE;          /* got some IDAT now, don't we */
-
-#ifdef MNG_SUPPORT_DISPLAY
-  if (iRawlen)
-  {                                    /* display processing */
-    mng_retcode iRetcode = mng_process_display_idat (pData, iRawlen, pRawdata);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the fields */
-    ((mng_idatp)*ppChunk)->bEmpty    = (mng_bool)(iRawlen == 0);
-    ((mng_idatp)*ppChunk)->iDatasize = iRawlen;
-
-    if (iRawlen != 0)                  /* is there any data ? */
-    {
-      MNG_ALLOC (pData, ((mng_idatp)*ppChunk)->pData, iRawlen);
-      MNG_COPY  (((mng_idatp)*ppChunk)->pData, pRawdata, iRawlen);
-    }
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_IDAT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-READ_CHUNK (mng_read_iend)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_IEND, MNG_LC_START);
-#endif
-
-  if (iRawlen > 0)                     /* must not contain data! */
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-#ifdef MNG_INCLUDE_JNG                 /* sequence checks */
-  if ((!pData->bHasIHDR) && (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
-#else
-  if ((!pData->bHasIHDR) && (!pData->bHasBASI) && (!pData->bHasDHDR))
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-                                       /* IHDR-block requires IDAT */
-  if ((pData->bHasIHDR) && (!pData->bHasIDAT))
-    MNG_ERROR (pData, MNG_IDATMISSING);
-
-  pData->iImagelevel--;                /* one level up */
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {                                    /* create an animation object */
-    mng_retcode iRetcode = mng_create_ani_image (pData);
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* display processing */
-    iRetcode = mng_process_display_iend (pData);
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_SUPPORT_DISPLAY
-  if (!pData->bTimerset)               /* reset only if not broken !!! */
-  {
-#endif
-                                       /* IEND signals the end for most ... */
-    pData->bHasIHDR         = MNG_FALSE;
-    pData->bHasBASI         = MNG_FALSE;
-    pData->bHasDHDR         = MNG_FALSE;
-#ifdef MNG_INCLUDE_JNG
-    pData->bHasJHDR         = MNG_FALSE;
-    pData->bHasJSEP         = MNG_FALSE;
-    pData->bHasJDAA         = MNG_FALSE;
-    pData->bHasJDAT         = MNG_FALSE;
-#endif
-    pData->bHasPLTE         = MNG_FALSE;
-    pData->bHasTRNS         = MNG_FALSE;
-    pData->bHasGAMA         = MNG_FALSE;
-    pData->bHasCHRM         = MNG_FALSE;
-    pData->bHasSRGB         = MNG_FALSE;
-    pData->bHasICCP         = MNG_FALSE;
-    pData->bHasBKGD         = MNG_FALSE;
-    pData->bHasIDAT         = MNG_FALSE;
-#ifdef MNG_SUPPORT_DISPLAY
-  }
-#endif
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_IEND, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-READ_CHUNK (mng_read_trns)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_TRNS, MNG_LC_START);
-#endif
-                                       /* sequence checks */
-  if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
-      (!pData->bHasBASI) && (!pData->bHasDHDR)    )
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIDAT) || (pData->bHasJHDR))
-#else
-  if (pData->bHasIDAT)
-#endif  
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-                                       /* multiple tRNS only inside BASI */
-  if ((pData->bHasTRNS) && (!pData->bHasBASI))
-    MNG_ERROR (pData, MNG_MULTIPLEERROR);
-
-  if (iRawlen > 256)                   /* it just can't be bigger than that! */
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-  {                                    /* not allowed with full alpha-channel */
-    if ((pData->iColortype == 4) || (pData->iColortype == 6))
-      MNG_ERROR (pData, MNG_CHUNKNOTALLOWED);
-
-    if (iRawlen != 0)                  /* filled ? */
-    {                                  /* length checks */
-      if ((pData->iColortype == 0) && (iRawlen != 2))
-        MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-      if ((pData->iColortype == 2) && (iRawlen != 6))
-        MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-#ifdef MNG_SUPPORT_DISPLAY
-      if (pData->iColortype == 3)
-      {
-        mng_imagep     pImage = (mng_imagep)pData->pCurrentobj;
-        mng_imagedatap pBuf;
-
-        if (!pImage)                   /* no object then check obj 0 */
-          pImage = (mng_imagep)pData->pObjzero;
-
-        pBuf = pImage->pImgbuf;        /* address object buffer */
-
-        if (iRawlen > pBuf->iPLTEcount)
-          MNG_ERROR (pData, MNG_INVALIDLENGTH);
-      }
-#endif
-    }
-    else                               /* if empty there must be global stuff! */
-    {
-      if (!pData->bHasglobalTRNS)
-        MNG_ERROR (pData, MNG_CANNOTBEEMPTY);
-    }
-  }
-
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-    pData->bHasTRNS = MNG_TRUE;        /* indicate tRNS available */
-  else
-    pData->bHasglobalTRNS = MNG_TRUE;
-
-#ifdef MNG_SUPPORT_DISPLAY
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-  {
-    mng_imagep     pImage;
-    mng_imagedatap pBuf;
-    mng_uint8p     pRawdata2;
-    mng_uint32     iRawlen2;
-
-#ifndef MNG_NO_DELTA_PNG
-    if (pData->bHasDHDR)               /* processing delta-image ? */
-    {                                  /* store in object 0 !!! */
-      pImage = (mng_imagep)pData->pObjzero;
-      pBuf   = pImage->pImgbuf;        /* address object buffer */
-
-      switch (pData->iColortype)       /* store fields for future reference */
-      {
-        case 0: {                      /* gray */
-#if defined(MNG_NO_1_2_4BIT_SUPPORT)
-                  mng_uint8 multiplier[]={0,255,85,0,17,0,0,0,1,
-                                          0,0,0,0,0,0,0,1};
-#endif
-                  pBuf->iTRNSgray  = mng_get_uint16 (pRawdata);
-                  pBuf->iTRNSred   = 0;
-                  pBuf->iTRNSgreen = 0;
-                  pBuf->iTRNSblue  = 0;
-                  pBuf->iTRNScount = 0;
-#if defined(MNG_NO_1_2_4BIT_SUPPORT)
-                  pBuf->iTRNSgray *= multiplier[pData->iPNGdepth];
-#endif
-#if defined(MNG_NO_16BIT_SUPPORT)
-                  if (pData->iPNGmult == 2)
-                     pBuf->iTRNSgray >>= 8;
-#endif
-                  break;
-                }
-        case 2: {                      /* rgb */
-                  pBuf->iTRNSgray  = 0;
-                  pBuf->iTRNSred   = mng_get_uint16 (pRawdata);
-                  pBuf->iTRNSgreen = mng_get_uint16 (pRawdata+2);
-                  pBuf->iTRNSblue  = mng_get_uint16 (pRawdata+4);
-                  pBuf->iTRNScount = 0;
-#if defined(MNG_NO_16BIT_SUPPORT)
-                  if (pData->iPNGmult == 2)
-                  {
-                     pBuf->iTRNSred   >>= 8;
-                     pBuf->iTRNSgreen >>= 8;
-                     pBuf->iTRNSblue  >>= 8;
-                  }
-#endif
-                  break;
-                }
-        case 3: {                      /* indexed */
-                  pBuf->iTRNSgray  = 0;
-                  pBuf->iTRNSred   = 0;
-                  pBuf->iTRNSgreen = 0;
-                  pBuf->iTRNSblue  = 0;
-                  pBuf->iTRNScount = iRawlen;
-                  MNG_COPY (pBuf->aTRNSentries, pRawdata, iRawlen);
-                  break;
-                }
-      }
-
-      pBuf->bHasTRNS = MNG_TRUE;       /* tell it it's got a tRNS now */
-    }
-    else
-#endif
-    {                                  /* address current object */
-      pImage = (mng_imagep)pData->pCurrentobj;
-
-      if (!pImage)                     /* no object then dump it in obj 0 */
-        pImage = (mng_imagep)pData->pObjzero;
-
-      pBuf = pImage->pImgbuf;          /* address object buffer */
-      pBuf->bHasTRNS = MNG_TRUE;       /* and tell it it's got a tRNS now */
-
-      if (iRawlen == 0)                /* if empty, inherit from global */
-      {
-        iRawlen2  = pData->iGlobalTRNSrawlen;
-        pRawdata2 = (mng_ptr)(pData->aGlobalTRNSrawdata);
-                                         /* global length oke ? */
-        if ((pData->iColortype == 0) && (iRawlen2 != 2))
-          MNG_ERROR (pData, MNG_GLOBALLENGTHERR);
-
-        if ((pData->iColortype == 2) && (iRawlen2 != 6))
-          MNG_ERROR (pData, MNG_GLOBALLENGTHERR);
-
-        if ((pData->iColortype == 3) && ((iRawlen2 == 0) || (iRawlen2 > pBuf->iPLTEcount)))
-          MNG_ERROR (pData, MNG_GLOBALLENGTHERR);
-      }
-      else
-      {
-        iRawlen2  = iRawlen;
-        pRawdata2 = pRawdata;
-      }
-
-      switch (pData->iColortype)        /* store fields for future reference */
-      {
-        case 0: {                      /* gray */
-                  pBuf->iTRNSgray  = mng_get_uint16 (pRawdata2);
-                  pBuf->iTRNSred   = 0;
-                  pBuf->iTRNSgreen = 0;
-                  pBuf->iTRNSblue  = 0;
-                  pBuf->iTRNScount = 0;
-#if defined(MNG_NO_16BIT_SUPPORT)
-                  if (pData->iPNGmult == 2)
-                     pBuf->iTRNSgray >>= 8;
-#endif
-                  break;
-                }
-        case 2: {                      /* rgb */
-                  pBuf->iTRNSgray  = 0;
-                  pBuf->iTRNSred   = mng_get_uint16 (pRawdata2);
-                  pBuf->iTRNSgreen = mng_get_uint16 (pRawdata2+2);
-                  pBuf->iTRNSblue  = mng_get_uint16 (pRawdata2+4);
-                  pBuf->iTRNScount = 0;
-#if defined(MNG_NO_16BIT_SUPPORT)
-                  if (pData->iPNGmult == 2)
-                  {
-                     pBuf->iTRNSred   >>= 8;
-                     pBuf->iTRNSgreen >>= 8;
-                     pBuf->iTRNSblue  >>= 8;
-                  }
-#endif
-                  break;
-                }
-        case 3: {                      /* indexed */
-                  pBuf->iTRNSgray  = 0;
-                  pBuf->iTRNSred   = 0;
-                  pBuf->iTRNSgreen = 0;
-                  pBuf->iTRNSblue  = 0;
-                  pBuf->iTRNScount = iRawlen2;
-                  MNG_COPY (pBuf->aTRNSentries, pRawdata2, iRawlen2);
-                  break;
-                }
-      }
-    }  
-  }
-  else                                 /* store as global */
-  {
-    pData->iGlobalTRNSrawlen = iRawlen;
-    MNG_COPY (pData->aGlobalTRNSrawdata, pRawdata, iRawlen);
-
-    {                                  /* create an animation object */
-      mng_retcode iRetcode = mng_create_ani_trns (pData, pData->iGlobalTRNSrawlen,
-                                                  pData->aGlobalTRNSrawdata);
-
-      if (iRetcode)                    /* on error bail out */
-        return iRetcode;
-    }
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-
-    if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-    {                                  /* not global! */
-      ((mng_trnsp)*ppChunk)->bGlobal  = MNG_FALSE;
-      ((mng_trnsp)*ppChunk)->iType    = pData->iColortype;
-
-      if (iRawlen == 0)                /* if empty, indicate so */
-        ((mng_trnsp)*ppChunk)->bEmpty = MNG_TRUE;
-      else
-      {
-        ((mng_trnsp)*ppChunk)->bEmpty = MNG_FALSE;
-
-        switch (pData->iColortype)     /* store fields */
-        {
-          case 0: {                    /* gray */
-                    ((mng_trnsp)*ppChunk)->iGray  = mng_get_uint16 (pRawdata);
-                    break;
-                  }
-          case 2: {                    /* rgb */
-                    ((mng_trnsp)*ppChunk)->iRed   = mng_get_uint16 (pRawdata);
-                    ((mng_trnsp)*ppChunk)->iGreen = mng_get_uint16 (pRawdata+2);
-                    ((mng_trnsp)*ppChunk)->iBlue  = mng_get_uint16 (pRawdata+4);
-                    break;
-                  }
-          case 3: {                    /* indexed */
-                    ((mng_trnsp)*ppChunk)->iCount = iRawlen;
-                    MNG_COPY (((mng_trnsp)*ppChunk)->aEntries, pRawdata, iRawlen);
-                    break;
-                  }
-        }
-      }
-    }
-    else                               /* it's global! */
-    {
-      ((mng_trnsp)*ppChunk)->bEmpty  = (mng_bool)(iRawlen == 0);
-      ((mng_trnsp)*ppChunk)->bGlobal = MNG_TRUE;
-      ((mng_trnsp)*ppChunk)->iType   = 0;
-      ((mng_trnsp)*ppChunk)->iRawlen = iRawlen;
-
-      MNG_COPY (((mng_trnsp)*ppChunk)->aRawdata, pRawdata, iRawlen);
-    }
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_TRNS, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-READ_CHUNK (mng_read_gama)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_GAMA, MNG_LC_START);
-#endif
-                                       /* sequence checks */
-#ifdef MNG_INCLUDE_JNG
-  if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
-      (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
-#else
-  if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
-      (!pData->bHasBASI) && (!pData->bHasDHDR)    )
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIDAT) || (pData->bHasPLTE) || (pData->bHasJDAT) || (pData->bHasJDAA))
-#else
-  if ((pData->bHasIDAT) || (pData->bHasPLTE))
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-  {                                    /* length must be exactly 4 */
-    if (iRawlen != 4)
-      MNG_ERROR (pData, MNG_INVALIDLENGTH);
-  }
-  else
-  {                                    /* length must be empty or exactly 4 */
-    if ((iRawlen != 0) && (iRawlen != 4))
-      MNG_ERROR (pData, MNG_INVALIDLENGTH);
-  }
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-    pData->bHasGAMA = MNG_TRUE;        /* indicate we've got it */
-  else
-    pData->bHasglobalGAMA = (mng_bool)(iRawlen != 0);
-
-#ifdef MNG_SUPPORT_DISPLAY
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-  {
-    mng_imagep pImage;
-
-#ifndef MNG_NO_DELTA_PNG
-    if (pData->bHasDHDR)               /* update delta image ? */
-    {                                  /* store in object 0 ! */
-      pImage = (mng_imagep)pData->pObjzero;
-                                       /* store for color-processing routines */
-      pImage->pImgbuf->iGamma   = mng_get_uint32 (pRawdata);
-      pImage->pImgbuf->bHasGAMA = MNG_TRUE;
-    }
-    else
-#endif
-    {
-      pImage = (mng_imagep)pData->pCurrentobj;
-
-      if (!pImage)                     /* no object then dump it in obj 0 */
-        pImage = (mng_imagep)pData->pObjzero;
-                                       /* store for color-processing routines */
-      pImage->pImgbuf->iGamma   = mng_get_uint32 (pRawdata);
-      pImage->pImgbuf->bHasGAMA = MNG_TRUE;
-    }
-  }
-  else
-  {                                    /* store as global */
-    if (iRawlen != 0)
-      pData->iGlobalGamma = mng_get_uint32 (pRawdata);
-
-    {                                  /* create an animation object */
-      mng_retcode iRetcode = mng_create_ani_gama (pData, (mng_bool)(iRawlen == 0),
-                                                  pData->iGlobalGamma);
-
-      if (iRetcode)                    /* on error bail out */
-        return iRetcode;
-    }
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the fields */
-    ((mng_gamap)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
-
-    if (iRawlen)
-      ((mng_gamap)*ppChunk)->iGamma = mng_get_uint32 (pRawdata);
-
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_GAMA, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifndef MNG_SKIPCHUNK_cHRM
-READ_CHUNK (mng_read_chrm)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_CHRM, MNG_LC_START);
-#endif
-                                       /* sequence checks */
-#ifdef MNG_INCLUDE_JNG
-  if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
-      (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
-#else
-  if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
-      (!pData->bHasBASI) && (!pData->bHasDHDR)    )
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIDAT) || (pData->bHasPLTE) || (pData->bHasJDAT) || (pData->bHasJDAA))
-#else
-  if ((pData->bHasIDAT) || (pData->bHasPLTE))
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-  {                                    /* length must be exactly 32 */
-    if (iRawlen != 32)
-      MNG_ERROR (pData, MNG_INVALIDLENGTH);
-  }
-  else
-  {                                    /* length must be empty or exactly 32 */
-    if ((iRawlen != 0) && (iRawlen != 32))
-      MNG_ERROR (pData, MNG_INVALIDLENGTH);
-  }
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-    pData->bHasCHRM = MNG_TRUE;        /* indicate we've got it */
-  else
-    pData->bHasglobalCHRM = (mng_bool)(iRawlen != 0);
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-    mng_uint32 iWhitepointx,   iWhitepointy;
-    mng_uint32 iPrimaryredx,   iPrimaryredy;
-    mng_uint32 iPrimarygreenx, iPrimarygreeny;
-    mng_uint32 iPrimarybluex,  iPrimarybluey;
-
-    iWhitepointx   = mng_get_uint32 (pRawdata);
-    iWhitepointy   = mng_get_uint32 (pRawdata+4);
-    iPrimaryredx   = mng_get_uint32 (pRawdata+8);
-    iPrimaryredy   = mng_get_uint32 (pRawdata+12);
-    iPrimarygreenx = mng_get_uint32 (pRawdata+16);
-    iPrimarygreeny = mng_get_uint32 (pRawdata+20);
-    iPrimarybluex  = mng_get_uint32 (pRawdata+24);
-    iPrimarybluey  = mng_get_uint32 (pRawdata+28);
-
-#ifdef MNG_INCLUDE_JNG
-    if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-    if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-    {
-      mng_imagep     pImage;
-      mng_imagedatap pBuf;
-
-#ifndef MNG_NO_DELTA_PNG
-      if (pData->bHasDHDR)             /* update delta image ? */
-      {                                /* store it in object 0 ! */
-        pImage = (mng_imagep)pData->pObjzero;
-
-        pBuf = pImage->pImgbuf;        /* address object buffer */
-        pBuf->bHasCHRM = MNG_TRUE;     /* and tell it it's got a CHRM now */
-                                       /* store for color-processing routines */
-        pBuf->iWhitepointx   = iWhitepointx;
-        pBuf->iWhitepointy   = iWhitepointy;
-        pBuf->iPrimaryredx   = iPrimaryredx;
-        pBuf->iPrimaryredy   = iPrimaryredy;
-        pBuf->iPrimarygreenx = iPrimarygreenx;
-        pBuf->iPrimarygreeny = iPrimarygreeny;
-        pBuf->iPrimarybluex  = iPrimarybluex;
-        pBuf->iPrimarybluey  = iPrimarybluey;
-      }
-      else
-#endif
-      {
-        pImage = (mng_imagep)pData->pCurrentobj;
-
-        if (!pImage)                   /* no object then dump it in obj 0 */
-          pImage = (mng_imagep)pData->pObjzero;
-
-        pBuf = pImage->pImgbuf;        /* address object buffer */
-        pBuf->bHasCHRM = MNG_TRUE;     /* and tell it it's got a CHRM now */
-                                       /* store for color-processing routines */
-        pBuf->iWhitepointx   = iWhitepointx;
-        pBuf->iWhitepointy   = iWhitepointy;
-        pBuf->iPrimaryredx   = iPrimaryredx;
-        pBuf->iPrimaryredy   = iPrimaryredy;
-        pBuf->iPrimarygreenx = iPrimarygreenx;
-        pBuf->iPrimarygreeny = iPrimarygreeny;
-        pBuf->iPrimarybluex  = iPrimarybluex;
-        pBuf->iPrimarybluey  = iPrimarybluey;
-      }
-    }
-    else
-    {                                  /* store as global */
-      if (iRawlen != 0)
-      {
-        pData->iGlobalWhitepointx   = iWhitepointx;
-        pData->iGlobalWhitepointy   = iWhitepointy;
-        pData->iGlobalPrimaryredx   = iPrimaryredx;
-        pData->iGlobalPrimaryredy   = iPrimaryredy;
-        pData->iGlobalPrimarygreenx = iPrimarygreenx;
-        pData->iGlobalPrimarygreeny = iPrimarygreeny;
-        pData->iGlobalPrimarybluex  = iPrimarybluex;
-        pData->iGlobalPrimarybluey  = iPrimarybluey;
-      }
-
-      {                                /* create an animation object */
-        mng_retcode iRetcode = mng_create_ani_chrm (pData, (mng_bool)(iRawlen == 0),
-                                                    iWhitepointx,   iWhitepointy,
-                                                    iPrimaryredx,   iPrimaryredy,
-                                                    iPrimarygreenx, iPrimarygreeny,
-                                                    iPrimarybluex,  iPrimarybluey);
-
-        if (iRetcode)                  /* on error bail out */
-          return iRetcode;
-      }
-    }
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the fields */
-    ((mng_chrmp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
-
-    if (iRawlen)
-    {
-      ((mng_chrmp)*ppChunk)->iWhitepointx = mng_get_uint32 (pRawdata);
-      ((mng_chrmp)*ppChunk)->iWhitepointy = mng_get_uint32 (pRawdata+4);
-      ((mng_chrmp)*ppChunk)->iRedx        = mng_get_uint32 (pRawdata+8);
-      ((mng_chrmp)*ppChunk)->iRedy        = mng_get_uint32 (pRawdata+12);
-      ((mng_chrmp)*ppChunk)->iGreenx      = mng_get_uint32 (pRawdata+16);
-      ((mng_chrmp)*ppChunk)->iGreeny      = mng_get_uint32 (pRawdata+20);
-      ((mng_chrmp)*ppChunk)->iBluex       = mng_get_uint32 (pRawdata+24);
-      ((mng_chrmp)*ppChunk)->iBluey       = mng_get_uint32 (pRawdata+28);
-    }
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_CHRM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-READ_CHUNK (mng_read_srgb)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_SRGB, MNG_LC_START);
-#endif
-                                       /* sequence checks */
-#ifdef MNG_INCLUDE_JNG
-  if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
-      (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
-#else
-  if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
-      (!pData->bHasBASI) && (!pData->bHasDHDR)    )
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIDAT) || (pData->bHasPLTE) || (pData->bHasJDAT) || (pData->bHasJDAA))
-#else
-  if ((pData->bHasIDAT) || (pData->bHasPLTE))
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-  {                                    /* length must be exactly 1 */
-    if (iRawlen != 1)
-      MNG_ERROR (pData, MNG_INVALIDLENGTH);
-  }
-  else
-  {                                    /* length must be empty or exactly 1 */
-    if ((iRawlen != 0) && (iRawlen != 1))
-      MNG_ERROR (pData, MNG_INVALIDLENGTH);
-  }
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-    pData->bHasSRGB = MNG_TRUE;        /* indicate we've got it */
-  else
-    pData->bHasglobalSRGB = (mng_bool)(iRawlen != 0);
-
-#ifdef MNG_SUPPORT_DISPLAY
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-  {
-    mng_imagep pImage;
-
-#ifndef MNG_NO_DELTA_PNG
-    if (pData->bHasDHDR)               /* update delta image ? */
-    {                                  /* store in object 0 ! */
-      pImage = (mng_imagep)pData->pObjzero;
-                                       /* store for color-processing routines */
-      pImage->pImgbuf->iRenderingintent = *pRawdata;
-      pImage->pImgbuf->bHasSRGB         = MNG_TRUE;
-    }
-    else
-#endif
-    {
-      pImage = (mng_imagep)pData->pCurrentobj;
-
-      if (!pImage)                     /* no object then dump it in obj 0 */
-        pImage = (mng_imagep)pData->pObjzero;
-                                       /* store for color-processing routines */
-      pImage->pImgbuf->iRenderingintent = *pRawdata;
-      pImage->pImgbuf->bHasSRGB         = MNG_TRUE;
-    }
-  }
-  else
-  {                                    /* store as global */
-    if (iRawlen != 0)
-      pData->iGlobalRendintent = *pRawdata;
-
-    {                                  /* create an animation object */
-      mng_retcode iRetcode = mng_create_ani_srgb (pData, (mng_bool)(iRawlen == 0),
-                                                  pData->iGlobalRendintent);
-
-      if (iRetcode)                    /* on error bail out */
-        return iRetcode;
-    }
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the fields */
-    ((mng_srgbp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
-
-    if (iRawlen)
-      ((mng_srgbp)*ppChunk)->iRenderingintent = *pRawdata;
-
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_SRGB, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifndef MNG_SKIPCHUNK_iCCP
-READ_CHUNK (mng_read_iccp)
-{
-  mng_retcode iRetcode;
-  mng_uint8p  pTemp;
-  mng_uint32  iCompressedsize;
-  mng_uint32  iProfilesize;
-  mng_uint32  iBufsize = 0;
-  mng_uint8p  pBuf = 0;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_ICCP, MNG_LC_START);
-#endif
-                                       /* sequence checks */
-#ifdef MNG_INCLUDE_JNG
-  if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
-      (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
-#else
-  if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
-      (!pData->bHasBASI) && (!pData->bHasDHDR)    )
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIDAT) || (pData->bHasPLTE) || (pData->bHasJDAT) || (pData->bHasJDAA))
-#else
-  if ((pData->bHasIDAT) || (pData->bHasPLTE))
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-  {                                    /* length must be at least 2 */
-    if (iRawlen < 2)
-      MNG_ERROR (pData, MNG_INVALIDLENGTH);
-  }
-  else
-  {                                    /* length must be empty or at least 2 */
-    if ((iRawlen != 0) && (iRawlen < 2))
-      MNG_ERROR (pData, MNG_INVALIDLENGTH);
-  }
-
-  pTemp = find_null (pRawdata);        /* find null-separator */
-                                       /* not found inside input-data ? */
-  if ((pTemp - pRawdata) > (mng_int32)iRawlen)
-    MNG_ERROR (pData, MNG_NULLNOTFOUND);
-                                       /* determine size of compressed profile */
-  iCompressedsize = (mng_uint32)(iRawlen - (pTemp - pRawdata) - 2);
-                                       /* decompress the profile */
-  iRetcode = mng_inflate_buffer (pData, pTemp+2, iCompressedsize,
-                                 &pBuf, &iBufsize, &iProfilesize);
-
-#ifdef MNG_CHECK_BAD_ICCP              /* Check for bad iCCP chunk */
-  if ((iRetcode) && (!strncmp ((char *)pRawdata, "Photoshop ICC profile", 21)))
-  {
-    if (iRawlen == 2615)               /* is it the sRGB profile ? */
-    {
-      mng_chunk_header chunk_srgb =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-        {MNG_UINT_sRGB, mng_init_general, mng_free_general, mng_read_srgb, mng_write_srgb, mng_assign_general, 0, 0, sizeof(mng_srgb)};
-#else
-        {MNG_UINT_sRGB, mng_init_srgb, mng_free_srgb, mng_read_srgb, mng_write_srgb, mng_assign_srgb, 0, 0};
-#endif
-                                       /* pretend it's an sRGB chunk then ! */
-      iRetcode = mng_read_srgb (pData, &chunk_srgb, 1, (mng_ptr)"0", ppChunk);
-
-      if (iRetcode)                    /* on error bail out */
-      {                                /* don't forget to drop the temp buffer */
-        MNG_FREEX (pData, pBuf, iBufsize);
-        return iRetcode;
-      }
-    }
-  }
-  else
-  {
-#endif /* MNG_CHECK_BAD_ICCP */
-
-    if (iRetcode)                      /* on error bail out */
-    {                                  /* don't forget to drop the temp buffer */
-      MNG_FREEX (pData, pBuf, iBufsize);
-      return iRetcode;
-    }
-
-#ifdef MNG_INCLUDE_JNG
-    if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-    if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-      pData->bHasICCP = MNG_TRUE;      /* indicate we've got it */
-    else
-      pData->bHasglobalICCP = (mng_bool)(iRawlen != 0);
-
-#ifdef MNG_SUPPORT_DISPLAY
-#ifdef MNG_INCLUDE_JNG
-    if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-    if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-    {
-      mng_imagep pImage;
-
-#ifndef MNG_NO_DELTA_PNG
-      if (pData->bHasDHDR)             /* update delta image ? */
-      {                                /* store in object 0 ! */
-        pImage = (mng_imagep)pData->pObjzero;
-
-        if (pImage->pImgbuf->pProfile) /* profile existed ? */
-          MNG_FREEX (pData, pImage->pImgbuf->pProfile, pImage->pImgbuf->iProfilesize);
-                                       /* allocate a buffer & copy it */
-        MNG_ALLOC (pData, pImage->pImgbuf->pProfile, iProfilesize);
-        MNG_COPY  (pImage->pImgbuf->pProfile, pBuf, iProfilesize);
-                                       /* store its length as well */
-        pImage->pImgbuf->iProfilesize = iProfilesize;
-        pImage->pImgbuf->bHasICCP     = MNG_TRUE;
-      }
-      else
-#endif
-      {
-        pImage = (mng_imagep)pData->pCurrentobj;
-
-        if (!pImage)                   /* no object then dump it in obj 0 */
-          pImage = (mng_imagep)pData->pObjzero;
-
-        if (pImage->pImgbuf->pProfile) /* profile existed ? */
-          MNG_FREEX (pData, pImage->pImgbuf->pProfile, pImage->pImgbuf->iProfilesize);
-                                       /* allocate a buffer & copy it */
-        MNG_ALLOC (pData, pImage->pImgbuf->pProfile, iProfilesize);
-        MNG_COPY  (pImage->pImgbuf->pProfile, pBuf, iProfilesize);
-                                       /* store its length as well */
-        pImage->pImgbuf->iProfilesize = iProfilesize;
-        pImage->pImgbuf->bHasICCP     = MNG_TRUE;
-      }
-    }
-    else
-    {                                  /* store as global */
-      if (iRawlen == 0)                /* empty chunk ? */
-      {
-        if (pData->pGlobalProfile)     /* did we have a global profile ? */
-          MNG_FREEX (pData, pData->pGlobalProfile, pData->iGlobalProfilesize);
-
-        pData->iGlobalProfilesize = 0; /* reset to null */
-        pData->pGlobalProfile     = MNG_NULL;
-      }
-      else
-      {                                /* allocate a global buffer & copy it */
-        MNG_ALLOC (pData, pData->pGlobalProfile, iProfilesize);
-        MNG_COPY  (pData->pGlobalProfile, pBuf, iProfilesize);
-                                       /* store its length as well */
-        pData->iGlobalProfilesize = iProfilesize;
-      }
-
-                                       /* create an animation object */
-      iRetcode = mng_create_ani_iccp (pData, (mng_bool)(iRawlen == 0),
-                                      pData->iGlobalProfilesize,
-                                      pData->pGlobalProfile);
-
-      if (iRetcode)                    /* on error bail out */
-        return iRetcode;
-    }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-    if (pData->bStorechunks)
-    {                                  /* initialize storage */
-      iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-      if (iRetcode)                    /* on error bail out */
-      {                                /* don't forget to drop the temp buffer */
-        MNG_FREEX (pData, pBuf, iBufsize);
-        return iRetcode;
-      }
-                                       /* store the fields */
-      ((mng_iccpp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
-
-      if (iRawlen)                     /* not empty ? */
-      {
-        if (!pBuf)                     /* hasn't been unpuzzled it yet ? */
-        {                              /* find null-separator */
-          pTemp = find_null (pRawdata);
-                                       /* not found inside input-data ? */
-          if ((pTemp - pRawdata) > (mng_int32)iRawlen)
-            MNG_ERROR (pData, MNG_NULLNOTFOUND);
-                                       /* determine size of compressed profile */
-          iCompressedsize = iRawlen - (pTemp - pRawdata) - 2;
-                                       /* decompress the profile */
-          iRetcode = mng_inflate_buffer (pData, pTemp+2, iCompressedsize,
-                                         &pBuf, &iBufsize, &iProfilesize);
-
-          if (iRetcode)                /* on error bail out */
-          {                            /* don't forget to drop the temp buffer */
-            MNG_FREEX (pData, pBuf, iBufsize);
-            return iRetcode;
-          }
-        }
-
-        ((mng_iccpp)*ppChunk)->iNamesize = (mng_uint32)(pTemp - pRawdata);
-
-        if (((mng_iccpp)*ppChunk)->iNamesize)
-        {
-          MNG_ALLOC (pData, ((mng_iccpp)*ppChunk)->zName,
-                            ((mng_iccpp)*ppChunk)->iNamesize + 1);
-          MNG_COPY  (((mng_iccpp)*ppChunk)->zName, pRawdata,
-                     ((mng_iccpp)*ppChunk)->iNamesize);
-        }
-
-        ((mng_iccpp)*ppChunk)->iCompression = *(pTemp+1);
-        ((mng_iccpp)*ppChunk)->iProfilesize = iProfilesize;
-
-        MNG_ALLOC (pData, ((mng_iccpp)*ppChunk)->pProfile, iProfilesize);
-        MNG_COPY  (((mng_iccpp)*ppChunk)->pProfile, pBuf, iProfilesize);
-      }
-    }
-#endif /* MNG_STORE_CHUNKS */
-
-    if (pBuf)                          /* free the temporary buffer */
-      MNG_FREEX (pData, pBuf, iBufsize);
-
-#ifdef MNG_CHECK_BAD_ICCP
-  }
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_ICCP, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifndef MNG_SKIPCHUNK_tEXt
-READ_CHUNK (mng_read_text)
-{
-  mng_uint32 iKeywordlen, iTextlen;
-  mng_pchar  zKeyword, zText;
-  mng_uint8p pTemp;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_TEXT, MNG_LC_START);
-#endif
-                                       /* sequence checks */
-#ifdef MNG_INCLUDE_JNG
-  if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
-      (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
-#else
-  if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
-      (!pData->bHasBASI) && (!pData->bHasDHDR)    )
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-  if (iRawlen < 2)                     /* length must be at least 2 */
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-  pTemp = find_null (pRawdata);        /* find the null separator */
-                                       /* not found inside input-data ? */
-  if ((pTemp - pRawdata) > (mng_int32)iRawlen)
-    MNG_ERROR (pData, MNG_NULLNOTFOUND);
-
-  if (pTemp == pRawdata)               /* there must be at least 1 char for keyword */
-    MNG_ERROR (pData, MNG_KEYWORDNULL);
-
-  iKeywordlen = (mng_uint32)(pTemp - pRawdata);
-  iTextlen    = iRawlen - iKeywordlen - 1;
-
-  if (pData->fProcesstext)             /* inform the application ? */
-  {
-    mng_bool bOke;
-
-    MNG_ALLOC (pData, zKeyword, iKeywordlen + 1);
-    MNG_COPY  (zKeyword, pRawdata, iKeywordlen);
-
-    MNG_ALLOCX (pData, zText, iTextlen + 1);
-
-    if (!zText)                        /* on error bail out */
-    {
-      MNG_FREEX (pData, zKeyword, iKeywordlen + 1);
-      MNG_ERROR (pData, MNG_OUTOFMEMORY);
-    }
-
-    if (iTextlen)
-      MNG_COPY (zText, pTemp+1, iTextlen);
-
-    bOke = pData->fProcesstext ((mng_handle)pData, MNG_TYPE_TEXT, zKeyword, zText, 0, 0);
-
-    MNG_FREEX (pData, zText, iTextlen + 1);
-    MNG_FREEX (pData, zKeyword, iKeywordlen + 1);
-
-    if (!bOke)
-      MNG_ERROR (pData, MNG_APPMISCERROR);
-
-  }
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the fields */
-    ((mng_textp)*ppChunk)->iKeywordsize = iKeywordlen;
-    ((mng_textp)*ppChunk)->iTextsize    = iTextlen;
-
-    if (iKeywordlen)
-    {
-      MNG_ALLOC (pData, ((mng_textp)*ppChunk)->zKeyword, iKeywordlen+1);
-      MNG_COPY  (((mng_textp)*ppChunk)->zKeyword, pRawdata, iKeywordlen);
-    }
-
-    if (iTextlen)
-    {
-      MNG_ALLOC (pData, ((mng_textp)*ppChunk)->zText, iTextlen+1);
-      MNG_COPY  (((mng_textp)*ppChunk)->zText, pTemp+1, iTextlen);
-    }
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_TEXT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifndef MNG_SKIPCHUNK_zTXt
-READ_CHUNK (mng_read_ztxt)
-{
-  mng_retcode iRetcode;
-  mng_uint32  iKeywordlen, iTextlen;
-  mng_pchar   zKeyword;
-  mng_uint8p  pTemp;
-  mng_uint32  iCompressedsize;
-  mng_uint32  iBufsize;
-  mng_uint8p  pBuf;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_ZTXT, MNG_LC_START);
-#endif
-                                       /* sequence checks */
-#ifdef MNG_INCLUDE_JNG
-  if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
-      (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
-#else
-  if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
-      (!pData->bHasBASI) && (!pData->bHasDHDR)    )
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-  if (iRawlen < 3)                     /* length must be at least 3 */
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-  pTemp = find_null (pRawdata);        /* find the null separator */
-                                       /* not found inside input-data ? */
-  if ((pTemp - pRawdata) > (mng_int32)iRawlen)
-    MNG_ERROR (pData, MNG_NULLNOTFOUND);
-
-  if (pTemp == pRawdata)               /* there must be at least 1 char for keyword */
-    MNG_ERROR (pData, MNG_KEYWORDNULL);
-
-  if (*(pTemp+1) != 0)                 /* only deflate compression-method allowed */
-    MNG_ERROR (pData, MNG_INVALIDCOMPRESS);
-
-  iKeywordlen     = (mng_uint32)(pTemp - pRawdata);
-  iCompressedsize = (mng_uint32)(iRawlen - iKeywordlen - 2);
-
-  zKeyword        = 0;                 /* there's no keyword buffer yet */
-  pBuf            = 0;                 /* or a temporary buffer ! */
-
-  if (pData->fProcesstext)             /* inform the application ? */
-  {                                    /* decompress the text */
-    iRetcode = mng_inflate_buffer (pData, pTemp+2, iCompressedsize,
-                                   &pBuf, &iBufsize, &iTextlen);
-
-    if (iRetcode)                      /* on error bail out */
-    {                                  /* don't forget to drop the temp buffers */
-      MNG_FREEX (pData, pBuf, iBufsize);
-      return iRetcode;
-    }
-
-    MNG_ALLOCX (pData, zKeyword, iKeywordlen+1);
-
-    if (!zKeyword)                     /* on error bail out */
-    {                                  /* don't forget to drop the temp buffers */
-      MNG_FREEX (pData, pBuf, iBufsize);
-      MNG_ERROR (pData, MNG_OUTOFMEMORY);
-    }
-
-    MNG_COPY (zKeyword, pRawdata, iKeywordlen);
-
-    if (!pData->fProcesstext ((mng_handle)pData, MNG_TYPE_ZTXT, zKeyword, (mng_pchar)pBuf, 0, 0))
-    {                                  /* don't forget to drop the temp buffers */
-      MNG_FREEX (pData, pBuf, iBufsize);
-      MNG_FREEX (pData, zKeyword, iKeywordlen+1);
-      MNG_ERROR (pData, MNG_APPMISCERROR);
-    }
-  }
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-    {                                  /* don't forget to drop the temp buffers */
-      MNG_FREEX (pData, pBuf, iBufsize);
-      MNG_FREEX (pData, zKeyword, iKeywordlen+1);
-      return iRetcode;
-    }
-                                       /* store the fields */
-    ((mng_ztxtp)*ppChunk)->iKeywordsize = iKeywordlen;
-    ((mng_ztxtp)*ppChunk)->iCompression = *(pTemp+1);
-
-    if ((!pBuf) && (iCompressedsize))  /* did we not get a text-buffer yet ? */
-    {                                  /* decompress the text */
-      iRetcode = mng_inflate_buffer (pData, pTemp+2, iCompressedsize,
-                                     &pBuf, &iBufsize, &iTextlen);
-
-      if (iRetcode)                    /* on error bail out */
-      {                                /* don't forget to drop the temp buffers */
-        MNG_FREEX (pData, pBuf, iBufsize);
-        MNG_FREEX (pData, zKeyword, iKeywordlen+1);
-        return iRetcode;
-      }
-    }
-
-    MNG_ALLOCX (pData, ((mng_ztxtp)*ppChunk)->zKeyword, iKeywordlen + 1);
-                                       /* on error bail out */
-    if (!((mng_ztxtp)*ppChunk)->zKeyword)
-    {                                  /* don't forget to drop the temp buffers */
-      MNG_FREEX (pData, pBuf, iBufsize);
-      MNG_FREEX (pData, zKeyword, iKeywordlen+1);
-      MNG_ERROR (pData, MNG_OUTOFMEMORY);
-    }
-
-    MNG_COPY (((mng_ztxtp)*ppChunk)->zKeyword, pRawdata, iKeywordlen);
-
-    ((mng_ztxtp)*ppChunk)->iTextsize = iTextlen;
-
-    if (iCompressedsize)
-    {
-      MNG_ALLOCX (pData, ((mng_ztxtp)*ppChunk)->zText, iTextlen + 1);
-                                       /* on error bail out */
-      if (!((mng_ztxtp)*ppChunk)->zText)
-      {                                /* don't forget to drop the temp buffers */
-        MNG_FREEX (pData, pBuf, iBufsize);
-        MNG_FREEX (pData, zKeyword, iKeywordlen+1);
-        MNG_ERROR (pData, MNG_OUTOFMEMORY);
-      }
-
-      MNG_COPY (((mng_ztxtp)*ppChunk)->zText, pBuf, iTextlen);
-    }
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-  MNG_FREEX (pData, pBuf, iBufsize);   /* free the temporary buffers */
-  MNG_FREEX (pData, zKeyword, iKeywordlen+1);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_ZTXT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifndef MNG_SKIPCHUNK_iTXt
-READ_CHUNK (mng_read_itxt)
-{
-  mng_retcode iRetcode;
-  mng_uint32  iKeywordlen, iTextlen, iLanguagelen, iTranslationlen;
-  mng_pchar   zKeyword, zLanguage, zTranslation;
-  mng_uint8p  pNull1, pNull2, pNull3;
-  mng_uint32  iCompressedsize;
-  mng_uint8   iCompressionflag;
-  mng_uint32  iBufsize;
-  mng_uint8p  pBuf;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_ITXT, MNG_LC_START);
-#endif
-                                       /* sequence checks */
-#ifdef MNG_INCLUDE_JNG
-  if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
-      (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
-#else
-  if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
-      (!pData->bHasBASI) && (!pData->bHasDHDR)    )
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-  if (iRawlen < 6)                     /* length must be at least 6 */
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-  pNull1 = find_null (pRawdata);       /* find the null separators */
-  pNull2 = find_null (pNull1+3);
-  pNull3 = find_null (pNull2+1);
-                                       /* not found inside input-data ? */
-  if (((pNull1 - pRawdata) > (mng_int32)iRawlen) ||
-      ((pNull2 - pRawdata) > (mng_int32)iRawlen) ||
-      ((pNull3 - pRawdata) > (mng_int32)iRawlen)    )
-    MNG_ERROR (pData, MNG_NULLNOTFOUND);
-
-  if (pNull1 == pRawdata)              /* there must be at least 1 char for keyword */
-    MNG_ERROR (pData, MNG_KEYWORDNULL);
-                                       /* compression or not ? */
-  if ((*(pNull1+1) != 0) && (*(pNull1+1) != 1))
-    MNG_ERROR (pData, MNG_INVALIDCOMPRESS);
-
-  if (*(pNull1+2) != 0)                /* only deflate compression-method allowed */
-    MNG_ERROR (pData, MNG_INVALIDCOMPRESS);
-
-  iKeywordlen      = (mng_uint32)(pNull1 - pRawdata);
-  iLanguagelen     = (mng_uint32)(pNull2 - pNull1 - 3);
-  iTranslationlen  = (mng_uint32)(pNull3 - pNull2 - 1);
-  iCompressedsize  = (mng_uint32)(iRawlen - iKeywordlen - iLanguagelen - iTranslationlen - 5);
-  iCompressionflag = *(pNull1+1);
-
-  zKeyword     = 0;                    /* no buffers acquired yet */
-  zLanguage    = 0;
-  zTranslation = 0;
-  pBuf         = 0;
-  iTextlen     = 0;
-
-  if (pData->fProcesstext)             /* inform the application ? */
-  {
-    if (iCompressionflag)              /* decompress the text ? */
-    {
-      iRetcode = mng_inflate_buffer (pData, pNull3+1, iCompressedsize,
-                                     &pBuf, &iBufsize, &iTextlen);
-
-      if (iRetcode)                    /* on error bail out */
-      {                                /* don't forget to drop the temp buffer */
-        MNG_FREEX (pData, pBuf, iBufsize);
-        return iRetcode;
-      }
-    }
-    else
-    {
-      iTextlen = iCompressedsize;
-      iBufsize = iTextlen+1;           /* plus 1 for terminator byte!!! */
-
-      MNG_ALLOC (pData, pBuf, iBufsize);
-      MNG_COPY  (pBuf, pNull3+1, iTextlen);
-    }
-
-    MNG_ALLOCX (pData, zKeyword,     iKeywordlen     + 1);
-    MNG_ALLOCX (pData, zLanguage,    iLanguagelen    + 1);
-    MNG_ALLOCX (pData, zTranslation, iTranslationlen + 1);
-                                       /* on error bail out */
-    if ((!zKeyword) || (!zLanguage) || (!zTranslation))
-    {                                  /* don't forget to drop the temp buffers */
-      MNG_FREEX (pData, zTranslation, iTranslationlen + 1);
-      MNG_FREEX (pData, zLanguage,    iLanguagelen    + 1);
-      MNG_FREEX (pData, zKeyword,     iKeywordlen     + 1);
-      MNG_FREEX (pData, pBuf, iBufsize);
-      MNG_ERROR (pData, MNG_OUTOFMEMORY);
-    }
-
-    MNG_COPY (zKeyword,     pRawdata, iKeywordlen);
-    MNG_COPY (zLanguage,    pNull1+3, iLanguagelen);
-    MNG_COPY (zTranslation, pNull2+1, iTranslationlen);
-
-    if (!pData->fProcesstext ((mng_handle)pData, MNG_TYPE_ITXT, zKeyword, (mng_pchar)pBuf,
-                                                                zLanguage, zTranslation))
-    {                                  /* don't forget to drop the temp buffers */
-      MNG_FREEX (pData, zTranslation, iTranslationlen + 1);
-      MNG_FREEX (pData, zLanguage,    iLanguagelen    + 1);
-      MNG_FREEX (pData, zKeyword,     iKeywordlen     + 1);
-      MNG_FREEX (pData, pBuf,         iBufsize);
-
-      MNG_ERROR (pData, MNG_APPMISCERROR);
-    }
-  }
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-    {                                  /* don't forget to drop the temp buffers */
-      MNG_FREEX (pData, zTranslation, iTranslationlen + 1);
-      MNG_FREEX (pData, zLanguage,    iLanguagelen    + 1);
-      MNG_FREEX (pData, zKeyword,     iKeywordlen     + 1);
-      MNG_FREEX (pData, pBuf,         iBufsize);
-      return iRetcode;
-    }
-                                       /* store the fields */
-    ((mng_itxtp)*ppChunk)->iKeywordsize       = iKeywordlen;
-    ((mng_itxtp)*ppChunk)->iLanguagesize      = iLanguagelen;
-    ((mng_itxtp)*ppChunk)->iTranslationsize   = iTranslationlen;
-    ((mng_itxtp)*ppChunk)->iCompressionflag   = *(pNull1+1);
-    ((mng_itxtp)*ppChunk)->iCompressionmethod = *(pNull1+2);
-
-    if ((!pBuf) && (iCompressedsize))  /* did we not get a text-buffer yet ? */
-    {
-      if (iCompressionflag)            /* decompress the text ? */
-      {
-        iRetcode = mng_inflate_buffer (pData, pNull3+1, iCompressedsize,
-                                       &pBuf, &iBufsize, &iTextlen);
-
-        if (iRetcode)                  /* on error bail out */
-        {                              /* don't forget to drop the temp buffers */
-          MNG_FREEX (pData, zTranslation, iTranslationlen + 1);
-          MNG_FREEX (pData, zLanguage,    iLanguagelen    + 1);
-          MNG_FREEX (pData, zKeyword,     iKeywordlen     + 1);
-          MNG_FREEX (pData, pBuf,         iBufsize);
-          return iRetcode;
-        }
-      }
-      else
-      {
-        iTextlen = iCompressedsize;
-        iBufsize = iTextlen+1;         /* plus 1 for terminator byte!!! */
-
-        MNG_ALLOC (pData, pBuf, iBufsize);
-        MNG_COPY  (pBuf, pNull3+1, iTextlen);
-      }
-    }
-
-    MNG_ALLOCX (pData, ((mng_itxtp)*ppChunk)->zKeyword,     iKeywordlen     + 1);
-    MNG_ALLOCX (pData, ((mng_itxtp)*ppChunk)->zLanguage,    iLanguagelen    + 1);
-    MNG_ALLOCX (pData, ((mng_itxtp)*ppChunk)->zTranslation, iTranslationlen + 1);
-                                       /* on error bail out */
-    if ((!((mng_itxtp)*ppChunk)->zKeyword    ) ||
-        (!((mng_itxtp)*ppChunk)->zLanguage   ) ||
-        (!((mng_itxtp)*ppChunk)->zTranslation)    )
-    {                                  /* don't forget to drop the temp buffers */
-      MNG_FREEX (pData, zTranslation, iTranslationlen + 1);
-      MNG_FREEX (pData, zLanguage,    iLanguagelen    + 1);
-      MNG_FREEX (pData, zKeyword,     iKeywordlen     + 1);
-      MNG_FREEX (pData, pBuf,         iBufsize);
-      MNG_ERROR (pData, MNG_OUTOFMEMORY);
-    }
-
-    MNG_COPY (((mng_itxtp)*ppChunk)->zKeyword,     pRawdata, iKeywordlen);
-    MNG_COPY (((mng_itxtp)*ppChunk)->zLanguage,    pNull1+3, iLanguagelen);
-    MNG_COPY (((mng_itxtp)*ppChunk)->zTranslation, pNull2+1, iTranslationlen);
-
-    ((mng_itxtp)*ppChunk)->iTextsize = iTextlen;
-
-    if (iTextlen)
-    {
-      MNG_ALLOCX (pData, ((mng_itxtp)*ppChunk)->zText, iTextlen + 1);
-
-      if (!((mng_itxtp)*ppChunk)->zText)
-      {                                /* don't forget to drop the temp buffers */
-        MNG_FREEX (pData, zTranslation, iTranslationlen + 1);
-        MNG_FREEX (pData, zLanguage,    iLanguagelen    + 1);
-        MNG_FREEX (pData, zKeyword,     iKeywordlen     + 1);
-        MNG_FREEX (pData, pBuf,         iBufsize);
-        MNG_ERROR (pData, MNG_OUTOFMEMORY);
-      }
-
-      MNG_COPY  (((mng_itxtp)*ppChunk)->zText, pBuf, iTextlen);
-    }
-  }
-#endif /* MNG_STORE_CHUNKS */
-                                       /* free the temporary buffers */
-  MNG_FREEX (pData, zTranslation, iTranslationlen + 1);
-  MNG_FREEX (pData, zLanguage,    iLanguagelen    + 1);
-  MNG_FREEX (pData, zKeyword,     iKeywordlen     + 1);
-  MNG_FREEX (pData, pBuf,         iBufsize);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_ITXT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifndef MNG_SKIPCHUNK_bKGD
-READ_CHUNK (mng_read_bkgd)
-{
-#ifdef MNG_SUPPORT_DISPLAY
-  mng_imagep     pImage = (mng_imagep)pData->pCurrentobj;
-  mng_imagedatap pBuf;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_BKGD, MNG_LC_START);
-#endif
-                                       /* sequence checks */
-#ifdef MNG_INCLUDE_JNG
-  if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
-      (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
-#else
-  if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
-      (!pData->bHasBASI) && (!pData->bHasDHDR)    )
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIDAT) || (pData->bHasJDAT) || (pData->bHasJDAA))
-#else
-  if (pData->bHasIDAT)
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-  if (iRawlen > 6)                     /* it just can't be bigger than that! */
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-#ifdef MNG_INCLUDE_JNG                 /* length checks */
-  if (pData->bHasJHDR)
-  {
-    if (((pData->iJHDRcolortype == 8) || (pData->iJHDRcolortype == 12)) && (iRawlen != 2))
-      MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-    if (((pData->iJHDRcolortype == 10) || (pData->iJHDRcolortype == 14)) && (iRawlen != 6))
-      MNG_ERROR (pData, MNG_INVALIDLENGTH);
-  }
-  else
-#endif /* MNG_INCLUDE_JNG */
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-  {
-    if (((pData->iColortype == 0) || (pData->iColortype == 4)) && (iRawlen != 2))
-      MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-    if (((pData->iColortype == 2) || (pData->iColortype == 6)) && (iRawlen != 6))
-      MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-    if ((pData->iColortype == 3) && (iRawlen != 1))
-      MNG_ERROR (pData, MNG_INVALIDLENGTH);
-  }
-  else
-  {
-    if (iRawlen != 6)                  /* global is always 16-bit RGB ! */
-      MNG_ERROR (pData, MNG_INVALIDLENGTH);
-  }
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-    pData->bHasBKGD = MNG_TRUE;        /* indicate bKGD available */
-  else
-    pData->bHasglobalBKGD = (mng_bool)(iRawlen != 0);
-
-#ifdef MNG_SUPPORT_DISPLAY
-  if (!pImage)                         /* if no object dump it in obj 0 */
-    pImage = (mng_imagep)pData->pObjzero;
-
-  pBuf = pImage->pImgbuf;              /* address object buffer */
-
-#ifdef MNG_INCLUDE_JNG
-  if (pData->bHasJHDR)
-  {
-    pBuf->bHasBKGD = MNG_TRUE;         /* tell the object it's got bKGD now */
-
-    switch (pData->iJHDRcolortype)     /* store fields for future reference */
-    {
-      case  8 : ;                      /* gray */
-      case 12 : {                      /* graya */
-                  pBuf->iBKGDgray  = mng_get_uint16 (pRawdata);
-                  break;
-                }
-      case 10 : ;                      /* rgb */
-      case 14 : {                      /* rgba */
-                  pBuf->iBKGDred   = mng_get_uint16 (pRawdata);
-                  pBuf->iBKGDgreen = mng_get_uint16 (pRawdata+2);
-                  pBuf->iBKGDblue  = mng_get_uint16 (pRawdata+4);
-                  break;
-                }
-    }
-  }
-  else
-#endif /* MNG_INCLUDE_JNG */
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-  {
-    pBuf->bHasBKGD = MNG_TRUE;         /* tell the object it's got bKGD now */
-
-    switch (pData->iColortype)         /* store fields for future reference */
-    {
-      case 0 : ;                        /* gray */
-      case 4 : {                        /* graya */
-                 pBuf->iBKGDgray  = mng_get_uint16 (pRawdata);
-                 break;
-               }
-      case 2 : ;                        /* rgb */
-      case 6 : {                        /* rgba */
-                 pBuf->iBKGDred   = mng_get_uint16 (pRawdata);
-                 pBuf->iBKGDgreen = mng_get_uint16 (pRawdata+2);
-                 pBuf->iBKGDblue  = mng_get_uint16 (pRawdata+4);
-                 break;
-               }
-      case 3 : {                        /* indexed */
-                 pBuf->iBKGDindex = *pRawdata;
-                 break;
-               }
-    }
-  }
-  else                                 /* store as global */
-  {
-    if (iRawlen)
-    {
-      pData->iGlobalBKGDred   = mng_get_uint16 (pRawdata);
-      pData->iGlobalBKGDgreen = mng_get_uint16 (pRawdata+2);
-      pData->iGlobalBKGDblue  = mng_get_uint16 (pRawdata+4);
-    }
-
-    {                                  /* create an animation object */
-      mng_retcode iRetcode = mng_create_ani_bkgd (pData, pData->iGlobalBKGDred,
-                                                  pData->iGlobalBKGDgreen,
-                                                  pData->iGlobalBKGDblue);
-
-      if (iRetcode)                    /* on error bail out */
-        return iRetcode;
-    }
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the fields */
-    ((mng_bkgdp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
-    ((mng_bkgdp)*ppChunk)->iType  = pData->iColortype;
-
-    if (iRawlen)
-    {
-      switch (iRawlen)                 /* guess from length */
-      {
-        case 1 : {                     /* indexed */
-                   ((mng_bkgdp)*ppChunk)->iType  = 3;
-                   ((mng_bkgdp)*ppChunk)->iIndex = *pRawdata;
-                   break;
-                 }
-        case 2 : {                     /* gray */
-                   ((mng_bkgdp)*ppChunk)->iType  = 0;
-                   ((mng_bkgdp)*ppChunk)->iGray  = mng_get_uint16 (pRawdata);
-                   break;
-                 }
-        case 6 : {                     /* rgb */
-                   ((mng_bkgdp)*ppChunk)->iType  = 2;
-                   ((mng_bkgdp)*ppChunk)->iRed   = mng_get_uint16 (pRawdata);
-                   ((mng_bkgdp)*ppChunk)->iGreen = mng_get_uint16 (pRawdata+2);
-                   ((mng_bkgdp)*ppChunk)->iBlue  = mng_get_uint16 (pRawdata+4);
-                   break;
-                 }
-      }
-    }
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_BKGD, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifndef MNG_SKIPCHUNK_pHYs
-READ_CHUNK (mng_read_phys)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_PHYS, MNG_LC_START);
-#endif
-                                       /* sequence checks */
-#ifdef MNG_INCLUDE_JNG
-  if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
-      (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
-#else
-  if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
-      (!pData->bHasBASI) && (!pData->bHasDHDR)    )
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIDAT) || (pData->bHasJDAT) || (pData->bHasJDAA))
-#else
-  if (pData->bHasIDAT)
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-                                       /* it's 9 bytes or empty; no more, no less! */
-  if ((iRawlen != 9) && (iRawlen != 0))
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-
-
-    /* TODO: something !!! */
-
-
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the fields */
-    ((mng_physp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
-
-    if (iRawlen)
-    {
-      ((mng_physp)*ppChunk)->iSizex = mng_get_uint32 (pRawdata);
-      ((mng_physp)*ppChunk)->iSizey = mng_get_uint32 (pRawdata+4);
-      ((mng_physp)*ppChunk)->iUnit  = *(pRawdata+8);
-    }
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_PHYS, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifndef MNG_SKIPCHUNK_sBIT
-READ_CHUNK (mng_read_sbit)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_SBIT, MNG_LC_START);
-#endif
-                                       /* sequence checks */
-#ifdef MNG_INCLUDE_JNG
-  if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
-      (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
-#else
-  if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
-      (!pData->bHasBASI) && (!pData->bHasDHDR)    )
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasPLTE) || (pData->bHasIDAT) || (pData->bHasJDAT) || (pData->bHasJDAA))
-#else
-  if ((pData->bHasPLTE) || (pData->bHasIDAT))
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-  if (iRawlen > 4)                     /* it just can't be bigger than that! */
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-#ifdef MNG_INCLUDE_JNG                 /* length checks */
-  if (pData->bHasJHDR)
-  {
-    if ((pData->iJHDRcolortype ==  8) && (iRawlen != 1))
-      MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-    if ((pData->iJHDRcolortype == 10) && (iRawlen != 3))
-      MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-    if ((pData->iJHDRcolortype == 12) && (iRawlen != 2))
-      MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-    if ((pData->iJHDRcolortype == 14) && (iRawlen != 4))
-      MNG_ERROR (pData, MNG_INVALIDLENGTH);
-  }
-  else
-#endif /* MNG_INCLUDE_JNG */
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-  {
-    if ((pData->iColortype == 0) && (iRawlen != 1))
-      MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-    if ((pData->iColortype == 2) && (iRawlen != 3))
-      MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-    if ((pData->iColortype == 3) && (iRawlen != 3))
-      MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-    if ((pData->iColortype == 4) && (iRawlen != 2))
-      MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-    if ((pData->iColortype == 6) && (iRawlen != 4))
-      MNG_ERROR (pData, MNG_INVALIDLENGTH);
-  }
-  else
-  {                                    /* global = empty or RGBA */
-    if ((iRawlen != 0) && (iRawlen != 4))
-      MNG_ERROR (pData, MNG_INVALIDLENGTH);
-  }
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-
-
-    /* TODO: something !!! */
-
-
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the fields */
-    ((mng_sbitp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
-
-    if (iRawlen)
-    {
-#ifdef MNG_INCLUDE_JNG
-      if (pData->bHasJHDR)
-        ((mng_sbitp)*ppChunk)->iType = pData->iJHDRcolortype;
-      else
-#endif
-      if (pData->bHasIHDR)
-        ((mng_sbitp)*ppChunk)->iType = pData->iColortype;
-      else                             /* global ! */
-        ((mng_sbitp)*ppChunk)->iType = 6;
-
-      if (iRawlen > 0)
-        ((mng_sbitp)*ppChunk)->aBits [0] = *pRawdata;
-      if (iRawlen > 1)
-        ((mng_sbitp)*ppChunk)->aBits [1] = *(pRawdata+1);
-      if (iRawlen > 2)
-        ((mng_sbitp)*ppChunk)->aBits [2] = *(pRawdata+2);
-      if (iRawlen > 3)
-        ((mng_sbitp)*ppChunk)->aBits [3] = *(pRawdata+3);
-
-    }
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_SBIT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifndef MNG_SKIPCHUNK_sPLT
-READ_CHUNK (mng_read_splt)
-{
-  mng_uint8p pTemp;
-  mng_uint32 iNamelen;
-  mng_uint8  iSampledepth;
-  mng_uint32 iRemain;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_SPLT, MNG_LC_START);
-#endif
-                                       /* sequence checks */
-  if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
-      (!pData->bHasBASI) && (!pData->bHasDHDR)    )
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-  if (pData->bHasIDAT)
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-  if (iRawlen)
-  {
-    pTemp = find_null (pRawdata);      /* find null-separator */
-                                       /* not found inside input-data ? */
-    if ((pTemp - pRawdata) > (mng_int32)iRawlen)
-      MNG_ERROR (pData, MNG_NULLNOTFOUND);
-
-    iNamelen     = (mng_uint32)(pTemp - pRawdata);
-    iSampledepth = *(pTemp+1);
-    iRemain      = (iRawlen - 2 - iNamelen);
-
-    if ((iSampledepth != 1) && (iSampledepth != 2))
-      MNG_ERROR (pData, MNG_INVSAMPLEDEPTH);
-                                       /* check remaining length */
-    if ( ((iSampledepth == 1) && (iRemain %  6 != 0)) ||
-         ((iSampledepth == 2) && (iRemain % 10 != 0))    )
-      MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-  }
-  else
-  {
-    pTemp        = MNG_NULL;
-    iNamelen     = 0;
-    iSampledepth = 0;
-    iRemain      = 0;
-  }
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-
-
-    /* TODO: something !!! */
-
-
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the fields */
-    ((mng_spltp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
-
-    if (iRawlen)
-    {
-      ((mng_spltp)*ppChunk)->iNamesize    = iNamelen;
-      ((mng_spltp)*ppChunk)->iSampledepth = iSampledepth;
-
-      if (iSampledepth == 1)
-        ((mng_spltp)*ppChunk)->iEntrycount = iRemain / 6;
-      else
-        ((mng_spltp)*ppChunk)->iEntrycount = iRemain / 10;
-
-      if (iNamelen)
-      {
-        MNG_ALLOC (pData, ((mng_spltp)*ppChunk)->zName, iNamelen+1);
-        MNG_COPY (((mng_spltp)*ppChunk)->zName, pRawdata, iNamelen);
-      }
-
-      if (iRemain)
-      {
-        MNG_ALLOC (pData, ((mng_spltp)*ppChunk)->pEntries, iRemain);
-        MNG_COPY (((mng_spltp)*ppChunk)->pEntries, pTemp+2, iRemain);
-      }
-    }
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_SPLT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifndef MNG_SKIPCHUNK_hIST
-READ_CHUNK (mng_read_hist)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_HIST, MNG_LC_START);
-#endif
-                                       /* sequence checks */
-  if ((!pData->bHasIHDR) && (!pData->bHasBASI) && (!pData->bHasDHDR)    )
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-  if ((!pData->bHasPLTE) || (pData->bHasIDAT))
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-                                       /* length oke ? */
-  if ( ((iRawlen & 0x01) != 0) || ((iRawlen >> 1) != pData->iPLTEcount) )
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-
-
-    /* TODO: something !!! */
-
-
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {
-    mng_uint32 iX;
-                                       /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the fields */
-    ((mng_histp)*ppChunk)->iEntrycount = iRawlen >> 1;
-
-    for (iX = 0; iX < (iRawlen >> 1); iX++)
-    {
-      ((mng_histp)*ppChunk)->aEntries [iX] = mng_get_uint16 (pRawdata);
-      pRawdata += 2;
-    }
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_HIST, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifndef MNG_SKIPCHUNK_tIME
-READ_CHUNK (mng_read_time)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_TIME, MNG_LC_START);
-#endif
-                                       /* sequence checks */
-#ifdef MNG_INCLUDE_JNG
-  if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
-      (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
-#else
-  if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
-      (!pData->bHasBASI) && (!pData->bHasDHDR)    )
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-  if (iRawlen != 7)                    /* length must be exactly 7 */
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-/*  if (pData->fProcesstime) */            /* inform the application ? */
-/*  {
-
-    pData->fProcesstime ((mng_handle)pData, );
-  } */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the fields */
-    ((mng_timep)*ppChunk)->iYear   = mng_get_uint16 (pRawdata);
-    ((mng_timep)*ppChunk)->iMonth  = *(pRawdata+2);
-    ((mng_timep)*ppChunk)->iDay    = *(pRawdata+3);
-    ((mng_timep)*ppChunk)->iHour   = *(pRawdata+4);
-    ((mng_timep)*ppChunk)->iMinute = *(pRawdata+5);
-    ((mng_timep)*ppChunk)->iSecond = *(pRawdata+6);
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_TIME, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-READ_CHUNK (mng_read_mhdr)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_MHDR, MNG_LC_START);
-#endif
-
-  if (pData->eSigtype != mng_it_mng)   /* sequence checks */
-    MNG_ERROR (pData, MNG_CHUNKNOTALLOWED);
-
-  if (pData->bHasheader)               /* can only be the first chunk! */
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-                                       /* correct length ? */
-#ifndef MNG_NO_OLD_VERSIONS
-  if ((iRawlen != 28) && (iRawlen != 12))
-#else
-  if ((iRawlen != 28))
-#endif
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-  pData->bHasMHDR       = MNG_TRUE;    /* oh boy, a real MNG */
-  pData->bHasheader     = MNG_TRUE;    /* we've got a header */
-  pData->eImagetype     = mng_it_mng;  /* fill header fields */
-  pData->iWidth         = mng_get_uint32 (pRawdata);
-  pData->iHeight        = mng_get_uint32 (pRawdata+4);
-  pData->iTicks         = mng_get_uint32 (pRawdata+8);
-
-#ifndef MNG_NO_OLD_VERSIONS
-  if (iRawlen == 28)                   /* proper MHDR ? */
-  {
-#endif
-    pData->iLayercount  = mng_get_uint32 (pRawdata+12);
-    pData->iFramecount  = mng_get_uint32 (pRawdata+16);
-    pData->iPlaytime    = mng_get_uint32 (pRawdata+20);
-    pData->iSimplicity  = mng_get_uint32 (pRawdata+24);
-
-#ifndef MNG_NO_OLD_VERSIONS
-    pData->bPreDraft48  = MNG_FALSE;
-  }
-  else                                 /* probably pre-draft48 then */
-  {
-    pData->iLayercount  = 0;
-    pData->iFramecount  = 0;
-    pData->iPlaytime    = 0;
-    pData->iSimplicity  = 0;
-
-    pData->bPreDraft48  = MNG_TRUE;
-  }
-#endif
-                                       /* predict alpha-depth */
-  if ((pData->iSimplicity & 0x00000001) == 0)
-#ifndef MNG_NO_16BIT_SUPPORT
-    pData->iAlphadepth = 16;           /* no indicators = assume the worst */
-#else
-    pData->iAlphadepth = 8;            /* anything else = assume the worst */
-#endif
-  else
-  if ((pData->iSimplicity & 0x00000008) == 0)
-    pData->iAlphadepth = 0;            /* no transparency at all */
-  else
-  if ((pData->iSimplicity & 0x00000140) == 0x00000040)
-    pData->iAlphadepth = 1;            /* no semi-transparency guaranteed */
-  else
-#ifndef MNG_NO_16BIT_SUPPORT
-    pData->iAlphadepth = 16;           /* anything else = assume the worst */
-#else
-    pData->iAlphadepth = 8;            /* anything else = assume the worst */
-#endif
-
-#ifdef MNG_INCLUDE_JNG                 /* can we handle the complexity ? */
-  if (pData->iSimplicity & 0x0000FC00)
-#else
-  if (pData->iSimplicity & 0x0000FC10)
-#endif
-    MNG_ERROR (pData, MNG_MNGTOOCOMPLEX);
-                                       /* fits on maximum canvas ? */
-  if ((pData->iWidth > pData->iMaxwidth) || (pData->iHeight > pData->iMaxheight))
-    MNG_WARNING (pData, MNG_IMAGETOOLARGE);
-
-  if (pData->fProcessheader)           /* inform the app ? */
-    if (!pData->fProcessheader (((mng_handle)pData), pData->iWidth, pData->iHeight))
-      MNG_ERROR (pData, MNG_APPMISCERROR);
-
-  pData->iImagelevel++;                /* one level deeper */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the fields */
-    ((mng_mhdrp)*ppChunk)->iWidth      = pData->iWidth;
-    ((mng_mhdrp)*ppChunk)->iHeight     = pData->iHeight;
-    ((mng_mhdrp)*ppChunk)->iTicks      = pData->iTicks;
-    ((mng_mhdrp)*ppChunk)->iLayercount = pData->iLayercount;
-    ((mng_mhdrp)*ppChunk)->iFramecount = pData->iFramecount;
-    ((mng_mhdrp)*ppChunk)->iPlaytime   = pData->iPlaytime;
-    ((mng_mhdrp)*ppChunk)->iSimplicity = pData->iSimplicity;
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_MHDR, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-READ_CHUNK (mng_read_mend)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_MEND, MNG_LC_START);
-#endif
-
-  if (!pData->bHasMHDR)                /* sequence checks */
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-  if (iRawlen > 0)                     /* must not contain data! */
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {                                    /* do something */
-    mng_retcode iRetcode = mng_process_display_mend (pData);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-
-    if (!pData->iTotalframes)          /* save totals */
-      pData->iTotalframes   = pData->iFrameseq;
-    if (!pData->iTotallayers)
-      pData->iTotallayers   = pData->iLayerseq;
-    if (!pData->iTotalplaytime)
-      pData->iTotalplaytime = pData->iFrametime;
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-  pData->bHasMHDR = MNG_FALSE;         /* end of the line, bro! */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_MEND, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifndef MNG_SKIPCHUNK_LOOP
-READ_CHUNK (mng_read_loop)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_LOOP, MNG_LC_START);
-#endif
-
-  if (!pData->bHasMHDR)                /* sequence checks */
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-  if (!pData->bCacheplayback)          /* must store playback info to work!! */
-    MNG_ERROR (pData, MNG_LOOPWITHCACHEOFF);
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-  if (iRawlen >= 5)                    /* length checks */
-  {
-    if (iRawlen >= 6)
-    {
-      if ((iRawlen - 6) % 4 != 0)
-        MNG_ERROR (pData, MNG_INVALIDLENGTH);
-    }
-  }
-  else
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-    mng_uint8   iLevel;
-    mng_uint32  iRepeat;
-    mng_uint8   iTermination = 0;
-    mng_uint32  iItermin     = 1;
-    mng_uint32  iItermax     = 0x7fffffffL;
-    mng_retcode iRetcode;
-
-    pData->bHasLOOP = MNG_TRUE;        /* indicate we're inside a loop */
-
-    iLevel = *pRawdata;                /* determine the fields for processing */
-
-#ifndef MNG_NO_OLD_VERSIONS
-    if (pData->bPreDraft48)
-    {
-      iTermination = *(pRawdata+1);
-
-      iRepeat = mng_get_uint32 (pRawdata+2);
-    }
-    else
-#endif
-      iRepeat = mng_get_uint32 (pRawdata+1);
-
-    if (iRawlen >= 6)
-    {
-#ifndef MNG_NO_OLD_VERSIONS
-      if (!pData->bPreDraft48)
-#endif
-        iTermination = *(pRawdata+5);
-
-      if (iRawlen >= 10)
-      {
-        iItermin = mng_get_uint32 (pRawdata+6);
-
-        if (iRawlen >= 14)
-        {
-          iItermax = mng_get_uint32 (pRawdata+10);
-
-          /* TODO: process signals */
-
-        }
-      }
-    }
-                                       /* create the LOOP ani-object */
-    iRetcode = mng_create_ani_loop (pData, iLevel, iRepeat, iTermination,
-                                           iItermin, iItermax, 0, 0);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* skip till matching ENDL if iteration=0 */
-    if ((!pData->bSkipping) && (iRepeat == 0))
-      pData->bSkipping = MNG_TRUE;
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-
-    if (iRawlen >= 5)                  /* store the fields */
-    {
-      ((mng_loopp)*ppChunk)->iLevel  = *pRawdata;
-
-#ifndef MNG_NO_OLD_VERSIONS
-      if (pData->bPreDraft48)
-      {
-        ((mng_loopp)*ppChunk)->iTermination = *(pRawdata+1);
-        ((mng_loopp)*ppChunk)->iRepeat = mng_get_uint32 (pRawdata+2);
-      }
-      else
-#endif
-      {
-        ((mng_loopp)*ppChunk)->iRepeat = mng_get_uint32 (pRawdata+1);
-      }
-
-      if (iRawlen >= 6)
-      {
-#ifndef MNG_NO_OLD_VERSIONS
-        if (!pData->bPreDraft48)
-#endif
-          ((mng_loopp)*ppChunk)->iTermination = *(pRawdata+5);
-
-        if (iRawlen >= 10)
-        {
-          ((mng_loopp)*ppChunk)->iItermin = mng_get_uint32 (pRawdata+6);
-
-#ifndef MNG_NO_LOOP_SIGNALS_SUPPORTED
-          if (iRawlen >= 14)
-          {
-            ((mng_loopp)*ppChunk)->iItermax = mng_get_uint32 (pRawdata+10);
-            ((mng_loopp)*ppChunk)->iCount   = (iRawlen - 14) / 4;
-
-            if (((mng_loopp)*ppChunk)->iCount)
-            {
-              MNG_ALLOC (pData, ((mng_loopp)*ppChunk)->pSignals,
-                                ((mng_loopp)*ppChunk)->iCount << 2);
-
-#ifndef MNG_BIGENDIAN_SUPPORTED
-              {
-                mng_uint32  iX;
-                mng_uint8p  pIn  = pRawdata + 14;
-                mng_uint32p pOut = (mng_uint32p)((mng_loopp)*ppChunk)->pSignals;
-
-                for (iX = 0; iX < ((mng_loopp)*ppChunk)->iCount; iX++)
-                {
-                  *pOut++ = mng_get_uint32 (pIn);
-                  pIn += 4;
-                }
-              }
-#else
-              MNG_COPY (((mng_loopp)*ppChunk)->pSignals, pRawdata + 14,
-                        ((mng_loopp)*ppChunk)->iCount << 2);
-#endif /* !MNG_BIGENDIAN_SUPPORTED */
-            }
-          }
-#endif
-        }
-      }
-    }
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_LOOP, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifndef MNG_SKIPCHUNK_LOOP
-READ_CHUNK (mng_read_endl)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_ENDL, MNG_LC_START);
-#endif
-
-  if (!pData->bHasMHDR)                /* sequence checks */
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-  if (iRawlen != 1)                    /* length must be exactly 1 */
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-    if (pData->bHasLOOP)               /* are we really processing a loop ? */
-    {
-      mng_uint8 iLevel = *pRawdata;    /* get the nest level */
-                                       /* create an ENDL animation object */
-      mng_retcode iRetcode = mng_create_ani_endl (pData, iLevel);
-                                 
-      if (iRetcode)                    /* on error bail out */
-        return iRetcode;
-
-/*      {
-        mng_ani_endlp pENDL = (mng_ani_endlp)pData->pLastaniobj;
-
-        iRetcode = pENDL->sHeader.fProcess (pData, pENDL);
-
-        if (iRetcode)
-          return iRetcode;
-      } */
-    }
-    else
-      MNG_ERROR (pData, MNG_NOMATCHINGLOOP);
-      
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the fields */
-    ((mng_endlp)*ppChunk)->iLevel = *pRawdata;
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_ENDL, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifndef MNG_SKIPCHUNK_DEFI
-READ_CHUNK (mng_read_defi)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_DEFI, MNG_LC_START);
-#endif
-
-  if (!pData->bHasMHDR)                /* sequence checks */
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-                                       /* check the length */
-  if ((iRawlen != 2) && (iRawlen != 3) && (iRawlen != 4) &&
-      (iRawlen != 12) && (iRawlen != 28))
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-    mng_retcode iRetcode;
-
-    pData->iDEFIobjectid       = mng_get_uint16 (pRawdata);
-
-    if (iRawlen > 2)
-    {
-      pData->bDEFIhasdonotshow = MNG_TRUE;
-      pData->iDEFIdonotshow    = *(pRawdata+2);
-    }
-    else
-    {
-      pData->bDEFIhasdonotshow = MNG_FALSE;
-      pData->iDEFIdonotshow    = 0;
-    }
-
-    if (iRawlen > 3)
-    {
-      pData->bDEFIhasconcrete  = MNG_TRUE;
-      pData->iDEFIconcrete     = *(pRawdata+3);
-    }
-    else
-    {
-      pData->bDEFIhasconcrete  = MNG_FALSE;
-      pData->iDEFIconcrete     = 0;
-    }
-
-    if (iRawlen > 4)
-    {
-      pData->bDEFIhasloca      = MNG_TRUE;
-      pData->iDEFIlocax        = mng_get_int32 (pRawdata+4);
-      pData->iDEFIlocay        = mng_get_int32 (pRawdata+8);
-    }
-    else
-    {
-      pData->bDEFIhasloca      = MNG_FALSE;
-      pData->iDEFIlocax        = 0;
-      pData->iDEFIlocay        = 0;
-    }
-
-    if (iRawlen > 12)
-    {
-      pData->bDEFIhasclip      = MNG_TRUE;
-      pData->iDEFIclipl        = mng_get_int32 (pRawdata+12);
-      pData->iDEFIclipr        = mng_get_int32 (pRawdata+16);
-      pData->iDEFIclipt        = mng_get_int32 (pRawdata+20);
-      pData->iDEFIclipb        = mng_get_int32 (pRawdata+24);
-    }
-    else
-    {
-      pData->bDEFIhasclip      = MNG_FALSE;
-      pData->iDEFIclipl        = 0;
-      pData->iDEFIclipr        = 0;
-      pData->iDEFIclipt        = 0;
-      pData->iDEFIclipb        = 0;
-    }
-                                       /* create an animation object */
-    iRetcode = mng_create_ani_defi (pData);
-                   
-    if (!iRetcode)                     /* do display processing */
-      iRetcode = mng_process_display_defi (pData);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the fields */
-    ((mng_defip)*ppChunk)->iObjectid       = mng_get_uint16 (pRawdata);
-
-    if (iRawlen > 2)
-    {
-      ((mng_defip)*ppChunk)->bHasdonotshow = MNG_TRUE;
-      ((mng_defip)*ppChunk)->iDonotshow    = *(pRawdata+2);
-    }
-    else
-      ((mng_defip)*ppChunk)->bHasdonotshow = MNG_FALSE;
-
-    if (iRawlen > 3)
-    {
-      ((mng_defip)*ppChunk)->bHasconcrete  = MNG_TRUE;
-      ((mng_defip)*ppChunk)->iConcrete     = *(pRawdata+3);
-    }
-    else
-      ((mng_defip)*ppChunk)->bHasconcrete  = MNG_FALSE;
-
-    if (iRawlen > 4)
-    {
-      ((mng_defip)*ppChunk)->bHasloca      = MNG_TRUE;
-      ((mng_defip)*ppChunk)->iXlocation    = mng_get_int32 (pRawdata+4);
-      ((mng_defip)*ppChunk)->iYlocation    = mng_get_int32 (pRawdata+8);
-    }
-    else
-      ((mng_defip)*ppChunk)->bHasloca      = MNG_FALSE;
-
-    if (iRawlen > 12)
-    {
-      ((mng_defip)*ppChunk)->bHasclip      = MNG_TRUE;
-      ((mng_defip)*ppChunk)->iLeftcb       = mng_get_int32 (pRawdata+12);
-      ((mng_defip)*ppChunk)->iRightcb      = mng_get_int32 (pRawdata+16);
-      ((mng_defip)*ppChunk)->iTopcb        = mng_get_int32 (pRawdata+20);
-      ((mng_defip)*ppChunk)->iBottomcb     = mng_get_int32 (pRawdata+24);
-    }
-    else
-      ((mng_defip)*ppChunk)->bHasclip      = MNG_FALSE;
-
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_DEFI, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifndef MNG_SKIPCHUNK_BASI
-READ_CHUNK (mng_read_basi)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_BASI, MNG_LC_START);
-#endif
-
-  if (!pData->bHasMHDR)                /* sequence checks */
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-                                       /* check the length */
-  if ((iRawlen != 13) && (iRawlen != 19) && (iRawlen != 21) && (iRawlen != 22))
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-  pData->bHasBASI     = MNG_TRUE;      /* inside a BASI-IEND block now */
-                                       /* store interesting fields */
-  pData->iDatawidth   = mng_get_uint32 (pRawdata);
-  pData->iDataheight  = mng_get_uint32 (pRawdata+4);
-  pData->iBitdepth    = *(pRawdata+8);
-  pData->iColortype   = *(pRawdata+9);
-  pData->iCompression = *(pRawdata+10);
-  pData->iFilter      = *(pRawdata+11);
-  pData->iInterlace   = *(pRawdata+12);
-
-
-#if defined(MNG_NO_1_2_4BIT_SUPPORT) || defined(MNG_NO_16BIT_SUPPORT)
-  pData->iPNGmult = 1;
-  pData->iPNGdepth = pData->iBitdepth;
-#endif
-
-#ifdef MNG_NO_1_2_4BIT_SUPPORT
-  if (pData->iBitdepth < 8)
-    pData->iBitdepth = 8;
-#endif
-#ifdef MNG_NO_16BIT_SUPPORT
-  if (pData->iBitdepth > 8)
-    {
-      pData->iBitdepth = 8;
-      pData->iPNGmult = 2;
-    }
-#endif
-
-  if ((pData->iBitdepth !=  8)      /* parameter validity checks */
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-      && (pData->iBitdepth !=  1) &&
-      (pData->iBitdepth !=  2) &&
-      (pData->iBitdepth !=  4)
-#endif
-#ifndef MNG_NO_16BIT_SUPPORT
-      && (pData->iBitdepth != 16)
-#endif
-      )
-    MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
-
-  if ((pData->iColortype != MNG_COLORTYPE_GRAY   ) &&
-      (pData->iColortype != MNG_COLORTYPE_RGB    ) &&
-      (pData->iColortype != MNG_COLORTYPE_INDEXED) &&
-      (pData->iColortype != MNG_COLORTYPE_GRAYA  ) &&
-      (pData->iColortype != MNG_COLORTYPE_RGBA   )    )
-    MNG_ERROR (pData, MNG_INVALIDCOLORTYPE);
-
-  if ((pData->iColortype == MNG_COLORTYPE_INDEXED) && (pData->iBitdepth > 8))
-    MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
-
-  if (((pData->iColortype == MNG_COLORTYPE_RGB    ) ||
-       (pData->iColortype == MNG_COLORTYPE_GRAYA  ) ||
-       (pData->iColortype == MNG_COLORTYPE_RGBA   )    ) &&
-      (pData->iBitdepth < 8                            )    )
-    MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
-
-  if (pData->iCompression != MNG_COMPRESSION_DEFLATE)
-    MNG_ERROR (pData, MNG_INVALIDCOMPRESS);
-
-#if defined(FILTER192) || defined(FILTER193)
-  if ((pData->iFilter != MNG_FILTER_ADAPTIVE ) &&
-#if defined(FILTER192) && defined(FILTER193)
-      (pData->iFilter != MNG_FILTER_DIFFERING) &&
-      (pData->iFilter != MNG_FILTER_NOFILTER )    )
-#else
-#ifdef FILTER192
-      (pData->iFilter != MNG_FILTER_DIFFERING)    )
-#else
-      (pData->iFilter != MNG_FILTER_NOFILTER )    )
-#endif
-#endif
-    MNG_ERROR (pData, MNG_INVALIDFILTER);
-#else
-  if (pData->iFilter)
-    MNG_ERROR (pData, MNG_INVALIDFILTER);
-#endif
-
-  if ((pData->iInterlace != MNG_INTERLACE_NONE ) &&
-      (pData->iInterlace != MNG_INTERLACE_ADAM7)    )
-    MNG_ERROR (pData, MNG_INVALIDINTERLACE);
-
-  pData->iImagelevel++;                /* one level deeper */
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-    mng_uint16  iRed      = 0;
-    mng_uint16  iGreen    = 0;
-    mng_uint16  iBlue     = 0;
-    mng_bool    bHasalpha = MNG_FALSE;
-    mng_uint16  iAlpha    = 0xFFFF;
-    mng_uint8   iViewable = 0;
-    mng_retcode iRetcode;
-
-    if (iRawlen > 13)                  /* get remaining fields, if any */
-    {
-      iRed      = mng_get_uint16 (pRawdata+13);
-      iGreen    = mng_get_uint16 (pRawdata+15);
-      iBlue     = mng_get_uint16 (pRawdata+17);
-    }
-
-    if (iRawlen > 19)
-    {
-      bHasalpha = MNG_TRUE;
-      iAlpha    = mng_get_uint16 (pRawdata+19);
-    }
-
-    if (iRawlen > 21)
-      iViewable = *(pRawdata+21);
-                                       /* create an animation object */
-    iRetcode = mng_create_ani_basi (pData, iRed, iGreen, iBlue,
-                                    bHasalpha, iAlpha, iViewable);
-
-/*    if (!iRetcode)
-      iRetcode = mng_process_display_basi (pData, iRed, iGreen, iBlue,
-                                           bHasalpha, iAlpha, iViewable); */
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the fields */
-    ((mng_basip)*ppChunk)->iWidth       = mng_get_uint32 (pRawdata);
-    ((mng_basip)*ppChunk)->iHeight      = mng_get_uint32 (pRawdata+4);
-#ifdef MNG_NO_16BIT_SUPPORT
-    if (*(pRawdata+8) > 8)
-      ((mng_basip)*ppChunk)->iBitdepth    = 8;
-    else
-#endif
-      ((mng_basip)*ppChunk)->iBitdepth    = *(pRawdata+8);
-    ((mng_basip)*ppChunk)->iColortype   = *(pRawdata+9);
-    ((mng_basip)*ppChunk)->iCompression = *(pRawdata+10);
-    ((mng_basip)*ppChunk)->iFilter      = *(pRawdata+11);
-    ((mng_basip)*ppChunk)->iInterlace   = *(pRawdata+12);
-
-    if (iRawlen > 13)
-    {
-      ((mng_basip)*ppChunk)->iRed       = mng_get_uint16 (pRawdata+13);
-      ((mng_basip)*ppChunk)->iGreen     = mng_get_uint16 (pRawdata+15);
-      ((mng_basip)*ppChunk)->iBlue      = mng_get_uint16 (pRawdata+17);
-    }
-
-    if (iRawlen > 19)
-      ((mng_basip)*ppChunk)->iAlpha     = mng_get_uint16 (pRawdata+19);
-
-    if (iRawlen > 21)
-      ((mng_basip)*ppChunk)->iViewable  = *(pRawdata+21);
-
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_BASI, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifndef MNG_SKIPCHUNK_CLON
-READ_CHUNK (mng_read_clon)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_CLON, MNG_LC_START);
-#endif
-
-  if (!pData->bHasMHDR)                /* sequence checks */
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-                                       /* check the length */
-  if ((iRawlen != 4) && (iRawlen != 5) && (iRawlen != 6) &&
-      (iRawlen != 7) && (iRawlen != 16))
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-    mng_uint16  iSourceid, iCloneid;
-    mng_uint8   iClonetype    = 0;
-    mng_bool    bHasdonotshow = MNG_FALSE;
-    mng_uint8   iDonotshow    = 0;
-    mng_uint8   iConcrete     = 0;
-    mng_bool    bHasloca      = MNG_FALSE;
-    mng_uint8   iLocationtype = 0;
-    mng_int32   iLocationx    = 0;
-    mng_int32   iLocationy    = 0;
-    mng_retcode iRetcode;
-
-    iSourceid       = mng_get_uint16 (pRawdata);
-    iCloneid        = mng_get_uint16 (pRawdata+2);
-
-    if (iRawlen > 4)
-      iClonetype    = *(pRawdata+4);
-
-    if (iRawlen > 5)
-    {
-      bHasdonotshow = MNG_TRUE;
-      iDonotshow    = *(pRawdata+5);
-    }
-
-    if (iRawlen > 6)
-      iConcrete     = *(pRawdata+6);
-
-    if (iRawlen > 7)
-    {
-      bHasloca      = MNG_TRUE;
-      iLocationtype = *(pRawdata+7);
-      iLocationx    = mng_get_int32 (pRawdata+8);
-      iLocationy    = mng_get_int32 (pRawdata+12);
-    }
-
-    iRetcode = mng_create_ani_clon (pData, iSourceid, iCloneid, iClonetype,
-                                    bHasdonotshow, iDonotshow, iConcrete,
-                                    bHasloca, iLocationtype, iLocationx, iLocationy);
-
-/*    if (!iRetcode)
-      iRetcode = mng_process_display_clon (pData, iSourceid, iCloneid, iClonetype,
-                                           bHasdonotshow, iDonotshow, iConcrete,
-                                           bHasloca, iLocationtype, iLocationx,
-                                           iLocationy); */
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the fields */
-    ((mng_clonp)*ppChunk)->iSourceid       = mng_get_uint16 (pRawdata);
-    ((mng_clonp)*ppChunk)->iCloneid        = mng_get_uint16 (pRawdata+2);
-
-    if (iRawlen > 4)
-      ((mng_clonp)*ppChunk)->iClonetype    = *(pRawdata+4);
-
-    if (iRawlen > 5)
-      ((mng_clonp)*ppChunk)->iDonotshow    = *(pRawdata+5);
-
-    if (iRawlen > 6)
-      ((mng_clonp)*ppChunk)->iConcrete     = *(pRawdata+6);
-
-    if (iRawlen > 7)
-    {
-      ((mng_clonp)*ppChunk)->bHasloca      = MNG_TRUE;
-      ((mng_clonp)*ppChunk)->iLocationtype = *(pRawdata+7);
-      ((mng_clonp)*ppChunk)->iLocationx    = mng_get_int32 (pRawdata+8);
-      ((mng_clonp)*ppChunk)->iLocationy    = mng_get_int32 (pRawdata+12);
-    }
-    else
-    {
-      ((mng_clonp)*ppChunk)->bHasloca      = MNG_FALSE;
-    }
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_CLON, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifndef MNG_SKIPCHUNK_PAST
-READ_CHUNK (mng_read_past)
-{
-#if defined(MNG_STORE_CHUNKS) || defined(MNG_SUPPORT_DISPLAY)
-  mng_retcode      iRetcode;
-  mng_uint16       iTargetid;
-  mng_uint8        iTargettype;
-  mng_int32        iTargetx;
-  mng_int32        iTargety;
-  mng_uint32       iCount;
-  mng_uint32       iSize;
-  mng_ptr          pSources;
-  mng_uint32       iX;
-  mng_past_sourcep pSource;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_PAST, MNG_LC_START);
-#endif
-
-  if (!pData->bHasMHDR)                /* sequence checks */
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-                                       /* check the length */
-  if ((iRawlen < 41) || (((iRawlen - 11) % 30) != 0))
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-#if defined(MNG_STORE_CHUNKS) || defined(MNG_SUPPORT_DISPLAY)
-  iTargetid   = mng_get_uint16 (pRawdata);
-  iTargettype = *(pRawdata+2);
-  iTargetx    = mng_get_int32  (pRawdata+3);
-  iTargety    = mng_get_int32  (pRawdata+7);
-  iCount      = ((iRawlen - 11) / 30); /* how many entries again? */
-  iSize       = iCount * sizeof (mng_past_source);
-
-  pRawdata += 11;
-                                       /* get a buffer for all the source blocks */
-  MNG_ALLOC (pData, pSources, iSize);
-
-  pSource = (mng_past_sourcep)pSources;
-
-  for (iX = 0; iX < iCount; iX++)      /* now copy the source blocks */
-  {
-    pSource->iSourceid     = mng_get_uint16 (pRawdata);
-    pSource->iComposition  = *(pRawdata+2);
-    pSource->iOrientation  = *(pRawdata+3);
-    pSource->iOffsettype   = *(pRawdata+4);
-    pSource->iOffsetx      = mng_get_int32 (pRawdata+5);
-    pSource->iOffsety      = mng_get_int32 (pRawdata+9);
-    pSource->iBoundarytype = *(pRawdata+13);
-    pSource->iBoundaryl    = mng_get_int32 (pRawdata+14);
-    pSource->iBoundaryr    = mng_get_int32 (pRawdata+18);
-    pSource->iBoundaryt    = mng_get_int32 (pRawdata+22);
-    pSource->iBoundaryb    = mng_get_int32 (pRawdata+26);
-
-    pSource++;
-    pRawdata += 30;
-  }
-#endif
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {                                    /* create playback object */
-    iRetcode = mng_create_ani_past (pData, iTargetid, iTargettype, iTargetx,
-                                    iTargety, iCount, pSources);
-
-/*    if (!iRetcode)
-      iRetcode = mng_process_display_past (pData, iTargetid, iTargettype, iTargetx,
-                                           iTargety, iCount, pSources); */
-
-    if (iRetcode)                      /* on error bail out */
-    {
-      MNG_FREEX (pData, pSources, iSize);
-      return iRetcode;
-    }
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-    {
-      MNG_FREEX (pData, pSources, iSize);
-      return iRetcode;
-    }
-                                       /* store the fields */
-    ((mng_pastp)*ppChunk)->iDestid     = iTargetid;
-    ((mng_pastp)*ppChunk)->iTargettype = iTargettype;
-    ((mng_pastp)*ppChunk)->iTargetx    = iTargetx;
-    ((mng_pastp)*ppChunk)->iTargety    = iTargety;
-    ((mng_pastp)*ppChunk)->iCount      = iCount;
-                                       /* get a buffer & copy the source blocks */
-    MNG_ALLOC (pData, ((mng_pastp)*ppChunk)->pSources, iSize);
-    MNG_COPY (((mng_pastp)*ppChunk)->pSources, pSources, iSize);
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#if defined(MNG_STORE_CHUNKS) || defined(MNG_SUPPORT_DISPLAY)
-                                       /* free the source block buffer */
-  MNG_FREEX (pData, pSources, iSize);
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_PAST, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifndef MNG_SKIPCHUNK_DISC
-READ_CHUNK (mng_read_disc)
-{
-#if defined(MNG_SUPPORT_DISPLAY) || defined(MNG_STORE_CHUNKS)
-  mng_uint32  iCount;
-  mng_uint16p pIds = MNG_NULL;
-  mng_retcode iRetcode;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_DISC, MNG_LC_START);
-#endif
-
-  if (!pData->bHasMHDR)                /* sequence checks */
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-  if ((iRawlen % 2) != 0)              /* check the length */
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-#if defined(MNG_SUPPORT_DISPLAY) || defined(MNG_STORE_CHUNKS)
-  iCount = (iRawlen / sizeof (mng_uint16));
-
-  if (iCount)
-  {
-    MNG_ALLOC (pData, pIds, iRawlen);
-
-#ifndef MNG_BIGENDIAN_SUPPORTED
-    {
-      mng_uint32  iX;
-      mng_uint8p  pIn  = pRawdata;
-      mng_uint16p pOut = pIds;
-
-      for (iX = 0; iX < iCount; iX++)
-      {
-        *pOut++ = mng_get_uint16 (pIn);
-        pIn += 2;
-      }
-    }
-#else
-    MNG_COPY (pIds, pRawdata, iRawlen);
-#endif /* !MNG_BIGENDIAN_SUPPORTED */
-  }
-#endif
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {                                    /* create playback object */
-    iRetcode = mng_create_ani_disc (pData, iCount, pIds);
-
-/*    if (!iRetcode)
-      iRetcode = mng_process_display_disc (pData, iCount, pIds); */
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the fields */
-    ((mng_discp)*ppChunk)->iCount = iCount;
-
-    if (iRawlen)
-    {
-      MNG_ALLOC (pData, ((mng_discp)*ppChunk)->pObjectids, iRawlen);
-      MNG_COPY (((mng_discp)*ppChunk)->pObjectids, pIds, iRawlen);
-    }
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#if defined(MNG_SUPPORT_DISPLAY) || defined(MNG_STORE_CHUNKS)
-  if (iRawlen)
-    MNG_FREEX (pData, pIds, iRawlen);
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_DISC, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifndef MNG_SKIPCHUNK_BACK
-READ_CHUNK (mng_read_back)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_BACK, MNG_LC_START);
-#endif
-
-  if (!pData->bHasMHDR)                /* sequence checks */
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-                                       /* check the length */
-  if ((iRawlen != 6) && (iRawlen != 7) && (iRawlen != 9) && (iRawlen != 10))
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-    mng_retcode iRetcode;
-                                       /* retrieve the fields */
-    pData->bHasBACK         = MNG_TRUE;
-    pData->iBACKred         = mng_get_uint16 (pRawdata);
-    pData->iBACKgreen       = mng_get_uint16 (pRawdata+2);
-    pData->iBACKblue        = mng_get_uint16 (pRawdata+4);
-
-    if (iRawlen > 6)
-      pData->iBACKmandatory = *(pRawdata+6);
-    else
-      pData->iBACKmandatory = 0;
-
-    if (iRawlen > 7)
-      pData->iBACKimageid   = mng_get_uint16 (pRawdata+7);
-    else
-      pData->iBACKimageid   = 0;
-
-    if (iRawlen > 9)
-      pData->iBACKtile      = *(pRawdata+9);
-    else
-      pData->iBACKtile      = 0;
-
-    iRetcode = mng_create_ani_back (pData, pData->iBACKred, pData->iBACKgreen,
-                                    pData->iBACKblue, pData->iBACKmandatory,
-                                    pData->iBACKimageid, pData->iBACKtile);
-
-    if (iRetcode)                    /* on error bail out */
-      return iRetcode;
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the fields */
-    ((mng_backp)*ppChunk)->iRed         = mng_get_uint16 (pRawdata);
-    ((mng_backp)*ppChunk)->iGreen       = mng_get_uint16 (pRawdata+2);
-    ((mng_backp)*ppChunk)->iBlue        = mng_get_uint16 (pRawdata+4);
-
-    if (iRawlen > 6)
-      ((mng_backp)*ppChunk)->iMandatory = *(pRawdata+6);
-
-    if (iRawlen > 7)
-      ((mng_backp)*ppChunk)->iImageid   = mng_get_uint16 (pRawdata+7);
-
-    if (iRawlen > 9)
-      ((mng_backp)*ppChunk)->iTile      = *(pRawdata+9);
-
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_BACK, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifndef MNG_SKIPCHUNK_FRAM
-READ_CHUNK (mng_read_fram)
-{
-  mng_uint8p pTemp;
-#ifdef MNG_STORE_CHUNKS
-  mng_uint32 iNamelen;
-#endif
-  mng_uint32 iRemain;
-  mng_uint32 iRequired = 0;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_FRAM, MNG_LC_START);
-#endif
-
-  if (!pData->bHasMHDR)                /* sequence checks */
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-  if (iRawlen <= 1)                    /* only framing-mode ? */
-  {
-#ifdef MNG_STORE_CHUNKS
-    iNamelen = 0;                      /* indicate so */
-#endif
-    iRemain  = 0;
-    pTemp    = MNG_NULL;
-  }
-  else
-  {
-    pTemp = find_null (pRawdata+1);    /* find null-separator */
-                                       /* not found inside input-data ? */
-    if ((pTemp - pRawdata) > (mng_int32)iRawlen)
-      pTemp  = pRawdata + iRawlen;     /* than remainder is name */
-
-#ifdef MNG_STORE_CHUNKS
-    iNamelen = (mng_uint32)((pTemp - pRawdata) - 1);
-#endif
-    iRemain  = (mng_uint32)(iRawlen - (pTemp - pRawdata));
-
-    if (iRemain)                       /* if there is remaining data it's less 1 byte */
-      iRemain--;
-
-    if ((iRemain) && (iRemain < 4))    /* remains must be empty or at least 4 bytes */
-      MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-    if (iRemain)
-    {
-      iRequired = 4;                   /* calculate and check required remaining length */
-
-      if (*(pTemp+1)) { iRequired += 4; }
-      if (*(pTemp+2)) { iRequired += 4; }
-      if (*(pTemp+3)) { iRequired += 17; }
-
-      if (*(pTemp+4))
-      {
-        if ((iRemain - iRequired) % 4 != 0)
-          MNG_ERROR (pData, MNG_INVALIDLENGTH);
-      }
-      else
-      {
-        if (iRemain != iRequired)
-          MNG_ERROR (pData, MNG_INVALIDLENGTH);
-      }
-    }
-  }
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-    mng_uint8p  pWork           = pTemp;
-    mng_uint8   iFramemode      = 0;
-    mng_uint8   iChangedelay    = 0;
-    mng_uint32  iDelay          = 0;
-    mng_uint8   iChangetimeout  = 0;
-    mng_uint32  iTimeout        = 0;
-    mng_uint8   iChangeclipping = 0;
-    mng_uint8   iCliptype       = 0;
-    mng_int32   iClipl          = 0;
-    mng_int32   iClipr          = 0;
-    mng_int32   iClipt          = 0;
-    mng_int32   iClipb          = 0;
-    mng_retcode iRetcode;
-
-    if (iRawlen)                       /* any data specified ? */
-    {
-      if (*(pRawdata))                 /* save the new framing mode ? */
-      {
-        iFramemode = *(pRawdata);
-
-#ifndef MNG_NO_OLD_VERSIONS
-        if (pData->bPreDraft48)        /* old style input-stream ? */
-        {
-          switch (iFramemode)
-          {
-            case  0: { break; }
-            case  1: { iFramemode = 3; break; }
-            case  2: { iFramemode = 4; break; }
-            case  3: { iFramemode = 1; break; }
-            case  4: { iFramemode = 1; break; }
-            case  5: { iFramemode = 2; break; }
-            default: { iFramemode = 1; break; }
-          }
-        }
-#endif
-      }
-
-      if (iRemain)
-      {
-        iChangedelay    = *(pWork+1);
-        iChangetimeout  = *(pWork+2);
-        iChangeclipping = *(pWork+3);
-        pWork += 5;
-
-        if (iChangedelay)              /* delay changed ? */
-        {
-          iDelay = mng_get_uint32 (pWork);
-          pWork += 4;
-        }
-
-        if (iChangetimeout)            /* timeout changed ? */
-        {
-          iTimeout = mng_get_uint32 (pWork);
-          pWork += 4;
-        }
-
-        if (iChangeclipping)           /* clipping changed ? */
-        {
-          iCliptype = *pWork;
-          iClipl    = mng_get_int32 (pWork+1);
-          iClipr    = mng_get_int32 (pWork+5);
-          iClipt    = mng_get_int32 (pWork+9);
-          iClipb    = mng_get_int32 (pWork+13);
-        }
-      }
-    }
-
-    iRetcode = mng_create_ani_fram (pData, iFramemode, iChangedelay, iDelay,
-                                    iChangetimeout, iTimeout,
-                                    iChangeclipping, iCliptype,
-                                    iClipl, iClipr, iClipt, iClipb);
-
-/*    if (!iRetcode)
-      iRetcode = mng_process_display_fram (pData, iFramemode, iChangedelay, iDelay,
-                                           iChangetimeout, iTimeout,
-                                           iChangeclipping, iCliptype,
-                                           iClipl, iClipr, iClipt, iClipb); */
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the fields */
-    ((mng_framp)*ppChunk)->bEmpty              = (mng_bool)(iRawlen == 0);
-
-    if (iRawlen)
-    {
-      mng_uint8 iFramemode = *(pRawdata);
-
-#ifndef MNG_NO_OLD_VERSIONS
-      if (pData->bPreDraft48)          /* old style input-stream ? */
-      {
-        switch (iFramemode)
-        {
-          case  1: { iFramemode = 3; break; }
-          case  2: { iFramemode = 4; break; }
-          case  3: { iFramemode = 5; break; }    /* TODO: provision for mode=5 ??? */
-          case  4: { iFramemode = 1; break; }
-          case  5: { iFramemode = 2; break; }
-          default: { iFramemode = 1; break; }
-        }
-      }
-#endif
-
-      ((mng_framp)*ppChunk)->iMode             = iFramemode;
-      ((mng_framp)*ppChunk)->iNamesize         = iNamelen;
-
-      if (iNamelen)
-      {
-        MNG_ALLOC (pData, ((mng_framp)*ppChunk)->zName, iNamelen+1);
-        MNG_COPY (((mng_framp)*ppChunk)->zName, pRawdata+1, iNamelen);
-      }
-
-      if (iRemain)
-      {
-        ((mng_framp)*ppChunk)->iChangedelay    = *(pTemp+1);
-        ((mng_framp)*ppChunk)->iChangetimeout  = *(pTemp+2);
-        ((mng_framp)*ppChunk)->iChangeclipping = *(pTemp+3);
-        ((mng_framp)*ppChunk)->iChangesyncid   = *(pTemp+4);
-
-        pTemp += 5;
-
-        if (((mng_framp)*ppChunk)->iChangedelay)
-        {
-          ((mng_framp)*ppChunk)->iDelay        = mng_get_uint32 (pTemp);
-          pTemp += 4;
-        }
-
-        if (((mng_framp)*ppChunk)->iChangetimeout)
-        {
-          ((mng_framp)*ppChunk)->iTimeout      = mng_get_uint32 (pTemp);
-          pTemp += 4;
-        }
-
-        if (((mng_framp)*ppChunk)->iChangeclipping)
-        {
-          ((mng_framp)*ppChunk)->iBoundarytype = *pTemp;
-          ((mng_framp)*ppChunk)->iBoundaryl    = mng_get_int32 (pTemp+1);
-          ((mng_framp)*ppChunk)->iBoundaryr    = mng_get_int32 (pTemp+5);
-          ((mng_framp)*ppChunk)->iBoundaryt    = mng_get_int32 (pTemp+9);
-          ((mng_framp)*ppChunk)->iBoundaryb    = mng_get_int32 (pTemp+13);
-          pTemp += 17;
-        }
-
-        if (((mng_framp)*ppChunk)->iChangesyncid)
-        {
-          ((mng_framp)*ppChunk)->iCount        = (iRemain - iRequired) / 4;
-
-          if (((mng_framp)*ppChunk)->iCount)
-          {
-            MNG_ALLOC (pData, ((mng_framp)*ppChunk)->pSyncids,
-                              ((mng_framp)*ppChunk)->iCount * 4);
-
-#ifndef MNG_BIGENDIAN_SUPPORTED
-            {
-              mng_uint32 iX;
-              mng_uint32p pOut = ((mng_framp)*ppChunk)->pSyncids;
-
-              for (iX = 0; iX < ((mng_framp)*ppChunk)->iCount; iX++)
-              {
-                *pOut++ = mng_get_uint32 (pTemp);
-                pTemp += 4;
-              }
-            }
-#else
-            MNG_COPY (((mng_framp)*ppChunk)->pSyncids, pTemp,
-                      ((mng_framp)*ppChunk)->iCount * 4);
-#endif /* !MNG_BIGENDIAN_SUPPORTED */
-          }
-        }
-      }
-    }
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_FRAM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifndef MNG_SKIPCHUNK_MOVE
-READ_CHUNK (mng_read_move)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_MOVE, MNG_LC_START);
-#endif
-
-  if (!pData->bHasMHDR)                /* sequence checks */
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-  if (iRawlen != 13)                   /* check the length */
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-    mng_retcode iRetcode;
-                                       /* create a MOVE animation object */
-    iRetcode = mng_create_ani_move (pData, mng_get_uint16 (pRawdata),
-                                           mng_get_uint16 (pRawdata+2),
-                                           *(pRawdata+4),
-                                           mng_get_int32 (pRawdata+5),
-                                           mng_get_int32 (pRawdata+9));
-
-/*    if (!iRetcode)
-      iRetcode = mng_process_display_move (pData,
-                                           mng_get_uint16 (pRawdata),
-                                           mng_get_uint16 (pRawdata+2),
-                                           *(pRawdata+4),
-                                           mng_get_int32 (pRawdata+5),
-                                           mng_get_int32 (pRawdata+9)); */
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the fields */
-    ((mng_movep)*ppChunk)->iFirstid  = mng_get_uint16 (pRawdata);
-    ((mng_movep)*ppChunk)->iLastid   = mng_get_uint16 (pRawdata+2);
-    ((mng_movep)*ppChunk)->iMovetype = *(pRawdata+4);
-    ((mng_movep)*ppChunk)->iMovex    = mng_get_int32 (pRawdata+5);
-    ((mng_movep)*ppChunk)->iMovey    = mng_get_int32 (pRawdata+9);
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_MOVE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifndef MNG_SKIPCHUNK_CLIP
-READ_CHUNK (mng_read_clip)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_CLIP, MNG_LC_START);
-#endif
-
-  if (!pData->bHasMHDR)                /* sequence checks */
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-  if (iRawlen != 21)                   /* check the length */
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-    mng_retcode iRetcode;
-                                       /* create a CLIP animation object */
-    iRetcode = mng_create_ani_clip (pData, mng_get_uint16 (pRawdata),
-                                           mng_get_uint16 (pRawdata+2),
-                                           *(pRawdata+4),
-                                           mng_get_int32 (pRawdata+5),
-                                           mng_get_int32 (pRawdata+9),
-                                           mng_get_int32 (pRawdata+13),
-                                           mng_get_int32 (pRawdata+17));
-
-/*    if (!iRetcode)
-      iRetcode = mng_process_display_clip (pData,
-                                           mng_get_uint16 (pRawdata),
-                                           mng_get_uint16 (pRawdata+2),
-                                           *(pRawdata+4),
-                                           mng_get_int32 (pRawdata+5),
-                                           mng_get_int32 (pRawdata+9),
-                                           mng_get_int32 (pRawdata+13),
-                                           mng_get_int32 (pRawdata+17)); */
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the fields */
-    ((mng_clipp)*ppChunk)->iFirstid  = mng_get_uint16 (pRawdata);
-    ((mng_clipp)*ppChunk)->iLastid   = mng_get_uint16 (pRawdata+2);
-    ((mng_clipp)*ppChunk)->iCliptype = *(pRawdata+4);
-    ((mng_clipp)*ppChunk)->iClipl    = mng_get_int32 (pRawdata+5);
-    ((mng_clipp)*ppChunk)->iClipr    = mng_get_int32 (pRawdata+9);
-    ((mng_clipp)*ppChunk)->iClipt    = mng_get_int32 (pRawdata+13);
-    ((mng_clipp)*ppChunk)->iClipb    = mng_get_int32 (pRawdata+17);
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_CLIP, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifndef MNG_SKIPCHUNK_SHOW
-READ_CHUNK (mng_read_show)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_SHOW, MNG_LC_START);
-#endif
-
-  if (!pData->bHasMHDR)                /* sequence checks */
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-                                       /* check the length */
-  if ((iRawlen != 0) && (iRawlen != 2) && (iRawlen != 4) && (iRawlen != 5))
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-    mng_retcode iRetcode;
-
-    if (iRawlen)                       /* determine parameters if any */
-    {
-      pData->iSHOWfromid = mng_get_uint16 (pRawdata);
-
-      if (iRawlen > 2)
-        pData->iSHOWtoid = mng_get_uint16 (pRawdata+2);
-      else
-        pData->iSHOWtoid = pData->iSHOWfromid;
-
-      if (iRawlen > 4)
-        pData->iSHOWmode = *(pRawdata+4);
-      else
-        pData->iSHOWmode = 0;
-    }
-    else                               /* use defaults then */
-    {
-      pData->iSHOWmode   = 2;
-      pData->iSHOWfromid = 1;
-      pData->iSHOWtoid   = 65535;
-    }
-                                       /* create a SHOW animation object */
-    iRetcode = mng_create_ani_show (pData, pData->iSHOWfromid,
-                                    pData->iSHOWtoid, pData->iSHOWmode);
-
-    if (!iRetcode)
-      iRetcode = mng_process_display_show (pData);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the fields */
-    ((mng_showp)*ppChunk)->bEmpty      = (mng_bool)(iRawlen == 0);
-
-    if (iRawlen)
-    {
-      ((mng_showp)*ppChunk)->iFirstid  = mng_get_uint16 (pRawdata);
-
-      if (iRawlen > 2)
-        ((mng_showp)*ppChunk)->iLastid = mng_get_uint16 (pRawdata+2);
-      else
-        ((mng_showp)*ppChunk)->iLastid = ((mng_showp)*ppChunk)->iFirstid;
-
-      if (iRawlen > 4)
-        ((mng_showp)*ppChunk)->iMode   = *(pRawdata+4);
-    }
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_SHOW, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifndef MNG_SKIPCHUNK_TERM
-READ_CHUNK (mng_read_term)
-{
-  mng_uint8   iTermaction;
-  mng_uint8   iIteraction = 0;
-  mng_uint32  iDelay      = 0;
-  mng_uint32  iItermax    = 0;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_TERM, MNG_LC_START);
-#endif
-
-  if (!pData->bHasMHDR)                /* sequence checks */
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-                                       /* should be behind MHDR or SAVE !! */
-  if ((!pData->bHasSAVE) && (pData->iChunkseq > 2))
-  {
-    pData->bMisplacedTERM = MNG_TRUE;  /* indicate we found a misplaced TERM */
-                                       /* and send a warning signal!!! */
-    MNG_WARNING (pData, MNG_SEQUENCEERROR);
-  }
-
-  if (pData->bHasLOOP)                 /* no way, jose! */
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-  if (pData->bHasTERM)                 /* only 1 allowed! */
-    MNG_ERROR (pData, MNG_MULTIPLEERROR);
-                                       /* check the length */
-  if ((iRawlen != 1) && (iRawlen != 10))
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-  pData->bHasTERM = MNG_TRUE;
-
-  iTermaction = *pRawdata;             /* get the fields */
-
-  if (iRawlen > 1)
-  {
-    iIteraction = *(pRawdata+1);
-    iDelay      = mng_get_uint32 (pRawdata+2);
-    iItermax    = mng_get_uint32 (pRawdata+6);
-  }
-
-  if (pData->fProcessterm)             /* inform the app ? */
-    if (!pData->fProcessterm (((mng_handle)pData), iTermaction, iIteraction,
-                                                   iDelay, iItermax))
-      MNG_ERROR (pData, MNG_APPMISCERROR);
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {                                    /* create the TERM ani-object */
-    mng_retcode iRetcode = mng_create_ani_term (pData, iTermaction, iIteraction,
-                                                iDelay, iItermax);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* save for future reference */
-    pData->pTermaniobj = pData->pLastaniobj;
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the fields */
-    ((mng_termp)*ppChunk)->iTermaction = iTermaction;
-    ((mng_termp)*ppChunk)->iIteraction = iIteraction;
-    ((mng_termp)*ppChunk)->iDelay      = iDelay;
-    ((mng_termp)*ppChunk)->iItermax    = iItermax;
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_TERM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifndef MNG_SKIPCHUNK_SAVE
-READ_CHUNK (mng_read_save)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_SAVE, MNG_LC_START);
-#endif
-                                       /* sequence checks */
-  if ((!pData->bHasMHDR) || (pData->bHasSAVE))
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-  pData->bHasSAVE = MNG_TRUE;
-
-  if (pData->fProcesssave)             /* inform the application ? */
-  {
-    mng_bool bOke = pData->fProcesssave ((mng_handle)pData);
-
-    if (!bOke)
-      MNG_ERROR (pData, MNG_APPMISCERROR);
-  }
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-    mng_retcode iRetcode;
-
-
-    /* TODO: something with the parameters */
-
-
-                                       /* create a SAVE animation object */
-    iRetcode = mng_create_ani_save (pData);
-
-    if (!iRetcode)
-      iRetcode = mng_process_display_save (pData);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-      
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the fields */
-    ((mng_savep)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
-
-    if (iRawlen)                       /* not empty ? */
-    {
-      mng_uint8       iOtype = *pRawdata;
-      mng_uint8       iEtype;
-      mng_uint32      iCount = 0;
-      mng_uint8p      pTemp;
-      mng_uint8p      pNull;
-      mng_uint32      iLen;
-      mng_uint32      iOffset[2];
-      mng_uint32      iStarttime[2];
-      mng_uint32      iFramenr;
-      mng_uint32      iLayernr;
-      mng_uint32      iX;
-      mng_save_entryp pEntry = MNG_NULL;
-      mng_uint32      iNamesize;
-
-      if ((iOtype != 4) && (iOtype != 8))
-        MNG_ERROR (pData, MNG_INVOFFSETSIZE);
-
-      ((mng_savep)*ppChunk)->iOffsettype = iOtype;
-
-      for (iX = 0; iX < 2; iX++)       /* do this twice to get the count first ! */
-      {
-        pTemp = pRawdata + 1;
-        iLen  = iRawlen  - 1;
-
-        if (iX)                        /* second run ? */
-        {
-          MNG_ALLOC (pData, pEntry, (iCount * sizeof (mng_save_entry)));
-
-          ((mng_savep)*ppChunk)->iCount   = iCount;
-          ((mng_savep)*ppChunk)->pEntries = pEntry;
-        }
-
-        while (iLen)                   /* anything left ? */
-        {
-          iEtype = *pTemp;             /* entrytype */
-
-          if ((iEtype != 0) && (iEtype != 1) && (iEtype != 2) && (iEtype != 3))
-            MNG_ERROR (pData, MNG_INVENTRYTYPE);
-
-          pTemp++;
-
-          if (iEtype > 1)
-          {
-            iOffset    [0] = 0;
-            iOffset    [1] = 0;
-            iStarttime [0] = 0;
-            iStarttime [1] = 0;
-            iLayernr       = 0;
-            iFramenr       = 0;
-          }
-          else
-          {
-            if (iOtype == 4)
-            {
-              iOffset [0] = 0;
-              iOffset [1] = mng_get_uint32 (pTemp);
-
-              pTemp += 4;
-            }
-            else
-            {
-              iOffset [0] = mng_get_uint32 (pTemp);
-              iOffset [1] = mng_get_uint32 (pTemp+4);
-
-              pTemp += 8;
-            }
-
-            if (iEtype > 0)
-            {
-              iStarttime [0] = 0;
-              iStarttime [1] = 0;
-              iLayernr       = 0;
-              iFramenr       = 0;
-            }
-            else
-            {
-              if (iOtype == 4)
-              {
-                iStarttime [0] = 0;
-                iStarttime [1] = mng_get_uint32 (pTemp+0);
-                iLayernr       = mng_get_uint32 (pTemp+4);
-                iFramenr       = mng_get_uint32 (pTemp+8);
-
-                pTemp += 12;
-              }
-              else
-              {
-                iStarttime [0] = mng_get_uint32 (pTemp+0);
-                iStarttime [1] = mng_get_uint32 (pTemp+4);
-                iLayernr       = mng_get_uint32 (pTemp+8);
-                iFramenr       = mng_get_uint32 (pTemp+12);
-
-                pTemp += 16;
-              }
-            }
-          }
-
-          pNull = find_null (pTemp);   /* get the name length */
-
-          if ((pNull - pRawdata) > (mng_int32)iRawlen)
-          {
-            iNamesize = iLen;          /* no null found; so end of SAVE */
-            iLen      = 0;
-          }
-          else
-          {
-            iNamesize = pNull - pTemp; /* should be another entry */
-            iLen     -= iNamesize;
-
-            if (!iLen)                 /* must not end with a null ! */
-              MNG_ERROR (pData, MNG_ENDWITHNULL);
-          }
-
-          if (!pEntry)
-          {
-            iCount++;
-          }
-          else
-          {
-            pEntry->iEntrytype     = iEtype;
-            pEntry->iOffset    [0] = iOffset    [0];
-            pEntry->iOffset    [1] = iOffset    [1];
-            pEntry->iStarttime [0] = iStarttime [0];
-            pEntry->iStarttime [1] = iStarttime [1];
-            pEntry->iLayernr       = iLayernr;
-            pEntry->iFramenr       = iFramenr;
-            pEntry->iNamesize      = iNamesize;
-
-            if (iNamesize)
-            {
-              MNG_ALLOC (pData, pEntry->zName, iNamesize+1);
-              MNG_COPY (pEntry->zName, pTemp, iNamesize);
-            }
-
-            pEntry++;
-          }
-
-          pTemp += iNamesize;
-        }
-      }
-    }
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_SAVE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifndef MNG_SKIPCHUNK_SEEK
-READ_CHUNK (mng_read_seek)
-{
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_SEEK, MNG_LC_START);
-#endif
-                                       /* sequence checks */
-  if ((!pData->bHasMHDR) || (!pData->bHasSAVE))
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-#ifdef MNG_SUPPORT_DISPLAY
-                                       /* create a SEEK animation object */
-  iRetcode = mng_create_ani_seek (pData, iRawlen, (mng_pchar)pRawdata);
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-    
-#endif /* MNG_SUPPORT_DISPLAY */
-
-  if (pData->fProcessseek)             /* inform the app ? */
-  {
-    mng_bool  bOke;
-    mng_pchar zName;
-
-    MNG_ALLOC (pData, zName, iRawlen + 1);
-
-    if (iRawlen)
-      MNG_COPY (zName, pRawdata, iRawlen);
-
-    bOke = pData->fProcessseek ((mng_handle)pData, zName);
-
-    MNG_FREEX (pData, zName, iRawlen + 1);
-
-    if (!bOke)
-      MNG_ERROR (pData, MNG_APPMISCERROR);
-  }
-
-#ifdef MNG_SUPPORT_DISPLAY
-                                       /* do display processing of the SEEK */
-  iRetcode = mng_process_display_seek (pData);
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the fields */
-    ((mng_seekp)*ppChunk)->iNamesize = iRawlen;
-
-    if (iRawlen)
-    {
-      MNG_ALLOC (pData, ((mng_seekp)*ppChunk)->zName, iRawlen+1);
-      MNG_COPY (((mng_seekp)*ppChunk)->zName, pRawdata, iRawlen);
-    }
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_SEEK, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifndef MNG_SKIPCHUNK_eXPI
-READ_CHUNK (mng_read_expi)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_EXPI, MNG_LC_START);
-#endif
-
-  if (!pData->bHasMHDR)                /* sequence checks */
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-  if (iRawlen < 3)                     /* check the length */
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-
-
-    /* TODO: something !!! */
-
-
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the fields */
-    ((mng_expip)*ppChunk)->iSnapshotid = mng_get_uint16 (pRawdata);
-    ((mng_expip)*ppChunk)->iNamesize   = iRawlen - 2;
-
-    if (((mng_expip)*ppChunk)->iNamesize)
-    {
-      MNG_ALLOC (pData, ((mng_expip)*ppChunk)->zName,
-                        ((mng_expip)*ppChunk)->iNamesize + 1);
-      MNG_COPY (((mng_expip)*ppChunk)->zName, pRawdata+2,
-                ((mng_expip)*ppChunk)->iNamesize);
-    }
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_EXPI, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifndef MNG_SKIPCHUNK_fPRI
-READ_CHUNK (mng_read_fpri)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_FPRI, MNG_LC_START);
-#endif
-
-  if (!pData->bHasMHDR)                /* sequence checks */
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-  if (iRawlen != 2)                    /* must be two bytes long */
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-
-
-    /* TODO: something !!! */
-
-
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the fields */
-    ((mng_fprip)*ppChunk)->iDeltatype = *pRawdata;
-    ((mng_fprip)*ppChunk)->iPriority  = *(pRawdata+1);
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_FPRI, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifndef MNG_SKIPCHUNK_nEED
-MNG_LOCAL mng_bool CheckKeyword (mng_datap  pData,
-                                 mng_uint8p pKeyword)
-{
-  mng_chunkid handled_chunks [] =
-  {
-    MNG_UINT_BACK,                     /* keep it sorted !!!! */
-    MNG_UINT_BASI,
-    MNG_UINT_CLIP,
-    MNG_UINT_CLON,
-#ifndef MNG_NO_DELTA_PNG
-/* TODO:    MNG_UINT_DBYK,  */
-#endif
-    MNG_UINT_DEFI,
-#ifndef MNG_NO_DELTA_PNG
-    MNG_UINT_DHDR,
-#endif
-    MNG_UINT_DISC,
-#ifndef MNG_NO_DELTA_PNG
-/* TODO:    MNG_UINT_DROP,  */
-#endif
-    MNG_UINT_ENDL,
-    MNG_UINT_FRAM,
-    MNG_UINT_IDAT,
-    MNG_UINT_IEND,
-    MNG_UINT_IHDR,
-#ifndef MNG_NO_DELTA_PNG
-#ifdef MNG_INCLUDE_JNG
-    MNG_UINT_IJNG,
-#endif    
-    MNG_UINT_IPNG,
-#endif
-#ifdef MNG_INCLUDE_JNG
-    MNG_UINT_JDAA,
-    MNG_UINT_JDAT,
-    MNG_UINT_JHDR,
-/* TODO:    MNG_UINT_JSEP,  */
-    MNG_UINT_JdAA,
-#endif
-    MNG_UINT_LOOP,
-    MNG_UINT_MAGN,
-    MNG_UINT_MEND,
-    MNG_UINT_MHDR,
-    MNG_UINT_MOVE,
-/* TODO:    MNG_UINT_ORDR,  */
-    MNG_UINT_PAST,
-    MNG_UINT_PLTE,
-#ifndef MNG_NO_DELTA_PNG
-    MNG_UINT_PPLT,
-    MNG_UINT_PROM,
-#endif
-    MNG_UINT_SAVE,
-    MNG_UINT_SEEK,
-    MNG_UINT_SHOW,
-    MNG_UINT_TERM,
-#ifdef MNG_INCLUDE_ANG_PROPOSAL
-    MNG_UINT_adAT,
-    MNG_UINT_ahDR,
-#endif
-    MNG_UINT_bKGD,
-    MNG_UINT_cHRM,
-/* TODO:    MNG_UINT_eXPI,  */
-    MNG_UINT_evNT,
-/* TODO:    MNG_UINT_fPRI,  */
-    MNG_UINT_gAMA,
-/* TODO:    MNG_UINT_hIST,  */
-    MNG_UINT_iCCP,
-    MNG_UINT_iTXt,
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-    MNG_UINT_mpNG,
-#endif
-    MNG_UINT_nEED,
-/* TODO:    MNG_UINT_oFFs,  */
-/* TODO:    MNG_UINT_pCAL,  */
-/* TODO:    MNG_UINT_pHYg,  */
-/* TODO:    MNG_UINT_pHYs,  */
-/* TODO:    MNG_UINT_sBIT,  */
-/* TODO:    MNG_UINT_sCAL,  */
-/* TODO:    MNG_UINT_sPLT,  */
-    MNG_UINT_sRGB,
-    MNG_UINT_tEXt,
-    MNG_UINT_tIME,
-    MNG_UINT_tRNS,
-    MNG_UINT_zTXt,
-  };
-
-  mng_bool bOke = MNG_FALSE;
-
-  if (pData->fProcessneed)             /* does the app handle it ? */
-    bOke = pData->fProcessneed ((mng_handle)pData, (mng_pchar)pKeyword);
-
-  if (!bOke)
-  {                                    /* find the keyword length */
-    mng_uint8p pNull = find_null (pKeyword);
-
-    if (pNull - pKeyword == 4)         /* test a chunk ? */
-    {                                  /* get the chunk-id */
-      mng_chunkid iChunkid = (*pKeyword     << 24) + (*(pKeyword+1) << 16) +
-                             (*(pKeyword+2) <<  8) + (*(pKeyword+3)      );
-                                       /* binary search variables */
-      mng_int32   iTop, iLower, iUpper, iMiddle;
-                                       /* determine max index of table */
-      iTop = (sizeof (handled_chunks) / sizeof (handled_chunks [0])) - 1;
-
-      /* binary search; with 52 chunks, worst-case is 7 comparisons */
-      iLower  = 0;
-      iMiddle = iTop >> 1;
-      iUpper  = iTop;
-
-      do                                   /* the binary search itself */
-        {
-          if (handled_chunks [iMiddle] < iChunkid)
-            iLower = iMiddle + 1;
-          else if (handled_chunks [iMiddle] > iChunkid)
-            iUpper = iMiddle - 1;
-          else
-          {
-            bOke = MNG_TRUE;
-            break;
-          }
-
-          iMiddle = (iLower + iUpper) >> 1;
-        }
-      while (iLower <= iUpper);
-    }
-                                       /* test draft ? */
-    if ((!bOke) && (pNull - pKeyword == 8) &&
-        (*pKeyword     == 'd') && (*(pKeyword+1) == 'r') &&
-        (*(pKeyword+2) == 'a') && (*(pKeyword+3) == 'f') &&
-        (*(pKeyword+4) == 't') && (*(pKeyword+5) == ' '))
-    {
-      mng_uint32 iDraft;
-
-      iDraft = (*(pKeyword+6) - '0') * 10 + (*(pKeyword+7) - '0');
-      bOke   = (mng_bool)(iDraft <= MNG_MNG_DRAFT);
-    }
-                                       /* test MNG 1.0/1.1 ? */
-    if ((!bOke) && (pNull - pKeyword == 7) &&
-        (*pKeyword     == 'M') && (*(pKeyword+1) == 'N') &&
-        (*(pKeyword+2) == 'G') && (*(pKeyword+3) == '-') &&
-        (*(pKeyword+4) == '1') && (*(pKeyword+5) == '.') &&
-        ((*(pKeyword+6) == '0') || (*(pKeyword+6) == '1')))
-      bOke   = MNG_TRUE;
-                                       /* test CACHEOFF ? */
-    if ((!bOke) && (pNull - pKeyword == 8) &&
-        (*pKeyword     == 'C') && (*(pKeyword+1) == 'A') &&
-        (*(pKeyword+2) == 'C') && (*(pKeyword+3) == 'H') &&
-        (*(pKeyword+4) == 'E') && (*(pKeyword+5) == 'O') &&
-        (*(pKeyword+6) == 'F') && (*(pKeyword+7) == 'F'))
-    {
-      if (!pData->pFirstaniobj)        /* only if caching hasn't started yet ! */
-      {
-        bOke                  = MNG_TRUE;
-        pData->bCacheplayback = MNG_FALSE;
-        pData->bStorechunks   = MNG_FALSE;
-      }
-    }
-  }
-
-  return bOke;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifndef MNG_SKIPCHUNK_nEED
-READ_CHUNK (mng_read_need)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_NEED, MNG_LC_START);
-#endif
-
-  if (!pData->bHasMHDR)                /* sequence checks */
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-  if (iRawlen < 1)                     /* check the length */
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-  {                                    /* let's check it */
-    mng_bool   bOke = MNG_TRUE;
-    mng_pchar  zKeywords;
-    mng_uint8p pNull, pTemp;
-
-    MNG_ALLOC (pData, zKeywords, iRawlen + 1);
-
-    if (iRawlen)
-      MNG_COPY (zKeywords, pRawdata, iRawlen);
-
-    pTemp = (mng_uint8p)zKeywords;
-    pNull = find_null (pTemp);
-
-    while ((bOke) && (pNull < (mng_uint8p)zKeywords + iRawlen))
-    {
-      bOke  = CheckKeyword (pData, pTemp);
-      pTemp = pNull + 1;
-      pNull = find_null (pTemp);
-    }
-
-    if (bOke)
-      bOke = CheckKeyword (pData, pTemp);
-
-    MNG_FREEX (pData, zKeywords, iRawlen + 1);
-
-    if (!bOke)
-      MNG_ERROR (pData, MNG_UNSUPPORTEDNEED);
-  }
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the fields */
-    ((mng_needp)*ppChunk)->iKeywordssize = iRawlen;
-
-    if (iRawlen)
-    {
-      MNG_ALLOC (pData, ((mng_needp)*ppChunk)->zKeywords, iRawlen+1);
-      MNG_COPY (((mng_needp)*ppChunk)->zKeywords, pRawdata, iRawlen);
-    }
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_NEED, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifndef MNG_SKIPCHUNK_pHYg
-READ_CHUNK (mng_read_phyg)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_PHYG, MNG_LC_START);
-#endif
-
-  if (!pData->bHasMHDR)                /* sequence checks */
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-                                       /* it's 9 bytes or empty; no more, no less! */
-  if ((iRawlen != 9) && (iRawlen != 0))
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-
-
-    /* TODO: something !!! */
-
-
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the fields */
-    ((mng_phygp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
-
-    if (iRawlen)
-    {
-      ((mng_phygp)*ppChunk)->iSizex = mng_get_uint32 (pRawdata);
-      ((mng_phygp)*ppChunk)->iSizey = mng_get_uint32 (pRawdata+4);
-      ((mng_phygp)*ppChunk)->iUnit  = *(pRawdata+8);
-    }
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_PHYG, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_INCLUDE_JNG
-READ_CHUNK (mng_read_jhdr)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_JHDR, MNG_LC_START);
-#endif
-                                       /* sequence checks */
-  if ((pData->eSigtype != mng_it_jng) && (pData->eSigtype != mng_it_mng))
-    MNG_ERROR (pData, MNG_CHUNKNOTALLOWED);
-
-  if ((pData->eSigtype == mng_it_jng) && (pData->iChunkseq > 1))
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-  if (iRawlen != 16)                   /* length oke ? */
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-                                       /* inside a JHDR-IEND block now */
-  pData->bHasJHDR              = MNG_TRUE;
-                                       /* and store interesting fields */
-  pData->iDatawidth            = mng_get_uint32 (pRawdata);
-  pData->iDataheight           = mng_get_uint32 (pRawdata+4);
-  pData->iJHDRcolortype        = *(pRawdata+8);
-  pData->iJHDRimgbitdepth      = *(pRawdata+9);
-  pData->iJHDRimgcompression   = *(pRawdata+10);
-  pData->iJHDRimginterlace     = *(pRawdata+11);
-  pData->iJHDRalphabitdepth    = *(pRawdata+12);
-  pData->iJHDRalphacompression = *(pRawdata+13);
-  pData->iJHDRalphafilter      = *(pRawdata+14);
-  pData->iJHDRalphainterlace   = *(pRawdata+15);
-
-
-#if defined(MNG_NO_1_2_4BIT_SUPPORT) || defined(MNG_NO_16BIT_SUPPORT)
-  pData->iPNGmult = 1;
-  pData->iPNGdepth = pData->iJHDRalphabitdepth;
-#endif
-
-#ifdef MNG_NO_1_2_4BIT_SUPPORT
-  if (pData->iJHDRalphabitdepth < 8)
-    pData->iJHDRalphabitdepth = 8;
-#endif
-
-#ifdef MNG_NO_16BIT_SUPPORT
-  if (pData->iJHDRalphabitdepth > 8)
-  {
-    pData->iPNGmult = 2;
-    pData->iJHDRalphabitdepth = 8;
-  }
-#endif
-                                       /* parameter validity checks */
-  if ((pData->iJHDRcolortype != MNG_COLORTYPE_JPEGGRAY  ) &&
-      (pData->iJHDRcolortype != MNG_COLORTYPE_JPEGCOLOR ) &&
-      (pData->iJHDRcolortype != MNG_COLORTYPE_JPEGGRAYA ) &&
-      (pData->iJHDRcolortype != MNG_COLORTYPE_JPEGCOLORA)    )
-    MNG_ERROR (pData, MNG_INVALIDCOLORTYPE);
-
-  if ((pData->iJHDRimgbitdepth != MNG_BITDEPTH_JPEG8     ) &&
-      (pData->iJHDRimgbitdepth != MNG_BITDEPTH_JPEG12    ) &&
-      (pData->iJHDRimgbitdepth != MNG_BITDEPTH_JPEG8AND12)    )
-    MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
-
-  if (pData->iJHDRimgcompression != MNG_COMPRESSION_BASELINEJPEG)
-    MNG_ERROR (pData, MNG_INVALIDCOMPRESS);
-
-  if ((pData->iJHDRimginterlace != MNG_INTERLACE_SEQUENTIAL ) &&
-      (pData->iJHDRimginterlace != MNG_INTERLACE_PROGRESSIVE)    )
-    MNG_ERROR (pData, MNG_INVALIDINTERLACE);
-
-  if ((pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA ) ||
-      (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA)    )
-  {
-    if ((pData->iJHDRalphabitdepth != MNG_BITDEPTH_8 )
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-        && (pData->iJHDRalphabitdepth != MNG_BITDEPTH_1 ) &&
-        (pData->iJHDRalphabitdepth != MNG_BITDEPTH_2 ) &&
-        (pData->iJHDRalphabitdepth != MNG_BITDEPTH_4 )
-#endif
-#ifndef MNG_NO_16BIT_SUPPORT
-        && (pData->iJHDRalphabitdepth != MNG_BITDEPTH_16)
-#endif
-        )
-      MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
-
-    if ((pData->iJHDRalphacompression != MNG_COMPRESSION_DEFLATE     ) &&
-        (pData->iJHDRalphacompression != MNG_COMPRESSION_BASELINEJPEG)    )
-      MNG_ERROR (pData, MNG_INVALIDCOMPRESS);
-
-    if ((pData->iJHDRalphacompression == MNG_COMPRESSION_BASELINEJPEG) &&
-        (pData->iJHDRalphabitdepth    !=  MNG_BITDEPTH_8             )    )
-      MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
-
-#if defined(FILTER192) || defined(FILTER193)
-    if ((pData->iJHDRalphafilter != MNG_FILTER_ADAPTIVE ) &&
-#if defined(FILTER192) && defined(FILTER193)
-        (pData->iJHDRalphafilter != MNG_FILTER_DIFFERING) &&
-        (pData->iJHDRalphafilter != MNG_FILTER_NOFILTER )    )
-#else
-#ifdef FILTER192
-        (pData->iJHDRalphafilter != MNG_FILTER_DIFFERING)    )
-#else
-        (pData->iJHDRalphafilter != MNG_FILTER_NOFILTER )    )
-#endif
-#endif
-      MNG_ERROR (pData, MNG_INVALIDFILTER);
-#else
-    if (pData->iJHDRalphafilter)
-      MNG_ERROR (pData, MNG_INVALIDFILTER);
-#endif
-
-    if ((pData->iJHDRalphainterlace != MNG_INTERLACE_NONE ) &&
-        (pData->iJHDRalphainterlace != MNG_INTERLACE_ADAM7)    )
-      MNG_ERROR (pData, MNG_INVALIDINTERLACE);
-
-  }
-  else
-  {
-    if (pData->iJHDRalphabitdepth)
-      MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
-
-    if (pData->iJHDRalphacompression)
-      MNG_ERROR (pData, MNG_INVALIDCOMPRESS);
-
-    if (pData->iJHDRalphafilter)
-      MNG_ERROR (pData, MNG_INVALIDFILTER);
-
-    if (pData->iJHDRalphainterlace)
-      MNG_ERROR (pData, MNG_INVALIDINTERLACE);
-
-  }
-
-  if (!pData->bHasheader)              /* first chunk ? */
-  {
-    pData->bHasheader = MNG_TRUE;      /* we've got a header */
-    pData->eImagetype = mng_it_jng;    /* then this must be a JNG */
-    pData->iWidth     = mng_get_uint32 (pRawdata);
-    pData->iHeight    = mng_get_uint32 (pRawdata+4);
-                                       /* predict alpha-depth ! */
-  if ((pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA ) ||
-      (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA)    )
-      pData->iAlphadepth = pData->iJHDRalphabitdepth;
-    else
-      pData->iAlphadepth = 0;
-                                       /* fits on maximum canvas ? */
-    if ((pData->iWidth > pData->iMaxwidth) || (pData->iHeight > pData->iMaxheight))
-      MNG_WARNING (pData, MNG_IMAGETOOLARGE);
-
-    if (pData->fProcessheader)         /* inform the app ? */
-      if (!pData->fProcessheader (((mng_handle)pData), pData->iWidth, pData->iHeight))
-      MNG_ERROR (pData, MNG_APPMISCERROR);
-
-  }
-
-  pData->iColortype = 0;               /* fake grayscale for other routines */
-  pData->iImagelevel++;                /* one level deeper */
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-    mng_retcode iRetcode = mng_process_display_jhdr (pData);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the fields */
-    ((mng_jhdrp)*ppChunk)->iWidth            = mng_get_uint32 (pRawdata);
-    ((mng_jhdrp)*ppChunk)->iHeight           = mng_get_uint32 (pRawdata+4);
-    ((mng_jhdrp)*ppChunk)->iColortype        = *(pRawdata+8);
-    ((mng_jhdrp)*ppChunk)->iImagesampledepth = *(pRawdata+9);
-    ((mng_jhdrp)*ppChunk)->iImagecompression = *(pRawdata+10);
-    ((mng_jhdrp)*ppChunk)->iImageinterlace   = *(pRawdata+11);
-    ((mng_jhdrp)*ppChunk)->iAlphasampledepth = *(pRawdata+12);
-#ifdef MNG_NO_16BIT_SUPPORT
-    if (*(pRawdata+12) > 8)
-        ((mng_jhdrp)*ppChunk)->iAlphasampledepth = 8;
-#endif
-    ((mng_jhdrp)*ppChunk)->iAlphacompression = *(pRawdata+13);
-    ((mng_jhdrp)*ppChunk)->iAlphafilter      = *(pRawdata+14);
-    ((mng_jhdrp)*ppChunk)->iAlphainterlace   = *(pRawdata+15);
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_JHDR, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#else
-#define read_jhdr 0
-#endif /* MNG_INCLUDE_JNG */
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_INCLUDE_JNG
-READ_CHUNK (mng_read_jdaa)
-{
-#if defined(MNG_SUPPORT_DISPLAY) || defined(MNG_STORE_CHUNKS)
-  volatile mng_retcode iRetcode;
-
-  iRetcode=MNG_NOERROR;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_JDAA, MNG_LC_START);
-#endif
-                                       /* sequence checks */
-  if ((!pData->bHasJHDR) && (!pData->bHasDHDR))
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-  if (pData->bHasJSEP)
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-    
-  if (pData->iJHDRalphacompression != MNG_COMPRESSION_BASELINEJPEG)
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-  if (iRawlen == 0)                    /* can never be empty */
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-  pData->bHasJDAA = MNG_TRUE;          /* got some JDAA now, don't we */
-
-#ifdef MNG_SUPPORT_DISPLAY
-  iRetcode = mng_process_display_jdaa (pData, iRawlen, pRawdata);
-
-  if (iRetcode)                      /* on error bail out */
-    return iRetcode;
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the fields */
-    ((mng_jdaap)*ppChunk)->bEmpty    = (mng_bool)(iRawlen == 0);
-    ((mng_jdaap)*ppChunk)->iDatasize = iRawlen;
-
-    if (iRawlen != 0)                  /* is there any data ? */
-    {
-      MNG_ALLOC (pData, ((mng_jdaap)*ppChunk)->pData, iRawlen);
-      MNG_COPY  (((mng_jdaap)*ppChunk)->pData, pRawdata, iRawlen);
-    }
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_JDAA, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#else
-#define read_jdaa 0
-#endif /* MNG_INCLUDE_JNG */
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_INCLUDE_JNG
-READ_CHUNK (mng_read_jdat)
-{
-#if defined(MNG_SUPPORT_DISPLAY) || defined(MNG_STORE_CHUNKS)
-  volatile mng_retcode iRetcode;
-
-  iRetcode=MNG_NOERROR;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_JDAT, MNG_LC_START);
-#endif
-                                       /* sequence checks */
-  if ((!pData->bHasJHDR) && (!pData->bHasDHDR))
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-  if (iRawlen == 0)                    /* can never be empty */
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-  pData->bHasJDAT = MNG_TRUE;          /* got some JDAT now, don't we */
-
-#ifdef MNG_SUPPORT_DISPLAY
-  iRetcode = mng_process_display_jdat (pData, iRawlen, pRawdata);
-
-  if (iRetcode)                      /* on error bail out */
-    return iRetcode;
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the fields */
-    ((mng_jdatp)*ppChunk)->bEmpty    = (mng_bool)(iRawlen == 0);
-    ((mng_jdatp)*ppChunk)->iDatasize = iRawlen;
-
-    if (iRawlen != 0)                  /* is there any data ? */
-    {
-      MNG_ALLOC (pData, ((mng_jdatp)*ppChunk)->pData, iRawlen);
-      MNG_COPY  (((mng_jdatp)*ppChunk)->pData, pRawdata, iRawlen);
-    }
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_JDAT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#else
-#define read_jdat 0
-#endif /* MNG_INCLUDE_JNG */
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_INCLUDE_JNG
-READ_CHUNK (mng_read_jsep)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_JSEP, MNG_LC_START);
-#endif
-
-  if (!pData->bHasJHDR)                /* sequence checks */
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-  if (iRawlen != 0)                    /* must be empty ! */
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-  pData->bHasJSEP = MNG_TRUE;          /* indicate we've had the 8-/12-bit separator */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_JSEP, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#else
-#define read_jsep 0
-#endif /* MNG_INCLUDE_JNG */
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifndef MNG_NO_DELTA_PNG
-READ_CHUNK (mng_read_dhdr)
-{
-  mng_uint8 iImagetype, iDeltatype;
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_DHDR, MNG_LC_START);
-#endif
-
-  if (!pData->bHasMHDR)                /* sequence checks */
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-  if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-                                       /* check for valid length */
-  if ((iRawlen != 4) && (iRawlen != 12) && (iRawlen != 20))
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-  iImagetype = *(pRawdata+2);          /* check fields for validity */
-  iDeltatype = *(pRawdata+3);
-
-  if (iImagetype > MNG_IMAGETYPE_JNG)
-    MNG_ERROR (pData, MNG_INVIMAGETYPE);
-
-  if (iDeltatype > MNG_DELTATYPE_NOCHANGE)
-    MNG_ERROR (pData, MNG_INVDELTATYPE);
-
-  if ((iDeltatype == MNG_DELTATYPE_REPLACE) && (iRawlen > 12))
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-  if ((iDeltatype == MNG_DELTATYPE_NOCHANGE) && (iRawlen > 4))
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-  pData->bHasDHDR   = MNG_TRUE;        /* inside a DHDR-IEND block now */
-  pData->iDeltatype = iDeltatype;
-
-  pData->iImagelevel++;                /* one level deeper */
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-    mng_uint16  iObjectid    = mng_get_uint16 (pRawdata);
-    mng_uint32  iBlockwidth  = 0;
-    mng_uint32  iBlockheight = 0;
-    mng_uint32  iBlockx      = 0;
-    mng_uint32  iBlocky      = 0;
-    mng_retcode iRetcode;
-
-    if (iRawlen > 4)
-    {
-      iBlockwidth  = mng_get_uint32 (pRawdata+4);
-      iBlockheight = mng_get_uint32 (pRawdata+8);
-    }
-
-    if (iRawlen > 12)
-    {
-      iBlockx      = mng_get_uint32 (pRawdata+12);
-      iBlocky      = mng_get_uint32 (pRawdata+16);
-    }
-
-    iRetcode = mng_create_ani_dhdr (pData, iObjectid, iImagetype, iDeltatype,
-                                    iBlockwidth, iBlockheight, iBlockx, iBlocky);
-
-/*    if (!iRetcode)
-      iRetcode = mng_process_display_dhdr (pData, iObjectid, iImagetype, iDeltatype,
-                                           iBlockwidth, iBlockheight, iBlockx, iBlocky); */
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the fields */
-    ((mng_dhdrp)*ppChunk)->iObjectid      = mng_get_uint16 (pRawdata);
-    ((mng_dhdrp)*ppChunk)->iImagetype     = iImagetype;
-    ((mng_dhdrp)*ppChunk)->iDeltatype     = iDeltatype;
-
-    if (iRawlen > 4)
-    {
-      ((mng_dhdrp)*ppChunk)->iBlockwidth  = mng_get_uint32 (pRawdata+4);
-      ((mng_dhdrp)*ppChunk)->iBlockheight = mng_get_uint32 (pRawdata+8);
-    }
-
-    if (iRawlen > 12)
-    {
-      ((mng_dhdrp)*ppChunk)->iBlockx      = mng_get_uint32 (pRawdata+12);
-      ((mng_dhdrp)*ppChunk)->iBlocky      = mng_get_uint32 (pRawdata+16);
-    }
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_DHDR, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifndef MNG_NO_DELTA_PNG
-READ_CHUNK (mng_read_prom)
-{
-  mng_uint8 iColortype;
-  mng_uint8 iSampledepth;
-  mng_uint8 iFilltype;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_PROM, MNG_LC_START);
-#endif
-                                       /* sequence checks */
-  if ((!pData->bHasMHDR) || (!pData->bHasDHDR))
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-  if (iRawlen != 3)                    /* gotta be exactly 3 bytes */
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-  iColortype   = *pRawdata;            /* check fields for validity */
-  iSampledepth = *(pRawdata+1);
-  iFilltype    = *(pRawdata+2);
-
-  if ((iColortype != MNG_COLORTYPE_GRAY   ) &&
-      (iColortype != MNG_COLORTYPE_RGB    ) &&
-      (iColortype != MNG_COLORTYPE_INDEXED) &&
-      (iColortype != MNG_COLORTYPE_GRAYA  ) &&
-      (iColortype != MNG_COLORTYPE_RGBA   )    )
-    MNG_ERROR (pData, MNG_INVALIDCOLORTYPE);
-
-#ifdef MNG_NO_16BIT_SUPPORT
-  if (iSampledepth == MNG_BITDEPTH_16 )
-      iSampledepth = MNG_BITDEPTH_8;
-#endif
-
-  if ((iSampledepth != MNG_BITDEPTH_1 ) &&
-      (iSampledepth != MNG_BITDEPTH_2 ) &&
-      (iSampledepth != MNG_BITDEPTH_4 ) &&
-      (iSampledepth != MNG_BITDEPTH_8 )
-#ifndef MNG_NO_16BIT_SUPPORT
-      && (iSampledepth != MNG_BITDEPTH_16)
-#endif
-    )
-    MNG_ERROR (pData, MNG_INVSAMPLEDEPTH);
-
-  if ((iFilltype != MNG_FILLMETHOD_LEFTBITREPLICATE) &&
-      (iFilltype != MNG_FILLMETHOD_ZEROFILL        )    )
-    MNG_ERROR (pData, MNG_INVFILLMETHOD);
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-    mng_retcode iRetcode = mng_create_ani_prom (pData, iSampledepth,
-                                                iColortype, iFilltype);
-
-/*    if (!iRetcode)
-      iRetcode = mng_process_display_prom (pData, iSampledepth,
-                                           iColortype, iFilltype); */
-                                           
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the fields */
-    ((mng_promp)*ppChunk)->iColortype   = iColortype;
-    ((mng_promp)*ppChunk)->iSampledepth = iSampledepth;
-    ((mng_promp)*ppChunk)->iFilltype    = iFilltype;
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_PROM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifndef MNG_NO_DELTA_PNG
-READ_CHUNK (mng_read_ipng)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_IPNG, MNG_LC_START);
-#endif
-                                       /* sequence checks */
-  if ((!pData->bHasMHDR) || (!pData->bHasDHDR))
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-  if (iRawlen != 0)                    /* gotta be empty */
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-    mng_retcode iRetcode = mng_create_ani_ipng (pData);
-
-    if (!iRetcode)
-      iRetcode = mng_process_display_ipng (pData);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_IPNG, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifndef MNG_NO_DELTA_PNG
-READ_CHUNK (mng_read_pplt)
-{
-  mng_uint8     iDeltatype;
-  mng_uint8p    pTemp;
-  mng_uint32    iLen;
-  mng_uint8     iX, iM;
-  mng_uint32    iY;
-  mng_uint32    iMax;
-  mng_rgbpaltab aIndexentries;
-  mng_uint8arr  aAlphaentries;
-  mng_uint8arr  aUsedentries;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_PPLT, MNG_LC_START);
-#endif
-                                       /* sequence checks */
-  if ((!pData->bHasMHDR) && (!pData->bHasDHDR))
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-  if (iRawlen < 1)                     /* must have at least 1 byte */
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-  iDeltatype = *pRawdata;
-                                       /* valid ? */
-  if (iDeltatype > MNG_DELTATYPE_DELTARGBA)
-    MNG_ERROR (pData, MNG_INVDELTATYPE);
-                                       /* must be indexed color ! */
-  if (pData->iColortype != MNG_COLORTYPE_INDEXED)
-    MNG_ERROR (pData, MNG_INVALIDCOLORTYPE);
-
-  pTemp = pRawdata + 1;
-  iLen  = iRawlen - 1;
-  iMax  = 0;
-
-  for (iY = 0; iY < 256; iY++)         /* reset arrays */
-  {
-    aIndexentries [iY].iRed   = 0;
-    aIndexentries [iY].iGreen = 0;
-    aIndexentries [iY].iBlue  = 0;
-    aAlphaentries [iY]        = 255;
-    aUsedentries  [iY]        = 0;
-  }
-
-  while (iLen)                         /* as long as there are entries left ... */
-  {
-    mng_uint32 iDiff;
-
-    if (iLen < 2)
-      MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-    iX = *pTemp;                       /* get start and end index */
-    iM = *(pTemp+1);
-
-    if (iM < iX)
-      MNG_ERROR (pData, MNG_INVALIDINDEX);
-
-    if ((mng_uint32)iM >= iMax)        /* determine highest used index */
-      iMax = (mng_uint32)iM + 1;
-
-    pTemp += 2;
-    iLen  -= 2;
-    iDiff = (iM - iX + 1);
-    if ((iDeltatype == MNG_DELTATYPE_REPLACERGB  ) ||
-        (iDeltatype == MNG_DELTATYPE_DELTARGB    )    )
-      iDiff = iDiff * 3;
-    else
-    if ((iDeltatype == MNG_DELTATYPE_REPLACERGBA) ||
-        (iDeltatype == MNG_DELTATYPE_DELTARGBA  )    )
-      iDiff = iDiff * 4;
-
-    if (iLen < iDiff)
-      MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-    if ((iDeltatype == MNG_DELTATYPE_REPLACERGB  ) ||
-        (iDeltatype == MNG_DELTATYPE_DELTARGB    )    )
-    {
-      for (iY = (mng_uint32)iX; iY <= (mng_uint32)iM; iY++)
-      {
-        aIndexentries [iY].iRed   = *pTemp;
-        aIndexentries [iY].iGreen = *(pTemp+1);
-        aIndexentries [iY].iBlue  = *(pTemp+2);
-        aUsedentries  [iY]        = 1;
-
-        pTemp += 3;
-        iLen  -= 3;
-      }
-    }
-    else
-    if ((iDeltatype == MNG_DELTATYPE_REPLACEALPHA) ||
-        (iDeltatype == MNG_DELTATYPE_DELTAALPHA  )    )
-    {
-      for (iY = (mng_uint32)iX; iY <= (mng_uint32)iM; iY++)
-      {
-        aAlphaentries [iY]        = *pTemp;
-        aUsedentries  [iY]        = 1;
-
-        pTemp++;
-        iLen--;
-      }
-    }
-    else
-    {
-      for (iY = (mng_uint32)iX; iY <= (mng_uint32)iM; iY++)
-      {
-        aIndexentries [iY].iRed   = *pTemp;
-        aIndexentries [iY].iGreen = *(pTemp+1);
-        aIndexentries [iY].iBlue  = *(pTemp+2);
-        aAlphaentries [iY]        = *(pTemp+3);
-        aUsedentries  [iY]        = 1;
-
-        pTemp += 4;
-        iLen  -= 4;
-      }
-    }
-  }
-
-  switch (pData->iBitdepth)            /* check maximum allowed entries for bitdepth */
-  {
-    case MNG_BITDEPTH_1 : {
-                            if (iMax > 2)
-                              MNG_ERROR (pData, MNG_INVALIDINDEX);
-                            break;
-                          }
-    case MNG_BITDEPTH_2 : {
-                            if (iMax > 4)
-                              MNG_ERROR (pData, MNG_INVALIDINDEX);
-                            break;
-                          }
-    case MNG_BITDEPTH_4 : {
-                            if (iMax > 16)
-                              MNG_ERROR (pData, MNG_INVALIDINDEX);
-                            break;
-                          }
-  }
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {                                    /* create animation object */
-    mng_retcode iRetcode = mng_create_ani_pplt (pData, iDeltatype, iMax,
-                                                aIndexentries, aAlphaentries,
-                                                aUsedentries);
-
-/*    if (!iRetcode)
-      iRetcode = mng_process_display_pplt (pData, iDeltatype, iMax, aIndexentries,
-                                           aAlphaentries, aUsedentries); */
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the fields */
-    ((mng_ppltp)*ppChunk)->iDeltatype = iDeltatype;
-    ((mng_ppltp)*ppChunk)->iCount     = iMax;
-
-    for (iY = 0; iY < 256; iY++)
-    {
-      ((mng_ppltp)*ppChunk)->aEntries [iY].iRed   = aIndexentries [iY].iRed;
-      ((mng_ppltp)*ppChunk)->aEntries [iY].iGreen = aIndexentries [iY].iGreen;
-      ((mng_ppltp)*ppChunk)->aEntries [iY].iBlue  = aIndexentries [iY].iBlue;
-      ((mng_ppltp)*ppChunk)->aEntries [iY].iAlpha = aAlphaentries [iY];
-      ((mng_ppltp)*ppChunk)->aEntries [iY].bUsed  = (mng_bool)(aUsedentries [iY]);
-    }
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_PPLT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifndef MNG_NO_DELTA_PNG
-#ifdef MNG_INCLUDE_JNG
-READ_CHUNK (mng_read_ijng)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_IJNG, MNG_LC_START);
-#endif
-                                       /* sequence checks */
-  if ((!pData->bHasMHDR) || (!pData->bHasDHDR))
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-  if (iRawlen != 0)                    /* gotta be empty */
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-    mng_retcode iRetcode = mng_create_ani_ijng (pData);
-
-    if (!iRetcode)
-      iRetcode = mng_process_display_ijng (pData);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_IJNG, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifndef MNG_NO_DELTA_PNG
-READ_CHUNK (mng_read_drop)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_DROP, MNG_LC_START);
-#endif
-                                       /* sequence checks */
-  if ((!pData->bHasMHDR) || (!pData->bHasDHDR))
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-                                       /* check length */
-  if ((iRawlen < 4) || ((iRawlen % 4) != 0))
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-
-
-    /* TODO: something !!! */
-
-
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the fields */
-    ((mng_dropp)*ppChunk)->iCount = iRawlen / 4;
-
-    if (iRawlen)
-    {
-      mng_uint32      iX;
-      mng_uint8p      pTemp = pRawdata;
-      mng_uint32p     pEntry;
-
-      MNG_ALLOC (pData, pEntry, iRawlen);
-
-      ((mng_dropp)*ppChunk)->pChunknames = (mng_ptr)pEntry;
-
-      for (iX = 0; iX < iRawlen / 4; iX++)
-      {
-        *pEntry = mng_get_uint32 (pTemp);
-
-        pTemp  += 4;
-        pEntry++;
-      }
-    }
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_DROP, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_SKIPCHUNK_DBYK
-READ_CHUNK (mng_read_dbyk)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_DBYK, MNG_LC_START);
-#endif
-                                       /* sequence checks */
-  if ((!pData->bHasMHDR) || (!pData->bHasDHDR))
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-  if (iRawlen < 6)                     /* must be at least 6 long */
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-
-
-    /* TODO: something !!! */
-
-
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the fields */
-    ((mng_dbykp)*ppChunk)->iChunkname    = mng_get_uint32 (pRawdata);
-    ((mng_dbykp)*ppChunk)->iPolarity     = *(pRawdata+4);
-    ((mng_dbykp)*ppChunk)->iKeywordssize = iRawlen - 5;
-
-    if (iRawlen > 5)
-    {
-      MNG_ALLOC (pData, ((mng_dbykp)*ppChunk)->zKeywords, iRawlen-4);
-      MNG_COPY (((mng_dbykp)*ppChunk)->zKeywords, pRawdata+5, iRawlen-5);
-    }
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_DBYK, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_SKIPCHUNK_ORDR
-READ_CHUNK (mng_read_ordr)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_ORDR, MNG_LC_START);
-#endif
-                                       /* sequence checks */
-  if ((!pData->bHasMHDR) || (!pData->bHasDHDR))
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-                                       /* check length */
-  if ((iRawlen < 5) || ((iRawlen % 5) != 0))
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-
-
-    /* TODO: something !!! */
-
-
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the fields */
-    ((mng_ordrp)*ppChunk)->iCount = iRawlen / 5;
-
-    if (iRawlen)
-    {
-      mng_uint32      iX;
-      mng_ordr_entryp pEntry;
-      mng_uint8p      pTemp = pRawdata;
-      
-      MNG_ALLOC (pData, pEntry, iRawlen);
-
-      ((mng_ordrp)*ppChunk)->pEntries = pEntry;
-
-      for (iX = 0; iX < iRawlen / 5; iX++)
-      {
-        pEntry->iChunkname = mng_get_uint32 (pTemp);
-        pEntry->iOrdertype = *(pTemp+4);
-
-        pTemp += 5;
-        pEntry++;
-      }
-    }
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_ORDR, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifndef MNG_SKIPCHUNK_MAGN
-READ_CHUNK (mng_read_magn)
-{
-  mng_uint16 iFirstid, iLastid;
-  mng_uint8  iMethodX, iMethodY;
-  mng_uint16 iMX, iMY, iML, iMR, iMT, iMB;
-  mng_bool   bFaulty;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_MAGN, MNG_LC_START);
-#endif
-                                       /* sequence checks */
-#ifdef MNG_SUPPORT_JNG
-  if ((!pData->bHasMHDR) || (pData->bHasIHDR) || (pData->bHasDHDR) || (pData->bHasJHDR))
-#else
-  if ((!pData->bHasMHDR) || (pData->bHasIHDR) || (pData->bHasDHDR))
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-                                       /* check length */
-  if (iRawlen > 20)
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-  /* following is an ugly hack to allow faulty layout caused by previous
-     versions of libmng and MNGeye, which wrote MAGN with a 16-bit
-     MethodX/MethodY (as opposed to the proper 8-bit as defined in the spec!) */
-
-  if ((iRawlen ==  6) || (iRawlen ==  8) || (iRawlen == 10) || (iRawlen == 12) ||
-      (iRawlen == 14) || (iRawlen == 16) || (iRawlen == 20))
-    bFaulty = MNG_TRUE;                /* these lengths are all wrong */
-  else                                 /* length 18 can be right or wrong !!! */
-  if ((iRawlen ==  18) && (mng_get_uint16 (pRawdata+4) <= 5) &&
-      (mng_get_uint16 (pRawdata+6)  < 256) &&
-      (mng_get_uint16 (pRawdata+8)  < 256) &&
-      (mng_get_uint16 (pRawdata+10) < 256) &&
-      (mng_get_uint16 (pRawdata+12) < 256) &&
-      (mng_get_uint16 (pRawdata+14) < 256) &&
-      (mng_get_uint16 (pRawdata+16) < 256))
-    bFaulty = MNG_TRUE;                /* this is very likely the wrong layout */
-  else
-    bFaulty = MNG_FALSE;               /* all other cases are handled as right */
-
-  if (bFaulty)                         /* wrong layout ? */
-  {
-    if (iRawlen > 0)                   /* get the fields */
-      iFirstid = mng_get_uint16 (pRawdata);
-    else
-      iFirstid = 0;
-
-    if (iRawlen > 2)
-      iLastid  = mng_get_uint16 (pRawdata+2);
-    else
-      iLastid  = iFirstid;
-
-    if (iRawlen > 4)
-      iMethodX = (mng_uint8)(mng_get_uint16 (pRawdata+4));
-    else
-      iMethodX = 0;
-
-    if (iRawlen > 6)
-      iMX      = mng_get_uint16 (pRawdata+6);
-    else
-      iMX      = 1;
-
-    if (iRawlen > 8)
-      iMY      = mng_get_uint16 (pRawdata+8);
-    else
-      iMY      = iMX;
-
-    if (iRawlen > 10)
-      iML      = mng_get_uint16 (pRawdata+10);
-    else
-      iML      = iMX;
-
-    if (iRawlen > 12)
-      iMR      = mng_get_uint16 (pRawdata+12);
-    else
-      iMR      = iMX;
-
-    if (iRawlen > 14)
-      iMT      = mng_get_uint16 (pRawdata+14);
-    else
-      iMT      = iMY;
-
-    if (iRawlen > 16)
-      iMB      = mng_get_uint16 (pRawdata+16);
-    else
-      iMB      = iMY;
-
-    if (iRawlen > 18)
-      iMethodY = (mng_uint8)(mng_get_uint16 (pRawdata+18));
-    else
-      iMethodY = iMethodX;
-  }
-  else                                 /* proper layout !!!! */
-  {
-    if (iRawlen > 0)                   /* get the fields */
-      iFirstid = mng_get_uint16 (pRawdata);
-    else
-      iFirstid = 0;
-
-    if (iRawlen > 2)
-      iLastid  = mng_get_uint16 (pRawdata+2);
-    else
-      iLastid  = iFirstid;
-
-    if (iRawlen > 4)
-      iMethodX = *(pRawdata+4);
-    else
-      iMethodX = 0;
-
-    if (iRawlen > 5)
-      iMX      = mng_get_uint16 (pRawdata+5);
-    else
-      iMX      = 1;
-
-    if (iRawlen > 7)
-      iMY      = mng_get_uint16 (pRawdata+7);
-    else
-      iMY      = iMX;
-
-    if (iRawlen > 9)
-      iML      = mng_get_uint16 (pRawdata+9);
-    else
-      iML      = iMX;
-
-    if (iRawlen > 11)
-      iMR      = mng_get_uint16 (pRawdata+11);
-    else
-      iMR      = iMX;
-
-    if (iRawlen > 13)
-      iMT      = mng_get_uint16 (pRawdata+13);
-    else
-      iMT      = iMY;
-
-    if (iRawlen > 15)
-      iMB      = mng_get_uint16 (pRawdata+15);
-    else
-      iMB      = iMY;
-
-    if (iRawlen > 17)
-      iMethodY = *(pRawdata+17);
-    else
-      iMethodY = iMethodX;
-  }
-                                       /* check field validity */
-  if ((iMethodX > 5) || (iMethodY > 5))
-    MNG_ERROR (pData, MNG_INVALIDMETHOD);
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-    mng_retcode iRetcode;
-
-    iRetcode = mng_create_ani_magn (pData, iFirstid, iLastid, iMethodX,
-                                    iMX, iMY, iML, iMR, iMT, iMB, iMethodY);
-
-/*    if (!iRetcode)
-      iRetcode = mng_process_display_magn (pData, iFirstid, iLastid, iMethodX,
-                                           iMX, iMY, iML, iMR, iMT, iMB, iMethodY); */
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the fields */
-    ((mng_magnp)*ppChunk)->iFirstid = iFirstid;
-    ((mng_magnp)*ppChunk)->iLastid  = iLastid;
-    ((mng_magnp)*ppChunk)->iMethodX = iMethodX;
-    ((mng_magnp)*ppChunk)->iMX      = iMX;
-    ((mng_magnp)*ppChunk)->iMY      = iMY;
-    ((mng_magnp)*ppChunk)->iML      = iML;
-    ((mng_magnp)*ppChunk)->iMR      = iMR;
-    ((mng_magnp)*ppChunk)->iMT      = iMT;
-    ((mng_magnp)*ppChunk)->iMB      = iMB;
-    ((mng_magnp)*ppChunk)->iMethodY = iMethodY;
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_MAGN, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-READ_CHUNK (mng_read_mpng)
-{
-  mng_uint32  iFramewidth;
-  mng_uint32  iFrameheight;
-  mng_uint16  iTickspersec;
-  mng_uint32  iFramessize;
-  mng_uint32  iCompressedsize;
-#if defined(MNG_SUPPORT_DISPLAY) || defined(MNG_STORE_CHUNKS)
-  mng_retcode iRetcode;
-  mng_uint16  iNumplays;
-  mng_uint32  iBufsize;
-  mng_uint8p  pBuf = 0;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_MPNG, MNG_LC_START);
-#endif
-                                       /* sequence checks */
-  if (!pData->bHasIHDR)
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-  if (iRawlen < 41)                    /* length must be at least 41 */
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-  iFramewidth     = mng_get_int32 (pRawdata);
-  if (iFramewidth == 0)                /* frame_width must not be zero */
-    MNG_ERROR (pData, MNG_INVALIDWIDTH);
-
-  iFrameheight    = mng_get_int32 (pRawdata+4);
-  if (iFrameheight == 0)               /* frame_height must not be zero */
-    MNG_ERROR (pData, MNG_INVALIDHEIGHT);
-
-  iTickspersec    = mng_get_uint16 (pRawdata+10);
-  if (iTickspersec == 0)               /* delay_den must not be zero */
-    MNG_ERROR (pData, MNG_INVALIDFIELDVAL);
-
-  if (*(pRawdata+12) != 0)             /* only deflate compression-method allowed */
-    MNG_ERROR (pData, MNG_INVALIDCOMPRESS);
-
-#if defined(MNG_SUPPORT_DISPLAY) || defined(MNG_STORE_CHUNKS)
-  iNumplays       = mng_get_uint16 (pRawdata+8);
-  iCompressedsize = (mng_uint32)(iRawlen - 13);
-#endif
-
-#ifdef MNG_SUPPORT_DISPLAY
-  {
-    iRetcode = mng_inflate_buffer (pData, pRawdata+13, iCompressedsize,
-                                   &pBuf, &iBufsize, &iFramessize);
-    if (iRetcode)                    /* on error bail out */
-    {
-      MNG_FREEX (pData, pBuf, iBufsize);
-      return iRetcode;
-    }
-
-    if (iFramessize % 26)
-    {
-      MNG_FREEX (pData, pBuf, iBufsize);
-      MNG_ERROR (pData, MNG_INVALIDLENGTH);
-    }
-
-    iRetcode = mng_create_mpng_obj (pData, iFramewidth, iFrameheight, iNumplays,
-                                    iTickspersec, iFramessize, pBuf);
-    if (iRetcode)                      /* on error bail out */
-    {
-      MNG_FREEX (pData, pBuf, iBufsize);
-      return iRetcode;
-    }
-  }
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the fields */
-    ((mng_mpngp)*ppChunk)->iFramewidth        = iFramewidth;
-    ((mng_mpngp)*ppChunk)->iFrameheight       = iFrameheight;
-    ((mng_mpngp)*ppChunk)->iNumplays          = iNumplays;
-    ((mng_mpngp)*ppChunk)->iTickspersec       = iTickspersec;
-    ((mng_mpngp)*ppChunk)->iCompressionmethod = *(pRawdata+14);
-
-#ifndef MNG_SUPPORT_DISPLAY
-    iRetcode = mng_inflate_buffer (pData, pRawdata+13, iCompressedsize,
-                                   &pBuf, &iBufsize, &iFramessize);
-    if (iRetcode)                    /* on error bail out */
-    {
-      MNG_FREEX (pData, pBuf, iBufsize);
-      return iRetcode;
-    }
-
-    if (iFramessize % 26)
-    {
-      MNG_FREEX (pData, pBuf, iBufsize);
-      MNG_ERROR (pData, MNG_INVALIDLENGTH);
-    }
-#endif
-
-    if (iFramessize)
-    {
-      MNG_ALLOCX (pData, ((mng_mpngp)*ppChunk)->pFrames, iFramessize);
-      if (((mng_mpngp)*ppChunk)->pFrames == 0)
-      {
-        MNG_FREEX (pData, pBuf, iBufsize);
-        MNG_ERROR (pData, MNG_OUTOFMEMORY);
-      }
-
-      ((mng_mpngp)*ppChunk)->iFramessize = iFramessize;
-      MNG_COPY (((mng_mpngp)*ppChunk)->pFrames, pBuf, iFramessize);
-    }
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#if defined(MNG_SUPPORT_DISPLAY) || defined(MNG_STORE_CHUNKS)
-  MNG_FREEX (pData, pBuf, iBufsize);
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_MPNG, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifndef MNG_SKIPCHUNK_evNT
-READ_CHUNK (mng_read_evnt)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_EVNT, MNG_LC_START);
-#endif
-                                       /* sequence checks */
-  if ((!pData->bHasMHDR) || (pData->bHasSAVE))
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-
-  if (iRawlen < 2)                     /* must have at least 1 entry ! */
-    MNG_ERROR (pData, MNG_INVALIDLENGTH);
-
-#if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_SUPPORT_DYNAMICMNG)
-  {
-    if (iRawlen)                       /* not empty ? */
-    {
-      mng_retcode iRetcode;
-      mng_uint8p  pTemp;
-      mng_uint8p  pNull;
-      mng_uint32  iLen;
-      mng_uint8   iEventtype;
-      mng_uint8   iMasktype;
-      mng_int32   iLeft;
-      mng_int32   iRight;
-      mng_int32   iTop;
-      mng_int32   iBottom;
-      mng_uint16  iObjectid;
-      mng_uint8   iIndex;
-      mng_uint32  iNamesize;
-
-      pTemp = pRawdata;
-      iLen  = iRawlen;
-
-      while (iLen)                   /* anything left ? */
-      {
-        iEventtype = *pTemp;         /* eventtype */
-        if (iEventtype > 5)
-          MNG_ERROR (pData, MNG_INVALIDEVENT);
-
-        pTemp++;
-
-        iMasktype  = *pTemp;         /* masktype */
-        if (iMasktype > 5)
-          MNG_ERROR (pData, MNG_INVALIDMASK);
-
-        pTemp++;
-        iLen -= 2;
-
-        iLeft     = 0;
-        iRight    = 0;
-        iTop      = 0;
-        iBottom   = 0;
-        iObjectid = 0;
-        iIndex    = 0;
-
-        switch (iMasktype)
-        {
-          case 1 :
-            {
-              if (iLen > 16)
-              {
-                iLeft     = mng_get_int32 (pTemp);
-                iRight    = mng_get_int32 (pTemp+4);
-                iTop      = mng_get_int32 (pTemp+8);
-                iBottom   = mng_get_int32 (pTemp+12);
-                pTemp += 16;
-                iLen -= 16;
-              }
-              else
-                MNG_ERROR (pData, MNG_INVALIDLENGTH);
-              break;
-            }
-          case 2 :
-            {
-              if (iLen > 2)
-              {
-                iObjectid = mng_get_uint16 (pTemp);
-                pTemp += 2;
-                iLen -= 2;
-              }
-              else
-                MNG_ERROR (pData, MNG_INVALIDLENGTH);
-              break;
-            }
-          case 3 :
-            {
-              if (iLen > 3)
-              {
-                iObjectid = mng_get_uint16 (pTemp);
-                iIndex    = *(pTemp+2);
-                pTemp += 3;
-                iLen -= 3;
-              }
-              else
-                MNG_ERROR (pData, MNG_INVALIDLENGTH);
-              break;
-            }
-          case 4 :
-            {
-              if (iLen > 18)
-              {
-                iLeft     = mng_get_int32 (pTemp);
-                iRight    = mng_get_int32 (pTemp+4);
-                iTop      = mng_get_int32 (pTemp+8);
-                iBottom   = mng_get_int32 (pTemp+12);
-                iObjectid = mng_get_uint16 (pTemp+16);
-                pTemp += 18;
-                iLen -= 18;
-              }
-              else
-                MNG_ERROR (pData, MNG_INVALIDLENGTH);
-              break;
-            }
-          case 5 :
-            {
-              if (iLen > 19)
-              {
-                iLeft     = mng_get_int32 (pTemp);
-                iRight    = mng_get_int32 (pTemp+4);
-                iTop      = mng_get_int32 (pTemp+8);
-                iBottom   = mng_get_int32 (pTemp+12);
-                iObjectid = mng_get_uint16 (pTemp+16);
-                iIndex    = *(pTemp+18);
-                pTemp += 19;
-                iLen -= 19;
-              }
-              else
-                MNG_ERROR (pData, MNG_INVALIDLENGTH);
-              break;
-            }
-        }
-
-        pNull = find_null (pTemp);   /* get the name length */
-
-        if ((pNull - pTemp) > (mng_int32)iLen)
-        {
-          iNamesize = iLen;          /* no null found; so end of evNT */
-          iLen      = 0;
-        }
-        else
-        {
-          iNamesize = pNull - pTemp; /* should be another entry */
-          iLen      = iLen - iNamesize - 1;
-
-          if (!iLen)                 /* must not end with a null ! */
-            MNG_ERROR (pData, MNG_ENDWITHNULL);
-        }
-
-        iRetcode = mng_create_event (pData, iEventtype, iMasktype, iLeft, iRight,
-                                            iTop, iBottom, iObjectid, iIndex,
-                                            iNamesize, (mng_pchar)pTemp);
-
-        if (iRetcode)                 /* on error bail out */
-          return iRetcode;
-
-        pTemp = pTemp + iNamesize + 1;
-      }
-    }
-  }
-#endif /* MNG_SUPPORT_DISPLAY && MNG_SUPPORT_DYNAMICMNG */
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-
-    if (iRawlen)                       /* not empty ? */
-    {
-      mng_uint32      iX;
-      mng_uint32      iCount = 0;
-      mng_uint8p      pTemp;
-      mng_uint8p      pNull;
-      mng_uint32      iLen;
-      mng_uint8       iEventtype;
-      mng_uint8       iMasktype;
-      mng_int32       iLeft;
-      mng_int32       iRight;
-      mng_int32       iTop;
-      mng_int32       iBottom;
-      mng_uint16      iObjectid;
-      mng_uint8       iIndex;
-      mng_uint32      iNamesize;
-      mng_evnt_entryp pEntry = MNG_NULL;
-
-      for (iX = 0; iX < 2; iX++)       /* do this twice to get the count first ! */
-      {
-        pTemp = pRawdata;
-        iLen  = iRawlen;
-
-        if (iX)                        /* second run ? */
-        {
-          MNG_ALLOC (pData, pEntry, (iCount * sizeof (mng_evnt_entry)));
-
-          ((mng_evntp)*ppChunk)->iCount   = iCount;
-          ((mng_evntp)*ppChunk)->pEntries = pEntry;
-        }
-
-        while (iLen)                   /* anything left ? */
-        {
-          iEventtype = *pTemp;         /* eventtype */
-          if (iEventtype > 5)
-            MNG_ERROR (pData, MNG_INVALIDEVENT);
-
-          pTemp++;
-
-          iMasktype  = *pTemp;         /* masktype */
-          if (iMasktype > 5)
-            MNG_ERROR (pData, MNG_INVALIDMASK);
-
-          pTemp++;
-          iLen -= 2;
-
-          iLeft     = 0;
-          iRight    = 0;
-          iTop      = 0;
-          iBottom   = 0;
-          iObjectid = 0;
-          iIndex    = 0;
-
-          switch (iMasktype)
-          {
-            case 1 :
-              {
-                if (iLen > 16)
-                {
-                  iLeft     = mng_get_int32 (pTemp);
-                  iRight    = mng_get_int32 (pTemp+4);
-                  iTop      = mng_get_int32 (pTemp+8);
-                  iBottom   = mng_get_int32 (pTemp+12);
-                  pTemp += 16;
-                  iLen -= 16;
-                }
-                else
-                  MNG_ERROR (pData, MNG_INVALIDLENGTH);
-                break;
-              }
-            case 2 :
-              {
-                if (iLen > 2)
-                {
-                  iObjectid = mng_get_uint16 (pTemp);
-                  pTemp += 2;
-                  iLen -= 2;
-                }
-                else
-                  MNG_ERROR (pData, MNG_INVALIDLENGTH);
-                break;
-              }
-            case 3 :
-              {
-                if (iLen > 3)
-                {
-                  iObjectid = mng_get_uint16 (pTemp);
-                  iIndex    = *(pTemp+2);
-                  pTemp += 3;
-                  iLen -= 3;
-                }
-                else
-                  MNG_ERROR (pData, MNG_INVALIDLENGTH);
-                break;
-              }
-            case 4 :
-              {
-                if (iLen > 18)
-                {
-                  iLeft     = mng_get_int32 (pTemp);
-                  iRight    = mng_get_int32 (pTemp+4);
-                  iTop      = mng_get_int32 (pTemp+8);
-                  iBottom   = mng_get_int32 (pTemp+12);
-                  iObjectid = mng_get_uint16 (pTemp+16);
-                  pTemp += 18;
-                  iLen -= 18;
-                }
-                else
-                  MNG_ERROR (pData, MNG_INVALIDLENGTH);
-                break;
-              }
-            case 5 :
-              {
-                if (iLen > 19)
-                {
-                  iLeft     = mng_get_int32 (pTemp);
-                  iRight    = mng_get_int32 (pTemp+4);
-                  iTop      = mng_get_int32 (pTemp+8);
-                  iBottom   = mng_get_int32 (pTemp+12);
-                  iObjectid = mng_get_uint16 (pTemp+16);
-                  iIndex    = *(pTemp+18);
-                  pTemp += 19;
-                  iLen -= 19;
-                }
-                else
-                  MNG_ERROR (pData, MNG_INVALIDLENGTH);
-                break;
-              }
-          }
-
-          pNull = find_null (pTemp);   /* get the name length */
-
-          if ((pNull - pTemp) > (mng_int32)iLen)
-          {
-            iNamesize = iLen;          /* no null found; so end of evNT */
-            iLen      = 0;
-          }
-          else
-          {
-            iNamesize = pNull - pTemp; /* should be another entry */
-            iLen      = iLen - iNamesize - 1;
-
-            if (!iLen)                 /* must not end with a null ! */
-              MNG_ERROR (pData, MNG_ENDWITHNULL);
-          }
-
-          if (!iX)
-          {
-            iCount++;
-          }
-          else
-          {
-            pEntry->iEventtype       = iEventtype;
-            pEntry->iMasktype        = iMasktype;
-            pEntry->iLeft            = iLeft;
-            pEntry->iRight           = iRight;
-            pEntry->iTop             = iTop;
-            pEntry->iBottom          = iBottom;
-            pEntry->iObjectid        = iObjectid;
-            pEntry->iIndex           = iIndex;
-            pEntry->iSegmentnamesize = iNamesize;
-
-            if (iNamesize)
-            {
-              MNG_ALLOC (pData, pEntry->zSegmentname, iNamesize+1);
-              MNG_COPY (pEntry->zSegmentname, pTemp, iNamesize);
-            }
-
-            pEntry++;
-          }
-
-          pTemp = pTemp + iNamesize + 1;
-        }
-      }
-    }
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_EVNT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-READ_CHUNK (mng_read_unknown)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_UNKNOWN, MNG_LC_START);
-#endif
-                                       /* sequence checks */
-#ifdef MNG_INCLUDE_JNG
-  if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
-      (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
-#else
-  if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
-      (!pData->bHasBASI) && (!pData->bHasDHDR)    )
-#endif
-    MNG_ERROR (pData, MNG_SEQUENCEERROR);
-                                       /* critical chunk ? */
-  if ((((mng_uint32)pData->iChunkname & 0x20000000) == 0)
-#ifdef MNG_SKIPCHUNK_SAVE
-    && (pData->iChunkname != MNG_UINT_SAVE)
-#endif
-#ifdef MNG_SKIPCHUNK_SEEK
-    && (pData->iChunkname != MNG_UINT_SEEK)
-#endif
-#ifdef MNG_SKIPCHUNK_DBYK
-    && (pData->iChunkname != MNG_UINT_DBYK)
-#endif
-#ifdef MNG_SKIPCHUNK_ORDR
-    && (pData->iChunkname != MNG_UINT_ORDR)
-#endif
-      )
-    MNG_ERROR (pData, MNG_UNKNOWNCRITICAL);
-
-  if (pData->fProcessunknown)          /* let the app handle it ? */
-  {
-    mng_bool bOke = pData->fProcessunknown ((mng_handle)pData, pData->iChunkname,
-                                            iRawlen, (mng_ptr)pRawdata);
-
-    if (!bOke)
-      MNG_ERROR (pData, MNG_APPMISCERROR);
-  }
-
-#ifdef MNG_STORE_CHUNKS
-  if (pData->bStorechunks)
-  {                                    /* initialize storage */
-    mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* store the length */
-    ((mng_chunk_headerp)*ppChunk)->iChunkname = pData->iChunkname;
-    ((mng_unknown_chunkp)*ppChunk)->iDatasize = iRawlen;
-
-    if (iRawlen == 0)                  /* any data at all ? */
-      ((mng_unknown_chunkp)*ppChunk)->pData = 0;
-    else
-    {                                  /* then store it */
-      MNG_ALLOC (pData, ((mng_unknown_chunkp)*ppChunk)->pData, iRawlen);
-      MNG_COPY (((mng_unknown_chunkp)*ppChunk)->pData, pRawdata, iRawlen);
-    }
-  }
-#endif /* MNG_STORE_CHUNKS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_UNKNOWN, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-#endif
-
-/* ************************************************************************** */
-
-#endif /* MNG_INCLUDE_READ_PROCS */
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * chunk write functions                                                  * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_WRITE_PROCS
-
-/* ************************************************************************** */
-
-WRITE_CHUNK (mng_write_ihdr)
-{
-  mng_ihdrp   pIHDR;
-  mng_uint8p  pRawdata;
-  mng_uint32  iRawlen;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_IHDR, MNG_LC_START);
-#endif
-
-  pIHDR    = (mng_ihdrp)pChunk;        /* address the proper chunk */
-  pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
-  iRawlen  = 13;
-                                       /* fill the output buffer */
-  mng_put_uint32 (pRawdata,   pIHDR->iWidth);
-  mng_put_uint32 (pRawdata+4, pIHDR->iHeight);
-
-  *(pRawdata+8)  = pIHDR->iBitdepth;
-  *(pRawdata+9)  = pIHDR->iColortype;
-  *(pRawdata+10) = pIHDR->iCompression;
-  *(pRawdata+11) = pIHDR->iFilter;
-  *(pRawdata+12) = pIHDR->iInterlace;
-                                       /* and write it */
-  iRetcode = write_raw_chunk (pData, pIHDR->sHeader.iChunkname, iRawlen, pRawdata);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_IHDR, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-
-/* ************************************************************************** */
-
-WRITE_CHUNK (mng_write_plte)
-{
-  mng_pltep   pPLTE;
-  mng_uint8p  pRawdata;
-  mng_uint32  iRawlen;
-  mng_retcode iRetcode;
-  mng_uint8p  pTemp;
-  mng_uint32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_PLTE, MNG_LC_START);
-#endif
-
-  pPLTE    = (mng_pltep)pChunk;        /* address the proper chunk */
-
-  if (pPLTE->bEmpty)                   /* write empty chunk ? */
-    iRetcode = write_raw_chunk (pData, pPLTE->sHeader.iChunkname, 0, 0);
-  else
-  {
-    pRawdata = pData->pWritebuf+8;     /* init output buffer & size */
-    iRawlen  = pPLTE->iEntrycount * 3;
-                                       /* fill the output buffer */
-    pTemp = pRawdata;
-
-    for (iX = 0; iX < pPLTE->iEntrycount; iX++)
-    {
-      *pTemp     = pPLTE->aEntries [iX].iRed;
-      *(pTemp+1) = pPLTE->aEntries [iX].iGreen;
-      *(pTemp+2) = pPLTE->aEntries [iX].iBlue;
-
-      pTemp += 3;
-    }
-                                       /* and write it */
-    iRetcode = write_raw_chunk (pData, pPLTE->sHeader.iChunkname, iRawlen, pRawdata);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_PLTE, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-
-/* ************************************************************************** */
-
-WRITE_CHUNK (mng_write_idat)
-{
-  mng_idatp   pIDAT;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_IDAT, MNG_LC_START);
-#endif
-
-  pIDAT = (mng_idatp)pChunk;           /* address the proper chunk */
-
-  if (pIDAT->bEmpty)                   /* and write it */
-    iRetcode = write_raw_chunk (pData, pIDAT->sHeader.iChunkname, 0, 0);
-  else
-    iRetcode = write_raw_chunk (pData, pIDAT->sHeader.iChunkname,
-                                pIDAT->iDatasize, pIDAT->pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_IDAT, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-
-/* ************************************************************************** */
-
-WRITE_CHUNK (mng_write_iend)
-{
-  mng_iendp   pIEND;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_IEND, MNG_LC_START);
-#endif
-
-  pIEND = (mng_iendp)pChunk;           /* address the proper chunk */
-                                       /* and write it */
-  iRetcode = write_raw_chunk (pData, pIEND->sHeader.iChunkname, 0, 0);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_IEND, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-
-/* ************************************************************************** */
-
-WRITE_CHUNK (mng_write_trns)
-{
-  mng_trnsp   pTRNS;
-  mng_uint8p  pRawdata;
-  mng_uint32  iRawlen;
-  mng_retcode iRetcode;
-  mng_uint8p  pTemp;
-  mng_uint32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_TRNS, MNG_LC_START);
-#endif
-
-  pTRNS = (mng_trnsp)pChunk;           /* address the proper chunk */
-
-  if (pTRNS->bEmpty)                   /* write empty chunk ? */
-    iRetcode = write_raw_chunk (pData, pTRNS->sHeader.iChunkname, 0, 0);
-  else
-  if (pTRNS->bGlobal)                  /* write global chunk ? */
-    iRetcode = write_raw_chunk (pData, pTRNS->sHeader.iChunkname,
-                                pTRNS->iRawlen, (mng_uint8p)pTRNS->aRawdata);
-  else
-  {
-    pRawdata = pData->pWritebuf+8;     /* init output buffer */
-    iRawlen  = 0;                      /* and default size */
-
-    switch (pTRNS->iType)
-    {
-      case 0: {
-                iRawlen   = 2;         /* fill the size & output buffer */
-                mng_put_uint16 (pRawdata, pTRNS->iGray);
-
-                break;
-              }
-      case 2: {
-                iRawlen       = 6;     /* fill the size & output buffer */
-                mng_put_uint16 (pRawdata,   pTRNS->iRed);
-                mng_put_uint16 (pRawdata+2, pTRNS->iGreen);
-                mng_put_uint16 (pRawdata+4, pTRNS->iBlue);
-
-                break;
-              }
-      case 3: {                        /* init output buffer size */
-                iRawlen = pTRNS->iCount;
-
-                pTemp   = pRawdata;    /* fill the output buffer */
-
-                for (iX = 0; iX < pTRNS->iCount; iX++)
-                {
-                  *pTemp = pTRNS->aEntries[iX];
-                  pTemp++;
-                }
-
-                break;
-              }
-    }
-                                       /* write the chunk */
-    iRetcode = write_raw_chunk (pData, pTRNS->sHeader.iChunkname,
-                                iRawlen, pRawdata);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_TRNS, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-
-/* ************************************************************************** */
-
-WRITE_CHUNK (mng_write_gama)
-{
-  mng_gamap   pGAMA;
-  mng_uint8p  pRawdata;
-  mng_uint32  iRawlen;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_GAMA, MNG_LC_START);
-#endif
-
-  pGAMA = (mng_gamap)pChunk;           /* address the proper chunk */
-
-  if (pGAMA->bEmpty)                   /* write empty ? */
-    iRetcode = write_raw_chunk (pData, pGAMA->sHeader.iChunkname, 0, 0);
-  else
-  {
-    pRawdata = pData->pWritebuf+8;     /* init output buffer & size */
-    iRawlen  = 4;
-                                       /* fill the buffer */
-    mng_put_uint32 (pRawdata, pGAMA->iGamma);
-                                       /* and write it */
-    iRetcode = write_raw_chunk (pData, pGAMA->sHeader.iChunkname,
-                                iRawlen, pRawdata);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_GAMA, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_cHRM
-WRITE_CHUNK (mng_write_chrm)
-{
-  mng_chrmp   pCHRM;
-  mng_uint8p  pRawdata;
-  mng_uint32  iRawlen;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_CHRM, MNG_LC_START);
-#endif
-
-  pCHRM = (mng_chrmp)pChunk;           /* address the proper chunk */
-
-  if (pCHRM->bEmpty)                   /* write empty ? */
-    iRetcode = write_raw_chunk (pData, pCHRM->sHeader.iChunkname, 0, 0);
-  else
-  {
-    pRawdata = pData->pWritebuf+8;     /* init output buffer & size */
-    iRawlen  = 32;
-                                       /* fill the buffer */
-    mng_put_uint32 (pRawdata,    pCHRM->iWhitepointx);
-    mng_put_uint32 (pRawdata+4,  pCHRM->iWhitepointy);
-    mng_put_uint32 (pRawdata+8,  pCHRM->iRedx);
-    mng_put_uint32 (pRawdata+12, pCHRM->iRedy);
-    mng_put_uint32 (pRawdata+16, pCHRM->iGreenx);
-    mng_put_uint32 (pRawdata+20, pCHRM->iGreeny);
-    mng_put_uint32 (pRawdata+24, pCHRM->iBluex);
-    mng_put_uint32 (pRawdata+28, pCHRM->iBluey);
-                                       /* and write it */
-    iRetcode = write_raw_chunk (pData, pCHRM->sHeader.iChunkname,
-                                iRawlen, pRawdata);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_CHRM, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-
-WRITE_CHUNK (mng_write_srgb)
-{
-  mng_srgbp   pSRGB;
-  mng_uint8p  pRawdata;
-  mng_uint32  iRawlen;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_SRGB, MNG_LC_START);
-#endif
-
-  pSRGB = (mng_srgbp)pChunk;           /* address the proper chunk */
-
-  if (pSRGB->bEmpty)                   /* write empty ? */
-    iRetcode = write_raw_chunk (pData, pSRGB->sHeader.iChunkname, 0, 0);
-  else
-  {
-    pRawdata = pData->pWritebuf+8;     /* init output buffer & size */
-    iRawlen  = 1;
-                                       /* fill the buffer */
-    *pRawdata = pSRGB->iRenderingintent;
-                                       /* and write it */
-    iRetcode = write_raw_chunk (pData, pSRGB->sHeader.iChunkname,
-                                iRawlen, pRawdata);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_SRGB, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_iCCP
-WRITE_CHUNK (mng_write_iccp)
-{
-  mng_iccpp   pICCP;
-  mng_uint8p  pRawdata;
-  mng_uint32  iRawlen;
-  mng_retcode iRetcode;
-  mng_uint8p  pTemp;
-  mng_uint8p  pBuf = 0;
-  mng_uint32  iBuflen;
-  mng_uint32  iReallen;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_ICCP, MNG_LC_START);
-#endif
-
-  pICCP = (mng_iccpp)pChunk;           /* address the proper chunk */
-
-  if (pICCP->bEmpty)                   /* write empty ? */
-    iRetcode = write_raw_chunk (pData, pICCP->sHeader.iChunkname, 0, 0);
-  else
-  {                                    /* compress the profile */
-    iRetcode = deflate_buffer (pData, pICCP->pProfile, pICCP->iProfilesize,
-                               &pBuf, &iBuflen, &iReallen);
-
-    if (!iRetcode)                     /* still oke ? */
-    {
-      pRawdata = pData->pWritebuf+8;   /* init output buffer & size */
-      iRawlen  = pICCP->iNamesize + 2 + iReallen;
-                                       /* requires large buffer ? */
-      if (iRawlen > pData->iWritebufsize)
-        MNG_ALLOC (pData, pRawdata, iRawlen);
-
-      pTemp = pRawdata;                /* fill the buffer */
-
-      if (pICCP->iNamesize)
-      {
-        MNG_COPY (pTemp, pICCP->zName, pICCP->iNamesize);
-        pTemp += pICCP->iNamesize;
-      }
-
-      *pTemp     = 0;
-      *(pTemp+1) = pICCP->iCompression;
-      pTemp += 2;
-
-      if (iReallen)
-        MNG_COPY (pTemp, pBuf, iReallen);
-                                       /* and write it */
-      iRetcode = write_raw_chunk (pData, pICCP->sHeader.iChunkname,
-                                  iRawlen, pRawdata);
-                                       /* drop the temp buffer ? */
-      if (iRawlen > pData->iWritebufsize)
-        MNG_FREEX (pData, pRawdata, iRawlen);
-
-    }
-
-    MNG_FREEX (pData, pBuf, iBuflen);  /* always drop the extra buffer */
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_ICCP, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_tEXt
-WRITE_CHUNK (mng_write_text)
-{
-  mng_textp   pTEXT;
-  mng_uint8p  pRawdata;
-  mng_uint32  iRawlen;
-  mng_retcode iRetcode;
-  mng_uint8p  pTemp;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_TEXT, MNG_LC_START);
-#endif
-
-  pTEXT = (mng_textp)pChunk;           /* address the proper chunk */
-
-  pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
-  iRawlen  = pTEXT->iKeywordsize + 1 + pTEXT->iTextsize;
-                                       /* requires large buffer ? */
-  if (iRawlen > pData->iWritebufsize)
-    MNG_ALLOC (pData, pRawdata, iRawlen);
-
-  pTemp = pRawdata;                    /* fill the buffer */
-
-  if (pTEXT->iKeywordsize)
-  {
-    MNG_COPY (pTemp, pTEXT->zKeyword, pTEXT->iKeywordsize);
-    pTemp += pTEXT->iKeywordsize;
-  }
-
-  *pTemp = 0;
-  pTemp += 1;
-
-  if (pTEXT->iTextsize)
-    MNG_COPY (pTemp, pTEXT->zText, pTEXT->iTextsize);
-                                       /* and write it */
-  iRetcode = write_raw_chunk (pData, pTEXT->sHeader.iChunkname,
-                              iRawlen, pRawdata);
-
-  if (iRawlen > pData->iWritebufsize)  /* drop the temp buffer ? */
-    MNG_FREEX (pData, pRawdata, iRawlen);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_TEXT, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_zTXt
-WRITE_CHUNK (mng_write_ztxt)
-{
-  mng_ztxtp   pZTXT;
-  mng_uint8p  pRawdata;
-  mng_uint32  iRawlen;
-  mng_retcode iRetcode;
-  mng_uint8p  pTemp;
-  mng_uint8p  pBuf = 0;
-  mng_uint32  iBuflen;
-  mng_uint32  iReallen;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_ZTXT, MNG_LC_START);
-#endif
-
-  pZTXT = (mng_ztxtp)pChunk;           /* address the proper chunk */
-                                       /* compress the text */
-  iRetcode = deflate_buffer (pData, (mng_uint8p)pZTXT->zText, pZTXT->iTextsize,
-                             &pBuf, &iBuflen, &iReallen);
-
-  if (!iRetcode)                       /* all ok ? */
-  {
-    pRawdata = pData->pWritebuf+8;     /* init output buffer & size */
-    iRawlen  = pZTXT->iKeywordsize + 2 + iReallen;
-                                       /* requires large buffer ? */
-    if (iRawlen > pData->iWritebufsize)
-      MNG_ALLOC (pData, pRawdata, iRawlen);
-
-    pTemp = pRawdata;                  /* fill the buffer */
-
-    if (pZTXT->iKeywordsize)
-    {
-      MNG_COPY (pTemp, pZTXT->zKeyword, pZTXT->iKeywordsize);
-      pTemp += pZTXT->iKeywordsize;
-    }
-
-    *pTemp = 0;                        /* terminator zero */
-    pTemp++;
-    *pTemp = 0;                        /* compression type */
-    pTemp++;
-
-    if (iReallen)
-      MNG_COPY (pTemp, pBuf, iReallen);
-                                       /* and write it */
-    iRetcode = write_raw_chunk (pData, pZTXT->sHeader.iChunkname,
-                                iRawlen, pRawdata);
-                                       /* drop the temp buffer ? */
-    if (iRawlen > pData->iWritebufsize)
-      MNG_FREEX (pData, pRawdata, iRawlen);
-
-  }
-
-  MNG_FREEX (pData, pBuf, iBuflen);    /* always drop the compression buffer */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_ZTXT, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_iTXt
-WRITE_CHUNK (mng_write_itxt)
-{
-  mng_itxtp   pITXT;
-  mng_uint8p  pRawdata;
-  mng_uint32  iRawlen;
-  mng_retcode iRetcode;
-  mng_uint8p  pTemp;
-  mng_uint8p  pBuf = 0;
-  mng_uint32  iBuflen;
-  mng_uint32  iReallen;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_ITXT, MNG_LC_START);
-#endif
-
-  pITXT = (mng_itxtp)pChunk;           /* address the proper chunk */
-
-  if (pITXT->iCompressionflag)         /* compress the text */
-    iRetcode = deflate_buffer (pData, (mng_uint8p)pITXT->zText, pITXT->iTextsize,
-                               &pBuf, &iBuflen, &iReallen);
-  else
-    iRetcode = MNG_NOERROR;
-
-  if (!iRetcode)                       /* all ok ? */
-  {
-    pRawdata = pData->pWritebuf+8;     /* init output buffer & size */
-    iRawlen  = pITXT->iKeywordsize + pITXT->iLanguagesize +
-               pITXT->iTranslationsize + 5;
-
-    if (pITXT->iCompressionflag)
-      iRawlen = iRawlen + iReallen;
-    else
-      iRawlen = iRawlen + pITXT->iTextsize;
-                                       /* requires large buffer ? */
-    if (iRawlen > pData->iWritebufsize)
-      MNG_ALLOC (pData, pRawdata, iRawlen);
-
-    pTemp = pRawdata;                  /* fill the buffer */
-
-    if (pITXT->iKeywordsize)
-    {
-      MNG_COPY (pTemp, pITXT->zKeyword, pITXT->iKeywordsize);
-      pTemp += pITXT->iKeywordsize;
-    }
-
-    *pTemp = 0;
-    pTemp++;
-    *pTemp = pITXT->iCompressionflag;
-    pTemp++;
-    *pTemp = pITXT->iCompressionmethod;
-    pTemp++;
-
-    if (pITXT->iLanguagesize)
-    {
-      MNG_COPY (pTemp, pITXT->zLanguage, pITXT->iLanguagesize);
-      pTemp += pITXT->iLanguagesize;
-    }
-
-    *pTemp = 0;
-    pTemp++;
-
-    if (pITXT->iTranslationsize)
-    {
-      MNG_COPY (pTemp, pITXT->zTranslation, pITXT->iTranslationsize);
-      pTemp += pITXT->iTranslationsize;
-    }
-
-    *pTemp = 0;
-    pTemp++;
-
-    if (pITXT->iCompressionflag)
-    {
-      if (iReallen)
-        MNG_COPY (pTemp, pBuf, iReallen);
-    }
-    else
-    {
-      if (pITXT->iTextsize)
-        MNG_COPY (pTemp, pITXT->zText, pITXT->iTextsize);
-    }
-                                       /* and write it */
-    iRetcode = write_raw_chunk (pData, pITXT->sHeader.iChunkname,
-                                iRawlen, pRawdata);
-                                       /* drop the temp buffer ? */
-    if (iRawlen > pData->iWritebufsize)
-      MNG_FREEX (pData, pRawdata, iRawlen);
-
-  }
-
-  MNG_FREEX (pData, pBuf, iBuflen);    /* always drop the compression buffer */
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_ITXT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_bKGD
-WRITE_CHUNK (mng_write_bkgd)
-{
-  mng_bkgdp   pBKGD;
-  mng_uint8p  pRawdata;
-  mng_uint32  iRawlen;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_BKGD, MNG_LC_START);
-#endif
-
-  pBKGD = (mng_bkgdp)pChunk;           /* address the proper chunk */
-
-  if (pBKGD->bEmpty)                   /* write empty ? */
-    iRetcode = write_raw_chunk (pData, pBKGD->sHeader.iChunkname, 0, 0);
-  else
-  {
-    pRawdata = pData->pWritebuf+8;     /* init output buffer & size */
-    iRawlen  = 0;                      /* and default size */
-
-    switch (pBKGD->iType)
-    {
-      case 0: {                        /* gray */
-                iRawlen = 2;           /* fill the size & output buffer */
-                mng_put_uint16 (pRawdata, pBKGD->iGray);
-
-                break;
-              }
-      case 2: {                        /* rgb */
-                iRawlen = 6;           /* fill the size & output buffer */
-                mng_put_uint16 (pRawdata,   pBKGD->iRed);
-                mng_put_uint16 (pRawdata+2, pBKGD->iGreen);
-                mng_put_uint16 (pRawdata+4, pBKGD->iBlue);
-
-                break;
-              }
-      case 3: {                        /* indexed */
-                iRawlen   = 1;         /* fill the size & output buffer */
-                *pRawdata = pBKGD->iIndex;
-
-                break;
-              }
-    }
-                                       /* and write it */
-    iRetcode = write_raw_chunk (pData, pBKGD->sHeader.iChunkname,
-                                iRawlen, pRawdata);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_BKGD, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_pHYs
-WRITE_CHUNK (mng_write_phys)
-{
-  mng_physp   pPHYS;
-  mng_uint8p  pRawdata;
-  mng_uint32  iRawlen;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_PHYS, MNG_LC_START);
-#endif
-
-  pPHYS = (mng_physp)pChunk;           /* address the proper chunk */
-
-  if (pPHYS->bEmpty)                   /* write empty ? */
-    iRetcode = write_raw_chunk (pData, pPHYS->sHeader.iChunkname, 0, 0);
-  else
-  {
-    pRawdata = pData->pWritebuf+8;     /* init output buffer & size */
-    iRawlen  = 9;
-                                       /* fill the output buffer */
-    mng_put_uint32 (pRawdata,   pPHYS->iSizex);
-    mng_put_uint32 (pRawdata+4, pPHYS->iSizey);
-
-    *(pRawdata+8) = pPHYS->iUnit;
-                                       /* and write it */
-    iRetcode = write_raw_chunk (pData, pPHYS->sHeader.iChunkname,
-                                iRawlen, pRawdata);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_PHYS, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_sBIT
-WRITE_CHUNK (mng_write_sbit)
-{
-  mng_sbitp   pSBIT;
-  mng_uint8p  pRawdata;
-  mng_uint32  iRawlen;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_SBIT, MNG_LC_START);
-#endif
-
-  pSBIT = (mng_sbitp)pChunk;           /* address the proper chunk */
-
-  if (pSBIT->bEmpty)                   /* write empty ? */
-    iRetcode = write_raw_chunk (pData, pSBIT->sHeader.iChunkname, 0, 0);
-  else
-  {
-    pRawdata = pData->pWritebuf+8;     /* init output buffer & size */
-    iRawlen  = 0;                      /* and default size */
-
-    switch (pSBIT->iType)
-    {
-      case  0: {                       /* gray */
-                 iRawlen       = 1;    /* fill the size & output buffer */
-                 *pRawdata     = pSBIT->aBits[0];
-
-                 break;
-               }
-      case  2: {                       /* rgb */
-                 iRawlen       = 3;    /* fill the size & output buffer */
-                 *pRawdata     = pSBIT->aBits[0];
-                 *(pRawdata+1) = pSBIT->aBits[1];
-                 *(pRawdata+2) = pSBIT->aBits[2];
-
-                 break;
-               }
-      case  3: {                       /* indexed */
-                 iRawlen       = 3;    /* fill the size & output buffer */
-                 *pRawdata     = pSBIT->aBits[0];
-                 *pRawdata     = pSBIT->aBits[1];
-                 *pRawdata     = pSBIT->aBits[2];
-
-                 break;
-               }
-      case  4: {                       /* gray + alpha */
-                 iRawlen       = 2;    /* fill the size & output buffer */
-                 *pRawdata     = pSBIT->aBits[0];
-                 *(pRawdata+1) = pSBIT->aBits[1];
-
-                 break;
-               }
-      case  6: {                       /* rgb + alpha */
-                 iRawlen       = 4;    /* fill the size & output buffer */
-                 *pRawdata     = pSBIT->aBits[0];
-                 *(pRawdata+1) = pSBIT->aBits[1];
-                 *(pRawdata+2) = pSBIT->aBits[2];
-                 *(pRawdata+3) = pSBIT->aBits[3];
-
-                 break;
-               }
-      case 10: {                       /* jpeg gray */
-                 iRawlen       = 1;    /* fill the size & output buffer */
-                 *pRawdata     = pSBIT->aBits[0];
-
-                 break;
-               }
-      case 12: {                       /* jpeg rgb */
-                 iRawlen       = 3;    /* fill the size & output buffer */
-                 *pRawdata     = pSBIT->aBits[0];
-                 *(pRawdata+1) = pSBIT->aBits[1];
-                 *(pRawdata+2) = pSBIT->aBits[2];
-
-                 break;
-               }
-      case 14: {                       /* jpeg gray + alpha */
-                 iRawlen       = 2;    /* fill the size & output buffer */
-                 *pRawdata     = pSBIT->aBits[0];
-                 *(pRawdata+1) = pSBIT->aBits[1];
-
-                 break;
-               }
-      case 16: {                       /* jpeg rgb + alpha */
-                 iRawlen       = 4;    /* fill the size & output buffer */
-                 *pRawdata     = pSBIT->aBits[0];
-                 *(pRawdata+1) = pSBIT->aBits[1];
-                 *(pRawdata+2) = pSBIT->aBits[2];
-                 *(pRawdata+3) = pSBIT->aBits[3];
-
-                 break;
-               }
-    }
-                                       /* and write it */
-    iRetcode = write_raw_chunk (pData, pSBIT->sHeader.iChunkname,
-                                iRawlen, pRawdata);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_SBIT, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_sPLT
-WRITE_CHUNK (mng_write_splt)
-{
-  mng_spltp   pSPLT;
-  mng_uint8p  pRawdata;
-  mng_uint32  iRawlen;
-  mng_retcode iRetcode;
-  mng_uint32  iEntrieslen;
-  mng_uint8p  pTemp;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_SPLT, MNG_LC_START);
-#endif
-
-  pSPLT = (mng_spltp)pChunk;           /* address the proper chunk */
-
-  pRawdata    = pData->pWritebuf+8;    /* init output buffer & size */
-  iEntrieslen = ((pSPLT->iSampledepth >> 3) * 4 + 2) * pSPLT->iEntrycount;
-  iRawlen     = pSPLT->iNamesize + 2 + iEntrieslen;
-                                       /* requires large buffer ? */
-  if (iRawlen > pData->iWritebufsize)
-    MNG_ALLOC (pData, pRawdata, iRawlen);
-
-  pTemp = pRawdata;                    /* fill the buffer */
-
-  if (pSPLT->iNamesize)
-  {
-    MNG_COPY (pTemp, pSPLT->zName, pSPLT->iNamesize);
-    pTemp += pSPLT->iNamesize;
-  }
-
-  *pTemp     = 0;
-  *(pTemp+1) = pSPLT->iSampledepth;
-  pTemp += 2;
-
-  if (pSPLT->iEntrycount)
-    MNG_COPY (pTemp, pSPLT->pEntries, iEntrieslen);
-                                       /* and write it */
-  iRetcode = write_raw_chunk (pData, pSPLT->sHeader.iChunkname,
-                              iRawlen, pRawdata);
-
-  if (iRawlen > pData->iWritebufsize)  /* drop the temp buffer ? */
-    MNG_FREEX (pData, pRawdata, iRawlen);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_SPLT, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_hIST
-WRITE_CHUNK (mng_write_hist)
-{
-  mng_histp   pHIST;
-  mng_uint8p  pRawdata;
-  mng_uint32  iRawlen;
-  mng_retcode iRetcode;
-  mng_uint8p  pTemp;
-  mng_uint32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_HIST, MNG_LC_START);
-#endif
-
-  pHIST = (mng_histp)pChunk;           /* address the proper chunk */
-
-  pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
-  iRawlen  = pHIST->iEntrycount << 1;
-
-  pTemp    = pRawdata;                 /* fill the output buffer */
-
-  for (iX = 0; iX < pHIST->iEntrycount; iX++)
-  {
-    mng_put_uint16 (pTemp, pHIST->aEntries [iX]);
-    pTemp += 2;
-  }
-                                       /* and write it */
-  iRetcode = write_raw_chunk (pData, pHIST->sHeader.iChunkname,
-                              iRawlen, pRawdata);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_HIST, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_tIME
-WRITE_CHUNK (mng_write_time)
-{
-  mng_timep   pTIME;
-  mng_uint8p  pRawdata;
-  mng_uint32  iRawlen;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_TIME, MNG_LC_START);
-#endif
-
-  pTIME = (mng_timep)pChunk;           /* address the proper chunk */
-
-  pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
-  iRawlen  = 7;
-                                       /* fill the output buffer */
-  mng_put_uint16 (pRawdata, pTIME->iYear);
-
-  *(pRawdata+2) = pTIME->iMonth;
-  *(pRawdata+3) = pTIME->iDay;
-  *(pRawdata+4) = pTIME->iHour;
-  *(pRawdata+5) = pTIME->iMinute;
-  *(pRawdata+6) = pTIME->iSecond;
-                                       /* and write it */
-  iRetcode = write_raw_chunk (pData, pTIME->sHeader.iChunkname,
-                              iRawlen, pRawdata);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_TIME, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-
-WRITE_CHUNK (mng_write_mhdr)
-{
-  mng_mhdrp   pMHDR;
-  mng_uint8p  pRawdata;
-  mng_uint32  iRawlen;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_MHDR, MNG_LC_START);
-#endif
-
-  pMHDR = (mng_mhdrp)pChunk;           /* address the proper chunk */
-
-  pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
-  iRawlen  = 28;
-                                       /* fill the output buffer */
-  mng_put_uint32 (pRawdata,    pMHDR->iWidth);
-  mng_put_uint32 (pRawdata+4,  pMHDR->iHeight);
-  mng_put_uint32 (pRawdata+8,  pMHDR->iTicks);
-  mng_put_uint32 (pRawdata+12, pMHDR->iLayercount);
-  mng_put_uint32 (pRawdata+16, pMHDR->iFramecount);
-  mng_put_uint32 (pRawdata+20, pMHDR->iPlaytime);
-  mng_put_uint32 (pRawdata+24, pMHDR->iSimplicity);
-
-                                       /* and write it */
-  iRetcode = write_raw_chunk (pData, pMHDR->sHeader.iChunkname,
-                              iRawlen, pRawdata);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_MHDR, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-
-/* ************************************************************************** */
-
-WRITE_CHUNK (mng_write_mend)
-{
-  mng_mendp   pMEND;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_MEND, MNG_LC_START);
-#endif
-
-  pMEND = (mng_mendp)pChunk;           /* address the proper chunk */
-                                       /* and write it */
-  iRetcode = write_raw_chunk (pData, pMEND->sHeader.iChunkname, 0, 0);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_MEND, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-
-/* ************************************************************************** */
-
-WRITE_CHUNK (mng_write_loop)
-{
-  mng_loopp   pLOOP;
-  mng_uint8p  pRawdata;
-  mng_uint32  iRawlen;
-  mng_retcode iRetcode;
-#ifndef MNG_NO_LOOP_SIGNALS_SUPPORTED
-  mng_uint8p  pTemp1;
-  mng_uint32p pTemp2;
-  mng_uint32  iX;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_LOOP, MNG_LC_START);
-#endif
-
-  pLOOP = (mng_loopp)pChunk;           /* address the proper chunk */
-
-  pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
-  iRawlen  = 5;
-                                       /* fill the output buffer */
-  *pRawdata = pLOOP->iLevel;
-  mng_put_uint32 (pRawdata+1,  pLOOP->iRepeat);
-
-  if (pLOOP->iTermination)
-  {
-    iRawlen++;
-    *(pRawdata+5) = pLOOP->iTermination;
-
-    if ((pLOOP->iCount) ||
-        (pLOOP->iItermin != 1) || (pLOOP->iItermax != 0x7FFFFFFFL))
-    {
-      iRawlen += 8;
-
-      mng_put_uint32 (pRawdata+6,  pLOOP->iItermin);
-      mng_put_uint32 (pRawdata+10, pLOOP->iItermax);
-
-#ifndef MNG_NO_LOOP_SIGNALS_SUPPORTED
-      if (pLOOP->iCount)
-      {
-        iRawlen += pLOOP->iCount * 4;
-
-        pTemp1 = pRawdata+14;
-        pTemp2 = pLOOP->pSignals;
-
-        for (iX = 0; iX < pLOOP->iCount; iX++)
-        {
-          mng_put_uint32 (pTemp1, *pTemp2);
-
-          pTemp1 += 4;
-          pTemp2++;
-        }
-      }
-#endif
-    }
-  }
-                                       /* and write it */
-  iRetcode = write_raw_chunk (pData, pLOOP->sHeader.iChunkname,
-                              iRawlen, pRawdata);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_LOOP, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-
-/* ************************************************************************** */
-
-WRITE_CHUNK (mng_write_endl)
-{
-  mng_endlp   pENDL;
-  mng_uint8p  pRawdata;
-  mng_uint32  iRawlen;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_ENDL, MNG_LC_START);
-#endif
-
-  pENDL     = (mng_endlp)pChunk;       /* address the proper chunk */
-
-  pRawdata  = pData->pWritebuf+8;      /* init output buffer & size */
-  iRawlen   = 1;
-
-  *pRawdata = pENDL->iLevel;           /* fill the output buffer */
-                                       /* and write it */
-  iRetcode  = write_raw_chunk (pData, pENDL->sHeader.iChunkname,
-                               iRawlen, pRawdata);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_ENDL, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-
-/* ************************************************************************** */
-
-WRITE_CHUNK (mng_write_defi)
-{
-  mng_defip   pDEFI;
-  mng_uint8p  pRawdata;
-  mng_uint32  iRawlen;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_DEFI, MNG_LC_START);
-#endif
-
-  pDEFI = (mng_defip)pChunk;           /* address the proper chunk */
-
-  pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
-  iRawlen  = 2;
-                                       /* fill the output buffer */
-  mng_put_uint16 (pRawdata, pDEFI->iObjectid);
-
-  if ((pDEFI->iDonotshow) || (pDEFI->iConcrete) || (pDEFI->bHasloca) || (pDEFI->bHasclip))
-  {
-    iRawlen++;
-    *(pRawdata+2) = pDEFI->iDonotshow;
-
-    if ((pDEFI->iConcrete) || (pDEFI->bHasloca) || (pDEFI->bHasclip))
-    {
-      iRawlen++;
-      *(pRawdata+3) = pDEFI->iConcrete;
-
-      if ((pDEFI->bHasloca) || (pDEFI->bHasclip))
-      {
-        iRawlen += 8;
-
-        mng_put_uint32 (pRawdata+4, pDEFI->iXlocation);
-        mng_put_uint32 (pRawdata+8, pDEFI->iYlocation);
-
-        if (pDEFI->bHasclip)
-        {
-          iRawlen += 16;
-
-          mng_put_uint32 (pRawdata+12, pDEFI->iLeftcb);
-          mng_put_uint32 (pRawdata+16, pDEFI->iRightcb);
-          mng_put_uint32 (pRawdata+20, pDEFI->iTopcb);
-          mng_put_uint32 (pRawdata+24, pDEFI->iBottomcb);
-        }
-      }
-    }
-  }
-                                       /* and write it */
-  iRetcode = write_raw_chunk (pData, pDEFI->sHeader.iChunkname,
-                              iRawlen, pRawdata);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_DEFI, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-
-/* ************************************************************************** */
-
-WRITE_CHUNK (mng_write_basi)
-{
-  mng_basip   pBASI;
-  mng_uint8p  pRawdata;
-  mng_uint32  iRawlen;
-  mng_retcode iRetcode;
-  mng_bool    bOpaque;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_BASI, MNG_LC_START);
-#endif
-
-  pBASI = (mng_basip)pChunk;           /* address the proper chunk */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-  if (pBASI->iBitdepth <= 8)           /* determine opacity alpha-field */
-#endif
-    bOpaque = (mng_bool)(pBASI->iAlpha == 0xFF);
-#ifndef MNG_NO_16BIT_SUPPORT
-  else
-    bOpaque = (mng_bool)(pBASI->iAlpha == 0xFFFF);
-#endif
-
-  pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
-  iRawlen  = 13;
-                                       /* fill the output buffer */
-  mng_put_uint32 (pRawdata,   pBASI->iWidth);
-  mng_put_uint32 (pRawdata+4, pBASI->iHeight);
-
-  *(pRawdata+8)  = pBASI->iBitdepth;
-  *(pRawdata+9)  = pBASI->iColortype;
-  *(pRawdata+10) = pBASI->iCompression;
-  *(pRawdata+11) = pBASI->iFilter;
-  *(pRawdata+12) = pBASI->iInterlace;
-
-  if ((pBASI->iRed) || (pBASI->iGreen) || (pBASI->iBlue) ||
-      (!bOpaque) || (pBASI->iViewable))
-  {
-    iRawlen += 6;
-    mng_put_uint16 (pRawdata+13, pBASI->iRed);
-    mng_put_uint16 (pRawdata+15, pBASI->iGreen);
-    mng_put_uint16 (pRawdata+17, pBASI->iBlue);
-
-    if ((!bOpaque) || (pBASI->iViewable))
-    {
-      iRawlen += 2;
-      mng_put_uint16 (pRawdata+19, pBASI->iAlpha);
-
-      if (pBASI->iViewable)
-      {
-        iRawlen++;
-        *(pRawdata+21) = pBASI->iViewable;
-      }
-    }
-  }
-                                       /* and write it */
-  iRetcode = write_raw_chunk (pData, pBASI->sHeader.iChunkname,
-                              iRawlen, pRawdata);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_BASI, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-
-/* ************************************************************************** */
-
-WRITE_CHUNK (mng_write_clon)
-{
-  mng_clonp   pCLON;
-  mng_uint8p  pRawdata;
-  mng_uint32  iRawlen;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_CLON, MNG_LC_START);
-#endif
-
-  pCLON = (mng_clonp)pChunk;           /* address the proper chunk */
-
-  pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
-  iRawlen  = 4;
-                                       /* fill the output buffer */
-  mng_put_uint16 (pRawdata,   pCLON->iSourceid);
-  mng_put_uint16 (pRawdata+2, pCLON->iCloneid);
-
-  if ((pCLON->iClonetype) || (pCLON->iDonotshow) || (pCLON->iConcrete) || (pCLON->bHasloca))
-  {
-    iRawlen++;
-    *(pRawdata+4) = pCLON->iClonetype;
-
-    if ((pCLON->iDonotshow) || (pCLON->iConcrete) || (pCLON->bHasloca))
-    {
-      iRawlen++;
-      *(pRawdata+5) = pCLON->iDonotshow;
-
-      if ((pCLON->iConcrete) || (pCLON->bHasloca))
-      {
-        iRawlen++;
-        *(pRawdata+6) = pCLON->iConcrete;
-
-        if (pCLON->bHasloca)
-        {
-          iRawlen += 9;
-          *(pRawdata+7) = pCLON->iLocationtype;
-          mng_put_int32 (pRawdata+8,  pCLON->iLocationx);
-          mng_put_int32 (pRawdata+12, pCLON->iLocationy);
-        }
-      }
-    }
-  }
-                                       /* and write it */
-  iRetcode = write_raw_chunk (pData, pCLON->sHeader.iChunkname,
-                              iRawlen, pRawdata);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_CLON, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_PAST
-WRITE_CHUNK (mng_write_past)
-{
-  mng_pastp        pPAST;
-  mng_uint8p       pRawdata;
-  mng_uint32       iRawlen;
-  mng_retcode      iRetcode;
-  mng_past_sourcep pSource;
-  mng_uint32       iX;
-  mng_uint8p       pTemp;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_PAST, MNG_LC_START);
-#endif
-
-  pPAST = (mng_pastp)pChunk;           /* address the proper chunk */
-
-  pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
-  iRawlen  = 11 + (30 * pPAST->iCount);
-                                       /* requires large buffer ? */
-  if (iRawlen > pData->iWritebufsize)
-    MNG_ALLOC (pData, pRawdata, iRawlen);
-                                       /* fill the output buffer */
-  mng_put_uint16 (pRawdata,   pPAST->iDestid);
-
-  *(pRawdata+2) = pPAST->iTargettype;
-
-  mng_put_int32  (pRawdata+3, pPAST->iTargetx);
-  mng_put_int32  (pRawdata+7, pPAST->iTargety);
-
-  pTemp   = pRawdata+11;
-  pSource = pPAST->pSources;
-
-  for (iX = 0; iX < pPAST->iCount; iX++)
-  {
-    mng_put_uint16 (pTemp,    pSource->iSourceid);
-
-    *(pTemp+2)  = pSource->iComposition;
-    *(pTemp+3)  = pSource->iOrientation;
-    *(pTemp+4)  = pSource->iOffsettype;
-
-    mng_put_int32  (pTemp+5,  pSource->iOffsetx);
-    mng_put_int32  (pTemp+9,  pSource->iOffsety);
-
-    *(pTemp+13) = pSource->iBoundarytype;
-
-    mng_put_int32  (pTemp+14, pSource->iBoundaryl);
-    mng_put_int32  (pTemp+18, pSource->iBoundaryr);
-    mng_put_int32  (pTemp+22, pSource->iBoundaryt);
-    mng_put_int32  (pTemp+26, pSource->iBoundaryb);
-
-    pSource++;
-    pTemp += 30;
-  }
-                                       /* and write it */
-  iRetcode = write_raw_chunk (pData, pPAST->sHeader.iChunkname,
-                              iRawlen, pRawdata);
-                                       /* free temporary buffer ? */
-  if (iRawlen > pData->iWritebufsize)
-    MNG_FREEX (pData, pRawdata, iRawlen);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_PAST, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-
-WRITE_CHUNK (mng_write_disc)
-{
-  mng_discp        pDISC;
-  mng_uint8p       pRawdata;
-  mng_uint32       iRawlen;
-  mng_retcode      iRetcode;
-  mng_uint32       iX;
-  mng_uint8p       pTemp1;
-  mng_uint16p      pTemp2;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_DISC, MNG_LC_START);
-#endif
-
-  pDISC    = (mng_discp)pChunk;        /* address the proper chunk */
-
-  pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
-  iRawlen  = pDISC->iCount << 1;
-
-  pTemp1   = pRawdata;                 /* fill the output buffer */
-  pTemp2   = pDISC->pObjectids;
-
-  for (iX = 0; iX < pDISC->iCount; iX++)
-  {
-    mng_put_uint16 (pTemp1, *pTemp2);
-
-    pTemp2++;
-    pTemp1 += 2;
-  }
-                                       /* and write it */
-  iRetcode = write_raw_chunk (pData, pDISC->sHeader.iChunkname,
-                              iRawlen, pRawdata);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_DISC, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-
-/* ************************************************************************** */
-
-WRITE_CHUNK (mng_write_back)
-{
-  mng_backp   pBACK;
-  mng_uint8p  pRawdata;
-  mng_uint32  iRawlen;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_BACK, MNG_LC_START);
-#endif
-
-  pBACK = (mng_backp)pChunk;           /* address the proper chunk */
-
-  pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
-  iRawlen  = 6;
-                                       /* fill the output buffer */
-  mng_put_uint16 (pRawdata,   pBACK->iRed);
-  mng_put_uint16 (pRawdata+2, pBACK->iGreen);
-  mng_put_uint16 (pRawdata+4, pBACK->iBlue);
-
-  if ((pBACK->iMandatory) || (pBACK->iImageid) || (pBACK->iTile))
-  {
-    iRawlen++;
-    *(pRawdata+6) = pBACK->iMandatory;
-
-    if ((pBACK->iImageid) || (pBACK->iTile))
-    {
-      iRawlen += 2;
-      mng_put_uint16 (pRawdata+7, pBACK->iImageid);
-
-      if (pBACK->iTile)
-      {
-        iRawlen++;
-        *(pRawdata+9) = pBACK->iTile;
-      }
-    }
-  }
-                                       /* and write it */
-  iRetcode = write_raw_chunk (pData, pBACK->sHeader.iChunkname,
-                              iRawlen, pRawdata);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_BACK, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-
-/* ************************************************************************** */
-
-WRITE_CHUNK (mng_write_fram)
-{
-  mng_framp   pFRAM;
-  mng_uint8p  pRawdata;
-  mng_uint32  iRawlen;
-  mng_retcode iRetcode;
-  mng_uint8p  pTemp;
-  mng_uint32p pTemp2;
-  mng_uint32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_FRAM, MNG_LC_START);
-#endif
-
-  pFRAM = (mng_framp)pChunk;           /* address the proper chunk */
-
-  if (pFRAM->bEmpty)                   /* empty ? */
-    iRetcode = write_raw_chunk (pData, pFRAM->sHeader.iChunkname, 0, 0);
-  else
-  {
-    pRawdata = pData->pWritebuf+8;     /* init output buffer & size */
-    iRawlen  = 1;
-                                       /* fill the output buffer */
-    *pRawdata = pFRAM->iMode;
-
-    if ((pFRAM->iNamesize      ) ||
-        (pFRAM->iChangedelay   ) || (pFRAM->iChangetimeout) ||
-        (pFRAM->iChangeclipping) || (pFRAM->iChangesyncid )    )
-    {
-      if (pFRAM->iNamesize)
-        MNG_COPY (pRawdata+1, pFRAM->zName, pFRAM->iNamesize);
-
-      iRawlen += pFRAM->iNamesize;
-      pTemp = pRawdata + pFRAM->iNamesize + 1;
-
-      if ((pFRAM->iChangedelay   ) || (pFRAM->iChangetimeout) ||
-          (pFRAM->iChangeclipping) || (pFRAM->iChangesyncid )    )
-      {
-        *pTemp     = 0;
-        *(pTemp+1) = pFRAM->iChangedelay;
-        *(pTemp+2) = pFRAM->iChangetimeout;
-        *(pTemp+3) = pFRAM->iChangeclipping;
-        *(pTemp+4) = pFRAM->iChangesyncid;
-
-        iRawlen += 5;
-        pTemp   += 5;
-
-        if (pFRAM->iChangedelay)
-        {
-          mng_put_uint32 (pTemp, pFRAM->iDelay);
-          iRawlen += 4;
-          pTemp   += 4;
-        }
-
-        if (pFRAM->iChangetimeout)
-        {
-          mng_put_uint32 (pTemp, pFRAM->iTimeout);
-          iRawlen += 4;
-          pTemp   += 4;
-        }
-
-        if (pFRAM->iChangeclipping)
-        {
-          *pTemp = pFRAM->iBoundarytype;
-
-          mng_put_uint32 (pTemp+1,  pFRAM->iBoundaryl);
-          mng_put_uint32 (pTemp+5,  pFRAM->iBoundaryr);
-          mng_put_uint32 (pTemp+9,  pFRAM->iBoundaryt);
-          mng_put_uint32 (pTemp+13, pFRAM->iBoundaryb);
-
-          iRawlen += 17;
-          pTemp   += 17;
-        }
-
-        if (pFRAM->iChangesyncid)
-        {
-          iRawlen += pFRAM->iCount * 4;
-          pTemp2 = pFRAM->pSyncids;
-
-          for (iX = 0; iX < pFRAM->iCount; iX++)
-          {
-            mng_put_uint32 (pTemp, *pTemp2);
-
-            pTemp2++;
-            pTemp += 4;
-          }  
-        }
-      }
-    }
-                                       /* and write it */
-    iRetcode = write_raw_chunk (pData, pFRAM->sHeader.iChunkname,
-                                iRawlen, pRawdata);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_FRAM, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-
-/* ************************************************************************** */
-
-WRITE_CHUNK (mng_write_move)
-{
-  mng_movep   pMOVE;
-  mng_uint8p  pRawdata;
-  mng_uint32  iRawlen;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_MOVE, MNG_LC_START);
-#endif
-
-  pMOVE = (mng_movep)pChunk;           /* address the proper chunk */
-
-  pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
-  iRawlen  = 13;
-                                       /* fill the output buffer */
-  mng_put_uint16 (pRawdata,   pMOVE->iFirstid);
-  mng_put_uint16 (pRawdata+2, pMOVE->iLastid);
-
-  *(pRawdata+4) = pMOVE->iMovetype;
-
-  mng_put_int32  (pRawdata+5, pMOVE->iMovex);
-  mng_put_int32  (pRawdata+9, pMOVE->iMovey);
-                                       /* and write it */
-  iRetcode = write_raw_chunk (pData, pMOVE->sHeader.iChunkname,
-                              iRawlen, pRawdata);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_MOVE, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-
-/* ************************************************************************** */
-
-WRITE_CHUNK (mng_write_clip)
-{
-  mng_clipp   pCLIP;
-  mng_uint8p  pRawdata;
-  mng_uint32  iRawlen;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_CLIP, MNG_LC_START);
-#endif
-
-  pCLIP = (mng_clipp)pChunk;           /* address the proper chunk */
-
-  pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
-  iRawlen  = 21;
-                                       /* fill the output buffer */
-  mng_put_uint16 (pRawdata,    pCLIP->iFirstid);
-  mng_put_uint16 (pRawdata+2,  pCLIP->iLastid);
-
-  *(pRawdata+4) = pCLIP->iCliptype;
-
-  mng_put_int32  (pRawdata+5,  pCLIP->iClipl);
-  mng_put_int32  (pRawdata+9,  pCLIP->iClipr);
-  mng_put_int32  (pRawdata+13, pCLIP->iClipt);
-  mng_put_int32  (pRawdata+17, pCLIP->iClipb);
-                                       /* and write it */
-  iRetcode = write_raw_chunk (pData, pCLIP->sHeader.iChunkname,
-                              iRawlen, pRawdata);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_CLIP, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-
-/* ************************************************************************** */
-
-WRITE_CHUNK (mng_write_show)
-{
-  mng_showp   pSHOW;
-  mng_uint8p  pRawdata;
-  mng_uint32  iRawlen;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_SHOW, MNG_LC_START);
-#endif
-
-  pSHOW = (mng_showp)pChunk;           /* address the proper chunk */
-
-  if (pSHOW->bEmpty)                   /* empty ? */
-    iRetcode = write_raw_chunk (pData, pSHOW->sHeader.iChunkname, 0, 0);
-  else
-  {
-    pRawdata = pData->pWritebuf+8;     /* init output buffer & size */
-    iRawlen  = 2;
-                                       /* fill the output buffer */
-    mng_put_uint16 (pRawdata, pSHOW->iFirstid);
-
-    if ((pSHOW->iLastid != pSHOW->iFirstid) || (pSHOW->iMode))
-    {
-      iRawlen += 2;
-      mng_put_uint16 (pRawdata+2, pSHOW->iLastid);
-
-      if (pSHOW->iMode)
-      {
-        iRawlen++;
-        *(pRawdata+4) = pSHOW->iMode;
-      }
-    }
-                                       /* and write it */
-    iRetcode = write_raw_chunk (pData, pSHOW->sHeader.iChunkname,
-                                iRawlen, pRawdata);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_SHOW, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-
-/* ************************************************************************** */
-
-WRITE_CHUNK (mng_write_term)
-{
-  mng_termp   pTERM;
-  mng_uint8p  pRawdata;
-  mng_uint32  iRawlen;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_TERM, MNG_LC_START);
-#endif
-
-  pTERM     = (mng_termp)pChunk;       /* address the proper chunk */
-
-  pRawdata  = pData->pWritebuf+8;      /* init output buffer & size */
-  iRawlen   = 1;
-
-  *pRawdata = pTERM->iTermaction;      /* fill the output buffer */
-
-  if (pTERM->iTermaction == 3)
-  {
-    iRawlen       = 10;
-    *(pRawdata+1) = pTERM->iIteraction;
-
-    mng_put_uint32 (pRawdata+2, pTERM->iDelay);
-    mng_put_uint32 (pRawdata+6, pTERM->iItermax);
-  }
-                                       /* and write it */
-  iRetcode = write_raw_chunk (pData, pTERM->sHeader.iChunkname,
-                              iRawlen, pRawdata);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_TERM, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_SAVE
-WRITE_CHUNK (mng_write_save)
-{
-  mng_savep       pSAVE;
-  mng_uint8p      pRawdata;
-  mng_uint32      iRawlen;
-  mng_retcode     iRetcode;
-  mng_save_entryp pEntry;
-  mng_uint32      iEntrysize;
-  mng_uint8p      pTemp;
-  mng_uint32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_SAVE, MNG_LC_START);
-#endif
-
-  pSAVE = (mng_savep)pChunk;           /* address the proper chunk */
-
-  if (pSAVE->bEmpty)                   /* empty ? */
-    iRetcode = write_raw_chunk (pData, pSAVE->sHeader.iChunkname, 0, 0);
-  else
-  {
-    pRawdata  = pData->pWritebuf+8;    /* init output buffer & size */
-    iRawlen   = 1;
-
-    *pRawdata = pSAVE->iOffsettype;    /* fill the output buffer */
-
-    if (pSAVE->iOffsettype == 16)
-      iEntrysize = 25;
-    else
-      iEntrysize = 17;
-
-    pTemp  = pRawdata+1;
-    pEntry = pSAVE->pEntries;
-
-    for (iX = 0; iX < pSAVE->iCount; iX++)
-    {
-      if (iX)                          /* put separator null-byte, except the first */
-      {
-        *pTemp = 0;
-        pTemp++;
-        iRawlen++;
-      }
-
-      iRawlen += iEntrysize + pEntry->iNamesize;
-      *pTemp = pEntry->iEntrytype;
-
-      if (pSAVE->iOffsettype == 16)
-      {
-        mng_put_uint32 (pTemp+1,  pEntry->iOffset[0]);
-        mng_put_uint32 (pTemp+5,  pEntry->iOffset[1]);
-        mng_put_uint32 (pTemp+9,  pEntry->iStarttime[0]);
-        mng_put_uint32 (pTemp+13, pEntry->iStarttime[1]);
-        mng_put_uint32 (pTemp+17, pEntry->iLayernr);
-        mng_put_uint32 (pTemp+21, pEntry->iFramenr);
-
-        pTemp += 25;
-      }
-      else
-      {
-        mng_put_uint32 (pTemp+1,  pEntry->iOffset[1]);
-        mng_put_uint32 (pTemp+5,  pEntry->iStarttime[1]);
-        mng_put_uint32 (pTemp+9,  pEntry->iLayernr);
-        mng_put_uint32 (pTemp+13, pEntry->iFramenr);
-
-        pTemp += 17;
-      }
-
-      if (pEntry->iNamesize)
-      {
-        MNG_COPY (pTemp, pEntry->zName, pEntry->iNamesize);
-        pTemp += pEntry->iNamesize;
-      }
-
-      pEntry++;  
-    }
-                                       /* and write it */
-    iRetcode = write_raw_chunk (pData, pSAVE->sHeader.iChunkname,
-                                iRawlen, pRawdata);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_SAVE, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_SEEK
-WRITE_CHUNK (mng_write_seek)
-{
-  mng_seekp   pSEEK;
-  mng_uint8p  pRawdata;
-  mng_uint32  iRawlen;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_SEEK, MNG_LC_START);
-#endif
-
-  pSEEK    = (mng_seekp)pChunk;        /* address the proper chunk */
-
-  pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
-  iRawlen  = pSEEK->iNamesize;
-
-  if (iRawlen)                         /* fill the output buffer */
-    MNG_COPY (pRawdata, pSEEK->zName, iRawlen);
-                                       /* and write it */
-  iRetcode = write_raw_chunk (pData, pSEEK->sHeader.iChunkname,
-                              iRawlen, pRawdata);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_SEEK, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_eXPI
-WRITE_CHUNK (mng_write_expi)
-{
-  mng_expip   pEXPI;
-  mng_uint8p  pRawdata;
-  mng_uint32  iRawlen;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_EXPI, MNG_LC_START);
-#endif
-
-  pEXPI    = (mng_expip)pChunk;        /* address the proper chunk */
-
-  pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
-  iRawlen  = 2 + pEXPI->iNamesize;
-                                       /* fill the output buffer */
-  mng_put_uint16 (pRawdata, pEXPI->iSnapshotid);
-
-  if (pEXPI->iNamesize)
-    MNG_COPY (pRawdata+2, pEXPI->zName, pEXPI->iNamesize);
-                                       /* and write it */
-  iRetcode = write_raw_chunk (pData, pEXPI->sHeader.iChunkname,
-                              iRawlen, pRawdata);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_EXPI, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_fPRI
-WRITE_CHUNK (mng_write_fpri)
-{
-  mng_fprip   pFPRI;
-  mng_uint8p  pRawdata;
-  mng_uint32  iRawlen;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_FPRI, MNG_LC_START);
-#endif
-
-  pFPRI         = (mng_fprip)pChunk;   /* address the proper chunk */
-
-  pRawdata      = pData->pWritebuf+8;  /* init output buffer & size */
-  iRawlen       = 2;
-
-  *pRawdata     = pFPRI->iDeltatype;   /* fill the output buffer */
-  *(pRawdata+1) = pFPRI->iPriority;
-                                       /* and write it */
-  iRetcode = write_raw_chunk (pData, pFPRI->sHeader.iChunkname,
-                              iRawlen, pRawdata);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_FPRI, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_nEED
-WRITE_CHUNK (mng_write_need)
-{
-  mng_needp   pNEED;
-  mng_uint8p  pRawdata;
-  mng_uint32  iRawlen;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_NEED, MNG_LC_START);
-#endif
-
-  pNEED    = (mng_needp)pChunk;        /* address the proper chunk */
-
-  pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
-  iRawlen  = pNEED->iKeywordssize;
-                                       /* fill the output buffer */
-  if (pNEED->iKeywordssize)
-    MNG_COPY (pRawdata, pNEED->zKeywords, pNEED->iKeywordssize);
-                                       /* and write it */
-  iRetcode = write_raw_chunk (pData, pNEED->sHeader.iChunkname,
-                              iRawlen, pRawdata);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_NEED, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_pHYg
-WRITE_CHUNK (mng_write_phyg)
-{
-  mng_phygp   pPHYG;
-  mng_uint8p  pRawdata;
-  mng_uint32  iRawlen;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_PHYG, MNG_LC_START);
-#endif
-
-  pPHYG = (mng_phygp)pChunk;           /* address the proper chunk */
-
-  if (pPHYG->bEmpty)                   /* write empty ? */
-    iRetcode = write_raw_chunk (pData, pPHYG->sHeader.iChunkname, 0, 0);
-  else
-  {
-    pRawdata = pData->pWritebuf+8;     /* init output buffer & size */
-    iRawlen  = 9;
-                                       /* fill the output buffer */
-    mng_put_uint32 (pRawdata,   pPHYG->iSizex);
-    mng_put_uint32 (pRawdata+4, pPHYG->iSizey);
-
-    *(pRawdata+8) = pPHYG->iUnit;
-                                       /* and write it */
-    iRetcode = write_raw_chunk (pData, pPHYG->sHeader.iChunkname,
-                                iRawlen, pRawdata);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_PHYG, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-
-/* B004 */
-#ifdef MNG_INCLUDE_JNG
-/* B004 */
-WRITE_CHUNK (mng_write_jhdr)
-{
-  mng_jhdrp   pJHDR;
-  mng_uint8p  pRawdata;
-  mng_uint32  iRawlen;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_JHDR, MNG_LC_START);
-#endif
-
-  pJHDR    = (mng_jhdrp)pChunk;        /* address the proper chunk */
-  pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
-  iRawlen  = 16;
-                                       /* fill the output buffer */
-  mng_put_uint32 (pRawdata,   pJHDR->iWidth);
-  mng_put_uint32 (pRawdata+4, pJHDR->iHeight);
-
-  *(pRawdata+8)  = pJHDR->iColortype;
-  *(pRawdata+9)  = pJHDR->iImagesampledepth;
-  *(pRawdata+10) = pJHDR->iImagecompression;
-  *(pRawdata+11) = pJHDR->iImageinterlace;
-  *(pRawdata+12) = pJHDR->iAlphasampledepth;
-  *(pRawdata+13) = pJHDR->iAlphacompression;
-  *(pRawdata+14) = pJHDR->iAlphafilter;
-  *(pRawdata+15) = pJHDR->iAlphainterlace;
-                                       /* and write it */
-  iRetcode = write_raw_chunk (pData, pJHDR->sHeader.iChunkname, iRawlen, pRawdata);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_JHDR, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#else
-#define write_jhdr 0
-/* B004 */
-#endif /* MNG_INCLUDE_JNG */
-/* B004 */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-WRITE_CHUNK (mng_write_jdaa)
-{
-  mng_jdatp   pJDAA;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_JDAA, MNG_LC_START);
-#endif
-
-  pJDAA = (mng_jdaap)pChunk;           /* address the proper chunk */
-
-  if (pJDAA->bEmpty)                   /* and write it */
-    iRetcode = write_raw_chunk (pData, pJDAA->sHeader.iChunkname, 0, 0);
-  else
-    iRetcode = write_raw_chunk (pData, pJDAA->sHeader.iChunkname,
-                                pJDAA->iDatasize, pJDAA->pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_JDAA, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#else
-#define write_jdaa 0
-#endif /* MNG_INCLUDE_JNG */
-
-/* ************************************************************************** */
-
-/* B004 */
-#ifdef MNG_INCLUDE_JNG
-/* B004 */
-WRITE_CHUNK (mng_write_jdat)
-{
-  mng_jdatp   pJDAT;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_JDAT, MNG_LC_START);
-#endif
-
-  pJDAT = (mng_jdatp)pChunk;           /* address the proper chunk */
-
-  if (pJDAT->bEmpty)                   /* and write it */
-    iRetcode = write_raw_chunk (pData, pJDAT->sHeader.iChunkname, 0, 0);
-  else
-    iRetcode = write_raw_chunk (pData, pJDAT->sHeader.iChunkname,
-                                pJDAT->iDatasize, pJDAT->pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_JDAT, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#else
-#define write_jdat 0
-/* B004 */
-#endif /* MNG_INCLUDE_JNG */
-/* B004 */
-
-/* ************************************************************************** */
-
-/* B004 */
-#ifdef MNG_INCLUDE_JNG
-/* B004 */
-WRITE_CHUNK (mng_write_jsep)
-{
-  mng_jsepp   pJSEP;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_JSEP, MNG_LC_START);
-#endif
-
-  pJSEP = (mng_jsepp)pChunk;           /* address the proper chunk */
-                                       /* and write it */
-  iRetcode = write_raw_chunk (pData, pJSEP->sHeader.iChunkname, 0, 0);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_JSEP, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#else
-#define write_jsep 0
-/* B004 */
-#endif /* MNG_INCLUDE_JNG */
-/* B004 */
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-WRITE_CHUNK (mng_write_dhdr)
-{
-  mng_dhdrp   pDHDR;
-  mng_uint8p  pRawdata;
-  mng_uint32  iRawlen;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_DHDR, MNG_LC_START);
-#endif
-
-  pDHDR    = (mng_dhdrp)pChunk;        /* address the proper chunk */
-
-  pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
-  iRawlen  = 4;
-                                       /* fill the output buffer */
-  mng_put_uint16 (pRawdata, pDHDR->iObjectid);
-
-  *(pRawdata+2) = pDHDR->iImagetype;
-  *(pRawdata+3) = pDHDR->iDeltatype;
-
-  if (pDHDR->iDeltatype != 7)
-  {
-    iRawlen += 8;
-    mng_put_uint32 (pRawdata+4, pDHDR->iBlockwidth);
-    mng_put_uint32 (pRawdata+8, pDHDR->iBlockheight);
-
-    if (pDHDR->iDeltatype != 0)
-    {
-      iRawlen += 8;
-      mng_put_uint32 (pRawdata+12, pDHDR->iBlockx);
-      mng_put_uint32 (pRawdata+16, pDHDR->iBlocky);
-    }
-  }
-                                       /* and write it */
-  iRetcode = write_raw_chunk (pData, pDHDR->sHeader.iChunkname,
-                              iRawlen, pRawdata);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_DHDR, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-WRITE_CHUNK (mng_write_prom)
-{
-  mng_promp   pPROM;
-  mng_uint8p  pRawdata;
-  mng_uint32  iRawlen;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_PROM, MNG_LC_START);
-#endif
-
-  pPROM    = (mng_promp)pChunk;        /* address the proper chunk */
-
-  pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
-  iRawlen  = 3;
-
-  *pRawdata     = pPROM->iColortype;   /* fill the output buffer */
-  *(pRawdata+1) = pPROM->iSampledepth;
-  *(pRawdata+2) = pPROM->iFilltype;
-                                       /* and write it */
-  iRetcode = write_raw_chunk (pData, pPROM->sHeader.iChunkname,
-                              iRawlen, pRawdata);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_PROM, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-WRITE_CHUNK (mng_write_ipng)
-{
-  mng_ipngp   pIPNG;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_IPNG, MNG_LC_START);
-#endif
-
-  pIPNG = (mng_ipngp)pChunk;           /* address the proper chunk */
-                                       /* and write it */
-  iRetcode = write_raw_chunk (pData, pIPNG->sHeader.iChunkname, 0, 0);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_IPNG, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-WRITE_CHUNK (mng_write_pplt)
-{
-  mng_ppltp       pPPLT;
-  mng_uint8p      pRawdata;
-  mng_uint32      iRawlen;
-  mng_retcode     iRetcode;
-  mng_pplt_entryp pEntry;
-  mng_uint8p      pTemp;
-  mng_uint32      iX;
-  mng_bool        bHasgroup;
-  mng_uint8p      pLastid = 0;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_PPLT, MNG_LC_START);
-#endif
-
-  pPPLT = (mng_ppltp)pChunk;           /* address the proper chunk */
-
-  pRawdata  = pData->pWritebuf+8;      /* init output buffer & size */
-  iRawlen   = 1;
-
-  *pRawdata = pPPLT->iDeltatype;       /* fill the output buffer */
-
-  pTemp     = pRawdata+1;
-  bHasgroup = MNG_FALSE;
-
-  for (iX = 0; iX < pPPLT->iCount; iX++)
-  {
-    pEntry = &pPPLT->aEntries[iX];
-    
-    if (pEntry->bUsed)                 /* valid entry ? */
-    {
-      if (!bHasgroup)                  /* start a new group ? */
-      {
-        bHasgroup  = MNG_TRUE;
-        pLastid    = pTemp+1;
-
-        *pTemp     = (mng_uint8)iX;
-        *(pTemp+1) = 0;
-
-        pTemp += 2;
-        iRawlen += 2;
-      }
-
-      switch (pPPLT->iDeltatype)       /* add group-entry depending on type */
-      {
-        case 0: ;
-        case 1: {
-                  *pTemp     = pEntry->iRed;
-                  *(pTemp+1) = pEntry->iGreen;
-                  *(pTemp+2) = pEntry->iBlue;
-
-                  pTemp += 3;
-                  iRawlen += 3;
-
-                  break;
-                }
-
-        case 2: ;
-        case 3: {
-                  *pTemp     = pEntry->iAlpha;
-
-                  pTemp++;
-                  iRawlen++;
-
-                  break;
-                }
-
-        case 4: ;
-        case 5: {
-                  *pTemp     = pEntry->iRed;
-                  *(pTemp+1) = pEntry->iGreen;
-                  *(pTemp+2) = pEntry->iBlue;
-                  *(pTemp+3) = pEntry->iAlpha;
-
-                  pTemp += 4;
-                  iRawlen += 4;
-
-                  break;
-                }
-
-      }
-    }
-    else
-    {
-      if (bHasgroup)                   /* finish off a group ? */
-        *pLastid = (mng_uint8)(iX-1);
-
-      bHasgroup = MNG_FALSE;
-    }
-  }
-
-  if (bHasgroup)                       /* last group unfinished ? */
-    *pLastid = (mng_uint8)(pPPLT->iCount-1);
-                                       /* write the output buffer */
-  iRetcode = write_raw_chunk (pData, pPPLT->sHeader.iChunkname,
-                              iRawlen, pRawdata);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_PPLT, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-#ifdef MNG_INCLUDE_JNG
-WRITE_CHUNK (mng_write_ijng)
-{
-  mng_ijngp   pIJNG;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_IJNG, MNG_LC_START);
-#endif
-
-  pIJNG = (mng_ijngp)pChunk;           /* address the proper chunk */
-                                       /* and write it */
-  iRetcode = write_raw_chunk (pData, pIJNG->sHeader.iChunkname, 0, 0);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_IJNG, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-WRITE_CHUNK (mng_write_drop)
-{
-  mng_dropp        pDROP;
-  mng_uint8p       pRawdata;
-  mng_uint32       iRawlen;
-  mng_retcode      iRetcode;
-  mng_uint32       iX;
-  mng_uint8p       pTemp1;
-  mng_chunkidp     pTemp2;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_DROP, MNG_LC_START);
-#endif
-
-  pDROP    = (mng_dropp)pChunk;        /* address the proper chunk */
-
-  pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
-  iRawlen  = pDROP->iCount << 2;
-
-  pTemp1   = pRawdata;                 /* fill the output buffer */
-  pTemp2   = pDROP->pChunknames;
-
-  for (iX = 0; iX < pDROP->iCount; iX++)
-  {
-    mng_put_uint32 (pTemp1, (mng_uint32)*pTemp2);
-
-    pTemp2++;
-    pTemp1 += 4;
-  }
-                                       /* and write it */
-  iRetcode = write_raw_chunk (pData, pDROP->sHeader.iChunkname,
-                              iRawlen, pRawdata);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_DROP, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_SKIPCHUNK_DBYK
-WRITE_CHUNK (mng_write_dbyk)
-{
-  mng_dbykp   pDBYK;
-  mng_uint8p  pRawdata;
-  mng_uint32  iRawlen;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_DBYK, MNG_LC_START);
-#endif
-
-  pDBYK = (mng_dbykp)pChunk;           /* address the proper chunk */
-
-  pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
-  iRawlen  = 5 + pDBYK->iKeywordssize;
-                                       /* fill the output buffer */
-  mng_put_uint32 (pRawdata, pDBYK->iChunkname);
-  *(pRawdata+4) = pDBYK->iPolarity;
-
-  if (pDBYK->iKeywordssize)
-    MNG_COPY (pRawdata+5, pDBYK->zKeywords, pDBYK->iKeywordssize);
-                                       /* and write it */
-  iRetcode = write_raw_chunk (pData, pDBYK->sHeader.iChunkname,
-                              iRawlen, pRawdata);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_DBYK, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_SKIPCHUNK_ORDR
-WRITE_CHUNK (mng_write_ordr)
-{
-  mng_ordrp       pORDR;
-  mng_uint8p      pRawdata;
-  mng_uint32      iRawlen;
-  mng_retcode     iRetcode;
-  mng_uint8p      pTemp;
-  mng_ordr_entryp pEntry;
-  mng_uint32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_ORDR, MNG_LC_START);
-#endif
-
-  pORDR    = (mng_ordrp)pChunk;        /* address the proper chunk */
-
-  pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
-  iRawlen  = pORDR->iCount * 5;
-
-  pTemp    = pRawdata;                 /* fill the output buffer */
-  pEntry   = pORDR->pEntries;
-
-  for (iX = 0; iX < pORDR->iCount; iX++)
-  {
-    mng_put_uint32 (pTemp, pEntry->iChunkname);
-    *(pTemp+4) = pEntry->iOrdertype;
-    pTemp += 5;
-    pEntry++;
-  }
-                                       /* and write it */
-  iRetcode = write_raw_chunk (pData, pORDR->sHeader.iChunkname,
-                              iRawlen, pRawdata);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_ORDR, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-WRITE_CHUNK (mng_write_magn)
-{
-  mng_magnp   pMAGN;
-  mng_uint8p  pRawdata;
-  mng_uint32  iRawlen;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_MAGN, MNG_LC_START);
-#endif
-
-  pMAGN    = (mng_magnp)pChunk;        /* address the proper chunk */
-
-  pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
-  iRawlen  = 18;
-                                       /* fill the output buffer */
-  mng_put_uint16 (pRawdata,    pMAGN->iFirstid);
-  mng_put_uint16 (pRawdata+2,  pMAGN->iLastid);
-  *(pRawdata+4) = pMAGN->iMethodX;
-  mng_put_uint16 (pRawdata+5,  pMAGN->iMX);
-  mng_put_uint16 (pRawdata+7,  pMAGN->iMY);
-  mng_put_uint16 (pRawdata+9,  pMAGN->iML);
-  mng_put_uint16 (pRawdata+11, pMAGN->iMR);
-  mng_put_uint16 (pRawdata+13, pMAGN->iMT);
-  mng_put_uint16 (pRawdata+15, pMAGN->iMB);
-  *(pRawdata+17) = pMAGN->iMethodY;
-                                       /* optimize length */
-  if (pMAGN->iMethodY == pMAGN->iMethodX)
-  {
-    iRawlen--;
-
-    if (pMAGN->iMB == pMAGN->iMY)
-    {
-      iRawlen -= 2;
-
-      if (pMAGN->iMT == pMAGN->iMY)
-      {
-        iRawlen -= 2;
-
-        if (pMAGN->iMR == pMAGN->iMX)
-        {
-          iRawlen -= 2;
-
-          if (pMAGN->iML == pMAGN->iMX)
-          {
-            iRawlen -= 2;
-
-            if (pMAGN->iMY == pMAGN->iMX)
-            {
-              iRawlen -= 2;
-
-              if (pMAGN->iMX == 1)
-              {
-                iRawlen -= 2;
-
-                if (pMAGN->iMethodX == 0)
-                {
-                  iRawlen--;
-
-                  if (pMAGN->iLastid == pMAGN->iFirstid)
-                  {
-                    iRawlen -= 2;
-
-                    if (pMAGN->iFirstid == 0)
-                      iRawlen = 0;
-
-                  }
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-                                       /* and write it */
-  iRetcode = write_raw_chunk (pData, pMAGN->sHeader.iChunkname,
-                              iRawlen, pRawdata);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_MAGN, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-WRITE_CHUNK (mng_write_mpng)
-{
-  mng_mpngp   pMPNG;
-  mng_uint8p  pRawdata;
-  mng_uint32  iRawlen;
-  mng_retcode iRetcode;
-  mng_uint8p  pBuf = 0;
-  mng_uint32  iBuflen;
-  mng_uint32  iReallen;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_MPNG, MNG_LC_START);
-#endif
-
-  pMPNG = (mng_mpngp)pChunk;           /* address the proper chunk */
-                                       /* compress the frame structures */
-  iRetcode = deflate_buffer (pData, (mng_uint8p)pMPNG->pFrames, pMPNG->iFramessize,
-                             &pBuf, &iBuflen, &iReallen);
-
-  if (!iRetcode)                       /* all ok ? */
-  {
-    pRawdata = pData->pWritebuf+8;     /* init output buffer & size */
-    iRawlen  = 15 + iReallen;
-                                       /* requires large buffer ? */
-    if (iRawlen > pData->iWritebufsize)
-      MNG_ALLOC (pData, pRawdata, iRawlen);
-                                       /* fill the buffer */
-    mng_put_uint32 (pRawdata,    pMPNG->iFramewidth);
-    mng_put_uint32 (pRawdata+4,  pMPNG->iFrameheight);
-    mng_put_uint16 (pRawdata+8,  pMPNG->iNumplays);
-    mng_put_uint16 (pRawdata+10, pMPNG->iTickspersec);
-    *(pRawdata+12) = pMPNG->iCompressionmethod;
-
-    if (iReallen)
-      MNG_COPY (pRawdata+13, pBuf, iReallen);
-                                       /* and write it */
-    iRetcode = write_raw_chunk (pData, pMPNG->sHeader.iChunkname,
-                                iRawlen, pRawdata);
-                                       /* drop the temp buffer ? */
-    if (iRawlen > pData->iWritebufsize)
-      MNG_FREEX (pData, pRawdata, iRawlen);
-  }
-
-  MNG_FREEX (pData, pBuf, iBuflen);    /* always drop the compression buffer */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_MPNG, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_ANG_PROPOSAL
-WRITE_CHUNK (mng_write_ahdr)
-{
-  mng_ahdrp   pAHDR;
-  mng_uint8p  pRawdata;
-  mng_uint32  iRawlen;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_AHDR, MNG_LC_START);
-#endif
-
-  pAHDR    = (mng_ahdrp)pChunk;        /* address the proper chunk */
-  pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
-  iRawlen  = 22;
-                                       /* fill the buffer */
-  mng_put_uint32 (pRawdata,    pAHDR->iNumframes);
-  mng_put_uint32 (pRawdata+4,  pAHDR->iTickspersec);
-  mng_put_uint32 (pRawdata+8,  pAHDR->iNumplays);
-  mng_put_uint32 (pRawdata+12, pAHDR->iTilewidth);
-  mng_put_uint32 (pRawdata+16, pAHDR->iTileheight);
-  *(pRawdata+20) = pAHDR->iInterlace;
-  *(pRawdata+21) = pAHDR->iStillused;
-                                       /* and write it */
-  iRetcode = write_raw_chunk (pData, pAHDR->sHeader.iChunkname,
-                              iRawlen, pRawdata);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_AHDR, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_ANG_PROPOSAL
-WRITE_CHUNK (mng_write_adat)
-{
-
-  /* TODO: something */
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_evNT
-WRITE_CHUNK (mng_write_evnt)
-{
-  mng_evntp       pEVNT;
-  mng_uint8p      pRawdata;
-  mng_uint32      iRawlen;
-  mng_retcode     iRetcode;
-  mng_evnt_entryp pEntry;
-  mng_uint8p      pTemp;
-  mng_uint32      iX;
-  mng_uint32      iNamesize;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_EVNT, MNG_LC_START);
-#endif
-
-  pEVNT = (mng_evntp)pChunk;           /* address the proper chunk */
-
-  if (!pEVNT->iCount)                  /* empty ? */
-    iRetcode = write_raw_chunk (pData, pEVNT->sHeader.iChunkname, 0, 0);
-  else
-  {
-    pRawdata  = pData->pWritebuf+8;    /* init output buffer & size */
-    iRawlen   = 0;
-    pTemp     = pRawdata;
-    pEntry    = pEVNT->pEntries;
-
-    for (iX = 0; iX < pEVNT->iCount; iX++)
-    {
-      if (iX)                          /* put separator null-byte, except the first */
-      {
-        *pTemp = 0;
-        pTemp++;
-        iRawlen++;
-      }
-
-      *pTemp     = pEntry->iEventtype;
-      *(pTemp+1) = pEntry->iMasktype;
-      pTemp   += 2;
-      iRawlen += 2;
-
-      switch (pEntry->iMasktype)
-      {
-        case 1 :
-          {
-            mng_put_int32 (pTemp, pEntry->iLeft);
-            mng_put_int32 (pTemp+4, pEntry->iRight);
-            mng_put_int32 (pTemp+8, pEntry->iTop);
-            mng_put_int32 (pTemp+12, pEntry->iBottom);
-            pTemp   += 16;
-            iRawlen += 16;
-            break;
-          }
-        case 2 :
-          {
-            mng_put_uint16 (pTemp, pEntry->iObjectid);
-            pTemp   += 2;
-            iRawlen += 2;
-            break;
-          }
-        case 3 :
-          {
-            mng_put_uint16 (pTemp, pEntry->iObjectid);
-            *(pTemp+2) = pEntry->iIndex;
-            pTemp   += 3;
-            iRawlen += 3;
-            break;
-          }
-        case 4 :
-          {
-            mng_put_int32 (pTemp, pEntry->iLeft);
-            mng_put_int32 (pTemp+4, pEntry->iRight);
-            mng_put_int32 (pTemp+8, pEntry->iTop);
-            mng_put_int32 (pTemp+12, pEntry->iBottom);
-            mng_put_uint16 (pTemp+16, pEntry->iObjectid);
-            pTemp   += 18;
-            iRawlen += 18;
-            break;
-          }
-        case 5 :
-          {
-            mng_put_int32 (pTemp, pEntry->iLeft);
-            mng_put_int32 (pTemp+4, pEntry->iRight);
-            mng_put_int32 (pTemp+8, pEntry->iTop);
-            mng_put_int32 (pTemp+12, pEntry->iBottom);
-            mng_put_uint16 (pTemp+16, pEntry->iObjectid);
-            *(pTemp+18) = pEntry->iIndex;
-            pTemp   += 19;
-            iRawlen += 19;
-            break;
-          }
-      }
-
-      iNamesize = pEntry->iSegmentnamesize;
-
-      if (iNamesize)
-      {
-        MNG_COPY (pTemp, pEntry->zSegmentname, iNamesize);
-        pTemp   += iNamesize;
-        iRawlen += iNamesize;
-      }
-
-      pEntry++;  
-    }
-                                       /* and write it */
-    iRetcode = write_raw_chunk (pData, pEVNT->sHeader.iChunkname,
-                                iRawlen, pRawdata);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_EVNT, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-
-WRITE_CHUNK (mng_write_unknown)
-{
-  mng_unknown_chunkp pUnknown;
-  mng_retcode        iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_UNKNOWN, MNG_LC_START);
-#endif
-                                       /* address the proper chunk */
-  pUnknown = (mng_unknown_chunkp)pChunk;
-                                       /* and write it */
-  iRetcode = write_raw_chunk (pData, pUnknown->sHeader.iChunkname,
-                              pUnknown->iDatasize, pUnknown->pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_UNKNOWN, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-
-/* ************************************************************************** */
-
-#endif /* MNG_INCLUDE_WRITE_PROCS */
-
-/* ************************************************************************** */
-/* * end of file                                                            * */
-/* ************************************************************************** */
-
diff --git a/Source/LibMNG/libmng_chunk_io.h b/Source/LibMNG/libmng_chunk_io.h
deleted file mode 100644
index f8505ba..0000000
--- a/Source/LibMNG/libmng_chunk_io.h
+++ /dev/null
@@ -1,415 +0,0 @@
-/* ************************************************************************** */
-/* *             For conditions of distribution and use,                    * */
-/* *                see copyright notice in libmng.h                        * */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * project   : libmng                                                     * */
-/* * file      : libmng_chunk_io.h         copyright (c) 2000-2007 G.Juyn   * */
-/* * version   : 1.0.109                                                      * */
-/* *                                                                        * */
-/* * purpose   : Chunk I/O routines (definition)                            * */
-/* *                                                                        * */
-/* * author    : G.Juyn                                                     * */
-/* *                                                                        * */
-/* * comment   : Definition of the chunk input/output routines              * */
-/* *                                                                        * */
-/* * changes   : 0.5.1 - 05/04/2000 - G.Juyn                                * */
-/* *             - changed CRC initialization to use dynamic structure      * */
-/* *               (wasn't thread-safe the old way !)                       * */
-/* *             0.5.1 - 05/08/2000 - G.Juyn                                * */
-/* *             - changed write routines definition                        * */
-/* *             - changed strict-ANSI stuff                                * */
-/* *                                                                        * */
-/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
-/* *             - changed file-prefixes                                    * */
-/* *                                                                        * */
-/* *             0.9.3 - 08/26/2000 - G.Juyn                                * */
-/* *             - added MAGN chunk                                         * */
-/* *             0.9.3 - 10/16/2000 - G.Juyn                                * */
-/* *             - added support for JDAA                                   * */
-/* *                                                                        * */
-/* *             1.0.5 - 08/19/2002 - G.Juyn                                * */
-/* *             - B597134 - libmng pollutes the linker namespace           * */
-/* *             1.0.5 - 09/14/2002 - G.Juyn                                * */
-/* *             - added event handling for dynamic MNG                     * */
-/* *                                                                        * */
-/* *             1.0.6 - 07/07/2003 - G.R-P                                 * */
-/* *             - added SKIP_CHUNK and NO_DELTA_PNG support                * */
-/* *             1.0.6 - 07/29/2003 - G.R-P                                 * */
-/* *             - added conditionals around PAST chunk support             * */
-/* *                                                                        * */
-/* *             1.0.7 - 03/24/2004 - G.R-P                                 * */
-/* *             - fixed SKIPCHUNK_itXT and SKIPCHUNK_ztXT typos            * */
-/* *                                                                        * */
-/* *             1.0.9 - 12/07/2004 - G.Juyn                                * */
-/* *             - added conditional MNG_OPTIMIZE_CHUNKREADER               * */
-/* *                                                                        * */
-/* *             1.0.10 - 04/08/2007 - G.Juyn                               * */
-/* *             - added support for mPNG proposal                          * */
-/* *             1.0.10 - 04/12/2007 - G.Juyn                               * */
-/* *             - added support for ANG proposal                           * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
-#pragma option -A                      /* force ANSI-C */
-#endif
-
-#ifndef _libmng_chunk_io_h_
-#define _libmng_chunk_io_h_
-
-/* ************************************************************************** */
-
-mng_uint32 mng_crc (mng_datap  pData,
-                    mng_uint8p buf,
-                    mng_int32  len);
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_READ_PROCS
-
-/* ************************************************************************** */
-
-mng_retcode mng_inflate_buffer (mng_datap  pData,
-                                mng_uint8p pInbuf,
-                                mng_uint32 iInsize,
-                                mng_uint8p *pOutbuf,
-                                mng_uint32 *iOutsize,
-                                mng_uint32 *iRealsize);
-
-/* ************************************************************************** */
-
-#define READ_CHUNK(n) mng_retcode n (mng_datap   pData,    \
-                                     mng_chunkp  pHeader,  \
-                                     mng_uint32  iRawlen,  \
-                                     mng_uint8p  pRawdata, \
-                                     mng_chunkp* ppChunk)
-
-#ifdef MNG_OPTIMIZE_CHUNKREADER
-READ_CHUNK (mng_read_general) ;
-#endif
-
-READ_CHUNK (mng_read_ihdr) ;
-READ_CHUNK (mng_read_plte) ;
-READ_CHUNK (mng_read_idat) ;
-READ_CHUNK (mng_read_iend) ;
-READ_CHUNK (mng_read_trns) ;
-READ_CHUNK (mng_read_gama) ;
-READ_CHUNK (mng_read_chrm) ;
-READ_CHUNK (mng_read_srgb) ;
-#ifndef MNG_SKIPCHUNK_iCCP
-READ_CHUNK (mng_read_iccp) ;
-#endif
-#ifndef MNG_SKIPCHUNK_tEXt
-READ_CHUNK (mng_read_text) ;
-#endif
-#ifndef MNG_SKIPCHUNK_zTXt
-READ_CHUNK (mng_read_ztxt) ;
-#endif
-#ifndef MNG_SKIPCHUNK_iTXt
-READ_CHUNK (mng_read_itxt) ;
-#endif
-#ifndef MNG_SKIPCHUNK_bKGD
-READ_CHUNK (mng_read_bkgd) ;
-#endif
-#ifndef MNG_SKIPCHUNK_pHYs
-READ_CHUNK (mng_read_phys) ;
-#endif
-#ifndef MNG_SKIPCHUNK_sBIT
-READ_CHUNK (mng_read_sbit) ;
-#endif
-#ifndef MNG_SKIPCHUNK_sPLT
-READ_CHUNK (mng_read_splt) ;
-#endif
-#ifndef MNG_SKIPCHUNK_hIST
-READ_CHUNK (mng_read_hist) ;
-#endif
-#ifndef MNG_SKIPCHUNK_tIME
-READ_CHUNK (mng_read_time) ;
-#endif
-READ_CHUNK (mng_read_mhdr) ;
-READ_CHUNK (mng_read_mend) ;
-READ_CHUNK (mng_read_loop) ;
-READ_CHUNK (mng_read_endl) ;
-READ_CHUNK (mng_read_defi) ;
-READ_CHUNK (mng_read_basi) ;
-READ_CHUNK (mng_read_clon) ;
-#ifndef MNG_SKIPCHUNK_PAST
-READ_CHUNK (mng_read_past) ;
-#endif
-READ_CHUNK (mng_read_disc) ;
-READ_CHUNK (mng_read_back) ;
-READ_CHUNK (mng_read_fram) ;
-READ_CHUNK (mng_read_move) ;
-READ_CHUNK (mng_read_clip) ;
-READ_CHUNK (mng_read_show) ;
-READ_CHUNK (mng_read_term) ;
-READ_CHUNK (mng_read_save) ;
-READ_CHUNK (mng_read_seek) ;
-#ifndef MNG_SKIPCHUNK_eXPI
-READ_CHUNK (mng_read_expi) ;
-#endif
-#ifndef MNG_SKIPCHUNK_fPRI
-READ_CHUNK (mng_read_fpri) ;
-#endif
-#ifndef MNG_SKIPCHUNK_pHYg
-READ_CHUNK (mng_read_phyg) ;
-#endif
-#ifdef MNG_INCLUDE_JNG
-READ_CHUNK (mng_read_jhdr) ;
-READ_CHUNK (mng_read_jdaa) ;
-READ_CHUNK (mng_read_jdat) ;
-READ_CHUNK (mng_read_jsep) ;
-#endif
-#ifndef MNG_NO_DELTA_PNG
-READ_CHUNK (mng_read_dhdr) ;
-READ_CHUNK (mng_read_prom) ;
-READ_CHUNK (mng_read_ipng) ;
-READ_CHUNK (mng_read_pplt) ;
-#ifdef MNG_INCLUDE_JNG
-READ_CHUNK (mng_read_ijng) ;
-#endif
-READ_CHUNK (mng_read_drop) ;
-READ_CHUNK (mng_read_dbyk) ;
-READ_CHUNK (mng_read_ordr) ;
-#endif
-READ_CHUNK (mng_read_magn) ;
-#ifndef MNG_SKIPCHUNK_nEED
-READ_CHUNK (mng_read_need) ;
-#endif
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-READ_CHUNK (mng_read_mpng) ;
-#endif
-#ifndef MNG_SKIPCHUNK_evNT
-READ_CHUNK (mng_read_evnt) ;
-#endif
-READ_CHUNK (mng_read_unknown) ;
-
-/* ************************************************************************** */
-
-#else /* MNG_INCLUDE_READ_PROCS */
-#define mng_read_ihdr 0
-#define mng_read_plte 0
-#define mng_read_idat 0
-#define mng_read_iend 0
-#define mng_read_trns 0
-#define mng_read_gama 0
-#define mng_read_chrm 0
-#define mng_read_srgb 0
-#define mng_read_iccp 0
-#define mng_read_text 0
-#define mng_read_ztxt 0
-#define mng_read_itxt 0
-#define mng_read_bkgd 0
-#define mng_read_phys 0
-#define mng_read_sbit 0
-#define mng_read_splt 0
-#define mng_read_hist 0
-#define mng_read_time 0
-#define mng_read_mhdr 0
-#define mng_read_mend 0
-#define mng_read_loop 0
-#define mng_read_endl 0
-#define mng_read_defi 0
-#define mng_read_basi 0
-#define mng_read_clon 0
-#ifndef MNG_SKIPCHUNK_PAST
-#define mng_read_past 0
-#endif
-#define mng_read_disc 0
-#define mng_read_back 0
-#define mng_read_fram 0
-#define mng_read_move 0
-#define mng_read_clip 0
-#define mng_read_show 0
-#define mng_read_term 0
-#define mng_read_save 0
-#define mng_read_seek 0
-#define mng_read_expi 0
-#define mng_read_fpri 0
-#define mng_read_phyg 0
-#ifdef MNG_INCLUDE_JNG
-#define mng_read_jhdr 0
-#define mng_read_jdaa 0
-#define mng_read_jdat 0
-#define mng_read_jsep 0
-#endif
-#ifndef MNG_NO_DELTA_PNG
-#define mng_read_dhdr 0
-#define mng_read_prom 0
-#define mng_read_ipng 0
-#define mng_read_pplt 0
-#ifdef MNG_INCLUDE_JNG
-#define mng_read_ijng 0
-#endif
-#define mng_read_drop 0
-#define mng_read_dbyk 0
-#define mng_read_ordr 0
-#endif
-#define mng_read_magn 0
-#define mng_read_need 0
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-#define mng_read_mpng 0
-#endif
-#define mng_read_evnt 0
-#define mng_read_unknown 0
-#endif /* MNG_INCLUDE_READ_PROCS */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_WRITE_PROCS
-
-#define WRITE_CHUNK(n) mng_retcode n (mng_datap  pData,   \
-                                      mng_chunkp pChunk)
-
-WRITE_CHUNK (mng_write_ihdr) ;
-WRITE_CHUNK (mng_write_plte) ;
-WRITE_CHUNK (mng_write_idat) ;
-WRITE_CHUNK (mng_write_iend) ;
-WRITE_CHUNK (mng_write_trns) ;
-WRITE_CHUNK (mng_write_gama) ;
-WRITE_CHUNK (mng_write_chrm) ;
-WRITE_CHUNK (mng_write_srgb) ;
-WRITE_CHUNK (mng_write_iccp) ;
-WRITE_CHUNK (mng_write_text) ;
-WRITE_CHUNK (mng_write_ztxt) ;
-WRITE_CHUNK (mng_write_itxt) ;
-WRITE_CHUNK (mng_write_bkgd) ;
-WRITE_CHUNK (mng_write_phys) ;
-WRITE_CHUNK (mng_write_sbit) ;
-WRITE_CHUNK (mng_write_splt) ;
-WRITE_CHUNK (mng_write_hist) ;
-WRITE_CHUNK (mng_write_time) ;
-WRITE_CHUNK (mng_write_mhdr) ;
-WRITE_CHUNK (mng_write_mend) ;
-WRITE_CHUNK (mng_write_loop) ;
-WRITE_CHUNK (mng_write_endl) ;
-WRITE_CHUNK (mng_write_defi) ;
-WRITE_CHUNK (mng_write_basi) ;
-WRITE_CHUNK (mng_write_clon) ;
-#ifndef MNG_SKIPCHUNK_PAST
-WRITE_CHUNK (mng_write_past) ;
-#endif
-WRITE_CHUNK (mng_write_disc) ;
-WRITE_CHUNK (mng_write_back) ;
-WRITE_CHUNK (mng_write_fram) ;
-WRITE_CHUNK (mng_write_move) ;
-WRITE_CHUNK (mng_write_clip) ;
-WRITE_CHUNK (mng_write_show) ;
-WRITE_CHUNK (mng_write_term) ;
-WRITE_CHUNK (mng_write_save) ;
-WRITE_CHUNK (mng_write_seek) ;
-WRITE_CHUNK (mng_write_expi) ;
-WRITE_CHUNK (mng_write_fpri) ;
-WRITE_CHUNK (mng_write_phyg) ;
-#ifdef MNG_INCLUDE_JNG
-WRITE_CHUNK (mng_write_jhdr) ;
-WRITE_CHUNK (mng_write_jdaa) ;
-WRITE_CHUNK (mng_write_jdat) ;
-WRITE_CHUNK (mng_write_jsep) ;
-#endif
-#ifndef MNG_NO_DELTA_PNG
-WRITE_CHUNK (mng_write_dhdr) ;
-WRITE_CHUNK (mng_write_prom) ;
-WRITE_CHUNK (mng_write_ipng) ;
-WRITE_CHUNK (mng_write_pplt) ;
-#ifdef MNG_INCLUDE_JNG
-WRITE_CHUNK (mng_write_ijng) ;
-#endif
-WRITE_CHUNK (mng_write_drop) ;
-WRITE_CHUNK (mng_write_dbyk) ;
-WRITE_CHUNK (mng_write_ordr) ;
-#endif
-WRITE_CHUNK (mng_write_magn) ;
-WRITE_CHUNK (mng_write_need) ;
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-WRITE_CHUNK (mng_write_mpng) ;
-#endif
-#ifdef MNG_INCLUDE_ANG_PROPOSAL
-WRITE_CHUNK (mng_write_ahdr) ;
-WRITE_CHUNK (mng_write_adat) ;
-#endif
-WRITE_CHUNK (mng_write_evnt) ;
-WRITE_CHUNK (mng_write_unknown) ;
-
-/* ************************************************************************** */
-
-#else /* MNG_INCLUDE_WRITE_PROCS */
-#define mng_write_ihdr 0
-#define mng_write_plte 0
-#define mng_write_idat 0
-#define mng_write_iend 0
-#define mng_write_trns 0
-#define mng_write_gama 0
-#define mng_write_chrm 0
-#define mng_write_srgb 0
-#define mng_write_iccp 0
-#define mng_write_text 0
-#define mng_write_ztxt 0
-#define mng_write_itxt 0
-#define mng_write_bkgd 0
-#define mng_write_phys 0
-#define mng_write_sbit 0
-#define mng_write_splt 0
-#define mng_write_hist 0
-#define mng_write_time 0
-#define mng_write_mhdr 0
-#define mng_write_mend 0
-#define mng_write_loop 0
-#define mng_write_endl 0
-#define mng_write_defi 0
-#define mng_write_basi 0
-#define mng_write_clon 0
-#ifndef MNG_SKIPCHUNK_PAST
-#define mng_write_past 0
-#endif
-#define mng_write_disc 0
-#define mng_write_back 0
-#define mng_write_fram 0
-#define mng_write_move 0
-#define mng_write_clip 0
-#define mng_write_show 0
-#define mng_write_term 0
-#define mng_write_save 0
-#define mng_write_seek 0
-#define mng_write_expi 0
-#define mng_write_fpri 0
-#define mng_write_phyg 0
-#ifdef MNG_INCLUDE_JNG
-#define mng_write_jhdr 0
-#define mng_write_jdaa 0
-#define mng_write_jdat 0
-#define mng_write_jsep 0
-#endif
-#ifndef MNG_NO_DELTA_PNG
-#define mng_write_dhdr 0
-#define mng_write_prom 0
-#define mng_write_ipng 0
-#define mng_write_pplt 0
-#ifdef MNG_INCLUDE_JNG
-#define mng_write_ijng 0
-#endif
-#define mng_write_drop 0
-#define mng_write_dbyk 0
-#define mng_write_ordr 0
-#endif
-#define mng_write_magn 0
-#define mng_write_need 0
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-#define mng_write_mpng 0
-#endif
-#ifdef MNG_INCLUDE_ANG_PROPOSAL
-#define mng_write_adat 0
-#define mng_write_ahdr 0
-#endif
-#define mng_write_evnt 0
-#define mng_write_unknown 0
-#endif /* MNG_INCLUDE_WRITE_PROCS */
-
-/* ************************************************************************** */
-
-#endif /* _libmng_chunk_io_h_ */
-
-/* ************************************************************************** */
-/* * end of file                                                            * */
-/* ************************************************************************** */
diff --git a/Source/LibMNG/libmng_chunk_prc.c b/Source/LibMNG/libmng_chunk_prc.c
deleted file mode 100644
index 6c8e589..0000000
--- a/Source/LibMNG/libmng_chunk_prc.c
+++ /dev/null
@@ -1,4452 +0,0 @@
-/* ************************************************************************** */
-/* *             For conditions of distribution and use,                    * */
-/* *                see copyright notice in libmng.h                        * */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * project   : libmng                                                     * */
-/* * file      : libmng_chunk_prc.c        copyright (c) 2000-2005 G.Juyn   * */
-/* * version   : 1.0.10                                                     * */
-/* *                                                                        * */
-/* * purpose   : Chunk initialization & cleanup (implementation)            * */
-/* *                                                                        * */
-/* * author    : G.Juyn                                                     * */
-/* *                                                                        * */
-/* * comment   : implementation of the chunk initialization & cleanup       * */
-/* *             routines                                                   * */
-/* *                                                                        * */
-/* * changes   : 0.5.1 - 05/08/2000 - G.Juyn                                * */
-/* *             - changed strict-ANSI stuff                                * */
-/* *             0.5.1 - 05/12/2000 - G.Juyn                                * */
-/* *             - changed trace to macro for callback error-reporting      * */
-/* *                                                                        * */
-/* *             0.9.1 - 07/19/2000 - G.Juyn                                * */
-/* *             - fixed creation-code                                      * */
-/* *                                                                        * */
-/* *             0.9.2 - 07/31/2000 - G.Juyn                                * */
-/* *             - put add_chunk() inside MNG_INCLUDE_WRITE_PROCS wrapper   * */
-/* *             0.9.2 - 08/01/2000 - G.Juyn                                * */
-/* *             - wrapper for add_chunk() changed                          * */
-/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
-/* *             - changed file-prefixes                                    * */
-/* *                                                                        * */
-/* *             0.9.3 - 08/26/2000 - G.Juyn                                * */
-/* *             - added MAGN chunk                                         * */
-/* *             0.9.3 - 10/16/2000 - G.Juyn                                * */
-/* *             - added support for JDAA                                   * */
-/* *                                                                        * */
-/* *             1.0.5 - 08/19/2002 - G.Juyn                                * */
-/* *             - B597134 - libmng pollutes the linker namespace           * */
-/* *             - added HLAPI function to copy chunks                      * */
-/* *             1.0.5 - 09/14/2002 - G.Juyn                                * */
-/* *             - added event handling for dynamic MNG                     * */
-/* *             1.0.5 - 10/04/2002 - G.Juyn                                * */
-/* *             - fixed chunk-storage for evNT chunk                       * */
-/* *             1.0.5 - 10/17/2002 - G.Juyn                                * */
-/* *             - fixed issue in freeing evNT chunk                        * */
-/* *                                                                        * */
-/* *             1.0.6 - 07/07/2003 - G.R-P                                 * */
-/* *             - added MNG_SKIPCHUNK_cHNK footprint optimizations         * */
-/* *             - added MNG_NO_DELTA_PNG reduction feature                 * */
-/* *             1.0.6 - 07/14/2003 - G.R-P                                 * */
-/* *             - added MNG_NO_LOOP_SIGNALS_SUPPORTED conditional          * */
-/* *             1.0.6 - 07/29/2003 - G.R-P                                 * */
-/* *             - added conditionals around PAST chunk support             * */
-/* *             1.0.6 - 08/17/2003 - G.R-P                                 * */
-/* *             - added conditionals around non-VLC chunk support          * */
-/* *                                                                        * */
-/* *             1.0.7 - 03/24/2004 - G.R-P                                 * */
-/* *             - fixed SKIPCHUNK_eXPI -> fPRI typo                        * */
-/* *                                                                        * */
-/* *             1.0.9 - 09/25/2004 - G.Juyn                                * */
-/* *             - replaced MNG_TWEAK_LARGE_FILES with permanent solution   * */
-/* *             1.0.9 - 12/05/2004 - G.Juyn                                * */
-/* *             - added conditional MNG_OPTIMIZE_CHUNKINITFREE             * */
-/* *             1.0.9 - 12/06/2004 - G.Juyn                                * */
-/* *             - added conditional MNG_OPTIMIZE_CHUNKASSIGN               * */
-/* *             1.0.9 - 12/20/2004 - G.Juyn                                * */
-/* *             - cleaned up macro-invocations (thanks to D. Airlie)       * */
-/* *                                                                        * */
-/* *             1.0.10 - 07/30/2005 - G.Juyn                               * */
-/* *             - fixed problem with CLON object during readdisplay()      * */
-/* *             1.0.10 - 04/08/2007 - G.Juyn                               * */
-/* *             - added support for mPNG proposal                          * */
-/* *             1.0.10 - 04/12/2007 - G.Juyn                               * */
-/* *             - added support for ANG proposal                           * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#include "libmng.h"
-#include "libmng_data.h"
-#include "libmng_error.h"
-#include "libmng_trace.h"
-#ifdef __BORLANDC__
-#pragma hdrstop
-#endif
-#include "libmng_memory.h"
-#include "libmng_chunks.h"
-#include "libmng_chunk_prc.h"
-
-#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
-#pragma option -A                      /* force ANSI-C */
-#endif
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * General chunk routines                                                 * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-void mng_add_chunk (mng_datap  pData,
-                    mng_chunkp pChunk)
-{
-  if (!pData->pFirstchunk)             /* list is still empty ? */
-  {
-    pData->pFirstchunk      = pChunk;  /* then this becomes the first */
-    
-#ifdef MNG_SUPPORT_WRITE
-    if (!pData->iFirstchunkadded)
-    {
-      pData->iFirstchunkadded = ((mng_chunk_headerp)pChunk)->iChunkname;
-#endif
-
-      if (((mng_chunk_headerp)pChunk)->iChunkname == MNG_UINT_IHDR)
-        pData->eImagetype     = mng_it_png;
-      else
-#ifdef MNG_INCLUDE_JNG
-      if (((mng_chunk_headerp)pChunk)->iChunkname == MNG_UINT_JHDR)
-        pData->eImagetype     = mng_it_jng;
-      else
-#endif
-        pData->eImagetype     = mng_it_mng;
-
-      pData->eSigtype         = pData->eImagetype;
-#ifdef MNG_SUPPORT_WRITE
-    }
-#endif
-  }
-  else
-  {                                    /* else we make appropriate links */
-    ((mng_chunk_headerp)pChunk)->pPrev = pData->pLastchunk;
-    ((mng_chunk_headerp)pData->pLastchunk)->pNext = pChunk;
-  }
-
-  pData->pLastchunk = pChunk;          /* and it's always the last */
-
-  return;
-}
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Chunk specific initialization routines                                 * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-INIT_CHUNK_HDR (mng_init_general)
-{
-  MNG_ALLOC (pData, *ppChunk, ((mng_chunk_headerp)pHeader)->iChunksize);
-  MNG_COPY (*ppChunk, pHeader, sizeof (mng_chunk_header));
-  return MNG_NOERROR;
-}
-
-#else /* MNG_OPTIMIZE_CHUNKINITFREE */
-
-/* ************************************************************************** */
-
-INIT_CHUNK_HDR (mng_init_ihdr)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_IHDR, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_ihdr));
-  ((mng_ihdrp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_IHDR, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-INIT_CHUNK_HDR (mng_init_plte)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_PLTE, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_plte));
-  ((mng_pltep)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_PLTE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-INIT_CHUNK_HDR (mng_init_idat)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_IDAT, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_idat));
-  ((mng_idatp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_IDAT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-INIT_CHUNK_HDR (mng_init_iend)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_IEND, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_iend));
-  ((mng_iendp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_IEND, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-INIT_CHUNK_HDR (mng_init_trns)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_TRNS, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_trns));
-  ((mng_trnsp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_TRNS, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_gAMA
-INIT_CHUNK_HDR (mng_init_gama)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_GAMA, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_gama));
-  ((mng_gamap)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_GAMA, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_cHRM
-INIT_CHUNK_HDR (mng_init_chrm)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_CHRM, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_chrm));
-  ((mng_chrmp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_CHRM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_sRGB
-INIT_CHUNK_HDR (mng_init_srgb)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_SRGB, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_srgb));
-  ((mng_srgbp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_SRGB, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_iCCP
-INIT_CHUNK_HDR (mng_init_iccp)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_ICCP, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_iccp));
-  ((mng_iccpp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_ICCP, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_tEXt
-INIT_CHUNK_HDR (mng_init_text)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_TEXT, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_text));
-  ((mng_textp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_TEXT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_zTXt
-INIT_CHUNK_HDR (mng_init_ztxt)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_ZTXT, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_ztxt));
-  ((mng_ztxtp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_ZTXT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_iTXt
-INIT_CHUNK_HDR (mng_init_itxt)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_ITXT, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_itxt));
-  ((mng_itxtp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_ITXT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_bKGD
-INIT_CHUNK_HDR (mng_init_bkgd)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_BKGD, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_bkgd));
-  ((mng_bkgdp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_BKGD, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_pHYs
-INIT_CHUNK_HDR (mng_init_phys)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_PHYS, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_phys));
-  ((mng_physp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_PHYS, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_sBIT
-INIT_CHUNK_HDR (mng_init_sbit)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_SBIT, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_sbit));
-  ((mng_sbitp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_SBIT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_sPLT
-INIT_CHUNK_HDR (mng_init_splt)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_SPLT, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_splt));
-  ((mng_spltp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_SPLT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_hIST
-INIT_CHUNK_HDR (mng_init_hist)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_HIST, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_hist));
-  ((mng_histp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_HIST, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_tIME
-INIT_CHUNK_HDR (mng_init_time)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_TIME, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_time));
-  ((mng_timep)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_TIME, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-INIT_CHUNK_HDR (mng_init_mhdr)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_MHDR, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_mhdr));
-  ((mng_mhdrp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_MHDR, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-INIT_CHUNK_HDR (mng_init_mend)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_MEND, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_mend));
-  ((mng_mendp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_MEND, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_LOOP
-INIT_CHUNK_HDR (mng_init_loop)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_LOOP, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_loop));
-  ((mng_loopp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_LOOP, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-INIT_CHUNK_HDR (mng_init_endl)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_ENDL, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_endl));
-  ((mng_endlp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_ENDL, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_DEFI
-INIT_CHUNK_HDR (mng_init_defi)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_DEFI, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_defi));
-  ((mng_defip)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_DEFI, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_BASI
-INIT_CHUNK_HDR (mng_init_basi)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_BASI, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_basi));
-  ((mng_basip)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_BASI, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_CLON
-INIT_CHUNK_HDR (mng_init_clon)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_CLON, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_clon));
-  ((mng_clonp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_CLON, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_PAST
-INIT_CHUNK_HDR (mng_init_past)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_PAST, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_past));
-  ((mng_pastp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_PAST, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_DISC
-INIT_CHUNK_HDR (mng_init_disc)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_DISC, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_disc));
-  ((mng_discp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_DISC, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_BACK
-INIT_CHUNK_HDR (mng_init_back)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_BACK, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_back));
-  ((mng_backp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_BACK, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_FRAM
-INIT_CHUNK_HDR (mng_init_fram)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_FRAM, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_fram));
-  ((mng_framp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_FRAM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_MOVE
-INIT_CHUNK_HDR (mng_init_move)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_MOVE, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_move));
-  ((mng_movep)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_MOVE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_CLIP
-INIT_CHUNK_HDR (mng_init_clip)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_CLIP, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_clip));
-  ((mng_clipp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_CLIP, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_SHOW
-INIT_CHUNK_HDR (mng_init_show)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_SHOW, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_show));
-  ((mng_showp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_SHOW, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_TERM
-INIT_CHUNK_HDR (mng_init_term)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_TERM, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_term));
-  ((mng_termp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_TERM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_SAVE
-INIT_CHUNK_HDR (mng_init_save)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_SAVE, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_save));
-  ((mng_savep)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_SAVE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_SEEK
-INIT_CHUNK_HDR (mng_init_seek)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_SEEK, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_seek));
-  ((mng_seekp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_SEEK, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_eXPI
-INIT_CHUNK_HDR (mng_init_expi)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_EXPI, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_expi));
-  ((mng_expip)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_EXPI, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_fPRI
-INIT_CHUNK_HDR (mng_init_fpri)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_FPRI, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_fpri));
-  ((mng_fprip)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_FPRI, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_nEED
-INIT_CHUNK_HDR (mng_init_need)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_NEED, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_need));
-  ((mng_needp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_NEED, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_pHYg
-INIT_CHUNK_HDR (mng_init_phyg)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_PHYG, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_phyg));
-  ((mng_phygp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_PHYG, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-INIT_CHUNK_HDR (mng_init_jhdr)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_JHDR, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_jhdr));
-  ((mng_jhdrp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_JHDR, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_INCLUDE_JNG */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-INIT_CHUNK_HDR (mng_init_jdaa)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_JDAA, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_jdaa));
-  ((mng_jdaap)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_JDAA, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_INCLUDE_JNG */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-INIT_CHUNK_HDR (mng_init_jdat)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_JDAT, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_jdat));
-  ((mng_jdatp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_JDAT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_INCLUDE_JNG */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-INIT_CHUNK_HDR (mng_init_jsep)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_JSEP, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_jsep));
-  ((mng_jsepp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_JSEP, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_INCLUDE_JNG */
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-INIT_CHUNK_HDR (mng_init_dhdr)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_DHDR, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_dhdr));
-  ((mng_dhdrp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_DHDR, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-INIT_CHUNK_HDR (mng_init_prom)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_PROM, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_prom));
-  ((mng_promp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_PROM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-INIT_CHUNK_HDR (mng_init_ipng)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_IPNG, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_ipng));
-  ((mng_ipngp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_IPNG, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-INIT_CHUNK_HDR (mng_init_pplt)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_PPLT, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_pplt));
-  ((mng_ppltp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_PPLT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-#ifdef MNG_INCLUDE_JNG
-INIT_CHUNK_HDR (mng_init_ijng)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_IJNG, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_ijng));
-  ((mng_ijngp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_IJNG, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-INIT_CHUNK_HDR (mng_init_drop)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_DROP, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_drop));
-  ((mng_dropp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_DROP, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_SKIPCHUNK_DBYK
-INIT_CHUNK_HDR (mng_init_dbyk)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_DBYK, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_dbyk));
-  ((mng_dbykp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_DBYK, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_SKIPCHUNK_ORDR
-INIT_CHUNK_HDR (mng_init_ordr)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_ORDR, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_ordr));
-  ((mng_ordrp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_ORDR, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_MAGN
-INIT_CHUNK_HDR (mng_init_magn)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_MAGN, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_magn));
-  ((mng_magnp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_MAGN, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_evNT
-INIT_CHUNK_HDR (mng_init_evnt)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_EVNT, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_evnt));
-  ((mng_evntp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_EVNT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-INIT_CHUNK_HDR (mng_init_unknown)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_UNKNOWN, MNG_LC_START);
-#endif
-
-  MNG_ALLOC (pData, *ppChunk, sizeof (mng_unknown_chunk));
-  ((mng_unknown_chunkp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_UNKNOWN, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#endif /* MNG_OPTIMIZE_CHUNKINITFREE */
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Chunk specific cleanup routines                                        * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-FREE_CHUNK_HDR (mng_free_general)
-{
-  MNG_FREEX (pData, pHeader, ((mng_chunk_headerp)pHeader)->iChunksize);
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-FREE_CHUNK_HDR (mng_free_ihdr)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_IHDR, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pHeader, sizeof (mng_ihdr));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_IHDR, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-FREE_CHUNK_HDR (mng_free_plte)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_PLTE, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pHeader, sizeof (mng_plte));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_PLTE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-FREE_CHUNK_HDR (mng_free_idat)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_IDAT, MNG_LC_START);
-#endif
-
-  if (((mng_idatp)pHeader)->iDatasize)
-    MNG_FREEX (pData, ((mng_idatp)pHeader)->pData,
-                      ((mng_idatp)pHeader)->iDatasize);
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  MNG_FREEX (pData, pHeader, sizeof (mng_idat));
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_IDAT, MNG_LC_END);
-#endif
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  return MNG_NOERROR;
-#else
-  return mng_free_general(pData, pHeader);
-#endif
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-FREE_CHUNK_HDR (mng_free_iend)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_IEND, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pHeader, sizeof (mng_iend));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_IEND, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-FREE_CHUNK_HDR (mng_free_trns)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_TRNS, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pHeader, sizeof (mng_trns));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_TRNS, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-#ifndef MNG_SKIPCHUNK_gAMA
-FREE_CHUNK_HDR (mng_free_gama)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_GAMA, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pHeader, sizeof (mng_gama));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_GAMA, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-#ifndef MNG_SKIPCHUNK_cHRM
-FREE_CHUNK_HDR (mng_free_chrm)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_CHRM, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pHeader, sizeof (mng_chrm));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_CHRM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-#ifndef MNG_SKIPCHUNK_sRGB
-FREE_CHUNK_HDR (mng_free_srgb)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_SRGB, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pHeader, sizeof (mng_srgb));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_SRGB, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_iCCP
-FREE_CHUNK_HDR (mng_free_iccp)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ICCP, MNG_LC_START);
-#endif
-
-  if (((mng_iccpp)pHeader)->iNamesize)
-    MNG_FREEX (pData, ((mng_iccpp)pHeader)->zName,
-                      ((mng_iccpp)pHeader)->iNamesize + 1);
-
-  if (((mng_iccpp)pHeader)->iProfilesize)
-    MNG_FREEX (pData, ((mng_iccpp)pHeader)->pProfile,
-                      ((mng_iccpp)pHeader)->iProfilesize);
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  MNG_FREEX (pData, pHeader, sizeof (mng_iccp));
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ICCP, MNG_LC_END);
-#endif
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  return MNG_NOERROR;
-#else
-  return mng_free_general(pData, pHeader);
-#endif
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_tEXt
-FREE_CHUNK_HDR (mng_free_text)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_TEXT, MNG_LC_START);
-#endif
-
-  if (((mng_textp)pHeader)->iKeywordsize)
-    MNG_FREEX (pData, ((mng_textp)pHeader)->zKeyword,
-                      ((mng_textp)pHeader)->iKeywordsize + 1);
-
-  if (((mng_textp)pHeader)->iTextsize)
-    MNG_FREEX (pData, ((mng_textp)pHeader)->zText,
-                      ((mng_textp)pHeader)->iTextsize + 1);
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  MNG_FREEX (pData, pHeader, sizeof (mng_text));
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_TEXT, MNG_LC_END);
-#endif
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  return MNG_NOERROR;
-#else
-  return mng_free_general(pData, pHeader);
-#endif
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_zTXt
-FREE_CHUNK_HDR (mng_free_ztxt)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ZTXT, MNG_LC_START);
-#endif
-
-  if (((mng_ztxtp)pHeader)->iKeywordsize)
-    MNG_FREEX (pData, ((mng_ztxtp)pHeader)->zKeyword,
-                      ((mng_ztxtp)pHeader)->iKeywordsize + 1);
-
-  if (((mng_ztxtp)pHeader)->iTextsize)
-    MNG_FREEX (pData, ((mng_ztxtp)pHeader)->zText,
-                      ((mng_ztxtp)pHeader)->iTextsize);
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  MNG_FREEX (pData, pHeader, sizeof (mng_ztxt));
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ZTXT, MNG_LC_END);
-#endif
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  return MNG_NOERROR;
-#else
-  return mng_free_general(pData, pHeader);
-#endif
-}
-#endif
-
-/* ************************************************************************** */
-#ifndef MNG_SKIPCHUNK_iTXt
-FREE_CHUNK_HDR (mng_free_itxt)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ITXT, MNG_LC_START);
-#endif
-
-  if (((mng_itxtp)pHeader)->iKeywordsize)
-    MNG_FREEX (pData, ((mng_itxtp)pHeader)->zKeyword,
-                      ((mng_itxtp)pHeader)->iKeywordsize + 1);
-
-  if (((mng_itxtp)pHeader)->iLanguagesize)
-    MNG_FREEX (pData, ((mng_itxtp)pHeader)->zLanguage,
-                      ((mng_itxtp)pHeader)->iLanguagesize + 1);
-
-  if (((mng_itxtp)pHeader)->iTranslationsize)
-    MNG_FREEX (pData, ((mng_itxtp)pHeader)->zTranslation,
-                      ((mng_itxtp)pHeader)->iTranslationsize + 1);
-
-  if (((mng_itxtp)pHeader)->iTextsize)
-    MNG_FREEX (pData, ((mng_itxtp)pHeader)->zText,
-                      ((mng_itxtp)pHeader)->iTextsize);
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  MNG_FREEX (pData, pHeader, sizeof (mng_itxt));
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ITXT, MNG_LC_END);
-#endif
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  return MNG_NOERROR;
-#else
-  return mng_free_general(pData, pHeader);
-#endif
-}
-#endif
-
-/* ************************************************************************** */
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-FREE_CHUNK_HDR (mng_free_mpng)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_MPNG, MNG_LC_START);
-#endif
-
-  if (((mng_mpngp)pHeader)->iFramessize)
-    MNG_FREEX (pData, ((mng_mpngp)pHeader)->pFrames,
-                      ((mng_mpngp)pHeader)->iFramessize);
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  MNG_FREEX (pData, pHeader, sizeof (mng_mpng));
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_MPNG, MNG_LC_END);
-#endif
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  return MNG_NOERROR;
-#else
-  return mng_free_general(pData, pHeader);
-#endif
-}
-#endif
-
-/* ************************************************************************** */
-#ifdef MNG_INCLUDE_ANG_PROPOSAL
-FREE_CHUNK_HDR (mng_free_adat)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ADAT, MNG_LC_START);
-#endif
-
-  if (((mng_adatp)pHeader)->iTilessize)
-    MNG_FREEX (pData, ((mng_adatp)pHeader)->pTiles, ((mng_adatp)pHeader)->iTilessize);
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  MNG_FREEX (pData, pHeader, sizeof (mng_adat));
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ADAT, MNG_LC_END);
-#endif
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  return MNG_NOERROR;
-#else
-  return mng_free_general(pData, pHeader);
-#endif
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-#ifndef MNG_SKIPCHUNK_bKGD
-FREE_CHUNK_HDR (mng_free_bkgd)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_BKGD, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pHeader, sizeof (mng_bkgd));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_BKGD, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-#ifndef MNG_SKIPCHUNK_pHYs
-FREE_CHUNK_HDR (mng_free_phys)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_PHYS, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pHeader, sizeof (mng_phys));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_PHYS, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-#ifndef MNG_SKIPCHUNK_sBIT
-FREE_CHUNK_HDR (mng_free_sbit)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_SBIT, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pHeader, sizeof (mng_sbit));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_SBIT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_sPLT
-FREE_CHUNK_HDR (mng_free_splt)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_SPLT, MNG_LC_START);
-#endif
-
-  if (((mng_spltp)pHeader)->iNamesize)
-    MNG_FREEX (pData, ((mng_spltp)pHeader)->zName,
-                      ((mng_spltp)pHeader)->iNamesize + 1);
-
-  if (((mng_spltp)pHeader)->iEntrycount)
-    MNG_FREEX (pData, ((mng_spltp)pHeader)->pEntries,
-                      ((mng_spltp)pHeader)->iEntrycount *
-                      (((mng_spltp)pHeader)->iSampledepth * 3 + sizeof (mng_uint16)) );
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  MNG_FREEX (pData, pHeader, sizeof (mng_splt));
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_SPLT, MNG_LC_END);
-#endif
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  return MNG_NOERROR;
-#else
-  return mng_free_general(pData, pHeader);
-#endif
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-#ifndef MNG_SKIPCHUNK_hIST
-FREE_CHUNK_HDR (mng_free_hist)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_HIST, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pHeader, sizeof (mng_hist));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_HIST, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-#ifndef MNG_SKIPCHUNK_tIME
-FREE_CHUNK_HDR (mng_free_time)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_TIME, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pHeader, sizeof (mng_time));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_TIME, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-FREE_CHUNK_HDR (mng_free_mhdr)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_MHDR, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pHeader, sizeof (mng_mhdr));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_MHDR, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-FREE_CHUNK_HDR (mng_free_mend)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_MEND, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pHeader, sizeof (mng_mend));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_MEND, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_LOOP
-FREE_CHUNK_HDR (mng_free_loop)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_LOOP, MNG_LC_START);
-#endif
-
-#ifndef MNG_NO_LOOP_SIGNALS_SUPPORTED
-  if (((mng_loopp)pHeader)->iCount)
-    MNG_FREEX (pData, ((mng_loopp)pHeader)->pSignals,
-                      ((mng_loopp)pHeader)->iCount * sizeof (mng_uint32) );
-#endif
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  MNG_FREEX (pData, pHeader, sizeof (mng_loop));
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_LOOP, MNG_LC_END);
-#endif
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  return MNG_NOERROR;
-#else
-  return mng_free_general(pData, pHeader);
-#endif
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-FREE_CHUNK_HDR (mng_free_endl)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ENDL, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pHeader, sizeof (mng_endl));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ENDL, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-#ifndef MNG_SKIPCHUNK_DEFI
-FREE_CHUNK_HDR (mng_free_defi)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_DEFI, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pHeader, sizeof (mng_defi));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_DEFI, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-#ifndef MNG_SKIPCHUNK_BASI
-FREE_CHUNK_HDR (mng_free_basi)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_BASI, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pHeader, sizeof (mng_basi));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_BASI, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-#ifndef MNG_SKIPCHUNK_CLON
-FREE_CHUNK_HDR (mng_free_clon)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_CLON, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pHeader, sizeof (mng_clon));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_CLON, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_PAST
-FREE_CHUNK_HDR (mng_free_past)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_PAST, MNG_LC_START);
-#endif
-
-  if (((mng_pastp)pHeader)->iCount)
-    MNG_FREEX (pData, ((mng_pastp)pHeader)->pSources,
-                      ((mng_pastp)pHeader)->iCount * sizeof (mng_past_source) );
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  MNG_FREEX (pData, pHeader, sizeof (mng_past));
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_PAST, MNG_LC_END);
-#endif
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  return MNG_NOERROR;
-#else
-  return mng_free_general(pData, pHeader);
-#endif
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_DISC
-FREE_CHUNK_HDR (mng_free_disc)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_DISC, MNG_LC_START);
-#endif
-
-  if (((mng_discp)pHeader)->iCount)
-    MNG_FREEX (pData, ((mng_discp)pHeader)->pObjectids,
-                      ((mng_discp)pHeader)->iCount * sizeof (mng_uint16) );
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  MNG_FREEX (pData, pHeader, sizeof (mng_disc));
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_DISC, MNG_LC_END);
-#endif
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  return MNG_NOERROR;
-#else
-  return mng_free_general(pData, pHeader);
-#endif
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-#ifndef MNG_SKIPCHUNK_BACK
-FREE_CHUNK_HDR (mng_free_back)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_BACK, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pHeader, sizeof (mng_back));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_BACK, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_FRAM
-FREE_CHUNK_HDR (mng_free_fram)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_FRAM, MNG_LC_START);
-#endif
-
-  if (((mng_framp)pHeader)->iNamesize)
-    MNG_FREEX (pData, ((mng_framp)pHeader)->zName,
-                      ((mng_framp)pHeader)->iNamesize + 1);
-
-  if (((mng_framp)pHeader)->iCount)
-    MNG_FREEX (pData, ((mng_framp)pHeader)->pSyncids,
-                      ((mng_framp)pHeader)->iCount * sizeof (mng_uint32) );
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  MNG_FREEX (pData, pHeader, sizeof (mng_fram));
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_FRAM, MNG_LC_END);
-#endif
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  return MNG_NOERROR;
-#else
-  return mng_free_general(pData, pHeader);
-#endif
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-#ifndef MNG_SKIPCHUNK_MOVE
-FREE_CHUNK_HDR (mng_free_move)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_MOVE, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pHeader, sizeof (mng_move));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_MOVE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-#ifndef MNG_SKIPCHUNK_CLIP
-FREE_CHUNK_HDR (mng_free_clip)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_CLIP, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pHeader, sizeof (mng_clip));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_CLIP, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-#ifndef MNG_SKIPCHUNK_SHOW
-FREE_CHUNK_HDR (mng_free_show)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_SHOW, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pHeader, sizeof (mng_show));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_SHOW, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-#ifndef MNG_SKIPCHUNK_TERM
-FREE_CHUNK_HDR (mng_free_term)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_TERM, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pHeader, sizeof (mng_term));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_TERM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_SAVE
-FREE_CHUNK_HDR (mng_free_save)
-{
-  mng_save_entryp pEntry = ((mng_savep)pHeader)->pEntries;
-  mng_uint32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_SAVE, MNG_LC_START);
-#endif
-
-  for (iX = 0; iX < ((mng_savep)pHeader)->iCount; iX++)
-  {
-    if (pEntry->iNamesize)
-      MNG_FREEX (pData, pEntry->zName, pEntry->iNamesize);
-
-    pEntry = pEntry + sizeof (mng_save_entry);
-  }
-
-  if (((mng_savep)pHeader)->iCount)
-    MNG_FREEX (pData, ((mng_savep)pHeader)->pEntries,
-                      ((mng_savep)pHeader)->iCount * sizeof (mng_save_entry) );
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  MNG_FREEX (pData, pHeader, sizeof (mng_save));
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_SAVE, MNG_LC_END);
-#endif
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  return MNG_NOERROR;
-#else
-  return mng_free_general(pData, pHeader);
-#endif
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_SEEK
-FREE_CHUNK_HDR (mng_free_seek)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_SEEK, MNG_LC_START);
-#endif
-
-  if (((mng_seekp)pHeader)->iNamesize)
-    MNG_FREEX (pData, ((mng_seekp)pHeader)->zName,
-                      ((mng_seekp)pHeader)->iNamesize + 1);
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  MNG_FREEX (pData, pHeader, sizeof (mng_seek));
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_SEEK, MNG_LC_END);
-#endif
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  return MNG_NOERROR;
-#else
-  return mng_free_general(pData, pHeader);
-#endif
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_eXPI
-FREE_CHUNK_HDR (mng_free_expi)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_EXPI, MNG_LC_START);
-#endif
-
-  if (((mng_expip)pHeader)->iNamesize)
-    MNG_FREEX (pData, ((mng_expip)pHeader)->zName,
-                      ((mng_expip)pHeader)->iNamesize + 1);
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  MNG_FREEX (pData, pHeader, sizeof (mng_expi));
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_EXPI, MNG_LC_END);
-#endif
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  return MNG_NOERROR;
-#else
-  return mng_free_general(pData, pHeader);
-#endif
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-#ifndef MNG_SKIPCHUNK_fPRI
-FREE_CHUNK_HDR (mng_free_fpri)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_FPRI, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pHeader, sizeof (mng_fpri));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_FPRI, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_nEED
-FREE_CHUNK_HDR (mng_free_need)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_NEED, MNG_LC_START);
-#endif
-
-  if (((mng_needp)pHeader)->iKeywordssize)
-    MNG_FREEX (pData, ((mng_needp)pHeader)->zKeywords,
-                      ((mng_needp)pHeader)->iKeywordssize + 1);
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  MNG_FREEX (pData, pHeader, sizeof (mng_need));
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_NEED, MNG_LC_END);
-#endif
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  return MNG_NOERROR;
-#else
-  return mng_free_general(pData, pHeader);
-#endif
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-#ifndef MNG_SKIPCHUNK_pHYg
-FREE_CHUNK_HDR (mng_free_phyg)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_PHYG, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pHeader, sizeof (mng_phyg));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_PHYG, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-#ifdef MNG_INCLUDE_JNG
-FREE_CHUNK_HDR (mng_free_jhdr)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_JHDR, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pHeader, sizeof (mng_jhdr));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_JHDR, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_INCLUDE_JNG */
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-FREE_CHUNK_HDR (mng_free_jdaa)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_JDAA, MNG_LC_START);
-#endif
-
-  if (((mng_jdaap)pHeader)->iDatasize)
-    MNG_FREEX (pData, ((mng_jdaap)pHeader)->pData,
-                      ((mng_jdaap)pHeader)->iDatasize);
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  MNG_FREEX (pData, pHeader, sizeof (mng_jdaa));
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_JDAA, MNG_LC_END);
-#endif
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  return MNG_NOERROR;
-#else
-  return mng_free_general(pData, pHeader);
-#endif
-}
-#endif /* MNG_INCLUDE_JNG */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-FREE_CHUNK_HDR (mng_free_jdat)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_JDAT, MNG_LC_START);
-#endif
-
-  if (((mng_jdatp)pHeader)->iDatasize)
-    MNG_FREEX (pData, ((mng_jdatp)pHeader)->pData,
-                      ((mng_jdatp)pHeader)->iDatasize);
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  MNG_FREEX (pData, pHeader, sizeof (mng_jdat));
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_JDAT, MNG_LC_END);
-#endif
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  return MNG_NOERROR;
-#else
-  return mng_free_general(pData, pHeader);
-#endif
-}
-#endif /* MNG_INCLUDE_JNG */
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-#ifdef MNG_INCLUDE_JNG
-FREE_CHUNK_HDR (mng_free_jsep)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_JSEP, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pHeader, sizeof (mng_jsep));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_JSEP, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_INCLUDE_JNG */
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-#ifndef MNG_NO_DELTA_PNG
-FREE_CHUNK_HDR (mng_free_dhdr)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_DHDR, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pHeader, sizeof (mng_dhdr));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_DHDR, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-#ifndef MNG_NO_DELTA_PNG
-FREE_CHUNK_HDR (mng_free_prom)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_PROM, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pHeader, sizeof (mng_prom));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_PROM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-#ifndef MNG_NO_DELTA_PNG
-FREE_CHUNK_HDR (mng_free_ipng)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_IPNG, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pHeader, sizeof (mng_ipng));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_IPNG, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-#ifndef MNG_NO_DELTA_PNG
-FREE_CHUNK_HDR (mng_free_pplt)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_PPLT, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pHeader, sizeof (mng_pplt));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_PPLT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-#ifndef MNG_NO_DELTA_PNG
-#ifdef MNG_INCLUDE_JNG
-FREE_CHUNK_HDR (mng_free_ijng)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_IJNG, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pHeader, sizeof (mng_ijng));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_IJNG, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-FREE_CHUNK_HDR (mng_free_drop)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_DROP, MNG_LC_START);
-#endif
-
-  if (((mng_dropp)pHeader)->iCount)
-    MNG_FREEX (pData, ((mng_dropp)pHeader)->pChunknames,
-                      ((mng_dropp)pHeader)->iCount * sizeof (mng_chunkid) );
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  MNG_FREEX (pData, pHeader, sizeof (mng_drop));
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_DROP, MNG_LC_END);
-#endif
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  return MNG_NOERROR;
-#else
-  return mng_free_general(pData, pHeader);
-#endif
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_SKIPCHUNK_DBYK
-FREE_CHUNK_HDR (mng_free_dbyk)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_DBYK, MNG_LC_START);
-#endif
-
-  if (((mng_dbykp)pHeader)->iKeywordssize)
-    MNG_FREEX (pData, ((mng_dbykp)pHeader)->zKeywords,
-                      ((mng_dbykp)pHeader)->iKeywordssize);
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  MNG_FREEX (pData, pHeader, sizeof (mng_dbyk));
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_DBYK, MNG_LC_END);
-#endif
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  return MNG_NOERROR;
-#else
-  return mng_free_general(pData, pHeader);
-#endif
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_SKIPCHUNK_ORDR
-FREE_CHUNK_HDR (mng_free_ordr)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ORDR, MNG_LC_START);
-#endif
-
-  if (((mng_ordrp)pHeader)->iCount)
-    MNG_FREEX (pData, ((mng_ordrp)pHeader)->pEntries,
-                      ((mng_ordrp)pHeader)->iCount * sizeof (mng_ordr_entry) );
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  MNG_FREEX (pData, pHeader, sizeof (mng_ordr));
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ORDR, MNG_LC_END);
-#endif
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  return MNG_NOERROR;
-#else
-  return mng_free_general(pData, pHeader);
-#endif
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-#ifndef MNG_SKIPCHUNK_MAGN
-FREE_CHUNK_HDR (mng_free_magn)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_MAGN, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pHeader, sizeof (mng_magn));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_MAGN, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_evNT
-FREE_CHUNK_HDR (mng_free_evnt)
-{
-  mng_evnt_entryp pEntry = ((mng_evntp)pHeader)->pEntries;
-  mng_uint32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_EVNT, MNG_LC_START);
-#endif
-
-  for (iX = 0; iX < ((mng_evntp)pHeader)->iCount; iX++)
-  {
-    if (pEntry->iSegmentnamesize)
-      MNG_FREEX (pData, pEntry->zSegmentname, pEntry->iSegmentnamesize+1);
-
-    pEntry++;
-  }
-
-  if (((mng_evntp)pHeader)->iCount)
-    MNG_FREEX (pData, ((mng_evntp)pHeader)->pEntries,
-                      ((mng_evntp)pHeader)->iCount * sizeof (mng_evnt_entry) );
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  MNG_FREEX (pData, pHeader, sizeof (mng_evnt));
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_EVNT, MNG_LC_END);
-#endif
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  return MNG_NOERROR;
-#else
-  return mng_free_general(pData, pHeader);
-#endif
-}
-#endif
-
-/* ************************************************************************** */
-
-FREE_CHUNK_HDR (mng_free_unknown)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_UNKNOWN, MNG_LC_START);
-#endif
-
-  if (((mng_unknown_chunkp)pHeader)->iDatasize)
-    MNG_FREEX (pData, ((mng_unknown_chunkp)pHeader)->pData,
-                      ((mng_unknown_chunkp)pHeader)->iDatasize);
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  MNG_FREEX (pData, pHeader, sizeof (mng_unknown_chunk));
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_UNKNOWN, MNG_LC_END);
-#endif
-
-#ifndef MNG_OPTIMIZE_CHUNKINITFREE
-  return MNG_NOERROR;
-#else
-  return mng_free_general(pData, pHeader);
-#endif
-}
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Chunk specific copy routines                                           * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_WRITE_PROCS
-
-/* ************************************************************************** */
-
-#ifdef MNG_OPTIMIZE_CHUNKASSIGN
-ASSIGN_CHUNK_HDR (mng_assign_general)
-{
-  mng_ptr    pSrc = (mng_uint8p)pChunkfrom + sizeof (mng_chunk_header);
-  mng_ptr    pDst = (mng_uint8p)pChunkto   + sizeof (mng_chunk_header);
-  mng_size_t iLen = ((mng_chunk_headerp)pChunkfrom)->iChunksize - sizeof (mng_chunk_header);
-
-  MNG_COPY (pDst, pSrc, iLen);
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKASSIGN
-ASSIGN_CHUNK_HDR (mng_assign_ihdr)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_IHDR, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_IHDR)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_ihdrp)pChunkto)->iWidth       = ((mng_ihdrp)pChunkfrom)->iWidth;
-  ((mng_ihdrp)pChunkto)->iHeight      = ((mng_ihdrp)pChunkfrom)->iHeight;
-  ((mng_ihdrp)pChunkto)->iBitdepth    = ((mng_ihdrp)pChunkfrom)->iBitdepth;
-  ((mng_ihdrp)pChunkto)->iColortype   = ((mng_ihdrp)pChunkfrom)->iColortype;
-  ((mng_ihdrp)pChunkto)->iCompression = ((mng_ihdrp)pChunkfrom)->iCompression;
-  ((mng_ihdrp)pChunkto)->iFilter      = ((mng_ihdrp)pChunkfrom)->iFilter;
-  ((mng_ihdrp)pChunkto)->iInterlace   = ((mng_ihdrp)pChunkfrom)->iInterlace;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_IHDR, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKASSIGN
-ASSIGN_CHUNK_HDR (mng_assign_plte)
-{
-  mng_uint32 iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_PLTE, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_PLTE)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_pltep)pChunkto)->bEmpty      = ((mng_pltep)pChunkfrom)->bEmpty;
-  ((mng_pltep)pChunkto)->iEntrycount = ((mng_pltep)pChunkfrom)->iEntrycount;
-
-  for (iX = 0; iX < ((mng_pltep)pChunkto)->iEntrycount; iX++)
-    ((mng_pltep)pChunkto)->aEntries [iX] = ((mng_pltep)pChunkfrom)->aEntries [iX];
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_PLTE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-ASSIGN_CHUNK_HDR (mng_assign_idat)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_IDAT, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_IDAT)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_idatp)pChunkto)->bEmpty    = ((mng_idatp)pChunkfrom)->bEmpty;
-  ((mng_idatp)pChunkto)->iDatasize = ((mng_idatp)pChunkfrom)->iDatasize;
-
-  if (((mng_idatp)pChunkto)->iDatasize)
-  {
-    MNG_ALLOC (pData, ((mng_idatp)pChunkto)->pData, ((mng_idatp)pChunkto)->iDatasize);
-    MNG_COPY  (((mng_idatp)pChunkto)->pData, ((mng_idatp)pChunkfrom)->pData,
-               ((mng_idatp)pChunkto)->iDatasize);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_IDAT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKASSIGN
-ASSIGN_CHUNK_HDR (mng_assign_iend)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_IEND, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_IEND)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_IEND, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKASSIGN
-ASSIGN_CHUNK_HDR (mng_assign_trns)
-{
-  mng_uint32 iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_TRNS, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_tRNS)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_trnsp)pChunkto)->bEmpty  = ((mng_trnsp)pChunkfrom)->bEmpty;
-  ((mng_trnsp)pChunkto)->bGlobal = ((mng_trnsp)pChunkfrom)->bGlobal;
-  ((mng_trnsp)pChunkto)->iType   = ((mng_trnsp)pChunkfrom)->iType;
-  ((mng_trnsp)pChunkto)->iCount  = ((mng_trnsp)pChunkfrom)->iCount;
-  ((mng_trnsp)pChunkto)->iGray   = ((mng_trnsp)pChunkfrom)->iGray;
-  ((mng_trnsp)pChunkto)->iRed    = ((mng_trnsp)pChunkfrom)->iRed;
-  ((mng_trnsp)pChunkto)->iGreen  = ((mng_trnsp)pChunkfrom)->iGreen;
-  ((mng_trnsp)pChunkto)->iBlue   = ((mng_trnsp)pChunkfrom)->iBlue;
-  ((mng_trnsp)pChunkto)->iRawlen = ((mng_trnsp)pChunkfrom)->iRawlen;
-
-  for (iX = 0; iX < ((mng_trnsp)pChunkto)->iCount; iX++)
-    ((mng_trnsp)pChunkto)->aEntries [iX] = ((mng_trnsp)pChunkfrom)->aEntries [iX];
-
-  for (iX = 0; iX < ((mng_trnsp)pChunkto)->iRawlen; iX++)
-    ((mng_trnsp)pChunkto)->aRawdata [iX] = ((mng_trnsp)pChunkfrom)->aRawdata [iX];
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_TRNS, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKASSIGN
-#ifndef MNG_SKIPCHUNK_gAMA
-ASSIGN_CHUNK_HDR (mng_assign_gama)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_GAMA, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_gAMA)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_gamap)pChunkto)->bEmpty = ((mng_gamap)pChunkfrom)->bEmpty;
-  ((mng_gamap)pChunkto)->iGamma = ((mng_gamap)pChunkfrom)->iGamma;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_GAMA, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKASSIGN
-#ifndef MNG_SKIPCHUNK_cHRM
-ASSIGN_CHUNK_HDR (mng_assign_chrm)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_CHRM, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_cHRM)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_chrmp)pChunkto)->bEmpty       = ((mng_chrmp)pChunkfrom)->bEmpty;
-  ((mng_chrmp)pChunkto)->iWhitepointx = ((mng_chrmp)pChunkfrom)->iWhitepointx;
-  ((mng_chrmp)pChunkto)->iWhitepointy = ((mng_chrmp)pChunkfrom)->iWhitepointy;
-  ((mng_chrmp)pChunkto)->iRedx        = ((mng_chrmp)pChunkfrom)->iRedx;
-  ((mng_chrmp)pChunkto)->iRedy        = ((mng_chrmp)pChunkfrom)->iRedy;
-  ((mng_chrmp)pChunkto)->iGreenx      = ((mng_chrmp)pChunkfrom)->iGreenx;
-  ((mng_chrmp)pChunkto)->iGreeny      = ((mng_chrmp)pChunkfrom)->iGreeny;
-  ((mng_chrmp)pChunkto)->iBluex       = ((mng_chrmp)pChunkfrom)->iBluex;
-  ((mng_chrmp)pChunkto)->iBluey       = ((mng_chrmp)pChunkfrom)->iBluey;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_CHRM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKASSIGN
-#ifndef MNG_SKIPCHUNK_sRGB
-ASSIGN_CHUNK_HDR (mng_assign_srgb)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_SRGB, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_sRGB)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_srgbp)pChunkto)->iRenderingintent = ((mng_srgbp)pChunkfrom)->iRenderingintent;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_SRGB, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_iCCP
-ASSIGN_CHUNK_HDR (mng_assign_iccp)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_ICCP, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_iCCP)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_iccpp)pChunkto)->bEmpty       = ((mng_iccpp)pChunkfrom)->bEmpty;
-  ((mng_iccpp)pChunkto)->iNamesize    = ((mng_iccpp)pChunkfrom)->iNamesize;
-  ((mng_iccpp)pChunkto)->iCompression = ((mng_iccpp)pChunkfrom)->iCompression;
-  ((mng_iccpp)pChunkto)->iProfilesize = ((mng_iccpp)pChunkfrom)->iProfilesize;
-
-  if (((mng_iccpp)pChunkto)->iNamesize)
-  {
-    MNG_ALLOC (pData, ((mng_iccpp)pChunkto)->zName, ((mng_iccpp)pChunkto)->iNamesize);
-    MNG_COPY  (((mng_iccpp)pChunkto)->zName, ((mng_iccpp)pChunkfrom)->zName,
-               ((mng_iccpp)pChunkto)->iNamesize);
-  }
-
-  if (((mng_iccpp)pChunkto)->iProfilesize)
-  {
-    MNG_ALLOC (pData, ((mng_iccpp)pChunkto)->pProfile, ((mng_iccpp)pChunkto)->iProfilesize);
-    MNG_COPY  (((mng_iccpp)pChunkto)->pProfile, ((mng_iccpp)pChunkfrom)->pProfile,
-               ((mng_iccpp)pChunkto)->iProfilesize);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_ICCP, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_tEXt
-ASSIGN_CHUNK_HDR (mng_assign_text)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_TEXT, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_tEXt)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_textp)pChunkto)->iKeywordsize = ((mng_textp)pChunkfrom)->iKeywordsize;
-  ((mng_textp)pChunkto)->iTextsize    = ((mng_textp)pChunkfrom)->iTextsize;
-
-  if (((mng_textp)pChunkto)->iKeywordsize)
-  {
-    MNG_ALLOC (pData, ((mng_itxtp)pChunkto)->zKeyword, ((mng_textp)pChunkto)->iKeywordsize);
-    MNG_COPY  (((mng_itxtp)pChunkto)->zKeyword, ((mng_textp)pChunkfrom)->zKeyword,
-               ((mng_itxtp)pChunkto)->iKeywordsize);
-  }
-
-  if (((mng_textp)pChunkto)->iTextsize)
-  {
-    MNG_ALLOC (pData, ((mng_textp)pChunkto)->zText, ((mng_textp)pChunkto)->iTextsize);
-    MNG_COPY  (((mng_textp)pChunkto)->zText, ((mng_textp)pChunkfrom)->zText,
-               ((mng_textp)pChunkto)->iTextsize);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_TEXT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_zTXt
-ASSIGN_CHUNK_HDR (mng_assign_ztxt)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_ZTXT, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_zTXt)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_ztxtp)pChunkto)->iKeywordsize = ((mng_ztxtp)pChunkfrom)->iKeywordsize;
-  ((mng_ztxtp)pChunkto)->iCompression = ((mng_ztxtp)pChunkfrom)->iCompression;
-  ((mng_ztxtp)pChunkto)->iTextsize    = ((mng_ztxtp)pChunkfrom)->iTextsize;
-
-  if (((mng_ztxtp)pChunkto)->iKeywordsize)
-  {
-    MNG_ALLOC (pData, ((mng_ztxtp)pChunkto)->zKeyword, ((mng_ztxtp)pChunkto)->iKeywordsize);
-    MNG_COPY  (((mng_ztxtp)pChunkto)->zKeyword, ((mng_ztxtp)pChunkfrom)->zKeyword,
-               ((mng_ztxtp)pChunkto)->iKeywordsize);
-  }
-
-  if (((mng_ztxtp)pChunkto)->iTextsize)
-  {
-    MNG_ALLOC (pData, ((mng_ztxtp)pChunkto)->zText, ((mng_ztxtp)pChunkto)->iTextsize);
-    MNG_COPY  (((mng_ztxtp)pChunkto)->zText, ((mng_ztxtp)pChunkfrom)->zText,
-               ((mng_ztxtp)pChunkto)->iTextsize);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_ZTXT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_iTXt
-ASSIGN_CHUNK_HDR (mng_assign_itxt)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_ITXT, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_iTXt)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_itxtp)pChunkto)->iKeywordsize       = ((mng_itxtp)pChunkfrom)->iKeywordsize;
-  ((mng_itxtp)pChunkto)->iCompressionflag   = ((mng_itxtp)pChunkfrom)->iCompressionflag;
-  ((mng_itxtp)pChunkto)->iCompressionmethod = ((mng_itxtp)pChunkfrom)->iCompressionmethod;
-  ((mng_itxtp)pChunkto)->iLanguagesize      = ((mng_itxtp)pChunkfrom)->iLanguagesize;
-  ((mng_itxtp)pChunkto)->iTranslationsize   = ((mng_itxtp)pChunkfrom)->iTranslationsize;
-  ((mng_itxtp)pChunkto)->iTextsize          = ((mng_itxtp)pChunkfrom)->iTextsize;
-
-  if (((mng_itxtp)pChunkto)->iKeywordsize)
-  {
-    MNG_ALLOC (pData, ((mng_itxtp)pChunkto)->zKeyword, ((mng_itxtp)pChunkto)->iKeywordsize);
-    MNG_COPY  (((mng_itxtp)pChunkto)->zKeyword, ((mng_itxtp)pChunkfrom)->zKeyword,
-               ((mng_itxtp)pChunkto)->iKeywordsize);
-  }
-
-  if (((mng_itxtp)pChunkto)->iTextsize)
-  {
-    MNG_ALLOC (pData, ((mng_itxtp)pChunkto)->zLanguage, ((mng_itxtp)pChunkto)->iLanguagesize);
-    MNG_COPY  (((mng_itxtp)pChunkto)->zLanguage, ((mng_itxtp)pChunkfrom)->zLanguage,
-               ((mng_itxtp)pChunkto)->iLanguagesize);
-  }
-
-  if (((mng_itxtp)pChunkto)->iTextsize)
-  {
-    MNG_ALLOC (pData, ((mng_itxtp)pChunkto)->zTranslation, ((mng_itxtp)pChunkto)->iTranslationsize);
-    MNG_COPY  (((mng_itxtp)pChunkto)->zTranslation, ((mng_itxtp)pChunkfrom)->zTranslation,
-               ((mng_itxtp)pChunkto)->iTranslationsize);
-  }
-
-  if (((mng_itxtp)pChunkto)->iTextsize)
-  {
-    MNG_ALLOC (pData, ((mng_itxtp)pChunkto)->zText, ((mng_itxtp)pChunkto)->iTextsize);
-    MNG_COPY  (((mng_itxtp)pChunkto)->zText, ((mng_itxtp)pChunkfrom)->zText,
-               ((mng_itxtp)pChunkto)->iTextsize);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_ITXT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKASSIGN
-#ifndef MNG_SKIPCHUNK_bKGD
-ASSIGN_CHUNK_HDR (mng_assign_bkgd)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_BKGD, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_bKGD)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_bkgdp)pChunkto)->bEmpty = ((mng_bkgdp)pChunkfrom)->bEmpty;
-  ((mng_bkgdp)pChunkto)->iType  = ((mng_bkgdp)pChunkfrom)->iType;
-  ((mng_bkgdp)pChunkto)->iIndex = ((mng_bkgdp)pChunkfrom)->iIndex;
-  ((mng_bkgdp)pChunkto)->iGray  = ((mng_bkgdp)pChunkfrom)->iGray;
-  ((mng_bkgdp)pChunkto)->iRed   = ((mng_bkgdp)pChunkfrom)->iRed;
-  ((mng_bkgdp)pChunkto)->iGreen = ((mng_bkgdp)pChunkfrom)->iGreen;
-  ((mng_bkgdp)pChunkto)->iBlue  = ((mng_bkgdp)pChunkfrom)->iBlue;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_BKGD, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKASSIGN
-#ifndef MNG_SKIPCHUNK_pHYs
-ASSIGN_CHUNK_HDR (mng_assign_phys)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_PHYS, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_pHYs)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_physp)pChunkto)->bEmpty = ((mng_physp)pChunkfrom)->bEmpty;
-  ((mng_physp)pChunkto)->iSizex = ((mng_physp)pChunkfrom)->iSizex;
-  ((mng_physp)pChunkto)->iSizey = ((mng_physp)pChunkfrom)->iSizey;
-  ((mng_physp)pChunkto)->iUnit  = ((mng_physp)pChunkfrom)->iUnit;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_PHYS, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKASSIGN
-#ifndef MNG_SKIPCHUNK_sBIT
-ASSIGN_CHUNK_HDR (mng_assign_sbit)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_SBIT, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_sBIT)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_sbitp)pChunkto)->bEmpty    = ((mng_sbitp)pChunkfrom)->bEmpty;
-  ((mng_sbitp)pChunkto)->iType     = ((mng_sbitp)pChunkfrom)->iType;
-  ((mng_sbitp)pChunkto)->aBits [0] = ((mng_sbitp)pChunkfrom)->aBits [0];
-  ((mng_sbitp)pChunkto)->aBits [1] = ((mng_sbitp)pChunkfrom)->aBits [1];
-  ((mng_sbitp)pChunkto)->aBits [2] = ((mng_sbitp)pChunkfrom)->aBits [2];
-  ((mng_sbitp)pChunkto)->aBits [3] = ((mng_sbitp)pChunkfrom)->aBits [3];
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_SBIT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_sPLT
-ASSIGN_CHUNK_HDR (mng_assign_splt)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_SPLT, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_sPLT)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_spltp)pChunkto)->bEmpty       = ((mng_spltp)pChunkfrom)->bEmpty;
-  ((mng_spltp)pChunkto)->iNamesize    = ((mng_spltp)pChunkfrom)->iNamesize;
-  ((mng_spltp)pChunkto)->iSampledepth = ((mng_spltp)pChunkfrom)->iSampledepth;
-  ((mng_spltp)pChunkto)->iEntrycount  = ((mng_spltp)pChunkfrom)->iEntrycount;
-  ((mng_spltp)pChunkto)->pEntries     = ((mng_spltp)pChunkfrom)->pEntries;
-
-  if (((mng_spltp)pChunkto)->iNamesize)
-  {
-    MNG_ALLOC (pData, ((mng_spltp)pChunkto)->zName, ((mng_spltp)pChunkto)->iNamesize);
-    MNG_COPY  (((mng_spltp)pChunkto)->zName, ((mng_spltp)pChunkfrom)->zName,
-               ((mng_spltp)pChunkto)->iNamesize);
-  }
-
-  if (((mng_spltp)pChunkto)->iEntrycount)
-  {
-    mng_uint32 iLen = ((mng_spltp)pChunkto)->iEntrycount *
-                      (((mng_spltp)pChunkto)->iSampledepth * 3 + sizeof (mng_uint16));
-
-    MNG_ALLOC (pData, ((mng_spltp)pChunkto)->pEntries, iLen);
-    MNG_COPY  (((mng_spltp)pChunkto)->pEntries, ((mng_spltp)pChunkfrom)->pEntries, iLen);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_SPLT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKASSIGN
-#ifndef MNG_SKIPCHUNK_hIST
-ASSIGN_CHUNK_HDR (mng_assign_hist)
-{
-  mng_uint32 iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_HIST, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_hIST)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_histp)pChunkto)->iEntrycount = ((mng_histp)pChunkfrom)->iEntrycount;
-
-  for (iX = 0; iX < ((mng_histp)pChunkto)->iEntrycount; iX++)
-    ((mng_histp)pChunkto)->aEntries [iX] = ((mng_histp)pChunkfrom)->aEntries [iX];
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_HIST, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKASSIGN
-#ifndef MNG_SKIPCHUNK_tIME
-ASSIGN_CHUNK_HDR (mng_assign_time)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_TIME, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_tIME)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_timep)pChunkto)->iYear   = ((mng_timep)pChunkfrom)->iYear;
-  ((mng_timep)pChunkto)->iMonth  = ((mng_timep)pChunkfrom)->iMonth;
-  ((mng_timep)pChunkto)->iDay    = ((mng_timep)pChunkfrom)->iDay;
-  ((mng_timep)pChunkto)->iHour   = ((mng_timep)pChunkfrom)->iHour;
-  ((mng_timep)pChunkto)->iMinute = ((mng_timep)pChunkfrom)->iMinute;
-  ((mng_timep)pChunkto)->iSecond = ((mng_timep)pChunkfrom)->iSecond;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_TIME, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKASSIGN
-ASSIGN_CHUNK_HDR (mng_assign_mhdr)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_MHDR, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_MHDR)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_mhdrp)pChunkto)->iWidth      = ((mng_mhdrp)pChunkfrom)->iWidth;
-  ((mng_mhdrp)pChunkto)->iHeight     = ((mng_mhdrp)pChunkfrom)->iHeight;
-  ((mng_mhdrp)pChunkto)->iTicks      = ((mng_mhdrp)pChunkfrom)->iTicks;
-  ((mng_mhdrp)pChunkto)->iLayercount = ((mng_mhdrp)pChunkfrom)->iLayercount;
-  ((mng_mhdrp)pChunkto)->iFramecount = ((mng_mhdrp)pChunkfrom)->iFramecount;
-  ((mng_mhdrp)pChunkto)->iPlaytime   = ((mng_mhdrp)pChunkfrom)->iPlaytime;
-  ((mng_mhdrp)pChunkto)->iSimplicity = ((mng_mhdrp)pChunkfrom)->iSimplicity;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_MHDR, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKASSIGN
-ASSIGN_CHUNK_HDR (mng_assign_mend)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_MEND, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_MEND)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_MEND, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_LOOP
-ASSIGN_CHUNK_HDR (mng_assign_loop)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_LOOP, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_LOOP)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_loopp)pChunkto)->iLevel       = ((mng_loopp)pChunkfrom)->iLevel;
-  ((mng_loopp)pChunkto)->iRepeat      = ((mng_loopp)pChunkfrom)->iRepeat;
-  ((mng_loopp)pChunkto)->iTermination = ((mng_loopp)pChunkfrom)->iTermination;
-  ((mng_loopp)pChunkto)->iItermin     = ((mng_loopp)pChunkfrom)->iItermin;
-  ((mng_loopp)pChunkto)->iItermax     = ((mng_loopp)pChunkfrom)->iItermax;
-  ((mng_loopp)pChunkto)->iCount       = ((mng_loopp)pChunkfrom)->iCount;
-
-#ifndef MNG_NO_LOOP_SIGNALS_SUPPORTED
-  if (((mng_loopp)pChunkto)->iCount)
-  {
-    mng_uint32 iLen = ((mng_loopp)pChunkto)->iCount * sizeof (mng_uint32);
-    MNG_ALLOC (pData, ((mng_loopp)pChunkto)->pSignals, iLen);
-    MNG_COPY  (((mng_loopp)pChunkto)->pSignals, ((mng_loopp)pChunkfrom)->pSignals, iLen);
-  }
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_LOOP, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKASSIGN
-ASSIGN_CHUNK_HDR (mng_assign_endl)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_ENDL, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_ENDL)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_endlp)pChunkto)->iLevel = ((mng_endlp)pChunkfrom)->iLevel;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_ENDL, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKASSIGN
-#ifndef MNG_SKIPCHUNK_DEFI
-ASSIGN_CHUNK_HDR (mng_assign_defi)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_DEFI, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_DEFI)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_defip)pChunkto)->iObjectid     = ((mng_defip)pChunkfrom)->iObjectid;
-  ((mng_defip)pChunkto)->bHasdonotshow = ((mng_defip)pChunkfrom)->bHasdonotshow;
-  ((mng_defip)pChunkto)->iDonotshow    = ((mng_defip)pChunkfrom)->iDonotshow;
-  ((mng_defip)pChunkto)->bHasconcrete  = ((mng_defip)pChunkfrom)->bHasconcrete;
-  ((mng_defip)pChunkto)->iConcrete     = ((mng_defip)pChunkfrom)->iConcrete;
-  ((mng_defip)pChunkto)->bHasloca      = ((mng_defip)pChunkfrom)->bHasloca;
-  ((mng_defip)pChunkto)->iXlocation    = ((mng_defip)pChunkfrom)->iXlocation;
-  ((mng_defip)pChunkto)->iYlocation    = ((mng_defip)pChunkfrom)->iYlocation;
-  ((mng_defip)pChunkto)->bHasclip      = ((mng_defip)pChunkfrom)->bHasclip;
-  ((mng_defip)pChunkto)->iLeftcb       = ((mng_defip)pChunkfrom)->iLeftcb;
-  ((mng_defip)pChunkto)->iRightcb      = ((mng_defip)pChunkfrom)->iRightcb;
-  ((mng_defip)pChunkto)->iTopcb        = ((mng_defip)pChunkfrom)->iTopcb;
-  ((mng_defip)pChunkto)->iBottomcb     = ((mng_defip)pChunkfrom)->iBottomcb;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_DEFI, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKASSIGN
-#ifndef MNG_SKIPCHUNK_BASI
-ASSIGN_CHUNK_HDR (mng_assign_basi)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_BASI, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_BASI)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_basip)pChunkto)->iWidth       = ((mng_basip)pChunkfrom)->iWidth;
-  ((mng_basip)pChunkto)->iHeight      = ((mng_basip)pChunkfrom)->iHeight;
-  ((mng_basip)pChunkto)->iBitdepth    = ((mng_basip)pChunkfrom)->iBitdepth;
-  ((mng_basip)pChunkto)->iColortype   = ((mng_basip)pChunkfrom)->iColortype;
-  ((mng_basip)pChunkto)->iCompression = ((mng_basip)pChunkfrom)->iCompression;
-  ((mng_basip)pChunkto)->iFilter      = ((mng_basip)pChunkfrom)->iFilter;
-  ((mng_basip)pChunkto)->iInterlace   = ((mng_basip)pChunkfrom)->iInterlace;
-  ((mng_basip)pChunkto)->iRed         = ((mng_basip)pChunkfrom)->iRed;
-  ((mng_basip)pChunkto)->iGreen       = ((mng_basip)pChunkfrom)->iGreen;
-  ((mng_basip)pChunkto)->iBlue        = ((mng_basip)pChunkfrom)->iBlue;
-  ((mng_basip)pChunkto)->iAlpha       = ((mng_basip)pChunkfrom)->iAlpha;
-  ((mng_basip)pChunkto)->iViewable    = ((mng_basip)pChunkfrom)->iViewable;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_BASI, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKASSIGN
-#ifndef MNG_SKIPCHUNK_CLON
-ASSIGN_CHUNK_HDR (mng_assign_clon)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_CLON, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_CLON)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_clonp)pChunkto)->iSourceid     = ((mng_clonp)pChunkfrom)->iSourceid;
-  ((mng_clonp)pChunkto)->iCloneid      = ((mng_clonp)pChunkfrom)->iCloneid;
-  ((mng_clonp)pChunkto)->iClonetype    = ((mng_clonp)pChunkfrom)->iClonetype;
-#ifdef MNG_OPTIMIZE_CHUNKREADER
-  ((mng_clonp)pChunkto)->bHasdonotshow = ((mng_clonp)pChunkfrom)->bHasdonotshow;
-#endif
-  ((mng_clonp)pChunkto)->iDonotshow    = ((mng_clonp)pChunkfrom)->iDonotshow;
-  ((mng_clonp)pChunkto)->iConcrete     = ((mng_clonp)pChunkfrom)->iConcrete;
-  ((mng_clonp)pChunkto)->bHasloca      = ((mng_clonp)pChunkfrom)->bHasloca;
-  ((mng_clonp)pChunkto)->iLocationtype = ((mng_clonp)pChunkfrom)->iLocationtype;
-  ((mng_clonp)pChunkto)->iLocationx    = ((mng_clonp)pChunkfrom)->iLocationx;
-  ((mng_clonp)pChunkto)->iLocationy    = ((mng_clonp)pChunkfrom)->iLocationy;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_CLON, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_PAST
-ASSIGN_CHUNK_HDR (mng_assign_past)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_PAST, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_PAST)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_pastp)pChunkto)->iDestid     = ((mng_pastp)pChunkfrom)->iDestid;
-  ((mng_pastp)pChunkto)->iTargettype = ((mng_pastp)pChunkfrom)->iTargettype;
-  ((mng_pastp)pChunkto)->iTargetx    = ((mng_pastp)pChunkfrom)->iTargetx;
-  ((mng_pastp)pChunkto)->iTargety    = ((mng_pastp)pChunkfrom)->iTargety;
-  ((mng_pastp)pChunkto)->iCount      = ((mng_pastp)pChunkfrom)->iCount;
-
-  if (((mng_pastp)pChunkto)->iCount)
-  {
-    mng_uint32 iLen = ((mng_pastp)pChunkto)->iCount * sizeof (mng_past_source);
-
-    MNG_ALLOC (pData, ((mng_pastp)pChunkto)->pSources, iLen);
-    MNG_COPY  (((mng_pastp)pChunkto)->pSources, ((mng_pastp)pChunkfrom)->pSources, iLen);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_PAST, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_DISC
-ASSIGN_CHUNK_HDR (mng_assign_disc)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_DISC, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_DISC)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_discp)pChunkto)->iCount = ((mng_discp)pChunkfrom)->iCount;
-
-  if (((mng_discp)pChunkto)->iCount)
-  {
-    mng_uint32 iLen = ((mng_discp)pChunkto)->iCount * sizeof (mng_uint16);
-
-    MNG_ALLOC (pData, ((mng_discp)pChunkto)->pObjectids, iLen);
-    MNG_COPY  (((mng_discp)pChunkto)->pObjectids, ((mng_discp)pChunkfrom)->pObjectids, iLen);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_DISC, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKASSIGN
-#ifndef MNG_SKIPCHUNK_BACK
-ASSIGN_CHUNK_HDR (mng_assign_back)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_BACK, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_BACK)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_backp)pChunkto)->iRed       = ((mng_backp)pChunkfrom)->iRed;
-  ((mng_backp)pChunkto)->iGreen     = ((mng_backp)pChunkfrom)->iGreen;
-  ((mng_backp)pChunkto)->iBlue      = ((mng_backp)pChunkfrom)->iBlue;
-  ((mng_backp)pChunkto)->iMandatory = ((mng_backp)pChunkfrom)->iMandatory;
-  ((mng_backp)pChunkto)->iImageid   = ((mng_backp)pChunkfrom)->iImageid;
-  ((mng_backp)pChunkto)->iTile      = ((mng_backp)pChunkfrom)->iTile;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_BACK, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_FRAM
-ASSIGN_CHUNK_HDR (mng_assign_fram)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_FRAM, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_FRAM)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_framp)pChunkto)->bEmpty          = ((mng_framp)pChunkfrom)->bEmpty;
-  ((mng_framp)pChunkto)->iMode           = ((mng_framp)pChunkfrom)->iMode;
-  ((mng_framp)pChunkto)->iNamesize       = ((mng_framp)pChunkfrom)->iNamesize;
-  ((mng_framp)pChunkto)->iChangedelay    = ((mng_framp)pChunkfrom)->iChangedelay;
-  ((mng_framp)pChunkto)->iChangetimeout  = ((mng_framp)pChunkfrom)->iChangetimeout;
-  ((mng_framp)pChunkto)->iChangeclipping = ((mng_framp)pChunkfrom)->iChangeclipping;
-  ((mng_framp)pChunkto)->iChangesyncid   = ((mng_framp)pChunkfrom)->iChangesyncid;
-  ((mng_framp)pChunkto)->iDelay          = ((mng_framp)pChunkfrom)->iDelay;
-  ((mng_framp)pChunkto)->iTimeout        = ((mng_framp)pChunkfrom)->iTimeout;
-  ((mng_framp)pChunkto)->iBoundarytype   = ((mng_framp)pChunkfrom)->iBoundarytype;
-  ((mng_framp)pChunkto)->iBoundaryl      = ((mng_framp)pChunkfrom)->iBoundaryl;
-  ((mng_framp)pChunkto)->iBoundaryr      = ((mng_framp)pChunkfrom)->iBoundaryr;
-  ((mng_framp)pChunkto)->iBoundaryt      = ((mng_framp)pChunkfrom)->iBoundaryt;
-  ((mng_framp)pChunkto)->iBoundaryb      = ((mng_framp)pChunkfrom)->iBoundaryb;
-  ((mng_framp)pChunkto)->iCount          = ((mng_framp)pChunkfrom)->iCount;
-
-  if (((mng_framp)pChunkto)->iNamesize)
-  {
-    MNG_ALLOC (pData, ((mng_framp)pChunkto)->zName, ((mng_framp)pChunkto)->iNamesize);
-    MNG_COPY  (((mng_framp)pChunkto)->zName, ((mng_framp)pChunkfrom)->zName,
-               ((mng_framp)pChunkto)->iNamesize);
-  }
-
-  if (((mng_framp)pChunkto)->iCount)
-  {
-    mng_uint32 iLen = ((mng_framp)pChunkto)->iCount * sizeof (mng_uint32);
-
-    MNG_ALLOC (pData, ((mng_framp)pChunkto)->pSyncids, iLen);
-    MNG_COPY  (((mng_framp)pChunkto)->pSyncids, ((mng_framp)pChunkfrom)->pSyncids, iLen);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_FRAM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKASSIGN
-#ifndef MNG_SKIPCHUNK_MOVE
-ASSIGN_CHUNK_HDR (mng_assign_move)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_MOVE, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_MOVE)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_movep)pChunkto)->iFirstid  = ((mng_movep)pChunkfrom)->iFirstid;
-  ((mng_movep)pChunkto)->iLastid   = ((mng_movep)pChunkfrom)->iLastid;
-  ((mng_movep)pChunkto)->iMovetype = ((mng_movep)pChunkfrom)->iMovetype;
-  ((mng_movep)pChunkto)->iMovex    = ((mng_movep)pChunkfrom)->iMovex;
-  ((mng_movep)pChunkto)->iMovey    = ((mng_movep)pChunkfrom)->iMovey;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_MOVE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKASSIGN
-#ifndef MNG_SKIPCHUNK_CLIP
-ASSIGN_CHUNK_HDR (mng_assign_clip)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_CLIP, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_CLIP)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_clipp)pChunkto)->iFirstid  = ((mng_clipp)pChunkfrom)->iFirstid;
-  ((mng_clipp)pChunkto)->iLastid   = ((mng_clipp)pChunkfrom)->iLastid;
-  ((mng_clipp)pChunkto)->iCliptype = ((mng_clipp)pChunkfrom)->iCliptype;
-  ((mng_clipp)pChunkto)->iClipl    = ((mng_clipp)pChunkfrom)->iClipl;
-  ((mng_clipp)pChunkto)->iClipr    = ((mng_clipp)pChunkfrom)->iClipr;
-  ((mng_clipp)pChunkto)->iClipt    = ((mng_clipp)pChunkfrom)->iClipt;
-  ((mng_clipp)pChunkto)->iClipb    = ((mng_clipp)pChunkfrom)->iClipb;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_CLIP, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKASSIGN
-#ifndef MNG_SKIPCHUNK_SHOW
-ASSIGN_CHUNK_HDR (mng_assign_show)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_SHOW, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_SHOW)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_showp)pChunkto)->bEmpty   = ((mng_showp)pChunkfrom)->bEmpty;
-  ((mng_showp)pChunkto)->iFirstid = ((mng_showp)pChunkfrom)->iFirstid;
-  ((mng_showp)pChunkto)->iLastid  = ((mng_showp)pChunkfrom)->iLastid;
-  ((mng_showp)pChunkto)->iMode    = ((mng_showp)pChunkfrom)->iMode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_SHOW, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKASSIGN
-#ifndef MNG_SKIPCHUNK_TERM
-ASSIGN_CHUNK_HDR (mng_assign_term)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_TERM, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_TERM)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_termp)pChunkto)->iTermaction = ((mng_termp)pChunkfrom)->iTermaction;
-  ((mng_termp)pChunkto)->iIteraction = ((mng_termp)pChunkfrom)->iIteraction;
-  ((mng_termp)pChunkto)->iDelay      = ((mng_termp)pChunkfrom)->iDelay;
-  ((mng_termp)pChunkto)->iItermax    = ((mng_termp)pChunkfrom)->iItermax;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_TERM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_SAVE
-ASSIGN_CHUNK_HDR (mng_assign_save)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_SAVE, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_SAVE)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_savep)pChunkto)->bEmpty      = ((mng_savep)pChunkfrom)->bEmpty;
-  ((mng_savep)pChunkto)->iOffsettype = ((mng_savep)pChunkfrom)->iOffsettype;
-  ((mng_savep)pChunkto)->iCount      = ((mng_savep)pChunkfrom)->iCount;
-
-  if (((mng_savep)pChunkto)->iCount)
-  {
-    mng_uint32      iX;
-    mng_save_entryp pEntry;
-    mng_uint32      iLen = ((mng_savep)pChunkto)->iCount * sizeof (mng_save_entry);
-
-    MNG_ALLOC (pData, ((mng_savep)pChunkto)->pEntries, iLen);
-    MNG_COPY  (((mng_savep)pChunkto)->pEntries, ((mng_savep)pChunkfrom)->pEntries, iLen);
-
-    pEntry = ((mng_savep)pChunkto)->pEntries;
-
-    for (iX = 0; iX < ((mng_savep)pChunkto)->iCount; iX++)
-    {
-      if (pEntry->iNamesize)
-      {
-        mng_pchar pTemp = pEntry->zName;
-
-        MNG_ALLOC (pData, pEntry->zName, pEntry->iNamesize);
-        MNG_COPY  (pEntry->zName, pTemp, pEntry->iNamesize);
-      }
-      else
-      {
-        pEntry->zName = MNG_NULL;
-      }
-
-      pEntry++;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_SAVE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_SEEK
-ASSIGN_CHUNK_HDR (mng_assign_seek)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_SEEK, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_SEEK)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_seekp)pChunkto)->iNamesize = ((mng_seekp)pChunkfrom)->iNamesize;
-
-  if (((mng_seekp)pChunkto)->iNamesize)
-  {
-    MNG_ALLOC (pData, ((mng_seekp)pChunkto)->zName, ((mng_seekp)pChunkto)->iNamesize);
-    MNG_COPY  (((mng_seekp)pChunkto)->zName, ((mng_seekp)pChunkfrom)->zName,
-               ((mng_seekp)pChunkto)->iNamesize);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_SEEK, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_eXPI
-ASSIGN_CHUNK_HDR (mng_assign_expi)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_EXPI, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_eXPI)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_expip)pChunkto)->iSnapshotid = ((mng_expip)pChunkfrom)->iSnapshotid;
-  ((mng_expip)pChunkto)->iNamesize   = ((mng_expip)pChunkfrom)->iNamesize;
-
-  if (((mng_expip)pChunkto)->iNamesize)
-  {
-    MNG_ALLOC (pData, ((mng_expip)pChunkto)->zName, ((mng_expip)pChunkto)->iNamesize);
-    MNG_COPY  (((mng_expip)pChunkto)->zName, ((mng_expip)pChunkfrom)->zName,
-               ((mng_expip)pChunkto)->iNamesize);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_EXPI, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKASSIGN
-#ifndef MNG_SKIPCHUNK_fPRI
-ASSIGN_CHUNK_HDR (mng_assign_fpri)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_FPRI, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_fPRI)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_fprip)pChunkto)->iDeltatype = ((mng_fprip)pChunkfrom)->iDeltatype;
-  ((mng_fprip)pChunkto)->iPriority  = ((mng_fprip)pChunkfrom)->iPriority;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_FPRI, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_nEED
-ASSIGN_CHUNK_HDR (mng_assign_need)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_NEED, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_nEED)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_needp)pChunkto)->iKeywordssize = ((mng_needp)pChunkfrom)->iKeywordssize;
-
-  if (((mng_needp)pChunkto)->iKeywordssize)
-  {
-    MNG_ALLOC (pData, ((mng_needp)pChunkto)->zKeywords, ((mng_needp)pChunkto)->iKeywordssize);
-    MNG_COPY  (((mng_needp)pChunkto)->zKeywords, ((mng_needp)pChunkfrom)->zKeywords,
-               ((mng_needp)pChunkto)->iKeywordssize);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_NEED, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKASSIGN
-#ifndef MNG_SKIPCHUNK_pHYg
-ASSIGN_CHUNK_HDR (mng_assign_phyg)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_PHYG, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_pHYg)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_phygp)pChunkto)->bEmpty = ((mng_phygp)pChunkfrom)->bEmpty;
-  ((mng_phygp)pChunkto)->iSizex = ((mng_phygp)pChunkfrom)->iSizex;
-  ((mng_phygp)pChunkto)->iSizey = ((mng_phygp)pChunkfrom)->iSizey;
-  ((mng_phygp)pChunkto)->iUnit  = ((mng_phygp)pChunkfrom)->iUnit;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_PHYG, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKASSIGN
-#ifdef MNG_INCLUDE_JNG
-ASSIGN_CHUNK_HDR (mng_assign_jhdr)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_JHDR, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_JHDR)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_jhdrp)pChunkto)->iWidth            = ((mng_jhdrp)pChunkfrom)->iWidth;
-  ((mng_jhdrp)pChunkto)->iHeight           = ((mng_jhdrp)pChunkfrom)->iHeight;
-  ((mng_jhdrp)pChunkto)->iColortype        = ((mng_jhdrp)pChunkfrom)->iColortype;
-  ((mng_jhdrp)pChunkto)->iImagesampledepth = ((mng_jhdrp)pChunkfrom)->iImagesampledepth;
-  ((mng_jhdrp)pChunkto)->iImagecompression = ((mng_jhdrp)pChunkfrom)->iImagecompression;
-  ((mng_jhdrp)pChunkto)->iImageinterlace   = ((mng_jhdrp)pChunkfrom)->iImageinterlace;
-  ((mng_jhdrp)pChunkto)->iAlphasampledepth = ((mng_jhdrp)pChunkfrom)->iAlphasampledepth;
-  ((mng_jhdrp)pChunkto)->iAlphacompression = ((mng_jhdrp)pChunkfrom)->iAlphacompression;
-  ((mng_jhdrp)pChunkto)->iAlphafilter      = ((mng_jhdrp)pChunkfrom)->iAlphafilter;
-  ((mng_jhdrp)pChunkto)->iAlphainterlace   = ((mng_jhdrp)pChunkfrom)->iAlphainterlace;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_JHDR, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_INCLUDE_JNG */
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-ASSIGN_CHUNK_HDR (mng_assign_jdaa)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_JDAA, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_JDAA)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_jdaap)pChunkto)->bEmpty    = ((mng_jdaap)pChunkfrom)->bEmpty;
-  ((mng_jdaap)pChunkto)->iDatasize = ((mng_jdaap)pChunkfrom)->iDatasize;
-
-  if (((mng_jdaap)pChunkto)->iDatasize)
-  {
-    MNG_ALLOC (pData, ((mng_jdaap)pChunkto)->pData, ((mng_jdaap)pChunkto)->iDatasize);
-    MNG_COPY  (((mng_jdaap)pChunkto)->pData, ((mng_jdaap)pChunkfrom)->pData,
-               ((mng_jdaap)pChunkto)->iDatasize);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_JDAA, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_INCLUDE_JNG */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-ASSIGN_CHUNK_HDR (mng_assign_jdat)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_JDAT, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_JDAT)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_jdatp)pChunkto)->bEmpty    = ((mng_jdatp)pChunkfrom)->bEmpty;
-  ((mng_jdatp)pChunkto)->iDatasize = ((mng_jdatp)pChunkfrom)->iDatasize;
-
-  if (((mng_jdatp)pChunkto)->iDatasize)
-  {
-    MNG_ALLOC (pData, ((mng_jdatp)pChunkto)->pData, ((mng_jdatp)pChunkto)->iDatasize);
-    MNG_COPY  (((mng_jdatp)pChunkto)->pData, ((mng_jdatp)pChunkfrom)->pData,
-               ((mng_jdatp)pChunkto)->iDatasize);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_JDAT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_INCLUDE_JNG */
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKASSIGN
-#ifdef MNG_INCLUDE_JNG
-ASSIGN_CHUNK_HDR (mng_assign_jsep)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_JSEP, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_JSEP)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_JSEP, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_INCLUDE_JNG */
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKASSIGN
-#ifndef MNG_NO_DELTA_PNG
-ASSIGN_CHUNK_HDR (mng_assign_dhdr)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_DHDR, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_DHDR)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_dhdrp)pChunkto)->iObjectid    = ((mng_dhdrp)pChunkfrom)->iObjectid;
-  ((mng_dhdrp)pChunkto)->iImagetype   = ((mng_dhdrp)pChunkfrom)->iImagetype;
-  ((mng_dhdrp)pChunkto)->iDeltatype   = ((mng_dhdrp)pChunkfrom)->iDeltatype;
-  ((mng_dhdrp)pChunkto)->iBlockwidth  = ((mng_dhdrp)pChunkfrom)->iBlockwidth;
-  ((mng_dhdrp)pChunkto)->iBlockheight = ((mng_dhdrp)pChunkfrom)->iBlockheight;
-  ((mng_dhdrp)pChunkto)->iBlockx      = ((mng_dhdrp)pChunkfrom)->iBlockx;
-  ((mng_dhdrp)pChunkto)->iBlocky      = ((mng_dhdrp)pChunkfrom)->iBlocky;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_DHDR, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKASSIGN
-#ifndef MNG_NO_DELTA_PNG
-ASSIGN_CHUNK_HDR (mng_assign_prom)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_PROM, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_PROM)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_promp)pChunkto)->iColortype   = ((mng_promp)pChunkfrom)->iColortype;
-  ((mng_promp)pChunkto)->iSampledepth = ((mng_promp)pChunkfrom)->iSampledepth;
-  ((mng_promp)pChunkto)->iFilltype    = ((mng_promp)pChunkfrom)->iFilltype;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_PROM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKASSIGN
-#ifndef MNG_NO_DELTA_PNG
-ASSIGN_CHUNK_HDR (mng_assign_ipng)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_IPNG, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_IPNG)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_IPNG, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKASSIGN
-#ifndef MNG_NO_DELTA_PNG
-ASSIGN_CHUNK_HDR (mng_assign_pplt)
-{
-  mng_uint32 iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_PPLT, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_PPLT)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_ppltp)pChunkto)->iDeltatype = ((mng_ppltp)pChunkfrom)->iDeltatype;
-  ((mng_ppltp)pChunkto)->iCount     = ((mng_ppltp)pChunkfrom)->iCount;
-
-  for (iX = 0; iX < ((mng_ppltp)pChunkto)->iCount; iX++)
-    ((mng_ppltp)pChunkto)->aEntries [iX] = ((mng_ppltp)pChunkfrom)->aEntries [iX];
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_PPLT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKASSIGN
-#ifndef MNG_NO_DELTA_PNG
-#ifdef MNG_INCLUDE_JNG
-ASSIGN_CHUNK_HDR (mng_assign_ijng)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_IJNG, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_IJNG)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_IJNG, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-ASSIGN_CHUNK_HDR (mng_assign_drop)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_DROP, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_DROP)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_dropp)pChunkto)->iCount = ((mng_dropp)pChunkfrom)->iCount;
-
-  if (((mng_dropp)pChunkto)->iCount)
-  {
-    mng_uint32 iLen = ((mng_dropp)pChunkto)->iCount * sizeof (mng_uint32);
-
-    MNG_ALLOC (pData, ((mng_dropp)pChunkto)->pChunknames, iLen);
-    MNG_COPY  (((mng_dropp)pChunkto)->pChunknames, ((mng_dropp)pChunkfrom)->pChunknames, iLen);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_DROP, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_SKIPCHUNK_DBYK
-ASSIGN_CHUNK_HDR (mng_assign_dbyk)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_DBYK, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_DBYK)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_dbykp)pChunkto)->iChunkname    = ((mng_dbykp)pChunkfrom)->iChunkname;
-  ((mng_dbykp)pChunkto)->iPolarity     = ((mng_dbykp)pChunkfrom)->iPolarity;
-  ((mng_dbykp)pChunkto)->iKeywordssize = ((mng_dbykp)pChunkfrom)->iKeywordssize;
-
-  if (((mng_dbykp)pChunkto)->iKeywordssize)
-  {
-    MNG_ALLOC (pData, ((mng_dbykp)pChunkto)->zKeywords, ((mng_dbykp)pChunkto)->iKeywordssize);
-    MNG_COPY  (((mng_dbykp)pChunkto)->zKeywords, ((mng_dbykp)pChunkfrom)->zKeywords,
-               ((mng_dbykp)pChunkto)->iKeywordssize);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_DBYK, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_SKIPCHUNK_ORDR
-ASSIGN_CHUNK_HDR (mng_assign_ordr)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_ORDR, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_ORDR)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_ordrp)pChunkto)->iCount = ((mng_ordrp)pChunkfrom)->iCount;
-
-  if (((mng_ordrp)pChunkto)->iCount)
-  {
-    mng_uint32 iLen = ((mng_ordrp)pChunkto)->iCount * sizeof (mng_ordr_entry);
-
-    MNG_ALLOC (pData, ((mng_ordrp)pChunkto)->pEntries, iLen);
-    MNG_COPY  (((mng_ordrp)pChunkto)->pEntries, ((mng_ordrp)pChunkfrom)->pEntries, iLen);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_ORDR, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKASSIGN
-#ifndef MNG_SKIPCHUNK_MAGN
-ASSIGN_CHUNK_HDR (mng_assign_magn)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_MAGN, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_MAGN)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_magnp)pChunkto)->iFirstid = ((mng_magnp)pChunkfrom)->iFirstid;
-  ((mng_magnp)pChunkto)->iLastid  = ((mng_magnp)pChunkfrom)->iLastid;
-  ((mng_magnp)pChunkto)->iMethodX = ((mng_magnp)pChunkfrom)->iMethodX;
-  ((mng_magnp)pChunkto)->iMX      = ((mng_magnp)pChunkfrom)->iMX;
-  ((mng_magnp)pChunkto)->iMY      = ((mng_magnp)pChunkfrom)->iMY;
-  ((mng_magnp)pChunkto)->iML      = ((mng_magnp)pChunkfrom)->iML;
-  ((mng_magnp)pChunkto)->iMR      = ((mng_magnp)pChunkfrom)->iMR;
-  ((mng_magnp)pChunkto)->iMT      = ((mng_magnp)pChunkfrom)->iMT;
-  ((mng_magnp)pChunkto)->iMB      = ((mng_magnp)pChunkfrom)->iMB;
-  ((mng_magnp)pChunkto)->iMethodY = ((mng_magnp)pChunkfrom)->iMethodY;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_MAGN, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-ASSIGN_CHUNK_HDR (mng_assign_mpng)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_MPNG, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_mpNG)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_mpngp)pChunkto)->iFramewidth        = ((mng_mpngp)pChunkfrom)->iFramewidth;
-  ((mng_mpngp)pChunkto)->iFrameheight       = ((mng_mpngp)pChunkfrom)->iFrameheight;
-  ((mng_mpngp)pChunkto)->iNumplays          = ((mng_mpngp)pChunkfrom)->iNumplays;
-  ((mng_mpngp)pChunkto)->iTickspersec       = ((mng_mpngp)pChunkfrom)->iTickspersec;
-  ((mng_mpngp)pChunkto)->iCompressionmethod = ((mng_mpngp)pChunkfrom)->iCompressionmethod;
-  ((mng_mpngp)pChunkto)->iFramessize        = ((mng_mpngp)pChunkfrom)->iFramessize;
-
-  if (((mng_mpngp)pChunkto)->iFramessize)
-  {
-    MNG_ALLOC (pData, ((mng_mpngp)pChunkto)->pFrames, ((mng_mpngp)pChunkto)->iFramessize);
-    MNG_COPY  (((mng_mpngp)pChunkto)->pFrames, ((mng_mpngp)pChunkfrom)->pFrames,
-               ((mng_mpngp)pChunkto)->iFramessize);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_MPNG, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_ANG_PROPOSAL
-ASSIGN_CHUNK_HDR (mng_assign_ahdr)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_AHDR, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_ahDR)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_ahdrp)pChunkto)->iNumframes   = ((mng_ahdrp)pChunkfrom)->iNumframes;
-  ((mng_ahdrp)pChunkto)->iTickspersec = ((mng_ahdrp)pChunkfrom)->iTickspersec;
-  ((mng_ahdrp)pChunkto)->iNumplays    = ((mng_ahdrp)pChunkfrom)->iNumplays;
-  ((mng_ahdrp)pChunkto)->iTilewidth   = ((mng_ahdrp)pChunkfrom)->iTilewidth;
-  ((mng_ahdrp)pChunkto)->iTileheight  = ((mng_ahdrp)pChunkfrom)->iTileheight;
-  ((mng_ahdrp)pChunkto)->iInterlace   = ((mng_ahdrp)pChunkfrom)->iInterlace;
-  ((mng_ahdrp)pChunkto)->iStillused   = ((mng_ahdrp)pChunkfrom)->iStillused;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_AHDR, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_ANG_PROPOSAL
-ASSIGN_CHUNK_HDR (mng_assign_adat)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_ADAT, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_adAT)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_adatp)pChunkto)->iTilessize = ((mng_adatp)pChunkfrom)->iTilessize;
-
-  if (((mng_adatp)pChunkto)->iTilessize)
-  {
-    MNG_ALLOC (pData, ((mng_adatp)pChunkto)->pTiles, ((mng_adatp)pChunkto)->iTilessize);
-    MNG_COPY  (((mng_adatp)pChunkto)->pTiles, ((mng_adatp)pChunkfrom)->pTiles,
-               ((mng_adatp)pChunkto)->iTilessize);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_ADAT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_evNT
-ASSIGN_CHUNK_HDR (mng_assign_evnt)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_EVNT, MNG_LC_START);
-#endif
-
-  if (((mng_chunk_headerp)pChunkfrom)->iChunkname != MNG_UINT_evNT)
-    MNG_ERROR (pData, MNG_WRONGCHUNK); /* ouch */
-
-  ((mng_evntp)pChunkto)->iCount = ((mng_evntp)pChunkfrom)->iCount;
-
-  if (((mng_evntp)pChunkto)->iCount)
-  {
-    mng_uint32      iX;
-    mng_evnt_entryp pEntry;
-    mng_uint32      iLen = ((mng_evntp)pChunkto)->iCount * sizeof (mng_evnt_entry);
-
-    MNG_ALLOC (pData, ((mng_evntp)pChunkto)->pEntries, iLen);
-    MNG_COPY  (((mng_evntp)pChunkto)->pEntries, ((mng_evntp)pChunkfrom)->pEntries, iLen);
-
-    pEntry = ((mng_evntp)pChunkto)->pEntries;
-
-    for (iX = 0; iX < ((mng_evntp)pChunkto)->iCount; iX++)
-    {
-      if (pEntry->iSegmentnamesize)
-      {
-        mng_pchar pTemp = pEntry->zSegmentname;
-
-        MNG_ALLOC (pData, pEntry->zSegmentname, pEntry->iSegmentnamesize+1);
-        MNG_COPY  (pEntry->zSegmentname, pTemp, pEntry->iSegmentnamesize);
-      }
-      else
-      {
-        pEntry->zSegmentname = MNG_NULL;
-      }
-
-      pEntry++;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_EVNT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-ASSIGN_CHUNK_HDR (mng_assign_unknown)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_UNKNOWN, MNG_LC_START);
-#endif
-
-  ((mng_unknown_chunkp)pChunkto)->iDatasize = ((mng_unknown_chunkp)pChunkfrom)->iDatasize;
-
-  if (((mng_unknown_chunkp)pChunkto)->iDatasize)
-  {
-    MNG_ALLOC (pData, ((mng_unknown_chunkp)pChunkto)->pData, ((mng_unknown_chunkp)pChunkto)->iDatasize);
-    MNG_COPY  (((mng_unknown_chunkp)pChunkto)->pData, ((mng_unknown_chunkp)pChunkfrom)->pData,
-               ((mng_unknown_chunkp)pChunkto)->iDatasize);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ASSIGN_UNKNOWN, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#endif /* MNG_INCLUDE_WRITE_PROCS */
-
-/* ************************************************************************** */
-/* * end of file                                                            * */
-/* ************************************************************************** */
-
diff --git a/Source/LibMNG/libmng_chunk_prc.h b/Source/LibMNG/libmng_chunk_prc.h
deleted file mode 100644
index 0cf0f3c..0000000
--- a/Source/LibMNG/libmng_chunk_prc.h
+++ /dev/null
@@ -1,381 +0,0 @@
-/* ************************************************************************** */
-/* *             For conditions of distribution and use,                    * */
-/* *                see copyright notice in libmng.h                        * */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * project   : libmng                                                     * */
-/* * file      : libmng_chunk_prc.h        copyright (c) 2000-2007 G.Juyn   * */
-/* * version   : 1.0.10                                                     * */
-/* *                                                                        * */
-/* * purpose   : Chunk initialization & cleanup (definition)                * */
-/* *                                                                        * */
-/* * author    : G.Juyn                                                     * */
-/* *                                                                        * */
-/* * comment   : definition of the chunk initialization & cleanup routines  * */
-/* *                                                                        * */
-/* * changes   : 0.5.1 - 05/08/2000 - G.Juyn                                * */
-/* *             - changed strict-ANSI stuff                                * */
-/* *                                                                        * */
-/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
-/* *             - changed file-prefixes                                    * */
-/* *                                                                        * */
-/* *             0.9.3 - 08/26/2000 - G.Juyn                                * */
-/* *             - added MAGN chunk                                         * */
-/* *             0.9.3 - 10/16/2000 - G.Juyn                                * */
-/* *             - added support for JDAA                                   * */
-/* *                                                                        * */
-/* *             1.0.5 - 08/19/2002 - G.Juyn                                * */
-/* *             - B597134 - libmng pollutes the linker namespace           * */
-/* *             1.0.5 - 09/14/2002 - G.Juyn                                * */
-/* *             - added event handling for dynamic MNG                     * */
-/* *                                                                        * */
-/* *             1.0.6 - 07/07/2003 - G.R-P                                 * */
-/* *             - added NO_DELTA_PNG support                               * */
-/* *             1.0.6 - 07/29/2003 - G.R-P                                 * */
-/* *             - added conditionals around PAST chunk support             * */
-/* *                                                                        * */
-/* *             1.0.9 - 12/05/2004 - G.Juyn                                * */
-/* *             - added conditional MNG_OPTIMIZE_CHUNKINITFREE             * */
-/* *             1.0.9 - 12/06/2004 - G.Juyn                                * */
-/* *             - added conditional MNG_OPTIMIZE_CHUNKASSIGN               * */
-/* *                                                                        * */
-/* *             1.0.10 - 04/08/2007 - G.Juyn                               * */
-/* *             - added support for mPNG proposal                          * */
-/* *             1.0.10 - 04/12/2007 - G.Juyn                               * */
-/* *             - added support for ANG proposal                           * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
-#pragma option -A                      /* force ANSI-C */
-#endif
-
-#ifndef _libmng_chunk_prc_h_
-#define _libmng_chunk_prc_h_
-
-/* ************************************************************************** */
-
-void mng_add_chunk (mng_datap  pData,
-                    mng_chunkp pChunk);
-
-/* ************************************************************************** */
-
-#define INIT_CHUNK_HDR(n) mng_retcode n (mng_datap   pData,    \
-                                         mng_chunkp  pHeader,  \
-                                         mng_chunkp* ppChunk)
-
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-INIT_CHUNK_HDR (mng_init_general) ;
-#else
-INIT_CHUNK_HDR (mng_init_ihdr) ;
-INIT_CHUNK_HDR (mng_init_plte) ;
-INIT_CHUNK_HDR (mng_init_idat) ;
-INIT_CHUNK_HDR (mng_init_iend) ;
-INIT_CHUNK_HDR (mng_init_trns) ;
-INIT_CHUNK_HDR (mng_init_gama) ;
-INIT_CHUNK_HDR (mng_init_chrm) ;
-INIT_CHUNK_HDR (mng_init_srgb) ;
-INIT_CHUNK_HDR (mng_init_iccp) ;
-INIT_CHUNK_HDR (mng_init_text) ;
-INIT_CHUNK_HDR (mng_init_ztxt) ;
-INIT_CHUNK_HDR (mng_init_itxt) ;
-INIT_CHUNK_HDR (mng_init_bkgd) ;
-INIT_CHUNK_HDR (mng_init_phys) ;
-INIT_CHUNK_HDR (mng_init_sbit) ;
-INIT_CHUNK_HDR (mng_init_splt) ;
-INIT_CHUNK_HDR (mng_init_hist) ;
-INIT_CHUNK_HDR (mng_init_time) ;
-INIT_CHUNK_HDR (mng_init_mhdr) ;
-INIT_CHUNK_HDR (mng_init_mend) ;
-INIT_CHUNK_HDR (mng_init_loop) ;
-INIT_CHUNK_HDR (mng_init_endl) ;
-INIT_CHUNK_HDR (mng_init_defi) ;
-INIT_CHUNK_HDR (mng_init_basi) ;
-INIT_CHUNK_HDR (mng_init_clon) ;
-#ifndef MNG_SKIPCHUNK_PAST
-INIT_CHUNK_HDR (mng_init_past) ;
-#endif
-INIT_CHUNK_HDR (mng_init_disc) ;
-INIT_CHUNK_HDR (mng_init_back) ;
-INIT_CHUNK_HDR (mng_init_fram) ;
-INIT_CHUNK_HDR (mng_init_move) ;
-INIT_CHUNK_HDR (mng_init_clip) ;
-INIT_CHUNK_HDR (mng_init_show) ;
-INIT_CHUNK_HDR (mng_init_term) ;
-INIT_CHUNK_HDR (mng_init_save) ;
-INIT_CHUNK_HDR (mng_init_seek) ;
-INIT_CHUNK_HDR (mng_init_expi) ;
-INIT_CHUNK_HDR (mng_init_fpri) ;
-INIT_CHUNK_HDR (mng_init_need) ;
-INIT_CHUNK_HDR (mng_init_phyg) ;
-#ifdef MNG_INCLUDE_JNG
-INIT_CHUNK_HDR (mng_init_jhdr) ;
-INIT_CHUNK_HDR (mng_init_jdaa) ;
-INIT_CHUNK_HDR (mng_init_jdat) ;
-INIT_CHUNK_HDR (mng_init_jsep) ;
-#endif
-#ifndef MNG_NO_DELTA_PNG
-INIT_CHUNK_HDR (mng_init_dhdr) ;
-INIT_CHUNK_HDR (mng_init_prom) ;
-INIT_CHUNK_HDR (mng_init_ipng) ;
-INIT_CHUNK_HDR (mng_init_pplt) ;
-#ifdef MNG_INCLUDE_JNG
-INIT_CHUNK_HDR (mng_init_ijng) ;
-#endif
-INIT_CHUNK_HDR (mng_init_drop) ;
-INIT_CHUNK_HDR (mng_init_dbyk) ;
-INIT_CHUNK_HDR (mng_init_ordr) ;
-#endif
-INIT_CHUNK_HDR (mng_init_magn) ;
-INIT_CHUNK_HDR (mng_init_evnt) ;
-INIT_CHUNK_HDR (mng_init_unknown) ;
-#endif /* MNG_OPTIMIZE_CHUNKINITFREE */
-
-/* ************************************************************************** */
-
-#define FREE_CHUNK_HDR(n) mng_retcode n (mng_datap   pData,    \
-                                         mng_chunkp  pHeader)
-
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-FREE_CHUNK_HDR (mng_free_general) ;
-#else /* MNG_OPTIMIZE_CHUNKINITFREE */
-FREE_CHUNK_HDR (mng_free_ihdr) ;
-FREE_CHUNK_HDR (mng_free_plte) ;
-FREE_CHUNK_HDR (mng_free_iend) ;
-FREE_CHUNK_HDR (mng_free_trns) ;
-FREE_CHUNK_HDR (mng_free_gama) ;
-FREE_CHUNK_HDR (mng_free_chrm) ;
-FREE_CHUNK_HDR (mng_free_srgb) ;
-FREE_CHUNK_HDR (mng_free_bkgd) ;
-FREE_CHUNK_HDR (mng_free_phys) ;
-FREE_CHUNK_HDR (mng_free_sbit) ;
-FREE_CHUNK_HDR (mng_free_hist) ;
-FREE_CHUNK_HDR (mng_free_time) ;
-FREE_CHUNK_HDR (mng_free_mhdr) ;
-FREE_CHUNK_HDR (mng_free_mend) ;
-FREE_CHUNK_HDR (mng_free_endl) ;
-FREE_CHUNK_HDR (mng_free_defi) ;
-FREE_CHUNK_HDR (mng_free_basi) ;
-FREE_CHUNK_HDR (mng_free_clon) ;
-FREE_CHUNK_HDR (mng_free_back) ;
-FREE_CHUNK_HDR (mng_free_move) ;
-FREE_CHUNK_HDR (mng_free_clip) ;
-FREE_CHUNK_HDR (mng_free_show) ;
-FREE_CHUNK_HDR (mng_free_term) ;
-FREE_CHUNK_HDR (mng_free_fpri) ;
-FREE_CHUNK_HDR (mng_free_phyg) ;
-#ifdef MNG_INCLUDE_JNG
-FREE_CHUNK_HDR (mng_free_jhdr) ;
-FREE_CHUNK_HDR (mng_free_jsep) ;
-#endif
-#ifndef MNG_NO_DELTA_PNG
-FREE_CHUNK_HDR (mng_free_dhdr) ;
-FREE_CHUNK_HDR (mng_free_prom) ;
-FREE_CHUNK_HDR (mng_free_ipng) ;
-FREE_CHUNK_HDR (mng_free_pplt) ;
-#ifdef MNG_INCLUDE_JNG
-FREE_CHUNK_HDR (mng_free_ijng) ;
-#endif
-#endif
-FREE_CHUNK_HDR (mng_free_magn) ;
-#endif /* MNG_OPTIMIZE_CHUNKINITFREE */
-
-FREE_CHUNK_HDR (mng_free_idat) ;
-FREE_CHUNK_HDR (mng_free_iccp) ;
-FREE_CHUNK_HDR (mng_free_text) ;
-FREE_CHUNK_HDR (mng_free_ztxt) ;
-FREE_CHUNK_HDR (mng_free_itxt) ;
-FREE_CHUNK_HDR (mng_free_splt) ;
-FREE_CHUNK_HDR (mng_free_loop) ;
-#ifndef MNG_SKIPCHUNK_PAST
-FREE_CHUNK_HDR (mng_free_past) ;
-#endif
-FREE_CHUNK_HDR (mng_free_disc) ;
-FREE_CHUNK_HDR (mng_free_fram) ;
-FREE_CHUNK_HDR (mng_free_save) ;
-FREE_CHUNK_HDR (mng_free_seek) ;
-FREE_CHUNK_HDR (mng_free_expi) ;
-FREE_CHUNK_HDR (mng_free_need) ;
-#ifdef MNG_INCLUDE_JNG
-FREE_CHUNK_HDR (mng_free_jdaa) ;
-FREE_CHUNK_HDR (mng_free_jdat) ;
-#endif
-#ifndef MNG_NO_DELTA_PNG
-FREE_CHUNK_HDR (mng_free_drop) ;
-FREE_CHUNK_HDR (mng_free_dbyk) ;
-FREE_CHUNK_HDR (mng_free_ordr) ;
-#endif
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-FREE_CHUNK_HDR (mng_free_mpng) ;
-#endif
-#ifdef MNG_INCLUDE_ANG_PROPOSAL
-FREE_CHUNK_HDR (mng_free_adat) ;
-#endif
-FREE_CHUNK_HDR (mng_free_evnt) ;
-FREE_CHUNK_HDR (mng_free_unknown) ;
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_WRITE_PROCS
-
-#define ASSIGN_CHUNK_HDR(n) mng_retcode n (mng_datap   pData,    \
-                                           mng_chunkp  pChunkto, \
-                                           mng_chunkp  pChunkfrom)
-
-#ifdef MNG_OPTIMIZE_CHUNKASSIGN
-ASSIGN_CHUNK_HDR (mng_assign_general) ;
-#else /* MNG_OPTIMIZE_CHUNKASSIGN */
-ASSIGN_CHUNK_HDR (mng_assign_ihdr) ;
-ASSIGN_CHUNK_HDR (mng_assign_plte) ;
-ASSIGN_CHUNK_HDR (mng_assign_iend) ;
-ASSIGN_CHUNK_HDR (mng_assign_trns) ;
-ASSIGN_CHUNK_HDR (mng_assign_gama) ;
-ASSIGN_CHUNK_HDR (mng_assign_chrm) ;
-ASSIGN_CHUNK_HDR (mng_assign_srgb) ;
-ASSIGN_CHUNK_HDR (mng_assign_bkgd) ;
-ASSIGN_CHUNK_HDR (mng_assign_phys) ;
-ASSIGN_CHUNK_HDR (mng_assign_sbit) ;
-ASSIGN_CHUNK_HDR (mng_assign_hist) ;
-ASSIGN_CHUNK_HDR (mng_assign_time) ;
-ASSIGN_CHUNK_HDR (mng_assign_mhdr) ;
-ASSIGN_CHUNK_HDR (mng_assign_mend) ;
-ASSIGN_CHUNK_HDR (mng_assign_endl) ;
-ASSIGN_CHUNK_HDR (mng_assign_defi) ;
-ASSIGN_CHUNK_HDR (mng_assign_basi) ;
-ASSIGN_CHUNK_HDR (mng_assign_clon) ;
-ASSIGN_CHUNK_HDR (mng_assign_back) ;
-ASSIGN_CHUNK_HDR (mng_assign_move) ;
-ASSIGN_CHUNK_HDR (mng_assign_clip) ;
-ASSIGN_CHUNK_HDR (mng_assign_show) ;
-ASSIGN_CHUNK_HDR (mng_assign_term) ;
-ASSIGN_CHUNK_HDR (mng_assign_fpri) ;
-ASSIGN_CHUNK_HDR (mng_assign_phyg) ;
-#ifdef MNG_INCLUDE_JNG
-ASSIGN_CHUNK_HDR (mng_assign_jhdr) ;
-ASSIGN_CHUNK_HDR (mng_assign_jsep) ;
-#endif
-#ifndef MNG_NO_DELTA_PNG
-ASSIGN_CHUNK_HDR (mng_assign_dhdr) ;
-ASSIGN_CHUNK_HDR (mng_assign_prom) ;
-ASSIGN_CHUNK_HDR (mng_assign_ipng) ;
-ASSIGN_CHUNK_HDR (mng_assign_pplt) ;
-#ifdef MNG_INCLUDE_JNG
-ASSIGN_CHUNK_HDR (mng_assign_ijng) ;
-#endif
-#endif
-ASSIGN_CHUNK_HDR (mng_assign_magn) ;
-#endif /* MNG_OPTIMIZE_CHUNKASSIGN */
-
-ASSIGN_CHUNK_HDR (mng_assign_idat) ;
-ASSIGN_CHUNK_HDR (mng_assign_iccp) ;
-ASSIGN_CHUNK_HDR (mng_assign_text) ;
-ASSIGN_CHUNK_HDR (mng_assign_ztxt) ;
-ASSIGN_CHUNK_HDR (mng_assign_itxt) ;
-ASSIGN_CHUNK_HDR (mng_assign_splt) ;
-ASSIGN_CHUNK_HDR (mng_assign_loop) ;
-#ifndef MNG_SKIPCHUNK_PAST
-ASSIGN_CHUNK_HDR (mng_assign_past) ;
-#endif
-ASSIGN_CHUNK_HDR (mng_assign_disc) ;
-ASSIGN_CHUNK_HDR (mng_assign_fram) ;
-ASSIGN_CHUNK_HDR (mng_assign_save) ;
-ASSIGN_CHUNK_HDR (mng_assign_seek) ;
-ASSIGN_CHUNK_HDR (mng_assign_need) ;
-ASSIGN_CHUNK_HDR (mng_assign_expi) ;
-#ifdef MNG_INCLUDE_JNG
-ASSIGN_CHUNK_HDR (mng_assign_jdaa) ;
-ASSIGN_CHUNK_HDR (mng_assign_jdat) ;
-#endif
-#ifndef MNG_NO_DELTA_PNG
-ASSIGN_CHUNK_HDR (mng_assign_drop) ;
-ASSIGN_CHUNK_HDR (mng_assign_dbyk) ;
-ASSIGN_CHUNK_HDR (mng_assign_ordr) ;
-#endif
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-ASSIGN_CHUNK_HDR (mng_assign_mpng) ;
-#endif
-#ifdef MNG_INCLUDE_ANG_PROPOSAL
-ASSIGN_CHUNK_HDR (mng_assign_ahdr) ;
-ASSIGN_CHUNK_HDR (mng_assign_adat) ;
-#endif
-ASSIGN_CHUNK_HDR (mng_assign_evnt) ;
-ASSIGN_CHUNK_HDR (mng_assign_unknown) ;
-
-/* ************************************************************************** */
-
-#else /* MNG_INCLUDE_WRITE_PROCS */
-#define mng_assign_general 0
-#define mng_assign_ihdr 0
-#define mng_assign_plte 0
-#define mng_assign_idat 0
-#define mng_assign_iend 0
-#define mng_assign_trns 0
-#define mng_assign_gama 0
-#define mng_assign_chrm 0
-#define mng_assign_srgb 0
-#define mng_assign_iccp 0
-#define mng_assign_text 0
-#define mng_assign_ztxt 0
-#define mng_assign_itxt 0
-#define mng_assign_bkgd 0
-#define mng_assign_phys 0
-#define mng_assign_sbit 0
-#define mng_assign_splt 0
-#define mng_assign_hist 0
-#define mng_assign_time 0
-#define mng_assign_mhdr 0
-#define mng_assign_mend 0
-#define mng_assign_loop 0
-#define mng_assign_endl 0
-#define mng_assign_defi 0
-#define mng_assign_basi 0
-#define mng_assign_clon 0
-#ifndef MNG_SKIPCHUNK_PAST
-#define mng_assign_past 0
-#endif
-#define mng_assign_disc 0
-#define mng_assign_back 0
-#define mng_assign_fram 0
-#define mng_assign_move 0
-#define mng_assign_clip 0
-#define mng_assign_show 0
-#define mng_assign_term 0
-#define mng_assign_save 0
-#define mng_assign_seek 0
-#define mng_assign_expi 0
-#define mng_assign_fpri 0
-#define mng_assign_phyg 0
-#ifdef MNG_INCLUDE_JNG
-#define mng_assign_jhdr 0
-#define mng_assign_jdaa 0
-#define mng_assign_jdat 0
-#define mng_assign_jsep 0
-#endif
-#ifndef MNG_NO_DELTA_PNG
-#define mng_assign_dhdr 0
-#define mng_assign_prom 0
-#define mng_assign_ipng 0
-#define mng_assign_pplt 0
-#ifdef MNG_INCLUDE_JNG
-#define mng_assign_ijng 0
-#endif
-#define mng_assign_drop 0
-#define mng_assign_dbyk 0
-#define mng_assign_ordr 0
-#endif
-#define mng_assign_magn 0
-#define mng_assign_need 0
-#define mng_assign_mpng 0
-#define mng_assign_ahdr 0
-#define mng_assign_adat 0
-#define mng_assign_evnt 0
-#define mng_assign_unknown 0
-#endif /* MNG_INCLUDE_WRITE_PROCS */
-
-/* ************************************************************************** */
-
-#endif /* _libmng_chunk_prc_h_ */
-
-/* ************************************************************************** */
-/* * end of file                                                            * */
-/* ************************************************************************** */
diff --git a/Source/LibMNG/libmng_chunk_xs.c b/Source/LibMNG/libmng_chunk_xs.c
deleted file mode 100644
index 1c4ec2e..0000000
--- a/Source/LibMNG/libmng_chunk_xs.c
+++ /dev/null
@@ -1,7016 +0,0 @@
-/* ************************************************************************** */
-/* *             For conditions of distribution and use,                    * */
-/* *                see copyright notice in libmng.h                        * */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * project   : libmng                                                     * */
-/* * file      : libmng_chunk_xs.c         copyright (c) 2000-2007 G.Juyn   * */
-/* * version   : 1.0.10                                                     * */
-/* *                                                                        * */
-/* * purpose   : chunk access functions (implementation)                    * */
-/* *                                                                        * */
-/* * author    : G.Juyn                                                     * */
-/* *                                                                        * */
-/* * comment   : implementation of the chunk access functions               * */
-/* *                                                                        * */
-/* * changes   : 0.5.1 - 05/06/2000 - G.Juyn                                * */
-/* *             - changed and filled iterate-chunk function                * */
-/* *             0.5.1 - 05/08/2000 - G.Juyn                                * */
-/* *             - fixed calling convention                                 * */
-/* *             - added getchunk functions                                 * */
-/* *             - added putchunk functions                                 * */
-/* *             - changed strict-ANSI stuff                                * */
-/* *             0.5.1 - 05/11/2000 - G.Juyn                                * */
-/* *             - added empty-chunk put-routines                           * */
-/* *             0.5.1 - 05/12/2000 - G.Juyn                                * */
-/* *             - changed trace to macro for callback error-reporting      * */
-/* *             0.5.1 - 05/15/2000 - G.Juyn                                * */
-/* *             - added getimgdata & putimgdata functions                  * */
-/* *                                                                        * */
-/* *             0.5.2 - 05/19/2000 - G.Juyn                                * */
-/* *             - B004 - fixed problem with MNG_SUPPORT_WRITE not defined  * */
-/* *               also for MNG_SUPPORT_WRITE without MNG_INCLUDE_JNG       * */
-/* *             - Cleaned up some code regarding mixed support             * */
-/* *                                                                        * */
-/* *             0.9.1 - 07/19/2000 - G.Juyn                                * */
-/* *             - fixed creation-code                                      * */
-/* *                                                                        * */
-/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
-/* *             - changed file-prefixes                                    * */
-/* *             - added function to set simplicity field                   * */
-/* *             - fixed putchunk_unknown() function                        * */
-/* *                                                                        * */
-/* *             0.9.3 - 08/07/2000 - G.Juyn                                * */
-/* *             - B111300 - fixup for improved portability                 * */
-/* *             0.9.3 - 08/26/2000 - G.Juyn                                * */
-/* *             - added MAGN chunk                                         * */
-/* *             0.9.3 - 10/20/2000 - G.Juyn                                * */
-/* *             - fixed putchunk_plte() to set bEmpty parameter            * */
-/* *                                                                        * */
-/* *             0.9.5 - 01/25/2001 - G.Juyn                                * */
-/* *             - fixed some small compiler warnings (thanks Nikki)        * */
-/* *                                                                        * */
-/* *             1.0.5 - 09/07/2002 - G.Juyn                                * */
-/* *             - B578940 - unimplemented functions return errorcode       * */
-/* *             1.0.5 - 08/19/2002 - G.Juyn                                * */
-/* *             - B597134 - libmng pollutes the linker namespace           * */
-/* *             - added HLAPI function to copy chunks                      * */
-/* *             1.0.5 - 09/14/2002 - G.Juyn                                * */
-/* *             - added event handling for dynamic MNG                     * */
-/* *             1.0.5 - 10/07/2002 - G.Juyn                                * */
-/* *             - added check for TERM placement during create/write       * */
-/* *             1.0.5 - 11/28/2002 - G.Juyn                                * */
-/* *             - fixed definition of iMethodX/Y for MAGN chunk            * */
-/* *                                                                        * */
-/* *             1.0.6 - 05/25/2003 - G.R-P                                 * */
-/* *             - added MNG_SKIPCHUNK_cHNK footprint optimizations         * */
-/* *             1.0.6 - 07/07/2003 - G.R-P                                 * */
-/* *             - added MNG_NO_DELTA_PNG reduction and more SKIPCHUNK      * */
-/* *               optimizations                                            * */
-/* *             1.0.6 - 07/29/2003 - G.R-P                                 * */
-/* *             - added conditionals around PAST chunk support             * */
-/* *             1.0.6 - 08/17/2003 - G.R-P                                 * */
-/* *             - added conditionals around non-VLC chunk support          * */
-/* *                                                                        * */
-/* *             1.0.8 - 04/01/2004 - G.Juyn                                * */
-/* *             - added missing get-/put-chunk-jdaa                        * */
-/* *             1.0.8 - 08/02/2004 - G.Juyn                                * */
-/* *             - added conditional to allow easier writing of large MNG's * */
-/* *                                                                        * */
-/* *             1.0.9 - 09/17/2004 - G.R-P                                 * */
-/* *             - added two more conditionals                              * */
-/* *             1.0.9 - 09/25/2004 - G.Juyn                                * */
-/* *             - replaced MNG_TWEAK_LARGE_FILES with permanent solution   * */
-/* *             1.0.9 - 17/14/2004 - G.Juyn                                * */
-/* *             - fixed PPLT getchunk/putchunk routines                    * */
-/* *             1.0.9 - 12/05/2004 - G.Juyn                                * */
-/* *             - added conditional MNG_OPTIMIZE_CHUNKINITFREE             * */
-/* *             1.0.9 - 12/20/2004 - G.Juyn                                * */
-/* *             - cleaned up macro-invocations (thanks to D. Airlie)       * */
-/* *                                                                        * */
-/* *             1.0.10 - 04/08/2007 - G.Juyn                               * */
-/* *             - added support for mPNG proposal                          * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#include "libmng.h"
-#include "libmng_data.h"
-#include "libmng_error.h"
-#include "libmng_trace.h"
-#ifdef __BORLANDC__
-#pragma hdrstop
-#endif
-#include "libmng_memory.h"
-#include "libmng_chunks.h"
-#ifdef MNG_OPTIMIZE_CHUNKREADER
-#include "libmng_chunk_descr.h"
-#endif
-#include "libmng_chunk_prc.h"
-#include "libmng_chunk_io.h"
-
-#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
-#pragma option -A                      /* force ANSI-C */
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_ACCESS_CHUNKS
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_iterate_chunks (mng_handle       hHandle,
-                                         mng_uint32       iChunkseq,
-                                         mng_iteratechunk fProc)
-{
-  mng_uint32  iSeq;
-  mng_chunkid iChunkname;
-  mng_datap   pData;
-  mng_chunkp  pChunk;
-  mng_bool    bCont;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_ITERATE_CHUNKS, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = ((mng_datap)hHandle);        /* and make it addressable */
-
-  iSeq   = 0;
-  bCont  = MNG_TRUE;
-  pChunk = pData->pFirstchunk;         /* get the first chunk */
-                                       /* as long as there are some more */
-  while ((pChunk) && (bCont))          /* and the app didn't signal a stop */
-  {
-    if (iSeq >= iChunkseq)             /* reached the first target ? */
-    {                                  /* then call this and next ones back in... */
-      iChunkname = ((mng_chunk_headerp)pChunk)->iChunkname;
-      bCont      = fProc (hHandle, (mng_handle)pChunk, iChunkname, iSeq);
-    }
-
-    iSeq++;                            /* next one */
-    pChunk = ((mng_chunk_headerp)pChunk)->pNext;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_ITERATE_CHUNKS, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_WRITE
-mng_retcode MNG_DECL mng_copy_chunk (mng_handle hHandle,
-                                     mng_handle hChunk,
-                                     mng_handle hHandleOut)
-{
-  mng_datap   pDataOut;
-  mng_chunkp  pChunk;
-  mng_chunkp  pChunkOut;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_COPY_CHUNK, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handles */
-  MNG_VALIDHANDLE (hHandleOut)
-
-  pDataOut = (mng_datap)hHandleOut;    /* make outhandle addressable */
-  pChunk   = (mng_chunkp)hChunk;       /* address the chunk */
-
-  if (!pDataOut->bCreating)            /* aren't we creating a new file ? */
-    MNG_ERROR (pDataOut, MNG_FUNCTIONINVALID)
-                                       /* create a new chunk */
-  iRetcode = ((mng_createchunk)((mng_chunk_headerp)pChunk)->fCreate)
-                        (pDataOut, ((mng_chunk_headerp)pChunk), &pChunkOut);
-  if (!iRetcode)                       /* assign the chunk-specific data */
-    iRetcode = ((mng_assignchunk)((mng_chunk_headerp)pChunk)->fAssign)
-                          (pDataOut, pChunkOut, pChunk);
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode; 
-
-  mng_add_chunk (pDataOut, pChunkOut); /* and put it in the output-stream */
-
-                                       /* could it be the end of the chain ? */
-  if (((mng_chunk_headerp)pChunkOut)->iChunkname == MNG_UINT_IEND)
-  {
-#ifdef MNG_INCLUDE_JNG
-    if ((pDataOut->iFirstchunkadded == MNG_UINT_IHDR) ||
-        (pDataOut->iFirstchunkadded == MNG_UINT_JHDR)    )
-#else
-    if (pDataOut->iFirstchunkadded == MNG_UINT_IHDR)
-#endif
-      pDataOut->bCreating = MNG_FALSE; /* right; this should be the last chunk !!! */
-  }
-
-  if (((mng_chunk_headerp)pChunkOut)->iChunkname == MNG_UINT_MEND)
-    pDataOut->bCreating = MNG_FALSE;   /* definitely this should be the last !!! */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_COPY_CHUNK, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_WRITE */
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_getchunk_ihdr (mng_handle hHandle,
-                                        mng_handle hChunk,
-                                        mng_uint32 *iWidth,
-                                        mng_uint32 *iHeight,
-                                        mng_uint8  *iBitdepth,
-                                        mng_uint8  *iColortype,
-                                        mng_uint8  *iCompression,
-                                        mng_uint8  *iFilter,
-                                        mng_uint8  *iInterlace)
-{
-  mng_datap pData;
-  mng_ihdrp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_IHDR, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_ihdrp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_IHDR)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *iWidth       = pChunk->iWidth;      /* fill the fields */
-  *iHeight      = pChunk->iHeight;
-  *iBitdepth    = pChunk->iBitdepth;
-  *iColortype   = pChunk->iColortype;
-  *iCompression = pChunk->iCompression;
-  *iFilter      = pChunk->iFilter;
-  *iInterlace   = pChunk->iInterlace;
-
-                                       /* fill the chunk */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_IHDR, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_getchunk_plte (mng_handle   hHandle,
-                                        mng_handle   hChunk,
-                                        mng_uint32   *iCount,
-                                        mng_palette8 *aPalette)
-{
-  mng_datap pData;
-  mng_pltep pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_PLTE, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_pltep)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_PLTE)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *iCount = pChunk->iEntrycount;       /* fill the fields */
-
-  MNG_COPY (*aPalette, pChunk->aEntries, sizeof (mng_palette8));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_PLTE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_getchunk_idat (mng_handle hHandle,
-                                        mng_handle hChunk,
-                                        mng_uint32 *iRawlen,
-                                        mng_ptr    *pRawdata)
-{
-  mng_datap pData;
-  mng_idatp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_IDAT, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_idatp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_IDAT)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *iRawlen  = pChunk->iDatasize;       /* fill the fields */
-  *pRawdata = pChunk->pData;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_IDAT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_getchunk_trns (mng_handle   hHandle,
-                                        mng_handle   hChunk,
-                                        mng_bool     *bEmpty,
-                                        mng_bool     *bGlobal,
-                                        mng_uint8    *iType,
-                                        mng_uint32   *iCount,
-                                        mng_uint8arr *aAlphas,
-                                        mng_uint16   *iGray,
-                                        mng_uint16   *iRed,
-                                        mng_uint16   *iGreen,
-                                        mng_uint16   *iBlue,
-                                        mng_uint32   *iRawlen,
-                                        mng_uint8arr *aRawdata)
-{
-  mng_datap pData;
-  mng_trnsp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_TRNS, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_trnsp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_tRNS)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *bEmpty   = pChunk->bEmpty;          /* fill the fields */
-  *bGlobal  = pChunk->bGlobal;
-  *iType    = pChunk->iType;
-  *iCount   = pChunk->iCount;
-  *iGray    = pChunk->iGray;
-  *iRed     = pChunk->iRed;
-  *iGreen   = pChunk->iGreen;
-  *iBlue    = pChunk->iBlue;
-  *iRawlen  = pChunk->iRawlen;
-
-  MNG_COPY (*aAlphas,  pChunk->aEntries, sizeof (mng_uint8arr));
-  MNG_COPY (*aRawdata, pChunk->aRawdata, sizeof (mng_uint8arr));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_TRNS, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_gAMA
-mng_retcode MNG_DECL mng_getchunk_gama (mng_handle hHandle,
-                                        mng_handle hChunk,
-                                        mng_bool   *bEmpty,
-                                        mng_uint32 *iGamma)
-{
-  mng_datap pData;
-  mng_gamap pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_GAMA, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_gamap)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_gAMA)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *bEmpty = pChunk->bEmpty;            /* fill the fields */
-  *iGamma = pChunk->iGamma;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_GAMA, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_cHRM
-mng_retcode MNG_DECL mng_getchunk_chrm (mng_handle hHandle,
-                                        mng_handle hChunk,
-                                        mng_bool   *bEmpty,
-                                        mng_uint32 *iWhitepointx,
-                                        mng_uint32 *iWhitepointy,
-                                        mng_uint32 *iRedx,
-                                        mng_uint32 *iRedy,
-                                        mng_uint32 *iGreenx,
-                                        mng_uint32 *iGreeny,
-                                        mng_uint32 *iBluex,
-                                        mng_uint32 *iBluey)
-{
-  mng_datap pData;
-  mng_chrmp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_CHRM, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_chrmp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_cHRM)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *bEmpty       = pChunk->bEmpty;      /* fill the fields */     
-  *iWhitepointx = pChunk->iWhitepointx;
-  *iWhitepointy = pChunk->iWhitepointy;
-  *iRedx        = pChunk->iRedx;
-  *iRedy        = pChunk->iRedy;
-  *iGreenx      = pChunk->iGreenx;
-  *iGreeny      = pChunk->iGreeny;
-  *iBluex       = pChunk->iBluex;
-  *iBluey       = pChunk->iBluey;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_CHRM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_sRGB
-mng_retcode MNG_DECL mng_getchunk_srgb (mng_handle hHandle,
-                                        mng_handle hChunk,
-                                        mng_bool   *bEmpty,
-                                        mng_uint8  *iRenderingintent)
-{
-  mng_datap pData;
-  mng_srgbp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_SRGB, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_srgbp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_sRGB)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *bEmpty           = pChunk->bEmpty;  /* fill the fields */        
-  *iRenderingintent = pChunk->iRenderingintent;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_SRGB, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_iCCP
-mng_retcode MNG_DECL mng_getchunk_iccp (mng_handle hHandle,
-                                        mng_handle hChunk,
-                                        mng_bool   *bEmpty,
-                                        mng_uint32 *iNamesize,
-                                        mng_pchar  *zName,
-                                        mng_uint8  *iCompression,
-                                        mng_uint32 *iProfilesize,
-                                        mng_ptr    *pProfile)
-{
-  mng_datap pData;
-  mng_iccpp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_ICCP, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_iccpp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_iCCP)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *bEmpty       = pChunk->bEmpty;      /* fill the fields */     
-  *iNamesize    = pChunk->iNamesize;
-  *zName        = pChunk->zName;
-  *iCompression = pChunk->iCompression;
-  *iProfilesize = pChunk->iProfilesize;
-  *pProfile     = pChunk->pProfile;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_ICCP, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_tEXt
-mng_retcode MNG_DECL mng_getchunk_text (mng_handle hHandle,
-                                        mng_handle hChunk,
-                                        mng_uint32 *iKeywordsize,
-                                        mng_pchar  *zKeyword,
-                                        mng_uint32 *iTextsize,
-                                        mng_pchar  *zText)
-{
-  mng_datap pData;
-  mng_textp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_TEXT, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_textp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_tEXt)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-                                       /* fill the fields */
-  *iKeywordsize = pChunk->iKeywordsize;
-  *zKeyword     = pChunk->zKeyword;
-  *iTextsize    = pChunk->iTextsize;
-  *zText        = pChunk->zText;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_TEXT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_zTXt
-mng_retcode MNG_DECL mng_getchunk_ztxt (mng_handle hHandle,
-                                        mng_handle hChunk,
-                                        mng_uint32 *iKeywordsize,
-                                        mng_pchar  *zKeyword,
-                                        mng_uint8  *iCompression,
-                                        mng_uint32 *iTextsize,
-                                        mng_pchar  *zText)
-{
-  mng_datap pData;
-  mng_ztxtp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_ZTXT, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_ztxtp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_zTXt)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-                                       /* fill the fields */
-  *iKeywordsize = pChunk->iKeywordsize;
-  *zKeyword     = pChunk->zKeyword;
-  *iCompression = pChunk->iCompression;
-  *iTextsize    = pChunk->iTextsize;
-  *zText        = pChunk->zText;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_ZTXT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_iTXt
-mng_retcode MNG_DECL mng_getchunk_itxt (mng_handle hHandle,
-                                        mng_handle hChunk,
-                                        mng_uint32 *iKeywordsize,
-                                        mng_pchar  *zKeyword,
-                                        mng_uint8  *iCompressionflag,
-                                        mng_uint8  *iCompressionmethod,
-                                        mng_uint32 *iLanguagesize,
-                                        mng_pchar  *zLanguage,
-                                        mng_uint32 *iTranslationsize,
-                                        mng_pchar  *zTranslation,
-                                        mng_uint32 *iTextsize,
-                                        mng_pchar  *zText)
-{
-  mng_datap pData;
-  mng_itxtp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_ITXT, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_itxtp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_iTXt)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-                                       /* fill the fields */
-  *iKeywordsize       = pChunk->iKeywordsize;
-  *zKeyword           = pChunk->zKeyword;
-  *iCompressionflag   = pChunk->iCompressionflag;
-  *iCompressionmethod = pChunk->iCompressionmethod;
-  *iLanguagesize      = pChunk->iLanguagesize;
-  *zLanguage          = pChunk->zLanguage;
-  *iTranslationsize   = pChunk->iTranslationsize;
-  *zTranslation       = pChunk->zTranslation;
-  *iTextsize          = pChunk->iTextsize;
-  *zText              = pChunk->zText;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_ITXT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_bKGD
-mng_retcode MNG_DECL mng_getchunk_bkgd (mng_handle hHandle,
-                                        mng_handle hChunk,
-                                        mng_bool   *bEmpty,
-                                        mng_uint8  *iType,
-                                        mng_uint8  *iIndex,
-                                        mng_uint16 *iGray,
-                                        mng_uint16 *iRed,
-                                        mng_uint16 *iGreen,
-                                        mng_uint16 *iBlue)
-{
-  mng_datap pData;
-  mng_bkgdp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_BKGD, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_bkgdp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_bKGD)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *bEmpty = pChunk->bEmpty;            /* fill the fields */
-  *iType  = pChunk->iType;
-  *iIndex = pChunk->iIndex;
-  *iGray  = pChunk->iGray;
-  *iRed   = pChunk->iRed;
-  *iGreen = pChunk->iGreen;
-  *iBlue  = pChunk->iBlue;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_BKGD, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_pHYs
-mng_retcode MNG_DECL mng_getchunk_phys (mng_handle hHandle,
-                                        mng_handle hChunk,
-                                        mng_bool   *bEmpty,
-                                        mng_uint32 *iSizex,
-                                        mng_uint32 *iSizey,
-                                        mng_uint8  *iUnit)
-{
-  mng_datap pData;
-  mng_physp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_PHYS, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_physp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_pHYs)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *bEmpty = pChunk->bEmpty;            /* fill the fields */
-  *iSizex = pChunk->iSizex;
-  *iSizey = pChunk->iSizey;
-  *iUnit  = pChunk->iUnit;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_PHYS, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_sBIT
-mng_retcode MNG_DECL mng_getchunk_sbit (mng_handle    hHandle,
-                                        mng_handle    hChunk,
-                                        mng_bool      *bEmpty,
-                                        mng_uint8     *iType,
-                                        mng_uint8arr4 *aBits)
-{
-  mng_datap pData;
-  mng_sbitp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_SBIT, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_sbitp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_sBIT)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *bEmpty     = pChunk->bEmpty;
-  *iType      = pChunk->iType;
-  (*aBits)[0] = pChunk->aBits[0];
-  (*aBits)[1] = pChunk->aBits[1];
-  (*aBits)[2] = pChunk->aBits[2];
-  (*aBits)[3] = pChunk->aBits[3];
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_SBIT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_sPLT
-mng_retcode MNG_DECL mng_getchunk_splt (mng_handle hHandle,
-                                        mng_handle hChunk,
-                                        mng_bool   *bEmpty,
-                                        mng_uint32 *iNamesize,
-                                        mng_pchar  *zName,
-                                        mng_uint8  *iSampledepth,
-                                        mng_uint32 *iEntrycount,
-                                        mng_ptr    *pEntries)
-{
-  mng_datap pData;
-  mng_spltp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_SPLT, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_spltp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_sPLT)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *bEmpty       = pChunk->bEmpty;      /* fill the fields */      
-  *iNamesize    = pChunk->iNamesize;
-  *zName        = pChunk->zName;
-  *iSampledepth = pChunk->iSampledepth;
-  *iEntrycount  = pChunk->iEntrycount;
-  *pEntries     = pChunk->pEntries;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_SPLT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_hIST
-mng_retcode MNG_DECL mng_getchunk_hist (mng_handle    hHandle,
-                                        mng_handle    hChunk,
-                                        mng_uint32    *iEntrycount,
-                                        mng_uint16arr *aEntries)
-{
-  mng_datap pData;
-  mng_histp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_HIST, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_histp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_hIST)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *iEntrycount = pChunk->iEntrycount;  /* fill the fields */
-
-  MNG_COPY (*aEntries, pChunk->aEntries, sizeof (mng_uint16arr));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_HIST, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_tIME
-mng_retcode MNG_DECL mng_getchunk_time (mng_handle hHandle,
-                                        mng_handle hChunk,
-                                        mng_uint16 *iYear,
-                                        mng_uint8  *iMonth,
-                                        mng_uint8  *iDay,
-                                        mng_uint8  *iHour,
-                                        mng_uint8  *iMinute,
-                                        mng_uint8  *iSecond)
-{
-  mng_datap pData;
-  mng_timep pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_TIME, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_timep)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_tIME)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *iYear   = pChunk->iYear;            /* fill the fields */ 
-  *iMonth  = pChunk->iMonth;
-  *iDay    = pChunk->iDay;
-  *iHour   = pChunk->iHour;
-  *iMinute = pChunk->iMinute;
-  *iSecond = pChunk->iSecond;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_TIME, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_getchunk_mhdr (mng_handle hHandle,
-                                        mng_handle hChunk,
-                                        mng_uint32 *iWidth,
-                                        mng_uint32 *iHeight,
-                                        mng_uint32 *iTicks,
-                                        mng_uint32 *iLayercount,
-                                        mng_uint32 *iFramecount,
-                                        mng_uint32 *iPlaytime,
-                                        mng_uint32 *iSimplicity)
-{
-  mng_datap pData;
-  mng_mhdrp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_MHDR, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_mhdrp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_MHDR)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *iWidth      = pChunk->iWidth;       /* fill the fields */   
-  *iHeight     = pChunk->iHeight;
-  *iTicks      = pChunk->iTicks;
-  *iLayercount = pChunk->iLayercount;
-  *iFramecount = pChunk->iFramecount;
-  *iPlaytime   = pChunk->iPlaytime;
-  *iSimplicity = pChunk->iSimplicity;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_MHDR, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_LOOP
-mng_retcode MNG_DECL mng_getchunk_loop (mng_handle  hHandle,
-                                        mng_handle  hChunk,
-                                        mng_uint8   *iLevel,
-                                        mng_uint32  *iRepeat,
-                                        mng_uint8   *iTermination,
-                                        mng_uint32  *iItermin,
-                                        mng_uint32  *iItermax,
-                                        mng_uint32  *iCount,
-                                        mng_uint32p *pSignals)
-{
-  mng_datap pData;
-  mng_loopp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_LOOP, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_loopp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_LOOP)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *iLevel       = pChunk->iLevel;      /* fill teh fields */
-  *iRepeat      = pChunk->iRepeat;
-  *iTermination = pChunk->iTermination;
-  *iItermin     = pChunk->iItermin;
-  *iItermax     = pChunk->iItermax;
-  *iCount       = pChunk->iCount;
-  *pSignals     = pChunk->pSignals;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_LOOP, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_getchunk_endl (mng_handle hHandle,
-                                        mng_handle hChunk,
-                                        mng_uint8  *iLevel)
-{
-  mng_datap pData;
-  mng_endlp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_ENDL, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_endlp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_ENDL)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *iLevel = pChunk->iLevel;            /* fill the field */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_ENDL, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_DEFI
-mng_retcode MNG_DECL mng_getchunk_defi (mng_handle hHandle,
-                                        mng_handle hChunk,
-                                        mng_uint16 *iObjectid,
-                                        mng_uint8  *iDonotshow,
-                                        mng_uint8  *iConcrete,
-                                        mng_bool   *bHasloca,
-                                        mng_int32  *iXlocation,
-                                        mng_int32  *iYlocation,
-                                        mng_bool   *bHasclip,
-                                        mng_int32  *iLeftcb,
-                                        mng_int32  *iRightcb,
-                                        mng_int32  *iTopcb,
-                                        mng_int32  *iBottomcb)
-{
-  mng_datap pData;
-  mng_defip pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_DEFI, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_defip)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_DEFI)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *iObjectid  = pChunk->iObjectid;     /* fill the fields */
-  *iDonotshow = pChunk->iDonotshow;
-  *iConcrete  = pChunk->iConcrete;
-  *bHasloca   = pChunk->bHasloca;
-  *iXlocation = pChunk->iXlocation;
-  *iYlocation = pChunk->iYlocation;
-  *bHasclip   = pChunk->bHasclip;
-  *iLeftcb    = pChunk->iLeftcb;
-  *iRightcb   = pChunk->iRightcb;
-  *iTopcb     = pChunk->iTopcb;
-  *iBottomcb  = pChunk->iBottomcb;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_DEFI, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_BASI
-mng_retcode MNG_DECL mng_getchunk_basi (mng_handle hHandle,
-                                        mng_handle hChunk,
-                                        mng_uint32 *iWidth,
-                                        mng_uint32 *iHeight,
-                                        mng_uint8  *iBitdepth,
-                                        mng_uint8  *iColortype,
-                                        mng_uint8  *iCompression,
-                                        mng_uint8  *iFilter,
-                                        mng_uint8  *iInterlace,
-                                        mng_uint16 *iRed,
-                                        mng_uint16 *iGreen,
-                                        mng_uint16 *iBlue,
-                                        mng_uint16 *iAlpha,
-                                        mng_uint8  *iViewable)
-{
-  mng_datap pData;
-  mng_basip pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_BASI, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_basip)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_BASI)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *iWidth       = pChunk->iWidth;      /* fill the fields */
-  *iHeight      = pChunk->iHeight;
-  *iBitdepth    = pChunk->iBitdepth;
-  *iColortype   = pChunk->iColortype;
-  *iCompression = pChunk->iCompression;
-  *iFilter      = pChunk->iFilter;
-  *iInterlace   = pChunk->iInterlace;
-  *iRed         = pChunk->iRed;
-  *iGreen       = pChunk->iGreen;
-  *iBlue        = pChunk->iBlue;
-  *iAlpha       = pChunk->iAlpha;
-  *iViewable    = pChunk->iViewable;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_BASI, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_CLON
-mng_retcode MNG_DECL mng_getchunk_clon (mng_handle hHandle,
-                                        mng_handle hChunk,
-                                        mng_uint16 *iSourceid,
-                                        mng_uint16 *iCloneid,
-                                        mng_uint8  *iClonetype,
-                                        mng_uint8  *iDonotshow,
-                                        mng_uint8  *iConcrete,
-                                        mng_bool   *bHasloca,
-                                        mng_uint8  *iLocationtype,
-                                        mng_int32  *iLocationx,
-                                        mng_int32  *iLocationy)
-{
-  mng_datap pData;
-  mng_clonp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_CLON, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_clonp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_CLON)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *iSourceid     = pChunk->iSourceid;  /* fill the fields */  
-  *iCloneid      = pChunk->iCloneid;
-  *iClonetype    = pChunk->iClonetype;
-  *iDonotshow    = pChunk->iDonotshow;
-  *iConcrete     = pChunk->iConcrete;
-  *bHasloca      = pChunk->bHasloca;
-  *iLocationtype = pChunk->iLocationtype;
-  *iLocationx    = pChunk->iLocationx;
-  *iLocationy    = pChunk->iLocationy;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_CLON, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_PAST
-mng_retcode MNG_DECL mng_getchunk_past (mng_handle hHandle,
-                                        mng_handle hChunk,
-                                        mng_uint16 *iDestid,
-                                        mng_uint8  *iTargettype,
-                                        mng_int32  *iTargetx,
-                                        mng_int32  *iTargety,
-                                        mng_uint32 *iCount)
-{
-  mng_datap pData;
-  mng_pastp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_PAST, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_pastp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_PAST)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *iDestid     = pChunk->iDestid;       /* fill the fields */
-  *iTargettype = pChunk->iTargettype;
-  *iTargetx    = pChunk->iTargetx;
-  *iTargety    = pChunk->iTargety;
-  *iCount      = pChunk->iCount;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_PAST, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_PAST
-mng_retcode MNG_DECL mng_getchunk_past_src (mng_handle hHandle,
-                                            mng_handle hChunk,
-                                            mng_uint32 iEntry,
-                                            mng_uint16 *iSourceid,
-                                            mng_uint8  *iComposition,
-                                            mng_uint8  *iOrientation,
-                                            mng_uint8  *iOffsettype,
-                                            mng_int32  *iOffsetx,
-                                            mng_int32  *iOffsety,
-                                            mng_uint8  *iBoundarytype,
-                                            mng_int32  *iBoundaryl,
-                                            mng_int32  *iBoundaryr,
-                                            mng_int32  *iBoundaryt,
-                                            mng_int32  *iBoundaryb)
-{
-  mng_datap        pData;
-  mng_pastp        pChunk;
-  mng_past_sourcep pEntry;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_PAST_SRC, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_pastp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_PAST)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  if (iEntry >= pChunk->iCount)        /* valid index ? */
-    MNG_ERROR (pData, MNG_INVALIDENTRYIX)
-                                       /* address the entry */
-  pEntry         = pChunk->pSources + iEntry;
-
-  *iSourceid     = pEntry->iSourceid;  /* fill the fields */
-  *iComposition  = pEntry->iComposition;
-  *iOrientation  = pEntry->iOrientation;
-  *iOffsettype   = pEntry->iOffsettype;
-  *iOffsetx      = pEntry->iOffsetx;
-  *iOffsety      = pEntry->iOffsety;
-  *iBoundarytype = pEntry->iBoundarytype;
-  *iBoundaryl    = pEntry->iBoundaryl;
-  *iBoundaryr    = pEntry->iBoundaryr;
-  *iBoundaryt    = pEntry->iBoundaryt;
-  *iBoundaryb    = pEntry->iBoundaryb;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_PAST_SRC, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_DISC
-mng_retcode MNG_DECL mng_getchunk_disc (mng_handle  hHandle,
-                                        mng_handle  hChunk,
-                                        mng_uint32  *iCount,
-                                        mng_uint16p *pObjectids)
-{
-  mng_datap pData;
-  mng_discp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_DISC, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_discp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_DISC)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *iCount     = pChunk->iCount;        /* fill the fields */
-  *pObjectids = pChunk->pObjectids;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_DISC, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_BACK
-mng_retcode MNG_DECL mng_getchunk_back (mng_handle hHandle,
-                                        mng_handle hChunk,
-                                        mng_uint16 *iRed,
-                                        mng_uint16 *iGreen,
-                                        mng_uint16 *iBlue,
-                                        mng_uint8  *iMandatory,
-                                        mng_uint16 *iImageid,
-                                        mng_uint8  *iTile)
-{
-  mng_datap pData;
-  mng_backp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_BACK, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_backp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_BACK)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *iRed       = pChunk->iRed;          /* fill the fields */
-  *iGreen     = pChunk->iGreen;
-  *iBlue      = pChunk->iBlue;
-  *iMandatory = pChunk->iMandatory;
-  *iImageid   = pChunk->iImageid;
-  *iTile      = pChunk->iTile;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_BACK, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_FRAM
-mng_retcode MNG_DECL mng_getchunk_fram (mng_handle  hHandle,
-                                        mng_handle  hChunk,
-                                        mng_bool    *bEmpty,
-                                        mng_uint8   *iMode,
-                                        mng_uint32  *iNamesize,
-                                        mng_pchar   *zName,
-                                        mng_uint8   *iChangedelay,
-                                        mng_uint8   *iChangetimeout,
-                                        mng_uint8   *iChangeclipping,
-                                        mng_uint8   *iChangesyncid,
-                                        mng_uint32  *iDelay,
-                                        mng_uint32  *iTimeout,
-                                        mng_uint8   *iBoundarytype,
-                                        mng_int32   *iBoundaryl,
-                                        mng_int32   *iBoundaryr,
-                                        mng_int32   *iBoundaryt,
-                                        mng_int32   *iBoundaryb,
-                                        mng_uint32  *iCount,
-                                        mng_uint32p *pSyncids)
-{
-  mng_datap pData;
-  mng_framp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_FRAM, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_framp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_FRAM)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *bEmpty          = pChunk->bEmpty;   /* fill the fields */      
-  *iMode           = pChunk->iMode;
-  *iNamesize       = pChunk->iNamesize;
-  *zName           = pChunk->zName;
-  *iChangedelay    = pChunk->iChangedelay;
-  *iChangetimeout  = pChunk->iChangetimeout;
-  *iChangeclipping = pChunk->iChangeclipping;
-  *iChangesyncid   = pChunk->iChangesyncid;
-  *iDelay          = pChunk->iDelay;
-  *iTimeout        = pChunk->iTimeout;
-  *iBoundarytype   = pChunk->iBoundarytype;
-  *iBoundaryl      = pChunk->iBoundaryl;
-  *iBoundaryr      = pChunk->iBoundaryr;
-  *iBoundaryt      = pChunk->iBoundaryt;
-  *iBoundaryb      = pChunk->iBoundaryb;
-  *iCount          = pChunk->iCount;
-  *pSyncids        = pChunk->pSyncids;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_FRAM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_MOVE
-mng_retcode MNG_DECL mng_getchunk_move (mng_handle hHandle,
-                                        mng_handle hChunk,
-                                        mng_uint16 *iFirstid,
-                                        mng_uint16 *iLastid,
-                                        mng_uint8  *iMovetype,
-                                        mng_int32  *iMovex,
-                                        mng_int32  *iMovey)
-{
-  mng_datap pData;
-  mng_movep pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_MOVE, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_movep)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_MOVE)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *iFirstid  = pChunk->iFirstid;       /* fill the fields */
-  *iLastid   = pChunk->iLastid;
-  *iMovetype = pChunk->iMovetype;
-  *iMovex    = pChunk->iMovex;
-  *iMovey    = pChunk->iMovey;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_MOVE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_CLIP
-mng_retcode MNG_DECL mng_getchunk_clip (mng_handle hHandle,
-                                        mng_handle hChunk,
-                                        mng_uint16 *iFirstid,
-                                        mng_uint16 *iLastid,
-                                        mng_uint8  *iCliptype,
-                                        mng_int32  *iClipl,
-                                        mng_int32  *iClipr,
-                                        mng_int32  *iClipt,
-                                        mng_int32  *iClipb)
-{
-  mng_datap pData;
-  mng_clipp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_CLIP, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_clipp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_CLIP)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *iFirstid  = pChunk->iFirstid;       /* fill the fields */
-  *iLastid   = pChunk->iLastid;
-  *iCliptype = pChunk->iCliptype;
-  *iClipl    = pChunk->iClipl;
-  *iClipr    = pChunk->iClipr;
-  *iClipt    = pChunk->iClipt;
-  *iClipb    = pChunk->iClipb;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_CLIP, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_SHOW
-mng_retcode MNG_DECL mng_getchunk_show (mng_handle hHandle,
-                                        mng_handle hChunk,
-                                        mng_bool   *bEmpty,
-                                        mng_uint16 *iFirstid,
-                                        mng_uint16 *iLastid,
-                                        mng_uint8  *iMode)
-{
-  mng_datap pData;
-  mng_showp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_SHOW, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_showp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_SHOW)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *bEmpty   = pChunk->bEmpty;          /* fill the fields */
-  *iFirstid = pChunk->iFirstid;
-  *iLastid  = pChunk->iLastid;
-  *iMode    = pChunk->iMode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_SHOW, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_TERM
-mng_retcode MNG_DECL mng_getchunk_term (mng_handle hHandle,
-                                        mng_handle hChunk,
-                                        mng_uint8  *iTermaction,
-                                        mng_uint8  *iIteraction,
-                                        mng_uint32 *iDelay,
-                                        mng_uint32 *iItermax)
-{
-  mng_datap pData;
-  mng_termp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_TERM, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_termp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_TERM)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *iTermaction = pChunk->iTermaction;  /* fill the fields */
-  *iIteraction = pChunk->iIteraction;
-  *iDelay      = pChunk->iDelay;
-  *iItermax    = pChunk->iItermax;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_TERM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_SAVE
-mng_retcode MNG_DECL mng_getchunk_save (mng_handle hHandle,
-                                        mng_handle hChunk,
-                                        mng_bool   *bEmpty,
-                                        mng_uint8  *iOffsettype,
-                                        mng_uint32 *iCount)
-{
-  mng_datap pData;
-  mng_savep pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_SAVE, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_savep)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_SAVE)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *bEmpty      = pChunk->bEmpty;       /* fill the fields */
-  *iOffsettype = pChunk->iOffsettype;
-  *iCount      = pChunk->iCount;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_SAVE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_getchunk_save_entry (mng_handle     hHandle,
-                                              mng_handle     hChunk,
-                                              mng_uint32     iEntry,
-                                              mng_uint8      *iEntrytype,
-                                              mng_uint32arr2 *iOffset,
-                                              mng_uint32arr2 *iStarttime,
-                                              mng_uint32     *iLayernr,
-                                              mng_uint32     *iFramenr,
-                                              mng_uint32     *iNamesize,
-                                              mng_pchar      *zName)
-{
-  mng_datap       pData;
-  mng_savep       pChunk;
-  mng_save_entryp pEntry;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_SAVE_ENTRY, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_savep)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_SAVE)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  if (iEntry >= pChunk->iCount)        /* valid index ? */
-    MNG_ERROR (pData, MNG_INVALIDENTRYIX)
-
-  pEntry  = pChunk->pEntries + iEntry; /* address the entry */
-                                       /* fill the fields */
-  *iEntrytype      = pEntry->iEntrytype;
-  (*iOffset)[0]    = pEntry->iOffset[0];
-  (*iOffset)[1]    = pEntry->iOffset[1];
-  (*iStarttime)[0] = pEntry->iStarttime[0];
-  (*iStarttime)[1] = pEntry->iStarttime[1];
-  *iLayernr        = pEntry->iLayernr;
-  *iFramenr        = pEntry->iFramenr;
-  *iNamesize       = pEntry->iNamesize;
-  *zName           = pEntry->zName;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_SAVE_ENTRY, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_SEEK
-mng_retcode MNG_DECL mng_getchunk_seek (mng_handle hHandle,
-                                        mng_handle hChunk,
-                                        mng_uint32 *iNamesize,
-                                        mng_pchar  *zName)
-{
-  mng_datap pData;
-  mng_seekp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_SEEK, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_seekp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_SEEK)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *iNamesize = pChunk->iNamesize;      /* fill the fields */
-  *zName     = pChunk->zName;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_SEEK, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_eXPI
-mng_retcode MNG_DECL mng_getchunk_expi (mng_handle hHandle,
-                                        mng_handle hChunk,
-                                        mng_uint16 *iSnapshotid,
-                                        mng_uint32 *iNamesize,
-                                        mng_pchar  *zName)
-{
-  mng_datap pData;
-  mng_expip pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_EXPI, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_expip)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_eXPI)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *iSnapshotid = pChunk->iSnapshotid;  /* fill the fields */
-  *iNamesize   = pChunk->iNamesize;
-  *zName       = pChunk->zName;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_EXPI, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_fPRI
-mng_retcode MNG_DECL mng_getchunk_fpri (mng_handle hHandle,
-                                        mng_handle hChunk,
-                                        mng_uint8  *iDeltatype,
-                                        mng_uint8  *iPriority)
-{
-  mng_datap pData;
-  mng_fprip pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_FPRI, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_fprip)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_fPRI)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *iDeltatype = pChunk->iDeltatype;    /* fill the fields */
-  *iPriority  = pChunk->iPriority;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_FPRI, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_nEED
-mng_retcode MNG_DECL mng_getchunk_need (mng_handle hHandle,
-                                        mng_handle hChunk,
-                                        mng_uint32 *iKeywordssize,
-                                        mng_pchar  *zKeywords)
-{
-  mng_datap pData;
-  mng_needp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_NEED, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_needp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_nEED)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-                                       /* fill the fields */
-  *iKeywordssize = pChunk->iKeywordssize;
-  *zKeywords     = pChunk->zKeywords;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_NEED, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_pHYg
-mng_retcode MNG_DECL mng_getchunk_phyg (mng_handle hHandle,
-                                        mng_handle hChunk,
-                                        mng_bool   *bEmpty,
-                                        mng_uint32 *iSizex,
-                                        mng_uint32 *iSizey,
-                                        mng_uint8  *iUnit)
-{
-  mng_datap pData;
-  mng_phygp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_PHYG, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_phygp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_pHYg)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *bEmpty = pChunk->bEmpty;            /* fill the fields */
-  *iSizex = pChunk->iSizex;
-  *iSizey = pChunk->iSizey;
-  *iUnit  = pChunk->iUnit;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_PHYG, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-
-mng_retcode MNG_DECL mng_getchunk_jhdr (mng_handle hHandle,
-                                        mng_handle hChunk,
-                                        mng_uint32 *iWidth,
-                                        mng_uint32 *iHeight,
-                                        mng_uint8  *iColortype,
-                                        mng_uint8  *iImagesampledepth,
-                                        mng_uint8  *iImagecompression,
-                                        mng_uint8  *iImageinterlace,
-                                        mng_uint8  *iAlphasampledepth,
-                                        mng_uint8  *iAlphacompression,
-                                        mng_uint8  *iAlphafilter,
-                                        mng_uint8  *iAlphainterlace)
-{
-  mng_datap pData;
-  mng_jhdrp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_JHDR, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_jhdrp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_JHDR)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *iWidth            = pChunk->iWidth; /* fill the fields */          
-  *iHeight           = pChunk->iHeight;
-  *iColortype        = pChunk->iColortype;
-  *iImagesampledepth = pChunk->iImagesampledepth;
-  *iImagecompression = pChunk->iImagecompression;
-  *iImageinterlace   = pChunk->iImageinterlace;
-  *iAlphasampledepth = pChunk->iAlphasampledepth;
-  *iAlphacompression = pChunk->iAlphacompression;
-  *iAlphafilter      = pChunk->iAlphafilter;
-  *iAlphainterlace   = pChunk->iAlphainterlace;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_JHDR, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-#endif /* MNG_INCLUDE_JNG */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-
-mng_retcode MNG_DECL mng_getchunk_jdat (mng_handle hHandle,
-                                        mng_handle hChunk,
-                                        mng_uint32 *iRawlen,
-                                        mng_ptr    *pRawdata)
-{
-  mng_datap pData;
-  mng_jdatp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_JDAT, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_jdatp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_JDAT)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *iRawlen  = pChunk->iDatasize;       /* fill the fields */
-  *pRawdata = pChunk->pData;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_JDAT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-#endif /* MNG_INCLUDE_JNG */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-
-mng_retcode MNG_DECL mng_getchunk_jdaa (mng_handle hHandle,
-                                        mng_handle hChunk,
-                                        mng_uint32 *iRawlen,
-                                        mng_ptr    *pRawdata)
-{
-  mng_datap pData;
-  mng_jdaap pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_JDAA, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_jdaap)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_JDAA)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *iRawlen  = pChunk->iDatasize;       /* fill the fields */
-  *pRawdata = pChunk->pData;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_JDAA, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-#endif /* MNG_INCLUDE_JNG */
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-mng_retcode MNG_DECL mng_getchunk_dhdr (mng_handle hHandle,
-                                        mng_handle hChunk,
-                                        mng_uint16 *iObjectid,
-                                        mng_uint8  *iImagetype,
-                                        mng_uint8  *iDeltatype,
-                                        mng_uint32 *iBlockwidth,
-                                        mng_uint32 *iBlockheight,
-                                        mng_uint32 *iBlockx,
-                                        mng_uint32 *iBlocky)
-{
-  mng_datap pData;
-  mng_dhdrp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_DHDR, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_dhdrp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_DHDR)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *iObjectid    = pChunk->iObjectid;   /* fill the fields */
-  *iImagetype   = pChunk->iImagetype;
-  *iDeltatype   = pChunk->iDeltatype;
-  *iBlockwidth  = pChunk->iBlockwidth;
-  *iBlockheight = pChunk->iBlockheight;
-  *iBlockx      = pChunk->iBlockx;
-  *iBlocky      = pChunk->iBlocky;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_DHDR, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-mng_retcode MNG_DECL mng_getchunk_prom (mng_handle hHandle,
-                                        mng_handle hChunk,
-                                        mng_uint8  *iColortype,
-                                        mng_uint8  *iSampledepth,
-                                        mng_uint8  *iFilltype)
-{
-  mng_datap pData;
-  mng_promp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_PROM, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_promp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_PROM)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *iColortype   = pChunk->iColortype;  /* fill the fields */
-  *iSampledepth = pChunk->iSampledepth;
-  *iFilltype    = pChunk->iFilltype;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_PROM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-mng_retcode MNG_DECL mng_getchunk_pplt (mng_handle hHandle,
-                                        mng_handle hChunk,
-                                        mng_uint8  *iDeltatype,
-                                        mng_uint32 *iCount)
-{
-  mng_datap pData;
-  mng_ppltp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_PPLT, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_ppltp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_PPLT)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *iDeltatype = pChunk->iDeltatype;    /* fill the fields */
-  *iCount     = pChunk->iCount;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_PPLT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-mng_retcode MNG_DECL mng_getchunk_pplt_entry (mng_handle hHandle,
-                                              mng_handle hChunk,
-                                              mng_uint32 iEntry,
-                                              mng_uint16 *iRed,
-                                              mng_uint16 *iGreen,
-                                              mng_uint16 *iBlue,
-                                              mng_uint16 *iAlpha,
-                                              mng_bool   *bUsed)
-{
-  mng_datap       pData;
-  mng_ppltp       pChunk;
-  mng_pplt_entryp pEntry;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_PPLT_ENTRY, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_ppltp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_PPLT)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  if (iEntry >= pChunk->iCount)        /* valid index ? */
-    MNG_ERROR (pData, MNG_INVALIDENTRYIX)
-
-  pEntry  = &pChunk->aEntries[iEntry]; /* address the entry */
-
-  *iRed   = pEntry->iRed;              /* fill the fields */
-  *iGreen = pEntry->iGreen;
-  *iBlue  = pEntry->iBlue;
-  *iAlpha = pEntry->iAlpha;
-  *bUsed  = pEntry->bUsed;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_PPLT_ENTRY, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-mng_retcode MNG_DECL mng_getchunk_drop (mng_handle   hHandle,
-                                        mng_handle   hChunk,
-                                        mng_uint32   *iCount,
-                                        mng_chunkidp *pChunknames)
-{
-  mng_datap pData;
-  mng_dropp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_DROP, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_dropp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_DROP)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *iCount      = pChunk->iCount;       /* fill the fields */
-  *pChunknames = pChunk->pChunknames;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_DROP, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_SKIPCHUNK_DBYK
-mng_retcode MNG_DECL mng_getchunk_dbyk (mng_handle  hHandle,
-                                        mng_handle  hChunk,
-                                        mng_chunkid *iChunkname,
-                                        mng_uint8   *iPolarity,
-                                        mng_uint32  *iKeywordssize,
-                                        mng_pchar   *zKeywords)
-{
-  mng_datap pData;
-  mng_dbykp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_DBYK, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_dbykp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_DBYK)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *iChunkname    = pChunk->iChunkname; /* fill the fields */  
-  *iPolarity     = pChunk->iPolarity;
-  *iKeywordssize = pChunk->iKeywordssize;
-  *zKeywords     = pChunk->zKeywords;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_DBYK, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_SKIPCHUNK_ORDR
-mng_retcode MNG_DECL mng_getchunk_ordr (mng_handle hHandle,
-                                        mng_handle hChunk,
-                                        mng_uint32 *iCount)
-{
-  mng_datap pData;
-  mng_ordrp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_ORDR, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_ordrp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_ORDR)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *iCount = pChunk->iCount;            /* fill the field */ 
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_ORDR, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_SKIPCHUNK_ORDR
-mng_retcode MNG_DECL mng_getchunk_ordr_entry (mng_handle  hHandle,
-                                              mng_handle  hChunk,
-                                              mng_uint32  iEntry,
-                                              mng_chunkid *iChunkname,
-                                              mng_uint8   *iOrdertype)
-{
-  mng_datap       pData;
-  mng_ordrp       pChunk;
-  mng_ordr_entryp pEntry;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_ORDR_ENTRY, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_ordrp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_ORDR)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  if (iEntry >= pChunk->iCount)        /* valid index ? */
-    MNG_ERROR (pData, MNG_INVALIDENTRYIX)
-
-  pEntry = pChunk->pEntries + iEntry;  /* address the proper entry */
-
-  *iChunkname = pEntry->iChunkname;    /* fill the fields */
-  *iOrdertype = pEntry->iOrdertype;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_ORDR_ENTRY, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_MAGN
-mng_retcode MNG_DECL mng_getchunk_magn (mng_handle hHandle,
-                                        mng_handle hChunk,
-                                        mng_uint16 *iFirstid,
-                                        mng_uint16 *iLastid,
-                                        mng_uint16 *iMethodX,
-                                        mng_uint16 *iMX,
-                                        mng_uint16 *iMY,
-                                        mng_uint16 *iML,
-                                        mng_uint16 *iMR,
-                                        mng_uint16 *iMT,
-                                        mng_uint16 *iMB,
-                                        mng_uint16 *iMethodY)
-{
-  mng_datap pData;
-  mng_magnp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_MAGN, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_magnp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_MAGN)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *iFirstid = pChunk->iFirstid;        /* fill the fields */
-  *iLastid  = pChunk->iLastid;
-  *iMethodX = (mng_uint16)pChunk->iMethodX;
-  *iMX      = pChunk->iMX;
-  *iMY      = pChunk->iMY;
-  *iML      = pChunk->iML;
-  *iMR      = pChunk->iMR;
-  *iMT      = pChunk->iMT;
-  *iMB      = pChunk->iMB;
-  *iMethodY = (mng_uint16)pChunk->iMethodY;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_MAGN, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_mpng (mng_handle hHandle,
-                                                mng_handle hChunk,
-                                                mng_uint32 *iFramewidth,
-                                                mng_uint32 *iFrameheight,
-                                                mng_uint16 *iNumplays,
-                                                mng_uint16 *iTickspersec,
-                                                mng_uint8  *iCompressionmethod,
-                                                mng_uint32 *iCount)
-{
-  mng_datap pData;
-  mng_mpngp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_MPNG, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_mpngp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_mpNG)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-                                       /* fill the fields */
-  *iFramewidth        = pChunk->iFramewidth;
-  *iFrameheight       = pChunk->iFrameheight;
-  *iNumplays          = pChunk->iNumplays;
-  *iTickspersec       = pChunk->iTickspersec;
-  *iCompressionmethod = pChunk->iCompressionmethod;
-  *iCount             = pChunk->iFramessize / sizeof (mng_mpng_frame);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_MPNG, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-MNG_EXT mng_retcode MNG_DECL mng_getchunk_mpng_frame (mng_handle hHandle,
-                                                      mng_handle hChunk,
-                                                      mng_uint32 iEntry,
-                                                      mng_uint32 *iX,
-                                                      mng_uint32 *iY,
-                                                      mng_uint32 *iWidth,
-                                                      mng_uint32 *iHeight,
-                                                      mng_int32  *iXoffset,
-                                                      mng_int32  *iYoffset,
-                                                      mng_uint16 *iTicks)
-{
-  mng_datap       pData;
-  mng_mpngp       pChunk;
-  mng_mpng_framep pFrame;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_MPNG_FRAME, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_mpngp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_mpNG)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-                                       /* valid index ? */
-  if (iEntry >= (pChunk->iFramessize / sizeof (mng_mpng_frame)))
-    MNG_ERROR (pData, MNG_INVALIDENTRYIX)
-
-  pFrame  = pChunk->pFrames + iEntry;  /* address the entry */
-                                       /* fill the fields */
-  *iX        = pFrame->iX;
-  *iY        = pFrame->iY;
-  *iWidth    = pFrame->iWidth;
-  *iHeight   = pFrame->iHeight;
-  *iXoffset  = pFrame->iXoffset;
-  *iYoffset  = pFrame->iYoffset;
-  *iTicks    = pFrame->iTicks;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_MPNG_FRAME, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_evNT
-mng_retcode MNG_DECL mng_getchunk_evnt (mng_handle hHandle,
-                                        mng_handle hChunk,
-                                        mng_uint32 *iCount)
-{
-  mng_datap pData;
-  mng_evntp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_EVNT, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_evntp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_evNT)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  *iCount = pChunk->iCount;            /* fill the fields */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_EVNT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_getchunk_evnt_entry (mng_handle hHandle,
-                                              mng_handle hChunk,
-                                              mng_uint32 iEntry,
-                                              mng_uint8  *iEventtype,
-                                              mng_uint8  *iMasktype,
-                                              mng_int32  *iLeft,
-                                              mng_int32  *iRight,
-                                              mng_int32  *iTop,
-                                              mng_int32  *iBottom,
-                                              mng_uint16 *iObjectid,
-                                              mng_uint8  *iIndex,
-                                              mng_uint32 *iSegmentnamesize,
-                                              mng_pchar  *zSegmentname)
-{
-  mng_datap       pData;
-  mng_evntp       pChunk;
-  mng_evnt_entryp pEntry;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_EVNT_ENTRY, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_evntp)hChunk;          /* address the chunk */
-
-  if (pChunk->sHeader.iChunkname != MNG_UINT_evNT)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-
-  if (iEntry >= pChunk->iCount)        /* valid index ? */
-    MNG_ERROR (pData, MNG_INVALIDENTRYIX)
-
-  pEntry  = pChunk->pEntries + iEntry; /* address the entry */
-                                       /* fill the fields */
-  *iEventtype       = pEntry->iEventtype;
-  *iMasktype        = pEntry->iMasktype;
-  *iLeft            = pEntry->iLeft;    
-  *iRight           = pEntry->iRight;
-  *iTop             = pEntry->iTop;
-  *iBottom          = pEntry->iBottom;
-  *iObjectid        = pEntry->iObjectid;
-  *iIndex           = pEntry->iIndex;
-  *iSegmentnamesize = pEntry->iSegmentnamesize;
-  *zSegmentname     = pEntry->zSegmentname;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_EVNT_ENTRY, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_getchunk_unknown (mng_handle  hHandle,
-                                           mng_handle  hChunk,
-                                           mng_chunkid *iChunkname,
-                                           mng_uint32  *iRawlen,
-                                           mng_ptr     *pRawdata)
-{
-  mng_datap          pData;
-  mng_unknown_chunkp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_UNKNOWN, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData  = (mng_datap)hHandle;         /* and make it addressable */
-  pChunk = (mng_unknown_chunkp)hChunk; /* address the chunk */
-
-  if (pChunk->sHeader.fCleanup != mng_free_unknown)
-    MNG_ERROR (pData, MNG_WRONGCHUNK)  /* ouch */
-                                       /* fill the fields */
-  *iChunkname = pChunk->sHeader.iChunkname;
-  *iRawlen    = pChunk->iDatasize;
-  *pRawdata   = pChunk->pData;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_UNKNOWN, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_WRITE_PROCS
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_TERM
-MNG_LOCAL mng_bool check_term (mng_datap   pData,
-                               mng_chunkid iChunkname)
-{
-  mng_chunk_headerp pChunk = (mng_chunk_headerp)pData->pLastchunk;
-
-  if (!pChunk)                         /* nothing added yet ? */
-    return MNG_TRUE;
-                                       /* last added chunk is TERM ? */
-  if (pChunk->iChunkname != MNG_UINT_TERM)
-    return MNG_TRUE;
-                                       /* previous to last is MHDR ? */
-  if ((pChunk->pPrev) && (((mng_chunk_headerp)pChunk->pPrev)->iChunkname == MNG_UINT_MHDR))
-    return MNG_TRUE;
-
-  if (iChunkname == MNG_UINT_SEEK)     /* new chunk to be added is SEEK ? */
-    return MNG_TRUE;
-
-  return MNG_FALSE;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_putchunk_ihdr (mng_handle hHandle,
-                                        mng_uint32 iWidth,
-                                        mng_uint32 iHeight,
-                                        mng_uint8  iBitdepth,
-                                        mng_uint8  iColortype,
-                                        mng_uint8  iCompression,
-                                        mng_uint8  iFilter,
-                                        mng_uint8  iInterlace)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_IHDR, mng_init_general, mng_free_general, mng_read_ihdr, mng_write_ihdr, mng_assign_general, 0, 0, sizeof(mng_ihdr)};
-#else
-          {MNG_UINT_IHDR, mng_init_ihdr, mng_free_ihdr, mng_read_ihdr, mng_write_ihdr, mng_assign_ihdr, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_IHDR, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_IHDR))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_ihdr (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_IHDR, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-  ((mng_ihdrp)pChunk)->iWidth       = iWidth;
-  ((mng_ihdrp)pChunk)->iHeight      = iHeight;
-  ((mng_ihdrp)pChunk)->iBitdepth    = iBitdepth;
-  ((mng_ihdrp)pChunk)->iColortype   = iColortype;
-  ((mng_ihdrp)pChunk)->iCompression = iCompression;
-  ((mng_ihdrp)pChunk)->iFilter      = iFilter;
-  ((mng_ihdrp)pChunk)->iInterlace   = iInterlace;
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_IHDR, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_putchunk_plte (mng_handle   hHandle,
-                                        mng_uint32   iCount,
-                                        mng_palette8 aPalette)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_PLTE, mng_init_general, mng_free_general, mng_read_plte, mng_write_plte, mng_assign_general, 0, 0, sizeof(mng_plte)};
-#else
-          {MNG_UINT_PLTE, mng_init_plte, mng_free_plte, mng_read_plte, mng_write_plte, mng_assign_plte, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_PLTE, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a header first! */
-  if (pData->iFirstchunkadded == 0)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_PLTE))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_plte (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_PLTE, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_pltep)pChunk)->iEntrycount = iCount;
-  ((mng_pltep)pChunk)->bEmpty      = (mng_bool)(iCount == 0);
-
-  MNG_COPY (((mng_pltep)pChunk)->aEntries, aPalette, sizeof (mng_palette8));
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_PLTE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_putchunk_idat (mng_handle hHandle,
-                                        mng_uint32 iRawlen,
-                                        mng_ptr    pRawdata)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_IDAT, mng_init_general, mng_free_idat, mng_read_idat, mng_write_idat, mng_assign_idat, 0, 0, sizeof(mng_idat)};
-#else
-          {MNG_UINT_IDAT, mng_init_idat, mng_free_idat, mng_read_idat, mng_write_idat, mng_assign_idat, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_IDAT, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a header first! */
-  if (pData->iFirstchunkadded == 0)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_IDAT))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_idat (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_IDAT, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_idatp)pChunk)->bEmpty    = (mng_bool)(iRawlen == 0);
-  ((mng_idatp)pChunk)->iDatasize = iRawlen;
-
-  if (iRawlen)
-  {
-    MNG_ALLOC (pData, ((mng_idatp)pChunk)->pData, iRawlen);
-    MNG_COPY (((mng_idatp)pChunk)->pData, pRawdata, iRawlen);
-  }
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_IDAT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_putchunk_iend (mng_handle hHandle)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_IEND, mng_init_general, mng_free_general, mng_read_iend, mng_write_iend, mng_assign_general, 0, 0, sizeof(mng_iend)};
-#else
-          {MNG_UINT_IEND, mng_init_iend, mng_free_iend, mng_read_iend, mng_write_iend, mng_assign_iend, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_IEND, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a header first! */
-  if (pData->iFirstchunkadded == 0)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_IEND))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_iend (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_IEND, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pData->iFirstchunkadded == MNG_UINT_IHDR) ||
-      (pData->iFirstchunkadded == MNG_UINT_JHDR)    )
-#else
-  if (pData->iFirstchunkadded == MNG_UINT_IHDR)
-#endif
-    pData->bCreating = MNG_FALSE;      /* should be last chunk !!! */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_IEND, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_putchunk_trns (mng_handle   hHandle,
-                                        mng_bool     bEmpty,
-                                        mng_bool     bGlobal,
-                                        mng_uint8    iType,
-                                        mng_uint32   iCount,
-                                        mng_uint8arr aAlphas,
-                                        mng_uint16   iGray,
-                                        mng_uint16   iRed,
-                                        mng_uint16   iGreen,
-                                        mng_uint16   iBlue,
-                                        mng_uint32   iRawlen,
-                                        mng_uint8arr aRawdata)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_tRNS, mng_init_general, mng_free_general, mng_read_trns, mng_write_trns, mng_assign_general, 0, 0, sizeof(mng_trns)};
-#else
-          {MNG_UINT_tRNS, mng_init_trns, mng_free_trns, mng_read_trns, mng_write_trns, mng_assign_trns, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_TRNS, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a header first! */
-  if (pData->iFirstchunkadded == 0)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_tRNS))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_trns (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_tRNS, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_trnsp)pChunk)->bEmpty   = bEmpty;
-  ((mng_trnsp)pChunk)->bGlobal  = bGlobal;
-  ((mng_trnsp)pChunk)->iType    = iType;
-  ((mng_trnsp)pChunk)->iCount   = iCount;
-  ((mng_trnsp)pChunk)->iGray    = iGray;
-  ((mng_trnsp)pChunk)->iRed     = iRed;
-  ((mng_trnsp)pChunk)->iGreen   = iGreen;
-  ((mng_trnsp)pChunk)->iBlue    = iBlue;
-  ((mng_trnsp)pChunk)->iRawlen  = iRawlen;
-
-  MNG_COPY (((mng_trnsp)pChunk)->aEntries, aAlphas,  sizeof (mng_uint8arr));
-  MNG_COPY (((mng_trnsp)pChunk)->aRawdata, aRawdata, sizeof (mng_uint8arr));
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_TRNS, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_gAMA
-mng_retcode MNG_DECL mng_putchunk_gama (mng_handle hHandle,
-                                        mng_bool   bEmpty,
-                                        mng_uint32 iGamma)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_gAMA, mng_init_general, mng_free_general, mng_read_gama, mng_write_gama, mng_assign_general, 0, 0, sizeof(mng_gama)};
-#else
-          {MNG_UINT_gAMA, mng_init_gama, mng_free_gama, mng_read_gama, mng_write_gama, mng_assign_gama, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_GAMA, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a header first! */
-  if (pData->iFirstchunkadded == 0)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_gAMA))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_gama (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_gAMA, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_gamap)pChunk)->bEmpty = bEmpty;
-  ((mng_gamap)pChunk)->iGamma = iGamma;
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_GAMA, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_cHRM
-mng_retcode MNG_DECL mng_putchunk_chrm (mng_handle hHandle,
-                                        mng_bool   bEmpty,
-                                        mng_uint32 iWhitepointx,
-                                        mng_uint32 iWhitepointy,
-                                        mng_uint32 iRedx,
-                                        mng_uint32 iRedy,
-                                        mng_uint32 iGreenx,
-                                        mng_uint32 iGreeny,
-                                        mng_uint32 iBluex,
-                                        mng_uint32 iBluey)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_cHRM, mng_init_general, mng_free_general, mng_read_chrm, mng_write_chrm, mng_assign_general, 0, 0, sizeof(mng_chrm)};
-#else
-          {MNG_UINT_cHRM, mng_init_chrm, mng_free_chrm, mng_read_chrm, mng_write_chrm, mng_assign_chrm, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_CHRM, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a header first! */
-  if (pData->iFirstchunkadded == 0)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_cHRM))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_chrm (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_cHRM, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_chrmp)pChunk)->bEmpty       = bEmpty;
-  ((mng_chrmp)pChunk)->iWhitepointx = iWhitepointx;
-  ((mng_chrmp)pChunk)->iWhitepointy = iWhitepointy;
-  ((mng_chrmp)pChunk)->iRedx        = iRedx;
-  ((mng_chrmp)pChunk)->iRedy        = iRedy;
-  ((mng_chrmp)pChunk)->iGreenx      = iGreenx;
-  ((mng_chrmp)pChunk)->iGreeny      = iGreeny;
-  ((mng_chrmp)pChunk)->iBluex       = iBluex;
-  ((mng_chrmp)pChunk)->iBluey       = iBluey;
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_CHRM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_sRGB
-mng_retcode MNG_DECL mng_putchunk_srgb (mng_handle hHandle,
-                                        mng_bool   bEmpty,
-                                        mng_uint8  iRenderingintent)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_sRGB, mng_init_general, mng_free_general, mng_read_srgb, mng_write_srgb, mng_assign_general, 0, 0, sizeof(mng_srgb)};
-#else
-          {MNG_UINT_sRGB, mng_init_srgb, mng_free_srgb, mng_read_srgb, mng_write_srgb, mng_assign_srgb, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_SRGB, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a header first! */
-  if (pData->iFirstchunkadded == 0)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_sRGB))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_srgb (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_sRGB, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_srgbp)pChunk)->bEmpty           = bEmpty;
-  ((mng_srgbp)pChunk)->iRenderingintent = iRenderingintent;
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_SRGB, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_iCCP
-mng_retcode MNG_DECL mng_putchunk_iccp (mng_handle hHandle,
-                                        mng_bool   bEmpty,
-                                        mng_uint32 iNamesize,
-                                        mng_pchar  zName,
-                                        mng_uint8  iCompression,
-                                        mng_uint32 iProfilesize,
-                                        mng_ptr    pProfile)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_iCCP, mng_init_general, mng_free_iccp, mng_read_iccp, mng_write_iccp, mng_assign_iccp, 0, 0, sizeof(mng_iccp)};
-#else
-          {MNG_UINT_iCCP, mng_init_iccp, mng_free_iccp, mng_read_iccp, mng_write_iccp, mng_assign_iccp, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_ICCP, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a header first! */
-  if (pData->iFirstchunkadded == 0)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_iCCP))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_iccp (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_iCCP, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_iccpp)pChunk)->bEmpty       = bEmpty;
-  ((mng_iccpp)pChunk)->iNamesize    = iNamesize;
-  ((mng_iccpp)pChunk)->iCompression = iCompression;
-  ((mng_iccpp)pChunk)->iProfilesize = iProfilesize;
-
-  if (iNamesize)
-  {
-    MNG_ALLOC (pData, ((mng_iccpp)pChunk)->zName, iNamesize + 1);
-    MNG_COPY (((mng_iccpp)pChunk)->zName, zName, iNamesize);
-  }
-
-  if (iProfilesize)
-  {
-    MNG_ALLOC (pData, ((mng_iccpp)pChunk)->pProfile, iProfilesize);
-    MNG_COPY (((mng_iccpp)pChunk)->pProfile, pProfile, iProfilesize);
-  }
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_ICCP, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_tEXt
-mng_retcode MNG_DECL mng_putchunk_text (mng_handle hHandle,
-                                        mng_uint32 iKeywordsize,
-                                        mng_pchar  zKeyword,
-                                        mng_uint32 iTextsize,
-                                        mng_pchar  zText)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_tEXt, mng_init_general, mng_free_text, mng_read_text, mng_write_text, mng_assign_text, 0, 0, sizeof(mng_text)};
-#else
-          {MNG_UINT_tEXt, mng_init_text, mng_free_text, mng_read_text, mng_write_text, mng_assign_text, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_TEXT, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a header first! */
-  if (pData->iFirstchunkadded == 0)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_tEXt))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_text (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_tEXt, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_textp)pChunk)->iKeywordsize = iKeywordsize;
-  ((mng_textp)pChunk)->iTextsize    = iTextsize;
-
-  if (iKeywordsize)
-  {
-    MNG_ALLOC (pData, ((mng_textp)pChunk)->zKeyword, iKeywordsize + 1);
-    MNG_COPY (((mng_textp)pChunk)->zKeyword, zKeyword, iKeywordsize);
-  }
-
-  if (iTextsize)
-  {
-    MNG_ALLOC (pData, ((mng_textp)pChunk)->zText, iTextsize + 1);
-    MNG_COPY (((mng_textp)pChunk)->zText, zText, iTextsize);
-  }
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_TEXT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_zTXt
-mng_retcode MNG_DECL mng_putchunk_ztxt (mng_handle hHandle,
-                                        mng_uint32 iKeywordsize,
-                                        mng_pchar  zKeyword,
-                                        mng_uint8  iCompression,
-                                        mng_uint32 iTextsize,
-                                        mng_pchar  zText)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_zTXt, mng_init_general, mng_free_ztxt, mng_read_ztxt, mng_write_ztxt, mng_assign_ztxt, 0, 0, sizeof(mng_ztxt)};
-#else
-          {MNG_UINT_zTXt, mng_init_ztxt, mng_free_ztxt, mng_read_ztxt, mng_write_ztxt, mng_assign_ztxt, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_ZTXT, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a header first! */
-  if (pData->iFirstchunkadded == 0)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_zTXt))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_ztxt (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_zTXt, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_ztxtp)pChunk)->iKeywordsize = iKeywordsize;
-  ((mng_ztxtp)pChunk)->iCompression = iCompression;
-  ((mng_ztxtp)pChunk)->iTextsize    = iTextsize;
-
-  if (iKeywordsize)
-  {
-    MNG_ALLOC (pData, ((mng_ztxtp)pChunk)->zKeyword, iKeywordsize + 1);
-    MNG_COPY (((mng_ztxtp)pChunk)->zKeyword, zKeyword, iKeywordsize);
-  }
-
-  if (iTextsize)
-  {
-    MNG_ALLOC (pData, ((mng_ztxtp)pChunk)->zText, iTextsize + 1);
-    MNG_COPY  (((mng_ztxtp)pChunk)->zText, zText, iTextsize);
-  }
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_ZTXT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_iTXt
-mng_retcode MNG_DECL mng_putchunk_itxt (mng_handle hHandle,
-                                        mng_uint32 iKeywordsize,
-                                        mng_pchar  zKeyword,
-                                        mng_uint8  iCompressionflag,
-                                        mng_uint8  iCompressionmethod,
-                                        mng_uint32 iLanguagesize,
-                                        mng_pchar  zLanguage,
-                                        mng_uint32 iTranslationsize,
-                                        mng_pchar  zTranslation,
-                                        mng_uint32 iTextsize,
-                                        mng_pchar  zText)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_iTXt, mng_init_general, mng_free_itxt, mng_read_itxt, mng_write_itxt, mng_assign_itxt, 0, 0, sizeof(mng_itxt)};
-#else
-          {MNG_UINT_iTXt, mng_init_itxt, mng_free_itxt, mng_read_itxt, mng_write_itxt, mng_assign_itxt, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_ITXT, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a header first! */
-  if (pData->iFirstchunkadded == 0)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_iTXt))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_itxt (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_iTXt, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_itxtp)pChunk)->iKeywordsize       = iKeywordsize;
-  ((mng_itxtp)pChunk)->iCompressionflag   = iCompressionflag;
-  ((mng_itxtp)pChunk)->iCompressionmethod = iCompressionmethod;
-  ((mng_itxtp)pChunk)->iLanguagesize      = iLanguagesize;
-  ((mng_itxtp)pChunk)->iTranslationsize   = iTranslationsize;
-  ((mng_itxtp)pChunk)->iTextsize          = iTextsize;
-
-  if (iKeywordsize)
-  {
-    MNG_ALLOC (pData, ((mng_itxtp)pChunk)->zKeyword, iKeywordsize + 1);
-    MNG_COPY (((mng_itxtp)pChunk)->zKeyword, zKeyword, iKeywordsize);
-  }
-
-  if (iLanguagesize)
-  {
-    MNG_ALLOC (pData, ((mng_itxtp)pChunk)->zLanguage, iLanguagesize + 1);
-    MNG_COPY (((mng_itxtp)pChunk)->zLanguage, zLanguage, iLanguagesize);
-  }
-
-  if (iTranslationsize)
-  {
-    MNG_ALLOC (pData, ((mng_itxtp)pChunk)->zTranslation, iTranslationsize + 1);
-    MNG_COPY (((mng_itxtp)pChunk)->zTranslation, zTranslation, iTranslationsize);
-  }
-
-  if (iTextsize)
-  {
-    MNG_ALLOC (pData, ((mng_itxtp)pChunk)->zText, iTextsize + 1);
-    MNG_COPY (((mng_itxtp)pChunk)->zText, zText, iTextsize);
-  }
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_ITXT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_bKGD
-mng_retcode MNG_DECL mng_putchunk_bkgd (mng_handle hHandle,
-                                        mng_bool   bEmpty,
-                                        mng_uint8  iType,
-                                        mng_uint8  iIndex,
-                                        mng_uint16 iGray,
-                                        mng_uint16 iRed,
-                                        mng_uint16 iGreen,
-                                        mng_uint16 iBlue)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_bKGD, mng_init_general, mng_free_general, mng_read_bkgd, mng_write_bkgd, mng_assign_general, 0, 0, sizeof(mng_bkgd)};
-#else
-          {MNG_UINT_bKGD, mng_init_bkgd, mng_free_bkgd, mng_read_bkgd, mng_write_bkgd, mng_assign_bkgd, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_BKGD, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a header first! */
-  if (pData->iFirstchunkadded == 0)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_bKGD))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_bkgd (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_bKGD, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_bkgdp)pChunk)->bEmpty = bEmpty;
-  ((mng_bkgdp)pChunk)->iType  = iType;
-  ((mng_bkgdp)pChunk)->iIndex = iIndex;
-  ((mng_bkgdp)pChunk)->iGray  = iGray;
-  ((mng_bkgdp)pChunk)->iRed   = iRed;
-  ((mng_bkgdp)pChunk)->iGreen = iGreen;
-  ((mng_bkgdp)pChunk)->iBlue  = iBlue;
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_BKGD, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_pHYs
-mng_retcode MNG_DECL mng_putchunk_phys (mng_handle hHandle,
-                                        mng_bool   bEmpty,
-                                        mng_uint32 iSizex,
-                                        mng_uint32 iSizey,
-                                        mng_uint8  iUnit)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_pHYs, mng_init_general, mng_free_general, mng_read_phys, mng_write_phys, mng_assign_general, 0, 0, sizeof(mng_phys)};
-#else
-          {MNG_UINT_pHYs, mng_init_phys, mng_free_phys, mng_read_phys, mng_write_phys, mng_assign_phys, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_PHYS, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a header first! */
-  if (pData->iFirstchunkadded == 0)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_pHYs))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_phys (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_pHYs, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_physp)pChunk)->bEmpty = bEmpty;
-  ((mng_physp)pChunk)->iSizex = iSizex;
-  ((mng_physp)pChunk)->iSizey = iSizey;
-  ((mng_physp)pChunk)->iUnit  = iUnit;
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_PHYS, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_sBIT
-mng_retcode MNG_DECL mng_putchunk_sbit (mng_handle    hHandle,
-                                        mng_bool      bEmpty,
-                                        mng_uint8     iType,
-                                        mng_uint8arr4 aBits)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_sBIT, mng_init_general, mng_free_general, mng_read_sbit, mng_write_sbit, mng_assign_general, 0, 0, sizeof(mng_sbit)};
-#else
-          {MNG_UINT_sBIT, mng_init_sbit, mng_free_sbit, mng_read_sbit, mng_write_sbit, mng_assign_sbit, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_SBIT, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a header first! */
-  if (pData->iFirstchunkadded == 0)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_sBIT))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_sbit (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_sBIT, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_sbitp)pChunk)->bEmpty   = bEmpty;
-  ((mng_sbitp)pChunk)->iType    = iType;
-  ((mng_sbitp)pChunk)->aBits[0] = aBits[0];
-  ((mng_sbitp)pChunk)->aBits[1] = aBits[1];
-  ((mng_sbitp)pChunk)->aBits[2] = aBits[2];
-  ((mng_sbitp)pChunk)->aBits[3] = aBits[3];
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_SBIT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_sPLT
-mng_retcode MNG_DECL mng_putchunk_splt (mng_handle hHandle,
-                                        mng_bool   bEmpty,
-                                        mng_uint32 iNamesize,
-                                        mng_pchar  zName,
-                                        mng_uint8  iSampledepth,
-                                        mng_uint32 iEntrycount,
-                                        mng_ptr    pEntries)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_sPLT, mng_init_general, mng_free_splt, mng_read_splt, mng_write_splt, mng_assign_splt, 0, 0, sizeof(mng_splt)};
-#else
-          {MNG_UINT_sPLT, mng_init_splt, mng_free_splt, mng_read_splt, mng_write_splt, mng_assign_splt, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_SPLT, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a header first! */
-  if (pData->iFirstchunkadded == 0)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_sPLT))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_splt (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_sPLT, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_spltp)pChunk)->bEmpty       = bEmpty;
-  ((mng_spltp)pChunk)->iNamesize    = iNamesize;
-  ((mng_spltp)pChunk)->iSampledepth = iSampledepth;
-  ((mng_spltp)pChunk)->iEntrycount  = iEntrycount;
-
-  if (iNamesize)
-  {
-    MNG_ALLOC (pData, ((mng_spltp)pChunk)->zName, iNamesize + 1);
-    MNG_COPY (((mng_spltp)pChunk)->zName, zName, iNamesize);
-  }
-
-  if (iEntrycount)
-  {
-    mng_uint32 iSize = iEntrycount * ((iSampledepth >> 1) + 2);
-
-    MNG_ALLOC (pData, ((mng_spltp)pChunk)->pEntries, iSize);
-    MNG_COPY  (((mng_spltp)pChunk)->pEntries, pEntries, iSize);
-  }
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_SPLT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_hIST
-mng_retcode MNG_DECL mng_putchunk_hist (mng_handle    hHandle,
-                                        mng_uint32    iEntrycount,
-                                        mng_uint16arr aEntries)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_hIST, mng_init_general, mng_free_general, mng_read_hist, mng_write_hist, mng_assign_general, 0, 0, sizeof(mng_hist)};
-#else
-          {MNG_UINT_hIST, mng_init_hist, mng_free_hist, mng_read_hist, mng_write_hist, mng_assign_hist, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_HIST, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a header first! */
-  if (pData->iFirstchunkadded == 0)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_hIST))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_hist (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_hIST, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_histp)pChunk)->iEntrycount = iEntrycount;
-
-  MNG_COPY (((mng_histp)pChunk)->aEntries, aEntries, sizeof (mng_uint16arr));
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_HIST, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_tIME
-mng_retcode MNG_DECL mng_putchunk_time (mng_handle hHandle,
-                                        mng_uint16 iYear,
-                                        mng_uint8  iMonth,
-                                        mng_uint8  iDay,
-                                        mng_uint8  iHour,
-                                        mng_uint8  iMinute,
-                                        mng_uint8  iSecond)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_tIME, mng_init_general, mng_free_general, mng_read_time, mng_write_time, mng_assign_general, 0, 0, sizeof(mng_time)};
-#else
-          {MNG_UINT_tIME, mng_init_time, mng_free_time, mng_read_time, mng_write_time, mng_assign_time, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_TIME, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_tIME))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* must have had a header first! */
-  if (pData->iFirstchunkadded == 0)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_time (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_tIME, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_timep)pChunk)->iYear   = iYear;
-  ((mng_timep)pChunk)->iMonth  = iMonth;
-  ((mng_timep)pChunk)->iDay    = iDay;
-  ((mng_timep)pChunk)->iHour   = iHour;
-  ((mng_timep)pChunk)->iMinute = iMinute;
-  ((mng_timep)pChunk)->iSecond = iSecond;
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_TIME, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_putchunk_mhdr (mng_handle hHandle,
-                                        mng_uint32 iWidth,
-                                        mng_uint32 iHeight,
-                                        mng_uint32 iTicks,
-                                        mng_uint32 iLayercount,
-                                        mng_uint32 iFramecount,
-                                        mng_uint32 iPlaytime,
-                                        mng_uint32 iSimplicity)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_MHDR, mng_init_general, mng_free_general, mng_read_mhdr, mng_write_mhdr, mng_assign_general, 0, 0, sizeof(mng_mhdr)};
-#else
-          {MNG_UINT_MHDR, mng_init_mhdr, mng_free_mhdr, mng_read_mhdr, mng_write_mhdr, mng_assign_mhdr, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_MHDR, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must be very first! */
-  if (pData->iFirstchunkadded != 0)
-    MNG_ERROR (pData, MNG_SEQUENCEERROR)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_MHDR))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_mhdr (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_MHDR, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_mhdrp)pChunk)->iWidth      = iWidth;
-  ((mng_mhdrp)pChunk)->iHeight     = iHeight;
-  ((mng_mhdrp)pChunk)->iTicks      = iTicks;
-  ((mng_mhdrp)pChunk)->iLayercount = iLayercount;
-  ((mng_mhdrp)pChunk)->iFramecount = iFramecount;
-  ((mng_mhdrp)pChunk)->iPlaytime   = iPlaytime;
-  ((mng_mhdrp)pChunk)->iSimplicity = iSimplicity;
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_MHDR, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_putchunk_mend (mng_handle hHandle)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_MEND, mng_init_general, mng_free_general, mng_read_mend, mng_write_mend, mng_assign_general, 0, 0, sizeof(mng_mend)};
-#else
-          {MNG_UINT_MEND, mng_init_mend, mng_free_mend, mng_read_mend, mng_write_mend, mng_assign_mend, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_MEND, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a header first! */
-  if (pData->iFirstchunkadded == 0)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_MEND))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_mend (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_MEND, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-  pData->bCreating = MNG_FALSE;        /* should be last chunk !!! */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_MEND, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_LOOP
-mng_retcode MNG_DECL mng_putchunk_loop (mng_handle  hHandle,
-                                        mng_uint8   iLevel,
-                                        mng_uint32  iRepeat,
-                                        mng_uint8   iTermination,
-                                        mng_uint32  iItermin,
-                                        mng_uint32  iItermax,
-                                        mng_uint32  iCount,
-                                        mng_uint32p pSignals)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_LOOP, mng_init_general, mng_free_loop, mng_read_loop, mng_write_loop, mng_assign_loop, 0, 0, sizeof(mng_loop)};
-#else
-          {MNG_UINT_LOOP, mng_init_loop, mng_free_loop, mng_read_loop, mng_write_loop, mng_assign_loop, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_LOOP, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a MHDR first! */
-  if (pData->iFirstchunkadded != MNG_UINT_MHDR)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_LOOP))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_loop (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_LOOP, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_loopp)pChunk)->iLevel       = iLevel;
-  ((mng_loopp)pChunk)->iRepeat      = iRepeat;
-  ((mng_loopp)pChunk)->iTermination = iTermination;
-  ((mng_loopp)pChunk)->iItermin     = iItermin;
-  ((mng_loopp)pChunk)->iItermax     = iItermax;
-  ((mng_loopp)pChunk)->iCount       = iCount;
-  ((mng_loopp)pChunk)->pSignals     = pSignals;
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_LOOP, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_putchunk_endl (mng_handle hHandle,
-                                        mng_uint8  iLevel)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_ENDL, mng_init_general, mng_free_general, mng_read_endl, mng_write_endl, mng_assign_general, 0, 0, sizeof(mng_endl)};
-#else
-          {MNG_UINT_ENDL, mng_init_endl, mng_free_endl, mng_read_endl, mng_write_endl, mng_assign_endl, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_ENDL, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a MHDR first! */
-  if (pData->iFirstchunkadded != MNG_UINT_MHDR)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_ENDL))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_endl (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_ENDL, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_endlp)pChunk)->iLevel = iLevel;
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_ENDL, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_DEFI
-mng_retcode MNG_DECL mng_putchunk_defi (mng_handle hHandle,
-                                        mng_uint16 iObjectid,
-                                        mng_uint8  iDonotshow,
-                                        mng_uint8  iConcrete,
-                                        mng_bool   bHasloca,
-                                        mng_int32  iXlocation,
-                                        mng_int32  iYlocation,
-                                        mng_bool   bHasclip,
-                                        mng_int32  iLeftcb,
-                                        mng_int32  iRightcb,
-                                        mng_int32  iTopcb,
-                                        mng_int32  iBottomcb)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_DEFI, mng_init_general, mng_free_general, mng_read_defi, mng_write_defi, mng_assign_general, 0, 0, sizeof(mng_defi)};
-#else
-          {MNG_UINT_DEFI, mng_init_defi, mng_free_defi, mng_read_defi, mng_write_defi, mng_assign_defi, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_DEFI, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a MHDR first! */
-  if (pData->iFirstchunkadded != MNG_UINT_MHDR)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_DEFI))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_defi (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_DEFI, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_defip)pChunk)->iObjectid  = iObjectid;
-  ((mng_defip)pChunk)->iDonotshow = iDonotshow;
-  ((mng_defip)pChunk)->iConcrete  = iConcrete;
-  ((mng_defip)pChunk)->bHasloca   = bHasloca;
-  ((mng_defip)pChunk)->iXlocation = iXlocation;
-  ((mng_defip)pChunk)->iYlocation = iYlocation;
-  ((mng_defip)pChunk)->bHasclip   = bHasclip;
-  ((mng_defip)pChunk)->iLeftcb    = iLeftcb;
-  ((mng_defip)pChunk)->iRightcb   = iRightcb;
-  ((mng_defip)pChunk)->iTopcb     = iTopcb;
-  ((mng_defip)pChunk)->iBottomcb  = iBottomcb;
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_DEFI, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_BASI
-mng_retcode MNG_DECL mng_putchunk_basi (mng_handle hHandle,
-                                        mng_uint32 iWidth,
-                                        mng_uint32 iHeight,
-                                        mng_uint8  iBitdepth,
-                                        mng_uint8  iColortype,
-                                        mng_uint8  iCompression,
-                                        mng_uint8  iFilter,
-                                        mng_uint8  iInterlace,
-                                        mng_uint16 iRed,
-                                        mng_uint16 iGreen,
-                                        mng_uint16 iBlue,
-                                        mng_uint16 iAlpha,
-                                        mng_uint8  iViewable)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_BASI, mng_init_general, mng_free_general, mng_read_basi, mng_write_basi, mng_assign_general, 0, 0, sizeof(mng_basi)};
-#else
-          {MNG_UINT_BASI, mng_init_basi, mng_free_basi, mng_read_basi, mng_write_basi, mng_assign_basi, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_BASI, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a MHDR first! */
-  if (pData->iFirstchunkadded != MNG_UINT_MHDR)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_BASI))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_basi (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_BASI, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_basip)pChunk)->iWidth       = iWidth;
-  ((mng_basip)pChunk)->iHeight      = iHeight;
-  ((mng_basip)pChunk)->iBitdepth    = iBitdepth;
-  ((mng_basip)pChunk)->iColortype   = iColortype;
-  ((mng_basip)pChunk)->iCompression = iCompression;
-  ((mng_basip)pChunk)->iFilter      = iFilter;
-  ((mng_basip)pChunk)->iInterlace   = iInterlace;
-  ((mng_basip)pChunk)->iRed         = iRed;
-  ((mng_basip)pChunk)->iGreen       = iGreen;
-  ((mng_basip)pChunk)->iBlue        = iBlue;
-  ((mng_basip)pChunk)->iAlpha       = iAlpha;
-  ((mng_basip)pChunk)->iViewable    = iViewable;
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_BASI, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_CLON
-mng_retcode MNG_DECL mng_putchunk_clon (mng_handle hHandle,
-                                        mng_uint16 iSourceid,
-                                        mng_uint16 iCloneid,
-                                        mng_uint8  iClonetype,
-                                        mng_uint8  iDonotshow,
-                                        mng_uint8  iConcrete,
-                                        mng_bool   bHasloca,
-                                        mng_uint8  iLocationtype,
-                                        mng_int32  iLocationx,
-                                        mng_int32  iLocationy)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_CLON, mng_init_general, mng_free_general, mng_read_clon, mng_write_clon, mng_assign_general, 0, 0, sizeof(mng_clon)};
-#else
-          {MNG_UINT_CLON, mng_init_clon, mng_free_clon, mng_read_clon, mng_write_clon, mng_assign_clon, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_CLON, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a MHDR first! */
-  if (pData->iFirstchunkadded != MNG_UINT_MHDR)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_CLON))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_clon (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_CLON, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_clonp)pChunk)->iSourceid     = iSourceid;
-  ((mng_clonp)pChunk)->iCloneid      = iCloneid;
-  ((mng_clonp)pChunk)->iClonetype    = iClonetype;
-  ((mng_clonp)pChunk)->iDonotshow    = iDonotshow;
-  ((mng_clonp)pChunk)->iConcrete     = iConcrete;
-  ((mng_clonp)pChunk)->bHasloca      = bHasloca;
-  ((mng_clonp)pChunk)->iLocationtype = iLocationtype;
-  ((mng_clonp)pChunk)->iLocationx    = iLocationx;
-  ((mng_clonp)pChunk)->iLocationy    = iLocationy;
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_CLON, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_PAST
-mng_retcode MNG_DECL mng_putchunk_past (mng_handle hHandle,
-                                        mng_uint16 iDestid,
-                                        mng_uint8  iTargettype,
-                                        mng_int32  iTargetx,
-                                        mng_int32  iTargety,
-                                        mng_uint32 iCount)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_PAST, mng_init_general, mng_free_past, mng_read_past, mng_write_past, mng_assign_past, 0, 0, sizeof(mng_past)};
-#else
-          {MNG_UINT_PAST, mng_init_past, mng_free_past, mng_read_past, mng_write_past, mng_assign_past, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_PAST, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a MHDR first! */
-  if (pData->iFirstchunkadded != MNG_UINT_MHDR)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_PAST))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_past (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_PAST, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_pastp)pChunk)->iDestid     = iDestid;
-  ((mng_pastp)pChunk)->iTargettype = iTargettype;
-  ((mng_pastp)pChunk)->iTargetx    = iTargetx;
-  ((mng_pastp)pChunk)->iTargety    = iTargety;
-  ((mng_pastp)pChunk)->iCount      = iCount;
-
-  if (iCount)
-    MNG_ALLOC (pData, ((mng_pastp)pChunk)->pSources, iCount * sizeof (mng_past_source));
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_PAST, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_PAST
-mng_retcode MNG_DECL mng_putchunk_past_src (mng_handle hHandle,
-                                            mng_uint32 iEntry,
-                                            mng_uint16 iSourceid,
-                                            mng_uint8  iComposition,
-                                            mng_uint8  iOrientation,
-                                            mng_uint8  iOffsettype,
-                                            mng_int32  iOffsetx,
-                                            mng_int32  iOffsety,
-                                            mng_uint8  iBoundarytype,
-                                            mng_int32  iBoundaryl,
-                                            mng_int32  iBoundaryr,
-                                            mng_int32  iBoundaryt,
-                                            mng_int32  iBoundaryb)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_past_sourcep pEntry;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_PAST_SRC, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a MHDR first! */
-  if (pData->iFirstchunkadded != MNG_UINT_MHDR)
-    MNG_ERROR (pData, MNG_NOHEADER)
-
-  pChunk = pData->pLastchunk;          /* last one must have been PAST ! */
-
-  if (((mng_chunk_headerp)pChunk)->iChunkname != MNG_UINT_PAST)
-    MNG_ERROR (pData, MNG_NOCORRCHUNK)
-                                       /* index out of bounds ? */
-  if (iEntry >= ((mng_pastp)pChunk)->iCount)
-    MNG_ERROR (pData, MNG_INVALIDENTRYIX)
-                                       /* address proper entry */
-  pEntry = ((mng_pastp)pChunk)->pSources + iEntry;
-
-  pEntry->iSourceid     = iSourceid;   /* fill entry */
-  pEntry->iComposition  = iComposition;
-  pEntry->iOrientation  = iOrientation;
-  pEntry->iOffsettype   = iOffsettype;
-  pEntry->iOffsetx      = iOffsetx;
-  pEntry->iOffsety      = iOffsety;
-  pEntry->iBoundarytype = iBoundarytype;
-  pEntry->iBoundaryl    = iBoundaryl;
-  pEntry->iBoundaryr    = iBoundaryr;
-  pEntry->iBoundaryt    = iBoundaryt;
-  pEntry->iBoundaryb    = iBoundaryb;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_PAST_SRC, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_DISC
-mng_retcode MNG_DECL mng_putchunk_disc (mng_handle  hHandle,
-                                        mng_uint32  iCount,
-                                        mng_uint16p pObjectids)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_DISC, mng_init_general, mng_free_disc, mng_read_disc, mng_write_disc, mng_assign_disc, 0, 0, sizeof(mng_disc)};
-#else
-          {MNG_UINT_DISC, mng_init_disc, mng_free_disc, mng_read_disc, mng_write_disc, mng_assign_disc, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_DISC, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a MHDR first! */
-  if (pData->iFirstchunkadded != MNG_UINT_MHDR)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_DISC))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_disc (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_DISC, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_discp)pChunk)->iCount = iCount;
-
-  if (iCount)
-  {
-    mng_uint32 iSize = iCount * sizeof (mng_uint32);
-
-    MNG_ALLOC (pData, ((mng_discp)pChunk)->pObjectids, iSize);
-    MNG_COPY (((mng_discp)pChunk)->pObjectids, pObjectids, iSize);
-  }
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_DISC, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_BACK
-mng_retcode MNG_DECL mng_putchunk_back (mng_handle hHandle,
-                                        mng_uint16 iRed,
-                                        mng_uint16 iGreen,
-                                        mng_uint16 iBlue,
-                                        mng_uint8  iMandatory,
-                                        mng_uint16 iImageid,
-                                        mng_uint8  iTile)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_BACK, mng_init_general, mng_free_general, mng_read_back, mng_write_back, mng_assign_general, 0, 0, sizeof(mng_back)};
-#else
-          {MNG_UINT_BACK, mng_init_back, mng_free_back, mng_read_back, mng_write_back, mng_assign_back, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_BACK, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a MHDR first! */
-  if (pData->iFirstchunkadded != MNG_UINT_MHDR)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_BACK))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_back (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_BACK, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_backp)pChunk)->iRed       = iRed;
-  ((mng_backp)pChunk)->iGreen     = iGreen;
-  ((mng_backp)pChunk)->iBlue      = iBlue;
-  ((mng_backp)pChunk)->iMandatory = iMandatory;
-  ((mng_backp)pChunk)->iImageid   = iImageid;
-  ((mng_backp)pChunk)->iTile      = iTile;
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_BACK, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_FRAM
-mng_retcode MNG_DECL mng_putchunk_fram (mng_handle  hHandle,
-                                        mng_bool    bEmpty,
-                                        mng_uint8   iMode,
-                                        mng_uint32  iNamesize,
-                                        mng_pchar   zName,
-                                        mng_uint8   iChangedelay,
-                                        mng_uint8   iChangetimeout,
-                                        mng_uint8   iChangeclipping,
-                                        mng_uint8   iChangesyncid,
-                                        mng_uint32  iDelay,
-                                        mng_uint32  iTimeout,
-                                        mng_uint8   iBoundarytype,
-                                        mng_int32   iBoundaryl,
-                                        mng_int32   iBoundaryr,
-                                        mng_int32   iBoundaryt,
-                                        mng_int32   iBoundaryb,
-                                        mng_uint32  iCount,
-                                        mng_uint32p pSyncids)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_FRAM, mng_init_general, mng_free_fram, mng_read_fram, mng_write_fram, mng_assign_fram, 0, 0, sizeof(mng_fram)};
-#else
-          {MNG_UINT_FRAM, mng_init_fram, mng_free_fram, mng_read_fram, mng_write_fram, mng_assign_fram, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_FRAM, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a MHDR first! */
-  if (pData->iFirstchunkadded != MNG_UINT_MHDR)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_FRAM))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_fram (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_FRAM, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_framp)pChunk)->bEmpty          = bEmpty;
-  ((mng_framp)pChunk)->iMode           = iMode;
-  ((mng_framp)pChunk)->iNamesize       = iNamesize;
-  ((mng_framp)pChunk)->iChangedelay    = iChangedelay;
-  ((mng_framp)pChunk)->iChangetimeout  = iChangetimeout;
-  ((mng_framp)pChunk)->iChangeclipping = iChangeclipping;
-  ((mng_framp)pChunk)->iChangesyncid   = iChangesyncid;
-  ((mng_framp)pChunk)->iDelay          = iDelay;
-  ((mng_framp)pChunk)->iTimeout        = iTimeout;
-  ((mng_framp)pChunk)->iBoundarytype   = iBoundarytype;
-  ((mng_framp)pChunk)->iBoundaryl      = iBoundaryl;
-  ((mng_framp)pChunk)->iBoundaryr      = iBoundaryr;
-  ((mng_framp)pChunk)->iBoundaryt      = iBoundaryt;
-  ((mng_framp)pChunk)->iBoundaryb      = iBoundaryb;
-  ((mng_framp)pChunk)->iCount          = iCount;
-
-  if (iNamesize)
-  {
-    MNG_ALLOC (pData, ((mng_framp)pChunk)->zName, iNamesize + 1);
-    MNG_COPY (((mng_framp)pChunk)->zName, zName, iNamesize);
-  }
-
-  if (iCount)
-  {
-    mng_uint32 iSize = iCount * sizeof (mng_uint32);
-
-    MNG_ALLOC (pData, ((mng_framp)pChunk)->pSyncids, iSize);
-    MNG_COPY (((mng_framp)pChunk)->pSyncids, pSyncids, iSize);
-  }
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_FRAM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_MOVE
-mng_retcode MNG_DECL mng_putchunk_move (mng_handle hHandle,
-                                        mng_uint16 iFirstid,
-                                        mng_uint16 iLastid,
-                                        mng_uint8  iMovetype,
-                                        mng_int32  iMovex,
-                                        mng_int32  iMovey)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_MOVE, mng_init_general, mng_free_general, mng_read_move, mng_write_move, mng_assign_general, 0, 0, sizeof(mng_move)};
-#else
-          {MNG_UINT_MOVE, mng_init_move, mng_free_move, mng_read_move, mng_write_move, mng_assign_move, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_MOVE, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a MHDR first! */
-  if (pData->iFirstchunkadded != MNG_UINT_MHDR)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_MOVE))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_move (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_MOVE, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_movep)pChunk)->iFirstid  = iFirstid;
-  ((mng_movep)pChunk)->iLastid   = iLastid;
-  ((mng_movep)pChunk)->iMovetype = iMovetype;
-  ((mng_movep)pChunk)->iMovex    = iMovex;
-  ((mng_movep)pChunk)->iMovey    = iMovey;
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_MOVE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_CLIP
-mng_retcode MNG_DECL mng_putchunk_clip (mng_handle hHandle,
-                                        mng_uint16 iFirstid,
-                                        mng_uint16 iLastid,
-                                        mng_uint8  iCliptype,
-                                        mng_int32  iClipl,
-                                        mng_int32  iClipr,
-                                        mng_int32  iClipt,
-                                        mng_int32  iClipb)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_CLIP, mng_init_general, mng_free_general, mng_read_clip, mng_write_clip, mng_assign_general, 0, 0, sizeof(mng_clip)};
-#else
-          {MNG_UINT_CLIP, mng_init_clip, mng_free_clip, mng_read_clip, mng_write_clip, mng_assign_clip, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_CLIP, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a MHDR first! */
-  if (pData->iFirstchunkadded != MNG_UINT_MHDR)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_CLIP))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_clip (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_CLIP, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_clipp)pChunk)->iFirstid  = iFirstid;
-  ((mng_clipp)pChunk)->iLastid   = iLastid;
-  ((mng_clipp)pChunk)->iCliptype = iCliptype;
-  ((mng_clipp)pChunk)->iClipl    = iClipl;
-  ((mng_clipp)pChunk)->iClipr    = iClipr;
-  ((mng_clipp)pChunk)->iClipt    = iClipt;
-  ((mng_clipp)pChunk)->iClipb    = iClipb;
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_CLIP, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_SHOW
-mng_retcode MNG_DECL mng_putchunk_show (mng_handle hHandle,
-                                        mng_bool   bEmpty,
-                                        mng_uint16 iFirstid,
-                                        mng_uint16 iLastid,
-                                        mng_uint8  iMode)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_SHOW, mng_init_general, mng_free_general, mng_read_show, mng_write_show, mng_assign_general, 0, 0, sizeof(mng_show)};
-#else
-          {MNG_UINT_SHOW, mng_init_show, mng_free_show, mng_read_show, mng_write_show, mng_assign_show, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_SHOW, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a MHDR first! */
-  if (pData->iFirstchunkadded != MNG_UINT_MHDR)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_SHOW))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_show (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_SHOW, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_showp)pChunk)->bEmpty   = bEmpty;
-  ((mng_showp)pChunk)->iFirstid = iFirstid;
-  ((mng_showp)pChunk)->iLastid  = iLastid;
-  ((mng_showp)pChunk)->iMode    = iMode;
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_SHOW, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_TERM
-mng_retcode MNG_DECL mng_putchunk_term (mng_handle hHandle,
-                                        mng_uint8  iTermaction,
-                                        mng_uint8  iIteraction,
-                                        mng_uint32 iDelay,
-                                        mng_uint32 iItermax)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_TERM, mng_init_general, mng_free_general, mng_read_term, mng_write_term, mng_assign_general, 0, 0, sizeof(mng_term)};
-#else
-          {MNG_UINT_TERM, mng_init_term, mng_free_term, mng_read_term, mng_write_term, mng_assign_term, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_TERM, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a MHDR first! */
-  if (pData->iFirstchunkadded != MNG_UINT_MHDR)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_term (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_TERM, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_termp)pChunk)->iTermaction = iTermaction;
-  ((mng_termp)pChunk)->iIteraction = iIteraction;
-  ((mng_termp)pChunk)->iDelay      = iDelay;
-  ((mng_termp)pChunk)->iItermax    = iItermax;
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_TERM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_SAVE
-mng_retcode MNG_DECL mng_putchunk_save (mng_handle hHandle,
-                                        mng_bool   bEmpty,
-                                        mng_uint8  iOffsettype,
-                                        mng_uint32 iCount)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_SAVE, mng_init_general, mng_free_save, mng_read_save, mng_write_save, mng_assign_save, 0, 0, sizeof(mng_save)};
-#else
-          {MNG_UINT_SAVE, mng_init_save, mng_free_save, mng_read_save, mng_write_save, mng_assign_save, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_SAVE, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a MHDR first! */
-  if (pData->iFirstchunkadded != MNG_UINT_MHDR)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_SAVE))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_save (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_SAVE, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_savep)pChunk)->bEmpty      = bEmpty;
-  ((mng_savep)pChunk)->iOffsettype = iOffsettype;
-  ((mng_savep)pChunk)->iCount      = iCount;
-
-  if (iCount)
-    MNG_ALLOC (pData, ((mng_savep)pChunk)->pEntries, iCount * sizeof (mng_save_entry));
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_SAVE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_putchunk_save_entry (mng_handle     hHandle,
-                                              mng_uint32     iEntry,
-                                              mng_uint8      iEntrytype,
-                                              mng_uint32arr2 iOffset,
-                                              mng_uint32arr2 iStarttime,
-                                              mng_uint32     iLayernr,
-                                              mng_uint32     iFramenr,
-                                              mng_uint32     iNamesize,
-                                              mng_pchar      zName)
-{
-  mng_datap       pData;
-  mng_chunkp      pChunk;
-  mng_save_entryp pEntry;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_SAVE_ENTRY, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a MHDR first! */
-  if (pData->iFirstchunkadded != MNG_UINT_MHDR)
-    MNG_ERROR (pData, MNG_NOHEADER)
-
-  pChunk = pData->pLastchunk;          /* last one must have been SAVE ! */
-
-  if (((mng_chunk_headerp)pChunk)->iChunkname != MNG_UINT_SAVE)
-    MNG_ERROR (pData, MNG_NOCORRCHUNK)
-                                       /* index out of bounds ? */
-  if (iEntry >= ((mng_savep)pChunk)->iCount)
-    MNG_ERROR (pData, MNG_INVALIDENTRYIX)
-                                       /* address proper entry */
-  pEntry = ((mng_savep)pChunk)->pEntries + iEntry;
-
-  pEntry->iEntrytype    = iEntrytype;  /* fill entry */
-  pEntry->iOffset[0]    = iOffset[0];
-  pEntry->iOffset[1]    = iOffset[1];
-  pEntry->iStarttime[0] = iStarttime[0];
-  pEntry->iStarttime[1] = iStarttime[1];
-  pEntry->iLayernr      = iLayernr;
-  pEntry->iFramenr      = iFramenr;
-  pEntry->iNamesize     = iNamesize;
-
-  if (iNamesize)
-  {
-    MNG_ALLOC (pData, pEntry->zName, iNamesize + 1);
-    MNG_COPY (pEntry->zName, zName, iNamesize);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_SAVE_ENTRY, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_SEEK
-mng_retcode MNG_DECL mng_putchunk_seek (mng_handle hHandle,
-                                        mng_uint32 iNamesize,
-                                        mng_pchar  zName)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_SEEK, mng_init_general, mng_free_seek, mng_read_seek, mng_write_seek, mng_assign_seek, 0, 0, sizeof(mng_seek)};
-#else
-          {MNG_UINT_SEEK, mng_init_seek, mng_free_seek, mng_read_seek, mng_write_seek, mng_assign_seek, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_SEEK, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a MHDR first! */
-  if (pData->iFirstchunkadded != MNG_UINT_MHDR)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_SEEK))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_seek (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_SEEK, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_seekp)pChunk)->iNamesize = iNamesize;
-
-  if (iNamesize)
-  {
-    MNG_ALLOC (pData, ((mng_seekp)pChunk)->zName, iNamesize + 1);
-    MNG_COPY (((mng_seekp)pChunk)->zName, zName, iNamesize);
-  }
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_SEEK, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_eXPI
-mng_retcode MNG_DECL mng_putchunk_expi (mng_handle hHandle,
-                                        mng_uint16 iSnapshotid,
-                                        mng_uint32 iNamesize,
-                                        mng_pchar  zName)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_eXPI, mng_init_general, mng_free_expi, mng_read_expi, mng_write_expi, mng_assign_general, 0, 0, sizeof(mng_expi)};
-#else
-          {MNG_UINT_eXPI, mng_init_expi, mng_free_expi, mng_read_expi, mng_write_expi, mng_assign_expi, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_EXPI, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a MHDR first! */
-  if (pData->iFirstchunkadded != MNG_UINT_MHDR)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_eXPI))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_expi (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_eXPI, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_expip)pChunk)->iSnapshotid = iSnapshotid;
-  ((mng_expip)pChunk)->iNamesize   = iNamesize;
-
-  if (iNamesize)
-  {
-    MNG_ALLOC (pData, ((mng_expip)pChunk)->zName, iNamesize + 1);
-    MNG_COPY (((mng_expip)pChunk)->zName, zName, iNamesize);
-  }
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_EXPI, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_fPRI
-mng_retcode MNG_DECL mng_putchunk_fpri (mng_handle hHandle,
-                                        mng_uint8  iDeltatype,
-                                        mng_uint8  iPriority)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_fPRI, mng_init_general, mng_free_general, mng_read_fpri, mng_write_fpri, mng_assign_general, 0, 0, sizeof(mng_fpri)};
-#else
-          {MNG_UINT_fPRI, mng_init_fpri, mng_free_fpri, mng_read_fpri, mng_write_fpri, mng_assign_fpri, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_FPRI, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a MHDR first! */
-  if (pData->iFirstchunkadded != MNG_UINT_MHDR)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_fPRI))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_fpri (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_fPRI, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_fprip)pChunk)->iDeltatype = iDeltatype;
-  ((mng_fprip)pChunk)->iPriority  = iPriority;
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_FPRI, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_nEED
-mng_retcode MNG_DECL mng_putchunk_need (mng_handle hHandle,
-                                        mng_uint32 iKeywordssize,
-                                        mng_pchar  zKeywords)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_nEED, mng_init_general, mng_free_need, mng_read_need, mng_write_need, mng_assign_need, 0, 0, sizeof(mng_need)};
-#else
-          {MNG_UINT_nEED, mng_init_need, mng_free_need, mng_read_need, mng_write_need, mng_assign_need, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_NEED, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a MHDR first! */
-  if (pData->iFirstchunkadded != MNG_UINT_MHDR)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_nEED))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_need (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_nEED, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_needp)pChunk)->iKeywordssize = iKeywordssize;
-
-  if (iKeywordssize)
-  {
-    MNG_ALLOC (pData, ((mng_needp)pChunk)->zKeywords, iKeywordssize + 1);
-    MNG_COPY (((mng_needp)pChunk)->zKeywords, zKeywords, iKeywordssize);
-  }
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_NEED, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_pHYg
-mng_retcode MNG_DECL mng_putchunk_phyg (mng_handle hHandle,
-                                        mng_bool   bEmpty,
-                                        mng_uint32 iSizex,
-                                        mng_uint32 iSizey,
-                                        mng_uint8  iUnit)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_pHYg, mng_init_general, mng_free_general, mng_read_phyg, mng_write_phyg, mng_assign_general, 0, 0, sizeof(mng_phyg)};
-#else
-          {MNG_UINT_pHYg, mng_init_phyg, mng_free_phyg, mng_read_phyg, mng_write_phyg, mng_assign_phyg, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_PHYG, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a MHDR first! */
-  if (pData->iFirstchunkadded != MNG_UINT_MHDR)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_pHYg))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_phyg (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_pHYg, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_phygp)pChunk)->bEmpty = bEmpty;
-  ((mng_phygp)pChunk)->iSizex = iSizex;
-  ((mng_phygp)pChunk)->iSizey = iSizey;
-  ((mng_phygp)pChunk)->iUnit  = iUnit;
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_PHYG, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-
-mng_retcode MNG_DECL mng_putchunk_jhdr (mng_handle hHandle,
-                                        mng_uint32 iWidth,
-                                        mng_uint32 iHeight,
-                                        mng_uint8  iColortype,
-                                        mng_uint8  iImagesampledepth,
-                                        mng_uint8  iImagecompression,
-                                        mng_uint8  iImageinterlace,
-                                        mng_uint8  iAlphasampledepth,
-                                        mng_uint8  iAlphacompression,
-                                        mng_uint8  iAlphafilter,
-                                        mng_uint8  iAlphainterlace)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_JHDR, mng_init_general, mng_free_general, mng_read_jhdr, mng_write_jhdr, mng_assign_general, 0, 0, sizeof(mng_jhdr)};
-#else
-          {MNG_UINT_JHDR, mng_init_jhdr, mng_free_jhdr, mng_read_jhdr, mng_write_jhdr, mng_assign_jhdr, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_JHDR, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_JHDR))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_jhdr (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_JHDR, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_jhdrp)pChunk)->iWidth            = iWidth;
-  ((mng_jhdrp)pChunk)->iHeight           = iHeight;
-  ((mng_jhdrp)pChunk)->iColortype        = iColortype;
-  ((mng_jhdrp)pChunk)->iImagesampledepth = iImagesampledepth;
-  ((mng_jhdrp)pChunk)->iImagecompression = iImagecompression;
-  ((mng_jhdrp)pChunk)->iImageinterlace   = iImageinterlace;
-  ((mng_jhdrp)pChunk)->iAlphasampledepth = iAlphasampledepth;
-  ((mng_jhdrp)pChunk)->iAlphacompression = iAlphacompression;
-  ((mng_jhdrp)pChunk)->iAlphafilter      = iAlphafilter;
-  ((mng_jhdrp)pChunk)->iAlphainterlace   = iAlphainterlace;
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_JHDR, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-#endif /* MNG_INCLUDE_JNG */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-
-mng_retcode MNG_DECL mng_putchunk_jdat (mng_handle hHandle,
-                                        mng_uint32 iRawlen,
-                                        mng_ptr    pRawdata)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_JDAT, mng_init_general, mng_free_jdat, mng_read_jdat, mng_write_jdat, mng_assign_jdat, 0, 0, sizeof(mng_jdat)};
-#else
-          {MNG_UINT_JDAT, mng_init_jdat, mng_free_jdat, mng_read_jdat, mng_write_jdat, mng_assign_jdat, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_JDAT, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a MHDR or JHDR first! */
-  if ((pData->iFirstchunkadded != MNG_UINT_MHDR) &&
-      (pData->iFirstchunkadded != MNG_UINT_JHDR)    )
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_JDAT))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_jdat (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_JDAT, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_jdatp)pChunk)->iDatasize = iRawlen;
-
-  if (iRawlen)
-  {
-    MNG_ALLOC (pData, ((mng_jdatp)pChunk)->pData, iRawlen);
-    MNG_COPY (((mng_jdatp)pChunk)->pData, pRawdata, iRawlen);
-  }
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_JDAT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-#endif /*  MNG_INCLUDE_JNG */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-
-mng_retcode MNG_DECL mng_putchunk_jdaa (mng_handle hHandle,
-                                        mng_uint32 iRawlen,
-                                        mng_ptr    pRawdata)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_JDAA, mng_init_general, mng_free_jdaa, mng_read_jdaa, mng_write_jdaa, mng_assign_jdaa, 0, 0, sizeof(mng_jdaa)};
-#else
-          {MNG_UINT_JDAA, mng_init_jdaa, mng_free_jdaa, mng_read_jdaa, mng_write_jdaa, mng_assign_jdaa, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_JDAA, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a MHDR or JHDR first! */
-  if ((pData->iFirstchunkadded != MNG_UINT_MHDR) &&
-      (pData->iFirstchunkadded != MNG_UINT_JHDR)    )
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_JDAA))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_jdaa (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_JDAA, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_jdaap)pChunk)->iDatasize = iRawlen;
-
-  if (iRawlen)
-  {
-    MNG_ALLOC (pData, ((mng_jdaap)pChunk)->pData, iRawlen);
-    MNG_COPY (((mng_jdaap)pChunk)->pData, pRawdata, iRawlen);
-  }
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_JDAA, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-#endif /*  MNG_INCLUDE_JNG */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-
-mng_retcode MNG_DECL mng_putchunk_jsep (mng_handle hHandle)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_JSEP, mng_init_general, mng_free_general, mng_read_jsep, mng_write_jsep, mng_assign_general, 0, 0, sizeof(mng_jsep)};
-#else
-          {MNG_UINT_JSEP, mng_init_jsep, mng_free_jsep, mng_read_jsep, mng_write_jsep, mng_assign_jsep, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_JSEP, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a MHDR or JHDR first! */
-  if ((pData->iFirstchunkadded != MNG_UINT_MHDR) &&
-      (pData->iFirstchunkadded != MNG_UINT_JHDR)    )
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_JSEP))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_jsep (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_JSEP, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_JSEP, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-#endif /* MNG_INCLUDE_JNG */
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-mng_retcode MNG_DECL mng_putchunk_dhdr (mng_handle hHandle,
-                                        mng_uint16 iObjectid,
-                                        mng_uint8  iImagetype,
-                                        mng_uint8  iDeltatype,
-                                        mng_uint32 iBlockwidth,
-                                        mng_uint32 iBlockheight,
-                                        mng_uint32 iBlockx,
-                                        mng_uint32 iBlocky)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_DHDR, mng_init_general, mng_free_general, mng_read_dhdr, mng_write_dhdr, mng_assign_general, 0, 0, sizeof(mng_dhdr)};
-#else
-          {MNG_UINT_DHDR, mng_init_dhdr, mng_free_dhdr, mng_read_dhdr, mng_write_dhdr, mng_assign_dhdr, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_DHDR, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a MHDR first! */
-  if (pData->iFirstchunkadded != MNG_UINT_MHDR)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_DHDR))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_dhdr (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_DHDR, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_dhdrp)pChunk)->iObjectid    = iObjectid;
-  ((mng_dhdrp)pChunk)->iImagetype   = iImagetype;
-  ((mng_dhdrp)pChunk)->iDeltatype   = iDeltatype;
-  ((mng_dhdrp)pChunk)->iBlockwidth  = iBlockwidth;
-  ((mng_dhdrp)pChunk)->iBlockheight = iBlockheight;
-  ((mng_dhdrp)pChunk)->iBlockx      = iBlockx;
-  ((mng_dhdrp)pChunk)->iBlocky      = iBlocky;
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_DHDR, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-mng_retcode MNG_DECL mng_putchunk_prom (mng_handle hHandle,
-                                        mng_uint8  iColortype,
-                                        mng_uint8  iSampledepth,
-                                        mng_uint8  iFilltype)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_PROM, mng_init_general, mng_free_general, mng_read_prom, mng_write_prom, mng_assign_general, 0, 0, sizeof(mng_prom)};
-#else
-          {MNG_UINT_PROM, mng_init_prom, mng_free_prom, mng_read_prom, mng_write_prom, mng_assign_prom, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_PROM, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a MHDR first! */
-  if (pData->iFirstchunkadded != MNG_UINT_MHDR)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_PROM))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_prom (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_PROM, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_promp)pChunk)->iColortype   = iColortype;
-  ((mng_promp)pChunk)->iSampledepth = iSampledepth;
-  ((mng_promp)pChunk)->iFilltype    = iFilltype;
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_PROM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-mng_retcode MNG_DECL mng_putchunk_ipng (mng_handle hHandle)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_IPNG, mng_init_general, mng_free_general, mng_read_ipng, mng_write_ipng, mng_assign_general, 0, 0, sizeof(mng_ipng)};
-#else
-          {MNG_UINT_IPNG, mng_init_ipng, mng_free_ipng, mng_read_ipng, mng_write_ipng, mng_assign_ipng, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_IPNG, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a MHDR first! */
-  if (pData->iFirstchunkadded != MNG_UINT_MHDR)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_IPNG))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_ipng (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_IPNG, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_IPNG, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-mng_retcode MNG_DECL mng_putchunk_pplt (mng_handle hHandle,
-                                        mng_uint8  iDeltatype,
-                                        mng_uint32 iCount)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_PPLT, mng_init_general, mng_free_general, mng_read_pplt, mng_write_pplt, mng_assign_general, 0, 0, sizeof(mng_pplt)};
-#else
-          {MNG_UINT_PPLT, mng_init_pplt, mng_free_pplt, mng_read_pplt, mng_write_pplt, mng_assign_pplt, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_PPLT, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a MHDR first! */
-  if (pData->iFirstchunkadded != MNG_UINT_MHDR)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_PPLT))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_pplt (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_PPLT, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_ppltp)pChunk)->iDeltatype = iDeltatype;
-  ((mng_ppltp)pChunk)->iCount     = iCount;
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_PPLT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-mng_retcode MNG_DECL mng_putchunk_pplt_entry (mng_handle hHandle,
-                                              mng_uint32 iEntry,
-                                              mng_uint16 iRed,
-                                              mng_uint16 iGreen,
-                                              mng_uint16 iBlue,
-                                              mng_uint16 iAlpha)
-{
-  mng_datap       pData;
-  mng_chunkp      pChunk;
-  mng_pplt_entryp pEntry;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_PPLT_ENTRY, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a MHDR first! */
-  if (pData->iFirstchunkadded != MNG_UINT_MHDR)
-    MNG_ERROR (pData, MNG_NOHEADER)
-
-  pChunk = pData->pLastchunk;          /* last one must have been PPLT ! */
-
-  if (((mng_chunk_headerp)pChunk)->iChunkname != MNG_UINT_PPLT)
-    MNG_ERROR (pData, MNG_NOCORRCHUNK)
-
-                                       /* index out of bounds ? */
-  if (iEntry >= ((mng_ppltp)pChunk)->iCount)
-    MNG_ERROR (pData, MNG_INVALIDENTRYIX)
-                                       /* address proper entry */
-  pEntry = (mng_pplt_entryp)(((mng_ppltp)pChunk)->aEntries) + iEntry;
-
-  pEntry->iRed   = (mng_uint8)iRed;    /* fill the entry */
-  pEntry->iGreen = (mng_uint8)iGreen;
-  pEntry->iBlue  = (mng_uint8)iBlue;
-  pEntry->iAlpha = (mng_uint8)iAlpha;
-  pEntry->bUsed  = MNG_TRUE;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_PPLT_ENTRY, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-#ifdef MNG_INCLUDE_JNG
-mng_retcode MNG_DECL mng_putchunk_ijng (mng_handle hHandle)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_IJNG, mng_init_general, mng_free_general, mng_read_ijng, mng_write_ijng, mng_assign_general, 0, 0, sizeof(mng_ijng)};
-#else
-          {MNG_UINT_IJNG, mng_init_ijng, mng_free_ijng, mng_read_ijng, mng_write_ijng, mng_assign_ijng, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_IJNG, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a MHDR first! */
-  if (pData->iFirstchunkadded != MNG_UINT_MHDR)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_IJNG))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_ijng (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_IJNG, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_IJNG, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-mng_retcode MNG_DECL mng_putchunk_drop (mng_handle   hHandle,
-                                        mng_uint32   iCount,
-                                        mng_chunkidp pChunknames)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_DROP, mng_init_general, mng_free_drop, mng_read_drop, mng_write_drop, mng_assign_drop, 0, 0, sizeof(mng_drop)};
-#else
-          {MNG_UINT_DROP, mng_init_drop, mng_free_drop, mng_read_drop, mng_write_drop, mng_assign_drop, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_DROP, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a MHDR first! */
-  if (pData->iFirstchunkadded != MNG_UINT_MHDR)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_DROP))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_drop (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_DROP, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_dropp)pChunk)->iCount = iCount;
-
-  if (iCount)
-  {
-    mng_uint32 iSize = iCount * sizeof (mng_chunkid);
-
-    MNG_ALLOC (pData, ((mng_dropp)pChunk)->pChunknames, iSize);
-    MNG_COPY (((mng_dropp)pChunk)->pChunknames, pChunknames, iSize);
-  }
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_DROP, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_SKIPCHUNK_DBYK
-mng_retcode MNG_DECL mng_putchunk_dbyk (mng_handle  hHandle,
-                                        mng_chunkid iChunkname,
-                                        mng_uint8   iPolarity,
-                                        mng_uint32  iKeywordssize,
-                                        mng_pchar   zKeywords)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_DBYK, mng_init_general, mng_free_dbyk, mng_read_dbyk, mng_write_dbyk, mng_assign_dbyk, 0, 0, sizeof(mng_dbyk)};
-#else
-          {MNG_UINT_DBYK, mng_init_dbyk, mng_free_dbyk, mng_read_dbyk, mng_write_dbyk, mng_assign_dbyk, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_DBYK, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a MHDR first! */
-  if (pData->iFirstchunkadded != MNG_UINT_MHDR)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_DBYK))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_dbyk (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_DBYK, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_dbykp)pChunk)->iChunkname    = iChunkname;
-  ((mng_dbykp)pChunk)->iPolarity     = iPolarity;
-  ((mng_dbykp)pChunk)->iKeywordssize = iKeywordssize;
-
-  if (iKeywordssize)
-  {
-    MNG_ALLOC (pData, ((mng_dbykp)pChunk)->zKeywords, iKeywordssize + 1);
-    MNG_COPY (((mng_dbykp)pChunk)->zKeywords, zKeywords, iKeywordssize);
-  }
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_DBYK, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_SKIPCHUNK_ORDR
-mng_retcode MNG_DECL mng_putchunk_ordr (mng_handle hHandle,
-                                        mng_uint32 iCount)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_ORDR, mng_init_general, mng_free_ordr, mng_read_ordr, mng_write_ordr, mng_assign_ordr, 0, 0, sizeof(mng_ordr)};
-#else
-          {MNG_UINT_ORDR, mng_init_ordr, mng_free_ordr, mng_read_ordr, mng_write_ordr, mng_assign_ordr, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_ORDR, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a MHDR first! */
-  if (pData->iFirstchunkadded != MNG_UINT_MHDR)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_ORDR))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_ordr (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_ORDR, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_ordrp)pChunk)->iCount = iCount;
-
-  if (iCount)
-    MNG_ALLOC (pData, ((mng_ordrp)pChunk)->pEntries, iCount * sizeof (mng_ordr_entry));
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_ORDR, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_SKIPCHUNK_ORDR
-mng_retcode MNG_DECL mng_putchunk_ordr_entry (mng_handle  hHandle,
-                                              mng_uint32  iEntry,
-                                              mng_chunkid iChunkname,
-                                              mng_uint8   iOrdertype)
-{
-  mng_datap       pData;
-  mng_chunkp      pChunk;
-  mng_ordr_entryp pEntry;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_ORDR_ENTRY, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a MHDR first! */
-  if (pData->iFirstchunkadded != MNG_UINT_MHDR)
-    MNG_ERROR (pData, MNG_NOHEADER)
-
-  pChunk = pData->pLastchunk;          /* last one must have been ORDR ! */
-
-  if (((mng_chunk_headerp)pChunk)->iChunkname != MNG_UINT_ORDR)
-    MNG_ERROR (pData, MNG_NOCORRCHUNK)
-                                       /* index out of bounds ? */
-  if (iEntry >= ((mng_ordrp)pChunk)->iCount)
-    MNG_ERROR (pData, MNG_INVALIDENTRYIX)
-                                       /* address proper entry */
-  pEntry = ((mng_ordrp)pChunk)->pEntries + iEntry;
-
-  pEntry->iChunkname = iChunkname;     /* fill the entry */
-  pEntry->iOrdertype = iOrdertype;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_ORDR_ENTRY, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_MAGN
-mng_retcode MNG_DECL mng_putchunk_magn (mng_handle hHandle,
-                                        mng_uint16 iFirstid,
-                                        mng_uint16 iLastid,
-                                        mng_uint16 iMethodX,
-                                        mng_uint16 iMX,
-                                        mng_uint16 iMY,
-                                        mng_uint16 iML,
-                                        mng_uint16 iMR,
-                                        mng_uint16 iMT,
-                                        mng_uint16 iMB,
-                                        mng_uint16 iMethodY)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_MAGN, mng_init_general, mng_free_general, mng_read_magn, mng_write_magn, mng_assign_general, 0, 0, sizeof(mng_magn)};
-#else
-          {MNG_UINT_MAGN, mng_init_magn, mng_free_magn, mng_read_magn, mng_write_magn, mng_assign_magn, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_MAGN, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a MHDR first! */
-  if (pData->iFirstchunkadded != MNG_UINT_MHDR)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_MAGN))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_magn (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_MAGN, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_magnp)pChunk)->iFirstid = iFirstid;
-  ((mng_magnp)pChunk)->iLastid  = iLastid;
-  ((mng_magnp)pChunk)->iMethodX = (mng_uint8)iMethodX;
-  ((mng_magnp)pChunk)->iMX      = iMX;
-  ((mng_magnp)pChunk)->iMY      = iMY;
-  ((mng_magnp)pChunk)->iML      = iML;
-  ((mng_magnp)pChunk)->iMR      = iMR;
-  ((mng_magnp)pChunk)->iMT      = iMT;
-  ((mng_magnp)pChunk)->iMB      = iMB;
-  ((mng_magnp)pChunk)->iMethodY = (mng_uint8)iMethodY;
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_MAGN, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_mpng (mng_handle hHandle,
-                                                mng_uint32 iFramewidth,
-                                                mng_uint32 iFrameheight,
-                                                mng_uint16 iNumplays,
-                                                mng_uint16 iTickspersec,
-                                                mng_uint8  iCompressionmethod,
-                                                mng_uint32 iCount)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_mpNG, mng_init_general, mng_free_mpng, mng_read_mpng, mng_write_mpng, mng_assign_mpng, 0, 0, sizeof(mng_mpng)};
-#else
-          {MNG_UINT_mpNG, mng_init_mpng, mng_free_mpng, mng_read_mpng, mng_write_mpng, mng_assign_mpng, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_MPNG, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a IHDR first! */
-  if (pData->iFirstchunkadded != MNG_UINT_IHDR)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_mpng (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_mpNG, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_mpngp)pChunk)->iFramewidth        = iFramewidth;
-  ((mng_mpngp)pChunk)->iFrameheight       = iFrameheight;
-  ((mng_mpngp)pChunk)->iNumplays          = iNumplays;
-  ((mng_mpngp)pChunk)->iTickspersec       = iTickspersec;
-  ((mng_mpngp)pChunk)->iCompressionmethod = iCompressionmethod;
-  ((mng_mpngp)pChunk)->iFramessize        = iCount * sizeof (mng_mpng_frame);
-
-  if (iCount)
-    MNG_ALLOC (pData, ((mng_mpngp)pChunk)->pFrames, ((mng_mpngp)pChunk)->iFramessize);
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_MPNG, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-MNG_EXT mng_retcode MNG_DECL mng_putchunk_mpng_frame (mng_handle hHandle,
-                                                      mng_uint32 iEntry,
-                                                      mng_uint32 iX,
-                                                      mng_uint32 iY,
-                                                      mng_uint32 iWidth,
-                                                      mng_uint32 iHeight,
-                                                      mng_int32  iXoffset,
-                                                      mng_int32  iYoffset,
-                                                      mng_uint16 iTicks)
-{
-  mng_datap       pData;
-  mng_chunkp      pChunk;
-  mng_mpng_framep pFrame;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_MPNG_FRAME, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a IHDR first! */
-  if (pData->iFirstchunkadded != MNG_UINT_IHDR)
-    MNG_ERROR (pData, MNG_NOHEADER)
-
-  pChunk = pData->pLastchunk;          /* last one must have been mpNG ! */
-
-  if (((mng_chunk_headerp)pChunk)->iChunkname != MNG_UINT_mpNG)
-    MNG_ERROR (pData, MNG_NOCORRCHUNK)
-                                       /* index out of bounds ? */
-  if (iEntry >= (((mng_mpngp)pChunk)->iFramessize / sizeof (mng_mpng_frame)))
-    MNG_ERROR (pData, MNG_INVALIDENTRYIX)
-                                       /* address proper entry */
-  pFrame = ((mng_mpngp)pChunk)->pFrames + iEntry;
-                                       /* fill entry */
-  pFrame->iX        = iX;
-  pFrame->iY        = iY;
-  pFrame->iWidth    = iWidth;
-  pFrame->iHeight   = iHeight;
-  pFrame->iXoffset  = iXoffset;
-  pFrame->iYoffset  = iYoffset;
-  pFrame->iTicks    = iTicks;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_MPNG_FRAME, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_evNT
-mng_retcode MNG_DECL mng_putchunk_evnt (mng_handle hHandle,
-                                        mng_uint32 iCount)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_evNT, mng_init_general, mng_free_evnt, mng_read_evnt, mng_write_evnt, mng_assign_evnt, 0, 0, sizeof(mng_evnt)};
-#else
-          {MNG_UINT_evNT, mng_init_evnt, mng_free_evnt, mng_read_evnt, mng_write_evnt, mng_assign_evnt, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_EVNT, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a MHDR first! */
-  if (pData->iFirstchunkadded != MNG_UINT_MHDR)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, MNG_UINT_evNT))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_evnt (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_evNT, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_evntp)pChunk)->iCount = iCount;
-
-  if (iCount)
-    MNG_ALLOC (pData, ((mng_evntp)pChunk)->pEntries, iCount * sizeof (mng_evnt_entry));
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_EVNT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_putchunk_evnt_entry (mng_handle hHandle,
-                                              mng_uint32 iEntry,
-                                              mng_uint8  iEventtype,
-                                              mng_uint8  iMasktype,
-                                              mng_int32  iLeft,
-                                              mng_int32  iRight,
-                                              mng_int32  iTop,
-                                              mng_int32  iBottom,
-                                              mng_uint16 iObjectid,
-                                              mng_uint8  iIndex,
-                                              mng_uint32 iSegmentnamesize,
-                                              mng_pchar  zSegmentname)
-{
-  mng_datap       pData;
-  mng_chunkp      pChunk;
-  mng_evnt_entryp pEntry;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_EVNT_ENTRY, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a MHDR first! */
-  if (pData->iFirstchunkadded != MNG_UINT_MHDR)
-    MNG_ERROR (pData, MNG_NOHEADER)
-
-  pChunk = pData->pLastchunk;          /* last one must have been evNT ! */
-
-  if (((mng_chunk_headerp)pChunk)->iChunkname != MNG_UINT_evNT)
-    MNG_ERROR (pData, MNG_NOCORRCHUNK)
-                                       /* index out of bounds ? */
-  if (iEntry >= ((mng_evntp)pChunk)->iCount)
-    MNG_ERROR (pData, MNG_INVALIDENTRYIX)
-                                       /* address proper entry */
-  pEntry = ((mng_evntp)pChunk)->pEntries + iEntry;
-                                       /* fill entry */
-  pEntry->iEventtype       = iEventtype;
-  pEntry->iMasktype        = iMasktype;
-  pEntry->iLeft            = iLeft;
-  pEntry->iRight           = iRight;
-  pEntry->iTop             = iTop;
-  pEntry->iBottom          = iBottom;
-  pEntry->iObjectid        = iObjectid;
-  pEntry->iIndex           = iIndex;
-  pEntry->iSegmentnamesize = iSegmentnamesize;
-
-  if (iSegmentnamesize)
-  {
-    MNG_ALLOC (pData, pEntry->zSegmentname, iSegmentnamesize + 1);
-    MNG_COPY (pEntry->zSegmentname, zSegmentname, iSegmentnamesize);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_EVNT_ENTRY, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_putchunk_unknown (mng_handle  hHandle,
-                                           mng_chunkid iChunkname,
-                                           mng_uint32  iRawlen,
-                                           mng_ptr     pRawdata)
-{
-  mng_datap        pData;
-  mng_chunkp       pChunk;
-  mng_retcode      iRetcode;
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  mng_chunk_header sChunkheader =
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-          {MNG_UINT_HUH, mng_init_general, mng_free_unknown, mng_read_unknown, mng_write_unknown, mng_assign_unknown, 0, 0, sizeof(mng_unknown_chunk)};
-#else
-          {MNG_UINT_HUH, mng_init_unknown, mng_free_unknown, mng_read_unknown, mng_write_unknown, mng_assign_unknown, 0, 0};
-#endif
-#else
-  mng_chunk_header sChunkheader;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_UNKNOWN, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must have had a header first! */
-  if (pData->iFirstchunkadded == 0)
-    MNG_ERROR (pData, MNG_NOHEADER)
-                                       /* prevent misplaced TERM ! */
-  if (!check_term (pData, iChunkname))
-    MNG_ERROR (pData, MNG_TERMSEQERROR)
-                                       /* create the chunk */
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#else
-  iRetcode = mng_init_unknown (pData, &sChunkheader, &pChunk);
-#endif
-#else
-  mng_get_chunkheader(MNG_UINT_HUH, &sChunkheader);
-  iRetcode = mng_init_general (pData, &sChunkheader, &pChunk);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fill the chunk */
-  ((mng_unknown_chunkp)pChunk)->sHeader.iChunkname = iChunkname;
-  ((mng_unknown_chunkp)pChunk)->iDatasize          = iRawlen;
-
-  if (iRawlen)
-  {
-    MNG_ALLOC (pData, ((mng_unknown_chunkp)pChunk)->pData, iRawlen);
-    MNG_COPY (((mng_unknown_chunkp)pChunk)->pData, pRawdata, iRawlen);
-  }
-
-  mng_add_chunk (pData, pChunk);       /* add it to the list */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_UNKNOWN, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#endif /* MNG_INCLUDE_WRITE_PROCS */
-
-/* ************************************************************************** */
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_getimgdata_seq (mng_handle        hHandle,
-                                         mng_uint32        iSeqnr,
-                                         mng_uint32        iCanvasstyle,
-                                         mng_getcanvasline fGetcanvasline)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETIMGDATA_SEQ, MNG_LC_START);
-#endif
-
-
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETIMGDATA_SEQ, MNG_LC_END);
-#endif
-
-  return MNG_FNNOTIMPLEMENTED;
-}
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_getimgdata_chunkseq (mng_handle        hHandle,
-                                              mng_uint32        iSeqnr,
-                                              mng_uint32        iCanvasstyle,
-                                              mng_getcanvasline fGetcanvasline)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETIMGDATA_CHUNKSEQ, MNG_LC_START);
-#endif
-
-
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETIMGDATA_CHUNKSEQ, MNG_LC_END);
-#endif
-
-  return MNG_FNNOTIMPLEMENTED;
-}
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_getimgdata_chunk (mng_handle        hHandle,
-                                           mng_handle        hChunk,
-                                           mng_uint32        iCanvasstyle,
-                                           mng_getcanvasline fGetcanvasline)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETIMGDATA_CHUNK, MNG_LC_START);
-#endif
-
-
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETIMGDATA_CHUNK, MNG_LC_END);
-#endif
-
-  return MNG_FNNOTIMPLEMENTED;
-}
-
-/* ************************************************************************** */
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_WRITE_PROCS
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_putimgdata_ihdr (mng_handle        hHandle,
-                                          mng_uint32        iWidth,
-                                          mng_uint32        iHeight,
-                                          mng_uint8         iColortype,
-                                          mng_uint8         iBitdepth,
-                                          mng_uint8         iCompression,
-                                          mng_uint8         iFilter,
-                                          mng_uint8         iInterlace,
-                                          mng_uint32        iCanvasstyle,
-                                          mng_getcanvasline fGetcanvasline)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTIMGDATA_IHDR, MNG_LC_START);
-#endif
-
-
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTIMGDATA_IHDR, MNG_LC_END);
-#endif
-
-  return MNG_FNNOTIMPLEMENTED;
-}
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-mng_retcode MNG_DECL mng_putimgdata_jhdr (mng_handle        hHandle,
-                                          mng_uint32        iWidth,
-                                          mng_uint32        iHeight,
-                                          mng_uint8         iColortype,
-                                          mng_uint8         iBitdepth,
-                                          mng_uint8         iCompression,
-                                          mng_uint8         iInterlace,
-                                          mng_uint8         iAlphaBitdepth,
-                                          mng_uint8         iAlphaCompression,
-                                          mng_uint8         iAlphaFilter,
-                                          mng_uint8         iAlphaInterlace,
-                                          mng_uint32        iCanvasstyle,
-                                          mng_getcanvasline fGetcanvasline)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTIMGDATA_JHDR, MNG_LC_START);
-#endif
-
-
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTIMGDATA_JHDR, MNG_LC_END);
-#endif
-
-  return MNG_FNNOTIMPLEMENTED;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_updatemngheader (mng_handle hHandle,
-                                          mng_uint32 iFramecount,
-                                          mng_uint32 iLayercount,
-                                          mng_uint32 iPlaytime)
-{
-  mng_datap  pData;
-  mng_chunkp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_UPDATEMNGHEADER, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must be a MNG animation! */
-  if ((pData->eImagetype != mng_it_mng) || (pData->iFirstchunkadded != MNG_UINT_MHDR))
-    MNG_ERROR (pData, MNG_NOMHDR)
-
-  pChunk = pData->pFirstchunk;         /* get the first chunk */
-                                       /* and update the variables */
-  ((mng_mhdrp)pChunk)->iFramecount = iFramecount;
-  ((mng_mhdrp)pChunk)->iLayercount = iLayercount;
-  ((mng_mhdrp)pChunk)->iPlaytime   = iPlaytime;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_UPDATEMNGHEADER, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_updatemngsimplicity (mng_handle hHandle,
-                                              mng_uint32 iSimplicity)
-{
-  mng_datap  pData;
-  mng_chunkp pChunk;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_UPDATEMNGSIMPLICITY, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = (mng_datap)hHandle;          /* and make it addressable */
-
-  if (!pData->bCreating)               /* aren't we creating a new file ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID)
-                                       /* must be a MNG animation! */
-  if ((pData->eImagetype != mng_it_mng) || (pData->iFirstchunkadded != MNG_UINT_MHDR))
-    MNG_ERROR (pData, MNG_NOMHDR)
-
-  pChunk = pData->pFirstchunk;         /* get the first chunk */
-                                       /* and update the variable */
-  ((mng_mhdrp)pChunk)->iSimplicity = iSimplicity;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_UPDATEMNGSIMPLICITY, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#endif /* MNG_INCLUDE_WRITE_PROCS */
-
-/* ************************************************************************** */
-
-#endif /* MNG_ACCESS_CHUNKS */
-
-/* ************************************************************************** */
-/* * end of file                                                            * */
-/* ************************************************************************** */
-
-
-
diff --git a/Source/LibMNG/libmng_chunks.h b/Source/LibMNG/libmng_chunks.h
deleted file mode 100644
index d10bf2d..0000000
--- a/Source/LibMNG/libmng_chunks.h
+++ /dev/null
@@ -1,1026 +0,0 @@
-/* ************************************************************************** */
-/* *             For conditions of distribution and use,                    * */
-/* *                see copyright notice in libmng.h                        * */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * project   : libmng                                                     * */
-/* * file      : libmng_chunks.h           copyright (c) 2000-2007 G.Juyn   * */
-/* * version   : 1.0.10                                                     * */
-/* *                                                                        * */
-/* * purpose   : Chunk structures (definition)                              * */
-/* *                                                                        * */
-/* * author    : G.Juyn                                                     * */
-/* *                                                                        * */
-/* * comment   : Definition of known chunk structures                       * */
-/* *                                                                        * */
-/* * changes   : 0.5.1 - 05/04/2000 - G.Juyn                                * */
-/* *             - put in some extra comments                               * */
-/* *             0.5.1 - 05/06/2000 - G.Juyn                                * */
-/* *             - fixed layout for sBIT, PPLT                              * */
-/* *             0.5.1 - 05/08/2000 - G.Juyn                                * */
-/* *             - changed write callback definition                        * */
-/* *             - changed strict-ANSI stuff                                * */
-/* *             0.5.1 - 05/11/2000 - G.Juyn                                * */
-/* *             - fixed layout for PPLT again (missed deltatype ?!?)       * */
-/* *                                                                        * */
-/* *             0.5.2 - 05/31/2000 - G.Juyn                                * */
-/* *             - removed useless definition (contributed by Tim Rowley)   * */
-/* *             0.5.2 - 06/03/2000 - G.Juyn                                * */
-/* *             - fixed makeup for Linux gcc compile                       * */
-/* *                                                                        * */
-/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
-/* *             - changed file-prefixes                                    * */
-/* *                                                                        * */
-/* *             0.9.3 - 08/26/2000 - G.Juyn                                * */
-/* *             - added MAGN chunk                                         * */
-/* *             0.9.3 - 09/10/2000 - G.Juyn                                * */
-/* *             - fixed DEFI behavior                                      * */
-/* *             0.9.3 - 10/16/2000 - G.Juyn                                * */
-/* *             - added JDAA chunk                                         * */
-/* *                                                                        * */
-/* *             1.0.5 - 08/19/2002 - G.Juyn                                * */
-/* *             - added HLAPI function to copy chunks                      * */
-/* *             1.0.5 - 09/14/2002 - G.Juyn                                * */
-/* *             - added event handling for dynamic MNG                     * */
-/* *             1.0.5 - 11/28/2002 - G.Juyn                                * */
-/* *             - fixed definition of iMethodX/Y for MAGN chunk            * */
-/* *                                                                        * */
-/* *             1.0.6 - 05/25/2003 - G.R-P                                 * */
-/* *               added MNG_SKIPCHUNK_cHNK footprint optimizations         * */
-/* *             1.0.6 - 07/29/2003 - G.R-P                                 * */
-/* *             - added conditionals around PAST chunk support             * */
-/* *                                                                        * */
-/* *             1.0.7 - 03/24/2004 - G.R-P                                 * */
-/* *             - added conditional around MNG_NO_DELTA_PNG support        * */
-/* *                                                                        * */
-/* *             1.0.9 - 12/05/2004 - G.Juyn                                * */
-/* *             - added conditional MNG_OPTIMIZE_CHUNKINITFREE             * */
-/* *             1.0.9 - 12/06/2004 - G.Juyn                                * */
-/* *             - added conditional MNG_OPTIMIZE_CHUNKREADER               * */
-/* *                                                                        * */
-/* *             1.0.10 - 04/08/2007 - G.Juyn                               * */
-/* *             - added support for mPNG proposal                          * */
-/* *             1.0.10 - 04/12/2007 - G.Juyn                               * */
-/* *             - added support for ANG proposal                           * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
-#pragma option -A                      /* force ANSI-C */
-#endif
-
-#ifndef _libmng_chunks_h_
-#define _libmng_chunks_h_
-
-/* ************************************************************************** */
-
-#ifdef MNG_SWAP_ENDIAN
-#define PNG_SIG 0x474e5089L
-#define JNG_SIG 0x474e4a8bL
-#define MNG_SIG 0x474e4d8aL
-#define POST_SIG 0x0a1a0a0dL
-#else
-#define PNG_SIG 0x89504e47L
-#define JNG_SIG 0x8b4a4e47L
-#define MNG_SIG 0x8a4d4e47L
-#define POST_SIG 0x0d0a1a0aL
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_OPTIMIZE_CHUNKREADER
-
-typedef mng_retcode (*mng_f_specialfunc)  (mng_datap   pData,
-                                           mng_chunkp  pChunk,
-                                           mng_uint32* piRawlen,
-                                           mng_uint8p* ppRawdata);
-                                           
-typedef mng_retcode (*mng_c_specialfunc)  (mng_datap  pData,
-                                           mng_chunkp pChunk);
-
-#define MNG_FIELD_OPTIONAL    0x0001
-#define MNG_FIELD_TERMINATOR  0x0002
-#define MNG_FIELD_REPETITIVE  0x0004
-#define MNG_FIELD_DEFLATED    0x0008
-#define MNG_FIELD_IFIMGTYPES  0x01F0   /* image-type mask */
-#define MNG_FIELD_IFIMGTYPE0  0x0010
-#define MNG_FIELD_IFIMGTYPE2  0x0020
-#define MNG_FIELD_IFIMGTYPE3  0x0040
-#define MNG_FIELD_IFIMGTYPE4  0x0080
-#define MNG_FIELD_IFIMGTYPE6  0x0100
-#define MNG_FIELD_PUTIMGTYPE  0x0200
-#define MNG_FIELD_NOHIGHBIT   0x0400
-#define MNG_FIELD_GROUPMASK   0x7000
-#define MNG_FIELD_GROUP1      0x1000
-#define MNG_FIELD_GROUP2      0x2000
-#define MNG_FIELD_GROUP3      0x3000
-#define MNG_FIELD_GROUP4      0x4000
-#define MNG_FIELD_GROUP5      0x5000
-#define MNG_FIELD_GROUP6      0x6000
-#define MNG_FIELD_GROUP7      0x7000
-#define MNG_FIELD_INT         0x8000
-
-typedef struct {                       /* chunk-field descriptor */
-           mng_f_specialfunc pSpecialfunc;
-           mng_uint16        iFlags;
-           mng_uint16        iMinvalue;
-           mng_uint16        iMaxvalue;
-           mng_uint16        iLengthmin;
-           mng_uint16        iLengthmax;
-           mng_uint16        iOffsetchunk;
-           mng_uint16        iOffsetchunkind;
-           mng_uint16        iOffsetchunklen;
-        } mng_field_descriptor;
-typedef mng_field_descriptor * mng_field_descp;
-
-#define MNG_DESCR_GLOBAL      0x0001
-#define MNG_DESCR_EMPTY       0x0002
-#define MNG_DESCR_EMPTYEMBED  0x0006
-#define MNG_DESCR_EMPTYGLOBAL 0x000A
-
-#define MNG_DESCR_GenHDR      0x0001   /* IHDR/JHDR/BASI/DHDR */
-#define MNG_DESCR_JngHDR      0x0002   /* JHDR/DHDR */
-#define MNG_DESCR_MHDR        0x0004
-#define MNG_DESCR_IHDR        0x0008
-#define MNG_DESCR_JHDR        0x0010
-#define MNG_DESCR_DHDR        0x0020
-#define MNG_DESCR_LOOP        0x0040
-#define MNG_DESCR_PLTE        0x0080
-#define MNG_DESCR_SAVE        0x0100
-
-#define MNG_DESCR_NOIHDR      0x0001
-#define MNG_DESCR_NOJHDR      0x0002
-#define MNG_DESCR_NOBASI      0x0004
-#define MNG_DESCR_NODHDR      0x0008
-#define MNG_DESCR_NOIDAT      0x0010
-#define MNG_DESCR_NOJDAT      0x0020
-#define MNG_DESCR_NOJDAA      0x0040
-#define MNG_DESCR_NOPLTE      0x0080
-#define MNG_DESCR_NOJSEP      0x0100
-#define MNG_DESCR_NOMHDR      0x0200
-#define MNG_DESCR_NOTERM      0x0400
-#define MNG_DESCR_NOLOOP      0x0800
-#define MNG_DESCR_NOSAVE      0x1000
-
-typedef struct {                       /* chunk descriptor */
-           mng_imgtype       eImgtype;
-           mng_createobjtype eCreateobject;
-           mng_uint16        iObjsize;
-           mng_uint16        iOffsetempty;
-           mng_ptr           pObjcleanup;
-           mng_ptr           pObjprocess;
-           mng_c_specialfunc pSpecialfunc;
-           mng_field_descp   pFielddesc;
-           mng_uint16        iFielddesc;
-           mng_uint16        iAllowed;
-           mng_uint16        iMusthaves;
-           mng_uint16        iMustNOThaves;
-        } mng_chunk_descriptor;
-typedef mng_chunk_descriptor * mng_chunk_descp;
-
-#endif /* MNG_OPTIMIZE_CHUNKREADER */
-
-/* ************************************************************************** */
-
-typedef mng_retcode (*mng_createchunk)  (mng_datap   pData,
-                                         mng_chunkp  pHeader,
-                                         mng_chunkp* ppChunk);
-
-typedef mng_retcode (*mng_cleanupchunk) (mng_datap   pData,
-                                         mng_chunkp  pHeader);
-
-typedef mng_retcode (*mng_readchunk)    (mng_datap   pData,
-                                         mng_chunkp  pHeader,
-                                         mng_uint32  iRawlen,
-                                         mng_uint8p  pRawdata,
-                                         mng_chunkp* pChunk);
-
-typedef mng_retcode (*mng_writechunk)   (mng_datap   pData,
-                                         mng_chunkp  pChunk);
-
-typedef mng_retcode (*mng_assignchunk)  (mng_datap   pData,
-                                         mng_chunkp  pChunkto,
-                                         mng_chunkp  pChunkfrom);
-
-/* ************************************************************************** */
-
-typedef struct {                       /* generic header */
-           mng_chunkid       iChunkname;
-           mng_createchunk   fCreate;
-           mng_cleanupchunk  fCleanup;
-           mng_readchunk     fRead;
-           mng_writechunk    fWrite;
-           mng_assignchunk   fAssign;
-           mng_chunkp        pNext;    /* for double-linked list */
-           mng_chunkp        pPrev;
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-           mng_size_t        iChunksize;
-#endif
-#ifdef MNG_OPTIMIZE_CHUNKREADER
-           mng_chunk_descp   pChunkdescr;
-#endif
-        } mng_chunk_header;
-typedef mng_chunk_header * mng_chunk_headerp;
-
-/* ************************************************************************** */
-
-typedef struct {                       /* IHDR */
-           mng_chunk_header  sHeader;
-           mng_uint32        iWidth;
-           mng_uint32        iHeight;
-           mng_uint8         iBitdepth;
-           mng_uint8         iColortype;
-           mng_uint8         iCompression;
-           mng_uint8         iFilter;
-           mng_uint8         iInterlace;
-        } mng_ihdr;
-typedef mng_ihdr * mng_ihdrp;
-
-/* ************************************************************************** */
-
-typedef struct {                       /* PLTE */
-           mng_chunk_header  sHeader;
-           mng_bool          bEmpty;
-           mng_uint32        iEntrycount;
-           mng_rgbpaltab     aEntries;
-        } mng_plte;
-typedef mng_plte * mng_pltep;
-
-/* ************************************************************************** */
-
-typedef struct {                       /* IDAT */
-           mng_chunk_header  sHeader;
-           mng_bool          bEmpty;
-           mng_uint32        iDatasize;
-           mng_ptr           pData;
-        } mng_idat;
-typedef mng_idat * mng_idatp;
-
-/* ************************************************************************** */
-
-typedef struct {                       /* IEND */
-           mng_chunk_header  sHeader;
-        } mng_iend;
-typedef mng_iend * mng_iendp;
-
-/* ************************************************************************** */
-
-typedef struct {                       /* tRNS */
-           mng_chunk_header  sHeader;
-           mng_bool          bEmpty;
-           mng_bool          bGlobal;
-           mng_uint8         iType;    /* colortype (0,2,3) */
-           mng_uint32        iCount;
-           mng_uint8arr      aEntries;
-           mng_uint16        iGray;
-           mng_uint16        iRed;
-           mng_uint16        iGreen;
-           mng_uint16        iBlue;
-           mng_uint32        iRawlen;
-           mng_uint8arr      aRawdata;
-        } mng_trns;
-typedef mng_trns * mng_trnsp;
-
-/* ************************************************************************** */
-
-typedef struct {                       /* gAMA */
-           mng_chunk_header  sHeader;
-           mng_bool          bEmpty;
-           mng_uint32        iGamma;
-        } mng_gama;
-typedef mng_gama * mng_gamap;
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_cHRM
-typedef struct {                       /* cHRM */
-           mng_chunk_header  sHeader;
-           mng_bool          bEmpty;
-           mng_uint32        iWhitepointx;
-           mng_uint32        iWhitepointy;
-           mng_uint32        iRedx;
-           mng_uint32        iRedy;
-           mng_uint32        iGreenx;
-           mng_uint32        iGreeny;
-           mng_uint32        iBluex;
-           mng_uint32        iBluey;
-        } mng_chrm;
-typedef mng_chrm * mng_chrmp;
-#endif
-
-/* ************************************************************************** */
-
-typedef struct {                       /* sRGB */
-           mng_chunk_header  sHeader;
-           mng_bool          bEmpty;
-           mng_uint8         iRenderingintent;
-        } mng_srgb;
-typedef mng_srgb * mng_srgbp;
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_iCCP
-typedef struct {                       /* iCCP */
-           mng_chunk_header  sHeader;
-           mng_bool          bEmpty;
-           mng_uint32        iNamesize;
-           mng_pchar         zName;
-           mng_uint8         iCompression;
-           mng_uint32        iProfilesize;
-           mng_ptr           pProfile;
-        } mng_iccp;
-typedef mng_iccp * mng_iccpp;
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_tEXt
-typedef struct {                       /* tEXt */
-           mng_chunk_header  sHeader;
-           mng_uint32        iKeywordsize;
-           mng_pchar         zKeyword;
-           mng_uint32        iTextsize;
-           mng_pchar         zText;
-        } mng_text;
-typedef mng_text * mng_textp;
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_zTXt
-typedef struct {                       /* zTXt */
-           mng_chunk_header  sHeader;
-           mng_uint32        iKeywordsize;
-           mng_pchar         zKeyword;
-           mng_uint8         iCompression;
-           mng_uint32        iTextsize;
-           mng_pchar         zText;
-        } mng_ztxt;
-typedef mng_ztxt * mng_ztxtp;
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_iTXt
-typedef struct {                       /* iTXt */
-           mng_chunk_header  sHeader;
-           mng_uint32        iKeywordsize;
-           mng_pchar         zKeyword;
-           mng_uint8         iCompressionflag;
-           mng_uint8         iCompressionmethod;
-           mng_uint32        iLanguagesize;
-           mng_pchar         zLanguage;
-           mng_uint32        iTranslationsize;
-           mng_pchar         zTranslation;
-           mng_uint32        iTextsize;
-           mng_pchar         zText;
-        } mng_itxt;
-typedef mng_itxt * mng_itxtp;
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_bKGD
-typedef struct {                       /* bKGD */
-           mng_chunk_header  sHeader;
-           mng_bool          bEmpty;
-           mng_uint8         iType;    /* 3=indexed, 0=gray, 2=rgb */
-           mng_uint8         iIndex;
-           mng_uint16        iGray;
-           mng_uint16        iRed;
-           mng_uint16        iGreen;
-           mng_uint16        iBlue;
-        } mng_bkgd;
-typedef mng_bkgd * mng_bkgdp;
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_pHYs
-typedef struct {                       /* pHYs */
-           mng_chunk_header  sHeader;
-           mng_bool          bEmpty;
-           mng_uint32        iSizex;
-           mng_uint32        iSizey;
-           mng_uint8         iUnit;
-        } mng_phys;
-typedef mng_phys * mng_physp;
-#endif
-
-/* ************************************************************************** */
-#ifndef MNG_SKIPCHUNK_sBIT
-
-typedef struct {                       /* sBIT */
-           mng_chunk_header  sHeader;
-           mng_bool          bEmpty;
-           mng_uint8         iType;    /* colortype (0,2,3,4,6,10,12,14,16) */
-           mng_uint8arr4     aBits;
-        } mng_sbit;
-typedef mng_sbit * mng_sbitp;
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_sPLT
-typedef struct {                       /* sPLT */
-           mng_chunk_header  sHeader;
-           mng_bool          bEmpty;
-           mng_uint32        iNamesize;
-           mng_pchar         zName;
-           mng_uint8         iSampledepth;
-           mng_uint32        iEntrycount;
-           mng_ptr           pEntries;
-        } mng_splt;
-typedef mng_splt * mng_spltp;
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_hIST
-typedef struct {                       /* hIST */
-           mng_chunk_header  sHeader;
-           mng_uint32        iEntrycount;
-           mng_uint16arr     aEntries;
-        } mng_hist;
-typedef mng_hist * mng_histp;
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_tIME
-typedef struct {                       /* tIME */
-           mng_chunk_header  sHeader;
-           mng_uint16        iYear;
-           mng_uint8         iMonth;
-           mng_uint8         iDay;
-           mng_uint8         iHour;
-           mng_uint8         iMinute;
-           mng_uint8         iSecond;
-        } mng_time;
-typedef mng_time * mng_timep;
-#endif
-
-/* ************************************************************************** */
-
-typedef struct {                       /* MHDR */
-           mng_chunk_header  sHeader;
-           mng_uint32        iWidth;
-           mng_uint32        iHeight;
-           mng_uint32        iTicks;
-           mng_uint32        iLayercount;
-           mng_uint32        iFramecount;
-           mng_uint32        iPlaytime;
-           mng_uint32        iSimplicity;
-        } mng_mhdr;
-typedef mng_mhdr * mng_mhdrp;
-
-/* ************************************************************************** */
-
-typedef struct {                       /* MEND */
-           mng_chunk_header  sHeader;
-        } mng_mend;
-typedef mng_mend * mng_mendp;
-
-/* ************************************************************************** */
-
-typedef struct {                       /* LOOP */
-           mng_chunk_header  sHeader;
-           mng_uint8         iLevel;
-           mng_uint32        iRepeat;
-           mng_uint8         iTermination;
-           mng_uint32        iItermin;
-           mng_uint32        iItermax;
-           mng_uint32        iCount;
-           mng_uint32p       pSignals;
-        } mng_loop;
-typedef mng_loop * mng_loopp;
-
-/* ************************************************************************** */
-
-typedef struct {                       /* ENDL */
-           mng_chunk_header  sHeader;
-           mng_uint8         iLevel;
-        } mng_endl;
-typedef mng_endl * mng_endlp;
-
-/* ************************************************************************** */
-
-typedef struct {                       /* DEFI */
-           mng_chunk_header  sHeader;
-           mng_uint16        iObjectid;
-           mng_bool          bHasdonotshow;
-           mng_uint8         iDonotshow;
-           mng_bool          bHasconcrete;
-           mng_uint8         iConcrete;
-           mng_bool          bHasloca;
-           mng_int32         iXlocation;
-           mng_int32         iYlocation;
-           mng_bool          bHasclip;
-           mng_int32         iLeftcb;
-           mng_int32         iRightcb;
-           mng_int32         iTopcb;
-           mng_int32         iBottomcb;
-        } mng_defi;
-typedef mng_defi * mng_defip;
-
-/* ************************************************************************** */
-
-typedef struct {                       /* BASI */
-           mng_chunk_header  sHeader;
-           mng_uint32        iWidth;
-           mng_uint32        iHeight;
-           mng_uint8         iBitdepth;
-           mng_uint8         iColortype;
-           mng_uint8         iCompression;
-           mng_uint8         iFilter;
-           mng_uint8         iInterlace;
-           mng_uint16        iRed;
-           mng_uint16        iGreen;
-           mng_uint16        iBlue;
-#ifdef MNG_OPTIMIZE_CHUNKREADER
-           mng_bool          bHasalpha;
-#endif
-           mng_uint16        iAlpha;
-           mng_uint8         iViewable;
-        } mng_basi;
-typedef mng_basi * mng_basip;
-
-/* ************************************************************************** */
-
-typedef struct {                       /* CLON */
-           mng_chunk_header  sHeader;
-           mng_uint16        iSourceid;
-           mng_uint16        iCloneid;
-           mng_uint8         iClonetype;
-#ifdef MNG_OPTIMIZE_CHUNKREADER
-           mng_bool          bHasdonotshow;
-#endif
-           mng_uint8         iDonotshow;
-           mng_uint8         iConcrete;
-           mng_bool          bHasloca;
-           mng_uint8         iLocationtype;
-           mng_int32         iLocationx;
-           mng_int32         iLocationy;
-        } mng_clon;
-typedef mng_clon * mng_clonp;
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_PAST
-typedef struct {                       /* PAST source */
-           mng_uint16        iSourceid;
-           mng_uint8         iComposition;
-           mng_uint8         iOrientation;
-           mng_uint8         iOffsettype;
-           mng_int32         iOffsetx;
-           mng_int32         iOffsety;
-           mng_uint8         iBoundarytype;
-           mng_int32         iBoundaryl;
-           mng_int32         iBoundaryr;
-           mng_int32         iBoundaryt;
-           mng_int32         iBoundaryb;
-        } mng_past_source;
-typedef mng_past_source * mng_past_sourcep;
-
-typedef struct {                       /* PAST */
-           mng_chunk_header  sHeader;
-           mng_uint16        iDestid;
-           mng_uint8         iTargettype;
-           mng_int32         iTargetx;
-           mng_int32         iTargety;
-           mng_uint32        iCount;
-           mng_past_sourcep  pSources;
-        } mng_past;
-typedef mng_past * mng_pastp;
-#endif
-
-/* ************************************************************************** */
-
-typedef struct {                       /* DISC */
-           mng_chunk_header  sHeader;
-           mng_uint32        iCount;
-           mng_uint16p       pObjectids;
-        } mng_disc;
-typedef mng_disc * mng_discp;
-
-/* ************************************************************************** */
-
-typedef struct {                       /* BACK */
-           mng_chunk_header  sHeader;
-           mng_uint16        iRed;
-           mng_uint16        iGreen;
-           mng_uint16        iBlue;
-           mng_uint8         iMandatory;
-           mng_uint16        iImageid;
-           mng_uint8         iTile;
-        } mng_back;
-typedef mng_back * mng_backp;
-
-/* ************************************************************************** */
-
-typedef struct {                       /* FRAM */
-           mng_chunk_header  sHeader;
-           mng_bool          bEmpty;
-           mng_uint8         iMode;
-           mng_uint32        iNamesize;
-           mng_pchar         zName;
-           mng_uint8         iChangedelay;
-           mng_uint8         iChangetimeout;
-           mng_uint8         iChangeclipping;
-           mng_uint8         iChangesyncid;
-           mng_uint32        iDelay;
-           mng_uint32        iTimeout;
-           mng_uint8         iBoundarytype;
-           mng_int32         iBoundaryl;
-           mng_int32         iBoundaryr;
-           mng_int32         iBoundaryt;
-           mng_int32         iBoundaryb;
-           mng_uint32        iCount;
-           mng_uint32p       pSyncids;
-        } mng_fram;
-typedef mng_fram * mng_framp;
-
-/* ************************************************************************** */
-
-typedef struct {                       /* MOVE */
-           mng_chunk_header  sHeader;
-           mng_uint16        iFirstid;
-           mng_uint16        iLastid;
-           mng_uint8         iMovetype;
-           mng_int32         iMovex;
-           mng_int32         iMovey;
-        } mng_move;
-typedef mng_move * mng_movep;
-
-/* ************************************************************************** */
-
-typedef struct {                       /* CLIP */
-           mng_chunk_header  sHeader;
-           mng_uint16        iFirstid;
-           mng_uint16        iLastid;
-           mng_uint8         iCliptype;
-           mng_int32         iClipl;
-           mng_int32         iClipr;
-           mng_int32         iClipt;
-           mng_int32         iClipb;
-        } mng_clip;
-typedef mng_clip * mng_clipp;
-
-/* ************************************************************************** */
-
-typedef struct {                       /* SHOW */
-           mng_chunk_header  sHeader;
-           mng_bool          bEmpty;
-           mng_uint16        iFirstid;
-#ifdef MNG_OPTIMIZE_CHUNKREADER
-           mng_bool          bHaslastid;
-#endif
-           mng_uint16        iLastid;
-           mng_uint8         iMode;
-        } mng_show;
-typedef mng_show * mng_showp;
-
-/* ************************************************************************** */
-
-typedef struct {                       /* TERM */
-           mng_chunk_header  sHeader;
-           mng_uint8         iTermaction;
-           mng_uint8         iIteraction;
-           mng_uint32        iDelay;
-           mng_uint32        iItermax;
-        } mng_term;
-typedef mng_term * mng_termp;
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_SAVE
-typedef struct {                       /* SAVE entry */
-           mng_uint8         iEntrytype;
-           mng_uint32arr2    iOffset;            /* 0=MSI, 1=LSI */
-           mng_uint32arr2    iStarttime;         /* 0=MSI, 1=LSI */
-           mng_uint32        iLayernr;
-           mng_uint32        iFramenr;
-           mng_uint32        iNamesize;
-           mng_pchar         zName;
-        } mng_save_entry;
-typedef mng_save_entry * mng_save_entryp;
-
-typedef struct {                       /* SAVE */
-           mng_chunk_header  sHeader;
-           mng_bool          bEmpty;
-           mng_uint8         iOffsettype;
-           mng_uint32        iCount;
-           mng_save_entryp   pEntries;
-        } mng_save;
-typedef mng_save * mng_savep;
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_SEEK
-typedef struct {                       /* SEEK */
-           mng_chunk_header  sHeader;
-           mng_uint32        iNamesize;
-           mng_pchar         zName;
-        } mng_seek;
-typedef mng_seek * mng_seekp;
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_eXPI
-typedef struct {                       /* eXPI */
-           mng_chunk_header  sHeader;
-           mng_uint16        iSnapshotid;
-           mng_uint32        iNamesize;
-           mng_pchar         zName;
-        } mng_expi;
-typedef mng_expi * mng_expip;
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_fPRI
-typedef struct {                       /* fPRI */
-           mng_chunk_header  sHeader;
-           mng_uint8         iDeltatype;
-           mng_uint8         iPriority;
-        } mng_fpri;
-typedef mng_fpri * mng_fprip;
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_nEED
-typedef struct {                       /* nEED */
-           mng_chunk_header  sHeader;
-           mng_uint32        iKeywordssize;
-           mng_pchar         zKeywords;
-        } mng_need;
-typedef mng_need * mng_needp;
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_pHYg
-typedef mng_phys mng_phyg;             /* pHYg */
-typedef mng_phyg * mng_phygp;
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-
-typedef struct {                       /* JHDR */
-           mng_chunk_header  sHeader;
-           mng_uint32        iWidth;
-           mng_uint32        iHeight;
-           mng_uint8         iColortype;
-           mng_uint8         iImagesampledepth;
-           mng_uint8         iImagecompression;
-           mng_uint8         iImageinterlace;
-           mng_uint8         iAlphasampledepth;
-           mng_uint8         iAlphacompression;
-           mng_uint8         iAlphafilter;
-           mng_uint8         iAlphainterlace;
-        } mng_jhdr;
-typedef mng_jhdr * mng_jhdrp;
-
-/* ************************************************************************** */
-
-typedef mng_idat mng_jdaa;             /* JDAA */
-typedef mng_jdaa * mng_jdaap;
-
-/* ************************************************************************** */
-
-typedef mng_idat mng_jdat;             /* JDAT */
-typedef mng_jdat * mng_jdatp;
-
-/* ************************************************************************** */
-
-typedef struct {                       /* JSEP */
-           mng_chunk_header  sHeader;
-        } mng_jsep;
-typedef mng_jsep * mng_jsepp;
-
-#endif /* MNG_INCLUDE_JNG */
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-
-typedef struct {                       /* DHDR */
-           mng_chunk_header  sHeader;
-           mng_uint16        iObjectid;
-           mng_uint8         iImagetype;
-           mng_uint8         iDeltatype;
-#ifdef MNG_OPTIMIZE_CHUNKREADER
-           mng_bool          bHasblocksize;
-#endif
-           mng_uint32        iBlockwidth;
-           mng_uint32        iBlockheight;
-#ifdef MNG_OPTIMIZE_CHUNKREADER
-           mng_bool          bHasblockloc;
-#endif
-           mng_uint32        iBlockx;
-           mng_uint32        iBlocky;
-        } mng_dhdr;
-typedef mng_dhdr * mng_dhdrp;
-
-/* ************************************************************************** */
-
-typedef struct {                       /* PROM */
-           mng_chunk_header  sHeader;
-           mng_uint8         iColortype;
-           mng_uint8         iSampledepth;
-           mng_uint8         iFilltype;
-        } mng_prom;
-typedef mng_prom * mng_promp;
-
-/* ************************************************************************** */
-
-typedef struct {                       /* IPNG */
-           mng_chunk_header  sHeader;
-        } mng_ipng;
-typedef mng_ipng *mng_ipngp;
-
-/* ************************************************************************** */
-
-typedef struct {                       /* PPLT entry */
-           mng_uint8         iRed;
-           mng_uint8         iGreen;
-           mng_uint8         iBlue;
-           mng_uint8         iAlpha;
-           mng_bool          bUsed;
-        } mng_pplt_entry;
-typedef mng_pplt_entry * mng_pplt_entryp;
-
-typedef struct {                       /* PPLT */
-           mng_chunk_header  sHeader;
-           mng_uint8         iDeltatype;
-           mng_uint32        iCount;
-           mng_pplt_entry    aEntries [256];
-        } mng_pplt;
-typedef mng_pplt * mng_ppltp;
-
-/* ************************************************************************** */
-
-typedef struct {                       /* IJNG */
-           mng_chunk_header  sHeader;
-        } mng_ijng;
-typedef mng_ijng *mng_ijngp;
-
-/* ************************************************************************** */
-
-typedef struct {                       /* DROP */
-           mng_chunk_header  sHeader;
-           mng_uint32        iCount;
-           mng_chunkidp      pChunknames;
-        } mng_drop;
-typedef mng_drop * mng_dropp;
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_DBYK
-typedef struct {                       /* DBYK */
-           mng_chunk_header  sHeader;
-           mng_chunkid       iChunkname;
-           mng_uint8         iPolarity;
-           mng_uint32        iKeywordssize;
-           mng_pchar         zKeywords;
-        } mng_dbyk;
-typedef mng_dbyk * mng_dbykp;
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_ORDR
-typedef struct {                       /* ORDR entry */
-           mng_chunkid       iChunkname;
-           mng_uint8         iOrdertype;
-        } mng_ordr_entry;
-typedef mng_ordr_entry * mng_ordr_entryp;
-
-typedef struct mng_ordr_struct {       /* ORDR */
-           mng_chunk_header  sHeader;
-           mng_uint32        iCount;
-           mng_ordr_entryp   pEntries;
-        } mng_ordr;
-typedef mng_ordr * mng_ordrp;
-#endif
-#endif /* MNG_NO_DELTA_PNG */
-
-/* ************************************************************************** */
-
-typedef struct {                       /* MAGN */
-           mng_chunk_header  sHeader;
-           mng_uint16        iFirstid;
-           mng_uint16        iLastid;
-           mng_uint8         iMethodX;
-           mng_uint16        iMX;
-           mng_uint16        iMY;
-           mng_uint16        iML;
-           mng_uint16        iMR;
-           mng_uint16        iMT;
-           mng_uint16        iMB;
-           mng_uint8         iMethodY;
-        } mng_magn;
-typedef mng_magn * mng_magnp;
-
-/* ************************************************************************** */
-
-typedef struct {                       /* evNT entry */
-           mng_uint8         iEventtype;
-           mng_uint8         iMasktype;
-           mng_int32         iLeft;
-           mng_int32         iRight;
-           mng_int32         iTop;
-           mng_int32         iBottom;
-           mng_uint16        iObjectid;
-           mng_uint8         iIndex;
-           mng_uint32        iSegmentnamesize;
-           mng_pchar         zSegmentname;
-        } mng_evnt_entry;
-typedef mng_evnt_entry * mng_evnt_entryp;
-
-typedef struct {                       /* evNT */
-           mng_chunk_header  sHeader;
-           mng_uint32        iCount;
-           mng_evnt_entryp   pEntries;
-        } mng_evnt;
-typedef mng_evnt * mng_evntp;
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-typedef struct {                       /* mpNG frame */
-           mng_uint32        iX;
-           mng_uint32        iY;
-           mng_uint32        iWidth;
-           mng_uint32        iHeight;
-           mng_int32         iXoffset;
-           mng_int32         iYoffset;
-           mng_uint16        iTicks;
-        } mng_mpng_frame;
-typedef mng_mpng_frame * mng_mpng_framep;
-
-typedef struct {                       /* mpNG */
-           mng_chunk_header  sHeader;
-           mng_uint32        iFramewidth;
-           mng_uint32        iFrameheight;
-           mng_uint16        iNumplays;
-           mng_uint16        iTickspersec;
-           mng_uint8         iCompressionmethod;
-           mng_uint32        iFramessize;
-           mng_mpng_framep   pFrames;
-        } mng_mpng;
-typedef mng_mpng * mng_mpngp;
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_ANG_PROPOSAL
-typedef struct {                       /* ahDR */
-           mng_chunk_header  sHeader;
-           mng_uint32        iNumframes;
-           mng_uint32        iTickspersec;
-           mng_uint32        iNumplays;
-           mng_uint32        iTilewidth;
-           mng_uint32        iTileheight;
-           mng_uint8         iInterlace;
-           mng_uint8         iStillused;
-        } mng_ahdr;
-typedef mng_ahdr * mng_ahdrp;
-
-typedef struct {                       /* adAT tile */
-           mng_uint32        iTicks;
-           mng_int32         iXoffset;
-           mng_int32         iYoffset;
-           mng_uint8         iTilesource;
-        } mng_adat_tile;
-typedef mng_adat_tile * mng_adat_tilep;
-
-typedef struct {                       /* adAT */
-           mng_chunk_header  sHeader;
-           mng_uint32        iTilessize;
-           mng_adat_tilep    pTiles;
-        } mng_adat;
-typedef mng_adat * mng_adatp;
-#endif
-
-/* ************************************************************************** */
-
-typedef struct {                       /* unknown chunk */
-           mng_chunk_header  sHeader;
-           mng_uint32        iDatasize;
-           mng_ptr           pData;
-        } mng_unknown_chunk;
-typedef mng_unknown_chunk * mng_unknown_chunkp;
-
-/* ************************************************************************** */
-
-#endif /* _libmng_chunks_h_ */
-
-/* ************************************************************************** */
-/* * end of file                                                            * */
-/* ************************************************************************** */
diff --git a/Source/LibMNG/libmng_cms.c b/Source/LibMNG/libmng_cms.c
deleted file mode 100644
index f215271..0000000
--- a/Source/LibMNG/libmng_cms.c
+++ /dev/null
@@ -1,758 +0,0 @@
-/* ************************************************************************** */
-/* *             For conditions of distribution and use,                    * */
-/* *                see copyright notice in libmng.h                        * */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * project   : libmng                                                     * */
-/* * file      : libmng_cms.c              copyright (c) 2000-2004 G.Juyn   * */
-/* * version   : 1.0.9                                                      * */
-/* *                                                                        * */
-/* * purpose   : color management routines (implementation)                 * */
-/* *                                                                        * */
-/* * author    : G.Juyn                                                     * */
-/* *                                                                        * */
-/* * comment   : implementation of the color management routines            * */
-/* *                                                                        * */
-/* * changes   : 0.5.1 - 05/01/2000 - G.Juyn                                * */
-/* *             - B001(105795) - fixed a typo and misconception about      * */
-/* *               freeing allocated gamma-table. (reported by Marti Maria) * */
-/* *             0.5.1 - 05/08/2000 - G.Juyn                                * */
-/* *             - changed strict-ANSI stuff                                * */
-/* *             0.5.1 - 05/09/2000 - G.Juyn                                * */
-/* *             - filled application-based color-management routines       * */
-/* *             0.5.1 - 05/11/2000 - G.Juyn                                * */
-/* *             - added creatememprofile                                   * */
-/* *             - added callback error-reporting support                   * */
-/* *             0.5.1 - 05/12/2000 - G.Juyn                                * */
-/* *             - changed trace to macro for callback error-reporting      * */
-/* *                                                                        * */
-/* *             0.5.2 - 06/10/2000 - G.Juyn                                * */
-/* *             - fixed some compilation-warnings (contrib Jason Morris)   * */
-/* *                                                                        * */
-/* *             0.5.3 - 06/21/2000 - G.Juyn                                * */
-/* *             - fixed problem with color-correction for stored images    * */
-/* *             0.5.3 - 06/23/2000 - G.Juyn                                * */
-/* *             - fixed problem with incorrect gamma-correction            * */
-/* *                                                                        * */
-/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
-/* *             - changed file-prefixes                                    * */
-/* *                                                                        * */
-/* *             0.9.3 - 08/31/2000 - G.Juyn                                * */
-/* *             - fixed sRGB precedence for gamma_only corection           * */
-/* *                                                                        * */
-/* *             0.9.4 - 12/16/2000 - G.Juyn                                * */
-/* *             - fixed mixup of data- & function-pointers (thanks Dimitri)* */
-/* *                                                                        * */
-/* *             1.0.1 - 03/31/2001 - G.Juyn                                * */
-/* *             - ignore gamma=0 (see png-list for more info)              * */
-/* *             1.0.1 - 04/25/2001 - G.Juyn (reported by Gregg Kelly)      * */
-/* *             - fixed problem with cms profile being created multiple    * */
-/* *               times when both iCCP & cHRM/gAMA are present             * */
-/* *             1.0.1 - 04/25/2001 - G.Juyn                                * */
-/* *             - moved mng_clear_cms to libmng_cms                        * */
-/* *             1.0.1 - 05/02/2001 - G.Juyn                                * */
-/* *             - added "default" sRGB generation (Thanks Marti!)          * */
-/* *                                                                        * */
-/* *             1.0.5 - 08/19/2002 - G.Juyn                                * */
-/* *             - B597134 - libmng pollutes the linker namespace           * */
-/* *             1.0.5 - 09/19/2002 - G.Juyn                                * */
-/* *             - optimized color-correction routines                      * */
-/* *             1.0.5 - 09/23/2002 - G.Juyn                                * */
-/* *             - added in-memory color-correction of abstract images      * */
-/* *             1.0.5 - 11/08/2002 - G.Juyn                                * */
-/* *             - fixed issues in init_app_cms()                           * */
-/* *                                                                        * */
-/* *             1.0.6 - 04/11/2003 - G.Juyn                                * */
-/* *             - B719420 - fixed several MNG_APP_CMS problems             * */
-/* *             1.0.6 - 07/11/2003 - G. R-P                                * */
-/* *             - added conditional MNG_SKIPCHUNK_cHRM/iCCP                * */
-/* *                                                                        * */
-/* *             1.0.9 - 12/20/2004 - G.Juyn                                * */
-/* *             - cleaned up macro-invocations (thanks to D. Airlie)       * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#include "libmng.h"
-#include "libmng_data.h"
-#include "libmng_error.h"
-#include "libmng_trace.h"
-#ifdef __BORLANDC__
-#pragma hdrstop
-#endif
-#include "libmng_objects.h"
-#include "libmng_cms.h"
-
-#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
-#pragma option -A                      /* force ANSI-C */
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_DISPLAY_PROCS
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Little CMS helper routines                                             * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_LCMS
-
-#define MNG_CMS_FLAGS 0
-
-/* ************************************************************************** */
-
-void mnglcms_initlibrary ()
-{
-  cmsErrorAction (LCMS_ERROR_IGNORE);  /* LCMS should ignore errors! */
-}
-
-/* ************************************************************************** */
-
-mng_cmsprof mnglcms_createfileprofile (mng_pchar zFilename)
-{
-  return cmsOpenProfileFromFile (zFilename, "r");
-}
-
-/* ************************************************************************** */
-
-mng_cmsprof mnglcms_creatememprofile (mng_uint32 iProfilesize,
-                                      mng_ptr    pProfile)
-{
-  return cmsOpenProfileFromMem (pProfile, iProfilesize);
-}
-
-/* ************************************************************************** */
-
-mng_cmsprof mnglcms_createsrgbprofile (void)
-{
-  cmsCIExyY       D65;
-  cmsCIExyYTRIPLE Rec709Primaries = {
-                                      {0.6400, 0.3300, 1.0},
-                                      {0.3000, 0.6000, 1.0},
-                                      {0.1500, 0.0600, 1.0}
-                                    };
-  LPGAMMATABLE    Gamma24[3];
-  mng_cmsprof     hsRGB;
-
-  cmsWhitePointFromTemp(6504, &D65);
-  Gamma24[0] = Gamma24[1] = Gamma24[2] = cmsBuildGamma(256, 2.4);
-  hsRGB = cmsCreateRGBProfile(&D65, &Rec709Primaries, Gamma24);
-  cmsFreeGamma(Gamma24[0]);
-
-  return hsRGB;
-}
-
-/* ************************************************************************** */
-
-void mnglcms_freeprofile (mng_cmsprof hProf)
-{
-  cmsCloseProfile (hProf);
-  return;
-}
-
-/* ************************************************************************** */
-
-void mnglcms_freetransform (mng_cmstrans hTrans)
-{
-/* B001 start */
-  cmsDeleteTransform (hTrans);
-/* B001 end */
-  return;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_clear_cms (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CLEAR_CMS, MNG_LC_START);
-#endif
-
-  if (pData->hTrans)                   /* transformation still active ? */
-    mnglcms_freetransform (pData->hTrans);
-
-  pData->hTrans = 0;
-
-  if (pData->hProf1)                   /* file profile still active ? */
-    mnglcms_freeprofile (pData->hProf1);
-
-  pData->hProf1 = 0;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CLEAR_CMS, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#endif /* MNG_INCLUDE_LCMS */
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Color-management initialization & correction routines                  * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_LCMS
-
-mng_retcode mng_init_full_cms (mng_datap pData,
-                               mng_bool  bGlobal,
-                               mng_bool  bObject,
-                               mng_bool  bRetrobj)
-{
-  mng_cmsprof    hProf;
-  mng_cmstrans   hTrans;
-  mng_imagep     pImage = MNG_NULL;
-  mng_imagedatap pBuf   = MNG_NULL;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_FULL_CMS, MNG_LC_START);
-#endif
-
-  if (bObject)                         /* use object if present ? */
-  {                                    /* current object ? */
-    if ((mng_imagep)pData->pCurrentobj)
-      pImage = (mng_imagep)pData->pCurrentobj;
-    else                               /* if not; use object 0 */
-      pImage = (mng_imagep)pData->pObjzero;
-  }
-
-  if (bRetrobj)                        /* retrieving from an object ? */
-    pImage = (mng_imagep)pData->pRetrieveobj;
-
-  if (pImage)                          /* are we using an object ? */
-    pBuf = pImage->pImgbuf;            /* then address the buffer */
-
-  if ((!pBuf) || (!pBuf->bCorrected))  /* is the buffer already corrected ? */
-  {
-#ifndef MNG_SKIPCHUNK_iCCP
-    if (((pBuf) && (pBuf->bHasICCP)) || ((bGlobal) && (pData->bHasglobalICCP)))
-    {
-      if (!pData->hProf2)              /* output profile not defined ? */
-      {                                /* then assume sRGB !! */
-        pData->hProf2 = mnglcms_createsrgbprofile ();
-
-        if (!pData->hProf2)            /* handle error ? */
-          MNG_ERRORL (pData, MNG_LCMS_NOHANDLE);
-      }
-
-      if ((pBuf) && (pBuf->bHasICCP))  /* generate a profile handle */
-        hProf = cmsOpenProfileFromMem (pBuf->pProfile, pBuf->iProfilesize);
-      else
-        hProf = cmsOpenProfileFromMem (pData->pGlobalProfile, pData->iGlobalProfilesize);
-
-      pData->hProf1 = hProf;           /* save for future use */
-
-      if (!hProf)                      /* handle error ? */
-        MNG_ERRORL (pData, MNG_LCMS_NOHANDLE);
-
-#ifndef MNG_NO_16BIT_SUPPORT
-      if (pData->bIsRGBA16)            /* 16-bit intermediates ? */
-        hTrans = cmsCreateTransform (hProf,         TYPE_RGBA_16_SE,
-                                     pData->hProf2, TYPE_RGBA_16_SE,
-                                     INTENT_PERCEPTUAL, MNG_CMS_FLAGS);
-      else
-#endif
-        hTrans = cmsCreateTransform (hProf,         TYPE_RGBA_8,
-                                     pData->hProf2, TYPE_RGBA_8,
-                                     INTENT_PERCEPTUAL, MNG_CMS_FLAGS);
-
-      pData->hTrans = hTrans;          /* save for future use */
-
-      if (!hTrans)                     /* handle error ? */
-        MNG_ERRORL (pData, MNG_LCMS_NOTRANS);
-                                       /* load color-correction routine */
-      pData->fCorrectrow = (mng_fptr)mng_correct_full_cms;
-
-      return MNG_NOERROR;              /* and done */
-    }
-    else
-#endif
-    if (((pBuf) && (pBuf->bHasSRGB)) || ((bGlobal) && (pData->bHasglobalSRGB)))
-    {
-      mng_uint8 iIntent;
-
-      if (pData->bIssRGB)              /* sRGB system ? */
-        return MNG_NOERROR;            /* no conversion required */
-
-      if (!pData->hProf3)              /* sRGB profile not defined ? */
-      {                                /* then create it implicitly !! */
-        pData->hProf3 = mnglcms_createsrgbprofile ();
-
-        if (!pData->hProf3)            /* handle error ? */
-          MNG_ERRORL (pData, MNG_LCMS_NOHANDLE);
-      }
-
-      hProf = pData->hProf3;           /* convert from sRGB profile */
-
-      if ((pBuf) && (pBuf->bHasSRGB))  /* determine rendering intent */
-        iIntent = pBuf->iRenderingintent;
-      else
-        iIntent = pData->iGlobalRendintent;
-
-      if (pData->bIsRGBA16)            /* 16-bit intermediates ? */
-        hTrans = cmsCreateTransform (hProf,         TYPE_RGBA_16_SE,
-                                     pData->hProf2, TYPE_RGBA_16_SE,
-                                     iIntent, MNG_CMS_FLAGS);
-      else
-        hTrans = cmsCreateTransform (hProf,         TYPE_RGBA_8,
-                                     pData->hProf2, TYPE_RGBA_8,
-                                     iIntent, MNG_CMS_FLAGS);
-
-      pData->hTrans = hTrans;          /* save for future use */
-
-      if (!hTrans)                     /* handle error ? */
-        MNG_ERRORL (pData, MNG_LCMS_NOTRANS);
-                                       /* load color-correction routine */
-      pData->fCorrectrow = (mng_fptr)mng_correct_full_cms;
-
-      return MNG_NOERROR;              /* and done */
-    }
-    else
-    if ( (((pBuf) && (pBuf->bHasCHRM)) || ((bGlobal) && (pData->bHasglobalCHRM))) &&
-         ( ((pBuf) && (pBuf->bHasGAMA) && (pBuf->iGamma > 0)) ||
-           ((bGlobal) && (pData->bHasglobalGAMA) && (pData->iGlobalGamma > 0))  )    )
-    {
-      mng_CIExyY       sWhitepoint;
-      mng_CIExyYTRIPLE sPrimaries;
-      mng_gammatabp    pGammatable[3];
-      mng_float        dGamma;
-
-      if (!pData->hProf2)              /* output profile not defined ? */
-      {                                /* then assume sRGB !! */
-        pData->hProf2 = mnglcms_createsrgbprofile ();
-
-        if (!pData->hProf2)            /* handle error ? */
-          MNG_ERRORL (pData, MNG_LCMS_NOHANDLE);
-      }
-
-#ifndef MNG_SKIPCHUNK_cHRM
-      if ((pBuf) && (pBuf->bHasCHRM))  /* local cHRM ? */
-      {
-        sWhitepoint.x      = (mng_float)pBuf->iWhitepointx   / 100000;
-        sWhitepoint.y      = (mng_float)pBuf->iWhitepointy   / 100000;
-        sPrimaries.Red.x   = (mng_float)pBuf->iPrimaryredx   / 100000;
-        sPrimaries.Red.y   = (mng_float)pBuf->iPrimaryredy   / 100000;
-        sPrimaries.Green.x = (mng_float)pBuf->iPrimarygreenx / 100000;
-        sPrimaries.Green.y = (mng_float)pBuf->iPrimarygreeny / 100000;
-        sPrimaries.Blue.x  = (mng_float)pBuf->iPrimarybluex  / 100000;
-        sPrimaries.Blue.y  = (mng_float)pBuf->iPrimarybluey  / 100000;
-      }
-      else
-      {
-        sWhitepoint.x      = (mng_float)pData->iGlobalWhitepointx   / 100000;
-        sWhitepoint.y      = (mng_float)pData->iGlobalWhitepointy   / 100000;
-        sPrimaries.Red.x   = (mng_float)pData->iGlobalPrimaryredx   / 100000;
-        sPrimaries.Red.y   = (mng_float)pData->iGlobalPrimaryredy   / 100000;
-        sPrimaries.Green.x = (mng_float)pData->iGlobalPrimarygreenx / 100000;
-        sPrimaries.Green.y = (mng_float)pData->iGlobalPrimarygreeny / 100000;
-        sPrimaries.Blue.x  = (mng_float)pData->iGlobalPrimarybluex  / 100000;
-        sPrimaries.Blue.y  = (mng_float)pData->iGlobalPrimarybluey  / 100000;
-      }
-#endif
-
-      sWhitepoint.Y      =             /* Y component is always 1.0 */
-      sPrimaries.Red.Y   =
-      sPrimaries.Green.Y =
-      sPrimaries.Blue.Y  = 1.0;
-
-      if ((pBuf) && (pBuf->bHasGAMA))  /* get the gamma value */
-        dGamma = (mng_float)pBuf->iGamma / 100000;
-      else
-        dGamma = (mng_float)pData->iGlobalGamma / 100000;
-
-      dGamma = pData->dViewgamma / dGamma;
-
-      pGammatable [0] =                /* and build the lookup tables */
-      pGammatable [1] =
-      pGammatable [2] = cmsBuildGamma (256, dGamma);
-
-      if (!pGammatable [0])            /* enough memory ? */
-        MNG_ERRORL (pData, MNG_LCMS_NOMEM);
-                                       /* create the profile */
-      hProf = cmsCreateRGBProfile (&sWhitepoint, &sPrimaries, pGammatable);
-
-      cmsFreeGamma (pGammatable [0]);  /* free the temporary gamma tables ? */
-                                       /* yes! but just the one! */
-
-      pData->hProf1 = hProf;           /* save for future use */
-
-      if (!hProf)                      /* handle error ? */
-        MNG_ERRORL (pData, MNG_LCMS_NOHANDLE);
-
-      if (pData->bIsRGBA16)            /* 16-bit intermediates ? */
-        hTrans = cmsCreateTransform (hProf,         TYPE_RGBA_16_SE,
-                                     pData->hProf2, TYPE_RGBA_16_SE,
-                                     INTENT_PERCEPTUAL, MNG_CMS_FLAGS);
-      else
-        hTrans = cmsCreateTransform (hProf,         TYPE_RGBA_8,
-                                     pData->hProf2, TYPE_RGBA_8,
-                                     INTENT_PERCEPTUAL, MNG_CMS_FLAGS);
-
-      pData->hTrans = hTrans;          /* save for future use */
-
-      if (!hTrans)                     /* handle error ? */
-        MNG_ERRORL (pData, MNG_LCMS_NOTRANS);
-                                       /* load color-correction routine */
-      pData->fCorrectrow = (mng_fptr)mng_correct_full_cms;
-
-      return MNG_NOERROR;              /* and done */
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_FULL_CMS, MNG_LC_END);
-#endif
-                                       /* if we get here, we'll only do gamma */
-  return mng_init_gamma_only (pData, bGlobal, bObject, bRetrobj);
-}
-#endif /* MNG_INCLUDE_LCMS */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_LCMS
-mng_retcode mng_correct_full_cms (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CORRECT_FULL_CMS, MNG_LC_START);
-#endif
-
-  cmsDoTransform (pData->hTrans, pData->pRGBArow, pData->pRGBArow, pData->iRowsamples);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CORRECT_FULL_CMS, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_INCLUDE_LCMS */
-
-/* ************************************************************************** */
-
-#if defined(MNG_GAMMA_ONLY) || defined(MNG_FULL_CMS) || defined(MNG_APP_CMS)
-mng_retcode mng_init_gamma_only (mng_datap pData,
-                                 mng_bool  bGlobal,
-                                 mng_bool  bObject,
-                                 mng_bool  bRetrobj)
-{
-  mng_float      dGamma;
-  mng_imagep     pImage = MNG_NULL;
-  mng_imagedatap pBuf   = MNG_NULL;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_GAMMA_ONLY, MNG_LC_START);
-#endif
-
-  if (bObject)                         /* use object if present ? */
-  {                                    /* current object ? */
-    if ((mng_imagep)pData->pCurrentobj)
-      pImage = (mng_imagep)pData->pCurrentobj;
-    else                               /* if not; use object 0 */
-      pImage = (mng_imagep)pData->pObjzero;
-  }
-
-  if (bRetrobj)                        /* retrieving from an object ? */
-    pImage = (mng_imagep)pData->pRetrieveobj;
-
-  if (pImage)                          /* are we using an object ? */
-    pBuf = pImage->pImgbuf;            /* then address the buffer */
-
-  if ((!pBuf) || (!pBuf->bCorrected))  /* is the buffer already corrected ? */
-  {
-    if ((pBuf) && (pBuf->bHasSRGB))    /* get the gamma value */
-      dGamma = 0.45455;
-    else
-    if ((pBuf) && (pBuf->bHasGAMA))
-      dGamma = (mng_float)pBuf->iGamma / 100000;
-    else
-    if ((bGlobal) && (pData->bHasglobalSRGB))
-      dGamma = 0.45455;
-    else
-    if ((bGlobal) && (pData->bHasglobalGAMA))
-      dGamma = (mng_float)pData->iGlobalGamma / 100000;
-    else
-      dGamma = pData->dDfltimggamma;
-
-    if (dGamma > 0)                    /* ignore gamma=0 */
-    {
-      dGamma = pData->dViewgamma / (dGamma * pData->dDisplaygamma);
-
-      if (dGamma != pData->dLastgamma) /* lookup table needs to be computed ? */
-      {
-        mng_int32 iX;
-
-        pData->aGammatab [0] = 0;
-
-        for (iX = 1; iX <= 255; iX++)
-          pData->aGammatab [iX] = (mng_uint8)(pow (iX / 255.0, dGamma) * 255 + 0.5);
-
-        pData->dLastgamma = dGamma;    /* keep for next time */
-      }
-                                       /* load color-correction routine */
-      pData->fCorrectrow = (mng_fptr)mng_correct_gamma_only;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_GAMMA_ONLY, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_GAMMA_ONLY || MNG_FULL_CMS || MNG_APP_CMS */
-
-/* ************************************************************************** */
-
-#if defined(MNG_GAMMA_ONLY) || defined(MNG_FULL_CMS) || defined(MNG_APP_CMS)
-mng_retcode mng_correct_gamma_only (mng_datap pData)
-{
-  mng_uint8p pWork;
-  mng_int32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CORRECT_GAMMA_ONLY, MNG_LC_START);
-#endif
-
-  pWork = pData->pRGBArow;             /* address intermediate row */
-
-  if (pData->bIsRGBA16)                /* 16-bit intermediate row ? */
-  {
-
-  
-     /* TODO: 16-bit precision gamma processing */
-     /* we'll just do the high-order byte for now */
-
-     
-                                       /* convert all samples in the row */
-     for (iX = 0; iX < pData->iRowsamples; iX++)
-     {                                 /* using the precalculated gamma lookup table */
-       *pWork     = pData->aGammatab [*pWork];
-       *(pWork+2) = pData->aGammatab [*(pWork+2)];
-       *(pWork+4) = pData->aGammatab [*(pWork+4)];
-
-       pWork += 8;
-     }
-  }
-  else
-  {                                    /* convert all samples in the row */
-     for (iX = 0; iX < pData->iRowsamples; iX++)
-     {                                 /* using the precalculated gamma lookup table */
-       *pWork     = pData->aGammatab [*pWork];
-       *(pWork+1) = pData->aGammatab [*(pWork+1)];
-       *(pWork+2) = pData->aGammatab [*(pWork+2)];
-
-       pWork += 4;
-     }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CORRECT_GAMMA_ONLY, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_GAMMA_ONLY || MNG_FULL_CMS || MNG_APP_CMS */
-
-/* ************************************************************************** */
-
-#ifdef MNG_APP_CMS
-mng_retcode mng_init_app_cms (mng_datap pData,
-                              mng_bool  bGlobal,
-                              mng_bool  bObject,
-                              mng_bool  bRetrobj)
-{
-  mng_imagep     pImage = MNG_NULL;
-  mng_imagedatap pBuf   = MNG_NULL;
-  mng_bool       bDone  = MNG_FALSE;
-  mng_retcode    iRetcode;
-  
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_APP_CMS, MNG_LC_START);
-#endif
-
-  if (bObject)                         /* use object if present ? */
-  {                                    /* current object ? */
-    if ((mng_imagep)pData->pCurrentobj)
-      pImage = (mng_imagep)pData->pCurrentobj;
-    else                               /* if not; use object 0 */
-      pImage = (mng_imagep)pData->pObjzero;
-  }
-
-  if (bRetrobj)                        /* retrieving from an object ? */
-    pImage = (mng_imagep)pData->pRetrieveobj;
-
-  if (pImage)                          /* are we using an object ? */
-    pBuf = pImage->pImgbuf;            /* then address the buffer */
-
-  if ((!pBuf) || (!pBuf->bCorrected))  /* is the buffer already corrected ? */
-  {
-#ifndef MNG_SKIPCHUNK_iCCP
-    if ( (pData->fProcessiccp) &&
-         (((pBuf) && (pBuf->bHasICCP)) || ((bGlobal) && (pData->bHasglobalICCP))) )
-    {
-      mng_uint32 iProfilesize;
-      mng_ptr    pProfile;
-
-      if ((pBuf) && (pBuf->bHasICCP))  /* get the right profile */
-      {
-        iProfilesize = pBuf->iProfilesize;
-        pProfile     = pBuf->pProfile;
-      }
-      else
-      {
-        iProfilesize = pData->iGlobalProfilesize;
-        pProfile     = pData->pGlobalProfile;
-      }
-                                       /* inform the app */
-      if (!pData->fProcessiccp ((mng_handle)pData, iProfilesize, pProfile))
-        MNG_ERROR (pData, MNG_APPCMSERROR);
-                                       /* load color-correction routine */
-      pData->fCorrectrow = (mng_fptr)mng_correct_app_cms;
-      bDone              = MNG_TRUE;
-    }
-#endif
-
-    if ( (pData->fProcesssrgb) &&
-         (((pBuf) && (pBuf->bHasSRGB)) || ((bGlobal) && (pData->bHasglobalSRGB))) )
-    {
-      mng_uint8 iIntent;
-
-      if ((pBuf) && (pBuf->bHasSRGB))  /* determine rendering intent */
-        iIntent = pBuf->iRenderingintent;
-      else
-        iIntent = pData->iGlobalRendintent;
-                                       /* inform the app */
-      if (!pData->fProcesssrgb ((mng_handle)pData, iIntent))
-        MNG_ERROR (pData, MNG_APPCMSERROR);
-                                       /* load color-correction routine */
-      pData->fCorrectrow = (mng_fptr)mng_correct_app_cms;
-      bDone              = MNG_TRUE;
-    }
-
-#ifndef MNG_SKIPCHUNK_cHRM
-    if ( (pData->fProcesschroma) &&
-         (((pBuf) && (pBuf->bHasCHRM)) || ((bGlobal) && (pData->bHasglobalCHRM))) )
-    {
-      mng_uint32 iWhitepointx,   iWhitepointy;
-      mng_uint32 iPrimaryredx,   iPrimaryredy;
-      mng_uint32 iPrimarygreenx, iPrimarygreeny;
-      mng_uint32 iPrimarybluex,  iPrimarybluey;
-
-      if ((pBuf) && (pBuf->bHasCHRM))  /* local cHRM ? */
-      {
-        iWhitepointx   = pBuf->iWhitepointx;
-        iWhitepointy   = pBuf->iWhitepointy;
-        iPrimaryredx   = pBuf->iPrimaryredx;
-        iPrimaryredy   = pBuf->iPrimaryredy;
-        iPrimarygreenx = pBuf->iPrimarygreenx;
-        iPrimarygreeny = pBuf->iPrimarygreeny;
-        iPrimarybluex  = pBuf->iPrimarybluex;
-        iPrimarybluey  = pBuf->iPrimarybluey;
-      }
-      else
-      {
-        iWhitepointx   = pData->iGlobalWhitepointx;
-        iWhitepointy   = pData->iGlobalWhitepointy;
-        iPrimaryredx   = pData->iGlobalPrimaryredx;
-        iPrimaryredy   = pData->iGlobalPrimaryredy;
-        iPrimarygreenx = pData->iGlobalPrimarygreenx;
-        iPrimarygreeny = pData->iGlobalPrimarygreeny;
-        iPrimarybluex  = pData->iGlobalPrimarybluex;
-        iPrimarybluey  = pData->iGlobalPrimarybluey;
-      }
-                                       /* inform the app */
-      if (!pData->fProcesschroma ((mng_handle)pData, iWhitepointx,   iWhitepointy,
-                                                     iPrimaryredx,   iPrimaryredy,
-                                                     iPrimarygreenx, iPrimarygreeny,
-                                                     iPrimarybluex,  iPrimarybluey))
-        MNG_ERROR (pData, MNG_APPCMSERROR);
-                                       /* load color-correction routine */
-      pData->fCorrectrow = (mng_fptr)mng_correct_app_cms;
-      bDone              = MNG_TRUE;
-    }
-#endif
-
-    if ( (pData->fProcessgamma) &&
-         (((pBuf) && (pBuf->bHasGAMA)) || ((bGlobal) && (pData->bHasglobalGAMA))) )
-    {
-      mng_uint32 iGamma;
-
-      if ((pBuf) && (pBuf->bHasGAMA))  /* get the gamma value */
-        iGamma = pBuf->iGamma;
-      else
-        iGamma = pData->iGlobalGamma;
-                                       /* inform the app */
-      if (!pData->fProcessgamma ((mng_handle)pData, iGamma))
-      {                                /* app wants us to use internal routines ! */
-        iRetcode = mng_init_gamma_only (pData, bGlobal, bObject, bRetrobj);
-        if (iRetcode)                  /* on error bail out */
-          return iRetcode;
-      }
-      else
-      {                                /* load color-correction routine */
-        pData->fCorrectrow = (mng_fptr)mng_correct_app_cms;
-      }
-
-      bDone = MNG_TRUE;
-    }
-
-    if (!bDone)                        /* no color-info at all ? */
-    {
-                                       /* then use default image gamma ! */
-      if (!pData->fProcessgamma ((mng_handle)pData,
-                                 (mng_uint32)((pData->dDfltimggamma * 100000) + 0.5)))
-      {                                /* app wants us to use internal routines ! */
-        iRetcode = mng_init_gamma_only (pData, bGlobal, bObject, bRetrobj);
-        if (iRetcode)                  /* on error bail out */
-          return iRetcode;
-      }
-      else
-      {                                /* load color-correction routine */
-        pData->fCorrectrow = (mng_fptr)mng_correct_app_cms;
-      }  
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_APP_CMS, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_APP_CMS */
-
-/* ************************************************************************** */
-
-#ifdef MNG_APP_CMS
-mng_retcode mng_correct_app_cms (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CORRECT_APP_CMS, MNG_LC_START);
-#endif
-
-  if (pData->fProcessarow)             /* let the app do something with our row */
-    if (!pData->fProcessarow ((mng_handle)pData, pData->iRowsamples,
-                              pData->bIsRGBA16, pData->pRGBArow))
-      MNG_ERROR (pData, MNG_APPCMSERROR);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CORRECT_APP_CMS, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_APP_CMS */
-
-/* ************************************************************************** */
-
-#endif /* MNG_INCLUDE_DISPLAY_PROCS */
-
-/* ************************************************************************** */
-/* * end of file                                                            * */
-/* ************************************************************************** */
-
-
-
diff --git a/Source/LibMNG/libmng_cms.h b/Source/LibMNG/libmng_cms.h
deleted file mode 100644
index 4459f80..0000000
--- a/Source/LibMNG/libmng_cms.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/* ************************************************************************** */
-/* *             For conditions of distribution and use,                    * */
-/* *                see copyright notice in libmng.h                        * */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * project   : libmng                                                     * */
-/* * file      : libmng_cms.h              copyright (c) 2000-2003 G.Juyn   * */
-/* * version   : 1.0.6                                                      * */
-/* *                                                                        * */
-/* * purpose   : color management routines (definition)                     * */
-/* *                                                                        * */
-/* * author    : G.Juyn                                                     * */
-/* *                                                                        * */
-/* * comment   : Definition of color management routines                    * */
-/* *                                                                        * */
-/* * changes   : 0.5.1 - 05/08/2000 - G.Juyn                                * */
-/* *             - changed strict-ANSI stuff                                * */
-/* *             0.5.1 - 05/11/2000 - G.Juyn                                * */
-/* *             - added creatememprofile                                   * */
-/* *                                                                        * */
-/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
-/* *             - changed file-prefixes                                    * */
-/* *                                                                        * */
-/* *             1.0.1 - 04/25/2001 - G.Juyn                                * */
-/* *             - moved mng_clear_cms to libmng_cms                        * */
-/* *             1.0.1 - 05/02/2001 - G.Juyn                                * */
-/* *             - added "default" sRGB generation (Thanks Marti!)          * */
-/* *                                                                        * */
-/* *             1.0.5 - 08/19/2002 - G.Juyn                                * */
-/* *             - B597134 - libmng pollutes the linker namespace           * */
-/* *             1.0.5 - 09/19/2002 - G.Juyn                                * */
-/* *             - optimized color-correction routines                      * */
-/* *                                                                        * */
-/* *             1.0.6 - 04/11/2003 - G.Juyn                                * */
-/* *             - B719420 - fixed several MNG_APP_CMS problems             * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
-#pragma option -A                      /* force ANSI-C */
-#endif
-
-#ifndef _libmng_cms_h_
-#define _libmng_cms_h_
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_LCMS
-void        mnglcms_initlibrary       (void);
-mng_cmsprof mnglcms_createfileprofile (mng_pchar    zFilename);
-mng_cmsprof mnglcms_creatememprofile  (mng_uint32   iProfilesize,
-                                       mng_ptr      pProfile );
-mng_cmsprof mnglcms_createsrgbprofile (void);
-void        mnglcms_freeprofile       (mng_cmsprof  hProf    );
-void        mnglcms_freetransform     (mng_cmstrans hTrans   );
-
-mng_retcode mng_clear_cms             (mng_datap    pData    );
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_FULL_CMS
-mng_retcode mng_init_full_cms          (mng_datap pData,
-                                        mng_bool  bGlobal,
-                                        mng_bool  bObject,
-                                        mng_bool  bRetrobj);
-mng_retcode mng_correct_full_cms       (mng_datap pData);
-#endif
-
-#if defined(MNG_FULL_CMS) || defined(MNG_GAMMA_ONLY) || defined(MNG_APP_CMS)
-mng_retcode mng_init_gamma_only        (mng_datap pData,
-                                        mng_bool  bGlobal,
-                                        mng_bool  bObject,
-                                        mng_bool  bRetrobj);
-mng_retcode mng_correct_gamma_only     (mng_datap pData);
-#endif
-
-#ifdef MNG_APP_CMS
-mng_retcode mng_init_app_cms           (mng_datap pData,
-                                        mng_bool  bGlobal,
-                                        mng_bool  bObject,
-                                        mng_bool  bRetrobj);
-mng_retcode mng_correct_app_cms        (mng_datap pData);
-#endif
-
-/* ************************************************************************** */
-
-#endif /* _libmng_cms_h_ */
-
-/* ************************************************************************** */
-/* * end of file                                                            * */
-/* ************************************************************************** */
diff --git a/Source/LibMNG/libmng_conf.h b/Source/LibMNG/libmng_conf.h
deleted file mode 100644
index 8e0925e..0000000
--- a/Source/LibMNG/libmng_conf.h
+++ /dev/null
@@ -1,306 +0,0 @@
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * project   : libmng                                                     * */
-/* * file      : libmng_conf.h             copyright (c) G.Juyn 2000-2004   * */
-/* * version   : 1.0.9                                                      * */
-/* *                                                                        * */
-/* * purpose   : main configuration file                                    * */
-/* *                                                                        * */
-/* * author    : G.Juyn                                                     * */
-/* *                                                                        * */
-/* * comment   : The configuration file. Change this to include/exclude     * */
-/* *             the options you want or do not want in libmng.             * */
-/* *                                                                        * */
-/* * changes   : 0.5.2 - 06/02/2000 - G.Juyn                                * */
-/* *             - separated configuration-options into this file           * */
-/* *             - changed to most likely configuration (?)                 * */
-/* *             0.5.2 - 06/03/2000 - G.Juyn                                * */
-/* *             - changed options to create a standard so-library          * */
-/* *               with everything enabled                                  * */
-/* *             0.5.2 - 06/04/2000 - G.Juyn                                * */
-/* *             - changed options to create a standard win32-dll           * */
-/* *               with everything enabled                                  * */
-/* *                                                                        * */
-/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
-/* *             - changed file-prefixes                                    * */
-/* *                                                                        * */
-/* *             0.9.3 - 08/12/2000 - G.Juyn                                * */
-/* *             - added workaround for faulty PhotoShop iCCP chunk         * */
-/* *             0.9.3 - 09/16/2000 - G.Juyn                                * */
-/* *             - removed trace-options from default SO/DLL builds         * */
-/* *                                                                        * */
-/* *             1.0.4 - 06/22/2002 - G.Juyn                                * */
-/* *             - B526138 - returned IJGSRC6B calling convention to        * */
-/* *               default for MSVC                                         * */
-/* *                                                                        * */
-/* *             1.0.5 - 09/14/2002 - G.Juyn                                * */
-/* *             - added event handling for dynamic MNG                     * */
-/* *             - added 'supports' call to check function availability     * */
-/* *                                                                        * */
-/* *             1.0.6 - 06/22/2002 - G.R-P                                 * */
-/* *             - added MNG_NO_INCLUDE_JNG conditional                     * */
-/* *             - added MNG_SKIPCHUNK_evNT conditional                     * */
-/* *             1.0.6 - 07/14/2002 - G.R-P                                 * */
-/* *             - added MNG_NO_SUPPORT_FUNCQUERY conditional               * */
-/* *                                                                        * */
-/* *             1.0.7 - 03/07/2004 - G.R-P                                 * */
-/* *             - added MNG_VERSION_QUERY_SUPPORT_ conditional             * */
-/* *                                                                        * */
-/* *             1.0.9 - 05/12/2004 - G.Juyn                                * */
-/* *             - clearified MNG_BIGENDIAN_SUPPORTED conditional           * */
-/* *             - added MNG_LITTLEENDIAN_SUPPORTED conditional             * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-
-#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
-#pragma option -A                      /* force ANSI-C */
-#endif
-
-#ifndef _libmng_conf_h_
-#define _libmng_conf_h_
-
-#ifdef MNG_MOZILLA_CFG
-#include "special\mozcfg\mozlibmngconf.h"
-#endif
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* *  User-selectable compile-time options                                  * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-/* ************************************************************************** */
-/* added by FreeImage */
-/* ************************************************************************** */
-
-#define MNG_OPTIMIZE_CHUNKINITFREE
-#define MNG_OPTIMIZE_OBJCLEANUP
-#define MNG_OPTIMIZE_CHUNKASSIGN
-#define MNG_OPTIMIZE_CHUNKREADER
-
-/* ************************************************************************** */
-
-/* enable exactly one(1) of the MNG-(sub)set selectors */
-/* use this to select which (sub)set of the MNG specification you wish
-   to support */
-/* generally you'll want full support as the library provides it automatically
-   for you! if you're really strung on memory-requirements you can opt
-   to enable less support (but it's just NOT a good idea!) */
-/* NOTE that this isn't actually implemented yet */
-
-#if !defined(MNG_SUPPORT_FULL) && !defined(MNG_SUPPORT_LC) && !defined(MNG_SUPPORT_VLC)
-#define MNG_SUPPORT_FULL
-/* #define MNG_SUPPORT_LC */
-/* #define MNG_SUPPORT_VLC */
-#endif
-
-/* ************************************************************************** */
-
-/* enable JPEG support if required */
-/* use this to enable the JNG support routines */
-/* this requires an external jpeg package;
-   currently only IJG's jpgsrc6b is supported! */
-/* NOTE that the IJG code can be either 8- or 12-bit (eg. not both);
-   so choose the one you've defined in jconfig.h; if you don't know what
-   the heck I'm talking about, just leave it at 8-bit support (thank you!) */
-
-#ifndef MNG_NO_INCLUDE_JNG
-#ifdef MNG_SUPPORT_FULL                /* full support includes JNG */
-#define MNG_SUPPORT_IJG6B
-#endif
-
-#ifndef MNG_SUPPORT_IJG6B
-#if defined(MNG_BUILD_SO) || defined(MNG_USE_SO) || defined(MNG_BUILD_DLL) || defined(MNG_USE_DLL)
-#define MNG_SUPPORT_IJG6B
-#endif
-#endif
-
-#if defined(MNG_SUPPORT_IJG6B) && !defined(MNG_SUPPORT_JPEG8) && !defined(MNG_SUPPORT_JPEG12)
-#define MNG_SUPPORT_JPEG8
-/* #define MNG_SUPPORT_JPEG12 */
-#endif
-
-/* The following is required to export the IJG routines from the DLL in
-   the Windows-standard calling convention;
-   currently this only works for Borland C++ !!! */
-
-#if defined(MNG_BUILD_DLL) || defined(MNG_USE_DLL)
-#if defined(MNG_SUPPORT_IJG6B) && defined(__BORLANDC__)
-#define MNG_DEFINE_JPEG_STDCALL
-#endif
-#endif
-#endif
-
-/* ************************************************************************** */
-
-/* enable required high-level functions */
-/* use this to select the high-level functions you require */
-/* if you only need to display a MNG, disable write support! */
-/* if you only need to examine a MNG, disable write & display support! */
-/* if you only need to copy a MNG, disable display support! */
-/* if you only need to create a MNG, disable read & display support! */
-/* NOTE that turning all options off will be very unuseful! */
-
-#if !defined(MNG_SUPPORT_READ) && !defined(MNG_SUPPORT_WRITE) && !defined(MNG_SUPPORT_DISPLAY)
-#define MNG_SUPPORT_READ
-#if defined(MNG_BUILD_SO) || defined(MNG_USE_SO) || defined(MNG_BUILD_DLL) || defined(MNG_USE_DLL)
-#define MNG_SUPPORT_WRITE
-#endif
-#define MNG_SUPPORT_DISPLAY
-#endif
-
-/* ************************************************************************** */
-
-/* enable chunk access functions */
-/* use this to select whether you need access to the individual chunks */
-/* useful if you want to examine a read MNG (you'll also need MNG_STORE_CHUNKS !)*/
-/* required if you need to create & write a new MNG! */
-
-#ifndef MNG_ACCESS_CHUNKS
-#if defined(MNG_BUILD_SO) || defined(MNG_USE_SO) || defined(MNG_BUILD_DLL) || defined(MNG_USE_DLL)
-#define MNG_ACCESS_CHUNKS
-#endif
-#endif
-
-/* ************************************************************************** */
-
-/* enable exactly one(1) of the color-management functionality selectors */
-/* use this to select the level of automatic color support */
-/* MNG_FULL_CMS requires the lcms (little cms) external package ! */
-/* if you want your own app (or the OS) to handle color-management
-   select MNG_APP_CMS */
-
-#define MNG_GAMMA_ONLY
-/* #define MNG_FULL_CMS */
-/* #define MNG_APP_CMS */
-
-/* ************************************************************************** */
-
-/* enable automatic dithering */
-/* use this if you need dithering support to convert high-resolution
-   images to a low-resolution output-device */
-/* NOTE that this is not supported yet */
-
-/* #define MNG_AUTO_DITHER */
-
-/* ************************************************************************** */
-
-/* enable whether chunks should be stored for reference later */
-/* use this if you need to examine the chunks of a MNG you have read,
-   or (re-)write a MNG you have read */
-/* turn this off if you want to reduce memory-consumption */
-
-#ifndef MNG_STORE_CHUNKS
-#if defined(MNG_BUILD_SO) || defined(MNG_USE_SO) || defined(MNG_BUILD_DLL) || defined(MNG_USE_DLL)
-#define MNG_STORE_CHUNKS
-#endif
-#endif
-
-/* ************************************************************************** */
-
-/* enable internal memory management (if your compiler supports it) */
-/* use this if your compiler supports the 'standard' memory functions
-   (calloc & free), and you want the library to use these functions and not
-   bother your app with memory-callbacks */
-
-/* #define MNG_INTERNAL_MEMMNGMT */
-
-/* ************************************************************************** */
-
-/* enable internal tracing-functionality (manual debugging purposes) */
-/* use this if you have trouble location bugs or problems */
-/* NOTE that you'll need to specify the trace callback function! */
-
-/* #define MNG_SUPPORT_TRACE */
-
-/* ************************************************************************** */
-
-/* enable extended error- and trace-telltaling */
-/* use this if you need explanatory messages with errors and/or tracing */
-
-#if !defined(MNG_ERROR_TELLTALE) && !defined(MNG_TRACE_TELLTALE)
-#if defined(MNG_BUILD_SO) || defined(MNG_USE_SO) || defined(MNG_BUILD_DLL) || defined(MNG_USE_DLL)
-#define MNG_ERROR_TELLTALE
-#define MNG_TRACE_TELLTALE
-#endif
-#endif
-
-/* ************************************************************************** */
-
-/* enable BIG/LITTLE endian optimizations */
-/* enable BIG if you're on an architecture that supports big-endian reads
-   and writes that aren't word-aligned */
-/* according to reliable sources this only works for PowerPC (bigendian mode)
-   and 680x0 */
-/* enable LITTLE if you're on an architecture that supports little-endian */
-/* when in doubt leave both off !!! */
-
-/* #define MNG_BIGENDIAN_SUPPORTED */
-/* #define MNG_LITTLEENDIAN_SUPPORTED */
-
-/* ************************************************************************** */
-/* enable 'version' functions */
-#if !defined(MNG_VERSION_QUERY_SUPPORT) && \
-    !defined(MNG_NO_VERSION_QUERY_SUPPORT)
-#define MNG_VERSION_QUERY_SUPPORT
-#endif
-
-/* enable 'supports' function */
-/* use this if you need to query the availability of functions at runtime;
-   useful for apps that dynamically load the library and that need specific
-   functions */
-
-#if !defined(MNG_NO_SUPPORT_FUNCQUERY) && !defined(MNG_SUPPORT_FUNCQUERY)
-#if defined(MNG_BUILD_SO) || defined(MNG_USE_SO) || \
-    defined(MNG_BUILD_DLL) || defined(MNG_USE_DLL)
-#define MNG_SUPPORT_FUNCQUERY
-#endif
-#endif
-
-/* ************************************************************************** */
-
-/* enable dynamic MNG features */
-/* use this if you would like to have dynamic support for specifically
-   designed MNGs; eg. this is useful for 'rollover' effects such as common
-   on the world wide web */
-
-#ifndef MNG_SUPPORT_DYNAMICMNG
-#if defined(MNG_BUILD_SO) || defined(MNG_USE_SO) || defined(MNG_BUILD_DLL) || defined(MNG_USE_DLL)
-#define MNG_SUPPORT_DYNAMICMNG
-#endif
-#endif
-#ifndef MNG_SUPPORT_DYNAMICMNG
-#ifndef MNG_SKIPCHUNK_evNT
-#define MNG_SKIPCHUNK_evNT
-#endif
-#endif
-
-#ifdef MNG_INCLUDE_JNG
-#ifndef MNG_NO_ACCESS_JPEG
-#ifndef MNG_ACCESS_JPEG
-#define MNG_ACCESS_JPEG
-#endif
-#endif
-#endif
-
-#ifdef MNG_INCLUDE_ZLIB
-#ifndef MNG_NO_ACCESS_ZLIB
-#ifndef MNG_ACCESS_ZLIB
-#define MNG_ACCESS_ZLIB
-#endif
-#endif
-#endif
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* *  End of user-selectable compile-time options                           * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#endif /* _libmng_conf_h_ */
-
-/* ************************************************************************** */
-/* * end of file                                                            * */
-/* ************************************************************************** */
-
diff --git a/Source/LibMNG/libmng_data.h b/Source/LibMNG/libmng_data.h
deleted file mode 100644
index 430dca9..0000000
--- a/Source/LibMNG/libmng_data.h
+++ /dev/null
@@ -1,1029 +0,0 @@
-/* ************************************************************************** */
-/* *             For conditions of distribution and use,                    * */
-/* *                see copyright notice in libmng.h                        * */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * project   : libmng                                                     * */
-/* * file      : libmng_data.h             copyright (c) 2000-2007 G.Juyn   * */
-/* * version   : 1.0.10                                                     * */
-/* *                                                                        * */
-/* * purpose   : main data structure definition                             * */
-/* *                                                                        * */
-/* * author    : G.Juyn                                                     * */
-/* *                                                                        * */
-/* * comment   : Definition of the library main data structure              * */
-/* *                                                                        * */
-/* * changes   : 0.5.1 - 05/04/2000 - G.Juyn                                * */
-/* *             - added CRC table to main structure (for thread-safety)    * */
-/* *             0.5.1 - 05/06/2000 - G.Juyn                                * */
-/* *             - added iPLTEentries for checking hIST-length              * */
-/* *             0.5.1 - 05/08/2000 - G.Juyn                                * */
-/* *             - changed palette definition to exported palette-type      * */
-/* *             - removed frozen indicator                                 * */
-/* *             - added create/write indicators                            * */
-/* *             - changed strict-ANSI stuff                                * */
-/* *             0.5.1 - 05/13/2000 - G.Juyn                                * */
-/* *             - added eMNGma hack (will be removed in 1.0.0 !!!)         * */
-/* *             - added TERM animation object pointer (easier reference)   * */
-/* *             - added saved-data structure for SAVE/SEEK processing      * */
-/* *                                                                        * */
-/* *             0.5.2 - 05/18/2000 - G.Juyn                                * */
-/* *             - added fields for JNG support (IJG-based)                 * */
-/* *             0.5.2 - 05/24/2000 - G.Juyn                                * */
-/* *             - changed global tRNS definition                           * */
-/* *             0.5.2 - 05/30/2000 - G.Juyn                                * */
-/* *             - added delta-image fields                                 * */
-/* *             0.5.2 - 06/01/2000 - G.Juyn                                * */
-/* *             - added internal delta-image processing callbacks          * */
-/* *             0.5.2 - 06/02/2000 - G.Juyn                                * */
-/* *             - changed SWAP_ENDIAN to BIGENDIAN_SUPPORTED               * */
-/* *               (contributed by Tim Rowley)                              * */
-/* *             - added getalphaline callback for RGB8_A8 canvasstyle      * */
-/* *             0.5.2 - 06/06/2000 - G.Juyn                                * */
-/* *             - added parameter for delayed buffer-processing            * */
-/* *                                                                        * */
-/* *             0.5.3 - 06/16/2000 - G.Juyn                                * */
-/* *             - added update-region parms for refresh calback            * */
-/* *             - added Needrefresh parameter                              * */
-/* *             0.5.3 - 06/17/2000 - G.Juyn                                * */
-/* *             - added Deltaimmediate parm for faster delta-processing    * */
-/* *             0.5.3 - 06/21/2000 - G.Juyn                                * */
-/* *             - added Speed parameter to facilitate testing              * */
-/* *             - added Imagelevel parameter for processtext callback      * */
-/* *             0.5.3 - 06/26/2000 - G.Juyn                                * */
-/* *             - changed userdata variable to mng_ptr                     * */
-/* *                                                                        * */
-/* *             0.9.1 - 07/07/2000 - G.Juyn                                * */
-/* *             - added variables for go_xxxx processing                   * */
-/* *             0.9.1 - 07/08/2000 - G.Juyn                                * */
-/* *             - added variables for improved timing support              * */
-/* *             0.9.1 - 07/15/2000 - G.Juyn                                * */
-/* *             - added callbacks for SAVE/SEEK processing                 * */
-/* *             - added variable for NEEDSECTIONWAIT breaks                * */
-/* *             - added variable for freeze & reset processing             * */
-/* *             0.9.1 - 07/17/2000 - G.Juyn                                * */
-/* *             - fixed suspension-buffering for 32K+ chunks               * */
-/* *                                                                        * */
-/* *             0.9.2 - 07/29/2000 - G.Juyn                                * */
-/* *             - removed Nextbackxxx fields (no longer used)              * */
-/* *             0.9.2 - 07/31/2000 - G.Juyn                                * */
-/* *             - fixed wrapping of suspension parameters                  * */
-/* *             0.9.2 - 08/04/2000 - G.Juyn                                * */
-/* *             - B111096 - fixed large-buffer read-suspension             * */
-/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
-/* *             - changed file-prefixes                                    * */
-/* *                                                                        * */
-/* *             0.9.3 - 08/26/2000 - G.Juyn                                * */
-/* *             - added MAGN chunk                                         * */
-/* *             0.9.3 - 09/07/2000 - G.Juyn                                * */
-/* *             - added support for new filter_types                       * */
-/* *             0.9.3 - 09/10/2000 - G.Juyn                                * */
-/* *             - fixed DEFI behavior                                      * */
-/* *             0.9.3 - 10/10/2000 - G.Juyn                                * */
-/* *             - added support for alpha-depth prediction                 * */
-/* *             0.9.3 - 10/11/2000 - G.Juyn                                * */
-/* *             - added support for nEED                                   * */
-/* *             0.9.3 - 10/16/2000 - G.Juyn                                * */
-/* *             - added optional support for bKGD for PNG images           * */
-/* *             - added support for JDAA                                   * */
-/* *             0.9.3 - 10/17/2000 - G.Juyn                                * */
-/* *             - added callback to process non-critical unknown chunks    * */
-/* *             - fixed support for bKGD                                   * */
-/* *             0.9.3 - 10/19/2000 - G.Juyn                                * */
-/* *             - implemented delayed delta-processing                     * */
-/* *             0.9.4 - 12/16/2000 - G.Juyn                                * */
-/* *             - fixed mixup of data- & function-pointers (thanks Dimitri)* */
-/* *                                                                        * */
-/* *             1.0.1 - 02/08/2001 - G.Juyn                                * */
-/* *             - added MEND processing callback                           * */
-/* *             1.0.1 - 02/13/2001 - G.Juyn                                * */
-/* *             - fixed first FRAM_MODE=4 timing problem                   * */
-/* *                                                                        * */
-/* *             1.0.2 - 06/23/2001 - G.Juyn                                * */
-/* *             - added optimization option for MNG-video playback         * */
-/* *             - added processterm callback                               * */
-/* *             1.0.2 - 06/25/2001 - G.Juyn                                * */
-/* *             - added option to turn off progressive refresh             * */
-/* *                                                                        * */
-/* *             1.0.5 - 07/08/2002 - G.Juyn                                * */
-/* *             - B578572 - removed eMNGma hack (thanks Dimitri!)          * */
-/* *             1.0.5 - 07/16/2002 - G.Juyn                                * */
-/* *             - B581625 - large chunks fail with suspension reads        * */
-/* *             1.0.5 - 08/15/2002 - G.Juyn                                * */
-/* *             - completed PROM support                                   * */
-/* *             1.0.5 - 09/15/2002 - G.Juyn                                * */
-/* *             - fixed LOOP iteration=0 special case                      * */
-/* *             1.0.5 - 09/20/2002 - G.Juyn                                * */
-/* *             - finished support for BACK image & tiling                 * */
-/* *             1.0.5 - 10/07/2002 - G.Juyn                                * */
-/* *             - added another fix for misplaced TERM chunk               * */
-/* *             - completed support for condition=2 in TERM chunk          * */
-/* *             1.0.5 - 10/20/2002 - G.Juyn                                * */
-/* *             - fixed processing for multiple objects in MAGN            * */
-/* *             - fixed display of visible target of PAST operation        * */
-/* *             1.0.5 - 11/07/2002 - G.Juyn                                * */
-/* *             - added support to get totals after mng_read()             * */
-/* *             1.0.5 - 24/02/2003 - G.Juyn                                * */
-/* *             - B683152 - libjpeg suspension not always honored correctly* */
-/* *                                                                        * */
-/* *             1.0.6 - 04/11/2003 - G.Juyn                                * */
-/* *             - B719420 - fixed several MNG_APP_CMS problems             * */
-/* *             1.0.6 - 07/05/2003 - G. R-P                                * */
-/* *             - optionally use zlib's crc32() function                   * */
-/* *             1.0.6 - 07/29/2003 - G.R-P                                 * */
-/* *             - added SKIPCHUNK conditionals around PAST chunk support   * */
-/* *             1.0.6 - 08/17/2003 - G.R-P                                 * */
-/* *             - added iPNGdepth member to pData structure                * */
-/* *                                                                        * */
-/* *             1.0.7 - 03/10/2004 - G.R-P                                 * */
-/* *             - added conditionals around openstream/closestream         * */
-/* *             1.0.7 - 03/24/2004 - G.R-P                                 * */
-/* *             - added more SKIPCHUNK conditionals                        * */
-/* *                                                                        * */
-/* *             1.0.8 - 04/02/2004 - G.Juyn                                * */
-/* *             - added CRC existence & checking flags                     * */
-/* *             1.0.8 - 04/10/2004 - G.Juyn                                * */
-/* *             - added data-push mechanisms for specialized decoders      * */
-/* *                                                                        * */
-/* *             1.0.9 - 12/11/2004 - G.Juyn                                * */
-/* *             - added conditional MNG_OPTIMIZE_DISPLAYCALLS              * */
-/* *                                                                        * */
-/* *             1.0.10 - 04/08/2007 - G.Juyn                               * */
-/* *             - added support for mPNG proposal                          * */
-/* *             1.0.10 - 04/12/2007 - G.Juyn                               * */
-/* *             - added support for ANG proposal                           * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
-#pragma option -A                      /* force ANSI-C */
-#endif
-
-#ifndef _libmng_data_h_
-#define _libmng_data_h_
-
-/* ************************************************************************** */
-
-#define MNG_MAGIC 0x52530a0aL
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Internal structures                                                    * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-typedef mng_palette8 mng_rgbpaltab;
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * The saved_data structure                                               * */
-/* *                                                                        * */
-/* * This contains the saved data after a SAVE chunk has been processed.    * */
-/* * The data is saved from the main data structure during SAVE processing, * */
-/* * and restored to the main data structure during SEEK processing.        * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-typedef struct mng_savedata_struct {
-
-#if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
-           mng_bool          bHasglobalPLTE;     /* global PLTE chunk processed */
-           mng_bool          bHasglobalTRNS;     /* global tRNS chunk processed */
-           mng_bool          bHasglobalGAMA;     /* global gAMA chunk processed */
-           mng_bool          bHasglobalCHRM;     /* global cHRM chunk processed */
-           mng_bool          bHasglobalSRGB;     /* global sRGB chunk processed */
-           mng_bool          bHasglobalICCP;     /* global iCCP chunk processed */
-           mng_bool          bHasglobalBKGD;     /* global bKGD chunk processed */
-#endif /* MNG_SUPPORT_READ || MNG_SUPPORT_WRITE */
-
-#ifdef MNG_SUPPORT_DISPLAY
-           mng_uint16        iBACKred;           /* BACK fields */
-           mng_uint16        iBACKgreen;
-           mng_uint16        iBACKblue;
-           mng_uint8         iBACKmandatory;
-           mng_uint16        iBACKimageid;
-           mng_uint8         iBACKtile;
-
-           mng_uint8         iFRAMmode;          /* FRAM fields (global) */
-           mng_uint32        iFRAMdelay;
-           mng_uint32        iFRAMtimeout;
-           mng_bool          bFRAMclipping;
-           mng_int32         iFRAMclipl;
-           mng_int32         iFRAMclipr;
-           mng_int32         iFRAMclipt;
-           mng_int32         iFRAMclipb;
-
-           mng_uint32        iGlobalPLTEcount;   /* global PLTE fields */
-           mng_rgbpaltab     aGlobalPLTEentries;
-
-           mng_uint32        iGlobalTRNSrawlen;  /* global tRNS fields */
-           mng_uint8arr      aGlobalTRNSrawdata;
-
-           mng_uint32        iGlobalGamma;       /* global gAMA fields */
-
-#ifndef MNG_SKIPCHUNK_cHRM
-           mng_uint32        iGlobalWhitepointx; /* global cHRM fields */
-           mng_uint32        iGlobalWhitepointy;
-           mng_uint32        iGlobalPrimaryredx;
-           mng_uint32        iGlobalPrimaryredy;
-           mng_uint32        iGlobalPrimarygreenx;
-           mng_uint32        iGlobalPrimarygreeny;
-           mng_uint32        iGlobalPrimarybluex;
-           mng_uint32        iGlobalPrimarybluey;
-#endif
-
-           mng_uint8         iGlobalRendintent;  /* global sRGB fields */
-
-           mng_uint32        iGlobalProfilesize; /* global iCCP fields */
-           mng_ptr           pGlobalProfile;
-
-           mng_uint16        iGlobalBKGDred;     /* global bKGD fields */
-           mng_uint16        iGlobalBKGDgreen;
-           mng_uint16        iGlobalBKGDblue;
-#endif /* MNG_SUPPORT_DISPLAY */
-
-        } mng_savedata;
-
-typedef mng_savedata * mng_savedatap;
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Internal buffer structure for data push mechanisms                     * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-typedef struct {
-           mng_ptr           pNext;              /* for linked list */
-           mng_ptr           pData;              /* used for chunks & data */
-           mng_uint32        iLength;
-           mng_bool          bOwned;
-           mng_uint8p        pDatanext;          /* only used for data */
-           mng_uint32        iRemaining;
-        } mng_pushdata;
-typedef mng_pushdata * mng_pushdatap;
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * The main libmng data structure                                         * */
-/* *                                                                        * */
-/* * The handle used in all functions points to this structure which        * */
-/* * contains all volatile data necessary to process the network graphic.   * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-typedef struct mng_data_struct {
-
-           mng_uint32        iMagic;             /* magic number to validate
-                                                    a given handle */     
-           mng_ptr           pUserdata;          /* application workdata */
-
-           mng_imgtype       eSigtype;           /* image information */
-           mng_imgtype       eImagetype;         /* initially zeroed */
-           mng_uint32        iWidth;             /* filled after header is processed */
-           mng_uint32        iHeight;
-           mng_uint32        iTicks;             /* these only after MHDR */
-           mng_uint32        iLayercount;
-           mng_uint32        iFramecount;
-           mng_uint32        iPlaytime;
-           mng_uint32        iSimplicity;
-           mng_uint8         iAlphadepth;        /* indicates expected alpha-depth */
-
-           mng_uint32        iImagelevel;        /* level of image inside a stream */
-
-           mng_uint32        iCanvasstyle;       /* layout of the drawing-canvas */
-           mng_uint32        iBkgdstyle;         /* layout of the background-canvas */
-
-           mng_int8          iMagnify;           /* magnification factor (not used yet) */
-           mng_uint32        iOffsetx;           /* x-offset for extremely large image */
-           mng_uint32        iOffsety;           /* y-offset for extremely large image */
-           mng_uint32        iCanvaswidth;       /* real canvas size */
-           mng_uint32        iCanvasheight;      /* must be set by processheader callback */
-
-           mng_uint16        iBGred;             /* default background color */
-           mng_uint16        iBGgreen;           /* initially "black" */
-           mng_uint16        iBGblue;
-           mng_bool          bUseBKGD;           /* preferred use of bKGD for PNG */
-
-           mng_bool          bIssRGB;            /* indicates sRGB system */
-
-#ifdef MNG_FULL_CMS                              /* little CMS variables */
-           mng_cmsprof       hProf1;             /* image input profile */
-           mng_cmsprof       hProf2;             /* default output profile */
-           mng_cmsprof       hProf3;             /* default sRGB profile */
-           mng_cmstrans      hTrans;             /* current transformation handle */
-#endif
-
-           mng_float         dViewgamma;         /* gamma calculation variables */
-           mng_float         dDisplaygamma;      /* initially set for sRGB conditions */
-           mng_float         dDfltimggamma;
-
-           mng_bool          bStorechunks;       /* switch for storing chunkdata */
-           mng_bool          bSectionbreaks;     /* indicate NEEDSECTIONWAIT breaks */
-           mng_bool          bCacheplayback;     /* switch to cache playback info */
-           mng_bool          bDoProgressive;     /* progressive refresh for large images */
-           mng_uint32        iCrcmode;           /* CRC existence & checking flags */
-
-           mng_speedtype     iSpeed;             /* speed-modifier for animations */
-
-           mng_uint32        iMaxwidth;          /* maximum canvas size */
-           mng_uint32        iMaxheight;         /* initially set to 1024 x 1024 */
-
-           mng_int32         iErrorcode;         /* error reporting fields */
-           mng_int8          iSeverity;
-           mng_int32         iErrorx1;
-           mng_int32         iErrorx2;
-           mng_pchar         zErrortext;
-
-           mng_memalloc      fMemalloc;          /* callback pointers */
-           mng_memfree       fMemfree;           /* initially nulled */
-           mng_releasedata   fReleasedata;
-#ifndef MNG_NO_OPEN_CLOSE_STREAM
-           mng_openstream    fOpenstream;
-           mng_closestream   fClosestream;
-#endif
-           mng_readdata      fReaddata;
-           mng_writedata     fWritedata;
-           mng_errorproc     fErrorproc;
-           mng_traceproc     fTraceproc;
-           mng_processheader fProcessheader;
-           mng_processtext   fProcesstext;
-           mng_processsave   fProcesssave;
-           mng_processseek   fProcessseek;
-           mng_processneed   fProcessneed;
-           mng_processmend   fProcessmend;
-           mng_processunknown fProcessunknown;
-           mng_processterm   fProcessterm;
-           mng_getcanvasline fGetcanvasline;
-           mng_getbkgdline   fGetbkgdline;
-           mng_getalphaline  fGetalphaline;
-           mng_refresh       fRefresh;
-           mng_gettickcount  fGettickcount;
-           mng_settimer      fSettimer;
-           mng_processgamma  fProcessgamma;
-           mng_processchroma fProcesschroma;
-           mng_processsrgb   fProcesssrgb;
-           mng_processiccp   fProcessiccp;
-           mng_processarow   fProcessarow;
-
-#if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
-#ifndef MNG_NO_OLD_VERSIONS
-           mng_bool          bPreDraft48;        /* flags ancient style draft */
-#endif
-
-           mng_chunkid       iChunkname;         /* read/write-state variables */
-           mng_uint32        iChunkseq;
-           mng_chunkp        pFirstchunk;        /* double-linked list of */
-           mng_chunkp        pLastchunk;         /* stored chunk-structures */
-
-           mng_bool          bHasheader;         /* first header chunk processed */
-           mng_bool          bHasMHDR;           /* inside a MHDR-MEND sequence */
-           mng_bool          bHasIHDR;           /* inside a IHDR-IEND sequence */
-           mng_bool          bHasBASI;           /* inside a BASI-IEND sequence */
-           mng_bool          bHasDHDR;           /* inside a DHDR-IEND sequence */
-#ifdef MNG_INCLUDE_JNG
-           mng_bool          bHasJHDR;           /* inside a JHDR-IEND sequence */
-           mng_bool          bHasJSEP;           /* passed the JSEP separator */
-           mng_bool          bHasJDAA;           /* at least 1 JDAA processed */
-           mng_bool          bHasJDAT;           /* at least 1 JDAT processed */
-#endif
-           mng_bool          bHasPLTE;           /* PLTE chunk processed */
-           mng_bool          bHasTRNS;           /* tRNS chunk processed */
-           mng_bool          bHasGAMA;           /* gAMA chunk processed */
-           mng_bool          bHasCHRM;           /* cHRM chunk processed */
-           mng_bool          bHasSRGB;           /* sRGB chunk processed */
-           mng_bool          bHasICCP;           /* iCCP chunk processed */
-           mng_bool          bHasBKGD;           /* bKGD chunk processed */
-           mng_bool          bHasIDAT;           /* at least 1 IDAT processed */
-           
-           mng_bool          bHasSAVE;           /* SAVE chunk processed */
-           mng_bool          bHasBACK;           /* BACK chunk processed */
-           mng_bool          bHasFRAM;           /* FRAM chunk processed */
-           mng_bool          bHasTERM;           /* TERM chunk processed */
-           mng_bool          bHasLOOP;           /* at least 1 LOOP open */
-
-           mng_bool          bHasglobalPLTE;     /* global PLTE chunk processed */
-           mng_bool          bHasglobalTRNS;     /* global tRNS chunk processed */
-           mng_bool          bHasglobalGAMA;     /* global gAMA chunk processed */
-           mng_bool          bHasglobalCHRM;     /* global cHRM chunk processed */
-           mng_bool          bHasglobalSRGB;     /* global sRGB chunk processed */
-           mng_bool          bHasglobalICCP;     /* global iCCP chunk processed */
-           mng_bool          bHasglobalBKGD;     /* global bKGD chunk processed */
-
-           mng_uint32        iDatawidth;         /* IHDR/BASI/DHDR fields */
-           mng_uint32        iDataheight;        /* valid if inside IHDR-IEND, */
-           mng_uint8         iBitdepth;          /* BASI-IEND or DHDR-IEND */
-           mng_uint8         iColortype;
-           mng_uint8         iCompression;
-           mng_uint8         iFilter;
-           mng_uint8         iInterlace;
-
-           mng_uint32        iPLTEcount;         /* PLTE fields */
-
-#ifdef MNG_INCLUDE_JNG
-           mng_uint8         iJHDRcolortype;     /* JHDR fields */
-           mng_uint8         iJHDRimgbitdepth;   /* valid if inside JHDR-IEND */
-           mng_uint8         iJHDRimgcompression;
-           mng_uint8         iJHDRimginterlace;
-           mng_uint8         iJHDRalphabitdepth;
-           mng_uint8         iJHDRalphacompression;
-           mng_uint8         iJHDRalphafilter;
-           mng_uint8         iJHDRalphainterlace;
-#endif
-
-#endif /* MNG_SUPPORT_READ || MNG_SUPPORT_WRITE */
-
-#ifdef MNG_SUPPORT_READ
-           mng_bool          bReading;           /* read processing variables */
-           mng_bool          bHavesig;
-           mng_bool          bEOF;
-           mng_uint32        iReadbufsize;
-           mng_uint8p        pReadbuf;
-
-           mng_uint32        iLargebufsize;      /* temp for very large chunks */
-           mng_uint8p        pLargebuf;
-
-           mng_uint32        iSuspendtime;       /* tickcount at last suspension */
-           mng_bool          bSuspended;         /* input-reading has been suspended;
-                                                    we're expecting a call to
-                                                    mng_read_resume! */
-           mng_uint8         iSuspendpoint;      /* indicates at which point the flow
-                                                    was broken to suspend input-reading */
-                                                    
-           mng_bool          bSuspensionmode;    /* I/O-suspension variables */
-           mng_uint32        iSuspendbufsize;
-           mng_uint8p        pSuspendbuf;
-           mng_uint8p        pSuspendbufnext;
-           mng_uint32        iSuspendbufleft;
-           mng_uint32        iChunklen;          /* chunk length */
-           mng_uint8p        pReadbufnext;       /* 32K+ suspension-processing */
-           mng_uint8p        pLargebufnext;
-
-           mng_pushdatap     pFirstpushchunk;    /* variables for push mechanisms */
-           mng_pushdatap     pLastpushchunk;
-           mng_pushdatap     pFirstpushdata;
-           mng_pushdatap     pLastpushdata;
-#endif /* MNG_SUPPORT_READ */
-
-#ifdef MNG_SUPPORT_WRITE
-           mng_bool          bCreating;          /* create/write processing variables */
-           mng_bool          bWriting;
-           mng_chunkid       iFirstchunkadded;
-           mng_uint32        iWritebufsize;
-           mng_uint8p        pWritebuf;
-#endif
-
-#ifdef MNG_SUPPORT_DISPLAY
-           mng_bool          bDisplaying;        /* display-state variables */
-           mng_bool          bFramedone;
-           mng_uint32        iFrameseq;
-           mng_uint32        iLayerseq;
-           mng_uint32        iFrametime;         /* millisecs */
-
-           mng_uint32        iTotalframes;       /* end-totals after mng_read() */
-           mng_uint32        iTotallayers;
-           mng_uint32        iTotalplaytime;     /* millisecs */
-
-           mng_bool          bSkipping;          /* LOOP iteration=0 */
-           
-#ifdef MNG_SUPPORT_DYNAMICMNG
-           mng_bool          bDynamic;           /* MNG is dynamic (eg. has events) */
-           mng_bool          bRunningevent;      /* currently processing an event */
-           mng_bool          bStopafterseek;     /* stop after next SEEK */
-           mng_int32         iEventx;            /* X/Y of current event */
-           mng_int32         iEventy;
-           mng_objectp       pLastmousemove;     /* last event triggered */
-#endif
-
-           mng_uint32        iRequestframe;      /* go_xxxx variables */
-           mng_uint32        iRequestlayer;
-           mng_uint32        iRequesttime;
-           mng_bool          bSearching;
-
-           mng_bool          bRestorebkgd;       /* flags restore required before IDAT/JDAT */
-
-           mng_uint32        iRuntime;           /* millisecs since start */
-           mng_uint32        iSynctime;          /* tickcount at last framesync */
-           mng_uint32        iStarttime;         /* tickcount at start */
-           mng_uint32        iEndtime;           /* tickcount at end */
-           mng_bool          bRunning;           /* animation is active */
-           mng_bool          bTimerset;          /* the timer has been set;
-                                                    we're expecting a call to
-                                                    mng_display_resume! */
-           mng_uint8         iBreakpoint;        /* indicates at which point the
-                                                    flow was broken to run the timer */
-           mng_bool          bSectionwait;       /* indicates a section break */
-           mng_bool          bFreezing;          /* indicates app requested a freeze */   
-           mng_bool          bResetting;         /* indicates app requested a reset */   
-           mng_bool          bNeedrefresh;       /* indicates screen-refresh is needed */
-           mng_bool          bMisplacedTERM;     /* indicates TERM is out of place */
-           mng_bool          bOnlyfirstframe;    /* show first frame after TERM and stop */
-           mng_uint32        iFramesafterTERM;   /* determines frame-count after TERM */          
-           mng_objectp       pCurrentobj;        /* current "object" */
-           mng_objectp       pCurraniobj;        /* current animation object
-                                                    "to be"/"being" processed */
-           mng_objectp       pTermaniobj;        /* TERM animation object */
-           mng_uint32        iIterations;        /* TERM/MEND iteration count */
-           mng_objectp       pObjzero;           /* "on-the-fly" image (object = 0) */
-           mng_objectp       pLastclone;         /* last clone */
-           mng_objectp       pStoreobj;          /* current store object for row routines */
-           mng_objectp       pStorebuf;          /* current store object-buffer for row routines */
-           mng_objectp       pRetrieveobj;       /* current retrieve object for row routines */
-           mng_savedatap     pSavedata;          /* pointer to saved data (after SAVE) */
-
-           mng_uint32        iUpdateleft;        /* update region for refresh */
-           mng_uint32        iUpdateright;
-           mng_uint32        iUpdatetop;
-           mng_uint32        iUpdatebottom;
-
-           mng_int8          iPass;              /* current interlacing pass;
-                                                    negative value means no interlace */
-           mng_int32         iRow;               /* current row counter */
-           mng_int32         iRowinc;            /* row increment for this pass */
-           mng_int32         iCol;               /* current starting column */
-           mng_int32         iColinc;            /* column increment for this pass */
-           mng_int32         iRowsamples;        /* nr. of samples in current workrow */
-           mng_int32         iSamplemul;         /* needed to calculate rowsize */
-           mng_int32         iSampleofs;            /* from rowsamples */
-           mng_int32         iSamplediv;
-           mng_int32         iRowsize;           /* size of actual data in work row */
-           mng_int32         iRowmax;            /* maximum size of data in work row */
-           mng_int32         iFilterofs;         /* offset to filter-byte in work row */
-           mng_int32         iPixelofs;          /* offset to pixel-bytes in work row */
-           mng_uint32        iLevel0;            /* leveling variables */
-           mng_uint32        iLevel1;
-           mng_uint32        iLevel2;
-           mng_uint32        iLevel3;
-           mng_uint8p        pWorkrow;           /* working row of pixel-data */
-           mng_uint8p        pPrevrow;           /* previous row of pixel-data */
-           mng_uint8p        pRGBArow;           /* intermediate row of RGBA8 or RGBA16 data */
-           mng_bool          bIsRGBA16;          /* indicates intermediate row is RGBA16 */
-           mng_bool          bIsOpaque;          /* indicates intermediate row is fully opaque */
-           mng_int32         iFilterbpp;         /* bpp index for filtering routines */
-
-           mng_int32         iSourcel;           /* variables for showing objects */
-           mng_int32         iSourcer;
-           mng_int32         iSourcet;
-           mng_int32         iSourceb;
-           mng_int32         iDestl;
-           mng_int32         iDestr;
-           mng_int32         iDestt;
-           mng_int32         iDestb;
-
-           mng_objectp       pFirstimgobj;       /* double-linked list of */
-           mng_objectp       pLastimgobj;        /* image-object structures */
-           mng_objectp       pFirstaniobj;       /* double-linked list of */
-           mng_objectp       pLastaniobj;        /* animation-object structures */
-#ifdef MNG_SUPPORT_DYNAMICMNG
-           mng_objectp       pFirstevent;        /* double-linked list of */
-           mng_objectp       pLastevent;         /* event-object structures */
-#endif
-
-#if defined(MNG_GAMMA_ONLY) || defined(MNG_FULL_CMS) || defined(MNG_APP_CMS)
-           mng_uint8         aGammatab[256];     /* precomputed gamma lookup table */
-           mng_float         dLastgamma;         /* last gamma used to compute table */
-#endif
-
-           mng_fptr          fDisplayrow;        /* internal callback to display an
-                                                    uncompressed/unfiltered/
-                                                    color-corrected row */
-           mng_fptr          fRestbkgdrow;       /* internal callback for restore-
-                                                    background processing of a row */
-           mng_fptr          fCorrectrow;        /* internal callback to color-correct an
-                                                    uncompressed/unfiltered row */
-           mng_fptr          fRetrieverow;       /* internal callback to retrieve an
-                                                    uncompressed/unfiltered row of data */
-           mng_fptr          fStorerow;          /* internal callback to store an
-                                                    uncompressed/unfiltered row of data */
-           mng_fptr          fProcessrow;        /* internal callback to process an
-                                                    uncompressed row of data */
-           mng_fptr          fDifferrow;         /* internal callback to perform
-                                                    added filter leveling and
-                                                    differing on an unfiltered row */
-           mng_fptr          fScalerow;          /* internal callback to scale a
-                                                    delta-row to the bitdepth of its target */
-           mng_fptr          fDeltarow;          /* internal callback to execute a
-                                                    delta-row onto a target */
-#ifndef MNG_SKIPCHUNK_PAST
-           mng_fptr          fFliprow;           /* internal callback to flip a row of pixels
-                                                    left<->right for a PAST operation */
-           mng_fptr          fTilerow;           /* internal callback to tile a row of pixels
-                                                    during a PAST operation */
-#endif
-           mng_fptr          fInitrowproc;       /* internal callback to initialize
-                                                    the row processing */
-
-           mng_uint16        iDEFIobjectid;      /* DEFI fields */
-           mng_bool          bDEFIhasdonotshow;
-           mng_uint8         iDEFIdonotshow;
-           mng_bool          bDEFIhasconcrete;
-           mng_uint8         iDEFIconcrete;
-           mng_bool          bDEFIhasloca;
-           mng_int32         iDEFIlocax;
-           mng_int32         iDEFIlocay;
-           mng_bool          bDEFIhasclip;
-           mng_int32         iDEFIclipl;
-           mng_int32         iDEFIclipr;
-           mng_int32         iDEFIclipt;
-           mng_int32         iDEFIclipb;
-
-           mng_uint16        iBACKred;           /* BACK fields */
-           mng_uint16        iBACKgreen;
-           mng_uint16        iBACKblue;
-           mng_uint8         iBACKmandatory;
-           mng_uint16        iBACKimageid;
-           mng_uint8         iBACKtile;
-
-           mng_int32         iBackimgoffsx;      /* temp variables for restore_bkgd */
-           mng_int32         iBackimgoffsy;
-           mng_uint32        iBackimgwidth;
-           mng_uint32        iBackimgheight;
-
-#ifndef MNG_SKIPCHUNK_FRAM
-           mng_uint8         iFRAMmode;          /* FRAM fields (global) */
-           mng_uint32        iFRAMdelay;
-           mng_uint32        iFRAMtimeout;
-           mng_bool          bFRAMclipping;
-           mng_int32         iFRAMclipl;
-           mng_int32         iFRAMclipr;
-           mng_int32         iFRAMclipt;
-           mng_int32         iFRAMclipb;
-
-           mng_uint8         iFramemode;         /* current subframe variables */
-           mng_uint32        iFramedelay;
-           mng_uint32        iFrametimeout;
-           mng_bool          bFrameclipping;
-           mng_int32         iFrameclipl;
-           mng_int32         iFrameclipr;
-           mng_int32         iFrameclipt;
-           mng_int32         iFrameclipb;
-
-           mng_uint32        iNextdelay;         /* delay *after* next image */
-#endif
-
-#ifndef MNG_SKIPCHUNK_SHOW
-           mng_uint8         iSHOWmode;          /* SHOW fields */
-           mng_uint16        iSHOWfromid;
-           mng_uint16        iSHOWtoid;
-           mng_uint16        iSHOWnextid;
-           mng_int16         iSHOWskip;
-#endif
-
-           mng_uint32        iGlobalPLTEcount;   /* global PLTE fields */
-           mng_rgbpaltab     aGlobalPLTEentries;
-
-           mng_uint32        iGlobalTRNSrawlen;  /* global tRNS fields */
-           mng_uint8arr      aGlobalTRNSrawdata;
-
-           mng_uint32        iGlobalGamma;       /* global gAMA fields */
-
-#ifndef MNG_SKIPCHUNK_cHRM
-           mng_uint32        iGlobalWhitepointx; /* global cHRM fields */
-           mng_uint32        iGlobalWhitepointy;
-           mng_uint32        iGlobalPrimaryredx;
-           mng_uint32        iGlobalPrimaryredy;
-           mng_uint32        iGlobalPrimarygreenx;
-           mng_uint32        iGlobalPrimarygreeny;
-           mng_uint32        iGlobalPrimarybluex;
-           mng_uint32        iGlobalPrimarybluey;
-#endif
-
-           mng_uint8         iGlobalRendintent;  /* global sRGB fields */
-
-#ifndef MNG_SKIPCHUNK_iCCP
-           mng_uint32        iGlobalProfilesize; /* global iCCP fields */
-           mng_ptr           pGlobalProfile;
-#endif
-
-           mng_uint16        iGlobalBKGDred;     /* global bKGD fields */
-           mng_uint16        iGlobalBKGDgreen;
-           mng_uint16        iGlobalBKGDblue;
-
-           mng_ptr           pDeltaImage;        /* delta-image fields */
-           mng_uint8         iDeltaImagetype;
-#endif /* MNG_SUPPORT_DISPLAY */
-           mng_uint8         iDeltatype;         /* need this one in read processing !! */
-#ifdef MNG_SUPPORT_DISPLAY
-           mng_uint32        iDeltaBlockwidth;
-           mng_uint32        iDeltaBlockheight;
-           mng_uint32        iDeltaBlockx;
-           mng_uint32        iDeltaBlocky;
-           mng_bool          bDeltaimmediate;
-
-           mng_fptr          fDeltagetrow;       /* internal delta-proc callbacks */
-           mng_fptr          fDeltaaddrow;
-           mng_fptr          fDeltareplacerow;
-           mng_fptr          fDeltaputrow;
-
-#ifndef MNG_SKIPCHUNK_PROM
-           mng_fptr          fPromoterow;        /* internal PROM fields */
-           mng_fptr          fPromBitdepth;
-           mng_ptr           pPromBuf;
-           mng_uint8         iPromColortype;
-           mng_uint8         iPromBitdepth;
-           mng_uint8         iPromFilltype;
-           mng_uint32        iPromWidth;
-           mng_ptr           pPromSrc;
-           mng_ptr           pPromDst;
-#endif
-
-#ifndef MNG_SKIPCHUNK_MAGN
-           mng_uint16        iMAGNfromid;
-           mng_uint16        iMAGNcurrentid;
-           mng_uint16        iMAGNtoid;
-#endif
-
-#ifndef MNG_SKIPCHUNK_PAST
-           mng_uint16        iPASTid;
-           mng_int32         iPastx;             /* target x/y of last PAST */
-           mng_int32         iPasty;
-#endif
-
-           mng_objectp       pLastseek;          /* last processed ani_seek object */
-
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-           mng_objectp       pMPNG;              /* mpNG object if available */
-#endif
-#ifdef MNG_INCLUDE_ANG_PROPOSAL
-           mng_objectp       pANG;               /* ANG object if available */
-#endif
-
-#endif /* MNG_SUPPORT_DISPLAY */
-
-#ifdef MNG_INCLUDE_ZLIB
-           z_stream          sZlib;              /* zlib (de)compression variables */
-
-           mng_int32         iZlevel;            /* zlib compression parameters */
-           mng_int32         iZmethod;
-           mng_int32         iZwindowbits;
-           mng_int32         iZmemlevel;
-           mng_int32         iZstrategy;
-
-           mng_uint32        iMaxIDAT;           /* maximum size of IDAT data */
-
-           mng_bool          bInflating;         /* indicates "inflate" in progress */
-           mng_bool          bDeflating;         /* indicates "deflate" in progress */
-#endif /* MNG_INCLUDE_ZLIB */
-
-#ifdef MNG_INCLUDE_JNG
-           mngjpeg_dctmethod eJPEGdctmethod;     /* IJG compression variables */
-           mng_int32         iJPEGquality;
-           mng_int32         iJPEGsmoothing;
-           mng_bool          bJPEGcompressprogr;
-           mng_bool          bJPEGcompressopt;
-
-           mng_uint32        iMaxJDAT;           /* maximum size of JDAT/JDAA data */
-
-           mngjpeg_compp     pJPEGcinfo;         /* compression structure */
-           mngjpeg_errorp    pJPEGcerr;          /* error-manager compress */
-
-           mngjpeg_decompp   pJPEGdinfo;         /* decompression structure (JDAT) */
-           mngjpeg_errorp    pJPEGderr;          /* error-manager decompress (JDAT) */
-           mngjpeg_sourcep   pJPEGdsrc;          /* source-manager decompress (JDAT) */
-
-           mngjpeg_decompp   pJPEGdinfo2;        /* decompression structure (JDAA) */
-           mngjpeg_errorp    pJPEGderr2;         /* error-manager decompress (JDAA) */
-           mngjpeg_sourcep   pJPEGdsrc2;         /* source-manager decompress (JDAA) */
-
-           mng_uint8p        pJPEGbuf;           /* buffer for JPEG (de)compression (JDAT) */
-           mng_uint32        iJPEGbufmax;        /* allocated space for buffer (JDAT) */
-           mng_uint8p        pJPEGcurrent;       /* current pointer into buffer (JDAT) */
-           mng_uint32        iJPEGbufremain;     /* remaining bytes in buffer (JDAT) */
-           mng_uint32        iJPEGtoskip;        /* bytes to skip on next input-block (JDAT) */
-
-           mng_uint8p        pJPEGbuf2;          /* buffer for JPEG (de)compression (JDAA) */
-           mng_uint32        iJPEGbufmax2;       /* allocated space for buffer (JDAA) */
-           mng_uint8p        pJPEGcurrent2;      /* current pointer into buffer (JDAA) */
-           mng_uint32        iJPEGbufremain2;    /* remaining bytes in buffer (JDAA) */
-           mng_uint32        iJPEGtoskip2;       /* bytes to skip on next input-block (JDAA) */
-
-           mng_uint8p        pJPEGrow;           /* buffer for a JPEG row of samples (JDAT) */
-           mng_uint32        iJPEGrowlen;
-
-           mng_uint8p        pJPEGrow2;          /* buffer for a JPEG row of samples (JDAA) */
-           mng_uint32        iJPEGrowlen2;
-
-           mng_bool          bJPEGcompress;      /* indicates "compress" initialized */
-
-           mng_bool          bJPEGdecompress;    /* indicates "decompress" initialized (JDAT) */
-           mng_bool          bJPEGhasheader;     /* indicates "readheader" succeeded (JDAT) */
-           mng_bool          bJPEGdecostarted;   /* indicates "decompress" started (JDAT) */
-           mng_bool          bJPEGscanstarted;   /* indicates "first scan" started (JDAT) */
-           mng_bool          bJPEGscanending;    /* indicates "finish_output" suspended (JDAT) */
-           mng_bool          bJPEGprogressive;   /* indicates a progressive image (JDAT) */
-
-           mng_bool          bJPEGdecompress2;   /* indicates "decompress" initialized (JDAA) */
-           mng_bool          bJPEGhasheader2;    /* indicates "readheader" succeeded (JDAA) */
-           mng_bool          bJPEGdecostarted2;  /* indicates "decompress" started (JDAA) */
-           mng_bool          bJPEGscanstarted2;  /* indicates "first scan" started (JDAA) */
-           mng_bool          bJPEGprogressive2;  /* indicates a progressive image (JDAA) */
-
-           mng_fptr          fStorerow2;         /* internal callback to store an
-                                                    uncompressed/unfiltered row of JPEG-data (JDAT) */
-
-           mng_fptr          fStorerow3;         /* internal callback to store an
-                                                    uncompressed/unfiltered row of JPEG-data (JDAA) */
-
-           mng_uint32        iJPEGrow;           /* row-number for current JPEG row */
-           mng_uint32        iJPEGalpharow;      /* nr. of rows filled with alpha */
-           mng_uint32        iJPEGrgbrow;        /* nr. of rows filled with 'color'-info */
-           mng_uint32        iJPEGdisprow;       /* nr. of rows already displayed "on-the-fly" */
-
-#if defined(MNG_USE_SETJMP) && defined (MNG_INCLUDE_IJG6B)
-           jmp_buf           sErrorbuf;          /* setjmp/longjmp buffer (error-recovery) */
-#endif
-
-#endif /* MNG_INCLUDE_JNG */
-
-#ifndef MNG_USE_ZLIB_CRC
-           mng_uint32        aCRCtable [256];    /* CRC prefab table */
-           mng_bool          bCRCcomputed;       /* "has been built" indicator */
-#endif
-
-#ifdef MNG_OPTIMIZE_FOOTPRINT_INIT
-           png_imgtype       ePng_imgtype;
-#endif
-
-#if defined(MNG_NO_1_2_4BIT_SUPPORT) || defined(MNG_NO_16BIT_SUPPORT)
-           mng_uint8         iPNGdepth;          /* Real input depth */
-           mng_uint8         iPNGmult;
-#endif
-
-#ifdef MNG_OPTIMIZE_DISPLAYCALLS
-           mng_uint32        iRawlen;            /* temp vars for display processing */
-           mng_uint8p        pRawdata;
-#ifndef MNG_SKIPCHUNK_BASI
-           mng_uint16        iBASIred;
-           mng_uint16        iBASIgreen;
-           mng_uint16        iBASIblue;
-           mng_bool          bBASIhasalpha;
-           mng_uint16        iBASIalpha;
-           mng_uint8         iBASIviewable;
-#endif
-#ifndef MNG_SKIPCHUNK_CLON
-           mng_uint16        iCLONsourceid;
-           mng_uint16        iCLONcloneid;
-           mng_uint8         iCLONclonetype;
-           mng_bool          bCLONhasdonotshow;
-           mng_uint8         iCLONdonotshow;
-           mng_uint8         iCLONconcrete;
-           mng_bool          bCLONhasloca;
-           mng_uint8         iCLONlocationtype;
-           mng_int32         iCLONlocationx;
-           mng_int32         iCLONlocationy;
-#endif
-#ifndef MNG_SKIPCHUNK_DISC
-           mng_uint32        iDISCcount;
-           mng_uint16p       pDISCids;
-#endif
-#ifndef MNG_SKIPCHUNK_FRAM
-           mng_uint8         iTempFramemode;
-           mng_uint8         iTempChangedelay;
-           mng_uint32        iTempDelay;
-           mng_uint8         iTempChangetimeout;
-           mng_uint32        iTempTimeout;
-           mng_uint8         iTempChangeclipping;
-           mng_uint8         iTempCliptype;
-           mng_int32         iTempClipl;
-           mng_int32         iTempClipr;
-           mng_int32         iTempClipt;
-           mng_int32         iTempClipb;
-#endif
-#ifndef MNG_SKIPCHUNK_MOVE
-           mng_uint16        iMOVEfromid;
-           mng_uint16        iMOVEtoid;
-           mng_uint8         iMOVEmovetype;
-           mng_int32         iMOVEmovex;
-           mng_int32         iMOVEmovey;
-#endif
-#ifndef MNG_SKIPCHUNK_CLIP
-           mng_uint16        iCLIPfromid;
-           mng_uint16        iCLIPtoid;
-           mng_uint8         iCLIPcliptype;
-           mng_int32         iCLIPclipl;
-           mng_int32         iCLIPclipr;
-           mng_int32         iCLIPclipt;
-           mng_int32         iCLIPclipb;
-#endif
-#ifndef MNG_NO_DELTA_PNG
-           mng_uint16        iDHDRobjectid;
-           mng_uint8         iDHDRimagetype;
-           mng_uint8         iDHDRdeltatype;
-           mng_uint32        iDHDRblockwidth;
-           mng_uint32        iDHDRblockheight;
-           mng_uint32        iDHDRblockx;
-           mng_uint32        iDHDRblocky;
-           mng_uint8         iPROMbitdepth;
-           mng_uint8         iPROMcolortype;
-           mng_uint8         iPROMfilltype;
-           mng_uint8         iPPLTtype;
-           mng_uint32        iPPLTcount;
-           mng_palette8ep    paPPLTindexentries;
-           mng_uint8p        paPPLTalphaentries;
-           mng_uint8p        paPPLTusedentries;
-#endif
-#ifndef MNG_SKIPCHUNK_MAGN
-           mng_uint16        iMAGNfirstid;
-           mng_uint16        iMAGNlastid;
-           mng_uint8         iMAGNmethodX;
-           mng_uint16        iMAGNmX;
-           mng_uint16        iMAGNmY;
-           mng_uint16        iMAGNmL;
-           mng_uint16        iMAGNmR;
-           mng_uint16        iMAGNmT;
-           mng_uint16        iMAGNmB;
-           mng_uint8         iMAGNmethodY;
-#endif
-#ifndef MNG_SKIPCHUNK_PAST
-           mng_uint16        iPASTtargetid;
-           mng_uint8         iPASTtargettype;
-           mng_int32         iPASTtargetx;
-           mng_int32         iPASTtargety;
-           mng_uint32        iPASTcount;
-           mng_ptr           pPASTsources;
-#endif
-#endif /* MNG_OPTIMIZE_DISPLAYCALLS */
-
-        } mng_data;
-
-typedef mng_data * mng_datap;
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Internal Callback-Function prototypes                                  * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-typedef mng_retcode(*mng_displayrow)  (mng_datap  pData);
-typedef mng_retcode(*mng_restbkgdrow) (mng_datap  pData);
-typedef mng_retcode(*mng_correctrow)  (mng_datap  pData);
-typedef mng_retcode(*mng_retrieverow) (mng_datap  pData);
-typedef mng_retcode(*mng_storerow)    (mng_datap  pData);
-typedef mng_retcode(*mng_processrow)  (mng_datap  pData);
-typedef mng_retcode(*mng_initrowproc) (mng_datap  pData);
-typedef mng_retcode(*mng_differrow)   (mng_datap  pData);
-typedef mng_retcode(*mng_scalerow)    (mng_datap  pData);
-typedef mng_retcode(*mng_deltarow)    (mng_datap  pData);
-typedef mng_retcode(*mng_promoterow)  (mng_datap  pData);
-typedef mng_retcode(*mng_fliprow)     (mng_datap  pData);
-typedef mng_retcode(*mng_tilerow)     (mng_datap  pData);
-
-typedef mng_uint8  (*mng_bitdepth_8)  (mng_uint8  iB);
-typedef mng_uint16 (*mng_bitdepth_16) (mng_uint8  iB);
-
-typedef mng_retcode(*mng_magnify_x)   (mng_datap  pData,
-                                       mng_uint16 iMX,
-                                       mng_uint16 iML,
-                                       mng_uint16 iMR,
-                                       mng_uint32 iWidth,
-                                       mng_uint8p iSrcline,
-                                       mng_uint8p iDstline);
-typedef mng_retcode(*mng_magnify_y)   (mng_datap  pData,
-                                       mng_int32  iM,
-                                       mng_int32  iS,
-                                       mng_uint32 iWidth,
-                                       mng_uint8p iSrcline1,
-                                       mng_uint8p iSrcline2,
-                                       mng_uint8p iDstline);
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Routines for swapping byte-order from and to graphic files             * */
-/* * (This code is adapted from the libpng package)                         * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifndef MNG_BIGENDIAN_SUPPORTED
-mng_uint32 mng_get_uint32 (mng_uint8p pBuf);
-mng_int32  mng_get_int32  (mng_uint8p pBuf);
-mng_uint16 mng_get_uint16 (mng_uint8p pBuf);
-void       mng_put_uint32 (mng_uint8p pBuf,
-                           mng_uint32 i);
-void       mng_put_int32  (mng_uint8p pBuf,
-                           mng_int32  i);
-void       mng_put_uint16 (mng_uint8p pBuf,
-                           mng_uint16 i);
-#else /* MNG_BIGENDIAN_SUPPORTED */
-#define mng_get_uint32(P)   *(mng_uint32p)(P)
-#define mng_get_int32(P)    *(mng_int32p)(P)
-#define mng_get_uint16(P)   *(mng_uint16p)(P)
-#define mng_put_uint32(P,I) *(mng_uint32p)(P) = (I)
-#define mng_put_int32(P,I)  *(mng_int32p)(P) = (I)
-#define mng_put_uint16(P,I) *(mng_uint16p)(P) = (I)
-#endif /* MNG_BIGENDIAN_SUPPORTED */
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Some handy(?) macro definitions                                        * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#define MAX_COORD(a, b)  (((a) > (b)) ? (a) : (b))
-#define MIN_COORD(a, b)  (((a) < (b)) ? (a) : (b))
-
-/* ************************************************************************** */
-
-#endif /* _libmng_data_h_ */
-
-/* ************************************************************************** */
-/* * end of file                                                            * */
-/* ************************************************************************** */
diff --git a/Source/LibMNG/libmng_display.c b/Source/LibMNG/libmng_display.c
deleted file mode 100644
index 65a5c31..0000000
--- a/Source/LibMNG/libmng_display.c
+++ /dev/null
@@ -1,7135 +0,0 @@
-/* ************************************************************************** */
-/* *             For conditions of distribution and use,                    * */
-/* *                see copyright notice in libmng.h                        * */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * project   : libmng                                                     * */
-/* * file      : libmng_display.c          copyright (c) 2000-2007 G.Juyn   * */
-/* * version   : 1.0.10                                                     * */
-/* *                                                                        * */
-/* * purpose   : Display management (implementation)                        * */
-/* *                                                                        * */
-/* * author    : G.Juyn                                                     * */
-/* *                                                                        * */
-/* * comment   : implementation of the display management routines          * */
-/* *                                                                        * */
-/* * changes   : 0.5.1 - 05/08/2000 - G.Juyn                                * */
-/* *             - changed strict-ANSI stuff                                * */
-/* *             0.5.1 - 05/11/2000 - G.Juyn                                * */
-/* *             - added callback error-reporting support                   * */
-/* *             - fixed frame_delay misalignment                           * */
-/* *             0.5.1 - 05/12/2000 - G.Juyn                                * */
-/* *             - added sanity check for frozen status                     * */
-/* *             - changed trace to macro for callback error-reporting      * */
-/* *             0.5.1 - 05/13/2000 - G.Juyn                                * */
-/* *             - changed display_mend to reset state to initial or SAVE   * */
-/* *             - added eMNGma hack (will be removed in 1.0.0 !!!)         * */
-/* *             - added TERM animation object pointer (easier reference)   * */
-/* *             - added process_save & process_seek routines               * */
-/* *             0.5.1 - 05/14/2000 - G.Juyn                                * */
-/* *             - added save_state and restore_state for SAVE/SEEK/TERM    * */
-/* *               processing                                               * */
-/* *                                                                        * */
-/* *             0.5.2 - 05/20/2000 - G.Juyn                                * */
-/* *             - added JNG support (JHDR/JDAT)                            * */
-/* *             0.5.2 - 05/23/2000 - G.Juyn                                * */
-/* *             - fixed problem with DEFI clipping                         * */
-/* *             0.5.2 - 05/30/2000 - G.Juyn                                * */
-/* *             - added delta-image support (DHDR,PROM,IPNG,IJNG)          * */
-/* *             0.5.2 - 05/31/2000 - G.Juyn                                * */
-/* *             - fixed pointer confusion (contributed by Tim Rowley)      * */
-/* *             0.5.2 - 06/03/2000 - G.Juyn                                * */
-/* *             - fixed makeup for Linux gcc compile                       * */
-/* *             0.5.2 - 06/05/2000 - G.Juyn                                * */
-/* *             - added support for RGB8_A8 canvasstyle                    * */
-/* *             0.5.2 - 06/09/2000 - G.Juyn                                * */
-/* *             - fixed timer-handling to run with Mozilla (Tim Rowley)    * */
-/* *             0.5.2 - 06/10/2000 - G.Juyn                                * */
-/* *             - fixed some compilation-warnings (contrib Jason Morris)   * */
-/* *                                                                        * */
-/* *             0.5.3 - 06/12/2000 - G.Juyn                                * */
-/* *             - fixed display of stored JNG images                       * */
-/* *             0.5.3 - 06/13/2000 - G.Juyn                                * */
-/* *             - fixed problem with BASI-IEND as object 0                 * */
-/* *             0.5.3 - 06/16/2000 - G.Juyn                                * */
-/* *             - changed progressive-display processing                   * */
-/* *             0.5.3 - 06/17/2000 - G.Juyn                                * */
-/* *             - changed delta-image processing                           * */
-/* *             0.5.3 - 06/20/2000 - G.Juyn                                * */
-/* *             - fixed some minor stuff                                   * */
-/* *             0.5.3 - 06/21/2000 - G.Juyn                                * */
-/* *             - added speed-modifier to timing routine                   * */
-/* *             0.5.3 - 06/22/2000 - G.Juyn                                * */
-/* *             - added support for PPLT chunk processing                  * */
-/* *             0.5.3 - 06/29/2000 - G.Juyn                                * */
-/* *             - swapped refresh parameters                               * */
-/* *                                                                        * */
-/* *             0.9.0 - 06/30/2000 - G.Juyn                                * */
-/* *             - changed refresh parameters to 'x,y,width,height'         * */
-/* *                                                                        * */
-/* *             0.9.1 - 07/07/2000 - G.Juyn                                * */
-/* *             - implemented support for freeze/reset/resume & go_xxxx    * */
-/* *             0.9.1 - 07/08/2000 - G.Juyn                                * */
-/* *             - added support for improved timing                        * */
-/* *             0.9.1 - 07/14/2000 - G.Juyn                                * */
-/* *             - changed EOF processing behavior                          * */
-/* *             - fixed TERM delay processing                              * */
-/* *             0.9.1 - 07/15/2000 - G.Juyn                                * */
-/* *             - fixed freeze & reset processing                          * */
-/* *             0.9.1 - 07/16/2000 - G.Juyn                                * */
-/* *             - fixed storage of images during mng_read()                * */
-/* *             - fixed support for mng_display() after mng_read()         * */
-/* *             0.9.1 - 07/24/2000 - G.Juyn                                * */
-/* *             - fixed reading of still-images                            * */
-/* *                                                                        * */
-/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
-/* *             - changed file-prefixes                                    * */
-/* *                                                                        * */
-/* *             0.9.3 - 08/07/2000 - G.Juyn                                * */
-/* *             - B111300 - fixup for improved portability                 * */
-/* *             0.9.3 - 08/21/2000 - G.Juyn                                * */
-/* *             - fixed TERM processing delay of 0 msecs                   * */
-/* *             0.9.3 - 08/26/2000 - G.Juyn                                * */
-/* *             - added MAGN chunk                                         * */
-/* *             0.9.3 - 09/10/2000 - G.Juyn                                * */
-/* *             - fixed problem with no refresh after TERM                 * */
-/* *             - fixed DEFI behavior                                      * */
-/* *             0.9.3 - 09/16/2000 - G.Juyn                                * */
-/* *             - fixed timing & refresh behavior for single PNG/JNG       * */
-/* *             0.9.3 - 09/19/2000 - G.Juyn                                * */
-/* *             - refixed timing & refresh behavior for single PNG/JNG     * */
-/* *             0.9.3 - 10/02/2000 - G.Juyn                                * */
-/* *             - fixed timing again (this is getting boring...)           * */
-/* *             - refixed problem with no refresh after TERM               * */
-/* *             0.9.3 - 10/16/2000 - G.Juyn                                * */
-/* *             - added JDAA chunk                                         * */
-/* *             0.9.3 - 10/17/2000 - G.Juyn                                * */
-/* *             - fixed support for bKGD                                   * */
-/* *             0.9.3 - 10/18/2000 - G.Juyn                                * */
-/* *             - fixed delta-processing behavior                          * */
-/* *             0.9.3 - 10/19/2000 - G.Juyn                                * */
-/* *             - added storage for pixel-/alpha-sampledepth for delta's   * */
-/* *             0.9.3 - 10/27/2000 - G.Juyn                                * */
-/* *             - fixed separate read() & display() processing             * */
-/* *                                                                        * */
-/* *             0.9.4 - 10/31/2000 - G.Juyn                                * */
-/* *             - fixed possible loop in display_resume() (Thanks Vova!)   * */
-/* *             0.9.4 - 11/20/2000 - G.Juyn                                * */
-/* *             - fixed unwanted repetition in mng_readdisplay()           * */
-/* *             0.9.4 - 11/24/2000 - G.Juyn                                * */
-/* *             - moved restore of object 0 to libmng_display              * */
-/* *             - added restore of object 0 to TERM processing !!!         * */
-/* *             - fixed TERM delay processing                              * */
-/* *             - fixed TERM end processing (count = 0)                    * */
-/* *             0.9.4 - 12/16/2000 - G.Juyn                                * */
-/* *             - fixed mixup of data- & function-pointers (thanks Dimitri)* */
-/* *             0.9.4 -  1/18/2001 - G.Juyn                                * */
-/* *             - removed test filter-methods 1 & 65                       * */
-/* *             - set default level-set for filtertype=64 to all zeroes    * */
-/* *                                                                        * */
-/* *             0.9.5 -  1/20/2001 - G.Juyn                                * */
-/* *             - fixed compiler-warnings Mozilla (thanks Tim)             * */
-/* *             0.9.5 -  1/23/2001 - G.Juyn                                * */
-/* *             - fixed timing-problem with switching framing_modes        * */
-/* *                                                                        * */
-/* *             1.0.1 - 02/08/2001 - G.Juyn                                * */
-/* *             - added MEND processing callback                           * */
-/* *             1.0.1 - 02/13/2001 - G.Juyn                                * */
-/* *             - fixed first FRAM_MODE=4 timing problem                   * */
-/* *             1.0.1 - 04/21/2001 - G.Juyn                                * */
-/* *             - fixed memory-leak for JNGs with alpha (Thanks Gregg!)    * */
-/* *             - added BGRA8 canvas with premultiplied alpha              * */
-/* *                                                                        * */
-/* *             1.0.2 - 06/25/2001 - G.Juyn                                * */
-/* *             - fixed memory-leak with delta-images (Thanks Michael!)    * */
-/* *                                                                        * */
-/* *             1.0.5 - 08/15/2002 - G.Juyn                                * */
-/* *             - completed PROM support                                   * */
-/* *             - completed delta-image support                            * */
-/* *             1.0.5 - 08/19/2002 - G.Juyn                                * */
-/* *             - B597134 - libmng pollutes the linker namespace           * */
-/* *             1.0.5 - 09/13/2002 - G.Juyn                                * */
-/* *             - fixed read/write of MAGN chunk                           * */
-/* *             1.0.5 - 09/15/2002 - G.Juyn                                * */
-/* *             - fixed LOOP iteration=0 special case                      * */
-/* *             1.0.5 - 09/19/2002 - G.Juyn                                * */
-/* *             - fixed color-correction for restore-background handling   * */
-/* *             - optimized restore-background for bKGD cases              * */
-/* *             - cleaned up some old stuff                                * */
-/* *             1.0.5 - 09/20/2002 - G.Juyn                                * */
-/* *             - finished support for BACK image & tiling                 * */
-/* *             - added support for PAST                                   * */
-/* *             1.0.5 - 09/22/2002 - G.Juyn                                * */
-/* *             - added bgrx8 canvas (filler byte)                         * */
-/* *             1.0.5 - 10/05/2002 - G.Juyn                                * */
-/* *             - fixed dropping mix of frozen/unfrozen objects            * */
-/* *             1.0.5 - 10/07/2002 - G.Juyn                                * */
-/* *             - added proposed change in handling of TERM- & if-delay    * */
-/* *             - added another fix for misplaced TERM chunk               * */
-/* *             - completed support for condition=2 in TERM chunk          * */
-/* *             1.0.5 - 10/18/2002 - G.Juyn                                * */
-/* *             - fixed clipping-problem with BACK tiling (Thanks Sakura!) * */
-/* *             1.0.5 - 10/20/2002 - G.Juyn                                * */
-/* *             - fixed processing for multiple objects in MAGN            * */
-/* *             - fixed display of visible target of PAST operation        * */
-/* *             1.0.5 - 10/30/2002 - G.Juyn                                * */
-/* *             - modified TERM/MEND processing for max(1, TERM_delay,     * */
-/* *               interframe_delay)                                        * */
-/* *             1.0.5 - 11/04/2002 - G.Juyn                                * */
-/* *             - fixed layer- & frame-counting during read()              * */
-/* *             - fixed goframe/golayer/gotime processing                  * */
-/* *             1.0.5 - 01/19/2003 - G.Juyn                                * */
-/* *             - B654627 - fixed SEGV when no gettickcount callback       * */
-/* *             - B664383 - fixed typo                                     * */
-/* *             - finalized changes in TERM/final_delay to elected proposal* */
-/* *                                                                        * */
-/* *             1.0.6 - 05/11/2003 - G. Juyn                               * */
-/* *             - added conditionals around canvas update routines         * */
-/* *             1.0.6 - 05/25/2003 - G.R-P                                 * */
-/* *             - added MNG_SKIPCHUNK_cHNK footprint optimizations         * */
-/* *             1.0.6 - 07/07/2003 - G.R-P                                 * */
-/* *             - added conditionals around some JNG-supporting code       * */
-/* *             - added conditionals around 16-bit supporting code         * */
-/* *             - reversed some loops to use decrementing counter          * */
-/* *             - combined init functions into one function                * */
-/* *             1.0.6 - 07/10/2003 - G.R-P                                 * */
-/* *             - replaced nested switches with simple init setup function * */
-/* *             1.0.6 - 07/29/2003 - G.R-P                                 * */
-/* *             - added conditionals around PAST chunk support             * */
-/* *             1.0.6 - 08/17/2003 - G.R-P                                 * */
-/* *             - added conditionals around non-VLC chunk support          * */
-/* *                                                                        * */
-/* *             1.0.7 - 11/27/2003 - R.A                                   * */
-/* *             - added CANVAS_RGB565 and CANVAS_BGR565                    * */
-/* *             1.0.7 - 12/06/2003 - R.A                                   * */
-/* *             - added CANVAS_RGBA565 and CANVAS_BGRA565                  * */
-/* *             1.0.7 - 01/25/2004 - J.S                                   * */
-/* *             - added premultiplied alpha canvas' for RGBA, ARGB, ABGR   * */
-/* *                                                                        * */
-/* *             1.0.8 - 03/31/2004 - G.Juyn                                * */
-/* *             - fixed problem with PAST usage where source > dest        * */
-/* *             1.0.8 - 05/04/2004 - G.R-P.                                * */
-/* *             - fixed misplaced 16-bit conditionals                      * */
-/* *                                                                        * */
-/* *             1.0.9 - 09/18/2004 - G.R-P.                                * */
-/* *             - revised some SKIPCHUNK conditionals                      * */
-/* *             1.0.9 - 10/10/2004 - G.R-P.                                * */
-/* *             - added MNG_NO_1_2_4BIT_SUPPORT                            * */
-/* *             1.0.9 - 10/14/2004 - G.Juyn                                * */
-/* *             - added bgr565_a8 canvas-style (thanks to J. Elvander)     * */
-/* *             1.0.9 - 12/11/2004 - G.Juyn                                * */
-/* *             - added conditional MNG_OPTIMIZE_DISPLAYCALLS              * */
-/* *             1.0.9 - 12/20/2004 - G.Juyn                                * */
-/* *             - cleaned up macro-invocations (thanks to D. Airlie)       * */
-/* *                                                                        * */
-/* *             1.0.10 - 07/06/2005 - G.R-P.                               * */
-/* *             - added more SKIPCHUNK conditionals                        * */
-/* *             1.0.10 - 12/28/2005 - G.R-P.                               * */
-/* *             - added missing SKIPCHUNK_MAGN conditional                 * */
-/* *             1.0.10 - 03/07/2006 - (thanks to W. Manthey)               * */
-/* *             - added CANVAS_RGB555 and CANVAS_BGR555                    * */
-/* *             1.0.10 - 04/08/2007 - G.Juyn                               * */
-/* *             - fixed several compiler warnings                          * */
-/* *             1.0.10 - 04/08/2007 - G.Juyn                               * */
-/* *             - added support for mPNG proposal                          * */
-/* *             1.0.10 - 04/12/2007 - G.Juyn                               * */
-/* *             - added support for ANG proposal                           * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#include "libmng.h"
-#include "libmng_data.h"
-#include "libmng_error.h"
-#include "libmng_trace.h"
-#ifdef __BORLANDC__
-#pragma hdrstop
-#endif
-#include "libmng_chunks.h"
-#include "libmng_objects.h"
-#include "libmng_object_prc.h"
-#include "libmng_memory.h"
-#include "libmng_zlib.h"
-#include "libmng_jpeg.h"
-#include "libmng_cms.h"
-#include "libmng_pixels.h"
-#include "libmng_display.h"
-
-#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
-#pragma option -A                      /* force ANSI-C */
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_DISPLAY_PROCS
-
-/* ************************************************************************** */
-
-MNG_LOCAL mng_retcode set_delay (mng_datap  pData,
-                                 mng_uint32 iInterval)
-{
-  if (!iInterval)                      /* at least 1 msec please! */
-    iInterval = 1;
-
-  if (pData->bRunning)                 /* only when really displaying */
-    if (!pData->fSettimer ((mng_handle)pData, iInterval))
-      MNG_ERROR (pData, MNG_APPTIMERERROR);
-
-#ifdef MNG_SUPPORT_DYNAMICMNG
-  if ((!pData->bDynamic) || (pData->bRunning))
-#else
-  if (pData->bRunning)
-#endif
-    pData->bTimerset = MNG_TRUE;       /* and indicate so */
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-MNG_LOCAL mng_uint32 calculate_delay (mng_datap  pData,
-                                      mng_uint32 iDelay)
-{
-  mng_uint32 iTicks   = pData->iTicks;
-  mng_uint32 iWaitfor = 1;             /* default non-MNG delay */
-
-  if (!iTicks)                         /* tick_count not specified ? */
-    if (pData->eImagetype == mng_it_mng)
-      iTicks = 1000;
-
-  if (iTicks)
-  {
-    switch (pData->iSpeed)             /* honor speed modifier */
-    {
-      case mng_st_fast :
-        {
-          iWaitfor = (mng_uint32)(( 500 * iDelay) / iTicks);
-          break;
-        }
-      case mng_st_slow :
-        {
-          iWaitfor = (mng_uint32)((3000 * iDelay) / iTicks);
-          break;
-        }
-      case mng_st_slowest :
-        {
-          iWaitfor = (mng_uint32)((8000 * iDelay) / iTicks);
-          break;
-        }
-      default :
-        {
-          iWaitfor = (mng_uint32)((1000 * iDelay) / iTicks);
-        }
-    }
-  }
-
-  return iWaitfor;
-}
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Progressive display refresh - does the call to the refresh callback    * */
-/* * and sets the timer to allow the app to perform the actual refresh to   * */
-/* * the screen (eg. process its main message-loop)                         * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-mng_retcode mng_display_progressive_refresh (mng_datap  pData,
-                                             mng_uint32 iInterval)
-{
-  {                                    /* let the app refresh first ? */
-    if ((pData->bRunning) && (!pData->bSkipping) &&
-        (pData->iUpdatetop < pData->iUpdatebottom) && (pData->iUpdateleft < pData->iUpdateright))
-    {
-      if (!pData->fRefresh (((mng_handle)pData),
-                            pData->iUpdateleft, pData->iUpdatetop,
-                            pData->iUpdateright  - pData->iUpdateleft,
-                            pData->iUpdatebottom - pData->iUpdatetop))
-        MNG_ERROR (pData, MNG_APPMISCERROR);
-
-      pData->iUpdateleft   = 0;        /* reset update-region */
-      pData->iUpdateright  = 0;
-      pData->iUpdatetop    = 0;
-      pData->iUpdatebottom = 0;        /* reset refreshneeded indicator */
-      pData->bNeedrefresh  = MNG_FALSE;
-                                       /* interval requested ? */
-      if ((!pData->bFreezing) && (iInterval))
-      {                                /* setup the timer */
-        mng_retcode iRetcode = set_delay (pData, iInterval);
-
-        if (iRetcode)                  /* on error bail out */
-          return iRetcode;
-      }
-    }
-  }
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Generic display routines                                               * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-MNG_LOCAL mng_retcode interframe_delay (mng_datap pData)
-{
-  mng_uint32  iWaitfor = 0;
-  mng_uint32  iInterval;
-  mng_uint32  iRuninterval;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INTERFRAME_DELAY, MNG_LC_START);
-#endif
-
-  {
-#ifndef MNG_SKIPCHUNK_FRAM
-    if (pData->iFramedelay > 0)        /* real delay ? */
-    {                                  /* let the app refresh first ? */
-      if ((pData->bRunning) && (!pData->bSkipping) &&
-          (pData->iUpdatetop < pData->iUpdatebottom) && (pData->iUpdateleft < pData->iUpdateright))
-        if (!pData->fRefresh (((mng_handle)pData),
-                              pData->iUpdateleft,  pData->iUpdatetop,
-                              pData->iUpdateright - pData->iUpdateleft,
-                              pData->iUpdatebottom - pData->iUpdatetop))
-          MNG_ERROR (pData, MNG_APPMISCERROR);
-
-      pData->iUpdateleft   = 0;        /* reset update-region */
-      pData->iUpdateright  = 0;
-      pData->iUpdatetop    = 0;
-      pData->iUpdatebottom = 0;        /* reset refreshneeded indicator */
-      pData->bNeedrefresh  = MNG_FALSE;
-
-#ifndef MNG_SKIPCHUNK_TERM
-      if (pData->bOnlyfirstframe)      /* only processing first frame after TERM ? */
-      {
-        pData->iFramesafterTERM++;
-                                       /* did we do a frame yet ? */
-        if (pData->iFramesafterTERM > 1)
-        {                              /* then that's it; just stop right here ! */
-          pData->pCurraniobj = MNG_NULL;
-          pData->bRunning    = MNG_FALSE;
-
-          return MNG_NOERROR;
-        }
-      }
-#endif
-
-      if (pData->fGettickcount)
-      {                                /* get current tickcount */
-        pData->iRuntime = pData->fGettickcount ((mng_handle)pData);
-                                       /* calculate interval since last sync-point */
-        if (pData->iRuntime < pData->iSynctime)
-          iRuninterval    = pData->iRuntime + ~pData->iSynctime + 1;
-        else
-          iRuninterval    = pData->iRuntime - pData->iSynctime;
-                                       /* calculate actual run-time */
-        if (pData->iRuntime < pData->iStarttime)
-          pData->iRuntime = pData->iRuntime + ~pData->iStarttime + 1;
-        else
-          pData->iRuntime = pData->iRuntime - pData->iStarttime;
-      }
-      else
-      {
-        iRuninterval = 0;
-      }
-
-      iWaitfor = calculate_delay (pData, pData->iFramedelay);
-
-      if (iWaitfor > iRuninterval)     /* delay necessary ? */
-        iInterval = iWaitfor - iRuninterval;
-      else
-        iInterval = 1;                 /* force app to process messageloop */
-                                       /* set the timer ? */
-      if (((pData->bRunning) || (pData->bSearching) || (pData->bReading)) &&
-          (!pData->bSkipping))
-      {
-        iRetcode = set_delay (pData, iInterval);
-
-        if (iRetcode)                  /* on error bail out */
-          return iRetcode;
-      }
-    }
-
-    if (!pData->bSkipping)             /* increase frametime in advance */
-      pData->iFrametime = pData->iFrametime + iWaitfor;
-                                       /* setup for next delay */
-    pData->iFramedelay = pData->iNextdelay;
-#endif
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INTERFRAME_DELAY, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-MNG_LOCAL void set_display_routine (mng_datap pData)
-{                                        /* actively running ? */
-  if (((pData->bRunning) || (pData->bSearching)) && (!pData->bSkipping))
-  {
-    switch (pData->iCanvasstyle)         /* determine display routine */
-    {
-#ifndef MNG_SKIPCANVAS_RGB8
-      case MNG_CANVAS_RGB8    : { pData->fDisplayrow = (mng_fptr)mng_display_rgb8;     break; }
-#endif
-#ifndef MNG_SKIPCANVAS_RGBA8
-      case MNG_CANVAS_RGBA8   : { pData->fDisplayrow = (mng_fptr)mng_display_rgba8;    break; }
-#endif
-#ifndef MNG_SKIPCANVAS_RGBA8_PM
-      case MNG_CANVAS_RGBA8_PM: { pData->fDisplayrow = (mng_fptr)mng_display_rgba8_pm; break; }
-#endif
-#ifndef MNG_SKIPCANVAS_ARGB8
-      case MNG_CANVAS_ARGB8   : { pData->fDisplayrow = (mng_fptr)mng_display_argb8;    break; }
-#endif
-#ifndef MNG_SKIPCANVAS_ARGB8_PM
-      case MNG_CANVAS_ARGB8_PM: { pData->fDisplayrow = (mng_fptr)mng_display_argb8_pm; break; }
-#endif
-#ifndef MNG_SKIPCANVAS_RGB8_A8
-      case MNG_CANVAS_RGB8_A8 : { pData->fDisplayrow = (mng_fptr)mng_display_rgb8_a8;  break; }
-#endif
-#ifndef MNG_SKIPCANVAS_BGR8
-      case MNG_CANVAS_BGR8    : { pData->fDisplayrow = (mng_fptr)mng_display_bgr8;     break; }
-#endif
-#ifndef MNG_SKIPCANVAS_BGRX8
-      case MNG_CANVAS_BGRX8   : { pData->fDisplayrow = (mng_fptr)mng_display_bgrx8;    break; }
-#endif
-#ifndef MNG_SKIPCANVAS_BGRA8
-      case MNG_CANVAS_BGRA8   : { pData->fDisplayrow = (mng_fptr)mng_display_bgra8;    break; }
-#endif
-#ifndef MNG_SKIPCANVAS_BGRA8_PM
-      case MNG_CANVAS_BGRA8_PM: { pData->fDisplayrow = (mng_fptr)mng_display_bgra8_pm; break; }
-#endif
-#ifndef MNG_SKIPCANVAS_ABGR8
-      case MNG_CANVAS_ABGR8   : { pData->fDisplayrow = (mng_fptr)mng_display_abgr8;    break; }
-#endif
-#ifndef MNG_SKIPCANVAS_ABGR8_PM
-      case MNG_CANVAS_ABGR8_PM: { pData->fDisplayrow = (mng_fptr)mng_display_abgr8_pm; break; }
-#endif
-#ifndef MNG_SKIPCANVAS_RGB565
-      case MNG_CANVAS_RGB565  : { pData->fDisplayrow = (mng_fptr)mng_display_rgb565;   break; }
-#endif
-#ifndef MNG_SKIPCANVAS_RGBA565
-      case MNG_CANVAS_RGBA565 : { pData->fDisplayrow = (mng_fptr)mng_display_rgba565;  break; }
-#endif
-#ifndef MNG_SKIPCANVAS_BGR565
-      case MNG_CANVAS_BGR565  : { pData->fDisplayrow = (mng_fptr)mng_display_bgr565;   break; }
-#endif
-#ifndef MNG_SKIPCANVAS_BGRA565
-      case MNG_CANVAS_BGRA565 : { pData->fDisplayrow = (mng_fptr)mng_display_bgra565;  break; }
-#endif
-#ifndef MNG_SKIPCANVAS_BGR565_A8
-      case MNG_CANVAS_BGR565_A8 : { pData->fDisplayrow = (mng_fptr)mng_display_bgr565_a8;  break; }
-#endif
-#ifndef MNG_SKIPCANVAS_RGB555
-      case MNG_CANVAS_RGB555  : { pData->fDisplayrow = (mng_fptr)mng_display_rgb555;  break; }
-#endif
-#ifndef MNG_SKIPCANVAS_BGR555
-      case MNG_CANVAS_BGR555  : { pData->fDisplayrow = (mng_fptr)mng_display_bgr555;  break; }
-#endif
-
-#ifndef MNG_NO_16BIT_SUPPORT
-/*      case MNG_CANVAS_RGB16   : { pData->fDisplayrow = (mng_fptr)mng_display_rgb16;    break; } */
-/*      case MNG_CANVAS_RGBA16  : { pData->fDisplayrow = (mng_fptr)mng_display_rgba16;   break; } */
-/*      case MNG_CANVAS_ARGB16  : { pData->fDisplayrow = (mng_fptr)mng_display_argb16;   break; } */
-/*      case MNG_CANVAS_BGR16   : { pData->fDisplayrow = (mng_fptr)mng_display_bgr16;    break; } */
-/*      case MNG_CANVAS_BGRA16  : { pData->fDisplayrow = (mng_fptr)mng_display_bgra16;   break; } */
-/*      case MNG_CANVAS_ABGR16  : { pData->fDisplayrow = (mng_fptr)mng_display_abgr16;   break; } */
-#endif
-/*      case MNG_CANVAS_INDEX8  : { pData->fDisplayrow = (mng_fptr)mng_display_index8;   break; } */
-/*      case MNG_CANVAS_INDEXA8 : { pData->fDisplayrow = (mng_fptr)mng_display_indexa8;  break; } */
-/*      case MNG_CANVAS_AINDEX8 : { pData->fDisplayrow = (mng_fptr)mng_display_aindex8;  break; } */
-/*      case MNG_CANVAS_GRAY8   : { pData->fDisplayrow = (mng_fptr)mng_display_gray8;    break; } */
-/*      case MNG_CANVAS_AGRAY8  : { pData->fDisplayrow = (mng_fptr)mng_display_agray8;   break; } */
-/*      case MNG_CANVAS_GRAYA8  : { pData->fDisplayrow = (mng_fptr)mng_display_graya8;   break; } */
-#ifndef MNG_NO_16BIT_SUPPORT
-/*      case MNG_CANVAS_GRAY16  : { pData->fDisplayrow = (mng_fptr)mng_display_gray16;   break; } */
-/*      case MNG_CANVAS_GRAYA16 : { pData->fDisplayrow = (mng_fptr)mng_display_graya16;  break; } */
-/*      case MNG_CANVAS_AGRAY16 : { pData->fDisplayrow = (mng_fptr)mng_display_agray16;  break; } */
-#endif
-/*      case MNG_CANVAS_DX15    : { pData->fDisplayrow = (mng_fptr)mng_display_dx15;     break; } */
-/*      case MNG_CANVAS_DX16    : { pData->fDisplayrow = (mng_fptr)mng_display_dx16;     break; } */
-    }
-  }
-
-  return;
-}
-
-/* ************************************************************************** */
-
-MNG_LOCAL mng_retcode load_bkgdlayer (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_LOAD_BKGDLAYER, MNG_LC_START);
-#endif
-                                       /* actively running ? */
-  if (((pData->bRunning) || (pData->bSearching)) && (!pData->bSkipping))
-  {
-    mng_int32   iY;
-    mng_retcode iRetcode;
-    mng_bool    bColorcorr   = MNG_FALSE;
-                                       /* save values */
-    mng_int32   iDestl       = pData->iDestl;
-    mng_int32   iDestr       = pData->iDestr;
-    mng_int32   iDestt       = pData->iDestt;
-    mng_int32   iDestb       = pData->iDestb;
-    mng_int32   iSourcel     = pData->iSourcel;
-    mng_int32   iSourcer     = pData->iSourcer;
-    mng_int32   iSourcet     = pData->iSourcet;
-    mng_int32   iSourceb     = pData->iSourceb;
-    mng_int8    iPass        = pData->iPass;
-    mng_int32   iRow         = pData->iRow;
-    mng_int32   iRowinc      = pData->iRowinc;
-    mng_int32   iCol         = pData->iCol;
-    mng_int32   iColinc      = pData->iColinc;
-    mng_int32   iRowsamples  = pData->iRowsamples;
-    mng_int32   iRowsize     = pData->iRowsize;
-    mng_uint8p  pPrevrow     = pData->pPrevrow;
-    mng_uint8p  pRGBArow     = pData->pRGBArow;
-    mng_bool    bIsRGBA16    = pData->bIsRGBA16;
-    mng_bool    bIsOpaque    = pData->bIsOpaque;
-    mng_fptr    fCorrectrow  = pData->fCorrectrow;
-    mng_fptr    fDisplayrow  = pData->fDisplayrow;
-    mng_fptr    fRetrieverow = pData->fRetrieverow;
-    mng_objectp pCurrentobj  = pData->pCurrentobj;
-    mng_objectp pRetrieveobj = pData->pRetrieveobj;
-
-    pData->iDestl   = 0;               /* determine clipping region */
-    pData->iDestt   = 0;
-    pData->iDestr   = pData->iWidth;
-    pData->iDestb   = pData->iHeight;
-
-#ifndef MNG_SKIPCHUNK_FRAM
-    if (pData->bFrameclipping)         /* frame clipping specified ? */
-    {
-      pData->iDestl = MAX_COORD (pData->iDestl,  pData->iFrameclipl);
-      pData->iDestt = MAX_COORD (pData->iDestt,  pData->iFrameclipt);
-      pData->iDestr = MIN_COORD (pData->iDestr,  pData->iFrameclipr);
-      pData->iDestb = MIN_COORD (pData->iDestb,  pData->iFrameclipb);
-    }
-#endif
-                                       /* anything to clear ? */
-    if ((pData->iDestr >= pData->iDestl) && (pData->iDestb >= pData->iDestt))
-    {
-      pData->iPass       = -1;         /* these are the object's dimensions now */
-      pData->iRow        = 0;
-      pData->iRowinc     = 1;
-      pData->iCol        = 0;
-      pData->iColinc     = 1;
-      pData->iRowsamples = pData->iWidth;
-      pData->iRowsize    = pData->iRowsamples << 2;
-      pData->bIsRGBA16   = MNG_FALSE;  /* let's keep it simple ! */
-      pData->bIsOpaque   = MNG_TRUE;
-
-      pData->iSourcel    = 0;          /* source relative to destination */
-      pData->iSourcer    = pData->iDestr - pData->iDestl;
-      pData->iSourcet    = 0;
-      pData->iSourceb    = pData->iDestb - pData->iDestt;
-
-      set_display_routine (pData);     /* determine display routine */
-                                       /* default restore using preset BG color */
-      pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_bgcolor;
-
-#ifndef MNG_SKIPCHUNK_bKGD
-      if (((pData->eImagetype == mng_it_png) || (pData->eImagetype == mng_it_jng)) &&
-          (pData->bUseBKGD))
-      {                                /* prefer bKGD in PNG/JNG */
-        if (!pData->pCurrentobj)
-          pData->pCurrentobj = pData->pObjzero;
-
-        if (((mng_imagep)pData->pCurrentobj)->pImgbuf->bHasBKGD)
-        {
-          pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_bkgd;
-          bColorcorr          = MNG_TRUE;
-        }
-      }
-#endif
-
-      if (pData->fGetbkgdline)         /* background-canvas-access callback set ? */
-      {
-        switch (pData->iBkgdstyle)
-        {
-#ifndef MNG_SKIPCANVAS_RGB8
-          case MNG_CANVAS_RGB8    : { pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_rgb8;    break; }
-#endif
-#ifndef MNG_SKIPCANVAS_BGR8
-          case MNG_CANVAS_BGR8    : { pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_bgr8;    break; }
-#endif
-#ifndef MNG_SKIPCANVAS_BGRX8
-          case MNG_CANVAS_BGRX8   : { pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_bgrx8;   break; }
-#endif
-#ifndef MNG_SKIPCANVAS_BGR565
-          case MNG_CANVAS_BGR565  : { pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_bgr565;  break; }
-#endif
-#ifndef MNG_SKIPCANVAS_RGB565
-          case MNG_CANVAS_RGB565  : { pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_rgb565;  break; }
-#endif
-#ifndef MNG_NO_16BIT_SUPPORT
-  /*        case MNG_CANVAS_RGB16   : { pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_rgb16;   break; } */
-  /*        case MNG_CANVAS_BGR16   : { pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_bgr16;   break; } */
-#endif
-  /*        case MNG_CANVAS_INDEX8  : { pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_index8;  break; } */
-  /*        case MNG_CANVAS_GRAY8   : { pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_gray8;   break; } */
-#ifndef MNG_NO_16BIT_SUPPORT
-  /*        case MNG_CANVAS_GRAY16  : { pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_gray16;  break; } */
-#endif
-  /*        case MNG_CANVAS_DX15    : { pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_dx15;    break; } */
-  /*        case MNG_CANVAS_DX16    : { pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_dx16;    break; } */
-        }
-      }
-
-#ifndef MNG_SKIPCHUNK_BACK
-      if (pData->bHasBACK)
-      {                                /* background image ? */
-        if ((pData->iBACKmandatory & 0x02) && (pData->iBACKimageid))
-        {
-          pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_backcolor;
-          bColorcorr          = MNG_TRUE;
-        }
-        else                           /* background color ? */
-        if (pData->iBACKmandatory & 0x01)
-        {
-          pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_backcolor;
-          bColorcorr          = MNG_TRUE;
-        }
-      }
-#endif
-
-      pData->fCorrectrow = MNG_NULL;   /* default no color-correction */
-
-      if (bColorcorr)                  /* do we have to do color-correction ? */
-      {
-#ifdef MNG_NO_CMS
-        iRetcode = MNG_NOERROR;
-#else
-#if defined(MNG_FULL_CMS)              /* determine color-management routine */
-        iRetcode = mng_init_full_cms   (pData, MNG_TRUE, MNG_FALSE, MNG_FALSE);
-#elif defined(MNG_GAMMA_ONLY)
-        iRetcode = mng_init_gamma_only (pData, MNG_TRUE, MNG_FALSE, MNG_FALSE);
-#elif defined(MNG_APP_CMS)
-        iRetcode = mng_init_app_cms    (pData, MNG_TRUE, MNG_FALSE, MNG_FALSE);
-#endif
-        if (iRetcode)                  /* on error bail out */
-          return iRetcode;
-#endif /* MNG_NO_CMS */
-      }
-                                       /* get a temporary row-buffer */
-      MNG_ALLOC (pData, pData->pRGBArow, pData->iRowsize);
-
-      iY       = pData->iDestt;        /* this is where we start */
-      iRetcode = MNG_NOERROR;          /* so far, so good */
-
-      while ((!iRetcode) && (iY < pData->iDestb))
-      {                                /* restore a background row */
-        iRetcode = ((mng_restbkgdrow)pData->fRestbkgdrow) (pData);
-                                       /* color correction ? */
-        if ((!iRetcode) && (pData->fCorrectrow))
-          iRetcode = ((mng_correctrow)pData->fCorrectrow) (pData);
-
-        if (!iRetcode)                 /* so... display it */
-          iRetcode = ((mng_displayrow)pData->fDisplayrow) (pData);
-
-        if (!iRetcode)
-          iRetcode = mng_next_row (pData);
-
-        iY++;                          /* and next line */
-      }
-                                       /* drop the temporary row-buffer */
-      MNG_FREE (pData, pData->pRGBArow, pData->iRowsize);
-
-      if (iRetcode)                    /* on error bail out */
-        return iRetcode;
-
-#if defined(MNG_FULL_CMS)              /* cleanup cms stuff */
-      if (bColorcorr)                  /* did we do color-correction ? */
-      {
-        iRetcode = mng_clear_cms (pData);
-
-        if (iRetcode)                  /* on error bail out */
-          return iRetcode;
-      }
-#endif
-#ifndef MNG_SKIPCHUNK_BACK
-                                       /* background image ? */
-      if ((pData->bHasBACK) && (pData->iBACKmandatory & 0x02) && (pData->iBACKimageid))
-      {
-        mng_imagep pImage;
-                                       /* let's find that object then */
-        pData->pRetrieveobj = mng_find_imageobject (pData, pData->iBACKimageid);
-        pImage              = (mng_imagep)pData->pRetrieveobj;
-                                       /* exists, viewable and visible ? */
-        if ((pImage) && (pImage->bViewable) && (pImage->bVisible))
-        {                              /* will it fall within the target region ? */
-          if ((pImage->iPosx < pData->iDestr) && (pImage->iPosy < pData->iDestb)             &&
-              ((pData->iBACKtile) ||
-               ((pImage->iPosx + (mng_int32)pImage->pImgbuf->iWidth  >= pData->iDestl) &&
-                (pImage->iPosy + (mng_int32)pImage->pImgbuf->iHeight >= pData->iDestt)    )) &&
-              ((!pImage->bClipped) ||
-               ((pImage->iClipl <= pImage->iClipr) && (pImage->iClipt <= pImage->iClipb)     &&
-                (pImage->iClipl < pData->iDestr)   && (pImage->iClipr >= pData->iDestl)      &&
-                (pImage->iClipt < pData->iDestb)   && (pImage->iClipb >= pData->iDestt)         )))
-          {                            /* right; we've got ourselves something to do */
-            if (pImage->bClipped)      /* clip output region with image's clipping region ? */
-            {
-              if (pImage->iClipl > pData->iDestl)
-                pData->iDestl = pImage->iClipl;
-              if (pImage->iClipr < pData->iDestr)
-                pData->iDestr = pImage->iClipr;
-              if (pImage->iClipt > pData->iDestt)
-                pData->iDestt = pImage->iClipt;
-              if (pImage->iClipb < pData->iDestb)
-                pData->iDestb = pImage->iClipb;
-            }
-                                       /* image offset does some extra clipping too ! */
-            if (pImage->iPosx > pData->iDestl)
-              pData->iDestl = pImage->iPosx;
-            if (pImage->iPosy > pData->iDestt)
-              pData->iDestt = pImage->iPosy;
-
-            if (!pData->iBACKtile)     /* without tiling further clipping is needed */
-            {
-              if (pImage->iPosx + (mng_int32)pImage->pImgbuf->iWidth  < pData->iDestr)
-                pData->iDestr = pImage->iPosx + (mng_int32)pImage->pImgbuf->iWidth;
-              if (pImage->iPosy + (mng_int32)pImage->pImgbuf->iHeight < pData->iDestb)
-                pData->iDestb = pImage->iPosy + (mng_int32)pImage->pImgbuf->iHeight;
-            }
-            
-            pData->iSourcel    = 0;    /* source relative to destination */
-            pData->iSourcer    = pData->iDestr - pData->iDestl;
-            pData->iSourcet    = 0;
-            pData->iSourceb    = pData->iDestb - pData->iDestt;
-                                       /* 16-bit background ? */
-
-#ifdef MNG_NO_16BIT_SUPPORT
-            pData->bIsRGBA16   = MNG_FALSE;
-#else
-            pData->bIsRGBA16      = (mng_bool)(pImage->pImgbuf->iBitdepth > 8);
-#endif
-                                       /* let restore routine know the offsets !!! */
-            pData->iBackimgoffsx  = pImage->iPosx;
-            pData->iBackimgoffsy  = pImage->iPosy;
-            pData->iBackimgwidth  = pImage->pImgbuf->iWidth;
-            pData->iBackimgheight = pImage->pImgbuf->iHeight;
-            pData->iRow           = 0; /* start at the top again !! */
-                                       /* determine background object retrieval routine */
-            switch (pImage->pImgbuf->iColortype)
-            {
-              case  0 : {
-#ifndef MNG_NO_16BIT_SUPPORT
-                          if (pImage->pImgbuf->iBitdepth > 8)
-                            pData->fRetrieverow = (mng_fptr)mng_retrieve_g16;
-                          else
-#endif
-                            pData->fRetrieverow = (mng_fptr)mng_retrieve_g8;
-
-                          pData->bIsOpaque      = (mng_bool)(!pImage->pImgbuf->bHasTRNS);
-                          break;
-                        }
-
-              case  2 : {
-#ifndef MNG_NO_16BIT_SUPPORT
-                          if (pImage->pImgbuf->iBitdepth > 8)
-                            pData->fRetrieverow = (mng_fptr)mng_retrieve_rgb16;
-                          else
-#endif
-                            pData->fRetrieverow = (mng_fptr)mng_retrieve_rgb8;
-
-                          pData->bIsOpaque      = (mng_bool)(!pImage->pImgbuf->bHasTRNS);
-                          break;
-                        }
-
-              case  3 : { pData->fRetrieverow   = (mng_fptr)mng_retrieve_idx8;
-                          pData->bIsOpaque      = (mng_bool)(!pImage->pImgbuf->bHasTRNS);
-                          break;
-                        }
-
-              case  4 : { 
-#ifndef MNG_NO_16BIT_SUPPORT
-			if (pImage->pImgbuf->iBitdepth > 8)
-                            pData->fRetrieverow = (mng_fptr)mng_retrieve_ga16;
-                          else
-#endif
-                            pData->fRetrieverow = (mng_fptr)mng_retrieve_ga8;
-
-                          pData->bIsOpaque      = MNG_FALSE;
-                          break;
-                        }
-
-              case  6 : {
-#ifndef MNG_NO_16BIT_SUPPORT
-                          if (pImage->pImgbuf->iBitdepth > 8)
-                            pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba16;
-                          else
-#endif
-                            pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba8;
-
-                          pData->bIsOpaque      = MNG_FALSE;
-                          break;
-                        }
-
-              case  8 : {
-#ifndef MNG_NO_16BIT_SUPPORT
-                          if (pImage->pImgbuf->iBitdepth > 8)
-                            pData->fRetrieverow = (mng_fptr)mng_retrieve_g16;
-                          else
-#endif
-                            pData->fRetrieverow = (mng_fptr)mng_retrieve_g8;
-
-                          pData->bIsOpaque      = MNG_TRUE;
-                          break;
-                        }
-
-              case 10 : {
-#ifndef MNG_NO_16BIT_SUPPORT
-                          if (pImage->pImgbuf->iBitdepth > 8)
-                            pData->fRetrieverow = (mng_fptr)mng_retrieve_rgb16;
-                          else
-#endif
-                            pData->fRetrieverow = (mng_fptr)mng_retrieve_rgb8;
-
-                          pData->bIsOpaque      = MNG_TRUE;
-                          break;
-                        }
-
-              case 12 : {
-#ifndef MNG_NO_16BIT_SUPPORT
-                          if (pImage->pImgbuf->iBitdepth > 8)
-                            pData->fRetrieverow = (mng_fptr)mng_retrieve_ga16;
-                          else
-#endif
-                            pData->fRetrieverow = (mng_fptr)mng_retrieve_ga8;
-
-                          pData->bIsOpaque      = MNG_FALSE;
-                          break;
-                        }
-
-              case 14 : {
-#ifndef MNG_NO_16BIT_SUPPORT
-                          if (pImage->pImgbuf->iBitdepth > 8)
-                            pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba16;
-                          else
-#endif
-                            pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba8;
-
-                          pData->bIsOpaque      = MNG_FALSE;
-                          break;
-                        }
-            }
-
-#ifdef MNG_NO_CMS
-            iRetcode = MNG_NOERROR;
-#else
-#if defined(MNG_FULL_CMS)              /* determine color-management routine */
-            iRetcode = mng_init_full_cms   (pData, MNG_FALSE, MNG_FALSE, MNG_TRUE);
-#elif defined(MNG_GAMMA_ONLY)
-            iRetcode = mng_init_gamma_only (pData, MNG_FALSE, MNG_FALSE, MNG_TRUE);
-#elif defined(MNG_APP_CMS)
-            iRetcode = mng_init_app_cms    (pData, MNG_FALSE, MNG_FALSE, MNG_TRUE);
-#endif
-            if (iRetcode)              /* on error bail out */
-              return iRetcode;
-#endif /* MNG_NO_CMS */
-                                       /* get temporary row-buffers */
-            MNG_ALLOC (pData, pData->pPrevrow, pData->iRowsize);
-            MNG_ALLOC (pData, pData->pRGBArow, pData->iRowsize);
-
-            iY       = pData->iDestt;  /* this is where we start */
-            iRetcode = MNG_NOERROR;    /* so far, so good */
-
-            while ((!iRetcode) && (iY < pData->iDestb))
-            {                          /* restore a background row */
-              iRetcode = mng_restore_bkgd_backimage (pData);
-                                       /* color correction ? */
-              if ((!iRetcode) && (pData->fCorrectrow))
-                iRetcode = ((mng_correctrow)pData->fCorrectrow) (pData);
-
-              if (!iRetcode)           /* so... display it */
-                iRetcode = ((mng_displayrow)pData->fDisplayrow) (pData);
-
-              if (!iRetcode)
-                iRetcode = mng_next_row (pData);
-
-              iY++;                    /* and next line */
-            }
-                                       /* drop temporary row-buffers */
-            MNG_FREE (pData, pData->pRGBArow, pData->iRowsize);
-            MNG_FREE (pData, pData->pPrevrow, pData->iRowsize);
-
-            if (iRetcode)              /* on error bail out */
-              return iRetcode;
-
-#if defined(MNG_FULL_CMS)              /* cleanup cms stuff */
-            iRetcode = mng_clear_cms (pData);
-
-            if (iRetcode)              /* on error bail out */
-              return iRetcode;
-#endif
-          }
-        }
-      }
-#endif
-    }
-
-    pData->iDestl       = iDestl;      /* restore values */
-    pData->iDestr       = iDestr;
-    pData->iDestt       = iDestt;
-    pData->iDestb       = iDestb;
-    pData->iSourcel     = iSourcel;
-    pData->iSourcer     = iSourcer;
-    pData->iSourcet     = iSourcet;
-    pData->iSourceb     = iSourceb;
-    pData->iPass        = iPass;
-    pData->iRow         = iRow;
-    pData->iRowinc      = iRowinc;
-    pData->iCol         = iCol;
-    pData->iColinc      = iColinc;
-    pData->iRowsamples  = iRowsamples;
-    pData->iRowsize     = iRowsize;
-    pData->pPrevrow     = pPrevrow;
-    pData->pRGBArow     = pRGBArow;
-    pData->bIsRGBA16    = bIsRGBA16;
-    pData->bIsOpaque    = bIsOpaque;
-    pData->fCorrectrow  = fCorrectrow;
-    pData->fDisplayrow  = fDisplayrow; 
-    pData->fRetrieverow = fRetrieverow;
-    pData->pCurrentobj  = pCurrentobj;
-    pData->pRetrieveobj = pRetrieveobj;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_LOAD_BKGDLAYER, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-MNG_LOCAL mng_retcode clear_canvas (mng_datap pData)
-{
-  mng_int32   iY;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CLEAR_CANVAS, MNG_LC_START);
-#endif
-
-  pData->iDestl      = 0;              /* clipping region is full canvas! */
-  pData->iDestt      = 0;
-  pData->iDestr      = pData->iWidth;
-  pData->iDestb      = pData->iHeight;
-
-  pData->iSourcel    = 0;              /* source is same as destination */
-  pData->iSourcer    = pData->iWidth;
-  pData->iSourcet    = 0;
-  pData->iSourceb    = pData->iHeight;
-
-  pData->iPass       = -1;             /* these are the object's dimensions now */
-  pData->iRow        = 0;
-  pData->iRowinc     = 1;
-  pData->iCol        = 0;
-  pData->iColinc     = 1;
-  pData->iRowsamples = pData->iWidth;
-  pData->iRowsize    = pData->iRowsamples << 2;
-  pData->bIsRGBA16   = MNG_FALSE;      /* let's keep it simple ! */
-  pData->bIsOpaque   = MNG_TRUE;
-
-  set_display_routine (pData);         /* determine display routine */
-                                       /* get a temporary row-buffer */
-                                       /* it's transparent black by default!! */
-  MNG_ALLOC (pData, pData->pRGBArow, pData->iRowsize);
-
-  iY       = pData->iDestt;            /* this is where we start */
-  iRetcode = MNG_NOERROR;              /* so far, so good */
-
-  while ((!iRetcode) && (iY < pData->iDestb))
-  {                                    /* clear a row then */
-    iRetcode = ((mng_displayrow)pData->fDisplayrow) (pData);
-
-    if (!iRetcode)
-      iRetcode = mng_next_row (pData); /* adjust variables for next row */
-
-    iY++;                              /* and next line */
-  }
-                                       /* drop the temporary row-buffer */
-  MNG_FREE (pData, pData->pRGBArow, pData->iRowsize);
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CLEAR_CANVAS, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-MNG_LOCAL mng_retcode next_frame (mng_datap  pData,
-                                  mng_uint8  iFramemode,
-                                  mng_uint8  iChangedelay,
-                                  mng_uint32 iDelay,
-                                  mng_uint8  iChangetimeout,
-                                  mng_uint32 iTimeout,
-                                  mng_uint8  iChangeclipping,
-                                  mng_uint8  iCliptype,
-                                  mng_int32  iClipl,
-                                  mng_int32  iClipr,
-                                  mng_int32  iClipt,
-                                  mng_int32  iClipb)
-{
-  mng_retcode iRetcode = MNG_NOERROR;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_NEXT_FRAME, MNG_LC_START);
-#endif
-
-  if (!pData->iBreakpoint)             /* no previous break here ? */
-  {
-#ifndef MNG_SKIPCHUNK_FRAM
-    mng_uint8 iOldmode = pData->iFramemode;
-                                       /* interframe delay required ? */
-    if ((iOldmode == 2) || (iOldmode == 4))
-    {
-      if ((pData->iFrameseq) && (iFramemode != 1) && (iFramemode != 3))
-        iRetcode = interframe_delay (pData);
-      else
-        pData->iFramedelay = pData->iNextdelay;
-    }
-    else
-    {                                  /* delay before inserting background layer? */
-      if ((pData->bFramedone) && (iFramemode == 4))
-        iRetcode = interframe_delay (pData);
-    }
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* now we'll assume we're in the next frame! */
-    if (iFramemode)                    /* save the new framing mode ? */
-    {
-      pData->iFRAMmode  = iFramemode;
-      pData->iFramemode = iFramemode;
-    }
-    else                               /* reload default */
-      pData->iFramemode = pData->iFRAMmode;
-
-    if (iChangedelay)                  /* delay changed ? */
-    {
-      pData->iNextdelay = iDelay;      /* for *after* next subframe */
-
-      if ((iOldmode == 2) || (iOldmode == 4))
-        pData->iFramedelay = pData->iFRAMdelay;
-
-      if (iChangedelay == 2)           /* also overall ? */
-        pData->iFRAMdelay = iDelay;
-    }
-    else
-    {                                  /* reload default */
-      pData->iNextdelay = pData->iFRAMdelay;
-    }
-
-    if (iChangetimeout)                /* timeout changed ? */
-    {                                  /* for next subframe */
-      pData->iFrametimeout = iTimeout;
-
-      if ((iChangetimeout == 2) ||     /* also overall ? */
-          (iChangetimeout == 4) ||
-          (iChangetimeout == 6) ||
-          (iChangetimeout == 8))
-        pData->iFRAMtimeout = iTimeout;
-    }
-    else                               /* reload default */
-      pData->iFrametimeout = pData->iFRAMtimeout;
-
-    if (iChangeclipping)               /* clipping changed ? */
-    {
-      pData->bFrameclipping = MNG_TRUE;
-
-      if (!iCliptype)                  /* absolute ? */
-      {
-        pData->iFrameclipl = iClipl;
-        pData->iFrameclipr = iClipr;
-        pData->iFrameclipt = iClipt;
-        pData->iFrameclipb = iClipb;
-      }
-      else                             /* relative */
-      {
-        pData->iFrameclipl = pData->iFrameclipl + iClipl;
-        pData->iFrameclipr = pData->iFrameclipr + iClipr;
-        pData->iFrameclipt = pData->iFrameclipt + iClipt;
-        pData->iFrameclipb = pData->iFrameclipb + iClipb;
-      }
-
-      if (iChangeclipping == 2)        /* also overall ? */
-      {
-        pData->bFRAMclipping = MNG_TRUE;
-
-        if (!iCliptype)                /* absolute ? */
-        {
-          pData->iFRAMclipl = iClipl;
-          pData->iFRAMclipr = iClipr;
-          pData->iFRAMclipt = iClipt;
-          pData->iFRAMclipb = iClipb;
-        }
-        else                           /* relative */
-        {
-          pData->iFRAMclipl = pData->iFRAMclipl + iClipl;
-          pData->iFRAMclipr = pData->iFRAMclipr + iClipr;
-          pData->iFRAMclipt = pData->iFRAMclipt + iClipt;
-          pData->iFRAMclipb = pData->iFRAMclipb + iClipb;
-        }
-      }
-    }
-    else
-    {                                  /* reload defaults */
-      pData->bFrameclipping = pData->bFRAMclipping;
-      pData->iFrameclipl    = pData->iFRAMclipl;
-      pData->iFrameclipr    = pData->iFRAMclipr;
-      pData->iFrameclipt    = pData->iFRAMclipt;
-      pData->iFrameclipb    = pData->iFRAMclipb;
-    }
-#endif
-  }
-
-  if (!pData->bTimerset)               /* timer still off ? */
-  {
-    if (
-#ifndef MNG_SKIPCHUNK_FRAM
-       (pData->iFramemode == 4) ||    /* insert background layer after a new frame */
-#endif
-        (!pData->iLayerseq))           /* and certainly before the very first layer */
-      iRetcode = load_bkgdlayer (pData);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-
-    pData->iFrameseq++;                /* count the frame ! */
-    pData->bFramedone = MNG_TRUE;      /* and indicate we've done one */
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_NEXT_FRAME, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-MNG_LOCAL mng_retcode next_layer (mng_datap pData)
-{
-  mng_imagep  pImage;
-  mng_retcode iRetcode = MNG_NOERROR;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_NEXT_LAYER, MNG_LC_START);
-#endif
-
-#ifndef MNG_SKIPCHUNK_FRAM
-  if (!pData->iBreakpoint)             /* no previous break here ? */
-  {                                    /* interframe delay required ? */
-    if ((pData->eImagetype == mng_it_mng) && (pData->iLayerseq) &&
-        ((pData->iFramemode == 1) || (pData->iFramemode == 3)))
-      iRetcode = interframe_delay (pData);
-    else
-      pData->iFramedelay = pData->iNextdelay;
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-  }
-#endif
-
-  if (!pData->bTimerset)               /* timer still off ? */
-  {
-    if (!pData->iLayerseq)             /* restore background for the very first layer ? */
-    {                                  /* wait till IDAT/JDAT for PNGs & JNGs !!! */
-      if ((pData->eImagetype == mng_it_png) || (pData->eImagetype == mng_it_jng))
-        pData->bRestorebkgd = MNG_TRUE;
-      else
-      {                                /* for MNG we do it right away */
-        iRetcode = load_bkgdlayer (pData);
-        pData->iLayerseq++;            /* and it counts as a layer then ! */
-      }
-    }
-#ifndef MNG_SKIPCHUNK_FRAM
-    else
-    if (pData->iFramemode == 3)        /* restore background for each layer ? */
-      iRetcode = load_bkgdlayer (pData);
-#endif
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-
-#ifndef MNG_NO_DELTA_PNG
-    if (pData->bHasDHDR)               /* processing a delta-image ? */
-      pImage = (mng_imagep)pData->pDeltaImage;
-    else
-#endif
-      pImage = (mng_imagep)pData->pCurrentobj;
-
-    if (!pImage)                       /* not an active object ? */
-      pImage = (mng_imagep)pData->pObjzero;
-                                       /* determine display rectangle */
-    pData->iDestl   = MAX_COORD ((mng_int32)0,   pImage->iPosx);
-    pData->iDestt   = MAX_COORD ((mng_int32)0,   pImage->iPosy);
-                                       /* is it a valid buffer ? */
-    if ((pImage->pImgbuf->iWidth) && (pImage->pImgbuf->iHeight))
-    {
-      pData->iDestr = MIN_COORD ((mng_int32)pData->iWidth,
-                                 pImage->iPosx + (mng_int32)pImage->pImgbuf->iWidth );
-      pData->iDestb = MIN_COORD ((mng_int32)pData->iHeight,
-                                 pImage->iPosy + (mng_int32)pImage->pImgbuf->iHeight);
-    }
-    else                               /* it's a single image ! */
-    {
-      pData->iDestr = MIN_COORD ((mng_int32)pData->iWidth,
-                                 (mng_int32)pData->iDatawidth );
-      pData->iDestb = MIN_COORD ((mng_int32)pData->iHeight,
-                                 (mng_int32)pData->iDataheight);
-    }
-
-#ifndef MNG_SKIPCHUNK_FRAM
-    if (pData->bFrameclipping)         /* frame clipping specified ? */
-    {
-      pData->iDestl = MAX_COORD (pData->iDestl,  pData->iFrameclipl);
-      pData->iDestt = MAX_COORD (pData->iDestt,  pData->iFrameclipt);
-      pData->iDestr = MIN_COORD (pData->iDestr,  pData->iFrameclipr);
-      pData->iDestb = MIN_COORD (pData->iDestb,  pData->iFrameclipb);
-    }
-#endif
-
-    if (pImage->bClipped)              /* is the image clipped itself ? */
-    {
-      pData->iDestl = MAX_COORD (pData->iDestl,  pImage->iClipl);
-      pData->iDestt = MAX_COORD (pData->iDestt,  pImage->iClipt);
-      pData->iDestr = MIN_COORD (pData->iDestr,  pImage->iClipr);
-      pData->iDestb = MIN_COORD (pData->iDestb,  pImage->iClipb);
-    }
-                                       /* determine source starting point */
-    pData->iSourcel = MAX_COORD ((mng_int32)0,   pData->iDestl - pImage->iPosx);
-    pData->iSourcet = MAX_COORD ((mng_int32)0,   pData->iDestt - pImage->iPosy);
-
-    if ((pImage->pImgbuf->iWidth) && (pImage->pImgbuf->iHeight))
-    {                                  /* and maximum size  */
-      pData->iSourcer = MIN_COORD ((mng_int32)pImage->pImgbuf->iWidth,
-                                   pData->iSourcel + pData->iDestr - pData->iDestl);
-      pData->iSourceb = MIN_COORD ((mng_int32)pImage->pImgbuf->iHeight,
-                                   pData->iSourcet + pData->iDestb - pData->iDestt);
-    }
-    else                               /* it's a single image ! */
-    {
-      pData->iSourcer = pData->iSourcel + pData->iDestr - pData->iDestl;
-      pData->iSourceb = pData->iSourcet + pData->iDestb - pData->iDestt;
-    }
-
-    pData->iLayerseq++;                /* count the layer ! */
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_NEXT_LAYER, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_display_image (mng_datap  pData,
-                               mng_imagep pImage,
-                               mng_bool   bLayeradvanced)
-{
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_IMAGE, MNG_LC_START);
-#endif
-                                       /* actively running ? */
-#ifndef MNG_SKIPCHUNK_MAGN
-  if (((pData->bRunning) || (pData->bSearching)) && (!pData->bSkipping))
-  {
-    if ( (!pData->iBreakpoint) &&      /* needs magnification ? */
-         ( (pImage->iMAGN_MethodX) || (pImage->iMAGN_MethodY) ) )
-    {
-      iRetcode = mng_magnify_imageobject (pData, pImage);
-
-      if (iRetcode)                    /* on error bail out */
-        return iRetcode;
-    }
-  }
-#endif
-
-  pData->pRetrieveobj = pImage;        /* so retrieve-row and color-correction can find it */
-
-  if (!bLayeradvanced)                 /* need to advance the layer ? */
-  {
-    mng_imagep pSave    = pData->pCurrentobj;
-    pData->pCurrentobj  = pImage;
-    next_layer (pData);                /* advance to next layer */
-    pData->pCurrentobj  = pSave;
-  }
-                                       /* need to restore the background ? */
-  if ((!pData->bTimerset) && (pData->bRestorebkgd))
-  {
-    mng_imagep pSave    = pData->pCurrentobj;
-    pData->pCurrentobj  = pImage;
-    pData->bRestorebkgd = MNG_FALSE;
-    iRetcode            = load_bkgdlayer (pData);
-    pData->pCurrentobj  = pSave;
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-
-    pData->iLayerseq++;                /* and it counts as a layer then ! */
-  }
-                                       /* actively running ? */
-  if (((pData->bRunning) || (pData->bSearching)) && (!pData->bSkipping))
-  {
-    if (!pData->bTimerset)             /* all systems still go ? */
-    {
-      pData->iBreakpoint = 0;          /* let's make absolutely sure... */
-                                       /* anything to display ? */
-      if ((pData->iDestr >= pData->iDestl) && (pData->iDestb >= pData->iDestt))
-      {
-        mng_int32 iY;
-
-        set_display_routine (pData);   /* determine display routine */
-                                       /* and image-buffer retrieval routine */
-        switch (pImage->pImgbuf->iColortype)
-        {
-          case  0 : {
-#ifndef MNG_NO_16BIT_SUPPORT
-                      if (pImage->pImgbuf->iBitdepth > 8)
-                        pData->fRetrieverow = (mng_fptr)mng_retrieve_g16;
-                      else
-#endif
-                        pData->fRetrieverow = (mng_fptr)mng_retrieve_g8;
-
-                      pData->bIsOpaque      = (mng_bool)(!pImage->pImgbuf->bHasTRNS);
-                      break;
-                    }
-
-          case  2 : {
-#ifndef MNG_NO_16BIT_SUPPORT
-                      if (pImage->pImgbuf->iBitdepth > 8)
-                        pData->fRetrieverow = (mng_fptr)mng_retrieve_rgb16;
-                      else
-#endif
-                        pData->fRetrieverow = (mng_fptr)mng_retrieve_rgb8;
-
-                      pData->bIsOpaque      = (mng_bool)(!pImage->pImgbuf->bHasTRNS);
-                      break;
-                    }
-
-
-          case  3 : { pData->fRetrieverow   = (mng_fptr)mng_retrieve_idx8;
-                      pData->bIsOpaque      = (mng_bool)(!pImage->pImgbuf->bHasTRNS);
-                      break;
-                    }
-
-
-          case  4 : {
-#ifndef MNG_NO_16BIT_SUPPORT
-                      if (pImage->pImgbuf->iBitdepth > 8)
-                        pData->fRetrieverow = (mng_fptr)mng_retrieve_ga16;
-                      else
-#endif
-                        pData->fRetrieverow = (mng_fptr)mng_retrieve_ga8;
-
-                      pData->bIsOpaque      = MNG_FALSE;
-                      break;
-                    }
-
-
-          case  6 : {
-#ifndef MNG_NO_16BIT_SUPPORT
-                      if (pImage->pImgbuf->iBitdepth > 8)
-                        pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba16;
-                      else
-#endif
-                        pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba8;
-
-                      pData->bIsOpaque      = MNG_FALSE;
-                      break;
-                    }
-
-          case  8 : {
-#ifndef MNG_NO_16BIT_SUPPORT
-                      if (pImage->pImgbuf->iBitdepth > 8)
-                        pData->fRetrieverow = (mng_fptr)mng_retrieve_g16;
-                      else
-#endif
-                        pData->fRetrieverow = (mng_fptr)mng_retrieve_g8;
-
-                      pData->bIsOpaque      = MNG_TRUE;
-                      break;
-                    }
-
-          case 10 : {
-#ifndef MNG_NO_16BIT_SUPPORT
-                      if (pImage->pImgbuf->iBitdepth > 8)
-                        pData->fRetrieverow = (mng_fptr)mng_retrieve_rgb16;
-                      else
-#endif
-                        pData->fRetrieverow = (mng_fptr)mng_retrieve_rgb8;
-
-                      pData->bIsOpaque      = MNG_TRUE;
-                      break;
-                    }
-
-
-          case 12 : {
-#ifndef MNG_NO_16BIT_SUPPORT
-                      if (pImage->pImgbuf->iBitdepth > 8)
-                        pData->fRetrieverow = (mng_fptr)mng_retrieve_ga16;
-                      else
-#endif
-                        pData->fRetrieverow = (mng_fptr)mng_retrieve_ga8;
-
-                      pData->bIsOpaque      = MNG_FALSE;
-                      break;
-                    }
-
-
-          case 14 : {
-#ifndef MNG_NO_16BIT_SUPPORT
-                      if (pImage->pImgbuf->iBitdepth > 8)
-                        pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba16;
-                      else
-#endif
-                        pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba8;
-
-                      pData->bIsOpaque      = MNG_FALSE;
-                      break;
-                    }
-
-        }
-
-        pData->iPass       = -1;       /* these are the object's dimensions now */
-        pData->iRow        = pData->iSourcet;
-        pData->iRowinc     = 1;
-        pData->iCol        = 0;
-        pData->iColinc     = 1;
-        pData->iRowsamples = pImage->pImgbuf->iWidth;
-        pData->iRowsize    = pData->iRowsamples << 2;
-        pData->bIsRGBA16   = MNG_FALSE;
-                                       /* adjust for 16-bit object ? */
-#ifndef MNG_NO_16BIT_SUPPORT
-        if (pImage->pImgbuf->iBitdepth > 8)
-        {
-          pData->bIsRGBA16 = MNG_TRUE;
-          pData->iRowsize  = pData->iRowsamples << 3;
-        }
-#endif
-
-        pData->fCorrectrow = MNG_NULL; /* default no color-correction */
-
-#ifdef MNG_NO_CMS
-        iRetcode = MNG_NOERROR;
-#else
-#if defined(MNG_FULL_CMS)              /* determine color-management routine */
-        iRetcode = mng_init_full_cms   (pData, MNG_FALSE, MNG_FALSE, MNG_TRUE);
-#elif defined(MNG_GAMMA_ONLY)
-        iRetcode = mng_init_gamma_only (pData, MNG_FALSE, MNG_FALSE, MNG_TRUE);
-#elif defined(MNG_APP_CMS)
-        iRetcode = mng_init_app_cms    (pData, MNG_FALSE, MNG_FALSE, MNG_TRUE);
-#endif
-        if (iRetcode)                  /* on error bail out */
-          return iRetcode;
-#endif /* MNG_NO_CMS */
-                                       /* get a temporary row-buffer */
-        MNG_ALLOC (pData, pData->pRGBArow, pData->iRowsize);
-
-        iY = pData->iSourcet;          /* this is where we start */
-
-        while ((!iRetcode) && (iY < pData->iSourceb))
-        {                              /* get a row */
-          iRetcode = ((mng_retrieverow)pData->fRetrieverow) (pData);
-                                       /* color correction ? */
-          if ((!iRetcode) && (pData->fCorrectrow))
-            iRetcode = ((mng_correctrow)pData->fCorrectrow) (pData);
-
-          if (!iRetcode)               /* so... display it */
-            iRetcode = ((mng_displayrow)pData->fDisplayrow) (pData);
-
-          if (!iRetcode)               /* adjust variables for next row */
-            iRetcode = mng_next_row (pData);
-
-          iY++;                        /* and next line */
-        }
-                                       /* drop the temporary row-buffer */
-        MNG_FREE (pData, pData->pRGBArow, pData->iRowsize);
-
-        if (iRetcode)                  /* on error bail out */
-          return iRetcode;
-
-#if defined(MNG_FULL_CMS)              /* cleanup cms stuff */
-        iRetcode = mng_clear_cms (pData);
-
-        if (iRetcode)                  /* on error bail out */
-          return iRetcode;
-#endif
-      }
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_IMAGE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* whehehe, this is good ! */
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-mng_retcode mng_execute_delta_image (mng_datap  pData,
-                                     mng_imagep pTarget,
-                                     mng_imagep pDelta)
-{
-  mng_imagedatap pBuftarget = pTarget->pImgbuf;
-  mng_imagedatap pBufdelta  = pDelta->pImgbuf;
-  mng_uint32     iY;
-  mng_retcode    iRetcode;
-  mng_ptr        pSaveRGBA;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_EXECUTE_DELTA_IMAGE, MNG_LC_START);
-#endif
-                                       /* actively running ? */
-  if (((pData->bRunning) || (pData->bSearching)) && (!pData->bSkipping))
-  {
-    if (pBufdelta->bHasPLTE)           /* palette in delta ? */
-    {
-      mng_uint32 iX;
-                                       /* new palette larger than old one ? */
-      if ((!pBuftarget->bHasPLTE) || (pBuftarget->iPLTEcount < pBufdelta->iPLTEcount))
-        pBuftarget->iPLTEcount = pBufdelta->iPLTEcount;
-                                       /* it's definitely got a PLTE now */
-      pBuftarget->bHasPLTE = MNG_TRUE;
-
-      for (iX = 0; iX < pBufdelta->iPLTEcount; iX++)
-      {
-        pBuftarget->aPLTEentries[iX].iRed   = pBufdelta->aPLTEentries[iX].iRed;
-        pBuftarget->aPLTEentries[iX].iGreen = pBufdelta->aPLTEentries[iX].iGreen;
-        pBuftarget->aPLTEentries[iX].iBlue  = pBufdelta->aPLTEentries[iX].iBlue;
-      }
-    }
-
-    if (pBufdelta->bHasTRNS)           /* cheap transparency in delta ? */
-    {
-      switch (pData->iColortype)       /* drop it into the target */
-      {
-        case 0: {                      /* gray */
-                  pBuftarget->iTRNSgray  = pBufdelta->iTRNSgray;
-                  pBuftarget->iTRNSred   = 0;
-                  pBuftarget->iTRNSgreen = 0;
-                  pBuftarget->iTRNSblue  = 0;
-                  pBuftarget->iTRNScount = 0;
-                  break;
-                }
-        case 2: {                      /* rgb */
-                  pBuftarget->iTRNSgray  = 0;
-                  pBuftarget->iTRNSred   = pBufdelta->iTRNSred;
-                  pBuftarget->iTRNSgreen = pBufdelta->iTRNSgreen;
-                  pBuftarget->iTRNSblue  = pBufdelta->iTRNSblue;
-                  pBuftarget->iTRNScount = 0;
-                  break;
-                }
-        case 3: {                      /* indexed */
-                  pBuftarget->iTRNSgray  = 0;
-                  pBuftarget->iTRNSred   = 0;
-                  pBuftarget->iTRNSgreen = 0;
-                  pBuftarget->iTRNSblue  = 0;
-                                       /* existing range smaller than new one ? */
-                  if ((!pBuftarget->bHasTRNS) || (pBuftarget->iTRNScount < pBufdelta->iTRNScount))
-                    pBuftarget->iTRNScount = pBufdelta->iTRNScount;
-
-                  MNG_COPY (pBuftarget->aTRNSentries, pBufdelta->aTRNSentries, pBufdelta->iTRNScount);
-                  break;
-                }
-      }
-
-      pBuftarget->bHasTRNS = MNG_TRUE; /* tell it it's got a tRNS now */
-    }
-
-#ifndef MNG_SKIPCHUNK_bKGD
-    if (pBufdelta->bHasBKGD)           /* bkgd in source ? */
-    {                                  /* drop it onto the target */
-      pBuftarget->bHasBKGD   = MNG_TRUE;
-      pBuftarget->iBKGDindex = pBufdelta->iBKGDindex;
-      pBuftarget->iBKGDgray  = pBufdelta->iBKGDgray;
-      pBuftarget->iBKGDred   = pBufdelta->iBKGDred;
-      pBuftarget->iBKGDgreen = pBufdelta->iBKGDgreen;
-      pBuftarget->iBKGDblue  = pBufdelta->iBKGDblue;
-    }
-#endif
-
-    if (pBufdelta->bHasGAMA)           /* gamma in source ? */
-    {
-      pBuftarget->bHasGAMA = MNG_TRUE; /* drop it onto the target */
-      pBuftarget->iGamma   = pBufdelta->iGamma;
-    }
-
-#ifndef MNG_SKIPCHUNK_cHRM
-    if (pBufdelta->bHasCHRM)           /* chroma in delta ? */
-    {                                  /* drop it onto the target */
-      pBuftarget->bHasCHRM       = MNG_TRUE;
-      pBuftarget->iWhitepointx   = pBufdelta->iWhitepointx;
-      pBuftarget->iWhitepointy   = pBufdelta->iWhitepointy;
-      pBuftarget->iPrimaryredx   = pBufdelta->iPrimaryredx;
-      pBuftarget->iPrimaryredy   = pBufdelta->iPrimaryredy;
-      pBuftarget->iPrimarygreenx = pBufdelta->iPrimarygreenx;
-      pBuftarget->iPrimarygreeny = pBufdelta->iPrimarygreeny;
-      pBuftarget->iPrimarybluex  = pBufdelta->iPrimarybluex;
-      pBuftarget->iPrimarybluey  = pBufdelta->iPrimarybluey;
-    }
-#endif
-
-#ifndef MNG_SKIPCHUNK_sRGB
-    if (pBufdelta->bHasSRGB)           /* sRGB in delta ? */
-    {                                  /* drop it onto the target */
-      pBuftarget->bHasSRGB         = MNG_TRUE;
-      pBuftarget->iRenderingintent = pBufdelta->iRenderingintent;
-    }
-#endif
-
-#ifndef MNG_SKIPCHUNK_iCCP
-    if (pBufdelta->bHasICCP)           /* ICC profile in delta ? */
-    {
-      pBuftarget->bHasICCP = MNG_TRUE; /* drop it onto the target */
-
-      if (pBuftarget->pProfile)        /* profile existed ? */
-        MNG_FREEX (pData, pBuftarget->pProfile, pBuftarget->iProfilesize);
-                                       /* allocate a buffer & copy it */
-      MNG_ALLOC (pData, pBuftarget->pProfile, pBufdelta->iProfilesize);
-      MNG_COPY  (pBuftarget->pProfile, pBufdelta->pProfile, pBufdelta->iProfilesize);
-                                       /* store its length as well */
-      pBuftarget->iProfilesize = pBufdelta->iProfilesize;
-    }
-#endif
-                                       /* need to execute delta pixels ? */
-    if ((!pData->bDeltaimmediate) && (pData->iDeltatype != MNG_DELTATYPE_NOCHANGE))
-    {
-      pData->fScalerow = MNG_NULL;     /* not needed by default */
-
-      switch (pBufdelta->iBitdepth)    /* determine scaling routine */
-      {
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-        case  1 : {
-                    switch (pBuftarget->iBitdepth)
-                    {
-                      case  2 : { pData->fScalerow = (mng_fptr)mng_scale_g1_g2;  break; }
-                      case  4 : { pData->fScalerow = (mng_fptr)mng_scale_g1_g4;  break; }
-
-                      case  8 : { pData->fScalerow = (mng_fptr)mng_scale_g1_g8;  break; }
-#ifndef MNG_NO_16BIT_SUPPORT
-                      case 16 : { pData->fScalerow = (mng_fptr)mng_scale_g1_g16; break; }
-#endif
-                    }
-                    break;
-                  }
-
-        case  2 : {
-                    switch (pBuftarget->iBitdepth)
-                    {
-                      case  1 : { pData->fScalerow = (mng_fptr)mng_scale_g2_g1;  break; }
-                      case  4 : { pData->fScalerow = (mng_fptr)mng_scale_g2_g4;  break; }
-                      case  8 : { pData->fScalerow = (mng_fptr)mng_scale_g2_g8;  break; }
-#ifndef MNG_NO_16BIT_SUPPORT
-                      case 16 : { pData->fScalerow = (mng_fptr)mng_scale_g2_g16; break; }
-#endif
-                    }
-                    break;
-                  }
-
-        case  4 : {
-                    switch (pBuftarget->iBitdepth)
-                    {
-                      case  1 : { pData->fScalerow = (mng_fptr)mng_scale_g4_g1;  break; }
-                      case  2 : { pData->fScalerow = (mng_fptr)mng_scale_g4_g2;  break; }
-                      case  8 : { pData->fScalerow = (mng_fptr)mng_scale_g4_g8;  break; }
-#ifndef MNG_NO_16BIT_SUPPORT
-                      case 16 : { pData->fScalerow = (mng_fptr)mng_scale_g4_g16; break; }
-#endif
-                    }
-                    break;
-                  }
-#endif /* MNG_NO_1_2_4BIT_SUPPORT */
-
-        case  8 : {
-                    switch (pBufdelta->iColortype)
-                    {
-                      case  0 : ;
-                      case  3 : ;
-                      case  8 : {
-                                  switch (pBuftarget->iBitdepth)
-                                  {
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-                                    case  1 : { pData->fScalerow = (mng_fptr)mng_scale_g8_g1;  break; }
-                                    case  2 : { pData->fScalerow = (mng_fptr)mng_scale_g8_g2;  break; }
-                                    case  4 : { pData->fScalerow = (mng_fptr)mng_scale_g8_g4;  break; }
-#endif /* MNG_NO_1_2_4BIT_SUPPORT */
-#ifndef MNG_NO_16BIT_SUPPORT
-                                    case 16 : { pData->fScalerow = (mng_fptr)mng_scale_g8_g16; break; }
-#endif
-                                  }
-                                  break;
-                                }
-                      case  2 : ;
-                      case 10 : {
-#ifndef MNG_NO_16BIT_SUPPORT
-                                  if (pBuftarget->iBitdepth == 16)
-                                    pData->fScalerow = (mng_fptr)mng_scale_rgb8_rgb16;
-#endif
-                                  break;
-                                }
-                      case  4 : ;
-                      case 12 : {
-#ifndef MNG_NO_16BIT_SUPPORT
-                                  if (pBuftarget->iBitdepth == 16)
-                                    pData->fScalerow = (mng_fptr)mng_scale_ga8_ga16;
-#endif
-                                  break;
-                                }
-                      case  6 : ;
-                      case 14 : {
-#ifndef MNG_NO_16BIT_SUPPORT
-                                  if (pBuftarget->iBitdepth == 16)
-                                    pData->fScalerow = (mng_fptr)mng_scale_rgba8_rgba16;
-#endif
-                                  break;
-                                }
-                    }
-                    break;
-                  }
-
-#ifndef MNG_NO_16BIT_SUPPORT
-        case 16 : {
-                    switch (pBufdelta->iColortype)
-                    {
-                      case  0 : ;
-                      case  3 : ;
-                      case  8 : {
-                                  switch (pBuftarget->iBitdepth)
-                                  {
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-                                    case 1 : { pData->fScalerow = (mng_fptr)mng_scale_g16_g1; break; }
-                                    case 2 : { pData->fScalerow = (mng_fptr)mng_scale_g16_g2; break; }
-                                    case 4 : { pData->fScalerow = (mng_fptr)mng_scale_g16_g4; break; }
-#endif /* MNG_NO_1_2_4BIT_SUPPORT */
-                                    case 8 : { pData->fScalerow = (mng_fptr)mng_scale_g16_g8; break; }
-                                  }
-                                  break;
-                                }
-                      case  2 : ;
-                      case 10 : {
-                                  if (pBuftarget->iBitdepth == 8)
-                                    pData->fScalerow = (mng_fptr)mng_scale_rgb16_rgb8;
-                                  break;
-                                }
-                      case  4 : ;
-                      case 12 : {
-                                  if (pBuftarget->iBitdepth == 8)
-                                    pData->fScalerow = (mng_fptr)mng_scale_ga16_ga8;
-                                  break;
-                                }
-                      case  6 : ;
-                      case 14 : {
-                                  if (pBuftarget->iBitdepth == 8)
-                                    pData->fScalerow = (mng_fptr)mng_scale_rgba16_rgba8;
-                                  break;
-                                }
-                    }
-                    break;
-                  }
-#endif
-
-      }
-
-      pData->fDeltarow = MNG_NULL;     /* let's assume there's nothing to do */
-
-      switch (pBuftarget->iColortype)  /* determine delta processing routine */
-      {
-        case  0 : ;
-        case  8 : {                     /* gray */
-                    if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE          ) ||
-                        (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD    ) ||
-                        (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
-                    {
-                      if ((pBufdelta->iColortype == 0) || (pBufdelta->iColortype == 3) ||
-                          (pBufdelta->iColortype == 8))
-                      {
-                        switch (pBuftarget->iBitdepth)
-                        {
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-                          case  1 : { pData->fDeltarow = (mng_fptr)mng_delta_g1_g1;   break; }
-                          case  2 : { pData->fDeltarow = (mng_fptr)mng_delta_g2_g2;   break; }
-                          case  4 : { pData->fDeltarow = (mng_fptr)mng_delta_g4_g4;   break; }
-#endif /* MNG_NO_1_2_4BIT_SUPPORT */
-                          case  8 : { pData->fDeltarow = (mng_fptr)mng_delta_g8_g8;   break; }
-#ifndef MNG_NO_16BIT_SUPPORT
-                          case 16 : { pData->fDeltarow = (mng_fptr)mng_delta_g16_g16; break; }
-#endif
-                        }
-                      }
-                    }
-
-                    break;
-                  }
-
-        case  2 : ;
-        case 10 : {                     /* rgb */
-                    if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE          ) ||
-                        (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD    ) ||
-                        (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
-                    {
-                      if ((pBufdelta->iColortype == 2) || (pBufdelta->iColortype == 10))
-                      {
-                        switch (pBuftarget->iBitdepth)
-                        {
-                          case  8 : { pData->fDeltarow = (mng_fptr)mng_delta_rgb8_rgb8;   break; }
-#ifndef MNG_NO_16BIT_SUPPORT
-                          case 16 : { pData->fDeltarow = (mng_fptr)mng_delta_rgb16_rgb16; break; }
-#endif
-                        }
-                      }
-                    }
-
-                    break;
-                  }
-
-        case  3 : {                     /* indexed; abuse gray routines */
-                    if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE          ) ||
-                        (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD    ) ||
-                        (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
-                    {
-                      if ((pBufdelta->iColortype == 0) || (pBufdelta->iColortype == 3))
-                      {
-                        switch (pBuftarget->iBitdepth)
-                        {
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-                          case  1 : { pData->fDeltarow = (mng_fptr)mng_delta_g1_g1; break; }
-                          case  2 : { pData->fDeltarow = (mng_fptr)mng_delta_g2_g2; break; }
-                          case  4 : { pData->fDeltarow = (mng_fptr)mng_delta_g4_g4; break; }
-#endif /* MNG_NO_1_2_4BIT_SUPPORT */
-                          case  8 : { pData->fDeltarow = (mng_fptr)mng_delta_g8_g8; break; }
-                        }
-                      }
-                    }
-
-                    break;
-                  }
-
-        case  4 : ;
-        case 12 : {                     /* gray + alpha */
-                    if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE          ) ||
-                        (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD    ) ||
-                        (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
-                    {
-                      if ((pBufdelta->iColortype == 4) || (pBufdelta->iColortype == 12))
-                      {
-                        switch (pBuftarget->iBitdepth)
-                        {
-                          case  8 : { pData->fDeltarow = (mng_fptr)mng_delta_ga8_ga8;   break; }
-#ifndef MNG_NO_16BIT_SUPPORT
-                          case 16 : { pData->fDeltarow = (mng_fptr)mng_delta_ga16_ga16; break; }
-#endif
-                        }
-                      }
-                    }
-                    else
-                    if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORADD    ) ||
-                        (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE)    )
-                    {
-                      if ((pBufdelta->iColortype == 0) || (pBufdelta->iColortype == 3) ||
-                          (pBufdelta->iColortype == 8))
-                      {
-                        switch (pBuftarget->iBitdepth)
-                        {
-                          case  8 : { pData->fDeltarow = (mng_fptr)mng_delta_ga8_g8;   break; }
-#ifndef MNG_NO_16BIT_SUPPORT
-                          case 16 : { pData->fDeltarow = (mng_fptr)mng_delta_ga16_g16; break; }
-#endif
-                        }
-                      }
-                    }
-                    else
-                    if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAADD    ) ||
-                        (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE)    )
-                    {
-                      if ((pBufdelta->iColortype == 0) || (pBufdelta->iColortype == 3))
-                      {
-                        switch (pBuftarget->iBitdepth)
-                        {
-                          case  8 : { pData->fDeltarow = (mng_fptr)mng_delta_ga8_a8;   break; }
-#ifndef MNG_NO_16BIT_SUPPORT
-                          case 16 : { pData->fDeltarow = (mng_fptr)mng_delta_ga16_a16; break; }
-#endif
-                        }
-                      }
-                    }
-
-                    break;
-                  }
-
-        case  6 : ;
-        case 14 : {                     /* rgb + alpha */
-                    if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE          ) ||
-                        (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD    ) ||
-                        (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
-                    {
-                      if ((pBufdelta->iColortype == 6) || (pBufdelta->iColortype == 14))
-                      {
-                        switch (pBuftarget->iBitdepth)
-                        {
-                          case  8 : { pData->fDeltarow = (mng_fptr)mng_delta_rgba8_rgba8;   break; }
-#ifndef MNG_NO_16BIT_SUPPORT
-                          case 16 : { pData->fDeltarow = (mng_fptr)mng_delta_rgba16_rgba16; break; }
-#endif
-                        }
-                      }
-                    }
-                    else
-                    if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORADD    ) ||
-                        (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE)    )
-                    {
-                      if ((pBufdelta->iColortype == 2) || (pBufdelta->iColortype == 10))
-                      {
-                        switch (pBuftarget->iBitdepth)
-                        {
-                          case  8 : { pData->fDeltarow = (mng_fptr)mng_delta_rgba8_rgb8;   break; }
-#ifndef MNG_NO_16BIT_SUPPORT
-                          case 16 : { pData->fDeltarow = (mng_fptr)mng_delta_rgba16_rgb16; break; }
-#endif
-                        }
-                      }
-                    }
-                    else
-                    if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAADD    ) ||
-                        (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE)    )
-                    {
-                      if ((pBufdelta->iColortype == 0) || (pBufdelta->iColortype == 3))
-                      {
-                        switch (pBuftarget->iBitdepth)
-                        {
-                          case  8 : { pData->fDeltarow = (mng_fptr)mng_delta_rgba8_a8;   break; }
-#ifndef MNG_NO_16BIT_SUPPORT
-                          case 16 : { pData->fDeltarow = (mng_fptr)mng_delta_rgba16_a16; break; }
-#endif
-                        }
-                      }
-                    }
-
-                    break;
-                  }
-
-      }
-
-      if (pData->fDeltarow)            /* do we need to take action ? */
-      {
-        pData->iPass        = -1;      /* setup row dimensions and stuff */
-        pData->iRow         = pData->iDeltaBlocky;
-        pData->iRowinc      = 1;
-        pData->iCol         = pData->iDeltaBlockx;
-        pData->iColinc      = 1;
-        pData->iRowsamples  = pBufdelta->iWidth;
-        pData->iRowsize     = pBuftarget->iRowsize;
-                                       /* indicate where to retrieve & where to store */
-        pData->pRetrieveobj = (mng_objectp)pDelta;
-        pData->pStoreobj    = (mng_objectp)pTarget;
-
-        pSaveRGBA = pData->pRGBArow;   /* save current temp-buffer! */
-                                       /* get a temporary row-buffer */
-        MNG_ALLOC (pData, pData->pRGBArow, (pBufdelta->iRowsize << 1));
-
-        iY       = 0;                  /* this is where we start */
-        iRetcode = MNG_NOERROR;        /* still oke for now */
-
-        while ((!iRetcode) && (iY < pBufdelta->iHeight))
-        {                              /* get a row */
-          mng_uint8p pWork = pBufdelta->pImgdata + (iY * pBufdelta->iRowsize);
-
-          MNG_COPY (pData->pRGBArow, pWork, pBufdelta->iRowsize);
-
-          if (pData->fScalerow)        /* scale it (if necessary) */
-            iRetcode = ((mng_scalerow)pData->fScalerow) (pData);
-
-          if (!iRetcode)               /* and... execute it */
-            iRetcode = ((mng_deltarow)pData->fDeltarow) (pData);
-
-          if (!iRetcode)               /* adjust variables for next row */
-            iRetcode = mng_next_row (pData);
-
-          iY++;                        /* and next line */
-        }
-                                       /* drop the temporary row-buffer */
-        MNG_FREE (pData, pData->pRGBArow, (pBufdelta->iRowsize << 1));
-        pData->pRGBArow = pSaveRGBA;   /* restore saved temp-buffer! */
-
-        if (iRetcode)                  /* on error bail out */
-          return iRetcode;
-
-      }
-      else
-        MNG_ERROR (pData, MNG_INVALIDDELTA);
-
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_EXECUTE_DELTA_IMAGE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_NO_DELTA_PNG */
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_SAVE
-MNG_LOCAL mng_retcode save_state (mng_datap pData)
-{
-  mng_savedatap pSave;
-  mng_imagep    pImage;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SAVE_STATE, MNG_LC_START);
-#endif
-
-  if (pData->pSavedata)                /* sanity check */
-    MNG_ERROR (pData, MNG_INTERNALERROR);
-                                       /* get a buffer for saving */
-  MNG_ALLOC (pData, pData->pSavedata, sizeof (mng_savedata));
-
-  pSave = pData->pSavedata;            /* address it more directly */
-                                       /* and copy global data from the main struct */
-#if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
-  pSave->bHasglobalPLTE       = pData->bHasglobalPLTE;
-  pSave->bHasglobalTRNS       = pData->bHasglobalTRNS;
-  pSave->bHasglobalGAMA       = pData->bHasglobalGAMA;
-  pSave->bHasglobalCHRM       = pData->bHasglobalCHRM;
-  pSave->bHasglobalSRGB       = pData->bHasglobalSRGB;
-  pSave->bHasglobalICCP       = pData->bHasglobalICCP;
-  pSave->bHasglobalBKGD       = pData->bHasglobalBKGD;
-#endif /* MNG_SUPPORT_READ || MNG_SUPPORT_WRITE */
-
-#ifndef MNG_SKIPCHUNK_BACK
-  pSave->iBACKred             = pData->iBACKred;
-  pSave->iBACKgreen           = pData->iBACKgreen;
-  pSave->iBACKblue            = pData->iBACKblue;
-  pSave->iBACKmandatory       = pData->iBACKmandatory;
-  pSave->iBACKimageid         = pData->iBACKimageid;
-  pSave->iBACKtile            = pData->iBACKtile;
-#endif
-
-#ifndef MNG_SKIPCHUNK_FRAM
-  pSave->iFRAMmode            = pData->iFRAMmode;
-  pSave->iFRAMdelay           = pData->iFRAMdelay;
-  pSave->iFRAMtimeout         = pData->iFRAMtimeout;
-  pSave->bFRAMclipping        = pData->bFRAMclipping;
-  pSave->iFRAMclipl           = pData->iFRAMclipl;
-  pSave->iFRAMclipr           = pData->iFRAMclipr;
-  pSave->iFRAMclipt           = pData->iFRAMclipt;
-  pSave->iFRAMclipb           = pData->iFRAMclipb;
-#endif
-
-  pSave->iGlobalPLTEcount     = pData->iGlobalPLTEcount;
-
-  MNG_COPY (pSave->aGlobalPLTEentries, pData->aGlobalPLTEentries, sizeof (mng_rgbpaltab));
-
-  pSave->iGlobalTRNSrawlen    = pData->iGlobalTRNSrawlen;
-  MNG_COPY (pSave->aGlobalTRNSrawdata, pData->aGlobalTRNSrawdata, 256);
-
-  pSave->iGlobalGamma         = pData->iGlobalGamma;
-
-#ifndef MNG_SKIPCHUNK_cHRM
-  pSave->iGlobalWhitepointx   = pData->iGlobalWhitepointx;
-  pSave->iGlobalWhitepointy   = pData->iGlobalWhitepointy;
-  pSave->iGlobalPrimaryredx   = pData->iGlobalPrimaryredx;
-  pSave->iGlobalPrimaryredy   = pData->iGlobalPrimaryredy;
-  pSave->iGlobalPrimarygreenx = pData->iGlobalPrimarygreenx;
-  pSave->iGlobalPrimarygreeny = pData->iGlobalPrimarygreeny;
-  pSave->iGlobalPrimarybluex  = pData->iGlobalPrimarybluex;
-  pSave->iGlobalPrimarybluey  = pData->iGlobalPrimarybluey;
-#endif
-
-#ifndef MNG_SKIPCHUNK_sRGB
-  pSave->iGlobalRendintent    = pData->iGlobalRendintent;
-#endif
-
-#ifndef MNG_SKIPCHUNK_iCCP
-  pSave->iGlobalProfilesize   = pData->iGlobalProfilesize;
-
-  if (pSave->iGlobalProfilesize)       /* has a profile ? */
-  {                                    /* then copy that ! */
-    MNG_ALLOC (pData, pSave->pGlobalProfile, pSave->iGlobalProfilesize);
-    MNG_COPY (pSave->pGlobalProfile, pData->pGlobalProfile, pSave->iGlobalProfilesize);
-  }
-#endif
-
-#ifndef MNG_SKIPCHUNK_bKGD
-  pSave->iGlobalBKGDred       = pData->iGlobalBKGDred;
-  pSave->iGlobalBKGDgreen     = pData->iGlobalBKGDgreen;
-  pSave->iGlobalBKGDblue      = pData->iGlobalBKGDblue;
-#endif
-
-                                       /* freeze current image objects */
-  pImage = (mng_imagep)pData->pFirstimgobj;
-
-  while (pImage)
-  {                                    /* freeze the object AND its buffer */
-    pImage->bFrozen          = MNG_TRUE;
-    pImage->pImgbuf->bFrozen = MNG_TRUE;
-                                       /* neeeext */
-    pImage = (mng_imagep)pImage->sHeader.pNext;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SAVE_STATE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_reset_objzero (mng_datap pData)
-{
-  mng_imagep  pImage   = (mng_imagep)pData->pObjzero;
-  mng_retcode iRetcode = mng_reset_object_details (pData, pImage, 0, 0, 0,
-                                                   0, 0, 0, 0, MNG_TRUE);
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-
-  pImage->bVisible             = MNG_TRUE;
-  pImage->bViewable            = MNG_TRUE;
-  pImage->iPosx                = 0;
-  pImage->iPosy                = 0;
-  pImage->bClipped             = MNG_FALSE;
-  pImage->iClipl               = 0;
-  pImage->iClipr               = 0;
-  pImage->iClipt               = 0;
-  pImage->iClipb               = 0;
-#ifndef MNG_SKIPCHUNK_MAGN
-  pImage->iMAGN_MethodX        = 0;
-  pImage->iMAGN_MethodY        = 0;
-  pImage->iMAGN_MX             = 0;
-  pImage->iMAGN_MY             = 0;
-  pImage->iMAGN_ML             = 0;
-  pImage->iMAGN_MR             = 0;
-  pImage->iMAGN_MT             = 0;
-  pImage->iMAGN_MB             = 0;
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-MNG_LOCAL mng_retcode restore_state (mng_datap pData)
-{
-#ifndef MNG_SKIPCHUNK_SAVE
-  mng_savedatap pSave;
-#endif
-  mng_imagep    pImage;
-  mng_retcode   iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RESTORE_STATE, MNG_LC_START);
-#endif
-                                       /* restore object 0 status !!! */
-  iRetcode = mng_reset_objzero (pData);
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* fresh cycle; fake no frames done yet */
-  pData->bFramedone             = MNG_FALSE;
-
-#ifndef MNG_SKIPCHUNK_SAVE
-  if (pData->pSavedata)                /* do we have a saved state ? */
-  {
-    pSave = pData->pSavedata;          /* address it more directly */
-                                       /* and copy it back to the main struct */
-#if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
-    pData->bHasglobalPLTE       = pSave->bHasglobalPLTE;
-    pData->bHasglobalTRNS       = pSave->bHasglobalTRNS;
-    pData->bHasglobalGAMA       = pSave->bHasglobalGAMA;
-    pData->bHasglobalCHRM       = pSave->bHasglobalCHRM;
-    pData->bHasglobalSRGB       = pSave->bHasglobalSRGB;
-    pData->bHasglobalICCP       = pSave->bHasglobalICCP;
-    pData->bHasglobalBKGD       = pSave->bHasglobalBKGD;
-#endif /* MNG_SUPPORT_READ || MNG_SUPPORT_WRITE */
-
-#ifndef MNG_SKIPCHUNK_BACK
-    pData->iBACKred             = pSave->iBACKred;
-    pData->iBACKgreen           = pSave->iBACKgreen;
-    pData->iBACKblue            = pSave->iBACKblue;
-    pData->iBACKmandatory       = pSave->iBACKmandatory;
-    pData->iBACKimageid         = pSave->iBACKimageid;
-    pData->iBACKtile            = pSave->iBACKtile;
-#endif
-
-#ifndef MNG_SKIPCHUNK_FRAM
-    pData->iFRAMmode            = pSave->iFRAMmode;
-/*    pData->iFRAMdelay           = pSave->iFRAMdelay; */
-    pData->iFRAMtimeout         = pSave->iFRAMtimeout;
-    pData->bFRAMclipping        = pSave->bFRAMclipping;
-    pData->iFRAMclipl           = pSave->iFRAMclipl;
-    pData->iFRAMclipr           = pSave->iFRAMclipr;
-    pData->iFRAMclipt           = pSave->iFRAMclipt;
-    pData->iFRAMclipb           = pSave->iFRAMclipb;
-                                       /* NOOOOOOOOOOOO */
-/*    pData->iFramemode           = pSave->iFRAMmode;
-    pData->iFramedelay          = pSave->iFRAMdelay;
-    pData->iFrametimeout        = pSave->iFRAMtimeout;
-    pData->bFrameclipping       = pSave->bFRAMclipping;
-    pData->iFrameclipl          = pSave->iFRAMclipl;
-    pData->iFrameclipr          = pSave->iFRAMclipr;
-    pData->iFrameclipt          = pSave->iFRAMclipt;
-    pData->iFrameclipb          = pSave->iFRAMclipb; */
-
-/*    pData->iNextdelay           = pSave->iFRAMdelay; */
-    pData->iNextdelay           = pData->iFramedelay;
-#endif
-
-    pData->iGlobalPLTEcount     = pSave->iGlobalPLTEcount;
-    MNG_COPY (pData->aGlobalPLTEentries, pSave->aGlobalPLTEentries, sizeof (mng_rgbpaltab));
-
-    pData->iGlobalTRNSrawlen    = pSave->iGlobalTRNSrawlen;
-    MNG_COPY (pData->aGlobalTRNSrawdata, pSave->aGlobalTRNSrawdata, 256);
-
-    pData->iGlobalGamma         = pSave->iGlobalGamma;
-
-#ifndef MNG_SKIPCHUNK_cHRM
-    pData->iGlobalWhitepointx   = pSave->iGlobalWhitepointx;
-    pData->iGlobalWhitepointy   = pSave->iGlobalWhitepointy;
-    pData->iGlobalPrimaryredx   = pSave->iGlobalPrimaryredx;
-    pData->iGlobalPrimaryredy   = pSave->iGlobalPrimaryredy;
-    pData->iGlobalPrimarygreenx = pSave->iGlobalPrimarygreenx;
-    pData->iGlobalPrimarygreeny = pSave->iGlobalPrimarygreeny;
-    pData->iGlobalPrimarybluex  = pSave->iGlobalPrimarybluex;
-    pData->iGlobalPrimarybluey  = pSave->iGlobalPrimarybluey;
-#endif
-
-    pData->iGlobalRendintent    = pSave->iGlobalRendintent;
-
-#ifndef MNG_SKIPCHUNK_iCCP
-    pData->iGlobalProfilesize   = pSave->iGlobalProfilesize;
-
-    if (pData->iGlobalProfilesize)     /* has a profile ? */
-    {                                  /* then copy that ! */
-      MNG_ALLOC (pData, pData->pGlobalProfile, pData->iGlobalProfilesize);
-      MNG_COPY (pData->pGlobalProfile, pSave->pGlobalProfile, pData->iGlobalProfilesize);
-    }
-#endif
-
-#ifndef MNG_SKIPCHUNK_bKGD
-    pData->iGlobalBKGDred       = pSave->iGlobalBKGDred;
-    pData->iGlobalBKGDgreen     = pSave->iGlobalBKGDgreen;
-    pData->iGlobalBKGDblue      = pSave->iGlobalBKGDblue;
-#endif
-  }
-  else                                 /* no saved-data; so reset the lot */
-#endif /* SKIPCHUNK_SAVE */
-  {
-#if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
-    pData->bHasglobalPLTE       = MNG_FALSE;
-    pData->bHasglobalTRNS       = MNG_FALSE;
-    pData->bHasglobalGAMA       = MNG_FALSE;
-    pData->bHasglobalCHRM       = MNG_FALSE;
-    pData->bHasglobalSRGB       = MNG_FALSE;
-    pData->bHasglobalICCP       = MNG_FALSE;
-    pData->bHasglobalBKGD       = MNG_FALSE;
-#endif /* MNG_SUPPORT_READ || MNG_SUPPORT_WRITE */
-
-#ifndef MNG_SKIPCHUNK_TERM
-    if (!pData->bMisplacedTERM)        /* backward compatible ugliness !!! */
-    {
-      pData->iBACKred           = 0;
-      pData->iBACKgreen         = 0;
-      pData->iBACKblue          = 0;
-      pData->iBACKmandatory     = 0;
-      pData->iBACKimageid       = 0;
-      pData->iBACKtile          = 0;
-    }
-#endif
-
-#ifndef MNG_SKIPCHUNK_FRAM
-    pData->iFRAMmode            = 1;
-/*    pData->iFRAMdelay           = 1; */
-    pData->iFRAMtimeout         = 0x7fffffffl;
-    pData->bFRAMclipping        = MNG_FALSE;
-    pData->iFRAMclipl           = 0;
-    pData->iFRAMclipr           = 0;
-    pData->iFRAMclipt           = 0;
-    pData->iFRAMclipb           = 0;
-                                       /* NOOOOOOOOOOOO */
-/*    pData->iFramemode           = 1;
-    pData->iFramedelay          = 1;
-    pData->iFrametimeout        = 0x7fffffffl;
-    pData->bFrameclipping       = MNG_FALSE;
-    pData->iFrameclipl          = 0;
-    pData->iFrameclipr          = 0;
-    pData->iFrameclipt          = 0;
-    pData->iFrameclipb          = 0; */
-
-/*    pData->iNextdelay           = 1; */
-    pData->iNextdelay           = pData->iFramedelay;
-#endif
-
-    pData->iGlobalPLTEcount     = 0;
-
-    pData->iGlobalTRNSrawlen    = 0;
-
-    pData->iGlobalGamma         = 0;
-
-#ifndef MNG_SKIPCHUNK_cHRM
-    pData->iGlobalWhitepointx   = 0;
-    pData->iGlobalWhitepointy   = 0;
-    pData->iGlobalPrimaryredx   = 0;
-    pData->iGlobalPrimaryredy   = 0;
-    pData->iGlobalPrimarygreenx = 0;
-    pData->iGlobalPrimarygreeny = 0;
-    pData->iGlobalPrimarybluex  = 0;
-    pData->iGlobalPrimarybluey  = 0;
-#endif
-
-    pData->iGlobalRendintent    = 0;
-
-#ifndef MNG_SKIPCHUNK_iCCP
-    if (pData->iGlobalProfilesize)     /* free a previous profile ? */
-      MNG_FREE (pData, pData->pGlobalProfile, pData->iGlobalProfilesize);
-
-    pData->iGlobalProfilesize   = 0;
-#endif
-
-#ifndef MNG_SKIPCHUNK_bKGD
-    pData->iGlobalBKGDred       = 0;
-    pData->iGlobalBKGDgreen     = 0;
-    pData->iGlobalBKGDblue      = 0;
-#endif
-  }
-
-#ifndef MNG_SKIPCHUNK_TERM
-  if (!pData->bMisplacedTERM)          /* backward compatible ugliness !!! */
-  {
-    pImage = (mng_imagep)pData->pFirstimgobj;
-                                       /* drop un-frozen image objects */
-    while (pImage)
-    {
-      mng_imagep pNext = (mng_imagep)pImage->sHeader.pNext;
-
-      if (!pImage->bFrozen)            /* is it un-frozen ? */
-      {
-        mng_imagep pPrev = (mng_imagep)pImage->sHeader.pPrev;
-
-        if (pPrev)                     /* unlink it */
-          pPrev->sHeader.pNext = pNext;
-        else
-          pData->pFirstimgobj  = pNext;
-
-        if (pNext)
-          pNext->sHeader.pPrev = pPrev;
-        else
-          pData->pLastimgobj   = pPrev;
-
-        if (pImage->pImgbuf->bFrozen)  /* buffer frozen ? */
-        {
-          if (pImage->pImgbuf->iRefcount < 2)
-            MNG_ERROR (pData, MNG_INTERNALERROR);
-                                       /* decrease ref counter */
-          pImage->pImgbuf->iRefcount--;
-                                       /* just cleanup the object then */
-          MNG_FREEX (pData, pImage, sizeof (mng_image));
-        }
-        else
-        {                              /* free the image buffer */
-          iRetcode = mng_free_imagedataobject (pData, pImage->pImgbuf);
-                                       /* and cleanup the object */
-          MNG_FREEX (pData, pImage, sizeof (mng_image));
-
-          if (iRetcode)                /* on error bail out */
-            return iRetcode;
-        }
-      }
-
-      pImage = pNext;                  /* neeeext */
-    }
-  }
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RESTORE_STATE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * General display processing routine                                     * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-mng_retcode mng_process_display (mng_datap pData)
-{
-  mng_retcode iRetcode = MNG_NOERROR;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY, MNG_LC_START);
-#endif
-
-  if (!pData->iBreakpoint)             /* not broken previously ? */
-  {
-    if ((pData->iRequestframe) || (pData->iRequestlayer) || (pData->iRequesttime))
-    {
-      pData->bSearching = MNG_TRUE;    /* indicate we're searching */
-
-      iRetcode = clear_canvas (pData); /* make the canvas virgin black ?!? */
-
-      if (iRetcode)                    /* on error bail out */
-        return iRetcode;
-                                       /* let's start from the top, shall we */
-      pData->pCurraniobj = pData->pFirstaniobj;
-    }
-  }
-
-  do                                   /* process the objects */
-  {
-    if (pData->bSearching)             /* clear timer-flag when searching !!! */
-      pData->bTimerset = MNG_FALSE;
-                                       /* do we need to finish something first ? */
-    if ((pData->iBreakpoint) && (pData->iBreakpoint < 99))
-    {
-      switch (pData->iBreakpoint)      /* return to broken display routine */
-      {
-#ifndef MNG_SKIPCHUNK_FRAM
-        case  1 : { iRetcode = mng_process_display_fram2 (pData); break; }
-#endif
-#ifndef MNG_SKIPCHUNK_SHOW
-        case  3 : ;                    /* same as 4 !!! */
-        case  4 : { iRetcode = mng_process_display_show  (pData); break; }
-#endif
-#ifndef MNG_SKIPCHUNK_CLON
-        case  5 : { iRetcode = mng_process_display_clon2 (pData); break; }
-#endif
-#ifndef MNG_SKIPCHUNK_MAGN
-        case  9 : { iRetcode = mng_process_display_magn2 (pData); break; }
-        case 10 : { iRetcode = mng_process_display_mend2 (pData); break; }
-#endif
-#ifndef MNG_SKIPCHUNK_PAST
-        case 11 : { iRetcode = mng_process_display_past2 (pData); break; }
-#endif
-        default : MNG_ERROR (pData, MNG_INTERNALERROR);
-      }
-    }
-    else
-    {
-      if (pData->pCurraniobj)
-        iRetcode = ((mng_object_headerp)pData->pCurraniobj)->fProcess (pData, pData->pCurraniobj);
-    }
-
-    if (!pData->bTimerset)             /* reset breakpoint flag ? */
-      pData->iBreakpoint = 0;
-                                       /* can we advance to next object ? */
-    if ((!iRetcode) && (pData->pCurraniobj) &&
-        (!pData->bTimerset) && (!pData->bSectionwait))
-    {
-      pData->pCurraniobj = ((mng_object_headerp)pData->pCurraniobj)->pNext;
-                                       /* MEND processing to be done ? */
-      if ((pData->eImagetype == mng_it_mng) && (!pData->pCurraniobj))
-        iRetcode = mng_process_display_mend (pData);
-
-      if (!pData->pCurraniobj)         /* refresh after last image ? */
-        pData->bNeedrefresh = MNG_TRUE;
-    }
-
-    if (pData->bSearching)             /* are we looking for something ? */
-    {
-      if ((pData->iRequestframe) && (pData->iRequestframe <= pData->iFrameseq))
-      {
-        pData->iRequestframe = 0;      /* found the frame ! */
-        pData->bSearching    = MNG_FALSE;
-      }
-      else
-      if ((pData->iRequestlayer) && (pData->iRequestlayer <= pData->iLayerseq))
-      {
-        pData->iRequestlayer = 0;      /* found the layer ! */
-        pData->bSearching    = MNG_FALSE;
-      }
-      else
-      if ((pData->iRequesttime) && (pData->iRequesttime <= pData->iFrametime))
-      {
-        pData->iRequesttime  = 0;      /* found the playtime ! */
-        pData->bSearching    = MNG_FALSE;
-      }
-    }
-  }                                    /* until error or a break or no more objects */
-  while ((!iRetcode) && (pData->pCurraniobj) &&
-         (((pData->bRunning) && (!pData->bTimerset)) || (pData->bSearching)) &&
-         (!pData->bSectionwait) && (!pData->bFreezing));
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* refresh needed ? */
-  if ((!pData->bTimerset) && (pData->bNeedrefresh))
-  {
-    iRetcode = mng_display_progressive_refresh (pData, 1);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-  }
-                                       /* timer break ? */
-  if ((pData->bTimerset) && (!pData->iBreakpoint))
-    pData->iBreakpoint = 99;
-  else
-  if (!pData->bTimerset)
-    pData->iBreakpoint = 0;            /* reset if no timer break */
-
-  if ((!pData->bTimerset) && (!pData->pCurraniobj))
-    pData->bRunning = MNG_FALSE;       /* all done now ! */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Chunk display processing routines                                      * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifdef MNG_OPTIMIZE_FOOTPRINT_INIT
-png_imgtype mng_png_imgtype(mng_uint8 colortype, mng_uint8 bitdepth)
-{
-  png_imgtype ret;
-  switch (bitdepth)
-  {
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-    case 1:
-    {
-      png_imgtype imgtype[]={png_g1,png_none,png_none,png_idx1};
-      ret=imgtype[colortype];
-      break;
-    }
-    case 2:
-    {
-      png_imgtype imgtype[]={png_g2,png_none,png_none,png_idx2};
-      ret=imgtype[colortype];
-      break;
-    }
-    case 4:
-    {
-      png_imgtype imgtype[]={png_g4,png_none,png_none,png_idx4};
-      ret=imgtype[colortype];
-      break;
-    }
-#endif
-    case 8:
-    {
-      png_imgtype imgtype[]={png_g8,png_none,png_rgb8,png_idx8,png_ga8,
-          png_none,png_rgba8};
-      ret=imgtype[colortype];
-      break;
-    }
-#ifndef MNG_NO_16BIT_SUPPORT
-    case 16:
-    {
-      png_imgtype imgtype[]={png_g16,png_none,png_rgb16,png_none,png_ga16,
-          png_none,png_rgba16};
-      ret=imgtype[colortype];
-      break;
-    }
-#endif
-    default:
-      ret=png_none;
-      break;
-  }
-  return (ret);
-}
-#endif /* MNG_OPTIMIZE_FOOTPRINT_INIT */
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_display_ihdr (mng_datap pData)
-{                                      /* address the current "object" if any */
-  mng_imagep pImage = (mng_imagep)pData->pCurrentobj;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IHDR, MNG_LC_START);
-#endif
-
-  if (!pData->bHasDHDR)
-  {
-    pData->fInitrowproc = MNG_NULL;    /* do nothing by default */
-    pData->fDisplayrow  = MNG_NULL;
-    pData->fCorrectrow  = MNG_NULL;
-    pData->fStorerow    = MNG_NULL;
-    pData->fProcessrow  = MNG_NULL;
-    pData->fDifferrow   = MNG_NULL;
-    pData->pStoreobj    = MNG_NULL;
-  }
-
-  if (!pData->iBreakpoint)             /* not previously broken ? */
-  {
-    mng_retcode iRetcode = MNG_NOERROR;
-
-#ifndef MNG_NO_DELTA_PNG
-    if (pData->bHasDHDR)               /* is a delta-image ? */
-    {
-      if (pData->iDeltatype == MNG_DELTATYPE_REPLACE)
-        iRetcode = mng_reset_object_details (pData, (mng_imagep)pData->pDeltaImage,
-                                             pData->iDatawidth, pData->iDataheight,
-                                             pData->iBitdepth, pData->iColortype,
-                                             pData->iCompression, pData->iFilter,
-                                             pData->iInterlace, MNG_TRUE);
-      else
-      if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD    ) ||
-          (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
-      {
-        ((mng_imagep)pData->pDeltaImage)->pImgbuf->iPixelsampledepth = pData->iBitdepth;
-        ((mng_imagep)pData->pDeltaImage)->pImgbuf->iAlphasampledepth = pData->iBitdepth;
-      }
-      else
-      if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAADD    ) ||
-          (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE)    )
-        ((mng_imagep)pData->pDeltaImage)->pImgbuf->iAlphasampledepth = pData->iBitdepth;
-      else
-      if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORADD    ) ||
-          (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE)    )
-        ((mng_imagep)pData->pDeltaImage)->pImgbuf->iPixelsampledepth = pData->iBitdepth;
-
-      if (!iRetcode)
-      {                                /* process immediately if bitdepth & colortype are equal */
-        pData->bDeltaimmediate =
-          (mng_bool)((pData->iBitdepth  == ((mng_imagep)pData->pDeltaImage)->pImgbuf->iBitdepth ) &&
-                     (pData->iColortype == ((mng_imagep)pData->pDeltaImage)->pImgbuf->iColortype)    );
-                                       /* be sure to reset object 0 */
-        iRetcode = mng_reset_object_details (pData, (mng_imagep)pData->pObjzero,
-                                             pData->iDatawidth, pData->iDataheight,
-                                             pData->iBitdepth, pData->iColortype,
-                                             pData->iCompression, pData->iFilter,
-                                             pData->iInterlace, MNG_TRUE);
-      }
-    }
-    else
-#endif
-    {
-      if (pImage)                      /* update object buffer ? */
-        iRetcode = mng_reset_object_details (pData, pImage,
-                                             pData->iDatawidth, pData->iDataheight,
-                                             pData->iBitdepth, pData->iColortype,
-                                             pData->iCompression, pData->iFilter,
-                                             pData->iInterlace, MNG_TRUE);
-      else
-        iRetcode = mng_reset_object_details (pData, (mng_imagep)pData->pObjzero,
-                                             pData->iDatawidth, pData->iDataheight,
-                                             pData->iBitdepth, pData->iColortype,
-                                             pData->iCompression, pData->iFilter,
-                                             pData->iInterlace, MNG_TRUE);
-    }
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-  }
-
-#ifndef MNG_NO_DELTA_PNG
-  if (!pData->bHasDHDR)
-#endif
-  {
-    if (pImage)                        /* real object ? */
-      pData->pStoreobj = pImage;       /* tell the row routines */
-    else                               /* otherwise use object 0 */
-      pData->pStoreobj = pData->pObjzero;
-
-#if !defined(MNG_INCLUDE_MPNG_PROPOSAL) && !defined(MNG_INCLUDE_ANG_PROPOSAL)
-    if (                               /* display "on-the-fly" ? */
-#ifndef MNG_SKIPCHUNK_MAGN
-         (((mng_imagep)pData->pStoreobj)->iMAGN_MethodX == 0) &&
-         (((mng_imagep)pData->pStoreobj)->iMAGN_MethodY == 0) &&
-#endif
-         ( (pData->eImagetype == mng_it_png         ) ||
-           (((mng_imagep)pData->pStoreobj)->bVisible)    )       )
-    {
-      next_layer (pData);              /* that's a new layer then ! */
-
-      if (pData->bTimerset)            /* timer break ? */
-        pData->iBreakpoint = 2;
-      else
-      {
-        pData->iBreakpoint = 0;
-                                       /* anything to display ? */
-        if ((pData->iDestr > pData->iDestl) && (pData->iDestb > pData->iDestt))
-          set_display_routine (pData); /* then determine display routine */
-      }
-    }
-#endif
-  }
-
-  if (!pData->bTimerset)               /* no timer break ? */
-  {
-#ifdef MNG_OPTIMIZE_FOOTPRINT_INIT
-    pData->fInitrowproc = (mng_fptr)mng_init_rowproc;
-    pData->ePng_imgtype=mng_png_imgtype(pData->iColortype,pData->iBitdepth);
-#else
-    switch (pData->iColortype)         /* determine row initialization routine */
-    {
-      case 0 : {                       /* gray */
-                 switch (pData->iBitdepth)
-                 {
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-                   case  1 : {
-                               if (!pData->iInterlace)
-                                 pData->fInitrowproc = (mng_fptr)mng_init_g1_ni;
-                               else
-                                 pData->fInitrowproc = (mng_fptr)mng_init_g1_i;
-
-                               break;
-                             }
-                   case  2 : {
-                               if (!pData->iInterlace)
-                                 pData->fInitrowproc = (mng_fptr)mng_init_g2_ni;
-                               else
-                                 pData->fInitrowproc = (mng_fptr)mng_init_g2_i;
-
-                               break;
-                             }
-                   case  4 : {
-                               if (!pData->iInterlace)
-                                 pData->fInitrowproc = (mng_fptr)mng_init_g4_ni;
-                               else
-                                 pData->fInitrowproc = (mng_fptr)mng_init_g4_i;
-                               break;
-                             }
-#endif /* MNG_NO_1_2_4BIT_SUPPORT */
-                   case  8 : {
-                               if (!pData->iInterlace)
-                                 pData->fInitrowproc = (mng_fptr)mng_init_g8_ni;
-                               else
-                                 pData->fInitrowproc = (mng_fptr)mng_init_g8_i;
-
-                               break;
-                             }
-#ifndef MNG_NO_16BIT_SUPPORT
-                   case 16 : {
-                               if (!pData->iInterlace)
-                                 pData->fInitrowproc = (mng_fptr)mng_init_g16_ni;
-                               else
-                                 pData->fInitrowproc = (mng_fptr)mng_init_g16_i;
-
-                               break;
-                             }
-#endif
-                 }
-
-                 break;
-               }
-      case 2 : {                       /* rgb */
-                 switch (pData->iBitdepth)
-                 {
-                   case  8 : {
-                               if (!pData->iInterlace)
-                                 pData->fInitrowproc = (mng_fptr)mng_init_rgb8_ni;
-                               else
-                                 pData->fInitrowproc = (mng_fptr)mng_init_rgb8_i;
-                               break;
-                             }
-#ifndef MNG_NO_16BIT_SUPPORT
-                   case 16 : {
-                               if (!pData->iInterlace)
-                                 pData->fInitrowproc = (mng_fptr)mng_init_rgb16_ni;
-                               else
-                                 pData->fInitrowproc = (mng_fptr)mng_init_rgb16_i;
-
-                               break;
-                             }
-#endif
-                 }
-
-                 break;
-               }
-      case 3 : {                       /* indexed */
-                 switch (pData->iBitdepth)
-                 {
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-                   case  1 : {
-                               if (!pData->iInterlace)
-                                 pData->fInitrowproc = (mng_fptr)mng_init_idx1_ni;
-                               else
-                                 pData->fInitrowproc = (mng_fptr)mng_init_idx1_i;
-
-                               break;
-                             }
-                   case  2 : {
-                               if (!pData->iInterlace)
-                                 pData->fInitrowproc = (mng_fptr)mng_init_idx2_ni;
-                               else
-                                 pData->fInitrowproc = (mng_fptr)mng_init_idx2_i;
-
-                               break;
-                             }
-                   case  4 : {
-                               if (!pData->iInterlace)
-                                 pData->fInitrowproc = (mng_fptr)mng_init_idx4_ni;
-                               else
-                                 pData->fInitrowproc = (mng_fptr)mng_init_idx4_i;
-
-                               break;
-                             }
-#endif /* MNG_NO_1_2_4BIT_SUPPORT */
-                   case  8 : {
-                               if (!pData->iInterlace)
-                                 pData->fInitrowproc = (mng_fptr)mng_init_idx8_ni;
-                               else
-                                 pData->fInitrowproc = (mng_fptr)mng_init_idx8_i;
-
-                               break;
-                             }
-                 }
-
-                 break;
-               }
-      case 4 : {                       /* gray+alpha */
-                 switch (pData->iBitdepth)
-                 {
-                   case  8 : {
-                               if (!pData->iInterlace)
-                                 pData->fInitrowproc = (mng_fptr)mng_init_ga8_ni;
-                               else
-                                 pData->fInitrowproc = (mng_fptr)mng_init_ga8_i;
-
-                               break;
-                             }
-#ifndef MNG_NO_16BIT_SUPPORT
-                   case 16 : {
-                               if (!pData->iInterlace)
-                                 pData->fInitrowproc = (mng_fptr)mng_init_ga16_ni;
-                               else
-                                 pData->fInitrowproc = (mng_fptr)mng_init_ga16_i;
-                               break;
-                             }
-#endif
-                 }
-
-                 break;
-               }
-      case 6 : {                       /* rgb+alpha */
-                 switch (pData->iBitdepth)
-                 {
-                   case  8 : {
-                               if (!pData->iInterlace)
-                                 pData->fInitrowproc = (mng_fptr)mng_init_rgba8_ni;
-                               else
-                                 pData->fInitrowproc = (mng_fptr)mng_init_rgba8_i;
-
-                               break;
-                             }
-#ifndef MNG_NO_16BIT_SUPPORT
-                   case 16 : {
-                               if (!pData->iInterlace)
-                                 pData->fInitrowproc = (mng_fptr)mng_init_rgba16_ni;
-                               else
-                                 pData->fInitrowproc = (mng_fptr)mng_init_rgba16_i;
-
-                               break;
-                             }
-#endif
-                 }
-
-                 break;
-               }
-    }
-#endif /* MNG_OPTIMIZE_FOOTPRINT_INIT */
-
-    pData->iFilterofs = 0;             /* determine filter characteristics */
-    pData->iLevel0    = 0;             /* default levels */
-    pData->iLevel1    = 0;    
-    pData->iLevel2    = 0;
-    pData->iLevel3    = 0;
-
-#ifdef FILTER192                       /* leveling & differing ? */
-    if (pData->iFilter == MNG_FILTER_DIFFERING)
-    {
-      switch (pData->iColortype)
-      {
-        case 0 : {
-                   if (pData->iBitdepth <= 8)
-                     pData->iFilterofs = 1;
-                   else
-                     pData->iFilterofs = 2;
-
-                   break;
-                 }
-        case 2 : {
-                   if (pData->iBitdepth <= 8)
-                     pData->iFilterofs = 3;
-                   else
-                     pData->iFilterofs = 6;
-
-                   break;
-                 }
-        case 3 : {
-                   pData->iFilterofs = 1;
-                   break;
-                 }
-        case 4 : {
-                   if (pData->iBitdepth <= 8)
-                     pData->iFilterofs = 2;
-                   else
-                     pData->iFilterofs = 4;
-
-                   break;
-                 }
-        case 6 : {
-                   if (pData->iBitdepth <= 8)
-                     pData->iFilterofs = 4;
-                   else
-                     pData->iFilterofs = 8;
-
-                   break;
-                 }
-      }
-    }
-#endif
-
-#ifdef FILTER193                       /* no adaptive filtering ? */
-    if (pData->iFilter == MNG_FILTER_NOFILTER)
-      pData->iPixelofs = pData->iFilterofs;
-    else
-#endif    
-      pData->iPixelofs = pData->iFilterofs + 1;
-
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IHDR, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-mng_retcode mng_process_display_mpng (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MPNG, MNG_LC_START);
-#endif
-
-  pData->iAlphadepth = 8;              /* assume transparency !! */
-
-  if (pData->fProcessheader)           /* inform the app (creating the output canvas) ? */
-  {
-    pData->iWidth  = ((mng_mpng_objp)pData->pMPNG)->iFramewidth;
-    pData->iHeight = ((mng_mpng_objp)pData->pMPNG)->iFrameheight;
-
-    if (!pData->fProcessheader (((mng_handle)pData), pData->iWidth, pData->iHeight))
-      MNG_ERROR (pData, MNG_APPMISCERROR);
-  }
-
-  next_layer (pData);                  /* first mPNG layer then ! */
-  pData->bTimerset   = MNG_FALSE;
-  pData->iBreakpoint = 0;
-
-  if ((pData->iDestr > pData->iDestl) && (pData->iDestb > pData->iDestt))
-    set_display_routine (pData);       /* then determine display routine */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MPNG, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_ANG_PROPOSAL
-mng_retcode mng_process_display_ang (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_ANG, MNG_LC_START);
-#endif
-
-  if (pData->fProcessheader)           /* inform the app (creating the output canvas) ? */
-  {
-    if (!pData->fProcessheader (((mng_handle)pData), pData->iWidth, pData->iHeight))
-      MNG_ERROR (pData, MNG_APPMISCERROR);
-  }
-
-  next_layer (pData);                  /* first mPNG layer then ! */
-  pData->bTimerset   = MNG_FALSE;
-  pData->iBreakpoint = 0;
-
-  if ((pData->iDestr > pData->iDestl) && (pData->iDestb > pData->iDestt))
-    set_display_routine (pData);       /* then determine display routine */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_ANG, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-mng_retcode mng_process_display_idat (mng_datap  pData,
-                                      mng_uint32 iRawlen,
-                                      mng_uint8p pRawdata)
-#else
-mng_retcode mng_process_display_idat (mng_datap  pData)
-#endif
-{
-  mng_retcode iRetcode = MNG_NOERROR;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IDAT, MNG_LC_START);
-#endif
-
-#if defined(MNG_INCLUDE_MPNG_PROPOSAL) || defined(MNG_INCLUDE_ANG_PROPOSAL) 
-  if ((pData->eImagetype == mng_it_png) && (pData->iLayerseq <= 0))
-  {
-    if (pData->fProcessheader)         /* inform the app (creating the output canvas) ? */
-      if (!pData->fProcessheader (((mng_handle)pData), pData->iWidth, pData->iHeight))
-        MNG_ERROR (pData, MNG_APPMISCERROR);
-
-    next_layer (pData);                /* first regular PNG layer then ! */
-    pData->bTimerset   = MNG_FALSE;
-    pData->iBreakpoint = 0;
-
-    if ((pData->iDestr > pData->iDestl) && (pData->iDestb > pData->iDestt))
-      set_display_routine (pData);     /* then determine display routine */
-  }
-#endif
-
-  if (pData->bRestorebkgd)             /* need to restore the background ? */
-  {
-    pData->bRestorebkgd = MNG_FALSE;
-    iRetcode            = load_bkgdlayer (pData);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-
-    pData->iLayerseq++;                /* and it counts as a layer then ! */
-  }
-
-  if (pData->fInitrowproc)             /* need to initialize row processing? */
-  {
-    iRetcode = ((mng_initrowproc)pData->fInitrowproc) (pData);
-    pData->fInitrowproc = MNG_NULL;    /* only call this once !!! */
-  }
-
-  if ((!iRetcode) && (!pData->bInflating))
-                                       /* initialize inflate */
-    iRetcode = mngzlib_inflateinit (pData);
-
-  if (!iRetcode)                       /* all ok? then inflate, my man */
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-    iRetcode = mngzlib_inflaterows (pData, iRawlen, pRawdata);
-#else
-    iRetcode = mngzlib_inflaterows (pData, pData->iRawlen, pData->pRawdata);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-    
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IDAT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_display_iend (mng_datap pData)
-{
-  mng_retcode iRetcode, iRetcode2;
-  mng_bool bDodisplay = MNG_FALSE;
-  mng_bool bMagnify   = MNG_FALSE;
-  mng_bool bCleanup   = (mng_bool)(pData->iBreakpoint != 0);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IEND, MNG_LC_START);
-#endif
-
-#ifdef MNG_INCLUDE_JNG                 /* progressive+alpha JNG can be displayed now */
-  if ( (pData->bHasJHDR                                         ) &&
-       ( (pData->bJPEGprogressive) || (pData->bJPEGprogressive2)) &&
-       ( (pData->eImagetype == mng_it_jng         ) ||
-         (((mng_imagep)pData->pStoreobj)->bVisible)             ) &&
-       ( (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA ) ||
-         (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA)    )    )
-    bDodisplay = MNG_TRUE;
-#endif
-
-#ifndef MNG_SKIPCHUNK_MAGN
-  if ( (pData->pStoreobj) &&           /* on-the-fly magnification ? */
-       ( (((mng_imagep)pData->pStoreobj)->iMAGN_MethodX) ||
-         (((mng_imagep)pData->pStoreobj)->iMAGN_MethodY)    ) )
-    bMagnify = MNG_TRUE;
-#endif
-
-  if ((pData->bHasBASI) ||             /* was it a BASI stream */
-      (bDodisplay)      ||             /* or should we display the JNG */
-#ifndef MNG_SKIPCHUNK_MAGN
-      (bMagnify)        ||             /* or should we magnify it */
-#endif
-                                       /* or did we get broken here last time ? */
-      ((pData->iBreakpoint) && (pData->iBreakpoint != 8)))
-  {
-    mng_imagep pImage = (mng_imagep)pData->pCurrentobj;
-
-    if (!pImage)                       /* or was it object 0 ? */
-      pImage = (mng_imagep)pData->pObjzero;
-                                       /* display it now then ? */
-    if ((pImage->bVisible) && (pImage->bViewable))
-    {                                  /* ok, so do it */
-      iRetcode = mng_display_image (pData, pImage, bDodisplay);
-
-      if (iRetcode)                    /* on error bail out */
-        return iRetcode;
-
-      if (pData->bTimerset)            /* timer break ? */
-        pData->iBreakpoint = 6;
-    }
-  }
-#ifndef MNG_NO_DELTA_PNG
-  else
-  if ((pData->bHasDHDR) ||             /* was it a DHDR stream */
-      (pData->iBreakpoint == 8))       /* or did we get broken here last time ? */
-  {
-    mng_imagep pImage = (mng_imagep)pData->pDeltaImage;
-
-    if (!pData->iBreakpoint)
-    {                                  /* perform the delta operations needed */
-      iRetcode = mng_execute_delta_image (pData, pImage, (mng_imagep)pData->pObjzero);
-
-      if (iRetcode)                    /* on error bail out */
-        return iRetcode;
-    }
-                                       /* display it now then ? */
-    if ((pImage->bVisible) && (pImage->bViewable))
-    {                                  /* ok, so do it */
-      iRetcode = mng_display_image (pData, pImage, MNG_FALSE);
-
-      if (iRetcode)                    /* on error bail out */
-        return iRetcode;
-
-      if (pData->bTimerset)            /* timer break ? */
-        pData->iBreakpoint = 8;
-    }
-  }
-#endif
-
-  if (!pData->bTimerset)               /* can we continue ? */
-  {
-    pData->iBreakpoint = 0;            /* clear this flag now ! */
-
-
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-    if (pData->eImagetype == mng_it_mpng)
-    {
-      pData->pCurraniobj = pData->pFirstaniobj;
-    } else
-#endif
-#ifdef MNG_INCLUDE_ANG_PROPOSAL
-    if (pData->eImagetype == mng_it_ang)
-    {
-      pData->pCurraniobj = pData->pFirstaniobj;
-    } else
-#endif
-    {                                  /* cleanup object 0 */
-      mng_reset_object_details (pData, (mng_imagep)pData->pObjzero,
-                                0, 0, 0, 0, 0, 0, 0, MNG_TRUE);
-    }
-
-    if (pData->bInflating)             /* if we've been inflating */
-    {                                  /* cleanup row-processing, */
-      iRetcode  = mng_cleanup_rowproc (pData);
-                                       /* also cleanup inflate! */
-      iRetcode2 = mngzlib_inflatefree (pData);
-
-      if (iRetcode)                    /* on error bail out */
-        return iRetcode;
-      if (iRetcode2)
-        return iRetcode2;
-    }
-
-#ifdef MNG_INCLUDE_JNG
-    if (pData->bJPEGdecompress)        /* if we've been decompressing JDAT */
-    {                                  /* cleanup row-processing, */
-      iRetcode  = mng_cleanup_rowproc (pData);
-                                       /* also cleanup decompress! */
-      iRetcode2 = mngjpeg_decompressfree (pData);
-
-      if (iRetcode)                    /* on error bail out */
-        return iRetcode;
-      if (iRetcode2)
-        return iRetcode2;
-    }
-
-    if (pData->bJPEGdecompress2)       /* if we've been decompressing JDAA */
-    {                                  /* cleanup row-processing, */
-      iRetcode  = mng_cleanup_rowproc (pData);
-                                       /* also cleanup decompress! */
-      iRetcode2 = mngjpeg_decompressfree2 (pData);
-
-      if (iRetcode)                    /* on error bail out */
-        return iRetcode;
-      if (iRetcode2)
-        return iRetcode2;
-    }
-#endif
-
-    if (bCleanup)                      /* if we got broken last time we need to cleanup */
-    {
-      pData->bHasIHDR = MNG_FALSE;     /* IEND signals the end for most ... */
-      pData->bHasBASI = MNG_FALSE;
-      pData->bHasDHDR = MNG_FALSE;
-#ifdef MNG_INCLUDE_JNG
-      pData->bHasJHDR = MNG_FALSE;
-      pData->bHasJSEP = MNG_FALSE;
-      pData->bHasJDAA = MNG_FALSE;
-      pData->bHasJDAT = MNG_FALSE;
-#endif
-      pData->bHasPLTE = MNG_FALSE;
-      pData->bHasTRNS = MNG_FALSE;
-      pData->bHasGAMA = MNG_FALSE;
-      pData->bHasCHRM = MNG_FALSE;
-      pData->bHasSRGB = MNG_FALSE;
-      pData->bHasICCP = MNG_FALSE;
-      pData->bHasBKGD = MNG_FALSE;
-      pData->bHasIDAT = MNG_FALSE;
-    }
-                                       /* if the image was displayed on the fly, */
-                                       /* we'll have to make the app refresh */
-    if ((pData->eImagetype != mng_it_mng) && (pData->fDisplayrow))
-      pData->bNeedrefresh = MNG_TRUE;
-     
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IEND, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-/* change in the MNG spec with regards to TERM delay & interframe_delay
-   as proposed by Adam M. Costello (option 4) and finalized by official vote
-   during december 2002 / check the 'mng-list' archives for more details */
-
-mng_retcode mng_process_display_mend (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MEND, MNG_LC_START);
-#endif
-
-#ifdef MNG_SUPPORT_DYNAMICMNG
-  if (pData->bStopafterseek)           /* need to stop after this ? */
-  {
-    pData->bFreezing      = MNG_TRUE;  /* stop processing on this one */
-    pData->bRunningevent  = MNG_FALSE;
-    pData->bStopafterseek = MNG_FALSE;
-    pData->bNeedrefresh   = MNG_TRUE;  /* make sure the last bit is displayed ! */
-  }
-#endif
-
-#ifndef MNG_SKIPCHUNK_TERM
-                                       /* TERM processed ? */
-  if ((pData->bDisplaying) && (pData->bRunning) &&
-      (pData->bHasTERM) && (pData->pTermaniobj))
-  {
-    mng_retcode   iRetcode;
-    mng_ani_termp pTERM;
-                                       /* get the right animation object ! */
-    pTERM = (mng_ani_termp)pData->pTermaniobj;
-
-    pData->iIterations++;              /* increase iteration count */
-
-    switch (pTERM->iTermaction)        /* determine what to do! */
-    {
-      case 0 : {                       /* show last frame indefinitly */
-                 break;                /* piece of cake, that is... */
-               }
-
-      case 1 : {                       /* cease displaying anything */
-                                       /* max(1, TERM delay, interframe_delay) */
-#ifndef MNG_SKIPCHUNK_FRAM
-                 if (pTERM->iDelay > pData->iFramedelay)
-                   pData->iFramedelay = pTERM->iDelay;
-                 if (!pData->iFramedelay)
-                   pData->iFramedelay = 1;
-#endif
-
-                 iRetcode = interframe_delay (pData);
-                                       /* no interframe_delay? then fake it */
-                 if ((!iRetcode) && (!pData->bTimerset))
-                   iRetcode = set_delay (pData, 1);
-
-                 if (iRetcode)
-                   return iRetcode;
-
-                 pData->iBreakpoint = 10;
-                 break;
-               }
-
-      case 2 : {                       /* show first image after TERM */
-                 iRetcode = restore_state (pData);
-
-                 if (iRetcode)         /* on error bail out */
-                   return iRetcode;
-                                       /* notify the app ? */
-                 if (pData->fProcessmend)
-                   if (!pData->fProcessmend ((mng_handle)pData, pData->iIterations, 0))
-                     MNG_ERROR (pData, MNG_APPMISCERROR);
-
-                                       /* show first frame after TERM chunk */
-                 pData->pCurraniobj      = pTERM;
-                 pData->bOnlyfirstframe  = MNG_TRUE;
-                 pData->iFramesafterTERM = 0;
-
-                                       /* max(1, TERM delay, interframe_delay) */
-#ifndef MNG_SKIPCHUNK_FRAM
-                 if (pTERM->iDelay > pData->iFramedelay)
-                   pData->iFramedelay = pTERM->iDelay;
-                 if (!pData->iFramedelay)
-                   pData->iFramedelay = 1;
-#endif
-
-                 break;
-               }
-
-      case 3 : {                       /* repeat */
-                 if ((pTERM->iItermax) && (pTERM->iItermax < 0x7FFFFFFF))
-                   pTERM->iItermax--;
-
-                 if (pTERM->iItermax)  /* go back to TERM ? */
-                 {                     /* restore to initial or SAVE state */
-                   iRetcode = restore_state (pData);
-
-                   if (iRetcode)       /* on error bail out */
-                     return iRetcode;
-                                       /* notify the app ? */
-                   if (pData->fProcessmend)
-                     if (!pData->fProcessmend ((mng_handle)pData,
-                                               pData->iIterations, pTERM->iItermax))
-                       MNG_ERROR (pData, MNG_APPMISCERROR);
-
-                                       /* restart from TERM chunk */
-                   pData->pCurraniobj = pTERM;
-
-                   if (pTERM->iDelay)  /* set the delay (?) */
-                   {
-                                       /* max(1, TERM delay, interframe_delay) */
-#ifndef MNG_SKIPCHUNK_FRAM
-                     if (pTERM->iDelay > pData->iFramedelay)
-                       pData->iFramedelay = pTERM->iDelay;
-                     if (!pData->iFramedelay)
-                       pData->iFramedelay = 1;
-#endif
-
-                     pData->bNeedrefresh = MNG_TRUE;
-                   }
-                 }
-                 else
-                 {
-                   switch (pTERM->iIteraction)
-                   {
-                     case 0 : {        /* show last frame indefinitly */
-                                break; /* piece of cake, that is... */
-                              }
-
-                     case 1 : {        /* cease displaying anything */
-                                       /* max(1, TERM delay, interframe_delay) */
-#ifndef MNG_SKIPCHUNK_FRAM
-                                if (pTERM->iDelay > pData->iFramedelay)
-                                  pData->iFramedelay = pTERM->iDelay;
-                                if (!pData->iFramedelay)
-                                  pData->iFramedelay = 1;
-#endif
-
-                                iRetcode = interframe_delay (pData);
-                                       /* no interframe_delay? then fake it */
-                                if ((!iRetcode) && (!pData->bTimerset))
-                                  iRetcode = set_delay (pData, 1);
-
-                                if (iRetcode)
-                                  return iRetcode;
-
-                                pData->iBreakpoint = 10;
-                                break;
-                              }
-
-                     case 2 : {        /* show first image after TERM */
-                                iRetcode = restore_state (pData);
-                                       /* on error bail out */
-                                if (iRetcode)
-                                  return iRetcode;
-                                       /* notify the app ? */
-                                if (pData->fProcessmend)
-                                  if (!pData->fProcessmend ((mng_handle)pData,
-                                                            pData->iIterations, 0))
-                                    MNG_ERROR (pData, MNG_APPMISCERROR);
-
-                                       /* show first frame after TERM chunk */
-                                pData->pCurraniobj      = pTERM;
-                                pData->bOnlyfirstframe  = MNG_TRUE;
-                                pData->iFramesafterTERM = 0;
-                                       /* max(1, TERM delay, interframe_delay) */
-#ifndef MNG_SKIPCHUNK_FRAM
-                                if (pTERM->iDelay > pData->iFramedelay)
-                                  pData->iFramedelay = pTERM->iDelay;
-                                if (!pData->iFramedelay)
-                                  pData->iFramedelay = 1;
-#endif
-
-                                break;
-                              }
-                   }
-                 }
-
-                 break;
-               }
-    }
-  }
-#endif /* MNG_SKIPCHUNK_TERM */
-                                       /* just reading ? */
-  if ((!pData->bDisplaying) && (pData->bReading))
-    if (pData->fProcessmend)           /* inform the app ? */
-      if (!pData->fProcessmend ((mng_handle)pData, 0, 0))
-        MNG_ERROR (pData, MNG_APPMISCERROR);
-
-  if (!pData->pCurraniobj)             /* always let the app refresh at the end ! */
-    pData->bNeedrefresh = MNG_TRUE;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MEND, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_display_mend2 (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MEND, MNG_LC_START);
-#endif
-
-#ifndef MNG_SKIPCHUNK_FRAM
-  pData->bFrameclipping = MNG_FALSE;   /* nothing to do but restore the app background */
-#endif
-  load_bkgdlayer (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MEND, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_DEFI
-mng_retcode mng_process_display_defi (mng_datap pData)
-{
-  mng_imagep pImage;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_DEFI, MNG_LC_START);
-#endif
-
-  if (!pData->iDEFIobjectid)           /* object id=0 ? */
-  {
-    pImage             = (mng_imagep)pData->pObjzero;
-
-    if (pData->bDEFIhasdonotshow)
-      pImage->bVisible = (mng_bool)(pData->iDEFIdonotshow == 0);
-
-    if (pData->bDEFIhasloca)
-    {
-      pImage->iPosx    = pData->iDEFIlocax;
-      pImage->iPosy    = pData->iDEFIlocay;
-    }
-
-    if (pData->bDEFIhasclip)
-    {
-      pImage->bClipped = pData->bDEFIhasclip;
-      pImage->iClipl   = pData->iDEFIclipl;
-      pImage->iClipr   = pData->iDEFIclipr;
-      pImage->iClipt   = pData->iDEFIclipt;
-      pImage->iClipb   = pData->iDEFIclipb;
-    }
-
-    pData->pCurrentobj = 0;            /* not a real object ! */
-  }
-  else
-  {                                    /* already exists ? */
-    pImage = (mng_imagep)mng_find_imageobject (pData, pData->iDEFIobjectid);
-
-    if (!pImage)                       /* if not; create new */
-    {
-      mng_retcode iRetcode = mng_create_imageobject (pData, pData->iDEFIobjectid,
-                                                     (mng_bool)(pData->iDEFIconcrete == 1),
-                                                     (mng_bool)(pData->iDEFIdonotshow == 0),
-                                                     MNG_FALSE, 0, 0, 0, 0, 0, 0, 0,
-                                                     pData->iDEFIlocax, pData->iDEFIlocay,
-                                                     pData->bDEFIhasclip,
-                                                     pData->iDEFIclipl, pData->iDEFIclipr,
-                                                     pData->iDEFIclipt, pData->iDEFIclipb,
-                                                     &pImage);
-
-      if (iRetcode)                    /* on error bail out */
-        return iRetcode;
-    }
-    else
-    {                                  /* exists; then set new info */
-      if (pData->bDEFIhasdonotshow)
-        pImage->bVisible = (mng_bool)(pData->iDEFIdonotshow == 0);
-
-      pImage->bViewable  = MNG_FALSE;
-
-      if (pData->bDEFIhasloca)
-      {
-        pImage->iPosx    = pData->iDEFIlocax;
-        pImage->iPosy    = pData->iDEFIlocay;
-      }
-
-      if (pData->bDEFIhasclip)
-      {
-        pImage->bClipped = pData->bDEFIhasclip;
-        pImage->iClipl   = pData->iDEFIclipl;
-        pImage->iClipr   = pData->iDEFIclipr;
-        pImage->iClipt   = pData->iDEFIclipt;
-        pImage->iClipb   = pData->iDEFIclipb;
-      }
-
-      if (pData->bDEFIhasconcrete)
-        pImage->pImgbuf->bConcrete = (mng_bool)(pData->iDEFIconcrete == 1);
-    }
-
-    pData->pCurrentobj = pImage;       /* others may want to know this */
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_DEFI, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_BASI
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-mng_retcode mng_process_display_basi (mng_datap  pData,
-                                      mng_uint16 iRed,
-                                      mng_uint16 iGreen,
-                                      mng_uint16 iBlue,
-                                      mng_bool   bHasalpha,
-                                      mng_uint16 iAlpha,
-                                      mng_uint8  iViewable)
-#else
-mng_retcode mng_process_display_basi (mng_datap  pData)
-#endif
-{                                      /* address the current "object" if any */
-  mng_imagep     pImage = (mng_imagep)pData->pCurrentobj;
-  mng_uint8p     pWork;
-  mng_uint32     iX;
-  mng_imagedatap pBuf;
-  mng_retcode    iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_BASI, MNG_LC_START);
-#endif
-
-  if (!pImage)                         /* or is it an "on-the-fly" image ? */
-    pImage = (mng_imagep)pData->pObjzero;
-                                       /* address the object-buffer */
-  pBuf               = pImage->pImgbuf;
-
-  pData->fDisplayrow = MNG_NULL;       /* do nothing by default */
-  pData->fCorrectrow = MNG_NULL;
-  pData->fStorerow   = MNG_NULL;
-  pData->fProcessrow = MNG_NULL;
-                                       /* set parms now that they're known */
-  iRetcode = mng_reset_object_details (pData, pImage, pData->iDatawidth,
-                                       pData->iDataheight, pData->iBitdepth,
-                                       pData->iColortype, pData->iCompression,
-                                       pData->iFilter, pData->iInterlace, MNG_FALSE);
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-                                       /* save the viewable flag */
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-  pImage->bViewable = (mng_bool)(iViewable == 1);
-#else
-  pImage->bViewable = (mng_bool)(pData->iBASIviewable == 1);
-#endif
-  pBuf->bViewable   = pImage->bViewable;
-  pData->pStoreobj  = pImage;          /* let row-routines know which object */
-
-  pWork = pBuf->pImgdata;              /* fill the object-buffer with the specified
-                                          "color" sample */
-  switch (pData->iColortype)           /* depending on color_type & bit_depth */
-  {
-    case 0 : {                         /* gray */
-#ifndef MNG_NO_16BIT_SUPPORT
-               if (pData->iBitdepth == 16)
-               {
-#ifdef MNG_DECREMENT_LOOPS
-                 for (iX = pData->iDatawidth * pData->iDataheight;
-                    iX > 0;iX--)
-#else
-                 for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
-#endif
-                 {
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-                   mng_put_uint16 (pWork, iRed);
-#else
-                   mng_put_uint16 (pWork, pData->iBASIred);
-#endif
-                   pWork += 2;
-                 }
-               }
-               else
-#endif
-               {
-#ifdef MNG_DECREMENT_LOOPS
-                 for (iX = pData->iDatawidth * pData->iDataheight;
-                    iX > 0;iX--)
-#else
-                 for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
-#endif
-                 {
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-                   *pWork = (mng_uint8)iRed;
-#else
-                   *pWork = (mng_uint8)pData->iBASIred;
-#endif
-                   pWork++;
-                 }
-               }
-                                       /* force tRNS ? */
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-               if ((bHasalpha) && (!iAlpha))
-#else
-               if ((pData->bBASIhasalpha) && (!pData->iBASIalpha))
-#endif
-               {
-                 pBuf->bHasTRNS  = MNG_TRUE;
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-                 pBuf->iTRNSgray = iRed;
-#else
-                 pBuf->iTRNSgray = pData->iBASIred;
-#endif
-               }
-
-               break;
-             }
-
-    case 2 : {                         /* rgb */
-#ifndef MNG_NO_16BIT_SUPPORT
-               if (pData->iBitdepth == 16)
-               {
-#ifdef MNG_DECREMENT_LOOPS
-                 for (iX = pData->iDatawidth * pData->iDataheight;
-                    iX > 0;iX--)
-#else
-                 for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
-#endif
-                 {
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-                   mng_put_uint16 (pWork,   iRed  );
-                   mng_put_uint16 (pWork+2, iGreen);
-                   mng_put_uint16 (pWork+4, iBlue );
-#else
-                   mng_put_uint16 (pWork,   pData->iBASIred  );
-                   mng_put_uint16 (pWork+2, pData->iBASIgreen);
-                   mng_put_uint16 (pWork+4, pData->iBASIblue );
-#endif
-                   pWork += 6;
-                 }
-               }
-               else
-#endif
-               {
-#ifdef MNG_DECREMENT_LOOPS
-                 for (iX = pData->iDatawidth * pData->iDataheight;
-                    iX > 0;iX--)
-#else
-                 for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
-#endif
-                 {
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-                   *pWork     = (mng_uint8)iRed;
-                   *(pWork+1) = (mng_uint8)iGreen;
-                   *(pWork+2) = (mng_uint8)iBlue;
-#else
-                   *pWork     = (mng_uint8)pData->iBASIred;
-                   *(pWork+1) = (mng_uint8)pData->iBASIgreen;
-                   *(pWork+2) = (mng_uint8)pData->iBASIblue;
-#endif
-                   pWork += 3;
-                 }
-               }
-                                       /* force tRNS ? */
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-               if ((bHasalpha) && (!iAlpha))
-#else
-               if ((pData->bBASIhasalpha) && (!pData->iBASIalpha))
-#endif
-               {
-                 pBuf->bHasTRNS   = MNG_TRUE;
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-                 pBuf->iTRNSred   = iRed;
-                 pBuf->iTRNSgreen = iGreen;
-                 pBuf->iTRNSblue  = iBlue;
-#else
-                 pBuf->iTRNSred   = pData->iBASIred;
-                 pBuf->iTRNSgreen = pData->iBASIgreen;
-                 pBuf->iTRNSblue  = pData->iBASIblue;
-#endif
-               }
-
-               break;
-             }
-
-    case 3 : {                         /* indexed */
-               pBuf->bHasPLTE = MNG_TRUE;
-
-               switch (pData->iBitdepth)
-               {
-                 case 1  : { pBuf->iPLTEcount =   2; break; }
-                 case 2  : { pBuf->iPLTEcount =   4; break; }
-                 case 4  : { pBuf->iPLTEcount =  16; break; }
-                 case 8  : { pBuf->iPLTEcount = 256; break; }
-                 default : { pBuf->iPLTEcount =   1; break; }
-               }
-
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-               pBuf->aPLTEentries [0].iRed   = (mng_uint8)iRed;
-               pBuf->aPLTEentries [0].iGreen = (mng_uint8)iGreen;
-               pBuf->aPLTEentries [0].iBlue  = (mng_uint8)iBlue;
-#else
-               pBuf->aPLTEentries [0].iRed   = (mng_uint8)pData->iBASIred;
-               pBuf->aPLTEentries [0].iGreen = (mng_uint8)pData->iBASIgreen;
-               pBuf->aPLTEentries [0].iBlue  = (mng_uint8)pData->iBASIblue;
-#endif
-
-               for (iX = 1; iX < pBuf->iPLTEcount; iX++)
-               {
-                 pBuf->aPLTEentries [iX].iRed   = 0;
-                 pBuf->aPLTEentries [iX].iGreen = 0;
-                 pBuf->aPLTEentries [iX].iBlue  = 0;
-               }
-                                       /* force tRNS ? */
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-               if ((bHasalpha) && (iAlpha < 255))
-#else
-               if ((pData->bBASIhasalpha) && (pData->iBASIalpha < 255))
-#endif
-               {
-                 pBuf->bHasTRNS         = MNG_TRUE;
-                 pBuf->iTRNScount       = 1;
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-                 pBuf->aTRNSentries [0] = (mng_uint8)iAlpha;
-#else
-                 pBuf->aTRNSentries [0] = (mng_uint8)pData->iBASIalpha;
-#endif
-               }
-
-               break;
-             }
-
-    case 4 : {                         /* gray+alpha */
-#ifndef MNG_NO_16BIT_SUPPORT
-               if (pData->iBitdepth == 16)
-               {
-#ifdef MNG_DECREMENT_LOOPS
-                 for (iX = pData->iDatawidth * pData->iDataheight;
-                    iX > 0;iX--)
-#else
-                 for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
-#endif
-                 {
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-                   mng_put_uint16 (pWork,   iRed);
-                   mng_put_uint16 (pWork+2, iAlpha);
-#else
-                   mng_put_uint16 (pWork,   pData->iBASIred);
-                   mng_put_uint16 (pWork+2, pData->iBASIalpha);
-#endif
-                   pWork += 4;
-                 }
-               }
-               else
-#endif
-               {
-#ifdef MNG_DECREMENT_LOOPS
-                 for (iX = pData->iDatawidth * pData->iDataheight;
-                    iX > 0;iX--)
-#else
-                 for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
-#endif
-                 {
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-                   *pWork     = (mng_uint8)iRed;
-                   *(pWork+1) = (mng_uint8)iAlpha;
-#else
-                   *pWork     = (mng_uint8)pData->iBASIred;
-                   *(pWork+1) = (mng_uint8)pData->iBASIalpha;
-#endif
-                   pWork += 2;
-                 }
-               }
-
-               break;
-             }
-
-    case 6 : {                         /* rgb+alpha */
-#ifndef MNG_NO_16BIT_SUPPORT
-               if (pData->iBitdepth == 16)
-               {
-#ifdef MNG_DECREMENT_LOOPS
-                 for (iX = pData->iDatawidth * pData->iDataheight;
-                    iX > 0;iX--)
-#else
-                 for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
-#endif
-                 {
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-                   mng_put_uint16 (pWork,   iRed);
-                   mng_put_uint16 (pWork+2, iGreen);
-                   mng_put_uint16 (pWork+4, iBlue);
-                   mng_put_uint16 (pWork+6, iAlpha);
-#else
-                   mng_put_uint16 (pWork,   pData->iBASIred);
-                   mng_put_uint16 (pWork+2, pData->iBASIgreen);
-                   mng_put_uint16 (pWork+4, pData->iBASIblue);
-                   mng_put_uint16 (pWork+6, pData->iBASIalpha);
-#endif
-                   pWork += 8;
-                 }
-               }
-               else
-#endif
-               {
-#ifdef MNG_DECREMENT_LOOPS
-                 for (iX = pData->iDatawidth * pData->iDataheight;
-                    iX > 0;iX--)
-#else
-                 for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
-#endif
-                 {
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-                   *pWork     = (mng_uint8)iRed;
-                   *(pWork+1) = (mng_uint8)iGreen;
-                   *(pWork+2) = (mng_uint8)iBlue;
-                   *(pWork+3) = (mng_uint8)iAlpha;
-#else
-                   *pWork     = (mng_uint8)pData->iBASIred;
-                   *(pWork+1) = (mng_uint8)pData->iBASIgreen;
-                   *(pWork+2) = (mng_uint8)pData->iBASIblue;
-                   *(pWork+3) = (mng_uint8)pData->iBASIalpha;
-#endif
-                   pWork += 4;
-                 }
-               }
-
-               break;
-             }
-
-  }
-
-#ifdef MNG_OPTIMIZE_FOOTPRINT_INIT
-  pData->fInitrowproc = (mng_fptr)mng_init_rowproc;
-  pData->ePng_imgtype=mng_png_imgtype(pData->iColortype,pData->iBitdepth);
-#else
-  switch (pData->iColortype)           /* determine row initialization routine */
-  {                                    /* just to accomodate IDAT if it arrives */
-    case 0 : {                         /* gray */
-               switch (pData->iBitdepth)
-               {
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-                 case  1 : {
-                             if (!pData->iInterlace)
-                               pData->fInitrowproc = (mng_fptr)mng_init_g1_ni;
-                             else
-                               pData->fInitrowproc = (mng_fptr)mng_init_g1_i;
-
-                             break;
-                           }
-                 case  2 : {
-                             if (!pData->iInterlace)
-                               pData->fInitrowproc = (mng_fptr)mng_init_g2_ni;
-                             else
-                               pData->fInitrowproc = (mng_fptr)mng_init_g2_i;
-
-                             break;
-                           }
-                 case  4 : {
-                             if (!pData->iInterlace)
-                               pData->fInitrowproc = (mng_fptr)mng_init_g4_ni;
-                             else
-                               pData->fInitrowproc = (mng_fptr)mng_init_g4_i;
-
-                             break;
-                           }
-#endif /* MNG_NO_1_2_4BIT_SUPPORT */
-                 case  8 : {
-                             if (!pData->iInterlace)
-                               pData->fInitrowproc = (mng_fptr)mng_init_g8_ni;
-                             else
-                               pData->fInitrowproc = (mng_fptr)mng_init_g8_i;
-
-                             break;
-                           }
-#ifndef MNG_NO_16BIT_SUPPORT
-                 case 16 : {
-                             if (!pData->iInterlace)
-                               pData->fInitrowproc = (mng_fptr)mng_init_g16_ni;
-                             else
-                               pData->fInitrowproc = (mng_fptr)mng_init_g16_i;
-
-                             break;
-                           }
-#endif
-               }
-
-               break;
-             }
-    case 2 : {                         /* rgb */
-               switch (pData->iBitdepth)
-               {
-                 case  8 : {
-                             if (!pData->iInterlace)
-                               pData->fInitrowproc = (mng_fptr)mng_init_rgb8_ni;
-                             else
-                               pData->fInitrowproc = (mng_fptr)mng_init_rgb8_i;
-
-                             break;
-                           }
-#ifndef MNG_NO_16BIT_SUPPORT
-                 case 16 : {
-                             if (!pData->iInterlace)
-                               pData->fInitrowproc = (mng_fptr)mng_init_rgb16_ni;
-                             else
-                               pData->fInitrowproc = (mng_fptr)mng_init_rgb16_i;
-
-                             break;
-                           }
-#endif
-               }
-
-               break;
-             }
-    case 3 : {                         /* indexed */
-               switch (pData->iBitdepth)
-               {
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-                 case  1 : {
-                             if (!pData->iInterlace)
-                               pData->fInitrowproc = (mng_fptr)mng_init_idx1_ni;
-                             else
-                               pData->fInitrowproc = (mng_fptr)mng_init_idx1_i;
-
-                             break;
-                           }
-                 case  2 : {
-                             if (!pData->iInterlace)
-                               pData->fInitrowproc = (mng_fptr)mng_init_idx2_ni;
-                             else
-                               pData->fInitrowproc = (mng_fptr)mng_init_idx2_i;
-
-                             break;
-                           }
-                 case  4 : {
-                             if (!pData->iInterlace)
-                               pData->fInitrowproc = (mng_fptr)mng_init_idx4_ni;
-                             else
-                               pData->fInitrowproc = (mng_fptr)mng_init_idx4_i;
-
-                             break;
-                           }
-#endif /* MNG_NO_1_2_4BIT_SUPPORT */
-                 case  8 : {
-                             if (!pData->iInterlace)
-                               pData->fInitrowproc = (mng_fptr)mng_init_idx8_ni;
-                             else
-                               pData->fInitrowproc = (mng_fptr)mng_init_idx8_i;
-
-                             break;
-                           }
-               }
-
-               break;
-             }
-    case 4 : {                         /* gray+alpha */
-               switch (pData->iBitdepth)
-               {
-                 case  8 : {
-                             if (!pData->iInterlace)
-                               pData->fInitrowproc = (mng_fptr)mng_init_ga8_ni;
-                             else
-                               pData->fInitrowproc = (mng_fptr)mng_init_ga8_i;
-
-                             break;
-                           }
-#ifndef MNG_NO_16BIT_SUPPORT
-                 case 16 : {
-                             if (!pData->iInterlace)
-                               pData->fInitrowproc = (mng_fptr)mng_init_ga16_ni;
-                             else
-                               pData->fInitrowproc = (mng_fptr)mng_init_ga16_i;
-
-                             break;
-                           }
-#endif
-               }
-
-               break;
-             }
-    case 6 : {                         /* rgb+alpha */
-               switch (pData->iBitdepth)
-               {
-                 case  8 : {
-                             if (!pData->iInterlace)
-                               pData->fInitrowproc = (mng_fptr)mng_init_rgba8_ni;
-                             else
-                               pData->fInitrowproc = (mng_fptr)mng_init_rgba8_i;
-
-                             break;
-                           }
-#ifndef MNG_NO_16BIT_SUPPORT
-                 case 16 : {
-                             if (!pData->iInterlace)
-                               pData->fInitrowproc = (mng_fptr)mng_init_rgba16_ni;
-                             else
-                               pData->fInitrowproc = (mng_fptr)mng_init_rgba16_i;
-
-                             break;
-                           }
-#endif
-               }
-
-               break;
-             }
-  }
-#endif /* MNG_OPTIMIZE_FOOTPRINT_INIT */
-
-  pData->iFilterofs = 0;               /* determine filter characteristics */
-  pData->iLevel0    = 0;               /* default levels */
-  pData->iLevel1    = 0;
-  pData->iLevel2    = 0;
-  pData->iLevel3    = 0;
-
-#ifdef FILTER192
-  if (pData->iFilter == 0xC0)          /* leveling & differing ? */
-  {
-    switch (pData->iColortype)
-    {
-      case 0 : {
-#ifndef MNG_NO_16BIT_SUPPORT
-                 if (pData->iBitdepth <= 8)
-#endif
-                   pData->iFilterofs = 1;
-#ifndef MNG_NO_16BIT_SUPPORT
-                 else
-                   pData->iFilterofs = 2;
-#endif
-
-                 break;
-               }
-      case 2 : {
-#ifndef MNG_NO_16BIT_SUPPORT
-                 if (pData->iBitdepth <= 8)
-#endif
-                   pData->iFilterofs = 3;
-#ifndef MNG_NO_16BIT_SUPPORT
-                 else
-                   pData->iFilterofs = 6;
-#endif
-
-                 break;
-               }
-      case 3 : {
-                 pData->iFilterofs = 1;
-                 break;
-               }
-      case 4 : {
-#ifndef MNG_NO_16BIT_SUPPORT
-                 if (pData->iBitdepth <= 8)
-#endif
-                   pData->iFilterofs = 2;
-#ifndef MNG_NO_16BIT_SUPPORT
-                 else
-                   pData->iFilterofs = 4;
-#endif
-
-                 break;
-               }
-      case 6 : {
-#ifndef MNG_NO_16BIT_SUPPORT
-                 if (pData->iBitdepth <= 8)
-#endif
-                   pData->iFilterofs = 4;
-#ifndef MNG_NO_16BIT_SUPPORT
-                 else
-                   pData->iFilterofs = 8;
-#endif
-
-                 break;
-               }
-    }
-  }
-#endif
-
-#ifdef FILTER193
-  if (pData->iFilter == 0xC1)          /* no adaptive filtering ? */
-    pData->iPixelofs = pData->iFilterofs;
-  else
-#endif
-    pData->iPixelofs = pData->iFilterofs + 1;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_BASI, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_CLON
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-mng_retcode mng_process_display_clon (mng_datap  pData,
-                                      mng_uint16 iSourceid,
-                                      mng_uint16 iCloneid,
-                                      mng_uint8  iClonetype,
-                                      mng_bool   bHasdonotshow,
-                                      mng_uint8  iDonotshow,
-                                      mng_uint8  iConcrete,
-                                      mng_bool   bHasloca,
-                                      mng_uint8  iLocationtype,
-                                      mng_int32  iLocationx,
-                                      mng_int32  iLocationy)
-#else
-mng_retcode mng_process_display_clon (mng_datap  pData)
-#endif
-{
-  mng_imagep  pSource, pClone;
-  mng_bool    bVisible, bAbstract;
-  mng_retcode iRetcode = MNG_NOERROR;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_CLON, MNG_LC_START);
-#endif
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-                                       /* locate the source object first */
-  pSource = mng_find_imageobject (pData, iSourceid);
-                                       /* check if the clone exists */
-  pClone  = mng_find_imageobject (pData, iCloneid);
-#else
-                                       /* locate the source object first */
-  pSource = mng_find_imageobject (pData, pData->iCLONsourceid);
-                                       /* check if the clone exists */
-  pClone  = mng_find_imageobject (pData, pData->iCLONcloneid);
-#endif
-
-  if (!pSource)                        /* source must exist ! */
-    MNG_ERROR (pData, MNG_OBJECTUNKNOWN);
-
-  if (pClone)                          /* clone must not exist ! */
-    MNG_ERROR (pData, MNG_OBJECTEXISTS);
-
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-  if (bHasdonotshow)                   /* DoNotShow flag filled ? */
-    bVisible = (mng_bool)(iDonotshow == 0);
-  else
-    bVisible = pSource->bVisible;
-#else
-  if (pData->bCLONhasdonotshow)        /* DoNotShow flag filled ? */
-    bVisible = (mng_bool)(pData->iCLONdonotshow == 0);
-  else
-    bVisible = pSource->bVisible;
-#endif
-
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-  bAbstract  = (mng_bool)(iConcrete == 1);
-#else
-  bAbstract  = (mng_bool)(pData->iCLONconcrete == 1);
-#endif
-
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-  switch (iClonetype)                  /* determine action to take */
-  {
-    case 0 : {                         /* full clone */
-               iRetcode = mng_clone_imageobject (pData, iCloneid, MNG_FALSE,
-                                                 bVisible, bAbstract, bHasloca,
-                                                 iLocationtype, iLocationx, iLocationy,
-                                                 pSource, &pClone);
-               break;
-             }
-
-    case 1 : {                         /* partial clone */
-               iRetcode = mng_clone_imageobject (pData, iCloneid, MNG_TRUE,
-                                                 bVisible, bAbstract, bHasloca,
-                                                 iLocationtype, iLocationx, iLocationy,
-                                                 pSource, &pClone);
-               break;
-             }
-
-    case 2 : {                         /* renumber object */
-               iRetcode = mng_renum_imageobject (pData, pSource, iCloneid,
-                                                 bVisible, bAbstract, bHasloca,
-                                                 iLocationtype, iLocationx, iLocationy);
-               pClone   = pSource;
-               break;
-             }
-
-  }
-#else
-  switch (pData->iCLONclonetype)       /* determine action to take */
-  {
-    case 0 : {                         /* full clone */
-               iRetcode = mng_clone_imageobject (pData, pData->iCLONcloneid, MNG_FALSE,
-                                                 bVisible, bAbstract,
-                                                 pData->bCLONhasloca, pData->iCLONlocationtype,
-                                                 pData->iCLONlocationx, pData->iCLONlocationy,
-                                                 pSource, &pClone);
-               break;
-             }
-
-    case 1 : {                         /* partial clone */
-               iRetcode = mng_clone_imageobject (pData, pData->iCLONcloneid, MNG_TRUE,
-                                                 bVisible, bAbstract,
-                                                 pData->bCLONhasloca, pData->iCLONlocationtype,
-                                                 pData->iCLONlocationx, pData->iCLONlocationy,
-                                                 pSource, &pClone);
-               break;
-             }
-
-    case 2 : {                         /* renumber object */
-               iRetcode = mng_renum_imageobject (pData, pSource, pData->iCLONcloneid,
-                                                 bVisible, bAbstract,
-                                                 pData->bCLONhasloca, pData->iCLONlocationtype,
-                                                 pData->iCLONlocationx, pData->iCLONlocationy);
-               pClone   = pSource;
-               break;
-             }
-
-  }
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-
-                                       /* display on the fly ? */
-  if ((pClone->bViewable) && (pClone->bVisible))
-  {
-    pData->pLastclone = pClone;        /* remember in case of timer break ! */
-                                       /* display it */
-    mng_display_image (pData, pClone, MNG_FALSE);
-
-    if (pData->bTimerset)              /* timer break ? */
-      pData->iBreakpoint = 5;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_CLON, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_display_clon2 (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_CLON, MNG_LC_START);
-#endif
-                                       /* only called after timer break ! */
-  mng_display_image (pData, (mng_imagep)pData->pLastclone, MNG_FALSE);
-  pData->iBreakpoint = 0;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_CLON, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_DISC
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-mng_retcode mng_process_display_disc (mng_datap   pData,
-                                      mng_uint32  iCount,
-                                      mng_uint16p pIds)
-#else
-mng_retcode mng_process_display_disc (mng_datap   pData)
-#endif
-{
-  mng_uint32 iX;
-  mng_imagep pImage;
-  mng_uint32 iRetcode;
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_DISC, MNG_LC_START);
-#endif
-
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-  if (iCount)                          /* specific list ? */
-#else
-  if (pData->iDISCcount)               /* specific list ? */
-#endif
-  {
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-    mng_uint16p pWork = pIds;
-#else
-    mng_uint16p pWork = pData->pDISCids;
-#endif
-
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-#ifdef MNG_DECREMENT_LOOPS             /* iterate the list */
-    for (iX = iCount; iX > 0; iX--)
-#else
-    for (iX = 0; iX < iCount; iX++)
-#endif
-#else
-#ifdef MNG_DECREMENT_LOOPS             /* iterate the list */
-    for (iX = pData->iDISCcount; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iDISCcount; iX++)
-#endif
-#endif
-    {
-      pImage = mng_find_imageobject (pData, *pWork++);
-
-      if (pImage)                      /* found the object ? */
-      {                                /* then drop it */
-        iRetcode = mng_free_imageobject (pData, pImage);
-
-        if (iRetcode)                  /* on error bail out */
-          return iRetcode;
-      }
-    }
-  }
-  else                                 /* empty: drop all un-frozen objects */
-  {
-    mng_imagep pNext = (mng_imagep)pData->pFirstimgobj;
-
-    while (pNext)                      /* any left ? */
-    {
-      pImage = pNext;
-      pNext  = pImage->sHeader.pNext;
-
-      if (!pImage->bFrozen)            /* not frozen ? */
-      {                                /* then drop it */
-        iRetcode = mng_free_imageobject (pData, pImage);
-                       
-        if (iRetcode)                  /* on error bail out */
-          return iRetcode;
-      }
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_DISC, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_FRAM
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-mng_retcode mng_process_display_fram (mng_datap  pData,
-                                      mng_uint8  iFramemode,
-                                      mng_uint8  iChangedelay,
-                                      mng_uint32 iDelay,
-                                      mng_uint8  iChangetimeout,
-                                      mng_uint32 iTimeout,
-                                      mng_uint8  iChangeclipping,
-                                      mng_uint8  iCliptype,
-                                      mng_int32  iClipl,
-                                      mng_int32  iClipr,
-                                      mng_int32  iClipt,
-                                      mng_int32  iClipb)
-#else
-mng_retcode mng_process_display_fram (mng_datap  pData)
-#endif
-{
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_FRAM, MNG_LC_START);
-#endif
-                                       /* advance a frame then */
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-  iRetcode = next_frame (pData, iFramemode, iChangedelay, iDelay,
-                         iChangetimeout, iTimeout, iChangeclipping,
-                         iCliptype, iClipl, iClipr, iClipt, iClipb);
-#else
-  iRetcode = next_frame (pData, pData->iTempFramemode, pData->iTempChangedelay,
-                         pData->iTempDelay, pData->iTempChangetimeout,
-                         pData->iTempTimeout, pData->iTempChangeclipping,
-                         pData->iTempCliptype, pData->iTempClipl, pData->iTempClipr,
-                         pData->iTempClipt, pData->iTempClipb);
-#endif
-
-  if (pData->bTimerset)                /* timer break ? */
-    pData->iBreakpoint = 1;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_FRAM, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_display_fram2 (mng_datap pData)
-{
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_FRAM, MNG_LC_START);
-#endif
-                                       /* again; after the break */
-  iRetcode = next_frame (pData, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
-  pData->iBreakpoint = 0;              /* not again! */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_FRAM, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_MOVE
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-mng_retcode mng_process_display_move (mng_datap  pData,
-                                      mng_uint16 iFromid,
-                                      mng_uint16 iToid,
-                                      mng_uint8  iMovetype,
-                                      mng_int32  iMovex,
-                                      mng_int32  iMovey)
-#else
-mng_retcode mng_process_display_move (mng_datap  pData)
-#endif
-{
-  mng_uint16 iX;
-  mng_imagep pImage;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MOVE, MNG_LC_START);
-#endif
-                                       /* iterate the list */
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-  for (iX = iFromid; iX <= iToid; iX++)
-#else
-  for (iX = pData->iMOVEfromid; iX <= pData->iMOVEtoid; iX++)
-#endif
-  {
-    if (!iX)                           /* object id=0 ? */
-      pImage = (mng_imagep)pData->pObjzero;
-    else
-      pImage = mng_find_imageobject (pData, iX);
-
-    if (pImage)                        /* object exists ? */
-    {
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-      switch (iMovetype)
-#else
-      switch (pData->iMOVEmovetype)
-#endif
-      {
-        case 0 : {                     /* absolute */
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-                   pImage->iPosx = iMovex;
-                   pImage->iPosy = iMovey;
-#else
-                   pImage->iPosx = pData->iMOVEmovex;
-                   pImage->iPosy = pData->iMOVEmovey;
-#endif
-                   break;
-                 }
-        case 1 : {                     /* relative */
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-                   pImage->iPosx = pImage->iPosx + iMovex;
-                   pImage->iPosy = pImage->iPosy + iMovey;
-#else
-                   pImage->iPosx = pImage->iPosx + pData->iMOVEmovex;
-                   pImage->iPosy = pImage->iPosy + pData->iMOVEmovey;
-#endif
-                   break;
-                 }
-      }
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MOVE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_CLIP
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-mng_retcode mng_process_display_clip (mng_datap  pData,
-                                      mng_uint16 iFromid,
-                                      mng_uint16 iToid,
-                                      mng_uint8  iCliptype,
-                                      mng_int32  iClipl,
-                                      mng_int32  iClipr,
-                                      mng_int32  iClipt,
-                                      mng_int32  iClipb)
-#else
-mng_retcode mng_process_display_clip (mng_datap  pData)
-#endif
-{
-  mng_uint16 iX;
-  mng_imagep pImage;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_CLIP, MNG_LC_START);
-#endif
-                                       /* iterate the list */
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-  for (iX = iFromid; iX <= iToid; iX++)
-#else
-  for (iX = pData->iCLIPfromid; iX <= pData->iCLIPtoid; iX++)
-#endif
-  {
-    if (!iX)                           /* object id=0 ? */
-      pImage = (mng_imagep)pData->pObjzero;
-    else
-      pImage = mng_find_imageobject (pData, iX);
-
-    if (pImage)                        /* object exists ? */
-    {
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-      switch (iCliptype)
-#else
-      switch (pData->iCLIPcliptype)
-#endif
-      {
-        case 0 : {                     /* absolute */
-                   pImage->bClipped = MNG_TRUE;
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-                   pImage->iClipl   = iClipl;
-                   pImage->iClipr   = iClipr;
-                   pImage->iClipt   = iClipt;
-                   pImage->iClipb   = iClipb;
-#else
-                   pImage->iClipl   = pData->iCLIPclipl;
-                   pImage->iClipr   = pData->iCLIPclipr;
-                   pImage->iClipt   = pData->iCLIPclipt;
-                   pImage->iClipb   = pData->iCLIPclipb;
-#endif
-                   break;
-                 }
-        case 1 : {                    /* relative */
-                   pImage->bClipped = MNG_TRUE;
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-                   pImage->iClipl   = pImage->iClipl + iClipl;
-                   pImage->iClipr   = pImage->iClipr + iClipr;
-                   pImage->iClipt   = pImage->iClipt + iClipt;
-                   pImage->iClipb   = pImage->iClipb + iClipb;
-#else
-                   pImage->iClipl   = pImage->iClipl + pData->iCLIPclipl;
-                   pImage->iClipr   = pImage->iClipr + pData->iCLIPclipr;
-                   pImage->iClipt   = pImage->iClipt + pData->iCLIPclipt;
-                   pImage->iClipb   = pImage->iClipb + pData->iCLIPclipb;
-#endif
-                   break;
-                 }
-      }
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_CLIP, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_SHOW
-mng_retcode mng_process_display_show (mng_datap pData)
-{
-  mng_int16  iX, iS, iFrom, iTo;
-  mng_imagep pImage;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_SHOW, MNG_LC_START);
-#endif
-
-  /* TODO: optimization for the cases where "abs (iTo - iFrom)" is rather high;
-     especially where ((iFrom==1) && (iTo==65535)); eg. an empty SHOW !!! */
-
-  if (pData->iBreakpoint == 3)         /* previously broken during cycle-mode ? */
-  {
-    pImage = mng_find_imageobject (pData, pData->iSHOWnextid);
-                 
-    if (pImage)                        /* still there ? */
-      mng_display_image (pData, pImage, MNG_FALSE);
-
-    pData->iBreakpoint = 0;            /* let's not go through this again! */
-  }
-  else
-  {
-    if (pData->iBreakpoint)            /* previously broken at other point ? */
-    {                                  /* restore last parms */
-      iFrom = (mng_int16)pData->iSHOWfromid;
-      iTo   = (mng_int16)pData->iSHOWtoid;
-      iX    = (mng_int16)pData->iSHOWnextid;
-      iS    = (mng_int16)pData->iSHOWskip;
-    }
-    else
-    {                                  /* regular sequence ? */
-      if (pData->iSHOWtoid >= pData->iSHOWfromid)
-        iS  = 1;
-      else                             /* reverse sequence ! */
-        iS  = -1;
-
-      iFrom = (mng_int16)pData->iSHOWfromid;
-      iTo   = (mng_int16)pData->iSHOWtoid;
-      iX    = iFrom;
-
-      pData->iSHOWfromid = (mng_uint16)iFrom;
-      pData->iSHOWtoid   = (mng_uint16)iTo;
-      pData->iSHOWskip   = iS;
-    }
-                                       /* cycle mode ? */
-    if ((pData->iSHOWmode == 6) || (pData->iSHOWmode == 7))
-    {
-      mng_uint16 iTrigger = 0;
-      mng_uint16 iFound   = 0;
-      mng_uint16 iPass    = 0;
-      mng_imagep pFound   = 0;
-
-      do
-      {
-        iPass++;                       /* lets prevent endless loops when there
-                                          are no potential candidates in the list! */
-
-        if (iS > 0)                    /* forward ? */
-        {
-          for (iX = iFrom; iX <= iTo; iX += iS)
-          {
-            pImage = mng_find_imageobject (pData, (mng_uint16)iX);
-                         
-            if (pImage)                /* object exists ? */
-            {
-              if (iFound)              /* already found a candidate ? */
-                pImage->bVisible = MNG_FALSE;
-              else
-              if (iTrigger)            /* found the trigger ? */
-              {
-                pImage->bVisible = MNG_TRUE;
-                iFound           = iX;
-                pFound           = pImage;
-              }
-              else
-              if (pImage->bVisible)    /* ok, this is the trigger */
-              {
-                pImage->bVisible = MNG_FALSE;
-                iTrigger         = iX;
-              }
-            }
-          }
-        }
-        else
-        {
-          for (iX = iFrom; iX >= iTo; iX += iS)
-          {
-            pImage = mng_find_imageobject (pData, (mng_uint16)iX);
-                         
-            if (pImage)                /* object exists ? */
-            {
-              if (iFound)              /* already found a candidate ? */
-                pImage->bVisible = MNG_FALSE;
-              else
-              if (iTrigger)            /* found the trigger ? */
-              {
-                pImage->bVisible = MNG_TRUE;
-                iFound           = iX;
-                pFound           = pImage;
-              }
-              else
-              if (pImage->bVisible)    /* ok, this is the trigger */
-              {
-                pImage->bVisible = MNG_FALSE;
-                iTrigger         = iX;
-              }
-            }
-          }
-        }
-
-        if (!iTrigger)                 /* did not find a trigger ? */
-          iTrigger = 1;                /* then fake it so the first image
-                                          gets nominated */
-      }                                /* cycle back to beginning ? */
-      while ((iPass < 2) && (iTrigger) && (!iFound));
-
-      pData->iBreakpoint = 0;          /* just a sanity precaution */
-                                       /* display it ? */
-      if ((pData->iSHOWmode == 6) && (pFound))
-      {
-        mng_display_image (pData, pFound, MNG_FALSE);
-
-        if (pData->bTimerset)          /* timer set ? */
-        {
-          pData->iBreakpoint = 3;
-          pData->iSHOWnextid = iFound; /* save it for after the break */
-        }
-      }
-    }
-    else
-    {
-      do
-      {
-        pImage = mng_find_imageobject (pData, iX);
-                     
-        if (pImage)                    /* object exists ? */
-        {
-          if (pData->iBreakpoint)      /* did we get broken last time ? */
-          {                            /* could only happen in the display routine */
-            mng_display_image (pData, pImage, MNG_FALSE);
-            pData->iBreakpoint = 0;    /* only once inside this loop please ! */
-          }
-          else
-          {
-            switch (pData->iSHOWmode)  /* do what ? */
-            {
-              case 0 : {
-                         pImage->bVisible = MNG_TRUE;
-                         mng_display_image (pData, pImage, MNG_FALSE);
-                         break;
-                       }
-              case 1 : {
-                         pImage->bVisible = MNG_FALSE;
-                         break;
-                       }
-              case 2 : {
-                         if (pImage->bVisible)
-                           mng_display_image (pData, pImage, MNG_FALSE);
-                         break;
-                       }
-              case 3 : {
-                         pImage->bVisible = MNG_TRUE;
-                         break;
-                       }
-              case 4 : {
-                         pImage->bVisible = (mng_bool)(!pImage->bVisible);
-                         if (pImage->bVisible)
-                           mng_display_image (pData, pImage, MNG_FALSE);
-                         break;
-                       }
-              case 5 : {
-                         pImage->bVisible = (mng_bool)(!pImage->bVisible);
-                       }
-            }
-          }
-        }
-
-        if (!pData->bTimerset)         /* next ? */
-          iX += iS;
-
-      }                                /* continue ? */
-      while ((!pData->bTimerset) && (((iS > 0) && (iX <= iTo)) ||
-                                     ((iS < 0) && (iX >= iTo))    ));
-
-      if (pData->bTimerset)            /* timer set ? */
-      {
-        pData->iBreakpoint = 4;
-        pData->iSHOWnextid = iX;       /* save for next time */
-      }
-      else
-        pData->iBreakpoint = 0;
-        
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_SHOW, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_SAVE
-mng_retcode mng_process_display_save (mng_datap pData)
-{
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_SAVE, MNG_LC_START);
-#endif
-
-  iRetcode = save_state (pData);       /* save the current state */
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_SAVE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_SEEK
-mng_retcode mng_process_display_seek (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_SEEK, MNG_LC_START);
-#endif
-
-#ifdef MNG_SUPPORT_DYNAMICMNG
-  if (pData->bStopafterseek)           /* need to stop after this SEEK ? */
-  {
-    pData->bFreezing      = MNG_TRUE;  /* stop processing on this one */
-    pData->bRunningevent  = MNG_FALSE;
-    pData->bStopafterseek = MNG_FALSE;
-    pData->bNeedrefresh   = MNG_TRUE;  /* make sure the last bit is displayed ! */
-  }
-  else
-#endif
-  {                                    /* restore the initial or SAVE state */
-    mng_retcode iRetcode = restore_state (pData);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-
-#ifdef MNG_SUPPORT_DYNAMICMNG
-                                       /* stop after next SEEK ? */
-    if ((pData->bDynamic) || (pData->bRunningevent))
-      pData->bStopafterseek = MNG_TRUE;
-#endif
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_SEEK, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-mng_retcode mng_process_display_jhdr (mng_datap pData)
-{                                      /* address the current "object" if any */
-  mng_imagep  pImage   = (mng_imagep)pData->pCurrentobj;
-  mng_retcode iRetcode = MNG_NOERROR;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_JHDR, MNG_LC_START);
-#endif
-
-  if (!pData->bHasDHDR)
-  {
-    pData->fInitrowproc  = MNG_NULL;   /* do nothing by default */
-    pData->fDisplayrow   = MNG_NULL;
-    pData->fCorrectrow   = MNG_NULL;
-    pData->fStorerow     = MNG_NULL;
-    pData->fProcessrow   = MNG_NULL;
-    pData->fDifferrow    = MNG_NULL;
-    pData->fStorerow2    = MNG_NULL;
-    pData->fStorerow3    = MNG_NULL;
-
-    pData->pStoreobj     = MNG_NULL;   /* initialize important work-parms */
-
-    pData->iJPEGrow      = 0;
-    pData->iJPEGalpharow = 0;
-    pData->iJPEGrgbrow   = 0;
-    pData->iRowmax       = 0;          /* so init_rowproc does the right thing ! */
-  }
-
-  if (!pData->iBreakpoint)             /* not previously broken ? */
-  {
-#ifndef MNG_NO_DELTA_PNG
-    if (pData->bHasDHDR)               /* delta-image ? */
-    {
-      if (pData->iDeltatype == MNG_DELTATYPE_REPLACE)
-      {
-        iRetcode = mng_reset_object_details (pData, (mng_imagep)pData->pDeltaImage,
-                                             pData->iDatawidth, pData->iDataheight,
-                                             pData->iJHDRimgbitdepth, pData->iJHDRcolortype,
-                                             pData->iJHDRalphacompression, pData->iJHDRalphafilter,
-                                             pData->iJHDRalphainterlace, MNG_TRUE);
-
-        ((mng_imagep)pData->pDeltaImage)->pImgbuf->iAlphabitdepth    = pData->iJHDRalphabitdepth;
-        ((mng_imagep)pData->pDeltaImage)->pImgbuf->iJHDRcompression  = pData->iJHDRimgcompression;
-        ((mng_imagep)pData->pDeltaImage)->pImgbuf->iJHDRinterlace    = pData->iJHDRimginterlace;
-        ((mng_imagep)pData->pDeltaImage)->pImgbuf->iAlphasampledepth = pData->iJHDRalphabitdepth;
-      }
-      else
-      if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD    ) ||
-          (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
-      {
-        ((mng_imagep)pData->pDeltaImage)->pImgbuf->iPixelsampledepth = pData->iJHDRimgbitdepth;
-        ((mng_imagep)pData->pDeltaImage)->pImgbuf->iAlphasampledepth = pData->iJHDRalphabitdepth;
-      }
-      else
-      if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAADD    ) ||
-          (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE)    )
-        ((mng_imagep)pData->pDeltaImage)->pImgbuf->iAlphasampledepth = pData->iJHDRalphabitdepth;
-      else
-      if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORADD    ) ||
-          (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE)    )
-        ((mng_imagep)pData->pDeltaImage)->pImgbuf->iPixelsampledepth = pData->iJHDRimgbitdepth;
-        
-    }
-    else
-#endif /* MNG_NO_DELTA_PNG */
-    {
-      if (pImage)                      /* update object buffer ? */
-      {
-        iRetcode = mng_reset_object_details (pData, pImage,
-                                             pData->iDatawidth, pData->iDataheight,
-                                             pData->iJHDRimgbitdepth, pData->iJHDRcolortype,
-                                             pData->iJHDRalphacompression, pData->iJHDRalphafilter,
-                                             pData->iJHDRalphainterlace, MNG_TRUE);
-
-        pImage->pImgbuf->iAlphabitdepth    = pData->iJHDRalphabitdepth;
-        pImage->pImgbuf->iJHDRcompression  = pData->iJHDRimgcompression;
-        pImage->pImgbuf->iJHDRinterlace    = pData->iJHDRimginterlace;
-        pImage->pImgbuf->iAlphasampledepth = pData->iJHDRalphabitdepth;
-      }
-      else                             /* update object 0 */
-      {
-        iRetcode = mng_reset_object_details (pData, (mng_imagep)pData->pObjzero,
-                                             pData->iDatawidth, pData->iDataheight,
-                                             pData->iJHDRimgbitdepth, pData->iJHDRcolortype,
-                                             pData->iJHDRalphacompression, pData->iJHDRalphafilter,
-                                             pData->iJHDRalphainterlace, MNG_TRUE);
-
-        ((mng_imagep)pData->pObjzero)->pImgbuf->iAlphabitdepth    = pData->iJHDRalphabitdepth;
-        ((mng_imagep)pData->pObjzero)->pImgbuf->iJHDRcompression  = pData->iJHDRimgcompression;
-        ((mng_imagep)pData->pObjzero)->pImgbuf->iJHDRinterlace    = pData->iJHDRimginterlace;
-        ((mng_imagep)pData->pObjzero)->pImgbuf->iAlphasampledepth = pData->iJHDRalphabitdepth;
-      }
-    }
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-  }
-
-  if (!pData->bHasDHDR)
-  {                                    /* we're always storing a JPEG */
-    if (pImage)                        /* real object ? */
-      pData->pStoreobj = pImage;       /* tell the row routines */
-    else                               /* otherwise use object 0 */
-      pData->pStoreobj = pData->pObjzero;
-                                       /* display "on-the-fly" ? */
-    if (
-#ifndef MNG_SKIPCHUNK_MAGN
-         ( ((mng_imagep)pData->pStoreobj)->iMAGN_MethodX == 0) &&
-         ( ((mng_imagep)pData->pStoreobj)->iMAGN_MethodY == 0) &&
-#endif
-         ( (pData->eImagetype == mng_it_jng         ) ||
-           (((mng_imagep)pData->pStoreobj)->bVisible)    )       )
-    {
-      next_layer (pData);              /* that's a new layer then ! */
-
-      pData->iBreakpoint = 0;
-
-      if (pData->bTimerset)            /* timer break ? */
-        pData->iBreakpoint = 7;
-      else
-      if (pData->bRunning)             /* still running ? */
-      {                                /* anything to display ? */
-        if ((pData->iDestr > pData->iDestl) && (pData->iDestb > pData->iDestt))
-        {
-          set_display_routine (pData); /* then determine display routine */
-                                       /* display from the object we store in */
-          pData->pRetrieveobj = pData->pStoreobj;
-        }
-      }
-    }
-  }
-
-  if (!pData->bTimerset)               /* no timer break ? */
-  {                                    /* default row initialization ! */
-#ifdef MNG_OPTIMIZE_FOOTPRINT_INIT
-    pData->ePng_imgtype=png_none;
-#endif
-    pData->fInitrowproc = (mng_fptr)mng_init_rowproc;
-
-    if ((!pData->bHasDHDR) || (pData->iDeltatype == MNG_DELTATYPE_REPLACE))
-    {                                  /* 8-bit JPEG ? */
-      if (pData->iJHDRimgbitdepth == 8)
-      {                                /* intermediate row is 8-bit deep */
-        pData->bIsRGBA16   = MNG_FALSE;
-        pData->iRowsamples = pData->iDatawidth;
-
-        switch (pData->iJHDRcolortype) /* determine pixel processing routines */
-        {
-          case MNG_COLORTYPE_JPEGGRAY :
-               {
-                 pData->fStorerow2   = (mng_fptr)mng_store_jpeg_g8;
-                 pData->fRetrieverow = (mng_fptr)mng_retrieve_g8;
-                 pData->bIsOpaque    = MNG_TRUE;
-                 break;
-               }
-          case MNG_COLORTYPE_JPEGCOLOR :
-               {
-                 pData->fStorerow2   = (mng_fptr)mng_store_jpeg_rgb8;
-                 pData->fRetrieverow = (mng_fptr)mng_retrieve_rgb8;
-                 pData->bIsOpaque    = MNG_TRUE;
-                 break;
-               }
-          case MNG_COLORTYPE_JPEGGRAYA :
-               {
-                 pData->fStorerow2   = (mng_fptr)mng_store_jpeg_ga8;
-                 pData->fRetrieverow = (mng_fptr)mng_retrieve_ga8;
-                 pData->bIsOpaque    = MNG_FALSE;
-                 break;
-               }
-          case MNG_COLORTYPE_JPEGCOLORA :
-               {
-                 pData->fStorerow2   = (mng_fptr)mng_store_jpeg_rgba8;
-                 pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba8;
-                 pData->bIsOpaque    = MNG_FALSE;
-                 break;
-               }
-        }
-      }
-#ifndef MNG_NO_16BIT_SUPPORT
-      else
-      {
-        pData->bIsRGBA16 = MNG_TRUE;   /* intermediate row is 16-bit deep */
-
-        /* TODO: 12-bit JPEG */
-        /* TODO: 8- + 12-bit JPEG (eg. type=20) */
-
-      }
-#endif
-                                       /* possible IDAT alpha-channel ? */
-      if (pData->iJHDRalphacompression == MNG_COMPRESSION_DEFLATE)
-      {
-                                       /* determine alpha processing routine */
-#ifdef MNG_OPTIMIZE_FOOTPRINT_INIT
-        pData->fInitrowproc = (mng_fptr)mng_init_rowproc;
-#endif
-        switch (pData->iJHDRalphabitdepth)
-        {
-#ifndef MNG_OPTIMIZE_FOOTPRINT_INIT
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-          case  1 : { pData->fInitrowproc = (mng_fptr)mng_init_jpeg_a1_ni;  break; }
-          case  2 : { pData->fInitrowproc = (mng_fptr)mng_init_jpeg_a2_ni;  break; }
-          case  4 : { pData->fInitrowproc = (mng_fptr)mng_init_jpeg_a4_ni;  break; }
-#endif /* MNG_NO_1_2_4BIT_SUPPORT */
-          case  8 : { pData->fInitrowproc = (mng_fptr)mng_init_jpeg_a8_ni;  break; }
-#ifndef MNG_NO_16BIT_SUPPORT
-          case 16 : { pData->fInitrowproc = (mng_fptr)mng_init_jpeg_a16_ni; break; }
-#endif
-#else
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-          case  1 : { pData->ePng_imgtype = png_jpeg_a1;  break; }
-          case  2 : { pData->ePng_imgtype = png_jpeg_a2;  break; }
-          case  4 : { pData->ePng_imgtype = png_jpeg_a4;  break; }
-#endif /* MNG_NO_1_2_4BIT_SUPPORT */
-          case  8 : { pData->ePng_imgtype = png_jpeg_a8;  break; }
-#ifndef MNG_NO_16BIT_SUPPORT
-          case 16 : { pData->ePng_imgtype = png_jpeg_a16; break; }
-#endif
-#endif
-        }
-      }
-      else                             /* possible JDAA alpha-channel ? */
-      if (pData->iJHDRalphacompression == MNG_COMPRESSION_BASELINEJPEG)
-      {                                /* 8-bit JPEG ? */
-        if (pData->iJHDRimgbitdepth == 8)
-        {
-          if (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA)
-            pData->fStorerow3 = (mng_fptr)mng_store_jpeg_g8_alpha;
-          else
-          if (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA)
-            pData->fStorerow3 = (mng_fptr)mng_store_jpeg_rgb8_alpha;
-        }
-        else
-        {
-          /* TODO: 12-bit JPEG with 8-bit JDAA */
-        }
-      }
-                                       /* initialize JPEG library */
-      iRetcode = mngjpeg_initialize (pData);
-
-      if (iRetcode)                    /* on error bail out */
-        return iRetcode;
-    }
-    else
-    {                                  /* must be alpha add/replace !! */
-      if ((pData->iDeltatype != MNG_DELTATYPE_BLOCKALPHAADD    ) &&
-          (pData->iDeltatype != MNG_DELTATYPE_BLOCKALPHAREPLACE)    )
-        MNG_ERROR (pData, MNG_INVDELTATYPE);
-                                       /* determine alpha processing routine */
-#ifdef MNG_OPTIMIZE_FOOTPRINT_INIT
-        pData->fInitrowproc = (mng_fptr)mng_init_rowproc;
-#endif
-      switch (pData->iJHDRalphabitdepth)
-      {
-#ifndef MNG_OPTIMIZE_FOOTPRINT_INIT
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-        case  1 : { pData->fInitrowproc = (mng_fptr)mng_init_g1_ni;  break; }
-        case  2 : { pData->fInitrowproc = (mng_fptr)mng_init_g2_ni;  break; }
-        case  4 : { pData->fInitrowproc = (mng_fptr)mng_init_g4_ni;  break; }
-#endif /* MNG_NO_1_2_4BIT_SUPPORT */
-        case  8 : { pData->fInitrowproc = (mng_fptr)mng_init_g8_ni;  break; }
-#ifndef MNG_NO_16BIT_SUPPORT
-        case 16 : { pData->fInitrowproc = (mng_fptr)mng_init_g16_ni; break; }
-#endif
-#else
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-        case  1 : { pData->ePng_imgtype = png_jpeg_a1;  break; }
-        case  2 : { pData->ePng_imgtype = png_jpeg_a2;  break; }
-        case  4 : { pData->ePng_imgtype = png_jpeg_a4;  break; }
-#endif /* MNG_NO_1_2_4BIT_SUPPORT */
-        case  8 : { pData->ePng_imgtype = png_jpeg_a8;  break; }
-#ifndef MNG_NO_16BIT_SUPPORT
-        case 16 : { pData->ePng_imgtype = png_jpeg_a16; break; }
-#endif
-#endif /* MNG_OPTIMIZE_FOOTPRINT_INIT */
-      }
-    }
-
-    pData->iFilterofs = 0;             /* determine filter characteristics */
-    pData->iLevel0    = 0;             /* default levels */
-    pData->iLevel1    = 0;    
-    pData->iLevel2    = 0;
-    pData->iLevel3    = 0;
-
-#ifdef FILTER192                       /* leveling & differing ? */
-    if (pData->iJHDRalphafilter == 0xC0)
-    {
-       if (pData->iJHDRalphabitdepth <= 8)
-         pData->iFilterofs = 1;
-       else
-         pData->iFilterofs = 2;
-
-    }
-#endif
-#ifdef FILTER193                       /* no adaptive filtering ? */
-    if (pData->iJHDRalphafilter == 0xC1)
-      pData->iPixelofs = pData->iFilterofs;
-    else
-#endif
-      pData->iPixelofs = pData->iFilterofs + 1;
-
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_JHDR, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_INCLUDE_JNG */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-mng_retcode mng_process_display_jdaa (mng_datap  pData,
-                                      mng_uint32 iRawlen,
-                                      mng_uint8p pRawdata)
-#else
-mng_retcode mng_process_display_jdaa (mng_datap  pData)
-#endif
-{
-  mng_retcode iRetcode = MNG_NOERROR;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_JDAA, MNG_LC_START);
-#endif
-
-  if (!pData->bJPEGdecompress2)        /* if we're not decompressing already */
-  {
-    if (pData->fInitrowproc)           /* initialize row-processing? */
-    {
-      iRetcode = ((mng_initrowproc)pData->fInitrowproc) (pData);
-      pData->fInitrowproc = MNG_NULL;  /* only call this once !!! */
-    }
-
-    if (!iRetcode)                     /* initialize decompress */
-      iRetcode = mngjpeg_decompressinit2 (pData);
-  }
-
-  if (!iRetcode)                       /* all ok? then decompress, my man */
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-    iRetcode = mngjpeg_decompressdata2 (pData, iRawlen, pRawdata);
-#else
-    iRetcode = mngjpeg_decompressdata2 (pData, pData->iRawlen, pData->pRawdata);
-#endif
-
-  if (iRetcode)
-    return iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_JDAA, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_INCLUDE_JNG */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-mng_retcode mng_process_display_jdat (mng_datap  pData,
-                                      mng_uint32 iRawlen,
-                                      mng_uint8p pRawdata)
-#else
-mng_retcode mng_process_display_jdat (mng_datap  pData)
-#endif
-{
-  mng_retcode iRetcode = MNG_NOERROR;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_JDAT, MNG_LC_START);
-#endif
-
-  if (pData->bRestorebkgd)             /* need to restore the background ? */
-  {
-    pData->bRestorebkgd = MNG_FALSE;
-    iRetcode            = load_bkgdlayer (pData);
-
-    pData->iLayerseq++;                /* and it counts as a layer then ! */
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-  }
-
-  if (!pData->bJPEGdecompress)         /* if we're not decompressing already */
-  {
-    if (pData->fInitrowproc)           /* initialize row-processing? */
-    {
-      iRetcode = ((mng_initrowproc)pData->fInitrowproc) (pData);
-      pData->fInitrowproc = MNG_NULL;  /* only call this once !!! */
-    }
-
-    if (!iRetcode)                     /* initialize decompress */
-      iRetcode = mngjpeg_decompressinit (pData);
-  }
-
-  if (!iRetcode)                       /* all ok? then decompress, my man */
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-    iRetcode = mngjpeg_decompressdata (pData, iRawlen, pRawdata);
-#else
-    iRetcode = mngjpeg_decompressdata (pData, pData->iRawlen, pData->pRawdata);
-#endif
-
-  if (iRetcode)
-    return iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_JDAT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_INCLUDE_JNG */
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-mng_retcode mng_process_display_dhdr (mng_datap  pData,
-                                      mng_uint16 iObjectid,
-                                      mng_uint8  iImagetype,
-                                      mng_uint8  iDeltatype,
-                                      mng_uint32 iBlockwidth,
-                                      mng_uint32 iBlockheight,
-                                      mng_uint32 iBlockx,
-                                      mng_uint32 iBlocky)
-#else
-mng_retcode mng_process_display_dhdr (mng_datap  pData)
-#endif
-{
-  mng_imagep  pImage;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_DHDR, MNG_LC_START);
-#endif
-
-  pData->fInitrowproc     = MNG_NULL;  /* do nothing by default */
-  pData->fDisplayrow      = MNG_NULL;
-  pData->fCorrectrow      = MNG_NULL;
-  pData->fStorerow        = MNG_NULL;
-  pData->fProcessrow      = MNG_NULL;
-  pData->pStoreobj        = MNG_NULL;
-
-  pData->fDeltagetrow     = MNG_NULL;
-  pData->fDeltaaddrow     = MNG_NULL;
-  pData->fDeltareplacerow = MNG_NULL;
-  pData->fDeltaputrow     = MNG_NULL;
-
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-  pImage = mng_find_imageobject (pData, iObjectid);
-#else
-  pImage = mng_find_imageobject (pData, pData->iDHDRobjectid);
-#endif
-
-  if (pImage)                          /* object exists ? */
-  {
-    if (pImage->pImgbuf->bConcrete)    /* is it concrete ? */
-    {                                  /* previous magnification to be done ? */
-#ifndef MNG_SKIPCHUNK_MAGN
-      if ((pImage->iMAGN_MethodX) || (pImage->iMAGN_MethodY))
-      {
-        iRetcode = mng_magnify_imageobject (pData, pImage);
-                       
-        if (iRetcode)                  /* on error bail out */
-          return iRetcode;
-      }
-#endif
-                                       /* save delta fields */
-      pData->pDeltaImage           = (mng_ptr)pImage;
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-      pData->iDeltaImagetype       = iImagetype;
-      pData->iDeltatype            = iDeltatype;
-      pData->iDeltaBlockwidth      = iBlockwidth;
-      pData->iDeltaBlockheight     = iBlockheight;
-      pData->iDeltaBlockx          = iBlockx;
-      pData->iDeltaBlocky          = iBlocky;
-#else
-      pData->iDeltaImagetype       = pData->iDHDRimagetype;
-      pData->iDeltatype            = pData->iDHDRdeltatype;
-      pData->iDeltaBlockwidth      = pData->iDHDRblockwidth;
-      pData->iDeltaBlockheight     = pData->iDHDRblockheight;
-      pData->iDeltaBlockx          = pData->iDHDRblockx;
-      pData->iDeltaBlocky          = pData->iDHDRblocky;
-#endif
-                                       /* restore target-object fields */
-      pData->iDatawidth            = pImage->pImgbuf->iWidth;
-      pData->iDataheight           = pImage->pImgbuf->iHeight;
-      pData->iBitdepth             = pImage->pImgbuf->iBitdepth;
-      pData->iColortype            = pImage->pImgbuf->iColortype;
-      pData->iCompression          = pImage->pImgbuf->iCompression;
-      pData->iFilter               = pImage->pImgbuf->iFilter;
-      pData->iInterlace            = pImage->pImgbuf->iInterlace;
-
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-      if ((iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD    ) ||
-          (iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
-        pData->iBitdepth           = pImage->pImgbuf->iPixelsampledepth;
-      else
-      if ((iDeltatype == MNG_DELTATYPE_BLOCKALPHAADD    ) ||
-          (iDeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE)    )
-        pData->iBitdepth           = pImage->pImgbuf->iAlphasampledepth;
-      else
-      if ((iDeltatype == MNG_DELTATYPE_BLOCKCOLORADD    ) ||
-          (iDeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE)    )
-        pData->iBitdepth           = pImage->pImgbuf->iPixelsampledepth;
-#else
-      if ((pData->iDHDRdeltatype == MNG_DELTATYPE_BLOCKPIXELADD    ) ||
-          (pData->iDHDRdeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
-        pData->iBitdepth           = pImage->pImgbuf->iPixelsampledepth;
-      else
-      if ((pData->iDHDRdeltatype == MNG_DELTATYPE_BLOCKALPHAADD    ) ||
-          (pData->iDHDRdeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE)    )
-        pData->iBitdepth           = pImage->pImgbuf->iAlphasampledepth;
-      else
-      if ((pData->iDHDRdeltatype == MNG_DELTATYPE_BLOCKCOLORADD    ) ||
-          (pData->iDHDRdeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE)    )
-        pData->iBitdepth           = pImage->pImgbuf->iPixelsampledepth;
-#endif
-
-#ifdef MNG_INCLUDE_JNG
-      pData->iJHDRimgbitdepth      = pImage->pImgbuf->iBitdepth;
-      pData->iJHDRcolortype        = pImage->pImgbuf->iColortype;
-      pData->iJHDRimgcompression   = pImage->pImgbuf->iJHDRcompression;
-      pData->iJHDRimginterlace     = pImage->pImgbuf->iJHDRinterlace;
-      pData->iJHDRalphacompression = pImage->pImgbuf->iCompression;
-      pData->iJHDRalphafilter      = pImage->pImgbuf->iFilter;
-      pData->iJHDRalphainterlace   = pImage->pImgbuf->iInterlace;
-      pData->iJHDRalphabitdepth    = pImage->pImgbuf->iAlphabitdepth;
-#endif
-
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-                                       /* block size specified ? */
-      if (iDeltatype != MNG_DELTATYPE_NOCHANGE)
-      {                                /* block entirely within target ? */
-        if (iDeltatype != MNG_DELTATYPE_REPLACE)
-        {
-          if (((iBlockx + iBlockwidth ) > pData->iDatawidth ) ||
-              ((iBlocky + iBlockheight) > pData->iDataheight)    )
-            MNG_ERROR (pData, MNG_INVALIDBLOCK);
-        }
-
-        pData->iDatawidth          = iBlockwidth;
-        pData->iDataheight         = iBlockheight;
-      }
-#else
-                                       /* block size specified ? */
-      if (pData->iDHDRdeltatype != MNG_DELTATYPE_NOCHANGE)
-      {                                /* block entirely within target ? */
-        if (pData->iDHDRdeltatype != MNG_DELTATYPE_REPLACE)
-        {
-          if (((pData->iDHDRblockx + pData->iDHDRblockwidth ) > pData->iDatawidth ) ||
-              ((pData->iDHDRblocky + pData->iDHDRblockheight) > pData->iDataheight)    )
-            MNG_ERROR (pData, MNG_INVALIDBLOCK);
-        }
-
-        pData->iDatawidth          = pData->iDHDRblockwidth;
-        pData->iDataheight         = pData->iDHDRblockheight;
-      }
-#endif
-
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-      switch (iDeltatype)              /* determine nr of delta-channels */
-#else
-      switch (pData->iDHDRdeltatype)   /* determine nr of delta-channels */
-#endif
-      {
-         case MNG_DELTATYPE_BLOCKALPHAADD : ;
-         case MNG_DELTATYPE_BLOCKALPHAREPLACE :
-              {
-#ifdef MNG_INCLUDE_JNG
-                if ((pData->iColortype     == MNG_COLORTYPE_GRAYA    ) ||
-                    (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA)    )
-                {
-                  pData->iColortype     = MNG_COLORTYPE_GRAY;
-                  pData->iJHDRcolortype = MNG_COLORTYPE_JPEGGRAY;
-                }
-                else
-                if ((pData->iColortype     == MNG_COLORTYPE_RGBA      ) ||
-                    (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA)    )
-                {
-                  pData->iColortype     = MNG_COLORTYPE_GRAY;
-                  pData->iJHDRcolortype = MNG_COLORTYPE_JPEGGRAY;
-                }
-#else
-                if (pData->iColortype      == MNG_COLORTYPE_GRAYA)
-                  pData->iColortype     = MNG_COLORTYPE_GRAY;
-                else
-                if (pData->iColortype      == MNG_COLORTYPE_RGBA)
-                  pData->iColortype     = MNG_COLORTYPE_GRAY;
-#endif
-                else                   /* target has no alpha; that sucks! */
-                  MNG_ERROR (pData, MNG_TARGETNOALPHA);
-
-                break;
-              }
-
-         case MNG_DELTATYPE_BLOCKCOLORADD : ;
-         case MNG_DELTATYPE_BLOCKCOLORREPLACE :
-              {
-#ifdef MNG_INCLUDE_JNG
-                if ((pData->iColortype     == MNG_COLORTYPE_GRAYA    ) ||
-                    (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA)    )
-                {
-                  pData->iColortype     = MNG_COLORTYPE_GRAY;
-                  pData->iJHDRcolortype = MNG_COLORTYPE_JPEGGRAY;
-                }
-                else
-                if ((pData->iColortype     == MNG_COLORTYPE_RGBA      ) ||
-                    (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA)    )
-                {
-                  pData->iColortype     = MNG_COLORTYPE_RGB;
-                  pData->iJHDRcolortype = MNG_COLORTYPE_JPEGCOLOR;
-                }
-#else
-                if (pData->iColortype == MNG_COLORTYPE_GRAYA)
-                  pData->iColortype = MNG_COLORTYPE_GRAY;
-                else
-                if (pData->iColortype == MNG_COLORTYPE_RGBA)
-                  pData->iColortype = MNG_COLORTYPE_RGB;
-#endif                  
-                else                   /* target has no alpha; that sucks! */
-                  MNG_ERROR (pData, MNG_TARGETNOALPHA);
-
-                break;
-              }
-
-      }
-                                       /* full image replace ? */
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-      if (iDeltatype == MNG_DELTATYPE_REPLACE)
-#else
-      if (pData->iDHDRdeltatype == MNG_DELTATYPE_REPLACE)
-#endif
-      {
-        iRetcode = mng_reset_object_details (pData, pImage,
-                                             pData->iDatawidth, pData->iDataheight,
-                                             pData->iBitdepth, pData->iColortype,
-                                             pData->iCompression, pData->iFilter,
-                                             pData->iInterlace, MNG_FALSE);
-
-        if (iRetcode)                  /* on error bail out */
-          return iRetcode;
-
-        pData->pStoreobj = pImage;     /* and store straight into this object */
-      }
-      else
-      {
-        mng_imagedatap pBufzero, pBuf;
-                                       /* we store in object 0 and process it later */
-        pData->pStoreobj = pData->pObjzero;
-                                       /* make sure to initialize object 0 then */
-        iRetcode = mng_reset_object_details (pData, (mng_imagep)pData->pObjzero,
-                                             pData->iDatawidth, pData->iDataheight,
-                                             pData->iBitdepth, pData->iColortype,
-                                             pData->iCompression, pData->iFilter,
-                                             pData->iInterlace, MNG_TRUE);
-
-        if (iRetcode)                  /* on error bail out */
-          return iRetcode;
-
-        pBuf     = pImage->pImgbuf;    /* copy possible palette & cheap transparency */
-        pBufzero = ((mng_imagep)pData->pObjzero)->pImgbuf;
-
-        pBufzero->bHasPLTE = pBuf->bHasPLTE;
-        pBufzero->bHasTRNS = pBuf->bHasTRNS;
-
-        if (pBufzero->bHasPLTE)        /* copy palette ? */
-        {
-          mng_uint32 iX;
-
-          pBufzero->iPLTEcount = pBuf->iPLTEcount;
-
-          for (iX = 0; iX < pBuf->iPLTEcount; iX++)
-          {
-            pBufzero->aPLTEentries [iX].iRed   = pBuf->aPLTEentries [iX].iRed;
-            pBufzero->aPLTEentries [iX].iGreen = pBuf->aPLTEentries [iX].iGreen;
-            pBufzero->aPLTEentries [iX].iBlue  = pBuf->aPLTEentries [iX].iBlue;
-          }
-        }
-
-        if (pBufzero->bHasTRNS)        /* copy cheap transparency ? */
-        {
-          pBufzero->iTRNSgray  = pBuf->iTRNSgray;
-          pBufzero->iTRNSred   = pBuf->iTRNSred;
-          pBufzero->iTRNSgreen = pBuf->iTRNSgreen;
-          pBufzero->iTRNSblue  = pBuf->iTRNSblue;
-          pBufzero->iTRNScount = pBuf->iTRNScount;
-
-          MNG_COPY (pBufzero->aTRNSentries, pBuf->aTRNSentries,
-                    sizeof (pBufzero->aTRNSentries));
-        }
-                                       /* process immediately if bitdepth & colortype are equal */
-        pData->bDeltaimmediate =
-          (mng_bool)((pData->bDisplaying) && (!pData->bSkipping) &&
-                     ((pData->bRunning) || (pData->bSearching)) &&
-                     (pData->iBitdepth  == ((mng_imagep)pData->pDeltaImage)->pImgbuf->iBitdepth ) &&
-                     (pData->iColortype == ((mng_imagep)pData->pDeltaImage)->pImgbuf->iColortype)    );
-      }
- 
-#ifdef MNG_OPTIMIZE_FOOTPRINT_INIT
-  pData->fInitrowproc = (mng_fptr)mng_init_rowproc;
-  pData->ePng_imgtype = mng_png_imgtype (pData->iColortype, pData->iBitdepth);
-#else
-      switch (pData->iColortype)       /* determine row initialization routine */
-      {
-        case 0 : {                     /* gray */
-                   switch (pData->iBitdepth)
-                   {
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-                     case  1 : {
-                                 if (!pData->iInterlace)
-                                   pData->fInitrowproc = (mng_fptr)mng_init_g1_ni;
-                                 else
-                                   pData->fInitrowproc = (mng_fptr)mng_init_g1_i;
-
-                                 break;
-                               }
-                     case  2 : {
-                                 if (!pData->iInterlace)
-                                   pData->fInitrowproc = (mng_fptr)mng_init_g2_ni;
-                                 else
-                                   pData->fInitrowproc = (mng_fptr)mng_init_g2_i;
-
-                                 break;
-                               }
-                     case  4 : {
-                                 if (!pData->iInterlace)
-                                   pData->fInitrowproc = (mng_fptr)mng_init_g4_ni;
-                                 else
-                                   pData->fInitrowproc = (mng_fptr)mng_init_g4_i;
-
-                                 break;
-                               }
-#endif /* MNG_NO_1_2_4BIT_SUPPORT */
-                     case  8 : {
-                                 if (!pData->iInterlace)
-                                   pData->fInitrowproc = (mng_fptr)mng_init_g8_ni;
-                                 else
-                                   pData->fInitrowproc = (mng_fptr)mng_init_g8_i;
-
-                                 break;
-                               }
-#ifndef MNG_NO_16BIT_SUPPORT
-                     case 16 : {
-                                 if (!pData->iInterlace)
-                                   pData->fInitrowproc = (mng_fptr)mng_init_g16_ni;
-                                 else
-                                   pData->fInitrowproc = (mng_fptr)mng_init_g16_i;
-
-                                 break;
-                               }
-#endif
-                   }
-
-                   break;
-                 }
-        case 2 : {                     /* rgb */
-                   switch (pData->iBitdepth)
-                   {
-                     case  8 : {
-                                 if (!pData->iInterlace)
-                                   pData->fInitrowproc = (mng_fptr)mng_init_rgb8_ni;
-                                 else
-                                   pData->fInitrowproc = (mng_fptr)mng_init_rgb8_i;
-
-                                 break;
-                               }
-#ifndef MNG_NO_16BIT_SUPPORT
-                     case 16 : {
-                                 if (!pData->iInterlace)
-                                   pData->fInitrowproc = (mng_fptr)mng_init_rgb16_ni;
-                                 else
-                                   pData->fInitrowproc = (mng_fptr)mng_init_rgb16_i;
-
-                                 break;
-                               }
-#endif
-                   }
-
-                   break;
-                 }
-        case 3 : {                     /* indexed */
-                   switch (pData->iBitdepth)
-                   {
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-                     case  1 : {
-                                 if (!pData->iInterlace)
-                                   pData->fInitrowproc = (mng_fptr)mng_init_idx1_ni;
-                                 else
-                                   pData->fInitrowproc = (mng_fptr)mng_init_idx1_i;
-
-                                 break;
-                               }
-                     case  2 : {
-                                 if (!pData->iInterlace)
-                                   pData->fInitrowproc = (mng_fptr)mng_init_idx2_ni;
-                                 else
-                                   pData->fInitrowproc = (mng_fptr)mng_init_idx2_i;
-
-                                 break;
-                               }
-                     case  4 : {
-                                 if (!pData->iInterlace)
-                                   pData->fInitrowproc = (mng_fptr)mng_init_idx4_ni;
-                                 else
-                                   pData->fInitrowproc = (mng_fptr)mng_init_idx4_i;
-
-                                 break;
-                               }
-#endif /* MNG_NO_1_2_4BIT_SUPPORT */
-                     case  8 : {
-                                 if (!pData->iInterlace)
-                                   pData->fInitrowproc = (mng_fptr)mng_init_idx8_ni;
-                                 else
-                                   pData->fInitrowproc = (mng_fptr)mng_init_idx8_i;
-
-                                 break;
-                               }
-                   }
-
-                   break;
-                 }
-        case 4 : {                     /* gray+alpha */
-                   switch (pData->iBitdepth)
-                   {
-                     case  8 : {
-                                 if (!pData->iInterlace)
-                                   pData->fInitrowproc = (mng_fptr)mng_init_ga8_ni;
-                                 else
-                                   pData->fInitrowproc = (mng_fptr)mng_init_ga8_i;
-
-                                 break;
-                               }
-#ifndef MNG_NO_16BIT_SUPPORT
-                     case 16 : {
-                                 if (!pData->iInterlace)
-                                   pData->fInitrowproc = (mng_fptr)mng_init_ga16_ni;
-                                 else
-                                   pData->fInitrowproc = (mng_fptr)mng_init_ga16_i;
-
-                                 break;
-                               }
-#endif
-                   }
-
-                   break;
-                 }
-        case 6 : {                     /* rgb+alpha */
-                   switch (pData->iBitdepth)
-                   {
-                     case  8 : {
-                                 if (!pData->iInterlace)
-                                   pData->fInitrowproc = (mng_fptr)mng_init_rgba8_ni;
-                                 else
-                                   pData->fInitrowproc = (mng_fptr)mng_init_rgba8_i;
-
-                                 break;
-                               }
-#ifndef MNG_NO_16BIT_SUPPORT
-                     case 16 : {
-                                 if (!pData->iInterlace)
-                                   pData->fInitrowproc = (mng_fptr)mng_init_rgba16_ni;
-                                 else
-                                   pData->fInitrowproc = (mng_fptr)mng_init_rgba16_i;
-
-                                 break;
-                               }
-#endif
-                   }
-
-                   break;
-                 }
-      }
-#endif /* MNG_OPTIMIZE_FOOTPRINT_INIT */
-    }
-    else
-      MNG_ERROR (pData, MNG_OBJNOTCONCRETE);
-
-  }
-  else
-    MNG_ERROR (pData, MNG_OBJECTUNKNOWN);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_DHDR, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-mng_retcode mng_process_display_prom (mng_datap  pData,
-                                      mng_uint8  iBitdepth,
-                                      mng_uint8  iColortype,
-                                      mng_uint8  iFilltype)
-#else
-mng_retcode mng_process_display_prom (mng_datap  pData)
-#endif
-{
-  mng_imagep     pImage;
-  mng_imagedatap pBuf;
-  mng_retcode    iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_PROM, MNG_LC_START);
-#endif
-
-  if (!pData->pDeltaImage)             /* gotta have this now! */
-    MNG_ERROR (pData, MNG_INVALIDDELTA);
-
-  pImage = (mng_imagep)pData->pDeltaImage;
-  pBuf   = pImage->pImgbuf;
-                                       /* can't demote bitdepth! */
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-  if (iBitdepth < pBuf->iBitdepth)
-    MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
-
-  if ( ((pBuf->iColortype == MNG_COLORTYPE_GRAY      ) &&
-        (iColortype       != MNG_COLORTYPE_GRAY      ) &&
-        (iColortype       != MNG_COLORTYPE_GRAYA     ) &&
-        (iColortype       != MNG_COLORTYPE_RGB       ) &&
-        (iColortype       != MNG_COLORTYPE_RGBA      )    ) ||
-       ((pBuf->iColortype == MNG_COLORTYPE_GRAYA     ) &&
-        (iColortype       != MNG_COLORTYPE_GRAYA     ) &&
-        (iColortype       != MNG_COLORTYPE_RGBA      )    ) ||
-       ((pBuf->iColortype == MNG_COLORTYPE_RGB       ) &&
-        (iColortype       != MNG_COLORTYPE_RGB       ) &&
-        (iColortype       != MNG_COLORTYPE_RGBA      )    ) ||
-       ((pBuf->iColortype == MNG_COLORTYPE_RGBA      ) &&
-        (iColortype       != MNG_COLORTYPE_RGBA      )    ) ||
-#ifdef MNG_INCLUDE_JNG
-       ((pBuf->iColortype == MNG_COLORTYPE_JPEGGRAY  ) &&
-        (iColortype       != MNG_COLORTYPE_JPEGGRAY  ) &&
-        (iColortype       != MNG_COLORTYPE_JPEGCOLOR ) &&
-        (iColortype       != MNG_COLORTYPE_JPEGGRAYA ) &&
-        (iColortype       != MNG_COLORTYPE_JPEGCOLORA)    ) ||
-       ((pBuf->iColortype == MNG_COLORTYPE_JPEGCOLOR ) &&
-        (iColortype       != MNG_COLORTYPE_JPEGCOLOR ) &&
-        (iColortype       != MNG_COLORTYPE_JPEGCOLORA)    ) ||
-       ((pBuf->iColortype == MNG_COLORTYPE_JPEGGRAYA ) &&
-        (iColortype       != MNG_COLORTYPE_JPEGGRAYA ) &&
-        (iColortype       != MNG_COLORTYPE_JPEGCOLORA)    ) ||
-       ((pBuf->iColortype == MNG_COLORTYPE_JPEGCOLORA) &&
-        (iColortype       != MNG_COLORTYPE_JPEGCOLORA)    ) ||
-#endif
-       ((pBuf->iColortype == MNG_COLORTYPE_INDEXED   ) &&
-        (iColortype       != MNG_COLORTYPE_INDEXED   ) &&
-        (iColortype       != MNG_COLORTYPE_RGB       ) &&
-        (iColortype       != MNG_COLORTYPE_RGBA      )    )    )
-    MNG_ERROR (pData, MNG_INVALIDCOLORTYPE);
-
-  iRetcode = mng_promote_imageobject (pData, pImage, iBitdepth, iColortype, iFilltype);
-#else
-  if (pData->iPROMbitdepth < pBuf->iBitdepth)
-    MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
-
-  if ( ((pBuf->iColortype      == MNG_COLORTYPE_GRAY      ) &&
-        (pData->iPROMcolortype != MNG_COLORTYPE_GRAY      ) &&
-        (pData->iPROMcolortype != MNG_COLORTYPE_GRAYA     ) &&
-        (pData->iPROMcolortype != MNG_COLORTYPE_RGB       ) &&
-        (pData->iPROMcolortype != MNG_COLORTYPE_RGBA      )    ) ||
-       ((pBuf->iColortype      == MNG_COLORTYPE_GRAYA     ) &&
-        (pData->iPROMcolortype != MNG_COLORTYPE_GRAYA     ) &&
-        (pData->iPROMcolortype != MNG_COLORTYPE_RGBA      )    ) ||
-       ((pBuf->iColortype      == MNG_COLORTYPE_RGB       ) &&
-        (pData->iPROMcolortype != MNG_COLORTYPE_RGB       ) &&
-        (pData->iPROMcolortype != MNG_COLORTYPE_RGBA      )    ) ||
-       ((pBuf->iColortype      == MNG_COLORTYPE_RGBA      ) &&
-        (pData->iPROMcolortype != MNG_COLORTYPE_RGBA      )    ) ||
-#ifdef MNG_INCLUDE_JNG
-       ((pBuf->iColortype      == MNG_COLORTYPE_JPEGGRAY  ) &&
-        (pData->iPROMcolortype != MNG_COLORTYPE_JPEGGRAY  ) &&
-        (pData->iPROMcolortype != MNG_COLORTYPE_JPEGCOLOR ) &&
-        (pData->iPROMcolortype != MNG_COLORTYPE_JPEGGRAYA ) &&
-        (pData->iPROMcolortype != MNG_COLORTYPE_JPEGCOLORA)    ) ||
-       ((pBuf->iColortype      == MNG_COLORTYPE_JPEGCOLOR ) &&
-        (pData->iPROMcolortype != MNG_COLORTYPE_JPEGCOLOR ) &&
-        (pData->iPROMcolortype != MNG_COLORTYPE_JPEGCOLORA)    ) ||
-       ((pBuf->iColortype      == MNG_COLORTYPE_JPEGGRAYA ) &&
-        (pData->iPROMcolortype != MNG_COLORTYPE_JPEGGRAYA ) &&
-        (pData->iPROMcolortype != MNG_COLORTYPE_JPEGCOLORA)    ) ||
-       ((pBuf->iColortype      == MNG_COLORTYPE_JPEGCOLORA) &&
-        (pData->iPROMcolortype != MNG_COLORTYPE_JPEGCOLORA)    ) ||
-#endif
-       ((pBuf->iColortype      == MNG_COLORTYPE_INDEXED   ) &&
-        (pData->iPROMcolortype != MNG_COLORTYPE_INDEXED   ) &&
-        (pData->iPROMcolortype != MNG_COLORTYPE_RGB       ) &&
-        (pData->iPROMcolortype != MNG_COLORTYPE_RGBA      )    )    )
-    MNG_ERROR (pData, MNG_INVALIDCOLORTYPE);
-
-  iRetcode = mng_promote_imageobject (pData, pImage, pData->iPROMbitdepth,
-                                      pData->iPROMcolortype, pData->iPROMfilltype);
-#endif
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_PROM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-mng_retcode mng_process_display_ipng (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IPNG, MNG_LC_START);
-#endif
-                                       /* indicate it for what it is now */
-  pData->iDeltaImagetype = MNG_IMAGETYPE_PNG;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IPNG, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-#ifdef MNG_INCLUDE_JNG
-mng_retcode mng_process_display_ijng (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IJNG, MNG_LC_START);
-#endif
-                                       /* indicate it for what it is now */
-  pData->iDeltaImagetype = MNG_IMAGETYPE_JNG;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IJNG, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-mng_retcode mng_process_display_pplt (mng_datap      pData,
-                                      mng_uint8      iType,
-                                      mng_uint32     iCount,
-                                      mng_palette8ep paIndexentries,
-                                      mng_uint8p     paAlphaentries,
-                                      mng_uint8p     paUsedentries)
-#else
-mng_retcode mng_process_display_pplt (mng_datap      pData)
-#endif
-{
-  mng_uint32     iX;
-  mng_imagep     pImage = (mng_imagep)pData->pObjzero;
-  mng_imagedatap pBuf   = pImage->pImgbuf;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_PPLT, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-  iX = iCount;
-#else
-  iX = pData->iPPLTcount;
-#endif
-#endif
-
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-  switch (iType)
-#else
-  switch (pData->iPPLTtype)
-#endif
-  {
-    case MNG_DELTATYPE_REPLACERGB :
-      {
-#ifdef MNG_DECREMENT_LOOPS
-        for (; iX > 0;iX--)
-#else
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-        for (iX = 0; iX < iCount; iX++)
-#else
-        for (iX = 0; iX < pData->iPPLTcount; iX++)
-#endif
-#endif
-        {
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-          if (paUsedentries [iX])
-          {
-            pBuf->aPLTEentries [iX].iRed   = paIndexentries [iX].iRed;
-            pBuf->aPLTEentries [iX].iGreen = paIndexentries [iX].iGreen;
-            pBuf->aPLTEentries [iX].iBlue  = paIndexentries [iX].iBlue;
-          }
-#else
-          if (pData->paPPLTusedentries [iX])
-          {
-            pBuf->aPLTEentries [iX].iRed   = pData->paPPLTindexentries [iX].iRed;
-            pBuf->aPLTEentries [iX].iGreen = pData->paPPLTindexentries [iX].iGreen;
-            pBuf->aPLTEentries [iX].iBlue  = pData->paPPLTindexentries [iX].iBlue;
-          }
-#endif
-        }
-
-        break;
-      }
-    case MNG_DELTATYPE_DELTARGB :
-      {
-#ifdef MNG_DECREMENT_LOOPS
-        for (; iX > 0;iX--)
-#else
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-        for (iX = 0; iX < iCount; iX++)
-#else
-        for (iX = 0; iX < pData->iPPLTcount; iX++)
-#endif
-#endif
-        {
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-          if (paUsedentries [iX])
-          {
-            pBuf->aPLTEentries [iX].iRed   =
-                               (mng_uint8)(pBuf->aPLTEentries [iX].iRed   +
-                                           paIndexentries [iX].iRed  );
-            pBuf->aPLTEentries [iX].iGreen =
-                               (mng_uint8)(pBuf->aPLTEentries [iX].iGreen +
-                                           paIndexentries [iX].iGreen);
-            pBuf->aPLTEentries [iX].iBlue  =
-                               (mng_uint8)(pBuf->aPLTEentries [iX].iBlue  +
-                                           paIndexentries [iX].iBlue );
-          }
-#else
-          if (pData->paPPLTusedentries [iX])
-          {
-            pBuf->aPLTEentries [iX].iRed   =
-                               (mng_uint8)(pBuf->aPLTEentries [iX].iRed   +
-                                           pData->paPPLTindexentries [iX].iRed  );
-            pBuf->aPLTEentries [iX].iGreen =
-                               (mng_uint8)(pBuf->aPLTEentries [iX].iGreen +
-                                           pData->paPPLTindexentries [iX].iGreen);
-            pBuf->aPLTEentries [iX].iBlue  =
-                               (mng_uint8)(pBuf->aPLTEentries [iX].iBlue  +
-                                           pData->paPPLTindexentries [iX].iBlue );
-          }
-#endif
-        }
-
-        break;
-      }
-    case MNG_DELTATYPE_REPLACEALPHA :
-      {
-#ifdef MNG_DECREMENT_LOOPS
-        for (; iX > 0;iX--)
-#else
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-        for (iX = 0; iX < iCount; iX++)
-#else
-        for (iX = 0; iX < pData->iPPLTcount; iX++)
-#endif
-#endif
-        {
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-          if (paUsedentries [iX])
-            pBuf->aTRNSentries [iX] = paAlphaentries [iX];
-        }
-#else
-          if (pData->paPPLTusedentries [iX])
-            pBuf->aTRNSentries [iX] = pData->paPPLTalphaentries [iX];
-        }
-#endif
-
-        break;
-      }
-    case MNG_DELTATYPE_DELTAALPHA :
-      {
-#ifdef MNG_DECREMENT_LOOPS
-        for (; iX > 0;iX--)
-#else
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-        for (iX = 0; iX < iCount; iX++)
-#else
-        for (iX = 0; iX < pData->iPPLTcount; iX++)
-#endif
-#endif
-        {
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-          if (paUsedentries [iX])
-            pBuf->aTRNSentries [iX] =
-                               (mng_uint8)(pBuf->aTRNSentries [iX] +
-                                           paAlphaentries [iX]);
-#else
-          if (pData->paPPLTusedentries [iX])
-            pBuf->aTRNSentries [iX] =
-                               (mng_uint8)(pBuf->aTRNSentries [iX] +
-                                           pData->paPPLTalphaentries [iX]);
-#endif
-        }
-
-        break;
-      }
-    case MNG_DELTATYPE_REPLACERGBA :
-      {
-#ifdef MNG_DECREMENT_LOOPS
-        for (; iX > 0;iX--)
-#else
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-        for (iX = 0; iX < iCount; iX++)
-#else
-        for (iX = 0; iX < pData->iPPLTcount; iX++)
-#endif
-#endif
-        {
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-          if (paUsedentries [iX])
-          {
-            pBuf->aPLTEentries [iX].iRed   = paIndexentries [iX].iRed;
-            pBuf->aPLTEentries [iX].iGreen = paIndexentries [iX].iGreen;
-            pBuf->aPLTEentries [iX].iBlue  = paIndexentries [iX].iBlue;
-            pBuf->aTRNSentries [iX]        = paAlphaentries [iX];
-          }
-#else
-          if (pData->paPPLTusedentries [iX])
-          {
-            pBuf->aPLTEentries [iX].iRed   = pData->paPPLTindexentries [iX].iRed;
-            pBuf->aPLTEentries [iX].iGreen = pData->paPPLTindexentries [iX].iGreen;
-            pBuf->aPLTEentries [iX].iBlue  = pData->paPPLTindexentries [iX].iBlue;
-            pBuf->aTRNSentries [iX]        = pData->paPPLTalphaentries [iX];
-          }
-#endif
-        }
-
-        break;
-      }
-    case MNG_DELTATYPE_DELTARGBA :
-      {
-#ifdef MNG_DECREMENT_LOOPS
-        for (; iX > 0;iX--)
-#else
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-        for (iX = 0; iX < iCount; iX++)
-#else
-        for (iX = 0; iX < pData->iPPLTcount; iX++)
-#endif
-#endif
-        {
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-          if (paUsedentries [iX])
-          {
-            pBuf->aPLTEentries [iX].iRed   =
-                               (mng_uint8)(pBuf->aPLTEentries [iX].iRed   +
-                                           paIndexentries [iX].iRed  );
-            pBuf->aPLTEentries [iX].iGreen =
-                               (mng_uint8)(pBuf->aPLTEentries [iX].iGreen +
-                                           paIndexentries [iX].iGreen);
-            pBuf->aPLTEentries [iX].iBlue  =
-                               (mng_uint8)(pBuf->aPLTEentries [iX].iBlue  +
-                                           paIndexentries [iX].iBlue );
-            pBuf->aTRNSentries [iX] =
-                               (mng_uint8)(pBuf->aTRNSentries [iX] +
-                                           paAlphaentries [iX]);
-          }
-#else
-          if (pData->paPPLTusedentries [iX])
-          {
-            pBuf->aPLTEentries [iX].iRed   =
-                               (mng_uint8)(pBuf->aPLTEentries [iX].iRed   +
-                                           pData->paPPLTindexentries [iX].iRed  );
-            pBuf->aPLTEentries [iX].iGreen =
-                               (mng_uint8)(pBuf->aPLTEentries [iX].iGreen +
-                                           pData->paPPLTindexentries [iX].iGreen);
-            pBuf->aPLTEentries [iX].iBlue  =
-                               (mng_uint8)(pBuf->aPLTEentries [iX].iBlue  +
-                                           pData->paPPLTindexentries [iX].iBlue );
-            pBuf->aTRNSentries [iX] =
-                               (mng_uint8)(pBuf->aTRNSentries [iX] +
-                                           pData->paPPLTalphaentries [iX]);
-          }
-#endif
-        }
-
-        break;
-      }
-  }
-
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-  if ((iType != MNG_DELTATYPE_REPLACERGB) && (iType != MNG_DELTATYPE_DELTARGB))
-#else
-  if ((pData->iPPLTtype != MNG_DELTATYPE_REPLACERGB) &&
-      (pData->iPPLTtype != MNG_DELTATYPE_DELTARGB  )    )
-#endif
-  {
-    if (pBuf->bHasTRNS)
-    {
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-      if (iCount > pBuf->iTRNScount)
-        pBuf->iTRNScount = iCount;
-#else
-      if (pData->iPPLTcount > pBuf->iTRNScount)
-        pBuf->iTRNScount = pData->iPPLTcount;
-#endif
-    }
-    else
-    {
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-      pBuf->iTRNScount = iCount;
-      pBuf->bHasTRNS   = MNG_TRUE;
-#else
-      pBuf->iTRNScount = pData->iPPLTcount;
-      pBuf->bHasTRNS   = MNG_TRUE;
-#endif
-    }
-  }
-
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-  if ((iType != MNG_DELTATYPE_REPLACEALPHA) && (iType != MNG_DELTATYPE_DELTAALPHA))
-#else
-  if ((pData->iPPLTtype != MNG_DELTATYPE_REPLACEALPHA) &&
-      (pData->iPPLTtype != MNG_DELTATYPE_DELTAALPHA  )    )
-#endif
-  {
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-    if (iCount > pBuf->iPLTEcount)
-      pBuf->iPLTEcount = iCount;
-#else
-    if (pData->iPPLTcount > pBuf->iPLTEcount)
-      pBuf->iPLTEcount = pData->iPPLTcount;
-#endif
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_PPLT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_MAGN
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-mng_retcode mng_process_display_magn (mng_datap  pData,
-                                      mng_uint16 iFirstid,
-                                      mng_uint16 iLastid,
-                                      mng_uint8  iMethodX,
-                                      mng_uint16 iMX,
-                                      mng_uint16 iMY,
-                                      mng_uint16 iML,
-                                      mng_uint16 iMR,
-                                      mng_uint16 iMT,
-                                      mng_uint16 iMB,
-                                      mng_uint8  iMethodY)
-#else
-mng_retcode mng_process_display_magn (mng_datap  pData)
-#endif
-{
-  mng_uint16 iX;
-  mng_imagep pImage;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MAGN, MNG_LC_START);
-#endif
-                                       /* iterate the object-ids */
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-  for (iX = iFirstid; iX <= iLastid; iX++)
-#else
-  for (iX = pData->iMAGNfirstid; iX <= pData->iMAGNlastid; iX++)
-#endif
-  {
-    if (iX == 0)                       /* process object 0 ? */
-    {
-      pImage = (mng_imagep)pData->pObjzero;
-
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-      pImage->iMAGN_MethodX = iMethodX;
-      pImage->iMAGN_MethodY = iMethodY;
-      pImage->iMAGN_MX      = iMX;
-      pImage->iMAGN_MY      = iMY;
-      pImage->iMAGN_ML      = iML;
-      pImage->iMAGN_MR      = iMR;
-      pImage->iMAGN_MT      = iMT;
-      pImage->iMAGN_MB      = iMB;
-#else
-      pImage->iMAGN_MethodX = pData->iMAGNmethodX;
-      pImage->iMAGN_MethodY = pData->iMAGNmethodY;
-      pImage->iMAGN_MX      = pData->iMAGNmX;
-      pImage->iMAGN_MY      = pData->iMAGNmY;
-      pImage->iMAGN_ML      = pData->iMAGNmL;
-      pImage->iMAGN_MR      = pData->iMAGNmR;
-      pImage->iMAGN_MT      = pData->iMAGNmT;
-      pImage->iMAGN_MB      = pData->iMAGNmB;
-#endif
-    }
-    else
-    {
-      pImage = mng_find_imageobject (pData, iX);
-                                       /* object exists & is not frozen ? */
-      if ((pImage) && (!pImage->bFrozen))
-      {                                /* previous magnification to be done ? */
-        if ((pImage->iMAGN_MethodX) || (pImage->iMAGN_MethodY))
-        {
-          mng_retcode iRetcode = mng_magnify_imageobject (pData, pImage);
-          if (iRetcode)                /* on error bail out */
-            return iRetcode;
-        }
-
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-        pImage->iMAGN_MethodX = iMethodX;
-        pImage->iMAGN_MethodY = iMethodY;
-        pImage->iMAGN_MX      = iMX;
-        pImage->iMAGN_MY      = iMY;
-        pImage->iMAGN_ML      = iML;
-        pImage->iMAGN_MR      = iMR;
-        pImage->iMAGN_MT      = iMT;
-        pImage->iMAGN_MB      = iMB;
-#else
-        pImage->iMAGN_MethodX = pData->iMAGNmethodX;
-        pImage->iMAGN_MethodY = pData->iMAGNmethodY;
-        pImage->iMAGN_MX      = pData->iMAGNmX;
-        pImage->iMAGN_MY      = pData->iMAGNmY;
-        pImage->iMAGN_ML      = pData->iMAGNmL;
-        pImage->iMAGN_MR      = pData->iMAGNmR;
-        pImage->iMAGN_MT      = pData->iMAGNmT;
-        pImage->iMAGN_MB      = pData->iMAGNmB;
-#endif
-      }
-    }
-  }
-
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-  pData->iMAGNfromid = iFirstid;
-  pData->iMAGNtoid   = iLastid;
-  iX                 = iFirstid;
-#else
-  pData->iMAGNfromid = pData->iMAGNfirstid;
-  pData->iMAGNtoid   = pData->iMAGNlastid;
-  iX                 = pData->iMAGNfirstid;
-#endif
-                                       /* iterate again for showing */
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-  while ((iX <= iLastid) && (!pData->bTimerset))
-#else
-  while ((iX <= pData->iMAGNlastid) && (!pData->bTimerset))
-#endif
-  {
-    pData->iMAGNcurrentid = iX;
-
-    if (iX)                            /* only real objects ! */
-    {
-      pImage = mng_find_imageobject (pData, iX);
-                                       /* object exists & is not frozen  &
-                                          is visible & is viewable ? */
-      if ((pImage) && (!pImage->bFrozen) &&
-          (pImage->bVisible) && (pImage->bViewable))
-      {
-        mng_retcode iRetcode = mng_display_image (pData, pImage, MNG_FALSE);
-        if (iRetcode)
-          return iRetcode;
-      }
-    }
-
-    iX++;
-  }
-
-  if (pData->bTimerset)                /* broken ? */
-    pData->iBreakpoint = 9;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MAGN, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_display_magn2 (mng_datap pData)
-{
-  mng_uint16 iX;
-  mng_imagep pImage;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MAGN, MNG_LC_START);
-#endif
-
-  iX = pData->iMAGNcurrentid;
-                                       /* iterate again for showing */
-  while ((iX <= pData->iMAGNtoid) && (!pData->bTimerset))
-  {
-    pData->iMAGNcurrentid = iX;
-
-    if (iX)                            /* only real objects ! */
-    {
-      pImage = mng_find_imageobject (pData, iX);
-                                       /* object exists & is not frozen  &
-                                          is visible & is viewable ? */
-      if ((pImage) && (!pImage->bFrozen) &&
-          (pImage->bVisible) && (pImage->bViewable))
-      {
-        mng_retcode iRetcode = mng_display_image (pData, pImage, MNG_FALSE);
-        if (iRetcode)
-          return iRetcode;
-      }
-    }
-
-    iX++;
-  }
-
-  if (pData->bTimerset)                /* broken ? */
-    pData->iBreakpoint = 9;
-  else
-    pData->iBreakpoint = 0;            /* not again ! */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MAGN, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_PAST
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-mng_retcode mng_process_display_past (mng_datap  pData,
-                                      mng_uint16 iTargetid,
-                                      mng_uint8  iTargettype,
-                                      mng_int32  iTargetx,
-                                      mng_int32  iTargety,
-                                      mng_uint32 iCount,
-                                      mng_ptr    pSources)
-#else
-mng_retcode mng_process_display_past (mng_datap  pData)
-#endif
-{
-  mng_retcode      iRetcode = MNG_NOERROR;
-  mng_imagep       pTargetimg;
-  mng_imagep       pSourceimg;
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-  mng_past_sourcep pSource = (mng_past_sourcep)pSources;
-#else
-  mng_past_sourcep pSource = (mng_past_sourcep)pData->pPASTsources;
-#endif
-  mng_uint32       iX      = 0;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_PAST, MNG_LC_START);
-#endif
-
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-  if (iTargetid)                       /* a real destination object ? */
-#else
-  if (pData->iPASTtargetid)            /* a real destination object ? */
-#endif
-  {                                    /* let's find it then */
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-    pTargetimg = (mng_imagep)mng_find_imageobject (pData, iTargetid);
-#else
-    pTargetimg = (mng_imagep)mng_find_imageobject (pData, pData->iPASTtargetid);
-#endif
-
-    if (!pTargetimg)                   /* if it doesn't exists; do a barf */
-      MNG_ERROR (pData, MNG_OBJECTUNKNOWN);
-                                       /* it's gotta be abstract !!! */
-    if (pTargetimg->pImgbuf->bConcrete)
-      MNG_ERROR (pData, MNG_OBJNOTABSTRACT);
-                                       /* we want 32-/64-bit RGBA to play with ! */
-    if ((pTargetimg->pImgbuf->iBitdepth <= MNG_BITDEPTH_8)          ||
-        (pTargetimg->pImgbuf->iColortype ==  MNG_COLORTYPE_GRAY)    ||
-        (pTargetimg->pImgbuf->iColortype ==  MNG_COLORTYPE_RGB)     ||
-        (pTargetimg->pImgbuf->iColortype ==  MNG_COLORTYPE_INDEXED) ||
-        (pTargetimg->pImgbuf->iColortype ==  MNG_COLORTYPE_GRAYA)      )
-      iRetcode = mng_promote_imageobject (pData, pTargetimg, MNG_BITDEPTH_8,
-                                          MNG_COLORTYPE_RGBA,
-                                          MNG_FILLMETHOD_LEFTBITREPLICATE);
-    else
-    if ((pTargetimg->pImgbuf->iBitdepth > MNG_BITDEPTH_8)              &&
-        ((pTargetimg->pImgbuf->iColortype ==  MNG_COLORTYPE_GRAY)  ||
-         (pTargetimg->pImgbuf->iColortype ==  MNG_COLORTYPE_RGB)   ||
-         (pTargetimg->pImgbuf->iColortype ==  MNG_COLORTYPE_GRAYA)    )   )
-      iRetcode = mng_promote_imageobject (pData, pTargetimg, MNG_BITDEPTH_16,
-                                          MNG_COLORTYPE_RGBA,
-                                          MNG_FILLMETHOD_LEFTBITREPLICATE);
-#ifdef MNG_INCLUDE_JNG
-    else
-    if ((pTargetimg->pImgbuf->iColortype ==  MNG_COLORTYPE_JPEGGRAY)  ||
-        (pTargetimg->pImgbuf->iColortype ==  MNG_COLORTYPE_JPEGCOLOR) ||
-        (pTargetimg->pImgbuf->iColortype ==  MNG_COLORTYPE_JPEGGRAYA)    )
-      iRetcode = mng_promote_imageobject (pData, pTargetimg,
-                                          pTargetimg->pImgbuf->iBitdepth,
-                                          MNG_COLORTYPE_JPEGCOLORA,
-                                          MNG_FILLMETHOD_LEFTBITREPLICATE);
-#endif
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-                                       /* make it really abstract ? */
-    if (!pTargetimg->pImgbuf->bCorrected)
-    {
-      iRetcode = mng_colorcorrect_object (pData, pTargetimg);
-
-      if (iRetcode)                    /* on error bail out */
-        return iRetcode;
-    }
-  }
-  else
-  {                                    /* pasting into object 0 !!! */
-    pTargetimg = (mng_imagep)pData->pObjzero;
-                                       /* is it usable ??? */
-    if ((pTargetimg->bClipped) &&
-        (pTargetimg->iClipr > pTargetimg->iPosx) &&
-        (pTargetimg->iClipb > pTargetimg->iPosy))
-    {
-                                       /* make it 32-bit RGBA please !!! */
-      iRetcode = mng_reset_object_details (pData, pTargetimg,
-                                           pTargetimg->iClipr - pTargetimg->iPosx,
-                                           pTargetimg->iClipb - pTargetimg->iPosy,
-                                           MNG_BITDEPTH_8, MNG_COLORTYPE_RGBA,
-                                           0, 0, 0, MNG_FALSE);
-
-      if (iRetcode)                    /* on error bail out */
-        return iRetcode;
-    }
-    else
-      pTargetimg = MNG_NULL;           /* clipped beyond visibility ! */
-  }
-
-  if (pTargetimg)                      /* usable destination ? */
-  {
-    mng_int32      iSourceY;
-    mng_int32      iSourceYinc;
-    mng_int32      iSourcerowsize;
-    mng_int32      iSourcesamples;
-    mng_bool       bSourceRGBA16;
-    mng_int32      iTargetY;
-    mng_int32      iTargetrowsize;
-    mng_int32      iTargetsamples;
-    mng_bool       bTargetRGBA16 = MNG_FALSE;
-    mng_int32      iTemprowsize;
-    mng_imagedatap pBuf;
-#ifndef MNG_SKIPCHUNK_MAGN
-                                       /* needs magnification ? */
-    if ((pTargetimg->iMAGN_MethodX) || (pTargetimg->iMAGN_MethodY))
-      iRetcode = mng_magnify_imageobject (pData, pTargetimg);
-#endif
-
-    if (!iRetcode)                     /* still ok ? */
-    {
-      bTargetRGBA16 = (mng_bool)(pTargetimg->pImgbuf->iBitdepth > 8);
-
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-      switch (iTargettype)             /* determine target x/y */
-#else
-      switch (pData->iPASTtargettype)  /* determine target x/y */
-#endif
-      {
-        case 0 : {
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-                   pData->iPastx = iTargetx;
-                   pData->iPasty = iTargety;
-#else
-                   pData->iPastx = pData->iPASTtargetx;
-                   pData->iPasty = pData->iPASTtargety;
-#endif
-                   break;
-                 }
-
-        case 1 : {
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-                   pData->iPastx = pTargetimg->iPastx + iTargetx;
-                   pData->iPasty = pTargetimg->iPasty + iTargety;
-#else
-                   pData->iPastx = pTargetimg->iPastx + pData->iPASTtargetx;
-                   pData->iPasty = pTargetimg->iPasty + pData->iPASTtargety;
-#endif
-                   break;
-                 }
-
-        case 2 : {
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-                   pData->iPastx += iTargetx;
-                   pData->iPasty += iTargety;
-#else
-                   pData->iPastx += pData->iPASTtargetx;
-                   pData->iPasty += pData->iPASTtargety;
-#endif
-                   break;
-                 }
-      }
-                                       /* save for next time ... */
-      pTargetimg->iPastx      = pData->iPastx;
-      pTargetimg->iPasty      = pData->iPasty;
-                                       /* address destination for row-routines */
-      pData->pStoreobj        = (mng_objectp)pTargetimg;
-      pData->pStorebuf        = (mng_objectp)pTargetimg->pImgbuf;
-    }
-                                       /* process the sources one by one */
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-    while ((!iRetcode) && (iX < iCount))
-#else
-    while ((!iRetcode) && (iX < pData->iPASTcount))
-#endif
-    {                                  /* find the little bastards first */
-      pSourceimg              = (mng_imagep)mng_find_imageobject (pData, pSource->iSourceid);
-                                       /* exists and viewable? */
-      if ((pSourceimg) && (pSourceimg->bViewable))
-      {                                /* needs magnification ? */
-#ifndef MNG_SKIPCHUNK_MAGN
-        if ((pSourceimg->iMAGN_MethodX) || (pSourceimg->iMAGN_MethodY))
-          iRetcode = mng_magnify_imageobject (pData, pSourceimg);
-#endif
-
-        if (!iRetcode)                 /* still ok ? */
-        {
-          pBuf                = (mng_imagedatap)pSourceimg->pImgbuf;
-                                       /* address source for row-routines */
-          pData->pRetrieveobj = (mng_objectp)pSourceimg;
-
-          pData->iPass        = -1;    /* init row-processing variables */
-          pData->iRowinc      = 1;
-          pData->iColinc      = 1;
-          pData->iPixelofs    = 0;
-          iSourcesamples      = (mng_int32)pBuf->iWidth;
-          iSourcerowsize      = pBuf->iRowsize;
-          bSourceRGBA16       = (mng_bool)(pBuf->iBitdepth > 8);
-                                       /* make sure the delta-routines do the right thing */
-          pData->iDeltatype   = MNG_DELTATYPE_BLOCKPIXELREPLACE;
-
-          switch (pBuf->iColortype)
-          {
-            case  0 : { 
-#ifndef MNG_NO_16BIT_SUPPORT
-                         if (bSourceRGBA16)
-                          pData->fRetrieverow = (mng_fptr)mng_retrieve_g16;
-                        else
-#endif
-                          pData->fRetrieverow = (mng_fptr)mng_retrieve_g8;
-
-                        pData->bIsOpaque      = (mng_bool)(!pBuf->bHasTRNS);
-                        break;
-                      }
-
-            case  2 : {
-#ifndef MNG_NO_16BIT_SUPPORT
-                        if (bSourceRGBA16)
-                          pData->fRetrieverow = (mng_fptr)mng_retrieve_rgb16;
-                        else
-#endif
-                          pData->fRetrieverow = (mng_fptr)mng_retrieve_rgb8;
-
-                        pData->bIsOpaque      = (mng_bool)(!pBuf->bHasTRNS);
-                        break;
-                      }
-
-
-            case  3 : { pData->fRetrieverow   = (mng_fptr)mng_retrieve_idx8;
-                        pData->bIsOpaque      = (mng_bool)(!pBuf->bHasTRNS);
-                        break;
-                      }
-
-
-            case  4 : {
-#ifndef MNG_NO_16BIT_SUPPORT
-                        if (bSourceRGBA16)
-                          pData->fRetrieverow = (mng_fptr)mng_retrieve_ga16;
-                        else
-#endif
-                          pData->fRetrieverow = (mng_fptr)mng_retrieve_ga8;
-
-                        pData->bIsOpaque      = MNG_FALSE;
-                        break;
-                      }
-
-
-            case  6 : {
-#ifndef MNG_NO_16BIT_SUPPORT
-                         if (bSourceRGBA16)
-                          pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba16;
-                        else
-#endif
-                          pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba8;
-
-                        pData->bIsOpaque      = MNG_FALSE;
-                        break;
-                      }
-
-            case  8 : {
-#ifndef MNG_NO_16BIT_SUPPORT
-                         if (bSourceRGBA16)
-                          pData->fRetrieverow = (mng_fptr)mng_retrieve_g16;
-                        else
-#endif
-                          pData->fRetrieverow = (mng_fptr)mng_retrieve_g8;
-
-                        pData->bIsOpaque      = MNG_TRUE;
-                        break;
-                      }
-
-            case 10 : {
-#ifndef MNG_NO_16BIT_SUPPORT
-                         if (bSourceRGBA16)
-                          pData->fRetrieverow = (mng_fptr)mng_retrieve_rgb16;
-                        else
-#endif
-                          pData->fRetrieverow = (mng_fptr)mng_retrieve_rgb8;
-
-                        pData->bIsOpaque      = MNG_TRUE;
-                        break;
-                      }
-
-
-            case 12 : {
-#ifndef MNG_NO_16BIT_SUPPORT
-                         if (bSourceRGBA16)
-                          pData->fRetrieverow = (mng_fptr)mng_retrieve_ga16;
-                        else
-#endif
-                          pData->fRetrieverow = (mng_fptr)mng_retrieve_ga8;
-
-                        pData->bIsOpaque      = MNG_FALSE;
-                        break;
-                      }
-
-
-            case 14 : {
-#ifndef MNG_NO_16BIT_SUPPORT
-                         if (bSourceRGBA16)
-                          pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba16;
-                        else
-#endif
-                          pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba8;
-
-                        pData->bIsOpaque      = MNG_FALSE;
-                        break;
-                      }
-          }
-                                       /* determine scaling */
-#ifndef MNG_NO_16BIT_SUPPORT
-#ifndef MNG_NO_DELTA_PNG
-          if ((!bSourceRGBA16) && (bTargetRGBA16))
-            pData->fScalerow = (mng_fptr)mng_scale_rgba8_rgba16;
-          else
-          if ((bSourceRGBA16) && (!bTargetRGBA16))
-            pData->fScalerow = (mng_fptr)mng_scale_rgba16_rgba8;
-          else
-#endif
-#endif
-            pData->fScalerow = MNG_NULL;
-
-                                       /* default no color-correction */
-          pData->fCorrectrow = MNG_NULL;
-
-#if defined(MNG_FULL_CMS)              /* determine color-management routine */
-          iRetcode = mng_init_full_cms   (pData, MNG_FALSE, MNG_FALSE, MNG_TRUE);
-#elif defined(MNG_GAMMA_ONLY)
-          iRetcode = mng_init_gamma_only (pData, MNG_FALSE, MNG_FALSE, MNG_TRUE);
-#elif defined(MNG_APP_CMS)
-          iRetcode = mng_init_app_cms    (pData, MNG_FALSE, MNG_FALSE, MNG_TRUE);
-#endif
-        }
-
-        if (!iRetcode)                 /* still ok ? */
-        {  
-          pData->fFliprow = MNG_NULL;  /* no flipping or tiling by default */
-          pData->fTilerow = MNG_NULL;
-                                       /* but perhaps we do have to ... */
-          switch (pSource->iOrientation)
-          {
-            case 2 : ;
-            case 4 : {
-#ifndef MNG_NO_16BIT_SUPPORT
-                       if (bTargetRGBA16)
-                         pData->fFliprow = (mng_fptr)mng_flip_rgba16;
-                       else
-#endif
-                         pData->fFliprow = (mng_fptr)mng_flip_rgba8;
-                       break;
-                     }
-
-            case 8 : {
-#ifndef MNG_NO_16BIT_SUPPORT
-                       if (bTargetRGBA16)
-                         pData->fTilerow = (mng_fptr)mng_tile_rgba16;
-                       else
-#endif
-                         pData->fTilerow = (mng_fptr)mng_tile_rgba8;
-                       break;
-                     }
-          }
-                                       /* determine composition routine */
-                                       /* note that we're abusing the delta-routine setup !!! */
-          switch (pSource->iComposition)
-          {
-            case 0 : {                 /* composite over */
-#ifndef MNG_NO_16BIT_SUPPORT
-                       if (bTargetRGBA16)
-                         pData->fDeltarow = (mng_fptr)mng_composeover_rgba16;
-                       else
-#endif
-                         pData->fDeltarow = (mng_fptr)mng_composeover_rgba8;
-                       break;
-                     }
-
-            case 1 : {                 /* replace */
-#ifndef MNG_NO_16BIT_SUPPORT
-                       if (bTargetRGBA16)
-                         pData->fDeltarow = (mng_fptr)mng_delta_rgba16_rgba16;
-                       else
-#endif
-                         pData->fDeltarow = (mng_fptr)mng_delta_rgba8_rgba8;
-                       break;
-                     }
-
-            case 2 : {                 /* composite under */
-#ifndef MNG_NO_16BIT_SUPPORT
-                       if (bTargetRGBA16)
-                         pData->fDeltarow = (mng_fptr)mng_composeunder_rgba16;
-                       else
-#endif
-                         pData->fDeltarow = (mng_fptr)mng_composeunder_rgba8;
-                       break;
-                     }
-          }
-                                       /* determine offsets & clipping */
-          if (pSource->iOffsettype == 1)
-          {
-            pData->iDestl          = pData->iPastx + pSource->iOffsetx;
-            pData->iDestt          = pData->iPasty + pSource->iOffsety;
-          }
-          else
-          {
-            pData->iDestl          = pSource->iOffsetx;
-            pData->iDestt          = pSource->iOffsety;
-          }
-
-          pData->iDestr            = (mng_int32)pTargetimg->pImgbuf->iWidth;
-          pData->iDestb            = (mng_int32)pTargetimg->pImgbuf->iHeight;
-                                       /* take the source dimension into account ? */
-          if (pSource->iOrientation != 8)
-          {
-            pData->iDestr          = MIN_COORD (pData->iDestr, pData->iDestl + (mng_int32)pBuf->iWidth);
-            pData->iDestb          = MIN_COORD (pData->iDestb, pData->iDestt + (mng_int32)pBuf->iHeight);
-          }
-                                       /* source clipping */
-          if (pSource->iBoundarytype == 1)
-          {
-            if (pData->iDestl < pData->iPastx + pSource->iBoundaryl)
-              pData->iSourcel      = pData->iPastx + pSource->iBoundaryl - pData->iDestl;
-            else
-              pData->iSourcel      = 0;
-
-            if (pData->iDestt < pData->iPasty + pSource->iBoundaryt)
-              pData->iSourcet      = pData->iPasty + pSource->iBoundaryt - pData->iDestt;
-            else
-              pData->iSourcet      = 0;
-
-            pData->iDestl          = MAX_COORD (pData->iDestl, pData->iPastx + pSource->iBoundaryl);
-            pData->iDestt          = MAX_COORD (pData->iDestt, pData->iPasty + pSource->iBoundaryt);
-            pData->iDestr          = MIN_COORD (pData->iDestr, pData->iPastx + pSource->iBoundaryr);
-            pData->iDestb          = MIN_COORD (pData->iDestb, pData->iPasty + pSource->iBoundaryb);
-          }
-          else
-          {
-            if (pData->iDestl < pSource->iBoundaryl)
-              pData->iSourcel      = pSource->iBoundaryl - pData->iDestl;
-            else
-              pData->iSourcel      = 0;
-
-            if (pData->iDestt < pSource->iBoundaryt)
-              pData->iSourcet      = pSource->iBoundaryt - pData->iDestt;
-            else
-              pData->iSourcet      = 0;
-
-            pData->iDestl          = MAX_COORD (pData->iDestl, pSource->iBoundaryl);
-            pData->iDestt          = MAX_COORD (pData->iDestt, pSource->iBoundaryt);
-            pData->iDestr          = MIN_COORD (pData->iDestr, pSource->iBoundaryr);
-            pData->iDestb          = MIN_COORD (pData->iDestb, pSource->iBoundaryb);
-          }
-
-          if (pData->iSourcel)         /* indent source ? */
-          {
-#ifndef MNG_NO_16BIT_SUPPORT
-             if (bTargetRGBA16)        /* abuse tiling routine to shift source-pixels */
-               pData->fTilerow = (mng_fptr)mng_tile_rgba16;
-             else
-#endif
-               pData->fTilerow = (mng_fptr)mng_tile_rgba8;
-          }
-                                       /* anything to display ? */
-          if ((pData->iDestl <= pData->iDestr) && (pData->iDestt <= pData->iDestb))
-          {                            /* init variables for the loop */
-            if ((pSource->iOrientation == 2) || (pSource->iOrientation == 6))
-            {
-              iSourceY             = (mng_int32)pBuf->iHeight - 1 - pData->iSourcet;
-              iSourceYinc          = -1;
-            }
-            else
-            {
-              iSourceY             = pData->iSourcet;
-              iSourceYinc          = 1;
-            }
-
-            iTargetY               = pData->iDestt;
-            pData->iCol            = pData->iDestl;
-
-            iTargetsamples         = pData->iDestr - pData->iDestl;
-
-#ifndef MNG_NO_16BIT_SUPPORT
-            if (bTargetRGBA16)
-              iTargetrowsize       = (iTargetsamples << 3);
-            else
-#endif
-              iTargetrowsize       = (iTargetsamples << 2);
-
-                                       /* get temporary work-buffers */
-            if (iSourcerowsize > iTargetrowsize)
-              iTemprowsize         = iSourcerowsize << 1;
-            else
-              iTemprowsize         = iTargetrowsize << 1;
-            MNG_ALLOC (pData, pData->pRGBArow, iTemprowsize);
-            MNG_ALLOC (pData, pData->pWorkrow, iTemprowsize);
-
-            while ((!iRetcode) && (iTargetY < pData->iDestb))
-            {                          /* get a row */
-              pData->iRow          = iSourceY;
-              pData->iRowsamples   = iSourcesamples;
-              pData->iRowsize      = iSourcerowsize;
-              pData->bIsRGBA16     = bSourceRGBA16;
-              iRetcode             = ((mng_retrieverow)pData->fRetrieverow) (pData);
-                                       /* scale it (if necessary) */
-              if ((!iRetcode) && (pData->fScalerow))
-                iRetcode           = ((mng_scalerow)pData->fScalerow) (pData);
-
-              pData->bIsRGBA16     = bTargetRGBA16;
-                                       /* color correction (if necessary) */
-              if ((!iRetcode) && (pData->fCorrectrow))
-                iRetcode           = ((mng_correctrow)pData->fCorrectrow) (pData);
-                                       /* flipping (if necessary) */
-              if ((!iRetcode) && (pData->fFliprow))
-                iRetcode           = ((mng_fliprow)pData->fFliprow) (pData);
-                                       /* tiling (if necessary) */
-              if ((!iRetcode) && (pData->fTilerow))
-                iRetcode           = ((mng_tilerow)pData->fTilerow) (pData);
-
-              if (!iRetcode)           /* and paste..... */
-              {
-                pData->iRow        = iTargetY;
-                pData->iRowsamples = iTargetsamples;
-                pData->iRowsize    = iTargetrowsize;
-                iRetcode           = ((mng_deltarow)pData->fDeltarow) (pData);
-              }
-
-              iSourceY += iSourceYinc; /* and next line */
-
-              if (iSourceY < 0)
-                iSourceY = (mng_int32)pBuf->iHeight - 1;
-              else
-              if (iSourceY >= (mng_int32)pBuf->iHeight)
-                iSourceY = 0;
-
-              iTargetY++;
-            }
-                                       /* drop the temporary row-buffer */
-            MNG_FREEX (pData, pData->pWorkrow, iTemprowsize);
-            MNG_FREEX (pData, pData->pRGBArow, iTemprowsize);
-          }
-
-#if defined(MNG_FULL_CMS)              /* cleanup cms stuff */
-          if (!iRetcode)
-            iRetcode = mng_clear_cms (pData);
-#endif
-        }
-
-        pSource++;                     /* neeeeext */
-        iX++;
-      }
-    }
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-    if (!iTargetid)                    /* did we paste into object 0 ? */
-#else
-    if (!pData->iPASTtargetid)         /* did we paste into object 0 ? */
-#endif
-    {                                  /* display it then ! */
-      iRetcode = mng_display_image (pData, pTargetimg, MNG_FALSE);
-      if (iRetcode)                    /* on error bail out */
-        return iRetcode;
-    }
-    else
-    {                                  /* target is visible & viewable ? */
-      if ((pTargetimg->bVisible) && (pTargetimg->bViewable))
-      {
-        iRetcode = mng_display_image (pData, pTargetimg, MNG_FALSE);
-        if (iRetcode)
-          return iRetcode;
-      }
-    }  
-  }
-
-  if (pData->bTimerset)                /* broken ? */
-  {
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-    pData->iPASTid     = iTargetid;
-#else
-    pData->iPASTid     = pData->iPASTtargetid;
-#endif
-    pData->iBreakpoint = 11;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_PAST, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SKIPCHUNK_PAST */
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_PAST
-mng_retcode mng_process_display_past2 (mng_datap pData)
-{
-  mng_retcode iRetcode;
-  mng_imagep  pTargetimg;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_PAST, MNG_LC_START);
-#endif
-
-  if (pData->iPASTid)                  /* a real destination object ? */
-    pTargetimg = (mng_imagep)mng_find_imageobject (pData, pData->iPASTid);
-  else                                 /* otherwise object 0 */
-    pTargetimg = (mng_imagep)pData->pObjzero;
-
-  iRetcode = mng_display_image (pData, pTargetimg, MNG_FALSE);
-  if (iRetcode)
-    return iRetcode;
-
-  pData->iBreakpoint = 0;              /* only once */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_PAST, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SKIPCHUNK_PAST */
-
-/* ************************************************************************** */
-
-#endif /* MNG_INCLUDE_DISPLAY_PROCS */
-
-/* ************************************************************************** */
-/* * end of file                                                            * */
-/* ************************************************************************** */
-
-
diff --git a/Source/LibMNG/libmng_display.h b/Source/LibMNG/libmng_display.h
deleted file mode 100644
index f394dd2..0000000
--- a/Source/LibMNG/libmng_display.h
+++ /dev/null
@@ -1,343 +0,0 @@
-/* ************************************************************************** */
-/* *             For conditions of distribution and use,                    * */
-/* *                see copyright notice in libmng.h                        * */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * project   : libmng                                                     * */
-/* * file      : libmng_display.h          copyright (c) 2000-2007 G.Juyn   * */
-/* * version   : 1.0.10                                                     * */
-/* *                                                                        * */
-/* * purpose   : Display management (definition)                            * */
-/* *                                                                        * */
-/* * author    : G.Juyn                                                     * */
-/* *                                                                        * */
-/* * comment   : Definition of the display managament routines              * */
-/* *                                                                        * */
-/* * changes   : 0.5.1 - 05/08/2000 - G.Juyn                                * */
-/* *             - changed strict-ANSI stuff                                * */
-/* *                                                                        * */
-/* *             0.5.2 - 05/20/2000 - G.Juyn                                * */
-/* *             - added JNG support stuff                                  * */
-/* *                                                                        * */
-/* *             0.5.3 - 06/16/2000 - G.Juyn                                * */
-/* *             - changed progressive-display processing                   * */
-/* *             0.5.3 - 06/22/2000 - G.Juyn                                * */
-/* *             - added support for delta-image processing                 * */
-/* *             - added support for PPLT chunk processing                  * */
-/* *                                                                        * */
-/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
-/* *             - changed file-prefixes                                    * */
-/* *             0.9.3 - 08/07/2000 - G.Juyn                                * */
-/* *             - B111300 - fixup for improved portability                 * */
-/* *             0.9.3 - 08/26/2000 - G.Juyn                                * */
-/* *             - added MAGN chunk                                         * */
-/* *             0.9.3 - 10/16/2000 - G.Juyn                                * */
-/* *             - added JDAA chunk                                         * */
-/* *                                                                        * */
-/* *             0.9.4 - 11/24/2000 - G.Juyn                                * */
-/* *             - moved restore of object 0 to libmng_display              * */
-/* *                                                                        * */
-/* *             1.0.5 - 08/19/2002 - G.Juyn                                * */
-/* *             - B597134 - libmng pollutes the linker namespace           * */
-/* *             1.0.5 - 09/13/2002 - G.Juyn                                * */
-/* *             - fixed read/write of MAGN chunk                           * */
-/* *             1.0.5 - 09/20/2002 - G.Juyn                                * */
-/* *             - added support for PAST                                   * */
-/* *             1.0.5 - 10/07/2002 - G.Juyn                                * */
-/* *             - added proposed change in handling of TERM- & if-delay    * */
-/* *             1.0.5 - 10/20/2002 - G.Juyn                                * */
-/* *             - fixed display of visible target of PAST operation        * */
-/* *                                                                        * */
-/* *             1.0.7 - 03/24/2004 - G.R-P.                                * */
-/* *             - added some SKIPCHUNK conditionals                        * */
-/* *                                                                        * */
-/* *             1.0.9 - 12/11/2004 - G.Juyn                                * */
-/* *             - added conditional MNG_OPTIMIZE_DISPLAYCALLS              * */
-/* *                                                                        * */
-/* *             1.0.10 - 04/08/2007 - G.Juyn                               * */
-/* *             - added support for mPNG proposal                          * */
-/* *             1.0.10 - 04/12/2007 - G.Juyn                               * */
-/* *             - added support for ANG proposal                           * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
-#pragma option -A                      /* force ANSI-C */
-#endif
-
-#ifndef _libmng_display_h_
-#define _libmng_display_h_
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_DISPLAY_PROCS
-
-/* ************************************************************************** */
-
-mng_retcode mng_display_progressive_refresh (mng_datap  pData,
-                                             mng_uint32 iInterval);
-
-/* ************************************************************************** */
-
-mng_retcode mng_reset_objzero         (mng_datap      pData);
-
-mng_retcode mng_display_image         (mng_datap      pData,
-                                       mng_imagep     pImage,
-                                       mng_bool       bLayeradvanced);
-
-mng_retcode mng_execute_delta_image   (mng_datap      pData,
-                                       mng_imagep     pTarget,
-                                       mng_imagep     pDelta);
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_display       (mng_datap      pData);
-
-/* ************************************************************************** */
-
-#ifdef MNG_OPTIMIZE_FOOTPRINT_INIT
-png_imgtype mng_png_imgtype           (mng_uint8      colortype,
-                                       mng_uint8      bitdepth);
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-
-mng_retcode mng_process_display_ihdr  (mng_datap      pData);
-
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-mng_retcode mng_process_display_mpng  (mng_datap      pData);
-#endif
-
-#ifdef MNG_INCLUDE_ANG_PROPOSAL
-mng_retcode mng_process_display_ang   (mng_datap      pData);
-#endif
-
-mng_retcode mng_process_display_idat  (mng_datap      pData,
-                                       mng_uint32     iRawlen,
-                                       mng_uint8p     pRawdata);
-
-mng_retcode mng_process_display_iend  (mng_datap      pData);
-mng_retcode mng_process_display_mend  (mng_datap      pData);
-mng_retcode mng_process_display_mend2 (mng_datap      pData);
-mng_retcode mng_process_display_defi  (mng_datap      pData);
-
-#ifndef MNG_SKIPCHUNK_BASI
-mng_retcode mng_process_display_basi  (mng_datap      pData,
-                                       mng_uint16     iRed,
-                                       mng_uint16     iGreen,
-                                       mng_uint16     iBlue,
-                                       mng_bool       bHasalpha,
-                                       mng_uint16     iAlpha,
-                                       mng_uint8      iViewable);
-#endif
-
-#ifndef MNG_SKIPCHUNK_CLON
-mng_retcode mng_process_display_clon  (mng_datap      pData,
-                                       mng_uint16     iSourceid,
-                                       mng_uint16     iCloneid,
-                                       mng_uint8      iClonetype,
-                                       mng_bool       bHasdonotshow,
-                                       mng_uint8      iDonotshow,
-                                       mng_uint8      iConcrete,
-                                       mng_bool       bHasloca,
-                                       mng_uint8      iLocationtype,
-                                       mng_int32      iLocationx,
-                                       mng_int32      iLocationy);
-mng_retcode mng_process_display_clon2 (mng_datap      pData);
-#endif
-
-#ifndef MNG_SKIPCHUNK_DISC
-mng_retcode mng_process_display_disc  (mng_datap      pData,
-                                       mng_uint32     iCount,
-                                       mng_uint16p    pIds);
-#endif
-
-#ifndef MNG_SKIPCHUNK_FRAM
-mng_retcode mng_process_display_fram  (mng_datap      pData,
-                                       mng_uint8      iFramemode,
-                                       mng_uint8      iChangedelay,
-                                       mng_uint32     iDelay,
-                                       mng_uint8      iChangetimeout,
-                                       mng_uint32     iTimeout,
-                                       mng_uint8      iChangeclipping,
-                                       mng_uint8      iCliptype,
-                                       mng_int32      iClipl,
-                                       mng_int32      iClipr,
-                                       mng_int32      iClipt,
-                                       mng_int32      iClipb);
-mng_retcode mng_process_display_fram2 (mng_datap      pData);
-#endif
-
-#ifndef MNG_SKIPCHUNK_MOVE
-mng_retcode mng_process_display_move  (mng_datap      pData,
-                                       mng_uint16     iFromid,
-                                       mng_uint16     iToid,
-                                       mng_uint8      iMovetype,
-                                       mng_int32      iMovex,
-                                       mng_int32      iMovey);
-#endif
-
-#ifndef MNG_SKIPCHUNK_CLIP
-mng_retcode mng_process_display_clip  (mng_datap      pData,
-                                       mng_uint16     iFromid,
-                                       mng_uint16     iToid,
-                                       mng_uint8      iCliptype,
-                                       mng_int32      iClipl,
-                                       mng_int32      iClipr,
-                                       mng_int32      iClipt,
-                                       mng_int32      iClipb);
-#endif
-
-#ifndef MNG_SKIPCHUNK_SHOW
-mng_retcode mng_process_display_show  (mng_datap      pData);
-#endif
-#ifndef MNG_SKIPCHUNK_SAVE
-mng_retcode mng_process_display_save  (mng_datap      pData);
-#endif
-#ifndef MNG_SKIPCHUNK_SEEK
-mng_retcode mng_process_display_seek  (mng_datap      pData);
-#endif
-#ifdef MNG_INCLUDE_JNG
-mng_retcode mng_process_display_jhdr  (mng_datap      pData);
-
-mng_retcode mng_process_display_jdaa  (mng_datap      pData,
-                                       mng_uint32     iRawlen,
-                                       mng_uint8p     pRawdata);
-
-mng_retcode mng_process_display_jdat  (mng_datap      pData,
-                                       mng_uint32     iRawlen,
-                                       mng_uint8p     pRawdata);
-
-#endif
-#ifndef MNG_NO_DELTA_PNG
-mng_retcode mng_process_display_dhdr  (mng_datap      pData,
-                                       mng_uint16     iObjectid,
-                                       mng_uint8      iImagetype,
-                                       mng_uint8      iDeltatype,
-                                       mng_uint32     iBlockwidth,
-                                       mng_uint32     iBlockheight,
-                                       mng_uint32     iBlockx,
-                                       mng_uint32     iBlocky);
-
-mng_retcode mng_process_display_prom  (mng_datap      pData,
-                                       mng_uint8      iBitdepth,
-                                       mng_uint8      iColortype,
-                                       mng_uint8      iFilltype);
-
-mng_retcode mng_process_display_ipng  (mng_datap      pData);
-#ifdef MNG_INCLUDE_JNG
-mng_retcode mng_process_display_ijng  (mng_datap      pData);
-#endif
-
-mng_retcode mng_process_display_pplt  (mng_datap      pData,
-                                       mng_uint8      iType,
-                                       mng_uint32     iCount,
-                                       mng_palette8ep paIndexentries,
-                                       mng_uint8p     paAlphaentries,
-                                       mng_uint8p     paUsedentries);
-#endif
-
-#ifndef MNG_SKIPCHUNK_MAGN
-mng_retcode mng_process_display_magn  (mng_datap      pData,
-                                       mng_uint16     iFirstid,
-                                       mng_uint16     iLastid,
-                                       mng_uint8      iMethodX,
-                                       mng_uint16     iMX,
-                                       mng_uint16     iMY,
-                                       mng_uint16     iML,
-                                       mng_uint16     iMR,
-                                       mng_uint16     iMT,
-                                       mng_uint16     iMB,
-                                       mng_uint8      iMethodY);
-mng_retcode mng_process_display_magn2 (mng_datap      pData);
-#endif
-
-#ifndef MNG_SKIPCHUNK_PAST
-mng_retcode mng_process_display_past  (mng_datap      pData,
-                                       mng_uint16     iTargetid,
-                                       mng_uint8      iTargettype,
-                                       mng_int32      iTargetx,
-                                       mng_int32      iTargety,
-                                       mng_uint32     iCount,
-                                       mng_ptr        pSources);
-mng_retcode mng_process_display_past2 (mng_datap      pData);
-#endif
-
-#else /* MNG_OPTIMIZE_DISPLAYCALLS */
-
-mng_retcode mng_process_display_ihdr  (mng_datap      pData);
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-mng_retcode mng_process_display_mpng  (mng_datap      pData);
-#endif
-mng_retcode mng_process_display_idat  (mng_datap      pData);
-mng_retcode mng_process_display_iend  (mng_datap      pData);
-mng_retcode mng_process_display_mend  (mng_datap      pData);
-mng_retcode mng_process_display_mend2 (mng_datap      pData);
-mng_retcode mng_process_display_defi  (mng_datap      pData);
-#ifndef MNG_SKIPCHUNK_BASI
-mng_retcode mng_process_display_basi  (mng_datap      pData);
-#endif
-#ifndef MNG_SKIPCHUNK_CLON
-mng_retcode mng_process_display_clon  (mng_datap      pData);
-mng_retcode mng_process_display_clon2 (mng_datap      pData);
-#endif
-#ifndef MNG_SKIPCHUNK_DISC
-mng_retcode mng_process_display_disc  (mng_datap      pData);
-#endif
-#ifndef MNG_SKIPCHUNK_FRAM
-mng_retcode mng_process_display_fram  (mng_datap      pData);
-mng_retcode mng_process_display_fram2 (mng_datap      pData);
-#endif
-#ifndef MNG_SKIPCHUNK_MOVE
-mng_retcode mng_process_display_move  (mng_datap      pData);
-#endif
-#ifndef MNG_SKIPCHUNK_CLIP
-mng_retcode mng_process_display_clip  (mng_datap      pData);
-#endif
-#ifndef MNG_SKIPCHUNK_SHOW
-mng_retcode mng_process_display_show  (mng_datap      pData);
-#endif
-#ifndef MNG_SKIPCHUNK_SAVE
-mng_retcode mng_process_display_save  (mng_datap      pData);
-#endif
-#ifndef MNG_SKIPCHUNK_SEEK
-mng_retcode mng_process_display_seek  (mng_datap      pData);
-#endif
-#ifdef MNG_INCLUDE_JNG
-mng_retcode mng_process_display_jhdr  (mng_datap      pData);
-mng_retcode mng_process_display_jdaa  (mng_datap      pData);
-mng_retcode mng_process_display_jdat  (mng_datap      pData);
-#endif
-#ifndef MNG_NO_DELTA_PNG
-mng_retcode mng_process_display_dhdr  (mng_datap      pData);
-mng_retcode mng_process_display_prom  (mng_datap      pData);
-mng_retcode mng_process_display_ipng  (mng_datap      pData);
-#ifdef MNG_INCLUDE_JNG
-mng_retcode mng_process_display_ijng  (mng_datap      pData);
-#endif
-mng_retcode mng_process_display_pplt  (mng_datap      pData);
-#endif
-#ifndef MNG_SKIPCHUNK_MAGN
-mng_retcode mng_process_display_magn  (mng_datap      pData);
-mng_retcode mng_process_display_magn2 (mng_datap      pData);
-#endif
-#ifndef MNG_SKIPCHUNK_PAST
-mng_retcode mng_process_display_past  (mng_datap      pData);
-mng_retcode mng_process_display_past2 (mng_datap      pData);
-#endif
-
-#endif /* MNG_OPTIMIZE_DISPLAYCALLS */
-
-/* ************************************************************************** */
-
-#endif /* MNG_INCLUDE_DISPLAY_PROCS */
-
-/* ************************************************************************** */
-
-#endif /* _libmng_display_h_ */
-
-/* ************************************************************************** */
-/* * end of file                                                            * */
-/* ************************************************************************** */
diff --git a/Source/LibMNG/libmng_dither.c b/Source/LibMNG/libmng_dither.c
deleted file mode 100644
index 3ba2a70..0000000
--- a/Source/LibMNG/libmng_dither.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/* ************************************************************************** */
-/* *             For conditions of distribution and use,                    * */
-/* *                see copyright notice in libmng.h                        * */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * project   : libmng                                                     * */
-/* * file      : libmng_dither.c           copyright (c) 2000-2004 G.Juyn   * */
-/* * version   : 1.0.9                                                      * */
-/* *                                                                        * */
-/* * purpose   : Dithering routines (implementation)                        * */
-/* *                                                                        * */
-/* * author    : G.Juyn                                                     * */
-/* *                                                                        * */
-/* * comment   : implementation of the dithering routines                   * */
-/* *                                                                        * */
-/* * changes   : 0.5.1 - 05/08/2000 - G.Juyn                                * */
-/* *             - changed strict-ANSI stuff                                * */
-/* *                                                                        * */
-/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
-/* *             - changed file-prefixes                                    * */
-/* *                                                                        * */
-/* *             1.0.5 - 08/19/2002 - G.Juyn                                * */
-/* *             - B597134 - libmng pollutes the linker namespace           * */
-/* *                                                                        * */
-/* *             1.0.9 - 12/20/2004 - G.Juyn                                * */
-/* *             - cleaned up macro-invocations (thanks to D. Airlie)       * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#include "libmng.h"
-#include "libmng_data.h"
-#include "libmng_error.h"
-#include "libmng_trace.h"
-#ifdef __BORLANDC__
-#pragma hdrstop
-#endif
-#include "libmng_dither.h"
-
-#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
-#pragma option -A                      /* force ANSI-C */
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_dither_a_row (mng_datap  pData,
-                              mng_uint8p pRow)
-{
-
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-/* * end of file                                                            * */
-/* ************************************************************************** */
-
-
-
diff --git a/Source/LibMNG/libmng_dither.h b/Source/LibMNG/libmng_dither.h
deleted file mode 100644
index d9217c0..0000000
--- a/Source/LibMNG/libmng_dither.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* ************************************************************************** */
-/* *             For conditions of distribution and use,                    * */
-/* *                see copyright notice in libmng.h                        * */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * project   : libmng                                                     * */
-/* * file      : libmng_dither.h           copyright (c) 2000-2002 G.Juyn   * */
-/* * version   : 1.0.5                                                      * */
-/* *                                                                        * */
-/* * purpose   : Dithering routines (definition)                            * */
-/* *                                                                        * */
-/* * author    : G.Juyn                                                     * */
-/* *                                                                        * */
-/* * comment   : Definition of the dithering routines                       * */
-/* *                                                                        * */
-/* * changes   : 0.5.1 - 05/08/2000 - G.Juyn                                * */
-/* *             - changed strict-ANSI stuff                                * */
-/* *                                                                        * */
-/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
-/* *             - changed file-prefixes                                    * */
-/* *                                                                        * */
-/* *             1.0.5 - 08/19/2002 - G.Juyn                                * */
-/* *             - B597134 - libmng pollutes the linker namespace           * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
-#pragma option -A                      /* force ANSI-C */
-#endif
-
-#ifndef _libmng_dither_h_
-#define _libmng_dither_h_
-
-/* ************************************************************************** */
-
-mng_retcode mng_dither_a_row (mng_datap  pData,
-                              mng_uint8p pRow);
-
-/* ************************************************************************** */
-
-#endif /* _libmng_dither_h_ */
-
-/* ************************************************************************** */
-/* * end of file                                                            * */
-/* ************************************************************************** */
diff --git a/Source/LibMNG/libmng_error.c b/Source/LibMNG/libmng_error.c
deleted file mode 100644
index 89501a2..0000000
--- a/Source/LibMNG/libmng_error.c
+++ /dev/null
@@ -1,326 +0,0 @@
-/* ************************************************************************** */
-/* *             For conditions of distribution and use,                    * */
-/* *                see copyright notice in libmng.h                        * */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * project   : libmng                                                     * */
-/* * file      : libmng_error.c            copyright (c) 2000-2007 G.Juyn   * */
-/* * version   : 1.0.10                                                     * */
-/* *                                                                        * */
-/* * purpose   : Error routines (implementation)                            * */
-/* *                                                                        * */
-/* * author    : G.Juyn                                                     * */
-/* *                                                                        * */
-/* * comment   : implementation of the general error handling routines      * */
-/* *                                                                        * */
-/* * changes   : 0.5.1 - 05/08/2000 - G.Juyn                                * */
-/* *             - changed strict-ANSI stuff                                * */
-/* *                                                                        * */
-/* *             0.5.2 - 05/23/2000 - G.Juyn                                * */
-/* *             - added error telltaling                                   * */
-/* *             0.5.2 - 05/30/2000 - G.Juyn                                * */
-/* *             - added errorstrings for delta-image processing            * */
-/* *             0.5.2 - 05/31/2000 - G.Juyn                                * */
-/* *             - fixed up punctuation (contributed by Tim Rowley)         * */
-/* *             0.5.2 - 06/06/2000 - G.Juyn                                * */
-/* *             - added errorstring for delayed buffer-processing          * */
-/* *                                                                        * */
-/* *             0.9.1 - 07/06/2000 - G.Juyn                                * */
-/* *             - added MNG_NEEDTIMERWAIT errorstring                      * */
-/* *             0.9.1 - 07/15/2000 - G.Juyn                                * */
-/* *             - added NEEDSECTIONWAIT errorstring                        * */
-/* *             - added macro + routine to set returncode without          * */
-/* *               calling error callback                                   * */
-/* *             0.9.1 - 07/19/2000 - G.Juyn                                * */
-/* *             - added errorstring for updatemngheader if not a MNG       * */
-/* *                                                                        * */
-/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
-/* *             - changed file-prefixes                                    * */
-/* *                                                                        * */
-/* *             0.9.3 - 08/09/2000 - G.Juyn                                * */
-/* *             - added check for simplicity-bits in MHDR                  * */
-/* *             0.9.3 - 10/11/2000 - G.Juyn                                * */
-/* *             - fixed processing of unknown critical chunks              * */
-/* *             - added support for nEED                                   * */
-/* *             0.9.3 - 10/20/2000 - G.Juyn                                * */
-/* *             - added errorcode for delayed delta-processing             * */
-/* *                                                                        * */
-/* *             0.9.4 - 01/18/2001 - G.Juyn                                * */
-/* *             - added errorcode for MAGN methods                         * */
-/* *                                                                        * */
-/* *             1.0.2 - 06/23/2001 - G.Juyn                                * */
-/* *             - added optimization option for MNG-video playback         * */
-/* *                                                                        * */
-/* *             1.0.5 - 07/04/2002 - G.Juyn                                * */
-/* *             - added errorcode for extreme chunk-sizes                  * */
-/* *             1.0.5 - 08/15/2002 - G.Juyn                                * */
-/* *             - completed delta-image support                            * */
-/* *             1.0.5 - 08/19/2002 - G.Juyn                                * */
-/* *             - B597134 - libmng pollutes the linker namespace           * */
-/* *             1.0.5 - 09/14/2002 - G.Juyn                                * */
-/* *             - added event handling for dynamic MNG                     * */
-/* *             1.0.5 - 09/15/2002 - G.Juyn                                * */
-/* *             - fixed LOOP iteration=0 special case                      * */
-/* *             1.0.5 - 09/19/2002 - G.Juyn                                * */
-/* *             - warnings are ignored by default now!                     * */
-/* *             1.0.5 - 09/20/2002 - G.Juyn                                * */
-/* *             - added support for PAST                                   * */
-/* *             1.0.5 - 10/07/2002 - G.Juyn                                * */
-/* *             - added check for TERM placement during create/write       * */
-/* *                                                                        * */
-/* *             1.0.6 - 07/07/2003 - G. R-P                                * */
-/* *             - added MNG_SKIPCHUNK_CHNK, MNG_NO_DELTA_PNG reductions.   * */
-/* *             - skipped more code when MNG_INCLUDE_JNG is not enabled.   * */
-/* *             1.0.6 - 07/29/2003 - G.R-P                                 * */
-/* *             - added conditional around evNT chunk support              * */
-/* *                                                                        * */
-/* *             1.0.7 - 03/24/2004 - G.R-P                                 * */
-/* *             - fixed typo on SKIPCHUNK_evNT (->PAST)                    * */
-/* *                                                                        * */
-/* *             1.0.9 - 12/20/2004 - G.Juyn                                * */
-/* *             - cleaned up macro-invocations (thanks to D. Airlie)       * */
-/* *                                                                        * */
-/* *             1.0.10 - 04/08/2007 - G.Juyn                               * */
-/* *             - added support for mPNG proposal                          * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#include "libmng.h"
-#include "libmng_data.h"
-#include "libmng_error.h"
-#include "libmng_trace.h"
-#ifdef __BORLANDC__
-#pragma hdrstop
-#endif
-
-#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
-#pragma option -A                      /* force ANSI-C */
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_ERROR_STRINGS
-MNG_LOCAL mng_error_entry const error_table [] =
-  {
-    {MNG_NOERROR,          "No error"},
-    {MNG_OUTOFMEMORY,      "Out of memory"},
-    {MNG_INVALIDHANDLE,    "The handle is invalid"},
-    {MNG_NOCALLBACK,       "A required callback is not defined"},
-    {MNG_UNEXPECTEDEOF,    "Encountered unexpected end-of-file"},
-    {MNG_ZLIBERROR,        "zlib encountered an error"},
-#ifdef MNG_INCLUDE_JNG
-    {MNG_JPEGERROR,        "ijgsrc6b encountered an error"},
-#endif
-    {MNG_LCMSERROR,        "lcms encountered an error"},
-    {MNG_NOOUTPUTPROFILE,  "No output-profile defined for CMS"},
-    {MNG_NOSRGBPROFILE,    "No sRGB-profile defined for CMS"},
-    {MNG_BUFOVERFLOW,      "Internal buffer-overflow"},
-    {MNG_FUNCTIONINVALID,  "Function is invalid at this point"},
-    {MNG_OUTPUTERROR,      "Writing was unsuccessful; disk full?"},
-    {MNG_JPEGBUFTOOSMALL,  "Internal buffer for JPEG processing too small"},
-    {MNG_NEEDMOREDATA,     "Reading suspended; waiting for I/O to catch up"},
-    {MNG_NEEDTIMERWAIT,    "Timer suspension; normal animation delay"},
-    {MNG_NEEDSECTIONWAIT,  "SEEK suspension; application decides"},
-    {MNG_LOOPWITHCACHEOFF, "LOOP encountered when playback cache is turned off"},
-
-    {MNG_APPIOERROR,       "Application signalled I/O error"},
-    {MNG_APPTIMERERROR,    "Application signalled timing error"},
-    {MNG_APPCMSERROR,      "Application signalled CMS error"},
-    {MNG_APPMISCERROR,     "Application signalled an error"},
-    {MNG_APPTRACEABORT,    "Application signalled error during trace-callback"},
-
-    {MNG_INTERNALERROR,    "Internal error in libmng"},
-
-    {MNG_INVALIDSIG,       "The signature is invalid"},
-    {MNG_INVALIDCRC,       "The CRC for this chunk is invalid"},
-    {MNG_INVALIDLENGTH,    "Chunk-length is invalid"},
-    {MNG_SEQUENCEERROR,    "Chunk out of sequence"},
-    {MNG_CHUNKNOTALLOWED,  "Chunk not allowed at this point"},
-    {MNG_MULTIPLEERROR,    "Chunk cannot occur multiple times"},
-    {MNG_PLTEMISSING,      "Missing PLTE chunk"},
-    {MNG_IDATMISSING,      "Missing IDAT chunk(s)"},
-    {MNG_CANNOTBEEMPTY,    "Chunk cannot be empty"},
-    {MNG_GLOBALLENGTHERR,  "Global data length invalid"},
-    {MNG_INVALIDBITDEPTH,  "The bit_depth is invalid"},
-    {MNG_INVALIDCOLORTYPE, "The color_type is invalid"},
-    {MNG_INVALIDCOMPRESS,  "The compression_method is invalid"},
-    {MNG_INVALIDFILTER,    "The filter_method or filter_type is invalid"},
-    {MNG_INVALIDINTERLACE, "The interlace_method is invalid"},
-    {MNG_NOTENOUGHIDAT,    "There is not enough data in the IDAT chunk(s)"},
-    {MNG_PLTEINDEXERROR,   "Palette-index out of bounds"},
-    {MNG_NULLNOTFOUND,     "NULL separator not found"},
-    {MNG_KEYWORDNULL,      "Keyword cannot be zero-length"},
-    {MNG_OBJECTUNKNOWN,    "Object does not exist"},
-    {MNG_OBJECTEXISTS,     "Object already exists"},
-    {MNG_TOOMUCHIDAT,      "Too much data in IDAT chunk(s)"},
-    {MNG_INVSAMPLEDEPTH,   "The sample_depth is invalid"},
-    {MNG_INVOFFSETSIZE,    "The offset_type is invalid"},
-    {MNG_INVENTRYTYPE,     "The entry_type is invalid"},
-    {MNG_ENDWITHNULL,      "Chunk must not end with NULL byte"},
-    {MNG_INVIMAGETYPE,     "The image_type is invalid"},
-#ifndef MNG_NO_DELTA_PNG
-    {MNG_INVDELTATYPE,     "The delta_type is invalid"},
-#endif
-    {MNG_INVALIDINDEX,     "Index-value out of bounds"},
-#ifdef MNG_INCLUDE_JNG
-    {MNG_TOOMUCHJDAT,      "Too much data in JDAT chunk(s)"},
-    {MNG_JPEGPARMSERR,     "JHDR parameters & JFIF-data do not match"},
-#endif
-    {MNG_INVFILLMETHOD,    "The fill_method is invalid"},
-#ifndef MNG_NO_DELTA_PNG
-    {MNG_OBJNOTCONCRETE,   "Target object for DHDR must be concrete"},
-#endif
-    {MNG_TARGETNOALPHA,    "Target object must have alpha-channel"},
-    {MNG_MNGTOOCOMPLEX,    "MHDR simplicity indicates unsupported feature(s)"},
-    {MNG_UNKNOWNCRITICAL,  "Unknown critical chunk encountered"},
-#ifndef MNG_SKIPCHUNK_nEED
-    {MNG_UNSUPPORTEDNEED,  "Requested nEED resources are not supported"},
-#endif
-    {MNG_INVALIDDELTA,     "The delta operation is invalid (mismatched color_types?)"},
-    {MNG_INVALIDMETHOD,    "Method is invalid"},
-    {MNG_IMPROBABLELENGTH, "Chunklength is incredibly large"},
-    {MNG_INVALIDBLOCK,     "Delta block width and or height invalid"},
-    {MNG_INVALIDEVENT,     "Event type is invalid"},
-    {MNG_INVALIDMASK,      "Mask type is invalid"},
-    {MNG_NOMATCHINGLOOP,   "ENDL without matching LOOP"},
-#ifndef MNG_SKIPCHUNK_evNT
-    {MNG_SEEKNOTFOUND,     "evNT points to unknown SEEK"},
-#endif
-#ifndef MNG_SKIPCHUNK_PAST
-    {MNG_OBJNOTABSTRACT,   "Destination object for PAST must be abstract"},
-#endif
-    {MNG_TERMSEQERROR,     "TERM misplaced during creation of MNG stream"},
-    {MNG_INVALIDFIELDVAL,  "invalid fieldvalue (generic)"},
-    {MNG_INVALIDWIDTH,     "invalid frame/image width"},
-    {MNG_INVALIDHEIGHT,    "invalid frame/image height"},
-
-    {MNG_INVALIDCNVSTYLE,  "Canvas_style is invalid"},
-    {MNG_WRONGCHUNK,       "Attempt to access the wrong chunk"},
-    {MNG_INVALIDENTRYIX,   "Attempt to access an non-existing entry"},
-    {MNG_NOHEADER,         "No valid header-chunk"},
-    {MNG_NOCORRCHUNK,      "Parent chunk not found"},
-    {MNG_NOMHDR,           "No MNG header (MHDR) found"},
-
-    {MNG_IMAGETOOLARGE,    "Image is larger than defined maximum"},
-    {MNG_NOTANANIMATION,   "Image is not an animation"},
-    {MNG_FRAMENRTOOHIGH,   "Framenr out of bounds"},
-    {MNG_LAYERNRTOOHIGH,   "Layernr out of bounds"},
-    {MNG_PLAYTIMETOOHIGH,  "Playtime out of bounds"},
-    {MNG_FNNOTIMPLEMENTED, "Function not yet implemented"},
-    {MNG_IMAGEFROZEN,      "Image is frozen"},
-
-    {MNG_LCMS_NOHANDLE,    "Handle could not be initialized"},
-    {MNG_LCMS_NOMEM,       "No memory for gamma-table(s)"},
-    {MNG_LCMS_NOTRANS,     "Transformation could not be initialized"}
-  };
-#endif /* MNG_INCLUDE_ERROR_STRINGS */
-
-/* ************************************************************************** */
-
-mng_bool mng_store_error (mng_datap   pData,
-                          mng_retcode iError,
-                          mng_retcode iExtra1,
-                          mng_retcode iExtra2)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEB (pData, MNG_FN_STORE_ERROR, MNG_LC_START);
-#endif
-
-  if (pData != 0)
-  {
-    pData->iErrorcode = iError;        /* save also for getlasterror */
-    pData->iErrorx1   = iExtra1;
-    pData->iErrorx2   = iExtra2;
-
-#ifdef MNG_INCLUDE_ERROR_STRINGS
-    {                                  /* binary search variables */
-      mng_int32        iTop, iLower, iUpper, iMiddle;
-      mng_error_entryp pEntry;         /* pointer to found entry */
-                                       /* determine max index of table */
-      iTop = (sizeof (error_table) / sizeof (error_table [0])) - 1;
-
-      iLower  = 0;                     /* initialize binary search */
-      iMiddle = iTop >> 1;             /* start in the middle */
-      iUpper  = iTop;
-      pEntry  = 0;                     /* no goods yet! */
-
-      do                               /* the binary search itself */
-        {
-          if (error_table [iMiddle].iError < iError)
-            iLower = iMiddle + 1;
-          else if (error_table [iMiddle].iError > iError)
-            iUpper = iMiddle - 1;
-          else
-          {
-            pEntry = &error_table [iMiddle];
-            break;
-          }
-
-          iMiddle = (iLower + iUpper) >> 1;
-        }
-      while (iLower <= iUpper);
-
-      if (pEntry)                      /* found it ? */
-        pData->zErrortext = pEntry->zErrortext;
-      else
-        pData->zErrortext = "Unknown error";
-      }
-#else /* MNG_INCLUDE_ERROR_STRINGS */
-    pData->zErrortext = 0;
-#endif /* MNG_INCLUDE_ERROR_STRINGS */
-
-    if (iError == 0)                   /* no error is not severe ! */
-    {
-      pData->iSeverity = 0;
-    }
-    else
-    {
-      switch (iError&0x3C00)           /* determine the severity */
-      {
-        case 0x0800 : { pData->iSeverity = 5; break; }
-        case 0x1000 : { pData->iSeverity = 2; break; }
-        case 0x2000 : { pData->iSeverity = 1; break; }      
-        default     : { pData->iSeverity = 9; }
-      }
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEB (pData, MNG_FN_STORE_ERROR, MNG_LC_END);
-#endif
-
-  return MNG_TRUE;
-}
-
-/* ************************************************************************** */
-
-mng_bool mng_process_error (mng_datap   pData,
-                            mng_retcode iError,
-                            mng_retcode iExtra1,
-                            mng_retcode iExtra2)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEB (pData, MNG_FN_PROCESS_ERROR, MNG_LC_START);
-#endif
-
-  mng_store_error (pData, iError, iExtra1, iExtra2);
-
-  if ((pData != MNG_NULL) && (pData->iMagic == MNG_MAGIC))
-  {
-    if (pData->fErrorproc)             /* callback defined ? */
-      return pData->fErrorproc (((mng_handle)pData), iError, pData->iSeverity,
-                                pData->iChunkname, pData->iChunkseq,
-                                pData->iErrorx1, pData->iErrorx2, pData->zErrortext);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEB (pData, MNG_FN_PROCESS_ERROR, MNG_LC_END);
-#endif
-
-  return MNG_TRUE;                     /* warnings are ignored by default ! */
-}
-
-/* ************************************************************************** */
-/* * end of file                                                            * */
-/* ************************************************************************** */
-
diff --git a/Source/LibMNG/libmng_error.h b/Source/LibMNG/libmng_error.h
deleted file mode 100644
index b49ff73..0000000
--- a/Source/LibMNG/libmng_error.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/* ************************************************************************** */
-/* *             For conditions of distribution and use,                    * */
-/* *                see copyright notice in libmng.h                        * */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * project   : libmng                                                     * */
-/* * file      : libmng_error.h            copyright (c) 2000-2002 G.Juyn   * */
-/* * version   : 1.0.5                                                      * */
-/* *                                                                        * */
-/* * purpose   : Error functions (definition)                               * */
-/* *                                                                        * */
-/* * author    : G.Juyn                                                     * */
-/* *                                                                        * */
-/* * comment   : Definition of the generic error-codes and functions        * */
-/* *                                                                        * */
-/* * changes   : 0.5.1 - 05/06/2000 - G.Juyn                                * */
-/* *             - added some errorcodes                                    * */
-/* *             0.5.1 - 05/08/2000 - G.Juyn                                * */
-/* *             - added some errorcodes                                    * */
-/* *             - changed strict-ANSI stuff                                * */
-/* *             0.5.1 - 05/11/2000 - G.Juyn                                * */
-/* *             - added application errorcodes (used with callbacks)       * */
-/* *             - moved chunk-access errorcodes to severity 5              * */
-/* *                                                                        * */
-/* *             0.5.2 - 05/20/2000 - G.Juyn                                * */
-/* *             - added JNG errorcodes                                     * */
-/* *             0.5.2 - 05/23/2000 - G.Juyn                                * */
-/* *             - added error tell-tale definition                         * */
-/* *             0.5.2 - 05/30/2000 - G.Juyn                                * */
-/* *             - added errorcodes for delta-image processing              * */
-/* *             0.5.2 - 06/06/2000 - G.Juyn                                * */
-/* *             - added errorcode for delayed buffer-processing            * */
-/* *             - moved errorcodes to "libmng.h"                           * */
-/* *                                                                        * */
-/* *             0.9.1 - 07/15/2000 - G.Juyn                                * */
-/* *             - added macro + routine to set returncode without          * */
-/* *               calling error callback                                   * */
-/* *                                                                        * */
-/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
-/* *             - changed file-prefixes                                    * */
-/* *                                                                        * */
-/* *             1.0.5 - 08/19/2002 - G.Juyn                                * */
-/* *             - B597134 - libmng pollutes the linker namespace           * */
-/* *             1.0.5 - 08/20/2002 - G.Juyn                                * */
-/* *             - added option for soft-handling of errors                 * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
-#pragma option -A                      /* force ANSI-C */
-#endif
-
-#ifndef _libmng_error_h_
-#define _libmng_error_h_
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Default error routines                                                 * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-mng_bool mng_store_error   (mng_datap   pData,
-                            mng_retcode iError,
-                            mng_retcode iExtra1,
-                            mng_retcode iExtra2);
-
-mng_bool mng_process_error (mng_datap   pData,
-                            mng_retcode iError,
-                            mng_retcode iExtra1,
-                            mng_retcode iExtra2);
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Error handling macros                                                  * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifdef MNG_SOFTERRORS
-#define MNG_ERROR(D,C)      { if (!mng_process_error (D, C, 0, 0)) return C; }
-#define MNG_ERRORZ(D,Z)     { if (!mng_process_error (D, MNG_ZLIBERROR, Z, 0)) return MNG_ZLIBERROR; }
-#define MNG_ERRORJ(D,J)     { if (!mng_process_error (D, MNG_JPEGERROR, J, 0)) return MNG_JPEGERROR; }
-#define MNG_ERRORL(D,L)     { if (!mng_process_error (D, MNG_LCMSERROR, L, 0)) return MNG_LCMSERROR; }
-#else
-#define MNG_ERROR(D,C)      { mng_process_error (D, C, 0, 0); return C; }
-#define MNG_ERRORZ(D,Z)     { mng_process_error (D, MNG_ZLIBERROR, Z, 0); return MNG_ZLIBERROR; }
-#define MNG_ERRORJ(D,J)     { mng_process_error (D, MNG_JPEGERROR, J, 0); return MNG_JPEGERROR; }
-#define MNG_ERRORL(D,L)     { mng_process_error (D, MNG_LCMSERROR, L, 0); return MNG_LCMSERROR; }
-#endif
-
-#define MNG_RETURN(D,C)     { mng_store_error (D, C, 0, 0); return C; }
-
-#define MNG_WARNING(D,C)    { if (!mng_process_error (D, C, 0, 0)) return C; }
-
-#define MNG_VALIDHANDLE(H)  { if ((H == 0) || (((mng_datap)H)->iMagic != MNG_MAGIC)) \
-                                return MNG_INVALIDHANDLE; }
-#define MNG_VALIDHANDLEX(H) { if ((H == 0) || (((mng_datap)H)->iMagic != MNG_MAGIC)) \
-                                return 0; }
-#define MNG_VALIDCB(D,C)    { if (!((mng_datap)D)->C) \
-                                MNG_ERROR (((mng_datap)D), MNG_NOCALLBACK) }
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Error string-table entry                                               * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-typedef struct {
-                 mng_retcode iError;
-                 mng_pchar   zErrortext;
-               } mng_error_entry;
-typedef mng_error_entry const * mng_error_entryp;
-
-/* ************************************************************************** */
-
-#endif /* _libmng_error_h_ */
-
-/* ************************************************************************** */
-/* * end of file                                                            * */
-/* ************************************************************************** */
diff --git a/Source/LibMNG/libmng_filter.c b/Source/LibMNG/libmng_filter.c
deleted file mode 100644
index ad57a3b..0000000
--- a/Source/LibMNG/libmng_filter.c
+++ /dev/null
@@ -1,978 +0,0 @@
-/* ************************************************************************** */
-/* *             For conditions of distribution and use,                    * */
-/* *                see copyright notice in libmng.h                        * */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * project   : libmng                                                     * */
-/* * file      : libmng_filter.c           copyright (c) 2000-2004 G.Juyn   * */
-/* * version   : 1.0.9                                                      * */
-/* *                                                                        * */
-/* * purpose   : Filtering routines (implementation)                        * */
-/* *                                                                        * */
-/* * author    : G.Juyn                                                     * */
-/* *                                                                        * */
-/* * comment   : implementation of the filtering routines                   * */
-/* *                                                                        * */
-/* * changes   : 0.5.1 - 05/08/2000 - G.Juyn                                * */
-/* *             - changed strict-ANSI stuff                                * */
-/* *             0.5.1 - 05/12/2000 - G.Juyn                                * */
-/* *             - changed trace to macro for callback error-reporting      * */
-/* *                                                                        * */
-/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
-/* *             - changed file-prefixes                                    * */
-/* *                                                                        * */
-/* *             0.9.3 - 09/07/2000 - G.Juyn                                * */
-/* *             - added support for new filter_types                       * */
-/* *                                                                        * */
-/* *             1.0.5 - 08/07/2002 - G.Juyn                                * */
-/* *             - added test-option for PNG filter method 193 (=no filter) * */
-/* *             1.0.5 - 08/19/2002 - G.Juyn                                * */
-/* *             - B597134 - libmng pollutes the linker namespace           * */
-/* *                                                                        * */
-/* *             1.0.6 - 07/07/2003 - G.R-P                                 * */
-/* *             - reversed some loops to use decrementing counter          * */
-/* *                                                                        * */
-/* *             1.0.9 - 12/20/2004 - G.Juyn                                * */
-/* *             - cleaned up macro-invocations (thanks to D. Airlie)       * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#include "libmng.h"
-#include "libmng_data.h"
-#include "libmng_error.h"
-#include "libmng_trace.h"
-#ifdef __BORLANDC__
-#pragma hdrstop
-#endif
-#include "libmng_filter.h"
-
-#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
-#pragma option -A                      /* force ANSI-C */
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_FILTERS
-
-/* ************************************************************************** */
-
-MNG_LOCAL mng_retcode filter_sub (mng_datap pData)
-{
-  mng_uint32 iBpp;
-  mng_uint8p pRawx;
-  mng_uint8p pRawx_prev;
-  mng_int32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FILTER_SUB, MNG_LC_START);
-#endif
-
-  iBpp       = pData->iFilterbpp;
-  pRawx      = pData->pWorkrow + pData->iPixelofs + iBpp;
-  pRawx_prev = pData->pWorkrow + pData->iPixelofs;
-
-  for (iX = iBpp; iX < pData->iRowsize; iX++)
-  {
-    *pRawx = (mng_uint8)(*pRawx + *pRawx_prev);
-    pRawx++;
-    pRawx_prev++;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FILTER_SUB, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-MNG_LOCAL mng_retcode filter_up (mng_datap pData)
-{
-  mng_uint8p pRawx;
-  mng_uint8p pPriorx;
-  mng_int32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FILTER_UP, MNG_LC_START);
-#endif
-
-  pRawx   = pData->pWorkrow + pData->iPixelofs;
-  pPriorx = pData->pPrevrow + pData->iPixelofs;
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsize - 1; iX >= 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsize; iX++)
-#endif
-  {
-    *pRawx = (mng_uint8)(*pRawx + *pPriorx);
-    pRawx++;
-    pPriorx++;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FILTER_UP, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-MNG_LOCAL mng_retcode filter_average (mng_datap pData)
-{
-  mng_int32  iBpp;
-  mng_uint8p pRawx;
-  mng_uint8p pRawx_prev;
-  mng_uint8p pPriorx;
-  mng_int32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FILTER_AVERAGE, MNG_LC_START);
-#endif
-
-  iBpp       = pData->iFilterbpp;
-  pRawx      = pData->pWorkrow + pData->iPixelofs;
-  pPriorx    = pData->pPrevrow + pData->iPixelofs;
-  pRawx_prev = pData->pWorkrow + pData->iPixelofs;
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = iBpp - 1; iX >= 0; iX--)
-#else
-  for (iX = 0; iX < iBpp; iX++)
-#endif
-  {
-    *pRawx = (mng_uint8)(*pRawx + ((*pPriorx) >> 1));
-    pRawx++;
-    pPriorx++;
-  }
-
-  for (iX = iBpp; iX < pData->iRowsize; iX++)
-  {
-    *pRawx = (mng_uint8)(*pRawx + ((*pRawx_prev + *pPriorx) >> 1));
-    pRawx++;
-    pPriorx++;
-    pRawx_prev++;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FILTER_AVERAGE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-MNG_LOCAL mng_retcode filter_paeth (mng_datap pData)
-{
-  mng_int32  iBpp;
-  mng_uint8p pRawx;
-  mng_uint8p pRawx_prev;
-  mng_uint8p pPriorx;
-  mng_uint8p pPriorx_prev;
-  mng_int32  iX;
-  mng_uint32 iA, iB, iC;
-  mng_uint32 iP;
-  mng_uint32 iPa, iPb, iPc;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FILTER_PAETH, MNG_LC_START);
-#endif
-
-  iBpp         = pData->iFilterbpp;
-  pRawx        = pData->pWorkrow + pData->iPixelofs;
-  pPriorx      = pData->pPrevrow + pData->iPixelofs;
-  pRawx_prev   = pData->pWorkrow + pData->iPixelofs;
-  pPriorx_prev = pData->pPrevrow + pData->iPixelofs;
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = iBpp - 1; iX >= 0; iX--)
-#else
-  for (iX = 0; iX < iBpp; iX++)
-#endif
-  {
-    *pRawx = (mng_uint8)(*pRawx + *pPriorx);
-
-    pRawx++;
-    pPriorx++;
-  }
-
-  for (iX = iBpp; iX < pData->iRowsize; iX++)
-  {
-    iA  = (mng_uint32)*pRawx_prev;
-    iB  = (mng_uint32)*pPriorx;
-    iC  = (mng_uint32)*pPriorx_prev;
-    iP  = iA + iB - iC;
-    iPa = abs (iP - iA);
-    iPb = abs (iP - iB);
-    iPc = abs (iP - iC);
-
-    if ((iPa <= iPb) && (iPa <= iPc))
-      *pRawx = (mng_uint8)(*pRawx + iA);
-    else
-      if (iPb <= iPc)
-        *pRawx = (mng_uint8)(*pRawx + iB);
-      else
-        *pRawx = (mng_uint8)(*pRawx + iC);
-
-    pRawx++;
-    pPriorx++;
-    pRawx_prev++;
-    pPriorx_prev++;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FILTER_PAETH, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_filter_a_row (mng_datap pData)
-{
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FILTER_A_ROW, MNG_LC_START);
-#endif
-
-  switch (*(pData->pWorkrow + pData->iFilterofs))
-  {
-    case 1  : {
-                iRetcode = filter_sub     (pData);
-                break;
-              }
-    case 2  : {
-                iRetcode = filter_up      (pData);
-                break;
-              }
-    case 3  : {
-                iRetcode = filter_average (pData);
-                break;
-              }
-    case 4  : {
-                iRetcode = filter_paeth   (pData);
-                break;
-              }
-
-    default : iRetcode = MNG_INVALIDFILTER;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FILTER_A_ROW, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-
-/* ************************************************************************** */
-/* ************************************************************************** */
-
-#ifdef FILTER192
-mng_retcode mng_init_rowdiffering (mng_datap pData)
-{
-  mng_uint8p pRawi, pRawo;
-  mng_int32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_ROWDIFFERING, MNG_LC_START);
-#endif
-
-  if (pData->iFilter == 0xC0)          /* has leveling parameters ? */
-  {
-    switch (pData->iColortype)         /* salvage leveling parameters */
-    {
-      case 0 : {                       /* gray */
-                 if (pData->iBitdepth <= 8)
-                   pData->iLevel0 = (mng_uint16)*pData->pWorkrow;
-                 else
-                   pData->iLevel0 = mng_get_uint16 (pData->pWorkrow);
-
-                 break;
-               }
-      case 2 : {                       /* rgb */
-                 if (pData->iBitdepth <= 8)
-                 {
-                   pData->iLevel0 = (mng_uint16)*pData->pWorkrow;
-                   pData->iLevel1 = (mng_uint16)*(pData->pWorkrow+1);
-                   pData->iLevel2 = (mng_uint16)*(pData->pWorkrow+2);
-                 }
-                 else
-                 {
-                   pData->iLevel0 = mng_get_uint16 (pData->pWorkrow);
-                   pData->iLevel1 = mng_get_uint16 (pData->pWorkrow+2);
-                   pData->iLevel2 = mng_get_uint16 (pData->pWorkrow+4);
-                 }
-
-                 break;
-               }
-      case 3 : {                       /* indexed */
-                 pData->iLevel0 = (mng_uint16)*pData->pWorkrow;
-                 break;
-               }
-      case 4 : {                       /* gray+alpha */
-                 if (pData->iBitdepth <= 8)
-                 {
-                   pData->iLevel0 = (mng_uint16)*pData->pWorkrow;
-                   pData->iLevel1 = (mng_uint16)*(pData->pWorkrow+1);
-                 }
-                 else
-                 {
-                   pData->iLevel0 = mng_get_uint16 (pData->pWorkrow);
-                   pData->iLevel1 = mng_get_uint16 (pData->pWorkrow+2);
-                 }
-
-                 break;
-               }
-      case 6 : {                       /* rgb+alpha */
-                 if (pData->iBitdepth <= 8)
-                 {
-                   pData->iLevel0 = (mng_uint16)*pData->pWorkrow;
-                   pData->iLevel1 = (mng_uint16)*(pData->pWorkrow+1);
-                   pData->iLevel2 = (mng_uint16)*(pData->pWorkrow+2);
-                   pData->iLevel3 = (mng_uint16)*(pData->pWorkrow+3);
-                 }
-                 else
-                 {
-                   pData->iLevel0 = mng_get_uint16 (pData->pWorkrow);
-                   pData->iLevel1 = mng_get_uint16 (pData->pWorkrow+2);
-                   pData->iLevel2 = mng_get_uint16 (pData->pWorkrow+4);
-                   pData->iLevel3 = mng_get_uint16 (pData->pWorkrow+6);
-                 }
-
-                 break;
-               }
-    }
-  }
-                                       /* shift the entire row back in place */
-  pRawi = pData->pWorkrow + pData->iFilterofs;
-  pRawo = pData->pWorkrow;
-
-  for (iX = 0; iX < pData->iRowsize + pData->iPixelofs - pData->iFilterofs; iX++)
-    *pRawo++ = *pRawi++;
-
-  pData->iFilterofs = 0;               /* indicate so ! */
-
-#ifdef FILTER193
-  if (pData->iFilter == 0xC1)          /* no adaptive filtering ? */
-    pData->iPixelofs = pData->iFilterofs;
-  else
-#endif
-    pData->iPixelofs = pData->iFilterofs + 1;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_ROWDIFFERING, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_differ_g1 (mng_datap pData)
-{
-  mng_uint8p pRawi, pRawo;
-  mng_int32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DIFFER_G1, MNG_LC_START);
-#endif
-
-  if (pData->iLevel0 & 0x01)           /* is it uneven level ? */
-  {
-    pRawi = pData->pWorkrow + pData->iPixelofs;
-    pRawo = pData->pPrevrow + pData->iPixelofs;
-                                       /* just invert every bit */
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsize - 1; iX >= 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsize; iX++)
-#endif
-      *pRawo++ = (mng_uint8)(~(*pRawi++));
-
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DIFFER_G1, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_differ_g2 (mng_datap pData)
-{
-  mng_uint8p pRawi, pRawo;
-  mng_int32  iX;
-  mng_int32  iC, iS;
-  mng_uint8  iB, iN, iQ;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DIFFER_G2, MNG_LC_START);
-#endif
-
-  pRawi = pData->pWorkrow + pData->iPixelofs;
-  pRawo = pData->pPrevrow + pData->iPixelofs;
-  iC    = 0;
-  iB    = 0;
-  iN    = 0;
-  iS    = 0;
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples - 1; iX >= 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    if (!iC)
-    {
-      iC = 4;
-      iB = *pRawi++;
-      iN = 0;
-      iS = 8;
-    }
-
-    iS -= 2;
-    iQ = (mng_uint8)(((iB >> iS) + pData->iLevel0) & 0x03);
-    iN = (mng_uint8)((iN << 2) + iQ);
-    iC--;
-
-    if (!iC)
-      *pRawo++ = iN;
-
-  }
-
-  if (iC)
-    *pRawo = (mng_uint8)(iN << iS);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DIFFER_G2, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_differ_g4 (mng_datap pData)
-{
-  mng_uint8p pRawi, pRawo;
-  mng_int32  iX;
-  mng_int32  iC, iS;
-  mng_uint8  iB, iN, iQ;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DIFFER_G4, MNG_LC_START);
-#endif
-
-  pRawi = pData->pWorkrow + pData->iPixelofs;
-  pRawo = pData->pPrevrow + pData->iPixelofs;
-  iC    = 0;
-  iB    = 0;
-  iN    = 0;
-  iS    = 0;
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples - 1; iX >= 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    if (!iC)
-    {
-      iC = 2;
-      iB = *pRawi++;
-      iN = 0;
-      iS = 8;
-    }
-
-    iS -= 4;
-    iQ = (mng_uint8)(((iB >> iS) + pData->iLevel0) & 0x0F);
-    iN = (mng_uint8)((iN << 4) + iQ);
-    iC--;
-
-    if (!iC)
-      *pRawo++ = iN;
-
-  }
-
-  if (iC)
-    *pRawo = (mng_uint8)(iN << iS);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DIFFER_G4, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_differ_g8 (mng_datap pData)
-{
-  mng_uint8p pRawi, pRawo;
-  mng_int32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DIFFER_G8, MNG_LC_START);
-#endif
-
-  pRawi = pData->pWorkrow + pData->iPixelofs;
-  pRawo = pData->pPrevrow + pData->iPixelofs;
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples - 1; iX >= 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *pRawo++ = (mng_uint8)(((mng_uint16)*pRawi + pData->iLevel0) & 0xFF);
-
-    pRawi++;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DIFFER_G8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_differ_g16 (mng_datap pData)
-{
-  mng_uint16p pRawi, pRawo;
-  mng_int32   iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DIFFER_G16, MNG_LC_START);
-#endif
-
-  pRawi = (mng_uint16p)(pData->pWorkrow + pData->iPixelofs);
-  pRawo = (mng_uint16p)(pData->pPrevrow + pData->iPixelofs);
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples - 1; iX >= 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *pRawo++ = (mng_uint16)(((mng_uint32)*pRawi + (mng_uint32)pData->iLevel0) & 0xFFFF);
-
-    pRawi++;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DIFFER_G16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_differ_rgb8 (mng_datap pData)
-{
-  mng_uint8p pRawi, pRawo;
-  mng_int32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DIFFER_RGB8, MNG_LC_START);
-#endif
-
-  pRawi = pData->pWorkrow + pData->iPixelofs;
-  pRawo = pData->pPrevrow + pData->iPixelofs;
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples - 1; iX >= 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *(pRawo+1) = (mng_uint8)(((mng_uint16)*(pRawi+1) + pData->iLevel1) & 0xFF);
-    *pRawo     = (mng_uint8)(((mng_uint16)*pRawi     + pData->iLevel0 +
-                              (mng_uint16)*(pRawo+1)) & 0xFF);
-    *(pRawo+2) = (mng_uint8)(((mng_uint16)*(pRawi+2) + pData->iLevel2 +
-                              (mng_uint16)*(pRawo+1)) & 0xFF);
-
-    pRawi += 3;
-    pRawo += 3;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DIFFER_RGB8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_differ_rgb16 (mng_datap pData)
-{
-  mng_uint16p pRawi, pRawo;
-  mng_int32   iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DIFFER_RGB16, MNG_LC_START);
-#endif
-
-  pRawi = (mng_uint16p)(pData->pWorkrow + pData->iPixelofs);
-  pRawo = (mng_uint16p)(pData->pPrevrow + pData->iPixelofs);
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples - 1; iX >= 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *(pRawo+1) = (mng_uint16)(((mng_uint32)*(pRawi+1) + (mng_uint32)pData->iLevel1) & 0xFFFF);
-    *pRawo     = (mng_uint16)(((mng_uint32)*pRawi     + (mng_uint32)pData->iLevel0 +
-                               (mng_uint32)*(pRawo+1)) & 0xFFFF);
-    *(pRawo+2) = (mng_uint16)(((mng_uint32)*(pRawi+2) + (mng_uint32)pData->iLevel2 +
-                               (mng_uint32)*(pRawo+1)) & 0xFFFF);
-
-    pRawi += 3;
-    pRawo += 3;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DIFFER_RGB16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_differ_idx1 (mng_datap pData)
-{
-  mng_uint8p pRawi, pRawo;
-  mng_int32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DIFFER_IDX1, MNG_LC_START);
-#endif
-
-  if (pData->iLevel0 & 0x01)           /* is it uneven level ? */
-  {
-    pRawi = pData->pWorkrow + pData->iPixelofs;
-    pRawo = pData->pPrevrow + pData->iPixelofs;
-                                       /* just invert every bit */
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsize - 1; iX >= 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsize; iX++)
-#endif
-      *pRawo++ = (mng_uint8)(~(*pRawi++));
-
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DIFFER_IDX1, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_differ_idx2 (mng_datap pData)
-{
-  mng_uint8p pRawi, pRawo;
-  mng_int32  iX;
-  mng_int32  iC, iS;
-  mng_uint8  iB, iN, iQ;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DIFFER_IDX2, MNG_LC_START);
-#endif
-
-  pRawi = pData->pWorkrow + pData->iPixelofs;
-  pRawo = pData->pPrevrow + pData->iPixelofs;
-  iC    = 0;
-  iB    = 0;
-  iN    = 0;
-  iS    = 0;
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples - 1; iX >= 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    if (!iC)
-    {
-      iC = 4;
-      iB = *pRawi++;
-      iN = 0;
-      iS = 8;
-    }
-
-    iS -= 2;
-    iQ = (mng_uint8)(((iB >> iS) + pData->iLevel0) & 0x03);
-    iN = (mng_uint8)((iN << 2) + iQ);
-    iC--;
-
-    if (!iC)
-      *pRawo++ = iN;
-
-  }
-
-  if (iC)
-    *pRawo = (mng_uint8)(iN << iS);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DIFFER_IDX2, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_differ_idx4 (mng_datap pData)
-{
-  mng_uint8p pRawi, pRawo;
-  mng_int32  iX;
-  mng_int32  iC, iS;
-  mng_uint8  iB, iN, iQ;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DIFFER_IDX4, MNG_LC_START);
-#endif
-
-  pRawi = pData->pWorkrow + pData->iPixelofs;
-  pRawo = pData->pPrevrow + pData->iPixelofs;
-  iC    = 0;
-  iB    = 0;
-  iN    = 0;
-  iS    = 0;
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples - 1; iX >= 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    if (!iC)
-    {
-      iC = 2;
-      iB = *pRawi++;
-      iN = 0;
-      iS = 8;
-    }
-
-    iS -= 4;
-    iQ = (mng_uint8)(((iB >> iS) + pData->iLevel0) & 0x0F);
-    iN = (mng_uint8)((iN << 4) + iQ);
-    iC--;
-
-    if (!iC)
-      *pRawo++ = iN;
-
-  }
-
-  if (iC)
-    *pRawo = (mng_uint8)(iN << iS);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DIFFER_IDX4, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_differ_idx8 (mng_datap pData)
-{
-  mng_uint8p pRawi, pRawo;
-  mng_int32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DIFFER_IDX8, MNG_LC_START);
-#endif
-
-  pRawi = pData->pWorkrow + pData->iPixelofs;
-  pRawo = pData->pPrevrow + pData->iPixelofs;
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples - 1; iX >= 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *pRawo++ = (mng_uint8)(((mng_uint16)*pRawi + pData->iLevel0) & 0xFF);
-
-    pRawi++;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DIFFER_IDX8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_differ_ga8 (mng_datap pData)
-{
-  mng_uint8p pRawi, pRawo;
-  mng_int32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DIFFER_GA8, MNG_LC_START);
-#endif
-
-  pRawi = pData->pWorkrow + pData->iPixelofs;
-  pRawo = pData->pPrevrow + pData->iPixelofs;
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples - 1; iX >= 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *pRawo     = (mng_uint8)(((mng_uint16)*pRawi     + pData->iLevel0) & 0xFF);
-    *(pRawo+1) = (mng_uint8)(((mng_uint16)*(pRawi+1) + pData->iLevel1) & 0xFF);
-
-    pRawi += 2;
-    pRawo += 2;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DIFFER_GA8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_differ_ga16 (mng_datap pData)
-{
-  mng_uint16p pRawi, pRawo;
-  mng_int32   iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DIFFER_GA16, MNG_LC_START);
-#endif
-
-  pRawi = (mng_uint16p)(pData->pWorkrow + pData->iPixelofs);
-  pRawo = (mng_uint16p)(pData->pPrevrow + pData->iPixelofs);
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples - 1; iX >= 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *pRawo     = (mng_uint16)(((mng_uint32)*pRawi     + (mng_uint32)pData->iLevel0) & 0xFFFF);
-    *(pRawo+1) = (mng_uint16)(((mng_uint32)*(pRawi+1) + (mng_uint32)pData->iLevel1) & 0xFFFF);
-
-    pRawi += 2;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DIFFER_GA16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_differ_rgba8 (mng_datap pData)
-{
-  mng_uint8p pRawi, pRawo;
-  mng_int32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DIFFER_RGBA8, MNG_LC_START);
-#endif
-
-  pRawi = pData->pWorkrow + pData->iPixelofs;
-  pRawo = pData->pPrevrow + pData->iPixelofs;
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples - 1; iX >= 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *(pRawo+1) = (mng_uint8)(((mng_uint16)*(pRawi+1) + pData->iLevel1) & 0xFF);
-    *pRawo     = (mng_uint8)(((mng_uint16)*pRawi     + pData->iLevel0 +
-                              (mng_uint16)*(pRawo+1)) & 0xFF);
-    *(pRawo+2) = (mng_uint8)(((mng_uint16)*(pRawi+2) + pData->iLevel2 +
-                              (mng_uint16)*(pRawo+1)) & 0xFF);
-    *(pRawo+3) = (mng_uint8)(((mng_uint16)*(pRawi+3) + pData->iLevel3) & 0xFF);
-
-    pRawi += 4;
-    pRawo += 4;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DIFFER_RGBA8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_differ_rgba16 (mng_datap pData)
-{
-  mng_uint16p pRawi, pRawo;
-  mng_int32   iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DIFFER_RGBA16, MNG_LC_START);
-#endif
-
-  pRawi = (mng_uint16p)(pData->pWorkrow + pData->iPixelofs);
-  pRawo = (mng_uint16p)(pData->pPrevrow + pData->iPixelofs);
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples - 1; iX >= 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *(pRawo+1) = (mng_uint16)(((mng_uint32)*(pRawi+1) + (mng_uint32)pData->iLevel1) & 0xFFFF);
-    *pRawo     = (mng_uint16)(((mng_uint32)*pRawi     + (mng_uint32)pData->iLevel0 +
-                               (mng_uint32)*(pRawo+1)) & 0xFFFF);
-    *(pRawo+2) = (mng_uint16)(((mng_uint32)*(pRawi+2) + (mng_uint32)pData->iLevel2 +
-                               (mng_uint32)*(pRawo+1)) & 0xFFFF);
-    *(pRawo+3) = (mng_uint16)(((mng_uint32)*(pRawi+3) + (mng_uint32)pData->iLevel3) & 0xFFFF);
-
-    pRawi += 4;
-    pRawo += 4;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DIFFER_RGBA16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#endif /* FILTER192 */
-
-/* ************************************************************************** */
-
-#endif /* MNG_INCLUDE_FILTERS */
-
-/* ************************************************************************** */
-/* * end of file                                                            * */
-/* ************************************************************************** */
-
diff --git a/Source/LibMNG/libmng_filter.h b/Source/LibMNG/libmng_filter.h
deleted file mode 100644
index 9ac9c7f..0000000
--- a/Source/LibMNG/libmng_filter.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* ************************************************************************** */
-/* *             For conditions of distribution and use,                    * */
-/* *                see copyright notice in libmng.h                        * */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * project   : libmng                                                     * */
-/* * file      : libmng_filter.h           copyright (c) 2000-2002 G.Juyn   * */
-/* * version   : 1.0.5                                                      * */
-/* *                                                                        * */
-/* * purpose   : Filtering routines (definition)                            * */
-/* *                                                                        * */
-/* * author    : G.Juyn                                                     * */
-/* *                                                                        * */
-/* * comment   : Definition of the filtering routines                       * */
-/* *                                                                        * */
-/* * changes   : 0.5.1 - 05/08/2000 - G.Juyn                                * */
-/* *             - changed strict-ANSI stuff                                * */
-/* *                                                                        * */
-/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
-/* *             - changed file-prefixes                                    * */
-/* *                                                                        * */
-/* *             0.9.3 - 09/07/2000 - G.Juyn                                * */
-/* *             - added support for new filter_types                       * */
-/* *                                                                        * */
-/* *             1.0.5 - 08/19/2002 - G.Juyn                                * */
-/* *             - B597134 - libmng pollutes the linker namespace           * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
-#pragma option -A                      /* force ANSI-C */
-#endif
-
-#ifndef _libmng_filter_h_
-#define _libmng_filter_h_
-
-/* ************************************************************************** */
-
-mng_retcode mng_filter_a_row         (mng_datap pData);
-
-/* ************************************************************************** */
-
-#ifdef FILTER192
-mng_retcode mng_init_rowdiffering    (mng_datap pData);
-
-mng_retcode mng_differ_g1            (mng_datap pData);
-mng_retcode mng_differ_g2            (mng_datap pData);
-mng_retcode mng_differ_g4            (mng_datap pData);
-mng_retcode mng_differ_g8            (mng_datap pData);
-mng_retcode mng_differ_g16           (mng_datap pData);
-mng_retcode mng_differ_rgb8          (mng_datap pData);
-mng_retcode mng_differ_rgb16         (mng_datap pData);
-mng_retcode mng_differ_idx1          (mng_datap pData);
-mng_retcode mng_differ_idx2          (mng_datap pData);
-mng_retcode mng_differ_idx4          (mng_datap pData);
-mng_retcode mng_differ_idx8          (mng_datap pData);
-mng_retcode mng_differ_ga8           (mng_datap pData);
-mng_retcode mng_differ_ga16          (mng_datap pData);
-mng_retcode mng_differ_rgba8         (mng_datap pData);
-mng_retcode mng_differ_rgba16        (mng_datap pData);
-#endif
-
-/* ************************************************************************** */
-
-#endif /* _libmng_filter_h_ */
-
-/* ************************************************************************** */
-/* * end of file                                                            * */
-/* ************************************************************************** */
diff --git a/Source/LibMNG/libmng_hlapi.c b/Source/LibMNG/libmng_hlapi.c
deleted file mode 100644
index ef0c2e1..0000000
--- a/Source/LibMNG/libmng_hlapi.c
+++ /dev/null
@@ -1,2995 +0,0 @@
-/* ************************************************************************** */
-/* *             For conditions of distribution and use,                    * */
-/* *                see copyright notice in libmng.h                        * */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * project   : libmng                                                     * */
-/* * file      : libmng_hlapi.c            copyright (c) 2000-2007 G.Juyn   * */
-/* * version   : 1.0.10                                                     * */
-/* *                                                                        * */
-/* * purpose   : high-level application API (implementation)                * */
-/* *                                                                        * */
-/* * author    : G.Juyn                                                     * */
-/* *                                                                        * */
-/* * comment   : implementation of the high-level function interface        * */
-/* *             for applications.                                          * */
-/* *                                                                        * */
-/* * changes   : 0.5.1 - 05/06/2000 - G.Juyn                                * */
-/* *             - added init of iPLTEcount                                 * */
-/* *             0.5.1 - 05/08/2000 - G.Juyn                                * */
-/* *             - changed calling-convention definition                    * */
-/* *             - changed status-handling of display-routines              * */
-/* *             - added versioning-control routines                        * */
-/* *             - filled the write routine                                 * */
-/* *             - changed strict-ANSI stuff                                * */
-/* *             0.5.1 - 05/11/2000 - G.Juyn                                * */
-/* *             - added callback error-reporting support                   * */
-/* *             0.5.1 - 05/12/2000 - G.Juyn                                * */
-/* *             - changed trace to macro for callback error-reporting      * */
-/* *             0.5.1 - 05/13/2000 - G.Juyn                                * */
-/* *             - added eMNGma hack (will be removed in 1.0.0 !!!)         * */
-/* *             - added TERM animation object pointer (easier reference)   * */
-/* *             0.5.1 - 05/14/2000 - G.Juyn                                * */
-/* *             - added cleanup of saved-data (SAVE/SEEK processing)       * */
-/* *             0.5.1 - 05/16/2000 - G.Juyn                                * */
-/* *             - moved the actual write_graphic functionality from here   * */
-/* *               to its appropriate function in the mng_write module      * */
-/* *                                                                        * */
-/* *             0.5.2 - 05/19/2000 - G.Juyn                                * */
-/* *             - cleaned up some code regarding mixed support             * */
-/* *             - added JNG support                                        * */
-/* *             0.5.2 - 05/24/2000 - G.Juyn                                * */
-/* *             - moved init of default zlib parms here from "mng_zlib.c"  * */
-/* *             - added init of default IJG parms                          * */
-/* *             0.5.2 - 05/29/2000 - G.Juyn                                * */
-/* *             - fixed inconsistancy with freeing global iCCP profile     * */
-/* *             0.5.2 - 05/30/2000 - G.Juyn                                * */
-/* *             - added delta-image field initialization                   * */
-/* *             0.5.2 - 06/06/2000 - G.Juyn                                * */
-/* *             - added initialization of the buffer-suspend parameter     * */
-/* *                                                                        * */
-/* *             0.5.3 - 06/16/2000 - G.Juyn                                * */
-/* *             - added initialization of update-region for refresh        * */
-/* *             - added initialization of Needrefresh parameter            * */
-/* *             0.5.3 - 06/17/2000 - G.Juyn                                * */
-/* *             - added initialization of Deltaimmediate                   * */
-/* *             0.5.3 - 06/21/2000 - G.Juyn                                * */
-/* *             - added initialization of Speed                            * */
-/* *             - added initialization of Imagelevel                       * */
-/* *             0.5.3 - 06/26/2000 - G.Juyn                                * */
-/* *             - changed userdata variable to mng_ptr                     * */
-/* *             0.5.3 - 06/29/2000 - G.Juyn                                * */
-/* *             - fixed initialization routine for new mng_handle type     * */
-/* *                                                                        * */
-/* *             0.9.1 - 07/06/2000 - G.Juyn                                * */
-/* *             - changed mng_display_resume to allow to be called after   * */
-/* *               a suspension return with MNG_NEEDMOREDATA                * */
-/* *             - added returncode MNG_NEEDTIMERWAIT for timer breaks      * */
-/* *             0.9.1 - 07/07/2000 - G.Juyn                                * */
-/* *             - implemented support for freeze/reset/resume & go_xxxx    * */
-/* *             0.9.1 - 07/08/2000 - G.Juyn                                * */
-/* *             - added support for improved timing                        * */
-/* *             - added support for improved I/O-suspension                * */
-/* *             0.9.1 - 07/14/2000 - G.Juyn                                * */
-/* *             - changed EOF processing behavior                          * */
-/* *             0.9.1 - 07/15/2000 - G.Juyn                                * */
-/* *             - added callbacks for SAVE/SEEK processing                 * */
-/* *             - added variable for NEEDSECTIONWAIT breaks                * */
-/* *             - added variable for freeze & reset processing             * */
-/* *             0.9.1 - 07/17/2000 - G.Juyn                                * */
-/* *             - added error cleanup processing                           * */
-/* *             - fixed support for mng_display_reset()                    * */
-/* *             - fixed suspension-buffering for 32K+ chunks               * */
-/* *                                                                        * */
-/* *             0.9.2 - 07/29/2000 - G.Juyn                                * */
-/* *             - fixed small bugs in display processing                   * */
-/* *             0.9.2 - 07/31/2000 - G.Juyn                                * */
-/* *             - fixed wrapping of suspension parameters                  * */
-/* *             0.9.2 - 08/04/2000 - G.Juyn                                * */
-/* *             - B111096 - fixed large-buffer read-suspension             * */
-/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
-/* *             - changed file-prefixes                                    * */
-/* *                                                                        * */
-/* *             0.9.3 - 09/07/2000 - G.Juyn                                * */
-/* *             - added support for new filter_types                       * */
-/* *             0.9.3 - 09/10/2000 - G.Juyn                                * */
-/* *             - fixed DEFI behavior                                      * */
-/* *             0.9.3 - 10/11/2000 - G.Juyn                                * */
-/* *             - added support for nEED                                   * */
-/* *             0.9.3 - 10/16/2000 - G.Juyn                                * */
-/* *             - added optional support for bKGD for PNG images           * */
-/* *             - raised initial maximum canvas size                       * */
-/* *             - added support for JDAA                                   * */
-/* *             0.9.3 - 10/17/2000 - G.Juyn                                * */
-/* *             - added callback to process non-critical unknown chunks    * */
-/* *             - fixed support for delta-images during read() / display() * */
-/* *             0.9.3 - 10/18/2000 - G.Juyn                                * */
-/* *             - added closestream() processing for mng_cleanup()         * */
-/* *             0.9.3 - 10/27/2000 - G.Juyn                                * */
-/* *             - fixed separate read() & display() processing             * */
-/* *                                                                        * */
-/* *             0.9.4 - 11/20/2000 - G.Juyn                                * */
-/* *             - fixed unwanted repetition in mng_readdisplay()           * */
-/* *             0.9.4 - 11/24/2000 - G.Juyn                                * */
-/* *             - moved restore of object 0 to libmng_display              * */
-/* *                                                                        * */
-/* *             1.0.1 - 02/08/2001 - G.Juyn                                * */
-/* *             - added MEND processing callback                           * */
-/* *             1.0.1 - 02/13/2001 - G.Juyn                                * */
-/* *             - fixed first FRAM_MODE=4 timing problem                   * */
-/* *             1.0.1 - 04/21/2001 - G.Juyn                                * */
-/* *             - fixed bug with display_reset/display_resume (Thanks G!)  * */
-/* *             1.0.1 - 04/22/2001 - G.Juyn                                * */
-/* *             - fixed memory-leak (Thanks Gregg!)                        * */
-/* *             1.0.1 - 04/23/2001 - G.Juyn                                * */
-/* *             - fixed reset_rundata to drop all objects                  * */
-/* *             1.0.1 - 04/25/2001 - G.Juyn                                * */
-/* *             - moved mng_clear_cms to libmng_cms                        * */
-/* *                                                                        * */
-/* *             1.0.2 - 06/23/2001 - G.Juyn                                * */
-/* *             - added optimization option for MNG-video playback         * */
-/* *             - added processterm callback                               * */
-/* *             1.0.2 - 06/25/2001 - G.Juyn                                * */
-/* *             - added option to turn off progressive refresh             * */
-/* *                                                                        * */
-/* *             1.0.5 - 07/08/2002 - G.Juyn                                * */
-/* *             - B578572 - removed eMNGma hack (thanks Dimitri!)          * */
-/* *             1.0.5 - 07/16/2002 - G.Juyn                                * */
-/* *             - B581625 - large chunks fail with suspension reads        * */
-/* *             1.0.5 - 08/19/2002 - G.Juyn                                * */
-/* *             - B597134 - libmng pollutes the linker namespace           * */
-/* *             1.0.5 - 09/15/2002 - G.Juyn                                * */
-/* *             - fixed LOOP iteration=0 special case                      * */
-/* *             1.0.5 - 10/07/2002 - G.Juyn                                * */
-/* *             - added another fix for misplaced TERM chunk               * */
-/* *             - completed support for condition=2 in TERM chunk          * */
-/* *             - added beta version function & constant                   * */
-/* *             1.0.5 - 10/11/2002 - G.Juyn                                * */
-/* *             - added mng_status_dynamic to supports function            * */
-/* *             1.0.5 - 11/04/2002 - G.Juyn                                * */
-/* *             - changed FRAMECOUNT/LAYERCOUNT/PLAYTIME error to warning  * */
-/* *             1.0.5 - 11/07/2002 - G.Juyn                                * */
-/* *             - added support to get totals after mng_read()             * */
-/* *             1.0.5 - 11/29/2002 - G.Juyn                                * */
-/* *             - fixed goxxxxx() support for zero values                  * */
-/* *                                                                        * */
-/* *             1.0.6 - 05/25/2003 - G.R-P                                 * */
-/* *             - added MNG_SKIPCHUNK_cHNK footprint optimizations         * */
-/* *             1.0.6 - 07/11/2003 - G.R-P                                 * */
-/* *             - added conditionals zlib and jpeg property accessors      * */
-/* *             1.0.6 - 07/14/2003 - G.R-P                                 * */
-/* *             - added conditionals around "mng_display_go*" and other    * */
-/* *               unused functions                                         * */
-/* *             1.0.6 - 07/29/2003 - G.R-P                                 * */
-/* *             - added conditionals around PAST chunk support             * */
-/* *                                                                        * */
-/* *             1.0.7 - 03/07/2004 - G. Randers-Pehrson                    * */
-/* *             - put gamma, cms-related declarations inside #ifdef        * */
-/* *             1.0.7 - 03/10/2004 - G.R-P                                 * */
-/* *             - added conditionals around openstream/closestream         * */
-/* *             1.0.7 - 03/24/2004 - G.R-P                                 * */
-/* *             - fixed zTXT -> zTXt typo                                  * */
-/* *                                                                        * */
-/* *             1.0.8 - 04/02/2004 - G.Juyn                                * */
-/* *             - added CRC existence & checking flags                     * */
-/* *             1.0.8 - 04/10/2004 - G.Juyn                                * */
-/* *             - added data-push mechanisms for specialized decoders      * */
-/* *             1.0.8 - 07/06/2004 - G.R-P                                 * */
-/* *             - defend against using undefined openstream function       * */
-/* *             1.0.8 - 08/02/2004 - G.Juyn                                * */
-/* *             - added conditional to allow easier writing of large MNG's * */
-/* *                                                                        * */
-/* *             1.0.9 - 08/17/2004 - G.R-P                                 * */
-/* *             - added more SKIPCHUNK conditionals                        * */
-/* *             1.0.9 - 09/25/2004 - G.Juyn                                * */
-/* *             - replaced MNG_TWEAK_LARGE_FILES with permanent solution   * */
-/* *             1.0.9 - 10/03/2004 - G.Juyn                                * */
-/* *             - added function to retrieve current FRAM delay            * */
-/* *             1.0.9 - 12/20/2004 - G.Juyn                                * */
-/* *             - cleaned up macro-invocations (thanks to D. Airlie)       * */
-/* *                                                                        * */
-/* *             1.0.10 - 07/06/2005 - G.R-P                                * */
-/* *             - added more SKIPCHUNK conditionals                        * */
-/* *             1.0.10 - 04/08/2007 - G.Juyn                               * */
-/* *             - added support for mPNG proposal                          * */
-/* *             1.0.10 - 04/12/2007 - G.Juyn                               * */
-/* *             - added support for ANG proposal                           * */
-/* *             1.0.10 - 07/06/2007 - G.R-P bugfix by Lucas Quintana       * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#include "libmng.h"
-#include "libmng_data.h"
-#include "libmng_error.h"
-#include "libmng_trace.h"
-#ifdef __BORLANDC__
-#pragma hdrstop
-#endif
-#include "libmng_objects.h"
-#include "libmng_object_prc.h"
-#include "libmng_chunks.h"
-#include "libmng_memory.h"
-#include "libmng_read.h"
-#include "libmng_write.h"
-#include "libmng_display.h"
-#include "libmng_zlib.h"
-#include "libmng_jpeg.h"
-#include "libmng_cms.h"
-#include "libmng_pixels.h"
-
-#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
-#pragma option -A                      /* force ANSI-C */
-#endif
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * local routines                                                         * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-MNG_LOCAL mng_retcode mng_drop_objects (mng_datap pData,
-                                        mng_bool  bDropaniobj)
-{
-  mng_objectp       pObject;
-  mng_objectp       pNext;
-  mng_cleanupobject fCleanup;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DROP_OBJECTS, MNG_LC_START);
-#endif
-
-  pObject = pData->pFirstimgobj;       /* get first stored image-object (if any) */
-
-  while (pObject)                      /* more objects to discard ? */
-  {
-    pNext = ((mng_object_headerp)pObject)->pNext;
-                                       /* call appropriate cleanup */
-    fCleanup = ((mng_object_headerp)pObject)->fCleanup;
-    fCleanup (pData, pObject);
-
-    pObject = pNext;                   /* neeeext */
-  }
-
-  pData->pFirstimgobj = MNG_NULL;      /* clean this up!!! */
-  pData->pLastimgobj  = MNG_NULL;
-
-  if (bDropaniobj)                     /* drop animation objects ? */
-  {
-    pObject = pData->pFirstaniobj;     /* get first stored animation-object (if any) */
-
-    while (pObject)                    /* more objects to discard ? */
-    {
-      pNext = ((mng_object_headerp)pObject)->pNext;
-                                       /* call appropriate cleanup */
-      fCleanup = ((mng_object_headerp)pObject)->fCleanup;
-      fCleanup (pData, pObject);
-
-      pObject = pNext;                 /* neeeext */
-    }
-
-    pData->pFirstaniobj = MNG_NULL;    /* clean this up!!! */
-    pData->pLastaniobj  = MNG_NULL;
-
-#ifdef MNG_SUPPORT_DYNAMICMNG
-    pObject = pData->pFirstevent;      /* get first event-object (if any) */
-
-    while (pObject)                    /* more objects to discard ? */
-    {
-      pNext = ((mng_object_headerp)pObject)->pNext;
-                                       /* call appropriate cleanup */
-      fCleanup = ((mng_object_headerp)pObject)->fCleanup;
-      fCleanup (pData, pObject);
-
-      pObject = pNext;                 /* neeeext */
-    }
-
-    pData->pFirstevent = MNG_NULL;     /* clean this up!!! */
-    pData->pLastevent  = MNG_NULL;
-#endif
-  }
-
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-  if (pData->pMPNG)                    /* drop MPNG data (if any) */
-  {
-    fCleanup = ((mng_object_headerp)pData->pMPNG)->fCleanup;
-    fCleanup (pData, pData->pMPNG);
-    pData->pMPNG = MNG_NULL;
-  }
-#endif
-
-#ifdef MNG_INCLUDE_ANG_PROPOSAL
-  if (pData->pANG)                     /* drop ANG data (if any) */
-  {
-    fCleanup = ((mng_object_headerp)pData->pANG)->fCleanup;
-    fCleanup (pData, pData->pANG);
-    pData->pANG = MNG_NULL;
-  }
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DROP_OBJECTS, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-#ifndef MNG_SKIPCHUNK_SAVE
-MNG_LOCAL mng_retcode mng_drop_savedata (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DROP_SAVEDATA, MNG_LC_START);
-#endif
-
-  if (pData->pSavedata)                /* sanity check */
-  {                                    /* address it more directly */
-    mng_savedatap pSave = pData->pSavedata;
-
-    if (pSave->iGlobalProfilesize)     /* cleanup the profile ? */
-      MNG_FREEX (pData, pSave->pGlobalProfile, pSave->iGlobalProfilesize);
-                                       /* cleanup the save structure */
-    MNG_FREE (pData, pData->pSavedata, sizeof (mng_savedata));
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DROP_SAVEDATA, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-MNG_LOCAL mng_retcode mng_reset_rundata (mng_datap pData)
-{
-  mng_drop_invalid_objects (pData);    /* drop invalidly stored objects */
-#ifndef MNG_SKIPCHUNK_SAVE
-  mng_drop_savedata        (pData);    /* drop stored savedata */
-#endif
-  mng_reset_objzero        (pData);    /* reset object 0 */
-                                       /* drop stored objects (if any) */
-  mng_drop_objects         (pData, MNG_FALSE);
-
-  pData->bFramedone            = MNG_FALSE;
-  pData->iFrameseq             = 0;    /* reset counters & stuff */
-  pData->iLayerseq             = 0;
-  pData->iFrametime            = 0;
-
-  pData->bSkipping             = MNG_FALSE;
-
-#ifdef MNG_SUPPORT_DYNAMICMNG
-  pData->bRunningevent         = MNG_FALSE;
-  pData->bStopafterseek        = MNG_FALSE;
-  pData->iEventx               = 0;
-  pData->iEventy               = 0;
-  pData->pLastmousemove        = MNG_NULL;
-#endif
-
-  pData->iRequestframe         = 0;
-  pData->iRequestlayer         = 0;
-  pData->iRequesttime          = 0;
-  pData->bSearching            = MNG_FALSE;
-
-  pData->iRuntime              = 0;
-  pData->iSynctime             = 0;
-  pData->iStarttime            = 0;
-  pData->iEndtime              = 0;
-  pData->bRunning              = MNG_FALSE;
-  pData->bTimerset             = MNG_FALSE;
-  pData->iBreakpoint           = 0;
-  pData->bSectionwait          = MNG_FALSE;
-  pData->bFreezing             = MNG_FALSE;
-  pData->bResetting            = MNG_FALSE;
-  pData->bNeedrefresh          = MNG_FALSE;
-  pData->bOnlyfirstframe       = MNG_FALSE;
-  pData->iFramesafterTERM      = 0;
-
-  pData->iIterations           = 0;
-                                       /* start of animation objects! */
-  pData->pCurraniobj           = MNG_NULL;
-
-  pData->iUpdateleft           = 0;    /* reset region */
-  pData->iUpdateright          = 0;
-  pData->iUpdatetop            = 0;
-  pData->iUpdatebottom         = 0;
-  pData->iPLTEcount            = 0;    /* reset PLTE data */
-
-#ifndef MNG_SKIPCHUNK_DEFI
-  pData->iDEFIobjectid         = 0;    /* reset DEFI data */
-  pData->bDEFIhasdonotshow     = MNG_FALSE;
-  pData->iDEFIdonotshow        = 0;
-  pData->bDEFIhasconcrete      = MNG_FALSE;
-  pData->iDEFIconcrete         = 0;
-  pData->bDEFIhasloca          = MNG_FALSE;
-  pData->iDEFIlocax            = 0;
-  pData->iDEFIlocay            = 0;
-  pData->bDEFIhasclip          = MNG_FALSE;
-  pData->iDEFIclipl            = 0;
-  pData->iDEFIclipr            = 0;
-  pData->iDEFIclipt            = 0;
-  pData->iDEFIclipb            = 0;
-#endif
-
-#ifndef MNG_SKIPCHUNK_BACK
-  pData->iBACKred              = 0;    /* reset BACK data */
-  pData->iBACKgreen            = 0;
-  pData->iBACKblue             = 0;
-  pData->iBACKmandatory        = 0;
-  pData->iBACKimageid          = 0;
-  pData->iBACKtile             = 0;
-#endif
-
-#ifndef MNG_SKIPCHUNK_FRAM
-  pData->iFRAMmode             = 1;     /* default global FRAM variables */
-  pData->iFRAMdelay            = 1;
-  pData->iFRAMtimeout          = 0x7fffffffl;
-  pData->bFRAMclipping         = MNG_FALSE;
-  pData->iFRAMclipl            = 0;
-  pData->iFRAMclipr            = 0;
-  pData->iFRAMclipt            = 0;
-  pData->iFRAMclipb            = 0;
-
-  pData->iFramemode            = 1;     /* again for the current frame */
-  pData->iFramedelay           = 1;
-  pData->iFrametimeout         = 0x7fffffffl;
-  pData->bFrameclipping        = MNG_FALSE;
-  pData->iFrameclipl           = 0;
-  pData->iFrameclipr           = 0;
-  pData->iFrameclipt           = 0;
-  pData->iFrameclipb           = 0;
-
-  pData->iNextdelay            = 1;
-#endif
-
-#ifndef MNG_SKIPCHUNK_SHOW
-  pData->iSHOWmode             = 0;    /* reset SHOW data */
-  pData->iSHOWfromid           = 0;
-  pData->iSHOWtoid             = 0;
-  pData->iSHOWnextid           = 0;
-  pData->iSHOWskip             = 0;
-#endif
-
-  pData->iGlobalPLTEcount      = 0;    /* reset global PLTE data */
-
-  pData->iGlobalTRNSrawlen     = 0;    /* reset global tRNS data */
-
-  pData->iGlobalGamma          = 0;    /* reset global gAMA data */
-
-#ifndef MNG_SKIPCHUNK_cHRM
-  pData->iGlobalWhitepointx    = 0;    /* reset global cHRM data */
-  pData->iGlobalWhitepointy    = 0;
-  pData->iGlobalPrimaryredx    = 0;
-  pData->iGlobalPrimaryredy    = 0;
-  pData->iGlobalPrimarygreenx  = 0;
-  pData->iGlobalPrimarygreeny  = 0;
-  pData->iGlobalPrimarybluex   = 0;
-  pData->iGlobalPrimarybluey   = 0;
-#endif
-
-#ifndef MNG_SKIPCHUNK_sRGB
-  pData->iGlobalRendintent     = 0;    /* reset global sRGB data */
-#endif
-
-#ifndef MNG_SKIPCHUNK_iCCP
-  if (pData->iGlobalProfilesize)       /* drop global profile (if any) */
-    MNG_FREE (pData, pData->pGlobalProfile, pData->iGlobalProfilesize);
-
-  pData->iGlobalProfilesize    = 0;    
-#endif
-
-#ifndef MNG_SKIPCHUNK_bKGD
-  pData->iGlobalBKGDred        = 0;    /* reset global bKGD data */
-  pData->iGlobalBKGDgreen      = 0;
-  pData->iGlobalBKGDblue       = 0;
-#endif
-#ifndef MNG_NO_DELTA_PNG
-                                       /* reset delta-image */
-  pData->pDeltaImage           = MNG_NULL;
-  pData->iDeltaImagetype       = 0;
-  pData->iDeltatype            = 0;
-  pData->iDeltaBlockwidth      = 0;
-  pData->iDeltaBlockheight     = 0;
-  pData->iDeltaBlockx          = 0;
-  pData->iDeltaBlocky          = 0;
-  pData->bDeltaimmediate       = MNG_FALSE;
-
-  pData->fDeltagetrow          = MNG_NULL;
-  pData->fDeltaaddrow          = MNG_NULL;
-  pData->fDeltareplacerow      = MNG_NULL;
-  pData->fDeltaputrow          = MNG_NULL;
-
-  pData->fPromoterow           = MNG_NULL;
-  pData->fPromBitdepth         = MNG_NULL;
-  pData->pPromBuf              = MNG_NULL;
-  pData->iPromColortype        = 0;
-  pData->iPromBitdepth         = 0;
-  pData->iPromFilltype         = 0;
-  pData->iPromWidth            = 0;
-  pData->pPromSrc              = MNG_NULL;
-  pData->pPromDst              = MNG_NULL;
-#endif
-
-#ifndef MNG_SKIPCHUNK_MAGN
-  pData->iMAGNfromid           = 0;
-  pData->iMAGNtoid             = 0;
-#endif
-
-#ifndef MNG_SKIPCHUNK_PAST
-  pData->iPastx                = 0;
-  pData->iPasty                = 0;
-#endif
-
-  pData->pLastseek             = MNG_NULL;
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-
-MNG_LOCAL void cleanup_errors (mng_datap pData)
-{
-  pData->iErrorcode = MNG_NOERROR;
-  pData->iSeverity  = 0;
-  pData->iErrorx1   = 0;
-  pData->iErrorx2   = 0;
-  pData->zErrortext = MNG_NULL;
-
-  return;
-}
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_READ
-MNG_LOCAL mng_retcode make_pushbuffer (mng_datap       pData,
-                                       mng_ptr         pPushdata,
-                                       mng_size_t      iLength,
-                                       mng_bool        bTakeownership,
-                                       mng_pushdatap * pPush)
-{
-  mng_pushdatap pTemp;
-
-  MNG_ALLOC (pData, pTemp, sizeof(mng_pushdata));
-
-  pTemp->pNext      = MNG_NULL;
-
-  if (bTakeownership)                  /* are we going to own the buffer? */
-  {                                    /* then just copy the pointer */
-    pTemp->pData    = (mng_uint8p)pPushdata;
-  }
-  else
-  {                                    /* otherwise create new buffer */
-    MNG_ALLOCX (pData, pTemp->pData, iLength);
-    if (!pTemp->pData)                 /* succeeded? */
-    {
-      MNG_FREEX (pData, pTemp, sizeof(mng_pushdata));
-      MNG_ERROR (pData, MNG_OUTOFMEMORY);
-    }
-                                       /* and copy the bytes across */
-    MNG_COPY (pTemp->pData, pPushdata, iLength);
-  }
-
-  pTemp->iLength    = iLength;
-  pTemp->bOwned     = bTakeownership;
-  pTemp->pDatanext  = pTemp->pData;
-  pTemp->iRemaining = iLength;
-
-  *pPush            = pTemp;           /* return it */
-
-  return MNG_NOERROR;                  /* and all's well */
-}
-#endif
-
-#ifdef MNG_VERSION_QUERY_SUPPORT
-/* ************************************************************************** */
-/* *                                                                        * */
-/* *  Versioning control                                                    * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-mng_pchar MNG_DECL mng_version_text    (void)
-{
-  return MNG_VERSION_TEXT;
-}
-
-/* ************************************************************************** */
-
-mng_uint8 MNG_DECL mng_version_so      (void)
-{
-  return MNG_VERSION_SO;
-}
-
-/* ************************************************************************** */
-
-mng_uint8 MNG_DECL mng_version_dll     (void)
-{
-  return MNG_VERSION_DLL;
-}
-
-/* ************************************************************************** */
-
-mng_uint8 MNG_DECL mng_version_major   (void)
-{
-  return MNG_VERSION_MAJOR;
-}
-
-/* ************************************************************************** */
-
-mng_uint8 MNG_DECL mng_version_minor   (void)
-{
-  return MNG_VERSION_MINOR;
-}
-
-/* ************************************************************************** */
-
-mng_uint8 MNG_DECL mng_version_release (void)
-{
-  return MNG_VERSION_RELEASE;
-}
-
-/* ************************************************************************** */
-
-mng_bool MNG_DECL mng_version_beta (void)
-{
-  return MNG_VERSION_BETA;
-}
-#endif
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * 'supports' function                                                    * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_FUNCQUERY
-typedef struct {
-                 mng_pchar  zFunction;
-                 mng_uint8  iMajor;    /* Major == 0 means not implemented ! */ 
-                 mng_uint8  iMinor;
-                 mng_uint8  iRelease;
-               } mng_func_entry;
-typedef mng_func_entry const * mng_func_entryp;
-
-MNG_LOCAL mng_func_entry const func_table [] =
-  {                                    /* keep it alphabetically sorted !!!!! */
-    {"mng_cleanup",                1, 0, 0},
-    {"mng_copy_chunk",             1, 0, 5},
-    {"mng_create",                 1, 0, 0},
-    {"mng_display",                1, 0, 0},
-    {"mng_display_freeze",         1, 0, 0},
-#ifndef MNG_NO_DISPLAY_GO_SUPPORTED
-    {"mng_display_goframe",        1, 0, 0},
-    {"mng_display_golayer",        1, 0, 0},
-    {"mng_display_gotime",         1, 0, 0},
-#endif
-    {"mng_display_reset",          1, 0, 0},
-    {"mng_display_resume",         1, 0, 0},
-    {"mng_get_alphabitdepth",      1, 0, 0},
-    {"mng_get_alphacompression",   1, 0, 0},
-    {"mng_get_alphadepth",         1, 0, 0},
-    {"mng_get_alphafilter",        1, 0, 0},
-    {"mng_get_alphainterlace",     1, 0, 0},
-    {"mng_get_bgcolor",            1, 0, 0},
-    {"mng_get_bitdepth",           1, 0, 0},
-    {"mng_get_bkgdstyle",          1, 0, 0},
-    {"mng_get_cacheplayback",      1, 0, 2},
-    {"mng_get_canvasstyle",        1, 0, 0},
-    {"mng_get_colortype",          1, 0, 0},
-    {"mng_get_compression",        1, 0, 0},
-#ifndef MNG_NO_CURRENT_INFO
-    {"mng_get_currentframe",       1, 0, 0},
-    {"mng_get_currentlayer",       1, 0, 0},
-    {"mng_get_currentplaytime",    1, 0, 0},
-#endif
-    {"mng_get_currframdelay",      1, 0, 9},
-#ifndef MNG_NO_DFLT_INFO
-    {"mng_get_dfltimggamma",       1, 0, 0},
-    {"mng_get_dfltimggammaint",    1, 0, 0},
-#endif
-    {"mng_get_displaygamma",       1, 0, 0},
-    {"mng_get_displaygammaint",    1, 0, 0},
-    {"mng_get_doprogressive",      1, 0, 2},
-    {"mng_get_filter",             1, 0, 0},
-    {"mng_get_framecount",         1, 0, 0},
-    {"mng_get_imageheight",        1, 0, 0},
-    {"mng_get_imagelevel",         1, 0, 0},
-    {"mng_get_imagetype",          1, 0, 0},
-    {"mng_get_imagewidth",         1, 0, 0},
-    {"mng_get_interlace",          1, 0, 0},
-#ifdef MNG_ACCESS_JPEG
-    {"mng_get_jpeg_dctmethod",     1, 0, 0},
-    {"mng_get_jpeg_maxjdat",       1, 0, 0},
-    {"mng_get_jpeg_optimized",     1, 0, 0},
-    {"mng_get_jpeg_progressive",   1, 0, 0},
-    {"mng_get_jpeg_quality",       1, 0, 0},
-    {"mng_get_jpeg_smoothing",     1, 0, 0},
-#endif
-    {"mng_get_lastbackchunk",      1, 0, 3},
-    {"mng_get_lastseekname",       1, 0, 5},
-    {"mng_get_layercount",         1, 0, 0},
-#ifndef MNG_SKIP_MAXCANVAS
-    {"mng_get_maxcanvasheight",    1, 0, 0},
-    {"mng_get_maxcanvaswidth",     1, 0, 0},
-#endif
-    {"mng_get_playtime",           1, 0, 0},
-    {"mng_get_refreshpass",        1, 0, 0},
-    {"mng_get_runtime",            1, 0, 0},
-    {"mng_get_sectionbreaks",      1, 0, 0},
-    {"mng_get_sigtype",            1, 0, 0},
-    {"mng_get_simplicity",         1, 0, 0},
-    {"mng_get_speed",              1, 0, 0},
-    {"mng_get_srgb",               1, 0, 0},
-    {"mng_get_starttime",          1, 0, 0},
-    {"mng_get_storechunks",        1, 0, 0},
-    {"mng_get_suspensionmode",     1, 0, 0},
-    {"mng_get_ticks",              1, 0, 0},
-#ifndef MNG_NO_CURRENT_INFO
-    {"mng_get_totalframes",        1, 0, 5},
-    {"mng_get_totallayers",        1, 0, 5},
-    {"mng_get_totalplaytime",      1, 0, 5},
-#endif
-    {"mng_get_usebkgd",            1, 0, 0},
-    {"mng_get_userdata",           1, 0, 0},
-#if defined(MNG_FULL_CMS) || defined(MNG_GAMMA_ONLY) || defined(MNG_APP_CMS)
-    {"mng_get_viewgamma",          1, 0, 0},
-    {"mng_get_viewgammaint",       1, 0, 0},
-#endif
-#ifdef MNG_ACCESS_ZLIB
-    {"mng_get_zlib_level",         1, 0, 0},
-    {"mng_get_zlib_maxidat",       1, 0, 0},
-    {"mng_get_zlib_memlevel",      1, 0, 0},
-    {"mng_get_zlib_method",        1, 0, 0},
-    {"mng_get_zlib_strategy",      1, 0, 0},
-    {"mng_get_zlib_windowbits",    1, 0, 0},
-#endif
-#ifndef MNG_NO_OPEN_CLOSE_STREAM
-    {"mng_getcb_closestream",      1, 0, 0},
-#endif
-    {"mng_getcb_errorproc",        1, 0, 0},
-    {"mng_getcb_getalphaline",     1, 0, 0},
-    {"mng_getcb_getbkgdline",      1, 0, 0},
-    {"mng_getcb_getcanvasline",    1, 0, 0},
-    {"mng_getcb_gettickcount",     1, 0, 0},
-    {"mng_getcb_memalloc",         1, 0, 0},
-    {"mng_getcb_memfree",          1, 0, 0},
-#ifndef MNG_NO_OPEN_CLOSE_STREAM
-    {"mng_getcb_openstream",       1, 0, 0},
-#endif
-    {"mng_getcb_processarow",      1, 0, 0},
-    {"mng_getcb_processchroma",    1, 0, 0},
-    {"mng_getcb_processgamma",     1, 0, 0},
-    {"mng_getcb_processheader",    1, 0, 0},
-    {"mng_getcb_processiccp",      1, 0, 0},
-    {"mng_getcb_processmend",      1, 0, 1},
-    {"mng_getcb_processneed",      1, 0, 0},
-    {"mng_getcb_processsave",      1, 0, 0},
-    {"mng_getcb_processseek",      1, 0, 0},
-    {"mng_getcb_processsrgb",      1, 0, 0},
-    {"mng_getcb_processterm",      1, 0, 2},
-    {"mng_getcb_processtext",      1, 0, 0},
-    {"mng_getcb_processunknown",   1, 0, 0},
-    {"mng_getcb_readdata",         1, 0, 0},
-    {"mng_getcb_refresh",          1, 0, 0},
-    {"mng_getcb_releasedata",      1, 0, 8},
-    {"mng_getcb_settimer",         1, 0, 0},
-    {"mng_getcb_traceproc",        1, 0, 0},
-    {"mng_getcb_writedata",        1, 0, 0},
-    {"mng_getchunk_back",          1, 0, 0},
-    {"mng_getchunk_basi",          1, 0, 0},
-#ifndef MNG_SKIPCHUNK_bKGD
-    {"mng_getchunk_bkgd",          1, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_cHRM
-    {"mng_getchunk_chrm",          1, 0, 0},
-#endif
-    {"mng_getchunk_clip",          1, 0, 0},
-    {"mng_getchunk_clon",          1, 0, 0},
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_SKIPCHUNK_dBYK
-    {"mng_getchunk_dbyk",          1, 0, 0},
-#endif
-#endif
-    {"mng_getchunk_defi",          1, 0, 0},
-#ifndef MNG_NO_DELTA_PNG
-    {"mng_getchunk_dhdr",          1, 0, 0},
-#endif
-    {"mng_getchunk_disc",          1, 0, 0},
-#ifndef MNG_NO_DELTA_PNG
-    {"mng_getchunk_drop",          1, 0, 0},
-#endif
-    {"mng_getchunk_endl",          1, 0, 0},
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-    {"mng_getchunk_mpng",          1, 0, 10},
-    {"mng_getchunk_mpng_frame",    1, 0, 10},
-#endif
-#ifndef MNG_SKIPCHUNK_evNT
-    {"mng_getchunk_evnt",          1, 0, 5},
-    {"mng_getchunk_evnt_entry",    1, 0, 5},
-#endif
-#ifndef MNG_SKIPCHUNK_eXPI
-    {"mng_getchunk_expi",          1, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_fPRI
-    {"mng_getchunk_fpri",          1, 0, 0},
-#endif
-    {"mng_getchunk_fram",          1, 0, 0},
-    {"mng_getchunk_gama",          1, 0, 0},
-#ifndef MNG_SKIPCHUNK_hIST
-    {"mng_getchunk_hist",          1, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_iCCP
-    {"mng_getchunk_iccp",          1, 0, 0},
-#endif
-    {"mng_getchunk_idat",          1, 0, 0},
-    {"mng_getchunk_iend",          1, 0, 0},
-    {"mng_getchunk_ihdr",          1, 0, 0},
-#ifndef MNG_NO_DELTA_PNG
-#ifdef MNG_INCLUDE_JNG
-    {"mng_getchunk_ijng",          1, 0, 0},
-#endif
-    {"mng_getchunk_ipng",          1, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_iTXt
-    {"mng_getchunk_itxt",          1, 0, 0},
-#endif
-#ifdef MNG_INCLUDE_JNG
-    {"mng_getchunk_jdaa",          1, 0, 0},
-    {"mng_getchunk_jdat",          1, 0, 0},
-    {"mng_getchunk_jhdr",          1, 0, 0},
-    {"mng_getchunk_jsep",          1, 0, 0},
-#endif
-    {"mng_getchunk_loop",          1, 0, 0},
-#ifndef MNG_SKIPCHUNK_MAGN
-    {"mng_getchunk_magn",          1, 0, 0},
-#endif
-    {"mng_getchunk_mend",          1, 0, 0},
-    {"mng_getchunk_mhdr",          1, 0, 0},
-    {"mng_getchunk_move",          1, 0, 0},
-#ifndef MNG_SKIPCHUNK_nEED
-    {"mng_getchunk_need",          1, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_ORDR
-#ifndef MNG_NO_DELTA_PNG
-    {"mng_getchunk_ordr",          1, 0, 0},
-    {"mng_getchunk_ordr_entry",    1, 0, 0},
-#endif
-#endif
-#ifndef MNG_SKIPCHUNK_PAST
-    {"mng_getchunk_past",          1, 0, 0},
-    {"mng_getchunk_past_src",      1, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_pHYg
-    {"mng_getchunk_phyg",          1, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_pHYs
-    {"mng_getchunk_phys",          1, 0, 0},
-#endif
-#ifndef MNG_NO_DELTA_PNG
-    {"mng_getchunk_plte",          1, 0, 0},
-    {"mng_getchunk_pplt",          1, 0, 0},
-    {"mng_getchunk_pplt_entry",    1, 0, 0},
-    {"mng_getchunk_prom",          1, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_SAVE
-    {"mng_getchunk_save",          1, 0, 0},
-    {"mng_getchunk_save_entry",    1, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_sBIT
-    {"mng_getchunk_sbit",          1, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_SEEK
-    {"mng_getchunk_seek",          1, 0, 0},
-#endif
-    {"mng_getchunk_show",          1, 0, 0},
-#ifndef MNG_SKIPCHUNK_sPLT
-    {"mng_getchunk_splt",          1, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_sRGB
-    {"mng_getchunk_srgb",          1, 0, 0},
-#endif
-    {"mng_getchunk_term",          1, 0, 0},
-#ifndef MNG_SKIPCHUNK_tEXt
-    {"mng_getchunk_text",          1, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_tIME
-    {"mng_getchunk_time",          1, 0, 0},
-#endif
-    {"mng_getchunk_trns",          1, 0, 0},
-    {"mng_getchunk_unkown",        1, 0, 0},
-#ifndef MNG_SKIPCHUNK_zTXt
-    {"mng_getchunk_ztxt",          1, 0, 0},
-#endif
-    {"mng_getimgdata_chunk",       0, 0, 0},
-    {"mng_getimgdata_chunkseq",    0, 0, 0},
-    {"mng_getimgdata_seq",         0, 0, 0},
-    {"mng_getlasterror",           1, 0, 0},
-    {"mng_initialize",             1, 0, 0},
-    {"mng_iterate_chunks",         1, 0, 0},
-    {"mng_putchunk_back",          1, 0, 0},
-#ifndef MNG_SKIPCHUNK_BASI
-    {"mng_putchunk_basi",          1, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_bKGD
-    {"mng_putchunk_bkgd",          1, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_cHRM
-    {"mng_putchunk_chrm",          1, 0, 0},
-#endif
-    {"mng_putchunk_clip",          1, 0, 0},
-    {"mng_putchunk_clon",          1, 0, 0},
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_SKIPCHUNK_DBYK
-    {"mng_putchunk_dbyk",          1, 0, 0},
-#endif
-#endif
-    {"mng_putchunk_defi",          1, 0, 0},
-#ifndef MNG_NO_DELTA_PNG
-    {"mng_putchunk_dhdr",          1, 0, 0},
-#endif
-    {"mng_putchunk_disc",          1, 0, 0},
-#ifndef MNG_NO_DELTA_PNG
-    {"mng_putchunk_drop",          1, 0, 0},
-#endif
-    {"mng_putchunk_endl",          1, 0, 0},
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-    {"mng_putchunk_mpng",          1, 0, 10},
-    {"mng_putchunk_mpng_frame",    1, 0, 10},
-#endif
-#ifndef MNG_SKIPCHUNK_evNT
-    {"mng_putchunk_evnt",          1, 0, 5},
-    {"mng_putchunk_evnt_entry",    1, 0, 5},
-#endif
-#ifndef MNG_SKIPCHUNK_eXPI
-    {"mng_putchunk_expi",          1, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_fPRI
-    {"mng_putchunk_fpri",          1, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_FRAM
-    {"mng_putchunk_fram",          1, 0, 0},
-#endif
-    {"mng_putchunk_gama",          1, 0, 0},
-#ifndef MNG_SKIPCHUNK_hIST
-    {"mng_putchunk_hist",          1, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_iCCP
-    {"mng_putchunk_iccp",          1, 0, 0},
-#endif
-    {"mng_putchunk_idat",          1, 0, 0},
-    {"mng_putchunk_iend",          1, 0, 0},
-    {"mng_putchunk_ihdr",          1, 0, 0},
-#ifndef MNG_NO_DELTA_PNG
-#ifdef MNG_INCLUDE_JNG
-    {"mng_putchunk_ijng",          1, 0, 0},
-#endif
-    {"mng_putchunk_ipng",          1, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_iTXt
-    {"mng_putchunk_itxt",          1, 0, 0},
-#endif
-#ifdef MNG_INCLUDE_JNG
-    {"mng_putchunk_jdaa",          1, 0, 0},
-    {"mng_putchunk_jdat",          1, 0, 0},
-    {"mng_putchunk_jhdr",          1, 0, 0},
-    {"mng_putchunk_jsep",          1, 0, 0},
-#endif
-    {"mng_putchunk_loop",          1, 0, 0},
-#ifndef MNG_SKIPCHUNK_MAGN
-    {"mng_putchunk_magn",          1, 0, 0},
-#endif
-    {"mng_putchunk_mend",          1, 0, 0},
-    {"mng_putchunk_mhdr",          1, 0, 0},
-    {"mng_putchunk_move",          1, 0, 0},
-#ifndef MNG_SKIPCHUNK_nEED
-    {"mng_putchunk_need",          1, 0, 0},
-#endif
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_SKIPCHUNK_ORDR
-    {"mng_putchunk_ordr",          1, 0, 0},
-    {"mng_putchunk_ordr_entry",    1, 0, 0},
-#endif
-#endif
-#ifndef MNG_SKIPCHUNK_PAST
-    {"mng_putchunk_past",          1, 0, 0},
-    {"mng_putchunk_past_src",      1, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_pHYg
-    {"mng_putchunk_phyg",          1, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_pHYs
-    {"mng_putchunk_phys",          1, 0, 0},
-#endif
-#ifndef MNG_NO_DELTA_PNG
-    {"mng_putchunk_plte",          1, 0, 0},
-    {"mng_putchunk_pplt",          1, 0, 0},
-    {"mng_putchunk_pplt_entry",    1, 0, 0},
-    {"mng_putchunk_prom",          1, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_SAVE
-    {"mng_putchunk_save",          1, 0, 0},
-    {"mng_putchunk_save_entry",    1, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_sBIT
-    {"mng_putchunk_sbit",          1, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_SEEK
-    {"mng_putchunk_seek",          1, 0, 0},
-#endif
-    {"mng_putchunk_show",          1, 0, 0},
-#ifndef MNG_SKIPCHUNK_sPLT
-    {"mng_putchunk_splt",          1, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_sRGB
-    {"mng_putchunk_srgb",          1, 0, 0},
-#endif
-    {"mng_putchunk_term",          1, 0, 0},
-#ifndef MNG_SKIPCHUNK_tEXt
-    {"mng_putchunk_text",          1, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_tIME
-    {"mng_putchunk_time",          1, 0, 0},
-#endif
-    {"mng_putchunk_trns",          1, 0, 0},
-    {"mng_putchunk_unkown",        1, 0, 0},
-#ifndef MNG_SKIPCHUNK_zTXt
-    {"mng_putchunk_ztxt",          1, 0, 0},
-#endif
-    {"mng_putimgdata_ihdr",        0, 0, 0},
-    {"mng_putimgdata_jhdr",        0, 0, 0},
-    {"mng_reset",                  1, 0, 0},
-    {"mng_read",                   1, 0, 0},
-    {"mng_read_pushchunk",         1, 0, 8},
-    {"mng_read_pushdata",          1, 0, 8},
-    {"mng_read_pushsig",           1, 0, 8},
-    {"mng_read_resume",            1, 0, 0},
-    {"mng_readdisplay",            1, 0, 0},
-    {"mng_set_bgcolor",            1, 0, 0},
-    {"mng_set_bkgdstyle",          1, 0, 0},
-    {"mng_set_cacheplayback",      1, 0, 2},
-    {"mng_set_canvasstyle",        1, 0, 0},
-    {"mng_set_dfltimggamma",       1, 0, 0},
-#ifndef MNG_NO_DFLT_INFO
-    {"mng_set_dfltimggammaint",    1, 0, 0},
-#endif
-    {"mng_set_displaygamma",       1, 0, 0},
-    {"mng_set_displaygammaint",    1, 0, 0},
-    {"mng_set_doprogressive",      1, 0, 2},
-#ifdef MNG_ACCESS_JPEG
-    {"mng_set_jpeg_dctmethod",     1, 0, 0},
-    {"mng_set_jpeg_maxjdat",       1, 0, 0},
-    {"mng_set_jpeg_optimized",     1, 0, 0},
-    {"mng_set_jpeg_progressive",   1, 0, 0},
-    {"mng_set_jpeg_quality",       1, 0, 0},
-    {"mng_set_jpeg_smoothing",     1, 0, 0},
-#endif
-#ifndef MNG_SKIP_MAXCANVAS
-    {"mng_set_maxcanvasheight",    1, 0, 0},
-    {"mng_set_maxcanvassize",      1, 0, 0},
-    {"mng_set_maxcanvaswidth",     1, 0, 0},
-#endif
-    {"mng_set_outputprofile",      1, 0, 0},
-    {"mng_set_outputprofile2",     1, 0, 0},
-    {"mng_set_outputsrgb",         1, 0, 1},
-    {"mng_set_sectionbreaks",      1, 0, 0},
-    {"mng_set_speed",              1, 0, 0},
-    {"mng_set_srgb",               1, 0, 0},
-    {"mng_set_srgbimplicit",       1, 0, 1},
-    {"mng_set_srgbprofile",        1, 0, 0},
-    {"mng_set_srgbprofile2",       1, 0, 0},
-    {"mng_set_storechunks",        1, 0, 0},
-    {"mng_set_suspensionmode",     1, 0, 0},
-    {"mng_set_usebkgd",            1, 0, 0},
-    {"mng_set_userdata",           1, 0, 0},
-#if defined(MNG_FULL_CMS) || defined(MNG_GAMMA_ONLY) || defined(MNG_APP_CMS)
-    {"mng_set_viewgamma",          1, 0, 0},
-    {"mng_set_viewgammaint",       1, 0, 0},
-#endif
-#ifdef MNG_ACCESS_ZLIB
-    {"mng_set_zlib_level",         1, 0, 0},
-    {"mng_set_zlib_maxidat",       1, 0, 0},
-    {"mng_set_zlib_memlevel",      1, 0, 0},
-    {"mng_set_zlib_method",        1, 0, 0},
-    {"mng_set_zlib_strategy",      1, 0, 0},
-    {"mng_set_zlib_windowbits",    1, 0, 0},
-#endif
-#ifndef MNG_NO_OPEN_CLOSE_STREAM
-    {"mng_setcb_closestream",      1, 0, 0},
-#endif
-    {"mng_setcb_errorproc",        1, 0, 0},
-    {"mng_setcb_getalphaline",     1, 0, 0},
-    {"mng_setcb_getbkgdline",      1, 0, 0},
-    {"mng_setcb_getcanvasline",    1, 0, 0},
-    {"mng_setcb_gettickcount",     1, 0, 0},
-    {"mng_setcb_memalloc",         1, 0, 0},
-    {"mng_setcb_memfree",          1, 0, 0},
-#ifndef MNG_NO_OPEN_CLOSE_STREAM
-    {"mng_setcb_openstream",       1, 0, 0},
-#endif
-    {"mng_setcb_processarow",      1, 0, 0},
-    {"mng_setcb_processchroma",    1, 0, 0},
-    {"mng_setcb_processgamma",     1, 0, 0},
-    {"mng_setcb_processheader",    1, 0, 0},
-    {"mng_setcb_processiccp",      1, 0, 0},
-    {"mng_setcb_processmend",      1, 0, 1},
-    {"mng_setcb_processneed",      1, 0, 0},
-    {"mng_setcb_processsave",      1, 0, 0},
-    {"mng_setcb_processseek",      1, 0, 0},
-    {"mng_setcb_processsrgb",      1, 0, 0},
-    {"mng_setcb_processterm",      1, 0, 2},
-    {"mng_setcb_processtext",      1, 0, 0},
-    {"mng_setcb_processunknown",   1, 0, 0},
-    {"mng_setcb_readdata",         1, 0, 0},
-    {"mng_setcb_refresh",          1, 0, 0},
-    {"mng_setcb_releasedata",      1, 0, 8},
-    {"mng_setcb_settimer",         1, 0, 0},
-    {"mng_setcb_traceproc",        1, 0, 0},
-    {"mng_setcb_writedata",        1, 0, 0},
-    {"mng_status_creating",        1, 0, 0},
-    {"mng_status_displaying",      1, 0, 0},
-    {"mng_status_dynamic",         1, 0, 5},
-    {"mng_status_error",           1, 0, 0},
-    {"mng_status_reading",         1, 0, 0},
-    {"mng_status_running",         1, 0, 0},
-    {"mng_status_runningevent",    1, 0, 5},
-    {"mng_status_suspendbreak",    1, 0, 0},
-    {"mng_status_timerbreak",      1, 0, 0},
-    {"mng_status_writing",         1, 0, 0},
-    {"mng_supports_func",          1, 0, 5},
-    {"mng_trapevent",              1, 0, 5},
-    {"mng_updatemngheader",        1, 0, 0},
-    {"mng_updatemngsimplicity",    1, 0, 0},
-    {"mng_version_beta",           1, 0, 5},
-    {"mng_version_dll",            1, 0, 0},
-    {"mng_version_major",          1, 0, 0},
-    {"mng_version_minor",          1, 0, 0},
-    {"mng_version_release",        1, 0, 0},
-    {"mng_version_so",             1, 0, 0},
-    {"mng_version_text",           1, 0, 0},
-    {"mng_write",                  1, 0, 0},
-  };
-
-mng_bool MNG_DECL mng_supports_func (mng_pchar  zFunction,
-                                     mng_uint8* iMajor,
-                                     mng_uint8* iMinor,
-                                     mng_uint8* iRelease)
-{
-  mng_int32       iTop, iLower, iUpper, iMiddle;
-  mng_func_entryp pEntry;          /* pointer to found entry */
-                                   /* determine max index of table */
-  iTop = (sizeof (func_table) / sizeof (func_table [0])) - 1;
-
-  iLower  = 0;                     /* initialize binary search */
-  iMiddle = iTop >> 1;             /* start in the middle */
-  iUpper  = iTop;
-  pEntry  = 0;                     /* no goods yet! */
-
-  do                               /* the binary search itself */
-    {
-      mng_int32 iRslt = strcmp(func_table [iMiddle].zFunction, zFunction);
-      if (iRslt < 0)
-        iLower = iMiddle + 1;
-      else if (iRslt > 0)
-        iUpper = iMiddle - 1;
-      else
-      {
-        pEntry = &func_table [iMiddle];
-        break;
-      };
-
-      iMiddle = (iLower + iUpper) >> 1;
-    }
-  while (iLower <= iUpper);
-
-  if (pEntry)                      /* found it ? */
-  {
-    *iMajor   = pEntry->iMajor;
-    *iMinor   = pEntry->iMinor;
-    *iRelease = pEntry->iRelease;
-    return MNG_TRUE;
-  }
-  else
-  {
-    *iMajor   = 0;
-    *iMinor   = 0;
-    *iRelease = 0;
-    return MNG_FALSE;
-  }
-}
-#endif
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * HLAPI routines                                                         * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-mng_handle MNG_DECL mng_initialize (mng_ptr       pUserdata,
-                                    mng_memalloc  fMemalloc,
-                                    mng_memfree   fMemfree,
-                                    mng_traceproc fTraceproc)
-{
-  mng_datap   pData;
-#ifdef MNG_SUPPORT_DISPLAY
-  mng_retcode iRetcode;
-  mng_imagep  pImage;
-#endif
-
-#ifdef MNG_INTERNAL_MEMMNGMT           /* allocate the main datastruc */
-  pData = (mng_datap)calloc (1, sizeof (mng_data));
-#else
-  pData = (mng_datap)fMemalloc (sizeof (mng_data));
-#endif
-
-  if (!pData)
-    return MNG_NULL;                   /* error: out of memory?? */
-                                       /* validate the structure */
-  pData->iMagic                = MNG_MAGIC;
-                                       /* save userdata field */
-  pData->pUserdata             = pUserdata;
-                                       /* remember trace callback */
-  pData->fTraceproc            = fTraceproc;
-
-#ifdef MNG_SUPPORT_TRACE
-  if (mng_trace (pData, MNG_FN_INITIALIZE, MNG_LC_INITIALIZE))
-  {
-    MNG_FREEX (pData, pData, sizeof (mng_data));
-    return MNG_NULL;
-  }
-#endif
-                                       /* default canvas styles are 8-bit RGB */
-  pData->iCanvasstyle          = MNG_CANVAS_RGB8;
-  pData->iBkgdstyle            = MNG_CANVAS_RGB8;
-
-  pData->iBGred                = 0;  /* black */
-  pData->iBGgreen              = 0;
-  pData->iBGblue               = 0;
-
-  pData->bUseBKGD              = MNG_TRUE;
-
-#ifdef MNG_FULL_CMS
-  pData->bIssRGB               = MNG_TRUE;
-  pData->hProf1                = 0;    /* no profiles yet */
-  pData->hProf2                = 0;
-  pData->hProf3                = 0;
-  pData->hTrans                = 0;
-#endif
-
-  pData->dViewgamma            = 1.0;
-  pData->dDisplaygamma         = 2.2;
-  pData->dDfltimggamma         = 0.45455;
-                                       /* initially remember chunks */
-  pData->bStorechunks          = MNG_TRUE;
-                                       /* no breaks at section-borders */
-  pData->bSectionbreaks        = MNG_FALSE;
-                                       /* initially cache playback info */
-  pData->bCacheplayback        = MNG_TRUE;
-                                       /* progressive refresh for large images */
-  pData->bDoProgressive        = MNG_TRUE;
-                                       /* crc exists; should check; error for
-                                          critical chunks; warning for ancillery;
-                                          generate crc for output */
-  pData->iCrcmode              = MNG_CRC_DEFAULT;
-                                       /* normal animation-speed ! */
-  pData->iSpeed                = mng_st_normal;
-                                       /* initial image limits */
-  pData->iMaxwidth             = 10000;
-  pData->iMaxheight            = 10000;
-
-#ifdef MNG_INTERNAL_MEMMNGMT           /* internal management */
-  pData->fMemalloc             = MNG_NULL;
-  pData->fMemfree              = MNG_NULL;
-#else                                  /* keep callbacks */
-  pData->fMemalloc             = fMemalloc;
-  pData->fMemfree              = fMemfree;
-#endif
-                                       /* no value (yet) */
-  pData->fReleasedata          = MNG_NULL;    
-#ifndef MNG_NO_OPEN_CLOSE_STREAM
-  pData->fOpenstream           = MNG_NULL;
-  pData->fClosestream          = MNG_NULL;
-#endif
-  pData->fReaddata             = MNG_NULL;
-  pData->fWritedata            = MNG_NULL;
-  pData->fErrorproc            = MNG_NULL;
-  pData->fProcessheader        = MNG_NULL;
-  pData->fProcesstext          = MNG_NULL;
-  pData->fProcesssave          = MNG_NULL;
-  pData->fProcessseek          = MNG_NULL;
-  pData->fProcessneed          = MNG_NULL;
-  pData->fProcessmend          = MNG_NULL;
-  pData->fProcessunknown       = MNG_NULL;
-  pData->fProcessterm          = MNG_NULL;
-  pData->fGetcanvasline        = MNG_NULL;
-  pData->fGetbkgdline          = MNG_NULL;
-  pData->fGetalphaline         = MNG_NULL;
-  pData->fRefresh              = MNG_NULL;
-  pData->fGettickcount         = MNG_NULL;
-  pData->fSettimer             = MNG_NULL;
-  pData->fProcessgamma         = MNG_NULL;
-  pData->fProcesschroma        = MNG_NULL;
-  pData->fProcesssrgb          = MNG_NULL;
-  pData->fProcessiccp          = MNG_NULL;
-  pData->fProcessarow          = MNG_NULL;
-
-#if defined(MNG_SUPPORT_DISPLAY) && (defined(MNG_GAMMA_ONLY) || defined(MNG_FULL_CMS))
-  pData->dLastgamma            = 0;    /* lookup table needs first-time calc */
-#endif
-
-#ifdef MNG_SUPPORT_DISPLAY             /* create object 0 */
-  iRetcode = mng_create_imageobject (pData, 0, MNG_TRUE, MNG_TRUE, MNG_TRUE,
-                                     0, 0, 0, 0, 0, 0, 0, 0, 0, MNG_FALSE,
-                                     0, 0, 0, 0, &pImage);
-
-  if (iRetcode)                        /* on error drop out */
-  {
-    MNG_FREEX (pData, pData, sizeof (mng_data));
-    return MNG_NULL;
-  }
-
-  pData->pObjzero = pImage;
-#endif
-
-#if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_INCLUDE_LCMS)
-  mnglcms_initlibrary ();              /* init lcms particulars */
-#endif
-
-#ifdef MNG_SUPPORT_READ
-  pData->bSuspensionmode       = MNG_FALSE;
-  pData->iSuspendbufsize       = 0;
-  pData->pSuspendbuf           = MNG_NULL;
-  pData->pSuspendbufnext       = MNG_NULL;
-  pData->iSuspendbufleft       = 0;
-  pData->iChunklen             = 0;
-  pData->pReadbufnext          = MNG_NULL;
-  pData->pLargebufnext         = MNG_NULL;
-
-  pData->pFirstpushchunk       = MNG_NULL;
-  pData->pLastpushchunk        = MNG_NULL;
-  pData->pFirstpushdata        = MNG_NULL;
-  pData->pLastpushdata         = MNG_NULL;
-#endif
-
-#ifdef MNG_INCLUDE_ZLIB
-  mngzlib_initialize (pData);          /* initialize zlib structures and such */
-                                       /* default zlib compression parameters */
-  pData->iZlevel               = MNG_ZLIB_LEVEL;
-  pData->iZmethod              = MNG_ZLIB_METHOD;
-  pData->iZwindowbits          = MNG_ZLIB_WINDOWBITS;
-  pData->iZmemlevel            = MNG_ZLIB_MEMLEVEL;
-  pData->iZstrategy            = MNG_ZLIB_STRATEGY;
-                                       /* default maximum IDAT data size */
-  pData->iMaxIDAT              = MNG_MAX_IDAT_SIZE;
-#endif
-
-#ifdef MNG_INCLUDE_JNG                 /* default IJG compression parameters */
-  pData->eJPEGdctmethod        = MNG_JPEG_DCT;
-  pData->iJPEGquality          = MNG_JPEG_QUALITY;
-  pData->iJPEGsmoothing        = MNG_JPEG_SMOOTHING;
-  pData->bJPEGcompressprogr    = MNG_JPEG_PROGRESSIVE;
-  pData->bJPEGcompressopt      = MNG_JPEG_OPTIMIZED;
-                                       /* default maximum JDAT data size */
-  pData->iMaxJDAT              = MNG_MAX_JDAT_SIZE;
-#endif
-
-  mng_reset ((mng_handle)pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  if (mng_trace (pData, MNG_FN_INITIALIZE, MNG_LC_END))
-  {
-    MNG_FREEX (pData, pData, sizeof (mng_data));
-    return MNG_NULL;
-  }
-#endif
-
-  return (mng_handle)pData;            /* if we get here, we're in business */
-}
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_reset (mng_handle hHandle)
-{
-  mng_datap pData;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_RESET, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = ((mng_datap)(hHandle));      /* address main structure */
-
-#ifdef MNG_SUPPORT_DISPLAY
-#ifndef MNG_SKIPCHUNK_SAVE
-  mng_drop_savedata (pData);           /* cleanup saved-data from SAVE/SEEK */
-#endif
-#endif
-
-#if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_FULL_CMS)
-  mng_clear_cms (pData);               /* cleanup left-over cms stuff if any */
-#endif
-
-#if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_INCLUDE_JNG)
-  mngjpeg_cleanup (pData);             /* cleanup jpeg stuff */
-#endif
-
-#ifdef MNG_INCLUDE_ZLIB
-  if (pData->bInflating)               /* if we've been inflating */
-  {
-#ifdef MNG_INCLUDE_DISPLAY_PROCS
-    mng_cleanup_rowproc (pData);       /* cleanup row-processing, */
-#endif
-    mngzlib_inflatefree (pData);       /* cleanup inflate! */
-  }
-#endif /* MNG_INCLUDE_ZLIB */
-
-#ifdef MNG_SUPPORT_READ
-  if ((pData->bReading) && (!pData->bEOF))
-    mng_process_eof (pData);           /* cleanup app streaming */
-                                       /* cleanup default read buffers */
-  MNG_FREE (pData, pData->pReadbuf,    pData->iReadbufsize);
-  MNG_FREE (pData, pData->pLargebuf,   pData->iLargebufsize);
-  MNG_FREE (pData, pData->pSuspendbuf, pData->iSuspendbufsize);
-
-  while (pData->pFirstpushdata)        /* release any pushed data & chunks */
-    mng_release_pushdata (pData);
-  while (pData->pFirstpushchunk)
-    mng_release_pushchunk (pData);
-#endif
-
-#ifdef MNG_SUPPORT_WRITE               /* cleanup default write buffer */
-  MNG_FREE (pData, pData->pWritebuf, pData->iWritebufsize);
-#endif
-
-#if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
-  mng_drop_chunks  (pData);            /* drop stored chunks (if any) */
-#endif
-
-#ifdef MNG_SUPPORT_DISPLAY
-  mng_drop_objects (pData, MNG_TRUE);  /* drop stored objects (if any) */
-
-#ifndef MNG_SKIPCHUNK_iCCP
-  if (pData->iGlobalProfilesize)       /* drop global profile (if any) */
-    MNG_FREEX (pData, pData->pGlobalProfile, pData->iGlobalProfilesize);
-#endif
-#endif
-
-  pData->eSigtype              = mng_it_unknown;
-  pData->eImagetype            = mng_it_unknown;
-  pData->iWidth                = 0;    /* these are unknown yet */
-  pData->iHeight               = 0;
-  pData->iTicks                = 0;
-  pData->iLayercount           = 0;
-  pData->iFramecount           = 0;
-  pData->iPlaytime             = 0;
-  pData->iSimplicity           = 0;
-  pData->iAlphadepth           = 16;   /* assume the worst! */
-
-  pData->iImagelevel           = 0;    /* no image encountered */
-
-  pData->iMagnify              = 0;    /* 1-to-1 display */
-  pData->iOffsetx              = 0;    /* no offsets */
-  pData->iOffsety              = 0;
-  pData->iCanvaswidth          = 0;    /* let the app decide during processheader */
-  pData->iCanvasheight         = 0;
-                                       /* so far, so good */
-  pData->iErrorcode            = MNG_NOERROR;
-  pData->iSeverity             = 0;
-  pData->iErrorx1              = 0;
-  pData->iErrorx2              = 0;
-  pData->zErrortext            = MNG_NULL;
-
-#if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
-                                       /* let's assume the best scenario */
-#ifndef MNG_NO_OLD_VERSIONS
-  pData->bPreDraft48           = MNG_FALSE;
-#endif
-                                       /* the unknown chunk */
-  pData->iChunkname            = MNG_UINT_HUH;
-  pData->iChunkseq             = 0;
-  pData->pFirstchunk           = MNG_NULL;
-  pData->pLastchunk            = MNG_NULL;
-                                       /* nothing processed yet */
-  pData->bHasheader            = MNG_FALSE;
-  pData->bHasMHDR              = MNG_FALSE;
-  pData->bHasIHDR              = MNG_FALSE;
-  pData->bHasBASI              = MNG_FALSE;
-  pData->bHasDHDR              = MNG_FALSE;
-#ifdef MNG_INCLUDE_JNG
-  pData->bHasJHDR              = MNG_FALSE;
-  pData->bHasJSEP              = MNG_FALSE;
-  pData->bHasJDAA              = MNG_FALSE;
-  pData->bHasJDAT              = MNG_FALSE;
-#endif
-  pData->bHasPLTE              = MNG_FALSE;
-  pData->bHasTRNS              = MNG_FALSE;
-  pData->bHasGAMA              = MNG_FALSE;
-  pData->bHasCHRM              = MNG_FALSE;
-  pData->bHasSRGB              = MNG_FALSE;
-  pData->bHasICCP              = MNG_FALSE;
-  pData->bHasBKGD              = MNG_FALSE;
-  pData->bHasIDAT              = MNG_FALSE;
-
-  pData->bHasSAVE              = MNG_FALSE;
-  pData->bHasBACK              = MNG_FALSE;
-  pData->bHasFRAM              = MNG_FALSE;
-  pData->bHasTERM              = MNG_FALSE;
-  pData->bHasLOOP              = MNG_FALSE;
-                                       /* there's no global stuff yet either */
-  pData->bHasglobalPLTE        = MNG_FALSE;
-  pData->bHasglobalTRNS        = MNG_FALSE;
-  pData->bHasglobalGAMA        = MNG_FALSE;
-  pData->bHasglobalCHRM        = MNG_FALSE;
-  pData->bHasglobalSRGB        = MNG_FALSE;
-  pData->bHasglobalICCP        = MNG_FALSE;
-
-  pData->iDatawidth            = 0;    /* no IHDR/BASI/DHDR done yet */
-  pData->iDataheight           = 0;
-  pData->iBitdepth             = 0;
-  pData->iColortype            = 0;
-  pData->iCompression          = 0;
-  pData->iFilter               = 0;
-  pData->iInterlace            = 0;
-
-#ifdef MNG_INCLUDE_JNG
-  pData->iJHDRcolortype        = 0;    /* no JHDR data */
-  pData->iJHDRimgbitdepth      = 0;
-  pData->iJHDRimgcompression   = 0;
-  pData->iJHDRimginterlace     = 0;
-  pData->iJHDRalphabitdepth    = 0;
-  pData->iJHDRalphacompression = 0;
-  pData->iJHDRalphafilter      = 0;
-  pData->iJHDRalphainterlace   = 0;
-#endif
-
-#endif /* MNG_SUPPORT_READ || MNG_SUPPORT_WRITE */
-
-#ifdef MNG_SUPPORT_READ                /* no reading done */
-  pData->bReading              = MNG_FALSE;
-  pData->bHavesig              = MNG_FALSE;
-  pData->bEOF                  = MNG_FALSE;
-  pData->iReadbufsize          = 0;
-  pData->pReadbuf              = MNG_NULL;
-
-  pData->iLargebufsize         = 0;
-  pData->pLargebuf             = MNG_NULL;
-
-  pData->iSuspendtime          = 0;
-  pData->bSuspended            = MNG_FALSE;
-  pData->iSuspendpoint         = 0;
-
-  pData->pSuspendbufnext       = pData->pSuspendbuf;
-  pData->iSuspendbufleft       = 0;
-#endif /* MNG_SUPPORT_READ */
-
-#ifdef MNG_SUPPORT_WRITE               /* no creating/writing done */
-  pData->bCreating             = MNG_FALSE;
-  pData->bWriting              = MNG_FALSE;
-  pData->iFirstchunkadded      = 0;
-  pData->iWritebufsize         = 0;
-  pData->pWritebuf             = MNG_NULL;
-#endif /* MNG_SUPPORT_WRITE */
-
-#ifdef MNG_SUPPORT_DISPLAY             /* done nuttin' yet */
-  pData->bDisplaying           = MNG_FALSE;
-  pData->iFrameseq             = 0;
-  pData->iLayerseq             = 0;
-  pData->iFrametime            = 0;
-
-  pData->iTotallayers          = 0;
-  pData->iTotalframes          = 0;
-  pData->iTotalplaytime        = 0;
-
-  pData->bSkipping             = MNG_FALSE;
-
-#ifdef MNG_SUPPORT_DYNAMICMNG
-  pData->bDynamic              = MNG_FALSE;
-  pData->bRunningevent         = MNG_FALSE;
-  pData->bStopafterseek        = MNG_FALSE;
-  pData->iEventx               = 0;
-  pData->iEventy               = 0;
-  pData->pLastmousemove        = MNG_NULL;
-#endif
-
-  pData->iRequestframe         = 0;
-  pData->iRequestlayer         = 0;
-  pData->iRequesttime          = 0;
-  pData->bSearching            = MNG_FALSE;
-
-  pData->bRestorebkgd          = MNG_FALSE;
-
-  pData->iRuntime              = 0;
-  pData->iSynctime             = 0;
-  pData->iStarttime            = 0;
-  pData->iEndtime              = 0;
-  pData->bRunning              = MNG_FALSE;
-  pData->bTimerset             = MNG_FALSE;
-  pData->iBreakpoint           = 0;
-  pData->bSectionwait          = MNG_FALSE;
-  pData->bFreezing             = MNG_FALSE;
-  pData->bResetting            = MNG_FALSE;
-  pData->bNeedrefresh          = MNG_FALSE;
-  pData->bMisplacedTERM        = MNG_FALSE;
-  pData->bOnlyfirstframe       = MNG_FALSE;
-  pData->iFramesafterTERM      = 0;
-                                       /* these don't exist yet */
-  pData->pCurrentobj           = MNG_NULL;
-  pData->pCurraniobj           = MNG_NULL;
-  pData->pTermaniobj           = MNG_NULL;
-  pData->pLastclone            = MNG_NULL;
-  pData->pStoreobj             = MNG_NULL;
-  pData->pStorebuf             = MNG_NULL;
-  pData->pRetrieveobj          = MNG_NULL;
-                                       /* no saved data ! */
-  pData->pSavedata             = MNG_NULL;
-
-  pData->iUpdateleft           = 0;    /* no region updated yet */
-  pData->iUpdateright          = 0;
-  pData->iUpdatetop            = 0;
-  pData->iUpdatebottom         = 0;
-
-  pData->iPass                 = -1;   /* interlacing stuff and temp buffers */
-  pData->iRow                  = 0;
-  pData->iRowinc               = 1;
-  pData->iCol                  = 0;
-  pData->iColinc               = 1;
-  pData->iRowsamples           = 0;
-  pData->iSamplemul            = 0;
-  pData->iSampleofs            = 0;
-  pData->iSamplediv            = 0;
-  pData->iRowsize              = 0;
-  pData->iRowmax               = 0;
-  pData->iFilterofs            = 0;
-  pData->iPixelofs             = 1;
-  pData->iLevel0               = 0;
-  pData->iLevel1               = 0;
-  pData->iLevel2               = 0;
-  pData->iLevel3               = 0;
-  pData->pWorkrow              = MNG_NULL;
-  pData->pPrevrow              = MNG_NULL;
-  pData->pRGBArow              = MNG_NULL;
-  pData->bIsRGBA16             = MNG_TRUE;
-  pData->bIsOpaque             = MNG_TRUE;
-  pData->iFilterbpp            = 1;
-
-  pData->iSourcel              = 0;    /* always initialized just before */
-  pData->iSourcer              = 0;    /* compositing the next layer */
-  pData->iSourcet              = 0;
-  pData->iSourceb              = 0;
-  pData->iDestl                = 0;
-  pData->iDestr                = 0;
-  pData->iDestt                = 0;
-  pData->iDestb                = 0;
-                                       /* lists are empty */
-  pData->pFirstimgobj          = MNG_NULL;
-  pData->pLastimgobj           = MNG_NULL;
-  pData->pFirstaniobj          = MNG_NULL;
-  pData->pLastaniobj           = MNG_NULL;
-#ifdef MNG_SUPPORT_DYNAMICMNG
-  pData->pFirstevent           = MNG_NULL;
-  pData->pLastevent            = MNG_NULL;
-#endif
-                                       /* no processing callbacks */
-  pData->fDisplayrow           = MNG_NULL;
-  pData->fRestbkgdrow          = MNG_NULL;
-  pData->fCorrectrow           = MNG_NULL;
-  pData->fRetrieverow          = MNG_NULL;
-  pData->fStorerow             = MNG_NULL;
-  pData->fProcessrow           = MNG_NULL;
-  pData->fDifferrow            = MNG_NULL;
-  pData->fScalerow             = MNG_NULL;
-  pData->fDeltarow             = MNG_NULL;
-#ifndef MNG_SKIPCHUNK_PAST
-  pData->fFliprow              = MNG_NULL;
-  pData->fTilerow              = MNG_NULL;
-#endif
-  pData->fInitrowproc          = MNG_NULL;
-
-  pData->iPLTEcount            = 0;    /* no PLTE data */
-
-#ifndef MNG_SKIPCHUNK_DEFI
-  pData->iDEFIobjectid         = 0;    /* no DEFI data */
-  pData->bDEFIhasdonotshow     = MNG_FALSE;
-  pData->iDEFIdonotshow        = 0;
-  pData->bDEFIhasconcrete      = MNG_FALSE;
-  pData->iDEFIconcrete         = 0;
-  pData->bDEFIhasloca          = MNG_FALSE;
-  pData->iDEFIlocax            = 0;
-  pData->iDEFIlocay            = 0;
-  pData->bDEFIhasclip          = MNG_FALSE;
-  pData->iDEFIclipl            = 0;
-  pData->iDEFIclipr            = 0;
-  pData->iDEFIclipt            = 0;
-  pData->iDEFIclipb            = 0;
-#endif
-
-#ifndef MNG_SKIPCHUNK_BACK
-  pData->iBACKred              = 0;    /* no BACK data */
-  pData->iBACKgreen            = 0;
-  pData->iBACKblue             = 0;
-  pData->iBACKmandatory        = 0;
-  pData->iBACKimageid          = 0;
-  pData->iBACKtile             = 0;
-#endif
-
-#ifndef MNG_SKIPCHUNK_FRAM
-  pData->iFRAMmode             = 1;     /* default global FRAM variables */
-  pData->iFRAMdelay            = 1;
-  pData->iFRAMtimeout          = 0x7fffffffl;
-  pData->bFRAMclipping         = MNG_FALSE;
-  pData->iFRAMclipl            = 0;
-  pData->iFRAMclipr            = 0;
-  pData->iFRAMclipt            = 0;
-  pData->iFRAMclipb            = 0;
-
-  pData->iFramemode            = 1;     /* again for the current frame */
-  pData->iFramedelay           = 1;
-  pData->iFrametimeout         = 0x7fffffffl;
-  pData->bFrameclipping        = MNG_FALSE;
-  pData->iFrameclipl           = 0;
-  pData->iFrameclipr           = 0;
-  pData->iFrameclipt           = 0;
-  pData->iFrameclipb           = 0;
-
-  pData->iNextdelay            = 1;
-#endif
-
-#ifndef MNG_SKIPCHUNK_SHOW
-  pData->iSHOWmode             = 0;    /* no SHOW data */
-  pData->iSHOWfromid           = 0;
-  pData->iSHOWtoid             = 0;
-  pData->iSHOWnextid           = 0;
-  pData->iSHOWskip             = 0;
-#endif
-
-  pData->iGlobalPLTEcount      = 0;    /* no global PLTE data */
-
-  pData->iGlobalTRNSrawlen     = 0;    /* no global tRNS data */
-
-  pData->iGlobalGamma          = 0;    /* no global gAMA data */
-
-#ifndef MNG_SKIPCHUNK_cHRM
-  pData->iGlobalWhitepointx    = 0;    /* no global cHRM data */
-  pData->iGlobalWhitepointy    = 0;
-  pData->iGlobalPrimaryredx    = 0;
-  pData->iGlobalPrimaryredy    = 0;
-  pData->iGlobalPrimarygreenx  = 0;
-  pData->iGlobalPrimarygreeny  = 0;
-  pData->iGlobalPrimarybluex   = 0;
-  pData->iGlobalPrimarybluey   = 0;
-#endif
-
-  pData->iGlobalRendintent     = 0;    /* no global sRGB data */
-
-#ifndef MNG_SKIPCHUNK_iCCP
-  pData->iGlobalProfilesize    = 0;    /* no global iCCP data */
-  pData->pGlobalProfile        = MNG_NULL;
-#endif
-
-#ifndef MNG_SKIPCHUNK_bKGD
-  pData->iGlobalBKGDred        = 0;    /* no global bKGD data */
-  pData->iGlobalBKGDgreen      = 0;
-  pData->iGlobalBKGDblue       = 0;
-#endif
-                                       /* no delta-image */
-#ifndef MNG_NO_DELTA_PNG
-  pData->pDeltaImage           = MNG_NULL;
-  pData->iDeltaImagetype       = 0;
-  pData->iDeltatype            = 0;
-  pData->iDeltaBlockwidth      = 0;
-  pData->iDeltaBlockheight     = 0;
-  pData->iDeltaBlockx          = 0;
-  pData->iDeltaBlocky          = 0;
-  pData->bDeltaimmediate       = MNG_FALSE;
-
-  pData->fDeltagetrow          = MNG_NULL;
-  pData->fDeltaaddrow          = MNG_NULL;
-  pData->fDeltareplacerow      = MNG_NULL;
-  pData->fDeltaputrow          = MNG_NULL;
-
-  pData->fPromoterow           = MNG_NULL;
-  pData->fPromBitdepth         = MNG_NULL;
-  pData->pPromBuf              = MNG_NULL;
-  pData->iPromColortype        = 0;
-  pData->iPromBitdepth         = 0;
-  pData->iPromFilltype         = 0;
-  pData->iPromWidth            = 0;
-  pData->pPromSrc              = MNG_NULL;
-  pData->pPromDst              = MNG_NULL;
-#endif
-
-#ifndef MNG_SKIPCHUNK_MAGN
-  pData->iMAGNfromid           = 0;
-  pData->iMAGNtoid             = 0;
-#endif
-
-#ifndef MNG_SKIPCHUNK_PAST
-  pData->iPastx                = 0;
-  pData->iPasty                = 0;
-#endif
-
-  pData->pLastseek             = MNG_NULL;
-#endif
-
-#ifdef MNG_INCLUDE_ZLIB
-  pData->bInflating            = 0;    /* no inflating or deflating */
-  pData->bDeflating            = 0;    /* going on at the moment */
-#endif
-
-#ifdef MNG_SUPPORT_DISPLAY             /* reset object 0 */
-  mng_reset_objzero (pData);
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_RESET, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_cleanup (mng_handle* hHandle)
-{
-  mng_datap pData;                     /* local vars */
-#ifndef MNG_INTERNAL_MEMMNGMT
-  mng_memfree fFree;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)*hHandle), MNG_FN_CLEANUP, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (*hHandle)           /* check validity handle */
-  pData = ((mng_datap)(*hHandle));     /* and address main structure */
-
-  mng_reset (*hHandle);                /* do an implicit reset to cleanup most stuff */
-
-#ifdef MNG_SUPPORT_DISPLAY             /* drop object 0 */
-  mng_free_imageobject (pData, (mng_imagep)pData->pObjzero);
-#endif
-
-#if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_FULL_CMS)
-  if (pData->hProf2)                   /* output profile defined ? */
-    mnglcms_freeprofile (pData->hProf2);
-
-  if (pData->hProf3)                   /* sRGB profile defined ? */
-    mnglcms_freeprofile (pData->hProf3);
-#endif 
-
-#ifdef MNG_INCLUDE_ZLIB
-  mngzlib_cleanup (pData);             /* cleanup zlib stuff */
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)*hHandle), MNG_FN_CLEANUP, MNG_LC_CLEANUP)
-#endif
-
-  pData->iMagic = 0;                   /* invalidate the actual memory */
-
-#ifdef MNG_INTERNAL_MEMMNGMT
-  free ((void *)*hHandle);             /* cleanup the data-structure */
-#else
-  fFree = ((mng_datap)*hHandle)->fMemfree;
-  fFree ((mng_ptr)*hHandle, sizeof (mng_data));
-#endif
-
-  *hHandle = 0;                        /* wipe pointer to inhibit future use */
-
-  return MNG_NOERROR;                  /* and we're done */
-}
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_READ
-mng_retcode MNG_DECL mng_read (mng_handle hHandle)
-{
-  mng_datap   pData;                   /* local vars */
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_READ, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle and callbacks */
-  pData = ((mng_datap)hHandle);        /* and make it addressable */
-
-#ifndef MNG_INTERNAL_MEMMNGMT
-  MNG_VALIDCB (hHandle, fMemalloc)
-  MNG_VALIDCB (hHandle, fMemfree)
-#endif
-
-#ifndef MNG_NO_OPEN_CLOSE_STREAM
-  MNG_VALIDCB (hHandle, fOpenstream)
-  MNG_VALIDCB (hHandle, fClosestream)
-#endif
-  MNG_VALIDCB (hHandle, fReaddata)
-
-#ifdef MNG_SUPPORT_DISPLAY             /* valid at this point ? */
-  if ((pData->bReading) || (pData->bDisplaying))
-#else
-  if (pData->bReading)
-#endif
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID);
-
-#ifdef MNG_SUPPORT_WRITE
-  if ((pData->bWriting) || (pData->bCreating))
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID);
-#endif
-
-  if (!pData->bCacheplayback)          /* must store playback info to work!! */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID);
-
-  cleanup_errors (pData);              /* cleanup previous errors */
-
-  pData->bReading = MNG_TRUE;          /* read only! */
-
-#ifndef MNG_NO_OPEN_CLOSE_STREAM
-  if (pData->fOpenstream && !pData->fOpenstream (hHandle))
-    /* open it and start reading */
-    iRetcode = MNG_APPIOERROR;
-  else
-#endif
-    iRetcode = mng_read_graphic (pData);
-
-  if (pData->bEOF)                     /* already at EOF ? */
-  {
-    pData->bReading = MNG_FALSE;       /* then we're no longer reading */
-    
-#ifdef MNG_SUPPORT_DISPLAY
-    mng_reset_rundata (pData);         /* reset rundata */
-#endif
-  }
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-
-  if (pData->bSuspended)               /* read suspension ? */
-  {
-     iRetcode            = MNG_NEEDMOREDATA;
-     pData->iSuspendtime = pData->fGettickcount ((mng_handle)pData);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_READ, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif /* MNG_SUPPORT_READ */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_READ
-mng_retcode MNG_DECL mng_read_pushdata (mng_handle hHandle,
-                                        mng_ptr    pData,
-                                        mng_size_t iLength,
-                                        mng_bool   bTakeownership)
-{
-  mng_datap     pMyData;               /* local vars */
-  mng_pushdatap pPush;
-  mng_retcode   iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_READ_PUSHDATA, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pMyData = ((mng_datap)hHandle);      /* and make it addressable */
-                                       /* create a containing buffer */
-  iRetcode = make_pushbuffer (pMyData, pData, iLength, bTakeownership, &pPush);
-  if (iRetcode)
-    return iRetcode;
-
-  if (pMyData->pLastpushdata)          /* and update the buffer chain */
-    pMyData->pLastpushdata->pNext = pPush;
-  else
-    pMyData->pFirstpushdata = pPush;
-
-  pMyData->pLastpushdata = pPush;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_READ_PUSHDATA, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_READ */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_READ
-mng_retcode MNG_DECL mng_read_pushsig (mng_handle  hHandle,
-                                       mng_imgtype eSigtype)
-{
-  mng_datap pData;                     /* local vars */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_READ_PUSHSIG, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = ((mng_datap)hHandle);        /* and make it addressable */
-
-  if (pData->bHavesig)                 /* can we expect this call ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID);
-
-  pData->eSigtype = eSigtype;
-  pData->bHavesig = MNG_TRUE;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_READ_PUSHSIG, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_READ */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_READ
-mng_retcode MNG_DECL mng_read_pushchunk (mng_handle hHandle,
-                                         mng_ptr    pChunk,
-                                         mng_size_t iLength,
-                                         mng_bool   bTakeownership)
-{
-  mng_datap     pMyData;               /* local vars */
-  mng_pushdatap pPush;
-  mng_retcode   iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_READ_PUSHCHUNK, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pMyData = ((mng_datap)hHandle);      /* and make it addressable */
-                                       /* create a containing buffer */
-  iRetcode = make_pushbuffer (pMyData, pChunk, iLength, bTakeownership, &pPush);
-  if (iRetcode)
-    return iRetcode;
-
-  if (pMyData->pLastpushchunk)         /* and update the buffer chain */
-    pMyData->pLastpushchunk->pNext = pPush;
-  else
-    pMyData->pFirstpushchunk = pPush;
-
-  pMyData->pLastpushchunk = pPush;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_READ_PUSHCHUNK, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_READ */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_READ
-mng_retcode MNG_DECL mng_read_resume (mng_handle hHandle)
-{
-  mng_datap   pData;                   /* local vars */
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_READ_RESUME, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = ((mng_datap)hHandle);        /* and make it addressable */
-                                       /* can we expect this call ? */
-  if ((!pData->bReading) || (!pData->bSuspended))
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID);
-
-  cleanup_errors (pData);              /* cleanup previous errors */
-
-  pData->bSuspended = MNG_FALSE;       /* reset the flag */
-
-#ifdef MNG_SUPPORT_DISPLAY             /* re-synchronize ? */
-  if ((pData->bDisplaying) && (pData->bRunning))
-    pData->iSynctime  = pData->iSynctime - pData->iSuspendtime +
-                        pData->fGettickcount (hHandle);
-#endif
-
-  iRetcode = mng_read_graphic (pData); /* continue reading now */
-
-  if (pData->bEOF)                     /* at EOF ? */
-  {
-    pData->bReading = MNG_FALSE;       /* then we're no longer reading */
-    
-#ifdef MNG_SUPPORT_DISPLAY
-    mng_reset_rundata (pData);         /* reset rundata */
-#endif
-  }
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-
-  if (pData->bSuspended)               /* read suspension ? */
-  {
-     iRetcode            = MNG_NEEDMOREDATA;
-     pData->iSuspendtime = pData->fGettickcount ((mng_handle)pData);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_READ_RESUME, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif /* MNG_SUPPORT_READ */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_WRITE
-mng_retcode MNG_DECL mng_write (mng_handle hHandle)
-{
-  mng_datap   pData;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_WRITE, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle and callbacks */
-  pData = ((mng_datap)hHandle);        /* and make it addressable */
-
-#ifndef MNG_INTERNAL_MEMMNGMT
-  MNG_VALIDCB (hHandle, fMemalloc)
-  MNG_VALIDCB (hHandle, fMemfree)
-#endif
-
-#ifndef MNG_NO_OPEN_CLOSE_STREAM
-  MNG_VALIDCB (hHandle, fOpenstream)
-  MNG_VALIDCB (hHandle, fClosestream)
-#endif
-  MNG_VALIDCB (hHandle, fWritedata)
-
-#ifdef MNG_SUPPORT_READ
-  if (pData->bReading)                 /* valid at this point ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID);
-#endif
-
-  cleanup_errors (pData);              /* cleanup previous errors */
-
-  iRetcode = mng_write_graphic (pData);/* do the write */
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_WRITE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_WRITE */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_WRITE
-mng_retcode MNG_DECL mng_create (mng_handle hHandle)
-{
-  mng_datap   pData;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_CREATE, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle and callbacks */
-  pData = ((mng_datap)hHandle);        /* and make it addressable */
-
-#ifndef MNG_INTERNAL_MEMMNGMT
-  MNG_VALIDCB (hHandle, fMemalloc)
-  MNG_VALIDCB (hHandle, fMemfree)
-#endif
-
-#ifdef MNG_SUPPORT_READ
-  if (pData->bReading)                 /* valid at this point ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID);
-#endif
-
-  if ((pData->bWriting) || (pData->bCreating))
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID);
-
-  cleanup_errors (pData);              /* cleanup previous errors */
-
-  iRetcode = mng_reset (hHandle);      /* clear any previous stuff */
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-
-  pData->bCreating = MNG_TRUE;         /* indicate we're creating a new file */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_CREATE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_WRITE */
-
-/* ************************************************************************** */
-
-#if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_SUPPORT_READ)
-mng_retcode MNG_DECL mng_readdisplay (mng_handle hHandle)
-{
-  mng_datap   pData;                   /* local vars */
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_READDISPLAY, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle and callbacks */
-  pData = ((mng_datap)hHandle);        /* and make it addressable */
-
-#ifndef MNG_INTERNAL_MEMMNGMT
-  MNG_VALIDCB (hHandle, fMemalloc)
-  MNG_VALIDCB (hHandle, fMemfree)
-#endif
-
-  MNG_VALIDCB (hHandle, fReaddata)
-  MNG_VALIDCB (hHandle, fGetcanvasline)
-  MNG_VALIDCB (hHandle, fRefresh)
-  MNG_VALIDCB (hHandle, fGettickcount)
-  MNG_VALIDCB (hHandle, fSettimer)
-                                       /* valid at this point ? */
-  if ((pData->bReading) || (pData->bDisplaying))
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID);
-
-#ifdef MNG_SUPPORT_WRITE
-  if ((pData->bWriting) || (pData->bCreating))
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID);
-#endif
-
-  cleanup_errors (pData);              /* cleanup previous errors */
-
-  pData->bReading      = MNG_TRUE;     /* read & display! */
-  pData->bDisplaying   = MNG_TRUE;
-  pData->bRunning      = MNG_TRUE;
-  pData->iFrameseq     = 0;
-  pData->iLayerseq     = 0;
-  pData->iFrametime    = 0;
-  pData->iRequestframe = 0;
-  pData->iRequestlayer = 0;
-  pData->iRequesttime  = 0;
-  pData->bSearching    = MNG_FALSE;
-  pData->iRuntime      = 0;
-  pData->iSynctime     = pData->fGettickcount (hHandle);
-  pData->iSuspendtime  = 0;
-  pData->iStarttime    = pData->iSynctime;
-  pData->iEndtime      = 0;
-
-#ifndef MNG_NO_OPEN_CLOSE_STREAM
-  if (pData->fOpenstream && !pData->fOpenstream (hHandle))
-    /* open it and start reading */
-    iRetcode = MNG_APPIOERROR;
-  else
-#endif
-    iRetcode = mng_read_graphic (pData);
-
-  if (pData->bEOF)                     /* already at EOF ? */
-  {
-    pData->bReading = MNG_FALSE;       /* then we're no longer reading */
-    mng_drop_invalid_objects (pData);  /* drop invalidly stored objects */
-  }
-  
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-
-  if (pData->bSuspended)               /* read suspension ? */
-  {
-     iRetcode            = MNG_NEEDMOREDATA;
-     pData->iSuspendtime = pData->fGettickcount ((mng_handle)pData);
-  }
-  else
-  if (pData->bTimerset)                /* indicate timer break ? */
-    iRetcode = MNG_NEEDTIMERWAIT;
-  else
-  if (pData->bSectionwait)             /* indicate section break ? */
-    iRetcode = MNG_NEEDSECTIONWAIT;
-  else
-  {                                    /* no breaks = end of run */
-    pData->bRunning = MNG_FALSE;
-
-    if (pData->bFreezing)              /* dynamic MNG reached SEEK ? */
-      pData->bFreezing = MNG_FALSE;    /* reset it ! */
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_READDISPLAY, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif /* MNG_SUPPORT_DISPLAY && MNG_SUPPORT_READ */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-mng_retcode MNG_DECL mng_display (mng_handle hHandle)
-{
-  mng_datap   pData;                   /* local vars */
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle and callbacks */
-  pData = ((mng_datap)hHandle);        /* and make it addressable */
-
-#ifndef MNG_INTERNAL_MEMMNGMT
-  MNG_VALIDCB (hHandle, fMemalloc)
-  MNG_VALIDCB (hHandle, fMemfree)
-#endif
-
-  MNG_VALIDCB (hHandle, fGetcanvasline)
-  MNG_VALIDCB (hHandle, fRefresh)
-  MNG_VALIDCB (hHandle, fGettickcount)
-  MNG_VALIDCB (hHandle, fSettimer)
-
-  if (pData->bDisplaying)              /* valid at this point ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID);
-    
-#ifdef MNG_SUPPORT_READ
-  if (pData->bReading)
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID);
-#endif
-
-#ifdef MNG_SUPPORT_WRITE
-  if ((pData->bWriting) || (pData->bCreating))
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID);
-#endif
-
-  cleanup_errors (pData);              /* cleanup previous errors */
-
-  pData->bDisplaying   = MNG_TRUE;     /* display! */
-  pData->bRunning      = MNG_TRUE;
-  pData->iFrameseq     = 0;
-  pData->iLayerseq     = 0;
-  pData->iFrametime    = 0;
-  pData->iRequestframe = 0;
-  pData->iRequestlayer = 0;
-  pData->iRequesttime  = 0;
-  pData->bSearching    = MNG_FALSE;
-  pData->iRuntime      = 0;
-  pData->iSynctime     = pData->fGettickcount (hHandle);
-#ifdef MNG_SUPPORT_READ
-  pData->iSuspendtime  = 0;
-#endif  
-  pData->iStarttime    = pData->iSynctime;
-  pData->iEndtime      = 0;
-  pData->pCurraniobj   = pData->pFirstaniobj;
-                                       /* go do it */
-  iRetcode = mng_process_display (pData);
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-
-  if (pData->bTimerset)                /* indicate timer break ? */
-    iRetcode = MNG_NEEDTIMERWAIT;
-  else
-  {                                    /* no breaks = end of run */
-    pData->bRunning = MNG_FALSE;
-
-    if (pData->bFreezing)              /* dynamic MNG reached SEEK ? */
-      pData->bFreezing = MNG_FALSE;    /* reset it ! */
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-mng_retcode MNG_DECL mng_display_resume (mng_handle hHandle)
-{
-  mng_datap   pData;                   /* local vars */
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY_RESUME, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = ((mng_datap)hHandle);        /* and make it addressable */
-
-  if (!pData->bDisplaying)             /* can we expect this call ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID);
-
-  cleanup_errors (pData);              /* cleanup previous errors */
-                                       /* was it running ? */
-  if ((pData->bRunning) || (pData->bReading))
-  {                                    /* are we expecting this call ? */
-    if ((pData->bTimerset) || (pData->bSuspended) || (pData->bSectionwait)) 
-    {
-      pData->bTimerset    = MNG_FALSE; /* reset the flags */
-      pData->bSectionwait = MNG_FALSE;
-
-#ifdef MNG_SUPPORT_READ
-      if (pData->bReading)             /* set during read&display ? */
-      {
-        if (pData->bSuspended)         /* calculate proper synchronization */
-          pData->iSynctime = pData->iSynctime - pData->iSuspendtime +
-                             pData->fGettickcount (hHandle);
-        else
-          pData->iSynctime = pData->fGettickcount (hHandle);
-
-        pData->bSuspended = MNG_FALSE; /* now reset this flag */  
-                                       /* and continue reading */
-        iRetcode = mng_read_graphic (pData);
-
-        if (pData->bEOF)               /* already at EOF ? */
-        {
-          pData->bReading = MNG_FALSE; /* then we're no longer reading */
-                                       /* drop invalidly stored objects */
-          mng_drop_invalid_objects (pData);
-        }
-      }
-      else
-#endif /* MNG_SUPPORT_READ */
-      {                                /* synchronize timing */
-        pData->iSynctime = pData->fGettickcount (hHandle);
-                                       /* resume display processing */
-        iRetcode = mng_process_display (pData);
-      }
-    }
-    else
-    {
-      MNG_ERROR (pData, MNG_FUNCTIONINVALID);
-    }
-  }
-  else
-  {                                    /* synchronize timing */
-    pData->iSynctime = pData->fGettickcount (hHandle);
-    pData->bRunning  = MNG_TRUE;       /* it's restarted again ! */
-                                       /* resume display processing */
-    iRetcode = mng_process_display (pData);
-  }
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-
-  if (pData->bSuspended)               /* read suspension ? */
-  {
-     iRetcode            = MNG_NEEDMOREDATA;
-     pData->iSuspendtime = pData->fGettickcount ((mng_handle)pData);
-  }
-  else
-  if (pData->bTimerset)                /* indicate timer break ? */
-    iRetcode = MNG_NEEDTIMERWAIT;
-  else
-  if (pData->bSectionwait)             /* indicate section break ? */
-    iRetcode = MNG_NEEDSECTIONWAIT;
-  else
-  {                                    /* no breaks = end of run */
-    pData->bRunning = MNG_FALSE;
-
-    if (pData->bFreezing)              /* trying to freeze ? */
-      pData->bFreezing = MNG_FALSE;    /* then we're there */
-
-    if (pData->bResetting)             /* trying to reset as well ? */
-    {                                  /* full stop!!! */
-      pData->bDisplaying = MNG_FALSE;
-
-      iRetcode = mng_reset_rundata (pData);
-
-      if (iRetcode)                    /* on error bail out */
-        return iRetcode;
-    }
-  }
-  
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY_RESUME, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-mng_retcode MNG_DECL mng_display_freeze (mng_handle hHandle)
-{
-  mng_datap pData;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY_FREEZE, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = ((mng_datap)hHandle);        /* and make it addressable */
-                                       /* can we expect this call ? */
-  if ((!pData->bDisplaying) || (pData->bReading))
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID);
-
-  cleanup_errors (pData);              /* cleanup previous errors */
-
-  if (pData->bRunning)                 /* is it running ? */
-  {
-    mng_retcode iRetcode;
-
-    pData->bFreezing = MNG_TRUE;       /* indicate we need to freeze */
-                                       /* continue "normal" processing */
-    iRetcode = mng_display_resume (hHandle);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY_FREEZE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-mng_retcode MNG_DECL mng_display_reset (mng_handle hHandle)
-{
-  mng_datap   pData;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY_RESET, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = ((mng_datap)hHandle);        /* and make it addressable */
-                                       /* can we expect this call ? */
-  if ((!pData->bDisplaying) || (pData->bReading))
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID);
-
-  if (!pData->bCacheplayback)          /* must store playback info to work!! */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID);
-
-  cleanup_errors (pData);              /* cleanup previous errors */
-
-  if (pData->bRunning)                 /* is it running ? */
-  {
-    pData->bFreezing  = MNG_TRUE;      /* indicate we need to freeze */
-    pData->bResetting = MNG_TRUE;      /* indicate we're about to reset too */
-                                       /* continue normal processing ? */
-    iRetcode = mng_display_resume (hHandle);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-  }
-  else
-  {                                    /* full stop!!! */
-    pData->bDisplaying = MNG_FALSE;
-
-    iRetcode = mng_reset_rundata (pData);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY_RESET, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-#ifndef MNG_NO_DISPLAY_GO_SUPPORTED
-mng_retcode MNG_DECL mng_display_goframe (mng_handle hHandle,
-                                          mng_uint32 iFramenr)
-{
-  mng_datap   pData;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY_GOFRAME, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = ((mng_datap)hHandle);        /* and make it addressable */
-
-  if (pData->eImagetype != mng_it_mng) /* is it an animation ? */
-    MNG_ERROR (pData, MNG_NOTANANIMATION);
-                                       /* can we expect this call ? */
-  if ((!pData->bDisplaying) || (pData->bRunning))
-    MNG_ERROR ((mng_datap)hHandle, MNG_FUNCTIONINVALID);
-
-  if (!pData->bCacheplayback)          /* must store playback info to work!! */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID);
-
-  if (iFramenr > pData->iTotalframes)  /* is the parameter within bounds ? */
-    MNG_ERROR (pData, MNG_FRAMENRTOOHIGH);
-                                       /* within MHDR bounds ? */
-  if ((pData->iFramecount) && (iFramenr > pData->iFramecount))
-    MNG_WARNING (pData, MNG_FRAMENRTOOHIGH);
-
-  cleanup_errors (pData);              /* cleanup previous errors */
-
-  if (pData->iFrameseq > iFramenr)     /* search from current or go back to start ? */
-  {
-    iRetcode = mng_reset_rundata (pData);
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-  }
-
-  if (iFramenr)
-  {
-    pData->iRequestframe = iFramenr;   /* go find the requested frame then */
-    iRetcode = mng_process_display (pData);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-
-    pData->bTimerset = MNG_FALSE;      /* reset just to be safe */
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY_GOFRAME, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-#ifndef MNG_NO_DISPLAY_GO_SUPPORTED
-mng_retcode MNG_DECL mng_display_golayer (mng_handle hHandle,
-                                          mng_uint32 iLayernr)
-{
-  mng_datap   pData;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY_GOLAYER, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = ((mng_datap)hHandle);        /* and make it addressable */
-
-  if (pData->eImagetype != mng_it_mng) /* is it an animation ? */
-    MNG_ERROR (pData, MNG_NOTANANIMATION);
-                                       /* can we expect this call ? */
-  if ((!pData->bDisplaying) || (pData->bRunning))
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID);
-
-  if (!pData->bCacheplayback)          /* must store playback info to work!! */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID);
-
-  if (iLayernr > pData->iTotallayers)  /* is the parameter within bounds ? */
-    MNG_ERROR (pData, MNG_LAYERNRTOOHIGH);
-                                       /* within MHDR bounds ? */
-  if ((pData->iLayercount) && (iLayernr > pData->iLayercount))
-    MNG_WARNING (pData, MNG_LAYERNRTOOHIGH);
-
-  cleanup_errors (pData);              /* cleanup previous errors */
-
-  if (pData->iLayerseq > iLayernr)     /* search from current or go back to start ? */
-  {
-    iRetcode = mng_reset_rundata (pData);
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-  }
-
-  if (iLayernr)
-  {
-    pData->iRequestlayer = iLayernr;   /* go find the requested layer then */
-    iRetcode = mng_process_display (pData);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-
-    pData->bTimerset = MNG_FALSE;      /* reset just to be safe */
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY_GOLAYER, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-#ifndef MNG_NO_DISPLAY_GO_SUPPORTED
-mng_retcode MNG_DECL mng_display_gotime (mng_handle hHandle,
-                                         mng_uint32 iPlaytime)
-{
-  mng_datap   pData;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY_GOTIME, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = ((mng_datap)hHandle);        /* and make it addressable */
-
-  if (pData->eImagetype != mng_it_mng) /* is it an animation ? */
-    MNG_ERROR (pData, MNG_NOTANANIMATION);
-                                       /* can we expect this call ? */
-  if ((!pData->bDisplaying) || (pData->bRunning))
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID);
-
-  if (!pData->bCacheplayback)          /* must store playback info to work!! */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID);
-                                       /* is the parameter within bounds ? */
-  if (iPlaytime > pData->iTotalplaytime)
-    MNG_ERROR (pData, MNG_PLAYTIMETOOHIGH);
-                                       /* within MHDR bounds ? */
-  if ((pData->iPlaytime) && (iPlaytime > pData->iPlaytime))
-    MNG_WARNING (pData, MNG_PLAYTIMETOOHIGH);
-
-  cleanup_errors (pData);              /* cleanup previous errors */
-
-  if (pData->iFrametime > iPlaytime)   /* search from current or go back to start ? */
-  {
-    iRetcode = mng_reset_rundata (pData);
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-  }
-
-  if (iPlaytime)
-  {
-    pData->iRequesttime = iPlaytime;   /* go find the requested playtime then */
-    iRetcode = mng_process_display (pData);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-
-    pData->bTimerset = MNG_FALSE;      /* reset just to be safe */
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY_GOTIME, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-
-#if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_SUPPORT_DYNAMICMNG)
-mng_retcode MNG_DECL mng_trapevent (mng_handle hHandle,
-                                    mng_uint8  iEventtype,
-                                    mng_int32  iX,
-                                    mng_int32  iY)
-{
-  mng_datap   pData;
-  mng_eventp  pEvent;
-  mng_bool    bFound = MNG_FALSE;
-  mng_retcode iRetcode;
-  mng_imagep  pImage;
-  mng_uint8p  pPixel;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_TRAPEVENT, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = ((mng_datap)hHandle);        /* and make it addressable */
-
-  if (pData->eImagetype != mng_it_mng) /* is it an animation ? */
-    MNG_ERROR (pData, MNG_NOTANANIMATION);
-
-  if (!pData->bDisplaying)             /* can we expect this call ? */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID);
-
-  if (!pData->bCacheplayback)          /* must store playback info to work!! */
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID);
-                                       /* let's find a matching event object */
-  pEvent = (mng_eventp)pData->pFirstevent;
-
-  while ((pEvent) && (!bFound))
-  {                                    /* matching eventtype ? */
-    if (pEvent->iEventtype == iEventtype)
-    {
-      switch (pEvent->iMasktype)       /* check X/Y on basis of masktype */
-      {
-        case MNG_MASK_NONE :           /* no mask is easy */
-          {
-            bFound = MNG_TRUE;
-            break;
-          }
-
-        case MNG_MASK_BOX :            /* inside the given box ? */
-          {                            /* right- and bottom-border don't count ! */
-            if ((iX >= pEvent->iLeft) && (iX < pEvent->iRight) &&
-                (iY >= pEvent->iTop) && (iY < pEvent->iBottom))
-              bFound = MNG_TRUE;
-            break;
-          }
-          
-        case MNG_MASK_OBJECT :         /* non-zero pixel in the image object ? */
-          {
-            pImage = mng_find_imageobject (pData, pEvent->iObjectid);
-                                       /* valid image ? */
-            if ((pImage) && (pImage->pImgbuf->iBitdepth <= 8) &&
-                ((pImage->pImgbuf->iColortype == 0) || (pImage->pImgbuf->iColortype == 3)) &&
-                ((mng_int32)pImage->pImgbuf->iWidth  > iX) &&
-                ((mng_int32)pImage->pImgbuf->iHeight > iY))
-            {
-              pPixel = pImage->pImgbuf->pImgdata + ((pImage->pImgbuf->iWidth * iY) + iX);
-
-              if (*pPixel)             /* non-zero ? */
-                bFound = MNG_TRUE;
-            }
-
-            break;
-          }
-
-        case MNG_MASK_OBJECTIX :       /* pixel in the image object matches index ? */
-          {
-            pImage = mng_find_imageobject (pData, pEvent->iObjectid);
-                                       /* valid image ? */
-            if ((pImage) && (pImage->pImgbuf->iBitdepth <= 8) &&
-                ((pImage->pImgbuf->iColortype == 0) || (pImage->pImgbuf->iColortype == 3)) &&
-                ((mng_int32)pImage->pImgbuf->iWidth  > iX) && (iX >= 0) &&
-                ((mng_int32)pImage->pImgbuf->iHeight > iY) && (iY >= 0))
-            {
-              pPixel = pImage->pImgbuf->pImgdata + ((pImage->pImgbuf->iWidth * iY) + iX);
-                                       /* matching index ? */
-              if (*pPixel == pEvent->iIndex)
-                bFound = MNG_TRUE;
-            }
-
-            break;
-          }
-
-        case MNG_MASK_BOXOBJECT :      /* non-zero pixel in the image object ? */
-          {
-            mng_int32 iTempx = iX - pEvent->iLeft;
-            mng_int32 iTempy = iY - pEvent->iTop;
-
-            pImage = mng_find_imageobject (pData, pEvent->iObjectid);
-                                       /* valid image ? */
-            if ((pImage) && (pImage->pImgbuf->iBitdepth <= 8) &&
-                ((pImage->pImgbuf->iColortype == 0) || (pImage->pImgbuf->iColortype == 3)) &&
-                (iTempx < (mng_int32)pImage->pImgbuf->iWidth) &&
-                (iTempx >= 0) && (iX < pEvent->iRight) &&
-                (iTempy < (mng_int32)pImage->pImgbuf->iHeight) &&
-                (iTempy >= 0) && (iY < pEvent->iBottom))
-            {
-              pPixel = pImage->pImgbuf->pImgdata + ((pImage->pImgbuf->iWidth * iTempy) + iTempx);
-
-              if (*pPixel)             /* non-zero ? */
-                bFound = MNG_TRUE;
-            }
-
-            break;
-          }
-
-        case MNG_MASK_BOXOBJECTIX :    /* pixel in the image object matches index ? */
-          {
-            mng_int32 iTempx = iX - pEvent->iLeft;
-            mng_int32 iTempy = iY - pEvent->iTop;
-
-            pImage = mng_find_imageobject (pData, pEvent->iObjectid);
-                                       /* valid image ? */
-            if ((pImage) && (pImage->pImgbuf->iBitdepth <= 8) &&
-                ((pImage->pImgbuf->iColortype == 0) || (pImage->pImgbuf->iColortype == 3)) &&
-                (iTempx < (mng_int32)pImage->pImgbuf->iWidth) &&
-                (iTempx >= 0) && (iX < pEvent->iRight) &&
-                (iTempy < (mng_int32)pImage->pImgbuf->iHeight) &&
-                (iTempy >= 0) && (iY < pEvent->iBottom))
-            {
-              pPixel = pImage->pImgbuf->pImgdata + ((pImage->pImgbuf->iWidth * iTempy) + iTempx);
-                                       /* matching index ? */
-              if (*pPixel == pEvent->iIndex)
-                bFound = MNG_TRUE;
-            }
-
-            break;
-          }
-
-      }
-    }
-
-    if (!bFound)                       /* try the next one */
-      pEvent = (mng_eventp)pEvent->sHeader.pNext;
-  }
-                                       /* found one that's not the last mousemove ? */
-  if ((pEvent) && ((mng_objectp)pEvent != pData->pLastmousemove))
-  {                                    /* can we start an event process now ? */
-    if ((!pData->bReading) && (!pData->bRunning))
-    {
-      pData->iEventx = iX;             /* save coordinates */
-      pData->iEventy = iY;
-                                       /* do it then ! */
-      iRetcode = pEvent->sHeader.fProcess (pData, pEvent);
-
-      if (iRetcode)                    /* on error bail out */
-        return iRetcode;
-                                       /* remember last mousemove event */
-      if (pEvent->iEventtype == MNG_EVENT_MOUSEMOVE)
-        pData->pLastmousemove = (mng_objectp)pEvent;
-      else
-        pData->pLastmousemove = MNG_NULL;
-    }
-    else
-    {
-
-      /* TODO: store unprocessed events or not ??? */
-
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_TRAPEVENT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_getlasterror (mng_handle   hHandle,
-                                       mng_int8*    iSeverity,
-                                       mng_chunkid* iChunkname,
-                                       mng_uint32*  iChunkseq,
-                                       mng_int32*   iExtra1,
-                                       mng_int32*   iExtra2,
-                                       mng_pchar*   zErrortext)
-{
-  mng_datap pData;                     /* local vars */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETLASTERROR, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)            /* check validity handle */
-  pData = ((mng_datap)hHandle);        /* and make it addressable */
-
-  *iSeverity  = pData->iSeverity;      /* return the appropriate fields */
-
-#if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
-  *iChunkname = pData->iChunkname;
-  *iChunkseq  = pData->iChunkseq;
-#else
-  *iChunkname = MNG_UINT_HUH;
-  *iChunkseq  = 0;
-#endif
-
-  *iExtra1    = pData->iErrorx1;
-  *iExtra2    = pData->iErrorx2;
-  *zErrortext = pData->zErrortext;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETLASTERROR, MNG_LC_END);
-#endif
-
-  return pData->iErrorcode;            /* and the errorcode */
-}
-
-/* ************************************************************************** */
-/* * end of file                                                            * */
-/* ************************************************************************** */
-
-
diff --git a/Source/LibMNG/libmng_jpeg.c b/Source/LibMNG/libmng_jpeg.c
deleted file mode 100644
index 409f6df..0000000
--- a/Source/LibMNG/libmng_jpeg.c
+++ /dev/null
@@ -1,1088 +0,0 @@
-/* ************************************************************************** */
-/* *             For conditions of distribution and use,                    * */
-/* *                see copyright notice in libmng.h                        * */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * project   : libmng                                                     * */
-/* * file      : libmng_jpeg.c             copyright (c) 2000-2004 G.Juyn   * */
-/* * version   : 1.0.9                                                      * */
-/* *                                                                        * */
-/* * purpose   : JPEG library interface (implementation)                    * */
-/* *                                                                        * */
-/* * author    : G.Juyn                                                     * */
-/* *                                                                        * */
-/* * comment   : implementation of the JPEG library interface               * */
-/* *                                                                        * */
-/* * changes   : 0.5.1 - 05/08/2000 - G.Juyn                                * */
-/* *             - changed strict-ANSI stuff                                * */
-/* *                                                                        * */
-/* *             0.5.2 - 05/22/2000 - G.Juyn                                * */
-/* *             - implemented all the JNG routines                         * */
-/* *                                                                        * */
-/* *             0.5.3 - 06/17/2000 - G.Juyn                                * */
-/* *             - added tracing of JPEG calls                              * */
-/* *             0.5.3 - 06/24/2000 - G.Juyn                                * */
-/* *             - fixed inclusion of IJG read/write code                   * */
-/* *             0.5.3 - 06/29/2000 - G.Juyn                                * */
-/* *             - fixed some 64-bit warnings                               * */
-/* *                                                                        * */
-/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
-/* *             - changed file-prefixes                                    * */
-/* *                                                                        * */
-/* *             0.9.3 - 10/16/2000 - G.Juyn                                * */
-/* *             - added support for JDAA                                   * */
-/* *                                                                        * */
-/* *             1.0.1 - 04/19/2001 - G.Juyn                                * */
-/* *             - added export of JPEG functions for DLL                   * */
-/* *             1.0.1 - 04/22/2001 - G.Juyn                                * */
-/* *             - fixed memory-leaks (Thanks Gregg!)                       * */
-/* *                                                                        * */
-/* *             1.0.4 - 06/22/2002 - G.Juyn                                * */
-/* *             - B526138 - returned IJGSRC6B calling convention to        * */
-/* *               default for MSVC                                         * */
-/* *                                                                        * */
-/* *             1.0.5 - 24/02/2003 - G.Juyn                                * */
-/* *             - B683152 - libjpeg suspension not always honored correctly* */
-/* *                                                                        * */
-/* *             1.0.6 - 03/04/2003 - G.Juyn                                * */
-/* *             - fixed some compiler-warnings                             * */
-/* *                                                                        * */
-/* *             1.0.8 - 08/01/2004 - G.Juyn                                * */
-/* *             - added support for 3+byte pixelsize for JPEG's            * */
-/* *                                                                        * */
-/* *             1.0.9 - 12/20/2004 - G.Juyn                                * */
-/* *             - cleaned up macro-invocations (thanks to D. Airlie)       * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#include "libmng.h"
-#include "libmng_data.h"
-#include "libmng_error.h"
-#include "libmng_trace.h"
-#ifdef __BORLANDC__
-#pragma hdrstop
-#endif
-#include "libmng_memory.h"
-#include "libmng_pixels.h"
-#include "libmng_jpeg.h"
-
-#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
-#pragma option -A                      /* force ANSI-C */
-#endif
-
-/* ************************************************************************** */
-
-#if defined(MNG_INCLUDE_JNG) && defined(MNG_INCLUDE_DISPLAY_PROCS)
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Local IJG callback routines (source-manager, error-manager and such)   * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_IJG6B
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG_READ
-#ifdef MNG_DEFINE_JPEG_STDCALL
-void MNG_DECL mng_init_source (j_decompress_ptr cinfo)
-#else
-void mng_init_source (j_decompress_ptr cinfo)
-#endif
-{
-  return;                              /* nothing needed */
-}
-#endif /* MNG_INCLUDE_JNG_READ */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG_READ
-#ifdef MNG_DEFINE_JPEG_STDCALL
-boolean MNG_DECL mng_fill_input_buffer (j_decompress_ptr cinfo)
-#else
-boolean mng_fill_input_buffer (j_decompress_ptr cinfo)
-#endif
-{
-  return FALSE;                        /* force IJG routine to return to caller */
-}
-#endif /* MNG_INCLUDE_JNG_READ */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG_READ
-#ifdef MNG_DEFINE_JPEG_STDCALL
-void MNG_DECL mng_skip_input_data (j_decompress_ptr cinfo, long num_bytes)
-#else
-void mng_skip_input_data (j_decompress_ptr cinfo, long num_bytes)
-#endif
-{
-  if (num_bytes > 0)                   /* ignore fony calls */
-  {                                    /* address my generic structure */
-    mng_datap pData = (mng_datap)cinfo->client_data;
-                                       /* address source manager */
-    mngjpeg_sourcep pSrc = pData->pJPEGdinfo->src;
-                                       /* problem scenario ? */
-    if (pSrc->bytes_in_buffer < (size_t)num_bytes)
-    {                                  /* tell the boss we need to skip some data! */
-      pData->iJPEGtoskip = (mng_uint32)((size_t)num_bytes - pSrc->bytes_in_buffer);
-
-      pSrc->bytes_in_buffer = 0;       /* let the JPEG lib suspend */
-      pSrc->next_input_byte = MNG_NULL;
-    }
-    else
-    {                                  /* simply advance in the buffer */
-      pSrc->bytes_in_buffer -= num_bytes;
-      pSrc->next_input_byte += num_bytes;
-    }
-  }
-
-  return;
-}
-#endif /* MNG_INCLUDE_JNG_READ */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG_READ
-#ifdef MNG_DEFINE_JPEG_STDCALL
-void MNG_DECL mng_skip_input_data2 (j_decompress_ptr cinfo, long num_bytes)
-#else
-void mng_skip_input_data2 (j_decompress_ptr cinfo, long num_bytes)
-#endif
-{
-  if (num_bytes > 0)                   /* ignore fony calls */
-  {                                    /* address my generic structure */
-    mng_datap pData = (mng_datap)cinfo->client_data;
-                                       /* address source manager */
-    mngjpeg_sourcep pSrc = pData->pJPEGdinfo2->src;
-                                       /* problem scenario ? */
-    if (pSrc->bytes_in_buffer < (size_t)num_bytes)
-    {                                  /* tell the boss we need to skip some data! */
-      pData->iJPEGtoskip2 = (mng_uint32)((size_t)num_bytes - pSrc->bytes_in_buffer);
-
-      pSrc->bytes_in_buffer = 0;       /* let the JPEG lib suspend */
-      pSrc->next_input_byte = MNG_NULL;
-    }
-    else
-    {                                  /* simply advance in the buffer */
-      pSrc->bytes_in_buffer -= num_bytes;
-      pSrc->next_input_byte += num_bytes;
-    }
-  }
-
-  return;
-}
-#endif /* MNG_INCLUDE_JNG_READ */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG_READ
-#ifdef MNG_DEFINE_JPEG_STDCALL
-void MNG_DECL mng_term_source (j_decompress_ptr cinfo)
-#else
-void mng_term_source (j_decompress_ptr cinfo)
-#endif
-{
-  return;                              /* nothing needed */
-}
-#endif /* MNG_INCLUDE_JNG_READ */
-
-/* ************************************************************************** */
-
-#ifdef MNG_USE_SETJMP
-#ifdef MNG_DEFINE_JPEG_STDCALL
-void MNG_DECL mng_error_exit (j_common_ptr cinfo)
-#else
-void mng_error_exit (j_common_ptr cinfo)
-#endif
-{                                      /* address my generic structure */
-  mng_datap pData = (mng_datap)cinfo->client_data;
-
-#ifdef MNG_ERROR_TELLTALE              /* fill the message text ??? */
-  (*cinfo->err->output_message) (cinfo);
-#endif
-                                       /* return to the point of no return... */
-  longjmp (pData->sErrorbuf, cinfo->err->msg_code);
-}
-#endif /* MNG_USE_SETJMP */
-
-/* ************************************************************************** */
-
-#ifdef MNG_USE_SETJMP
-#ifdef MNG_DEFINE_JPEG_STDCALL
-void MNG_DECL mng_output_message (j_common_ptr cinfo)
-#else
-void mng_output_message (j_common_ptr cinfo)
-#endif
-{
-  return;                              /* just do nothing ! */
-}
-#endif /* MNG_USE_SETJMP */
-
-/* ************************************************************************** */
-
-#endif /* MNG_INCLUDE_IJG6B */
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Global JPEG routines                                                   * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-mng_retcode mngjpeg_initialize (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_JPEG_INITIALIZE, MNG_LC_START);
-#endif
-                                       /* allocate space for JPEG structures if necessary */
-#ifdef MNG_INCLUDE_JNG_READ
-  if (pData->pJPEGderr   == MNG_NULL)
-    MNG_ALLOC (pData, pData->pJPEGderr,   sizeof (mngjpeg_error ));
-  if (pData->pJPEGdsrc   == MNG_NULL)
-    MNG_ALLOC (pData, pData->pJPEGdsrc,   sizeof (mngjpeg_source));
-  if (pData->pJPEGdinfo  == MNG_NULL)
-    MNG_ALLOC (pData, pData->pJPEGdinfo,  sizeof (mngjpeg_decomp));
-                                       /* enable reverse addressing */
-  pData->pJPEGdinfo->client_data  = pData;
-
-  if (pData->pJPEGderr2  == MNG_NULL)
-    MNG_ALLOC (pData, pData->pJPEGderr2,  sizeof (mngjpeg_error ));
-  if (pData->pJPEGdsrc2  == MNG_NULL)
-    MNG_ALLOC (pData, pData->pJPEGdsrc2,  sizeof (mngjpeg_source));
-  if (pData->pJPEGdinfo2 == MNG_NULL)
-    MNG_ALLOC (pData, pData->pJPEGdinfo2, sizeof (mngjpeg_decomp));
-                                       /* enable reverse addressing */
-  pData->pJPEGdinfo2->client_data = pData;
-#endif
-
-#ifdef MNG_INCLUDE_JNG_WRITE
-  if (pData->pJPEGcerr  == MNG_NULL)
-    MNG_ALLOC (pData, pData->pJPEGcerr,  sizeof (mngjpeg_error ));
-  if (pData->pJPEGcinfo == MNG_NULL)
-    MNG_ALLOC (pData, pData->pJPEGcinfo, sizeof (mngjpeg_comp  ));
-                                       /* enable reverse addressing */
-  pData->pJPEGcinfo->client_data = pData;
-#endif
-
-  if (pData->pJPEGbuf   == MNG_NULL)   /* initialize temporary buffers */
-  {
-    pData->iJPEGbufmax     = MNG_JPEG_MAXBUF;
-    MNG_ALLOC (pData, pData->pJPEGbuf, pData->iJPEGbufmax);
-  }
-
-  if (pData->pJPEGbuf2  == MNG_NULL) 
-  {
-    pData->iJPEGbufmax2    = MNG_JPEG_MAXBUF;
-    MNG_ALLOC (pData, pData->pJPEGbuf2, pData->iJPEGbufmax2);
-  }
-
-  pData->pJPEGcurrent      = pData->pJPEGbuf;
-  pData->iJPEGbufremain    = 0;
-  pData->pJPEGrow          = MNG_NULL;
-  pData->iJPEGrowlen       = 0;
-  pData->iJPEGtoskip       = 0;
-
-  pData->pJPEGcurrent2     = pData->pJPEGbuf2;
-  pData->iJPEGbufremain2   = 0;
-  pData->pJPEGrow2         = MNG_NULL;
-  pData->iJPEGrowlen2      = 0;
-  pData->iJPEGtoskip2      = 0;
-                                      /* not doing anything yet ! */
-  pData->bJPEGcompress     = MNG_FALSE;
-  
-  pData->bJPEGdecompress   = MNG_FALSE;
-  pData->bJPEGhasheader    = MNG_FALSE;
-  pData->bJPEGdecostarted  = MNG_FALSE;
-  pData->bJPEGscanstarted  = MNG_FALSE;
-  pData->bJPEGscanending   = MNG_FALSE;
-
-  pData->bJPEGdecompress2  = MNG_FALSE;
-  pData->bJPEGhasheader2   = MNG_FALSE;
-  pData->bJPEGdecostarted2 = MNG_FALSE;
-  pData->bJPEGscanstarted2 = MNG_FALSE;
-
-  pData->iJPEGrow          = 0;        /* zero input/output lines */
-  pData->iJPEGalpharow     = 0;
-  pData->iJPEGrgbrow       = 0;
-  pData->iJPEGdisprow      = 0;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_JPEG_INITIALIZE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mngjpeg_cleanup (mng_datap pData)
-{
-#if defined(MNG_INCLUDE_IJG6B) && defined(MNG_USE_SETJMP)
-  mng_retcode iRetcode;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_JPEG_CLEANUP, MNG_LC_START);
-#endif
-
-#ifdef MNG_INCLUDE_IJG6B
-#ifdef MNG_USE_SETJMP
-  iRetcode = setjmp (pData->sErrorbuf);/* setup local JPEG error-recovery */
-  if (iRetcode != 0)                   /* got here from longjmp ? */
-    MNG_ERRORJ (pData, iRetcode);      /* then IJG-lib issued an error */
-#endif
-
-#ifdef MNG_INCLUDE_JNG_READ            /* still decompressing something ? */
-  if (pData->bJPEGdecompress)
-    jpeg_destroy_decompress (pData->pJPEGdinfo);
-  if (pData->bJPEGdecompress2)
-    jpeg_destroy_decompress (pData->pJPEGdinfo2);
-#endif
-
-#ifdef MNG_INCLUDE_JNG_WRITE
-  if (pData->bJPEGcompress)            /* still compressing something ? */
-    jpeg_destroy_compress (pData->pJPEGcinfo);
-#endif
-
-#endif /* MNG_INCLUDE_IJG6B */
-                                       /* cleanup temporary buffers */
-  MNG_FREE (pData, pData->pJPEGbuf2, pData->iJPEGbufmax2);
-  MNG_FREE (pData, pData->pJPEGbuf,  pData->iJPEGbufmax);
-                                       /* cleanup space for JPEG structures */
-#ifdef MNG_INCLUDE_JNG_WRITE
-  MNG_FREE (pData, pData->pJPEGcinfo,  sizeof (mngjpeg_comp  ));
-  MNG_FREE (pData, pData->pJPEGcerr,   sizeof (mngjpeg_error ));
-#endif
-
-#ifdef MNG_INCLUDE_JNG_READ
-  MNG_FREE (pData, pData->pJPEGdinfo,  sizeof (mngjpeg_decomp));
-  MNG_FREE (pData, pData->pJPEGdsrc,   sizeof (mngjpeg_source));
-  MNG_FREE (pData, pData->pJPEGderr,   sizeof (mngjpeg_error ));
-  MNG_FREE (pData, pData->pJPEGdinfo2, sizeof (mngjpeg_decomp));
-  MNG_FREE (pData, pData->pJPEGdsrc2,  sizeof (mngjpeg_source));
-  MNG_FREE (pData, pData->pJPEGderr2,  sizeof (mngjpeg_error ));
-#endif
-
-  MNG_FREE (pData, pData->pJPEGrow2, pData->iJPEGrowlen2);
-  MNG_FREE (pData, pData->pJPEGrow,  pData->iJPEGrowlen);
-                                       /* whatever we were doing ... */
-                                       /* we don't anymore ... */
-  pData->bJPEGcompress     = MNG_FALSE;
-
-  pData->bJPEGdecompress   = MNG_FALSE;
-  pData->bJPEGhasheader    = MNG_FALSE;
-  pData->bJPEGdecostarted  = MNG_FALSE;
-  pData->bJPEGscanstarted  = MNG_FALSE;
-  pData->bJPEGscanending   = MNG_FALSE;
-
-  pData->bJPEGdecompress2  = MNG_FALSE;
-  pData->bJPEGhasheader2   = MNG_FALSE;
-  pData->bJPEGdecostarted2 = MNG_FALSE;
-  pData->bJPEGscanstarted2 = MNG_FALSE;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_JPEG_CLEANUP, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * JPEG decompression routines (JDAT)                                     * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG_READ
-mng_retcode mngjpeg_decompressinit (mng_datap pData)
-{
-#if defined(MNG_INCLUDE_IJG6B) && defined(MNG_USE_SETJMP)
-  mng_retcode iRetcode;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSINIT, MNG_LC_START);
-#endif
-
-#ifdef MNG_INCLUDE_IJG6B
-  /* allocate and initialize a JPEG decompression object */
-  pData->pJPEGdinfo->err = jpeg_std_error (pData->pJPEGderr);
-
-#ifdef MNG_USE_SETJMP                  /* setup local JPEG error-routines */
-  pData->pJPEGderr->error_exit     = mng_error_exit;
-  pData->pJPEGderr->output_message = mng_output_message;
-
-  iRetcode = setjmp (pData->sErrorbuf);/* setup local JPEG error-recovery */
-  if (iRetcode != 0)                   /* got here from longjmp ? */
-    MNG_ERRORJ (pData, iRetcode);      /* then IJG-lib issued an error */
-#endif /* MNG_USE_SETJMP */
-
-  /* allocate and initialize a JPEG decompression object (continued) */
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSINIT, MNG_LC_JPEG_CREATE_DECOMPRESS)
-#endif
-  jpeg_create_decompress (pData->pJPEGdinfo);
-
-  pData->bJPEGdecompress = MNG_TRUE;   /* indicate it's initialized */
-
-  /* specify the source of the compressed data (eg, a file) */
-                                       /* no, not a file; we have buffered input */
-  pData->pJPEGdinfo->src = pData->pJPEGdsrc;
-                                       /* use the default handler */
-  pData->pJPEGdinfo->src->resync_to_restart = jpeg_resync_to_restart;
-                                       /* setup local source routine & parms */
-  pData->pJPEGdinfo->src->init_source       = mng_init_source;
-  pData->pJPEGdinfo->src->fill_input_buffer = mng_fill_input_buffer;
-  pData->pJPEGdinfo->src->skip_input_data   = mng_skip_input_data;
-  pData->pJPEGdinfo->src->term_source       = mng_term_source;
-  pData->pJPEGdinfo->src->next_input_byte   = pData->pJPEGcurrent;
-  pData->pJPEGdinfo->src->bytes_in_buffer   = pData->iJPEGbufremain;
-
-#endif /* MNG_INCLUDE_IJG6B */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSINIT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_INCLUDE_JNG_READ */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG_READ
-mng_retcode mngjpeg_decompressdata (mng_datap  pData,
-                                    mng_uint32 iRawsize,
-                                    mng_uint8p pRawdata)
-{
-  mng_retcode iRetcode;
-  mng_uint32  iRemain;
-  mng_uint8p  pWork;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_START);
-#endif
-
-#if defined (MNG_INCLUDE_IJG6B) && defined(MNG_USE_SETJMP)
-  iRetcode = setjmp (pData->sErrorbuf);/* initialize local JPEG error-recovery */
-  if (iRetcode != 0)                   /* got here from longjmp ? */
-    MNG_ERRORJ (pData, iRetcode);      /* then IJG-lib issued an error */
-#endif
-
-  pWork   = pRawdata;
-  iRemain = iRawsize;
-
-  if (pData->iJPEGtoskip)              /* JPEG-lib told us to skip some more data ? */
-  {
-    if (iRemain > pData->iJPEGtoskip)  /* enough data in this buffer ? */
-    {
-      iRemain -= pData->iJPEGtoskip;   /* skip enough to access the next byte */
-      pWork   += pData->iJPEGtoskip;
-
-      pData->iJPEGtoskip = 0;          /* no more to skip then */
-    }
-    else
-    {
-      pData->iJPEGtoskip -= iRemain;   /* skip all data in the buffer */
-      iRemain = 0;                     /* and indicate this accordingly */
-    }
-                                       /* the skip set current-pointer to NULL ! */
-    pData->pJPEGcurrent = pData->pJPEGbuf;
-  }
-
-  while (iRemain)                      /* repeat until no more input-bytes */
-  {                                    /* need to shift anything ? */
-    if ((pData->pJPEGcurrent > pData->pJPEGbuf) &&
-        (pData->pJPEGcurrent - pData->pJPEGbuf + pData->iJPEGbufremain + iRemain > pData->iJPEGbufmax))
-    {
-      if (pData->iJPEGbufremain > 0)   /* then do so */
-        MNG_COPY (pData->pJPEGbuf, pData->pJPEGcurrent, pData->iJPEGbufremain);
-
-      pData->pJPEGcurrent = pData->pJPEGbuf;
-    }
-                                       /* does the remaining input fit into the buffer ? */
-    if (pData->iJPEGbufremain + iRemain <= pData->iJPEGbufmax)
-    {                                  /* move the lot */
-      MNG_COPY ((pData->pJPEGcurrent + pData->iJPEGbufremain), pWork, iRemain);
-
-      pData->iJPEGbufremain += iRemain;/* adjust remaining_bytes counter */
-      iRemain = 0;                     /* and indicate there's no input left */
-    }
-    else
-    {                                  /* calculate what does fit */
-      mng_uint32 iFits = pData->iJPEGbufmax - pData->iJPEGbufremain;
-
-      if (iFits <= 0)                  /* no space is just bugger 'm all */
-        MNG_ERROR (pData, MNG_JPEGBUFTOOSMALL);
-                                       /* move that */
-      MNG_COPY ((pData->pJPEGcurrent + pData->iJPEGbufremain), pWork, iFits);
-
-      pData->iJPEGbufremain += iFits;  /* adjust remain_bytes counter */
-      iRemain -= iFits;                /* and the input-parms */
-      pWork   += iFits;
-    }
-
-#ifdef MNG_INCLUDE_IJG6B
-    pData->pJPEGdinfo->src->next_input_byte = pData->pJPEGcurrent;
-    pData->pJPEGdinfo->src->bytes_in_buffer = pData->iJPEGbufremain;
-
-    if (!pData->bJPEGhasheader)        /* haven't got the header yet ? */
-    {
-      /* call jpeg_read_header() to obtain image info */
-#ifdef MNG_SUPPORT_TRACE
-      MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_JPEG_READ_HEADER)
-#endif
-      if (jpeg_read_header (pData->pJPEGdinfo, TRUE) != JPEG_SUSPENDED)
-      {                                /* indicate the header's oke */
-        pData->bJPEGhasheader = MNG_TRUE;
-                                       /* let's do some sanity checks ! */
-        if ((pData->pJPEGdinfo->image_width  != pData->iDatawidth ) ||
-            (pData->pJPEGdinfo->image_height != pData->iDataheight)    )
-          MNG_ERROR (pData, MNG_JPEGPARMSERR);
-
-        if ( ((pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAY ) ||
-              (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA)    ) &&
-             (pData->pJPEGdinfo->jpeg_color_space != JCS_GRAYSCALE  )    )
-          MNG_ERROR (pData, MNG_JPEGPARMSERR);
-
-        if ( ((pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLOR ) ||
-              (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA)    ) &&
-             (pData->pJPEGdinfo->jpeg_color_space != JCS_YCbCr       )    )
-          MNG_ERROR (pData, MNG_JPEGPARMSERR);
-                                       /* indicate whether or not it's progressive */
-        pData->bJPEGprogressive = (mng_bool)jpeg_has_multiple_scans (pData->pJPEGdinfo);
-                                       /* progressive+alpha can't display "on-the-fly"!! */
-        if ((pData->bJPEGprogressive) &&
-            ((pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA ) ||
-             (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA)    ))
-          pData->fDisplayrow = MNG_NULL;
-                                       /* allocate a row of JPEG-samples */
-        if (pData->pJPEGdinfo->jpeg_color_space == JCS_YCbCr)
-          pData->iJPEGrowlen = pData->pJPEGdinfo->image_width * RGB_PIXELSIZE;
-        else
-          pData->iJPEGrowlen = pData->pJPEGdinfo->image_width;
-
-        MNG_ALLOC (pData, pData->pJPEGrow, pData->iJPEGrowlen);
-
-        pData->iJPEGrgbrow = 0;        /* quite empty up to now */
-      }
-
-      pData->pJPEGcurrent   = (mng_uint8p)pData->pJPEGdinfo->src->next_input_byte;
-      pData->iJPEGbufremain = (mng_uint32)pData->pJPEGdinfo->src->bytes_in_buffer;
-    }
-                                       /* decompress not started ? */
-    if ((pData->bJPEGhasheader) && (!pData->bJPEGdecostarted))
-    {
-      /* set parameters for decompression */
-
-      if (pData->bJPEGprogressive)     /* progressive display ? */
-        pData->pJPEGdinfo->buffered_image = TRUE;
-
-      /* jpeg_start_decompress(...); */
-#ifdef MNG_SUPPORT_TRACE
-      MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_JPEG_START_DECOMPRESS)
-#endif
-      if (jpeg_start_decompress (pData->pJPEGdinfo) == TRUE)
-                                       /* indicate it started */
-        pData->bJPEGdecostarted = MNG_TRUE;
-
-      pData->pJPEGcurrent   = (mng_uint8p)pData->pJPEGdinfo->src->next_input_byte;
-      pData->iJPEGbufremain = (mng_uint32)pData->pJPEGdinfo->src->bytes_in_buffer;
-    }
-                                       /* process some scanlines ? */
-    if ((pData->bJPEGhasheader) && (pData->bJPEGdecostarted) &&
-	    ((!jpeg_input_complete (pData->pJPEGdinfo)) ||
-         (pData->pJPEGdinfo->output_scanline < pData->pJPEGdinfo->output_height) ||
-         ((pData->bJPEGprogressive) && (pData->bJPEGscanending))))
-    {
-      mng_int32 iLines = 0;
-
-      /* for (each output pass) */
-      do
-      {                                /* address the row output buffer */
-        JSAMPROW pRow = (JSAMPROW)pData->pJPEGrow;
-
-                                       /* init new pass ? */
-        if ((pData->bJPEGprogressive) && (!pData->bJPEGscanstarted))
-        {
-          pData->bJPEGscanstarted = MNG_TRUE;
-
-          /* adjust output decompression parameters if required */
-          /* nop */
-
-          /* start a new output pass */
-#ifdef MNG_SUPPORT_TRACE
-          MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_JPEG_START_OUTPUT)
-#endif
-          jpeg_start_output (pData->pJPEGdinfo, pData->pJPEGdinfo->input_scan_number);
-
-          pData->iJPEGrow = 0;         /* start at row 0 in the image again */
-        }
-
-        /* while (scan lines remain to be read) */
-        if ((!pData->bJPEGprogressive) || (!pData->bJPEGscanending))
-        {
-          do
-          {
-          /*   jpeg_read_scanlines(...); */
-#ifdef MNG_SUPPORT_TRACE
-            MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_JPEG_READ_SCANLINES)
-#endif
-            iLines = jpeg_read_scanlines (pData->pJPEGdinfo, (JSAMPARRAY)&pRow, 1);
-
-            pData->pJPEGcurrent   = (mng_uint8p)pData->pJPEGdinfo->src->next_input_byte;
-            pData->iJPEGbufremain = (mng_uint32)pData->pJPEGdinfo->src->bytes_in_buffer;
-
-            if (iLines > 0)            /* got something ? */
-            {
-              if (pData->fStorerow2)   /* store in object ? */
-              {
-                iRetcode = ((mng_storerow)pData->fStorerow2) (pData);
-
-                if (iRetcode)          /* on error bail out */
-                return iRetcode;
-
-              }
-            }
-          }
-          while ((pData->pJPEGdinfo->output_scanline < pData->pJPEGdinfo->output_height) &&
-                 (iLines > 0));        /* until end-of-image or not enough input-data */
-        }
-
-        /* terminate output pass */
-        if ((pData->bJPEGprogressive) &&
-            (pData->pJPEGdinfo->output_scanline >= pData->pJPEGdinfo->output_height))
-        {
-#ifdef MNG_SUPPORT_TRACE
-          MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_JPEG_FINISH_OUTPUT)
-#endif
-          if (jpeg_finish_output (pData->pJPEGdinfo) != JPEG_SUSPENDED)
-          {                            /* this scan has ended */
-            pData->bJPEGscanstarted = MNG_FALSE;
-            pData->bJPEGscanending  = MNG_FALSE;
-          }
-          else
-          {
-            pData->bJPEGscanending  = MNG_TRUE;
-          }
-        }
-      }
-      while ((!jpeg_input_complete (pData->pJPEGdinfo)) &&
-             (iLines > 0) && (!pData->bJPEGscanending));
-    }
-                                       /* end of image ? */
-    if ((pData->bJPEGhasheader) && (pData->bJPEGdecostarted) &&
-        (!pData->bJPEGscanending) && (jpeg_input_complete (pData->pJPEGdinfo)) &&
-        (pData->pJPEGdinfo->input_scan_number == pData->pJPEGdinfo->output_scan_number))
-    {
-      /* jpeg_finish_decompress(...); */
-#ifdef MNG_SUPPORT_TRACE
-      MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_JPEG_FINISH_DECOMPRESS)
-#endif
-      if (jpeg_finish_decompress (pData->pJPEGdinfo) == TRUE)
-      {                                /* indicate it's done */
-        pData->bJPEGhasheader   = MNG_FALSE;
-        pData->bJPEGdecostarted = MNG_FALSE;
-        pData->pJPEGcurrent     = (mng_uint8p)pData->pJPEGdinfo->src->next_input_byte;
-        pData->iJPEGbufremain   = (mng_uint32)pData->pJPEGdinfo->src->bytes_in_buffer;
-                                       /* remaining fluff is an error ! */
-        if ((pData->iJPEGbufremain > 0) || (iRemain > 0))
-          MNG_ERROR (pData, MNG_TOOMUCHJDAT);
-      }
-    }
-#endif /* MNG_INCLUDE_IJG6B */
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_INCLUDE_JNG_READ */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG_READ
-mng_retcode mngjpeg_decompressfree (mng_datap pData)
-{
-#if defined(MNG_INCLUDE_IJG6B) && defined(MNG_USE_SETJMP)
-  mng_retcode iRetcode;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSFREE, MNG_LC_START);
-#endif
-
-#ifdef MNG_INCLUDE_IJG6B
-#ifdef MNG_USE_SETJMP
-  iRetcode = setjmp (pData->sErrorbuf);/* setup local JPEG error-recovery */
-  if (iRetcode != 0)                   /* got here from longjmp ? */
-    MNG_ERRORJ (pData, iRetcode);      /* then IJG-lib issued an error */
-#endif
-                                       /* free the row of JPEG-samples*/
-  MNG_FREE (pData, pData->pJPEGrow, pData->iJPEGrowlen);
-
-  /* release the JPEG decompression object */
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSFREE, MNG_LC_JPEG_DESTROY_DECOMPRESS)
-#endif
-  jpeg_destroy_decompress (pData->pJPEGdinfo);
-
-  pData->bJPEGdecompress = MNG_FALSE;  /* indicate it's done */
-
-#endif /* MNG_INCLUDE_IJG6B */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSFREE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_INCLUDE_JNG_READ */
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * JPEG decompression routines (JDAA)                                     * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG_READ
-mng_retcode mngjpeg_decompressinit2 (mng_datap pData)
-{
-#if defined(MNG_INCLUDE_IJG6B) && defined(MNG_USE_SETJMP)
-  mng_retcode iRetcode;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSINIT, MNG_LC_START);
-#endif
-
-#ifdef MNG_INCLUDE_IJG6B
-  /* allocate and initialize a JPEG decompression object */
-  pData->pJPEGdinfo2->err = jpeg_std_error (pData->pJPEGderr2);
-
-#ifdef MNG_USE_SETJMP                  /* setup local JPEG error-routines */
-  pData->pJPEGderr2->error_exit     = mng_error_exit;
-  pData->pJPEGderr2->output_message = mng_output_message;
-
-  iRetcode = setjmp (pData->sErrorbuf);/* setup local JPEG error-recovery */
-  if (iRetcode != 0)                   /* got here from longjmp ? */
-    MNG_ERRORJ (pData, iRetcode);      /* then IJG-lib issued an error */
-#endif /* MNG_USE_SETJMP */
-
-  /* allocate and initialize a JPEG decompression object (continued) */
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSINIT, MNG_LC_JPEG_CREATE_DECOMPRESS)
-#endif
-  jpeg_create_decompress (pData->pJPEGdinfo2);
-
-  pData->bJPEGdecompress2 = MNG_TRUE;  /* indicate it's initialized */
-
-  /* specify the source of the compressed data (eg, a file) */
-                                       /* no, not a file; we have buffered input */
-  pData->pJPEGdinfo2->src = pData->pJPEGdsrc2;
-                                       /* use the default handler */
-  pData->pJPEGdinfo2->src->resync_to_restart = jpeg_resync_to_restart;
-                                       /* setup local source routine & parms */
-  pData->pJPEGdinfo2->src->init_source       = mng_init_source;
-  pData->pJPEGdinfo2->src->fill_input_buffer = mng_fill_input_buffer;
-  pData->pJPEGdinfo2->src->skip_input_data   = mng_skip_input_data2;
-  pData->pJPEGdinfo2->src->term_source       = mng_term_source;
-  pData->pJPEGdinfo2->src->next_input_byte   = pData->pJPEGcurrent2;
-  pData->pJPEGdinfo2->src->bytes_in_buffer   = pData->iJPEGbufremain2;
-
-#endif /* MNG_INCLUDE_IJG6B */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSINIT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_INCLUDE_JNG_READ */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG_READ
-mng_retcode mngjpeg_decompressdata2 (mng_datap  pData,
-                                     mng_uint32 iRawsize,
-                                     mng_uint8p pRawdata)
-{
-  mng_retcode iRetcode;
-  mng_uint32  iRemain;
-  mng_uint8p  pWork;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_START);
-#endif
-
-#if defined (MNG_INCLUDE_IJG6B) && defined(MNG_USE_SETJMP)
-  iRetcode = setjmp (pData->sErrorbuf);/* initialize local JPEG error-recovery */
-  if (iRetcode != 0)                   /* got here from longjmp ? */
-    MNG_ERRORJ (pData, iRetcode);      /* then IJG-lib issued an error */
-#endif
-
-  pWork   = pRawdata;
-  iRemain = iRawsize;
-
-  if (pData->iJPEGtoskip2)             /* JPEG-lib told us to skip some more data ? */
-  {
-    if (iRemain > pData->iJPEGtoskip2) /* enough data in this buffer ? */
-    {
-      iRemain -= pData->iJPEGtoskip2;  /* skip enough to access the next byte */
-      pWork   += pData->iJPEGtoskip2;
-
-      pData->iJPEGtoskip2 = 0;         /* no more to skip then */
-    }
-    else
-    {
-      pData->iJPEGtoskip2 -= iRemain;  /* skip all data in the buffer */
-      iRemain = 0;                     /* and indicate this accordingly */
-    }
-                                       /* the skip set current-pointer to NULL ! */
-    pData->pJPEGcurrent2 = pData->pJPEGbuf2;
-  }
-
-  while (iRemain)                      /* repeat until no more input-bytes */
-  {                                    /* need to shift anything ? */
-    if ((pData->pJPEGcurrent2 > pData->pJPEGbuf2) &&
-        (pData->pJPEGcurrent2 - pData->pJPEGbuf2 + pData->iJPEGbufremain2 + iRemain > pData->iJPEGbufmax2))
-    {
-      if (pData->iJPEGbufremain2 > 0)  /* then do so */
-        MNG_COPY (pData->pJPEGbuf2, pData->pJPEGcurrent2, pData->iJPEGbufremain2);
-
-      pData->pJPEGcurrent2 = pData->pJPEGbuf2;
-    }
-                                       /* does the remaining input fit into the buffer ? */
-    if (pData->iJPEGbufremain2 + iRemain <= pData->iJPEGbufmax2)
-    {                                  /* move the lot */
-      MNG_COPY ((pData->pJPEGcurrent2 + pData->iJPEGbufremain2), pWork, iRemain);
-                                       /* adjust remaining_bytes counter */
-      pData->iJPEGbufremain2 += iRemain;
-      iRemain = 0;                     /* and indicate there's no input left */
-    }
-    else
-    {                                  /* calculate what does fit */
-      mng_uint32 iFits = pData->iJPEGbufmax2 - pData->iJPEGbufremain2;
-
-      if (iFits <= 0)                  /* no space is just bugger 'm all */
-        MNG_ERROR (pData, MNG_JPEGBUFTOOSMALL);
-                                       /* move that */
-      MNG_COPY ((pData->pJPEGcurrent2 + pData->iJPEGbufremain2), pWork, iFits);
-
-      pData->iJPEGbufremain2 += iFits; /* adjust remain_bytes counter */
-      iRemain -= iFits;                /* and the input-parms */
-      pWork   += iFits;
-    }
-
-#ifdef MNG_INCLUDE_IJG6B
-    pData->pJPEGdinfo2->src->next_input_byte = pData->pJPEGcurrent2;
-    pData->pJPEGdinfo2->src->bytes_in_buffer = pData->iJPEGbufremain2;
-
-    if (!pData->bJPEGhasheader2)       /* haven't got the header yet ? */
-    {
-      /* call jpeg_read_header() to obtain image info */
-#ifdef MNG_SUPPORT_TRACE
-      MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_JPEG_READ_HEADER)
-#endif
-      if (jpeg_read_header (pData->pJPEGdinfo2, TRUE) != JPEG_SUSPENDED)
-      {                                /* indicate the header's oke */
-        pData->bJPEGhasheader2 = MNG_TRUE;
-                                       /* let's do some sanity checks ! */
-        if ((pData->pJPEGdinfo2->image_width  != pData->iDatawidth ) ||
-            (pData->pJPEGdinfo2->image_height != pData->iDataheight)    )
-          MNG_ERROR (pData, MNG_JPEGPARMSERR);
-
-        if (pData->pJPEGdinfo2->jpeg_color_space != JCS_GRAYSCALE)
-          MNG_ERROR (pData, MNG_JPEGPARMSERR);
-                                       /* indicate whether or not it's progressive */
-        pData->bJPEGprogressive2 = (mng_bool)jpeg_has_multiple_scans (pData->pJPEGdinfo2);
-
-        if (pData->bJPEGprogressive2)  /* progressive alphachannel not allowed !!! */
-          MNG_ERROR (pData, MNG_JPEGPARMSERR);
-                                       /* allocate a row of JPEG-samples */
-        if (pData->pJPEGdinfo2->jpeg_color_space == JCS_YCbCr)
-          pData->iJPEGrowlen2 = pData->pJPEGdinfo2->image_width * RGB_PIXELSIZE;
-        else
-          pData->iJPEGrowlen2 = pData->pJPEGdinfo2->image_width;
-
-        MNG_ALLOC (pData, pData->pJPEGrow2, pData->iJPEGrowlen2);
-
-        pData->iJPEGalpharow = 0;      /* quite empty up to now */
-      }
-
-      pData->pJPEGcurrent2   = (mng_uint8p)pData->pJPEGdinfo2->src->next_input_byte;
-      pData->iJPEGbufremain2 = (mng_uint32)pData->pJPEGdinfo2->src->bytes_in_buffer;
-    }
-                                       /* decompress not started ? */
-    if ((pData->bJPEGhasheader2) && (!pData->bJPEGdecostarted2))
-    {
-      /* set parameters for decompression */
-
-      if (pData->bJPEGprogressive2)    /* progressive display ? */
-        pData->pJPEGdinfo2->buffered_image = TRUE;
-
-      /* jpeg_start_decompress(...); */
-#ifdef MNG_SUPPORT_TRACE
-      MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_JPEG_START_DECOMPRESS)
-#endif
-      if (jpeg_start_decompress (pData->pJPEGdinfo2) == TRUE)
-                                       /* indicate it started */
-        pData->bJPEGdecostarted2 = MNG_TRUE;
-
-      pData->pJPEGcurrent2   = (mng_uint8p)pData->pJPEGdinfo2->src->next_input_byte;
-      pData->iJPEGbufremain2 = (mng_uint32)pData->pJPEGdinfo2->src->bytes_in_buffer;
-    }
-                                       /* process some scanlines ? */
-    if ((pData->bJPEGhasheader2) && (pData->bJPEGdecostarted2) &&
-	    ((!jpeg_input_complete (pData->pJPEGdinfo2)) ||
-         (pData->pJPEGdinfo2->output_scanline < pData->pJPEGdinfo2->output_height)))
-    {
-      mng_int32 iLines;
-
-      /* for (each output pass) */
-      do
-      {                                /* address the row output buffer */
-        JSAMPROW pRow = (JSAMPROW)pData->pJPEGrow2;
-
-                                       /* init new pass ? */
-        if ((pData->bJPEGprogressive2) &&
-            ((!pData->bJPEGscanstarted2) ||
-             (pData->pJPEGdinfo2->output_scanline >= pData->pJPEGdinfo2->output_height)))
-        {
-          pData->bJPEGscanstarted2 = MNG_TRUE;
-
-          /* adjust output decompression parameters if required */
-          /* nop */
-
-          /* start a new output pass */
-#ifdef MNG_SUPPORT_TRACE
-          MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_JPEG_START_OUTPUT)
-#endif
-          jpeg_start_output (pData->pJPEGdinfo2, pData->pJPEGdinfo2->input_scan_number);
-
-          pData->iJPEGrow = 0;         /* start at row 0 in the image again */
-        }
-
-        /* while (scan lines remain to be read) */
-        do
-        {
-          /*   jpeg_read_scanlines(...); */
-#ifdef MNG_SUPPORT_TRACE
-          MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_JPEG_READ_SCANLINES)
-#endif
-          iLines = jpeg_read_scanlines (pData->pJPEGdinfo2, (JSAMPARRAY)&pRow, 1);
-
-          pData->pJPEGcurrent2   = (mng_uint8p)pData->pJPEGdinfo2->src->next_input_byte;
-          pData->iJPEGbufremain2 = (mng_uint32)pData->pJPEGdinfo2->src->bytes_in_buffer;
-
-          if (iLines > 0)              /* got something ? */
-          {
-            if (pData->fStorerow3)     /* store in object ? */
-            {
-              iRetcode = ((mng_storerow)pData->fStorerow3) (pData);
-
-              if (iRetcode)            /* on error bail out */
-                return iRetcode;
-
-            }
-          }
-        }
-        while ((pData->pJPEGdinfo2->output_scanline < pData->pJPEGdinfo2->output_height) &&
-               (iLines > 0));          /* until end-of-image or not enough input-data */
-
-        /* terminate output pass */
-        if ((pData->bJPEGprogressive2) &&
-            (pData->pJPEGdinfo2->output_scanline >= pData->pJPEGdinfo2->output_height))
-        {
-#ifdef MNG_SUPPORT_TRACE
-          MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_JPEG_FINISH_OUTPUT)
-#endif
-          if (jpeg_finish_output (pData->pJPEGdinfo2) == JPEG_SUSPENDED)
-            jpeg_finish_output (pData->pJPEGdinfo2);
-                                       /* this scan has ended */
-          pData->bJPEGscanstarted2 = MNG_FALSE;
-        }
-      }
-      while ((!jpeg_input_complete (pData->pJPEGdinfo2)) && (iLines > 0));
-    }
-                                       /* end of image ? */
-    if ((pData->bJPEGhasheader2) && (pData->bJPEGdecostarted2) &&
-        (jpeg_input_complete (pData->pJPEGdinfo2)) &&
-        (pData->pJPEGdinfo2->input_scan_number == pData->pJPEGdinfo2->output_scan_number))
-    {
-      /* jpeg_finish_decompress(...); */
-#ifdef MNG_SUPPORT_TRACE
-      MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_JPEG_FINISH_DECOMPRESS)
-#endif
-      if (jpeg_finish_decompress (pData->pJPEGdinfo2) == TRUE)
-      {                                /* indicate it's done */
-        pData->bJPEGhasheader2   = MNG_FALSE;
-        pData->bJPEGdecostarted2 = MNG_FALSE;
-        pData->pJPEGcurrent2     = (mng_uint8p)pData->pJPEGdinfo2->src->next_input_byte;
-        pData->iJPEGbufremain2   = (mng_uint32)pData->pJPEGdinfo2->src->bytes_in_buffer;
-                                       /* remaining fluff is an error ! */
-        if ((pData->iJPEGbufremain2 > 0) || (iRemain > 0))
-          MNG_ERROR (pData, MNG_TOOMUCHJDAT);
-      }
-    }
-#endif /* MNG_INCLUDE_IJG6B */
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_INCLUDE_JNG_READ */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG_READ
-mng_retcode mngjpeg_decompressfree2 (mng_datap pData)
-{
-#if defined(MNG_INCLUDE_IJG6B) && defined(MNG_USE_SETJMP)
-  mng_retcode iRetcode;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSFREE, MNG_LC_START);
-#endif
-
-#ifdef MNG_INCLUDE_IJG6B
-#ifdef MNG_USE_SETJMP
-  iRetcode = setjmp (pData->sErrorbuf);/* setup local JPEG error-recovery */
-  if (iRetcode != 0)                   /* got here from longjmp ? */
-    MNG_ERRORJ (pData, iRetcode);      /* then IJG-lib issued an error */
-#endif
-                                       /* free the row of JPEG-samples*/
-  MNG_FREE (pData, pData->pJPEGrow2, pData->iJPEGrowlen2);
-
-  /* release the JPEG decompression object */
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSFREE, MNG_LC_JPEG_DESTROY_DECOMPRESS)
-#endif
-  jpeg_destroy_decompress (pData->pJPEGdinfo2);
-
-  pData->bJPEGdecompress2 = MNG_FALSE; /* indicate it's done */
-
-#endif /* MNG_INCLUDE_IJG6B */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSFREE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_INCLUDE_JNG_READ */
-
-/* ************************************************************************** */
-
-#endif /* MNG_INCLUDE_JNG && MNG_INCLUDE_DISPLAY_PROCS */
-
-/* ************************************************************************** */
-/* * end of file                                                            * */
-/* ************************************************************************** */
-
diff --git a/Source/LibMNG/libmng_jpeg.h b/Source/LibMNG/libmng_jpeg.h
deleted file mode 100644
index a072af9..0000000
--- a/Source/LibMNG/libmng_jpeg.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* ************************************************************************** */
-/* *             For conditions of distribution and use,                    * */
-/* *                see copyright notice in libmng.h                        * */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * project   : libmng                                                     * */
-/* * file      : libmng_jpeg.h             copyright (c) 2000-2002 G.Juyn   * */
-/* * version   : 1.0.0                                                      * */
-/* *                                                                        * */
-/* * purpose   : JPEG library interface (definition)                        * */
-/* *                                                                        * */
-/* * author    : G.Juyn                                                     * */
-/* *                                                                        * */
-/* * comment   : Definition of the JPEG library interface                   * */
-/* *                                                                        * */
-/* * changes   : 0.5.1 - 05/08/2000 - G.Juyn                                * */
-/* *             - changed strict-ANSI stuff                                * */
-/* *                                                                        * */
-/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
-/* *             - changed file-prefixes                                    * */
-/* *                                                                        * */
-/* *             0.9.3 - 10/16/2000 - G.Juyn                                * */
-/* *             - added support for JDAA                                   * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
-#pragma option -A                      /* force ANSI-C */
-#endif
-
-#ifndef _libmng_jpeg_h_
-#define _libmng_jpeg_h_
-
-/* ************************************************************************** */
-
-mng_retcode mngjpeg_initialize      (mng_datap  pData);
-mng_retcode mngjpeg_cleanup         (mng_datap  pData);
-
-mng_retcode mngjpeg_decompressinit  (mng_datap  pData);
-mng_retcode mngjpeg_decompressdata  (mng_datap  pData,
-                                     mng_uint32 iRawsize,
-                                     mng_uint8p pRawdata);
-mng_retcode mngjpeg_decompressfree  (mng_datap  pData);
-
-mng_retcode mngjpeg_decompressinit2 (mng_datap  pData);
-mng_retcode mngjpeg_decompressdata2 (mng_datap  pData,
-                                     mng_uint32 iRawsize,
-                                     mng_uint8p pRawdata);
-mng_retcode mngjpeg_decompressfree2 (mng_datap  pData);
-
-/* ************************************************************************** */
-
-#endif /* _libmng_jpeg_h_ */
-
-/* ************************************************************************** */
-/* * end of file                                                            * */
-/* ************************************************************************** */
diff --git a/Source/LibMNG/libmng_memory.h b/Source/LibMNG/libmng_memory.h
deleted file mode 100644
index b92d0c1..0000000
--- a/Source/LibMNG/libmng_memory.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* ************************************************************************** */
-/* *             For conditions of distribution and use,                    * */
-/* *                see copyright notice in libmng.h                        * */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * project   : libmng                                                     * */
-/* * file      : libmng_memory.h           copyright (c) 2000-2003 G.Juyn   * */
-/* * version   : 1.0.0                                                      * */
-/* *                                                                        * */
-/* * purpose   : Memory management (definition)                             * */
-/* *                                                                        * */
-/* * author    : G.Juyn                                                     * */
-/* *                                                                        * */
-/* * comment   : Definition of memory management functions                  * */
-/* *                                                                        * */
-/* * changes   : 0.5.1 - 05/08/2000 - G.Juyn                                * */
-/* *             - changed strict-ANSI stuff                                * */
-/* *                                                                        * */
-/* *             0.5.3 - 06/12/2000 - G.Juyn                                * */
-/* *             - swapped MNG_COPY parameter-names                         * */
-/* *             0.5.3 - 06/27/2000 - G.Juyn                                * */
-/* *             - changed size parameter to mng_size_t                     * */
-/* *                                                                        * */
-/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
-/* *             - changed file-prefixes                                    * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
-#pragma option -A                      /* force ANSI-C */
-#endif
-
-#ifndef _libmng_memory_h_
-#define _libmng_memory_h_
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Generic memory manager macros                                          * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifdef MNG_INTERNAL_MEMMNGMT
-#define MNG_ALLOC(H,P,L)  { P = calloc (1, (mng_size_t)(L)); \
-                            if (P == 0) { MNG_ERROR (H, MNG_OUTOFMEMORY) } }
-#define MNG_ALLOCX(H,P,L) { P = calloc (1, (mng_size_t)(L)); }
-#define MNG_FREE(H,P,L)   { if (P) { free (P); P = 0; } }
-#define MNG_FREEX(H,P,L)  { if (P) free (P); }
-#else
-#define MNG_ALLOC(H,P,L)  { P = H->fMemalloc ((mng_size_t)(L)); \
-                            if (P == 0) { MNG_ERROR (H, MNG_OUTOFMEMORY) } }
-#define MNG_ALLOCX(H,P,L) { P = H->fMemalloc ((mng_size_t)(L)); }
-#define MNG_FREE(H,P,L)   { if (P) { H->fMemfree (P, (mng_size_t)(L)); P = 0; } }
-#define MNG_FREEX(H,P,L)  { if (P) { H->fMemfree (P, (mng_size_t)(L)); } }
-#endif /* mng_internal_memmngmt */
-
-#define MNG_COPY(D,S,L)   { memcpy (D, S, (mng_size_t)(L)); }
-
-/* ************************************************************************** */
-
-#endif /* _libmng_memory_h_ */
-
-/* ************************************************************************** */
-/* * end of file                                                            * */
-/* ************************************************************************** */
diff --git a/Source/LibMNG/libmng_object_prc.c b/Source/LibMNG/libmng_object_prc.c
deleted file mode 100644
index 570d346..0000000
--- a/Source/LibMNG/libmng_object_prc.c
+++ /dev/null
@@ -1,6998 +0,0 @@
-/* ************************************************************************** */
-/* *             For conditions of distribution and use,                    * */
-/* *                see copyright notice in libmng.h                        * */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * project   : libmng                                                     * */
-/* * file      : libmng_object_prc.c       copyright (c) 2000-2007 G.Juyn   * */
-/* * version   : 1.0.10                                                     * */
-/* *                                                                        * */
-/* * purpose   : Object processing routines (implementation)                * */
-/* *                                                                        * */
-/* * author    : G.Juyn                                                     * */
-/* *                                                                        * */
-/* * comment   : implementation of the internal object processing routines  * */
-/* *                                                                        * */
-/* * changes   : 0.5.1 - 05/08/2000 - G.Juyn                                * */
-/* *             - changed strict-ANSI stuff                                * */
-/* *             0.5.1 - 05/12/2000 - G.Juyn                                * */
-/* *             - changed trace to macro for callback error-reporting      * */
-/* *                                                                        * */
-/* *             0.5.2 - 05/20/2000 - G.Juyn                                * */
-/* *             - fixed to support JNG objects                             * */
-/* *             0.5.2 - 05/24/2000 - G.Juyn                                * */
-/* *             - added support for global color-chunks in animation       * */
-/* *             - added support for global PLTE,tRNS,bKGD in animation     * */
-/* *             - added SAVE & SEEK animation objects                      * */
-/* *             0.5.2 - 05/29/2000 - G.Juyn                                * */
-/* *             - added initialization of framenr/layernr/playtime         * */
-/* *             - changed ani_object create routines not to return the     * */
-/* *               created object (wasn't necessary)                        * */
-/* *             0.5.2 - 05/30/2000 - G.Juyn                                * */
-/* *             - added object promotion routine (PROM handling)           * */
-/* *             - added ani-object routines for delta-image processing     * */
-/* *             - added compression/filter/interlace fields to             * */
-/* *               object-buffer for delta-image processing                 * */
-/* *                                                                        * */
-/* *             0.5.3 - 06/17/2000 - G.Juyn                                * */
-/* *             - changed support for delta-image processing               * */
-/* *             0.5.3 - 06/20/2000 - G.Juyn                                * */
-/* *             - fixed some small things (as precaution)                  * */
-/* *             0.5.3 - 06/21/2000 - G.Juyn                                * */
-/* *             - added processing of PLTE/tRNS & color-info for           * */
-/* *               delta-images in the ani_objects chain                    * */
-/* *             0.5.3 - 06/22/2000 - G.Juyn                                * */
-/* *             - added support for PPLT chunk                             * */
-/* *                                                                        * */
-/* *             0.9.1 - 07/07/2000 - G.Juyn                                * */
-/* *             - added support for freeze/restart/resume & go_xxxx        * */
-/* *             0.9.1 - 07/16/2000 - G.Juyn                                * */
-/* *             - fixed support for mng_display() after mng_read()         * */
-/* *                                                                        * */
-/* *             0.9.2 - 07/29/2000 - G.Juyn                                * */
-/* *             - fixed small bugs in display processing                   * */
-/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
-/* *             - changed file-prefixes                                    * */
-/* *                                                                        * */
-/* *             0.9.3 - 08/07/2000 - G.Juyn                                * */
-/* *             - B111300 - fixup for improved portability                 * */
-/* *             0.9.3 - 08/26/2000 - G.Juyn                                * */
-/* *             - added MAGN chunk                                         * */
-/* *             0.9.3 - 09/10/2000 - G.Juyn                                * */
-/* *             - fixed DEFI behavior                                      * */
-/* *             0.9.3 - 10/17/2000 - G.Juyn                                * */
-/* *             - added valid-flag to stored objects for read() / display()* */
-/* *             - added routine to discard "invalid" objects               * */
-/* *             0.9.3 - 10/18/2000 - G.Juyn                                * */
-/* *             - fixed delta-processing behavior                          * */
-/* *             0.9.3 - 10/19/2000 - G.Juyn                                * */
-/* *             - added storage for pixel-/alpha-sampledepth for delta's   * */
-/* *                                                                        * */
-/* *             0.9.4 -  1/18/2001 - G.Juyn                                * */
-/* *             - removed "old" MAGN methods 3 & 4                         * */
-/* *             - added "new" MAGN methods 3, 4 & 5                        * */
-/* *                                                                        * */
-/* *             0.9.5 -  1/22/2001 - G.Juyn                                * */
-/* *             - B129681 - fixed compiler warnings SGI/Irix               * */
-/* *                                                                        * */
-/* *             1.0.2 - 06/23/2001 - G.Juyn                                * */
-/* *             - added optimization option for MNG-video playback         * */
-/* *                                                                        * */
-/* *             1.0.5 - 08/15/2002 - G.Juyn                                * */
-/* *             - completed PROM support                                   * */
-/* *             1.0.5 - 08/16/2002 - G.Juyn                                * */
-/* *             - completed MAGN support (16-bit functions)                * */
-/* *             1.0.5 - 08/19/2002 - G.Juyn                                * */
-/* *             - B597134 - libmng pollutes the linker namespace           * */
-/* *             1.0.5 - 09/13/2002 - G.Juyn                                * */
-/* *             - fixed read/write of MAGN chunk                           * */
-/* *             1.0.5 - 09/15/2002 - G.Juyn                                * */
-/* *             - added event handling for dynamic MNG                     * */
-/* *             1.0.5 - 09/20/2002 - G.Juyn                                * */
-/* *             - added support for PAST                                   * */
-/* *             1.0.5 - 09/23/2002 - G.Juyn                                * */
-/* *             - fixed reset_object_detail to clear old buffer            * */
-/* *             - added in-memory color-correction of abstract images      * */
-/* *             1.0.5 - 10/05/2002 - G.Juyn                                * */
-/* *             - fixed problem with cloned objects marked as invalid      * */
-/* *             - fixed problem cloning frozen object_buffers              * */
-/* *             1.0.5 - 10/07/2002 - G.Juyn                                * */
-/* *             - fixed DISC support                                       * */
-/* *             1.0.5 - 11/04/2002 - G.Juyn                                * */
-/* *             - fixed goframe/golayer/gotime processing                  * */
-/* *             1.0.5 - 11/07/2002 - G.Juyn                                * */
-/* *             - fixed magnification bug with object 0                    * */
-/* *             1.0.5 - 01/19/2003 - G.Juyn                                * */
-/* *             - B664911 - fixed buffer overflow during init              * */
-/* *                                                                        * */
-/* *             1.0.6 - 04/19/2003 - G.Juyn                                * */
-/* *             - fixed problem with infinite loops during readdisplay()   * */
-/* *             1.0.6 - 05/25/2003 - G.R-P                                 * */
-/* *             - added MNG_SKIPCHUNK_cHNK footprint optimizations         * */
-/* *             1.0.6 - 06/09/2003 - G. R-P                                * */
-/* *             - added conditionals around 8-bit magn routines            * */
-/* *             1.0.6 - 07/07/2003 - G.R-P                                 * */
-/* *             - added conditionals around some JNG-supporting code       * */
-/* *             - removed conditionals around 8-bit magn routines          * */
-/* *             - added conditionals around delta-png and 16-bit code      * */
-/* *             1.0.6 - 07/14/2003 - G.R-P                                 * */
-/* *             - added MNG_NO_LOOP_SIGNALS_SUPPORTED conditional          * */
-/* *             1.0.6 - 07/29/2003 - G.Juyn                                * */
-/* *             - fixed invalid test in promote_imageobject                * */
-/* *             1.0.6 - 07/29/2003 - G.R-P.                                * */
-/* *             - added conditionals around PAST chunk support             * */
-/* *             1.0.6 - 08/17/2003 - G.R-P.                                * */
-/* *             - added conditionals around MAGN chunk support             * */
-/* *                                                                        * */
-/* *             1.0.7 - 03/21/2004 - G.Juyn                                * */
-/* *             - fixed some 64-bit platform compiler warnings             * */
-/* *                                                                        * */
-/* *             1.0.9 - 10/10/2004 - G.R-P.                                * */
-/* *             - added MNG_NO_1_2_4BIT_SUPPORT support                    * */
-/* *             1.0.9 - 12/05/2004 - G.Juyn                                * */
-/* *             - added conditional MNG_OPTIMIZE_OBJCLEANUP                * */
-/* *             1.0.9 - 12/11/2004 - G.Juyn                                * */
-/* *             - added conditional MNG_OPTIMIZE_DISPLAYCALLS              * */
-/* *             1.0.9 - 12/31/2004 - G.R-P.                                * */
-/* *             - fixed warnings about possible uninitialized pointers     * */
-/* *             1.0.9 - 01/02/2005 - G.Juyn                                * */
-/* *             - fixing some compiler-warnings                            * */
-/* *                                                                        * */
-/* *             1.0.10 - 02/07/2005 - G.Juyn                               * */
-/* *             - fixed some compiler-warnings                             * */
-/* *             1.0.10 - 07/30/2005 - G.Juyn                               * */
-/* *             - fixed problem with CLON object during readdisplay()      * */
-/* *             1.0.10 - 04/08/2007 - G.Juyn                               * */
-/* *             - added support for mPNG proposal                          * */
-/* *             1.0.10 - 04/12/2007 - G.Juyn                               * */
-/* *             - added support for ANG proposal                           * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#include "libmng.h"
-#include "libmng_data.h"
-#include "libmng_error.h"
-#include "libmng_trace.h"
-#ifdef __BORLANDC__
-#pragma hdrstop
-#endif
-#include "libmng_memory.h"
-#include "libmng_chunks.h"
-#include "libmng_objects.h"
-#include "libmng_display.h"
-#include "libmng_pixels.h"
-#include "libmng_object_prc.h"
-#include "libmng_cms.h"
-
-#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
-#pragma option -A                      /* force ANSI-C */
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_DISPLAY_PROCS
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Generic object routines                                                * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-mng_retcode mng_drop_invalid_objects (mng_datap pData)
-{
-  mng_objectp       pObject;
-  mng_objectp       pNext;
-  mng_cleanupobject fCleanup;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DROP_INVALID_OBJECTS, MNG_LC_START);
-#endif
-
-  pObject = pData->pFirstimgobj;       /* get first stored image-object (if any) */
-
-  while (pObject)                      /* more objects to check ? */
-  {
-    pNext = ((mng_object_headerp)pObject)->pNext;
-                                       /* invalid ? */
-    if (!((mng_imagep)pObject)->bValid)
-    {                                  /* call appropriate cleanup */
-      fCleanup = ((mng_object_headerp)pObject)->fCleanup;
-      fCleanup (pData, pObject);
-    }
-
-    pObject = pNext;                   /* neeeext */
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DROP_INVALID_OBJECTS, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-MNG_LOCAL mng_retcode create_obj_general (mng_datap          pData,
-                                          mng_size_t         iObjsize,
-                                          mng_cleanupobject  fCleanup,
-                                          mng_processobject  fProcess,
-                                          mng_ptr            *ppObject)
-{
-  mng_object_headerp pWork;
-
-  MNG_ALLOC (pData, pWork, iObjsize);
-
-  pWork->fCleanup = fCleanup;
-  pWork->fProcess = fProcess;
-  pWork->iObjsize = iObjsize;
-  *ppObject       = (mng_ptr)pWork;
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-MNG_LOCAL mng_retcode mng_free_obj_general (mng_datap   pData,
-                                            mng_objectp pObject)
-{
-  MNG_FREEX (pData, pObject, ((mng_object_headerp)pObject)->iObjsize);
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Image-data-object routines                                             * */
-/* *                                                                        * */
-/* * these handle the "object buffer" as defined by the MNG specification   * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-mng_retcode mng_create_imagedataobject (mng_datap      pData,
-                                        mng_bool       bConcrete,
-                                        mng_bool       bViewable,
-                                        mng_uint32     iWidth,
-                                        mng_uint32     iHeight,
-                                        mng_uint8      iBitdepth,
-                                        mng_uint8      iColortype,
-                                        mng_uint8      iCompression,
-                                        mng_uint8      iFilter,
-                                        mng_uint8      iInterlace,
-                                        mng_imagedatap *ppObject)
-{
-  mng_imagedatap pImagedata;
-  mng_uint32 iSamplesize = 0;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_IMGDATAOBJECT, MNG_LC_START);
-#endif
-                                       /* get a buffer */
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-  {
-    mng_ptr pTemp;
-    mng_retcode iRetcode = create_obj_general (pData, sizeof (mng_imagedata),
-                                               (mng_cleanupobject)mng_free_imagedataobject,
-                                               MNG_NULL, &pTemp);
-    if (iRetcode)
-      return iRetcode;
-    pImagedata = (mng_imagedatap)pTemp;
-  }
-#else
-  MNG_ALLOC (pData, pImagedata, sizeof (mng_imagedata));
-                                       /* fill the appropriate fields */
-  pImagedata->sHeader.fCleanup   = (mng_cleanupobject)mng_free_imagedataobject;
-  pImagedata->sHeader.fProcess   = MNG_NULL;
-#endif
-  pImagedata->iRefcount          = 1;
-  pImagedata->bFrozen            = MNG_FALSE;
-  pImagedata->bConcrete          = bConcrete;
-  pImagedata->bViewable          = bViewable;
-  pImagedata->iWidth             = iWidth;
-  pImagedata->iHeight            = iHeight;
-  pImagedata->iBitdepth          = iBitdepth;
-  pImagedata->iColortype         = iColortype;
-  pImagedata->iCompression       = iCompression;
-  pImagedata->iFilter            = iFilter;
-  pImagedata->iInterlace         = iInterlace;
-  pImagedata->bCorrected         = MNG_FALSE;
-  pImagedata->iAlphabitdepth     = 0;
-  pImagedata->iJHDRcompression   = 0;
-  pImagedata->iJHDRinterlace     = 0;
-  pImagedata->iPixelsampledepth  = iBitdepth;
-  pImagedata->iAlphasampledepth  = iBitdepth;
-                                       /* determine samplesize from color_type/bit_depth */
-  switch (iColortype)                  /* for < 8-bit samples we just reserve 8 bits */
-  {
-    case  0  : ;                       /* gray */
-    case  8  : {                       /* JPEG gray */
-#ifndef MNG_NO_16BIT_SUPPORT
-                 if (iBitdepth > 8)
-                   iSamplesize = 2;
-                 else
-#endif
-                   iSamplesize = 1;
-
-                 break;
-               }
-    case  2  : ;                       /* rgb */
-    case 10  : {                       /* JPEG rgb */
-#ifndef MNG_NO_16BIT_SUPPORT
-                 if (iBitdepth > 8)
-                   iSamplesize = 6;
-                 else
-#endif
-                   iSamplesize = 3;
-
-                 break;
-               }
-    case  3  : {                       /* indexed */
-                 iSamplesize = 1;
-                 break;
-               }
-    case  4  : ;                       /* gray+alpha */
-    case 12  : {                       /* JPEG gray+alpha */
-#ifndef MNG_NO_16BIT_SUPPORT
-                 if (iBitdepth > 8)
-                   iSamplesize = 4;
-                 else
-#endif
-                   iSamplesize = 2;
-
-                 break;
-               }
-    case  6  : ;                       /* rgb+alpha */
-    case 14  : {                       /* JPEG rgb+alpha */
-#ifndef MNG_NO_16BIT_SUPPORT
-                 if (iBitdepth > 8)
-                   iSamplesize = 8;
-                 else
-#endif
-                   iSamplesize = 4;
-
-                 break;
-               }
-  }
-                                       /* make sure we remember all this */
-  pImagedata->iSamplesize  = iSamplesize;
-  pImagedata->iRowsize     = iSamplesize * iWidth;
-  pImagedata->iImgdatasize = pImagedata->iRowsize * iHeight;
-
-  if (pImagedata->iImgdatasize)        /* need a buffer ? */
-  {                                    /* so allocate it */
-    MNG_ALLOCX (pData, pImagedata->pImgdata, pImagedata->iImgdatasize);
-
-    if (!pImagedata->pImgdata)         /* enough memory ? */
-    {
-      MNG_FREEX (pData, pImagedata, sizeof (mng_imagedata));
-      MNG_ERROR (pData, MNG_OUTOFMEMORY);
-    }
-  }
-                                       /* check global stuff */
-  pImagedata->bHasGAMA           = pData->bHasglobalGAMA;
-#ifndef MNG_SKIPCHUNK_cHRM
-  pImagedata->bHasCHRM           = pData->bHasglobalCHRM;
-#endif
-  pImagedata->bHasSRGB           = pData->bHasglobalSRGB;
-#ifndef MNG_SKIPCHUNK_iCCP
-  pImagedata->bHasICCP           = pData->bHasglobalICCP;
-#endif
-#ifndef MNG_SKIPCHUNK_bKGD
-  pImagedata->bHasBKGD           = pData->bHasglobalBKGD;
-#endif
-
-  if (pData->bHasglobalGAMA)           /* global gAMA present ? */
-    pImagedata->iGamma           = pData->iGlobalGamma;
-
-#ifndef MNG_SKIPCHUNK_cHRM
-  if (pData->bHasglobalCHRM)           /* global cHRM present ? */
-  {
-    pImagedata->iWhitepointx     = pData->iGlobalWhitepointx;
-    pImagedata->iWhitepointy     = pData->iGlobalWhitepointy;
-    pImagedata->iPrimaryredx     = pData->iGlobalPrimaryredx;
-    pImagedata->iPrimaryredy     = pData->iGlobalPrimaryredy;
-    pImagedata->iPrimarygreenx   = pData->iGlobalPrimarygreenx;
-    pImagedata->iPrimarygreeny   = pData->iGlobalPrimarygreeny;
-    pImagedata->iPrimarybluex    = pData->iGlobalPrimarybluex;
-    pImagedata->iPrimarybluey    = pData->iGlobalPrimarybluey;
-  }
-#endif
-
-  if (pData->bHasglobalSRGB)           /* glbal sRGB present ? */
-    pImagedata->iRenderingintent = pData->iGlobalRendintent;
-
-#ifndef MNG_SKIPCHUNK_iCCP
-  if (pData->bHasglobalICCP)           /* glbal iCCP present ? */
-  {
-    pImagedata->iProfilesize     = pData->iGlobalProfilesize;
-
-    if (pImagedata->iProfilesize)
-    {
-      MNG_ALLOCX (pData, pImagedata->pProfile, pImagedata->iProfilesize);
-
-      if (!pImagedata->pProfile)       /* enough memory ? */
-      {
-        MNG_FREEX (pData, pImagedata->pImgdata, pImagedata->iImgdatasize);
-        MNG_FREEX (pData, pImagedata, sizeof (mng_imagedata));
-        MNG_ERROR (pData, MNG_OUTOFMEMORY);
-      }
-
-      MNG_COPY  (pImagedata->pProfile, pData->pGlobalProfile, pImagedata->iProfilesize);
-    }
-  }
-#endif
-
-#ifndef MNG_SKIPCHUNK_bKGD
-  if (pData->bHasglobalBKGD)           /* global bKGD present ? */
-  {
-    pImagedata->iBKGDred         = pData->iGlobalBKGDred;
-    pImagedata->iBKGDgreen       = pData->iGlobalBKGDgreen;
-    pImagedata->iBKGDblue        = pData->iGlobalBKGDblue;
-  }
-#endif
-
-  *ppObject = pImagedata;              /* return it */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_IMGDATAOBJECT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_free_imagedataobject   (mng_datap      pData,
-                                        mng_imagedatap pImagedata)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_IMGDATAOBJECT, MNG_LC_START);
-#endif
-
-  if (pImagedata->iRefcount)           /* decrease reference count */
-    pImagedata->iRefcount--;
-
-  if (!pImagedata->iRefcount)          /* reached zero ? */
-  {
-#ifndef MNG_SKIPCHUNK_iCCP
-    if (pImagedata->iProfilesize)      /* stored an iCCP profile ? */
-      MNG_FREEX (pData, pImagedata->pProfile, pImagedata->iProfilesize);
-#endif
-    if (pImagedata->iImgdatasize)      /* sample-buffer present ? */
-      MNG_FREEX (pData, pImagedata->pImgdata, pImagedata->iImgdatasize);
-                                       /* drop the buffer */
-    MNG_FREEX (pData, pImagedata, sizeof (mng_imagedata));
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_IMGDATAOBJECT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_clone_imagedataobject  (mng_datap      pData,
-                                        mng_bool       bConcrete,
-                                        mng_imagedatap pSource,
-                                        mng_imagedatap *ppClone)
-{
-  mng_imagedatap pNewdata;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CLONE_IMGDATAOBJECT, MNG_LC_START);
-#endif
-                                       /* get a buffer */
-  MNG_ALLOC (pData, pNewdata, sizeof (mng_imagedata));
-                                       /* blatently copy the original buffer */
-  MNG_COPY (pNewdata, pSource, sizeof (mng_imagedata));
-
-  pNewdata->iRefcount = 1;             /* only the reference count */
-  pNewdata->bConcrete = bConcrete;     /* and concrete-flag are different */
-  pNewdata->bFrozen   = MNG_FALSE;
-
-  if (pNewdata->iImgdatasize)          /* sample buffer present ? */
-  {
-    MNG_ALLOCX (pData, pNewdata->pImgdata, pNewdata->iImgdatasize);
-
-    if (!pNewdata->pImgdata)           /* not enough memory ? */
-    {
-      MNG_FREEX (pData, pNewdata, sizeof (mng_imagedata));
-      MNG_ERROR (pData, MNG_OUTOFMEMORY);
-    }
-                                       /* make a copy */
-    MNG_COPY (pNewdata->pImgdata, pSource->pImgdata, pNewdata->iImgdatasize);
-  }
-
-#ifndef MNG_SKIPCHUNK_iCCP
-  if (pNewdata->iProfilesize)          /* iCCP profile present ? */
-  {
-    MNG_ALLOCX (pData, pNewdata->pProfile, pNewdata->iProfilesize);
-
-    if (!pNewdata->pProfile)           /* enough memory ? */
-    {
-      MNG_FREEX (pData, pNewdata, sizeof (mng_imagedata));
-      MNG_ERROR (pData, MNG_OUTOFMEMORY);
-    }
-                                       /* make a copy */
-    MNG_COPY (pNewdata->pProfile, pSource->pProfile, pNewdata->iProfilesize);
-  }
-#endif
-
-  *ppClone = pNewdata;                 /* return the clone */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CLONE_IMGDATAOBJECT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Image-object routines                                                  * */
-/* *                                                                        * */
-/* * these handle the "object" as defined by the MNG specification          * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-mng_retcode mng_create_imageobject (mng_datap  pData,
-                                    mng_uint16 iId,
-                                    mng_bool   bConcrete,
-                                    mng_bool   bVisible,
-                                    mng_bool   bViewable,
-                                    mng_uint32 iWidth,
-                                    mng_uint32 iHeight,
-                                    mng_uint8  iBitdepth,
-                                    mng_uint8  iColortype,
-                                    mng_uint8  iCompression,
-                                    mng_uint8  iFilter,
-                                    mng_uint8  iInterlace,
-                                    mng_int32  iPosx,
-                                    mng_int32  iPosy,
-                                    mng_bool   bClipped,
-                                    mng_int32  iClipl,
-                                    mng_int32  iClipr,
-                                    mng_int32  iClipt,
-                                    mng_int32  iClipb,
-                                    mng_imagep *ppObject)
-{
-  mng_imagep     pImage;
-  mng_imagep     pPrev, pNext;
-  mng_retcode    iRetcode;
-  mng_imagedatap pImgbuf;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_IMGOBJECT, MNG_LC_START);
-#endif
-                                       /* get a buffer */
-  MNG_ALLOC (pData, pImage, sizeof (mng_image));
-                                       /* now get a new "object buffer" */
-  iRetcode = mng_create_imagedataobject (pData, bConcrete, bViewable,
-                                         iWidth, iHeight, iBitdepth, iColortype,
-                                         iCompression, iFilter, iInterlace,
-                                         &pImgbuf);
-
-  if (iRetcode)                        /* on error bail out */
-  {
-    MNG_FREEX (pData, pImage, sizeof (mng_image));
-    return iRetcode;
-  }
-                                       /* fill the appropriate fields */
-  pImage->sHeader.fCleanup = (mng_cleanupobject)mng_free_imageobject;
-  pImage->sHeader.fProcess = MNG_NULL;
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-  pImage->sHeader.iObjsize = sizeof (mng_image);
-#endif
-  pImage->iId              = iId;
-  pImage->bFrozen          = MNG_FALSE;
-  pImage->bVisible         = bVisible;
-  pImage->bViewable        = bViewable;
-  pImage->bValid           = (mng_bool)((pData->bDisplaying) &&
-                                        ((pData->bRunning) || (pData->bSearching)) &&
-                                        (!pData->bFreezing));
-  pImage->iPosx            = iPosx;
-  pImage->iPosy            = iPosy;
-  pImage->bClipped         = bClipped;
-  pImage->iClipl           = iClipl;
-  pImage->iClipr           = iClipr;
-  pImage->iClipt           = iClipt;
-  pImage->iClipb           = iClipb;
-#ifndef MNG_SKIPCHUNK_MAGN
-  pImage->iMAGN_MethodX    = 0;
-  pImage->iMAGN_MethodY    = 0;
-  pImage->iMAGN_MX         = 0;
-  pImage->iMAGN_MY         = 0;
-  pImage->iMAGN_ML         = 0;
-  pImage->iMAGN_MR         = 0;
-  pImage->iMAGN_MT         = 0;
-  pImage->iMAGN_MB         = 0;
-#endif
-#ifndef MNG_SKIPCHUNK_PAST
-  pImage->iPastx           = 0;
-  pImage->iPasty           = 0;
-#endif
-  pImage->pImgbuf          = pImgbuf;
-
-  if (iId)                             /* only if not object 0 ! */
-  {                                    /* find previous lower object-id */
-    pPrev = (mng_imagep)pData->pLastimgobj;
-
-    while ((pPrev) && (pPrev->iId > iId))
-      pPrev = (mng_imagep)pPrev->sHeader.pPrev;
-
-    if (pPrev)                         /* found it ? */
-    {
-      pImage->sHeader.pPrev = pPrev;   /* than link it in place */
-      pImage->sHeader.pNext = pPrev->sHeader.pNext;
-      pPrev->sHeader.pNext  = pImage;
-    }
-    else                               /* if not found, it becomes the first ! */
-    {
-      pImage->sHeader.pNext = pData->pFirstimgobj;
-      pData->pFirstimgobj   = pImage;
-    }
-
-    pNext                   = (mng_imagep)pImage->sHeader.pNext;
-
-    if (pNext)
-      pNext->sHeader.pPrev  = pImage;
-    else
-      pData->pLastimgobj    = pImage;
-    
-  }  
-
-  *ppObject = pImage;                  /* and return the new buffer */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_IMGOBJECT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* okido */
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_free_imageobject (mng_datap  pData,
-                                  mng_imagep pImage)
-{
-  mng_retcode    iRetcode;
-  mng_imagep     pPrev   = pImage->sHeader.pPrev;
-  mng_imagep     pNext   = pImage->sHeader.pNext;
-  mng_imagedatap pImgbuf = pImage->pImgbuf;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_IMGOBJECT, MNG_LC_START);
-#endif
-
-  if (pImage->iId)                     /* not for object 0 */
-  {
-    if (pPrev)                         /* unlink from the list first ! */
-      pPrev->sHeader.pNext = pImage->sHeader.pNext;
-    else
-      pData->pFirstimgobj  = pImage->sHeader.pNext;
-
-    if (pNext)
-      pNext->sHeader.pPrev = pImage->sHeader.pPrev;
-    else
-      pData->pLastimgobj   = pImage->sHeader.pPrev;
-
-  }
-                                       /* unlink the image-data buffer */
-  iRetcode = mng_free_imagedataobject (pData, pImgbuf);
-                                       /* drop its own buffer */
-  MNG_FREEX (pData, pImage, sizeof (mng_image));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_IMGOBJECT, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-
-/* ************************************************************************** */
-
-mng_imagep mng_find_imageobject (mng_datap  pData,
-                                 mng_uint16 iId)
-{
-  mng_imagep pImage = (mng_imagep)pData->pFirstimgobj;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (pData, MNG_FN_FIND_IMGOBJECT, MNG_LC_START);
-#endif
-                                       /* look up the right id */
-  while ((pImage) && (pImage->iId != iId))
-    pImage = (mng_imagep)pImage->sHeader.pNext;
-
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-  if ((!pImage) && (pData->eImagetype == mng_it_mpng))
-    pImage = pData->pObjzero;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (pData, MNG_FN_FIND_IMGOBJECT, MNG_LC_END);
-#endif
-
-  return pImage;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_clone_imageobject (mng_datap  pData,
-                                   mng_uint16 iId,
-                                   mng_bool   bPartial,
-                                   mng_bool   bVisible,
-                                   mng_bool   bAbstract,
-                                   mng_bool   bHasloca,
-                                   mng_uint8  iLocationtype,
-                                   mng_int32  iLocationx,
-                                   mng_int32  iLocationy,
-                                   mng_imagep pSource,
-                                   mng_imagep *ppClone)
-{
-  mng_imagep     pNew;
-  mng_imagep     pPrev, pNext;
-  mng_retcode    iRetcode;
-  mng_imagedatap pImgbuf;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CLONE_IMGOBJECT, MNG_LC_START);
-#endif
-
-#ifndef MNG_SKIPCHUNK_MAGN
-  if ((pSource->iId) &&                /* needs magnification ? */
-      ((pSource->iMAGN_MethodX) || (pSource->iMAGN_MethodY)))
-  {
-    iRetcode = mng_magnify_imageobject (pData, pSource);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-  }
-#endif
-                                       /* get a buffer */
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-  {
-    mng_ptr     pTemp;
-    mng_retcode iRetcode = create_obj_general (pData, sizeof (mng_image),
-                                               (mng_cleanupobject)mng_free_imageobject,
-                                               MNG_NULL, &pTemp);
-    if (iRetcode)
-      return iRetcode;
-    pNew = (mng_imagep)pTemp;
-  }
-#else
-  MNG_ALLOC (pData, pNew, sizeof (mng_image));
-                                       /* fill or copy the appropriate fields */
-  pNew->sHeader.fCleanup = (mng_cleanupobject)mng_free_imageobject;
-  pNew->sHeader.fProcess = MNG_NULL;
-#endif
-  pNew->iId              = iId;
-  pNew->bFrozen          = MNG_FALSE;
-  pNew->bVisible         = bVisible;
-  pNew->bViewable        = pSource->bViewable;
-  pNew->bValid           = MNG_TRUE;
-
-  if (bHasloca)                        /* location info available ? */
-  {
-    if (iLocationtype == 0)            /* absolute position ? */
-    {
-      pNew->iPosx        = iLocationx;
-      pNew->iPosy        = iLocationy;
-    }
-    else                               /* relative */
-    {
-      pNew->iPosx        = pSource->iPosx + iLocationx;
-      pNew->iPosy        = pSource->iPosy + iLocationy;
-    }
-  }
-  else                                 /* copy from source */
-  {
-    pNew->iPosx          = pSource->iPosx;
-    pNew->iPosy          = pSource->iPosy;
-  }
-                                       /* copy clipping info */
-  pNew->bClipped         = pSource->bClipped;
-  pNew->iClipl           = pSource->iClipl;
-  pNew->iClipr           = pSource->iClipr;
-  pNew->iClipt           = pSource->iClipt;
-  pNew->iClipb           = pSource->iClipb;
-#ifndef MNG_SKIPCHUNK_MAGN
-                                       /* copy magnification info */
-/*  pNew->iMAGN_MethodX    = pSource->iMAGN_MethodX;     LET'S NOT !!!!!!
-  pNew->iMAGN_MethodY    = pSource->iMAGN_MethodY;
-  pNew->iMAGN_MX         = pSource->iMAGN_MX;
-  pNew->iMAGN_MY         = pSource->iMAGN_MY;
-  pNew->iMAGN_ML         = pSource->iMAGN_ML;
-  pNew->iMAGN_MR         = pSource->iMAGN_MR;
-  pNew->iMAGN_MT         = pSource->iMAGN_MT;
-  pNew->iMAGN_MB         = pSource->iMAGN_MB; */
-#endif
-
-#ifndef MNG_SKIPCHUNK_PAST
-  pNew->iPastx           = 0;          /* initialize PAST info */
-  pNew->iPasty           = 0;
-#endif
-
-  if (iId)                             /* not for object 0 */
-  {                                    /* find previous lower object-id */
-    pPrev = (mng_imagep)pData->pLastimgobj;
-    while ((pPrev) && (pPrev->iId > iId))
-      pPrev = (mng_imagep)pPrev->sHeader.pPrev;
-
-    if (pPrev)                         /* found it ? */
-    {
-      pNew->sHeader.pPrev  = pPrev;    /* than link it in place */
-      pNew->sHeader.pNext  = pPrev->sHeader.pNext;
-      pPrev->sHeader.pNext = pNew;
-    }
-    else                               /* if not found, it becomes the first ! */
-    {
-      pNew->sHeader.pNext  = pData->pFirstimgobj;
-      pData->pFirstimgobj  = pNew;
-    }
-
-    pNext                  = (mng_imagep)pNew->sHeader.pNext;
-
-    if (pNext)
-      pNext->sHeader.pPrev = pNew;
-    else
-      pData->pLastimgobj   = pNew;
-
-  }
-
-  if (bPartial)                        /* partial clone ? */
-  {
-    pNew->pImgbuf = pSource->pImgbuf;  /* use the same object buffer */
-    pNew->pImgbuf->iRefcount++;        /* and increase the reference count */
-  }
-  else                                 /* create a full clone ! */
-  {
-    mng_bool bConcrete = MNG_FALSE;    /* it's abstract by default (?) */
-
-    if (!bAbstract)                    /* determine concreteness from source ? */
-      bConcrete = pSource->pImgbuf->bConcrete;
-                                       /* create a full clone ! */
-    iRetcode = mng_clone_imagedataobject (pData, bConcrete, pSource->pImgbuf, &pImgbuf);
-
-    if (iRetcode)                      /* on error bail out */
-    {
-      MNG_FREEX (pData, pNew, sizeof (mng_image));
-      return iRetcode;
-    }
-
-    pNew->pImgbuf = pImgbuf;           /* and remember it */
-  }
-
-  *ppClone = pNew;                     /* return it */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CLONE_IMGOBJECT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_renum_imageobject (mng_datap  pData,
-                                   mng_imagep pSource,
-                                   mng_uint16 iId,
-                                   mng_bool   bVisible,
-                                   mng_bool   bAbstract,
-                                   mng_bool   bHasloca,
-                                   mng_uint8  iLocationtype,
-                                   mng_int32  iLocationx,
-                                   mng_int32  iLocationy)
-{
-  mng_imagep pPrev, pNext;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RENUM_IMGOBJECT, MNG_LC_START);
-#endif
-
-  pSource->bVisible  = bVisible;       /* store the new visibility */
-
-  if (bHasloca)                        /* location info available ? */
-  {
-    if (iLocationtype == 0)            /* absolute position ? */
-    {
-      pSource->iPosx = iLocationx;
-      pSource->iPosy = iLocationy;
-    }
-    else                               /* relative */
-    {
-      pSource->iPosx = pSource->iPosx + iLocationx;
-      pSource->iPosy = pSource->iPosy + iLocationy;
-    }
-  }
-
-  if (iId)                             /* not for object 0 */
-  {                                    /* find previous lower object-id */
-    pPrev = (mng_imagep)pData->pLastimgobj;
-    while ((pPrev) && (pPrev->iId > iId))
-      pPrev = (mng_imagep)pPrev->sHeader.pPrev;
-                                       /* different from current ? */
-    if (pPrev != (mng_imagep)pSource->sHeader.pPrev)
-    {
-      if (pSource->sHeader.pPrev)      /* unlink from current position !! */
-        ((mng_imagep)pSource->sHeader.pPrev)->sHeader.pNext = pSource->sHeader.pNext;
-      else
-        pData->pFirstimgobj                                 = pSource->sHeader.pNext;
-
-      if (pSource->sHeader.pNext)
-        ((mng_imagep)pSource->sHeader.pNext)->sHeader.pPrev = pSource->sHeader.pPrev;
-      else
-        pData->pLastimgobj                                  = pSource->sHeader.pPrev;
-
-      if (pPrev)                       /* found the previous ? */
-      {                                /* than link it in place */
-        pSource->sHeader.pPrev = pPrev;
-        pSource->sHeader.pNext = pPrev->sHeader.pNext;
-        pPrev->sHeader.pNext   = pSource;
-      }
-      else                             /* if not found, it becomes the first ! */
-      {
-        pSource->sHeader.pNext = pData->pFirstimgobj;
-        pData->pFirstimgobj    = pSource;
-      }
-
-      pNext                    = (mng_imagep)pSource->sHeader.pNext;
-
-      if (pNext)
-        pNext->sHeader.pPrev   = pSource;
-      else
-        pData->pLastimgobj     = pSource;
-
-    }
-  }
-
-  pSource->iId = iId;                  /* now set the new id! */
-
-  if (bAbstract)                       /* force it to abstract ? */
-    pSource->pImgbuf->bConcrete = MNG_FALSE;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RENUM_IMGOBJECT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_reset_object_details (mng_datap  pData,
-                                      mng_imagep pImage,
-                                      mng_uint32 iWidth,
-                                      mng_uint32 iHeight,
-                                      mng_uint8  iBitdepth,
-                                      mng_uint8  iColortype,
-                                      mng_uint8  iCompression,
-                                      mng_uint8  iFilter,
-                                      mng_uint8  iInterlace,
-                                      mng_bool   bResetall)
-{
-  mng_imagedatap pBuf  = pImage->pImgbuf;
-  mng_uint32     iSamplesize = 0;
-  mng_uint32     iRowsize;
-  mng_uint32     iImgdatasize;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RESET_OBJECTDETAILS, MNG_LC_START);
-#endif
-
-  pBuf->iWidth         = iWidth;       /* set buffer characteristics */
-  pBuf->iHeight        = iHeight;
-  pBuf->iBitdepth      = iBitdepth;
-  pBuf->iColortype     = iColortype;
-  pBuf->iCompression   = iCompression;
-  pBuf->iFilter        = iFilter;
-  pBuf->iInterlace     = iInterlace;
-  pBuf->bCorrected     = MNG_FALSE;
-  pBuf->iAlphabitdepth = 0;
-                                       /* determine samplesize from color_type/bit_depth */
-  switch (iColortype)                  /* for < 8-bit samples we just reserve 8 bits */
-  {
-    case  0  : ;                       /* gray */
-    case  8  : {                       /* JPEG gray */
-#ifndef MNG_NO_16BIT_SUPPORT
-                 if (iBitdepth > 8)
-                   iSamplesize = 2;
-                 else
-#endif
-                   iSamplesize = 1;
-
-                 break;
-               }
-    case  2  : ;                       /* rgb */
-    case 10  : {                       /* JPEG rgb */
-#ifndef MNG_NO_16BIT_SUPPORT
-                 if (iBitdepth > 8)
-                   iSamplesize = 6;
-                 else
-#endif
-                   iSamplesize = 3;
-
-                 break;
-               }
-    case  3  : {                       /* indexed */
-                 iSamplesize = 1;
-                 break;
-               }
-    case  4  : ;                       /* gray+alpha */
-    case 12  : {                       /* JPEG gray+alpha */
-#ifndef MNG_NO_16BIT_SUPPORT
-                 if (iBitdepth > 8)
-                   iSamplesize = 4;
-                 else
-#endif
-                   iSamplesize = 2;
-
-                 break;
-               }
-    case  6  : ;                       /* rgb+alpha */
-    case 14  : {                       /* JPEG rgb+alpha */
-#ifndef MNG_NO_16BIT_SUPPORT
-                 if (iBitdepth > 8)
-                   iSamplesize = 8;
-                 else
-#endif
-                   iSamplesize = 4;
-
-                 break;
-               }
-  }
-
-  iRowsize     = iSamplesize * iWidth;
-  iImgdatasize = iRowsize    * iHeight;
-                                       /* buffer size changed ? */
-  if (iImgdatasize != pBuf->iImgdatasize)
-  {                                    /* drop the old one */
-    MNG_FREE (pData, pBuf->pImgdata, pBuf->iImgdatasize);
-
-    if (iImgdatasize)                  /* allocate new sample-buffer ? */
-      MNG_ALLOC (pData, pBuf->pImgdata, iImgdatasize);
-  }
-  else
-  {
-    if (iImgdatasize)                  /* clear old buffer */
-    {
-      mng_uint8p pTemp = pBuf->pImgdata;
-      mng_uint32 iX;
-      
-      for (iX = 0; iX < (iImgdatasize & (mng_uint32)(~3L)); iX += 4)
-      {
-        *((mng_uint32p)pTemp) = 0x00000000l;
-        pTemp += 4;
-      }
-
-      while (pTemp < (pBuf->pImgdata + iImgdatasize))
-      {
-        *pTemp = 0;
-        pTemp++;
-      }
-    }
-  }
-
-  pBuf->iSamplesize  = iSamplesize;    /* remember new sizes */
-  pBuf->iRowsize     = iRowsize;
-  pBuf->iImgdatasize = iImgdatasize;
-
-  if (!pBuf->iPixelsampledepth)        /* set delta sampledepths if empty */
-    pBuf->iPixelsampledepth = iBitdepth;
-  if (!pBuf->iAlphasampledepth)
-    pBuf->iAlphasampledepth = iBitdepth;
-                                       /* dimension set and clipping not ? */
-  if ((iWidth) && (iHeight) && (!pImage->bClipped))
-  {
-    pImage->iClipl   = 0;              /* set clipping to dimension by default */
-    pImage->iClipr   = iWidth;
-    pImage->iClipt   = 0;
-    pImage->iClipb   = iHeight;
-  }
-
-#ifndef MNG_SKIPCHUNK_MAGN
-  if (pImage->iId)                     /* reset magnification info ? */
-  {
-    pImage->iMAGN_MethodX = 0;
-    pImage->iMAGN_MethodY = 0;
-    pImage->iMAGN_MX      = 0;
-    pImage->iMAGN_MY      = 0;
-    pImage->iMAGN_ML      = 0;
-    pImage->iMAGN_MR      = 0;
-    pImage->iMAGN_MT      = 0;
-    pImage->iMAGN_MB      = 0;
-  }
-#endif
-
-  if (bResetall)                       /* reset the other characteristics ? */
-  {
-#ifndef MNG_SKIPCHUNK_PAST
-    pImage->iPastx = 0;
-    pImage->iPasty = 0;
-#endif
-
-    pBuf->bHasPLTE = MNG_FALSE;
-    pBuf->bHasTRNS = MNG_FALSE;
-    pBuf->bHasGAMA = pData->bHasglobalGAMA;
-#ifndef MNG_SKIPCHUNK_cHRM
-    pBuf->bHasCHRM = pData->bHasglobalCHRM;
-#endif
-    pBuf->bHasSRGB = pData->bHasglobalSRGB;
-#ifndef MNG_SKIPCHUNK_iCCP
-    pBuf->bHasICCP = pData->bHasglobalICCP;
-#endif
-#ifndef MNG_SKIPCHUNK_bKGD
-    pBuf->bHasBKGD = pData->bHasglobalBKGD;
-#endif
-
-#ifndef MNG_SKIPCHUNK_iCCP
-    if (pBuf->iProfilesize)            /* drop possibly old ICC profile */
-    {
-      MNG_FREE (pData, pBuf->pProfile, pBuf->iProfilesize);
-      pBuf->iProfilesize     = 0;
-    }  
-#endif
-
-    if (pData->bHasglobalGAMA)         /* global gAMA present ? */
-      pBuf->iGamma           = pData->iGlobalGamma;
-
-#ifndef MNG_SKIPCHUNK_cHRM
-    if (pData->bHasglobalCHRM)         /* global cHRM present ? */
-    {
-      pBuf->iWhitepointx     = pData->iGlobalWhitepointx;
-      pBuf->iWhitepointy     = pData->iGlobalWhitepointy;
-      pBuf->iPrimaryredx     = pData->iGlobalPrimaryredx;
-      pBuf->iPrimaryredy     = pData->iGlobalPrimaryredy;
-      pBuf->iPrimarygreenx   = pData->iGlobalPrimarygreenx;
-      pBuf->iPrimarygreeny   = pData->iGlobalPrimarygreeny;
-      pBuf->iPrimarybluex    = pData->iGlobalPrimarybluex;
-      pBuf->iPrimarybluey    = pData->iGlobalPrimarybluey;
-    }
-#endif
-
-    if (pData->bHasglobalSRGB)           /* global sRGB present ? */
-      pBuf->iRenderingintent = pData->iGlobalRendintent;
-
-#ifndef MNG_SKIPCHUNK_iCCP
-    if (pData->bHasglobalICCP)           /* global iCCP present ? */
-    {
-      if (pData->iGlobalProfilesize)
-      {
-        MNG_ALLOC (pData, pBuf->pProfile, pData->iGlobalProfilesize);
-        MNG_COPY  (pBuf->pProfile, pData->pGlobalProfile, pData->iGlobalProfilesize);
-      }
-
-      pBuf->iProfilesize     = pData->iGlobalProfilesize;
-    }
-#endif
-
-#ifndef MNG_SKIPCHUNK_bKGD
-    if (pData->bHasglobalBKGD)           /* global bKGD present ? */
-    {
-      pBuf->iBKGDred         = pData->iGlobalBKGDred;
-      pBuf->iBKGDgreen       = pData->iGlobalBKGDgreen;
-      pBuf->iBKGDblue        = pData->iGlobalBKGDblue;
-    }
-#endif
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RESET_OBJECTDETAILS, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#if !defined(MNG_NO_DELTA_PNG) || !defined(MNG_SKIPCHUNK_PAST) || !defined(MNG_SKIPCHUNK_MAGN)
-mng_retcode mng_promote_imageobject (mng_datap  pData,
-                                     mng_imagep pImage,
-                                     mng_uint8  iBitdepth,
-                                     mng_uint8  iColortype,
-                                     mng_uint8  iFilltype)
-{
-  mng_retcode    iRetcode       = MNG_NOERROR;
-  mng_imagedatap pBuf           = pImage->pImgbuf;
-  mng_uint32     iW             = pBuf->iWidth;
-  mng_uint32     iH             = pBuf->iHeight;
-  mng_uint8p     pNewbuf;
-  mng_uint32     iNewbufsize;
-  mng_uint32     iNewrowsize;
-  mng_uint32     iNewsamplesize = pBuf->iSamplesize;
-  mng_uint32     iY;
-  mng_uint8      iTempdepth;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_IMGOBJECT, MNG_LC_START);
-#endif
-
-#ifdef MNG_NO_1_2_4BIT_SUPPORT
-  if (iBitdepth < 8)
-    iBitdepth=8;
-  if (pBuf->iBitdepth < 8)
-    pBuf->iBitdepth=8;
-#endif
-#ifdef MNG_NO_16BIT_SUPPORT
-  if (iBitdepth > 8)
-    iBitdepth=8;
-  if (pBuf->iBitdepth > 8)
-    pBuf->iBitdepth=8;
-#endif
-
-  pData->fPromoterow    = MNG_NULL;    /* init promotion fields */
-  pData->fPromBitdepth  = MNG_NULL;
-  pData->iPromColortype = iColortype;
-  pData->iPromBitdepth  = iBitdepth;
-  pData->iPromFilltype  = iFilltype;
-
-  if (iBitdepth != pBuf->iBitdepth)    /* determine bitdepth promotion */
-  {
-    if (pBuf->iColortype == MNG_COLORTYPE_INDEXED)
-      iTempdepth = 8;
-    else
-      iTempdepth = pBuf->iBitdepth;
-
-#ifndef MNG_NO_DELTA_PNG
-    if (iFilltype == MNG_FILLMETHOD_ZEROFILL)
-    {
-      switch (iTempdepth)
-      {
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-        case 1 : {
-                   switch (iBitdepth)
-                   {
-                     case  2 : { pData->fPromBitdepth = (mng_fptr)mng_promote_zerofill_1_2;  break; }
-                     case  4 : { pData->fPromBitdepth = (mng_fptr)mng_promote_zerofill_1_4;  break; }
-                     case  8 : { pData->fPromBitdepth = (mng_fptr)mng_promote_zerofill_1_8;  break; }
-#ifndef MNG_NO_16BIT_SUPPORT
-                     case 16 : { pData->fPromBitdepth = (mng_fptr)mng_promote_zerofill_1_16; break; }
-#endif
-                   }
-                   break;
-                 }
-        case 2 : {
-                   switch (iBitdepth)
-                   {
-                     case  4 : { pData->fPromBitdepth = (mng_fptr)mng_promote_zerofill_2_4;  break; }
-                     case  8 : { pData->fPromBitdepth = (mng_fptr)mng_promote_zerofill_2_8;  break; }
-#ifndef MNG_NO_16BIT_SUPPORT
-                     case 16 : { pData->fPromBitdepth = (mng_fptr)mng_promote_zerofill_2_16; break; }
-#endif
-                   }
-                   break;
-                 }
-        case 4 : {
-                   switch (iBitdepth)
-                   {
-                     case  8 : { pData->fPromBitdepth = (mng_fptr)mng_promote_zerofill_4_8;  break; }
-#ifndef MNG_NO_16BIT_SUPPORT
-                     case 16 : { pData->fPromBitdepth = (mng_fptr)mng_promote_zerofill_4_16; break; }
-#endif
-                   }
-                   break;
-                 }
-#endif /* MNG_NO_1_2_4BIT_SUPPORT */
-        case 8 : {
-#ifndef MNG_NO_16BIT_SUPPORT
-                   if (iBitdepth == 16)
-                     pData->fPromBitdepth = (mng_fptr)mng_promote_zerofill_8_16;
-#endif
-                   break;
-                 }
-      }
-    }
-    else
-#endif
-    {
-      switch (iTempdepth)
-      {
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-        case 1 : {
-                   switch (iBitdepth)
-                   {
-                     case  2 : { pData->fPromBitdepth = (mng_fptr)mng_promote_replicate_1_2;  break; }
-                     case  4 : { pData->fPromBitdepth = (mng_fptr)mng_promote_replicate_1_4;  break; }
-                     case  8 : { pData->fPromBitdepth = (mng_fptr)mng_promote_replicate_1_8;  break; }
-#ifndef MNG_NO_16BIT_SUPPORT
-                     case 16 : { pData->fPromBitdepth = (mng_fptr)mng_promote_replicate_1_16; break; }
-#endif
-                   }
-                   break;
-                 }
-        case 2 : {
-                   switch (iBitdepth)
-                   {
-                     case  4 : { pData->fPromBitdepth = (mng_fptr)mng_promote_replicate_2_4;  break; }
-                     case  8 : { pData->fPromBitdepth = (mng_fptr)mng_promote_replicate_2_8;  break; }
-#ifndef MNG_NO_16BIT_SUPPORT
-                     case 16 : { pData->fPromBitdepth = (mng_fptr)mng_promote_replicate_2_16; break; }
-#endif
-                   }
-                   break;
-                 }
-        case 4 : {
-                   switch (iBitdepth)
-                   {
-                     case  8 : { pData->fPromBitdepth = (mng_fptr)mng_promote_replicate_4_8;  break; }
-#ifndef MNG_NO_16BIT_SUPPORT
-                     case 16 : { pData->fPromBitdepth = (mng_fptr)mng_promote_replicate_4_16; break; }
-#endif
-                   }
-                   break;
-                 }
-#endif /* MNG_NO_1_2_4BIT_SUPPORT */
-        case 8 : {
-#ifndef MNG_NO_16BIT_SUPPORT
-                   if (iBitdepth == 16)
-                     pData->fPromBitdepth = (mng_fptr)mng_promote_replicate_8_16;
-#endif
-                   break;
-                 }
-      }
-    }
-  }
-                                       /* g -> g */
-  if ((pBuf->iColortype == MNG_COLORTYPE_GRAY) &&
-      (iColortype == MNG_COLORTYPE_GRAY))
-  {
-    if (pBuf->iBitdepth <= 8)          /* source <= 8 bits */
-    {
-#ifndef MNG_NO_16BIT_SUPPORT
-      if (iBitdepth == 16)
-        pData->fPromoterow = (mng_fptr)mng_promote_g8_g16;
-      else
-#endif
-        pData->fPromoterow = (mng_fptr)mng_promote_g8_g8;
-    }
-
-    iNewsamplesize = 1;
-
-#ifndef MNG_NO_16BIT_SUPPORT
-    if (iBitdepth == 16)               /* 16-bit wide ? */
-      iNewsamplesize = 2;
-#endif
-  }
-  else                                 /* g -> ga */
-  if ((pBuf->iColortype == MNG_COLORTYPE_GRAY) &&
-      (iColortype == MNG_COLORTYPE_GRAYA))
-  {
-    if (pBuf->iBitdepth <= 8)          /* source <= 8 bits */
-    {
-#ifndef MNG_NO_16BIT_SUPPORT
-      if (iBitdepth == 16)
-        pData->fPromoterow = (mng_fptr)mng_promote_g8_ga16;
-      else
-#endif
-        pData->fPromoterow = (mng_fptr)mng_promote_g8_ga8;
-    }
-#ifndef MNG_NO_16BIT_SUPPORT
-    else                               /* source = 16 bits */
-      pData->fPromoterow = (mng_fptr)mng_promote_g16_ga16;
-#endif
-
-    iNewsamplesize = 2;
-
-#ifndef MNG_NO_16BIT_SUPPORT
-    if (iBitdepth == 16)               /* 16-bit wide ? */
-      iNewsamplesize = 4;
-#endif
-  }
-  else                                 /* g -> rgb */
-  if ((pBuf->iColortype == MNG_COLORTYPE_GRAY) &&
-      (iColortype == MNG_COLORTYPE_RGB))
-  {
-    if (pBuf->iBitdepth <= 8)          /* source <= 8 bits */
-    {
-#ifndef MNG_NO_16BIT_SUPPORT
-      if (iBitdepth == 16)
-        pData->fPromoterow = (mng_fptr)mng_promote_g8_rgb16;
-      else
-#endif
-        pData->fPromoterow = (mng_fptr)mng_promote_g8_rgb8;
-    }
-#ifndef MNG_NO_16BIT_SUPPORT
-    else                               /* source = 16 bits */
-      pData->fPromoterow = (mng_fptr)mng_promote_g16_rgb16;
-#endif
-
-    iNewsamplesize = 3;
-
-#ifndef MNG_NO_16BIT_SUPPORT
-    if (iBitdepth == 16)               /* 16-bit wide ? */
-      iNewsamplesize = 6;
-#endif
-  }
-  else                                 /* g -> rgba */
-  if ((pBuf->iColortype == MNG_COLORTYPE_GRAY) &&
-      (iColortype == MNG_COLORTYPE_RGBA))
-  {
-    if (pBuf->iBitdepth <= 8)          /* source <= 8 bits */
-    {
-#ifndef MNG_NO_16BIT_SUPPORT
-      if (iBitdepth == 16)
-        pData->fPromoterow = (mng_fptr)mng_promote_g8_rgba16;
-      else
-#endif
-        pData->fPromoterow = (mng_fptr)mng_promote_g8_rgba8;
-    }
-#ifndef MNG_NO_16BIT_SUPPORT
-    else                               /* source = 16 bits */
-      pData->fPromoterow = (mng_fptr)mng_promote_g16_rgba16;
-#endif
-
-    iNewsamplesize = 4;
-
-#ifndef MNG_NO_16BIT_SUPPORT
-    if (iBitdepth == 16)               /* 16-bit wide ? */
-      iNewsamplesize = 8;
-#endif
-  }
-  else                                 /* ga -> ga */
-  if ((pBuf->iColortype == MNG_COLORTYPE_GRAYA) &&
-      (iColortype == MNG_COLORTYPE_GRAYA))
-  {
-    iNewsamplesize = 2;
-#ifndef MNG_NO_16BIT_SUPPORT
-    if (pBuf->iBitdepth <= 8)          /* source <= 8 bits */
-      if (iBitdepth == 16)
-        pData->fPromoterow = (mng_fptr)mng_promote_ga8_ga16;
-    if (iBitdepth == 16)
-      iNewsamplesize = 4;
-#endif
-  }
-  else                                 /* ga -> rgba */
-  if ((pBuf->iColortype == MNG_COLORTYPE_GRAYA) &&
-      (iColortype == MNG_COLORTYPE_RGBA))
-  {
-    if (pBuf->iBitdepth <= 8)          /* source <= 8 bits */
-    {
-#ifndef MNG_NO_16BIT_SUPPORT
-      if (iBitdepth == 16)
-        pData->fPromoterow = (mng_fptr)mng_promote_ga8_rgba16;
-      else
-#endif
-        pData->fPromoterow = (mng_fptr)mng_promote_ga8_rgba8;
-    }
-#ifndef MNG_NO_16BIT_SUPPORT
-    else                               /* source = 16 bits */
-      pData->fPromoterow = (mng_fptr)mng_promote_ga16_rgba16;
-#endif
-
-    iNewsamplesize = 4;
-
-#ifndef MNG_NO_16BIT_SUPPORT
-    if (iBitdepth == 16)               /* 16-bit wide ? */
-      iNewsamplesize = 8;
-#endif
-  }
-  else                                 /* rgb -> rgb */
-  if ((pBuf->iColortype == MNG_COLORTYPE_RGB) &&
-      (iColortype == MNG_COLORTYPE_RGB))
-  {
-    iNewsamplesize = 3;
-#ifndef MNG_NO_16BIT_SUPPORT
-    if (pBuf->iBitdepth <= 8)          /* source <= 8 bits */
-      if (iBitdepth == 16)
-        pData->fPromoterow = (mng_fptr)mng_promote_rgb8_rgb16;
-    if (iBitdepth == 16)
-      iNewsamplesize = 6;
-#endif
-  }
-  else                                 /* rgb -> rgba */
-  if ((pBuf->iColortype == MNG_COLORTYPE_RGB) &&
-      (iColortype == MNG_COLORTYPE_RGBA))
-  {
-    if (pBuf->iBitdepth <= 8)          /* source <= 8 bits */
-    {
-#ifndef MNG_NO_16BIT_SUPPORT
-      if (iBitdepth == 16)
-        pData->fPromoterow = (mng_fptr)mng_promote_rgb8_rgba16;
-      else
-#endif
-        pData->fPromoterow = (mng_fptr)mng_promote_rgb8_rgba8;
-    }
-#ifndef MNG_NO_16BIT_SUPPORT
-    else                               /* source = 16 bits */
-      pData->fPromoterow = (mng_fptr)mng_promote_rgb16_rgba16;
-#endif
-
-    iNewsamplesize = 4;
-#ifndef MNG_NO_16BIT_SUPPORT
-    if (iBitdepth == 16)               /* 16-bit wide ? */
-      iNewsamplesize = 8;
-#endif
-  }
-  else                                 /* indexed -> rgb */
-  if ((pBuf->iColortype == MNG_COLORTYPE_INDEXED) &&
-      (iColortype == MNG_COLORTYPE_RGB))
-  {
-#ifndef MNG_NO_16BIT_SUPPORT
-    if (iBitdepth == 16)
-      pData->fPromoterow = (mng_fptr)mng_promote_idx8_rgb16;
-    else
-#endif
-      pData->fPromoterow = (mng_fptr)mng_promote_idx8_rgb8;
-
-    iNewsamplesize = 3;
-
-#ifndef MNG_NO_16BIT_SUPPORT
-    if (iBitdepth == 16)               /* 16-bit wide ? */
-      iNewsamplesize = 6;
-#endif
-  }
-  else                                 /* indexed -> rgba */
-  if ((pBuf->iColortype == MNG_COLORTYPE_INDEXED) &&
-      (iColortype == MNG_COLORTYPE_RGBA))
-  {
-#ifndef MNG_NO_16BIT_SUPPORT
-    if (iBitdepth == 16)
-      pData->fPromoterow = (mng_fptr)mng_promote_idx8_rgba16;
-    else
-#endif
-      pData->fPromoterow = (mng_fptr)mng_promote_idx8_rgba8;
-
-    iNewsamplesize = 4;
-
-#ifndef MNG_NO_16BIT_SUPPORT
-    if (iBitdepth == 16)               /* 16-bit wide ? */
-      iNewsamplesize = 8;
-#endif
-  }
-  else                                 /* rgba -> rgba */
-  if ((pBuf->iColortype == MNG_COLORTYPE_RGBA) &&
-      (iColortype == MNG_COLORTYPE_RGBA))
-  {
-    iNewsamplesize = 4;
-#ifndef MNG_NO_16BIT_SUPPORT
-    if (pBuf->iBitdepth <= 8)          /* source <= 8 bits */
-    {
-      if (iBitdepth == 16)
-        pData->fPromoterow = (mng_fptr)mng_promote_rgba8_rgba16;
-    }
-    if (iBitdepth == 16)               /* 16-bit wide ? */
-      iNewsamplesize = 8;
-#endif
-  }
-#ifdef MNG_INCLUDE_JNG
-  else                                 /* JPEG g -> g */
-  if ((pBuf->iColortype == MNG_COLORTYPE_JPEGGRAY) &&
-      (iColortype == MNG_COLORTYPE_JPEGGRAY))
-  {
-    if (pBuf->iBitdepth <= 8)          /* source <= 8 bits */
-    {
-#ifndef MNG_NO_16BIT_SUPPORT
-      if (iBitdepth == 16)
-        pData->fPromoterow = (mng_fptr)mng_promote_g8_g16;
-      else
-#endif
-        pData->fPromoterow = (mng_fptr)mng_promote_g8_g8;
-    }
-
-    iNewsamplesize = 1;
-
-#ifndef MNG_NO_16BIT_SUPPORT
-    if (iBitdepth == 16)               /* 16-bit wide ? */
-      iNewsamplesize = 2;
-#endif
-  }
-  else                                 /* JPEG g -> ga */
-  if ((pBuf->iColortype == MNG_COLORTYPE_JPEGGRAY) &&
-      (iColortype == MNG_COLORTYPE_JPEGGRAYA))
-  {
-    if (pBuf->iBitdepth <= 8)          /* source <= 8 bits */
-    {
-#ifndef MNG_NO_16BIT_SUPPORT
-      if (iBitdepth == 16)
-        pData->fPromoterow = (mng_fptr)mng_promote_g8_ga16;
-      else
-#endif
-        pData->fPromoterow = (mng_fptr)mng_promote_g8_ga8;
-    }
-#ifndef MNG_NO_16BIT_SUPPORT
-    else                               /* source = 16 bits */
-      pData->fPromoterow = (mng_fptr)mng_promote_g16_ga16;
-#endif
-
-    iNewsamplesize = 2;
-
-#ifndef MNG_NO_16BIT_SUPPORT
-    if (iBitdepth == 16)               /* 16-bit wide ? */
-      iNewsamplesize = 4;
-#endif
-  }
-  else                                 /* JPEG g -> rgb */
-  if ((pBuf->iColortype == MNG_COLORTYPE_JPEGGRAY) &&
-      (iColortype == MNG_COLORTYPE_JPEGCOLOR))
-  {
-    if (pBuf->iBitdepth <= 8)          /* source <= 8 bits */
-    {
-#ifndef MNG_NO_16BIT_SUPPORT
-      if (iBitdepth == 16)
-        pData->fPromoterow = (mng_fptr)mng_promote_g8_rgb16;
-      else
-#endif
-        pData->fPromoterow = (mng_fptr)mng_promote_g8_rgb8;
-    }
-#ifndef MNG_NO_16BIT_SUPPORT
-    else                               /* source = 16 bits */
-      pData->fPromoterow = (mng_fptr)mng_promote_g16_rgb16;
-#endif
-
-    iNewsamplesize = 3;
-
-#ifndef MNG_NO_16BIT_SUPPORT
-    if (iBitdepth == 16)               /* 16-bit wide ? */
-      iNewsamplesize = 6;
-#endif
-  }
-  else                                 /* JPEG g -> rgba */
-  if ((pBuf->iColortype == MNG_COLORTYPE_JPEGGRAY) &&
-      (iColortype == MNG_COLORTYPE_JPEGCOLORA))
-  {
-    if (pBuf->iBitdepth <= 8)          /* source <= 8 bits */
-    {
-#ifndef MNG_NO_16BIT_SUPPORT
-      if (iBitdepth == 16)
-        pData->fPromoterow = (mng_fptr)mng_promote_g8_rgba16;
-      else
-#endif
-        pData->fPromoterow = (mng_fptr)mng_promote_g8_rgba8;
-    }
-#ifndef MNG_NO_16BIT_SUPPORT
-    else                               /* source = 16 bits */
-      pData->fPromoterow = (mng_fptr)mng_promote_g16_rgba16;
-#endif
-
-    iNewsamplesize = 4;
-
-#ifndef MNG_NO_16BIT_SUPPORT
-    if (iBitdepth == 16)               /* 16-bit wide ? */
-      iNewsamplesize = 8;
-#endif
-  }
-  else                                 /* JPEG ga -> ga */
-  if ((pBuf->iColortype == MNG_COLORTYPE_JPEGGRAYA) &&
-      (iColortype == MNG_COLORTYPE_JPEGGRAYA))
-  {
-    iNewsamplesize = 2;
-#ifndef MNG_NO_16BIT_SUPPORT
-    if (pBuf->iBitdepth <= 8)          /* source <= 8 bits */
-      if (iBitdepth == 16)
-        pData->fPromoterow = (mng_fptr)mng_promote_ga8_ga16;
-    if (iBitdepth == 16)
-      iNewsamplesize = 4;
-#endif
-
-  }
-  else                                 /* JPEG ga -> rgba */
-  if ((pBuf->iColortype == MNG_COLORTYPE_JPEGGRAYA) &&
-      (iColortype == MNG_COLORTYPE_JPEGCOLORA))
-  {
-    if (pBuf->iBitdepth <= 8)          /* source <= 8 bits */
-    {
-#ifndef MNG_NO_16BIT_SUPPORT
-      if (iBitdepth == 16)
-        pData->fPromoterow = (mng_fptr)mng_promote_ga8_rgba16;
-      else
-#endif
-        pData->fPromoterow = (mng_fptr)mng_promote_ga8_rgba8;
-    }
-#ifndef MNG_NO_16BIT_SUPPORT
-    else                               /* source = 16 bits */
-      pData->fPromoterow = (mng_fptr)mng_promote_ga16_rgba16;
-#endif
-
-    iNewsamplesize = 4;
-
-#ifndef MNG_NO_16BIT_SUPPORT
-    if (iBitdepth == 16)               /* 16-bit wide ? */
-      iNewsamplesize = 8;
-#endif
-  }
-  else                                 /* JPEG rgb -> rgb */
-  if ((pBuf->iColortype == MNG_COLORTYPE_JPEGCOLOR) &&
-      (iColortype == MNG_COLORTYPE_JPEGCOLOR))
-  {
-    iNewsamplesize = 3;
-#ifndef MNG_NO_16BIT_SUPPORT
-    if (pBuf->iBitdepth <= 8)          /* source <= 8 bits */
-      if (iBitdepth == 16)
-        pData->fPromoterow = (mng_fptr)mng_promote_rgb8_rgb16;
-    if (iBitdepth == 16)
-      iNewsamplesize = 6;
-#endif
-
-  }
-  else                                 /* JPEG rgb -> rgba */
-  if ((pBuf->iColortype == MNG_COLORTYPE_JPEGCOLOR) &&
-      (iColortype == MNG_COLORTYPE_JPEGCOLORA))
-  {
-    if (pBuf->iBitdepth <= 8)          /* source <= 8 bits */
-    {
-#ifndef MNG_NO_16BIT_SUPPORT
-      if (iBitdepth == 16)
-        pData->fPromoterow = (mng_fptr)mng_promote_rgb8_rgba16;
-      else
-#endif
-        pData->fPromoterow = (mng_fptr)mng_promote_rgb8_rgba8;
-    }
-#ifndef MNG_NO_16BIT_SUPPORT
-    else                               /* source = 16 bits */
-      pData->fPromoterow = (mng_fptr)mng_promote_rgb16_rgba16;
-#endif
-
-    iNewsamplesize = 4;
-
-#ifndef MNG_NO_16BIT_SUPPORT
-    if (iBitdepth == 16)               /* 16-bit wide ? */
-      iNewsamplesize = 8;
-#endif
-  }
-  else                                 /* JPEG rgba -> rgba */
-  if ((pBuf->iColortype == MNG_COLORTYPE_JPEGCOLORA) &&
-      (iColortype == MNG_COLORTYPE_JPEGCOLORA))
-  {
-    iNewsamplesize = 4;
-#ifndef MNG_NO_16BIT_SUPPORT
-    if (pBuf->iBitdepth <= 8)          /* source <= 8 bits */
-      if (iBitdepth == 16)
-        pData->fPromoterow = (mng_fptr)mng_promote_rgba8_rgba16;
-    if (iBitdepth == 16)
-      iNewsamplesize = 8;
-#endif
-  }
-#endif /* JNG */
-
-  /* found a proper promotion ? */
-  if (pData->fPromoterow)
-  {
-    pData->pPromBuf    = (mng_ptr)pBuf;
-    pData->iPromWidth  = pBuf->iWidth;
-    iNewrowsize        = iW * iNewsamplesize;
-    iNewbufsize        = iH * iNewrowsize;
-
-    MNG_ALLOC (pData, pNewbuf, iNewbufsize);
-
-    pData->pPromSrc    = (mng_ptr)pBuf->pImgdata;
-    pData->pPromDst    = (mng_ptr)pNewbuf;
-    iY                 = 0;
-
-    while ((!iRetcode) && (iY < iH))
-    {
-      iRetcode         = ((mng_promoterow)pData->fPromoterow) (pData);
-      pData->pPromSrc  = (mng_uint8p)pData->pPromSrc + pBuf->iRowsize;
-      pData->pPromDst  = (mng_uint8p)pData->pPromDst + iNewrowsize;
-/*      pData->pPromSrc  = (mng_ptr)((mng_uint32)pData->pPromSrc + pBuf->iRowsize); */
-/*      pData->pPromDst  = (mng_ptr)((mng_uint32)pData->pPromDst + iNewrowsize); */
-      iY++;
-    }
-
-    MNG_FREEX (pData, pBuf->pImgdata, pBuf->iImgdatasize);
-
-    pBuf->iBitdepth    = iBitdepth;
-    pBuf->iColortype   = iColortype;
-    pBuf->iSamplesize  = iNewsamplesize;
-    pBuf->iRowsize     = iNewrowsize;
-    pBuf->iImgdatasize = iNewbufsize;
-    pBuf->pImgdata     = pNewbuf;
-    pBuf->bHasPLTE     = MNG_FALSE;
-    pBuf->iPLTEcount   = 0;
-    pBuf->bHasTRNS     = MNG_FALSE;
-    pBuf->iTRNScount   = 0;
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_IMGOBJECT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_MAGN
-mng_retcode mng_magnify_imageobject (mng_datap  pData,
-                                     mng_imagep pImage)
-{
-  mng_uint8p     pNewdata;
-  mng_uint8p     pSrcline1;
-  mng_uint8p     pSrcline2;
-  mng_uint8p     pTempline;
-  mng_uint8p     pDstline;
-  mng_uint32     iNewrowsize;
-  mng_uint32     iNewsize;
-  mng_uint32     iY;
-  mng_int32      iS, iM;
-  mng_retcode    iRetcode;
-
-  mng_imagedatap pBuf      = pImage->pImgbuf;
-  mng_uint32     iNewW     = pBuf->iWidth;
-  mng_uint32     iNewH     = pBuf->iHeight;
-  mng_magnify_x  fMagnifyX = MNG_NULL;
-  mng_magnify_y  fMagnifyY = MNG_NULL;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_IMGOBJECT, MNG_LC_START);
-#endif
-
-  if (pBuf->iColortype == MNG_COLORTYPE_INDEXED)           /* indexed color ? */
-  {                                    /* concrete buffer ? */
-    if ((pBuf->bConcrete) && (pImage->iId))
-      MNG_ERROR (pData, MNG_INVALIDCOLORTYPE);
-
-#ifndef MNG_OPTIMIZE_FOOTPRINT_MAGN
-    if (pBuf->iTRNScount)              /* with transparency ? */
-      iRetcode = mng_promote_imageobject (pData, pImage, 8, 6, 0);
-    else
-      iRetcode = mng_promote_imageobject (pData, pImage, 8, 2, 0);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-#endif
-  }
-
-#ifdef MNG_OPTIMIZE_FOOTPRINT_MAGN
-  /* Promote everything to RGBA, using fill method 0 (LBR) */
-  iRetcode = mng_promote_imageobject (pData, pImage, 8, 6, 0);           
-  if (iRetcode)                      /* on error bail out */
-    return iRetcode;
-#endif
-
-  if (pImage->iMAGN_MethodX)           /* determine new width */
-  {
-    if (pImage->iMAGN_MethodX == 1)
-    {
-      iNewW   = pImage->iMAGN_ML;
-      if (pBuf->iWidth  > 1)
-        iNewW = iNewW + pImage->iMAGN_MR;
-      if (pBuf->iWidth  > 2)
-        iNewW = iNewW + (pBuf->iWidth  - 2) * (pImage->iMAGN_MX);
-    }
-    else
-    {
-      iNewW   = pBuf->iWidth  + pImage->iMAGN_ML - 1;
-      if (pBuf->iWidth  > 2)
-        iNewW = iNewW + pImage->iMAGN_MR - 1;
-      if (pBuf->iWidth  > 3)
-        iNewW = iNewW + (pBuf->iWidth  - 3) * (pImage->iMAGN_MX - 1);
-    }
-  }
-
-  if (pImage->iMAGN_MethodY)           /* determine new height */
-  {
-    if (pImage->iMAGN_MethodY == 1)
-    {
-      iNewH   = pImage->iMAGN_MT;
-      if (pBuf->iHeight > 1)
-        iNewH = iNewH + pImage->iMAGN_ML;
-      if (pBuf->iHeight > 2)
-        iNewH = iNewH + (pBuf->iHeight - 2) * (pImage->iMAGN_MY);
-    }
-    else
-    {
-      iNewH   = pBuf->iHeight + pImage->iMAGN_MT - 1;
-      if (pBuf->iHeight > 2)
-        iNewH = iNewH + pImage->iMAGN_MB - 1;
-      if (pBuf->iHeight > 3)
-        iNewH = iNewH + (pBuf->iHeight - 3) * (pImage->iMAGN_MY - 1);
-    }
-  }
-                                       /* get new buffer */
-  iNewrowsize  = iNewW * pBuf->iSamplesize;
-  iNewsize     = iNewH * iNewrowsize;
-
-  MNG_ALLOC (pData, pNewdata, iNewsize);
-
-  switch (pBuf->iColortype)            /* determine magnification routines */
-  {
-#ifndef MNG_OPTIMIZE_FOOTPRINT_MAGN
-    case  0 : ;
-    case  8 : {
-                if (pBuf->iBitdepth <= 8)
-                {
-                  switch (pImage->iMAGN_MethodX)
-                  {
-                    case 1  : { fMagnifyX = mng_magnify_g8_x1; break; }
-                    case 2  : { fMagnifyX = mng_magnify_g8_x2; break; }
-                    case 3  : { fMagnifyX = mng_magnify_g8_x3; break; }
-                    case 4  : { fMagnifyX = mng_magnify_g8_x2; break; }
-                    case 5  : { fMagnifyX = mng_magnify_g8_x3; break; }
-                  }
-
-                  switch (pImage->iMAGN_MethodY)
-                  {
-                    case 1  : { fMagnifyY = mng_magnify_g8_y1; break; }
-                    case 2  : { fMagnifyY = mng_magnify_g8_y2; break; }
-                    case 3  : { fMagnifyY = mng_magnify_g8_y3; break; }
-                    case 4  : { fMagnifyY = mng_magnify_g8_y2; break; }
-                    case 5  : { fMagnifyY = mng_magnify_g8_y3; break; }
-                  }
-                }
-#ifndef MNG_NO_16BIT_SUPPORT
-                else
-                {
-                  switch (pImage->iMAGN_MethodX)
-                  {
-                    case 1  : { fMagnifyX = mng_magnify_g16_x1; break; }
-                    case 2  : { fMagnifyX = mng_magnify_g16_x2; break; }
-                    case 3  : { fMagnifyX = mng_magnify_g16_x3; break; }
-                    case 4  : { fMagnifyX = mng_magnify_g16_x2; break; }
-                    case 5  : { fMagnifyX = mng_magnify_g16_x3; break; }
-                  }
-
-                  switch (pImage->iMAGN_MethodY)
-                  {
-                    case 1  : { fMagnifyY = mng_magnify_g16_y1; break; }
-                    case 2  : { fMagnifyY = mng_magnify_g16_y2; break; }
-                    case 3  : { fMagnifyY = mng_magnify_g16_y3; break; }
-                    case 4  : { fMagnifyY = mng_magnify_g16_y2; break; }
-                    case 5  : { fMagnifyY = mng_magnify_g16_y3; break; }
-                  }
-                }
-#endif
-
-                break;
-              }
-
-    case  2 : ;
-    case 10 : {
-                if (pBuf->iBitdepth <= 8)
-                {
-                  switch (pImage->iMAGN_MethodX)
-                  {
-                    case 1  : { fMagnifyX = mng_magnify_rgb8_x1; break; }
-                    case 2  : { fMagnifyX = mng_magnify_rgb8_x2; break; }
-                    case 3  : { fMagnifyX = mng_magnify_rgb8_x3; break; }
-                    case 4  : { fMagnifyX = mng_magnify_rgb8_x2; break; }
-                    case 5  : { fMagnifyX = mng_magnify_rgb8_x3; break; }
-                  }
-
-                  switch (pImage->iMAGN_MethodY)
-                  {
-                    case 1  : { fMagnifyY = mng_magnify_rgb8_y1; break; }
-                    case 2  : { fMagnifyY = mng_magnify_rgb8_y2; break; }
-                    case 3  : { fMagnifyY = mng_magnify_rgb8_y3; break; }
-                    case 4  : { fMagnifyY = mng_magnify_rgb8_y2; break; }
-                    case 5  : { fMagnifyY = mng_magnify_rgb8_y3; break; }
-                  }
-                }
-#ifndef MNG_NO_16BIT_SUPPORT
-                else
-                {
-                  switch (pImage->iMAGN_MethodX)
-                  {
-                    case 1  : { fMagnifyX = mng_magnify_rgb16_x1; break; }
-                    case 2  : { fMagnifyX = mng_magnify_rgb16_x2; break; }
-                    case 3  : { fMagnifyX = mng_magnify_rgb16_x3; break; }
-                    case 4  : { fMagnifyX = mng_magnify_rgb16_x2; break; }
-                    case 5  : { fMagnifyX = mng_magnify_rgb16_x3; break; }
-                  }
-
-                  switch (pImage->iMAGN_MethodY)
-                  {
-                    case 1  : { fMagnifyY = mng_magnify_rgb16_y1; break; }
-                    case 2  : { fMagnifyY = mng_magnify_rgb16_y2; break; }
-                    case 3  : { fMagnifyY = mng_magnify_rgb16_y3; break; }
-                    case 4  : { fMagnifyY = mng_magnify_rgb16_y2; break; }
-                    case 5  : { fMagnifyY = mng_magnify_rgb16_y3; break; }
-                  }
-                }
-#endif
-
-                break;
-              }
-
-    case  4 : ;
-    case 12 : {
-                if (pBuf->iBitdepth <= 8)
-                {
-                  switch (pImage->iMAGN_MethodX)
-                  {
-                    case 1  : { fMagnifyX = mng_magnify_ga8_x1; break; }
-                    case 2  : { fMagnifyX = mng_magnify_ga8_x2; break; }
-                    case 3  : { fMagnifyX = mng_magnify_ga8_x3; break; }
-                    case 4  : { fMagnifyX = mng_magnify_ga8_x4; break; }
-                    case 5  : { fMagnifyX = mng_magnify_ga8_x5; break; }
-                  }
-
-                  switch (pImage->iMAGN_MethodY)
-                  {
-                    case 1  : { fMagnifyY = mng_magnify_ga8_y1; break; }
-                    case 2  : { fMagnifyY = mng_magnify_ga8_y2; break; }
-                    case 3  : { fMagnifyY = mng_magnify_ga8_y3; break; }
-                    case 4  : { fMagnifyY = mng_magnify_ga8_y4; break; }
-                    case 5  : { fMagnifyY = mng_magnify_ga8_y5; break; }
-                  }
-                }
-#ifndef MNG_NO_16BIT_SUPPORT
-                else
-                {
-                  switch (pImage->iMAGN_MethodX)
-                  {
-                    case 1  : { fMagnifyX = mng_magnify_ga16_x1; break; }
-                    case 2  : { fMagnifyX = mng_magnify_ga16_x2; break; }
-                    case 3  : { fMagnifyX = mng_magnify_ga16_x3; break; }
-                    case 4  : { fMagnifyX = mng_magnify_ga16_x4; break; }
-                    case 5  : { fMagnifyX = mng_magnify_ga16_x5; break; }
-                  }
-
-                  switch (pImage->iMAGN_MethodY)
-                  {
-                    case 1  : { fMagnifyY = mng_magnify_ga16_y1; break; }
-                    case 2  : { fMagnifyY = mng_magnify_ga16_y2; break; }
-                    case 3  : { fMagnifyY = mng_magnify_ga16_y3; break; }
-                    case 4  : { fMagnifyY = mng_magnify_ga16_y4; break; }
-                    case 5  : { fMagnifyY = mng_magnify_ga16_y5; break; }
-                  }
-                }
-#endif
-
-                break;
-              }
-#endif
-
-    case  6 : ;
-    case 14 : {
-                if (pBuf->iBitdepth <= 8)
-                {
-                  switch (pImage->iMAGN_MethodX)
-                  {
-                    case 1  : { fMagnifyX = mng_magnify_rgba8_x1; break; }
-                    case 2  : { fMagnifyX = mng_magnify_rgba8_x2; break; }
-                    case 3  : { fMagnifyX = mng_magnify_rgba8_x3; break; }
-                    case 4  : { fMagnifyX = mng_magnify_rgba8_x4; break; }
-                    case 5  : { fMagnifyX = mng_magnify_rgba8_x5; break; }
-                  }
-
-                  switch (pImage->iMAGN_MethodY)
-                  {
-                    case 1  : { fMagnifyY = mng_magnify_rgba8_y1; break; }
-                    case 2  : { fMagnifyY = mng_magnify_rgba8_y2; break; }
-                    case 3  : { fMagnifyY = mng_magnify_rgba8_y3; break; }
-                    case 4  : { fMagnifyY = mng_magnify_rgba8_y4; break; }
-                    case 5  : { fMagnifyY = mng_magnify_rgba8_y5; break; }
-                  }
-                }
-#ifndef MNG_NO_16BIT_SUPPORT
-#ifndef MNG_OPTIMIZE_FOOTPRINT_MAGN
-                else
-                {
-                  switch (pImage->iMAGN_MethodX)
-                  {
-                    case 1  : { fMagnifyX = mng_magnify_rgba16_x1; break; }
-                    case 2  : { fMagnifyX = mng_magnify_rgba16_x2; break; }
-                    case 3  : { fMagnifyX = mng_magnify_rgba16_x3; break; }
-                    case 4  : { fMagnifyX = mng_magnify_rgba16_x4; break; }
-                    case 5  : { fMagnifyX = mng_magnify_rgba16_x5; break; }
-                  }
-
-                  switch (pImage->iMAGN_MethodY)
-                  {
-                    case 1  : { fMagnifyY = mng_magnify_rgba16_y1; break; }
-                    case 2  : { fMagnifyY = mng_magnify_rgba16_y2; break; }
-                    case 3  : { fMagnifyY = mng_magnify_rgba16_y3; break; }
-                    case 4  : { fMagnifyY = mng_magnify_rgba16_y4; break; }
-                    case 5  : { fMagnifyY = mng_magnify_rgba16_y5; break; }
-                  }
-                }
-#endif
-#endif
-                break;
-              }
-  }
-
-  pSrcline1 = pBuf->pImgdata;          /* initialize row-loop variables */
-  pDstline  = pNewdata;
-                                       /* allocate temporary row */
-  MNG_ALLOC (pData, pTempline, iNewrowsize);
-
-  for (iY = 0; iY < pBuf->iHeight; iY++)
-  {
-    pSrcline2 = pSrcline1 + pBuf->iRowsize;
-
-    if (fMagnifyX)                     /* magnifying in X-direction ? */
-    {
-      iRetcode = fMagnifyX (pData, pImage->iMAGN_MX,
-                            pImage->iMAGN_ML, pImage->iMAGN_MR,
-                            pBuf->iWidth, pSrcline1, pDstline);
-
-      if (iRetcode)                    /* on error bail out */
-      {
-        MNG_FREEX (pData, pTempline, iNewrowsize);
-        MNG_FREEX (pData, pNewdata,  iNewsize);
-        return iRetcode;
-      }
-    }
-    else
-    {
-      MNG_COPY (pDstline, pSrcline1, iNewrowsize);
-    }
-
-    pDstline += iNewrowsize;
-                                       /* magnifying in Y-direction ? */
-    if ((fMagnifyY) &&
-        ((iY < pBuf->iHeight - 1) || (pBuf->iHeight == 1) || (pImage->iMAGN_MethodY == 1)))
-    {
-      if (iY == 0)                     /* first interval ? */
-      {
-        if (pBuf->iHeight == 1)        /* single row ? */
-          pSrcline2 = MNG_NULL;
-
-        iM = (mng_int32)pImage->iMAGN_MT;
-      }
-      else                             /* last interval ? */
-      if (((pImage->iMAGN_MethodY == 1) && (iY == (pBuf->iHeight - 1))) ||
-          ((pImage->iMAGN_MethodY != 1) && (iY == (pBuf->iHeight - 2)))    )
-        iM = (mng_int32)pImage->iMAGN_MB;
-      else                             /* middle interval */
-        iM = (mng_int32)pImage->iMAGN_MY;
-
-      for (iS = 1; iS < iM; iS++)
-      {
-        iRetcode = fMagnifyY (pData, iS, iM, pBuf->iWidth,
-                              pSrcline1, pSrcline2, pTempline);
-
-        if (iRetcode)                  /* on error bail out */
-        {
-          MNG_FREEX (pData, pTempline, iNewrowsize);
-          MNG_FREEX (pData, pNewdata,  iNewsize);
-          return iRetcode;
-        }
-
-        if (fMagnifyX)                   /* magnifying in X-direction ? */
-        {
-          iRetcode = fMagnifyX (pData, pImage->iMAGN_MX,
-                                pImage->iMAGN_ML, pImage->iMAGN_MR,
-                                pBuf->iWidth, pTempline, pDstline);
-
-          if (iRetcode)                  /* on error bail out */
-          {
-            MNG_FREEX (pData, pTempline, iNewrowsize);
-            MNG_FREEX (pData, pNewdata,  iNewsize);
-            return iRetcode;
-          }
-        }
-        else
-        {
-          MNG_COPY (pDstline, pTempline, iNewrowsize);
-        }
-
-        pDstline  += iNewrowsize;
-      }
-    }
-
-    pSrcline1 += pBuf->iRowsize;
-  }
-                                       /* drop temporary row */
-  MNG_FREEX (pData, pTempline, iNewrowsize);
-                                       /* drop old pixel-data */
-  MNG_FREEX (pData, pBuf->pImgdata, pBuf->iImgdatasize);
-
-  pBuf->pImgdata     = pNewdata;       /* save new buffer dimensions */
-  pBuf->iRowsize     = iNewrowsize;
-  pBuf->iImgdatasize = iNewsize;
-  pBuf->iWidth       = iNewW;
-  pBuf->iHeight      = iNewH;
-
-  if (pImage->iId)                     /* real object ? */
-  {
-    pImage->iMAGN_MethodX = 0;         /* it's done; don't do it again !!! */
-    pImage->iMAGN_MethodY = 0;
-    pImage->iMAGN_MX      = 0;
-    pImage->iMAGN_MY      = 0;
-    pImage->iMAGN_ML      = 0;
-    pImage->iMAGN_MR      = 0;
-    pImage->iMAGN_MT      = 0;
-    pImage->iMAGN_MB      = 0;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_IMGOBJECT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_colorcorrect_object (mng_datap  pData,
-                                     mng_imagep pImage)
-{
-  mng_imagedatap pBuf = pImage->pImgbuf;
-  mng_retcode    iRetcode;
-  mng_uint32     iY;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_COLORCORRECT_OBJECT, MNG_LC_START);
-#endif
-
-#ifdef MNG_INCLUDE_JNG
-  if ((pBuf->iBitdepth < 8) ||         /* we need 8- or 16-bit RGBA !!! */
-      ((pBuf->iColortype != MNG_COLORTYPE_RGBA      ) &&
-       (pBuf->iColortype != MNG_COLORTYPE_JPEGCOLORA)    ))
-#else
-  if (pBuf->iBitdepth < 8)         /* we need 8- or 16-bit RGBA !!! */
-#endif
-    MNG_ERROR (pData, MNG_OBJNOTABSTRACT);
-
-  if (!pBuf->bCorrected)               /* only if not already done ! */
-  {                                    /* so the row routines now to find it */
-    pData->pRetrieveobj   = (mng_objectp)pImage;
-    pData->pStoreobj      = (mng_objectp)pImage;
-    pData->pStorebuf      = (mng_objectp)pImage->pImgbuf;
-
-#ifndef MNG_NO_16BIT_SUPPORT
-    if (pBuf->iBitdepth > 8)
-    {
-      pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba16;
-      pData->fStorerow    = (mng_fptr)mng_store_rgba16;
-    }
-    else
-#endif
-    {
-      pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba8;
-      pData->fStorerow    = (mng_fptr)mng_store_rgba8;
-    }
-
-    pData->bIsOpaque      = MNG_FALSE;
-
-    pData->iPass          = -1;        /* these are the object's dimensions now */
-    pData->iRow           = 0;
-    pData->iRowinc        = 1;
-    pData->iCol           = 0;
-    pData->iColinc        = 1;
-    pData->iRowsamples    = pBuf->iWidth;
-    pData->iRowsize       = pData->iRowsamples << 2;
-    pData->iPixelofs      = 0;
-    pData->bIsRGBA16      = MNG_FALSE;
-                                       /* adjust for 16-bit object ? */
-#ifndef MNG_NO_16BIT_SUPPORT
-    if (pBuf->iBitdepth > 8)
-    {
-      pData->bIsRGBA16    = MNG_TRUE;
-      pData->iRowsize     = pData->iRowsamples << 3;
-    }
-#endif
-
-    pData->fCorrectrow    = MNG_NULL;  /* default no color-correction */
-
-#ifdef MNG_NO_CMS
-    iRetcode = MNG_NOERROR;
-#else
-#if defined(MNG_FULL_CMS)              /* determine color-management routine */
-    iRetcode = mng_init_full_cms   (pData, MNG_FALSE, MNG_FALSE, MNG_TRUE);
-#elif defined(MNG_GAMMA_ONLY)
-    iRetcode = mng_init_gamma_only (pData, MNG_FALSE, MNG_FALSE, MNG_TRUE);
-#elif defined(MNG_APP_CMS)
-    iRetcode = mng_init_app_cms    (pData, MNG_FALSE, MNG_FALSE, MNG_TRUE);
-#endif
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-#endif /* MNG_NO_CMS */
-
-    if (pData->fCorrectrow)            /* really correct something ? */
-    {                                  /* get a temporary row-buffer */
-      MNG_ALLOC (pData, pData->pRGBArow, pData->iRowsize);
-
-      pData->pWorkrow = pData->pRGBArow;
-      iY              = 0;             /* start from the top */
-
-      while ((!iRetcode) && (iY < pBuf->iHeight))
-      {                                /* get a row */
-        iRetcode = ((mng_retrieverow)pData->fRetrieverow) (pData);
-
-        if (!iRetcode)                 /* color correct it */
-          iRetcode = ((mng_correctrow)pData->fCorrectrow) (pData);
-
-        if (!iRetcode)                 /* store it back ! */
-          iRetcode = ((mng_storerow)pData->fStorerow) (pData);
-
-        if (!iRetcode)                 /* adjust variables for next row */
-          iRetcode = mng_next_row (pData);
-
-        iY++;                          /* and next line */
-      }
-                                       /* drop the temporary row-buffer */
-      MNG_FREEX (pData, pData->pRGBArow, pData->iRowsize);
-
-      if (iRetcode)                    /* on error bail out */
-        return iRetcode;
-
-#if defined(MNG_FULL_CMS)              /* cleanup cms stuff */
-      iRetcode = mng_clear_cms (pData);
-
-      if (iRetcode)                    /* on error bail out */
-        return iRetcode;
-#endif
-    }
-
-    pBuf->bCorrected = MNG_TRUE;       /* let's not go through that again ! */
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_COLORCORRECT_OBJECT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Animation-object routines                                              * */
-/* *                                                                        * */
-/* * these handle the animation objects used to re-run parts of a MNG.      * */
-/* * eg. during LOOP or TERM processing                                     * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-void mng_add_ani_object (mng_datap          pData,
-                         mng_object_headerp pObject)
-{
-  mng_object_headerp pLast = (mng_object_headerp)pData->pLastaniobj;
-
-  if (pLast)                           /* link it as last in the chain */
-  {
-    pObject->pPrev      = pLast;
-    pLast->pNext        = pObject;
-  }
-  else
-  {
-    pObject->pPrev      = MNG_NULL;    /* be on the safe side */
-    pData->pFirstaniobj = pObject;
-  }
-
-  pObject->pNext        = MNG_NULL;    /* be on the safe side */
-  pData->pLastaniobj    = pObject;
-                                       /* keep track for jumping */
-  pObject->iFramenr     = pData->iFrameseq;
-  pObject->iLayernr     = pData->iLayerseq;
-  pObject->iPlaytime    = pData->iFrametime;
-                                       /* save restart object ? */
-  if ((pData->bDisplaying) && (!pData->bRunning) && (!pData->pCurraniobj))
-    pData->pCurraniobj  = pObject;
-
-  return;
-}
-
-/* ************************************************************************** */
-/* ************************************************************************** */
-
-mng_retcode mng_create_ani_image (mng_datap pData)
-{
-  mng_ani_imagep pImage;
-  mng_imagep     pCurrent;
-  mng_retcode    iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_IMAGE, MNG_LC_START);
-#endif
-
-  if (pData->bCacheplayback)           /* caching playback info ? */
-  {
-#ifndef MNG_NO_DELTA_PNG
-    if (pData->bHasDHDR)               /* processing delta-image ? */
-      pCurrent = (mng_imagep)pData->pObjzero;
-    else                               /* get the current object */
-#endif
-      pCurrent = (mng_imagep)pData->pCurrentobj;
-
-    if (!pCurrent)                     /* otherwise object 0 */
-      pCurrent = (mng_imagep)pData->pObjzero;
-                                       /* now just clone the object !!! */
-    iRetcode  = mng_clone_imageobject (pData, 0, MNG_FALSE, pCurrent->bVisible,
-                                       MNG_FALSE, MNG_FALSE, 0, 0, 0, pCurrent,
-                                       &pImage);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-
-    pImage->sHeader.fCleanup = mng_free_ani_image;
-    pImage->sHeader.fProcess = mng_process_ani_image;
-
-    mng_add_ani_object (pData, (mng_object_headerp)pImage);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_IMAGE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* okido */
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_free_ani_image (mng_datap   pData,
-                                mng_objectp pObject)
-{
-  mng_ani_imagep pImage = (mng_ani_imagep)pObject;
-  mng_imagedatap pImgbuf = pImage->pImgbuf;
-  mng_retcode    iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_IMAGE, MNG_LC_START);
-#endif
-                                       /* unlink the image-data buffer */
-  iRetcode = mng_free_imagedataobject (pData, pImgbuf);
-                                       /* drop its own buffer */
-  MNG_FREEX (pData, pImage, sizeof (mng_ani_image));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_IMAGE, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_ani_image (mng_datap   pData,
-                                   mng_objectp pObject)
-{
-  mng_retcode    iRetcode = MNG_NOERROR;
-  mng_ani_imagep pImage   = (mng_imagep)pObject;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_IMAGE, MNG_LC_START);
-#endif
-
-#ifndef MNG_NO_DELTA_PNG
-  if (pData->bHasDHDR)                 /* processing delta-image ? */
-  {
-    mng_imagep pDelta = (mng_imagep)pData->pDeltaImage;
-
-    if (!pData->iBreakpoint)           /* only execute if not broken before */
-    {                                  /* make sure to process pixels as well */
-      pData->bDeltaimmediate = MNG_FALSE;
-                                       /* execute the delta process */
-      iRetcode = mng_execute_delta_image (pData, pDelta, (mng_imagep)pObject);
-
-      if (iRetcode)                    /* on error bail out */
-        return iRetcode;
-    }
-                                       /* now go and shoot it off (if required) */
-    if ((pDelta->bVisible) && (pDelta->bViewable))
-      iRetcode = mng_display_image (pData, pDelta, MNG_FALSE);
-
-    if (!pData->bTimerset)
-      pData->bHasDHDR = MNG_FALSE;     /* this image signifies IEND !! */
-
-  }
-  else
-#endif
-  if (pData->pCurrentobj)              /* active object ? */
-  {
-    mng_imagep     pCurrent = (mng_imagep)pData->pCurrentobj;
-    mng_imagedatap pBuf     = pCurrent->pImgbuf;
-
-    if (!pData->iBreakpoint)           /* don't copy it again ! */
-    {
-      if (pBuf->iImgdatasize)          /* buffer present in active object ? */
-                                       /* then drop it */
-        MNG_FREE (pData, pBuf->pImgdata, pBuf->iImgdatasize);
-
-#ifndef MNG_SKIPCHUNK_iCCP
-      if (pBuf->iProfilesize)          /* iCCP profile present ? */
-                                       /* then drop it */
-        MNG_FREE (pData, pBuf->pProfile, pBuf->iProfilesize);
-#endif
-                                       /* now blatently copy the animation buffer */
-      MNG_COPY (pBuf, pImage->pImgbuf, sizeof (mng_imagedata));
-                                       /* copy viewability */
-      pCurrent->bViewable = pImage->bViewable;
-
-      if (pBuf->iImgdatasize)          /* sample buffer present ? */
-      {                                /* then make a copy */
-        MNG_ALLOC (pData, pBuf->pImgdata, pBuf->iImgdatasize);
-        MNG_COPY (pBuf->pImgdata, pImage->pImgbuf->pImgdata, pBuf->iImgdatasize);
-      }
-
-#ifndef MNG_SKIPCHUNK_iCCP
-      if (pBuf->iProfilesize)          /* iCCP profile present ? */
-      {                                /* then make a copy */
-        MNG_ALLOC (pData, pBuf->pProfile, pBuf->iProfilesize);
-        MNG_COPY (pBuf->pProfile, pImage->pImgbuf->pProfile, pBuf->iProfilesize);
-      }
-#endif
-    }
-                                       /* now go and shoot it off (if required) */
-    if ((pCurrent->bVisible) && (pCurrent->bViewable))
-      iRetcode = mng_display_image (pData, pCurrent, MNG_FALSE);
-  }
-  else
-  {
-    mng_imagep     pObjzero = (mng_imagep)pData->pObjzero;
-    mng_imagedatap pBuf     = pObjzero->pImgbuf;
-
-    if (!pData->iBreakpoint)           /* don't copy it again ! */
-    {
-      if (pBuf->iImgdatasize)          /* buffer present in active object ? */
-                                       /* then drop it */
-        MNG_FREE (pData, pBuf->pImgdata, pBuf->iImgdatasize);
-
-#ifndef MNG_SKIPCHUNK_iCCP
-      if (pBuf->iProfilesize)          /* iCCP profile present ? */
-                                       /* then drop it */
-        MNG_FREE (pData, pBuf->pProfile, pBuf->iProfilesize);
-#endif
-                                       /* now blatently copy the animation buffer */
-      MNG_COPY (pBuf, pImage->pImgbuf, sizeof (mng_imagedata));
-                                       /* copy viewability */
-      pObjzero->bViewable = pImage->bViewable;
-
-      if (pBuf->iImgdatasize)          /* sample buffer present ? */
-      {                                /* then make a copy */
-        MNG_ALLOC (pData, pBuf->pImgdata, pBuf->iImgdatasize);
-        MNG_COPY (pBuf->pImgdata, pImage->pImgbuf->pImgdata, pBuf->iImgdatasize);
-      }
-
-#ifndef MNG_SKIPCHUNK_iCCP
-      if (pBuf->iProfilesize)          /* iCCP profile present ? */
-      {                                /* then make a copy */
-        MNG_ALLOC (pData, pBuf->pProfile, pBuf->iProfilesize);
-        MNG_COPY (pBuf->pProfile, pImage->pImgbuf->pProfile, pBuf->iProfilesize);
-      }
-#endif
-    }
-                                       /* now go and show it */
-    iRetcode = mng_display_image (pData, pObjzero, MNG_FALSE);
-  }
-
-  if (!iRetcode)                       /* all's well ? */
-  {
-    if (pData->bTimerset)              /* timer break ? */
-      pData->iBreakpoint = 99;         /* fictive number; no more processing needed! */
-    else
-      pData->iBreakpoint = 0;          /* else clear it */
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_IMAGE, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-
-/* ************************************************************************** */
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-mng_retcode mng_create_ani_plte (mng_datap      pData,
-                                 mng_uint32     iEntrycount,
-                                 mng_palette8ep paEntries)
-#else
-mng_retcode mng_create_ani_plte (mng_datap      pData)
-#endif
-{
-  mng_ani_pltep pPLTE;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_PLTE, MNG_LC_START);
-#endif
-
-  if (pData->bCacheplayback)           /* caching playback info ? */
-  {
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-    mng_ptr     pTemp;
-    mng_retcode iRetcode = create_obj_general (pData, sizeof (mng_ani_plte),
-                                               mng_free_obj_general,
-                                               mng_process_ani_plte,
-                                               &pTemp);
-    if (iRetcode)
-      return iRetcode;
-    pPLTE = (mng_ani_pltep)pTemp;
-#else
-    MNG_ALLOC (pData, pPLTE, sizeof (mng_ani_plte));
-
-    pPLTE->sHeader.fCleanup = mng_free_ani_plte;
-    pPLTE->sHeader.fProcess = mng_process_ani_plte;
-#endif
-
-    mng_add_ani_object (pData, (mng_object_headerp)pPLTE);
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-    pPLTE->iEntrycount = iEntrycount;
-    MNG_COPY (pPLTE->aEntries, paEntries, sizeof (pPLTE->aEntries));
-#else
-    pPLTE->iEntrycount = pData->iGlobalPLTEcount;
-    MNG_COPY (pPLTE->aEntries, pData->aGlobalPLTEentries, sizeof (pPLTE->aEntries));
-#endif
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_PLTE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_OBJCLEANUP
-mng_retcode mng_free_ani_plte (mng_datap   pData,
-                               mng_objectp pObject)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_PLTE, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pObject, sizeof (mng_ani_plte));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_PLTE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_ani_plte (mng_datap   pData,
-                                  mng_objectp pObject)
-{
-  mng_ani_pltep pPLTE = (mng_ani_pltep)pObject;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_PLTE, MNG_LC_START);
-#endif
-
-  pData->bHasglobalPLTE   = MNG_TRUE;
-  pData->iGlobalPLTEcount = pPLTE->iEntrycount;
-
-  MNG_COPY (pData->aGlobalPLTEentries, pPLTE->aEntries, sizeof (pPLTE->aEntries));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_PLTE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-mng_retcode mng_create_ani_trns (mng_datap    pData,
-                                 mng_uint32   iRawlen,
-                                 mng_uint8p   pRawdata)
-#else
-mng_retcode mng_create_ani_trns (mng_datap    pData)
-#endif
-{
-  mng_ani_trnsp pTRNS;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_TRNS, MNG_LC_START);
-#endif
-
-  if (pData->bCacheplayback)           /* caching playback info ? */
-  {
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-    mng_ptr     pTemp;
-    mng_retcode iRetcode = create_obj_general (pData, sizeof (mng_ani_trns),
-                                               mng_free_obj_general,
-                                               mng_process_ani_trns,
-                                               &pTemp);
-    if (iRetcode)
-      return iRetcode;
-    pTRNS = (mng_ani_trnsp)pTemp;
-#else
-    MNG_ALLOC (pData, pTRNS, sizeof (mng_ani_trns));
-
-    pTRNS->sHeader.fCleanup = mng_free_ani_trns;
-    pTRNS->sHeader.fProcess = mng_process_ani_trns;
-#endif
-
-    mng_add_ani_object (pData, (mng_object_headerp)pTRNS);
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-    pTRNS->iRawlen = iRawlen;
-    MNG_COPY (pTRNS->aRawdata, pRawdata, sizeof (pTRNS->aRawdata));
-#else
-    pTRNS->iRawlen = pData->iGlobalTRNSrawlen;
-    MNG_COPY (pTRNS->aRawdata, pData->aGlobalTRNSrawdata, sizeof (pTRNS->aRawdata));
-#endif
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_TRNS, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_OBJCLEANUP
-mng_retcode mng_free_ani_trns (mng_datap   pData,
-                               mng_objectp pObject)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_TRNS, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pObject, sizeof (mng_ani_trns));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_TRNS, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_ani_trns (mng_datap   pData,
-                                  mng_objectp pObject)
-{
-  mng_ani_trnsp pTRNS = (mng_ani_trnsp)pObject;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_TRNS, MNG_LC_START);
-#endif
-
-  pData->bHasglobalTRNS    = MNG_TRUE;
-  pData->iGlobalTRNSrawlen = pTRNS->iRawlen;
-
-  MNG_COPY (pData->aGlobalTRNSrawdata, pTRNS->aRawdata, sizeof (pTRNS->aRawdata));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_TRNS, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_gAMA
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-mng_retcode mng_create_ani_gama (mng_datap  pData,
-                                 mng_bool   bEmpty,
-                                 mng_uint32 iGamma)
-#else
-mng_retcode mng_create_ani_gama (mng_datap  pData,
-                                 mng_chunkp pChunk)
-#endif
-{
-  mng_ani_gamap pGAMA;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_GAMA, MNG_LC_START);
-#endif
-
-  if (pData->bCacheplayback)           /* caching playback info ? */
-  {
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-    mng_ptr     pTemp;
-    mng_retcode iRetcode = create_obj_general (pData, sizeof (mng_ani_gama),
-                                               mng_free_obj_general,
-                                               mng_process_ani_gama,
-                                               &pTemp);
-    if (iRetcode)
-      return iRetcode;
-    pGAMA = (mng_ani_gamap)pTemp;
-#else
-    MNG_ALLOC (pData, pGAMA, sizeof (mng_ani_gama));
-
-    pGAMA->sHeader.fCleanup = mng_free_ani_gama;
-    pGAMA->sHeader.fProcess = mng_process_ani_gama;
-#endif
-
-    mng_add_ani_object (pData, (mng_object_headerp)pGAMA);
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-    pGAMA->bEmpty = bEmpty;
-    pGAMA->iGamma = iGamma;
-#else
-    pGAMA->bEmpty = ((mng_gamap)pChunk)->bEmpty;
-    pGAMA->iGamma = ((mng_gamap)pChunk)->iGamma;
-#endif
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_GAMA, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_OBJCLEANUP
-mng_retcode mng_free_ani_gama (mng_datap   pData,
-                               mng_objectp pObject)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_GAMA, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pObject, sizeof (mng_ani_gama));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_GAMA, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_ani_gama (mng_datap   pData,
-                                  mng_objectp pObject)
-{
-  mng_ani_gamap pGAMA = (mng_ani_gamap)pObject;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_GAMA, MNG_LC_START);
-#endif
-
-  if (pGAMA->bEmpty)                   /* empty chunk ? */
-  {                                    /* clear global gAMA */
-    pData->bHasglobalGAMA = MNG_FALSE;
-    pData->iGlobalGamma   = 0;
-  }
-  else
-  {                                    /* set global gAMA */
-    pData->bHasglobalGAMA = MNG_TRUE;
-    pData->iGlobalGamma   = pGAMA->iGamma;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_GAMA, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_cHRM
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-mng_retcode mng_create_ani_chrm (mng_datap  pData,
-                                 mng_bool   bEmpty,
-                                 mng_uint32 iWhitepointx,
-                                 mng_uint32 iWhitepointy,
-                                 mng_uint32 iRedx,
-                                 mng_uint32 iRedy,
-                                 mng_uint32 iGreenx,
-                                 mng_uint32 iGreeny,
-                                 mng_uint32 iBluex,
-                                 mng_uint32 iBluey)
-#else
-mng_retcode mng_create_ani_chrm (mng_datap  pData,
-                                 mng_chunkp pChunk)
-#endif
-{
-  mng_ptr       pTemp;
-  mng_ani_chrmp pCHRM;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_CHRM, MNG_LC_START);
-#endif
-
-  if (pData->bCacheplayback)           /* caching playback info ? */
-  {
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-    mng_retcode iRetcode = create_obj_general (pData, sizeof (mng_ani_chrm),
-                                               mng_free_obj_general,
-                                               mng_process_ani_chrm,
-                                               &pTemp);
-    if (iRetcode)
-      return iRetcode;
-    pCHRM = (mng_ani_chrmp)pTemp;
-#else
-    MNG_ALLOC (pData, pCHRM, sizeof (mng_ani_chrm));
-
-    pCHRM->sHeader.fCleanup = mng_free_ani_chrm;
-    pCHRM->sHeader.fProcess = mng_process_ani_chrm;
-#endif
-
-    mng_add_ani_object (pData, (mng_object_headerp)pCHRM);
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-    pCHRM->bEmpty       = bEmpty;
-    pCHRM->iWhitepointx = iWhitepointx;
-    pCHRM->iWhitepointy = iWhitepointy;
-    pCHRM->iRedx        = iRedx;
-    pCHRM->iRedy        = iRedy;
-    pCHRM->iGreenx      = iGreenx;
-    pCHRM->iGreeny      = iGreeny;
-    pCHRM->iBluex       = iBluex;
-    pCHRM->iBluey       = iBluey;
-#else
-    pCHRM->bEmpty       = ((mng_chrmp)pChunk)->bEmpty;
-    pCHRM->iWhitepointx = ((mng_chrmp)pChunk)->iWhitepointx;
-    pCHRM->iWhitepointy = ((mng_chrmp)pChunk)->iWhitepointy;
-    pCHRM->iRedx        = ((mng_chrmp)pChunk)->iRedx;
-    pCHRM->iRedy        = ((mng_chrmp)pChunk)->iRedy;
-    pCHRM->iGreenx      = ((mng_chrmp)pChunk)->iGreenx;
-    pCHRM->iGreeny      = ((mng_chrmp)pChunk)->iGreeny;
-    pCHRM->iBluex       = ((mng_chrmp)pChunk)->iBluex;
-    pCHRM->iBluey       = ((mng_chrmp)pChunk)->iBluey;
-#endif
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_CHRM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_OBJCLEANUP
-mng_retcode mng_free_ani_chrm (mng_datap   pData,
-                               mng_objectp pObject)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_CHRM, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pObject, sizeof (mng_ani_chrm));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_CHRM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_ani_chrm (mng_datap   pData,
-                                  mng_objectp pObject)
-{
-  mng_ani_chrmp pCHRM = (mng_ani_chrmp)pObject;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_CHRM, MNG_LC_START);
-#endif
-
-  if (pCHRM->bEmpty)                   /* empty chunk ? */
-  {                                    /* clear global cHRM */
-    pData->bHasglobalCHRM       = MNG_FALSE;
-    pData->iGlobalWhitepointx   = 0;
-    pData->iGlobalWhitepointy   = 0;
-    pData->iGlobalPrimaryredx   = 0;
-    pData->iGlobalPrimaryredy   = 0;
-    pData->iGlobalPrimarygreenx = 0;
-    pData->iGlobalPrimarygreeny = 0;
-    pData->iGlobalPrimarybluex  = 0;
-    pData->iGlobalPrimarybluey  = 0;
-  }
-  else
-  {                                    /* set global cHRM */
-    pData->bHasglobalCHRM       = MNG_TRUE;
-    pData->iGlobalWhitepointx   = pCHRM->iWhitepointx;
-    pData->iGlobalWhitepointy   = pCHRM->iWhitepointy;
-    pData->iGlobalPrimaryredx   = pCHRM->iRedx;
-    pData->iGlobalPrimaryredy   = pCHRM->iRedy;
-    pData->iGlobalPrimarygreenx = pCHRM->iGreenx;
-    pData->iGlobalPrimarygreeny = pCHRM->iGreeny;
-    pData->iGlobalPrimarybluex  = pCHRM->iBluex;
-    pData->iGlobalPrimarybluey  = pCHRM->iBluey;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_CHRM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_sRGB
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-mng_retcode mng_create_ani_srgb (mng_datap pData,
-                                 mng_bool  bEmpty,
-                                 mng_uint8 iRenderingintent)
-#else
-mng_retcode mng_create_ani_srgb (mng_datap pData,
-                                 mng_chunkp pChunk)
-#endif
-{
-  mng_ani_srgbp pSRGB;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_SRGB, MNG_LC_START);
-#endif
-
-  if (pData->bCacheplayback)           /* caching playback info ? */
-  {
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-    mng_ptr     pTemp;
-    mng_retcode iRetcode = create_obj_general (pData, sizeof (mng_ani_srgb),
-                                               mng_free_obj_general,
-                                               mng_process_ani_srgb,
-                                               &pTemp);
-    if (iRetcode)
-      return iRetcode;
-    pSRGB = (mng_ani_srgbp)pTemp;
-#else
-    MNG_ALLOC (pData, pSRGB, sizeof (mng_ani_srgb));
-
-    pSRGB->sHeader.fCleanup = mng_free_ani_srgb;
-    pSRGB->sHeader.fProcess = mng_process_ani_srgb;
-#endif
-
-    mng_add_ani_object (pData, (mng_object_headerp)pSRGB);
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-    pSRGB->bEmpty           = bEmpty;
-    pSRGB->iRenderingintent = iRenderingintent;
-#else
-    pSRGB->bEmpty           = ((mng_srgbp)pChunk)->bEmpty;
-    pSRGB->iRenderingintent = ((mng_srgbp)pChunk)->iRenderingintent;
-#endif
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_SRGB, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_OBJCLEANUP
-mng_retcode mng_free_ani_srgb (mng_datap   pData,
-                               mng_objectp pObject)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_SRGB, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pObject, sizeof (mng_ani_srgb));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_SRGB, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_ani_srgb (mng_datap   pData,
-                                  mng_objectp pObject)
-{
-  mng_ani_srgbp pSRGB = (mng_ani_srgbp)pObject;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_SRGB, MNG_LC_START);
-#endif
-
-  if (pSRGB->bEmpty)                   /* empty chunk ? */
-  {                                    /* clear global sRGB */
-    pData->bHasglobalSRGB    = MNG_FALSE;
-    pData->iGlobalRendintent = 0;
-  }
-  else
-  {                                    /* set global sRGB */
-    pData->bHasglobalSRGB    = MNG_TRUE;
-    pData->iGlobalRendintent = pSRGB->iRenderingintent;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_SRGB, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_iCCP
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-mng_retcode mng_create_ani_iccp (mng_datap  pData,
-                                 mng_bool   bEmpty,
-                                 mng_uint32 iProfilesize,
-                                 mng_ptr    pProfile)
-#else
-mng_retcode mng_create_ani_iccp (mng_datap  pData,
-                                 mng_chunkp pChunk)
-#endif
-{
-  mng_ptr       pTemp;
-  mng_ani_iccpp pICCP;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_ICCP, MNG_LC_START);
-#endif
-
-  if (pData->bCacheplayback)           /* caching playback info ? */
-  {
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-    mng_retcode iRetcode = create_obj_general (pData, sizeof (mng_ani_iccp),
-                                               mng_free_ani_iccp,
-                                               mng_process_ani_iccp,
-                                               &pTemp);
-    if (iRetcode)
-      return iRetcode;
-    pICCP = (mng_ani_iccpp)pTemp;
-#else
-    MNG_ALLOC (pData, pICCP, sizeof (mng_ani_iccp));
-
-    pICCP->sHeader.fCleanup = mng_free_ani_iccp;
-    pICCP->sHeader.fProcess = mng_process_ani_iccp;
-#endif
-
-    mng_add_ani_object (pData, (mng_object_headerp)pICCP);
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-    pICCP->bEmpty       = bEmpty;
-    pICCP->iProfilesize = iProfilesize;
-
-    if (iProfilesize)
-    {
-      MNG_ALLOC (pData, pICCP->pProfile, iProfilesize);
-      MNG_COPY (pICCP->pProfile, pProfile, iProfilesize);
-    }
-#else
-    pICCP->bEmpty       = ((mng_iccpp)pChunk)->bEmpty;
-    pICCP->iProfilesize = ((mng_iccpp)pChunk)->iProfilesize;
-
-    if (pICCP->iProfilesize)
-    {
-      MNG_ALLOC (pData, pICCP->pProfile, pICCP->iProfilesize);
-      MNG_COPY (pICCP->pProfile, ((mng_iccpp)pChunk)->pProfile, pICCP->iProfilesize);
-    }
-#endif
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_ICCP, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_free_ani_iccp (mng_datap   pData,
-                               mng_objectp pObject)
-{
-  mng_ani_iccpp pICCP = (mng_ani_iccpp)pObject;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_ICCP, MNG_LC_START);
-#endif
-
-  if (pICCP->iProfilesize)
-    MNG_FREEX (pData, pICCP->pProfile, pICCP->iProfilesize);
-
-#ifndef MNG_OPTIMIZE_OBJCLEANUP
-  MNG_FREEX (pData, pObject, sizeof (mng_ani_iccp));
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_ICCP, MNG_LC_END);
-#endif
-
-#ifndef MNG_OPTIMIZE_OBJCLEANUP
-  return MNG_NOERROR;
-#else
-  return mng_free_obj_general(pData, pObject);
-#endif
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_ani_iccp (mng_datap   pData,
-                                  mng_objectp pObject)
-{
-  mng_ani_iccpp pICCP = (mng_ani_iccpp)pObject;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_ICCP, MNG_LC_START);
-#endif
-
-  if (pICCP->bEmpty)                   /* empty chunk ? */
-  {                                    /* clear global iCCP */
-    pData->bHasglobalICCP = MNG_FALSE;
-
-    if (pData->iGlobalProfilesize)
-      MNG_FREEX (pData, pData->pGlobalProfile, pData->iGlobalProfilesize);
-
-    pData->iGlobalProfilesize = 0;
-    pData->pGlobalProfile     = MNG_NULL;
-  }
-  else
-  {                                    /* set global iCCP */
-    pData->bHasglobalICCP     = MNG_TRUE;
-    pData->iGlobalProfilesize = pICCP->iProfilesize;
-
-    if (pICCP->iProfilesize)
-    {
-      MNG_ALLOC (pData, pData->pGlobalProfile, pICCP->iProfilesize);
-      MNG_COPY (pData->pGlobalProfile, pICCP->pProfile, pICCP->iProfilesize);
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_ICCP, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_bKGD
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-mng_retcode mng_create_ani_bkgd (mng_datap  pData,
-                                 mng_uint16 iRed,
-                                 mng_uint16 iGreen,
-                                 mng_uint16 iBlue)
-#else
-mng_retcode mng_create_ani_bkgd (mng_datap  pData)
-#endif
-{
-  mng_ptr       pTemp;
-  mng_ani_bkgdp pBKGD;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_BKGD, MNG_LC_START);
-#endif
-
-  if (pData->bCacheplayback)           /* caching playback info ? */
-  {
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-    mng_retcode iRetcode = create_obj_general (pData, sizeof (mng_ani_bkgd),
-                                               mng_free_obj_general,
-                                               mng_process_ani_bkgd,
-                                               &pTemp);
-    if (iRetcode)
-      return iRetcode;
-    pBKGD = (mng_ani_bkgdp)pTemp;
-#else
-    MNG_ALLOC (pData, pBKGD, sizeof (mng_ani_bkgd));
-
-    pBKGD->sHeader.fCleanup = mng_free_ani_bkgd;
-    pBKGD->sHeader.fProcess = mng_process_ani_bkgd;
-#endif
-
-    mng_add_ani_object (pData, (mng_object_headerp)pBKGD);
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-    pBKGD->iRed   = iRed;
-    pBKGD->iGreen = iGreen;
-    pBKGD->iBlue  = iBlue;
-#else
-    pBKGD->iRed   = pData->iGlobalBKGDred;
-    pBKGD->iGreen = pData->iGlobalBKGDgreen;
-    pBKGD->iBlue  = pData->iGlobalBKGDblue;
-#endif
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_BKGD, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_OBJCLEANUP
-mng_retcode mng_free_ani_bkgd (mng_datap   pData,
-                               mng_objectp pObject)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_BKGD, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pObject, sizeof (mng_ani_bkgd));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_BKGD, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_ani_bkgd (mng_datap   pData,
-                                  mng_objectp pObject)
-{
-  mng_ani_bkgdp pBKGD = (mng_ani_bkgdp)pObject;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_BKGD, MNG_LC_START);
-#endif
-
-  pData->bHasglobalBKGD   = MNG_TRUE;
-  pData->iGlobalBKGDred   = pBKGD->iRed;
-  pData->iGlobalBKGDgreen = pBKGD->iGreen;
-  pData->iGlobalBKGDblue  = pBKGD->iBlue;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_BKGD, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_LOOP
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-mng_retcode mng_create_ani_loop (mng_datap   pData,
-                                 mng_uint8   iLevel,
-                                 mng_uint32  iRepeatcount,
-                                 mng_uint8   iTermcond,
-                                 mng_uint32  iItermin,
-                                 mng_uint32  iItermax,
-                                 mng_uint32  iCount,
-                                 mng_uint32p pSignals)
-#else
-mng_retcode mng_create_ani_loop (mng_datap   pData,
-                                 mng_chunkp  pChunk)
-#endif
-{
-  mng_ani_loopp pLOOP;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_LOOP, MNG_LC_START);
-#endif
-
-  if (pData->bCacheplayback)           /* caching playback info ? */
-  {
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-    mng_ptr     pTemp;
-    mng_retcode iRetcode = create_obj_general (pData, sizeof (mng_ani_loop),
-                                               mng_free_ani_loop,
-                                               mng_process_ani_loop,
-                                               &pTemp);
-    if (iRetcode)
-      return iRetcode;
-    pLOOP = (mng_ani_loopp)pTemp;
-#else
-    MNG_ALLOC (pData, pLOOP, sizeof (mng_ani_loop));
-
-    pLOOP->sHeader.fCleanup = mng_free_ani_loop;
-    pLOOP->sHeader.fProcess = mng_process_ani_loop;
-#endif
-
-    mng_add_ani_object (pData, (mng_object_headerp)pLOOP);
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-    pLOOP->iLevel       = iLevel;
-    pLOOP->iRepeatcount = iRepeatcount;
-    pLOOP->iTermcond    = iTermcond;
-    pLOOP->iItermin     = iItermin;
-    pLOOP->iItermax     = iItermax;
-    pLOOP->iCount       = iCount;
-
-#ifndef MNG_NO_LOOP_SIGNALS_SUPPORTED
-    if (iCount)
-    {
-      MNG_ALLOC (pData, pLOOP->pSignals, (iCount << 1));
-      MNG_COPY (pLOOP->pSignals, pSignals, (iCount << 1));
-    }
-#endif
-#else /* MNG_OPTIMIZE_CHUNKREADER */
-    pLOOP->iLevel       = ((mng_loopp)pChunk)->iLevel;
-    pLOOP->iRepeatcount = ((mng_loopp)pChunk)->iRepeat;
-    pLOOP->iTermcond    = ((mng_loopp)pChunk)->iTermination;
-    pLOOP->iItermin     = ((mng_loopp)pChunk)->iItermin;
-    pLOOP->iItermax     = ((mng_loopp)pChunk)->iItermax;
-    pLOOP->iCount       = ((mng_loopp)pChunk)->iCount;
-
-#ifndef MNG_NO_LOOP_SIGNALS_SUPPORTED
-    if (pLOOP->iCount)
-    {
-      MNG_ALLOC (pData, pLOOP->pSignals, (pLOOP->iCount << 1));
-      MNG_COPY (pLOOP->pSignals, ((mng_loopp)pChunk)->pSignals, (pLOOP->iCount << 1));
-    }
-#endif
-#endif /* MNG_OPTIMIZE_CHUNKREADER */
-                                         /* running counter starts with repeat_count */
-    pLOOP->iRunningcount = pLOOP->iRepeatcount;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_LOOP, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_free_ani_loop (mng_datap   pData,
-                               mng_objectp pObject)
-{
-#ifndef MNG_NO_LOOP_SIGNALS_SUPPORTED
-  mng_ani_loopp pLOOP = (mng_ani_loopp)pObject;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_LOOP, MNG_LC_START);
-#endif
-
-#ifndef MNG_NO_LOOP_SIGNALS_SUPPORTED
-  if (pLOOP->iCount)                   /* drop signal buffer ? */
-    MNG_FREEX (pData, pLOOP->pSignals, (pLOOP->iCount << 1));
-#endif
-
-#ifndef MNG_OPTIMIZE_OBJCLEANUP
-  MNG_FREEX (pData, pObject, sizeof (mng_ani_loop));
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_LOOP, MNG_LC_END);
-#endif
-
-#ifndef MNG_OPTIMIZE_OBJCLEANUP
-  return MNG_NOERROR;
-#else
-  return mng_free_obj_general(pData, pObject);
-#endif
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_ani_loop (mng_datap   pData,
-                                  mng_objectp pObject)
-{
-  mng_ani_loopp pLOOP = (mng_ani_loopp)pObject;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_LOOP, MNG_LC_START);
-#endif
-                                       /* just reset the running counter */
-  pLOOP->iRunningcount = pLOOP->iRepeatcount;
-                                       /* iteration=0 means we're skipping ! */
-  if ((!pData->bSkipping) && (pLOOP->iRepeatcount == 0))
-    pData->bSkipping = MNG_TRUE;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_LOOP, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-/* ************************************************************************** */
-
-mng_retcode mng_create_ani_endl (mng_datap pData,
-                                 mng_uint8 iLevel)
-{
-  mng_ani_endlp pENDL;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_ENDL, MNG_LC_START);
-#endif
-
-  if (pData->bCacheplayback)           /* caching playback info ? */
-  {
-    mng_retcode iRetcode;
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-    mng_ptr     pTemp;
-    iRetcode = create_obj_general (pData, sizeof (mng_ani_endl),
-                                               mng_free_obj_general,
-                                               mng_process_ani_endl,
-                                               &pTemp);
-    if (iRetcode)
-      return iRetcode;
-    pENDL = (mng_ani_endlp)pTemp;
-#else
-    MNG_ALLOC (pData, pENDL, sizeof (mng_ani_endl));
-
-    pENDL->sHeader.fCleanup = mng_free_ani_endl;
-    pENDL->sHeader.fProcess = mng_process_ani_endl;
-#endif
-
-    mng_add_ani_object (pData, (mng_object_headerp)pENDL);
-
-    pENDL->iLevel = iLevel;
-
-    iRetcode = mng_process_ani_endl (pData, (mng_objectp)pENDL);
-    if (iRetcode)
-      return iRetcode;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_ENDL, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_OBJCLEANUP
-mng_retcode mng_free_ani_endl (mng_datap   pData,
-                               mng_objectp pObject)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_ENDL, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pObject, sizeof (mng_ani_endl));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_ENDL, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_ani_endl (mng_datap   pData,
-                                  mng_objectp pObject)
-{
-  mng_ani_endlp pENDL = (mng_ani_endlp)pObject;
-  mng_ani_loopp pLOOP;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_ENDL, MNG_LC_START);
-#endif
-
-  if (((pData->bDisplaying) && ((pData->bRunning) || (pData->bSearching))) ||
-      (pData->bReading)                                                       )
-  {
-    pLOOP = pENDL->pLOOP;              /* determine matching LOOP */
-
-    if (!pLOOP)                        /* haven't got it yet ? */
-    {                                  /* go and look back in the list */
-      pLOOP = (mng_ani_loopp)pENDL->sHeader.pPrev;
-
-      while ((pLOOP) &&
-             ((pLOOP->sHeader.fCleanup != mng_free_ani_loop) ||
-              (pLOOP->iLevel           != pENDL->iLevel)        ))
-        pLOOP = pLOOP->sHeader.pPrev;
-    }
-                                       /* got it now ? */
-    if ((pLOOP) && (pLOOP->iLevel == pENDL->iLevel))
-    {
-      pENDL->pLOOP = pLOOP;            /* save for next time ! */
-                                       /* decrease running counter ? */
-      if ((pLOOP->iRunningcount) && (pLOOP->iRunningcount < 0x7fffffffL))
-        pLOOP->iRunningcount--;
-
-      if ((!pData->bDisplaying) && (pData->bReading) &&
-          (pLOOP->iRunningcount >= 0x7fffffffL))
-      {
-        pData->iTotalframes   = 0x7fffffffL;
-        pData->iTotallayers   = 0x7fffffffL;
-        pData->iTotalplaytime = 0x7fffffffL;
-      }
-      else
-      {
-        /* TODO: we're cheating out on the termination_condition,
-           iteration_min, iteration_max and possible signals;
-           the code is just not ready for that can of worms.... */
-
-        if (!pLOOP->iRunningcount)     /* reached zero ? */
-        {                              /* was this the outer LOOP ? */
-          if (pData->pFirstaniobj == (mng_objectp)pLOOP)  /* TODO: THIS IS WRONG!! */
-            pData->bHasLOOP = MNG_FALSE;
-        }
-        else
-        {
-          if (pData->pCurraniobj)      /* was we processing objects ? */
-            pData->pCurraniobj = pLOOP;/* then restart with LOOP */
-          else                         /* else restart behind LOOP !!! */
-            pData->pCurraniobj = pLOOP->sHeader.pNext;
-        }
-      }
-                                       /* does this match a 'skipping' LOOP? */
-      if ((pData->bSkipping) && (pLOOP->iRepeatcount == 0))
-        pData->bSkipping = MNG_FALSE;
-    }
-    else
-      MNG_ERROR (pData, MNG_NOMATCHINGLOOP);
-
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_ENDL, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_DEFI
-mng_retcode mng_create_ani_defi (mng_datap pData)
-{               
-  mng_ani_defip pDEFI;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_DEFI, MNG_LC_START);
-#endif
-
-  if (pData->bCacheplayback)           /* caching playback info ? */
-  {
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-    mng_ptr     pTemp;
-    mng_retcode iRetcode = create_obj_general (pData, sizeof (mng_ani_defi),
-                                               mng_free_obj_general,
-                                               mng_process_ani_defi,
-                                               &pTemp);
-    if (iRetcode)
-      return iRetcode;
-    pDEFI = (mng_ani_defip)pTemp;
-#else
-    MNG_ALLOC (pData, pDEFI, sizeof (mng_ani_defi));
-
-    pDEFI->sHeader.fCleanup = mng_free_ani_defi;
-    pDEFI->sHeader.fProcess = mng_process_ani_defi;
-#endif
-
-    mng_add_ani_object (pData, (mng_object_headerp)pDEFI);
-
-    pDEFI->iId              = pData->iDEFIobjectid;
-    pDEFI->bHasdonotshow    = pData->bDEFIhasdonotshow;
-    pDEFI->iDonotshow       = pData->iDEFIdonotshow;
-    pDEFI->bHasconcrete     = pData->bDEFIhasconcrete;
-    pDEFI->iConcrete        = pData->iDEFIconcrete;
-    pDEFI->bHasloca         = pData->bDEFIhasloca;
-    pDEFI->iLocax           = pData->iDEFIlocax;
-    pDEFI->iLocay           = pData->iDEFIlocay;
-    pDEFI->bHasclip         = pData->bDEFIhasclip;
-    pDEFI->iClipl           = pData->iDEFIclipl;
-    pDEFI->iClipr           = pData->iDEFIclipr;
-    pDEFI->iClipt           = pData->iDEFIclipt;
-    pDEFI->iClipb           = pData->iDEFIclipb;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_DEFI, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_OBJCLEANUP
-mng_retcode mng_free_ani_defi (mng_datap   pData,
-                               mng_objectp pObject)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_DEFI, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pObject, sizeof (mng_ani_defi));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_DEFI, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_ani_defi (mng_datap   pData,
-                                  mng_objectp pObject)
-{
-  mng_ani_defip pDEFI = (mng_ani_defip)pObject;
-  mng_retcode   iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_DEFI, MNG_LC_START);
-#endif
-
-  pData->iDEFIobjectid     = pDEFI->iId;
-  pData->bDEFIhasdonotshow = pDEFI->bHasdonotshow;
-  pData->iDEFIdonotshow    = pDEFI->iDonotshow;
-  pData->bDEFIhasconcrete  = pDEFI->bHasconcrete;
-  pData->iDEFIconcrete     = pDEFI->iConcrete;
-  pData->bDEFIhasloca      = pDEFI->bHasloca;
-  pData->iDEFIlocax        = pDEFI->iLocax;
-  pData->iDEFIlocay        = pDEFI->iLocay;
-  pData->bDEFIhasclip      = pDEFI->bHasclip;
-  pData->iDEFIclipl        = pDEFI->iClipl;
-  pData->iDEFIclipr        = pDEFI->iClipr;
-  pData->iDEFIclipt        = pDEFI->iClipt;
-  pData->iDEFIclipb        = pDEFI->iClipb;
-
-  iRetcode = mng_process_display_defi (pData);
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_DEFI, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_BASI
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-mng_retcode mng_create_ani_basi (mng_datap  pData,
-                                 mng_uint16 iRed,
-                                 mng_uint16 iGreen,
-                                 mng_uint16 iBlue,
-                                 mng_bool   bHasalpha,
-                                 mng_uint16 iAlpha,
-                                 mng_uint8  iViewable)
-#else
-mng_retcode mng_create_ani_basi (mng_datap  pData,
-                                 mng_chunkp pChunk)
-#endif
-{
-  mng_ani_basip pBASI;
-  mng_retcode   iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_BASI, MNG_LC_START);
-#endif
-
-  if (pData->bCacheplayback)           /* caching playback info ? */
-  {
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-    mng_ptr pTemp;
-    iRetcode = create_obj_general (pData, sizeof (mng_ani_basi),
-                                   mng_free_obj_general,
-                                   mng_process_ani_basi,
-                                   &pTemp);
-    if (iRetcode)
-      return iRetcode;
-    pBASI = (mng_ani_basip)pTemp;
-#else
-    MNG_ALLOC (pData, pBASI, sizeof (mng_ani_basi));
-
-    pBASI->sHeader.fCleanup = mng_free_ani_basi;
-    pBASI->sHeader.fProcess = mng_process_ani_basi;
-#endif
-
-    mng_add_ani_object (pData, (mng_object_headerp)pBASI);
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-    pBASI->iRed      = iRed;
-    pBASI->iGreen    = iGreen;
-    pBASI->iBlue     = iBlue;
-    pBASI->bHasalpha = bHasalpha;
-    pBASI->iAlpha    = iAlpha;
-    pBASI->iViewable = iViewable;
-#else
-    pBASI->iRed      = ((mng_basip)pChunk)->iRed;
-    pBASI->iGreen    = ((mng_basip)pChunk)->iGreen;
-    pBASI->iBlue     = ((mng_basip)pChunk)->iBlue;
-    pBASI->bHasalpha = ((mng_basip)pChunk)->bHasalpha;
-    pBASI->iAlpha    = ((mng_basip)pChunk)->iAlpha;
-    pBASI->iViewable = ((mng_basip)pChunk)->iViewable;
-#endif
-  }
-
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  iRetcode = mng_process_display_basi (pData, iRed, iGreen, iBlue,
-                                       bHasalpha, iAlpha, iViewable);
-#else
-  iRetcode = mng_process_display_basi (pData,
-                                       ((mng_basip)pChunk)->iRed,
-                                       ((mng_basip)pChunk)->iGreen,
-                                       ((mng_basip)pChunk)->iBlue,
-                                       ((mng_basip)pChunk)->bHasalpha,
-                                       ((mng_basip)pChunk)->iAlpha,
-                                       ((mng_basip)pChunk)->iViewable);
-#endif
-#else
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  pData->iBASIred      = iRed;
-  pData->iBASIgreen    = iGreen;
-  pData->iBASIblue     = iBlue;
-  pData->bBASIhasalpha = bHasalpha;
-  pData->iBASIalpha    = iAlpha;
-  pData->iBASIviewable = iViewable;
-#else
-  pData->iBASIred      = ((mng_basip)pChunk)->iRed;
-  pData->iBASIgreen    = ((mng_basip)pChunk)->iGreen;
-  pData->iBASIblue     = ((mng_basip)pChunk)->iBlue;
-  pData->bBASIhasalpha = ((mng_basip)pChunk)->bHasalpha;
-  pData->iBASIalpha    = ((mng_basip)pChunk)->iAlpha;
-  pData->iBASIviewable = ((mng_basip)pChunk)->iViewable;
-#endif
-
-  iRetcode = mng_process_display_basi (pData);
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_BASI, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_OBJCLEANUP
-mng_retcode mng_free_ani_basi (mng_datap   pData,
-                               mng_objectp pObject)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_BASI, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pObject, sizeof (mng_ani_basi));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_BASI, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_ani_basi (mng_datap   pData,
-                                  mng_objectp pObject)
-{
-  mng_ani_basip pBASI = (mng_ani_basip)pObject;
-  mng_retcode   iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_BASI, MNG_LC_START);
-#endif
-
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-  iRetcode = mng_process_display_basi (pData, pBASI->iRed, pBASI->iGreen, pBASI->iBlue,
-                                       pBASI->bHasalpha, pBASI->iAlpha, pBASI->iViewable);
-#else
-  pData->iBASIred      = pBASI->iRed;
-  pData->iBASIgreen    = pBASI->iGreen;
-  pData->iBASIblue     = pBASI->iBlue;
-  pData->bBASIhasalpha = pBASI->bHasalpha;
-  pData->iBASIalpha    = pBASI->iAlpha;
-  pData->iBASIviewable = pBASI->iViewable;
-
-  iRetcode = mng_process_display_basi (pData);
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_BASI, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_CLON
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-mng_retcode mng_create_ani_clon (mng_datap  pData,
-                                 mng_uint16 iSourceid,
-                                 mng_uint16 iCloneid,
-                                 mng_uint8  iClonetype,
-                                 mng_bool   bHasdonotshow,
-                                 mng_uint8  iDonotshow,
-                                 mng_uint8  iConcrete,
-                                 mng_bool   bHasloca,
-                                 mng_uint8  iLocatype,
-                                 mng_int32  iLocax,
-                                 mng_int32  iLocay)
-#else
-mng_retcode mng_create_ani_clon (mng_datap  pData,
-                                 mng_chunkp pChunk)
-#endif
-{
-  mng_ani_clonp pCLON;
-  mng_retcode   iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_CLON, MNG_LC_START);
-#endif
-
-  if (pData->bCacheplayback)           /* caching playback info ? */
-  {
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-    mng_ptr pTemp;
-    iRetcode = create_obj_general (pData, sizeof (mng_ani_clon),
-                                   mng_free_obj_general,
-                                   mng_process_ani_clon,
-                                   &pTemp);
-    if (iRetcode)
-      return iRetcode;
-    pCLON = (mng_ani_clonp)pTemp;
-#else
-    MNG_ALLOC (pData, pCLON, sizeof (mng_ani_clon));
-
-    pCLON->sHeader.fCleanup = mng_free_ani_clon;
-    pCLON->sHeader.fProcess = mng_process_ani_clon;
-#endif
-
-    mng_add_ani_object (pData, (mng_object_headerp)pCLON);
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-    pCLON->iSourceid     = iSourceid;
-    pCLON->iCloneid      = iCloneid;
-    pCLON->iClonetype    = iClonetype;
-    pCLON->bHasdonotshow = bHasdonotshow;
-    pCLON->iDonotshow    = iDonotshow;
-    pCLON->iConcrete     = iConcrete;
-    pCLON->bHasloca      = bHasloca;
-    pCLON->iLocatype     = iLocatype;
-    pCLON->iLocax        = iLocax;
-    pCLON->iLocay        = iLocay;
-#else
-    pCLON->iSourceid     = ((mng_clonp)pChunk)->iSourceid;
-    pCLON->iCloneid      = ((mng_clonp)pChunk)->iCloneid;
-    pCLON->iClonetype    = ((mng_clonp)pChunk)->iClonetype;
-    pCLON->bHasdonotshow = ((mng_clonp)pChunk)->bHasdonotshow;
-    pCLON->iDonotshow    = ((mng_clonp)pChunk)->iDonotshow;
-    pCLON->iConcrete     = ((mng_clonp)pChunk)->iConcrete;
-    pCLON->bHasloca      = ((mng_clonp)pChunk)->bHasloca;
-    pCLON->iLocatype     = ((mng_clonp)pChunk)->iLocationtype;
-    pCLON->iLocax        = ((mng_clonp)pChunk)->iLocationx;
-    pCLON->iLocay        = ((mng_clonp)pChunk)->iLocationy;
-#endif
-  }
-
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  iRetcode = mng_process_display_clon (pData, iSourceid, iCloneid, iClonetype,
-                                       bHasdonotshow, iDonotshow, iConcrete,
-                                       bHasloca, iLocatype, iLocax, iLocay);
-#else
-  iRetcode = mng_process_display_clon (pData,
-                                       ((mng_clonp)pChunk)->iSourceid,
-                                       ((mng_clonp)pChunk)->iCloneid,
-                                       ((mng_clonp)pChunk)->iClonetype,
-                                       ((mng_clonp)pChunk)->bHasdonotshow,
-                                       ((mng_clonp)pChunk)->iDonotshow,
-                                       ((mng_clonp)pChunk)->iConcrete,
-                                       ((mng_clonp)pChunk)->bHasloca,
-                                       ((mng_clonp)pChunk)->iLocationtype,
-                                       ((mng_clonp)pChunk)->iLocationx,
-                                       ((mng_clonp)pChunk)->iLocationy);
-#endif
-#else
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  pData->iCLONsourceid     = iSourceid;
-  pData->iCLONcloneid      = iCloneid;
-  pData->iCLONclonetype    = iClonetype;
-  pData->bCLONhasdonotshow = bHasdonotshow;
-  pData->iCLONdonotshow    = iDonotshow;
-  pData->iCLONconcrete     = iConcrete;
-  pData->bCLONhasloca      = bHasloca;
-  pData->iCLONlocationtype = iLocatype;
-  pData->iCLONlocationx    = iLocax;
-  pData->iCLONlocationy    = iLocay;
-#else
-  pData->iCLONsourceid     = ((mng_clonp)pChunk)->iSourceid;
-  pData->iCLONcloneid      = ((mng_clonp)pChunk)->iCloneid;
-  pData->iCLONclonetype    = ((mng_clonp)pChunk)->iClonetype;
-  pData->bCLONhasdonotshow = ((mng_clonp)pChunk)->bHasdonotshow;
-  pData->iCLONdonotshow    = ((mng_clonp)pChunk)->iDonotshow;
-  pData->iCLONconcrete     = ((mng_clonp)pChunk)->iConcrete;
-  pData->bCLONhasloca      = ((mng_clonp)pChunk)->bHasloca;
-  pData->iCLONlocationtype = ((mng_clonp)pChunk)->iLocationtype;
-  pData->iCLONlocationx    = ((mng_clonp)pChunk)->iLocationx;
-  pData->iCLONlocationy    = ((mng_clonp)pChunk)->iLocationy;
-#endif
-
-  iRetcode = mng_process_display_clon (pData);
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_CLON, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_OBJCLEANUP
-mng_retcode mng_free_ani_clon (mng_datap   pData,
-                               mng_objectp pObject)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_CLON, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pObject, sizeof (mng_ani_clon));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_CLON, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_ani_clon (mng_datap   pData,
-                                  mng_objectp pObject)
-{
-  mng_ani_clonp pCLON = (mng_ani_clonp)pObject;
-  mng_retcode   iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_CLON, MNG_LC_START);
-#endif
-
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-  iRetcode = mng_process_display_clon (pData, pCLON->iSourceid, pCLON->iCloneid,
-                                       pCLON->iClonetype, pCLON->bHasdonotshow,
-                                       pCLON->iDonotshow, pCLON->iConcrete,
-                                       pCLON->bHasloca, pCLON->iLocatype,
-                                       pCLON->iLocax, pCLON->iLocay);
-#else
-  pData->iCLONcloneid      = pCLON->iCloneid;
-  pData->iCLONsourceid     = pCLON->iSourceid;
-  pData->iCLONclonetype    = pCLON->iClonetype;
-  pData->bCLONhasdonotshow = pCLON->bHasdonotshow;
-  pData->iCLONdonotshow    = pCLON->iDonotshow;
-  pData->iCLONconcrete     = pCLON->iConcrete;
-  pData->bCLONhasloca      = pCLON->bHasloca;
-  pData->iCLONlocationtype = pCLON->iLocatype;
-  pData->iCLONlocationx    = pCLON->iLocax;
-  pData->iCLONlocationy    = pCLON->iLocay;
-
-  iRetcode = mng_process_display_clon (pData);
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_CLON, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_BACK
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-mng_retcode mng_create_ani_back (mng_datap  pData,
-                                 mng_uint16 iRed,
-                                 mng_uint16 iGreen,
-                                 mng_uint16 iBlue,
-                                 mng_uint8  iMandatory,
-                                 mng_uint16 iImageid,
-                                 mng_uint8  iTile)
-#else
-mng_retcode mng_create_ani_back (mng_datap  pData)
-#endif
-{
-  mng_ani_backp pBACK;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_BACK, MNG_LC_START);
-#endif
-
-  if (pData->bCacheplayback)           /* caching playback info ? */
-  {
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-    mng_ptr     pTemp;
-    mng_retcode iRetcode = create_obj_general (pData, sizeof (mng_ani_back),
-                                               mng_free_obj_general,
-                                               mng_process_ani_back,
-                                               &pTemp);
-    if (iRetcode)
-      return iRetcode;
-    pBACK = (mng_ani_backp)pTemp;
-#else
-    MNG_ALLOC (pData, pBACK, sizeof (mng_ani_back));
-
-    pBACK->sHeader.fCleanup = mng_free_ani_back;
-    pBACK->sHeader.fProcess = mng_process_ani_back;
-#endif
-
-    mng_add_ani_object (pData, (mng_object_headerp)pBACK);
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-    pBACK->iRed       = iRed;
-    pBACK->iGreen     = iGreen;
-    pBACK->iBlue      = iBlue;
-    pBACK->iMandatory = iMandatory;
-    pBACK->iImageid   = iImageid;
-    pBACK->iTile      = iTile;
-#else
-    pBACK->iRed       = pData->iBACKred;      
-    pBACK->iGreen     = pData->iBACKgreen;
-    pBACK->iBlue      = pData->iBACKblue;
-    pBACK->iMandatory = pData->iBACKmandatory;
-    pBACK->iImageid   = pData->iBACKimageid;
-    pBACK->iTile      = pData->iBACKtile;
-#endif
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_BACK, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_OBJCLEANUP
-mng_retcode mng_free_ani_back (mng_datap   pData,
-                               mng_objectp pObject)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_BACK, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pObject, sizeof (mng_ani_back));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_BACK, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_ani_back (mng_datap   pData,
-                                  mng_objectp pObject)
-{
-  mng_ani_backp pBACK = (mng_ani_backp)pObject;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_BACK, MNG_LC_START);
-#endif
-
-  pData->iBACKred       = pBACK->iRed;
-  pData->iBACKgreen     = pBACK->iGreen;
-  pData->iBACKblue      = pBACK->iBlue;
-  pData->iBACKmandatory = pBACK->iMandatory;
-  pData->iBACKimageid   = pBACK->iImageid;
-  pData->iBACKtile      = pBACK->iTile;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_BACK, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_FRAM
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-mng_retcode mng_create_ani_fram (mng_datap  pData,
-                                 mng_uint8  iFramemode,
-                                 mng_uint8  iChangedelay,
-                                 mng_uint32 iDelay,
-                                 mng_uint8  iChangetimeout,
-                                 mng_uint32 iTimeout,
-                                 mng_uint8  iChangeclipping,
-                                 mng_uint8  iCliptype,
-                                 mng_int32  iClipl,
-                                 mng_int32  iClipr,
-                                 mng_int32  iClipt,
-                                 mng_int32  iClipb)
-#else
-mng_retcode mng_create_ani_fram (mng_datap  pData,
-                                 mng_chunkp pChunk)
-#endif
-{
-  mng_ani_framp pFRAM;
-  mng_retcode   iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_FRAM, MNG_LC_START);
-#endif
-
-  if (pData->bCacheplayback)           /* caching playback info ? */
-  {
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-    mng_ptr pTemp;
-    iRetcode = create_obj_general (pData, sizeof (mng_ani_fram),
-                                   mng_free_obj_general,
-                                   mng_process_ani_fram,
-                                   &pTemp);
-    if (iRetcode)
-      return iRetcode;
-    pFRAM = (mng_ani_framp)pTemp;
-#else
-    MNG_ALLOC (pData, pFRAM, sizeof (mng_ani_fram));
-
-    pFRAM->sHeader.fCleanup = mng_free_ani_fram;
-    pFRAM->sHeader.fProcess = mng_process_ani_fram;
-#endif
-
-    mng_add_ani_object (pData, (mng_object_headerp)pFRAM);
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-    pFRAM->iFramemode      = iFramemode;
-    pFRAM->iChangedelay    = iChangedelay;
-    pFRAM->iDelay          = iDelay;
-    pFRAM->iChangetimeout  = iChangetimeout;
-    pFRAM->iTimeout        = iTimeout;
-    pFRAM->iChangeclipping = iChangeclipping;
-    pFRAM->iCliptype       = iCliptype;
-    pFRAM->iClipl          = iClipl;
-    pFRAM->iClipr          = iClipr;
-    pFRAM->iClipt          = iClipt;
-    pFRAM->iClipb          = iClipb;
-#else
-    pFRAM->iFramemode      = ((mng_framp)pChunk)->iMode;
-    pFRAM->iChangedelay    = ((mng_framp)pChunk)->iChangedelay;
-    pFRAM->iDelay          = ((mng_framp)pChunk)->iDelay;
-    pFRAM->iChangetimeout  = ((mng_framp)pChunk)->iChangetimeout;
-    pFRAM->iTimeout        = ((mng_framp)pChunk)->iTimeout;
-    pFRAM->iChangeclipping = ((mng_framp)pChunk)->iChangeclipping;
-    pFRAM->iCliptype       = ((mng_framp)pChunk)->iBoundarytype;
-    pFRAM->iClipl          = ((mng_framp)pChunk)->iBoundaryl;
-    pFRAM->iClipr          = ((mng_framp)pChunk)->iBoundaryr;
-    pFRAM->iClipt          = ((mng_framp)pChunk)->iBoundaryt;
-    pFRAM->iClipb          = ((mng_framp)pChunk)->iBoundaryb;
-#endif
-  }
-
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  iRetcode = mng_process_display_fram (pData, iFramemode,
-                                       iChangedelay, iDelay,
-                                       iChangetimeout, iTimeout,
-                                       iChangeclipping, iCliptype,
-                                       iClipl, iClipr,
-                                       iClipt, iClipb);
-#else
-  iRetcode = mng_process_display_fram (pData,
-                                       ((mng_framp)pChunk)->iMode,
-                                       ((mng_framp)pChunk)->iChangedelay,
-                                       ((mng_framp)pChunk)->iDelay,
-                                       ((mng_framp)pChunk)->iChangetimeout,
-                                       ((mng_framp)pChunk)->iTimeout,
-                                       ((mng_framp)pChunk)->iChangeclipping,
-                                       ((mng_framp)pChunk)->iBoundarytype,
-                                       ((mng_framp)pChunk)->iBoundaryl,
-                                       ((mng_framp)pChunk)->iBoundaryr,
-                                       ((mng_framp)pChunk)->iBoundaryt,
-                                       ((mng_framp)pChunk)->iBoundaryb);
-#endif
-#else
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  pData->iTempFramemode      = iFramemode;
-  pData->iTempChangedelay    = iChangedelay;
-  pData->iTempDelay          = iDelay;
-  pData->iTempChangetimeout  = iChangetimeout;
-  pData->iTempTimeout        = iTimeout;
-  pData->iTempChangeclipping = iChangeclipping;
-  pData->iTempCliptype       = iCliptype;
-  pData->iTempClipl          = iClipl;
-  pData->iTempClipr          = iClipr;
-  pData->iTempClipt          = iClipt;
-  pData->iTempClipb          = iClipb;
-#else
-  pData->iTempFramemode      = ((mng_framp)pChunk)->iMode;
-  pData->iTempChangedelay    = ((mng_framp)pChunk)->iChangedelay;
-  pData->iTempDelay          = ((mng_framp)pChunk)->iDelay;
-  pData->iTempChangetimeout  = ((mng_framp)pChunk)->iChangetimeout;
-  pData->iTempTimeout        = ((mng_framp)pChunk)->iTimeout;
-  pData->iTempChangeclipping = ((mng_framp)pChunk)->iChangeclipping;
-  pData->iTempCliptype       = ((mng_framp)pChunk)->iBoundarytype;
-  pData->iTempClipl          = ((mng_framp)pChunk)->iBoundaryl;
-  pData->iTempClipr          = ((mng_framp)pChunk)->iBoundaryr;
-  pData->iTempClipt          = ((mng_framp)pChunk)->iBoundaryt;
-  pData->iTempClipb          = ((mng_framp)pChunk)->iBoundaryb;
-#endif
-
-  iRetcode = mng_process_display_fram (pData);
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_FRAM, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_OBJCLEANUP
-mng_retcode mng_free_ani_fram (mng_datap   pData,
-                               mng_objectp pObject)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_FRAM, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pObject, sizeof (mng_ani_fram));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_FRAM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_ani_fram (mng_datap   pData,
-                                  mng_objectp pObject)
-{
-  mng_ani_framp pFRAM = (mng_ani_framp)pObject;
-  mng_retcode   iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_FRAM, MNG_LC_START);
-#endif
-
-  if (pData->iBreakpoint)              /* previously broken ? */
-  {
-    iRetcode           = mng_process_display_fram2 (pData);
-    pData->iBreakpoint = 0;            /* not again */
-  }
-  else
-  {
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-    iRetcode = mng_process_display_fram (pData, pFRAM->iFramemode,
-                                         pFRAM->iChangedelay, pFRAM->iDelay,
-                                         pFRAM->iChangetimeout, pFRAM->iTimeout,
-                                         pFRAM->iChangeclipping, pFRAM->iCliptype,
-                                         pFRAM->iClipl, pFRAM->iClipr,
-                                         pFRAM->iClipt, pFRAM->iClipb);
-#else
-    pData->iTempFramemode      = pFRAM->iFramemode;
-    pData->iTempChangedelay    = pFRAM->iChangedelay;
-    pData->iTempDelay          = pFRAM->iDelay;
-    pData->iTempChangetimeout  = pFRAM->iChangetimeout;
-    pData->iTempTimeout        = pFRAM->iTimeout;
-    pData->iTempChangeclipping = pFRAM->iChangeclipping;
-    pData->iTempCliptype       = pFRAM->iCliptype;
-    pData->iTempClipl          = pFRAM->iClipl;
-    pData->iTempClipr          = pFRAM->iClipr;
-    pData->iTempClipt          = pFRAM->iClipt;
-    pData->iTempClipb          = pFRAM->iClipb;
-
-    iRetcode = mng_process_display_fram (pData);
-#endif
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_FRAM, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_MOVE
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-mng_retcode mng_create_ani_move (mng_datap  pData,
-                                 mng_uint16 iFirstid,
-                                 mng_uint16 iLastid,
-                                 mng_uint8  iType,
-                                 mng_int32  iLocax,
-                                 mng_int32  iLocay)
-#else
-mng_retcode mng_create_ani_move (mng_datap  pData,
-                                 mng_chunkp pChunk)
-#endif
-{
-  mng_ani_movep pMOVE;
-  mng_retcode   iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_MOVE, MNG_LC_START);
-#endif
-
-  if (pData->bCacheplayback)           /* caching playback info ? */
-  {
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-    mng_ptr pTemp;
-    iRetcode = create_obj_general (pData, sizeof (mng_ani_move),
-                                   mng_free_obj_general,
-                                   mng_process_ani_move,
-                                   &pTemp);
-    if (iRetcode)
-      return iRetcode;
-    pMOVE = (mng_ani_movep)pTemp;
-#else
-    MNG_ALLOC (pData, pMOVE, sizeof (mng_ani_move));
-
-    pMOVE->sHeader.fCleanup = mng_free_ani_move;
-    pMOVE->sHeader.fProcess = mng_process_ani_move;
-#endif
-
-    mng_add_ani_object (pData, (mng_object_headerp)pMOVE);
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-    pMOVE->iFirstid = iFirstid;
-    pMOVE->iLastid  = iLastid;
-    pMOVE->iType    = iType;
-    pMOVE->iLocax   = iLocax;
-    pMOVE->iLocay   = iLocay;
-#else
-    pMOVE->iFirstid = ((mng_movep)pChunk)->iFirstid;
-    pMOVE->iLastid  = ((mng_movep)pChunk)->iLastid;
-    pMOVE->iType    = ((mng_movep)pChunk)->iMovetype;
-    pMOVE->iLocax   = ((mng_movep)pChunk)->iMovex;
-    pMOVE->iLocay   = ((mng_movep)pChunk)->iMovey;
-#endif
-  }
-
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  iRetcode = mng_process_display_move (pData, iFirstid, iLastid,
-                                       iType, iLocax, iLocay);
-#else
-  iRetcode = mng_process_display_move (pData,
-                                       ((mng_movep)pChunk)->iFirstid,
-                                       ((mng_movep)pChunk)->iLastid,
-                                       ((mng_movep)pChunk)->iMovetype,
-                                       ((mng_movep)pChunk)->iMovex,
-                                       ((mng_movep)pChunk)->iMovey);
-#endif
-#else
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  pData->iMOVEfromid   = iFirstid;
-  pData->iMOVEtoid     = iLastid;
-  pData->iMOVEmovetype = iType;
-  pData->iMOVEmovex    = iLocax;
-  pData->iMOVEmovey    = iLocay;
-#else
-  pData->iMOVEfromid   = ((mng_movep)pChunk)->iFirstid;
-  pData->iMOVEtoid     = ((mng_movep)pChunk)->iLastid;
-  pData->iMOVEmovetype = ((mng_movep)pChunk)->iMovetype;
-  pData->iMOVEmovex    = ((mng_movep)pChunk)->iMovex;
-  pData->iMOVEmovey    = ((mng_movep)pChunk)->iMovey;
-#endif
-
-  iRetcode = mng_process_display_move (pData);
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_MOVE, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_OBJCLEANUP
-mng_retcode mng_free_ani_move (mng_datap   pData,
-                               mng_objectp pObject)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_MOVE, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pObject, sizeof (mng_ani_move));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_MOVE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_ani_move (mng_datap   pData,
-                                  mng_objectp pObject)
-{
-  mng_retcode   iRetcode;
-  mng_ani_movep pMOVE = (mng_ani_movep)pObject;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_MOVE, MNG_LC_START);
-#endif
-                                       /* re-process the MOVE chunk */
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-  iRetcode = mng_process_display_move (pData, pMOVE->iFirstid, pMOVE->iLastid,
-                                       pMOVE->iType, pMOVE->iLocax, pMOVE->iLocay);
-#else
-  pData->iMOVEfromid   = pMOVE->iFirstid;
-  pData->iMOVEtoid     = pMOVE->iLastid;
-  pData->iMOVEmovetype = pMOVE->iType;
-  pData->iMOVEmovex    = pMOVE->iLocax;
-  pData->iMOVEmovey    = pMOVE->iLocay;
-
-  iRetcode = mng_process_display_move (pData);
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_MOVE, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_CLIP
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-mng_retcode mng_create_ani_clip (mng_datap  pData,
-                                 mng_uint16 iFirstid,
-                                 mng_uint16 iLastid,
-                                 mng_uint8  iType,
-                                 mng_int32  iClipl,
-                                 mng_int32  iClipr,
-                                 mng_int32  iClipt,
-                                 mng_int32  iClipb)
-#else
-mng_retcode mng_create_ani_clip (mng_datap  pData,
-                                 mng_chunkp pChunk)
-#endif
-{
-  mng_ani_clipp pCLIP;
-  mng_retcode   iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_CLIP, MNG_LC_START);
-#endif
-
-  if (pData->bCacheplayback)           /* caching playback info ? */
-  {
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-    mng_ptr pTemp;
-    iRetcode = create_obj_general (pData, sizeof (mng_ani_clip),
-                                   mng_free_obj_general,
-                                   mng_process_ani_clip,
-                                   &pTemp);
-    if (iRetcode)
-      return iRetcode;
-    pCLIP = (mng_ani_clipp)pTemp;
-#else
-    MNG_ALLOC (pData, pCLIP, sizeof (mng_ani_clip));
-
-    pCLIP->sHeader.fCleanup = mng_free_ani_clip;
-    pCLIP->sHeader.fProcess = mng_process_ani_clip;
-#endif
-
-    mng_add_ani_object (pData, (mng_object_headerp)pCLIP);
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-    pCLIP->iFirstid = iFirstid;
-    pCLIP->iLastid  = iLastid;
-    pCLIP->iType    = iType;
-    pCLIP->iClipl   = iClipl;
-    pCLIP->iClipr   = iClipr;
-    pCLIP->iClipt   = iClipt;
-    pCLIP->iClipb   = iClipb;
-#else
-    pCLIP->iFirstid = ((mng_clipp)pChunk)->iFirstid;
-    pCLIP->iLastid  = ((mng_clipp)pChunk)->iLastid;
-    pCLIP->iType    = ((mng_clipp)pChunk)->iCliptype;
-    pCLIP->iClipl   = ((mng_clipp)pChunk)->iClipl;
-    pCLIP->iClipr   = ((mng_clipp)pChunk)->iClipr;
-    pCLIP->iClipt   = ((mng_clipp)pChunk)->iClipt;
-    pCLIP->iClipb   = ((mng_clipp)pChunk)->iClipb;
-#endif
-  }
-
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  iRetcode = mng_process_display_clip (pData, iFirstid, iLastid,
-                                       iType, iClipl, iClipr,
-                                       iClipt, iClipb);
-#else
-  iRetcode = mng_process_display_clip (pData,
-                                       ((mng_clipp)pChunk)->iFirstid,
-                                       ((mng_clipp)pChunk)->iLastid,
-                                       ((mng_clipp)pChunk)->iCliptype,
-                                       ((mng_clipp)pChunk)->iClipl,
-                                       ((mng_clipp)pChunk)->iClipr,
-                                       ((mng_clipp)pChunk)->iClipt,
-                                       ((mng_clipp)pChunk)->iClipb);
-#endif
-#else
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  pData->iCLIPfromid   = iFirstid;
-  pData->iCLIPtoid     = iLastid;
-  pData->iCLIPcliptype = iType;
-  pData->iCLIPclipl    = iClipl;
-  pData->iCLIPclipr    = iClipr;
-  pData->iCLIPclipt    = iClipt;
-  pData->iCLIPclipb    = iClipb;
-#else
-  pData->iCLIPfromid   = ((mng_clipp)pChunk)->iFirstid;
-  pData->iCLIPtoid     = ((mng_clipp)pChunk)->iLastid;
-  pData->iCLIPcliptype = ((mng_clipp)pChunk)->iCliptype;
-  pData->iCLIPclipl    = ((mng_clipp)pChunk)->iClipl;
-  pData->iCLIPclipr    = ((mng_clipp)pChunk)->iClipr;
-  pData->iCLIPclipt    = ((mng_clipp)pChunk)->iClipt;
-  pData->iCLIPclipb    = ((mng_clipp)pChunk)->iClipb;
-#endif
-
-  iRetcode = mng_process_display_clip (pData);
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_CLIP, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_OBJCLEANUP
-mng_retcode mng_free_ani_clip (mng_datap   pData,
-                               mng_objectp pObject)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_CLIP, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pObject, sizeof (mng_ani_clip));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_CLIP, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_ani_clip (mng_datap   pData,
-                                  mng_objectp pObject)
-{
-  mng_retcode   iRetcode;
-  mng_ani_clipp pCLIP = (mng_ani_clipp)pObject;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_CLIP, MNG_LC_START);
-#endif
-                                       /* re-process the CLIP chunk */
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-  iRetcode = mng_process_display_clip (pData, pCLIP->iFirstid, pCLIP->iLastid,
-                                       pCLIP->iType, pCLIP->iClipl, pCLIP->iClipr,
-                                       pCLIP->iClipt, pCLIP->iClipb);
-#else
-  pData->iCLIPfromid   = pCLIP->iFirstid;
-  pData->iCLIPtoid     = pCLIP->iLastid;
-  pData->iCLIPcliptype = pCLIP->iType;
-  pData->iCLIPclipl    = pCLIP->iClipl;
-  pData->iCLIPclipr    = pCLIP->iClipr;
-  pData->iCLIPclipt    = pCLIP->iClipt;
-  pData->iCLIPclipb    = pCLIP->iClipb;
-
-  iRetcode = mng_process_display_clip (pData);
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_CLIP, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_SHOW
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-mng_retcode mng_create_ani_show (mng_datap  pData,
-                                 mng_uint16 iFirstid,
-                                 mng_uint16 iLastid,
-                                 mng_uint8  iMode)
-#else
-mng_retcode mng_create_ani_show (mng_datap  pData)
-#endif
-{
-  mng_ani_showp pSHOW;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_SHOW, MNG_LC_START);
-#endif
-
-  if (pData->bCacheplayback)           /* caching playback info ? */
-  {
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-    mng_ptr     pTemp;
-    mng_retcode iRetcode = create_obj_general (pData, sizeof (mng_ani_show),
-                                               mng_free_obj_general,
-                                               mng_process_ani_show,
-                                               &pTemp);
-    if (iRetcode)
-      return iRetcode;
-    pSHOW = (mng_ani_showp)pTemp;
-#else
-    MNG_ALLOC (pData, pSHOW, sizeof (mng_ani_show));
-
-    pSHOW->sHeader.fCleanup = mng_free_ani_show;
-    pSHOW->sHeader.fProcess = mng_process_ani_show;
-#endif
-
-    mng_add_ani_object (pData, (mng_object_headerp)pSHOW);
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-    pSHOW->iFirstid = iFirstid;
-    pSHOW->iLastid  = iLastid;
-    pSHOW->iMode    = iMode;
-#else
-    pSHOW->iFirstid = pData->iSHOWfromid;
-    pSHOW->iLastid  = pData->iSHOWtoid;
-    pSHOW->iMode    = pData->iSHOWmode;
-#endif
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_SHOW, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_OBJCLEANUP
-mng_retcode mng_free_ani_show (mng_datap   pData,
-                               mng_objectp pObject)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_SHOW, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pObject, sizeof (mng_ani_show));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_SHOW, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_ani_show (mng_datap   pData,
-                                  mng_objectp pObject)
-{
-  mng_retcode   iRetcode;
-  mng_ani_showp pSHOW = (mng_ani_showp)pObject;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_SHOW, MNG_LC_START);
-#endif
-
-  if (pData->iBreakpoint)              /* returning from breakpoint ? */
-  {
-    iRetcode           = mng_process_display_show (pData);
-  }
-  else
-  {                                    /* "re-run" SHOW chunk */
-    pData->iSHOWmode   = pSHOW->iMode;
-    pData->iSHOWfromid = pSHOW->iFirstid;
-    pData->iSHOWtoid   = pSHOW->iLastid;
-
-    iRetcode           = mng_process_display_show (pData);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_SHOW, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_TERM
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-mng_retcode mng_create_ani_term (mng_datap  pData,
-                                 mng_uint8  iTermaction,
-                                 mng_uint8  iIteraction,
-                                 mng_uint32 iDelay,
-                                 mng_uint32 iItermax)
-#else
-mng_retcode mng_create_ani_term (mng_datap  pData,
-                                 mng_chunkp pChunk)
-#endif
-{
-  mng_ani_termp pTERM;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_TERM, MNG_LC_START);
-#endif
-
-  if (pData->bCacheplayback)           /* caching playback info ? */
-  {
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-    mng_ptr     pTemp;
-    mng_retcode iRetcode = create_obj_general (pData, sizeof (mng_ani_term),
-                                               mng_free_obj_general,
-                                               mng_process_ani_term,
-                                               &pTemp);
-    if (iRetcode)
-      return iRetcode;
-    pTERM = (mng_ani_termp)pTemp;
-#else
-    MNG_ALLOC (pData, pTERM, sizeof (mng_ani_term));
-
-    pTERM->sHeader.fCleanup = mng_free_ani_term;
-    pTERM->sHeader.fProcess = mng_process_ani_term;
-#endif
-
-    mng_add_ani_object (pData, (mng_object_headerp)pTERM);
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-    pTERM->iTermaction = iTermaction;
-    pTERM->iIteraction = iIteraction;
-    pTERM->iDelay      = iDelay;
-    pTERM->iItermax    = iItermax;
-#else
-    pTERM->iTermaction = ((mng_termp)pChunk)->iTermaction;
-    pTERM->iIteraction = ((mng_termp)pChunk)->iIteraction;
-    pTERM->iDelay      = ((mng_termp)pChunk)->iDelay;
-    pTERM->iItermax    = ((mng_termp)pChunk)->iItermax;
-#endif
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_TERM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_OBJCLEANUP
-mng_retcode mng_free_ani_term (mng_datap   pData,
-                               mng_objectp pObject)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_TERM, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pObject, sizeof (mng_ani_term));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_TERM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_ani_term (mng_datap   pData,
-                                  mng_objectp pObject)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_TERM, MNG_LC_START);
-#endif
-
-  /* dummy: no action required! */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_TERM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_SAVE
-mng_retcode mng_create_ani_save (mng_datap pData)
-{
-  mng_ptr       pTemp;
-  mng_ani_savep pSAVE;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_SAVE, MNG_LC_START);
-#endif
-
-  if (pData->bCacheplayback)           /* caching playback info ? */
-  {
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-    mng_retcode iRetcode = create_obj_general (pData, sizeof (mng_ani_save),
-                                               mng_free_obj_general,
-                                               mng_process_ani_save,
-                                               &pTemp);
-    if (iRetcode)
-      return iRetcode;
-    pSAVE = (mng_ani_savep)pTemp;
-#else
-    MNG_ALLOC (pData, pSAVE, sizeof (mng_ani_save));
-
-    pSAVE->sHeader.fCleanup = mng_free_ani_save;
-    pSAVE->sHeader.fProcess = mng_process_ani_save;
-#endif
-
-    mng_add_ani_object (pData, (mng_object_headerp)pSAVE);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_SAVE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_OBJCLEANUP
-mng_retcode mng_free_ani_save (mng_datap   pData,
-                               mng_objectp pObject)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_SAVE, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pObject, sizeof (mng_ani_save));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_SAVE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_ani_save (mng_datap   pData,
-                                  mng_objectp pObject)
-{
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_SAVE, MNG_LC_START);
-#endif
-
-  iRetcode = mng_process_display_save (pData);
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_SAVE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_SEEK
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-mng_retcode mng_create_ani_seek (mng_datap  pData,
-                                 mng_uint32 iSegmentnamesize,
-                                 mng_pchar  zSegmentname)
-#else
-mng_retcode mng_create_ani_seek (mng_datap  pData,
-                                 mng_chunkp pChunk)
-#endif
-{
-  mng_ptr       pTemp;
-  mng_ani_seekp pSEEK;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_SEEK, MNG_LC_START);
-#endif
-
-  if (pData->bCacheplayback)           /* caching playback info ? */
-  {
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-    mng_retcode iRetcode = create_obj_general (pData, sizeof (mng_ani_seek),
-                                               mng_free_ani_seek,
-                                               mng_process_ani_seek,
-                                               &pTemp);
-    if (iRetcode)
-      return iRetcode;
-    pSEEK = (mng_ani_seekp)pTemp;
-#else
-    MNG_ALLOC (pData, pSEEK, sizeof (mng_ani_seek));
-
-    pSEEK->sHeader.fCleanup = mng_free_ani_seek;
-    pSEEK->sHeader.fProcess = mng_process_ani_seek;
-#endif
-
-    mng_add_ani_object (pData, (mng_object_headerp)pSEEK);
-
-    pData->pLastseek = (mng_objectp)pSEEK;
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-    pSEEK->iSegmentnamesize = iSegmentnamesize;
-    if (iSegmentnamesize)
-    {
-      MNG_ALLOC (pData, pSEEK->zSegmentname, iSegmentnamesize + 1);
-      MNG_COPY (pSEEK->zSegmentname, zSegmentname, iSegmentnamesize);
-    }
-#else
-    pSEEK->iSegmentnamesize = ((mng_seekp)pChunk)->iNamesize;
-    if (pSEEK->iSegmentnamesize)
-    {
-      MNG_ALLOC (pData, pSEEK->zSegmentname, pSEEK->iSegmentnamesize + 1);
-      MNG_COPY (pSEEK->zSegmentname, ((mng_seekp)pChunk)->zName, pSEEK->iSegmentnamesize);
-    }
-#endif
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_SEEK, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_free_ani_seek (mng_datap   pData,
-                               mng_objectp pObject)
-{
-  mng_ani_seekp pSEEK = (mng_ani_seekp)pObject;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_SEEK, MNG_LC_START);
-#endif
-
-  if (pSEEK->iSegmentnamesize)
-    MNG_FREEX (pData, pSEEK->zSegmentname, pSEEK->iSegmentnamesize + 1);
-
-#ifndef MNG_OPTIMIZE_OBJCLEANUP
-  MNG_FREEX (pData, pObject, sizeof (mng_ani_seek));
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_SEEK, MNG_LC_END);
-#endif
-
-#ifndef MNG_OPTIMIZE_OBJCLEANUP
-  return MNG_NOERROR;
-#else
-  return mng_free_obj_general(pData, pObject);
-#endif
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_ani_seek (mng_datap   pData,
-                                  mng_objectp pObject)
-{
-  mng_ani_seekp pSEEK = (mng_ani_seekp)pObject;
-  mng_retcode   iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_SEEK, MNG_LC_START);
-#endif
-
-#ifdef MNG_SUPPORT_DYNAMICMNG
-  if (!pData->bStopafterseek)          /* can we really process this one ? */
-#endif  
-  {
-    pData->pLastseek = pObject;
-
-    if (pData->fProcessseek)           /* inform the app ? */
-    {
-      mng_bool  bOke;
-      mng_pchar zName;
-
-      MNG_ALLOC (pData, zName, pSEEK->iSegmentnamesize + 1);
-
-      if (pSEEK->iSegmentnamesize)
-        MNG_COPY (zName, pSEEK->zSegmentname, pSEEK->iSegmentnamesize);
-
-      bOke = pData->fProcessseek ((mng_handle)pData, zName);
-
-      MNG_FREEX (pData, zName, pSEEK->iSegmentnamesize + 1);
-
-      if (!bOke)
-        MNG_ERROR (pData, MNG_APPMISCERROR);
-    }
-  }
-
-  iRetcode = mng_process_display_seek (pData);
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_SEEK, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-mng_retcode mng_create_ani_dhdr (mng_datap  pData,
-                                 mng_uint16 iObjectid,
-                                 mng_uint8  iImagetype,
-                                 mng_uint8  iDeltatype,
-                                 mng_uint32 iBlockwidth,
-                                 mng_uint32 iBlockheight,
-                                 mng_uint32 iBlockx,
-                                 mng_uint32 iBlocky)
-#else
-mng_retcode mng_create_ani_dhdr (mng_datap  pData,
-                                 mng_chunkp pChunk)
-#endif
-{
-  mng_ani_dhdrp pDHDR;
-  mng_retcode   iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_DHDR, MNG_LC_START);
-#endif
-
-  if (pData->bCacheplayback)           /* caching playback info ? */
-  {
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-    mng_ptr pTemp;
-    iRetcode = create_obj_general (pData, sizeof (mng_ani_dhdr),
-                                   mng_free_obj_general,
-                                   mng_process_ani_dhdr,
-                                   &pTemp);
-    if (iRetcode)
-      return iRetcode;
-    pDHDR = (mng_ani_dhdrp)pTemp;
-#else
-    MNG_ALLOC (pData, pDHDR, sizeof (mng_ani_dhdr));
-
-    pDHDR->sHeader.fCleanup = mng_free_ani_dhdr;
-    pDHDR->sHeader.fProcess = mng_process_ani_dhdr;
-#endif
-
-    mng_add_ani_object (pData, (mng_object_headerp)pDHDR);
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-    pDHDR->iObjectid    = iObjectid;
-    pDHDR->iImagetype   = iImagetype;
-    pDHDR->iDeltatype   = iDeltatype;
-    pDHDR->iBlockwidth  = iBlockwidth;
-    pDHDR->iBlockheight = iBlockheight;
-    pDHDR->iBlockx      = iBlockx;
-    pDHDR->iBlocky      = iBlocky;
-#else
-    pDHDR->iObjectid    = ((mng_dhdrp)pChunk)->iObjectid;
-    pDHDR->iImagetype   = ((mng_dhdrp)pChunk)->iImagetype;
-    pDHDR->iDeltatype   = ((mng_dhdrp)pChunk)->iDeltatype;
-    pDHDR->iBlockwidth  = ((mng_dhdrp)pChunk)->iBlockwidth;
-    pDHDR->iBlockheight = ((mng_dhdrp)pChunk)->iBlockheight;
-    pDHDR->iBlockx      = ((mng_dhdrp)pChunk)->iBlockx;
-    pDHDR->iBlocky      = ((mng_dhdrp)pChunk)->iBlocky;
-#endif
-  }
-
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  iRetcode = mng_process_display_dhdr (pData, iObjectid,
-                                       iImagetype, iDeltatype,
-                                       iBlockwidth, iBlockheight,
-                                       iBlockx, iBlocky);
-#else
-  iRetcode = mng_process_display_dhdr (pData,
-                                       ((mng_dhdrp)pChunk)->iObjectid,
-                                       ((mng_dhdrp)pChunk)->iImagetype,
-                                       ((mng_dhdrp)pChunk)->iDeltatype,
-                                       ((mng_dhdrp)pChunk)->iBlockwidth,
-                                       ((mng_dhdrp)pChunk)->iBlockheight,
-                                       ((mng_dhdrp)pChunk)->iBlockx,
-                                       ((mng_dhdrp)pChunk)->iBlocky);
-#endif
-#else
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  pData->iDHDRobjectid    = iObjectid;
-  pData->iDHDRimagetype   = iImagetype;
-  pData->iDHDRdeltatype   = iDeltatype;
-  pData->iDHDRblockwidth  = iBlockwidth;
-  pData->iDHDRblockheight = iBlockheight;
-  pData->iDHDRblockx      = iBlockx;
-  pData->iDHDRblocky      = iBlocky;
-#else
-  pData->iDHDRobjectid    = ((mng_dhdrp)pChunk)->iObjectid;
-  pData->iDHDRimagetype   = ((mng_dhdrp)pChunk)->iImagetype;
-  pData->iDHDRdeltatype   = ((mng_dhdrp)pChunk)->iDeltatype;
-  pData->iDHDRblockwidth  = ((mng_dhdrp)pChunk)->iBlockwidth;
-  pData->iDHDRblockheight = ((mng_dhdrp)pChunk)->iBlockheight;
-  pData->iDHDRblockx      = ((mng_dhdrp)pChunk)->iBlockx;
-  pData->iDHDRblocky      = ((mng_dhdrp)pChunk)->iBlocky;
-#endif
-
-  iRetcode = mng_process_display_dhdr (pData);
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_DHDR, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_OBJCLEANUP
-mng_retcode mng_free_ani_dhdr (mng_datap   pData,
-                               mng_objectp pObject)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_DHDR, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pObject, sizeof (mng_ani_dhdr));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_DHDR, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_ani_dhdr (mng_datap   pData,
-                                  mng_objectp pObject)
-{
-  mng_ani_dhdrp pDHDR = (mng_ani_dhdrp)pObject;
-  mng_retcode   iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_DHDR, MNG_LC_START);
-#endif
-
-  pData->bHasDHDR = MNG_TRUE;          /* let everyone know we're inside a DHDR */
-
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-  iRetcode = mng_process_display_dhdr (pData, pDHDR->iObjectid,
-                                       pDHDR->iImagetype, pDHDR->iDeltatype,
-                                       pDHDR->iBlockwidth, pDHDR->iBlockheight,
-                                       pDHDR->iBlockx, pDHDR->iBlocky);
-#else
-  pData->iDHDRobjectid    = pDHDR->iObjectid;
-  pData->iDHDRimagetype   = pDHDR->iImagetype;
-  pData->iDHDRdeltatype   = pDHDR->iDeltatype;
-  pData->iDHDRblockwidth  = pDHDR->iBlockwidth;
-  pData->iDHDRblockheight = pDHDR->iBlockheight;
-  pData->iDHDRblockx      = pDHDR->iBlockx;
-  pData->iDHDRblocky      = pDHDR->iBlocky;
-
-  iRetcode = mng_process_display_dhdr (pData);
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_DHDR, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-mng_retcode mng_create_ani_prom (mng_datap pData,
-                                 mng_uint8 iBitdepth,
-                                 mng_uint8 iColortype,
-                                 mng_uint8 iFilltype)
-#else
-mng_retcode mng_create_ani_prom (mng_datap pData,
-                                 mng_chunkp pChunk)
-#endif
-{
-  mng_ani_promp pPROM=NULL;
-  mng_retcode   iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_PROM, MNG_LC_START);
-#endif
-
-  if (pData->bCacheplayback)           /* caching playback info ? */
-  {
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-    mng_ptr pTemp;
-    iRetcode = create_obj_general (pData, sizeof (mng_ani_prom),
-                                   mng_free_obj_general,
-                                   mng_process_ani_prom,
-                                   &pTemp);
-    if (iRetcode)
-      return iRetcode;
-    pPROM = (mng_ani_promp)pTemp;
-#else
-    MNG_ALLOC (pData, pPROM, sizeof (mng_ani_prom));
-
-    pPROM->sHeader.fCleanup = mng_free_ani_prom;
-    pPROM->sHeader.fProcess = mng_process_ani_prom;
-#endif
-
-    mng_add_ani_object (pData, (mng_object_headerp)pPROM);
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-    pPROM->iBitdepth  = iBitdepth;
-    pPROM->iColortype = iColortype;
-    pPROM->iFilltype  = iFilltype;
-#else
-    pPROM->iBitdepth  = ((mng_promp)pChunk)->iSampledepth;
-    pPROM->iColortype = ((mng_promp)pChunk)->iColortype;
-    pPROM->iFilltype  = ((mng_promp)pChunk)->iFilltype;
-#endif
-  }
-
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  iRetcode = mng_process_display_prom (pData, iBitdepth,
-                                       iColortype, iFilltype);
-#else
-  iRetcode = mng_process_display_prom (pData,
-                                       ((mng_promp)pChunk)->iSampledepth,
-                                       ((mng_promp)pChunk)->iColortype,
-                                       ((mng_promp)pChunk)->iFilltype);
-#endif
-#else
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  pData->iPROMbitdepth  = iBitdepth;
-  pData->iPROMcolortype = iColortype;
-  pData->iPROMfilltype  = iFilltype;
-#else
-  pData->iPROMbitdepth  = ((mng_promp)pChunk)->iSampledepth;
-  pData->iPROMcolortype = ((mng_promp)pChunk)->iColortype;
-  pData->iPROMfilltype  = ((mng_promp)pChunk)->iFilltype;
-#endif
-
-  iRetcode = mng_process_display_prom (pData);
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_PROM, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_OBJCLEANUP
-mng_retcode mng_free_ani_prom (mng_datap   pData,
-                               mng_objectp pObject)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_PROM, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pObject, sizeof (mng_ani_prom));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_PROM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_ani_prom (mng_datap   pData,
-                                  mng_objectp pObject)
-{
-  mng_ani_promp pPROM = (mng_ani_promp)pObject;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_PROM, MNG_LC_START);
-#endif
-
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-  iRetcode = mng_process_display_prom (pData, pPROM->iBitdepth,
-                                       pPROM->iColortype, pPROM->iFilltype);
-#else
-  pData->iPROMbitdepth  = pPROM->iBitdepth;
-  pData->iPROMcolortype = pPROM->iColortype;
-  pData->iPROMfilltype  = pPROM->iFilltype;
-
-  iRetcode = mng_process_display_prom (pData);
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_PROM, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-mng_retcode mng_create_ani_ipng (mng_datap pData)
-{
-  mng_ani_ipngp pIPNG;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_IPNG, MNG_LC_START);
-#endif
-
-  if (pData->bCacheplayback)           /* caching playback info ? */
-  {
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-    mng_ptr     pTemp;
-    mng_retcode iRetcode = create_obj_general (pData, sizeof (mng_ani_ipng),
-                                               mng_free_obj_general,
-                                               mng_process_ani_ipng,
-                                               &pTemp);
-    if (iRetcode)
-      return iRetcode;
-    pIPNG = (mng_ani_ipngp)pTemp;
-#else
-    MNG_ALLOC (pData, pIPNG, sizeof (mng_ani_ipng));
-
-    pIPNG->sHeader.fCleanup = mng_free_ani_ipng;
-    pIPNG->sHeader.fProcess = mng_process_ani_ipng;
-#endif
-
-    mng_add_ani_object (pData, (mng_object_headerp)pIPNG);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_IPNG, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_OBJCLEANUP
-mng_retcode mng_free_ani_ipng (mng_datap   pData,
-                               mng_objectp pObject)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_IPNG, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pObject, sizeof (mng_ani_ipng));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_IPNG, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_ani_ipng (mng_datap   pData,
-                                  mng_objectp pObject)
-{
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_IPNG, MNG_LC_START);
-#endif
-
-  iRetcode = mng_process_display_ipng (pData);
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_IPNG, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-#ifdef MNG_INCLUDE_JNG
-mng_retcode mng_create_ani_ijng (mng_datap pData)
-{
-  mng_ani_ijngp pIJNG;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_IJNG, MNG_LC_START);
-#endif
-
-  if (pData->bCacheplayback)           /* caching playback info ? */
-  {
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-    mng_ptr     pTemp;
-    mng_retcode iRetcode = create_obj_general (pData, sizeof (mng_ani_ijng),
-                                               mng_free_obj_general,
-                                               mng_process_ani_ijng,
-                                               &pTemp);
-    if (iRetcode)
-      return iRetcode;
-    pIJNG = (mng_ani_ijngp)pTemp;
-#else
-    MNG_ALLOC (pData, pIJNG, sizeof (mng_ani_ijng));
-
-    pIJNG->sHeader.fCleanup = mng_free_ani_ijng;
-    pIJNG->sHeader.fProcess = mng_process_ani_ijng;
-#endif
-
-    mng_add_ani_object (pData, (mng_object_headerp)pIJNG);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_IJNG, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_OBJCLEANUP
-mng_retcode mng_free_ani_ijng (mng_datap   pData,
-                               mng_objectp pObject)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_IJNG, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pObject, sizeof (mng_ani_ijng));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_IJNG, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_ani_ijng (mng_datap   pData,
-                                  mng_objectp pObject)
-{
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_IJNG, MNG_LC_START);
-#endif
-
-  iRetcode = mng_process_display_ijng (pData);
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_IJNG, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-mng_retcode mng_create_ani_pplt (mng_datap      pData,
-                                 mng_uint8      iType,
-                                 mng_uint32     iCount,
-                                 mng_palette8ep paIndexentries,
-                                 mng_uint8p     paAlphaentries,
-                                 mng_uint8p     paUsedentries)
-{
-  mng_ani_ppltp pPPLT;
-  mng_retcode   iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_PPLT, MNG_LC_START);
-#endif
-
-  if (pData->bCacheplayback)           /* caching playback info ? */
-  {
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-    mng_ptr pTemp;
-    iRetcode = create_obj_general (pData, sizeof (mng_ani_pplt),
-                                   mng_free_obj_general,
-                                   mng_process_ani_pplt,
-                                   &pTemp);
-    if (iRetcode)
-      return iRetcode;
-    pPPLT = (mng_ani_ppltp)pTemp;
-#else
-    MNG_ALLOC (pData, pPPLT, sizeof (mng_ani_pplt));
-
-    pPPLT->sHeader.fCleanup = mng_free_ani_pplt;
-    pPPLT->sHeader.fProcess = mng_process_ani_pplt;
-#endif
-
-    pPPLT->iType            = iType;
-    pPPLT->iCount           = iCount;
-
-    MNG_COPY (pPPLT->aIndexentries, paIndexentries, sizeof (pPPLT->aIndexentries));
-    MNG_COPY (pPPLT->aAlphaentries, paAlphaentries, sizeof (pPPLT->aAlphaentries));
-    MNG_COPY (pPPLT->aUsedentries,  paUsedentries,  sizeof (pPPLT->aUsedentries ));
-
-    mng_add_ani_object (pData, (mng_object_headerp)pPPLT);
-  }
-
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-  iRetcode = mng_process_display_pplt (pData, iType, iCount,
-                                       paIndexentries, paAlphaentries, paUsedentries);
-#else
-  pData->iPPLTtype          = iType;
-  pData->iPPLTcount         = iCount;
-  pData->paPPLTindexentries = paIndexentries;
-  pData->paPPLTalphaentries = paAlphaentries;
-  pData->paPPLTusedentries  = paUsedentries;
-
-  iRetcode = mng_process_display_pplt (pData);
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_PPLT, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_OBJCLEANUP
-mng_retcode mng_free_ani_pplt (mng_datap   pData,
-                               mng_objectp pObject)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_PPLT, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pObject, sizeof (mng_ani_pplt));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_PPLT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_ani_pplt (mng_datap   pData,
-                                  mng_objectp pObject)
-{
-  mng_ani_ppltp pPPLT = (mng_ani_ppltp)pObject;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_PPLT, MNG_LC_START);
-#endif
-
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-  iRetcode = mng_process_display_pplt (pData, pPPLT->iType, pPPLT->iCount,
-                                       pPPLT->aIndexentries, pPPLT->aAlphaentries,
-                                       pPPLT->aUsedentries);
-#else
-  pData->iPPLTtype          = pPPLT->iType;
-  pData->iPPLTcount         = pPPLT->iCount;
-  pData->paPPLTindexentries = &pPPLT->aIndexentries;
-  pData->paPPLTalphaentries = &pPPLT->aAlphaentries;
-  pData->paPPLTusedentries  = &pPPLT->aUsedentries;
-
-  iRetcode = mng_process_display_pplt (pData);
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_PPLT, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_MAGN
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-mng_retcode mng_create_ani_magn (mng_datap  pData,
-                                 mng_uint16 iFirstid,
-                                 mng_uint16 iLastid,
-                                 mng_uint8  iMethodX,
-                                 mng_uint16 iMX,
-                                 mng_uint16 iMY,
-                                 mng_uint16 iML,
-                                 mng_uint16 iMR,
-                                 mng_uint16 iMT,
-                                 mng_uint16 iMB,
-                                 mng_uint8  iMethodY)
-#else
-mng_retcode mng_create_ani_magn (mng_datap  pData,
-                                 mng_chunkp pChunk)
-#endif
-{
-  mng_ani_magnp pMAGN=NULL;
-  mng_retcode   iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_MAGN, MNG_LC_START);
-#endif
-
-  if (pData->bCacheplayback)           /* caching playback info ? */
-  {
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-    mng_ptr pTemp;
-    iRetcode = create_obj_general (pData, sizeof (mng_ani_magn),
-                                   mng_free_obj_general,
-                                   mng_process_ani_magn,
-                                   &pTemp);
-    if (iRetcode)
-      return iRetcode;
-    pMAGN = (mng_ani_magnp)pTemp;
-#else
-    MNG_ALLOC (pData, pMAGN, sizeof (mng_ani_magn));
-
-    pMAGN->sHeader.fCleanup = mng_free_ani_magn;
-    pMAGN->sHeader.fProcess = mng_process_ani_magn;
-#endif
-
-    mng_add_ani_object (pData, (mng_object_headerp)pMAGN);
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-    pMAGN->iFirstid = iFirstid;
-    pMAGN->iLastid  = iLastid;
-    pMAGN->iMethodX = iMethodX;
-    pMAGN->iMX      = iMX;
-    pMAGN->iMY      = iMY;
-    pMAGN->iML      = iML;
-    pMAGN->iMR      = iMR;
-    pMAGN->iMT      = iMT;
-    pMAGN->iMB      = iMB;
-    pMAGN->iMethodY = iMethodY;
-#else
-    pMAGN->iFirstid = ((mng_magnp)pChunk)->iFirstid;
-    pMAGN->iLastid  = ((mng_magnp)pChunk)->iLastid;
-    pMAGN->iMethodX = ((mng_magnp)pChunk)->iMethodX;
-    pMAGN->iMX      = ((mng_magnp)pChunk)->iMX;
-    pMAGN->iMY      = ((mng_magnp)pChunk)->iMY;
-    pMAGN->iML      = ((mng_magnp)pChunk)->iML;
-    pMAGN->iMR      = ((mng_magnp)pChunk)->iMR;
-    pMAGN->iMT      = ((mng_magnp)pChunk)->iMT;
-    pMAGN->iMB      = ((mng_magnp)pChunk)->iMB;
-    pMAGN->iMethodY = ((mng_magnp)pChunk)->iMethodY;
-#endif
-  }
-
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  iRetcode = mng_process_display_magn (pData, pMAGN->iFirstid, pMAGN->iLastid,
-                                       pMAGN->iMethodX, pMAGN->iMX, pMAGN->iMY,
-                                       pMAGN->iML, pMAGN->iMR, pMAGN->iMT,
-                                       pMAGN->iMB, pMAGN->iMethodY);
-#else
-  iRetcode = mng_process_display_magn (pData,
-                                       ((mng_magnp)pChunk)->iFirstid,
-                                       ((mng_magnp)pChunk)->iLastid,
-                                       ((mng_magnp)pChunk)->iMethodX,
-                                       ((mng_magnp)pChunk)->iMX,
-                                       ((mng_magnp)pChunk)->iMY,
-                                       ((mng_magnp)pChunk)->iML,
-                                       ((mng_magnp)pChunk)->iMR,
-                                       ((mng_magnp)pChunk)->iMT,
-                                       ((mng_magnp)pChunk)->iMB,
-                                       ((mng_magnp)pChunk)->iMethodY);
-#endif
-#else
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  pData->iMAGNfirstid = iFirstid;
-  pData->iMAGNlastid  = iLastid;
-  pData->iMAGNmethodX = iMethodX;
-  pData->iMAGNmX      = iMX;
-  pData->iMAGNmY      = iMY;
-  pData->iMAGNmL      = iML;
-  pData->iMAGNmR      = iMR;
-  pData->iMAGNmT      = iMT;
-  pData->iMAGNmB      = iMB;
-  pData->iMAGNmethodY = iMethodY;
-#else
-  pData->iMAGNfirstid = ((mng_magnp)pChunk)->iFirstid;
-  pData->iMAGNlastid  = ((mng_magnp)pChunk)->iLastid;
-  pData->iMAGNmethodX = ((mng_magnp)pChunk)->iMethodX;
-  pData->iMAGNmX      = ((mng_magnp)pChunk)->iMX;
-  pData->iMAGNmY      = ((mng_magnp)pChunk)->iMY;
-  pData->iMAGNmL      = ((mng_magnp)pChunk)->iML;
-  pData->iMAGNmR      = ((mng_magnp)pChunk)->iMR;
-  pData->iMAGNmT      = ((mng_magnp)pChunk)->iMT;
-  pData->iMAGNmB      = ((mng_magnp)pChunk)->iMB;
-  pData->iMAGNmethodY = ((mng_magnp)pChunk)->iMethodY;
-#endif
-
-  iRetcode = mng_process_display_magn (pData);
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_MAGN, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_OBJCLEANUP
-mng_retcode mng_free_ani_magn (mng_datap   pData,
-                               mng_objectp pObject)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_MAGN, MNG_LC_START);
-#endif
-
-  MNG_FREEX (pData, pObject, sizeof (mng_ani_magn));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_MAGN, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_ani_magn (mng_datap   pData,
-                                  mng_objectp pObject)
-{
-  mng_ani_magnp pMAGN = (mng_ani_magnp)pObject;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_MAGN, MNG_LC_START);
-#endif
-
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-  iRetcode = mng_process_display_magn (pData, pMAGN->iFirstid, pMAGN->iLastid,
-                                       pMAGN->iMethodX, pMAGN->iMX, pMAGN->iMY,
-                                       pMAGN->iML, pMAGN->iMR, pMAGN->iMT,
-                                       pMAGN->iMB, pMAGN->iMethodY);
-#else
-  pData->iMAGNfirstid = pMAGN->iFirstid;
-  pData->iMAGNlastid  = pMAGN->iLastid;
-  pData->iMAGNmethodX = pMAGN->iMethodX;
-  pData->iMAGNmX      = pMAGN->iMX;
-  pData->iMAGNmY      = pMAGN->iMY;
-  pData->iMAGNmL      = pMAGN->iML;
-  pData->iMAGNmR      = pMAGN->iMR;
-  pData->iMAGNmT      = pMAGN->iMT;
-  pData->iMAGNmB      = pMAGN->iMB;
-  pData->iMAGNmethodY = pMAGN->iMethodY;
-
-  iRetcode = mng_process_display_magn (pData);
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_MAGN, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_PAST
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-mng_retcode mng_create_ani_past (mng_datap  pData,
-                                 mng_uint16 iTargetid,
-                                 mng_uint8  iTargettype,
-                                 mng_int32  iTargetx,
-                                 mng_int32  iTargety,
-                                 mng_uint32 iCount,
-                                 mng_ptr    pSources)
-#else
-mng_retcode mng_create_ani_past (mng_datap  pData,
-                                 mng_chunkp pChunk)
-#endif
-{
-  mng_ani_pastp pPAST;
-  mng_retcode   iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_PAST, MNG_LC_START);
-#endif
-
-  if (pData->bCacheplayback)           /* caching playback info ? */
-  {
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-    mng_ptr pTemp;
-    iRetcode = create_obj_general (pData, sizeof (mng_ani_past),
-                                   mng_free_ani_past,
-                                   mng_process_ani_past,
-                                   &pTemp);
-    if (iRetcode)
-      return iRetcode;
-    pPAST = (mng_ani_pastp)pTemp;
-#else
-    MNG_ALLOC (pData, pPAST, sizeof (mng_ani_past));
-
-    pPAST->sHeader.fCleanup = mng_free_ani_past;
-    pPAST->sHeader.fProcess = mng_process_ani_past;
-#endif
-
-    mng_add_ani_object (pData, (mng_object_headerp)pPAST);
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-    pPAST->iTargetid   = iTargetid;
-    pPAST->iTargettype = iTargettype;
-    pPAST->iTargetx    = iTargetx;
-    pPAST->iTargety    = iTargety;
-    pPAST->iCount      = iCount;
-
-    if (iCount)
-    {
-      MNG_ALLOC (pData, pPAST->pSources, (iCount * sizeof (mng_past_source)));
-      MNG_COPY (pPAST->pSources, pSources, (iCount * sizeof (mng_past_source)));
-    }
-#else
-    pPAST->iTargetid   = ((mng_pastp)pChunk)->iDestid;
-    pPAST->iTargettype = ((mng_pastp)pChunk)->iTargettype;
-    pPAST->iTargetx    = ((mng_pastp)pChunk)->iTargetx;
-    pPAST->iTargety    = ((mng_pastp)pChunk)->iTargety;
-    pPAST->iCount      = ((mng_pastp)pChunk)->iCount;
-
-    if (pPAST->iCount)
-    {
-      mng_size_t iSize = (mng_size_t)(pPAST->iCount * sizeof (mng_past_source));
-      MNG_ALLOC (pData, pPAST->pSources, iSize);
-      MNG_COPY (pPAST->pSources, ((mng_pastp)pChunk)->pSources, iSize);
-    }
-#endif
-  }
-
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  iRetcode = mng_process_display_past (pData, iTargetid, iTargettype,
-                                       iTargetx, iTargety,
-                                       iCount, pSources);
-#else
-  iRetcode = mng_process_display_past (pData,
-                                       ((mng_pastp)pChunk)->iDestid,
-                                       ((mng_pastp)pChunk)->iTargettype,
-                                       ((mng_pastp)pChunk)->iTargetx,
-                                       ((mng_pastp)pChunk)->iTargety,
-                                       ((mng_pastp)pChunk)->iCount,
-                                       ((mng_pastp)pChunk)->pSources);
-#endif
-#else
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  pData->iPASTtargetid   = iTargetid;
-  pData->iPASTtargettype = iTargettype;
-  pData->iPASTtargetx    = iTargetx;
-  pData->iPASTtargety    = iTargety;
-  pData->iPASTcount      = iCount;
-  pData->pPASTsources    = pSources;
-#else
-  pData->iPASTtargetid   = ((mng_pastp)pChunk)->iDestid;
-  pData->iPASTtargettype = ((mng_pastp)pChunk)->iTargettype;
-  pData->iPASTtargetx    = ((mng_pastp)pChunk)->iTargetx;
-  pData->iPASTtargety    = ((mng_pastp)pChunk)->iTargety;
-  pData->iPASTcount      = ((mng_pastp)pChunk)->iCount;
-  pData->pPASTsources    = ((mng_pastp)pChunk)->pSources;
-#endif
-
-  iRetcode = mng_process_display_past (pData);
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_PAST, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_PAST
-mng_retcode mng_free_ani_past (mng_datap   pData,
-                               mng_objectp pObject)
-{
-  mng_ani_pastp pPAST = (mng_ani_pastp)pObject;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_PAST, MNG_LC_START);
-#endif
-
-  if (pPAST->iCount)
-    MNG_FREEX (pData, pPAST->pSources, (pPAST->iCount * sizeof (mng_past_source)));
-
-#ifndef MNG_OPTIMIZE_OBJCLEANUP
-  MNG_FREEX (pData, pObject, sizeof (mng_ani_past));
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_PAST, MNG_LC_END);
-#endif
-
-#ifndef MNG_OPTIMIZE_OBJCLEANUP
-  return MNG_NOERROR;
-#else
-  return mng_free_obj_general(pData, pObject);
-#endif
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_PAST
-mng_retcode mng_process_ani_past (mng_datap   pData,
-                                  mng_objectp pObject)
-{
-  mng_ani_pastp pPAST = (mng_ani_pastp)pObject;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_PAST, MNG_LC_START);
-#endif
-
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-  iRetcode = mng_process_display_past (pData, pPAST->iTargetid, pPAST->iTargettype,
-                                       pPAST->iTargetx, pPAST->iTargety,
-                                       pPAST->iCount, pPAST->pSources);
-#else
-  pData->iPASTtargetid   = pPAST->iTargetid;
-  pData->iPASTtargettype = pPAST->iTargettype;
-  pData->iPASTtargetx    = pPAST->iTargetx;
-  pData->iPASTtargety    = pPAST->iTargety;
-  pData->iPASTcount      = pPAST->iCount;
-  pData->pPASTsources    = pPAST->pSources;
-
-  iRetcode = mng_process_display_past (pData);
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_PAST, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_DISC
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-mng_retcode mng_create_ani_disc (mng_datap   pData,
-                                 mng_uint32  iCount,
-                                 mng_uint16p pIds)
-#else
-mng_retcode mng_create_ani_disc (mng_datap   pData,
-                                 mng_chunkp  pChunk)
-#endif
-{
-  mng_ani_discp pDISC;
-  mng_retcode   iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_DISC, MNG_LC_START);
-#endif
-
-  if (pData->bCacheplayback)           /* caching playback info ? */
-  {
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-    mng_ptr pTemp;
-    iRetcode = create_obj_general (pData, sizeof (mng_ani_disc),
-                                   mng_free_ani_disc,
-                                   mng_process_ani_disc,
-                                   &pTemp);
-    if (iRetcode)
-      return iRetcode;
-    pDISC = (mng_ani_discp)pTemp;
-#else
-    MNG_ALLOC (pData, pDISC, sizeof (mng_ani_disc));
-
-    pDISC->sHeader.fCleanup = mng_free_ani_disc;
-    pDISC->sHeader.fProcess = mng_process_ani_disc;
-#endif
-
-    mng_add_ani_object (pData, (mng_object_headerp)pDISC);
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-    pDISC->iCount = iCount;
-
-    if (iCount)
-    {
-      MNG_ALLOC (pData, pDISC->pIds, (iCount << 1));
-      MNG_COPY (pDISC->pIds, pIds, (iCount << 1));
-    }
-#else
-    pDISC->iCount = ((mng_discp)pChunk)->iCount;
-
-    if (pDISC->iCount)
-    {
-      mng_size_t iSize = (mng_size_t)(pDISC->iCount << 1);
-      MNG_ALLOC (pData, pDISC->pIds, iSize);
-      MNG_COPY (pDISC->pIds, ((mng_discp)pChunk)->pObjectids, iSize);
-    }
-#endif
-  }
-
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  iRetcode = mng_process_display_disc (pData, iCount, pIds);
-#else
-  iRetcode = mng_process_display_disc (pData,
-                                       ((mng_discp)pChunk)->iCount,
-                                       ((mng_discp)pChunk)->pObjectids);
-#endif
-#else
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  pData->iDISCcount = iCount;
-  pData->pDISCids   = pIds;
-#else
-  pData->iDISCcount = ((mng_discp)pChunk)->iCount;
-  pData->pDISCids   = ((mng_discp)pChunk)->pObjectids;
-#endif
-
-  iRetcode = mng_process_display_disc (pData);
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANI_DISC, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_free_ani_disc (mng_datap   pData,
-                               mng_objectp pObject)
-{
-  mng_ani_discp pDISC = (mng_ani_discp)pObject;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_DISC, MNG_LC_START);
-#endif
-
-  if (pDISC->iCount)
-    MNG_FREEX (pData, pDISC->pIds, (pDISC->iCount << 1));
-
-#ifndef MNG_OPTIMIZE_OBJCLEANUP
-  MNG_FREEX (pData, pObject, sizeof (mng_ani_disc));
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANI_DISC, MNG_LC_END);
-#endif
-
-#ifndef MNG_OPTIMIZE_OBJCLEANUP
-  return MNG_NOERROR;
-#else
-  return mng_free_obj_general(pData, pObject);
-#endif
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_ani_disc (mng_datap   pData,
-                                  mng_objectp pObject)
-{
-  mng_ani_discp pDISC = (mng_ani_discp)pObject;
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_DISC, MNG_LC_START);
-#endif
-
-#ifndef MNG_OPTIMIZE_DISPLAYCALLS
-  iRetcode = mng_process_display_disc (pData, pDISC->iCount, pDISC->pIds);
-#else
-  pData->iDISCcount = pDISC->iCount;
-  pData->pDISCids   = pDISC->pIds;
-
-  iRetcode = mng_process_display_disc (pData);
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANI_DISC, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-#endif
-
-/* ************************************************************************** */
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DYNAMICMNG
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-mng_retcode mng_create_event (mng_datap  pData,
-                              mng_uint8  iEventtype,
-                              mng_uint8  iMasktype,
-                              mng_int32  iLeft,
-                              mng_int32  iRight,
-                              mng_int32  iTop,
-                              mng_int32  iBottom,
-                              mng_uint16 iObjectid,
-                              mng_uint8  iIndex,
-                              mng_uint32 iSegmentnamesize,
-                              mng_pchar  zSegmentname)
-#else
-mng_retcode mng_create_event (mng_datap  pData,
-                              mng_ptr    pEntry)
-#endif
-{
-  mng_eventp pEvent;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_EVENT, MNG_LC_START);
-#endif
-
-  if (pData->bCacheplayback)           /* caching playback info ? */
-  {
-    mng_object_headerp pLast;
-
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-    mng_ptr     pTemp;
-    mng_retcode iRetcode = create_obj_general (pData, sizeof (mng_event),
-                                               mng_free_event,
-                                               mng_process_event,
-                                               &pTemp);
-    if (iRetcode)
-      return iRetcode;
-    pEvent = (mng_eventp)pTemp;
-#else
-    MNG_ALLOC (pData, pEvent, sizeof (mng_event));
-
-    pEvent->sHeader.fCleanup = mng_free_event;
-    pEvent->sHeader.fProcess = mng_process_event;
-#endif
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-    pEvent->iEventtype       = iEventtype;
-    pEvent->iMasktype        = iMasktype;
-    pEvent->iLeft            = iLeft;
-    pEvent->iRight           = iRight;
-    pEvent->iTop             = iTop;
-    pEvent->iBottom          = iBottom;
-    pEvent->iObjectid        = iObjectid;
-    pEvent->iIndex           = iIndex;
-    pEvent->iSegmentnamesize = iSegmentnamesize;
-
-    if (iSegmentnamesize)
-    {
-      MNG_ALLOC (pData, pEvent->zSegmentname, iSegmentnamesize+1);
-      MNG_COPY (pEvent->zSegmentname, zSegmentname, iSegmentnamesize);
-    }
-#else
-    pEvent->iEventtype       = ((mng_evnt_entryp)pEntry)->iEventtype;
-    pEvent->iMasktype        = ((mng_evnt_entryp)pEntry)->iMasktype;
-    pEvent->iLeft            = ((mng_evnt_entryp)pEntry)->iLeft;
-    pEvent->iRight           = ((mng_evnt_entryp)pEntry)->iRight;
-    pEvent->iTop             = ((mng_evnt_entryp)pEntry)->iTop;
-    pEvent->iBottom          = ((mng_evnt_entryp)pEntry)->iBottom;
-    pEvent->iObjectid        = ((mng_evnt_entryp)pEntry)->iObjectid;
-    pEvent->iIndex           = ((mng_evnt_entryp)pEntry)->iIndex;
-    pEvent->iSegmentnamesize = ((mng_evnt_entryp)pEntry)->iSegmentnamesize;
-
-    if (pEvent->iSegmentnamesize)
-    {
-      MNG_ALLOC (pData, pEvent->zSegmentname, pEvent->iSegmentnamesize+1);
-      MNG_COPY (pEvent->zSegmentname, ((mng_evnt_entryp)pEntry)->zSegmentname, pEvent->iSegmentnamesize);
-    }
-#endif
-                                       /* fixup the double-linked list */
-    pLast                    = (mng_object_headerp)pData->pLastevent;
-
-    if (pLast)                         /* link it as last in the chain */
-    {
-      pEvent->sHeader.pPrev  = pLast;
-      pLast->pNext           = pEvent;
-    }
-    else
-    {
-      pData->pFirstevent     = pEvent;
-    }
-
-    pData->pLastevent        = pEvent;
-    pData->bDynamic          = MNG_TRUE;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_EVENT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_free_event (mng_datap   pData,
-                            mng_objectp pObject)
-{
-  mng_eventp pEvent = (mng_eventp)pObject;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_EVENT, MNG_LC_START);
-#endif
-
-  if (pEvent->iSegmentnamesize)
-    MNG_FREEX (pData, pEvent->zSegmentname, pEvent->iSegmentnamesize + 1);
-
-#ifndef MNG_OPTIMIZE_OBJCLEANUP
-  MNG_FREEX (pData, pEvent, sizeof (mng_event));
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_EVENT, MNG_LC_END);
-#endif
-
-#ifndef MNG_OPTIMIZE_OBJCLEANUP
-  return MNG_NOERROR;
-#else
-  return mng_free_obj_general(pData, pObject);
-#endif
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_event (mng_datap   pData,
-                               mng_objectp pObject)
-{
-#ifndef MNG_SKIPCHUNK_SEEK
-  mng_eventp         pEvent  = (mng_eventp)pObject;
-  mng_object_headerp pAni;
-  mng_bool           bFound = MNG_FALSE;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_EVENT, MNG_LC_START);
-#endif
-
-#ifndef MNG_SKIPCHUNK_SEEK
-  if (!pEvent->pSEEK)                  /* need to find SEEK first ? */
-  {
-    pAni = (mng_object_headerp)pData->pFirstaniobj;
-
-    while ((pAni) && (!bFound))
-    {
-      if ((pAni->fCleanup == mng_free_ani_seek) &&
-          (strcmp(pEvent->zSegmentname, ((mng_ani_seekp)pAni)->zSegmentname) == 0))
-        bFound = MNG_TRUE;
-      else
-        pAni = (mng_object_headerp)pAni->pNext;
-    }
-
-    if (pAni)
-      pEvent->pSEEK = (mng_ani_seekp)pAni;
-  }
-
-  if (pEvent->pSEEK)                   /* anything to do ? */
-  {
-    pEvent->iLastx = pData->iEventx;
-    pEvent->iLasty = pData->iEventy;
-                                       /* let's start from this SEEK then */
-    pData->pCurraniobj   = (mng_objectp)pEvent->pSEEK;
-    pData->bRunningevent = MNG_TRUE;
-                                       /* wake-up the app ! */
-    if (!pData->fSettimer ((mng_handle)pData, 5))
-      MNG_ERROR (pData, MNG_APPTIMERERROR);
-
-  }
-  else
-    MNG_ERROR (pData, MNG_SEEKNOTFOUND);
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_EVENT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#endif /* MNG_SUPPORT_DYNAMICMNG */
-
-/* ************************************************************************** */
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-mng_retcode mng_create_mpng_obj (mng_datap  pData,
-                                 mng_uint32 iFramewidth,
-                                 mng_uint32 iFrameheight,
-                                 mng_uint16 iNumplays,
-                                 mng_uint16 iTickspersec,
-                                 mng_uint32 iFramessize,
-                                 mng_ptr    pFrames)
-#else
-mng_retcode mng_create_mpng_obj (mng_datap  pData,
-                                 mng_ptr    pEntry)
-#endif
-{
-  mng_mpng_objp pMPNG;
-  mng_ptr       pTemp;
-  mng_retcode   iRetcode;
-  mng_uint8p    pFrame;
-  mng_int32     iCnt, iMax;
-  mng_uint32    iX, iY, iWidth, iHeight;
-  mng_int32     iXoffset, iYoffset;
-  mng_uint16    iTicks;
-  mng_uint16    iDelay;
-  mng_bool      bNewframe;
-  mng_ani_loopp pLOOP;
-  mng_ani_endlp pENDL;
-  mng_ani_framp pFRAM;
-  mng_ani_movep pMOVE;
-  mng_ani_clipp pCLIP;
-  mng_ani_showp pSHOW;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_MPNG_OBJ, MNG_LC_START);
-#endif
-
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-  iRetcode = create_obj_general (pData, sizeof (mng_mpng_obj), mng_free_mpng_obj,
-                                 mng_process_mpng_obj, &pTemp);
-  if (iRetcode)
-    return iRetcode;
-  pMPNG = (mng_mpng_objp)pTemp;
-#else
-  MNG_ALLOC (pData, pMPNG, sizeof (mng_mpng_obj));
-
-  pMPNG->sHeader.fCleanup = mng_free_mpng_obj;
-  pMPNG->sHeader.fProcess = mng_process_mpng_obj;
-#endif
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  pMPNG->iFramewidth  = iFramewidth;
-  pMPNG->iFrameheight = iFrameheight;
-  pMPNG->iNumplays    = iNumplays;
-  pMPNG->iTickspersec = iTickspersec;
-  pMPNG->iFramessize  = iFramessize;
-
-  if (iFramessize)
-  {
-    MNG_ALLOC (pData, pMPNG->pFrames, iFramessize);
-    MNG_COPY (pMPNG->pFrames, pFrames, iFramessize);
-  }
-#else
-  pMPNG->iFramewidth  = ((mng_mpngp)pEntry)->iFramewidth;
-  pMPNG->iFrameheight = ((mng_mpngp)pEntry)->iFrameheight;
-  pMPNG->iNumplays    = ((mng_mpngp)pEntry)->iNumplays;
-  pMPNG->iTickspersec = ((mng_mpngp)pEntry)->iTickspersec;
-  pMPNG->iFramessize  = ((mng_mpngp)pEntry)->iFramessize;
-
-  if (pMPNG->iFramessize)
-  {
-    MNG_ALLOC (pData, pMPNG->pFrames, pMPNG->iFramessize);
-    MNG_COPY (pMPNG->pFrames, ((mng_mpngp)pEntry)->pFrames, pMPNG->iFramessize);
-  }
-#endif
-
-  pData->pMPNG      = pMPNG;
-  pData->eImagetype = mng_it_mpng;
-
-  iRetcode = mng_process_display_mpng (pData);
-  if (iRetcode)
-    return iRetcode;
-
-  /* now let's create the MNG animation directives from this */
-
-  pFrame = (mng_uint8p)pMPNG->pFrames;
-  iMax   = pMPNG->iFramessize / 26;
-                                       /* set up MNG impersonation */
-  pData->iTicks      = pMPNG->iTickspersec;
-  pData->iLayercount = iMax;
-
-  if (pMPNG->iNumplays != 1)           /* create a LOOP/ENDL pair ? */
-  {
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-    iRetcode = create_obj_general (pData, sizeof (mng_ani_loop),
-                                   mng_free_ani_loop, mng_process_ani_loop,
-                                   &((mng_ptr)pLOOP));
-    if (iRetcode)
-      return iRetcode;
-#else
-    MNG_ALLOC (pData, pLOOP, sizeof (mng_ani_loop));
-
-    pLOOP->sHeader.fCleanup = mng_free_ani_loop;
-    pLOOP->sHeader.fProcess = mng_process_ani_loop;
-#endif
-
-    pLOOP->iLevel = 1;
-    if (pMPNG->iNumplays)
-      pLOOP->iRepeatcount = pMPNG->iNumplays;
-    else
-      pLOOP->iRepeatcount = 0xFFFFFFFFl;
-
-    mng_add_ani_object (pData, (mng_object_headerp)pLOOP);
-  }
-
-  bNewframe = MNG_TRUE;                /* create the frame display objects */
-
-  for (iCnt = 0; iCnt < iMax; iCnt++)
-  {
-    iX       = mng_get_uint32 (pFrame);
-    iY       = mng_get_uint32 (pFrame+4);
-    iWidth   = mng_get_uint32 (pFrame+8);
-    iHeight  = mng_get_uint32 (pFrame+12);
-    iXoffset = mng_get_int32  (pFrame+16);
-    iYoffset = mng_get_int32  (pFrame+20);
-    iTicks   = mng_get_uint16 (pFrame+24);
-
-    iDelay = iTicks;
-    if (!iDelay)
-    {
-      mng_uint8p pTemp = pFrame+26;
-      mng_int32  iTemp = iCnt+1;
-
-      while ((iTemp < iMax) && (!iDelay))
-      {
-        iDelay = mng_get_uint16 (pTemp+24);
-        pTemp += 26;
-        iTemp++;
-      }
-    }
-
-    if (bNewframe)
-    {
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-      iRetcode = create_obj_general (pData, sizeof (mng_ani_fram),
-                                     mng_free_obj_general, mng_process_ani_fram,
-                                     &((mng_ptr)pFRAM));
-      if (iRetcode)
-        return iRetcode;
-#else
-      MNG_ALLOC (pData, pFRAM, sizeof (mng_ani_fram));
-
-      pFRAM->sHeader.fCleanup = mng_free_ani_fram;
-      pFRAM->sHeader.fProcess = mng_process_ani_fram;
-#endif
-
-      pFRAM->iFramemode   = 4;
-      pFRAM->iChangedelay = 1;
-      pFRAM->iDelay       = iDelay;
-
-      mng_add_ani_object (pData, (mng_object_headerp)pFRAM);
-    }
-
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-    iRetcode = create_obj_general (pData, sizeof (mng_ani_move),
-                                   mng_free_obj_general,
-                                   mng_process_ani_move,
-                                   &((mng_ptr)pMOVE));
-    if (iRetcode)
-      return iRetcode;
-#else
-    MNG_ALLOC (pData, pMOVE, sizeof (mng_ani_move));
-
-    pMOVE->sHeader.fCleanup = mng_free_ani_move;
-    pMOVE->sHeader.fProcess = mng_process_ani_move;
-#endif
-
-    pMOVE->iLocax   = iXoffset - (mng_int32)iX;
-    pMOVE->iLocay   = iYoffset - (mng_int32)iY;
-
-    mng_add_ani_object (pData, (mng_object_headerp)pMOVE);
-
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-    iRetcode = create_obj_general (pData, sizeof (mng_ani_clip),
-                                   mng_free_obj_general,
-                                   mng_process_ani_clip,
-                                   &((mng_ptr)pCLIP));
-    if (iRetcode)
-      return iRetcode;
-#else
-    MNG_ALLOC (pData, pCLIP, sizeof (mng_ani_clip));
-
-    pCLIP->sHeader.fCleanup = mng_free_ani_clip;
-    pCLIP->sHeader.fProcess = mng_process_ani_clip;
-#endif
-
-    pCLIP->iClipl = iXoffset;
-    pCLIP->iClipr = iXoffset + (mng_int32)iWidth;
-    pCLIP->iClipt = iYoffset;
-    pCLIP->iClipb = iYoffset + (mng_int32)iHeight;
-
-    mng_add_ani_object (pData, (mng_object_headerp)pCLIP);
-
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-    iRetcode = create_obj_general (pData, sizeof (mng_ani_show),
-                                   mng_free_obj_general, mng_process_ani_show,
-                                   &((mng_ptr)pSHOW));
-    if (iRetcode)
-      return iRetcode;
-#else
-    MNG_ALLOC (pData, pSHOW, sizeof (mng_ani_show));
-
-    pSHOW->sHeader.fCleanup = mng_free_ani_show;
-    pSHOW->sHeader.fProcess = mng_process_ani_show;
-#endif
-
-    mng_add_ani_object (pData, (mng_object_headerp)pSHOW);
-
-    bNewframe = (mng_bool)iTicks;
-    pFrame += 26;
-  }
-
-  if (pMPNG->iNumplays != 1)           /* create a LOOP/ENDL pair ? */
-  {
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-    iRetcode = create_obj_general (pData, sizeof (mng_ani_endl),
-                                   mng_free_obj_general, mng_process_ani_endl,
-                                   &((mng_ptr)pENDL));
-    if (iRetcode)
-      return iRetcode;
-#else
-    MNG_ALLOC (pData, pENDL, sizeof (mng_ani_endl));
-
-    pENDL->sHeader.fCleanup = mng_free_ani_endl;
-    pENDL->sHeader.fProcess = mng_process_ani_endl;
-#endif
-
-    pENDL->iLevel = 1;
-
-    mng_add_ani_object (pData, (mng_object_headerp)pENDL);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_MPNG_OBJ, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_free_mpng_obj (mng_datap   pData,
-                               mng_objectp pObject)
-{
-  mng_mpng_objp pMPNG = (mng_mpng_objp)pObject;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_MPNG_OBJ, MNG_LC_START);
-#endif
-
-  if (pMPNG->iFramessize)
-    MNG_FREEX (pData, pMPNG->pFrames, pMPNG->iFramessize);
-
-#ifndef MNG_OPTIMIZE_OBJCLEANUP
-  MNG_FREEX (pData, pMPNG, sizeof (mng_mpng_obj));
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_MPNG_OBJ, MNG_LC_END);
-#endif
-
-#ifndef MNG_OPTIMIZE_OBJCLEANUP
-  return MNG_NOERROR;
-#else
-  return mng_free_obj_general(pData, pObject);
-#endif
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_mpng_obj (mng_datap   pData,
-                                  mng_objectp pObject)
-{
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#endif /* MNG_INCLUDE_MPNG_PROPOSAL */
-
-/* ************************************************************************** */
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_ANG_PROPOSAL
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-mng_retcode mng_create_ang_obj (mng_datap  pData,
-                                mng_uint32 iNumframes,
-                                mng_uint32 iTickspersec,
-                                mng_uint32 iNumplays,
-                                mng_uint32 iTilewidth,
-                                mng_uint32 iTileheight,
-                                mng_uint8  iInterlace,
-                                mng_uint8  iStillused)
-#else
-mng_retcode mng_create_ang_obj (mng_datap  pData,
-                                mng_ptr    pEntry)
-#endif
-{
-  mng_ang_objp  pANG;
-  mng_ptr       pTemp;
-  mng_retcode   iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANG_OBJ, MNG_LC_START);
-#endif
-
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-  iRetcode = create_obj_general (pData, sizeof (mng_ang_obj), mng_free_ang_obj,
-                                 mng_process_ang_obj, &pTemp);
-  if (iRetcode)
-    return iRetcode;
-  pANG = (mng_ang_objp)pTemp;
-#else
-  MNG_ALLOC (pData, pANG, sizeof (mng_ang_obj));
-
-  pANG->sHeader.fCleanup = mng_free_ang_obj;
-  pANG->sHeader.fProcess = mng_process_ang_obj;
-#endif
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  pANG->iNumframes   = iNumframes;
-  pANG->iTickspersec = iTickspersec;
-  pANG->iNumplays    = iNumplays;
-  pANG->iTilewidth   = iTilewidth;
-  pANG->iTileheight  = iTileheight;
-  pANG->iInterlace   = iInterlace;
-  pANG->iStillused   = iStillused;
-#else
-  pANG->iNumframes   = ((mng_ahdrp)pEntry)->iNumframes;
-  pANG->iTickspersec = ((mng_ahdrp)pEntry)->iTickspersec;
-  pANG->iNumplays    = ((mng_ahdrp)pEntry)->iNumplays;
-  pANG->iTilewidth   = ((mng_ahdrp)pEntry)->iTilewidth;
-  pANG->iTileheight  = ((mng_ahdrp)pEntry)->iTileheight;
-  pANG->iInterlace   = ((mng_ahdrp)pEntry)->iInterlace;
-  pANG->iStillused   = ((mng_ahdrp)pEntry)->iStillused;
-#endif
-
-  pData->pANG       = pANG;
-  pData->eImagetype = mng_it_ang;
-
-  iRetcode = mng_process_display_ang (pData);
-  if (iRetcode)
-    return iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CREATE_ANG_OBJ, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_free_ang_obj (mng_datap   pData,
-                              mng_objectp pObject)
-{
-  mng_ang_objp pANG = (mng_ang_objp)pObject;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANG_OBJ, MNG_LC_START);
-#endif
-
-  if (pANG->iTilessize)
-    MNG_FREEX (pData, pANG->pTiles, pANG->iTilessize);
-
-#ifndef MNG_OPTIMIZE_OBJCLEANUP
-  MNG_FREEX (pData, pANG, sizeof (mng_ang_obj));
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FREE_ANG_OBJ, MNG_LC_END);
-#endif
-
-#ifndef MNG_OPTIMIZE_OBJCLEANUP
-  return MNG_NOERROR;
-#else
-  return mng_free_obj_general(pData, pObject);
-#endif
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_ang_obj (mng_datap   pData,
-                                 mng_objectp pObject)
-{
-  mng_ang_objp  pANG  = (mng_ang_objp)pObject;
-  mng_uint8p    pTile = (mng_uint8p)pANG->pTiles;
-  mng_retcode   iRetcode;
-  mng_int32     iCnt, iMax;
-  mng_uint32    iTicks;
-  mng_int32     iXoffset, iYoffset;
-  mng_uint8     iSource;
-  mng_ani_loopp pLOOP;
-  mng_ani_endlp pENDL;
-  mng_ani_framp pFRAM;
-  mng_ani_movep pMOVE;
-  mng_ani_showp pSHOW;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANG_OBJ, MNG_LC_START);
-#endif
-
-  /* let's create the MNG animation directives from this */
-
-  iMax = pANG->iNumframes;
-                                       /* set up MNG impersonation */
-  pData->iTicks      = pANG->iTickspersec;
-  pData->iLayercount = iMax;
-
-  if (pANG->iNumplays != 1)            /* create a LOOP/ENDL pair ? */
-  {
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-    iRetcode = create_obj_general (pData, sizeof (mng_ani_loop),
-                                   mng_free_ani_loop, mng_process_ani_loop,
-                                   &((mng_ptr)pLOOP));
-    if (iRetcode)
-      return iRetcode;
-#else
-    MNG_ALLOC (pData, pLOOP, sizeof (mng_ani_loop));
-
-    pLOOP->sHeader.fCleanup = mng_free_ani_loop;
-    pLOOP->sHeader.fProcess = mng_process_ani_loop;
-#endif
-
-    pLOOP->iLevel = 1;
-    if (pANG->iNumplays)
-      pLOOP->iRepeatcount = pANG->iNumplays;
-    else
-      pLOOP->iRepeatcount = 0xFFFFFFFFl;
-
-    mng_add_ani_object (pData, (mng_object_headerp)pLOOP);
-  }
-
-  for (iCnt = 0; iCnt < iMax; iCnt++)
-  {
-    iTicks   = mng_get_uint32 (pTile);
-    iXoffset = mng_get_int32  (pTile+4);
-    iYoffset = mng_get_int32  (pTile+8);
-    iSource  = *(pTile+12);
-
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-    iRetcode = create_obj_general (pData, sizeof (mng_ani_fram),
-                                   mng_free_obj_general, mng_process_ani_fram,
-                                   &((mng_ptr)pFRAM));
-    if (iRetcode)
-      return iRetcode;
-#else
-    MNG_ALLOC (pData, pFRAM, sizeof (mng_ani_fram));
-
-    pFRAM->sHeader.fCleanup = mng_free_ani_fram;
-    pFRAM->sHeader.fProcess = mng_process_ani_fram;
-#endif
-
-    pFRAM->iFramemode   = 4;
-    pFRAM->iChangedelay = 1;
-    pFRAM->iDelay       = iTicks;
-
-    mng_add_ani_object (pData, (mng_object_headerp)pFRAM);
-
-    if (!iSource)
-    {
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-      iRetcode = create_obj_general (pData, sizeof (mng_ani_move),
-                                     mng_free_obj_general,
-                                     mng_process_ani_move,
-                                     &((mng_ptr)pMOVE));
-      if (iRetcode)
-        return iRetcode;
-#else
-      MNG_ALLOC (pData, pMOVE, sizeof (mng_ani_move));
-
-      pMOVE->sHeader.fCleanup = mng_free_ani_move;
-      pMOVE->sHeader.fProcess = mng_process_ani_move;
-#endif
-
-      pMOVE->iFirstid = 1;
-      pMOVE->iLastid  = 1;
-      pMOVE->iLocax   = -iXoffset;
-      pMOVE->iLocay   = -iYoffset;
-
-      mng_add_ani_object (pData, (mng_object_headerp)pMOVE);
-    }
-
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-    iRetcode = create_obj_general (pData, sizeof (mng_ani_show),
-                                   mng_free_obj_general, mng_process_ani_show,
-                                   &((mng_ptr)pSHOW));
-    if (iRetcode)
-      return iRetcode;
-#else
-    MNG_ALLOC (pData, pSHOW, sizeof (mng_ani_show));
-
-    pSHOW->sHeader.fCleanup = mng_free_ani_show;
-    pSHOW->sHeader.fProcess = mng_process_ani_show;
-#endif
-
-    if (iSource)
-      pSHOW->iFirstid = 0;
-    else
-      pSHOW->iFirstid = 1;
-    pSHOW->iLastid    = pSHOW->iFirstid;
-
-    mng_add_ani_object (pData, (mng_object_headerp)pSHOW);
-
-    pTile += sizeof(mng_adat_tile);
-  }
-
-  if (pANG->iNumplays != 1)            /* create a LOOP/ENDL pair ? */
-  {
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-    iRetcode = create_obj_general (pData, sizeof (mng_ani_endl),
-                                   mng_free_obj_general, mng_process_ani_endl,
-                                   &((mng_ptr)pENDL));
-    if (iRetcode)
-      return iRetcode;
-#else
-    MNG_ALLOC (pData, pENDL, sizeof (mng_ani_endl));
-
-    pENDL->sHeader.fCleanup = mng_free_ani_endl;
-    pENDL->sHeader.fProcess = mng_process_ani_endl;
-#endif
-
-    pENDL->iLevel = 1;
-
-    mng_add_ani_object (pData, (mng_object_headerp)pENDL);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_ANG_OBJ, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#endif /* MNG_INCLUDE_ANG_PROPOSAL */
-
-/* ************************************************************************** */
-
-#endif /* MNG_INCLUDE_DISPLAY_PROCS */
-
-/* ************************************************************************** */
-/* * end of file                                                            * */
-/* ************************************************************************** */
-
diff --git a/Source/LibMNG/libmng_object_prc.h b/Source/LibMNG/libmng_object_prc.h
deleted file mode 100644
index ffd20c8..0000000
--- a/Source/LibMNG/libmng_object_prc.h
+++ /dev/null
@@ -1,690 +0,0 @@
-/* ************************************************************************** */
-/* *             For conditions of distribution and use,                    * */
-/* *                see copyright notice in libmng.h                        * */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * project   : libmng                                                     * */
-/* * file      : libmng_object_prc.h       copyright (c) 2000-2007 G.Juyn   * */
-/* * version   : 1.0.10                                                     * */
-/* *                                                                        * */
-/* * purpose   : Object processing routines (definition)                    * */
-/* *                                                                        * */
-/* * author    : G.Juyn                                                     * */
-/* *                                                                        * */
-/* * comment   : Definition of the internal object processing routines      * */
-/* *                                                                        * */
-/* * changes   : 0.5.1 - 05/08/2000 - G.Juyn                                * */
-/* *             - changed strict-ANSI stuff                                * */
-/* *                                                                        * */
-/* *             0.5.2 - 05/24/2000 - G.Juyn                                * */
-/* *             - added support for global color-chunks in animation       * */
-/* *             - added support for global PLTE,tRNS,bKGD in animation     * */
-/* *             - added SAVE & SEEK animation objects                      * */
-/* *             0.5.2 - 05/29/2000 - G.Juyn                                * */
-/* *             - changed ani_object create routines not to return the     * */
-/* *               created object (wasn't necessary)                        * */
-/* *             - added compression/filter/interlace fields to             * */
-/* *               object-buffer for delta-image processing                 * */
-/* *                                                                        * */
-/* *             0.5.3 - 06/22/2000 - G.Juyn                                * */
-/* *             - added support for PPLT chunk                             * */
-/* *                                                                        * */
-/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
-/* *             - changed file-prefixes                                    * */
-/* *                                                                        * */
-/* *             0.9.3 - 08/26/2000 - G.Juyn                                * */
-/* *             - added MAGN chunk                                         * */
-/* *             0.9.3 - 10/17/2000 - G.Juyn                                * */
-/* *             - added routine to discard "invalid" objects               * */
-/* *                                                                        * */
-/* *             1.0.5 - 08/19/2002 - G.Juyn                                * */
-/* *             - B597134 - libmng pollutes the linker namespace           * */
-/* *             1.0.5 - 09/13/2002 - G.Juyn                                * */
-/* *             - fixed read/write of MAGN chunk                           * */
-/* *             1.0.5 - 09/15/2002 - G.Juyn                                * */
-/* *             - added event handling for dynamic MNG                     * */
-/* *             1.0.5 - 09/20/2002 - G.Juyn                                * */
-/* *             - added support for PAST                                   * */
-/* *             1.0.5 - 09/23/2002 - G.Juyn                                * */
-/* *             - added in-memory color-correction of abstract images      * */
-/* *             1.0.5 - 10/07/2002 - G.Juyn                                * */
-/* *             - fixed DISC support                                       * */
-/* *                                                                        * */
-/* *             1.0.6 - 07/07/2003 - G.R-P                                 * */
-/* *             - added conditionals around Delta-PNG code                 * */
-/* *             - added SKIPCHUNK feature                                  * */
-/* *             1.0.6 - 07/29/2003 - G.R-P                                 * */
-/* *             - added conditionals around PAST chunk support             * */
-/* *                                                                        * */
-/* *             1.0.7 - 03/24/2004 - G.R-P                                 * */
-/* *             - added more SKIPCHUNK conditionals                        * */
-/* *                                                                        * */
-/* *             1.0.9 - 12/05/2004 - G.Juyn                                * */
-/* *             - added conditional MNG_OPTIMIZE_OBJCLEANUP                * */
-/* *                                                                        * */
-/* *             1.0.10 - 04/08/2007 - G.Juyn                               * */
-/* *             - added support for mPNG proposal                          * */
-/* *             1.0.10 - 04/12/2007 - G.Juyn                               * */
-/* *             - added support for ANG proposal                           * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
-#pragma option -A                      /* force ANSI-C */
-#endif
-
-#ifndef _libmng_object_prc_h_
-#define _libmng_object_prc_h_
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_DISPLAY_PROCS
-
-/* ************************************************************************** */
-
-mng_retcode mng_drop_invalid_objects   (mng_datap      pData);
-
-/* ************************************************************************** */
-
-mng_retcode mng_create_imagedataobject (mng_datap      pData,
-                                        mng_bool       bConcrete,
-                                        mng_bool       bViewable,
-                                        mng_uint32     iWidth,
-                                        mng_uint32     iHeight,
-                                        mng_uint8      iBitdepth,
-                                        mng_uint8      iColortype,
-                                        mng_uint8      iCompression,
-                                        mng_uint8      iFilter,
-                                        mng_uint8      iInterlace,
-                                        mng_imagedatap *ppObject);
-
-mng_retcode mng_free_imagedataobject   (mng_datap      pData,
-                                        mng_imagedatap pImagedata);
-
-mng_retcode mng_clone_imagedataobject  (mng_datap      pData,
-                                        mng_bool       bConcrete,
-                                        mng_imagedatap pSource,
-                                        mng_imagedatap *ppClone);
-
-/* ************************************************************************** */
-
-mng_retcode mng_create_imageobject   (mng_datap  pData,
-                                      mng_uint16 iId,
-                                      mng_bool   bConcrete,
-                                      mng_bool   bVisible,
-                                      mng_bool   bViewable,
-                                      mng_uint32 iWidth,
-                                      mng_uint32 iHeight,
-                                      mng_uint8  iBitdepth,
-                                      mng_uint8  iColortype,
-                                      mng_uint8  iCompression,
-                                      mng_uint8  iFilter,
-                                      mng_uint8  iInterlace,
-                                      mng_int32  iPosx,
-                                      mng_int32  iPosy,
-                                      mng_bool   bClipped,
-                                      mng_int32  iClipl,
-                                      mng_int32  iClipr,
-                                      mng_int32  iClipt,
-                                      mng_int32  iClipb,
-                                      mng_imagep *ppObject);
-
-mng_retcode mng_free_imageobject     (mng_datap  pData,
-                                      mng_imagep pImage);
-
-mng_imagep  mng_find_imageobject     (mng_datap  pData,
-                                      mng_uint16 iId);
-
-mng_retcode mng_clone_imageobject    (mng_datap  pData,
-                                      mng_uint16 iId,
-                                      mng_bool   bPartial,
-                                      mng_bool   bVisible,
-                                      mng_bool   bAbstract,
-                                      mng_bool   bHasloca,
-                                      mng_uint8  iLocationtype,
-                                      mng_int32  iLocationx,
-                                      mng_int32  iLocationy,
-                                      mng_imagep pSource,
-                                      mng_imagep *ppClone);
-
-mng_retcode mng_renum_imageobject    (mng_datap  pData,
-                                      mng_imagep pSource,
-                                      mng_uint16 iId,
-                                      mng_bool   bVisible,
-                                      mng_bool   bAbstract,
-                                      mng_bool   bHasloca,
-                                      mng_uint8  iLocationtype,
-                                      mng_int32  iLocationx,
-                                      mng_int32  iLocationy);
-
-mng_retcode mng_reset_object_details (mng_datap  pData,
-                                      mng_imagep pImage,
-                                      mng_uint32 iWidth,
-                                      mng_uint32 iHeight,
-                                      mng_uint8  iBitdepth,
-                                      mng_uint8  iColortype,
-                                      mng_uint8  iCompression,
-                                      mng_uint8  iFilter,
-                                      mng_uint8  iInterlace,
-                                      mng_bool   bResetall);
-
-mng_retcode mng_promote_imageobject  (mng_datap  pData,
-                                      mng_imagep pImage,
-                                      mng_uint8  iBitdepth,
-                                      mng_uint8  iColortype,
-                                      mng_uint8  iFilltype);
-
-mng_retcode mng_magnify_imageobject  (mng_datap  pData,
-                                      mng_imagep pImage);
-
-mng_retcode mng_colorcorrect_object  (mng_datap  pData,
-                                      mng_imagep pImage);
-
-/* ************************************************************************** */
-
-mng_retcode mng_create_ani_image  (mng_datap      pData);
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-
-mng_retcode mng_create_ani_plte   (mng_datap      pData,
-                                   mng_uint32     iEntrycount,
-                                   mng_palette8ep paEntries);
-
-mng_retcode mng_create_ani_trns   (mng_datap      pData,
-                                   mng_uint32     iRawlen,
-                                   mng_uint8p     pRawdata);
-
-mng_retcode mng_create_ani_gama   (mng_datap      pData,
-                                   mng_bool       bEmpty,
-                                   mng_uint32     iGamma);
-
-mng_retcode mng_create_ani_chrm   (mng_datap      pData,
-                                   mng_bool       bEmpty,
-                                   mng_uint32     iWhitepointx,
-                                   mng_uint32     iWhitepointy,
-                                   mng_uint32     iRedx,
-                                   mng_uint32     iRedy,
-                                   mng_uint32     iGreenx,
-                                   mng_uint32     iGreeny,
-                                   mng_uint32     iBluex,
-                                   mng_uint32     iBluey);
-
-mng_retcode mng_create_ani_srgb   (mng_datap      pData,
-                                   mng_bool       bEmpty,
-                                   mng_uint8      iRenderinginent);
-
-mng_retcode mng_create_ani_iccp   (mng_datap      pData,
-                                   mng_bool       bEmpty,
-                                   mng_uint32     iProfilesize,
-                                   mng_ptr        pProfile);
-
-mng_retcode mng_create_ani_bkgd   (mng_datap      pData,
-                                   mng_uint16     iRed,
-                                   mng_uint16     iGreen,
-                                   mng_uint16     iBlue);
-
-mng_retcode mng_create_ani_loop   (mng_datap      pData,
-                                   mng_uint8      iLevel,
-                                   mng_uint32     iRepeatcount,
-                                   mng_uint8      iTermcond,
-                                   mng_uint32     iItermin,
-                                   mng_uint32     iItermax,
-                                   mng_uint32     iCount,
-                                   mng_uint32p    pSignals);
-
-mng_retcode mng_create_ani_endl   (mng_datap      pData,
-                                   mng_uint8      iLevel);
-
-mng_retcode mng_create_ani_defi   (mng_datap      pData);
-
-mng_retcode mng_create_ani_basi   (mng_datap      pData,
-                                   mng_uint16     iRed,
-                                   mng_uint16     iGreen,
-                                   mng_uint16     iBlue,
-                                   mng_bool       bHasalpha,
-                                   mng_uint16     iAlpha,
-                                   mng_uint8      iViewable);
-
-mng_retcode mng_create_ani_clon   (mng_datap      pData,
-                                   mng_uint16     iSourceid,
-                                   mng_uint16     iCloneid,
-                                   mng_uint8      iClonetype,
-                                   mng_bool       bHasdonotshow,
-                                   mng_uint8      iDonotshow,
-                                   mng_uint8      iConcrete,
-                                   mng_bool       bHasloca,
-                                   mng_uint8      iLocatype,
-                                   mng_int32      iLocax,
-                                   mng_int32      iLocay);
-
-mng_retcode mng_create_ani_back   (mng_datap      pData,
-                                   mng_uint16     iRed,
-                                   mng_uint16     iGreen,
-                                   mng_uint16     iBlue,
-                                   mng_uint8      iMandatory,
-                                   mng_uint16     iImageid,
-                                   mng_uint8      iTile);
-
-mng_retcode mng_create_ani_fram   (mng_datap      pData,
-                                   mng_uint8      iFramemode,
-                                   mng_uint8      iChangedelay,
-                                   mng_uint32     iDelay,
-                                   mng_uint8      iChangetimeout,
-                                   mng_uint32     iTimeout,
-                                   mng_uint8      iChangeclipping,
-                                   mng_uint8      iCliptype,
-                                   mng_int32      iClipl,
-                                   mng_int32      iClipr,
-                                   mng_int32      iClipt,
-                                   mng_int32      iClipb);
-
-mng_retcode mng_create_ani_move   (mng_datap      pData,
-                                   mng_uint16     iFirstid,
-                                   mng_uint16     iLastid,
-                                   mng_uint8      iType,
-                                   mng_int32      iLocax,
-                                   mng_int32      iLocay);
-
-mng_retcode mng_create_ani_clip   (mng_datap      pData,
-                                   mng_uint16     iFirstid,
-                                   mng_uint16     iLastid,
-                                   mng_uint8      iType,
-                                   mng_int32      iClipl,
-                                   mng_int32      iClipr,
-                                   mng_int32      iClipt,
-                                   mng_int32      iClipb);
-
-mng_retcode mng_create_ani_show   (mng_datap      pData,
-                                   mng_uint16     iFirstid,
-                                   mng_uint16     iLastid,
-                                   mng_uint8      iMode);
-
-mng_retcode mng_create_ani_term   (mng_datap      pData,
-                                   mng_uint8      iTermaction,
-                                   mng_uint8      iIteraction,
-                                   mng_uint32     iDelay,
-                                   mng_uint32     iItermax);
-
-#ifndef MNG_SKIPCHUNK_SAVE
-mng_retcode mng_create_ani_save   (mng_datap      pData);
-#endif
-#ifndef MNG_SKIPCHUNK_SEEK
-mng_retcode mng_create_ani_seek   (mng_datap      pData,
-                                   mng_uint32     iSegmentnamesize,
-                                   mng_pchar      zSegmentname);
-#endif
-#ifndef MNG_NO_DELTA_PNG
-mng_retcode mng_create_ani_dhdr   (mng_datap      pData,
-                                   mng_uint16     iObjectid,
-                                   mng_uint8      iImagetype,
-                                   mng_uint8      iDeltatype,
-                                   mng_uint32     iBlockwidth,
-                                   mng_uint32     iBlockheight,
-                                   mng_uint32     iBlockx,
-                                   mng_uint32     iBlocky);
-
-mng_retcode mng_create_ani_prom   (mng_datap      pData,
-                                   mng_uint8      iBitdepth,
-                                   mng_uint8      iColortype,
-                                   mng_uint8      iFilltype);
-
-mng_retcode mng_create_ani_ipng   (mng_datap      pData);
-mng_retcode mng_create_ani_ijng   (mng_datap      pData);
-
-mng_retcode mng_create_ani_pplt   (mng_datap      pData,
-                                   mng_uint8      iType,
-                                   mng_uint32     iCount,
-                                   mng_palette8ep paIndexentries,
-                                   mng_uint8p     paAlphaentries,
-                                   mng_uint8p     paUsedentries);
-#endif
-
-#ifndef MNG_SKIPCHUNK_MAGN
-mng_retcode mng_create_ani_magn   (mng_datap      pData,
-                                   mng_uint16     iFirstid,
-                                   mng_uint16     iLastid,
-                                   mng_uint8      iMethodX,
-                                   mng_uint16     iMX,
-                                   mng_uint16     iMY,
-                                   mng_uint16     iML,
-                                   mng_uint16     iMR,
-                                   mng_uint16     iMT,
-                                   mng_uint16     iMB,
-                                   mng_uint8      iMethodY);
-#endif
-
-#ifndef MNG_SKIPCHUNK_PAST
-mng_retcode mng_create_ani_past   (mng_datap      pData,
-                                   mng_uint16     iTargetid,
-                                   mng_uint8      iTargettype,
-                                   mng_int32      iTargetx,
-                                   mng_int32      iTargety,
-                                   mng_uint32     iCount,
-                                   mng_ptr        pSources);
-#endif
-
-#ifndef MNG_SKIPCHUNK_DISC
-mng_retcode mng_create_ani_disc   (mng_datap      pData,
-                                   mng_uint32     iCount,
-                                   mng_uint16p    pIds);
-#endif
-
-#else /* MNG_OPTIMIZE_CHUNKREADER */
-
-mng_retcode mng_create_ani_plte   (mng_datap      pData);
-mng_retcode mng_create_ani_trns   (mng_datap      pData);
-mng_retcode mng_create_ani_gama   (mng_datap      pData,
-                                   mng_chunkp     pChunk);
-mng_retcode mng_create_ani_chrm   (mng_datap      pData,
-                                   mng_chunkp     pChunk);
-mng_retcode mng_create_ani_srgb   (mng_datap      pData,
-                                   mng_chunkp     pChunk);
-mng_retcode mng_create_ani_iccp   (mng_datap      pData,
-                                   mng_chunkp     pChunk);
-mng_retcode mng_create_ani_bkgd   (mng_datap      pData);
-mng_retcode mng_create_ani_loop   (mng_datap      pData,
-                                   mng_chunkp     pChunk);
-mng_retcode mng_create_ani_endl   (mng_datap      pData,
-                                   mng_uint8      iLevel);
-mng_retcode mng_create_ani_defi   (mng_datap      pData);
-mng_retcode mng_create_ani_basi   (mng_datap      pData,
-                                   mng_chunkp     pChunk);
-mng_retcode mng_create_ani_clon   (mng_datap      pData,
-                                   mng_chunkp     pChunk);
-mng_retcode mng_create_ani_back   (mng_datap      pData);
-mng_retcode mng_create_ani_fram   (mng_datap      pData,
-                                   mng_chunkp     pChunk);
-mng_retcode mng_create_ani_move   (mng_datap      pData,
-                                   mng_chunkp     pChunk);
-mng_retcode mng_create_ani_clip   (mng_datap      pData,
-                                   mng_chunkp     pChunk);
-mng_retcode mng_create_ani_show   (mng_datap      pData);
-mng_retcode mng_create_ani_term   (mng_datap      pData,
-                                   mng_chunkp     pChunk);
-#ifndef MNG_SKIPCHUNK_SAVE
-mng_retcode mng_create_ani_save   (mng_datap      pData);
-#endif
-#ifndef MNG_SKIPCHUNK_SEEK
-mng_retcode mng_create_ani_seek   (mng_datap      pData,
-                                   mng_chunkp     pChunk);
-#endif
-#ifndef MNG_NO_DELTA_PNG
-mng_retcode mng_create_ani_dhdr   (mng_datap      pData,
-                                   mng_chunkp     pChunk);
-mng_retcode mng_create_ani_prom   (mng_datap      pData,
-                                   mng_chunkp     pChunk);
-mng_retcode mng_create_ani_ipng   (mng_datap      pData);
-mng_retcode mng_create_ani_ijng   (mng_datap      pData);
-
-mng_retcode mng_create_ani_pplt   (mng_datap      pData,
-                                   mng_uint8      iType,
-                                   mng_uint32     iCount,
-                                   mng_palette8ep paIndexentries,
-                                   mng_uint8p     paAlphaentries,
-                                   mng_uint8p     paUsedentries);
-#endif
-
-#ifndef MNG_SKIPCHUNK_MAGN
-mng_retcode mng_create_ani_magn   (mng_datap      pData,
-                                   mng_chunkp     pChunk);
-#endif
-#ifndef MNG_SKIPCHUNK_PAST
-mng_retcode mng_create_ani_past   (mng_datap      pData,
-                                   mng_chunkp     pChunk);
-#endif
-#ifndef MNG_SKIPCHUNK_DISC
-mng_retcode mng_create_ani_disc   (mng_datap      pData,
-                                   mng_chunkp     pChunk);
-#endif
-
-#endif /* MNG_OPTIMIZE_CHUNKREADER */
-
-/* ************************************************************************** */
-
-mng_retcode mng_free_ani_image    (mng_datap    pData,
-                                   mng_objectp  pObject);
-
-#ifndef MNG_OPTIMIZE_OBJCLEANUP
-
-mng_retcode mng_free_ani_plte     (mng_datap    pData,
-                                   mng_objectp  pObject);
-mng_retcode mng_free_ani_trns     (mng_datap    pData,
-                                   mng_objectp  pObject);
-mng_retcode mng_free_ani_gama     (mng_datap    pData,
-                                   mng_objectp  pObject);
-#ifndef MNG_SKIPCHUNK_cHRM
-mng_retcode mng_free_ani_chrm     (mng_datap    pData,
-                                   mng_objectp  pObject);
-#endif
-#ifndef MNG_SKIPCHUNK_sRGB
-mng_retcode mng_free_ani_srgb     (mng_datap    pData,
-                                   mng_objectp  pObject);
-#endif
-#ifndef MNG_SKIPCHUNK_bKGD
-mng_retcode mng_free_ani_bkgd     (mng_datap    pData,
-                                   mng_objectp  pObject);
-#endif
-#ifndef MNG_SKIPCHUNK_LOOP
-mng_retcode mng_free_ani_endl     (mng_datap    pData,
-                                   mng_objectp  pObject);
-#endif
-mng_retcode mng_free_ani_defi     (mng_datap    pData,
-                                   mng_objectp  pObject);
-mng_retcode mng_free_ani_basi     (mng_datap    pData,
-                                   mng_objectp  pObject);
-mng_retcode mng_free_ani_clon     (mng_datap    pData,
-                                   mng_objectp  pObject);
-mng_retcode mng_free_ani_back     (mng_datap    pData,
-                                   mng_objectp  pObject);
-mng_retcode mng_free_ani_fram     (mng_datap    pData,
-                                   mng_objectp  pObject);
-mng_retcode mng_free_ani_move     (mng_datap    pData,
-                                   mng_objectp  pObject);
-mng_retcode mng_free_ani_clip     (mng_datap    pData,
-                                   mng_objectp  pObject);
-mng_retcode mng_free_ani_show     (mng_datap    pData,
-                                   mng_objectp  pObject);
-mng_retcode mng_free_ani_term     (mng_datap    pData,
-                                   mng_objectp  pObject);
-#ifndef MNG_SKIPCHUNK_SAVE
-mng_retcode mng_free_ani_save     (mng_datap    pData,
-                                   mng_objectp  pObject);
-#endif
-#ifndef MNG_NO_DELTA_PNG
-mng_retcode mng_free_ani_dhdr     (mng_datap    pData,
-                                   mng_objectp  pObject);
-mng_retcode mng_free_ani_prom     (mng_datap    pData,
-                                   mng_objectp  pObject);
-mng_retcode mng_free_ani_ipng     (mng_datap    pData,
-                                   mng_objectp  pObject);
-mng_retcode mng_free_ani_ijng     (mng_datap    pData,
-                                   mng_objectp  pObject);
-mng_retcode mng_free_ani_pplt     (mng_datap    pData,
-                                   mng_objectp  pObject);
-#endif
-#ifndef MNG_SKIPCHUNK_MAGN
-mng_retcode mng_free_ani_magn     (mng_datap    pData,
-                                   mng_objectp  pObject);
-#endif
-
-#endif /* MNG_OPTIMIZE_OBJCLEANUP */
-
-
-#ifndef MNG_SKIPCHUNK_iCCP
-mng_retcode mng_free_ani_iccp     (mng_datap    pData,
-                                   mng_objectp  pObject);
-#endif
-#ifndef MNG_SKIPCHUNK_LOOP
-mng_retcode mng_free_ani_loop     (mng_datap    pData,
-                                   mng_objectp  pObject);
-#endif
-#ifndef MNG_SKIPCHUNK_SAVE
-mng_retcode mng_free_ani_seek     (mng_datap    pData,
-                                   mng_objectp  pObject);
-#endif
-#ifndef MNG_SKIPCHUNK_PAST
-mng_retcode mng_free_ani_past     (mng_datap    pData,
-                                   mng_objectp  pObject);
-#endif
-mng_retcode mng_free_ani_disc     (mng_datap    pData,
-                                   mng_objectp  pObject);
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_ani_image (mng_datap    pData,
-                                   mng_objectp  pObject);
-
-mng_retcode mng_process_ani_plte  (mng_datap    pData,
-                                   mng_objectp  pObject);
-mng_retcode mng_process_ani_trns  (mng_datap    pData,
-                                   mng_objectp  pObject);
-mng_retcode mng_process_ani_gama  (mng_datap    pData,
-                                   mng_objectp  pObject);
-#ifndef MNG_SKIPCHUNK_cHRM
-mng_retcode mng_process_ani_chrm  (mng_datap    pData,
-                                   mng_objectp  pObject);
-#endif
-#ifndef MNG_SKIPCHUNK_sRGB
-mng_retcode mng_process_ani_srgb  (mng_datap    pData,
-                                   mng_objectp  pObject);
-#endif
-#ifndef MNG_SKIPCHUNK_iCCP
-mng_retcode mng_process_ani_iccp  (mng_datap    pData,
-                                   mng_objectp  pObject);
-#endif
-#ifndef MNG_SKIPCHUNK_bKGD
-mng_retcode mng_process_ani_bkgd  (mng_datap    pData,
-                                   mng_objectp  pObject);
-#endif
-#ifndef MNG_SKIPCHUNK_LOOP
-mng_retcode mng_process_ani_loop  (mng_datap    pData,
-                                   mng_objectp  pObject);
-mng_retcode mng_process_ani_endl  (mng_datap    pData,
-                                   mng_objectp  pObject);
-#endif
-mng_retcode mng_process_ani_defi  (mng_datap    pData,
-                                   mng_objectp  pObject);
-mng_retcode mng_process_ani_basi  (mng_datap    pData,
-                                   mng_objectp  pObject);
-mng_retcode mng_process_ani_clon  (mng_datap    pData,
-                                   mng_objectp  pObject);
-mng_retcode mng_process_ani_back  (mng_datap    pData,
-                                   mng_objectp  pObject);
-mng_retcode mng_process_ani_fram  (mng_datap    pData,
-                                   mng_objectp  pObject);
-mng_retcode mng_process_ani_move  (mng_datap    pData,
-                                   mng_objectp  pObject);
-mng_retcode mng_process_ani_clip  (mng_datap    pData,
-                                   mng_objectp  pObject);
-mng_retcode mng_process_ani_show  (mng_datap    pData,
-                                   mng_objectp  pObject);
-mng_retcode mng_process_ani_term  (mng_datap    pData,
-                                   mng_objectp  pObject);
-#ifndef MNG_SKIPCHUNK_SAVE
-mng_retcode mng_process_ani_save  (mng_datap    pData,
-                                   mng_objectp  pObject);
-#endif
-#ifndef MNG_SKIPCHUNK_SEEK
-mng_retcode mng_process_ani_seek  (mng_datap    pData,
-                                   mng_objectp  pObject);
-#endif
-#ifndef MNG_NO_DELTA_PNG
-mng_retcode mng_process_ani_dhdr  (mng_datap    pData,
-                                   mng_objectp  pObject);
-mng_retcode mng_process_ani_prom  (mng_datap    pData,
-                                   mng_objectp  pObject);
-mng_retcode mng_process_ani_ipng  (mng_datap    pData,
-                                   mng_objectp  pObject);
-mng_retcode mng_process_ani_ijng  (mng_datap    pData,
-                                   mng_objectp  pObject);
-mng_retcode mng_process_ani_pplt  (mng_datap    pData,
-                                   mng_objectp  pObject);
-#endif
-mng_retcode mng_process_ani_magn  (mng_datap    pData,
-                                   mng_objectp  pObject);
-#ifndef MNG_SKIPCHUNK_PAST
-mng_retcode mng_process_ani_past  (mng_datap    pData,
-                                   mng_objectp  pObject);
-#endif
-mng_retcode mng_process_ani_disc  (mng_datap    pData,
-                                   mng_objectp  pObject);
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DYNAMICMNG
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-mng_retcode mng_create_event      (mng_datap    pData,
-                                   mng_uint8    iEventtype,
-                                   mng_uint8    iMasktype,
-                                   mng_int32    iLeft,
-                                   mng_int32    iRight,
-                                   mng_int32    iTop,
-                                   mng_int32    iBottom,
-                                   mng_uint16   iObjectid,
-                                   mng_uint8    iIndex,
-                                   mng_uint32   iSegmentnamesize,
-                                   mng_pchar    zSegmentname);
-#else
-mng_retcode mng_create_event      (mng_datap    pData,
-                                   mng_ptr      pEntry);
-#endif
-mng_retcode mng_free_event        (mng_datap    pData,
-                                   mng_objectp  pObject);
-mng_retcode mng_process_event     (mng_datap    pData,
-                                   mng_objectp  pObject);
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-mng_retcode mng_create_mpng_obj   (mng_datap    pData,
-                                   mng_uint32   iFramewidth,
-                                   mng_uint32   iFrameheight,
-                                   mng_uint16   iNumplays,
-                                   mng_uint16   iTickspersec,
-                                   mng_uint32   iFramessize,
-                                   mng_ptr      pFrames);
-#else
-mng_retcode mng_create_mpng_obj   (mng_datap    pData,
-                                   mng_ptr      pEntry);
-#endif
-mng_retcode mng_free_mpng_obj     (mng_datap    pData,
-                                   mng_objectp  pObject);
-mng_retcode mng_process_mpng_obj  (mng_datap    pData,
-                                   mng_objectp  pObject);
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_ANG_PROPOSAL
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-mng_retcode mng_create_ang_obj    (mng_datap    pData,
-                                   mng_uint32   iNumframes,
-                                   mng_uint32   iTickspersec,
-                                   mng_uint32   iNumplays,
-                                   mng_uint32   iTilewidth,
-                                   mng_uint32   iTileheight,
-                                   mng_uint8    iInterlace,
-                                   mng_uint8    iStillused);
-#else
-mng_retcode mng_create_ang_obj    (mng_datap    pData,
-                                   mng_ptr      pEntry);
-#endif
-mng_retcode mng_free_ang_obj      (mng_datap    pData,
-                                   mng_objectp  pObject);
-mng_retcode mng_process_ang_obj   (mng_datap    pData,
-                                   mng_objectp  pObject);
-#endif
-
-/* ************************************************************************** */
-
-#endif /* MNG_INCLUDE_DISPLAY_PROCS */
-
-/* ************************************************************************** */
-
-#endif /* _libmng_object_prc_h_ */
-
-/* ************************************************************************** */
-/* * end of file                                                            * */
-/* ************************************************************************** */
diff --git a/Source/LibMNG/libmng_objects.h b/Source/LibMNG/libmng_objects.h
deleted file mode 100644
index 053e6b4..0000000
--- a/Source/LibMNG/libmng_objects.h
+++ /dev/null
@@ -1,635 +0,0 @@
-/* ************************************************************************** */
-/* *             For conditions of distribution and use,                    * */
-/* *                see copyright notice in libmng.h                        * */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * project   : libmng                                                     * */
-/* * file      : libmng_objects.h          copyright (c) 2000-2007 G.Juyn   * */
-/* * version   : 1.0.10                                                     * */
-/* *                                                                        * */
-/* * purpose   : Internal object structures (definition)                    * */
-/* *                                                                        * */
-/* * author    : G.Juyn                                                     * */
-/* *                                                                        * */
-/* * comment   : Definition of the internal object structures               * */
-/* *                                                                        * */
-/* * changes   : 0.5.1 - 05/08/2000 - G.Juyn                                * */
-/* *             - changed strict-ANSI stuff                                * */
-/* *                                                                        * */
-/* *             0.5.2 - 05/23/2000 - G.Juyn                                * */
-/* *             - changed inclusion to DISPLAY_PROCS                       * */
-/* *             0.5.2 - 05/24/2000 - G.Juyn                                * */
-/* *             - added global color-chunks for animations                 * */
-/* *             - added global PLTE,tRNS,bKGD chunks for animation         * */
-/* *             - added SAVE & SEEK animation objects                      * */
-/* *             0.5.2 - 05/29/2000 - G.Juyn                                * */
-/* *             - added framenr/layernr/playtime to object header          * */
-/* *             0.5.2 - 05/30/2000 - G.Juyn                                * */
-/* *             - added ani-objects for delta-image processing             * */
-/* *             - added compression/filter/interlace fields to             * */
-/* *               object-buffer for delta-image processing                 * */
-/* *                                                                        * */
-/* *             0.5.3 - 06/17/2000 - G.Juyn                                * */
-/* *             - changed definition of aTRNSentries                       * */
-/* *             0.5.3 - 06/22/2000 - G.Juyn                                * */
-/* *             - added definition for PPLT animation-processing           * */
-/* *                                                                        * */
-/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
-/* *             - changed file-prefixes                                    * */
-/* *                                                                        * */
-/* *             0.9.3 - 08/26/2000 - G.Juyn                                * */
-/* *             - added MAGN chunk                                         * */
-/* *             0.9.3 - 09/10/2000 - G.Juyn                                * */
-/* *             - fixed DEFI behavior                                      * */
-/* *             0.9.3 - 10/16/2000 - G.Juyn                                * */
-/* *             - added support for delta-JNG                              * */
-/* *             0.9.3 - 10/17/2000 - G.Juyn                                * */
-/* *             - added valid-flag to stored objects for read() / display()* */
-/* *             0.9.3 - 10/19/2000 - G.Juyn                                * */
-/* *             - added storage for pixel-/alpha-sampledepth for delta's   * */
-/* *                                                                        * */
-/* *             1.0.5 - 09/13/2002 - G.Juyn                                * */
-/* *             - fixed read/write of MAGN chunk                           * */
-/* *             1.0.5 - 09/15/2002 - G.Juyn                                * */
-/* *             - added event handling for dynamic MNG                     * */
-/* *             1.0.5 - 09/20/2002 - G.Juyn                                * */
-/* *             - added support for PAST                                   * */
-/* *             1.0.5 - 09/23/2002 - G.Juyn                                * */
-/* *             - added in-memory color-correction of abstract images      * */
-/* *             1.0.5 - 10/07/2002 - G.Juyn                                * */
-/* *             - fixed DISC support                                       * */
-/* *                                                                        * */
-/* *             1.0.6 - 10/07/2003 - G.R-P                                 * */
-/* *             - added SKIPCHUNK conditionals                             * */
-/* *                                                                        * */
-/* *             1.0.7 - 03/24/2004 - G.R-P                                 * */
-/* *             - added more SKIPCHUNK conditionals                        * */
-/* *                                                                        * */
-/* *             1.0.9 - 12/05/2004 - G.Juyn                                * */
-/* *             - added conditional MNG_OPTIMIZE_OBJCLEANUP                * */
-/* *                                                                        * */
-/* *             1.0.10 - 04/08/2007 - G.Juyn                               * */
-/* *             - added support for mPNG proposal                          * */
-/* *             1.0.10 - 04/12/2007 - G.Juyn                               * */
-/* *             - added support for ANG proposal                           * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
-#pragma option -A                      /* force ANSI-C */
-#endif
-
-#ifndef _libmng_objects_h_
-#define _libmng_objects_h_
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_DISPLAY_PROCS
-
-/* ************************************************************************** */
-
-typedef mng_retcode (*mng_cleanupobject) (mng_datap    pData,
-                                          mng_objectp  pHeader);
-
-typedef mng_retcode (*mng_processobject) (mng_datap    pData,
-                                          mng_objectp  pHeader);
-
-/* ************************************************************************** */
-
-typedef struct {
-           mng_cleanupobject fCleanup;
-           mng_processobject fProcess;
-           mng_objectp       pNext;              /* for double-linked list */
-           mng_objectp       pPrev;
-           mng_uint32        iFramenr;
-           mng_uint32        iLayernr;
-           mng_uint32        iPlaytime;
-#ifdef MNG_OPTIMIZE_OBJCLEANUP
-           mng_size_t        iObjsize;                    
-#endif
-        } mng_object_header;
-typedef mng_object_header * mng_object_headerp;
-
-/* ************************************************************************** */
-
-typedef struct {                                 /* MNG specification "object-buffer" */
-           mng_object_header sHeader;            /* default header (DO NOT REMOVE) */
-           mng_uint32        iRefcount;          /* reference counter */
-           mng_bool          bFrozen;            /* frozen flag */
-           mng_bool          bConcrete;          /* concrete flag */
-           mng_bool          bViewable;          /* viewable flag */
-           mng_uint32        iWidth;             /* image specifics */
-           mng_uint32        iHeight;
-           mng_uint8         iBitdepth;
-           mng_uint8         iColortype;
-           mng_uint8         iCompression;
-           mng_uint8         iFilter;
-           mng_uint8         iInterlace;
-
-           mng_bool          bCorrected;         /* indicates if an abstract image
-                                                    has already been color-corrected */
-           
-           mng_uint8         iAlphabitdepth;     /* used only for JNG images */
-           mng_uint8         iJHDRcompression;
-           mng_uint8         iJHDRinterlace;
-
-           mng_uint8         iPixelsampledepth;  /* used with delta-images */
-           mng_uint8         iAlphasampledepth;
-
-           mng_bool          bHasPLTE;           /* PLTE chunk present */
-           mng_bool          bHasTRNS;           /* tRNS chunk present */
-           mng_bool          bHasGAMA;           /* gAMA chunk present */
-           mng_bool          bHasCHRM;           /* cHRM chunk present */
-           mng_bool          bHasSRGB;           /* sRGB chunk present */
-           mng_bool          bHasICCP;           /* iCCP chunk present */
-           mng_bool          bHasBKGD;           /* bKGD chunk present */
-
-           mng_uint32        iPLTEcount;         /* PLTE fields */
-           mng_rgbpaltab     aPLTEentries;
-
-           mng_uint16        iTRNSgray;          /* tRNS fields */
-           mng_uint16        iTRNSred;
-           mng_uint16        iTRNSgreen;
-           mng_uint16        iTRNSblue;
-           mng_uint32        iTRNScount;
-           mng_uint8arr      aTRNSentries;
-
-           mng_uint32        iGamma;             /* gAMA fields */
-
-           mng_uint32        iWhitepointx;       /* cHRM fields */
-           mng_uint32        iWhitepointy;
-           mng_uint32        iPrimaryredx;
-           mng_uint32        iPrimaryredy;
-           mng_uint32        iPrimarygreenx;
-           mng_uint32        iPrimarygreeny;
-           mng_uint32        iPrimarybluex;
-           mng_uint32        iPrimarybluey;
-
-           mng_uint8         iRenderingintent;   /* sRGB fields */
-
-           mng_uint32        iProfilesize;       /* iCCP fields */
-           mng_ptr           pProfile;
-
-           mng_uint8         iBKGDindex;         /* bKGD fields */
-           mng_uint16        iBKGDgray;
-           mng_uint16        iBKGDred;
-           mng_uint16        iBKGDgreen;
-           mng_uint16        iBKGDblue;
-
-           mng_uint32        iSamplesize;        /* size of a sample */
-           mng_uint32        iRowsize;           /* size of a row of samples */
-           mng_uint32        iImgdatasize;       /* size of the sample data buffer */
-           mng_uint8p        pImgdata;           /* actual sample data buffer */
-
-         } mng_imagedata;
-typedef mng_imagedata * mng_imagedatap;
-
-/* ************************************************************************** */
-
-typedef struct {                                 /* MNG specification "object" */
-           mng_object_header sHeader;            /* default header (DO NOT REMOVE) */
-           mng_uint16        iId;                /* object-id */
-           mng_bool          bFrozen;            /* frozen flag */
-           mng_bool          bVisible;           /* potential visibility flag */
-           mng_bool          bViewable;          /* viewable flag */
-           mng_bool          bValid;             /* marks invalid when only reading */
-           mng_int32         iPosx;              /* location fields */
-           mng_int32         iPosy;
-           mng_bool          bClipped;           /* clipping fields */
-           mng_int32         iClipl;
-           mng_int32         iClipr;
-           mng_int32         iClipt;
-           mng_int32         iClipb;
-#ifndef MNG_SKIPCHUNK_MAGN
-           mng_uint8         iMAGN_MethodX;      /* magnification (MAGN) */
-           mng_uint8         iMAGN_MethodY;
-           mng_uint16        iMAGN_MX;
-           mng_uint16        iMAGN_MY;
-           mng_uint16        iMAGN_ML;
-           mng_uint16        iMAGN_MR;
-           mng_uint16        iMAGN_MT;
-           mng_uint16        iMAGN_MB;
-#endif
-#ifndef MNG_SKIPCHUNK_PAST
-           mng_int32         iPastx;             /* target x/y from previous PAST */
-           mng_int32         iPasty;
-#endif
-           mng_imagedatap    pImgbuf;            /* the image-data buffer */
-        } mng_image;
-typedef mng_image * mng_imagep;
-
-/* ************************************************************************** */
-
-                                                 /* "on-the-fly" image (= object 0) */       
-typedef mng_image mng_ani_image;                 /* let's (ab)use the general "object" */
-typedef mng_ani_image * mng_ani_imagep;          /* that's actualy crucial, so don't change it! */
-
-/* ************************************************************************** */
-
-typedef struct {                                 /* global PLTE object */
-           mng_object_header sHeader;            /* default header (DO NOT REMOVE) */
-           mng_uint32        iEntrycount;
-           mng_rgbpaltab     aEntries;
-        } mng_ani_plte;
-typedef mng_ani_plte * mng_ani_pltep;
-
-/* ************************************************************************** */
-
-typedef struct {                                 /* global tRNS object */
-           mng_object_header sHeader;            /* default header (DO NOT REMOVE) */
-           mng_uint32        iRawlen;
-           mng_uint8arr      aRawdata;
-        } mng_ani_trns;
-typedef mng_ani_trns * mng_ani_trnsp;
-
-/* ************************************************************************** */
-
-typedef struct {                                 /* global gAMA object */
-           mng_object_header sHeader;            /* default header (DO NOT REMOVE) */
-           mng_bool          bEmpty;
-           mng_uint32        iGamma;
-        } mng_ani_gama;
-typedef mng_ani_gama * mng_ani_gamap;
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_cHRM
-typedef struct {                                 /* global cHRM object */
-           mng_object_header sHeader;            /* default header (DO NOT REMOVE) */
-           mng_bool          bEmpty;
-           mng_uint32        iWhitepointx;
-           mng_uint32        iWhitepointy;
-           mng_uint32        iRedx;
-           mng_uint32        iRedy;
-           mng_uint32        iGreenx;
-           mng_uint32        iGreeny;
-           mng_uint32        iBluex;
-           mng_uint32        iBluey;
-        } mng_ani_chrm;
-typedef mng_ani_chrm * mng_ani_chrmp;
-#endif
-
-/* ************************************************************************** */
-
-typedef struct {                                 /* global sRGB object */
-           mng_object_header sHeader;            /* default header (DO NOT REMOVE) */
-           mng_bool          bEmpty;
-           mng_uint8         iRenderingintent;
-        } mng_ani_srgb;
-typedef mng_ani_srgb * mng_ani_srgbp;
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_iCCP
-typedef struct {                                 /* global iCCP object */
-           mng_object_header sHeader;            /* default header (DO NOT REMOVE) */
-           mng_bool          bEmpty;
-           mng_uint32        iProfilesize;
-           mng_ptr           pProfile;
-        } mng_ani_iccp;
-typedef mng_ani_iccp * mng_ani_iccpp;
-#endif
-
-/* ************************************************************************** */
-
-typedef struct {                                 /* global bKGD object */
-           mng_object_header sHeader;            /* default header (DO NOT REMOVE) */
-           mng_uint16        iRed;
-           mng_uint16        iGreen;
-           mng_uint16        iBlue;
-        } mng_ani_bkgd;
-typedef mng_ani_bkgd * mng_ani_bkgdp;
-
-/* ************************************************************************** */
-
-typedef struct {                                 /* LOOP object */
-           mng_object_header sHeader;            /* default header (DO NOT REMOVE) */
-           mng_uint8         iLevel;
-           mng_uint32        iRepeatcount;
-           mng_uint8         iTermcond;
-           mng_uint32        iItermin;
-           mng_uint32        iItermax;
-           mng_uint32        iCount;
-           mng_uint32p       pSignals;
-
-           mng_uint32        iRunningcount;      /* running counter */
-        } mng_ani_loop;
-typedef mng_ani_loop * mng_ani_loopp;
-
-/* ************************************************************************** */
-
-typedef struct {                                 /* ENDL object */
-           mng_object_header sHeader;            /* default header (DO NOT REMOVE) */
-           mng_uint8         iLevel;
-
-           mng_ani_loopp     pLOOP;              /* matching LOOP */
-        } mng_ani_endl;
-typedef mng_ani_endl * mng_ani_endlp;
-
-/* ************************************************************************** */
-
-typedef struct {                                 /* DEFI object */
-           mng_object_header sHeader;            /* default header (DO NOT REMOVE) */
-           mng_uint16        iId;                
-           mng_bool          bHasdonotshow;
-           mng_uint8         iDonotshow;
-           mng_bool          bHasconcrete;
-           mng_uint8         iConcrete;
-           mng_bool          bHasloca;           
-           mng_int32         iLocax;
-           mng_int32         iLocay;
-           mng_bool          bHasclip;
-           mng_int32         iClipl;
-           mng_int32         iClipr;
-           mng_int32         iClipt;
-           mng_int32         iClipb;
-        } mng_ani_defi;
-typedef mng_ani_defi * mng_ani_defip;
-
-/* ************************************************************************** */
-
-typedef struct {                                 /* BASI object */
-           mng_object_header sHeader;            /* default header (DO NOT REMOVE) */
-           mng_uint16        iRed;               
-           mng_uint16        iGreen;             
-           mng_uint16        iBlue;              
-           mng_bool          bHasalpha;             
-           mng_uint16        iAlpha;
-           mng_uint8         iViewable;
-        } mng_ani_basi;
-typedef mng_ani_basi * mng_ani_basip;
-
-/* ************************************************************************** */
-
-typedef struct {                                 /* CLON object */
-           mng_object_header sHeader;            /* default header (DO NOT REMOVE) */
-           mng_uint16        iCloneid;
-           mng_uint16        iSourceid;
-           mng_uint8         iClonetype;
-           mng_bool          bHasdonotshow;
-           mng_uint8         iDonotshow;
-           mng_uint8         iConcrete;
-           mng_bool          bHasloca;
-           mng_uint8         iLocatype;
-           mng_int32         iLocax;
-           mng_int32         iLocay;
-        } mng_ani_clon;
-typedef mng_ani_clon * mng_ani_clonp;
-
-/* ************************************************************************** */
-
-typedef struct {                                 /* BACK object */
-           mng_object_header sHeader;            /* default header (DO NOT REMOVE) */
-           mng_uint16        iRed;
-           mng_uint16        iGreen;
-           mng_uint16        iBlue;
-           mng_uint8         iMandatory;
-           mng_uint16        iImageid;
-           mng_uint8         iTile;
-        } mng_ani_back;
-typedef mng_ani_back * mng_ani_backp;
-
-/* ************************************************************************** */
-
-typedef struct {                                 /* FRAM object */
-           mng_object_header sHeader;            /* default header (DO NOT REMOVE) */
-           mng_uint8         iFramemode;
-           mng_uint8         iChangedelay;
-           mng_uint32        iDelay;
-           mng_uint8         iChangetimeout;
-           mng_uint32        iTimeout;
-           mng_uint8         iChangeclipping;
-           mng_uint8         iCliptype;
-           mng_int32         iClipl;
-           mng_int32         iClipr;
-           mng_int32         iClipt;
-           mng_int32         iClipb;
-        } mng_ani_fram;
-typedef mng_ani_fram * mng_ani_framp;
-
-/* ************************************************************************** */
-
-typedef struct {                                 /* MOVE object */
-           mng_object_header sHeader;            /* default header (DO NOT REMOVE) */
-           mng_uint16        iFirstid;           
-           mng_uint16        iLastid;            
-           mng_uint8         iType;              
-           mng_int32         iLocax;             
-           mng_int32         iLocay;
-        } mng_ani_move;
-typedef mng_ani_move * mng_ani_movep;
-
-/* ************************************************************************** */
-
-typedef struct {                                 /* CLIP object */
-           mng_object_header sHeader;            /* default header (DO NOT REMOVE) */
-           mng_uint16        iFirstid;           
-           mng_uint16        iLastid;            
-           mng_uint8         iType;              
-           mng_int32         iClipl;             
-           mng_int32         iClipr;             
-           mng_int32         iClipt;             
-           mng_int32         iClipb;
-        } mng_ani_clip;
-typedef mng_ani_clip * mng_ani_clipp;
-
-/* ************************************************************************** */
-
-typedef struct {                                 /* SHOW object */
-           mng_object_header sHeader;            /* default header (DO NOT REMOVE) */
-           mng_uint16        iFirstid;           
-           mng_uint16        iLastid;            
-           mng_uint8         iMode;
-        } mng_ani_show;
-typedef mng_ani_show * mng_ani_showp;
-
-/* ************************************************************************** */
-
-typedef struct {                                 /* TERM object */
-           mng_object_header sHeader;            /* default header (DO NOT REMOVE) */
-           mng_uint8         iTermaction;        
-           mng_uint8         iIteraction;        
-           mng_uint32        iDelay;             
-           mng_uint32        iItermax;
-        } mng_ani_term;
-typedef mng_ani_term * mng_ani_termp;
-
-/* ************************************************************************** */
-
-typedef struct {                                 /* SAVE object */
-           mng_object_header sHeader;            /* default header (DO NOT REMOVE) */
-        } mng_ani_save;
-typedef mng_ani_save * mng_ani_savep;
-
-/* ************************************************************************** */
-
-typedef struct {                                 /* SEEK object */
-           mng_object_header sHeader;            /* default header (DO NOT REMOVE) */
-           mng_uint32        iSegmentnamesize;
-           mng_pchar         zSegmentname;
-        } mng_ani_seek;
-typedef mng_ani_seek * mng_ani_seekp;
-
-/* ************************************************************************** */
-#ifndef MNG_NO_DELTA_PNG
-typedef struct {                                 /* DHDR object */
-           mng_object_header sHeader;            /* default header (DO NOT REMOVE) */
-           mng_uint16        iObjectid;
-           mng_uint8         iImagetype;
-           mng_uint8         iDeltatype;
-           mng_uint32        iBlockwidth;
-           mng_uint32        iBlockheight;
-           mng_uint32        iBlockx;
-           mng_uint32        iBlocky;
-        } mng_ani_dhdr;
-typedef mng_ani_dhdr * mng_ani_dhdrp;
-
-/* ************************************************************************** */
-
-typedef struct {                                 /* PROM object */
-           mng_object_header sHeader;            /* default header (DO NOT REMOVE) */
-           mng_uint8         iBitdepth;
-           mng_uint8         iColortype;
-           mng_uint8         iFilltype;
-        } mng_ani_prom;
-typedef mng_ani_prom * mng_ani_promp;
-
-/* ************************************************************************** */
-
-typedef struct {                                 /* IPNG object */
-           mng_object_header sHeader;            /* default header (DO NOT REMOVE) */
-        } mng_ani_ipng;
-typedef mng_ani_ipng * mng_ani_ipngp;
-
-/* ************************************************************************** */
-
-typedef struct {                                 /* IJNG object */
-           mng_object_header sHeader;            /* default header (DO NOT REMOVE) */
-        } mng_ani_ijng;
-typedef mng_ani_ijng * mng_ani_ijngp;
-
-/* ************************************************************************** */
-
-typedef struct {                                 /* PPLT object */
-           mng_object_header sHeader;            /* default header (DO NOT REMOVE) */
-           mng_uint8         iType;
-           mng_uint32        iCount;
-           mng_rgbpaltab     aIndexentries;
-           mng_uint8arr      aAlphaentries;
-           mng_uint8arr      aUsedentries;
-        } mng_ani_pplt;
-typedef mng_ani_pplt * mng_ani_ppltp;
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_MAGN
-typedef struct {                                 /* MAGN object */
-           mng_object_header sHeader;            /* default header (DO NOT REMOVE) */
-           mng_uint16        iFirstid;
-           mng_uint16        iLastid;
-           mng_uint8         iMethodX;
-           mng_uint16        iMX;
-           mng_uint16        iMY;
-           mng_uint16        iML;
-           mng_uint16        iMR;
-           mng_uint16        iMT;
-           mng_uint16        iMB;
-           mng_uint8         iMethodY;
-        } mng_ani_magn;
-typedef mng_ani_magn * mng_ani_magnp;
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_PAST
-typedef struct {                                 /* PAST object */
-           mng_object_header sHeader;            /* default header (DO NOT REMOVE) */
-           mng_uint16        iTargetid;
-           mng_uint8         iTargettype;
-           mng_int32         iTargetx;
-           mng_int32         iTargety;
-           mng_uint32        iCount;
-           mng_ptr           pSources;
-        } mng_ani_past;
-typedef mng_ani_past * mng_ani_pastp;
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_DISC
-typedef struct {                                 /* DISC object */
-           mng_object_header sHeader;            /* default header (DO NOT REMOVE) */
-           mng_uint32        iCount;
-           mng_uint16p       pIds;
-        } mng_ani_disc;
-typedef mng_ani_disc * mng_ani_discp;
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DYNAMICMNG
-typedef struct {                                 /* event object */
-           mng_object_header sHeader;            /* default header (DO NOT REMOVE) */
-           mng_uint8         iEventtype;
-           mng_uint8         iMasktype;
-           mng_int32         iLeft;
-           mng_int32         iRight;
-           mng_int32         iTop;
-           mng_int32         iBottom;
-           mng_uint16        iObjectid;
-           mng_uint8         iIndex;
-           mng_uint32        iSegmentnamesize;
-           mng_pchar         zSegmentname;
-
-           mng_ani_seekp     pSEEK;              /* SEEK ani object */
-           mng_int32         iLastx;             /* last X/Y coordinates */
-           mng_int32         iLasty;
-        } mng_event;
-typedef mng_event * mng_eventp;
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-typedef struct {                                 /* mPNG object */
-           mng_object_header sHeader;            /* default header (DO NOT REMOVE) */
-           mng_uint32        iFramewidth;
-           mng_uint32        iFrameheight;
-           mng_uint32        iNumplays;
-           mng_uint16        iTickspersec;
-           mng_uint32        iFramessize;
-           mng_ptr           pFrames;
-        } mng_mpng_obj;
-typedef mng_mpng_obj * mng_mpng_objp;
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_ANG_PROPOSAL
-typedef struct {                                 /* ANG object */
-           mng_object_header sHeader;            /* default header (DO NOT REMOVE) */
-           mng_uint32        iNumframes;
-           mng_uint32        iTickspersec;
-           mng_uint32        iNumplays;
-           mng_uint32        iTilewidth;
-           mng_uint32        iTileheight;
-           mng_uint8         iInterlace;
-           mng_uint8         iStillused;
-           mng_uint32        iTilessize;
-           mng_ptr           pTiles;
-        } mng_ang_obj;
-typedef mng_ang_obj * mng_ang_objp;
-#endif
-
-/* ************************************************************************** */
-
-#endif /* MNG_INCLUDE_DISPLAY_PROCS */
-
-/* ************************************************************************** */
-
-#endif /* _libmng_objects_h_ */
-
-/* ************************************************************************** */
-/* * end of file                                                            * */
-/* ************************************************************************** */
diff --git a/Source/LibMNG/libmng_pixels.c b/Source/LibMNG/libmng_pixels.c
deleted file mode 100644
index 9990ee6..0000000
--- a/Source/LibMNG/libmng_pixels.c
+++ /dev/null
@@ -1,24610 +0,0 @@
-/* ************************************************************************** */
-/* *             For conditions of distribution and use,                    * */
-/* *                see copyright notice in libmng.h                        * */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * project   : libmng                                                     * */
-/* * file      : libmng_pixels.c           copyright (c) 2000-2005 G.Juyn   * */
-/* * version   : 1.0.10                                                     * */
-/* *                                                                        * */
-/* * purpose   : Pixel-row management routines (implementation)             * */
-/* *                                                                        * */
-/* * author    : G.Juyn                                                     * */
-/* *                                                                        * */
-/* * comment   : implementation of the pixel-row management routines        * */
-/* *                                                                        * */
-/* *             the dual alpha-composing for RGBA/BGRA/etc output-canvas'  * */
-/* *             is based on the Note on Compositing chapter of the         * */
-/* *             DOH-3 draft, noted to me by Adam M. Costello               * */
-/* *                                                                        * */
-/* * changes   : 0.5.1 - 05/08/2000 - G.Juyn                                * */
-/* *             - changed strict-ANSI stuff                                * */
-/* *             0.5.1 - 05/11/2000 - G.Juyn                                * */
-/* *             - added callback error-reporting support                   * */
-/* *             0.5.1 - 05/12/2000 - G.Juyn                                * */
-/* *             - changed trace to macro for callback error-reporting      * */
-/* *                                                                        * */
-/* *             0.5.2 - 05/22/2000 - G.Juyn                                * */
-/* *             - added JNG support                                        * */
-/* *             0.5.2 - 05/30/2000 - G.Juyn                                * */
-/* *             - fixed minor bugs 16-bit pixel-handling                   * */
-/* *             - added delta-image row-processing routines                * */
-/* *             0.5.2 - 06/02/2000 - G.Juyn                                * */
-/* *             - fixed endian support (hopefully)                         * */
-/* *             0.5.2 - 06/03/2000 - G.Juyn                                * */
-/* *             - fixed makeup for Linux gcc compile                       * */
-/* *             0.5.2 - 06/05/2000 - G.Juyn                                * */
-/* *             - implemented app bkgd restore routines                    * */
-/* *             - implemented RGBA8, ARGB8, BGRA8 & ABGR8 display routines * */
-/* *             - added support for RGB8_A8 canvasstyle                    * */
-/* *             0.5.2 - 06/09/2000 - G.Juyn                                * */
-/* *             - fixed alpha-handling for alpha canvasstyles              * */
-/* *                                                                        * */
-/* *             0.5.3 - 06/16/2000 - G.Juyn                                * */
-/* *             - changed progressive-display processing                   * */
-/* *             0.5.3 - 06/17/2000 - G.Juyn                                * */
-/* *             - changed to support delta-images                          * */
-/* *             - optimized some store_xxx routines                        * */
-/* *             0.5.3 - 06/20/2000 - G.Juyn                                * */
-/* *             - fixed nasty bug with embedded PNG after delta-image      * */
-/* *             0.5.3 - 06/24/2000 - G.Juyn                                * */
-/* *             - fixed problem with 16-bit GA format                      * */
-/* *             0.5.3 - 06/25/2000 - G.Juyn                                * */
-/* *             - fixed problem with cheap transparency for 4-bit gray     * */
-/* *             - fixed display_xxxx routines for interlaced images        * */
-/* *             0.5.3 - 06/28/2000 - G.Juyn                                * */
-/* *             - fixed compiler-warning for non-initialized iB variable   * */
-/* *                                                                        * */
-/* *             0.9.1 - 07/05/2000 - G.Juyn                                * */
-/* *             - fixed mandatory BACK color to be opaque                  * */
-/* *                                                                        * */
-/* *             0.9.2 - 07/31/2000 - G.Juyn                                * */
-/* *             - B110547 - fixed bug in interlace code                    * */
-/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
-/* *             - changed file-prefixes                                    * */
-/* *                                                                        * */
-/* *             0.9.3 - 08/20/2000 - G.Juyn                                * */
-/* *             - fixed app-supplied background restore                    * */
-/* *             0.9.3 - 08/26/2000 - G.Juyn                                * */
-/* *             - added MAGN chunk                                         * */
-/* *             0.9.3 - 09/07/2000 - G.Juyn                                * */
-/* *             - added support for new filter_types                       * */
-/* *             0.9.3 - 09/30/2000 - G.Juyn                                * */
-/* *             - fixed MAGN rounding errors (thanks Matthias!)            * */
-/* *             0.9.3 - 10/10/2000 - G.Juyn                                * */
-/* *             - fixed alpha-blending for RGBA canvasstyle                * */
-/* *             0.9.3 - 10/11/2000 - G.Juyn                                * */
-/* *             - fixed alpha-blending for other alpha-canvasstyles        * */
-/* *             0.9.3 - 10/16/2000 - G.Juyn                                * */
-/* *             - added optional support for bKGD for PNG images           * */
-/* *             - added support for JDAA                                   * */
-/* *             0.9.3 - 10/17/2000 - G.Juyn                                * */
-/* *             - fixed support for bKGD                                   * */
-/* *             0.9.3 - 10/19/2000 - G.Juyn                                * */
-/* *             - implemented delayed delta-processing                     * */
-/* *             0.9.3 - 10/28/2000 - G.Juyn                                * */
-/* *             - fixed tRNS processing for gray-image < 8-bits            * */
-/* *                                                                        * */
-/* *             0.9.4 - 12/16/2000 - G.Juyn                                * */
-/* *             - fixed mixup of data- & function-pointers (thanks Dimitri)* */
-/* *             0.9.4 -  1/18/2001 - G.Juyn                                * */
-/* *             - removed "old" MAGN methods 3 & 4                         * */
-/* *             - added "new" MAGN methods 3, 4 & 5                        * */
-/* *             - removed test filter-methods 1 & 65                       * */
-/* *                                                                        * */
-/* *             1.0.1 - 04/21/2001 - G.Juyn (code by G.Kelly)              * */
-/* *             - added BGRA8 canvas with premultiplied alpha              * */
-/* *             1.0.1 - 04/25/2001 - G.Juyn                                * */
-/* *             - moved mng_clear_cms to libmng_cms                        * */
-/* *                                                                        * */
-/* *             1.0.2 - 06/25/2001 - G.Juyn                                * */
-/* *             - added option to turn off progressive refresh             * */
-/* *                                                                        * */
-/* *             1.0.4 - 11/04/2001 - G.Juyn                                * */
-/* *             - fixed possible compile-problem in cleanup_rowproc        * */
-/* *             1.0.4 - 06/22/2002 - G.Juyn                                * */
-/* *             - B558212 - off by one error                               * */
-/* *             - MNG subimage alpha composite wrong for rgba8 images      * */
-/* *                                                                        * */
-/* *             1.0.5 - 08/07/2002 - G.Juyn                                * */
-/* *             - added test-option for PNG filter method 193 (=no filter) * */
-/* *             1.0.5 - 08/15/2002 - G.Juyn                                * */
-/* *             - completed PROM support                                   * */
-/* *             - completed delta-image support                            * */
-/* *             1.0.5 - 08/16/2002 - G.Juyn                                * */
-/* *             - completed MAGN support (16-bit functions)                * */
-/* *             1.0.5 - 08/19/2002 - G.Juyn                                * */
-/* *             - B597134 - libmng pollutes the linker namespace           * */
-/* *             1.0.5 - 09/19/2002 - G.Juyn                                * */
-/* *             - optimized restore-background for bKGD cases              * */
-/* *             1.0.5 - 09/20/2002 - G.Juyn                                * */
-/* *             - finished support for BACK image & tiling                 * */
-/* *             1.0.5 - 09/22/2002 - G.Juyn                                * */
-/* *             - added bgrx8 canvas (filler byte)                         * */
-/* *             1.0.5 - 09/23/2002 - G.Juyn                                * */
-/* *             - added compose over/under routines for PAST processing    * */
-/* *             - added flip & tile routines for PAST processing           * */
-/* *                                                                        * */
-/* *             1.0.6 - 03/09/2003 - G.Juyn                                * */
-/* *             - hiding 12-bit JPEG stuff                                 * */
-/* *             1.0.6 - 05/11/2003 - Glenn RP                              * */
-/* *             - added size-optimization COMPOSE routine usage            * */
-/* *             1.0.6 - 05/11/2003 - G. Juyn                               * */
-/* *             - added conditionals around canvas update routines         * */
-/* *             1.0.6 - 05/25/2003 - Glenn RP                              * */
-/* *             - added size-optimization DIV255B8 routine usage           * */
-/* *             1.0.6 - 06/09/2003 - G. R-P                                * */
-/* *             - added conditionals around 8-bit magn routines            * */
-/* *             1.0.6 - 07/07/2003 - G. R-P                                * */
-/* *             - removed conditionals around 8-bit magn routines          * */
-/* *             - added MNG_NO_16BIT_SUPPORT and MNG_NO_DELTA_PNG          * */
-/* *               conditionals                                             * */
-/* *             - reversed many loops to use decrementing counter          * */
-/* *             - combined init functions                                  * */
-/* *             - converted some switches to array references              * */
-/* *             1.0.6 - 07/29/2003 - G.Juyn                                * */
-/* *             - fixed duplicate for-loop                                 * */
-/* *             1.0.6 - 07/29/2003 - G.R-P                                 * */
-/* *             - added SKIPCHUNK conditionals around PAST chunk support   * */
-/* *             - fixed "FOOTPRINT_COMPOSEIV" typo (now "FOOTPRINT_DIV")   * */
-/* *             1.0.6 - 08/17/2003 - G.R-P                                 * */
-/* *             - added more conditionals around "promote" functions       * */
-/* *                                                                        * */
-/* *             1.0.7 - 11/27/2003 - R.A                                   * */
-/* *             - added CANVAS_RGB565 and CANVAS_BGR565                    * */
-/* *             1.0.7 - 12/06/2003 - R.A                                   * */
-/* *             - added CANVAS_RGBA565 and CANVAS_BGRA565                  * */
-/* *             1.0.7 - 01/25/2004 - J.S                                   * */
-/* *             - added premultiplied alpha canvas' for RGBA, ARGB, ABGR   * */
-/* *             1.0.7 - 03/08/2004 - G.R-P                                 * */
-/* *             - added more conditionals around 16-bit-supporting code    * */
-/* *             1.0.7 - 03/09/2004 - G.Juyn                                * */
-/* *             - fixed bug in promote_g8_g8 with 16bit support off        * */
-/* *             1.0.7 - 03/09/2004 - G.R-P                                 * */
-/* *             - more optimizations with 16bit support off                * */
-/* *             1.0.7 - 03/10/2004 - G.Juyn                                * */
-/* *             - fixed some warnings for 16bit optimizations              * */
-/* *             1.0.7 - 03/21/2004 - G.Juyn                                * */
-/* *             - fixed some 64-bit platform compiler warnings             * */
-/* *                                                                        * */
-/* *             1.0.8 - 06/20/2004 - G.Juyn                                * */
-/* *             - some speed optimizations (thanks to John Stiles)         * */
-/* *             1.0.8 - 08/01/2004 - G.Juyn                                * */
-/* *             - added support for 3+byte pixelsize for JPEG's            * */
-/* *                                                                        * */
-/* *             1.0.9 - 10/10/2004 - G.R-P.                                * */
-/* *             - added MNG_NO_1_2_4BIT_SUPPORT                            * */
-/* *             1.0.9 - 10/14/2004 - G.Juyn                                * */
-/* *             - added bgr565_a8 canvas-style (thanks to J. Elvander)     * */
-/* *             1.0.9 - 12/05/2004 - G.Juyn                                * */
-/* *             - added LITTLEENDIAN/BIGENDIAN fixtures (thanks J.Stiles)  * */
-/* *             - fixed MNG_NO_1_2_4BIT_SUPPORT for TBBN1G04.PNG           * */
-/* *             1.0.9 - 12/31/2004 - G.R-P.                                * */
-/* *             - fixed warnings about C++ style (//) comments             * */
-/* *                                                                        * */
-/* *             1.0.10 - 07/06/2005 - G.R-P.                               * */
-/* *             - added MORE MNG_NO_1_2_4BIT_SUPPORT                       * */
-/* *             1.0.10 - 10/06/2005 - G.R-P.                               * */
-/* *             - alloc more memory for MNG_NO_1_2_4BIT_SUPPORT            * */
-/* *             1.0.10 - 12/07/2005 - G.R-P.                               * */
-/* *             - optimized footprint of 16bit support                     * */
-/* *             1.0.10 - 03/07/2006 - (thanks to W. Manthey)               * */
-/* *             - added CANVAS_RGB555 and CANVAS_BGR555                    * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#include "libmng.h"
-#include "libmng_data.h"
-#include "libmng_error.h"
-#include "libmng_trace.h"
-#ifdef __BORLANDC__
-#pragma hdrstop
-#endif
-#include "libmng_objects.h"
-#include "libmng_object_prc.h"
-#include "libmng_memory.h"
-#include "libmng_cms.h"
-#include "libmng_filter.h"
-#include "libmng_pixels.h"
-
-#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
-#pragma option -A                      /* force ANSI-C */
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_DISPLAY_PROCS
-
-/* TODO: magnification & canvas-positioning/-clipping */
-
-/* TODO: major optimization of pixel-loops by using assembler (?) */
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Interlace tables                                                       * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-MNG_LOCAL mng_uint32 const interlace_row      [7] = { 0, 0, 4, 0, 2, 0, 1 };
-MNG_LOCAL mng_uint32 const interlace_rowskip  [7] = { 8, 8, 8, 4, 4, 2, 2 };
-MNG_LOCAL mng_uint32 const interlace_col      [7] = { 0, 4, 0, 2, 0, 1, 0 };
-MNG_LOCAL mng_uint32 const interlace_colskip  [7] = { 8, 8, 4, 4, 2, 2, 1 };
-MNG_LOCAL mng_uint32 const interlace_roundoff [7] = { 7, 7, 3, 3, 1, 1, 0 };
-MNG_LOCAL mng_uint32 const interlace_divider  [7] = { 3, 3, 2, 2, 1, 1, 0 };
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Alpha composing macros                                                 * */
-/* * the code below is slightly modified from the libpng package            * */
-/* * the original was last optimized by Greg Roelofs & Mark Adler           * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#define MNG_COMPOSE8(RET,FG,ALPHA,BG) {                                    \
-       mng_uint16 iH = (mng_uint16)((mng_uint16)(FG) * (mng_uint16)(ALPHA) \
-                        + (mng_uint16)(BG)*(mng_uint16)(255 -              \
-                          (mng_uint16)(ALPHA)) + (mng_uint16)128);         \
-       (RET) = (mng_uint8)((iH + (iH >> 8)) >> 8); }
-
-#define MNG_COMPOSE16(RET,FG,ALPHA,BG) {                                   \
-       mng_uint32 iH = (mng_uint32)((mng_uint32)(FG) * (mng_uint32)(ALPHA) \
-                        + (mng_uint32)(BG)*(mng_uint32)(65535L -           \
-                          (mng_uint32)(ALPHA)) + (mng_uint32)32768L);      \
-       (RET) = (mng_uint16)((iH + (iH >> 16)) >> 16); }
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Alpha blending macros                                                  * */
-/* * this code is based on Adam Costello's "Note on Compositing" from the   * */
-/* * mng-list which gives the following formula:                            * */
-/* *                                                                        * */
-/* * top pixel       = (Rt, Gt, Bt, At)                                     * */
-/* * bottom pixel    = (Rb, Gb, Bb, Ab)                                     * */
-/* * composite pixel = (Rc, Gc, Bc, Ac)                                     * */
-/* *                                                                        * */
-/* * all values in the range 0..1                                           * */
-/* *                                                                        * */
-/* * Ac = 1 - (1 - At)(1 - Ab)                                              * */
-/* * s = At / Ac                                                            * */
-/* * t = (1 - At) Ab / Ac                                                   * */
-/* * Rc = s Rt + t Rb                                                       * */
-/* * Gc = s Gt + t Gb                                                       * */
-/* * Bc = s Bt + t Bb                                                       * */
-/* *                                                                        * */
-/* * (I just hope I coded it correctly in integer arithmetic...)            * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#define MNG_BLEND8(RT, GT, BT, AT, RB, GB, BB, AB, RC, GC, BC, AC) {         \
-       mng_uint32 S, T;                                                      \
-       (AC) = (mng_uint8)((mng_uint32)255 -                                  \
-                          ((((mng_uint32)255 - (mng_uint32)(AT)) *           \
-                            ((mng_uint32)255 - (mng_uint32)(AB))   ) >> 8)); \
-       S    = (mng_uint32)(((mng_uint32)(AT) << 8) /                         \
-                           (mng_uint32)(AC));                                \
-       T    = (mng_uint32)(((mng_uint32)255 - (mng_uint32)(AT)) *            \
-                            (mng_uint32)(AB) / (mng_uint32)(AC));            \
-       (RC) = (mng_uint8)((S * (mng_uint32)(RT) +                            \
-                           T * (mng_uint32)(RB) + (mng_uint32)127) >> 8);    \
-       (GC) = (mng_uint8)((S * (mng_uint32)(GT) +                            \
-                           T * (mng_uint32)(GB) + (mng_uint32)127) >> 8);    \
-       (BC) = (mng_uint8)((S * (mng_uint32)(BT) +                            \
-                           T * (mng_uint32)(BB) + (mng_uint32)127) >> 8); }
-
-#define MNG_BLEND16(RT, GT, BT, AT, RB, GB, BB, AB, RC, GC, BC, AC) {            \
-       mng_uint32 S, T;                                                          \
-       (AC) = (mng_uint16)((mng_uint32)65535 -                                   \
-                           ((((mng_uint32)65535 - (mng_uint32)(AT)) *            \
-                             ((mng_uint32)65535 - (mng_uint32)(AB))   ) >> 16)); \
-       S    = (mng_uint32)(((mng_uint32)(AT) << 16) /                            \
-                            (mng_uint32)(AC));                                   \
-       T    = (mng_uint32)(((mng_uint32)65535 - (mng_uint32)(AT)) *              \
-                            (mng_uint32)(AB) / (mng_uint32)(AC));                \
-       (RC) = (mng_uint16)((S * (mng_uint32)(RT) +                               \
-                            T * (mng_uint32)(RB) + (mng_uint32)32767) >> 16);    \
-       (GC) = (mng_uint16)((S * (mng_uint32)(GT) +                               \
-                            T * (mng_uint32)(GB) + (mng_uint32)32767) >> 16);    \
-       (BC) = (mng_uint16)((S * (mng_uint32)(BT) +                               \
-                            T * (mng_uint32)(BB) + (mng_uint32)32767) >> 16); }
-
-/* ************************************************************************** */
-
-/* note a good optimizing compiler will optimize this */
-#define DIV255B8(x) (mng_uint8)(((x) + 127) / 255)
-#define DIV255B16(x) (mng_uint16)(((x) + 32767) / 65535)
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Progressive display check - checks to see if progressive display is    * */
-/* * in order & indicates so                                                * */
-/* *                                                                        * */
-/* * The routine is called after a call to one of the display_xxx routines  * */
-/* * if appropriate                                                         * */
-/* *                                                                        * */
-/* * The refresh is warrented in the read_chunk routine (mng_read.c)        * */
-/* * and only during read&display processing, since there's not much point  * */
-/* * doing it from memory!                                                  * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-mng_retcode mng_display_progressive_check (mng_datap pData)
-{
-  if ((pData->bDoProgressive) &&       /* need progressive display? */
-      ((pData->eImagetype != mng_it_mng) || (pData->iDataheight > 300)) &&
-      (pData->iDestb - pData->iDestt > 50) && (!pData->pCurraniobj))
-  {
-    mng_int32 iC = pData->iRow + pData->iDestt - pData->iSourcet;
-
-    if (iC % 20 == 0)                  /* every 20th line */
-      pData->bNeedrefresh = MNG_TRUE;
-
-  }
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Display routines - convert rowdata (which is already color-corrected)  * */
-/* * to the output canvas, respecting the opacity information               * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-MNG_LOCAL void check_update_region (mng_datap pData)
-{                                      /* determine actual canvas row */
-  mng_int32 iRow = pData->iRow + pData->iDestt - pData->iSourcet;
-                                       /* check for change in update-region */
-  if ((pData->iDestl < (mng_int32)pData->iUpdateleft) || (pData->iUpdateright == 0))
-    pData->iUpdateleft   = pData->iDestl;
-
-  if (pData->iDestr > (mng_int32)pData->iUpdateright)
-    pData->iUpdateright  = pData->iDestr;
-
-  if ((iRow < (mng_int32)pData->iUpdatetop) || (pData->iUpdatebottom == 0))
-    pData->iUpdatetop    = iRow;
-
-  if (iRow+1 > (mng_int32)pData->iUpdatebottom)
-    pData->iUpdatebottom = iRow+1;
-
-  return;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCANVAS_RGB8
-#ifndef MNG_NO_16BIT_SUPPORT
-#ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
-mng_retcode mng_display_rgb8 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint16 iA16;
-  mng_uint16 iFGr16, iFGg16, iFGb16;
-  mng_uint16 iBGr16, iBGg16, iBGb16;
-  mng_uint8  iA8;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8, MNG_LC_START);
-#endif
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol * 3) + (pData->iDestl * 3);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-    if (pData->bIsRGBA16)              /* adjust source row starting-point */
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
-    else
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* scale down by dropping the LSB */
-          *pScanline     = *pDataline;
-          *(pScanline+1) = *(pDataline+2);
-          *(pScanline+2) = *(pDataline+4);
-
-          pScanline += (pData->iColinc * 3);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values */
-          *pScanline     = *pDataline;
-          *(pScanline+1) = *(pDataline+1);
-          *(pScanline+2) = *(pDataline+2);
-
-          pScanline += (pData->iColinc * 3);
-          pDataline += 4;
-        }
-      }
-    }
-    else
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iA16 = mng_get_uint16 (pDataline+6);
-
-          if (iA16)                    /* any opacity at all ? */
-          {
-            if (iA16 == 0xFFFF)        /* fully opaque ? */
-            {                          /* scale down by dropping the LSB */
-              *pScanline     = *pDataline;
-              *(pScanline+1) = *(pDataline+2);
-              *(pScanline+2) = *(pDataline+4);
-            }
-            else
-            {                          /* get the proper values */
-              iFGr16 = mng_get_uint16 (pDataline  );
-              iFGg16 = mng_get_uint16 (pDataline+2);
-              iFGb16 = mng_get_uint16 (pDataline+4);
-                                       /* scale background up */
-              iBGr16 = (mng_uint16)(*pScanline    );
-              iBGg16 = (mng_uint16)(*(pScanline+1));
-              iBGb16 = (mng_uint16)(*(pScanline+2));
-              iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
-              iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-              iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
-                                       /* now compose */
-              MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16);
-              MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
-              MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16);
-                                       /* and return the composed values */
-              *pScanline     = (mng_uint8)(iFGr16 >> 8);
-              *(pScanline+1) = (mng_uint8)(iFGg16 >> 8);
-              *(pScanline+2) = (mng_uint8)(iFGb16 >> 8);
-            }
-          }
-
-          pScanline += (pData->iColinc * 3);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iA8 = *(pDataline+3);        /* get alpha value */
-
-          if (iA8)                     /* any opacity at all ? */
-          {
-            if (iA8 == 0xFF)           /* fully opaque ? */
-            {                          /* then simply copy the values */
-              *pScanline     = *pDataline;
-              *(pScanline+1) = *(pDataline+1);
-              *(pScanline+2) = *(pDataline+2);
-            }
-            else
-            {                          /* do alpha composing */
-              MNG_COMPOSE8 (*pScanline,     *pDataline,     iA8, *pScanline    );
-              MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iA8, *(pScanline+1));
-              MNG_COMPOSE8 (*(pScanline+2), *(pDataline+2), iA8, *(pScanline+2));
-            }
-          }
-
-          pScanline += (pData->iColinc * 3);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
-mng_retcode mng_display_rgb8 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint16 iA16;
-  mng_uint16 iFGg16;
-  mng_uint16 iBGg16;
-  mng_uint8  iA8;
-  mng_uint8  iBps;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8, MNG_LC_START);
-#endif
-
-  iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol * 3) + (pData->iDestl * 3);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-    /* adjust source row starting-point */
-    pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* scale down by dropping the LSB */
-          *pScanline     = *pDataline;
-          *(pScanline+1) = *(pDataline+iBps);
-          *(pScanline+2) = *(pDataline+2*iBps);
-
-          pScanline += (pData->iColinc * 3);
-          pDataline += 4*iBps;
-        }
-      }
-    }
-    else
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iA16 = mng_get_uint16 (pDataline+6);
-
-          if (iA16)                    /* any opacity at all ? */
-          {
-            if (iA16 == 0xFFFF)        /* fully opaque ? */
-            {                          /* scale down by dropping the LSB */
-              *pScanline     = *pDataline;
-              *(pScanline+1) = *(pDataline+2);
-              *(pScanline+2) = *(pDataline+4);
-            }
-            else
-            {                          /* get the proper values */
-              int i;
-              for (i=2; i >= 0; i--)
-              {
-                iFGg16 = mng_get_uint16 (pDataline+i+i);
-                                         /* scale background up */
-                iBGg16 = (mng_uint16)(*(pScanline+i));
-                iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-                                         /* now compose */
-                MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
-                                         /* and return the composed values */
-                *(pScanline+i) = (mng_uint8)(iFGg16 >> 8);
-              }
-            }
-          }
-
-          pScanline += (pData->iColinc * 3);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iA8 = *(pDataline+3);        /* get alpha value */
-
-          if (iA8)                     /* any opacity at all ? */
-          {
-            if (iA8 == 0xFF)           /* fully opaque ? */
-            {                          /* then simply copy the values */
-              *pScanline     = *pDataline;
-              *(pScanline+1) = *(pDataline+1);
-              *(pScanline+2) = *(pDataline+2);
-            }
-            else
-            {                          /* do alpha composing */
-              int i;
-              for (i=2; i >= 0; i--)
-              {
-              MNG_COMPOSE8 (*(pScanline+i), *(pDataline+i), iA8, *(pScanline+i));
-              }
-            }
-          }
-
-          pScanline += (pData->iColinc * 3);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
-#else /* MNG_NO_16BIT_SUPPORT */
-mng_retcode mng_display_rgb8 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint8  iA8;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8, MNG_LC_START);
-#endif
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol * 3) + (pData->iDestl * 3);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values */
-          *pScanline     = *pDataline;
-          *(pScanline+1) = *(pDataline+1);
-          *(pScanline+2) = *(pDataline+2);
-
-          pScanline += (pData->iColinc * 3);
-          pDataline += 4;
-        }
-      }
-    }
-    else
-    {
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iA8 = *(pDataline+3);        /* get alpha value */
-
-          if (iA8)                     /* any opacity at all ? */
-          {
-            if (iA8 == 0xFF)           /* fully opaque ? */
-            {                          /* then simply copy the values */
-              *pScanline     = *pDataline;
-              *(pScanline+1) = *(pDataline+1);
-              *(pScanline+2) = *(pDataline+2);
-            }
-            else
-            {                          /* do alpha composing */
-#ifdef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
-              int i;
-              for (i=2; i >= 0; i--)
-              {
-              MNG_COMPOSE8 (*(pScanline+i), *(pDataline+i), iA8, *(pScanline+i));
-              }
-#else
-              MNG_COMPOSE8 (*pScanline,     *pDataline,     iA8, *pScanline    );
-              MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iA8, *(pScanline+1));
-              MNG_COMPOSE8 (*(pScanline+2), *(pDataline+2), iA8, *(pScanline+2));
-#endif
-            }
-          }
-
-          pScanline += (pData->iColinc * 3);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_NO_16BIT_SUPPORT */
-#endif /* MNG_SKIPCANVAS_RGB8 */
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCANVAS_RGBA8
-#ifndef MNG_NO_16BIT_SUPPORT
-#ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
-mng_retcode mng_display_rgba8 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint8  iFGa8, iBGa8, iCa8;
-  mng_uint16 iFGa16, iBGa16, iCa16;
-  mng_uint16 iFGr16, iFGg16, iFGb16;
-  mng_uint16 iBGr16, iBGg16, iBGb16;
-  mng_uint16 iCr16, iCg16, iCb16;
-  mng_uint8  iCr8, iCg8, iCb8;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA8, MNG_LC_START);
-#endif
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-    if (pData->bIsRGBA16)              /* adjust source row starting-point */
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
-    else
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* scale down by dropping the LSB */
-          *pScanline     = *pDataline;
-          *(pScanline+1) = *(pDataline+2);
-          *(pScanline+2) = *(pDataline+4);
-          *(pScanline+3) = *(pDataline+6);
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values */
-          *pScanline     = *pDataline;
-          *(pScanline+1) = *(pDataline+1);
-          *(pScanline+2) = *(pDataline+2);
-          *(pScanline+3) = *(pDataline+3);
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-    else
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* get alpha values */
-          iFGa16 = mng_get_uint16 (pDataline+6);
-          iBGa16 = (mng_uint16)(*(pScanline+3));
-          iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
-
-          if (iFGa16)                  /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
-            {                          /* plain copy it */
-              *pScanline     = *pDataline;
-              *(pScanline+1) = *(pDataline+2);
-              *(pScanline+2) = *(pDataline+4);
-              *(pScanline+3) = *(pDataline+6);
-            }
-            else
-            {
-              if (iBGa16 == 0xFFFF)    /* background fully opaque ? */
-              {                        /* get the proper values */
-                iFGr16 = mng_get_uint16 (pDataline  );
-                iFGg16 = mng_get_uint16 (pDataline+2);
-                iFGb16 = mng_get_uint16 (pDataline+4);
-                                       /* scale background up */
-                iBGr16 = (mng_uint16)(*pScanline    );
-                iBGg16 = (mng_uint16)(*(pScanline+1));
-                iBGb16 = (mng_uint16)(*(pScanline+2));
-                iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
-                iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-                iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
-                                       /* now compose */
-                MNG_COMPOSE16(iFGr16, iFGr16, iFGa16, iBGr16);
-                MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
-                MNG_COMPOSE16(iFGb16, iFGb16, iFGa16, iBGb16);
-                                       /* and return the composed values */
-                *pScanline     = (mng_uint8)(iFGr16 >> 8);
-                *(pScanline+1) = (mng_uint8)(iFGg16 >> 8);
-                *(pScanline+2) = (mng_uint8)(iFGb16 >> 8);
-                                       /* alpha remains fully opaque !!! */
-              }
-              else
-              {                        /* scale background up */
-                iBGr16 = (mng_uint16)(*pScanline    );
-                iBGg16 = (mng_uint16)(*(pScanline+1));
-                iBGb16 = (mng_uint16)(*(pScanline+2));
-                iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
-                iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-                iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
-                                       /* let's blend */
-                MNG_BLEND16 (mng_get_uint16 (pDataline  ),
-                             mng_get_uint16 (pDataline+2),
-                             mng_get_uint16 (pDataline+4), iFGa16,
-                             iBGr16, iBGg16, iBGb16, iBGa16,
-                             iCr16,  iCg16,  iCb16,  iCa16);
-                                       /* and return the composed values */
-                *pScanline     = (mng_uint8)(iCr16 >> 8);
-                *(pScanline+1) = (mng_uint8)(iCg16 >> 8);
-                *(pScanline+2) = (mng_uint8)(iCb16 >> 8);
-                *(pScanline+3) = (mng_uint8)(iCa16 >> 8);
-              }
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iFGa8 = *(pDataline+3);      /* get alpha values */
-          iBGa8 = *(pScanline+3);
-
-          if (iFGa8)                   /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if ((iFGa8 == 0xFF) || (iBGa8 == 0))
-            {                          /* then simply copy the values */
-              *pScanline     = *pDataline;
-              *(pScanline+1) = *(pDataline+1);
-              *(pScanline+2) = *(pDataline+2);
-              *(pScanline+3) = *(pDataline+3);
-            }
-            else
-            {
-              if (iBGa8 == 0xFF)       /* background fully opaque ? */
-              {                        /* do alpha composing */
-                MNG_COMPOSE8 (*pScanline,     *pDataline,     iFGa8, *pScanline    );
-                MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iFGa8, *(pScanline+1));
-                MNG_COMPOSE8 (*(pScanline+2), *(pDataline+2), iFGa8, *(pScanline+2));
-                                       /* alpha remains fully opaque !!! */
-              }
-              else
-              {                        /* now blend */
-                MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
-                            *pScanline, *(pScanline+1), *(pScanline+2), iBGa8,
-                            iCr8, iCg8, iCb8, iCa8);
-                                       /* and return the composed values */
-                *pScanline     = iCr8;
-                *(pScanline+1) = iCg8;
-                *(pScanline+2) = iCb8;
-                *(pScanline+3) = iCa8;
-              }
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
-mng_retcode mng_display_rgba8 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint8  iFGa8, iBGa8, iCa8;
-  mng_uint16 iFGa16, iBGa16, iCa16;
-  mng_uint16 iFGg16;
-  mng_uint16 iBGr16, iBGg16, iBGb16;
-  mng_uint16 iCr16, iCg16, iCb16;
-  mng_uint8  iCr8, iCg8, iCb8;
-  mng_uint8  iBps;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA8, MNG_LC_START);
-#endif
-
-  iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-    /* adjust source row starting-point */
-    pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* scale down by dropping the LSB */
-          *pScanline     = *pDataline;
-          *(pScanline+1) = *(pDataline+iBps);
-          *(pScanline+2) = *(pDataline+2*iBps);
-          *(pScanline+3) = *(pDataline+3*iBps);
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4*iBps;
-        }
-    }
-    else
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* get alpha values */
-          iFGa16 = mng_get_uint16 (pDataline+6);
-          iBGa16 = (mng_uint16)(*(pScanline+3));
-          iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
-
-          if (iFGa16)                  /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
-            {                          /* plain copy it */
-              *pScanline     = *pDataline;
-              *(pScanline+1) = *(pDataline+2);
-              *(pScanline+2) = *(pDataline+4);
-              *(pScanline+3) = *(pDataline+6);
-            }
-            else
-            {
-              if (iBGa16 == 0xFFFF)    /* background fully opaque ? */
-              {                        /* get the proper values */
-              int i;
-              for (i=2; i >= 0; i--)
-              {
-                iFGg16 = mng_get_uint16 (pDataline+i+i);
-                                       /* scale background up */
-                iBGg16 = (mng_uint16)(*(pScanline+i));
-                iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-                                       /* now compose */
-                MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
-                                       /* and return the composed values */
-                *(pScanline+i) = (mng_uint8)(iFGg16 >> 8);
-                                       /* alpha remains fully opaque !!! */
-              }
-              }
-              else
-              {                        /* scale background up */
-                iBGr16 = (mng_uint16)(*pScanline    );
-                iBGg16 = (mng_uint16)(*(pScanline+1));
-                iBGb16 = (mng_uint16)(*(pScanline+2));
-                iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
-                iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-                iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
-                                       /* let's blend */
-                MNG_BLEND16 (mng_get_uint16 (pDataline  ),
-                             mng_get_uint16 (pDataline+2),
-                             mng_get_uint16 (pDataline+4), iFGa16,
-                             iBGr16, iBGg16, iBGb16, iBGa16,
-                             iCr16,  iCg16,  iCb16,  iCa16);
-                                       /* and return the composed values */
-                *pScanline     = (mng_uint8)(iCr16 >> 8);
-                *(pScanline+1) = (mng_uint8)(iCg16 >> 8);
-                *(pScanline+2) = (mng_uint8)(iCb16 >> 8);
-                *(pScanline+3) = (mng_uint8)(iCa16 >> 8);
-              }
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iFGa8 = *(pDataline+3);      /* get alpha values */
-          iBGa8 = *(pScanline+3);
-
-          if (iFGa8)                   /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if ((iFGa8 == 0xFF) || (iBGa8 == 0))
-            {                          /* then simply copy the values */
-              *pScanline     = *pDataline;
-              *(pScanline+1) = *(pDataline+1);
-              *(pScanline+2) = *(pDataline+2);
-              *(pScanline+3) = *(pDataline+3);
-            }
-            else
-            {
-              if (iBGa8 == 0xFF)       /* background fully opaque ? */
-              {                        /* do alpha composing */
-              int i;
-              for (i=2; i >= 0; i--)
-              {
-              MNG_COMPOSE8 (*(pScanline+i), *(pDataline+i), iFGa8, *(pScanline+i));
-              }
-                                       /* alpha remains fully opaque !!! */
-              }
-              else
-              {                        /* now blend */
-                MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
-                            *pScanline, *(pScanline+1), *(pScanline+2), iBGa8,
-                            iCr8, iCg8, iCb8, iCa8);
-                                       /* and return the composed values */
-                *pScanline     = iCr8;
-                *(pScanline+1) = iCg8;
-                *(pScanline+2) = iCb8;
-                *(pScanline+3) = iCa8;
-              }
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
-#else /* MNG_NO_16BIT_SUPPORT */
-mng_retcode mng_display_rgba8 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint8  iFGa8, iBGa8, iCa8;
-  mng_uint8  iCr8, iCg8, iCb8;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA8, MNG_LC_START);
-#endif
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values */
-          *pScanline     = *pDataline;
-          *(pScanline+1) = *(pDataline+1);
-          *(pScanline+2) = *(pDataline+2);
-          *(pScanline+3) = *(pDataline+3);
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-    else
-    {
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iFGa8 = *(pDataline+3);      /* get alpha values */
-          iBGa8 = *(pScanline+3);
-
-          if (iFGa8)                   /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if ((iFGa8 == 0xFF) || (iBGa8 == 0))
-            {                          /* then simply copy the values */
-              *pScanline     = *pDataline;
-              *(pScanline+1) = *(pDataline+1);
-              *(pScanline+2) = *(pDataline+2);
-              *(pScanline+3) = *(pDataline+3);
-            }
-            else
-            {
-              if (iBGa8 == 0xFF)       /* background fully opaque ? */
-              {                        /* do alpha composing */
-#ifdef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
-              int i;
-              for (i=2; i >= 0; i--)
-              {
-              MNG_COMPOSE8 (*(pScanline+i), *(pDataline+i), iFGa8, *(pScanline+i));
-              }
-#else
-                MNG_COMPOSE8 (*pScanline,     *pDataline,     iFGa8, *pScanline    );
-                MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iFGa8, *(pScanline+1));
-                MNG_COMPOSE8 (*(pScanline+2), *(pDataline+2), iFGa8, *(pScanline+2));
-#endif
-                                       /* alpha remains fully opaque !!! */
-              }
-              else
-              {                        /* now blend */
-                MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
-                            *pScanline, *(pScanline+1), *(pScanline+2), iBGa8,
-                            iCr8, iCg8, iCb8, iCa8);
-                                       /* and return the composed values */
-                *pScanline     = iCr8;
-                *(pScanline+1) = iCg8;
-                *(pScanline+2) = iCb8;
-                *(pScanline+3) = iCa8;
-              }
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_NO_16BIT_SUPPORT */
-#endif /* MNG_SKIPCANVAS_RGBA8 */
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCANVAS_RGBA8_PM
-#ifndef MNG_NO_16BIT_SUPPORT
-#ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
-mng_retcode mng_display_rgba8_pm (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint32 s, t;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA8_PM, MNG_LC_START);
-#endif
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-    if (pData->bIsRGBA16)              /* adjust source row starting-point */
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
-    else
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* scale down by dropping the LSB */
-		  if ((s = pDataline[6]) == 0)
-			*(mng_uint32*) pScanline = 0; /* set all components = 0 */
-		  else
-		  {
-			if (s == 255)
-			{
-              pScanline[0] = pDataline[0];
-              pScanline[1] = pDataline[2];
-		      pScanline[2] = pDataline[4];
-              pScanline[3] = 255;
-			}
-			else
-			{
-#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
-              int i;
-              for (i=2; i >= 0; i--)
-              {
-                pScanline[2-i] = DIV255B8(s * pDataline[4-i-i]);
-              }
-#else
-              pScanline[0] = DIV255B8(s * pDataline[0]);
-              pScanline[1] = DIV255B8(s * pDataline[2]);
-              pScanline[2] = DIV255B8(s * pDataline[4]);
-#endif
-              pScanline[3] = (mng_uint8)s;
-			}
-		  }
-          pScanline += (pData->iColinc << 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values and premultiply */
-		  if ((s = pDataline[3]) == 0)
-			*(mng_uint32*) pScanline = 0; /* set all components = 0 */
-		  else
-		  {
-			if (s == 255)
-			{
-#ifdef MNG_BIGENDIAN_SUPPORTED
-              *(mng_uint32*)pScanline = (*(mng_uint32*)pDataline) | 0x000000FF;
-#else
-              pScanline[0] = pDataline[0];
-              pScanline[1] = pDataline[1];
-		      pScanline[2] = pDataline[2];
-              pScanline[3] = 255;
-#endif
-			}
-			else
-			{
-#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
-              int i;
-              for (i=2; i >= 0; i--)
-              {
-                pScanline[2-i] = DIV255B8(s * pDataline[2-i]);
-              }
-#else
-              pScanline[0] = DIV255B8(s * pDataline[0]);
-              pScanline[1] = DIV255B8(s * pDataline[1]);
-		      pScanline[2] = DIV255B8(s * pDataline[2]);
-#endif
-              pScanline[3] = (mng_uint8)s;
-			}
-		  }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-    else
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* get alpha values */
-          if ((s = pDataline[6]) != 0)       /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if (s == 255)
-            {                          /* plain copy it */
-              pScanline[0] = pDataline[0];
-              pScanline[1] = pDataline[2];
-              pScanline[2] = pDataline[4];
-              pScanline[3] = 255;
-            }
-            else
-            {                          /* now blend (premultiplied) */
-			  t = 255 - s;
-#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
-              {
-                int i;
-                for (i=2; i >= 0; i--)
-                {
-                  pScanline[2-i] = DIV255B8(s * pDataline[4-i-i] + t *
-                     pScanline[2-i]);
-                }
-              }
-#else
-              pScanline[0] = DIV255B8(s * pDataline[0] + t * pScanline[0]);
-              pScanline[1] = DIV255B8(s * pDataline[2] + t * pScanline[1]);
-			  pScanline[2] = DIV255B8(s * pDataline[4] + t * pScanline[2]);
-#endif
-              pScanline[3] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[3])));
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          if ((s = pDataline[3]) != 0) /* any opacity at all ? */
-          {                            /* fully opaque ? */
-            if (s == 255)
-            {                          /* then simply copy the values */
-#ifdef MNG_BIGENDIAN_SUPPORTED
-              *(mng_uint32*)pScanline = (*(mng_uint32*)pDataline) | 0x000000FF;
-#else
-              pScanline[0] = pDataline[0];
-              pScanline[1] = pDataline[1];
-              pScanline[2] = pDataline[2];
-              pScanline[3] = 255;
-#endif
-            }
-            else
-            {                          /* now blend (premultiplied) */
-			  t = 255 - s;
-#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
-              {
-                int i;
-                for (i=2; i >= 0; i--)
-                {
-                  pScanline[2-i] = DIV255B8(s * pDataline[2-i] + t *
-                     pScanline[2-i]);
-                }
-              }
-#else
-              pScanline[0] = DIV255B8(s * pDataline[0] + t * pScanline[0]);
-              pScanline[1] = DIV255B8(s * pDataline[1] + t * pScanline[1]);
-			  pScanline[2] = DIV255B8(s * pDataline[2] + t * pScanline[2]);
-#endif
-              pScanline[3] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[3])));
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA8_PM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
-mng_retcode mng_display_rgba8_pm (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint32 s, t;
-  mng_uint8  iBps;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA8_PM, MNG_LC_START);
-#endif
-                  
-  iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-    /* adjust source row starting-point */
-    pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* scale down by dropping the LSB */
-		  if ((s = pDataline[6]) == 0)
-			*(mng_uint32*) pScanline = 0; /* set all components = 0 */
-		  else
-		  {
-			if (s == 255)
-			{
-              pScanline[0] = pDataline[0];
-              pScanline[1] = pDataline[2];
-		      pScanline[2] = pDataline[4];
-              pScanline[3] = 255;
-			}
-			else
-			{
-#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
-              int i;
-              for (i=2; i >= 0; i--)
-              {
-                pScanline[2-i] = DIV255B8(s * pDataline[4-i-i]);
-              }
-#else
-              pScanline[0] = DIV255B8(s * pDataline[0]);
-              pScanline[1] = DIV255B8(s * pDataline[2]);
-              pScanline[2] = DIV255B8(s * pDataline[4]);
-#endif
-              pScanline[3] = (mng_uint8)s;
-			}
-		  }
-          pScanline += (pData->iColinc << 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values and premultiply */
-		  if ((s = pDataline[3]) == 0)
-			*(mng_uint32*) pScanline = 0; /* set all components = 0 */
-		  else
-		  {
-			if (s == 255)
-			{
-#ifdef MNG_BIGENDIAN_SUPPORTED
-              *(mng_uint32*)pScanline = (*(mng_uint32*)pDataline) | 0x000000FF;
-#else
-              pScanline[0] = pDataline[0];
-              pScanline[1] = pDataline[1];
-		      pScanline[2] = pDataline[2];
-              pScanline[3] = 255;
-#endif
-			}
-			else
-			{
-#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
-              int i;
-              for (i=2; i >= 0; i--)
-              {
-                pScanline[2-i] = DIV255B8(s * pDataline[2-i]);
-              }
-#else
-              pScanline[0] = DIV255B8(s * pDataline[0]);
-              pScanline[1] = DIV255B8(s * pDataline[1]);
-		      pScanline[2] = DIV255B8(s * pDataline[2]);
-#endif
-              pScanline[3] = (mng_uint8)s;
-			}
-		  }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-    else
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* get alpha values */
-          if ((s = pDataline[6]) != 0)       /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if (s == 255)
-            {                          /* plain copy it */
-              pScanline[0] = pDataline[0];
-              pScanline[1] = pDataline[2];
-              pScanline[2] = pDataline[4];
-              pScanline[3] = 255;
-            }
-            else
-            {                          /* now blend (premultiplied) */
-			  t = 255 - s;
-#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
-              {
-                int i;
-                for (i=2; i >= 0; i--)
-                {
-                  pScanline[2-i] = DIV255B8(s * pDataline[4-i-i] + t *
-                     pScanline[2-i]);
-                }
-              }
-#else
-              pScanline[0] = DIV255B8(s * pDataline[0] + t * pScanline[0]);
-              pScanline[1] = DIV255B8(s * pDataline[2] + t * pScanline[1]);
-			  pScanline[2] = DIV255B8(s * pDataline[4] + t * pScanline[2]);
-#endif
-              pScanline[3] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[3])));
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          if ((s = pDataline[3]) != 0) /* any opacity at all ? */
-          {                            /* fully opaque ? */
-            if (s == 255)
-            {                          /* then simply copy the values */
-#ifdef MNG_BIGENDIAN_SUPPORTED
-              *(mng_uint32*)pScanline = (*(mng_uint32*)pDataline) | 0x000000FF;
-#else
-              pScanline[0] = pDataline[0];
-              pScanline[1] = pDataline[1];
-              pScanline[2] = pDataline[2];
-              pScanline[3] = 255;
-#endif
-            }
-            else
-            {                          /* now blend (premultiplied) */
-			  t = 255 - s;
-#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
-              {
-                int i;
-                for (i=2; i >= 0; i--)
-                {
-                  pScanline[2-i] = DIV255B8(s * pDataline[2-i] + t *
-                     pScanline[2-i]);
-                }
-              }
-#else
-              pScanline[0] = DIV255B8(s * pDataline[0] + t * pScanline[0]);
-              pScanline[1] = DIV255B8(s * pDataline[1] + t * pScanline[1]);
-			  pScanline[2] = DIV255B8(s * pDataline[2] + t * pScanline[2]);
-#endif
-              pScanline[3] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[3])));
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA8_PM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
-#else /* MNG_NO_16BIT_SUPPORT */
-mng_retcode mng_display_rgba8_pm (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint32 s, t;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA8_PM, MNG_LC_START);
-#endif
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values and premultiply */
-		  if ((s = pDataline[3]) == 0)
-			*(mng_uint32*) pScanline = 0; /* set all components = 0 */
-		  else
-		  {
-			if (s == 255)
-			{
-#ifdef MNG_BIGENDIAN_SUPPORTED
-              *(mng_uint32*)pScanline = (*(mng_uint32*)pDataline) | 0x000000FF;
-#else
-              pScanline[0] = pDataline[0];
-              pScanline[1] = pDataline[1];
-		      pScanline[2] = pDataline[2];
-              pScanline[3] = 255;
-#endif
-			}
-			else
-			{
-#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
-              int i;
-              for (i=2; i >= 0; i--)
-              {
-                pScanline[2-i] = DIV255B8(s * pDataline[2-i]);
-              }
-#else
-              pScanline[0] = DIV255B8(s * pDataline[0]);
-              pScanline[1] = DIV255B8(s * pDataline[1]);
-		      pScanline[2] = DIV255B8(s * pDataline[2]);
-#endif
-              pScanline[3] = (mng_uint8)s;
-			}
-		  }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-    else
-    {
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          if ((s = pDataline[3]) != 0) /* any opacity at all ? */
-          {                            /* fully opaque ? */
-            if (s == 255)
-            {                          /* then simply copy the values */
-#ifdef MNG_BIGENDIAN_SUPPORTED
-              *(mng_uint32*)pScanline = (*(mng_uint32*)pDataline) | 0x000000FF;
-#else
-              pScanline[0] = pDataline[0];
-              pScanline[1] = pDataline[1];
-              pScanline[2] = pDataline[2];
-              pScanline[3] = 255;
-#endif
-            }
-            else
-            {                          /* now blend (premultiplied) */
-			  t = 255 - s;
-#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
-              {
-                int i;
-                for (i=2; i >= 0; i--)
-                {
-                  pScanline[2-i] = DIV255B8(s * pDataline[2-i] + t *
-                     pScanline[2-i]);
-                }
-              }
-#else
-              pScanline[0] = DIV255B8(s * pDataline[0] + t * pScanline[0]);
-              pScanline[1] = DIV255B8(s * pDataline[1] + t * pScanline[1]);
-			  pScanline[2] = DIV255B8(s * pDataline[2] + t * pScanline[2]);
-#endif
-              pScanline[3] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[3])));
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA8_PM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_NO_16BIT_SUPPORT */
-#endif /* MNG_SKIPCANVAS_RGBA8_PM */
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCANVAS_ARGB8
-#ifndef MNG_NO_16BIT_SUPPORT
-#ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
-mng_retcode mng_display_argb8 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint8  iFGa8, iBGa8, iCa8;
-  mng_uint16 iFGa16, iBGa16, iCa16;
-  mng_uint16 iFGr16, iFGg16, iFGb16;
-  mng_uint16 iBGr16, iBGg16, iBGb16;
-  mng_uint16 iCr16, iCg16, iCb16;
-  mng_uint8  iCr8, iCg8, iCb8;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_ARGB8, MNG_LC_START);
-#endif
-
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-    if (pData->bIsRGBA16)              /* adjust source row starting-point */
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
-    else
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* scale down by dropping the LSB */
-          *pScanline     = *(pDataline+6);
-          *(pScanline+1) = *pDataline;
-          *(pScanline+2) = *(pDataline+2);
-          *(pScanline+3) = *(pDataline+4);
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values */
-          *pScanline     = *(pDataline+3);
-          *(pScanline+1) = *pDataline;
-          *(pScanline+2) = *(pDataline+1);
-          *(pScanline+3) = *(pDataline+2);
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-    else
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* get alpha values */
-          iFGa16 = mng_get_uint16 (pDataline+6);
-          iBGa16 = (mng_uint16)(*pScanline);
-          iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
-
-          if (iFGa16)                  /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
-            {                          /* plain copy it */
-              *pScanline     = *(pDataline+6);
-              *(pScanline+1) = *pDataline;
-              *(pScanline+2) = *(pDataline+2);
-              *(pScanline+3) = *(pDataline+4);
-            }
-            else
-            {
-              if (iBGa16 == 0xFFFF)    /* background fully opaque ? */
-              {                        /* get the proper values */
-                iFGr16 = mng_get_uint16 (pDataline  );
-                iFGg16 = mng_get_uint16 (pDataline+2);
-                iFGb16 = mng_get_uint16 (pDataline+4);
-                                       /* scale background up */
-                iBGr16 = (mng_uint16)(*(pScanline+1));
-                iBGg16 = (mng_uint16)(*(pScanline+2));
-                iBGb16 = (mng_uint16)(*(pScanline+3));
-                iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
-                iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-                iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
-                                       /* now compose */
-                MNG_COMPOSE16(iFGr16, iFGr16, iFGa16, iBGr16);
-                MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
-                MNG_COMPOSE16(iFGb16, iFGb16, iFGa16, iBGb16);
-                                       /* and return the composed values */
-                                       /* alpha remains fully opaque !!! */
-                *(pScanline+1) = (mng_uint8)(iFGr16 >> 8);
-                *(pScanline+2) = (mng_uint8)(iFGg16 >> 8);
-                *(pScanline+3) = (mng_uint8)(iFGb16 >> 8);
-              }
-              else
-              {                        /* scale background up */
-                iBGr16 = (mng_uint16)(*(pScanline+1));
-                iBGg16 = (mng_uint16)(*(pScanline+2));
-                iBGb16 = (mng_uint16)(*(pScanline+3));
-                iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
-                iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-                iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
-                                       /* let's blend */
-                MNG_BLEND16 (mng_get_uint16 (pDataline  ),
-                             mng_get_uint16 (pDataline+2),
-                             mng_get_uint16 (pDataline+4), iFGa16,
-                             iBGr16, iBGg16, iBGb16, iBGa16,
-                             iCr16,  iCg16,  iCb16,  iCa16);
-                                       /* and return the composed values */
-                *pScanline     = (mng_uint8)(iCa16 >> 8);
-                *(pScanline+1) = (mng_uint8)(iCr16 >> 8);
-                *(pScanline+2) = (mng_uint8)(iCg16 >> 8);
-                *(pScanline+3) = (mng_uint8)(iCb16 >> 8);
-              }
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iFGa8 = *(pDataline+3);      /* get alpha values */
-          iBGa8 = *pScanline;
-
-          if (iFGa8)                   /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if ((iFGa8 == 0xFF) || (iBGa8 == 0))
-            {                          /* then simply copy the values */
-              *pScanline     = *(pDataline+3);
-              *(pScanline+1) = *pDataline;
-              *(pScanline+2) = *(pDataline+1);
-              *(pScanline+3) = *(pDataline+2);
-            }
-            else
-            {
-              if (iBGa8 == 0xFF)       /* background fully opaque ? */
-              {                        /* do simple alpha composing */
-                                       /* alpha itself remains fully opaque !!! */
-              }
-              else
-              {                        /* now blend */
-                MNG_BLEND8 (*pDataline,     *(pDataline+1), *(pDataline+2), iFGa8,
-                            *(pScanline+1), *(pScanline+2), *(pScanline+3), iBGa8,
-                            iCr8, iCg8, iCb8, iCa8);
-                                       /* and return the composed values */
-                *pScanline     = iCa8;
-                *(pScanline+1) = iCr8;
-                *(pScanline+2) = iCg8;
-                *(pScanline+3) = iCb8;
-              }
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_ARGB8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
-mng_retcode mng_display_argb8 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint8  iFGa8, iBGa8, iCa8;
-  mng_uint16 iFGa16, iBGa16, iCa16;
-  mng_uint16 iFGg16;
-  mng_uint16 iBGr16, iBGg16, iBGb16;
-  mng_uint16 iCr16, iCg16, iCb16;
-  mng_uint8  iCr8, iCg8, iCb8;
-  mng_uint8  iBps;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_ARGB8, MNG_LC_START);
-#endif
-
-  iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-    /* adjust source row starting-point */
-    pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* scale down by dropping the LSB */
-          *pScanline     = *(pDataline+3*iBps);
-          *(pScanline+1) = *pDataline;
-          *(pScanline+2) = *(pDataline+iBps);
-          *(pScanline+3) = *(pDataline+2*iBps);
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4*iBps;
-        }
-    }
-    else
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* get alpha values */
-          iFGa16 = mng_get_uint16 (pDataline+6);
-          iBGa16 = (mng_uint16)(*pScanline);
-          iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
-
-          if (iFGa16)                  /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
-            {                          /* plain copy it */
-              *pScanline     = *(pDataline+6);
-              *(pScanline+1) = *pDataline;
-              *(pScanline+2) = *(pDataline+2);
-              *(pScanline+3) = *(pDataline+4);
-            }
-            else
-            {
-              if (iBGa16 == 0xFFFF)    /* background fully opaque ? */
-              {                        /* get the proper values */
-              int i;
-              for (i=2; i >= 0; i--)
-              {
-                iFGg16 = mng_get_uint16 (pDataline+i+i);
-                                       /* scale background up */
-                iBGg16 = (mng_uint16)(*(pScanline+i+1));
-                iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-                                       /* now compose */
-                MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
-                                       /* and return the composed values */
-                                       /* alpha remains fully opaque !!! */
-                *(pScanline+i+1) = (mng_uint8)(iFGg16 >> 8);
-              }
-              }
-              else
-              {                        /* scale background up */
-                iBGr16 = (mng_uint16)(*(pScanline+1));
-                iBGg16 = (mng_uint16)(*(pScanline+2));
-                iBGb16 = (mng_uint16)(*(pScanline+3));
-                iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
-                iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-                iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
-                                       /* let's blend */
-                MNG_BLEND16 (mng_get_uint16 (pDataline  ),
-                             mng_get_uint16 (pDataline+2),
-                             mng_get_uint16 (pDataline+4), iFGa16,
-                             iBGr16, iBGg16, iBGb16, iBGa16,
-                             iCr16,  iCg16,  iCb16,  iCa16);
-                                       /* and return the composed values */
-                *pScanline     = (mng_uint8)(iCa16 >> 8);
-                *(pScanline+1) = (mng_uint8)(iCr16 >> 8);
-                *(pScanline+2) = (mng_uint8)(iCg16 >> 8);
-                *(pScanline+3) = (mng_uint8)(iCb16 >> 8);
-              }
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iFGa8 = *(pDataline+3);      /* get alpha values */
-          iBGa8 = *pScanline;
-
-          if (iFGa8)                   /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if ((iFGa8 == 0xFF) || (iBGa8 == 0))
-            {                          /* then simply copy the values */
-              *pScanline     = *(pDataline+3);
-              *(pScanline+1) = *pDataline;
-              *(pScanline+2) = *(pDataline+1);
-              *(pScanline+3) = *(pDataline+2);
-            }
-            else
-            {
-              if (iBGa8 == 0xFF)       /* background fully opaque ? */
-              {                        /* do simple alpha composing */
-                                       /* alpha itself remains fully opaque !!! */
-              int i;
-              for (i=2; i >= 0; i--)
-              {
-              MNG_COMPOSE8 (*(pScanline+i+1), *(pDataline+i), iFGa8, *(pScanline+i+1));
-              }
-              }
-              else
-              {                        /* now blend */
-                MNG_BLEND8 (*pDataline,     *(pDataline+1), *(pDataline+2), iFGa8,
-                            *(pScanline+1), *(pScanline+2), *(pScanline+3), iBGa8,
-                            iCr8, iCg8, iCb8, iCa8);
-                                       /* and return the composed values */
-                *pScanline     = iCa8;
-                *(pScanline+1) = iCr8;
-                *(pScanline+2) = iCg8;
-                *(pScanline+3) = iCb8;
-              }
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_ARGB8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
-#else /* MNG_NO_16BIT_SUPPORT */
-mng_retcode mng_display_argb8 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint8  iFGa8, iBGa8, iCa8;
-  mng_uint8  iCr8, iCg8, iCb8;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_ARGB8, MNG_LC_START);
-#endif
-
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values */
-          *pScanline     = *(pDataline+3);
-          *(pScanline+1) = *pDataline;
-          *(pScanline+2) = *(pDataline+1);
-          *(pScanline+3) = *(pDataline+2);
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-    else
-    {
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iFGa8 = *(pDataline+3);      /* get alpha values */
-          iBGa8 = *pScanline;
-
-          if (iFGa8)                   /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if ((iFGa8 == 0xFF) || (iBGa8 == 0))
-            {                          /* then simply copy the values */
-              *pScanline     = *(pDataline+3);
-              *(pScanline+1) = *pDataline;
-              *(pScanline+2) = *(pDataline+1);
-              *(pScanline+3) = *(pDataline+2);
-            }
-            else
-            {
-              if (iBGa8 == 0xFF)       /* background fully opaque ? */
-              {                        /* do simple alpha composing */
-                                       /* alpha itself remains fully opaque !!! */
-#ifdef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
-              int i;
-              for (i=2; i >= 0; i--)
-              {
-              MNG_COMPOSE8 (*(pScanline+i+1), *(pDataline+i), iFGa8, *(pScanline+i+1));
-              }
-#else
-                MNG_COMPOSE8 (*(pScanline+1), *pDataline,     iFGa8, *(pScanline+1));
-                MNG_COMPOSE8 (*(pScanline+2), *(pDataline+1), iFGa8, *(pScanline+2));
-                MNG_COMPOSE8 (*(pScanline+3), *(pDataline+2), iFGa8, *(pScanline+3));
-#endif
-              }
-              else
-              {                        /* now blend */
-                MNG_BLEND8 (*pDataline,     *(pDataline+1), *(pDataline+2), iFGa8,
-                            *(pScanline+1), *(pScanline+2), *(pScanline+3), iBGa8,
-                            iCr8, iCg8, iCb8, iCa8);
-                                       /* and return the composed values */
-                *pScanline     = iCa8;
-                *(pScanline+1) = iCr8;
-                *(pScanline+2) = iCg8;
-                *(pScanline+3) = iCb8;
-              }
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_ARGB8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_NO_16BIT_SUPPORT */
-#endif /* MNG_SKIPCANVAS_ARGB8 */
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCANVAS_ARGB8_PM
-#ifndef MNG_NO_16BIT_SUPPORT
-#ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
-mng_retcode mng_display_argb8_pm (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint32 s, t;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_ARGB8_PM, MNG_LC_START);
-#endif
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-    if (pData->bIsRGBA16)              /* adjust source row starting-point */
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
-    else
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* scale down by dropping the LSB */
-		  if ((s = pDataline[6]) == 0)
-			*(mng_uint32*) pScanline = 0; /* set all components = 0 */
-		  else
-		  {
-			if (s == 255)
-			{
-              pScanline[0] = 255;
-              pScanline[1] = pDataline[0];
-              pScanline[2] = pDataline[2];
-		      pScanline[3] = pDataline[4];
-			}
-			else
-			{
-              pScanline[0] = (mng_uint8)s;
-#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
-              {
-                int i;
-                for (i=2; i >= 0; i--)
-                {
-                  pScanline[3-i] = DIV255B8(s * pDataline[4-i-i]);
-                }
-              }
-#else
-              pScanline[1] = DIV255B8(s * pDataline[0]);
-              pScanline[2] = DIV255B8(s * pDataline[2]);
-              pScanline[3] = DIV255B8(s * pDataline[4]);
-#endif
-			}
-		  }
-          pScanline += (pData->iColinc << 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values and premultiply */
-		  if ((s = pDataline[3]) == 0)
-			*(mng_uint32*) pScanline = 0; /* set all components = 0 */
-		  else
-		  {
-			if (s == 255)
-			{
-              pScanline[0] = 255;
-              pScanline[1] = pDataline[0];
-              pScanline[2] = pDataline[1];
-		      pScanline[3] = pDataline[2];
-			}
-			else
-			{
-              pScanline[0] = (mng_uint8)s;
-#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
-              {
-                int i;
-                for (i=2; i >= 0; i--)
-                {
-                  pScanline[3-i] = DIV255B8(s * pDataline[2-i]);
-                }
-              }
-#else
-              pScanline[1] = DIV255B8(s * pDataline[0]);
-              pScanline[2] = DIV255B8(s * pDataline[1]);
-		      pScanline[3] = DIV255B8(s * pDataline[2]);
-#endif
-			}
-		  }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-    else
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* get alpha values */
-          if ((s = pDataline[6]) != 0)       /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if (s == 255)
-            {                          /* plain copy it */
-              pScanline[0] = 255;
-              pScanline[1] = pDataline[0];
-              pScanline[2] = pDataline[2];
-              pScanline[3] = pDataline[4];
-            }
-            else
-            {                          /* now blend (premultiplied) */
-			  t = 255 - s;
-              pScanline[0] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[0])));
-#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
-              {
-                int i;
-                for (i=2; i >= 0; i--)
-                {
-                  pScanline[3-i] = DIV255B8(s * pDataline[4-i-i] + t *
-                     pScanline[3-i]);
-                }
-              }
-#else
-              pScanline[1] = DIV255B8(s * pDataline[0] + t * pScanline[1]);
-              pScanline[2] = DIV255B8(s * pDataline[2] + t * pScanline[2]);
-			  pScanline[3] = DIV255B8(s * pDataline[4] + t * pScanline[3]);
-#endif
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          if ((s = pDataline[3]) != 0)       /* any opacity at all ? */
-          {                            /* fully opaque ? */
-            if (s == 255)
-            {                          /* then simply copy the values */
-              pScanline[0] = 255;
-              pScanline[1] = pDataline[0];
-              pScanline[2] = pDataline[1];
-              pScanline[3] = pDataline[2];
-            }
-            else
-            {                          /* now blend (premultiplied) */
-			  t = 255 - s;
-              pScanline[0] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[0])));
-#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
-              {
-                int i;
-                for (i=2; i >= 0; i--)
-                {
-                  pScanline[3-i] = DIV255B8(s * pDataline[2-i] + t *
-                     pScanline[3-i]);
-                }
-              }
-#else
-              pScanline[1] = DIV255B8(s * pDataline[0] + t * pScanline[1]);
-              pScanline[2] = DIV255B8(s * pDataline[1] + t * pScanline[2]);
-			  pScanline[3] = DIV255B8(s * pDataline[2] + t * pScanline[3]);
-#endif
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_ARGB8_PM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
-mng_retcode mng_display_argb8_pm (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint32 s, t;
-  mng_uint8  iBps;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_ARGB8_PM, MNG_LC_START);
-#endif
-
-  iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-    /* adjust source row starting-point */
-    pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* scale down by dropping the LSB */
-		  if ((s = pDataline[6]) == 0)
-			*(mng_uint32*) pScanline = 0; /* set all components = 0 */
-		  else
-		  {
-			if (s == 255)
-			{
-              pScanline[0] = 255;
-              pScanline[1] = pDataline[0];
-              pScanline[2] = pDataline[2];
-		      pScanline[3] = pDataline[4];
-			}
-			else
-			{
-              pScanline[0] = (mng_uint8)s;
-#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
-              {
-                int i;
-                for (i=2; i >= 0; i--)
-                {
-                  pScanline[3-i] = DIV255B8(s * pDataline[4-i-i]);
-                }
-              }
-#else
-              pScanline[1] = DIV255B8(s * pDataline[0]);
-              pScanline[2] = DIV255B8(s * pDataline[2]);
-              pScanline[3] = DIV255B8(s * pDataline[4]);
-#endif
-			}
-		  }
-          pScanline += (pData->iColinc << 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values and premultiply */
-		  if ((s = pDataline[3]) == 0)
-			*(mng_uint32*) pScanline = 0; /* set all components = 0 */
-		  else
-		  {
-			if (s == 255)
-			{
-              pScanline[0] = 255;
-              pScanline[1] = pDataline[0];
-              pScanline[2] = pDataline[1];
-		      pScanline[3] = pDataline[2];
-			}
-			else
-			{
-              pScanline[0] = (mng_uint8)s;
-#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
-              {
-                int i;
-                for (i=2; i >= 0; i--)
-                {
-                  pScanline[3-i] = DIV255B8(s * pDataline[2-i]);
-                }
-              }
-#else
-              pScanline[1] = DIV255B8(s * pDataline[0]);
-              pScanline[2] = DIV255B8(s * pDataline[1]);
-		      pScanline[3] = DIV255B8(s * pDataline[2]);
-#endif
-			}
-		  }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-    else
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* get alpha values */
-          if ((s = pDataline[6]) != 0)       /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if (s == 255)
-            {                          /* plain copy it */
-              pScanline[0] = 255;
-              pScanline[1] = pDataline[0];
-              pScanline[2] = pDataline[2];
-              pScanline[3] = pDataline[4];
-            }
-            else
-            {                          /* now blend (premultiplied) */
-			  t = 255 - s;
-              pScanline[0] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[0])));
-#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
-              {
-                int i;
-                for (i=2; i >= 0; i--)
-                {
-                  pScanline[3-i] = DIV255B8(s * pDataline[4-i-i] + t *
-                     pScanline[3-i]);
-                }
-              }
-#else
-              pScanline[1] = DIV255B8(s * pDataline[0] + t * pScanline[1]);
-              pScanline[2] = DIV255B8(s * pDataline[2] + t * pScanline[2]);
-			  pScanline[3] = DIV255B8(s * pDataline[4] + t * pScanline[3]);
-#endif
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          if ((s = pDataline[3]) != 0)       /* any opacity at all ? */
-          {                            /* fully opaque ? */
-            if (s == 255)
-            {                          /* then simply copy the values */
-              pScanline[0] = 255;
-              pScanline[1] = pDataline[0];
-              pScanline[2] = pDataline[1];
-              pScanline[3] = pDataline[2];
-            }
-            else
-            {                          /* now blend (premultiplied) */
-			  t = 255 - s;
-              pScanline[0] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[0])));
-#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
-              {
-                int i;
-                for (i=2; i >= 0; i--)
-                {
-                  pScanline[3-i] = DIV255B8(s * pDataline[2-i] + t *
-                     pScanline[3-i]);
-                }
-              }
-#else
-              pScanline[1] = DIV255B8(s * pDataline[0] + t * pScanline[1]);
-              pScanline[2] = DIV255B8(s * pDataline[1] + t * pScanline[2]);
-			  pScanline[3] = DIV255B8(s * pDataline[2] + t * pScanline[3]);
-#endif
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_ARGB8_PM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
-#else /* MNG_NO_16BIT_SUPPORT */
-mng_retcode mng_display_argb8_pm (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint32 s, t;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_ARGB8_PM, MNG_LC_START);
-#endif
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values and premultiply */
-		  if ((s = pDataline[3]) == 0)
-			*(mng_uint32*) pScanline = 0; /* set all components = 0 */
-		  else
-		  {
-			if (s == 255)
-			{
-              pScanline[0] = 255;
-              pScanline[1] = pDataline[0];
-              pScanline[2] = pDataline[1];
-		      pScanline[3] = pDataline[2];
-			}
-			else
-			{
-              pScanline[0] = (mng_uint8)s;
-#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
-              {
-                int i;
-                for (i=2; i >= 0; i--)
-                {
-                  pScanline[3-i] = DIV255B8(s * pDataline[2-i]);
-                }
-              }
-#else
-              pScanline[1] = DIV255B8(s * pDataline[0]);
-              pScanline[2] = DIV255B8(s * pDataline[1]);
-		      pScanline[3] = DIV255B8(s * pDataline[2]);
-#endif
-			}
-		  }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-    else
-    {
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          if ((s = pDataline[3]) != 0)       /* any opacity at all ? */
-          {                            /* fully opaque ? */
-            if (s == 255)
-            {                          /* then simply copy the values */
-              pScanline[0] = 255;
-              pScanline[1] = pDataline[0];
-              pScanline[2] = pDataline[1];
-              pScanline[3] = pDataline[2];
-            }
-            else
-            {                          /* now blend (premultiplied) */
-			  t = 255 - s;
-              pScanline[0] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[0])));
-#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
-              {
-                int i;
-                for (i=2; i >= 0; i--)
-                {
-                  pScanline[3-i] = DIV255B8(s * pDataline[2-i] + t *
-                     pScanline[3-i]);
-                }
-              }
-#else
-              pScanline[1] = DIV255B8(s * pDataline[0] + t * pScanline[1]);
-              pScanline[2] = DIV255B8(s * pDataline[1] + t * pScanline[2]);
-			  pScanline[3] = DIV255B8(s * pDataline[2] + t * pScanline[3]);
-#endif
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_ARGB8_PM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_NO_16BIT_SUPPORT */
-#endif /* MNG_SKIPCANVAS_ARGB8_PM */
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCANVAS_RGB8_A8
-#ifndef MNG_NO_16BIT_SUPPORT
-#ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
-mng_retcode mng_display_rgb8_a8 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pAlphaline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint8  iFGa8, iBGa8, iCa8;
-  mng_uint16 iFGa16, iBGa16, iCa16;
-  mng_uint16 iFGr16, iFGg16, iFGb16;
-  mng_uint16 iBGr16, iBGg16, iBGb16;
-  mng_uint16 iCr16, iCg16, iCb16;
-  mng_uint8  iCr8, iCg8, iCb8;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8_A8, MNG_LC_START);
-#endif
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination rows */
-    pScanline  = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                    pData->iRow + pData->iDestt -
-                                                    pData->iSourcet);
-    pAlphaline = (mng_uint8p)pData->fGetalphaline  (((mng_handle)pData),
-                                                    pData->iRow + pData->iDestt -
-                                                    pData->iSourcet);
-                                       /* adjust destination rows starting-point */
-    pScanline  = pScanline  + (pData->iCol * 3) + (pData->iDestl * 3);
-    pAlphaline = pAlphaline + pData->iCol + pData->iDestl;
-
-    pDataline  = pData->pRGBArow;      /* address source row */
-
-    if (pData->bIsRGBA16)              /* adjust source row starting-point */
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
-    else
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* scale down by dropping the LSB */
-          *pScanline     = *pDataline;
-          *(pScanline+1) = *(pDataline+2);
-          *(pScanline+2) = *(pDataline+4);
-          *pAlphaline    = *(pDataline+6);
-
-          pScanline  += (pData->iColinc * 3);
-          pAlphaline += pData->iColinc;
-          pDataline  += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values */
-          *pScanline     = *pDataline;
-          *(pScanline+1) = *(pDataline+1);
-          *(pScanline+2) = *(pDataline+2);
-          *pAlphaline    = *(pDataline+3);
-
-          pScanline  += (pData->iColinc * 3);
-          pAlphaline += pData->iColinc;
-          pDataline  += 4;
-        }
-      }
-    }
-    else
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* get alpha values */
-          iFGa16 = mng_get_uint16 (pDataline+6);
-          iBGa16 = (mng_uint16)(*pAlphaline);
-          iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
-
-          if (iFGa16)                  /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
-            {                          /* plain copy it */
-              *pScanline     = *pDataline;
-              *(pScanline+1) = *(pDataline+2);
-              *(pScanline+2) = *(pDataline+4);
-              *pAlphaline    = *(pDataline+6);
-            }
-            else
-            {
-              if (iBGa16 == 0xFFFF)    /* background fully opaque ? */
-              {                        /* get the proper values */
-                iFGr16 = mng_get_uint16 (pDataline  );
-                iFGg16 = mng_get_uint16 (pDataline+2);
-                iFGb16 = mng_get_uint16 (pDataline+4);
-                                       /* scale background up */
-                iBGr16 = (mng_uint16)(*pScanline    );
-                iBGg16 = (mng_uint16)(*(pScanline+1));
-                iBGb16 = (mng_uint16)(*(pScanline+2));
-                iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
-                iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-                iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
-                                       /* now compose */
-                MNG_COMPOSE16(iFGr16, iFGr16, iFGa16, iBGr16);
-                MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
-                MNG_COMPOSE16(iFGb16, iFGb16, iFGa16, iBGb16);
-                                       /* and return the composed values */
-                *pScanline     = (mng_uint8)(iFGr16 >> 8);
-                *(pScanline+1) = (mng_uint8)(iFGg16 >> 8);
-                *(pScanline+2) = (mng_uint8)(iFGb16 >> 8);
-                                       /* alpha remains fully opaque !!! */
-              }
-              else
-              {                        /* scale background up */
-                iBGr16 = (mng_uint16)(*pScanline    );
-                iBGg16 = (mng_uint16)(*(pScanline+1));
-                iBGb16 = (mng_uint16)(*(pScanline+2));
-                iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
-                iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-                iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
-                                       /* let's blend */
-                MNG_BLEND16 (mng_get_uint16 (pDataline  ),
-                             mng_get_uint16 (pDataline+2),
-                             mng_get_uint16 (pDataline+4), iFGa16,
-                             iBGr16, iBGg16, iBGb16, iBGa16,
-                             iCr16,  iCg16,  iCb16,  iCa16);
-                                       /* and return the composed values */
-                *pScanline     = (mng_uint8)(iCr16 >> 8);
-                *(pScanline+1) = (mng_uint8)(iCg16 >> 8);
-                *(pScanline+2) = (mng_uint8)(iCb16 >> 8);
-                *pAlphaline    = (mng_uint8)(iCa16 >> 8);
-              }
-            }
-          }
-
-          pScanline  += (pData->iColinc * 3);
-          pAlphaline += pData->iColinc;
-          pDataline  += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iFGa8 = *(pDataline+3);      /* get alpha values */
-          iBGa8 = *pAlphaline;
-
-          if (iFGa8)                   /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if ((iFGa8 == 0xFF) || (iBGa8 == 0))
-            {                          /* then simply copy the values */
-              *pScanline     = *pDataline;
-              *(pScanline+1) = *(pDataline+1);
-              *(pScanline+2) = *(pDataline+2);
-              *pAlphaline    = *(pDataline+3);
-            }
-            else
-            {
-              if (iBGa8 == 0xFF)       /* background fully opaque ? */
-              {                        /* do alpha composing */
-                MNG_COMPOSE8 (*pScanline,     *pDataline,     iFGa8, *pScanline    );
-                MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iFGa8, *(pScanline+1));
-                MNG_COMPOSE8 (*(pScanline+2), *(pDataline+2), iFGa8, *(pScanline+2));
-                                       /* alpha remains fully opaque !!! */
-              }
-              else
-              {                        /* now blend */
-                MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
-                            *pScanline, *(pScanline+1), *(pScanline+2), iBGa8,
-                            iCr8, iCg8, iCb8, iCa8);
-                                       /* and return the composed values */
-                *pScanline     = iCr8;
-                *(pScanline+1) = iCg8;
-                *(pScanline+2) = iCb8;
-                *pAlphaline    = iCa8;
-              }
-            }
-          }
-
-          pScanline  += (pData->iColinc * 3);
-          pAlphaline += pData->iColinc;
-          pDataline  += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8_A8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
-mng_retcode mng_display_rgb8_a8 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pAlphaline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint8  iFGa8, iBGa8, iCa8;
-  mng_uint16 iFGa16, iBGa16, iCa16;
-  mng_uint16 iFGg16;
-  mng_uint16 iBGr16, iBGg16, iBGb16;
-  mng_uint16 iCr16, iCg16, iCb16;
-  mng_uint8  iCr8, iCg8, iCb8;
-  mng_uint8  iBps;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8_A8, MNG_LC_START);
-#endif
-
-  iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination rows */
-    pScanline  = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                    pData->iRow + pData->iDestt -
-                                                    pData->iSourcet);
-    pAlphaline = (mng_uint8p)pData->fGetalphaline  (((mng_handle)pData),
-                                                    pData->iRow + pData->iDestt -
-                                                    pData->iSourcet);
-                                       /* adjust destination rows starting-point */
-    pScanline  = pScanline  + (pData->iCol * 3) + (pData->iDestl * 3);
-    pAlphaline = pAlphaline + pData->iCol + pData->iDestl;
-
-    pDataline  = pData->pRGBArow;      /* address source row */
-
-    /* adjust source row starting-point */
-    pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* scale down by dropping the LSB */
-          *pScanline     = *pDataline;
-          *(pScanline+1) = *(pDataline+iBps);
-          *(pScanline+2) = *(pDataline+2*iBps);
-          *pAlphaline    = *(pDataline+3*iBps);
-
-          pScanline  += (pData->iColinc * 3);
-          pAlphaline += pData->iColinc;
-          pDataline  += 4*iBps;
-        }
-    }
-    else
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* get alpha values */
-          iFGa16 = mng_get_uint16 (pDataline+6);
-          iBGa16 = (mng_uint16)(*pAlphaline);
-          iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
-
-          if (iFGa16)                  /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
-            {                          /* plain copy it */
-              *pScanline     = *pDataline;
-              *(pScanline+1) = *(pDataline+2);
-              *(pScanline+2) = *(pDataline+4);
-              *pAlphaline    = *(pDataline+6);
-            }
-            else
-            {
-              if (iBGa16 == 0xFFFF)    /* background fully opaque ? */
-              {                        /* get the proper values */
-              int i;
-              for (i=2; i >= 0; i--)
-              {
-                iFGg16 = mng_get_uint16 (pDataline+i+i);
-                                       /* scale background up */
-                iBGg16 = (mng_uint16)(*(pScanline+i));
-                iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-                                       /* now compose */
-                MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
-                                       /* and return the composed values */
-                *(pScanline+i) = (mng_uint8)(iFGg16 >> 8);
-                                       /* alpha remains fully opaque !!! */
-              }
-              }
-              else
-              {                        /* scale background up */
-                iBGr16 = (mng_uint16)(*pScanline    );
-                iBGg16 = (mng_uint16)(*(pScanline+1));
-                iBGb16 = (mng_uint16)(*(pScanline+2));
-                iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
-                iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-                iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
-                                       /* let's blend */
-                MNG_BLEND16 (mng_get_uint16 (pDataline  ),
-                             mng_get_uint16 (pDataline+2),
-                             mng_get_uint16 (pDataline+4), iFGa16,
-                             iBGr16, iBGg16, iBGb16, iBGa16,
-                             iCr16,  iCg16,  iCb16,  iCa16);
-                                       /* and return the composed values */
-                *pScanline     = (mng_uint8)(iCr16 >> 8);
-                *(pScanline+1) = (mng_uint8)(iCg16 >> 8);
-                *(pScanline+2) = (mng_uint8)(iCb16 >> 8);
-                *pAlphaline    = (mng_uint8)(iCa16 >> 8);
-              }
-            }
-          }
-
-          pScanline  += (pData->iColinc * 3);
-          pAlphaline += pData->iColinc;
-          pDataline  += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iFGa8 = *(pDataline+3);      /* get alpha values */
-          iBGa8 = *pAlphaline;
-
-          if (iFGa8)                   /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if ((iFGa8 == 0xFF) || (iBGa8 == 0))
-            {                          /* then simply copy the values */
-              *pScanline     = *pDataline;
-              *(pScanline+1) = *(pDataline+1);
-              *(pScanline+2) = *(pDataline+2);
-              *pAlphaline    = *(pDataline+3);
-            }
-            else
-            {
-              if (iBGa8 == 0xFF)       /* background fully opaque ? */
-              {                        /* do alpha composing */
-              int i;
-              for (i=2; i >= 0; i--)
-              {
-              MNG_COMPOSE8 (*(pScanline+i), *(pDataline+i), iFGa8, *(pScanline+i));
-              }
-                                       /* alpha remains fully opaque !!! */
-              }
-              else
-              {                        /* now blend */
-                MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
-                            *pScanline, *(pScanline+1), *(pScanline+2), iBGa8,
-                            iCr8, iCg8, iCb8, iCa8);
-                                       /* and return the composed values */
-                *pScanline     = iCr8;
-                *(pScanline+1) = iCg8;
-                *(pScanline+2) = iCb8;
-                *pAlphaline    = iCa8;
-              }
-            }
-          }
-
-          pScanline  += (pData->iColinc * 3);
-          pAlphaline += pData->iColinc;
-          pDataline  += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8_A8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
-#else /* MNG_NO_16BIT_SUPPORT */
-mng_retcode mng_display_rgb8_a8 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pAlphaline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint8  iFGa8, iBGa8, iCa8;
-  mng_uint8  iCr8, iCg8, iCb8;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8_A8, MNG_LC_START);
-#endif
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination rows */
-    pScanline  = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                    pData->iRow + pData->iDestt -
-                                                    pData->iSourcet);
-    pAlphaline = (mng_uint8p)pData->fGetalphaline  (((mng_handle)pData),
-                                                    pData->iRow + pData->iDestt -
-                                                    pData->iSourcet);
-                                       /* adjust destination rows starting-point */
-    pScanline  = pScanline  + (pData->iCol * 3) + (pData->iDestl * 3);
-    pAlphaline = pAlphaline + pData->iCol + pData->iDestl;
-
-    pDataline  = pData->pRGBArow;      /* address source row */
-
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values */
-          *pScanline     = *pDataline;
-          *(pScanline+1) = *(pDataline+1);
-          *(pScanline+2) = *(pDataline+2);
-          *pAlphaline    = *(pDataline+3);
-
-          pScanline  += (pData->iColinc * 3);
-          pAlphaline += pData->iColinc;
-          pDataline  += 4;
-        }
-      }
-    }
-    else
-    {
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iFGa8 = *(pDataline+3);      /* get alpha values */
-          iBGa8 = *pAlphaline;
-
-          if (iFGa8)                   /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if ((iFGa8 == 0xFF) || (iBGa8 == 0))
-            {                          /* then simply copy the values */
-              *pScanline     = *pDataline;
-              *(pScanline+1) = *(pDataline+1);
-              *(pScanline+2) = *(pDataline+2);
-              *pAlphaline    = *(pDataline+3);
-            }
-            else
-            {
-              if (iBGa8 == 0xFF)       /* background fully opaque ? */
-              {                        /* do alpha composing */
-#ifdef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
-              int i;
-              for (i=2; i >= 0; i--)
-              {
-              MNG_COMPOSE8 (*(pScanline+i), *(pDataline+i), iFGa8, *(pScanline+i));
-              }
-#else
-                MNG_COMPOSE8 (*pScanline,     *pDataline,     iFGa8, *pScanline    );
-                MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iFGa8, *(pScanline+1));
-                MNG_COMPOSE8 (*(pScanline+2), *(pDataline+2), iFGa8, *(pScanline+2));
-#endif
-                                       /* alpha remains fully opaque !!! */
-              }
-              else
-              {                        /* now blend */
-                MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
-                            *pScanline, *(pScanline+1), *(pScanline+2), iBGa8,
-                            iCr8, iCg8, iCb8, iCa8);
-                                       /* and return the composed values */
-                *pScanline     = iCr8;
-                *(pScanline+1) = iCg8;
-                *(pScanline+2) = iCb8;
-                *pAlphaline    = iCa8;
-              }
-            }
-          }
-
-          pScanline  += (pData->iColinc * 3);
-          pAlphaline += pData->iColinc;
-          pDataline  += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8_A8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_NO_16BIT_SUPPORT */
-#endif /* MNG_SKIPCANVAS_RGB8_A8 */
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCANVAS_BGR8
-#ifndef MNG_NO_16BIT_SUPPORT
-#ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
-mng_retcode mng_display_bgr8 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint16 iA16;
-  mng_uint16 iFGr16, iFGg16, iFGb16;
-  mng_uint16 iBGr16, iBGg16, iBGb16;
-  mng_uint8  iA8;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGR8, MNG_LC_START);
-#endif
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol * 3) + (pData->iDestl * 3);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-    if (pData->bIsRGBA16)              /* adjust source row starting-point */
-      pDataline = pDataline + (pData->iSourcel / pData->iColinc) * 8;
-    else
-      pDataline = pDataline + (pData->iSourcel / pData->iColinc) * 4;
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* scale down by dropping the LSB */
-          *pScanline     = *(pDataline+4);
-          *(pScanline+1) = *(pDataline+2);
-          *(pScanline+2) = *pDataline;
-
-          pScanline += (pData->iColinc * 3);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values */
-          *pScanline     = *(pDataline+2);
-          *(pScanline+1) = *(pDataline+1);
-          *(pScanline+2) = *pDataline;
-
-          pScanline += (pData->iColinc * 3);
-          pDataline += 4;
-        }
-      }
-    }
-    else
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* get alpha value */
-          iA16 = mng_get_uint16 (pDataline+6);
-
-          if (iA16)                    /* any opacity at all ? */
-          {
-            if (iA16 == 0xFFFF)        /* fully opaque ? */
-            {                          /* scale down by dropping the LSB */
-              *pScanline     = *(pDataline+4);
-              *(pScanline+1) = *(pDataline+2);
-              *(pScanline+2) = *pDataline;
-            }
-            else
-            {                          /* get the proper values */
-              iFGr16 = mng_get_uint16 (pDataline  );
-              iFGg16 = mng_get_uint16 (pDataline+2);
-              iFGb16 = mng_get_uint16 (pDataline+4);
-                                       /* scale background up */
-              iBGr16 = (mng_uint16)(*(pScanline+2));
-              iBGg16 = (mng_uint16)(*(pScanline+1));
-              iBGb16 = (mng_uint16)(*pScanline    );
-              iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
-              iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-              iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
-                                       /* now compose */
-              MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16);
-              MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
-              MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16);
-                                       /* and return the composed values */
-              *pScanline     = (mng_uint8)(iFGb16 >> 8);
-              *(pScanline+1) = (mng_uint8)(iFGg16 >> 8);
-              *(pScanline+2) = (mng_uint8)(iFGr16 >> 8);
-            }
-          }
-
-          pScanline += (pData->iColinc * 3);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iA8 = *(pDataline+3);        /* get alpha value */
-
-          if (iA8)                     /* any opacity at all ? */
-          {
-            if (iA8 == 0xFF)           /* fully opaque ? */
-            {                          /* then simply copy the values */
-              *pScanline     = *(pDataline+2);
-              *(pScanline+1) = *(pDataline+1);
-              *(pScanline+2) = *pDataline;
-            }
-            else
-            {                          /* do alpha composing */
-              MNG_COMPOSE8 (*pScanline,     *(pDataline+2), iA8, *pScanline    );
-              MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iA8, *(pScanline+1));
-              MNG_COMPOSE8 (*(pScanline+2), *pDataline,     iA8, *(pScanline+2));
-            }
-          }
-
-          pScanline += (pData->iColinc * 3);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGR8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
-mng_retcode mng_display_bgr8 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint16 iA16;
-  mng_uint16 iFGg16;
-  mng_uint16 iBGg16;
-  mng_uint8  iA8;
-  mng_uint8  iBps;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGR8, MNG_LC_START);
-#endif
-
-  iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol * 3) + (pData->iDestl * 3);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-    /* adjust source row starting-point */
-    pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* scale down by dropping the LSB */
-          *pScanline     = *(pDataline+2*iBps);
-          *(pScanline+1) = *(pDataline+iBps);
-          *(pScanline+2) = *pDataline;
-
-          pScanline += (pData->iColinc * 3);
-          pDataline += 4*iBps;
-        }
-    }
-    else
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* get alpha value */
-          iA16 = mng_get_uint16 (pDataline+6);
-
-          if (iA16)                    /* any opacity at all ? */
-          {
-            if (iA16 == 0xFFFF)        /* fully opaque ? */
-            {                          /* scale down by dropping the LSB */
-              *pScanline     = *(pDataline+4);
-              *(pScanline+1) = *(pDataline+2);
-              *(pScanline+2) = *pDataline;
-            }
-            else
-            {                          /* get the proper values */
-              int i;
-              for (i=2; i >= 0; i--)
-              {
-              iFGg16 = mng_get_uint16 (pDataline+i+i);
-                                       /* scale background up */
-              iBGg16 = (mng_uint16)(*(pScanline+2-i));
-              iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-                                       /* now compose */
-              MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
-                                       /* and return the composed values */
-              *(pScanline+2-i) = (mng_uint8)(iFGg16 >> 8);
-              }
-            }
-          }
-
-          pScanline += (pData->iColinc * 3);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iA8 = *(pDataline+3);        /* get alpha value */
-
-          if (iA8)                     /* any opacity at all ? */
-          {
-            if (iA8 == 0xFF)           /* fully opaque ? */
-            {                          /* then simply copy the values */
-              *pScanline     = *(pDataline+2);
-              *(pScanline+1) = *(pDataline+1);
-              *(pScanline+2) = *pDataline;
-            }
-            else
-            {                          /* do alpha composing */
-              int i;
-              for (i=2; i >= 0; i--)
-              {
-              MNG_COMPOSE8 (*(pScanline+i), *(pDataline+2-i), iA8, *(pScanline+i));
-              }
-            }
-          }
-
-          pScanline += (pData->iColinc * 3);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGR8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
-#else /* MNG_NO_16BIT_SUPPORT */
-mng_retcode mng_display_bgr8 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint8  iA8;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGR8, MNG_LC_START);
-#endif
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol * 3) + (pData->iDestl * 3);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-      pDataline = pDataline + (pData->iSourcel / pData->iColinc) * 4;
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values */
-          *pScanline     = *(pDataline+2);
-          *(pScanline+1) = *(pDataline+1);
-          *(pScanline+2) = *pDataline;
-
-          pScanline += (pData->iColinc * 3);
-          pDataline += 4;
-        }
-      }
-    }
-    else
-    {
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iA8 = *(pDataline+3);        /* get alpha value */
-
-          if (iA8)                     /* any opacity at all ? */
-          {
-            if (iA8 == 0xFF)           /* fully opaque ? */
-            {                          /* then simply copy the values */
-              *pScanline     = *(pDataline+2);
-              *(pScanline+1) = *(pDataline+1);
-              *(pScanline+2) = *pDataline;
-            }
-            else
-            {                          /* do alpha composing */
-#ifdef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
-              int i;
-              for (i=2; i >= 0; i--)
-              {
-              MNG_COMPOSE8 (*(pScanline+i), *(pDataline+2-i), iA8, *(pScanline+i));
-              }
-#else
-              MNG_COMPOSE8 (*pScanline,     *(pDataline+2), iA8, *pScanline    );
-              MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iA8, *(pScanline+1));
-              MNG_COMPOSE8 (*(pScanline+2), *pDataline,     iA8, *(pScanline+2));
-#endif
-            }
-          }
-
-          pScanline += (pData->iColinc * 3);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGR8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_NO_16BIT_SUPPORT */
-#endif /* MNG_SKIPCANVAS_BGR8 */
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCANVAS_BGRX8
-#ifndef MNG_NO_16BIT_SUPPORT
-#ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
-mng_retcode mng_display_bgrx8 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint16 iA16;
-  mng_uint16 iFGr16, iFGg16, iFGb16;
-  mng_uint16 iBGr16, iBGg16, iBGb16;
-  mng_uint8  iA8;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGRX8, MNG_LC_START);
-#endif
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-    if (pData->bIsRGBA16)              /* adjust source row starting-point */
-      pDataline = pDataline + (pData->iSourcel / pData->iColinc) * 8;
-    else
-      pDataline = pDataline + (pData->iSourcel / pData->iColinc) * 4;
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* scale down by dropping the LSB */
-          *pScanline     = *(pDataline+4);
-          *(pScanline+1) = *(pDataline+2);
-          *(pScanline+2) = *pDataline;
-          *(pScanline+3) = 0xFF;       /* filler byte */
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values */
-          *pScanline     = *(pDataline+2);
-          *(pScanline+1) = *(pDataline+1);
-          *(pScanline+2) = *pDataline;
-          *(pScanline+3) = 0xFF;       /* filler byte */
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-    else
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* get alpha value */
-          iA16 = mng_get_uint16 (pDataline+6);
-
-          if (iA16)                    /* any opacity at all ? */
-          {
-            if (iA16 == 0xFFFF)        /* fully opaque ? */
-            {                          /* scale down by dropping the LSB */
-              *pScanline     = *(pDataline+4);
-              *(pScanline+1) = *(pDataline+2);
-              *(pScanline+2) = *pDataline;
-              *(pScanline+3) = 0xFF;   /* filler byte */
-            }
-            else
-            {                          /* get the proper values */
-              iFGr16 = mng_get_uint16 (pDataline  );
-              iFGg16 = mng_get_uint16 (pDataline+2);
-              iFGb16 = mng_get_uint16 (pDataline+4);
-                                       /* scale background up */
-              iBGr16 = (mng_uint16)(*(pScanline+2));
-              iBGg16 = (mng_uint16)(*(pScanline+1));
-              iBGb16 = (mng_uint16)(*pScanline    );
-              iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
-              iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-              iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
-                                       /* now compose */
-              MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16);
-              MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
-              MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16);
-                                       /* and return the composed values */
-              *pScanline     = (mng_uint8)(iFGb16 >> 8);
-              *(pScanline+1) = (mng_uint8)(iFGg16 >> 8);
-              *(pScanline+2) = (mng_uint8)(iFGr16 >> 8);
-              *(pScanline+3) = 0xFF;   /* filler byte */
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iA8 = *(pDataline+3);        /* get alpha value */
-
-          if (iA8)                     /* any opacity at all ? */
-          {
-            if (iA8 == 0xFF)           /* fully opaque ? */
-            {                          /* then simply copy the values */
-              *pScanline     = *(pDataline+2);
-              *(pScanline+1) = *(pDataline+1);
-              *(pScanline+2) = *pDataline;
-              *(pScanline+3) = 0xFF;   /* filler byte */
-            }
-            else
-            {                          /* do alpha composing */
-              MNG_COMPOSE8 (*pScanline,     *(pDataline+2), iA8, *pScanline    );
-              MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iA8, *(pScanline+1));
-              MNG_COMPOSE8 (*(pScanline+2), *pDataline,     iA8, *(pScanline+2));
-              *(pScanline+3) = 0xFF;   /* filler byte */
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGRX8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
-mng_retcode mng_display_bgrx8 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint16 iA16;
-  mng_uint16 iFGg16;
-  mng_uint16 iBGg16;
-  mng_uint8  iA8;
-  mng_uint8  iBps;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGRX8, MNG_LC_START);
-#endif
-
-  iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-    /* adjust source row starting-point */
-    pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* scale down by dropping the LSB */
-          *pScanline     = *(pDataline+2*iBps);
-          *(pScanline+1) = *(pDataline+iBps);
-          *(pScanline+2) = *pDataline;
-          *(pScanline+3) = 0xFF;       /* filler byte */
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4*iBps;
-        }
-    }
-    else
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* get alpha value */
-          iA16 = mng_get_uint16 (pDataline+6);
-
-          if (iA16)                    /* any opacity at all ? */
-          {
-            if (iA16 == 0xFFFF)        /* fully opaque ? */
-            {                          /* scale down by dropping the LSB */
-              *pScanline     = *(pDataline+4);
-              *(pScanline+1) = *(pDataline+2);
-              *(pScanline+2) = *pDataline;
-              *(pScanline+3) = 0xFF;   /* filler byte */
-            }
-            else
-            {                          /* get the proper values */
-              int i;
-              for (i=2; i >= 0; i--)
-              {
-              iFGg16 = mng_get_uint16 (pDataline+i+i);
-                                       /* scale background up */
-              iBGg16 = (mng_uint16)(*(pScanline+2-i));
-              iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-                                       /* now compose */
-              MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
-                                       /* and return the composed values */
-              *(pScanline+2-i) = (mng_uint8)(iFGg16 >> 8);
-              }
-              *(pScanline+3) = 0xFF;   /* filler byte */
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iA8 = *(pDataline+3);        /* get alpha value */
-
-          if (iA8)                     /* any opacity at all ? */
-          {
-            if (iA8 == 0xFF)           /* fully opaque ? */
-            {                          /* then simply copy the values */
-              *pScanline     = *(pDataline+2);
-              *(pScanline+1) = *(pDataline+1);
-              *(pScanline+2) = *pDataline;
-              *(pScanline+3) = 0xFF;   /* filler byte */
-            }
-            else
-            {                          /* do alpha composing */
-              int i;
-              for (i=2; i >= 0; i--)
-              {
-              MNG_COMPOSE8 (*(pScanline+i), *(pDataline+2-i), iA8, *(pScanline+i));
-              }
-              *(pScanline+3) = 0xFF;   /* filler byte */
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGRX8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
-#else /* MNG_NO_16BIT_SUPPORT */
-mng_retcode mng_display_bgrx8 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint8  iA8;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGRX8, MNG_LC_START);
-#endif
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-      pDataline = pDataline + (pData->iSourcel / pData->iColinc) * 4;
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values */
-          *pScanline     = *(pDataline+2);
-          *(pScanline+1) = *(pDataline+1);
-          *(pScanline+2) = *pDataline;
-          *(pScanline+3) = 0xFF;       /* filler byte */
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-    else
-    {
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iA8 = *(pDataline+3);        /* get alpha value */
-
-          if (iA8)                     /* any opacity at all ? */
-          {
-            if (iA8 == 0xFF)           /* fully opaque ? */
-            {                          /* then simply copy the values */
-              *pScanline     = *(pDataline+2);
-              *(pScanline+1) = *(pDataline+1);
-              *(pScanline+2) = *pDataline;
-              *(pScanline+3) = 0xFF;   /* filler byte */
-            }
-            else
-            {                          /* do alpha composing */
-#ifdef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
-              int i;
-              for (i=2; i >= 0; i--)
-              {
-              MNG_COMPOSE8 (*(pScanline+i), *(pDataline+2-i), iA8, *(pScanline+i));
-              }
-#else
-              MNG_COMPOSE8 (*pScanline,     *(pDataline+2), iA8, *pScanline    );
-              MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iA8, *(pScanline+1));
-              MNG_COMPOSE8 (*(pScanline+2), *pDataline,     iA8, *(pScanline+2));
-#endif
-              *(pScanline+3) = 0xFF;   /* filler byte */
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGRX8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_NO_16BIT_SUPPORT */
-#endif /* MNG_SKIPCANVAS_BGRX8 */
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCANVAS_BGRA8
-#ifndef MNG_NO_16BIT_SUPPORT
-#ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
-mng_retcode mng_display_bgra8 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint8  iFGa8, iBGa8, iCa8;
-  mng_uint16 iFGa16, iBGa16, iCa16;
-  mng_uint16 iFGr16, iFGg16, iFGb16;
-  mng_uint16 iBGr16, iBGg16, iBGb16;
-  mng_uint16 iCr16, iCg16, iCb16;
-  mng_uint8  iCr8, iCg8, iCb8;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA8, MNG_LC_START);
-#endif
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-    if (pData->bIsRGBA16)              /* adjust source row starting-point */
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
-    else
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* scale down by dropping the LSB */
-          *pScanline     = *(pDataline+4);
-          *(pScanline+1) = *(pDataline+2);
-          *(pScanline+2) = *pDataline;
-          *(pScanline+3) = *(pDataline+6);
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values */
-          *pScanline     = *(pDataline+2);
-          *(pScanline+1) = *(pDataline+1);
-          *(pScanline+2) = *pDataline;
-          *(pScanline+3) = *(pDataline+3);
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-    else
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* get alpha values */
-          iFGa16 = mng_get_uint16 (pDataline+6);
-          iBGa16 = (mng_uint16)(*(pScanline+3));
-          iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
-
-          if (iFGa16)                  /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
-            {                          /* plain copy it */
-              *pScanline     = *(pDataline+4);
-              *(pScanline+1) = *(pDataline+2);
-              *(pScanline+2) = *pDataline;
-              *(pScanline+3) = *(pDataline+6);
-            }
-            else
-            {
-              if (iBGa16 == 0xFFFF)    /* background fully opaque ? */
-              {                        /* get the proper values */
-                iFGr16 = mng_get_uint16 (pDataline  );
-                iFGg16 = mng_get_uint16 (pDataline+2);
-                iFGb16 = mng_get_uint16 (pDataline+4);
-                                       /* scale background up */
-                iBGr16 = (mng_uint16)(*(pScanline+2));
-                iBGg16 = (mng_uint16)(*(pScanline+1));
-                iBGb16 = (mng_uint16)(*pScanline    );
-                iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
-                iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-                iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
-                                       /* now compose */
-                MNG_COMPOSE16(iFGr16, iFGr16, iFGa16, iBGr16);
-                MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
-                MNG_COMPOSE16(iFGb16, iFGb16, iFGa16, iBGb16);
-                                       /* and return the composed values */
-                *pScanline     = (mng_uint8)(iFGb16 >> 8);
-                *(pScanline+1) = (mng_uint8)(iFGg16 >> 8);
-                *(pScanline+2) = (mng_uint8)(iFGr16 >> 8);
-                                       /* alpha remains fully opaque !!! */
-              }
-              else
-              {                        /* scale background up */
-                iBGr16 = (mng_uint16)(*(pScanline+2));
-                iBGg16 = (mng_uint16)(*(pScanline+1));
-                iBGb16 = (mng_uint16)(*pScanline    );
-                iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
-                iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-                iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
-                                       /* let's blend */
-                MNG_BLEND16 (mng_get_uint16 (pDataline  ),
-                             mng_get_uint16 (pDataline+2),
-                             mng_get_uint16 (pDataline+4), iFGa16,
-                             iBGr16, iBGg16, iBGb16, iBGa16,
-                             iCr16,  iCg16,  iCb16,  iCa16);
-                                       /* and return the composed values */
-                *pScanline     = (mng_uint8)(iCb16 >> 8);
-                *(pScanline+1) = (mng_uint8)(iCg16 >> 8);
-                *(pScanline+2) = (mng_uint8)(iCr16 >> 8);
-                *(pScanline+3) = (mng_uint8)(iCa16 >> 8);
-              }
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iFGa8 = *(pDataline+3);      /* get alpha values */
-          iBGa8 = *(pScanline+3);
-
-          if (iFGa8)                   /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if ((iFGa8 == 0xFF) || (iBGa8 == 0))
-            {                          /* then simply copy the values */
-              *pScanline     = *(pDataline+2);
-              *(pScanline+1) = *(pDataline+1);
-              *(pScanline+2) = *pDataline;
-              *(pScanline+3) = *(pDataline+3);
-            }
-            else
-            {
-              if (iBGa8 == 0xFF)       /* background fully opaque ? */
-              {                        /* do alpha composing */
-                MNG_COMPOSE8 (*pScanline,     *(pDataline+2), iFGa8, *pScanline    );
-                MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iFGa8, *(pScanline+1));
-                MNG_COMPOSE8 (*(pScanline+2), *pDataline,     iFGa8, *(pScanline+2));
-                                       /* alpha remains fully opaque !!! */
-              }
-              else
-              {                        /* now blend */
-                MNG_BLEND8 (*pDataline,     *(pDataline+1), *(pDataline+2), iFGa8,
-                            *(pScanline+2), *(pScanline+1), *pScanline,     iBGa8,
-                            iCr8, iCg8, iCb8, iCa8);
-                                       /* and return the composed values */
-                *pScanline     = iCb8;
-                *(pScanline+1) = iCg8;
-                *(pScanline+2) = iCr8;
-                *(pScanline+3) = iCa8;
-              }
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
-mng_retcode mng_display_bgra8 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint8  iFGa8, iBGa8, iCa8;
-  mng_uint16 iFGa16, iBGa16, iCa16;
-  mng_uint16 iFGg16;
-  mng_uint16 iBGr16, iBGg16, iBGb16;
-  mng_uint16 iCr16, iCg16, iCb16;
-  mng_uint8  iCr8, iCg8, iCb8;
-  mng_uint8  iBps;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA8, MNG_LC_START);
-#endif
-
-  iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-    /* adjust source row starting-point */
-    pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* scale down by dropping the LSB */
-          *pScanline     = *(pDataline+2*iBps);
-          *(pScanline+1) = *(pDataline+iBps);
-          *(pScanline+2) = *pDataline;
-          *(pScanline+3) = *(pDataline+3*iBps);
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4*iBps;
-        }
-    }
-    else
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* get alpha values */
-          iFGa16 = mng_get_uint16 (pDataline+6);
-          iBGa16 = (mng_uint16)(*(pScanline+3));
-          iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
-
-          if (iFGa16)                  /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
-            {                          /* plain copy it */
-              *pScanline     = *(pDataline+4);
-              *(pScanline+1) = *(pDataline+2);
-              *(pScanline+2) = *pDataline;
-              *(pScanline+3) = *(pDataline+6);
-            }
-            else
-            {
-              if (iBGa16 == 0xFFFF)    /* background fully opaque ? */
-              {                        /* get the proper values */
-              int i;
-              for (i=2; i >= 0; i--)
-              {
-                iFGg16 = mng_get_uint16 (pDataline+i+i);
-                                       /* scale background up */
-                iBGg16 = (mng_uint16)(*(pScanline+2-i));
-                iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-                                       /* now compose */
-                MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
-                                       /* and return the composed values */
-                *(pScanline+2-i) = (mng_uint8)(iFGg16 >> 8);
-                                       /* alpha remains fully opaque !!! */
-              }
-              }
-              else
-              {                        /* scale background up */
-                iBGr16 = (mng_uint16)(*(pScanline+2));
-                iBGg16 = (mng_uint16)(*(pScanline+1));
-                iBGb16 = (mng_uint16)(*pScanline    );
-                iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
-                iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-                iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
-                                       /* let's blend */
-                MNG_BLEND16 (mng_get_uint16 (pDataline  ),
-                             mng_get_uint16 (pDataline+2),
-                             mng_get_uint16 (pDataline+4), iFGa16,
-                             iBGr16, iBGg16, iBGb16, iBGa16,
-                             iCr16,  iCg16,  iCb16,  iCa16);
-                                       /* and return the composed values */
-                *pScanline     = (mng_uint8)(iCb16 >> 8);
-                *(pScanline+1) = (mng_uint8)(iCg16 >> 8);
-                *(pScanline+2) = (mng_uint8)(iCr16 >> 8);
-                *(pScanline+3) = (mng_uint8)(iCa16 >> 8);
-              }
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iFGa8 = *(pDataline+3);      /* get alpha values */
-          iBGa8 = *(pScanline+3);
-
-          if (iFGa8)                   /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if ((iFGa8 == 0xFF) || (iBGa8 == 0))
-            {                          /* then simply copy the values */
-              *pScanline     = *(pDataline+2);
-              *(pScanline+1) = *(pDataline+1);
-              *(pScanline+2) = *pDataline;
-              *(pScanline+3) = *(pDataline+3);
-            }
-            else
-            {
-              if (iBGa8 == 0xFF)       /* background fully opaque ? */
-              {                        /* do alpha composing */
-                int i;
-                for (i=2; i >= 0; i--)
-                {
-                MNG_COMPOSE8 (*(pScanline+i), *(pDataline+2-i), iFGa8, *(pScanline+i));
-                }
-                                       /* alpha remains fully opaque !!! */
-              }
-              else
-              {                        /* now blend */
-                MNG_BLEND8 (*pDataline,     *(pDataline+1), *(pDataline+2), iFGa8,
-                            *(pScanline+2), *(pScanline+1), *pScanline,     iBGa8,
-                            iCr8, iCg8, iCb8, iCa8);
-                                       /* and return the composed values */
-                *pScanline     = iCb8;
-                *(pScanline+1) = iCg8;
-                *(pScanline+2) = iCr8;
-                *(pScanline+3) = iCa8;
-              }
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
-#else /* MNG_NO_16BIT_SUPPORT */
-mng_retcode mng_display_bgra8 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint8  iFGa8, iBGa8, iCa8;
-  mng_uint8  iCr8, iCg8, iCb8;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA8, MNG_LC_START);
-#endif
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values */
-          *pScanline     = *(pDataline+2);
-          *(pScanline+1) = *(pDataline+1);
-          *(pScanline+2) = *pDataline;
-          *(pScanline+3) = *(pDataline+3);
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-    else
-    {
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iFGa8 = *(pDataline+3);      /* get alpha values */
-          iBGa8 = *(pScanline+3);
-
-          if (iFGa8)                   /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if ((iFGa8 == 0xFF) || (iBGa8 == 0))
-            {                          /* then simply copy the values */
-              *pScanline     = *(pDataline+2);
-              *(pScanline+1) = *(pDataline+1);
-              *(pScanline+2) = *pDataline;
-              *(pScanline+3) = *(pDataline+3);
-            }
-            else
-            {
-              if (iBGa8 == 0xFF)       /* background fully opaque ? */
-              {                        /* do alpha composing */
-#ifdef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
-                int i;
-                for (i=2; i >= 0; i--)
-                {
-                MNG_COMPOSE8 (*(pScanline+i), *(pDataline+2-i), iFGa8, *(pScanline+i));
-                }
-#else
-                MNG_COMPOSE8 (*pScanline,     *(pDataline+2), iFGa8, *pScanline    );
-                MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iFGa8, *(pScanline+1));
-                MNG_COMPOSE8 (*(pScanline+2), *pDataline,     iFGa8, *(pScanline+2));
-#endif
-                                       /* alpha remains fully opaque !!! */
-              }
-              else
-              {                        /* now blend */
-                MNG_BLEND8 (*pDataline,     *(pDataline+1), *(pDataline+2), iFGa8,
-                            *(pScanline+2), *(pScanline+1), *pScanline,     iBGa8,
-                            iCr8, iCg8, iCb8, iCa8);
-                                       /* and return the composed values */
-                *pScanline     = iCb8;
-                *(pScanline+1) = iCg8;
-                *(pScanline+2) = iCr8;
-                *(pScanline+3) = iCa8;
-              }
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_NO_16BIT_SUPPORT */
-#endif /* MNG_SKIPCANVAS_BGRA8 */
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCANVAS_BGRA8_PM
-#ifndef MNG_NO_16BIT_SUPPORT
-#ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
-mng_retcode mng_display_bgra8_pm (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint32 s, t;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA8PM, MNG_LC_START);
-#endif
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-    if (pData->bIsRGBA16)              /* adjust source row starting-point */
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
-    else
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* scale down by dropping the LSB */
-          if ((s = pDataline[6]) == 0)
-            *(mng_uint32*) pScanline = 0; /* set all components = 0 */
-          else
-          {
-            if (s == 255)
-            {
-              pScanline[0] = pDataline[4];
-              pScanline[1] = pDataline[2];
-              pScanline[2] = pDataline[0];
-              pScanline[3] = 255;
-            }
-            else
-            {
-              pScanline[0] = DIV255B8(s * pDataline[4]);
-              pScanline[1] = DIV255B8(s * pDataline[2]);
-              pScanline[2] = DIV255B8(s * pDataline[0]);
-              pScanline[3] = (mng_uint8)s;
-            }
-          }
-          pScanline += (pData->iColinc << 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values and premultiply */
-          if ((s = pDataline[3]) == 0)
-            *(mng_uint32*) pScanline = 0; /* set all components = 0 */
-          else
-          {
-            if (s == 255)
-            {
-              pScanline[0] = pDataline[2];
-              pScanline[1] = pDataline[1];
-              pScanline[2] = pDataline[0];
-              pScanline[3] = 255;
-            }
-            else
-            {
-              pScanline[0] = DIV255B8(s * pDataline[2]);
-              pScanline[1] = DIV255B8(s * pDataline[1]);
-              pScanline[2] = DIV255B8(s * pDataline[0]);
-              pScanline[3] = (mng_uint8)s;
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-    else
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* get alpha values */
-          if ((s = pDataline[6]) != 0)       /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if (s == 255)
-            {                          /* plain copy it */
-              pScanline[0] = pDataline[4];
-              pScanline[1] = pDataline[2];
-              pScanline[2] = pDataline[0];
-              pScanline[3] = 255;
-            }
-            else
-            {                          /* now blend (premultiplied) */
-              t = 255 - s;
-#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
-              {
-                int i;
-                for (i=2; i >= 0; i--)
-                {
-                  pScanline[i] = DIV255B8(s * pDataline[4-i-i] + t *
-                     pScanline[i]);
-                }
-              }
-#else
-              pScanline[0] = DIV255B8(s * pDataline[4] + t * pScanline[0]);
-              pScanline[1] = DIV255B8(s * pDataline[2] + t * pScanline[1]);
-              pScanline[2] = DIV255B8(s * pDataline[0] + t * pScanline[2]);
-#endif
-              pScanline[3] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[3])));
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          if ((s = pDataline[3]) != 0)       /* any opacity at all ? */
-          {                            /* fully opaque ? */
-            if (s == 255)
-            {                          /* then simply copy the values */
-              pScanline[0] = pDataline[2];
-              pScanline[1] = pDataline[1];
-              pScanline[2] = pDataline[0];
-              pScanline[3] = 255;
-            }
-            else
-            {                          /* now blend (premultiplied) */
-              t = 255 - s;
-#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
-              {
-                int i;
-                for (i=2; i >= 0; i--)
-                {
-                  pScanline[i] = DIV255B8(s * pDataline[2-i] + t *
-                     pScanline[i]);
-                }
-              }
-#else
-              pScanline[0] = DIV255B8(s * pDataline[2] + t * pScanline[0]);
-              pScanline[1] = DIV255B8(s * pDataline[1] + t * pScanline[1]);
-              pScanline[2] = DIV255B8(s * pDataline[0] + t * pScanline[2]);
-#endif
-              pScanline[3] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[3])));
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA8PM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
-mng_retcode mng_display_bgra8_pm (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint32 s, t;
-  mng_uint8  iBps;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA8PM, MNG_LC_START);
-#endif
-
-  iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-    /* adjust source row starting-point */
-    pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* scale down by dropping the LSB */
-          if ((s = pDataline[6]) == 0)
-            *(mng_uint32*) pScanline = 0; /* set all components = 0 */
-          else
-          {
-            if (s == 255)
-            {
-              pScanline[0] = pDataline[4];
-              pScanline[1] = pDataline[2];
-              pScanline[2] = pDataline[0];
-              pScanline[3] = 255;
-            }
-            else
-            {
-#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
-              int i;
-              for (i=2; i >= 0; i--)
-              {
-                pScanline[i] = DIV255B8(s * pDataline[4-i-i]);
-              }
-#else
-              pScanline[0] = DIV255B8(s * pDataline[4]);
-              pScanline[1] = DIV255B8(s * pDataline[2]);
-              pScanline[2] = DIV255B8(s * pDataline[0]);
-#endif
-              pScanline[3] = (mng_uint8)s;
-            }
-          }
-          pScanline += (pData->iColinc << 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values and premultiply */
-          if ((s = pDataline[3]) == 0)
-            *(mng_uint32*) pScanline = 0; /* set all components = 0 */
-          else
-          {
-            if (s == 255)
-            {
-              pScanline[0] = pDataline[2];
-              pScanline[1] = pDataline[1];
-              pScanline[2] = pDataline[0];
-              pScanline[3] = 255;
-            }
-            else
-            {
-#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
-              int i;
-              for (i=2; i >= 0; i--)
-              {
-                pScanline[i] = DIV255B8(s * pDataline[2-i]);
-              }
-#else
-              pScanline[0] = DIV255B8(s * pDataline[2]);
-              pScanline[1] = DIV255B8(s * pDataline[1]);
-              pScanline[2] = DIV255B8(s * pDataline[0]);
-#endif
-              pScanline[3] = (mng_uint8)s;
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-    else
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* get alpha values */
-          if ((s = pDataline[6]) != 0)       /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if (s == 255)
-            {                          /* plain copy it */
-              pScanline[0] = pDataline[4];
-              pScanline[1] = pDataline[2];
-              pScanline[2] = pDataline[0];
-              pScanline[3] = 255;
-            }
-            else
-            {                          /* now blend (premultiplied) */
-              t = 255 - s;
-#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
-              {
-                int i;
-                for (i=2; i >= 0; i--)
-                {
-                  pScanline[i] = DIV255B8(s * pDataline[4-i-i] + t *
-                     pScanline[i]);
-                }
-              }
-#else
-              pScanline[0] = DIV255B8(s * pDataline[4] + t * pScanline[0]);
-              pScanline[1] = DIV255B8(s * pDataline[2] + t * pScanline[1]);
-              pScanline[2] = DIV255B8(s * pDataline[0] + t * pScanline[2]);
-#endif
-              pScanline[3] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[3])));
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          if ((s = pDataline[3]) != 0)       /* any opacity at all ? */
-          {                            /* fully opaque ? */
-            if (s == 255)
-            {                          /* then simply copy the values */
-              pScanline[0] = pDataline[2];
-              pScanline[1] = pDataline[1];
-              pScanline[2] = pDataline[0];
-              pScanline[3] = 255;
-            }
-            else
-            {                          /* now blend (premultiplied) */
-              t = 255 - s;
-#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
-              {
-                int i;
-                for (i=2; i >= 0; i--)
-                {
-                  pScanline[i] = DIV255B8(s * pDataline[2-i] + t *
-                     pScanline[i]);
-                }
-              }
-#else
-              pScanline[0] = DIV255B8(s * pDataline[2] + t * pScanline[0]);
-              pScanline[1] = DIV255B8(s * pDataline[1] + t * pScanline[1]);
-              pScanline[2] = DIV255B8(s * pDataline[0] + t * pScanline[2]);
-#endif
-              pScanline[3] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[3])));
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA8PM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
-#else /* MNG_NO_16BIT_SUPPORT */
-mng_retcode mng_display_bgra8_pm (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint32 s, t;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA8PM, MNG_LC_START);
-#endif
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values and premultiply */
-          if ((s = pDataline[3]) == 0)
-            *(mng_uint32*) pScanline = 0; /* set all components = 0 */
-          else
-          {
-            if (s == 255)
-            {
-              pScanline[0] = pDataline[2];
-              pScanline[1] = pDataline[1];
-              pScanline[2] = pDataline[0];
-              pScanline[3] = 255;
-            }
-            else
-            {
-#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
-              int i;
-              for (i=2; i >= 0; i--)
-              {
-                pScanline[i] = DIV255B8(s * pDataline[2-i]);
-              }
-#else
-              pScanline[0] = DIV255B8(s * pDataline[2]);
-              pScanline[1] = DIV255B8(s * pDataline[1]);
-              pScanline[2] = DIV255B8(s * pDataline[0]);
-#endif
-              pScanline[3] = (mng_uint8)s;
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-    else
-    {
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          if ((s = pDataline[3]) != 0)       /* any opacity at all ? */
-          {                            /* fully opaque ? */
-            if (s == 255)
-            {                          /* then simply copy the values */
-              pScanline[0] = pDataline[2];
-              pScanline[1] = pDataline[1];
-              pScanline[2] = pDataline[0];
-              pScanline[3] = 255;
-            }
-            else
-            {                          /* now blend (premultiplied) */
-              t = 255 - s;
-#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
-              {
-                int i;
-                for (i=2; i >= 0; i--)
-                {
-                  pScanline[i] = DIV255B8(s * pDataline[2-i] + t *
-                     pScanline[i]);
-                }
-              }
-#else
-              pScanline[0] = DIV255B8(s * pDataline[2] + t * pScanline[0]);
-              pScanline[1] = DIV255B8(s * pDataline[1] + t * pScanline[1]);
-              pScanline[2] = DIV255B8(s * pDataline[0] + t * pScanline[2]);
-#endif
-              pScanline[3] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[3])));
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA8PM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_NO_16BIT_SUPPORT */
-#endif /* MNG_SKIPCANVAS_BGRA8_PM */
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCANVAS_ABGR8
-#ifndef MNG_NO_16BIT_SUPPORT
-#ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
-mng_retcode mng_display_abgr8 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint8  iFGa8, iBGa8, iCa8;
-  mng_uint16 iFGa16, iBGa16, iCa16;
-  mng_uint16 iFGr16, iFGg16, iFGb16;
-  mng_uint16 iBGr16, iBGg16, iBGb16;
-  mng_uint16 iCr16, iCg16, iCb16;
-  mng_uint8  iCr8, iCg8, iCb8;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_ABGR8, MNG_LC_START);
-#endif
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-    if (pData->bIsRGBA16)              /* adjust source row starting-point */
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
-    else
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* scale down by dropping the LSB */
-          *pScanline     = *(pDataline+6);
-          *(pScanline+1) = *(pDataline+4);
-          *(pScanline+2) = *(pDataline+2);
-          *(pScanline+3) = *pDataline;
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values */
-          *pScanline     = *(pDataline+3);
-          *(pScanline+1) = *(pDataline+2);
-          *(pScanline+2) = *(pDataline+1);
-          *(pScanline+3) = *pDataline;
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-    else
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* get alpha values */
-          iFGa16 = mng_get_uint16 (pDataline+6);
-          iBGa16 = (mng_uint16)(*pScanline);
-          iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
-
-          if (iFGa16)                  /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
-            {                          /* plain copy it */
-              *pScanline     = *(pDataline+6);
-              *(pScanline+1) = *(pDataline+4);
-              *(pScanline+2) = *(pDataline+2);
-              *(pScanline+3) = *pDataline;
-            }
-            else
-            {
-              if (iBGa16 == 0xFFFF)    /* background fully opaque ? */
-              {                        /* get the proper values */
-                iFGr16 = mng_get_uint16 (pDataline  );
-                iFGg16 = mng_get_uint16 (pDataline+2);
-                iFGb16 = mng_get_uint16 (pDataline+4);
-                                       /* scale background up */
-                iBGr16 = (mng_uint16)(*(pScanline+3));
-                iBGg16 = (mng_uint16)(*(pScanline+2));
-                iBGb16 = (mng_uint16)(*(pScanline+1));
-                iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
-                iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-                iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
-                                       /* now compose */
-                MNG_COMPOSE16(iFGr16, iFGr16, iFGa16, iBGr16);
-                MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
-                MNG_COMPOSE16(iFGb16, iFGb16, iFGa16, iBGb16);
-                                       /* and return the composed values */
-                                       /* alpha itself remains fully opaque !!! */
-                *(pScanline+1) = (mng_uint8)(iFGb16 >> 8);
-                *(pScanline+2) = (mng_uint8)(iFGg16 >> 8);
-                *(pScanline+3) = (mng_uint8)(iFGr16 >> 8);
-              }
-              else
-              {                        /* scale background up */
-                iBGr16 = (mng_uint16)(*(pScanline+3));
-                iBGg16 = (mng_uint16)(*(pScanline+2));
-                iBGb16 = (mng_uint16)(*(pScanline+1));
-                iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
-                iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-                iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
-                                       /* let's blend */
-                MNG_BLEND16 (mng_get_uint16 (pDataline  ),
-                             mng_get_uint16 (pDataline+2),
-                             mng_get_uint16 (pDataline+4), iFGa16,
-                             iBGr16, iBGg16, iBGb16, iBGa16,
-                             iCr16,  iCg16,  iCb16,  iCa16);
-                                       /* and return the composed values */
-                *pScanline     = (mng_uint8)(iCa16 >> 8);
-                *(pScanline+1) = (mng_uint8)(iCb16 >> 8);
-                *(pScanline+2) = (mng_uint8)(iCg16 >> 8);
-                *(pScanline+3) = (mng_uint8)(iCr16 >> 8);
-              }
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iFGa8 = *(pDataline+3);      /* get alpha values */
-          iBGa8 = *pScanline;
-
-          if (iFGa8)                   /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if ((iFGa8 == 0xFF) || (iBGa8 == 0))
-            {                          /* then simply copy the values */
-              *pScanline     = *(pDataline+3);
-              *(pScanline+1) = *(pDataline+2);
-              *(pScanline+2) = *(pDataline+1);
-              *(pScanline+3) = *pDataline;
-            }
-            else
-            {
-              if (iBGa8 == 0xFF)       /* background fully opaque ? */
-              {                        /* do simple alpha composing */
-                                       /* alpha itself remains fully opaque !!! */
-                MNG_COMPOSE8 (*(pScanline+1), *(pDataline+2), iFGa8, *(pScanline+1));
-                MNG_COMPOSE8 (*(pScanline+2), *(pDataline+1), iFGa8, *(pScanline+2));
-                MNG_COMPOSE8 (*(pScanline+3), *pDataline,     iFGa8, *(pScanline+3));
-              }
-              else
-              {                        /* now blend */
-                MNG_BLEND8 (*pDataline,     *(pDataline+1), *(pDataline+2), iFGa8,
-                            *(pScanline+3), *(pScanline+2), *(pScanline+1), iBGa8,
-                            iCr8, iCg8, iCb8, iCa8);
-                                       /* and return the composed values */
-                *pScanline     = iCa8;
-                *(pScanline+1) = iCb8;
-                *(pScanline+2) = iCg8;
-                *(pScanline+3) = iCr8;
-              }
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_ABGR8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
-mng_retcode mng_display_abgr8 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint8  iFGa8, iBGa8, iCa8;
-  mng_uint16 iFGa16, iBGa16, iCa16;
-  mng_uint16 iFGg16;
-  mng_uint16 iBGr16, iBGg16, iBGb16;
-  mng_uint16 iCr16, iCg16, iCb16;
-  mng_uint8  iCr8, iCg8, iCb8;
-  mng_uint8  iBps;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_ABGR8, MNG_LC_START);
-#endif
-
-  iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-    /* adjust source row starting-point */
-    pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* scale down by dropping the LSB */
-          *pScanline     = *(pDataline+3*iBps);
-          *(pScanline+1) = *(pDataline+2*iBps);
-          *(pScanline+2) = *(pDataline+iBps);
-          *(pScanline+3) = *pDataline;
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4*iBps;
-        }
-    }
-    else
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* get alpha values */
-          iFGa16 = mng_get_uint16 (pDataline+6);
-          iBGa16 = (mng_uint16)(*pScanline);
-          iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
-
-          if (iFGa16)                  /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
-            {                          /* plain copy it */
-              *pScanline     = *(pDataline+6);
-              *(pScanline+1) = *(pDataline+4);
-              *(pScanline+2) = *(pDataline+2);
-              *(pScanline+3) = *pDataline;
-            }
-            else
-            {
-              if (iBGa16 == 0xFFFF)    /* background fully opaque ? */
-              {                        /* get the proper values */
-              int i;
-              for (i=2; i >= 0; i--)
-              {
-                iFGg16 = mng_get_uint16 (pDataline+i+i);
-                                       /* scale background up */
-                iBGg16 = (mng_uint16)(*(pScanline+3-i));
-                iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-                                       /* now compose */
-                MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
-                                       /* and return the composed values */
-                                       /* alpha itself remains fully opaque !!! */
-                *(pScanline+3-i) = (mng_uint8)(iFGg16 >> 8);
-              }
-              }
-              else
-              {                        /* scale background up */
-                iBGr16 = (mng_uint16)(*(pScanline+3));
-                iBGg16 = (mng_uint16)(*(pScanline+2));
-                iBGb16 = (mng_uint16)(*(pScanline+1));
-                iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
-                iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-                iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
-                                       /* let's blend */
-                MNG_BLEND16 (mng_get_uint16 (pDataline  ),
-                             mng_get_uint16 (pDataline+2),
-                             mng_get_uint16 (pDataline+4), iFGa16,
-                             iBGr16, iBGg16, iBGb16, iBGa16,
-                             iCr16,  iCg16,  iCb16,  iCa16);
-                                       /* and return the composed values */
-                *pScanline     = (mng_uint8)(iCa16 >> 8);
-                *(pScanline+1) = (mng_uint8)(iCb16 >> 8);
-                *(pScanline+2) = (mng_uint8)(iCg16 >> 8);
-                *(pScanline+3) = (mng_uint8)(iCr16 >> 8);
-              }
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iFGa8 = *(pDataline+3);      /* get alpha values */
-          iBGa8 = *pScanline;
-
-          if (iFGa8)                   /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if ((iFGa8 == 0xFF) || (iBGa8 == 0))
-            {                          /* then simply copy the values */
-              *pScanline     = *(pDataline+3);
-              *(pScanline+1) = *(pDataline+2);
-              *(pScanline+2) = *(pDataline+1);
-              *(pScanline+3) = *pDataline;
-            }
-            else
-            {
-              if (iBGa8 == 0xFF)       /* background fully opaque ? */
-              {                        /* do simple alpha composing */
-                                       /* alpha itself remains fully opaque !!! */
-                int i;
-                for (i=2; i >= 0; i--)
-                {
-                MNG_COMPOSE8 (*(pScanline+i+1), *(pDataline+2-i), iFGa8, *(pScanline+i+1));
-                }
-              }
-              else
-              {                        /* now blend */
-                MNG_BLEND8 (*pDataline,     *(pDataline+1), *(pDataline+2), iFGa8,
-                            *(pScanline+3), *(pScanline+2), *(pScanline+1), iBGa8,
-                            iCr8, iCg8, iCb8, iCa8);
-                                       /* and return the composed values */
-                *pScanline     = iCa8;
-                *(pScanline+1) = iCb8;
-                *(pScanline+2) = iCg8;
-                *(pScanline+3) = iCr8;
-              }
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_ABGR8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
-#else /* MNG_NO_16BIT_SUPPORT */
-mng_retcode mng_display_abgr8 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint8  iFGa8, iBGa8, iCa8;
-  mng_uint8  iCr8, iCg8, iCb8;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_ABGR8, MNG_LC_START);
-#endif
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values */
-          *pScanline     = *(pDataline+3);
-          *(pScanline+1) = *(pDataline+2);
-          *(pScanline+2) = *(pDataline+1);
-          *(pScanline+3) = *pDataline;
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-    else
-    {
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iFGa8 = *(pDataline+3);      /* get alpha values */
-          iBGa8 = *pScanline;
-
-          if (iFGa8)                   /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if ((iFGa8 == 0xFF) || (iBGa8 == 0))
-            {                          /* then simply copy the values */
-              *pScanline     = *(pDataline+3);
-              *(pScanline+1) = *(pDataline+2);
-              *(pScanline+2) = *(pDataline+1);
-              *(pScanline+3) = *pDataline;
-            }
-            else
-            {
-              if (iBGa8 == 0xFF)       /* background fully opaque ? */
-              {                        /* do simple alpha composing */
-                                       /* alpha itself remains fully opaque !!! */
-#ifdef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
-                int i;
-                for (i=2; i >= 0; i--)
-                {
-                MNG_COMPOSE8 (*(pScanline+i+1), *(pDataline+2-i), iFGa8, *(pScanline+i+1));
-                }
-#else
-                MNG_COMPOSE8 (*(pScanline+1), *(pDataline+2), iFGa8, *(pScanline+1));
-                MNG_COMPOSE8 (*(pScanline+2), *(pDataline+1), iFGa8, *(pScanline+2));
-                MNG_COMPOSE8 (*(pScanline+3), *pDataline,     iFGa8, *(pScanline+3));
-#endif
-              }
-              else
-              {                        /* now blend */
-                MNG_BLEND8 (*pDataline,     *(pDataline+1), *(pDataline+2), iFGa8,
-                            *(pScanline+3), *(pScanline+2), *(pScanline+1), iBGa8,
-                            iCr8, iCg8, iCb8, iCa8);
-                                       /* and return the composed values */
-                *pScanline     = iCa8;
-                *(pScanline+1) = iCb8;
-                *(pScanline+2) = iCg8;
-                *(pScanline+3) = iCr8;
-              }
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_ABGR8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_NO_16BIT_SUPPORT */
-#endif /* MNG_SKIPCANVAS_ABGR8 */
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCANVAS_ABGR8_PM
-#ifndef MNG_NO_16BIT_SUPPORT
-#ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
-mng_retcode mng_display_abgr8_pm (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint32 s, t;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_ABGR8_PM, MNG_LC_START);
-#endif
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-    if (pData->bIsRGBA16)              /* adjust source row starting-point */
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
-    else
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* scale down by dropping the LSB */
-		  if ((s = pDataline[6]) == 0)
-			*(mng_uint32*) pScanline = 0; /* set all components = 0 */
-		  else
-		  {
-			if (s == 255)
-			{
-              pScanline[0] = 255;
-		      pScanline[1] = pDataline[4];
-              pScanline[2] = pDataline[2];
-              pScanline[3] = pDataline[0];
-			}
-			else
-			{
-              pScanline[0] = (mng_uint8)s;
-#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
-              {
-                int i;
-                for (i=2; i >= 0; i--)
-                {
-                  pScanline[i+1] = DIV255B8(s * pDataline[4-i-i]);
-                }
-              }
-#else
-              pScanline[1] = DIV255B8(s * pDataline[4]);
-              pScanline[2] = DIV255B8(s * pDataline[2]);
-              pScanline[3] = DIV255B8(s * pDataline[0]);
-#endif
-			}
-		  }
-          pScanline += (pData->iColinc << 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values and premultiply */
-		  if ((s = pDataline[3]) == 0)
-			*(mng_uint32*) pScanline = 0; /* set all components = 0 */
-		  else
-		  {
-			if (s == 255)
-			{
-              pScanline[0] = 255;
-		      pScanline[1] = pDataline[2];
-              pScanline[2] = pDataline[1];
-              pScanline[3] = pDataline[0];
-			}
-			else
-			{
-              pScanline[0] = (mng_uint8)s;
-#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
-              {
-                int i;
-                for (i=2; i >= 0; i--)
-                {
-                  pScanline[i+1] = DIV255B8(s * pDataline[2-i]);
-                }
-              }
-#else
-              pScanline[1] = DIV255B8(s * pDataline[2]);
-              pScanline[2] = DIV255B8(s * pDataline[1]);
-		      pScanline[3] = DIV255B8(s * pDataline[0]);
-#endif
-			}
-		  }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-    else
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* get alpha values */
-          if ((s = pDataline[6]) != 0)       /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if (s == 255)
-            {                          /* plain copy it */
-              pScanline[0] = 255;
-              pScanline[1] = pDataline[4];
-              pScanline[2] = pDataline[2];
-              pScanline[3] = pDataline[0];
-            }
-            else
-            {                          /* now blend (premultiplied) */
-			  t = 255 - s;
-              pScanline[0] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[0])));
-#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
-              {
-                int i;
-                for (i=2; i >= 0; i--)
-                {
-                  pScanline[i+1] = DIV255B8(s * pDataline[4-i-i] + t *
-                     pScanline[i+1]);
-                }
-              }
-#else
-			  pScanline[1] = DIV255B8(s * pDataline[4] + t * pScanline[1]);
-              pScanline[2] = DIV255B8(s * pDataline[2] + t * pScanline[2]);
-              pScanline[3] = DIV255B8(s * pDataline[0] + t * pScanline[3]);
-#endif
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          if ((s = pDataline[3]) != 0)       /* any opacity at all ? */
-          {                            /* fully opaque ? */
-            if (s == 255)
-            {                          /* then simply copy the values */
-              pScanline[0] = 255;
-              pScanline[1] = pDataline[2];
-              pScanline[2] = pDataline[1];
-              pScanline[3] = pDataline[0];
-            }
-            else
-            {                          /* now blend (premultiplied) */
-			  t = 255 - s;
-              pScanline[0] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[0])));
-#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
-              {
-                int i;
-                for (i=2; i >= 0; i--)
-                {
-                  pScanline[i+1] = DIV255B8(s * pDataline[2-i] + t *
-                     pScanline[i+1]);
-                }
-              }
-#else
-			  pScanline[1] = DIV255B8(s * pDataline[2] + t * pScanline[1]);
-              pScanline[2] = DIV255B8(s * pDataline[1] + t * pScanline[2]);
-              pScanline[3] = DIV255B8(s * pDataline[0] + t * pScanline[3]);
-#endif
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_ABGR8_PM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
-mng_retcode mng_display_abgr8_pm (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint32 s, t;
-  mng_uint8  iBps;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_ABGR8_PM, MNG_LC_START);
-#endif
-
-  iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-    /* adjust source row starting-point */
-    pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* scale down by dropping the LSB */
-		  if ((s = pDataline[6]) == 0)
-			*(mng_uint32*) pScanline = 0; /* set all components = 0 */
-		  else
-		  {
-			if (s == 255)
-			{
-              pScanline[0] = 255;
-		      pScanline[1] = pDataline[4];
-              pScanline[2] = pDataline[2];
-              pScanline[3] = pDataline[0];
-			}
-			else
-			{
-              pScanline[0] = (mng_uint8)s;
-#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
-              {
-                int i;
-                for (i=2; i >= 0; i--)
-                {
-                  pScanline[i+1] = DIV255B8(s * pDataline[4-i-i]);
-                }
-              }
-#else
-              pScanline[1] = DIV255B8(s * pDataline[4]);
-              pScanline[2] = DIV255B8(s * pDataline[2]);
-              pScanline[3] = DIV255B8(s * pDataline[0]);
-#endif
-			}
-		  }
-          pScanline += (pData->iColinc << 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values and premultiply */
-		  if ((s = pDataline[3]) == 0)
-			*(mng_uint32*) pScanline = 0; /* set all components = 0 */
-		  else
-		  {
-			if (s == 255)
-			{
-              pScanline[0] = 255;
-		      pScanline[1] = pDataline[2];
-              pScanline[2] = pDataline[1];
-              pScanline[3] = pDataline[0];
-			}
-			else
-			{
-              pScanline[0] = (mng_uint8)s;
-#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
-              {
-                int i;
-                for (i=2; i >= 0; i--)
-                {
-                  pScanline[i+1] = DIV255B8(s * pDataline[2-i]);
-                }
-              }
-#else
-              pScanline[1] = DIV255B8(s * pDataline[2]);
-              pScanline[2] = DIV255B8(s * pDataline[1]);
-		      pScanline[3] = DIV255B8(s * pDataline[0]);
-#endif
-			}
-		  }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-    else
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* get alpha values */
-          if ((s = pDataline[6]) != 0)       /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if (s == 255)
-            {                          /* plain copy it */
-              pScanline[0] = 255;
-              pScanline[1] = pDataline[4];
-              pScanline[2] = pDataline[2];
-              pScanline[3] = pDataline[0];
-            }
-            else
-            {                          /* now blend (premultiplied) */
-			  t = 255 - s;
-              pScanline[0] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[0])));
-#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
-              {
-                int i;
-                for (i=2; i >= 0; i--)
-                {
-                  pScanline[i+1] = DIV255B8(s * pDataline[4-i-i] + t *
-                     pScanline[i+1]);
-                }
-              }
-#else
-			  pScanline[1] = DIV255B8(s * pDataline[4] + t * pScanline[1]);
-              pScanline[2] = DIV255B8(s * pDataline[2] + t * pScanline[2]);
-              pScanline[3] = DIV255B8(s * pDataline[0] + t * pScanline[3]);
-#endif
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          if ((s = pDataline[3]) != 0)       /* any opacity at all ? */
-          {                            /* fully opaque ? */
-            if (s == 255)
-            {                          /* then simply copy the values */
-              pScanline[0] = 255;
-              pScanline[1] = pDataline[2];
-              pScanline[2] = pDataline[1];
-              pScanline[3] = pDataline[0];
-            }
-            else
-            {                          /* now blend (premultiplied) */
-			  t = 255 - s;
-              pScanline[0] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[0])));
-#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
-              {
-                int i;
-                for (i=2; i >= 0; i--)
-                {
-                  pScanline[i+1] = DIV255B8(s * pDataline[2-i] + t *
-                     pScanline[i+1]);
-                }
-              }
-#else
-			  pScanline[1] = DIV255B8(s * pDataline[2] + t * pScanline[1]);
-              pScanline[2] = DIV255B8(s * pDataline[1] + t * pScanline[2]);
-              pScanline[3] = DIV255B8(s * pDataline[0] + t * pScanline[3]);
-#endif
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_ABGR8_PM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
-#else /* MNG_NO_16BIT_SUPPORT */
-mng_retcode mng_display_abgr8_pm (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint32 s, t;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_ABGR8_PM, MNG_LC_START);
-#endif
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values and premultiply */
-		  if ((s = pDataline[3]) == 0)
-			*(mng_uint32*) pScanline = 0; /* set all components = 0 */
-		  else
-		  {
-			if (s == 255)
-			{
-              pScanline[0] = 255;
-		      pScanline[1] = pDataline[2];
-              pScanline[2] = pDataline[1];
-              pScanline[3] = pDataline[0];
-			}
-			else
-			{
-              pScanline[0] = (mng_uint8)s;
-#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
-              {
-                int i;
-                for (i=2; i >= 0; i--)
-                {
-                  pScanline[i+1] = DIV255B8(s * pDataline[2-i]);
-                }
-              }
-#else
-              pScanline[1] = DIV255B8(s * pDataline[2]);
-              pScanline[2] = DIV255B8(s * pDataline[1]);
-		      pScanline[3] = DIV255B8(s * pDataline[0]);
-#endif
-			}
-		  }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-    else
-    {
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          if ((s = pDataline[3]) != 0)       /* any opacity at all ? */
-          {                            /* fully opaque ? */
-            if (s == 255)
-            {                          /* then simply copy the values */
-              pScanline[0] = 255;
-              pScanline[1] = pDataline[2];
-              pScanline[2] = pDataline[1];
-              pScanline[3] = pDataline[0];
-            }
-            else
-            {                          /* now blend (premultiplied) */
-			  t = 255 - s;
-              pScanline[0] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[0])));
-#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
-              {
-                int i;
-                for (i=2; i >= 0; i--)
-                {
-                  pScanline[i+1] = DIV255B8(s * pDataline[2-i] + t *
-                     pScanline[i+1]);
-                }
-              }
-#else
-			  pScanline[1] = DIV255B8(s * pDataline[2] + t * pScanline[1]);
-              pScanline[2] = DIV255B8(s * pDataline[1] + t * pScanline[2]);
-              pScanline[3] = DIV255B8(s * pDataline[0] + t * pScanline[3]);
-#endif
-            }
-          }
-
-          pScanline += (pData->iColinc << 2);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_ABGR8_PM, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_NO_16BIT_SUPPORT */
-#endif /* MNG_SKIPCANVAS_ABGR8_PM */
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCANVAS_BGR565
-#ifndef MNG_NO_16BIT_SUPPORT
-#ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
-mng_retcode mng_display_bgr565 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint16 iA16;
-  mng_uint16 iFGr16, iFGg16, iFGb16;
-  mng_uint16 iBGr16, iBGg16, iBGb16;
-  mng_uint8  iA8;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGR565, MNG_LC_START);
-#endif
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-    if (pData->bIsRGBA16)              /* adjust source row starting-point */
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
-    else
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* scale down by dropping the LSB */
-          *(pScanline+1) = (mng_uint8)( ( (*(pDataline))&0xF8 ) | (   (*(pDataline+2)>>5)       ) );
-          *pScanline     = (mng_uint8)( ( (*(pDataline+4)) >>3) | (   (*(pDataline+2)&0xFC) << 3) );
-
-          pScanline += (pData->iColinc * 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values */
-          *(pScanline+1) = (mng_uint8)( ( (*(pDataline))&0xF8 )  |  ( (*(pDataline+1)>>5   )     ) );
-          *pScanline     = (mng_uint8)( (  *(pDataline+2) >>3 )  |  ( (*(pDataline+1)&0xFC ) << 3) );
-
-
-          pScanline += (pData->iColinc * 2);
-          pDataline += 4;
-        }
-      }
-    }
-    else
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iA16 = mng_get_uint16 (pDataline+6);
-
-          if (iA16)                    /* any opacity at all ? */
-          {
-            if (iA16 == 0xFFFF)        /* fully opaque ? */
-            {                          /* scale down by dropping the LSB */
-              *(pScanline+1) = (mng_uint8)( (*(pDataline))&0xF8 )  |  (mng_uint8)( (*(pDataline+2)>>5  )     );
-              *pScanline     = (mng_uint8)( (*(pDataline+4)) >>3)  |  (mng_uint8)( (*(pDataline+2)&0xFC) << 3);
-            }
-            else
-            {                          /* get the proper values */
-              iFGr16 = mng_get_uint16 (pDataline  );
-              iFGg16 = mng_get_uint16 (pDataline+2);
-              iFGb16 = mng_get_uint16 (pDataline+4);
-                                       /* scale background up */
-
-              iBGb16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
-              iBGg16 = (mng_uint16)( (*(pScanline+1) << 5)  |  (((*(pScanline  )) & 0xE0) >>3 ) );
-              iBGr16 = (mng_uint16)( (*(pScanline  )) << 3   );
-
-              iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
-              iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-              iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
-                                       /* now compose */
-              MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16);
-              MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
-              MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16);
-                                       /* and return the composed values */
-              *(pScanline+1) = (mng_uint8) ( ( (iFGr16 >> 8)&0xF8 )  |  ( (mng_uint8)(iFGg16>>8) >> 5)      );
-              *pScanline     = (mng_uint8) ( ( (iFGb16>>11)       )  |  (((mng_uint8)(iFGg16>>8)&0xFC) << 3) );
-            }
-          }
-
-          pScanline += (pData->iColinc * 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iA8 = *(pDataline+3);        /* get alpha value */
-
-          if (iA8)                     /* any opacity at all ? */
-          {
-            if (iA8 == 0xFF)           /* fully opaque ? */
-            {                          /* then simply copy the values */
-              *(pScanline+1) = (mng_uint8)( (  (*(pDataline)) &0xF8 )  |   (*(pDataline+1) >>5 )       );
-              *pScanline     = (mng_uint8)( ( ((*(pDataline+2))>>3) )  |  ((*(pDataline+1)&0xFC) << 3) );
-            }
-            else
-            {                          /* do alpha composing */
-              mng_uint8 iRed, iGreen, iBlue;
-
-              iRed   = (mng_uint8) (  *(pScanline+1) & 0xF8 );
-              iGreen = (mng_uint8) ( (*(pScanline+1) << 5)  |  ( ((*pScanline) & 0xE0)>>3 ) );
-              iBlue  = (mng_uint8) ( (*pScanline << 3) );
-
-              MNG_COMPOSE8 (iRed,     *pDataline,     iA8, iRed    );
-              MNG_COMPOSE8 (iGreen,   *(pDataline+1), iA8, iGreen  );
-              MNG_COMPOSE8 (iBlue,    *(pDataline+2), iA8, iBlue   );
-
-              *(pScanline+1) = (mng_uint8) ( ( iRed  & 0xF8 )  |   (iGreen>>5) );
-              *pScanline     = (mng_uint8) ( ( iBlue >>  3  )  | ( (iGreen & 0xFC) << 3) );
-            }
-          }
-
-          pScanline += (pData->iColinc * 2);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGR565, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
-mng_retcode mng_display_bgr565 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint16 iA16;
-  mng_uint16 iFGr16, iFGg16, iFGb16;
-  mng_uint16 iBGr16, iBGg16, iBGb16;
-  mng_uint8  iA8;
-  mng_uint8  iBps;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGR565, MNG_LC_START);
-#endif
-
-  iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-    /* adjust source row starting-point */
-    pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* scale down by dropping the LSB */
-          *(pScanline+1) = (mng_uint8)( ( (*(pDataline))&0xF8 ) |
-           (   (*(pDataline+iBps)>>5)       ) );
-          *pScanline     = (mng_uint8)( ( (*(pDataline+2*iBps)) >>3) |
-           (   (*(pDataline+iBps)&0xFC) << 3) );
-
-          pScanline += (pData->iColinc * 2);
-          pDataline += 4*iBps;
-        }
-    }
-    else
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iA16 = mng_get_uint16 (pDataline+6);
-
-          if (iA16)                    /* any opacity at all ? */
-          {
-            if (iA16 == 0xFFFF)        /* fully opaque ? */
-            {                          /* scale down by dropping the LSB */
-              *(pScanline+1) = (mng_uint8)( (*(pDataline))&0xF8 )  |  (mng_uint8)( (*(pDataline+2)>>5  )     );
-              *pScanline     = (mng_uint8)( (*(pDataline+4)) >>3)  |  (mng_uint8)( (*(pDataline+2)&0xFC) << 3);
-            }
-            else
-            {                          /* get the proper values */
-              iFGr16 = mng_get_uint16 (pDataline  );
-              iFGg16 = mng_get_uint16 (pDataline+2);
-              iFGb16 = mng_get_uint16 (pDataline+4);
-                                       /* scale background up */
-
-              iBGb16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
-              iBGg16 = (mng_uint16)( (*(pScanline+1) << 5)  |  (((*(pScanline  )) & 0xE0) >>3 ) );
-              iBGr16 = (mng_uint16)( (*(pScanline  )) << 3   );
-
-              iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
-              iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-              iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
-                                       /* now compose */
-              MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16);
-              MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
-              MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16);
-                                       /* and return the composed values */
-              *(pScanline+1) = (mng_uint8) ( ( (iFGr16 >> 8)&0xF8 )  |  ( (mng_uint8)(iFGg16>>8) >> 5)      );
-              *pScanline     = (mng_uint8) ( ( (iFGb16>>11)       )  |  (((mng_uint8)(iFGg16>>8)&0xFC) << 3) );
-            }
-          }
-
-          pScanline += (pData->iColinc * 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iA8 = *(pDataline+3);        /* get alpha value */
-
-          if (iA8)                     /* any opacity at all ? */
-          {
-            if (iA8 == 0xFF)           /* fully opaque ? */
-            {                          /* then simply copy the values */
-              *(pScanline+1) = (mng_uint8)( (  (*(pDataline)) &0xF8 )  |   (*(pDataline+1) >>5 )       );
-              *pScanline     = (mng_uint8)( ( ((*(pDataline+2))>>3) )  |  ((*(pDataline+1)&0xFC) << 3) );
-            }
-            else
-            {                          /* do alpha composing */
-              mng_uint8 iRed, iGreen, iBlue;
-
-              iRed   = (mng_uint8) (  *(pScanline+1) & 0xF8 );
-              iGreen = (mng_uint8) ( (*(pScanline+1) << 5)  |  ( ((*pScanline) & 0xE0)>>3 ) );
-              iBlue  = (mng_uint8) ( (*pScanline << 3) );
-
-              MNG_COMPOSE8 (iRed,     *pDataline,     iA8, iRed    );
-              MNG_COMPOSE8 (iGreen,   *(pDataline+1), iA8, iGreen  );
-              MNG_COMPOSE8 (iBlue,    *(pDataline+2), iA8, iBlue   );
-
-              *(pScanline+1) = (mng_uint8) ( ( iRed  & 0xF8 )  |   (iGreen>>5) );
-              *pScanline     = (mng_uint8) ( ( iBlue >>  3  )  | ( (iGreen & 0xFC) << 3) );
-            }
-          }
-
-          pScanline += (pData->iColinc * 2);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGR565, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
-#else /* MNG_NO_16BIT_SUPPORT */
-mng_retcode mng_display_bgr565 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint8  iA8;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGR565, MNG_LC_START);
-#endif
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values */
-          *(pScanline+1) = (mng_uint8)( ( (*(pDataline))&0xF8 )  |  ( (*(pDataline+1)>>5   )     ) );
-          *pScanline     = (mng_uint8)( (  *(pDataline+2) >>3 )  |  ( (*(pDataline+1)&0xFC ) << 3) );
-
-
-          pScanline += (pData->iColinc * 2);
-          pDataline += 4;
-        }
-      }
-    }
-    else
-    {
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iA8 = *(pDataline+3);        /* get alpha value */
-
-          if (iA8)                     /* any opacity at all ? */
-          {
-            if (iA8 == 0xFF)           /* fully opaque ? */
-            {                          /* then simply copy the values */
-              *(pScanline+1) = (mng_uint8)( (  (*(pDataline)) &0xF8 )  |   (*(pDataline+1) >>5 )       );
-              *pScanline     = (mng_uint8)( ( ((*(pDataline+2))>>3) )  |  ((*(pDataline+1)&0xFC) << 3) );
-            }
-            else
-            {                          /* do alpha composing */
-              mng_uint8 iRed, iGreen, iBlue;
-
-              iRed   = (mng_uint8) (  *(pScanline+1) & 0xF8 );
-              iGreen = (mng_uint8) ( (*(pScanline+1) << 5)  |  ( ((*pScanline) & 0xE0)>>3 ) );
-              iBlue  = (mng_uint8) ( (*pScanline << 3) );
-
-              MNG_COMPOSE8 (iRed,     *pDataline,     iA8, iRed    );
-              MNG_COMPOSE8 (iGreen,   *(pDataline+1), iA8, iGreen  );
-              MNG_COMPOSE8 (iBlue,    *(pDataline+2), iA8, iBlue   );
-
-              *(pScanline+1) = (mng_uint8) ( ( iRed  & 0xF8 )  |   (iGreen>>5) );
-              *pScanline     = (mng_uint8) ( ( iBlue >>  3  )  | ( (iGreen & 0xFC) << 3) );
-            }
-          }
-
-          pScanline += (pData->iColinc * 2);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGR565, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_NO_16BIT_SUPPORT */
-#endif /* MNG_SKIPCANVAS_BGR565 */
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCANVAS_RGB565
-#ifndef MNG_NO_16BIT_SUPPORT
-#ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
-mng_retcode mng_display_rgb565 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint16 iA16;
-  mng_uint16 iFGr16, iFGg16, iFGb16;
-  mng_uint16 iBGr16, iBGg16, iBGb16;
-  mng_uint8  iA8;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGB565, MNG_LC_START);
-#endif
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-    if (pData->bIsRGBA16)              /* adjust source row starting-point */
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
-    else
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* scale down by dropping the LSB */
-          *(pScanline+1) = (mng_uint8)( ( ( *(pDataline+4)) & 0xF8)  |   (*(pDataline+2) >> 5  )       );
-          *pScanline     = (mng_uint8)( ( ( *(pDataline  )) >> 3  )  |  ((*(pDataline+2) & 0xFC) << 3) );
-
-          pScanline += (pData->iColinc * 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values */
-          *(pScanline+1) = (mng_uint8)( ( (*(pDataline+2)) & 0xF8)  |   (*(pDataline+1) >> 5        ) );
-          *pScanline     = (mng_uint8)( (  *(pDataline  )  >> 3  )  |  ((*(pDataline+1) & 0xFC) << 3) );
-
-          pScanline += (pData->iColinc * 2);
-          pDataline += 4;
-        }
-      }
-    }
-    else
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iA16 = mng_get_uint16 (pDataline+6);
-
-          if (iA16)                    /* any opacity at all ? */
-          {
-            if (iA16 == 0xFFFF)        /* fully opaque ? */
-            {                          /* scale down by dropping the LSB */
-              *(pScanline+1) = (mng_uint8)( ( (*(pDataline+4)) & 0xF8)  |   (*(pDataline+2)>>5) );
-              *pScanline     = (mng_uint8)( ( (*(pDataline  )) >> 3  )  |  ((*(pDataline+2)&0xFC) << 3) );
-            }
-            else
-            {                          /* get the proper values */
-              iFGr16 = mng_get_uint16 (pDataline  );
-              iFGg16 = mng_get_uint16 (pDataline+2);
-              iFGb16 = mng_get_uint16 (pDataline+4);
-
-			                           /* scale background up */
-              iBGr16 = (mng_uint8)(  *(pScanline+1) & 0xF8 );
-              iBGg16 = (mng_uint8)( (*(pScanline+1) << 5)  |  ( ((*pScanline) & 0xE0) >> 3 ) );
-              iBGb16 = (mng_uint8)(  *(pScanline  ) << 3   );
-
-              iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
-              iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-              iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
-                                       /* now compose */
-              MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16);
-              MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
-              MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16);
-                                       /* and return the composed values */
-              *(pScanline+1) = (mng_uint8)( (mng_uint8)((iFGb16 >> 8) &0xF8) |   (   (mng_uint8)(iFGg16 >> 8) >> 5  )        );
-              *pScanline     = (mng_uint8)( (mng_uint8) (iFGr16 >>11)        |   ( ( (mng_uint8)(iFGg16 >> 8) & 0xFC) << 3)  );
-            }
-          }
-
-          pScanline += (pData->iColinc * 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iA8 = *(pDataline+3);        /* get alpha value */
-
-          if (iA8)                     /* any opacity at all ? */
-          {
-            if (iA8 == 0xFF)           /* fully opaque ? */
-            {                          /* then simply copy the values */
-              *(pScanline+1) = (mng_uint8)( ( (*(pDataline+2)) & 0xF8)  |  (  *(pDataline+1) >> 5         ) );
-              *pScanline     = (mng_uint8)( ( (*(pDataline  )) >> 3  )  |  ( (*(pDataline+1) & 0xFC) << 3 ) );
-            }
-            else
-            {                          /* do alpha composing */
-              mng_uint8 iRed, iGreen, iBlue;
-
-              iRed   = (mng_uint8)(   *(pScanline+1) & 0xF8);
-              iGreen = (mng_uint8)( ( *(pScanline+1) << 5  )  |  ( ( (*pScanline)&0xE0)>>3 ) );
-              iBlue  = (mng_uint8)(   *(pScanline  ) << 3 );
-
-              MNG_COMPOSE8 (iRed,     *(pDataline+2), iA8, iRed    );
-              MNG_COMPOSE8 (iGreen,   *(pDataline+1), iA8, iGreen  );
-              MNG_COMPOSE8 (iBlue,    *(pDataline+0), iA8, iBlue   );
-
-              *(pScanline+1) = (mng_uint8)( ( iRed & 0xF8)  |  (  iGreen >> 5        ) );
-              *pScanline     = (mng_uint8)( (iBlue >> 3  )  |  ( (iGreen & 0xFC) << 3) );
-            }
-          }
-
-          pScanline += (pData->iColinc * 2);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGB565, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
-mng_retcode mng_display_rgb565 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint16 iA16;
-  mng_uint16 iFGr16, iFGg16, iFGb16;
-  mng_uint16 iBGr16, iBGg16, iBGb16;
-  mng_uint8  iA8;
-  mng_uint8  iBps;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGB565, MNG_LC_START);
-#endif
-
-  iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-    /* adjust source row starting-point */
-    pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* scale down by dropping the LSB */
-          *(pScanline+1) = (mng_uint8)( ( ( *(pDataline+2*iBps)) & 0xF8)  |
-              (*(pDataline+iBps) >> 5  )       );
-          *pScanline     = (mng_uint8)( ( ( *(pDataline  )) >> 3  )  |
-             ((*(pDataline+iBps) & 0xFC) << 3) );
-
-          pScanline += (pData->iColinc * 2);
-          pDataline += 4*iBps;
-        }
-    }
-    else
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iA16 = mng_get_uint16 (pDataline+6);
-
-          if (iA16)                    /* any opacity at all ? */
-          {
-            if (iA16 == 0xFFFF)        /* fully opaque ? */
-            {                          /* scale down by dropping the LSB */
-              *(pScanline+1) = (mng_uint8)( ( (*(pDataline+4)) & 0xF8)  |   (*(pDataline+2)>>5) );
-              *pScanline     = (mng_uint8)( ( (*(pDataline  )) >> 3  )  |  ((*(pDataline+2)&0xFC) << 3) );
-            }
-            else
-            {                          /* get the proper values */
-              iFGr16 = mng_get_uint16 (pDataline  );
-              iFGg16 = mng_get_uint16 (pDataline+2);
-              iFGb16 = mng_get_uint16 (pDataline+4);
-
-			                           /* scale background up */
-              iBGr16 = (mng_uint8)(  *(pScanline+1) & 0xF8 );
-              iBGg16 = (mng_uint8)( (*(pScanline+1) << 5)  |  ( ((*pScanline) & 0xE0) >> 3 ) );
-              iBGb16 = (mng_uint8)(  *(pScanline  ) << 3   );
-
-              iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
-              iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-              iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
-                                       /* now compose */
-              MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16);
-              MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
-              MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16);
-                                       /* and return the composed values */
-              *(pScanline+1) = (mng_uint8)( (mng_uint8)((iFGb16 >> 8) &0xF8) |   (   (mng_uint8)(iFGg16 >> 8) >> 5  )        );
-              *pScanline     = (mng_uint8)( (mng_uint8) (iFGr16 >>11)        |   ( ( (mng_uint8)(iFGg16 >> 8) & 0xFC) << 3)  );
-            }
-          }
-
-          pScanline += (pData->iColinc * 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iA8 = *(pDataline+3);        /* get alpha value */
-
-          if (iA8)                     /* any opacity at all ? */
-          {
-            if (iA8 == 0xFF)           /* fully opaque ? */
-            {                          /* then simply copy the values */
-              *(pScanline+1) = (mng_uint8)( ( (*(pDataline+2)) & 0xF8)  |  (  *(pDataline+1) >> 5         ) );
-              *pScanline     = (mng_uint8)( ( (*(pDataline  )) >> 3  )  |  ( (*(pDataline+1) & 0xFC) << 3 ) );
-            }
-            else
-            {                          /* do alpha composing */
-              mng_uint8 iRed, iGreen, iBlue;
-
-              iRed   = (mng_uint8)(   *(pScanline+1) & 0xF8);
-              iGreen = (mng_uint8)( ( *(pScanline+1) << 5  )  |  ( ( (*pScanline)&0xE0)>>3 ) );
-              iBlue  = (mng_uint8)(   *(pScanline  ) << 3 );
-
-              MNG_COMPOSE8 (iRed,     *(pDataline+2), iA8, iRed    );
-              MNG_COMPOSE8 (iGreen,   *(pDataline+1), iA8, iGreen  );
-              MNG_COMPOSE8 (iBlue,    *(pDataline+0), iA8, iBlue   );
-
-              *(pScanline+1) = (mng_uint8)( ( iRed & 0xF8)  |  (  iGreen >> 5        ) );
-              *pScanline     = (mng_uint8)( (iBlue >> 3  )  |  ( (iGreen & 0xFC) << 3) );
-            }
-          }
-
-          pScanline += (pData->iColinc * 2);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGB565, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
-#else /* MNG_NO_16BIT_SUPPORT */
-mng_retcode mng_display_rgb565 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint8  iA8;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGB565, MNG_LC_START);
-#endif
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values */
-          *(pScanline+1) = (mng_uint8)( ( (*(pDataline+2)) & 0xF8)  |   (*(pDataline+1) >> 5        ) );
-          *pScanline     = (mng_uint8)( (  *(pDataline  )  >> 3  )  |  ((*(pDataline+1) & 0xFC) << 3) );
-
-          pScanline += (pData->iColinc * 2);
-          pDataline += 4;
-        }
-      }
-    }
-    else
-    {
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iA8 = *(pDataline+3);        /* get alpha value */
-
-          if (iA8)                     /* any opacity at all ? */
-          {
-            if (iA8 == 0xFF)           /* fully opaque ? */
-            {                          /* then simply copy the values */
-              *(pScanline+1) = (mng_uint8)( ( (*(pDataline+2)) & 0xF8)  |  (  *(pDataline+1) >> 5         ) );
-              *pScanline     = (mng_uint8)( ( (*(pDataline  )) >> 3  )  |  ( (*(pDataline+1) & 0xFC) << 3 ) );
-            }
-            else
-            {                          /* do alpha composing */
-              mng_uint8 iRed, iGreen, iBlue;
-
-              iRed   = (mng_uint8)(   *(pScanline+1) & 0xF8);
-              iGreen = (mng_uint8)( ( *(pScanline+1) << 5  )  |  ( ( (*pScanline)&0xE0)>>3 ) );
-              iBlue  = (mng_uint8)(   *(pScanline  ) << 3 );
-
-              MNG_COMPOSE8 (iRed,     *(pDataline+2), iA8, iRed    );
-              MNG_COMPOSE8 (iGreen,   *(pDataline+1), iA8, iGreen  );
-              MNG_COMPOSE8 (iBlue,    *(pDataline+0), iA8, iBlue   );
-
-              *(pScanline+1) = (mng_uint8)( ( iRed & 0xF8)  |  (  iGreen >> 5        ) );
-              *pScanline     = (mng_uint8)( (iBlue >> 3  )  |  ( (iGreen & 0xFC) << 3) );
-            }
-          }
-
-          pScanline += (pData->iColinc * 2);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGB565, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_NO_16BIT_SUPPORT */
-#endif /* MNG_SKIPCANVAS_RGB565 */
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCANVAS_BGRA565
-#ifndef MNG_NO_16BIT_SUPPORT
-#ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
-mng_retcode mng_display_bgra565 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint8  iFGa8, iBGa8, iCa8;
-  mng_uint16 iFGa16, iBGa16, iCa16;
-  mng_uint16 iFGr16, iFGg16, iFGb16;
-  mng_uint16 iBGr16, iBGg16, iBGb16;
-  mng_uint16 iCr16, iCg16, iCb16;
-  mng_uint8  iCr8, iCg8, iCb8;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA565, MNG_LC_START);
-#endif
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl * 3);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-    if (pData->bIsRGBA16)              /* adjust source row starting-point */
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
-    else
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* scale down by dropping the LSB */
-          *(pScanline+1) = (mng_uint8)( ( (*(pDataline))&0xF8 ) | (   (*(pDataline+2)>>5)       ) );
-          *pScanline     = (mng_uint8)( ( (*(pDataline+4)) >>3) | (   (*(pDataline+2)&0xFC) << 3) );
-          *(pScanline+2) = *(pDataline+6);
-
-          pScanline += (pData->iColinc * 3);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values */
-          *(pScanline+1) = (mng_uint8)( ( (*(pDataline))&0xF8 )  |  ( (*(pDataline+1)>>5   )     ) );
-          *pScanline     = (mng_uint8)( (  *(pDataline+2) >>3 )  |  ( (*(pDataline+1)&0xFC ) << 3) );
-          *(pScanline+2) = *(pDataline+3);
-
-          pScanline += (pData->iColinc * 3);
-          pDataline += 4;
-        }
-      }
-    }
-    else
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* get alpha values */
-          iFGa16 = mng_get_uint16 (pDataline+6);
-          iBGa16 = (mng_uint16)(*(pScanline+2));
-          iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
-
-          if (iFGa16)                  /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
-            {                          /* plain copy it */
-              *(pScanline+1) = (mng_uint8)( (*(pDataline))&0xF8 )  |  (mng_uint8)( (*(pDataline+2)>>5  )     );
-              *pScanline     = (mng_uint8)( (*(pDataline+4)) >>3)  |  (mng_uint8)( (*(pDataline+2)&0xFC) << 3);
-			  *(pScanline+2) = *(pDataline+6);
-            }
-            else
-            {
-              if (iBGa16 == 0xFFFF)    /* background fully opaque ? */
-              {                        /* get the proper values */
-                iFGr16 = mng_get_uint16 (pDataline  );
-                iFGg16 = mng_get_uint16 (pDataline+2);
-                iFGb16 = mng_get_uint16 (pDataline+4);
-                                       /* scale background up */
-                iBGb16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
-                iBGg16 = (mng_uint16)( (*(pScanline+1) << 5)  |  (((*(pScanline  )) & 0xE0) >>3 ) );
-                iBGr16 = (mng_uint16)( (*(pScanline  )) << 3   );
-
-				iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
-                iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-                iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
-
-                                       /* now compose */
-                MNG_COMPOSE16(iFGr16, iFGr16, iFGa16, iBGr16);
-                MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
-                MNG_COMPOSE16(iFGb16, iFGb16, iFGa16, iBGb16);
-                                       /* and return the composed values */
-                *(pScanline+1) = (mng_uint8) ( ( (iFGr16 >> 8)&0xF8 )  |  ( (mng_uint8)(iFGg16>>8) >> 5)      );
-                *pScanline     = (mng_uint8) ( ( (iFGb16>>11)       )  |  (((mng_uint8)(iFGg16>>8)&0xFC) << 3) );
-              }
-              else
-              {                        /* scale background up */
-                iBGb16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
-                iBGg16 = (mng_uint16)( (*(pScanline+1) << 5)  |  (((*(pScanline  )) & 0xE0) >>3 ) );
-                iBGr16 = (mng_uint16)( (*(pScanline  )) << 3   );
-
-				iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
-                iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-                iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
-                                       /* let's blend */
-                MNG_BLEND16 (mng_get_uint16 (pDataline  ),
-                             mng_get_uint16 (pDataline+2),
-                             mng_get_uint16 (pDataline+4), iFGa16,
-                             iBGr16, iBGg16, iBGb16, iBGa16,
-                             iCr16,  iCg16,  iCb16,  iCa16);
-                                       /* and return the composed values */
-                *(pScanline+1) = (mng_uint8) ( ( (iCr16 >>  8) & 0xF8 )  |  ( (mng_uint8)(iCg16 >> 8) >> 5  )       );
-                *pScanline     = (mng_uint8) ( ( (iCb16 >> 11)        )  |  (((mng_uint8)(iCg16 >> 8) & 0xFC) << 3) );
-                *(pScanline+2) = (mng_uint8)(iCa16 >> 8);
-              }
-            }
-          }
-
-          pScanline += (pData->iColinc * 3);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iFGa8 = *(pDataline+3);      /* get alpha values */
-          iBGa8 = *(pScanline+2);
-
-          if (iFGa8)                   /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if ((iFGa8 == 0xFF) || (iBGa8 == 0))
-            {                          /* then simply copy the values */
-              *(pScanline+1) = (mng_uint8)( (  (*(pDataline)) &0xF8 )  |   (*(pDataline+1) >>5 )       );
-              *pScanline     = (mng_uint8)( ( ((*(pDataline+2))>>3) )  |  ((*(pDataline+1)&0xFC) << 3) );
-              *(pScanline+2) = *(pDataline+3);
-            }
-            else
-            {
-              mng_uint8 iRed, iGreen, iBlue;
-
-              iRed   = (mng_uint8) (  *(pScanline+1) & 0xF8 );
-              iGreen = (mng_uint8) ( (*(pScanline+1) << 5)  |  ( ((*pScanline) & 0xE0)>>3 ) );
-              iBlue  = (mng_uint8) ( (*pScanline << 3) );
-
-              if (iBGa8 == 0xFF)       /* background fully opaque ? */
-              {                        /* do alpha composing */
-                MNG_COMPOSE8 (iRed,   *pDataline,     iFGa8, iRed   );
-                MNG_COMPOSE8 (iGreen, *(pDataline+1), iFGa8, iGreen );
-                MNG_COMPOSE8 (iBlue,  *(pDataline+2), iFGa8, iBlue  );
-                                       /* alpha remains fully opaque !!! */
-                *(pScanline+1) = (mng_uint8) ( ( iRed  & 0xF8 )  |   (iGreen>>5) );
-                *pScanline     = (mng_uint8) ( ( iBlue >>  3  )  | ( (iGreen & 0xFC) << 3) );
-              }
-              else
-              {                        /* now blend */
-                MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
-                            iRed      , iGreen        , iBlue         , iBGa8,
-                            iCr8, iCg8, iCb8, iCa8);
-                                       /* and return the composed values */
-
-
-                *pScanline     = (mng_uint8) ( ( iCb8 >>  3  )  | ( (iCg8 & 0xFC) << 3) );
-                *(pScanline+1) = (mng_uint8) ( ( iCr8  & 0xF8 )  |   (iCg8>>5) );
-				*(pScanline+2) = (mng_uint8) iCa8;
-              }
-            }
-          }
-
-          pScanline += (pData->iColinc *3);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA565, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
-mng_retcode mng_display_bgra565 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint8  iFGa8, iBGa8, iCa8;
-  mng_uint16 iFGa16, iBGa16, iCa16;
-  mng_uint16 iFGr16, iFGg16, iFGb16;
-  mng_uint16 iBGr16, iBGg16, iBGb16;
-  mng_uint16 iCr16, iCg16, iCb16;
-  mng_uint8  iCr8, iCg8, iCb8;
-  mng_uint8  iBps;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA565, MNG_LC_START);
-#endif
-
-  iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl * 3);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-    /* adjust source row starting-point */
-    pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* scale down by dropping the LSB */
-          *(pScanline+1) = (mng_uint8)( ( (*(pDataline))&0xF8 ) |
-              (   (*(pDataline+iBps)>>5)       ) );
-          *pScanline     = (mng_uint8)( ( (*(pDataline+2*iBps)) >>3) |
-              (   (*(pDataline+iBps)&0xFC) << 3) );
-          *(pScanline+2) = *(pDataline+3*iBps);
-
-          pScanline += (pData->iColinc * 3);
-          pDataline += 4*iBps;
-        }
-    }
-    else
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* get alpha values */
-          iFGa16 = mng_get_uint16 (pDataline+6);
-          iBGa16 = (mng_uint16)(*(pScanline+2));
-          iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
-
-          if (iFGa16)                  /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
-            {                          /* plain copy it */
-              *(pScanline+1) = (mng_uint8)( (*(pDataline))&0xF8 )  |  (mng_uint8)( (*(pDataline+2)>>5  )     );
-              *pScanline     = (mng_uint8)( (*(pDataline+4)) >>3)  |  (mng_uint8)( (*(pDataline+2)&0xFC) << 3);
-			  *(pScanline+2) = *(pDataline+6);
-            }
-            else
-            {
-              if (iBGa16 == 0xFFFF)    /* background fully opaque ? */
-              {                        /* get the proper values */
-                iFGr16 = mng_get_uint16 (pDataline  );
-                iFGg16 = mng_get_uint16 (pDataline+2);
-                iFGb16 = mng_get_uint16 (pDataline+4);
-                                       /* scale background up */
-                iBGb16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
-                iBGg16 = (mng_uint16)( (*(pScanline+1) << 5)  |  (((*(pScanline  )) & 0xE0) >>3 ) );
-                iBGr16 = (mng_uint16)( (*(pScanline  )) << 3   );
-
-				iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
-                iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-                iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
-
-                                       /* now compose */
-                MNG_COMPOSE16(iFGr16, iFGr16, iFGa16, iBGr16);
-                MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
-                MNG_COMPOSE16(iFGb16, iFGb16, iFGa16, iBGb16);
-                                       /* and return the composed values */
-                *(pScanline+1) = (mng_uint8) ( ( (iFGr16 >> 8)&0xF8 )  |  ( (mng_uint8)(iFGg16>>8) >> 5)      );
-                *pScanline     = (mng_uint8) ( ( (iFGb16>>11)       )  |  (((mng_uint8)(iFGg16>>8)&0xFC) << 3) );
-              }
-              else
-              {                        /* scale background up */
-                iBGb16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
-                iBGg16 = (mng_uint16)( (*(pScanline+1) << 5)  |  (((*(pScanline  )) & 0xE0) >>3 ) );
-                iBGr16 = (mng_uint16)( (*(pScanline  )) << 3   );
-
-				iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
-                iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-                iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
-                                       /* let's blend */
-                MNG_BLEND16 (mng_get_uint16 (pDataline  ),
-                             mng_get_uint16 (pDataline+2),
-                             mng_get_uint16 (pDataline+4), iFGa16,
-                             iBGr16, iBGg16, iBGb16, iBGa16,
-                             iCr16,  iCg16,  iCb16,  iCa16);
-                                       /* and return the composed values */
-                *(pScanline+1) = (mng_uint8) ( ( (iCr16 >>  8) & 0xF8 )  |  ( (mng_uint8)(iCg16 >> 8) >> 5  )       );
-                *pScanline     = (mng_uint8) ( ( (iCb16 >> 11)        )  |  (((mng_uint8)(iCg16 >> 8) & 0xFC) << 3) );
-                *(pScanline+2) = (mng_uint8)(iCa16 >> 8);
-              }
-            }
-          }
-
-          pScanline += (pData->iColinc * 3);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iFGa8 = *(pDataline+3);      /* get alpha values */
-          iBGa8 = *(pScanline+2);
-
-          if (iFGa8)                   /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if ((iFGa8 == 0xFF) || (iBGa8 == 0))
-            {                          /* then simply copy the values */
-              *(pScanline+1) = (mng_uint8)( (  (*(pDataline)) &0xF8 )  |   (*(pDataline+1) >>5 )       );
-              *pScanline     = (mng_uint8)( ( ((*(pDataline+2))>>3) )  |  ((*(pDataline+1)&0xFC) << 3) );
-              *(pScanline+2) = *(pDataline+3);
-            }
-            else
-            {
-              mng_uint8 iRed, iGreen, iBlue;
-
-              iRed   = (mng_uint8) (  *(pScanline+1) & 0xF8 );
-              iGreen = (mng_uint8) ( (*(pScanline+1) << 5)  |  ( ((*pScanline) & 0xE0)>>3 ) );
-              iBlue  = (mng_uint8) ( (*pScanline << 3) );
-
-              if (iBGa8 == 0xFF)       /* background fully opaque ? */
-              {                        /* do alpha composing */
-                MNG_COMPOSE8 (iRed,   *pDataline,     iFGa8, iRed   );
-                MNG_COMPOSE8 (iGreen, *(pDataline+1), iFGa8, iGreen );
-                MNG_COMPOSE8 (iBlue,  *(pDataline+2), iFGa8, iBlue  );
-                                       /* alpha remains fully opaque !!! */
-                *(pScanline+1) = (mng_uint8) ( ( iRed  & 0xF8 )  |   (iGreen>>5) );
-                *pScanline     = (mng_uint8) ( ( iBlue >>  3  )  | ( (iGreen & 0xFC) << 3) );
-              }
-              else
-              {                        /* now blend */
-                MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
-                            iRed      , iGreen        , iBlue         , iBGa8,
-                            iCr8, iCg8, iCb8, iCa8);
-                                       /* and return the composed values */
-
-
-                *pScanline     = (mng_uint8) ( ( iCb8 >>  3  )  | ( (iCg8 & 0xFC) << 3) );
-                *(pScanline+1) = (mng_uint8) ( ( iCr8  & 0xF8 )  |   (iCg8>>5) );
-				*(pScanline+2) = (mng_uint8) iCa8;
-              }
-            }
-          }
-
-          pScanline += (pData->iColinc *3);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA565, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
-#else /* MNG_NO_16BIT_SUPPORT */
-mng_retcode mng_display_bgra565 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint8  iFGa8, iBGa8, iCa8;
-  mng_uint8  iCr8, iCg8, iCb8;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA565, MNG_LC_START);
-#endif
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl * 3);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values */
-          *(pScanline+1) = (mng_uint8)( ( (*(pDataline))&0xF8 )  |  ( (*(pDataline+1)>>5   )     ) );
-          *pScanline     = (mng_uint8)( (  *(pDataline+2) >>3 )  |  ( (*(pDataline+1)&0xFC ) << 3) );
-          *(pScanline+2) = *(pDataline+3);
-
-          pScanline += (pData->iColinc * 3);
-          pDataline += 4;
-        }
-      }
-    }
-    else
-    {
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iFGa8 = *(pDataline+3);      /* get alpha values */
-          iBGa8 = *(pScanline+2);
-
-          if (iFGa8)                   /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if ((iFGa8 == 0xFF) || (iBGa8 == 0))
-            {                          /* then simply copy the values */
-              *(pScanline+1) = (mng_uint8)( (  (*(pDataline)) &0xF8 )  |   (*(pDataline+1) >>5 )       );
-              *pScanline     = (mng_uint8)( ( ((*(pDataline+2))>>3) )  |  ((*(pDataline+1)&0xFC) << 3) );
-              *(pScanline+2) = *(pDataline+3);
-            }
-            else
-            {
-              mng_uint8 iRed, iGreen, iBlue;
-
-              iRed   = (mng_uint8) (  *(pScanline+1) & 0xF8 );
-              iGreen = (mng_uint8) ( (*(pScanline+1) << 5)  |  ( ((*pScanline) & 0xE0)>>3 ) );
-              iBlue  = (mng_uint8) ( (*pScanline << 3) );
-
-              if (iBGa8 == 0xFF)       /* background fully opaque ? */
-              {                        /* do alpha composing */
-                MNG_COMPOSE8 (iRed,   *pDataline,     iFGa8, iRed   );
-                MNG_COMPOSE8 (iGreen, *(pDataline+1), iFGa8, iGreen );
-                MNG_COMPOSE8 (iBlue,  *(pDataline+2), iFGa8, iBlue  );
-                                       /* alpha remains fully opaque !!! */
-                *(pScanline+1) = (mng_uint8) ( ( iRed  & 0xF8 )  |   (iGreen>>5) );
-                *pScanline     = (mng_uint8) ( ( iBlue >>  3  )  | ( (iGreen & 0xFC) << 3) );
-              }
-              else
-              {                        /* now blend */
-                MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
-                            iRed      , iGreen        , iBlue         , iBGa8,
-                            iCr8, iCg8, iCb8, iCa8);
-                                       /* and return the composed values */
-
-
-                *pScanline     = (mng_uint8) ( ( iCb8 >>  3  )  | ( (iCg8 & 0xFC) << 3) );
-                *(pScanline+1) = (mng_uint8) ( ( iCr8  & 0xF8 )  |   (iCg8>>5) );
-				*(pScanline+2) = (mng_uint8) iCa8;
-              }
-            }
-          }
-
-          pScanline += (pData->iColinc *3);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA565, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_NO_16BIT_SUPPORT */
-#endif /* MNG_SKIPCANVAS_BGRA565 */
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCANVAS_RGBA565
-#ifndef MNG_NO_16BIT_SUPPORT
-#ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
-mng_retcode mng_display_rgba565 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint8  iFGa8, iBGa8, iCa8;
-  mng_uint16 iFGa16, iBGa16, iCa16;
-  mng_uint16 iFGr16, iFGg16, iFGb16;
-  mng_uint16 iBGr16, iBGg16, iBGb16;
-  mng_uint16 iCr16, iCg16, iCb16;
-  mng_uint8  iCr8, iCg8, iCb8;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA565, MNG_LC_START);
-#endif
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl * 3);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-    if (pData->bIsRGBA16)              /* adjust source row starting-point */
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
-    else
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* scale down by dropping the LSB */
-          *(pScanline+1) = (mng_uint8)( ( (*(pDataline+4))&0xF8 ) | (   (*(pDataline+2)>>5)       ) );
-          *pScanline     = (mng_uint8)( ( (*(pDataline)) >>3) | (   (*(pDataline+2)&0xFC) << 3) );
-          *(pScanline+2) = *(pDataline+6);
-
-          pScanline += (pData->iColinc * 3);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values */
-          *(pScanline+1) = (mng_uint8)( ( (*(pDataline+2))&0xF8 )  |  ( (*(pDataline+1)>>5   )     ) );
-          *pScanline     = (mng_uint8)( (  *(pDataline) >>3 )  |  ( (*(pDataline+1)&0xFC ) << 3) );
-          *(pScanline+2) = *(pDataline+3);
-
-          pScanline += (pData->iColinc * 3);
-          pDataline += 4;
-        }
-      }
-    }
-    else
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* get alpha values */
-          iFGa16 = mng_get_uint16 (pDataline+6);
-          iBGa16 = (mng_uint16)(*(pScanline+2));
-          iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
-
-          if (iFGa16)                  /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
-            {                          /* plain copy it */
-              *(pScanline+1) = (mng_uint8)( (*(pDataline+4))&0xF8 )  |  (mng_uint8)( (*(pDataline+2)>>5  )     );
-              *pScanline     = (mng_uint8)( (*(pDataline)) >>3)  |  (mng_uint8)( (*(pDataline+2)&0xFC) << 3);
-			  *(pScanline+2) = *(pDataline+6);
-            }
-            else
-            {
-              if (iBGa16 == 0xFFFF)    /* background fully opaque ? */
-              {                        /* get the proper values */
-                iFGr16 = mng_get_uint16 (pDataline  );
-                iFGg16 = mng_get_uint16 (pDataline+2);
-                iFGb16 = mng_get_uint16 (pDataline+4);
-                                       /* scale background up */
-                iBGr16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
-                iBGg16 = (mng_uint16)( (*(pScanline+1) << 5)  |  (((*(pScanline  )) & 0xE0) >>3 ) );
-                iBGb16 = (mng_uint16)( (*(pScanline  )) << 3   );
-
-				iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
-                iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-                iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
-
-                                       /* now compose */
-                MNG_COMPOSE16(iFGr16, iFGr16, iFGa16, iBGr16);
-                MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
-                MNG_COMPOSE16(iFGb16, iFGb16, iFGa16, iBGb16);
-                                       /* and return the composed values */
-                *(pScanline+1) = (mng_uint8) ( ( (iFGb16 >> 8)&0xF8 )  |  ( (mng_uint8)(iFGg16>>8) >> 5)      );
-                *pScanline     = (mng_uint8) ( ( (iFGr16>>11)       )  |  (((mng_uint8)(iFGg16>>8)&0xFC) << 3) );
-              }
-              else
-              {                        /* scale background up */
-                iBGr16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
-                iBGg16 = (mng_uint16)( (*(pScanline+1) << 5)  |  (((*(pScanline  )) & 0xE0) >>3 ) );
-                iBGb16 = (mng_uint16)( (*(pScanline  )) << 3   );
-
-				iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
-                iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-                iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
-                                       /* let's blend */
-                MNG_BLEND16 (mng_get_uint16 (pDataline  ),
-                             mng_get_uint16 (pDataline+2),
-                             mng_get_uint16 (pDataline+4), iFGa16,
-                             iBGr16, iBGg16, iBGb16, iBGa16,
-                             iCr16,  iCg16,  iCb16,  iCa16);
-                                       /* and return the composed values */
-                *(pScanline+1) = (mng_uint8) ( ( (iCb16 >>  8) & 0xF8 )  |  ( (mng_uint8)(iCg16 >> 8) >> 5  )       );
-                *pScanline     = (mng_uint8) ( ( (iCr16 >> 11)        )  |  (((mng_uint8)(iCg16 >> 8) & 0xFC) << 3) );
-                *(pScanline+2) = (mng_uint8)(iCa16 >> 8);
-              }
-            }
-          }
-
-          pScanline += (pData->iColinc * 3);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iFGa8 = *(pDataline+3);      /* get alpha values */
-          iBGa8 = *(pScanline+2);
-
-          if (iFGa8)                   /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if ((iFGa8 == 0xFF) || (iBGa8 == 0))
-            {                          /* then simply copy the values */
-              *(pScanline+1) = (mng_uint8)( (  (*(pDataline+2)) &0xF8 )  |   (*(pDataline+1) >>5 )       );
-              *pScanline     = (mng_uint8)( ( ((*(pDataline))>>3) )  |  ((*(pDataline+1)&0xFC) << 3) );
-              *(pScanline+2) = *(pDataline+3);
-            }
-            else
-            {
-              mng_uint8 iRed, iGreen, iBlue;
-
-              iBlue   = (mng_uint8) (  *(pScanline+1) & 0xF8 );
-              iGreen = (mng_uint8) ( (*(pScanline+1) << 5)  |  ( ((*pScanline) & 0xE0)>>3 ) );
-              iRed  = (mng_uint8) ( (*pScanline << 3) );
-
-              if (iBGa8 == 0xFF)       /* background fully opaque ? */
-              {                        /* do alpha composing */
-                MNG_COMPOSE8 (iRed,   *pDataline,     iFGa8, iRed   );
-                MNG_COMPOSE8 (iGreen, *(pDataline+1), iFGa8, iGreen );
-                MNG_COMPOSE8 (iBlue,  *(pDataline+2), iFGa8, iBlue  );
-                                       /* alpha remains fully opaque !!! */
-                *(pScanline+1) = (mng_uint8) ( ( iBlue  & 0xF8 )  |   (iGreen>>5) );
-                *pScanline     = (mng_uint8) ( ( iRed >>  3  )  | ( (iGreen & 0xFC) << 3) );
-              }
-              else
-              {                        /* now blend */
-                MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
-                            iRed      , iGreen        , iBlue         , iBGa8,
-                            iCr8, iCg8, iCb8, iCa8);
-                                       /* and return the composed values */
-
-
-                *pScanline     = (mng_uint8) ( ( iCr8 >>  3  )  | ( (iCg8 & 0xFC) << 3) );
-                *(pScanline+1) = (mng_uint8) ( ( iCb8  & 0xF8 )  |   (iCg8>>5) );
-				*(pScanline+2) = (mng_uint8) iCa8;
-              }
-            }
-          }
-
-          pScanline += (pData->iColinc *3);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA565, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
-mng_retcode mng_display_rgba565 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint8  iFGa8, iBGa8, iCa8;
-  mng_uint16 iFGa16, iBGa16, iCa16;
-  mng_uint16 iFGr16, iFGg16, iFGb16;
-  mng_uint16 iBGr16, iBGg16, iBGb16;
-  mng_uint16 iCr16, iCg16, iCb16;
-  mng_uint8  iCr8, iCg8, iCb8;
-  mng_uint8  iBps;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA565, MNG_LC_START);
-#endif
-
-  iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl * 3);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-    /* adjust source row starting-point */
-    pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* scale down by dropping the LSB */
-          *(pScanline+1) = (mng_uint8)( ( (*(pDataline+2*iBps))&0xF8 ) |
-             (   (*(pDataline+iBps)>>5)       ) );
-          *pScanline     = (mng_uint8)( ( (*(pDataline)) >>3) |
-             (   (*(pDataline+iBps)&0xFC) << 3) );
-          *(pScanline+2) = *(pDataline+3*iBps);
-
-          pScanline += (pData->iColinc * 3);
-          pDataline += 4*iBps;
-        }
-    }
-    else
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* get alpha values */
-          iFGa16 = mng_get_uint16 (pDataline+6);
-          iBGa16 = (mng_uint16)(*(pScanline+2));
-          iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
-
-          if (iFGa16)                  /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
-            {                          /* plain copy it */
-              *(pScanline+1) = (mng_uint8)( (*(pDataline+4))&0xF8 )  |  (mng_uint8)( (*(pDataline+2)>>5  )     );
-              *pScanline     = (mng_uint8)( (*(pDataline)) >>3)  |  (mng_uint8)( (*(pDataline+2)&0xFC) << 3);
-			  *(pScanline+2) = *(pDataline+6);
-            }
-            else
-            {
-              if (iBGa16 == 0xFFFF)    /* background fully opaque ? */
-              {                        /* get the proper values */
-                iFGr16 = mng_get_uint16 (pDataline  );
-                iFGg16 = mng_get_uint16 (pDataline+2);
-                iFGb16 = mng_get_uint16 (pDataline+4);
-                                       /* scale background up */
-                iBGr16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
-                iBGg16 = (mng_uint16)( (*(pScanline+1) << 5)  |  (((*(pScanline  )) & 0xE0) >>3 ) );
-                iBGb16 = (mng_uint16)( (*(pScanline  )) << 3   );
-
-				iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
-                iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-                iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
-
-                                       /* now compose */
-                MNG_COMPOSE16(iFGr16, iFGr16, iFGa16, iBGr16);
-                MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
-                MNG_COMPOSE16(iFGb16, iFGb16, iFGa16, iBGb16);
-                                       /* and return the composed values */
-                *(pScanline+1) = (mng_uint8) ( ( (iFGb16 >> 8)&0xF8 )  |  ( (mng_uint8)(iFGg16>>8) >> 5)      );
-                *pScanline     = (mng_uint8) ( ( (iFGr16>>11)       )  |  (((mng_uint8)(iFGg16>>8)&0xFC) << 3) );
-              }
-              else
-              {                        /* scale background up */
-                iBGr16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
-                iBGg16 = (mng_uint16)( (*(pScanline+1) << 5)  |  (((*(pScanline  )) & 0xE0) >>3 ) );
-                iBGb16 = (mng_uint16)( (*(pScanline  )) << 3   );
-
-				iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
-                iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-                iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
-                                       /* let's blend */
-                MNG_BLEND16 (mng_get_uint16 (pDataline  ),
-                             mng_get_uint16 (pDataline+2),
-                             mng_get_uint16 (pDataline+4), iFGa16,
-                             iBGr16, iBGg16, iBGb16, iBGa16,
-                             iCr16,  iCg16,  iCb16,  iCa16);
-                                       /* and return the composed values */
-                *(pScanline+1) = (mng_uint8) ( ( (iCb16 >>  8) & 0xF8 )  |  ( (mng_uint8)(iCg16 >> 8) >> 5  )       );
-                *pScanline     = (mng_uint8) ( ( (iCr16 >> 11)        )  |  (((mng_uint8)(iCg16 >> 8) & 0xFC) << 3) );
-                *(pScanline+2) = (mng_uint8)(iCa16 >> 8);
-              }
-            }
-          }
-
-          pScanline += (pData->iColinc * 3);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iFGa8 = *(pDataline+3);      /* get alpha values */
-          iBGa8 = *(pScanline+2);
-
-          if (iFGa8)                   /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if ((iFGa8 == 0xFF) || (iBGa8 == 0))
-            {                          /* then simply copy the values */
-              *(pScanline+1) = (mng_uint8)( (  (*(pDataline+2)) &0xF8 )  |   (*(pDataline+1) >>5 )       );
-              *pScanline     = (mng_uint8)( ( ((*(pDataline))>>3) )  |  ((*(pDataline+1)&0xFC) << 3) );
-              *(pScanline+2) = *(pDataline+3);
-            }
-            else
-            {
-              mng_uint8 iRed, iGreen, iBlue;
-
-              iBlue   = (mng_uint8) (  *(pScanline+1) & 0xF8 );
-              iGreen = (mng_uint8) ( (*(pScanline+1) << 5)  |  ( ((*pScanline) & 0xE0)>>3 ) );
-              iRed  = (mng_uint8) ( (*pScanline << 3) );
-
-              if (iBGa8 == 0xFF)       /* background fully opaque ? */
-              {                        /* do alpha composing */
-                MNG_COMPOSE8 (iRed,   *pDataline,     iFGa8, iRed   );
-                MNG_COMPOSE8 (iGreen, *(pDataline+1), iFGa8, iGreen );
-                MNG_COMPOSE8 (iBlue,  *(pDataline+2), iFGa8, iBlue  );
-                                       /* alpha remains fully opaque !!! */
-                *(pScanline+1) = (mng_uint8) ( ( iBlue  & 0xF8 )  |   (iGreen>>5) );
-                *pScanline     = (mng_uint8) ( ( iRed >>  3  )  | ( (iGreen & 0xFC) << 3) );
-              }
-              else
-              {                        /* now blend */
-                MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
-                            iRed      , iGreen        , iBlue         , iBGa8,
-                            iCr8, iCg8, iCb8, iCa8);
-                                       /* and return the composed values */
-
-
-                *pScanline     = (mng_uint8) ( ( iCr8 >>  3  )  | ( (iCg8 & 0xFC) << 3) );
-                *(pScanline+1) = (mng_uint8) ( ( iCb8  & 0xF8 )  |   (iCg8>>5) );
-				*(pScanline+2) = (mng_uint8) iCa8;
-              }
-            }
-          }
-
-          pScanline += (pData->iColinc *3);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA565, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
-#else /* MNG_NO_16BIT_SUPPORT */
-mng_retcode mng_display_rgba565 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint8  iFGa8, iBGa8, iCa8;
-  mng_uint8  iCr8, iCg8, iCb8;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA565, MNG_LC_START);
-#endif
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl * 3);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values */
-          *(pScanline+1) = (mng_uint8)( ( (*(pDataline+2))&0xF8 )  |  ( (*(pDataline+1)>>5   )     ) );
-          *pScanline     = (mng_uint8)( (  *(pDataline) >>3 )  |  ( (*(pDataline+1)&0xFC ) << 3) );
-          *(pScanline+2) = *(pDataline+3);
-
-          pScanline += (pData->iColinc * 3);
-          pDataline += 4;
-        }
-      }
-    }
-    else
-    {
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iFGa8 = *(pDataline+3);      /* get alpha values */
-          iBGa8 = *(pScanline+2);
-
-          if (iFGa8)                   /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if ((iFGa8 == 0xFF) || (iBGa8 == 0))
-            {                          /* then simply copy the values */
-              *(pScanline+1) = (mng_uint8)( (  (*(pDataline+2)) &0xF8 )  |   (*(pDataline+1) >>5 )       );
-              *pScanline     = (mng_uint8)( ( ((*(pDataline))>>3) )  |  ((*(pDataline+1)&0xFC) << 3) );
-              *(pScanline+2) = *(pDataline+3);
-            }
-            else
-            {
-              mng_uint8 iRed, iGreen, iBlue;
-
-              iBlue   = (mng_uint8) (  *(pScanline+1) & 0xF8 );
-              iGreen = (mng_uint8) ( (*(pScanline+1) << 5)  |  ( ((*pScanline) & 0xE0)>>3 ) );
-              iRed  = (mng_uint8) ( (*pScanline << 3) );
-
-              if (iBGa8 == 0xFF)       /* background fully opaque ? */
-              {                        /* do alpha composing */
-                MNG_COMPOSE8 (iRed,   *pDataline,     iFGa8, iRed   );
-                MNG_COMPOSE8 (iGreen, *(pDataline+1), iFGa8, iGreen );
-                MNG_COMPOSE8 (iBlue,  *(pDataline+2), iFGa8, iBlue  );
-                                       /* alpha remains fully opaque !!! */
-                *(pScanline+1) = (mng_uint8) ( ( iBlue  & 0xF8 )  |   (iGreen>>5) );
-                *pScanline     = (mng_uint8) ( ( iRed >>  3  )  | ( (iGreen & 0xFC) << 3) );
-              }
-              else
-              {                        /* now blend */
-                MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
-                            iRed      , iGreen        , iBlue         , iBGa8,
-                            iCr8, iCg8, iCb8, iCa8);
-                                       /* and return the composed values */
-
-
-                *pScanline     = (mng_uint8) ( ( iCr8 >>  3  )  | ( (iCg8 & 0xFC) << 3) );
-                *(pScanline+1) = (mng_uint8) ( ( iCb8  & 0xF8 )  |   (iCg8>>5) );
-				*(pScanline+2) = (mng_uint8) iCa8;
-              }
-            }
-          }
-
-          pScanline += (pData->iColinc *3);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA565, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_NO_16BIT_SUPPORT */
-#endif /* MNG_SKIPCANVAS_RGBA565 */
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCANVAS_BGR565_A8
-#ifndef MNG_NO_16BIT_SUPPORT
-#ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
-mng_retcode mng_display_bgr565_a8 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pAlphaline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint16 iA16;
-  mng_uint16 iFGr16, iFGg16, iFGb16;
-  mng_uint16 iBGr16, iBGg16, iBGb16, iBGa16;
-  mng_uint16 iCr16,  iCg16,  iCb16,  iCa16;
-  mng_uint8  iA8, iBGa8, iCa8;
-  mng_uint8  iCr8, iCg8, iCb8;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGR565_A8, MNG_LC_START);
-#endif
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-    pAlphaline = (mng_uint8p)pData->fGetalphaline  (((mng_handle)pData),
-                                                    pData->iRow + pData->iDestt -
-                                                    pData->iSourcet);
-                                       /* adjust destination row
-starting-point */
-    pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
-    pAlphaline = pAlphaline + pData->iCol + pData->iDestl;
-    pDataline = pData->pRGBArow;       /* address source row */
-
-    if (pData->bIsRGBA16)       /* adjust source row starting-point */
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
-    else
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* scale down by dropping the LSB */
-          *(pScanline+1) = (mng_uint8)( ( (*(pDataline))&0xF8 ) | ((*(pDataline+2)>>5)       ) );
-          *pScanline     = (mng_uint8)( ( (*(pDataline+4)) >>3) | ((*(pDataline+2)&0xFC) << 3) );
-          *pAlphaline    = (mng_uint8)(*(pDataline+6));
-
-          pScanline += (pData->iColinc * 2);
-          pAlphaline += pData->iColinc;
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values */
-          *(pScanline+1) = (mng_uint8)( ( (*(pDataline))&0xF8 )  |  ((*(pDataline+1)>>5   )     ) );
-          *pScanline     = (mng_uint8)( (  *(pDataline+2) >>3 )  |  ((*(pDataline+1)&0xFC ) << 3) );
-          *pAlphaline    = (mng_uint8)(*(pDataline+3));
-
-          pScanline += (pData->iColinc * 2);
-          pAlphaline += pData->iColinc;
-          pDataline += 4;
-        }
-      }
-    }
-    else /* Not fully opaque */
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iA16 = mng_get_uint16 (pDataline+6);
-          iBGa16 = (mng_uint16)(*pAlphaline);
-          iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
-
-          if (iA16)                    /* any opacity at all ? */
-          {
-            if ((iA16 == 0xFFFF) || (iBGa16 == 0))       /* fully opaque or background fully transparent ? */
-            {                          /* scale down by dropping the LSB */
-              *(pScanline+1) = (mng_uint8)( (*(pDataline))&0xF8 )  | (mng_uint8)( (*(pDataline+2)>>5  )     );
-              *pScanline     = (mng_uint8)( (*(pDataline+4)) >>3)  | (mng_uint8)( (*(pDataline+2)&0xFC) << 3);
-              *pAlphaline    = *(pDataline+6);
-            }
-            else
-            {
-              if (iBGa16 == 0xFFFF)    /* background fully opaque ? */
-              {
-                                        /* get the proper values */
-                iFGr16 = mng_get_uint16 (pDataline  );
-                iFGg16 = mng_get_uint16 (pDataline+2);
-                iFGb16 = mng_get_uint16 (pDataline+4);
-                                         /* scale background up */
-
-                iBGb16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
-                iBGg16 = (mng_uint16)( (*(pScanline+1) << 5)  | (((*(pScanline  )) & 0xE0) >>3 ) );
-                iBGr16 = (mng_uint16)( (*(pScanline  )) << 3   );
-
-                iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
-                iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-                iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
-                                         /* now compose */
-                MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16);
-                MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
-                MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16);
-                                         /* and return the composed values */
-                *(pScanline+1) = (mng_uint8) ( ( (iFGr16 >> 8)&0xF8 )  | ( (mng_uint8)(iFGg16>>8) >> 5)       );
-                *pScanline     = (mng_uint8) ( ( (iFGb16>>11)       )  | (((mng_uint8)(iFGg16>>8)&0xFC) << 3) );
-                *pAlphaline    = (mng_uint8)(iA16>>8);
-              }
-              else /* background is not fully opaque */
-              {                         /* scale background up */
-                iBGb16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
-                iBGg16 = (mng_uint16)( (*(pScanline+1) << 5)  | (((*(pScanline  )) & 0xE0) >>3 ) );
-                iBGr16 = (mng_uint16)( (*(pScanline  )) << 3   );
-
-                iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
-                iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-                iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
-                                       /* let's blend */
-                MNG_BLEND16 (mng_get_uint16 (pDataline  ),
-                             mng_get_uint16 (pDataline+2),
-                             mng_get_uint16 (pDataline+4), iA16,
-                             iBGr16, iBGg16, iBGb16, iBGa16,
-                             iCr16,  iCg16,  iCb16,  iCa16);
-                                       /* and return the composed values */
-                *(pScanline+1) = (mng_uint8) ( ( (iCr16 >> 8)&0xF8 )  | ( (mng_uint8)(iCg16>>8) >> 5)       );
-                *pScanline     = (mng_uint8) ( ( (iCb16>>11)       )  | (((mng_uint8)(iCg16>>8)&0xFC) << 3) );
-                *pAlphaline    = (mng_uint8)(iCa16 >> 8);
-              }
-            }
-          }
-
-          pScanline += (pData->iColinc * 2);
-          pAlphaline += pData->iColinc;
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-iX += pData->iColinc)
-        {
-          iA8 = *(pDataline+3);        /* get alpha value */
-          iBGa8 = *pAlphaline;
-
-          if (iA8)                     /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if ((iA8 == 0xFF) || (iBGa8 == 0))
-            {                          /* then simply copy the values */
-              *(pScanline+1) = (mng_uint8)( (  (*(pDataline)) &0xF8 )  | (*(pDataline+1) >>5 )        );
-              *pScanline     = (mng_uint8)( ( ((*(pDataline+2))>>3) )  | ((*(pDataline+1)&0xFC) << 3) );
-              *pAlphaline    = *(pDataline+3);
-            }
-            else
-            {
-              if (iBGa8 == 0xFF)       /* background fully opaque ? */
-              {
-                /* do alpha composing */
-                mng_uint8 iRed, iGreen, iBlue;
-
-                iRed   = (mng_uint8) (  *(pScanline+1) & 0xF8 );
-                iGreen = (mng_uint8) ( (*(pScanline+1) << 5)  |  (((*pScanline) & 0xE0)>>3 ) );
-                iBlue  = (mng_uint8) ( (*pScanline << 3) );
-
-                MNG_COMPOSE8 (iRed,     *pDataline,     iA8, iRed    );
-                MNG_COMPOSE8 (iGreen,   *(pDataline+1), iA8, iGreen  );
-                MNG_COMPOSE8 (iBlue,    *(pDataline+2), iA8, iBlue   );
-
-                *(pScanline+1) = (mng_uint8) ( ( iRed  & 0xF8 )  | (iGreen>>5) );
-                *pScanline     = (mng_uint8) ( ( iBlue >>  3  )  | ((iGreen & 0xFC) << 3) );
-                *pAlphaline    = iA8;
-              }
-              else /* background not fully opaque */
-              {
-                MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iA8,
-                            *pScanline, *(pScanline+1), *(pScanline+2), iBGa8,
-                            iCr8, iCg8, iCb8, iCa8);
-                                       /* and return the composed values */
-                *(pScanline+1) = (mng_uint8) ( ( iCr8  & 0xF8 )  | (iCg8>>5) );
-                *pScanline     = (mng_uint8) ( ( iCb8 >>  3  )  | ((iCg8 & 0xFC) << 3) );
-                *pAlphaline    = iCa8;
-              }
-            }
-          }
-
-          pScanline += (pData->iColinc * 2);
-          pAlphaline += pData->iColinc;
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGR565_A8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
-mng_retcode mng_display_bgr565_a8 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pAlphaline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint16 iA16;
-  mng_uint16 iFGr16, iFGg16, iFGb16;
-  mng_uint16 iBGr16, iBGg16, iBGb16, iBGa16;
-  mng_uint16 iCr16,  iCg16,  iCb16,  iCa16;
-  mng_uint8  iA8, iBGa8, iCa8;
-  mng_uint8  iCr8, iCg8, iCb8;
-  mng_uint8  iBps;
-
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGR565_A8, MNG_LC_START);
-#endif
-
-  iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-    pAlphaline = (mng_uint8p)pData->fGetalphaline  (((mng_handle)pData),
-                                                    pData->iRow + pData->iDestt -
-                                                    pData->iSourcet);
-                                       /* adjust destination row
-starting-point */
-    pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
-    pAlphaline = pAlphaline + pData->iCol + pData->iDestl;
-    pDataline = pData->pRGBArow;       /* address source row */
-
-    /* adjust source row starting-point */
-    pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* scale down by dropping the LSB */
-          *(pScanline+1) = (mng_uint8)( ( (*(pDataline))&0xF8 ) |
-              ((*(pDataline+iBps)>>5)       ) );
-          *pScanline     = (mng_uint8)( ( (*(pDataline+2*iBps)) >>3) |
-              ((*(pDataline+iBps)&0xFC) << 3) );
-          *pAlphaline    = (mng_uint8)(*(pDataline+6));
-
-          pScanline += (pData->iColinc * 2);
-          pAlphaline += pData->iColinc;
-          pDataline += 8;
-        }
-    }
-    else /* Not fully opaque */
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iA16 = mng_get_uint16 (pDataline+6);
-          iBGa16 = (mng_uint16)(*pAlphaline);
-          iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
-
-          if (iA16)                    /* any opacity at all ? */
-          {
-            if ((iA16 == 0xFFFF) || (iBGa16 == 0))       /* fully opaque or background fully transparent ? */
-            {                          /* scale down by dropping the LSB */
-              *(pScanline+1) = (mng_uint8)( (*(pDataline))&0xF8 )  | (mng_uint8)( (*(pDataline+2)>>5  )     );
-              *pScanline     = (mng_uint8)( (*(pDataline+4)) >>3)  | (mng_uint8)( (*(pDataline+2)&0xFC) << 3);
-              *pAlphaline    = *(pDataline+6);
-            }
-            else
-            {
-              if (iBGa16 == 0xFFFF)    /* background fully opaque ? */
-              {
-                                        /* get the proper values */
-                iFGr16 = mng_get_uint16 (pDataline  );
-                iFGg16 = mng_get_uint16 (pDataline+2);
-                iFGb16 = mng_get_uint16 (pDataline+4);
-                                         /* scale background up */
-
-                iBGb16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
-                iBGg16 = (mng_uint16)( (*(pScanline+1) << 5)  | (((*(pScanline  )) & 0xE0) >>3 ) );
-                iBGr16 = (mng_uint16)( (*(pScanline  )) << 3   );
-
-                iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
-                iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-                iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
-                                         /* now compose */
-                MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16);
-                MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
-                MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16);
-                                         /* and return the composed values */
-                *(pScanline+1) = (mng_uint8) ( ( (iFGr16 >> 8)&0xF8 )  | ( (mng_uint8)(iFGg16>>8) >> 5)       );
-                *pScanline     = (mng_uint8) ( ( (iFGb16>>11)       )  | (((mng_uint8)(iFGg16>>8)&0xFC) << 3) );
-                *pAlphaline    = (mng_uint8)(iA16>>8);
-              }
-              else /* background is not fully opaque */
-              {                         /* scale background up */
-                iBGb16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
-                iBGg16 = (mng_uint16)( (*(pScanline+1) << 5)  | (((*(pScanline  )) & 0xE0) >>3 ) );
-                iBGr16 = (mng_uint16)( (*(pScanline  )) << 3   );
-
-                iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
-                iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-                iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
-                                       /* let's blend */
-                MNG_BLEND16 (mng_get_uint16 (pDataline  ),
-                             mng_get_uint16 (pDataline+2),
-                             mng_get_uint16 (pDataline+4), iA16,
-                             iBGr16, iBGg16, iBGb16, iBGa16,
-                             iCr16,  iCg16,  iCb16,  iCa16);
-                                       /* and return the composed values */
-                *(pScanline+1) = (mng_uint8) ( ( (iCr16 >> 8)&0xF8 )  | ( (mng_uint8)(iCg16>>8) >> 5)       );
-                *pScanline     = (mng_uint8) ( ( (iCb16>>11)       )  | (((mng_uint8)(iCg16>>8)&0xFC) << 3) );
-                *pAlphaline    = (mng_uint8)(iCa16 >> 8);
-              }
-            }
-          }
-
-          pScanline += (pData->iColinc * 2);
-          pAlphaline += pData->iColinc;
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-iX += pData->iColinc)
-        {
-          iA8 = *(pDataline+3);        /* get alpha value */
-          iBGa8 = *pAlphaline;
-
-          if (iA8)                     /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if ((iA8 == 0xFF) || (iBGa8 == 0))
-            {                          /* then simply copy the values */
-              *(pScanline+1) = (mng_uint8)( (  (*(pDataline)) &0xF8 )  | (*(pDataline+1) >>5 )        );
-              *pScanline     = (mng_uint8)( ( ((*(pDataline+2))>>3) )  | ((*(pDataline+1)&0xFC) << 3) );
-              *pAlphaline    = *(pDataline+3);
-            }
-            else
-            {
-              if (iBGa8 == 0xFF)       /* background fully opaque ? */
-              {
-                /* do alpha composing */
-                mng_uint8 iRed, iGreen, iBlue;
-
-                iRed   = (mng_uint8) (  *(pScanline+1) & 0xF8 );
-                iGreen = (mng_uint8) ( (*(pScanline+1) << 5)  |  (((*pScanline) & 0xE0)>>3 ) );
-                iBlue  = (mng_uint8) ( (*pScanline << 3) );
-
-                MNG_COMPOSE8 (iRed,     *pDataline,     iA8, iRed    );
-                MNG_COMPOSE8 (iGreen,   *(pDataline+1), iA8, iGreen  );
-                MNG_COMPOSE8 (iBlue,    *(pDataline+2), iA8, iBlue   );
-
-                *(pScanline+1) = (mng_uint8) ( ( iRed  & 0xF8 )  | (iGreen>>5) );
-                *pScanline     = (mng_uint8) ( ( iBlue >>  3  )  | ((iGreen & 0xFC) << 3) );
-                *pAlphaline    = iA8;
-              }
-              else /* background not fully opaque */
-              {
-                MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iA8,
-                            *pScanline, *(pScanline+1), *(pScanline+2), iBGa8,
-                            iCr8, iCg8, iCb8, iCa8);
-                                       /* and return the composed values */
-                *(pScanline+1) = (mng_uint8) ( ( iCr8  & 0xF8 )  | (iCg8>>5) );
-                *pScanline     = (mng_uint8) ( ( iCb8 >>  3  )  | ((iCg8 & 0xFC) << 3) );
-                *pAlphaline    = iCa8;
-              }
-            }
-          }
-
-          pScanline += (pData->iColinc * 2);
-          pAlphaline += pData->iColinc;
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGR565_A8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
-#else /* MNG_NO_16BIT_SUPPORT */
-mng_retcode mng_display_bgr565_a8 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pAlphaline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint8  iA8, iBGa8, iCa8;
-  mng_uint8  iCr8, iCg8, iCb8;
-
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGR565_A8, MNG_LC_START);
-#endif
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-    pAlphaline = (mng_uint8p)pData->fGetalphaline  (((mng_handle)pData),
-                                                    pData->iRow + pData->iDestt -
-                                                    pData->iSourcet);
-                                       /* adjust destination row
-starting-point */
-    pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
-    pAlphaline = pAlphaline + pData->iCol + pData->iDestl;
-    pDataline = pData->pRGBArow;       /* address source row */
-
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values */
-          *(pScanline+1) = (mng_uint8)( ( (*(pDataline))&0xF8 )  |  ((*(pDataline+1)>>5   )     ) );
-          *pScanline     = (mng_uint8)( (  *(pDataline+2) >>3 )  |  ((*(pDataline+1)&0xFC ) << 3) );
-          *pAlphaline    = (mng_uint8)(*(pDataline+3));
-
-          pScanline += (pData->iColinc * 2);
-          pAlphaline += pData->iColinc;
-          pDataline += 4;
-        }
-      }
-    }
-    else /* Not fully opaque */
-    {
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-iX += pData->iColinc)
-        {
-          iA8 = *(pDataline+3);        /* get alpha value */
-          iBGa8 = *pAlphaline;
-
-          if (iA8)                     /* any opacity at all ? */
-          {                            /* fully opaque or background fully transparent ? */
-            if ((iA8 == 0xFF) || (iBGa8 == 0))
-            {                          /* then simply copy the values */
-              *(pScanline+1) = (mng_uint8)( (  (*(pDataline)) &0xF8 )  | (*(pDataline+1) >>5 )        );
-              *pScanline     = (mng_uint8)( ( ((*(pDataline+2))>>3) )  | ((*(pDataline+1)&0xFC) << 3) );
-              *pAlphaline    = *(pDataline+3);
-            }
-            else
-            {
-              if (iBGa8 == 0xFF)       /* background fully opaque ? */
-              {
-                /* do alpha composing */
-                mng_uint8 iRed, iGreen, iBlue;
-
-                iRed   = (mng_uint8) (  *(pScanline+1) & 0xF8 );
-                iGreen = (mng_uint8) ( (*(pScanline+1) << 5)  |  (((*pScanline) & 0xE0)>>3 ) );
-                iBlue  = (mng_uint8) ( (*pScanline << 3) );
-
-                MNG_COMPOSE8 (iRed,     *pDataline,     iA8, iRed    );
-                MNG_COMPOSE8 (iGreen,   *(pDataline+1), iA8, iGreen  );
-                MNG_COMPOSE8 (iBlue,    *(pDataline+2), iA8, iBlue   );
-
-                *(pScanline+1) = (mng_uint8) ( ( iRed  & 0xF8 )  | (iGreen>>5) );
-                *pScanline     = (mng_uint8) ( ( iBlue >>  3  )  | ((iGreen & 0xFC) << 3) );
-                *pAlphaline    = iA8;
-              }
-              else /* background not fully opaque */
-              {
-                MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iA8,
-                            *pScanline, *(pScanline+1), *(pScanline+2), iBGa8,
-                            iCr8, iCg8, iCb8, iCa8);
-                                       /* and return the composed values */
-                *(pScanline+1) = (mng_uint8) ( ( iCr8  & 0xF8 )  | (iCg8>>5) );
-                *pScanline     = (mng_uint8) ( ( iCb8 >>  3  )  | ((iCg8 & 0xFC) << 3) );
-                *pAlphaline    = iCa8;
-              }
-            }
-          }
-
-          pScanline += (pData->iColinc * 2);
-          pAlphaline += pData->iColinc;
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGR565_A8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_NO_16BIT_SUPPORT */
-#endif /* MNG_SKIPCANVAS_BGR565_A8 */
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCANVAS_RGB555
-#ifndef MNG_NO_16BIT_SUPPORT
-#ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
-mng_retcode mng_display_rgb555 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint16 iA16;
-  mng_uint16 iFGr16, iFGg16, iFGb16;
-  mng_uint16 iBGr16, iBGg16, iBGb16;
-  mng_uint8  iA8;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGB555, MNG_LC_START);
-#endif
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-    if (pData->bIsRGBA16)              /* adjust source row starting-point */
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
-    else
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* scale down by dropping the LSB */
-          *(pScanline+1) = (mng_uint8)( ((*(pDataline+4) & 0xF8) >> 1 ) |  (*(pDataline+2)         >> 6 ) );
-          *pScanline     = (mng_uint8)( ( *(pDataline  )         >> 3 ) | ((*(pDataline+2) & 0xF8) << 2 ) );
-
-          pScanline += (pData->iColinc * 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values */
-          *(pScanline+1) = (mng_uint8)( ((*(pDataline+2) & 0xF8) >> 1 ) |  (*(pDataline+1)         >> 6 ) );
-          *pScanline     = (mng_uint8)( ( *(pDataline  )         >> 3 ) | ((*(pDataline+1) & 0xF8) << 2 ) );
-
-          pScanline += (pData->iColinc * 2);
-          pDataline += 4;
-        }
-      }
-    }
-    else
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iA16 = mng_get_uint16 (pDataline+6);
-
-          if (iA16)                    /* any opacity at all ? */
-          {
-            if (iA16 == 0xFFFF)        /* fully opaque ? */
-            {                          /* scale down by dropping the LSB */
-              *(pScanline+1) = (mng_uint8)( ((*(pDataline+4) & 0xF8) >> 1 ) |  (*(pDataline+2)         >> 6 ) );
-              *pScanline     = (mng_uint8)( ( *(pDataline  )         >> 3 ) | ((*(pDataline+2) & 0xF8) << 2 ) );
-            }
-            else
-            {                          /* get the proper values */
-              iFGr16 = mng_get_uint16 (pDataline  );
-              iFGg16 = mng_get_uint16 (pDataline+2);
-              iFGb16 = mng_get_uint16 (pDataline+4);
-
-			                           /* scale background up */
-              iBGr16 = (mng_uint8)( (*(pScanline+1) & 0xF8) << 1 );
-              iBGg16 = (mng_uint8)( (*(pScanline+1)         << 6 )  |  ( ((*pScanline) & 0xE0) >> 2 ) );
-              iBGb16 = (mng_uint8)(  *(pScanline  )         << 3 );
-
-              iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
-              iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-              iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
-                                       /* now compose */
-              MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16);
-              MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
-              MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16);
-                                       /* and return the composed values */
-              *(pScanline+1) = (mng_uint8)( (mng_uint8)(((iFGb16 >> 8) & 0xF8) >> 1 ) | (   (mng_uint8)(iFGg16 >> 8)         >> 6 ) );
-              *pScanline     = (mng_uint8)( (mng_uint8) ((iFGr16 >>11)         >> 3 ) | ( ( (mng_uint8)(iFGg16 >> 8) & 0xF8) << 2 ) );
-            }
-          }
-
-          pScanline += (pData->iColinc * 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iA8 = *(pDataline+3);        /* get alpha value */
-
-          if (iA8)                     /* any opacity at all ? */
-          {
-            if (iA8 == 0xFF)           /* fully opaque ? */
-            {                          /* then simply copy the values */
-              *(pScanline+1) = (mng_uint8)( ((*(pDataline+2) & 0xF8) >> 1 ) |  (*(pDataline+1)         >> 6 ) );
-              *pScanline     = (mng_uint8)( ( *(pDataline  )         >> 3 ) | ((*(pDataline+1) & 0xF8) << 2 ) );
-            }
-            else
-            {                          /* do alpha composing */
-              mng_uint8 iRed, iGreen, iBlue;
-
-              iRed   = (mng_uint8)( (*(pScanline+1) & 0xF8) << 1 );
-              iGreen = (mng_uint8)( (*(pScanline+1)         << 6 )  |  ( ((*pScanline) & 0xE0) >> 2 ) );
-              iBlue  = (mng_uint8)(  *(pScanline  )         << 3 );
-
-              MNG_COMPOSE8 (iRed,     *(pDataline+2), iA8, iRed    );
-              MNG_COMPOSE8 (iGreen,   *(pDataline+1), iA8, iGreen  );
-              MNG_COMPOSE8 (iBlue,    *(pDataline+0), iA8, iBlue   );
-
-              *(pScanline+1) = (mng_uint8)( ( (iRed & 0xF8) >> 1 )  |  (  iGreen         >> 6 ) );
-              *pScanline     = (mng_uint8)(   (iBlue        >> 3 )  |  ( (iGreen & 0xF8) << 2 ) );
-            }
-          }
-
-          pScanline += (pData->iColinc * 2);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGB555, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
-mng_retcode mng_display_rgb555 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint16 iA16;
-  mng_uint16 iFGr16, iFGg16, iFGb16;
-  mng_uint16 iBGr16, iBGg16, iBGb16;
-  mng_uint8  iA8;
-  mng_uint8  iBps;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGB555, MNG_LC_START);
-#endif
-
-  iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-    /* adjust source row starting-point */
-    pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* scale down by dropping the LSB */
-          *(pScanline+1) = (mng_uint8)( ((*(pDataline+2*iBps) & 0xF8) >> 1 ) |  (*(pDataline+iBps)         >> 6 ) );
-          *pScanline     = (mng_uint8)( ( *(pDataline       )         >> 3 ) | ((*(pDataline+iBps) & 0xF8) << 2 ) );
-
-          pScanline += (pData->iColinc * 2);
-          pDataline += 4*iBps;
-        }
-    }
-    else
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iA16 = mng_get_uint16 (pDataline+6);
-
-          if (iA16)                    /* any opacity at all ? */
-          {
-            if (iA16 == 0xFFFF)        /* fully opaque ? */
-            {                          /* scale down by dropping the LSB */
-              *(pScanline+1) = (mng_uint8)( ((*(pDataline+4) & 0xF8) >> 1 ) |  (*(pDataline+2)         >> 6 ) );
-              *pScanline     = (mng_uint8)( ( *(pDataline  )         >> 3 ) | ((*(pDataline+2) & 0xF8) << 2 ) );
-            }
-            else
-            {                          /* get the proper values */
-              iFGr16 = mng_get_uint16 (pDataline  );
-              iFGg16 = mng_get_uint16 (pDataline+2);
-              iFGb16 = mng_get_uint16 (pDataline+4);
-
-			                           /* scale background up */
-              iBGr16 = (mng_uint8)( (*(pScanline+1) & 0xF8) << 1 );
-              iBGg16 = (mng_uint8)( (*(pScanline+1)         << 6 )  |  ( ((*pScanline) & 0xE0) >> 2 ) );
-              iBGb16 = (mng_uint8)(  *(pScanline  )         << 3 );
-
-              iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
-              iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-              iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
-                                       /* now compose */
-              MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16);
-              MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
-              MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16);
-                                       /* and return the composed values */
-              *(pScanline+1) = (mng_uint8)( (mng_uint8)(((iFGb16 >> 8) & 0xF8) >> 1 ) | (   (mng_uint8)(iFGg16 >> 8)         >> 6 ) );
-              *pScanline     = (mng_uint8)( (mng_uint8) ((iFGr16 >>11)         >> 3 ) | ( ( (mng_uint8)(iFGg16 >> 8) & 0xF8) << 2 ) );
-            }
-          }
-
-          pScanline += (pData->iColinc * 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iA8 = *(pDataline+3);        /* get alpha value */
-
-          if (iA8)                     /* any opacity at all ? */
-          {
-            if (iA8 == 0xFF)           /* fully opaque ? */
-            {                          /* then simply copy the values */
-              *(pScanline+1) = (mng_uint8)( ((*(pDataline+2) & 0xF8) >> 1 ) |  (*(pDataline+1)         >> 6 ) );
-              *pScanline     = (mng_uint8)( ( *(pDataline  )         >> 3 ) | ((*(pDataline+1) & 0xF8) << 2 ) );
-            }
-            else
-            {                          /* do alpha composing */
-              mng_uint8 iRed, iGreen, iBlue;
-
-              iRed   = (mng_uint8)( (*(pScanline+1) & 0xF8) << 1 );
-              iGreen = (mng_uint8)( (*(pScanline+1)         << 6 )  |  ( ((*pScanline) & 0xE0) >> 2 ) );
-              iBlue  = (mng_uint8)(  *(pScanline  )         << 3 );
-
-              MNG_COMPOSE8 (iRed,     *(pDataline+2), iA8, iRed    );
-              MNG_COMPOSE8 (iGreen,   *(pDataline+1), iA8, iGreen  );
-              MNG_COMPOSE8 (iBlue,    *(pDataline+0), iA8, iBlue   );
-
-              *(pScanline+1) = (mng_uint8)( ( (iRed & 0xF8) >> 1 )  |  (  iGreen         >> 6 ) );
-              *pScanline     = (mng_uint8)(   (iBlue        >> 3 )  |  ( (iGreen & 0xF8) << 2 ) );
-            }
-          }
-
-          pScanline += (pData->iColinc * 2);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGB555, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
-#else /* MNG_NO_16BIT_SUPPORT */
-mng_retcode mng_display_rgb555 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint8  iA8;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGB555, MNG_LC_START);
-#endif
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values */
-          *(pScanline+1) = (mng_uint8)( ((*(pDataline+2) & 0xF8) >> 1 ) |  (*(pDataline+1)         >> 6 ) );
-          *pScanline     = (mng_uint8)( ( *(pDataline  )         >> 3 ) | ((*(pDataline+1) & 0xF8) << 2 ) );
-
-          pScanline += (pData->iColinc * 2);
-          pDataline += 4;
-        }
-      }
-    }
-    else
-    {
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iA8 = *(pDataline+3);        /* get alpha value */
-
-          if (iA8)                     /* any opacity at all ? */
-          {
-            if (iA8 == 0xFF)           /* fully opaque ? */
-            {                          /* then simply copy the values */
-              *(pScanline+1) = (mng_uint8)( ((*(pDataline+2) & 0xF8) >> 1 ) |  (*(pDataline+1)         >> 6 ) );
-              *pScanline     = (mng_uint8)( ( *(pDataline  )         >> 3 ) | ((*(pDataline+1) & 0xF8) << 2 ) );
-            }
-            else
-            {                          /* do alpha composing */
-              mng_uint8 iRed, iGreen, iBlue;
-
-              iRed   = (mng_uint8)( (*(pScanline+1) & 0xF8) << 1 );
-              iGreen = (mng_uint8)( (*(pScanline+1)         << 6 )  |  ( ((*pScanline) & 0xE0) >> 2 ) );
-              iBlue  = (mng_uint8)(  *(pScanline  )         << 3 );
-
-              MNG_COMPOSE8 (iRed,     *(pDataline+2), iA8, iRed    );
-              MNG_COMPOSE8 (iGreen,   *(pDataline+1), iA8, iGreen  );
-              MNG_COMPOSE8 (iBlue,    *(pDataline+0), iA8, iBlue   );
-
-              *(pScanline+1) = (mng_uint8)( ( (iRed & 0xF8) >> 1 )  |  (  iGreen         >> 6 ) );
-              *pScanline     = (mng_uint8)(   (iBlue        >> 3 )  |  ( (iGreen & 0xF8) << 2 ) );
-            }
-          }
-
-          pScanline += (pData->iColinc * 2);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_RGB555, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_NO_16BIT_SUPPORT */
-#endif /* MNG_SKIPCANVAS_RGB555 */
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCANVAS_BGR555
-#ifndef MNG_NO_16BIT_SUPPORT
-#ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
-mng_retcode mng_display_bgr555 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint16 iA16;
-  mng_uint16 iFGr16, iFGg16, iFGb16;
-  mng_uint16 iBGr16, iBGg16, iBGb16;
-  mng_uint8  iA8;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGR555, MNG_LC_START);
-#endif
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-    if (pData->bIsRGBA16)              /* adjust source row starting-point */
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
-    else
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* scale down by dropping the LSB */
-          *(pScanline+1) = (mng_uint8)( ((*(pDataline  ) & 0xF8) >> 1 ) |  (*(pDataline+2)         >> 6 ) );
-          *pScanline     = (mng_uint8)( ( *(pDataline+4)         >> 3 ) | ((*(pDataline+2) & 0xF8) << 2 ) );
-
-          pScanline += (pData->iColinc * 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values */
-          *(pScanline+1) = (mng_uint8)( ((*(pDataline  ) & 0xF8) >> 1 ) |  (*(pDataline+1)         >> 6 ) );
-          *pScanline     = (mng_uint8)( ( *(pDataline+2)         >> 3 ) | ((*(pDataline+1) & 0xF8) << 2 ) );
-
-          pScanline += (pData->iColinc * 2);
-          pDataline += 4;
-        }
-      }
-    }
-    else
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iA16 = mng_get_uint16 (pDataline+6);
-
-          if (iA16)                    /* any opacity at all ? */
-          {
-            if (iA16 == 0xFFFF)        /* fully opaque ? */
-            {                          /* scale down by dropping the LSB */
-              *(pScanline+1) = (mng_uint8)( ((*(pDataline  ) & 0xF8) >> 1 ) |  (*(pDataline+2)         >> 6 ) );
-              *pScanline     = (mng_uint8)( ( *(pDataline+4)         >> 3 ) | ((*(pDataline+2) & 0xF8) << 2 ) );
-            }
-            else
-            {                          /* get the proper values */
-              iFGr16 = mng_get_uint16 (pDataline  );
-              iFGg16 = mng_get_uint16 (pDataline+2);
-              iFGb16 = mng_get_uint16 (pDataline+4);
-
-			                           /* scale background up */
-              iBGb16 = (mng_uint8)( (*(pScanline+1) & 0xF8) << 1 );
-              iBGg16 = (mng_uint8)( (*(pScanline+1)         << 6 )  |  ( ((*pScanline) & 0xE0) >> 2 ) );
-              iBGr16 = (mng_uint8)(  *(pScanline  )         << 3 );
-
-              iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
-              iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-              iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
-                                       /* now compose */
-              MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16);
-              MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
-              MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16);
-                                       /* and return the composed values */
-              *(pScanline+1) = (mng_uint8)( (mng_uint8)(((iFGr16 >> 8) & 0xF8) >> 1 ) | (   (mng_uint8)(iFGg16 >> 8)         >> 6 ) );
-              *pScanline     = (mng_uint8)( (mng_uint8) ((iFGb16 >>11)         >> 3 ) | ( ( (mng_uint8)(iFGg16 >> 8) & 0xF8) << 2 ) );
-            }
-          }
-
-          pScanline += (pData->iColinc * 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iA8 = *(pDataline+3);        /* get alpha value */
-
-          if (iA8)                     /* any opacity at all ? */
-          {
-            if (iA8 == 0xFF)           /* fully opaque ? */
-            {                          /* then simply copy the values */
-              *(pScanline+1) = (mng_uint8)( ((*(pDataline  ) & 0xF8) >> 1 ) |  (*(pDataline+1)         >> 6 ) );
-              *pScanline     = (mng_uint8)( ( *(pDataline+2)         >> 3 ) | ((*(pDataline+1) & 0xF8) << 2 ) );
-            }
-            else
-            {                          /* do alpha composing */
-              mng_uint8 iRed, iGreen, iBlue;
-
-              iRed   = (mng_uint8)( (*(pScanline+1) & 0xF8) << 1 );
-              iGreen = (mng_uint8)( (*(pScanline+1)         << 6 )  |  ( ((*pScanline) & 0xE0) >> 2 ) );
-              iBlue  = (mng_uint8)(  *(pScanline  )         << 3 );
-
-              MNG_COMPOSE8 (iRed,     *(pDataline+0), iA8, iRed    );
-              MNG_COMPOSE8 (iGreen,   *(pDataline+1), iA8, iGreen  );
-              MNG_COMPOSE8 (iBlue,    *(pDataline+2), iA8, iBlue   );
-
-              *(pScanline+1) = (mng_uint8)( ( (iRed & 0xF8) >> 1 )  |  (  iGreen         >> 6 ) );
-              *pScanline     = (mng_uint8)(   (iBlue        >> 3 )  |  ( (iGreen & 0xF8) << 2 ) );
-            }
-          }
-
-          pScanline += (pData->iColinc * 2);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGR555, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
-mng_retcode mng_display_bgr555 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint16 iA16;
-  mng_uint16 iFGr16, iFGg16, iFGb16;
-  mng_uint16 iBGr16, iBGg16, iBGb16;
-  mng_uint8  iA8;
-  mng_uint8  iBps;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGR555, MNG_LC_START);
-#endif
-
-  iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-    /* adjust source row starting-point */
-    pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* scale down by dropping the LSB */
-          *(pScanline+1) = (mng_uint8)( ((*(pDataline       ) & 0xF8) >> 1 ) |  (*(pDataline+iBps)         >> 6 ) );
-          *pScanline     = (mng_uint8)( ( *(pDataline+2*iBps)         >> 3 ) | ((*(pDataline+iBps) & 0xF8) << 2 ) );
-
-          pScanline += (pData->iColinc * 2);
-          pDataline += 4*iBps;
-        }
-    }
-    else
-    {
-      if (pData->bIsRGBA16)            /* 16-bit input row ? */
-      {
-
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iA16 = mng_get_uint16 (pDataline+6);
-
-          if (iA16)                    /* any opacity at all ? */
-          {
-            if (iA16 == 0xFFFF)        /* fully opaque ? */
-            {                          /* scale down by dropping the LSB */
-              *(pScanline+1) = (mng_uint8)( ((*(pDataline  ) & 0xF8) >> 1 ) |  (*(pDataline+2)         >> 6 ) );
-              *pScanline     = (mng_uint8)( ( *(pDataline+4)         >> 3 ) | ((*(pDataline+2) & 0xF8) << 2 ) );
-            }
-            else
-            {                          /* get the proper values */
-              iFGr16 = mng_get_uint16 (pDataline  );
-              iFGg16 = mng_get_uint16 (pDataline+2);
-              iFGb16 = mng_get_uint16 (pDataline+4);
-
-			                           /* scale background up */
-              iBGb16 = (mng_uint8)( (*(pScanline+1) & 0xF8) << 1 );
-              iBGg16 = (mng_uint8)( (*(pScanline+1)         << 6 )  |  ( ((*pScanline) & 0xE0) >> 2 ) );
-              iBGr16 = (mng_uint8)(  *(pScanline  )         << 3 );
-
-              iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
-              iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
-              iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
-                                       /* now compose */
-              MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16);
-              MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
-              MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16);
-                                       /* and return the composed values */
-              *(pScanline+1) = (mng_uint8)( (mng_uint8)(((iFGr16 >> 8) & 0xF8) >> 1 ) | (   (mng_uint8)(iFGg16 >> 8)         >> 6 ) );
-              *pScanline     = (mng_uint8)( (mng_uint8) ((iFGb16 >>11)         >> 3 ) | ( ( (mng_uint8)(iFGg16 >> 8) & 0xF8) << 2 ) );
-            }
-          }
-
-          pScanline += (pData->iColinc * 2);
-          pDataline += 8;
-        }
-      }
-      else
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iA8 = *(pDataline+3);        /* get alpha value */
-
-          if (iA8)                     /* any opacity at all ? */
-          {
-            if (iA8 == 0xFF)           /* fully opaque ? */
-            {                          /* then simply copy the values */
-              *(pScanline+1) = (mng_uint8)( ((*(pDataline  ) & 0xF8) >> 1 ) |  (*(pDataline+1)         >> 6 ) );
-              *pScanline     = (mng_uint8)( ( *(pDataline+2)         >> 3 ) | ((*(pDataline+1) & 0xF8) << 2 ) );
-            }
-            else
-            {                          /* do alpha composing */
-              mng_uint8 iRed, iGreen, iBlue;
-
-              iRed   = (mng_uint8)( (*(pScanline+1) & 0xF8) << 1 );
-              iGreen = (mng_uint8)( (*(pScanline+1)         << 6 )  |  ( ((*pScanline) & 0xE0) >> 2 ) );
-              iBlue  = (mng_uint8)(  *(pScanline  )         << 3 );
-
-              MNG_COMPOSE8 (iRed,     *(pDataline+0), iA8, iRed    );
-              MNG_COMPOSE8 (iGreen,   *(pDataline+1), iA8, iGreen  );
-              MNG_COMPOSE8 (iBlue,    *(pDataline+2), iA8, iBlue   );
-
-              *(pScanline+1) = (mng_uint8)( ( (iRed & 0xF8) >> 1 )  |  (  iGreen         >> 6 ) );
-              *pScanline     = (mng_uint8)(   (iBlue        >> 3 )  |  ( (iGreen & 0xF8) << 2 ) );
-            }
-          }
-
-          pScanline += (pData->iColinc * 2);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGR555, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
-#else /* MNG_NO_16BIT_SUPPORT */
-mng_retcode mng_display_bgr555 (mng_datap pData)
-{
-  mng_uint8p pScanline;
-  mng_uint8p pDataline;
-  mng_int32  iX;
-  mng_uint8  iA8;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGR555, MNG_LC_START);
-#endif
-                                       /* viewable row ? */
-  if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
-  {                                    /* address destination row */
-    pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
-                                                   pData->iRow + pData->iDestt -
-                                                   pData->iSourcet);
-                                       /* adjust destination row starting-point */
-    pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
-    pDataline = pData->pRGBArow;       /* address source row */
-
-      pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
-
-    if (pData->bIsOpaque)              /* forget about transparency ? */
-    {
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {                              /* copy the values */
-          *(pScanline+1) = (mng_uint8)( ((*(pDataline  ) & 0xF8) >> 1 ) |  (*(pDataline+1)         >> 6 ) );
-          *pScanline     = (mng_uint8)( ( *(pDataline+2)         >> 3 ) | ((*(pDataline+1) & 0xF8) << 2 ) );
-
-          pScanline += (pData->iColinc * 2);
-          pDataline += 4;
-        }
-      }
-    }
-    else
-    {
-      {
-        for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
-             iX += pData->iColinc)
-        {
-          iA8 = *(pDataline+3);        /* get alpha value */
-
-          if (iA8)                     /* any opacity at all ? */
-          {
-            if (iA8 == 0xFF)           /* fully opaque ? */
-            {                          /* then simply copy the values */
-              *(pScanline+1) = (mng_uint8)( ((*(pDataline  ) & 0xF8) >> 1 ) |  (*(pDataline+1)         >> 6 ) );
-              *pScanline     = (mng_uint8)( ( *(pDataline+2)         >> 3 ) | ((*(pDataline+1) & 0xF8) << 2 ) );
-            }
-            else
-            {                          /* do alpha composing */
-              mng_uint8 iRed, iGreen, iBlue;
-
-              iRed   = (mng_uint8)( (*(pScanline+1) & 0xF8) << 1 );
-              iGreen = (mng_uint8)( (*(pScanline+1)         << 6 )  |  ( ((*pScanline) & 0xE0) >> 2 ) );
-              iBlue  = (mng_uint8)(  *(pScanline  )         << 3 );
-
-              MNG_COMPOSE8 (iRed,     *(pDataline+0), iA8, iRed    );
-              MNG_COMPOSE8 (iGreen,   *(pDataline+1), iA8, iGreen  );
-              MNG_COMPOSE8 (iBlue,    *(pDataline+2), iA8, iBlue   );
-
-              *(pScanline+1) = (mng_uint8)( ( (iRed & 0xF8) >> 1 )  |  (  iGreen         >> 6 ) );
-              *pScanline     = (mng_uint8)(   (iBlue        >> 3 )  |  ( (iGreen & 0xF8) << 2 ) );
-            }
-          }
-
-          pScanline += (pData->iColinc * 2);
-          pDataline += 4;
-        }
-      }
-    }
-  }
-
-  check_update_region (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_BGR555, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_NO_16BIT_SUPPORT */
-#endif /* MNG_SKIPCANVAS_BGR555 */
-
-
-#ifndef MNG_SKIPCHUNK_BACK
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Background restore routines - restore the background with info from    * */
-/* * the BACK and/or bKGD chunk or the app's background canvas              * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-mng_retcode mng_restore_bkgd_backimage (mng_datap pData)
-{
-                                       /* save some stuff */
-  mng_uint8p  pRGBArow    = pData->pRGBArow;
-  mng_int32   iRow        = pData->iRow;
-  mng_int32   iRowsamples = pData->iRowsamples;
-
-  mng_retcode iRetcode;                /* work variables */
-  mng_uint8p  pTemp;
-  mng_uint8p  pWork       = pRGBArow;
-  mng_uint32  iX;
-  mng_int32   iZ;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RESTORE_BACKIMAGE, MNG_LC_START);
-#endif
-                                       /* determine row to retrieve */
-  pData->iRow        = pData->iDestt + iRow + pData->iBackimgoffsy;
-
-  while (pData->iRow >= (mng_int32)pData->iBackimgheight)
-    pData->iRow -= (mng_int32)pData->iBackimgheight;
-                                       /* set width to that of background image */
-  pData->iRowsamples = pData->iBackimgwidth;
-                                       /* retrieve into alternate buffer ! */
-  pData->pRGBArow    = pData->pPrevrow;
-                                       /* get it then */
-  iRetcode = ((mng_retrieverow)pData->fRetrieverow) (pData);
-
-  if (iRetcode)                        /* on error; bail out */
-    return iRetcode;
-                                       /* we got the full row; but now need to
-                                          paste it into the proper location */
-  iX = pData->iDestl - pData->iBackimgoffsx;
-
-  while (iX >= pData->iBackimgwidth)
-    iX -= pData->iBackimgwidth;
-
-#ifndef MNG_NO_16BIT_SUPPORT
-  if (pData->bIsRGBA16)                /* 16-bit buffer ? */
-  {
-    pTemp = pData->pPrevrow + (iX << 3);
-
-    for (iZ = (pData->iDestr - pData->iDestl); iZ > 0; iZ--)
-    {
-      MNG_COPY (pWork, pTemp, 8);
-
-      pWork += 8;
-      pTemp += 8;
-      iX++;
-                                       /* reached end of bkgd-image line ? */
-      if (iX >= pData->iBackimgwidth)
-      {
-        iX    = 0;
-        pTemp = pData->pPrevrow;
-      }
-    }
-  }
-  else
-#endif
-  {
-    pTemp = pData->pPrevrow + (iX << 2);
-
-    for (iZ = (pData->iDestr - pData->iDestl); iZ > 0; iZ--)
-    {
-      MNG_COPY (pWork, pTemp, 4);
-
-      pWork += 4;
-      pTemp += 4;
-      iX++;
-                                       /* reached end of bkgd-image line ? */
-      if (iX >= pData->iBackimgwidth)
-      {
-        iX    = 0;
-        pTemp = pData->pPrevrow;
-      }
-    }
-  }
-
-  pData->pRGBArow    = pRGBArow;       /* restore original values */
-  pData->iRow        = iRow;
-  pData->iRowsamples = iRowsamples;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RESTORE_BACKIMAGE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_restore_bkgd_backcolor (mng_datap pData)
-{
-  mng_int32   iX;
-  mng_uint32p pWork32 = (mng_uint32p)pData->pRGBArow;
-  mng_uint32  iWrite;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RESTORE_BACKCOLOR, MNG_LC_START);
-#endif
-
-#ifdef MNG_BIGENDIAN_SUPPORTED
-  /* fast way for big endian */
-  iWrite = (((mng_uint8)(pData->iBACKred   >> 8)) << 24) |
-		   (((mng_uint8)(pData->iBACKgreen >> 8)) << 16) |
-		   (((mng_uint8)(pData->iBACKblue  >> 8)) <<  8) |
-           ( 0xFF                                      );
-#elif defined(MNG_LITTLEENDIAN_SUPPORTED)
-  /* fast way for little endian */
-  iWrite = ( 0xFF                                 << 24) |
-           (((mng_uint8)(pData->iBACKblue  >> 8)) << 16) |
-		   (((mng_uint8)(pData->iBACKgreen >> 8)) <<  8) |
-		   (((mng_uint8)(pData->iBACKred   >> 8))      );
-#else
-  /* generic way, works on all platforms */
-  /* put the data in memory in the correct order */
-  {
-    mng_uint8 aBytes[4];
-    aBytes[0] = (mng_uint8)(pData->iBACKred   >> 8);
-    aBytes[1] = (mng_uint8)(pData->iBACKgreen >> 8);
-    aBytes[2] = (mng_uint8)(pData->iBACKblue  >> 8);
-    aBytes[3] = 0xFF;
-    /* load that data into a register */
-    iWrite = *(mng_uint32*) aBytes;
-  }
-#endif
-                                       /* ok; drop the background-color in there */
-  for (iX = (pData->iSourcer - pData->iSourcel); iX > 0; iX--)
-    *pWork32++ = iWrite;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RESTORE_BACKCOLOR, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_bKGD
-mng_retcode mng_restore_bkgd_bkgd (mng_datap pData)
-{
-  mng_int32      iX;
-  mng_uint8p     pWork   = pData->pRGBArow;
-  mng_imagep     pImage  = (mng_imagep)pData->pCurrentobj;
-  mng_imagedatap pBuf    = pImage->pImgbuf;
-  mng_uint8      iRed    = 0;
-  mng_uint8      iGreen  = 0;
-  mng_uint8      iBlue   = 0;
-  mng_uint32p    pWork32 = (mng_uint32p)pWork;
-  mng_uint32     iWrite;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RESTORE_BKGD, MNG_LC_START);
-#endif
-
-  switch (pBuf->iColortype)
-  {
-    case 0 : ;                         /* gray types */
-    case 4 : {
-               mng_uint8 iGray;
-
-#ifndef MNG_NO_16BIT_SUPPORT
-               if (pBuf->iBitdepth > 8)
-                 iGray = (mng_uint8)(pBuf->iBKGDgray >> 8);
-               else
-#endif
-               {
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-                 /* LBR scaling */
-                 mng_uint8 multiplier[]={0,255,85,0,17,0,0,0,1};
-                 iGray = (mng_uint8)(multiplier[pBuf->iBitdepth] * pBuf->iBKGDgray);
-#else
-                 iGray = (mng_uint8)pBuf->iBKGDgray;
-#endif
-               }
-
-               iRed   = iGray;
-               iGreen = iGray;
-               iBlue  = iGray;
-
-               break;
-             }
-
-    case 3 : {                         /* indexed type */
-               iRed   = pBuf->aPLTEentries [pBuf->iBKGDindex].iRed;
-               iGreen = pBuf->aPLTEentries [pBuf->iBKGDindex].iGreen;
-               iBlue  = pBuf->aPLTEentries [pBuf->iBKGDindex].iBlue;
-
-               break;
-             }
-
-    case 2 : ;                         /* rgb types */
-    case 6 : {
-#ifndef MNG_NO_16BIT_SUPPORT
-               if (pBuf->iBitdepth > 8)
-               {
-                 iRed   = (mng_uint8)(pBuf->iBKGDred   >> 8);
-                 iGreen = (mng_uint8)(pBuf->iBKGDgreen >> 8);
-                 iBlue  = (mng_uint8)(pBuf->iBKGDblue  >> 8);
-               }
-               else
-#endif
-               {
-                 iRed   = (mng_uint8)(pBuf->iBKGDred  );
-                 iGreen = (mng_uint8)(pBuf->iBKGDgreen);
-                 iBlue  = (mng_uint8)(pBuf->iBKGDblue );
-               }
-
-               break;
-             }
-  }
-
-#ifdef MNG_BIGENDIAN_SUPPORTED
-  /* fast way for big endian */
-  iWrite = (iRed   << 24) |
-		   (iGreen << 16) |
-		   (iBlue  <<  8);
-#elif defined(MNG_LITTLEENDIAN_SUPPORTED)
-  /* fast way for little endian */
-  iWrite = (iBlue  << 16) |
-		   (iGreen <<  8) |
-		   (iRed        );
-#else
-  /* generic way, works on all platforms */
-  /* put the data in memory in the correct order */
-  {
-    mng_uint8 aBytes[4];
-    aBytes[0] = (mng_uint8)(iRed);
-    aBytes[1] = (mng_uint8)(iGreen);
-    aBytes[2] = (mng_uint8)(iBlue);
-    aBytes[3] = 0x00;
-    /* load that data into a register */
-    iWrite = *(mng_uint32*) aBytes;
-  }
-#endif
-                                       /* ok; drop it in there */
-  for (iX = (pData->iSourcer - pData->iSourcel); iX > 0; iX--)
-    *pWork32++ = iWrite;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RESTORE_BKGD, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_restore_bkgd_bgcolor (mng_datap pData)
-{
-  mng_int32   iX;
-  mng_uint32p pWork32 = (mng_uint32p)pData->pRGBArow;
-  mng_uint32  iWrite;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RESTORE_BGCOLOR, MNG_LC_START);
-#endif
-
-#ifdef MNG_BIGENDIAN_SUPPORTED
-  /* fast way for big endian */
-  iWrite = (((mng_uint8)(pData->iBGred   >> 8)) << 24) |
-		   (((mng_uint8)(pData->iBGgreen >> 8)) << 16) |
-		   (((mng_uint8)(pData->iBGblue  >> 8)) <<  8);
-#elif defined(MNG_LITTLEENDIAN_SUPPORTED)
-  /* fast way for little endian */
-  iWrite = (((mng_uint8)(pData->iBGblue  >> 8)) << 16) |
-		   (((mng_uint8)(pData->iBGgreen >> 8)) <<  8) |
-		   (((mng_uint8)(pData->iBGred   >> 8))      );
-#else
-  /* generic way, works on all platforms */
-  /* put the data in memory in the correct order */
-  {
-    mng_uint8 aBytes[4];
-    aBytes[0] = (mng_uint8)(pData->iBGred   >> 8);
-    aBytes[1] = (mng_uint8)(pData->iBGgreen >> 8);
-    aBytes[2] = (mng_uint8)(pData->iBGblue  >> 8);
-    aBytes[3] = 0x00;
-    /* load that data into a register */
-    iWrite = *(mng_uint32*) aBytes;
-  }
-#endif
-                                       /* ok; drop the background-color in there */
-  for (iX = (pData->iSourcer - pData->iSourcel); iX > 0; iX--)
-    *pWork32++ = iWrite;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RESTORE_BGCOLOR, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCANVAS_RGB8
-mng_retcode mng_restore_bkgd_rgb8 (mng_datap pData)
-{
-  mng_int32  iX;
-  mng_uint8p pBkgd;
-  mng_uint8p pWork = pData->pRGBArow;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RESTORE_RGB8, MNG_LC_START);
-#endif
-
-  if (pData->fGetbkgdline)             /* can we access the background ? */
-  {                                    /* point to the right pixel then */
-    pBkgd = (mng_uint8p)pData->fGetbkgdline ((mng_handle)pData,
-                                             pData->iRow + pData->iDestt) +
-            (3 * pData->iDestl);
-
-    for (iX = (pData->iSourcer - pData->iSourcel); iX > 0; iX--)
-    {
-      *pWork     = *pBkgd;             /* ok; copy the pixel */
-      *(pWork+1) = *(pBkgd+1);
-      *(pWork+2) = *(pBkgd+2);
-      *(pWork+3) = 0x00;               /* transparant for alpha-canvasses */
-
-      pWork += 4;
-      pBkgd += 3;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RESTORE_RGB8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SKIPCANVAS_RGB8 */
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCANVAS_BGR8
-mng_retcode mng_restore_bkgd_bgr8 (mng_datap pData)
-{
-  mng_int32  iX;
-  mng_uint8p pBkgd;
-  mng_uint8p pWork = pData->pRGBArow;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RESTORE_BGR8, MNG_LC_START);
-#endif
-
-  if (pData->fGetbkgdline)             /* can we access the background ? */
-  {                                    /* point to the right pixel then */
-    pBkgd = (mng_uint8p)pData->fGetbkgdline ((mng_handle)pData,
-                                             pData->iRow + pData->iDestt) +
-            (3 * pData->iDestl);
-
-    for (iX = (pData->iSourcer - pData->iSourcel); iX > 0; iX--)
-    {
-      *pWork     = *(pBkgd+2);         /* ok; copy the pixel */
-      *(pWork+1) = *(pBkgd+1);
-      *(pWork+2) = *pBkgd;
-      *(pWork+3) = 0x00;               /* transparant for alpha-canvasses */
-
-      pWork += 4;
-      pBkgd += 3;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RESTORE_BGR8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SKIPCANVAS_BGR8 */
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCANVAS_BGRX8
-mng_retcode mng_restore_bkgd_bgrx8 (mng_datap pData)
-{
-  mng_int32  iX;
-  mng_uint8p pBkgd;
-  mng_uint8p pWork = pData->pRGBArow;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RESTORE_BGRX8, MNG_LC_START);
-#endif
-
-  if (pData->fGetbkgdline)             /* can we access the background ? */
-  {                                    /* point to the right pixel then */
-    pBkgd = (mng_uint8p)pData->fGetbkgdline ((mng_handle)pData,
-                                             pData->iRow + pData->iDestt) +
-            (3 * pData->iDestl);
-
-    for (iX = (pData->iSourcer - pData->iSourcel); iX > 0; iX--)
-    {
-      *pWork     = *(pBkgd+2);         /* ok; copy the pixel */
-      *(pWork+1) = *(pBkgd+1);
-      *(pWork+2) = *pBkgd;
-      *(pWork+3) = 0x00;               /* transparant for alpha-canvasses */
-
-      pWork += 4;
-      pBkgd += 4;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RESTORE_BGRX8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SKIPCANVAS_BGRX8 */
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCANVAS_BGR565
-mng_retcode mng_restore_bkgd_bgr565 (mng_datap pData)
-{
-  mng_int32  iX;
-  mng_uint8p pBkgd;
-  mng_uint8p pWork = pData->pRGBArow;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RESTORE_BGR565, MNG_LC_START);
-#endif
-
-  if (pData->fGetbkgdline)             /* can we access the background ? */
-  {                                    /* point to the right pixel then */
-    pBkgd = (mng_uint8p)pData->fGetbkgdline ((mng_handle)pData,
-                                             pData->iRow + pData->iDestt) +
-            (3 * pData->iDestl);
-
-    for (iX = (pData->iSourcer - pData->iSourcel); iX > 0; iX--)
-    {
-      *pWork     = (mng_uint8)(  *(pBkgd+1) & 0xF8);             /* ok; copy the pixel */
-      *(pWork+1) = (mng_uint8)( (*(pBkgd+1) << 5 )  |  ( ((*pBkgd)&0xE0)>>3 ) );
-      *(pWork+2) = (mng_uint8)(  *(pBkgd) << 3 );
-      *(pWork+3) = 0x00;               /* transparant for alpha-canvasses */
-
-      pWork += 4;
-      pBkgd += 2;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RESTORE_BGR565, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SKIPCANVAS_BGR565 */
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCANVAS_RGB565
-mng_retcode mng_restore_bkgd_rgb565 (mng_datap pData)
-{
-  mng_int32  iX;
-  mng_uint8p pBkgd;
-  mng_uint8p pWork = pData->pRGBArow;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RESTORE_RGB565, MNG_LC_START);
-#endif
-
-  if (pData->fGetbkgdline)             /* can we access the background ? */
-  {                                    /* point to the right pixel then */
-    pBkgd = (mng_uint8p)pData->fGetbkgdline ((mng_handle)pData,
-                                             pData->iRow + pData->iDestt) +
-            (3 * pData->iDestl);
-
-    for (iX = (pData->iSourcer - pData->iSourcel); iX > 0; iX--)
-    {
-      *pWork     = (mng_uint8)(  *(pBkgd)&0xF8);             /* ok; copy the pixel */
-      *(pWork+1) = (mng_uint8)( (*(pBkgd+1) << 5)  |  ( ((*pBkgd)&0xE0)>>3 ) );
-      *(pWork+2) = (mng_uint8)(  *(pBkgd+1) << 3);
-      *(pWork+3) = 0x00;               /* transparant for alpha-canvasses */
-
-      pWork += 4;
-      pBkgd += 2;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RESTORE_RGB565, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SKIPCANVAS_RBB565 */
-
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Row retrieval routines - retrieve processed & uncompressed row-data    * */
-/* * from the current "object"                                              * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-/* TODO: a serious optimization is to retrieve only those pixels that will
-         actually be displayed; this would require changes in
-         the "display_image" routine (in mng_display.c) &
-         all the "retrieve_xxx" routines below &
-         the "display_xxx" routines above !!!!!
-         NOTE that "correct_xxx" routines would not require modification */
-
-mng_retcode mng_retrieve_g8 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pRGBArow;
-  mng_int32      iX;
-  mng_uint8      iG;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RETRIEVE_G8, MNG_LC_START);
-#endif
-
-  pRGBArow = pData->pRGBArow;          /* temporary work pointers */
-  pWorkrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize);
-
-  if (pBuf->bHasTRNS)                  /* tRNS in buffer ? */
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      iG = *pWorkrow;                  /* get the gray-value */
-                                       /* is it transparent ? */
-      if ((mng_uint16)iG == pBuf->iTRNSgray)
-      {
-        *pRGBArow     = 0x00;          /* nuttin to display */
-        *(pRGBArow+1) = 0x00;
-        *(pRGBArow+2) = 0x00;
-        *(pRGBArow+3) = 0x00;
-      }
-      else
-      {
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-        mng_uint8 multiplier[]={0,255,85,0,17,0,0,0,1};
-        iG = (mng_uint8)(iG * multiplier[pBuf->iBitdepth]);
-#endif
-
-        *pRGBArow     = iG;            /* put in intermediate row */
-        *(pRGBArow+1) = iG;
-        *(pRGBArow+2) = iG;
-        *(pRGBArow+3) = 0xFF;
-      }
-
-      pWorkrow++;                      /* next pixel */
-      pRGBArow += 4;
-    }
-  }
-  else
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-      mng_uint8 multiplier[]={0,255,85,0,17,0,0,0,1};   /* LBR scaling */
-      iG = (mng_uint8)(multiplier[pBuf->iBitdepth] * *pWorkrow);
-#else
-      iG = *pWorkrow;                  /* get the gray-value */
-#endif
-
-      *pRGBArow     = iG;              /* put in intermediate row */
-      *(pRGBArow+1) = iG;
-      *(pRGBArow+2) = iG;
-      *(pRGBArow+3) = 0xFF;
-
-      pWorkrow++;                      /* next pixel */
-      pRGBArow += 4;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RETRIEVE_G8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_retrieve_g16 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pRGBArow;
-  mng_int32      iX;
-  mng_uint16     iG;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RETRIEVE_G16, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pRGBArow = pData->pRGBArow;
-  pWorkrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize);
-
-  if (pBuf->bHasTRNS)                  /* tRNS in buffer ? */
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      iG = mng_get_uint16 (pWorkrow);  /* get the gray-value */
-                                       /* is it transparent ? */
-      if (iG == pBuf->iTRNSgray)
-      {                                /* nuttin to display */
-        mng_put_uint16 (pRGBArow,   0x0000);
-        mng_put_uint16 (pRGBArow+2, 0x0000);
-        mng_put_uint16 (pRGBArow+4, 0x0000);
-        mng_put_uint16 (pRGBArow+6, 0x0000);
-      }
-      else
-      {                                /* put in intermediate row */
-        mng_put_uint16 (pRGBArow,   iG);
-        mng_put_uint16 (pRGBArow+2, iG);
-        mng_put_uint16 (pRGBArow+4, iG);
-        mng_put_uint16 (pRGBArow+6, 0xFFFF);
-      }
-
-      pWorkrow += 2;                   /* next pixel */
-      pRGBArow += 8;
-    }
-  }
-  else
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      iG = mng_get_uint16 (pWorkrow);  /* get the gray-value */
-
-      mng_put_uint16 (pRGBArow,   iG); /* and put in intermediate row */
-      mng_put_uint16 (pRGBArow+2, iG);
-      mng_put_uint16 (pRGBArow+4, iG);
-      mng_put_uint16 (pRGBArow+6, 0xFFFF);
-
-      pWorkrow += 2;                  /* next pixel */
-      pRGBArow += 8;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RETRIEVE_G16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_retrieve_rgb8 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pRGBArow;
-  mng_int32      iX;
-  mng_uint8      iR, iG, iB;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RETRIEVE_RGB8, MNG_LC_START);
-#endif
-
-  pRGBArow = pData->pRGBArow;          /* temporary work pointers */
-  pWorkrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize);
-
-  if (pBuf->bHasTRNS)                  /* tRNS in buffer ? */
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      iR = *pWorkrow;                  /* get the rgb-values */
-      iG = *(pWorkrow+1);
-      iB = *(pWorkrow+2);
-                                       /* is it transparent ? */
-      if (((mng_uint16)iR == pBuf->iTRNSred  ) &&
-          ((mng_uint16)iG == pBuf->iTRNSgreen) &&
-          ((mng_uint16)iB == pBuf->iTRNSblue )    )
-      {
-        *pRGBArow     = 0x00;          /* nothing to display */
-        *(pRGBArow+1) = 0x00;
-        *(pRGBArow+2) = 0x00;
-        *(pRGBArow+3) = 0x00;
-      }
-      else
-      {
-        *pRGBArow     = iR;            /* put in intermediate row */
-        *(pRGBArow+1) = iG;
-        *(pRGBArow+2) = iB;
-        *(pRGBArow+3) = 0xFF;
-      }
-
-      pWorkrow += 3;                   /* next pixel */
-      pRGBArow += 4;
-    }
-  }
-  else
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      *pRGBArow     = *pWorkrow;       /* just copy the pixel */
-      *(pRGBArow+1) = *(pWorkrow+1);
-      *(pRGBArow+2) = *(pWorkrow+2);
-      *(pRGBArow+3) = 0xFF;
-
-      pWorkrow += 3;                   /* next pixel */
-      pRGBArow += 4;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RETRIEVE_RGB8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_retrieve_rgb16 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pRGBArow;
-  mng_int32      iX;
-  mng_uint16     iR, iG, iB;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RETRIEVE_RGB16, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pRGBArow = pData->pRGBArow;
-  pWorkrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize);
-
-  if (pBuf->bHasTRNS)                  /* tRNS in buffer ? */
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      iR = mng_get_uint16 (pWorkrow);  /* get the rgb-values */
-      iG = mng_get_uint16 (pWorkrow+2);
-      iB = mng_get_uint16 (pWorkrow+4);
-                                       /* is it transparent ? */
-      if ((iR == pBuf->iTRNSred  ) &&
-          (iG == pBuf->iTRNSgreen) &&
-          (iB == pBuf->iTRNSblue )    )
-      {                                /* nothing to display */
-        mng_put_uint16 (pRGBArow,   0x0000);
-        mng_put_uint16 (pRGBArow+2, 0x0000);
-        mng_put_uint16 (pRGBArow+4, 0x0000);
-        mng_put_uint16 (pRGBArow+6, 0x0000);
-      }
-      else
-      {                                /* put in intermediate row */
-        mng_put_uint16 (pRGBArow,   iR);
-        mng_put_uint16 (pRGBArow+2, iG);
-        mng_put_uint16 (pRGBArow+4, iB);
-        mng_put_uint16 (pRGBArow+6, 0xFFFF);
-      }
-
-      pWorkrow += 6;                   /* next pixel */
-      pRGBArow += 8;
-    }
-  }
-  else
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {                                  /* just copy the pixel */
-      mng_put_uint16 (pRGBArow,   mng_get_uint16 (pWorkrow  ));
-      mng_put_uint16 (pRGBArow+2, mng_get_uint16 (pWorkrow+2));
-      mng_put_uint16 (pRGBArow+4, mng_get_uint16 (pWorkrow+4));
-      mng_put_uint16 (pRGBArow+6, 0xFFFF);
-
-      pWorkrow += 6;                   /* next pixel */
-      pRGBArow += 8;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RETRIEVE_RGB16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_retrieve_idx8 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pRGBArow;
-  mng_int32      iX;
-  mng_uint8      iQ;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RETRIEVE_IDX8, MNG_LC_START);
-#endif
-
-  pRGBArow = pData->pRGBArow;          /* temporary work pointers */
-  pWorkrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize);
-
-  if (pBuf->bHasTRNS)                  /* tRNS in buffer ? */
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      iQ = *pWorkrow;                  /* get the index */
-                                       /* is it valid ? */
-      if ((mng_uint32)iQ < pBuf->iPLTEcount)
-      {                                /* put in intermediate row */
-        *pRGBArow     = pBuf->aPLTEentries [iQ].iRed;
-        *(pRGBArow+1) = pBuf->aPLTEentries [iQ].iGreen;
-        *(pRGBArow+2) = pBuf->aPLTEentries [iQ].iBlue;
-                                       /* transparency for this index ? */
-        if ((mng_uint32)iQ < pBuf->iTRNScount)
-          *(pRGBArow+3) = pBuf->aTRNSentries [iQ];
-        else
-          *(pRGBArow+3) = 0xFF;
-      }
-      else
-        MNG_ERROR (pData, MNG_PLTEINDEXERROR);
-
-      pWorkrow++;                      /* next pixel */
-      pRGBArow += 4;
-    }
-  }
-  else
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      iQ = *pWorkrow;                  /* get the index */
-                                       /* is it valid ? */
-      if ((mng_uint32)iQ < pBuf->iPLTEcount)
-      {                                /* put in intermediate row */
-        *pRGBArow     = pBuf->aPLTEentries [iQ].iRed;
-        *(pRGBArow+1) = pBuf->aPLTEentries [iQ].iGreen;
-        *(pRGBArow+2) = pBuf->aPLTEentries [iQ].iBlue;
-        *(pRGBArow+3) = 0xFF;
-      }
-      else
-        MNG_ERROR (pData, MNG_PLTEINDEXERROR);
-
-      pWorkrow++;                      /* next pixel */
-      pRGBArow += 4;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RETRIEVE_IDX8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_retrieve_ga8 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pRGBArow;
-  mng_int32      iX;
-  mng_uint8      iG;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RETRIEVE_GA8, MNG_LC_START);
-#endif
-
-  pRGBArow = pData->pRGBArow;          /* temporary work pointers */
-  pWorkrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize);
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    iG = *pWorkrow;                    /* get the gray-value */
-    *pRGBArow     = iG;                /* put in intermediate row */
-    *(pRGBArow+1) = iG;
-    *(pRGBArow+2) = iG;
-    *(pRGBArow+3) = *(pWorkrow+1);
-
-    pWorkrow += 2;                     /* next pixel */
-    pRGBArow += 4;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RETRIEVE_GA8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_retrieve_ga16 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pRGBArow;
-  mng_int32      iX;
-  mng_uint16     iG;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RETRIEVE_GA16, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pRGBArow = pData->pRGBArow;
-  pWorkrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize);
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    iG = mng_get_uint16 (pWorkrow);    /* get the gray-value */
-
-    mng_put_uint16 (pRGBArow,   iG);   /* and put in intermediate row */
-    mng_put_uint16 (pRGBArow+2, iG);
-    mng_put_uint16 (pRGBArow+4, iG);
-    mng_put_uint16 (pRGBArow+6, mng_get_uint16 (pWorkrow+2));
-
-    pWorkrow += 4;                     /* next pixel */
-    pRGBArow += 8;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RETRIEVE_GA16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_retrieve_rgba8 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pRGBArow;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RETRIEVE_RGBA8, MNG_LC_START);
-#endif
-
-  pRGBArow = pData->pRGBArow;          /* temporary work pointers */
-  pWorkrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize);
-                                       /* can't be easier than this ! */
-  MNG_COPY (pRGBArow, pWorkrow, pBuf->iRowsize);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RETRIEVE_RGBA8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_retrieve_rgba16 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pRGBArow;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RETRIEVE_RGBA16, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pRGBArow = pData->pRGBArow;
-  pWorkrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize);
-                                       /* can't be easier than this ! */
-  MNG_COPY (pRGBArow, pWorkrow, pBuf->iRowsize);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RETRIEVE_RGBA16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Row storage routines - store processed & uncompressed row-data         * */
-/* * into the current "object"                                              * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-mng_retcode mng_store_g1 (mng_datap pData)
-{
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-  mng_uint8      iB;
-  mng_uint8      iM;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_G1, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize);
-  iM       = 0;                        /* start at pixel 0 */
-  iB       = 0;
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    if (!iM)                           /* mask underflow ? */
-    {
-      iB = *pWorkrow;                  /* get next input-byte */
-      pWorkrow++;
-      iM = 0x80;
-    }
-
-    if (iB & iM)                       /* is it white ? */
-      *pOutrow = 0x01;                 /* white */
-    else
-      *pOutrow = 0x00;                 /* black */
-
-    pOutrow += pData->iColinc;         /* next pixel */
-    iM >>=  1;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_G1, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_store_g2 (mng_datap pData)
-{
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-  mng_uint8      iB;
-  mng_uint8      iM;
-  mng_uint32     iS;
-  mng_uint8      iQ;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_G2, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize);
-  iM       = 0;                        /* start at pixel 0 */
-  iB       = 0;
-  iS       = 0;
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    if (!iM)                           /* mask underflow ? */
-    {
-      iB = *pWorkrow;                  /* get next input-byte */
-      pWorkrow++;
-      iM = 0xC0;
-      iS = 6;
-    }
-
-    iQ = (mng_uint8)((iB & iM) >> iS); /* get the gray level */
-    *pOutrow = iQ;                     /* put in object buffer */
-
-    pOutrow += pData->iColinc;         /* next pixel */
-    iM >>=  2;
-    iS -= 2;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_G2, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_store_g4 (mng_datap pData)
-{
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-  mng_uint8      iB;
-  mng_uint8      iM;
-  mng_uint32     iS;
-  mng_uint8      iQ;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_G4, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize);
-  iM       = 0;                        /* start at pixel 0 */
-  iB       = 0;
-  iS       = 0;
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    if (!iM)                           /* mask underflow ? */
-    {
-      iB = *pWorkrow;                  /* get next input-byte */
-      pWorkrow++;
-      iM = 0xF0;
-      iS = 4;
-    }
-
-    iQ = (mng_uint8)((iB & iM) >> iS); /* get the gray level */
-    *pOutrow = iQ;                     /* put in object buffer */
-
-    pOutrow += pData->iColinc;         /* next pixel */
-    iM >>=  4;
-    iS -= 4;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_G4, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_store_g8 (mng_datap pData)
-{
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_G8, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize);
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *pOutrow = *pWorkrow;              /* put in object buffer */
-
-    pOutrow += pData->iColinc;         /* next pixel */
-    pWorkrow++;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_G8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_store_g16 (mng_datap pData)
-{
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_G16, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize);
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {                                    /* copy into object buffer */
-    mng_put_uint16 (pOutrow, mng_get_uint16 (pWorkrow));
-
-    pOutrow  += (pData->iColinc << 1); /* next pixel */
-    pWorkrow += 2;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_G16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_store_rgb8 (mng_datap pData)
-{
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_RGB8, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize);
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *pOutrow     = *pWorkrow;          /* copy the RGB bytes */
-    *(pOutrow+1) = *(pWorkrow+1);
-    *(pOutrow+2) = *(pWorkrow+2);
-
-    pWorkrow += 3;                     /* next pixel */
-    pOutrow  += (pData->iColinc * 3);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_RGB8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_store_rgb16 (mng_datap pData)
-{
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_RGB16, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize);
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    MNG_COPY (pOutrow, pWorkrow, 6);   /* copy the RGB bytes */
-
-    pWorkrow += 6;                     /* next pixel */
-    pOutrow  += (pData->iColinc * 6);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_RGB16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-mng_retcode mng_store_idx1 (mng_datap pData)
-{
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-  mng_uint8      iB;
-  mng_uint8      iM;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_IDX1, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize);
-  iM       = 0;                        /* start at pixel 0 */
-  iB       = 0;
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    if (!iM)                           /* mask underflow ? */
-    {
-      iB = *pWorkrow;                  /* get next input-byte */
-      pWorkrow++;
-      iM = 0x80;
-    }
-
-    if (iB & iM)                       /* store the index */
-      *pOutrow = 0x01;
-    else
-      *pOutrow = 0x00;
-
-    pOutrow += pData->iColinc;         /* next pixel */
-    iM >>=  1;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_IDX1, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_store_idx2 (mng_datap pData)
-{
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-  mng_uint8      iB;
-  mng_uint8      iM;
-  mng_uint32     iS;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_IDX2, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize);
-  iM       = 0;                        /* start at pixel 0 */
-  iB       = 0;
-  iS       = 0;
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    if (!iM)                           /* mask underflow ? */
-    {
-      iB = *pWorkrow;                  /* get next input-byte */
-      pWorkrow++;
-      iM = 0xC0;
-      iS = 6;
-    }
-                                       /* store the index */
-    *pOutrow = (mng_uint8)((iB & iM) >> iS);
-
-    pOutrow += pData->iColinc;         /* next pixel */
-    iM >>=  2;
-    iS -= 2;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_IDX2, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_store_idx4 (mng_datap pData)
-{
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-  mng_uint8      iB;
-  mng_uint8      iM;
-  mng_uint32     iS;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_IDX4, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize);
-  iM       = 0;                        /* start at pixel 0 */
-  iB       = 0;
-  iS       = 0;
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    if (!iM)                           /* mask underflow ? */
-    {
-      iB = *pWorkrow;                  /* get next input-byte */
-      pWorkrow++;
-      iM = 0xF0;
-      iS = 4;
-    }
-                                       /* store the index */
-    *pOutrow = (mng_uint8)((iB & iM) >> iS);
-
-    pOutrow += pData->iColinc;         /* next pixel */
-    iM >>=  4;
-    iS -= 4;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_IDX4, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_store_idx8 (mng_datap pData)
-{
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_IDX8, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize);
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *pOutrow = *pWorkrow;              /* put in object buffer */
-
-    pOutrow += pData->iColinc;         /* next pixel */
-    pWorkrow++;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_IDX8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_store_ga8 (mng_datap pData)
-{
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_GA8, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize);
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *pOutrow     = *pWorkrow;          /* copy the GA bytes */
-    *(pOutrow+1) = *(pWorkrow+1);
-
-    pWorkrow += 2;                     /* next pixel */
-    pOutrow  += (pData->iColinc << 1);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_GA8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_store_ga16 (mng_datap pData)
-{
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_GA16, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize);
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    MNG_COPY (pOutrow, pWorkrow, 4);   /* copy the GA bytes */
-
-    pWorkrow += 4;                     /* next pixel */
-    pOutrow  += (pData->iColinc << 2);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_GA16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_store_rgba8 (mng_datap pData)
-{
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_RGBA8, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize);
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *pOutrow     = *pWorkrow;          /* copy the RGBA bytes */
-    *(pOutrow+1) = *(pWorkrow+1);
-    *(pOutrow+2) = *(pWorkrow+2);
-    *(pOutrow+3) = *(pWorkrow+3);
-
-    pWorkrow += 4;                     /* next pixel */
-    pOutrow  += (pData->iColinc << 2);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_RGBA8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_store_rgba16 (mng_datap pData)
-{
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_RGBA16, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize);
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    MNG_COPY (pOutrow, pWorkrow, 8);   /* copy the RGBA bytes */
-
-    pWorkrow += 8;                     /* next pixel */
-    pOutrow  += (pData->iColinc << 3);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_RGBA16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Row storage routines (JPEG) - store processed & uncompressed row-data  * */
-/* * into the current "object"                                              * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-
-/* ************************************************************************** */
-
-mng_retcode mng_store_jpeg_g8 (mng_datap pData)
-{
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8, MNG_LC_START);
-#endif
-
-  pWorkrow = pData->pJPEGrow;          /* temporary work pointers */
-  pOutrow  = pBuf->pImgdata + (pData->iJPEGrow * pBuf->iRowsize);
-                                       /* easy as pie ... */
-  MNG_COPY (pOutrow, pWorkrow, pData->iRowsamples);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8, MNG_LC_END);
-#endif
-
-  return mng_next_jpeg_row (pData);    /* we've got one more row of gray-samples */
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_store_jpeg_rgb8 (mng_datap pData)
-{
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-#if RGB_PIXELSIZE != 3
-  mng_int32      iX;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8, MNG_LC_START);
-#endif
-
-  pWorkrow = pData->pJPEGrow;          /* temporary work pointers */
-  pOutrow  = pBuf->pImgdata + (pData->iJPEGrow * pBuf->iRowsize);
-
-#if RGB_PIXELSIZE == 3
-                                       /* easy as pie ... */
-  MNG_COPY (pOutrow, pWorkrow, pData->iRowsamples * 3);
-#else
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *pOutrow     = *pWorkrow;          /* copy pixel into object buffer */
-    *(pOutrow+1) = *(pWorkrow+1);
-    *(pOutrow+2) = *(pWorkrow+2);
-
-    pOutrow  += 3;                     /* next pixel */
-    pWorkrow += RGB_PIXELSIZE;
-  }
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8, MNG_LC_END);
-#endif
-
-  return mng_next_jpeg_row (pData);    /* we've got one more row of rgb-samples */
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_store_jpeg_ga8 (mng_datap pData)
-{
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_GA8, MNG_LC_START);
-#endif
-
-  pWorkrow = pData->pJPEGrow;          /* temporary work pointers */
-  pOutrow  = pBuf->pImgdata + (pData->iJPEGrow * pBuf->iRowsize);
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *pOutrow = *pWorkrow;              /* copy into object buffer */
-
-    pOutrow += 2;                      /* next pixel */
-    pWorkrow++;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_GA8, MNG_LC_END);
-#endif
-
-  return mng_next_jpeg_row (pData);    /* we've got one more row of gray-samples */
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_store_jpeg_rgba8 (mng_datap pData)
-{
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGBA8, MNG_LC_START);
-#endif
-
-  pWorkrow = pData->pJPEGrow;          /* temporary work pointers */
-  pOutrow  = pBuf->pImgdata + (pData->iJPEGrow * pBuf->iRowsize);
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *pOutrow     = *pWorkrow;          /* copy pixel into object buffer */
-    *(pOutrow+1) = *(pWorkrow+1);
-    *(pOutrow+2) = *(pWorkrow+2);
-
-    pOutrow  += 4;                     /* next pixel */
-    pWorkrow += RGB_PIXELSIZE;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGBA8, MNG_LC_END);
-#endif
-
-  return mng_next_jpeg_row (pData);    /* we've got one more row of rgb-samples */
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_store_jpeg_g8_alpha (mng_datap pData)
-{
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_ALPHA, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pJPEGrow2;
-  pOutrow  = pBuf->pImgdata + (pData->iJPEGalpharow * pBuf->iRowsize) + 1;
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *pOutrow = *pWorkrow;              /* put in object buffer */
-
-    pOutrow += 2;                      /* next pixel */
-    pWorkrow++;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_ALPHA, MNG_LC_END);
-#endif
-                                       /* we've got one more row of alpha-samples */
-  return mng_next_jpeg_alpharow (pData);
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_store_jpeg_rgb8_alpha (mng_datap pData)
-{
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_ALPHA, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pJPEGrow2;
-  pOutrow  = pBuf->pImgdata + (pData->iJPEGalpharow * pBuf->iRowsize) + 3;
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *pOutrow = *pWorkrow;              /* put in object buffer */
-
-    pOutrow += 4;                      /* next pixel */
-    pWorkrow++;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_ALPHA, MNG_LC_END);
-#endif
-                                       /* we've got one more row of alpha-samples */
-  return mng_next_jpeg_alpharow (pData);
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-mng_retcode mng_store_jpeg_g8_a1 (mng_datap pData)
-{
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-  mng_uint8      iB;
-  mng_uint8      iM;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_A1, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize) + 1;
-  iM       = 0;                        /* start at pixel 0 */
-  iB       = 0;
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    if (!iM)                           /* mask underflow ? */
-    {
-      iB = *pWorkrow;                  /* get next input-byte */
-      pWorkrow++;
-      iM = 0x80;
-    }
-
-    if (iB & iM)                       /* is it opaque ? */
-      *pOutrow = 0xFF;                 /* opaque */
-    else
-      *pOutrow = 0x00;                 /* transparent */
-
-    pOutrow += 2;                      /* next pixel */
-    iM >>=  1;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_A1, MNG_LC_END);
-#endif
-                                       /* we've got one more row of alpha-samples */
-  return mng_next_jpeg_alpharow (pData);
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_store_jpeg_g8_a2 (mng_datap pData)
-{
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-  mng_uint8      iB;
-  mng_uint8      iM;
-  mng_uint32     iS;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_A2, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize) + 1;
-  iM       = 0;                        /* start at pixel 0 */
-  iB       = 0;
-  iS       = 0;
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    if (!iM)                           /* mask underflow ? */
-    {
-      iB = *pWorkrow;                  /* get next input-byte */
-      pWorkrow++;
-      iM = 0xC0;
-      iS = 6;
-    }
-
-#ifdef MNG_OPTIMIZE_FOOTPRINT_SWITCH
-    {
-      const mng_uint8  alpha_level[4] = { 0x00, 0x55, 0xAA, 0xFF};
-        *pOutrow = alpha_level[((iB & iM) >> iS)] ;
-    }
-#else
-    switch ((iB & iM) >> iS)           /* determine the alpha level */
-    {
-      case 0x03 : { *pOutrow = 0xFF; break; }
-      case 0x02 : { *pOutrow = 0xAA; break; }
-      case 0x01 : { *pOutrow = 0x55; break; }
-      default   : { *pOutrow = 0x00; }
-    }
-#endif
-
-    pOutrow += 2;                      /* next pixel */
-    iM >>=  2;
-    iS -= 2;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_A2, MNG_LC_END);
-#endif
-                                       /* we've got one more row of alpha-samples */
-  return mng_next_jpeg_alpharow (pData);
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_store_jpeg_g8_a4 (mng_datap pData)
-{
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-  mng_uint8      iB;
-  mng_uint8      iM;
-  mng_uint32     iS;
-  mng_uint8      iQ;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_A4, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize) + 1;
-  iM       = 0;                        /* start at pixel 0 */
-  iB       = 0;
-  iS       = 0;
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    if (!iM)                           /* mask underflow ? */
-    {
-      iB = *pWorkrow;                  /* get next input-byte */
-      pWorkrow++;
-      iM = 0xF0;
-      iS = 4;
-    }
-                                       /* get the alpha level */
-    iQ = (mng_uint8)((iB & iM) >> iS);
-    iQ = (mng_uint8)(iQ + (iQ << 4));  /* expand to 8-bit by replication */
-
-    *pOutrow = iQ;                     /* put in object buffer */
-
-    pOutrow += 2;                      /* next pixel */
-    iM >>=  4;
-    iS -= 4;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_A4, MNG_LC_END);
-#endif
-                                       /* we've got one more row of alpha-samples */
-  return mng_next_jpeg_alpharow (pData);
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_store_jpeg_g8_a8 (mng_datap pData)
-{
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_A8, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize) + 1;
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *pOutrow = *pWorkrow;              /* put in object buffer */
-
-    pOutrow += 2;                      /* next pixel */
-    pWorkrow++;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_A8, MNG_LC_END);
-#endif
-                                       /* we've got one more row of alpha-samples */
-  return mng_next_jpeg_alpharow (pData);
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_store_jpeg_g8_a16 (mng_datap pData)
-{
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_A16, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize) + 1;
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *pOutrow = *pWorkrow;              /* only high-order byte! */
-
-    pOutrow  += 2;                     /* next pixel */
-    pWorkrow += 2;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_A16, MNG_LC_END);
-#endif
-                                       /* we've got one more row of alpha-samples */
-  return mng_next_jpeg_alpharow (pData);
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-mng_retcode mng_store_jpeg_rgb8_a1 (mng_datap pData)
-{
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-  mng_uint8      iB;
-  mng_uint8      iM;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_A1, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize) + 3;
-  iM       = 0;                        /* start at pixel 0 */
-  iB       = 0;
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    if (!iM)                           /* mask underflow ? */
-    {
-      iB = *pWorkrow;                  /* get next input-byte */
-      pWorkrow++;
-      iM = 0x80;
-    }
-
-    if (iB & iM)                       /* is it opaque ? */
-      *pOutrow = 0xFF;                 /* opaque */
-    else
-      *pOutrow = 0x00;                 /* transparent */
-
-    pOutrow += 4;                      /* next pixel */
-    iM >>=  1;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_A1, MNG_LC_END);
-#endif
-                                       /* we've got one more row of alpha-samples */
-  return mng_next_jpeg_alpharow (pData);
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_store_jpeg_rgb8_a2 (mng_datap pData)
-{
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-  mng_uint8      iB;
-  mng_uint8      iM;
-  mng_uint32     iS;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_A2, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize) + 3;
-  iM       = 0;                        /* start at pixel 0 */
-  iB       = 0;
-  iS       = 0;
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    if (!iM)                           /* mask underflow ? */
-    {
-      iB = *pWorkrow;                  /* get next input-byte */
-      pWorkrow++;
-      iM = 0xC0;
-      iS = 6;
-    }
-
-#ifdef MNG_OPTIMIZE_FOOTPRINT_SWITCH
-    {
-      const mng_uint8  alpha_level[4] = { 0x00, 0x55, 0xAA, 0xFF};
-      *pOutrow = alpha_level[((iB & iM) >> iS)] ;
-    }
-#else
-    switch ((iB & iM) >> iS)           /* determine the alpha level */
-    {
-      case 0x03 : { *pOutrow = 0xFF; break; }
-      case 0x02 : { *pOutrow = 0xAA; break; }
-      case 0x01 : { *pOutrow = 0x55; break; }
-      default   : { *pOutrow = 0x00; }
-    }
-#endif
-
-    pOutrow += 4;                      /* next pixel */
-    iM >>=  2;
-    iS -= 2;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_A2, MNG_LC_END);
-#endif
-                                       /* we've got one more row of alpha-samples */
-  return mng_next_jpeg_alpharow (pData);
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_store_jpeg_rgb8_a4 (mng_datap pData)
-{
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-  mng_uint8      iB;
-  mng_uint8      iM;
-  mng_uint32     iS;
-  mng_uint8      iQ;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_A4, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize) + 3;
-  iM       = 0;                        /* start at pixel 0 */
-  iB       = 0;
-  iS       = 0;
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    if (!iM)                           /* mask underflow ? */
-    {
-      iB = *pWorkrow;                  /* get next input-byte */
-      pWorkrow++;
-      iM = 0xF0;
-      iS = 4;
-    }
-                                       /* get the alpha level */
-    iQ = (mng_uint8)((iB & iM) >> iS);
-    iQ = (mng_uint8)(iQ + (iQ << 4));  /* expand to 8-bit by replication */
-
-    *pOutrow = iQ;                     /* put in object buffer */
-
-    pOutrow += 4;                      /* next pixel */
-    iM >>=  4;
-    iS -= 4;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_A4, MNG_LC_END);
-#endif
-                                       /* we've got one more row of alpha-samples */
-  return mng_next_jpeg_alpharow (pData);
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_store_jpeg_rgb8_a8 (mng_datap pData)
-{
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_A8, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize) + 3;
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *pOutrow = *pWorkrow;              /* put in buffer */
-
-    pOutrow += 4;                      /* next pixel */
-    pWorkrow++;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_A8, MNG_LC_END);
-#endif
-                                       /* we've got one more row of alpha-samples */
-  return mng_next_jpeg_alpharow (pData);
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_store_jpeg_rgb8_a16 (mng_datap pData)
-{
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_A16, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize) + 3;
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *pOutrow = *pWorkrow;              /* only high-order byte */
-
-    pOutrow  += 4;                     /* next pixel */
-    pWorkrow += 2;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_A16, MNG_LC_END);
-#endif
-                                       /* we've got one more row of alpha-samples */
-  return mng_next_jpeg_alpharow (pData);
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_JPEG12
-mng_retcode mng_store_jpeg_g12_a1 (mng_datap pData)
-{
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-  mng_uint8      iB;
-  mng_uint8      iM;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_G12_A1, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize) + 2;
-  iM       = 0;                        /* start at pixel 0 */
-  iB       = 0;
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    if (!iM)                           /* mask underflow ? */
-    {
-      iB = *pWorkrow;                  /* get next input-byte */
-      pWorkrow++;
-      iM = 0x80;
-    }
-
-    if (iB & iM)                       /* opaque ? */
-      mng_put_uint16 (pOutrow, 0xFFFF);/* opaque */
-    else
-      mng_put_uint16 (pOutrow, 0x0000);/* transparent */
-
-    pOutrow += 4;                      /* next pixel */
-    iM >>=  1;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_G12_A1, MNG_LC_END);
-#endif
-                                       /* we've got one more row of alpha-samples */
-  return mng_next_jpeg_alpharow (pData);
-}
-#endif /* MNG_SUPPORT_JPEG12 */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_JPEG12
-mng_retcode mng_store_jpeg_g12_a2 (mng_datap pData)
-{
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-  mng_uint8      iB;
-  mng_uint8      iM;
-  mng_uint32     iS;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_G12_A2, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize) + 2;
-  iM       = 0;                        /* start at pixel 0 */
-  iB       = 0;
-  iS       = 0;
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    if (!iM)                           /* mask underflow ? */
-    {
-      iB = *pWorkrow;                  /* get next input-byte */
-      pWorkrow++;
-      iM = 0xC0;
-      iS = 6;
-    }
-
-#ifdef MNG_OPTIMIZE_FOOTPRINT_SWITCH
-    {
-      const mng_uint16  gray_level[4] = { 0x0000, 0x5555, 0xAAAA, 0xFFFF};
-      mng_put_uint16 (pOutrow, gray_level[((iB & iM) >> iS)]) ;
-    }
-#else
-    switch ((iB & iM) >> iS)           /* determine the gray level */
-    {
-      case 0x03 : { mng_put_uint16 (pOutrow, 0xFFFF); break; }
-      case 0x02 : { mng_put_uint16 (pOutrow, 0xAAAA); break; }
-      case 0x01 : { mng_put_uint16 (pOutrow, 0x5555); break; }
-      default   : { mng_put_uint16 (pOutrow, 0x0000); }
-    }
-#endif
-
-    pOutrow += 4;                      /* next pixel */
-    iM >>=  2;
-    iS -= 2;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_G12_A2, MNG_LC_END);
-#endif
-                                       /* we've got one more row of alpha-samples */
-  return mng_next_jpeg_alpharow (pData);
-}
-#endif /* MNG_SUPPORT_JPEG12 */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_JPEG12
-mng_retcode mng_store_jpeg_g12_a4 (mng_datap pData)
-{
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-  mng_uint8      iB;
-  mng_uint8      iM;
-  mng_uint32     iS;
-  mng_uint16     iQ;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_G12_A4, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize) + 2;
-  iM       = 0;                        /* start at pixel 0 */
-  iB       = 0;
-  iS       = 0;
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    if (!iM)                           /* mask underflow ? */
-    {
-      iB = *pWorkrow;                  /* get next input-byte */
-      pWorkrow++;
-      iM = 0xF0;
-      iS = 4;
-    }
-                                       /* get the gray level */
-    iQ = (mng_uint16)((iB & iM) >> iS);
-    iQ = (mng_uint16)(iQ + (iQ << 4)); /* expand to 16-bit by replication */
-    iQ = (mng_uint16)(iQ + (iQ << 8));
-                                       /* put in object buffer */
-    mng_put_uint16 (pOutrow, iQ);
-
-    pOutrow += 4;                      /* next pixel */
-    iM >>=  4;
-    iS -= 4;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_G12_A4, MNG_LC_END);
-#endif
-                                       /* we've got one more row of alpha-samples */
-  return mng_next_jpeg_alpharow (pData);
-}
-#endif /* MNG_SUPPORT_JPEG12 */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_JPEG12
-mng_retcode mng_store_jpeg_g12_a8 (mng_datap pData)
-{
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-  mng_uint16     iW;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_G12_A8, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize) + 2;
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    iW = (mng_uint16)(*pWorkrow);      /* get input byte */
-    iW = (mng_uint16)(iW + (iW << 8)); /* expand to 16-bit by replication */
-
-    mng_put_uint16 (pOutrow, iW);      /* put in object buffer */
-
-    pOutrow += 4;                      /* next pixel */
-    pWorkrow++;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_G12_A8, MNG_LC_END);
-#endif
-                                       /* we've got one more row of alpha-samples */
-  return mng_next_jpeg_alpharow (pData);
-}
-#endif /* MNG_SUPPORT_JPEG12 */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_JPEG12
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_store_jpeg_g12_a16 (mng_datap pData)
-{
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_G12_A16, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize) + 2;
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {                                    /* copy it */
-    mng_put_uint16 (pOutrow, mng_get_uint16 (pWorkrow));
-
-    pOutrow  += 4;                     /* next pixel */
-    pWorkrow += 2;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_STORE_JPEG_G12_A16, MNG_LC_END);
-#endif
-                                       /* we've got one more row of alpha-samples */
-  return mng_next_jpeg_alpharow (pData);
-}
-#endif
-#endif /* MNG_SUPPORT_JPEG12 */
-
-/* ************************************************************************** */
-
-#endif /* MNG_INCLUDE_JNG */
-
-#ifndef MNG_NO_DELTA_PNG
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Delta-image row routines - apply the processed & uncompressed row-data * */
-/* * onto the target "object"                                               * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-mng_retcode mng_delta_g1 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-  mng_uint8      iB;
-  mng_uint8      iM;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_G1, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow         * pBuf->iRowsize   ) +
-                              (pData->iDeltaBlocky * pBuf->iRowsize   ) +
-                              (pData->iCol         * pBuf->iSamplesize) +
-                              (pData->iDeltaBlockx * pBuf->iSamplesize);
-  iM       = 0;                        /* start at pixel 0 */
-  iB       = 0;
-                                       /* pixel replace ? */
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      if (!iM)                         /* mask underflow ? */
-      {
-        iB = *pWorkrow;                /* get next input-byte */
-        pWorkrow++;
-        iM = 0x80;
-      }
-
-      if (iB & iM)                     /* is it white ? */
-        *pOutrow = 0xFF;               /* white */
-      else
-        *pOutrow = 0x00;               /* black */
-
-      pOutrow += pData->iColinc;       /* next pixel */
-      iM >>=  1;
-    }
-  }
-  else
-  {                                    /* pixel add ! */
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      if (!iM)                         /* mask underflow ? */
-      {
-        iB = *pWorkrow;                /* get next input-byte */
-        pWorkrow++;
-        iM = 0x80;
-      }
-
-      if (iB & iM)                     /* invert if it is white ? */
-        *pOutrow = (mng_uint8)(*pOutrow ^ 0xFF);
-
-      pOutrow += pData->iColinc;       /* next pixel */
-      iM >>=  1;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_G1, MNG_LC_END);
-#endif
-
-  return mng_store_g1 (pData);
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_delta_g2 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-  mng_uint8      iB;
-  mng_uint8      iM;
-  mng_uint32     iS;
-#ifdef MNG_OPTIMIZE_FOOTPRINT_SWITCH
-  const mng_uint8  level[4] = { 0x00, 0x55, 0xAA, 0xFF};
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_G2, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow         * pBuf->iRowsize   ) +
-                              (pData->iDeltaBlocky * pBuf->iRowsize   ) +
-                              (pData->iCol         * pBuf->iSamplesize) +
-                              (pData->iDeltaBlockx * pBuf->iSamplesize);
-  iM       = 0;                        /* start at pixel 0 */
-  iB       = 0;
-  iS       = 0;
-                                       /* pixel replace ? */
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      if (!iM)                         /* mask underflow ? */
-      {
-        iB = *pWorkrow;                /* get next input-byte */
-        pWorkrow++;
-        iM = 0xC0;
-        iS = 6;
-      }
-
-#ifdef MNG_OPTIMIZE_FOOTPRINT_SWITCH
-    *pOutrow = level[((iB & iM) >> iS)] ;
-#else
-    switch ((iB & iM) >> iS)           /* determine the alpha level */
-    {
-      case 0x03 : { *pOutrow = 0xFF; break; }
-      case 0x02 : { *pOutrow = 0xAA; break; }
-      case 0x01 : { *pOutrow = 0x55; break; }
-      default   : { *pOutrow = 0x00; }
-    }
-#endif
-
-      pOutrow += pData->iColinc;       /* next pixel */
-      iM >>=  2;
-      iS -= 2;
-    }
-  }
-  else
-  {                                    /* pixel add ! */
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      if (!iM)                         /* mask underflow ? */
-      {
-        iB = *pWorkrow;                /* get next input-byte */
-        pWorkrow++;
-        iM = 0xC0;
-        iS = 6;
-      }
-
-#ifdef MNG_OPTIMIZE_FOOTPRINT_SWITCH
-      *pOutrow = level[((*pOutrow >> 6) + ((iB & iM) >> iS)) & 0x03] ;
-#else
-      switch (((*pOutrow >> 6) + ((iB & iM) >> iS)) & 0x03)
-      {
-        case 0x03 : { *pOutrow = 0xFF; break; }
-        case 0x02 : { *pOutrow = 0xAA; break; }
-        case 0x01 : { *pOutrow = 0x55; break; }
-        default   : { *pOutrow = 0x00; }
-      }
-#endif
-
-      pOutrow += pData->iColinc;       /* next pixel */
-      iM >>=  2;
-      iS -= 2;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_G2, MNG_LC_END);
-#endif
-
-  return mng_store_g2 (pData);
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_delta_g4 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-  mng_uint8      iB;
-  mng_uint8      iM;
-  mng_uint32     iS;
-  mng_uint8      iQ;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_G4, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow         * pBuf->iRowsize   ) +
-                              (pData->iDeltaBlocky * pBuf->iRowsize   ) +
-                              (pData->iCol         * pBuf->iSamplesize) +
-                              (pData->iDeltaBlockx * pBuf->iSamplesize);
-  iM       = 0;                        /* start at pixel 0 */
-  iB       = 0;
-  iS       = 0;
-                                       /* pixel replace ? */
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      if (!iM)                         /* mask underflow ? */
-      {
-        iB = *pWorkrow;                /* get next input-byte */
-        pWorkrow++;
-        iM = 0xF0;
-        iS = 4;
-      }
-                                       /* get the gray level */
-      iQ = (mng_uint8)((iB & iM) >> iS);
-                                       /* expand to 8-bit by replication */
-      iQ = (mng_uint8)(iQ + (iQ << 4));
-
-      *pOutrow = iQ;                   /* put in object buffer */
-
-      pOutrow += pData->iColinc;       /* next pixel */
-      iM >>=  4;
-      iS -= 4;
-    }
-  }
-  else
-  {                                    /* pixel add ! */
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      if (!iM)                         /* mask underflow ? */
-      {
-        iB = *pWorkrow;                /* get next input-byte */
-        pWorkrow++;
-        iM = 0xF0;
-        iS = 4;
-      }
-                                       /* get the gray level */
-      iQ = (mng_uint8)(((*pOutrow >> 4) + ((iB & iM) >> iS)) & 0x0F);
-                                       /* expand to 8-bit by replication */
-      iQ = (mng_uint8)(iQ + (iQ << 4));
-
-      *pOutrow = iQ;                   /* put in object buffer */
-
-      pOutrow += pData->iColinc;       /* next pixel */
-      iM >>=  4;
-      iS -= 4;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_G4, MNG_LC_END);
-#endif
-
-  return mng_store_g4 (pData);
-}
-#endif /* MNG_NO_1_2_4BIT_SUPPORT */
-
-/* ************************************************************************** */
-
-mng_retcode mng_delta_g8 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_G8, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow         * pBuf->iRowsize   ) +
-                              (pData->iDeltaBlocky * pBuf->iRowsize   ) +
-                              (pData->iCol         * pBuf->iSamplesize) +
-                              (pData->iDeltaBlockx * pBuf->iSamplesize);
-                                       /* pixel replace ? */
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      *pOutrow = *pWorkrow;            /* put in object buffer */
-
-      pOutrow += pData->iColinc;       /* next pixel */
-      pWorkrow++;
-    }
-  }
-  else
-  {                                    /* pixel add ! */
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {                                  /* add to object buffer */
-      *pOutrow = (mng_uint8)(*pOutrow + *pWorkrow);
-
-      pOutrow += pData->iColinc;       /* next pixel */
-      pWorkrow++;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_G8, MNG_LC_END);
-#endif
-
-  return mng_store_g8 (pData);
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_delta_g16 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_G16, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow         * pBuf->iRowsize   ) +
-                              (pData->iDeltaBlocky * pBuf->iRowsize   ) +
-                              (pData->iCol         * pBuf->iSamplesize) +
-                              (pData->iDeltaBlockx * pBuf->iSamplesize);
-                                       /* pixel replace ? */
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      *pOutrow     = *pWorkrow;        /* put in object buffer */
-      *(pOutrow+1) = *(pWorkrow+1);
-                                       /* next pixel */
-      pOutrow  += (pData->iColinc << 1);
-      pWorkrow += 2;
-    }
-  }
-  else
-  {                                    /* pixel add ! */
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {                                  /* add to object buffer */
-      mng_put_uint16 (pOutrow, (mng_uint16)(mng_get_uint16 (pOutrow ) +
-                                            mng_get_uint16 (pWorkrow)   ));
-                                       /* next pixel */
-      pOutrow  += (pData->iColinc << 1);
-      pWorkrow += 2;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_G16, MNG_LC_END);
-#endif
-
-  return mng_store_g16 (pData);
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_delta_rgb8 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_RGB8, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow         * pBuf->iRowsize   ) +
-                              (pData->iDeltaBlocky * pBuf->iRowsize   ) +
-                              (pData->iCol         * pBuf->iSamplesize) +
-                              (pData->iDeltaBlockx * pBuf->iSamplesize);
-                                       /* pixel replace ? */
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      *pOutrow     = *pWorkrow;        /* put in object buffer */
-      *(pOutrow+1) = *(pWorkrow+1);
-      *(pOutrow+2) = *(pWorkrow+2);
-                                       /* next pixel */
-      pOutrow  += (pData->iColinc * 3);
-      pWorkrow += 3;
-    }
-  }
-  else
-  {                                    /* pixel add ! */
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {                                  /* add to object buffer */
-      *pOutrow     = (mng_uint8)(*pOutrow     + *pWorkrow    );
-      *(pOutrow+1) = (mng_uint8)(*(pOutrow+1) + *(pWorkrow+1));
-      *(pOutrow+2) = (mng_uint8)(*(pOutrow+2) + *(pWorkrow+2));
-                                       /* next pixel */
-      pOutrow  += (pData->iColinc * 3);
-      pWorkrow += 3;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_RGB8, MNG_LC_END);
-#endif
-
-  return mng_store_rgb8 (pData);
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_delta_rgb16 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_RGB16, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow         * pBuf->iRowsize   ) +
-                              (pData->iDeltaBlocky * pBuf->iRowsize   ) +
-                              (pData->iCol         * pBuf->iSamplesize) +
-                              (pData->iDeltaBlockx * pBuf->iSamplesize);
-                                       /* pixel replace ? */
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      *pOutrow     = *pWorkrow;        /* put in object buffer */
-      *(pOutrow+1) = *(pWorkrow+1);
-      *(pOutrow+2) = *(pWorkrow+2);
-      *(pOutrow+3) = *(pWorkrow+3);
-      *(pOutrow+4) = *(pWorkrow+4);
-      *(pOutrow+5) = *(pWorkrow+5);
-                                       /* next pixel */
-      pOutrow  += (pData->iColinc * 6);
-      pWorkrow += 6;
-    }
-  }
-  else
-  {                                    /* pixel add ! */
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {                                  /* add to object buffer */
-      mng_put_uint16 (pOutrow,   (mng_uint16)(mng_get_uint16 (pOutrow   ) +
-                                              mng_get_uint16 (pWorkrow  )   ));
-      mng_put_uint16 (pOutrow+2, (mng_uint16)(mng_get_uint16 (pOutrow+2 ) +
-                                              mng_get_uint16 (pWorkrow+2)   ));
-      mng_put_uint16 (pOutrow+4, (mng_uint16)(mng_get_uint16 (pOutrow+4 ) +
-                                              mng_get_uint16 (pWorkrow+4)   ));
-                                       /* next pixel */
-      pOutrow  += (pData->iColinc * 6);
-      pWorkrow += 6;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_RGB16, MNG_LC_END);
-#endif
-
-  return mng_store_rgb16 (pData);
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-mng_retcode mng_delta_idx1 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-  mng_uint8      iB;
-  mng_uint8      iM;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_IDX1, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow         * pBuf->iRowsize   ) +
-                              (pData->iDeltaBlocky * pBuf->iRowsize   ) +
-                              (pData->iCol         * pBuf->iSamplesize) +
-                              (pData->iDeltaBlockx * pBuf->iSamplesize);
-  iM       = 0;                        /* start at pixel 0 */
-  iB       = 0;
-                                       /* pixel replace ? */
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      if (!iM)                         /* mask underflow ? */
-      {
-        iB = *pWorkrow;                /* get next input-byte */
-        pWorkrow++;
-        iM = 0x80;
-      }
-
-      if (iB & iM)                     /* put the right index value */
-        *pOutrow = 1;
-      else
-        *pOutrow = 0;
-
-      pOutrow += pData->iColinc;       /* next pixel */
-      iM >>=  1;
-    }
-  }
-  else
-  {                                    /* pixel add ! */
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      if (!iM)                         /* mask underflow ? */
-      {
-        iB = *pWorkrow;                /* get next input-byte */
-        pWorkrow++;
-        iM = 0x80;
-      }
-
-      if (iB & iM)                     /* invert if it is non-zero index */
-        *pOutrow = (mng_uint8)(*pOutrow ^ 0x01);
-
-      pOutrow += pData->iColinc;       /* next pixel */
-      iM >>=  1;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_IDX1, MNG_LC_END);
-#endif
-
-  return mng_store_idx1 (pData);
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_delta_idx2 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-  mng_uint8      iB;
-  mng_uint8      iM;
-  mng_uint32     iS;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_IDX2, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow         * pBuf->iRowsize   ) +
-                              (pData->iDeltaBlocky * pBuf->iRowsize   ) +
-                              (pData->iCol         * pBuf->iSamplesize) +
-                              (pData->iDeltaBlockx * pBuf->iSamplesize);
-  iM       = 0;                        /* start at pixel 0 */
-  iB       = 0;
-  iS       = 0;
-                                       /* pixel replace ? */
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      if (!iM)                         /* mask underflow ? */
-      {
-        iB = *pWorkrow;                /* get next input-byte */
-        pWorkrow++;
-        iM = 0xC0;
-        iS = 6;
-      }
-                                       /* put the index */
-      *pOutrow = (mng_uint8)((iB & iM) >> iS);
-
-      pOutrow += pData->iColinc;       /* next pixel */
-      iM >>=  2;
-      iS -= 2;
-    }
-  }
-  else
-  {                                    /* pixel add ! */
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      if (!iM)                         /* mask underflow ? */
-      {
-        iB = *pWorkrow;                /* get next input-byte */
-        pWorkrow++;
-        iM = 0xC0;
-        iS = 6;
-      }
-                                       /* calculate the index */
-      *pOutrow = (mng_uint8)((*pOutrow + ((iB & iM) >> iS)) & 0x03);
-
-      pOutrow += pData->iColinc;       /* next pixel */
-      iM >>=  2;
-      iS -= 2;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_IDX2, MNG_LC_END);
-#endif
-
-  return mng_store_idx2 (pData);
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_delta_idx4 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-  mng_uint8      iB;
-  mng_uint8      iM;
-  mng_uint32     iS;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_IDX4, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow         * pBuf->iRowsize   ) +
-                              (pData->iDeltaBlocky * pBuf->iRowsize   ) +
-                              (pData->iCol         * pBuf->iSamplesize) +
-                              (pData->iDeltaBlockx * pBuf->iSamplesize);
-  iM       = 0;                        /* start at pixel 0 */
-  iB       = 0;
-  iS       = 0;
-                                       /* pixel replace ? */
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      if (!iM)                         /* mask underflow ? */
-      {
-        iB = *pWorkrow;                /* get next input-byte */
-        pWorkrow++;
-        iM = 0xF0;
-        iS = 4;
-      }
-                                       /* put the index */
-      *pOutrow = (mng_uint8)((iB & iM) >> iS);
-
-      pOutrow += pData->iColinc;       /* next pixel */
-      iM >>=  4;
-      iS -= 4;
-    }
-  }
-  else
-  {                                    /* pixel add ! */
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      if (!iM)                         /* mask underflow ? */
-      {
-        iB = *pWorkrow;                /* get next input-byte */
-        pWorkrow++;
-        iM = 0xF0;
-        iS = 4;
-      }
-                                       /* calculate the index */
-      *pOutrow = (mng_uint8)((*pOutrow + ((iB & iM) >> iS)) & 0x0F);
-
-      pOutrow += pData->iColinc;       /* next pixel */
-      iM >>=  4;
-      iS -= 4;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_IDX4, MNG_LC_END);
-#endif
-
-  return mng_store_idx4 (pData);
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_delta_idx8 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_IDX8, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow         * pBuf->iRowsize   ) +
-                              (pData->iDeltaBlocky * pBuf->iRowsize   ) +
-                              (pData->iCol         * pBuf->iSamplesize) +
-                              (pData->iDeltaBlockx * pBuf->iSamplesize);
-                                       /* pixel replace ? */
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      *pOutrow = *pWorkrow;            /* put in object buffer */
-
-      pOutrow += pData->iColinc;       /* next pixel */
-      pWorkrow++;
-    }
-  }
-  else
-  {                                    /* pixel add ! */
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {                                  /* add to object buffer */
-      *pOutrow = (mng_uint8)(*pOutrow + *pWorkrow);
-
-      pOutrow += pData->iColinc;       /* next pixel */
-      pWorkrow++;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_IDX8, MNG_LC_END);
-#endif
-
-  return mng_store_idx8 (pData);
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_delta_ga8 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_GA8, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow         * pBuf->iRowsize   ) +
-                              (pData->iDeltaBlocky * pBuf->iRowsize   ) +
-                              (pData->iCol         * pBuf->iSamplesize) +
-                              (pData->iDeltaBlockx * pBuf->iSamplesize);
-                                       /* pixel replace ? */
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      *pOutrow     = *pWorkrow;        /* put in object buffer */
-      *(pOutrow+1) = *(pWorkrow+1);
-                                       /* next pixel */
-      pOutrow  += (pData->iColinc << 1);
-      pWorkrow += 2;
-    }
-  }
-  else
-  {                                    /* pixel add ! */
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {                                  /* add to object buffer */
-      *pOutrow     = (mng_uint8)(*pOutrow     + *pWorkrow    );
-      *(pOutrow+1) = (mng_uint8)(*(pOutrow+1) + *(pWorkrow+1));
-                                       /* next pixel */
-      pOutrow  += (pData->iColinc << 1);
-      pWorkrow += 2;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_GA8, MNG_LC_END);
-#endif
-
-  return mng_store_ga8 (pData);
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_delta_ga16 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_GA16, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow         * pBuf->iRowsize   ) +
-                              (pData->iDeltaBlocky * pBuf->iRowsize   ) +
-                              (pData->iCol         * pBuf->iSamplesize) +
-                              (pData->iDeltaBlockx * pBuf->iSamplesize);
-                                       /* pixel replace ? */
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      *pOutrow     = *pWorkrow;        /* put in object buffer */
-      *(pOutrow+1) = *(pWorkrow+1);
-      *(pOutrow+2) = *(pWorkrow+2);
-      *(pOutrow+3) = *(pWorkrow+3);
-                                       /* next pixel */
-      pOutrow  += (pData->iColinc << 2);
-      pWorkrow += 4;
-    }
-  }
-  else
-  {                                    /* pixel add ! */
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {                                  /* add to object buffer */
-      mng_put_uint16 (pOutrow,   (mng_uint16)(mng_get_uint16 (pOutrow   ) +
-                                              mng_get_uint16 (pWorkrow  )   ));
-      mng_put_uint16 (pOutrow+2, (mng_uint16)(mng_get_uint16 (pOutrow+2 ) +
-                                              mng_get_uint16 (pWorkrow+2)   ));
-                                       /* next pixel */
-      pOutrow  += (pData->iColinc << 2);
-      pWorkrow += 4;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_GA16, MNG_LC_END);
-#endif
-
-  return mng_store_ga16 (pData);
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_delta_rgba8 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_RGBA8, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow         * pBuf->iRowsize   ) +
-                              (pData->iDeltaBlocky * pBuf->iRowsize   ) +
-                              (pData->iCol         * pBuf->iSamplesize) +
-                              (pData->iDeltaBlockx * pBuf->iSamplesize);
-                                       /* pixel replace ? */
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      *pOutrow     = *pWorkrow;        /* put in object buffer */
-      *(pOutrow+1) = *(pWorkrow+1);
-      *(pOutrow+2) = *(pWorkrow+2);
-      *(pOutrow+3) = *(pWorkrow+3);
-                                       /* next pixel */
-      pOutrow  += (pData->iColinc << 2);
-      pWorkrow += 4;
-    }
-  }
-  else
-  {                                    /* pixel add ! */
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {                                  /* add to object buffer */
-      *pOutrow     = (mng_uint8)(*pOutrow     + *pWorkrow    );
-      *(pOutrow+1) = (mng_uint8)(*(pOutrow+1) + *(pWorkrow+1));
-      *(pOutrow+2) = (mng_uint8)(*(pOutrow+2) + *(pWorkrow+2));
-      *(pOutrow+3) = (mng_uint8)(*(pOutrow+3) + *(pWorkrow+3));
-                                       /* next pixel */
-      pOutrow  += (pData->iColinc << 2);
-      pWorkrow += 4;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_RGBA8, MNG_LC_END);
-#endif
-
-  return mng_store_rgba8 (pData);
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_delta_rgba16 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_RGBA16, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pOutrow  = pBuf->pImgdata + (pData->iRow         * pBuf->iRowsize   ) +
-                              (pData->iDeltaBlocky * pBuf->iRowsize   ) +
-                              (pData->iCol         * pBuf->iSamplesize) +
-                              (pData->iDeltaBlockx * pBuf->iSamplesize);
-                                       /* pixel replace ? */
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      MNG_COPY (pOutrow, pWorkrow, 8); /* put in object buffer */
-                                       /* next pixel */
-      pOutrow  += (pData->iColinc << 3);
-      pWorkrow += 8;
-    }
-  }
-  else
-  {                                    /* pixel add ! */
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {                                  /* add to object buffer */
-      mng_put_uint16 (pOutrow,   (mng_uint16)(mng_get_uint16 (pOutrow   ) +
-                                              mng_get_uint16 (pWorkrow  )   ));
-      mng_put_uint16 (pOutrow+2, (mng_uint16)(mng_get_uint16 (pOutrow+2 ) +
-                                              mng_get_uint16 (pWorkrow+2)   ));
-      mng_put_uint16 (pOutrow+4, (mng_uint16)(mng_get_uint16 (pOutrow+4 ) +
-                                              mng_get_uint16 (pWorkrow+4)   ));
-      mng_put_uint16 (pOutrow+6, (mng_uint16)(mng_get_uint16 (pOutrow+6 ) +
-                                              mng_get_uint16 (pWorkrow+6)   ));
-                                       /* next pixel */
-      pOutrow  += (pData->iColinc << 3);
-      pWorkrow += 8;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_RGBA16, MNG_LC_END);
-#endif
-
-  return mng_store_rgba16 (pData);
-}
-#endif
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Delta-image row routines - apply the source row onto the target        * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-mng_retcode mng_delta_g1_g1 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_G1_G1, MNG_LC_START);
-#endif
-
-  pWorkrow = pData->pRGBArow;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize);
-
-  if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE          ) ||
-      (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
-  {
-    MNG_COPY (pOutrow, pWorkrow, pData->iRowsamples);
-  }
-  else
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
-                              (mng_uint16)*pWorkrow) & 0x01);
-
-      pOutrow++;
-      pWorkrow++;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_G1_G1, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_delta_g2_g2 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_G2_G2, MNG_LC_START);
-#endif
-
-  pWorkrow = pData->pRGBArow;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize);
-
-  if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE          ) ||
-      (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
-  {
-    MNG_COPY (pOutrow, pWorkrow, pData->iRowsamples);
-  }
-  else
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
-                              (mng_uint16)*pWorkrow) & 0x03);
-
-      pOutrow++;
-      pWorkrow++;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_G2_G2, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_delta_g4_g4 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_G4_G4, MNG_LC_START);
-#endif
-
-  pWorkrow = pData->pRGBArow;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize);
-
-  if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE          ) ||
-      (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
-  {
-    MNG_COPY (pOutrow, pWorkrow, pData->iRowsamples);
-  }
-  else
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
-                              (mng_uint16)*pWorkrow) & 0x0F);
-
-      pOutrow++;
-      pWorkrow++;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_G4_G4, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_delta_g8_g8 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_G8_G8, MNG_LC_START);
-#endif
-
-  pWorkrow = pData->pRGBArow;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize);
-
-  if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE          ) ||
-      (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
-  {
-    MNG_COPY (pOutrow, pWorkrow, pData->iRowsamples);
-  }
-  else
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
-                              (mng_uint16)*pWorkrow) & 0xFF);
-
-      pOutrow++;
-      pWorkrow++;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_G8_G8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_delta_g16_g16 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_G16_G16, MNG_LC_START);
-#endif
-
-  pWorkrow = pData->pRGBArow;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize);
-
-  if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE          ) ||
-      (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
-  {
-    MNG_COPY (pOutrow, pWorkrow, (pData->iRowsamples << 1));
-  }
-  else
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      mng_put_uint16 (pOutrow, (mng_uint16)((mng_get_uint16 (pOutrow) +
-                                             mng_get_uint16 (pWorkrow)) & 0xFFFF));
-
-      pOutrow  += 2;
-      pWorkrow += 2;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_G16_G16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif /* MNG_NO_DELTA_PNG */
-
-/* ************************************************************************** */
-
-mng_retcode mng_delta_rgb8_rgb8 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_RGB8_RGB8, MNG_LC_START);
-#endif
-
-  pWorkrow = pData->pRGBArow;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize);
-
-  if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE          ) ||
-      (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
-  {
-    MNG_COPY (pOutrow, pWorkrow, pData->iRowsamples * 3);
-  }
-  else
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples*3; iX > 0; iX--)
-#else
-    for (iX = 0; iX < (pData->iRowsamples * 3); iX++)
-#endif
-    {
-      *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
-                              (mng_uint16)*pWorkrow) & 0xFF);
-
-      pOutrow++;
-      pWorkrow++;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_RGB8_RGB8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_delta_rgb16_rgb16 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_RGB16_RGB16, MNG_LC_START);
-#endif
-
-  pWorkrow = pData->pRGBArow;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize);
-
-  if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE          ) ||
-      (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
-  {
-    MNG_COPY (pOutrow, pWorkrow, (pData->iRowsamples * 6));
-  }
-  else
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      mng_put_uint16 (pOutrow,   (mng_uint16)((mng_get_uint16 (pOutrow  ) +
-                                               mng_get_uint16 (pWorkrow  )) & 0xFFFF));
-      mng_put_uint16 (pOutrow+2, (mng_uint16)((mng_get_uint16 (pOutrow+2) +
-                                               mng_get_uint16 (pWorkrow+2)) & 0xFFFF));
-      mng_put_uint16 (pOutrow+4, (mng_uint16)((mng_get_uint16 (pOutrow+4) +
-                                               mng_get_uint16 (pWorkrow+4)) & 0xFFFF));
-
-      pOutrow  += 6;
-      pWorkrow += 6;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_RGB16_RGB16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-mng_retcode mng_delta_ga8_ga8 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_GA8_GA8, MNG_LC_START);
-#endif
-
-  pWorkrow = pData->pRGBArow;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize);
-
-  if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE          ) ||
-      (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
-  {
-    MNG_COPY (pOutrow, pWorkrow, pData->iRowsamples << 1);
-  }
-  else
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = (pData->iRowsamples<<1); iX > 0; iX--)
-#else
-    for (iX = 0; iX < (pData->iRowsamples << 1); iX++)
-#endif
-    {
-      *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
-                              (mng_uint16)*pWorkrow) & 0xFF);
-
-      pOutrow++;
-      pWorkrow++;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_GA8_GA8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_delta_ga8_g8 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_GA8_G8, MNG_LC_START);
-#endif
-
-  pWorkrow = pData->pRGBArow;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize);
-
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      *pOutrow = *pWorkrow;
-
-      pOutrow += 2;
-      pWorkrow++;
-    }
-  }
-  else
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORADD)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
-                              (mng_uint16)*pWorkrow) & 0xFF);
-
-      pOutrow += 2;
-      pWorkrow++;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_GA8_G8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_delta_ga8_a8 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_GA8_A8, MNG_LC_START);
-#endif
-
-  pWorkrow = pData->pRGBArow;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize) + 1;
-
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      *pOutrow = *pWorkrow;
-
-      pOutrow += 2;
-      pWorkrow++;
-    }
-  }
-  else
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAADD)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
-                              (mng_uint16)*pWorkrow) & 0xFF);
-
-      pOutrow += 2;
-      pWorkrow++;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_GA8_A8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_delta_ga16_ga16 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_GA16_GA16, MNG_LC_START);
-#endif
-
-  pWorkrow = pData->pRGBArow;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize);
-
-  if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE          ) ||
-      (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
-  {
-    MNG_COPY (pOutrow, pWorkrow, (pData->iRowsamples << 2));
-  }
-  else
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      mng_put_uint16 (pOutrow,   (mng_uint16)((mng_get_uint16 (pOutrow  ) +
-                                               mng_get_uint16 (pWorkrow  )) & 0xFFFF));
-      mng_put_uint16 (pOutrow+2, (mng_uint16)((mng_get_uint16 (pOutrow+2) +
-                                               mng_get_uint16 (pWorkrow+2)) & 0xFFFF));
-
-      pOutrow  += 4;
-      pWorkrow += 4;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_GA16_GA16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_delta_ga16_g16 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_GA16_G16, MNG_LC_START);
-#endif
-
-  pWorkrow = pData->pRGBArow;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize);
-
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      mng_put_uint16 (pOutrow, mng_get_uint16 (pWorkrow));
-
-      pOutrow  += 4;
-      pWorkrow += 2;
-    }
-  }
-  else
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORADD)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      mng_put_uint16 (pOutrow, (mng_uint16)((mng_get_uint16 (pOutrow) +
-                                             mng_get_uint16 (pWorkrow)) & 0xFFFF));
-
-      pOutrow  += 4;
-      pWorkrow += 2;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_GA16_G16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_delta_ga16_a16 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_GA16_A16, MNG_LC_START);
-#endif
-
-  pWorkrow = pData->pRGBArow;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize);
-
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      mng_put_uint16 (pOutrow+2, mng_get_uint16 (pWorkrow));
-
-      pOutrow  += 4;
-      pWorkrow += 2;
-    }
-  }
-  else
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAADD)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      mng_put_uint16 (pOutrow+2, (mng_uint16)((mng_get_uint16 (pOutrow+2) +
-                                               mng_get_uint16 (pWorkrow)) & 0xFFFF));
-
-      pOutrow  += 4;
-      pWorkrow += 2;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_GA16_A16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif /* MNG_NO_DELTA_PNG */
-
-/* ************************************************************************** */
-
-mng_retcode mng_delta_rgba8_rgba8 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_RGBA8_RGBA8, MNG_LC_START);
-#endif
-
-  pWorkrow = pData->pRGBArow;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize);
-
-  if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE          ) ||
-      (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
-  {
-    MNG_COPY (pOutrow, pWorkrow, pData->iRowsamples << 2);
-  }
-  else
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = (pData->iRowsamples << 2); iX > 0; iX--)
-#else
-    for (iX = 0; iX < (pData->iRowsamples << 2); iX++)
-#endif
-    {
-      *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
-                              (mng_uint16)*pWorkrow) & 0xFF);
-
-      pOutrow++;
-      pWorkrow++;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_RGBA8_RGBA8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-mng_retcode mng_delta_rgba8_rgb8 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_RGBA8_RGB8, MNG_LC_START);
-#endif
-
-  pWorkrow = pData->pRGBArow;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize);
-
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      *pOutrow     = *pWorkrow;
-      *(pOutrow+1) = *(pWorkrow+1);
-      *(pOutrow+2) = *(pWorkrow+2);
-
-      pOutrow  += 4;
-      pWorkrow += 3;
-    }
-  }
-  else
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORADD)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      *pOutrow     = (mng_uint8)(((mng_uint16)*pOutrow     +
-                                  (mng_uint16)*pWorkrow    ) & 0xFF);
-      *(pOutrow+1) = (mng_uint8)(((mng_uint16)*(pOutrow+1) +
-                                  (mng_uint16)*(pWorkrow+1)) & 0xFF);
-      *(pOutrow+2) = (mng_uint8)(((mng_uint16)*(pOutrow+2) +
-                                  (mng_uint16)*(pWorkrow+2)) & 0xFF);
-
-      pOutrow  += 4;
-      pWorkrow += 3;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_RGBA8_RGB8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_delta_rgba8_a8 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_RGBA8_A8, MNG_LC_START);
-#endif
-
-  pWorkrow = pData->pRGBArow;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize) + 3;
-
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      *pOutrow = *pWorkrow;
-
-      pOutrow += 4;
-      pWorkrow++;
-    }
-  }
-  else
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAADD)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
-                              (mng_uint16)*pWorkrow) & 0xFF);
-
-      pOutrow += 4;
-      pWorkrow++;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_RGBA8_A8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_NO_DELTA_PNG */
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_delta_rgba16_rgba16 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_RGBA16_RGBA16, MNG_LC_START);
-#endif
-
-  pWorkrow = pData->pRGBArow;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize);
-
-  if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE          ) ||
-      (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
-  {
-    MNG_COPY (pOutrow, pWorkrow, (pData->iRowsamples << 3));
-  }
-  else
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      mng_put_uint16 (pOutrow,   (mng_uint16)((mng_get_uint16 (pOutrow  ) +
-                                               mng_get_uint16 (pWorkrow  )) & 0xFFFF));
-      mng_put_uint16 (pOutrow+2, (mng_uint16)((mng_get_uint16 (pOutrow+2) +
-                                               mng_get_uint16 (pWorkrow+2)) & 0xFFFF));
-      mng_put_uint16 (pOutrow+4, (mng_uint16)((mng_get_uint16 (pOutrow+4) +
-                                               mng_get_uint16 (pWorkrow+4)) & 0xFFFF));
-      mng_put_uint16 (pOutrow+6, (mng_uint16)((mng_get_uint16 (pOutrow+6) +
-                                               mng_get_uint16 (pWorkrow+6)) & 0xFFFF));
-
-      pOutrow  += 8;
-      pWorkrow += 8;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_RGBA16_RGBA16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_delta_rgba16_rgb16 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_RGBA16_RGB16, MNG_LC_START);
-#endif
-
-  pWorkrow = pData->pRGBArow;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize);
-
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      mng_put_uint16 (pOutrow,   mng_get_uint16 (pWorkrow  ));
-      mng_put_uint16 (pOutrow+2, mng_get_uint16 (pWorkrow+2));
-      mng_put_uint16 (pOutrow+4, mng_get_uint16 (pWorkrow+4));
-
-      pOutrow  += 8;
-      pWorkrow += 6;
-    }
-  }
-  else
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORADD)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      mng_put_uint16 (pOutrow,   (mng_uint16)((mng_get_uint16 (pOutrow  ) +
-                                               mng_get_uint16 (pWorkrow  )) & 0xFFFF));
-      mng_put_uint16 (pOutrow+2, (mng_uint16)((mng_get_uint16 (pOutrow+2) +
-                                               mng_get_uint16 (pWorkrow+2)) & 0xFFFF));
-      mng_put_uint16 (pOutrow+4, (mng_uint16)((mng_get_uint16 (pOutrow+4) +
-                                               mng_get_uint16 (pWorkrow+4)) & 0xFFFF));
-
-      pOutrow  += 8;
-      pWorkrow += 6;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_RGBA16_RGB16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_delta_rgba16_a16 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_RGBA16_A16, MNG_LC_START);
-#endif
-
-  pWorkrow = pData->pRGBArow;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize);
-
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      mng_put_uint16 (pOutrow+6, mng_get_uint16 (pWorkrow));
-
-      pOutrow  += 8;
-      pWorkrow += 2;
-    }
-  }
-  else
-  if (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAADD)
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      mng_put_uint16 (pOutrow+6, (mng_uint16)((mng_get_uint16 (pOutrow+6) +
-                                               mng_get_uint16 (pWorkrow)) & 0xFFFF));
-
-      pOutrow  += 8;
-      pWorkrow += 2;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DELTA_RGBA16_A16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif /* MNG_NO_DELTA_PNG */
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Delta-image row routines - scale the delta to bitdepth of target       * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-mng_retcode mng_scale_g1_g2 (mng_datap pData)
-{
-  mng_uint8p pWorkrow = pData->pRGBArow;
-  mng_int32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_G1_G2, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *pWorkrow = (mng_uint8)(*pWorkrow << 1);
-    pWorkrow++;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_G1_G2, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_scale_g1_g4 (mng_datap pData)
-{
-  mng_uint8p pWorkrow = pData->pRGBArow;
-  mng_int32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_G1_G4, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *pWorkrow = (mng_uint8)(*pWorkrow << 3);
-    pWorkrow++;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_G1_G4, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_scale_g1_g8 (mng_datap pData)
-{
-  mng_uint8p pWorkrow = pData->pRGBArow;
-  mng_int32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_G1_G8, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *pWorkrow = (mng_uint8)(*pWorkrow << 7);
-    pWorkrow++;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_G1_G8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_scale_g1_g16 (mng_datap pData)
-{
-  mng_uint8p pWorkrow = pData->pRGBArow;
-  mng_uint8p pOutrow  = pData->pRGBArow;
-  mng_int32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_G1_G16, MNG_LC_START);
-#endif
-
-  pWorkrow = pWorkrow + (pData->iRowsamples - 1);
-  pOutrow  = pOutrow  + ((pData->iRowsamples - 1) << 1);
-/*  pWorkrow = (mng_uint8p)((mng_uint32)pWorkrow + pData->iRowsamples - 1); */
-/*  pOutrow  = (mng_uint8p)((mng_uint32)pOutrow  + ((pData->iRowsamples - 1) << 1)); */
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *(pOutrow+1) = 0;
-    *pOutrow     = (mng_uint8)(*pWorkrow << 7);
-
-    pWorkrow--;
-    pOutrow -= 2;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_G1_G16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_scale_g2_g4 (mng_datap pData)
-{
-  mng_uint8p pWorkrow = pData->pRGBArow;
-  mng_int32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_G2_G4, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *pWorkrow = (mng_uint8)(*pWorkrow << 2);
-    pWorkrow++;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_G2_G4, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_scale_g2_g8 (mng_datap pData)
-{
-  mng_uint8p pWorkrow = pData->pRGBArow;
-  mng_int32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_G2_G8, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *pWorkrow = (mng_uint8)(*pWorkrow << 6);
-    pWorkrow++;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_G2_G8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_scale_g2_g16 (mng_datap pData)
-{
-  mng_uint8p pWorkrow = pData->pRGBArow;
-  mng_uint8p pOutrow  = pData->pRGBArow;
-  mng_int32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_G2_G16, MNG_LC_START);
-#endif
-
-  pWorkrow = pWorkrow + (pData->iRowsamples - 1);
-  pOutrow  = pOutrow  + ((pData->iRowsamples - 1) << 1);
-/*  pWorkrow = (mng_uint8p)((mng_uint32)pWorkrow + pData->iRowsamples - 1); */
-/*  pOutrow  = (mng_uint8p)((mng_uint32)pOutrow  + ((pData->iRowsamples - 1) << 1)); */
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *(pOutrow+1) = 0;
-    *pOutrow     = (mng_uint8)(*pWorkrow << 6);
-
-    pWorkrow--;
-    pOutrow -= 2;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_G2_G16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_scale_g4_g8 (mng_datap pData)
-{
-  mng_uint8p pWorkrow = pData->pRGBArow;
-  mng_int32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_G4_G8, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *pWorkrow = (mng_uint8)(*pWorkrow << 4);
-    pWorkrow++;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_G4_G8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_scale_g4_g16 (mng_datap pData)
-{
-  mng_uint8p pWorkrow = pData->pRGBArow;
-  mng_uint8p pOutrow  = pData->pRGBArow;
-  mng_int32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_G4_G16, MNG_LC_START);
-#endif
-
-  pWorkrow = pWorkrow + (pData->iRowsamples - 1);
-  pOutrow  = pOutrow  + ((pData->iRowsamples - 1) << 1);
-/*  pWorkrow = (mng_uint8p)((mng_uint32)pWorkrow + pData->iRowsamples - 1); */
-/*  pOutrow  = (mng_uint8p)((mng_uint32)pOutrow  + ((pData->iRowsamples - 1) << 1)); */
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *(pOutrow+1) = 0;
-    *pOutrow     = (mng_uint8)(*pWorkrow << 4);
-
-    pWorkrow--;
-    pOutrow -= 2;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_G4_G16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif /* MNG_NO_1_2_4BIT_SUPPORT */
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_scale_g8_g16 (mng_datap pData)
-{
-  mng_uint8p pWorkrow = pData->pRGBArow;
-  mng_uint8p pOutrow  = pData->pRGBArow;
-  mng_int32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_G8_G16, MNG_LC_START);
-#endif
-
-  pWorkrow = pWorkrow + (pData->iRowsamples - 1);
-  pOutrow  = pOutrow  + ((pData->iRowsamples - 1) << 1);
-/*  pWorkrow = (mng_uint8p)((mng_uint32)pWorkrow + pData->iRowsamples - 1); */
-/*  pOutrow  = (mng_uint8p)((mng_uint32)pOutrow  + ((pData->iRowsamples - 1) << 1)); */
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *(pOutrow+1) = 0;
-    *pOutrow     = *pWorkrow;
-
-    pWorkrow--;
-    pOutrow -= 2;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_G8_G16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_scale_ga8_ga16 (mng_datap pData)
-{
-  mng_uint8p pWorkrow = pData->pRGBArow;
-  mng_uint8p pOutrow  = pData->pRGBArow;
-  mng_int32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_GA8_GA16, MNG_LC_START);
-#endif
-
-  pWorkrow = pWorkrow + ((pData->iRowsamples - 1) << 1);
-  pOutrow  = pOutrow  + ((pData->iRowsamples - 1) << 2);
-/*  pWorkrow = (mng_uint8p)((mng_uint32)pWorkrow + ((pData->iRowsamples - 1) << 1)); */
-/*  pOutrow  = (mng_uint8p)((mng_uint32)pOutrow  + ((pData->iRowsamples - 1) << 2)); */
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *(pOutrow+3) = 0;
-    *(pOutrow+2) = *(pWorkrow+1);
-    *(pOutrow+1) = 0;
-    *pOutrow     = *pWorkrow;
-
-    pWorkrow -= 2;
-    pOutrow  -= 4;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_GA8_GA16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_scale_rgb8_rgb16 (mng_datap pData)
-{
-  mng_uint8p pWorkrow = pData->pRGBArow;
-  mng_uint8p pOutrow  = pData->pRGBArow;
-  mng_int32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_RGB8_RGB16, MNG_LC_START);
-#endif
-
-  pWorkrow = pWorkrow + (3 * (pData->iRowsamples - 1));
-  pOutrow  = pOutrow  + (6 * (pData->iRowsamples - 1));
-/*  pWorkrow = (mng_uint8p)((mng_uint32)pWorkrow + 3 * (pData->iRowsamples - 1)); */
-/*  pOutrow  = (mng_uint8p)((mng_uint32)pOutrow  + 6 * (pData->iRowsamples - 1)); */
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *(pOutrow+5) = 0;
-    *(pOutrow+4) = *(pWorkrow+2);
-    *(pOutrow+3) = 0;
-    *(pOutrow+2) = *(pWorkrow+1);
-    *(pOutrow+1) = 0;
-    *pOutrow     = *pWorkrow;
-
-    pWorkrow -= 3;
-    pOutrow  -= 6;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_RGB8_RGB16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_scale_rgba8_rgba16 (mng_datap pData)
-{
-  mng_uint8p pWorkrow = pData->pRGBArow;
-  mng_uint8p pOutrow  = pData->pRGBArow;
-  mng_int32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_RGBA8_RGBA16, MNG_LC_START);
-#endif
-
-  pWorkrow = pWorkrow + ((pData->iRowsamples - 1) << 2);
-  pOutrow  = pOutrow  + ((pData->iRowsamples - 1) << 3);
-/*  pWorkrow = (mng_uint8p)((mng_uint32)pWorkrow + ((pData->iRowsamples - 1) << 2)); */
-/*  pOutrow  = (mng_uint8p)((mng_uint32)pOutrow  + ((pData->iRowsamples - 1) << 3)); */
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *(pOutrow+7) = 0;
-    *(pOutrow+6) = *(pWorkrow+3);
-    *(pOutrow+5) = 0;
-    *(pOutrow+4) = *(pWorkrow+2);
-    *(pOutrow+3) = 0;
-    *(pOutrow+2) = *(pWorkrow+1);
-    *(pOutrow+1) = 0;
-    *pOutrow     = *pWorkrow;
-
-    pWorkrow -= 4;
-    pOutrow  -= 8;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_RGBA8_RGBA16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-mng_retcode mng_scale_g2_g1 (mng_datap pData)
-{
-  mng_uint8p pWorkrow = pData->pRGBArow;
-  mng_int32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_G2_G1, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *pWorkrow = (mng_uint8)(*pWorkrow >> 1);
-    pWorkrow++;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_G2_G1, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_scale_g4_g1 (mng_datap pData)
-{
-  mng_uint8p pWorkrow = pData->pRGBArow;
-  mng_int32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_G4_G1, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *pWorkrow = (mng_uint8)(*pWorkrow >> 3);
-    pWorkrow++;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_G4_G1, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_scale_g8_g1 (mng_datap pData)
-{
-  mng_uint8p pWorkrow = pData->pRGBArow;
-  mng_int32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_G8_G1, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *pWorkrow = (mng_uint8)(*pWorkrow >> 7);
-    pWorkrow++;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_G8_G1, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_scale_g16_g1 (mng_datap pData)
-{
-  mng_uint8p pWorkrow = pData->pRGBArow;
-  mng_uint8p pOutrow  = pData->pRGBArow;
-  mng_int32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_G16_G1, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *pOutrow = (mng_uint8)(mng_get_uint16 (pWorkrow) >> 15);
-    pOutrow++;
-    pWorkrow += 2;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_G16_G1, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_scale_g4_g2 (mng_datap pData)
-{
-  mng_uint8p pWorkrow = pData->pRGBArow;
-  mng_int32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_G4_G2, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *pWorkrow = (mng_uint8)(*pWorkrow >> 2);
-    pWorkrow++;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_G4_G2, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_scale_g8_g2 (mng_datap pData)
-{
-  mng_uint8p pWorkrow = pData->pRGBArow;
-  mng_int32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_G8_G2, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *pWorkrow = (mng_uint8)(*pWorkrow >> 6);
-    pWorkrow++;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_G8_G2, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_scale_g16_g2 (mng_datap pData)
-{
-  mng_uint8p pWorkrow = pData->pRGBArow;
-  mng_uint8p pOutrow  = pData->pRGBArow;
-  mng_int32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_G16_G2, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *pOutrow = (mng_uint8)(mng_get_uint16 (pWorkrow) >> 14);
-    pOutrow++;
-    pWorkrow += 2;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_G16_G2, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_scale_g8_g4 (mng_datap pData)
-{
-  mng_uint8p pWorkrow = pData->pRGBArow;
-  mng_int32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_G8_G4, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *pWorkrow = (mng_uint8)(*pWorkrow >> 4);
-    pWorkrow++;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_G8_G4, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_scale_g16_g4 (mng_datap pData)
-{
-  mng_uint8p pWorkrow = pData->pRGBArow;
-  mng_uint8p pOutrow  = pData->pRGBArow;
-  mng_int32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_G16_G4, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *pOutrow = (mng_uint8)(mng_get_uint16 (pWorkrow) >> 12);
-    pOutrow++;
-    pWorkrow += 2;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_G16_G4, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif /* NO_1_2_4BIT_SUPPORT */
-
-/* ************************************************************************** */
-
-mng_retcode mng_scale_g16_g8 (mng_datap pData)
-{
-  mng_uint8p pWorkrow = pData->pRGBArow;
-  mng_uint8p pOutrow  = pData->pRGBArow;
-  mng_int32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_G16_G8, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *pOutrow = (mng_uint8)(mng_get_uint16 (pWorkrow) >> 8);
-    pOutrow++;
-    pWorkrow += 2;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_G16_G8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_scale_ga16_ga8 (mng_datap pData)
-{
-  mng_uint8p pWorkrow = pData->pRGBArow;
-  mng_uint8p pOutrow  = pData->pRGBArow;
-  mng_int32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_GA16_GA8, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *pOutrow = (mng_uint8)(mng_get_uint16 (pWorkrow) >> 8);
-    pOutrow++;
-    pWorkrow += 2;
-    *pOutrow = (mng_uint8)(mng_get_uint16 (pWorkrow) >> 8);
-    pOutrow++;
-    pWorkrow += 2;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_GA16_GA8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_scale_rgb16_rgb8 (mng_datap pData)
-{
-  mng_uint8p pWorkrow = pData->pRGBArow;
-  mng_uint8p pOutrow  = pData->pRGBArow;
-  mng_int32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_RGB16_RGB8, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *pOutrow = (mng_uint8)(mng_get_uint16 (pWorkrow) >> 8);
-    pOutrow++;
-    pWorkrow += 2;
-    *pOutrow = (mng_uint8)(mng_get_uint16 (pWorkrow) >> 8);
-    pOutrow++;
-    pWorkrow += 2;
-    *pOutrow = (mng_uint8)(mng_get_uint16 (pWorkrow) >> 8);
-    pOutrow++;
-    pWorkrow += 2;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_RGB16_RGB8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_scale_rgba16_rgba8 (mng_datap pData)
-{
-  mng_uint8p pWorkrow = pData->pRGBArow;
-  mng_uint8p pOutrow  = pData->pRGBArow;
-  mng_int32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_RGBA16_RGBA8, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *pOutrow = (mng_uint8)(mng_get_uint16 (pWorkrow) >> 8);
-    pOutrow++;
-    pWorkrow += 2;
-    *pOutrow = (mng_uint8)(mng_get_uint16 (pWorkrow) >> 8);
-    pOutrow++;
-    pWorkrow += 2;
-    *pOutrow = (mng_uint8)(mng_get_uint16 (pWorkrow) >> 8);
-    pOutrow++;
-    pWorkrow += 2;
-    *pOutrow = (mng_uint8)(mng_get_uint16 (pWorkrow) >> 8);
-    pOutrow++;
-    pWorkrow += 2;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_SCALE_RGBA16_RGBA8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Delta-image bit routines - promote bit_depth                           * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-mng_uint8 mng_promote_replicate_1_2 (mng_uint8 iB)
-{
-  return (mng_uint8)((iB << 1) | iB);
-}
-
-/* ************************************************************************** */
-
-mng_uint8 mng_promote_replicate_1_4 (mng_uint8 iB)
-{
-  iB = (mng_uint8)((iB << 1) + iB);
-  return (mng_uint8)((iB << 2) + iB);
-}
-
-/* ************************************************************************** */
-
-mng_uint8 mng_promote_replicate_1_8 (mng_uint8 iB)
-{
-  iB = (mng_uint8)((iB << 1) + iB);
-  iB = (mng_uint8)((iB << 2) + iB);
-  return (mng_uint8)((iB << 4) + iB);
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_uint16 mng_promote_replicate_1_16 (mng_uint8 iB)
-{
-  iB = (mng_uint8)((iB << 1) + iB);
-  iB = (mng_uint8)((iB << 2) + iB);
-  iB = (mng_uint8)((iB << 4) + iB);
-  return (mng_uint16)(((mng_uint16)iB << 8) + (mng_uint16)iB);
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_uint8 mng_promote_replicate_2_4 (mng_uint8 iB)
-{
-  return (mng_uint8)((iB << 2) + iB);
-}
-
-/* ************************************************************************** */
-
-mng_uint8 mng_promote_replicate_2_8 (mng_uint8 iB)
-{
-  iB = (mng_uint8)((iB << 2) + iB);
-  return (mng_uint8)((iB << 4) + iB);
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_uint16 mng_promote_replicate_2_16 (mng_uint8 iB)
-{
-  iB = (mng_uint8)((iB << 2) + iB);
-  iB = (mng_uint8)((iB << 4) + iB);
-  return (mng_uint16)(((mng_uint16)iB << 8) + (mng_uint16)iB);
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_uint8 mng_promote_replicate_4_8 (mng_uint8 iB)
-{
-  return (mng_uint8)((iB << 4) + iB);
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_uint16 mng_promote_replicate_4_16 (mng_uint8 iB)
-{
-  iB = (mng_uint8)((iB << 4) + iB);
-  return (mng_uint16)(((mng_uint16)iB << 8) + (mng_uint16)iB);
-}
-#endif
-#endif /* NO_1_2_4BIT_SUPPORT */
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_uint16 mng_promote_replicate_8_16 (mng_uint8 iB)
-{
-  return (mng_uint16)(((mng_uint16)iB << 8) + (mng_uint16)iB);
-}
-#endif
-
-/* ************************************************************************** */
-
-#if !defined(MNG_NO_DELTA_PNG)
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-mng_uint8 mng_promote_zerofill_1_2 (mng_uint8 iB)
-{
-  return (mng_uint8)(iB << 1);
-}
-
-/* ************************************************************************** */
-
-mng_uint8 mng_promote_zerofill_1_4 (mng_uint8 iB)
-{
-  return (mng_uint8)(iB << 3);
-}
-
-/* ************************************************************************** */
-
-mng_uint8 mng_promote_zerofill_1_8 (mng_uint8 iB)
-{
-  return (mng_uint8)(iB << 7);
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_uint16 mng_promote_zerofill_1_16 (mng_uint8 iB)
-{
-  return (mng_uint16)((mng_uint16)iB << 15);
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_uint8 mng_promote_zerofill_2_4 (mng_uint8 iB)
-{
-  return (mng_uint8)(iB << 2);
-}
-
-/* ************************************************************************** */
-
-mng_uint8 mng_promote_zerofill_2_8 (mng_uint8 iB)
-{
-  return (mng_uint8)(iB << 6);
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_uint16 mng_promote_zerofill_2_16 (mng_uint8 iB)
-{
-  return (mng_uint16)((mng_uint16)iB << 14);
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_uint8 mng_promote_zerofill_4_8 (mng_uint8 iB)
-{
-  return (mng_uint8)(iB << 4);
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_uint16 mng_promote_zerofill_4_16 (mng_uint8 iB)
-{
-  return (mng_uint16)((mng_uint16)iB << 12);
-}
-#endif
-#endif /* MNG_NO_1_2_4BIT_SUPPORT */
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_uint16 mng_promote_zerofill_8_16 (mng_uint8 iB)
-{
-  return (mng_uint16)((mng_uint16)iB << 8);
-}
-#endif
-#endif /* MNG_NO_DELTA_PNG */
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Delta-image row routines - promote color_type                          * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#if !defined(MNG_NO_DELTA_PNG) || !defined(MNG_SKIPCHUNK_PAST) || !defined(MNG_SKIPCHUNK_MAGN)
-mng_retcode mng_promote_g8_g8 (mng_datap pData)
-{
-  mng_uint8p pSrcline = (mng_uint8p)pData->pPromSrc;
-  mng_uint8p pDstline = (mng_uint8p)pData->pPromDst;
-  mng_uint32 iX;
-  mng_uint8  iB;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_G8_G8, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iPromWidth; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iPromWidth; iX++)
-#endif
-  {
-    iB = *pSrcline;
-    if (pData->fPromBitdepth)      /* bitdepth promoted ? */
-      iB = ((mng_bitdepth_8)pData->fPromBitdepth) (iB);
-    *pDstline = iB;
-
-    pSrcline++;
-    pDstline++;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_G8_G8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_promote_g8_g16 (mng_datap pData)
-{
-  mng_uint8p pSrcline = (mng_uint8p)pData->pPromSrc;
-  mng_uint8p pDstline = (mng_uint8p)pData->pPromDst;
-  mng_uint32 iX;
-  mng_uint16 iW;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_G8_G16, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iPromWidth; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iPromWidth; iX++)
-#endif
-  {
-    iW = ((mng_bitdepth_16)pData->fPromBitdepth) (*pSrcline);
-
-    *pDstline     = (mng_uint8)(iW >> 8);
-    *(pDstline+1) = (mng_uint8)(iW && 0xFF);
-
-    pSrcline++;
-    pDstline += 2;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_G8_G16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_promote_g16_g16 (mng_datap pData)
-{
-  mng_uint16p pSrcline = (mng_uint16p)pData->pPromSrc;
-  mng_uint16p pDstline = (mng_uint16p)pData->pPromDst;
-  mng_uint32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_G16_G16, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iPromWidth; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iPromWidth; iX++)
-#endif
-  {
-    *pDstline = *pSrcline;
-    pSrcline++;
-    pDstline++;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_G16_G16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_promote_g8_ga8 (mng_datap pData)
-{
-  mng_imagedatap pBuf     = (mng_imagedatap)pData->pPromBuf;
-  mng_uint8p     pSrcline = (mng_uint8p)pData->pPromSrc;
-  mng_uint8p     pDstline = (mng_uint8p)pData->pPromDst;
-  mng_uint32     iX;
-  mng_uint8      iB;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_G8_GA8, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iPromWidth; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iPromWidth; iX++)
-#endif
-  {
-    iB = *pSrcline;
-                                   /* no cheap transparency ? */
-    if ((!pBuf->bHasTRNS) || ((mng_uint16)iB != pBuf->iTRNSgray))
-      *(pDstline+1) = 0xFF;
-
-    if (pData->fPromBitdepth)      /* bitdepth promoted ? */
-      iB = ((mng_bitdepth_8)pData->fPromBitdepth) (iB);
-
-    *pDstline = iB;
-
-    pSrcline++;
-    pDstline += 2;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_G8_GA8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_promote_g8_ga16 (mng_datap pData)
-{
-  mng_imagedatap pBuf     = (mng_imagedatap)pData->pPromBuf;
-  mng_uint8p     pSrcline = (mng_uint8p)pData->pPromSrc;
-  mng_uint8p     pDstline = (mng_uint8p)pData->pPromDst;
-  mng_uint32     iX;
-  mng_uint8      iB;
-  mng_uint16     iW;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_G8_GA16, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iPromWidth; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iPromWidth; iX++)
-#endif
-  {
-    iB = *pSrcline;
-                                   /* no cheap transparency ? */
-    if ((!pBuf->bHasTRNS) || ((mng_uint16)iB != pBuf->iTRNSgray))
-    {
-      *(pDstline+2) = 0xFF;
-      *(pDstline+3) = 0xFF;
-    }
-
-    iW = ((mng_bitdepth_16)pData->fPromBitdepth) (iB);
-
-    *pDstline     = (mng_uint8)(iW >> 8);
-    *(pDstline+1) = (mng_uint8)(iW && 0xFF);
-
-    pSrcline++;
-    pDstline += 4;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_G8_GA16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_promote_g16_ga16 (mng_datap pData)
-{
-  mng_imagedatap pBuf     = (mng_imagedatap)pData->pPromBuf;
-  mng_uint16p    pSrcline = (mng_uint16p)pData->pPromSrc;
-  mng_uint16p    pDstline = (mng_uint16p)pData->pPromDst;
-  mng_uint32     iX;
-  mng_uint16     iW;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_G16_GA16, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iPromWidth; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iPromWidth; iX++)
-#endif
-  {
-    iW = *pSrcline;
-                                   /* no cheap transparency ? */
-    if ((!pBuf->bHasTRNS) || ((mng_uint16)iW != pBuf->iTRNSgray))
-      *(pDstline+1) = 0xFFFF;
-
-    *pDstline = iW;
-
-    pSrcline++;
-    pDstline += 2;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_G16_GA16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_promote_g8_rgb8 (mng_datap pData)
-{
-  mng_uint8p pSrcline = (mng_uint8p)pData->pPromSrc;
-  mng_uint8p pDstline = (mng_uint8p)pData->pPromDst;
-  mng_uint32 iX;
-  mng_uint8  iB;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_G8_RGB8, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iPromWidth; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iPromWidth; iX++)
-#endif
-  {
-    iB = *pSrcline;
-
-    if (pData->fPromBitdepth)      /* bitdepth promoted ? */
-      iB = ((mng_bitdepth_8)pData->fPromBitdepth) (iB);
-
-    *pDstline     = iB;
-    *(pDstline+1) = iB;
-    *(pDstline+2) = iB;
-
-    pSrcline++;
-    pDstline += 3;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_G8_RGB8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_promote_g8_rgb16 (mng_datap pData)
-{
-  mng_uint8p pSrcline = (mng_uint8p)pData->pPromSrc;
-  mng_uint8p pDstline = (mng_uint8p)pData->pPromDst;
-  mng_uint32 iX;
-  mng_uint8  iB;
-  mng_uint16 iW;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_G8_RGB16, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iPromWidth; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iPromWidth; iX++)
-#endif
-  {
-    iB = *pSrcline;
-    iW = ((mng_bitdepth_16)pData->fPromBitdepth) (iB);
-
-    iB            = (mng_uint8)(iW >> 8);
-    *pDstline     = iB;
-    *(pDstline+2) = iB;
-    *(pDstline+4) = iB;
-    iB            = (mng_uint8)(iW && 0xFF);
-    *(pDstline+1) = iB;
-    *(pDstline+3) = iB;
-    *(pDstline+5) = iB;
-
-    pSrcline++;
-    pDstline += 6;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_G8_RGB16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_promote_g16_rgb16 (mng_datap pData)
-{
-  mng_uint16p pSrcline = (mng_uint16p)pData->pPromSrc;
-  mng_uint16p pDstline = (mng_uint16p)pData->pPromDst;
-  mng_uint32  iX;
-  mng_uint16  iW;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_G16_RGB16, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iPromWidth; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iPromWidth; iX++)
-#endif
-  {
-    iW = *pSrcline;
-
-    *pDstline     = iW;
-    *(pDstline+1) = iW;
-    *(pDstline+2) = iW;
-
-    pSrcline++;
-    pDstline += 3;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_G16_RGB16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_promote_g8_rgba8 (mng_datap pData)
-{
-  mng_imagedatap pBuf     = (mng_imagedatap)pData->pPromBuf;
-  mng_uint8p     pSrcline = (mng_uint8p)pData->pPromSrc;
-  mng_uint8p     pDstline = (mng_uint8p)pData->pPromDst;
-  mng_uint32     iX;
-  mng_uint8      iB;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_G8_RGBA8, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iPromWidth; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iPromWidth; iX++)
-#endif
-  {
-    iB = *pSrcline;
-                                   /* no cheap transparency ? */
-    if ((!pBuf->bHasTRNS) || ((mng_uint16)iB != pBuf->iTRNSgray))
-      *(pDstline+3) = 0xFF;
-
-    if (pData->fPromBitdepth)      /* bitdepth promoted ? */
-      iB = ((mng_bitdepth_8)pData->fPromBitdepth) (iB);
-
-    *pDstline     = iB;
-    *(pDstline+1) = iB;
-    *(pDstline+2) = iB;
-
-    pSrcline++;
-    pDstline += 4;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_G8_RGBA8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_promote_g8_rgba16 (mng_datap pData)
-{
-  mng_imagedatap pBuf     = (mng_imagedatap)pData->pPromBuf;
-  mng_uint8p     pSrcline = (mng_uint8p)pData->pPromSrc;
-  mng_uint8p     pDstline = (mng_uint8p)pData->pPromDst;
-  mng_uint32     iX;
-  mng_uint8      iB;
-  mng_uint16     iW;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_G8_RGBA16, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iPromWidth; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iPromWidth; iX++)
-#endif
-  {
-    iB = *pSrcline;
-                                   /* no cheap transparency ? */
-    if ((!pBuf->bHasTRNS) || ((mng_uint16)iB != pBuf->iTRNSgray))
-    {
-      *(pDstline+6) = 0xFF;
-      *(pDstline+7) = 0xFF;
-    }
-
-    iW            = ((mng_bitdepth_16)pData->fPromBitdepth) (iB);
-
-    iB            = (mng_uint8)(iW >> 8);
-    *pDstline     = iB;
-    *(pDstline+2) = iB;
-    *(pDstline+4) = iB;
-    iB            = (mng_uint8)(iW && 0xFF);
-    *(pDstline+1) = iB;
-    *(pDstline+3) = iB;
-    *(pDstline+5) = iB;;
-
-    pSrcline++;
-    pDstline += 8;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_G8_RGBA16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_promote_g16_rgba16 (mng_datap pData)
-{
-  mng_imagedatap pBuf     = (mng_imagedatap)pData->pPromBuf;
-  mng_uint16p    pSrcline = (mng_uint16p)pData->pPromSrc;
-  mng_uint16p    pDstline = (mng_uint16p)pData->pPromDst;
-  mng_uint32     iX;
-  mng_uint16     iW;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_G16_RGBA16, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iPromWidth; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iPromWidth; iX++)
-#endif
-  {
-    iW = *pSrcline;
-                                   /* no cheap transparency ? */
-    if ((!pBuf->bHasTRNS) || (iW != pBuf->iTRNSgray))
-      *(pDstline+3) = 0xFFFF;
-
-    *pDstline     = iW;
-    *(pDstline+1) = iW;
-    *(pDstline+2) = iW;
-
-    pSrcline++;
-    pDstline += 4;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_G16_RGBA16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_promote_ga8_ga16 (mng_datap pData)
-{
-  mng_uint8p pSrcline = (mng_uint8p)pData->pPromSrc;
-  mng_uint8p pDstline = (mng_uint8p)pData->pPromDst;
-  mng_uint32 iX;
-  mng_uint16 iW;
-  mng_uint16 iA;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_GA8_GA16, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iPromWidth; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iPromWidth; iX++)
-#endif
-  {
-    iW = ((mng_bitdepth_16)pData->fPromBitdepth) (*pSrcline);
-    iA = ((mng_bitdepth_16)pData->fPromBitdepth) (*(pSrcline+1));
-
-    *pDstline     = (mng_uint8)(iW >> 8);
-    *(pDstline+1) = (mng_uint8)(iW && 0xFF);
-    *(pDstline+2) = (mng_uint8)(iA >> 8);
-    *(pDstline+3) = (mng_uint8)(iA && 0xFF);
-
-    pSrcline += 2;
-    pDstline += 4;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_GA8_GA16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_promote_ga8_rgba8 (mng_datap pData)
-{
-  mng_uint8p     pSrcline = (mng_uint8p)pData->pPromSrc;
-  mng_uint8p     pDstline = (mng_uint8p)pData->pPromDst;
-  mng_uint32     iX;
-  mng_uint8      iB;
-  mng_uint8      iA;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_GA8_RGBA8, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iPromWidth; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iPromWidth; iX++)
-#endif
-  {
-    iB = *pSrcline;
-    iA = *(pSrcline+1);
-
-    *pDstline     = iB;
-    *(pDstline+1) = iB;
-    *(pDstline+2) = iB;
-    *(pDstline+3) = iA;
-
-    pSrcline += 2;
-    pDstline += 4;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_GA8_RGBA8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_promote_ga8_rgba16 (mng_datap pData)
-{
-  mng_uint8p pSrcline = (mng_uint8p)pData->pPromSrc;
-  mng_uint8p pDstline = (mng_uint8p)pData->pPromDst;
-  mng_uint32 iX;
-  mng_uint8  iB;
-  mng_uint16 iW;
-  mng_uint16 iA;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_GA8_RGBA16, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iPromWidth; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iPromWidth; iX++)
-#endif
-  {
-    iW = ((mng_bitdepth_16)pData->fPromBitdepth) (*pSrcline);
-    iA = ((mng_bitdepth_16)pData->fPromBitdepth) (*(pSrcline+1));
-
-    iB            = (mng_uint8)(iW >> 8);
-    *pDstline     = iB;
-    *(pDstline+2) = iB;
-    *(pDstline+4) = iB;
-    iB            = (mng_uint8)(iW && 0xFF);
-    *(pDstline+1) = iB;
-    *(pDstline+3) = iB;
-    *(pDstline+5) = iB;
-    *(pDstline+6) = (mng_uint8)(iA >> 8);
-    *(pDstline+7) = (mng_uint8)(iA && 0xFF);
-
-    pSrcline += 2;
-    pDstline += 8;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_GA8_RGBA16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_promote_ga16_rgba16 (mng_datap pData)
-{
-  mng_uint16p pSrcline = (mng_uint16p)pData->pPromSrc;
-  mng_uint16p pDstline = (mng_uint16p)pData->pPromDst;
-  mng_uint32 iX;
-  mng_uint16 iW;
-  mng_uint16 iA;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_GA16_RGBA16, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iPromWidth; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iPromWidth; iX++)
-#endif
-  {
-    iW = *pSrcline;
-    iA = *(pSrcline+1);
-
-    *pDstline     = iW;
-    *(pDstline+1) = iW;
-    *(pDstline+2) = iW;
-    *(pDstline+3) = iA;
-
-    pSrcline += 2;
-    pDstline += 4;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_GA16_RGBA16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_promote_rgb8_rgb16 (mng_datap pData)
-{
-  mng_uint8p pSrcline = (mng_uint8p)pData->pPromSrc;
-  mng_uint8p pDstline = (mng_uint8p)pData->pPromDst;
-  mng_uint32 iX;
-  mng_uint16 iR;
-  mng_uint16 iG;
-  mng_uint16 iB;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_RGB8_RGB16, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iPromWidth; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iPromWidth; iX++)
-#endif
-  {
-    iR            = ((mng_bitdepth_16)pData->fPromBitdepth) (*pSrcline);
-    iG            = ((mng_bitdepth_16)pData->fPromBitdepth) (*(pSrcline+1));
-    iB            = ((mng_bitdepth_16)pData->fPromBitdepth) (*(pSrcline+2));
-
-    *pDstline     = (mng_uint8)(iR >> 8);
-    *(pDstline+1) = (mng_uint8)(iR && 0xFF);
-    *(pDstline+2) = (mng_uint8)(iG >> 8);
-    *(pDstline+3) = (mng_uint8)(iG && 0xFF);
-    *(pDstline+4) = (mng_uint8)(iB >> 8);
-    *(pDstline+5) = (mng_uint8)(iB && 0xFF);
-
-    pSrcline += 3;
-    pDstline += 6;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_RGB8_RGB16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_promote_rgb8_rgba8 (mng_datap pData)
-{
-  mng_imagedatap pBuf     = (mng_imagedatap)pData->pPromBuf;
-  mng_uint8p     pSrcline = (mng_uint8p)pData->pPromSrc;
-  mng_uint8p     pDstline = (mng_uint8p)pData->pPromDst;
-  mng_uint32     iX;
-  mng_uint8      iR;
-  mng_uint8      iG;
-  mng_uint8      iB;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_RGB8_RGBA8, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iPromWidth; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iPromWidth; iX++)
-#endif
-  {
-    iR = *pSrcline;
-    iG = *(pSrcline+1);
-    iB = *(pSrcline+2);
-                                   /* no cheap transparency ? */
-    if ((!pBuf->bHasTRNS) || ((mng_uint16)iR != pBuf->iTRNSred) ||
-        ((mng_uint16)iG != pBuf->iTRNSgreen) || ((mng_uint16)iB != pBuf->iTRNSblue))
-      *(pDstline+3) = 0xFF;
-
-    *pDstline     = iR;
-    *(pDstline+1) = iG;
-    *(pDstline+2) = iB;
-
-    pSrcline += 3;
-    pDstline += 4;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_RGB8_RGBA8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_promote_rgb8_rgba16 (mng_datap pData)
-{
-  mng_imagedatap pBuf     = (mng_imagedatap)pData->pPromBuf;
-  mng_uint8p     pSrcline = (mng_uint8p)pData->pPromSrc;
-  mng_uint8p     pDstline = (mng_uint8p)pData->pPromDst;
-  mng_uint32     iX;
-  mng_uint8      iR;
-  mng_uint8      iG;
-  mng_uint8      iB;
-  mng_uint16     iRw;
-  mng_uint16     iGw;
-  mng_uint16     iBw;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_RGB8_RGBA16, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iPromWidth; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iPromWidth; iX++)
-#endif
-  {
-    iR = *pSrcline;
-    iG = *(pSrcline+1);
-    iB = *(pSrcline+2);
-                                   /* no cheap transparency ? */
-    if ((!pBuf->bHasTRNS) || ((mng_uint16)iR != pBuf->iTRNSred) ||
-        ((mng_uint16)iG != pBuf->iTRNSgreen) || ((mng_uint16)iB != pBuf->iTRNSblue))
-    {
-      *(pDstline+6) = 0xFF;
-      *(pDstline+7) = 0xFF;
-    }
-
-    iRw           = ((mng_bitdepth_16)pData->fPromBitdepth) (iR);
-    iGw           = ((mng_bitdepth_16)pData->fPromBitdepth) (iG);
-    iBw           = ((mng_bitdepth_16)pData->fPromBitdepth) (iB);
-
-    *pDstline     = (mng_uint8)(iRw >> 8);
-    *(pDstline+1) = (mng_uint8)(iRw && 0xFF);
-    *(pDstline+2) = (mng_uint8)(iGw >> 8);
-    *(pDstline+3) = (mng_uint8)(iGw && 0xFF);
-    *(pDstline+4) = (mng_uint8)(iBw >> 8);
-    *(pDstline+5) = (mng_uint8)(iBw && 0xFF);
-
-    pSrcline += 3;
-    pDstline += 8;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_RGB8_RGBA16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_promote_rgb16_rgba16 (mng_datap pData)
-{
-  mng_imagedatap pBuf     = (mng_imagedatap)pData->pPromBuf;
-  mng_uint16p    pSrcline = (mng_uint16p)pData->pPromSrc;
-  mng_uint16p    pDstline = (mng_uint16p)pData->pPromDst;
-  mng_uint32     iX;
-  mng_uint16     iR;
-  mng_uint16     iG;
-  mng_uint16     iB;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_RGB16_RGBA16, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iPromWidth; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iPromWidth; iX++)
-#endif
-  {
-    iR = *pSrcline;
-    iG = *(pSrcline+1);
-    iB = *(pSrcline+2);
-                                   /* no cheap transparency ? */
-    if ((!pBuf->bHasTRNS) || (iR != pBuf->iTRNSred) ||
-        (iG != pBuf->iTRNSgreen) || (iB != pBuf->iTRNSblue))
-      *(pDstline+3) = 0xFFFF;
-
-    *pDstline     = iR;
-    *(pDstline+1) = iG;
-    *(pDstline+2) = iB;
-
-    pSrcline += 3;
-    pDstline += 4;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_RGB16_RGBA16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_promote_idx8_rgb8 (mng_datap pData)
-{
-  mng_imagedatap pBuf     = (mng_imagedatap)pData->pPromBuf;
-  mng_uint8p     pSrcline = (mng_uint8p)pData->pPromSrc;
-  mng_uint8p     pDstline = (mng_uint8p)pData->pPromDst;
-  mng_uint32     iX;
-  mng_uint8      iB;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_IDX8_RGB8, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iPromWidth; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iPromWidth; iX++)
-#endif
-  {
-    iB = *pSrcline;
-
-    if ((mng_uint32)iB < pBuf->iPLTEcount)
-    {
-      *pDstline     = pBuf->aPLTEentries [iB].iRed;
-      *(pDstline+1) = pBuf->aPLTEentries [iB].iGreen;
-      *(pDstline+2) = pBuf->aPLTEentries [iB].iBlue;
-    }
-
-    pSrcline++;
-    pDstline += 3;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_IDX8_RGB8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_promote_idx8_rgb16 (mng_datap pData)
-{
-  mng_imagedatap pBuf     = (mng_imagedatap)pData->pPromBuf;
-  mng_uint8p     pSrcline = (mng_uint8p)pData->pPromSrc;
-  mng_uint8p     pDstline = (mng_uint8p)pData->pPromDst;
-  mng_uint32     iX;
-  mng_uint8      iN;
-  mng_uint16     iR;
-  mng_uint16     iG;
-  mng_uint16     iB;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_IDX8_RGB16, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iPromWidth; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iPromWidth; iX++)
-#endif
-  {
-    iN = *pSrcline;
-
-    if ((mng_uint32)iN < pBuf->iPLTEcount)
-    {
-      iR              = ((mng_bitdepth_16)pData->fPromBitdepth) (pBuf->aPLTEentries [iN].iRed);
-      iG              = ((mng_bitdepth_16)pData->fPromBitdepth) (pBuf->aPLTEentries [iN].iGreen);
-      iB              = ((mng_bitdepth_16)pData->fPromBitdepth) (pBuf->aPLTEentries [iN].iBlue);
-      *pDstline       = (mng_uint8)(iR >> 8);
-      *(pDstline+1)   = (mng_uint8)(iR && 0xFF);
-      *(pDstline+2)   = (mng_uint8)(iG >> 8);
-      *(pDstline+3)   = (mng_uint8)(iG && 0xFF);
-      *(pDstline+4)   = (mng_uint8)(iB >> 8);
-      *(pDstline+5)   = (mng_uint8)(iB && 0xFF);
-    }
-
-    pSrcline++;
-    pDstline += 6;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_IDX8_RGB16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_promote_idx8_rgba8 (mng_datap pData)
-{
-  mng_imagedatap pBuf     = (mng_imagedatap)pData->pPromBuf;
-  mng_uint8p     pSrcline = (mng_uint8p)pData->pPromSrc;
-  mng_uint8p     pDstline = (mng_uint8p)pData->pPromDst;
-  mng_uint32     iX;
-  mng_uint8      iB;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_IDX8_RGBA8, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iPromWidth; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iPromWidth; iX++)
-#endif
-  {
-    iB = *pSrcline;
-
-    if ((mng_uint32)iB < pBuf->iPLTEcount)
-    {
-      *pDstline       = pBuf->aPLTEentries [iB].iRed;
-      *(pDstline+1)   = pBuf->aPLTEentries [iB].iGreen;
-      *(pDstline+2)   = pBuf->aPLTEentries [iB].iBlue;
-
-      if ((pBuf->bHasTRNS) && ((mng_uint32)iB < pBuf->iTRNScount))
-        *(pDstline+3) = pBuf->aTRNSentries [iB];
-      else
-        *(pDstline+3) = 0xFF;
-    }
-
-    pSrcline++;
-    pDstline += 4;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_IDX8_RGBA8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_promote_idx8_rgba16 (mng_datap pData)
-{
-  mng_imagedatap pBuf     = (mng_imagedatap)pData->pPromBuf;
-  mng_uint8p     pSrcline = (mng_uint8p)pData->pPromSrc;
-  mng_uint8p     pDstline = (mng_uint8p)pData->pPromDst;
-  mng_uint32     iX;
-  mng_uint8      iN;
-  mng_uint16     iR;
-  mng_uint16     iG;
-  mng_uint16     iB;
-  mng_uint16     iA;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_IDX8_RGBA16, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iPromWidth; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iPromWidth; iX++)
-#endif
-  {
-    iN = *pSrcline;
-
-    if ((mng_uint32)iN < pBuf->iPLTEcount)
-    {
-      iR            = ((mng_bitdepth_16)pData->fPromBitdepth) (pBuf->aPLTEentries [iN].iRed);
-      iG            = ((mng_bitdepth_16)pData->fPromBitdepth) (pBuf->aPLTEentries [iN].iGreen);
-      iB            = ((mng_bitdepth_16)pData->fPromBitdepth) (pBuf->aPLTEentries [iN].iBlue);
-
-      if ((pBuf->bHasTRNS) && ((mng_uint32)iN < pBuf->iTRNScount))
-        iA          = ((mng_bitdepth_16)pData->fPromBitdepth) (pBuf->aTRNSentries [iN]);
-      else
-        iA          = 0xFFFF;
-
-      *pDstline     = (mng_uint8)(iR >> 8);
-      *(pDstline+1) = (mng_uint8)(iR && 0xFF);
-      *(pDstline+2) = (mng_uint8)(iG >> 8);
-      *(pDstline+3) = (mng_uint8)(iG && 0xFF);
-      *(pDstline+4) = (mng_uint8)(iB >> 8);
-      *(pDstline+5) = (mng_uint8)(iB && 0xFF);
-      *(pDstline+6) = (mng_uint8)(iA >> 8);
-      *(pDstline+7) = (mng_uint8)(iA && 0xFF);
-    }
-
-    pSrcline++;
-    pDstline += 8;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_IDX8_RGBA16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_promote_rgba8_rgba16 (mng_datap pData)
-{
-  mng_uint8p pSrcline = (mng_uint8p)pData->pPromSrc;
-  mng_uint8p pDstline = (mng_uint8p)pData->pPromDst;
-  mng_uint32 iX;
-  mng_uint16 iR;
-  mng_uint16 iG;
-  mng_uint16 iB;
-  mng_uint16 iA;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_RGBA8_RGBA16, MNG_LC_START);
-#endif
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iPromWidth; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iPromWidth; iX++)
-#endif
-  {
-    iR            = ((mng_bitdepth_16)pData->fPromBitdepth) (*pSrcline);
-    iG            = ((mng_bitdepth_16)pData->fPromBitdepth) (*(pSrcline+1));
-    iB            = ((mng_bitdepth_16)pData->fPromBitdepth) (*(pSrcline+2));
-    iA            = ((mng_bitdepth_16)pData->fPromBitdepth) (*(pSrcline+3));
-
-    *pDstline     = (mng_uint8)(iR >> 8);
-    *(pDstline+1) = (mng_uint8)(iR && 0xFF);
-    *(pDstline+2) = (mng_uint8)(iG >> 8);
-    *(pDstline+3) = (mng_uint8)(iG && 0xFF);
-    *(pDstline+4) = (mng_uint8)(iB >> 8);
-    *(pDstline+5) = (mng_uint8)(iB && 0xFF);
-    *(pDstline+6) = (mng_uint8)(iA >> 8);
-    *(pDstline+7) = (mng_uint8)(iA && 0xFF);
-
-    pSrcline += 4;
-    pDstline += 8;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROMOTE_RGBA8_RGBA16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif /* !defined(MNG_NO_DELTA_PNG) || !defined(MNG_SKIPCHUNK_PAST) || !defined(MNG_SKIPCHUNK_MAGN) */
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Row processing routines - convert uncompressed data from zlib to       * */
-/* * managable row-data which serves as input to the color-management       * */
-/* * routines                                                               * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-mng_retcode mng_process_g1 (mng_datap pData)
-{
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pRGBArow;
-  mng_int32      iX;
-  mng_uint8      iB;
-  mng_uint8      iM;
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_G1, MNG_LC_START);
-#endif
-
-  if (!pBuf)                           /* no object? then use obj 0 */
-    pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pRGBArow = pData->pRGBArow;
-  iM       = 0;                        /* start at pixel 0 */
-  iB       = 0;
-
-  if (pBuf->bHasTRNS)                  /* tRNS encountered ? */
-  {
-    if (pBuf->iTRNSgray)               /* white transparent ? */
-    {
-#ifdef MNG_DECREMENT_LOOPS
-      for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-      for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-      {
-        if (!iM)                       /* mask underflow ? */
-        {
-          iB = *pWorkrow;              /* get next input-byte */
-          pWorkrow++;
-          iM = 0x80;
-        }
-
-        if (iB & iM)                   /* is it white ? */
-                                       /* transparent ! */
-          mng_put_uint32 (pRGBArow, 0x00000000);
-        else                           /* opaque black */
-          mng_put_uint32 (pRGBArow, 0x000000FF);
-
-        pRGBArow += 4;                 /* next pixel */
-        iM >>=  1;
-      }
-    }
-    else                               /* black transparent */
-    {
-#ifdef MNG_DECREMENT_LOOPS
-      for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-      for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-      {
-        if (!iM)                       /* mask underflow ? */
-        {
-          iB = *pWorkrow;              /* get next input-byte */
-          pWorkrow++;
-          iM = 0x80;
-        }
-
-        if (iB & iM)                   /* is it white ? */
-                                       /* opaque white */
-          mng_put_uint32 (pRGBArow, 0xFFFFFFFF);
-        else                           /* transparent */
-          mng_put_uint32 (pRGBArow, 0x00000000);
-
-        pRGBArow += 4;                 /* next pixel */
-        iM >>=  1;
-      }
-    }
-
-    pData->bIsOpaque = MNG_FALSE;      /* it's not fully opaque */
-  }
-  else                                 /* no transparency */
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      if (!iM)                         /* mask underflow ? */
-      {
-        iB = *pWorkrow;                /* get next input-byte */
-        pWorkrow++;
-        iM = 0x80;
-      }
-
-      if (iB & iM)                     /* is it white ? */
-                                       /* opaque white */
-        mng_put_uint32 (pRGBArow, 0xFFFFFFFF);
-      else                             /* opaque black */
-        mng_put_uint32 (pRGBArow, 0x000000FF);
-
-      pRGBArow += 4;                   /* next pixel */
-      iM >>=  1;
-    }
-
-    pData->bIsOpaque = MNG_TRUE;       /* it's fully opaque */
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_G1, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_g2 (mng_datap pData)
-{
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pRGBArow;
-  mng_int32      iX;
-  mng_uint8      iB;
-  mng_uint8      iM;
-  mng_uint32     iS;
-  mng_uint8      iQ;
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-#ifdef MNG_OPTIMIZE_FOOTPRINT_SWITCH
-  const mng_uint32  level[4] = { 0x000000FF, 0x555555FF,
-          0xAAAAAAFF, 0xFFFFFFFF};
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_G2, MNG_LC_START);
-#endif
-
-  if (!pBuf)                           /* no object? then use obj 0 */
-    pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pRGBArow = pData->pRGBArow;
-  iM       = 0;                        /* start at pixel 0 */
-  iB       = 0;
-  iS       = 0;
-
-  if (pBuf->bHasTRNS)                  /* tRNS encountered ? */
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      if (!iM)                         /* mask underflow ? */
-      {
-        iB = *pWorkrow;                /* get next input-byte */
-        pWorkrow++;
-        iM = 0xC0;
-        iS = 6;
-      }
-                                       /* determine gray level */
-      iQ = (mng_uint8)((iB & iM) >> iS);
-
-      if (iQ == pBuf->iTRNSgray)       /* transparent ? */
-        mng_put_uint32 (pRGBArow, 0x00000000);
-      else
-      {
-#ifdef MNG_OPTIMIZE_FOOTPRINT_SWITCH
-        mng_put_uint32 (pRGBArow, level[iQ]);
-#else
-        switch (iQ)                    /* determine the gray level */
-        {
-          case 0x03 : { mng_put_uint32 (pRGBArow, 0xFFFFFFFF); break; }
-          case 0x02 : { mng_put_uint32 (pRGBArow, 0xAAAAAAFF); break; }
-          case 0x01 : { mng_put_uint32 (pRGBArow, 0x555555FF); break; }
-          default   : { mng_put_uint32 (pRGBArow, 0x000000FF); }
-        }
-#endif
-      }
-
-      pRGBArow += 4;                   /* next pixel */
-      iM >>=  2;
-      iS -= 2;
-    }
-
-    pData->bIsOpaque = MNG_FALSE;      /* it's not fully opaque */
-  }
-  else
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      if (!iM)                         /* mask underflow ? */
-      {
-        iB = *pWorkrow;                /* get next input-byte */
-        pWorkrow++;
-        iM = 0xC0;
-        iS = 6;
-      }
-
-#ifdef MNG_OPTIMIZE_FOOTPRINT_SWITCH
-      mng_put_uint32 (pRGBArow, level[((iB & iM) >> iS)] );
-#else
-      switch ((iB & iM) >> iS)         /* determine the gray level */
-      {
-        case 0x03 : { mng_put_uint32 (pRGBArow, 0xFFFFFFFF); break; }
-        case 0x02 : { mng_put_uint32 (pRGBArow, 0xAAAAAAFF); break; }
-        case 0x01 : { mng_put_uint32 (pRGBArow, 0x555555FF); break; }
-        default   : { mng_put_uint32 (pRGBArow, 0x000000FF); }
-      }
-#endif
-
-      pRGBArow += 4;                   /* next pixel */
-      iM >>=  2;
-      iS -= 2;
-    }
-
-    pData->bIsOpaque = MNG_TRUE;       /* it's fully opaque */
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_G2, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_g4 (mng_datap pData)
-{
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pRGBArow;
-  mng_int32      iX;
-  mng_uint8      iB;
-  mng_uint8      iM;
-  mng_uint32     iS;
-  mng_uint8      iQ;
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_G4, MNG_LC_START);
-#endif
-
-  if (!pBuf)                           /* no object? then use obj 0 */
-    pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pRGBArow = pData->pRGBArow;
-  iM       = 0;                        /* start at pixel 0 */
-  iB       = 0;
-  iS       = 0;
-
-  if (pBuf->bHasTRNS)                  /* tRNS encountered ? */
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      if (!iM)                         /* mask underflow ? */
-      {
-        iB = *pWorkrow;                /* get next input-byte */
-        pWorkrow++;
-        iM = 0xF0;
-        iS = 4;
-      }
-                                       /* get the gray level */
-      iQ = (mng_uint8)((iB & iM) >> iS);
-
-      if (iQ == pBuf->iTRNSgray)       /* transparent ? */
-      {
-        *pRGBArow     = 0;             /* put in intermediate row */
-        *(pRGBArow+1) = 0;
-        *(pRGBArow+2) = 0;
-        *(pRGBArow+3) = 0;
-      }
-      else
-      {                                /* expand to 8-bit by replication */
-        iQ = (mng_uint8)(iQ + (iQ << 4));
-
-        *pRGBArow     = iQ;            /* put in intermediate row */
-        *(pRGBArow+1) = iQ;
-        *(pRGBArow+2) = iQ;
-        *(pRGBArow+3) = 0xFF;
-      }
-
-      pRGBArow += 4;                   /* next pixel */
-      iM >>=  4;
-      iS -= 4;
-    }
-
-    pData->bIsOpaque = MNG_FALSE;      /* it's not fully opaque */
-  }
-  else
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      if (!iM)                         /* mask underflow ? */
-      {
-        iB = *pWorkrow;                /* get next input-byte */
-        pWorkrow++;
-        iM = 0xF0;
-        iS = 4;
-      }
-                                       /* get the gray level */
-      iQ = (mng_uint8)((iB & iM) >> iS);
-      iQ = (mng_uint8)(iQ + (iQ << 4));/* expand to 8-bit by replication */
-
-      *pRGBArow     = iQ;              /* put in intermediate row */
-      *(pRGBArow+1) = iQ;
-      *(pRGBArow+2) = iQ;
-      *(pRGBArow+3) = 0xFF;
-
-      pRGBArow += 4;                   /* next pixel */
-      iM >>=  4;
-      iS -= 4;
-    }
-
-    pData->bIsOpaque = MNG_TRUE;       /* it's fully opaque */
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_G4, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_NO_1_2_4BIT_SUPPORT */
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_g8 (mng_datap pData)
-{
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pRGBArow;
-  mng_int32      iX;
-  mng_uint8      iB;
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_G8, MNG_LC_START);
-#endif
-
-  if (!pBuf)                           /* no object? then use obj 0 */
-    pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pRGBArow = pData->pRGBArow;
-
-  if (pBuf->bHasTRNS)                  /* tRNS encountered ? */
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      iB = *pWorkrow;                  /* get next input-byte */
-
-      if (iB == pBuf->iTRNSgray)       /* transparent ? */
-      {
-        *pRGBArow     = 0;             /* put in intermediate row */
-        *(pRGBArow+1) = 0;
-        *(pRGBArow+2) = 0;
-        *(pRGBArow+3) = 0;
-      }
-      else
-      {
-        *pRGBArow     = iB;            /* put in intermediate row */
-        *(pRGBArow+1) = iB;
-        *(pRGBArow+2) = iB;
-        *(pRGBArow+3) = 0xFF;
-      }
-
-      pRGBArow += 4;                   /* next pixel */
-      pWorkrow++;
-    }
-
-    pData->bIsOpaque = MNG_FALSE;      /* it's not fully opaque */
-  }
-  else
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      iB = *pWorkrow;                  /* get next input-byte */
-
-      *pRGBArow     = iB;              /* put in intermediate row */
-      *(pRGBArow+1) = iB;
-      *(pRGBArow+2) = iB;
-      *(pRGBArow+3) = 0xFF;
-
-      pRGBArow += 4;                   /* next pixel */
-      pWorkrow++;
-    }
-
-    pData->bIsOpaque = MNG_TRUE;       /* it's fully opaque */
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_G8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_process_g16 (mng_datap pData)
-{
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pRGBArow;
-  mng_int32      iX;
-  mng_uint16     iW;
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_G16, MNG_LC_START);
-#endif
-
-  if (!pBuf)                           /* no object? then use obj 0 */
-    pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pRGBArow = pData->pRGBArow;
-
-  if (pBuf->bHasTRNS)                  /* tRNS encountered ? */
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      iW = mng_get_uint16 (pWorkrow);  /* get input */
-
-      if (iW == pBuf->iTRNSgray)       /* transparent ? */
-      {                                /* put in intermediate row */
-        mng_put_uint16 (pRGBArow,   0);
-        mng_put_uint16 (pRGBArow+2, 0);
-        mng_put_uint16 (pRGBArow+4, 0);
-        mng_put_uint16 (pRGBArow+6, 0);
-      }
-      else
-      {                                /* put in intermediate row */
-        mng_put_uint16 (pRGBArow,   iW);
-        mng_put_uint16 (pRGBArow+2, iW);
-        mng_put_uint16 (pRGBArow+4, iW);
-        mng_put_uint16 (pRGBArow+6, 0xFFFF);
-      }
-
-      pRGBArow += 8;                   /* next pixel */
-      pWorkrow += 2;
-    }
-
-    pData->bIsOpaque = MNG_FALSE;      /* it's not fully opaque */
-  }
-  else
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      iW = mng_get_uint16 (pWorkrow);  /* get input */
-
-      mng_put_uint16 (pRGBArow,   iW); /* and put in intermediate row */
-      mng_put_uint16 (pRGBArow+2, iW);
-      mng_put_uint16 (pRGBArow+4, iW);
-      mng_put_uint16 (pRGBArow+6, 0xFFFF);
-
-      pRGBArow += 8;                   /* next pixel */
-      pWorkrow += 2;
-    }
-
-    pData->bIsOpaque = MNG_TRUE;       /* it's fully opaque */
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_G16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_rgb8 (mng_datap pData)
-{
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pRGBArow;
-  mng_int32      iX;
-  mng_uint8      iR, iG, iB;
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_RGB8, MNG_LC_START);
-#endif
-
-  if (!pBuf)                           /* no object? then use obj 0 */
-    pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pRGBArow = pData->pRGBArow;
-
-  if (pBuf->bHasTRNS)                  /* tRNS encountered ? */
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      iR = *pWorkrow;                  /* get the RGB values */
-      iG = *(pWorkrow+1);
-      iB = *(pWorkrow+2);
-                                       /* transparent ? */
-      if ((iR == pBuf->iTRNSred) && (iG == pBuf->iTRNSgreen) &&
-          (iB == pBuf->iTRNSblue))
-      {
-        *pRGBArow     = 0;             /* this pixel is transparent ! */
-        *(pRGBArow+1) = 0;
-        *(pRGBArow+2) = 0;
-        *(pRGBArow+3) = 0;
-      }
-      else
-      {
-        *pRGBArow     = iR;            /* copy the RGB values */
-        *(pRGBArow+1) = iG;
-        *(pRGBArow+2) = iB;
-        *(pRGBArow+3) = 0xFF;          /* this one isn't transparent */
-      }
-
-      pWorkrow += 3;                   /* next pixel */
-      pRGBArow += 4;
-    }
-
-    pData->bIsOpaque = MNG_FALSE;      /* it's not fully opaque */
-  }
-  else
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      *pRGBArow     = *pWorkrow;       /* copy the RGB bytes */
-      *(pRGBArow+1) = *(pWorkrow+1);
-      *(pRGBArow+2) = *(pWorkrow+2);
-      *(pRGBArow+3) = 0xFF;            /* no alpha; so always fully opaque */
-
-      pWorkrow += 3;                   /* next pixel */
-      pRGBArow += 4;
-    }
-
-    pData->bIsOpaque = MNG_TRUE;       /* it's fully opaque */
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_RGB8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_process_rgb16 (mng_datap pData)
-{
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pRGBArow;
-  mng_int32      iX;
-  mng_uint16     iR, iG, iB;
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_RGB16, MNG_LC_START);
-#endif
-
-  if (!pBuf)                           /* no object? then use obj 0 */
-    pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pRGBArow = pData->pRGBArow;
-
-  if (pBuf->bHasTRNS)                  /* tRNS encountered ? */
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      iR = mng_get_uint16 (pWorkrow);  /* get the RGB values */
-      iG = mng_get_uint16 (pWorkrow+2);
-      iB = mng_get_uint16 (pWorkrow+4);
-                                       /* transparent ? */
-      if ((iR == pBuf->iTRNSred) && (iG == pBuf->iTRNSgreen) &&
-          (iB == pBuf->iTRNSblue))
-      {                                /* transparent then */
-        mng_put_uint16 (pRGBArow,   0);
-        mng_put_uint16 (pRGBArow+2, 0);
-        mng_put_uint16 (pRGBArow+4, 0);
-        mng_put_uint16 (pRGBArow+6, 0);
-      }
-      else
-      {                                /* put in intermediate row */
-        mng_put_uint16 (pRGBArow,   iR);
-        mng_put_uint16 (pRGBArow+2, iG);
-        mng_put_uint16 (pRGBArow+4, iB);
-        mng_put_uint16 (pRGBArow+6, 0xFFFF);
-      }
-
-      pWorkrow += 6;                   /* next pixel */
-      pRGBArow += 8;
-    }
-
-    pData->bIsOpaque = MNG_FALSE;      /* it's not fully opaque */
-  }
-  else
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {                                  /* copy the RGB values */
-      mng_put_uint16 (pRGBArow,   mng_get_uint16 (pWorkrow  ));
-      mng_put_uint16 (pRGBArow+2, mng_get_uint16 (pWorkrow+2));
-      mng_put_uint16 (pRGBArow+4, mng_get_uint16 (pWorkrow+4));
-      mng_put_uint16 (pRGBArow+6, 0xFFFF);
-
-      pWorkrow += 6;                   /* next pixel */
-      pRGBArow += 8;
-    }
-
-    pData->bIsOpaque = MNG_TRUE;       /* it's fully opaque */
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_RGB16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-mng_retcode mng_process_idx1 (mng_datap pData)
-{
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pRGBArow;
-  mng_int32      iX;
-  mng_uint8      iB;
-  mng_uint8      iM;
-  mng_uint32     iS;
-  mng_uint8      iQ;
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_IDX1, MNG_LC_START);
-#endif
-
-  if (!pBuf)                           /* no object? then use obj 0 */
-    pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pRGBArow = pData->pRGBArow;
-  iM       = 0;                        /* start at pixel 0 */
-  iB       = 0;
-  iS       = 0;
-
-  if (pBuf->bHasTRNS)                  /* tRNS encountered ? */
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      if (!iM)                         /* mask underflow ? */
-      {
-        iB = *pWorkrow;                /* get next input-byte */
-        pWorkrow++;
-        iM = 0x80;
-        iS = 7;
-      }
-                                       /* get the index */
-      iQ = (mng_uint8)((iB & iM) >> iS);
-                                       /* index valid ? */
-      if ((mng_uint32)iQ < pBuf->iPLTEcount)
-      {                                /* put in intermediate row */
-        *pRGBArow     = pBuf->aPLTEentries [iQ].iRed;
-        *(pRGBArow+1) = pBuf->aPLTEentries [iQ].iGreen;
-        *(pRGBArow+2) = pBuf->aPLTEentries [iQ].iBlue;
-                                       /* transparency for this index ? */
-        if ((mng_uint32)iQ < pBuf->iTRNScount)
-          *(pRGBArow+3) = pBuf->aTRNSentries [iQ];
-        else
-          *(pRGBArow+3) = 0xFF;
-      }
-      else
-        MNG_ERROR (pData, MNG_PLTEINDEXERROR);
-
-      pRGBArow += 4;                   /* next pixel */
-      iM >>=  1;
-      iS -= 1;
-    }
-
-    pData->bIsOpaque = MNG_FALSE;      /* it's not fully opaque */
-  }
-  else
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      if (!iM)                         /* mask underflow ? */
-      {
-        iB = *pWorkrow;                /* get next input-byte */
-        pWorkrow++;
-        iM = 0x80;
-        iS = 7;
-      }
-                                       /* get the index */
-      iQ = (mng_uint8)((iB & iM) >> iS);
-                                       /* index valid ? */
-      if ((mng_uint32)iQ < pBuf->iPLTEcount)
-      {                                /* put in intermediate row */
-        *pRGBArow     = pBuf->aPLTEentries [iQ].iRed;
-        *(pRGBArow+1) = pBuf->aPLTEentries [iQ].iGreen;
-        *(pRGBArow+2) = pBuf->aPLTEentries [iQ].iBlue;
-        *(pRGBArow+3) = 0xFF;
-      }
-      else
-        MNG_ERROR (pData, MNG_PLTEINDEXERROR);
-
-      pRGBArow += 4;                   /* next pixel */
-      iM >>=  1;
-      iS -= 1;
-    }
-
-    pData->bIsOpaque = MNG_TRUE;       /* it's fully opaque */
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_IDX1, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_idx2 (mng_datap pData)
-{
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pRGBArow;
-  mng_int32      iX;
-  mng_uint8      iB;
-  mng_uint8      iM;
-  mng_uint32     iS;
-  mng_uint8      iQ;
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_IDX2, MNG_LC_START);
-#endif
-
-  if (!pBuf)                           /* no object? then use obj 0 */
-    pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pRGBArow = pData->pRGBArow;
-  iM       = 0;                        /* start at pixel 0 */
-  iB       = 0;
-  iS       = 0;
-
-  if (pBuf->bHasTRNS)                  /* tRNS encountered ? */
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      if (!iM)                         /* mask underflow ? */
-      {
-        iB = *pWorkrow;                /* get next input-byte */
-        pWorkrow++;
-        iM = 0xC0;
-        iS = 6;
-      }
-                                       /* get the index */
-      iQ = (mng_uint8)((iB & iM) >> iS);
-                                       /* index valid ? */
-      if ((mng_uint32)iQ < pBuf->iPLTEcount)
-      {                                /* put in intermediate row */
-        *pRGBArow     = pBuf->aPLTEentries [iQ].iRed;
-        *(pRGBArow+1) = pBuf->aPLTEentries [iQ].iGreen;
-        *(pRGBArow+2) = pBuf->aPLTEentries [iQ].iBlue;
-                                       /* transparency for this index ? */
-        if ((mng_uint32)iQ < pBuf->iTRNScount)
-          *(pRGBArow+3) = pBuf->aTRNSentries [iQ];
-        else
-          *(pRGBArow+3) = 0xFF;
-      }
-      else
-        MNG_ERROR (pData, MNG_PLTEINDEXERROR);
-
-      pRGBArow += 4;                   /* next pixel */
-      iM >>=  2;
-      iS -= 2;
-    }
-
-    pData->bIsOpaque = MNG_FALSE;      /* it's not fully opaque */
-  }
-  else
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      if (!iM)                         /* mask underflow ? */
-      {
-        iB = *pWorkrow;                /* get next input-byte */
-        pWorkrow++;
-        iM = 0xC0;
-        iS = 6;
-      }
-                                       /* get the index */
-      iQ = (mng_uint8)((iB & iM) >> iS);
-                                       /* index valid ? */
-      if ((mng_uint32)iQ < pBuf->iPLTEcount)
-      {                                /* put in intermediate row */
-        *pRGBArow     = pBuf->aPLTEentries [iQ].iRed;
-        *(pRGBArow+1) = pBuf->aPLTEentries [iQ].iGreen;
-        *(pRGBArow+2) = pBuf->aPLTEentries [iQ].iBlue;
-        *(pRGBArow+3) = 0xFF;
-      }
-      else
-        MNG_ERROR (pData, MNG_PLTEINDEXERROR);
-
-      pRGBArow += 4;                   /* next pixel */
-      iM >>=  2;
-      iS -= 2;
-    }
-
-    pData->bIsOpaque = MNG_TRUE;       /* it's fully opaque */
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_IDX2, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_idx4 (mng_datap pData)
-{
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pRGBArow;
-  mng_int32      iX;
-  mng_uint8      iB;
-  mng_uint8      iM;
-  mng_uint32     iS;
-  mng_uint8      iQ;
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_IDX4, MNG_LC_START);
-#endif
-
-  if (!pBuf)                           /* no object? then use obj 0 */
-    pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pRGBArow = pData->pRGBArow;
-  iM       = 0;                        /* start at pixel 0 */
-  iB       = 0;
-  iS       = 0;
-
-  if (pBuf->bHasTRNS)                  /* tRNS encountered ? */
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      if (!iM)                         /* mask underflow ? */
-      {
-        iB = pWorkrow [0];             /* get next input-byte */
-        pWorkrow++;
-        iM = 0xF0;
-        iS = 4;
-      }
-                                       /* get the index */
-      iQ = (mng_uint8)((iB & iM) >> iS);
-                                       /* index valid ? */
-      if ((mng_uint32)iQ < pBuf->iPLTEcount)
-      {                                /* put in intermediate row */
-        pRGBArow [0] = pBuf->aPLTEentries [iQ].iRed;
-        pRGBArow [1] = pBuf->aPLTEentries [iQ].iGreen;
-        pRGBArow [2] = pBuf->aPLTEentries [iQ].iBlue;
-                                       /* transparency for this index ? */
-        if ((mng_uint32)iQ < pBuf->iTRNScount)
-          pRGBArow [3] = pBuf->aTRNSentries [iQ];
-        else
-          pRGBArow [3] = 0xFF;
-      }
-      else
-        MNG_ERROR (pData, MNG_PLTEINDEXERROR);
-
-      pRGBArow += 4;                   /* next pixel */
-      iM >>=  4;
-      iS -= 4;
-    }
-
-    pData->bIsOpaque = MNG_FALSE;      /* it's not fully opaque */
-  }
-  else
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      if (!iM)                         /* mask underflow ? */
-      {
-        iB = pWorkrow [0];             /* get next input-byte */
-        pWorkrow++;
-        iM = 0xF0;
-        iS = 4;
-      }
-                                       /* get the index */
-      iQ = (mng_uint8)((iB & iM) >> iS);
-                                       /* index valid ? */
-      if ((mng_uint32)iQ < pBuf->iPLTEcount)
-      {                                /* put in intermediate row */
-        pRGBArow [0] = pBuf->aPLTEentries [iQ].iRed;
-        pRGBArow [1] = pBuf->aPLTEentries [iQ].iGreen;
-        pRGBArow [2] = pBuf->aPLTEentries [iQ].iBlue;
-        pRGBArow [3] = 0xFF;
-      }
-      else
-        MNG_ERROR (pData, MNG_PLTEINDEXERROR);
-
-      pRGBArow += 4;                   /* next pixel */
-      iM >>=  4;
-      iS -= 4;
-    }
-
-    pData->bIsOpaque = MNG_TRUE;       /* it's fully opaque */
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_IDX4, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_NO_1_2_4BIT_SUPPORT */
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_idx8 (mng_datap pData)
-{
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pRGBArow;
-  mng_int32      iX;
-  mng_uint8      iQ;
-  mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_IDX8, MNG_LC_START);
-#endif
-
-  if (!pBuf)                           /* no object? then use obj 0 */
-    pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pRGBArow = pData->pRGBArow;
-
-  if (pBuf->bHasTRNS)                  /* tRNS encountered ? */
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      iQ = *pWorkrow;                  /* get input byte */
-                                       /* index valid ? */
-      if ((mng_uint32)iQ < pBuf->iPLTEcount)
-      {                                /* put in intermediate row */
-        pRGBArow [0] = pBuf->aPLTEentries [iQ].iRed;
-        pRGBArow [1] = pBuf->aPLTEentries [iQ].iGreen;
-        pRGBArow [2] = pBuf->aPLTEentries [iQ].iBlue;
-                                       /* transparency for this index ? */
-        if ((mng_uint32)iQ < pBuf->iTRNScount)
-          pRGBArow [3] = pBuf->aTRNSentries [iQ];
-        else
-          pRGBArow [3] = 0xFF;
-      }
-      else
-        MNG_ERROR (pData, MNG_PLTEINDEXERROR);
-
-      pRGBArow += 4;                   /* next pixel */
-      pWorkrow++;
-    }
-
-    pData->bIsOpaque = MNG_FALSE;      /* it's not fully opaque */
-  }
-  else
-  {
-#ifdef MNG_DECREMENT_LOOPS
-    for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-    for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-    {
-      iQ = *pWorkrow;                  /* get input byte */
-                                       /* index valid ? */
-      if ((mng_uint32)iQ < pBuf->iPLTEcount)
-      {                                /* put in intermediate row */
-        pRGBArow [0] = pBuf->aPLTEentries [iQ].iRed;
-        pRGBArow [1] = pBuf->aPLTEentries [iQ].iGreen;
-        pRGBArow [2] = pBuf->aPLTEentries [iQ].iBlue;
-        pRGBArow [3] = 0xFF;
-      }
-      else
-        MNG_ERROR (pData, MNG_PLTEINDEXERROR);
-
-      pRGBArow += 4;                   /* next pixel */
-      pWorkrow++;
-    }
-
-    pData->bIsOpaque = MNG_TRUE;       /* it's fully opaque */
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_IDX8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_ga8 (mng_datap pData)
-{
-  mng_uint8p pWorkrow;
-  mng_uint8p pRGBArow;
-  mng_int32  iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_GA8, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pRGBArow = pData->pRGBArow;
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    *pRGBArow     = *pWorkrow;         /* copy the gray value */
-    *(pRGBArow+1) = *pWorkrow;
-    *(pRGBArow+2) = *pWorkrow;
-    *(pRGBArow+3) = *(pWorkrow+1);     /* copy the alpha value */
-
-    pWorkrow += 2;                     /* next pixel */
-    pRGBArow += 4;
-  }
-
-  pData->bIsOpaque = MNG_FALSE;        /* it's definitely not fully opaque */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_GA8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_process_ga16 (mng_datap pData)
-{
-  mng_uint8p  pWorkrow;
-  mng_uint8p  pRGBArow;
-  mng_int32  iX;
-  mng_uint16 iW;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_GA16, MNG_LC_START);
-#endif
-                                       /* temporary work pointers */
-  pWorkrow = pData->pWorkrow + pData->iPixelofs;
-  pRGBArow = pData->pRGBArow;
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    iW = mng_get_uint16 (pWorkrow);    /* copy the gray value */
-    mng_put_uint16 (pRGBArow,   iW);
-    mng_put_uint16 (pRGBArow+2, iW);
-    mng_put_uint16 (pRGBArow+4, iW);
-                                       /* copy the alpha value */
-    mng_put_uint16 (pRGBArow+6, mng_get_uint16 (pWorkrow+2));
-
-    pWorkrow += 4;                     /* next pixel */
-    pRGBArow += 8;
-  }
-
-  pData->bIsOpaque = MNG_FALSE;        /* it's definitely not fully opaque */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_GA16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_rgba8 (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_RGBA8, MNG_LC_START);
-#endif
-                                       /* this is the easiest transform */
-  MNG_COPY (pData->pRGBArow, pData->pWorkrow + pData->iPixelofs, pData->iRowsize);
-
-  pData->bIsOpaque = MNG_FALSE;        /* it's definitely not fully opaque */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_RGBA8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_process_rgba16 (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_RGBA16, MNG_LC_START);
-#endif
-                                       /* this is the easiest transform */
-  MNG_COPY (pData->pRGBArow, pData->pWorkrow + pData->iPixelofs, pData->iRowsize);
-
-  pData->bIsOpaque = MNG_FALSE;        /* it's definitely not fully opaque */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_RGBA16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Row processing initialization routines - set up the variables needed   * */
-/* * to process uncompressed row-data                                       * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_FOOTPRINT_INIT
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-mng_retcode mng_init_g1_ni     (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_G1_NI, MNG_LC_START);
-#endif
-
-  if (pData->fDisplayrow)
-    pData->fProcessrow = (mng_fptr)mng_process_g1;
-
-  if (pData->pStoreobj)                /* store in object too ? */
-  {                                    /* immediate delta ? */
-#ifndef MNG_NO_DELTA_PNG
-    if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
-      pData->fStorerow = (mng_fptr)mng_delta_g1;
-    else
-#endif
-      pData->fStorerow = (mng_fptr)mng_store_g1;
-  }
-
-#ifdef FILTER192                       /* leveling & differing ? */
-  if (pData->iFilter == MNG_FILTER_DIFFERING)
-    pData->fDifferrow  = (mng_fptr)mng_differ_g1;
-#endif
-
-  pData->iPass       = -1;
-  pData->iRow        = 0;
-  pData->iRowinc     = 1;
-  pData->iCol        = 0;
-  pData->iColinc     = 1;
-  pData->iRowsamples = pData->iDatawidth;
-  pData->iSamplemul  = 1;
-  pData->iSampleofs  = 7;
-  pData->iSamplediv  = 3;
-  pData->iRowsize    = (pData->iRowsamples + 7) >> 3;
-  pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
-  pData->iFilterbpp  = 1;
-  pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_G1_NI, MNG_LC_END);
-#endif
-
-  return mng_init_rowproc (pData);
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_init_g1_i      (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_G1_I, MNG_LC_START);
-#endif
-
-  if (pData->fDisplayrow)
-    pData->fProcessrow = (mng_fptr)mng_process_g1;
-
-  if (pData->pStoreobj)                /* store in object too ? */
-  {                                    /* immediate delta ? */
-#ifndef MNG_NO_DELTA_PNG
-    if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
-      pData->fStorerow = (mng_fptr)mng_delta_g1;
-    else
-#endif
-      pData->fStorerow = (mng_fptr)mng_store_g1;
-  }
-
-#ifdef FILTER192                       /* leveling & differing ? */
-  if (pData->iFilter == MNG_FILTER_DIFFERING)
-    pData->fDifferrow  = (mng_fptr)mng_differ_g1;
-#endif
-
-  pData->iPass       = 0;              /* from 0..6; is 1..7 in specifications */
-  pData->iRow        = interlace_row     [0];
-  pData->iRowinc     = interlace_rowskip [0];
-  pData->iCol        = interlace_col     [0];
-  pData->iColinc     = interlace_colskip [0];
-  pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
-  pData->iSamplemul  = 1;
-  pData->iSampleofs  = 7;
-  pData->iSamplediv  = 3;
-  pData->iRowsize    = ((pData->iRowsamples + 7) >> 3);
-  pData->iRowmax     = ((pData->iDatawidth + 7) >> 3) + pData->iPixelofs;
-  pData->iFilterbpp  = 1;
-  pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_G1_I, MNG_LC_END);
-#endif
-
-  return mng_init_rowproc (pData);
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_init_g2_ni     (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_G2_NI, MNG_LC_START);
-#endif
-
-  if (pData->fDisplayrow)
-    pData->fProcessrow = (mng_fptr)mng_process_g2;
-
-  if (pData->pStoreobj)                /* store in object too ? */
-  {                                    /* immediate delta ? */
-#ifndef MNG_NO_DELTA_PNG
-    if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
-      pData->fStorerow = (mng_fptr)mng_delta_g2;
-    else
-#endif
-      pData->fStorerow = (mng_fptr)mng_store_g2;
-  }
-
-#ifdef FILTER192                       /* leveling & differing ? */
-  if (pData->iFilter == MNG_FILTER_DIFFERING)
-    pData->fDifferrow  = (mng_fptr)mng_differ_g2;
-#endif
-
-  pData->iPass       = -1;
-  pData->iRow        = 0;
-  pData->iRowinc     = 1;
-  pData->iCol        = 0;
-  pData->iColinc     = 1;
-  pData->iRowsamples = pData->iDatawidth;
-  pData->iSamplemul  = 1;
-  pData->iSampleofs  = 3;
-  pData->iSamplediv  = 2;
-  pData->iRowsize    = (pData->iRowsamples + 3) >> 2;
-  pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
-  pData->iFilterbpp  = 1;
-  pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_G2_NI, MNG_LC_END);
-#endif
-
-  return mng_init_rowproc (pData);
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_init_g2_i      (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_G2_I, MNG_LC_START);
-#endif
-
-  if (pData->fDisplayrow)
-    pData->fProcessrow = (mng_fptr)mng_process_g2;
-
-  if (pData->pStoreobj)                /* store in object too ? */
-  {                                    /* immediate delta ? */
-#ifndef MNG_NO_DELTA_PNG
-    if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
-      pData->fStorerow = (mng_fptr)mng_delta_g2;
-    else
-#endif
-      pData->fStorerow = (mng_fptr)mng_store_g2;
-  }
-
-#ifdef FILTER192                       /* leveling & differing ? */
-  if (pData->iFilter == MNG_FILTER_DIFFERING)
-    pData->fDifferrow  = (mng_fptr)mng_differ_g2;
-#endif
-
-  pData->iPass       = 0;              /* from 0..6; is 1..7 in specifications */
-  pData->iRow        = interlace_row     [0];
-  pData->iRowinc     = interlace_rowskip [0];
-  pData->iCol        = interlace_col     [0];
-  pData->iColinc     = interlace_colskip [0];
-  pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
-  pData->iSamplemul  = 1;
-  pData->iSampleofs  = 3;
-  pData->iSamplediv  = 2;
-  pData->iRowsize    = ((pData->iRowsamples + 3) >> 2);
-  pData->iRowmax     = ((pData->iDatawidth + 3) >> 2) + pData->iPixelofs;
-  pData->iFilterbpp  = 1;
-  pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_G2_I, MNG_LC_END);
-#endif
-
-  return mng_init_rowproc (pData);
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_init_g4_ni     (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_G4_NI, MNG_LC_START);
-#endif
-
-  if (pData->fDisplayrow)
-    pData->fProcessrow = (mng_fptr)mng_process_g4;
-
-  if (pData->pStoreobj)                /* store in object too ? */
-  {                                    /* immediate delta ? */
-#ifndef MNG_NO_DELTA_PNG
-    if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
-      pData->fStorerow = (mng_fptr)mng_delta_g4;
-    else
-#endif
-      pData->fStorerow = (mng_fptr)mng_store_g4;
-  }
-
-#ifdef FILTER192                       /* leveling & differing ? */
-  if (pData->iFilter == MNG_FILTER_DIFFERING)
-    pData->fDifferrow  = (mng_fptr)mng_differ_g4;
-#endif
-
-  pData->iPass       = -1;
-  pData->iRow        = 0;
-  pData->iRowinc     = 1;
-  pData->iCol        = 0;
-  pData->iColinc     = 1;
-  pData->iRowsamples = pData->iDatawidth;
-  pData->iSamplemul  = 1;
-  pData->iSampleofs  = 1;
-  pData->iSamplediv  = 1;
-  pData->iRowsize    = (pData->iRowsamples + 1) >> 1;
-  pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
-  pData->iFilterbpp  = 1;
-  pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_G4_NI, MNG_LC_END);
-#endif
-
-  return mng_init_rowproc (pData);
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_init_g4_i      (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_G4_I, MNG_LC_START);
-#endif
-
-  if (pData->fDisplayrow)
-    pData->fProcessrow = (mng_fptr)mng_process_g4;
-
-  if (pData->pStoreobj)                /* store in object too ? */
-  {                                    /* immediate delta ? */
-#ifndef MNG_NO_DELTA_PNG
-    if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
-      pData->fStorerow = (mng_fptr)mng_delta_g4;
-    else
-#endif
-      pData->fStorerow = (mng_fptr)mng_store_g4;
-  }
-
-#ifdef FILTER192                       /* leveling & differing ? */
-  if (pData->iFilter == MNG_FILTER_DIFFERING)
-    pData->fDifferrow  = (mng_fptr)mng_differ_g4;
-#endif
-
-  pData->iPass       = 0;              /* from 0..6; is 1..7 in specifications */
-  pData->iRow        = interlace_row     [0];
-  pData->iRowinc     = interlace_rowskip [0];
-  pData->iCol        = interlace_col     [0];
-  pData->iColinc     = interlace_colskip [0];
-  pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
-  pData->iSamplemul  = 1;
-  pData->iSampleofs  = 1;
-  pData->iSamplediv  = 1;
-  pData->iRowsize    = ((pData->iRowsamples + 1) >> 1);
-  pData->iRowmax     = ((pData->iDatawidth + 1) >> 1) + pData->iPixelofs;
-  pData->iFilterbpp  = 1;
-  pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_G4_I, MNG_LC_END);
-#endif
-
-  return mng_init_rowproc (pData);
-}
-#endif /* MNG_NO_1_2_4BIT_SUPPORT */
-
-/* ************************************************************************** */
-
-mng_retcode mng_init_g8_ni     (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_G8_NI, MNG_LC_START);
-#endif
-
-  if (pData->fDisplayrow)
-    pData->fProcessrow = (mng_fptr)mng_process_g8;
-
-  if (pData->pStoreobj)                /* store in object too ? */
-  {                                    /* immediate delta ? */
-#ifndef MNG_NO_DELTA_PNG
-    if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
-      pData->fStorerow = (mng_fptr)mng_delta_g8;
-    else
-#endif
-      pData->fStorerow = (mng_fptr)mng_store_g8;
-  }
-
-#ifdef FILTER192                       /* leveling & differing ? */
-  if (pData->iFilter == MNG_FILTER_DIFFERING)
-    pData->fDifferrow  = (mng_fptr)mng_differ_g8;
-#endif
-
-  pData->iPass       = -1;
-  pData->iRow        = 0;
-  pData->iRowinc     = 1;
-  pData->iCol        = 0;
-  pData->iColinc     = 1;
-  pData->iRowsamples = pData->iDatawidth;
-  pData->iSamplemul  = 1;
-  pData->iSampleofs  = 0;
-  pData->iSamplediv  = 0;
-  pData->iRowsize    = pData->iRowsamples;
-  pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
-  pData->iFilterbpp  = 1;
-  pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_G8_NI, MNG_LC_END);
-#endif
-
-  return mng_init_rowproc (pData);
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_init_g8_i      (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_G8_I, MNG_LC_START);
-#endif
-
-  if (pData->fDisplayrow)
-    pData->fProcessrow = (mng_fptr)mng_process_g8;
-
-  if (pData->pStoreobj)                /* store in object too ? */
-  {                                    /* immediate delta ? */
-#ifndef MNG_NO_DELTA_PNG
-    if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
-      pData->fStorerow = (mng_fptr)mng_delta_g8;
-    else
-#endif
-      pData->fStorerow = (mng_fptr)mng_store_g8;
-  }
-
-#ifdef FILTER192                       /* leveling & differing ? */
-  if (pData->iFilter == MNG_FILTER_DIFFERING)
-    pData->fDifferrow  = (mng_fptr)mng_differ_g8;
-#endif
-
-  pData->iPass       = 0;              /* from 0..6; is 1..7 in specifications */
-  pData->iRow        = interlace_row     [0];
-  pData->iRowinc     = interlace_rowskip [0];
-  pData->iCol        = interlace_col     [0];
-  pData->iColinc     = interlace_colskip [0];
-  pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
-  pData->iSamplemul  = 1;
-  pData->iSampleofs  = 0;
-  pData->iSamplediv  = 0;
-  pData->iRowsize    = pData->iRowsamples;
-  pData->iRowmax     = pData->iDatawidth + pData->iPixelofs;
-  pData->iFilterbpp  = 1;
-  pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_G8_I, MNG_LC_END);
-#endif
-
-  return mng_init_rowproc (pData);
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_init_g16_ni    (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_G16_NI, MNG_LC_START);
-#endif
-
-  if (pData->fDisplayrow)
-    pData->fProcessrow = (mng_fptr)mng_process_g16;
-
-  if (pData->pStoreobj)                /* store in object too ? */
-  {                                    /* immediate delta ? */
-#ifndef MNG_NO_DELTA_PNG
-    if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
-      pData->fStorerow = (mng_fptr)mng_delta_g16;
-    else
-#endif
-      pData->fStorerow = (mng_fptr)mng_store_g16;
-  }
-
-#ifdef FILTER192                       /* leveling & differing ? */
-  if (pData->iFilter == MNG_FILTER_DIFFERING)
-    pData->fDifferrow  = (mng_fptr)mng_differ_g16;
-#endif
-
-  pData->iPass       = -1;
-  pData->iRow        = 0;
-  pData->iRowinc     = 1;
-  pData->iCol        = 0;
-  pData->iColinc     = 1;
-  pData->iRowsamples = pData->iDatawidth;
-  pData->iSamplemul  = 2;
-  pData->iSampleofs  = 0;
-  pData->iSamplediv  = 0;
-  pData->iRowsize    = pData->iRowsamples << 1;
-  pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
-  pData->iFilterbpp  = 2;
-  pData->bIsRGBA16   = MNG_TRUE;       /* intermediate row is 16-bit deep */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_G16_NI, MNG_LC_END);
-#endif
-
-  return mng_init_rowproc (pData);
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_init_g16_i     (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_G16_I, MNG_LC_START);
-#endif
-
-  if (pData->fDisplayrow)
-    pData->fProcessrow = (mng_fptr)mng_process_g16;
-
-  if (pData->pStoreobj)                /* store in object too ? */
-  {                                    /* immediate delta ? */
-#ifndef MNG_NO_DELTA_PNG
-    if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
-      pData->fStorerow = (mng_fptr)mng_delta_g16;
-    else
-#endif
-      pData->fStorerow = (mng_fptr)mng_store_g16;
-  }
-
-#ifdef FILTER192                       /* leveling & differing ? */
-  if (pData->iFilter == MNG_FILTER_DIFFERING)
-    pData->fDifferrow  = (mng_fptr)mng_differ_g16;
-#endif
-
-  pData->iPass       = 0;              /* from 0..6; is 1..7 in specifications */
-  pData->iRow        = interlace_row     [0];
-  pData->iRowinc     = interlace_rowskip [0];
-  pData->iCol        = interlace_col     [0];
-  pData->iColinc     = interlace_colskip [0];
-  pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
-  pData->iSamplemul  = 2;
-  pData->iSampleofs  = 0;
-  pData->iSamplediv  = 0;
-  pData->iRowsize    = pData->iRowsamples << 1;
-  pData->iRowmax     = (pData->iDatawidth << 1) + pData->iPixelofs;
-  pData->iFilterbpp  = 2;
-  pData->bIsRGBA16   = MNG_TRUE;       /* intermediate row is 16-bit deep */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_G16_I, MNG_LC_END);
-#endif
-
-  return mng_init_rowproc (pData);
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_init_rgb8_ni   (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_RGB8_NI, MNG_LC_START);
-#endif
-
-  if (pData->fDisplayrow)
-    pData->fProcessrow = (mng_fptr)mng_process_rgb8;
-
-  if (pData->pStoreobj)                /* store in object too ? */
-  {                                    /* immediate delta ? */
-#ifndef MNG_NO_DELTA_PNG
-    if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
-      pData->fStorerow = (mng_fptr)mng_delta_rgb8;
-    else
-#endif
-      pData->fStorerow = (mng_fptr)mng_store_rgb8;
-  }
-
-#ifdef FILTER192                       /* leveling & differing ? */
-  if (pData->iFilter == MNG_FILTER_DIFFERING)
-    pData->fDifferrow  = (mng_fptr)mng_differ_rgb8;
-#endif
-
-  pData->iPass       = -1;
-  pData->iRow        = 0;
-  pData->iRowinc     = 1;
-  pData->iCol        = 0;
-  pData->iColinc     = 1;
-  pData->iRowsamples = pData->iDatawidth;
-  pData->iSamplemul  = 3;
-  pData->iSampleofs  = 0;
-  pData->iSamplediv  = 0;
-  pData->iRowsize    = pData->iRowsamples * 3;
-  pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
-  pData->iFilterbpp  = 3;
-  pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_RGB8_NI, MNG_LC_END);
-#endif
-
-  return mng_init_rowproc (pData);
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_init_rgb8_i    (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_RGB8_I, MNG_LC_START);
-#endif
-
-  if (pData->fDisplayrow)
-    pData->fProcessrow = (mng_fptr)mng_process_rgb8;
-
-  if (pData->pStoreobj)                /* store in object too ? */
-  {                                    /* immediate delta ? */
-#ifndef MNG_NO_DELTA_PNG
-    if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
-      pData->fStorerow = (mng_fptr)mng_delta_rgb8;
-    else
-#endif
-      pData->fStorerow = (mng_fptr)mng_store_rgb8;
-  }
-
-#ifdef FILTER192                       /* leveling & differing ? */
-  if (pData->iFilter == MNG_FILTER_DIFFERING)
-    pData->fDifferrow  = (mng_fptr)mng_differ_rgb8;
-#endif
-
-  pData->iPass       = 0;              /* from 0..6; is 1..7 in specifications */
-  pData->iRow        = interlace_row     [0];
-  pData->iRowinc     = interlace_rowskip [0];
-  pData->iCol        = interlace_col     [0];
-  pData->iColinc     = interlace_colskip [0];
-  pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
-  pData->iSamplemul  = 3;
-  pData->iSampleofs  = 0;
-  pData->iSamplediv  = 0;
-  pData->iRowsize    = pData->iRowsamples * 3;
-  pData->iRowmax     = (pData->iDatawidth * 3) + pData->iPixelofs;
-  pData->iFilterbpp  = 3;
-  pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_RGB8_I, MNG_LC_END);
-#endif
-
-  return mng_init_rowproc (pData);
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_init_rgb16_ni  (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_RGB16_NI, MNG_LC_START);
-#endif
-
-  if (pData->fDisplayrow)
-    pData->fProcessrow = (mng_fptr)mng_process_rgb16;
-
-  if (pData->pStoreobj)                /* store in object too ? */
-  {                                    /* immediate delta ? */
-#ifndef MNG_NO_DELTA_PNG
-    if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
-      pData->fStorerow = (mng_fptr)mng_delta_rgb16;
-    else
-#endif
-      pData->fStorerow = (mng_fptr)mng_store_rgb16;
-  }
-
-#ifdef FILTER192                       /* leveling & differing ? */
-  if (pData->iFilter == MNG_FILTER_DIFFERING)
-    pData->fDifferrow  = (mng_fptr)mng_differ_rgb16;
-#endif
-
-  pData->iPass       = -1;
-  pData->iRow        = 0;
-  pData->iRowinc     = 1;
-  pData->iCol        = 0;
-  pData->iColinc     = 1;
-  pData->iRowsamples = pData->iDatawidth;
-  pData->iSamplemul  = 6;
-  pData->iSampleofs  = 0;
-  pData->iSamplediv  = 0;
-  pData->iRowsize    = pData->iRowsamples * 6;
-  pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
-  pData->iFilterbpp  = 6;
-  pData->bIsRGBA16   = MNG_TRUE;       /* intermediate row is 16-bit deep */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_RGB16_NI, MNG_LC_END);
-#endif
-
-  return mng_init_rowproc (pData);
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_init_rgb16_i   (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_RGB16_I, MNG_LC_START);
-#endif
-
-  if (pData->fDisplayrow)
-    pData->fProcessrow = (mng_fptr)mng_process_rgb16;
-
-  if (pData->pStoreobj)                /* store in object too ? */
-  {                                    /* immediate delta ? */
-#ifndef MNG_NO_DELTA_PNG
-    if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
-      pData->fStorerow = (mng_fptr)mng_delta_rgb16;
-    else
-#endif
-      pData->fStorerow = (mng_fptr)mng_store_rgb16;
-  }
-
-#ifdef FILTER192                       /* leveling & differing ? */
-  if (pData->iFilter == MNG_FILTER_DIFFERING)
-    pData->fDifferrow  = (mng_fptr)mng_differ_rgb16;
-#endif
-
-  pData->iPass       = 0;              /* from 0..6; is 1..7 in specifications */
-  pData->iRow        = interlace_row     [0];
-  pData->iRowinc     = interlace_rowskip [0];
-  pData->iCol        = interlace_col     [0];
-  pData->iColinc     = interlace_colskip [0];
-  pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
-  pData->iSamplemul  = 6;
-  pData->iSampleofs  = 0;
-  pData->iSamplediv  = 0;
-  pData->iRowsize    = pData->iRowsamples * 6;
-  pData->iRowmax     = (pData->iDatawidth * 6) + pData->iPixelofs;
-  pData->iFilterbpp  = 6;
-  pData->bIsRGBA16   = MNG_TRUE;       /* intermediate row is 16-bit deep */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_RGB16_I, MNG_LC_END);
-#endif
-
-  return mng_init_rowproc (pData);
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-mng_retcode mng_init_idx1_ni   (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_IDX1_NI, MNG_LC_START);
-#endif
-
-  if (pData->fDisplayrow)
-    pData->fProcessrow = (mng_fptr)mng_process_idx1;
-
-  if (pData->pStoreobj)                /* store in object too ? */
-  {                                    /* immediate delta ? */
-#ifndef MNG_NO_DELTA_PNG
-    if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
-      pData->fStorerow = (mng_fptr)mng_delta_idx1;
-    else
-#endif
-      pData->fStorerow = (mng_fptr)mng_store_idx1;
-  }
-
-#ifdef FILTER192                       /* leveling & differing ? */
-  if (pData->iFilter == MNG_FILTER_DIFFERING)
-    pData->fDifferrow  = (mng_fptr)mng_differ_idx1;
-#endif
-
-  pData->iPass       = -1;
-  pData->iRow        = 0;
-  pData->iRowinc     = 1;
-  pData->iCol        = 0;
-  pData->iColinc     = 1;
-  pData->iRowsamples = pData->iDatawidth;
-  pData->iSamplemul  = 1;
-  pData->iSampleofs  = 7;
-  pData->iSamplediv  = 3;
-  pData->iRowsize    = (pData->iRowsamples + 7) >> 3;
-  pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
-  pData->iFilterbpp  = 1;
-  pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_IDX1_NI, MNG_LC_END);
-#endif
-
-  return mng_init_rowproc (pData);
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_init_idx1_i    (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_IDX1_I, MNG_LC_START);
-#endif
-
-  if (pData->fDisplayrow)
-    pData->fProcessrow = (mng_fptr)mng_process_idx1;
-
-  if (pData->pStoreobj)                /* store in object too ? */
-  {                                    /* immediate delta ? */
-#ifndef MNG_NO_DELTA_PNG
-    if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
-      pData->fStorerow = (mng_fptr)mng_delta_idx1;
-    else
-#endif
-      pData->fStorerow = (mng_fptr)mng_store_idx1;
-  }
-
-#ifdef FILTER192                       /* leveling & differing ? */
-  if (pData->iFilter == MNG_FILTER_DIFFERING)
-    pData->fDifferrow  = (mng_fptr)mng_differ_idx1;
-#endif
-
-  pData->iPass       = 0;              /* from 0..6; is 1..7 in specifications */
-  pData->iRow        = interlace_row     [0];
-  pData->iRowinc     = interlace_rowskip [0];
-  pData->iCol        = interlace_col     [0];
-  pData->iColinc     = interlace_colskip [0];
-  pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
-  pData->iSamplemul  = 1;
-  pData->iSampleofs  = 7;
-  pData->iSamplediv  = 3;
-  pData->iRowsize    = (pData->iRowsamples + 7) >> 3;
-  pData->iRowmax     = ((pData->iDatawidth + 7) >> 3) + pData->iPixelofs;
-  pData->iFilterbpp  = 1;
-  pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_IDX1_I, MNG_LC_END);
-#endif
-
-  return mng_init_rowproc (pData);
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_init_idx2_ni   (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_IDX2_NI, MNG_LC_START);
-#endif
-
-  if (pData->fDisplayrow)
-    pData->fProcessrow = (mng_fptr)mng_process_idx2;
-
-  if (pData->pStoreobj)                /* store in object too ? */
-  {                                    /* immediate delta ? */
-#ifndef MNG_NO_DELTA_PNG
-    if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
-      pData->fStorerow = (mng_fptr)mng_delta_idx2;
-    else
-#endif
-      pData->fStorerow = (mng_fptr)mng_store_idx2;
-  }
-
-#ifdef FILTER192                       /* leveling & differing ? */
-  if (pData->iFilter == MNG_FILTER_DIFFERING)
-    pData->fDifferrow  = (mng_fptr)mng_differ_idx2;
-#endif
-
-  pData->iPass       = -1;
-  pData->iRow        = 0;
-  pData->iRowinc     = 1;
-  pData->iCol        = 0;
-  pData->iColinc     = 1;
-  pData->iRowsamples = pData->iDatawidth;
-  pData->iSamplemul  = 1;
-  pData->iSampleofs  = 3;
-  pData->iSamplediv  = 2;
-  pData->iRowsize    = (pData->iRowsamples + 3) >> 2;
-  pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
-  pData->iFilterbpp  = 1;
-  pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_IDX2_NI, MNG_LC_END);
-#endif
-
-  return mng_init_rowproc (pData);
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_init_idx2_i    (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_IDX2_I, MNG_LC_START);
-#endif
-
-  if (pData->fDisplayrow)
-    pData->fProcessrow = (mng_fptr)mng_process_idx2;
-
-  if (pData->pStoreobj)                /* store in object too ? */
-  {                                    /* immediate delta ? */
-#ifndef MNG_NO_DELTA_PNG
-    if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
-      pData->fStorerow = (mng_fptr)mng_delta_idx2;
-    else
-#endif
-      pData->fStorerow = (mng_fptr)mng_store_idx2;
-  }
-
-#ifdef FILTER192                       /* leveling & differing ? */
-  if (pData->iFilter == MNG_FILTER_DIFFERING)
-    pData->fDifferrow  = (mng_fptr)mng_differ_idx2;
-#endif
-
-  pData->iPass       = 0;              /* from 0..6; is 1..7 in specifications */
-  pData->iRow        = interlace_row     [0];
-  pData->iRowinc     = interlace_rowskip [0];
-  pData->iCol        = interlace_col     [0];
-  pData->iColinc     = interlace_colskip [0];
-  pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
-  pData->iSamplemul  = 1;
-  pData->iSampleofs  = 3;
-  pData->iSamplediv  = 2;
-  pData->iRowsize    = (pData->iRowsamples + 3) >> 2;
-  pData->iRowmax     = ((pData->iDatawidth + 3) >> 2) + pData->iPixelofs;
-  pData->iFilterbpp  = 1;
-  pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_IDX2_I, MNG_LC_END);
-#endif
-
-  return mng_init_rowproc (pData);
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_init_idx4_ni   (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_IDX4_NI, MNG_LC_START);
-#endif
-
-  if (pData->fDisplayrow)
-    pData->fProcessrow = (mng_fptr)mng_process_idx4;
-
-  if (pData->pStoreobj)                /* store in object too ? */
-  {                                    /* immediate delta ? */
-#ifndef MNG_NO_DELTA_PNG
-    if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
-      pData->fStorerow = (mng_fptr)mng_delta_idx4;
-    else
-#endif
-      pData->fStorerow = (mng_fptr)mng_store_idx4;
-  }
-
-#ifdef FILTER192                       /* leveling & differing ? */
-  if (pData->iFilter == MNG_FILTER_DIFFERING)
-    pData->fDifferrow  = (mng_fptr)mng_differ_idx4;
-#endif
-
-  pData->iPass       = -1;
-  pData->iRow        = 0;
-  pData->iRowinc     = 1;
-  pData->iCol        = 0;
-  pData->iColinc     = 1;
-  pData->iRowsamples = pData->iDatawidth;
-  pData->iSamplemul  = 1;
-  pData->iSampleofs  = 1;
-  pData->iSamplediv  = 1;
-  pData->iRowsize    = (pData->iRowsamples + 1) >> 1;
-  pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
-  pData->iFilterbpp  = 1;
-  pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_IDX4_NI, MNG_LC_END);
-#endif
-
-  return mng_init_rowproc (pData);
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_init_idx4_i    (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_IDX4_I, MNG_LC_START);
-#endif
-
-  if (pData->fDisplayrow)
-    pData->fProcessrow = (mng_fptr)mng_process_idx4;
-
-  if (pData->pStoreobj)                /* store in object too ? */
-  {                                    /* immediate delta ? */
-#ifndef MNG_NO_DELTA_PNG
-    if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
-      pData->fStorerow = (mng_fptr)mng_delta_idx4;
-    else
-#endif
-      pData->fStorerow = (mng_fptr)mng_store_idx4;
-  }
-
-#ifdef FILTER192                       /* leveling & differing ? */
-  if (pData->iFilter == MNG_FILTER_DIFFERING)
-    pData->fDifferrow  = (mng_fptr)mng_differ_idx4;
-#endif
-
-  pData->iPass       = 0;              /* from 0..6; is 1..7 in specifications */
-  pData->iRow        = interlace_row     [0];
-  pData->iRowinc     = interlace_rowskip [0];
-  pData->iCol        = interlace_col     [0];
-  pData->iColinc     = interlace_colskip [0];
-  pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
-  pData->iSamplemul  = 1;
-  pData->iSampleofs  = 1;
-  pData->iSamplediv  = 1;
-  pData->iRowsize    = (pData->iRowsamples + 1) >> 1;
-  pData->iRowmax     = ((pData->iDatawidth + 1) >> 1) + pData->iPixelofs;
-  pData->iFilterbpp  = 1;
-  pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_IDX4_I, MNG_LC_END);
-#endif
-
-  return mng_init_rowproc (pData);
-}
-#endif /* MNG_NO_1_2_4BIT_SUPPORT */
-
-/* ************************************************************************** */
-
-mng_retcode mng_init_idx8_ni   (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_IDX8_NI, MNG_LC_START);
-#endif
-
-  if (pData->fDisplayrow)
-    pData->fProcessrow = (mng_fptr)mng_process_idx8;
-
-  if (pData->pStoreobj)                /* store in object too ? */
-  {                                    /* immediate delta ? */
-#ifndef MNG_NO_DELTA_PNG
-    if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
-      pData->fStorerow = (mng_fptr)mng_delta_idx8;
-    else
-#endif
-      pData->fStorerow = (mng_fptr)mng_store_idx8;
-  }
-
-#ifdef FILTER192                       /* leveling & differing ? */
-  if (pData->iFilter == MNG_FILTER_DIFFERING)
-    pData->fDifferrow  = (mng_fptr)mng_differ_idx8;
-#endif
-
-  pData->iPass       = -1;
-  pData->iRow        = 0;
-  pData->iRowinc     = 1;
-  pData->iCol        = 0;
-  pData->iColinc     = 1;
-  pData->iRowsamples = pData->iDatawidth;
-  pData->iSamplemul  = 1;
-  pData->iSampleofs  = 0;
-  pData->iSamplediv  = 0;
-  pData->iRowsize    = pData->iRowsamples;
-  pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
-  pData->iFilterbpp  = 1;
-  pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_IDX8_NI, MNG_LC_END);
-#endif
-
-  return mng_init_rowproc (pData);
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_init_idx8_i    (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_IDX8_I, MNG_LC_START);
-#endif
-
-  if (pData->fDisplayrow)
-    pData->fProcessrow = (mng_fptr)mng_process_idx8;
-
-  if (pData->pStoreobj)                /* store in object too ? */
-  {                                    /* immediate delta ? */
-#ifndef MNG_NO_DELTA_PNG
-    if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
-      pData->fStorerow = (mng_fptr)mng_delta_idx8;
-    else
-#endif
-      pData->fStorerow = (mng_fptr)mng_store_idx8;
-  }
-
-#ifdef FILTER192                       /* leveling & differing ? */
-  if (pData->iFilter == MNG_FILTER_DIFFERING)
-    pData->fDifferrow  = (mng_fptr)mng_differ_idx8;
-#endif
-
-  pData->iPass       = 0;              /* from 0..6; is 1..7 in specifications */
-  pData->iRow        = interlace_row     [0];
-  pData->iRowinc     = interlace_rowskip [0];
-  pData->iCol        = interlace_col     [0];
-  pData->iColinc     = interlace_colskip [0];
-  pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
-  pData->iSamplemul  = 1;
-  pData->iSampleofs  = 0;
-  pData->iSamplediv  = 0;
-  pData->iRowsize    = pData->iRowsamples;
-  pData->iRowmax     = pData->iDatawidth + pData->iPixelofs;
-  pData->iFilterbpp  = 1;
-  pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_IDX8_I, MNG_LC_END);
-#endif
-
-  return mng_init_rowproc (pData);
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_init_ga8_ni    (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_GA8_NI, MNG_LC_START);
-#endif
-
-  if (pData->fDisplayrow)
-    pData->fProcessrow = (mng_fptr)mng_process_ga8;
-
-  if (pData->pStoreobj)                /* store in object too ? */
-  {                                    /* immediate delta ? */
-#ifndef MNG_NO_DELTA_PNG
-    if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
-      pData->fStorerow = (mng_fptr)mng_delta_ga8;
-    else
-#endif
-      pData->fStorerow = (mng_fptr)mng_store_ga8;
-  }
-
-#ifdef FILTER192                       /* leveling & differing ? */
-  if (pData->iFilter == MNG_FILTER_DIFFERING)
-    pData->fDifferrow  = (mng_fptr)mng_differ_ga8;
-#endif
-
-  pData->iPass       = -1;
-  pData->iRow        = 0;
-  pData->iRowinc     = 1;
-  pData->iCol        = 0;
-  pData->iColinc     = 1;
-  pData->iRowsamples = pData->iDatawidth;
-  pData->iSamplemul  = 2;
-  pData->iSampleofs  = 0;
-  pData->iSamplediv  = 0;
-  pData->iRowsize    = pData->iRowsamples << 1;
-  pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
-  pData->iFilterbpp  = 2;
-  pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_GA8_NI, MNG_LC_END);
-#endif
-
-  return mng_init_rowproc (pData);
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_init_ga8_i     (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_GA8_I, MNG_LC_START);
-#endif
-
-  if (pData->fDisplayrow)
-    pData->fProcessrow = (mng_fptr)mng_process_ga8;
-
-  if (pData->pStoreobj)                /* store in object too ? */
-  {                                    /* immediate delta ? */
-#ifndef MNG_NO_DELTA_PNG
-    if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
-      pData->fStorerow = (mng_fptr)mng_delta_ga8;
-    else
-#endif
-      pData->fStorerow = (mng_fptr)mng_store_ga8;
-  }
-
-#ifdef FILTER192                       /* leveling & differing ? */
-  if (pData->iFilter == MNG_FILTER_DIFFERING)
-    pData->fDifferrow  = (mng_fptr)mng_differ_ga8;
-#endif
-
-  pData->iPass       = 0;              /* from 0..6; is 1..7 in specifications */
-  pData->iRow        = interlace_row     [0];
-  pData->iRowinc     = interlace_rowskip [0];
-  pData->iCol        = interlace_col     [0];
-  pData->iColinc     = interlace_colskip [0];
-  pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
-  pData->iSamplemul  = 2;
-  pData->iSampleofs  = 0;
-  pData->iSamplediv  = 0;
-  pData->iRowsize    = pData->iRowsamples << 1;
-  pData->iRowmax     = (pData->iDatawidth << 1) + pData->iPixelofs;
-  pData->iFilterbpp  = 2;
-  pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_GA8_I, MNG_LC_END);
-#endif
-
-  return mng_init_rowproc (pData);
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_init_ga16_ni   (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_GA16_NI, MNG_LC_START);
-#endif
-
-  if (pData->fDisplayrow)
-    pData->fProcessrow = (mng_fptr)mng_process_ga16;
-
-  if (pData->pStoreobj)                /* store in object too ? */
-  {                                    /* immediate delta ? */
-#ifndef MNG_NO_DELTA_PNG
-    if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
-      pData->fStorerow = (mng_fptr)mng_delta_ga16;
-    else
-#endif
-      pData->fStorerow = (mng_fptr)mng_store_ga16;
-  }
-
-#ifdef FILTER192                       /* leveling & differing ? */
-  if (pData->iFilter == MNG_FILTER_DIFFERING)
-    pData->fDifferrow  = (mng_fptr)mng_differ_ga16;
-#endif
-
-  pData->iPass       = -1;
-  pData->iRow        = 0;
-  pData->iRowinc     = 1;
-  pData->iCol        = 0;
-  pData->iColinc     = 1;
-  pData->iRowsamples = pData->iDatawidth;
-  pData->iSamplemul  = 4;
-  pData->iSampleofs  = 0;
-  pData->iSamplediv  = 0;
-  pData->iRowsize    = pData->iRowsamples << 2;
-  pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
-  pData->iFilterbpp  = 4;
-  pData->bIsRGBA16   = MNG_TRUE;       /* intermediate row is 16-bit deep */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_GA16_NI, MNG_LC_END);
-#endif
-
-  return mng_init_rowproc (pData);
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_init_ga16_i    (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_GA16_I, MNG_LC_START);
-#endif
-
-  if (pData->fDisplayrow)
-    pData->fProcessrow = (mng_fptr)mng_process_ga16;
-
-  if (pData->pStoreobj)                /* store in object too ? */
-  {                                    /* immediate delta ? */
-#ifndef MNG_NO_DELTA_PNG
-    if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
-      pData->fStorerow = (mng_fptr)mng_delta_ga16;
-    else
-#endif
-      pData->fStorerow = (mng_fptr)mng_store_ga16;
-  }
-
-#ifdef FILTER192                       /* leveling & differing ? */
-  if (pData->iFilter == MNG_FILTER_DIFFERING)
-    pData->fDifferrow  = (mng_fptr)mng_differ_ga16;
-#endif
-
-  pData->iPass       = 0;              /* from 0..6; is 1..7 in specifications */
-  pData->iRow        = interlace_row     [0];
-  pData->iRowinc     = interlace_rowskip [0];
-  pData->iCol        = interlace_col     [0];
-  pData->iColinc     = interlace_colskip [0];
-  pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
-  pData->iSamplemul  = 4;
-  pData->iSampleofs  = 0;
-  pData->iSamplediv  = 0;
-  pData->iRowsize    = pData->iRowsamples << 2;
-  pData->iRowmax     = (pData->iDatawidth << 2) + pData->iPixelofs;
-  pData->iFilterbpp  = 4;
-  pData->bIsRGBA16   = MNG_TRUE;       /* intermediate row is 16-bit deep */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_GA16_I, MNG_LC_END);
-#endif
-
-  return mng_init_rowproc (pData);
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_init_rgba8_ni  (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_RGBA8_NI, MNG_LC_START);
-#endif
-
-  if (pData->fDisplayrow)
-    pData->fProcessrow = (mng_fptr)mng_process_rgba8;
-
-  if (pData->pStoreobj)                /* store in object too ? */
-  {                                    /* immediate delta ? */
-#ifndef MNG_NO_DELTA_PNG
-    if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
-      pData->fStorerow = (mng_fptr)mng_delta_rgba8;
-    else
-#endif
-      pData->fStorerow = (mng_fptr)mng_store_rgba8;
-  }
-
-#ifdef FILTER192                       /* leveling & differing ? */
-  if (pData->iFilter == MNG_FILTER_DIFFERING)
-    pData->fDifferrow  = (mng_fptr)mng_differ_rgba8;
-#endif
-
-  pData->iPass       = -1;
-  pData->iRow        = 0;
-  pData->iRowinc     = 1;
-  pData->iCol        = 0;
-  pData->iColinc     = 1;
-  pData->iRowsamples = pData->iDatawidth;
-  pData->iSamplemul  = 4;
-  pData->iSampleofs  = 0;
-  pData->iSamplediv  = 0;
-  pData->iRowsize    = pData->iRowsamples << 2;
-  pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
-  pData->iFilterbpp  = 4;
-  pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_RGBA8_NI, MNG_LC_END);
-#endif
-
-  return mng_init_rowproc (pData);
-}
-/* ************************************************************************** */
-
-mng_retcode mng_init_rgba8_i   (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_RGBA8_I, MNG_LC_START);
-#endif
-
-  if (pData->fDisplayrow)
-    pData->fProcessrow = (mng_fptr)mng_process_rgba8;
-
-  if (pData->pStoreobj)                /* store in object too ? */
-  {                                    /* immediate delta ? */
-#ifndef MNG_NO_DELTA_PNG
-    if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
-      pData->fStorerow = (mng_fptr)mng_delta_rgba8;
-    else
-#endif
-      pData->fStorerow = (mng_fptr)mng_store_rgba8;
-  }
-
-#ifdef FILTER192                       /* leveling & differing ? */
-  if (pData->iFilter == MNG_FILTER_DIFFERING)
-    pData->fDifferrow  = (mng_fptr)mng_differ_rgba8;
-#endif
-
-  pData->iPass       = 0;              /* from 0..6; is 1..7 in specifications */
-  pData->iRow        = interlace_row     [0];
-  pData->iRowinc     = interlace_rowskip [0];
-  pData->iCol        = interlace_col     [0];
-  pData->iColinc     = interlace_colskip [0];
-  pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
-  pData->iSamplemul  = 4;
-  pData->iSampleofs  = 0;
-  pData->iSamplediv  = 0;
-  pData->iRowsize    = pData->iRowsamples << 2;
-  pData->iRowmax     = (pData->iDatawidth << 2) + pData->iPixelofs;
-  pData->iFilterbpp  = 4;
-  pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_RGBA8_I, MNG_LC_END);
-#endif
-
-  return mng_init_rowproc (pData);
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_init_rgba16_ni (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_RGBA16_NI, MNG_LC_START);
-#endif
-
-  if (pData->fDisplayrow)
-    pData->fProcessrow = (mng_fptr)mng_process_rgba16;
-
-  if (pData->pStoreobj)                /* store in object too ? */
-  {                                    /* immediate delta ? */
-#ifndef MNG_NO_DELTA_PNG
-    if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
-      pData->fStorerow = (mng_fptr)mng_delta_rgba16;
-    else
-#endif
-      pData->fStorerow = (mng_fptr)mng_store_rgba16;
-  }
-
-#ifdef FILTER192                       /* leveling & differing ? */
-  if (pData->iFilter == MNG_FILTER_DIFFERING)
-    pData->fDifferrow  = (mng_fptr)mng_differ_rgba16;
-#endif
-
-  pData->iPass       = -1;
-  pData->iRow        = 0;
-  pData->iRowinc     = 1;
-  pData->iCol        = 0;
-  pData->iColinc     = 1;
-  pData->iRowsamples = pData->iDatawidth;
-  pData->iSamplemul  = 8;
-  pData->iSampleofs  = 0;
-  pData->iSamplediv  = 0;
-  pData->iRowsize    = pData->iRowsamples << 3;
-  pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
-  pData->iFilterbpp  = 8;
-  pData->bIsRGBA16   = MNG_TRUE;       /* intermediate row is 16-bit deep */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_RGBA16_NI, MNG_LC_END);
-#endif
-
-  return mng_init_rowproc (pData);
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_init_rgba16_i  (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_RGBA16_I, MNG_LC_START);
-#endif
-
-  if (pData->fDisplayrow)
-    pData->fProcessrow = (mng_fptr)mng_process_rgba16;
-
-  if (pData->pStoreobj)                /* store in object too ? */
-  {                                    /* immediate delta ? */
-#ifndef MNG_NO_DELTA_PNG
-    if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
-      pData->fStorerow = (mng_fptr)mng_delta_rgba16;
-    else
-#endif
-      pData->fStorerow = (mng_fptr)mng_store_rgba16;
-  }
-
-#ifdef FILTER192                       /* leveling & differing ? */
-  if (pData->iFilter == MNG_FILTER_DIFFERING)
-    pData->fDifferrow  = (mng_fptr)mng_differ_rgba16;
-#endif
-
-  pData->iPass       = 0;              /* from 0..6; (1..7 in specification) */
-  pData->iRow        = interlace_row     [0];
-  pData->iRowinc     = interlace_rowskip [0];
-  pData->iCol        = interlace_col     [0];
-  pData->iColinc     = interlace_colskip [0];
-  pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
-  pData->iSamplemul  = 8;
-  pData->iSampleofs  = 0;
-  pData->iSamplediv  = 0;
-  pData->iRowsize    = pData->iRowsamples << 3;
-  pData->iRowmax     = (pData->iDatawidth << 3) + pData->iPixelofs;
-  pData->iFilterbpp  = 8;
-  pData->bIsRGBA16   = MNG_TRUE;       /* intermediate row is 16-bit deep */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_RGBA16_I, MNG_LC_END);
-#endif
-
-  return mng_init_rowproc (pData);
-}
-#endif
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Row processing initialization routines (JPEG) - set up the variables   * */
-/* * needed to process uncompressed row-data                                * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-mng_retcode mng_init_jpeg_a1_ni     (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_JPEG_A1_NI, MNG_LC_START);
-#endif
-
-  if (pData->pStoreobj)                /* store in object too ? */
-  {
-    if (pData->iJHDRimgbitdepth == 8)
-    {
-      switch (pData->iJHDRcolortype)
-      {
-        case 12 : { pData->fStorerow = (mng_fptr)mng_store_jpeg_g8_a1;   break; }
-        case 14 : { pData->fStorerow = (mng_fptr)mng_store_jpeg_rgb8_a1; break; }
-      }
-    }
-
-    /* TODO: bitdepth 12 & 20 */
-
-  }
-
-#ifdef FILTER192                       /* leveling & differing ? */
-  if (pData->iFilter == MNG_FILTER_DIFFERING)
-    pData->fDifferrow  = (mng_fptr)mng_differ_g1;
-#endif
-
-  pData->iPass       = -1;
-  pData->iRow        = 0;
-  pData->iRowinc     = 1;
-  pData->iCol        = 0;
-  pData->iColinc     = 1;
-  pData->iRowsamples = pData->iDatawidth;
-  pData->iSamplemul  = 1;
-  pData->iSampleofs  = 7;
-  pData->iSamplediv  = 3;
-  pData->iRowsize    = (pData->iRowsamples + 7) >> 3;
-  pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
-  pData->iFilterbpp  = 1;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_JPEG_A1_NI, MNG_LC_END);
-#endif
-
-  return mng_init_rowproc (pData);
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_init_jpeg_a2_ni     (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_JPEG_A2_NI, MNG_LC_START);
-#endif
-
-  if (pData->pStoreobj)                /* store in object too ? */
-  {
-    if (pData->iJHDRimgbitdepth == 8)
-    {
-      switch (pData->iJHDRcolortype)
-      {
-        case 12 : { pData->fStorerow = (mng_fptr)mng_store_jpeg_g8_a2;   break; }
-        case 14 : { pData->fStorerow = (mng_fptr)mng_store_jpeg_rgb8_a2; break; }
-      }
-    }
-
-    /* TODO: bitdepth 12 & 20 */
-
-  }
-
-#ifdef FILTER192                       /* leveling & differing ? */
-  if (pData->iFilter == MNG_FILTER_DIFFERING)
-    pData->fDifferrow  = (mng_fptr)mng_differ_g2;
-#endif
-
-  pData->iPass       = -1;
-  pData->iRow        = 0;
-  pData->iRowinc     = 1;
-  pData->iCol        = 0;
-  pData->iColinc     = 1;
-  pData->iRowsamples = pData->iDatawidth;
-  pData->iSamplemul  = 1;
-  pData->iSampleofs  = 3;
-  pData->iSamplediv  = 2;
-  pData->iRowsize    = (pData->iRowsamples + 3) >> 2;
-  pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
-  pData->iFilterbpp  = 1;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_JPEG_A2_NI, MNG_LC_END);
-#endif
-
-  return mng_init_rowproc (pData);
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_init_jpeg_a4_ni     (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_JPEG_A4_NI, MNG_LC_START);
-#endif
-
-  if (pData->pStoreobj)                /* store in object too ? */
-  {
-    if (pData->iJHDRimgbitdepth == 8)
-    {
-      switch (pData->iJHDRcolortype)
-      {
-        case 12 : { pData->fStorerow = (mng_fptr)mng_store_jpeg_g8_a4;   break; }
-        case 14 : { pData->fStorerow = (mng_fptr)mng_store_jpeg_rgb8_a4; break; }
-      }
-    }
-
-    /* TODO: bitdepth 12 & 20 */
-
-  }
-
-#ifdef FILTER192                       /* leveling & differing ? */
-  if (pData->iFilter == MNG_FILTER_DIFFERING)
-    pData->fDifferrow  = (mng_fptr)mng_differ_g4;
-#endif
-
-  pData->iPass       = -1;
-  pData->iRow        = 0;
-  pData->iRowinc     = 1;
-  pData->iCol        = 0;
-  pData->iColinc     = 1;
-  pData->iRowsamples = pData->iDatawidth;
-  pData->iSamplemul  = 1;
-  pData->iSampleofs  = 1;
-  pData->iSamplediv  = 1;
-  pData->iRowsize    = (pData->iRowsamples + 1) >> 1;
-  pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
-  pData->iFilterbpp  = 1;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_JPEG_A4_NI, MNG_LC_END);
-#endif
-
-  return mng_init_rowproc (pData);
-}
-#endif /* MNG_NO_1_2_4BIT_SUPPORT */
-
-/* ************************************************************************** */
-
-mng_retcode mng_init_jpeg_a8_ni     (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_JPEG_A8_NI, MNG_LC_START);
-#endif
-
-  if (pData->pStoreobj)                /* store in object too ? */
-  {
-    if (pData->iJHDRimgbitdepth == 8)
-    {
-      switch (pData->iJHDRcolortype)
-      {
-        case 12 : { pData->fStorerow = (mng_fptr)mng_store_jpeg_g8_a8;   break; }
-        case 14 : { pData->fStorerow = (mng_fptr)mng_store_jpeg_rgb8_a8; break; }
-      }
-    }
-
-    /* TODO: bitdepth 12 & 20 */
-
-  }
-
-#ifdef FILTER192                       /* leveling & differing ? */
-  if (pData->iFilter == MNG_FILTER_DIFFERING)
-    pData->fDifferrow  = (mng_fptr)mng_differ_g8;
-#endif
-
-  pData->iPass       = -1;
-  pData->iRow        = 0;
-  pData->iRowinc     = 1;
-  pData->iCol        = 0;
-  pData->iColinc     = 1;
-  pData->iRowsamples = pData->iDatawidth;
-  pData->iSamplemul  = 1;
-  pData->iSampleofs  = 0;
-  pData->iSamplediv  = 0;
-  pData->iRowsize    = pData->iRowsamples;
-  pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
-  pData->iFilterbpp  = 1;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_JPEG_A8_NI, MNG_LC_END);
-#endif
-
-  return mng_init_rowproc (pData);
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_init_jpeg_a16_ni    (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_JPEG_A16_NI, MNG_LC_START);
-#endif
-
-  if (pData->pStoreobj)                /* store in object too ? */
-  {
-    if (pData->iJHDRimgbitdepth == 8)
-    {
-      switch (pData->iJHDRcolortype)
-      {
-        case 12 : { pData->fStorerow = (mng_fptr)mng_store_jpeg_g8_a16;   break; }
-        case 14 : { pData->fStorerow = (mng_fptr)mng_store_jpeg_rgb8_a16; break; }
-      }
-    }
-
-    /* TODO: bitdepth 12 & 20 */
-
-  }
-
-#ifdef FILTER192                       /* leveling & differing ? */
-  if (pData->iFilter == MNG_FILTER_DIFFERING)
-    pData->fDifferrow  = (mng_fptr)mng_differ_g16;
-#endif
-
-  pData->iPass       = -1;
-  pData->iRow        = 0;
-  pData->iRowinc     = 1;
-  pData->iCol        = 0;
-  pData->iColinc     = 1;
-  pData->iRowsamples = pData->iDatawidth;
-  pData->iSamplemul  = 2;
-  pData->iSampleofs  = 0;
-  pData->iSamplediv  = 0;
-  pData->iRowsize    = pData->iRowsamples << 1;
-  pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
-  pData->iFilterbpp  = 2;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_JPEG_A16_NI, MNG_LC_END);
-#endif
-
-  return mng_init_rowproc (pData);
-}
-#endif
-
-/* ************************************************************************** */
-
-#endif /* MNG_INCLUDE_JNG */
-#endif /* MNG_OPTIMIZE_FOOTPRINT_INIT */
-
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Generic row processing initialization & cleanup routines               * */
-/* * - initialize the buffers used by the row processing routines           * */
-/* * - cleanup the buffers used by the row processing routines              * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-mng_retcode mng_init_rowproc (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_ROWPROC, MNG_LC_START);
-#endif
-
-#ifdef MNG_OPTIMIZE_FOOTPRINT_INIT
-  if (pData->ePng_imgtype != png_none)
-  {
-  if (pData->fDisplayrow)
-    switch (pData->ePng_imgtype)
-    {
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-    case png_g1:
-      pData->fProcessrow = (mng_fptr)mng_process_g1;
-      break;
-    case png_g2:
-      pData->fProcessrow = (mng_fptr)mng_process_g2;
-      break;
-    case png_g4:
-      pData->fProcessrow = (mng_fptr)mng_process_g4;
-      break;
-#endif /* MNG_NO_1_2_4BIT_SUPPORT */
-    case png_g8:
-      pData->fProcessrow = (mng_fptr)mng_process_g8;
-      break;
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-    case png_idx1:
-      pData->fProcessrow = (mng_fptr)mng_process_idx1;
-      break;
-    case png_idx2:
-      pData->fProcessrow = (mng_fptr)mng_process_idx2;
-      break;
-    case png_idx4:
-      pData->fProcessrow = (mng_fptr)mng_process_idx4;
-      break;
-#endif /* MNG_NO_1_2_4BIT_SUPPORT */
-    case png_idx8:
-      pData->fProcessrow = (mng_fptr)mng_process_idx8;
-      break;
-    case png_ga8:
-      pData->fProcessrow = (mng_fptr)mng_process_ga8;
-      break;
-    case png_rgb8:
-      pData->fProcessrow = (mng_fptr)mng_process_rgb8;
-      break;
-    case png_rgba8:
-      pData->fProcessrow = (mng_fptr)mng_process_rgba8;
-      break;
-#ifndef MNG_NO_16BIT_SUPPORT
-    case png_g16:
-      pData->fProcessrow = (mng_fptr)mng_process_g16;
-      break;
-    case png_ga16:
-      pData->fProcessrow = (mng_fptr)mng_process_ga16;
-      break;
-    case png_rgb16:
-      pData->fProcessrow = (mng_fptr)mng_process_rgb16;
-      break;
-    case png_rgba16:
-      pData->fProcessrow = (mng_fptr)mng_process_rgba16;
-      break;
-#endif
-    default:
-      break;
-    }
-
-  if (pData->pStoreobj)                /* store in object too ? */
-  {
-#ifndef MNG_NO_DELTA_PNG
-  if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
-    switch (pData->ePng_imgtype)
-    {
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-    case png_g1:
-      pData->fStorerow = (mng_fptr)mng_delta_g1;
-      break;
-    case png_g2:
-      pData->fStorerow = (mng_fptr)mng_delta_g2;
-      break;
-    case png_g4:
-      pData->fStorerow = (mng_fptr)mng_delta_g4;
-      break;
-#endif /* MNG_NO_1_2_4BIT_SUPPORT */
-    case png_g8:
-      pData->fStorerow = (mng_fptr)mng_delta_g8;
-      break;
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-    case png_idx1:
-      pData->fStorerow = (mng_fptr)mng_delta_idx1;
-      break;
-    case png_idx2:
-      pData->fStorerow = (mng_fptr)mng_delta_idx2;
-      break;
-    case png_idx4:
-      pData->fStorerow = (mng_fptr)mng_delta_idx4;
-      break;
-#endif /* MNG_NO_1_2_4BIT_SUPPORT */
-    case png_idx8:
-      pData->fStorerow = (mng_fptr)mng_delta_idx8;
-      break;
-    case png_ga8:
-      pData->fStorerow = (mng_fptr)mng_delta_ga8;
-      break;
-    case png_rgb8:
-      pData->fStorerow = (mng_fptr)mng_delta_rgb8;
-      break;
-    case png_rgba8:
-      pData->fStorerow = (mng_fptr)mng_delta_rgba8;
-      break;
-#ifndef MNG_NO_16BIT_SUPPORT
-    case png_g16:
-      pData->fStorerow = (mng_fptr)mng_delta_g16;
-      break;
-    case png_ga16:
-      pData->fStorerow = (mng_fptr)mng_delta_ga16;
-      break;
-    case png_rgb16:
-      pData->fStorerow = (mng_fptr)mng_delta_rgb16;
-      break;
-    case png_rgba16:
-      pData->fStorerow = (mng_fptr)mng_delta_rgba16;
-      break;
-#endif
-    default:
-      break;
-    }
-  else
-#endif  /* MNG_NO_DELTA_PNG */
-    switch (pData->ePng_imgtype)
-    {
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-    case png_g1:
-      pData->fStorerow = (mng_fptr)mng_store_g1;
-      break;
-    case png_g2:
-      pData->fStorerow = (mng_fptr)mng_store_g2;
-      break;
-    case png_g4:
-      pData->fStorerow = (mng_fptr)mng_store_g4;
-      break;
-#endif /* MNG_NO_1_2_4BIT_SUPPORT */
-    case png_g8:
-      pData->fStorerow = (mng_fptr)mng_store_g8;
-      break;
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-    case png_idx1:
-      pData->fStorerow = (mng_fptr)mng_store_idx1;
-      break;
-    case png_idx2:
-      pData->fStorerow = (mng_fptr)mng_store_idx2;
-      break;
-    case png_idx4:
-      pData->fStorerow = (mng_fptr)mng_store_idx4;
-      break;
-#endif /* MNG_NO_1_2_4BIT_SUPPORT */
-    case png_idx8:
-      pData->fStorerow = (mng_fptr)mng_store_idx8;
-      break;
-    case png_ga8:
-      pData->fStorerow = (mng_fptr)mng_store_ga8;
-      break;
-    case png_rgb8:
-      pData->fStorerow = (mng_fptr)mng_store_rgb8;
-      break;
-    case png_rgba8:
-      pData->fStorerow = (mng_fptr)mng_store_rgba8;
-      break;
-#ifndef MNG_NO_16BIT_SUPPORT
-    case png_g16:
-      pData->fStorerow = (mng_fptr)mng_store_g16;
-      break;
-    case png_ga16:
-      pData->fStorerow = (mng_fptr)mng_store_ga16;
-      break;
-    case png_rgb16:
-      pData->fStorerow = (mng_fptr)mng_store_rgb16;
-      break;
-    case png_rgba16:
-      pData->fStorerow = (mng_fptr)mng_store_rgba16;
-      break;
-#endif
-
-#ifdef MNG_INCLUDE_JNG
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-    case png_jpeg_a1:
-/*  if (pData->iJHDRimgbitdepth == 8) */
-      {
-        switch (pData->iJHDRcolortype)
-        {
-        case 12 :
-          { pData->fStorerow = (mng_fptr)mng_store_jpeg_g8_a1;   break; }
-        case 14 :
-          { pData->fStorerow = (mng_fptr)mng_store_jpeg_rgb8_a1; break; }
-        }
-      }
-      /* TODO: bitdepth 12 & 20 */
-      break;
-    case png_jpeg_a2:
-/*  if (pData->iJHDRimgbitdepth == 8) */
-      {
-        switch (pData->iJHDRcolortype)
-        {
-          case 12 :
-            { pData->fStorerow = (mng_fptr)mng_store_jpeg_g8_a2;   break; }
-          case 14 :
-            { pData->fStorerow = (mng_fptr)mng_store_jpeg_rgb8_a2; break; }
-        }
-      }
-      break;
-      /* TODO: bitdepth 12 & 20 */
-    case png_jpeg_a4:
-/*  if (pData->iJHDRimgbitdepth == 8) */
-      {
-        switch (pData->iJHDRcolortype)
-        {
-          case 12 :
-           { pData->fStorerow = (mng_fptr)mng_store_jpeg_g8_a4;   break; }
-          case 14 :
-           { pData->fStorerow = (mng_fptr)mng_store_jpeg_rgb8_a4; break; }
-        }
-      }
-      break;
-#endif /* MNG_NO_1_2_4BIT_SUPPORT */
-      /* TODO: bitdepth 12 & 20 */
-    case png_jpeg_a8:
-/*  if (pData->iJHDRimgbitdepth == 8) */
-      {
-        switch (pData->iJHDRcolortype)
-        {
-          case 12 :
-            { pData->fStorerow = (mng_fptr)mng_store_jpeg_g8_a8;   break; }
-          case 14 :
-            { pData->fStorerow = (mng_fptr)mng_store_jpeg_rgb8_a8; break; }
-        }
-      }
-      break;
-      /* TODO: bitdepth 12 & 20 */
-#ifndef MNG_NO_16BIT_SUPPORT
-    case png_jpeg_a16:
-/*  if (pData->iJHDRimgbitdepth == 8) */
-      {
-        switch (pData->iJHDRcolortype)
-        {
-          case 12 :
-            { pData->fStorerow = (mng_fptr)mng_store_jpeg_g8_a16;   break; }
-          case 14 :
-            { pData->fStorerow = (mng_fptr)mng_store_jpeg_rgb8_a16; break; }
-        }
-      }
-      break;
-      /* TODO: bitdepth 12 & 20 */
-#endif
-#endif /* MNG_INCLUDE_JNG */
-    default:
-      break;
-    }
-  }
-
-#ifdef FILTER192                       /* leveling & differing ? */
-  if (pData->iFilter == MNG_FILTER_DIFFERING)
-  switch (pData->ePng_imgtype)
-  {
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-    case png_g1:
-#ifdef MNG_INCLUDE_JNG
-    case png_jpeg_a1:
-#endif
-      pData->fDifferrow  = (mng_fptr)mng_differ_g1;
-      break;
-    case png_g2:
-#ifdef MNG_INCLUDE_JNG
-    case png_jpeg_a2:
-#endif
-      pData->fDifferrow  = (mng_fptr)mng_differ_g2;
-      break;
-    case png_g4:
-#ifdef MNG_INCLUDE_JNG
-    case png_jpeg_a4:
-#endif
-      pData->fDifferrow  = (mng_fptr)mng_differ_g4;
-      break;
-#endif /* MNG_NO_1_2_4BIT_SUPPORT */
-    case png_g8:
-#ifdef MNG_INCLUDE_JNG
-    case png_jpeg_a8:
-#endif
-      pData->fDifferrow  = (mng_fptr)mng_differ_g8;
-      break;
-    case png_rgb8:
-      pData->fDifferrow  = (mng_fptr)mng_differ_rgb8;
-      break;
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-    case png_idx1:
-      pData->fDifferrow  = (mng_fptr)mng_differ_idx1;
-      break;
-    case png_idx2:
-      pData->fDifferrow  = (mng_fptr)mng_differ_idx2;
-      break;
-    case png_idx4:
-      pData->fDifferrow  = (mng_fptr)mng_differ_idx4;
-      break;
-#endif /* MNG_NO_1_2_4BIT_SUPPORT */
-    case png_idx8:
-      pData->fDifferrow  = (mng_fptr)mng_differ_idx8;
-      break;
-    case png_ga8:
-      pData->fDifferrow  = (mng_fptr)mng_differ_ga8;
-      break;
-    case png_rgb8:
-      pData->fDifferrow  = (mng_fptr)mng_differ_rgb8;
-      break;
-    case png_rgba8:
-      pData->fDifferrow  = (mng_fptr)mng_differ_rgba8;
-      break;
-#ifndef MNG_NO_16BIT_SUPPORT
-    case png_g16:
-#ifdef MNG_INCLUDE_JNG
-    case png_jpeg_a16:
-#endif
-      pData->fDifferrow  = (mng_fptr)mng_differ_g16;
-      break;
-    case png_ga16:
-      pData->fDifferrow  = (mng_fptr)mng_differ_ga16;
-      break;
-    case png_rgb16:
-      pData->fDifferrow  = (mng_fptr)mng_differ_rgb16;
-      break;
-    case png_rgba16:
-      pData->fDifferrow  = (mng_fptr)mng_differ_rgba16;
-      break;
-#endif
-    default:
-      break;
-  }
-#endif
-
-  switch (pData->ePng_imgtype)
-  {
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-    case png_g1:
-    case png_idx1:
-#ifdef MNG_INCLUDE_JNG
-    case png_jpeg_a1:
-#endif
-        pData->iSamplemul  = 1;
-        pData->iSampleofs  = 7;
-        pData->iSamplediv  = 3;
-        pData->iFilterbpp  = 1;
-        break;
-    case png_g2:
-    case png_idx2:
-#ifdef MNG_INCLUDE_JNG
-    case png_jpeg_a2:
-#endif
-        pData->iSamplemul  = 1;
-        pData->iSampleofs  = 3;
-        pData->iSamplediv  = 2;
-        pData->iFilterbpp  = 1;
-        break;
-    case png_g4:
-    case png_idx4:
-#ifdef MNG_INCLUDE_JNG
-    case png_jpeg_a4:
-#endif
-        pData->iSamplemul  = 1;
-        pData->iSampleofs  = 1;
-        pData->iSamplediv  = 1;
-        pData->iFilterbpp  = 1;
-        break;
-#endif /* MNG_NO_1_2_4BIT_SUPPORT */
-    case png_g8:
-    case png_idx8:
-#ifdef MNG_INCLUDE_JNG
-    case png_jpeg_a8:
-#endif
-        pData->iSamplemul  = 1;
-        pData->iSampleofs  = 0;
-        pData->iSamplediv  = 0;
-        pData->iFilterbpp  = 1;
-        break;
-    case png_ga8:
-#ifndef MNG_NO_16BIT_SUPPORT
-    case png_g16:
-#ifdef MNG_INCLUDE_JNG
-    case png_jpeg_a16:
-#endif
-#endif
-        pData->iSamplemul  = 2;
-        pData->iSampleofs  = 0;
-        pData->iSamplediv  = 0;
-        pData->iFilterbpp  = 2;
-        break;
-    case png_rgb8:
-        pData->iSamplemul  = 3;
-        pData->iSampleofs  = 0;
-        pData->iSamplediv  = 0;
-        pData->iFilterbpp  = 3;
-        break;
-#ifndef MNG_NO_16BIT_SUPPORT
-    case png_ga16:
-#endif
-    case png_rgba8:
-        pData->iSamplemul  = 4;
-        pData->iSampleofs  = 0;
-        pData->iSamplediv  = 0;
-        pData->iFilterbpp  = 4;
-        break;
-#ifndef MNG_NO_16BIT_SUPPORT
-    case png_rgb16:
-        pData->iSamplemul  = 6;
-        pData->iSampleofs  = 0;
-        pData->iSamplediv  = 0;
-        pData->iFilterbpp  = 6;
-        break;
-    case png_rgba16:
-        pData->iSamplemul  = 8;
-        pData->iSampleofs  = 0;
-        pData->iSamplediv  = 0;
-        pData->iFilterbpp  = 8;
-        break;
-#endif
-    default:
-        break;
-  }
-
-  if (pData->iInterlace)               /* noninterlaced */
-  {
-    pData->iPass       = 0;      /* from 0..6; (1..7 in specification) */
-    pData->iRow        = interlace_row     [0];
-    pData->iRowinc     = interlace_rowskip [0];
-    pData->iCol        = interlace_col     [0];
-    pData->iColinc     = interlace_colskip [0];
-    pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >>
-       interlace_divider [0];
-    pData->iRowmax     = ((pData->iDatawidth * pData->iSamplemul +
-       pData->iSampleofs) >> pData->iSamplediv) + pData->iPixelofs;
-  }
-  else                                 /* interlaced */
-  {
-    pData->iPass       = -1;
-    pData->iRow        = 0;
-    pData->iRowinc     = 1;
-    pData->iCol        = 0;
-    pData->iColinc     = 1;
-    pData->iRowsamples = pData->iDatawidth;
-  }
-  if (pData->iSamplediv > 0)
-     pData->iRowsize    = (pData->iRowsamples + pData->iSampleofs) >>
-         pData->iSamplediv;
-  else
-     pData->iRowsize    = (pData->iRowsamples * pData->iSamplemul);
-
-  if (!pData->iInterlace)               /* noninterlaced */
-     pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
-
-#ifdef MNG_NO_16BIT_SUPPORT
-  pData->bIsRGBA16 = MNG_FALSE;
-#else
-  switch (pData->ePng_imgtype)
-  {
-    case png_g16:
-    case png_ga16:
-    case png_rgb16:
-    case png_rgba16:
-       pData->bIsRGBA16 = MNG_TRUE;
-       break;
-    default:
-       pData->bIsRGBA16 = MNG_FALSE;
-       break;
-  }
-#endif
-
-  }
-#endif /* MNG_OPTIMIZE_FOOTPRINT_INIT */
-
-  if (pData->pStoreobj)                /* storage object selected ? */
-  {
-    pData->pStorebuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
-                                       /* and so it becomes viewable ! */
-    ((mng_imagep)pData->pStoreobj)->bViewable     = MNG_TRUE;
-    ((mng_imagedatap)pData->pStorebuf)->bViewable = MNG_TRUE;
-  }
-
-  /* allocate the buffers; the individual init routines have already
-     calculated the required maximum size; except in the case of a JNG
-     without alpha!!! */
-  if (pData->iRowmax)
-  {
-#if defined(MNG_NO_16BIT_SUPPORT) || defined (MNG_NO_1_2_4BIT_SUPPORT)
-    mng_uint8 iRowadd = 0;
-#ifdef MNG_NO_1_2_4BIT_SUPPORT
-    if (pData->iPNGdepth < 8)
-       iRowadd=(pData->iPNGdepth*pData->iRowmax+7)/8;
-#endif
-#ifdef MNG_NO_16BIT_SUPPORT
-    if (pData->iPNGdepth > 8)
-       iRowadd=pData->iRowmax;
-#endif
-    MNG_ALLOC (pData, pData->pWorkrow, pData->iRowmax+iRowadd);
-    MNG_ALLOC (pData, pData->pPrevrow, pData->iRowmax+iRowadd);
-#else
-    MNG_ALLOC (pData, pData->pWorkrow, pData->iRowmax);
-    MNG_ALLOC (pData, pData->pPrevrow, pData->iRowmax);
-#endif
-  }
-
-  /* allocate an RGBA16 row for intermediate processing */
-  MNG_ALLOC (pData, pData->pRGBArow, (pData->iDatawidth << 3));
-
-#ifndef MNG_NO_CMS
-  if (pData->fDisplayrow)              /* display "on-the-fly" ? */
-  {
-#if defined(MNG_FULL_CMS)              /* determine color-management initialization */
-    mng_retcode iRetcode = mng_init_full_cms   (pData, MNG_TRUE, MNG_TRUE, MNG_FALSE);
-#elif defined(MNG_GAMMA_ONLY)
-    mng_retcode iRetcode = mng_init_gamma_only (pData, MNG_TRUE, MNG_TRUE, MNG_FALSE);
-#elif defined(MNG_APP_CMS)
-    mng_retcode iRetcode = mng_init_app_cms    (pData, MNG_TRUE, MNG_TRUE, MNG_FALSE);
-#endif
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-  }
-#endif /* !MNG_NO_CMS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_INIT_ROWPROC, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_next_row (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_NEXT_ROW, MNG_LC_START);
-#endif
-
-  pData->iRow += pData->iRowinc;       /* increase the row counter */
-
-  if (pData->iPass >= 0)               /* interlaced ? */
-  {
-    while ((pData->iPass < 7) &&       /* went 'outside' the image ? */
-           ((pData->iRow >= (mng_int32)pData->iDataheight) ||
-            (pData->iCol >= (mng_int32)pData->iDatawidth )    ))
-    {
-      pData->iPass++;                  /* next pass ! */
-
-      if (pData->iPass < 7)            /* there's only 7 passes ! */
-      {
-        pData->iRow        = interlace_row     [pData->iPass];
-        pData->iRowinc     = interlace_rowskip [pData->iPass];
-        pData->iCol        = interlace_col     [pData->iPass];
-        pData->iColinc     = interlace_colskip [pData->iPass];
-        pData->iRowsamples = (pData->iDatawidth - pData->iCol + interlace_roundoff [pData->iPass])
-                                 >> interlace_divider [pData->iPass];
-
-        if (pData->iSamplemul > 1)     /* recalculate row dimension */
-          pData->iRowsize  = pData->iRowsamples * pData->iSamplemul;
-        else
-        if (pData->iSamplediv > 0)
-          pData->iRowsize  = (pData->iRowsamples + pData->iSampleofs) >> pData->iSamplediv;
-        else
-          pData->iRowsize  = pData->iRowsamples;
-
-      }
-
-      if ((pData->iPass < 7) &&        /* reset previous row to zeroes ? */
-          (pData->iRow  < (mng_int32)pData->iDataheight) &&
-          (pData->iCol  < (mng_int32)pData->iDatawidth )    )
-      {                                /* making sure the filters will work properly! */
-        mng_int32  iX;
-        mng_uint8p pTemp = pData->pPrevrow;
-
-#ifdef MNG_NO_16BIT_SUPPORT
-#ifdef MNG_DECREMENT_LOOPS
-        for (iX = pData->iPNGmult*pData->iRowsize; iX > 0; iX--)
-#else
-        for (iX = 0; iX < pData->iPNGmult*pData->iRowsize; iX++)
-#endif
-#else
-#ifdef MNG_DECREMENT_LOOPS
-        for (iX = pData->iRowsize; iX > 0; iX--)
-#else
-        for (iX = 0; iX < pData->iRowsize; iX++)
-#endif
-#endif
-        {
-          *pTemp = 0;
-          pTemp++;
-        }
-      }
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_NEXT_ROW, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_cleanup_rowproc (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CLEANUP_ROWPROC, MNG_LC_START);
-#endif
-
-#ifdef MNG_INCLUDE_LCMS                /* cleanup cms profile/transform */
-  {
-    mng_retcode iRetcode = mng_clear_cms (pData);
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-  }
-#endif /* MNG_INCLUDE_LCMS */
-
-  if (pData->pRGBArow)                 /* cleanup buffer for intermediate row */
-    MNG_FREEX (pData, pData->pRGBArow, (pData->iDatawidth << 3));
-  if (pData->pPrevrow)                 /* cleanup buffer for previous row */
-    MNG_FREEX (pData, pData->pPrevrow, pData->iRowmax);
-  if (pData->pWorkrow)                 /* cleanup buffer for working row */
-    MNG_FREEX (pData, pData->pWorkrow, pData->iRowmax);
-
-  pData->pWorkrow = MNG_NULL;          /* propogate uninitialized buffers */
-  pData->pPrevrow = MNG_NULL;
-  pData->pRGBArow = MNG_NULL;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_CLEANUP_ROWPROC, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* woohiii */
-}
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Generic row processing routines for JNG                                * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-
-/* ************************************************************************** */
-
-mng_retcode mng_display_jpeg_rows (mng_datap pData)
-{
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_JPEG_ROWS, MNG_LC_START);
-#endif
-                                       /* any completed rows ? */
-  if ((pData->iJPEGrow      > pData->iJPEGdisprow) &&
-      (pData->iJPEGalpharow > pData->iJPEGdisprow)    )
-  {
-    mng_uint32 iX, iMax;
-    mng_uint32 iSaverow = pData->iRow; /* save alpha decompression row-count */
-                                       /* determine the highest complete(!) row */
-    if (pData->iJPEGrow > pData->iJPEGalpharow)
-      iMax = pData->iJPEGalpharow;
-    else
-      iMax = pData->iJPEGrow;
-                                       /* display the rows */
-    for (iX = pData->iJPEGdisprow; iX < iMax; iX++)
-    {
-      pData->iRow = iX;                /* make sure we all know which row to handle */
-                                       /* makeup an intermediate row from the buffer */
-      iRetcode = ((mng_retrieverow)pData->fRetrieverow) (pData);
-                                       /* color-correct it if necessary */
-      if ((!iRetcode) && (pData->fCorrectrow))
-        iRetcode = ((mng_correctrow)pData->fCorrectrow) (pData);
-
-      if (!iRetcode)                   /* and display it */
-      {
-        iRetcode = ((mng_displayrow)pData->fDisplayrow) (pData);
-
-        if (!iRetcode)                 /* check progressive display refresh */
-          iRetcode = mng_display_progressive_check (pData);
-      }
-
-      if (iRetcode)                    /* on error bail out */
-        return iRetcode;
-    }
-
-    pData->iJPEGdisprow = iMax;        /* keep track of the last displayed row */
-    pData->iRow         = iSaverow;    /* restore alpha decompression row-count */
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DISPLAY_JPEG_ROWS, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_next_jpeg_alpharow (mng_datap pData)
-{
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_NEXT_JPEG_ALPHAROW, MNG_LC_START);
-#endif
-
-  pData->iJPEGalpharow++;              /* count the row */
-
-  if (pData->fDisplayrow)              /* display "on-the-fly" ? */
-  {                                    /* try to display what you can */
-    iRetcode = mng_display_jpeg_rows (pData);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_NEXT_JPEG_ALPHAROW, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_next_jpeg_row (mng_datap pData)
-{
-  mng_retcode iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_NEXT_JPEG_ROW, MNG_LC_START);
-#endif
-
-  pData->iJPEGrow++;                   /* increase the row-counter */
-
-  if (pData->fDisplayrow)              /* display "on-the-fly" ? */
-  {                                    /* has alpha channel ? */
-    if ((pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA ) ||
-        (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA)    )
-    {                                  /* try to display what you can */
-      iRetcode = mng_display_jpeg_rows (pData);
-    }
-    else
-    {                                  /* make sure we all know which row to handle */
-      pData->iRow = pData->iJPEGrow - 1;
-                                       /* makeup an intermediate row from the buffer */
-      iRetcode = ((mng_retrieverow)pData->fRetrieverow) (pData);
-                                       /* color-correct it if necessary */
-      if ((!iRetcode) && (pData->fCorrectrow))
-        iRetcode = ((mng_correctrow)pData->fCorrectrow) (pData);
-
-      if (!iRetcode)                   /* and display it */
-      {
-        iRetcode = ((mng_displayrow)pData->fDisplayrow) (pData);
-
-        if (!iRetcode)                 /* check progressive display refresh */
-          iRetcode = mng_display_progressive_check (pData);
-      }
-    }
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-  }
-
-                                       /* surpassed last filled row ? */
-  if (pData->iJPEGrow > pData->iJPEGrgbrow)
-    pData->iJPEGrgbrow = pData->iJPEGrow;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_NEXT_JPEG_ROW, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#endif /* MNG_INCLUDE_JNG */
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_MAGN
-#ifndef MNG_OPTIMIZE_FOOTPRINT_MAGN
-#ifndef MNG_NO_GRAY_SUPPORT
-mng_retcode mng_magnify_g8_x1 (mng_datap  pData,
-                               mng_uint16 iMX,
-                               mng_uint16 iML,
-                               mng_uint16 iMR,
-                               mng_uint32 iWidth,
-                               mng_uint8p pSrcline,
-                               mng_uint8p pDstline)
-{
-  mng_uint32 iX, iS, iM;
-  mng_uint8p pTempsrc1;
-  mng_uint8p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_G8_X1, MNG_LC_START);
-#endif
-
-  pTempsrc1 = pSrcline;                /* initialize pixel-loop */
-  pTempdst  = pDstline;
-
-  for (iX = 0; iX < iWidth; iX++)
-  {
-    *pTempdst = *pTempsrc1;            /* copy original source pixel */
-    pTempdst++;
-
-    if (iX == 0)                       /* first interval ? */
-      iM = iML;
-    else
-    if (iX == (iWidth - 1))            /* last interval ? */
-      iM = iMR;
-    else
-      iM = iMX;
-
-    for (iS = 1; iS < iM; iS++)        /* fill interval */
-    {
-      *pTempdst = *pTempsrc1;          /* copy original source pixel */
-      pTempdst++;
-    }
-
-    pTempsrc1++;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_G8_X1, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_g8_x2 (mng_datap  pData,
-                               mng_uint16 iMX,
-                               mng_uint16 iML,
-                               mng_uint16 iMR,
-                               mng_uint32 iWidth,
-                               mng_uint8p pSrcline,
-                               mng_uint8p pDstline)
-{
-  mng_uint32 iX;
-  mng_int32  iS, iM;
-  mng_uint8p pTempsrc1;
-  mng_uint8p pTempsrc2;
-  mng_uint8p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_G8_X2, MNG_LC_START);
-#endif
-
-  pTempsrc1 = pSrcline;                /* initialize pixel-loop */
-  pTempdst  = pDstline;
-
-  for (iX = 0; iX < iWidth; iX++)
-  {
-    pTempsrc2 = pTempsrc1 + 1;
-
-    *pTempdst = *pTempsrc1;            /* copy original source pixel */
-    pTempdst++;
-
-    if (iX == 0)                       /* first interval ? */
-    {
-      if (iWidth == 1)                 /* single pixel ? */
-        pTempsrc2 = MNG_NULL;
-
-      iM = iML;
-    }
-    else
-    if (iX == (iWidth - 2))            /* last interval ? */
-      iM = iMR;
-    else
-      iM = iMX;
-                                       /* fill interval ? */
-    if ((iX < iWidth - 1) || (iWidth == 1))
-    {
-      if (pTempsrc2)                   /* do we have the second pixel ? */
-      {                                /* is it same as first ? */
-        if (*pTempsrc1 == *pTempsrc2)
-        {
-          for (iS = 1; iS < iM; iS++)  /* then just repeat the first */
-          {
-            *pTempdst = *pTempsrc1;
-            pTempdst++;
-          }
-        }
-        else
-        {
-          for (iS = 1; iS < iM; iS++)  /* calculate the distances */
-          {
-            *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*pTempsrc2)     -
-                                                 (mng_int32)(*pTempsrc1)     ) + iM) /
-                                     (iM * 2)) + (mng_int32)(*pTempsrc1)             );
-            pTempdst++;
-          }
-        }
-      }
-      else
-      {
-        for (iS = 1; iS < iM; iS++)
-        {
-          *pTempdst = *pTempsrc1;      /* repeat first source pixel */
-          pTempdst++;
-        }
-      }
-    }
-
-    pTempsrc1++;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_G8_X2, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_g8_x3 (mng_datap  pData,
-                               mng_uint16 iMX,
-                               mng_uint16 iML,
-                               mng_uint16 iMR,
-                               mng_uint32 iWidth,
-                               mng_uint8p pSrcline,
-                               mng_uint8p pDstline)
-{
-  mng_uint32 iX;
-  mng_int32  iS, iM, iH;
-  mng_uint8p pTempsrc1;
-  mng_uint8p pTempsrc2;
-  mng_uint8p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_G8_X3, MNG_LC_START);
-#endif
-
-  pTempsrc1 = pSrcline;                /* initialize pixel-loop */
-  pTempdst  = pDstline;
-
-  for (iX = 0; iX < iWidth; iX++)
-  {
-    pTempsrc2 = pTempsrc1 + 1;
-
-    *pTempdst = *pTempsrc1;            /* copy original source pixel */
-    pTempdst++;
-
-    if (iX == 0)                       /* first interval ? */
-    {
-      if (iWidth == 1)                 /* single pixel ? */
-        pTempsrc2 = MNG_NULL;
-
-      iM = iML;
-    }
-    else
-    if (iX == (iWidth - 2))            /* last interval ? */
-      iM = iMR;
-    else
-      iM = iMX;
-                                       /* fill interval ? */
-    if ((iX < iWidth - 1) || (iWidth == 1))
-    {
-      if (pTempsrc2)                   /* do we have the second pixel ? */
-      {                                /* is it same as first ? */
-        if (*pTempsrc1 == *pTempsrc2)
-        {
-          for (iS = 1; iS < iM; iS++)  /* then just repeat the first */
-          {
-            *pTempdst = *pTempsrc1;
-            pTempdst++;
-          }
-        }
-        else
-        {
-          iH = (iM+1) / 2;             /* calculate halfway point */
-
-          for (iS = 1; iS < iH; iS++)  /* replicate first half */
-          {
-            *pTempdst = *pTempsrc1;
-            pTempdst++;
-          }
-
-          for (iS = iH; iS < iM; iS++) /* replicate second half */
-          {
-            *pTempdst = *pTempsrc2;
-            pTempdst++;
-          }
-        }
-      }
-      else
-      {
-        for (iS = 1; iS < iM; iS++)
-        {
-          *pTempdst = *pTempsrc1;      /* repeat first source pixel */
-          pTempdst++;
-        }
-      }
-    }
-
-    pTempsrc1++;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_G8_X3, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_NO_GRAY_SUPPORT */
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_rgb8_x1 (mng_datap  pData,
-                                 mng_uint16 iMX,
-                                 mng_uint16 iML,
-                                 mng_uint16 iMR,
-                                 mng_uint32 iWidth,
-                                 mng_uint8p pSrcline,
-                                 mng_uint8p pDstline)
-{
-  mng_uint32 iX, iS, iM;
-  mng_uint8p pTempsrc1;
-  mng_uint8p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB8_X1, MNG_LC_START);
-#endif
-
-  pTempsrc1 = pSrcline;                /* initialize pixel-loop */
-  pTempdst  = pDstline;
-
-  for (iX = 0; iX < iWidth; iX++)
-  {
-    *pTempdst = *pTempsrc1;            /* copy original source pixel */
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+1);
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+2);
-    pTempdst++;
-
-    if (iX == 0)                       /* first interval ? */
-      iM = iML;
-    else
-    if (iX == (iWidth - 1))            /* last interval ? */
-      iM = iMR;
-    else
-      iM = iMX;
-
-    for (iS = 1; iS < iM; iS++)        /* fill interval */
-    {
-      *pTempdst = *pTempsrc1;          /* copy original source pixel */
-      pTempdst++;
-      *pTempdst = *(pTempsrc1+1);
-      pTempdst++;
-      *pTempdst = *(pTempsrc1+2);
-      pTempdst++;
-    }
-
-    pTempsrc1 += 3;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB8_X1, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_rgb8_x2 (mng_datap  pData,
-                                 mng_uint16 iMX,
-                                 mng_uint16 iML,
-                                 mng_uint16 iMR,
-                                 mng_uint32 iWidth,
-                                 mng_uint8p pSrcline,
-                                 mng_uint8p pDstline)
-{
-  mng_uint32 iX;
-  mng_int32  iS, iM;
-  mng_uint8p pTempsrc1;
-  mng_uint8p pTempsrc2;
-  mng_uint8p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB8_X2, MNG_LC_START);
-#endif
-
-  pTempsrc1 = pSrcline;                /* initialize pixel-loop */
-  pTempdst  = pDstline;
-
-  for (iX = 0; iX < iWidth; iX++)
-  {
-    pTempsrc2 = pTempsrc1 + 3;
-
-    *pTempdst = *pTempsrc1;            /* copy original source pixel */
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+1);
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+2);
-    pTempdst++;
-
-    if (iX == 0)                       /* first interval ? */
-    {
-      if (iWidth == 1)                 /* single pixel ? */
-        pTempsrc2 = MNG_NULL;
-
-      iM = (mng_int32)iML;
-    }
-    else
-    if (iX == (iWidth - 2))            /* last interval ? */
-      iM = (mng_int32)iMR;
-    else
-      iM = (mng_int32)iMX;
-                                       /* fill interval ? */
-    if ((iX < iWidth - 1) || (iWidth == 1))
-    {
-      if (pTempsrc2)                   /* do we have the second pixel ? */
-      {
-        for (iS = 1; iS < iM; iS++)
-        {
-          if (*pTempsrc1 == *pTempsrc2)
-            *pTempdst = *pTempsrc1;    /* just repeat the first */
-          else                         /* calculate the distance */
-            *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*pTempsrc2)     -
-                                                 (mng_int32)(*pTempsrc1)     ) + iM) /
-                                     (iM * 2)) + (mng_int32)(*pTempsrc1)             );
-
-          pTempdst++;
-
-          if (*(pTempsrc1+1) == *(pTempsrc2+1))
-            *pTempdst = *(pTempsrc1+1);
-          else
-            *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+1)) -
-                                                 (mng_int32)(*(pTempsrc1+1)) ) + iM) /
-                                     (iM * 2)) + (mng_int32)(*(pTempsrc1+1))         );
-
-          pTempdst++;
-
-          if (*(pTempsrc1+2) == *(pTempsrc2+2))
-            *pTempdst = *(pTempsrc1+2);
-          else
-            *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+2)) -
-                                                 (mng_int32)(*(pTempsrc1+2)) ) + iM) /
-                                     (iM * 2)) + (mng_int32)(*(pTempsrc1+2))         );
-
-          pTempdst++;
-        }
-      }
-      else
-      {
-        for (iS = 1; iS < iM; iS++)
-        {
-          *pTempdst = *pTempsrc1;      /* repeat first source pixel */
-          pTempdst++;
-          *pTempdst = *(pTempsrc1+1);
-          pTempdst++;
-          *pTempdst = *(pTempsrc1+2);
-          pTempdst++;
-        }
-      }
-    }
-
-    pTempsrc1 += 3;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB8_X2, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_rgb8_x3 (mng_datap  pData,
-                                 mng_uint16 iMX,
-                                 mng_uint16 iML,
-                                 mng_uint16 iMR,
-                                 mng_uint32 iWidth,
-                                 mng_uint8p pSrcline,
-                                 mng_uint8p pDstline)
-{
-  mng_uint32 iX;
-  mng_int32  iS, iM, iH;
-  mng_uint8p pTempsrc1;
-  mng_uint8p pTempsrc2;
-  mng_uint8p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB8_X3, MNG_LC_START);
-#endif
-
-  pTempsrc1 = pSrcline;                /* initialize pixel-loop */
-  pTempdst  = pDstline;
-
-  for (iX = 0; iX < iWidth; iX++)
-  {
-    pTempsrc2 = pTempsrc1 + 3;
-
-    *pTempdst = *pTempsrc1;            /* copy original source pixel */
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+1);
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+2);
-    pTempdst++;
-
-    if (iX == 0)                       /* first interval ? */
-    {
-      if (iWidth == 1)                 /* single pixel ? */
-        pTempsrc2 = MNG_NULL;
-
-      iM = (mng_int32)iML;
-    }
-    else
-    if (iX == (iWidth - 2))            /* last interval ? */
-      iM = (mng_int32)iMR;
-    else
-      iM = (mng_int32)iMX;
-                                       /* fill interval ? */
-    if ((iX < iWidth - 1) || (iWidth == 1))
-    {
-      if (pTempsrc2)                   /* do we have the second pixel ? */
-      {
-        iH = (iM+1) / 2;               /* calculate halfway point */
-
-        for (iS = 1; iS < iH; iS++)    /* replicate first half */
-        {
-          *pTempdst     = *pTempsrc1;
-          *(pTempdst+1) = *(pTempsrc1+1);
-          *(pTempdst+2) = *(pTempsrc1+2);
-
-          pTempdst += 3;
-        }
-
-        for (iS = iH; iS < iM; iS++)    /* replicate second half */
-        {
-          *pTempdst     = *pTempsrc2;
-          *(pTempdst+1) = *(pTempsrc2+1);
-          *(pTempdst+2) = *(pTempsrc2+2);
-
-          pTempdst += 3;
-        }
-      }
-      else
-      {
-        for (iS = 1; iS < iM; iS++)
-        {
-          *pTempdst = *pTempsrc1;      /* repeat first source pixel */
-          pTempdst++;
-          *pTempdst = *(pTempsrc1+1);
-          pTempdst++;
-          *pTempdst = *(pTempsrc1+2);
-          pTempdst++;
-        }
-      }
-    }
-
-    pTempsrc1 += 3;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB8_X3, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_GRAY_SUPPORT
-mng_retcode mng_magnify_ga8_x1 (mng_datap  pData,
-                                mng_uint16 iMX,
-                                mng_uint16 iML,
-                                mng_uint16 iMR,
-                                mng_uint32 iWidth,
-                                mng_uint8p pSrcline,
-                                mng_uint8p pDstline)
-{
-  mng_uint32 iX, iS, iM;
-  mng_uint8p pTempsrc1;
-  mng_uint8p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_X1, MNG_LC_START);
-#endif
-
-  pTempsrc1 = pSrcline;                /* initialize pixel-loop */
-  pTempdst  = pDstline;
-
-  for (iX = 0; iX < iWidth; iX++)
-  {
-    *pTempdst = *pTempsrc1;            /* copy original source pixel */
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+1);
-    pTempdst++;
-
-    if (iX == 0)                       /* first interval ? */
-      iM = iML;
-    else
-    if (iX == (iWidth - 1))            /* last interval ? */
-      iM = iMR;
-    else
-      iM = iMX;
-
-    for (iS = 1; iS < iM; iS++)        /* fill interval */
-    {
-      *pTempdst = *pTempsrc1;          /* copy original source pixel */
-      pTempdst++;
-      *pTempdst = *(pTempsrc1+1);
-      pTempdst++;
-    }
-
-    pTempsrc1 += 2;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_X1, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_ga8_x2 (mng_datap  pData,
-                                mng_uint16 iMX,
-                                mng_uint16 iML,
-                                mng_uint16 iMR,
-                                mng_uint32 iWidth,
-                                mng_uint8p pSrcline,
-                                mng_uint8p pDstline)
-{
-  mng_uint32 iX;
-  mng_int32  iS, iM;
-  mng_uint8p pTempsrc1;
-  mng_uint8p pTempsrc2;
-  mng_uint8p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_X2, MNG_LC_START);
-#endif
-
-  pTempsrc1 = pSrcline;                /* initialize pixel-loop */
-  pTempdst  = pDstline;
-
-  for (iX = 0; iX < iWidth; iX++)
-  {
-    pTempsrc2 = pTempsrc1 + 2;
-
-    *pTempdst = *pTempsrc1;            /* copy original source pixel */
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+1);
-    pTempdst++;
-
-    if (iX == 0)                       /* first interval ? */
-    {
-      if (iWidth == 1)                 /* single pixel ? */
-        pTempsrc2 = MNG_NULL;
-
-      iM = iML;
-    }
-    else
-    if (iX == (iWidth - 2))            /* last interval ? */
-      iM = iMR;
-    else
-      iM = iMX;
-                                       /* fill interval ? */
-    if ((iX < iWidth - 1) || (iWidth == 1))
-    {
-      if (pTempsrc2)                   /* do we have the second pixel ? */
-      {
-        for (iS = 1; iS < iM; iS++)
-        {
-          if (*pTempsrc1 == *pTempsrc2)
-            *pTempdst = *pTempsrc1;    /* just repeat the first */
-          else                         /* calculate the distance */
-            *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*pTempsrc2)     -
-                                                 (mng_int32)(*pTempsrc1)     ) + iM) /
-                                     (iM * 2)) + (mng_int32)(*pTempsrc1)             );
-
-          pTempdst++;
-
-          if (*(pTempsrc1+1) == *(pTempsrc2+1))
-            *pTempdst = *(pTempsrc1+1);
-          else
-            *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+1)) -
-                                                 (mng_int32)(*(pTempsrc1+1)) ) + iM) /
-                                     (iM * 2)) + (mng_int32)(*(pTempsrc1+1))         );
-
-          pTempdst++;
-        }
-      }
-      else
-      {
-        for (iS = 1; iS < iM; iS++)
-        {
-          *pTempdst = *pTempsrc1;      /* repeat first source pixel */
-          pTempdst++;
-          *pTempdst = *(pTempsrc1+1);
-          pTempdst++;
-        }
-      }
-    }
-
-    pTempsrc1 += 2;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_X2, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_ga8_x3 (mng_datap  pData,
-                                mng_uint16 iMX,
-                                mng_uint16 iML,
-                                mng_uint16 iMR,
-                                mng_uint32 iWidth,
-                                mng_uint8p pSrcline,
-                                mng_uint8p pDstline)
-{
-  mng_uint32 iX;
-  mng_int32  iS, iM, iH;
-  mng_uint8p pTempsrc1;
-  mng_uint8p pTempsrc2;
-  mng_uint8p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_X3, MNG_LC_START);
-#endif
-
-  pTempsrc1 = pSrcline;                /* initialize pixel-loop */
-  pTempdst  = pDstline;
-
-  for (iX = 0; iX < iWidth; iX++)
-  {
-    pTempsrc2 = pTempsrc1 + 2;
-
-    *pTempdst = *pTempsrc1;            /* copy original source pixel */
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+1);
-    pTempdst++;
-
-    if (iX == 0)                       /* first interval ? */
-    {
-      if (iWidth == 1)                 /* single pixel ? */
-        pTempsrc2 = MNG_NULL;
-
-      iM = iML;
-    }
-    else
-    if (iX == (iWidth - 2))            /* last interval ? */
-      iM = iMR;
-    else
-      iM = iMX;
-                                       /* fill interval ? */
-    if ((iX < iWidth - 1) || (iWidth == 1))
-    {
-      if (pTempsrc2)                   /* do we have the second pixel ? */
-      {
-        iH = (iM+1) / 2;               /* calculate halfway point */
-
-        for (iS = 1; iS < iH; iS++)    /* replicate first half */
-        {
-          *pTempdst     = *pTempsrc1;
-          *(pTempdst+1) = *(pTempsrc1+1);
-
-          pTempdst += 2;
-        }
-
-        for (iS = iH; iS < iM; iS++)   /* replicate second half */
-        {
-          *pTempdst     = *pTempsrc2;
-          *(pTempdst+1) = *(pTempsrc2+1);
-
-          pTempdst += 2;
-        }
-      }
-      else
-      {
-        for (iS = 1; iS < iM; iS++)
-        {
-          *pTempdst = *pTempsrc1;      /* repeat first source pixel */
-          pTempdst++;
-          *pTempdst = *(pTempsrc1+1);
-          pTempdst++;
-        }
-      }
-    }
-
-    pTempsrc1 += 2;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_X3, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_ga8_x4 (mng_datap  pData,
-                                mng_uint16 iMX,
-                                mng_uint16 iML,
-                                mng_uint16 iMR,
-                                mng_uint32 iWidth,
-                                mng_uint8p pSrcline,
-                                mng_uint8p pDstline)
-{
-  mng_uint32 iX;
-  mng_int32  iS, iM, iH;
-  mng_uint8p pTempsrc1;
-  mng_uint8p pTempsrc2;
-  mng_uint8p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_X4, MNG_LC_START);
-#endif
-
-  pTempsrc1 = pSrcline;                /* initialize pixel-loop */
-  pTempdst  = pDstline;
-
-  for (iX = 0; iX < iWidth; iX++)
-  {
-    pTempsrc2 = pTempsrc1 + 2;
-
-    *pTempdst = *pTempsrc1;            /* copy original source pixel */
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+1);
-    pTempdst++;
-
-    if (iX == 0)                       /* first interval ? */
-    {
-      if (iWidth == 1)                 /* single pixel ? */
-        pTempsrc2 = MNG_NULL;
-
-      iM = iML;
-    }
-    else
-    if (iX == (iWidth - 2))            /* last interval ? */
-      iM = iMR;
-    else
-      iM = iMX;
-                                       /* fill interval ? */
-    if ((iX < iWidth - 1) || (iWidth == 1))
-    {
-      if (pTempsrc2)                   /* do we have the second pixel ? */
-      {
-        iH = (iM+1) / 2;               /* calculate halfway point */
-
-        for (iS = 1; iS < iH; iS++)    /* first half */
-        {
-          if (*pTempsrc1 == *pTempsrc2)
-            *pTempdst = *pTempsrc1;    /* just repeat the first */
-          else                         /* calculate the distance */
-            *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*pTempsrc2)     -
-                                                 (mng_int32)(*pTempsrc1)     ) + iM) /
-                                     (iM * 2)) + (mng_int32)(*pTempsrc1)             );
-
-          pTempdst++;
-
-          *pTempdst = *(pTempsrc1+1);  /* replicate alpha from left */
-
-          pTempdst++;
-        }
-
-        for (iS = iH; iS < iM; iS++)   /* second half */
-        {
-          if (*pTempsrc1 == *pTempsrc2)
-            *pTempdst = *pTempsrc1;    /* just repeat the first */
-          else                         /* calculate the distance */
-            *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*pTempsrc2)     -
-                                                 (mng_int32)(*pTempsrc1)     ) + iM) /
-                                     (iM * 2)) + (mng_int32)(*pTempsrc1)             );
-
-          pTempdst++;
-
-          *pTempdst = *(pTempsrc2+1);  /* replicate alpha from right */
-
-          pTempdst++;
-        }
-      }
-      else
-      {
-        for (iS = 1; iS < iM; iS++)
-        {
-          *pTempdst = *pTempsrc1;      /* repeat first source pixel */
-          pTempdst++;
-          *pTempdst = *(pTempsrc1+1);
-          pTempdst++;
-        }
-      }
-    }
-
-    pTempsrc1 += 2;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_X4, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_ga8_x5 (mng_datap  pData,
-                                mng_uint16 iMX,
-                                mng_uint16 iML,
-                                mng_uint16 iMR,
-                                mng_uint32 iWidth,
-                                mng_uint8p pSrcline,
-                                mng_uint8p pDstline)
-{
-  mng_uint32 iX;
-  mng_int32  iS, iM, iH;
-  mng_uint8p pTempsrc1;
-  mng_uint8p pTempsrc2;
-  mng_uint8p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_X5, MNG_LC_START);
-#endif
-
-  pTempsrc1 = pSrcline;                /* initialize pixel-loop */
-  pTempdst  = pDstline;
-
-  for (iX = 0; iX < iWidth; iX++)
-  {
-    pTempsrc2 = pTempsrc1 + 2;
-
-    *pTempdst = *pTempsrc1;            /* copy original source pixel */
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+1);
-    pTempdst++;
-
-    if (iX == 0)                       /* first interval ? */
-    {
-      if (iWidth == 1)                 /* single pixel ? */
-        pTempsrc2 = MNG_NULL;
-
-      iM = iML;
-    }
-    else
-    if (iX == (iWidth - 2))            /* last interval ? */
-      iM = iMR;
-    else
-      iM = iMX;
-                                       /* fill interval ? */
-    if ((iX < iWidth - 1) || (iWidth == 1))
-    {
-      if (pTempsrc2)                   /* do we have the second pixel ? */
-      {
-        iH = (iM+1) / 2;               /* calculate halfway point */
-
-        for (iS = 1; iS < iH; iS++)    /* first half */
-        {
-          *pTempdst = *pTempsrc1;      /* replicate gray from left */
-
-          pTempdst++;
-
-          if (*(pTempsrc1+1) == *(pTempsrc2+1))
-            *pTempdst = *(pTempsrc1+1);/* just repeat the first */
-          else                         /* calculate the distance */
-            *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+1))     -
-                                                 (mng_int32)(*(pTempsrc1+1))     ) + iM) /
-                                     (iM * 2)) + (mng_int32)(*(pTempsrc1+1))             );
-
-          pTempdst++;
-        }
-
-        for (iS = iH; iS < iM; iS++)   /* second half */
-        {
-          *pTempdst = *pTempsrc2;      /* replicate gray from right */
-
-          pTempdst++;
-
-          if (*(pTempsrc1+1) == *(pTempsrc2+1))
-            *pTempdst = *(pTempsrc1+1);/* just repeat the first */
-          else                         /* calculate the distance */
-            *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+1))     -
-                                                 (mng_int32)(*(pTempsrc1+1))     ) + iM) /
-                                     (iM * 2)) + (mng_int32)(*(pTempsrc1+1))             );
-
-          pTempdst++;
-        }
-      }
-      else
-      {
-        for (iS = 1; iS < iM; iS++)
-        {
-          *pTempdst = *pTempsrc1;      /* repeat first source pixel */
-          pTempdst++;
-          *pTempdst = *(pTempsrc1+1);
-          pTempdst++;
-        }
-      }
-    }
-
-    pTempsrc1 += 2;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_X5, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_NO_GRAY_SUPPORT */
-#endif /* MNG_OPTIMIZE_FOOTPRINT_MAGN */
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_rgba8_x1 (mng_datap  pData,
-                                  mng_uint16 iMX,
-                                  mng_uint16 iML,
-                                  mng_uint16 iMR,
-                                  mng_uint32 iWidth,
-                                  mng_uint8p pSrcline,
-                                  mng_uint8p pDstline)
-{
-  mng_uint32 iX, iS, iM;
-  mng_uint8p pTempsrc1;
-  mng_uint8p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_X1, MNG_LC_START);
-#endif
-
-  pTempsrc1 = pSrcline;                /* initialize pixel-loop */
-  pTempdst  = pDstline;
-
-  for (iX = 0; iX < iWidth; iX++)
-  {
-    *pTempdst = *pTempsrc1;            /* copy original source pixel */
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+1);
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+2);
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+3);
-    pTempdst++;
-
-    if (iX == 0)                       /* first interval ? */
-      iM = iML;
-    else
-    if (iX == (iWidth - 1))            /* last interval ? */
-      iM = iMR;
-    else
-      iM = iMX;
-
-    for (iS = 1; iS < iM; iS++)        /* fill interval */
-    {
-      *pTempdst = *pTempsrc1;          /* copy original source pixel */
-      pTempdst++;
-      *pTempdst = *(pTempsrc1+1);
-      pTempdst++;
-      *pTempdst = *(pTempsrc1+2);
-      pTempdst++;
-      *pTempdst = *(pTempsrc1+3);
-      pTempdst++;
-    }
-
-    pTempsrc1 += 4;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_X1, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_rgba8_x2 (mng_datap  pData,
-                                  mng_uint16 iMX,
-                                  mng_uint16 iML,
-                                  mng_uint16 iMR,
-                                  mng_uint32 iWidth,
-                                  mng_uint8p pSrcline,
-                                  mng_uint8p pDstline)
-{
-  mng_uint32 iX;
-  mng_int32  iS, iM;
-  mng_uint8p pTempsrc1;
-  mng_uint8p pTempsrc2;
-  mng_uint8p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_X2, MNG_LC_START);
-#endif
-
-  pTempsrc1 = pSrcline;                /* initialize pixel-loop */
-  pTempdst  = pDstline;
-
-  for (iX = 0; iX < iWidth; iX++)
-  {
-    pTempsrc2 = pTempsrc1 + 4;
-
-    *pTempdst = *pTempsrc1;            /* copy original source pixel */
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+1);
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+2);
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+3);
-    pTempdst++;
-
-    if (iX == 0)                       /* first interval ? */
-    {
-      if (iWidth == 1)                 /* single pixel ? */
-        pTempsrc2 = MNG_NULL;
-
-      iM = (mng_int32)iML;
-    }
-    else
-    if (iX == (iWidth - 2))            /* last interval ? */
-      iM = (mng_int32)iMR;
-    else
-      iM = (mng_int32)iMX;
-                                       /* fill interval ? */
-    if ((iX < iWidth - 1) || (iWidth == 1))
-    {
-      if (pTempsrc2)                   /* do we have the second pixel ? */
-      {
-        for (iS = 1; iS < iM; iS++)
-        {
-          if (*pTempsrc1 == *pTempsrc2)
-            *pTempdst = *pTempsrc1;    /* just repeat the first */
-          else                         /* calculate the distance */
-            *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*pTempsrc2)     -
-                                                 (mng_int32)(*pTempsrc1)     ) + iM) /
-                                     (iM * 2)) + (mng_int32)(*pTempsrc1)             );
-
-          pTempdst++;
-
-          if (*(pTempsrc1+1) == *(pTempsrc2+1))
-            *pTempdst = *(pTempsrc1+1);
-          else
-            *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+1)) -
-                                                 (mng_int32)(*(pTempsrc1+1)) ) + iM) /
-                                     (iM * 2)) + (mng_int32)(*(pTempsrc1+1))         );
-
-          pTempdst++;
-
-          if (*(pTempsrc1+2) == *(pTempsrc2+2))
-            *pTempdst = *(pTempsrc1+2);
-          else
-            *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+2)) -
-                                                 (mng_int32)(*(pTempsrc1+2)) ) + iM) /
-                                     (iM * 2)) + (mng_int32)(*(pTempsrc1+2))         );
-
-          pTempdst++;
-
-          if (*(pTempsrc1+3) == *(pTempsrc2+3))
-            *pTempdst = *(pTempsrc1+3);
-          else
-            *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+3)) -
-                                                 (mng_int32)(*(pTempsrc1+3)) ) + iM) /
-                                     (iM * 2)) + (mng_int32)(*(pTempsrc1+3))         );
-
-          pTempdst++;
-        }
-      }
-      else
-      {
-        for (iS = 1; iS < iM; iS++)
-        {
-          *pTempdst = *pTempsrc1;      /* repeat first source pixel */
-          pTempdst++;
-          *pTempdst = *(pTempsrc1+1);
-          pTempdst++;
-          *pTempdst = *(pTempsrc1+2);
-          pTempdst++;
-          *pTempdst = *(pTempsrc1+3);
-          pTempdst++;
-        }
-      }
-    }
-
-    pTempsrc1 += 4;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_X2, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_rgba8_x3 (mng_datap  pData,
-                                  mng_uint16 iMX,
-                                  mng_uint16 iML,
-                                  mng_uint16 iMR,
-                                  mng_uint32 iWidth,
-                                  mng_uint8p pSrcline,
-                                  mng_uint8p pDstline)
-{
-  mng_uint32 iX;
-  mng_int32  iS, iM, iH;
-  mng_uint8p pTempsrc1;
-  mng_uint8p pTempsrc2;
-  mng_uint8p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_X3, MNG_LC_START);
-#endif
-
-  pTempsrc1 = pSrcline;                /* initialize pixel-loop */
-  pTempdst  = pDstline;
-
-  for (iX = 0; iX < iWidth; iX++)
-  {
-    pTempsrc2 = pTempsrc1 + 4;
-
-    *pTempdst = *pTempsrc1;            /* copy original source pixel */
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+1);
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+2);
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+3);
-    pTempdst++;
-
-    if (iX == 0)                       /* first interval ? */
-    {
-      if (iWidth == 1)                 /* single pixel ? */
-        pTempsrc2 = MNG_NULL;
-
-      iM = (mng_int32)iML;
-    }
-    else
-    if (iX == (iWidth - 2))            /* last interval ? */
-      iM = (mng_int32)iMR;
-    else
-      iM = (mng_int32)iMX;
-                                       /* fill interval ? */
-    if ((iX < iWidth - 1) || (iWidth == 1))
-    {
-      if (pTempsrc2)                   /* do we have the second pixel ? */
-      {
-        iH = (iM+1) / 2;               /* calculate halfway point */
-
-        for (iS = 1; iS < iH; iS++)    /* replicate first half */
-        {
-          *pTempdst     = *pTempsrc1;
-          *(pTempdst+1) = *(pTempsrc1+1);
-          *(pTempdst+2) = *(pTempsrc1+2);
-          *(pTempdst+3) = *(pTempsrc1+3);
-
-          pTempdst += 4;
-        }
-
-        for (iS = iH; iS < iM; iS++)   /* replicate second half */
-        {
-          *pTempdst     = *pTempsrc2;
-          *(pTempdst+1) = *(pTempsrc2+1);
-          *(pTempdst+2) = *(pTempsrc2+2);
-          *(pTempdst+3) = *(pTempsrc2+3);
-
-          pTempdst += 4;
-        }
-      }
-      else
-      {
-        for (iS = 1; iS < iM; iS++)
-        {
-          *pTempdst = *pTempsrc1;      /* repeat first source pixel */
-          pTempdst++;
-          *pTempdst = *(pTempsrc1+1);
-          pTempdst++;
-          *pTempdst = *(pTempsrc1+2);
-          pTempdst++;
-          *pTempdst = *(pTempsrc1+3);
-          pTempdst++;
-        }
-      }
-    }
-
-    pTempsrc1 += 4;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_X3, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_rgba8_x4 (mng_datap  pData,
-                                  mng_uint16 iMX,
-                                  mng_uint16 iML,
-                                  mng_uint16 iMR,
-                                  mng_uint32 iWidth,
-                                  mng_uint8p pSrcline,
-                                  mng_uint8p pDstline)
-{
-  mng_uint32 iX;
-  mng_int32  iS, iM, iH;
-  mng_uint8p pTempsrc1;
-  mng_uint8p pTempsrc2;
-  mng_uint8p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_X4, MNG_LC_START);
-#endif
-
-  pTempsrc1 = pSrcline;                /* initialize pixel-loop */
-  pTempdst  = pDstline;
-
-  for (iX = 0; iX < iWidth; iX++)
-  {
-    pTempsrc2 = pTempsrc1 + 4;
-
-    *pTempdst = *pTempsrc1;            /* copy original source pixel */
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+1);
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+2);
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+3);
-    pTempdst++;
-
-    if (iX == 0)                       /* first interval ? */
-    {
-      if (iWidth == 1)                 /* single pixel ? */
-        pTempsrc2 = MNG_NULL;
-
-      iM = (mng_int32)iML;
-    }
-    else
-    if (iX == (iWidth - 2))            /* last interval ? */
-      iM = (mng_int32)iMR;
-    else
-      iM = (mng_int32)iMX;
-                                       /* fill interval ? */
-    if ((iX < iWidth - 1) || (iWidth == 1))
-    {
-      if (pTempsrc2)                   /* do we have the second pixel ? */
-      {
-        iH = (iM+1) / 2;               /* calculate halfway point */
-
-        for (iS = 1; iS < iH; iS++)    /* first half */
-        {
-          if (*pTempsrc1 == *pTempsrc2)
-            *pTempdst = *pTempsrc1;    /* just repeat the first */
-          else                         /* calculate the distance */
-            *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*pTempsrc2)     -
-                                                 (mng_int32)(*pTempsrc1)     ) + iM) /
-                                     (iM * 2)) + (mng_int32)(*pTempsrc1)             );
-
-          pTempdst++;
-
-          if (*(pTempsrc1+1) == *(pTempsrc2+1))
-            *pTempdst = *(pTempsrc1+1);
-          else
-            *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+1)) -
-                                                 (mng_int32)(*(pTempsrc1+1)) ) + iM) /
-                                     (iM * 2)) + (mng_int32)(*(pTempsrc1+1))         );
-
-          pTempdst++;
-
-          if (*(pTempsrc1+2) == *(pTempsrc2+2))
-            *pTempdst = *(pTempsrc1+2);
-          else
-            *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+2)) -
-                                                 (mng_int32)(*(pTempsrc1+2)) ) + iM) /
-                                     (iM * 2)) + (mng_int32)(*(pTempsrc1+2))         );
-
-          pTempdst++;
-                                       /* replicate alpha from left */
-          *pTempdst     = *(pTempsrc1+3);
-
-          pTempdst++;
-        }
-
-        for (iS = iH; iS < iM; iS++)   /* second half */
-        {
-          if (*pTempsrc1 == *pTempsrc2)
-            *pTempdst = *pTempsrc1;    /* just repeat the first */
-          else                         /* calculate the distance */
-            *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*pTempsrc2)     -
-                                                 (mng_int32)(*pTempsrc1)     ) + iM) /
-                                     (iM * 2)) + (mng_int32)(*pTempsrc1)             );
-
-          pTempdst++;
-
-          if (*(pTempsrc1+1) == *(pTempsrc2+1))
-            *pTempdst = *(pTempsrc1+1);
-          else
-            *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+1)) -
-                                                 (mng_int32)(*(pTempsrc1+1)) ) + iM) /
-                                     (iM * 2)) + (mng_int32)(*(pTempsrc1+1))         );
-
-          pTempdst++;
-
-          if (*(pTempsrc1+2) == *(pTempsrc2+2))
-            *pTempdst = *(pTempsrc1+2);
-          else
-            *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+2)) -
-                                                 (mng_int32)(*(pTempsrc1+2)) ) + iM) /
-                                     (iM * 2)) + (mng_int32)(*(pTempsrc1+2))         );
-
-          pTempdst++;
-                                       /* replicate alpha from right */
-          *pTempdst     = *(pTempsrc2+3);
-
-          pTempdst++;
-        }
-      }
-      else
-      {
-        for (iS = 1; iS < iM; iS++)
-        {
-          *pTempdst = *pTempsrc1;      /* repeat first source pixel */
-          pTempdst++;
-          *pTempdst = *(pTempsrc1+1);
-          pTempdst++;
-          *pTempdst = *(pTempsrc1+2);
-          pTempdst++;
-          *pTempdst = *(pTempsrc1+3);
-          pTempdst++;
-        }
-      }
-    }
-
-    pTempsrc1 += 4;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_X4, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_rgba8_x5 (mng_datap  pData,
-                                  mng_uint16 iMX,
-                                  mng_uint16 iML,
-                                  mng_uint16 iMR,
-                                  mng_uint32 iWidth,
-                                  mng_uint8p pSrcline,
-                                  mng_uint8p pDstline)
-{
-  mng_uint32 iX;
-  mng_int32  iS, iM, iH;
-  mng_uint8p pTempsrc1;
-  mng_uint8p pTempsrc2;
-  mng_uint8p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_X5, MNG_LC_START);
-#endif
-
-  pTempsrc1 = pSrcline;                /* initialize pixel-loop */
-  pTempdst  = pDstline;
-
-  for (iX = 0; iX < iWidth; iX++)
-  {
-    pTempsrc2 = pTempsrc1 + 4;
-
-    *pTempdst = *pTempsrc1;            /* copy original source pixel */
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+1);
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+2);
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+3);
-    pTempdst++;
-
-    if (iX == 0)                       /* first interval ? */
-    {
-      if (iWidth == 1)                 /* single pixel ? */
-        pTempsrc2 = MNG_NULL;
-
-      iM = (mng_int32)iML;
-    }
-    else
-    if (iX == (iWidth - 2))            /* last interval ? */
-      iM = (mng_int32)iMR;
-    else
-      iM = (mng_int32)iMX;
-                                       /* fill interval ? */
-    if ((iX < iWidth - 1) || (iWidth == 1))
-    {
-      if (pTempsrc2)                   /* do we have the second pixel ? */
-      {
-        iH = (iM+1) / 2;               /* calculate halfway point */
-
-        for (iS = 1; iS < iH; iS++)    /* first half */
-        {
-          *pTempdst     = *pTempsrc1;  /* replicate color from left */
-          *(pTempdst+1) = *(pTempsrc1+1);
-          *(pTempdst+2) = *(pTempsrc1+2);
-
-          if (*(pTempsrc1+3) == *(pTempsrc2+3))
-            *(pTempdst+3) = *(pTempsrc1+3);
-          else
-            *(pTempdst+3) = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+3)) -
-                                                   (mng_int32)(*(pTempsrc1+3)) ) + iM) /
-                                       (iM * 2)) + (mng_int32)(*(pTempsrc1+3))         );
-
-          pTempdst += 4;
-        }
-
-        for (iS = iH; iS < iM; iS++)   /* second half */
-        {
-          *pTempdst     = *pTempsrc2;  /* replicate color from right */
-          *(pTempdst+1) = *(pTempsrc2+1);
-          *(pTempdst+2) = *(pTempsrc2+2);
-
-          if (*(pTempsrc1+3) == *(pTempsrc2+3))
-            *(pTempdst+3) = *(pTempsrc1+3);
-          else
-            *(pTempdst+3) = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+3)) -
-                                                   (mng_int32)(*(pTempsrc1+3)) ) + iM) /
-                                       (iM * 2)) + (mng_int32)(*(pTempsrc1+3))         );
-
-          pTempdst += 4;
-        }
-      }
-      else
-      {
-        for (iS = 1; iS < iM; iS++)
-        {
-          *pTempdst = *pTempsrc1;      /* repeat first source pixel */
-          pTempdst++;
-          *pTempdst = *(pTempsrc1+1);
-          pTempdst++;
-          *pTempdst = *(pTempsrc1+2);
-          pTempdst++;
-          *pTempdst = *(pTempsrc1+3);
-          pTempdst++;
-        }
-      }
-    }
-
-    pTempsrc1 += 4;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_X4, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_FOOTPRINT_MAGN
-#ifndef MNG_NO_GRAY_SUPPORT
-mng_retcode mng_magnify_g8_y1 (mng_datap  pData,
-                               mng_int32  iS,
-                               mng_int32  iM,
-                               mng_uint32 iWidth,
-                               mng_uint8p pSrcline1,
-                               mng_uint8p pSrcline2,
-                               mng_uint8p pDstline)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_G8_Y1, MNG_LC_START);
-#endif
-
-  MNG_COPY (pDstline, pSrcline1, iWidth);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_G8_Y1, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-mng_retcode mng_magnify_g8_y2 (mng_datap  pData,
-                               mng_int32  iS,
-                               mng_int32  iM,
-                               mng_uint32 iWidth,
-                               mng_uint8p pSrcline1,
-                               mng_uint8p pSrcline2,
-                               mng_uint8p pDstline)
-{
-  mng_uint32 iX;
-  mng_uint8p pTempsrc1;
-  mng_uint8p pTempsrc2;
-  mng_uint8p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_G8_Y2, MNG_LC_START);
-#endif
-
-  pTempsrc1 = pSrcline1;               /* initialize pixel-loop */
-  pTempsrc2 = pSrcline2;
-  pTempdst  = pDstline;
-
-  if (pTempsrc2)                       /* do we have a second line ? */
-  {
-    for (iX = 0; iX < iWidth; iX++)
-    {                                  /* calculate the distances */
-      if (*pTempsrc1 == *pTempsrc2)
-        *pTempdst = *pTempsrc1;
-      else
-        *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
-                                               (mng_int32)(*pTempsrc1) ) + iM) /
-                                   (iM * 2) ) + (mng_int32)(*pTempsrc1) );
-
-      pTempdst++;
-      pTempsrc1++;
-      pTempsrc2++;
-    }
-  }
-  else
-  {                                    /* just repeat the entire line */
-    MNG_COPY (pTempdst, pTempsrc1, iWidth);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_G8_Y2, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_g8_y3 (mng_datap  pData,
-                               mng_int32  iS,
-                               mng_int32  iM,
-                               mng_uint32 iWidth,
-                               mng_uint8p pSrcline1,
-                               mng_uint8p pSrcline2,
-                               mng_uint8p pDstline)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_G8_Y3, MNG_LC_START);
-#endif
-
-  if (pSrcline2)                       /* do we have a second line ? */
-  {
-    if (iS < (iM+1) / 2)               /* top half ? */
-      MNG_COPY (pDstline, pSrcline1, iWidth)
-    else
-      MNG_COPY (pDstline, pSrcline2, iWidth);
-  }
-  else
-  {                                    /* just repeat the entire line */
-    MNG_COPY (pDstline, pSrcline1, iWidth);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_G8_Y3, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_NO_GRAY_SUPPORT */
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_rgb8_y1 (mng_datap  pData,
-                                 mng_int32  iS,
-                                 mng_int32  iM,
-                                 mng_uint32 iWidth,
-                                 mng_uint8p pSrcline1,
-                                 mng_uint8p pSrcline2,
-                                 mng_uint8p pDstline)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB8_Y1, MNG_LC_START);
-#endif
-
-  MNG_COPY (pDstline, pSrcline1, iWidth * 3);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB8_Y1, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_rgb8_y2 (mng_datap  pData,
-                                 mng_int32  iS,
-                                 mng_int32  iM,
-                                 mng_uint32 iWidth,
-                                 mng_uint8p pSrcline1,
-                                 mng_uint8p pSrcline2,
-                                 mng_uint8p pDstline)
-{
-  mng_uint32 iX;
-  mng_uint8p pTempsrc1;
-  mng_uint8p pTempsrc2;
-  mng_uint8p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB8_Y2, MNG_LC_START);
-#endif
-
-  pTempsrc1 = pSrcline1;               /* initialize pixel-loop */
-  pTempsrc2 = pSrcline2;
-  pTempdst  = pDstline;
-
-  if (pTempsrc2)                       /* do we have a second line ? */
-  {
-    for (iX = 0; iX < iWidth; iX++)
-    {                                  /* calculate the distances */
-      if (*pTempsrc1 == *pTempsrc2)
-        *pTempdst = *pTempsrc1;
-      else
-        *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
-                                               (mng_int32)(*pTempsrc1) ) + iM) /
-                                   (iM * 2) ) + (mng_int32)(*pTempsrc1) );
-
-      pTempdst++;
-      pTempsrc1++;
-      pTempsrc2++;
-
-      if (*pTempsrc1 == *pTempsrc2)
-        *pTempdst = *pTempsrc1;
-      else
-        *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
-                                               (mng_int32)(*pTempsrc1) ) + iM) /
-                                   (iM * 2) ) + (mng_int32)(*pTempsrc1) );
-
-      pTempdst++;
-      pTempsrc1++;
-      pTempsrc2++;
-
-      if (*pTempsrc1 == *pTempsrc2)
-        *pTempdst = *pTempsrc1;
-      else
-        *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
-                                               (mng_int32)(*pTempsrc1) ) + iM) /
-                                   (iM * 2) ) + (mng_int32)(*pTempsrc1) );
-
-      pTempdst++;
-      pTempsrc1++;
-      pTempsrc2++;
-    }
-  }
-  else
-  {                                    /* just repeat the entire line */
-    MNG_COPY (pTempdst, pTempsrc1, iWidth * 3);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB8_Y2, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_rgb8_y3 (mng_datap  pData,
-                                 mng_int32  iS,
-                                 mng_int32  iM,
-                                 mng_uint32 iWidth,
-                                 mng_uint8p pSrcline1,
-                                 mng_uint8p pSrcline2,
-                                 mng_uint8p pDstline)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB8_Y3, MNG_LC_START);
-#endif
-
-  if (pSrcline2)                       /* do we have a second line ? */
-  {
-    if (iS < (iM+1) / 2)               /* top half ? */
-      MNG_COPY (pDstline, pSrcline1, iWidth * 3)
-    else
-      MNG_COPY (pDstline, pSrcline2, iWidth * 3);
-  }
-  else
-  {                                    /* just repeat the entire line */
-    MNG_COPY (pDstline, pSrcline1, iWidth * 3);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB8_Y3, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_GRAY_SUPPORT
-mng_retcode mng_magnify_ga8_y1 (mng_datap  pData,
-                                mng_int32  iS,
-                                mng_int32  iM,
-                                mng_uint32 iWidth,
-                                mng_uint8p pSrcline1,
-                                mng_uint8p pSrcline2,
-                                mng_uint8p pDstline)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_Y1, MNG_LC_START);
-#endif
-
-  MNG_COPY (pDstline, pSrcline1, iWidth << 1);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_Y1, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_ga8_y2 (mng_datap  pData,
-                                mng_int32  iS,
-                                mng_int32  iM,
-                                mng_uint32 iWidth,
-                                mng_uint8p pSrcline1,
-                                mng_uint8p pSrcline2,
-                                mng_uint8p pDstline)
-{
-  mng_uint32 iX;
-  mng_uint8p pTempsrc1;
-  mng_uint8p pTempsrc2;
-  mng_uint8p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_Y2, MNG_LC_START);
-#endif
-
-  pTempsrc1 = pSrcline1;               /* initialize pixel-loop */
-  pTempsrc2 = pSrcline2;
-  pTempdst  = pDstline;
-
-  if (pTempsrc2)                       /* do we have a second line ? */
-  {
-    for (iX = 0; iX < iWidth; iX++)
-    {                                  /* calculate the distances */
-      if (*pTempsrc1 == *pTempsrc2)
-        *pTempdst = *pTempsrc1;
-      else
-        *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
-                                               (mng_int32)(*pTempsrc1) ) + iM) /
-                                   (iM * 2) ) + (mng_int32)(*pTempsrc1) );
-
-      pTempdst++;
-      pTempsrc1++;
-      pTempsrc2++;
-
-      if (*pTempsrc1 == *pTempsrc2)
-        *pTempdst = *pTempsrc1;
-      else
-        *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
-                                               (mng_int32)(*pTempsrc1) ) + iM) /
-                                   (iM * 2) ) + (mng_int32)(*pTempsrc1) );
-
-      pTempdst++;
-      pTempsrc1++;
-      pTempsrc2++;
-    }
-  }
-  else
-  {                                    /* just repeat the entire line */
-    MNG_COPY (pTempdst, pTempsrc1, iWidth << 1);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_Y2, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_ga8_y3 (mng_datap  pData,
-                                mng_int32  iS,
-                                mng_int32  iM,
-                                mng_uint32 iWidth,
-                                mng_uint8p pSrcline1,
-                                mng_uint8p pSrcline2,
-                                mng_uint8p pDstline)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_Y3, MNG_LC_START);
-#endif
-
-  if (pSrcline2)                       /* do we have a second line ? */
-  {
-    if (iS < (iM+1) / 2)               /* top half ? */
-      MNG_COPY (pDstline, pSrcline1, iWidth << 1)
-    else
-      MNG_COPY (pDstline, pSrcline2, iWidth << 1);
-  }
-  else
-  {                                    /* just repeat the entire line */
-    MNG_COPY (pDstline, pSrcline1, iWidth << 1);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_Y2, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_ga8_y4 (mng_datap  pData,
-                                mng_int32  iS,
-                                mng_int32  iM,
-                                mng_uint32 iWidth,
-                                mng_uint8p pSrcline1,
-                                mng_uint8p pSrcline2,
-                                mng_uint8p pDstline)
-{
-  mng_uint32 iX;
-  mng_uint8p pTempsrc1;
-  mng_uint8p pTempsrc2;
-  mng_uint8p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_Y4, MNG_LC_START);
-#endif
-
-  pTempsrc1 = pSrcline1;               /* initialize pixel-loop */
-  pTempsrc2 = pSrcline2;
-  pTempdst  = pDstline;
-
-  if (pTempsrc2)                       /* do we have a second line ? */
-  {
-    if (iS < (iM+1) / 2)               /* top half ? */
-    {
-      for (iX = 0; iX < iWidth; iX++)
-      {                                /* calculate the distances */
-        if (*pTempsrc1 == *pTempsrc2)
-          *pTempdst = *pTempsrc1;
-        else
-          *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
-                                                 (mng_int32)(*pTempsrc1) ) + iM) /
-                                     (iM * 2) ) + (mng_int32)(*pTempsrc1) );
-
-        pTempdst++;
-        pTempsrc1++;
-        pTempsrc2 += 2;
-
-        *pTempdst++ = *pTempsrc1++;    /* replicate alpha from top */
-      }
-    }
-    else
-    {
-      for (iX = 0; iX < iWidth; iX++)
-      {                                /* calculate the distances */
-        if (*pTempsrc1 == *pTempsrc2)
-          *pTempdst = *pTempsrc1;
-        else
-          *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
-                                                 (mng_int32)(*pTempsrc1) ) + iM) /
-                                     (iM * 2) ) + (mng_int32)(*pTempsrc1) );
-
-        pTempdst++;
-        pTempsrc1 += 2;
-        pTempsrc2++;
-
-        *pTempdst++ = *pTempsrc2++;    /* replicate alpha from bottom */
-      }
-    }
-  }
-  else
-  {                                    /* just repeat the entire line */
-    MNG_COPY (pTempdst, pTempsrc1, iWidth << 1);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_Y4, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_ga8_y5 (mng_datap  pData,
-                                mng_int32  iS,
-                                mng_int32  iM,
-                                mng_uint32 iWidth,
-                                mng_uint8p pSrcline1,
-                                mng_uint8p pSrcline2,
-                                mng_uint8p pDstline)
-{
-  mng_uint32 iX;
-  mng_uint8p pTempsrc1;
-  mng_uint8p pTempsrc2;
-  mng_uint8p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_Y5, MNG_LC_START);
-#endif
-
-  pTempsrc1 = pSrcline1;               /* initialize pixel-loop */
-  pTempsrc2 = pSrcline2;
-  pTempdst  = pDstline;
-
-  if (pTempsrc2)                       /* do we have a second line ? */
-  {
-    if (iS < (iM+1) / 2)               /* top half ? */
-    {
-      for (iX = 0; iX < iWidth; iX++)
-      {
-        *pTempdst = *pTempsrc1;        /* replicate gray from top */
-
-        pTempdst++;
-        pTempsrc1++;
-        pTempsrc2++;
-
-        if (*pTempsrc1 == *pTempsrc2)  /* calculate the distances */
-          *pTempdst = *pTempsrc1;
-        else
-          *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
-                                                 (mng_int32)(*pTempsrc1) ) + iM) /
-                                     (iM * 2) ) + (mng_int32)(*pTempsrc1) );
-
-        pTempdst++;
-        pTempsrc1++;
-        pTempsrc2++;
-      }
-    }
-    else
-    {
-      for (iX = 0; iX < iWidth; iX++)
-      {
-        *pTempdst = *pTempsrc2;        /* replicate gray from bottom */
-
-        pTempdst++;
-        pTempsrc1++;
-        pTempsrc2++;
-
-        if (*pTempsrc1 == *pTempsrc2)  /* calculate the distances */
-          *pTempdst = *pTempsrc1;
-        else
-          *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
-                                                 (mng_int32)(*pTempsrc1) ) + iM) /
-                                     (iM * 2) ) + (mng_int32)(*pTempsrc1) );
-
-        pTempdst++;
-        pTempsrc1++;
-        pTempsrc2++;
-      }
-    }
-  }
-  else
-  {                                    /* just repeat the entire line */
-    MNG_COPY (pTempdst, pTempsrc1, iWidth << 1);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_Y5, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_NO_GRAY_SUPPORT */
-#endif /* MNG_OPTIMIZE_FOOTPRINT_MAGN */
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_rgba8_y1 (mng_datap  pData,
-                                  mng_int32  iS,
-                                  mng_int32  iM,
-                                  mng_uint32 iWidth,
-                                  mng_uint8p pSrcline1,
-                                  mng_uint8p pSrcline2,
-                                  mng_uint8p pDstline)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_Y1, MNG_LC_START);
-#endif
-
-  MNG_COPY (pDstline, pSrcline1, iWidth << 2);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_Y1, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_rgba8_y2 (mng_datap  pData,
-                                  mng_int32  iS,
-                                  mng_int32  iM,
-                                  mng_uint32 iWidth,
-                                  mng_uint8p pSrcline1,
-                                  mng_uint8p pSrcline2,
-                                  mng_uint8p pDstline)
-{
-  mng_uint32 iX;
-  mng_uint8p pTempsrc1;
-  mng_uint8p pTempsrc2;
-  mng_uint8p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_Y2, MNG_LC_START);
-#endif
-
-  pTempsrc1 = pSrcline1;               /* initialize pixel-loop */
-  pTempsrc2 = pSrcline2;
-  pTempdst  = pDstline;
-
-  if (pTempsrc2)                       /* do we have a second line ? */
-  {
-    for (iX = 0; iX < iWidth; iX++)
-    {                                  /* calculate the distances */
-      if (*pTempsrc1 == *pTempsrc2)
-        *pTempdst = *pTempsrc1;
-      else
-        *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
-                                               (mng_int32)(*pTempsrc1) ) + iM) /
-                                   (iM * 2) ) + (mng_int32)(*pTempsrc1) );
-
-      pTempdst++;
-      pTempsrc1++;
-      pTempsrc2++;
-
-      if (*pTempsrc1 == *pTempsrc2)
-        *pTempdst = *pTempsrc1;
-      else
-        *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
-                                               (mng_int32)(*pTempsrc1) ) + iM) /
-                                   (iM * 2) ) + (mng_int32)(*pTempsrc1) );
-
-      pTempdst++;
-      pTempsrc1++;
-      pTempsrc2++;
-
-      if (*pTempsrc1 == *pTempsrc2)
-        *pTempdst = *pTempsrc1;
-      else
-        *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
-                                               (mng_int32)(*pTempsrc1) ) + iM) /
-                                   (iM * 2) ) + (mng_int32)(*pTempsrc1) );
-
-      pTempdst++;
-      pTempsrc1++;
-      pTempsrc2++;
-
-      if (*pTempsrc1 == *pTempsrc2)
-        *pTempdst = *pTempsrc1;
-      else
-        *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
-                                               (mng_int32)(*pTempsrc1) ) + iM) /
-                                   (iM * 2) ) + (mng_int32)(*pTempsrc1) );
-
-      pTempdst++;
-      pTempsrc1++;
-      pTempsrc2++;
-    }
-  }
-  else
-  {                                    /* just repeat the entire line */
-    MNG_COPY (pTempdst, pTempsrc1, iWidth << 2);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_Y2, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_rgba8_y3 (mng_datap  pData,
-                                  mng_int32  iS,
-                                  mng_int32  iM,
-                                  mng_uint32 iWidth,
-                                  mng_uint8p pSrcline1,
-                                  mng_uint8p pSrcline2,
-                                  mng_uint8p pDstline)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_Y3, MNG_LC_START);
-#endif
-
-  if (pSrcline2)                       /* do we have a second line ? */
-  {
-    if (iS < (iM+1) / 2)               /* top half ? */
-      MNG_COPY (pDstline, pSrcline1, iWidth << 2)
-    else
-      MNG_COPY (pDstline, pSrcline2, iWidth << 2);
-  }
-  else
-  {                                    /* just repeat the entire line */
-    MNG_COPY (pDstline, pSrcline1, iWidth << 2);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_Y2, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_rgba8_y4 (mng_datap  pData,
-                                  mng_int32  iS,
-                                  mng_int32  iM,
-                                  mng_uint32 iWidth,
-                                  mng_uint8p pSrcline1,
-                                  mng_uint8p pSrcline2,
-                                  mng_uint8p pDstline)
-{
-  mng_uint32 iX;
-  mng_uint8p pTempsrc1;
-  mng_uint8p pTempsrc2;
-  mng_uint8p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_Y4, MNG_LC_START);
-#endif
-
-  pTempsrc1 = pSrcline1;               /* initialize pixel-loop */
-  pTempsrc2 = pSrcline2;
-  pTempdst  = pDstline;
-
-  if (pTempsrc2)                       /* do we have a second line ? */
-  {
-    if (iS < (iM+1) / 2)               /* top half ? */
-    {
-      for (iX = 0; iX < iWidth; iX++)
-      {                                /* calculate the distances */
-        if (*pTempsrc1 == *pTempsrc2)
-          *pTempdst = *pTempsrc1;
-        else
-          *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
-                                                 (mng_int32)(*pTempsrc1) ) + iM) /
-                                     (iM * 2) ) + (mng_int32)(*pTempsrc1) );
-
-        pTempdst++;
-        pTempsrc1++;
-        pTempsrc2++;
-
-        if (*pTempsrc1 == *pTempsrc2)
-          *pTempdst = *pTempsrc1;
-        else
-          *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
-                                                 (mng_int32)(*pTempsrc1) ) + iM) /
-                                     (iM * 2) ) + (mng_int32)(*pTempsrc1) );
-
-        pTempdst++;
-        pTempsrc1++;
-        pTempsrc2++;
-
-        if (*pTempsrc1 == *pTempsrc2)
-          *pTempdst = *pTempsrc1;
-        else
-          *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
-                                                 (mng_int32)(*pTempsrc1) ) + iM) /
-                                     (iM * 2) ) + (mng_int32)(*pTempsrc1) );
-
-        pTempdst++;
-        pTempsrc1++;
-        pTempsrc2 += 2;
-
-        *pTempdst++ = *pTempsrc1++;    /* replicate alpha from top */
-      }
-    }
-    else
-    {
-      for (iX = 0; iX < iWidth; iX++)
-      {                                /* calculate the distances */
-        if (*pTempsrc1 == *pTempsrc2)
-          *pTempdst = *pTempsrc1;
-        else
-          *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
-                                                 (mng_int32)(*pTempsrc1) ) + iM) /
-                                     (iM * 2) ) + (mng_int32)(*pTempsrc1) );
-
-        pTempdst++;
-        pTempsrc1++;
-        pTempsrc2++;
-
-        if (*pTempsrc1 == *pTempsrc2)
-          *pTempdst = *pTempsrc1;
-        else
-          *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
-                                                 (mng_int32)(*pTempsrc1) ) + iM) /
-                                     (iM * 2) ) + (mng_int32)(*pTempsrc1) );
-
-        pTempdst++;
-        pTempsrc1++;
-        pTempsrc2++;
-
-        if (*pTempsrc1 == *pTempsrc2)
-          *pTempdst = *pTempsrc1;
-        else
-          *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
-                                                 (mng_int32)(*pTempsrc1) ) + iM) /
-                                     (iM * 2) ) + (mng_int32)(*pTempsrc1) );
-
-        pTempdst++;
-        pTempsrc1 += 2;
-        pTempsrc2++;
-
-        *pTempdst++ = *pTempsrc2++;    /* replicate alpha from bottom */
-      }
-    }
-  }
-  else
-  {                                    /* just repeat the entire line */
-    MNG_COPY (pTempdst, pTempsrc1, iWidth << 2);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_Y4, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_rgba8_y5 (mng_datap  pData,
-                                  mng_int32  iS,
-                                  mng_int32  iM,
-                                  mng_uint32 iWidth,
-                                  mng_uint8p pSrcline1,
-                                  mng_uint8p pSrcline2,
-                                  mng_uint8p pDstline)
-{
-  mng_uint32 iX;
-  mng_uint8p pTempsrc1;
-  mng_uint8p pTempsrc2;
-  mng_uint8p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_Y5, MNG_LC_START);
-#endif
-
-  pTempsrc1 = pSrcline1;               /* initialize pixel-loop */
-  pTempsrc2 = pSrcline2;
-  pTempdst  = pDstline;
-
-  if (pTempsrc2)                       /* do we have a second line ? */
-  {
-    if (iS < (iM+1) / 2)               /* top half ? */
-    {
-      for (iX = 0; iX < iWidth; iX++)
-      {
-        *pTempdst++ = *pTempsrc1++;    /* replicate color from top */
-        *pTempdst++ = *pTempsrc1++;
-        *pTempdst++ = *pTempsrc1++;
-
-        pTempsrc2 += 3;
-
-        if (*pTempsrc1 == *pTempsrc2)  /* calculate the distances */
-          *pTempdst = *pTempsrc1;
-        else
-          *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
-                                                 (mng_int32)(*pTempsrc1) ) + iM) /
-                                     (iM * 2) ) + (mng_int32)(*pTempsrc1) );
-
-        pTempdst++;
-        pTempsrc1++;
-        pTempsrc2++;
-      }
-    }
-    else
-    {
-      for (iX = 0; iX < iWidth; iX++)
-      {
-        *pTempdst++ = *pTempsrc2++;    /* replicate color from bottom */
-        *pTempdst++ = *pTempsrc2++;
-        *pTempdst++ = *pTempsrc2++;
-
-        pTempsrc1 += 3;
-
-        if (*pTempsrc1 == *pTempsrc2)  /* calculate the distances */
-          *pTempdst = *pTempsrc1;
-        else
-          *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
-                                                 (mng_int32)(*pTempsrc1) ) + iM) /
-                                     (iM * 2) ) + (mng_int32)(*pTempsrc1) );
-
-        pTempdst++;
-        pTempsrc1++;
-        pTempsrc2++;
-      }
-    }
-  }
-  else
-  {                                    /* just repeat the entire line */
-    MNG_COPY (pTempdst, pTempsrc1, iWidth << 2);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_Y5, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_FOOTPRINT_MAGN
-#ifndef MNG_NO_16BIT_SUPPORT
-#ifndef MNG_NO_GRAY_SUPPORT
-mng_retcode mng_magnify_g16_x1 (mng_datap  pData,
-                                mng_uint16 iMX,
-                                mng_uint16 iML,
-                                mng_uint16 iMR,
-                                mng_uint32 iWidth,
-                                mng_uint8p pSrcline,
-                                mng_uint8p pDstline)
-{
-  mng_uint32  iX, iS, iM;
-  mng_uint16p pTempsrc1;
-  mng_uint16p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_G16_X1, MNG_LC_START);
-#endif
-
-  pTempsrc1 = (mng_uint16p)pSrcline;   /* initialize pixel-loop */
-  pTempdst  = (mng_uint16p)pDstline;
-
-  for (iX = 0; iX < iWidth; iX++)
-  {
-    *pTempdst = *pTempsrc1;            /* copy original source pixel */
-    pTempdst++;
-
-    if (iX == 0)                       /* first interval ? */
-      iM = iML;
-    else
-    if (iX == (iWidth - 1))            /* last interval ? */
-      iM = iMR;
-    else
-      iM = iMX;
-
-    for (iS = 1; iS < iM; iS++)        /* fill interval */
-    {
-      *pTempdst = *pTempsrc1;          /* copy original source pixel */
-      pTempdst++;
-    }
-
-    pTempsrc1++;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_G16_X1, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_g16_x2 (mng_datap  pData,
-                                mng_uint16 iMX,
-                                mng_uint16 iML,
-                                mng_uint16 iMR,
-                                mng_uint32 iWidth,
-                                mng_uint8p pSrcline,
-                                mng_uint8p pDstline)
-{
-  mng_uint32  iX;
-  mng_int32   iS, iM;
-  mng_uint16p pTempsrc1;
-  mng_uint16p pTempsrc2;
-  mng_uint16p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_G16_X2, MNG_LC_START);
-#endif
-
-  pTempsrc1 = (mng_uint16p)pSrcline;   /* initialize pixel-loop */
-  pTempdst  = (mng_uint16p)pDstline;
-
-  for (iX = 0; iX < iWidth; iX++)
-  {
-    pTempsrc2 = pTempsrc1 + 1;
-
-    *pTempdst = *pTempsrc1;            /* copy original source pixel */
-    pTempdst++;
-
-    if (iX == 0)                       /* first interval ? */
-    {
-      if (iWidth == 1)                 /* single pixel ? */
-        pTempsrc2 = MNG_NULL;
-
-      iM = iML;
-    }
-    else
-    if (iX == (iWidth - 2))            /* last interval ? */
-      iM = iMR;
-    else
-      iM = iMX;
-                                       /* fill interval ? */
-    if ((iX < iWidth - 1) || (iWidth == 1))
-    {
-      if (pTempsrc2)                   /* do we have the second pixel ? */
-      {                                /* is it same as first ? */
-        if (*pTempsrc1 == *pTempsrc2)
-        {
-          for (iS = 1; iS < iM; iS++)  /* then just repeat the first */
-          {
-            *pTempdst = *pTempsrc1;
-            pTempdst++;
-          }
-        }
-        else
-        {
-          for (iS = 1; iS < iM; iS++)  /* calculate the distances */
-          {
-            mng_put_uint16 ((mng_uint8p)pTempdst,
-                            (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2))   -
-                                                      (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
-                                          (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))          ));
-            pTempdst++;
-          }
-        }
-      }
-      else
-      {
-        for (iS = 1; iS < iM; iS++)
-        {
-          *pTempdst = *pTempsrc1;      /* repeat first source pixel */
-          pTempdst++;
-        }
-      }
-    }
-
-    pTempsrc1++;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_G16_X2, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_g16_x3 (mng_datap  pData,
-                                mng_uint16 iMX,
-                                mng_uint16 iML,
-                                mng_uint16 iMR,
-                                mng_uint32 iWidth,
-                                mng_uint8p pSrcline,
-                                mng_uint8p pDstline)
-{
-  mng_uint32  iX;
-  mng_int32   iS, iM, iH;
-  mng_uint16p pTempsrc1;
-  mng_uint16p pTempsrc2;
-  mng_uint16p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_G16_X3, MNG_LC_START);
-#endif
-
-  pTempsrc1 = (mng_uint16p)pSrcline;   /* initialize pixel-loop */
-  pTempdst  = (mng_uint16p)pDstline;
-
-  for (iX = 0; iX < iWidth; iX++)
-  {
-    pTempsrc2 = pTempsrc1 + 1;
-
-    *pTempdst = *pTempsrc1;            /* copy original source pixel */
-    pTempdst++;
-
-    if (iX == 0)                       /* first interval ? */
-    {
-      if (iWidth == 1)                 /* single pixel ? */
-        pTempsrc2 = MNG_NULL;
-
-      iM = iML;
-    }
-    else
-    if (iX == (iWidth - 2))            /* last interval ? */
-      iM = iMR;
-    else
-      iM = iMX;
-                                       /* fill interval ? */
-    if ((iX < iWidth - 1) || (iWidth == 1))
-    {
-      if (pTempsrc2)                   /* do we have the second pixel ? */
-      {                                /* is it same as first ? */
-        if (*pTempsrc1 == *pTempsrc2)
-        {
-          for (iS = 1; iS < iM; iS++)  /* then just repeat the first */
-          {
-            *pTempdst = *pTempsrc1;
-            pTempdst++;
-          }
-        }
-        else
-        {
-          iH = (iM+1) / 2;             /* calculate halfway point */
-
-          for (iS = 1; iS < iH; iS++)  /* replicate first half */
-          {
-            *pTempdst = *pTempsrc1;
-            pTempdst++;
-          }
-
-          for (iS = iH; iS < iM; iS++) /* replicate second half */
-          {
-            *pTempdst = *pTempsrc2;
-            pTempdst++;
-          }
-        }
-      }
-      else
-      {
-        for (iS = 1; iS < iM; iS++)
-        {
-          *pTempdst = *pTempsrc1;      /* repeat first source pixel */
-          pTempdst++;
-        }
-      }
-    }
-
-    pTempsrc1++;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_G16_X3, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_NO_GRAY_SUPPORT */
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_rgb16_x1 (mng_datap  pData,
-                                  mng_uint16 iMX,
-                                  mng_uint16 iML,
-                                  mng_uint16 iMR,
-                                  mng_uint32 iWidth,
-                                  mng_uint8p pSrcline,
-                                  mng_uint8p pDstline)
-{
-  mng_uint32  iX, iS, iM;
-  mng_uint16p pTempsrc1;
-  mng_uint16p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB16_X1, MNG_LC_START);
-#endif
-
-  pTempsrc1 = (mng_uint16p)pSrcline;   /* initialize pixel-loop */
-  pTempdst  = (mng_uint16p)pDstline;
-
-  for (iX = 0; iX < iWidth; iX++)
-  {
-    *pTempdst = *pTempsrc1;            /* copy original source pixel */
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+1);
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+2);
-    pTempdst++;
-
-    if (iX == 0)                       /* first interval ? */
-      iM = iML;
-    else
-    if (iX == (iWidth - 1))            /* last interval ? */
-      iM = iMR;
-    else
-      iM = iMX;
-
-    for (iS = 1; iS < iM; iS++)        /* fill interval */
-    {
-      *pTempdst = *pTempsrc1;          /* copy original source pixel */
-      pTempdst++;
-      *pTempdst = *(pTempsrc1+1);
-      pTempdst++;
-      *pTempdst = *(pTempsrc1+2);
-      pTempdst++;
-    }
-
-    pTempsrc1 += 3;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB16_X1, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_rgb16_x2 (mng_datap  pData,
-                                  mng_uint16 iMX,
-                                  mng_uint16 iML,
-                                  mng_uint16 iMR,
-                                  mng_uint32 iWidth,
-                                  mng_uint8p pSrcline,
-                                  mng_uint8p pDstline)
-{
-  mng_uint32  iX;
-  mng_int32   iS, iM;
-  mng_uint16p pTempsrc1;
-  mng_uint16p pTempsrc2;
-  mng_uint16p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB16_X2, MNG_LC_START);
-#endif
-
-  pTempsrc1 = (mng_uint16p)pSrcline;   /* initialize pixel-loop */
-  pTempdst  = (mng_uint16p)pDstline;
-
-  for (iX = 0; iX < iWidth; iX++)
-  {
-    pTempsrc2 = pTempsrc1 + 3;
-
-    *pTempdst = *pTempsrc1;            /* copy original source pixel */
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+1);
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+2);
-    pTempdst++;
-
-    if (iX == 0)                       /* first interval ? */
-    {
-      if (iWidth == 1)                 /* single pixel ? */
-        pTempsrc2 = MNG_NULL;
-
-      iM = (mng_int32)iML;
-    }
-    else
-    if (iX == (iWidth - 2))            /* last interval ? */
-      iM = (mng_int32)iMR;
-    else
-      iM = (mng_int32)iMX;
-                                       /* fill interval ? */
-    if ((iX < iWidth - 1) || (iWidth == 1))
-    {
-      if (pTempsrc2)                   /* do we have the second pixel ? */
-      {
-        for (iS = 1; iS < iM; iS++)
-        {
-          if (*pTempsrc1 == *pTempsrc2)
-            *pTempdst = *pTempsrc1;    /* just repeat the first */
-          else                         /* calculate the distance */
-            mng_put_uint16 ((mng_uint8p)pTempdst,
-                            (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
-                                                      (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
-                                          (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
-
-          pTempdst++;
-
-          if (*(pTempsrc1+1) == *(pTempsrc2+1))
-            *pTempdst = *(pTempsrc1+1);
-          else
-            mng_put_uint16 ((mng_uint8p)pTempdst,
-                            (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc2+1))) -
-                                                      (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+1))) ) + iM) /
-                                          (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+1)))         ) );
-
-          pTempdst++;
-
-          if (*(pTempsrc1+2) == *(pTempsrc2+2))
-            *pTempdst = *(pTempsrc1+2);
-          else
-            mng_put_uint16 ((mng_uint8p)pTempdst,
-                            (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc2+2))) -
-                                                      (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+2))) ) + iM) /
-                                          (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+2)))         ) );
-
-          pTempdst++;
-        }
-      }
-      else
-      {
-        for (iS = 1; iS < iM; iS++)
-        {
-          *pTempdst = *pTempsrc1;      /* repeat first source pixel */
-          pTempdst++;
-          *pTempdst = *(pTempsrc1+1);
-          pTempdst++;
-          *pTempdst = *(pTempsrc1+2);
-          pTempdst++;
-        }
-      }
-    }
-
-    pTempsrc1 += 3;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB16_X2, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_rgb16_x3 (mng_datap  pData,
-                                  mng_uint16 iMX,
-                                  mng_uint16 iML,
-                                  mng_uint16 iMR,
-                                  mng_uint32 iWidth,
-                                  mng_uint8p pSrcline,
-                                  mng_uint8p pDstline)
-{
-  mng_uint32  iX;
-  mng_int32   iS, iM, iH;
-  mng_uint16p pTempsrc1;
-  mng_uint16p pTempsrc2;
-  mng_uint16p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB16_X3, MNG_LC_START);
-#endif
-
-  pTempsrc1 = (mng_uint16p)pSrcline;   /* initialize pixel-loop */
-  pTempdst  = (mng_uint16p)pDstline;
-
-  for (iX = 0; iX < iWidth; iX++)
-  {
-    pTempsrc2 = pTempsrc1 + 3;
-
-    *pTempdst = *pTempsrc1;            /* copy original source pixel */
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+1);
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+2);
-    pTempdst++;
-
-    if (iX == 0)                       /* first interval ? */
-    {
-      if (iWidth == 1)                 /* single pixel ? */
-        pTempsrc2 = MNG_NULL;
-
-      iM = (mng_int32)iML;
-    }
-    else
-    if (iX == (iWidth - 2))            /* last interval ? */
-      iM = (mng_int32)iMR;
-    else
-      iM = (mng_int32)iMX;
-                                       /* fill interval ? */
-    if ((iX < iWidth - 1) || (iWidth == 1))
-    {
-      if (pTempsrc2)                   /* do we have the second pixel ? */
-      {
-        iH = (iM+1) / 2;               /* calculate halfway point */
-
-        for (iS = 1; iS < iH; iS++)    /* replicate first half */
-        {
-          *pTempdst     = *pTempsrc1;
-          *(pTempdst+1) = *(pTempsrc1+1);
-          *(pTempdst+2) = *(pTempsrc1+2);
-
-          pTempdst += 3;
-        }
-
-        for (iS = iH; iS < iM; iS++)    /* replicate second half */
-        {
-          *pTempdst     = *pTempsrc2;
-          *(pTempdst+1) = *(pTempsrc2+1);
-          *(pTempdst+2) = *(pTempsrc2+2);
-
-          pTempdst += 3;
-        }
-      }
-      else
-      {
-        for (iS = 1; iS < iM; iS++)
-        {
-          *pTempdst = *pTempsrc1;      /* repeat first source pixel */
-          pTempdst++;
-          *pTempdst = *(pTempsrc1+1);
-          pTempdst++;
-          *pTempdst = *(pTempsrc1+2);
-          pTempdst++;
-        }
-      }
-    }
-
-    pTempsrc1 += 3;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB16_X3, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_GRAY_SUPPORT
-mng_retcode mng_magnify_ga16_x1 (mng_datap  pData,
-                                 mng_uint16 iMX,
-                                 mng_uint16 iML,
-                                 mng_uint16 iMR,
-                                 mng_uint32 iWidth,
-                                 mng_uint8p pSrcline,
-                                 mng_uint8p pDstline)
-{
-  mng_uint32  iX, iS, iM;
-  mng_uint16p pTempsrc1;
-  mng_uint16p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_GA16_X1, MNG_LC_START);
-#endif
-
-  pTempsrc1 = (mng_uint16p) pSrcline;  /* initialize pixel-loop */
-  pTempdst  = (mng_uint16p)pDstline;
-
-  for (iX = 0; iX < iWidth; iX++)
-  {
-    *pTempdst = *pTempsrc1;            /* copy original source pixel */
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+1);
-    pTempdst++;
-
-    if (iX == 0)                       /* first interval ? */
-      iM = iML;
-    else
-    if (iX == (iWidth - 1))            /* last interval ? */
-      iM = iMR;
-    else
-      iM = iMX;
-
-    for (iS = 1; iS < iM; iS++)        /* fill interval */
-    {
-      *pTempdst = *pTempsrc1;          /* copy original source pixel */
-      pTempdst++;
-      *pTempdst = *(pTempsrc1+1);
-      pTempdst++;
-    }
-
-    pTempsrc1 += 2;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_GA16_X1, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_ga16_x2 (mng_datap  pData,
-                                 mng_uint16 iMX,
-                                 mng_uint16 iML,
-                                 mng_uint16 iMR,
-                                 mng_uint32 iWidth,
-                                 mng_uint8p pSrcline,
-                                 mng_uint8p pDstline)
-{
-  mng_uint32  iX;
-  mng_int32   iS, iM;
-  mng_uint16p pTempsrc1;
-  mng_uint16p pTempsrc2;
-  mng_uint16p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_GA16_X2, MNG_LC_START);
-#endif
-
-  pTempsrc1 = (mng_uint16p)pSrcline;   /* initialize pixel-loop */
-  pTempdst  = (mng_uint16p)pDstline;
-
-  for (iX = 0; iX < iWidth; iX++)
-  {
-    pTempsrc2 = pTempsrc1 + 2;
-
-    *pTempdst = *pTempsrc1;            /* copy original source pixel */
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+1);
-    pTempdst++;
-
-    if (iX == 0)                       /* first interval ? */
-    {
-      if (iWidth == 1)                 /* single pixel ? */
-        pTempsrc2 = MNG_NULL;
-
-      iM = iML;
-    }
-    else
-    if (iX == (iWidth - 2))            /* last interval ? */
-      iM = iMR;
-    else
-      iM = iMX;
-                                       /* fill interval ? */
-    if ((iX < iWidth - 1) || (iWidth == 1))
-    {
-      if (pTempsrc2)                   /* do we have the second pixel ? */
-      {
-        for (iS = 1; iS < iM; iS++)
-        {
-          if (*pTempsrc1 == *pTempsrc2)
-            *pTempdst = *pTempsrc1;    /* just repeat the first */
-          else                         /* calculate the distance */
-            mng_put_uint16 ((mng_uint8p)pTempdst,
-                            (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
-                                                      (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
-                                          (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
-
-          pTempdst++;
-
-          if (*(pTempsrc1+1) == *(pTempsrc2+1))
-            *pTempdst = *(pTempsrc1+1);
-          else
-            mng_put_uint16 ((mng_uint8p)pTempdst,
-                            (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc2+1))) -
-                                                      (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+1))) ) + iM) /
-                                          (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+1)))         ) );
-
-          pTempdst++;
-        }
-      }
-      else
-      {
-        for (iS = 1; iS < iM; iS++)
-        {
-          *pTempdst = *pTempsrc1;      /* repeat first source pixel */
-          pTempdst++;
-          *pTempdst = *(pTempsrc1+1);
-          pTempdst++;
-        }
-      }
-    }
-
-    pTempsrc1 += 2;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_GA16_X2, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_ga16_x3 (mng_datap  pData,
-                                 mng_uint16 iMX,
-                                 mng_uint16 iML,
-                                 mng_uint16 iMR,
-                                 mng_uint32 iWidth,
-                                 mng_uint8p pSrcline,
-                                 mng_uint8p pDstline)
-{
-  mng_uint32  iX;
-  mng_int32   iS, iM, iH;
-  mng_uint16p pTempsrc1;
-  mng_uint16p pTempsrc2;
-  mng_uint16p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_GA16_X3, MNG_LC_START);
-#endif
-
-  pTempsrc1 = (mng_uint16p)pSrcline;   /* initialize pixel-loop */
-  pTempdst  = (mng_uint16p)pDstline;
-
-  for (iX = 0; iX < iWidth; iX++)
-  {
-    pTempsrc2 = pTempsrc1 + 2;
-
-    *pTempdst = *pTempsrc1;            /* copy original source pixel */
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+1);
-    pTempdst++;
-
-    if (iX == 0)                       /* first interval ? */
-    {
-      if (iWidth == 1)                 /* single pixel ? */
-        pTempsrc2 = MNG_NULL;
-
-      iM = iML;
-    }
-    else
-    if (iX == (iWidth - 2))            /* last interval ? */
-      iM = iMR;
-    else
-      iM = iMX;
-                                       /* fill interval ? */
-    if ((iX < iWidth - 1) || (iWidth == 1))
-    {
-      if (pTempsrc2)                   /* do we have the second pixel ? */
-      {
-        iH = (iM+1) / 2;               /* calculate halfway point */
-
-        for (iS = 1; iS < iH; iS++)    /* replicate first half */
-        {
-          *pTempdst     = *pTempsrc1;
-          *(pTempdst+1) = *(pTempsrc1+1);
-
-          pTempdst += 2;
-        }
-
-        for (iS = iH; iS < iM; iS++)   /* replicate second half */
-        {
-          *pTempdst     = *pTempsrc2;
-          *(pTempdst+1) = *(pTempsrc2+1);
-
-          pTempdst += 2;
-        }
-      }
-      else
-      {
-        for (iS = 1; iS < iM; iS++)
-        {
-          *pTempdst = *pTempsrc1;      /* repeat first source pixel */
-          pTempdst++;
-          *pTempdst = *(pTempsrc1+1);
-          pTempdst++;
-        }
-      }
-    }
-
-    pTempsrc1 += 2;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_GA16_X3, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_ga16_x4 (mng_datap  pData,
-                                 mng_uint16 iMX,
-                                 mng_uint16 iML,
-                                 mng_uint16 iMR,
-                                 mng_uint32 iWidth,
-                                 mng_uint8p pSrcline,
-                                 mng_uint8p pDstline)
-{
-  mng_uint32  iX;
-  mng_int32   iS, iM, iH;
-  mng_uint16p pTempsrc1;
-  mng_uint16p pTempsrc2;
-  mng_uint16p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_GA16_X4, MNG_LC_START);
-#endif
-
-  pTempsrc1 = (mng_uint16p)pSrcline;   /* initialize pixel-loop */
-  pTempdst  = (mng_uint16p)pDstline;
-
-  for (iX = 0; iX < iWidth; iX++)
-  {
-    pTempsrc2 = pTempsrc1 + 2;
-
-    *pTempdst = *pTempsrc1;            /* copy original source pixel */
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+1);
-    pTempdst++;
-
-    if (iX == 0)                       /* first interval ? */
-    {
-      if (iWidth == 1)                 /* single pixel ? */
-        pTempsrc2 = MNG_NULL;
-
-      iM = iML;
-    }
-    else
-    if (iX == (iWidth - 2))            /* last interval ? */
-      iM = iMR;
-    else
-      iM = iMX;
-                                       /* fill interval ? */
-    if ((iX < iWidth - 1) || (iWidth == 1))
-    {
-      if (pTempsrc2)                   /* do we have the second pixel ? */
-      {
-        iH = (iM+1) / 2;               /* calculate halfway point */
-
-        for (iS = 1; iS < iH; iS++)    /* first half */
-        {
-          if (*pTempsrc1 == *pTempsrc2)
-            *pTempdst = *pTempsrc1;    /* just repeat the first */
-          else                         /* calculate the distance */
-            mng_put_uint16 ((mng_uint8p)pTempdst,
-                            (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
-                                                      (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
-                                          (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
-
-          pTempdst++;
-
-          *pTempdst = *(pTempsrc1+1);  /* replicate alpha from left */
-
-          pTempdst++;
-        }
-
-        for (iS = iH; iS < iM; iS++)   /* second half */
-        {
-          if (*pTempsrc1 == *pTempsrc2)
-            *pTempdst = *pTempsrc1;    /* just repeat the first */
-          else                         /* calculate the distance */
-            mng_put_uint16 ((mng_uint8p)pTempdst,
-                            (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
-                                                      (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
-                                          (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
-
-          pTempdst++;
-
-          *pTempdst = *(pTempsrc2+1);  /* replicate alpha from right */
-
-          pTempdst++;
-        }
-      }
-      else
-      {
-        for (iS = 1; iS < iM; iS++)
-        {
-          *pTempdst = *pTempsrc1;      /* repeat first source pixel */
-          pTempdst++;
-          *pTempdst = *(pTempsrc1+1);
-          pTempdst++;
-        }
-      }
-    }
-
-    pTempsrc1 += 2;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_GA16_X4, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_ga16_x5 (mng_datap  pData,
-                                 mng_uint16 iMX,
-                                 mng_uint16 iML,
-                                 mng_uint16 iMR,
-                                 mng_uint32 iWidth,
-                                 mng_uint8p pSrcline,
-                                 mng_uint8p pDstline)
-{
-  mng_uint32  iX;
-  mng_int32   iS, iM, iH;
-  mng_uint16p pTempsrc1;
-  mng_uint16p pTempsrc2;
-  mng_uint16p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_GA16_X5, MNG_LC_START);
-#endif
-
-  pTempsrc1 = (mng_uint16p)pSrcline;   /* initialize pixel-loop */
-  pTempdst  = (mng_uint16p)pDstline;
-
-  for (iX = 0; iX < iWidth; iX++)
-  {
-    pTempsrc2 = pTempsrc1 + 2;
-
-    *pTempdst = *pTempsrc1;            /* copy original source pixel */
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+1);
-    pTempdst++;
-
-    if (iX == 0)                       /* first interval ? */
-    {
-      if (iWidth == 1)                 /* single pixel ? */
-        pTempsrc2 = MNG_NULL;
-
-      iM = iML;
-    }
-    else
-    if (iX == (iWidth - 2))            /* last interval ? */
-      iM = iMR;
-    else
-      iM = iMX;
-                                       /* fill interval ? */
-    if ((iX < iWidth - 1) || (iWidth == 1))
-    {
-      if (pTempsrc2)                   /* do we have the second pixel ? */
-      {
-        iH = (iM+1) / 2;               /* calculate halfway point */
-
-        for (iS = 1; iS < iH; iS++)    /* first half */
-        {
-          *pTempdst = *pTempsrc1;      /* replicate gray from left */
-
-          pTempdst++;
-
-          if (*(pTempsrc1+1) == *(pTempsrc2+1))
-            *pTempdst = *(pTempsrc1+1);/* just repeat the first */
-          else                         /* calculate the distance */
-            mng_put_uint16 ((mng_uint8p)pTempdst,
-                            (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc2+1))) -
-                                                      (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+1))) ) + iM) /
-                                          (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+1)))         ) );
-
-          pTempdst++;
-        }
-
-        for (iS = iH; iS < iM; iS++)   /* second half */
-        {
-          *pTempdst = *pTempsrc2;      /* replicate gray from right */
-
-          pTempdst++;
-
-          if (*(pTempsrc1+1) == *(pTempsrc2+1))
-            *pTempdst = *(pTempsrc1+1);/* just repeat the first */
-          else                         /* calculate the distance */
-            mng_put_uint16 ((mng_uint8p)pTempdst,
-                            (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc2+1))) -
-                                                      (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+1))) ) + iM) /
-                                          (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+1)))         ) );
-
-          pTempdst++;
-        }
-      }
-      else
-      {
-        for (iS = 1; iS < iM; iS++)
-        {
-          *pTempdst = *pTempsrc1;      /* repeat first source pixel */
-          pTempdst++;
-          *pTempdst = *(pTempsrc1+1);
-          pTempdst++;
-        }
-      }
-    }
-
-    pTempsrc1 += 2;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_GA16_X5, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_NO_GRAY_SUPPORT */
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_rgba16_x1 (mng_datap  pData,
-                                   mng_uint16 iMX,
-                                   mng_uint16 iML,
-                                   mng_uint16 iMR,
-                                   mng_uint32 iWidth,
-                                   mng_uint8p pSrcline,
-                                   mng_uint8p pDstline)
-{
-  mng_uint32  iX, iS, iM;
-  mng_uint16p pTempsrc1;
-  mng_uint16p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA16_X1, MNG_LC_START);
-#endif
-
-  pTempsrc1 = (mng_uint16p)pSrcline;   /* initialize pixel-loop */
-  pTempdst  = (mng_uint16p)pDstline;
-
-  for (iX = 0; iX < iWidth; iX++)
-  {
-    *pTempdst = *pTempsrc1;            /* copy original source pixel */
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+1);
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+2);
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+3);
-    pTempdst++;
-
-    if (iX == 0)                       /* first interval ? */
-      iM = iML;
-    else
-    if (iX == (iWidth - 1))            /* last interval ? */
-      iM = iMR;
-    else
-      iM = iMX;
-
-    for (iS = 1; iS < iM; iS++)        /* fill interval */
-    {
-      *pTempdst = *pTempsrc1;          /* copy original source pixel */
-      pTempdst++;
-      *pTempdst = *(pTempsrc1+1);
-      pTempdst++;
-      *pTempdst = *(pTempsrc1+2);
-      pTempdst++;
-      *pTempdst = *(pTempsrc1+3);
-      pTempdst++;
-    }
-
-    pTempsrc1 += 4;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA16_X1, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_rgba16_x2 (mng_datap  pData,
-                                   mng_uint16 iMX,
-                                   mng_uint16 iML,
-                                   mng_uint16 iMR,
-                                   mng_uint32 iWidth,
-                                   mng_uint8p pSrcline,
-                                   mng_uint8p pDstline)
-{
-  mng_uint32  iX;
-  mng_int32   iS, iM;
-  mng_uint16p pTempsrc1;
-  mng_uint16p pTempsrc2;
-  mng_uint16p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA16_X2, MNG_LC_START);
-#endif
-
-  pTempsrc1 = (mng_uint16p)pSrcline;   /* initialize pixel-loop */
-  pTempdst  = (mng_uint16p)pDstline;
-
-  for (iX = 0; iX < iWidth; iX++)
-  {
-    pTempsrc2 = pTempsrc1 + 4;
-
-    *pTempdst = *pTempsrc1;            /* copy original source pixel */
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+1);
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+2);
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+3);
-    pTempdst++;
-
-    if (iX == 0)                       /* first interval ? */
-    {
-      if (iWidth == 1)                 /* single pixel ? */
-        pTempsrc2 = MNG_NULL;
-
-      iM = (mng_int32)iML;
-    }
-    else
-    if (iX == (iWidth - 2))            /* last interval ? */
-      iM = (mng_int32)iMR;
-    else
-      iM = (mng_int32)iMX;
-                                       /* fill interval ? */
-    if ((iX < iWidth - 1) || (iWidth == 1))
-    {
-      if (pTempsrc2)                   /* do we have the second pixel ? */
-      {
-        for (iS = 1; iS < iM; iS++)
-        {
-          if (*pTempsrc1 == *pTempsrc2)
-            *pTempdst = *pTempsrc1;    /* just repeat the first */
-          else                         /* calculate the distance */
-            mng_put_uint16 ((mng_uint8p)pTempdst,
-                            (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
-                                                      (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
-                                          (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
-
-          pTempdst++;
-
-          if (*(pTempsrc1+1) == *(pTempsrc2+1))
-            *pTempdst = *(pTempsrc1+1);
-          else
-            mng_put_uint16 ((mng_uint8p)pTempdst,
-                            (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc2+1))) -
-                                                      (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+1))) ) + iM) /
-                                          (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+1)))         ) );
-
-          pTempdst++;
-
-          if (*(pTempsrc1+2) == *(pTempsrc2+2))
-            *pTempdst = *(pTempsrc1+2);
-          else
-            mng_put_uint16 ((mng_uint8p)pTempdst,
-                            (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc2+2))) -
-                                                      (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+2))) ) + iM) /
-                                          (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+2)))         ) );
-
-          pTempdst++;
-
-          if (*(pTempsrc1+3) == *(pTempsrc2+3))
-            *pTempdst = *(pTempsrc1+3);
-          else
-            mng_put_uint16 ((mng_uint8p)pTempdst,
-                            (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc2+3))) -
-                                                      (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+3))) ) + iM) /
-                                          (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+3)))         ) );
-
-          pTempdst++;
-        }
-      }
-      else
-      {
-        for (iS = 1; iS < iM; iS++)
-        {
-          *pTempdst = *pTempsrc1;      /* repeat first source pixel */
-          pTempdst++;
-          *pTempdst = *(pTempsrc1+1);
-          pTempdst++;
-          *pTempdst = *(pTempsrc1+2);
-          pTempdst++;
-          *pTempdst = *(pTempsrc1+3);
-          pTempdst++;
-        }
-      }
-    }
-
-    pTempsrc1 += 4;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA16_X2, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_rgba16_x3 (mng_datap  pData,
-                                   mng_uint16 iMX,
-                                   mng_uint16 iML,
-                                   mng_uint16 iMR,
-                                   mng_uint32 iWidth,
-                                   mng_uint8p pSrcline,
-                                   mng_uint8p pDstline)
-{
-  mng_uint32  iX;
-  mng_int32   iS, iM, iH;
-  mng_uint16p pTempsrc1;
-  mng_uint16p pTempsrc2;
-  mng_uint16p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA16_X3, MNG_LC_START);
-#endif
-
-  pTempsrc1 = (mng_uint16p)pSrcline;   /* initialize pixel-loop */
-  pTempdst  = (mng_uint16p)pDstline;
-
-  for (iX = 0; iX < iWidth; iX++)
-  {
-    pTempsrc2 = pTempsrc1 + 4;
-
-    *pTempdst = *pTempsrc1;            /* copy original source pixel */
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+1);
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+2);
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+3);
-    pTempdst++;
-
-    if (iX == 0)                       /* first interval ? */
-    {
-      if (iWidth == 1)                 /* single pixel ? */
-        pTempsrc2 = MNG_NULL;
-
-      iM = (mng_int32)iML;
-    }
-    else
-    if (iX == (iWidth - 2))            /* last interval ? */
-      iM = (mng_int32)iMR;
-    else
-      iM = (mng_int32)iMX;
-                                       /* fill interval ? */
-    if ((iX < iWidth - 1) || (iWidth == 1))
-    {
-      if (pTempsrc2)                   /* do we have the second pixel ? */
-      {
-        iH = (iM+1) / 2;               /* calculate halfway point */
-
-        for (iS = 1; iS < iH; iS++)    /* replicate first half */
-        {
-          *pTempdst     = *pTempsrc1;
-          *(pTempdst+1) = *(pTempsrc1+1);
-          *(pTempdst+2) = *(pTempsrc1+2);
-          *(pTempdst+3) = *(pTempsrc1+3);
-
-          pTempdst += 4;
-        }
-
-        for (iS = iH; iS < iM; iS++)   /* replicate second half */
-        {
-          *pTempdst     = *pTempsrc2;
-          *(pTempdst+1) = *(pTempsrc2+1);
-          *(pTempdst+2) = *(pTempsrc2+2);
-          *(pTempdst+3) = *(pTempsrc2+3);
-
-          pTempdst += 4;
-        }
-      }
-      else
-      {
-        for (iS = 1; iS < iM; iS++)
-        {
-          *pTempdst = *pTempsrc1;      /* repeat first source pixel */
-          pTempdst++;
-          *pTempdst = *(pTempsrc1+1);
-          pTempdst++;
-          *pTempdst = *(pTempsrc1+2);
-          pTempdst++;
-          *pTempdst = *(pTempsrc1+3);
-          pTempdst++;
-        }
-      }
-    }
-
-    pTempsrc1 += 4;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA16_X3, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_rgba16_x4 (mng_datap  pData,
-                                   mng_uint16 iMX,
-                                   mng_uint16 iML,
-                                   mng_uint16 iMR,
-                                   mng_uint32 iWidth,
-                                   mng_uint8p pSrcline,
-                                   mng_uint8p pDstline)
-{
-  mng_uint32  iX;
-  mng_int32   iS, iM, iH;
-  mng_uint16p pTempsrc1;
-  mng_uint16p pTempsrc2;
-  mng_uint16p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA16_X4, MNG_LC_START);
-#endif
-
-  pTempsrc1 = (mng_uint16p)pSrcline;   /* initialize pixel-loop */
-  pTempdst  = (mng_uint16p)pDstline;
-
-  for (iX = 0; iX < iWidth; iX++)
-  {
-    pTempsrc2 = pTempsrc1 + 4;
-
-    *pTempdst = *pTempsrc1;            /* copy original source pixel */
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+1);
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+2);
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+3);
-    pTempdst++;
-
-    if (iX == 0)                       /* first interval ? */
-    {
-      if (iWidth == 1)                 /* single pixel ? */
-        pTempsrc2 = MNG_NULL;
-
-      iM = (mng_int32)iML;
-    }
-    else
-    if (iX == (iWidth - 2))            /* last interval ? */
-      iM = (mng_int32)iMR;
-    else
-      iM = (mng_int32)iMX;
-                                       /* fill interval ? */
-    if ((iX < iWidth - 1) || (iWidth == 1))
-    {
-      if (pTempsrc2)                   /* do we have the second pixel ? */
-      {
-        iH = (iM+1) / 2;               /* calculate halfway point */
-
-        for (iS = 1; iS < iH; iS++)    /* first half */
-        {
-          if (*pTempsrc1 == *pTempsrc2)
-            *pTempdst = *pTempsrc1;    /* just repeat the first */
-          else                         /* calculate the distance */
-            mng_put_uint16 ((mng_uint8p)pTempdst,
-                            (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
-                                                      (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
-                                          (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
-
-          pTempdst++;
-
-          if (*(pTempsrc1+1) == *(pTempsrc2+1))
-            *pTempdst = *(pTempsrc1+1);
-          else
-            mng_put_uint16 ((mng_uint8p)pTempdst,
-                            (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc2+1))) -
-                                                      (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+1))) ) + iM) /
-                                          (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+1)))         ) );
-
-          pTempdst++;
-
-          if (*(pTempsrc1+2) == *(pTempsrc2+2))
-            *pTempdst = *(pTempsrc1+2);
-          else
-            mng_put_uint16 ((mng_uint8p)pTempdst,
-                            (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc2+2))) -
-                                                      (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+2))) ) + iM) /
-                                          (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+2)))         ) );
-
-          pTempdst++;
-                                       /* replicate alpha from left */
-          *pTempdst     = *(pTempsrc1+3);
-
-          pTempdst++;
-        }
-
-        for (iS = iH; iS < iM; iS++)   /* second half */
-        {
-          if (*pTempsrc1 == *pTempsrc2)
-            *pTempdst = *pTempsrc1;    /* just repeat the first */
-          else                         /* calculate the distance */
-            mng_put_uint16 ((mng_uint8p)pTempdst,
-                            (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
-                                                      (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
-                                          (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
-
-          pTempdst++;
-
-          if (*(pTempsrc1+1) == *(pTempsrc2+1))
-            *pTempdst = *(pTempsrc1+1);
-          else
-            mng_put_uint16 ((mng_uint8p)pTempdst,
-                            (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc2+1))) -
-                                                      (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+1))) ) + iM) /
-                                          (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+1)))         ) );
-
-          pTempdst++;
-
-          if (*(pTempsrc1+2) == *(pTempsrc2+2))
-            *pTempdst = *(pTempsrc1+2);
-          else
-            mng_put_uint16 ((mng_uint8p)pTempdst,
-                            (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc2+2))) -
-                                                      (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+2))) ) + iM) /
-                                          (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+2)))         ) );
-
-          pTempdst++;
-                                       /* replicate alpha from right */
-          *pTempdst     = *(pTempsrc2+3);
-
-          pTempdst++;
-        }
-      }
-      else
-      {
-        for (iS = 1; iS < iM; iS++)
-        {
-          *pTempdst = *pTempsrc1;      /* repeat first source pixel */
-          pTempdst++;
-          *pTempdst = *(pTempsrc1+1);
-          pTempdst++;
-          *pTempdst = *(pTempsrc1+2);
-          pTempdst++;
-          *pTempdst = *(pTempsrc1+3);
-          pTempdst++;
-        }
-      }
-    }
-
-    pTempsrc1 += 4;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA16_X4, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_rgba16_x5 (mng_datap  pData,
-                                   mng_uint16 iMX,
-                                   mng_uint16 iML,
-                                   mng_uint16 iMR,
-                                   mng_uint32 iWidth,
-                                   mng_uint8p pSrcline,
-                                   mng_uint8p pDstline)
-{
-  mng_uint32  iX;
-  mng_int32   iS, iM, iH;
-  mng_uint16p pTempsrc1;
-  mng_uint16p pTempsrc2;
-  mng_uint16p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA16_X5, MNG_LC_START);
-#endif
-
-  pTempsrc1 = (mng_uint16p)pSrcline;   /* initialize pixel-loop */
-  pTempdst  = (mng_uint16p)pDstline;
-
-  for (iX = 0; iX < iWidth; iX++)
-  {
-    pTempsrc2 = pTempsrc1 + 4;
-
-    *pTempdst = *pTempsrc1;            /* copy original source pixel */
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+1);
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+2);
-    pTempdst++;
-    *pTempdst = *(pTempsrc1+3);
-    pTempdst++;
-
-    if (iX == 0)                       /* first interval ? */
-    {
-      if (iWidth == 1)                 /* single pixel ? */
-        pTempsrc2 = MNG_NULL;
-
-      iM = (mng_int32)iML;
-    }
-    else
-    if (iX == (iWidth - 2))            /* last interval ? */
-      iM = (mng_int32)iMR;
-    else
-      iM = (mng_int32)iMX;
-                                       /* fill interval ? */
-    if ((iX < iWidth - 1) || (iWidth == 1))
-    {
-      if (pTempsrc2)                   /* do we have the second pixel ? */
-      {
-        iH = (iM+1) / 2;               /* calculate halfway point */
-
-        for (iS = 1; iS < iH; iS++)    /* first half */
-        {
-          *pTempdst     = *pTempsrc1;  /* replicate color from left */
-          *(pTempdst+1) = *(pTempsrc1+1);
-          *(pTempdst+2) = *(pTempsrc1+2);
-
-          if (*(pTempsrc1+3) == *(pTempsrc2+3))
-            *(pTempdst+3) = *(pTempsrc1+3);
-          else
-            mng_put_uint16 ((mng_uint8p)(pTempdst+3),
-                            (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc2+3))) -
-                                                      (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+3))) ) + iM) /
-                                          (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+3)))         ) );
-
-          pTempdst += 4;
-        }
-
-        for (iS = iH; iS < iM; iS++)   /* second half */
-        {
-          *pTempdst     = *pTempsrc2;  /* replicate color from right */
-          *(pTempdst+1) = *(pTempsrc2+1);
-          *(pTempdst+2) = *(pTempsrc2+2);
-
-          if (*(pTempsrc1+3) == *(pTempsrc2+3))
-            *(pTempdst+3) = *(pTempsrc1+3);
-          else
-            mng_put_uint16 ((mng_uint8p)(pTempdst+3),
-                            (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc2+3))) -
-                                                      (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+3))) ) + iM) /
-                                          (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+3)))         ) );
-
-          pTempdst += 4;
-        }
-      }
-      else
-      {
-        for (iS = 1; iS < iM; iS++)
-        {
-          *pTempdst = *pTempsrc1;      /* repeat first source pixel */
-          pTempdst++;
-          *pTempdst = *(pTempsrc1+1);
-          pTempdst++;
-          *pTempdst = *(pTempsrc1+2);
-          pTempdst++;
-          *pTempdst = *(pTempsrc1+3);
-          pTempdst++;
-        }
-      }
-    }
-
-    pTempsrc1 += 4;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA16_X4, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_GRAY_SUPPORT
-mng_retcode mng_magnify_g16_y1 (mng_datap  pData,
-                                mng_int32  iS,
-                                mng_int32  iM,
-                                mng_uint32 iWidth,
-                                mng_uint8p pSrcline1,
-                                mng_uint8p pSrcline2,
-                                mng_uint8p pDstline)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_G16_Y1, MNG_LC_START);
-#endif
-
-  MNG_COPY (pDstline, pSrcline1, (iWidth << 1));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_G16_Y1, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_g16_y2 (mng_datap  pData,
-                                mng_int32  iS,
-                                mng_int32  iM,
-                                mng_uint32 iWidth,
-                                mng_uint8p pSrcline1,
-                                mng_uint8p pSrcline2,
-                                mng_uint8p pDstline)
-{
-  mng_uint32  iX;
-  mng_uint16p pTempsrc1;
-  mng_uint16p pTempsrc2;
-  mng_uint16p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_G16_Y2, MNG_LC_START);
-#endif
-
-  pTempsrc1 = (mng_uint16p)pSrcline1;  /* initialize pixel-loop */
-  pTempsrc2 = (mng_uint16p)pSrcline2;
-  pTempdst  = (mng_uint16p)pDstline;
-
-  if (pTempsrc2)                       /* do we have a second line ? */
-  {
-    for (iX = 0; iX < iWidth; iX++)
-    {                                  /* calculate the distances */
-      if (*pTempsrc1 == *pTempsrc2)
-        *pTempdst = *pTempsrc1;
-      else
-        mng_put_uint16 ((mng_uint8p)pTempdst,
-                        (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
-                                                    (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
-                                        (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
-
-      pTempdst++;
-      pTempsrc1++;
-      pTempsrc2++;
-    }
-  }
-  else
-  {                                    /* just repeat the entire line */
-    MNG_COPY (pTempdst, pTempsrc1, (iWidth << 1));
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_G16_Y2, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_g16_y3 (mng_datap  pData,
-                                mng_int32  iS,
-                                mng_int32  iM,
-                                mng_uint32 iWidth,
-                                mng_uint8p pSrcline1,
-                                mng_uint8p pSrcline2,
-                                mng_uint8p pDstline)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_G16_Y3, MNG_LC_START);
-#endif
-
-  if (pSrcline2)                       /* do we have a second line ? */
-  {
-    if (iS < (iM+1) / 2)               /* top half ? */
-      MNG_COPY (pDstline, pSrcline1, (iWidth << 1))
-    else
-      MNG_COPY (pDstline, pSrcline2, (iWidth << 1));
-  }
-  else
-  {                                    /* just repeat the entire line */
-    MNG_COPY (pDstline, pSrcline1, (iWidth << 1));
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_G16_Y3, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_NO_GRAY_SUPPORT */
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_rgb16_y1 (mng_datap  pData,
-                                  mng_int32  iS,
-                                  mng_int32  iM,
-                                  mng_uint32 iWidth,
-                                  mng_uint8p pSrcline1,
-                                  mng_uint8p pSrcline2,
-                                  mng_uint8p pDstline)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB16_Y1, MNG_LC_START);
-#endif
-
-  MNG_COPY (pDstline, pSrcline1, iWidth * 6);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB16_Y1, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_rgb16_y2 (mng_datap  pData,
-                                  mng_int32  iS,
-                                  mng_int32  iM,
-                                  mng_uint32 iWidth,
-                                  mng_uint8p pSrcline1,
-                                  mng_uint8p pSrcline2,
-                                  mng_uint8p pDstline)
-{
-  mng_uint32  iX;
-  mng_uint16p pTempsrc1;
-  mng_uint16p pTempsrc2;
-  mng_uint16p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB16_Y2, MNG_LC_START);
-#endif
-
-  pTempsrc1 = (mng_uint16p)pSrcline1;  /* initialize pixel-loop */
-  pTempsrc2 = (mng_uint16p)pSrcline2;
-  pTempdst  = (mng_uint16p)pDstline;
-
-  if (pTempsrc2)                       /* do we have a second line ? */
-  {
-    for (iX = 0; iX < iWidth; iX++)
-    {                                  /* calculate the distances */
-      if (*pTempsrc1 == *pTempsrc2)
-        *pTempdst = *pTempsrc1;
-      else
-        mng_put_uint16 ((mng_uint8p)pTempdst,
-                        (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
-                                                    (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
-                                        (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
-
-      pTempdst++;
-      pTempsrc1++;
-      pTempsrc2++;
-
-      if (*pTempsrc1 == *pTempsrc2)
-        *pTempdst = *pTempsrc1;
-      else
-        mng_put_uint16 ((mng_uint8p)pTempdst,
-                        (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
-                                                    (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
-                                        (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
-
-      pTempdst++;
-      pTempsrc1++;
-      pTempsrc2++;
-
-      if (*pTempsrc1 == *pTempsrc2)
-        *pTempdst = *pTempsrc1;
-      else
-        mng_put_uint16 ((mng_uint8p)pTempdst,
-                        (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
-                                                    (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
-                                        (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
-
-      pTempdst++;
-      pTempsrc1++;
-      pTempsrc2++;
-    }
-  }
-  else
-  {                                    /* just repeat the entire line */
-    MNG_COPY (pTempdst, pTempsrc1, iWidth * 6);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB16_Y2, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_rgb16_y3 (mng_datap  pData,
-                                  mng_int32  iS,
-                                  mng_int32  iM,
-                                  mng_uint32 iWidth,
-                                  mng_uint8p pSrcline1,
-                                  mng_uint8p pSrcline2,
-                                  mng_uint8p pDstline)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB16_Y3, MNG_LC_START);
-#endif
-
-  if (pSrcline2)                       /* do we have a second line ? */
-  {
-    if (iS < (iM+1) / 2)               /* top half ? */
-      MNG_COPY (pDstline, pSrcline1, iWidth * 6)
-    else
-      MNG_COPY (pDstline, pSrcline2, iWidth * 6);
-  }
-  else
-  {                                    /* just repeat the entire line */
-    MNG_COPY (pDstline, pSrcline1, iWidth * 6);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB16_Y3, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_GRAY_SUPPORT
-mng_retcode mng_magnify_ga16_y1 (mng_datap  pData,
-                                 mng_int32  iS,
-                                 mng_int32  iM,
-                                 mng_uint32 iWidth,
-                                 mng_uint8p pSrcline1,
-                                 mng_uint8p pSrcline2,
-                                 mng_uint8p pDstline)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_GA16_Y1, MNG_LC_START);
-#endif
-
-  MNG_COPY (pDstline, pSrcline1, (iWidth << 2));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_GA16_Y1, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_ga16_y2 (mng_datap  pData,
-                                 mng_int32  iS,
-                                 mng_int32  iM,
-                                 mng_uint32 iWidth,
-                                 mng_uint8p pSrcline1,
-                                 mng_uint8p pSrcline2,
-                                 mng_uint8p pDstline)
-{
-  mng_uint32  iX;
-  mng_uint16p pTempsrc1;
-  mng_uint16p pTempsrc2;
-  mng_uint16p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_GA16_Y2, MNG_LC_START);
-#endif
-
-  pTempsrc1 = (mng_uint16p)pSrcline1;  /* initialize pixel-loop */
-  pTempsrc2 = (mng_uint16p)pSrcline2;
-  pTempdst  = (mng_uint16p)pDstline;
-
-  if (pTempsrc2)                       /* do we have a second line ? */
-  {
-    for (iX = 0; iX < iWidth; iX++)
-    {                                  /* calculate the distances */
-      if (*pTempsrc1 == *pTempsrc2)
-        *pTempdst = *pTempsrc1;
-      else
-        mng_put_uint16 ((mng_uint8p)pTempdst,
-                        (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
-                                                    (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
-                                        (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
-
-      pTempdst++;
-      pTempsrc1++;
-      pTempsrc2++;
-
-      if (*pTempsrc1 == *pTempsrc2)
-        *pTempdst = *pTempsrc1;
-      else
-        mng_put_uint16 ((mng_uint8p)pTempdst,
-                        (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
-                                                    (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
-                                        (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
-
-      pTempdst++;
-      pTempsrc1++;
-      pTempsrc2++;
-    }
-  }
-  else
-  {                                    /* just repeat the entire line */
-    MNG_COPY (pTempdst, pTempsrc1, (iWidth << 2));
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_GA16_Y2, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_ga16_y3 (mng_datap  pData,
-                                mng_int32  iS,
-                                mng_int32  iM,
-                                mng_uint32 iWidth,
-                                mng_uint8p pSrcline1,
-                                mng_uint8p pSrcline2,
-                                mng_uint8p pDstline)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_GA16_Y3, MNG_LC_START);
-#endif
-
-  if (pSrcline2)                       /* do we have a second line ? */
-  {
-    if (iS < (iM+1) / 2)               /* top half ? */
-      MNG_COPY (pDstline, pSrcline1, (iWidth << 2))
-    else
-      MNG_COPY (pDstline, pSrcline2, (iWidth << 2));
-  }
-  else
-  {                                    /* just repeat the entire line */
-    MNG_COPY (pDstline, pSrcline1, (iWidth << 2));
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_GA16_Y2, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_ga16_y4 (mng_datap  pData,
-                                 mng_int32  iS,
-                                 mng_int32  iM,
-                                 mng_uint32 iWidth,
-                                 mng_uint8p pSrcline1,
-                                 mng_uint8p pSrcline2,
-                                 mng_uint8p pDstline)
-{
-  mng_uint32  iX;
-  mng_uint16p pTempsrc1;
-  mng_uint16p pTempsrc2;
-  mng_uint16p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_GA16_Y4, MNG_LC_START);
-#endif
-
-  pTempsrc1 = (mng_uint16p)pSrcline1;  /* initialize pixel-loop */
-  pTempsrc2 = (mng_uint16p)pSrcline2;
-  pTempdst  = (mng_uint16p)pDstline;
-
-  if (pTempsrc2)                       /* do we have a second line ? */
-  {
-    if (iS < (iM+1) / 2)               /* top half ? */
-    {
-      for (iX = 0; iX < iWidth; iX++)
-      {                                /* calculate the distances */
-        if (*pTempsrc1 == *pTempsrc2)
-          *pTempdst = *pTempsrc1;
-        else
-          mng_put_uint16 ((mng_uint8p)pTempdst,
-                          (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
-                                                      (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
-                                          (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
-
-        pTempdst++;
-        pTempsrc1++;
-        pTempsrc2 += 2;
-
-        *pTempdst++ = *pTempsrc1++;    /* replicate alpha from top */
-      }
-    }
-    else
-    {
-       for (iX = 0; iX < iWidth; iX++)
-      {                                /* calculate the distances */
-        if (*pTempsrc1 == *pTempsrc2)
-          *pTempdst = *pTempsrc1;
-        else
-          mng_put_uint16 ((mng_uint8p)pTempdst,
-                          (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
-                                                      (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
-                                          (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
-
-        pTempdst++;
-        pTempsrc1 += 2;
-        pTempsrc2++;
-
-        *pTempdst++ = *pTempsrc2++;    /* replicate alpha from bottom */
-      }
-    }
-  }
-  else
-  {                                    /* just repeat the entire line */
-    MNG_COPY (pTempdst, pTempsrc1, (iWidth << 2));
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_GA16_Y4, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_ga16_y5 (mng_datap  pData,
-                                 mng_int32  iS,
-                                 mng_int32  iM,
-                                 mng_uint32 iWidth,
-                                 mng_uint8p pSrcline1,
-                                 mng_uint8p pSrcline2,
-                                 mng_uint8p pDstline)
-{
-  mng_uint32  iX;
-  mng_uint16p pTempsrc1;
-  mng_uint16p pTempsrc2;
-  mng_uint16p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_GA16_Y5, MNG_LC_START);
-#endif
-
-  pTempsrc1 = (mng_uint16p)pSrcline1;  /* initialize pixel-loop */
-  pTempsrc2 = (mng_uint16p)pSrcline2;
-  pTempdst  = (mng_uint16p)pDstline;
-
-  if (pTempsrc2)                       /* do we have a second line ? */
-  {
-    if (iS < (iM+1) / 2)               /* top half ? */
-    {
-      for (iX = 0; iX < iWidth; iX++)
-      {
-        *pTempdst = *pTempsrc1;        /* replicate gray from top */
-
-        pTempdst++;
-        pTempsrc1++;
-        pTempsrc2++;
-
-        if (*pTempsrc1 == *pTempsrc2)  /* calculate the distances */
-          *pTempdst = *pTempsrc1;
-        else
-          mng_put_uint16 ((mng_uint8p)pTempdst,
-                          (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
-                                                      (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
-                                          (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
-
-        pTempdst++;
-        pTempsrc1++;
-        pTempsrc2++;
-      }
-    }
-    else
-    {
-      for (iX = 0; iX < iWidth; iX++)
-      {
-        *pTempdst = *pTempsrc2;        /* replicate gray from bottom */
-
-        pTempdst++;
-        pTempsrc1++;
-        pTempsrc2++;
-
-        if (*pTempsrc1 == *pTempsrc2)  /* calculate the distances */
-          *pTempdst = *pTempsrc1;
-        else
-          mng_put_uint16 ((mng_uint8p)pTempdst,
-                          (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
-                                                      (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
-                                          (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
-
-        pTempdst++;
-        pTempsrc1++;
-        pTempsrc2++;
-      }
-    }
-  }
-  else
-  {                                    /* just repeat the entire line */
-    MNG_COPY (pTempdst, pTempsrc1, (iWidth << 2));
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_GA16_Y5, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_NO_GRAY_SUPPORT */
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_rgba16_y1 (mng_datap  pData,
-                                   mng_int32  iS,
-                                   mng_int32  iM,
-                                   mng_uint32 iWidth,
-                                   mng_uint8p pSrcline1,
-                                   mng_uint8p pSrcline2,
-                                   mng_uint8p pDstline)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA16_Y1, MNG_LC_START);
-#endif
-
-  MNG_COPY (pDstline, pSrcline1, (iWidth << 3));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA16_Y1, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_rgba16_y2 (mng_datap  pData,
-                                   mng_int32  iS,
-                                   mng_int32  iM,
-                                   mng_uint32 iWidth,
-                                   mng_uint8p pSrcline1,
-                                   mng_uint8p pSrcline2,
-                                   mng_uint8p pDstline)
-{
-  mng_uint32  iX;
-  mng_uint16p pTempsrc1;
-  mng_uint16p pTempsrc2;
-  mng_uint16p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA16_Y2, MNG_LC_START);
-#endif
-
-  pTempsrc1 = (mng_uint16p)pSrcline1;  /* initialize pixel-loop */
-  pTempsrc2 = (mng_uint16p)pSrcline2;
-  pTempdst  = (mng_uint16p)pDstline;
-
-  if (pTempsrc2)                       /* do we have a second line ? */
-  {
-    for (iX = 0; iX < iWidth; iX++)
-    {                                  /* calculate the distances */
-      if (*pTempsrc1 == *pTempsrc2)
-        *pTempdst = *pTempsrc1;
-      else
-        mng_put_uint16 ((mng_uint8p)pTempdst,
-                        (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
-                                                    (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
-                                        (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
-
-      pTempdst++;
-      pTempsrc1++;
-      pTempsrc2++;
-
-      if (*pTempsrc1 == *pTempsrc2)
-        *pTempdst = *pTempsrc1;
-      else
-        mng_put_uint16 ((mng_uint8p)pTempdst,
-                        (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
-                                                    (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
-                                        (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
-
-      pTempdst++;
-      pTempsrc1++;
-      pTempsrc2++;
-
-      if (*pTempsrc1 == *pTempsrc2)
-        *pTempdst = *pTempsrc1;
-      else
-        mng_put_uint16 ((mng_uint8p)pTempdst,
-                        (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
-                                                    (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
-                                        (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
-
-      pTempdst++;
-      pTempsrc1++;
-      pTempsrc2++;
-
-      if (*pTempsrc1 == *pTempsrc2)
-        *pTempdst = *pTempsrc1;
-      else
-        mng_put_uint16 ((mng_uint8p)pTempdst,
-                        (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
-                                                    (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
-                                        (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
-
-      pTempdst++;
-      pTempsrc1++;
-      pTempsrc2++;
-    }
-  }
-  else
-  {                                    /* just repeat the entire line */
-    MNG_COPY (pTempdst, pTempsrc1, (iWidth << 3));
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA16_Y2, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_rgba16_y3 (mng_datap  pData,
-                                   mng_int32  iS,
-                                   mng_int32  iM,
-                                   mng_uint32 iWidth,
-                                   mng_uint8p pSrcline1,
-                                   mng_uint8p pSrcline2,
-                                   mng_uint8p pDstline)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA16_Y3, MNG_LC_START);
-#endif
-
-  if (pSrcline2)                       /* do we have a second line ? */
-  {
-    if (iS < (iM+1) / 2)               /* top half ? */
-      MNG_COPY (pDstline, pSrcline1, (iWidth << 3))
-    else
-      MNG_COPY (pDstline, pSrcline2, (iWidth << 3));
-  }
-  else
-  {                                    /* just repeat the entire line */
-    MNG_COPY (pDstline, pSrcline1, (iWidth << 3));
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA16_Y2, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_rgba16_y4 (mng_datap  pData,
-                                   mng_int32  iS,
-                                   mng_int32  iM,
-                                   mng_uint32 iWidth,
-                                   mng_uint8p pSrcline1,
-                                   mng_uint8p pSrcline2,
-                                   mng_uint8p pDstline)
-{
-  mng_uint32  iX;
-  mng_uint16p pTempsrc1;
-  mng_uint16p pTempsrc2;
-  mng_uint16p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA16_Y4, MNG_LC_START);
-#endif
-
-  pTempsrc1 = (mng_uint16p)pSrcline1;  /* initialize pixel-loop */
-  pTempsrc2 = (mng_uint16p)pSrcline2;
-  pTempdst  = (mng_uint16p)pDstline;
-
-  if (pTempsrc2)                       /* do we have a second line ? */
-  {
-    if (iS < (iM+1) / 2)               /* top half ? */
-    {
-      for (iX = 0; iX < iWidth; iX++)
-      {                                /* calculate the distances */
-        if (*pTempsrc1 == *pTempsrc2)
-          *pTempdst = *pTempsrc1;
-        else
-          mng_put_uint16 ((mng_uint8p)pTempdst,
-                          (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
-                                                      (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
-                                          (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
-
-        pTempdst++;
-        pTempsrc1++;
-        pTempsrc2++;
-
-        if (*pTempsrc1 == *pTempsrc2)
-          *pTempdst = *pTempsrc1;
-        else
-          mng_put_uint16 ((mng_uint8p)pTempdst,
-                          (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
-                                                      (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
-                                          (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
-
-        pTempdst++;
-        pTempsrc1++;
-        pTempsrc2++;
-
-        if (*pTempsrc1 == *pTempsrc2)
-          *pTempdst = *pTempsrc1;
-        else
-          mng_put_uint16 ((mng_uint8p)pTempdst,
-                          (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
-                                                      (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
-                                          (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
-
-        pTempdst++;
-        pTempsrc1++;
-        pTempsrc2 += 2;
-
-        *pTempdst++ = *pTempsrc1++;    /* replicate alpha from top */
-      }
-    }
-    else
-    {
-      for (iX = 0; iX < iWidth; iX++)
-      {                                /* calculate the distances */
-        if (*pTempsrc1 == *pTempsrc2)
-          *pTempdst = *pTempsrc1;
-        else
-          mng_put_uint16 ((mng_uint8p)pTempdst,
-                          (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
-                                                      (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
-                                          (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
-
-        pTempdst++;
-        pTempsrc1++;
-        pTempsrc2++;
-
-        if (*pTempsrc1 == *pTempsrc2)
-          *pTempdst = *pTempsrc1;
-        else
-          mng_put_uint16 ((mng_uint8p)pTempdst,
-                          (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
-                                                      (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
-                                          (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
-
-        pTempdst++;
-        pTempsrc1++;
-        pTempsrc2++;
-
-        if (*pTempsrc1 == *pTempsrc2)
-          *pTempdst = *pTempsrc1;
-        else
-          mng_put_uint16 ((mng_uint8p)pTempdst,
-                          (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
-                                                      (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
-                                          (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
-
-        pTempdst++;
-        pTempsrc1 += 2;
-        pTempsrc2++;
-
-        *pTempdst++ = *pTempsrc2++;    /* replicate alpha from bottom */
-      }
-    }
-  }
-  else
-  {                                    /* just repeat the entire line */
-    MNG_COPY (pTempdst, pTempsrc1, (iWidth << 3));
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA16_Y4, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_magnify_rgba16_y5 (mng_datap  pData,
-                                   mng_int32  iS,
-                                   mng_int32  iM,
-                                   mng_uint32 iWidth,
-                                   mng_uint8p pSrcline1,
-                                   mng_uint8p pSrcline2,
-                                   mng_uint8p pDstline)
-{
-  mng_uint32  iX;
-  mng_uint16p pTempsrc1;
-  mng_uint16p pTempsrc2;
-  mng_uint16p pTempdst;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA16_Y5, MNG_LC_START);
-#endif
-
-  pTempsrc1 = (mng_uint16p)pSrcline1;  /* initialize pixel-loop */
-  pTempsrc2 = (mng_uint16p)pSrcline2;
-  pTempdst  = (mng_uint16p)pDstline;
-
-  if (pTempsrc2)                       /* do we have a second line ? */
-  {
-    if (iS < (iM+1) / 2)               /* top half ? */
-    {
-      for (iX = 0; iX < iWidth; iX++)
-      {
-        *pTempdst++ = *pTempsrc1++;    /* replicate color from top */
-        *pTempdst++ = *pTempsrc1++;
-        *pTempdst++ = *pTempsrc1++;
-
-        pTempsrc2 += 3;
-
-        if (*pTempsrc1 == *pTempsrc2)  /* calculate the distances */
-          *pTempdst = *pTempsrc1;
-        else
-          mng_put_uint16 ((mng_uint8p)pTempdst,
-                          (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
-                                                      (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
-                                          (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
-
-        pTempdst++;
-        pTempsrc1++;
-        pTempsrc2++;
-      }
-    }
-    else
-    {
-      for (iX = 0; iX < iWidth; iX++)
-      {
-        *pTempdst++ = *pTempsrc2++;    /* replicate color from bottom */
-        *pTempdst++ = *pTempsrc2++;
-        *pTempdst++ = *pTempsrc2++;
-
-        pTempsrc1 += 3;
-
-        if (*pTempsrc1 == *pTempsrc2)  /* calculate the distances */
-          *pTempdst = *pTempsrc1;
-        else
-          mng_put_uint16 ((mng_uint8p)pTempdst,
-                          (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
-                                                      (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
-                                          (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
-
-        pTempdst++;
-        pTempsrc1++;
-        pTempsrc2++;
-      }
-    }
-  }
-  else
-  {                                    /* just repeat the entire line */
-    MNG_COPY (pTempdst, pTempsrc1, (iWidth << 3));
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA16_Y5, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_NO_16BIT_SUPPORT */
-#endif /* MNG_OPTIMIZE_FOOTPRINT_MAGN */
-#endif /* MNG_SKIPCHUNK_MAGN */
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * PAST composition routines - compose over/under with a target object    * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_PAST
-mng_retcode mng_composeover_rgba8 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-  mng_uint8      iFGa8, iBGa8;
-  mng_uint8      iCr8, iCg8, iCb8, iCa8;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_COMPOSEOVER_RGBA8, MNG_LC_START);
-#endif
-
-  pWorkrow = pData->pRGBArow;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize);
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    iFGa8 = *(pWorkrow+3);       /* get alpha values */
-    iBGa8 = *(pOutrow+3);
-
-    if (iFGa8)                   /* any opacity at all ? */
-    {                            /* fully opaque or background fully transparent ? */
-      if ((iFGa8 == 0xFF) || (iBGa8 == 0))
-      {                          /* then simply copy the values */
-        *pOutrow     = *pWorkrow;
-        *(pOutrow+1) = *(pWorkrow+1);
-        *(pOutrow+2) = *(pWorkrow+2);
-        *(pOutrow+3) = iFGa8;
-      }
-      else
-      {
-        if (iBGa8 == 0xFF)       /* background fully opaque ? */
-        {                        /* do alpha composing */
-#ifdef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
-          int i;
-          for (i=2; i >= 0; i--)
-          {
-          MNG_COMPOSE8 (*(pOutrow+i), *(pWorkrow+i), iFGa8, *(pOutrow+i));
-          }
-#else
-          MNG_COMPOSE8 (*pOutrow,     *pWorkrow,     iFGa8, *pOutrow    );
-          MNG_COMPOSE8 (*(pOutrow+1), *(pWorkrow+1), iFGa8, *(pOutrow+1));
-          MNG_COMPOSE8 (*(pOutrow+2), *(pWorkrow+2), iFGa8, *(pOutrow+2));
-#endif
-                                 /* alpha remains fully opaque !!! */
-        }
-        else
-        {                        /* here we'll have to blend */
-          MNG_BLEND8 (*pWorkrow, *(pWorkrow+1), *(pWorkrow+2), iFGa8,
-                      *pOutrow, *(pOutrow+1), *(pOutrow+2), iBGa8,
-                      iCr8, iCg8, iCb8, iCa8);
-                                 /* and return the composed values */
-          *pOutrow     = iCr8;
-          *(pOutrow+1) = iCg8;
-          *(pOutrow+2) = iCb8;
-          *(pOutrow+3) = iCa8;
-        }
-      }
-    }
-
-    pOutrow  += 4;
-    pWorkrow += 4;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_COMPOSEOVER_RGBA8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_composeover_rgba16 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
-  mng_uint16p    pWorkrow;
-  mng_uint16p    pOutrow;
-  mng_int32      iX;
-  mng_uint16     iFGa16, iFGr16, iFGg16, iFGb16;
-  mng_uint16     iBGa16, iBGr16, iBGg16, iBGb16;
-  mng_uint16     iCr16, iCg16, iCb16, iCa16;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_COMPOSEOVER_RGBA16, MNG_LC_START);
-#endif
-
-  pWorkrow = (mng_uint16p)pData->pRGBArow;
-  pOutrow  = (mng_uint16p)(pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                                            (pData->iCol * pBuf->iSamplesize));
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {                              /* get alpha values */
-    iFGa16 = mng_get_uint16 ((mng_uint8p)(pWorkrow+3));
-    iBGa16 = mng_get_uint16 ((mng_uint8p)(pOutrow+3));
-
-    if (iFGa16)                  /* any opacity at all ? */
-    {                            /* fully opaque or background fully transparent ? */
-      if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
-      {                          /* then simply copy the values */
-        *pOutrow     = *pWorkrow;
-        *(pOutrow+1) = *(pWorkrow+1);
-        *(pOutrow+2) = *(pWorkrow+2);
-        *(pOutrow+3) = *(pWorkrow+3);
-      }
-      else
-      {                          /* get color values */
-        iFGr16 = mng_get_uint16 ((mng_uint8p)pWorkrow);
-        iFGg16 = mng_get_uint16 ((mng_uint8p)(pWorkrow+1));
-        iFGb16 = mng_get_uint16 ((mng_uint8p)(pWorkrow+2));
-        iBGr16 = mng_get_uint16 ((mng_uint8p)pOutrow);
-        iBGg16 = mng_get_uint16 ((mng_uint8p)(pOutrow+1));
-        iBGb16 = mng_get_uint16 ((mng_uint8p)(pOutrow+2));
-
-        if (iBGa16 == 0xFFFF)    /* background fully opaque ? */
-        {                        /* do alpha composing */
-          MNG_COMPOSE16 (iFGr16, iFGr16, iFGa16, iBGr16);
-          MNG_COMPOSE16 (iFGg16, iFGg16, iFGa16, iBGg16);
-          MNG_COMPOSE16 (iFGb16, iFGb16, iFGa16, iBGb16);
-
-          mng_put_uint16 ((mng_uint8p)pOutrow,     iFGr16);
-          mng_put_uint16 ((mng_uint8p)(pOutrow+1), iFGg16);
-          mng_put_uint16 ((mng_uint8p)(pOutrow+2), iFGb16);
-                                 /* alpha remains fully opaque !!! */
-        }
-        else
-        {                        /* here we'll have to blend */
-          MNG_BLEND16 (iFGr16, iFGg16, iFGb16, iFGa16,
-                       iBGr16, iBGg16, iBGb16, iBGa16,
-                       iCr16,  iCg16,  iCb16,  iCa16);
-                                 /* and return the composed values */
-          mng_put_uint16 ((mng_uint8p)pOutrow,     iCr16);
-          mng_put_uint16 ((mng_uint8p)(pOutrow+1), iCg16);
-          mng_put_uint16 ((mng_uint8p)(pOutrow+2), iCb16);
-          mng_put_uint16 ((mng_uint8p)(pOutrow+3), iCa16);
-        }
-      }
-    }
-
-    pOutrow  += 4;
-    pWorkrow += 4;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_COMPOSEOVER_RGBA16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_composeunder_rgba8 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
-  mng_uint8p     pWorkrow;
-  mng_uint8p     pOutrow;
-  mng_int32      iX;
-  mng_uint8      iFGa8, iBGa8;
-  mng_uint8      iCr8, iCg8, iCb8, iCa8;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_COMPOSEUNDER_RGBA8, MNG_LC_START);
-#endif
-
-  pWorkrow = pData->pRGBArow;
-  pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                              (pData->iCol * pBuf->iSamplesize);
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {
-    iFGa8 = *(pOutrow+3);        /* get alpha values */
-    iBGa8 = *(pWorkrow+3);
-                                 /* anything to do at all ? */
-    if ((iBGa8) && (iFGa8 != 0xFF))
-    {
-      if (iBGa8 == 0xFF)         /* background fully opaque ? */
-      {                          /* do alpha composing */
-#ifdef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
-        int i;
-        for (i=2; i >= 0; i--)
-        {
-        MNG_COMPOSE8 (*(pOutrow+i), *(pOutrow+i), iFGa8, *(pWorkrow+i));
-        }
-#else
-        MNG_COMPOSE8 (*pOutrow,     *pOutrow,     iFGa8, *pWorkrow    );
-        MNG_COMPOSE8 (*(pOutrow+1), *(pOutrow+1), iFGa8, *(pWorkrow+1));
-        MNG_COMPOSE8 (*(pOutrow+2), *(pOutrow+2), iFGa8, *(pWorkrow+2));
-#endif
-        *(pOutrow+3) = 0xFF;     /* alpha becomes fully opaque !!! */
-      }
-      else
-      {                          /* here we'll have to blend */
-        MNG_BLEND8 (*pOutrow, *(pOutrow+1), *(pOutrow+2), iFGa8,
-                    *pWorkrow, *(pWorkrow+1), *(pWorkrow+2), iBGa8,
-                    iCr8, iCg8, iCb8, iCa8);
-                                 /* and return the composed values */
-        *pOutrow     = iCr8;
-        *(pOutrow+1) = iCg8;
-        *(pOutrow+2) = iCb8;
-        *(pOutrow+3) = iCa8;
-      }
-    }
-
-    pOutrow  += 4;
-    pWorkrow += 4;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_COMPOSEUNDER_RGBA8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_composeunder_rgba16 (mng_datap pData)
-{
-  mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
-  mng_uint16p    pWorkrow;
-  mng_uint16p    pOutrow;
-  mng_int32      iX;
-  mng_uint16     iFGa16, iFGr16, iFGg16, iFGb16;
-  mng_uint16     iBGa16, iBGr16, iBGg16, iBGb16;
-  mng_uint16     iCr16, iCg16, iCb16, iCa16;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_COMPOSEUNDER_RGBA16, MNG_LC_START);
-#endif
-
-  pWorkrow = (mng_uint16p)pData->pRGBArow;
-  pOutrow  = (mng_uint16p)(pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
-                                            (pData->iCol * pBuf->iSamplesize));
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {                              /* get alpha values */
-    iFGa16 = mng_get_uint16 ((mng_uint8p)(pOutrow+3));
-    iBGa16 = mng_get_uint16 ((mng_uint8p)(pWorkrow+3));
-                                 /* anything to do at all ? */
-    if ((iBGa16) && (iFGa16 != 0xFFFF))
-    {
-      iFGr16 = mng_get_uint16 ((mng_uint8p)pOutrow);
-      iFGg16 = mng_get_uint16 ((mng_uint8p)(pOutrow+1));
-      iFGb16 = mng_get_uint16 ((mng_uint8p)(pOutrow+2));
-      iBGr16 = mng_get_uint16 ((mng_uint8p)pWorkrow);
-      iBGg16 = mng_get_uint16 ((mng_uint8p)(pWorkrow+1));
-      iBGb16 = mng_get_uint16 ((mng_uint8p)(pWorkrow+2));
-
-      if (iBGa16 == 0xFFFF)      /* background fully opaque ? */
-      {                          /* do alpha composing */
-        MNG_COMPOSE16 (iFGr16, iFGr16, iFGa16, iBGr16);
-        MNG_COMPOSE16 (iFGg16, iFGg16, iFGa16, iBGg16);
-        MNG_COMPOSE16 (iFGb16, iFGb16, iFGa16, iBGb16);
-
-        mng_put_uint16 ((mng_uint8p)pOutrow,     iFGr16);
-        mng_put_uint16 ((mng_uint8p)(pOutrow+1), iFGg16);
-        mng_put_uint16 ((mng_uint8p)(pOutrow+2), iFGb16);
-        *(pOutrow+3) = 0xFFFF;   /* alpha becomes fully opaque !!! */
-      }
-      else
-      {                          /* here we'll have to blend */
-        MNG_BLEND16 (iFGr16, iFGg16, iFGb16, iFGa16,
-                     iBGr16, iBGg16, iBGb16, iBGa16,
-                     iCr16,  iCg16,  iCb16,  iCa16);
-                                 /* and return the composed values */
-        mng_put_uint16 ((mng_uint8p)pOutrow,     iCr16);
-        mng_put_uint16 ((mng_uint8p)(pOutrow+1), iCg16);
-        mng_put_uint16 ((mng_uint8p)(pOutrow+2), iCb16);
-        mng_put_uint16 ((mng_uint8p)(pOutrow+3), iCa16);
-      }
-    }
-
-    pOutrow  += 4;
-    pWorkrow += 4;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_COMPOSEUNDER_RGBA16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * PAST flip & tile routines - flip or tile a row of pixels               * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_PAST
-mng_retcode mng_flip_rgba8 (mng_datap pData)
-{
-  mng_uint32p pWorkrow;
-  mng_uint32p pOutrow;
-  mng_int32   iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FLIP_RGBA8, MNG_LC_START);
-#endif
-                                       /* setup temp pointers */
-  pWorkrow        = (mng_uint32p)pData->pRGBArow + pData->iRowsamples - 1;
-  pOutrow         = (mng_uint32p)pData->pWorkrow;
-                                       /* swap original buffers */
-  pData->pWorkrow = pData->pRGBArow;
-  pData->pRGBArow = (mng_uint8p)pOutrow;
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {                                    /* let's flip */
-    *pOutrow = *pWorkrow;
-    pOutrow++;
-    pWorkrow--;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FLIP_RGBA8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_flip_rgba16 (mng_datap pData)
-{
-  mng_uint32p pWorkrow;
-  mng_uint32p pOutrow;
-  mng_int32   iX;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FLIP_RGBA16, MNG_LC_START);
-#endif
-                                       /* setup temp pointers */
-  pWorkrow        = (mng_uint32p)pData->pRGBArow + ((pData->iRowsamples - 1) << 1);
-  pOutrow         = (mng_uint32p)pData->pWorkrow;
-                                       /* swap original buffers */
-  pData->pWorkrow = pData->pRGBArow;
-  pData->pRGBArow = (mng_uint8p)pOutrow;
-
-#ifdef MNG_DECREMENT_LOOPS
-  for (iX = pData->iRowsamples; iX > 0; iX--)
-#else
-  for (iX = 0; iX < pData->iRowsamples; iX++)
-#endif
-  {                                    /* let's flip */
-    *pOutrow       = *pWorkrow;
-    *(pOutrow + 1) = *(pWorkrow + 1);
-
-    pOutrow  += 2;
-    pWorkrow -= 2;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_FLIP_RGBA16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode mng_tile_rgba8 (mng_datap pData)
-{
-  mng_uint32p pWorkrow;
-  mng_uint32p pOutrow;
-  mng_int32   iX;
-  mng_uint32  iZ, iMax;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_TILE_RGBA8, MNG_LC_START);
-#endif
-
-  iZ              = pData->iSourcel;   /* indent ? */
-                                       /* what's our source-length */
-  iMax            = ((mng_imagep)pData->pRetrieveobj)->pImgbuf->iWidth;
-                                       /* setup temp pointers */
-  pWorkrow        = (mng_uint32p)pData->pRGBArow + iZ;
-  pOutrow         = (mng_uint32p)pData->pWorkrow;
-                                       /* swap original buffers */
-  pData->pWorkrow = pData->pRGBArow;
-  pData->pRGBArow = (mng_uint8p)pOutrow;
-
-  for (iX = pData->iDestl; iX < pData->iDestr; iX++)
-  {                                    /* tiiiile */
-    *pOutrow = *pWorkrow;
-
-    pWorkrow++;
-    pOutrow++;
-    iZ++;
-
-    if (iZ >= iMax)                    /* end of source ? */
-    {
-      iZ       = 0;
-      pWorkrow = (mng_uint32p)pData->pWorkrow;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_TILE_RGBA8, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_tile_rgba16 (mng_datap pData)
-{
-  mng_uint32p pWorkrow;
-  mng_uint32p pOutrow;
-  mng_int32   iX;
-  mng_uint32  iZ, iMax;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_TILE_RGBA16, MNG_LC_START);
-#endif
-
-  iZ              = pData->iSourcel;   /* indent ? */
-                                       /* what's our source-length */
-  iMax            = ((mng_imagep)pData->pRetrieveobj)->pImgbuf->iWidth;
-                                       /* setup temp pointers */
-  pWorkrow        = (mng_uint32p)pData->pRGBArow + (iZ << 1);
-  pOutrow         = (mng_uint32p)pData->pWorkrow;
-                                       /* swap original buffers */
-  pData->pWorkrow = pData->pRGBArow;
-  pData->pRGBArow = (mng_uint8p)pOutrow;
-
-  for (iX = pData->iDestl; iX < pData->iDestr; iX++)
-  {                                    /* tiiiile */
-    *pOutrow       = *pWorkrow;
-    *(pOutrow + 1) = *(pWorkrow + 1);
-
-    pWorkrow += 2;
-    pOutrow  += 2;
-    iZ++;
-
-    if (iZ >= iMax)                    /* end of source ? */
-    {
-      iZ       = 0;
-      pWorkrow = (mng_uint32p)pData->pWorkrow;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_TILE_RGBA16, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif /* MNG_SKIPCHUNK_PAST */
-
-/* ************************************************************************** */
-
-#endif /* MNG_INCLUDE_DISPLAY_PROCS */
-
-/* ************************************************************************** */
-/* * end of file                                                            * */
-/* ************************************************************************** */
diff --git a/Source/LibMNG/libmng_pixels.h b/Source/LibMNG/libmng_pixels.h
deleted file mode 100644
index 5a0281e..0000000
--- a/Source/LibMNG/libmng_pixels.h
+++ /dev/null
@@ -1,1147 +0,0 @@
-/* ************************************************************************** */
-/* *             For conditions of distribution and use,                    * */
-/* *                see copyright notice in libmng.h                        * */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * project   : libmng                                                     * */
-/* * file      : libmng_pixels.h           copyright (c) 2000-2006 G.Juyn   * */
-/* * version   : 1.0.10                                                     * */
-/* *                                                                        * */
-/* * purpose   : Pixel-row management routines (definition)                 * */
-/* *                                                                        * */
-/* * author    : G.Juyn                                                     * */
-/* *                                                                        * */
-/* * comment   : Definition of the pixel-row management routines            * */
-/* *                                                                        * */
-/* * changes   : 0.5.1 - 05/08/2000 - G.Juyn                                * */
-/* *             - changed strict-ANSI stuff                                * */
-/* *                                                                        * */
-/* *             0.5.2 - 05/22/2000 - G.Juyn                                * */
-/* *             - added some JNG definitions                               * */
-/* *             - added delta-image row-processing routines                * */
-/* *             0.5.2 - 06/05/2000 - G.Juyn                                * */
-/* *             - added support for RGB8_A8 canvasstyle                    * */
-/* *                                                                        * */
-/* *             0.5.3 - 06/16/2000 - G.Juyn                                * */
-/* *             - changed progressive-display processing                   * */
-/* *                                                                        * */
-/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
-/* *             - changed file-prefixes                                    * */
-/* *                                                                        * */
-/* *             0.9.3 - 08/26/2000 - G.Juyn                                * */
-/* *             - added MAGN support                                       * */
-/* *             0.9.3 - 09/07/2000 - G.Juyn                                * */
-/* *             - added support for new filter_types                       * */
-/* *             0.9.3 - 10/16/2000 - G.Juyn                                * */
-/* *             - added optional support for bKGD for PNG images           * */
-/* *             - added support for JDAA                                   * */
-/* *             0.9.3 - 10/19/2000 - G.Juyn                                * */
-/* *             - implemented delayed delta-processing                     * */
-/* *                                                                        * */
-/* *             0.9.4 -  1/18/2001 - G.Juyn                                * */
-/* *             - added "new" MAGN methods 3, 4 & 5                        * */
-/* *                                                                        * */
-/* *             1.0.1 - 04/21/2001 - G.Juyn (code by G.Kelly)              * */
-/* *             - added BGRA8 canvas with premultiplied alpha              * */
-/* *                                                                        * */
-/* *             1.0.5 - 08/15/2002 - G.Juyn                                * */
-/* *             - completed PROM support                                   * */
-/* *             - completed delta-image support                            * */
-/* *             1.0.5 - 08/16/2002 - G.Juyn                                * */
-/* *             - completed MAGN support (16-bit functions)                * */
-/* *             1.0.5 - 08/19/2002 - G.Juyn                                * */
-/* *             - B597134 - libmng pollutes the linker namespace           * */
-/* *             1.0.5 - 09/22/2002 - G.Juyn                                * */
-/* *             - added bgrx8 canvas (filler byte)                         * */
-/* *             1.0.5 - 09/23/2002 - G.Juyn                                * */
-/* *             - added compose over/under routines for PAST processing    * */
-/* *             - added flip & tile routines for PAST processing           * */
-/* *                                                                        * */
-/* *             1.0.6 - 03/09/2003 - G.Juyn                                * */
-/* *             - hiding 12-bit JPEG stuff                                 * */
-/* *             1.0.6 - 05/11/2003 - G. Juyn                               * */
-/* *             - added conditionals around canvas update routines         * */
-/* *             1.0.6 - 06/09/2003 - G. R-P                                * */
-/* *             - added conditionals around 8-bit magn routines            * */
-/* *             1.0.6 - 07/07/2003 - G. R-P                                * */
-/* *             - removed conditionals around 8-bit magn routines          * */
-/* *             - added conditionals around 16-bit and delta-PNG           * */
-/* *               supporting code                                          * */
-/* *             1.0.6 - 07/29/2003 - G.R-P                                 * */
-/* *             - added SKIPCHUNK conditionals around PAST chunk support   * */
-/* *             1.0.6 - 08/18/2003 - G.R-P                                 * */
-/* *             - added conditionals around 1, 2, and 4-bit prototypes     * */
-/* *                                                                        * */
-/* *             1.0.7 - 11/27/2003 - R.A                                   * */
-/* *             - added CANVAS_RGB565 and CANVAS_BGR565                    * */
-/* *             1.0.7 - 12/06/2003 - R.A                                   * */
-/* *             - added CANVAS_RGBA565 and CANVAS_BGRA565                  * */
-/* *             1.0.7 - 01/25/2004 - J.S                                   * */
-/* *             - added premultiplied alpha canvas' for RGBA, ARGB, ABGR   * */
-/* *                                                                        * */
-/* *             1.0.9 - 10/10/2004 - G.R-P.                                * */
-/* *             - added MNG_NO_1_2_4BIT_SUPPORT                            * */
-/* *             1.0.9 - 10/14/2004 - G.Juyn                                * */
-/* *             - added bgr565_a8 canvas-style (thanks to J. Elvander)     * */
-/* *                                                                        * */
-/* *             1.0.10 - 03/07/2006 - (thanks to W. Manthey)               * */
-/* *             - added CANVAS_RGB555 and CANVAS_BGR555                    * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
-#pragma option -A                      /* force ANSI-C */
-#endif
-
-#ifndef _libmng_pixels_h_
-#define _libmng_pixels_h_
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Progressive display check - checks to see if progressive display is    * */
-/* * in order & indicates so                                                * */
-/* *                                                                        * */
-/* * The routine is called after a call to one of the display_xxx routines  * */
-/* * if appropriate                                                         * */
-/* *                                                                        * */
-/* * The refresh is warrented in the read_chunk routine (mng_read.c)        * */
-/* * and only during read&display processing, since there's not much point  * */
-/* * doing it from memory!                                                  * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-mng_retcode mng_display_progressive_check (mng_datap pData);
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Display routines - convert rowdata (which is already color-corrected)  * */
-/* * to the output canvas, respecting any transparency information          * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCANVAS_RGB8
-mng_retcode mng_display_rgb8           (mng_datap  pData);
-#endif
-#ifndef MNG_SKIPCANVAS_RGBA8
-mng_retcode mng_display_rgba8          (mng_datap  pData);
-#endif
-#ifndef MNG_SKIPCANVAS_RGBA8_PM
-mng_retcode mng_display_rgba8_pm       (mng_datap  pData);
-#endif
-#ifndef MNG_SKIPCANVAS_ARGB8
-mng_retcode mng_display_argb8          (mng_datap  pData);
-#endif
-#ifndef MNG_SKIPCANVAS_ARGB8_PM
-mng_retcode mng_display_argb8_pm       (mng_datap  pData);
-#endif
-#ifndef MNG_SKIPCANVAS_RGB8_A8
-mng_retcode mng_display_rgb8_a8        (mng_datap  pData);
-#endif
-#ifndef MNG_SKIPCANVAS_BGR8
-mng_retcode mng_display_bgr8           (mng_datap  pData);
-#endif
-#ifndef MNG_SKIPCANVAS_BGRX8
-mng_retcode mng_display_bgrx8          (mng_datap  pData);
-#endif
-#ifndef MNG_SKIPCANVAS_BGRA8
-mng_retcode mng_display_bgra8          (mng_datap  pData);
-#endif
-#ifndef MNG_SKIPCANVAS_BGRA8_PM
-mng_retcode mng_display_bgra8_pm       (mng_datap  pData);
-#endif
-#ifndef MNG_SKIPCANVAS_ABGR8
-mng_retcode mng_display_abgr8          (mng_datap  pData);
-#endif
-#ifndef MNG_SKIPCANVAS_ABGR8_PM
-mng_retcode mng_display_abgr8_pm       (mng_datap  pData);
-#endif
-#ifndef MNG_SKIPCANVAS_RGB565
-mng_retcode mng_display_rgb565         (mng_datap  pData);
-#endif
-#ifndef MNG_SKIPCANVAS_RGBA565
-mng_retcode mng_display_rgba565        (mng_datap  pData);
-#endif
-#ifndef MNG_SKIPCANVAS_BGR565
-mng_retcode mng_display_bgr565         (mng_datap  pData);
-#endif
-#ifndef MNG_SKIPCANVAS_BGRA565
-mng_retcode mng_display_bgra565        (mng_datap  pData);
-#endif
-#ifndef MNG_SKIPCANVAS_BGR565_A8
-mng_retcode mng_display_bgr565_a8      (mng_datap  pData);
-#endif
-#ifndef MNG_SKIPCANVAS_RGB555
-mng_retcode mng_display_rgb555         (mng_datap  pData);
-#endif
-#ifndef MNG_SKIPCANVAS_BGR555
-mng_retcode mng_display_bgr555         (mng_datap  pData);
-#endif
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Background restore routines - restore the background with info from    * */
-/* * the BACK and/or bKGD chunk and/or the app's background canvas          * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-mng_retcode mng_restore_bkgd_backimage (mng_datap  pData);
-mng_retcode mng_restore_bkgd_backcolor (mng_datap  pData);
-mng_retcode mng_restore_bkgd_bkgd      (mng_datap  pData);
-mng_retcode mng_restore_bkgd_bgcolor   (mng_datap  pData);
-#ifndef MNG_SKIPCANVAS_RGB8
-mng_retcode mng_restore_bkgd_rgb8      (mng_datap  pData);
-#endif
-#ifndef MNG_SKIPCANVAS_BGR8
-mng_retcode mng_restore_bkgd_bgr8      (mng_datap  pData);
-#endif
-#ifndef MNG_SKIPCANVAS_BGRX8
-mng_retcode mng_restore_bkgd_bgrx8     (mng_datap  pData);
-#endif
-#ifndef MNG_SKIPCANVAS_RGB565
-mng_retcode mng_restore_bkgd_rgb565    (mng_datap  pData);
-#endif
-#ifndef MNG_SKIPCANVAS_BGR565
-mng_retcode mng_restore_bkgd_bgr565    (mng_datap  pData);
-#endif
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Row retrieval routines - retrieve processed & uncompressed row-data    * */
-/* * from the current "object"                                              * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-mng_retcode mng_retrieve_g8            (mng_datap  pData);
-mng_retcode mng_retrieve_rgb8          (mng_datap  pData);
-mng_retcode mng_retrieve_idx8          (mng_datap  pData);
-mng_retcode mng_retrieve_ga8           (mng_datap  pData);
-mng_retcode mng_retrieve_rgba8         (mng_datap  pData);
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_retrieve_g16           (mng_datap  pData);
-mng_retcode mng_retrieve_ga16          (mng_datap  pData);
-mng_retcode mng_retrieve_rgb16         (mng_datap  pData);
-mng_retcode mng_retrieve_rgba16        (mng_datap  pData);
-#endif
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Row storage routines - store processed & uncompressed row-data         * */
-/* * into the current "object"                                              * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-mng_retcode mng_store_g1               (mng_datap  pData);
-mng_retcode mng_store_g2               (mng_datap  pData);
-mng_retcode mng_store_g4               (mng_datap  pData);
-mng_retcode mng_store_idx1             (mng_datap  pData);
-mng_retcode mng_store_idx2             (mng_datap  pData);
-mng_retcode mng_store_idx4             (mng_datap  pData);
-#endif
-mng_retcode mng_store_idx8             (mng_datap  pData);
-mng_retcode mng_store_rgb8             (mng_datap  pData);
-mng_retcode mng_store_g8               (mng_datap  pData);
-mng_retcode mng_store_ga8              (mng_datap  pData);
-mng_retcode mng_store_rgba8            (mng_datap  pData);
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_store_g16              (mng_datap  pData);
-mng_retcode mng_store_ga16             (mng_datap  pData);
-mng_retcode mng_store_rgb16            (mng_datap  pData);
-mng_retcode mng_store_rgba16           (mng_datap  pData);
-#endif
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Row storage routines (JPEG) - store processed & uncompressed row-data  * */
-/* * into the current "object"                                              * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-mng_retcode mng_store_jpeg_g8          (mng_datap  pData);
-mng_retcode mng_store_jpeg_rgb8        (mng_datap  pData);
-mng_retcode mng_store_jpeg_ga8         (mng_datap  pData);
-mng_retcode mng_store_jpeg_rgba8       (mng_datap  pData);
-
-#ifdef MNG_SUPPORT_JPEG12
-mng_retcode mng_store_jpeg_g12         (mng_datap  pData);
-mng_retcode mng_store_jpeg_rgb12       (mng_datap  pData);
-mng_retcode mng_store_jpeg_ga12        (mng_datap  pData);
-mng_retcode mng_store_jpeg_rgba12      (mng_datap  pData);
-#endif
-
-mng_retcode mng_store_jpeg_g8_alpha    (mng_datap  pData);
-mng_retcode mng_store_jpeg_rgb8_alpha  (mng_datap  pData);
-
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-mng_retcode mng_store_jpeg_g8_a1       (mng_datap  pData);
-mng_retcode mng_store_jpeg_g8_a2       (mng_datap  pData);
-mng_retcode mng_store_jpeg_g8_a4       (mng_datap  pData);
-#endif
-mng_retcode mng_store_jpeg_g8_a8       (mng_datap  pData);
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_store_jpeg_g8_a16      (mng_datap  pData);
-#endif
-
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-mng_retcode mng_store_jpeg_rgb8_a1     (mng_datap  pData);
-mng_retcode mng_store_jpeg_rgb8_a2     (mng_datap  pData);
-mng_retcode mng_store_jpeg_rgb8_a4     (mng_datap  pData);
-#endif
-mng_retcode mng_store_jpeg_rgb8_a8     (mng_datap  pData);
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_store_jpeg_rgb8_a16    (mng_datap  pData);
-#endif
-
-#ifdef MNG_SUPPORT_JPEG12
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-mng_retcode mng_store_jpeg_g12_a1      (mng_datap  pData);
-mng_retcode mng_store_jpeg_g12_a2      (mng_datap  pData);
-mng_retcode mng_store_jpeg_g12_a4      (mng_datap  pData);
-#endif
-mng_retcode mng_store_jpeg_g12_a8      (mng_datap  pData);
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_store_jpeg_g12_a16     (mng_datap  pData);
-#endif
-
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-mng_retcode mng_store_jpeg_rgb12_a1    (mng_datap  pData);
-mng_retcode mng_store_jpeg_rgb12_a2    (mng_datap  pData);
-mng_retcode mng_store_jpeg_rgb12_a4    (mng_datap  pData);
-#endif
-mng_retcode mng_store_jpeg_rgb12_a8    (mng_datap  pData);
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_store_jpeg_rgb12_a16   (mng_datap  pData);
-#endif
-#endif
-#endif
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Delta-image row routines - apply the processed & uncompressed row-data * */
-/* * onto the target "object"                                               * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-mng_retcode mng_delta_g1               (mng_datap  pData);
-mng_retcode mng_delta_g2               (mng_datap  pData);
-mng_retcode mng_delta_g4               (mng_datap  pData);
-#endif
-mng_retcode mng_delta_g8               (mng_datap  pData);
-mng_retcode mng_delta_g16              (mng_datap  pData);
-mng_retcode mng_delta_rgb8             (mng_datap  pData);
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_delta_rgb16            (mng_datap  pData);
-#endif
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-mng_retcode mng_delta_idx1             (mng_datap  pData);
-mng_retcode mng_delta_idx2             (mng_datap  pData);
-mng_retcode mng_delta_idx4             (mng_datap  pData);
-#endif
-mng_retcode mng_delta_idx8             (mng_datap  pData);
-mng_retcode mng_delta_ga8              (mng_datap  pData);
-mng_retcode mng_delta_rgba8            (mng_datap  pData);
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_delta_ga16             (mng_datap  pData);
-mng_retcode mng_delta_rgba16           (mng_datap  pData);
-#endif
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Delta-image row routines - apply the source row onto the target        * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-mng_retcode mng_delta_g1_g1            (mng_datap  pData);
-mng_retcode mng_delta_g2_g2            (mng_datap  pData);
-mng_retcode mng_delta_g4_g4            (mng_datap  pData);
-#endif
-mng_retcode mng_delta_g8_g8            (mng_datap  pData);
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_delta_g16_g16          (mng_datap  pData);
-#endif
-mng_retcode mng_delta_ga8_ga8          (mng_datap  pData);
-mng_retcode mng_delta_ga8_g8           (mng_datap  pData);
-mng_retcode mng_delta_ga8_a8           (mng_datap  pData);
-mng_retcode mng_delta_rgba8_rgb8       (mng_datap  pData);
-mng_retcode mng_delta_rgba8_a8         (mng_datap  pData);
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_delta_ga16_ga16        (mng_datap  pData);
-mng_retcode mng_delta_ga16_g16         (mng_datap  pData);
-mng_retcode mng_delta_ga16_a16         (mng_datap  pData);
-mng_retcode mng_delta_rgba16_a16       (mng_datap  pData);
-mng_retcode mng_delta_rgba16_rgb16     (mng_datap  pData);
-#endif
-#endif /* MNG_NO_DELTA_PNG */
-mng_retcode mng_delta_rgb8_rgb8        (mng_datap  pData); /* Used for PAST */
-mng_retcode mng_delta_rgba8_rgba8      (mng_datap  pData);
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_delta_rgb16_rgb16      (mng_datap  pData);
-mng_retcode mng_delta_rgba16_rgba16    (mng_datap  pData);
-#endif
-
-#ifndef MNG_NO_DELTA_PNG
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Delta-image row routines - scale the delta to bitdepth of target       * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-mng_retcode mng_scale_g1_g2            (mng_datap  pData);
-mng_retcode mng_scale_g1_g4            (mng_datap  pData);
-mng_retcode mng_scale_g1_g8            (mng_datap  pData);
-mng_retcode mng_scale_g2_g4            (mng_datap  pData);
-mng_retcode mng_scale_g2_g8            (mng_datap  pData);
-mng_retcode mng_scale_g4_g8            (mng_datap  pData);
-#endif
-#ifndef MNG_NO_16BIT_SUPPORT
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-mng_retcode mng_scale_g1_g16           (mng_datap  pData);
-mng_retcode mng_scale_g2_g16           (mng_datap  pData);
-mng_retcode mng_scale_g4_g16           (mng_datap  pData);
-#endif
-mng_retcode mng_scale_g8_g16           (mng_datap  pData);
-mng_retcode mng_scale_ga8_ga16         (mng_datap  pData);
-mng_retcode mng_scale_rgb8_rgb16       (mng_datap  pData);
-mng_retcode mng_scale_rgba8_rgba16     (mng_datap  pData);
-#endif
-
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-mng_retcode mng_scale_g2_g1            (mng_datap  pData);
-mng_retcode mng_scale_g4_g1            (mng_datap  pData);
-mng_retcode mng_scale_g8_g1            (mng_datap  pData);
-mng_retcode mng_scale_g4_g2            (mng_datap  pData);
-mng_retcode mng_scale_g8_g2            (mng_datap  pData);
-mng_retcode mng_scale_g8_g4            (mng_datap  pData);
-#endif
-#ifndef MNG_NO_16BIT_SUPPORT
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-mng_retcode mng_scale_g16_g1           (mng_datap  pData);
-mng_retcode mng_scale_g16_g2           (mng_datap  pData);
-mng_retcode mng_scale_g16_g4           (mng_datap  pData);
-#endif
-mng_retcode mng_scale_g16_g8           (mng_datap  pData);
-mng_retcode mng_scale_ga16_ga8         (mng_datap  pData);
-mng_retcode mng_scale_rgb16_rgb8       (mng_datap  pData);
-mng_retcode mng_scale_rgba16_rgba8     (mng_datap  pData);
-#endif
-#endif /* MNG_NO_DELTA_PNG */
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Delta-image bit routines - promote bit_depth                           * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-mng_uint8   mng_promote_replicate_1_2  (mng_uint8  iB);
-mng_uint8   mng_promote_replicate_1_4  (mng_uint8  iB);
-mng_uint8   mng_promote_replicate_1_8  (mng_uint8  iB);
-mng_uint8   mng_promote_replicate_2_4  (mng_uint8  iB);
-mng_uint8   mng_promote_replicate_2_8  (mng_uint8  iB);
-mng_uint8   mng_promote_replicate_4_8  (mng_uint8  iB);
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_uint16  mng_promote_replicate_1_16 (mng_uint8  iB);
-mng_uint16  mng_promote_replicate_2_16 (mng_uint8  iB);
-mng_uint16  mng_promote_replicate_4_16 (mng_uint8  iB);
-mng_uint16  mng_promote_replicate_8_16 (mng_uint8  iB);
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DELTA_PNG
-mng_uint8   mng_promote_zerofill_1_2   (mng_uint8  iB);
-mng_uint8   mng_promote_zerofill_1_4   (mng_uint8  iB);
-mng_uint8   mng_promote_zerofill_1_8   (mng_uint8  iB);
-mng_uint8   mng_promote_zerofill_2_4   (mng_uint8  iB);
-mng_uint8   mng_promote_zerofill_2_8   (mng_uint8  iB);
-mng_uint8   mng_promote_zerofill_4_8   (mng_uint8  iB);
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_uint16  mng_promote_zerofill_1_16  (mng_uint8  iB);
-mng_uint16  mng_promote_zerofill_2_16  (mng_uint8  iB);
-mng_uint16  mng_promote_zerofill_4_16  (mng_uint8  iB);
-mng_uint16  mng_promote_zerofill_8_16  (mng_uint8  iB);
-#endif
-#endif /* MNG_NO_DELTA_PNG */
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Delta-image row routines - promote color_type                          * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-mng_retcode mng_promote_g8_g8          (mng_datap  pData);
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_promote_g8_g16         (mng_datap  pData);
-mng_retcode mng_promote_g16_g16        (mng_datap  pData);
-#endif
-
-mng_retcode mng_promote_g8_ga8         (mng_datap  pData);
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_promote_g8_ga16        (mng_datap  pData);
-mng_retcode mng_promote_g16_ga16       (mng_datap  pData);
-#endif
-
-mng_retcode mng_promote_g8_rgb8        (mng_datap  pData);
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_promote_g8_rgb16       (mng_datap  pData);
-mng_retcode mng_promote_g16_rgb16      (mng_datap  pData);
-#endif
-
-mng_retcode mng_promote_g8_rgba8       (mng_datap  pData);
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_promote_g8_rgba16      (mng_datap  pData);
-mng_retcode mng_promote_g16_rgba16     (mng_datap  pData);
-
-mng_retcode mng_promote_ga8_ga16       (mng_datap  pData);
-#endif
-
-mng_retcode mng_promote_ga8_rgba8      (mng_datap  pData);
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_promote_ga8_rgba16     (mng_datap  pData);
-mng_retcode mng_promote_ga16_rgba16    (mng_datap  pData);
-#endif
-
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_promote_rgb8_rgb16     (mng_datap  pData);
-#endif
-
-mng_retcode mng_promote_rgb8_rgba8     (mng_datap  pData);
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_promote_rgb8_rgba16    (mng_datap  pData);
-mng_retcode mng_promote_rgb16_rgba16   (mng_datap  pData);
-#endif
-
-mng_retcode mng_promote_idx8_rgb8      (mng_datap  pData);
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_promote_idx8_rgb16     (mng_datap  pData);
-#endif
-
-mng_retcode mng_promote_idx8_rgba8     (mng_datap  pData);
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_promote_idx8_rgba16    (mng_datap  pData);
-
-mng_retcode mng_promote_rgba8_rgba16   (mng_datap  pData);
-#endif
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Row processing routines - convert uncompressed data from zlib to       * */
-/* * managable row-data which serves as input to the color-management       * */
-/* * routines                                                               * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-mng_retcode mng_process_g1             (mng_datap  pData);
-mng_retcode mng_process_g2             (mng_datap  pData);
-mng_retcode mng_process_g4             (mng_datap  pData);
-#endif
-mng_retcode mng_process_g8             (mng_datap  pData);
-mng_retcode mng_process_rgb8           (mng_datap  pData);
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-mng_retcode mng_process_idx1           (mng_datap  pData);
-mng_retcode mng_process_idx2           (mng_datap  pData);
-mng_retcode mng_process_idx4           (mng_datap  pData);
-#endif
-mng_retcode mng_process_idx8           (mng_datap  pData);
-mng_retcode mng_process_ga8            (mng_datap  pData);
-mng_retcode mng_process_rgba8          (mng_datap  pData);
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_process_g16            (mng_datap  pData);
-mng_retcode mng_process_ga16           (mng_datap  pData);
-mng_retcode mng_process_rgb16          (mng_datap  pData);
-mng_retcode mng_process_rgba16         (mng_datap  pData);
-#endif
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Row processing initialization routines - set up the variables needed   * */
-/* * to process uncompressed row-data                                       * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_FOOTPRINT_INIT
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-mng_retcode mng_init_g1_i              (mng_datap  pData);
-mng_retcode mng_init_g2_i              (mng_datap  pData);
-mng_retcode mng_init_g4_i              (mng_datap  pData);
-#endif
-mng_retcode mng_init_g8_i              (mng_datap  pData);
-mng_retcode mng_init_rgb8_i            (mng_datap  pData);
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-mng_retcode mng_init_idx1_i            (mng_datap  pData);
-mng_retcode mng_init_idx2_i            (mng_datap  pData);
-mng_retcode mng_init_idx4_i            (mng_datap  pData);
-#endif
-mng_retcode mng_init_idx8_i            (mng_datap  pData);
-mng_retcode mng_init_ga8_i             (mng_datap  pData);
-mng_retcode mng_init_rgba8_i           (mng_datap  pData);
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-mng_retcode mng_init_g1_ni             (mng_datap  pData);
-mng_retcode mng_init_g2_ni             (mng_datap  pData);
-mng_retcode mng_init_g4_ni             (mng_datap  pData);
-#endif
-mng_retcode mng_init_g8_ni             (mng_datap  pData);
-mng_retcode mng_init_rgb8_ni           (mng_datap  pData);
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-mng_retcode mng_init_idx1_ni           (mng_datap  pData);
-mng_retcode mng_init_idx2_ni           (mng_datap  pData);
-mng_retcode mng_init_idx4_ni           (mng_datap  pData);
-#endif
-mng_retcode mng_init_idx8_ni           (mng_datap  pData);
-mng_retcode mng_init_ga8_ni            (mng_datap  pData);
-mng_retcode mng_init_rgba8_ni          (mng_datap  pData);
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_init_g16_i             (mng_datap  pData);
-mng_retcode mng_init_rgb16_i           (mng_datap  pData);
-mng_retcode mng_init_ga16_i            (mng_datap  pData);
-mng_retcode mng_init_rgba16_i          (mng_datap  pData);
-mng_retcode mng_init_g16_ni            (mng_datap  pData);
-mng_retcode mng_init_rgb16_ni          (mng_datap  pData);
-mng_retcode mng_init_ga16_ni           (mng_datap  pData);
-mng_retcode mng_init_rgba16_ni         (mng_datap  pData);
-#endif
-#endif
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Row processing initialization routines (JPEG) - set up the variables   * */
-/* * needed to process uncompressed row-data                                * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_FOOTPRINT_INIT
-#ifdef MNG_INCLUDE_JNG
-#ifndef MNG_NO_1_2_4BIT_SUPPORT
-mng_retcode mng_init_jpeg_a1_ni        (mng_datap  pData);
-mng_retcode mng_init_jpeg_a2_ni        (mng_datap  pData);
-mng_retcode mng_init_jpeg_a4_ni        (mng_datap  pData);
-#endif
-mng_retcode mng_init_jpeg_a8_ni        (mng_datap  pData);
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_init_jpeg_a16_ni       (mng_datap  pData);
-#endif
-#endif
-#endif
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * General row processing routines                                        * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-mng_retcode mng_init_rowproc           (mng_datap  pData);
-mng_retcode mng_next_row               (mng_datap  pData);
-#ifdef MNG_INCLUDE_JNG
-mng_retcode mng_next_jpeg_alpharow     (mng_datap  pData);
-mng_retcode mng_next_jpeg_row          (mng_datap  pData);
-#endif
-mng_retcode mng_cleanup_rowproc        (mng_datap  pData);
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Magnification row routines - apply magnification transforms            * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifndef MNG_OPTIMIZE_FOOTPRINT_MAGN
-mng_retcode mng_magnify_g8_x1          (mng_datap  pData,
-                                        mng_uint16 iMX,
-                                        mng_uint16 iML,
-                                        mng_uint16 iMR,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_g8_x2          (mng_datap  pData,
-                                        mng_uint16 iMX,
-                                        mng_uint16 iML,
-                                        mng_uint16 iMR,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_g8_x3          (mng_datap  pData,
-                                        mng_uint16 iMX,
-                                        mng_uint16 iML,
-                                        mng_uint16 iMR,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_rgb8_x1        (mng_datap  pData,
-                                        mng_uint16 iMX,
-                                        mng_uint16 iML,
-                                        mng_uint16 iMR,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_rgb8_x2        (mng_datap  pData,
-                                        mng_uint16 iMX,
-                                        mng_uint16 iML,
-                                        mng_uint16 iMR,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_rgb8_x3        (mng_datap  pData,
-                                        mng_uint16 iMX,
-                                        mng_uint16 iML,
-                                        mng_uint16 iMR,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_ga8_x1         (mng_datap  pData,
-                                        mng_uint16 iMX,
-                                        mng_uint16 iML,
-                                        mng_uint16 iMR,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_ga8_x2         (mng_datap  pData,
-                                        mng_uint16 iMX,
-                                        mng_uint16 iML,
-                                        mng_uint16 iMR,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_ga8_x3         (mng_datap  pData,
-                                        mng_uint16 iMX,
-                                        mng_uint16 iML,
-                                        mng_uint16 iMR,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_ga8_x4         (mng_datap  pData,
-                                        mng_uint16 iMX,
-                                        mng_uint16 iML,
-                                        mng_uint16 iMR,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_ga8_x5         (mng_datap  pData,
-                                        mng_uint16 iMX,
-                                        mng_uint16 iML,
-                                        mng_uint16 iMR,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline,
-                                        mng_uint8p pDstline);
-#endif
-mng_retcode mng_magnify_rgba8_x1       (mng_datap  pData,
-                                        mng_uint16 iMX,
-                                        mng_uint16 iML,
-                                        mng_uint16 iMR,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_rgba8_x2       (mng_datap  pData,
-                                        mng_uint16 iMX,
-                                        mng_uint16 iML,
-                                        mng_uint16 iMR,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_rgba8_x3       (mng_datap  pData,
-                                        mng_uint16 iMX,
-                                        mng_uint16 iML,
-                                        mng_uint16 iMR,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_rgba8_x4       (mng_datap  pData,
-                                        mng_uint16 iMX,
-                                        mng_uint16 iML,
-                                        mng_uint16 iMR,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_rgba8_x5       (mng_datap  pData,
-                                        mng_uint16 iMX,
-                                        mng_uint16 iML,
-                                        mng_uint16 iMR,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline,
-                                        mng_uint8p pDstline);
-#ifndef MNG_OPTIMIZE_FOOTPRINT_MAGN
-mng_retcode mng_magnify_g8_y1          (mng_datap  pData,
-                                        mng_int32  iS,
-                                        mng_int32  iM,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline1,
-                                        mng_uint8p pSrcline2,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_g8_y2          (mng_datap  pData,
-                                        mng_int32  iS,
-                                        mng_int32  iM,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline1,
-                                        mng_uint8p pSrcline2,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_g8_y3          (mng_datap  pData,
-                                        mng_int32  iS,
-                                        mng_int32  iM,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline1,
-                                        mng_uint8p pSrcline2,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_rgb8_y1        (mng_datap  pData,
-                                        mng_int32  iS,
-                                        mng_int32  iM,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline1,
-                                        mng_uint8p pSrcline2,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_rgb8_y2        (mng_datap  pData,
-                                        mng_int32  iS,
-                                        mng_int32  iM,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline1,
-                                        mng_uint8p pSrcline2,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_rgb8_y3        (mng_datap  pData,
-                                        mng_int32  iS,
-                                        mng_int32  iM,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline1,
-                                        mng_uint8p pSrcline2,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_ga8_y1         (mng_datap  pData,
-                                        mng_int32  iS,
-                                        mng_int32  iM,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline1,
-                                        mng_uint8p pSrcline2,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_ga8_y2         (mng_datap  pData,
-                                        mng_int32  iS,
-                                        mng_int32  iM,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline1,
-                                        mng_uint8p pSrcline2,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_ga8_y3         (mng_datap  pData,
-                                        mng_int32  iS,
-                                        mng_int32  iM,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline1,
-                                        mng_uint8p pSrcline2,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_ga8_y4         (mng_datap  pData,
-                                        mng_int32  iS,
-                                        mng_int32  iM,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline1,
-                                        mng_uint8p pSrcline2,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_ga8_y5         (mng_datap  pData,
-                                        mng_int32  iS,
-                                        mng_int32  iM,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline1,
-                                        mng_uint8p pSrcline2,
-                                        mng_uint8p pDstline);
-#endif
-mng_retcode mng_magnify_rgba8_y1       (mng_datap  pData,
-                                        mng_int32  iS,
-                                        mng_int32  iM,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline1,
-                                        mng_uint8p pSrcline2,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_rgba8_y2       (mng_datap  pData,
-                                        mng_int32  iS,
-                                        mng_int32  iM,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline1,
-                                        mng_uint8p pSrcline2,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_rgba8_y3       (mng_datap  pData,
-                                        mng_int32  iS,
-                                        mng_int32  iM,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline1,
-                                        mng_uint8p pSrcline2,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_rgba8_y4       (mng_datap  pData,
-                                        mng_int32  iS,
-                                        mng_int32  iM,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline1,
-                                        mng_uint8p pSrcline2,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_rgba8_y5       (mng_datap  pData,
-                                        mng_int32  iS,
-                                        mng_int32  iM,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline1,
-                                        mng_uint8p pSrcline2,
-                                        mng_uint8p pDstline);
-
-/* ************************************************************************** */
-#ifndef MNG_NO_16BIT_SUPPORT
-#ifndef MNG_OPTIMIZE_FOOTPRINT_MAGN
-mng_retcode mng_magnify_g16_x1         (mng_datap  pData,
-                                        mng_uint16 iMX,
-                                        mng_uint16 iML,
-                                        mng_uint16 iMR,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_g16_x2         (mng_datap  pData,
-                                        mng_uint16 iMX,
-                                        mng_uint16 iML,
-                                        mng_uint16 iMR,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_g16_x3         (mng_datap  pData,
-                                        mng_uint16 iMX,
-                                        mng_uint16 iML,
-                                        mng_uint16 iMR,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_rgb16_x1       (mng_datap  pData,
-                                        mng_uint16 iMX,
-                                        mng_uint16 iML,
-                                        mng_uint16 iMR,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_rgb16_x2       (mng_datap  pData,
-                                        mng_uint16 iMX,
-                                        mng_uint16 iML,
-                                        mng_uint16 iMR,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_rgb16_x3       (mng_datap  pData,
-                                        mng_uint16 iMX,
-                                        mng_uint16 iML,
-                                        mng_uint16 iMR,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_ga16_x1        (mng_datap  pData,
-                                        mng_uint16 iMX,
-                                        mng_uint16 iML,
-                                        mng_uint16 iMR,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_ga16_x2        (mng_datap  pData,
-                                        mng_uint16 iMX,
-                                        mng_uint16 iML,
-                                        mng_uint16 iMR,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_ga16_x3        (mng_datap  pData,
-                                        mng_uint16 iMX,
-                                        mng_uint16 iML,
-                                        mng_uint16 iMR,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_ga16_x4        (mng_datap  pData,
-                                        mng_uint16 iMX,
-                                        mng_uint16 iML,
-                                        mng_uint16 iMR,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_ga16_x5        (mng_datap  pData,
-                                        mng_uint16 iMX,
-                                        mng_uint16 iML,
-                                        mng_uint16 iMR,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_rgba16_x1      (mng_datap  pData,
-                                        mng_uint16 iMX,
-                                        mng_uint16 iML,
-                                        mng_uint16 iMR,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_rgba16_x2      (mng_datap  pData,
-                                        mng_uint16 iMX,
-                                        mng_uint16 iML,
-                                        mng_uint16 iMR,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_rgba16_x3      (mng_datap  pData,
-                                        mng_uint16 iMX,
-                                        mng_uint16 iML,
-                                        mng_uint16 iMR,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_rgba16_x4      (mng_datap  pData,
-                                        mng_uint16 iMX,
-                                        mng_uint16 iML,
-                                        mng_uint16 iMR,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_rgba16_x5      (mng_datap  pData,
-                                        mng_uint16 iMX,
-                                        mng_uint16 iML,
-                                        mng_uint16 iMR,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline,
-                                        mng_uint8p pDstline);
-
-mng_retcode mng_magnify_g16_y1         (mng_datap  pData,
-                                        mng_int32  iS,
-                                        mng_int32  iM,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline1,
-                                        mng_uint8p pSrcline2,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_g16_y2         (mng_datap  pData,
-                                        mng_int32  iS,
-                                        mng_int32  iM,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline1,
-                                        mng_uint8p pSrcline2,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_g16_y3         (mng_datap  pData,
-                                        mng_int32  iS,
-                                        mng_int32  iM,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline1,
-                                        mng_uint8p pSrcline2,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_rgb16_y1       (mng_datap  pData,
-                                        mng_int32  iS,
-                                        mng_int32  iM,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline1,
-                                        mng_uint8p pSrcline2,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_rgb16_y2       (mng_datap  pData,
-                                        mng_int32  iS,
-                                        mng_int32  iM,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline1,
-                                        mng_uint8p pSrcline2,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_rgb16_y3       (mng_datap  pData,
-                                        mng_int32  iS,
-                                        mng_int32  iM,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline1,
-                                        mng_uint8p pSrcline2,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_ga16_y1        (mng_datap  pData,
-                                        mng_int32  iS,
-                                        mng_int32  iM,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline1,
-                                        mng_uint8p pSrcline2,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_ga16_y2        (mng_datap  pData,
-                                        mng_int32  iS,
-                                        mng_int32  iM,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline1,
-                                        mng_uint8p pSrcline2,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_ga16_y3        (mng_datap  pData,
-                                        mng_int32  iS,
-                                        mng_int32  iM,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline1,
-                                        mng_uint8p pSrcline2,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_ga16_y4        (mng_datap  pData,
-                                        mng_int32  iS,
-                                        mng_int32  iM,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline1,
-                                        mng_uint8p pSrcline2,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_ga16_y5        (mng_datap  pData,
-                                        mng_int32  iS,
-                                        mng_int32  iM,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline1,
-                                        mng_uint8p pSrcline2,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_rgba16_y1      (mng_datap  pData,
-                                        mng_int32  iS,
-                                        mng_int32  iM,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline1,
-                                        mng_uint8p pSrcline2,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_rgba16_y2      (mng_datap  pData,
-                                        mng_int32  iS,
-                                        mng_int32  iM,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline1,
-                                        mng_uint8p pSrcline2,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_rgba16_y3      (mng_datap  pData,
-                                        mng_int32  iS,
-                                        mng_int32  iM,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline1,
-                                        mng_uint8p pSrcline2,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_rgba16_y4      (mng_datap  pData,
-                                        mng_int32  iS,
-                                        mng_int32  iM,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline1,
-                                        mng_uint8p pSrcline2,
-                                        mng_uint8p pDstline);
-mng_retcode mng_magnify_rgba16_y5      (mng_datap  pData,
-                                        mng_int32  iS,
-                                        mng_int32  iM,
-                                        mng_uint32 iWidth,
-                                        mng_uint8p pSrcline1,
-                                        mng_uint8p pSrcline2,
-                                        mng_uint8p pDstline);
-#endif
-#endif
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * PAST composition routines - compose over/under with a target object    * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-mng_retcode mng_composeover_rgba8      (mng_datap  pData);
-#ifndef MNG_SKIPCHUNK_PAST
-mng_retcode mng_composeunder_rgba8     (mng_datap  pData);
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_composeover_rgba16     (mng_datap  pData);
-mng_retcode mng_composeunder_rgba16    (mng_datap  pData);
-#endif
-#endif
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * PAST flip & tile routines - flip or tile a row of pixels               * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifndef MNG_SKIPCHUNK_PAST
-mng_retcode mng_flip_rgba8             (mng_datap  pData);
-mng_retcode mng_tile_rgba8             (mng_datap  pData);
-#ifndef MNG_NO_16BIT_SUPPORT
-mng_retcode mng_flip_rgba16            (mng_datap  pData);
-mng_retcode mng_tile_rgba16            (mng_datap  pData);
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#endif /* _libmng_pixels_h_ */
-
-/* ************************************************************************** */
-/* * end of file                                                            * */
-/* ************************************************************************** */
diff --git a/Source/LibMNG/libmng_prop_xs.c b/Source/LibMNG/libmng_prop_xs.c
deleted file mode 100644
index d4afc87..0000000
--- a/Source/LibMNG/libmng_prop_xs.c
+++ /dev/null
@@ -1,2799 +0,0 @@
-/* ************************************************************************** */
-/* *             For conditions of distribution and use,                    * */
-/* *                see copyright notice in libmng.h                        * */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * project   : libmng                                                     * */
-/* * file      : libmng_prop_xs.c          copyright (c) 2000-2006 G.Juyn   * */
-/* * version   : 1.0.10                                                     * */
-/* *                                                                        * */
-/* * purpose   : property get/set interface (implementation)                * */
-/* *                                                                        * */
-/* * author    : G.Juyn                                                     * */
-/* *                                                                        * */
-/* * comment   : implementation of the property get/set functions           * */
-/* *                                                                        * */
-/* * changes   : 0.5.1 - 05/08/2000 - G.Juyn                                * */
-/* *             - fixed calling convention                                 * */
-/* *             - changed strict-ANSI stuff                                * */
-/* *             0.5.1 - 05/11/2000 - G.Juyn                                * */
-/* *             - added set_outputprofile2 & set_srgbprofile2              * */
-/* *             0.5.1 - 05/12/2000 - G.Juyn                                * */
-/* *             - changed trace to macro for callback error-reporting      * */
-/* *                                                                        * */
-/* *             0.5.2 - 05/23/2000 - G.Juyn                                * */
-/* *             - changed inclusion of cms-routines                        * */
-/* *             0.5.2 - 05/24/2000 - G.Juyn                                * */
-/* *             - added support for get/set default zlib/IJG parms         * */
-/* *             0.5.2 - 05/31/2000 - G.Juyn                                * */
-/* *             - fixed up punctuation (contribution by Tim Rowley)        * */
-/* *             0.5.2 - 06/05/2000 - G.Juyn                                * */
-/* *             - added support for RGB8_A8 canvasstyle                    * */
-/* *                                                                        * */
-/* *             0.5.3 - 06/21/2000 - G.Juyn                                * */
-/* *             - added get/set for speedtype to facilitate testing        * */
-/* *             - added get for imagelevel during processtext callback     * */
-/* *             0.5.3 - 06/26/2000 - G.Juyn                                * */
-/* *             - changed userdata variable to mng_ptr                     * */
-/* *             0.5.3 - 06/29/2000 - G.Juyn                                * */
-/* *             - fixed incompatible return-types                          * */
-/* *                                                                        * */
-/* *             0.9.1 - 07/08/2000 - G.Juyn                                * */
-/* *             - added get routines for internal display variables        * */
-/* *             - added get/set routines for suspensionmode variable       * */
-/* *             0.9.1 - 07/15/2000 - G.Juyn                                * */
-/* *             - added get/set routines for sectionbreak variable         * */
-/* *                                                                        * */
-/* *             0.9.2 - 07/31/2000 - G.Juyn                                * */
-/* *             - added status_xxxx functions                              * */
-/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
-/* *             - changed file-prefixes                                    * */
-/* *                                                                        * */
-/* *             0.9.3 - 10/10/2000 - G.Juyn                                * */
-/* *             - added support for alpha-depth prediction                 * */
-/* *             0.9.3 - 10/16/2000 - G.Juyn                                * */
-/* *             - added functions to retrieve PNG/JNG specific header-info * */
-/* *             0.9.3 - 10/20/2000 - G.Juyn                                * */
-/* *             - added get/set for bKGD preference setting                * */
-/* *             0.9.3 - 10/21/2000 - G.Juyn                                * */
-/* *             - added get function for interlace/progressive display     * */
-/* *                                                                        * */
-/* *             1.0.1 - 04/21/2001 - G.Juyn (code by G.Kelly)              * */
-/* *             - added BGRA8 canvas with premultiplied alpha              * */
-/* *             1.0.1 - 05/02/2001 - G.Juyn                                * */
-/* *             - added "default" sRGB generation (Thanks Marti!)          * */
-/* *                                                                        * */
-/* *             1.0.2 - 06/23/2001 - G.Juyn                                * */
-/* *             - added optimization option for MNG-video playback         * */
-/* *             1.0.2 - 06/25/2001 - G.Juyn                                * */
-/* *             - added option to turn off progressive refresh             * */
-/* *                                                                        * */
-/* *             1.0.3 - 08/06/2001 - G.Juyn                                * */
-/* *             - added get function for last processed BACK chunk         * */
-/* *                                                                        * */
-/* *             1.0.4 - 06/22/2002 - G.Juyn                                * */
-/* *             - B495442 - invalid returnvalue in mng_get_suspensionmode  * */
-/* *                                                                        * */
-/* *             1.0.5 - 09/14/2002 - G.Juyn                                * */
-/* *             - added event handling for dynamic MNG                     * */
-/* *             1.0.5 - 09/22/2002 - G.Juyn                                * */
-/* *             - added bgrx8 canvas (filler byte)                         * */
-/* *             1.0.5 - 11/07/2002 - G.Juyn                                * */
-/* *             - added support to get totals after mng_read()             * */
-/* *                                                                        * */
-/* *             1.0.6 - 05/11/2003 - G. Juyn                               * */
-/* *             - added conditionals around canvas update routines         * */
-/* *             1.0.6 - 07/07/2003 - G.R-P                                 * */
-/* *             - added conditionals around some JNG-supporting code       * */
-/* *             1.0.6 - 07/11/2003 - G.R-P                                 * */
-/* *             - added conditionals zlib and jpeg property accessors      * */
-/* *             1.0.6 - 07/14/2003 - G.R-P                                 * */
-/* *             - added conditionals around various unused functions       * */
-/* *                                                                        * */
-/* *             1.0.7 - 11/27/2003 - R.A                                   * */
-/* *             - added CANVAS_RGB565 and CANVAS_BGR565                    * */
-/* *             1.0.7 - 12/06/2003 - R.A                                   * */
-/* *             - added CANVAS_RGBA565 and CANVAS_BGRA565                  * */
-/* *             1.0.7 - 01/25/2004 - J.S                                   * */
-/* *             - added premultiplied alpha canvas' for RGBA, ARGB, ABGR   * */
-/* *             1.0.7 - 03/07/2004 - G.R-P.                                * */
-/* *             - put gamma, cms-related functions inside #ifdef           * */
-/* *                                                                        * */
-/* *             1.0.8 - 04/02/2004 - G.Juyn                                * */
-/* *             - added CRC existence & checking flags                     * */
-/* *                                                                        * */
-/* *             1.0.9 - 09/18/2004 - G.R-P.                                * */
-/* *             - added some MNG_SUPPORT_WRITE conditionals                * */
-/* *             1.0.9 - 10/03/2004 - G.Juyn                                * */
-/* *             - added function to retrieve current FRAM delay            * */
-/* *             1.0.9 - 10/14/2004 - G.Juyn                                * */
-/* *             - added bgr565_a8 canvas-style (thanks to J. Elvander)     * */
-/* *             1.0.9 - 12/20/2004 - G.Juyn                                * */
-/* *             - cleaned up macro-invocations (thanks to D. Airlie)       * */
-/* *                                                                        * */
-/* *             1.0.10 - 03/07/2006 - (thanks to W. Manthey)               * */
-/* *             - added CANVAS_RGB555 and CANVAS_BGR555                    * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#include "libmng.h"
-#include "libmng_data.h"
-#include "libmng_error.h"
-#include "libmng_trace.h"
-#ifdef __BORLANDC__
-#pragma hdrstop
-#endif
-#include "libmng_objects.h"
-#include "libmng_memory.h"
-#include "libmng_cms.h"
-
-#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
-#pragma option -A                      /* force ANSI-C */
-#endif
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* *  Property set functions                                                * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_set_userdata (mng_handle hHandle,
-                                       mng_ptr    pUserdata)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_USERDATA, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->pUserdata = pUserdata;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_USERDATA, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_set_canvasstyle (mng_handle hHandle,
-                                          mng_uint32 iStyle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_CANVASSTYLE, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-
-  switch (iStyle)
-  {
-#ifndef MNG_SKIPCANVAS_RGB8
-    case MNG_CANVAS_RGB8    : break;
-#endif
-#ifndef MNG_SKIPCANVAS_RGBA8
-    case MNG_CANVAS_RGBA8   : break;
-#endif
-#ifndef MNG_SKIPCANVAS_RGBA8_PM
-    case MNG_CANVAS_RGBA8_PM: break;
-#endif
-#ifndef MNG_SKIPCANVAS_ARGB8
-    case MNG_CANVAS_ARGB8   : break;
-#endif
-#ifndef MNG_SKIPCANVAS_ARGB8_PM
-    case MNG_CANVAS_ARGB8_PM: break;
-#endif
-#ifndef MNG_SKIPCANVAS_RGB8_A8
-    case MNG_CANVAS_RGB8_A8 : break;
-#endif
-#ifndef MNG_SKIPCANVAS_BGR8
-    case MNG_CANVAS_BGR8    : break;
-#endif
-#ifndef MNG_SKIPCANVAS_BGRX8
-    case MNG_CANVAS_BGRX8   : break;
-#endif
-#ifndef MNG_SKIPCANVAS_BGRA8
-    case MNG_CANVAS_BGRA8   : break;
-#endif
-#ifndef MNG_SKIPCANVAS_BGRA8_PM
-    case MNG_CANVAS_BGRA8_PM: break;
-#endif
-#ifndef MNG_SKIPCANVAS_ABGR8
-    case MNG_CANVAS_ABGR8   : break;
-#endif
-#ifndef MNG_SKIPCANVAS_ABGR8_PM
-    case MNG_CANVAS_ABGR8_PM: break;
-#endif
-#ifndef MNG_SKIPCANVAS_RGB565
-    case MNG_CANVAS_RGB565  : break;
-#endif
-#ifndef MNG_SKIPCANVAS_RGBA565
-    case MNG_CANVAS_RGBA565 : break;
-#endif
-#ifndef MNG_SKIPCANVAS_BGR565
-    case MNG_CANVAS_BGR565  : break;
-#endif
-#ifndef MNG_SKIPCANVAS_BGRA565
-    case MNG_CANVAS_BGRA565 : break;
-#endif
-#ifndef MNG_SKIPCANVAS_BGR565_A8
-    case MNG_CANVAS_BGR565_A8 : break;
-#endif
-#ifndef MNG_SKIPCANVAS_RGB555
-    case MNG_CANVAS_RGB555  : break;
-#endif
-#ifndef MNG_SKIPCANVAS_BGR555
-    case MNG_CANVAS_BGR555  : break;
-#endif
-/*    case MNG_CANVAS_RGB16   : break; */
-/*    case MNG_CANVAS_RGBA16  : break; */
-/*    case MNG_CANVAS_ARGB16  : break; */
-/*    case MNG_CANVAS_BGR16   : break; */
-/*    case MNG_CANVAS_BGRA16  : break; */
-/*    case MNG_CANVAS_ABGR16  : break; */
-/*    case MNG_CANVAS_INDEX8  : break; */
-/*    case MNG_CANVAS_INDEXA8 : break; */
-/*    case MNG_CANVAS_AINDEX8 : break; */
-/*    case MNG_CANVAS_GRAY8   : break; */
-/*    case MNG_CANVAS_GRAY16  : break; */
-/*    case MNG_CANVAS_GRAYA8  : break; */
-/*    case MNG_CANVAS_GRAYA16 : break; */
-/*    case MNG_CANVAS_AGRAY8  : break; */
-/*    case MNG_CANVAS_AGRAY16 : break; */
-/*    case MNG_CANVAS_DX15    : break; */
-/*    case MNG_CANVAS_DX16    : break; */
-    default                 : { MNG_ERROR (((mng_datap)hHandle), MNG_INVALIDCNVSTYLE) };
-  }
-
-  ((mng_datap)hHandle)->iCanvasstyle = iStyle;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_CANVASSTYLE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_set_bkgdstyle (mng_handle hHandle,
-                                        mng_uint32 iStyle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_BKGDSTYLE, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-
-  switch (iStyle)                      /* alpha-modes not supported */
-  {
-#ifndef MNG_SKIPCANVAS_RGB8
-    case MNG_CANVAS_RGB8    : break;
-#endif
-#ifndef MNG_SKIPCANVAS_BGR8
-    case MNG_CANVAS_BGR8    : break;
-#endif
-#ifndef MNG_SKIPCANVAS_BGRX8
-    case MNG_CANVAS_BGRX8   : break;
-#endif
-#ifndef MNG_SKIPCANVAS_RGB565
-    case MNG_CANVAS_RGB565  : break;
-#endif
-#ifndef MNG_SKIPCANVAS_BGR565
-    case MNG_CANVAS_BGR565  : break;
-#endif
-/*    case MNG_CANVAS_RGB16   : break; */
-/*    case MNG_CANVAS_BGR16   : break; */
-/*    case MNG_CANVAS_INDEX8  : break; */
-/*    case MNG_CANVAS_GRAY8   : break; */
-/*    case MNG_CANVAS_GRAY16  : break; */
-/*    case MNG_CANVAS_DX15    : break; */
-/*    case MNG_CANVAS_DX16    : break; */
-    default                 : MNG_ERROR (((mng_datap)hHandle), MNG_INVALIDCNVSTYLE);
-  }
-
-  ((mng_datap)hHandle)->iBkgdstyle = iStyle;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_BKGDSTYLE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_set_bgcolor (mng_handle hHandle,
-                                      mng_uint16 iRed,
-                                      mng_uint16 iGreen,
-                                      mng_uint16 iBlue)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_BGCOLOR, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->iBGred   = iRed;
-  ((mng_datap)hHandle)->iBGgreen = iGreen;
-  ((mng_datap)hHandle)->iBGblue  = iBlue;
-  ((mng_datap)hHandle)->bUseBKGD = MNG_FALSE;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_BGCOLOR, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_set_usebkgd (mng_handle hHandle,
-                                      mng_bool   bUseBKGD)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_USEBKGD, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->bUseBKGD = bUseBKGD;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_USEBKGD, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_set_storechunks (mng_handle hHandle,
-                                          mng_bool   bStorechunks)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_STORECHUNKS, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->bStorechunks = bStorechunks;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_STORECHUNKS, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_set_sectionbreaks (mng_handle hHandle,
-                                            mng_bool   bSectionbreaks)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_SECTIONBREAKS, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->bSectionbreaks = bSectionbreaks;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_SECTIONBREAKS, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_set_cacheplayback (mng_handle hHandle,
-                                            mng_bool   bCacheplayback)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_CACHEPLAYBACK, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-
-  if (((mng_datap)hHandle)->bHasheader)
-    MNG_ERROR (((mng_datap)hHandle), MNG_FUNCTIONINVALID);
-
-  ((mng_datap)hHandle)->bCacheplayback = bCacheplayback;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_CACHEPLAYBACK, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_set_doprogressive (mng_handle hHandle,
-                                            mng_bool   bDoProgressive)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_DOPROGRESSIVE, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-
-  ((mng_datap)hHandle)->bDoProgressive = bDoProgressive;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_DOPROGRESSIVE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_set_crcmode (mng_handle hHandle,
-                                      mng_uint32 iCrcmode)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_CRCMODE, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-
-  ((mng_datap)hHandle)->iCrcmode = iCrcmode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_CRCMODE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-mng_retcode MNG_DECL mng_set_srgb (mng_handle hHandle,
-                                   mng_bool   bIssRGB)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_SRGB, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->bIssRGB = bIssRGB;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_SRGB, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-#ifndef MNG_SKIPCHUNK_iCCP
-mng_retcode MNG_DECL mng_set_outputprofile (mng_handle hHandle,
-                                            mng_pchar  zFilename)
-{
-#ifdef MNG_INCLUDE_LCMS
-  mng_datap pData;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_OUTPUTPROFILE, MNG_LC_START);
-#endif
-
-#ifdef MNG_INCLUDE_LCMS
-  MNG_VALIDHANDLE (hHandle)
-
-  pData = (mng_datap)hHandle;          /* address the structure */
-
-  if (pData->hProf2)                   /* previously defined ? */
-    mnglcms_freeprofile (pData->hProf2);
-                                       /* allocate new CMS profile handle */
-  pData->hProf2 = mnglcms_createfileprofile (zFilename);
-
-  if (!pData->hProf2)                  /* handle error ? */
-    MNG_ERRORL (pData, MNG_LCMS_NOHANDLE);
-#endif /* MNG_INCLUDE_LCMS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_OUTPUTPROFILE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-#ifndef MNG_SKIPCHUNK_iCCP
-mng_retcode MNG_DECL mng_set_outputprofile2 (mng_handle hHandle,
-                                             mng_uint32 iProfilesize,
-                                             mng_ptr    pProfile)
-{
-#ifdef MNG_INCLUDE_LCMS
-  mng_datap pData;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_OUTPUTPROFILE2, MNG_LC_START);
-#endif
-
-#ifdef MNG_INCLUDE_LCMS
-  MNG_VALIDHANDLE (hHandle)
-
-  pData = (mng_datap)hHandle;          /* address the structure */
-
-  if (pData->hProf2)                   /* previously defined ? */
-    mnglcms_freeprofile (pData->hProf2);
-                                       /* allocate new CMS profile handle */
-  pData->hProf2 = mnglcms_creatememprofile (iProfilesize, pProfile);
-
-  if (!pData->hProf2)                  /* handle error ? */
-    MNG_ERRORL (pData, MNG_LCMS_NOHANDLE);
-#endif /* MNG_INCLUDE_LCMS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_OUTPUTPROFILE2, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_set_outputsrgb (mng_handle hHandle)
-{
-#ifdef MNG_INCLUDE_LCMS
-  mng_datap pData;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_OUTPUTSRGB, MNG_LC_START);
-#endif
-
-#ifdef MNG_INCLUDE_LCMS
-  MNG_VALIDHANDLE (hHandle)
-
-  pData = (mng_datap)hHandle;          /* address the structure */
-
-  if (pData->hProf2)                   /* previously defined ? */
-    mnglcms_freeprofile (pData->hProf2);
-                                       /* allocate new CMS profile handle */
-  pData->hProf2 = mnglcms_createsrgbprofile ();
-
-  if (!pData->hProf2)                  /* handle error ? */
-    MNG_ERRORL (pData, MNG_LCMS_NOHANDLE);
-#endif /* MNG_INCLUDE_LCMS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_OUTPUTSRGB, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-mng_retcode MNG_DECL mng_set_srgbprofile (mng_handle hHandle,
-                                          mng_pchar  zFilename)
-{
-#ifdef MNG_INCLUDE_LCMS
-  mng_datap pData;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_SRGBPROFILE2, MNG_LC_START);
-#endif
-
-#ifdef MNG_INCLUDE_LCMS
-  MNG_VALIDHANDLE (hHandle)
-
-  pData = (mng_datap)hHandle;          /* address the structure */
-
-  if (pData->hProf3)                   /* previously defined ? */
-    mnglcms_freeprofile (pData->hProf3);
-                                       /* allocate new CMS profile handle */
-  pData->hProf3 = mnglcms_createfileprofile (zFilename);
-
-  if (!pData->hProf3)                  /* handle error ? */
-    MNG_ERRORL (pData, MNG_LCMS_NOHANDLE);
-#endif /* MNG_INCLUDE_LCMS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_SRGBPROFILE2, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-mng_retcode MNG_DECL mng_set_srgbprofile2 (mng_handle hHandle,
-                                           mng_uint32 iProfilesize,
-                                           mng_ptr    pProfile)
-{
-#ifdef MNG_INCLUDE_LCMS
-  mng_datap pData;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_SRGBPROFILE, MNG_LC_START);
-#endif
-
-#ifdef MNG_INCLUDE_LCMS
-  MNG_VALIDHANDLE (hHandle)
-
-  pData = (mng_datap)hHandle;          /* address the structure */
-
-  if (pData->hProf3)                   /* previously defined ? */
-    mnglcms_freeprofile (pData->hProf3);
-                                       /* allocate new CMS profile handle */
-  pData->hProf3 = mnglcms_creatememprofile (iProfilesize, pProfile);
-
-  if (!pData->hProf3)                  /* handle error ? */
-    MNG_ERRORL (pData, MNG_LCMS_NOHANDLE);
-#endif /* MNG_INCLUDE_LCMS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_SRGBPROFILE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_set_srgbimplicit (mng_handle hHandle)
-{
-#ifdef MNG_INCLUDE_LCMS
-  mng_datap pData;
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_SRGBIMPLICIT, MNG_LC_START);
-#endif
-
-#ifdef MNG_INCLUDE_LCMS
-  MNG_VALIDHANDLE (hHandle)
-
-  pData = (mng_datap)hHandle;          /* address the structure */
-
-  if (pData->hProf3)                   /* previously defined ? */
-    mnglcms_freeprofile (pData->hProf3);
-                                       /* allocate new CMS profile handle */
-  pData->hProf3 = mnglcms_createsrgbprofile ();
-
-  if (!pData->hProf3)                  /* handle error ? */
-    MNG_ERRORL (pData, MNG_LCMS_NOHANDLE);
-#endif /* MNG_INCLUDE_LCMS */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_SRGBIMPLICIT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#if defined(MNG_FULL_CMS) || defined(MNG_GAMMA_ONLY) || defined(MNG_APP_CMS)
-mng_retcode MNG_DECL mng_set_viewgamma (mng_handle hHandle,
-                                        mng_float  dGamma)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_VIEWGAMMA, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->dViewgamma = dGamma;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_VIEWGAMMA, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_set_displaygamma (mng_handle hHandle,
-                                           mng_float  dGamma)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_DISPLAYGAMMA, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->dDisplaygamma = dGamma;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_DISPLAYGAMMA, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_set_dfltimggamma (mng_handle hHandle,
-                                           mng_float  dGamma)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_DFLTIMGGAMMA, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->dDfltimggamma = dGamma;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_DFLTIMGGAMMA, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#if defined(MNG_FULL_CMS) || defined(MNG_GAMMA_ONLY) || defined(MNG_APP_CMS)
-mng_retcode MNG_DECL mng_set_viewgammaint (mng_handle hHandle,
-                                           mng_uint32 iGamma)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_VIEWGAMMA, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->dViewgamma = (mng_float)iGamma / 100000;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_VIEWGAMMA, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_set_displaygammaint (mng_handle hHandle,
-                                              mng_uint32 iGamma)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_DISPLAYGAMMA, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->dDisplaygamma = (mng_float)iGamma / 100000;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_DISPLAYGAMMA, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DFLT_INFO
-mng_retcode MNG_DECL mng_set_dfltimggammaint (mng_handle hHandle,
-                                              mng_uint32 iGamma)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_DFLTIMGGAMMA, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->dDfltimggamma = (mng_float)iGamma / 100000;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_DFLTIMGGAMMA, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIP_MAXCANVAS
-mng_retcode MNG_DECL mng_set_maxcanvaswidth (mng_handle hHandle,
-                                             mng_uint32 iMaxwidth)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_MAXCANVASWIDTH, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->iMaxwidth = iMaxwidth;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_MAXCANVASWIDTH, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_set_maxcanvasheight (mng_handle hHandle,
-                                              mng_uint32 iMaxheight)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_MAXCANVASHEIGHT, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->iMaxheight = iMaxheight;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_MAXCANVASHEIGHT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_set_maxcanvassize (mng_handle hHandle,
-                                            mng_uint32 iMaxwidth,
-                                            mng_uint32 iMaxheight)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_MAXCANVASSIZE, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->iMaxwidth  = iMaxwidth;
-  ((mng_datap)hHandle)->iMaxheight = iMaxheight;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_MAXCANVASSIZE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_ZLIB
-#ifdef MNG_ACCESS_ZLIB
-#ifdef MNG_SUPPORT_WRITE
-mng_retcode MNG_DECL mng_set_zlib_level (mng_handle hHandle,
-                                         mng_int32  iZlevel)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_ZLIB_LEVEL, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->iZlevel = iZlevel;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_ZLIB_LEVEL, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_WRITE */
-#endif /* MNG_ACCESS_ZLIB */
-#endif /* MNG_INCLUDE_ZLIB */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_ZLIB
-#ifdef MNG_ACCESS_ZLIB
-#ifdef MNG_SUPPORT_WRITE
-mng_retcode MNG_DECL mng_set_zlib_method (mng_handle hHandle,
-                                          mng_int32  iZmethod)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_ZLIB_METHOD, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->iZmethod = iZmethod;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_ZLIB_METHOD, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_WRITE */
-#endif /* MNG_ACCESS_ZLIB */
-#endif /* MNG_INCLUDE_ZLIB */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_ZLIB
-#ifdef MNG_ACCESS_ZLIB
-#ifdef MNG_SUPPORT_WRITE
-mng_retcode MNG_DECL mng_set_zlib_windowbits (mng_handle hHandle,
-                                              mng_int32  iZwindowbits)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_ZLIB_WINDOWBITS, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->iZwindowbits = iZwindowbits;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_ZLIB_WINDOWBITS, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_WRITE */
-#endif /* MNG_ACCESS_ZLIB */
-#endif /* MNG_INCLUDE_ZLIB */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_ZLIB
-#ifdef MNG_ACCESS_ZLIB
-#ifdef MNG_SUPPORT_WRITE
-mng_retcode MNG_DECL mng_set_zlib_memlevel (mng_handle hHandle,
-                                            mng_int32  iZmemlevel)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_ZLIB_MEMLEVEL, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->iZmemlevel = iZmemlevel;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_ZLIB_MEMLEVEL, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_WRITE */
-#endif /* MNG_ACCESS_ZLIB */
-#endif /* MNG_INCLUDE_ZLIB */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_ZLIB
-#ifdef MNG_ACCESS_ZLIB
-#ifdef MNG_SUPPORT_WRITE
-mng_retcode MNG_DECL mng_set_zlib_strategy (mng_handle hHandle,
-                                            mng_int32  iZstrategy)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_ZLIB_STRATEGY, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->iZstrategy = iZstrategy;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_ZLIB_STRATEGY, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_WRITE */
-#endif /* MNG_ACCESS_ZLIB */
-#endif /* MNG_INCLUDE_ZLIB */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_ZLIB
-#ifdef MNG_ACCESS_ZLIB
-#ifdef MNG_SUPPORT_WRITE
-mng_retcode MNG_DECL mng_set_zlib_maxidat (mng_handle hHandle,
-                                           mng_uint32 iMaxIDAT)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_ZLIB_MAXIDAT, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->iMaxIDAT = iMaxIDAT;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_ZLIB_MAXIDAT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_WRITE */
-#endif /* MNG_ACCESS_ZLIB */
-#endif /* MNG_INCLUDE_ZLIB */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-#ifdef MNG_ACCESS_JPEG
-#ifdef MNG_SUPPORT_WRITE
-mng_retcode MNG_DECL mng_set_jpeg_dctmethod (mng_handle        hHandle,
-                                             mngjpeg_dctmethod eJPEGdctmethod)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_JPEG_DCTMETHOD, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->eJPEGdctmethod = eJPEGdctmethod;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_JPEG_DCTMETHOD, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif MNG_SUPPORT_WRITE
-#endif /* MNG_ACCESS_JPEG */
-#endif /* MNG_INCLUDE_JNG */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-#ifdef MNG_ACCESS_JPEG
-#ifdef MNG_SUPPORT_WRITE
-mng_retcode MNG_DECL mng_set_jpeg_quality (mng_handle hHandle,
-                                           mng_int32  iJPEGquality)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_JPEG_QUALITY, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->iJPEGquality = iJPEGquality;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_JPEG_QUALITY, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_WRITE */
-#endif /* MNG_ACCESS_JPEG */
-#endif /* MNG_INCLUDE_JNG */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-#ifdef MNG_ACCESS_JPEG
-#ifdef MNG_SUPPORT_WRITE
-mng_retcode MNG_DECL mng_set_jpeg_smoothing (mng_handle hHandle,
-                                             mng_int32  iJPEGsmoothing)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_JPEG_SMOOTHING, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->iJPEGsmoothing = iJPEGsmoothing;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_JPEG_SMOOTHING, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_WRITE */
-#endif /* MNG_ACCESS_JPEG */
-#endif /* MNG_INCLUDE_JNG */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-#ifdef MNG_ACCESS_JPEG
-#ifdef MNG_SUPPORT_WRITE
-mng_retcode MNG_DECL mng_set_jpeg_progressive (mng_handle hHandle,
-                                               mng_bool   bJPEGprogressive)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_JPEG_PROGRESSIVE, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->bJPEGcompressprogr = bJPEGprogressive;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_JPEG_PROGRESSIVE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_WRITE */
-#endif /* MNG_ACCESS_JPEG */
-#endif /* MNG_INCLUDE_JNG */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-#ifdef MNG_ACCESS_JPEG
-#ifdef MNG_SUPPORT_WRITE
-mng_retcode MNG_DECL mng_set_jpeg_optimized (mng_handle hHandle,
-                                             mng_bool   bJPEGoptimized)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_JPEG_OPTIMIZED, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->bJPEGcompressopt = bJPEGoptimized;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_JPEG_OPTIMIZED, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_WRITE */
-#endif /* MNG_ACCESS_JPEG */
-#endif /* MNG_INCLUDE_JNG */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-#ifdef MNG_ACCESS_JPEG
-#ifdef MNG_SUPPORT_WRITE
-mng_retcode MNG_DECL mng_set_jpeg_maxjdat (mng_handle hHandle,
-                                           mng_uint32 iMaxJDAT)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_JPEG_MAXJDAT, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->iMaxJDAT = iMaxJDAT;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_JPEG_MAXJDAT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_WRITE */
-#endif /* MNG_ACCESS_JPEG */
-#endif /* MNG_INCLUDE_JNG */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_READ
-mng_retcode MNG_DECL mng_set_suspensionmode (mng_handle hHandle,
-                                             mng_bool   bSuspensionmode)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_SUSPENSIONMODE, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-
-  if (((mng_datap)hHandle)->bReading)  /* we must NOT be reading !!! */
-    MNG_ERROR ((mng_datap)hHandle, MNG_FUNCTIONINVALID);
-
-  ((mng_datap)hHandle)->bSuspensionmode = bSuspensionmode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_SUSPENSIONMODE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_READ */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-mng_retcode MNG_DECL mng_set_speed (mng_handle    hHandle,
-                                    mng_speedtype iSpeed)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_SPEED, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  ((mng_datap)hHandle)->iSpeed = iSpeed;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_SPEED, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* *  Property get functions                                                * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-mng_ptr MNG_DECL mng_get_userdata (mng_handle hHandle)
-{                            /* no tracing in here to prevent recursive calls */
-  MNG_VALIDHANDLEX (hHandle)
-  return ((mng_datap)hHandle)->pUserdata;
-}
-
-/* ************************************************************************** */
-
-mng_imgtype MNG_DECL mng_get_sigtype (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_SIGTYPE, MNG_LC_START);
-#endif
-
-  if ((hHandle == 0) || (((mng_datap)hHandle)->iMagic != MNG_MAGIC))
-    return mng_it_unknown;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_SIGTYPE, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->eSigtype;
-}
-
-/* ************************************************************************** */
-
-mng_imgtype MNG_DECL mng_get_imagetype (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_IMAGETYPE, MNG_LC_START);
-#endif
-
-  if ((hHandle == 0) || (((mng_datap)hHandle)->iMagic != MNG_MAGIC))
-    return mng_it_unknown;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_IMAGETYPE, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->eImagetype;
-}
-
-/* ************************************************************************** */
-
-mng_uint32 MNG_DECL mng_get_imagewidth (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_IMAGEWIDTH, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_IMAGEWIDTH, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->iWidth;
-}
-
-/* ************************************************************************** */
-
-mng_uint32 MNG_DECL mng_get_imageheight (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_IMAGEWIDTH, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_IMAGEHEIGHT, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->iHeight;
-}
-
-/* ************************************************************************** */
-
-mng_uint32 MNG_DECL mng_get_ticks (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_TICKS, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_TICKS, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->iTicks;
-}
-
-/* ************************************************************************** */
-
-mng_uint32 MNG_DECL mng_get_framecount (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_FRAMECOUNT, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_FRAMECOUNT, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->iFramecount;
-}
-
-/* ************************************************************************** */
-
-mng_uint32 MNG_DECL mng_get_layercount (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_LAYERCOUNT, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_LAYERCOUNT, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->iLayercount;
-}
-
-/* ************************************************************************** */
-
-mng_uint32 MNG_DECL mng_get_playtime (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_PLAYTIME, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_PLAYTIME, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->iPlaytime;
-}
-
-/* ************************************************************************** */
-
-mng_uint32 MNG_DECL mng_get_simplicity (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_SIMPLICITY, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_SIMPLICITY, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->iSimplicity;
-}
-
-/* ************************************************************************** */
-
-mng_uint8 MNG_DECL mng_get_bitdepth (mng_handle hHandle)
-{
-  mng_uint8 iRslt;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_BITDEPTH, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-  if (((mng_datap)hHandle)->eImagetype == mng_it_png)
-    iRslt = ((mng_datap)hHandle)->iBitdepth;
-  else
-#ifdef MNG_INCLUDE_JNG
-  if (((mng_datap)hHandle)->eImagetype == mng_it_jng)
-    iRslt = ((mng_datap)hHandle)->iJHDRimgbitdepth;
-  else
-#endif
-    iRslt = 0;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_BITDEPTH, MNG_LC_END);
-#endif
-
-  return iRslt;
-}
-
-/* ************************************************************************** */
-
-mng_uint8 MNG_DECL mng_get_colortype (mng_handle hHandle)
-{
-  mng_uint8 iRslt;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_COLORTYPE, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-  if (((mng_datap)hHandle)->eImagetype == mng_it_png)
-    iRslt = ((mng_datap)hHandle)->iColortype;
-  else
-#ifdef MNG_INCLUDE_JNG
-  if (((mng_datap)hHandle)->eImagetype == mng_it_jng)
-    iRslt = ((mng_datap)hHandle)->iJHDRcolortype;
-  else
-#endif
-    iRslt = 0;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_COLORTYPE, MNG_LC_END);
-#endif
-
-  return iRslt;
-}
-
-/* ************************************************************************** */
-
-mng_uint8 MNG_DECL mng_get_compression (mng_handle hHandle)
-{
-  mng_uint8 iRslt;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_COMPRESSION, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-  if (((mng_datap)hHandle)->eImagetype == mng_it_png)
-    iRslt = ((mng_datap)hHandle)->iCompression;
-  else
-#ifdef MNG_INCLUDE_JNG
-  if (((mng_datap)hHandle)->eImagetype == mng_it_jng)
-    iRslt = ((mng_datap)hHandle)->iJHDRimgcompression;
-  else
-#endif
-    iRslt = 0;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_COMPRESSION, MNG_LC_END);
-#endif
-
-  return iRslt;
-}
-
-/* ************************************************************************** */
-
-mng_uint8 MNG_DECL mng_get_filter (mng_handle hHandle)
-{
-  mng_uint8 iRslt;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_FILTER, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-  if (((mng_datap)hHandle)->eImagetype == mng_it_png)
-    iRslt = ((mng_datap)hHandle)->iFilter;
-  else
-    iRslt = 0;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_FILTER, MNG_LC_END);
-#endif
-
-  return iRslt;
-}
-
-/* ************************************************************************** */
-
-mng_uint8 MNG_DECL mng_get_interlace (mng_handle hHandle)
-{
-  mng_uint8 iRslt;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_INTERLACE, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-  if (((mng_datap)hHandle)->eImagetype == mng_it_png)
-    iRslt = ((mng_datap)hHandle)->iInterlace;
-  else
-#ifdef MNG_INCLUDE_JNG
-  if (((mng_datap)hHandle)->eImagetype == mng_it_jng)
-    iRslt = ((mng_datap)hHandle)->iJHDRimginterlace;
-  else
-#endif
-    iRslt = 0;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_INTERLACE, MNG_LC_END);
-#endif
-
-  return iRslt;
-}
-
-/* ************************************************************************** */
-
-mng_uint8 MNG_DECL mng_get_alphabitdepth (mng_handle hHandle)
-{
-  mng_uint8 iRslt;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ALPHABITDEPTH, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_INCLUDE_JNG
-  if (((mng_datap)hHandle)->eImagetype == mng_it_jng)
-    iRslt = ((mng_datap)hHandle)->iJHDRalphabitdepth;
-  else
-#endif
-    iRslt = 0;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ALPHABITDEPTH, MNG_LC_END);
-#endif
-
-  return iRslt;
-}
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-mng_uint8 MNG_DECL mng_get_refreshpass (mng_handle hHandle)
-{
-  mng_uint8 iRslt;
-  mng_datap pData;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_REFRESHPASS, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-  pData = (mng_datap)hHandle;
-                                       /* for PNG we know the exact pass */
-  if ((pData->eImagetype == mng_it_png) && (pData->iPass >= 0))
-    iRslt = pData->iPass;
-#ifdef MNG_INCLUDE_JNG
-  else                                 /* for JNG we'll fake it... */
-  if ((pData->eImagetype == mng_it_jng) &&
-      (pData->bJPEGhasheader) && (pData->bJPEGdecostarted) &&
-      (pData->bJPEGprogressive))
-  {
-    if (pData->pJPEGdinfo->input_scan_number <= 1)
-      iRslt = 0;                       /* first pass (I think...) */
-    else
-    if (jpeg_input_complete (pData->pJPEGdinfo))
-      iRslt = 7;                       /* input complete; aka final pass */
-    else
-      iRslt = 3;                       /* anything between 0 and 7 will do */
-
-  }
-#endif
-  else
-    iRslt = 0;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_REFRESHPASS, MNG_LC_END);
-#endif
-
-  return iRslt;
-}
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-mng_uint8 MNG_DECL mng_get_alphacompression (mng_handle hHandle)
-{
-  mng_uint8 iRslt;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ALPHACOMPRESSION, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_INCLUDE_JNG
-  if (((mng_datap)hHandle)->eImagetype == mng_it_jng)
-    iRslt = ((mng_datap)hHandle)->iJHDRalphacompression;
-  else
-#endif
-    iRslt = 0;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ALPHACOMPRESSION, MNG_LC_END);
-#endif
-
-  return iRslt;
-}
-
-/* ************************************************************************** */
-
-mng_uint8 MNG_DECL mng_get_alphafilter (mng_handle hHandle)
-{
-  mng_uint8 iRslt;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ALPHAFILTER, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_INCLUDE_JNG
-  if (((mng_datap)hHandle)->eImagetype == mng_it_jng)
-    iRslt = ((mng_datap)hHandle)->iJHDRalphafilter;
-  else
-#endif
-    iRslt = 0;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ALPHAFILTER, MNG_LC_END);
-#endif
-
-  return iRslt;
-}
-
-/* ************************************************************************** */
-
-mng_uint8 MNG_DECL mng_get_alphainterlace (mng_handle hHandle)
-{
-  mng_uint8 iRslt;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ALPHAINTERLACE, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_INCLUDE_JNG
-  if (((mng_datap)hHandle)->eImagetype == mng_it_jng)
-    iRslt = ((mng_datap)hHandle)->iJHDRalphainterlace;
-  else
-#endif
-    iRslt = 0;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ALPHAINTERLACE, MNG_LC_END);
-#endif
-
-  return iRslt;
-}
-
-/* ************************************************************************** */
-
-mng_uint8 MNG_DECL mng_get_alphadepth (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ALPHADEPTH, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ALPHADEPTH, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->iAlphadepth;
-}
-
-/* ************************************************************************** */
-
-mng_uint32 MNG_DECL mng_get_canvasstyle (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_CANVASSTYLE, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_CANVASSTYLE, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->iCanvasstyle;
-}
-
-/* ************************************************************************** */
-
-mng_uint32 MNG_DECL mng_get_bkgdstyle (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_BKGDSTYLE, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_BKGDSTYLE, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->iBkgdstyle;
-}
-
-/* ************************************************************************** */
-
-mng_retcode MNG_DECL mng_get_bgcolor (mng_handle  hHandle,
-                                      mng_uint16* iRed,
-                                      mng_uint16* iGreen,
-                                      mng_uint16* iBlue)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GET_BGCOLOR, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-  *iRed   = ((mng_datap)hHandle)->iBGred;
-  *iGreen = ((mng_datap)hHandle)->iBGgreen;
-  *iBlue  = ((mng_datap)hHandle)->iBGblue;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (((mng_datap)hHandle), MNG_FN_GET_BGCOLOR, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_bool MNG_DECL mng_get_usebkgd (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEB (((mng_datap)hHandle), MNG_FN_GET_USEBKGD, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEB (((mng_datap)hHandle), MNG_FN_GET_USEBKGD, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->bUseBKGD;
-}
-
-/* ************************************************************************** */
-
-mng_bool MNG_DECL mng_get_storechunks (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEB (((mng_datap)hHandle), MNG_FN_GET_STORECHUNKS, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEB (((mng_datap)hHandle), MNG_FN_GET_STORECHUNKS, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->bStorechunks;
-}
-
-/* ************************************************************************** */
-
-mng_bool MNG_DECL mng_get_sectionbreaks (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEB (((mng_datap)hHandle), MNG_FN_GET_SECTIONBREAKS, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEB (((mng_datap)hHandle), MNG_FN_GET_SECTIONBREAKS, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->bSectionbreaks;
-}
-
-/* ************************************************************************** */
-
-mng_bool MNG_DECL mng_get_cacheplayback (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEB (((mng_datap)hHandle), MNG_FN_GET_CACHEPLAYBACK, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEB (((mng_datap)hHandle), MNG_FN_GET_CACHEPLAYBACK, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->bCacheplayback;
-}
-
-/* ************************************************************************** */
-
-mng_bool MNG_DECL mng_get_doprogressive (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEB (((mng_datap)hHandle), MNG_FN_GET_DOPROGRESSIVE, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEB (((mng_datap)hHandle), MNG_FN_GET_DOPROGRESSIVE, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->bDoProgressive;
-}
-
-/* ************************************************************************** */
-
-mng_uint32 MNG_DECL mng_get_crcmode (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEB (((mng_datap)hHandle), MNG_FN_GET_CRCMODE, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEB (((mng_datap)hHandle), MNG_FN_GET_CRCMODE, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->iCrcmode;
-}
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-mng_bool MNG_DECL mng_get_srgb (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEB (((mng_datap)hHandle), MNG_FN_GET_SRGB, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEB (((mng_datap)hHandle), MNG_FN_GET_SRGB, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->bIssRGB;
-}
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-
-#if defined(MNG_FULL_CMS) || defined(MNG_GAMMA_ONLY) || defined(MNG_APP_CMS)
-mng_float MNG_DECL mng_get_viewgamma (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_VIEWGAMMA, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_VIEWGAMMA, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->dViewgamma;
-}
-#endif
-
-/* ************************************************************************** */
-
-#if defined(MNG_FULL_CMS) || defined(MNG_GAMMA_ONLY) || defined(MNG_APP_CMS)
-mng_float MNG_DECL mng_get_displaygamma (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_DISPLAYGAMMA, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_DISPLAYGAMMA, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->dDisplaygamma;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DFLT_INFO
-#if defined(MNG_FULL_CMS) || defined(MNG_GAMMA_ONLY) || defined(MNG_APP_CMS)
-mng_float MNG_DECL mng_get_dfltimggamma (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_DFLTIMGGAMMA, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_DFLTIMGGAMMA, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->dDfltimggamma;
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#if defined(MNG_FULL_CMS) || defined(MNG_GAMMA_ONLY) || defined(MNG_APP_CMS)
-mng_uint32 MNG_DECL mng_get_viewgammaint (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_VIEWGAMMA, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_VIEWGAMMA, MNG_LC_END);
-#endif
-
-  return (mng_uint32)(((mng_datap)hHandle)->dViewgamma * 100000);
-}
-#endif
-
-/* ************************************************************************** */
-
-#if defined(MNG_FULL_CMS) || defined(MNG_GAMMA_ONLY) || defined(MNG_APP_CMS)
-mng_uint32 MNG_DECL mng_get_displaygammaint (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_DISPLAYGAMMA, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_DISPLAYGAMMA, MNG_LC_END);
-#endif
-
-  return (mng_uint32)(((mng_datap)hHandle)->dDisplaygamma * 100000);
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_NO_DFLT_INFO
-#if defined(MNG_FULL_CMS) || defined(MNG_GAMMA_ONLY) || defined(MNG_APP_CMS)
-mng_uint32 MNG_DECL mng_get_dfltimggammaint (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_DFLTIMGGAMMA, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_DFLTIMGGAMMA, MNG_LC_END);
-#endif
-
-  return (mng_uint32)(((mng_datap)hHandle)->dDfltimggamma * 100000);
-}
-#endif
-#endif
-
-/* ************************************************************************** */
-
-#ifndef MNG_SKIP_MAXCANVAS
-mng_uint32 MNG_DECL mng_get_maxcanvaswidth (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_MAXCANVASWIDTH, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_MAXCANVASWIDTH, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->iMaxwidth;
-}
-
-/* ************************************************************************** */
-
-mng_uint32 MNG_DECL mng_get_maxcanvasheight (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_MAXCANVASHEIGHT, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_MAXCANVASHEIGHT, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->iMaxheight;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_ZLIB
-#ifdef MNG_ACCESS_ZLIB
-mng_int32 MNG_DECL mng_get_zlib_level (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ZLIB_LEVEL, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ZLIB_LEVEL, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->iZlevel;
-}
-#endif /* MNG_ACCESS_ZLIB */
-#endif /* MNG_INCLUDE_ZLIB */
-
-/* ************************************************************************** */
-#ifdef MNG_INCLUDE_ZLIB
-#ifdef MNG_ACCESS_ZLIB
-mng_int32 MNG_DECL mng_get_zlib_method (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ZLIB_METHOD, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ZLIB_METHOD, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->iZmethod;
-}
-
-#endif /* MNG_ACCESS_ZLIB */
-#endif /* MNG_INCLUDE_ZLIB */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_ZLIB
-#ifdef MNG_ACCESS_ZLIB
-mng_int32 MNG_DECL mng_get_zlib_windowbits (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ZLIB_WINDOWBITS, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ZLIB_WINDOWBITS, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->iZwindowbits;
-}
-#endif /* MNG_ACCESS_ZLIB */
-#endif /* MNG_INCLUDE_ZLIB */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_ZLIB
-#ifdef MNG_ACCESS_ZLIB
-mng_int32 MNG_DECL mng_get_zlib_memlevel (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ZLIB_MEMLEVEL, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ZLIB_MEMLEVEL, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->iZmemlevel;
-}
-#endif /* MNG_ACCESS_ZLIB */
-#endif /* MNG_INCLUDE_ZLIB */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_ZLIB
-#ifdef MNG_ACCESS_ZLIB
-mng_int32 MNG_DECL mng_get_zlib_strategy (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ZLIB_STRATEGY, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ZLIB_STRATEGY, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->iZstrategy;
-}
-#endif /* MNG_ACCESS_ZLIB */
-#endif /* MNG_INCLUDE_ZLIB */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_ZLIB
-#ifdef MNG_ACCESS_ZLIB
-mng_uint32 MNG_DECL mng_get_zlib_maxidat (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ZLIB_MAXIDAT, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ZLIB_MAXIDAT, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->iMaxIDAT;
-}
-#endif /* MNG_ACCESS_ZLIB */
-#endif /* MNG_INCLUDE_ZLIB */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-#ifdef MNG_ACCESS_JPEG
-mngjpeg_dctmethod MNG_DECL mng_get_jpeg_dctmethod (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_JPEG_DCTMETHOD, MNG_LC_START);
-#endif
-
-  if ((hHandle == 0) || (((mng_datap)hHandle)->iMagic != MNG_MAGIC))
-    return JDCT_ISLOW;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_JPEG_DCTMETHOD, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->eJPEGdctmethod;
-}
-#endif /* MNG_ACCESS_JPEG */
-#endif /* MNG_INCLUDE_JNG */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-#ifdef MNG_ACCESS_JPEG
-mng_int32 MNG_DECL mng_get_jpeg_quality (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_JPEG_QUALITY, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_JPEG_QUALITY, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->iJPEGquality;
-}
-#endif /* MNG_ACCESS_JPEG */
-#endif /* MNG_INCLUDE_JNG */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-#ifdef MNG_ACCESS_JPEG
-mng_int32 MNG_DECL mng_get_jpeg_smoothing (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_JPEG_SMOOTHING, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_JPEG_SMOOTHING, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->iJPEGsmoothing;
-}
-#endif /* MNG_ACCESS_JPEG */
-#endif /* MNG_INCLUDE_JNG */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-#ifdef MNG_ACCESS_JPEG
-mng_bool MNG_DECL mng_get_jpeg_progressive (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_JPEG_PROGRESSIVE, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_JPEG_PROGRESSIVE, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->bJPEGcompressprogr;
-}
-#endif /* MNG_ACCESS_JPEG */
-#endif /* MNG_INCLUDE_JNG */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-#ifdef MNG_ACCESS_JPEG
-mng_bool MNG_DECL mng_get_jpeg_optimized (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_JPEG_OPTIMIZED, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_JPEG_OPTIMIZED, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->bJPEGcompressopt;
-}
-#endif /* MNG_ACCESS_JPEG */
-#endif /* MNG_INCLUDE_JNG */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-#ifdef MNG_ACCESS_JPEG
-mng_uint32 MNG_DECL mng_get_jpeg_maxjdat (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_JPEG_MAXJDAT, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_JPEG_MAXJDAT, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->iMaxJDAT;
-}
-#endif /* MNG_ACCESS_JPEG */
-#endif /* MNG_INCLUDE_JNG */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_READ
-mng_bool MNG_DECL mng_get_suspensionmode (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_SUSPENSIONMODE, MNG_LC_START);
-#endif
-
-  if ((hHandle == 0) || (((mng_datap)hHandle)->iMagic != MNG_MAGIC))
-    return MNG_FALSE;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_SUSPENSIONMODE, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->bSuspensionmode;
-}
-#endif /* MNG_SUPPORT_READ */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-mng_speedtype MNG_DECL mng_get_speed (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_SPEED, MNG_LC_START);
-#endif
-
-  if ((hHandle == 0) || (((mng_datap)hHandle)->iMagic != MNG_MAGIC))
-    return mng_st_normal;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_SPEED, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->iSpeed;
-}
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-
-mng_uint32 MNG_DECL mng_get_imagelevel (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_IMAGELEVEL, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLEX (hHandle)
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_IMAGELEVEL, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->iImagelevel;
-}
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-mng_retcode MNG_DECL mng_get_lastbackchunk (mng_handle  hHandle,
-                                            mng_uint16* iRed,
-                                            mng_uint16* iGreen,
-                                            mng_uint16* iBlue,
-                                            mng_uint8*  iMandatory)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_LASTBACKCHUNK, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-
-  if (((mng_datap)hHandle)->eImagetype != mng_it_mng)
-    MNG_ERROR (((mng_datap)hHandle), MNG_FUNCTIONINVALID);
-
-  *iRed       = ((mng_datap)hHandle)->iBACKred;
-  *iGreen     = ((mng_datap)hHandle)->iBACKgreen;
-  *iBlue      = ((mng_datap)hHandle)->iBACKblue;
-  *iMandatory = ((mng_datap)hHandle)->iBACKmandatory;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_LASTBACKCHUNK, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-mng_retcode MNG_DECL mng_get_lastseekname (mng_handle hHandle,
-                                           mng_pchar  zSegmentname)
-{
-  mng_datap pData;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_LASTSEEKNAME, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-
-  pData = (mng_datap)hHandle;
-                                       /* only allowed for MNG ! */
-  if (pData->eImagetype != mng_it_mng)
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID);
-
-  if (pData->pLastseek)                /* is there a last SEEK ? */
-  {
-    mng_ani_seekp pSEEK = (mng_ani_seekp)pData->pLastseek;
-
-    if (pSEEK->iSegmentnamesize)       /* copy the name if there is one */
-      MNG_COPY (zSegmentname, pSEEK->zSegmentname, pSEEK->iSegmentnamesize);
-
-    *(((mng_uint8p)zSegmentname) + pSEEK->iSegmentnamesize) = 0;
-  }
-  else
-  {                                    /* return an empty string */
-    *((mng_uint8p)zSegmentname) = 0;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_LASTSEEKNAME, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-mng_uint32 MNG_DECL mng_get_currframdelay (mng_handle hHandle)
-{
-  mng_datap  pData;
-  mng_uint32 iRslt;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_CURRFRAMDELAY, MNG_LC_START);
-#endif
-
-  MNG_VALIDHANDLE (hHandle)
-
-  pData = (mng_datap)hHandle;
-                                       /* only allowed for MNG ! */
-  if (pData->eImagetype != mng_it_mng)
-    MNG_ERROR (pData, MNG_FUNCTIONINVALID);
-
-  iRslt = pData->iFramedelay;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_CURRFRAMDELAY, MNG_LC_END);
-#endif
-
-  return iRslt;
-}
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-mng_uint32 MNG_DECL mng_get_starttime (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_STARTTIME, MNG_LC_START);
-#endif
-
-  if ((hHandle == 0) || (((mng_datap)hHandle)->iMagic != MNG_MAGIC))
-    return mng_st_normal;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_STARTTIME, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->iStarttime;
-}
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-mng_uint32 MNG_DECL mng_get_runtime (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_RUNTIME, MNG_LC_START);
-#endif
-
-  if ((hHandle == 0) || (((mng_datap)hHandle)->iMagic != MNG_MAGIC))
-    return mng_st_normal;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_RUNTIME, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->iRuntime;
-}
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-#ifndef MNG_NO_CURRENT_INFO
-mng_uint32 MNG_DECL mng_get_currentframe (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_CURRENTFRAME, MNG_LC_START);
-#endif
-
-  if ((hHandle == 0) || (((mng_datap)hHandle)->iMagic != MNG_MAGIC))
-    return mng_st_normal;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_CURRENTFRAME, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->iFrameseq;
-}
-#endif
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-#ifndef MNG_NO_CURRENT_INFO
-mng_uint32 MNG_DECL mng_get_currentlayer (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_CURRENTLAYER, MNG_LC_START);
-#endif
-
-  if ((hHandle == 0) || (((mng_datap)hHandle)->iMagic != MNG_MAGIC))
-    return mng_st_normal;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_CURRENTLAYER, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->iLayerseq;
-}
-#endif
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-#ifndef MNG_NO_CURRENT_INFO
-mng_uint32 MNG_DECL mng_get_currentplaytime (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_CURRENTPLAYTIME, MNG_LC_START);
-#endif
-
-  if ((hHandle == 0) || (((mng_datap)hHandle)->iMagic != MNG_MAGIC))
-    return mng_st_normal;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_CURRENTPLAYTIME, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->iFrametime;
-}
-#endif
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-#ifndef MNG_NO_CURRENT_INFO
-mng_uint32 MNG_DECL mng_get_totalframes (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_TOTALFRAMES, MNG_LC_START);
-#endif
-
-  if ((hHandle == 0) || (((mng_datap)hHandle)->iMagic != MNG_MAGIC))
-    return mng_st_normal;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_TOTALFRAMES, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->iTotalframes;
-}
-#endif
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-#ifndef MNG_NO_CURRENT_INFO
-mng_uint32 MNG_DECL mng_get_totallayers (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_TOTALLAYERS, MNG_LC_START);
-#endif
-
-  if ((hHandle == 0) || (((mng_datap)hHandle)->iMagic != MNG_MAGIC))
-    return mng_st_normal;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_TOTALLAYERS, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->iTotallayers;
-}
-#endif
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-#ifndef MNG_NO_CURRENT_INFO
-mng_uint32 MNG_DECL mng_get_totalplaytime (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_TOTALPLAYTIME, MNG_LC_START);
-#endif
-
-  if ((hHandle == 0) || (((mng_datap)hHandle)->iMagic != MNG_MAGIC))
-    return mng_st_normal;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_TOTALPLAYTIME, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->iTotalplaytime;
-}
-#endif
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-
-mng_bool MNG_DECL mng_status_error (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_STATUS_ERROR, MNG_LC_START);
-#endif
-
-  if ((hHandle == 0) || (((mng_datap)hHandle)->iMagic != MNG_MAGIC))
-    return MNG_FALSE;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_STATUS_ERROR, MNG_LC_END);
-#endif
-
-  return (mng_bool)((mng_datap)hHandle)->iErrorcode;
-}
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_READ
-mng_bool MNG_DECL mng_status_reading (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_STATUS_READING, MNG_LC_START);
-#endif
-
-  if ((hHandle == 0) || (((mng_datap)hHandle)->iMagic != MNG_MAGIC))
-    return MNG_FALSE;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_STATUS_READING, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->bReading;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_READ
-mng_bool MNG_DECL mng_status_suspendbreak (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_STATUS_SUSPENDBREAK, MNG_LC_START);
-#endif
-
-  if ((hHandle == 0) || (((mng_datap)hHandle)->iMagic != MNG_MAGIC))
-    return MNG_FALSE;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_STATUS_SUSPENDBREAK, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->bSuspended;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_WRITE
-mng_bool MNG_DECL mng_status_creating (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_STATUS_CREATING, MNG_LC_START);
-#endif
-
-  if ((hHandle == 0) || (((mng_datap)hHandle)->iMagic != MNG_MAGIC))
-    return MNG_FALSE;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_STATUS_CREATING, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->bCreating;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_WRITE
-mng_bool MNG_DECL mng_status_writing (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_STATUS_WRITING, MNG_LC_START);
-#endif
-
-  if ((hHandle == 0) || (((mng_datap)hHandle)->iMagic != MNG_MAGIC))
-    return MNG_FALSE;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_STATUS_WRITING, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->bWriting;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-mng_bool MNG_DECL mng_status_displaying (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_STATUS_DISPLAYING, MNG_LC_START);
-#endif
-
-  if ((hHandle == 0) || (((mng_datap)hHandle)->iMagic != MNG_MAGIC))
-    return MNG_FALSE;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_STATUS_DISPLAYING, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->bDisplaying;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-mng_bool MNG_DECL mng_status_running (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_STATUS_RUNNING, MNG_LC_START);
-#endif
-
-  if ((hHandle == 0) || (((mng_datap)hHandle)->iMagic != MNG_MAGIC))
-    return MNG_FALSE;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_STATUS_RUNNING, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->bRunning;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-mng_bool MNG_DECL mng_status_timerbreak (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_STATUS_TIMERBREAK, MNG_LC_START);
-#endif
-
-  if ((hHandle == 0) || (((mng_datap)hHandle)->iMagic != MNG_MAGIC))
-    return MNG_FALSE;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_STATUS_TIMERBREAK, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->bTimerset;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DYNAMICMNG
-mng_bool MNG_DECL mng_status_dynamic (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_STATUS_DYNAMIC, MNG_LC_START);
-#endif
-
-  if ((hHandle == 0) || (((mng_datap)hHandle)->iMagic != MNG_MAGIC))
-    return MNG_FALSE;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_STATUS_DYNAMIC, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->bDynamic;
-}
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DYNAMICMNG
-mng_bool MNG_DECL mng_status_runningevent (mng_handle hHandle)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_STATUS_RUNNINGEVENT, MNG_LC_START);
-#endif
-
-  if ((hHandle == 0) || (((mng_datap)hHandle)->iMagic != MNG_MAGIC))
-    return MNG_FALSE;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACEX (((mng_datap)hHandle), MNG_FN_STATUS_RUNNINGEVENT, MNG_LC_END);
-#endif
-
-  return ((mng_datap)hHandle)->bRunningevent;
-}
-#endif
-
-/* ************************************************************************** */
-/* * end of file                                                            * */
-/* ************************************************************************** */
-
diff --git a/Source/LibMNG/libmng_read.c b/Source/LibMNG/libmng_read.c
deleted file mode 100644
index 3a6e49f..0000000
--- a/Source/LibMNG/libmng_read.c
+++ /dev/null
@@ -1,1369 +0,0 @@
-/* ************************************************************************** */
-/* *             For conditions of distribution and use,                    * */
-/* *                see copyright notice in libmng.h                        * */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * project   : libmng                                                     * */
-/* * file      : libmng_read.c             copyright (c) 2000-2007 G.Juyn   * */
-/* * version   : 1.0.10                                                     * */
-/* *                                                                        * */
-/* * purpose   : Read logic (implementation)                                * */
-/* *                                                                        * */
-/* * author    : G.Juyn                                                     * */
-/* *                                                                        * */
-/* * comment   : implementation of the high-level read logic                * */
-/* *                                                                        * */
-/* * changes   : 0.5.1 - 05/08/2000 - G.Juyn                                * */
-/* *             - changed strict-ANSI stuff                                * */
-/* *             0.5.1 - 05/11/2000 - G.Juyn                                * */
-/* *             - added callback error-reporting support                   * */
-/* *             0.5.1 - 05/12/2000 - G.Juyn                                * */
-/* *             - changed trace to macro for callback error-reporting      * */
-/* *                                                                        * */
-/* *             0.5.2 - 05/19/2000 - G.Juyn                                * */
-/* *             - cleaned up some code regarding mixed support             * */
-/* *             0.5.2 - 05/20/2000 - G.Juyn                                * */
-/* *             - added support for JNG                                    * */
-/* *             0.5.2 - 05/31/2000 - G.Juyn                                * */
-/* *             - fixed up punctuation (contribution by Tim Rowley)        * */
-/* *                                                                        * */
-/* *             0.5.3 - 06/16/2000 - G.Juyn                                * */
-/* *             - changed progressive-display processing                   * */
-/* *                                                                        * */
-/* *             0.9.1 - 07/08/2000 - G.Juyn                                * */
-/* *             - changed read-processing for improved I/O-suspension      * */
-/* *             0.9.1 - 07/14/2000 - G.Juyn                                * */
-/* *             - changed EOF processing behavior                          * */
-/* *             0.9.1 - 07/14/2000 - G.Juyn                                * */
-/* *             - changed default readbuffer size from 1024 to 4200        * */
-/* *                                                                        * */
-/* *             0.9.2 - 07/27/2000 - G.Juyn                                * */
-/* *             - B110320 - fixed GCC warning about mix-sized pointer math * */
-/* *             0.9.2 - 07/31/2000 - G.Juyn                                * */
-/* *             - B110546 - fixed for improperly returning UNEXPECTEDEOF   * */
-/* *             0.9.2 - 08/04/2000 - G.Juyn                                * */
-/* *             - B111096 - fixed large-buffer read-suspension             * */
-/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
-/* *             - changed file-prefixes                                    * */
-/* *                                                                        * */
-/* *             0.9.3 - 08/26/2000 - G.Juyn                                * */
-/* *             - added MAGN chunk                                         * */
-/* *             0.9.3 - 10/11/2000 - G.Juyn                                * */
-/* *             - removed test-MaGN                                        * */
-/* *             0.9.3 - 10/16/2000 - G.Juyn                                * */
-/* *             - added support for JDAA                                   * */
-/* *                                                                        * */
-/* *             0.9.5 - 01/23/2001 - G.Juyn                                * */
-/* *             - fixed timing-problem with switching framing_modes        * */
-/* *                                                                        * */
-/* *             1.0.4 - 06/22/2002 - G.Juyn                                * */
-/* *             - B495443 - incorrect suspend check in read_databuffer     * */
-/* *                                                                        * */
-/* *             1.0.5 - 07/04/2002 - G.Juyn                                * */
-/* *             - added errorcode for extreme chunk-sizes                  * */
-/* *             1.0.5 - 07/08/2002 - G.Juyn                                * */
-/* *             - B578572 - removed eMNGma hack (thanks Dimitri!)          * */
-/* *             1.0.5 - 07/16/2002 - G.Juyn                                * */
-/* *             - B581625 - large chunks fail with suspension reads        * */
-/* *             1.0.5 - 08/19/2002 - G.Juyn                                * */
-/* *             - B597134 - libmng pollutes the linker namespace           * */
-/* *             - added HLAPI function to copy chunks                      * */
-/* *             1.0.5 - 09/16/2002 - G.Juyn                                * */
-/* *             - added event handling for dynamic MNG                     * */
-/* *                                                                        * */
-/* *             1.0.6 - 05/25/2003 - G.R-P                                 * */
-/* *             - added MNG_SKIPCHUNK_cHNK footprint optimizations         * */
-/* *             1.0.6 - 07/07/2003 - G.R-P                                 * */
-/* *             - added MNG_NO_DELTA_PNG reduction                         * */
-/* *             - skip additional code when MNG_INCLUDE_JNG is not enabled * */
-/* *             1.0.6 - 07/29/2003 - G.R-P                                 * */
-/* *             - added conditionals around PAST chunk support             * */
-/* *             1.0.6 - 08/17/2003 - G.R-P                                 * */
-/* *             - added conditionals around non-VLC chunk support          * */
-/* *                                                                        * */
-/* *             1.0.7 - 03/10/2004 - G.R-P                                 * */
-/* *             - added conditionals around openstream/closestream         * */
-/* *                                                                        * */
-/* *             1.0.8 - 04/08/2004 - G.Juyn                                * */
-/* *             - added CRC existence & checking flags                     * */
-/* *             1.0.8 - 04/11/2004 - G.Juyn                                * */
-/* *             - added data-push mechanisms for specialized decoders      * */
-/* *             1.0.8 - 07/06/2004 - G.R-P                                 * */
-/* *             - defend against using undefined closestream function      * */
-/* *             1.0.8 - 07/28/2004 - G.R-P                                 * */
-/* *             - added check for extreme chunk-lengths                    * */
-/* *                                                                        * */
-/* *             1.0.9 - 09/16/2004 - G.Juyn                                * */
-/* *             - fixed chunk pushing mechanism                            * */
-/* *             1.0.9 - 12/05/2004 - G.Juyn                                * */
-/* *             - added conditional MNG_OPTIMIZE_CHUNKINITFREE             * */
-/* *             1.0.9 - 12/06/2004 - G.Juyn                                * */
-/* *             - added conditional MNG_OPTIMIZE_CHUNKASSIGN               * */
-/* *             - added conditional MNG_OPTIMIZE_CHUNKREADER               * */
-/* *             1.0.9 - 12/20/2004 - G.Juyn                                * */
-/* *             - cleaned up macro-invocations (thanks to D. Airlie)       * */
-/* *             1.0.9 - 12/31/2004 - G.R-P                                 * */
-/* *             - removed stray characters from #ifdef directive           * */
-/* *                                                                        * */
-/* *             1.0.10 - 04/08/2007 - G.Juyn                               * */
-/* *             - added support for mPNG proposal                          * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#include "libmng.h"
-#include "libmng_data.h"
-#include "libmng_error.h"
-#include "libmng_trace.h"
-#ifdef __BORLANDC__
-#pragma hdrstop
-#endif
-#include "libmng_memory.h"
-#include "libmng_objects.h"
-#include "libmng_object_prc.h"
-#include "libmng_chunks.h"
-#ifdef MNG_OPTIMIZE_CHUNKREADER
-#include "libmng_chunk_descr.h"
-#endif
-#include "libmng_chunk_prc.h"
-#include "libmng_chunk_io.h"
-#include "libmng_display.h"
-#include "libmng_read.h"
-
-#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
-#pragma option -A                      /* force ANSI-C */
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_READ_PROCS
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_eof (mng_datap pData)
-{
-  if (!pData->bEOF)                    /* haven't closed the stream yet ? */
-  {
-    pData->bEOF = MNG_TRUE;            /* now we do! */
-
-#ifndef MNG_NO_OPEN_CLOSE_STREAM
-    if (pData->fClosestream && !pData->fClosestream ((mng_handle)pData))
-    {
-      MNG_ERROR (pData, MNG_APPIOERROR);
-    }
-#endif
-  }
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_release_pushdata (mng_datap pData)
-{
-  mng_pushdatap pFirst  = pData->pFirstpushdata;
-  mng_pushdatap pNext   = pFirst->pNext;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RELEASE_PUSHDATA, MNG_LC_START);
-#endif
-
-  pData->pFirstpushdata = pNext;       /* next becomes the first */
-
-  if (!pNext)                          /* no next? => no last! */
-    pData->pLastpushdata = MNG_NULL;
-                                       /* buffer owned and release callback defined? */
-  if ((pFirst->bOwned) && (pData->fReleasedata))
-    pData->fReleasedata ((mng_handle)pData, pFirst->pData, pFirst->iLength);
-  else                                 /* otherwise use internal free mechanism */
-    MNG_FREEX (pData, pFirst->pData, pFirst->iLength);
-                                       /* and free it */
-  MNG_FREEX (pData, pFirst, sizeof(mng_pushdata));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RELEASE_PUSHDATA, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_release_pushchunk (mng_datap pData)
-{
-  mng_pushdatap pFirst  = pData->pFirstpushchunk;
-  mng_pushdatap pNext   = pFirst->pNext;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RELEASE_PUSHCHUNK, MNG_LC_START);
-#endif
-
-  pData->pFirstpushchunk = pNext;      /* next becomes the first */
-
-  if (!pNext)                          /* no next? => no last! */
-    pData->pLastpushchunk = MNG_NULL;
-                                       /* buffer owned and release callback defined? */
-  if ((pFirst->bOwned) && (pData->fReleasedata))
-    pData->fReleasedata ((mng_handle)pData, pFirst->pData, pFirst->iLength);
-  else                                 /* otherwise use internal free mechanism */
-    MNG_FREEX (pData, pFirst->pData, pFirst->iLength);
-                                       /* and free it */
-  MNG_FREEX (pData, pFirst, sizeof(mng_pushdata));
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_RELEASE_PUSHCHUNK, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-MNG_LOCAL mng_retcode read_data (mng_datap    pData,
-                                 mng_uint8p   pBuf,
-                                 mng_uint32   iSize,
-                                 mng_uint32 * iRead)
-{
-  mng_retcode   iRetcode;
-  mng_uint32    iTempsize = iSize;
-  mng_uint8p    pTempbuf  = pBuf;
-  mng_pushdatap pPush     = pData->pFirstpushdata;
-  mng_uint32    iPushsize = 0;
-  *iRead                  = 0;         /* nothing yet */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_DATA, MNG_LC_START);
-#endif
-
-  while (pPush)                        /* calculate size of pushed data */
-  {
-    iPushsize += pPush->iRemaining;
-    pPush      = pPush->pNext;
-  }
-
-  if (iTempsize <= iPushsize)          /* got enough push data? */
-  {
-    while (iTempsize)
-    {
-      pPush = pData->pFirstpushdata;
-                                       /* enough data remaining in this buffer? */
-      if (pPush->iRemaining <= iTempsize)
-      {                                /* no: then copy what we've got */
-        MNG_COPY (pTempbuf, pPush->pDatanext, pPush->iRemaining);
-                                       /* move pointers & lengths */
-        pTempbuf  += pPush->iRemaining;
-        *iRead    += pPush->iRemaining;
-        iTempsize -= pPush->iRemaining;
-                                       /* release the depleted buffer */
-        iRetcode = mng_release_pushdata (pData);
-        if (iRetcode)
-          return iRetcode;
-      }
-      else
-      {                                /* copy the needed bytes */
-        MNG_COPY (pTempbuf, pPush->pDatanext, iTempsize);
-                                       /* move pointers & lengths */
-        pPush->iRemaining -= iTempsize;
-        pPush->pDatanext  += iTempsize;
-        pTempbuf          += iTempsize;
-        *iRead            += iTempsize;
-        iTempsize         = 0;         /* all done!!! */
-      }
-    }
-  }
-  else
-  {
-    mng_uint32 iTempread = 0;
-                                       /* get it from the app then */
-    if (!pData->fReaddata (((mng_handle)pData), pTempbuf, iTempsize, &iTempread))
-      MNG_ERROR (pData, MNG_APPIOERROR);
-
-    *iRead += iTempread;
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_DATA, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-MNG_LOCAL mng_retcode read_databuffer (mng_datap    pData,
-                                       mng_uint8p   pBuf,
-                                       mng_uint8p * pBufnext,
-                                       mng_uint32   iSize,
-                                       mng_uint32 * iRead)
-{
-  mng_retcode iRetcode;
-  
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_DATABUFFER, MNG_LC_START);
-#endif
-
-  if (pData->bSuspensionmode)
-  {
-    mng_uint8p pTemp;
-    mng_uint32 iTemp;
-
-    *iRead = 0;                        /* let's be negative about the outcome */
-
-    if (!pData->pSuspendbuf)           /* need to create a suspension buffer ? */
-    {
-      pData->iSuspendbufsize = MNG_SUSPENDBUFFERSIZE;
-                                       /* so, create it */
-      MNG_ALLOC (pData, pData->pSuspendbuf, pData->iSuspendbufsize);
-
-      pData->iSuspendbufleft = 0;      /* make sure to fill it first time */
-      pData->pSuspendbufnext = pData->pSuspendbuf;
-    }
-                                       /* more than our buffer can hold ? */
-    if (iSize > pData->iSuspendbufsize)
-    {
-      mng_uint32 iRemain;
-
-      if (!*pBufnext)                  /* first time ? */
-      {
-        if (pData->iSuspendbufleft)    /* do we have some data left ? */
-        {                              /* then copy it */
-          MNG_COPY (pBuf, pData->pSuspendbufnext, pData->iSuspendbufleft);
-                                       /* fixup variables */
-          *pBufnext              = pBuf + pData->iSuspendbufleft;
-          pData->pSuspendbufnext = pData->pSuspendbuf;
-          pData->iSuspendbufleft = 0;
-        }
-        else
-        {
-          *pBufnext              = pBuf;
-        }
-      }
-                                       /* calculate how much to get */
-      iRemain = iSize - (mng_uint32)(*pBufnext - pBuf);
-                                       /* let's go get it */
-      iRetcode = read_data (pData, *pBufnext, iRemain, &iTemp);
-      if (iRetcode)
-        return iRetcode;
-                                       /* first read after suspension return 0 means EOF */
-      if ((pData->iSuspendpoint) && (iTemp == 0))
-      {                                /* that makes it final */
-        mng_retcode iRetcode = mng_process_eof (pData);
-        if (iRetcode)                  /* on error bail out */
-          return iRetcode;
-                                       /* indicate the source is depleted */
-        *iRead = iSize - iRemain + iTemp;
-      }
-      else
-      {
-        if (iTemp < iRemain)           /* suspension required ? */
-        {
-          *pBufnext         = *pBufnext + iTemp;
-          pData->bSuspended = MNG_TRUE;
-        }
-        else
-        {
-          *iRead = iSize;              /* got it all now ! */
-        }
-      }
-    }
-    else
-    {                                  /* need to read some more ? */
-      while ((!pData->bSuspended) && (!pData->bEOF) && (iSize > pData->iSuspendbufleft))
-      {                                /* not enough space left in buffer ? */
-        if (pData->iSuspendbufsize - pData->iSuspendbufleft -
-            (mng_uint32)(pData->pSuspendbufnext - pData->pSuspendbuf) <
-                                                          MNG_SUSPENDREQUESTSIZE)
-        {
-          if (pData->iSuspendbufleft)  /* then lets shift (if there's anything left) */
-            MNG_COPY (pData->pSuspendbuf, pData->pSuspendbufnext, pData->iSuspendbufleft);
-                                       /* adjust running pointer */
-          pData->pSuspendbufnext = pData->pSuspendbuf;
-        }
-                                       /* still not enough room ? */
-        if (pData->iSuspendbufsize - pData->iSuspendbufleft < MNG_SUSPENDREQUESTSIZE)
-          MNG_ERROR (pData, MNG_INTERNALERROR);
-                                       /* now read some more data */
-        pTemp = pData->pSuspendbufnext + pData->iSuspendbufleft;
-
-        iRetcode = read_data (pData, pTemp, MNG_SUSPENDREQUESTSIZE, &iTemp);
-        if (iRetcode)
-          return iRetcode;
-                                       /* adjust fill-counter */
-        pData->iSuspendbufleft += iTemp;
-                                       /* first read after suspension returning 0 means EOF */
-        if ((pData->iSuspendpoint) && (iTemp == 0))
-        {                              /* that makes it final */
-          mng_retcode iRetcode = mng_process_eof (pData);
-          if (iRetcode)                /* on error bail out */
-            return iRetcode;
-
-          if (pData->iSuspendbufleft)  /* return the leftover scraps */
-            MNG_COPY (pBuf, pData->pSuspendbufnext, pData->iSuspendbufleft);
-                                       /* and indicate so */
-          *iRead = pData->iSuspendbufleft;
-          pData->pSuspendbufnext = pData->pSuspendbuf;
-          pData->iSuspendbufleft = 0;
-        }
-        else
-        {                              /* suspension required ? */
-          if ((iSize > pData->iSuspendbufleft) && (iTemp < MNG_SUSPENDREQUESTSIZE))
-            pData->bSuspended = MNG_TRUE;
-
-        }
-
-        pData->iSuspendpoint = 0;      /* reset it here in case we loop back */
-      }
-
-      if ((!pData->bSuspended) && (!pData->bEOF))
-      {                                /* return the data ! */
-        MNG_COPY (pBuf, pData->pSuspendbufnext, iSize);
-
-        *iRead = iSize;                /* returned it all */
-                                       /* adjust suspension-buffer variables */
-        pData->pSuspendbufnext += iSize;
-        pData->iSuspendbufleft -= iSize;
-      }
-    }
-  }
-  else
-  {
-    iRetcode = read_data (pData, (mng_ptr)pBuf, iSize, iRead);
-    if (iRetcode)
-      return iRetcode;
-    if (*iRead == 0)                   /* suspension required ? */
-      pData->bSuspended = MNG_TRUE;
-  }
-
-  pData->iSuspendpoint = 0;            /* safely reset it here ! */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_DATABUFFER, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-MNG_LOCAL mng_retcode process_raw_chunk (mng_datap  pData,
-                                         mng_uint8p pBuf,
-                                         mng_uint32 iBuflen)
-{
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  /* the table-idea & binary search code was adapted from
-     libpng 1.1.0 (pngread.c) */
-  /* NOTE1: the table must remain sorted by chunkname, otherwise the binary
-     search will break !!! (ps. watch upper-/lower-case chunknames !!) */
-  /* NOTE2: the layout must remain equal to the header part of all the
-     chunk-structures (yes, that means even the pNext and pPrev fields;
-     it's wasting a bit of space, but hey, the code is a lot easier) */
-
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-  mng_chunk_header mng_chunk_unknown = {MNG_UINT_HUH, mng_init_general, mng_free_unknown,
-                                        mng_read_unknown, mng_write_unknown, mng_assign_unknown, 0, 0, sizeof(mng_unknown_chunk)};
-#else
-  mng_chunk_header mng_chunk_unknown = {MNG_UINT_HUH, mng_init_unknown, mng_free_unknown,
-                                        mng_read_unknown, mng_write_unknown, mng_assign_unknown, 0, 0};
-#endif
-
-#ifdef MNG_OPTIMIZE_CHUNKINITFREE
-
-  mng_chunk_header mng_chunk_table [] =
-  {
-#ifndef MNG_SKIPCHUNK_BACK
-    {MNG_UINT_BACK, mng_init_general, mng_free_general, mng_read_back, mng_write_back, mng_assign_general, 0, 0, sizeof(mng_back)},
-#endif
-#ifndef MNG_SKIPCHUNK_BASI
-    {MNG_UINT_BASI, mng_init_general, mng_free_general, mng_read_basi, mng_write_basi, mng_assign_general, 0, 0, sizeof(mng_basi)},
-#endif
-#ifndef MNG_SKIPCHUNK_CLIP
-    {MNG_UINT_CLIP, mng_init_general, mng_free_general, mng_read_clip, mng_write_clip, mng_assign_general, 0, 0, sizeof(mng_clip)},
-#endif
-#ifndef MNG_SKIPCHUNK_CLON
-    {MNG_UINT_CLON, mng_init_general, mng_free_general, mng_read_clon, mng_write_clon, mng_assign_general, 0, 0, sizeof(mng_clon)},
-#endif
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_SKIPCHUNK_DBYK
-    {MNG_UINT_DBYK, mng_init_general, mng_free_dbyk,    mng_read_dbyk, mng_write_dbyk, mng_assign_dbyk,    0, 0, sizeof(mng_dbyk)},
-#endif
-#endif
-#ifndef MNG_SKIPCHUNK_DEFI
-    {MNG_UINT_DEFI, mng_init_general, mng_free_general, mng_read_defi, mng_write_defi, mng_assign_general, 0, 0, sizeof(mng_defi)},
-#endif
-#ifndef MNG_NO_DELTA_PNG
-    {MNG_UINT_DHDR, mng_init_general, mng_free_general, mng_read_dhdr, mng_write_dhdr, mng_assign_general, 0, 0, sizeof(mng_dhdr)},
-#endif
-#ifndef MNG_SKIPCHUNK_DISC
-    {MNG_UINT_DISC, mng_init_general, mng_free_disc,    mng_read_disc, mng_write_disc, mng_assign_disc,    0, 0, sizeof(mng_disc)},
-#endif
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_SKIPCHUNK_DROP
-    {MNG_UINT_DROP, mng_init_general, mng_free_drop,    mng_read_drop, mng_write_drop, mng_assign_drop,    0, 0, sizeof(mng_drop)},
-#endif
-#endif
-#ifndef MNG_SKIPCHUNK_LOOP
-    {MNG_UINT_ENDL, mng_init_general, mng_free_general, mng_read_endl, mng_write_endl, mng_assign_general, 0, 0, sizeof(mng_endl)},
-#endif
-#ifndef MNG_SKIPCHUNK_FRAM
-    {MNG_UINT_FRAM, mng_init_general, mng_free_fram,    mng_read_fram, mng_write_fram, mng_assign_fram,    0, 0, sizeof(mng_fram)},
-#endif
-    {MNG_UINT_IDAT, mng_init_general, mng_free_idat,    mng_read_idat, mng_write_idat, mng_assign_idat,    0, 0, sizeof(mng_idat)},  /* 12-th element! */
-    {MNG_UINT_IEND, mng_init_general, mng_free_general, mng_read_iend, mng_write_iend, mng_assign_general, 0, 0, sizeof(mng_iend)},
-    {MNG_UINT_IHDR, mng_init_general, mng_free_general, mng_read_ihdr, mng_write_ihdr, mng_assign_general, 0, 0, sizeof(mng_ihdr)},
-#ifndef MNG_NO_DELTA_PNG
-#ifdef MNG_INCLUDE_JNG
-    {MNG_UINT_IJNG, mng_init_general, mng_free_general, mng_read_ijng, mng_write_ijng, mng_assign_general, 0, 0, sizeof(mng_ijng)},
-#endif
-    {MNG_UINT_IPNG, mng_init_general, mng_free_general, mng_read_ipng, mng_write_ipng, mng_assign_general, 0, 0, sizeof(mng_ipng)},
-#endif
-#ifdef MNG_INCLUDE_JNG
-    {MNG_UINT_JDAA, mng_init_general, mng_free_jdaa,    mng_read_jdaa, mng_write_jdaa, mng_assign_jdaa,    0, 0, sizeof(mng_jdaa)},
-    {MNG_UINT_JDAT, mng_init_general, mng_free_jdat,    mng_read_jdat, mng_write_jdat, mng_assign_jdat,    0, 0, sizeof(mng_jdat)},
-    {MNG_UINT_JHDR, mng_init_general, mng_free_general, mng_read_jhdr, mng_write_jhdr, mng_assign_general, 0, 0, sizeof(mng_jhdr)},
-    {MNG_UINT_JSEP, mng_init_general, mng_free_general, mng_read_jsep, mng_write_jsep, mng_assign_general, 0, 0, sizeof(mng_jsep)},
-    {MNG_UINT_JdAA, mng_init_general, mng_free_jdaa,    mng_read_jdaa, mng_write_jdaa, mng_assign_jdaa,    0, 0, sizeof(mng_jdaa)},
-#endif
-#ifndef MNG_SKIPCHUNK_LOOP
-    {MNG_UINT_LOOP, mng_init_general, mng_free_loop,    mng_read_loop, mng_write_loop, mng_assign_loop,    0, 0, sizeof(mng_loop)},
-#endif
-#ifndef MNG_SKIPCHUNK_MAGN
-    {MNG_UINT_MAGN, mng_init_general, mng_free_general, mng_read_magn, mng_write_magn, mng_assign_general, 0, 0, sizeof(mng_magn)},
-#endif
-    {MNG_UINT_MEND, mng_init_general, mng_free_general, mng_read_mend, mng_write_mend, mng_assign_general, 0, 0, sizeof(mng_mend)},
-    {MNG_UINT_MHDR, mng_init_general, mng_free_general, mng_read_mhdr, mng_write_mhdr, mng_assign_general, 0, 0, sizeof(mng_mhdr)},
-#ifndef MNG_SKIPCHUNK_MOVE
-    {MNG_UINT_MOVE, mng_init_general, mng_free_general, mng_read_move, mng_write_move, mng_assign_general, 0, 0, sizeof(mng_move)},
-#endif
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_SKIPCHUNK_ORDR
-    {MNG_UINT_ORDR, mng_init_general, mng_free_ordr,    mng_read_ordr, mng_write_ordr, mng_assign_ordr,    0, 0, sizeof(mng_ordr)},
-#endif
-#endif
-#ifndef MNG_SKIPCHUNK_PAST
-    {MNG_UINT_PAST, mng_init_general, mng_free_past,    mng_read_past, mng_write_past, mng_assign_past,    0, 0, sizeof(mng_past)},
-#endif
-    {MNG_UINT_PLTE, mng_init_general, mng_free_general, mng_read_plte, mng_write_plte, mng_assign_general, 0, 0, sizeof(mng_plte)},
-#ifndef MNG_NO_DELTA_PNG
-    {MNG_UINT_PPLT, mng_init_general, mng_free_general, mng_read_pplt, mng_write_pplt, mng_assign_general, 0, 0, sizeof(mng_pplt)},
-    {MNG_UINT_PROM, mng_init_general, mng_free_general, mng_read_prom, mng_write_prom, mng_assign_general, 0, 0, sizeof(mng_prom)},
-#endif
-#ifndef MNG_SKIPCHUNK_SAVE
-    {MNG_UINT_SAVE, mng_init_general, mng_free_save,    mng_read_save, mng_write_save, mng_assign_save,    0, 0, sizeof(mng_save)},
-#endif
-#ifndef MNG_SKIPCHUNK_SEEK
-    {MNG_UINT_SEEK, mng_init_general, mng_free_seek,    mng_read_seek, mng_write_seek, mng_assign_seek,    0, 0, sizeof(mng_seek)},
-#endif
-#ifndef MNG_SKIPCHUNK_SHOW
-    {MNG_UINT_SHOW, mng_init_general, mng_free_general, mng_read_show, mng_write_show, mng_assign_general, 0, 0, sizeof(mng_show)},
-#endif
-#ifndef MNG_SKIPCHUNK_TERM
-    {MNG_UINT_TERM, mng_init_general, mng_free_general, mng_read_term, mng_write_term, mng_assign_general, 0, 0, sizeof(mng_term)},
-#endif
-#ifndef MNG_SKIPCHUNK_bKGD
-    {MNG_UINT_bKGD, mng_init_general, mng_free_general, mng_read_bkgd, mng_write_bkgd, mng_assign_general, 0, 0, sizeof(mng_bkgd)},
-#endif
-#ifndef MNG_SKIPCHUNK_cHRM
-    {MNG_UINT_cHRM, mng_init_general, mng_free_general, mng_read_chrm, mng_write_chrm, mng_assign_general, 0, 0, sizeof(mng_chrm)},
-#endif
-#ifndef MNG_SKIPCHUNK_eXPI
-    {MNG_UINT_eXPI, mng_init_general, mng_free_expi,    mng_read_expi, mng_write_expi, mng_assign_expi,    0, 0, sizeof(mng_expi)},
-#endif
-#ifndef MNG_SKIPCHUNK_evNT
-    {MNG_UINT_evNT, mng_init_general, mng_free_evnt,    mng_read_evnt, mng_write_evnt, mng_assign_evnt,    0, 0, sizeof(mng_evnt)},
-#endif
-#ifndef MNG_SKIPCHUNK_fPRI
-    {MNG_UINT_fPRI, mng_init_general, mng_free_general, mng_read_fpri, mng_write_fpri, mng_assign_general, 0, 0, sizeof(mng_fpri)},
-#endif
-#ifndef MNG_SKIPCHUNK_gAMA
-    {MNG_UINT_gAMA, mng_init_general, mng_free_general, mng_read_gama, mng_write_gama, mng_assign_general, 0, 0, sizeof(mng_gama)},
-#endif
-#ifndef MNG_SKIPCHUNK_hIST
-    {MNG_UINT_hIST, mng_init_general, mng_free_general, mng_read_hist, mng_write_hist, mng_assign_general, 0, 0, sizeof(mng_hist)},
-#endif
-#ifndef MNG_SKIPCHUNK_iCCP
-    {MNG_UINT_iCCP, mng_init_general, mng_free_iccp,    mng_read_iccp, mng_write_iccp, mng_assign_iccp,    0, 0, sizeof(mng_iccp)},
-#endif
-#ifndef MNG_SKIPCHUNK_iTXt
-    {MNG_UINT_iTXt, mng_init_general, mng_free_itxt,    mng_read_itxt, mng_write_itxt, mng_assign_itxt,    0, 0, sizeof(mng_itxt)},
-#endif
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-    {MNG_UINT_mpNG, mng_init_general, mng_free_mpng,    mng_read_mpng, mng_write_mpng, mng_assign_mpng,    0, 0, sizeof(mng_mpng)},
-#endif
-#ifndef MNG_SKIPCHUNK_nEED
-    {MNG_UINT_nEED, mng_init_general, mng_free_need,    mng_read_need, mng_write_need, mng_assign_need,    0, 0, sizeof(mng_need)},
-#endif
-/* TODO:     {MNG_UINT_oFFs, 0, 0, 0, 0, 0, 0},  */
-/* TODO:     {MNG_UINT_pCAL, 0, 0, 0, 0, 0, 0},  */
-#ifndef MNG_SKIPCHUNK_pHYg
-    {MNG_UINT_pHYg, mng_init_general, mng_free_general, mng_read_phyg, mng_write_phyg, mng_assign_general, 0, 0, sizeof(mng_phyg)},
-#endif
-#ifndef MNG_SKIPCHUNK_pHYs
-    {MNG_UINT_pHYs, mng_init_general, mng_free_general, mng_read_phys, mng_write_phys, mng_assign_general, 0, 0, sizeof(mng_phys)},
-#endif
-#ifndef MNG_SKIPCHUNK_sBIT
-    {MNG_UINT_sBIT, mng_init_general, mng_free_general, mng_read_sbit, mng_write_sbit, mng_assign_general, 0, 0, sizeof(mng_sbit)},
-#endif
-/* TODO:     {MNG_UINT_sCAL, 0, 0, 0, 0, 0, 0},  */
-#ifndef MNG_SKIPCHUNK_sPLT
-    {MNG_UINT_sPLT, mng_init_general, mng_free_splt,    mng_read_splt, mng_write_splt, mng_assign_splt,    0, 0, sizeof(mng_splt)},
-#endif
-    {MNG_UINT_sRGB, mng_init_general, mng_free_general, mng_read_srgb, mng_write_srgb, mng_assign_general, 0, 0, sizeof(mng_srgb)},
-#ifndef MNG_SKIPCHUNK_tEXt
-    {MNG_UINT_tEXt, mng_init_general, mng_free_text,    mng_read_text, mng_write_text, mng_assign_text,    0, 0, sizeof(mng_text)},
-#endif
-#ifndef MNG_SKIPCHUNK_tIME
-    {MNG_UINT_tIME, mng_init_general, mng_free_general, mng_read_time, mng_write_time, mng_assign_general, 0, 0, sizeof(mng_time)},
-#endif
-    {MNG_UINT_tRNS, mng_init_general, mng_free_general, mng_read_trns, mng_write_trns, mng_assign_general, 0, 0, sizeof(mng_trns)},
-#ifndef MNG_SKIPCHUNK_zTXt
-    {MNG_UINT_zTXt, mng_init_general, mng_free_ztxt,    mng_read_ztxt, mng_write_ztxt, mng_assign_ztxt,    0, 0, sizeof(mng_ztxt)},
-#endif
-  };
-
-#else                        /* MNG_OPTIMIZE_CHUNKINITFREE */
-
-  mng_chunk_header mng_chunk_table [] =
-  {
-#ifndef MNG_SKIPCHUNK_BACK
-    {MNG_UINT_BACK, mng_init_back, mng_free_back, mng_read_back, mng_write_back, mng_assign_back, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_BASI
-    {MNG_UINT_BASI, mng_init_basi, mng_free_basi, mng_read_basi, mng_write_basi, mng_assign_basi, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_CLIP
-    {MNG_UINT_CLIP, mng_init_clip, mng_free_clip, mng_read_clip, mng_write_clip, mng_assign_clip, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_CLON
-    {MNG_UINT_CLON, mng_init_clon, mng_free_clon, mng_read_clon, mng_write_clon, mng_assign_clon, 0, 0},
-#endif
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_SKIPCHUNK_DBYK
-    {MNG_UINT_DBYK, mng_init_dbyk, mng_free_dbyk, mng_read_dbyk, mng_write_dbyk, mng_assign_dbyk, 0, 0},
-#endif
-#endif
-#ifndef MNG_SKIPCHUNK_DEFI
-    {MNG_UINT_DEFI, mng_init_defi, mng_free_defi, mng_read_defi, mng_write_defi, mng_assign_defi, 0, 0},
-#endif
-#ifndef MNG_NO_DELTA_PNG
-    {MNG_UINT_DHDR, mng_init_dhdr, mng_free_dhdr, mng_read_dhdr, mng_write_dhdr, mng_assign_dhdr, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_DISC
-    {MNG_UINT_DISC, mng_init_disc, mng_free_disc, mng_read_disc, mng_write_disc, mng_assign_disc, 0, 0},
-#endif
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_SKIPCHUNK_DROP
-    {MNG_UINT_DROP, mng_init_drop, mng_free_drop, mng_read_drop, mng_write_drop, mng_assign_drop, 0, 0},
-#endif
-#endif
-#ifndef MNG_SKIPCHUNK_LOOP
-    {MNG_UINT_ENDL, mng_init_endl, mng_free_endl, mng_read_endl, mng_write_endl, mng_assign_endl, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_FRAM
-    {MNG_UINT_FRAM, mng_init_fram, mng_free_fram, mng_read_fram, mng_write_fram, mng_assign_fram, 0, 0},
-#endif
-    {MNG_UINT_IDAT, mng_init_idat, mng_free_idat, mng_read_idat, mng_write_idat, mng_assign_idat, 0, 0},  /* 12-th element! */
-    {MNG_UINT_IEND, mng_init_iend, mng_free_iend, mng_read_iend, mng_write_iend, mng_assign_iend, 0, 0},
-    {MNG_UINT_IHDR, mng_init_ihdr, mng_free_ihdr, mng_read_ihdr, mng_write_ihdr, mng_assign_ihdr, 0, 0},
-#ifndef MNG_NO_DELTA_PNG
-#ifdef MNG_INCLUDE_JNG
-    {MNG_UINT_IJNG, mng_init_ijng, mng_free_ijng, mng_read_ijng, mng_write_ijng, mng_assign_ijng, 0, 0},
-#endif
-    {MNG_UINT_IPNG, mng_init_ipng, mng_free_ipng, mng_read_ipng, mng_write_ipng, mng_assign_ipng, 0, 0},
-#endif
-#ifdef MNG_INCLUDE_JNG
-    {MNG_UINT_JDAA, mng_init_jdaa, mng_free_jdaa, mng_read_jdaa, mng_write_jdaa, mng_assign_jdaa, 0, 0},
-    {MNG_UINT_JDAT, mng_init_jdat, mng_free_jdat, mng_read_jdat, mng_write_jdat, mng_assign_jdat, 0, 0},
-    {MNG_UINT_JHDR, mng_init_jhdr, mng_free_jhdr, mng_read_jhdr, mng_write_jhdr, mng_assign_jhdr, 0, 0},
-    {MNG_UINT_JSEP, mng_init_jsep, mng_free_jsep, mng_read_jsep, mng_write_jsep, mng_assign_jsep, 0, 0},
-    {MNG_UINT_JdAA, mng_init_jdaa, mng_free_jdaa, mng_read_jdaa, mng_write_jdaa, mng_assign_jdaa, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_LOOP
-    {MNG_UINT_LOOP, mng_init_loop, mng_free_loop, mng_read_loop, mng_write_loop, mng_assign_loop, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_MAGN
-    {MNG_UINT_MAGN, mng_init_magn, mng_free_magn, mng_read_magn, mng_write_magn, mng_assign_magn, 0, 0},
-#endif
-    {MNG_UINT_MEND, mng_init_mend, mng_free_mend, mng_read_mend, mng_write_mend, mng_assign_mend, 0, 0},
-    {MNG_UINT_MHDR, mng_init_mhdr, mng_free_mhdr, mng_read_mhdr, mng_write_mhdr, mng_assign_mhdr, 0, 0},
-#ifndef MNG_SKIPCHUNK_MOVE
-    {MNG_UINT_MOVE, mng_init_move, mng_free_move, mng_read_move, mng_write_move, mng_assign_move, 0, 0},
-#endif
-#ifndef MNG_NO_DELTA_PNG
-#ifndef MNG_SKIPCHUNK_ORDR
-    {MNG_UINT_ORDR, mng_init_ordr, mng_free_ordr, mng_read_ordr, mng_write_ordr, mng_assign_ordr, 0, 0},
-#endif
-#endif
-#ifndef MNG_SKIPCHUNK_PAST
-    {MNG_UINT_PAST, mng_init_past, mng_free_past, mng_read_past, mng_write_past, mng_assign_past, 0, 0},
-#endif
-    {MNG_UINT_PLTE, mng_init_plte, mng_free_plte, mng_read_plte, mng_write_plte, mng_assign_plte, 0, 0},
-#ifndef MNG_NO_DELTA_PNG
-    {MNG_UINT_PPLT, mng_init_pplt, mng_free_pplt, mng_read_pplt, mng_write_pplt, mng_assign_pplt, 0, 0},
-    {MNG_UINT_PROM, mng_init_prom, mng_free_prom, mng_read_prom, mng_write_prom, mng_assign_prom, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_SAVE
-    {MNG_UINT_SAVE, mng_init_save, mng_free_save, mng_read_save, mng_write_save, mng_assign_save, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_SEEK
-    {MNG_UINT_SEEK, mng_init_seek, mng_free_seek, mng_read_seek, mng_write_seek, mng_assign_seek, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_SHOW
-    {MNG_UINT_SHOW, mng_init_show, mng_free_show, mng_read_show, mng_write_show, mng_assign_show, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_TERM
-    {MNG_UINT_TERM, mng_init_term, mng_free_term, mng_read_term, mng_write_term, mng_assign_term, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_bKGD
-    {MNG_UINT_bKGD, mng_init_bkgd, mng_free_bkgd, mng_read_bkgd, mng_write_bkgd, mng_assign_bkgd, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_cHRM
-    {MNG_UINT_cHRM, mng_init_chrm, mng_free_chrm, mng_read_chrm, mng_write_chrm, mng_assign_chrm, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_eXPI
-    {MNG_UINT_eXPI, mng_init_expi, mng_free_expi, mng_read_expi, mng_write_expi, mng_assign_expi, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_evNT
-    {MNG_UINT_evNT, mng_init_evnt, mng_free_evnt, mng_read_evnt, mng_write_evnt, mng_assign_evnt, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_fPRI
-    {MNG_UINT_fPRI, mng_init_fpri, mng_free_fpri, mng_read_fpri, mng_write_fpri, mng_assign_fpri, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_gAMA
-    {MNG_UINT_gAMA, mng_init_gama, mng_free_gama, mng_read_gama, mng_write_gama, mng_assign_gama, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_hIST
-    {MNG_UINT_hIST, mng_init_hist, mng_free_hist, mng_read_hist, mng_write_hist, mng_assign_hist, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_iCCP
-    {MNG_UINT_iCCP, mng_init_iccp, mng_free_iccp, mng_read_iccp, mng_write_iccp, mng_assign_iccp, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_iTXt
-    {MNG_UINT_iTXt, mng_init_itxt, mng_free_itxt, mng_read_itxt, mng_write_itxt, mng_assign_itxt, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_nEED
-    {MNG_UINT_nEED, mng_init_need, mng_free_need, mng_read_need, mng_write_need, mng_assign_need, 0, 0},
-#endif
-/* TODO:     {MNG_UINT_oFFs, 0, 0, 0, 0, 0, 0},  */
-/* TODO:     {MNG_UINT_pCAL, 0, 0, 0, 0, 0, 0},  */
-#ifndef MNG_SKIPCHUNK_pHYg
-    {MNG_UINT_pHYg, mng_init_phyg, mng_free_phyg, mng_read_phyg, mng_write_phyg, mng_assign_phyg, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_pHYs
-    {MNG_UINT_pHYs, mng_init_phys, mng_free_phys, mng_read_phys, mng_write_phys, mng_assign_phys, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_sBIT
-    {MNG_UINT_sBIT, mng_init_sbit, mng_free_sbit, mng_read_sbit, mng_write_sbit, mng_assign_sbit, 0, 0},
-#endif
-/* TODO:     {MNG_UINT_sCAL, 0, 0, 0, 0, 0, 0},  */
-#ifndef MNG_SKIPCHUNK_sPLT
-    {MNG_UINT_sPLT, mng_init_splt, mng_free_splt, mng_read_splt, mng_write_splt, mng_assign_splt, 0, 0},
-#endif
-    {MNG_UINT_sRGB, mng_init_srgb, mng_free_srgb, mng_read_srgb, mng_write_srgb, mng_assign_srgb, 0, 0},
-#ifndef MNG_SKIPCHUNK_tEXt
-    {MNG_UINT_tEXt, mng_init_text, mng_free_text, mng_read_text, mng_write_text, mng_assign_text, 0, 0},
-#endif
-#ifndef MNG_SKIPCHUNK_tIME
-    {MNG_UINT_tIME, mng_init_time, mng_free_time, mng_read_time, mng_write_time, mng_assign_time, 0, 0},
-#endif
-    {MNG_UINT_tRNS, mng_init_trns, mng_free_trns, mng_read_trns, mng_write_trns, mng_assign_trns, 0, 0},
-#ifndef MNG_SKIPCHUNK_zTXt
-    {MNG_UINT_zTXt, mng_init_ztxt, mng_free_ztxt, mng_read_ztxt, mng_write_ztxt, mng_assign_ztxt, 0, 0},
-#endif
-  };
-
-#endif                       /* MNG_OPTIMIZE_CHUNKINITFREE */
-
-                                       /* binary search variables */
-  mng_int32         iTop, iLower, iUpper, iMiddle;
-  mng_chunk_headerp pEntry;            /* pointer to found entry */
-#else
-  mng_chunk_header  sEntry;            /* temp chunk-header */
-#endif /* MNG_OPTIMIZE_CHUNKREADER */
-
-  mng_chunkid       iChunkname;        /* the chunk's tag */
-  mng_chunkp        pChunk;            /* chunk structure (if #define MNG_STORE_CHUNKS) */
-  mng_retcode       iRetcode;          /* temporary error-code */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_RAW_CHUNK, MNG_LC_START);
-#endif
-                                       /* reset timer indicator on read-cycle */
-  if ((pData->bReading) && (!pData->bDisplaying))
-    pData->bTimerset = MNG_FALSE;
-                                       /* get the chunkname */
-  iChunkname = (mng_chunkid)(mng_get_uint32 (pBuf));
-
-  pBuf += sizeof (mng_chunkid);        /* adjust the buffer */
-  iBuflen -= sizeof (mng_chunkid);
-  pChunk = 0;
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-                                       /* determine max index of table */
-  iTop = (sizeof (mng_chunk_table) / sizeof (mng_chunk_table [0])) - 1;
-
-  /* binary search; with 54 chunks, worst-case is 7 comparisons */
-  iLower  = 0;
-#ifndef MNG_NO_DELTA_PNG
-  iMiddle = 11;                        /* start with the IDAT entry */
-#else
-  iMiddle = 8;
-#endif
-  iUpper  = iTop;
-  pEntry  = 0;                         /* no goods yet! */
-
-  do                                   /* the binary search itself */
-    {
-      if (mng_chunk_table [iMiddle].iChunkname < iChunkname)
-        iLower = iMiddle + 1;
-      else if (mng_chunk_table [iMiddle].iChunkname > iChunkname)
-        iUpper = iMiddle - 1;
-      else
-      {
-        pEntry = &mng_chunk_table [iMiddle];
-        break;
-      }
-
-      iMiddle = (iLower + iUpper) >> 1;
-    }
-  while (iLower <= iUpper);
-
-  if (!pEntry)                         /* unknown chunk ? */
-    pEntry = &mng_chunk_unknown;       /* make it so! */
-
-#else /* MNG_OPTIMIZE_CHUNKREADER */
-
-  mng_get_chunkheader (iChunkname, &sEntry);
-
-#endif /* MNG_OPTIMIZE_CHUNKREADER */
-
-  pData->iChunkname = iChunkname;      /* keep track of where we are */
-  pData->iChunkseq++;
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-  if (pEntry->fRead)                   /* read-callback available ? */
-  {
-    iRetcode = pEntry->fRead (pData, pEntry, iBuflen, (mng_ptr)pBuf, &pChunk);
-
-    if (!iRetcode)                     /* everything oke ? */
-    {                                  /* remember unknown chunk's id */
-      if ((pChunk) && (pEntry->iChunkname == MNG_UINT_HUH))
-        ((mng_chunk_headerp)pChunk)->iChunkname = iChunkname;
-    }
-  }
-#else /* MNG_OPTIMIZE_CHUNKREADER */
-  if (sEntry.fRead)                    /* read-callback available ? */
-  {
-    iRetcode = sEntry.fRead (pData, &sEntry, iBuflen, (mng_ptr)pBuf, &pChunk);
-
-#ifndef MNG_OPTIMIZE_CHUNKREADER
-    if (!iRetcode)                     /* everything oke ? */
-    {                                  /* remember unknown chunk's id */
-      if ((pChunk) && (sEntry.iChunkname == MNG_UINT_HUH))
-        ((mng_chunk_headerp)pChunk)->iChunkname = iChunkname;
-    }
-#endif
-  }
-#endif /* MNG_OPTIMIZE_CHUNKREADER */
-  else
-    iRetcode = MNG_NOERROR;
-
-  if (pChunk)                          /* store this chunk ? */
-    mng_add_chunk (pData, pChunk);     /* do it */
-
-#ifdef MNG_INCLUDE_JNG                 /* implicit EOF ? */
-  if ((!pData->bHasMHDR) && (!pData->bHasIHDR) && (!pData->bHasJHDR))
-#else
-  if ((!pData->bHasMHDR) && (!pData->bHasIHDR))
-#endif
-    iRetcode = mng_process_eof (pData);/* then do some EOF processing */
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_PROCESS_RAW_CHUNK, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-MNG_LOCAL mng_retcode check_chunk_crc (mng_datap  pData,
-                                       mng_uint8p pBuf,
-                                       mng_uint32 iBuflen)
-{
-  mng_uint32  iCrc;                    /* calculated CRC */
-  mng_bool    bDiscard = MNG_FALSE;
-  mng_retcode iRetcode = MNG_NOERROR;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_CHUNK_CRC, MNG_LC_START);
-#endif
-
-  if (pData->iCrcmode & MNG_CRC_INPUT) /* crc included ? */
-  {
-    mng_bool bCritical = (mng_bool)((*pBuf & 0x20) == 0);
-    mng_uint32 iL = iBuflen - (mng_uint32)(sizeof (iCrc));
-
-    if (((bCritical ) && (pData->iCrcmode & MNG_CRC_CRITICAL )) ||
-        ((!bCritical) && (pData->iCrcmode & MNG_CRC_ANCILLARY)))
-    {                                  /* calculate the crc */
-      iCrc = mng_crc (pData, pBuf, iL);
-                                       /* and check it */
-      if (!(iCrc == mng_get_uint32 (pBuf + iL)))
-      {
-        mng_bool bWarning = MNG_FALSE;
-        mng_bool bError   = MNG_FALSE;
-
-        if (bCritical)
-        {
-          switch (pData->iCrcmode & MNG_CRC_CRITICAL)
-          {
-            case MNG_CRC_CRITICAL_WARNING  : { bWarning = MNG_TRUE; break; }
-            case MNG_CRC_CRITICAL_ERROR    : { bError   = MNG_TRUE; break; }
-          }
-        }
-        else
-        {
-          switch (pData->iCrcmode & MNG_CRC_ANCILLARY)
-          {
-            case MNG_CRC_ANCILLARY_DISCARD : { bDiscard = MNG_TRUE; break; }
-            case MNG_CRC_ANCILLARY_WARNING : { bWarning = MNG_TRUE; break; }
-            case MNG_CRC_ANCILLARY_ERROR   : { bError   = MNG_TRUE; break; }
-          }
-        }
-
-        if (bWarning)
-          MNG_WARNING (pData, MNG_INVALIDCRC);
-        if (bError)
-          MNG_ERROR (pData, MNG_INVALIDCRC);
-      }
-    }
-
-    if (!bDiscard)                     /* still processing ? */
-      iRetcode = process_raw_chunk (pData, pBuf, iL);
-  }
-  else
-  {                                    /* no crc => straight onto processing */
-    iRetcode = process_raw_chunk (pData, pBuf, iBuflen);
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_CHUNK_CRC, MNG_LC_END);
-#endif
-
-  return iRetcode;
-}
-
-/* ************************************************************************** */
-
-MNG_LOCAL mng_retcode read_chunk (mng_datap  pData)
-{
-  mng_uint32  iBufmax   = pData->iReadbufsize;
-  mng_uint8p  pBuf      = pData->pReadbuf;
-  mng_uint32  iBuflen   = 0;           /* number of bytes requested */
-  mng_uint32  iRead     = 0;           /* number of bytes read */
-  mng_retcode iRetcode  = MNG_NOERROR;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_CHUNK, MNG_LC_START);
-#endif
-
-#ifdef MNG_SUPPORT_DISPLAY
-  if (pData->pCurraniobj)              /* processing an animation object ? */
-  {
-    do                                 /* process it then */
-    {
-      iRetcode = ((mng_object_headerp)pData->pCurraniobj)->fProcess (pData, pData->pCurraniobj);
-                                       /* refresh needed ? */
-/*      if ((!iRetcode) && (!pData->bTimerset) && (pData->bNeedrefresh))
-        iRetcode = display_progressive_refresh (pData, 1); */
-                                       /* can we advance to next object ? */
-      if ((!iRetcode) && (pData->pCurraniobj) &&
-          (!pData->bTimerset) && (!pData->bSectionwait))
-      {                                /* reset timer indicator on read-cycle */
-        if ((pData->bReading) && (!pData->bDisplaying))
-          pData->bTimerset = MNG_FALSE;
-
-        pData->pCurraniobj = ((mng_object_headerp)pData->pCurraniobj)->pNext;
-                                       /* TERM processing to be done ? */
-        if ((!pData->pCurraniobj) && (pData->bHasTERM) && (!pData->bHasMHDR))
-          iRetcode = mng_process_display_mend (pData);
-      }
-    }                                  /* until error or a break or no more objects */
-    while ((!iRetcode) && (pData->pCurraniobj) &&
-           (!pData->bTimerset) && (!pData->bSectionwait) && (!pData->bFreezing));
-  }
-  else
-  {
-    if (pData->iBreakpoint)            /* do we need to finish something first ? */
-    {
-      switch (pData->iBreakpoint)      /* return to broken display routine */
-      {
-#ifndef MNG_SKIPCHUNK_FRAM
-        case  1 : { iRetcode = mng_process_display_fram2 (pData); break; }
-#endif
-        case  2 : { iRetcode = mng_process_display_ihdr  (pData); break; }
-#ifndef MNG_SKIPCHUNK_SHOW
-        case  3 : ;                     /* same as 4 !!! */
-        case  4 : { iRetcode = mng_process_display_show  (pData); break; }
-#endif
-#ifndef MNG_SKIPCHUNK_CLON
-        case  5 : { iRetcode = mng_process_display_clon2 (pData); break; }
-#endif
-#ifdef MNG_INCLUDE_JNG
-        case  7 : { iRetcode = mng_process_display_jhdr  (pData); break; }
-#endif
-        case  6 : ;                     /* same as 8 !!! */
-        case  8 : { iRetcode = mng_process_display_iend  (pData); break; }
-#ifndef MNG_SKIPCHUNK_MAGN
-        case  9 : { iRetcode = mng_process_display_magn2 (pData); break; }
-#endif
-        case 10 : { iRetcode = mng_process_display_mend2 (pData); break; }
-#ifndef MNG_SKIPCHUNK_PAST
-        case 11 : { iRetcode = mng_process_display_past2 (pData); break; }
-#endif
-      }
-    }
-  }
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-
-#endif /* MNG_SUPPORT_DISPLAY */
-                                       /* can we continue processing now, or do we */
-                                       /* need to wait for the timer to finish (again) ? */
-#ifdef MNG_SUPPORT_DISPLAY
-  if ((!pData->bTimerset) && (!pData->bSectionwait) && (!pData->bEOF))
-#else
-  if (!pData->bEOF)
-#endif
-  {
-#ifdef MNG_SUPPORT_DISPLAY
-                                       /* freezing in progress ? */
-    if ((pData->bFreezing) && (pData->iSuspendpoint == 0))
-      pData->bRunning = MNG_FALSE;     /* then this is the right moment to do it */
-#endif
-
-    if (pData->iSuspendpoint <= 2)
-    {
-      iBuflen  = sizeof (mng_uint32);  /* read length */
-      iRetcode = read_databuffer (pData, pBuf, &pData->pReadbufnext, iBuflen, &iRead);
-
-      if (iRetcode)                    /* bail on errors */
-        return iRetcode;
-
-      if (pData->bSuspended)           /* suspended ? */
-        pData->iSuspendpoint = 2;
-      else                             /* save the length */
-      {
-        pData->iChunklen = mng_get_uint32 (pBuf);
-        if (pData->iChunklen > 0x7ffffff)
-           return MNG_INVALIDLENGTH;
-      }
-
-    }
-
-    if (!pData->bSuspended)            /* still going ? */
-    {                                  /* previously suspended or not eof ? */
-      if ((pData->iSuspendpoint > 2) || (iRead == iBuflen))
-      {                                /* determine length chunkname + data (+ crc) */
-        if (pData->iCrcmode & MNG_CRC_INPUT)
-          iBuflen = pData->iChunklen + (mng_uint32)(sizeof (mng_chunkid) + sizeof (mng_uint32));
-        else
-          iBuflen = pData->iChunklen + (mng_uint32)(sizeof (mng_chunkid));
-
-                                       /* do we have enough data in the current push buffer ? */
-        if ((pData->pFirstpushdata) && (iBuflen <= pData->pFirstpushdata->iRemaining))
-        {
-          mng_pushdatap pPush  = pData->pFirstpushdata;
-          pBuf                 = pPush->pDatanext;
-          pPush->pDatanext    += iBuflen;
-          pPush->iRemaining   -= iBuflen;
-          pData->iSuspendpoint = 0;    /* safely reset this here ! */
-
-          iRetcode = check_chunk_crc (pData, pBuf, iBuflen);
-          if (iRetcode)
-            return iRetcode;
-
-          if (!pPush->iRemaining)      /* buffer depleted? then release it */
-            iRetcode = mng_release_pushdata (pData);
-        }
-        else
-        {
-          if (iBuflen < iBufmax)       /* does it fit in default buffer ? */
-          {                            /* note that we don't use the full size
-                                          so there's always a zero-byte at the
-                                          very end !!! */
-            iRetcode = read_databuffer (pData, pBuf, &pData->pReadbufnext, iBuflen, &iRead);
-            if (iRetcode)              /* bail on errors */
-              return iRetcode;
-
-            if (pData->bSuspended)     /* suspended ? */
-              pData->iSuspendpoint = 3;
-            else
-            {
-              if (iRead != iBuflen)    /* did we get all the data ? */
-                MNG_ERROR (pData, MNG_UNEXPECTEDEOF);
-              iRetcode = check_chunk_crc (pData, pBuf, iBuflen);
-            }
-          }
-          else
-          {
-            if (iBuflen > 16777216)    /* is the length incredible? */
-              MNG_ERROR (pData, MNG_IMPROBABLELENGTH);
-
-            if (!pData->iSuspendpoint) /* create additional large buffer ? */
-            {                          /* again reserve space for the last zero-byte */
-              pData->iLargebufsize = iBuflen + 1;
-              pData->pLargebufnext = MNG_NULL;
-              MNG_ALLOC (pData, pData->pLargebuf, pData->iLargebufsize);
-            }
-
-            iRetcode = read_databuffer (pData, pData->pLargebuf, &pData->pLargebufnext, iBuflen, &iRead);
-            if (iRetcode)
-              return iRetcode;
-
-            if (pData->bSuspended)     /* suspended ? */
-              pData->iSuspendpoint = 4;
-            else
-            {
-              if (iRead != iBuflen)    /* did we get all the data ? */
-                MNG_ERROR (pData, MNG_UNEXPECTEDEOF);
-              iRetcode = check_chunk_crc (pData, pData->pLargebuf, iBuflen);
-                                       /* cleanup additional large buffer */
-              MNG_FREE (pData, pData->pLargebuf, pData->iLargebufsize);
-            }
-          }
-        }
-
-        if (iRetcode)                  /* on error bail out */
-          return iRetcode;
-
-      }
-      else
-      {                                /* that's final */
-        iRetcode = mng_process_eof (pData);
-
-        if (iRetcode)                  /* on error bail out */
-          return iRetcode;
-
-        if ((iRead != 0) ||            /* did we get an unexpected eof ? */
-#ifdef MNG_INCLUDE_JNG
-            (pData->bHasIHDR || pData->bHasMHDR || pData->bHasJHDR))
-#else
-            (pData->bHasIHDR || pData->bHasMHDR))
-#endif
-          MNG_ERROR (pData, MNG_UNEXPECTEDEOF);
-      } 
-    }
-  }
-
-#ifdef MNG_SUPPORT_DISPLAY             /* refresh needed ? */
-  if ((!pData->bTimerset) && (!pData->bSuspended) && (pData->bNeedrefresh))
-  {
-    iRetcode = mng_display_progressive_refresh (pData, 1);
-
-    if (iRetcode)                      /* on error bail out */
-      return iRetcode;
-  }
-#endif
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_CHUNK, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-MNG_LOCAL mng_retcode process_pushedchunk (mng_datap pData)
-{
-  mng_pushdatap pPush;
-  mng_retcode   iRetcode = MNG_NOERROR;
-
-#ifdef MNG_SUPPORT_DISPLAY
-  if (pData->pCurraniobj)              /* processing an animation object ? */
-  {
-    do                                 /* process it then */
-    {
-      iRetcode = ((mng_object_headerp)pData->pCurraniobj)->fProcess (pData, pData->pCurraniobj);
-                                       /* refresh needed ? */
-/*      if ((!iRetcode) && (!pData->bTimerset) && (pData->bNeedrefresh))
-        iRetcode = display_progressive_refresh (pData, 1); */
-                                       /* can we advance to next object ? */
-      if ((!iRetcode) && (pData->pCurraniobj) &&
-          (!pData->bTimerset) && (!pData->bSectionwait))
-      {                                /* reset timer indicator on read-cycle */
-        if ((pData->bReading) && (!pData->bDisplaying))
-          pData->bTimerset = MNG_FALSE;
-
-        pData->pCurraniobj = ((mng_object_headerp)pData->pCurraniobj)->pNext;
-                                       /* TERM processing to be done ? */
-        if ((!pData->pCurraniobj) && (pData->bHasTERM) && (!pData->bHasMHDR))
-          iRetcode = mng_process_display_mend (pData);
-      }
-    }                                  /* until error or a break or no more objects */
-    while ((!iRetcode) && (pData->pCurraniobj) &&
-           (!pData->bTimerset) && (!pData->bSectionwait) && (!pData->bFreezing));
-  }
-  else
-  {
-    if (pData->iBreakpoint)            /* do we need to finish something first ? */
-    {
-      switch (pData->iBreakpoint)      /* return to broken display routine */
-      {
-#ifndef MNG_SKIPCHUNK_FRAM
-        case  1 : { iRetcode = mng_process_display_fram2 (pData); break; }
-#endif
-        case  2 : { iRetcode = mng_process_display_ihdr  (pData); break; }
-#ifndef MNG_SKIPCHUNK_SHOW
-        case  3 : ;                     /* same as 4 !!! */
-        case  4 : { iRetcode = mng_process_display_show  (pData); break; }
-#endif
-#ifndef MNG_SKIPCHUNK_CLON
-        case  5 : { iRetcode = mng_process_display_clon2 (pData); break; }
-#endif
-#ifdef MNG_INCLUDE_JNG
-        case  7 : { iRetcode = mng_process_display_jhdr  (pData); break; }
-#endif
-        case  6 : ;                     /* same as 8 !!! */
-        case  8 : { iRetcode = mng_process_display_iend  (pData); break; }
-#ifndef MNG_SKIPCHUNK_MAGN
-        case  9 : { iRetcode = mng_process_display_magn2 (pData); break; }
-#endif
-        case 10 : { iRetcode = mng_process_display_mend2 (pData); break; }
-#ifndef MNG_SKIPCHUNK_PAST
-        case 11 : { iRetcode = mng_process_display_past2 (pData); break; }
-#endif
-      }
-    }
-  }
-
-  if (iRetcode)                        /* on error bail out */
-    return iRetcode;
-
-#endif /* MNG_SUPPORT_DISPLAY */
-                                       /* can we continue processing now, or do we */
-                                       /* need to wait for the timer to finish (again) ? */
-#ifdef MNG_SUPPORT_DISPLAY
-  if ((!pData->bTimerset) && (!pData->bSectionwait) && (!pData->bEOF))
-#else
-  if (!pData->bEOF)
-#endif
-  {
-    pData->iSuspendpoint = 0;            /* safely reset it here ! */
-    pPush = pData->pFirstpushchunk;
-
-    iRetcode = process_raw_chunk (pData, pPush->pData, pPush->iLength);
-    if (iRetcode)
-      return iRetcode;
-
-#ifdef MNG_SUPPORT_DISPLAY             /* refresh needed ? */
-    if ((!pData->bTimerset) && (!pData->bSuspended) && (pData->bNeedrefresh))
-    {
-      iRetcode = mng_display_progressive_refresh (pData, 1);
-      if (iRetcode)                      /* on error bail out */
-        return iRetcode;
-    }
-#endif
-  }
-
-  return mng_release_pushchunk (pData);
-}
-
-/* ************************************************************************** */
-
-mng_retcode mng_read_graphic (mng_datap pData)
-{
-  mng_uint32  iBuflen;                 /* number of bytes requested */
-  mng_uint32  iRead;                   /* number of bytes read */
-  mng_retcode iRetcode;                /* temporary error-code */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_GRAPHIC, MNG_LC_START);
-#endif
-
-  if (!pData->pReadbuf)                /* buffer allocated ? */
-  {
-    pData->iReadbufsize = 4200;        /* allocate a default read buffer */
-    MNG_ALLOC (pData, pData->pReadbuf, pData->iReadbufsize);
-  }
-                                       /* haven't processed the signature ? */
-  if ((!pData->bHavesig) || (pData->iSuspendpoint == 1))
-  {
-    iBuflen = 2 * sizeof (mng_uint32); /* read signature */
-
-    iRetcode = read_databuffer (pData, pData->pReadbuf, &pData->pReadbufnext, iBuflen, &iRead);
-
-    if (iRetcode)
-      return iRetcode;
-
-    if (pData->bSuspended)             /* input suspension ? */
-      pData->iSuspendpoint = 1;
-    else
-    {
-      if (iRead != iBuflen)            /* full signature received ? */
-        MNG_ERROR (pData, MNG_UNEXPECTEDEOF);
-                                       /* is it a valid signature ? */
-      if (mng_get_uint32 (pData->pReadbuf) == PNG_SIG)
-        pData->eSigtype = mng_it_png;
-      else
-#ifdef MNG_INCLUDE_JNG
-      if (mng_get_uint32 (pData->pReadbuf) == JNG_SIG)
-        pData->eSigtype = mng_it_jng;
-      else
-#endif
-      if (mng_get_uint32 (pData->pReadbuf) == MNG_SIG)
-        pData->eSigtype = mng_it_mng;
-      else
-        MNG_ERROR (pData, MNG_INVALIDSIG);
-                                       /* all of it ? */
-      if (mng_get_uint32 (pData->pReadbuf+4) != POST_SIG)
-        MNG_ERROR (pData, MNG_INVALIDSIG);
-
-      pData->bHavesig = MNG_TRUE;
-    }
-  }
-
-  if (!pData->bSuspended)              /* still going ? */
-  {
-    do
-    {                                  /* reset timer during mng_read() ? */
-      if ((pData->bReading) && (!pData->bDisplaying))
-        pData->bTimerset = MNG_FALSE;
-
-      if (pData->pFirstpushchunk)      /* chunks pushed ? */
-        iRetcode = process_pushedchunk (pData); /* process the pushed chunk */
-      else
-        iRetcode = read_chunk (pData); /* read & process a chunk */
-
-      if (iRetcode)                    /* on error bail out */
-        return iRetcode;
-    }
-#ifdef MNG_SUPPORT_DISPLAY             /* until EOF or a break-request */
-    while (((!pData->bEOF) || (pData->pCurraniobj)) &&
-           (!pData->bSuspended) && (!pData->bSectionwait) &&
-           ((!pData->bTimerset) || ((pData->bReading) && (!pData->bDisplaying))));
-#else
-    while ((!pData->bEOF) && (!pData->bSuspended));
-#endif
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_READ_GRAPHIC, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#endif /* MNG_INCLUDE_READ_PROCS */
-
-/* ************************************************************************** */
-/* * end of file                                                            * */
-/* ************************************************************************** */
-
diff --git a/Source/LibMNG/libmng_read.h b/Source/LibMNG/libmng_read.h
deleted file mode 100644
index 119cc3e..0000000
--- a/Source/LibMNG/libmng_read.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * project   : libmng                                                     * */
-/* * file      : libmng_read.h             copyright (c) 2000-2004 G.Juyn   * */
-/* * version   : 1.0.8                                                      * */
-/* *                                                                        * */
-/* * purpose   : Read management (definition)                               * */
-/* *                                                                        * */
-/* * author    : G.Juyn                                                     * */
-/* *                                                                        * */
-/* * comment   : Definition of the read management routines                 * */
-/* *                                                                        * */
-/* * changes   : 0.5.1 - 05/08/2000 - G.Juyn                                * */
-/* *             - changed strict-ANSI stuff                                * */
-/* *                                                                        * */
-/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
-/* *             - changed file-prefixes                                    * */
-/* *                                                                        * */
-/* *             0.9.3 - 10/18/2000 - G.Juyn                                * */
-/* *             - added closestream() processing for mng_cleanup()         * */
-/* *                                                                        * */
-/* *             1.0.5 - 08/19/2002 - G.Juyn                                * */
-/* *             - B597134 - libmng pollutes the linker namespace           * */
-/* *                                                                        * */
-/* *             1.0.8 - 04/12/2004 - G.Juyn                                * */
-/* *             - added data-push mechanisms for specialized decoders      * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
-#pragma option -A                      /* force ANSI-C */
-#endif
-
-#ifndef _libmng_read_h_
-#define _libmng_read_h_
-
-/* ************************************************************************** */
-
-mng_retcode mng_process_eof       (mng_datap pData);
-
-mng_retcode mng_release_pushdata  (mng_datap pData);
-
-mng_retcode mng_release_pushchunk (mng_datap pData);
-
-mng_retcode mng_read_graphic      (mng_datap pData);
-
-/* ************************************************************************** */
-
-#endif /* _libmng_read_h_ */
-
-/* ************************************************************************** */
-/* * end of file                                                            * */
-/* ************************************************************************** */
diff --git a/Source/LibMNG/libmng_trace.c b/Source/LibMNG/libmng_trace.c
deleted file mode 100644
index ffb7b57..0000000
--- a/Source/LibMNG/libmng_trace.c
+++ /dev/null
@@ -1,1683 +0,0 @@
-/* ************************************************************************** */
-/* *             For conditions of distribution and use,                    * */
-/* *                see copyright notice in libmng.h                        * */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * project   : libmng                                                     * */
-/* * file      : libmng_trace.c            copyright (c) 2000-2007 G.Juyn   * */
-/* * version   : 1.0.10                                                     * */
-/* *                                                                        * */
-/* * purpose   : Trace functions (implementation)                           * */
-/* *                                                                        * */
-/* * author    : G.Juyn                                                     * */
-/* *                                                                        * */
-/* * comment   : implementation of the trace functions                      * */
-/* *                                                                        * */
-/* * changes   : 0.5.1 - 05/08/2000 - G.Juyn                                * */
-/* *             - changed strict-ANSI stuff                                * */
-/* *             0.5.1 - 05/12/2000 - G.Juyn                                * */
-/* *             - added callback error-reporting support                   * */
-/* *                                                                        * */
-/* *             0.5.2 - 05/23/2000 - G.Juyn                                * */
-/* *             - added trace telltale reporting                           * */
-/* *             0.5.2 - 05/24/2000 - G.Juyn                                * */
-/* *             - added tracestrings for global animation color-chunks     * */
-/* *             - added tracestrings for get/set of default ZLIB/IJG parms * */
-/* *             - added tracestrings for global PLTE,tRNS,bKGD             * */
-/* *             0.5.2 - 05/30/2000 - G.Juyn                                * */
-/* *             - added tracestrings for image-object promotion            * */
-/* *             - added tracestrings for delta-image processing            * */
-/* *             0.5.2 - 06/02/2000 - G.Juyn                                * */
-/* *             - added tracestrings for getalphaline callback             * */
-/* *             0.5.2 - 06/05/2000 - G.Juyn                                * */
-/* *             - added tracestring for RGB8_A8 canvasstyle                * */
-/* *             0.5.2 - 06/06/2000 - G.Juyn                                * */
-/* *             - added tracestring for mng_read_resume HLAPI function     * */
-/* *                                                                        * */
-/* *             0.5.3 - 06/21/2000 - G.Juyn                                * */
-/* *             - added tracestrings for get/set speedtype                 * */
-/* *             - added tracestring for get imagelevel                     * */
-/* *             0.5.3 - 06/22/2000 - G.Juyn                                * */
-/* *             - added tracestring for delta-image processing             * */
-/* *             - added tracestrings for PPLT chunk processing             * */
-/* *                                                                        * */
-/* *             0.9.1 - 07/07/2000 - G.Juyn                                * */
-/* *             - added tracecodes for special display processing          * */
-/* *             0.9.1 - 07/08/2000 - G.Juyn                                * */
-/* *             - added tracestring for get/set suspensionmode             * */
-/* *             - added tracestrings for get/set display variables         * */
-/* *             - added tracecode for read_databuffer (I/O-suspension)     * */
-/* *             0.9.1 - 07/15/2000 - G.Juyn                                * */
-/* *             - added tracestrings for SAVE/SEEK callbacks               * */
-/* *             - added tracestrings for get/set sectionbreaks             * */
-/* *             - added tracestring for special error routine              * */
-/* *             0.9.1 - 07/19/2000 - G.Juyn                                * */
-/* *             - added tracestring for updatemngheader                    * */
-/* *                                                                        * */
-/* *             0.9.2 - 07/31/2000 - G.Juyn                                * */
-/* *             - added tracestrings for status_xxxxx functions            * */
-/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
-/* *             - changed file-prefixes                                    * */
-/* *             - added tracestring for updatemngsimplicity                * */
-/* *                                                                        * */
-/* *             0.9.3 - 08/26/2000 - G.Juyn                                * */
-/* *             - added MAGN chunk                                         * */
-/* *             0.9.3 - 09/07/2000 - G.Juyn                                * */
-/* *             - added support for new filter_types                       * */
-/* *             0.9.3 - 10/10/2000 - G.Juyn                                * */
-/* *             - added support for alpha-depth prediction                 * */
-/* *             0.9.3 - 10/11/2000 - G.Juyn                                * */
-/* *             - added JDAA chunk                                         * */
-/* *             - added support for nEED                                   * */
-/* *             0.9.3 - 10/16/2000 - G.Juyn                                * */
-/* *             - added functions to retrieve PNG/JNG specific header-info * */
-/* *             - added optional support for bKGD for PNG images           * */
-/* *             0.9.3 - 10/17/2000 - G.Juyn                                * */
-/* *             - added callback to process non-critical unknown chunks    * */
-/* *             - added routine to discard "invalid" objects               * */
-/* *             0.9.3 - 10/19/2000 - G.Juyn                                * */
-/* *             - implemented delayed delta-processing                     * */
-/* *             0.9.3 - 10/20/2000 - G.Juyn                                * */
-/* *             - added get/set for bKGD preference setting                * */
-/* *             0.9.3 - 10/21/2000 - G.Juyn                                * */
-/* *             - added get function for interlace/progressive display     * */
-/* *                                                                        * */
-/* *             0.9.4 -  1/18/2001 - G.Juyn                                * */
-/* *             - added "new" MAGN methods 3, 4 & 5                        * */
-/* *                                                                        * */
-/* *             1.0.1 - 02/08/2001 - G.Juyn                                * */
-/* *             - added MEND processing callback                           * */
-/* *             1.0.1 - 04/21/2001 - G.Juyn (code by G.Kelly)              * */
-/* *             - added BGRA8 canvas with premultiplied alpha              * */
-/* *             1.0.1 - 05/02/2001 - G.Juyn                                * */
-/* *             - added "default" sRGB generation (Thanks Marti!)          * */
-/* *                                                                        * */
-/* *             1.0.2 - 06/23/2001 - G.Juyn                                * */
-/* *             - added optimization option for MNG-video playback         * */
-/* *             - added processterm callback                               * */
-/* *             1.0.2 - 06/25/2001 - G.Juyn                                * */
-/* *             - added option to turn off progressive refresh             * */
-/* *                                                                        * */
-/* *             1.0.3 - 08/06/2001 - G.Juyn                                * */
-/* *             - added get function for last processed BACK chunk         * */
-/* *                                                                        * */
-/* *             1.0.5 - 08/15/2002 - G.Juyn                                * */
-/* *             - completed PROM support                                   * */
-/* *             - completed delta-image support                            * */
-/* *             1.0.5 - 08/19/2002 - G.Juyn                                * */
-/* *             - B597134 - libmng pollutes the linker namespace           * */
-/* *             - added HLAPI function to copy chunks                      * */
-/* *             1.0.5 - 09/14/2002 - G.Juyn                                * */
-/* *             - added event handling for dynamic MNG                     * */
-/* *             1.0.5 - 09/20/2002 - G.Juyn                                * */
-/* *             - added support for PAST                                   * */
-/* *             1.0.5 - 09/22/2002 - G.Juyn                                * */
-/* *             - added bgrx8 canvas (filler byte)                         * */
-/* *             1.0.5 - 09/23/2002 - G.Juyn                                * */
-/* *             - added in-memory color-correction of abstract images      * */
-/* *             - added compose over/under routines for PAST processing    * */
-/* *             - added flip & tile routines for PAST processing           * */
-/* *             1.0.5 - 10/09/2002 - G.Juyn                                * */
-/* *             - fixed trace-constants for PAST chunk                     * */
-/* *             1.0.5 - 11/07/2002 - G.Juyn                                * */
-/* *             - added support to get totals after mng_read()             * */
-/* *                                                                        * */
-/* *             1.0.6 - 07/07/2003 - G.R-P                                 * */
-/* *             - added conditionals around JNG and Delta-PNG code         * */
-/* *             1.0.6 - 07/14/2003 - G.R-P                                 * */
-/* *             - added conditionals around various unused functions       * */
-/* *             1.0.6 - 07/29/2003 - G.R-P                                 * */
-/* *             - added conditionals around PAST chunk support             * */
-/* *                                                                        * */
-/* *             1.0.7 - 11/27/2003 - R.A                                   * */
-/* *             - added CANVAS_RGB565 and CANVAS_BGR565                    * */
-/* *             1.0.7 - 01/25/2004 - J.S                                   * */
-/* *             - added premultiplied alpha canvas' for RGBA, ARGB, ABGR   * */
-/* *             1.0.7 - 03/07/2004 - G. Randers-Pehrson                    * */
-/* *             - put gamma, cms-related declarations inside #ifdef        * */
-/* *             1.0.7 - 03/10/2004 - G.R-P                                 * */
-/* *             - added conditionals around openstream/closestream         * */
-/* *                                                                        * */
-/* *             1.0.8 - 04/02/2004 - G.Juyn                                * */
-/* *             - added CRC existence & checking flags                     * */
-/* *             1.0.8 - 04/11/2004 - G.Juyn                                * */
-/* *             - added data-push mechanisms for specialized decoders      * */
-/* *                                                                        * */
-/* *             1.0.9 - 10/03/2004 - G.Juyn                                * */
-/* *             - added function to retrieve current FRAM delay            * */
-/* *             1.0.9 - 10/14/2004 - G.Juyn                                * */
-/* *             - added bgr565_a8 canvas-style (thanks to J. Elvander)     * */
-/* *                                                                        * */
-/* *             1.0.10 - 04/08/2007 - G.Juyn                               * */
-/* *             - added support for mPNG proposal                          * */
-/* *             1.0.10 - 07/06/2007 - G.R-P bugfix by Lucas Quintana       * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#include "libmng.h"
-#include "libmng_data.h"
-#include "libmng_error.h"
-#include "libmng_trace.h"
-#ifdef __BORLANDC__
-#pragma hdrstop
-#endif
-
-#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
-#pragma option -A                      /* force ANSI-C */
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_TRACE_PROCS
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_TRACE_STRINGS
-MNG_LOCAL mng_trace_entry const trace_table [] =
-  {
-    {MNG_FN_INITIALIZE,                "initialize"},
-    {MNG_FN_RESET,                     "reset"},
-    {MNG_FN_CLEANUP,                   "cleanup"},
-    {MNG_FN_READ,                      "read"},
-    {MNG_FN_WRITE,                     "write"},
-    {MNG_FN_CREATE,                    "create"},
-    {MNG_FN_READDISPLAY,               "readdisplay"},
-    {MNG_FN_DISPLAY,                   "display"},
-    {MNG_FN_DISPLAY_RESUME,            "display_resume"},
-    {MNG_FN_DISPLAY_FREEZE,            "display_freeze"},
-    {MNG_FN_DISPLAY_RESET,             "display_reset"},
-#ifndef MNG_NO_DISPLAY_GO_SUPPORTED
-    {MNG_FN_DISPLAY_GOFRAME,           "display_goframe"},
-    {MNG_FN_DISPLAY_GOLAYER,           "display_golayer"},
-    {MNG_FN_DISPLAY_GOTIME,            "display_gotime"},
-#endif
-    {MNG_FN_GETLASTERROR,              "getlasterror"},
-    {MNG_FN_READ_RESUME,               "read_resume"},
-    {MNG_FN_TRAPEVENT,                 "trapevent"},
-    {MNG_FN_READ_PUSHDATA,             "read_pushdata"},
-    {MNG_FN_READ_PUSHSIG,              "read_pushsig"},
-    {MNG_FN_READ_PUSHCHUNK,            "read_pushchunk"},
-
-    {MNG_FN_SETCB_MEMALLOC,            "setcb_memalloc"},
-    {MNG_FN_SETCB_MEMFREE,             "setcb_memfree"},
-    {MNG_FN_SETCB_READDATA,            "setcb_readdata"},
-    {MNG_FN_SETCB_WRITEDATA,           "setcb_writedata"},
-    {MNG_FN_SETCB_ERRORPROC,           "setcb_errorproc"},
-    {MNG_FN_SETCB_TRACEPROC,           "setcb_traceproc"},
-    {MNG_FN_SETCB_PROCESSHEADER,       "setcb_processheader"},
-    {MNG_FN_SETCB_PROCESSTEXT,         "setcb_processtext"},
-    {MNG_FN_SETCB_GETCANVASLINE,       "setcb_getcanvasline"},
-    {MNG_FN_SETCB_GETBKGDLINE,         "setcb_getbkgdline"},
-    {MNG_FN_SETCB_REFRESH,             "setcb_refresh"},
-    {MNG_FN_SETCB_GETTICKCOUNT,        "setcb_gettickcount"},
-    {MNG_FN_SETCB_SETTIMER,            "setcb_settimer"},
-    {MNG_FN_SETCB_PROCESSGAMMA,        "setcb_processgamma"},
-    {MNG_FN_SETCB_PROCESSCHROMA,       "setcb_processchroma"},
-    {MNG_FN_SETCB_PROCESSSRGB,         "setcb_processsrgb"},
-    {MNG_FN_SETCB_PROCESSICCP,         "setcb_processiccp"},
-    {MNG_FN_SETCB_PROCESSAROW,         "setcb_processarow"},
-#ifndef MNG_NO_OPEN_CLOSE_STREAM
-    {MNG_FN_SETCB_OPENSTREAM,          "setcb_openstream"},
-    {MNG_FN_SETCB_CLOSESTREAM,         "setcb_closestream"},
-#endif
-    {MNG_FN_SETCB_GETALPHALINE,        "setcb_getalphaline"},
-    {MNG_FN_SETCB_PROCESSSAVE,         "setcb_processsave"},
-    {MNG_FN_SETCB_PROCESSSEEK,         "setcb_processseek"},
-    {MNG_FN_SETCB_PROCESSNEED,         "setcb_processneed"},
-    {MNG_FN_SETCB_PROCESSUNKNOWN,      "setcb_processunknown"},
-    {MNG_FN_SETCB_PROCESSMEND,         "setcb_processmend"},
-    {MNG_FN_SETCB_PROCESSTERM,         "setcb_processterm"},
-    {MNG_FN_SETCB_RELEASEDATA,         "setcb_releasedata"},
-
-    {MNG_FN_GETCB_MEMALLOC,            "getcb_memalloc"},
-    {MNG_FN_GETCB_MEMFREE,             "getcb_memfree"},
-    {MNG_FN_GETCB_READDATA,            "getcb_readdata,"},
-    {MNG_FN_GETCB_WRITEDATA,           "getcb_writedata"},
-    {MNG_FN_GETCB_ERRORPROC,           "getcb_errorproc"},
-    {MNG_FN_GETCB_TRACEPROC,           "getcb_traceproc"},
-    {MNG_FN_GETCB_PROCESSHEADER,       "getcb_processheader"},
-    {MNG_FN_GETCB_PROCESSTEXT,         "getcb_processtext"},
-    {MNG_FN_GETCB_GETCANVASLINE,       "getcb_getcanvasline"},
-    {MNG_FN_GETCB_GETBKGDLINE,         "getcb_getbkgdline"},
-    {MNG_FN_GETCB_REFRESH,             "getcb_refresh"},
-    {MNG_FN_GETCB_GETTICKCOUNT,        "getcb_gettickcount"},
-    {MNG_FN_GETCB_SETTIMER,            "getcb_settimer"},
-    {MNG_FN_GETCB_PROCESSGAMMA,        "getcb_processgamma"},
-    {MNG_FN_GETCB_PROCESSCHROMA,       "getcb_processchroma"},
-    {MNG_FN_GETCB_PROCESSSRGB,         "getcb_processsrgb"},
-    {MNG_FN_GETCB_PROCESSICCP,         "getcb_processiccp"},
-    {MNG_FN_GETCB_PROCESSAROW,         "getcb_processarow"},
-#ifndef MNG_NO_OPEN_CLOSE_STREAM
-    {MNG_FN_GETCB_OPENSTREAM,          "getcb_openstream"},
-    {MNG_FN_GETCB_CLOSESTREAM,         "getcb_closestream"},
-#endif
-    {MNG_FN_GETCB_GETALPHALINE,        "getcb_getalphaline"},
-    {MNG_FN_GETCB_PROCESSSAVE,         "getcb_processsave"},
-    {MNG_FN_GETCB_PROCESSSEEK,         "getcb_processseek"},
-    {MNG_FN_GETCB_PROCESSNEED,         "getcb_processneed"},
-    {MNG_FN_GETCB_PROCESSUNKNOWN,      "getcb_processunknown"},
-    {MNG_FN_GETCB_PROCESSMEND,         "getcb_processmend"},
-    {MNG_FN_GETCB_PROCESSTERM,         "getcb_processterm"},
-    {MNG_FN_GETCB_RELEASEDATA,         "getcb_releasedata"},
-
-    {MNG_FN_SET_USERDATA,              "set_userdata"},
-    {MNG_FN_SET_CANVASSTYLE,           "set_canvasstyle"},
-    {MNG_FN_SET_BKGDSTYLE,             "set_bkgdstyle"},
-    {MNG_FN_SET_BGCOLOR,               "set_bgcolor"},
-    {MNG_FN_SET_STORECHUNKS,           "set_storechunks"},
-#if defined(MNG_FULL_CMS) || defined(MNG_GAMMA_ONLY) || defined(MNG_APP_CMS)
-    {MNG_FN_SET_VIEWGAMMA,             "set_viewgamma"},
-#ifndef MNG_NO_DFLT_INFO
-    {MNG_FN_SET_DISPLAYGAMMA,          "set_displaygamma"},
-#endif
-    {MNG_FN_SET_DFLTIMGGAMMA,          "set_dfltimggamma"},
-#endif
-    {MNG_FN_SET_SRGB,                  "set_srgb"},
-    {MNG_FN_SET_OUTPUTPROFILE,         "set_outputprofile"},
-    {MNG_FN_SET_SRGBPROFILE,           "set_srgbprofile"},
-#ifndef MNG_SKIP_MAXCANVAS
-    {MNG_FN_SET_MAXCANVASWIDTH,        "set_maxcanvaswidth"},
-    {MNG_FN_SET_MAXCANVASHEIGHT,       "set_maxcanvasheight"},
-    {MNG_FN_SET_MAXCANVASSIZE,         "set_maxcanvassize"},
-#endif
-#ifndef MNG_NO_ACCESS_ZLIB
-    {MNG_FN_SET_ZLIB_LEVEL,            "set_zlib_level"},
-    {MNG_FN_SET_ZLIB_METHOD,           "set_zlib_method"},
-    {MNG_FN_SET_ZLIB_WINDOWBITS,       "set_zlib_windowbits"},
-    {MNG_FN_SET_ZLIB_MEMLEVEL,         "set_zlib_memlevel"},
-    {MNG_FN_SET_ZLIB_STRATEGY,         "set_zlib_strategy"},
-    {MNG_FN_SET_ZLIB_MAXIDAT,          "set_zlib_maxidat"},
-#endif
-#ifndef MNG_NO_ACCESS_JPEG
-    {MNG_FN_SET_JPEG_DCTMETHOD,        "set_jpeg_dctmethod"},
-    {MNG_FN_SET_JPEG_QUALITY,          "set_jpeg_quality"},
-    {MNG_FN_SET_JPEG_SMOOTHING,        "set_jpeg_smoothing"},
-    {MNG_FN_SET_JPEG_PROGRESSIVE,      "set_jpeg_progressive"},
-    {MNG_FN_SET_JPEG_OPTIMIZED,        "set_jpeg_optimized"},
-    {MNG_FN_SET_JPEG_MAXJDAT,          "set_jpeg_maxjdat"},
-#endif
-    {MNG_FN_SET_SPEED,                 "set_speed"},
-    {MNG_FN_SET_SUSPENSIONMODE,        "set_suspensionmode"},
-    {MNG_FN_SET_SECTIONBREAKS,         "set_sectionbreaks"},
-    {MNG_FN_SET_USEBKGD,               "set_usebkgd"},
-    {MNG_FN_SET_OUTPUTPROFILE2,        "set_outputprofile2"},
-    {MNG_FN_SET_SRGBPROFILE2,          "set_srgbprofile2"},
-    {MNG_FN_SET_OUTPUTSRGB,            "set_outputsrgb"},
-    {MNG_FN_SET_SRGBIMPLICIT,          "set_srgbimplicit"},
-    {MNG_FN_SET_CACHEPLAYBACK,         "set_cacheplayback"},
-    {MNG_FN_SET_DOPROGRESSIVE,         "set_doprogressive"},
-    {MNG_FN_SET_CRCMODE,               "set_crcmode"},
-
-    {MNG_FN_GET_USERDATA,              "get_userdata"},
-    {MNG_FN_GET_SIGTYPE,               "get_sigtype"},
-    {MNG_FN_GET_IMAGETYPE,             "get_imagetype"},
-    {MNG_FN_GET_IMAGEWIDTH,            "get_imagewidth"},
-    {MNG_FN_GET_IMAGEHEIGHT,           "get_imageheight"},
-    {MNG_FN_GET_TICKS,                 "get_ticks"},
-    {MNG_FN_GET_FRAMECOUNT,            "get_framecount"},
-    {MNG_FN_GET_LAYERCOUNT,            "get_layercount"},
-    {MNG_FN_GET_PLAYTIME,              "get_playtime"},
-    {MNG_FN_GET_SIMPLICITY,            "get_simplicity"},
-    {MNG_FN_GET_CANVASSTYLE,           "get_canvasstyle"},
-    {MNG_FN_GET_BKGDSTYLE,             "get_bkgdstyle"},
-    {MNG_FN_GET_BGCOLOR,               "get_bgcolor"},
-    {MNG_FN_GET_STORECHUNKS,           "get_storechunks"},
-#if defined(MNG_FULL_CMS) || defined(MNG_GAMMA_ONLY) || defined(MNG_APP_CMS)
-    {MNG_FN_GET_VIEWGAMMA,             "get_viewgamma"},
-    {MNG_FN_GET_DISPLAYGAMMA,          "get_displaygamma"},
-#ifndef MNG_NO_DFLT_INFO
-    {MNG_FN_GET_DFLTIMGGAMMA,          "get_dfltimggamma"},
-#endif
-#endif
-    {MNG_FN_GET_SRGB,                  "get_srgb"},
-#ifndef MNG_SKIP_MAXCANVAS
-    {MNG_FN_GET_MAXCANVASWIDTH,        "get_maxcanvaswidth"},
-    {MNG_FN_GET_MAXCANVASHEIGHT,       "get_maxcanvasheight"},
-#endif
-#ifndef MNG_NO_ACCESS_ZLIB
-    {MNG_FN_GET_ZLIB_LEVEL,            "get_zlib_level"},
-    {MNG_FN_GET_ZLIB_METHOD,           "get_zlib_method"},
-    {MNG_FN_GET_ZLIB_WINDOWBITS,       "get_zlib_windowbits"},
-    {MNG_FN_GET_ZLIB_MEMLEVEL,         "get_zlib_memlevel"},
-    {MNG_FN_GET_ZLIB_STRATEGY,         "get_zlib_strategy"},
-    {MNG_FN_GET_ZLIB_MAXIDAT,          "get_zlib_maxidat"},
-#endif
-#ifndef MNG_NO_ACCESS_JPEG
-    {MNG_FN_GET_JPEG_DCTMETHOD,        "get_jpeg_dctmethod"},
-    {MNG_FN_GET_JPEG_QUALITY,          "get_jpeg_quality"},
-    {MNG_FN_GET_JPEG_SMOOTHING,        "get_jpeg_smoothing"},
-    {MNG_FN_GET_JPEG_PROGRESSIVE,      "get_jpeg_progressive"},
-    {MNG_FN_GET_JPEG_OPTIMIZED,        "get_jpeg_optimized"},
-    {MNG_FN_GET_JPEG_MAXJDAT,          "get_jpeg_maxjdat"},
-#endif
-    {MNG_FN_GET_SPEED,                 "get_speed"},
-    {MNG_FN_GET_IMAGELEVEL,            "get_imagelevel"},
-    {MNG_FN_GET_SUSPENSIONMODE,        "get_speed"},
-    {MNG_FN_GET_STARTTIME,             "get_starttime"},
-    {MNG_FN_GET_RUNTIME,               "get_runtime"},
-#ifndef MNG_NO_CURRENT_INFO
-    {MNG_FN_GET_CURRENTFRAME,          "get_currentframe"},
-    {MNG_FN_GET_CURRENTLAYER,          "get_currentlayer"},
-    {MNG_FN_GET_CURRENTPLAYTIME,       "get_currentplaytime"},
-#endif
-    {MNG_FN_GET_SECTIONBREAKS,         "get_sectionbreaks"},
-    {MNG_FN_GET_ALPHADEPTH,            "get_alphadepth"},
-    {MNG_FN_GET_BITDEPTH,              "get_bitdepth"},
-    {MNG_FN_GET_COLORTYPE,             "get_colortype"},
-    {MNG_FN_GET_COMPRESSION,           "get_compression"},
-    {MNG_FN_GET_FILTER,                "get_filter"},
-    {MNG_FN_GET_INTERLACE,             "get_interlace"},
-    {MNG_FN_GET_ALPHABITDEPTH,         "get_alphabitdepth"},
-    {MNG_FN_GET_ALPHACOMPRESSION,      "get_alphacompression"},
-    {MNG_FN_GET_ALPHAFILTER,           "get_alphafilter"},
-    {MNG_FN_GET_ALPHAINTERLACE,        "get_alphainterlace"},
-    {MNG_FN_GET_USEBKGD,               "get_usebkgd"},
-    {MNG_FN_GET_REFRESHPASS,           "get_refreshpass"},
-    {MNG_FN_GET_CACHEPLAYBACK,         "get_cacheplayback"},
-    {MNG_FN_GET_DOPROGRESSIVE,         "get_doprogressive"},
-    {MNG_FN_GET_LASTBACKCHUNK,         "get_lastbackchunk"},
-    {MNG_FN_GET_LASTSEEKNAME,          "get_lastseekname"},
-#ifndef MNG_NO_CURRENT_INFO
-    {MNG_FN_GET_TOTALFRAMES,           "get_totalframes"},
-    {MNG_FN_GET_TOTALLAYERS,           "get_totallayers"},
-    {MNG_FN_GET_TOTALPLAYTIME,         "get_totalplaytime"},
-#endif
-    {MNG_FN_GET_CRCMODE,               "get_crcmode"},
-    {MNG_FN_GET_CURRFRAMDELAY,         "get_currframdelay"},
-
-    {MNG_FN_STATUS_ERROR,              "status_error"},
-    {MNG_FN_STATUS_READING,            "status_reading"},
-    {MNG_FN_STATUS_SUSPENDBREAK,       "status_suspendbreak"},
-    {MNG_FN_STATUS_CREATING,           "status_creating"},
-    {MNG_FN_STATUS_WRITING,            "status_writing"},
-    {MNG_FN_STATUS_DISPLAYING,         "status_displaying"},
-    {MNG_FN_STATUS_RUNNING,            "status_running"},
-    {MNG_FN_STATUS_TIMERBREAK,         "status_timerbreak"},
-    {MNG_FN_STATUS_DYNAMIC,            "status_dynamic"},
-    {MNG_FN_STATUS_RUNNINGEVENT,       "status_runningevent"},
-
-    {MNG_FN_ITERATE_CHUNKS,            "iterate_chunks"},
-    {MNG_FN_COPY_CHUNK,                "copy_chunk"},
-
-    {MNG_FN_GETCHUNK_IHDR,             "getchunk_ihdr"},
-    {MNG_FN_GETCHUNK_PLTE,             "getchunk_plte"},
-    {MNG_FN_GETCHUNK_IDAT,             "getchunk_idat"},
-    {MNG_FN_GETCHUNK_IEND,             "getchunk_iend"},
-    {MNG_FN_GETCHUNK_TRNS,             "getchunk_trns"},
-#ifndef MNG_SKIPCHUNK_gAMA
-    {MNG_FN_GETCHUNK_GAMA,             "getchunk_gama"},
-#endif
-#ifndef MNG_SKIPCHUNK_cHRM
-    {MNG_FN_GETCHUNK_CHRM,             "getchunk_chrm"},
-#endif
-#ifndef MNG_SKIPCHUNK_sRGB
-    {MNG_FN_GETCHUNK_SRGB,             "getchunk_srgb"},
-#endif
-#ifndef MNG_SKIPCHUNK_iCCP
-    {MNG_FN_GETCHUNK_ICCP,             "getchunk_iccp"},
-#endif
-#ifndef MNG_SKIPCHUNK_tEXt
-    {MNG_FN_GETCHUNK_TEXT,             "getchunk_text"},
-#endif
-#ifndef MNG_SKIPCHUNK_zTXt
-    {MNG_FN_GETCHUNK_ZTXT,             "getchunk_ztxt"},
-#endif
-#ifndef MNG_SKIPCHUNK_iTXt
-    {MNG_FN_GETCHUNK_ITXT,             "getchunk_itxt"},
-#endif
-#ifndef MNG_SKIPCHUNK_bKGD
-    {MNG_FN_GETCHUNK_BKGD,             "getchunk_bkgd"},
-#endif
-#ifndef MNG_SKIPCHUNK_pHYs
-    {MNG_FN_GETCHUNK_PHYS,             "getchunk_phys"},
-#endif
-#ifndef MNG_SKIPCHUNK_sBIT
-    {MNG_FN_GETCHUNK_SBIT,             "getchunk_sbit"},
-#endif
-#ifndef MNG_SKIPCHUNK_sPLT
-    {MNG_FN_GETCHUNK_SPLT,             "getchunk_splt"},
-#endif
-#ifndef MNG_SKIPCHUNK_hIST
-    {MNG_FN_GETCHUNK_HIST,             "getchunk_hist"},
-#endif
-#ifndef MNG_SKIPCHUNK_tIME
-    {MNG_FN_GETCHUNK_TIME,             "getchunk_time"},
-#endif
-    {MNG_FN_GETCHUNK_MHDR,             "getchunk_mhdr"},
-    {MNG_FN_GETCHUNK_MEND,             "getchunk_mend"},
-#ifndef MNG_SKIPCHUNK_LOOP
-    {MNG_FN_GETCHUNK_LOOP,             "getchunk_loop"},
-    {MNG_FN_GETCHUNK_ENDL,             "getchunk_endl"},
-#endif
-    {MNG_FN_GETCHUNK_DEFI,             "getchunk_defi"},
-#ifndef MNG_SKIPCHUNK_BASI
-    {MNG_FN_GETCHUNK_BASI,             "getchunk_basi"},
-#endif
-    {MNG_FN_GETCHUNK_CLON,             "getchunk_clon"},
-#ifndef MNG_SKIPCHUNK_PAST
-    {MNG_FN_GETCHUNK_PAST,             "getchunk_past"},
-#endif
-    {MNG_FN_GETCHUNK_DISC,             "getchunk_disc"},
-    {MNG_FN_GETCHUNK_BACK,             "getchunk_back"},
-    {MNG_FN_GETCHUNK_FRAM,             "getchunk_fram"},
-    {MNG_FN_GETCHUNK_MOVE,             "getchunk_move"},
-    {MNG_FN_GETCHUNK_CLIP,             "getchunk_clip"},
-    {MNG_FN_GETCHUNK_SHOW,             "getchunk_show"},
-    {MNG_FN_GETCHUNK_TERM,             "getchunk_term"},
-#ifndef MNG_SKIPCHUNK_SAVE
-    {MNG_FN_GETCHUNK_SAVE,             "getchunk_save"},
-#endif
-#ifndef MNG_SKIPCHUNK_SEEK
-    {MNG_FN_GETCHUNK_SEEK,             "getchunk_seek"},
-#endif
-#ifndef MNG_SKIPCHUNK_eXPI
-    {MNG_FN_GETCHUNK_EXPI,             "getchunk_expi"},
-#endif
-#ifndef MNG_SKIPCHUNK_fPRI
-    {MNG_FN_GETCHUNK_FPRI,             "getchunk_fpri"},
-#endif
-#ifndef MNG_SKIPCHUNK_nEED
-    {MNG_FN_GETCHUNK_NEED,             "getchunk_need"},
-#endif
-#ifndef MNG_SKIPCHUNK_pHYg
-    {MNG_FN_GETCHUNK_PHYG,             "getchunk_phyg"},
-#endif
-#ifdef MNG_INCLUDE_JNG
-    {MNG_FN_GETCHUNK_JHDR,             "getchunk_jhdr"},
-    {MNG_FN_GETCHUNK_JDAT,             "getchunk_jdat"},
-    {MNG_FN_GETCHUNK_JSEP,             "getchunk_jsep"},
-#endif
-#ifndef MNG_NO_DELTA_PNG
-    {MNG_FN_GETCHUNK_DHDR,             "getchunk_dhdr"},
-    {MNG_FN_GETCHUNK_PROM,             "getchunk_prom"},
-    {MNG_FN_GETCHUNK_IPNG,             "getchunk_ipng"},
-    {MNG_FN_GETCHUNK_PPLT,             "getchunk_pplt"},
-#ifdef MNG_INCLUDE_JNG
-    {MNG_FN_GETCHUNK_IJNG,             "getchunk_ijng"},
-#endif
-#ifndef MNG_SKIPCHUNK_DROP
-    {MNG_FN_GETCHUNK_DROP,             "getchunk_drop"},
-#endif
-#ifndef MNG_SKIPCHUNK_DBYK
-    {MNG_FN_GETCHUNK_DBYK,             "getchunk_dbyk"},
-#endif
-#ifndef MNG_SKIPCHUNK_ORDR
-    {MNG_FN_GETCHUNK_ORDR,             "getchunk_ordr"},
-#endif
-#endif
-    {MNG_FN_GETCHUNK_UNKNOWN,          "getchunk_unknown"},
-    {MNG_FN_GETCHUNK_MAGN,             "getchunk_magn"},
-#ifdef MNG_INCLUDE_JNG
-    {MNG_FN_GETCHUNK_JDAA,             "getchunk_jdaa"},
-#endif
-#ifndef MNG_SKIPCHUNK_evNT
-    {MNG_FN_GETCHUNK_EVNT,             "getchunk_evnt"},
-#endif
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-    {MNG_FN_GETCHUNK_MPNG,             "getchunk_mpng"},
-#endif
-
-#ifndef MNG_SKIPCHUNK_PAST
-    {MNG_FN_GETCHUNK_PAST_SRC,         "getchunk_past_src"},
-#endif
-#ifndef MNG_SKIPCHUNK_SAVE
-    {MNG_FN_GETCHUNK_SAVE_ENTRY,       "getchunk_save_entry"},
-#endif
-#ifndef MNG_NO_DELTA_PNG
-    {MNG_FN_GETCHUNK_PPLT_ENTRY,       "getchunk_pplt_entry"},
-    {MNG_FN_GETCHUNK_ORDR_ENTRY,       "getchunk_ordr_entry"},
-#endif
-#ifndef MNG_SKIPCHUNK_evNT
-    {MNG_FN_GETCHUNK_EVNT_ENTRY,       "getchunk_evnt_entry"},
-#endif
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-    {MNG_FN_GETCHUNK_MPNG_FRAME,       "getchunk_mpng_frame"},
-#endif
-
-    {MNG_FN_PUTCHUNK_IHDR,             "putchunk_ihdr"},
-    {MNG_FN_PUTCHUNK_PLTE,             "putchunk_plte"},
-    {MNG_FN_PUTCHUNK_IDAT,             "putchunk_idat"},
-    {MNG_FN_PUTCHUNK_IEND,             "putchunk_iend"},
-    {MNG_FN_PUTCHUNK_TRNS,             "putchunk_trns"},
-#ifndef MNG_SKIPCHUNK_gAMA
-    {MNG_FN_PUTCHUNK_GAMA,             "putchunk_gama"},
-#endif
-#ifndef MNG_SKIPCHUNK_cHRM
-    {MNG_FN_PUTCHUNK_CHRM,             "putchunk_chrm"},
-#endif
-#ifndef MNG_SKIPCHUNK_sRGB
-    {MNG_FN_PUTCHUNK_SRGB,             "putchunk_srgb"},
-#endif
-#ifndef MNG_SKIPCHUNK_iCCP
-    {MNG_FN_PUTCHUNK_ICCP,             "putchunk_iccp"},
-#endif
-#ifndef MNG_SKIPCHUNK_tEXt
-    {MNG_FN_PUTCHUNK_TEXT,             "putchunk_text"},
-#endif
-#ifndef MNG_SKIPCHUNK_zTXt
-    {MNG_FN_PUTCHUNK_ZTXT,             "putchunk_ztxt"},
-#endif
-#ifndef MNG_SKIPCHUNK_iTXt
-    {MNG_FN_PUTCHUNK_ITXT,             "putchunk_itxt"},
-#endif
-#ifndef MNG_SKIPCHUNK_bKGD
-    {MNG_FN_PUTCHUNK_BKGD,             "putchunk_bkgd"},
-#endif
-#ifndef MNG_SKIPCHUNK_pHYs
-    {MNG_FN_PUTCHUNK_PHYS,             "putchunk_phys"},
-#endif
-#ifndef MNG_SKIPCHUNK_sBIT
-    {MNG_FN_PUTCHUNK_SBIT,             "putchunk_sbit"},
-#endif
-#ifndef MNG_SKIPCHUNK_sPLT
-    {MNG_FN_PUTCHUNK_SPLT,             "putchunk_splt"},
-#endif
-#ifndef MNG_SKIPCHUNK_hIST
-    {MNG_FN_PUTCHUNK_HIST,             "putchunk_hist"},
-#endif
-#ifndef MNG_SKIPCHUNK_tIME
-    {MNG_FN_PUTCHUNK_TIME,             "putchunk_time"},
-#endif
-    {MNG_FN_PUTCHUNK_MHDR,             "putchunk_mhdr"},
-    {MNG_FN_PUTCHUNK_MEND,             "putchunk_mend"},
-    {MNG_FN_PUTCHUNK_LOOP,             "putchunk_loop"},
-    {MNG_FN_PUTCHUNK_ENDL,             "putchunk_endl"},
-    {MNG_FN_PUTCHUNK_DEFI,             "putchunk_defi"},
-    {MNG_FN_PUTCHUNK_BASI,             "putchunk_basi"},
-    {MNG_FN_PUTCHUNK_CLON,             "putchunk_clon"},
-#ifndef MNG_SKIPCHUNK_PAST
-    {MNG_FN_PUTCHUNK_PAST,             "putchunk_past"},
-#endif
-    {MNG_FN_PUTCHUNK_DISC,             "putchunk_disc"},
-    {MNG_FN_PUTCHUNK_BACK,             "putchunk_back"},
-    {MNG_FN_PUTCHUNK_FRAM,             "putchunk_fram"},
-    {MNG_FN_PUTCHUNK_MOVE,             "putchunk_move"},
-    {MNG_FN_PUTCHUNK_CLIP,             "putchunk_clip"},
-    {MNG_FN_PUTCHUNK_SHOW,             "putchunk_show"},
-    {MNG_FN_PUTCHUNK_TERM,             "putchunk_term"},
-#ifndef MNG_SKIPCHUNK_SAVE
-    {MNG_FN_PUTCHUNK_SAVE,             "putchunk_save"},
-#endif
-#ifndef MNG_SKIPCHUNK_SEEK
-    {MNG_FN_PUTCHUNK_SEEK,             "putchunk_seek"},
-#endif
-#ifndef MNG_SKIPCHUNK_eXPI
-    {MNG_FN_PUTCHUNK_EXPI,             "putchunk_expi"},
-#endif
-#ifndef MNG_SKIPCHUNK_fPRI
-    {MNG_FN_PUTCHUNK_FPRI,             "putchunk_fpri"},
-#endif
-#ifndef MNG_SKIPCHUNK_nEED
-    {MNG_FN_PUTCHUNK_NEED,             "putchunk_need"},
-#endif
-#ifndef MNG_SKIPCHUNK_pHYg
-    {MNG_FN_PUTCHUNK_PHYG,             "putchunk_phyg"},
-#endif
-#ifdef MNG_INCLUDE_JNG
-    {MNG_FN_PUTCHUNK_JHDR,             "putchunk_jhdr"},
-    {MNG_FN_PUTCHUNK_JDAT,             "putchunk_jdat"},
-    {MNG_FN_PUTCHUNK_JSEP,             "putchunk_jsep"},
-#endif
-#ifndef MNG_NO_DELTA_PNG
-    {MNG_FN_PUTCHUNK_DHDR,             "putchunk_dhdr"},
-    {MNG_FN_PUTCHUNK_PROM,             "putchunk_prom"},
-#ifdef MNG_INCLUDE_JNG
-    {MNG_FN_PUTCHUNK_IPNG,             "putchunk_ipng"},
-#endif
-    {MNG_FN_PUTCHUNK_PPLT,             "putchunk_pplt"},
-    {MNG_FN_PUTCHUNK_IJNG,             "putchunk_ijng"},
-#ifndef MNG_SKIPCHUNK_DROP
-    {MNG_FN_PUTCHUNK_DROP,             "putchunk_drop"},
-#endif
-#ifndef MNG_SKIPCHUNK_DBYK
-    {MNG_FN_PUTCHUNK_DBYK,             "putchunk_dbyk"},
-#endif
-#ifndef MNG_SKIPCHUNK_ORDR
-    {MNG_FN_PUTCHUNK_ORDR,             "putchunk_ordr"},
-#endif
-#endif
-    {MNG_FN_PUTCHUNK_UNKNOWN,          "putchunk_unknown"},
-    {MNG_FN_PUTCHUNK_MAGN,             "putchunk_magn"},
-    {MNG_FN_PUTCHUNK_JDAA,             "putchunk_jdaa"},
-#ifndef MNG_SKIPCHUNK_evNT
-    {MNG_FN_PUTCHUNK_EVNT,             "putchunk_evnt"},
-#endif
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-    {MNG_FN_PUTCHUNK_MPNG,             "putchunk_mpng"},
-#endif
-
-#ifndef MNG_SKIPCHUNK_PAST
-    {MNG_FN_PUTCHUNK_PAST_SRC,         "putchunk_past_src"},
-#endif
-#ifndef MNG_SKIPCHUNK_SAVE
-    {MNG_FN_PUTCHUNK_SAVE_ENTRY,       "putchunk_save_entry"},
-#endif
-#ifndef MNG_NO_DELTA_PNG
-    {MNG_FN_PUTCHUNK_PPLT_ENTRY,       "putchunk_pplt_entry"},
-#ifndef MNG_SKIPCHUNK_ORDR
-    {MNG_FN_PUTCHUNK_ORDR_ENTRY,       "putchunk_ordr_entry"},
-#endif
-#endif
-#ifndef MNG_SKIPCHUNK_evNT
-    {MNG_FN_PUTCHUNK_EVNT_ENTRY,       "putchunk_evnt_entry"},
-#endif
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-    {MNG_FN_PUTCHUNK_MPNG_FRAME,       "putchunk_mpng_frame"},
-#endif
-
-    {MNG_FN_GETIMGDATA_SEQ,            "getimgdata_seq"},
-    {MNG_FN_GETIMGDATA_CHUNKSEQ,       "getimgdata_chunkseq"},
-    {MNG_FN_GETIMGDATA_CHUNK,          "getimgdata_chunk"},
-
-    {MNG_FN_PUTIMGDATA_IHDR,           "putimgdata_ihdr"},
-#ifdef MNG_INCLUDE_JNG
-    {MNG_FN_PUTIMGDATA_JHDR,           "putimgdata_jhdr"},
-    {MNG_FN_PUTIMGDATA_BASI,           "putimgdata_basi"},
-    {MNG_FN_PUTIMGDATA_DHDR,           "putimgdata_dhdr"},
-#endif
-
-    {MNG_FN_UPDATEMNGHEADER,           "updatemngheader"},
-    {MNG_FN_UPDATEMNGSIMPLICITY,       "updatemngsimplicity"},
-
-    {MNG_FN_PROCESS_RAW_CHUNK,         "process_raw_chunk"},
-    {MNG_FN_READ_GRAPHIC,              "read_graphic"},
-    {MNG_FN_DROP_CHUNKS,               "drop_chunks"},
-    {MNG_FN_PROCESS_ERROR,             "process_error"},
-    {MNG_FN_CLEAR_CMS,                 "clear_cms"},
-    {MNG_FN_DROP_OBJECTS,              "drop_objects"},
-    {MNG_FN_READ_CHUNK,                "read_chunk"},
-    {MNG_FN_LOAD_BKGDLAYER,            "load_bkgdlayer"},
-    {MNG_FN_NEXT_FRAME,                "next_frame"},
-    {MNG_FN_NEXT_LAYER,                "next_layer"},
-    {MNG_FN_INTERFRAME_DELAY,          "interframe_delay"},
-    {MNG_FN_DISPLAY_IMAGE,             "display_image"},
-    {MNG_FN_DROP_IMGOBJECTS,           "drop_imgobjects"},
-    {MNG_FN_DROP_ANIOBJECTS,           "drop_aniobjects"},
-    {MNG_FN_INFLATE_BUFFER,            "inflate_buffer"},
-    {MNG_FN_DEFLATE_BUFFER,            "deflate_buffer"},
-    {MNG_FN_WRITE_RAW_CHUNK,           "write_raw_chunk"},
-    {MNG_FN_WRITE_GRAPHIC,             "write_graphic"},
-    {MNG_FN_SAVE_STATE,                "save_state"},
-    {MNG_FN_RESTORE_STATE,             "restore_state"},
-    {MNG_FN_DROP_SAVEDATA,             "drop_savedata"},
-#ifndef MNG_NO_DELTA_PNG
-    {MNG_FN_EXECUTE_DELTA_IMAGE,       "execute_delta_image"},
-#endif
-    {MNG_FN_PROCESS_DISPLAY,           "process_display"},
-    {MNG_FN_CLEAR_CANVAS,              "clear_canvas"},
-    {MNG_FN_READ_DATABUFFER,           "read_databuffer"},
-    {MNG_FN_STORE_ERROR,               "store_error"},
-    {MNG_FN_DROP_INVALID_OBJECTS,      "drop_invalid_objects"},
-    {MNG_FN_RELEASE_PUSHDATA,          "release_pushdata"},
-    {MNG_FN_READ_DATA,                 "read_data"},
-    {MNG_FN_READ_CHUNK_CRC,            "read_chunk_crc"},
-    {MNG_FN_RELEASE_PUSHCHUNK,         "release_pushchunk"},
-
-    {MNG_FN_DISPLAY_RGB8,              "display_rgb8"},
-    {MNG_FN_DISPLAY_RGBA8,             "display_rgba8"},
-    {MNG_FN_DISPLAY_ARGB8,             "display_argb8"},
-    {MNG_FN_DISPLAY_BGR8,              "display_bgr8"},
-    {MNG_FN_DISPLAY_BGRA8,             "display_bgra8"},
-    {MNG_FN_DISPLAY_ABGR8,             "display_abgr8"},
-    {MNG_FN_DISPLAY_RGB16,             "display_rgb16"},
-    {MNG_FN_DISPLAY_RGBA16,            "display_rgba16"},
-    {MNG_FN_DISPLAY_ARGB16,            "display_argb16"},
-    {MNG_FN_DISPLAY_BGR16,             "display_bgr16"},
-    {MNG_FN_DISPLAY_BGRA16,            "display_bgra16"},
-    {MNG_FN_DISPLAY_ABGR16,            "display_abgr16"},
-    {MNG_FN_DISPLAY_INDEX8,            "display_index8"},
-    {MNG_FN_DISPLAY_INDEXA8,           "display_indexa8"},
-    {MNG_FN_DISPLAY_AINDEX8,           "display_aindex8"},
-    {MNG_FN_DISPLAY_GRAY8,             "display_gray8"},
-    {MNG_FN_DISPLAY_GRAY16,            "display_gray16"},
-    {MNG_FN_DISPLAY_GRAYA8,            "display_graya8"},
-    {MNG_FN_DISPLAY_GRAYA16,           "display_graya16"},
-    {MNG_FN_DISPLAY_AGRAY8,            "display_agray8"},
-    {MNG_FN_DISPLAY_AGRAY16,           "display_agray16"},
-    {MNG_FN_DISPLAY_DX15,              "display_dx15"},
-    {MNG_FN_DISPLAY_DX16,              "display_dx16"},
-    {MNG_FN_DISPLAY_RGB8_A8,           "display_rgb8_a8"},
-    {MNG_FN_DISPLAY_BGRA8PM,           "display_bgra8_pm"},
-    {MNG_FN_DISPLAY_BGRX8,             "display_bgrx8"},
-    {MNG_FN_DISPLAY_RGB565,            "display_rgb565"},
-    {MNG_FN_DISPLAY_RGBA565,           "display_rgba565"},
-    {MNG_FN_DISPLAY_BGR565,            "display_bgr565"},
-    {MNG_FN_DISPLAY_BGRA565,           "display_bgra565"},
-    {MNG_FN_DISPLAY_RGBA8_PM,          "display_rgba8_pm"},
-    {MNG_FN_DISPLAY_ARGB8_PM,          "display_argb8_pm"},
-    {MNG_FN_DISPLAY_ABGR8_PM,          "display_abgr8_pm"},
-    {MNG_FN_DISPLAY_BGR565_A8,         "display_bgr565_a8"},
-
-    {MNG_FN_INIT_FULL_CMS,             "init_full_cms"},
-    {MNG_FN_CORRECT_FULL_CMS,          "correct_full_cms"},
-    {MNG_FN_INIT_GAMMA_ONLY,           "init_gamma_only"},
-    {MNG_FN_CORRECT_GAMMA_ONLY,        "correct_gamma_only"},
-    {MNG_FN_CORRECT_APP_CMS,           "correct_app_cms"},
-    {MNG_FN_INIT_FULL_CMS_OBJ,         "init_full_cms_obj"},
-    {MNG_FN_INIT_GAMMA_ONLY_OBJ,       "init_gamma_only_obj"},
-    {MNG_FN_INIT_APP_CMS,              "init_app_cms"},
-    {MNG_FN_INIT_APP_CMS_OBJ,          "init_app_cms_obj"},
-
-    {MNG_FN_PROCESS_G1,                "process_g1"},
-    {MNG_FN_PROCESS_G2,                "process_g2"},
-    {MNG_FN_PROCESS_G4,                "process_g4"},
-    {MNG_FN_PROCESS_G8,                "process_g8"},
-    {MNG_FN_PROCESS_G16,               "process_g16"},
-    {MNG_FN_PROCESS_RGB8,              "process_rgb8"},
-    {MNG_FN_PROCESS_RGB16,             "process_rgb16"},
-    {MNG_FN_PROCESS_IDX1,              "process_idx1"},
-    {MNG_FN_PROCESS_IDX2,              "process_idx2"},
-    {MNG_FN_PROCESS_IDX4,              "process_idx4"},
-    {MNG_FN_PROCESS_IDX8,              "process_idx8"},
-    {MNG_FN_PROCESS_GA8,               "process_ga8"},
-    {MNG_FN_PROCESS_GA16,              "process_ga16"},
-    {MNG_FN_PROCESS_RGBA8,             "process_rgba8"},
-    {MNG_FN_PROCESS_RGBA16,            "process_rgba16"},
-
-    {MNG_FN_INIT_G1_I,                 "init_g1_i"},
-    {MNG_FN_INIT_G2_I,                 "init_g2_i"},
-    {MNG_FN_INIT_G4_I,                 "init_g4_i"},
-    {MNG_FN_INIT_G8_I,                 "init_g8_i"},
-    {MNG_FN_INIT_G16_I,                "init_g16_i"},
-    {MNG_FN_INIT_RGB8_I,               "init_rgb8_i"},
-    {MNG_FN_INIT_RGB16_I,              "init_rgb16_i"},
-    {MNG_FN_INIT_IDX1_I,               "init_idx1_i"},
-    {MNG_FN_INIT_IDX2_I,               "init_idx2_i"},
-    {MNG_FN_INIT_IDX4_I,               "init_idx4_i"},
-    {MNG_FN_INIT_IDX8_I,               "init_idx8_i"},
-    {MNG_FN_INIT_GA8_I,                "init_ga8_i"},
-    {MNG_FN_INIT_GA16_I,               "init_ga16_i"},
-    {MNG_FN_INIT_RGBA8_I,              "init_rgba8_i"},
-    {MNG_FN_INIT_RGBA16_I,             "init_rgba16_i"},
-#ifndef MNG_OPTIMIZE_FOOTPRINT_INIT
-    {MNG_FN_INIT_G1_NI,                "init_g1_ni"},
-    {MNG_FN_INIT_G2_NI,                "init_g2_ni"},
-    {MNG_FN_INIT_G4_NI,                "init_g4_ni"},
-    {MNG_FN_INIT_G8_NI,                "init_g8_ni"},
-    {MNG_FN_INIT_G16_NI,               "init_g16_ni"},
-    {MNG_FN_INIT_RGB8_NI,              "init_rgb8_ni"},
-    {MNG_FN_INIT_RGB16_NI,             "init_rgb16_ni"},
-    {MNG_FN_INIT_IDX1_NI,              "init_idx1_ni"},
-    {MNG_FN_INIT_IDX2_NI,              "init_idx2_ni"},
-    {MNG_FN_INIT_IDX4_NI,              "init_idx4_ni"},
-    {MNG_FN_INIT_IDX8_NI,              "init_idx8_ni"},
-    {MNG_FN_INIT_GA8_NI,               "init_ga8_ni"},
-    {MNG_FN_INIT_GA16_NI,              "init_ga16_ni"},
-    {MNG_FN_INIT_RGBA8_NI,             "init_rgba8_ni"},
-    {MNG_FN_INIT_RGBA16_NI,            "init_rgba16_ni"},
-#endif
-
-    {MNG_FN_INIT_ROWPROC,              "init_rowproc"},
-    {MNG_FN_NEXT_ROW,                  "next_row"},
-    {MNG_FN_CLEANUP_ROWPROC,           "cleanup_rowproc"},
-
-    {MNG_FN_FILTER_A_ROW,              "filter_a_row"},
-    {MNG_FN_FILTER_SUB,                "filter_sub"},
-    {MNG_FN_FILTER_UP,                 "filter_up"},
-    {MNG_FN_FILTER_AVERAGE,            "filter_average"},
-    {MNG_FN_FILTER_PAETH,              "filter_paeth"},
-
-    {MNG_FN_INIT_ROWDIFFERING,         "init_rowdiffering"},
-    {MNG_FN_DIFFER_G1,                 "differ_g1"},
-    {MNG_FN_DIFFER_G2,                 "differ_g2"},
-    {MNG_FN_DIFFER_G4,                 "differ_g4"},
-    {MNG_FN_DIFFER_G8,                 "differ_g8"},
-    {MNG_FN_DIFFER_G16,                "differ_g16"},
-    {MNG_FN_DIFFER_RGB8,               "differ_rgb8"},
-    {MNG_FN_DIFFER_RGB16,              "differ_rgb16"},
-    {MNG_FN_DIFFER_IDX1,               "differ_idx1"},
-    {MNG_FN_DIFFER_IDX2,               "differ_idx2"},
-    {MNG_FN_DIFFER_IDX4,               "differ_idx4"},
-    {MNG_FN_DIFFER_IDX8,               "differ_idx8"},
-    {MNG_FN_DIFFER_GA8,                "differ_ga8"},
-    {MNG_FN_DIFFER_GA16,               "differ_ga16"},
-    {MNG_FN_DIFFER_RGBA8,              "differ_rgba8"},
-    {MNG_FN_DIFFER_RGBA16,             "differ_rgba16"},
-
-    {MNG_FN_CREATE_IMGDATAOBJECT,      "create_imgdataobject"},
-    {MNG_FN_FREE_IMGDATAOBJECT,        "free_imgdataobject"},
-    {MNG_FN_CLONE_IMGDATAOBJECT,       "clone_imgdataobject"},
-    {MNG_FN_CREATE_IMGOBJECT,          "create_imgobject"},
-    {MNG_FN_FREE_IMGOBJECT,            "free_imgobject"},
-    {MNG_FN_FIND_IMGOBJECT,            "find_imgobject"},
-    {MNG_FN_CLONE_IMGOBJECT,           "clone_imgobject"},
-    {MNG_FN_RESET_OBJECTDETAILS,       "reset_objectdetails"},
-    {MNG_FN_RENUM_IMGOBJECT,           "renum_imgobject"},
-    {MNG_FN_PROMOTE_IMGOBJECT,         "promote_imgobject"},
-    {MNG_FN_MAGNIFY_IMGOBJECT,         "magnify_imgobject"},
-    {MNG_FN_COLORCORRECT_OBJECT,       "colorcorrect_object"},
-
-    {MNG_FN_STORE_G1,                  "store_g1"},
-    {MNG_FN_STORE_G2,                  "store_g2"},
-    {MNG_FN_STORE_G4,                  "store_g4"},
-    {MNG_FN_STORE_G8,                  "store_g8"},
-    {MNG_FN_STORE_G16,                 "store_g16"},
-    {MNG_FN_STORE_RGB8,                "store_rgb8"},
-    {MNG_FN_STORE_RGB16,               "store_rgb16"},
-    {MNG_FN_STORE_IDX1,                "store_idx1"},
-    {MNG_FN_STORE_IDX2,                "store_idx2"},
-    {MNG_FN_STORE_IDX4,                "store_idx4"},
-    {MNG_FN_STORE_IDX8,                "store_idx8"},
-    {MNG_FN_STORE_GA8,                 "store_ga8"},
-    {MNG_FN_STORE_GA16,                "store_ga16"},
-    {MNG_FN_STORE_RGBA8,               "store_rgba8"},
-    {MNG_FN_STORE_RGBA16,              "store_rgba16"},
-
-    {MNG_FN_RETRIEVE_G8,               "retrieve_g8"},
-    {MNG_FN_RETRIEVE_G16,              "retrieve_g16"},
-    {MNG_FN_RETRIEVE_RGB8,             "retrieve_rgb8"},
-    {MNG_FN_RETRIEVE_RGB16,            "retrieve_rgb16"},
-    {MNG_FN_RETRIEVE_IDX8,             "retrieve_idx8"},
-    {MNG_FN_RETRIEVE_GA8,              "retrieve_ga8"},
-    {MNG_FN_RETRIEVE_GA16,             "retrieve_ga16"},
-    {MNG_FN_RETRIEVE_RGBA8,            "retrieve_rgba8"},
-    {MNG_FN_RETRIEVE_RGBA16,           "retrieve_rgba16"},
-
-#ifndef MNG_NO_DELTA_PNG
-    {MNG_FN_DELTA_G1,                  "delta_g1"},
-    {MNG_FN_DELTA_G2,                  "delta_g2"},
-    {MNG_FN_DELTA_G4,                  "delta_g4"},
-    {MNG_FN_DELTA_G8,                  "delta_g8"},
-    {MNG_FN_DELTA_G16,                 "delta_g16"},
-    {MNG_FN_DELTA_RGB8,                "delta_rgb8"},
-    {MNG_FN_DELTA_RGB16,               "delta_rgb16"},
-    {MNG_FN_DELTA_IDX1,                "delta_idx1"},
-    {MNG_FN_DELTA_IDX2,                "delta_idx2"},
-    {MNG_FN_DELTA_IDX4,                "delta_idx4"},
-    {MNG_FN_DELTA_IDX8,                "delta_idx8"},
-    {MNG_FN_DELTA_GA8,                 "delta_ga8"},
-    {MNG_FN_DELTA_GA16,                "delta_ga16"},
-    {MNG_FN_DELTA_RGBA8,               "delta_rgba8"},
-    {MNG_FN_DELTA_RGBA16,              "delta_rgba16"},
-#endif
-
-    {MNG_FN_CREATE_ANI_LOOP,           "create_ani_loop"},
-    {MNG_FN_CREATE_ANI_ENDL,           "create_ani_endl"},
-    {MNG_FN_CREATE_ANI_DEFI,           "create_ani_defi"},
-    {MNG_FN_CREATE_ANI_BASI,           "create_ani_basi"},
-    {MNG_FN_CREATE_ANI_CLON,           "create_ani_clon"},
-#ifndef MNG_SKIPCHUNK_PAST
-    {MNG_FN_CREATE_ANI_PAST,           "create_ani_past"},
-#endif
-    {MNG_FN_CREATE_ANI_DISC,           "create_ani_disc"},
-    {MNG_FN_CREATE_ANI_BACK,           "create_ani_back"},
-    {MNG_FN_CREATE_ANI_FRAM,           "create_ani_fram"},
-    {MNG_FN_CREATE_ANI_MOVE,           "create_ani_move"},
-    {MNG_FN_CREATE_ANI_CLIP,           "create_ani_clip"},
-    {MNG_FN_CREATE_ANI_SHOW,           "create_ani_show"},
-    {MNG_FN_CREATE_ANI_TERM,           "create_ani_term"},
-    {MNG_FN_CREATE_ANI_SAVE,           "create_ani_save"},
-    {MNG_FN_CREATE_ANI_SEEK,           "create_ani_seek"},
-    {MNG_FN_CREATE_ANI_GAMA,           "create_ani_gama"},
-    {MNG_FN_CREATE_ANI_CHRM,           "create_ani_chrm"},
-    {MNG_FN_CREATE_ANI_SRGB,           "create_ani_srgb"},
-    {MNG_FN_CREATE_ANI_ICCP,           "create_ani_iccp"},
-    {MNG_FN_CREATE_ANI_PLTE,           "create_ani_plte"},
-    {MNG_FN_CREATE_ANI_TRNS,           "create_ani_trns"},
-    {MNG_FN_CREATE_ANI_BKGD,           "create_ani_bkgd"},
-#ifndef MNG_NO_DELTA_PNG
-    {MNG_FN_CREATE_ANI_DHDR,           "create_ani_dhdr"},
-    {MNG_FN_CREATE_ANI_PROM,           "create_ani_prom"},
-#ifdef MNG_INCLUDE_JNG
-    {MNG_FN_CREATE_ANI_IPNG,           "create_ani_ipng"},
-#endif
-    {MNG_FN_CREATE_ANI_IJNG,           "create_ani_ijng"},
-    {MNG_FN_CREATE_ANI_PPLT,           "create_ani_pplt"},
-#endif
-    {MNG_FN_CREATE_ANI_MAGN,           "create_ani_magn"},
-
-    {MNG_FN_CREATE_ANI_IMAGE,          "create_ani_image"},
-    {MNG_FN_CREATE_EVENT,              "create_event"},
-
-    {MNG_FN_FREE_ANI_LOOP,             "free_ani_loop"},
-    {MNG_FN_FREE_ANI_ENDL,             "free_ani_endl"},
-    {MNG_FN_FREE_ANI_DEFI,             "free_ani_defi"},
-    {MNG_FN_FREE_ANI_BASI,             "free_ani_basi"},
-    {MNG_FN_FREE_ANI_CLON,             "free_ani_clon"},
-#ifndef MNG_SKIPCHUNK_PAST
-    {MNG_FN_FREE_ANI_PAST,             "free_ani_past"},
-#endif
-    {MNG_FN_FREE_ANI_DISC,             "free_ani_disc"},
-    {MNG_FN_FREE_ANI_BACK,             "free_ani_back"},
-    {MNG_FN_FREE_ANI_FRAM,             "free_ani_fram"},
-    {MNG_FN_FREE_ANI_MOVE,             "free_ani_move"},
-    {MNG_FN_FREE_ANI_CLIP,             "free_ani_clip"},
-    {MNG_FN_FREE_ANI_SHOW,             "free_ani_show"},
-    {MNG_FN_FREE_ANI_TERM,             "free_ani_term"},
-    {MNG_FN_FREE_ANI_SAVE,             "free_ani_save"},
-    {MNG_FN_FREE_ANI_SEEK,             "free_ani_seek"},
-    {MNG_FN_FREE_ANI_GAMA,             "free_ani_gama"},
-    {MNG_FN_FREE_ANI_CHRM,             "free_ani_chrm"},
-    {MNG_FN_FREE_ANI_SRGB,             "free_ani_srgb"},
-    {MNG_FN_FREE_ANI_ICCP,             "free_ani_iccp"},
-    {MNG_FN_FREE_ANI_PLTE,             "free_ani_plte"},
-    {MNG_FN_FREE_ANI_TRNS,             "free_ani_trns"},
-    {MNG_FN_FREE_ANI_BKGD,             "free_ani_bkgd"},
-#ifndef MNG_NO_DELTA_PNG
-    {MNG_FN_FREE_ANI_DHDR,             "free_ani_dhdr"},
-    {MNG_FN_FREE_ANI_PROM,             "free_ani_prom"},
-#ifdef MNG_INCLUDE_JNG
-    {MNG_FN_FREE_ANI_IPNG,             "free_ani_ipng"},
-#endif
-    {MNG_FN_FREE_ANI_IJNG,             "free_ani_ijng"},
-    {MNG_FN_FREE_ANI_PPLT,             "free_ani_pplt"},
-#endif
-    {MNG_FN_FREE_ANI_MAGN,             "free_ani_magn"},
-
-    {MNG_FN_FREE_ANI_IMAGE,            "free_ani_image"},
-    {MNG_FN_FREE_EVENT,                "free_event"},
-
-    {MNG_FN_PROCESS_ANI_LOOP,          "process_ani_loop"},
-    {MNG_FN_PROCESS_ANI_ENDL,          "process_ani_endl"},
-    {MNG_FN_PROCESS_ANI_DEFI,          "process_ani_defi"},
-    {MNG_FN_PROCESS_ANI_BASI,          "process_ani_basi"},
-    {MNG_FN_PROCESS_ANI_CLON,          "process_ani_clon"},
-#ifndef MNG_SKIPCHUNK_PAST
-    {MNG_FN_PROCESS_ANI_PAST,          "process_ani_past"},
-#endif
-    {MNG_FN_PROCESS_ANI_DISC,          "process_ani_disc"},
-    {MNG_FN_PROCESS_ANI_BACK,          "process_ani_back"},
-    {MNG_FN_PROCESS_ANI_FRAM,          "process_ani_fram"},
-    {MNG_FN_PROCESS_ANI_MOVE,          "process_ani_move"},
-    {MNG_FN_PROCESS_ANI_CLIP,          "process_ani_clip"},
-    {MNG_FN_PROCESS_ANI_SHOW,          "process_ani_show"},
-    {MNG_FN_PROCESS_ANI_TERM,          "process_ani_term"},
-    {MNG_FN_PROCESS_ANI_SAVE,          "process_ani_save"},
-    {MNG_FN_PROCESS_ANI_SEEK,          "process_ani_seek"},
-    {MNG_FN_PROCESS_ANI_GAMA,          "process_ani_gama"},
-    {MNG_FN_PROCESS_ANI_CHRM,          "process_ani_chrm"},
-    {MNG_FN_PROCESS_ANI_SRGB,          "process_ani_srgb"},
-    {MNG_FN_PROCESS_ANI_ICCP,          "process_ani_iccp"},
-    {MNG_FN_PROCESS_ANI_PLTE,          "process_ani_plte"},
-    {MNG_FN_PROCESS_ANI_TRNS,          "process_ani_trns"},
-    {MNG_FN_PROCESS_ANI_BKGD,          "process_ani_bkgd"},
-#ifndef MNG_NO_DELTA_PNG
-    {MNG_FN_PROCESS_ANI_DHDR,          "process_ani_dhdr"},
-    {MNG_FN_PROCESS_ANI_PROM,          "process_ani_prom"},
-#ifdef MNG_INCLUDE_JNG
-    {MNG_FN_PROCESS_ANI_IPNG,          "process_ani_ipng"},
-#endif
-    {MNG_FN_PROCESS_ANI_IJNG,          "process_ani_ijng"},
-    {MNG_FN_PROCESS_ANI_PPLT,          "process_ani_pplt"},
-#endif
-    {MNG_FN_PROCESS_ANI_MAGN,          "process_ani_magn"},
-
-    {MNG_FN_PROCESS_ANI_IMAGE,         "process_ani_image"},
-    {MNG_FN_PROCESS_EVENT,             "process_event"},
-
-    {MNG_FN_RESTORE_BACKIMAGE,         "restore_backimage"},
-    {MNG_FN_RESTORE_BACKCOLOR,         "restore_backcolor"},
-    {MNG_FN_RESTORE_BGCOLOR,           "restore_bgcolor"},
-    {MNG_FN_RESTORE_RGB8,              "restore_rgb8"},
-    {MNG_FN_RESTORE_BGR8,              "restore_bgr8"},
-    {MNG_FN_RESTORE_BKGD,              "restore_bkgd"},
-    {MNG_FN_RESTORE_BGRX8,             "restore_bgrx8"},
-    {MNG_FN_RESTORE_RGB565,            "restore_rgb565"},
-
-    {MNG_FN_INIT_IHDR,                 "init_ihdr"},
-    {MNG_FN_INIT_PLTE,                 "init_plte"},
-    {MNG_FN_INIT_IDAT,                 "init_idat"},
-    {MNG_FN_INIT_IEND,                 "init_iend"},
-    {MNG_FN_INIT_TRNS,                 "init_trns"},
-    {MNG_FN_INIT_GAMA,                 "init_gama"},
-    {MNG_FN_INIT_CHRM,                 "init_chrm"},
-    {MNG_FN_INIT_SRGB,                 "init_srgb"},
-    {MNG_FN_INIT_ICCP,                 "init_iccp"},
-    {MNG_FN_INIT_TEXT,                 "init_text"},
-    {MNG_FN_INIT_ZTXT,                 "init_ztxt"},
-    {MNG_FN_INIT_ITXT,                 "init_itxt"},
-    {MNG_FN_INIT_BKGD,                 "init_bkgd"},
-    {MNG_FN_INIT_PHYS,                 "init_phys"},
-    {MNG_FN_INIT_SBIT,                 "init_sbit"},
-    {MNG_FN_INIT_SPLT,                 "init_splt"},
-    {MNG_FN_INIT_HIST,                 "init_hist"},
-    {MNG_FN_INIT_TIME,                 "init_time"},
-    {MNG_FN_INIT_MHDR,                 "init_mhdr"},
-    {MNG_FN_INIT_MEND,                 "init_mend"},
-    {MNG_FN_INIT_LOOP,                 "init_loop"},
-    {MNG_FN_INIT_ENDL,                 "init_endl"},
-    {MNG_FN_INIT_DEFI,                 "init_defi"},
-    {MNG_FN_INIT_BASI,                 "init_basi"},
-    {MNG_FN_INIT_CLON,                 "init_clon"},
-#ifndef MNG_SKIPCHUNK_PAST
-    {MNG_FN_INIT_PAST,                 "init_past"},
-#endif
-    {MNG_FN_INIT_DISC,                 "init_disc"},
-    {MNG_FN_INIT_BACK,                 "init_back"},
-    {MNG_FN_INIT_FRAM,                 "init_fram"},
-    {MNG_FN_INIT_MOVE,                 "init_move"},
-    {MNG_FN_INIT_CLIP,                 "init_clip"},
-    {MNG_FN_INIT_SHOW,                 "init_show"},
-    {MNG_FN_INIT_TERM,                 "init_term"},
-    {MNG_FN_INIT_SAVE,                 "init_save"},
-    {MNG_FN_INIT_SEEK,                 "init_seek"},
-    {MNG_FN_INIT_EXPI,                 "init_expi"},
-    {MNG_FN_INIT_FPRI,                 "init_fpri"},
-    {MNG_FN_INIT_NEED,                 "init_need"},
-    {MNG_FN_INIT_PHYG,                 "init_phyg"},
-#ifndef MNG_NO_DELTA_PNG
-    {MNG_FN_INIT_JHDR,                 "init_jhdr"},
-    {MNG_FN_INIT_JDAT,                 "init_jdat"},
-    {MNG_FN_INIT_JSEP,                 "init_jsep"},
-#endif
-#ifndef MNG_NO_DELTA_PNG
-    {MNG_FN_INIT_DHDR,                 "init_dhdr"},
-    {MNG_FN_INIT_PROM,                 "init_prom"},
-#ifdef MNG_INCLUDE_JNG
-    {MNG_FN_INIT_IPNG,                 "init_ipng"},
-#endif
-    {MNG_FN_INIT_PPLT,                 "init_pplt"},
-    {MNG_FN_INIT_IJNG,                 "init_ijng"},
-    {MNG_FN_INIT_DROP,                 "init_drop"},
-    {MNG_FN_INIT_DBYK,                 "init_dbyk"},
-    {MNG_FN_INIT_ORDR,                 "init_ordr"},
-#endif
-    {MNG_FN_INIT_UNKNOWN,              "init_unknown"},
-    {MNG_FN_INIT_MAGN,                 "init_magn"},
-    {MNG_FN_INIT_JDAA,                 "init_jdaa"},
-    {MNG_FN_INIT_EVNT,                 "init_evnt"},
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-    {MNG_FN_INIT_MPNG,                 "init_mpng"},
-#endif
-
-    {MNG_FN_ASSIGN_IHDR,               "assign_ihdr"},
-    {MNG_FN_ASSIGN_PLTE,               "assign_plte"},
-    {MNG_FN_ASSIGN_IDAT,               "assign_idat"},
-    {MNG_FN_ASSIGN_IEND,               "assign_iend"},
-    {MNG_FN_ASSIGN_TRNS,               "assign_trns"},
-    {MNG_FN_ASSIGN_GAMA,               "assign_gama"},
-    {MNG_FN_ASSIGN_CHRM,               "assign_chrm"},
-    {MNG_FN_ASSIGN_SRGB,               "assign_srgb"},
-    {MNG_FN_ASSIGN_ICCP,               "assign_iccp"},
-    {MNG_FN_ASSIGN_TEXT,               "assign_text"},
-    {MNG_FN_ASSIGN_ZTXT,               "assign_ztxt"},
-    {MNG_FN_ASSIGN_ITXT,               "assign_itxt"},
-    {MNG_FN_ASSIGN_BKGD,               "assign_bkgd"},
-    {MNG_FN_ASSIGN_PHYS,               "assign_phys"},
-    {MNG_FN_ASSIGN_SBIT,               "assign_sbit"},
-    {MNG_FN_ASSIGN_SPLT,               "assign_splt"},
-    {MNG_FN_ASSIGN_HIST,               "assign_hist"},
-    {MNG_FN_ASSIGN_TIME,               "assign_time"},
-    {MNG_FN_ASSIGN_MHDR,               "assign_mhdr"},
-    {MNG_FN_ASSIGN_MEND,               "assign_mend"},
-    {MNG_FN_ASSIGN_LOOP,               "assign_loop"},
-    {MNG_FN_ASSIGN_ENDL,               "assign_endl"},
-    {MNG_FN_ASSIGN_DEFI,               "assign_defi"},
-    {MNG_FN_ASSIGN_BASI,               "assign_basi"},
-    {MNG_FN_ASSIGN_CLON,               "assign_clon"},
-#ifndef MNG_SKIPCHUNK_PAST
-    {MNG_FN_ASSIGN_PAST,               "assign_past"},
-#endif
-    {MNG_FN_ASSIGN_DISC,               "assign_disc"},
-    {MNG_FN_ASSIGN_BACK,               "assign_back"},
-    {MNG_FN_ASSIGN_FRAM,               "assign_fram"},
-    {MNG_FN_ASSIGN_MOVE,               "assign_move"},
-    {MNG_FN_ASSIGN_CLIP,               "assign_clip"},
-    {MNG_FN_ASSIGN_SHOW,               "assign_show"},
-    {MNG_FN_ASSIGN_TERM,               "assign_term"},
-    {MNG_FN_ASSIGN_SAVE,               "assign_save"},
-    {MNG_FN_ASSIGN_SEEK,               "assign_seek"},
-    {MNG_FN_ASSIGN_EXPI,               "assign_expi"},
-    {MNG_FN_ASSIGN_FPRI,               "assign_fpri"},
-    {MNG_FN_ASSIGN_NEED,               "assign_need"},
-    {MNG_FN_ASSIGN_PHYG,               "assign_phyg"},
-#ifdef MNG_INCLUDE_JNG
-    {MNG_FN_ASSIGN_JHDR,               "assign_jhdr"},
-    {MNG_FN_ASSIGN_JDAT,               "assign_jdat"},
-    {MNG_FN_ASSIGN_JSEP,               "assign_jsep"},
-#endif
-#ifndef MNG_NO_DELTA_PNG
-    {MNG_FN_ASSIGN_DHDR,               "assign_dhdr"},
-    {MNG_FN_ASSIGN_PROM,               "assign_prom"},
-#ifdef MNG_INCLUDE_JNG
-    {MNG_FN_ASSIGN_IPNG,               "assign_ipng"},
-#endif
-    {MNG_FN_ASSIGN_PPLT,               "assign_pplt"},
-    {MNG_FN_ASSIGN_IJNG,               "assign_ijng"},
-    {MNG_FN_ASSIGN_DROP,               "assign_drop"},
-    {MNG_FN_ASSIGN_DBYK,               "assign_dbyk"},
-    {MNG_FN_ASSIGN_ORDR,               "assign_ordr"},
-#endif
-    {MNG_FN_ASSIGN_UNKNOWN,            "assign_unknown"},
-    {MNG_FN_ASSIGN_MAGN,               "assign_magn"},
-    {MNG_FN_ASSIGN_JDAA,               "assign_jdaa"},
-    {MNG_FN_ASSIGN_EVNT,               "assign_evnt"},
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-    {MNG_FN_ASSIGN_MPNG,               "assign_mpng"},
-#endif
-
-    {MNG_FN_FREE_IHDR,                 "free_ihdr"},
-    {MNG_FN_FREE_PLTE,                 "free_plte"},
-    {MNG_FN_FREE_IDAT,                 "free_idat"},
-    {MNG_FN_FREE_IEND,                 "free_iend"},
-    {MNG_FN_FREE_TRNS,                 "free_trns"},
-    {MNG_FN_FREE_GAMA,                 "free_gama"},
-    {MNG_FN_FREE_CHRM,                 "free_chrm"},
-    {MNG_FN_FREE_SRGB,                 "free_srgb"},
-    {MNG_FN_FREE_ICCP,                 "free_iccp"},
-    {MNG_FN_FREE_TEXT,                 "free_text"},
-    {MNG_FN_FREE_ZTXT,                 "free_ztxt"},
-    {MNG_FN_FREE_ITXT,                 "free_itxt"},
-    {MNG_FN_FREE_BKGD,                 "free_bkgd"},
-    {MNG_FN_FREE_PHYS,                 "free_phys"},
-    {MNG_FN_FREE_SBIT,                 "free_sbit"},
-    {MNG_FN_FREE_SPLT,                 "free_splt"},
-    {MNG_FN_FREE_HIST,                 "free_hist"},
-    {MNG_FN_FREE_TIME,                 "free_time"},
-    {MNG_FN_FREE_MHDR,                 "free_mhdr"},
-    {MNG_FN_FREE_MEND,                 "free_mend"},
-    {MNG_FN_FREE_LOOP,                 "free_loop"},
-    {MNG_FN_FREE_ENDL,                 "free_endl"},
-    {MNG_FN_FREE_DEFI,                 "free_defi"},
-    {MNG_FN_FREE_BASI,                 "free_basi"},
-    {MNG_FN_FREE_CLON,                 "free_clon"},
-#ifndef MNG_SKIPCHUNK_PAST
-    {MNG_FN_FREE_PAST,                 "free_past"},
-#endif
-    {MNG_FN_FREE_DISC,                 "free_disc"},
-    {MNG_FN_FREE_BACK,                 "free_back"},
-    {MNG_FN_FREE_FRAM,                 "free_fram"},
-    {MNG_FN_FREE_MOVE,                 "free_move"},
-    {MNG_FN_FREE_CLIP,                 "free_clip"},
-    {MNG_FN_FREE_SHOW,                 "free_show"},
-    {MNG_FN_FREE_TERM,                 "free_term"},
-    {MNG_FN_FREE_SAVE,                 "free_save"},
-    {MNG_FN_FREE_SEEK,                 "free_seek"},
-    {MNG_FN_FREE_EXPI,                 "free_expi"},
-    {MNG_FN_FREE_FPRI,                 "free_fpri"},
-    {MNG_FN_FREE_NEED,                 "free_need"},
-    {MNG_FN_FREE_PHYG,                 "free_phyg"},
-#ifdef MNG_INCLUDE_JNG
-    {MNG_FN_FREE_JHDR,                 "free_jhdr"},
-    {MNG_FN_FREE_JDAT,                 "free_jdat"},
-    {MNG_FN_FREE_JSEP,                 "free_jsep"},
-#endif
-#ifndef MNG_NO_DELTA_PNG
-    {MNG_FN_FREE_DHDR,                 "free_dhdr"},
-    {MNG_FN_FREE_PROM,                 "free_prom"},
-#ifdef MNG_INCLUDE_JNG
-    {MNG_FN_FREE_IPNG,                 "free_ipng"},
-#endif
-    {MNG_FN_FREE_PPLT,                 "free_pplt"},
-    {MNG_FN_FREE_IJNG,                 "free_ijng"},
-    {MNG_FN_FREE_DROP,                 "free_drop"},
-    {MNG_FN_FREE_DBYK,                 "free_dbyk"},
-    {MNG_FN_FREE_ORDR,                 "free_ordr"},
-#endif
-    {MNG_FN_FREE_UNKNOWN,              "free_unknown"},
-    {MNG_FN_FREE_MAGN,                 "free_magn"},
-    {MNG_FN_FREE_JDAA,                 "free_jdaa"},
-    {MNG_FN_FREE_EVNT,                 "free_evnt"},
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-    {MNG_FN_FREE_MPNG,                 "free_mpng"},
-#endif
-
-    {MNG_FN_READ_IHDR,                 "read_ihdr"},
-    {MNG_FN_READ_PLTE,                 "read_plte"},
-    {MNG_FN_READ_IDAT,                 "read_idat"},
-    {MNG_FN_READ_IEND,                 "read_iend"},
-    {MNG_FN_READ_TRNS,                 "read_trns"},
-    {MNG_FN_READ_GAMA,                 "read_gama"},
-    {MNG_FN_READ_CHRM,                 "read_chrm"},
-    {MNG_FN_READ_SRGB,                 "read_srgb"},
-    {MNG_FN_READ_ICCP,                 "read_iccp"},
-    {MNG_FN_READ_TEXT,                 "read_text"},
-    {MNG_FN_READ_ZTXT,                 "read_ztxt"},
-    {MNG_FN_READ_ITXT,                 "read_itxt"},
-    {MNG_FN_READ_BKGD,                 "read_bkgd"},
-    {MNG_FN_READ_PHYS,                 "read_phys"},
-    {MNG_FN_READ_SBIT,                 "read_sbit"},
-    {MNG_FN_READ_SPLT,                 "read_splt"},
-    {MNG_FN_READ_HIST,                 "read_hist"},
-    {MNG_FN_READ_TIME,                 "read_time"},
-    {MNG_FN_READ_MHDR,                 "read_mhdr"},
-    {MNG_FN_READ_MEND,                 "read_mend"},
-    {MNG_FN_READ_LOOP,                 "read_loop"},
-    {MNG_FN_READ_ENDL,                 "read_endl"},
-    {MNG_FN_READ_DEFI,                 "read_defi"},
-    {MNG_FN_READ_BASI,                 "read_basi"},
-    {MNG_FN_READ_CLON,                 "read_clon"},
-#ifndef MNG_SKIPCHUNK_PAST
-    {MNG_FN_READ_PAST,                 "read_past"},
-#endif
-    {MNG_FN_READ_DISC,                 "read_disc"},
-    {MNG_FN_READ_BACK,                 "read_back"},
-    {MNG_FN_READ_FRAM,                 "read_fram"},
-    {MNG_FN_READ_MOVE,                 "read_move"},
-    {MNG_FN_READ_CLIP,                 "read_clip"},
-    {MNG_FN_READ_SHOW,                 "read_show"},
-    {MNG_FN_READ_TERM,                 "read_term"},
-    {MNG_FN_READ_SAVE,                 "read_save"},
-    {MNG_FN_READ_SEEK,                 "read_seek"},
-    {MNG_FN_READ_EXPI,                 "read_expi"},
-    {MNG_FN_READ_FPRI,                 "read_fpri"},
-    {MNG_FN_READ_NEED,                 "read_need"},
-    {MNG_FN_READ_PHYG,                 "read_phyg"},
-#ifdef MNG_INCLUDE_JNG
-    {MNG_FN_READ_JHDR,                 "read_jhdr"},
-    {MNG_FN_READ_JDAT,                 "read_jdat"},
-    {MNG_FN_READ_JSEP,                 "read_jsep"},
-#endif
-#ifndef MNG_NO_DELTA_PNG
-    {MNG_FN_READ_DHDR,                 "read_dhdr"},
-    {MNG_FN_READ_PROM,                 "read_prom"},
-    {MNG_FN_READ_IPNG,                 "read_ipng"},
-    {MNG_FN_READ_PPLT,                 "read_pplt"},
-#ifdef MNG_INCLUDE_JNG
-    {MNG_FN_READ_IJNG,                 "read_ijng"},
-#endif
-    {MNG_FN_READ_DROP,                 "read_drop"},
-    {MNG_FN_READ_DBYK,                 "read_dbyk"},
-    {MNG_FN_READ_ORDR,                 "read_ordr"},
-#endif
-    {MNG_FN_READ_UNKNOWN,              "read_unknown"},
-    {MNG_FN_READ_MAGN,                 "read_magn"},
-    {MNG_FN_READ_JDAA,                 "read_jdaa"},
-    {MNG_FN_READ_EVNT,                 "read_evnt"},
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-    {MNG_FN_READ_MPNG,                 "read_mpng"},
-#endif
-
-    {MNG_FN_WRITE_IHDR,                "write_ihdr"},
-    {MNG_FN_WRITE_PLTE,                "write_plte"},
-    {MNG_FN_WRITE_IDAT,                "write_idat"},
-    {MNG_FN_WRITE_IEND,                "write_iend"},
-    {MNG_FN_WRITE_TRNS,                "write_trns"},
-    {MNG_FN_WRITE_GAMA,                "write_gama"},
-    {MNG_FN_WRITE_CHRM,                "write_chrm"},
-    {MNG_FN_WRITE_SRGB,                "write_srgb"},
-    {MNG_FN_WRITE_ICCP,                "write_iccp"},
-    {MNG_FN_WRITE_TEXT,                "write_text"},
-    {MNG_FN_WRITE_ZTXT,                "write_ztxt"},
-    {MNG_FN_WRITE_ITXT,                "write_itxt"},
-    {MNG_FN_WRITE_BKGD,                "write_bkgd"},
-    {MNG_FN_WRITE_PHYS,                "write_phys"},
-    {MNG_FN_WRITE_SBIT,                "write_sbit"},
-    {MNG_FN_WRITE_SPLT,                "write_splt"},
-    {MNG_FN_WRITE_HIST,                "write_hist"},
-    {MNG_FN_WRITE_TIME,                "write_time"},
-    {MNG_FN_WRITE_MHDR,                "write_mhdr"},
-    {MNG_FN_WRITE_MEND,                "write_mend"},
-    {MNG_FN_WRITE_LOOP,                "write_loop"},
-    {MNG_FN_WRITE_ENDL,                "write_endl"},
-    {MNG_FN_WRITE_DEFI,                "write_defi"},
-    {MNG_FN_WRITE_BASI,                "write_basi"},
-    {MNG_FN_WRITE_CLON,                "write_clon"},
-#ifndef MNG_SKIPCHUNK_PAST
-    {MNG_FN_WRITE_PAST,                "write_past"},
-#endif
-    {MNG_FN_WRITE_DISC,                "write_disc"},
-    {MNG_FN_WRITE_BACK,                "write_back"},
-    {MNG_FN_WRITE_FRAM,                "write_fram"},
-    {MNG_FN_WRITE_MOVE,                "write_move"},
-    {MNG_FN_WRITE_CLIP,                "write_clip"},
-    {MNG_FN_WRITE_SHOW,                "write_show"},
-    {MNG_FN_WRITE_TERM,                "write_term"},
-    {MNG_FN_WRITE_SAVE,                "write_save"},
-    {MNG_FN_WRITE_SEEK,                "write_seek"},
-    {MNG_FN_WRITE_EXPI,                "write_expi"},
-    {MNG_FN_WRITE_FPRI,                "write_fpri"},
-    {MNG_FN_WRITE_NEED,                "write_need"},
-    {MNG_FN_WRITE_PHYG,                "write_phyg"},
-#ifdef MNG_INCLUDE_JNG
-    {MNG_FN_WRITE_JHDR,                "write_jhdr"},
-    {MNG_FN_WRITE_JDAT,                "write_jdat"},
-    {MNG_FN_WRITE_JSEP,                "write_jsep"},
-#endif
-#ifndef MNG_NO_DELTA_PNG
-    {MNG_FN_WRITE_DHDR,                "write_dhdr"},
-    {MNG_FN_WRITE_PROM,                "write_prom"},
-#ifdef MNG_INCLUDE_JNG
-    {MNG_FN_WRITE_IPNG,                "write_ipng"},
-#endif
-    {MNG_FN_WRITE_PPLT,                "write_pplt"},
-    {MNG_FN_WRITE_IJNG,                "write_ijng"},
-    {MNG_FN_WRITE_DROP,                "write_drop"},
-    {MNG_FN_WRITE_DBYK,                "write_dbyk"},
-    {MNG_FN_WRITE_ORDR,                "write_ordr"},
-#endif
-    {MNG_FN_WRITE_UNKNOWN,             "write_unknown"},
-    {MNG_FN_WRITE_MAGN,                "write_magn"},
-    {MNG_FN_WRITE_JDAA,                "write_jdaa"},
-    {MNG_FN_WRITE_EVNT,                "write_evnt"},
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-    {MNG_FN_WRITE_MPNG,                "write_mpng"},
-#endif
-
-    {MNG_FN_ZLIB_INITIALIZE,           "zlib_initialize"},
-    {MNG_FN_ZLIB_CLEANUP,              "zlib_cleanup"},
-    {MNG_FN_ZLIB_INFLATEINIT,          "zlib_inflateinit"},
-    {MNG_FN_ZLIB_INFLATEROWS,          "zlib_inflaterows"},
-    {MNG_FN_ZLIB_INFLATEDATA,          "zlib_inflatedata"},
-    {MNG_FN_ZLIB_INFLATEFREE,          "zlib_inflatefree"},
-    {MNG_FN_ZLIB_DEFLATEINIT,          "zlib_deflateinit"},
-    {MNG_FN_ZLIB_DEFLATEROWS,          "zlib_deflaterows"},
-    {MNG_FN_ZLIB_DEFLATEDATA,          "zlib_deflatedata"},
-    {MNG_FN_ZLIB_DEFLATEFREE,          "zlib_deflatefree"},
-
-    {MNG_FN_PROCESS_DISPLAY_IHDR,      "process_display_ihdr"},
-    {MNG_FN_PROCESS_DISPLAY_PLTE,      "process_display_plte"},
-    {MNG_FN_PROCESS_DISPLAY_IDAT,      "process_display_idat"},
-    {MNG_FN_PROCESS_DISPLAY_IEND,      "process_display_iend"},
-    {MNG_FN_PROCESS_DISPLAY_TRNS,      "process_display_trns"},
-    {MNG_FN_PROCESS_DISPLAY_GAMA,      "process_display_gama"},
-    {MNG_FN_PROCESS_DISPLAY_CHRM,      "process_display_chrm"},
-    {MNG_FN_PROCESS_DISPLAY_SRGB,      "process_display_srgb"},
-    {MNG_FN_PROCESS_DISPLAY_ICCP,      "process_display_iccp"},
-    {MNG_FN_PROCESS_DISPLAY_BKGD,      "process_display_bkgd"},
-    {MNG_FN_PROCESS_DISPLAY_PHYS,      "process_display_phys"},
-    {MNG_FN_PROCESS_DISPLAY_SBIT,      "process_display_sbit"},
-    {MNG_FN_PROCESS_DISPLAY_SPLT,      "process_display_splt"},
-    {MNG_FN_PROCESS_DISPLAY_HIST,      "process_display_hist"},
-    {MNG_FN_PROCESS_DISPLAY_MHDR,      "process_display_mhdr"},
-    {MNG_FN_PROCESS_DISPLAY_MEND,      "process_display_mend"},
-    {MNG_FN_PROCESS_DISPLAY_LOOP,      "process_display_loop"},
-    {MNG_FN_PROCESS_DISPLAY_ENDL,      "process_display_endl"},
-    {MNG_FN_PROCESS_DISPLAY_DEFI,      "process_display_defi"},
-    {MNG_FN_PROCESS_DISPLAY_BASI,      "process_display_basi"},
-    {MNG_FN_PROCESS_DISPLAY_CLON,      "process_display_clon"},
-#ifndef MNG_SKIPCHUNK_PAST
-    {MNG_FN_PROCESS_DISPLAY_PAST,      "process_display_past"},
-#endif
-    {MNG_FN_PROCESS_DISPLAY_DISC,      "process_display_disc"},
-    {MNG_FN_PROCESS_DISPLAY_BACK,      "process_display_back"},
-    {MNG_FN_PROCESS_DISPLAY_FRAM,      "process_display_fram"},
-    {MNG_FN_PROCESS_DISPLAY_MOVE,      "process_display_move"},
-    {MNG_FN_PROCESS_DISPLAY_CLIP,      "process_display_clip"},
-    {MNG_FN_PROCESS_DISPLAY_SHOW,      "process_display_show"},
-    {MNG_FN_PROCESS_DISPLAY_TERM,      "process_display_term"},
-    {MNG_FN_PROCESS_DISPLAY_SAVE,      "process_display_save"},
-    {MNG_FN_PROCESS_DISPLAY_SEEK,      "process_display_seek"},
-    {MNG_FN_PROCESS_DISPLAY_EXPI,      "process_display_expi"},
-    {MNG_FN_PROCESS_DISPLAY_FPRI,      "process_display_fpri"},
-    {MNG_FN_PROCESS_DISPLAY_NEED,      "process_display_need"},
-    {MNG_FN_PROCESS_DISPLAY_PHYG,      "process_display_phyg"},
-#ifdef MNG_INCLUDE_JNG
-    {MNG_FN_PROCESS_DISPLAY_JHDR,      "process_display_jhdr"},
-    {MNG_FN_PROCESS_DISPLAY_JDAT,      "process_display_jdat"},
-    {MNG_FN_PROCESS_DISPLAY_JSEP,      "process_display_jsep"},
-#endif
-#ifndef MNG_NO_DELTA_PNG
-    {MNG_FN_PROCESS_DISPLAY_DHDR,      "process_display_dhdr"},
-    {MNG_FN_PROCESS_DISPLAY_PROM,      "process_display_prom"},
-#ifdef MNG_INCLUDE_JNG
-    {MNG_FN_PROCESS_DISPLAY_IPNG,      "process_display_ipng"},
-#endif
-    {MNG_FN_PROCESS_DISPLAY_PPLT,      "process_display_pplt"},
-    {MNG_FN_PROCESS_DISPLAY_IJNG,      "process_display_ijng"},
-    {MNG_FN_PROCESS_DISPLAY_DROP,      "process_display_drop"},
-    {MNG_FN_PROCESS_DISPLAY_DBYK,      "process_display_dbyk"},
-    {MNG_FN_PROCESS_DISPLAY_ORDR,      "process_display_ordr"},
-#endif
-    {MNG_FN_PROCESS_DISPLAY_MAGN,      "process_display_magn"},
-    {MNG_FN_PROCESS_DISPLAY_JDAA,      "process_display_jdaa"},
-
-    {MNG_FN_JPEG_INITIALIZE,           "jpeg_initialize"},
-    {MNG_FN_JPEG_CLEANUP,              "jpeg_cleanup"},
-    {MNG_FN_JPEG_DECOMPRESSINIT,       "jpeg_decompressinit"},
-    {MNG_FN_JPEG_DECOMPRESSDATA,       "jpeg_decompressdata"},
-    {MNG_FN_JPEG_DECOMPRESSFREE,       "jpeg_decompressfree"},
-
-    {MNG_FN_STORE_JPEG_G8,             "store_jpeg_g8"},
-    {MNG_FN_STORE_JPEG_RGB8,           "store_jpeg_rgb8"},
-    {MNG_FN_STORE_JPEG_G12,            "store_jpeg_g12"},
-    {MNG_FN_STORE_JPEG_RGB12,          "store_jpeg_rgb12"},
-    {MNG_FN_STORE_JPEG_GA8,            "store_jpeg_ga8"},
-    {MNG_FN_STORE_JPEG_RGBA8,          "store_jpeg_rgba8"},
-    {MNG_FN_STORE_JPEG_GA12,           "store_jpeg_ga12"},
-    {MNG_FN_STORE_JPEG_RGBA12,         "store_jpeg_rgba12"},
-    {MNG_FN_STORE_JPEG_G8_ALPHA,       "store_jpeg_g8_alpha"},
-    {MNG_FN_STORE_JPEG_RGB8_ALPHA,     "store_jpeg_rgb8_alpha"},
-
-    {MNG_FN_INIT_JPEG_A1_NI,           "init_jpeg_a1_ni"},
-    {MNG_FN_INIT_JPEG_A2_NI,           "init_jpeg_a2_ni"},
-    {MNG_FN_INIT_JPEG_A4_NI,           "init_jpeg_a4_ni"},
-    {MNG_FN_INIT_JPEG_A8_NI,           "init_jpeg_a8_ni"},
-    {MNG_FN_INIT_JPEG_A16_NI,          "init_jpeg_a16_ni"},
-
-    {MNG_FN_STORE_JPEG_G8_A1,          "store_jpeg_g8_a1"},
-    {MNG_FN_STORE_JPEG_G8_A2,          "store_jpeg_g8_a2"},
-    {MNG_FN_STORE_JPEG_G8_A4,          "store_jpeg_g8_a4"},
-    {MNG_FN_STORE_JPEG_G8_A8,          "store_jpeg_g8_a8"},
-    {MNG_FN_STORE_JPEG_G8_A16,         "store_jpeg_g8_a16"},
-
-    {MNG_FN_STORE_JPEG_RGB8_A1,        "store_jpeg_rgb8_a1"},
-    {MNG_FN_STORE_JPEG_RGB8_A2,        "store_jpeg_rgb8_a2"},
-    {MNG_FN_STORE_JPEG_RGB8_A4,        "store_jpeg_rgb8_a4"},
-    {MNG_FN_STORE_JPEG_RGB8_A8,        "store_jpeg_rgb8_a8"},
-    {MNG_FN_STORE_JPEG_RGB8_A16,       "store_jpeg_rgb8_a16"},
-
-    {MNG_FN_STORE_JPEG_G12_A1,         "store_jpeg_g12_a1"},
-    {MNG_FN_STORE_JPEG_G12_A2,         "store_jpeg_g12_a2"},
-    {MNG_FN_STORE_JPEG_G12_A4,         "store_jpeg_g12_a4"},
-    {MNG_FN_STORE_JPEG_G12_A8,         "store_jpeg_g12_a8"},
-    {MNG_FN_STORE_JPEG_G12_A16,        "store_jpeg_g12_a16"},
-
-    {MNG_FN_STORE_JPEG_RGB12_A1,       "store_jpeg_rgb12_a1"},
-    {MNG_FN_STORE_JPEG_RGB12_A2,       "store_jpeg_rgb12_a2"},
-    {MNG_FN_STORE_JPEG_RGB12_A4,       "store_jpeg_rgb12_a4"},
-    {MNG_FN_STORE_JPEG_RGB12_A8,       "store_jpeg_rgb12_a8"},
-    {MNG_FN_STORE_JPEG_RGB12_A16,      "store_jpeg_rgb12_a16"},
-
-    {MNG_FN_NEXT_JPEG_ALPHAROW,        "next_jpeg_alpharow"},
-    {MNG_FN_NEXT_JPEG_ROW,             "next_jpeg_row"},
-    {MNG_FN_DISPLAY_JPEG_ROWS,         "display_jpeg_rows"},
-
-    {MNG_FN_MAGNIFY_G8_X1,             "magnify_g8_x1"},
-    {MNG_FN_MAGNIFY_G8_X2,             "magnify_g8_x2"},
-    {MNG_FN_MAGNIFY_RGB8_X1,           "magnify_rgb8_x1"},
-    {MNG_FN_MAGNIFY_RGB8_X2,           "magnify_rgb8_x2"},
-    {MNG_FN_MAGNIFY_GA8_X1,            "magnify_ga8_x1"},
-    {MNG_FN_MAGNIFY_GA8_X2,            "magnify_ga8_x2"},
-    {MNG_FN_MAGNIFY_GA8_X3,            "magnify_ga8_x3"},
-    {MNG_FN_MAGNIFY_GA8_X4,            "magnify_ga8_x4"},
-    {MNG_FN_MAGNIFY_RGBA8_X1,          "magnify_rgba8_x1"},
-    {MNG_FN_MAGNIFY_RGBA8_X2,          "magnify_rgba8_x2"},
-    {MNG_FN_MAGNIFY_RGBA8_X3,          "magnify_rgba8_x3"},
-    {MNG_FN_MAGNIFY_RGBA8_X4,          "magnify_rgba8_x4"},
-    {MNG_FN_MAGNIFY_G8_X3,             "magnify_g8_x3"},
-    {MNG_FN_MAGNIFY_RGB8_X3,           "magnify_rgb8_x3"},
-    {MNG_FN_MAGNIFY_GA8_X5,            "magnify_ga8_x5"},
-    {MNG_FN_MAGNIFY_RGBA8_X5,          "magnify_rgba8_x5"},
-
-    {MNG_FN_MAGNIFY_G8_Y1,             "magnify_g8_y1"},
-    {MNG_FN_MAGNIFY_G8_Y2,             "magnify_g8_y2"},
-    {MNG_FN_MAGNIFY_RGB8_Y1,           "magnify_rgb8_y1"},
-    {MNG_FN_MAGNIFY_RGB8_Y2,           "magnify_rgb8_y2"},
-    {MNG_FN_MAGNIFY_GA8_Y1,            "magnify_ga8_y1"},
-    {MNG_FN_MAGNIFY_GA8_Y2,            "magnify_ga8_y2"},
-    {MNG_FN_MAGNIFY_GA8_Y3,            "magnify_ga8_y3"},
-    {MNG_FN_MAGNIFY_GA8_Y4,            "magnify_ga8_y4"},
-    {MNG_FN_MAGNIFY_RGBA8_Y1,          "magnify_rgba8_y1"},
-    {MNG_FN_MAGNIFY_RGBA8_Y2,          "magnify_rgba8_y2"},
-    {MNG_FN_MAGNIFY_RGBA8_Y3,          "magnify_rgba8_y3"},
-    {MNG_FN_MAGNIFY_RGBA8_Y4,          "magnify_rgba8_y4"},
-    {MNG_FN_MAGNIFY_G8_Y3,             "magnify_g8_y3"},
-    {MNG_FN_MAGNIFY_RGB8_Y3,           "magnify_rgb8_y3"},
-    {MNG_FN_MAGNIFY_GA8_Y5,            "magnify_ga8_y5"},
-    {MNG_FN_MAGNIFY_RGBA8_Y5,          "magnify_rgba8_y5"},
-
-    {MNG_FN_MAGNIFY_G8_X1,             "magnify_g8_x1"},
-    {MNG_FN_MAGNIFY_G8_X2,             "magnify_g8_x2"},
-    {MNG_FN_MAGNIFY_RGB8_X1,           "magnify_rgb8_x1"},
-    {MNG_FN_MAGNIFY_RGB8_X2,           "magnify_rgb8_x2"},
-    {MNG_FN_MAGNIFY_GA8_X1,            "magnify_ga8_x1"},
-    {MNG_FN_MAGNIFY_GA8_X2,            "magnify_ga8_x2"},
-    {MNG_FN_MAGNIFY_GA8_X3,            "magnify_ga8_x3"},
-    {MNG_FN_MAGNIFY_GA8_X4,            "magnify_ga8_x4"},
-    {MNG_FN_MAGNIFY_RGBA8_X1,          "magnify_rgba8_x1"},
-    {MNG_FN_MAGNIFY_RGBA8_X2,          "magnify_rgba8_x2"},
-    {MNG_FN_MAGNIFY_RGBA8_X3,          "magnify_rgba8_x3"},
-    {MNG_FN_MAGNIFY_RGBA8_X4,          "magnify_rgba8_x4"},
-    {MNG_FN_MAGNIFY_G8_X3,             "magnify_g8_x3"},
-    {MNG_FN_MAGNIFY_RGB8_X3,           "magnify_rgb8_x3"},
-    {MNG_FN_MAGNIFY_GA8_X5,            "magnify_ga8_x5"},
-    {MNG_FN_MAGNIFY_RGBA8_X5,          "magnify_rgba8_x5"},
-
-    {MNG_FN_MAGNIFY_G8_Y1,             "magnify_g8_y1"},
-    {MNG_FN_MAGNIFY_G8_Y2,             "magnify_g8_y2"},
-    {MNG_FN_MAGNIFY_RGB8_Y1,           "magnify_rgb8_y1"},
-    {MNG_FN_MAGNIFY_RGB8_Y2,           "magnify_rgb8_y2"},
-    {MNG_FN_MAGNIFY_GA8_Y1,            "magnify_ga8_y1"},
-    {MNG_FN_MAGNIFY_GA8_Y2,            "magnify_ga8_y2"},
-    {MNG_FN_MAGNIFY_GA8_Y3,            "magnify_ga8_y3"},
-    {MNG_FN_MAGNIFY_GA8_Y4,            "magnify_ga8_y4"},
-    {MNG_FN_MAGNIFY_RGBA8_Y1,          "magnify_rgba8_y1"},
-    {MNG_FN_MAGNIFY_RGBA8_Y2,          "magnify_rgba8_y2"},
-    {MNG_FN_MAGNIFY_RGBA8_Y3,          "magnify_rgba8_y3"},
-    {MNG_FN_MAGNIFY_RGBA8_Y4,          "magnify_rgba8_y4"},
-    {MNG_FN_MAGNIFY_G8_Y3,             "magnify_g8_y3"},
-    {MNG_FN_MAGNIFY_RGB8_Y3,           "magnify_rgb8_y3"},
-    {MNG_FN_MAGNIFY_GA8_Y5,            "magnify_ga8_y5"},
-    {MNG_FN_MAGNIFY_RGBA8_Y5,          "magnify_rgba8_y5"},
-
-    {MNG_FN_DELTA_G1_G1,               "delta_g1_g1"},
-    {MNG_FN_DELTA_G2_G2,               "delta_g2_g2"},
-    {MNG_FN_DELTA_G4_G4,               "delta_g4_g4"},
-    {MNG_FN_DELTA_G8_G8,               "delta_g8_g8"},
-    {MNG_FN_DELTA_G16_G16,             "delta_g16_g16"},
-    {MNG_FN_DELTA_RGB8_RGB8,           "delta_rgb8_rgb8"},
-    {MNG_FN_DELTA_RGB16_RGB16,         "delta_rgb16_rgb16"},
-    {MNG_FN_DELTA_GA8_GA8,             "delta_ga8_ga8"},
-    {MNG_FN_DELTA_GA8_G8,              "delta_ga8_g8"},
-    {MNG_FN_DELTA_GA8_A8,              "delta_ga8_a8"},
-    {MNG_FN_DELTA_GA16_GA16,           "delta_ga16_ga16"},
-    {MNG_FN_DELTA_GA16_G16,            "delta_ga16_g16"},
-    {MNG_FN_DELTA_GA16_A16,            "delta_ga16_a16"},
-    {MNG_FN_DELTA_RGBA8_RGBA8,         "delta_rgba8_rgba8"},
-    {MNG_FN_DELTA_RGBA8_RGB8,          "delta_rgba8_rgb8"},
-    {MNG_FN_DELTA_RGBA8_A8,            "delta_rgba8_a8"},
-    {MNG_FN_DELTA_RGBA16_RGBA16,       "delta_rgba16_rgba16"},
-    {MNG_FN_DELTA_RGBA16_RGB16,        "delta_rgba16_rgb16"},
-    {MNG_FN_DELTA_RGBA16_A16,          "delta_rgba16_a16"},
-
-    {MNG_FN_PROMOTE_G8_G8,             "promote_g8_g8"},
-    {MNG_FN_PROMOTE_G8_G16,            "promote_g8_g16"},
-    {MNG_FN_PROMOTE_G16_G16,           "promote_g8_g16"},
-    {MNG_FN_PROMOTE_G8_GA8,            "promote_g8_ga8"},
-    {MNG_FN_PROMOTE_G8_GA16,           "promote_g8_ga16"},
-    {MNG_FN_PROMOTE_G16_GA16,          "promote_g16_ga16"},
-    {MNG_FN_PROMOTE_G8_RGB8,           "promote_g8_rgb8"},
-    {MNG_FN_PROMOTE_G8_RGB16,          "promote_g8_rgb16"},
-    {MNG_FN_PROMOTE_G16_RGB16,         "promote_g16_rgb16"},
-    {MNG_FN_PROMOTE_G8_RGBA8,          "promote_g8_rgba8"},
-    {MNG_FN_PROMOTE_G8_RGBA16,         "promote_g8_rgba16"},
-    {MNG_FN_PROMOTE_G16_RGBA16,        "promote_g16_rgba16"},
-    {MNG_FN_PROMOTE_GA8_GA16,          "promote_ga8_ga16"},
-    {MNG_FN_PROMOTE_GA8_RGBA8,         "promote_ga8_rgba8"},
-    {MNG_FN_PROMOTE_GA8_RGBA16,        "promote_ga8_rgba16"},
-    {MNG_FN_PROMOTE_GA16_RGBA16,       "promote_ga16_rgba16"},
-    {MNG_FN_PROMOTE_RGB8_RGB16,        "promote_rgb8_rgb16"},
-    {MNG_FN_PROMOTE_RGB8_RGBA8,        "promote_rgb8_rgba8"},
-    {MNG_FN_PROMOTE_RGB8_RGBA16,       "promote_rgb8_rgba16"},
-    {MNG_FN_PROMOTE_RGB16_RGBA16,      "promote_rgb16_rgba16"},
-    {MNG_FN_PROMOTE_RGBA8_RGBA16,      "promote_rgba8_rgba16"},
-    {MNG_FN_PROMOTE_IDX8_RGB8,         "promote_idx8_rgb8"},
-    {MNG_FN_PROMOTE_IDX8_RGB16,        "promote_idx8_rgb16"},
-    {MNG_FN_PROMOTE_IDX8_RGBA8,        "promote_idx8_rgba8"},
-    {MNG_FN_PROMOTE_IDX8_RGBA16,       "promote_idx8_rgba16"},
-
-    {MNG_FN_SCALE_G1_G2,               "scale_g1_g2"},
-    {MNG_FN_SCALE_G1_G4,               "scale_g1_g4"},
-    {MNG_FN_SCALE_G1_G8,               "scale_g1_g8"},
-    {MNG_FN_SCALE_G1_G16,              "scale_g1_g16"},
-    {MNG_FN_SCALE_G2_G4,               "scale_g2_g4"},
-    {MNG_FN_SCALE_G2_G8,               "scale_g2_g8"},
-    {MNG_FN_SCALE_G2_G16,              "scale_g2_g16"},
-    {MNG_FN_SCALE_G4_G8,               "scale_g4_g8"},
-    {MNG_FN_SCALE_G4_G16,              "scale_g4_g16"},
-    {MNG_FN_SCALE_G8_G16,              "scale_g8_g16"},
-    {MNG_FN_SCALE_GA8_GA16,            "scale_ga8_ga16"},
-    {MNG_FN_SCALE_RGB8_RGB16,          "scale_rgb8_rgb16"},
-    {MNG_FN_SCALE_RGBA8_RGBA16,        "scale_rgba8_rgba16"},
-
-    {MNG_FN_SCALE_G2_G1,               "scale_g2_g1"},
-    {MNG_FN_SCALE_G4_G1,               "scale_g4_g1"},
-    {MNG_FN_SCALE_G8_G1,               "scale_g8_g1"},
-    {MNG_FN_SCALE_G16_G1,              "scale_g16_g1"},
-    {MNG_FN_SCALE_G4_G2,               "scale_g4_g2"},
-    {MNG_FN_SCALE_G8_G2,               "scale_g8_g2"},
-    {MNG_FN_SCALE_G16_G2,              "scale_g16_g2"},
-    {MNG_FN_SCALE_G8_G4,               "scale_g8_g4"},
-    {MNG_FN_SCALE_G16_G4,              "scale_g16_g4"},
-    {MNG_FN_SCALE_G16_G8,              "scale_g16_g8"},
-    {MNG_FN_SCALE_GA16_GA8,            "scale_ga16_ga8"},
-    {MNG_FN_SCALE_RGB16_RGB8,          "scale_rgb16_rgb8"},
-    {MNG_FN_SCALE_RGBA16_RGBA8,        "scale_rgba16_rgba8"},
-
-    {MNG_FN_COMPOSEOVER_RGBA8,         "composeover_rgba8"},
-    {MNG_FN_COMPOSEOVER_RGBA16,        "composeover_rgba16"},
-    {MNG_FN_COMPOSEUNDER_RGBA8,        "composeunder_rgba8"},
-    {MNG_FN_COMPOSEUNDER_RGBA16,       "composeunder_rgba16"},
-
-    {MNG_FN_FLIP_RGBA8,                "flip_rgba8"},
-    {MNG_FN_FLIP_RGBA16,               "flip_rgba16"},
-    {MNG_FN_TILE_RGBA8,                "tile_rgba8"},
-    {MNG_FN_TILE_RGBA16,               "tile_rgba16"}
-
-  };
-#endif /* MNG_INCLUDE_TRACE_STINGS */
-
-/* ************************************************************************** */
-
-mng_retcode mng_trace (mng_datap  pData,
-                       mng_uint32 iFunction,
-                       mng_uint32 iLocation)
-{
-  mng_pchar zName = 0;                 /* bufferptr for tracestring */
-
-  if ((pData == 0) || (pData->iMagic != MNG_MAGIC))
-    return MNG_INVALIDHANDLE;          /* no good if the handle is corrupt */
-
-  if (pData->fTraceproc)               /* report back to user ? */
-  {
-#ifdef MNG_INCLUDE_TRACE_STRINGS
-    {                                  /* binary search variables */
-      mng_int32        iTop, iLower, iUpper, iMiddle;
-      mng_trace_entryp pEntry;         /* pointer to found entry */
-                                       /* determine max index of table */
-      iTop = (sizeof (trace_table) / sizeof (trace_table [0])) - 1;
-
-      iLower  = 0;                     /* initialize binary search */
-      iMiddle = iTop >> 1;             /* start in the middle */
-      iUpper  = iTop;
-      pEntry  = 0;                     /* no goods yet! */
-
-      do                               /* the binary search itself */
-        {
-          if (trace_table [iMiddle].iFunction < iFunction)
-            iLower = iMiddle + 1;
-          else if (trace_table [iMiddle].iFunction > iFunction)
-            iUpper = iMiddle - 1;
-          else
-          {
-            pEntry = &trace_table [iMiddle];
-            break;
-          };
-
-          iMiddle = (iLower + iUpper) >> 1;
-        }
-      while (iLower <= iUpper);
-
-      if (pEntry)                      /* found it ? */
-        zName = pEntry->zTracetext;
-
-    }
-#endif
-                                       /* oke, now tell */
-    if (!pData->fTraceproc (((mng_handle)pData), iFunction, iLocation, zName))
-      return MNG_APPTRACEABORT;
-
-  }
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#endif /* MNG_INCLUDE_TRACE_PROCS */
-
-/* ************************************************************************** */
-/* * end of file                                                            * */
-/* ************************************************************************** */
-
diff --git a/Source/LibMNG/libmng_trace.h b/Source/LibMNG/libmng_trace.h
deleted file mode 100644
index 0c749d9..0000000
--- a/Source/LibMNG/libmng_trace.h
+++ /dev/null
@@ -1,1474 +0,0 @@
-/* ************************************************************************** */
-/* *             For conditions of distribution and use,                    * */
-/* *                see copyright notice in libmng.h                        * */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * project   : libmng                                                     * */
-/* * file      : libmng_trace.h            copyright (c) 2000-2007 G.Juyn   * */
-/* * version   : 1.0.10                                                     * */
-/* *                                                                        * */
-/* * purpose   : Trace functions (definition)                               * */
-/* *                                                                        * */
-/* * author    : G.Juyn                                                     * */
-/* *                                                                        * */
-/* * comment   : Definition of the trace functions                          * */
-/* *                                                                        * */
-/* * changes   : 0.5.1 - 05/08/2000 - G.Juyn                                * */
-/* *             - added chunk-access function trace-codes                  * */
-/* *             - changed strict-ANSI stuff                                * */
-/* *             0.5.1 - 05/12/2000 - G.Juyn                                * */
-/* *             - changed trace to macro for callback error-reporting      * */
-/* *             0.5.1 - 05/13/2000 - G.Juyn                                * */
-/* *             - added save_state & restore_state trace-codes             * */
-/* *             0.5.1 - 05/15/2000 - G.Juyn                                * */
-/* *             - added getimgdata & putimgdata trace-codes                * */
-/* *                                                                        * */
-/* *             0.5.2 - 05/20/2000 - G.Juyn                                * */
-/* *             - added JNG tracecodes                                     * */
-/* *             0.5.2 - 05/23/2000 - G.Juyn                                * */
-/* *             - added trace-table entry definition                       * */
-/* *             0.5.2 - 05/24/2000 - G.Juyn                                * */
-/* *             - added tracecodes for global animation color-chunks       * */
-/* *             - added tracecodes for get/set of default ZLIB/IJG parms   * */
-/* *             - added tracecodes for global PLTE,tRNS,bKGD               * */
-/* *             0.5.2 - 05/30/2000 - G.Juyn                                * */
-/* *             - added tracecodes for image-object promotion              * */
-/* *             - added tracecodes for delta-image processing              * */
-/* *             0.5.2 - 06/02/2000 - G.Juyn                                * */
-/* *             - added tracecodes for getalphaline callback               * */
-/* *             0.5.2 - 06/05/2000 - G.Juyn                                * */
-/* *             - added tracecode for RGB8_A8 canvasstyle                  * */
-/* *             0.5.2 - 06/06/2000 - G.Juyn                                * */
-/* *             - added tracecode for mng_read_resume HLAPI function       * */
-/* *                                                                        * */
-/* *             0.5.3 - 06/06/2000 - G.Juyn                                * */
-/* *             - added tracecodes for tracing JPEG progression            * */
-/* *             0.5.3 - 06/21/2000 - G.Juyn                                * */
-/* *             - added tracecodes for get/set speedtype                   * */
-/* *             - added tracecodes for get imagelevel                      * */
-/* *             0.5.3 - 06/22/2000 - G.Juyn                                * */
-/* *             - added tracecode for delta-image processing               * */
-/* *             - added tracecodes for PPLT chunk processing               * */
-/* *                                                                        * */
-/* *             0.9.1 - 07/07/2000 - G.Juyn                                * */
-/* *             - added tracecodes for special display processing          * */
-/* *             0.9.1 - 07/08/2000 - G.Juyn                                * */
-/* *             - added tracecode for get/set suspensionmode               * */
-/* *             - added tracecodes for get/set display variables           * */
-/* *             - added tracecode for read_databuffer (I/O-suspension)     * */
-/* *             0.9.1 - 07/15/2000 - G.Juyn                                * */
-/* *             - added tracecodes for SAVE/SEEK callbacks                 * */
-/* *             - added tracecodes for get/set sectionbreaks               * */
-/* *             - added tracecode for special error routine                * */
-/* *             0.9.1 - 07/19/2000 - G.Juyn                                * */
-/* *             - added tracecode for updatemngheader                      * */
-/* *                                                                        * */
-/* *             0.9.2 - 07/31/2000 - G.Juyn                                * */
-/* *             - added tracecodes for status_xxxxx functions              * */
-/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
-/* *             - changed file-prefixes                                    * */
-/* *             - added tracecode for updatemngsimplicity                  * */
-/* *                                                                        * */
-/* *             0.9.3 - 08/26/2000 - G.Juyn                                * */
-/* *             - added MAGN chunk                                         * */
-/* *             0.9.3 - 09/07/2000 - G.Juyn                                * */
-/* *             - added support for new filter_types                       * */
-/* *             0.9.3 - 10/10/2000 - G.Juyn                                * */
-/* *             - added support for alpha-depth prediction                 * */
-/* *             0.9.3 - 10/11/2000 - G.Juyn                                * */
-/* *             - added JDAA chunk                                         * */
-/* *             - added support for nEED                                   * */
-/* *             0.9.3 - 10/16/2000 - G.Juyn                                * */
-/* *             - added functions to retrieve PNG/JNG specific header-info * */
-/* *             - added optional support for bKGD for PNG images           * */
-/* *             0.9.3 - 10/17/2000 - G.Juyn                                * */
-/* *             - added callback to process non-critical unknown chunks    * */
-/* *             - added routine to discard "invalid" objects               * */
-/* *             0.9.3 - 10/19/2000 - G.Juyn                                * */
-/* *             - implemented delayed delta-processing                     * */
-/* *             0.9.3 - 10/20/2000 - G.Juyn                                * */
-/* *             - added get/set for bKGD preference setting                * */
-/* *             0.9.3 - 10/21/2000 - G.Juyn                                * */
-/* *             - added get function for interlace/progressive display     * */
-/* *                                                                        * */
-/* *             0.9.4 -  1/18/2001 - G.Juyn                                * */
-/* *             - added "new" MAGN methods 3, 4 & 5                        * */
-/* *                                                                        * */
-/* *             1.0.1 - 02/08/2001 - G.Juyn                                * */
-/* *             - added MEND processing callback                           * */
-/* *             1.0.1 - 04/21/2001 - G.Juyn (code by G.Kelly)              * */
-/* *             - added BGRA8 canvas with premultiplied alpha              * */
-/* *             1.0.1 - 05/02/2001 - G.Juyn                                * */
-/* *             - added "default" sRGB generation (Thanks Marti!)          * */
-/* *                                                                        * */
-/* *             1.0.2 - 06/23/2001 - G.Juyn                                * */
-/* *             - added optimization option for MNG-video playback         * */
-/* *             - added processterm callback                               * */
-/* *             1.0.2 - 06/25/2001 - G.Juyn                                * */
-/* *             - added option to turn off progressive refresh             * */
-/* *                                                                        * */
-/* *             1.0.3 - 08/06/2001 - G.Juyn                                * */
-/* *             - added get function for last processed BACK chunk         * */
-/* *                                                                        * */
-/* *             1.0.5 - 08/15/2002 - G.Juyn                                * */
-/* *             - completed PROM support                                   * */
-/* *             - completed delta-image support                            * */
-/* *             1.0.5 - 08/19/2002 - G.Juyn                                * */
-/* *             - B597134 - libmng pollutes the linker namespace           * */
-/* *             - added HLAPI function to copy chunks                      * */
-/* *             1.0.5 - 09/14/2002 - G.Juyn                                * */
-/* *             - added event handling for dynamic MNG                     * */
-/* *             1.0.5 - 09/20/2002 - G.Juyn                                * */
-/* *             - added support for PAST                                   * */
-/* *             1.0.5 - 09/22/2002 - G.Juyn                                * */
-/* *             - added bgrx8 canvas (filler byte)                         * */
-/* *             1.0.5 - 09/23/2002 - G.Juyn                                * */
-/* *             - added in-memory color-correction of abstract images      * */
-/* *             - added compose over/under routines for PAST processing    * */
-/* *             - added flip & tile routines for PAST processing           * */
-/* *             1.0.5 - 10/09/2002 - G.Juyn                                * */
-/* *             - fixed trace-constants for PAST chunk                     * */
-/* *             1.0.5 - 11/07/2002 - G.Juyn                                * */
-/* *             - added support to get totals after mng_read()             * */
-/* *                                                                        * */
-/* *             1.0.6 - 07/14/2003 - G.Randers-Pehrson                     * */
-/* *             - added conditionals around rarely used features           * */
-/* *                                                                        * */
-/* *             1.0.7 - 11/27/2003 - R.A                                   * */
-/* *             - added CANVAS_RGB565 and CANVAS_BGR565                    * */
-/* *             1.0.7 - 01/25/2004 - J.S                                   * */
-/* *             - added premultiplied alpha canvas' for RGBA, ARGB, ABGR   * */
-/* *             1.0.7 - 03/10/2004 - G.R-P                                 * */
-/* *             - added conditionals around openstream/closestream         * */
-/* *                                                                        * */
-/* *             1.0.8 - 04/02/2004 - G.Juyn                                * */
-/* *             - added CRC existence & checking flags                     * */
-/* *             1.0.8 - 04/11/2004 - G.Juyn                                * */
-/* *             - added data-push mechanisms for specialized decoders      * */
-/* *                                                                        * */
-/* *             1.0.9 - 10/03/2004 - G.Juyn                                * */
-/* *             - added function to retrieve current FRAM delay            * */
-/* *             1.0.9 - 10/14/2004 - G.Juyn                                * */
-/* *             - added bgr565_a8 canvas-style (thanks to J. Elvander)     * */
-/* *                                                                        * */
-/* *             1.0.10 - 04/08/2007 - G.Juyn                               * */
-/* *             - added support for mPNG proposal                          * */
-/* *             1.0.10 - 07/06/2007 - G.R-P bugfix by Lucas Quintana       * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
-#pragma option -A                      /* force ANSI-C */
-#endif
-
-#ifndef _libmng_trace_h_
-#define _libmng_trace_h_
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_TRACE_PROCS
-
-/* ************************************************************************** */
-
-/* TODO: add a trace-mask so certain functions can be excluded */
-
-mng_retcode mng_trace (mng_datap  pData,
-                       mng_uint32 iFunction,
-                       mng_uint32 iLocation);
-
-/* ************************************************************************** */
-
-#define MNG_TRACE(D,F,L)  { mng_retcode iR = mng_trace (D,F,L); \
-                            if (iR) return iR; }
-
-#define MNG_TRACEB(D,F,L) { if (mng_trace (D,F,L)) return MNG_FALSE; }
-
-#define MNG_TRACEX(D,F,L) { if (mng_trace (D,F,L)) return 0; }
-
-/* ************************************************************************** */
-
-#define MNG_LC_START                    1
-#define MNG_LC_END                      2
-#define MNG_LC_INITIALIZE               3
-#define MNG_LC_CLEANUP                  4
-
-/* ************************************************************************** */
-
-#define MNG_LC_JPEG_CREATE_DECOMPRESS   101
-#define MNG_LC_JPEG_READ_HEADER         102
-#define MNG_LC_JPEG_START_DECOMPRESS    103
-#define MNG_LC_JPEG_START_OUTPUT        104
-#define MNG_LC_JPEG_READ_SCANLINES      105
-#define MNG_LC_JPEG_FINISH_OUTPUT       106
-#define MNG_LC_JPEG_FINISH_DECOMPRESS   107
-#define MNG_LC_JPEG_DESTROY_DECOMPRESS  108
-
-/* ************************************************************************** */
-
-#define MNG_FN_INITIALIZE               1
-#define MNG_FN_RESET                    2
-#define MNG_FN_CLEANUP                  3
-#define MNG_FN_READ                     4
-#define MNG_FN_WRITE                    5
-#define MNG_FN_CREATE                   6
-#define MNG_FN_READDISPLAY              7
-#define MNG_FN_DISPLAY                  8
-#define MNG_FN_DISPLAY_RESUME           9
-#define MNG_FN_DISPLAY_FREEZE          10
-#define MNG_FN_DISPLAY_RESET           11
-#ifndef MNG_NO_DISPLAY_GO_SUPPORTED
-#define MNG_FN_DISPLAY_GOFRAME         12
-#define MNG_FN_DISPLAY_GOLAYER         13
-#define MNG_FN_DISPLAY_GOTIME          14
-#endif
-#define MNG_FN_GETLASTERROR            15
-#define MNG_FN_READ_RESUME             16
-#define MNG_FN_TRAPEVENT               17
-#define MNG_FN_READ_PUSHDATA           18
-#define MNG_FN_READ_PUSHSIG            19
-#define MNG_FN_READ_PUSHCHUNK          20
-
-#define MNG_FN_SETCB_MEMALLOC         101
-#define MNG_FN_SETCB_MEMFREE          102
-#define MNG_FN_SETCB_READDATA         103
-#define MNG_FN_SETCB_WRITEDATA        104
-#define MNG_FN_SETCB_ERRORPROC        105
-#define MNG_FN_SETCB_TRACEPROC        106
-#define MNG_FN_SETCB_PROCESSHEADER    107
-#define MNG_FN_SETCB_PROCESSTEXT      108
-#define MNG_FN_SETCB_GETCANVASLINE    109
-#define MNG_FN_SETCB_GETBKGDLINE      110
-#define MNG_FN_SETCB_REFRESH          111
-#define MNG_FN_SETCB_GETTICKCOUNT     112
-#define MNG_FN_SETCB_SETTIMER         113
-#define MNG_FN_SETCB_PROCESSGAMMA     114
-#define MNG_FN_SETCB_PROCESSCHROMA    115
-#define MNG_FN_SETCB_PROCESSSRGB      116
-#define MNG_FN_SETCB_PROCESSICCP      117
-#define MNG_FN_SETCB_PROCESSAROW      118
-#ifndef MNG_NO_OPEN_CLOSE_STREAM
-#define MNG_FN_SETCB_OPENSTREAM       119
-#define MNG_FN_SETCB_CLOSESTREAM      120
-#endif
-#define MNG_FN_SETCB_GETALPHALINE     121
-#define MNG_FN_SETCB_PROCESSSAVE      122
-#define MNG_FN_SETCB_PROCESSSEEK      123
-#define MNG_FN_SETCB_PROCESSNEED      124
-#define MNG_FN_SETCB_PROCESSUNKNOWN   125
-#define MNG_FN_SETCB_PROCESSMEND      126
-#define MNG_FN_SETCB_PROCESSTERM      127
-#define MNG_FN_SETCB_RELEASEDATA      128
-
-#define MNG_FN_GETCB_MEMALLOC         201
-#define MNG_FN_GETCB_MEMFREE          202
-#define MNG_FN_GETCB_READDATA         203
-#define MNG_FN_GETCB_WRITEDATA        204
-#define MNG_FN_GETCB_ERRORPROC        205
-#define MNG_FN_GETCB_TRACEPROC        206
-#define MNG_FN_GETCB_PROCESSHEADER    207
-#define MNG_FN_GETCB_PROCESSTEXT      208
-#define MNG_FN_GETCB_GETCANVASLINE    209
-#define MNG_FN_GETCB_GETBKGDLINE      210
-#define MNG_FN_GETCB_REFRESH          211
-#define MNG_FN_GETCB_GETTICKCOUNT     212
-#define MNG_FN_GETCB_SETTIMER         213
-#define MNG_FN_GETCB_PROCESSGAMMA     214
-#define MNG_FN_GETCB_PROCESSCHROMA    215
-#define MNG_FN_GETCB_PROCESSSRGB      216
-#define MNG_FN_GETCB_PROCESSICCP      217
-#define MNG_FN_GETCB_PROCESSAROW      218
-#ifndef MNG_NO_OPEN_CLOSE_STREAM
-#define MNG_FN_GETCB_OPENSTREAM       219
-#define MNG_FN_GETCB_CLOSESTREAM      220
-#endif
-#define MNG_FN_GETCB_GETALPHALINE     221
-#define MNG_FN_GETCB_PROCESSSAVE      222
-#define MNG_FN_GETCB_PROCESSSEEK      223
-#define MNG_FN_GETCB_PROCESSNEED      224
-#define MNG_FN_GETCB_PROCESSUNKNOWN   225
-#define MNG_FN_GETCB_PROCESSMEND      226
-#define MNG_FN_GETCB_PROCESSTERM      227
-#define MNG_FN_GETCB_RELEASEDATA      228
-
-#define MNG_FN_SET_USERDATA           301
-#define MNG_FN_SET_CANVASSTYLE        302
-#define MNG_FN_SET_BKGDSTYLE          303
-#define MNG_FN_SET_BGCOLOR            304
-#define MNG_FN_SET_STORECHUNKS        305
-#define MNG_FN_SET_VIEWGAMMA          306
-#define MNG_FN_SET_DISPLAYGAMMA       307
-#define MNG_FN_SET_DFLTIMGGAMMA       308
-#define MNG_FN_SET_SRGB               309
-#define MNG_FN_SET_OUTPUTPROFILE      310
-#define MNG_FN_SET_SRGBPROFILE        311
-#define MNG_FN_SET_MAXCANVASWIDTH     312
-#define MNG_FN_SET_MAXCANVASHEIGHT    313
-#define MNG_FN_SET_MAXCANVASSIZE      314
-#define MNG_FN_SET_ZLIB_LEVEL         315
-#define MNG_FN_SET_ZLIB_METHOD        316
-#define MNG_FN_SET_ZLIB_WINDOWBITS    317
-#define MNG_FN_SET_ZLIB_MEMLEVEL      318
-#define MNG_FN_SET_ZLIB_STRATEGY      319
-#define MNG_FN_SET_ZLIB_MAXIDAT       320
-#define MNG_FN_SET_JPEG_DCTMETHOD     321
-#define MNG_FN_SET_JPEG_QUALITY       322
-#define MNG_FN_SET_JPEG_SMOOTHING     323
-#define MNG_FN_SET_JPEG_PROGRESSIVE   324
-#define MNG_FN_SET_JPEG_OPTIMIZED     325
-#define MNG_FN_SET_JPEG_MAXJDAT       326
-#define MNG_FN_SET_SPEED              327
-#define MNG_FN_SET_SUSPENSIONMODE     328
-#define MNG_FN_SET_SECTIONBREAKS      329
-#define MNG_FN_SET_USEBKGD            330
-#define MNG_FN_SET_OUTPUTPROFILE2     331
-#define MNG_FN_SET_SRGBPROFILE2       332
-#define MNG_FN_SET_OUTPUTSRGB         333
-#define MNG_FN_SET_SRGBIMPLICIT       334
-#define MNG_FN_SET_CACHEPLAYBACK      335
-#define MNG_FN_SET_DOPROGRESSIVE      336
-#define MNG_FN_SET_CRCMODE            337
-
-#define MNG_FN_GET_USERDATA           401
-#define MNG_FN_GET_SIGTYPE            402
-#define MNG_FN_GET_IMAGETYPE          403
-#define MNG_FN_GET_IMAGEWIDTH         404
-#define MNG_FN_GET_IMAGEHEIGHT        405
-#define MNG_FN_GET_TICKS              406
-#define MNG_FN_GET_FRAMECOUNT         407
-#define MNG_FN_GET_LAYERCOUNT         408
-#define MNG_FN_GET_PLAYTIME           409
-#define MNG_FN_GET_SIMPLICITY         410
-#define MNG_FN_GET_CANVASSTYLE        411
-#define MNG_FN_GET_BKGDSTYLE          412
-#define MNG_FN_GET_BGCOLOR            413
-#define MNG_FN_GET_STORECHUNKS        414
-#define MNG_FN_GET_VIEWGAMMA          415
-#define MNG_FN_GET_DISPLAYGAMMA       416
-#define MNG_FN_GET_DFLTIMGGAMMA       417
-#define MNG_FN_GET_SRGB               418
-#define MNG_FN_GET_MAXCANVASWIDTH     419
-#define MNG_FN_GET_MAXCANVASHEIGHT    420
-#define MNG_FN_GET_ZLIB_LEVEL         421
-#define MNG_FN_GET_ZLIB_METHOD        422
-#define MNG_FN_GET_ZLIB_WINDOWBITS    423
-#define MNG_FN_GET_ZLIB_MEMLEVEL      424
-#define MNG_FN_GET_ZLIB_STRATEGY      425
-#define MNG_FN_GET_ZLIB_MAXIDAT       426
-#define MNG_FN_GET_JPEG_DCTMETHOD     427
-#define MNG_FN_GET_JPEG_QUALITY       428
-#define MNG_FN_GET_JPEG_SMOOTHING     429
-#define MNG_FN_GET_JPEG_PROGRESSIVE   430
-#define MNG_FN_GET_JPEG_OPTIMIZED     431
-#define MNG_FN_GET_JPEG_MAXJDAT       432
-#define MNG_FN_GET_SPEED              433
-#define MNG_FN_GET_IMAGELEVEL         434
-#define MNG_FN_GET_SUSPENSIONMODE     435
-#define MNG_FN_GET_STARTTIME          436
-#define MNG_FN_GET_RUNTIME            437
-#define MNG_FN_GET_CURRENTFRAME       438
-#define MNG_FN_GET_CURRENTLAYER       439
-#define MNG_FN_GET_CURRENTPLAYTIME    440
-#define MNG_FN_GET_SECTIONBREAKS      441
-#define MNG_FN_GET_ALPHADEPTH         442
-#define MNG_FN_GET_BITDEPTH           443
-#define MNG_FN_GET_COLORTYPE          444
-#define MNG_FN_GET_COMPRESSION        445
-#define MNG_FN_GET_FILTER             446
-#define MNG_FN_GET_INTERLACE          447
-#define MNG_FN_GET_ALPHABITDEPTH      448
-#define MNG_FN_GET_ALPHACOMPRESSION   449
-#define MNG_FN_GET_ALPHAFILTER        450
-#define MNG_FN_GET_ALPHAINTERLACE     451
-#define MNG_FN_GET_USEBKGD            452
-#define MNG_FN_GET_REFRESHPASS        453
-#define MNG_FN_GET_CACHEPLAYBACK      454
-#define MNG_FN_GET_DOPROGRESSIVE      455
-#define MNG_FN_GET_LASTBACKCHUNK      456
-#define MNG_FN_GET_LASTSEEKNAME       457
-#define MNG_FN_GET_TOTALFRAMES        458
-#define MNG_FN_GET_TOTALLAYERS        459
-#define MNG_FN_GET_TOTALPLAYTIME      460
-#define MNG_FN_GET_CRCMODE            461
-#define MNG_FN_GET_CURRFRAMDELAY      462
-
-#define MNG_FN_STATUS_ERROR           481
-#define MNG_FN_STATUS_READING         482
-#define MNG_FN_STATUS_SUSPENDBREAK    483
-#define MNG_FN_STATUS_CREATING        484
-#define MNG_FN_STATUS_WRITING         485
-#define MNG_FN_STATUS_DISPLAYING      486
-#define MNG_FN_STATUS_RUNNING         487
-#define MNG_FN_STATUS_TIMERBREAK      488
-#define MNG_FN_STATUS_DYNAMIC         489
-#define MNG_FN_STATUS_RUNNINGEVENT    490
-
-/* ************************************************************************** */
-
-#define MNG_FN_ITERATE_CHUNKS         601
-#define MNG_FN_COPY_CHUNK             602
-
-#define MNG_FN_GETCHUNK_IHDR          701
-#define MNG_FN_GETCHUNK_PLTE          702
-#define MNG_FN_GETCHUNK_IDAT          703
-#define MNG_FN_GETCHUNK_IEND          704
-#define MNG_FN_GETCHUNK_TRNS          705
-#define MNG_FN_GETCHUNK_GAMA          706
-#define MNG_FN_GETCHUNK_CHRM          707
-#define MNG_FN_GETCHUNK_SRGB          708
-#define MNG_FN_GETCHUNK_ICCP          709
-#define MNG_FN_GETCHUNK_TEXT          710
-#define MNG_FN_GETCHUNK_ZTXT          711
-#define MNG_FN_GETCHUNK_ITXT          712
-#define MNG_FN_GETCHUNK_BKGD          713
-#define MNG_FN_GETCHUNK_PHYS          714
-#define MNG_FN_GETCHUNK_SBIT          715
-#define MNG_FN_GETCHUNK_SPLT          716
-#define MNG_FN_GETCHUNK_HIST          717
-#define MNG_FN_GETCHUNK_TIME          718
-#define MNG_FN_GETCHUNK_MHDR          719
-#define MNG_FN_GETCHUNK_MEND          720
-#define MNG_FN_GETCHUNK_LOOP          721
-#define MNG_FN_GETCHUNK_ENDL          722
-#define MNG_FN_GETCHUNK_DEFI          723
-#define MNG_FN_GETCHUNK_BASI          724
-#define MNG_FN_GETCHUNK_CLON          725
-#define MNG_FN_GETCHUNK_PAST          726
-#define MNG_FN_GETCHUNK_DISC          727
-#define MNG_FN_GETCHUNK_BACK          728
-#define MNG_FN_GETCHUNK_FRAM          729
-#define MNG_FN_GETCHUNK_MOVE          730
-#define MNG_FN_GETCHUNK_CLIP          731
-#define MNG_FN_GETCHUNK_SHOW          732
-#define MNG_FN_GETCHUNK_TERM          733
-#define MNG_FN_GETCHUNK_SAVE          734
-#define MNG_FN_GETCHUNK_SEEK          735
-#define MNG_FN_GETCHUNK_EXPI          736
-#define MNG_FN_GETCHUNK_FPRI          737
-#define MNG_FN_GETCHUNK_NEED          738
-#define MNG_FN_GETCHUNK_PHYG          739
-#define MNG_FN_GETCHUNK_JHDR          740
-#define MNG_FN_GETCHUNK_JDAT          741
-#define MNG_FN_GETCHUNK_JSEP          742
-#define MNG_FN_GETCHUNK_DHDR          743
-#define MNG_FN_GETCHUNK_PROM          744
-#define MNG_FN_GETCHUNK_IPNG          745
-#define MNG_FN_GETCHUNK_PPLT          746
-#define MNG_FN_GETCHUNK_IJNG          747
-#define MNG_FN_GETCHUNK_DROP          748
-#define MNG_FN_GETCHUNK_DBYK          749
-#define MNG_FN_GETCHUNK_ORDR          750
-#define MNG_FN_GETCHUNK_UNKNOWN       751
-#define MNG_FN_GETCHUNK_MAGN          752
-#define MNG_FN_GETCHUNK_JDAA          753
-#define MNG_FN_GETCHUNK_EVNT          754
-#define MNG_FN_GETCHUNK_MPNG          755
-
-#define MNG_FN_GETCHUNK_PAST_SRC      781
-#define MNG_FN_GETCHUNK_SAVE_ENTRY    782
-#define MNG_FN_GETCHUNK_PPLT_ENTRY    783
-#define MNG_FN_GETCHUNK_ORDR_ENTRY    784
-#define MNG_FN_GETCHUNK_EVNT_ENTRY    785
-#define MNG_FN_GETCHUNK_MPNG_FRAME    786
-
-#define MNG_FN_PUTCHUNK_IHDR          801
-#define MNG_FN_PUTCHUNK_PLTE          802
-#define MNG_FN_PUTCHUNK_IDAT          803
-#define MNG_FN_PUTCHUNK_IEND          804
-#define MNG_FN_PUTCHUNK_TRNS          805
-#define MNG_FN_PUTCHUNK_GAMA          806
-#define MNG_FN_PUTCHUNK_CHRM          807
-#define MNG_FN_PUTCHUNK_SRGB          808
-#define MNG_FN_PUTCHUNK_ICCP          809
-#define MNG_FN_PUTCHUNK_TEXT          810
-#define MNG_FN_PUTCHUNK_ZTXT          811
-#define MNG_FN_PUTCHUNK_ITXT          812
-#define MNG_FN_PUTCHUNK_BKGD          813
-#define MNG_FN_PUTCHUNK_PHYS          814
-#define MNG_FN_PUTCHUNK_SBIT          815
-#define MNG_FN_PUTCHUNK_SPLT          816
-#define MNG_FN_PUTCHUNK_HIST          817
-#define MNG_FN_PUTCHUNK_TIME          818
-#define MNG_FN_PUTCHUNK_MHDR          819
-#define MNG_FN_PUTCHUNK_MEND          820
-#define MNG_FN_PUTCHUNK_LOOP          821
-#define MNG_FN_PUTCHUNK_ENDL          822
-#define MNG_FN_PUTCHUNK_DEFI          823
-#define MNG_FN_PUTCHUNK_BASI          824
-#define MNG_FN_PUTCHUNK_CLON          825
-#define MNG_FN_PUTCHUNK_PAST          826
-#define MNG_FN_PUTCHUNK_DISC          827
-#define MNG_FN_PUTCHUNK_BACK          828
-#define MNG_FN_PUTCHUNK_FRAM          829
-#define MNG_FN_PUTCHUNK_MOVE          830
-#define MNG_FN_PUTCHUNK_CLIP          831
-#define MNG_FN_PUTCHUNK_SHOW          832
-#define MNG_FN_PUTCHUNK_TERM          833
-#define MNG_FN_PUTCHUNK_SAVE          834
-#define MNG_FN_PUTCHUNK_SEEK          835
-#define MNG_FN_PUTCHUNK_EXPI          836
-#define MNG_FN_PUTCHUNK_FPRI          837
-#define MNG_FN_PUTCHUNK_NEED          838
-#define MNG_FN_PUTCHUNK_PHYG          839
-#define MNG_FN_PUTCHUNK_JHDR          840
-#define MNG_FN_PUTCHUNK_JDAT          841
-#define MNG_FN_PUTCHUNK_JSEP          842
-#define MNG_FN_PUTCHUNK_DHDR          843
-#define MNG_FN_PUTCHUNK_PROM          844
-#define MNG_FN_PUTCHUNK_IPNG          845
-#define MNG_FN_PUTCHUNK_PPLT          846
-#define MNG_FN_PUTCHUNK_IJNG          847
-#define MNG_FN_PUTCHUNK_DROP          848
-#define MNG_FN_PUTCHUNK_DBYK          849
-#define MNG_FN_PUTCHUNK_ORDR          850
-#define MNG_FN_PUTCHUNK_UNKNOWN       851
-#define MNG_FN_PUTCHUNK_MAGN          852
-#define MNG_FN_PUTCHUNK_JDAA          853
-#define MNG_FN_PUTCHUNK_EVNT          854
-#define MNG_FN_PUTCHUNK_MPNG          855
-
-#define MNG_FN_PUTCHUNK_PAST_SRC      881
-#define MNG_FN_PUTCHUNK_SAVE_ENTRY    882
-#define MNG_FN_PUTCHUNK_PPLT_ENTRY    883
-#define MNG_FN_PUTCHUNK_ORDR_ENTRY    884
-#define MNG_FN_PUTCHUNK_EVNT_ENTRY    885
-#define MNG_FN_PUTCHUNK_MPNG_FRAME    886
-
-/* ************************************************************************** */
-
-#define MNG_FN_GETIMGDATA_SEQ         901
-#define MNG_FN_GETIMGDATA_CHUNKSEQ    902
-#define MNG_FN_GETIMGDATA_CHUNK       903
-
-#define MNG_FN_PUTIMGDATA_IHDR        951
-#define MNG_FN_PUTIMGDATA_JHDR        952
-#define MNG_FN_PUTIMGDATA_BASI        953
-#define MNG_FN_PUTIMGDATA_DHDR        954
-
-#define MNG_FN_UPDATEMNGHEADER        981
-#define MNG_FN_UPDATEMNGSIMPLICITY    982
-
-/* ************************************************************************** */
-
-#define MNG_FN_PROCESS_RAW_CHUNK     1001
-#define MNG_FN_READ_GRAPHIC          1002
-#define MNG_FN_DROP_CHUNKS           1003
-#define MNG_FN_PROCESS_ERROR         1004
-#define MNG_FN_CLEAR_CMS             1005
-#define MNG_FN_DROP_OBJECTS          1006
-#define MNG_FN_READ_CHUNK            1007
-#define MNG_FN_LOAD_BKGDLAYER        1008
-#define MNG_FN_NEXT_FRAME            1009
-#define MNG_FN_NEXT_LAYER            1010
-#define MNG_FN_INTERFRAME_DELAY      1011
-#define MNG_FN_DISPLAY_IMAGE         1012
-#define MNG_FN_DROP_IMGOBJECTS       1013
-#define MNG_FN_DROP_ANIOBJECTS       1014
-#define MNG_FN_INFLATE_BUFFER        1015
-#define MNG_FN_DEFLATE_BUFFER        1016
-#define MNG_FN_WRITE_RAW_CHUNK       1017
-#define MNG_FN_WRITE_GRAPHIC         1018
-#define MNG_FN_SAVE_STATE            1019
-#define MNG_FN_RESTORE_STATE         1020
-#define MNG_FN_DROP_SAVEDATA         1021
-#define MNG_FN_EXECUTE_DELTA_IMAGE   1022
-#define MNG_FN_PROCESS_DISPLAY       1023
-#define MNG_FN_CLEAR_CANVAS          1024
-#define MNG_FN_READ_DATABUFFER       1025
-#define MNG_FN_STORE_ERROR           1026
-#define MNG_FN_DROP_INVALID_OBJECTS  1027
-#define MNG_FN_RELEASE_PUSHDATA      1028
-#define MNG_FN_READ_DATA             1029
-#define MNG_FN_READ_CHUNK_CRC        1030
-#define MNG_FN_RELEASE_PUSHCHUNK     1031
-
-/* ************************************************************************** */
-
-#define MNG_FN_DISPLAY_RGB8          1101
-#define MNG_FN_DISPLAY_RGBA8         1102
-#define MNG_FN_DISPLAY_ARGB8         1103
-#define MNG_FN_DISPLAY_BGR8          1104
-#define MNG_FN_DISPLAY_BGRA8         1105
-#define MNG_FN_DISPLAY_ABGR8         1106
-#define MNG_FN_DISPLAY_RGB16         1107
-#define MNG_FN_DISPLAY_RGBA16        1108
-#define MNG_FN_DISPLAY_ARGB16        1109
-#define MNG_FN_DISPLAY_BGR16         1110
-#define MNG_FN_DISPLAY_BGRA16        1111
-#define MNG_FN_DISPLAY_ABGR16        1112
-#define MNG_FN_DISPLAY_INDEX8        1113
-#define MNG_FN_DISPLAY_INDEXA8       1114
-#define MNG_FN_DISPLAY_AINDEX8       1115
-#define MNG_FN_DISPLAY_GRAY8         1116
-#define MNG_FN_DISPLAY_GRAY16        1117
-#define MNG_FN_DISPLAY_GRAYA8        1118
-#define MNG_FN_DISPLAY_GRAYA16       1119
-#define MNG_FN_DISPLAY_AGRAY8        1120
-#define MNG_FN_DISPLAY_AGRAY16       1121
-#define MNG_FN_DISPLAY_DX15          1122
-#define MNG_FN_DISPLAY_DX16          1123
-#define MNG_FN_DISPLAY_RGB8_A8       1124
-#define MNG_FN_DISPLAY_BGRA8PM       1125
-#define MNG_FN_DISPLAY_BGRX8         1126
-#define MNG_FN_DISPLAY_RGB565        1127
-#define MNG_FN_DISPLAY_RGBA565       1128
-#define MNG_FN_DISPLAY_BGR565        1129
-#define MNG_FN_DISPLAY_BGRA565       1130
-#define MNG_FN_DISPLAY_RGBA8_PM      1131
-#define MNG_FN_DISPLAY_ARGB8_PM      1132
-#define MNG_FN_DISPLAY_ABGR8_PM      1133
-#define MNG_FN_DISPLAY_BGR565_A8     1134
-#define MNG_FN_DISPLAY_RGB555        1135
-#define MNG_FN_DISPLAY_BGR555        1136
-
-/* ************************************************************************** */
-
-#define MNG_FN_INIT_FULL_CMS         1201
-#define MNG_FN_CORRECT_FULL_CMS      1202
-#define MNG_FN_INIT_GAMMA_ONLY       1204
-#define MNG_FN_CORRECT_GAMMA_ONLY    1205
-#define MNG_FN_CORRECT_APP_CMS       1206
-#define MNG_FN_INIT_FULL_CMS_OBJ     1207
-#define MNG_FN_INIT_GAMMA_ONLY_OBJ   1208
-#define MNG_FN_INIT_APP_CMS          1209
-#define MNG_FN_INIT_APP_CMS_OBJ      1210
-
-/* ************************************************************************** */
-
-#define MNG_FN_PROCESS_G1            1301
-#define MNG_FN_PROCESS_G2            1302
-#define MNG_FN_PROCESS_G4            1303
-#define MNG_FN_PROCESS_G8            1304
-#define MNG_FN_PROCESS_G16           1305
-#define MNG_FN_PROCESS_RGB8          1306
-#define MNG_FN_PROCESS_RGB16         1307
-#define MNG_FN_PROCESS_IDX1          1308
-#define MNG_FN_PROCESS_IDX2          1309
-#define MNG_FN_PROCESS_IDX4          1310
-#define MNG_FN_PROCESS_IDX8          1311
-#define MNG_FN_PROCESS_GA8           1312
-#define MNG_FN_PROCESS_GA16          1313
-#define MNG_FN_PROCESS_RGBA8         1314
-#define MNG_FN_PROCESS_RGBA16        1315
-
-/* ************************************************************************** */
-
-#define MNG_FN_INIT_G1_NI            1401
-#define MNG_FN_INIT_G1_I             1402
-#define MNG_FN_INIT_G2_NI            1403
-#define MNG_FN_INIT_G2_I             1404
-#define MNG_FN_INIT_G4_NI            1405
-#define MNG_FN_INIT_G4_I             1406
-#define MNG_FN_INIT_G8_NI            1407
-#define MNG_FN_INIT_G8_I             1408
-#define MNG_FN_INIT_G16_NI           1409
-#define MNG_FN_INIT_G16_I            1410
-#define MNG_FN_INIT_RGB8_NI          1411
-#define MNG_FN_INIT_RGB8_I           1412
-#define MNG_FN_INIT_RGB16_NI         1413
-#define MNG_FN_INIT_RGB16_I          1414
-#define MNG_FN_INIT_IDX1_NI          1415
-#define MNG_FN_INIT_IDX1_I           1416
-#define MNG_FN_INIT_IDX2_NI          1417
-#define MNG_FN_INIT_IDX2_I           1418
-#define MNG_FN_INIT_IDX4_NI          1419
-#define MNG_FN_INIT_IDX4_I           1420
-#define MNG_FN_INIT_IDX8_NI          1421
-#define MNG_FN_INIT_IDX8_I           1422
-#define MNG_FN_INIT_GA8_NI           1423
-#define MNG_FN_INIT_GA8_I            1424
-#define MNG_FN_INIT_GA16_NI          1425
-#define MNG_FN_INIT_GA16_I           1426
-#define MNG_FN_INIT_RGBA8_NI         1427
-#define MNG_FN_INIT_RGBA8_I          1428
-#define MNG_FN_INIT_RGBA16_NI        1429
-#define MNG_FN_INIT_RGBA16_I         1430
-
-#define MNG_FN_INIT_ROWPROC          1497
-#define MNG_FN_NEXT_ROW              1498
-#define MNG_FN_CLEANUP_ROWPROC       1499
-
-/* ************************************************************************** */
-
-#define MNG_FN_FILTER_A_ROW          1501
-#define MNG_FN_FILTER_SUB            1502
-#define MNG_FN_FILTER_UP             1503
-#define MNG_FN_FILTER_AVERAGE        1504
-#define MNG_FN_FILTER_PAETH          1505
-
-#define MNG_FN_INIT_ROWDIFFERING     1551
-#define MNG_FN_DIFFER_G1             1552
-#define MNG_FN_DIFFER_G2             1553
-#define MNG_FN_DIFFER_G4             1554
-#define MNG_FN_DIFFER_G8             1555
-#define MNG_FN_DIFFER_G16            1556
-#define MNG_FN_DIFFER_RGB8           1557
-#define MNG_FN_DIFFER_RGB16          1558
-#define MNG_FN_DIFFER_IDX1           1559
-#define MNG_FN_DIFFER_IDX2           1560
-#define MNG_FN_DIFFER_IDX4           1561
-#define MNG_FN_DIFFER_IDX8           1562
-#define MNG_FN_DIFFER_GA8            1563
-#define MNG_FN_DIFFER_GA16           1564
-#define MNG_FN_DIFFER_RGBA8          1565
-#define MNG_FN_DIFFER_RGBA16         1566
-
-/* ************************************************************************** */
-
-#define MNG_FN_CREATE_IMGDATAOBJECT  1601
-#define MNG_FN_FREE_IMGDATAOBJECT    1602
-#define MNG_FN_CLONE_IMGDATAOBJECT   1603
-#define MNG_FN_CREATE_IMGOBJECT      1604
-#define MNG_FN_FREE_IMGOBJECT        1605
-#define MNG_FN_FIND_IMGOBJECT        1606
-#define MNG_FN_CLONE_IMGOBJECT       1607
-#define MNG_FN_RESET_OBJECTDETAILS   1608
-#define MNG_FN_RENUM_IMGOBJECT       1609
-#define MNG_FN_PROMOTE_IMGOBJECT     1610
-#define MNG_FN_MAGNIFY_IMGOBJECT     1611
-#define MNG_FN_COLORCORRECT_OBJECT   1612
-
-/* ************************************************************************** */
-
-#define MNG_FN_STORE_G1              1701
-#define MNG_FN_STORE_G2              1702
-#define MNG_FN_STORE_G4              1703
-#define MNG_FN_STORE_G8              1704
-#define MNG_FN_STORE_G16             1705
-#define MNG_FN_STORE_RGB8            1706
-#define MNG_FN_STORE_RGB16           1707
-#define MNG_FN_STORE_IDX1            1708
-#define MNG_FN_STORE_IDX2            1709
-#define MNG_FN_STORE_IDX4            1710
-#define MNG_FN_STORE_IDX8            1711
-#define MNG_FN_STORE_GA8             1712
-#define MNG_FN_STORE_GA16            1713
-#define MNG_FN_STORE_RGBA8           1714
-#define MNG_FN_STORE_RGBA16          1715
-
-#define MNG_FN_RETRIEVE_G8           1751
-#define MNG_FN_RETRIEVE_G16          1752
-#define MNG_FN_RETRIEVE_RGB8         1753
-#define MNG_FN_RETRIEVE_RGB16        1754
-#define MNG_FN_RETRIEVE_IDX8         1755
-#define MNG_FN_RETRIEVE_GA8          1756
-#define MNG_FN_RETRIEVE_GA16         1757
-#define MNG_FN_RETRIEVE_RGBA8        1758
-#define MNG_FN_RETRIEVE_RGBA16       1759
-
-#define MNG_FN_DELTA_G1              1771
-#define MNG_FN_DELTA_G2              1772
-#define MNG_FN_DELTA_G4              1773
-#define MNG_FN_DELTA_G8              1774
-#define MNG_FN_DELTA_G16             1775
-#define MNG_FN_DELTA_RGB8            1776
-#define MNG_FN_DELTA_RGB16           1777
-#define MNG_FN_DELTA_IDX1            1778
-#define MNG_FN_DELTA_IDX2            1779
-#define MNG_FN_DELTA_IDX4            1780
-#define MNG_FN_DELTA_IDX8            1781
-#define MNG_FN_DELTA_GA8             1782
-#define MNG_FN_DELTA_GA16            1783
-#define MNG_FN_DELTA_RGBA8           1784
-#define MNG_FN_DELTA_RGBA16          1785
-
-/* ************************************************************************** */
-
-#define MNG_FN_CREATE_ANI_LOOP       1801
-#define MNG_FN_CREATE_ANI_ENDL       1802
-#define MNG_FN_CREATE_ANI_DEFI       1803
-#define MNG_FN_CREATE_ANI_BASI       1804
-#define MNG_FN_CREATE_ANI_CLON       1805
-#define MNG_FN_CREATE_ANI_PAST       1806
-#define MNG_FN_CREATE_ANI_DISC       1807
-#define MNG_FN_CREATE_ANI_BACK       1808
-#define MNG_FN_CREATE_ANI_FRAM       1809
-#define MNG_FN_CREATE_ANI_MOVE       1810
-#define MNG_FN_CREATE_ANI_CLIP       1811
-#define MNG_FN_CREATE_ANI_SHOW       1812
-#define MNG_FN_CREATE_ANI_TERM       1813
-#define MNG_FN_CREATE_ANI_SAVE       1814
-#define MNG_FN_CREATE_ANI_SEEK       1815
-#define MNG_FN_CREATE_ANI_GAMA       1816
-#define MNG_FN_CREATE_ANI_CHRM       1817
-#define MNG_FN_CREATE_ANI_SRGB       1818
-#define MNG_FN_CREATE_ANI_ICCP       1819
-#define MNG_FN_CREATE_ANI_PLTE       1820
-#define MNG_FN_CREATE_ANI_TRNS       1821
-#define MNG_FN_CREATE_ANI_BKGD       1822
-#define MNG_FN_CREATE_ANI_DHDR       1823
-#define MNG_FN_CREATE_ANI_PROM       1824
-#define MNG_FN_CREATE_ANI_IPNG       1825
-#define MNG_FN_CREATE_ANI_IJNG       1826
-#define MNG_FN_CREATE_ANI_PPLT       1827
-#define MNG_FN_CREATE_ANI_MAGN       1828
-
-#define MNG_FN_CREATE_ANI_IMAGE      1891
-#define MNG_FN_CREATE_EVENT          1892
-
-/* ************************************************************************** */
-
-#define MNG_FN_FREE_ANI_LOOP         1901
-#define MNG_FN_FREE_ANI_ENDL         1902
-#define MNG_FN_FREE_ANI_DEFI         1903
-#define MNG_FN_FREE_ANI_BASI         1904
-#define MNG_FN_FREE_ANI_CLON         1905
-#define MNG_FN_FREE_ANI_PAST         1906
-#define MNG_FN_FREE_ANI_DISC         1907
-#define MNG_FN_FREE_ANI_BACK         1908
-#define MNG_FN_FREE_ANI_FRAM         1909
-#define MNG_FN_FREE_ANI_MOVE         1910
-#define MNG_FN_FREE_ANI_CLIP         1911
-#define MNG_FN_FREE_ANI_SHOW         1912
-#define MNG_FN_FREE_ANI_TERM         1913
-#define MNG_FN_FREE_ANI_SAVE         1914
-#define MNG_FN_FREE_ANI_SEEK         1915
-#define MNG_FN_FREE_ANI_GAMA         1916
-#define MNG_FN_FREE_ANI_CHRM         1917
-#define MNG_FN_FREE_ANI_SRGB         1918
-#define MNG_FN_FREE_ANI_ICCP         1919
-#define MNG_FN_FREE_ANI_PLTE         1920
-#define MNG_FN_FREE_ANI_TRNS         1921
-#define MNG_FN_FREE_ANI_BKGD         1922
-#define MNG_FN_FREE_ANI_DHDR         1923
-#define MNG_FN_FREE_ANI_PROM         1924
-#define MNG_FN_FREE_ANI_IPNG         1925
-#define MNG_FN_FREE_ANI_IJNG         1926
-#define MNG_FN_FREE_ANI_PPLT         1927
-#define MNG_FN_FREE_ANI_MAGN         1928
-
-#define MNG_FN_FREE_ANI_IMAGE        1991
-#define MNG_FN_FREE_EVENT            1992
-
-/* ************************************************************************** */
-
-#define MNG_FN_PROCESS_ANI_LOOP      2001
-#define MNG_FN_PROCESS_ANI_ENDL      2002
-#define MNG_FN_PROCESS_ANI_DEFI      2003
-#define MNG_FN_PROCESS_ANI_BASI      2004
-#define MNG_FN_PROCESS_ANI_CLON      2005
-#define MNG_FN_PROCESS_ANI_PAST      2006
-#define MNG_FN_PROCESS_ANI_DISC      2007
-#define MNG_FN_PROCESS_ANI_BACK      2008
-#define MNG_FN_PROCESS_ANI_FRAM      2009
-#define MNG_FN_PROCESS_ANI_MOVE      2010
-#define MNG_FN_PROCESS_ANI_CLIP      2011
-#define MNG_FN_PROCESS_ANI_SHOW      2012
-#define MNG_FN_PROCESS_ANI_TERM      2013
-#define MNG_FN_PROCESS_ANI_SAVE      2014
-#define MNG_FN_PROCESS_ANI_SEEK      2015
-#define MNG_FN_PROCESS_ANI_GAMA      2016
-#define MNG_FN_PROCESS_ANI_CHRM      2017
-#define MNG_FN_PROCESS_ANI_SRGB      2018
-#define MNG_FN_PROCESS_ANI_ICCP      2019
-#define MNG_FN_PROCESS_ANI_PLTE      2020
-#define MNG_FN_PROCESS_ANI_TRNS      2021
-#define MNG_FN_PROCESS_ANI_BKGD      2022
-#define MNG_FN_PROCESS_ANI_DHDR      2023
-#define MNG_FN_PROCESS_ANI_PROM      2024
-#define MNG_FN_PROCESS_ANI_IPNG      2025
-#define MNG_FN_PROCESS_ANI_IJNG      2026
-#define MNG_FN_PROCESS_ANI_PPLT      2027
-#define MNG_FN_PROCESS_ANI_MAGN      2028
-
-#define MNG_FN_PROCESS_ANI_IMAGE     2091
-#define MNG_FN_PROCESS_EVENT         2092
-
-/* ************************************************************************** */
-
-#define MNG_FN_RESTORE_BACKIMAGE     2101
-#define MNG_FN_RESTORE_BACKCOLOR     2102
-#define MNG_FN_RESTORE_BGCOLOR       2103
-#define MNG_FN_RESTORE_RGB8          2104
-#define MNG_FN_RESTORE_BGR8          2105
-#define MNG_FN_RESTORE_BKGD          2106
-#define MNG_FN_RESTORE_BGRX8         2107
-#define MNG_FN_RESTORE_RGB565        2108
-#define MNG_FN_RESTORE_BGR565        2109
-
-/* ************************************************************************** */
-
-#define MNG_FN_INIT_IHDR             2201
-#define MNG_FN_INIT_PLTE             2202
-#define MNG_FN_INIT_IDAT             2203
-#define MNG_FN_INIT_IEND             2204
-#define MNG_FN_INIT_TRNS             2205
-#define MNG_FN_INIT_GAMA             2206
-#define MNG_FN_INIT_CHRM             2207
-#define MNG_FN_INIT_SRGB             2208
-#define MNG_FN_INIT_ICCP             2209
-#define MNG_FN_INIT_TEXT             2210
-#define MNG_FN_INIT_ZTXT             2211
-#define MNG_FN_INIT_ITXT             2212
-#define MNG_FN_INIT_BKGD             2213
-#define MNG_FN_INIT_PHYS             2214
-#define MNG_FN_INIT_SBIT             2215
-#define MNG_FN_INIT_SPLT             2216
-#define MNG_FN_INIT_HIST             2217
-#define MNG_FN_INIT_TIME             2218
-#define MNG_FN_INIT_MHDR             2219
-#define MNG_FN_INIT_MEND             2220
-#define MNG_FN_INIT_LOOP             2221
-#define MNG_FN_INIT_ENDL             2222
-#define MNG_FN_INIT_DEFI             2223
-#define MNG_FN_INIT_BASI             2224
-#define MNG_FN_INIT_CLON             2225
-#define MNG_FN_INIT_PAST             2226
-#define MNG_FN_INIT_DISC             2227
-#define MNG_FN_INIT_BACK             2228
-#define MNG_FN_INIT_FRAM             2229
-#define MNG_FN_INIT_MOVE             2230
-#define MNG_FN_INIT_CLIP             2231
-#define MNG_FN_INIT_SHOW             2232
-#define MNG_FN_INIT_TERM             2233
-#define MNG_FN_INIT_SAVE             2234
-#define MNG_FN_INIT_SEEK             2235
-#define MNG_FN_INIT_EXPI             2236
-#define MNG_FN_INIT_FPRI             2237
-#define MNG_FN_INIT_NEED             2238
-#define MNG_FN_INIT_PHYG             2239
-#define MNG_FN_INIT_JHDR             2240
-#define MNG_FN_INIT_JDAT             2241
-#define MNG_FN_INIT_JSEP             2242
-#define MNG_FN_INIT_DHDR             2243
-#define MNG_FN_INIT_PROM             2244
-#define MNG_FN_INIT_IPNG             2245
-#define MNG_FN_INIT_PPLT             2246
-#define MNG_FN_INIT_IJNG             2247
-#define MNG_FN_INIT_DROP             2248
-#define MNG_FN_INIT_DBYK             2249
-#define MNG_FN_INIT_ORDR             2250
-#define MNG_FN_INIT_UNKNOWN          2251
-#define MNG_FN_INIT_MAGN             2252
-#define MNG_FN_INIT_JDAA             2253
-#define MNG_FN_INIT_EVNT             2254
-#define MNG_FN_INIT_MPNG             2255
-
-/* ************************************************************************** */
-
-#define MNG_FN_ASSIGN_IHDR           2301
-#define MNG_FN_ASSIGN_PLTE           2302
-#define MNG_FN_ASSIGN_IDAT           2303
-#define MNG_FN_ASSIGN_IEND           2304
-#define MNG_FN_ASSIGN_TRNS           2305
-#define MNG_FN_ASSIGN_GAMA           2306
-#define MNG_FN_ASSIGN_CHRM           2307
-#define MNG_FN_ASSIGN_SRGB           2308
-#define MNG_FN_ASSIGN_ICCP           2309
-#define MNG_FN_ASSIGN_TEXT           2310
-#define MNG_FN_ASSIGN_ZTXT           2311
-#define MNG_FN_ASSIGN_ITXT           2312
-#define MNG_FN_ASSIGN_BKGD           2313
-#define MNG_FN_ASSIGN_PHYS           2314
-#define MNG_FN_ASSIGN_SBIT           2315
-#define MNG_FN_ASSIGN_SPLT           2316
-#define MNG_FN_ASSIGN_HIST           2317
-#define MNG_FN_ASSIGN_TIME           2318
-#define MNG_FN_ASSIGN_MHDR           2319
-#define MNG_FN_ASSIGN_MEND           2320
-#define MNG_FN_ASSIGN_LOOP           2321
-#define MNG_FN_ASSIGN_ENDL           2322
-#define MNG_FN_ASSIGN_DEFI           2323
-#define MNG_FN_ASSIGN_BASI           2324
-#define MNG_FN_ASSIGN_CLON           2325
-#define MNG_FN_ASSIGN_PAST           2326
-#define MNG_FN_ASSIGN_DISC           2327
-#define MNG_FN_ASSIGN_BACK           2328
-#define MNG_FN_ASSIGN_FRAM           2329
-#define MNG_FN_ASSIGN_MOVE           2330
-#define MNG_FN_ASSIGN_CLIP           2331
-#define MNG_FN_ASSIGN_SHOW           2332
-#define MNG_FN_ASSIGN_TERM           2333
-#define MNG_FN_ASSIGN_SAVE           2334
-#define MNG_FN_ASSIGN_SEEK           2335
-#define MNG_FN_ASSIGN_EXPI           2336
-#define MNG_FN_ASSIGN_FPRI           2337
-#define MNG_FN_ASSIGN_NEED           2338
-#define MNG_FN_ASSIGN_PHYG           2339
-#define MNG_FN_ASSIGN_JHDR           2340
-#define MNG_FN_ASSIGN_JDAT           2341
-#define MNG_FN_ASSIGN_JSEP           2342
-#define MNG_FN_ASSIGN_DHDR           2343
-#define MNG_FN_ASSIGN_PROM           2344
-#define MNG_FN_ASSIGN_IPNG           2345
-#define MNG_FN_ASSIGN_PPLT           2346
-#define MNG_FN_ASSIGN_IJNG           2347
-#define MNG_FN_ASSIGN_DROP           2348
-#define MNG_FN_ASSIGN_DBYK           2349
-#define MNG_FN_ASSIGN_ORDR           2350
-#define MNG_FN_ASSIGN_UNKNOWN        2351
-#define MNG_FN_ASSIGN_MAGN           2352
-#define MNG_FN_ASSIGN_JDAA           2353
-#define MNG_FN_ASSIGN_EVNT           2354
-#define MNG_FN_ASSIGN_MPNG           2355
-
-/* ************************************************************************** */
-
-#define MNG_FN_FREE_IHDR             2401
-#define MNG_FN_FREE_PLTE             2402
-#define MNG_FN_FREE_IDAT             2403
-#define MNG_FN_FREE_IEND             2404
-#define MNG_FN_FREE_TRNS             2405
-#define MNG_FN_FREE_GAMA             2406
-#define MNG_FN_FREE_CHRM             2407
-#define MNG_FN_FREE_SRGB             2408
-#define MNG_FN_FREE_ICCP             2409
-#define MNG_FN_FREE_TEXT             2410
-#define MNG_FN_FREE_ZTXT             2411
-#define MNG_FN_FREE_ITXT             2412
-#define MNG_FN_FREE_BKGD             2413
-#define MNG_FN_FREE_PHYS             2414
-#define MNG_FN_FREE_SBIT             2415
-#define MNG_FN_FREE_SPLT             2416
-#define MNG_FN_FREE_HIST             2417
-#define MNG_FN_FREE_TIME             2418
-#define MNG_FN_FREE_MHDR             2419
-#define MNG_FN_FREE_MEND             2420
-#define MNG_FN_FREE_LOOP             2421
-#define MNG_FN_FREE_ENDL             2422
-#define MNG_FN_FREE_DEFI             2423
-#define MNG_FN_FREE_BASI             2424
-#define MNG_FN_FREE_CLON             2425
-#define MNG_FN_FREE_PAST             2426
-#define MNG_FN_FREE_DISC             2427
-#define MNG_FN_FREE_BACK             2428
-#define MNG_FN_FREE_FRAM             2429
-#define MNG_FN_FREE_MOVE             2430
-#define MNG_FN_FREE_CLIP             2431
-#define MNG_FN_FREE_SHOW             2432
-#define MNG_FN_FREE_TERM             2433
-#define MNG_FN_FREE_SAVE             2434
-#define MNG_FN_FREE_SEEK             2435
-#define MNG_FN_FREE_EXPI             2436
-#define MNG_FN_FREE_FPRI             2437
-#define MNG_FN_FREE_NEED             2438
-#define MNG_FN_FREE_PHYG             2439
-#define MNG_FN_FREE_JHDR             2440
-#define MNG_FN_FREE_JDAT             2441
-#define MNG_FN_FREE_JSEP             2442
-#define MNG_FN_FREE_DHDR             2443
-#define MNG_FN_FREE_PROM             2444
-#define MNG_FN_FREE_IPNG             2445
-#define MNG_FN_FREE_PPLT             2446
-#define MNG_FN_FREE_IJNG             2447
-#define MNG_FN_FREE_DROP             2448
-#define MNG_FN_FREE_DBYK             2449
-#define MNG_FN_FREE_ORDR             2450
-#define MNG_FN_FREE_UNKNOWN          2451
-#define MNG_FN_FREE_MAGN             2452
-#define MNG_FN_FREE_JDAA             2453
-#define MNG_FN_FREE_EVNT             2454
-#define MNG_FN_FREE_MPNG             2455
-
-/* ************************************************************************** */
-
-#define MNG_FN_READ_IHDR             2601
-#define MNG_FN_READ_PLTE             2602
-#define MNG_FN_READ_IDAT             2603
-#define MNG_FN_READ_IEND             2604
-#define MNG_FN_READ_TRNS             2605
-#define MNG_FN_READ_GAMA             2606
-#define MNG_FN_READ_CHRM             2607
-#define MNG_FN_READ_SRGB             2608
-#define MNG_FN_READ_ICCP             2609
-#define MNG_FN_READ_TEXT             2610
-#define MNG_FN_READ_ZTXT             2611
-#define MNG_FN_READ_ITXT             2612
-#define MNG_FN_READ_BKGD             2613
-#define MNG_FN_READ_PHYS             2614
-#define MNG_FN_READ_SBIT             2615
-#define MNG_FN_READ_SPLT             2616
-#define MNG_FN_READ_HIST             2617
-#define MNG_FN_READ_TIME             2618
-#define MNG_FN_READ_MHDR             2619
-#define MNG_FN_READ_MEND             2620
-#define MNG_FN_READ_LOOP             2621
-#define MNG_FN_READ_ENDL             2622
-#define MNG_FN_READ_DEFI             2623
-#define MNG_FN_READ_BASI             2624
-#define MNG_FN_READ_CLON             2625
-#define MNG_FN_READ_PAST             2626
-#define MNG_FN_READ_DISC             2627
-#define MNG_FN_READ_BACK             2628
-#define MNG_FN_READ_FRAM             2629
-#define MNG_FN_READ_MOVE             2630
-#define MNG_FN_READ_CLIP             2631
-#define MNG_FN_READ_SHOW             2632
-#define MNG_FN_READ_TERM             2633
-#define MNG_FN_READ_SAVE             2634
-#define MNG_FN_READ_SEEK             2635
-#define MNG_FN_READ_EXPI             2636
-#define MNG_FN_READ_FPRI             2637
-#define MNG_FN_READ_NEED             2638
-#define MNG_FN_READ_PHYG             2639
-#define MNG_FN_READ_JHDR             2640
-#define MNG_FN_READ_JDAT             2641
-#define MNG_FN_READ_JSEP             2642
-#define MNG_FN_READ_DHDR             2643
-#define MNG_FN_READ_PROM             2644
-#define MNG_FN_READ_IPNG             2645
-#define MNG_FN_READ_PPLT             2646
-#define MNG_FN_READ_IJNG             2647
-#define MNG_FN_READ_DROP             2648
-#define MNG_FN_READ_DBYK             2649
-#define MNG_FN_READ_ORDR             2650
-#define MNG_FN_READ_UNKNOWN          2651
-#define MNG_FN_READ_MAGN             2652
-#define MNG_FN_READ_JDAA             2653
-#define MNG_FN_READ_EVNT             2654
-#define MNG_FN_READ_MPNG             2655
-
-/* ************************************************************************** */
-
-#define MNG_FN_WRITE_IHDR            2801
-#define MNG_FN_WRITE_PLTE            2802
-#define MNG_FN_WRITE_IDAT            2803
-#define MNG_FN_WRITE_IEND            2804
-#define MNG_FN_WRITE_TRNS            2805
-#define MNG_FN_WRITE_GAMA            2806
-#define MNG_FN_WRITE_CHRM            2807
-#define MNG_FN_WRITE_SRGB            2808
-#define MNG_FN_WRITE_ICCP            2809
-#define MNG_FN_WRITE_TEXT            2810
-#define MNG_FN_WRITE_ZTXT            2811
-#define MNG_FN_WRITE_ITXT            2812
-#define MNG_FN_WRITE_BKGD            2813
-#define MNG_FN_WRITE_PHYS            2814
-#define MNG_FN_WRITE_SBIT            2815
-#define MNG_FN_WRITE_SPLT            2816
-#define MNG_FN_WRITE_HIST            2817
-#define MNG_FN_WRITE_TIME            2818
-#define MNG_FN_WRITE_MHDR            2819
-#define MNG_FN_WRITE_MEND            2820
-#define MNG_FN_WRITE_LOOP            2821
-#define MNG_FN_WRITE_ENDL            2822
-#define MNG_FN_WRITE_DEFI            2823
-#define MNG_FN_WRITE_BASI            2824
-#define MNG_FN_WRITE_CLON            2825
-#define MNG_FN_WRITE_PAST            2826
-#define MNG_FN_WRITE_DISC            2827
-#define MNG_FN_WRITE_BACK            2828
-#define MNG_FN_WRITE_FRAM            2829
-#define MNG_FN_WRITE_MOVE            2830
-#define MNG_FN_WRITE_CLIP            2831
-#define MNG_FN_WRITE_SHOW            2832
-#define MNG_FN_WRITE_TERM            2833
-#define MNG_FN_WRITE_SAVE            2834
-#define MNG_FN_WRITE_SEEK            2835
-#define MNG_FN_WRITE_EXPI            2836
-#define MNG_FN_WRITE_FPRI            2837
-#define MNG_FN_WRITE_NEED            2838
-#define MNG_FN_WRITE_PHYG            2839
-#define MNG_FN_WRITE_JHDR            2840
-#define MNG_FN_WRITE_JDAT            2841
-#define MNG_FN_WRITE_JSEP            2842
-#define MNG_FN_WRITE_DHDR            2843
-#define MNG_FN_WRITE_PROM            2844
-#define MNG_FN_WRITE_IPNG            2845
-#define MNG_FN_WRITE_PPLT            2846
-#define MNG_FN_WRITE_IJNG            2847
-#define MNG_FN_WRITE_DROP            2848
-#define MNG_FN_WRITE_DBYK            2849
-#define MNG_FN_WRITE_ORDR            2850
-#define MNG_FN_WRITE_UNKNOWN         2851
-#define MNG_FN_WRITE_MAGN            2852
-#define MNG_FN_WRITE_JDAA            2853
-#define MNG_FN_WRITE_EVNT            2854
-#define MNG_FN_WRITE_MPNG            2855
-
-/* ************************************************************************** */
-
-#define MNG_FN_ZLIB_INITIALIZE       3001
-#define MNG_FN_ZLIB_CLEANUP          3002
-#define MNG_FN_ZLIB_INFLATEINIT      3003
-#define MNG_FN_ZLIB_INFLATEROWS      3004
-#define MNG_FN_ZLIB_INFLATEDATA      3005
-#define MNG_FN_ZLIB_INFLATEFREE      3006
-#define MNG_FN_ZLIB_DEFLATEINIT      3007
-#define MNG_FN_ZLIB_DEFLATEROWS      3008
-#define MNG_FN_ZLIB_DEFLATEDATA      3009
-#define MNG_FN_ZLIB_DEFLATEFREE      3010
-
-/* ************************************************************************** */
-
-#define MNG_FN_PROCESS_DISPLAY_IHDR  3201
-#define MNG_FN_PROCESS_DISPLAY_PLTE  3202
-#define MNG_FN_PROCESS_DISPLAY_IDAT  3203
-#define MNG_FN_PROCESS_DISPLAY_IEND  3204
-#define MNG_FN_PROCESS_DISPLAY_TRNS  3205
-#define MNG_FN_PROCESS_DISPLAY_GAMA  3206
-#define MNG_FN_PROCESS_DISPLAY_CHRM  3207
-#define MNG_FN_PROCESS_DISPLAY_SRGB  3208
-#define MNG_FN_PROCESS_DISPLAY_ICCP  3209
-#define MNG_FN_PROCESS_DISPLAY_BKGD  3210
-#define MNG_FN_PROCESS_DISPLAY_PHYS  3211
-#define MNG_FN_PROCESS_DISPLAY_SBIT  3212
-#define MNG_FN_PROCESS_DISPLAY_SPLT  3213
-#define MNG_FN_PROCESS_DISPLAY_HIST  3214
-#define MNG_FN_PROCESS_DISPLAY_MHDR  3215
-#define MNG_FN_PROCESS_DISPLAY_MEND  3216
-#define MNG_FN_PROCESS_DISPLAY_LOOP  3217
-#define MNG_FN_PROCESS_DISPLAY_ENDL  3218
-#define MNG_FN_PROCESS_DISPLAY_DEFI  3219
-#define MNG_FN_PROCESS_DISPLAY_BASI  3220
-#define MNG_FN_PROCESS_DISPLAY_CLON  3221
-#define MNG_FN_PROCESS_DISPLAY_PAST  3222
-#define MNG_FN_PROCESS_DISPLAY_DISC  3223
-#define MNG_FN_PROCESS_DISPLAY_BACK  3224
-#define MNG_FN_PROCESS_DISPLAY_FRAM  3225
-#define MNG_FN_PROCESS_DISPLAY_MOVE  3226
-#define MNG_FN_PROCESS_DISPLAY_CLIP  3227
-#define MNG_FN_PROCESS_DISPLAY_SHOW  3228
-#define MNG_FN_PROCESS_DISPLAY_TERM  3229
-#define MNG_FN_PROCESS_DISPLAY_SAVE  3230
-#define MNG_FN_PROCESS_DISPLAY_SEEK  3231
-#define MNG_FN_PROCESS_DISPLAY_EXPI  3232
-#define MNG_FN_PROCESS_DISPLAY_FPRI  3233
-#define MNG_FN_PROCESS_DISPLAY_NEED  3234
-#define MNG_FN_PROCESS_DISPLAY_PHYG  3235
-#define MNG_FN_PROCESS_DISPLAY_JHDR  3236
-#define MNG_FN_PROCESS_DISPLAY_JDAT  3237
-#define MNG_FN_PROCESS_DISPLAY_JSEP  3238
-#define MNG_FN_PROCESS_DISPLAY_DHDR  3239
-#define MNG_FN_PROCESS_DISPLAY_PROM  3240
-#define MNG_FN_PROCESS_DISPLAY_IPNG  3241
-#define MNG_FN_PROCESS_DISPLAY_PPLT  3242
-#define MNG_FN_PROCESS_DISPLAY_IJNG  3243
-#define MNG_FN_PROCESS_DISPLAY_DROP  3244
-#define MNG_FN_PROCESS_DISPLAY_DBYK  3245
-#define MNG_FN_PROCESS_DISPLAY_ORDR  3246
-#define MNG_FN_PROCESS_DISPLAY_MAGN  3247
-#define MNG_FN_PROCESS_DISPLAY_JDAA  3248
-
-/* ************************************************************************** */
-
-#define MNG_FN_JPEG_INITIALIZE       3401
-#define MNG_FN_JPEG_CLEANUP          3402
-#define MNG_FN_JPEG_DECOMPRESSINIT   3403
-#define MNG_FN_JPEG_DECOMPRESSDATA   3404
-#define MNG_FN_JPEG_DECOMPRESSFREE   3405
-
-#define MNG_FN_STORE_JPEG_G8         3501
-#define MNG_FN_STORE_JPEG_RGB8       3502
-#define MNG_FN_STORE_JPEG_G12        3503
-#define MNG_FN_STORE_JPEG_RGB12      3504
-#define MNG_FN_STORE_JPEG_GA8        3505
-#define MNG_FN_STORE_JPEG_RGBA8      3506
-#define MNG_FN_STORE_JPEG_GA12       3507
-#define MNG_FN_STORE_JPEG_RGBA12     3508
-#define MNG_FN_STORE_JPEG_G8_ALPHA   3509
-#define MNG_FN_STORE_JPEG_RGB8_ALPHA 3510
-
-#define MNG_FN_INIT_JPEG_A1_NI       3511
-#define MNG_FN_INIT_JPEG_A2_NI       3512
-#define MNG_FN_INIT_JPEG_A4_NI       3513
-#define MNG_FN_INIT_JPEG_A8_NI       3514
-#define MNG_FN_INIT_JPEG_A16_NI      3515
-
-#define MNG_FN_STORE_JPEG_G8_A1      3521
-#define MNG_FN_STORE_JPEG_G8_A2      3522
-#define MNG_FN_STORE_JPEG_G8_A4      3523
-#define MNG_FN_STORE_JPEG_G8_A8      3524
-#define MNG_FN_STORE_JPEG_G8_A16     3525
-
-#define MNG_FN_STORE_JPEG_RGB8_A1    3531
-#define MNG_FN_STORE_JPEG_RGB8_A2    3532
-#define MNG_FN_STORE_JPEG_RGB8_A4    3533
-#define MNG_FN_STORE_JPEG_RGB8_A8    3534
-#define MNG_FN_STORE_JPEG_RGB8_A16   3535
-
-#define MNG_FN_STORE_JPEG_G12_A1     3541
-#define MNG_FN_STORE_JPEG_G12_A2     3542
-#define MNG_FN_STORE_JPEG_G12_A4     3543
-#define MNG_FN_STORE_JPEG_G12_A8     3544
-#define MNG_FN_STORE_JPEG_G12_A16    3545
-
-#define MNG_FN_STORE_JPEG_RGB12_A1   3551
-#define MNG_FN_STORE_JPEG_RGB12_A2   3552
-#define MNG_FN_STORE_JPEG_RGB12_A4   3553
-#define MNG_FN_STORE_JPEG_RGB12_A8   3554
-#define MNG_FN_STORE_JPEG_RGB12_A16  3555
-
-#define MNG_FN_NEXT_JPEG_ALPHAROW    3591
-#define MNG_FN_NEXT_JPEG_ROW         3592
-#define MNG_FN_DISPLAY_JPEG_ROWS     3593
-
-/* ************************************************************************** */
-
-#define MNG_FN_MAGNIFY_G8_X1         3701
-#define MNG_FN_MAGNIFY_G8_X2         3702
-#define MNG_FN_MAGNIFY_RGB8_X1       3703
-#define MNG_FN_MAGNIFY_RGB8_X2       3704
-#define MNG_FN_MAGNIFY_GA8_X1        3705
-#define MNG_FN_MAGNIFY_GA8_X2        3706
-#define MNG_FN_MAGNIFY_GA8_X3        3707
-#define MNG_FN_MAGNIFY_GA8_X4        3708
-#define MNG_FN_MAGNIFY_RGBA8_X1      3709
-#define MNG_FN_MAGNIFY_RGBA8_X2      3710
-#define MNG_FN_MAGNIFY_RGBA8_X3      3711
-#define MNG_FN_MAGNIFY_RGBA8_X4      3712
-#define MNG_FN_MAGNIFY_G8_X3         3713
-#define MNG_FN_MAGNIFY_RGB8_X3       3714
-#define MNG_FN_MAGNIFY_GA8_X5        3715
-#define MNG_FN_MAGNIFY_RGBA8_X5      3716
-
-#define MNG_FN_MAGNIFY_G16_X1        3725
-#define MNG_FN_MAGNIFY_G16_X2        3726
-#define MNG_FN_MAGNIFY_RGB16_X1      3727
-#define MNG_FN_MAGNIFY_RGB16_X2      3728
-#define MNG_FN_MAGNIFY_GA16_X1       3729
-#define MNG_FN_MAGNIFY_GA16_X2       3730
-#define MNG_FN_MAGNIFY_GA16_X3       3731
-#define MNG_FN_MAGNIFY_GA16_X4       3732
-#define MNG_FN_MAGNIFY_RGBA16_X1     3733
-#define MNG_FN_MAGNIFY_RGBA16_X2     3734
-#define MNG_FN_MAGNIFY_RGBA16_X3     3735
-#define MNG_FN_MAGNIFY_RGBA16_X4     3736
-#define MNG_FN_MAGNIFY_G16_X3        3737
-#define MNG_FN_MAGNIFY_RGB16_X3      3738
-#define MNG_FN_MAGNIFY_GA16_X5       3739
-#define MNG_FN_MAGNIFY_RGBA16_X5     3740
-
-#define MNG_FN_MAGNIFY_G8_Y1         3751
-#define MNG_FN_MAGNIFY_G8_Y2         3752
-#define MNG_FN_MAGNIFY_RGB8_Y1       3753
-#define MNG_FN_MAGNIFY_RGB8_Y2       3754
-#define MNG_FN_MAGNIFY_GA8_Y1        3755
-#define MNG_FN_MAGNIFY_GA8_Y2        3756
-#define MNG_FN_MAGNIFY_GA8_Y3        3757
-#define MNG_FN_MAGNIFY_GA8_Y4        3758
-#define MNG_FN_MAGNIFY_RGBA8_Y1      3759
-#define MNG_FN_MAGNIFY_RGBA8_Y2      3760
-#define MNG_FN_MAGNIFY_RGBA8_Y3      3761
-#define MNG_FN_MAGNIFY_RGBA8_Y4      3762
-#define MNG_FN_MAGNIFY_G8_Y3         3763
-#define MNG_FN_MAGNIFY_RGB8_Y3       3764
-#define MNG_FN_MAGNIFY_GA8_Y5        3765
-#define MNG_FN_MAGNIFY_RGBA8_Y5      3766
-
-#define MNG_FN_MAGNIFY_G16_Y1        3775
-#define MNG_FN_MAGNIFY_G16_Y2        3776
-#define MNG_FN_MAGNIFY_RGB16_Y1      3777
-#define MNG_FN_MAGNIFY_RGB16_Y2      3778
-#define MNG_FN_MAGNIFY_GA16_Y1       3779
-#define MNG_FN_MAGNIFY_GA16_Y2       3780
-#define MNG_FN_MAGNIFY_GA16_Y3       3781
-#define MNG_FN_MAGNIFY_GA16_Y4       3782
-#define MNG_FN_MAGNIFY_RGBA16_Y1     3783
-#define MNG_FN_MAGNIFY_RGBA16_Y2     3784
-#define MNG_FN_MAGNIFY_RGBA16_Y3     3785
-#define MNG_FN_MAGNIFY_RGBA16_Y4     3786
-#define MNG_FN_MAGNIFY_G16_Y3        3787
-#define MNG_FN_MAGNIFY_RGB16_Y3      3788
-#define MNG_FN_MAGNIFY_GA16_Y5       3789
-#define MNG_FN_MAGNIFY_RGBA16_Y5     3790
-
-/* ************************************************************************** */
-
-#define MNG_FN_DELTA_G1_G1           3801
-#define MNG_FN_DELTA_G2_G2           3802
-#define MNG_FN_DELTA_G4_G4           3803
-#define MNG_FN_DELTA_G8_G8           3804
-#define MNG_FN_DELTA_G16_G16         3805
-#define MNG_FN_DELTA_RGB8_RGB8       3806
-#define MNG_FN_DELTA_RGB16_RGB16     3807
-#define MNG_FN_DELTA_GA8_GA8         3808
-#define MNG_FN_DELTA_GA8_G8          3809
-#define MNG_FN_DELTA_GA8_A8          3810
-#define MNG_FN_DELTA_GA16_GA16       3811
-#define MNG_FN_DELTA_GA16_G16        3812
-#define MNG_FN_DELTA_GA16_A16        3813
-#define MNG_FN_DELTA_RGBA8_RGBA8     3814
-#define MNG_FN_DELTA_RGBA8_RGB8      3815
-#define MNG_FN_DELTA_RGBA8_A8        3816
-#define MNG_FN_DELTA_RGBA16_RGBA16   3817
-#define MNG_FN_DELTA_RGBA16_RGB16    3818
-#define MNG_FN_DELTA_RGBA16_A16      3819
-
-#define MNG_FN_PROMOTE_G8_G8         3901
-#define MNG_FN_PROMOTE_G8_G16        3902
-#define MNG_FN_PROMOTE_G16_G16       3903
-#define MNG_FN_PROMOTE_G8_GA8        3904
-#define MNG_FN_PROMOTE_G8_GA16       3905
-#define MNG_FN_PROMOTE_G16_GA16      3906
-#define MNG_FN_PROMOTE_G8_RGB8       3907
-#define MNG_FN_PROMOTE_G8_RGB16      3908
-#define MNG_FN_PROMOTE_G16_RGB16     3909
-#define MNG_FN_PROMOTE_G8_RGBA8      3910
-#define MNG_FN_PROMOTE_G8_RGBA16     3911
-#define MNG_FN_PROMOTE_G16_RGBA16    3912
-#define MNG_FN_PROMOTE_GA8_GA16      3913
-#define MNG_FN_PROMOTE_GA8_RGBA8     3914
-#define MNG_FN_PROMOTE_GA8_RGBA16    3915
-#define MNG_FN_PROMOTE_GA16_RGBA16   3916
-#define MNG_FN_PROMOTE_RGB8_RGB16    3917
-#define MNG_FN_PROMOTE_RGB8_RGBA8    3918
-#define MNG_FN_PROMOTE_RGB8_RGBA16   3919
-#define MNG_FN_PROMOTE_RGB16_RGBA16  3920
-#define MNG_FN_PROMOTE_RGBA8_RGBA16  3921
-#define MNG_FN_PROMOTE_IDX8_RGB8     3922
-#define MNG_FN_PROMOTE_IDX8_RGB16    3923
-#define MNG_FN_PROMOTE_IDX8_RGBA8    3924
-#define MNG_FN_PROMOTE_IDX8_RGBA16   3925
-
-#define MNG_FN_SCALE_G1_G2           4001
-#define MNG_FN_SCALE_G1_G4           4002
-#define MNG_FN_SCALE_G1_G8           4003
-#define MNG_FN_SCALE_G1_G16          4004
-#define MNG_FN_SCALE_G2_G4           4005
-#define MNG_FN_SCALE_G2_G8           4006
-#define MNG_FN_SCALE_G2_G16          4007
-#define MNG_FN_SCALE_G4_G8           4008
-#define MNG_FN_SCALE_G4_G16          4009
-#define MNG_FN_SCALE_G8_G16          4010
-#define MNG_FN_SCALE_GA8_GA16        4011
-#define MNG_FN_SCALE_RGB8_RGB16      4012
-#define MNG_FN_SCALE_RGBA8_RGBA16    4013
-
-#define MNG_FN_SCALE_G2_G1           4021
-#define MNG_FN_SCALE_G4_G1           4022
-#define MNG_FN_SCALE_G8_G1           4023
-#define MNG_FN_SCALE_G16_G1          4024
-#define MNG_FN_SCALE_G4_G2           4025
-#define MNG_FN_SCALE_G8_G2           4026
-#define MNG_FN_SCALE_G16_G2          4027
-#define MNG_FN_SCALE_G8_G4           4028
-#define MNG_FN_SCALE_G16_G4          4029
-#define MNG_FN_SCALE_G16_G8          4030
-#define MNG_FN_SCALE_GA16_GA8        4031
-#define MNG_FN_SCALE_RGB16_RGB8      4032
-#define MNG_FN_SCALE_RGBA16_RGBA8    4033
-
-#define MNG_FN_COMPOSEOVER_RGBA8     4501
-#define MNG_FN_COMPOSEOVER_RGBA16    4502
-#define MNG_FN_COMPOSEUNDER_RGBA8    4503
-#define MNG_FN_COMPOSEUNDER_RGBA16   4504
-
-#define MNG_FN_FLIP_RGBA8            4521
-#define MNG_FN_FLIP_RGBA16           4522
-#define MNG_FN_TILE_RGBA8            4523
-#define MNG_FN_TILE_RGBA16           4524
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Trace string-table entry                                               * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-typedef struct {
-                 mng_uint32 iFunction;
-                 mng_pchar  zTracetext;
-               } mng_trace_entry;
-typedef mng_trace_entry const * mng_trace_entryp;
-
-/* ************************************************************************** */
-
-#endif /* MNG_INCLUDE_TRACE_PROCS */
-
-/* ************************************************************************** */
-
-#endif /* _libmng_trace_h_ */
-
-/* ************************************************************************** */
-/* * end of file                                                            * */
-/* ************************************************************************** */
-
diff --git a/Source/LibMNG/libmng_types.h b/Source/LibMNG/libmng_types.h
deleted file mode 100644
index 000a9a4..0000000
--- a/Source/LibMNG/libmng_types.h
+++ /dev/null
@@ -1,574 +0,0 @@
-/* ************************************************************************** */
-/* *             For conditions of distribution and use,                    * */
-/* *                see copyright notice in libmng.h                        * */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * project   : libmng                                                     * */
-/* * file      : libmng_types.h            copyright (c) 2000-2007 G.Juyn   * */
-/* * version   : 1.0.10                                                     * */
-/* *                                                                        * */
-/* * purpose   : type specifications                                        * */
-/* *                                                                        * */
-/* * author    : G.Juyn                                                     * */
-/* *                                                                        * */
-/* * comment   : Specification of the types used by the library             * */
-/* *             Creates platform-independant structure                     * */
-/* *                                                                        * */
-/* * changes   : 0.5.1 - 05/06/2000 - G.Juyn                                * */
-/* *             - added iteratechunk callback definition                   * */
-/* *             0.5.1 - 05/08/2000 - G.Juyn                                * */
-/* *             - improved definitions for DLL support                     * */
-/* *             - added 8-bit palette definition                           * */
-/* *             - added general array definitions                          * */
-/* *             - added MNG_NULL definition                                * */
-/* *             - changed strict-ANSI stuff                                * */
-/* *             0.5.1 - 05/11/2000 - G.Juyn                                * */
-/* *             - changed most callback prototypes to allow the app        * */
-/* *               to report errors during callback processing              * */
-/* *             0.5.1 - 05/16/2000 - G.Juyn                                * */
-/* *             - moved standard header includes into this file            * */
-/* *               (stdlib/mem for mem-mngmt & math for fp gamma-calc)      * */
-/* *                                                                        * */
-/* *             0.5.2 - 05/18/2000 - G.Juyn                                * */
-/* *             - B003 - fixed problem with <mem.h> being proprietary      * */
-/* *               to Borland platform                                      * */
-/* *             - added helper definitions for JNG (IJG-based)             * */
-/* *             - fixed support for IJGSRC6B                               * */
-/* *             0.5.2 - 05/24/2000 - G.Juyn                                * */
-/* *             - added default IJG compression parameters and such        * */
-/* *             0.5.2 - 05/31/2000 - G.Juyn                                * */
-/* *             - fixed inclusion for memcpy (contributed by Tim Rowley)   * */
-/* *             - added mng_int32p (contributed by Tim Rowley)             * */
-/* *             0.5.2 - 06/02/2000 - G.Juyn                                * */
-/* *             - removed SWAP_ENDIAN reference (contributed by Tim Rowley)* */
-/* *             - added getalphaline callback for RGB8_A8 canvasstyle      * */
-/* *                                                                        * */
-/* *             0.5.3 - 06/21/2000 - G.Juyn                                * */
-/* *             - added speedtype to facilitate testing                    * */
-/* *             0.5.3 - 06/27/2000 - G.Juyn                                * */
-/* *             - added typedef for mng_size_t                             * */
-/* *             - changed size parameter for memory callbacks to           * */
-/* *               mng_size_t                                               * */
-/* *             0.5.3 - 06/28/2000 - G.Juyn                                * */
-/* *             - changed definition of 32-bit ints (64-bit platforms)     * */
-/* *             - changed definition of mng_handle (64-bit platforms)      * */
-/* *             0.5.3 - 06/29/2000 - G.Juyn                                * */
-/* *             - changed definition of mng_handle (again)                 * */
-/* *             - swapped refresh parameters                               * */
-/* *             - added inclusion of stdlib.h for abs()                    * */
-/* *                                                                        * */
-/* *             0.9.0 - 06/30/2000 - G.Juyn                                * */
-/* *             - changed refresh parameters to 'x,y,width,height'         * */
-/* *             0.9.1 - 07/10/2000 - G.Juyn                                * */
-/* *             - added suspendbuffer constants                            * */
-/* *             0.9.1 - 07/15/2000 - G.Juyn                                * */
-/* *             - added callbacks for SAVE/SEEK processing                 * */
-/* *                                                                        * */
-/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
-/* *             - changed file-prefixes                                    * */
-/* *                                                                        * */
-/* *             0.9.3 - 08/07/2000 - G.Juyn                                * */
-/* *             - B111300 - fixup for improved portability                 * */
-/* *             0.9.3 - 08/12/2000 - G.Juyn                                * */
-/* *             - added workaround for faulty PhotoShop iCCP chunk         * */
-/* *             0.9.3 - 09/11/2000 - G.Juyn                                * */
-/* *             - added export of zlib functions from windows dll          * */
-/* *             - fixed inclusion parameters once again to make those      * */
-/* *               external libs work together                              * */
-/* *             - re-fixed fixed inclusion parameters                      * */
-/* *               (these freeking libraries make me mad)                   * */
-/* *             0.9.3 - 10/11/2000 - G.Juyn                                * */
-/* *             - added support for nEED                                   * */
-/* *             0.9.3 - 10/17/2000 - G.Juyn                                * */
-/* *             - added callback to process non-critical unknown chunks    * */
-/* *                                                                        * */
-/* *             0.9.4 - 11/20/2000 - R.Giles                               * */
-/* *             - fixed inclusion of lcms header for non-windows platforms * */
-/* *             0.9.4 - 12/12/2000 - G.Juyn                                * */
-/* *             - changed callback convention for MSVC (Thanks Chad)       * */
-/* *             0.9.4 - 12/16/2000 - G.Juyn                                * */
-/* *             - fixed mixup of data- & function-pointers (thanks Dimitri)* */
-/* *                                                                        * */
-/* *             1.0.1 - 02/08/2001 - G.Juyn                                * */
-/* *             - added MEND processing callback                           * */
-/* *                                                                        * */
-/* *             1.0.2 - 06/23/2001 - G.Juyn                                * */
-/* *             - added processterm callback                               * */
-/* *                                                                        * */
-/* *             1.0.3 - 08/06/2001 - G.Juyn                                * */
-/* *             - changed inclusion of lcms.h for Linux platforms          * */
-/* *                                                                        * */
-/* *             1.0.5 - 08/19/2002 - G.Juyn                                * */
-/* *             - B597134 - libmng pollutes the linker namespace           * */
-/* *                                                                        * */
-/* *             1.0.6 - 04/11/2003 - G.Juyn                                * */
-/* *             - B719420 - fixed several MNG_APP_CMS problems             * */
-/* *             1.0.6 - 06/15/2003 - R.Giles                               * */
-/* *             - lcms.h inclusion is generally no longer prefixed         * */
-/* *             1.0.6 - 07/07/2003 - G. R-P.                               * */
-/* *             - added png_imgtypes enumeration                           * */
-/* *                                                                        * */
-/* *             1.0.7 - 03/10/2004 - G.R-P                                 * */
-/* *             - added conditionals around openstream/closestream         * */
-/* *                                                                        * */
-/* *             1.0.8 - 04/11/2004 - G.Juyn                                * */
-/* *             - added data-push mechanisms for specialized decoders      * */
-/* *             1.0.8 - 08/01/2004 - G.Juyn                                * */
-/* *             - added support for 3+byte pixelsize for JPEG's            * */
-/* *                                                                        * */
-/* *             1.0.9 - 12/05/2004 - G.Juyn                                * */
-/* *             - inclusion of zlib/lcms/ijgsrc6b with <> instead of ""    * */
-/* *             1.0.9 - 12/06/2004 - G.Juyn                                * */
-/* *             - added conditional MNG_OPTIMIZE_CHUNKREADER               * */
-/* *                                                                        * */
-/* *             1.0.10 - 04/08/2007 - G.Juyn                               * */
-/* *             - added support for mPNG proposal                          * */
-/* *             1.0.10 - 04/12/2007 - G.Juyn                               * */
-/* *             - added support for ANG proposal                           * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifndef _libmng_types_h_
-#define _libmng_types_h_
-
-/* ************************************************************************** */
-
-#ifdef __BORLANDC__
-#pragma option -AT                     /* turn off strict ANSI-C for the moment */
-#endif
-
-#ifndef WIN32
-#if defined(_WIN32) || defined(__WIN32__) || defined(_Windows) || defined(_WINDOWS)
-#define WIN32                          /* gather them into a single define */
-#endif
-#endif
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Here's where the external & standard libs are embedded                 * */
-/* *                                                                        * */
-/* * (it can be a bit of a pain in the lower-back to get them to work       * */
-/* *  together)                                                             * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#ifdef WIN32                           /* only include needed stuff */
-#ifndef WIN32_LEAN_AND_MEAN
-#define WIN32_LEAN_AND_MEAN
-#endif
-#endif
-
-#ifdef MNG_USE_DLL
-#ifdef MNG_SKIP_ZLIB
-#undef MNG_INCLUDE_ZLIB
-#endif
-#ifdef MNG_SKIP_LCMS
-#undef MNG_INCLUDE_LCMS
-#endif
-#ifdef MNG_SKIP_IJG6B
-#undef MNG_INCLUDE_IJG6B
-#endif
-#endif
-
-#ifdef MNG_INCLUDE_ZLIB                /* zlib by Mark Adler & Jean-loup Gailly */
-#include <zlib.h>
-#endif
-
-#ifdef MNG_INCLUDE_LCMS                /* little cms by Marti Maria Saguer */
-#ifndef ZLIB_DLL
-#undef FAR
-#endif
-#include <lcms.h>
-#endif /* MNG_INCLUDE_LCMS */
-
-#ifdef MNG_INCLUDE_IJG6B               /* IJG's jpgsrc6b */
-#include <stdio.h>
-#ifdef MNG_USE_SETJMP
-#include <setjmp.h>                    /* needed for error-recovery (blergh) */
-#else
-#ifdef WIN32
-#define USE_WINDOWS_MESSAGEBOX         /* display a messagebox under Windoze */
-#endif
-#endif /* MNG_USE_SETJMP */
-#ifdef FAR
-#undef FAR                             /* possibly defined by zlib or lcms */
-#endif
-#define JPEG_INTERNAL_OPTIONS          /* for RGB_PIXELSIZE */
-#include "../LibJPEG/jpeglib.h"        /* all that for JPEG support  :-) */
-#endif /* MNG_INCLUDE_IJG6B */
-
-#if defined(MNG_INTERNAL_MEMMNGMT) || defined(MNG_INCLUDE_FILTERS)
-#include <stdlib.h>                    /* "calloc" & "free" & "abs" */
-#endif
-
-#include <limits.h>                    /* get proper integer widths */
-
-#ifdef WIN32
-#if defined __BORLANDC__
-#include <mem.h>                       /* defines "memcpy" for BCB */
-#else
-#include <memory.h>                    /* defines "memcpy" for other win32 platforms */
-#endif
-#include <string.h>                    /* "strncmp" + "strcmp" */
-#else /* WIN32 */
-#ifdef BSD
-#include <strings.h>                   /* defines "memcpy", etc for BSD (?) */
-#else
-#include <string.h>                    /* defines "memcpy", etc for all others (???) */
-#endif
-#endif /* WIN32 */
-
-#if defined(MNG_FULL_CMS) || defined(MNG_GAMMA_ONLY) || defined(MNG_APP_CMS)
-#include <math.h>                      /* fp gamma-calculation */
-#endif
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Platform-dependant stuff                                               * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-/* TODO: this may require some elaboration for other platforms;
-   only works with BCB for now */
-
-#ifndef MNG_DLL
-#if defined(MNG_BUILD_DLL) || defined(MNG_USE_DLL)
-#define MNG_DLL
-#endif
-#endif
-
-#define MNG_LOCAL static
-
-#if defined(MNG_DLL) && defined(WIN32) /* setup DLL calling conventions */ 
-#define MNG_DECL __stdcall
-#if defined(MNG_BUILD_DLL)
-#define MNG_EXT __declspec(dllexport)
-#elif defined(MNG_USE_DLL)
-#define MNG_EXT __declspec(dllimport)
-#else
-#define MNG_EXT
-#endif
-#ifdef MNG_STRICT_ANSI
-#undef MNG_STRICT_ANSI                 /* can't do strict-ANSI with this DLL-stuff */
-#endif
-#else
-#define MNG_DECL                       /* dummies for non-DLL */
-#define MNG_EXT
-#endif /* MNG_DLL && WIN32 */
-
-#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
-#pragma option -A                      /* now force ANSI-C from here on */
-#endif
-
-/* ************************************************************************** */
-
-#if USHRT_MAX == 0xffffffffU                     /* get the proper 32-bit width !!! */
-typedef unsigned short   mng_uint32;
-typedef signed   short   mng_int32;
-#elif UINT_MAX == 0xffffffffU
-typedef unsigned int     mng_uint32;
-typedef signed   int     mng_int32;
-#elif ULONG_MAX == 0xffffffffU
-typedef unsigned long    mng_uint32;
-typedef signed   long    mng_int32;
-#else
-#error "Sorry, I can't find any 32-bit integers on this platform."
-#endif
-
-typedef signed   short   mng_int16;              /* other basic integers */
-typedef unsigned short   mng_uint16;
-typedef signed   char    mng_int8;
-typedef unsigned char    mng_uint8;
-
-typedef double           mng_float;              /* basic float */
-
-typedef size_t           mng_size_t;             /* size field for memory allocation */
-
-typedef char *           mng_pchar;              /* string */
-typedef void *           mng_ptr;                /* generic pointer */
-typedef void             (*mng_fptr) (void);     /* generic function pointer */
-
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * Platform-independant from here                                         * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-typedef mng_uint32 *     mng_uint32p;            /* pointer to unsigned longs */
-typedef mng_int32 *      mng_int32p;             /* pointer to longs */
-typedef mng_uint16 *     mng_uint16p;            /* pointer to unsigned words */
-typedef mng_uint8 *      mng_uint8p;             /* pointer to unsigned bytes */
-
-typedef mng_int8         mng_bool;               /* booleans */
-
-struct mng_data_struct;
-typedef struct mng_data_struct * mng_handle;     /* generic handle */
-
-typedef mng_int32        mng_retcode;            /* generic return code */
-typedef mng_int32        mng_chunkid;            /* 4-byte chunkname identifier */
-typedef mng_ptr          mng_chunkp;             /* pointer to a chunk-structure */
-typedef mng_ptr          mng_objectp;            /* pointer to an object-structure */
-
-typedef mng_chunkid *    mng_chunkidp;           /* pointer to chunkid */
-
-typedef struct {                                 /* 8-bit palette element */
-          mng_uint8 iRed;
-          mng_uint8 iGreen;
-          mng_uint8 iBlue;
-        } mng_palette8e;
-typedef mng_palette8e   mng_palette8[256];       /* 8-bit palette */
-typedef mng_palette8e * mng_palette8ep;
-
-typedef mng_uint8       mng_uint8arr[256];       /* generic arrays */
-typedef mng_uint8       mng_uint8arr4[4];
-typedef mng_uint16      mng_uint16arr[256];
-typedef mng_uint32      mng_uint32arr2[2];
-
-/* ************************************************************************** */
-
-#define MNG_FALSE 0
-#define MNG_TRUE  1
-#define MNG_NULL  0
-
-#define MNG_SUSPENDBUFFERSIZE  32768
-#define MNG_SUSPENDREQUESTSIZE  1024
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_ZLIB
-
-/* size of temporary zlib buffer for deflate processing */
-#define MNG_ZLIB_MAXBUF     8192
-
-/* default zlib compression parameters for deflateinit2 */
-#define MNG_ZLIB_LEVEL      9                    /* level */
-#define MNG_ZLIB_METHOD     Z_DEFLATED           /* method */
-#define MNG_ZLIB_WINDOWBITS 15                   /* window size */
-#define MNG_ZLIB_MEMLEVEL   9                    /* memory level */
-#define MNG_ZLIB_STRATEGY   Z_DEFAULT_STRATEGY   /* strategy */
-
-#define MNG_MAX_IDAT_SIZE   4096                 /* maximum size of IDAT data */
-
-#endif /* MNG_INCLUDE_ZLIB */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_JNG
-
-#ifdef MNG_INCLUDE_IJG6B                         /* IJG helper defs */
-typedef struct jpeg_compress_struct   mngjpeg_comp;
-typedef struct jpeg_decompress_struct mngjpeg_decomp;
-typedef struct jpeg_error_mgr         mngjpeg_error;
-typedef struct jpeg_source_mgr        mngjpeg_source;
-
-typedef mngjpeg_comp   * mngjpeg_compp;
-typedef mngjpeg_decomp * mngjpeg_decompp;
-typedef mngjpeg_error  * mngjpeg_errorp;
-typedef mngjpeg_source * mngjpeg_sourcep;
-
-typedef J_DCT_METHOD     mngjpeg_dctmethod;
-
-/* default IJG parameters for compression */
-#define MNG_JPEG_DCT         JDCT_DEFAULT        /* DCT algorithm (JDCT_ISLOW) */
-#define MNG_JPEG_QUALITY     100                 /* quality 0..100; 100=best */
-#define MNG_JPEG_SMOOTHING   0                   /* default no smoothing */
-#define MNG_JPEG_PROGRESSIVE MNG_FALSE           /* default is just baseline */
-#define MNG_JPEG_OPTIMIZED   MNG_FALSE           /* default is not optimized */
-#endif /* MNG_INCLUDE_IJG6B */
-
-#define MNG_JPEG_MAXBUF      65500               /* max size of temp JPEG buffer */
-#define MNG_MAX_JDAT_SIZE    4096                /* maximum size of JDAT data */
-
-#endif /* MNG_INCLUDE_JNG */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_LCMS
-typedef cmsHPROFILE         mng_cmsprof;         /* little CMS helper defs */
-typedef cmsHTRANSFORM       mng_cmstrans;
-typedef cmsCIExyY           mng_CIExyY;
-typedef cmsCIExyYTRIPLE     mng_CIExyYTRIPLE;
-typedef LPGAMMATABLE        mng_gammatabp;
-#endif /* MNG_INCLUDE_LCMS */
-
-/* ************************************************************************** */
-
-                                       /* enumeration of known graphics types */
-enum mng_imgtypes {mng_it_unknown, mng_it_png, mng_it_mng, mng_it_jng
-#ifdef MNG_INCLUDE_MPNG_PROPOSAL
-     ,mng_it_mpng
-#endif     
-#ifdef MNG_INCLUDE_ANG_PROPOSAL
-     ,mng_it_ang
-#endif
-     };
-typedef enum mng_imgtypes mng_imgtype;
-
-                                       /* enumeration of animation speed-types */
-enum mng_speedtypes {mng_st_normal, mng_st_fast, mng_st_slow, mng_st_slowest};
-typedef enum mng_speedtypes mng_speedtype;
-
-#ifdef MNG_OPTIMIZE_CHUNKREADER
-                                       /* enumeration object-creation indicators */
-enum mng_createobjtypes {mng_create_none, mng_create_always, mng_create_ifglobal};
-typedef enum mng_createobjtypes mng_createobjtype;
-#endif
-
-/* ************************************************************************** */
-
-/* enumeration of PNG image types */
-#ifdef MNG_OPTIMIZE_FOOTPRINT_INIT
-enum png_imgtypes
-  {
-    png_g1,
-    png_g2,
-    png_g4,
-    png_g8,
-    png_rgb8,
-    png_idx1,
-    png_idx2,
-    png_idx4,
-    png_idx8,
-    png_ga8,
-    png_rgba8,
-#ifdef MNG_INCLUDE_JNG
-    png_jpeg_a1,
-    png_jpeg_a2,
-    png_jpeg_a4,
-    png_jpeg_a8,
-#endif
-#ifndef MNG_NO_16BIT_SUPPORT
-    png_g16,
-    png_ga16,
-    png_rgb16,
-    png_rgba16,
-#ifdef MNG_INCLUDE_JNG
-    png_jpeg_a16,
-#endif
-#endif
-    png_none
-  };
-    
-typedef enum png_imgtypes png_imgtype;
-#endif
-/* ************************************************************************** */
-
-                                       /* memory management callbacks */
-typedef mng_ptr    (MNG_DECL *mng_memalloc)      (mng_size_t  iLen);
-typedef void       (MNG_DECL *mng_memfree)       (mng_ptr     iPtr,
-                                                  mng_size_t  iLen);
-
-typedef void       (MNG_DECL *mng_releasedata)   (mng_ptr     pUserdata,
-                                                  mng_ptr     pData,
-                                                  mng_size_t  iLength);
-
-                                       /* I/O management callbacks */
-#ifndef MNG_NO_OPEN_CLOSE_STREAM
-typedef mng_bool   (MNG_DECL *mng_openstream)    (mng_handle  hHandle);
-typedef mng_bool   (MNG_DECL *mng_closestream)   (mng_handle  hHandle);
-#endif
-typedef mng_bool   (MNG_DECL *mng_readdata)      (mng_handle  hHandle,
-                                                  mng_ptr     pBuf,
-                                                  mng_uint32  iBuflen,
-                                                  mng_uint32p pRead);
-typedef mng_bool   (MNG_DECL *mng_writedata)     (mng_handle  hHandle,
-                                                  mng_ptr     pBuf,
-                                                  mng_uint32  iBuflen,
-                                                  mng_uint32p pWritten);
-
-                                       /* error & trace processing callbacks */
-typedef mng_bool   (MNG_DECL *mng_errorproc)     (mng_handle  hHandle,
-                                                  mng_int32   iErrorcode,
-                                                  mng_int8    iSeverity,
-                                                  mng_chunkid iChunkname,
-                                                  mng_uint32  iChunkseq,
-                                                  mng_int32   iExtra1,
-                                                  mng_int32   iExtra2,
-                                                  mng_pchar   zErrortext);
-typedef mng_bool   (MNG_DECL *mng_traceproc)     (mng_handle  hHandle,
-                                                  mng_int32   iFuncnr,
-                                                  mng_int32   iFuncseq,
-                                                  mng_pchar   zFuncname);
-
-                                       /* read processing callbacks */
-typedef mng_bool   (MNG_DECL *mng_processheader) (mng_handle  hHandle,
-                                                  mng_uint32  iWidth,
-                                                  mng_uint32  iHeight);
-typedef mng_bool   (MNG_DECL *mng_processtext)   (mng_handle  hHandle,
-                                                  mng_uint8   iType,
-                                                  mng_pchar   zKeyword,
-                                                  mng_pchar   zText,
-                                                  mng_pchar   zLanguage,
-                                                  mng_pchar   zTranslation);
-typedef mng_bool   (MNG_DECL *mng_processsave)   (mng_handle  hHandle);
-typedef mng_bool   (MNG_DECL *mng_processseek)   (mng_handle  hHandle,
-                                                  mng_pchar   zName);
-typedef mng_bool   (MNG_DECL *mng_processneed)   (mng_handle  hHandle,
-                                                  mng_pchar   zKeyword);
-typedef mng_bool   (MNG_DECL *mng_processmend)   (mng_handle  hHandle,
-                                                  mng_uint32  iIterationsdone,
-                                                  mng_uint32  iIterationsleft);
-typedef mng_bool   (MNG_DECL *mng_processunknown) (mng_handle  hHandle,
-                                                   mng_chunkid iChunkid,
-                                                   mng_uint32  iRawlen,
-                                                   mng_ptr     pRawdata);
-typedef mng_bool   (MNG_DECL *mng_processterm)   (mng_handle  hHandle,
-                                                  mng_uint8   iTermaction,
-                                                  mng_uint8   iIteraction,
-                                                  mng_uint32  iDelay,
-                                                  mng_uint32  iItermax);
-
-                                       /* display processing callbacks */
-typedef mng_ptr    (MNG_DECL *mng_getcanvasline) (mng_handle  hHandle,
-                                                  mng_uint32  iLinenr);
-typedef mng_ptr    (MNG_DECL *mng_getbkgdline)   (mng_handle  hHandle,
-                                                  mng_uint32  iLinenr);
-typedef mng_ptr    (MNG_DECL *mng_getalphaline)  (mng_handle  hHandle,
-                                                  mng_uint32  iLinenr);
-typedef mng_bool   (MNG_DECL *mng_refresh)       (mng_handle  hHandle,
-                                                  mng_uint32  iX,
-                                                  mng_uint32  iY,
-                                                  mng_uint32  iWidth,
-                                                  mng_uint32  iHeight);
-
-                                       /* timer management callbacks */
-typedef mng_uint32 (MNG_DECL *mng_gettickcount)  (mng_handle  hHandle);
-typedef mng_bool   (MNG_DECL *mng_settimer)      (mng_handle  hHandle,
-                                                  mng_uint32  iMsecs);
-
-                                       /* color management callbacks */
-typedef mng_bool   (MNG_DECL *mng_processgamma)  (mng_handle  hHandle,
-                                                  mng_uint32  iGamma);
-typedef mng_bool   (MNG_DECL *mng_processchroma) (mng_handle  hHandle,
-                                                  mng_uint32  iWhitepointx,
-                                                  mng_uint32  iWhitepointy,
-                                                  mng_uint32  iRedx,
-                                                  mng_uint32  iRedy,
-                                                  mng_uint32  iGreenx,
-                                                  mng_uint32  iGreeny,
-                                                  mng_uint32  iBluex,
-                                                  mng_uint32  iBluey);
-typedef mng_bool   (MNG_DECL *mng_processsrgb)   (mng_handle  hHandle,
-                                                  mng_uint8   iRenderingintent);
-typedef mng_bool   (MNG_DECL *mng_processiccp)   (mng_handle  hHandle,
-                                                  mng_uint32  iProfilesize,
-                                                  mng_ptr     pProfile);
-typedef mng_bool   (MNG_DECL *mng_processarow)   (mng_handle  hHandle,
-                                                  mng_uint32  iRowsamples,
-                                                  mng_bool    bIsRGBA16,
-                                                  mng_ptr     pRow);
-
-                                       /* chunk access callback(s) */
-typedef mng_bool   (MNG_DECL *mng_iteratechunk)  (mng_handle  hHandle,
-                                                  mng_handle  hChunk,
-                                                  mng_chunkid iChunkid,
-                                                  mng_uint32  iChunkseq);
-
-/* ************************************************************************** */
-
-#endif /* _libmng_types_h_ */
-
-/* ************************************************************************** */
-/* * end of file                                                            * */
-/* ************************************************************************** */
-
diff --git a/Source/LibMNG/libmng_write.c b/Source/LibMNG/libmng_write.c
deleted file mode 100644
index 22ed3a0..0000000
--- a/Source/LibMNG/libmng_write.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/* ************************************************************************** */
-/* *             For conditions of distribution and use,                    * */
-/* *                see copyright notice in libmng.h                        * */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * project   : libmng                                                     * */
-/* * file      : libmng_write.c            copyright (c) 2000-2004 G.Juyn   * */
-/* * version   : 1.0.9                                                      * */
-/* *                                                                        * */
-/* * purpose   : Write management (implementation)                          * */
-/* *                                                                        * */
-/* * author    : G.Juyn                                                     * */
-/* *                                                                        * */
-/* * comment   : implementation of the write management routines            * */
-/* *                                                                        * */
-/* * changes   : 0.5.1 - 05/08/2000 - G.Juyn                                * */
-/* *             - changed strict-ANSI stuff                                * */
-/* *             0.5.1 - 05/12/2000 - G.Juyn                                * */
-/* *             - changed trace to macro for callback error-reporting      * */
-/* *             0.5.1 - 05/16/2000 - G.Juyn                                * */
-/* *             - moved the actual write_graphic functionality from        * */
-/* *               mng_hlapi to its appropriate function here               * */
-/* *                                                                        * */
-/* *             0.9.1 - 07/19/2000 - G.Juyn                                * */
-/* *             - fixed writing of signature                               * */
-/* *                                                                        * */
-/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
-/* *             - changed file-prefixes                                    * */
-/* *                                                                        * */
-/* *             1.0.5 - 08/19/2002 - G.Juyn                                * */
-/* *             - B597134 - libmng pollutes the linker namespace           * */
-/* *                                                                        * */
-/* *             1.0.8 - 07/06/2004 - G.R-P                                 * */
-/* *             - added conditionals around openstream/closestream         * */
-/* *             - defend against using undefined Open/Closestream function * */
-/* *             1.0.8 - 08/02/2004 - G.Juyn                                * */
-/* *             - added conditional to allow easier writing of large MNG's * */
-/* *                                                                        * */
-/* *             1.0.9 - 09/25/2004 - G.Juyn                                * */
-/* *             - replaced MNG_TWEAK_LARGE_FILES with permanent solution   * */
-/* *             1.0.9 - 12/20/2004 - G.Juyn                                * */
-/* *             - cleaned up macro-invocations (thanks to D. Airlie)       * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#include "libmng.h"
-#include "libmng_data.h"
-#include "libmng_error.h"
-#include "libmng_trace.h"
-#ifdef __BORLANDC__
-#pragma hdrstop
-#endif
-#include "libmng_memory.h"
-#include "libmng_chunks.h"
-#include "libmng_chunk_io.h"
-#include "libmng_write.h"
-
-#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
-#pragma option -A                      /* force ANSI-C */
-#endif
-
-/* ************************************************************************** */
-
-#if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
-mng_retcode mng_drop_chunks (mng_datap pData)
-{
-  mng_chunkp       pChunk;
-  mng_chunkp       pNext;
-  mng_cleanupchunk fCleanup;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DROP_CHUNKS, MNG_LC_START);
-#endif
-
-  pChunk = pData->pFirstchunk;         /* and get first stored chunk (if any) */
-
-  while (pChunk)                       /* more chunks to discard ? */
-  {
-    pNext = ((mng_chunk_headerp)pChunk)->pNext;
-                                       /* call appropriate cleanup */
-    fCleanup = ((mng_chunk_headerp)pChunk)->fCleanup;
-    fCleanup (pData, pChunk);
-
-    pChunk = pNext;                    /* neeeext */
-  }
-
-  pData->pFirstchunk = MNG_NULL;
-  pData->pLastchunk  = MNG_NULL;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_DROP_CHUNKS, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_READ || MNG_SUPPORT_WRITE */
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_WRITE_PROCS
-
-/* ************************************************************************** */
-
-mng_retcode mng_write_graphic (mng_datap pData)
-{
-  mng_chunkp  pChunk;
-  mng_retcode iRetcode;
-  mng_uint32  iWritten;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_GRAPHIC, MNG_LC_START);
-#endif
-
-  pChunk = pData->pFirstchunk;         /* we'll start with the first, thank you */
-
-  if (pChunk)                          /* is there anything to write ? */
-  {                                    /* open the file */
-    if (!pData->bWriting)
-    {
-#ifndef MNG_NO_OPEN_CLOSE_STREAM
-      if (pData->fOpenstream && !pData->fOpenstream ((mng_handle)pData))
-        MNG_ERROR (pData, MNG_APPIOERROR);
-#endif
-      {
-        pData->bWriting      = MNG_TRUE; /* indicate writing */
-        pData->iWritebufsize = 32768;    /* get a temporary write buffer */
-                                       /* reserve 12 bytes for length, chunkname & crc */
-        MNG_ALLOC (pData, pData->pWritebuf, pData->iWritebufsize+12);
-
-                                       /* write the signature */
-        if (((mng_chunk_headerp)pChunk)->iChunkname == MNG_UINT_IHDR)
-          mng_put_uint32 (pData->pWritebuf, PNG_SIG);
-        else
-        if (((mng_chunk_headerp)pChunk)->iChunkname == MNG_UINT_JHDR)
-          mng_put_uint32 (pData->pWritebuf, JNG_SIG);
-        else
-          mng_put_uint32 (pData->pWritebuf, MNG_SIG);
-
-        mng_put_uint32 (pData->pWritebuf+4, POST_SIG);
-
-        if (!pData->fWritedata ((mng_handle)pData, pData->pWritebuf, 8, &iWritten))
-        {
-          MNG_FREE (pData, pData->pWritebuf, pData->iWritebufsize+12);
-          MNG_ERROR (pData, MNG_APPIOERROR);
-        }
-
-        if (iWritten != 8)             /* disk full ? */
-        {
-          MNG_FREE (pData, pData->pWritebuf, pData->iWritebufsize+12);
-          MNG_ERROR (pData, MNG_OUTPUTERROR);
-        }
-      }
-    }
-
-    while (pChunk)                     /* so long as there's something to write */
-    {                                  /* let's call its output routine */
-      iRetcode = ((mng_chunk_headerp)pChunk)->fWrite (pData, pChunk);
-      if (iRetcode)                    /* on error bail out */
-        return iRetcode;
-                                       /* neeeext */
-      pChunk = ((mng_chunk_headerp)pChunk)->pNext;
-    }
-
-    if (!pData->bCreating)
-    {                                  /* free the temporary buffer */
-      MNG_FREE (pData, pData->pWritebuf, pData->iWritebufsize+12);
-
-      pData->bWriting = MNG_FALSE;     /* done writing */
-                                       /* close the stream now */
-#ifndef MNG_NO_OPEN_CLOSE_STREAM
-      if (pData->fClosestream && !pData->fClosestream ((mng_handle)pData))
-        MNG_ERROR (pData, MNG_APPIOERROR);
-#endif
-
-    } else {
-                                       /* cleanup the written chunks */
-      iRetcode = mng_drop_chunks (pData);
-      if (iRetcode)                    /* on error bail out */
-        return iRetcode;
-    }
-  }
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_WRITE_GRAPHIC, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-#endif /* MNG_INCLUDE_WRITE_PROCS */
-
-/* ************************************************************************** */
-/* * end of file                                                            * */
-/* ************************************************************************** */
-
-
diff --git a/Source/LibMNG/libmng_write.h b/Source/LibMNG/libmng_write.h
deleted file mode 100644
index df058fb..0000000
--- a/Source/LibMNG/libmng_write.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* ************************************************************************** */
-/* *             For conditions of distribution and use,                    * */
-/* *                see copyright notice in libmng.h                        * */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * project   : libmng                                                     * */
-/* * file      : libmng_write.h            copyright (c) 2000-2004 G.Juyn   * */
-/* * version   : 1.0.9                                                      * */
-/* *                                                                        * */
-/* * purpose   : Write management (definition)                              * */
-/* *                                                                        * */
-/* * author    : G.Juyn                                                     * */
-/* *                                                                        * */
-/* * comment   : Definition of the write management routines                * */
-/* *                                                                        * */
-/* * changes   : 0.5.1 - 05/08/2000 - G.Juyn                                * */
-/* *             - changed strict-ANSI stuff                                * */
-/* *                                                                        * */
-/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
-/* *             - changed file-prefixes                                    * */
-/* *                                                                        * */
-/* *             1.0.5 - 08/19/2002 - G.Juyn                                * */
-/* *             - B597134 - libmng pollutes the linker namespace           * */
-/* *                                                                        * */
-/* *             1.0.9 - 09/25/2004 - G.Juyn                                * */
-/* *             - replaced MNG_TWEAK_LARGE_FILES with permanent solution   * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
-#pragma option -A                      /* force ANSI-C */
-#endif
-
-#ifndef _libmng_write_h_
-#define _libmng_write_h_
-
-/* ************************************************************************** */
-
-mng_retcode mng_drop_chunks   (mng_datap pData);
-
-mng_retcode mng_write_graphic (mng_datap pData);
-
-/* ************************************************************************** */
-
-#endif /* _libmng_write_h_ */
-
-/* ************************************************************************** */
-/* * end of file                                                            * */
-/* ************************************************************************** */
diff --git a/Source/LibMNG/libmng_zlib.c b/Source/LibMNG/libmng_zlib.c
deleted file mode 100644
index 894bc74..0000000
--- a/Source/LibMNG/libmng_zlib.c
+++ /dev/null
@@ -1,607 +0,0 @@
-/* ************************************************************************** */
-/* *             For conditions of distribution and use,                    * */
-/* *                see copyright notice in libmng.h                        * */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * project   : libmng                                                     * */
-/* * file      : libmng_zlib.c             copyright (c) 2000-2004 G.Juyn   * */
-/* * version   : 1.0.9                                                      * */
-/* *                                                                        * */
-/* * purpose   : ZLIB library interface (implementation)                    * */
-/* *                                                                        * */
-/* * author    : G.Juyn                                                     * */
-/* *                                                                        * */
-/* * comment   : implementation of the ZLIB library interface               * */
-/* *                                                                        * */
-/* * changes   : 0.5.1 - 05/08/2000 - G.Juyn                                * */
-/* *             - changed strict-ANSI stuff                                * */
-/* *             0.5.1 - 05/11/2000 - G.Juyn                                * */
-/* *             - filled the deflatedata routine                           * */
-/* *             0.5.1 - 05/12/2000 - G.Juyn                                * */
-/* *             - changed trace to macro for callback error-reporting      * */
-/* *                                                                        * */
-/* *             0.5.2 - 05/20/2000 - G.Juyn                                * */
-/* *             - fixed for JNG alpha handling                             * */
-/* *             0.5.2 - 05/24/2000 - G.Juyn                                * */
-/* *             - moved init of default zlib parms from here to            * */
-/* *               "mng_hlapi.c"                                            * */
-/* *                                                                        * */
-/* *             0.5.3 - 06/16/2000 - G.Juyn                                * */
-/* *             - changed progressive-display processing                   * */
-/* *                                                                        * */
-/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
-/* *             - changed file-prefixes                                    * */
-/* *                                                                        * */
-/* *             0.9.3 - 08/08/2000 - G.Juyn                                * */
-/* *             - fixed compiler-warnings from Mozilla                     * */
-/* *             0.9.3 - 09/07/2000 - G.Juyn                                * */
-/* *             - added support for new filter_types                       * */
-/* *                                                                        * */
-/* *             1.0.5 - 08/07/2002 - G.Juyn                                * */
-/* *             - added test-option for PNG filter method 193 (=no filter) * */
-/* *             1.0.5 - 08/19/2002 - G.Juyn                                * */
-/* *             - B597134 - libmng pollutes the linker namespace           * */
-/* *             1.0.5 - 09/19/2002 - G.Juyn                                * */
-/* *             - added warning for too much IDAT data                     * */
-/* *                                                                        * */
-/* *             1.0.6 - 07/07/2003 - G.R-P                                 * */
-/* *             - added MNG_NO_16BIT_SUPPORT support                       * */
-/* *                                                                        * */
-/* *             1.0.9 - 10/09/2004 - G.R-P                                 * */
-/* *             - added MNG_NO_1_2_4BIT_SUPPORT support                    * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#include "libmng.h"
-#include "libmng_data.h"
-#include "libmng_error.h"
-#include "libmng_trace.h"
-#ifdef __BORLANDC__
-#pragma hdrstop
-#endif
-#include "libmng_memory.h"
-#include "libmng_pixels.h"
-#include "libmng_filter.h"
-#include "libmng_zlib.h"
-
-#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
-#pragma option -A                      /* force ANSI-C */
-#endif
-
-/* ************************************************************************** */
-
-#ifdef MNG_INCLUDE_ZLIB
-
-/* ************************************************************************** */
-
-voidpf mngzlib_alloc (voidpf pData,
-                      uInt   iCount,
-                      uInt   iSize)
-{
-  voidpf pPtr;                         /* temporary space */
-
-#ifdef MNG_INTERNAL_MEMMNGMT
-  pPtr = calloc (iCount, iSize);       /* local allocation */
-#else
-  if (((mng_datap)pData)->fMemalloc)   /* callback function set ? */
-    pPtr = ((mng_datap)pData)->fMemalloc (iCount * iSize);
-  else
-    pPtr = Z_NULL;                     /* can't allocate! */
-#endif
-
-  return pPtr;                         /* return the result */
-}
-
-/* ************************************************************************** */
-
-void mngzlib_free (voidpf pData,
-                   voidpf pAddress)
-{
-#ifdef MNG_INTERNAL_MEMMNGMT
-  free (pAddress);                     /* free locally */
-#else
-  if (((mng_datap)pData)->fMemfree)    /* callback set? */
-    ((mng_datap)pData)->fMemfree (pAddress, 1);
-#endif
-}
-
-/* ************************************************************************** */
-
-mng_retcode mngzlib_initialize (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ZLIB_INITIALIZE, MNG_LC_START);
-#endif
-
-#ifdef MNG_INTERNAL_MEMMNGMT
-  pData->sZlib.zalloc = Z_NULL;        /* let zlib figure out memory management */
-  pData->sZlib.zfree  = Z_NULL;
-  pData->sZlib.opaque = Z_NULL;
-#else                                  /* use user-provided callbacks */
-  pData->sZlib.zalloc = mngzlib_alloc;
-  pData->sZlib.zfree  = mngzlib_free;
-  pData->sZlib.opaque = (voidpf)pData;
-#endif
-
-  pData->bInflating   = MNG_FALSE;     /* not performing any action yet */
-  pData->bDeflating   = MNG_FALSE;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ZLIB_INITIALIZE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-
-/* ************************************************************************** */
-
-mng_retcode mngzlib_cleanup (mng_datap pData)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ZLIB_CLEANUP, MNG_LC_START);
-#endif
-
-  if (pData->bInflating)               /* force zlib cleanup */
-    mngzlib_inflatefree (pData);
-  if (pData->bDeflating)
-    mngzlib_deflatefree (pData);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ZLIB_CLEANUP, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-
-/* ************************************************************************** */
-
-mng_retcode mngzlib_inflateinit (mng_datap pData)
-{
-  int iZrslt;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ZLIB_INFLATEINIT, MNG_LC_START);
-#endif
-                                       /* initialize zlib structures and such */
-  iZrslt = inflateInit (&pData->sZlib);
-
-  if (iZrslt != Z_OK)                  /* on error bail out */
-    MNG_ERRORZ (pData, (mng_uint32)iZrslt);
-
-  pData->bInflating      = MNG_TRUE;   /* really inflating something now */
-  pData->sZlib.next_out  = 0;          /* force JIT initialization */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ZLIB_INFLATEINIT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-
-/* ************************************************************************** */
-
-#ifdef MNG_SUPPORT_DISPLAY
-mng_retcode mngzlib_inflaterows (mng_datap  pData,
-                                 mng_uint32 iInlen,
-                                 mng_uint8p pIndata)
-{
-  int         iZrslt;
-  mng_retcode iRslt;
-  mng_ptr     pSwap;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ZLIB_INFLATEROWS, MNG_LC_START);
-#endif
-
-  pData->sZlib.next_in   = pIndata;    /* let zlib know where to get stuff */
-  pData->sZlib.avail_in  = (uInt)iInlen;
-
-  if (pData->sZlib.next_out == 0)      /* initialize output variables ? */
-  {                                    /* let zlib know where to store stuff */
-    pData->sZlib.next_out  = pData->pWorkrow;
-    pData->sZlib.avail_out = (uInt)(pData->iRowsize + pData->iPixelofs);
-#ifdef MNG_NO_1_2_4BIT_SUPPORT
-    if (pData->iPNGdepth < 8)
-       pData->sZlib.avail_out = (uInt)((pData->iPNGdepth*pData->iRowsize + 7)/8
-           + pData->iPixelofs);
-#endif
-#ifdef MNG_NO_16BIT_SUPPORT
-    if (pData->iPNGdepth > 8)
-       pData->sZlib.avail_out = (uInt)(2*pData->iRowsize + pData->iPixelofs);
-#endif
-  }
-
-  do
-  {                                    /* now inflate a row */
-    iZrslt = inflate (&pData->sZlib, Z_SYNC_FLUSH);
-                                       /* produced a full row ? */
-    if (((iZrslt == Z_OK) || (iZrslt == Z_STREAM_END)) &&
-        (pData->sZlib.avail_out == 0))
-    {                                  /* image not completed yet ? */
-      if (pData->iRow < (mng_int32)pData->iDataheight)
-      {
-#ifdef MNG_NO_1_2_4BIT_SUPPORT
-        if (pData->iPNGdepth == 1)
-        {
-          /* Inflate Workrow to 8-bit */
-          mng_int32  iX;
-          mng_uint8p pSrc = pData->pWorkrow+1;
-          mng_uint8p pDest = pSrc + pData->iRowsize - (pData->iRowsize+7)/8;
-
-          for (iX = ((pData->iRowsize+7)/8) ; iX > 0 ; iX--)
-             *pDest++ = *pSrc++;
-
-          pDest = pData->pWorkrow+1;
-          pSrc = pDest + pData->iRowsize - (pData->iRowsize+7)/8;
-          for (iX = pData->iRowsize; ;)
-          {
-            *pDest++ = (((*pSrc)>>7)&1);
-            if (iX-- <= 0)
-              break;
-            *pDest++ = (((*pSrc)>>6)&1);
-            if (iX-- <= 0)
-              break;
-            *pDest++ = (((*pSrc)>>5)&1);
-            if (iX-- <= 0)
-              break;
-            *pDest++ = (((*pSrc)>>4)&1);
-            if (iX-- <= 0)
-              break;
-            *pDest++ = (((*pSrc)>>3)&1);
-            if (iX-- <= 0)
-              break;
-            *pDest++ = (((*pSrc)>>2)&1);
-            if (iX-- <= 0)
-              break;
-            *pDest++ = (((*pSrc)>>1)&1);
-            if (iX-- <= 0)
-              break;
-            *pDest++ = (((*pSrc)   )&1);
-            if (iX-- <= 0)
-              break;
-            pSrc++;
-          }
-        }
-        else if (pData->iPNGdepth == 2)
-        {
-          /* Inflate Workrow to 8-bit */
-          mng_int32  iX;
-          mng_uint8p pSrc = pData->pWorkrow+1;
-          mng_uint8p pDest = pSrc + pData->iRowsize - (2*pData->iRowsize+7)/8;
-
-          for (iX = ((2*pData->iRowsize+7)/8) ; iX > 0 ; iX--)
-             *pDest++ = *pSrc++;
-
-          pDest = pData->pWorkrow+1;
-          pSrc = pDest + pData->iRowsize - (2*pData->iRowsize+7)/8;
-          for (iX = pData->iRowsize; ;)
-          {
-            *pDest++ = (((*pSrc)>>6)&3);
-            if (iX-- <= 0)
-              break;
-            *pDest++ = (((*pSrc)>>4)&3);
-            if (iX-- <= 0)
-              break;
-            *pDest++ = (((*pSrc)>>2)&3);
-            if (iX-- <= 0)
-              break;
-            *pDest++ = (((*pSrc)   )&3);
-            if (iX-- <= 0)
-              break;
-            pSrc++;
-          }
-        }
-        else if (pData->iPNGdepth == 4)
-        {
-          /* Inflate Workrow to 8-bit */
-          mng_int32  iX;
-          mng_uint8p pSrc = pData->pWorkrow+1;
-          mng_uint8p pDest = pSrc + pData->iRowsize - (4*pData->iRowsize+7)/8;
-
-          for (iX = ((4*pData->iRowsize+7)/8) ; iX > 0 ; iX--)
-             *pDest++ = *pSrc++;
-
-          pDest = pData->pWorkrow+1;
-          pSrc = pDest + pData->iRowsize - (4*pData->iRowsize+7)/8;
-          for (iX = pData->iRowsize; ;)
-          {
-            *pDest++ = (((*pSrc)>>4)&0x0f);
-            if (iX-- <= 0)
-              break;
-            *pDest++ = (((*pSrc)   )&0x0f);
-            if (iX-- <= 0)
-              break;
-            pSrc++;
-          }
-        }
-        if (pData->iPNGdepth < 8 && pData->iColortype == 0)
-        {
-          /* Expand samples to 8-bit by LBR */
-          mng_int32  iX;
-          mng_uint8p pSrc = pData->pWorkrow+1;
-          mng_uint8 multiplier[]={0,255,85,0,17,0,0,0,1};
-
-          for (iX = pData->iRowsize; iX > 0; iX--)
-              *pSrc++ *= multiplier[pData->iPNGdepth];
-        }
-#endif
-#ifdef MNG_NO_16BIT_SUPPORT
-        if (pData->iPNGdepth > 8)
-        {
-          /* Reduce Workrow to 8-bit */
-          mng_int32  iX;
-          mng_uint8p pSrc = pData->pWorkrow+1;
-          mng_uint8p pDest = pSrc;
-
-          for (iX = pData->iRowsize; iX > 0; iX--)
-          {
-            *pDest = *pSrc;
-            pDest++;
-            pSrc+=2;
-          }
-        }
-#endif
-
-#ifdef FILTER192                       /* has leveling info ? */
-        if (pData->iFilterofs == MNG_FILTER_DIFFERING)
-          iRslt = init_rowdiffering (pData);
-        else
-#endif
-          iRslt = MNG_NOERROR;
-                                       /* filter the row if necessary */
-        if ((!iRslt) && (pData->iFilterofs < pData->iPixelofs  ) &&
-                        (*(pData->pWorkrow + pData->iFilterofs))    )
-          iRslt = mng_filter_a_row (pData);
-        else
-          iRslt = MNG_NOERROR;
-                                       /* additional leveling/differing ? */
-        if ((!iRslt) && (pData->fDifferrow))
-        {
-          iRslt = ((mng_differrow)pData->fDifferrow) (pData);
-
-          pSwap           = pData->pWorkrow;
-          pData->pWorkrow = pData->pPrevrow;
-          pData->pPrevrow = pSwap;     /* make sure we're processing the right data */
-        }
-
-        if (!iRslt)
-        {
-#ifdef MNG_INCLUDE_JNG
-          if (pData->bHasJHDR)         /* is JNG alpha-channel ? */
-          {                            /* just store in object ? */
-            if ((!iRslt) && (pData->fStorerow))
-              iRslt = ((mng_storerow)pData->fStorerow)     (pData);
-          }
-          else
-#endif /* MNG_INCLUDE_JNG */
-          {                            /* process this row */
-            if ((!iRslt) && (pData->fProcessrow))
-              iRslt = ((mng_processrow)pData->fProcessrow) (pData);
-                                       /* store in object ? */
-            if ((!iRslt) && (pData->fStorerow))
-              iRslt = ((mng_storerow)pData->fStorerow)     (pData);
-                                       /* color correction ? */
-            if ((!iRslt) && (pData->fCorrectrow))
-              iRslt = ((mng_correctrow)pData->fCorrectrow) (pData);
-                                       /* slap onto canvas ? */
-            if ((!iRslt) && (pData->fDisplayrow))
-            {
-              iRslt = ((mng_displayrow)pData->fDisplayrow) (pData);
-
-              if (!iRslt)              /* check progressive display refresh */
-                iRslt = mng_display_progressive_check (pData);
-
-            }
-          }
-        }
-
-        if (iRslt)                     /* on error bail out */
-          MNG_ERROR (pData, iRslt);
-
-        if (!pData->fDifferrow)        /* swap row-pointers */
-        {
-          pSwap           = pData->pWorkrow;
-          pData->pWorkrow = pData->pPrevrow;
-          pData->pPrevrow = pSwap;     /* so prev points to the processed row! */
-        }
-
-        iRslt = mng_next_row (pData);  /* adjust variables for next row */
-
-        if (iRslt)                     /* on error bail out */
-          MNG_ERROR (pData, iRslt);
-      }
-                                       /* let zlib know where to store next output */
-      pData->sZlib.next_out  = pData->pWorkrow;
-      pData->sZlib.avail_out = (uInt)(pData->iRowsize + pData->iPixelofs);
-#ifdef MNG_NO_1_2_4BIT_SUPPORT
-    if (pData->iPNGdepth < 8)
-       pData->sZlib.avail_out = (uInt)((pData->iPNGdepth*pData->iRowsize + 7)/8
-           + pData->iPixelofs);
-#endif
-#ifdef MNG_NO_16BIT_SUPPORT
-      if (pData->iPNGdepth > 8)
-        pData->sZlib.avail_out = (uInt)(2*pData->iRowsize + pData->iPixelofs);
-#endif
-    }
-  }                                    /* until some error or EOI
-                                          or all pixels received */
-  while ( (iZrslt == Z_OK) && (pData->sZlib.avail_in > 0)      &&
-          ( (pData->iRow < (mng_int32)pData->iDataheight) ||
-            ( (pData->iPass >= 0) && (pData->iPass < 7) )    )    );
-                                       /* on error bail out */
-  if ((iZrslt != Z_OK) && (iZrslt != Z_STREAM_END))
-    MNG_ERRORZ (pData, (mng_uint32)iZrslt);
-                                       /* too much data ? */
-  if ((iZrslt == Z_OK) && (pData->sZlib.avail_in > 0))
-    MNG_WARNING (pData, MNG_TOOMUCHIDAT);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ZLIB_INFLATEROWS, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-#endif /* MNG_SUPPORT_DISPLAY */
-
-/* ************************************************************************** */
-
-mng_retcode mngzlib_inflatedata (mng_datap  pData,
-                                 mng_uint32 iInlen,
-                                 mng_uint8p pIndata)
-{
-  int iZrslt;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ZLIB_INFLATEDATA, MNG_LC_START);
-#endif
-                                       /* let zlib know where to get stuff */
-  pData->sZlib.next_in   = pIndata;
-  pData->sZlib.avail_in  = (uInt)iInlen;
-                                       /* now inflate the data in one go! */
-  iZrslt = inflate (&pData->sZlib, Z_FINISH);
-                                       /* not enough room in output-buffer ? */
-  if ((iZrslt == Z_BUF_ERROR) || (pData->sZlib.avail_in > 0))
-    return MNG_BUFOVERFLOW;
-                                       /* on error bail out */
-  if ((iZrslt != Z_OK) && (iZrslt != Z_STREAM_END))
-    MNG_ERRORZ (pData, (mng_uint32)iZrslt);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ZLIB_INFLATEDATA, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mngzlib_inflatefree (mng_datap pData)
-{
-  int iZrslt;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ZLIB_INFLATEFREE, MNG_LC_START);
-#endif
-
-  pData->bInflating = MNG_FALSE;       /* stopped it */
-
-  iZrslt = inflateEnd (&pData->sZlib); /* let zlib cleanup its own stuff */
-
-  if (iZrslt != Z_OK)                  /* on error bail out */
-    MNG_ERRORZ (pData, (mng_uint32)iZrslt);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ZLIB_INFLATEFREE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-
-/* ************************************************************************** */
-
-mng_retcode mngzlib_deflateinit (mng_datap pData)
-{
-  int iZrslt;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ZLIB_DEFLATEINIT, MNG_LC_START);
-#endif
-                                       /* initialize zlib structures and such */
-  iZrslt = deflateInit2 (&pData->sZlib, pData->iZlevel, pData->iZmethod,
-                         pData->iZwindowbits, pData->iZmemlevel,
-                         pData->iZstrategy);
-
-  if (iZrslt != Z_OK)                  /* on error bail out */
-    MNG_ERRORZ (pData, (mng_uint32)iZrslt);
-
-  pData->bDeflating = MNG_TRUE;        /* really deflating something now */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ZLIB_DEFLATEINIT, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-
-/* ************************************************************************** */
-
-mng_retcode mngzlib_deflaterows (mng_datap  pData,
-                                 mng_uint32 iInlen,
-                                 mng_uint8p pIndata)
-{
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ZLIB_DEFLATEROWS, MNG_LC_START);
-#endif
-
-
-
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ZLIB_DEFLATEROWS, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mngzlib_deflatedata (mng_datap  pData,
-                                 mng_uint32 iInlen,
-                                 mng_uint8p pIndata)
-{
-  int iZrslt;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ZLIB_DEFLATEDATA, MNG_LC_START);
-#endif
-
-  pData->sZlib.next_in  = pIndata;     /* let zlib know where to get stuff */
-  pData->sZlib.avail_in = (uInt)iInlen;
-                                       /* now deflate the data in one go! */
-  iZrslt = deflate (&pData->sZlib, Z_FINISH);
-                                       /* not enough room in output-buffer ? */
-  if ((iZrslt == Z_BUF_ERROR) || (pData->sZlib.avail_in > 0))
-    return MNG_BUFOVERFLOW;
-                                       /* on error bail out */
-  if ((iZrslt != Z_OK) && (iZrslt != Z_STREAM_END))
-    MNG_ERRORZ (pData, (mng_uint32)iZrslt);
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ZLIB_DEFLATEDATA, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;
-}
-
-/* ************************************************************************** */
-
-mng_retcode mngzlib_deflatefree (mng_datap pData)
-{
-  int iZrslt;
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ZLIB_DEFLATEFREE, MNG_LC_START);
-#endif
-
-  iZrslt = deflateEnd (&pData->sZlib); /* let zlib cleanup its own stuff */
-
-  if (iZrslt != Z_OK)                  /* on error bail out */
-    MNG_ERRORZ (pData, (mng_uint32)iZrslt);
-
-  pData->bDeflating = MNG_FALSE;       /* stopped it */
-
-#ifdef MNG_SUPPORT_TRACE
-  MNG_TRACE (pData, MNG_FN_ZLIB_DEFLATEFREE, MNG_LC_END);
-#endif
-
-  return MNG_NOERROR;                  /* done */
-}
-
-/* ************************************************************************** */
-
-#endif /* MNG_INCLUDE_ZLIB */
-
-/* ************************************************************************** */
-/* * end of file                                                            * */
-/* ************************************************************************** */
-
diff --git a/Source/LibMNG/libmng_zlib.h b/Source/LibMNG/libmng_zlib.h
deleted file mode 100644
index cfc3918..0000000
--- a/Source/LibMNG/libmng_zlib.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* ************************************************************************** */
-/* *             For conditions of distribution and use,                    * */
-/* *                see copyright notice in libmng.h                        * */
-/* ************************************************************************** */
-/* *                                                                        * */
-/* * project   : libmng                                                     * */
-/* * file      : libmng_zlib.h             copyright (c) 2000-2002 G.Juyn   * */
-/* * version   : 1.0.0                                                      * */
-/* *                                                                        * */
-/* * purpose   : ZLIB package interface (definition)                        * */
-/* *                                                                        * */
-/* * author    : G.Juyn                                                     * */
-/* *                                                                        * */
-/* * comment   : Definition of the ZLIB package interface                   * */
-/* *                                                                        * */
-/* * changes   : 0.5.1 - 05/08/2000 - G.Juyn                                * */
-/* *             - changed strict-ANSI stuff                                * */
-/* *                                                                        * */
-/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
-/* *             - changed file-prefixes                                    * */
-/* *                                                                        * */
-/* ************************************************************************** */
-
-#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
-#pragma option -A                      /* force ANSI-C */
-#endif
-
-#ifndef _libmng_zlib_h_
-#define _libmng_zlib_h_
-
-/* ************************************************************************** */
-
-mng_retcode mngzlib_initialize  (mng_datap pData);
-mng_retcode mngzlib_cleanup     (mng_datap pData);
-
-mng_retcode mngzlib_inflateinit (mng_datap pData);
-mng_retcode mngzlib_inflaterows (mng_datap  pData,
-                                 mng_uint32 iInlen,
-                                 mng_uint8p pIndata);
-mng_retcode mngzlib_inflatedata (mng_datap  pData,
-                                 mng_uint32 iInlen,
-                                 mng_uint8p pIndata);
-mng_retcode mngzlib_inflatefree (mng_datap pData);
-
-mng_retcode mngzlib_deflateinit (mng_datap pData);
-mng_retcode mngzlib_deflaterows (mng_datap  pData,
-                                 mng_uint32 iInlen,
-                                 mng_uint8p pIndata);
-mng_retcode mngzlib_deflatedata (mng_datap  pData,
-                                 mng_uint32 iInlen,
-                                 mng_uint8p pIndata);
-mng_retcode mngzlib_deflatefree (mng_datap pData);
-
-/* ************************************************************************** */
-
-#endif /* _libmng_zlib_h_ */
-
-/* ************************************************************************** */
-/* * end of file                                                            * */
-/* ************************************************************************** */
diff --git a/Source/LibOpenJPEG/AUTHORS b/Source/LibOpenJPEG/AUTHORS
index dd765ac..dd1ac08 100644
--- a/Source/LibOpenJPEG/AUTHORS
+++ b/Source/LibOpenJPEG/AUTHORS
@@ -5,6 +5,8 @@ David Janssens designed and implemented the first version of OpenJPEG.
 Kaori Hagihara designed and implemented the first version of OpenJPIP.
 Jerome Fimes implemented the alpha version of OpenJPEG v2.
 Giuseppe Baruffa added the JPWL functionalities.
+Micka�l Savinaud implemented the final OpenJPEG v2 version based on a big merge between 1.5 version and alpha version of v2.
+Mathieu Malaterre  participate to the OpenJPEG v2 version and release the OpenJPEG 1.5 and 1.5.1 version. 
 Yannick Verschueren, 
 Herve Drolon, 
 Francois-Olivier Devaux, 
diff --git a/Source/LibOpenJPEG/CHANGES b/Source/LibOpenJPEG/CHANGES
deleted file mode 100644
index ab21f8a..0000000
--- a/Source/LibOpenJPEG/CHANGES
+++ /dev/null
@@ -1,425 +0,0 @@
-2012-09-10  Mathieu Malaterre
-
-	* [r1920] NEWS: [1.5] update NEWS file
-	* [r1919] libopenjpeg/j2k.c: [1.5] Fix Heap-based buffer-overflow
-	  when decoding openjpeg image
-	  
-	  Thanks to Huzaifa Sidhpurwala of Red Hat Security Response Team
-	  for dataset to reproduce the issue.
-	  Fixes issue 170
-	* [r1917] libopenjpeg/event.c: [1.5] Fix issue with str_length not
-	  being used. Rewrite code to prefer use of vsnprintf to prevent
-	  potential buffer overflow.
-	* [r1914] libopenjpeg/jpwl/crc.c, libopenjpeg/jpwl/jpwl_lib.c:
-	  [1.5] remove extra trailing semicolon
-
-2012-08-24  Mathieu Malaterre
-
-	* [r1899] applications/codec/j2k_dump.c,
-	  applications/jpip/libopenjpip/byte_manager.c,
-	  libopenjpeg/jpwl/jpwl_lib.c, libopenjpeg/tcd.c: [1.5] COMP: Fix
-	  warnings identified by clang31
-	  
-	  openjpeg/libopenjpeg/tcd.c:1884 col 48: warning: comparison of
-	  unsigned expressi
-	  on < 0 is always false
-	  
-	  openjpeg/applications/codec/j2k_dump.c:362 col 29: warning:
-	  equality comparison
-	  with extraneous parentheses
-	  
-	  openjpeg/libopenjpeg/jpwl/jpwl_lib.c:680:19: warning: format
-	  specifies type 'int
-	  ' but the argument has type 'long long' [-Wformat]
-	  printf("Marker@%d: %X\n", cio_tell(cio) - 2, id);
-	  ~^ ~~~~~~~~~~~~~~~~~
-	  %lld
-	  
-	  openjpeg/applications/jpip/libopenjpip/byte_manager.c:58:63:
-	  warning: format spe
-	  cifies type 'long' but the argument has type 'OPJ_OFF_T' (aka
-	  'long long') [-Wfo
-	  rmat]
-	  fprintf( FCGI_stderr, "Error: error in fetch_bytes( %d, %ld,
-	  %lu)\n", fd, offset
-	  , size);
-	  
-	  Author: Hans Johnson <hans-johnson at uiowa.edu>
-
-2012-07-29  Mathieu Malaterre
-
-	* [r1736] applications/jpip/libopenjpip/sock_manager.c: [1.5]
-	  Import portion of patch from Alex Zimnitsky to fix compilation on
-	  FreeBSD
-
-2012-07-11  Mathieu Malaterre
-
-	* [r1733] libopenjpeg/cio.c, libopenjpeg/cio.h: [1.5] Fix
-	  compilation issue with Compiler Borland C++ v. 5.5
-	  
-	  Fixes issue 154
-	* [r1732] libopenjpeg/j2k.c: [1.5] Fix r1727 (Issue 156) to compile
-	  on compilers where false is not defined.
-	* [r1729] libopenjpeg/j2k.c, libopenjpeg/tcd.c: [1.5] This fixes
-	  issues seen on PDF files
-	  
-	  Fixes issue 156
-
-2012-07-10  Mathieu Malaterre
-
-	* [r1727] libopenjpeg/j2k.c: [1.5] Fix heap buffer overflow
-	  
-	  Enforce sanity checks on tile number and tile length, even when
-	  the (rather
-	  broken) USE_JPWL code isn't enabled.
-
-2012-05-29  Mathieu Malaterre
-
-	* [r1705] libopenjpeg/jp2.c: [1.5] jp2_read_boxhdr() call ignores
-	  return value
-	  Fixes issue 91
-	* [r1704] applications/mj2/frames_to_mj2.c, applications/mj2/mj2.c,
-	  applications/mj2/mj2_convert.c: [1.5] Make sure openjpeg/mj2 can
-	  be compiled with gcc -std=c89
-	* [r1703] libopenjpeg/tcd.c: [1.5] This commit hides symptoms of
-	  CVE-2009-5030
-	  
-	  As explained in issue 5, comment 1. This is an easy fix to avoid
-	  memory overrun.
-	  Update issue 5
-	  Update issue 62
-	* [r1702] libopenjpeg/j2k.c,
-	  tests/nonregression/test_suite.ctest.in: [1.5] Applying old patch
-	  from r1642, with further modification from winfried. Also enable
-	  failing test. Everything seems to be working well now.
-	  Fixes issue 150
-	* [r1701] libopenjpeg/tcd.c: [1.5] Import r1669 from trunk over to
-	  1.5 branch
-	* [r1700] libopenjpeg/j2k.c, libopenjpeg/t1.c, libopenjpeg/t2.c,
-	  libopenjpeg/tcd.c: [1.5] Apply private patch from Alex Macfarlane
-	  Smith
-	  This gets rids of a lot memory leaks when used on device with low
-	  memory
-	* [r1696] applications/codec/convert.c, libopenjpeg/jp2.c: [1.5]
-	  The two files in Issue145 have a precision < 8-bit:
-	  therefore 'jp2_read_pclr' must be changed.
-	  
-	  j2k_to_image fails to create RGB/RGBA images with a
-	  precision < 8-bit: therefore 'imagetopng' must be
-	  changed.
-	  Update issue 145
-	* [r1694] libopenjpeg-jpwl.pc.in, libopenjpeg/Makefile.am: [1.5]
-	  Fix autotools installation. Thanks to winfried for patch.
-	  Update issue 149
-	* [r1693] libopenjpeg/opj_malloc.h: [1.5] Fix compilation on
-	  FreeBSD. Thanks to rafael carre (funman at videolan.org) for patch.
-	  
-	  Fixes issue 111
-
-2012-05-21  Mathieu Malaterre
-
-	* [r1686] libopenjpeg/opj_malloc.h: [1.5] Build fails on AIX
-	  
-	  Fixes issue 139
-	* [r1683] doc/man/man1/image_to_j2k.1, doc/man/man1/j2k_to_image.1,
-	  doc/man/man3/libopenjpeg.3: [1.5] Man page syntax fixes. Thanks
-	  to vskytta for patch.
-	  
-	  Fixes issue 147
-	* [r1682] libopenjpeg/tcd.c: [1.5] fix compilation warning about
-	  lrintf being implicit.
-	  
-	  Fixes issue 144
-
-2012-04-23  Mathieu Malaterre
-
-	* [r1649] libopenjpeg/j2k.c: [1.5] Revert r1642, as explained on
-	  https://groups.google.com/group/openjpeg/msg/77a67fef94a0309b
-	* [r1648] tests/nonregression/test_suite.ctest.in: [1.5] Adding
-	  test suite for file409752.jp2
-	* [r1647] CMakeLists.txt: [1.5] Make it easier to find /data from
-	  within 1.5 sub-branch
-	* [r1643] applications/JavaOpenJPEG/JavaOpenJPEG.c,
-	  applications/JavaOpenJPEG/JavaOpenJPEGDecoder.c,
-	  applications/codec/convert.c: [1.5] Integrate patch from winfried
-	  posted on the mailing list. See here for more info:
-	  https://groups.google.com/group/openjpeg/msg/6488859a0dce77
-	* [r1642] libopenjpeg/j2k.c: [1.5] Integrate patch from winfried
-	  posted on the mailing list. See here for more info:
-	  https://groups.google.com/group/openjpeg/msg/1bbf7ae7ddee3a51
-	* [r1640] applications/mj2/extract_j2k_from_mj2.c,
-	  applications/mj2/frames_to_mj2.c, applications/mj2/mj2.h,
-	  applications/mj2/mj2_to_frames.c,
-	  applications/mj2/wrap_j2k_in_mj2.c, libopenjpeg/openjpeg.h: [1.5]
-	  Integrate patch from winfried posted on the mailing list. See
-	  here for more info:
-	  https://groups.google.com/group/openjpeg/msg/7e30b6e288ad5908
-
-2012-04-20  Mathieu Malaterre
-
-	* [r1637] applications/jpip/util/CMakeLists.txt,
-	  applications/jpip/util/addXMLinJP2.c: [1.5] Need to
-	  compile/install tool to embed XML file in JP2 for jpip server
-
-2012-04-19  Mathieu Malaterre
-
-	* [r1636] applications/JavaOpenJPEG/CMakeLists.txt,
-	  applications/jpip/util/CMakeLists.txt: [1.5] jar files are arch
-	  independant. We can install them safely in share
-	* [r1635] applications/jpip/util/CMakeLists.txt: [1.5] Add install
-	  rules for openjpip client
-	* [r1634] applications/JavaOpenJPEG/CMakeLists.txt: [1.5] Add
-	  missing symbols from getopt into the java glue lib
-	* [r1633] applications/JavaOpenJPEG/CMakeLists.txt: [1.5] resolve
-	  missing symbols from convert.c/index.c
-	* [r1632] applications/JavaOpenJPEG/CMakeLists.txt: [1.5] Add
-	  explicit linking from glue java lib to real openjpeg lib
-	* [r1631] applications/JavaOpenJPEG/CMakeLists.txt: [1.5] install
-	  java module
-	* [r1630] CMake/OpenJPEGConfig.cmake.in, CMakeLists.txt: [1.5] Fix
-	  computation of relative path from include/ to lib/
-
-2012-04-18  Mathieu Malaterre
-
-	* [r1629] CMakeLists.txt, libopenjpeg/jpwl/CMakeLists.txt,
-	  tests/unit/testempty1.c, tests/unit/testempty2.c: [1.5] fix
-	  compilation warnings on windows box
-
-2012-04-16  Mathieu Malaterre
-
-	* [r1628] libopenjpeg/jpwl/CMakeLists.txt: [1.5] debian tools
-	  detected a missing link to math lib
-
-2012-04-06  Mathieu Malaterre
-
-	* [r1626] tests/CMakeLists.txt, tests/unit,
-	  tests/unit/CMakeLists.txt, tests/unit/testempty1.c,
-	  tests/unit/testempty2.c: [1.5] Adding some simple unit tests
-
-2012-04-05  Mathieu Malaterre
-
-	* [r1625] CMakeLists.txt: [1.5] introduce fix for the SOVERSION
-	  regression introduced in 1.5.0
-
-2012-03-16  Mathieu Malaterre
-
-	* [r1571] applications/jpip/libopenjpip/j2kheader_manager.c,
-	  applications/jpip/libopenjpip/query_parser.c: [1.5] Remove a
-	  simple warning report
-	* [r1570] applications/jpip/libopenjpip/query_parser.c: [1.5] I
-	  think == was meant here.
-
-2012-03-02  Mathieu Malaterre
-
-	* [r1534] applications/jpip/libopenjpip/channel_manager.c: [1.5]
-	  Remove a warning about undefined snprintf on windows compiler.
-	* [r1533] applications/jpip/libopenjpip/auxtrans_manager.c,
-	  applications/jpip/libopenjpip/byte_manager.h,
-	  applications/jpip/libopenjpip/channel_manager.c,
-	  applications/jpip/libopenjpip/channel_manager.h,
-	  applications/jpip/libopenjpip/codestream_manager.c,
-	  applications/jpip/libopenjpip/j2kheader_manager.c,
-	  applications/jpip/libopenjpip/jp2k_decoder.c,
-	  applications/jpip/libopenjpip/manfbox_manager.c,
-	  applications/jpip/libopenjpip/marker_manager.c,
-	  applications/jpip/libopenjpip/mhixbox_manager.c,
-	  applications/jpip/libopenjpip/session_manager.c,
-	  applications/jpip/libopenjpip/session_manager.h: [1.5] Change the
-	  logic in byte_manager.h. Prefer the use of stdint.h when
-	  available. Default to compiler specific mecanism otherwise.
-	  Remove some c++ comments. Fix signed vs unsigned comparison
-	* [r1527] doc/CMakeLists.txt, doc/Doxyfile.dox.cmake.in: [1.5]
-	  Finish import of r963
-	* [r1526] ., doc/Doxyfile.dox, doc/Doxyfile.dox.cmake.in,
-	  doc/mainpage.dox.cmake[CPY]: [1.5] merge r963 from trunk over to
-	  branch 1.5
-	* [r1524] tests/nonregression/test_suite.ctest.in: [1.5] Convert
-	  from DOS eol to UNIX eol
-	* [r1517] libopenjpeg/jpwl/README.txt, libopenjpeg/jpwl/crc.c,
-	  libopenjpeg/jpwl/jpwl.c: [1.5] Set from DOS eol to UNIX eol
-	* [r1510] libopenjpeg/cidx_manager.c: [1.5] Sync with trunk and
-	  remove uneeded include headers
-	* [r1506] applications/mj2/extract_j2k_from_mj2.c,
-	  applications/mj2/frames_to_mj2.c, applications/mj2/mj2.c: [1.5]
-	  Import rev 1053 from trunk over to 1.5
-	* [r1504] applications/codec/j2k_dump.c: [1.5] Fix typo in date.
-	* [r1496] applications/jpip/libopenjpip/comMakefile.mk[DEL]: [1.5]
-	  Sync with trunk. Remove remainings bits of old Makefile based
-	  build system
-	* [r1492] applications/codec/index.c, applications/codec/index.h,
-	  applications/codec/windirent.h: [1.5] Convert from DOS eol to
-	  UNIX eol
-	* [r1488] applications/OPJViewer/CMakeLists.txt,
-	  applications/OPJViewer/OPJViewer.iss,
-	  applications/OPJViewer/Readme.txt,
-	  applications/OPJViewer/about/about.htm,
-	  applications/OPJViewer/source/OPJAbout.cpp,
-	  applications/OPJViewer/source/OPJChild16.xpm,
-	  applications/OPJViewer/source/OPJDialogs.cpp,
-	  applications/OPJViewer/source/OPJThreads.cpp,
-	  applications/OPJViewer/source/OPJViewer.cpp,
-	  applications/OPJViewer/source/OPJViewer.h,
-	  applications/OPJViewer/source/OPJViewer.rc,
-	  applications/OPJViewer/source/OPJViewer16.xpm,
-	  applications/OPJViewer/source/about_htm.h,
-	  applications/OPJViewer/source/build.h,
-	  applications/OPJViewer/source/imagjpeg2000.cpp,
-	  applications/OPJViewer/source/imagjpeg2000.h,
-	  applications/OPJViewer/source/imagmxf.cpp,
-	  applications/OPJViewer/source/imagmxf.h,
-	  applications/OPJViewer/source/license.txt,
-	  applications/OPJViewer/source/readmeafter.txt,
-	  applications/OPJViewer/source/readmebefore.txt,
-	  applications/OPJViewer/source/wxj2kparser.cpp,
-	  applications/OPJViewer/source/wxjp2parser.cpp: [1.5] Use UNIX eol
-	  for source code
-	* [r1486] INSTALL: [1.5] Sync with trunk.
-	* [r1482] CMakeLists.txt: [1.5] As discussed on the mailing list.
-	  OpenJPEG should be compatible with Multi-Arch distros. Thanks to
-	  Rex for report
-	* [r1481] applications/jpip/libopenjpip/box_manager.c,
-	  applications/jpip/libopenjpip/box_manager.h,
-	  applications/jpip/libopenjpip/boxheader_manager.c,
-	  applications/jpip/libopenjpip/byte_manager.h,
-	  applications/jpip/libopenjpip/cachemodel_manager.c,
-	  applications/jpip/libopenjpip/cachemodel_manager.h,
-	  applications/jpip/libopenjpip/imgreg_manager.c,
-	  applications/jpip/libopenjpip/imgreg_manager.h,
-	  applications/jpip/libopenjpip/jp2k_encoder.c,
-	  applications/jpip/libopenjpip/jpip_parser.c,
-	  applications/jpip/libopenjpip/manfbox_manager.c,
-	  applications/jpip/libopenjpip/manfbox_manager.h,
-	  applications/jpip/libopenjpip/metadata_manager.c,
-	  applications/jpip/libopenjpip/metadata_manager.h,
-	  applications/jpip/libopenjpip/placeholder_manager.c,
-	  applications/jpip/libopenjpip/placeholder_manager.h,
-	  applications/jpip/libopenjpip/target_manager.c,
-	  applications/jpip/libopenjpip/target_manager.h,
-	  applications/jpip/util/jpip_to_j2k.c,
-	  applications/jpip/util/opj_server.c: [1.5] Fix a bunch of
-	  comparison between signed and unsigned integer expressions. Some
-	  are still left to decide.
-
-2012-03-01  Mathieu Malaterre
-
-	* [r1480] applications/jpip/libopenjpip/openjpip.c: [1.5] Fix rev
-	  1474, typo in the spelling.
-	* [r1479] libopenjpeg/jpwl/jpwl.c: [1.5] Fix a warning about
-	  comparison of ulong >= 0. Thanks to winfried for report.
-	* [r1475] applications/codec/convert.c: [1.5] Apply big-endian
-	  patch from winfried: libopenjpeg and WORDS_BIGENDIAN, 2012/02/14
-	* [r1474] applications/jpip/libopenjpip/openjpip.c: Fix a warning
-	  reported on the continuous dashboard for linux.
-	* [r1473] applications/codec/convert.c: [1.5] j2k_to_image does not
-	  support writing image with precision less than 8bits. Simply give
-	  up for now. Thanks to winfried for report. Also add static
-	  keyword for undeclared function in convert.h
-	* [r1472] applications/jpip/libopenjpip/jpipstream_manager.c,
-	  applications/jpip/libopenjpip/jpipstream_manager.h: [1.5] Fix a
-	  warning about conversion from const char* to char*
-	* [r1471] CMakeLists.txt: [1.5] cmake recommends the use of
-	  fullpath. Thanks to winfried for report.
-	* [r1468] libopenjpeg/jpwl/CMakeLists.txt: [1.5] Fix JPWL's DLL
-	  installation. Thanks to winfried for report.
-
-2012-02-29  Kaori Hagihara
-
-	* [r1467] applications/jpip/README: [1.5][JPIP] README modification
-	  regarding the JP2 encoding
-
-2012-02-28  Rex Dieter
-
-	* [r1464] CMakeLists.txt, libopenjpeg/CMakeLists.txt,
-	  libopenjpeg1.pc.cmake: allow finer-grain control of header
-	  location via OPENJPEG_INSTALL_INCLUDE_DIR
-	* [r1463] CMakeLists.txt, libopenjpeg1.pc.cmake: fix assumptions
-	  that OPENJPEG_INSTALL_*_DIR aren't relative paths
-
-2012-02-28  Kaori Hagihara
-
-	* [r1462] applications/jpip/CHANGES,
-	  applications/jpip/libopenjpip/comMakefile.mk,
-	  applications/jpip/libopenjpip/jpip_parser.c,
-	  applications/jpip/libopenjpip/metadata_manager.c,
-	  applications/jpip/libopenjpip/openjpip.c,
-	  applications/jpip/libopenjpip/query_parser.c,
-	  applications/jpip/util/opj_server.c: [1.5][JPIP] enabled the
-	  opj_server to reply the first query consisting with len request
-	  from kakadu client
-
-2012-02-23  Rex Dieter
-
-	* [r1460] libopenjpeg1.pc.cmake, libopenjpeg1.pc.in: fix pkgconfig
-	  to include -I/usr/include/openjpeg-1.5 in cflags (issue #118)
-
-2012-02-17  Mathieu Malaterre
-
-	* [r1444] applications/jpip/util/CMakeLists.txt: [1.5] allow
-	  mecanism to provide JFLAGS
-
-2012-02-16  Mathieu Malaterre
-
-	* [r1437] CMakeLists.txt: only install CHANGES when present
-	* [r1436] applications/jpip/util/opj_dec_server.c: remove a warning
-	  about unused variable
-
-2012-02-14  Mathieu Malaterre
-
-	* [r1435] CMake/CTestCustom.cmake.in: Hide some warnings generated
-	  by 3rd party libs
-	* [r1434] applications/jpip/util/opj_dec_server.c: Make the code
-	  C90 compliant for VS2010
-	* [r1433] applications/jpip/util/CMakeLists.txt: Work around issue
-	  with FindJava module
-
-2012-02-13  Mathieu Malaterre
-
-	* [r1429] applications/jpip/libopenjpip/sock_manager.c: Use C style
-	  comment.
-	* [r1424] applications/jpip/libopenjpip/sock_manager.c: [1.5] Need
-	  to include unistd for close() declaration
-	* [r1423] applications/jpip/util/CMakeLists.txt: By default,
-	  openjpip client can still built even without java compiler. Print
-	  a message to the user as warning.
-	* [r1422] applications/jpip/CMakeLists.txt: [1.5] Fix typo in
-	  CMAKE_USE_PTHREADS vs CMAKE_USE_PTHREADS_INIT
-	* [r1420] CMake/FindFCGI.cmake: [1.5] Backport diff from trunk
-	* [r1419] CMake/FindPTHREAD.cmake[DEL],
-	  applications/jpip/CMakeLists.txt,
-	  applications/jpip/libopenjpip/CMakeLists.txt: [1.5] Remove use of
-	  custom PTHREAD module. Prefer cmake's one.
-
-2012-02-10  Kaori Hagihara
-
-	* [r1405] applications/jpip/CHANGES, applications/jpip/README,
-	  applications/jpip/util/opj_dec_server.c,
-	  applications/jpip/util/opj_viewer/src/ImageManager.java,
-	  applications/jpip/util/opj_viewer/src/ImageWindow.java,
-	  applications/jpip/util/opj_viewer/src/ImgdecClient.java,
-	  applications/jpip/util/opj_viewer_xerces/src/ImageWindow.java:
-	  [1.5][JPIP] added execution argument to set port number for
-	  opj_dec_server, opj_viewer*
-	* [r1404] applications/jpip/CHANGES,
-	  applications/jpip/doc/Doxyfile: [1.5][JPIP] fixed Doxygen
-	  configuration file to document the utilities
-
-2012-02-10  Antonin Descampe
-
-	* [r1403] CMakeLists.txt, libopenjpeg/CMakeLists.txt: [1.5] revert
-	  r1399 and r1400
-	* [r1402] doc/Makefile.am: [1.5] fixed an error in autotools that
-	  prevented the build because no CHANGES file anymore
-
-2012-02-10  Rex Dieter
-
-	* [r1401] CMake/OpenJPEGConfig.cmake.in: make OpenJPEGConfig.cmake
-	  provide useful (non-empty) values
-	* [r1400] libopenjpeg/CMakeLists.txt: make openjpeg.h header
-	  symlink to match autotools
-	* [r1399] CMakeLists.txt: install cmake/pkgconfig bits in LIB_DIR
-
-2012-02-07  Antonin Descampe
-
-	* [r1391] CMake/OpenJPEGCPack.cmake: update OpenJPEGCPack.cmake
-	  with correct package names
-
diff --git a/Source/LibOpenJPEG/INSTALL b/Source/LibOpenJPEG/INSTALL
index 144d0c7..109ec4b 100644
--- a/Source/LibOpenJPEG/INSTALL
+++ b/Source/LibOpenJPEG/INSTALL
@@ -2,63 +2,10 @@
 How to build and install openjpeg binaries
 ==========================================
 
-UNIX/LINUX similar systems
+UNIX/LINUX/MacOSX/Windows systems
 --------------------------
 
-1) Using autotools
-
-It is highly recommended that pkg-config is installed. If needed, you have to
-properly set the environment variable PKG_CONFIG_PATH so that the .pc files
-are found.
-
-To build from top-level directory, you can simply type: 
-  ./bootstrap.sh
-  ./configure
-  make
-
-To keep all build files in a separate directory, you can type instead: 
-  ./bootstrap.sh
-  mkdir build
-  cd build
-  ../configure
-  make
-
-To install:
-  sudo make install
-  
-To clean:
-  make clean
-  make distclean
-
-To build doc (requires 'doxygen' to be found on your system):
-(this will create an html directory in TOP_LEVEL/doc)
-  make doc
-
-Main './configure' options (type './configure --help' for more details)
-  '--enable-mj2'
-  '--enable-jpwl'
-  '--enable-jpip'
-  '--prefix=/path/to/install/directory' (example : '--prefix=$PWD/installed')
-  '--enable-debug' (default : disabled)
-
-You can also specify your own CFLAGS and LDFLAGS with (for example):
-  CFLAGS="-O3 -pipe" LDFLAGS="-Wl,-s" ./configure
-
-The (optional) dependencies of some binaries are libpng, libtiff, libcms 1 or 2
-and FastCGI. Only libtiff and FastCGI have no .pc file. There should be some
-automatic detection if they are installed in /usr, /usr/local or /opt/local.
-Otherwise, you can tune their detection (as well as for libpng and libcms1 or 2
-too) with the environment variables:
-
-TIFF_CFLAGS
-TIFF_LIBS
-FCGI_CFLAGS
-FCGI_LIBS
-
-See './configure --help' output for more details.
-
-
-2) Using cmake (see www.cmake.org)
+Using cmake (see www.cmake.org)
 
 Type:
   cmake .
@@ -84,9 +31,15 @@ Main available cmake flags:
 * To build the shared libraries and links the executables against it: '-DBUILD_SHARED_LIBS:bool=on' (default: 'ON')
   Note: when using this option, static libraries are not built and executables are dynamically linked.
 * To build the CODEC executables: '-DBUILD_CODEC:bool=on' (default: 'ON')
+* To build the documentation: '-DBUILD_DOC:bool=on' (default: 'OFF')
 * To build the MJ2 executables: '-DBUILD_MJ2:bool=on' (default: 'OFF')
 * To build the JPWL executables and JPWL library: '-DBUILD_JPWL:bool=on' (default: 'OFF')
 * To build the JPIP library and utilities: '-DBUILD_JPIP:bool=on' (default: 'OFF')
+** To build the JPIP server: '-DBUILD_JPIP_SERVER:bool=on' (default: 'OFF')
+* To build the JP3D library and utilities: '-DBUILD_JP3D:bool=on' (default: 'OFF') (experimental)
+* To build the Java binding: '-DBUILD_JAVA:bool=on' (default: 'OFF') (experimental).
+** to choose which java implementation, you can set your JAVA_HOME env var.
+* To build the wxWidgets/C++ viewer: 'BUILD_VIEWER:BOOL=ON' (default OFF) (experimental)
 * To enable testing (and automatic result upload to http://my.cdash.org/index.php?project=OPENJPEG):
     cmake . -DBUILD_TESTING:BOOL=ON -DOPJ_DATA_ROOT:PATH='path/to/the/data/directory'
     make
@@ -99,7 +52,7 @@ Main available cmake flags:
 MACOSX
 ------
 
-The same building procedures as above (autotools and cmake) work for MACOSX.
+The same building procedures as above work for MACOSX.
 The xcode project file can also be used.
 
 If it does not work, try adding the following flag to the cmake command : 
@@ -108,7 +61,9 @@ If it does not work, try adding the following flag to the cmake command :
 WINDOWS
 -------
 
-If you're using cygwin or MinGW+MSYS, the same procedures as for Unix can be used. 
-
-Otherwise you can use cmake to generate project files for the IDE you are using (VC2010, etc).
+You can use cmake to generate project files for the IDE you are using (VS2010, NMake, etc).
 Type 'cmake --help' for available generators on your platform.
+
+Make sure to build the third party libs (png, zlib ...):
+
+  '-DBUILD_THIRDPARTY:BOOL=ON'
diff --git a/Source/LibOpenJPEG/LICENSE b/Source/LibOpenJPEG/LICENSE
index 88bd07a..5040692 100644
--- a/Source/LibOpenJPEG/LICENSE
+++ b/Source/LibOpenJPEG/LICENSE
@@ -6,6 +6,9 @@
  * Copyright (c) 2005, Herve Drolon, FreeImage Team
  * Copyright (c) 2002-2003, Yannick Verschueren
  * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2011-2012, Centre National d'Etudes Spatiales (CNES), France 
+ * Copyright (c) 2012, CS Systemes d'Information, France
+ *
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/Source/LibOpenJPEG/LibOpenJPEG.2003.vcproj b/Source/LibOpenJPEG/LibOpenJPEG.2003.vcproj
deleted file mode 100644
index 6907b93..0000000
--- a/Source/LibOpenJPEG/LibOpenJPEG.2003.vcproj
+++ /dev/null
@@ -1,558 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="7.10"
-	Name="LibOpenJPEG"
-	ProjectGUID="{E3536C28-A7F1-4B53-8E52-7D2232F9E098}"
-	SccProjectName=""
-	SccLocalPath="">
-	<Platforms>
-		<Platform
-			Name="Win32"/>
-	</Platforms>
-	<Configurations>
-		<Configuration
-			Name="Release|Win32"
-			OutputDirectory=".\Release"
-			IntermediateDirectory=".\Release"
-			ConfigurationType="4"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="FALSE"
-			CharacterSet="2">
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="2"
-				GlobalOptimizations="TRUE"
-				InlineFunctionExpansion="2"
-				EnableIntrinsicFunctions="TRUE"
-				FavorSizeOrSpeed="1"
-				OmitFramePointers="TRUE"
-				OptimizeForProcessor="3"
-				PreprocessorDefinitions="WIN32;NDEBUG;_LIB;OPJ_STATIC"
-				StringPooling="TRUE"
-				RuntimeLibrary="0"
-				BufferSecurityCheck="FALSE"
-				EnableFunctionLevelLinking="FALSE"
-				UsePrecompiledHeader="2"
-				PrecompiledHeaderFile=".\Release/LibOpenJPEG.pch"
-				AssemblerListingLocation=".\Release/"
-				ObjectFile=".\Release/"
-				ProgramDataBaseFileName=".\Release/"
-				WarningLevel="3"
-				SuppressStartupBanner="TRUE"/>
-			<Tool
-				Name="VCCustomBuildTool"/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile=".\Release\LibOpenJPEG.lib"
-				SuppressStartupBanner="TRUE"/>
-			<Tool
-				Name="VCMIDLTool"/>
-			<Tool
-				Name="VCPostBuildEventTool"/>
-			<Tool
-				Name="VCPreBuildEventTool"/>
-			<Tool
-				Name="VCPreLinkEventTool"/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="1033"/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"/>
-			<Tool
-				Name="VCManagedWrapperGeneratorTool"/>
-			<Tool
-				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
-		</Configuration>
-		<Configuration
-			Name="Debug|Win32"
-			OutputDirectory=".\Debug"
-			IntermediateDirectory=".\Debug"
-			ConfigurationType="4"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="FALSE"
-			CharacterSet="2">
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="0"
-				PreprocessorDefinitions="WIN32;_DEBUG;_LIB;OPJ_STATIC"
-				StringPooling="TRUE"
-				BasicRuntimeChecks="3"
-				RuntimeLibrary="1"
-				StructMemberAlignment="0"
-				UsePrecompiledHeader="2"
-				PrecompiledHeaderFile=".\Debug/LibOpenJPEG.pch"
-				AssemblerListingLocation=".\Debug/"
-				ObjectFile=".\Debug/"
-				ProgramDataBaseFileName=".\Debug/"
-				WarningLevel="3"
-				SuppressStartupBanner="TRUE"
-				Detect64BitPortabilityProblems="FALSE"
-				DebugInformationFormat="4"/>
-			<Tool
-				Name="VCCustomBuildTool"/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile=".\Debug\LibOpenJPEG.lib"
-				SuppressStartupBanner="TRUE"/>
-			<Tool
-				Name="VCMIDLTool"/>
-			<Tool
-				Name="VCPostBuildEventTool"/>
-			<Tool
-				Name="VCPreBuildEventTool"/>
-			<Tool
-				Name="VCPreLinkEventTool"/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="_DEBUG"
-				Culture="1033"/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"/>
-			<Tool
-				Name="VCManagedWrapperGeneratorTool"/>
-			<Tool
-				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Source Files"
-			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
-			<File
-				RelativePath="bio.c">
-				<FileConfiguration
-					Name="Release|Win32">
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32">
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath=".\cidx_manager.c">
-			</File>
-			<File
-				RelativePath="cio.c">
-				<FileConfiguration
-					Name="Release|Win32">
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32">
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="dwt.c">
-				<FileConfiguration
-					Name="Release|Win32">
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32">
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="event.c">
-				<FileConfiguration
-					Name="Release|Win32">
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32">
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"
-						CompileAs="1"/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="image.c">
-				<FileConfiguration
-					Name="Release|Win32">
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32">
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="j2k.c">
-				<FileConfiguration
-					Name="Release|Win32">
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32">
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="j2k_lib.c">
-				<FileConfiguration
-					Name="Release|Win32">
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32">
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="jp2.c">
-				<FileConfiguration
-					Name="Release|Win32">
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32">
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="jpt.c">
-				<FileConfiguration
-					Name="Release|Win32">
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32">
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="mct.c">
-				<FileConfiguration
-					Name="Release|Win32">
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32">
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="mqc.c">
-				<FileConfiguration
-					Name="Release|Win32">
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32">
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="openjpeg.c">
-				<FileConfiguration
-					Name="Release|Win32">
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32">
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath=".\phix_manager.c">
-			</File>
-			<File
-				RelativePath="pi.c">
-				<FileConfiguration
-					Name="Release|Win32">
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32">
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath=".\ppix_manager.c">
-			</File>
-			<File
-				RelativePath="raw.c">
-				<FileConfiguration
-					Name="Release|Win32">
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32">
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="t1.c">
-				<FileConfiguration
-					Name="Release|Win32">
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32">
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath=".\t1_generate_luts.c">
-			</File>
-			<File
-				RelativePath="t2.c">
-				<FileConfiguration
-					Name="Release|Win32">
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32">
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="tcd.c">
-				<FileConfiguration
-					Name="Release|Win32">
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32">
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="tgt.c">
-				<FileConfiguration
-					Name="Release|Win32">
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32">
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath=".\thix_manager.c">
-			</File>
-			<File
-				RelativePath=".\tpix_manager.c">
-			</File>
-		</Filter>
-		<Filter
-			Name="Header Files"
-			Filter="h;hpp;hxx;hm;inl">
-			<File
-				RelativePath="bio.h">
-			</File>
-			<File
-				RelativePath=".\cidx_manager.h">
-			</File>
-			<File
-				RelativePath="cio.h">
-			</File>
-			<File
-				RelativePath="dwt.h">
-			</File>
-			<File
-				RelativePath="event.h">
-			</File>
-			<File
-				RelativePath="fix.h">
-			</File>
-			<File
-				RelativePath="image.h">
-			</File>
-			<File
-				RelativePath=".\indexbox_manager.h">
-			</File>
-			<File
-				RelativePath="int.h">
-			</File>
-			<File
-				RelativePath="j2k.h">
-			</File>
-			<File
-				RelativePath="j2k_lib.h">
-			</File>
-			<File
-				RelativePath="jp2.h">
-			</File>
-			<File
-				RelativePath="jpt.h">
-			</File>
-			<File
-				RelativePath="mct.h">
-			</File>
-			<File
-				RelativePath="mqc.h">
-			</File>
-			<File
-				RelativePath="openjpeg.h">
-			</File>
-			<File
-				RelativePath=".\opj_config.h">
-			</File>
-			<File
-				RelativePath="opj_includes.h">
-			</File>
-			<File
-				RelativePath=".\opj_malloc.h">
-			</File>
-			<File
-				RelativePath="pi.h">
-			</File>
-			<File
-				RelativePath="raw.h">
-			</File>
-			<File
-				RelativePath="t1.h">
-			</File>
-			<File
-				RelativePath=".\t1_luts.h">
-			</File>
-			<File
-				RelativePath="t2.h">
-			</File>
-			<File
-				RelativePath="tcd.h">
-			</File>
-			<File
-				RelativePath="tgt.h">
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
diff --git a/Source/LibOpenJPEG/LibOpenJPEG.2005.vcproj b/Source/LibOpenJPEG/LibOpenJPEG.2005.vcproj
index 962c9fe..537c307 100644
--- a/Source/LibOpenJPEG/LibOpenJPEG.2005.vcproj
+++ b/Source/LibOpenJPEG/LibOpenJPEG.2005.vcproj
@@ -332,783 +332,79 @@
 			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
 			>
 			<File
-				RelativePath="bio.c"
+				RelativePath=".\bio.c"
 				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"
-					/>
-				</FileConfiguration>
 			</File>
 			<File
-				RelativePath=".\cidx_manager.c"
+				RelativePath=".\cio.c"
 				>
 			</File>
 			<File
-				RelativePath="cio.c"
+				RelativePath=".\dwt.c"
 				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"
-					/>
-				</FileConfiguration>
 			</File>
 			<File
-				RelativePath="dwt.c"
+				RelativePath=".\event.c"
 				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"
-					/>
-				</FileConfiguration>
 			</File>
 			<File
-				RelativePath="event.c"
+				RelativePath=".\function_list.c"
 				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"
-					/>
-				</FileConfiguration>
 			</File>
 			<File
-				RelativePath="image.c"
+				RelativePath=".\image.c"
 				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"
-					/>
-				</FileConfiguration>
 			</File>
 			<File
-				RelativePath="j2k.c"
+				RelativePath=".\invert.c"
 				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"
-					/>
-				</FileConfiguration>
 			</File>
 			<File
-				RelativePath="j2k_lib.c"
+				RelativePath=".\j2k.c"
 				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"
-					/>
-				</FileConfiguration>
 			</File>
 			<File
-				RelativePath="jp2.c"
+				RelativePath=".\jp2.c"
 				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"
-					/>
-				</FileConfiguration>
 			</File>
 			<File
-				RelativePath="jpt.c"
+				RelativePath=".\mct.c"
 				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"
-					/>
-				</FileConfiguration>
 			</File>
 			<File
-				RelativePath="mct.c"
+				RelativePath=".\mqc.c"
 				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"
-					/>
-				</FileConfiguration>
 			</File>
 			<File
-				RelativePath="mqc.c"
+				RelativePath=".\openjpeg.c"
 				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"
-					/>
-				</FileConfiguration>
 			</File>
 			<File
-				RelativePath="openjpeg.c"
+				RelativePath=".\opj_clock.c"
 				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"
-					/>
-				</FileConfiguration>
 			</File>
 			<File
-				RelativePath=".\phix_manager.c"
+				RelativePath=".\pi.c"
 				>
 			</File>
 			<File
-				RelativePath="pi.c"
+				RelativePath=".\raw.c"
 				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"
-					/>
-				</FileConfiguration>
 			</File>
 			<File
-				RelativePath=".\ppix_manager.c"
+				RelativePath=".\t1.c"
 				>
 			</File>
 			<File
-				RelativePath="raw.c"
+				RelativePath=".\t2.c"
 				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"
-					/>
-				</FileConfiguration>
 			</File>
 			<File
-				RelativePath="t1.c"
+				RelativePath=".\tcd.c"
 				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"
-					/>
-				</FileConfiguration>
 			</File>
 			<File
-				RelativePath=".\t1_generate_luts.c"
-				>
-			</File>
-			<File
-				RelativePath="t2.c"
-				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="tcd.c"
-				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="tgt.c"
-				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath=".\thix_manager.c"
-				>
-			</File>
-			<File
-				RelativePath=".\tpix_manager.c"
+				RelativePath=".\tgt.c"
 				>
 			</File>
 		</Filter>
@@ -1117,75 +413,75 @@
 			Filter="h;hpp;hxx;hm;inl"
 			>
 			<File
-				RelativePath="bio.h"
+				RelativePath=".\bio.h"
 				>
 			</File>
 			<File
-				RelativePath=".\cidx_manager.h"
+				RelativePath=".\cio.h"
 				>
 			</File>
 			<File
-				RelativePath="cio.h"
+				RelativePath=".\dwt.h"
 				>
 			</File>
 			<File
-				RelativePath="dwt.h"
+				RelativePath=".\event.h"
 				>
 			</File>
 			<File
-				RelativePath="event.h"
+				RelativePath=".\function_list.h"
 				>
 			</File>
 			<File
-				RelativePath="fix.h"
+				RelativePath=".\image.h"
 				>
 			</File>
 			<File
-				RelativePath="image.h"
+				RelativePath=".\invert.h"
 				>
 			</File>
 			<File
-				RelativePath=".\indexbox_manager.h"
+				RelativePath=".\j2k.h"
 				>
 			</File>
 			<File
-				RelativePath="int.h"
+				RelativePath=".\jp2.h"
 				>
 			</File>
 			<File
-				RelativePath="j2k.h"
+				RelativePath=".\mct.h"
 				>
 			</File>
 			<File
-				RelativePath="j2k_lib.h"
+				RelativePath=".\mqc.h"
 				>
 			</File>
 			<File
-				RelativePath="jp2.h"
+				RelativePath=".\openjpeg.h"
 				>
 			</File>
 			<File
-				RelativePath="jpt.h"
+				RelativePath=".\opj_clock.h"
 				>
 			</File>
 			<File
-				RelativePath="mct.h"
+				RelativePath=".\opj_config.h"
 				>
 			</File>
 			<File
-				RelativePath="mqc.h"
+				RelativePath=".\opj_config_private.h"
 				>
 			</File>
 			<File
-				RelativePath="openjpeg.h"
+				RelativePath=".\opj_includes.h"
 				>
 			</File>
 			<File
-				RelativePath=".\opj_config.h"
+				RelativePath=".\opj_intmath.h"
 				>
 			</File>
 			<File
-				RelativePath="opj_includes.h"
+				RelativePath=".\opj_inttypes.h"
 				>
 			</File>
 			<File
@@ -1193,15 +489,19 @@
 				>
 			</File>
 			<File
-				RelativePath="pi.h"
+				RelativePath=".\opj_stdint.h"
+				>
+			</File>
+			<File
+				RelativePath=".\pi.h"
 				>
 			</File>
 			<File
-				RelativePath="raw.h"
+				RelativePath=".\raw.h"
 				>
 			</File>
 			<File
-				RelativePath="t1.h"
+				RelativePath=".\t1.h"
 				>
 			</File>
 			<File
@@ -1209,15 +509,15 @@
 				>
 			</File>
 			<File
-				RelativePath="t2.h"
+				RelativePath=".\t2.h"
 				>
 			</File>
 			<File
-				RelativePath="tcd.h"
+				RelativePath=".\tcd.h"
 				>
 			</File>
 			<File
-				RelativePath="tgt.h"
+				RelativePath=".\tgt.h"
 				>
 			</File>
 		</Filter>
diff --git a/Source/LibOpenJPEG/LibOpenJPEG.2008.vcproj b/Source/LibOpenJPEG/LibOpenJPEG.2008.vcproj
index fe5e8b8..60cfee3 100644
--- a/Source/LibOpenJPEG/LibOpenJPEG.2008.vcproj
+++ b/Source/LibOpenJPEG/LibOpenJPEG.2008.vcproj
@@ -375,10 +375,6 @@
 				</FileConfiguration>
 			</File>
 			<File
-				RelativePath=".\cidx_manager.c"
-				>
-			</File>
-			<File
 				RelativePath="cio.c"
 				>
 				<FileConfiguration
@@ -505,49 +501,11 @@
 				</FileConfiguration>
 			</File>
 			<File
-				RelativePath="image.c"
+				RelativePath=".\function_list.c"
 				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"
-					/>
-				</FileConfiguration>
 			</File>
 			<File
-				RelativePath="j2k.c"
+				RelativePath="image.c"
 				>
 				<FileConfiguration
 					Name="Release|Win32"
@@ -589,49 +547,11 @@
 				</FileConfiguration>
 			</File>
 			<File
-				RelativePath="j2k_lib.c"
+				RelativePath=".\invert.c"
 				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="2"
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						Optimization="0"
-						PreprocessorDefinitions=""
-						BasicRuntimeChecks="3"
-					/>
-				</FileConfiguration>
 			</File>
 			<File
-				RelativePath="jp2.c"
+				RelativePath="j2k.c"
 				>
 				<FileConfiguration
 					Name="Release|Win32"
@@ -673,7 +593,7 @@
 				</FileConfiguration>
 			</File>
 			<File
-				RelativePath="jpt.c"
+				RelativePath="jp2.c"
 				>
 				<FileConfiguration
 					Name="Release|Win32"
@@ -841,7 +761,7 @@
 				</FileConfiguration>
 			</File>
 			<File
-				RelativePath=".\phix_manager.c"
+				RelativePath=".\opj_clock.c"
 				>
 			</File>
 			<File
@@ -887,10 +807,6 @@
 				</FileConfiguration>
 			</File>
 			<File
-				RelativePath=".\ppix_manager.c"
-				>
-			</File>
-			<File
 				RelativePath="raw.c"
 				>
 				<FileConfiguration
@@ -1100,89 +1016,85 @@
 					/>
 				</FileConfiguration>
 			</File>
-			<File
-				RelativePath=".\thix_manager.c"
-				>
-			</File>
-			<File
-				RelativePath=".\tpix_manager.c"
-				>
-			</File>
 		</Filter>
 		<Filter
 			Name="Header Files"
 			Filter="h;hpp;hxx;hm;inl"
 			>
 			<File
-				RelativePath="bio.h"
+				RelativePath=".\bio.h"
 				>
 			</File>
 			<File
-				RelativePath=".\cidx_manager.h"
+				RelativePath=".\cio.h"
 				>
 			</File>
 			<File
-				RelativePath="cio.h"
+				RelativePath=".\dwt.h"
 				>
 			</File>
 			<File
-				RelativePath="dwt.h"
+				RelativePath=".\event.h"
 				>
 			</File>
 			<File
-				RelativePath="event.h"
+				RelativePath=".\function_list.h"
 				>
 			</File>
 			<File
-				RelativePath="fix.h"
+				RelativePath=".\image.h"
 				>
 			</File>
 			<File
-				RelativePath="image.h"
+				RelativePath=".\indexbox_manager.h"
 				>
 			</File>
 			<File
-				RelativePath=".\indexbox_manager.h"
+				RelativePath=".\invert.h"
 				>
 			</File>
 			<File
-				RelativePath="int.h"
+				RelativePath=".\j2k.h"
 				>
 			</File>
 			<File
-				RelativePath="j2k.h"
+				RelativePath=".\jp2.h"
 				>
 			</File>
 			<File
-				RelativePath="j2k_lib.h"
+				RelativePath=".\mct.h"
 				>
 			</File>
 			<File
-				RelativePath="jp2.h"
+				RelativePath=".\mqc.h"
 				>
 			</File>
 			<File
-				RelativePath="jpt.h"
+				RelativePath=".\openjpeg.h"
 				>
 			</File>
 			<File
-				RelativePath="mct.h"
+				RelativePath=".\opj_clock.h"
 				>
 			</File>
 			<File
-				RelativePath="mqc.h"
+				RelativePath=".\opj_config.h"
 				>
 			</File>
 			<File
-				RelativePath="openjpeg.h"
+				RelativePath=".\opj_config_private.h"
 				>
 			</File>
 			<File
-				RelativePath=".\opj_config.h"
+				RelativePath=".\opj_includes.h"
 				>
 			</File>
 			<File
-				RelativePath="opj_includes.h"
+				RelativePath=".\opj_intmath.h"
+				>
+			</File>
+			<File
+				RelativePath=".\opj_inttypes.h"
 				>
 			</File>
 			<File
@@ -1190,15 +1102,19 @@
 				>
 			</File>
 			<File
-				RelativePath="pi.h"
+				RelativePath=".\opj_stdint.h"
+				>
+			</File>
+			<File
+				RelativePath=".\pi.h"
 				>
 			</File>
 			<File
-				RelativePath="raw.h"
+				RelativePath=".\raw.h"
 				>
 			</File>
 			<File
-				RelativePath="t1.h"
+				RelativePath=".\t1.h"
 				>
 			</File>
 			<File
@@ -1206,15 +1122,15 @@
 				>
 			</File>
 			<File
-				RelativePath="t2.h"
+				RelativePath=".\t2.h"
 				>
 			</File>
 			<File
-				RelativePath="tcd.h"
+				RelativePath=".\tcd.h"
 				>
 			</File>
 			<File
-				RelativePath="tgt.h"
+				RelativePath=".\tgt.h"
 				>
 			</File>
 		</Filter>
diff --git a/Source/LibOpenJPEG/LibOpenJPEG.2013.vcxproj b/Source/LibOpenJPEG/LibOpenJPEG.2013.vcxproj
new file mode 100644
index 0000000..2586b2f
--- /dev/null
+++ b/Source/LibOpenJPEG/LibOpenJPEG.2013.vcxproj
@@ -0,0 +1,360 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectName>LibOpenJPEG</ProjectName>
+    <ProjectGuid>{E3536C28-A7F1-4B53-8E52-7D2232F9E098}</ProjectGuid>
+    <RootNamespace>LibOpenJPEG</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>12.0.21005.1</_ProjectFileVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <Optimization>Full</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <OmitFramePointers>true</OmitFramePointers>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;OPJ_STATIC;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>false</FunctionLevelLinking>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+      <DebugInformationFormat>None</DebugInformationFormat>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0409</Culture>
+    </ResourceCompile>
+    <Lib>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <LinkTimeCodeGeneration>true</LinkTimeCodeGeneration>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>Full</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <OmitFramePointers>true</OmitFramePointers>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;OPJ_STATIC;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>false</FunctionLevelLinking>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+      <DebugInformationFormat>None</DebugInformationFormat>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0409</Culture>
+    </ResourceCompile>
+    <Lib>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <LinkTimeCodeGeneration>true</LinkTimeCodeGeneration>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;OPJ_STATIC;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <StructMemberAlignment>Default</StructMemberAlignment>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0409</Culture>
+    </ResourceCompile>
+    <Lib>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;OPJ_STATIC;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <StructMemberAlignment>Default</StructMemberAlignment>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0409</Culture>
+    </ResourceCompile>
+    <Lib>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="bio.c">
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+    </ClCompile>
+    <ClCompile Include="cio.c">
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+    </ClCompile>
+    <ClCompile Include="dwt.c">
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+    </ClCompile>
+    <ClCompile Include="event.c">
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+    </ClCompile>
+    <ClCompile Include="function_list.c" />
+    <ClCompile Include="image.c">
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+    </ClCompile>
+    <ClCompile Include="invert.c" />
+    <ClCompile Include="j2k.c">
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+    </ClCompile>
+    <ClCompile Include="jp2.c">
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+    </ClCompile>
+    <ClCompile Include="mct.c">
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+    </ClCompile>
+    <ClCompile Include="mqc.c">
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+    </ClCompile>
+    <ClCompile Include="openjpeg.c">
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+    </ClCompile>
+    <ClCompile Include="opj_clock.c" />
+    <ClCompile Include="pi.c">
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+    </ClCompile>
+    <ClCompile Include="raw.c">
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+    </ClCompile>
+    <ClCompile Include="t1.c">
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+    </ClCompile>
+    <ClCompile Include="t2.c">
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+    </ClCompile>
+    <ClCompile Include="tcd.c">
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+    </ClCompile>
+    <ClCompile Include="tgt.c">
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="bio.h" />
+    <ClInclude Include="cio.h" />
+    <ClInclude Include="dwt.h" />
+    <ClInclude Include="event.h" />
+    <ClInclude Include="function_list.h" />
+    <ClInclude Include="image.h" />
+    <ClInclude Include="indexbox_manager.h" />
+    <ClInclude Include="invert.h" />
+    <ClInclude Include="j2k.h" />
+    <ClInclude Include="jp2.h" />
+    <ClInclude Include="mct.h" />
+    <ClInclude Include="mqc.h" />
+    <ClInclude Include="openjpeg.h" />
+    <ClInclude Include="opj_clock.h" />
+    <ClInclude Include="opj_config.h" />
+    <ClInclude Include="opj_config_private.h" />
+    <ClInclude Include="opj_includes.h" />
+    <ClInclude Include="opj_intmath.h" />
+    <ClInclude Include="opj_inttypes.h" />
+    <ClInclude Include="opj_malloc.h" />
+    <ClInclude Include="opj_stdint.h" />
+    <ClInclude Include="pi.h" />
+    <ClInclude Include="raw.h" />
+    <ClInclude Include="t1.h" />
+    <ClInclude Include="t1_luts.h" />
+    <ClInclude Include="t2.h" />
+    <ClInclude Include="tcd.h" />
+    <ClInclude Include="tgt.h" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/Source/LibOpenJPEG/LibOpenJPEG.2013.vcxproj.filters b/Source/LibOpenJPEG/LibOpenJPEG.2013.vcxproj.filters
new file mode 100644
index 0000000..617176c
--- /dev/null
+++ b/Source/LibOpenJPEG/LibOpenJPEG.2013.vcxproj.filters
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{0c3108c5-5ec7-43a4-a464-22b036977c34}</UniqueIdentifier>
+      <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{7be8dc1e-caaa-423f-bd9c-50cc5887a179}</UniqueIdentifier>
+      <Extensions>h;hpp;hxx;hm;inl</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="bio.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="cio.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="dwt.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="event.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="function_list.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="image.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="invert.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="j2k.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="jp2.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="mct.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="mqc.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="openjpeg.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="opj_clock.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="pi.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="raw.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="t1.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="t2.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="tcd.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="tgt.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="bio.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="cio.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="dwt.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="event.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="function_list.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="image.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="indexbox_manager.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="invert.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="j2k.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="jp2.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="mct.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="mqc.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="openjpeg.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="opj_clock.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="opj_config.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="opj_config_private.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="opj_includes.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="opj_intmath.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="opj_inttypes.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="opj_malloc.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="opj_stdint.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="pi.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="raw.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="t1.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="t1_luts.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="t2.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="tcd.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="tgt.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/Source/LibOpenJPEG/NEWS b/Source/LibOpenJPEG/NEWS
index f4cb03a..2d0bcf3 100644
--- a/Source/LibOpenJPEG/NEWS
+++ b/Source/LibOpenJPEG/NEWS
@@ -2,23 +2,20 @@
 OpenJPEG NEWS - user visible changes
 ====================================
 
-Changes from OpenJPEG 1.5.1 to OpenJPEG 1.5.0
+Changes from OpenJPEG 1.5.x to OpenJPEG 2.0.0
 ----------------------------------------------
 
-Security:
-
-    * Fixes: CVE-2012-3535
-    * Fixes: CVE-2012-3358
-
 New Features:
 
-    * Use a new API scheme and solve the SOVERSIONing in OpenJPEG
-    * Allow better integration with multi-arch system
-    * Compile & Install Java bindings (CMake)
-    * Install required addXMLinJP2 (JPIP)
+    * streaming capabilities
+    * merge JP3D
+
+API modifications:
 
+    * Use a 64bits capable API
+    
 Misc:
 
-    * fix linker error by resolving all symbols (eg. missing -lm)
-    * fix some man page typos
+    * removed autotools build system
+    * folders hierarchies reorganisation
     * Huge amount of bug fixes. See CHANGES for details.
diff --git a/Source/LibOpenJPEG/README b/Source/LibOpenJPEG/README
index 018ba2d..0a89178 100644
--- a/Source/LibOpenJPEG/README
+++ b/Source/LibOpenJPEG/README
@@ -4,22 +4,44 @@ OPENJPEG LIBRARY and APPLICATIONS
 
 Details on folders hierarchy:
 
-* libopenjpeg: contains the sources of the openjpeg library
-    * jpwl: contains the additional sources if you want to build a JPWL-flavoured library.
-* applications: contains all applications that use the openjpeg library
+* src
+  * lib
+    * openjp2: contains the sources of the openjp2 library (Part 1 & 2)
+    * openjpwl: contains the additional sources if you want to build a JPWL-flavoured library.
+    * openjpip: complete client-server architecture for remote browsing of jpeg 2000 images.
+    * openjp3d: JP3D implementation
+    * openmj2: MJ2 implementation
+  * bin: contains all applications that use the openjpeg library
     * common: common files to all applications
-    * codec: a basic codec
+    * jp2: a basic codec
     * mj2: motion jpeg 2000 executables
-    * JavaOpenJPEG: java jni to use openjpeg in a java program
-    * jpip: complete client-server architecture for remote browsing of jpeg 2000 images. See corresponding README for more details.
-    * OPJViewer: gui for displaying j2k files (based on wxWidget)
+    * jpip: OpenJPIP applications (server and dec server)
+      * java: a Java client viewer for JPIP
+    * jp3d: JP3D applications
+      * tcltk: a test tool for JP3D
+    * wx
+      * OPJViewer: gui for displaying j2k files (based on wxWidget)
+* wrapping
+  * java: java jni to use openjpeg in a java program
 * thirdparty: thirdparty libraries used by some applications. These libraries will be built only if there are not found on the system. Note that libopenjpeg itself does not have any dependency.
 * doc: doxygen documentation setup file and man pages
 * tests: configuration files and utilities for the openjpeg test suite. All test images are located in 'http://openjpeg.googlecode.com/svn/data' folder.
-* CMake: cmake related files
-* m4: autotools related files
+* cmake: cmake related files
 
 see LICENSE for license and copyright information.
 see INSTALL for installation procedures.
 see NEWS for user visible changes in successive releases.
 see CHANGES for per-revision changes.
+
+----------------
+API/ABI
+
+OpenJPEG strives to provide a stable API/ABI for your applications. As such it
+only exposes a limited subset of its functions.  It uses a mecanism of
+exporting/hiding functions. If you are unsure which functions you can use in
+your applications, you should compile OpenJPEG using something similar to gcc:
+-fvisibility=hidden compilation flag.
+See also: http://gcc.gnu.org/wiki/Visibility
+
+On windows, MSVC directly supports export/hidding function and as such the only
+API available is the one supported by OpenJPEG.
diff --git a/Source/LibOpenJPEG/THANKS b/Source/LibOpenJPEG/THANKS
index c0d136a..27a35aa 100644
--- a/Source/LibOpenJPEG/THANKS
+++ b/Source/LibOpenJPEG/THANKS
@@ -4,13 +4,11 @@ Many people have contributed to OpenJPEG by reporting problems, suggesting vario
 or submitting actual code. Here is a list of these people. Help me keep
 it complete and exempt of errors.
 
-Mathieu Malaterre
 Winfried Szukalski
 Vincent Torri
 Bob Friesenhahn
 Callum Lerwick
 Dzonatas Sol
-Mickaël Savinaud
 Julien Malik
 Jerôme Fimes
 Herve Drolon
@@ -31,3 +29,5 @@ Arnaud Maye
 Rex Dieter
 David Burken
 Parvatha Elangovan
+Hans Johnson
+Luc Hermitte
\ No newline at end of file
diff --git a/Source/LibOpenJPEG/bio.c b/Source/LibOpenJPEG/bio.c
index 9438ff1..213a994 100644
--- a/Source/LibOpenJPEG/bio.c
+++ b/Source/LibOpenJPEG/bio.c
@@ -1,187 +1,188 @@
-/*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
- * Copyright (c) 2001-2003, David Janssens
- * Copyright (c) 2002-2003, Yannick Verschueren
- * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "opj_includes.h"
-
-/** @defgroup BIO BIO - Individual bit input-output stream */
-/*@{*/
-
-/** @name Local static functions */
-/*@{*/
-
-/**
-Write a bit
- at param bio BIO handle
- at param b Bit to write (0 or 1)
-*/
-static void bio_putbit(opj_bio_t *bio, int b);
-/**
-Read a bit
- at param bio BIO handle
- at return Returns the read bit
-*/
-static int bio_getbit(opj_bio_t *bio);
-/**
-Write a byte
- at param bio BIO handle
- at return Returns 0 if successful, returns 1 otherwise
-*/
-static int bio_byteout(opj_bio_t *bio);
-/**
-Read a byte
- at param bio BIO handle
- at return Returns 0 if successful, returns 1 otherwise
-*/
-static int bio_bytein(opj_bio_t *bio);
-
-/*@}*/
-
-/*@}*/
-
-/* 
-==========================================================
-   local functions
-==========================================================
-*/
-
-static int bio_byteout(opj_bio_t *bio) {
-	bio->buf = (bio->buf << 8) & 0xffff;
-	bio->ct = bio->buf == 0xff00 ? 7 : 8;
-	if (bio->bp >= bio->end) {
-		return 1;
-	}
-	*bio->bp++ = bio->buf >> 8;
-	return 0;
-}
-
-static int bio_bytein(opj_bio_t *bio) {
-	bio->buf = (bio->buf << 8) & 0xffff;
-	bio->ct = bio->buf == 0xff00 ? 7 : 8;
-	if (bio->bp >= bio->end) {
-		return 1;
-	}
-	bio->buf |= *bio->bp++;
-	return 0;
-}
-
-static void bio_putbit(opj_bio_t *bio, int b) {
-	if (bio->ct == 0) {
-		bio_byteout(bio);
-	}
-	bio->ct--;
-	bio->buf |= b << bio->ct;
-}
-
-static int bio_getbit(opj_bio_t *bio) {
-	if (bio->ct == 0) {
-		bio_bytein(bio);
-	}
-	bio->ct--;
-	return (bio->buf >> bio->ct) & 1;
-}
-
-/* 
-==========================================================
-   Bit Input/Output interface
-==========================================================
-*/
-
-opj_bio_t* bio_create(void) {
-	opj_bio_t *bio = (opj_bio_t*)opj_malloc(sizeof(opj_bio_t));
-	return bio;
-}
-
-void bio_destroy(opj_bio_t *bio) {
-	if(bio) {
-		opj_free(bio);
-	}
-}
-
-int bio_numbytes(opj_bio_t *bio) {
-	return (bio->bp - bio->start);
-}
-
-void bio_init_enc(opj_bio_t *bio, unsigned char *bp, int len) {
-	bio->start = bp;
-	bio->end = bp + len;
-	bio->bp = bp;
-	bio->buf = 0;
-	bio->ct = 8;
-}
-
-void bio_init_dec(opj_bio_t *bio, unsigned char *bp, int len) {
-	bio->start = bp;
-	bio->end = bp + len;
-	bio->bp = bp;
-	bio->buf = 0;
-	bio->ct = 0;
-}
-
-void bio_write(opj_bio_t *bio, int v, int n) {
-	int i;
-	for (i = n - 1; i >= 0; i--) {
-		bio_putbit(bio, (v >> i) & 1);
-	}
-}
-
-int bio_read(opj_bio_t *bio, int n) {
-	int i, v;
-	v = 0;
-	for (i = n - 1; i >= 0; i--) {
-		v += bio_getbit(bio) << i;
-	}
-	return v;
-}
-
-int bio_flush(opj_bio_t *bio) {
-	bio->ct = 0;
-	if (bio_byteout(bio)) {
-		return 1;
-	}
-	if (bio->ct == 7) {
-		bio->ct = 0;
-		if (bio_byteout(bio)) {
-			return 1;
-		}
-	}
-	return 0;
-}
-
-int bio_inalign(opj_bio_t *bio) {
-	bio->ct = 0;
-	if ((bio->buf & 0xff) == 0xff) {
-		if (bio_bytein(bio)) {
-			return 1;
-		}
-		bio->ct = 0;
-	}
-	return 0;
-}
+/*
+ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2007, Professor Benoit Macq
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "opj_includes.h"
+
+/** @defgroup BIO BIO - Individual bit input-output stream */
+/*@{*/
+
+/** @name Local static functions */
+/*@{*/
+
+/**
+Write a bit
+ at param bio BIO handle
+ at param b Bit to write (0 or 1)
+*/
+static void opj_bio_putbit(opj_bio_t *bio, OPJ_UINT32 b);
+/**
+Read a bit
+ at param bio BIO handle
+ at return Returns the read bit
+*/
+static OPJ_UINT32 opj_bio_getbit(opj_bio_t *bio);
+/**
+Write a byte
+ at param bio BIO handle
+ at return Returns OPJ_TRUE if successful, returns OPJ_FALSE otherwise
+*/
+static OPJ_BOOL opj_bio_byteout(opj_bio_t *bio);
+/**
+Read a byte
+ at param bio BIO handle
+ at return Returns OPJ_TRUE if successful, returns OPJ_FALSE otherwise
+*/
+static OPJ_BOOL opj_bio_bytein(opj_bio_t *bio);
+
+/*@}*/
+
+/*@}*/
+
+/* 
+==========================================================
+   local functions
+==========================================================
+*/
+
+OPJ_BOOL opj_bio_byteout(opj_bio_t *bio) {
+	bio->buf = (bio->buf << 8) & 0xffff;
+	bio->ct = bio->buf == 0xff00 ? 7 : 8;
+	if (bio->bp >= bio->end) {
+		return OPJ_FALSE;
+	}
+	*bio->bp++ = (OPJ_BYTE)(bio->buf >> 8);
+	return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_bio_bytein(opj_bio_t *bio) {
+	bio->buf = (bio->buf << 8) & 0xffff;
+	bio->ct = bio->buf == 0xff00 ? 7 : 8;
+	if (bio->bp >= bio->end) {
+		return OPJ_FALSE;
+	}
+	bio->buf |= *bio->bp++;
+	return OPJ_TRUE;
+}
+
+void opj_bio_putbit(opj_bio_t *bio, OPJ_UINT32 b) {
+	if (bio->ct == 0) {
+		opj_bio_byteout(bio); /* MSD: why not check the return value of this function ? */
+	}
+	bio->ct--;
+	bio->buf |= b << bio->ct;
+}
+
+OPJ_UINT32 opj_bio_getbit(opj_bio_t *bio) {
+	if (bio->ct == 0) {
+		opj_bio_bytein(bio); /* MSD: why not check the return value of this function ? */
+	}
+	bio->ct--;
+	return (bio->buf >> bio->ct) & 1;
+}
+
+/* 
+==========================================================
+   Bit Input/Output interface
+==========================================================
+*/
+
+opj_bio_t* opj_bio_create(void) {
+	opj_bio_t *bio = (opj_bio_t*)opj_malloc(sizeof(opj_bio_t));
+	return bio;
+}
+
+void opj_bio_destroy(opj_bio_t *bio) {
+	if(bio) {
+		opj_free(bio);
+	}
+}
+
+ptrdiff_t opj_bio_numbytes(opj_bio_t *bio) {
+	return (bio->bp - bio->start);
+}
+
+void opj_bio_init_enc(opj_bio_t *bio, OPJ_BYTE *bp, OPJ_UINT32 len) {
+	bio->start = bp;
+	bio->end = bp + len;
+	bio->bp = bp;
+	bio->buf = 0;
+	bio->ct = 8;
+}
+
+void opj_bio_init_dec(opj_bio_t *bio, OPJ_BYTE *bp, OPJ_UINT32 len) {
+	bio->start = bp;
+	bio->end = bp + len;
+	bio->bp = bp;
+	bio->buf = 0;
+	bio->ct = 0;
+}
+
+void opj_bio_write(opj_bio_t *bio, OPJ_UINT32 v, OPJ_UINT32 n) {
+	OPJ_UINT32 i;
+	for (i = n - 1; i < n; i--) {
+		opj_bio_putbit(bio, (v >> i) & 1);
+	}
+}
+
+OPJ_UINT32 opj_bio_read(opj_bio_t *bio, OPJ_UINT32 n) {
+	OPJ_UINT32 i;
+    OPJ_UINT32 v;
+	v = 0;
+	for (i = n - 1; i < n; i--) {
+		v += opj_bio_getbit(bio) << i;
+	}
+	return v;
+}
+
+OPJ_BOOL opj_bio_flush(opj_bio_t *bio) {
+	bio->ct = 0;
+	if (! opj_bio_byteout(bio)) {
+		return OPJ_FALSE;
+	}
+	if (bio->ct == 7) {
+		bio->ct = 0;
+		if (! opj_bio_byteout(bio)) {
+			return OPJ_FALSE;
+		}
+	}
+	return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_bio_inalign(opj_bio_t *bio) {
+	bio->ct = 0;
+	if ((bio->buf & 0xff) == 0xff) {
+		if (! opj_bio_bytein(bio)) {
+			return OPJ_FALSE;
+		}
+		bio->ct = 0;
+	}
+	return OPJ_TRUE;
+}
diff --git a/Source/LibOpenJPEG/bio.h b/Source/LibOpenJPEG/bio.h
index 81f93f3..b4dd7fa 100644
--- a/Source/LibOpenJPEG/bio.h
+++ b/Source/LibOpenJPEG/bio.h
@@ -1,125 +1,128 @@
-/*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
- * Copyright (c) 2001-2003, David Janssens
- * Copyright (c) 2002-2003, Yannick Verschueren
- * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __BIO_H
-#define __BIO_H
-/** 
- at file bio.h
- at brief Implementation of an individual bit input-output (BIO)
-
-The functions in BIO.C have for goal to realize an individual bit input - output.
-*/
-
-/** @defgroup BIO BIO - Individual bit input-output stream */
-/*@{*/
-
-/**
-Individual bit input-output stream (BIO)
-*/
-typedef struct opj_bio {
-	/** pointer to the start of the buffer */
-	unsigned char *start;
-	/** pointer to the end of the buffer */
-	unsigned char *end;
-	/** pointer to the present position in the buffer */
-	unsigned char *bp;
-	/** temporary place where each byte is read or written */
-	unsigned int buf;
-	/** coder : number of bits free to write. decoder : number of bits read */
-	int ct;
-} opj_bio_t;
-
-/** @name Exported functions */
-/*@{*/
-/* ----------------------------------------------------------------------- */
-/**
-Create a new BIO handle 
- at return Returns a new BIO handle if successful, returns NULL otherwise
-*/
-opj_bio_t* bio_create(void);
-/**
-Destroy a previously created BIO handle
- at param bio BIO handle to destroy
-*/
-void bio_destroy(opj_bio_t *bio);
-/**
-Number of bytes written.
- at param bio BIO handle
- at return Returns the number of bytes written
-*/
-int bio_numbytes(opj_bio_t *bio);
-/**
-Init encoder
- at param bio BIO handle
- at param bp Output buffer
- at param len Output buffer length 
-*/
-void bio_init_enc(opj_bio_t *bio, unsigned char *bp, int len);
-/**
-Init decoder
- at param bio BIO handle
- at param bp Input buffer
- at param len Input buffer length 
-*/
-void bio_init_dec(opj_bio_t *bio, unsigned char *bp, int len);
-/**
-Write bits
- at param bio BIO handle
- at param v Value of bits
- at param n Number of bits to write
-*/
-void bio_write(opj_bio_t *bio, int v, int n);
-/**
-Read bits
- at param bio BIO handle
- at param n Number of bits to read 
- at return Returns the corresponding read number
-*/
-int bio_read(opj_bio_t *bio, int n);
-/**
-Flush bits
- at param bio BIO handle
- at return Returns 1 if successful, returns 0 otherwise
-*/
-int bio_flush(opj_bio_t *bio);
-/**
-Passes the ending bits (coming from flushing)
- at param bio BIO handle
- at return Returns 1 if successful, returns 0 otherwise
-*/
-int bio_inalign(opj_bio_t *bio);
-/* ----------------------------------------------------------------------- */
-/*@}*/
-
-/*@}*/
-
-#endif /* __BIO_H */
-
+/*
+ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2007, Professor Benoit Macq
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __BIO_H
+#define __BIO_H
+
+#include <stddef.h> /* ptrdiff_t */
+
+/** 
+ at file bio.h
+ at brief Implementation of an individual bit input-output (BIO)
+
+The functions in BIO.C have for goal to realize an individual bit input - output.
+*/
+
+/** @defgroup BIO BIO - Individual bit input-output stream */
+/*@{*/
+
+/**
+Individual bit input-output stream (BIO)
+*/
+typedef struct opj_bio {
+	/** pointer to the start of the buffer */
+	OPJ_BYTE *start;
+	/** pointer to the end of the buffer */
+	OPJ_BYTE *end;
+	/** pointer to the present position in the buffer */
+	OPJ_BYTE *bp;
+	/** temporary place where each byte is read or written */
+	OPJ_UINT32 buf;
+	/** coder : number of bits free to write. decoder : number of bits read */
+	OPJ_UINT32 ct;
+} opj_bio_t;
+
+/** @name Exported functions */
+/*@{*/
+/* ----------------------------------------------------------------------- */
+/**
+Create a new BIO handle 
+ at return Returns a new BIO handle if successful, returns NULL otherwise
+*/
+opj_bio_t* opj_bio_create(void);
+/**
+Destroy a previously created BIO handle
+ at param bio BIO handle to destroy
+*/
+void opj_bio_destroy(opj_bio_t *bio);
+/**
+Number of bytes written.
+ at param bio BIO handle
+ at return Returns the number of bytes written
+*/
+ptrdiff_t opj_bio_numbytes(opj_bio_t *bio);
+/**
+Init encoder
+ at param bio BIO handle
+ at param bp Output buffer
+ at param len Output buffer length 
+*/
+void opj_bio_init_enc(opj_bio_t *bio, OPJ_BYTE *bp, OPJ_UINT32 len);
+/**
+Init decoder
+ at param bio BIO handle
+ at param bp Input buffer
+ at param len Input buffer length 
+*/
+void opj_bio_init_dec(opj_bio_t *bio, OPJ_BYTE *bp, OPJ_UINT32 len);
+/**
+Write bits
+ at param bio BIO handle
+ at param v Value of bits
+ at param n Number of bits to write
+*/
+void opj_bio_write(opj_bio_t *bio, OPJ_UINT32 v, OPJ_UINT32 n);
+/**
+Read bits
+ at param bio BIO handle
+ at param n Number of bits to read 
+ at return Returns the corresponding read number
+*/
+OPJ_UINT32 opj_bio_read(opj_bio_t *bio, OPJ_UINT32 n);
+/**
+Flush bits
+ at param bio BIO handle
+ at return Returns OPJ_TRUE if successful, returns OPJ_FALSE otherwise
+*/
+OPJ_BOOL opj_bio_flush(opj_bio_t *bio);
+/**
+Passes the ending bits (coming from flushing)
+ at param bio BIO handle
+ at return Returns OPJ_TRUE if successful, returns OPJ_FALSE otherwise
+*/
+OPJ_BOOL opj_bio_inalign(opj_bio_t *bio);
+/* ----------------------------------------------------------------------- */
+/*@}*/
+
+/*@}*/
+
+#endif /* __BIO_H */
+
diff --git a/Source/LibOpenJPEG/cidx_manager.c b/Source/LibOpenJPEG/cidx_manager.c
index 778683e..42f87c2 100644
--- a/Source/LibOpenJPEG/cidx_manager.c
+++ b/Source/LibOpenJPEG/cidx_manager.c
@@ -1,5 +1,5 @@
 /*
- * $Id: cidx_manager.c,v 1.2 2012/09/23 12:44:41 drolon Exp $
+ * $Id: cidx_manager.c,v 1.4 2014/03/16 12:29:51 drolon Exp $
  *
  * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
  * Copyright (c) 2002-2011, Professor Benoit Macq
@@ -39,39 +39,24 @@
  * @param[in] clen length of j2k codestream
  * @param[in] cio  file output handle
  */
-void write_cptr(int coff, int clen, opj_cio_t *cio);
 
+void opj_write_cptr(int coff, int clen, opj_stream_private_t *cio,
+              opj_event_mgr_t * p_manager );
 
-/* 
- * Write main header index table (box)
- *
- * @param[in] coff offset of j2k codestream
- * @param[in] cstr_info codestream information
- * @param[in] cio  file output handle
- * @return         length of mainmhix box
- */
-int write_mainmhix( int coff, opj_codestream_info_t cstr_info, opj_cio_t *cio);
 
 
-/* 
- * Check if EPH option is used
- *
- * @param[in] coff    offset of j2k codestream
- * @param[in] markers marker information
- * @param[in] marknum number of markers
- * @param[in] cio     file output handle
- * @return            true if EPH is used
- */
-opj_bool check_EPHuse( int coff, opj_marker_info_t *markers, int marknum, opj_cio_t *cio);
 
 
-int write_cidx( int offset, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t cstr_info, int j2klen)
+int opj_write_cidx( int offset, opj_stream_private_t *cio, opj_codestream_info_t cstr_info, int j2klen,
+              opj_event_mgr_t * p_manager )
 {
-  int len, i, lenp;
+  int i;
+  OPJ_OFF_T lenp;
+  OPJ_UINT32 len;
   opj_jp2_box_t *box;
   int num_box = 0;
-  opj_bool  EPHused;
-  (void)image; /* unused ? */
+  OPJ_BOOL  EPHused;
+  OPJ_BYTE l_data_header [4];
 
   lenp = -1;
   box = (opj_jp2_box_t *)opj_calloc( 32, sizeof(opj_jp2_box_t));
@@ -79,133 +64,176 @@ int write_cidx( int offset, opj_cio_t *cio, opj_image_t *image, opj_codestream_i
   for (i=0;i<2;i++){
   
     if(i)
-      cio_seek( cio, lenp);
+      opj_stream_seek(cio,lenp,p_manager);
+
 
-    lenp = cio_tell( cio);
+    lenp = opj_stream_tell (cio);
 
-    cio_skip( cio, 4);              /* L [at the end] */
-    cio_write( cio, JPIP_CIDX, 4);  /* CIDX           */
-    write_cptr( offset, cstr_info.codestream_size, cio);
+    opj_stream_skip(cio, 4, p_manager); /* L [at the end] */
 
-    write_manf( i, num_box, box, cio);
+    opj_write_bytes(l_data_header,JPIP_CIDX,4); /* CIDX */
+    opj_stream_write_data(cio,l_data_header,4,p_manager);
+
+    opj_write_cptr( offset, cstr_info.codestream_size, cio,p_manager);
+
+    opj_write_manf( i, num_box, box, cio,p_manager);
     
     num_box = 0;
-    box[num_box].length = write_mainmhix( offset, cstr_info, cio);
+    box[num_box].length = (OPJ_UINT32)opj_write_mainmhix( offset, cstr_info, cio,p_manager);
     box[num_box].type = JPIP_MHIX;
     num_box++;
 
-    box[num_box].length = write_tpix( offset, cstr_info, j2klen, cio);
+    box[num_box].length = (OPJ_UINT32)opj_write_tpix( offset, cstr_info, j2klen, cio,p_manager);
     box[num_box].type = JPIP_TPIX;
     num_box++;
       
-    box[num_box].length = write_thix( offset, cstr_info, cio);
+    box[num_box].length = (OPJ_UINT32)opj_write_thix( offset, cstr_info, cio, p_manager);
     box[num_box].type = JPIP_THIX;
     num_box++;
 
-    EPHused = check_EPHuse( offset, cstr_info.marker, cstr_info.marknum, cio);
+    EPHused = opj_check_EPHuse( offset, cstr_info.marker, cstr_info.marknum, cio,p_manager);
       
-    box[num_box].length = write_ppix( offset, cstr_info, EPHused, j2klen, cio);
+    box[num_box].length = (OPJ_UINT32)opj_write_ppix( offset, cstr_info, EPHused, j2klen, cio,p_manager);
     box[num_box].type = JPIP_PPIX;
     num_box++;
     
-    box[num_box].length = write_phix( offset, cstr_info, EPHused, j2klen, cio);
+    box[num_box].length = (OPJ_UINT32)opj_write_phix( offset, cstr_info, EPHused, j2klen, cio,p_manager);
     box[num_box].type = JPIP_PHIX;
     num_box++;
       
-    len = cio_tell( cio)-lenp;
-    cio_seek( cio, lenp);
-    cio_write( cio, len, 4);        /* L             */
-    cio_seek( cio, lenp+len);
+    len = (OPJ_UINT32) (opj_stream_tell(cio)-lenp);
+    opj_stream_seek(cio, lenp,p_manager);
+    opj_write_bytes(l_data_header,len,4);/* L  */
+    opj_stream_write_data(cio,l_data_header,4,p_manager);
+    opj_stream_seek(cio, lenp+len,p_manager);
   }
 
   opj_free( box);
   
-  return len;
+  return (int)len;
 }
 
-void write_cptr(int coff, int clen, opj_cio_t *cio)
+
+
+void opj_write_cptr(int coff, int clen, opj_stream_private_t *cio,
+              opj_event_mgr_t * p_manager )
 {
-  int len, lenp;
-
-  lenp = cio_tell( cio);
-  cio_skip( cio, 4);               /* L [at the end]     */
-  cio_write( cio, JPIP_CPTR, 4);   /* T                  */
-  cio_write( cio, 0, 2);           /* DR  A PRECISER !!  */
-  cio_write( cio, 0, 2);           /* CONT               */
-  cio_write( cio, coff, 8);    /* COFF A PRECISER !! */
-  cio_write( cio, clen, 8);    /* CLEN               */
-  len = cio_tell( cio) - lenp;
-  cio_seek( cio, lenp);
-  cio_write( cio, len, 4);         /* L                  */
-  cio_seek( cio, lenp+len);
+  OPJ_BYTE l_data_header [3*8];
+  OPJ_UINT32 len;
+  OPJ_OFF_T lenp;
+
+
+  lenp = opj_stream_tell(cio);
+  opj_stream_skip( cio, 4, p_manager);               /* L [at the end]     */
+  opj_write_bytes( l_data_header, JPIP_CPTR, 4);   /* T                  */
+  opj_write_bytes( l_data_header+4, 0, 2);           /* DR  A PRECISER !!  */
+  opj_write_bytes( l_data_header+6, 0, 2);           /* CONT               */
+  opj_write_bytes( l_data_header+8, (OPJ_UINT32)coff, 8);    /* COFF A PRECISER !! */
+  opj_write_bytes( l_data_header+16, (OPJ_UINT32)clen, 8);    /* CLEN               */
+  opj_stream_write_data(cio,l_data_header,3*8,p_manager);
+
+  len = (OPJ_UINT32) (opj_stream_tell(cio) - lenp);
+  opj_stream_seek(cio,lenp,p_manager);
+  opj_write_bytes(l_data_header, len, 4);         /* L                  */
+  opj_stream_write_data(cio,l_data_header,4,p_manager);
+  opj_stream_seek(cio, lenp+len,p_manager);
+
 }
 
-void write_manf(int second, int v, opj_jp2_box_t *box, opj_cio_t *cio)
+
+
+void opj_write_manf(int second, 
+                    int v, 
+                    opj_jp2_box_t *box, 
+                    opj_stream_private_t *cio,
+                    opj_event_mgr_t * p_manager )
 {
-  int len, lenp, i;
+  OPJ_BYTE l_data_header [4];
+  int i;
+  OPJ_UINT32 len;
+  OPJ_OFF_T lenp;
   
-  lenp = cio_tell( cio); 
-  cio_skip( cio, 4);                         /* L [at the end]                    */
-  cio_write( cio, JPIP_MANF,4);              /* T                                 */
+  lenp = opj_stream_tell(cio);
+  opj_stream_skip( cio, 4, p_manager);             /* L [at the end]     */
+  opj_write_bytes( l_data_header, JPIP_MANF, 4);   /* T                  */
+  opj_stream_write_data(cio,l_data_header,4,p_manager);
 
   if (second){                          /* Write only during the second pass */
     for( i=0; i<v; i++){
-      cio_write( cio, box[i].length, 4);  /* Box length                     */ 
-      cio_write( cio, box[i].type, 4); /* Box type                       */
+      opj_write_bytes( l_data_header, box[i].length, 4); /* Box length                     */
+      opj_stream_write_data(cio,l_data_header,4,p_manager);
+      opj_write_bytes( l_data_header, box[i].type, 4); /* Box type                       */
+      opj_stream_write_data(cio,l_data_header,4,p_manager);
     }
   }
 
-  len = cio_tell( cio) - lenp;
-  cio_seek( cio, lenp);
-  cio_write( cio, len, 4);                   /* L                                 */
-  cio_seek( cio, lenp+len);
+  len = (OPJ_UINT32) (opj_stream_tell(cio) - lenp);
+  opj_stream_seek(cio,lenp,p_manager);
+  opj_write_bytes(l_data_header, len, 4);/* L                                 */
+  opj_stream_write_data(cio,l_data_header,4,p_manager);
+  opj_stream_seek(cio,lenp+len,p_manager);
 }
 
-int write_mainmhix( int coff, opj_codestream_info_t cstr_info, opj_cio_t *cio)
+
+int opj_write_mainmhix( int coff, opj_codestream_info_t cstr_info, opj_stream_private_t *cio,
+              opj_event_mgr_t * p_manager )
 {
-  int i;
-  int len, lenp;
+  OPJ_BYTE l_data_header [8];
+  OPJ_UINT32 i;
+  OPJ_UINT32 len;
+  OPJ_OFF_T lenp;
   
-  lenp = cio_tell( cio);
-  cio_skip( cio, 4);                               /* L [at the end]                    */
-  cio_write( cio, JPIP_MHIX, 4);                   /* MHIX                              */
-
-  cio_write( cio, cstr_info.main_head_end-cstr_info.main_head_start+1, 8);        /* TLEN                              */
-
-  for(i = 1; i < cstr_info.marknum; i++){    /* Marker restricted to 1 apparition, skip SOC marker */
-    cio_write( cio, cstr_info.marker[i].type, 2);
-    cio_write( cio, 0, 2);
-    cio_write( cio, cstr_info.marker[i].pos-coff, 8);
-    cio_write( cio, cstr_info.marker[i].len, 2);
+  lenp = opj_stream_tell (cio);
+  opj_stream_skip(cio, 4, p_manager);               /* L [at the end]                    */
+  opj_write_bytes(l_data_header,JPIP_MHIX,4);       /* MHIX                              */
+  opj_stream_write_data(cio,l_data_header,4,p_manager);
+
+  opj_write_bytes(l_data_header, (OPJ_UINT32)(cstr_info.main_head_end-cstr_info.main_head_start+1), 8);        /* TLEN                              */
+  opj_stream_write_data(cio,l_data_header,8,p_manager);
+
+  for(i = 1; i < (OPJ_UINT32)cstr_info.marknum; i++){    /* Marker restricted to 1 apparition, skip SOC marker */
+    opj_write_bytes( l_data_header, cstr_info.marker[i].type, 2);
+    opj_write_bytes( l_data_header+2, 0, 2);
+    opj_stream_write_data(cio,l_data_header,4,p_manager);
+    opj_write_bytes( l_data_header,(OPJ_UINT32) (cstr_info.marker[i].pos-coff), 8);
+    opj_stream_write_data(cio,l_data_header,8,p_manager);
+    opj_write_bytes( l_data_header, (OPJ_UINT32)cstr_info.marker[i].len, 2);
+    opj_stream_write_data(cio,l_data_header,2,p_manager);
   }
 
-  len = cio_tell( cio) - lenp;
-  cio_seek( cio, lenp);
-  cio_write( cio, len, 4);        /* L           */
-  cio_seek( cio, lenp+len);
+  len = (OPJ_UINT32) (opj_stream_tell(cio)-lenp);
+  opj_stream_seek(cio, lenp,p_manager);
+  opj_write_bytes(l_data_header,len,4);/* L  */
+  opj_stream_write_data(cio,l_data_header,4,p_manager);
+  opj_stream_seek(cio, lenp+len,p_manager);
   
-  return len;
+  return (int)len;
 }
 
-opj_bool check_EPHuse( int coff, opj_marker_info_t *markers, int marknum, opj_cio_t *cio)
+OPJ_BOOL opj_check_EPHuse( int coff, opj_marker_info_t *markers, int marknum, opj_stream_private_t *cio,
+              opj_event_mgr_t * p_manager )
 {
-  opj_bool EPHused = OPJ_FALSE;
+  OPJ_BYTE l_data_header [4];
+  OPJ_BOOL EPHused = OPJ_FALSE;
   int i=0;
-  int org_pos;
+  OPJ_OFF_T org_pos;
   unsigned int Scod;
 
-  for(i = 0; i < marknum; i++){
-    if( markers[i].type == J2K_MS_COD){
-      org_pos = cio_tell( cio);
-      cio_seek( cio, coff+markers[i].pos+2);
-      
-      Scod = cio_read( cio, 1);
+  for(i = 0; i < marknum; i++)
+    {
+    if( markers[i].type == J2K_MS_COD)
+      {
+      org_pos = opj_stream_tell(cio);
+      opj_stream_seek(cio, coff+markers[i].pos+2,p_manager);
+
+      opj_stream_read_data(cio,l_data_header,1,p_manager);
+      opj_read_bytes(l_data_header,&Scod,1);
       if( ((Scod >> 2) & 1))
-	EPHused = OPJ_TRUE;
-      cio_seek( cio, org_pos);
+        EPHused = OPJ_TRUE;
+      opj_stream_seek( cio, org_pos, p_manager);
 
       break;
-    }
-  }    
+      }
+    }    
   return EPHused;
 }
diff --git a/Source/LibOpenJPEG/cidx_manager.h b/Source/LibOpenJPEG/cidx_manager.h
index 91bb3fb..a4f7d9a 100644
--- a/Source/LibOpenJPEG/cidx_manager.h
+++ b/Source/LibOpenJPEG/cidx_manager.h
@@ -1,56 +1,68 @@
-/*
- * $Id: cidx_manager.h,v 1.2 2012/09/23 12:44:41 drolon Exp $
- *
- * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2011, Professor Benoit Macq
- * Copyright (c) 2003-2004, Yannick Verschueren
- * Copyright (c) 2010-2011, Kaori Hagihara
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*! \file
- *  \brief Modification of jpip.h from 2KAN indexer
- */
-
-
-#ifndef  CIDX_MANAGER_H_
-# define CIDX_MANAGER_H_
-
-#include "openjpeg.h"
-
-
-/* 
- * Write Codestream index box (superbox)
- *
- * @param[in] offset    offset of j2k codestream
- * @param[in] cio       file output handle
- * @param[in] image     image data
- * @param[in] cstr_info codestream information
- * @param[in] j2klen    length of j2k codestream
- * @return              length of cidx box
- */
-int write_cidx( int offset, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t cstr_info, int j2klen);
-
-
-#endif      /* !CIDX_MANAGER_H_ */
+/*
+ * $Id: cidx_manager.h,v 1.4 2014/03/16 12:29:52 drolon Exp $
+ *
+ * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2011, Professor Benoit Macq
+ * Copyright (c) 2003-2004, Yannick Verschueren
+ * Copyright (c) 2010-2011, Kaori Hagihara
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*! \file
+ *  \brief Modification of jpip.h from 2KAN indexer
+ */
+
+
+#ifndef  CIDX_MANAGER_H_
+# define CIDX_MANAGER_H_
+
+#include "openjpeg.h"
+
+
+/* 
+ * Write Codestream index box (superbox)
+ *
+ * @param[in] offset    offset of j2k codestream
+ * @param[in] cio       file output handle
+ * @param[in] image     image data
+ * @param[in] cstr_info codestream information
+ * @param[in] j2klen    length of j2k codestream
+ * @return              length of cidx box
+ */
+int opj_write_cidx( int offset, opj_stream_private_t *cio, opj_codestream_info_t cstr_info, int j2klen,
+              opj_event_mgr_t * p_manager );
+
+/* 
+ * Check if EPH option is used
+ *
+ * @param[in] coff    offset of j2k codestream
+ * @param[in] markers marker information
+ * @param[in] marknum number of markers
+ * @param[in] cio     file output handle
+ * @return            true if EPH is used
+ */
+OPJ_BOOL opj_check_EPHuse( int coff, opj_marker_info_t *markers, int marknum, opj_stream_private_t *cio,
+              opj_event_mgr_t * p_manager );
+
+#endif      /* !CIDX_MANAGER_H_ */
diff --git a/Source/LibOpenJPEG/cio.c b/Source/LibOpenJPEG/cio.c
index 1a428ed..f7f1bc7 100644
--- a/Source/LibOpenJPEG/cio.c
+++ b/Source/LibOpenJPEG/cio.c
@@ -1,191 +1,644 @@
-/*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
- * Copyright (c) 2001-2003, David Janssens
- * Copyright (c) 2002-2003, Yannick Verschueren
- * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "opj_includes.h"
-
-/* ----------------------------------------------------------------------- */
-
-opj_cio_t* OPJ_CALLCONV opj_cio_open(opj_common_ptr cinfo, unsigned char *buffer, int length) {
-	opj_cp_t *cp = NULL;
-	opj_cio_t *cio = (opj_cio_t*)opj_malloc(sizeof(opj_cio_t));
-	if(!cio) return NULL;
-	cio->cinfo = cinfo;
-	if(buffer && length) {
-		/* wrap a user buffer containing the encoded image */
-		cio->openmode = OPJ_STREAM_READ;
-		cio->buffer = buffer;
-		cio->length = length;
-	}
-	else if(!buffer && !length && cinfo) {
-		/* allocate a buffer for the encoded image */
-		cio->openmode = OPJ_STREAM_WRITE;
-		switch(cinfo->codec_format) {
-			case CODEC_J2K:
-				cp = ((opj_j2k_t*)cinfo->j2k_handle)->cp;
-				break;
-			case CODEC_JP2:
-				cp = ((opj_jp2_t*)cinfo->jp2_handle)->j2k->cp;
-				break;
-			default:
-				opj_free(cio);
-				return NULL;
-		}
-		cio->length = (unsigned int) (0.1625 * cp->img_size + 2000); /* 0.1625 = 1.3/8 and 2000 bytes as a minimum for headers */
-		cio->buffer = (unsigned char *)opj_malloc(cio->length);
-		if(!cio->buffer) {
-			opj_event_msg(cio->cinfo, EVT_ERROR, "Error allocating memory for compressed bitstream\n");
-			opj_free(cio);
-			return NULL;
-		}
-	}
-	else {
-		opj_free(cio);
-		return NULL;
-	}
-
-	/* Initialize byte IO */
-	cio->start = cio->buffer;
-	cio->end = cio->buffer + cio->length;
-	cio->bp = cio->buffer;
-
-	return cio;
-}
-
-void OPJ_CALLCONV opj_cio_close(opj_cio_t *cio) {
-	if(cio) {
-		if(cio->openmode == OPJ_STREAM_WRITE) {
-			/* destroy the allocated buffer */
-			opj_free(cio->buffer);
-		}
-		/* destroy the cio */
-		opj_free(cio);
-	}
-}
-
-
-/* ----------------------------------------------------------------------- */
-
-/*
- * Get position in byte stream.
- */
-int OPJ_CALLCONV cio_tell(opj_cio_t *cio) {
-	return cio->bp - cio->start;
-}
-
-/*
- * Set position in byte stream.
- *
- * pos : position, in number of bytes, from the beginning of the stream
- */
-void OPJ_CALLCONV cio_seek(opj_cio_t *cio, int pos) {
-	cio->bp = cio->start + pos;
-}
-
-/*
- * Number of bytes left before the end of the stream.
- */
-int cio_numbytesleft(opj_cio_t *cio) {
-	return cio->end - cio->bp;
-}
-
-/*
- * Get pointer to the current position in the stream.
- */
-unsigned char *cio_getbp(opj_cio_t *cio) {
-	return cio->bp;
-}
-
-/*
- * Write a byte.
- */
-opj_bool cio_byteout(opj_cio_t *cio, unsigned char v) {
-	if (cio->bp >= cio->end) {
-		opj_event_msg(cio->cinfo, EVT_ERROR, "write error\n");
-		return OPJ_FALSE;
-	}
-	*cio->bp++ = v;
-	return OPJ_TRUE;
-}
-
-/*
- * Read a byte.
- */
-unsigned char cio_bytein(opj_cio_t *cio) {
-	if (cio->bp >= cio->end) {
-		opj_event_msg(cio->cinfo, EVT_ERROR, "read error: passed the end of the codestream (start = %d, current = %d, end = %d\n", cio->start, cio->bp, cio->end);
-		return 0;
-	}
-	return *cio->bp++;
-}
-
-/*
- * Write some bytes.
- *
- * v : value to write
- * n : number of bytes to write
- */
-unsigned int cio_write(opj_cio_t *cio, unsigned int64 v, int n) {
-	int i;
-	for (i = n - 1; i >= 0; i--) {
-		if( !cio_byteout(cio, (unsigned char) ((v >> (i << 3)) & 0xff)) )
-			return 0;
-	}
-	return n;
-}
-
-/*
- * Read some bytes.
- *
- * n : number of bytes to read
- *
- * return : value of the n bytes read
- */
-unsigned int cio_read(opj_cio_t *cio, int n) {
-	int i;
-	unsigned int v;
-	v = 0;
-	for (i = n - 1; i >= 0; i--) {
-		v += cio_bytein(cio) << (i << 3);
-	}
-	return v;
-}
-
-/* 
- * Skip some bytes.
- *
- * n : number of bytes to skip
- */
-void cio_skip(opj_cio_t *cio, int n) {
-	cio->bp += n;
-}
-
-
-
+/*
+ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2007, Professor Benoit Macq
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2008;2011-2012, Centre National d'Etudes Spatiales (CNES), France 
+ * Copyright (c) 2012, CS Systemes d'Information, France
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "opj_includes.h"
+
+/* ----------------------------------------------------------------------- */
+
+
+/* ----------------------------------------------------------------------- */
+
+void opj_write_bytes_BE (OPJ_BYTE * p_buffer, OPJ_UINT32 p_value, OPJ_UINT32 p_nb_bytes)
+{
+	const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value) + p_nb_bytes;
+
+	assert(p_nb_bytes > 0 && p_nb_bytes <=  sizeof(OPJ_UINT32));
+
+	memcpy(p_buffer,l_data_ptr,p_nb_bytes);
+}
+
+void opj_write_bytes_LE (OPJ_BYTE * p_buffer, OPJ_UINT32 p_value, OPJ_UINT32 p_nb_bytes)
+{
+	const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value) + p_nb_bytes - 1;
+	OPJ_UINT32 i;
+
+	assert(p_nb_bytes > 0 && p_nb_bytes <= sizeof(OPJ_UINT32));
+
+	for	(i=0;i<p_nb_bytes;++i) {
+		*(p_buffer++) = *(l_data_ptr--);
+	}
+}
+
+void opj_read_bytes_BE(const OPJ_BYTE * p_buffer, OPJ_UINT32 * p_value, OPJ_UINT32 p_nb_bytes)
+{
+	OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value);
+
+	assert(p_nb_bytes > 0 && p_nb_bytes <= sizeof(OPJ_UINT32));
+
+	*p_value = 0;
+	memcpy(l_data_ptr+4-p_nb_bytes,p_buffer,p_nb_bytes);
+}
+
+void opj_read_bytes_LE(const OPJ_BYTE * p_buffer, OPJ_UINT32 * p_value, OPJ_UINT32 p_nb_bytes)
+{
+	OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value) + p_nb_bytes-1;
+	OPJ_UINT32 i;
+
+	assert(p_nb_bytes > 0 && p_nb_bytes <= sizeof(OPJ_UINT32));
+
+	*p_value = 0;
+	for (i=0;i<p_nb_bytes;++i) {
+		*(l_data_ptr--) = *(p_buffer++);
+	}
+}
+
+void opj_write_double_BE(OPJ_BYTE * p_buffer, OPJ_FLOAT64 p_value)
+{
+	const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value);
+	memcpy(p_buffer,l_data_ptr,sizeof(OPJ_FLOAT64));
+}
+
+void opj_write_double_LE(OPJ_BYTE * p_buffer, OPJ_FLOAT64 p_value)
+{
+	const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value) + sizeof(OPJ_FLOAT64) - 1;
+	OPJ_UINT32 i;
+	for	(i=0;i<sizeof(OPJ_FLOAT64);++i) {
+		*(p_buffer++) = *(l_data_ptr--);
+	}
+}
+
+void opj_read_double_BE(const OPJ_BYTE * p_buffer, OPJ_FLOAT64 * p_value)
+{
+	OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value);
+	memcpy(l_data_ptr,p_buffer,sizeof(OPJ_FLOAT64));
+}
+
+void opj_read_double_LE(const OPJ_BYTE * p_buffer, OPJ_FLOAT64 * p_value)
+{
+	OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value) + sizeof(OPJ_FLOAT64)-1;
+	OPJ_UINT32 i;
+	for (i=0;i<sizeof(OPJ_FLOAT64);++i) {
+		*(l_data_ptr--) = *(p_buffer++);
+	}
+}
+
+void opj_write_float_BE(OPJ_BYTE * p_buffer, OPJ_FLOAT32 p_value)
+{
+	const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value);
+	memcpy(p_buffer,l_data_ptr,sizeof(OPJ_FLOAT32));
+}
+
+void opj_write_float_LE(OPJ_BYTE * p_buffer, OPJ_FLOAT32 p_value)
+{
+	const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value) + sizeof(OPJ_FLOAT32) - 1;
+	OPJ_UINT32 i;
+	for	(i=0;i<sizeof(OPJ_FLOAT32);++i) {
+		*(p_buffer++) = *(l_data_ptr--);
+	}
+}
+
+void opj_read_float_BE(const OPJ_BYTE * p_buffer, OPJ_FLOAT32 * p_value)
+{
+	OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value);
+	memcpy(l_data_ptr,p_buffer,sizeof(OPJ_FLOAT32));
+}
+
+void opj_read_float_LE(const OPJ_BYTE * p_buffer, OPJ_FLOAT32 * p_value)
+{
+	OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value) + sizeof(OPJ_FLOAT32)-1;
+	OPJ_UINT32 i;
+	for	(i=0;i<sizeof(OPJ_FLOAT32);++i) {
+		*(l_data_ptr--) = *(p_buffer++);
+	}
+}
+
+opj_stream_t* OPJ_CALLCONV opj_stream_create(OPJ_SIZE_T p_buffer_size,OPJ_BOOL l_is_input)
+{
+	opj_stream_private_t * l_stream = 00;
+	l_stream = (opj_stream_private_t*) opj_malloc(sizeof(opj_stream_private_t));
+	if (! l_stream) {
+		return 00;
+	}
+
+	memset(l_stream,0,sizeof(opj_stream_private_t));
+	l_stream->m_buffer_size = p_buffer_size;
+	l_stream->m_stored_data = (OPJ_BYTE *) opj_malloc(p_buffer_size);
+	if (! l_stream->m_stored_data) {
+		opj_free(l_stream);
+		return 00;
+	}
+
+	l_stream->m_current_data = l_stream->m_stored_data;
+
+	if (l_is_input) {
+		l_stream->m_status |= opj_stream_e_input;
+		l_stream->m_opj_skip = opj_stream_read_skip;
+		l_stream->m_opj_seek = opj_stream_read_seek;
+	}
+	else {
+		l_stream->m_status |= opj_stream_e_output;
+		l_stream->m_opj_skip = opj_stream_write_skip;
+		l_stream->m_opj_seek = opj_stream_write_seek;
+	}
+
+	l_stream->m_read_fn = opj_stream_default_read;
+	l_stream->m_write_fn = opj_stream_default_write;
+	l_stream->m_skip_fn = opj_stream_default_skip;
+	l_stream->m_seek_fn = opj_stream_default_seek;
+
+	return (opj_stream_t *) l_stream;
+}
+
+opj_stream_t* OPJ_CALLCONV opj_stream_default_create(OPJ_BOOL l_is_input)
+{
+	return opj_stream_create(OPJ_J2K_STREAM_CHUNK_SIZE,l_is_input);
+}
+
+void OPJ_CALLCONV opj_stream_destroy(opj_stream_t* p_stream)
+{
+	opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
+	
+	if (l_stream) {
+		if (l_stream->m_free_user_data_fn) {
+			l_stream->m_free_user_data_fn(l_stream->m_user_data);
+		}
+		opj_free(l_stream->m_stored_data);
+		l_stream->m_stored_data = 00;
+		opj_free(l_stream);
+	}
+}
+
+void OPJ_CALLCONV opj_stream_destroy_v3(opj_stream_t* p_stream)
+{
+	opj_stream_destroy(p_stream);
+}
+
+void OPJ_CALLCONV opj_stream_set_read_function(opj_stream_t* p_stream, opj_stream_read_fn p_function)
+{
+	opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
+
+	if ((!l_stream) || (! (l_stream->m_status & opj_stream_e_input))) {
+		return;
+	}
+
+	l_stream->m_read_fn = p_function;
+}
+
+void OPJ_CALLCONV opj_stream_set_seek_function(opj_stream_t* p_stream, opj_stream_seek_fn p_function)
+{
+	opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
+	
+	if (!l_stream) {
+		return;
+	}
+	l_stream->m_seek_fn = p_function;
+}
+
+void OPJ_CALLCONV opj_stream_set_write_function(opj_stream_t* p_stream, opj_stream_write_fn p_function)
+{
+	opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
+	
+	if ((!l_stream )|| (! (l_stream->m_status & opj_stream_e_output))) {
+		return;
+	}
+
+	l_stream->m_write_fn = p_function;
+}
+
+void OPJ_CALLCONV opj_stream_set_skip_function(opj_stream_t* p_stream, opj_stream_skip_fn p_function)
+{
+	opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
+	
+	if (! l_stream) {
+		return;
+	}
+
+	l_stream->m_skip_fn = p_function;
+}
+
+void OPJ_CALLCONV opj_stream_set_user_data(opj_stream_t* p_stream, void * p_data, opj_stream_free_user_data_fn p_function)
+{
+	opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
+	if (!l_stream)
+		return;
+	l_stream->m_user_data = p_data;
+  l_stream->m_free_user_data_fn = p_function;
+}
+
+void OPJ_CALLCONV opj_stream_set_user_data_length(opj_stream_t* p_stream, OPJ_UINT64 data_length)
+{
+	opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
+	if (!l_stream)
+		return;
+	l_stream->m_user_data_length = data_length;
+}
+
+OPJ_SIZE_T opj_stream_read_data (opj_stream_private_t * p_stream,OPJ_BYTE * p_buffer, OPJ_SIZE_T p_size, opj_event_mgr_t * p_event_mgr)
+{
+	OPJ_SIZE_T l_read_nb_bytes = 0;
+	if (p_stream->m_bytes_in_buffer >= p_size) {
+		memcpy(p_buffer,p_stream->m_current_data,p_size);
+		p_stream->m_current_data += p_size;
+		p_stream->m_bytes_in_buffer -= p_size;
+		l_read_nb_bytes += p_size;
+		p_stream->m_byte_offset += (OPJ_OFF_T)p_size;
+		return l_read_nb_bytes;
+	}
+
+	/* we are now in the case when the remaining data if not sufficient */
+	if (p_stream->m_status & opj_stream_e_end) {
+		l_read_nb_bytes += p_stream->m_bytes_in_buffer;
+		memcpy(p_buffer,p_stream->m_current_data,p_stream->m_bytes_in_buffer);
+		p_stream->m_current_data += p_stream->m_bytes_in_buffer;
+		p_stream->m_byte_offset += (OPJ_OFF_T)p_stream->m_bytes_in_buffer;
+		p_stream->m_bytes_in_buffer = 0;
+		return l_read_nb_bytes ? l_read_nb_bytes : (OPJ_SIZE_T)-1;
+	}
+
+	/* the flag is not set, we copy data and then do an actual read on the stream */
+	if (p_stream->m_bytes_in_buffer) {
+		l_read_nb_bytes += p_stream->m_bytes_in_buffer;
+		memcpy(p_buffer,p_stream->m_current_data,p_stream->m_bytes_in_buffer);
+		p_stream->m_current_data = p_stream->m_stored_data;
+		p_buffer += p_stream->m_bytes_in_buffer;
+		p_size -= p_stream->m_bytes_in_buffer;
+		p_stream->m_byte_offset += (OPJ_OFF_T)p_stream->m_bytes_in_buffer;
+		p_stream->m_bytes_in_buffer = 0;
+	}
+	else {
+    /* case where we are already at the end of the buffer
+       so reset the m_current_data to point to the start of the
+       stored buffer to get ready to read from disk*/
+		p_stream->m_current_data = p_stream->m_stored_data;
+	}
+
+	while(1){
+		/* we should read less than a chunk -> read a chunk */
+		if (p_size < p_stream->m_buffer_size) {
+			/* we should do an actual read on the media */
+			p_stream->m_bytes_in_buffer = p_stream->m_read_fn(p_stream->m_stored_data,p_stream->m_buffer_size,p_stream->m_user_data);
+
+			if (p_stream->m_bytes_in_buffer == (OPJ_SIZE_T)-1) {
+				/* end of stream */
+				opj_event_msg(p_event_mgr, EVT_INFO, "Stream reached its end !\n");
+
+				p_stream->m_bytes_in_buffer = 0;
+				p_stream->m_status |= opj_stream_e_end;
+				/* end of stream */
+				return l_read_nb_bytes ? l_read_nb_bytes : (OPJ_SIZE_T)-1;
+			}
+			else if	(p_stream->m_bytes_in_buffer < p_size) {
+				/* not enough data */
+				l_read_nb_bytes += p_stream->m_bytes_in_buffer;
+				memcpy(p_buffer,p_stream->m_current_data,p_stream->m_bytes_in_buffer);
+				p_stream->m_current_data = p_stream->m_stored_data;
+				p_buffer += p_stream->m_bytes_in_buffer;
+				p_size -= p_stream->m_bytes_in_buffer;
+				p_stream->m_byte_offset += (OPJ_OFF_T)p_stream->m_bytes_in_buffer;
+				p_stream->m_bytes_in_buffer = 0;
+			}
+			else {
+				l_read_nb_bytes += p_size;
+				memcpy(p_buffer,p_stream->m_current_data,p_size);
+				p_stream->m_current_data += p_size;
+				p_stream->m_bytes_in_buffer -= p_size;
+				p_stream->m_byte_offset += (OPJ_OFF_T)p_size;
+				return l_read_nb_bytes;
+			}
+		}
+		else {
+			/* direct read on the dest buffer */
+			p_stream->m_bytes_in_buffer = p_stream->m_read_fn(p_buffer,p_size,p_stream->m_user_data);
+
+			if (p_stream->m_bytes_in_buffer == (OPJ_SIZE_T)-1) {
+				/*  end of stream */
+				opj_event_msg(p_event_mgr, EVT_INFO, "Stream reached its end !\n");
+
+				p_stream->m_bytes_in_buffer = 0;
+				p_stream->m_status |= opj_stream_e_end;
+				/* end of stream */
+				return l_read_nb_bytes ? l_read_nb_bytes : (OPJ_SIZE_T)-1;
+			}
+			else if (p_stream->m_bytes_in_buffer < p_size) {
+				/* not enough data */
+				l_read_nb_bytes += p_stream->m_bytes_in_buffer;
+				p_stream->m_current_data = p_stream->m_stored_data;
+				p_buffer += p_stream->m_bytes_in_buffer;
+				p_size -= p_stream->m_bytes_in_buffer;
+				p_stream->m_byte_offset += (OPJ_OFF_T)p_stream->m_bytes_in_buffer;
+				p_stream->m_bytes_in_buffer = 0;
+			}
+			else {
+				/* we have read the exact size */
+				l_read_nb_bytes += p_stream->m_bytes_in_buffer;
+				p_stream->m_byte_offset += (OPJ_OFF_T)p_stream->m_bytes_in_buffer;
+				p_stream->m_current_data = p_stream->m_stored_data;
+				p_stream->m_bytes_in_buffer = 0;
+				return l_read_nb_bytes;
+			}
+		}
+	}
+}
+
+OPJ_SIZE_T opj_stream_write_data (opj_stream_private_t * p_stream,
+								  const OPJ_BYTE * p_buffer,
+								  OPJ_SIZE_T p_size, 
+								  opj_event_mgr_t * p_event_mgr)
+{
+	OPJ_SIZE_T l_remaining_bytes = 0;
+	OPJ_SIZE_T l_write_nb_bytes = 0;
+
+	if (p_stream->m_status & opj_stream_e_error) {
+		return (OPJ_SIZE_T)-1;
+	}
+
+	while(1) {
+		l_remaining_bytes = p_stream->m_buffer_size - p_stream->m_bytes_in_buffer;
+		
+		/* we have more memory than required */
+		if (l_remaining_bytes >= p_size) {
+			memcpy(p_stream->m_current_data, p_buffer, p_size);
+			
+			p_stream->m_current_data += p_size;
+			p_stream->m_bytes_in_buffer += p_size;
+			l_write_nb_bytes += p_size;
+			p_stream->m_byte_offset += (OPJ_OFF_T)p_size;
+			
+			return l_write_nb_bytes;
+		}
+
+		/* we copy data and then do an actual read on the stream */
+		if (l_remaining_bytes) {
+			l_write_nb_bytes += l_remaining_bytes;
+			
+			memcpy(p_stream->m_current_data,p_buffer,l_remaining_bytes);
+			
+			p_stream->m_current_data = p_stream->m_stored_data;
+			
+			p_buffer += l_remaining_bytes;
+			p_size -= l_remaining_bytes;
+			p_stream->m_bytes_in_buffer += l_remaining_bytes;
+			p_stream->m_byte_offset += (OPJ_OFF_T)l_remaining_bytes;
+		}
+
+		if (! opj_stream_flush(p_stream, p_event_mgr)) {
+			return (OPJ_SIZE_T)-1;
+		}
+	}
+
+}
+
+OPJ_BOOL opj_stream_flush (opj_stream_private_t * p_stream, opj_event_mgr_t * p_event_mgr)
+{
+	/* the number of bytes written on the media. */
+	OPJ_SIZE_T l_current_write_nb_bytes = 0;
+
+	p_stream->m_current_data = p_stream->m_stored_data;
+
+	while (p_stream->m_bytes_in_buffer) {
+		/* we should do an actual write on the media */
+		l_current_write_nb_bytes = p_stream->m_write_fn(p_stream->m_current_data,
+														p_stream->m_bytes_in_buffer,
+														p_stream->m_user_data);
+		
+		if (l_current_write_nb_bytes == (OPJ_SIZE_T)-1) {
+			p_stream->m_status |= opj_stream_e_error;
+			opj_event_msg(p_event_mgr, EVT_INFO, "Error on writing stream!\n");
+
+			return OPJ_FALSE;
+		}
+
+		p_stream->m_current_data += l_current_write_nb_bytes;
+		p_stream->m_bytes_in_buffer -= l_current_write_nb_bytes;
+	}
+
+	p_stream->m_current_data = p_stream->m_stored_data;
+	
+	return OPJ_TRUE;
+}
+
+OPJ_OFF_T opj_stream_read_skip (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, opj_event_mgr_t * p_event_mgr)
+{
+	OPJ_OFF_T l_skip_nb_bytes = 0;
+	OPJ_OFF_T l_current_skip_nb_bytes = 0;
+	
+	assert( p_size >= 0 );
+	
+	if (p_stream->m_bytes_in_buffer >= (OPJ_SIZE_T)p_size) {
+		p_stream->m_current_data += p_size;
+		/* it is safe to cast p_size to OPJ_SIZE_T since it is <= m_bytes_in_buffer
+		which is of type OPJ_SIZE_T */
+		p_stream->m_bytes_in_buffer -= (OPJ_SIZE_T)p_size;
+		l_skip_nb_bytes += p_size;
+		p_stream->m_byte_offset += l_skip_nb_bytes;
+		return l_skip_nb_bytes;
+	}
+
+	/* we are now in the case when the remaining data if not sufficient */
+	if (p_stream->m_status & opj_stream_e_end) {
+		l_skip_nb_bytes += (OPJ_OFF_T)p_stream->m_bytes_in_buffer;
+		p_stream->m_current_data += p_stream->m_bytes_in_buffer;
+		p_stream->m_bytes_in_buffer = 0;
+		p_stream->m_byte_offset += l_skip_nb_bytes;
+		return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_OFF_T) -1;
+	}
+
+	/* the flag is not set, we copy data and then do an actual skip on the stream */
+	if (p_stream->m_bytes_in_buffer) {
+		l_skip_nb_bytes += (OPJ_OFF_T)p_stream->m_bytes_in_buffer;
+		p_stream->m_current_data = p_stream->m_stored_data;
+		p_size -= (OPJ_OFF_T)p_stream->m_bytes_in_buffer;
+		p_stream->m_bytes_in_buffer = 0;
+	}
+
+	while (p_size > 0) {
+		/* we should do an actual skip on the media */
+		l_current_skip_nb_bytes = p_stream->m_skip_fn(p_size, p_stream->m_user_data);
+		if (l_current_skip_nb_bytes == (OPJ_OFF_T) -1) {
+			opj_event_msg(p_event_mgr, EVT_INFO, "Stream reached its end !\n");
+
+			p_stream->m_status |= opj_stream_e_end;
+			p_stream->m_byte_offset += l_skip_nb_bytes;
+			/* end if stream */
+			return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_OFF_T) -1;
+		}
+		p_size -= l_current_skip_nb_bytes;
+		l_skip_nb_bytes += l_current_skip_nb_bytes;
+	}
+
+	p_stream->m_byte_offset += l_skip_nb_bytes;
+	
+	return l_skip_nb_bytes;
+}
+
+OPJ_OFF_T opj_stream_write_skip (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, opj_event_mgr_t * p_event_mgr)
+{
+	OPJ_BOOL l_is_written = 0;
+	OPJ_OFF_T l_current_skip_nb_bytes = 0;
+	OPJ_OFF_T l_skip_nb_bytes = 0;
+
+	if (p_stream->m_status & opj_stream_e_error) {
+		return (OPJ_OFF_T) -1;
+	}
+
+	/* we should flush data */
+	l_is_written = opj_stream_flush (p_stream, p_event_mgr);
+	if (! l_is_written) {
+		p_stream->m_status |= opj_stream_e_error;
+		p_stream->m_bytes_in_buffer = 0;
+		return (OPJ_OFF_T) -1;
+	}
+	/* then skip */
+
+	while (p_size > 0) {
+		/* we should do an actual skip on the media */
+		l_current_skip_nb_bytes = p_stream->m_skip_fn(p_size, p_stream->m_user_data);
+		
+		if (l_current_skip_nb_bytes == (OPJ_OFF_T)-1) {
+			opj_event_msg(p_event_mgr, EVT_INFO, "Stream error!\n");
+
+			p_stream->m_status |= opj_stream_e_error;
+			p_stream->m_byte_offset += l_skip_nb_bytes;
+			/* end if stream */
+			return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_OFF_T)-1;
+		}
+		p_size -= l_current_skip_nb_bytes;
+		l_skip_nb_bytes += l_current_skip_nb_bytes;
+	}
+
+	p_stream->m_byte_offset += l_skip_nb_bytes;
+	
+	return l_skip_nb_bytes;
+}
+
+OPJ_OFF_T opj_stream_tell (const opj_stream_private_t * p_stream)
+{
+	return p_stream->m_byte_offset;
+}
+
+OPJ_OFF_T opj_stream_get_number_byte_left (const opj_stream_private_t * p_stream)
+{
+  assert( p_stream->m_byte_offset >= 0 );
+  assert( p_stream->m_user_data_length >= (OPJ_UINT64)p_stream->m_byte_offset);
+  return p_stream->m_user_data_length ?
+				(OPJ_OFF_T)(p_stream->m_user_data_length) - p_stream->m_byte_offset :
+				0;
+}
+
+OPJ_OFF_T opj_stream_skip (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, opj_event_mgr_t * p_event_mgr)
+{
+	assert(p_size >= 0);
+	return p_stream->m_opj_skip(p_stream,p_size,p_event_mgr);
+}
+
+OPJ_BOOL opj_stream_read_seek (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, opj_event_mgr_t * p_event_mgr)
+{
+	OPJ_ARG_NOT_USED(p_event_mgr);
+	p_stream->m_current_data = p_stream->m_stored_data;
+	p_stream->m_bytes_in_buffer = 0;
+
+	if( !(p_stream->m_seek_fn(p_size,p_stream->m_user_data)) ) {
+		p_stream->m_status |= opj_stream_e_end;
+		return OPJ_FALSE;
+	}
+	else {
+		/* reset stream status */
+		p_stream->m_status &= (~opj_stream_e_end);
+		p_stream->m_byte_offset = p_size;
+
+	}
+
+	return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_stream_write_seek (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, opj_event_mgr_t * p_event_mgr)
+{
+	if (! opj_stream_flush(p_stream,p_event_mgr)) {
+		p_stream->m_status |= opj_stream_e_error;
+		return OPJ_FALSE;
+	}
+
+	p_stream->m_current_data = p_stream->m_stored_data;
+	p_stream->m_bytes_in_buffer = 0;
+
+	if (! p_stream->m_seek_fn(p_size,p_stream->m_user_data)) {
+		p_stream->m_status |= opj_stream_e_error;
+		return OPJ_FALSE;
+	}
+	else {
+		p_stream->m_byte_offset = p_size;
+	}
+
+	return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_stream_seek (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, struct opj_event_mgr * p_event_mgr)
+{
+	assert(p_size >= 0);
+	return p_stream->m_opj_seek(p_stream,p_size,p_event_mgr);
+}
+
+OPJ_BOOL opj_stream_has_seek (const opj_stream_private_t * p_stream)
+{
+	return p_stream->m_seek_fn != opj_stream_default_seek;
+}
+
+OPJ_SIZE_T opj_stream_default_read (void * p_buffer, OPJ_SIZE_T p_nb_bytes, void * p_user_data)
+{
+	OPJ_ARG_NOT_USED(p_buffer);
+	OPJ_ARG_NOT_USED(p_nb_bytes);
+	OPJ_ARG_NOT_USED(p_user_data);
+	return (OPJ_SIZE_T) -1;
+}
+
+OPJ_SIZE_T opj_stream_default_write (void * p_buffer, OPJ_SIZE_T p_nb_bytes, void * p_user_data)
+{
+	OPJ_ARG_NOT_USED(p_buffer);
+	OPJ_ARG_NOT_USED(p_nb_bytes);
+	OPJ_ARG_NOT_USED(p_user_data);
+	return (OPJ_SIZE_T) -1;
+}
+
+OPJ_OFF_T opj_stream_default_skip (OPJ_OFF_T p_nb_bytes, void * p_user_data)
+{
+	OPJ_ARG_NOT_USED(p_nb_bytes);
+	OPJ_ARG_NOT_USED(p_user_data);
+	return (OPJ_OFF_T) -1;
+}
+
+OPJ_BOOL opj_stream_default_seek (OPJ_OFF_T p_nb_bytes, void * p_user_data)
+{
+	OPJ_ARG_NOT_USED(p_nb_bytes);
+	OPJ_ARG_NOT_USED(p_user_data);
+	return OPJ_FALSE;
+}
diff --git a/Source/LibOpenJPEG/cio.h b/Source/LibOpenJPEG/cio.h
index cccaf91..edbc200 100644
--- a/Source/LibOpenJPEG/cio.h
+++ b/Source/LibOpenJPEG/cio.h
@@ -1,93 +1,393 @@
-/*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
- * Copyright (c) 2001-2003, David Janssens
- * Copyright (c) 2002-2003, Yannick Verschueren
- * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __CIO_H
-#define __CIO_H
-
-#if defined(_MSC_VER) || defined(__BORLANDC__)
-#define int64 __int64
-#else
-#define int64 long long
-#endif
-
-/**
- at file cio.h
- at brief Implementation of a byte input-output process (CIO)
-
-The functions in CIO.C have for goal to realize a byte input / output process.
-*/
-
-/** @defgroup CIO CIO - byte input-output stream */
-/*@{*/
-
-/** @name Exported functions (see also openjpeg.h) */
-/*@{*/
-/* ----------------------------------------------------------------------- */
-/**
-Number of bytes left before the end of the stream
- at param cio CIO handle
- at return Returns the number of bytes before the end of the stream
-*/
-int cio_numbytesleft(opj_cio_t *cio);
-/**
-Get pointer to the current position in the stream
- at param cio CIO handle
- at return Returns a pointer to the current position
-*/
-unsigned char *cio_getbp(opj_cio_t *cio);
-/**
-Write some bytes
- at param cio CIO handle
- at param v Value to write
- at param n Number of bytes to write
- at return Returns the number of bytes written or 0 if an error occured
-*/
-unsigned int cio_write(opj_cio_t *cio, unsigned int64 v, int n);
-/**
-Read some bytes
- at param cio CIO handle
- at param n Number of bytes to read
- at return Returns the value of the n bytes read
-*/
-unsigned int cio_read(opj_cio_t *cio, int n);
-/**
-Skip some bytes
- at param cio CIO handle
- at param n Number of bytes to skip
-*/
-void cio_skip(opj_cio_t *cio, int n);
-/* ----------------------------------------------------------------------- */
-/*@}*/
-
-/*@}*/
-
-#endif /* __CIO_H */
-
+/*
+ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2007, Professor Benoit Macq
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2008;2011-2012, Centre National d'Etudes Spatiales (CNES), France 
+ * Copyright (c) 2012, CS Systemes d'Information, France
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __CIO_H
+#define __CIO_H
+/**
+ at file cio.h
+ at brief Implementation of a byte input-output process (CIO)
+
+The functions in CIO.C have for goal to realize a byte input / output process.
+*/
+
+/** @defgroup CIO CIO - byte input-output stream */
+/*@{*/
+
+#include "opj_config.h"
+
+/* ----------------------------------------------------------------------- */
+
+#if defined(OPJ_BIG_ENDIAN)
+	#define opj_write_bytes		opj_write_bytes_BE
+	#define opj_read_bytes		opj_read_bytes_BE
+	#define opj_write_double	opj_write_double_BE
+	#define opj_read_double		opj_read_double_BE
+	#define opj_write_float		opj_write_float_BE
+	#define opj_read_float		opj_read_float_BE
+#else
+	#define opj_write_bytes		opj_write_bytes_LE
+	#define opj_read_bytes		opj_read_bytes_LE
+	#define opj_write_double	opj_write_double_LE
+	#define opj_read_double		opj_read_double_LE
+	#define opj_write_float		opj_write_float_LE
+	#define opj_read_float		opj_read_float_LE
+#endif
+
+
+
+typedef enum
+{
+	opj_signed_sentinel		= -1, /* do not use in code */
+	opj_stream_e_output		= 0x1,
+	opj_stream_e_input		= 0x2,
+	opj_stream_e_end		= 0x4,
+	opj_stream_e_error		= 0x8
+}
+opj_stream_flag ;
+
+/**
+Byte input-output stream.
+*/
+typedef struct opj_stream_private
+{
+	/**
+	 * User data, be it files, ... The actual data depends on the type of the stream.
+	 */
+	void *					m_user_data;
+
+	/**
+	 * Pointer to function to free m_user_data (NULL at initialization)
+	 * when destroying the stream. If pointer is NULL the function is not
+	 * called and the m_user_data is not freed (even if non-NULL).
+	 */
+	opj_stream_free_user_data_fn		m_free_user_data_fn;
+
+	/**
+	 * User data length
+	 */
+	OPJ_UINT64 				m_user_data_length;
+
+	/**
+	 * Pointer to actual read function (NULL at the initialization of the cio.
+	 */
+	opj_stream_read_fn		m_read_fn;
+
+	/**
+	 * Pointer to actual write function (NULL at the initialization of the cio.
+	 */
+	opj_stream_write_fn		m_write_fn;
+
+	/**
+	 * Pointer to actual skip function (NULL at the initialization of the cio.
+	 * There is no seek function to prevent from back and forth slow procedures.
+	 */
+	opj_stream_skip_fn		m_skip_fn;
+
+	/**
+	 * Pointer to actual seek function (if available).
+	 */
+	opj_stream_seek_fn		m_seek_fn;
+
+	/**
+	 * Actual data stored into the stream if readed from. Data is read by chunk of fixed size.
+	 * you should never access this data directly.
+	 */
+	OPJ_BYTE *					m_stored_data;
+
+	/**
+	 * Pointer to the current read data.
+	 */
+	OPJ_BYTE *					m_current_data;
+
+    /**
+    * FIXME DOC.
+    */
+	OPJ_OFF_T (* m_opj_skip)(struct opj_stream_private * ,OPJ_OFF_T , struct opj_event_mgr *);
+
+    /**
+    * FIXME DOC.
+    */
+	OPJ_BOOL (* m_opj_seek) (struct opj_stream_private * , OPJ_OFF_T , struct opj_event_mgr *);
+
+	/**
+	 * number of bytes containing in the buffer.
+	 */
+	OPJ_SIZE_T			m_bytes_in_buffer;
+
+	/**
+	 * The number of bytes read/written from the beginning of the stream
+	 */
+	OPJ_OFF_T			m_byte_offset;
+
+	/**
+	 * The size of the buffer.
+	 */
+	OPJ_SIZE_T			m_buffer_size;
+
+	/**
+	 * Flags to tell the status of the stream.
+	 */
+	opj_stream_flag m_status;
+
+}
+opj_stream_private_t;
+
+/** @name Exported functions (see also openjpeg.h) */
+/*@{*/
+/* ----------------------------------------------------------------------- */
+/**
+ * Write some bytes to the given data buffer, this function is used in Big Endian cpus.
+ * @param p_buffer		pointer the data buffer to write data to.
+ * @param p_value		the value to write
+ * @param p_nb_bytes	the number of bytes to write
+*/
+void opj_write_bytes_BE (OPJ_BYTE * p_buffer, OPJ_UINT32 p_value, OPJ_UINT32 p_nb_bytes);
+
+/**
+ * Reads some bytes from the given data buffer, this function is used in Big Endian cpus.
+ * @param p_buffer		pointer the data buffer to read data from.
+ * @param p_value		pointer to the value that will store the data.
+ * @param p_nb_bytes	the nb bytes to read.
+ * @return				the number of bytes read or -1 if an error occured.
+ */
+void opj_read_bytes_BE(const OPJ_BYTE * p_buffer, OPJ_UINT32 * p_value, OPJ_UINT32 p_nb_bytes);
+
+/**
+ * Write some bytes to the given data buffer, this function is used in Little Endian cpus.
+ * @param p_buffer		pointer the data buffer to write data to.
+ * @param p_value		the value to write
+ * @param p_nb_bytes	the number of bytes to write
+ * @return				the number of bytes written or -1 if an error occured
+*/
+void opj_write_bytes_LE (OPJ_BYTE * p_buffer, OPJ_UINT32 p_value, OPJ_UINT32 p_nb_bytes);
+
+/**
+ * Reads some bytes from the given data buffer, this function is used in Little Endian cpus.
+ * @param p_buffer		pointer the data buffer to read data from.
+ * @param p_value		pointer to the value that will store the data.
+ * @param p_nb_bytes	the nb bytes to read.
+ * @return				the number of bytes read or -1 if an error occured.
+ */
+void opj_read_bytes_LE(const OPJ_BYTE * p_buffer, OPJ_UINT32 * p_value, OPJ_UINT32 p_nb_bytes);
+
+
+/**
+ * Write some bytes to the given data buffer, this function is used in Little Endian cpus.
+ * @param p_buffer		pointer the data buffer to write data to.
+ * @param p_value		the value to write
+ */
+void opj_write_double_LE(OPJ_BYTE * p_buffer, OPJ_FLOAT64 p_value);
+
+/***
+ * Write some bytes to the given data buffer, this function is used in Big Endian cpus.
+ * @param p_buffer		pointer the data buffer to write data to.
+ * @param p_value		the value to write
+ */
+void opj_write_double_BE(OPJ_BYTE * p_buffer, OPJ_FLOAT64 p_value);
+
+/**
+ * Reads some bytes from the given data buffer, this function is used in Little Endian cpus.
+ * @param p_buffer		pointer the data buffer to read data from.
+ * @param p_value		pointer to the value that will store the data.
+ */
+void opj_read_double_LE(const OPJ_BYTE * p_buffer, OPJ_FLOAT64 * p_value);
+
+/**
+ * Reads some bytes from the given data buffer, this function is used in Big Endian cpus.
+ * @param p_buffer		pointer the data buffer to read data from.
+ * @param p_value		pointer to the value that will store the data.
+ */
+void opj_read_double_BE(const OPJ_BYTE * p_buffer, OPJ_FLOAT64 * p_value);
+
+/**
+ * Reads some bytes from the given data buffer, this function is used in Little Endian cpus.
+ * @param p_buffer		pointer the data buffer to read data from.
+ * @param p_value		pointer to the value that will store the data.
+ */
+void opj_read_float_LE(const OPJ_BYTE * p_buffer, OPJ_FLOAT32 * p_value);
+
+/**
+ * Reads some bytes from the given data buffer, this function is used in Big Endian cpus.
+ * @param p_buffer		pointer the data buffer to read data from.
+ * @param p_value		pointer to the value that will store the data.
+ */
+void opj_read_float_BE(const OPJ_BYTE * p_buffer, OPJ_FLOAT32 * p_value);
+
+/**
+ * Write some bytes to the given data buffer, this function is used in Little Endian cpus.
+ * @param p_buffer		pointer the data buffer to write data to.
+ * @param p_value		the value to write
+ */
+void opj_write_float_LE(OPJ_BYTE * p_buffer, OPJ_FLOAT32 p_value);
+
+/***
+ * Write some bytes to the given data buffer, this function is used in Big Endian cpus.
+ * @param p_buffer		pointer the data buffer to write data to.
+ * @param p_value		the value to write
+ */
+void opj_write_float_BE(OPJ_BYTE * p_buffer, OPJ_FLOAT32 p_value);
+
+/**
+ * Reads some bytes from the stream.
+ * @param		p_stream	the stream to read data from.
+ * @param		p_buffer	pointer to the data buffer that will receive the data.
+ * @param		p_size		number of bytes to read.
+ * @param		p_event_mgr	the user event manager to be notified of special events.
+ * @return		the number of bytes read, or -1 if an error occured or if the stream is at the end.
+ */
+OPJ_SIZE_T opj_stream_read_data (opj_stream_private_t * p_stream,OPJ_BYTE * p_buffer, OPJ_SIZE_T p_size, struct opj_event_mgr * p_event_mgr);
+
+/**
+ * Writes some bytes to the stream.
+ * @param		p_stream	the stream to write data to.
+ * @param		p_buffer	pointer to the data buffer holds the data to be writtent.
+ * @param		p_size		number of bytes to write.
+ * @param		p_event_mgr	the user event manager to be notified of special events.
+ * @return		the number of bytes writtent, or -1 if an error occured.
+ */
+OPJ_SIZE_T opj_stream_write_data (opj_stream_private_t * p_stream,const OPJ_BYTE * p_buffer, OPJ_SIZE_T p_size, struct opj_event_mgr * p_event_mgr);
+
+/**
+ * Writes the content of the stream buffer to the stream.
+ * @param		p_stream	the stream to write data to.
+ * @param		p_event_mgr	the user event manager to be notified of special events.
+ * @return		true if the data could be flushed, false else.
+ */
+OPJ_BOOL opj_stream_flush (opj_stream_private_t * p_stream, struct opj_event_mgr * p_event_mgr);
+
+/**
+ * Skips a number of bytes from the stream.
+ * @param		p_stream	the stream to skip data from.
+ * @param		p_size		the number of bytes to skip.
+ * @param		p_event_mgr	the user event manager to be notified of special events.
+ * @return		the number of bytes skipped, or -1 if an error occured.
+ */
+OPJ_OFF_T opj_stream_skip (opj_stream_private_t * p_stream,OPJ_OFF_T p_size, struct opj_event_mgr * p_event_mgr);
+
+/**
+ * Tells the byte offset on the stream (similar to ftell).
+ *
+ * @param		p_stream	the stream to get the information from.
+ *
+ * @return		the current position o fthe stream.
+ */
+OPJ_OFF_T opj_stream_tell (const opj_stream_private_t * p_stream);
+
+
+/**
+ * Get the number of bytes left before the end of the stream (similar to cio_numbytesleft).
+ *
+ * @param		p_stream	the stream to get the information from.
+ *
+ * @return		Number of bytes left before the end of the stream.
+ */
+OPJ_OFF_T opj_stream_get_number_byte_left (const opj_stream_private_t * p_stream);
+
+/**
+ * Skips a number of bytes from the stream.
+ * @param		p_stream	the stream to skip data from.
+ * @param		p_size		the number of bytes to skip.
+ * @param		p_event_mgr	the user event manager to be notified of special events.
+ * @return		the number of bytes skipped, or -1 if an error occured.
+ */
+OPJ_OFF_T opj_stream_write_skip (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, struct opj_event_mgr * p_event_mgr);
+
+/**
+ * Skips a number of bytes from the stream.
+ * @param		p_stream	the stream to skip data from.
+ * @param		p_size		the number of bytes to skip.
+ * @param		p_event_mgr	the user event manager to be notified of special events.
+ * @return		the number of bytes skipped, or -1 if an error occured.
+ */
+OPJ_OFF_T opj_stream_read_skip (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, struct opj_event_mgr * p_event_mgr);
+
+/**
+ * Skips a number of bytes from the stream.
+ * @param		p_stream	the stream to skip data from.
+ * @param		p_size		the number of bytes to skip.
+ * @param		p_event_mgr	the user event manager to be notified of special events.
+ * @return		OPJ_TRUE if success, or OPJ_FALSE if an error occured.
+ */
+OPJ_BOOL opj_stream_read_seek (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, struct opj_event_mgr * p_event_mgr);
+
+/**
+ * Skips a number of bytes from the stream.
+ * @param		p_stream	the stream to skip data from.
+ * @param		p_size		the number of bytes to skip.
+ * @param		p_event_mgr	the user event manager to be notified of special events.
+ * @return		the number of bytes skipped, or -1 if an error occured.
+ */
+OPJ_BOOL opj_stream_write_seek (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, struct opj_event_mgr * p_event_mgr);
+
+/**
+ * Seeks a number of bytes from the stream.
+ * @param		p_stream	the stream to skip data from.
+ * @param		p_size		the number of bytes to skip.
+ * @param		p_event_mgr	the user event manager to be notified of special events.
+ * @return		true if the stream is seekable.
+ */
+OPJ_BOOL opj_stream_seek (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, struct opj_event_mgr * p_event_mgr);
+
+/**
+ * Tells if the given stream is seekable.
+ */
+OPJ_BOOL opj_stream_has_seek (const opj_stream_private_t * p_stream);
+
+/**
+ * FIXME DOC.
+ */
+OPJ_SIZE_T opj_stream_default_read (void * p_buffer, OPJ_SIZE_T p_nb_bytes, void * p_user_data);
+
+/**
+ * FIXME DOC.
+ */
+OPJ_SIZE_T opj_stream_default_write (void * p_buffer, OPJ_SIZE_T p_nb_bytes, void * p_user_data);
+
+/**
+ * FIXME DOC.
+ */
+OPJ_OFF_T opj_stream_default_skip (OPJ_OFF_T p_nb_bytes, void * p_user_data);
+
+/**
+ * FIXME DOC.
+ */
+OPJ_BOOL opj_stream_default_seek (OPJ_OFF_T p_nb_bytes, void * p_user_data);
+
+/* ----------------------------------------------------------------------- */
+/*@}*/
+
+/*@}*/
+
+
+#endif /* __CIO_H */
+
diff --git a/Source/LibOpenJPEG/dwt.c b/Source/LibOpenJPEG/dwt.c
index 6f9b12d..b36d68d 100644
--- a/Source/LibOpenJPEG/dwt.c
+++ b/Source/LibOpenJPEG/dwt.c
@@ -1,858 +1,919 @@
-/*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
- * Copyright (c) 2001-2003, David Janssens
- * Copyright (c) 2002-2003, Yannick Verschueren
- * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * Copyright (c) 2007, Jonathan Ballard <dzonatas at dzonux.net>
- * Copyright (c) 2007, Callum Lerwick <seg at haxxed.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifdef __SSE__
-#include <xmmintrin.h>
-#endif
-
-#include "opj_includes.h"
-
-/** @defgroup DWT DWT - Implementation of a discrete wavelet transform */
-/*@{*/
-
-#define WS(i) v->mem[(i)*2]
-#define WD(i) v->mem[(1+(i)*2)]
-
-/** @name Local data structures */
-/*@{*/
-
-typedef struct dwt_local {
-	int* mem;
-	int dn;
-	int sn;
-	int cas;
-} dwt_t;
-
-typedef union {
-	float	f[4];
-} v4;
-
-typedef struct v4dwt_local {
-	v4*	wavelet ;
-	int		dn ;
-	int		sn ;
-	int		cas ;
-} v4dwt_t ;
-
-static const float dwt_alpha =  1.586134342f; /*  12994 */
-static const float dwt_beta  =  0.052980118f; /*    434 */
-static const float dwt_gamma = -0.882911075f; /*  -7233 */
-static const float dwt_delta = -0.443506852f; /*  -3633 */
-
-static const float K      = 1.230174105f; /*  10078 */
-/* FIXME: What is this constant? */
-static const float c13318 = 1.625732422f;
-
-/*@}*/
-
-/**
-Virtual function type for wavelet transform in 1-D 
-*/
-typedef void (*DWT1DFN)(dwt_t* v);
-
-/** @name Local static functions */
-/*@{*/
-
-/**
-Forward lazy transform (horizontal)
-*/
-static void dwt_deinterleave_h(int *a, int *b, int dn, int sn, int cas);
-/**
-Forward lazy transform (vertical)
-*/
-static void dwt_deinterleave_v(int *a, int *b, int dn, int sn, int x, int cas);
-/**
-Inverse lazy transform (horizontal)
-*/
-static void dwt_interleave_h(dwt_t* h, int *a);
-/**
-Inverse lazy transform (vertical)
-*/
-static void dwt_interleave_v(dwt_t* v, int *a, int x);
-/**
-Forward 5-3 wavelet transform in 1-D
-*/
-static void dwt_encode_1(int *a, int dn, int sn, int cas);
-/**
-Inverse 5-3 wavelet transform in 1-D
-*/
-static void dwt_decode_1(dwt_t *v);
-/**
-Forward 9-7 wavelet transform in 1-D
-*/
-static void dwt_encode_1_real(int *a, int dn, int sn, int cas);
-/**
-Explicit calculation of the Quantization Stepsizes 
-*/
-static void dwt_encode_stepsize(int stepsize, int numbps, opj_stepsize_t *bandno_stepsize);
-/**
-Inverse wavelet transform in 2-D.
-*/
-static void dwt_decode_tile(opj_tcd_tilecomp_t* tilec, int i, DWT1DFN fn);
-
-/*@}*/
-
-/*@}*/
-
-#define S(i) a[(i)*2]
-#define D(i) a[(1+(i)*2)]
-#define S_(i) ((i)<0?S(0):((i)>=sn?S(sn-1):S(i)))
-#define D_(i) ((i)<0?D(0):((i)>=dn?D(dn-1):D(i)))
-/* new */
-#define SS_(i) ((i)<0?S(0):((i)>=dn?S(dn-1):S(i)))
-#define DD_(i) ((i)<0?D(0):((i)>=sn?D(sn-1):D(i)))
-
-/* <summary>                                                              */
-/* This table contains the norms of the 5-3 wavelets for different bands. */
-/* </summary>                                                             */
-static const double dwt_norms[4][10] = {
-	{1.000, 1.500, 2.750, 5.375, 10.68, 21.34, 42.67, 85.33, 170.7, 341.3},
-	{1.038, 1.592, 2.919, 5.703, 11.33, 22.64, 45.25, 90.48, 180.9},
-	{1.038, 1.592, 2.919, 5.703, 11.33, 22.64, 45.25, 90.48, 180.9},
-	{.7186, .9218, 1.586, 3.043, 6.019, 12.01, 24.00, 47.97, 95.93}
-};
-
-/* <summary>                                                              */
-/* This table contains the norms of the 9-7 wavelets for different bands. */
-/* </summary>                                                             */
-static const double dwt_norms_real[4][10] = {
-	{1.000, 1.965, 4.177, 8.403, 16.90, 33.84, 67.69, 135.3, 270.6, 540.9},
-	{2.022, 3.989, 8.355, 17.04, 34.27, 68.63, 137.3, 274.6, 549.0},
-	{2.022, 3.989, 8.355, 17.04, 34.27, 68.63, 137.3, 274.6, 549.0},
-	{2.080, 3.865, 8.307, 17.18, 34.71, 69.59, 139.3, 278.6, 557.2}
-};
-
-/* 
-==========================================================
-   local functions
-==========================================================
-*/
-
-/* <summary>			                 */
-/* Forward lazy transform (horizontal).  */
-/* </summary>                            */ 
-static void dwt_deinterleave_h(int *a, int *b, int dn, int sn, int cas) {
-	int i;
-    for (i=0; i<sn; i++) b[i]=a[2*i+cas];
-    for (i=0; i<dn; i++) b[sn+i]=a[(2*i+1-cas)];
-}
-
-/* <summary>                             */  
-/* Forward lazy transform (vertical).    */
-/* </summary>                            */ 
-static void dwt_deinterleave_v(int *a, int *b, int dn, int sn, int x, int cas) {
-    int i;
-    for (i=0; i<sn; i++) b[i*x]=a[2*i+cas];
-    for (i=0; i<dn; i++) b[(sn+i)*x]=a[(2*i+1-cas)];
-}
-
-/* <summary>                             */
-/* Inverse lazy transform (horizontal).  */
-/* </summary>                            */
-static void dwt_interleave_h(dwt_t* h, int *a) {
-    int *ai = a;
-    int *bi = h->mem + h->cas;
-    int  i	= h->sn;
-    while( i-- ) {
-      *bi = *(ai++);
-	  bi += 2;
-    }
-    ai	= a + h->sn;
-    bi	= h->mem + 1 - h->cas;
-    i	= h->dn ;
-    while( i-- ) {
-      *bi = *(ai++);
-	  bi += 2;
-    }
-}
-
-/* <summary>                             */  
-/* Inverse lazy transform (vertical).    */
-/* </summary>                            */ 
-static void dwt_interleave_v(dwt_t* v, int *a, int x) {
-    int *ai = a;
-    int *bi = v->mem + v->cas;
-    int  i = v->sn;
-    while( i-- ) {
-      *bi = *ai;
-	  bi += 2;
-	  ai += x;
-    }
-    ai = a + (v->sn * x);
-    bi = v->mem + 1 - v->cas;
-    i = v->dn ;
-    while( i-- ) {
-      *bi = *ai;
-	  bi += 2;  
-	  ai += x;
-    }
-}
-
-
-/* <summary>                            */
-/* Forward 5-3 wavelet transform in 1-D. */
-/* </summary>                           */
-static void dwt_encode_1(int *a, int dn, int sn, int cas) {
-	int i;
-	
-	if (!cas) {
-		if ((dn > 0) || (sn > 1)) {	/* NEW :  CASE ONE ELEMENT */
-			for (i = 0; i < dn; i++) D(i) -= (S_(i) + S_(i + 1)) >> 1;
-			for (i = 0; i < sn; i++) S(i) += (D_(i - 1) + D_(i) + 2) >> 2;
-		}
-	} else {
-		if (!sn && dn == 1)		    /* NEW :  CASE ONE ELEMENT */
-			S(0) *= 2;
-		else {
-			for (i = 0; i < dn; i++) S(i) -= (DD_(i) + DD_(i - 1)) >> 1;
-			for (i = 0; i < sn; i++) D(i) += (SS_(i) + SS_(i + 1) + 2) >> 2;
-		}
-	}
-}
-
-/* <summary>                            */
-/* Inverse 5-3 wavelet transform in 1-D. */
-/* </summary>                           */ 
-static void dwt_decode_1_(int *a, int dn, int sn, int cas) {
-	int i;
-	
-	if (!cas) {
-		if ((dn > 0) || (sn > 1)) { /* NEW :  CASE ONE ELEMENT */
-			for (i = 0; i < sn; i++) S(i) -= (D_(i - 1) + D_(i) + 2) >> 2;
-			for (i = 0; i < dn; i++) D(i) += (S_(i) + S_(i + 1)) >> 1;
-		}
-	} else {
-		if (!sn  && dn == 1)          /* NEW :  CASE ONE ELEMENT */
-			S(0) /= 2;
-		else {
-			for (i = 0; i < sn; i++) D(i) -= (SS_(i) + SS_(i + 1) + 2) >> 2;
-			for (i = 0; i < dn; i++) S(i) += (DD_(i) + DD_(i - 1)) >> 1;
-		}
-	}
-}
-
-/* <summary>                            */
-/* Inverse 5-3 wavelet transform in 1-D. */
-/* </summary>                           */ 
-static void dwt_decode_1(dwt_t *v) {
-	dwt_decode_1_(v->mem, v->dn, v->sn, v->cas);
-}
-
-/* <summary>                             */
-/* Forward 9-7 wavelet transform in 1-D. */
-/* </summary>                            */
-static void dwt_encode_1_real(int *a, int dn, int sn, int cas) {
-	int i;
-	if (!cas) {
-		if ((dn > 0) || (sn > 1)) {	/* NEW :  CASE ONE ELEMENT */
-			for (i = 0; i < dn; i++)
-				D(i) -= fix_mul(S_(i) + S_(i + 1), 12993);
-			for (i = 0; i < sn; i++)
-				S(i) -= fix_mul(D_(i - 1) + D_(i), 434);
-			for (i = 0; i < dn; i++)
-				D(i) += fix_mul(S_(i) + S_(i + 1), 7233);
-			for (i = 0; i < sn; i++)
-				S(i) += fix_mul(D_(i - 1) + D_(i), 3633);
-			for (i = 0; i < dn; i++)
-				D(i) = fix_mul(D(i), 5038);	/*5038 */
-			for (i = 0; i < sn; i++)
-				S(i) = fix_mul(S(i), 6659);	/*6660 */
-		}
-	} else {
-		if ((sn > 0) || (dn > 1)) {	/* NEW :  CASE ONE ELEMENT */
-			for (i = 0; i < dn; i++)
-				S(i) -= fix_mul(DD_(i) + DD_(i - 1), 12993);
-			for (i = 0; i < sn; i++)
-				D(i) -= fix_mul(SS_(i) + SS_(i + 1), 434);
-			for (i = 0; i < dn; i++)
-				S(i) += fix_mul(DD_(i) + DD_(i - 1), 7233);
-			for (i = 0; i < sn; i++)
-				D(i) += fix_mul(SS_(i) + SS_(i + 1), 3633);
-			for (i = 0; i < dn; i++)
-				S(i) = fix_mul(S(i), 5038);	/*5038 */
-			for (i = 0; i < sn; i++)
-				D(i) = fix_mul(D(i), 6659);	/*6660 */
-		}
-	}
-}
-
-static void dwt_encode_stepsize(int stepsize, int numbps, opj_stepsize_t *bandno_stepsize) {
-	int p, n;
-	p = int_floorlog2(stepsize) - 13;
-	n = 11 - int_floorlog2(stepsize);
-	bandno_stepsize->mant = (n < 0 ? stepsize >> -n : stepsize << n) & 0x7ff;
-	bandno_stepsize->expn = numbps - p;
-}
-
-/* 
-==========================================================
-   DWT interface
-==========================================================
-*/
-
-/* <summary>                            */
-/* Forward 5-3 wavelet transform in 2-D. */
-/* </summary>                           */
-void dwt_encode(opj_tcd_tilecomp_t * tilec) {
-	int i, j, k;
-	int *a = NULL;
-	int *aj = NULL;
-	int *bj = NULL;
-	int w, l;
-	
-	w = tilec->x1-tilec->x0;
-	l = tilec->numresolutions-1;
-	a = tilec->data;
-	
-	for (i = 0; i < l; i++) {
-		int rw;			/* width of the resolution level computed                                                           */
-		int rh;			/* height of the resolution level computed                                                          */
-		int rw1;		/* width of the resolution level once lower than computed one                                       */
-		int rh1;		/* height of the resolution level once lower than computed one                                      */
-		int cas_col;	/* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */
-		int cas_row;	/* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering   */
-		int dn, sn;
-		
-		rw = tilec->resolutions[l - i].x1 - tilec->resolutions[l - i].x0;
-		rh = tilec->resolutions[l - i].y1 - tilec->resolutions[l - i].y0;
-		rw1= tilec->resolutions[l - i - 1].x1 - tilec->resolutions[l - i - 1].x0;
-		rh1= tilec->resolutions[l - i - 1].y1 - tilec->resolutions[l - i - 1].y0;
-		
-		cas_row = tilec->resolutions[l - i].x0 % 2;
-		cas_col = tilec->resolutions[l - i].y0 % 2;
-        
-		sn = rh1;
-		dn = rh - rh1;
-		bj = (int*)opj_malloc(rh * sizeof(int));
-		for (j = 0; j < rw; j++) {
-			aj = a + j;
-			for (k = 0; k < rh; k++)  bj[k] = aj[k*w];
-			dwt_encode_1(bj, dn, sn, cas_col);
-			dwt_deinterleave_v(bj, aj, dn, sn, w, cas_col);
-		}
-		opj_free(bj);
-		
-		sn = rw1;
-		dn = rw - rw1;
-		bj = (int*)opj_malloc(rw * sizeof(int));
-		for (j = 0; j < rh; j++) {
-			aj = a + j * w;
-			for (k = 0; k < rw; k++)  bj[k] = aj[k];
-			dwt_encode_1(bj, dn, sn, cas_row);
-			dwt_deinterleave_h(bj, aj, dn, sn, cas_row);
-		}
-		opj_free(bj);
-	}
-}
-
-
-/* <summary>                            */
-/* Inverse 5-3 wavelet transform in 2-D. */
-/* </summary>                           */
-void dwt_decode(opj_tcd_tilecomp_t* tilec, int numres) {
-	dwt_decode_tile(tilec, numres, &dwt_decode_1);
-}
-
-
-/* <summary>                          */
-/* Get gain of 5-3 wavelet transform. */
-/* </summary>                         */
-int dwt_getgain(int orient) {
-	if (orient == 0)
-		return 0;
-	if (orient == 1 || orient == 2)
-		return 1;
-	return 2;
-}
-
-/* <summary>                */
-/* Get norm of 5-3 wavelet. */
-/* </summary>               */
-double dwt_getnorm(int level, int orient) {
-	return dwt_norms[orient][level];
-}
-
-/* <summary>                             */
-/* Forward 9-7 wavelet transform in 2-D. */
-/* </summary>                            */
-
-void dwt_encode_real(opj_tcd_tilecomp_t * tilec) {
-	int i, j, k;
-	int *a = NULL;
-	int *aj = NULL;
-	int *bj = NULL;
-	int w, l;
-	
-	w = tilec->x1-tilec->x0;
-	l = tilec->numresolutions-1;
-	a = tilec->data;
-	
-	for (i = 0; i < l; i++) {
-		int rw;			/* width of the resolution level computed                                                     */
-		int rh;			/* height of the resolution level computed                                                    */
-		int rw1;		/* width of the resolution level once lower than computed one                                 */
-		int rh1;		/* height of the resolution level once lower than computed one                                */
-		int cas_col;	/* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */
-		int cas_row;	/* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering   */
-		int dn, sn;
-		
-		rw = tilec->resolutions[l - i].x1 - tilec->resolutions[l - i].x0;
-		rh = tilec->resolutions[l - i].y1 - tilec->resolutions[l - i].y0;
-		rw1= tilec->resolutions[l - i - 1].x1 - tilec->resolutions[l - i - 1].x0;
-		rh1= tilec->resolutions[l - i - 1].y1 - tilec->resolutions[l - i - 1].y0;
-		
-		cas_row = tilec->resolutions[l - i].x0 % 2;
-		cas_col = tilec->resolutions[l - i].y0 % 2;
-		
-		sn = rh1;
-		dn = rh - rh1;
-		bj = (int*)opj_malloc(rh * sizeof(int));
-		for (j = 0; j < rw; j++) {
-			aj = a + j;
-			for (k = 0; k < rh; k++)  bj[k] = aj[k*w];
-			dwt_encode_1_real(bj, dn, sn, cas_col);
-			dwt_deinterleave_v(bj, aj, dn, sn, w, cas_col);
-		}
-		opj_free(bj);
-		
-		sn = rw1;
-		dn = rw - rw1;
-		bj = (int*)opj_malloc(rw * sizeof(int));
-		for (j = 0; j < rh; j++) {
-			aj = a + j * w;
-			for (k = 0; k < rw; k++)  bj[k] = aj[k];
-			dwt_encode_1_real(bj, dn, sn, cas_row);
-			dwt_deinterleave_h(bj, aj, dn, sn, cas_row);
-		}
-		opj_free(bj);
-	}
-}
-
-
-/* <summary>                          */
-/* Get gain of 9-7 wavelet transform. */
-/* </summary>                         */
-int dwt_getgain_real(int orient) {
-	(void)orient;
-	return 0;
-}
-
-/* <summary>                */
-/* Get norm of 9-7 wavelet. */
-/* </summary>               */
-double dwt_getnorm_real(int level, int orient) {
-	return dwt_norms_real[orient][level];
-}
-
-void dwt_calc_explicit_stepsizes(opj_tccp_t * tccp, int prec) {
-	int numbands, bandno;
-	numbands = 3 * tccp->numresolutions - 2;
-	for (bandno = 0; bandno < numbands; bandno++) {
-		double stepsize;
-		int resno, level, orient, gain;
-
-		resno = (bandno == 0) ? 0 : ((bandno - 1) / 3 + 1);
-		orient = (bandno == 0) ? 0 : ((bandno - 1) % 3 + 1);
-		level = tccp->numresolutions - 1 - resno;
-		gain = (tccp->qmfbid == 0) ? 0 : ((orient == 0) ? 0 : (((orient == 1) || (orient == 2)) ? 1 : 2));
-		if (tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) {
-			stepsize = 1.0;
-		} else {
-			double norm = dwt_norms_real[orient][level];
-			stepsize = (1 << (gain)) / norm;
-		}
-		dwt_encode_stepsize((int) floor(stepsize * 8192.0), prec + gain, &tccp->stepsizes[bandno]);
-	}
-}
-
-
-/* <summary>                             */
-/* Determine maximum computed resolution level for inverse wavelet transform */
-/* </summary>                            */
-static int dwt_decode_max_resolution(opj_tcd_resolution_t* restrict r, int i) {
-	int mr	= 1;
-	int w;
-	while( --i ) {
-		r++;
-		if( mr < ( w = r->x1 - r->x0 ) )
-			mr = w ;
-		if( mr < ( w = r->y1 - r->y0 ) )
-			mr = w ;
-	}
-	return mr ;
-}
-
-
-/* <summary>                            */
-/* Inverse wavelet transform in 2-D.     */
-/* </summary>                           */
-static void dwt_decode_tile(opj_tcd_tilecomp_t* tilec, int numres, DWT1DFN dwt_1D) {
-	dwt_t h;
-	dwt_t v;
-
-	opj_tcd_resolution_t* tr = tilec->resolutions;
-
-	int rw = tr->x1 - tr->x0;	/* width of the resolution level computed */
-	int rh = tr->y1 - tr->y0;	/* height of the resolution level computed */
-
-	int w = tilec->x1 - tilec->x0;
-
-	h.mem = (int*)opj_aligned_malloc(dwt_decode_max_resolution(tr, numres) * sizeof(int));
-	v.mem = h.mem;
-
-	while( --numres) {
-		int * restrict tiledp = tilec->data;
-		int j;
-
-		++tr;
-		h.sn = rw;
-		v.sn = rh;
-
-		rw = tr->x1 - tr->x0;
-		rh = tr->y1 - tr->y0;
-
-		h.dn = rw - h.sn;
-		h.cas = tr->x0 % 2;
-
-		for(j = 0; j < rh; ++j) {
-			dwt_interleave_h(&h, &tiledp[j*w]);
-			(dwt_1D)(&h);
-			memcpy(&tiledp[j*w], h.mem, rw * sizeof(int));
-		}
-
-		v.dn = rh - v.sn;
-		v.cas = tr->y0 % 2;
-
-		for(j = 0; j < rw; ++j){
-			int k;
-			dwt_interleave_v(&v, &tiledp[j], w);
-			(dwt_1D)(&v);
-			for(k = 0; k < rh; ++k) {
-				tiledp[k * w + j] = v.mem[k];
-			}
-		}
-	}
-	opj_aligned_free(h.mem);
-}
-
-static void v4dwt_interleave_h(v4dwt_t* restrict w, float* restrict a, int x, int size){
-	float* restrict bi = (float*) (w->wavelet + w->cas);
-	int count = w->sn;
-	int i, k;
-	for(k = 0; k < 2; ++k){
-		if (count + 3 * x < size && ((size_t) a & 0x0f) == 0 && ((size_t) bi & 0x0f) == 0 && (x & 0x0f) == 0) {
-			/* Fast code path */
-			for(i = 0; i < count; ++i){
-				int j = i;
-				bi[i*8    ] = a[j];
-				j += x;
-				bi[i*8 + 1] = a[j];
-				j += x;
-				bi[i*8 + 2] = a[j];
-				j += x;
-				bi[i*8 + 3] = a[j];
-			}
-		} else {
-			/* Slow code path */
-		for(i = 0; i < count; ++i){
-			int j = i;
-			bi[i*8    ] = a[j];
-			j += x;
-			if(j > size) continue;
-			bi[i*8 + 1] = a[j];
-			j += x;
-			if(j > size) continue;
-			bi[i*8 + 2] = a[j];
-			j += x;
-			if(j > size) continue;
-			bi[i*8 + 3] = a[j];
-		}
-		}
-		bi = (float*) (w->wavelet + 1 - w->cas);
-		a += w->sn;
-		size -= w->sn;
-		count = w->dn;
-	}
-}
-
-static void v4dwt_interleave_v(v4dwt_t* restrict v , float* restrict a , int x){
-	v4* restrict bi = v->wavelet + v->cas;
-	int i;
-	for(i = 0; i < v->sn; ++i){
-		memcpy(&bi[i*2], &a[i*x], 4 * sizeof(float));
-	}
-	a += v->sn * x;
-	bi = v->wavelet + 1 - v->cas;
-	for(i = 0; i < v->dn; ++i){
-		memcpy(&bi[i*2], &a[i*x], 4 * sizeof(float));
-	}
-}
-
-#ifdef __SSE__
-
-static void v4dwt_decode_step1_sse(v4* w, int count, const __m128 c){
-	__m128* restrict vw = (__m128*) w;
-	int i;
-	/* 4x unrolled loop */
-	for(i = 0; i < count >> 2; ++i){
-		*vw = _mm_mul_ps(*vw, c);
-		vw += 2;
-		*vw = _mm_mul_ps(*vw, c);
-		vw += 2;
-		*vw = _mm_mul_ps(*vw, c);
-		vw += 2;
-		*vw = _mm_mul_ps(*vw, c);
-		vw += 2;
-	}
-	count &= 3;
-	for(i = 0; i < count; ++i){
-		*vw = _mm_mul_ps(*vw, c);
-		vw += 2;
-	}
-}
-
-static void v4dwt_decode_step2_sse(v4* l, v4* w, int k, int m, __m128 c){
-	__m128* restrict vl = (__m128*) l;
-	__m128* restrict vw = (__m128*) w;
-	int i;
-	__m128 tmp1, tmp2, tmp3;
-	tmp1 = vl[0];
-	for(i = 0; i < m; ++i){
-		tmp2 = vw[-1];
-		tmp3 = vw[ 0];
-		vw[-1] = _mm_add_ps(tmp2, _mm_mul_ps(_mm_add_ps(tmp1, tmp3), c));
-		tmp1 = tmp3;
-		vw += 2;
-	}
-	vl = vw - 2;
-	if(m >= k){
-		return;
-	}
-	c = _mm_add_ps(c, c);
-	c = _mm_mul_ps(c, vl[0]);
-	for(; m < k; ++m){
-		__m128 tmp = vw[-1];
-		vw[-1] = _mm_add_ps(tmp, c);
-		vw += 2;
-	}
-}
-
-#else
-
-static void v4dwt_decode_step1(v4* w, int count, const float c){
-	float* restrict fw = (float*) w;
-	int i;
-	for(i = 0; i < count; ++i){
-		float tmp1 = fw[i*8    ];
-		float tmp2 = fw[i*8 + 1];
-		float tmp3 = fw[i*8 + 2];
-		float tmp4 = fw[i*8 + 3];
-		fw[i*8    ] = tmp1 * c;
-		fw[i*8 + 1] = tmp2 * c;
-		fw[i*8 + 2] = tmp3 * c;
-		fw[i*8 + 3] = tmp4 * c;
-	}
-}
-
-static void v4dwt_decode_step2(v4* l, v4* w, int k, int m, float c){
-	float* restrict fl = (float*) l;
-	float* restrict fw = (float*) w;
-	int i;
-	for(i = 0; i < m; ++i){
-		float tmp1_1 = fl[0];
-		float tmp1_2 = fl[1];
-		float tmp1_3 = fl[2];
-		float tmp1_4 = fl[3];
-		float tmp2_1 = fw[-4];
-		float tmp2_2 = fw[-3];
-		float tmp2_3 = fw[-2];
-		float tmp2_4 = fw[-1];
-		float tmp3_1 = fw[0];
-		float tmp3_2 = fw[1];
-		float tmp3_3 = fw[2];
-		float tmp3_4 = fw[3];
-		fw[-4] = tmp2_1 + ((tmp1_1 + tmp3_1) * c);
-		fw[-3] = tmp2_2 + ((tmp1_2 + tmp3_2) * c);
-		fw[-2] = tmp2_3 + ((tmp1_3 + tmp3_3) * c);
-		fw[-1] = tmp2_4 + ((tmp1_4 + tmp3_4) * c);
-		fl = fw;
-		fw += 8;
-	}
-	if(m < k){
-		float c1;
-		float c2;
-		float c3;
-		float c4;
-		c += c;
-		c1 = fl[0] * c;
-		c2 = fl[1] * c;
-		c3 = fl[2] * c;
-		c4 = fl[3] * c;
-		for(; m < k; ++m){
-			float tmp1 = fw[-4];
-			float tmp2 = fw[-3];
-			float tmp3 = fw[-2];
-			float tmp4 = fw[-1];
-			fw[-4] = tmp1 + c1;
-			fw[-3] = tmp2 + c2;
-			fw[-2] = tmp3 + c3;
-			fw[-1] = tmp4 + c4;
-			fw += 8;
-		}
-	}
-}
-
-#endif
-
-/* <summary>                             */
-/* Inverse 9-7 wavelet transform in 1-D. */
-/* </summary>                            */
-static void v4dwt_decode(v4dwt_t* restrict dwt){
-	int a, b;
-	if(dwt->cas == 0) {
-		if(!((dwt->dn > 0) || (dwt->sn > 1))){
-			return;
-		}
-		a = 0;
-		b = 1;
-	}else{
-		if(!((dwt->sn > 0) || (dwt->dn > 1))) {
-			return;
-		}
-		a = 1;
-		b = 0;
-	}
-#ifdef __SSE__
-	v4dwt_decode_step1_sse(dwt->wavelet+a, dwt->sn, _mm_set1_ps(K));
-	v4dwt_decode_step1_sse(dwt->wavelet+b, dwt->dn, _mm_set1_ps(c13318));
-	v4dwt_decode_step2_sse(dwt->wavelet+b, dwt->wavelet+a+1, dwt->sn, int_min(dwt->sn, dwt->dn-a), _mm_set1_ps(dwt_delta));
-	v4dwt_decode_step2_sse(dwt->wavelet+a, dwt->wavelet+b+1, dwt->dn, int_min(dwt->dn, dwt->sn-b), _mm_set1_ps(dwt_gamma));
-	v4dwt_decode_step2_sse(dwt->wavelet+b, dwt->wavelet+a+1, dwt->sn, int_min(dwt->sn, dwt->dn-a), _mm_set1_ps(dwt_beta));
-	v4dwt_decode_step2_sse(dwt->wavelet+a, dwt->wavelet+b+1, dwt->dn, int_min(dwt->dn, dwt->sn-b), _mm_set1_ps(dwt_alpha));
-#else
-	v4dwt_decode_step1(dwt->wavelet+a, dwt->sn, K);
-	v4dwt_decode_step1(dwt->wavelet+b, dwt->dn, c13318);
-	v4dwt_decode_step2(dwt->wavelet+b, dwt->wavelet+a+1, dwt->sn, int_min(dwt->sn, dwt->dn-a), dwt_delta);
-	v4dwt_decode_step2(dwt->wavelet+a, dwt->wavelet+b+1, dwt->dn, int_min(dwt->dn, dwt->sn-b), dwt_gamma);
-	v4dwt_decode_step2(dwt->wavelet+b, dwt->wavelet+a+1, dwt->sn, int_min(dwt->sn, dwt->dn-a), dwt_beta);
-	v4dwt_decode_step2(dwt->wavelet+a, dwt->wavelet+b+1, dwt->dn, int_min(dwt->dn, dwt->sn-b), dwt_alpha);
-#endif
-}
-
-/* <summary>                             */
-/* Inverse 9-7 wavelet transform in 2-D. */
-/* </summary>                            */
-void dwt_decode_real(opj_tcd_tilecomp_t* restrict tilec, int numres){
-	v4dwt_t h;
-	v4dwt_t v;
-
-	opj_tcd_resolution_t* res = tilec->resolutions;
-
-	int rw = res->x1 - res->x0;	/* width of the resolution level computed */
-	int rh = res->y1 - res->y0;	/* height of the resolution level computed */
-
-	int w = tilec->x1 - tilec->x0;
-
-	h.wavelet = (v4*) opj_aligned_malloc((dwt_decode_max_resolution(res, numres)+5) * sizeof(v4));
-	v.wavelet = h.wavelet;
-
-	while( --numres) {
-		float * restrict aj = (float*) tilec->data;
-		int bufsize = (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0);
-		int j;
-
-		h.sn = rw;
-		v.sn = rh;
-
-		++res;
-
-		rw = res->x1 - res->x0;	/* width of the resolution level computed */
-		rh = res->y1 - res->y0;	/* height of the resolution level computed */
-
-		h.dn = rw - h.sn;
-		h.cas = res->x0 % 2;
-
-		for(j = rh; j > 3; j -= 4){
-			int k;
-			v4dwt_interleave_h(&h, aj, w, bufsize);
-			v4dwt_decode(&h);
-				for(k = rw; --k >= 0;){
-					aj[k    ] = h.wavelet[k].f[0];
-					aj[k+w  ] = h.wavelet[k].f[1];
-					aj[k+w*2] = h.wavelet[k].f[2];
-					aj[k+w*3] = h.wavelet[k].f[3];
-				}
-			aj += w*4;
-			bufsize -= w*4;
-		}
-		if (rh & 0x03) {
-				int k;
-			j = rh & 0x03;
-			v4dwt_interleave_h(&h, aj, w, bufsize);
-			v4dwt_decode(&h);
-				for(k = rw; --k >= 0;){
-					switch(j) {
-						case 3: aj[k+w*2] = h.wavelet[k].f[2];
-						case 2: aj[k+w  ] = h.wavelet[k].f[1];
-						case 1: aj[k    ] = h.wavelet[k].f[0];
-					}
-				}
-			}
-
-		v.dn = rh - v.sn;
-		v.cas = res->y0 % 2;
-
-		aj = (float*) tilec->data;
-		for(j = rw; j > 3; j -= 4){
-			int k;
-			v4dwt_interleave_v(&v, aj, w);
-			v4dwt_decode(&v);
-				for(k = 0; k < rh; ++k){
-					memcpy(&aj[k*w], &v.wavelet[k], 4 * sizeof(float));
-				}
-			aj += 4;
-		}
-		if (rw & 0x03){
-				int k;
-			j = rw & 0x03;
-			v4dwt_interleave_v(&v, aj, w);
-			v4dwt_decode(&v);
-				for(k = 0; k < rh; ++k){
-					memcpy(&aj[k*w], &v.wavelet[k], j * sizeof(float));
-				}
-			}
-	}
-
-	opj_aligned_free(h.wavelet);
-}
-
+/*
+ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2007, Professor Benoit Macq
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2007, Jonathan Ballard <dzonatas at dzonux.net>
+ * Copyright (c) 2007, Callum Lerwick <seg at haxxed.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef __SSE__
+#include <xmmintrin.h>
+#endif
+
+#include "opj_includes.h"
+
+/** @defgroup DWT DWT - Implementation of a discrete wavelet transform */
+/*@{*/
+
+#define OPJ_WS(i) v->mem[(i)*2]
+#define OPJ_WD(i) v->mem[(1+(i)*2)]
+
+/** @name Local data structures */
+/*@{*/
+
+typedef struct dwt_local {
+	OPJ_INT32* mem;
+	OPJ_INT32 dn;
+	OPJ_INT32 sn;
+	OPJ_INT32 cas;
+} opj_dwt_t;
+
+typedef union {
+	OPJ_FLOAT32	f[4];
+} opj_v4_t;
+
+typedef struct v4dwt_local {
+	opj_v4_t*	wavelet ;
+	OPJ_INT32		dn ;
+	OPJ_INT32		sn ;
+	OPJ_INT32		cas ;
+} opj_v4dwt_t ;
+
+static const OPJ_FLOAT32 opj_dwt_alpha =  1.586134342f; /*  12994 */
+static const OPJ_FLOAT32 opj_dwt_beta  =  0.052980118f; /*    434 */
+static const OPJ_FLOAT32 opj_dwt_gamma = -0.882911075f; /*  -7233 */
+static const OPJ_FLOAT32 opj_dwt_delta = -0.443506852f; /*  -3633 */
+
+static const OPJ_FLOAT32 opj_K      = 1.230174105f; /*  10078 */
+static const OPJ_FLOAT32 opj_c13318 = 1.625732422f;
+
+/*@}*/
+
+/**
+Virtual function type for wavelet transform in 1-D 
+*/
+typedef void (*DWT1DFN)(opj_dwt_t* v);
+
+/** @name Local static functions */
+/*@{*/
+
+/**
+Forward lazy transform (horizontal)
+*/
+static void opj_dwt_deinterleave_h(OPJ_INT32 *a, OPJ_INT32 *b, OPJ_INT32 dn, OPJ_INT32 sn, OPJ_INT32 cas);
+/**
+Forward lazy transform (vertical)
+*/
+static void opj_dwt_deinterleave_v(OPJ_INT32 *a, OPJ_INT32 *b, OPJ_INT32 dn, OPJ_INT32 sn, OPJ_INT32 x, OPJ_INT32 cas);
+/**
+Inverse lazy transform (horizontal)
+*/
+static void opj_dwt_interleave_h(opj_dwt_t* h, OPJ_INT32 *a);
+/**
+Inverse lazy transform (vertical)
+*/
+static void opj_dwt_interleave_v(opj_dwt_t* v, OPJ_INT32 *a, OPJ_INT32 x);
+/**
+Forward 5-3 wavelet transform in 1-D
+*/
+static void opj_dwt_encode_1(OPJ_INT32 *a, OPJ_INT32 dn, OPJ_INT32 sn, OPJ_INT32 cas);
+/**
+Inverse 5-3 wavelet transform in 1-D
+*/
+static void opj_dwt_decode_1(opj_dwt_t *v);
+static void opj_dwt_decode_1_(OPJ_INT32 *a, OPJ_INT32 dn, OPJ_INT32 sn, OPJ_INT32 cas);
+/**
+Forward 9-7 wavelet transform in 1-D
+*/
+static void opj_dwt_encode_1_real(OPJ_INT32 *a, OPJ_INT32 dn, OPJ_INT32 sn, OPJ_INT32 cas);
+/**
+Explicit calculation of the Quantization Stepsizes 
+*/
+static void opj_dwt_encode_stepsize(OPJ_INT32 stepsize, OPJ_INT32 numbps, opj_stepsize_t *bandno_stepsize);
+/**
+Inverse wavelet transform in 2-D.
+*/
+static OPJ_BOOL opj_dwt_decode_tile(opj_tcd_tilecomp_t* tilec, OPJ_UINT32 i, DWT1DFN fn);
+
+static OPJ_BOOL opj_dwt_encode_procedure(	opj_tcd_tilecomp_t * tilec,
+										    void (*p_function)(OPJ_INT32 *, OPJ_INT32,OPJ_INT32,OPJ_INT32) );
+
+static OPJ_UINT32 opj_dwt_max_resolution(opj_tcd_resolution_t* restrict r, OPJ_UINT32 i);
+
+/* <summary>                             */
+/* Inverse 9-7 wavelet transform in 1-D. */
+/* </summary>                            */
+static void opj_v4dwt_decode(opj_v4dwt_t* restrict dwt);
+
+static void opj_v4dwt_interleave_h(opj_v4dwt_t* restrict w, OPJ_FLOAT32* restrict a, OPJ_INT32 x, OPJ_INT32 size);
+
+static void opj_v4dwt_interleave_v(opj_v4dwt_t* restrict v , OPJ_FLOAT32* restrict a , OPJ_INT32 x, OPJ_INT32 nb_elts_read);
+
+#ifdef __SSE__
+static void opj_v4dwt_decode_step1_sse(opj_v4_t* w, OPJ_INT32 count, const __m128 c);
+
+static void opj_v4dwt_decode_step2_sse(opj_v4_t* l, opj_v4_t* w, OPJ_INT32 k, OPJ_INT32 m, __m128 c);
+
+#else
+static void opj_v4dwt_decode_step1(opj_v4_t* w, OPJ_INT32 count, const OPJ_FLOAT32 c);
+
+static void opj_v4dwt_decode_step2(opj_v4_t* l, opj_v4_t* w, OPJ_INT32 k, OPJ_INT32 m, OPJ_FLOAT32 c);
+
+#endif
+
+/*@}*/
+
+/*@}*/
+
+#define OPJ_S(i) a[(i)*2]
+#define OPJ_D(i) a[(1+(i)*2)]
+#define OPJ_S_(i) ((i)<0?OPJ_S(0):((i)>=sn?OPJ_S(sn-1):OPJ_S(i)))
+#define OPJ_D_(i) ((i)<0?OPJ_D(0):((i)>=dn?OPJ_D(dn-1):OPJ_D(i)))
+/* new */
+#define OPJ_SS_(i) ((i)<0?OPJ_S(0):((i)>=dn?OPJ_S(dn-1):OPJ_S(i)))
+#define OPJ_DD_(i) ((i)<0?OPJ_D(0):((i)>=sn?OPJ_D(sn-1):OPJ_D(i)))
+
+/* <summary>                                                              */
+/* This table contains the norms of the 5-3 wavelets for different bands. */
+/* </summary>                                                             */
+static const OPJ_FLOAT64 opj_dwt_norms[4][10] = {
+	{1.000, 1.500, 2.750, 5.375, 10.68, 21.34, 42.67, 85.33, 170.7, 341.3},
+	{1.038, 1.592, 2.919, 5.703, 11.33, 22.64, 45.25, 90.48, 180.9},
+	{1.038, 1.592, 2.919, 5.703, 11.33, 22.64, 45.25, 90.48, 180.9},
+	{.7186, .9218, 1.586, 3.043, 6.019, 12.01, 24.00, 47.97, 95.93}
+};
+
+/* <summary>                                                              */
+/* This table contains the norms of the 9-7 wavelets for different bands. */
+/* </summary>                                                             */
+static const OPJ_FLOAT64 opj_dwt_norms_real[4][10] = {
+	{1.000, 1.965, 4.177, 8.403, 16.90, 33.84, 67.69, 135.3, 270.6, 540.9},
+	{2.022, 3.989, 8.355, 17.04, 34.27, 68.63, 137.3, 274.6, 549.0},
+	{2.022, 3.989, 8.355, 17.04, 34.27, 68.63, 137.3, 274.6, 549.0},
+	{2.080, 3.865, 8.307, 17.18, 34.71, 69.59, 139.3, 278.6, 557.2}
+};
+
+/* 
+==========================================================
+   local functions
+==========================================================
+*/
+
+/* <summary>			                 */
+/* Forward lazy transform (horizontal).  */
+/* </summary>                            */ 
+void opj_dwt_deinterleave_h(OPJ_INT32 *a, OPJ_INT32 *b, OPJ_INT32 dn, OPJ_INT32 sn, OPJ_INT32 cas) {
+	OPJ_INT32 i;
+	OPJ_INT32 * l_dest = b;
+	OPJ_INT32 * l_src = a+cas;
+
+    for (i=0; i<sn; ++i) {
+		*l_dest++ = *l_src;
+		l_src += 2;
+	}
+	
+    l_dest = b + sn;
+	l_src = a + 1 - cas;
+
+    for	(i=0; i<dn; ++i)  {
+		*l_dest++=*l_src;
+		l_src += 2;
+	}
+}
+
+/* <summary>                             */  
+/* Forward lazy transform (vertical).    */
+/* </summary>                            */ 
+void opj_dwt_deinterleave_v(OPJ_INT32 *a, OPJ_INT32 *b, OPJ_INT32 dn, OPJ_INT32 sn, OPJ_INT32 x, OPJ_INT32 cas) {
+    OPJ_INT32 i = sn;
+	OPJ_INT32 * l_dest = b;
+	OPJ_INT32 * l_src = a+cas;
+
+    while (i--) {
+		*l_dest = *l_src;
+		l_dest += x;
+		l_src += 2;
+		} /* b[i*x]=a[2*i+cas]; */
+
+	l_dest = b + sn * x;
+	l_src = a + 1 - cas;
+	
+	i = dn;
+    while (i--) {
+		*l_dest = *l_src;
+		l_dest += x;
+		l_src += 2;
+        } /*b[(sn+i)*x]=a[(2*i+1-cas)];*/
+}
+
+/* <summary>                             */
+/* Inverse lazy transform (horizontal).  */
+/* </summary>                            */
+void opj_dwt_interleave_h(opj_dwt_t* h, OPJ_INT32 *a) {
+    OPJ_INT32 *ai = a;
+    OPJ_INT32 *bi = h->mem + h->cas;
+    OPJ_INT32  i	= h->sn;
+    while( i-- ) {
+      *bi = *(ai++);
+	  bi += 2;
+    }
+    ai	= a + h->sn;
+    bi	= h->mem + 1 - h->cas;
+    i	= h->dn ;
+    while( i-- ) {
+      *bi = *(ai++);
+	  bi += 2;
+    }
+}
+
+/* <summary>                             */  
+/* Inverse lazy transform (vertical).    */
+/* </summary>                            */ 
+void opj_dwt_interleave_v(opj_dwt_t* v, OPJ_INT32 *a, OPJ_INT32 x) {
+    OPJ_INT32 *ai = a;
+    OPJ_INT32 *bi = v->mem + v->cas;
+    OPJ_INT32  i = v->sn;
+    while( i-- ) {
+      *bi = *ai;
+	  bi += 2;
+	  ai += x;
+    }
+    ai = a + (v->sn * x);
+    bi = v->mem + 1 - v->cas;
+    i = v->dn ;
+    while( i-- ) {
+      *bi = *ai;
+	  bi += 2;  
+	  ai += x;
+    }
+}
+
+
+/* <summary>                            */
+/* Forward 5-3 wavelet transform in 1-D. */
+/* </summary>                           */
+void opj_dwt_encode_1(OPJ_INT32 *a, OPJ_INT32 dn, OPJ_INT32 sn, OPJ_INT32 cas) {
+	OPJ_INT32 i;
+	
+	if (!cas) {
+		if ((dn > 0) || (sn > 1)) {	/* NEW :  CASE ONE ELEMENT */
+			for (i = 0; i < dn; i++) OPJ_D(i) -= (OPJ_S_(i) + OPJ_S_(i + 1)) >> 1;
+			for (i = 0; i < sn; i++) OPJ_S(i) += (OPJ_D_(i - 1) + OPJ_D_(i) + 2) >> 2;
+		}
+	} else {
+		if (!sn && dn == 1)		    /* NEW :  CASE ONE ELEMENT */
+			OPJ_S(0) *= 2;
+		else {
+			for (i = 0; i < dn; i++) OPJ_S(i) -= (OPJ_DD_(i) + OPJ_DD_(i - 1)) >> 1;
+			for (i = 0; i < sn; i++) OPJ_D(i) += (OPJ_SS_(i) + OPJ_SS_(i + 1) + 2) >> 2;
+		}
+	}
+}
+
+/* <summary>                            */
+/* Inverse 5-3 wavelet transform in 1-D. */
+/* </summary>                           */ 
+void opj_dwt_decode_1_(OPJ_INT32 *a, OPJ_INT32 dn, OPJ_INT32 sn, OPJ_INT32 cas) {
+	OPJ_INT32 i;
+	
+	if (!cas) {
+		if ((dn > 0) || (sn > 1)) { /* NEW :  CASE ONE ELEMENT */
+			for (i = 0; i < sn; i++) OPJ_S(i) -= (OPJ_D_(i - 1) + OPJ_D_(i) + 2) >> 2;
+			for (i = 0; i < dn; i++) OPJ_D(i) += (OPJ_S_(i) + OPJ_S_(i + 1)) >> 1;
+		}
+	} else {
+		if (!sn  && dn == 1)          /* NEW :  CASE ONE ELEMENT */
+			OPJ_S(0) /= 2;
+		else {
+			for (i = 0; i < sn; i++) OPJ_D(i) -= (OPJ_SS_(i) + OPJ_SS_(i + 1) + 2) >> 2;
+			for (i = 0; i < dn; i++) OPJ_S(i) += (OPJ_DD_(i) + OPJ_DD_(i - 1)) >> 1;
+		}
+	}
+}
+
+/* <summary>                            */
+/* Inverse 5-3 wavelet transform in 1-D. */
+/* </summary>                           */ 
+void opj_dwt_decode_1(opj_dwt_t *v) {
+	opj_dwt_decode_1_(v->mem, v->dn, v->sn, v->cas);
+}
+
+/* <summary>                             */
+/* Forward 9-7 wavelet transform in 1-D. */
+/* </summary>                            */
+void opj_dwt_encode_1_real(OPJ_INT32 *a, OPJ_INT32 dn, OPJ_INT32 sn, OPJ_INT32 cas) {
+	OPJ_INT32 i;
+	if (!cas) {
+		if ((dn > 0) || (sn > 1)) {	/* NEW :  CASE ONE ELEMENT */
+			for (i = 0; i < dn; i++)
+				OPJ_D(i) -= opj_int_fix_mul(OPJ_S_(i) + OPJ_S_(i + 1), 12993);
+			for (i = 0; i < sn; i++)
+				OPJ_S(i) -= opj_int_fix_mul(OPJ_D_(i - 1) + OPJ_D_(i), 434);
+			for (i = 0; i < dn; i++)
+				OPJ_D(i) += opj_int_fix_mul(OPJ_S_(i) + OPJ_S_(i + 1), 7233);
+			for (i = 0; i < sn; i++)
+				OPJ_S(i) += opj_int_fix_mul(OPJ_D_(i - 1) + OPJ_D_(i), 3633);
+			for (i = 0; i < dn; i++)
+				OPJ_D(i) = opj_int_fix_mul(OPJ_D(i), 5038);	/*5038 */
+			for (i = 0; i < sn; i++)
+				OPJ_S(i) = opj_int_fix_mul(OPJ_S(i), 6659);	/*6660 */
+		}
+	} else {
+		if ((sn > 0) || (dn > 1)) {	/* NEW :  CASE ONE ELEMENT */
+			for (i = 0; i < dn; i++)
+				OPJ_S(i) -= opj_int_fix_mul(OPJ_DD_(i) + OPJ_DD_(i - 1), 12993);
+			for (i = 0; i < sn; i++)
+				OPJ_D(i) -= opj_int_fix_mul(OPJ_SS_(i) + OPJ_SS_(i + 1), 434);
+			for (i = 0; i < dn; i++)
+				OPJ_S(i) += opj_int_fix_mul(OPJ_DD_(i) + OPJ_DD_(i - 1), 7233);
+			for (i = 0; i < sn; i++)
+				OPJ_D(i) += opj_int_fix_mul(OPJ_SS_(i) + OPJ_SS_(i + 1), 3633);
+			for (i = 0; i < dn; i++)
+				OPJ_S(i) = opj_int_fix_mul(OPJ_S(i), 5038);	/*5038 */
+			for (i = 0; i < sn; i++)
+				OPJ_D(i) = opj_int_fix_mul(OPJ_D(i), 6659);	/*6660 */
+		}
+	}
+}
+
+void opj_dwt_encode_stepsize(OPJ_INT32 stepsize, OPJ_INT32 numbps, opj_stepsize_t *bandno_stepsize) {
+	OPJ_INT32 p, n;
+	p = opj_int_floorlog2(stepsize) - 13;
+	n = 11 - opj_int_floorlog2(stepsize);
+	bandno_stepsize->mant = (n < 0 ? stepsize >> -n : stepsize << n) & 0x7ff;
+	bandno_stepsize->expn = numbps - p;
+}
+
+/* 
+==========================================================
+   DWT interface
+==========================================================
+*/
+
+
+/* <summary>                            */
+/* Forward 5-3 wavelet transform in 2-D. */
+/* </summary>                           */
+INLINE OPJ_BOOL opj_dwt_encode_procedure(opj_tcd_tilecomp_t * tilec,void (*p_function)(OPJ_INT32 *, OPJ_INT32,OPJ_INT32,OPJ_INT32) )
+{
+	OPJ_INT32 i, j, k;
+	OPJ_INT32 *a = 00;
+	OPJ_INT32 *aj = 00;
+	OPJ_INT32 *bj = 00;
+	OPJ_INT32 w, l;
+
+	OPJ_INT32 rw;			/* width of the resolution level computed   */
+	OPJ_INT32 rh;			/* height of the resolution level computed  */
+	OPJ_UINT32 l_data_size;
+
+	opj_tcd_resolution_t * l_cur_res = 0;
+	opj_tcd_resolution_t * l_last_res = 0;
+
+	w = tilec->x1-tilec->x0;
+	l = (OPJ_INT32)tilec->numresolutions-1;
+	a = tilec->data;
+
+	l_cur_res = tilec->resolutions + l;
+	l_last_res = l_cur_res - 1;
+
+	l_data_size = opj_dwt_max_resolution( tilec->resolutions,tilec->numresolutions) * (OPJ_UINT32)sizeof(OPJ_INT32);
+	bj = (OPJ_INT32*)opj_malloc((size_t)l_data_size);
+	if (! bj) {
+		return OPJ_FALSE;
+	}
+	i = l;
+
+	while (i--) {
+		OPJ_INT32 rw1;		/* width of the resolution level once lower than computed one                                       */
+		OPJ_INT32 rh1;		/* height of the resolution level once lower than computed one                                      */
+		OPJ_INT32 cas_col;	/* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */
+		OPJ_INT32 cas_row;	/* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering   */
+		OPJ_INT32 dn, sn;
+
+		rw  = l_cur_res->x1 - l_cur_res->x0;
+		rh  = l_cur_res->y1 - l_cur_res->y0;
+		rw1 = l_last_res->x1 - l_last_res->x0;
+		rh1 = l_last_res->y1 - l_last_res->y0;
+
+		cas_row = l_cur_res->x0 & 1;
+		cas_col = l_cur_res->y0 & 1;
+
+		sn = rh1;
+		dn = rh - rh1;
+		for (j = 0; j < rw; ++j) {
+			aj = a + j;
+			for (k = 0; k < rh; ++k) {
+				bj[k] = aj[k*w];
+			}
+
+			(*p_function) (bj, dn, sn, cas_col);
+
+			opj_dwt_deinterleave_v(bj, aj, dn, sn, w, cas_col);
+		}
+
+		sn = rw1;
+		dn = rw - rw1;
+
+		for (j = 0; j < rh; j++) {
+			aj = a + j * w;
+			for (k = 0; k < rw; k++)  bj[k] = aj[k];
+			(*p_function) (bj, dn, sn, cas_row);
+			opj_dwt_deinterleave_h(bj, aj, dn, sn, cas_row);
+		}
+
+		l_cur_res = l_last_res;
+
+		--l_last_res;
+	}
+
+	opj_free(bj);
+	return OPJ_TRUE;
+}
+
+/* Forward 5-3 wavelet transform in 2-D. */
+/* </summary>                           */
+OPJ_BOOL opj_dwt_encode(opj_tcd_tilecomp_t * tilec)
+{
+	return opj_dwt_encode_procedure(tilec,opj_dwt_encode_1);
+}
+
+/* <summary>                            */
+/* Inverse 5-3 wavelet transform in 2-D. */
+/* </summary>                           */
+OPJ_BOOL opj_dwt_decode(opj_tcd_tilecomp_t* tilec, OPJ_UINT32 numres) {
+	return opj_dwt_decode_tile(tilec, numres, &opj_dwt_decode_1);
+}
+
+
+/* <summary>                          */
+/* Get gain of 5-3 wavelet transform. */
+/* </summary>                         */
+OPJ_UINT32 opj_dwt_getgain(OPJ_UINT32 orient) {
+	if (orient == 0)
+		return 0;
+	if (orient == 1 || orient == 2)
+		return 1;
+	return 2;
+}
+
+/* <summary>                */
+/* Get norm of 5-3 wavelet. */
+/* </summary>               */
+OPJ_FLOAT64 opj_dwt_getnorm(OPJ_UINT32 level, OPJ_UINT32 orient) {
+	return opj_dwt_norms[orient][level];
+}
+
+/* <summary>                             */
+/* Forward 9-7 wavelet transform in 2-D. */
+/* </summary>                            */
+OPJ_BOOL opj_dwt_encode_real(opj_tcd_tilecomp_t * tilec)
+{
+	return opj_dwt_encode_procedure(tilec,opj_dwt_encode_1_real);
+}
+
+/* <summary>                          */
+/* Get gain of 9-7 wavelet transform. */
+/* </summary>                         */
+OPJ_UINT32 opj_dwt_getgain_real(OPJ_UINT32 orient) {
+	(void)orient;
+	return 0;
+}
+
+/* <summary>                */
+/* Get norm of 9-7 wavelet. */
+/* </summary>               */
+OPJ_FLOAT64 opj_dwt_getnorm_real(OPJ_UINT32 level, OPJ_UINT32 orient) {
+	return opj_dwt_norms_real[orient][level];
+}
+
+void opj_dwt_calc_explicit_stepsizes(opj_tccp_t * tccp, OPJ_UINT32 prec) {
+	OPJ_UINT32 numbands, bandno;
+	numbands = 3 * tccp->numresolutions - 2;
+	for (bandno = 0; bandno < numbands; bandno++) {
+		OPJ_FLOAT64 stepsize;
+		OPJ_UINT32 resno, level, orient, gain;
+
+		resno = (bandno == 0) ? 0 : ((bandno - 1) / 3 + 1);
+		orient = (bandno == 0) ? 0 : ((bandno - 1) % 3 + 1);
+		level = tccp->numresolutions - 1 - resno;
+		gain = (tccp->qmfbid == 0) ? 0 : ((orient == 0) ? 0 : (((orient == 1) || (orient == 2)) ? 1 : 2));
+		if (tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) {
+			stepsize = 1.0;
+		} else {
+			OPJ_FLOAT64 norm = opj_dwt_norms_real[orient][level];
+			stepsize = (1 << (gain)) / norm;
+		}
+		opj_dwt_encode_stepsize((OPJ_INT32) floor(stepsize * 8192.0), (OPJ_INT32)(prec + gain), &tccp->stepsizes[bandno]);
+	}
+}
+
+/* <summary>                             */
+/* Determine maximum computed resolution level for inverse wavelet transform */
+/* </summary>                            */
+OPJ_UINT32 opj_dwt_max_resolution(opj_tcd_resolution_t* restrict r, OPJ_UINT32 i) {
+	OPJ_UINT32 mr	= 0;
+	OPJ_UINT32 w;
+	while( --i ) {
+		++r;
+		if( mr < ( w = (OPJ_UINT32)(r->x1 - r->x0) ) )
+			mr = w ;
+		if( mr < ( w = (OPJ_UINT32)(r->y1 - r->y0) ) )
+			mr = w ;
+	}
+	return mr ;
+}
+
+/* <summary>                            */
+/* Inverse wavelet transform in 2-D.     */
+/* </summary>                           */
+OPJ_BOOL opj_dwt_decode_tile(opj_tcd_tilecomp_t* tilec, OPJ_UINT32 numres, DWT1DFN dwt_1D) {
+	opj_dwt_t h;
+	opj_dwt_t v;
+
+	opj_tcd_resolution_t* tr = tilec->resolutions;
+
+	OPJ_UINT32 rw = (OPJ_UINT32)(tr->x1 - tr->x0);	/* width of the resolution level computed */
+	OPJ_UINT32 rh = (OPJ_UINT32)(tr->y1 - tr->y0);	/* height of the resolution level computed */
+
+	OPJ_UINT32 w = (OPJ_UINT32)(tilec->x1 - tilec->x0);
+
+	h.mem = (OPJ_INT32*)
+	opj_aligned_malloc(opj_dwt_max_resolution(tr, numres) * sizeof(OPJ_INT32));
+	if (! h.mem){
+		return OPJ_FALSE;
+	}
+
+	v.mem = h.mem;
+
+	while( --numres) {
+		OPJ_INT32 * restrict tiledp = tilec->data;
+		OPJ_UINT32 j;
+
+		++tr;
+		h.sn = (OPJ_INT32)rw;
+		v.sn = (OPJ_INT32)rh;
+
+		rw = (OPJ_UINT32)(tr->x1 - tr->x0);
+		rh = (OPJ_UINT32)(tr->y1 - tr->y0);
+
+		h.dn = (OPJ_INT32)(rw - (OPJ_UINT32)h.sn);
+		h.cas = tr->x0 % 2;
+
+		for(j = 0; j < rh; ++j) {
+			opj_dwt_interleave_h(&h, &tiledp[j*w]);
+			(dwt_1D)(&h);
+			memcpy(&tiledp[j*w], h.mem, rw * sizeof(OPJ_INT32));
+		}
+
+		v.dn = (OPJ_INT32)(rh - (OPJ_UINT32)v.sn);
+		v.cas = tr->y0 % 2;
+
+		for(j = 0; j < rw; ++j){
+			OPJ_UINT32 k;
+			opj_dwt_interleave_v(&v, &tiledp[j], (OPJ_INT32)w);
+			(dwt_1D)(&v);
+			for(k = 0; k < rh; ++k) {
+				tiledp[k * w + j] = v.mem[k];
+			}
+		}
+	}
+	opj_aligned_free(h.mem);
+	return OPJ_TRUE;
+}
+
+void opj_v4dwt_interleave_h(opj_v4dwt_t* restrict w, OPJ_FLOAT32* restrict a, OPJ_INT32 x, OPJ_INT32 size){
+	OPJ_FLOAT32* restrict bi = (OPJ_FLOAT32*) (w->wavelet + w->cas);
+	OPJ_INT32 count = w->sn;
+	OPJ_INT32 i, k;
+
+	for(k = 0; k < 2; ++k){
+		if ( count + 3 * x < size && ((size_t) a & 0x0f) == 0 && ((size_t) bi & 0x0f) == 0 && (x & 0x0f) == 0 ) {
+			/* Fast code path */
+			for(i = 0; i < count; ++i){
+				OPJ_INT32 j = i;
+				bi[i*8    ] = a[j];
+				j += x;
+				bi[i*8 + 1] = a[j];
+				j += x;
+				bi[i*8 + 2] = a[j];
+				j += x;
+				bi[i*8 + 3] = a[j];
+			}
+		}
+		else {
+			/* Slow code path */
+			for(i = 0; i < count; ++i){
+				OPJ_INT32 j = i;
+				bi[i*8    ] = a[j];
+				j += x;
+				if(j >= size) continue;
+				bi[i*8 + 1] = a[j];
+				j += x;
+				if(j >= size) continue;
+				bi[i*8 + 2] = a[j];
+				j += x;
+				if(j >= size) continue;
+				bi[i*8 + 3] = a[j]; /* This one*/
+			}
+		}
+
+		bi = (OPJ_FLOAT32*) (w->wavelet + 1 - w->cas);
+		a += w->sn;
+		size -= w->sn;
+		count = w->dn;
+	}
+}
+
+void opj_v4dwt_interleave_v(opj_v4dwt_t* restrict v , OPJ_FLOAT32* restrict a , OPJ_INT32 x, OPJ_INT32 nb_elts_read){
+	opj_v4_t* restrict bi = v->wavelet + v->cas;
+	OPJ_INT32 i;
+
+	for(i = 0; i < v->sn; ++i){
+		memcpy(&bi[i*2], &a[i*x], (size_t)nb_elts_read * sizeof(OPJ_FLOAT32));
+	}
+
+	a += v->sn * x;
+	bi = v->wavelet + 1 - v->cas;
+
+	for(i = 0; i < v->dn; ++i){
+		memcpy(&bi[i*2], &a[i*x], (size_t)nb_elts_read * sizeof(OPJ_FLOAT32));
+	}
+}
+
+#ifdef __SSE__
+
+void opj_v4dwt_decode_step1_sse(opj_v4_t* w, OPJ_INT32 count, const __m128 c){
+	__m128* restrict vw = (__m128*) w;
+	OPJ_INT32 i;
+	/* 4x unrolled loop */
+	for(i = 0; i < count >> 2; ++i){
+		*vw = _mm_mul_ps(*vw, c);
+		vw += 2;
+		*vw = _mm_mul_ps(*vw, c);
+		vw += 2;
+		*vw = _mm_mul_ps(*vw, c);
+		vw += 2;
+		*vw = _mm_mul_ps(*vw, c);
+		vw += 2;
+	}
+	count &= 3;
+	for(i = 0; i < count; ++i){
+		*vw = _mm_mul_ps(*vw, c);
+		vw += 2;
+	}
+}
+
+void opj_v4dwt_decode_step2_sse(opj_v4_t* l, opj_v4_t* w, OPJ_INT32 k, OPJ_INT32 m, __m128 c){
+	__m128* restrict vl = (__m128*) l;
+	__m128* restrict vw = (__m128*) w;
+	OPJ_INT32 i;
+	__m128 tmp1, tmp2, tmp3;
+	tmp1 = vl[0];
+	for(i = 0; i < m; ++i){
+		tmp2 = vw[-1];
+		tmp3 = vw[ 0];
+		vw[-1] = _mm_add_ps(tmp2, _mm_mul_ps(_mm_add_ps(tmp1, tmp3), c));
+		tmp1 = tmp3;
+		vw += 2;
+	}
+	vl = vw - 2;
+	if(m >= k){
+		return;
+	}
+	c = _mm_add_ps(c, c);
+	c = _mm_mul_ps(c, vl[0]);
+	for(; m < k; ++m){
+		__m128 tmp = vw[-1];
+		vw[-1] = _mm_add_ps(tmp, c);
+		vw += 2;
+	}
+}
+
+#else
+
+void opj_v4dwt_decode_step1(opj_v4_t* w, OPJ_INT32 count, const OPJ_FLOAT32 c)
+{
+	OPJ_FLOAT32* restrict fw = (OPJ_FLOAT32*) w;
+	OPJ_INT32 i;
+	for(i = 0; i < count; ++i){
+		OPJ_FLOAT32 tmp1 = fw[i*8    ];
+		OPJ_FLOAT32 tmp2 = fw[i*8 + 1];
+		OPJ_FLOAT32 tmp3 = fw[i*8 + 2];
+		OPJ_FLOAT32 tmp4 = fw[i*8 + 3];
+		fw[i*8    ] = tmp1 * c;
+		fw[i*8 + 1] = tmp2 * c;
+		fw[i*8 + 2] = tmp3 * c;
+		fw[i*8 + 3] = tmp4 * c;
+	}
+}
+
+void opj_v4dwt_decode_step2(opj_v4_t* l, opj_v4_t* w, OPJ_INT32 k, OPJ_INT32 m, OPJ_FLOAT32 c)
+{
+	OPJ_FLOAT32* restrict fl = (OPJ_FLOAT32*) l;
+	OPJ_FLOAT32* restrict fw = (OPJ_FLOAT32*) w;
+	OPJ_INT32 i;
+	for(i = 0; i < m; ++i){
+		OPJ_FLOAT32 tmp1_1 = fl[0];
+		OPJ_FLOAT32 tmp1_2 = fl[1];
+		OPJ_FLOAT32 tmp1_3 = fl[2];
+		OPJ_FLOAT32 tmp1_4 = fl[3];
+		OPJ_FLOAT32 tmp2_1 = fw[-4];
+		OPJ_FLOAT32 tmp2_2 = fw[-3];
+		OPJ_FLOAT32 tmp2_3 = fw[-2];
+		OPJ_FLOAT32 tmp2_4 = fw[-1];
+		OPJ_FLOAT32 tmp3_1 = fw[0];
+		OPJ_FLOAT32 tmp3_2 = fw[1];
+		OPJ_FLOAT32 tmp3_3 = fw[2];
+		OPJ_FLOAT32 tmp3_4 = fw[3];
+		fw[-4] = tmp2_1 + ((tmp1_1 + tmp3_1) * c);
+		fw[-3] = tmp2_2 + ((tmp1_2 + tmp3_2) * c);
+		fw[-2] = tmp2_3 + ((tmp1_3 + tmp3_3) * c);
+		fw[-1] = tmp2_4 + ((tmp1_4 + tmp3_4) * c);
+		fl = fw;
+		fw += 8;
+	}
+	if(m < k){
+		OPJ_FLOAT32 c1;
+		OPJ_FLOAT32 c2;
+		OPJ_FLOAT32 c3;
+		OPJ_FLOAT32 c4;
+		c += c;
+		c1 = fl[0] * c;
+		c2 = fl[1] * c;
+		c3 = fl[2] * c;
+		c4 = fl[3] * c;
+		for(; m < k; ++m){
+			OPJ_FLOAT32 tmp1 = fw[-4];
+			OPJ_FLOAT32 tmp2 = fw[-3];
+			OPJ_FLOAT32 tmp3 = fw[-2];
+			OPJ_FLOAT32 tmp4 = fw[-1];
+			fw[-4] = tmp1 + c1;
+			fw[-3] = tmp2 + c2;
+			fw[-2] = tmp3 + c3;
+			fw[-1] = tmp4 + c4;
+			fw += 8;
+		}
+	}
+}
+
+#endif
+
+/* <summary>                             */
+/* Inverse 9-7 wavelet transform in 1-D. */
+/* </summary>                            */
+void opj_v4dwt_decode(opj_v4dwt_t* restrict dwt)
+{
+	OPJ_INT32 a, b;
+	if(dwt->cas == 0) {
+		if(!((dwt->dn > 0) || (dwt->sn > 1))){
+			return;
+		}
+		a = 0;
+		b = 1;
+	}else{
+		if(!((dwt->sn > 0) || (dwt->dn > 1))) {
+			return;
+		}
+		a = 1;
+		b = 0;
+	}
+#ifdef __SSE__
+	opj_v4dwt_decode_step1_sse(dwt->wavelet+a, dwt->sn, _mm_set1_ps(opj_K));
+	opj_v4dwt_decode_step1_sse(dwt->wavelet+b, dwt->dn, _mm_set1_ps(opj_c13318));
+	opj_v4dwt_decode_step2_sse(dwt->wavelet+b, dwt->wavelet+a+1, dwt->sn, opj_int_min(dwt->sn, dwt->dn-a), _mm_set1_ps(opj_dwt_delta));
+	opj_v4dwt_decode_step2_sse(dwt->wavelet+a, dwt->wavelet+b+1, dwt->dn, opj_int_min(dwt->dn, dwt->sn-b), _mm_set1_ps(opj_dwt_gamma));
+	opj_v4dwt_decode_step2_sse(dwt->wavelet+b, dwt->wavelet+a+1, dwt->sn, opj_int_min(dwt->sn, dwt->dn-a), _mm_set1_ps(opj_dwt_beta));
+	opj_v4dwt_decode_step2_sse(dwt->wavelet+a, dwt->wavelet+b+1, dwt->dn, opj_int_min(dwt->dn, dwt->sn-b), _mm_set1_ps(opj_dwt_alpha));
+#else
+	opj_v4dwt_decode_step1(dwt->wavelet+a, dwt->sn, opj_K);
+	opj_v4dwt_decode_step1(dwt->wavelet+b, dwt->dn, opj_c13318);
+	opj_v4dwt_decode_step2(dwt->wavelet+b, dwt->wavelet+a+1, dwt->sn, opj_int_min(dwt->sn, dwt->dn-a), opj_dwt_delta);
+	opj_v4dwt_decode_step2(dwt->wavelet+a, dwt->wavelet+b+1, dwt->dn, opj_int_min(dwt->dn, dwt->sn-b), opj_dwt_gamma);
+	opj_v4dwt_decode_step2(dwt->wavelet+b, dwt->wavelet+a+1, dwt->sn, opj_int_min(dwt->sn, dwt->dn-a), opj_dwt_beta);
+	opj_v4dwt_decode_step2(dwt->wavelet+a, dwt->wavelet+b+1, dwt->dn, opj_int_min(dwt->dn, dwt->sn-b), opj_dwt_alpha);
+#endif
+}
+
+
+/* <summary>                             */
+/* Inverse 9-7 wavelet transform in 2-D. */
+/* </summary>                            */
+OPJ_BOOL opj_dwt_decode_real(opj_tcd_tilecomp_t* restrict tilec, OPJ_UINT32 numres)
+{
+	opj_v4dwt_t h;
+	opj_v4dwt_t v;
+
+	opj_tcd_resolution_t* res = tilec->resolutions;
+
+	OPJ_UINT32 rw = (OPJ_UINT32)(res->x1 - res->x0);	/* width of the resolution level computed */
+	OPJ_UINT32 rh = (OPJ_UINT32)(res->y1 - res->y0);	/* height of the resolution level computed */
+
+	OPJ_UINT32 w = (OPJ_UINT32)(tilec->x1 - tilec->x0);
+
+	h.wavelet = (opj_v4_t*) opj_aligned_malloc((opj_dwt_max_resolution(res, numres)+5) * sizeof(opj_v4_t));
+	v.wavelet = h.wavelet;
+
+	while( --numres) {
+		OPJ_FLOAT32 * restrict aj = (OPJ_FLOAT32*) tilec->data;
+		OPJ_UINT32 bufsize = (OPJ_UINT32)((tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0));
+		OPJ_INT32 j;
+
+		h.sn = (OPJ_INT32)rw;
+		v.sn = (OPJ_INT32)rh;
+
+		++res;
+
+		rw = (OPJ_UINT32)(res->x1 - res->x0);	/* width of the resolution level computed */
+		rh = (OPJ_UINT32)(res->y1 - res->y0);	/* height of the resolution level computed */
+
+		h.dn = (OPJ_INT32)(rw - (OPJ_UINT32)h.sn);
+		h.cas = res->x0 % 2;
+
+		for(j = (OPJ_INT32)rh; j > 3; j -= 4) {
+			OPJ_INT32 k;
+			opj_v4dwt_interleave_h(&h, aj, (OPJ_INT32)w, (OPJ_INT32)bufsize);
+			opj_v4dwt_decode(&h);
+
+			for(k = (OPJ_INT32)rw; --k >= 0;){
+				aj[k               ] = h.wavelet[k].f[0];
+				aj[k+(OPJ_INT32)w  ] = h.wavelet[k].f[1];
+				aj[k+(OPJ_INT32)w*2] = h.wavelet[k].f[2];
+				aj[k+(OPJ_INT32)w*3] = h.wavelet[k].f[3];
+			}
+
+			aj += w*4;
+			bufsize -= w*4;
+		}
+
+		if (rh & 0x03) {
+			OPJ_INT32 k;
+			j = rh & 0x03;
+			opj_v4dwt_interleave_h(&h, aj, (OPJ_INT32)w, (OPJ_INT32)bufsize);
+			opj_v4dwt_decode(&h);
+			for(k = (OPJ_INT32)rw; --k >= 0;){
+				switch(j) {
+					case 3: aj[k+(OPJ_INT32)w*2] = h.wavelet[k].f[2];
+					case 2: aj[k+(OPJ_INT32)w  ] = h.wavelet[k].f[1];
+					case 1: aj[k               ] = h.wavelet[k].f[0];
+				}
+			}
+		}
+
+		v.dn = (OPJ_INT32)(rh - (OPJ_UINT32)v.sn);
+		v.cas = res->y0 % 2;
+
+		aj = (OPJ_FLOAT32*) tilec->data;
+		for(j = (OPJ_INT32)rw; j > 3; j -= 4){
+			OPJ_UINT32 k;
+
+			opj_v4dwt_interleave_v(&v, aj, (OPJ_INT32)w, 4);
+			opj_v4dwt_decode(&v);
+
+			for(k = 0; k < rh; ++k){
+				memcpy(&aj[k*w], &v.wavelet[k], 4 * sizeof(OPJ_FLOAT32));
+			}
+			aj += 4;
+		}
+
+		if (rw & 0x03){
+			OPJ_UINT32 k;
+
+			j = rw & 0x03;
+
+			opj_v4dwt_interleave_v(&v, aj, (OPJ_INT32)w, j);
+			opj_v4dwt_decode(&v);
+
+			for(k = 0; k < rh; ++k){
+				memcpy(&aj[k*w], &v.wavelet[k], (size_t)j * sizeof(OPJ_FLOAT32));
+			}
+		}
+	}
+
+	opj_aligned_free(h.wavelet);
+	return OPJ_TRUE;
+}
diff --git a/Source/LibOpenJPEG/dwt.h b/Source/LibOpenJPEG/dwt.h
index c67c456..fae3726 100644
--- a/Source/LibOpenJPEG/dwt.h
+++ b/Source/LibOpenJPEG/dwt.h
@@ -1,113 +1,116 @@
-/*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
- * Copyright (c) 2001-2003, David Janssens
- * Copyright (c) 2002-2003, Yannick Verschueren
- * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __DWT_H
-#define __DWT_H
-/**
- at file dwt.h
- at brief Implementation of a discrete wavelet transform (DWT)
-
-The functions in DWT.C have for goal to realize forward and inverse discret wavelet
-transform with filter 5-3 (reversible) and filter 9-7 (irreversible). The functions in
-DWT.C are used by some function in TCD.C.
-*/
-
-/** @defgroup DWT DWT - Implementation of a discrete wavelet transform */
-/*@{*/
-
-
-/** @name Exported functions */
-/*@{*/
-/* ----------------------------------------------------------------------- */
-/**
-Forward 5-3 wavelet tranform in 2-D. 
-Apply a reversible DWT transform to a component of an image.
- at param tilec Tile component information (current tile)
-*/
-void dwt_encode(opj_tcd_tilecomp_t * tilec);
-/**
-Inverse 5-3 wavelet tranform in 2-D.
-Apply a reversible inverse DWT transform to a component of an image.
- at param tilec Tile component information (current tile)
- at param numres Number of resolution levels to decode
-*/
-void dwt_decode(opj_tcd_tilecomp_t* tilec, int numres);
-/**
-Get the gain of a subband for the reversible 5-3 DWT.
- at param orient Number that identifies the subband (0->LL, 1->HL, 2->LH, 3->HH)
- at return Returns 0 if orient = 0, returns 1 if orient = 1 or 2, returns 2 otherwise
-*/
-int dwt_getgain(int orient);
-/**
-Get the norm of a wavelet function of a subband at a specified level for the reversible 5-3 DWT.
- at param level Level of the wavelet function
- at param orient Band of the wavelet function
- at return Returns the norm of the wavelet function
-*/
-double dwt_getnorm(int level, int orient);
-/**
-Forward 9-7 wavelet transform in 2-D. 
-Apply an irreversible DWT transform to a component of an image.
- at param tilec Tile component information (current tile)
-*/
-void dwt_encode_real(opj_tcd_tilecomp_t * tilec);
-/**
-Inverse 9-7 wavelet transform in 2-D. 
-Apply an irreversible inverse DWT transform to a component of an image.
- at param tilec Tile component information (current tile)
- at param numres Number of resolution levels to decode
-*/
-void dwt_decode_real(opj_tcd_tilecomp_t* tilec, int numres);
-/**
-Get the gain of a subband for the irreversible 9-7 DWT.
- at param orient Number that identifies the subband (0->LL, 1->HL, 2->LH, 3->HH)
- at return Returns the gain of the 9-7 wavelet transform
-*/
-int dwt_getgain_real(int orient);
-/**
-Get the norm of a wavelet function of a subband at a specified level for the irreversible 9-7 DWT
- at param level Level of the wavelet function
- at param orient Band of the wavelet function
- at return Returns the norm of the 9-7 wavelet
-*/
-double dwt_getnorm_real(int level, int orient);
-/**
-Explicit calculation of the Quantization Stepsizes 
- at param tccp Tile-component coding parameters
- at param prec Precint analyzed
-*/
-void dwt_calc_explicit_stepsizes(opj_tccp_t * tccp, int prec);
-/* ----------------------------------------------------------------------- */
-/*@}*/
-
-/*@}*/
-
-#endif /* __DWT_H */
+/*
+ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2007, Professor Benoit Macq
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __DWT_H
+#define __DWT_H
+/**
+ at file dwt.h
+ at brief Implementation of a discrete wavelet transform (DWT)
+
+The functions in DWT.C have for goal to realize forward and inverse discret wavelet
+transform with filter 5-3 (reversible) and filter 9-7 (irreversible). The functions in
+DWT.C are used by some function in TCD.C.
+*/
+
+/** @defgroup DWT DWT - Implementation of a discrete wavelet transform */
+/*@{*/
+
+
+/** @name Exported functions */
+/*@{*/
+/* ----------------------------------------------------------------------- */
+/**
+Forward 5-3 wavelet tranform in 2-D. 
+Apply a reversible DWT transform to a component of an image.
+ at param tilec Tile component information (current tile)
+*/
+OPJ_BOOL opj_dwt_encode(opj_tcd_tilecomp_t * tilec);
+
+/**
+Inverse 5-3 wavelet tranform in 2-D.
+Apply a reversible inverse DWT transform to a component of an image.
+ at param tilec Tile component information (current tile)
+ at param numres Number of resolution levels to decode
+*/
+OPJ_BOOL opj_dwt_decode(opj_tcd_tilecomp_t* tilec, OPJ_UINT32 numres);
+
+/**
+Get the gain of a subband for the reversible 5-3 DWT.
+ at param orient Number that identifies the subband (0->LL, 1->HL, 2->LH, 3->HH)
+ at return Returns 0 if orient = 0, returns 1 if orient = 1 or 2, returns 2 otherwise
+*/
+OPJ_UINT32 opj_dwt_getgain(OPJ_UINT32 orient) ;
+/**
+Get the norm of a wavelet function of a subband at a specified level for the reversible 5-3 DWT.
+ at param level Level of the wavelet function
+ at param orient Band of the wavelet function
+ at return Returns the norm of the wavelet function
+*/
+OPJ_FLOAT64 opj_dwt_getnorm(OPJ_UINT32 level, OPJ_UINT32 orient);
+/**
+Forward 9-7 wavelet transform in 2-D. 
+Apply an irreversible DWT transform to a component of an image.
+ at param tilec Tile component information (current tile)
+*/
+OPJ_BOOL opj_dwt_encode_real(opj_tcd_tilecomp_t * tilec);
+/**
+Inverse 9-7 wavelet transform in 2-D. 
+Apply an irreversible inverse DWT transform to a component of an image.
+ at param tilec Tile component information (current tile)
+ at param numres Number of resolution levels to decode
+*/
+OPJ_BOOL opj_dwt_decode_real(opj_tcd_tilecomp_t* restrict tilec, OPJ_UINT32 numres);
+
+/**
+Get the gain of a subband for the irreversible 9-7 DWT.
+ at param orient Number that identifies the subband (0->LL, 1->HL, 2->LH, 3->HH)
+ at return Returns the gain of the 9-7 wavelet transform
+*/
+OPJ_UINT32 opj_dwt_getgain_real(OPJ_UINT32 orient);
+/**
+Get the norm of a wavelet function of a subband at a specified level for the irreversible 9-7 DWT
+ at param level Level of the wavelet function
+ at param orient Band of the wavelet function
+ at return Returns the norm of the 9-7 wavelet
+*/
+OPJ_FLOAT64 opj_dwt_getnorm_real(OPJ_UINT32 level, OPJ_UINT32 orient);
+/**
+Explicit calculation of the Quantization Stepsizes 
+ at param tccp Tile-component coding parameters
+ at param prec Precint analyzed
+*/
+void opj_dwt_calc_explicit_stepsizes(opj_tccp_t * tccp, OPJ_UINT32 prec);
+/* ----------------------------------------------------------------------- */
+/*@}*/
+
+/*@}*/
+
+#endif /* __DWT_H */
diff --git a/Source/LibOpenJPEG/event.c b/Source/LibOpenJPEG/event.c
index 81bc89b..6c53515 100644
--- a/Source/LibOpenJPEG/event.c
+++ b/Source/LibOpenJPEG/event.c
@@ -1,130 +1,141 @@
-/*
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "opj_includes.h"
-
-#ifdef WIN32
-	/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
-	#if !defined(vsnprintf) && !defined(NO_vsnprintf)
-		#if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 )
-			#define vsnprintf _vsnprintf
-		#endif
-	#endif
+/*
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2008;2011-2012, Centre National d'Etudes Spatiales (CNES), France 
+ * Copyright (c) 2012, CS Systemes d'Information, France
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "opj_includes.h"
+
+/* ==========================================================
+     Utility functions
+   ==========================================================*/
+
+#ifdef OPJ_CODE_NOT_USED
+#ifndef _WIN32
+static char*
+i2a(unsigned i, char *a, unsigned r) {
+	if (i/r > 0) a = i2a(i/r,a,r);
+	*a = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[i%r];
+	return a+1;
+}
+
+/** 
+ Transforms integer i into an ascii string and stores the result in a; 
+ string is encoded in the base indicated by r.
+ @param i Number to be converted
+ @param a String result
+ @param r Base of value; must be in the range 2 - 36
+ @return Returns a
+*/
+static char *
+_itoa(int i, char *a, int r) {
+	r = ((r < 2) || (r > 36)) ? 10 : r;
+	if(i < 0) {
+		*a = '-';
+		*i2a(-i, a+1, r) = 0;
+	}
+	else *i2a(i, a, r) = 0;
+	return a;
+}
+
+#endif /* !_WIN32 */
 #endif
-
-/* ==========================================================
-     Utility functions
-   ==========================================================*/
-
-#ifdef OPJ_CODE_NOT_USED
-#ifndef _WIN32
-static char*
-i2a(unsigned i, char *a, unsigned r) {
-	if (i/r > 0) a = i2a(i/r,a,r);
-	*a = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[i%r];
-	return a+1;
-}
-
-/** 
- Transforms integer i into an ascii string and stores the result in a; 
- string is encoded in the base indicated by r.
- @param i Number to be converted
- @param a String result
- @param r Base of value; must be in the range 2 - 36
- @return Returns a
-*/
-static char *
-_itoa(int i, char *a, int r) {
-	r = ((r < 2) || (r > 36)) ? 10 : r;
-	if(i < 0) {
-		*a = '-';
-		*i2a(-i, a+1, r) = 0;
-	}
-	else *i2a(i, a, r) = 0;
-	return a;
-}
-
-#endif /* !_WIN32 */
-#endif
-/* ----------------------------------------------------------------------- */
-
-opj_event_mgr_t* OPJ_CALLCONV opj_set_event_mgr(opj_common_ptr cinfo, opj_event_mgr_t *event_mgr, void *context) {
-	if(cinfo) {
-		opj_event_mgr_t *previous = cinfo->event_mgr;
-		cinfo->event_mgr = event_mgr;
-		cinfo->client_data = context;
-		return previous;
-	}
-
-	return NULL;
-}
-
-opj_bool opj_event_msg(opj_common_ptr cinfo, int event_type, const char *fmt, ...) {
-#define MSG_SIZE 512 /* 512 bytes should be more than enough for a short message */
-	opj_msg_callback msg_handler = NULL;
-
-	opj_event_mgr_t *event_mgr = cinfo->event_mgr;
-	if(event_mgr != NULL) {
-		switch(event_type) {
-			case EVT_ERROR:
-				msg_handler = event_mgr->error_handler;
-				break;
-			case EVT_WARNING:
-				msg_handler = event_mgr->warning_handler;
-				break;
-			case EVT_INFO:
-				msg_handler = event_mgr->info_handler;
-				break;
-			default:
-				break;
-		}
-		if(msg_handler == NULL) {
-			return OPJ_FALSE;
-		}
-	} else {
-		return OPJ_FALSE;
-	}
-
-	if ((fmt != NULL) && (event_mgr != NULL)) {
-		va_list arg;
-		int str_length/*, i, j*/; /* UniPG */
-		char message[MSG_SIZE];
-		/* initialize the optional parameter list */
-		va_start(arg, fmt);
-		/* parse the format string and put the result in 'message' */
-		str_length = vsnprintf(message, MSG_SIZE, fmt, arg); /* UniPG */
-		/* deinitialize the optional parameter list */
-		va_end(arg);
-
-		/* output the message to the user program */
-    if( str_length > -1 && str_length < MSG_SIZE )
-      msg_handler(message, cinfo->client_data);
-    else return OPJ_FALSE;
-	}
-
-	return OPJ_TRUE;
-}
-
+
+/* ----------------------------------------------------------------------- */
+/**
+ * Default callback function.
+ * Do nothing.
+ */
+static void opj_default_callback (const char *msg, void *client_data)
+{
+    OPJ_ARG_NOT_USED(msg);
+    OPJ_ARG_NOT_USED(client_data);
+}
+
+/* ----------------------------------------------------------------------- */
+
+
+/* ----------------------------------------------------------------------- */
+OPJ_BOOL opj_event_msg(opj_event_mgr_t* p_event_mgr, OPJ_INT32 event_type, const char *fmt, ...) {
+#define OPJ_MSG_SIZE 512 /* 512 bytes should be more than enough for a short message */
+	opj_msg_callback msg_handler = 00;
+	void * l_data = 00;
+
+	if(p_event_mgr != 00) {
+		switch(event_type) {
+			case EVT_ERROR:
+				msg_handler = p_event_mgr->error_handler;
+				l_data = p_event_mgr->m_error_data;
+				break;
+			case EVT_WARNING:
+				msg_handler = p_event_mgr->warning_handler;
+				l_data = p_event_mgr->m_warning_data;
+				break;
+			case EVT_INFO:
+				msg_handler = p_event_mgr->info_handler;
+				l_data = p_event_mgr->m_info_data;
+				break;
+			default:
+				break;
+		}
+		if(msg_handler == 00) {
+			return OPJ_FALSE;
+		}
+	} else {
+		return OPJ_FALSE;
+	}
+
+	if ((fmt != 00) && (p_event_mgr != 00)) {
+		va_list arg;
+		size_t str_length/*, i, j*/; /* UniPG */
+		char message[OPJ_MSG_SIZE];
+		memset(message, 0, OPJ_MSG_SIZE);
+		/* initialize the optional parameter list */
+		va_start(arg, fmt);
+		/* check the length of the format string */
+		str_length = (strlen(fmt) > OPJ_MSG_SIZE) ? OPJ_MSG_SIZE : strlen(fmt);
+        (void)str_length;
+		/* parse the format string and put the result in 'message' */
+		vsprintf(message, fmt, arg); /* UniPG */
+		/* deinitialize the optional parameter list */
+		va_end(arg);
+
+		/* output the message to the user program */
+		msg_handler(message, l_data);
+	}
+
+	return OPJ_TRUE;
+}
+
+void opj_set_default_event_handler(opj_event_mgr_t * p_manager)
+{
+	p_manager->m_error_data = 00;
+	p_manager->m_warning_data = 00;
+	p_manager->m_info_data = 00;
+	p_manager->error_handler = opj_default_callback;
+	p_manager->info_handler = opj_default_callback;
+	p_manager->warning_handler = opj_default_callback;
+}
+
diff --git a/Source/LibOpenJPEG/event.h b/Source/LibOpenJPEG/event.h
index 211acc4..4d89576 100644
--- a/Source/LibOpenJPEG/event.h
+++ b/Source/LibOpenJPEG/event.h
@@ -1,58 +1,97 @@
-/*
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef __EVENT_H
-#define __EVENT_H
-/**
- at file event.h
- at brief Implementation of a event callback system
-
-The functions in EVENT.C have for goal to send output messages (errors, warnings, debug) to the user.
-*/
-
-#define EVT_ERROR	1	/**< Error event type */
-#define EVT_WARNING	2	/**< Warning event type */
-#define EVT_INFO	4	/**< Debug event type */
-
-/** @defgroup EVENT EVENT - Implementation of a event callback system */
-/*@{*/
-
-/** @name Exported functions (see also openjpeg.h) */
-/*@{*/
-/* ----------------------------------------------------------------------- */
-/**
-Write formatted data to a string and send the string to a user callback. 
- at param cinfo Codec context info
- at param event_type Event type or callback to use to send the message
- at param fmt Format-control string (plus optionnal arguments)
- at return Returns true if successful, returns false otherwise
-*/
-opj_bool opj_event_msg(opj_common_ptr cinfo, int event_type, const char *fmt, ...);
-/* ----------------------------------------------------------------------- */
-/*@}*/
-
-/*@}*/
-
-#endif /* __EVENT_H */
+/*
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2008;2011-2012, Centre National d'Etudes Spatiales (CNES), France 
+ * Copyright (c) 2012, CS Systemes d'Information, France
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef __EVENT_H
+#define __EVENT_H
+/**
+ at file event.h
+ at brief Implementation of a event callback system
+
+The functions in EVENT.C have for goal to send output messages (errors, warnings, debug) to the user.
+*/
+/**
+Message handler object
+used for 
+<ul>
+<li>Error messages
+<li>Warning messages
+<li>Debugging messages
+</ul>
+*/
+typedef struct opj_event_mgr 
+{
+	/** Data to call the event manager upon */
+	void *			m_error_data;
+	/** Data to call the event manager upon */
+	void *			m_warning_data;
+	/** Data to call the event manager upon */
+	void *			m_info_data;
+	/** Error message callback if available, NULL otherwise */
+	opj_msg_callback error_handler;
+	/** Warning message callback if available, NULL otherwise */
+	opj_msg_callback warning_handler;
+	/** Debug message callback if available, NULL otherwise */
+	opj_msg_callback info_handler;
+} opj_event_mgr_t;
+
+
+#define EVT_ERROR	1	/**< Error event type */
+#define EVT_WARNING	2	/**< Warning event type */
+#define EVT_INFO	4	/**< Debug event type */
+
+/** @defgroup EVENT EVENT - Implementation of a event callback system */
+/*@{*/
+
+/** @name Exported functions (see also openjpeg.h) */
+/*@{*/
+/* ----------------------------------------------------------------------- */
+
+
+/* ----------------------------------------------------------------------- */
+
+/**
+ * Write formatted data to a string and send the string to a user callback.
+ *
+ * @param event_mgr			Event handler
+ * @param event_type 		Event type or callback to use to send the message
+ * @param fmt 				Format-control string (plus optional arguments)
+ *
+ * @return Returns true if successful, returns false otherwise
+ */
+OPJ_BOOL opj_event_msg(opj_event_mgr_t* event_mgr, OPJ_INT32 event_type, const char *fmt, ...);
+/* ----------------------------------------------------------------------- */
+
+/**
+ * Set the event manager with the default callback function for the 3 levels.
+ */
+void opj_set_default_event_handler(opj_event_mgr_t * p_manager);
+
+/*@}*/
+
+/*@}*/
+
+#endif /* __EVENT_H */
diff --git a/Source/LibOpenJPEG/fix.h b/Source/LibOpenJPEG/fix.h
deleted file mode 100644
index 01716d4..0000000
--- a/Source/LibOpenJPEG/fix.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
- * Copyright (c) 2001-2003, David Janssens
- * Copyright (c) 2002-2003, Yannick Verschueren
- * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef __FIX_H
-#define __FIX_H
-
-#if defined(_MSC_VER) || defined(__BORLANDC__)
-#define int64 __int64
-#else
-#define int64 long long
-#endif
-
-/**
- at file fix.h
- at brief Implementation of operations of specific multiplication (FIX)
-
-The functions in FIX.H have for goal to realize specific multiplication.
-*/
-
-/** @defgroup FIX FIX - Implementation of operations of specific multiplication */
-/*@{*/
-
-/**
-Multiply two fixed-precision rational numbers.
- at param a
- at param b
- at return Returns a * b
-*/
-static INLINE int fix_mul(int a, int b) {
-    int64 temp = (int64) a * (int64) b ;
-    temp += temp & 4096;
-    return (int) (temp >> 13) ;
-}
-
-/*@}*/
-
-#endif /* __FIX_H */
diff --git a/Source/LibOpenJPEG/function_list.c b/Source/LibOpenJPEG/function_list.c
new file mode 100644
index 0000000..bf8c0bb
--- /dev/null
+++ b/Source/LibOpenJPEG/function_list.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2008, Jerome Fimes, Communications & Systemes <jerome.fimes at c-s.fr>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "opj_includes.h"
+
+/**
+ * Default size of the validation list, if not sufficient, data will be reallocated with a double size.
+ */
+#define OPJ_VALIDATION_SIZE 10
+
+opj_procedure_list_t *  opj_procedure_list_create()
+{
+        /* memory allocation */
+        opj_procedure_list_t * l_validation = (opj_procedure_list_t *) opj_malloc(sizeof(opj_procedure_list_t));
+        if (! l_validation)
+        {
+                return 00;
+        }
+        /* initialization */
+        memset(l_validation,0,sizeof(opj_procedure_list_t));
+        l_validation->m_nb_max_procedures = OPJ_VALIDATION_SIZE;
+        l_validation->m_procedures = (opj_procedure*)opj_malloc(
+                OPJ_VALIDATION_SIZE * sizeof(opj_procedure));
+        if (! l_validation->m_procedures)
+        {
+                opj_free(l_validation);
+                return 00;
+        }
+        memset(l_validation->m_procedures,0,OPJ_VALIDATION_SIZE * sizeof(opj_procedure));
+        return l_validation;
+}
+
+void  opj_procedure_list_destroy(opj_procedure_list_t * p_list)
+{
+        if (! p_list)
+        {
+                return;
+        }
+        /* initialization */
+        if (p_list->m_procedures)
+        {
+                opj_free(p_list->m_procedures);
+        }
+        opj_free(p_list);
+}
+
+OPJ_BOOL opj_procedure_list_add_procedure (opj_procedure_list_t * p_validation_list, opj_procedure p_procedure)
+{
+        if (p_validation_list->m_nb_max_procedures == p_validation_list->m_nb_procedures)
+        {
+                opj_procedure * new_procedures;
+
+                p_validation_list->m_nb_max_procedures += OPJ_VALIDATION_SIZE;
+                new_procedures = (opj_procedure*)opj_realloc(
+                        p_validation_list->m_procedures,
+                        p_validation_list->m_nb_max_procedures * sizeof(opj_procedure));
+                if (! new_procedures)
+                {
+                        opj_free(p_validation_list->m_procedures);
+                        p_validation_list->m_nb_max_procedures = 0;
+                        p_validation_list->m_nb_procedures = 0;
+                        /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to add a new validation procedure\n"); */
+                        fprintf(stderr, "Not enough memory to add a new validation procedure\n");
+                        
+                        return OPJ_FALSE;
+                }
+                else
+                {
+                        p_validation_list->m_procedures = new_procedures;
+                }
+        }
+        p_validation_list->m_procedures[p_validation_list->m_nb_procedures] = p_procedure;
+        ++p_validation_list->m_nb_procedures;
+
+        return OPJ_TRUE;
+}
+
+OPJ_UINT32 opj_procedure_list_get_nb_procedures (opj_procedure_list_t * p_validation_list)
+{
+        return p_validation_list->m_nb_procedures;
+}
+
+opj_procedure* opj_procedure_list_get_first_procedure (opj_procedure_list_t * p_validation_list)
+{
+        return p_validation_list->m_procedures;
+}
+
+void opj_procedure_list_clear (opj_procedure_list_t * p_validation_list)
+{
+        p_validation_list->m_nb_procedures = 0;
+}
diff --git a/Source/LibOpenJPEG/function_list.h b/Source/LibOpenJPEG/function_list.h
new file mode 100644
index 0000000..ffb75a0
--- /dev/null
+++ b/Source/LibOpenJPEG/function_list.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2008, Jerome Fimes, Communications & Systemes <jerome.fimes at c-s.fr>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __FUNCTION_LIST_H
+#define __FUNCTION_LIST_H
+
+/** 
+ * @file function_list.h
+ * @brief Implementation of a list of procedures.
+
+ * The functions in validation.c aims to have access to a list of procedures.
+*/
+
+/** @defgroup VAL VAL - validation procedure*/
+/*@{*/
+
+/**************************************************************************************************
+ ***************************************** FORWARD DECLARATION ************************************
+ **************************************************************************************************/
+
+/**
+ * declare a function pointer
+ */
+typedef void (*opj_procedure)(void);
+
+/**
+ * A list of procedures.
+*/
+typedef struct opj_procedure_list 
+{
+	/**
+	 * The number of validation procedures.
+	 */
+	OPJ_UINT32 m_nb_procedures;
+	/**
+	 * The number of the array of validation procedures.
+	 */
+	OPJ_UINT32 m_nb_max_procedures;
+	/**
+	 * The array of procedures.
+	 */
+	opj_procedure * m_procedures;
+
+} opj_procedure_list_t;
+
+/* ----------------------------------------------------------------------- */
+
+/**
+ * Creates a validation list.
+ *
+ * @return	the newly created validation list.
+ */
+opj_procedure_list_t *  opj_procedure_list_create(void);
+
+/**
+ * Destroys a validation list.
+ *
+ * @param p_list the list to destroy.
+ */
+void  opj_procedure_list_destroy(opj_procedure_list_t * p_list);
+
+/**
+ * Adds a new validation procedure.
+ *
+ * @param	p_validation_list the list of procedure to modify.
+ * @param	p_procedure		the procedure to add.
+ *
+ * @return	OPJ_TRUE if the procedure could be added.
+ */
+OPJ_BOOL opj_procedure_list_add_procedure (opj_procedure_list_t * p_validation_list, opj_procedure p_procedure);
+
+/**
+ * Gets the number of validation procedures.
+ *
+ * @param	p_validation_list the list of procedure to modify.
+ *
+ * @return the number of validation procedures.
+ */
+OPJ_UINT32 opj_procedure_list_get_nb_procedures (opj_procedure_list_t * p_validation_list);
+
+/**
+ * Gets the pointer on the first validation procedure. This function is similar to the C++
+ * iterator class to iterate through all the procedures inside the validation list.
+ * the caller does not take ownership of the pointer.
+ *
+ * @param	p_validation_list the list of procedure to get the first procedure from.
+ *
+ * @return	a pointer to the first procedure.
+ */
+opj_procedure* opj_procedure_list_get_first_procedure (opj_procedure_list_t * p_validation_list);
+
+
+/**
+ * Clears the list of validation procedures.
+ *
+ * @param	p_validation_list the list of procedure to clear.
+ *
+ */
+void opj_procedure_list_clear (opj_procedure_list_t * p_validation_list);
+/*@}*/
+
+#endif /* __FUNCTION_LIST_H */
+
diff --git a/Source/LibOpenJPEG/image.c b/Source/LibOpenJPEG/image.c
index b3260a3..24f868d 100644
--- a/Source/LibOpenJPEG/image.c
+++ b/Source/LibOpenJPEG/image.c
@@ -1,89 +1,235 @@
-/*
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "opj_includes.h"
-
-opj_image_t* opj_image_create0(void) {
-	opj_image_t *image = (opj_image_t*)opj_calloc(1, sizeof(opj_image_t));
-	return image;
-}
-
-opj_image_t* OPJ_CALLCONV opj_image_create(int numcmpts, opj_image_cmptparm_t *cmptparms, OPJ_COLOR_SPACE clrspc) {
-	int compno;
-	opj_image_t *image = NULL;
-
-	image = (opj_image_t*) opj_calloc(1, sizeof(opj_image_t));
-	if(image) {
-		image->color_space = clrspc;
-		image->numcomps = numcmpts;
-		/* allocate memory for the per-component information */
-		image->comps = (opj_image_comp_t*)opj_malloc(image->numcomps * sizeof(opj_image_comp_t));
-		if(!image->comps) {
-			fprintf(stderr,"Unable to allocate memory for image.\n");
-			opj_image_destroy(image);
-			return NULL;
-		}
-		/* create the individual image components */
-		for(compno = 0; compno < numcmpts; compno++) {
-			opj_image_comp_t *comp = &image->comps[compno];
-			comp->dx = cmptparms[compno].dx;
-			comp->dy = cmptparms[compno].dy;
-			comp->w = cmptparms[compno].w;
-			comp->h = cmptparms[compno].h;
-			comp->x0 = cmptparms[compno].x0;
-			comp->y0 = cmptparms[compno].y0;
-			comp->prec = cmptparms[compno].prec;
-			comp->bpp = cmptparms[compno].bpp;
-			comp->sgnd = cmptparms[compno].sgnd;
-			comp->data = (int*) opj_calloc(comp->w * comp->h, sizeof(int));
-			if(!comp->data) {
-				fprintf(stderr,"Unable to allocate memory for image.\n");
-				opj_image_destroy(image);
-				return NULL;
-			}
-		}
-	}
-
-	return image;
-}
-
-void OPJ_CALLCONV opj_image_destroy(opj_image_t *image) {
-	int i;
-	if(image) {
-		if(image->comps) {
-			/* image components */
-			for(i = 0; i < image->numcomps; i++) {
-				opj_image_comp_t *image_comp = &image->comps[i];
-				if(image_comp->data) {
-					opj_free(image_comp->data);
-				}
-			}
-			opj_free(image->comps);
-		}
-		opj_free(image);
-	}
-}
-
+/*
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "opj_includes.h"
+
+opj_image_t* opj_image_create0(void) {
+	opj_image_t *image = (opj_image_t*)opj_calloc(1, sizeof(opj_image_t));
+	return image;
+}
+
+opj_image_t* OPJ_CALLCONV opj_image_create(OPJ_UINT32 numcmpts, opj_image_cmptparm_t *cmptparms, OPJ_COLOR_SPACE clrspc) {
+	OPJ_UINT32 compno;
+	opj_image_t *image = NULL;
+
+	image = (opj_image_t*) opj_calloc(1, sizeof(opj_image_t));
+	if(image) {
+		image->color_space = clrspc;
+		image->numcomps = numcmpts;
+		/* allocate memory for the per-component information */
+		image->comps = (opj_image_comp_t*)opj_calloc(1,image->numcomps * sizeof(opj_image_comp_t));
+		if(!image->comps) {
+			fprintf(stderr,"Unable to allocate memory for image.\n");
+			opj_image_destroy(image);
+			return NULL;
+		}
+		/* create the individual image components */
+		for(compno = 0; compno < numcmpts; compno++) {
+			opj_image_comp_t *comp = &image->comps[compno];
+			comp->dx = cmptparms[compno].dx;
+			comp->dy = cmptparms[compno].dy;
+			comp->w = cmptparms[compno].w;
+			comp->h = cmptparms[compno].h;
+			comp->x0 = cmptparms[compno].x0;
+			comp->y0 = cmptparms[compno].y0;
+			comp->prec = cmptparms[compno].prec;
+			comp->bpp = cmptparms[compno].bpp;
+			comp->sgnd = cmptparms[compno].sgnd;
+			comp->data = (OPJ_INT32*) opj_calloc(comp->w * comp->h, sizeof(OPJ_INT32));
+			if(!comp->data) {
+				fprintf(stderr,"Unable to allocate memory for image.\n");
+				opj_image_destroy(image);
+				return NULL;
+			}
+		}
+	}
+
+	return image;
+}
+
+void OPJ_CALLCONV opj_image_destroy(opj_image_t *image) {
+	if(image) {
+		if(image->comps) {
+			OPJ_UINT32 compno;
+
+			/* image components */
+			for(compno = 0; compno < image->numcomps; compno++) {
+				opj_image_comp_t *image_comp = &(image->comps[compno]);
+				if(image_comp->data) {
+					opj_free(image_comp->data);
+				}
+			}
+			opj_free(image->comps);
+		}
+
+		if(image->icc_profile_buf) {
+			opj_free(image->icc_profile_buf);
+		}
+
+		opj_free(image);
+	}
+}
+
+/**
+ * Updates the components characteristics of the image from the coding parameters.
+ *
+ * @param p_image_header	the image header to update.
+ * @param p_cp				the coding parameters from which to update the image.
+ */
+void opj_image_comp_header_update(opj_image_t * p_image_header, const struct opj_cp * p_cp)
+{
+	OPJ_UINT32 i, l_width, l_height;
+	OPJ_INT32 l_x0, l_y0, l_x1, l_y1;
+	OPJ_INT32 l_comp_x0, l_comp_y0, l_comp_x1, l_comp_y1;
+	opj_image_comp_t* l_img_comp = NULL;
+
+	l_x0 = opj_int_max((OPJ_INT32)p_cp->tx0 , (OPJ_INT32)p_image_header->x0);
+	l_y0 = opj_int_max((OPJ_INT32)p_cp->ty0 , (OPJ_INT32)p_image_header->y0);
+	l_x1 = opj_int_min((OPJ_INT32)(p_cp->tx0 + p_cp->tw * p_cp->tdx), (OPJ_INT32)p_image_header->x1);
+	l_y1 = opj_int_min((OPJ_INT32)(p_cp->ty0 + p_cp->th * p_cp->tdy), (OPJ_INT32)p_image_header->y1);
+
+	l_img_comp = p_image_header->comps;
+	for	(i = 0; i < p_image_header->numcomps; ++i) {
+		l_comp_x0 = opj_int_ceildiv(l_x0, (OPJ_INT32)l_img_comp->dx);
+		l_comp_y0 = opj_int_ceildiv(l_y0, (OPJ_INT32)l_img_comp->dy);
+		l_comp_x1 = opj_int_ceildiv(l_x1, (OPJ_INT32)l_img_comp->dx);
+		l_comp_y1 = opj_int_ceildiv(l_y1, (OPJ_INT32)l_img_comp->dy);
+		l_width = (OPJ_UINT32)opj_int_ceildivpow2(l_comp_x1 - l_comp_x0, (OPJ_INT32)l_img_comp->factor);
+		l_height = (OPJ_UINT32)opj_int_ceildivpow2(l_comp_y1 - l_comp_y0, (OPJ_INT32)l_img_comp->factor);
+		l_img_comp->w = l_width;
+		l_img_comp->h = l_height;
+		l_img_comp->x0 = (OPJ_UINT32)l_comp_x0/*l_x0*/;
+		l_img_comp->y0 = (OPJ_UINT32)l_comp_y0/*l_y0*/;
+		++l_img_comp;
+	}
+}
+
+
+/**
+ * Copy only header of image and its component header (no data are copied)
+ * if dest image have data, they will be freed
+ *
+ * @param	p_image_src		the src image
+ * @param	p_image_dest	the dest image
+ *
+ */
+void opj_copy_image_header(const opj_image_t* p_image_src, opj_image_t* p_image_dest)
+{
+	OPJ_UINT32 compno;
+
+	/* preconditions */
+	assert(p_image_src != 00);
+	assert(p_image_dest != 00);
+
+	p_image_dest->x0 = p_image_src->x0;
+	p_image_dest->y0 = p_image_src->y0;
+	p_image_dest->x1 = p_image_src->x1;
+	p_image_dest->y1 = p_image_src->y1;
+
+	if (p_image_dest->comps){
+		for(compno = 0; compno < p_image_dest->numcomps; compno++) {
+			opj_image_comp_t *image_comp = &(p_image_dest->comps[compno]);
+			if(image_comp->data) {
+				opj_free(image_comp->data);
+			}
+		}
+		opj_free(p_image_dest->comps);
+		p_image_dest->comps = NULL;
+	}
+
+	p_image_dest->numcomps = p_image_src->numcomps;
+
+	p_image_dest->comps = (opj_image_comp_t*) opj_malloc(p_image_dest->numcomps * sizeof(opj_image_comp_t));
+	if (!p_image_dest->comps){
+		p_image_dest->comps = NULL;
+		p_image_dest->numcomps = 0;
+		return;
+	}
+
+	for (compno=0; compno < p_image_dest->numcomps; compno++){
+		memcpy( &(p_image_dest->comps[compno]),
+				&(p_image_src->comps[compno]),
+				sizeof(opj_image_comp_t));
+		p_image_dest->comps[compno].data = NULL;
+	}
+
+	p_image_dest->color_space = p_image_src->color_space;
+	p_image_dest->icc_profile_len = p_image_src->icc_profile_len;
+
+	if (p_image_dest->icc_profile_len) {
+		p_image_dest->icc_profile_buf = (OPJ_BYTE*)opj_malloc(p_image_dest->icc_profile_len);
+		if (!p_image_dest->icc_profile_buf){
+			p_image_dest->icc_profile_buf = NULL;
+			p_image_dest->icc_profile_len = 0;
+			return;
+		}
+		memcpy( p_image_dest->icc_profile_buf,
+				p_image_src->icc_profile_buf,
+				p_image_src->icc_profile_len);
+		}
+		else
+			p_image_dest->icc_profile_buf = NULL;
+
+	return;
+}
+
+opj_image_t* OPJ_CALLCONV opj_image_tile_create(OPJ_UINT32 numcmpts, opj_image_cmptparm_t *cmptparms, OPJ_COLOR_SPACE clrspc) {
+	OPJ_UINT32 compno;
+	opj_image_t *image = 00;
+
+	image = (opj_image_t*) opj_malloc(sizeof(opj_image_t));
+	if (image)
+	{
+		memset(image,0,sizeof(opj_image_t));
+		
+		image->color_space = clrspc;
+		image->numcomps = numcmpts;
+		
+		/* allocate memory for the per-component information */
+		image->comps = (opj_image_comp_t*)opj_malloc(image->numcomps * sizeof(opj_image_comp_t));
+		if (!image->comps) {
+			opj_image_destroy(image);
+			return 00;
+		}
+		memset(image->comps,0,image->numcomps * sizeof(opj_image_comp_t));
+		
+		/* create the individual image components */
+		for(compno = 0; compno < numcmpts; compno++) {
+			opj_image_comp_t *comp = &image->comps[compno];
+			comp->dx = cmptparms[compno].dx;
+			comp->dy = cmptparms[compno].dy;
+			comp->w = cmptparms[compno].w;
+			comp->h = cmptparms[compno].h;
+			comp->x0 = cmptparms[compno].x0;
+			comp->y0 = cmptparms[compno].y0;
+			comp->prec = cmptparms[compno].prec;
+			comp->sgnd = cmptparms[compno].sgnd;
+			comp->data = 0;
+		}
+	}
+
+	return image;
+}
diff --git a/Source/LibOpenJPEG/image.h b/Source/LibOpenJPEG/image.h
index fc02f49..323dc34 100644
--- a/Source/LibOpenJPEG/image.h
+++ b/Source/LibOpenJPEG/image.h
@@ -1,48 +1,63 @@
-/*
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef __IMAGE_H
-#define __IMAGE_H
-/**
- at file image.h
- at brief Implementation of operations on images (IMAGE)
-
-The functions in IMAGE.C have for goal to realize operations on images.
-*/
-
-/** @defgroup IMAGE IMAGE - Implementation of operations on images */
-/*@{*/
-
-/**
-Create an empty image
- at todo this function should be removed
- at return returns an empty image if successful, returns NULL otherwise
-*/
-opj_image_t* opj_image_create0(void);
-
-/*@}*/
-
-#endif /* __IMAGE_H */
-
+/*
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef __IMAGE_H
+#define __IMAGE_H
+/**
+ at file image.h
+ at brief Implementation of operations on images (IMAGE)
+
+The functions in IMAGE.C have for goal to realize operations on images.
+*/
+
+struct opj_image;
+struct opj_cp;
+
+/** @defgroup IMAGE IMAGE - Implementation of operations on images */
+/*@{*/
+
+/**
+ * Create an empty image
+ *
+ * @return returns an empty image if successful, returns NULL otherwise
+ */
+opj_image_t* opj_image_create0(void);
+
+
+
+/**
+ * Updates the components characteristics of the image from the coding parameters.
+ *
+ * @param p_image_header		the image header to update.
+ * @param p_cp					the coding parameters from which to update the image.
+ */
+void opj_image_comp_header_update(opj_image_t * p_image, const struct opj_cp* p_cp);
+
+void opj_copy_image_header(const opj_image_t* p_image_src, opj_image_t* p_image_dest);
+
+/*@}*/
+
+#endif /* __IMAGE_H */
+
diff --git a/Source/LibOpenJPEG/indexbox_manager.h b/Source/LibOpenJPEG/indexbox_manager.h
index 33e0772..d810c27 100644
--- a/Source/LibOpenJPEG/indexbox_manager.h
+++ b/Source/LibOpenJPEG/indexbox_manager.h
@@ -1,118 +1,148 @@
-/*
- * $Id: indexbox_manager.h,v 1.2 2012/09/23 12:44:41 drolon Exp $
- *
- * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2011, Professor Benoit Macq
- * Copyright (c) 2003-2004, Yannick Verschueren
- * Copyright (c) 2010-2011, Kaori Hagihara
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*! \file
- *  \brief Modification of jpip.c from 2KAN indexer
- */
-
-#ifndef  INDEXBOX_MANAGER_H_
-# define INDEXBOX_MANAGER_H_
-
-#include "openjpeg.h"
-#include "j2k.h" /* needed to use jp2.h */
-#include "jp2.h"
-
-#define JPIP_CIDX 0x63696478   /* Codestream index                */
-#define JPIP_CPTR 0x63707472   /* Codestream Finder Box           */
-#define JPIP_MANF 0x6d616e66   /* Manifest Box                    */
-#define JPIP_FAIX 0x66616978   /* Fragment array Index box        */
-#define JPIP_MHIX 0x6d686978   /* Main Header Index Table         */
-#define JPIP_TPIX 0x74706978   /* Tile-part Index Table box       */
-#define JPIP_THIX 0x74686978   /* Tile header Index Table box     */
-#define JPIP_PPIX 0x70706978   /* Precinct Packet Index Table box */
-#define JPIP_PHIX 0x70686978   /* Packet Header index Table       */
-#define JPIP_FIDX 0x66696478   /* File Index                      */
-#define JPIP_FPTR 0x66707472   /* File Finder                     */
-#define JPIP_PRXY 0x70727879   /* Proxy boxes                     */
-#define JPIP_IPTR 0x69707472   /* Index finder box                */
-#define JPIP_PHLD 0x70686c64   /* Place holder                    */
-
-
-/* 
- * Write tile-part Index table box (superbox)
- *
- * @param[in] coff      offset of j2k codestream
- * @param[in] cstr_info codestream information
- * @param[in] j2klen    length of j2k codestream
- * @param[in] cio       file output handle
- * @return              length of tpix box
- */
-int write_tpix( int coff, opj_codestream_info_t cstr_info, int j2klen, opj_cio_t *cio);
-
-
-/* 
- * Write tile header index table box (superbox)
- *
- * @param[in] coff      offset of j2k codestream
- * @param[in] cstr_info codestream information pointer
- * @param[in] cio       file output handle
- * @return              length of thix box
- */
-int write_thix( int coff, opj_codestream_info_t cstr_info, opj_cio_t *cio);
-
-
-/* 
- * Write precinct packet index table box (superbox)
- *
- * @param[in] coff      offset of j2k codestream
- * @param[in] cstr_info codestream information
- * @param[in] EPHused   true if EPH option used
- * @param[in] j2klen    length of j2k codestream
- * @param[in] cio       file output handle
- * @return              length of ppix box
- */
-int write_ppix( int coff, opj_codestream_info_t cstr_info, opj_bool EPHused, int j2klen, opj_cio_t *cio);
-
-
-/* 
- * Write packet header index table box (superbox)
- *
- * @param[in] coff      offset of j2k codestream
- * @param[in] cstr_info codestream information
- * @param[in] EPHused   true if EPH option used
- * @param[in] j2klen    length of j2k codestream
- * @param[in] cio       file output handle
- * @return              length of ppix box
- */
-int write_phix( int coff, opj_codestream_info_t cstr_info, opj_bool EPHused, int j2klen, opj_cio_t *cio);
-
-/* 
- * Wriet manifest box (box)
- *
- * @param[in] second number to be visited
- * @param[in] v      number of boxes
- * @param[in] box    box to be manifested
- * @param[in] cio    file output handle
- */
-void write_manf(int second, int v, opj_jp2_box_t *box, opj_cio_t *cio);
-
-
-#endif      /* !INDEXBOX_MANAGER_H_ */
+/*
+ * $Id: indexbox_manager.h,v 1.4 2014/03/16 12:29:52 drolon Exp $
+ *
+ * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2011, Professor Benoit Macq
+ * Copyright (c) 2003-2004, Yannick Verschueren
+ * Copyright (c) 2010-2011, Kaori Hagihara
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*! \file
+ *  \brief Modification of jpip.c from 2KAN indexer
+ */
+
+#ifndef  INDEXBOX_MANAGER_H_
+# define INDEXBOX_MANAGER_H_
+
+#include "openjpeg.h"
+#include "j2k.h" /* needed to use jp2.h */
+#include "jp2.h"
+
+#define JPIP_CIDX 0x63696478   /* Codestream index                */
+#define JPIP_CPTR 0x63707472   /* Codestream Finder Box           */
+#define JPIP_MANF 0x6d616e66   /* Manifest Box                    */
+#define JPIP_FAIX 0x66616978   /* Fragment array Index box        */
+#define JPIP_MHIX 0x6d686978   /* Main Header Index Table         */
+#define JPIP_TPIX 0x74706978   /* Tile-part Index Table box       */
+#define JPIP_THIX 0x74686978   /* Tile header Index Table box     */
+#define JPIP_PPIX 0x70706978   /* Precinct Packet Index Table box */
+#define JPIP_PHIX 0x70686978   /* Packet Header index Table       */
+#define JPIP_FIDX 0x66696478   /* File Index                      */
+#define JPIP_FPTR 0x66707472   /* File Finder                     */
+#define JPIP_PRXY 0x70727879   /* Proxy boxes                     */
+#define JPIP_IPTR 0x69707472   /* Index finder box                */
+#define JPIP_PHLD 0x70686c64   /* Place holder                    */
+
+
+/* 
+ * Write tile-part Index table box (superbox)
+ *
+ * @param[in] coff      offset of j2k codestream
+ * @param[in] cstr_info codestream information
+ * @param[in] j2klen    length of j2k codestream
+ * @param[in] cio       file output handle
+ * @return              length of tpix box
+ */
+int opj_write_tpix( int coff, opj_codestream_info_t cstr_info, int j2klen, opj_stream_private_t *cio,
+              opj_event_mgr_t * p_manager );
+
+
+/* 
+ * Write tile header index table box (superbox)
+ *
+ * @param[in] coff      offset of j2k codestream
+ * @param[in] cstr_info codestream information pointer
+ * @param[in] cio       file output handle
+ * @return              length of thix box
+ */
+int opj_write_thix( int coff, opj_codestream_info_t cstr_info, opj_stream_private_t *cio, opj_event_mgr_t * p_manager );
+
+
+/* 
+ * Write precinct packet index table box (superbox)
+ *
+ * @param[in] coff      offset of j2k codestream
+ * @param[in] cstr_info codestream information
+ * @param[in] EPHused   true if EPH option used
+ * @param[in] j2klen    length of j2k codestream
+ * @param[in] cio       file output handle
+ * @return              length of ppix box
+ */
+int opj_write_ppix( int coff, opj_codestream_info_t cstr_info, OPJ_BOOL EPHused, int j2klen, opj_stream_private_t *cio,
+              opj_event_mgr_t * p_manager );
+
+
+/* 
+ * Write packet header index table box (superbox)
+ *
+ * @param[in] coff      offset of j2k codestream
+ * @param[in] cstr_info codestream information
+ * @param[in] EPHused   true if EPH option used
+ * @param[in] j2klen    length of j2k codestream
+ * @param[in] cio       file output handle
+ * @return              length of ppix box
+ */
+int opj_write_phix( int coff, opj_codestream_info_t cstr_info, OPJ_BOOL EPHused, int j2klen, opj_stream_private_t *cio,
+              opj_event_mgr_t * p_manager );
+
+/* 
+ * Wriet manifest box (box)
+ *
+ * @param[in] second number to be visited
+ * @param[in] v      number of boxes
+ * @param[in] box    box to be manifested
+ * @param[in] cio    file output handle
+ */
+
+void opj_write_manf(int second, 
+                    int v, 
+                    opj_jp2_box_t *box, 
+                    opj_stream_private_t *cio,
+                    opj_event_mgr_t * p_manager );
+
+/* 
+ * Write main header index table (box)
+ *
+ * @param[in] coff offset of j2k codestream
+ * @param[in] cstr_info codestream information
+ * @param[in] cio  file output handle
+ * @return         length of mainmhix box
+ */
+int opj_write_mainmhix( int coff, opj_codestream_info_t cstr_info, opj_stream_private_t *cio,
+              opj_event_mgr_t * p_manager );
+
+int opj_write_phixfaix( int coff, int compno, opj_codestream_info_t cstr_info, OPJ_BOOL EPHused, int j2klen, opj_stream_private_t *cio,
+              opj_event_mgr_t * p_manager );
+
+int opj_write_ppixfaix( int coff, int compno, opj_codestream_info_t cstr_info, OPJ_BOOL EPHused, int j2klen, opj_stream_private_t *cio,
+              opj_event_mgr_t * p_manager );
+
+int opj_write_tilemhix( int coff, opj_codestream_info_t cstr_info, int tileno, opj_stream_private_t *cio,
+              opj_event_mgr_t * p_manager );
+
+int opj_write_tpixfaix( int coff, int compno, opj_codestream_info_t cstr_info, int j2klen, opj_stream_private_t *cio,
+              opj_event_mgr_t * p_manager );
+
+#endif      /* !INDEXBOX_MANAGER_H_ */
diff --git a/Source/LibOpenJPEG/int.h b/Source/LibOpenJPEG/int.h
deleted file mode 100644
index b650075..0000000
--- a/Source/LibOpenJPEG/int.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
- * Copyright (c) 2001-2003, David Janssens
- * Copyright (c) 2002-2003, Yannick Verschueren
- * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef __INT_H
-#define __INT_H
-/**
- at file int.h
- at brief Implementation of operations on integers (INT)
-
-The functions in INT.H have for goal to realize operations on integers.
-*/
-
-/** @defgroup INT INT - Implementation of operations on integers */
-/*@{*/
-
-/** @name Exported functions (see also openjpeg.h) */
-/*@{*/
-/* ----------------------------------------------------------------------- */
-/**
-Get the minimum of two integers
- at return Returns a if a < b else b
-*/
-static INLINE int int_min(int a, int b) {
-	return a < b ? a : b;
-}
-/**
-Get the maximum of two integers
- at return Returns a if a > b else b
-*/
-static INLINE int int_max(int a, int b) {
-	return (a > b) ? a : b;
-}
-/**
-Clamp an integer inside an interval
- at return
-<ul>
-<li>Returns a if (min < a < max)
-<li>Returns max if (a > max)
-<li>Returns min if (a < min) 
-</ul>
-*/
-static INLINE int int_clamp(int a, int min, int max) {
-	if (a < min)
-		return min;
-	if (a > max)
-		return max;
-	return a;
-}
-/**
- at return Get absolute value of integer
-*/
-static INLINE int int_abs(int a) {
-	return a < 0 ? -a : a;
-}
-/**
-Divide an integer and round upwards
- at return Returns a divided by b
-*/
-static INLINE int int_ceildiv(int a, int b) {
-	return (a + b - 1) / b;
-}
-/**
-Divide an integer by a power of 2 and round upwards
- at return Returns a divided by 2^b
-*/
-static INLINE int int_ceildivpow2(int a, int b) {
-	return (a + (1 << b) - 1) >> b;
-}
-/**
-Divide an integer by a power of 2 and round downwards
- at return Returns a divided by 2^b
-*/
-static INLINE int int_floordivpow2(int a, int b) {
-	return a >> b;
-}
-/**
-Get logarithm of an integer and round downwards
- at return Returns log2(a)
-*/
-static INLINE int int_floorlog2(int a) {
-	int l;
-	for (l = 0; a > 1; l++) {
-		a >>= 1;
-	}
-	return l;
-}
-/* ----------------------------------------------------------------------- */
-/*@}*/
-
-/*@}*/
-
-#endif
diff --git a/Source/LibOpenJPEG/invert.c b/Source/LibOpenJPEG/invert.c
new file mode 100644
index 0000000..bb6672d
--- /dev/null
+++ b/Source/LibOpenJPEG/invert.c
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2008, Jerome Fimes, Communications & Systemes <jerome.fimes at c-s.fr>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "opj_includes.h"
+
+/** 
+ * LUP decomposition
+ */
+static OPJ_BOOL opj_lupDecompose(OPJ_FLOAT32 * matrix,
+                                 OPJ_UINT32 * permutations, 
+                                 OPJ_FLOAT32 * p_swap_area,
+                                 OPJ_UINT32 nb_compo);
+/** 
+ * LUP solving
+ */
+static void opj_lupSolve(OPJ_FLOAT32 * pResult, 
+                         OPJ_FLOAT32* pMatrix, 
+                         OPJ_FLOAT32* pVector, 
+                         OPJ_UINT32* pPermutations, 
+                         OPJ_UINT32 nb_compo,
+                         OPJ_FLOAT32 * p_intermediate_data);
+
+/** 
+ *LUP inversion (call with the result of lupDecompose)
+ */
+static void opj_lupInvert ( OPJ_FLOAT32 * pSrcMatrix,
+                            OPJ_FLOAT32 * pDestMatrix,
+                            OPJ_UINT32 nb_compo,
+                            OPJ_UINT32 * pPermutations,
+                            OPJ_FLOAT32 * p_src_temp,
+                            OPJ_FLOAT32 * p_dest_temp,
+                            OPJ_FLOAT32 * p_swap_area);
+
+/*
+==========================================================
+   Matric inversion interface
+==========================================================
+*/
+/**
+ * Matrix inversion.
+ */
+OPJ_BOOL opj_matrix_inversion_f(OPJ_FLOAT32 * pSrcMatrix,
+                                OPJ_FLOAT32 * pDestMatrix, 
+                                OPJ_UINT32 nb_compo)
+{
+	OPJ_BYTE * l_data = 00;
+	OPJ_UINT32 l_permutation_size = nb_compo * (OPJ_UINT32)sizeof(OPJ_UINT32);
+	OPJ_UINT32 l_swap_size = nb_compo * (OPJ_UINT32)sizeof(OPJ_FLOAT32);
+	OPJ_UINT32 l_total_size = l_permutation_size + 3 * l_swap_size;
+	OPJ_UINT32 * lPermutations = 00;
+	OPJ_FLOAT32 * l_double_data = 00;
+
+	l_data = (OPJ_BYTE *) opj_malloc(l_total_size);
+	if (l_data == 0) {
+		return OPJ_FALSE;
+	}
+	lPermutations = (OPJ_UINT32 *) l_data;
+	l_double_data = (OPJ_FLOAT32 *) (l_data + l_permutation_size);
+	memset(lPermutations,0,l_permutation_size);
+
+	if(! opj_lupDecompose(pSrcMatrix,lPermutations,l_double_data,nb_compo)) {
+		opj_free(l_data);
+		return OPJ_FALSE;
+	}
+	
+    opj_lupInvert(pSrcMatrix,pDestMatrix,nb_compo,lPermutations,l_double_data,l_double_data + nb_compo,l_double_data + 2*nb_compo);
+	opj_free(l_data);
+	
+    return OPJ_TRUE;
+}
+
+
+/*
+==========================================================
+   Local functions
+==========================================================
+*/
+OPJ_BOOL opj_lupDecompose(OPJ_FLOAT32 * matrix,OPJ_UINT32 * permutations, 
+                          OPJ_FLOAT32 * p_swap_area,
+                          OPJ_UINT32 nb_compo) 
+{
+	OPJ_UINT32 * tmpPermutations = permutations;
+	OPJ_UINT32 * dstPermutations;
+	OPJ_UINT32 k2=0,t;
+	OPJ_FLOAT32 temp;
+	OPJ_UINT32 i,j,k;
+	OPJ_FLOAT32 p;
+	OPJ_UINT32 lLastColum = nb_compo - 1;
+	OPJ_UINT32 lSwapSize = nb_compo * (OPJ_UINT32)sizeof(OPJ_FLOAT32);
+	OPJ_FLOAT32 * lTmpMatrix = matrix;
+	OPJ_FLOAT32 * lColumnMatrix,* lDestMatrix;
+	OPJ_UINT32 offset = 1;
+	OPJ_UINT32 lStride = nb_compo-1;
+
+	/*initialize permutations */
+	for (i = 0; i < nb_compo; ++i) 
+	{
+    	*tmpPermutations++ = i;
+	}
+	/* now make a pivot with colum switch */
+	tmpPermutations = permutations;
+	for (k = 0; k < lLastColum; ++k) {
+		p = 0.0;
+
+		/* take the middle element */
+		lColumnMatrix = lTmpMatrix + k;
+		
+		/* make permutation with the biggest value in the column */
+        for (i = k; i < nb_compo; ++i) {
+			temp = ((*lColumnMatrix > 0) ? *lColumnMatrix : -(*lColumnMatrix));
+     		if (temp > p) {
+     			p = temp;
+     			k2 = i;
+     		}
+			/* next line */
+			lColumnMatrix += nb_compo;
+     	}
+
+     	/* a whole rest of 0 -> non singular */
+     	if (p == 0.0) {
+    		return OPJ_FALSE;
+		}
+
+		/* should we permute ? */
+		if (k2 != k) {
+			/*exchange of line */
+     		/* k2 > k */
+			dstPermutations = tmpPermutations + k2 - k;
+			/* swap indices */
+			t = *tmpPermutations;
+     		*tmpPermutations = *dstPermutations;
+     		*dstPermutations = t;
+
+			/* and swap entire line. */
+			lColumnMatrix = lTmpMatrix + (k2 - k) * nb_compo;
+			memcpy(p_swap_area,lColumnMatrix,lSwapSize);
+			memcpy(lColumnMatrix,lTmpMatrix,lSwapSize);
+			memcpy(lTmpMatrix,p_swap_area,lSwapSize);
+		}
+
+		/* now update data in the rest of the line and line after */
+		lDestMatrix = lTmpMatrix + k;
+		lColumnMatrix = lDestMatrix + nb_compo;
+		/* take the middle element */
+		temp = *(lDestMatrix++);
+
+		/* now compute up data (i.e. coeff up of the diagonal). */
+     	for (i = offset; i < nb_compo; ++i)  {
+			/*lColumnMatrix; */
+			/* divide the lower column elements by the diagonal value */
+
+			/* matrix[i][k] /= matrix[k][k]; */
+     		/* p = matrix[i][k] */
+			p = *lColumnMatrix / temp;
+			*(lColumnMatrix++) = p;
+     		
+            for (j = /* k + 1 */ offset; j < nb_compo; ++j) {
+				/* matrix[i][j] -= matrix[i][k] * matrix[k][j]; */
+     			*(lColumnMatrix++) -= p * (*(lDestMatrix++));
+			}
+			/* come back to the k+1th element */
+			lDestMatrix -= lStride;
+			/* go to kth element of the next line */
+			lColumnMatrix += k;
+     	}
+
+		/* offset is now k+2 */
+		++offset;
+		/* 1 element less for stride */
+		--lStride;
+		/* next line */
+		lTmpMatrix+=nb_compo;
+		/* next permutation element */
+		++tmpPermutations;
+	}
+    return OPJ_TRUE;
+}
+   		
+void opj_lupSolve (OPJ_FLOAT32 * pResult, 
+                   OPJ_FLOAT32 * pMatrix, 
+                   OPJ_FLOAT32 * pVector, 
+                   OPJ_UINT32* pPermutations, 
+                   OPJ_UINT32 nb_compo,OPJ_FLOAT32 * p_intermediate_data) 
+{
+	OPJ_INT32 k;
+    OPJ_UINT32 i,j;
+	OPJ_FLOAT32 sum;
+	OPJ_FLOAT32 u;
+    OPJ_UINT32 lStride = nb_compo+1;
+	OPJ_FLOAT32 * lCurrentPtr;
+	OPJ_FLOAT32 * lIntermediatePtr;
+	OPJ_FLOAT32 * lDestPtr;
+	OPJ_FLOAT32 * lTmpMatrix;
+	OPJ_FLOAT32 * lLineMatrix = pMatrix;
+	OPJ_FLOAT32 * lBeginPtr = pResult + nb_compo - 1;
+	OPJ_FLOAT32 * lGeneratedData;
+	OPJ_UINT32 * lCurrentPermutationPtr = pPermutations;
+
+	
+	lIntermediatePtr = p_intermediate_data;
+	lGeneratedData = p_intermediate_data + nb_compo - 1;
+	
+    for (i = 0; i < nb_compo; ++i) {
+       	sum = 0.0;
+		lCurrentPtr = p_intermediate_data;
+		lTmpMatrix = lLineMatrix;
+        for (j = 1; j <= i; ++j) 
+		{
+			/* sum += matrix[i][j-1] * y[j-1]; */
+        	sum += (*(lTmpMatrix++)) * (*(lCurrentPtr++));
+        }
+		/*y[i] = pVector[pPermutations[i]] - sum; */
+        *(lIntermediatePtr++) = pVector[*(lCurrentPermutationPtr++)] - sum;
+		lLineMatrix += nb_compo;
+	}
+
+	/* we take the last point of the matrix */
+	lLineMatrix = pMatrix + nb_compo*nb_compo - 1;
+
+	/* and we take after the last point of the destination vector */
+	lDestPtr = pResult + nb_compo;
+
+
+    assert(nb_compo != 0);
+	for (k = (OPJ_INT32)nb_compo - 1; k != -1 ; --k) {
+		sum = 0.0;
+		lTmpMatrix = lLineMatrix;
+        u = *(lTmpMatrix++);
+		lCurrentPtr = lDestPtr--;
+        for (j = (OPJ_UINT32)(k + 1); j < nb_compo; ++j) {
+			/* sum += matrix[k][j] * x[j] */
+        	sum += (*(lTmpMatrix++)) * (*(lCurrentPtr++));
+		}
+		/*x[k] = (y[k] - sum) / u; */
+        *(lBeginPtr--) = (*(lGeneratedData--) - sum) / u;
+		lLineMatrix -= lStride;
+	}
+}
+    
+
+void opj_lupInvert (OPJ_FLOAT32 * pSrcMatrix,
+                    OPJ_FLOAT32 * pDestMatrix,
+                    OPJ_UINT32 nb_compo,
+                    OPJ_UINT32 * pPermutations,
+                    OPJ_FLOAT32 * p_src_temp,
+                    OPJ_FLOAT32 * p_dest_temp,
+                    OPJ_FLOAT32 * p_swap_area )
+{
+	OPJ_UINT32 j,i;
+	OPJ_FLOAT32 * lCurrentPtr;
+	OPJ_FLOAT32 * lLineMatrix = pDestMatrix;
+	OPJ_UINT32 lSwapSize = nb_compo * (OPJ_UINT32)sizeof(OPJ_FLOAT32);
+
+	for (j = 0; j < nb_compo; ++j) {
+		lCurrentPtr = lLineMatrix++;
+        memset(p_src_temp,0,lSwapSize);
+    	p_src_temp[j] = 1.0;
+		opj_lupSolve(p_dest_temp,pSrcMatrix,p_src_temp, pPermutations, nb_compo , p_swap_area);
+
+		for (i = 0; i < nb_compo; ++i) {
+    		*(lCurrentPtr) = p_dest_temp[i];
+			lCurrentPtr+=nb_compo;
+    	}
+    }
+}
+
diff --git a/Source/LibOpenJPEG/invert.h b/Source/LibOpenJPEG/invert.h
new file mode 100644
index 0000000..2193fc1
--- /dev/null
+++ b/Source/LibOpenJPEG/invert.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2008, Jerome Fimes, Communications & Systemes <jerome.fimes at c-s.fr>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __INVERT_H
+#define __INVERT_H
+/**
+ at file invert.h
+ at brief Implementation of the matrix inversion
+
+The function in INVERT.H compute a matrix inversion with a LUP method
+*/
+
+/** @defgroup INVERT INVERT - Implementation of a matrix inversion */
+/*@{*/
+/** @name Exported functions */
+/*@{*/
+/* ----------------------------------------------------------------------- */
+
+/**
+ * Calculates a n x n double matrix inversion with a LUP method. Data is aligned, rows after rows (or columns after columns).
+ * The function does not take ownership of any memory block, data must be fred by the user.
+ *
+ * @param pSrcMatrix	the matrix to invert.
+ * @param pDestMatrix	data to store the inverted matrix. 
+ * @param n size of the matrix
+ * @return OPJ_TRUE if the inversion is successful, OPJ_FALSE if the matrix is singular.
+ */
+OPJ_BOOL opj_matrix_inversion_f(OPJ_FLOAT32 * pSrcMatrix,
+                                OPJ_FLOAT32 * pDestMatrix, 
+                                OPJ_UINT32 nb_compo);
+/* ----------------------------------------------------------------------- */
+/*@}*/
+
+/*@}*/
+
+#endif /* __INVERT_H */ 
diff --git a/Source/LibOpenJPEG/j2k.c b/Source/LibOpenJPEG/j2k.c
index dd87469..4434bf1 100644
--- a/Source/LibOpenJPEG/j2k.c
+++ b/Source/LibOpenJPEG/j2k.c
@@ -1,2616 +1,10238 @@
-/*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
- * Copyright (c) 2001-2003, David Janssens
- * Copyright (c) 2002-2003, Yannick Verschueren
- * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * Copyright (c) 2006-2007, Parvatha Elangovan
- * Copyright (c) 2010-2011, Kaori Hagihara
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "opj_includes.h"
-
-/** @defgroup J2K J2K - JPEG-2000 codestream reader/writer */
-/*@{*/
-
-/** @name Local static functions */
-/*@{*/
-
-/**
-Write the SOC marker (Start Of Codestream)
- at param j2k J2K handle
-*/
-static void j2k_write_soc(opj_j2k_t *j2k);
-/**
-Read the SOC marker (Start of Codestream)
- at param j2k J2K handle
-*/
-static void j2k_read_soc(opj_j2k_t *j2k);
-/**
-Write the SIZ marker (image and tile size)
- at param j2k J2K handle
-*/
-static void j2k_write_siz(opj_j2k_t *j2k);
-/**
-Read the SIZ marker (image and tile size)
- at param j2k J2K handle
-*/
-static void j2k_read_siz(opj_j2k_t *j2k);
-/**
-Write the COM marker (comment)
- at param j2k J2K handle
-*/
-static void j2k_write_com(opj_j2k_t *j2k);
-/**
-Read the COM marker (comment)
- at param j2k J2K handle
-*/
-static void j2k_read_com(opj_j2k_t *j2k);
-/**
-Write the value concerning the specified component in the marker COD and COC
- at param j2k J2K handle
- at param compno Number of the component concerned by the information written
-*/
-static void j2k_write_cox(opj_j2k_t *j2k, int compno);
-/**
-Read the value concerning the specified component in the marker COD and COC
- at param j2k J2K handle
- at param compno Number of the component concerned by the information read
-*/
-static void j2k_read_cox(opj_j2k_t *j2k, int compno);
-/**
-Write the COD marker (coding style default)
- at param j2k J2K handle
-*/
-static void j2k_write_cod(opj_j2k_t *j2k);
-/**
-Read the COD marker (coding style default)
- at param j2k J2K handle
-*/
-static void j2k_read_cod(opj_j2k_t *j2k);
-/**
-Write the COC marker (coding style component)
- at param j2k J2K handle
- at param compno Number of the component concerned by the information written
-*/
-static void j2k_write_coc(opj_j2k_t *j2k, int compno);
-/**
-Read the COC marker (coding style component)
- at param j2k J2K handle
-*/
-static void j2k_read_coc(opj_j2k_t *j2k);
-/**
-Write the value concerning the specified component in the marker QCD and QCC
- at param j2k J2K handle
- at param compno Number of the component concerned by the information written
-*/
-static void j2k_write_qcx(opj_j2k_t *j2k, int compno);
-/**
-Read the value concerning the specified component in the marker QCD and QCC
- at param j2k J2K handle
- at param compno Number of the component concern by the information read
- at param len Length of the information in the QCX part of the marker QCD/QCC
-*/
-static void j2k_read_qcx(opj_j2k_t *j2k, int compno, int len);
-/**
-Write the QCD marker (quantization default)
- at param j2k J2K handle
-*/
-static void j2k_write_qcd(opj_j2k_t *j2k);
-/**
-Read the QCD marker (quantization default)
- at param j2k J2K handle
-*/
-static void j2k_read_qcd(opj_j2k_t *j2k);
-/**
-Write the QCC marker (quantization component)
- at param j2k J2K handle
- at param compno Number of the component concerned by the information written
-*/
-static void j2k_write_qcc(opj_j2k_t *j2k, int compno);
-/**
-Read the QCC marker (quantization component)
- at param j2k J2K handle
-*/
-static void j2k_read_qcc(opj_j2k_t *j2k);
-/**
-Write the POC marker (progression order change)
- at param j2k J2K handle
-*/
-static void j2k_write_poc(opj_j2k_t *j2k);
-/**
-Read the POC marker (progression order change)
- at param j2k J2K handle
-*/
-static void j2k_read_poc(opj_j2k_t *j2k);
-/**
-Read the CRG marker (component registration)
- at param j2k J2K handle
-*/
-static void j2k_read_crg(opj_j2k_t *j2k);
-/**
-Read the TLM marker (tile-part lengths)
- at param j2k J2K handle
-*/
-static void j2k_read_tlm(opj_j2k_t *j2k);
-/**
-Read the PLM marker (packet length, main header)
- at param j2k J2K handle
-*/
-static void j2k_read_plm(opj_j2k_t *j2k);
-/**
-Read the PLT marker (packet length, tile-part header)
- at param j2k J2K handle
-*/
-static void j2k_read_plt(opj_j2k_t *j2k);
-/**
-Read the PPM marker (packet packet headers, main header)
- at param j2k J2K handle
-*/
-static void j2k_read_ppm(opj_j2k_t *j2k);
-/**
-Read the PPT marker (packet packet headers, tile-part header)
- at param j2k J2K handle
-*/
-static void j2k_read_ppt(opj_j2k_t *j2k);
-/**
-Write the TLM marker (Mainheader)
- at param j2k J2K handle
-*/
-static void j2k_write_tlm(opj_j2k_t *j2k);
-/**
-Write the SOT marker (start of tile-part)
- at param j2k J2K handle
-*/
-static void j2k_write_sot(opj_j2k_t *j2k);
-/**
-Read the SOT marker (start of tile-part)
- at param j2k J2K handle
-*/
-static void j2k_read_sot(opj_j2k_t *j2k);
-/**
-Write the SOD marker (start of data)
- at param j2k J2K handle
- at param tile_coder Pointer to a TCD handle
-*/
-static void j2k_write_sod(opj_j2k_t *j2k, void *tile_coder);
-/**
-Read the SOD marker (start of data)
- at param j2k J2K handle
-*/
-static void j2k_read_sod(opj_j2k_t *j2k);
-/**
-Write the RGN marker (region-of-interest)
- at param j2k J2K handle
- at param compno Number of the component concerned by the information written
- at param tileno Number of the tile concerned by the information written
-*/
-static void j2k_write_rgn(opj_j2k_t *j2k, int compno, int tileno);
-/**
-Read the RGN marker (region-of-interest)
- at param j2k J2K handle
-*/
-static void j2k_read_rgn(opj_j2k_t *j2k);
-/**
-Write the EOC marker (end of codestream)
- at param j2k J2K handle
-*/
-static void j2k_write_eoc(opj_j2k_t *j2k);
-/**
-Read the EOC marker (end of codestream)
- at param j2k J2K handle
-*/
-static void j2k_read_eoc(opj_j2k_t *j2k);
-/**
-Read an unknown marker
- at param j2k J2K handle
-*/
-static void j2k_read_unk(opj_j2k_t *j2k);
-/**
-Add main header marker information
- at param cstr_info Codestream information structure
- at param type marker type
- at param pos byte offset of marker segment
- at param len length of marker segment
- */
-static void j2k_add_mhmarker(opj_codestream_info_t *cstr_info, unsigned short int type, int pos, int len);
-/**
-Add tile header marker information
- at param tileno tile index number
- at param cstr_info Codestream information structure
- at param type marker type
- at param pos byte offset of marker segment
- at param len length of marker segment
- */
-static void j2k_add_tlmarker( int tileno, opj_codestream_info_t *cstr_info, unsigned short int type, int pos, int len);
-
-/*@}*/
-
-/*@}*/
-
-/* ----------------------------------------------------------------------- */
-typedef struct j2k_prog_order{
-	OPJ_PROG_ORDER enum_prog;
-	char str_prog[5];
-}j2k_prog_order_t;
-
-j2k_prog_order_t j2k_prog_order_list[] = {
-	{CPRL, "CPRL"},
-	{LRCP, "LRCP"},
-	{PCRL, "PCRL"},
-	{RLCP, "RLCP"},
-	{RPCL, "RPCL"},
-	{(OPJ_PROG_ORDER)-1, ""}
-};
-
-char *j2k_convert_progression_order(OPJ_PROG_ORDER prg_order){
-	j2k_prog_order_t *po;
-	for(po = j2k_prog_order_list; po->enum_prog != -1; po++ ){
-		if(po->enum_prog == prg_order){
-			break;
-		}
-	}
-	return po->str_prog;
-}
-
-/* ----------------------------------------------------------------------- */
-static int j2k_get_num_tp(opj_cp_t *cp,int pino,int tileno){
-	char *prog;
-	int i;
-	int tpnum=1,tpend=0;
-	opj_tcp_t *tcp = &cp->tcps[tileno];
-	prog = j2k_convert_progression_order(tcp->prg);
-	
-	if(cp->tp_on == 1){
-		for(i=0;i<4;i++){
-			if(tpend!=1){
-				if( cp->tp_flag == prog[i] ){
-					tpend=1;cp->tp_pos=i;
-				}
-				switch(prog[i]){
-				case 'C':
-					tpnum= tpnum * tcp->pocs[pino].compE;
-					break;
-				case 'R':
-					tpnum= tpnum * tcp->pocs[pino].resE;
-					break;
-				case 'P':
-					tpnum= tpnum * tcp->pocs[pino].prcE;
-					break;
-				case 'L':
-					tpnum= tpnum * tcp->pocs[pino].layE;
-					break;
-				}
-			}
-		}
-	}else{
-		tpnum=1;
-	}
-	return tpnum;
-}
-
-/**	mem allocation for TLM marker*/
-int j2k_calculate_tp(opj_cp_t *cp,int img_numcomp,opj_image_t *image,opj_j2k_t *j2k ){
-	int pino,tileno,totnum_tp=0;
-
-	OPJ_ARG_NOT_USED(img_numcomp);
-
-	j2k->cur_totnum_tp = (int *) opj_malloc(cp->tw * cp->th * sizeof(int));
-	for (tileno = 0; tileno < cp->tw * cp->th; tileno++) {
-		int cur_totnum_tp = 0;
-		opj_tcp_t *tcp = &cp->tcps[tileno];
-		for(pino = 0; pino <= tcp->numpocs; pino++) {
-			int tp_num=0;
-			opj_pi_iterator_t *pi = pi_initialise_encode(image, cp, tileno,FINAL_PASS);
-			if(!pi) { return -1;}
-			tp_num = j2k_get_num_tp(cp,pino,tileno);
-			totnum_tp = totnum_tp + tp_num;
-			cur_totnum_tp = cur_totnum_tp + tp_num;
-			pi_destroy(pi, cp, tileno);
-		}
-		j2k->cur_totnum_tp[tileno] = cur_totnum_tp;
-		/* INDEX >> */
-		if (j2k->cstr_info) {
-			j2k->cstr_info->tile[tileno].num_tps = cur_totnum_tp;
-			j2k->cstr_info->tile[tileno].tp = (opj_tp_info_t *) opj_malloc(cur_totnum_tp * sizeof(opj_tp_info_t));
-		}
-		/* << INDEX */
-	}
-	return totnum_tp;
-}
-
-static void j2k_write_soc(opj_j2k_t *j2k) {
-	opj_cio_t *cio = j2k->cio;
-	cio_write(cio, J2K_MS_SOC, 2);
-
-	if(j2k->cstr_info)
-	  j2k_add_mhmarker(j2k->cstr_info, J2K_MS_SOC, cio_tell(cio), 0);
-
-/* UniPG>> */
-#ifdef USE_JPWL
-
-	/* update markers struct */
-	j2k_add_marker(j2k->cstr_info, J2K_MS_SOC, cio_tell(cio) - 2, 2);
-#endif /* USE_JPWL */
-/* <<UniPG */
-}
-
-static void j2k_read_soc(opj_j2k_t *j2k) {	
-	j2k->state = J2K_STATE_MHSIZ;
-	/* Index */
-	if (j2k->cstr_info) {
-		j2k->cstr_info->main_head_start = cio_tell(j2k->cio) - 2;
-		j2k->cstr_info->codestream_size = cio_numbytesleft(j2k->cio) + 2 - j2k->cstr_info->main_head_start;
-	}
-}
-
-static void j2k_write_siz(opj_j2k_t *j2k) {
-	int i;
-	int lenp, len;
-
-	opj_cio_t *cio = j2k->cio;
-	opj_image_t *image = j2k->image;
-	opj_cp_t *cp = j2k->cp;
-
-	cio_write(cio, J2K_MS_SIZ, 2);	/* SIZ */
-	lenp = cio_tell(cio);
-	cio_skip(cio, 2);
-	cio_write(cio, cp->rsiz, 2);			/* Rsiz (capabilities) */
-	cio_write(cio, image->x1, 4);	/* Xsiz */
-	cio_write(cio, image->y1, 4);	/* Ysiz */
-	cio_write(cio, image->x0, 4);	/* X0siz */
-	cio_write(cio, image->y0, 4);	/* Y0siz */
-	cio_write(cio, cp->tdx, 4);		/* XTsiz */
-	cio_write(cio, cp->tdy, 4);		/* YTsiz */
-	cio_write(cio, cp->tx0, 4);		/* XT0siz */
-	cio_write(cio, cp->ty0, 4);		/* YT0siz */
-	cio_write(cio, image->numcomps, 2);	/* Csiz */
-	for (i = 0; i < image->numcomps; i++) {
-		cio_write(cio, image->comps[i].prec - 1 + (image->comps[i].sgnd << 7), 1);	/* Ssiz_i */
-		cio_write(cio, image->comps[i].dx, 1);	/* XRsiz_i */
-		cio_write(cio, image->comps[i].dy, 1);	/* YRsiz_i */
-	}
-	len = cio_tell(cio) - lenp;
-	cio_seek(cio, lenp);
-	cio_write(cio, len, 2);		/* Lsiz */
-	cio_seek(cio, lenp + len);
-	
-	if(j2k->cstr_info)
-	  j2k_add_mhmarker(j2k->cstr_info, J2K_MS_SIZ, lenp, len);
-}
-
-static void j2k_read_siz(opj_j2k_t *j2k) {
-	int len, i;
-	
-	opj_cio_t *cio = j2k->cio;
-	opj_image_t *image = j2k->image;
-	opj_cp_t *cp = j2k->cp;
-	
-	len = cio_read(cio, 2);			/* Lsiz */
-	cio_read(cio, 2);				/* Rsiz (capabilities) */
-	image->x1 = cio_read(cio, 4);	/* Xsiz */
-	image->y1 = cio_read(cio, 4);	/* Ysiz */
-	image->x0 = cio_read(cio, 4);	/* X0siz */
-	image->y0 = cio_read(cio, 4);	/* Y0siz */
-	cp->tdx = cio_read(cio, 4);		/* XTsiz */
-	cp->tdy = cio_read(cio, 4);		/* YTsiz */
-	cp->tx0 = cio_read(cio, 4);		/* XT0siz */
-	cp->ty0 = cio_read(cio, 4);		/* YT0siz */
-	
-	if ((image->x0<0)||(image->x1<0)||(image->y0<0)||(image->y1<0)) {
-		opj_event_msg(j2k->cinfo, EVT_ERROR,
-									"%s: invalid image size (x0:%d, x1:%d, y0:%d, y1:%d)\n",
-									image->x0,image->x1,image->y0,image->y1);
-		return;
-	}
-	
-	image->numcomps = cio_read(cio, 2);	/* Csiz */
-
-#ifdef USE_JPWL
-	if (j2k->cp->correct) {
-		/* if JPWL is on, we check whether TX errors have damaged
-		  too much the SIZ parameters */
-		if (!(image->x1 * image->y1)) {
-			opj_event_msg(j2k->cinfo, EVT_ERROR,
-				"JPWL: bad image size (%d x %d)\n",
-				image->x1, image->y1);
-			if (!JPWL_ASSUME || JPWL_ASSUME) {
-				opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n");
-				return;
-			}
-		}
-		if (image->numcomps != ((len - 38) / 3)) {
-			opj_event_msg(j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
-				"JPWL: Csiz is %d => space in SIZ only for %d comps.!!!\n",
-				image->numcomps, ((len - 38) / 3));
-			if (!JPWL_ASSUME) {
-				opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n");
-				return;
-			}
-			/* we try to correct */
-			opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust this\n");
-			if (image->numcomps < ((len - 38) / 3)) {
-				len = 38 + 3 * image->numcomps;
-				opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting Lsiz to %d => HYPOTHESIS!!!\n",
-					len);				
-			} else {
-				image->numcomps = ((len - 38) / 3);
-				opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting Csiz to %d => HYPOTHESIS!!!\n",
-					image->numcomps);				
-			}
-		}
-
-		/* update components number in the jpwl_exp_comps filed */
-		cp->exp_comps = image->numcomps;
-	}
-#endif /* USE_JPWL */
-
-	image->comps = (opj_image_comp_t*) opj_calloc(image->numcomps, sizeof(opj_image_comp_t));
-	for (i = 0; i < image->numcomps; i++) {
-		int tmp, w, h;
-		tmp = cio_read(cio, 1);		/* Ssiz_i */
-		image->comps[i].prec = (tmp & 0x7f) + 1;
-		image->comps[i].sgnd = tmp >> 7;
-		image->comps[i].dx = cio_read(cio, 1);	/* XRsiz_i */
-		image->comps[i].dy = cio_read(cio, 1);	/* YRsiz_i */
-		
-#ifdef USE_JPWL
-		if (j2k->cp->correct) {
-		/* if JPWL is on, we check whether TX errors have damaged
-			too much the SIZ parameters, again */
-			if (!(image->comps[i].dx * image->comps[i].dy)) {
-				opj_event_msg(j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
-					"JPWL: bad XRsiz_%d/YRsiz_%d (%d x %d)\n",
-					i, i, image->comps[i].dx, image->comps[i].dy);
-				if (!JPWL_ASSUME) {
-					opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n");
-					return;
-				}
-				/* we try to correct */
-				opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust them\n");
-				if (!image->comps[i].dx) {
-					image->comps[i].dx = 1;
-					opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting XRsiz_%d to %d => HYPOTHESIS!!!\n",
-						i, image->comps[i].dx);
-				}
-				if (!image->comps[i].dy) {
-					image->comps[i].dy = 1;
-					opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting YRsiz_%d to %d => HYPOTHESIS!!!\n",
-						i, image->comps[i].dy);
-				}
-			}
-			
-		}
-#endif /* USE_JPWL */
-
-		/* TODO: unused ? */
-		w = int_ceildiv(image->x1 - image->x0, image->comps[i].dx);
-		h = int_ceildiv(image->y1 - image->y0, image->comps[i].dy);
-
-		image->comps[i].resno_decoded = 0;	/* number of resolution decoded */
-		image->comps[i].factor = cp->reduce; /* reducing factor per component */
-	}
-	
-	cp->tw = int_ceildiv(image->x1 - cp->tx0, cp->tdx);
-	cp->th = int_ceildiv(image->y1 - cp->ty0, cp->tdy);
-
-#ifdef USE_JPWL
-	if (j2k->cp->correct) {
-		/* if JPWL is on, we check whether TX errors have damaged
-		  too much the SIZ parameters */
-		if ((cp->tw < 1) || (cp->th < 1) || (cp->tw > cp->max_tiles) || (cp->th > cp->max_tiles)) {
-			opj_event_msg(j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
-				"JPWL: bad number of tiles (%d x %d)\n",
-				cp->tw, cp->th);
-			if (!JPWL_ASSUME) {
-				opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n");
-				return;
-			}
-			/* we try to correct */
-			opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust them\n");
-			if (cp->tw < 1) {
-				cp->tw= 1;
-				opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting %d tiles in x => HYPOTHESIS!!!\n",
-					cp->tw);
-			}
-			if (cp->tw > cp->max_tiles) {
-				cp->tw= 1;
-				opj_event_msg(j2k->cinfo, EVT_WARNING, "- too large x, increase expectance of %d\n"
-					"- setting %d tiles in x => HYPOTHESIS!!!\n",
-					cp->max_tiles, cp->tw);
-			}
-			if (cp->th < 1) {
-				cp->th= 1;
-				opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting %d tiles in y => HYPOTHESIS!!!\n",
-					cp->th);
-			}
-			if (cp->th > cp->max_tiles) {
-				cp->th= 1;
-				opj_event_msg(j2k->cinfo, EVT_WARNING, "- too large y, increase expectance of %d to continue\n",
-					"- setting %d tiles in y => HYPOTHESIS!!!\n",
-					cp->max_tiles, cp->th);
-			}
-		}
-	}
-#endif /* USE_JPWL */
-
-	cp->tcps = (opj_tcp_t*) opj_calloc(cp->tw * cp->th, sizeof(opj_tcp_t));
-    if (cp->tcps == NULL)
-    {
-        opj_event_msg(j2k->cinfo, EVT_ERROR, "Out of memory\n");
-        return;
-    }
-	cp->tileno = (int*) opj_malloc(cp->tw * cp->th * sizeof(int));
-    if (cp->tileno == NULL)
-    {
-        opj_event_msg(j2k->cinfo, EVT_ERROR, "Out of memory\n");
-        return;
-    }
-	cp->tileno_size = 0;
-	
-#ifdef USE_JPWL
-	if (j2k->cp->correct) {
-		if (!cp->tcps) {
-			opj_event_msg(j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
-				"JPWL: could not alloc tcps field of cp\n");
-			if (!JPWL_ASSUME || JPWL_ASSUME) {
-				opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n");
-				return;
-			}
-		}
-	}
-#endif /* USE_JPWL */
-
-	for (i = 0; i < cp->tw * cp->th; i++) {
-		cp->tcps[i].POC = 0;
-		cp->tcps[i].numpocs = 0;
-		cp->tcps[i].first = 1;
-	}
-	
-	/* Initialization for PPM marker */
-	cp->ppm = 0;
-	cp->ppm_data = NULL;
-	cp->ppm_data_first = NULL;
-	cp->ppm_previous = 0;
-	cp->ppm_store = 0;
-
-	j2k->default_tcp->tccps = (opj_tccp_t*) opj_calloc(image->numcomps, sizeof(opj_tccp_t));
-	for (i = 0; i < cp->tw * cp->th; i++) {
-		cp->tcps[i].tccps = (opj_tccp_t*) opj_malloc(image->numcomps * sizeof(opj_tccp_t));
-	}	
-	j2k->tile_data = (unsigned char**) opj_calloc(cp->tw * cp->th, sizeof(unsigned char*));
-	j2k->tile_len = (int*) opj_calloc(cp->tw * cp->th, sizeof(int));
-	j2k->state = J2K_STATE_MH;
-
-	/* Index */
-	if (j2k->cstr_info) {
-		opj_codestream_info_t *cstr_info = j2k->cstr_info;
-		cstr_info->image_w = image->x1 - image->x0;
-		cstr_info->image_h = image->y1 - image->y0;
-		cstr_info->numcomps = image->numcomps;
-		cstr_info->tw = cp->tw;
-		cstr_info->th = cp->th;
-		cstr_info->tile_x = cp->tdx;	
-		cstr_info->tile_y = cp->tdy;	
-		cstr_info->tile_Ox = cp->tx0;	
-		cstr_info->tile_Oy = cp->ty0;			
-		cstr_info->tile = (opj_tile_info_t*) opj_calloc(cp->tw * cp->th, sizeof(opj_tile_info_t));		
-	}
-}
-
-static void j2k_write_com(opj_j2k_t *j2k) {
-	unsigned int i;
-	int lenp, len;
-
-	if(j2k->cp->comment) {
-		opj_cio_t *cio = j2k->cio;
-		char *comment = j2k->cp->comment;
-
-		cio_write(cio, J2K_MS_COM, 2);
-		lenp = cio_tell(cio);
-		cio_skip(cio, 2);
-		cio_write(cio, 1, 2);		/* General use (IS 8859-15:1999 (Latin) values) */
-		for (i = 0; i < strlen(comment); i++) {
-			cio_write(cio, comment[i], 1);
-		}
-		len = cio_tell(cio) - lenp;
-		cio_seek(cio, lenp);
-		cio_write(cio, len, 2);
-		cio_seek(cio, lenp + len);
-
-		
-		if(j2k->cstr_info)
-		  j2k_add_mhmarker(j2k->cstr_info, J2K_MS_COM, lenp, len);
-
-	}
-}
-
-static void j2k_read_com(opj_j2k_t *j2k) {
-	int len;
-	
-	opj_cio_t *cio = j2k->cio;
-
-	len = cio_read(cio, 2);
-	cio_skip(cio, len - 2);  
-}
-
-static void j2k_write_cox(opj_j2k_t *j2k, int compno) {
-	int i;
-
-	opj_cp_t *cp = j2k->cp;
-	opj_tcp_t *tcp = &cp->tcps[j2k->curtileno];
-	opj_tccp_t *tccp = &tcp->tccps[compno];
-	opj_cio_t *cio = j2k->cio;
-	
-	cio_write(cio, tccp->numresolutions - 1, 1);	/* SPcox (D) */
-	cio_write(cio, tccp->cblkw - 2, 1);				/* SPcox (E) */
-	cio_write(cio, tccp->cblkh - 2, 1);				/* SPcox (F) */
-	cio_write(cio, tccp->cblksty, 1);				/* SPcox (G) */
-	cio_write(cio, tccp->qmfbid, 1);				/* SPcox (H) */
-	
-	if (tccp->csty & J2K_CCP_CSTY_PRT) {
-		for (i = 0; i < tccp->numresolutions; i++) {
-			cio_write(cio, tccp->prcw[i] + (tccp->prch[i] << 4), 1);	/* SPcox (I_i) */
-		}
-	}
-}
-
-static void j2k_read_cox(opj_j2k_t *j2k, int compno) {
-	int i;
-
-	opj_cp_t *cp = j2k->cp;
-	opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp;
-	opj_tccp_t *tccp = &tcp->tccps[compno];
-	opj_cio_t *cio = j2k->cio;
-
-	tccp->numresolutions = cio_read(cio, 1) + 1;	/* SPcox (D) */
-
-	/* If user wants to remove more resolutions than the codestream contains, return error*/
-	if (cp->reduce >= tccp->numresolutions) {
-		opj_event_msg(j2k->cinfo, EVT_ERROR, "Error decoding component %d.\nThe number of resolutions to remove is higher than the number "
-					"of resolutions of this component\nModify the cp_reduce parameter.\n\n", compno);
-		j2k->state |= J2K_STATE_ERR;
-	}
-  if( tccp->numresolutions > J2K_MAXRLVLS ) {
-    opj_event_msg(j2k->cinfo, EVT_ERROR, "Error decoding component %d.\nThe number of resolutions is too big: %d vs max= %d. Truncating.\n\n",
-      compno, tccp->numresolutions, J2K_MAXRLVLS);
-		j2k->state |= J2K_STATE_ERR;
-    tccp->numresolutions = J2K_MAXRLVLS;
- }
-
-	tccp->cblkw = cio_read(cio, 1) + 2;	/* SPcox (E) */
-	tccp->cblkh = cio_read(cio, 1) + 2;	/* SPcox (F) */
-	tccp->cblksty = cio_read(cio, 1);	/* SPcox (G) */
-	tccp->qmfbid = cio_read(cio, 1);	/* SPcox (H) */
-	if (tccp->csty & J2K_CP_CSTY_PRT) {
-		for (i = 0; i < tccp->numresolutions; i++) {
-			int tmp = cio_read(cio, 1);	/* SPcox (I_i) */
-			tccp->prcw[i] = tmp & 0xf;
-			tccp->prch[i] = tmp >> 4;
-		}
-	}
-
-	/* INDEX >> */
-	if(j2k->cstr_info && compno == 0) {
-		for (i = 0; i < tccp->numresolutions; i++) {
-			if (tccp->csty & J2K_CP_CSTY_PRT) {
-				j2k->cstr_info->tile[j2k->curtileno].pdx[i] = tccp->prcw[i];
-				j2k->cstr_info->tile[j2k->curtileno].pdy[i] = tccp->prch[i];
-			}
-			else {
-				j2k->cstr_info->tile[j2k->curtileno].pdx[i] = 15;
-				j2k->cstr_info->tile[j2k->curtileno].pdx[i] = 15;
-			}
-		}
-	}
-	/* << INDEX */
-}
-
-static void j2k_write_cod(opj_j2k_t *j2k) {
-	opj_cp_t *cp = NULL;
-	opj_tcp_t *tcp = NULL;
-	int lenp, len;
-
-	opj_cio_t *cio = j2k->cio;
-	
-	cio_write(cio, J2K_MS_COD, 2);	/* COD */
-	
-	lenp = cio_tell(cio);
-	cio_skip(cio, 2);
-	
-	cp = j2k->cp;
-	tcp = &cp->tcps[j2k->curtileno];
-
-	cio_write(cio, tcp->csty, 1);		/* Scod */
-	cio_write(cio, tcp->prg, 1);		/* SGcod (A) */
-	cio_write(cio, tcp->numlayers, 2);	/* SGcod (B) */
-	cio_write(cio, tcp->mct, 1);		/* SGcod (C) */
-	
-	j2k_write_cox(j2k, 0);
-	len = cio_tell(cio) - lenp;
-	cio_seek(cio, lenp);
-	cio_write(cio, len, 2);		/* Lcod */
-	cio_seek(cio, lenp + len);
-
-	if(j2k->cstr_info)
-	  j2k_add_mhmarker(j2k->cstr_info, J2K_MS_COD, lenp, len);
-
-}
-
-static void j2k_read_cod(opj_j2k_t *j2k) {
-	int len, i, pos;
-	
-	opj_cio_t *cio = j2k->cio;
-	opj_cp_t *cp = j2k->cp;
-	opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp;
-	opj_image_t *image = j2k->image;
-	
-	len = cio_read(cio, 2);				/* Lcod */
-	tcp->csty = cio_read(cio, 1);		/* Scod */
-	tcp->prg = (OPJ_PROG_ORDER)cio_read(cio, 1);		/* SGcod (A) */
-	tcp->numlayers = cio_read(cio, 2);	/* SGcod (B) */
-	tcp->mct = cio_read(cio, 1);		/* SGcod (C) */
-	
-	pos = cio_tell(cio);
-	for (i = 0; i < image->numcomps; i++) {
-		tcp->tccps[i].csty = tcp->csty & J2K_CP_CSTY_PRT;
-		cio_seek(cio, pos);
-		j2k_read_cox(j2k, i);
-	}
-
-	/* Index */
-	if (j2k->cstr_info) {
-		opj_codestream_info_t *cstr_info = j2k->cstr_info;
-		cstr_info->prog = tcp->prg;
-		cstr_info->numlayers = tcp->numlayers;
-		cstr_info->numdecompos = (int*) opj_malloc(image->numcomps * sizeof(int));
-		for (i = 0; i < image->numcomps; i++) {
-			cstr_info->numdecompos[i] = tcp->tccps[i].numresolutions - 1;
-		}
-	}
-}
-
-static void j2k_write_coc(opj_j2k_t *j2k, int compno) {
-	int lenp, len;
-
-	opj_cp_t *cp = j2k->cp;
-	opj_tcp_t *tcp = &cp->tcps[j2k->curtileno];
-	opj_image_t *image = j2k->image;
-	opj_cio_t *cio = j2k->cio;
-	
-	cio_write(cio, J2K_MS_COC, 2);	/* COC */
-	lenp = cio_tell(cio);
-	cio_skip(cio, 2);
-	cio_write(cio, compno, image->numcomps <= 256 ? 1 : 2);	/* Ccoc */
-	cio_write(cio, tcp->tccps[compno].csty, 1);	/* Scoc */
-	j2k_write_cox(j2k, compno);
-	len = cio_tell(cio) - lenp;
-	cio_seek(cio, lenp);
-	cio_write(cio, len, 2);			/* Lcoc */
-	cio_seek(cio, lenp + len);
-}
-
-static void j2k_read_coc(opj_j2k_t *j2k) {
-	int len, compno;
-
-	opj_cp_t *cp = j2k->cp;
-	opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp;
-	opj_image_t *image = j2k->image;
-	opj_cio_t *cio = j2k->cio;
-	
-	len = cio_read(cio, 2);		/* Lcoc */
-	compno = cio_read(cio, image->numcomps <= 256 ? 1 : 2);	/* Ccoc */
-	tcp->tccps[compno].csty = cio_read(cio, 1);	/* Scoc */
-	j2k_read_cox(j2k, compno);
-}
-
-static void j2k_write_qcx(opj_j2k_t *j2k, int compno) {
-	int bandno, numbands;
-	int expn, mant;
-	
-	opj_cp_t *cp = j2k->cp;
-	opj_tcp_t *tcp = &cp->tcps[j2k->curtileno];
-	opj_tccp_t *tccp = &tcp->tccps[compno];
-	opj_cio_t *cio = j2k->cio;
-	
-	cio_write(cio, tccp->qntsty + (tccp->numgbits << 5), 1);	/* Sqcx */
-	numbands = tccp->qntsty == J2K_CCP_QNTSTY_SIQNT ? 1 : tccp->numresolutions * 3 - 2;
-	
-	for (bandno = 0; bandno < numbands; bandno++) {
-		expn = tccp->stepsizes[bandno].expn;
-		mant = tccp->stepsizes[bandno].mant;
-		
-		if (tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) {
-			cio_write(cio, expn << 3, 1);	/* SPqcx_i */
-		} else {
-			cio_write(cio, (expn << 11) + mant, 2);	/* SPqcx_i */
-		}
-	}
-}
-
-static void j2k_read_qcx(opj_j2k_t *j2k, int compno, int len) {
-	int tmp;
-	int bandno, numbands;
-
-	opj_cp_t *cp = j2k->cp;
-	opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp;
-	opj_tccp_t *tccp = &tcp->tccps[compno];
-	opj_cio_t *cio = j2k->cio;
-
-	tmp = cio_read(cio, 1);		/* Sqcx */
-	tccp->qntsty = tmp & 0x1f;
-	tccp->numgbits = tmp >> 5;
-	numbands = (tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) ? 
-		1 : ((tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) ? len - 1 : (len - 1) / 2);
-
-#ifdef USE_JPWL
-	if (j2k->cp->correct) {
-
-		/* if JPWL is on, we check whether there are too many subbands */
-		if ((numbands < 0) || (numbands >= J2K_MAXBANDS)) {
-			opj_event_msg(j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
-				"JPWL: bad number of subbands in Sqcx (%d)\n",
-				numbands);
-			if (!JPWL_ASSUME) {
-				opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n");
-				return;
-			}
-			/* we try to correct */
-			numbands = 1;
-			opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust them\n"
-				"- setting number of bands to %d => HYPOTHESIS!!!\n",
-				numbands);
-		};
-
-	};
-
-#else
-	/* We check whether there are too many subbands */
-	if ((numbands < 0) || (numbands >= J2K_MAXBANDS)) {
-		opj_event_msg(j2k->cinfo, EVT_WARNING ,
-					"bad number of subbands in Sqcx (%d) regarding to J2K_MAXBANDS (%d) \n"
-				    "- limiting number of bands to J2K_MAXBANDS and try to move to the next markers\n", numbands, J2K_MAXBANDS);
-	}
-
-#endif /* USE_JPWL */
-
-	for (bandno = 0; bandno < numbands; bandno++) {
-		int expn, mant;
-		if (tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) {
-			expn = cio_read(cio, 1) >> 3;	/* SPqcx_i */
-			mant = 0;
-		} else {
-			tmp = cio_read(cio, 2);	/* SPqcx_i */
-			expn = tmp >> 11;
-			mant = tmp & 0x7ff;
-		}
-		if (bandno < J2K_MAXBANDS){
-			tccp->stepsizes[bandno].expn = expn;
-			tccp->stepsizes[bandno].mant = mant;
-		}
-	}
-	
-	/* Add Antonin : if scalar_derived -> compute other stepsizes */
-	if (tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) {
-		for (bandno = 1; bandno < J2K_MAXBANDS; bandno++) {
-			tccp->stepsizes[bandno].expn = 
-				((tccp->stepsizes[0].expn) - ((bandno - 1) / 3) > 0) ? 
-					(tccp->stepsizes[0].expn) - ((bandno - 1) / 3) : 0;
-			tccp->stepsizes[bandno].mant = tccp->stepsizes[0].mant;
-		}
-	}
-	/* ddA */
-}
-
-static void j2k_write_qcd(opj_j2k_t *j2k) {
-	int lenp, len;
-
-	opj_cio_t *cio = j2k->cio;
-	
-	cio_write(cio, J2K_MS_QCD, 2);	/* QCD */
-	lenp = cio_tell(cio);
-	cio_skip(cio, 2);
-	j2k_write_qcx(j2k, 0);
-	len = cio_tell(cio) - lenp;
-	cio_seek(cio, lenp);
-	cio_write(cio, len, 2);			/* Lqcd */
-	cio_seek(cio, lenp + len);
-
-	if(j2k->cstr_info)
-	  j2k_add_mhmarker(j2k->cstr_info, J2K_MS_QCD, lenp, len);
-}
-
-static void j2k_read_qcd(opj_j2k_t *j2k) {
-	int len, i, pos;
-
-	opj_cio_t *cio = j2k->cio;
-	opj_image_t *image = j2k->image;
-	
-	len = cio_read(cio, 2);		/* Lqcd */
-	pos = cio_tell(cio);
-	for (i = 0; i < image->numcomps; i++) {
-		cio_seek(cio, pos);
-		j2k_read_qcx(j2k, i, len - 2);
-	}
-}
-
-static void j2k_write_qcc(opj_j2k_t *j2k, int compno) {
-	int lenp, len;
-
-	opj_cio_t *cio = j2k->cio;
-	
-	cio_write(cio, J2K_MS_QCC, 2);	/* QCC */
-	lenp = cio_tell(cio);
-	cio_skip(cio, 2);
-	cio_write(cio, compno, j2k->image->numcomps <= 256 ? 1 : 2);	/* Cqcc */
-	j2k_write_qcx(j2k, compno);
-	len = cio_tell(cio) - lenp;
-	cio_seek(cio, lenp);
-	cio_write(cio, len, 2);			/* Lqcc */
-	cio_seek(cio, lenp + len);
-}
-
-static void j2k_read_qcc(opj_j2k_t *j2k) {
-	int len, compno;
-	int numcomp = j2k->image->numcomps;
-	opj_cio_t *cio = j2k->cio;
-
-	len = cio_read(cio, 2);	/* Lqcc */
-	compno = cio_read(cio, numcomp <= 256 ? 1 : 2);	/* Cqcc */
-
-#ifdef USE_JPWL
-	if (j2k->cp->correct) {
-
-		static int backup_compno = 0;
-
-		/* compno is negative or larger than the number of components!!! */
-		if ((compno < 0) || (compno >= numcomp)) {
-			opj_event_msg(j2k->cinfo, EVT_ERROR,
-				"JPWL: bad component number in QCC (%d out of a maximum of %d)\n",
-				compno, numcomp);
-			if (!JPWL_ASSUME) {
-				opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n");
-				return;
-			}
-			/* we try to correct */
-			compno = backup_compno % numcomp;
-			opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust this\n"
-				"- setting component number to %d\n",
-				compno);
-		}
-
-		/* keep your private count of tiles */
-		backup_compno++;
-	};
-#endif /* USE_JPWL */
-
-	j2k_read_qcx(j2k, compno, len - 2 - (numcomp <= 256 ? 1 : 2));
-}
-
-static void j2k_write_poc(opj_j2k_t *j2k) {
-	int len, numpchgs, i;
-
-	int numcomps = j2k->image->numcomps;
-	
-	opj_cp_t *cp = j2k->cp;
-	opj_tcp_t *tcp = &cp->tcps[j2k->curtileno];
-	opj_tccp_t *tccp = &tcp->tccps[0];
-	opj_cio_t *cio = j2k->cio;
-
-	numpchgs = 1 + tcp->numpocs;
-	cio_write(cio, J2K_MS_POC, 2);	/* POC  */
-	len = 2 + (5 + 2 * (numcomps <= 256 ? 1 : 2)) * numpchgs;
-	cio_write(cio, len, 2);		/* Lpoc */
-	for (i = 0; i < numpchgs; i++) {
-		opj_poc_t *poc = &tcp->pocs[i];
-		cio_write(cio, poc->resno0, 1);	/* RSpoc_i */
-		cio_write(cio, poc->compno0, (numcomps <= 256 ? 1 : 2));	/* CSpoc_i */
-		cio_write(cio, poc->layno1, 2);	/* LYEpoc_i */
-		poc->layno1 = int_min(poc->layno1, tcp->numlayers);
-		cio_write(cio, poc->resno1, 1);	/* REpoc_i */
-		poc->resno1 = int_min(poc->resno1, tccp->numresolutions);
-		cio_write(cio, poc->compno1, (numcomps <= 256 ? 1 : 2));	/* CEpoc_i */
-		poc->compno1 = int_min(poc->compno1, numcomps);
-		cio_write(cio, poc->prg, 1);	/* Ppoc_i */
-	}
-}
-
-static void j2k_read_poc(opj_j2k_t *j2k) {
-	int len, numpchgs, i, old_poc;
-
-	int numcomps = j2k->image->numcomps;
-	
-	opj_cp_t *cp = j2k->cp;
-	opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp;
-	opj_cio_t *cio = j2k->cio;
-	
-	old_poc = tcp->POC ? tcp->numpocs + 1 : 0;
-	tcp->POC = 1;
-	len = cio_read(cio, 2);		/* Lpoc */
-	numpchgs = (len - 2) / (5 + 2 * (numcomps <= 256 ? 1 : 2));
-	
-	for (i = old_poc; i < numpchgs + old_poc; i++) {
-		opj_poc_t *poc;
-		poc = &tcp->pocs[i];
-		poc->resno0 = cio_read(cio, 1);	/* RSpoc_i */
-		poc->compno0 = cio_read(cio, numcomps <= 256 ? 1 : 2);	/* CSpoc_i */
-		poc->layno1 = cio_read(cio, 2);    /* LYEpoc_i */
-		poc->resno1 = cio_read(cio, 1);    /* REpoc_i */
-		poc->compno1 = int_min(
-			cio_read(cio, numcomps <= 256 ? 1 : 2), (unsigned int) numcomps);	/* CEpoc_i */
-		poc->prg = (OPJ_PROG_ORDER)cio_read(cio, 1);	/* Ppoc_i */
-	}
-	
-	tcp->numpocs = numpchgs + old_poc - 1;
-}
-
-static void j2k_read_crg(opj_j2k_t *j2k) {
-	int len, i, Xcrg_i, Ycrg_i;
-	
-	opj_cio_t *cio = j2k->cio;
-	int numcomps = j2k->image->numcomps;
-	
-	len = cio_read(cio, 2);			/* Lcrg */
-	for (i = 0; i < numcomps; i++) {
-		Xcrg_i = cio_read(cio, 2);	/* Xcrg_i */
-		Ycrg_i = cio_read(cio, 2);	/* Ycrg_i */
-	}
-}
-
-static void j2k_read_tlm(opj_j2k_t *j2k) {
-	int len, Ztlm, Stlm, ST, SP, tile_tlm, i;
-	long int Ttlm_i, Ptlm_i;
-
-	opj_cio_t *cio = j2k->cio;
-	
-	len = cio_read(cio, 2);		/* Ltlm */
-	Ztlm = cio_read(cio, 1);	/* Ztlm */
-	Stlm = cio_read(cio, 1);	/* Stlm */
-	ST = ((Stlm >> 4) & 0x01) + ((Stlm >> 4) & 0x02);
-	SP = (Stlm >> 6) & 0x01;
-	tile_tlm = (len - 4) / ((SP + 1) * 2 + ST);
-	for (i = 0; i < tile_tlm; i++) {
-		Ttlm_i = cio_read(cio, ST);	/* Ttlm_i */
-		Ptlm_i = cio_read(cio, SP ? 4 : 2);	/* Ptlm_i */
-	}
-}
-
-static void j2k_read_plm(opj_j2k_t *j2k) {
-	int len, i, Zplm, Nplm, add, packet_len = 0;
-	
-	opj_cio_t *cio = j2k->cio;
-
-	len = cio_read(cio, 2);		/* Lplm */
-	Zplm = cio_read(cio, 1);	/* Zplm */
-	len -= 3;
-	while (len > 0) {
-		Nplm = cio_read(cio, 4);		/* Nplm */
-		len -= 4;
-		for (i = Nplm; i > 0; i--) {
-			add = cio_read(cio, 1);
-			len--;
-			packet_len = (packet_len << 7) + add;	/* Iplm_ij */
-			if ((add & 0x80) == 0) {
-				/* New packet */
-				packet_len = 0;
-			}
-			if (len <= 0)
-				break;
-		}
-	}
-}
-
-static void j2k_read_plt(opj_j2k_t *j2k) {
-	int len, i, Zplt, packet_len = 0, add;
-	
-	opj_cio_t *cio = j2k->cio;
-	
-	len = cio_read(cio, 2);		/* Lplt */
-	Zplt = cio_read(cio, 1);	/* Zplt */
-	for (i = len - 3; i > 0; i--) {
-		add = cio_read(cio, 1);
-		packet_len = (packet_len << 7) + add;	/* Iplt_i */
-		if ((add & 0x80) == 0) {
-			/* New packet */
-			packet_len = 0;
-		}
-	}
-}
-
-static void j2k_read_ppm(opj_j2k_t *j2k) {
-	int len, Z_ppm, i, j;
-	int N_ppm;
-
-	opj_cp_t *cp = j2k->cp;
-	opj_cio_t *cio = j2k->cio;
-	
-	len = cio_read(cio, 2);
-	cp->ppm = 1;
-	
-	Z_ppm = cio_read(cio, 1);	/* Z_ppm */
-	len -= 3;
-	while (len > 0) {
-		if (cp->ppm_previous == 0) {
-			N_ppm = cio_read(cio, 4);	/* N_ppm */
-			len -= 4;
-		} else {
-			N_ppm = cp->ppm_previous;
-		}
-		j = cp->ppm_store;
-		if (Z_ppm == 0) {	/* First PPM marker */
-			cp->ppm_data = (unsigned char *) opj_malloc(N_ppm * sizeof(unsigned char));
-			cp->ppm_data_first = cp->ppm_data;
-			cp->ppm_len = N_ppm;
-		} else {			/* NON-first PPM marker */
-			cp->ppm_data = (unsigned char *) opj_realloc(cp->ppm_data, (N_ppm +	cp->ppm_store) * sizeof(unsigned char));
-
-#ifdef USE_JPWL
-			/* this memory allocation check could be done even in non-JPWL cases */
-			if (cp->correct) {
-				if (!cp->ppm_data) {
-					opj_event_msg(j2k->cinfo, EVT_ERROR,
-						"JPWL: failed memory allocation during PPM marker parsing (pos. %x)\n",
-						cio_tell(cio));
-					if (!JPWL_ASSUME || JPWL_ASSUME) {
-						opj_free(cp->ppm_data);
-						opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n");
-						return;
-					}
-				}
-			}
-#endif
-
-			cp->ppm_data_first = cp->ppm_data;
-			cp->ppm_len = N_ppm + cp->ppm_store;
-		}
-		for (i = N_ppm; i > 0; i--) {	/* Read packet header */
-			cp->ppm_data[j] = cio_read(cio, 1);
-			j++;
-			len--;
-			if (len == 0)
-				break;			/* Case of non-finished packet header in present marker but finished in next one */
-		}
-		cp->ppm_previous = i - 1;
-		cp->ppm_store = j;
-	}
-}
-
-static void j2k_read_ppt(opj_j2k_t *j2k) {
-	int len, Z_ppt, i, j = 0;
-
-	opj_cp_t *cp = j2k->cp;
-	opj_tcp_t *tcp = cp->tcps + j2k->curtileno;
-	opj_cio_t *cio = j2k->cio;
-
-	len = cio_read(cio, 2);
-	Z_ppt = cio_read(cio, 1);
-	tcp->ppt = 1;
-	if (Z_ppt == 0) {		/* First PPT marker */
-		tcp->ppt_data = (unsigned char *) opj_malloc((len - 3) * sizeof(unsigned char));
-		tcp->ppt_data_first = tcp->ppt_data;
-		tcp->ppt_store = 0;
-		tcp->ppt_len = len - 3;
-	} else {			/* NON-first PPT marker */
-		tcp->ppt_data =	(unsigned char *) opj_realloc(tcp->ppt_data, (len - 3 + tcp->ppt_store) * sizeof(unsigned char));
-		tcp->ppt_data_first = tcp->ppt_data;
-		tcp->ppt_len = len - 3 + tcp->ppt_store;
-	}
-	j = tcp->ppt_store;
-	for (i = len - 3; i > 0; i--) {
-		tcp->ppt_data[j] = cio_read(cio, 1);
-		j++;
-	}
-	tcp->ppt_store = j;
-}
-
-static void j2k_write_tlm(opj_j2k_t *j2k){
-	int lenp;
-	opj_cio_t *cio = j2k->cio;
-	j2k->tlm_start = cio_tell(cio);
-	cio_write(cio, J2K_MS_TLM, 2);/* TLM */
-	lenp = 4 + (5*j2k->totnum_tp);
-	cio_write(cio,lenp,2);				/* Ltlm */
-	cio_write(cio, 0,1);					/* Ztlm=0*/
-	cio_write(cio,80,1);					/* Stlm ST=1(8bits-255 tiles max),SP=1(Ptlm=32bits) */
-	cio_skip(cio,5*j2k->totnum_tp);
-}
-
-static void j2k_write_sot(opj_j2k_t *j2k) {
-	int lenp, len;
-
-	opj_cio_t *cio = j2k->cio;
-
-	j2k->sot_start = cio_tell(cio);
-	cio_write(cio, J2K_MS_SOT, 2);		/* SOT */
-	lenp = cio_tell(cio);
-	cio_skip(cio, 2);					/* Lsot (further) */
-	cio_write(cio, j2k->curtileno, 2);	/* Isot */
-	cio_skip(cio, 4);					/* Psot (further in j2k_write_sod) */
-	cio_write(cio, j2k->cur_tp_num , 1);	/* TPsot */
-	cio_write(cio, j2k->cur_totnum_tp[j2k->curtileno], 1);		/* TNsot */
-	len = cio_tell(cio) - lenp;
-	cio_seek(cio, lenp);
-	cio_write(cio, len, 2);				/* Lsot */
-	cio_seek(cio, lenp + len);
-
-	/* UniPG>> */
-#ifdef USE_JPWL
-	/* update markers struct */
-	j2k_add_marker(j2k->cstr_info, J2K_MS_SOT, j2k->sot_start, len + 2);
-#endif /* USE_JPWL */
-	/* <<UniPG */
-
-	if( j2k->cstr_info && j2k->cur_tp_num==0){
-	  j2k_add_tlmarker( j2k->curtileno, j2k->cstr_info, J2K_MS_SOT, lenp, len);
-	}
-}
-
-static void j2k_read_sot(opj_j2k_t *j2k) {
-	int len, tileno, totlen, partno, numparts, i;
-	opj_tcp_t *tcp = NULL;
-	char status = 0;
-
-	opj_cp_t *cp = j2k->cp;
-	opj_cio_t *cio = j2k->cio;
-
-	len = cio_read(cio, 2);
-	tileno = cio_read(cio, 2);
-
-#ifdef USE_JPWL
-	if (j2k->cp->correct) {
-
-		static int backup_tileno = 0;
-
-		/* tileno is negative or larger than the number of tiles!!! */
-		if ((tileno < 0) || (tileno >= (cp->tw * cp->th))) {
-			opj_event_msg(j2k->cinfo, EVT_ERROR,
-				"JPWL: bad tile number (%d out of a maximum of %d)\n",
-				tileno, (cp->tw * cp->th));
-			if (!JPWL_ASSUME) {
-				opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n");
-				return;
-			}
-			/* we try to correct */
-			tileno = backup_tileno;
-			opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust this\n"
-				"- setting tile number to %d\n",
-				tileno);
-		}
-
-		/* keep your private count of tiles */
-		backup_tileno++;
-	}
-  else
-#endif /* USE_JPWL */
-  {
-    /* tileno is negative or larger than the number of tiles!!! */
-    if ((tileno < 0) || (tileno >= (cp->tw * cp->th))) {
-      opj_event_msg(j2k->cinfo, EVT_ERROR,
-        "JPWL: bad tile number (%d out of a maximum of %d)\n",
-        tileno, (cp->tw * cp->th));
-      return;
-    }
-  }
-	
-	if (cp->tileno_size == 0) {
-		cp->tileno[cp->tileno_size] = tileno;
-		cp->tileno_size++;
-	} else {
-		i = 0;
-		while (i < cp->tileno_size && status == 0) {
-			status = cp->tileno[i] == tileno ? 1 : 0;
-			i++;
-		}
-		if (status == 0) {
-			cp->tileno[cp->tileno_size] = tileno;
-			cp->tileno_size++;
-		}
-	}
-	
-	totlen = cio_read(cio, 4);
-
-#ifdef USE_JPWL
-	if (j2k->cp->correct) {
-
-		/* totlen is negative or larger than the bytes left!!! */
-		if ((totlen < 0) || (totlen > (cio_numbytesleft(cio) + 8))) {
-			opj_event_msg(j2k->cinfo, EVT_ERROR,
-				"JPWL: bad tile byte size (%d bytes against %d bytes left)\n",
-				totlen, cio_numbytesleft(cio) + 8);
-			if (!JPWL_ASSUME) {
-				opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n");
-				return;
-			}
-			/* we try to correct */
-			totlen = 0;
-			opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust this\n"
-				"- setting Psot to %d => assuming it is the last tile\n",
-				totlen);
-		}
-
-	}
-  else
-#endif /* USE_JPWL */
-  {
-    /* totlen is negative or larger than the bytes left!!! */
-    if ((totlen < 0) || (totlen > (cio_numbytesleft(cio) + 8))) {
-      opj_event_msg(j2k->cinfo, EVT_ERROR,
-        "JPWL: bad tile byte size (%d bytes against %d bytes left)\n",
-        totlen, cio_numbytesleft(cio) + 8);
-      return;
-    }
-  }
-
-	if (!totlen)
-		totlen = cio_numbytesleft(cio) + 8;
-	
-	partno = cio_read(cio, 1);
-	numparts = cio_read(cio, 1);
-  
-  if (partno >= numparts) {
-    opj_event_msg(j2k->cinfo, EVT_WARNING, "SOT marker inconsistency in tile %d: tile-part index greater (%d) than number of tile-parts (%d)\n", tileno, partno, numparts);
-    numparts = partno+1;
-  }
-	
-	j2k->curtileno = tileno;
-	j2k->cur_tp_num = partno;
-	j2k->eot = cio_getbp(cio) - 12 + totlen;
-	j2k->state = J2K_STATE_TPH;
-	tcp = &cp->tcps[j2k->curtileno];
-
-	/* Index */
-	if (j2k->cstr_info) {
-		if (tcp->first) {
-			if (tileno == 0) 
-				j2k->cstr_info->main_head_end = cio_tell(cio) - 13;
-			j2k->cstr_info->tile[tileno].tileno = tileno;
-			j2k->cstr_info->tile[tileno].start_pos = cio_tell(cio) - 12;
-			j2k->cstr_info->tile[tileno].end_pos = j2k->cstr_info->tile[tileno].start_pos + totlen - 1;				
-    } else {
-			j2k->cstr_info->tile[tileno].end_pos += totlen;
-		}
-    j2k->cstr_info->tile[tileno].num_tps = numparts;
-    if (numparts)
-      j2k->cstr_info->tile[tileno].tp = (opj_tp_info_t *) opj_realloc(j2k->cstr_info->tile[tileno].tp, numparts * sizeof(opj_tp_info_t));
-    else
-      j2k->cstr_info->tile[tileno].tp = (opj_tp_info_t *) opj_realloc(j2k->cstr_info->tile[tileno].tp, 10 * sizeof(opj_tp_info_t)); /* Fixme (10)*/
-		j2k->cstr_info->tile[tileno].tp[partno].tp_start_pos = cio_tell(cio) - 12;
-		j2k->cstr_info->tile[tileno].tp[partno].tp_end_pos = 
-			j2k->cstr_info->tile[tileno].tp[partno].tp_start_pos + totlen - 1;
-	}
-	
-	if (tcp->first == 1) {		
-		/* Initialization PPT */
-		opj_tccp_t *tmp = tcp->tccps;
-		memcpy(tcp, j2k->default_tcp, sizeof(opj_tcp_t));
-		tcp->ppt = 0;
-		tcp->ppt_data = NULL;
-		tcp->ppt_data_first = NULL;
-		tcp->tccps = tmp;
-
-		for (i = 0; i < j2k->image->numcomps; i++) {
-			tcp->tccps[i] = j2k->default_tcp->tccps[i];
-		}
-		cp->tcps[j2k->curtileno].first = 0;
-	}
-}
-
-static void j2k_write_sod(opj_j2k_t *j2k, void *tile_coder) {
-	int l, layno;
-	int totlen;
-	opj_tcp_t *tcp = NULL;
-	opj_codestream_info_t *cstr_info = NULL;
-	
-	opj_tcd_t *tcd = (opj_tcd_t*)tile_coder;	/* cast is needed because of conflicts in header inclusions */
-	opj_cp_t *cp = j2k->cp;
-	opj_cio_t *cio = j2k->cio;
-
-	tcd->tp_num = j2k->tp_num ;
-	tcd->cur_tp_num = j2k->cur_tp_num;
-	
-	cio_write(cio, J2K_MS_SOD, 2);
-
-	if( j2k->cstr_info && j2k->cur_tp_num==0){
-	  j2k_add_tlmarker( j2k->curtileno, j2k->cstr_info, J2K_MS_SOD, cio_tell(cio), 0);
-	}
-
-	if (j2k->curtileno == 0) {
-		j2k->sod_start = cio_tell(cio) + j2k->pos_correction;
-	}
-
-	/* INDEX >> */
-	cstr_info = j2k->cstr_info;
-	if (cstr_info) {
-		if (!j2k->cur_tp_num ) {
-			cstr_info->tile[j2k->curtileno].end_header = cio_tell(cio) + j2k->pos_correction - 1;
-			j2k->cstr_info->tile[j2k->curtileno].tileno = j2k->curtileno;
-		}
-		else{
-			if(cstr_info->tile[j2k->curtileno].packet[cstr_info->packno - 1].end_pos < cio_tell(cio))
-				cstr_info->tile[j2k->curtileno].packet[cstr_info->packno].start_pos = cio_tell(cio);
-		}
-		/* UniPG>> */
-#ifdef USE_JPWL
-		/* update markers struct */
-		j2k_add_marker(j2k->cstr_info, J2K_MS_SOD, j2k->sod_start, 2);
-#endif /* USE_JPWL */
-		/* <<UniPG */
-	}
-	/* << INDEX */
-	
-	tcp = &cp->tcps[j2k->curtileno];
-	for (layno = 0; layno < tcp->numlayers; layno++) {
-		if (tcp->rates[layno]>(j2k->sod_start / (cp->th * cp->tw))) {
-			tcp->rates[layno]-=(j2k->sod_start / (cp->th * cp->tw));
-		} else if (tcp->rates[layno]) {
-			tcp->rates[layno]=1;
-		}
-	}
-	if(j2k->cur_tp_num == 0){
-		tcd->tcd_image->tiles->packno = 0;
-		if(cstr_info)
-			cstr_info->packno = 0;
-	}
-	
-	l = tcd_encode_tile(tcd, j2k->curtileno, cio_getbp(cio), cio_numbytesleft(cio) - 2, cstr_info);
-	
-	/* Writing Psot in SOT marker */
-	totlen = cio_tell(cio) + l - j2k->sot_start;
-	cio_seek(cio, j2k->sot_start + 6);
-	cio_write(cio, totlen, 4);
-	cio_seek(cio, j2k->sot_start + totlen);
-	/* Writing Ttlm and Ptlm in TLM marker */
-	if(cp->cinema){
-		cio_seek(cio, j2k->tlm_start + 6 + (5*j2k->cur_tp_num));
-		cio_write(cio, j2k->curtileno, 1);
-		cio_write(cio, totlen, 4);
-	}
-	cio_seek(cio, j2k->sot_start + totlen);
-}
-
-static void j2k_read_sod(opj_j2k_t *j2k) {
-	int len, truncate = 0, i;
-	unsigned char *data = NULL, *data_ptr = NULL;
-
-	opj_cio_t *cio = j2k->cio;
-	int curtileno = j2k->curtileno;
-
-	/* Index */
-	if (j2k->cstr_info) {
-		j2k->cstr_info->tile[j2k->curtileno].tp[j2k->cur_tp_num].tp_end_header =
-			cio_tell(cio) + j2k->pos_correction - 1;
-		if (j2k->cur_tp_num == 0)
-			j2k->cstr_info->tile[j2k->curtileno].end_header = cio_tell(cio) + j2k->pos_correction - 1;
-		j2k->cstr_info->packno = 0;
-	}
-	
-	len = int_min(j2k->eot - cio_getbp(cio), cio_numbytesleft(cio) + 1);
-
-	if (len == cio_numbytesleft(cio) + 1) {
-		truncate = 1;		/* Case of a truncate codestream */
-	}	
-
-   {/* chop padding bytes: */
-    unsigned char *s, *e; 
-
-    s = cio_getbp(cio);
-    e = s + len;
-
-  if(len > 8) s = e - 8;
-
-  if(e[-2] == 0x00 && e[-1] == 0x00) /* padding bytes */
-  {
-	while(e > s)
- {
-	if(e[-2] == 0xff && e[-1] == 0xd9)	break;
-  --len; --e; truncate = 1;
- }
-  }
-   }
-
-	data = j2k->tile_data[curtileno];
-	data = (unsigned char*) opj_realloc(data, (j2k->tile_len[curtileno] + len) * sizeof(unsigned char));
-
-	data_ptr = data + j2k->tile_len[curtileno];
-	for (i = 0; i < len; i++) {
-		data_ptr[i] = cio_read(cio, 1);
-	}
-
-	j2k->tile_len[curtileno] += len;
-	j2k->tile_data[curtileno] = data;
-	
-	if (!truncate) {
-		j2k->state = J2K_STATE_TPHSOT;
-	} else {
-		j2k->state = J2K_STATE_NEOC;	/* RAJOUTE !! */
-	}
-	j2k->cur_tp_num++;
-}
-
-static void j2k_write_rgn(opj_j2k_t *j2k, int compno, int tileno) {
-	opj_cp_t *cp = j2k->cp;
-	opj_tcp_t *tcp = &cp->tcps[tileno];
-	opj_cio_t *cio = j2k->cio;
-	int numcomps = j2k->image->numcomps;
-	
-	cio_write(cio, J2K_MS_RGN, 2);						/* RGN  */
-	cio_write(cio, numcomps <= 256 ? 5 : 6, 2);			/* Lrgn */
-	cio_write(cio, compno, numcomps <= 256 ? 1 : 2);	/* Crgn */
-	cio_write(cio, 0, 1);								/* Srgn */
-	cio_write(cio, tcp->tccps[compno].roishift, 1);		/* SPrgn */
-}
-
-static void j2k_read_rgn(opj_j2k_t *j2k) {
-	int len, compno, roisty;
-
-	opj_cp_t *cp = j2k->cp;
-	opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp;
-	opj_cio_t *cio = j2k->cio;
-	int numcomps = j2k->image->numcomps;
-
-	len = cio_read(cio, 2);										/* Lrgn */
-	compno = cio_read(cio, numcomps <= 256 ? 1 : 2);			/* Crgn */
-	roisty = cio_read(cio, 1);									/* Srgn */
-
-#ifdef USE_JPWL
-	if (j2k->cp->correct) {
-		/* totlen is negative or larger than the bytes left!!! */
-		if (compno >= numcomps) {
-			opj_event_msg(j2k->cinfo, EVT_ERROR,
-				"JPWL: bad component number in RGN (%d when there are only %d)\n",
-				compno, numcomps);
-			if (!JPWL_ASSUME || JPWL_ASSUME) {
-				opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n");
-				return;
-			}
-		}
-	};
-#endif /* USE_JPWL */
-
-	tcp->tccps[compno].roishift = cio_read(cio, 1);				/* SPrgn */
-}
-
-static void j2k_write_eoc(opj_j2k_t *j2k) {
-	opj_cio_t *cio = j2k->cio;
-	/* opj_event_msg(j2k->cinfo, "%.8x: EOC\n", cio_tell(cio) + j2k->pos_correction); */
-	cio_write(cio, J2K_MS_EOC, 2);
-
-/* UniPG>> */
-#ifdef USE_JPWL
-	/* update markers struct */
-	j2k_add_marker(j2k->cstr_info, J2K_MS_EOC, cio_tell(cio) - 2, 2);
-#endif /* USE_JPWL */
-/* <<UniPG */
-}
-
-static void j2k_read_eoc(opj_j2k_t *j2k) {
-	int i, tileno;
-	opj_bool success = OPJ_FALSE;
-
-	/* if packets should be decoded */
-	if (j2k->cp->limit_decoding != DECODE_ALL_BUT_PACKETS) {
-		opj_tcd_t *tcd = tcd_create(j2k->cinfo);
-		tcd_malloc_decode(tcd, j2k->image, j2k->cp);
-		for (i = 0; i < j2k->cp->tileno_size; i++) {
-			tcd_malloc_decode_tile(tcd, j2k->image, j2k->cp, i, j2k->cstr_info);
-			if (j2k->cp->tileno[i] != -1)
-			{
-				tileno = j2k->cp->tileno[i];
-				success = tcd_decode_tile(tcd, j2k->tile_data[tileno], j2k->tile_len[tileno], tileno, j2k->cstr_info);
-				opj_free(j2k->tile_data[tileno]);
-				j2k->tile_data[tileno] = NULL;
-				tcd_free_decode_tile(tcd, i);
-			}
-			else
-				success = OPJ_FALSE;
-			if (success == OPJ_FALSE) {
-				j2k->state |= J2K_STATE_ERR;
-				break;
-			}
-		}
-		tcd_free_decode(tcd);
-		tcd_destroy(tcd);
-	}
-	/* if packets should not be decoded  */
-	else {
-		for (i = 0; i < j2k->cp->tileno_size; i++) {
-			tileno = j2k->cp->tileno[i];
-			opj_free(j2k->tile_data[tileno]);
-			j2k->tile_data[tileno] = NULL;
-		}
-	}	
-	if (j2k->state & J2K_STATE_ERR)
-		j2k->state = J2K_STATE_MT + J2K_STATE_ERR;
-	else
-		j2k->state = J2K_STATE_MT; 
-}
-
-typedef struct opj_dec_mstabent {
-	/** marker value */
-	int id;
-	/** value of the state when the marker can appear */
-	int states;
-	/** action linked to the marker */
-	void (*handler) (opj_j2k_t *j2k);
-} opj_dec_mstabent_t;
-
-opj_dec_mstabent_t j2k_dec_mstab[] = {
-  {J2K_MS_SOC, J2K_STATE_MHSOC, j2k_read_soc},
-  {J2K_MS_SOT, J2K_STATE_MH | J2K_STATE_TPHSOT, j2k_read_sot},
-  {J2K_MS_SOD, J2K_STATE_TPH, j2k_read_sod},
-  {J2K_MS_EOC, J2K_STATE_TPHSOT, j2k_read_eoc},
-  {J2K_MS_SIZ, J2K_STATE_MHSIZ, j2k_read_siz},
-  {J2K_MS_COD, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_cod},
-  {J2K_MS_COC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_coc},
-  {J2K_MS_RGN, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_rgn},
-  {J2K_MS_QCD, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_qcd},
-  {J2K_MS_QCC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_qcc},
-  {J2K_MS_POC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_poc},
-  {J2K_MS_TLM, J2K_STATE_MH, j2k_read_tlm},
-  {J2K_MS_PLM, J2K_STATE_MH, j2k_read_plm},
-  {J2K_MS_PLT, J2K_STATE_TPH, j2k_read_plt},
-  {J2K_MS_PPM, J2K_STATE_MH, j2k_read_ppm},
-  {J2K_MS_PPT, J2K_STATE_TPH, j2k_read_ppt},
-  {J2K_MS_SOP, 0, 0},
-  {J2K_MS_CRG, J2K_STATE_MH, j2k_read_crg},
-  {J2K_MS_COM, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_com},
-
-#ifdef USE_JPWL
-  {J2K_MS_EPC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_epc},
-  {J2K_MS_EPB, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_epb},
-  {J2K_MS_ESD, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_esd},
-  {J2K_MS_RED, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_red},
-#endif /* USE_JPWL */
-#ifdef USE_JPSEC
-  {J2K_MS_SEC, J2K_STATE_MH, j2k_read_sec},
-  {J2K_MS_INSEC, 0, j2k_read_insec},
-#endif /* USE_JPSEC */
-
-  {0, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_unk}
-};
-
-static void j2k_read_unk(opj_j2k_t *j2k) {
-	opj_event_msg(j2k->cinfo, EVT_WARNING, "Unknown marker\n");
-
-#ifdef USE_JPWL
-	if (j2k->cp->correct) {
-		int m = 0, id, i;
-		int min_id = 0, min_dist = 17, cur_dist = 0, tmp_id;
-		cio_seek(j2k->cio, cio_tell(j2k->cio) - 2);
-		id = cio_read(j2k->cio, 2);
-		opj_event_msg(j2k->cinfo, EVT_ERROR,
-			"JPWL: really don't know this marker %x\n",
-			id);
-		if (!JPWL_ASSUME) {
-			opj_event_msg(j2k->cinfo, EVT_ERROR,
-				"- possible synch loss due to uncorrectable codestream errors => giving up\n");
-			return;
-		}
-		/* OK, activate this at your own risk!!! */
-		/* we look for the marker at the minimum hamming distance from this */
-		while (j2k_dec_mstab[m].id) {
-			
-			/* 1's where they differ */
-			tmp_id = j2k_dec_mstab[m].id ^ id;
-
-			/* compute the hamming distance between our id and the current */
-			cur_dist = 0;
-			for (i = 0; i < 16; i++) {
-				if ((tmp_id >> i) & 0x0001) {
-					cur_dist++;
-				}
-			}
-
-			/* if current distance is smaller, set the minimum */
-			if (cur_dist < min_dist) {
-				min_dist = cur_dist;
-				min_id = j2k_dec_mstab[m].id;
-			}
-			
-			/* jump to the next marker */
-			m++;
-		}
-
-		/* do we substitute the marker? */
-		if (min_dist < JPWL_MAXIMUM_HAMMING) {
-			opj_event_msg(j2k->cinfo, EVT_ERROR,
-				"- marker %x is at distance %d from the read %x\n",
-				min_id, min_dist, id);
-			opj_event_msg(j2k->cinfo, EVT_ERROR,
-				"- trying to substitute in place and crossing fingers!\n");
-			cio_seek(j2k->cio, cio_tell(j2k->cio) - 2);
-			cio_write(j2k->cio, min_id, 2);
-
-			/* rewind */
-			cio_seek(j2k->cio, cio_tell(j2k->cio) - 2);
-
-		}
-
-	};
-#endif /* USE_JPWL */
-
-}
-
-/**
-Read the lookup table containing all the marker, status and action
- at param id Marker value
-*/
-static opj_dec_mstabent_t *j2k_dec_mstab_lookup(int id) {
-	opj_dec_mstabent_t *e;
-	for (e = j2k_dec_mstab; e->id != 0; e++) {
-		if (e->id == id) {
-			break;
-		}
-	}
-	return e;
-}
-
-/* ----------------------------------------------------------------------- */
-/* J2K / JPT decoder interface                                             */
-/* ----------------------------------------------------------------------- */
-
-opj_j2k_t* j2k_create_decompress(opj_common_ptr cinfo) {
-	opj_j2k_t *j2k = (opj_j2k_t*) opj_calloc(1, sizeof(opj_j2k_t));
-	if(!j2k)
-		return NULL;
-
-	j2k->default_tcp = (opj_tcp_t*) opj_calloc(1, sizeof(opj_tcp_t));
-	if(!j2k->default_tcp) {
-		opj_free(j2k);
-		return NULL;
-	}
-
-	j2k->cinfo = cinfo;
-	j2k->tile_data = NULL;
-
-	return j2k;
-}
-
-void j2k_destroy_decompress(opj_j2k_t *j2k) {
-	int i = 0;
-
-	if(j2k->tile_len != NULL) {
-		opj_free(j2k->tile_len);
-	}
-	if(j2k->tile_data != NULL) {
-        if(j2k->cp != NULL) {
-            for (i = 0; i < j2k->cp->tileno_size; i++) {
-                int tileno = j2k->cp->tileno[i];
-                opj_free(j2k->tile_data[tileno]);
-                j2k->tile_data[tileno] = NULL;
-            }
-        }
-
-		opj_free(j2k->tile_data);
-	}
-	if(j2k->default_tcp != NULL) {
-		opj_tcp_t *default_tcp = j2k->default_tcp;
-		if(default_tcp->ppt_data_first != NULL) {
-			opj_free(default_tcp->ppt_data_first);
-		}
-		if(j2k->default_tcp->tccps != NULL) {
-			opj_free(j2k->default_tcp->tccps);
-		}
-		opj_free(j2k->default_tcp);
-	}
-	if(j2k->cp != NULL) {
-		opj_cp_t *cp = j2k->cp;
-		if(cp->tcps != NULL) {
-			for(i = 0; i < cp->tw * cp->th; i++) {
-				if(cp->tcps[i].ppt_data_first != NULL) {
-					opj_free(cp->tcps[i].ppt_data_first);
-				}
-				if(cp->tcps[i].tccps != NULL) {
-					opj_free(cp->tcps[i].tccps);
-				}
-			}
-			opj_free(cp->tcps);
-		}
-		if(cp->ppm_data_first != NULL) {
-			opj_free(cp->ppm_data_first);
-		}
-		if(cp->tileno != NULL) {
-			opj_free(cp->tileno);  
-		}
-		if(cp->comment != NULL) {
-			opj_free(cp->comment);
-		}
-
-		opj_free(cp);
-	}
-	opj_free(j2k);
-}
-
-void j2k_setup_decoder(opj_j2k_t *j2k, opj_dparameters_t *parameters) {
-	if(j2k && parameters) {
-		/* create and initialize the coding parameters structure */
-		opj_cp_t *cp = (opj_cp_t*) opj_calloc(1, sizeof(opj_cp_t));
-		cp->reduce = parameters->cp_reduce;	
-		cp->layer = parameters->cp_layer;
-		cp->limit_decoding = parameters->cp_limit_decoding;
-
-#ifdef USE_JPWL
-		cp->correct = parameters->jpwl_correct;
-		cp->exp_comps = parameters->jpwl_exp_comps;
-		cp->max_tiles = parameters->jpwl_max_tiles;
-#endif /* USE_JPWL */
-
-
-		/* keep a link to cp so that we can destroy it later in j2k_destroy_decompress */
-		j2k->cp = cp;
-	}
-}
-
-opj_image_t* j2k_decode(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestream_info_t *cstr_info) {
-	opj_image_t *image = NULL;
-
-	opj_common_ptr cinfo = j2k->cinfo;	
-
-	j2k->cio = cio;
-	j2k->cstr_info = cstr_info;
-	if (cstr_info)
-		memset(cstr_info, 0, sizeof(opj_codestream_info_t));
-
-	/* create an empty image */
-	image = opj_image_create0();
-	j2k->image = image;
-
-	j2k->state = J2K_STATE_MHSOC;
-
-	for (;;) {
-		opj_dec_mstabent_t *e;
-		int id = cio_read(cio, 2);
-
-#ifdef USE_JPWL
-		/* we try to honor JPWL correction power */
-		if (j2k->cp->correct) {
-
-			int orig_pos = cio_tell(cio);
-			opj_bool status;
-
-			/* call the corrector */
-			status = jpwl_correct(j2k);
-
-			/* go back to where you were */
-			cio_seek(cio, orig_pos - 2);
-
-			/* re-read the marker */
-			id = cio_read(cio, 2);
-
-			/* check whether it begins with ff */
-			if (id >> 8 != 0xff) {
-				opj_event_msg(cinfo, EVT_ERROR,
-					"JPWL: possible bad marker %x at %d\n",
-					id, cio_tell(cio) - 2);
-				if (!JPWL_ASSUME) {
-					opj_image_destroy(image);
-					opj_event_msg(cinfo, EVT_ERROR, "JPWL: giving up\n");
-					return 0;
-				}
-				/* we try to correct */
-				id = id | 0xff00;
-				cio_seek(cio, cio_tell(cio) - 2);
-				cio_write(cio, id, 2);
-				opj_event_msg(cinfo, EVT_WARNING, "- trying to adjust this\n"
-					"- setting marker to %x\n",
-					id);
-			}
-
-		}
-#endif /* USE_JPWL */
-
-		if (id >> 8 != 0xff) {
-		if(cio_numbytesleft(cio) != 0) /* not end of file reached and no EOC */
-	   {
-		opj_event_msg(cinfo, EVT_ERROR, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id);
-		opj_image_destroy(image);
-		return 0;
-	   }
-		opj_event_msg(cinfo, EVT_WARNING, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id);
-		j2k->state = J2K_STATE_NEOC;
-		break;
-		}
-		e = j2k_dec_mstab_lookup(id);
-		/* Check if the marker is known*/
-		if (!(j2k->state & e->states)) {
-			opj_image_destroy(image);
-			opj_event_msg(cinfo, EVT_ERROR, "%.8x: unexpected marker %x\n", cio_tell(cio) - 2, id);
-			return 0;
-		}
-		/* Check if the decoding is limited to the main header*/
-		if (e->id == J2K_MS_SOT && j2k->cp->limit_decoding == LIMIT_TO_MAIN_HEADER) {
-			opj_event_msg(cinfo, EVT_INFO, "Main Header decoded.\n");
-			return image;
-		}		
-
-		if (e->handler) {
-			(*e->handler)(j2k);
-		}
-		if (j2k->state & J2K_STATE_ERR) 
-        {
-            opj_image_destroy(image);
-			return NULL;	
-        }
-
-		if (j2k->state == J2K_STATE_MT) {
-			break;
-		}
-		if (j2k->state == J2K_STATE_NEOC) {
-			break;
-		}
-	}
-	if (j2k->state == J2K_STATE_NEOC) {
-		j2k_read_eoc(j2k);
-	}
-
-	if (j2k->state != J2K_STATE_MT) {
-		opj_event_msg(cinfo, EVT_WARNING, "Incomplete bitstream\n");
-	}
-	return image;
-}
-
-/*
-* Read a JPT-stream and decode file
-*
-*/
-opj_image_t* j2k_decode_jpt_stream(opj_j2k_t *j2k, opj_cio_t *cio,  opj_codestream_info_t *cstr_info) {
-	opj_image_t *image = NULL;
-	opj_jpt_msg_header_t header;
-	int position;
-	opj_common_ptr cinfo = j2k->cinfo;
-
-	OPJ_ARG_NOT_USED(cstr_info);
-
-	j2k->cio = cio;
-
-	/* create an empty image */
-	image = opj_image_create0();
-	j2k->image = image;
-
-	j2k->state = J2K_STATE_MHSOC;
-	
-	/* Initialize the header */
-	jpt_init_msg_header(&header);
-	/* Read the first header of the message */
-	jpt_read_msg_header(cinfo, cio, &header);
-	
-	position = cio_tell(cio);
-	if (header.Class_Id != 6) {	/* 6 : Main header data-bin message */
-		opj_image_destroy(image);
-		opj_event_msg(cinfo, EVT_ERROR, "[JPT-stream] : Expecting Main header first [class_Id %d] !\n", header.Class_Id);
-		return 0;
-	}
-	
-	for (;;) {
-		opj_dec_mstabent_t *e = NULL;
-		int id;
-		
-		if (!cio_numbytesleft(cio)) {
-			j2k_read_eoc(j2k);
-			return image;
-		}
-		/* data-bin read -> need to read a new header */
-		if ((unsigned int) (cio_tell(cio) - position) == header.Msg_length) {
-			jpt_read_msg_header(cinfo, cio, &header);
-			position = cio_tell(cio);
-			if (header.Class_Id != 4) {	/* 4 : Tile data-bin message */
-				opj_image_destroy(image);
-				opj_event_msg(cinfo, EVT_ERROR, "[JPT-stream] : Expecting Tile info !\n");
-				return 0;
-			}
-		}
-		
-		id = cio_read(cio, 2);
-		if (id >> 8 != 0xff) {
-        if(cio_numbytesleft(cio) != 0) /* no end of file reached and no EOC */
-	  {
-		opj_event_msg(cinfo, EVT_ERROR, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id);
-		opj_image_destroy(image);
-		return 0;
-	  }
-		opj_event_msg(cinfo, EVT_WARNING, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id);
-		j2k->state = J2K_STATE_NEOC;
-		break;
-		}
-		e = j2k_dec_mstab_lookup(id);
-		if (!(j2k->state & e->states)) {
-			opj_image_destroy(image);
-			opj_event_msg(cinfo, EVT_ERROR, "%.8x: unexpected marker %x\n", cio_tell(cio) - 2, id);
-			return 0;
-		}
-		if (e->handler) {
-			(*e->handler)(j2k);
-		}
-		if (j2k->state == J2K_STATE_MT) {
-			break;
-		}
-		if (j2k->state == J2K_STATE_NEOC) {
-			break;
-		}
-	}
-	if (j2k->state == J2K_STATE_NEOC) {
-		j2k_read_eoc(j2k);
-	}
-	
-	if (j2k->state != J2K_STATE_MT) {
-		opj_event_msg(cinfo, EVT_WARNING, "Incomplete bitstream\n");
-	}
-
-	return image;
-}
-
-/* ----------------------------------------------------------------------- */
-/* J2K encoder interface                                                       */
-/* ----------------------------------------------------------------------- */
-
-opj_j2k_t* j2k_create_compress(opj_common_ptr cinfo) {
-	opj_j2k_t *j2k = (opj_j2k_t*) opj_calloc(1, sizeof(opj_j2k_t));
-	if(j2k) {
-		j2k->cinfo = cinfo;
-	}
-	return j2k;
-}
-
-void j2k_destroy_compress(opj_j2k_t *j2k) {
-	int tileno;
-
-	if(!j2k) return;
-	if(j2k->cp != NULL) {
-		opj_cp_t *cp = j2k->cp;
-
-		if(cp->comment) {
-			opj_free(cp->comment);
-		}
-		if(cp->matrice) {
-			opj_free(cp->matrice);
-		}
-		for (tileno = 0; tileno < cp->tw * cp->th; tileno++) {
-			opj_free(cp->tcps[tileno].tccps);
-		}
-		opj_free(cp->tcps);
-		opj_free(cp);
-	}
-
-	opj_free(j2k);
-}
-
-void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_t *image) {
-	int i, j, tileno, numpocs_tile;
-	opj_cp_t *cp = NULL;
-
-	if(!j2k || !parameters || ! image) {
-		return;
-	}
-
-	/* create and initialize the coding parameters structure */
-	cp = (opj_cp_t*) opj_calloc(1, sizeof(opj_cp_t));
-
-	/* keep a link to cp so that we can destroy it later in j2k_destroy_compress */
-	j2k->cp = cp;
-
-	/* set default values for cp */
-	cp->tw = 1;
-	cp->th = 1;
-
-	/* 
-	copy user encoding parameters 
-	*/
-	cp->cinema = parameters->cp_cinema;
-	cp->max_comp_size =	parameters->max_comp_size;
-	cp->rsiz   = parameters->cp_rsiz;
-	cp->disto_alloc = parameters->cp_disto_alloc;
-	cp->fixed_alloc = parameters->cp_fixed_alloc;
-	cp->fixed_quality = parameters->cp_fixed_quality;
-
-	/* mod fixed_quality */
-	if(parameters->cp_matrice) {
-		size_t array_size = parameters->tcp_numlayers * parameters->numresolution * 3 * sizeof(int);
-		cp->matrice = (int *) opj_malloc(array_size);
-		memcpy(cp->matrice, parameters->cp_matrice, array_size);
-	}
-
-	/* tiles */
-	cp->tdx = parameters->cp_tdx;
-	cp->tdy = parameters->cp_tdy;
-
-	/* tile offset */
-	cp->tx0 = parameters->cp_tx0;
-	cp->ty0 = parameters->cp_ty0;
-
-	/* comment string */
-	if(parameters->cp_comment) {
-		cp->comment = (char*)opj_malloc(strlen(parameters->cp_comment) + 1);
-		if(cp->comment) {
-			strcpy(cp->comment, parameters->cp_comment);
-		}
-	}
-
-	/*
-	calculate other encoding parameters
-	*/
-
-	if (parameters->tile_size_on) {
-		cp->tw = int_ceildiv(image->x1 - cp->tx0, cp->tdx);
-		cp->th = int_ceildiv(image->y1 - cp->ty0, cp->tdy);
-	} else {
-		cp->tdx = image->x1 - cp->tx0;
-		cp->tdy = image->y1 - cp->ty0;
-	}
-
-	if(parameters->tp_on){
-		cp->tp_flag = parameters->tp_flag;
-		cp->tp_on = 1;
-	}
-	
-	cp->img_size = 0;
-	for(i=0;i<image->numcomps ;i++){
-	cp->img_size += (image->comps[i].w *image->comps[i].h * image->comps[i].prec);
-	}
-
-
-#ifdef USE_JPWL
-	/*
-	calculate JPWL encoding parameters
-	*/
-
-	if (parameters->jpwl_epc_on) {
-		int i;
-
-		/* set JPWL on */
-		cp->epc_on = OPJ_TRUE;
-		cp->info_on = OPJ_FALSE; /* no informative technique */
-
-		/* set EPB on */
-		if ((parameters->jpwl_hprot_MH > 0) || (parameters->jpwl_hprot_TPH[0] > 0)) {
-			cp->epb_on = OPJ_TRUE;
-			
-			cp->hprot_MH = parameters->jpwl_hprot_MH;
-			for (i = 0; i < JPWL_MAX_NO_TILESPECS; i++) {
-				cp->hprot_TPH_tileno[i] = parameters->jpwl_hprot_TPH_tileno[i];
-				cp->hprot_TPH[i] = parameters->jpwl_hprot_TPH[i];
-			}
-			/* if tile specs are not specified, copy MH specs */
-			if (cp->hprot_TPH[0] == -1) {
-				cp->hprot_TPH_tileno[0] = 0;
-				cp->hprot_TPH[0] = parameters->jpwl_hprot_MH;
-			}
-			for (i = 0; i < JPWL_MAX_NO_PACKSPECS; i++) {
-				cp->pprot_tileno[i] = parameters->jpwl_pprot_tileno[i];
-				cp->pprot_packno[i] = parameters->jpwl_pprot_packno[i];
-				cp->pprot[i] = parameters->jpwl_pprot[i];
-			}
-		}
-
-		/* set ESD writing */
-		if ((parameters->jpwl_sens_size == 1) || (parameters->jpwl_sens_size == 2)) {
-			cp->esd_on = OPJ_TRUE;
-
-			cp->sens_size = parameters->jpwl_sens_size;
-			cp->sens_addr = parameters->jpwl_sens_addr;
-			cp->sens_range = parameters->jpwl_sens_range;
-
-			cp->sens_MH = parameters->jpwl_sens_MH;
-			for (i = 0; i < JPWL_MAX_NO_TILESPECS; i++) {
-				cp->sens_TPH_tileno[i] = parameters->jpwl_sens_TPH_tileno[i];
-				cp->sens_TPH[i] = parameters->jpwl_sens_TPH[i];
-			}
-		}
-
-		/* always set RED writing to false: we are at the encoder */
-		cp->red_on = OPJ_FALSE;
-
-	} else {
-		cp->epc_on = OPJ_FALSE;
-	}
-#endif /* USE_JPWL */
-
-
-	/* initialize the mutiple tiles */
-	/* ---------------------------- */
-	cp->tcps = (opj_tcp_t*) opj_calloc(cp->tw * cp->th, sizeof(opj_tcp_t));
-
-	for (tileno = 0; tileno < cp->tw * cp->th; tileno++) {
-		opj_tcp_t *tcp = &cp->tcps[tileno];
-		tcp->numlayers = parameters->tcp_numlayers;
-		for (j = 0; j < tcp->numlayers; j++) {
-			if(cp->cinema){
-				if (cp->fixed_quality) {
-					tcp->distoratio[j] = parameters->tcp_distoratio[j];
-				}
-				tcp->rates[j] = parameters->tcp_rates[j];
-			}else{
-				if (cp->fixed_quality) {	/* add fixed_quality */
-					tcp->distoratio[j] = parameters->tcp_distoratio[j];
-				} else {
-					tcp->rates[j] = parameters->tcp_rates[j];
-				}
-			}
-		}
-		tcp->csty = parameters->csty;
-		tcp->prg = parameters->prog_order;
-		tcp->mct = parameters->tcp_mct; 
-
-		numpocs_tile = 0;
-		tcp->POC = 0;
-		if (parameters->numpocs) {
-			/* initialisation of POC */
-			tcp->POC = 1;
-			for (i = 0; i < parameters->numpocs; i++) {
-				if((tileno == parameters->POC[i].tile - 1) || (parameters->POC[i].tile == -1)) {
-					opj_poc_t *tcp_poc = &tcp->pocs[numpocs_tile];
-					tcp_poc->resno0		= parameters->POC[numpocs_tile].resno0;
-					tcp_poc->compno0	= parameters->POC[numpocs_tile].compno0;
-					tcp_poc->layno1		= parameters->POC[numpocs_tile].layno1;
-					tcp_poc->resno1		= parameters->POC[numpocs_tile].resno1;
-					tcp_poc->compno1	= parameters->POC[numpocs_tile].compno1;
-					tcp_poc->prg1		= parameters->POC[numpocs_tile].prg1;
-					tcp_poc->tile		= parameters->POC[numpocs_tile].tile;
-					numpocs_tile++;
-				}
-			}
-			tcp->numpocs = numpocs_tile -1 ;
-		}else{ 
-			tcp->numpocs = 0;
-		}
-
-		tcp->tccps = (opj_tccp_t*) opj_calloc(image->numcomps, sizeof(opj_tccp_t));
-
-		for (i = 0; i < image->numcomps; i++) {
-			opj_tccp_t *tccp = &tcp->tccps[i];
-			tccp->csty = parameters->csty & 0x01;	/* 0 => one precinct || 1 => custom precinct  */
-			tccp->numresolutions = parameters->numresolution;
-			tccp->cblkw = int_floorlog2(parameters->cblockw_init);
-			tccp->cblkh = int_floorlog2(parameters->cblockh_init);
-			tccp->cblksty = parameters->mode;
-			tccp->qmfbid = parameters->irreversible ? 0 : 1;
-			tccp->qntsty = parameters->irreversible ? J2K_CCP_QNTSTY_SEQNT : J2K_CCP_QNTSTY_NOQNT;
-			tccp->numgbits = 2;
-			if (i == parameters->roi_compno) {
-				tccp->roishift = parameters->roi_shift;
-			} else {
-				tccp->roishift = 0;
-			}
-
-			if(parameters->cp_cinema)
-			{
-				/*Precinct size for lowest frequency subband=128*/
-				tccp->prcw[0] = 7;
-				tccp->prch[0] = 7;
-				/*Precinct size at all other resolutions = 256*/
-				for (j = 1; j < tccp->numresolutions; j++) {
-					tccp->prcw[j] = 8;
-					tccp->prch[j] = 8;
-				}
-			}else{
-				if (parameters->csty & J2K_CCP_CSTY_PRT) {
-					int p = 0;
-					for (j = tccp->numresolutions - 1; j >= 0; j--) {
-						if (p < parameters->res_spec) {
-							
-							if (parameters->prcw_init[p] < 1) {
-								tccp->prcw[j] = 1;
-							} else {
-								tccp->prcw[j] = int_floorlog2(parameters->prcw_init[p]);
-							}
-							
-							if (parameters->prch_init[p] < 1) {
-								tccp->prch[j] = 1;
-							}else {
-								tccp->prch[j] = int_floorlog2(parameters->prch_init[p]);
-							}
-
-						} else {
-							int res_spec = parameters->res_spec;
-							int size_prcw = parameters->prcw_init[res_spec - 1] >> (p - (res_spec - 1));
-							int size_prch = parameters->prch_init[res_spec - 1] >> (p - (res_spec - 1));
-							
-							if (size_prcw < 1) {
-								tccp->prcw[j] = 1;
-							} else {
-								tccp->prcw[j] = int_floorlog2(size_prcw);
-							}
-							
-							if (size_prch < 1) {
-								tccp->prch[j] = 1;
-							} else {
-								tccp->prch[j] = int_floorlog2(size_prch);
-							}
-						}
-						p++;
-						/*printf("\nsize precinct for level %d : %d,%d\n", j,tccp->prcw[j], tccp->prch[j]); */
-					}	/*end for*/
-				} else {
-					for (j = 0; j < tccp->numresolutions; j++) {
-						tccp->prcw[j] = 15;
-						tccp->prch[j] = 15;
-					}
-				}
-			}
-
-			dwt_calc_explicit_stepsizes(tccp, image->comps[i].prec);
-		}
-	}
-}
-
-opj_bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) {
-	int tileno, compno;
-	opj_cp_t *cp = NULL;
-
-	opj_tcd_t *tcd = NULL;	/* TCD component */
-
-	j2k->cio = cio;	
-	j2k->image = image;
-
-	cp = j2k->cp;
-
-	/* INDEX >> */
-	j2k->cstr_info = cstr_info;
-	if (cstr_info) {
-		int compno;
-		cstr_info->tile = (opj_tile_info_t *) opj_malloc(cp->tw * cp->th * sizeof(opj_tile_info_t));
-		cstr_info->image_w = image->x1 - image->x0;
-		cstr_info->image_h = image->y1 - image->y0;
-		cstr_info->prog = (&cp->tcps[0])->prg;
-		cstr_info->tw = cp->tw;
-		cstr_info->th = cp->th;
-		cstr_info->tile_x = cp->tdx;	/* new version parser */
-		cstr_info->tile_y = cp->tdy;	/* new version parser */
-		cstr_info->tile_Ox = cp->tx0;	/* new version parser */
-		cstr_info->tile_Oy = cp->ty0;	/* new version parser */
-		cstr_info->numcomps = image->numcomps;
-		cstr_info->numlayers = (&cp->tcps[0])->numlayers;
-		cstr_info->numdecompos = (int*) opj_malloc(image->numcomps * sizeof(int));
-		for (compno=0; compno < image->numcomps; compno++) {
-			cstr_info->numdecompos[compno] = (&cp->tcps[0])->tccps->numresolutions - 1;
-		}
-		cstr_info->D_max = 0.0;		/* ADD Marcela */
-		cstr_info->main_head_start = cio_tell(cio); /* position of SOC */
-		cstr_info->maxmarknum = 100;
-		cstr_info->marker = (opj_marker_info_t *) opj_malloc(cstr_info->maxmarknum * sizeof(opj_marker_info_t));
-		cstr_info->marknum = 0;
-	}
-	/* << INDEX */
-
-	j2k_write_soc(j2k);
-	j2k_write_siz(j2k);
-	j2k_write_cod(j2k);
-	j2k_write_qcd(j2k);
-
-	if(cp->cinema){
-		for (compno = 1; compno < image->numcomps; compno++) {
-			j2k_write_coc(j2k, compno);
-			j2k_write_qcc(j2k, compno);
-		}
-	}
-
-	for (compno = 0; compno < image->numcomps; compno++) {
-		opj_tcp_t *tcp = &cp->tcps[0];
-		if (tcp->tccps[compno].roishift)
-			j2k_write_rgn(j2k, compno, 0);
-	}
-	if (cp->comment != NULL) {
-		j2k_write_com(j2k);
-	}
-
-	j2k->totnum_tp = j2k_calculate_tp(cp,image->numcomps,image,j2k);
-	/* TLM Marker*/
-	if(cp->cinema){
-		j2k_write_tlm(j2k);
-		if (cp->cinema == CINEMA4K_24) {
-			j2k_write_poc(j2k);
-		}
-	}
-
-	/* uncomment only for testing JPSEC marker writing */
-	/* j2k_write_sec(j2k); */
-
-	/* INDEX >> */
-	if(cstr_info) {
-		cstr_info->main_head_end = cio_tell(cio) - 1;
-	}
-	/* << INDEX */
-	/**** Main Header ENDS here ***/
-
-	/* create the tile encoder */
-	tcd = tcd_create(j2k->cinfo);
-
-	/* encode each tile */
-	for (tileno = 0; tileno < cp->tw * cp->th; tileno++) {
-		int pino;
-		int tilepartno=0;
-		/* UniPG>> */
-		int acc_pack_num = 0;
-		/* <<UniPG */
-
-
-		opj_tcp_t *tcp = &cp->tcps[tileno];
-		opj_event_msg(j2k->cinfo, EVT_INFO, "tile number %d / %d\n", tileno + 1, cp->tw * cp->th);
-
-		j2k->curtileno = tileno;
-		j2k->cur_tp_num = 0;
-		tcd->cur_totnum_tp = j2k->cur_totnum_tp[j2k->curtileno];
-		/* initialisation before tile encoding  */
-		if (tileno == 0) {
-			tcd_malloc_encode(tcd, image, cp, j2k->curtileno);
-		} else {
-			tcd_init_encode(tcd, image, cp, j2k->curtileno);
-		}
-
-		/* INDEX >> */
-		if(cstr_info) {
-			cstr_info->tile[j2k->curtileno].start_pos = cio_tell(cio) + j2k->pos_correction;
-			cstr_info->tile[j2k->curtileno].maxmarknum = 10;
-			cstr_info->tile[j2k->curtileno].marker = (opj_marker_info_t *) opj_malloc(cstr_info->tile[j2k->curtileno].maxmarknum * sizeof(opj_marker_info_t));
-			cstr_info->tile[j2k->curtileno].marknum = 0;
-		}
-		/* << INDEX */
-
-		for(pino = 0; pino <= tcp->numpocs; pino++) {
-			int tot_num_tp;
-			tcd->cur_pino=pino;
-
-			/*Get number of tile parts*/
-			tot_num_tp = j2k_get_num_tp(cp,pino,tileno);
-			tcd->tp_pos = cp->tp_pos;
-
-			for(tilepartno = 0; tilepartno < tot_num_tp ; tilepartno++){
-				j2k->tp_num = tilepartno;
-				/* INDEX >> */
-				if(cstr_info)
-					cstr_info->tile[j2k->curtileno].tp[j2k->cur_tp_num].tp_start_pos =
-					cio_tell(cio) + j2k->pos_correction;
-				/* << INDEX */
-				j2k_write_sot(j2k);
-
-				if(j2k->cur_tp_num == 0 && cp->cinema == 0){
-					for (compno = 1; compno < image->numcomps; compno++) {
-						j2k_write_coc(j2k, compno);
-						j2k_write_qcc(j2k, compno);
-					}
-					if (cp->tcps[tileno].numpocs) {
-						j2k_write_poc(j2k);
-					}
-				}
-
-				/* INDEX >> */
-				if(cstr_info)
-					cstr_info->tile[j2k->curtileno].tp[j2k->cur_tp_num].tp_end_header =
-					cio_tell(cio) + j2k->pos_correction + 1;
-				/* << INDEX */
-
-				j2k_write_sod(j2k, tcd);
-
-				/* INDEX >> */
-				if(cstr_info) {
-					cstr_info->tile[j2k->curtileno].tp[j2k->cur_tp_num].tp_end_pos =
-						cio_tell(cio) + j2k->pos_correction - 1;
-					cstr_info->tile[j2k->curtileno].tp[j2k->cur_tp_num].tp_start_pack =
-						acc_pack_num;
-					cstr_info->tile[j2k->curtileno].tp[j2k->cur_tp_num].tp_numpacks =
-						cstr_info->packno - acc_pack_num;
-					acc_pack_num = cstr_info->packno;
-				}
-				/* << INDEX */
-
-				j2k->cur_tp_num++;
-			}			
-		}
-		if(cstr_info) {
-			cstr_info->tile[j2k->curtileno].end_pos = cio_tell(cio) + j2k->pos_correction - 1;
-		}
-
-
-		/*
-		if (tile->PPT) { // BAD PPT !!! 
-		FILE *PPT_file;
-		int i;
-		PPT_file=fopen("PPT","rb");
-		fprintf(stderr,"%c%c%c%c",255,97,tile->len_ppt/256,tile->len_ppt%256);
-		for (i=0;i<tile->len_ppt;i++) {
-		unsigned char elmt;
-		fread(&elmt, 1, 1, PPT_file);
-		fwrite(&elmt,1,1,f);
-		}
-		fclose(PPT_file);
-		unlink("PPT");
-		}
-		*/
-
-	}
-
-	/* destroy the tile encoder */
-	tcd_free_encode(tcd);
-	tcd_destroy(tcd);
-
-	opj_free(j2k->cur_totnum_tp);
-
-	j2k_write_eoc(j2k);
-
-	if(cstr_info) {
-		cstr_info->codestream_size = cio_tell(cio) + j2k->pos_correction;
-		/* UniPG>> */
-		/* The following adjustment is done to adjust the codestream size */
-		/* if SOD is not at 0 in the buffer. Useful in case of JP2, where */
-		/* the first bunch of bytes is not in the codestream              */
-		cstr_info->codestream_size -= cstr_info->main_head_start;
-		/* <<UniPG */
-	}
-
-#ifdef USE_JPWL
-	/*
-	preparation of JPWL marker segments
-	*/
-	if(cp->epc_on) {
-
-		/* encode according to JPWL */
-		jpwl_encode(j2k, cio, image);
-
-	}
-#endif /* USE_JPWL */
-
-	return OPJ_TRUE;
-}
-
-static void j2k_add_mhmarker(opj_codestream_info_t *cstr_info, unsigned short int type, int pos, int len) {
-
-	if (!cstr_info)
-		return;
-
-	/* expand the list? */
-	if ((cstr_info->marknum + 1) > cstr_info->maxmarknum) {
-		cstr_info->maxmarknum = 100 + (int) ((float) cstr_info->maxmarknum * 1.0F);
-		cstr_info->marker = (opj_marker_info_t*)opj_realloc(cstr_info->marker, cstr_info->maxmarknum);
-	}
-
-	/* add the marker */
-	cstr_info->marker[cstr_info->marknum].type = type;
-	cstr_info->marker[cstr_info->marknum].pos = pos;
-	cstr_info->marker[cstr_info->marknum].len = len;
-	cstr_info->marknum++;
-
-}
-
-static void j2k_add_tlmarker( int tileno, opj_codestream_info_t *cstr_info, unsigned short int type, int pos, int len) {
-
-  opj_marker_info_t *marker;
-
-	if (!cstr_info)
-		return;
-
-	/* expand the list? */
-	if ((cstr_info->tile[tileno].marknum + 1) > cstr_info->tile[tileno].maxmarknum) {
-		cstr_info->tile[tileno].maxmarknum = 100 + (int) ((float) cstr_info->tile[tileno].maxmarknum * 1.0F);
-		cstr_info->tile[tileno].marker = (opj_marker_info_t*)opj_realloc(cstr_info->tile[tileno].marker, cstr_info->maxmarknum);
-	}
-
-	marker = &(cstr_info->tile[tileno].marker[cstr_info->tile[tileno].marknum]);
-
-	/* add the marker */
-	marker->type = type;
-	marker->pos = pos;
-	marker->len = len;
-	cstr_info->tile[tileno].marknum++;
-}
+/*
+ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2007, Professor Benoit Macq
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2008, Jerome Fimes, Communications & Systemes <jerome.fimes at c-s.fr>
+ * Copyright (c) 2006-2007, Parvatha Elangovan
+ * Copyright (c) 2010-2011, Kaori Hagihara
+ * Copyright (c) 2011-2012, Centre National d'Etudes Spatiales (CNES), France 
+ * Copyright (c) 2012, CS Systemes d'Information, France
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "opj_includes.h"
+
+#define CINEMA_24_CS 1302083	/*Codestream length for 24fps*/
+#define CINEMA_48_CS 651041		/*Codestream length for 48fps*/
+#define COMP_24_CS 1041666		/*Maximum size per color component for 2K & 4K @ 24fps*/
+#define COMP_48_CS 520833		/*Maximum size per color component for 2K @ 48fps*/
+
+/** @defgroup J2K J2K - JPEG-2000 codestream reader/writer */
+/*@{*/
+
+/** @name Local static functions */
+/*@{*/
+
+/**
+ * Sets up the procedures to do on reading header. Developpers wanting to extend the library can add their own reading procedures.
+ */
+static void opj_j2k_setup_header_reading (opj_j2k_t *p_j2k);
+
+/**
+ * The read header procedure.
+ */
+static OPJ_BOOL opj_j2k_read_header_procedure(  opj_j2k_t *p_j2k,
+                                                opj_stream_private_t *p_stream,
+                                                opj_event_mgr_t * p_manager);
+
+/**
+ * The default encoding validation procedure without any extension.
+ *
+ * @param       p_j2k                   the jpeg2000 codec to validate.
+ * @param       p_stream                the input stream to validate.
+ * @param       p_manager               the user event manager.
+ *
+ * @return true if the parameters are correct.
+ */
+static OPJ_BOOL opj_j2k_encoding_validation (   opj_j2k_t * p_j2k,
+                                                opj_stream_private_t *p_stream,
+                                                opj_event_mgr_t * p_manager );
+
+/**
+ * The default decoding validation procedure without any extension.
+ *
+ * @param       p_j2k                   the jpeg2000 codec to validate.
+ * @param       p_stream                                the input stream to validate.
+ * @param       p_manager               the user event manager.
+ *
+ * @return true if the parameters are correct.
+ */
+static OPJ_BOOL opj_j2k_decoding_validation (   opj_j2k_t * p_j2k,
+                                                opj_stream_private_t *p_stream,
+                                                opj_event_mgr_t * p_manager );
+
+/**
+ * Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters
+ * are valid. Developpers wanting to extend the library can add their own validation procedures.
+ */
+static void opj_j2k_setup_encoding_validation (opj_j2k_t *p_j2k);
+
+/**
+ * Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters
+ * are valid. Developpers wanting to extend the library can add their own validation procedures.
+ */
+static void opj_j2k_setup_decoding_validation (opj_j2k_t *p_j2k);
+
+/**
+ * Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters
+ * are valid. Developpers wanting to extend the library can add their own validation procedures.
+ */
+static void opj_j2k_setup_end_compress (opj_j2k_t *p_j2k);
+
+/**
+ * The mct encoding validation procedure.
+ *
+ * @param       p_j2k                   the jpeg2000 codec to validate.
+ * @param       p_stream                                the input stream to validate.
+ * @param       p_manager               the user event manager.
+ *
+ * @return true if the parameters are correct.
+ */
+static OPJ_BOOL opj_j2k_mct_validation (opj_j2k_t * p_j2k,
+                                        opj_stream_private_t *p_stream,
+                                        opj_event_mgr_t * p_manager );
+
+/**
+ * Builds the tcd decoder to use to decode tile.
+ */
+static OPJ_BOOL opj_j2k_build_decoder ( opj_j2k_t * p_j2k,
+                                        opj_stream_private_t *p_stream,
+                                        opj_event_mgr_t * p_manager );
+/**
+ * Builds the tcd encoder to use to encode tile.
+ */
+static OPJ_BOOL opj_j2k_build_encoder ( opj_j2k_t * p_j2k,
+                                        opj_stream_private_t *p_stream,
+                                        opj_event_mgr_t * p_manager );
+
+/**
+ * Creates a tile-coder decoder.
+ *
+ * @param       p_stream                        the stream to write data to.
+ * @param       p_j2k                           J2K codec.
+ * @param       p_manager                   the user event manager.
+*/
+static OPJ_BOOL opj_j2k_create_tcd(     opj_j2k_t *p_j2k,
+                                                                    opj_stream_private_t *p_stream,
+                                                                    opj_event_mgr_t * p_manager );
+
+/**
+ * Excutes the given procedures on the given codec.
+ *
+ * @param       p_procedure_list        the list of procedures to execute
+ * @param       p_j2k                           the jpeg2000 codec to execute the procedures on.
+ * @param       p_stream                        the stream to execute the procedures on.
+ * @param       p_manager                       the user manager.
+ *
+ * @return      true                            if all the procedures were successfully executed.
+ */
+static OPJ_BOOL opj_j2k_exec (  opj_j2k_t * p_j2k,
+                            opj_procedure_list_t * p_procedure_list,
+                            opj_stream_private_t *p_stream,
+                            opj_event_mgr_t * p_manager);
+
+/**
+ * Updates the rates of the tcp.
+ *
+ * @param       p_stream                                the stream to write data to.
+ * @param       p_j2k                           J2K codec.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_update_rates(   opj_j2k_t *p_j2k,
+                                                                            opj_stream_private_t *p_stream,
+                                                                            opj_event_mgr_t * p_manager );
+
+/**
+ * Copies the decoding tile parameters onto all the tile parameters.
+ * Creates also the tile decoder.
+ */
+static OPJ_BOOL opj_j2k_copy_default_tcp_and_create_tcd (       opj_j2k_t * p_j2k,
+                                                            opj_stream_private_t *p_stream,
+                                                            opj_event_mgr_t * p_manager );
+
+/**
+ * Destroys the memory associated with the decoding of headers.
+ */
+static OPJ_BOOL opj_j2k_destroy_header_memory ( opj_j2k_t * p_j2k,
+                                                opj_stream_private_t *p_stream,
+                                                opj_event_mgr_t * p_manager );
+
+/**
+ * Reads the lookup table containing all the marker, status and action, and returns the handler associated
+ * with the marker value.
+ * @param       p_id            Marker value to look up
+ *
+ * @return      the handler associated with the id.
+*/
+static const struct opj_dec_memory_marker_handler * opj_j2k_get_marker_handler (OPJ_UINT32 p_id);
+
+/**
+ * Destroys a tile coding parameter structure.
+ *
+ * @param       p_tcp           the tile coding parameter to destroy.
+ */
+static void opj_j2k_tcp_destroy (opj_tcp_t *p_tcp);
+
+/**
+ * Destroys the data inside a tile coding parameter structure.
+ *
+ * @param       p_tcp           the tile coding parameter which contain data to destroy.
+ */
+static void opj_j2k_tcp_data_destroy (opj_tcp_t *p_tcp);
+
+/**
+ * Destroys a coding parameter structure.
+ *
+ * @param       p_cp            the coding parameter to destroy.
+ */
+static void opj_j2k_cp_destroy (opj_cp_t *p_cp);
+
+/**
+ * Writes a SPCod or SPCoc element, i.e. the coding style of a given component of a tile.
+ *
+ * @param       p_j2k           J2K codec.
+ * @param       p_tile_no       FIXME DOC
+ * @param       p_comp_no       the component number to output.
+ * @param       p_data          FIXME DOC
+ * @param       p_header_size   FIXME DOC
+ * @param       p_manager       the user event manager.
+ *
+ * @return FIXME DOC
+*/
+static OPJ_BOOL opj_j2k_write_SPCod_SPCoc(      opj_j2k_t *p_j2k,
+                                                                                    OPJ_UINT32 p_tile_no,
+                                                                                    OPJ_UINT32 p_comp_no,
+                                                                                    OPJ_BYTE * p_data,
+                                                                                    OPJ_UINT32 * p_header_size,
+                                                                                    opj_event_mgr_t * p_manager );
+
+/**
+ * Gets the size taken by writing a SPCod or SPCoc for the given tile and component.
+ *
+ * @param       p_j2k                   the J2K codec.
+ * @param       p_tile_no               the tile index.
+ * @param       p_comp_no               the component being outputted.
+ *
+ * @return      the number of bytes taken by the SPCod element.
+ */
+static OPJ_UINT32 opj_j2k_get_SPCod_SPCoc_size (opj_j2k_t *p_j2k,
+                                                                                            OPJ_UINT32 p_tile_no,
+                                                                                            OPJ_UINT32 p_comp_no );
+
+/**
+ * Reads a SPCod or SPCoc element, i.e. the coding style of a given component of a tile.
+ * @param       p_j2k           the jpeg2000 codec.
+ * @param       compno          FIXME DOC
+ * @param       p_header_data   the data contained in the COM box.
+ * @param       p_header_size   the size of the data contained in the COM marker.
+ * @param       p_manager       the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_SPCod_SPCoc(   opj_j2k_t *p_j2k,
+                                            OPJ_UINT32 compno,
+                                            OPJ_BYTE * p_header_data,
+                                            OPJ_UINT32 * p_header_size,
+                                            opj_event_mgr_t * p_manager );
+
+/**
+ * Gets the size taken by writing SQcd or SQcc element, i.e. the quantization values of a band in the QCD or QCC.
+ *
+ * @param       p_tile_no               the tile index.
+ * @param       p_comp_no               the component being outputted.
+ * @param       p_j2k                   the J2K codec.
+ *
+ * @return      the number of bytes taken by the SPCod element.
+ */
+static OPJ_UINT32 opj_j2k_get_SQcd_SQcc_size (  opj_j2k_t *p_j2k,
+                                                                                    OPJ_UINT32 p_tile_no,
+                                                                                    OPJ_UINT32 p_comp_no );
+
+/**
+ * Writes a SQcd or SQcc element, i.e. the quantization values of a band in the QCD or QCC.
+ *
+ * @param       p_tile_no               the tile to output.
+ * @param       p_comp_no               the component number to output.
+ * @param       p_data                  the data buffer.
+ * @param       p_header_size   pointer to the size of the data buffer, it is changed by the function.
+ * @param       p_j2k                   J2K codec.
+ * @param       p_manager               the user event manager.
+ *
+*/
+static OPJ_BOOL opj_j2k_write_SQcd_SQcc(opj_j2k_t *p_j2k,
+                                                                            OPJ_UINT32 p_tile_no,
+                                                                            OPJ_UINT32 p_comp_no,
+                                                                            OPJ_BYTE * p_data,
+                                                                            OPJ_UINT32 * p_header_size,
+                                                                            opj_event_mgr_t * p_manager);
+
+/**
+ * Updates the Tile Length Marker.
+ */
+static void opj_j2k_update_tlm ( opj_j2k_t * p_j2k, OPJ_UINT32 p_tile_part_size);
+
+/**
+ * Reads a SQcd or SQcc element, i.e. the quantization values of a band in the QCD or QCC.
+ *
+ * @param       p_j2k           J2K codec.
+ * @param       compno          the component number to output.
+ * @param       p_header_data   the data buffer.
+ * @param       p_header_size   pointer to the size of the data buffer, it is changed by the function.
+ * @param       p_manager       the user event manager.
+ *
+*/
+static OPJ_BOOL opj_j2k_read_SQcd_SQcc( opj_j2k_t *p_j2k,
+                                        OPJ_UINT32 compno,
+                                        OPJ_BYTE * p_header_data,
+                                        OPJ_UINT32 * p_header_size,
+                                        opj_event_mgr_t * p_manager );
+
+/**
+ * Copies the tile component parameters of all the component from the first tile component.
+ *
+ * @param               p_j2k           the J2k codec.
+ */
+static void opj_j2k_copy_tile_component_parameters( opj_j2k_t *p_j2k );
+
+/**
+ * Copies the tile quantization parameters of all the component from the first tile component.
+ *
+ * @param               p_j2k           the J2k codec.
+ */
+static void opj_j2k_copy_tile_quantization_parameters( opj_j2k_t *p_j2k );
+
+/**
+ * Reads the tiles.
+ */
+static OPJ_BOOL opj_j2k_decode_tiles (  opj_j2k_t *p_j2k,
+                                        opj_stream_private_t *p_stream,
+                                        opj_event_mgr_t * p_manager);
+
+static OPJ_BOOL opj_j2k_pre_write_tile ( opj_j2k_t * p_j2k,
+                                                                             OPJ_UINT32 p_tile_index,
+                                                                             opj_stream_private_t *p_stream,
+                                                                             opj_event_mgr_t * p_manager );
+
+static OPJ_BOOL opj_j2k_update_image_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data, opj_image_t* p_output_image);
+
+static void opj_j2k_get_tile_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data);
+
+static OPJ_BOOL opj_j2k_post_write_tile (opj_j2k_t * p_j2k,
+                                                                             OPJ_BYTE * p_data,
+                                                                             OPJ_UINT32 p_data_size,
+                                                                             opj_stream_private_t *p_stream,
+                                                                             opj_event_mgr_t * p_manager );
+
+/**
+ * Sets up the procedures to do on writing header.
+ * Developers wanting to extend the library can add their own writing procedures.
+ */
+static void opj_j2k_setup_header_writing (opj_j2k_t *p_j2k);
+
+static OPJ_BOOL opj_j2k_write_first_tile_part(  opj_j2k_t *p_j2k,
+                                                                                            OPJ_BYTE * p_data,
+                                                                                            OPJ_UINT32 * p_data_written,
+                                                                                            OPJ_UINT32 p_total_data_size,
+                                                                                            opj_stream_private_t *p_stream,
+                                                                                            struct opj_event_mgr * p_manager );
+
+static OPJ_BOOL opj_j2k_write_all_tile_parts(   opj_j2k_t *p_j2k,
+                                                                                            OPJ_BYTE * p_data,
+                                                                                            OPJ_UINT32 * p_data_written,
+                                                                                            OPJ_UINT32 p_total_data_size,
+                                                                                            opj_stream_private_t *p_stream,
+                                                                                            struct opj_event_mgr * p_manager );
+
+/**
+ * Gets the offset of the header.
+ *
+ * @param       p_stream                the stream to write data to.
+ * @param       p_j2k                   J2K codec.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_get_end_header( opj_j2k_t *p_j2k,
+                                        opj_stream_private_t *p_stream,
+                                        opj_event_mgr_t * p_manager );
+
+static OPJ_BOOL opj_j2k_allocate_tile_element_cstr_index(opj_j2k_t *p_j2k);
+
+/*
+ * -----------------------------------------------------------------------
+ * -----------------------------------------------------------------------
+ * -----------------------------------------------------------------------
+ */
+
+/**
+ * Writes the SOC marker (Start Of Codestream)
+ *
+ * @param       p_stream                        the stream to write data to.
+ * @param       p_j2k                   J2K codec.
+ * @param       p_manager       the user event manager.
+*/
+static OPJ_BOOL opj_j2k_write_soc(      opj_j2k_t *p_j2k,
+                                                        opj_stream_private_t *p_stream,
+                                                            opj_event_mgr_t * p_manager );
+
+/**
+ * Reads a SOC marker (Start of Codestream)
+ * @param       p_j2k           the jpeg2000 file codec.
+ * @param       p_stream        XXX needs data
+ * @param       p_manager       the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_soc(   opj_j2k_t *p_j2k,
+                                    opj_stream_private_t *p_stream,
+                                    opj_event_mgr_t * p_manager );
+
+/**
+ * Writes the SIZ marker (image and tile size)
+ *
+ * @param       p_j2k           J2K codec.
+ * @param       p_stream        the stream to write data to.
+ * @param       p_manager       the user event manager.
+*/
+static OPJ_BOOL opj_j2k_write_siz(      opj_j2k_t *p_j2k,
+                                                                opj_stream_private_t *p_stream,
+                                                                opj_event_mgr_t * p_manager );
+
+/**
+ * Reads a SIZ marker (image and tile size)
+ * @param       p_j2k           the jpeg2000 file codec.
+ * @param       p_header_data   the data contained in the SIZ box.
+ * @param       p_header_size   the size of the data contained in the SIZ marker.
+ * @param       p_manager       the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_siz(opj_j2k_t *p_j2k,
+                                 OPJ_BYTE * p_header_data,
+                                 OPJ_UINT32 p_header_size,
+                                 opj_event_mgr_t * p_manager);
+
+/**
+ * Writes the COM marker (comment)
+ *
+ * @param       p_stream                        the stream to write data to.
+ * @param       p_j2k                   J2K codec.
+ * @param       p_manager       the user event manager.
+*/
+static OPJ_BOOL opj_j2k_write_com(      opj_j2k_t *p_j2k,
+                                                                        opj_stream_private_t *p_stream,
+                                                                        opj_event_mgr_t * p_manager );
+
+/**
+ * Reads a COM marker (comments)
+ * @param       p_j2k           the jpeg2000 file codec.
+ * @param       p_header_data   the data contained in the COM box.
+ * @param       p_header_size   the size of the data contained in the COM marker.
+ * @param       p_manager       the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_com (  opj_j2k_t *p_j2k,
+                                    OPJ_BYTE * p_header_data,
+                                    OPJ_UINT32 p_header_size,
+                                    opj_event_mgr_t * p_manager );
+/**
+ * Writes the COD marker (Coding style default)
+ *
+ * @param       p_stream                        the stream to write data to.
+ * @param       p_j2k                   J2K codec.
+ * @param       p_manager       the user event manager.
+*/
+static OPJ_BOOL opj_j2k_write_cod(      opj_j2k_t *p_j2k,
+                                                                        opj_stream_private_t *p_stream,
+                                                                        opj_event_mgr_t * p_manager );
+
+/**
+ * Reads a COD marker (Coding Styke defaults)
+ * @param       p_header_data   the data contained in the COD box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the COD marker.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_cod (  opj_j2k_t *p_j2k,
+                                    OPJ_BYTE * p_header_data,
+                                    OPJ_UINT32 p_header_size,
+                                    opj_event_mgr_t * p_manager);
+
+#if 0
+/**
+ * Writes the COC marker (Coding style component)
+ *
+ * @param       p_j2k       J2K codec.
+ * @param       p_comp_no   the index of the component to output.
+ * @param       p_stream    the stream to write data to.
+ * @param       p_manager   the user event manager.
+*/
+static OPJ_BOOL opj_j2k_write_coc(  opj_j2k_t *p_j2k,
+                                                                OPJ_UINT32 p_comp_no,
+                                                                opj_stream_private_t *p_stream,
+                                                                opj_event_mgr_t * p_manager );
+#endif
+
+#if 0
+/**
+ * Writes the COC marker (Coding style component)
+ *
+ * @param       p_j2k                   J2K codec.
+ * @param       p_comp_no               the index of the component to output.
+ * @param       p_data          FIXME DOC
+ * @param       p_data_written  FIXME DOC
+ * @param       p_manager               the user event manager.
+*/
+static void opj_j2k_write_coc_in_memory(opj_j2k_t *p_j2k,
+                                                                            OPJ_UINT32 p_comp_no,
+                                                                            OPJ_BYTE * p_data,
+                                                                            OPJ_UINT32 * p_data_written,
+                                                                            opj_event_mgr_t * p_manager );
+#endif
+
+/**
+ * Gets the maximum size taken by a coc.
+ *
+ * @param       p_j2k   the jpeg2000 codec to use.
+ */
+static OPJ_UINT32 opj_j2k_get_max_coc_size(opj_j2k_t *p_j2k);
+
+/**
+ * Reads a COC marker (Coding Style Component)
+ * @param       p_header_data   the data contained in the COC box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the COC marker.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_coc (  opj_j2k_t *p_j2k,
+                                    OPJ_BYTE * p_header_data,
+                                    OPJ_UINT32 p_header_size,
+                                    opj_event_mgr_t * p_manager );
+
+/**
+ * Writes the QCD marker (quantization default)
+ *
+ * @param       p_j2k                   J2K codec.
+ * @param       p_stream                the stream to write data to.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_write_qcd(      opj_j2k_t *p_j2k,
+                                                                        opj_stream_private_t *p_stream,
+                                                                        opj_event_mgr_t * p_manager );
+
+/**
+ * Reads a QCD marker (Quantization defaults)
+ * @param       p_header_data   the data contained in the QCD box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the QCD marker.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_qcd (  opj_j2k_t *p_j2k,
+                                    OPJ_BYTE * p_header_data,
+                                    OPJ_UINT32 p_header_size,
+                                    opj_event_mgr_t * p_manager );
+#if 0
+/**
+ * Writes the QCC marker (quantization component)
+ *
+ * @param       p_comp_no       the index of the component to output.
+ * @param       p_stream                the stream to write data to.
+ * @param       p_j2k                   J2K codec.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_write_qcc(      opj_j2k_t *p_j2k,
+                                                                        OPJ_UINT32 p_comp_no,
+                                                                        opj_stream_private_t *p_stream,
+                                                                        opj_event_mgr_t * p_manager );
+#endif
+
+#if 0
+/**
+ * Writes the QCC marker (quantization component)
+ *
+ * @param       p_j2k           J2K codec.
+ * @param       p_comp_no       the index of the component to output.
+ * @param       p_data          FIXME DOC
+ * @param       p_data_written  the stream to write data to.
+ * @param       p_manager       the user event manager.
+*/
+static void opj_j2k_write_qcc_in_memory(opj_j2k_t *p_j2k,
+                                                                            OPJ_UINT32 p_comp_no,
+                                                                            OPJ_BYTE * p_data,
+                                                                            OPJ_UINT32 * p_data_written,
+                                                                            opj_event_mgr_t * p_manager );
+#endif
+
+/**
+ * Gets the maximum size taken by a qcc.
+ */
+static OPJ_UINT32 opj_j2k_get_max_qcc_size (opj_j2k_t *p_j2k);
+
+/**
+ * Reads a QCC marker (Quantization component)
+ * @param       p_header_data   the data contained in the QCC box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the QCC marker.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_qcc(   opj_j2k_t *p_j2k,
+                                    OPJ_BYTE * p_header_data,
+                                    OPJ_UINT32 p_header_size,
+                                    opj_event_mgr_t * p_manager);
+/**
+ * Writes the POC marker (Progression Order Change)
+ *
+ * @param       p_stream                                the stream to write data to.
+ * @param       p_j2k                           J2K codec.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_write_poc(      opj_j2k_t *p_j2k,
+                                                                        opj_stream_private_t *p_stream,
+                                                                        opj_event_mgr_t * p_manager );
+/**
+ * Writes the POC marker (Progression Order Change)
+ *
+ * @param       p_j2k          J2K codec.
+ * @param       p_data         FIXME DOC
+ * @param       p_data_written the stream to write data to.
+ * @param       p_manager      the user event manager.
+ */
+static void opj_j2k_write_poc_in_memory(opj_j2k_t *p_j2k,
+                                                                            OPJ_BYTE * p_data,
+                                                                            OPJ_UINT32 * p_data_written,
+                                                                            opj_event_mgr_t * p_manager );
+/**
+ * Gets the maximum size taken by the writing of a POC.
+ */
+static OPJ_UINT32 opj_j2k_get_max_poc_size(opj_j2k_t *p_j2k);
+
+/**
+ * Reads a POC marker (Progression Order Change)
+ *
+ * @param       p_header_data   the data contained in the POC box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the POC marker.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_poc (  opj_j2k_t *p_j2k,
+                                    OPJ_BYTE * p_header_data,
+                                    OPJ_UINT32 p_header_size,
+                                    opj_event_mgr_t * p_manager );
+
+/**
+ * Gets the maximum size taken by the toc headers of all the tile parts of any given tile.
+ */
+static OPJ_UINT32 opj_j2k_get_max_toc_size (opj_j2k_t *p_j2k);
+
+/**
+ * Gets the maximum size taken by the headers of the SOT.
+ *
+ * @param       p_j2k   the jpeg2000 codec to use.
+ */
+static OPJ_UINT32 opj_j2k_get_specific_header_sizes(opj_j2k_t *p_j2k);
+
+/**
+ * Reads a CRG marker (Component registration)
+ *
+ * @param       p_header_data   the data contained in the TLM box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the TLM marker.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_crg (  opj_j2k_t *p_j2k,
+                                    OPJ_BYTE * p_header_data,
+                                    OPJ_UINT32 p_header_size,
+                                    opj_event_mgr_t * p_manager );
+/**
+ * Reads a TLM marker (Tile Length Marker)
+ *
+ * @param       p_header_data   the data contained in the TLM box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the TLM marker.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_tlm (  opj_j2k_t *p_j2k,
+                                    OPJ_BYTE * p_header_data,
+                                    OPJ_UINT32 p_header_size,
+                                    opj_event_mgr_t * p_manager);
+
+/**
+ * Writes the updated tlm.
+ *
+ * @param       p_stream                the stream to write data to.
+ * @param       p_j2k                   J2K codec.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_write_updated_tlm(      opj_j2k_t *p_j2k,
+                                            opj_stream_private_t *p_stream,
+                                            opj_event_mgr_t * p_manager );
+
+/**
+ * Reads a PLM marker (Packet length, main header marker)
+ *
+ * @param       p_header_data   the data contained in the TLM box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the TLM marker.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_plm (  opj_j2k_t *p_j2k,
+                                    OPJ_BYTE * p_header_data,
+                                    OPJ_UINT32 p_header_size,
+                                    opj_event_mgr_t * p_manager);
+/**
+ * Reads a PLT marker (Packet length, tile-part header)
+ *
+ * @param       p_header_data   the data contained in the PLT box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the PLT marker.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_plt (  opj_j2k_t *p_j2k,
+                                    OPJ_BYTE * p_header_data,
+                                    OPJ_UINT32 p_header_size,
+                                    opj_event_mgr_t * p_manager );
+
+#if 0
+/**
+ * Reads a PPM marker (Packed packet headers, main header)
+ *
+ * @param       p_header_data   the data contained in the POC box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the POC marker.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL j2k_read_ppm_v2 (
+                                                opj_j2k_t *p_j2k,
+                                                OPJ_BYTE * p_header_data,
+                                                OPJ_UINT32 p_header_size,
+                                                struct opj_event_mgr * p_manager
+                                        );
+#endif
+
+static OPJ_BOOL j2k_read_ppm_v3 (
+                                                opj_j2k_t *p_j2k,
+                                                OPJ_BYTE * p_header_data,
+                                                OPJ_UINT32 p_header_size,
+                                                opj_event_mgr_t * p_manager );
+
+/**
+ * Reads a PPT marker (Packed packet headers, tile-part header)
+ *
+ * @param       p_header_data   the data contained in the PPT box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the PPT marker.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_ppt (  opj_j2k_t *p_j2k,
+                                    OPJ_BYTE * p_header_data,
+                                    OPJ_UINT32 p_header_size,
+                                    opj_event_mgr_t * p_manager );
+/**
+ * Writes the TLM marker (Tile Length Marker)
+ *
+ * @param       p_stream                                the stream to write data to.
+ * @param       p_j2k                           J2K codec.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_write_tlm(      opj_j2k_t *p_j2k,
+                                                                        opj_stream_private_t *p_stream,
+                                                                        opj_event_mgr_t * p_manager );
+
+/**
+ * Writes the SOT marker (Start of tile-part)
+ *
+ * @param       p_j2k            J2K codec.
+ * @param       p_data           FIXME DOC
+ * @param       p_data_written   FIXME DOC
+ * @param       p_stream         the stream to write data to.
+ * @param       p_manager        the user event manager.
+*/
+static OPJ_BOOL opj_j2k_write_sot(      opj_j2k_t *p_j2k,
+                                                                        OPJ_BYTE * p_data,
+                                                                        OPJ_UINT32 * p_data_written,
+                                                                        const opj_stream_private_t *p_stream,
+                                                                        opj_event_mgr_t * p_manager );
+
+/**
+ * Reads a PPT marker (Packed packet headers, tile-part header)
+ *
+ * @param       p_header_data   the data contained in the PPT box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the PPT marker.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_sot (  opj_j2k_t *p_j2k,
+                                    OPJ_BYTE * p_header_data,
+                                    OPJ_UINT32 p_header_size,
+                                    opj_event_mgr_t * p_manager );
+/**
+ * Writes the SOD marker (Start of data)
+ *
+ * @param       p_j2k               J2K codec.
+ * @param       p_tile_coder        FIXME DOC
+ * @param       p_data              FIXME DOC
+ * @param       p_data_written      FIXME DOC
+ * @param       p_total_data_size   FIXME DOC
+ * @param       p_stream            the stream to write data to.
+ * @param       p_manager           the user event manager.
+*/
+static OPJ_BOOL opj_j2k_write_sod(      opj_j2k_t *p_j2k,
+                                                                        opj_tcd_t * p_tile_coder,
+                                                                        OPJ_BYTE * p_data,
+                                                                        OPJ_UINT32 * p_data_written,
+                                                                        OPJ_UINT32 p_total_data_size,
+                                                                        const opj_stream_private_t *p_stream,
+                                                                        opj_event_mgr_t * p_manager );
+
+/**
+ * Reads a SOD marker (Start Of Data)
+ *
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_stream                FIXME DOC
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_sod(   opj_j2k_t *p_j2k,
+                                    opj_stream_private_t *p_stream,
+                                    opj_event_mgr_t * p_manager );
+
+void opj_j2k_update_tlm (opj_j2k_t * p_j2k, OPJ_UINT32 p_tile_part_size )
+{
+        opj_write_bytes(p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current,p_j2k->m_current_tile_number,1);            /* PSOT */
+        ++p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current;
+
+        opj_write_bytes(p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current,p_tile_part_size,4);                                        /* PSOT */
+        p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current += 4;
+}
+
+/**
+ * Writes the RGN marker (Region Of Interest)
+ *
+ * @param       p_tile_no               the tile to output
+ * @param       p_comp_no               the component to output
+ * @param       nb_comps                the number of components
+ * @param       p_stream                the stream to write data to.
+ * @param       p_j2k                   J2K codec.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_write_rgn(  opj_j2k_t *p_j2k,
+                                    OPJ_UINT32 p_tile_no,
+                                    OPJ_UINT32 p_comp_no,
+                                    OPJ_UINT32 nb_comps,
+                                    opj_stream_private_t *p_stream,
+                                    opj_event_mgr_t * p_manager );
+
+/**
+ * Reads a RGN marker (Region Of Interest)
+ *
+ * @param       p_header_data   the data contained in the POC box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the POC marker.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_rgn (opj_j2k_t *p_j2k,
+                                  OPJ_BYTE * p_header_data,
+                                  OPJ_UINT32 p_header_size,
+                                  opj_event_mgr_t * p_manager );
+
+/**
+ * Writes the EOC marker (End of Codestream)
+ *
+ * @param       p_stream                the stream to write data to.
+ * @param       p_j2k                   J2K codec.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_write_eoc(      opj_j2k_t *p_j2k,
+                                    opj_stream_private_t *p_stream,
+                                    opj_event_mgr_t * p_manager );
+
+#if 0
+/**
+ * Reads a EOC marker (End Of Codestream)
+ *
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_stream                FIXME DOC
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_eoc (      opj_j2k_t *p_j2k,
+                                                                opj_stream_private_t *p_stream,
+                                                                opj_event_mgr_t * p_manager );
+#endif
+
+/**
+ * Writes the CBD-MCT-MCC-MCO markers (Multi components transform)
+ *
+ * @param       p_stream                        the stream to write data to.
+ * @param       p_j2k                   J2K codec.
+ * @param       p_manager       the user event manager.
+*/
+static OPJ_BOOL opj_j2k_write_mct_data_group(   opj_j2k_t *p_j2k,
+                                                opj_stream_private_t *p_stream,
+                                                opj_event_mgr_t * p_manager );
+
+/**
+ * Inits the Info
+ *
+ * @param       p_stream                the stream to write data to.
+ * @param       p_j2k                   J2K codec.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_init_info(      opj_j2k_t *p_j2k,
+                                    opj_stream_private_t *p_stream,
+                                    opj_event_mgr_t * p_manager );
+
+/**
+Add main header marker information
+ at param cstr_index    Codestream information structure
+ at param type         marker type
+ at param pos          byte offset of marker segment
+ at param len          length of marker segment
+ */
+static OPJ_BOOL opj_j2k_add_mhmarker(opj_codestream_index_t *cstr_index, OPJ_UINT32 type, OPJ_OFF_T pos, OPJ_UINT32 len) ;
+/**
+Add tile header marker information
+ at param tileno       tile index number
+ at param cstr_index   Codestream information structure
+ at param type         marker type
+ at param pos          byte offset of marker segment
+ at param len          length of marker segment
+ */
+static OPJ_BOOL opj_j2k_add_tlmarker(OPJ_UINT32 tileno, opj_codestream_index_t *cstr_index, OPJ_UINT32 type, OPJ_OFF_T pos, OPJ_UINT32 len);
+
+/**
+ * Reads an unknown marker
+ *
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_stream                the stream object to read from.
+ * @param       output_marker           FIXME DOC
+ * @param       p_manager               the user event manager.
+ *
+ * @return      true                    if the marker could be deduced.
+*/
+static OPJ_BOOL opj_j2k_read_unk( opj_j2k_t *p_j2k,
+                                  opj_stream_private_t *p_stream,
+                                  OPJ_UINT32 *output_marker,
+                                  opj_event_mgr_t * p_manager );
+
+/**
+ * Writes the MCT marker (Multiple Component Transform)
+ *
+ * @param       p_j2k           J2K codec.
+ * @param       p_mct_record    FIXME DOC
+ * @param       p_stream        the stream to write data to.
+ * @param       p_manager       the user event manager.
+*/
+static OPJ_BOOL opj_j2k_write_mct_record(       opj_j2k_t *p_j2k,
+                                                                                    opj_mct_data_t * p_mct_record,
+                                            opj_stream_private_t *p_stream,
+                                            opj_event_mgr_t * p_manager );
+
+/**
+ * Reads a MCT marker (Multiple Component Transform)
+ *
+ * @param       p_header_data   the data contained in the MCT box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the MCT marker.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_mct (      opj_j2k_t *p_j2k,
+                                                                    OPJ_BYTE * p_header_data,
+                                                                    OPJ_UINT32 p_header_size,
+                                                                    opj_event_mgr_t * p_manager );
+
+/**
+ * Writes the MCC marker (Multiple Component Collection)
+ *
+ * @param       p_j2k                   J2K codec.
+ * @param       p_mcc_record            FIXME DOC
+ * @param       p_stream                the stream to write data to.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_write_mcc_record(   opj_j2k_t *p_j2k,
+                                            opj_simple_mcc_decorrelation_data_t * p_mcc_record,
+                                            opj_stream_private_t *p_stream,
+                                            opj_event_mgr_t * p_manager );
+
+/**
+ * Reads a MCC marker (Multiple Component Collection)
+ *
+ * @param       p_header_data   the data contained in the MCC box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the MCC marker.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_mcc (      opj_j2k_t *p_j2k,
+                                                                    OPJ_BYTE * p_header_data,
+                                                                    OPJ_UINT32 p_header_size,
+                                                                    opj_event_mgr_t * p_manager );
+
+/**
+ * Writes the MCO marker (Multiple component transformation ordering)
+ *
+ * @param       p_stream                                the stream to write data to.
+ * @param       p_j2k                           J2K codec.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_write_mco(      opj_j2k_t *p_j2k,
+                                    opj_stream_private_t *p_stream,
+                                    opj_event_mgr_t * p_manager );
+
+/**
+ * Reads a MCO marker (Multiple Component Transform Ordering)
+ *
+ * @param       p_header_data   the data contained in the MCO box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the MCO marker.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_mco (      opj_j2k_t *p_j2k,
+                                                                    OPJ_BYTE * p_header_data,
+                                                                    OPJ_UINT32 p_header_size,
+                                                                    opj_event_mgr_t * p_manager );
+
+static OPJ_BOOL opj_j2k_add_mct(opj_tcp_t * p_tcp, opj_image_t * p_image, OPJ_UINT32 p_index);
+
+static void  opj_j2k_read_int16_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
+static void  opj_j2k_read_int32_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
+static void  opj_j2k_read_float32_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
+static void  opj_j2k_read_float64_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
+
+static void  opj_j2k_read_int16_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
+static void  opj_j2k_read_int32_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
+static void  opj_j2k_read_float32_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
+static void  opj_j2k_read_float64_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
+
+static void  opj_j2k_write_float_to_int16 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
+static void  opj_j2k_write_float_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
+static void  opj_j2k_write_float_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
+static void  opj_j2k_write_float_to_float64 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
+
+/**
+ * Ends the encoding, i.e. frees memory.
+ *
+ * @param       p_stream                the stream to write data to.
+ * @param       p_j2k                   J2K codec.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_end_encoding(   opj_j2k_t *p_j2k,
+                                                                            opj_stream_private_t *p_stream,
+                                                                            opj_event_mgr_t * p_manager );
+
+/**
+ * Writes the CBD marker (Component bit depth definition)
+ *
+ * @param       p_stream                                the stream to write data to.
+ * @param       p_j2k                           J2K codec.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_write_cbd(      opj_j2k_t *p_j2k,
+                                                                    opj_stream_private_t *p_stream,
+                                                                        opj_event_mgr_t * p_manager );
+
+/**
+ * Reads a CBD marker (Component bit depth definition)
+ * @param       p_header_data   the data contained in the CBD box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the CBD marker.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_cbd (      opj_j2k_t *p_j2k,
+                                                                OPJ_BYTE * p_header_data,
+                                                                OPJ_UINT32 p_header_size,
+                                                                opj_event_mgr_t * p_manager);
+
+#if 0
+/**
+ * Writes COC marker for each component.
+ *
+ * @param       p_stream                the stream to write data to.
+ * @param       p_j2k                   J2K codec.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_write_all_coc( opj_j2k_t *p_j2k,
+                                                                        opj_stream_private_t *p_stream,
+                                                                        opj_event_mgr_t * p_manager );
+#endif
+
+#if 0
+/**
+ * Writes QCC marker for each component.
+ *
+ * @param       p_stream                the stream to write data to.
+ * @param       p_j2k                   J2K codec.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_write_all_qcc( opj_j2k_t *p_j2k,
+                                                                        opj_stream_private_t *p_stream,
+                                                                        opj_event_mgr_t * p_manager );
+#endif
+
+/**
+ * Writes regions of interests.
+ *
+ * @param       p_stream                the stream to write data to.
+ * @param       p_j2k                   J2K codec.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_write_regions(  opj_j2k_t *p_j2k,
+                                                                        opj_stream_private_t *p_stream,
+                                                                        opj_event_mgr_t * p_manager );
+
+/**
+ * Writes EPC ????
+ *
+ * @param       p_stream                the stream to write data to.
+ * @param       p_j2k                   J2K codec.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_write_epc(      opj_j2k_t *p_j2k,
+                                                                    opj_stream_private_t *p_stream,
+                                                                    opj_event_mgr_t * p_manager );
+
+/**
+ * Checks the progression order changes values. Tells of the poc given as input are valid.
+ * A nice message is outputted at errors.
+ *
+ * @param       p_pocs                  the progression order changes.
+ * @param       p_nb_pocs               the number of progression order changes.
+ * @param       p_nb_resolutions        the number of resolutions.
+ * @param       numcomps                the number of components
+ * @param       numlayers               the number of layers.
+ * @param       p_manager               the user event manager.
+ *
+ * @return      true if the pocs are valid.
+ */
+static OPJ_BOOL opj_j2k_check_poc_val(  const opj_poc_t *p_pocs,
+                                                                            OPJ_UINT32 p_nb_pocs,
+                                                                            OPJ_UINT32 p_nb_resolutions,
+                                                                            OPJ_UINT32 numcomps,
+                                                                            OPJ_UINT32 numlayers,
+                                                                            opj_event_mgr_t * p_manager);
+
+/**
+ * Gets the number of tile parts used for the given change of progression (if any) and the given tile.
+ *
+ * @param               cp                      the coding parameters.
+ * @param               pino            the offset of the given poc (i.e. its position in the coding parameter).
+ * @param               tileno          the given tile.
+ *
+ * @return              the number of tile parts.
+ */
+static OPJ_UINT32 opj_j2k_get_num_tp( opj_cp_t *cp, OPJ_UINT32 pino, OPJ_UINT32 tileno);
+
+/**
+ * Calculates the total number of tile parts needed by the encoder to
+ * encode such an image. If not enough memory is available, then the function return false.
+ *
+ * @param       p_nb_tiles      pointer that will hold the number of tile parts.
+ * @param       cp                      the coding parameters for the image.
+ * @param       image           the image to encode.
+ * @param       p_j2k                   the p_j2k encoder.
+ * @param       p_manager       the user event manager.
+ *
+ * @return true if the function was successful, false else.
+ */
+static OPJ_BOOL opj_j2k_calculate_tp(   opj_j2k_t *p_j2k,
+                                                                            opj_cp_t *cp,
+                                                                            OPJ_UINT32 * p_nb_tiles,
+                                                                            opj_image_t *image,
+                                                                            opj_event_mgr_t * p_manager);
+
+static void opj_j2k_dump_MH_info(opj_j2k_t* p_j2k, FILE* out_stream);
+
+static void opj_j2k_dump_MH_index(opj_j2k_t* p_j2k, FILE* out_stream);
+
+static opj_codestream_index_t* opj_j2k_create_cstr_index(void);
+
+static OPJ_FLOAT32 opj_j2k_get_tp_stride (opj_tcp_t * p_tcp);
+
+static OPJ_FLOAT32 opj_j2k_get_default_stride (opj_tcp_t * p_tcp);
+
+static int opj_j2k_initialise_4K_poc(opj_poc_t *POC, int numres);
+
+static void opj_j2k_set_cinema_parameters(opj_cparameters_t *parameters, opj_image_t *image, opj_event_mgr_t *p_manager);
+
+static OPJ_BOOL opj_j2k_is_cinema_compliant(opj_image_t *image, OPJ_CINEMA_MODE cinema_mode, opj_event_mgr_t *p_manager);
+
+/*@}*/
+
+/*@}*/
+
+/* ----------------------------------------------------------------------- */
+typedef struct j2k_prog_order{
+        OPJ_PROG_ORDER enum_prog;
+        char str_prog[5];
+}j2k_prog_order_t;
+
+j2k_prog_order_t j2k_prog_order_list[] = {
+        {OPJ_CPRL, "CPRL"},
+        {OPJ_LRCP, "LRCP"},
+        {OPJ_PCRL, "PCRL"},
+        {OPJ_RLCP, "RLCP"},
+        {OPJ_RPCL, "RPCL"},
+        {(OPJ_PROG_ORDER)-1, ""}
+};
+
+/**
+ * FIXME DOC
+ */
+static const OPJ_UINT32 MCT_ELEMENT_SIZE [] =
+{
+        2,
+        4,
+        4,
+        8
+};
+
+typedef void (* opj_j2k_mct_function) (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
+
+const opj_j2k_mct_function j2k_mct_read_functions_to_float [] =
+{
+        opj_j2k_read_int16_to_float,
+        opj_j2k_read_int32_to_float,
+        opj_j2k_read_float32_to_float,
+        opj_j2k_read_float64_to_float
+};
+
+const opj_j2k_mct_function j2k_mct_read_functions_to_int32 [] =
+{
+        opj_j2k_read_int16_to_int32,
+        opj_j2k_read_int32_to_int32,
+        opj_j2k_read_float32_to_int32,
+        opj_j2k_read_float64_to_int32
+};
+
+const opj_j2k_mct_function j2k_mct_write_functions_from_float [] =
+{
+        opj_j2k_write_float_to_int16,
+        opj_j2k_write_float_to_int32,
+        opj_j2k_write_float_to_float,
+        opj_j2k_write_float_to_float64
+};
+
+typedef struct opj_dec_memory_marker_handler
+{
+        /** marker value */
+        OPJ_UINT32 id;
+        /** value of the state when the marker can appear */
+        OPJ_UINT32 states;
+        /** action linked to the marker */
+        OPJ_BOOL (*handler) (   opj_j2k_t *p_j2k,
+                            OPJ_BYTE * p_header_data,
+                            OPJ_UINT32 p_header_size,
+                            opj_event_mgr_t * p_manager );
+}
+opj_dec_memory_marker_handler_t;
+
+const opj_dec_memory_marker_handler_t j2k_memory_marker_handler_tab [] =
+{
+  {J2K_MS_SOT, J2K_STATE_MH | J2K_STATE_TPHSOT, opj_j2k_read_sot},
+  {J2K_MS_COD, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_cod},
+  {J2K_MS_COC, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_coc},
+  {J2K_MS_RGN, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_rgn},
+  {J2K_MS_QCD, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_qcd},
+  {J2K_MS_QCC, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_qcc},
+  {J2K_MS_POC, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_poc},
+  {J2K_MS_SIZ, J2K_STATE_MHSIZ, opj_j2k_read_siz},
+  {J2K_MS_TLM, J2K_STATE_MH, opj_j2k_read_tlm},
+  {J2K_MS_PLM, J2K_STATE_MH, opj_j2k_read_plm},
+  {J2K_MS_PLT, J2K_STATE_TPH, opj_j2k_read_plt},
+  {J2K_MS_PPM, J2K_STATE_MH, j2k_read_ppm_v3},
+  {J2K_MS_PPT, J2K_STATE_TPH, opj_j2k_read_ppt},
+  {J2K_MS_SOP, 0, 0},
+  {J2K_MS_CRG, J2K_STATE_MH, opj_j2k_read_crg},
+  {J2K_MS_COM, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_com},
+  {J2K_MS_MCT, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_mct},
+  {J2K_MS_CBD, J2K_STATE_MH , opj_j2k_read_cbd},
+  {J2K_MS_MCC, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_mcc},
+  {J2K_MS_MCO, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_mco},
+#ifdef USE_JPWL
+#ifdef TODO_MS /* remove these functions which are not commpatible with the v2 API */
+  {J2K_MS_EPC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_epc},
+  {J2K_MS_EPB, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_epb},
+  {J2K_MS_ESD, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_esd},
+  {J2K_MS_RED, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_red},
+#endif
+#endif /* USE_JPWL */
+#ifdef USE_JPSEC
+  {J2K_MS_SEC, J2K_DEC_STATE_MH, j2k_read_sec},
+  {J2K_MS_INSEC, 0, j2k_read_insec}
+#endif /* USE_JPSEC */
+  {J2K_MS_UNK, J2K_STATE_MH | J2K_STATE_TPH, 0}/*opj_j2k_read_unk is directly used*/
+};
+
+void  opj_j2k_read_int16_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
+{
+        OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data;
+        OPJ_FLOAT32 * l_dest_data = (OPJ_FLOAT32 *) p_dest_data;
+        OPJ_UINT32 i;
+        OPJ_UINT32 l_temp;
+
+        for (i=0;i<p_nb_elem;++i) {
+                opj_read_bytes(l_src_data,&l_temp,2);
+
+                l_src_data+=sizeof(OPJ_INT16);
+
+                *(l_dest_data++) = (OPJ_FLOAT32) l_temp;
+        }
+}
+
+void  opj_j2k_read_int32_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
+{
+        OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data;
+        OPJ_FLOAT32 * l_dest_data = (OPJ_FLOAT32 *) p_dest_data;
+        OPJ_UINT32 i;
+        OPJ_UINT32 l_temp;
+
+        for (i=0;i<p_nb_elem;++i) {
+                opj_read_bytes(l_src_data,&l_temp,4);
+
+                l_src_data+=sizeof(OPJ_INT32);
+
+                *(l_dest_data++) = (OPJ_FLOAT32) l_temp;
+        }
+}
+
+void  opj_j2k_read_float32_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
+{
+        OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data;
+        OPJ_FLOAT32 * l_dest_data = (OPJ_FLOAT32 *) p_dest_data;
+        OPJ_UINT32 i;
+        OPJ_FLOAT32 l_temp;
+
+        for (i=0;i<p_nb_elem;++i) {
+                opj_read_float(l_src_data,&l_temp);
+
+                l_src_data+=sizeof(OPJ_FLOAT32);
+
+                *(l_dest_data++) = l_temp;
+        }
+}
+
+void  opj_j2k_read_float64_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
+{
+        OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data;
+        OPJ_FLOAT32 * l_dest_data = (OPJ_FLOAT32 *) p_dest_data;
+        OPJ_UINT32 i;
+        OPJ_FLOAT64 l_temp;
+
+        for (i=0;i<p_nb_elem;++i) {
+                opj_read_double(l_src_data,&l_temp);
+
+                l_src_data+=sizeof(OPJ_FLOAT64);
+
+                *(l_dest_data++) = (OPJ_FLOAT32) l_temp;
+        }
+}
+
+void  opj_j2k_read_int16_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
+{
+        OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data;
+        OPJ_INT32 * l_dest_data = (OPJ_INT32 *) p_dest_data;
+        OPJ_UINT32 i;
+        OPJ_UINT32 l_temp;
+
+        for (i=0;i<p_nb_elem;++i) {
+                opj_read_bytes(l_src_data,&l_temp,2);
+
+                l_src_data+=sizeof(OPJ_INT16);
+
+                *(l_dest_data++) = (OPJ_INT32) l_temp;
+        }
+}
+
+void  opj_j2k_read_int32_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
+{
+        OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data;
+        OPJ_INT32 * l_dest_data = (OPJ_INT32 *) p_dest_data;
+        OPJ_UINT32 i;
+        OPJ_UINT32 l_temp;
+
+        for (i=0;i<p_nb_elem;++i) {
+                opj_read_bytes(l_src_data,&l_temp,4);
+
+                l_src_data+=sizeof(OPJ_INT32);
+
+                *(l_dest_data++) = (OPJ_INT32) l_temp;
+        }
+}
+
+void  opj_j2k_read_float32_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
+{
+        OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data;
+        OPJ_INT32 * l_dest_data = (OPJ_INT32 *) p_dest_data;
+        OPJ_UINT32 i;
+        OPJ_FLOAT32 l_temp;
+
+        for (i=0;i<p_nb_elem;++i) {
+                opj_read_float(l_src_data,&l_temp);
+
+                l_src_data+=sizeof(OPJ_FLOAT32);
+
+                *(l_dest_data++) = (OPJ_INT32) l_temp;
+        }
+}
+
+void  opj_j2k_read_float64_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
+{
+        OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data;
+        OPJ_INT32 * l_dest_data = (OPJ_INT32 *) p_dest_data;
+        OPJ_UINT32 i;
+        OPJ_FLOAT64 l_temp;
+
+        for (i=0;i<p_nb_elem;++i) {
+                opj_read_double(l_src_data,&l_temp);
+
+                l_src_data+=sizeof(OPJ_FLOAT64);
+
+                *(l_dest_data++) = (OPJ_INT32) l_temp;
+        }
+}
+
+void  opj_j2k_write_float_to_int16 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
+{
+        OPJ_BYTE * l_dest_data = (OPJ_BYTE *) p_dest_data;
+        OPJ_FLOAT32 * l_src_data = (OPJ_FLOAT32 *) p_src_data;
+        OPJ_UINT32 i;
+        OPJ_UINT32 l_temp;
+
+        for (i=0;i<p_nb_elem;++i) {
+                l_temp = (OPJ_UINT32) *(l_src_data++);
+
+                opj_write_bytes(l_dest_data,l_temp,sizeof(OPJ_INT16));
+
+                l_dest_data+=sizeof(OPJ_INT16);
+        }
+}
+
+void opj_j2k_write_float_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
+{
+        OPJ_BYTE * l_dest_data = (OPJ_BYTE *) p_dest_data;
+        OPJ_FLOAT32 * l_src_data = (OPJ_FLOAT32 *) p_src_data;
+        OPJ_UINT32 i;
+        OPJ_UINT32 l_temp;
+
+        for (i=0;i<p_nb_elem;++i) {
+                l_temp = (OPJ_UINT32) *(l_src_data++);
+
+                opj_write_bytes(l_dest_data,l_temp,sizeof(OPJ_INT32));
+
+                l_dest_data+=sizeof(OPJ_INT32);
+        }
+}
+
+void  opj_j2k_write_float_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
+{
+        OPJ_BYTE * l_dest_data = (OPJ_BYTE *) p_dest_data;
+        OPJ_FLOAT32 * l_src_data = (OPJ_FLOAT32 *) p_src_data;
+        OPJ_UINT32 i;
+        OPJ_FLOAT32 l_temp;
+
+        for (i=0;i<p_nb_elem;++i) {
+                l_temp = (OPJ_FLOAT32) *(l_src_data++);
+
+                opj_write_float(l_dest_data,l_temp);
+
+                l_dest_data+=sizeof(OPJ_FLOAT32);
+        }
+}
+
+void  opj_j2k_write_float_to_float64 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
+{
+        OPJ_BYTE * l_dest_data = (OPJ_BYTE *) p_dest_data;
+        OPJ_FLOAT32 * l_src_data = (OPJ_FLOAT32 *) p_src_data;
+        OPJ_UINT32 i;
+        OPJ_FLOAT64 l_temp;
+
+        for (i=0;i<p_nb_elem;++i) {
+                l_temp = (OPJ_FLOAT64) *(l_src_data++);
+
+                opj_write_double(l_dest_data,l_temp);
+
+                l_dest_data+=sizeof(OPJ_FLOAT64);
+        }
+}
+
+char *opj_j2k_convert_progression_order(OPJ_PROG_ORDER prg_order){
+        j2k_prog_order_t *po;
+        for(po = j2k_prog_order_list; po->enum_prog != -1; po++ ){
+                if(po->enum_prog == prg_order){
+                        return po->str_prog;
+                }
+        }
+        return po->str_prog;
+}
+
+OPJ_BOOL opj_j2k_check_poc_val( const opj_poc_t *p_pocs,
+                                                        OPJ_UINT32 p_nb_pocs,
+                                                        OPJ_UINT32 p_nb_resolutions,
+                                                        OPJ_UINT32 p_num_comps,
+                                                        OPJ_UINT32 p_num_layers,
+                                                        opj_event_mgr_t * p_manager)
+{
+        OPJ_UINT32* packet_array;
+        OPJ_UINT32 index , resno, compno, layno;
+        OPJ_UINT32 i;
+        OPJ_UINT32 step_c = 1;
+        OPJ_UINT32 step_r = p_num_comps * step_c;
+        OPJ_UINT32 step_l = p_nb_resolutions * step_r;
+        OPJ_BOOL loss = OPJ_FALSE;
+        OPJ_UINT32 layno0 = 0;
+
+        packet_array = (OPJ_UINT32*) opj_calloc(step_l * p_num_layers, sizeof(OPJ_UINT32));
+        if (packet_array == 00) {
+                opj_event_msg(p_manager , EVT_ERROR, "Not enough memory for checking the poc values.\n");
+                return OPJ_FALSE;
+        }
+        memset(packet_array,0,step_l * p_num_layers* sizeof(OPJ_UINT32));
+
+        if (p_nb_pocs == 0) {
+        opj_free(packet_array);
+                return OPJ_TRUE;
+        }
+
+        index = step_r * p_pocs->resno0;
+        /* take each resolution for each poc */
+        for (resno = p_pocs->resno0 ; resno < p_pocs->resno1 ; ++resno)
+        {
+                OPJ_UINT32 res_index = index + p_pocs->compno0 * step_c;
+
+                /* take each comp of each resolution for each poc */
+                for (compno = p_pocs->compno0 ; compno < p_pocs->compno1 ; ++compno) {
+                        OPJ_UINT32 comp_index = res_index + layno0 * step_l;
+
+                        /* and finally take each layer of each res of ... */
+                        for (layno = layno0; layno < p_pocs->layno1 ; ++layno) {
+                                /*index = step_r * resno + step_c * compno + step_l * layno;*/
+                                packet_array[comp_index] = 1;
+                                comp_index += step_l;
+                        }
+
+                        res_index += step_c;
+                }
+
+                index += step_r;
+        }
+        ++p_pocs;
+
+        /* iterate through all the pocs */
+        for (i = 1; i < p_nb_pocs ; ++i) {
+                OPJ_UINT32 l_last_layno1 = (p_pocs-1)->layno1 ;
+
+                layno0 = (p_pocs->layno1 > l_last_layno1)? l_last_layno1 : 0;
+                index = step_r * p_pocs->resno0;
+
+                /* take each resolution for each poc */
+                for (resno = p_pocs->resno0 ; resno < p_pocs->resno1 ; ++resno) {
+                        OPJ_UINT32 res_index = index + p_pocs->compno0 * step_c;
+
+                        /* take each comp of each resolution for each poc */
+                        for (compno = p_pocs->compno0 ; compno < p_pocs->compno1 ; ++compno) {
+                                OPJ_UINT32 comp_index = res_index + layno0 * step_l;
+
+                                /* and finally take each layer of each res of ... */
+                                for (layno = layno0; layno < p_pocs->layno1 ; ++layno) {
+                                        /*index = step_r * resno + step_c * compno + step_l * layno;*/
+                                        packet_array[comp_index] = 1;
+                                        comp_index += step_l;
+                                }
+
+                                res_index += step_c;
+                        }
+
+                        index += step_r;
+                }
+
+                ++p_pocs;
+        }
+
+        index = 0;
+        for (layno = 0; layno < p_num_layers ; ++layno) {
+                for (resno = 0; resno < p_nb_resolutions; ++resno) {
+                        for (compno = 0; compno < p_num_comps; ++compno) {
+                                loss |= (packet_array[index]!=1);
+                                /*index = step_r * resno + step_c * compno + step_l * layno;*/
+                                index += step_c;
+                        }
+                }
+        }
+
+        if (loss) {
+                opj_event_msg(p_manager , EVT_ERROR, "Missing packets possible loss of data\n");
+        }
+
+        opj_free(packet_array);
+
+        return !loss;
+}
+
+/* ----------------------------------------------------------------------- */
+
+OPJ_UINT32 opj_j2k_get_num_tp(opj_cp_t *cp, OPJ_UINT32 pino, OPJ_UINT32 tileno)
+{
+        const OPJ_CHAR *prog = 00;
+        OPJ_INT32 i;
+        OPJ_UINT32 tpnum = 1;
+        opj_tcp_t *tcp = 00;
+        opj_poc_t * l_current_poc = 00;
+
+        /*  preconditions */
+        assert(tileno < (cp->tw * cp->th));
+        assert(pino < (cp->tcps[tileno].numpocs + 1));
+
+        /* get the given tile coding parameter */
+        tcp = &cp->tcps[tileno];
+        assert(tcp != 00);
+
+        l_current_poc = &(tcp->pocs[pino]);
+        assert(l_current_poc != 0);
+
+        /* get the progression order as a character string */
+        prog = opj_j2k_convert_progression_order(tcp->prg);
+        assert(strlen(prog) > 0);
+
+        if (cp->m_specific_param.m_enc.m_tp_on == 1) {
+                for (i=0;i<4;++i) {
+                        switch (prog[i])
+                        {
+                                /* component wise */
+                                case 'C':
+                                        tpnum *= l_current_poc->compE;
+                                        break;
+                                /* resolution wise */
+                                case 'R':
+                                        tpnum *= l_current_poc->resE;
+                                        break;
+                                /* precinct wise */
+                                case 'P':
+                                        tpnum *= l_current_poc->prcE;
+                                        break;
+                                /* layer wise */
+                                case 'L':
+                                        tpnum *= l_current_poc->layE;
+                                        break;
+                        }
+                        /* whould we split here ? */
+                        if ( cp->m_specific_param.m_enc.m_tp_flag == prog[i] ) {
+                                cp->m_specific_param.m_enc.m_tp_pos=i;
+                                break;
+                        }
+                }
+        }
+        else {
+                tpnum=1;
+        }
+
+        return tpnum;
+}
+
+OPJ_BOOL opj_j2k_calculate_tp(  opj_j2k_t *p_j2k,
+                                                        opj_cp_t *cp,
+                                                        OPJ_UINT32 * p_nb_tiles,
+                                                        opj_image_t *image,
+                                                        opj_event_mgr_t * p_manager
+                                )
+{
+        OPJ_UINT32 pino,tileno;
+        OPJ_UINT32 l_nb_tiles;
+        opj_tcp_t *tcp;
+
+        /* preconditions */
+        assert(p_nb_tiles != 00);
+        assert(cp != 00);
+        assert(image != 00);
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+
+        l_nb_tiles = cp->tw * cp->th;
+        * p_nb_tiles = 0;
+        tcp = cp->tcps;
+
+        /* INDEX >> */
+        /* TODO mergeV2: check this part which use cstr_info */
+        /*if (p_j2k->cstr_info) {
+                opj_tile_info_t * l_info_tile_ptr = p_j2k->cstr_info->tile;
+
+                for (tileno = 0; tileno < l_nb_tiles; ++tileno) {
+                        OPJ_UINT32 cur_totnum_tp = 0;
+
+                        opj_pi_update_encoding_parameters(image,cp,tileno);
+
+                        for (pino = 0; pino <= tcp->numpocs; ++pino)
+                        {
+                                OPJ_UINT32 tp_num = opj_j2k_get_num_tp(cp,pino,tileno);
+
+                                *p_nb_tiles = *p_nb_tiles + tp_num;
+
+                                cur_totnum_tp += tp_num;
+                        }
+
+                        tcp->m_nb_tile_parts = cur_totnum_tp;
+
+                        l_info_tile_ptr->tp = (opj_tp_info_t *) opj_malloc(cur_totnum_tp * sizeof(opj_tp_info_t));
+                        if (l_info_tile_ptr->tp == 00) {
+                                return OPJ_FALSE;
+                        }
+
+                        memset(l_info_tile_ptr->tp,0,cur_totnum_tp * sizeof(opj_tp_info_t));
+
+                        l_info_tile_ptr->num_tps = cur_totnum_tp;
+
+                        ++l_info_tile_ptr;
+                        ++tcp;
+                }
+        }
+        else */{
+                for (tileno = 0; tileno < l_nb_tiles; ++tileno) {
+                        OPJ_UINT32 cur_totnum_tp = 0;
+
+                        opj_pi_update_encoding_parameters(image,cp,tileno);
+
+                        for (pino = 0; pino <= tcp->numpocs; ++pino) {
+                                OPJ_UINT32 tp_num = opj_j2k_get_num_tp(cp,pino,tileno);
+
+                                *p_nb_tiles = *p_nb_tiles + tp_num;
+
+                                cur_totnum_tp += tp_num;
+                        }
+                        tcp->m_nb_tile_parts = cur_totnum_tp;
+
+                        ++tcp;
+                }
+        }
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_write_soc(     opj_j2k_t *p_j2k,
+                                                opj_stream_private_t *p_stream,
+                                                    opj_event_mgr_t * p_manager )
+{
+        /* 2 bytes will be written */
+        OPJ_BYTE * l_start_stream = 00;
+
+        /* preconditions */
+        assert(p_stream != 00);
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+
+        l_start_stream = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
+
+        /* write SOC identifier */
+        opj_write_bytes(l_start_stream,J2K_MS_SOC,2);
+
+        if (opj_stream_write_data(p_stream,l_start_stream,2,p_manager) != 2) {
+                return OPJ_FALSE;
+        }
+
+/* UniPG>> */
+#ifdef USE_JPWL
+        /* update markers struct */
+/*
+        OPJ_BOOL res = j2k_add_marker(p_j2k->cstr_info, J2K_MS_SOC, p_stream_tell(p_stream) - 2, 2);
+*/
+  assert( 0 && "TODO" );
+#endif /* USE_JPWL */
+/* <<UniPG */
+
+        return OPJ_TRUE;
+}
+
+/**
+ * Reads a SOC marker (Start of Codestream)
+ * @param       p_j2k           the jpeg2000 file codec.
+ * @param       p_stream        FIXME DOC
+ * @param       p_manager       the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_soc(   opj_j2k_t *p_j2k,
+                                    opj_stream_private_t *p_stream,
+                                    opj_event_mgr_t * p_manager
+                                    )
+{
+        OPJ_BYTE l_data [2];
+        OPJ_UINT32 l_marker;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+        assert(p_stream != 00);
+
+        if (opj_stream_read_data(p_stream,l_data,2,p_manager) != 2) {
+                return OPJ_FALSE;
+        }
+
+        opj_read_bytes(l_data,&l_marker,2);
+        if (l_marker != J2K_MS_SOC) {
+                return OPJ_FALSE;
+        }
+
+        /* Next marker should be a SIZ marker in the main header */
+        p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_MHSIZ;
+
+        /* FIXME move it in a index structure included in p_j2k*/
+        p_j2k->cstr_index->main_head_start = opj_stream_tell(p_stream) - 2;
+
+        opj_event_msg(p_manager, EVT_INFO, "Start to read j2k main header (%d).\n", p_j2k->cstr_index->main_head_start);
+
+        /* Add the marker to the codestream index*/
+        if (OPJ_FALSE == opj_j2k_add_mhmarker(p_j2k->cstr_index, J2K_MS_SOC, p_j2k->cstr_index->main_head_start, 2)) {
+                opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to add mh marker\n");
+                return OPJ_FALSE;
+        }
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_write_siz(     opj_j2k_t *p_j2k,
+                                                        opj_stream_private_t *p_stream,
+                                                        opj_event_mgr_t * p_manager )
+{
+        OPJ_UINT32 i;
+        OPJ_UINT32 l_size_len;
+        OPJ_BYTE * l_current_ptr;
+        opj_image_t * l_image = 00;
+        opj_cp_t *cp = 00;
+        opj_image_comp_t * l_img_comp = 00;
+
+        /* preconditions */
+        assert(p_stream != 00);
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+
+        l_image = p_j2k->m_private_image;
+        cp = &(p_j2k->m_cp);
+        l_size_len = 40 + 3 * l_image->numcomps;
+        l_img_comp = l_image->comps;
+
+        if (l_size_len > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) {
+
+                OPJ_BYTE *new_header_tile_data = (OPJ_BYTE *) opj_realloc(p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_size_len);
+                if (! new_header_tile_data) {
+                        opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data);
+                        p_j2k->m_specific_param.m_encoder.m_header_tile_data = NULL;
+                        p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0;
+                        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory for the SIZ marker\n");
+                        return OPJ_FALSE;
+                }
+                p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data;
+                p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_size_len;
+        }
+
+        l_current_ptr = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
+
+        /* write SOC identifier */
+        opj_write_bytes(l_current_ptr,J2K_MS_SIZ,2);    /* SIZ */
+        l_current_ptr+=2;
+
+        opj_write_bytes(l_current_ptr,l_size_len-2,2); /* L_SIZ */
+        l_current_ptr+=2;
+
+        opj_write_bytes(l_current_ptr, cp->rsiz, 2);    /* Rsiz (capabilities) */
+        l_current_ptr+=2;
+
+        opj_write_bytes(l_current_ptr, l_image->x1, 4); /* Xsiz */
+        l_current_ptr+=4;
+
+        opj_write_bytes(l_current_ptr, l_image->y1, 4); /* Ysiz */
+        l_current_ptr+=4;
+
+        opj_write_bytes(l_current_ptr, l_image->x0, 4); /* X0siz */
+        l_current_ptr+=4;
+
+        opj_write_bytes(l_current_ptr, l_image->y0, 4); /* Y0siz */
+        l_current_ptr+=4;
+
+        opj_write_bytes(l_current_ptr, cp->tdx, 4);             /* XTsiz */
+        l_current_ptr+=4;
+
+        opj_write_bytes(l_current_ptr, cp->tdy, 4);             /* YTsiz */
+        l_current_ptr+=4;
+
+        opj_write_bytes(l_current_ptr, cp->tx0, 4);             /* XT0siz */
+        l_current_ptr+=4;
+
+        opj_write_bytes(l_current_ptr, cp->ty0, 4);             /* YT0siz */
+        l_current_ptr+=4;
+
+        opj_write_bytes(l_current_ptr, l_image->numcomps, 2);   /* Csiz */
+        l_current_ptr+=2;
+
+        for (i = 0; i < l_image->numcomps; ++i) {
+                /* TODO here with MCT ? */
+                opj_write_bytes(l_current_ptr, l_img_comp->prec - 1 + (l_img_comp->sgnd << 7), 1);      /* Ssiz_i */
+                ++l_current_ptr;
+
+                opj_write_bytes(l_current_ptr, l_img_comp->dx, 1);      /* XRsiz_i */
+                ++l_current_ptr;
+
+                opj_write_bytes(l_current_ptr, l_img_comp->dy, 1);      /* YRsiz_i */
+                ++l_current_ptr;
+
+                ++l_img_comp;
+        }
+
+        if (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_size_len,p_manager) != l_size_len) {
+                return OPJ_FALSE;
+        }
+
+        return OPJ_TRUE;
+}
+
+/**
+ * Reads a SIZ marker (image and tile size)
+ * @param       p_j2k           the jpeg2000 file codec.
+ * @param       p_header_data   the data contained in the SIZ box.
+ * @param       p_header_size   the size of the data contained in the SIZ marker.
+ * @param       p_manager       the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_siz(opj_j2k_t *p_j2k,
+                                 OPJ_BYTE * p_header_data,
+                                 OPJ_UINT32 p_header_size,
+                                 opj_event_mgr_t * p_manager
+                                 )
+{
+        OPJ_UINT32 i;
+        OPJ_UINT32 l_nb_comp;
+        OPJ_UINT32 l_nb_comp_remain;
+        OPJ_UINT32 l_remaining_size;
+        OPJ_UINT32 l_nb_tiles;
+        OPJ_UINT32 l_tmp;
+        opj_image_t *l_image = 00;
+        opj_cp_t *l_cp = 00;
+        opj_image_comp_t * l_img_comp = 00;
+        opj_tcp_t * l_current_tile_param = 00;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+        assert(p_header_data != 00);
+
+        l_image = p_j2k->m_private_image;
+        l_cp = &(p_j2k->m_cp);
+
+        /* minimum size == 39 - 3 (= minimum component parameter) */
+        if (p_header_size < 36) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error with SIZ marker size\n");
+                return OPJ_FALSE;
+        }
+
+        l_remaining_size = p_header_size - 36;
+        l_nb_comp = l_remaining_size / 3;
+        l_nb_comp_remain = l_remaining_size % 3;
+        if (l_nb_comp_remain != 0){
+                opj_event_msg(p_manager, EVT_ERROR, "Error with SIZ marker size\n");
+                return OPJ_FALSE;
+        }
+
+        opj_read_bytes(p_header_data,&l_tmp ,2);                                                /* Rsiz (capabilities) */
+        p_header_data+=2;
+        l_cp->rsiz = (OPJ_RSIZ_CAPABILITIES) l_tmp;
+        opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_image->x1, 4);   /* Xsiz */
+        p_header_data+=4;
+        opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_image->y1, 4);   /* Ysiz */
+        p_header_data+=4;
+        opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_image->x0, 4);   /* X0siz */
+        p_header_data+=4;
+        opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_image->y0, 4);   /* Y0siz */
+        p_header_data+=4;
+        opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_cp->tdx, 4);             /* XTsiz */
+        p_header_data+=4;
+        opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_cp->tdy, 4);             /* YTsiz */
+        p_header_data+=4;
+        opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_cp->tx0, 4);             /* XT0siz */
+        p_header_data+=4;
+        opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_cp->ty0, 4);             /* YT0siz */
+        p_header_data+=4;
+        opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_tmp, 2);                 /* Csiz */
+        p_header_data+=2;
+        if (l_tmp < 16385)
+                l_image->numcomps = (OPJ_UINT16) l_tmp;
+        else {
+                opj_event_msg(p_manager, EVT_ERROR, "Error with SIZ marker: number of component is illegal -> %d\n", l_tmp);
+                return OPJ_FALSE;
+        }
+
+        if (l_image->numcomps != l_nb_comp) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error with SIZ marker: number of component is not compatible with the remaining number of parameters ( %d vs %d)\n", l_image->numcomps, l_nb_comp);
+                return OPJ_FALSE;
+        }
+
+        /* testcase 4035.pdf.SIGSEGV.d8b.3375 */
+        if (l_image->x0 > l_image->x1 || l_image->y0 > l_image->y1) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error with SIZ marker: negative image size (%d x %d)\n", l_image->x1 - l_image->x0, l_image->y1 - l_image->y0);
+                return OPJ_FALSE;
+        }
+        /* testcase 2539.pdf.SIGFPE.706.1712 (also 3622.pdf.SIGFPE.706.2916 and 4008.pdf.SIGFPE.706.3345 and maybe more) */
+        if (!(l_cp->tdx * l_cp->tdy)) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error with SIZ marker: invalid tile size (tdx: %d, tdy: %d)\n", l_cp->tdx, l_cp->tdy);
+                return OPJ_FALSE;
+        }
+
+        /* testcase 1610.pdf.SIGSEGV.59c.681 */
+        if (((OPJ_UINT64)l_image->x1) * ((OPJ_UINT64)l_image->y1) != (l_image->x1 * l_image->y1)) {
+                opj_event_msg(p_manager, EVT_ERROR, "Prevent buffer overflow (x1: %d, y1: %d)", l_image->x1, l_image->y1);
+                return OPJ_FALSE;
+        }
+
+#ifdef USE_JPWL
+        if (l_cp->correct) {
+                /* if JPWL is on, we check whether TX errors have damaged
+                  too much the SIZ parameters */
+                if (!(l_image->x1 * l_image->y1)) {
+                        opj_event_msg(p_manager, EVT_ERROR,
+                                "JPWL: bad image size (%d x %d)\n",
+                                l_image->x1, l_image->y1);
+                        if (!JPWL_ASSUME || JPWL_ASSUME) {
+                                opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n");
+                                return OPJ_FALSE;
+                        }
+                }
+
+        /* FIXME check previously in the function so why keep this piece of code ? Need by the norm ?
+                if (l_image->numcomps != ((len - 38) / 3)) {
+                        opj_event_msg(p_manager, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
+                                "JPWL: Csiz is %d => space in SIZ only for %d comps.!!!\n",
+                                l_image->numcomps, ((len - 38) / 3));
+                        if (!JPWL_ASSUME) {
+                                opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n");
+                                return OPJ_FALSE;
+                        }
+        */              /* we try to correct */
+        /*              opj_event_msg(p_manager, EVT_WARNING, "- trying to adjust this\n");
+                        if (l_image->numcomps < ((len - 38) / 3)) {
+                                len = 38 + 3 * l_image->numcomps;
+                                opj_event_msg(p_manager, EVT_WARNING, "- setting Lsiz to %d => HYPOTHESIS!!!\n",
+                                        len);
+                        } else {
+                                l_image->numcomps = ((len - 38) / 3);
+                                opj_event_msg(p_manager, EVT_WARNING, "- setting Csiz to %d => HYPOTHESIS!!!\n",
+                                        l_image->numcomps);
+                        }
+                }
+        */
+
+                /* update components number in the jpwl_exp_comps filed */
+                l_cp->exp_comps = l_image->numcomps;
+        }
+#endif /* USE_JPWL */
+
+        /* Allocate the resulting image components */
+        l_image->comps = (opj_image_comp_t*) opj_calloc(l_image->numcomps, sizeof(opj_image_comp_t));
+        if (l_image->comps == 00){
+                l_image->numcomps = 0;
+                opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to take in charge SIZ marker\n");
+                return OPJ_FALSE;
+        }
+
+        memset(l_image->comps,0,l_image->numcomps * sizeof(opj_image_comp_t));
+        l_img_comp = l_image->comps;
+
+        /* Read the component information */
+        for (i = 0; i < l_image->numcomps; ++i){
+                OPJ_UINT32 tmp;
+                opj_read_bytes(p_header_data,&tmp,1);   /* Ssiz_i */
+                ++p_header_data;
+                l_img_comp->prec = (tmp & 0x7f) + 1;
+                l_img_comp->sgnd = tmp >> 7;
+                opj_read_bytes(p_header_data,&tmp,1);   /* XRsiz_i */
+                ++p_header_data;
+                l_img_comp->dx = (OPJ_UINT32)tmp; /* should be between 1 and 255 */
+                opj_read_bytes(p_header_data,&tmp,1);   /* YRsiz_i */
+                ++p_header_data;
+                l_img_comp->dy = (OPJ_UINT32)tmp; /* should be between 1 and 255 */
+                if( l_img_comp->dx < 1 || l_img_comp->dx > 255 ||
+                    l_img_comp->dy < 1 || l_img_comp->dy > 255 ) {
+                    opj_event_msg(p_manager, EVT_ERROR,
+                                  "Invalid values for comp = %d : dx=%u dy=%u\n (should be between 1 and 255 according the JPEG2000 norm)",
+                                  i, l_img_comp->dx, l_img_comp->dy);
+                    return OPJ_FALSE;
+                }
+
+#ifdef USE_JPWL
+                if (l_cp->correct) {
+                /* if JPWL is on, we check whether TX errors have damaged
+                        too much the SIZ parameters, again */
+                        if (!(l_image->comps[i].dx * l_image->comps[i].dy)) {
+                                opj_event_msg(p_manager, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
+                                        "JPWL: bad XRsiz_%d/YRsiz_%d (%d x %d)\n",
+                                        i, i, l_image->comps[i].dx, l_image->comps[i].dy);
+                                if (!JPWL_ASSUME) {
+                                        opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n");
+                                        return OPJ_FALSE;
+                                }
+                                /* we try to correct */
+                                opj_event_msg(p_manager, EVT_WARNING, "- trying to adjust them\n");
+                                if (!l_image->comps[i].dx) {
+                                        l_image->comps[i].dx = 1;
+                                        opj_event_msg(p_manager, EVT_WARNING, "- setting XRsiz_%d to %d => HYPOTHESIS!!!\n",
+                                                i, l_image->comps[i].dx);
+                                }
+                                if (!l_image->comps[i].dy) {
+                                        l_image->comps[i].dy = 1;
+                                        opj_event_msg(p_manager, EVT_WARNING, "- setting YRsiz_%d to %d => HYPOTHESIS!!!\n",
+                                                i, l_image->comps[i].dy);
+                                }
+                        }
+                }
+#endif /* USE_JPWL */
+                l_img_comp->resno_decoded = 0;                                                          /* number of resolution decoded */
+                l_img_comp->factor = l_cp->m_specific_param.m_dec.m_reduce; /* reducing factor per component */
+                ++l_img_comp;
+        }
+
+        /* Compute the number of tiles */
+        l_cp->tw = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)(l_image->x1 - l_cp->tx0), (OPJ_INT32)l_cp->tdx);
+        l_cp->th = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)(l_image->y1 - l_cp->ty0), (OPJ_INT32)l_cp->tdy);
+
+        /* Check that the number of tiles is valid */
+        if (l_cp->tw == 0 || l_cp->th == 0 || l_cp->tw > 65535 / l_cp->th) {
+            opj_event_msg(  p_manager, EVT_ERROR, 
+                            "Invalid number of tiles : %u x %u (maximum fixed by jpeg2000 norm is 65535 tiles)\n",
+                            l_cp->tw, l_cp->th);
+            return OPJ_FALSE;
+        }
+        l_nb_tiles = l_cp->tw * l_cp->th;
+
+        /* Define the tiles which will be decoded */
+        if (p_j2k->m_specific_param.m_decoder.m_discard_tiles) {
+                p_j2k->m_specific_param.m_decoder.m_start_tile_x = (p_j2k->m_specific_param.m_decoder.m_start_tile_x - l_cp->tx0) / l_cp->tdx;
+                p_j2k->m_specific_param.m_decoder.m_start_tile_y = (p_j2k->m_specific_param.m_decoder.m_start_tile_y - l_cp->ty0) / l_cp->tdy;
+                p_j2k->m_specific_param.m_decoder.m_end_tile_x = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)(p_j2k->m_specific_param.m_decoder.m_end_tile_x - l_cp->tx0), (OPJ_INT32)l_cp->tdx);
+                p_j2k->m_specific_param.m_decoder.m_end_tile_y = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)(p_j2k->m_specific_param.m_decoder.m_end_tile_y - l_cp->ty0), (OPJ_INT32)l_cp->tdy);
+        }
+        else {
+                p_j2k->m_specific_param.m_decoder.m_start_tile_x = 0;
+                p_j2k->m_specific_param.m_decoder.m_start_tile_y = 0;
+                p_j2k->m_specific_param.m_decoder.m_end_tile_x = l_cp->tw;
+                p_j2k->m_specific_param.m_decoder.m_end_tile_y = l_cp->th;
+        }
+
+#ifdef USE_JPWL
+        if (l_cp->correct) {
+                /* if JPWL is on, we check whether TX errors have damaged
+                  too much the SIZ parameters */
+                if ((l_cp->tw < 1) || (l_cp->th < 1) || (l_cp->tw > l_cp->max_tiles) || (l_cp->th > l_cp->max_tiles)) {
+                        opj_event_msg(p_manager, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
+                                "JPWL: bad number of tiles (%d x %d)\n",
+                                l_cp->tw, l_cp->th);
+                        if (!JPWL_ASSUME) {
+                                opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n");
+                                return OPJ_FALSE;
+                        }
+                        /* we try to correct */
+                        opj_event_msg(p_manager, EVT_WARNING, "- trying to adjust them\n");
+                        if (l_cp->tw < 1) {
+                                l_cp->tw= 1;
+                                opj_event_msg(p_manager, EVT_WARNING, "- setting %d tiles in x => HYPOTHESIS!!!\n",
+                                                l_cp->tw);
+                        }
+                        if (l_cp->tw > l_cp->max_tiles) {
+                                l_cp->tw= 1;
+                                opj_event_msg(p_manager, EVT_WARNING, "- too large x, increase expectance of %d\n"
+                                        "- setting %d tiles in x => HYPOTHESIS!!!\n",
+                                        l_cp->max_tiles, l_cp->tw);
+                        }
+                        if (l_cp->th < 1) {
+                                l_cp->th= 1;
+                                opj_event_msg(p_manager, EVT_WARNING, "- setting %d tiles in y => HYPOTHESIS!!!\n",
+                                                l_cp->th);
+                        }
+                        if (l_cp->th > l_cp->max_tiles) {
+                                l_cp->th= 1;
+                                opj_event_msg(p_manager, EVT_WARNING, "- too large y, increase expectance of %d to continue\n",
+                                        "- setting %d tiles in y => HYPOTHESIS!!!\n",
+                                        l_cp->max_tiles, l_cp->th);
+                        }
+                }
+        }
+#endif /* USE_JPWL */
+
+        /* memory allocations */
+        l_cp->tcps = (opj_tcp_t*) opj_calloc(l_nb_tiles, sizeof(opj_tcp_t));
+        if (l_cp->tcps == 00) {
+                opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to take in charge SIZ marker\n");
+                return OPJ_FALSE;
+        }
+        memset(l_cp->tcps,0,l_nb_tiles*sizeof(opj_tcp_t));
+
+#ifdef USE_JPWL
+        if (l_cp->correct) {
+                if (!l_cp->tcps) {
+                        opj_event_msg(p_manager, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
+                                "JPWL: could not alloc tcps field of cp\n");
+                        if (!JPWL_ASSUME || JPWL_ASSUME) {
+                                opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n");
+                                return OPJ_FALSE;
+                        }
+                }
+        }
+#endif /* USE_JPWL */
+
+        p_j2k->m_specific_param.m_decoder.m_default_tcp->tccps =
+                        (opj_tccp_t*) opj_calloc(l_image->numcomps, sizeof(opj_tccp_t));
+        if(p_j2k->m_specific_param.m_decoder.m_default_tcp->tccps  == 00) {
+                opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to take in charge SIZ marker\n");
+                return OPJ_FALSE;
+        }
+        memset(p_j2k->m_specific_param.m_decoder.m_default_tcp->tccps ,0,l_image->numcomps*sizeof(opj_tccp_t));
+
+        p_j2k->m_specific_param.m_decoder.m_default_tcp->m_mct_records =
+                        (opj_mct_data_t*)opj_malloc(OPJ_J2K_MCT_DEFAULT_NB_RECORDS * sizeof(opj_mct_data_t));
+
+        if (! p_j2k->m_specific_param.m_decoder.m_default_tcp->m_mct_records) {
+                opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to take in charge SIZ marker\n");
+                return OPJ_FALSE;
+        }
+        memset(p_j2k->m_specific_param.m_decoder.m_default_tcp->m_mct_records,0,OPJ_J2K_MCT_DEFAULT_NB_RECORDS * sizeof(opj_mct_data_t));
+        p_j2k->m_specific_param.m_decoder.m_default_tcp->m_nb_max_mct_records = OPJ_J2K_MCT_DEFAULT_NB_RECORDS;
+
+        p_j2k->m_specific_param.m_decoder.m_default_tcp->m_mcc_records =
+                        (opj_simple_mcc_decorrelation_data_t*)
+                        opj_malloc(OPJ_J2K_MCC_DEFAULT_NB_RECORDS * sizeof(opj_simple_mcc_decorrelation_data_t));
+
+        if (! p_j2k->m_specific_param.m_decoder.m_default_tcp->m_mcc_records) {
+                opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to take in charge SIZ marker\n");
+                return OPJ_FALSE;
+        }
+        memset(p_j2k->m_specific_param.m_decoder.m_default_tcp->m_mcc_records,0,OPJ_J2K_MCC_DEFAULT_NB_RECORDS * sizeof(opj_simple_mcc_decorrelation_data_t));
+        p_j2k->m_specific_param.m_decoder.m_default_tcp->m_nb_max_mcc_records = OPJ_J2K_MCC_DEFAULT_NB_RECORDS;
+
+        /* set up default dc level shift */
+        for (i=0;i<l_image->numcomps;++i) {
+                if (! l_image->comps[i].sgnd) {
+                        p_j2k->m_specific_param.m_decoder.m_default_tcp->tccps[i].m_dc_level_shift = 1 << (l_image->comps[i].prec - 1);
+                }
+        }
+
+        l_current_tile_param = l_cp->tcps;
+        for     (i = 0; i < l_nb_tiles; ++i) {
+                l_current_tile_param->tccps = (opj_tccp_t*) opj_malloc(l_image->numcomps * sizeof(opj_tccp_t));
+                if (l_current_tile_param->tccps == 00) {
+                        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to take in charge SIZ marker\n");
+                        return OPJ_FALSE;
+                }
+                memset(l_current_tile_param->tccps,0,l_image->numcomps * sizeof(opj_tccp_t));
+
+                ++l_current_tile_param;
+        }
+
+        p_j2k->m_specific_param.m_decoder.m_state =  J2K_STATE_MH; /* FIXME J2K_DEC_STATE_MH; */
+        opj_image_comp_header_update(l_image,l_cp);
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_write_com(     opj_j2k_t *p_j2k,
+                                                        opj_stream_private_t *p_stream,
+                                                        opj_event_mgr_t * p_manager
+                            )
+{
+        OPJ_UINT32 l_comment_size;
+        OPJ_UINT32 l_total_com_size;
+        const OPJ_CHAR *l_comment;
+        OPJ_BYTE * l_current_ptr = 00;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_stream != 00);
+        assert(p_manager != 00);
+
+        l_comment = p_j2k->m_cp.comment;
+        l_comment_size = (OPJ_UINT32)strlen(l_comment);
+        l_total_com_size = l_comment_size + 6;
+
+        if (l_total_com_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) {
+                OPJ_BYTE *new_header_tile_data = (OPJ_BYTE *) opj_realloc(p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_total_com_size);
+                if (! new_header_tile_data) {
+                        opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data);
+                        p_j2k->m_specific_param.m_encoder.m_header_tile_data = NULL;
+                        p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0;
+                        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to write the COM marker\n");
+                        return OPJ_FALSE;
+                }
+                p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data;
+                p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_total_com_size;
+        }
+
+        l_current_ptr = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
+
+        opj_write_bytes(l_current_ptr,J2K_MS_COM , 2);  /* COM */
+        l_current_ptr+=2;
+
+        opj_write_bytes(l_current_ptr,l_total_com_size - 2 , 2);        /* L_COM */
+        l_current_ptr+=2;
+
+        opj_write_bytes(l_current_ptr,1 , 2);   /* General use (IS 8859-15:1999 (Latin) values) */
+        l_current_ptr+=2;
+
+        memcpy( l_current_ptr,l_comment,l_comment_size);
+
+        if (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_total_com_size,p_manager) != l_total_com_size) {
+                return OPJ_FALSE;
+        }
+
+        return OPJ_TRUE;
+}
+
+/**
+ * Reads a COM marker (comments)
+ * @param       p_j2k           the jpeg2000 file codec.
+ * @param       p_header_data   the data contained in the COM box.
+ * @param       p_header_size   the size of the data contained in the COM marker.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_com (  opj_j2k_t *p_j2k,
+                                    OPJ_BYTE * p_header_data,
+                                    OPJ_UINT32 p_header_size,
+                                    opj_event_mgr_t * p_manager
+                                    )
+{
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+        assert(p_header_data != 00);
+  (void)p_header_size;
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_write_cod(     opj_j2k_t *p_j2k,
+                                                        opj_stream_private_t *p_stream,
+                                                        opj_event_mgr_t * p_manager )
+{
+        opj_cp_t *l_cp = 00;
+        opj_tcp_t *l_tcp = 00;
+        OPJ_UINT32 l_code_size,l_remaining_size;
+        OPJ_BYTE * l_current_data = 00;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+        assert(p_stream != 00);
+
+        l_cp = &(p_j2k->m_cp);
+        l_tcp = &l_cp->tcps[p_j2k->m_current_tile_number];
+        l_code_size = 9 + opj_j2k_get_SPCod_SPCoc_size(p_j2k,p_j2k->m_current_tile_number,0);
+        l_remaining_size = l_code_size;
+
+        if (l_code_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) {
+                OPJ_BYTE *new_header_tile_data = (OPJ_BYTE *) opj_realloc(p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_code_size);
+                if (! new_header_tile_data) {
+                        opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data);
+                        p_j2k->m_specific_param.m_encoder.m_header_tile_data = NULL;
+                        p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0;
+                        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to write COD marker\n");
+                        return OPJ_FALSE;
+                }
+                p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data;
+                p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_code_size;
+        }
+
+        l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
+
+        opj_write_bytes(l_current_data,J2K_MS_COD,2);           /* COD */
+        l_current_data += 2;
+
+        opj_write_bytes(l_current_data,l_code_size-2,2);        /* L_COD */
+        l_current_data += 2;
+
+        opj_write_bytes(l_current_data,l_tcp->csty,1);          /* Scod */
+        ++l_current_data;
+
+        opj_write_bytes(l_current_data,l_tcp->prg,1);           /* SGcod (A) */
+        ++l_current_data;
+
+        opj_write_bytes(l_current_data,l_tcp->numlayers,2);     /* SGcod (B) */
+        l_current_data+=2;
+
+        opj_write_bytes(l_current_data,l_tcp->mct,1);           /* SGcod (C) */
+        ++l_current_data;
+
+        l_remaining_size -= 9;
+
+        if (! opj_j2k_write_SPCod_SPCoc(p_j2k,p_j2k->m_current_tile_number,0,l_current_data,&l_remaining_size,p_manager)) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error writing COD marker\n");
+                return OPJ_FALSE;
+        }
+
+        if (l_remaining_size != 0) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error writing COD marker\n");
+                return OPJ_FALSE;
+        }
+
+        if (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_code_size,p_manager) != l_code_size) {
+                return OPJ_FALSE;
+        }
+
+        return OPJ_TRUE;
+}
+
+/**
+ * Reads a COD marker (Coding Styke defaults)
+ * @param       p_header_data   the data contained in the COD box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the COD marker.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_cod (  opj_j2k_t *p_j2k,
+                                    OPJ_BYTE * p_header_data,
+                                    OPJ_UINT32 p_header_size,
+                                    opj_event_mgr_t * p_manager
+                                    )
+{
+        /* loop */
+        OPJ_UINT32 i;
+        OPJ_UINT32 l_tmp;
+        opj_cp_t *l_cp = 00;
+        opj_tcp_t *l_tcp = 00;
+        opj_image_t *l_image = 00;
+
+        /* preconditions */
+        assert(p_header_data != 00);
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+
+        l_image = p_j2k->m_private_image;
+        l_cp = &(p_j2k->m_cp);
+
+        /* If we are in the first tile-part header of the current tile */
+        l_tcp = (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH) ?
+                                &l_cp->tcps[p_j2k->m_current_tile_number] :
+                                p_j2k->m_specific_param.m_decoder.m_default_tcp;
+
+        /* Make sure room is sufficient */
+        if (p_header_size < 5) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error reading COD marker\n");
+                return OPJ_FALSE;
+        }
+
+        opj_read_bytes(p_header_data,&l_tcp->csty,1);           /* Scod */
+        ++p_header_data;
+        opj_read_bytes(p_header_data,&l_tmp,1);                         /* SGcod (A) */
+        ++p_header_data;
+        l_tcp->prg = (OPJ_PROG_ORDER) l_tmp;
+        opj_read_bytes(p_header_data,&l_tcp->numlayers,2);      /* SGcod (B) */
+        p_header_data+=2;
+
+        /* If user didn't set a number layer to decode take the max specify in the codestream. */
+        if      (l_cp->m_specific_param.m_dec.m_layer) {
+                l_tcp->num_layers_to_decode = l_cp->m_specific_param.m_dec.m_layer;
+        }
+        else {
+                l_tcp->num_layers_to_decode = l_tcp->numlayers;
+        }
+
+        opj_read_bytes(p_header_data,&l_tcp->mct,1);            /* SGcod (C) */
+        ++p_header_data;
+
+        p_header_size -= 5;
+        for     (i = 0; i < l_image->numcomps; ++i) {
+                l_tcp->tccps[i].csty = l_tcp->csty & J2K_CCP_CSTY_PRT;
+        }
+
+        if (! opj_j2k_read_SPCod_SPCoc(p_j2k,0,p_header_data,&p_header_size,p_manager)) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error reading COD marker\n");
+                return OPJ_FALSE;
+        }
+
+        if (p_header_size != 0) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error reading COD marker\n");
+                return OPJ_FALSE;
+        }
+
+        /* Apply the coding style to other components of the current tile or the m_default_tcp*/
+        opj_j2k_copy_tile_component_parameters(p_j2k);
+
+        /* Index */
+#ifdef WIP_REMOVE_MSD
+        if (p_j2k->cstr_info) {
+                /*opj_codestream_info_t *l_cstr_info = p_j2k->cstr_info;*/
+                p_j2k->cstr_info->prog = l_tcp->prg;
+                p_j2k->cstr_info->numlayers = l_tcp->numlayers;
+                p_j2k->cstr_info->numdecompos = (OPJ_INT32*) opj_malloc(l_image->numcomps * sizeof(OPJ_UINT32));
+                for     (i = 0; i < l_image->numcomps; ++i) {
+                        p_j2k->cstr_info->numdecompos[i] = l_tcp->tccps[i].numresolutions - 1;
+                }
+        }
+#endif
+
+        return OPJ_TRUE;
+}
+
+#if 0
+OPJ_BOOL opj_j2k_write_coc( opj_j2k_t *p_j2k,
+                                                OPJ_UINT32 p_comp_no,
+                                                opj_stream_private_t *p_stream,
+                                                opj_event_mgr_t * p_manager )
+{
+        OPJ_UINT32 l_coc_size,l_remaining_size;
+        OPJ_UINT32 l_comp_room;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+        assert(p_stream != 00);
+
+        l_comp_room = (p_j2k->m_private_image->numcomps <= 256) ? 1 : 2;
+
+        l_coc_size = 5 + l_comp_room + opj_j2k_get_SPCod_SPCoc_size(p_j2k,p_j2k->m_current_tile_number,p_comp_no);
+
+        if (l_coc_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) {
+                OPJ_BYTE *new_header_tile_data;
+                /*p_j2k->m_specific_param.m_encoder.m_header_tile_data
+                        = (OPJ_BYTE*)opj_realloc(
+                                p_j2k->m_specific_param.m_encoder.m_header_tile_data,
+                                l_coc_size);*/
+
+                new_header_tile_data = (OPJ_BYTE *) opj_realloc(p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_coc_size);
+                if (! new_header_tile_data) {
+                        opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data);
+                        p_j2k->m_specific_param.m_encoder.m_header_tile_data = NULL;
+                        p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0;
+                        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to write COC marker\n");
+                        return OPJ_FALSE;
+                }
+                p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data;
+                p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_coc_size;
+        }
+
+        opj_j2k_write_coc_in_memory(p_j2k,p_comp_no,p_j2k->m_specific_param.m_encoder.m_header_tile_data,&l_remaining_size,p_manager);
+
+        if (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_coc_size,p_manager) != l_coc_size) {
+                return OPJ_FALSE;
+        }
+
+        return OPJ_TRUE;
+}
+#endif
+
+#if 0
+void opj_j2k_write_coc_in_memory(   opj_j2k_t *p_j2k,
+                                                OPJ_UINT32 p_comp_no,
+                                                OPJ_BYTE * p_data,
+                                                OPJ_UINT32 * p_data_written,
+                                                opj_event_mgr_t * p_manager
+                                    )
+{
+        opj_cp_t *l_cp = 00;
+        opj_tcp_t *l_tcp = 00;
+        OPJ_UINT32 l_coc_size,l_remaining_size;
+        OPJ_BYTE * l_current_data = 00;
+        opj_image_t *l_image = 00;
+        OPJ_UINT32 l_comp_room;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+
+        l_cp = &(p_j2k->m_cp);
+        l_tcp = &l_cp->tcps[p_j2k->m_current_tile_number];
+        l_image = p_j2k->m_private_image;
+        l_comp_room = (l_image->numcomps <= 256) ? 1 : 2;
+
+        l_coc_size = 5 + l_comp_room + opj_j2k_get_SPCod_SPCoc_size(p_j2k,p_j2k->m_current_tile_number,p_comp_no);
+        l_remaining_size = l_coc_size;
+
+        l_current_data = p_data;
+
+        opj_write_bytes(l_current_data,J2K_MS_COC,2);                           /* COC */
+        l_current_data += 2;
+
+        opj_write_bytes(l_current_data,l_coc_size-2,2);                         /* L_COC */
+        l_current_data += 2;
+
+        opj_write_bytes(l_current_data,p_comp_no, l_comp_room);         /* Ccoc */
+        l_current_data+=l_comp_room;
+
+        opj_write_bytes(l_current_data, l_tcp->tccps[p_comp_no].csty, 1);               /* Scoc */
+        ++l_current_data;
+
+        l_remaining_size -= (5 + l_comp_room);
+        opj_j2k_write_SPCod_SPCoc(p_j2k,p_j2k->m_current_tile_number,0,l_current_data,&l_remaining_size,p_manager);
+        * p_data_written = l_coc_size;
+}
+#endif
+
+OPJ_UINT32 opj_j2k_get_max_coc_size(opj_j2k_t *p_j2k)
+{
+        OPJ_UINT32 i,j;
+        OPJ_UINT32 l_nb_comp;
+        OPJ_UINT32 l_nb_tiles;
+        OPJ_UINT32 l_max = 0;
+
+        /* preconditions */
+
+        l_nb_tiles = p_j2k->m_cp.tw * p_j2k->m_cp.th ;
+        l_nb_comp = p_j2k->m_private_image->numcomps;
+
+        for (i=0;i<l_nb_tiles;++i) {
+                for (j=0;j<l_nb_comp;++j) {
+                        l_max = opj_uint_max(l_max,opj_j2k_get_SPCod_SPCoc_size(p_j2k,i,j));
+                }
+        }
+
+        return 6 + l_max;
+}
+
+/**
+ * Reads a COC marker (Coding Style Component)
+ * @param       p_header_data   the data contained in the COC box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the COC marker.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_coc (  opj_j2k_t *p_j2k,
+                                    OPJ_BYTE * p_header_data,
+                                    OPJ_UINT32 p_header_size,
+                                    opj_event_mgr_t * p_manager
+                                    )
+{
+        opj_cp_t *l_cp = NULL;
+        opj_tcp_t *l_tcp = NULL;
+        opj_image_t *l_image = NULL;
+        OPJ_UINT32 l_comp_room;
+        OPJ_UINT32 l_comp_no;
+
+        /* preconditions */
+        assert(p_header_data != 00);
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+
+        l_cp = &(p_j2k->m_cp);
+        l_tcp = (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH ) ? /*FIXME J2K_DEC_STATE_TPH*/
+                                &l_cp->tcps[p_j2k->m_current_tile_number] :
+                                p_j2k->m_specific_param.m_decoder.m_default_tcp;
+        l_image = p_j2k->m_private_image;
+
+        l_comp_room = l_image->numcomps <= 256 ? 1 : 2;
+
+        /* make sure room is sufficient*/
+        if (p_header_size < l_comp_room + 1) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error reading COC marker\n");
+                return OPJ_FALSE;
+        }
+        p_header_size -= l_comp_room + 1;
+
+        opj_read_bytes(p_header_data,&l_comp_no,l_comp_room);                   /* Ccoc */
+        p_header_data += l_comp_room;
+        if (l_comp_no >= l_image->numcomps) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error reading COC marker (bad number of components)\n");
+                return OPJ_FALSE;
+        }
+
+        opj_read_bytes(p_header_data,&l_tcp->tccps[l_comp_no].csty,1);                  /* Scoc */
+        ++p_header_data ;
+
+        if (! opj_j2k_read_SPCod_SPCoc(p_j2k,l_comp_no,p_header_data,&p_header_size,p_manager)) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error reading COC marker\n");
+                return OPJ_FALSE;
+        }
+
+        if (p_header_size != 0) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error reading COC marker\n");
+                return OPJ_FALSE;
+        }
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_write_qcd(     opj_j2k_t *p_j2k,
+                                                        opj_stream_private_t *p_stream,
+                                                        opj_event_mgr_t * p_manager
+                            )
+{
+        OPJ_UINT32 l_qcd_size,l_remaining_size;
+        OPJ_BYTE * l_current_data = 00;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+        assert(p_stream != 00);
+
+        l_qcd_size = 4 + opj_j2k_get_SQcd_SQcc_size(p_j2k,p_j2k->m_current_tile_number,0);
+        l_remaining_size = l_qcd_size;
+
+        if (l_qcd_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) {
+                OPJ_BYTE *new_header_tile_data = (OPJ_BYTE *) opj_realloc(p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_qcd_size);
+                if (! new_header_tile_data) {
+                        opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data);
+                        p_j2k->m_specific_param.m_encoder.m_header_tile_data = NULL;
+                        p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0;
+                        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to write QCD marker\n");
+                        return OPJ_FALSE;
+                }
+                p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data;
+                p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_qcd_size;
+        }
+
+        l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
+
+        opj_write_bytes(l_current_data,J2K_MS_QCD,2);           /* QCD */
+        l_current_data += 2;
+
+        opj_write_bytes(l_current_data,l_qcd_size-2,2);         /* L_QCD */
+        l_current_data += 2;
+
+        l_remaining_size -= 4;
+
+        if (! opj_j2k_write_SQcd_SQcc(p_j2k,p_j2k->m_current_tile_number,0,l_current_data,&l_remaining_size,p_manager)) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error writing QCD marker\n");
+                return OPJ_FALSE;
+        }
+
+        if (l_remaining_size != 0) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error writing QCD marker\n");
+                return OPJ_FALSE;
+        }
+
+        if (opj_stream_write_data(p_stream, p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_qcd_size,p_manager) != l_qcd_size) {
+                return OPJ_FALSE;
+        }
+
+        return OPJ_TRUE;
+}
+
+/**
+ * Reads a QCD marker (Quantization defaults)
+ * @param       p_header_data   the data contained in the QCD box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the QCD marker.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_qcd (  opj_j2k_t *p_j2k,
+                                    OPJ_BYTE * p_header_data,
+                                    OPJ_UINT32 p_header_size,
+                                    opj_event_mgr_t * p_manager
+                                    )
+{
+        /* preconditions */
+        assert(p_header_data != 00);
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+
+        if (! opj_j2k_read_SQcd_SQcc(p_j2k,0,p_header_data,&p_header_size,p_manager)) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error reading QCD marker\n");
+                return OPJ_FALSE;
+        }
+
+        if (p_header_size != 0) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error reading QCD marker\n");
+                return OPJ_FALSE;
+        }
+
+        /* Apply the quantization parameters to other components of the current tile or the m_default_tcp */
+        opj_j2k_copy_tile_quantization_parameters(p_j2k);
+
+        return OPJ_TRUE;
+}
+
+#if 0
+OPJ_BOOL opj_j2k_write_qcc(     opj_j2k_t *p_j2k,
+                                                OPJ_UINT32 p_comp_no,
+                                                opj_stream_private_t *p_stream,
+                                                opj_event_mgr_t * p_manager
+                            )
+{
+        OPJ_UINT32 l_qcc_size,l_remaining_size;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+        assert(p_stream != 00);
+
+        l_qcc_size = 5 + opj_j2k_get_SQcd_SQcc_size(p_j2k,p_j2k->m_current_tile_number,p_comp_no);
+        l_qcc_size += p_j2k->m_private_image->numcomps <= 256 ? 0:1;
+        l_remaining_size = l_qcc_size;
+
+        if (l_qcc_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) {
+                OPJ_BYTE *new_header_tile_data = (OPJ_BYTE *) opj_realloc(p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_qcc_size);
+                if (! new_header_tile_data) {
+                        opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data);
+                        p_j2k->m_specific_param.m_encoder.m_header_tile_data = NULL;
+                        p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0;
+                        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to write QCC marker\n");
+                        return OPJ_FALSE;
+                }
+                p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data;
+                p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_qcc_size;
+        }
+
+        opj_j2k_write_qcc_in_memory(p_j2k,p_comp_no,p_j2k->m_specific_param.m_encoder.m_header_tile_data,&l_remaining_size,p_manager);
+
+        if (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_qcc_size,p_manager) != l_qcc_size) {
+                return OPJ_FALSE;
+        }
+
+        return OPJ_TRUE;
+}
+#endif
+
+#if 0
+void opj_j2k_write_qcc_in_memory(   opj_j2k_t *p_j2k,
+                                                                OPJ_UINT32 p_comp_no,
+                                                                OPJ_BYTE * p_data,
+                                                                OPJ_UINT32 * p_data_written,
+                                                                opj_event_mgr_t * p_manager
+                                    )
+{
+        OPJ_UINT32 l_qcc_size,l_remaining_size;
+        OPJ_BYTE * l_current_data = 00;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+
+        l_qcc_size = 6 + opj_j2k_get_SQcd_SQcc_size(p_j2k,p_j2k->m_current_tile_number,p_comp_no);
+        l_remaining_size = l_qcc_size;
+
+        l_current_data = p_data;
+
+        opj_write_bytes(l_current_data,J2K_MS_QCC,2);           /* QCC */
+        l_current_data += 2;
+
+        if (p_j2k->m_private_image->numcomps <= 256) {
+                --l_qcc_size;
+
+                opj_write_bytes(l_current_data,l_qcc_size-2,2);         /* L_QCC */
+                l_current_data += 2;
+
+                opj_write_bytes(l_current_data, p_comp_no, 1);  /* Cqcc */
+                ++l_current_data;
+
+                /* in the case only one byte is sufficient the last byte allocated is useless -> still do -6 for available */
+                l_remaining_size -= 6;
+        }
+        else {
+                opj_write_bytes(l_current_data,l_qcc_size-2,2);         /* L_QCC */
+                l_current_data += 2;
+
+                opj_write_bytes(l_current_data, p_comp_no, 2);  /* Cqcc */
+                l_current_data+=2;
+
+                l_remaining_size -= 6;
+        }
+
+        opj_j2k_write_SQcd_SQcc(p_j2k,p_j2k->m_current_tile_number,p_comp_no,l_current_data,&l_remaining_size,p_manager);
+
+        *p_data_written = l_qcc_size;
+}
+#endif
+
+OPJ_UINT32 opj_j2k_get_max_qcc_size (opj_j2k_t *p_j2k)
+{
+        return opj_j2k_get_max_coc_size(p_j2k);
+}
+
+/**
+ * Reads a QCC marker (Quantization component)
+ * @param       p_header_data   the data contained in the QCC box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the QCC marker.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_qcc(   opj_j2k_t *p_j2k,
+                                    OPJ_BYTE * p_header_data,
+                                    OPJ_UINT32 p_header_size,
+                                    opj_event_mgr_t * p_manager
+                                    )
+{
+        OPJ_UINT32 l_num_comp,l_comp_no;
+
+        /* preconditions */
+        assert(p_header_data != 00);
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+
+        l_num_comp = p_j2k->m_private_image->numcomps;
+
+        if (l_num_comp <= 256) {
+                if (p_header_size < 1) {
+                        opj_event_msg(p_manager, EVT_ERROR, "Error reading QCC marker\n");
+                        return OPJ_FALSE;
+                }
+                opj_read_bytes(p_header_data,&l_comp_no,1);
+                ++p_header_data;
+                --p_header_size;
+        }
+        else {
+                if (p_header_size < 2) {
+                        opj_event_msg(p_manager, EVT_ERROR, "Error reading QCC marker\n");
+                        return OPJ_FALSE;
+                }
+                opj_read_bytes(p_header_data,&l_comp_no,2);
+                p_header_data+=2;
+                p_header_size-=2;
+        }
+
+#ifdef USE_JPWL
+        if (p_j2k->m_cp.correct) {
+
+                static OPJ_UINT32 backup_compno = 0;
+
+                /* compno is negative or larger than the number of components!!! */
+                if (/*(l_comp_no < 0) ||*/ (l_comp_no >= l_num_comp)) {
+                        opj_event_msg(p_manager, EVT_ERROR,
+                                "JPWL: bad component number in QCC (%d out of a maximum of %d)\n",
+                                l_comp_no, l_num_comp);
+                        if (!JPWL_ASSUME) {
+                                opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n");
+                                return OPJ_FALSE;
+                        }
+                        /* we try to correct */
+                        l_comp_no = backup_compno % l_num_comp;
+                        opj_event_msg(p_manager, EVT_WARNING, "- trying to adjust this\n"
+                                "- setting component number to %d\n",
+                                l_comp_no);
+                }
+
+                /* keep your private count of tiles */
+                backup_compno++;
+        };
+#endif /* USE_JPWL */
+
+        if (l_comp_no >= p_j2k->m_private_image->numcomps) {
+                opj_event_msg(p_manager, EVT_ERROR,
+                              "Invalid component number: %d, regarding the number of components %d\n",
+                              l_comp_no, p_j2k->m_private_image->numcomps);
+                return OPJ_FALSE;
+        }
+
+        if (! opj_j2k_read_SQcd_SQcc(p_j2k,l_comp_no,p_header_data,&p_header_size,p_manager)) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error reading QCC marker\n");
+                return OPJ_FALSE;
+        }
+
+        if (p_header_size != 0) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error reading QCC marker\n");
+                return OPJ_FALSE;
+        }
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_write_poc(     opj_j2k_t *p_j2k,
+                                                        opj_stream_private_t *p_stream,
+                                                        opj_event_mgr_t * p_manager
+                            )
+{
+        OPJ_UINT32 l_nb_comp;
+        OPJ_UINT32 l_nb_poc;
+        OPJ_UINT32 l_poc_size;
+        OPJ_UINT32 l_written_size = 0;
+        opj_tcp_t *l_tcp = 00;
+        OPJ_UINT32 l_poc_room;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+        assert(p_stream != 00);
+
+        l_tcp = &p_j2k->m_cp.tcps[p_j2k->m_current_tile_number];
+        l_nb_comp = p_j2k->m_private_image->numcomps;
+        l_nb_poc = 1 + l_tcp->numpocs;
+
+        if (l_nb_comp <= 256) {
+                l_poc_room = 1;
+        }
+        else {
+                l_poc_room = 2;
+        }
+        l_poc_size = 4 + (5 + 2 * l_poc_room) * l_nb_poc;
+
+        if (l_poc_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) {
+                OPJ_BYTE *new_header_tile_data = (OPJ_BYTE *) opj_realloc(p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_poc_size);
+                if (! new_header_tile_data) {
+                        opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data);
+                        p_j2k->m_specific_param.m_encoder.m_header_tile_data = NULL;
+                        p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0;
+                        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to write POC marker\n");
+                        return OPJ_FALSE;
+                }
+                p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data;
+                p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_poc_size;
+        }
+
+        opj_j2k_write_poc_in_memory(p_j2k,p_j2k->m_specific_param.m_encoder.m_header_tile_data,&l_written_size,p_manager);
+
+        if (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_poc_size,p_manager) != l_poc_size) {
+                return OPJ_FALSE;
+        }
+
+        return OPJ_TRUE;
+}
+
+void opj_j2k_write_poc_in_memory(   opj_j2k_t *p_j2k,
+                                                                OPJ_BYTE * p_data,
+                                                                OPJ_UINT32 * p_data_written,
+                                                                opj_event_mgr_t * p_manager
+                                    )
+{
+        OPJ_UINT32 i;
+        OPJ_BYTE * l_current_data = 00;
+        OPJ_UINT32 l_nb_comp;
+        OPJ_UINT32 l_nb_poc;
+        OPJ_UINT32 l_poc_size;
+        opj_image_t *l_image = 00;
+        opj_tcp_t *l_tcp = 00;
+        opj_tccp_t *l_tccp = 00;
+        opj_poc_t *l_current_poc = 00;
+        OPJ_UINT32 l_poc_room;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+
+        l_tcp = &p_j2k->m_cp.tcps[p_j2k->m_current_tile_number];
+        l_tccp = &l_tcp->tccps[0];
+        l_image = p_j2k->m_private_image;
+        l_nb_comp = l_image->numcomps;
+        l_nb_poc = 1 + l_tcp->numpocs;
+
+        if (l_nb_comp <= 256) {
+                l_poc_room = 1;
+        }
+        else {
+                l_poc_room = 2;
+        }
+
+        l_poc_size = 4 + (5 + 2 * l_poc_room) * l_nb_poc;
+
+        l_current_data = p_data;
+
+        opj_write_bytes(l_current_data,J2K_MS_POC,2);                                   /* POC  */
+        l_current_data += 2;
+
+        opj_write_bytes(l_current_data,l_poc_size-2,2);                                 /* Lpoc */
+        l_current_data += 2;
+
+        l_current_poc =  l_tcp->pocs;
+        for (i = 0; i < l_nb_poc; ++i) {
+                opj_write_bytes(l_current_data,l_current_poc->resno0,1);                                /* RSpoc_i */
+                ++l_current_data;
+
+                opj_write_bytes(l_current_data,l_current_poc->compno0,l_poc_room);              /* CSpoc_i */
+                l_current_data+=l_poc_room;
+
+                opj_write_bytes(l_current_data,l_current_poc->layno1,2);                                /* LYEpoc_i */
+                l_current_data+=2;
+
+                opj_write_bytes(l_current_data,l_current_poc->resno1,1);                                /* REpoc_i */
+                ++l_current_data;
+
+                opj_write_bytes(l_current_data,l_current_poc->compno1,l_poc_room);              /* CEpoc_i */
+                l_current_data+=l_poc_room;
+
+                opj_write_bytes(l_current_data,l_current_poc->prg,1);                                   /* Ppoc_i */
+                ++l_current_data;
+
+                /* change the value of the max layer according to the actual number of layers in the file, components and resolutions*/
+                l_current_poc->layno1 = (OPJ_UINT32)opj_int_min((OPJ_INT32)l_current_poc->layno1, (OPJ_INT32)l_tcp->numlayers);
+                l_current_poc->resno1 = (OPJ_UINT32)opj_int_min((OPJ_INT32)l_current_poc->resno1, (OPJ_INT32)l_tccp->numresolutions);
+                l_current_poc->compno1 = (OPJ_UINT32)opj_int_min((OPJ_INT32)l_current_poc->compno1, (OPJ_INT32)l_nb_comp);
+
+                ++l_current_poc;
+        }
+
+        *p_data_written = l_poc_size;
+}
+
+OPJ_UINT32 opj_j2k_get_max_poc_size(opj_j2k_t *p_j2k)
+{
+        opj_tcp_t * l_tcp = 00;
+        OPJ_UINT32 l_nb_tiles = 0;
+        OPJ_UINT32 l_max_poc = 0;
+        OPJ_UINT32 i;
+
+        l_tcp = p_j2k->m_cp.tcps;
+        l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw;
+
+        for (i=0;i<l_nb_tiles;++i) {
+                l_max_poc = opj_uint_max(l_max_poc,l_tcp->numpocs);
+                ++l_tcp;
+        }
+
+        ++l_max_poc;
+
+        return 4 + 9 * l_max_poc;
+}
+
+OPJ_UINT32 opj_j2k_get_max_toc_size (opj_j2k_t *p_j2k)
+{
+        OPJ_UINT32 i;
+        OPJ_UINT32 l_nb_tiles;
+        OPJ_UINT32 l_max = 0;
+        opj_tcp_t * l_tcp = 00;
+
+        l_tcp = p_j2k->m_cp.tcps;
+        l_nb_tiles = p_j2k->m_cp.tw * p_j2k->m_cp.th ;
+
+        for (i=0;i<l_nb_tiles;++i) {
+                l_max = opj_uint_max(l_max,l_tcp->m_nb_tile_parts);
+
+                ++l_tcp;
+        }
+
+        return 12 * l_max;
+}
+
+OPJ_UINT32 opj_j2k_get_specific_header_sizes(opj_j2k_t *p_j2k)
+{
+        OPJ_UINT32 l_nb_bytes = 0;
+        OPJ_UINT32 l_nb_comps;
+        OPJ_UINT32 l_coc_bytes,l_qcc_bytes;
+
+        l_nb_comps = p_j2k->m_private_image->numcomps - 1;
+        l_nb_bytes += opj_j2k_get_max_toc_size(p_j2k);
+
+        if (p_j2k->m_cp.m_specific_param.m_enc.m_cinema == 0) {
+                l_coc_bytes = opj_j2k_get_max_coc_size(p_j2k);
+                l_nb_bytes += l_nb_comps * l_coc_bytes;
+
+                l_qcc_bytes = opj_j2k_get_max_qcc_size(p_j2k);
+                l_nb_bytes += l_nb_comps * l_qcc_bytes;
+        }
+
+        l_nb_bytes += opj_j2k_get_max_poc_size(p_j2k);
+
+        /*** DEVELOPER CORNER, Add room for your headers ***/
+
+        return l_nb_bytes;
+}
+
+/**
+ * Reads a POC marker (Progression Order Change)
+ *
+ * @param       p_header_data   the data contained in the POC box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the POC marker.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_poc (  opj_j2k_t *p_j2k,
+                                    OPJ_BYTE * p_header_data,
+                                    OPJ_UINT32 p_header_size,
+                                    opj_event_mgr_t * p_manager
+                                    )
+{
+        OPJ_UINT32 i, l_nb_comp, l_tmp;
+        opj_image_t * l_image = 00;
+        OPJ_UINT32 l_old_poc_nb, l_current_poc_nb, l_current_poc_remaining;
+        OPJ_UINT32 l_chunk_size, l_comp_room;
+
+        opj_cp_t *l_cp = 00;
+        opj_tcp_t *l_tcp = 00;
+        opj_poc_t *l_current_poc = 00;
+
+        /* preconditions */
+        assert(p_header_data != 00);
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+
+        l_image = p_j2k->m_private_image;
+        l_nb_comp = l_image->numcomps;
+        if (l_nb_comp <= 256) {
+                l_comp_room = 1;
+        }
+        else {
+                l_comp_room = 2;
+        }
+        l_chunk_size = 5 + 2 * l_comp_room;
+        l_current_poc_nb = p_header_size / l_chunk_size;
+        l_current_poc_remaining = p_header_size % l_chunk_size;
+
+        if ((l_current_poc_nb <= 0) || (l_current_poc_remaining != 0)) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error reading POC marker\n");
+                return OPJ_FALSE;
+        }
+
+        l_cp = &(p_j2k->m_cp);
+        l_tcp = (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH) ?
+                                &l_cp->tcps[p_j2k->m_current_tile_number] :
+                                p_j2k->m_specific_param.m_decoder.m_default_tcp;
+        l_old_poc_nb = l_tcp->POC ? l_tcp->numpocs + 1 : 0;
+        l_current_poc_nb += l_old_poc_nb;
+
+        if(l_current_poc_nb >= 32)
+          {
+          opj_event_msg(p_manager, EVT_ERROR, "Too many POCs %d\n", l_current_poc_nb);
+          return OPJ_FALSE;
+          }
+        assert(l_current_poc_nb < 32);
+
+        /* now poc is in use.*/
+        l_tcp->POC = 1;
+
+        l_current_poc = &l_tcp->pocs[l_old_poc_nb];
+        for     (i = l_old_poc_nb; i < l_current_poc_nb; ++i) {
+                opj_read_bytes(p_header_data,&(l_current_poc->resno0),1);                               /* RSpoc_i */
+                ++p_header_data;
+                opj_read_bytes(p_header_data,&(l_current_poc->compno0),l_comp_room);    /* CSpoc_i */
+                p_header_data+=l_comp_room;
+                opj_read_bytes(p_header_data,&(l_current_poc->layno1),2);                               /* LYEpoc_i */
+                /* make sure layer end is in acceptable bounds */
+                l_current_poc->layno1 = opj_uint_min(l_current_poc->layno1, l_tcp->numlayers);
+                p_header_data+=2;
+                opj_read_bytes(p_header_data,&(l_current_poc->resno1),1);                               /* REpoc_i */
+                ++p_header_data;
+                opj_read_bytes(p_header_data,&(l_current_poc->compno1),l_comp_room);    /* CEpoc_i */
+                p_header_data+=l_comp_room;
+                opj_read_bytes(p_header_data,&l_tmp,1);                                                                 /* Ppoc_i */
+                ++p_header_data;
+                l_current_poc->prg = (OPJ_PROG_ORDER) l_tmp;
+                /* make sure comp is in acceptable bounds */
+                l_current_poc->compno1 = opj_uint_min(l_current_poc->compno1, l_nb_comp);
+                ++l_current_poc;
+        }
+
+        l_tcp->numpocs = l_current_poc_nb - 1;
+        return OPJ_TRUE;
+}
+
+/**
+ * Reads a CRG marker (Component registration)
+ *
+ * @param       p_header_data   the data contained in the TLM box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the TLM marker.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_crg (  opj_j2k_t *p_j2k,
+                                    OPJ_BYTE * p_header_data,
+                                    OPJ_UINT32 p_header_size,
+                                    opj_event_mgr_t * p_manager
+                                    )
+{
+        OPJ_UINT32 l_nb_comp;
+        /* preconditions */
+        assert(p_header_data != 00);
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+
+        l_nb_comp = p_j2k->m_private_image->numcomps;
+
+        if (p_header_size != l_nb_comp *4) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error reading CRG marker\n");
+                return OPJ_FALSE;
+        }
+        /* Do not care of this at the moment since only local variables are set here */
+        /*
+        for
+                (i = 0; i < l_nb_comp; ++i)
+        {
+                opj_read_bytes(p_header_data,&l_Xcrg_i,2);                              // Xcrg_i
+                p_header_data+=2;
+                opj_read_bytes(p_header_data,&l_Ycrg_i,2);                              // Xcrg_i
+                p_header_data+=2;
+        }
+        */
+        return OPJ_TRUE;
+}
+
+/**
+ * Reads a TLM marker (Tile Length Marker)
+ *
+ * @param       p_header_data   the data contained in the TLM box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the TLM marker.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_tlm (  opj_j2k_t *p_j2k,
+                                    OPJ_BYTE * p_header_data,
+                                    OPJ_UINT32 p_header_size,
+                                    opj_event_mgr_t * p_manager
+                                    )
+{
+        OPJ_UINT32 l_Ztlm, l_Stlm, l_ST, l_SP, l_tot_num_tp_remaining, l_quotient, l_Ptlm_size;
+        /* preconditions */
+        assert(p_header_data != 00);
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+
+        if (p_header_size < 2) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error reading TLM marker\n");
+                return OPJ_FALSE;
+        }
+        p_header_size -= 2;
+
+        opj_read_bytes(p_header_data,&l_Ztlm,1);                                /* Ztlm */
+        ++p_header_data;
+        opj_read_bytes(p_header_data,&l_Stlm,1);                                /* Stlm */
+        ++p_header_data;
+
+        l_ST = ((l_Stlm >> 4) & 0x3);
+        l_SP = (l_Stlm >> 6) & 0x1;
+
+        l_Ptlm_size = (l_SP + 1) * 2;
+        l_quotient = l_Ptlm_size + l_ST;
+
+        l_tot_num_tp_remaining = p_header_size % l_quotient;
+
+        if (l_tot_num_tp_remaining != 0) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error reading TLM marker\n");
+                return OPJ_FALSE;
+        }
+        /* FIXME Do not care of this at the moment since only local variables are set here */
+        /*
+        for
+                (i = 0; i < l_tot_num_tp; ++i)
+        {
+                opj_read_bytes(p_header_data,&l_Ttlm_i,l_ST);                           // Ttlm_i
+                p_header_data += l_ST;
+                opj_read_bytes(p_header_data,&l_Ptlm_i,l_Ptlm_size);            // Ptlm_i
+                p_header_data += l_Ptlm_size;
+        }*/
+        return OPJ_TRUE;
+}
+
+/**
+ * Reads a PLM marker (Packet length, main header marker)
+ *
+ * @param       p_header_data   the data contained in the TLM box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the TLM marker.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_plm (  opj_j2k_t *p_j2k,
+                                    OPJ_BYTE * p_header_data,
+                                    OPJ_UINT32 p_header_size,
+                                    opj_event_mgr_t * p_manager
+                                    )
+{
+        /* preconditions */
+        assert(p_header_data != 00);
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+
+        if (p_header_size < 1) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error reading PLM marker\n");
+                return OPJ_FALSE;
+        }
+        /* Do not care of this at the moment since only local variables are set here */
+        /*
+        opj_read_bytes(p_header_data,&l_Zplm,1);                                        // Zplm
+        ++p_header_data;
+        --p_header_size;
+
+        while
+                (p_header_size > 0)
+        {
+                opj_read_bytes(p_header_data,&l_Nplm,1);                                // Nplm
+                ++p_header_data;
+                p_header_size -= (1+l_Nplm);
+                if
+                        (p_header_size < 0)
+                {
+                        opj_event_msg(p_manager, EVT_ERROR, "Error reading PLM marker\n");
+                        return false;
+                }
+                for
+                        (i = 0; i < l_Nplm; ++i)
+                {
+                        opj_read_bytes(p_header_data,&l_tmp,1);                         // Iplm_ij
+                        ++p_header_data;
+                        // take only the last seven bytes
+                        l_packet_len |= (l_tmp & 0x7f);
+                        if
+                                (l_tmp & 0x80)
+                        {
+                                l_packet_len <<= 7;
+                        }
+                        else
+                        {
+                // store packet length and proceed to next packet
+                                l_packet_len = 0;
+                        }
+                }
+                if
+                        (l_packet_len != 0)
+                {
+                        opj_event_msg(p_manager, EVT_ERROR, "Error reading PLM marker\n");
+                        return false;
+                }
+        }
+        */
+        return OPJ_TRUE;
+}
+
+/**
+ * Reads a PLT marker (Packet length, tile-part header)
+ *
+ * @param       p_header_data   the data contained in the PLT box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the PLT marker.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_plt (  opj_j2k_t *p_j2k,
+                                    OPJ_BYTE * p_header_data,
+                                    OPJ_UINT32 p_header_size,
+                                    opj_event_mgr_t * p_manager
+                                    )
+{
+        OPJ_UINT32 l_Zplt, l_tmp, l_packet_len = 0, i;
+
+        /* preconditions */
+        assert(p_header_data != 00);
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+
+        if (p_header_size < 1) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error reading PLT marker\n");
+                return OPJ_FALSE;
+        }
+
+        opj_read_bytes(p_header_data,&l_Zplt,1);                /* Zplt */
+        ++p_header_data;
+        --p_header_size;
+
+        for (i = 0; i < p_header_size; ++i) {
+                opj_read_bytes(p_header_data,&l_tmp,1);         /* Iplt_ij */
+                ++p_header_data;
+                /* take only the last seven bytes */
+                l_packet_len |= (l_tmp & 0x7f);
+                if (l_tmp & 0x80) {
+                        l_packet_len <<= 7;
+                }
+                else {
+            /* store packet length and proceed to next packet */
+                        l_packet_len = 0;
+                }
+        }
+
+        if (l_packet_len != 0) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error reading PLT marker\n");
+                return OPJ_FALSE;
+        }
+
+        return OPJ_TRUE;
+}
+
+#if 0
+OPJ_BOOL j2k_read_ppm_v2 (
+                                                opj_j2k_t *p_j2k,
+                                                OPJ_BYTE * p_header_data,
+                                                OPJ_UINT32 p_header_size,
+                                                struct opj_event_mgr * p_manager
+                                        )
+{
+
+        opj_cp_t *l_cp = 00;
+        OPJ_UINT32 l_remaining_data, l_Z_ppm, l_N_ppm;
+
+        /* preconditions */
+        assert(p_header_data != 00);
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+
+        if (p_header_size < 1) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error reading PPM marker\n");
+                return OPJ_FALSE;
+        }
+
+        l_cp = &(p_j2k->m_cp);
+        l_cp->ppm = 1;
+
+        opj_read_bytes(p_header_data,&l_Z_ppm,1);               /* Z_ppm */
+        ++p_header_data;
+        --p_header_size;
+
+        /* First PPM marker */
+        if (l_Z_ppm == 0) {
+                if (p_header_size < 4) {
+                        opj_event_msg(p_manager, EVT_ERROR, "Error reading PPM marker\n");
+                        return OPJ_FALSE;
+                }
+
+                opj_read_bytes(p_header_data,&l_N_ppm,4);               /* N_ppm */
+                p_header_data+=4;
+                p_header_size-=4;
+
+                /* First PPM marker: Initialization */
+                l_cp->ppm_len = l_N_ppm;
+                l_cp->ppm_data_size = 0;
+
+                l_cp->ppm_buffer = (OPJ_BYTE *) opj_malloc(l_cp->ppm_len);
+                if (l_cp->ppm_buffer == 00) {
+                        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory reading ppm marker\n");
+                        return OPJ_FALSE;
+                }
+                memset(l_cp->ppm_buffer,0,l_cp->ppm_len);
+
+                l_cp->ppm_data = l_cp->ppm_buffer;
+        }
+
+        while (1) {
+                if (l_cp->ppm_data_size == l_cp->ppm_len) {
+                        if (p_header_size >= 4) {
+                                /* read a N_ppm */
+                                opj_read_bytes(p_header_data,&l_N_ppm,4);               /* N_ppm */
+                                p_header_data+=4;
+                                p_header_size-=4;
+                                l_cp->ppm_len += l_N_ppm ;
+
+                                OPJ_BYTE *new_ppm_buffer = (OPJ_BYTE *) opj_realloc(l_cp->ppm_buffer, l_cp->ppm_len);
+                                if (! new_ppm_buffer) {
+                                        opj_free(l_cp->ppm_buffer);
+                                        l_cp->ppm_buffer = NULL;
+                                        l_cp->ppm_len = 0;
+                                        l_cp->ppm_data = NULL;
+                                        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory reading ppm marker\n");
+                                        return OPJ_FALSE;
+                                }
+                                l_cp->ppm_buffer = new_ppm_buffer;
+                                memset(l_cp->ppm_buffer+l_cp->ppm_data_size,0,l_N_ppm);
+                                l_cp->ppm_data = l_cp->ppm_buffer;
+                        }
+                        else {
+                                return OPJ_FALSE;
+                        }
+                }
+
+                l_remaining_data = l_cp->ppm_len - l_cp->ppm_data_size;
+
+                if (l_remaining_data <= p_header_size) {
+                        /* we must store less information than available in the packet */
+                        memcpy(l_cp->ppm_buffer + l_cp->ppm_data_size , p_header_data , l_remaining_data);
+                        l_cp->ppm_data_size = l_cp->ppm_len;
+                        p_header_size -= l_remaining_data;
+                        p_header_data += l_remaining_data;
+                }
+                else {
+                        memcpy(l_cp->ppm_buffer + l_cp->ppm_data_size , p_header_data , p_header_size);
+                        l_cp->ppm_data_size += p_header_size;
+                        p_header_data += p_header_size;
+                        p_header_size = 0;
+                        break;
+                }
+        }
+
+        return OPJ_TRUE;
+}
+#endif
+
+OPJ_BOOL j2k_read_ppm_v3 (
+                                                opj_j2k_t *p_j2k,
+                                                OPJ_BYTE * p_header_data,
+                                                OPJ_UINT32 p_header_size,
+                                                struct opj_event_mgr * p_manager
+                                        )
+{
+        opj_cp_t *l_cp = 00;
+        OPJ_UINT32 l_remaining_data, l_Z_ppm, l_N_ppm;
+
+        /* preconditions */
+        assert(p_header_data != 00);
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+
+        /* Minimum size of PPM marker is equal to the size of Zppm element */
+        if (p_header_size < 1) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error reading PPM marker\n");
+                return OPJ_FALSE;
+        }
+
+        l_cp = &(p_j2k->m_cp);
+        l_cp->ppm = 1;
+
+        opj_read_bytes(p_header_data,&l_Z_ppm,1);               /* Z_ppm */
+        ++p_header_data;
+        --p_header_size;
+
+        /* First PPM marker */
+        if (l_Z_ppm == 0) {
+                /* We need now at least the Nppm^0 element */
+                if (p_header_size < 4) {
+                        opj_event_msg(p_manager, EVT_ERROR, "Error reading PPM marker\n");
+                        return OPJ_FALSE;
+                }
+
+                opj_read_bytes(p_header_data,&l_N_ppm,4);               /* First N_ppm */
+                p_header_data+=4;
+                p_header_size-=4;
+
+                /* sanity check: how much bytes is left for Ippm */
+                if( p_header_size < l_N_ppm )
+                  {
+                  opj_event_msg(p_manager, EVT_ERROR, "Not enough bytes (%u) to hold Ippm series (%u), Index (%d)\n", p_header_size, l_N_ppm, l_Z_ppm );
+                  opj_free(l_cp->ppm_data);
+                  l_cp->ppm_data = NULL;
+                  l_cp->ppm_buffer = NULL;
+                  l_cp->ppm = 0; /* do not use PPM */
+                  return OPJ_TRUE;
+                  }
+
+                /* First PPM marker: Initialization */
+                l_cp->ppm_len = l_N_ppm;
+                l_cp->ppm_data_read = 0;
+
+                l_cp->ppm_data = (OPJ_BYTE *) opj_malloc(l_cp->ppm_len);
+                l_cp->ppm_buffer = l_cp->ppm_data;
+                if (l_cp->ppm_data == 00) {
+                        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read ppm marker\n");
+                        return OPJ_FALSE;
+                }
+                memset(l_cp->ppm_data,0,l_cp->ppm_len);
+
+                l_cp->ppm_data_current = l_cp->ppm_data;
+
+                /*l_cp->ppm_data = l_cp->ppm_buffer;*/
+        }
+        else {
+                if (p_header_size < 4) {
+                        opj_event_msg(p_manager, EVT_WARNING, "Empty PPM marker\n");
+                        return OPJ_TRUE;
+                }
+                else {
+                        /* Uncompleted Ippm series in the previous PPM marker?*/
+                        if (l_cp->ppm_data_read < l_cp->ppm_len) {
+                                /* Get the place where add the remaining Ippm series*/
+                                l_cp->ppm_data_current = &(l_cp->ppm_data[l_cp->ppm_data_read]);
+                                l_N_ppm = l_cp->ppm_len - l_cp->ppm_data_read;
+                        }
+                        else {
+                                OPJ_BYTE *new_ppm_data;
+                                opj_read_bytes(p_header_data,&l_N_ppm,4);               /* First N_ppm */
+                                p_header_data+=4;
+                                p_header_size-=4;
+
+                                /* sanity check: how much bytes is left for Ippm */
+                                if( p_header_size < l_N_ppm )
+                                  {
+                                  opj_event_msg(p_manager, EVT_ERROR, "Not enough bytes (%u) to hold Ippm series (%u), Index (%d)\n", p_header_size, l_N_ppm, l_Z_ppm );
+                                  opj_free(l_cp->ppm_data);
+                                  l_cp->ppm_data = NULL;
+                                  l_cp->ppm_buffer = NULL;
+                                  l_cp->ppm = 0; /* do not use PPM */
+                                  return OPJ_TRUE;
+                                  }
+                                /* Increase the size of ppm_data to add the new Ippm series*/
+                                assert(l_cp->ppm_data == l_cp->ppm_buffer && "We need ppm_data and ppm_buffer to be the same when reallocating");
+                                new_ppm_data = (OPJ_BYTE *) opj_realloc(l_cp->ppm_data, l_cp->ppm_len + l_N_ppm);
+                                if (! new_ppm_data) {
+                                        opj_free(l_cp->ppm_data);
+                                        l_cp->ppm_data = NULL;
+                                        l_cp->ppm_buffer = NULL;  /* TODO: no need for a new local variable: ppm_buffer and ppm_data are enough */
+                                        l_cp->ppm_len = 0;
+                                        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to increase the size of ppm_data to add the new Ippm series\n");
+                                        return OPJ_FALSE;
+                                }
+                                l_cp->ppm_data = new_ppm_data;
+                                l_cp->ppm_buffer = l_cp->ppm_data;
+
+                                /* Keep the position of the place where concatenate the new series*/
+                                l_cp->ppm_data_current = &(l_cp->ppm_data[l_cp->ppm_len]);
+                                l_cp->ppm_len += l_N_ppm;
+                        }
+                }
+        }
+
+        l_remaining_data = p_header_size;
+
+        while (l_remaining_data >= l_N_ppm) {
+                /* read a complete Ippm series*/
+                memcpy(l_cp->ppm_data_current, p_header_data, l_N_ppm);
+                p_header_size -= l_N_ppm;
+                p_header_data += l_N_ppm;
+
+                l_cp->ppm_data_read += l_N_ppm; /* Increase the number of data read*/
+
+                if (p_header_size)
+                {
+                        opj_read_bytes(p_header_data,&l_N_ppm,4);               /* N_ppm^i */
+                        p_header_data+=4;
+                        p_header_size-=4;
+                }
+                else {
+                        l_remaining_data = p_header_size;
+                        break;
+                }
+
+                l_remaining_data = p_header_size;
+
+                /* Next Ippm series is a complete series ?*/
+                if (l_remaining_data >= l_N_ppm) {
+                        OPJ_BYTE *new_ppm_data;
+                        /* Increase the size of ppm_data to add the new Ippm series*/
+                        assert(l_cp->ppm_data == l_cp->ppm_buffer && "We need ppm_data and ppm_buffer to be the same when reallocating");
+                        new_ppm_data = (OPJ_BYTE *) opj_realloc(l_cp->ppm_data, l_cp->ppm_len + l_N_ppm);
+                        if (! new_ppm_data) {
+                                opj_free(l_cp->ppm_data);
+                                l_cp->ppm_data = NULL;
+                                l_cp->ppm_buffer = NULL;  /* TODO: no need for a new local variable: ppm_buffer and ppm_data are enough */
+                                l_cp->ppm_len = 0;
+                                opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to increase the size of ppm_data to add the new (complete) Ippm series\n");
+                                return OPJ_FALSE;
+                        }
+                        l_cp->ppm_data = new_ppm_data;
+                        l_cp->ppm_buffer = l_cp->ppm_data;
+
+                        /* Keep the position of the place where concatenate the new series */
+                        l_cp->ppm_data_current = &(l_cp->ppm_data[l_cp->ppm_len]);
+                        l_cp->ppm_len += l_N_ppm;
+                }
+
+        }
+
+        /* Need to read an incomplete Ippm series*/
+        if (l_remaining_data) {
+                OPJ_BYTE *new_ppm_data;
+                assert(l_cp->ppm_data == l_cp->ppm_buffer && "We need ppm_data and ppm_buffer to be the same when reallocating");
+                new_ppm_data = (OPJ_BYTE *) opj_realloc(l_cp->ppm_data, l_cp->ppm_len + l_N_ppm);
+                if (! new_ppm_data) {
+                        opj_free(l_cp->ppm_data);
+                        l_cp->ppm_data = NULL;
+                        l_cp->ppm_buffer = NULL;  /* TODO: no need for a new local variable: ppm_buffer and ppm_data are enough */
+                        l_cp->ppm_len = 0;
+                        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to increase the size of ppm_data to add the new (incomplete) Ippm series\n");
+                        return OPJ_FALSE;
+                }
+                l_cp->ppm_data = new_ppm_data;
+                l_cp->ppm_buffer = l_cp->ppm_data;
+
+                /* Keep the position of the place where concatenate the new series*/
+                l_cp->ppm_data_current = &(l_cp->ppm_data[l_cp->ppm_len]);
+                l_cp->ppm_len += l_N_ppm;
+
+                /* Read incomplete Ippm series*/
+                memcpy(l_cp->ppm_data_current, p_header_data, l_remaining_data);
+                p_header_size -= l_remaining_data;
+                p_header_data += l_remaining_data;
+
+                l_cp->ppm_data_read += l_remaining_data; /* Increase the number of data read*/
+        }
+
+#ifdef CLEAN_MSD
+
+                if (l_cp->ppm_data_size == l_cp->ppm_len) {
+                        if (p_header_size >= 4) {
+                                /* read a N_ppm*/
+                                opj_read_bytes(p_header_data,&l_N_ppm,4);               /* N_ppm */
+                                p_header_data+=4;
+                                p_header_size-=4;
+                                l_cp->ppm_len += l_N_ppm ;
+
+                                OPJ_BYTE *new_ppm_buffer = (OPJ_BYTE *) opj_realloc(l_cp->ppm_buffer, l_cp->ppm_len);
+                                if (! new_ppm_buffer) {
+                                        opj_free(l_cp->ppm_buffer);
+                                        l_cp->ppm_buffer = NULL;
+                                        l_cp->ppm_len = 0;
+                                        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read ppm marker\n");
+                                        return OPJ_FALSE;
+                                }
+                                l_cp->ppm_buffer = new_ppm_buffer;
+                                memset(l_cp->ppm_buffer+l_cp->ppm_data_size,0,l_N_ppm);
+
+                                l_cp->ppm_data = l_cp->ppm_buffer;
+                        }
+                        else {
+                                return OPJ_FALSE;
+                        }
+                }
+
+                l_remaining_data = l_cp->ppm_len - l_cp->ppm_data_size;
+
+                if (l_remaining_data <= p_header_size) {
+                        /* we must store less information than available in the packet */
+                        memcpy(l_cp->ppm_buffer + l_cp->ppm_data_size , p_header_data , l_remaining_data);
+                        l_cp->ppm_data_size = l_cp->ppm_len;
+                        p_header_size -= l_remaining_data;
+                        p_header_data += l_remaining_data;
+                }
+                else {
+                        memcpy(l_cp->ppm_buffer + l_cp->ppm_data_size , p_header_data , p_header_size);
+                        l_cp->ppm_data_size += p_header_size;
+                        p_header_data += p_header_size;
+                        p_header_size = 0;
+                        break;
+                }
+        }
+#endif
+        return OPJ_TRUE;
+}
+
+/**
+ * Reads a PPT marker (Packed packet headers, tile-part header)
+ *
+ * @param       p_header_data   the data contained in the PPT box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the PPT marker.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_ppt (  opj_j2k_t *p_j2k,
+                                    OPJ_BYTE * p_header_data,
+                                    OPJ_UINT32 p_header_size,
+                                    opj_event_mgr_t * p_manager
+                                    )
+{
+        opj_cp_t *l_cp = 00;
+        opj_tcp_t *l_tcp = 00;
+        OPJ_UINT32 l_Z_ppt;
+
+        /* preconditions */
+        assert(p_header_data != 00);
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+
+        /* We need to have the Z_ppt element at minimum */
+        if (p_header_size < 1) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error reading PPT marker\n");
+                return OPJ_FALSE;
+        }
+
+        l_cp = &(p_j2k->m_cp);
+        if (l_cp->ppm){
+                opj_event_msg(p_manager, EVT_ERROR, "Error reading PPT marker: packet header have been previously found in the main header (PPM marker).\n");
+                return OPJ_FALSE;
+        }
+
+        l_tcp = &(l_cp->tcps[p_j2k->m_current_tile_number]);
+        l_tcp->ppt = 1;
+
+        opj_read_bytes(p_header_data,&l_Z_ppt,1);               /* Z_ppt */
+        ++p_header_data;
+        --p_header_size;
+
+        /* Allocate buffer to read the packet header */
+        if (l_Z_ppt == 0) {
+                /* First PPT marker */
+                l_tcp->ppt_data_size = 0;
+                l_tcp->ppt_len = p_header_size;
+
+                opj_free(l_tcp->ppt_buffer);
+                l_tcp->ppt_buffer = (OPJ_BYTE *) opj_calloc(l_tcp->ppt_len, sizeof(OPJ_BYTE) );
+                if (l_tcp->ppt_buffer == 00) {
+                        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPT marker\n");
+                        return OPJ_FALSE;
+                }
+                l_tcp->ppt_data = l_tcp->ppt_buffer;
+
+                /* memset(l_tcp->ppt_buffer,0,l_tcp->ppt_len); */
+        }
+        else {
+                OPJ_BYTE *new_ppt_buffer;
+                l_tcp->ppt_len += p_header_size;
+
+                new_ppt_buffer = (OPJ_BYTE *) opj_realloc(l_tcp->ppt_buffer, l_tcp->ppt_len);
+                if (! new_ppt_buffer) {
+                        opj_free(l_tcp->ppt_buffer);
+                        l_tcp->ppt_buffer = NULL;
+                        l_tcp->ppt_len = 0;
+                        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPT marker\n");
+                        return OPJ_FALSE;
+                }
+                l_tcp->ppt_buffer = new_ppt_buffer;
+                l_tcp->ppt_data = l_tcp->ppt_buffer;
+
+                memset(l_tcp->ppt_buffer+l_tcp->ppt_data_size,0,p_header_size);
+        }
+
+        /* Read packet header from buffer */
+        memcpy(l_tcp->ppt_buffer+l_tcp->ppt_data_size,p_header_data,p_header_size);
+
+        l_tcp->ppt_data_size += p_header_size;
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_write_tlm(     opj_j2k_t *p_j2k,
+                                                        opj_stream_private_t *p_stream,
+                                                        opj_event_mgr_t * p_manager
+                            )
+{
+        OPJ_BYTE * l_current_data = 00;
+        OPJ_UINT32 l_tlm_size;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+        assert(p_stream != 00);
+
+        l_tlm_size = 6 + (5*p_j2k->m_specific_param.m_encoder.m_total_tile_parts);
+
+        if (l_tlm_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) {
+                OPJ_BYTE *new_header_tile_data = (OPJ_BYTE *) opj_realloc(p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_tlm_size);
+                if (! new_header_tile_data) {
+                        opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data);
+                        p_j2k->m_specific_param.m_encoder.m_header_tile_data = NULL;
+                        p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0;
+                        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to write TLM marker\n");
+                        return OPJ_FALSE;
+                }
+                p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data;
+                p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_tlm_size;
+        }
+
+        l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
+
+        /* change the way data is written to avoid seeking if possible */
+        /* TODO */
+        p_j2k->m_specific_param.m_encoder.m_tlm_start = opj_stream_tell(p_stream);
+
+        opj_write_bytes(l_current_data,J2K_MS_TLM,2);                                   /* TLM */
+        l_current_data += 2;
+
+        opj_write_bytes(l_current_data,l_tlm_size-2,2);                                 /* Lpoc */
+        l_current_data += 2;
+
+        opj_write_bytes(l_current_data,0,1);                                                    /* Ztlm=0*/
+        ++l_current_data;
+
+        opj_write_bytes(l_current_data,0x50,1);                                                 /* Stlm ST=1(8bits-255 tiles max),SP=1(Ptlm=32bits) */
+        ++l_current_data;
+
+        /* do nothing on the 5 * l_j2k->m_specific_param.m_encoder.m_total_tile_parts remaining data */
+        if (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_tlm_size,p_manager) != l_tlm_size) {
+                return OPJ_FALSE;
+        }
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_write_sot(     opj_j2k_t *p_j2k,
+                                                        OPJ_BYTE * p_data,
+                                                        OPJ_UINT32 * p_data_written,
+                                                        const opj_stream_private_t *p_stream,
+                                                        opj_event_mgr_t * p_manager
+                            )
+{
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+        assert(p_stream != 00);
+
+        opj_write_bytes(p_data,J2K_MS_SOT,2);                                   /* SOT */
+        p_data += 2;
+
+        opj_write_bytes(p_data,10,2);                                                   /* Lsot */
+        p_data += 2;
+
+        opj_write_bytes(p_data, p_j2k->m_current_tile_number,2);                        /* Isot */
+        p_data += 2;
+
+        /* Psot  */
+        p_data += 4;
+
+        opj_write_bytes(p_data, p_j2k->m_specific_param.m_encoder.m_current_tile_part_number,1);                        /* TPsot */
+        ++p_data;
+
+        opj_write_bytes(p_data, p_j2k->m_cp.tcps[p_j2k->m_current_tile_number].m_nb_tile_parts,1);                      /* TNsot */
+        ++p_data;
+
+        /* UniPG>> */
+#ifdef USE_JPWL
+        /* update markers struct */
+/*
+        OPJ_BOOL res = j2k_add_marker(p_j2k->cstr_info, J2K_MS_SOT, p_j2k->sot_start, len + 2);
+*/
+  assert( 0 && "TODO" );
+#endif /* USE_JPWL */
+
+        * p_data_written = 12;
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_read_sot ( opj_j2k_t *p_j2k,
+                            OPJ_BYTE * p_header_data,
+                            OPJ_UINT32 p_header_size,
+                            opj_event_mgr_t * p_manager )
+{
+        opj_cp_t *l_cp = 00;
+        opj_tcp_t *l_tcp = 00;
+        OPJ_UINT32 l_tot_len, l_num_parts = 0;
+        OPJ_UINT32 l_current_part;
+        OPJ_UINT32 l_tile_x,l_tile_y;
+
+        /* preconditions */
+        assert(p_header_data != 00);
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+
+        /* Size of this marker is fixed = 12 (we have already read marker and its size)*/
+        if (p_header_size != 8) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error reading SOT marker\n");
+                return OPJ_FALSE;
+        }
+
+        l_cp = &(p_j2k->m_cp);
+        opj_read_bytes(p_header_data,&(p_j2k->m_current_tile_number),2);                /* Isot */
+        p_header_data+=2;
+
+        /* testcase 2.pdf.SIGFPE.706.1112 */
+        if (p_j2k->m_current_tile_number >= l_cp->tw * l_cp->th) {
+                opj_event_msg(p_manager, EVT_ERROR, "Invalid tile number %d\n", p_j2k->m_current_tile_number);
+                return OPJ_FALSE;
+        }
+
+        l_tcp = &l_cp->tcps[p_j2k->m_current_tile_number];
+        l_tile_x = p_j2k->m_current_tile_number % l_cp->tw;
+        l_tile_y = p_j2k->m_current_tile_number / l_cp->tw;
+
+#ifdef USE_JPWL
+        if (l_cp->correct) {
+
+                OPJ_UINT32 tileno = p_j2k->m_current_tile_number;
+                static OPJ_UINT32 backup_tileno = 0;
+
+                /* tileno is negative or larger than the number of tiles!!! */
+                if (tileno > (l_cp->tw * l_cp->th)) {
+                        opj_event_msg(p_manager, EVT_ERROR,
+                                        "JPWL: bad tile number (%d out of a maximum of %d)\n",
+                                        tileno, (l_cp->tw * l_cp->th));
+                        if (!JPWL_ASSUME) {
+                                opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n");
+                                return OPJ_FALSE;
+                        }
+                        /* we try to correct */
+                        tileno = backup_tileno;
+                        opj_event_msg(p_manager, EVT_WARNING, "- trying to adjust this\n"
+                                        "- setting tile number to %d\n",
+                                        tileno);
+                }
+
+                /* keep your private count of tiles */
+                backup_tileno++;
+        };
+#endif /* USE_JPWL */
+
+        /* look for the tile in the list of already processed tile (in parts). */
+        /* Optimization possible here with a more complex data structure and with the removing of tiles */
+        /* since the time taken by this function can only grow at the time */
+
+        opj_read_bytes(p_header_data,&l_tot_len,4);             /* Psot */
+        p_header_data+=4;
+
+        /* PSot should be equal to zero or >=14 or <= 2^32-1 */
+        if ((l_tot_len !=0 ) && (l_tot_len < 14) )
+        {
+            if (l_tot_len == 12 ) /* MSD: Special case for the PHR data which are read by kakadu*/
+            {
+                opj_event_msg(p_manager, EVT_WARNING, "Empty SOT marker detected: Psot=%d.\n", l_tot_len);
+            }
+            else
+            {
+                opj_event_msg(p_manager, EVT_ERROR, "Psot value is not correct regards to the JPEG2000 norm: %d.\n", l_tot_len);
+                return OPJ_FALSE;
+            }
+        }
+
+#ifdef USE_JPWL
+        if (l_cp->correct) {
+
+                /* totlen is negative or larger than the bytes left!!! */
+                if (/*(l_tot_len < 0) ||*/ (l_tot_len > p_header_size ) ) { /* FIXME it seems correct; for info in V1 -> (p_stream_numbytesleft(p_stream) + 8))) { */
+                        opj_event_msg(p_manager, EVT_ERROR,
+                                        "JPWL: bad tile byte size (%d bytes against %d bytes left)\n",
+                                        l_tot_len, p_header_size ); /* FIXME it seems correct; for info in V1 -> p_stream_numbytesleft(p_stream) + 8); */
+                        if (!JPWL_ASSUME) {
+                                opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n");
+                                return OPJ_FALSE;
+                        }
+                        /* we try to correct */
+                        l_tot_len = 0;
+                        opj_event_msg(p_manager, EVT_WARNING, "- trying to adjust this\n"
+                                        "- setting Psot to %d => assuming it is the last tile\n",
+                                        l_tot_len);
+                }
+                };
+#endif /* USE_JPWL */
+
+                /* Ref A.4.2: Psot could be equal zero if it is the last tile-part of the codestream.*/
+                if (!l_tot_len) {
+                        opj_event_msg(p_manager, EVT_INFO, "Psot value of the current tile-part is equal to zero, "
+                                        "we assuming it is the last tile-part of the codestream.\n");
+                        p_j2k->m_specific_param.m_decoder.m_last_tile_part = 1;
+                }
+
+                opj_read_bytes(p_header_data,&l_current_part ,1);       /* TPsot */
+                ++p_header_data;
+
+                opj_read_bytes(p_header_data,&l_num_parts ,1);          /* TNsot */
+                ++p_header_data;
+
+                if (l_num_parts != 0) { /* Number of tile-part header is provided by this tile-part header */
+                        /* Useful to manage the case of textGBR.jp2 file because two values of TNSot are allowed: the correct numbers of
+                         * tile-parts for that tile and zero (A.4.2 of 15444-1 : 2002). */
+                        if (l_tcp->m_nb_tile_parts) {
+                                if (l_current_part >= l_tcp->m_nb_tile_parts){
+                                        opj_event_msg(p_manager, EVT_ERROR, "In SOT marker, TPSot (%d) is not valid regards to the current "
+                                                        "number of tile-part (%d), giving up\n", l_current_part, l_tcp->m_nb_tile_parts );
+                                        p_j2k->m_specific_param.m_decoder.m_last_tile_part = 1;
+                                        return OPJ_FALSE;
+                                }
+                        }
+                        if( l_current_part >= l_num_parts ) {
+                          /* testcase 451.pdf.SIGSEGV.ce9.3723 */
+                          opj_event_msg(p_manager, EVT_ERROR, "In SOT marker, TPSot (%d) is not valid regards to the current "
+                            "number of tile-part (header) (%d), giving up\n", l_current_part, l_num_parts );
+                          p_j2k->m_specific_param.m_decoder.m_last_tile_part = 1;
+                          return OPJ_FALSE;
+                        }
+                        l_tcp->m_nb_tile_parts = l_num_parts;
+                }
+
+                /* If know the number of tile part header we will check if we didn't read the last*/
+                if (l_tcp->m_nb_tile_parts) {
+                        if (l_tcp->m_nb_tile_parts == (l_current_part+1)) {
+                                p_j2k->m_specific_param.m_decoder.m_can_decode = 1; /* Process the last tile-part header*/
+                        }
+                }
+
+                if (!p_j2k->m_specific_param.m_decoder.m_last_tile_part){
+                        /* Keep the size of data to skip after this marker */
+                        p_j2k->m_specific_param.m_decoder.m_sot_length = l_tot_len - 12; /* SOT_marker_size = 12 */
+                }
+                else {
+                        /* FIXME: need to be computed from the number of bytes remaining in the codestream */
+                        p_j2k->m_specific_param.m_decoder.m_sot_length = 0;
+                }
+
+                p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_TPH;
+
+                /* Check if the current tile is outside the area we want decode or not corresponding to the tile index*/
+                if (p_j2k->m_specific_param.m_decoder.m_tile_ind_to_dec == -1) {
+                        p_j2k->m_specific_param.m_decoder.m_skip_data =
+                                (l_tile_x < p_j2k->m_specific_param.m_decoder.m_start_tile_x)
+                                ||      (l_tile_x >= p_j2k->m_specific_param.m_decoder.m_end_tile_x)
+                                ||  (l_tile_y < p_j2k->m_specific_param.m_decoder.m_start_tile_y)
+                                ||      (l_tile_y >= p_j2k->m_specific_param.m_decoder.m_end_tile_y);
+                }
+                else {
+                        assert( p_j2k->m_specific_param.m_decoder.m_tile_ind_to_dec >= 0 );
+                        p_j2k->m_specific_param.m_decoder.m_skip_data =
+                                (p_j2k->m_current_tile_number != (OPJ_UINT32)p_j2k->m_specific_param.m_decoder.m_tile_ind_to_dec);
+                }
+
+                /* Index */
+                if (p_j2k->cstr_index)
+                {
+                        assert(p_j2k->cstr_index->tile_index != 00);
+                        p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tileno = p_j2k->m_current_tile_number;
+                        p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_tpsno = l_current_part;
+
+                        if (l_num_parts != 0){
+                                p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].nb_tps = l_num_parts;
+                                p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_nb_tps = l_num_parts;
+
+                                if (!p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index) {
+                                        p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index =
+                                                (opj_tp_index_t*)opj_calloc(l_num_parts, sizeof(opj_tp_index_t));
+                                }
+                                else {
+                                        opj_tp_index_t *new_tp_index = (opj_tp_index_t *) opj_realloc(
+                                                        p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index, l_num_parts* sizeof(opj_tp_index_t));
+                                        if (! new_tp_index) {
+                                                opj_free(p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index);
+                                                p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index = NULL;
+                                                opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPT marker\n");
+                                                return OPJ_FALSE;
+                                        }
+                                        p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index = new_tp_index;
+                                }
+                        }
+                        else{
+                                /*if (!p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index)*/ {
+
+                                        if (!p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index) {
+                                                p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_nb_tps = 10;
+                                                p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index =
+                                                        (opj_tp_index_t*)opj_calloc( p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_nb_tps,
+                                                                        sizeof(opj_tp_index_t));
+                                        }
+
+                                        if ( l_current_part >= p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_nb_tps ){
+                                                opj_tp_index_t *new_tp_index;
+                                                p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_nb_tps = l_current_part + 1;
+                                                new_tp_index = (opj_tp_index_t *) opj_realloc(
+                                                                p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index,
+                                                                p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_nb_tps * sizeof(opj_tp_index_t));
+                                                if (! new_tp_index) {
+                                                        opj_free(p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index);
+                                                        p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index = NULL;
+                                                        p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_nb_tps = 0;
+                                                        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPT marker\n");
+                                                        return OPJ_FALSE;
+                                                }
+                                                p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index = new_tp_index;
+                                        }
+                                }
+
+                        }
+
+                }
+
+                /* FIXME move this onto a separate method to call before reading any SOT, remove part about main_end header, use a index struct inside p_j2k */
+                /* if (p_j2k->cstr_info) {
+                   if (l_tcp->first) {
+                   if (tileno == 0) {
+                   p_j2k->cstr_info->main_head_end = p_stream_tell(p_stream) - 13;
+                   }
+
+                   p_j2k->cstr_info->tile[tileno].tileno = tileno;
+                   p_j2k->cstr_info->tile[tileno].start_pos = p_stream_tell(p_stream) - 12;
+                   p_j2k->cstr_info->tile[tileno].end_pos = p_j2k->cstr_info->tile[tileno].start_pos + totlen - 1;
+                   p_j2k->cstr_info->tile[tileno].num_tps = numparts;
+
+                   if (numparts) {
+                   p_j2k->cstr_info->tile[tileno].tp = (opj_tp_info_t *) opj_malloc(numparts * sizeof(opj_tp_info_t));
+                   }
+                   else {
+                   p_j2k->cstr_info->tile[tileno].tp = (opj_tp_info_t *) opj_malloc(10 * sizeof(opj_tp_info_t)); // Fixme (10)
+                   }
+                   }
+                   else {
+                   p_j2k->cstr_info->tile[tileno].end_pos += totlen;
+                   }
+
+                   p_j2k->cstr_info->tile[tileno].tp[partno].tp_start_pos = p_stream_tell(p_stream) - 12;
+                   p_j2k->cstr_info->tile[tileno].tp[partno].tp_end_pos =
+                   p_j2k->cstr_info->tile[tileno].tp[partno].tp_start_pos + totlen - 1;
+                   }*/
+                return OPJ_TRUE;
+        }
+
+OPJ_BOOL opj_j2k_write_sod(     opj_j2k_t *p_j2k,
+                                                        opj_tcd_t * p_tile_coder,
+                                                        OPJ_BYTE * p_data,
+                                                        OPJ_UINT32 * p_data_written,
+                                                        OPJ_UINT32 p_total_data_size,
+                                                        const opj_stream_private_t *p_stream,
+                                                        opj_event_mgr_t * p_manager
+                            )
+{
+        opj_codestream_info_t *l_cstr_info = 00;
+        OPJ_UINT32 l_remaining_data;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+        assert(p_stream != 00);
+
+        opj_write_bytes(p_data,J2K_MS_SOD,2);                                   /* SOD */
+        p_data += 2;
+
+        /* make room for the EOF marker */
+        l_remaining_data =  p_total_data_size - 4;
+
+        /* update tile coder */
+        p_tile_coder->tp_num = p_j2k->m_specific_param.m_encoder.m_current_poc_tile_part_number ;
+        p_tile_coder->cur_tp_num = p_j2k->m_specific_param.m_encoder.m_current_tile_part_number;
+
+         /* INDEX >> */
+        /* TODO mergeV2: check this part which use cstr_info */
+        /*l_cstr_info = p_j2k->cstr_info;
+        if (l_cstr_info) {
+                if (!p_j2k->m_specific_param.m_encoder.m_current_tile_part_number ) {
+                        //TODO cstr_info->tile[p_j2k->m_current_tile_number].end_header = p_stream_tell(p_stream) + p_j2k->pos_correction - 1;
+                        l_cstr_info->tile[p_j2k->m_current_tile_number].tileno = p_j2k->m_current_tile_number;
+                }
+                else {*/
+                        /*
+                        TODO
+                        if
+                                (cstr_info->tile[p_j2k->m_current_tile_number].packet[cstr_info->packno - 1].end_pos < p_stream_tell(p_stream))
+                        {
+                                cstr_info->tile[p_j2k->m_current_tile_number].packet[cstr_info->packno].start_pos = p_stream_tell(p_stream);
+                        }*/
+                /*}*/
+                /* UniPG>> */
+#ifdef USE_JPWL
+                /* update markers struct */
+                /*OPJ_BOOL res = j2k_add_marker(p_j2k->cstr_info, J2K_MS_SOD, p_j2k->sod_start, 2);
+*/
+  assert( 0 && "TODO" );
+#endif /* USE_JPWL */
+                /* <<UniPG */
+        /*}*/
+        /* << INDEX */
+
+        if (p_j2k->m_specific_param.m_encoder.m_current_tile_part_number == 0) {
+                p_tile_coder->tcd_image->tiles->packno = 0;
+                if (l_cstr_info) {
+                        l_cstr_info->packno = 0;
+                }
+        }
+
+        *p_data_written = 0;
+
+        if (! opj_tcd_encode_tile(p_tile_coder, p_j2k->m_current_tile_number, p_data, p_data_written, l_remaining_data , l_cstr_info)) {
+                opj_event_msg(p_manager, EVT_ERROR, "Cannot encode tile\n");
+                return OPJ_FALSE;
+        }
+
+        *p_data_written += 2;
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_read_sod (opj_j2k_t *p_j2k,
+                           opj_stream_private_t *p_stream,
+                                                   opj_event_mgr_t * p_manager
+                           )
+{
+        OPJ_SIZE_T l_current_read_size;
+        opj_codestream_index_t * l_cstr_index = 00;
+        OPJ_BYTE ** l_current_data = 00;
+        opj_tcp_t * l_tcp = 00;
+        OPJ_UINT32 * l_tile_len = 00;
+        OPJ_BOOL l_sot_length_pb_detected = OPJ_FALSE;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+        assert(p_stream != 00);
+
+        l_tcp = &(p_j2k->m_cp.tcps[p_j2k->m_current_tile_number]);
+
+        if (p_j2k->m_specific_param.m_decoder.m_last_tile_part) {
+                /* opj_stream_get_number_byte_left returns OPJ_OFF_T
+                // but we are in the last tile part,
+                // so its result will fit on OPJ_UINT32 unless we find
+                // a file with a single tile part of more than 4 GB...*/
+                p_j2k->m_specific_param.m_decoder.m_sot_length = (OPJ_UINT32)(opj_stream_get_number_byte_left(p_stream) - 2);
+        }
+        else {
+            /* Check to avoid pass the limit of OPJ_UINT32 */
+            if (p_j2k->m_specific_param.m_decoder.m_sot_length >= 2 )
+                p_j2k->m_specific_param.m_decoder.m_sot_length -= 2;
+            else {
+                /* MSD: case commented to support empty SOT marker (PHR data) */
+            }
+        }
+
+        l_current_data = &(l_tcp->m_data);
+        l_tile_len = &l_tcp->m_data_size;
+
+        /* Patch to support new PHR data */
+        if (p_j2k->m_specific_param.m_decoder.m_sot_length) {
+            if (! *l_current_data) {
+                /* LH: oddly enough, in this path, l_tile_len!=0.
+                 * TODO: If this was consistant, we could simplify the code to only use realloc(), as realloc(0,...) default to malloc(0,...).
+                 */
+                *l_current_data = (OPJ_BYTE*) opj_malloc(p_j2k->m_specific_param.m_decoder.m_sot_length);
+            }
+            else {
+                OPJ_BYTE *l_new_current_data = (OPJ_BYTE *) opj_realloc(*l_current_data, *l_tile_len + p_j2k->m_specific_param.m_decoder.m_sot_length);
+                if (! l_new_current_data) {
+                        opj_free(*l_current_data);
+                        /*nothing more is done as l_current_data will be set to null, and just
+                          afterward we enter in the error path
+                          and the actual tile_len is updated (committed) at the end of the
+                          function. */
+                }
+                *l_current_data = l_new_current_data;
+            }
+            
+            if (*l_current_data == 00) {
+                opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to decode tile\n");
+                return OPJ_FALSE;
+            }
+        }
+        else {
+            l_sot_length_pb_detected = OPJ_TRUE;
+        }
+
+        /* Index */
+        l_cstr_index = p_j2k->cstr_index;
+        if (l_cstr_index) {
+                OPJ_OFF_T l_current_pos = opj_stream_tell(p_stream) - 2;
+
+                OPJ_UINT32 l_current_tile_part = l_cstr_index->tile_index[p_j2k->m_current_tile_number].current_tpsno;
+                l_cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index[l_current_tile_part].end_header =
+                                l_current_pos;
+                l_cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index[l_current_tile_part].end_pos =
+                                l_current_pos + p_j2k->m_specific_param.m_decoder.m_sot_length + 2;
+
+                if (OPJ_FALSE == opj_j2k_add_tlmarker(p_j2k->m_current_tile_number,
+                                        l_cstr_index,
+                                        J2K_MS_SOD,
+                                        l_current_pos,
+                                        p_j2k->m_specific_param.m_decoder.m_sot_length + 2)) {
+                        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to add tl marker\n");
+                        return OPJ_FALSE;
+                }
+
+                /*l_cstr_index->packno = 0;*/
+        }
+
+        /* Patch to support new PHR data */
+        if (!l_sot_length_pb_detected) {
+            l_current_read_size = opj_stream_read_data(
+                        p_stream,
+                        *l_current_data + *l_tile_len,
+                        p_j2k->m_specific_param.m_decoder.m_sot_length,
+                        p_manager);
+        }
+        else
+        {
+            l_current_read_size = 0;
+        }
+
+        if (l_current_read_size != p_j2k->m_specific_param.m_decoder.m_sot_length) {
+                p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_NEOC;
+        }
+        else {
+                p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_TPHSOT;
+        }
+
+        *l_tile_len += (OPJ_UINT32)l_current_read_size;
+
+        return OPJ_TRUE;
+}
+
+ OPJ_BOOL opj_j2k_write_rgn(opj_j2k_t *p_j2k,
+                            OPJ_UINT32 p_tile_no,
+                            OPJ_UINT32 p_comp_no,
+                            OPJ_UINT32 nb_comps,
+                            opj_stream_private_t *p_stream,
+                            opj_event_mgr_t * p_manager
+                            )
+{
+        OPJ_BYTE * l_current_data = 00;
+        OPJ_UINT32 l_rgn_size;
+        opj_cp_t *l_cp = 00;
+        opj_tcp_t *l_tcp = 00;
+        opj_tccp_t *l_tccp = 00;
+        OPJ_UINT32 l_comp_room;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+        assert(p_stream != 00);
+
+        l_cp = &(p_j2k->m_cp);
+        l_tcp = &l_cp->tcps[p_tile_no];
+        l_tccp = &l_tcp->tccps[p_comp_no];
+
+        if (nb_comps <= 256) {
+                l_comp_room = 1;
+        }
+        else {
+                l_comp_room = 2;
+        }
+
+        l_rgn_size = 6 + l_comp_room;
+
+        l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
+
+        opj_write_bytes(l_current_data,J2K_MS_RGN,2);                                   /* RGN  */
+        l_current_data += 2;
+
+        opj_write_bytes(l_current_data,l_rgn_size-2,2);                                 /* Lrgn */
+        l_current_data += 2;
+
+        opj_write_bytes(l_current_data,p_comp_no,l_comp_room);                          /* Crgn */
+        l_current_data+=l_comp_room;
+
+        opj_write_bytes(l_current_data, 0,1);                                           /* Srgn */
+        ++l_current_data;
+
+        opj_write_bytes(l_current_data, (OPJ_UINT32)l_tccp->roishift,1);                            /* SPrgn */
+        ++l_current_data;
+
+        if (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_rgn_size,p_manager) != l_rgn_size) {
+                return OPJ_FALSE;
+        }
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_write_eoc(     opj_j2k_t *p_j2k,
+                            opj_stream_private_t *p_stream,
+                            opj_event_mgr_t * p_manager
+                            )
+{
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+        assert(p_stream != 00);
+
+        opj_write_bytes(p_j2k->m_specific_param.m_encoder.m_header_tile_data,J2K_MS_EOC,2);                                     /* EOC */
+
+/* UniPG>> */
+#ifdef USE_JPWL
+        /* update markers struct */
+        /*
+        OPJ_BOOL res = j2k_add_marker(p_j2k->cstr_info, J2K_MS_EOC, p_stream_tell(p_stream) - 2, 2);
+*/
+#endif /* USE_JPWL */
+
+        if ( opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,2,p_manager) != 2) {
+                return OPJ_FALSE;
+        }
+
+        if ( ! opj_stream_flush(p_stream,p_manager) ) {
+                return OPJ_FALSE;
+        }
+
+        return OPJ_TRUE;
+}
+
+/**
+ * Reads a RGN marker (Region Of Interest)
+ *
+ * @param       p_header_data   the data contained in the POC box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the POC marker.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_rgn (opj_j2k_t *p_j2k,
+                                  OPJ_BYTE * p_header_data,
+                                  OPJ_UINT32 p_header_size,
+                                  opj_event_mgr_t * p_manager
+                                  )
+{
+        OPJ_UINT32 l_nb_comp;
+        opj_image_t * l_image = 00;
+
+        opj_cp_t *l_cp = 00;
+        opj_tcp_t *l_tcp = 00;
+        OPJ_UINT32 l_comp_room, l_comp_no, l_roi_sty;
+
+        /* preconditions*/
+        assert(p_header_data != 00);
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+
+        l_image = p_j2k->m_private_image;
+        l_nb_comp = l_image->numcomps;
+
+        if (l_nb_comp <= 256) {
+                l_comp_room = 1; }
+        else {
+                l_comp_room = 2; }
+
+        if (p_header_size != 2 + l_comp_room) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error reading RGN marker\n");
+                return OPJ_FALSE;
+        }
+
+        l_cp = &(p_j2k->m_cp);
+        l_tcp = (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH) ?
+                                &l_cp->tcps[p_j2k->m_current_tile_number] :
+                                p_j2k->m_specific_param.m_decoder.m_default_tcp;
+
+        opj_read_bytes(p_header_data,&l_comp_no,l_comp_room);           /* Crgn */
+        p_header_data+=l_comp_room;
+        opj_read_bytes(p_header_data,&l_roi_sty,1);                                     /* Srgn */
+        ++p_header_data;
+
+#ifdef USE_JPWL
+        if (l_cp->correct) {
+                /* totlen is negative or larger than the bytes left!!! */
+                if (l_comp_room >= l_nb_comp) {
+                        opj_event_msg(p_manager, EVT_ERROR,
+                                "JPWL: bad component number in RGN (%d when there are only %d)\n",
+                                l_comp_room, l_nb_comp);
+                        if (!JPWL_ASSUME || JPWL_ASSUME) {
+                                opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n");
+                                return OPJ_FALSE;
+                        }
+                }
+        };
+#endif /* USE_JPWL */
+
+        /* testcase 3635.pdf.asan.77.2930 */
+        if (l_comp_no >= l_nb_comp) {
+                opj_event_msg(p_manager, EVT_ERROR,
+                        "bad component number in RGN (%d when there are only %d)\n",
+                        l_comp_no, l_nb_comp);
+                return OPJ_FALSE;
+        }
+
+        opj_read_bytes(p_header_data,(OPJ_UINT32 *) (&(l_tcp->tccps[l_comp_no].roishift)),1);   /* SPrgn */
+        ++p_header_data;
+
+        return OPJ_TRUE;
+
+}
+
+OPJ_FLOAT32 opj_j2k_get_tp_stride (opj_tcp_t * p_tcp)
+{
+        return (OPJ_FLOAT32) ((p_tcp->m_nb_tile_parts - 1) * 14);
+}
+
+OPJ_FLOAT32 opj_j2k_get_default_stride (opj_tcp_t * p_tcp)
+{
+    (void)p_tcp;
+    return 0;
+}
+
+OPJ_BOOL opj_j2k_update_rates(  opj_j2k_t *p_j2k,
+                                                            opj_stream_private_t *p_stream,
+                                                            opj_event_mgr_t * p_manager )
+{
+        opj_cp_t * l_cp = 00;
+        opj_image_t * l_image = 00;
+        opj_tcp_t * l_tcp = 00;
+        opj_image_comp_t * l_img_comp = 00;
+
+        OPJ_UINT32 i,j,k;
+        OPJ_INT32 l_x0,l_y0,l_x1,l_y1;
+        OPJ_FLOAT32 * l_rates = 0;
+        OPJ_FLOAT32 l_sot_remove;
+        OPJ_UINT32 l_bits_empty, l_size_pixel;
+        OPJ_UINT32 l_tile_size = 0;
+        OPJ_UINT32 l_last_res;
+        OPJ_FLOAT32 (* l_tp_stride_func)(opj_tcp_t *) = 00;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+        assert(p_stream != 00);
+
+        l_cp = &(p_j2k->m_cp);
+        l_image = p_j2k->m_private_image;
+        l_tcp = l_cp->tcps;
+
+        l_bits_empty = 8 * l_image->comps->dx * l_image->comps->dy;
+        l_size_pixel = l_image->numcomps * l_image->comps->prec;
+        l_sot_remove = (OPJ_FLOAT32) opj_stream_tell(p_stream) / (OPJ_FLOAT32)(l_cp->th * l_cp->tw);
+
+        if (l_cp->m_specific_param.m_enc.m_tp_on) {
+                l_tp_stride_func = opj_j2k_get_tp_stride;
+        }
+        else {
+                l_tp_stride_func = opj_j2k_get_default_stride;
+        }
+
+        for (i=0;i<l_cp->th;++i) {
+                for (j=0;j<l_cp->tw;++j) {
+                        OPJ_FLOAT32 l_offset = (OPJ_FLOAT32)(*l_tp_stride_func)(l_tcp) / (OPJ_FLOAT32)l_tcp->numlayers;
+
+                        /* 4 borders of the tile rescale on the image if necessary */
+                        l_x0 = opj_int_max((OPJ_INT32)(l_cp->tx0 + j * l_cp->tdx), (OPJ_INT32)l_image->x0);
+                        l_y0 = opj_int_max((OPJ_INT32)(l_cp->ty0 + i * l_cp->tdy), (OPJ_INT32)l_image->y0);
+                        l_x1 = opj_int_min((OPJ_INT32)(l_cp->tx0 + (j + 1) * l_cp->tdx), (OPJ_INT32)l_image->x1);
+                        l_y1 = opj_int_min((OPJ_INT32)(l_cp->ty0 + (i + 1) * l_cp->tdy), (OPJ_INT32)l_image->y1);
+
+                        l_rates = l_tcp->rates;
+
+                        /* Modification of the RATE >> */
+                        if (*l_rates) {
+                                *l_rates =              (( (OPJ_FLOAT32) (l_size_pixel * (OPJ_UINT32)(l_x1 - l_x0) * (OPJ_UINT32)(l_y1 - l_y0)))
+                                                                /
+                                                                ((*l_rates) * (OPJ_FLOAT32)l_bits_empty)
+                                                                )
+                                                                -
+                                                                l_offset;
+                        }
+
+                        ++l_rates;
+
+                        for (k = 1; k < l_tcp->numlayers; ++k) {
+                                if (*l_rates) {
+                                        *l_rates =              (( (OPJ_FLOAT32) (l_size_pixel * (OPJ_UINT32)(l_x1 - l_x0) * (OPJ_UINT32)(l_y1 - l_y0)))
+                                                                        /
+                                                                                ((*l_rates) * (OPJ_FLOAT32)l_bits_empty)
+                                                                        )
+                                                                        -
+                                                                        l_offset;
+                                }
+
+                                ++l_rates;
+                        }
+
+                        ++l_tcp;
+
+                }
+        }
+
+        l_tcp = l_cp->tcps;
+
+        for (i=0;i<l_cp->th;++i) {
+                for     (j=0;j<l_cp->tw;++j) {
+                        l_rates = l_tcp->rates;
+
+                        if (*l_rates) {
+                                *l_rates -= l_sot_remove;
+
+                                if (*l_rates < 30) {
+                                        *l_rates = 30;
+                                }
+                        }
+
+                        ++l_rates;
+
+                        l_last_res = l_tcp->numlayers - 1;
+
+                        for (k = 1; k < l_last_res; ++k) {
+
+                                if (*l_rates) {
+                                        *l_rates -= l_sot_remove;
+
+                                        if (*l_rates < *(l_rates - 1) + 10) {
+                                                *l_rates  = (*(l_rates - 1)) + 20;
+                                        }
+                                }
+
+                                ++l_rates;
+                        }
+
+                        if (*l_rates) {
+                                *l_rates -= (l_sot_remove + 2.f);
+
+                                if (*l_rates < *(l_rates - 1) + 10) {
+                                        *l_rates  = (*(l_rates - 1)) + 20;
+                                }
+                        }
+
+                        ++l_tcp;
+                }
+        }
+
+        l_img_comp = l_image->comps;
+        l_tile_size = 0;
+
+        for (i=0;i<l_image->numcomps;++i) {
+                l_tile_size += (        opj_uint_ceildiv(l_cp->tdx,l_img_comp->dx)
+                                                        *
+                                                        opj_uint_ceildiv(l_cp->tdy,l_img_comp->dy)
+                                                        *
+                                                        l_img_comp->prec
+                                                );
+
+                ++l_img_comp;
+        }
+
+        l_tile_size = (OPJ_UINT32) (l_tile_size * 0.1625); /* 1.3/8 = 0.1625 */
+
+        l_tile_size += opj_j2k_get_specific_header_sizes(p_j2k);
+
+        p_j2k->m_specific_param.m_encoder.m_encoded_tile_size = l_tile_size;
+        p_j2k->m_specific_param.m_encoder.m_encoded_tile_data =
+                        (OPJ_BYTE *) opj_malloc(p_j2k->m_specific_param.m_encoder.m_encoded_tile_size);
+        if (p_j2k->m_specific_param.m_encoder.m_encoded_tile_data == 00) {
+                return OPJ_FALSE;
+        }
+
+        if (l_cp->m_specific_param.m_enc.m_cinema) {
+                p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer =
+                                (OPJ_BYTE *) opj_malloc(5*p_j2k->m_specific_param.m_encoder.m_total_tile_parts);
+                if (! p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer) {
+                        return OPJ_FALSE;
+                }
+
+                p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current =
+                                p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer;
+        }
+
+        return OPJ_TRUE;
+}
+
+#if 0
+OPJ_BOOL opj_j2k_read_eoc (     opj_j2k_t *p_j2k,
+                                                        opj_stream_private_t *p_stream,
+                                                        opj_event_mgr_t * p_manager )
+{
+        OPJ_UINT32 i;
+        opj_tcd_t * l_tcd = 00;
+        OPJ_UINT32 l_nb_tiles;
+        opj_tcp_t * l_tcp = 00;
+        OPJ_BOOL l_success;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+        assert(p_stream != 00);
+
+        l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw;
+        l_tcp = p_j2k->m_cp.tcps;
+
+        l_tcd = opj_tcd_create(OPJ_TRUE);
+        if (l_tcd == 00) {
+                opj_event_msg(p_manager, EVT_ERROR, "Cannot decode tile, memory error\n");
+                return OPJ_FALSE;
+        }
+
+        for (i = 0; i < l_nb_tiles; ++i) {
+                if (l_tcp->m_data) {
+                        if (! opj_tcd_init_decode_tile(l_tcd, i)) {
+                                opj_tcd_destroy(l_tcd);
+                                opj_event_msg(p_manager, EVT_ERROR, "Cannot decode tile, memory error\n");
+                                return OPJ_FALSE;
+                        }
+
+                        l_success = opj_tcd_decode_tile(l_tcd, l_tcp->m_data, l_tcp->m_data_size, i, p_j2k->cstr_index);
+                        /* cleanup */
+
+                        if (! l_success) {
+                                p_j2k->m_specific_param.m_decoder.m_state |= J2K_STATE_ERR;
+                                break;
+                        }
+                }
+
+                opj_j2k_tcp_destroy(l_tcp);
+                ++l_tcp;
+        }
+
+        opj_tcd_destroy(l_tcd);
+        return OPJ_TRUE;
+}
+#endif
+
+OPJ_BOOL opj_j2k_get_end_header(opj_j2k_t *p_j2k,
+                                                        struct opj_stream_private *p_stream,
+                                                        struct opj_event_mgr * p_manager )
+{
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+        assert(p_stream != 00);
+
+        p_j2k->cstr_index->main_head_end = opj_stream_tell(p_stream);
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_write_mct_data_group(  opj_j2k_t *p_j2k,
+                                                                        struct opj_stream_private *p_stream,
+                                                                        struct opj_event_mgr * p_manager )
+{
+        OPJ_UINT32 i;
+        opj_simple_mcc_decorrelation_data_t * l_mcc_record;
+        opj_mct_data_t * l_mct_record;
+        opj_tcp_t * l_tcp;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_stream != 00);
+        assert(p_manager != 00);
+
+        if (! opj_j2k_write_cbd(p_j2k,p_stream,p_manager)) {
+                return OPJ_FALSE;
+        }
+
+        l_tcp = &(p_j2k->m_cp.tcps[p_j2k->m_current_tile_number]);
+        l_mct_record = l_tcp->m_mct_records;
+
+        for (i=0;i<l_tcp->m_nb_mct_records;++i) {
+
+                if (! opj_j2k_write_mct_record(p_j2k,l_mct_record,p_stream,p_manager)) {
+                        return OPJ_FALSE;
+                }
+
+                ++l_mct_record;
+        }
+
+        l_mcc_record = l_tcp->m_mcc_records;
+
+        for     (i=0;i<l_tcp->m_nb_mcc_records;++i) {
+
+                if (! opj_j2k_write_mcc_record(p_j2k,l_mcc_record,p_stream,p_manager)) {
+                        return OPJ_FALSE;
+                }
+
+                ++l_mcc_record;
+        }
+
+        if (! opj_j2k_write_mco(p_j2k,p_stream,p_manager)) {
+                return OPJ_FALSE;
+        }
+
+        return OPJ_TRUE;
+}
+
+#if 0
+OPJ_BOOL opj_j2k_write_all_coc(opj_j2k_t *p_j2k,
+                                                                        struct opj_stream_private *p_stream,
+                                                                        struct opj_event_mgr * p_manager )
+{
+        OPJ_UINT32 compno;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+        assert(p_stream != 00);
+
+        for (compno = 0; compno < p_j2k->m_private_image->numcomps; ++compno)
+        {
+                if (! opj_j2k_write_coc(p_j2k,compno,p_stream, p_manager)) {
+                        return OPJ_FALSE;
+                }
+        }
+
+        return OPJ_TRUE;
+}
+#endif
+
+#if 0
+OPJ_BOOL opj_j2k_write_all_qcc(opj_j2k_t *p_j2k,
+                                                                        struct opj_stream_private *p_stream,
+                                                                        struct opj_event_mgr * p_manager )
+{
+        OPJ_UINT32 compno;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+        assert(p_stream != 00);
+
+        for (compno = 0; compno < p_j2k->m_private_image->numcomps; ++compno)
+        {
+                if (! opj_j2k_write_qcc(p_j2k,compno,p_stream, p_manager)) {
+                        return OPJ_FALSE;
+                }
+        }
+
+        return OPJ_TRUE;
+}
+#endif
+
+
+OPJ_BOOL opj_j2k_write_regions( opj_j2k_t *p_j2k,
+                                                        struct opj_stream_private *p_stream,
+                                                        struct opj_event_mgr * p_manager )
+{
+        OPJ_UINT32 compno;
+        const opj_tccp_t *l_tccp = 00;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+        assert(p_stream != 00);
+
+        l_tccp = p_j2k->m_cp.tcps->tccps;
+
+        for     (compno = 0; compno < p_j2k->m_private_image->numcomps; ++compno)  {
+                if (l_tccp->roishift) {
+
+                        if (! opj_j2k_write_rgn(p_j2k,0,compno,p_j2k->m_private_image->numcomps,p_stream,p_manager)) {
+                                return OPJ_FALSE;
+                        }
+                }
+
+                ++l_tccp;
+        }
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_write_epc(     opj_j2k_t *p_j2k,
+                                                struct opj_stream_private *p_stream,
+                                                struct opj_event_mgr * p_manager )
+{
+        opj_codestream_index_t * l_cstr_index = 00;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+        assert(p_stream != 00);
+
+        l_cstr_index = p_j2k->cstr_index;
+        if (l_cstr_index) {
+                l_cstr_index->codestream_size = (OPJ_UINT64)opj_stream_tell(p_stream);
+                /* UniPG>> */
+                /* The following adjustment is done to adjust the codestream size */
+                /* if SOD is not at 0 in the buffer. Useful in case of JP2, where */
+                /* the first bunch of bytes is not in the codestream              */
+                l_cstr_index->codestream_size -= (OPJ_UINT64)l_cstr_index->main_head_start;
+                /* <<UniPG */
+        }
+
+#ifdef USE_JPWL
+        /* preparation of JPWL marker segments */
+#if 0
+        if(cp->epc_on) {
+
+                /* encode according to JPWL */
+                jpwl_encode(p_j2k, p_stream, image);
+
+        }
+#endif
+  assert( 0 && "TODO" );
+#endif /* USE_JPWL */
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_read_unk (     opj_j2k_t *p_j2k,
+                                                        opj_stream_private_t *p_stream,
+                                                        OPJ_UINT32 *output_marker,
+                                                        opj_event_mgr_t * p_manager
+                                                        )
+{
+        OPJ_UINT32 l_unknown_marker;
+        const opj_dec_memory_marker_handler_t * l_marker_handler;
+        OPJ_UINT32 l_size_unk = 2;
+
+        /* preconditions*/
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+        assert(p_stream != 00);
+
+        opj_event_msg(p_manager, EVT_WARNING, "Unknown marker\n");
+
+        while(1) {
+                /* Try to read 2 bytes (the next marker ID) from stream and copy them into the buffer*/
+                if (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2) {
+                        opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n");
+                        return OPJ_FALSE;
+                }
+
+                /* read 2 bytes as the new marker ID*/
+                opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data,&l_unknown_marker,2);
+
+                if (!(l_unknown_marker < 0xff00)) {
+
+                        /* Get the marker handler from the marker ID*/
+                        l_marker_handler = opj_j2k_get_marker_handler(l_unknown_marker);
+
+                        if (!(p_j2k->m_specific_param.m_decoder.m_state & l_marker_handler->states)) {
+                                opj_event_msg(p_manager, EVT_ERROR, "Marker is not compliant with its position\n");
+                                return OPJ_FALSE;
+                        }
+                        else {
+                                if (l_marker_handler->id != J2K_MS_UNK) {
+                                        /* Add the marker to the codestream index*/
+                                        if (l_marker_handler->id != J2K_MS_SOT)
+                                        {
+                                                OPJ_BOOL res = opj_j2k_add_mhmarker(p_j2k->cstr_index, J2K_MS_UNK,
+                                                                (OPJ_UINT32) opj_stream_tell(p_stream) - l_size_unk,
+                                                                l_size_unk);
+                                                if (res == OPJ_FALSE) {
+                                                        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to add mh marker\n");
+                                                        return OPJ_FALSE;
+                                                }
+                                        }
+                                        break; /* next marker is known and well located */
+                                }
+                                else
+                                        l_size_unk += 2;
+                        }
+                }
+        }
+
+        *output_marker = l_marker_handler->id ;
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_write_mct_record(      opj_j2k_t *p_j2k,
+                                                                opj_mct_data_t * p_mct_record,
+                                                                struct opj_stream_private *p_stream,
+                                                                struct opj_event_mgr * p_manager )
+{
+        OPJ_UINT32 l_mct_size;
+        OPJ_BYTE * l_current_data = 00;
+        OPJ_UINT32 l_tmp;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+        assert(p_stream != 00);
+
+        l_mct_size = 10 + p_mct_record->m_data_size;
+
+        if (l_mct_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) {
+                OPJ_BYTE *new_header_tile_data = (OPJ_BYTE *) opj_realloc(p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_mct_size);
+                if (! new_header_tile_data) {
+                        opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data);
+                        p_j2k->m_specific_param.m_encoder.m_header_tile_data = NULL;
+                        p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0;
+                        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to write MCT marker\n");
+                        return OPJ_FALSE;
+                }
+                p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data;
+                p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_mct_size;
+        }
+
+        l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
+
+        opj_write_bytes(l_current_data,J2K_MS_MCT,2);                                   /* MCT */
+        l_current_data += 2;
+
+        opj_write_bytes(l_current_data,l_mct_size-2,2);                                 /* Lmct */
+        l_current_data += 2;
+
+        opj_write_bytes(l_current_data,0,2);                                                    /* Zmct */
+        l_current_data += 2;
+
+        /* only one marker atm */
+        l_tmp = (p_mct_record->m_index & 0xff) | (p_mct_record->m_array_type << 8) | (p_mct_record->m_element_type << 10);
+
+        opj_write_bytes(l_current_data,l_tmp,2);
+        l_current_data += 2;
+
+        opj_write_bytes(l_current_data,0,2);                                                    /* Ymct */
+        l_current_data+=2;
+
+        memcpy(l_current_data,p_mct_record->m_data,p_mct_record->m_data_size);
+
+        if (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_mct_size,p_manager) != l_mct_size) {
+                return OPJ_FALSE;
+        }
+
+        return OPJ_TRUE;
+}
+
+/**
+ * Reads a MCT marker (Multiple Component Transform)
+ *
+ * @param       p_header_data   the data contained in the MCT box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the MCT marker.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_mct (      opj_j2k_t *p_j2k,
+                                                                    OPJ_BYTE * p_header_data,
+                                                                    OPJ_UINT32 p_header_size,
+                                                                    opj_event_mgr_t * p_manager
+                                    )
+{
+        OPJ_UINT32 i;
+        opj_tcp_t *l_tcp = 00;
+        OPJ_UINT32 l_tmp;
+        OPJ_UINT32 l_indix;
+        opj_mct_data_t * l_mct_data;
+
+        /* preconditions */
+        assert(p_header_data != 00);
+        assert(p_j2k != 00);
+
+        l_tcp = p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH ?
+                        &p_j2k->m_cp.tcps[p_j2k->m_current_tile_number] :
+                        p_j2k->m_specific_param.m_decoder.m_default_tcp;
+
+        if (p_header_size < 2) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error reading MCT marker\n");
+                return OPJ_FALSE;
+        }
+
+        /* first marker */
+        opj_read_bytes(p_header_data,&l_tmp,2);                         /* Zmct */
+        p_header_data += 2;
+        if (l_tmp != 0) {
+                opj_event_msg(p_manager, EVT_WARNING, "Cannot take in charge mct data within multiple MCT records\n");
+                return OPJ_TRUE;
+        }
+
+        if(p_header_size <= 6) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error reading MCT marker\n");
+                return OPJ_FALSE;
+        }
+
+        /* Imct -> no need for other values, take the first, type is double with decorrelation x0000 1101 0000 0000*/
+        opj_read_bytes(p_header_data,&l_tmp,2);                         /* Imct */
+        p_header_data += 2;
+
+        l_indix = l_tmp & 0xff;
+        l_mct_data = l_tcp->m_mct_records;
+
+        for (i=0;i<l_tcp->m_nb_mct_records;++i) {
+                if (l_mct_data->m_index == l_indix) {
+                        break;
+                }
+                ++l_mct_data;
+        }
+
+        /* NOT FOUND */
+        if (i == l_tcp->m_nb_mct_records) {
+                if (l_tcp->m_nb_mct_records == l_tcp->m_nb_max_mct_records) {
+                        opj_mct_data_t *new_mct_records;
+                        l_tcp->m_nb_max_mct_records += OPJ_J2K_MCT_DEFAULT_NB_RECORDS;
+
+                        new_mct_records = (opj_mct_data_t *) opj_realloc(l_tcp->m_mct_records, l_tcp->m_nb_max_mct_records * sizeof(opj_mct_data_t));
+                        if (! new_mct_records) {
+                                opj_free(l_tcp->m_mct_records);
+                                l_tcp->m_mct_records = NULL;
+                                l_tcp->m_nb_max_mct_records = 0;
+                                l_tcp->m_nb_mct_records = 0;
+                                opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read MCT marker\n");
+                                return OPJ_FALSE;
+                        }
+                        l_tcp->m_mct_records = new_mct_records;
+                        l_mct_data = l_tcp->m_mct_records + l_tcp->m_nb_mct_records;
+                        memset(l_mct_data ,0,(l_tcp->m_nb_max_mct_records - l_tcp->m_nb_mct_records) * sizeof(opj_mct_data_t));
+                }
+
+                l_mct_data = l_tcp->m_mct_records + l_tcp->m_nb_mct_records;
+        }
+
+        if (l_mct_data->m_data) {
+                opj_free(l_mct_data->m_data);
+                l_mct_data->m_data = 00;
+        }
+
+        l_mct_data->m_index = l_indix;
+        l_mct_data->m_array_type = (J2K_MCT_ARRAY_TYPE)((l_tmp  >> 8) & 3);
+        l_mct_data->m_element_type = (J2K_MCT_ELEMENT_TYPE)((l_tmp  >> 10) & 3);
+
+        opj_read_bytes(p_header_data,&l_tmp,2);                         /* Ymct */
+        p_header_data+=2;
+        if (l_tmp != 0) {
+                opj_event_msg(p_manager, EVT_WARNING, "Cannot take in charge multiple MCT markers\n");
+                return OPJ_TRUE;
+        }
+
+        p_header_size -= 6;
+
+        l_mct_data->m_data = (OPJ_BYTE*)opj_malloc(p_header_size);
+        if (! l_mct_data->m_data) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error reading MCT marker\n");
+                return OPJ_FALSE;
+        }
+        memcpy(l_mct_data->m_data,p_header_data,p_header_size);
+
+        l_mct_data->m_data_size = p_header_size;
+        ++l_tcp->m_nb_mct_records;
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_write_mcc_record(      opj_j2k_t *p_j2k,
+                                                                struct opj_simple_mcc_decorrelation_data * p_mcc_record,
+                                                                struct opj_stream_private *p_stream,
+                                                                struct opj_event_mgr * p_manager )
+{
+        OPJ_UINT32 i;
+        OPJ_UINT32 l_mcc_size;
+        OPJ_BYTE * l_current_data = 00;
+        OPJ_UINT32 l_nb_bytes_for_comp;
+        OPJ_UINT32 l_mask;
+        OPJ_UINT32 l_tmcc;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+        assert(p_stream != 00);
+
+        if (p_mcc_record->m_nb_comps > 255 ) {
+        l_nb_bytes_for_comp = 2;
+                l_mask = 0x8000;
+        }
+        else {
+                l_nb_bytes_for_comp = 1;
+                l_mask = 0;
+        }
+
+        l_mcc_size = p_mcc_record->m_nb_comps * 2 * l_nb_bytes_for_comp + 19;
+        if (l_mcc_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size)
+        {
+                OPJ_BYTE *new_header_tile_data = (OPJ_BYTE *) opj_realloc(p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_mcc_size);
+                if (! new_header_tile_data) {
+                        opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data);
+                        p_j2k->m_specific_param.m_encoder.m_header_tile_data = NULL;
+                        p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0;
+                        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to write MCC marker\n");
+                        return OPJ_FALSE;
+                }
+                p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data;
+                p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_mcc_size;
+        }
+
+        l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
+
+        opj_write_bytes(l_current_data,J2K_MS_MCC,2);                                   /* MCC */
+        l_current_data += 2;
+
+        opj_write_bytes(l_current_data,l_mcc_size-2,2);                                 /* Lmcc */
+        l_current_data += 2;
+
+        /* first marker */
+        opj_write_bytes(l_current_data,0,2);                                    /* Zmcc */
+        l_current_data += 2;
+
+        opj_write_bytes(l_current_data,p_mcc_record->m_index,1);                                        /* Imcc -> no need for other values, take the first */
+        ++l_current_data;
+
+        /* only one marker atm */
+        opj_write_bytes(l_current_data,0,2);                                    /* Ymcc */
+        l_current_data+=2;
+
+        opj_write_bytes(l_current_data,1,2);                                    /* Qmcc -> number of collections -> 1 */
+        l_current_data+=2;
+
+        opj_write_bytes(l_current_data,0x1,1);                                  /* Xmcci type of component transformation -> array based decorrelation */
+        ++l_current_data;
+
+        opj_write_bytes(l_current_data,p_mcc_record->m_nb_comps | l_mask,2);    /* Nmcci number of input components involved and size for each component offset = 8 bits */
+        l_current_data+=2;
+
+        for (i=0;i<p_mcc_record->m_nb_comps;++i) {
+                opj_write_bytes(l_current_data,i,l_nb_bytes_for_comp);                          /* Cmccij Component offset*/
+                l_current_data+=l_nb_bytes_for_comp;
+        }
+
+        opj_write_bytes(l_current_data,p_mcc_record->m_nb_comps|l_mask,2);      /* Mmcci number of output components involved and size for each component offset = 8 bits */
+        l_current_data+=2;
+
+        for (i=0;i<p_mcc_record->m_nb_comps;++i)
+        {
+                opj_write_bytes(l_current_data,i,l_nb_bytes_for_comp);                          /* Wmccij Component offset*/
+                l_current_data+=l_nb_bytes_for_comp;
+        }
+
+        l_tmcc = ((!p_mcc_record->m_is_irreversible)&1)<<16;
+
+        if (p_mcc_record->m_decorrelation_array) {
+                l_tmcc |= p_mcc_record->m_decorrelation_array->m_index;
+        }
+
+        if (p_mcc_record->m_offset_array) {
+                l_tmcc |= ((p_mcc_record->m_offset_array->m_index)<<8);
+        }
+
+        opj_write_bytes(l_current_data,l_tmcc,3);       /* Tmcci : use MCT defined as number 1 and irreversible array based. */
+        l_current_data+=3;
+
+        if (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_mcc_size,p_manager) != l_mcc_size) {
+                return OPJ_FALSE;
+        }
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_read_mcc (     opj_j2k_t *p_j2k,
+                                                OPJ_BYTE * p_header_data,
+                                                OPJ_UINT32 p_header_size,
+                                                opj_event_mgr_t * p_manager )
+{
+        OPJ_UINT32 i,j;
+        OPJ_UINT32 l_tmp;
+        OPJ_UINT32 l_indix;
+        opj_tcp_t * l_tcp;
+        opj_simple_mcc_decorrelation_data_t * l_mcc_record;
+        opj_mct_data_t * l_mct_data;
+        OPJ_UINT32 l_nb_collections;
+        OPJ_UINT32 l_nb_comps;
+        OPJ_UINT32 l_nb_bytes_by_comp;
+
+        /* preconditions */
+        assert(p_header_data != 00);
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+
+        l_tcp = p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH ?
+                        &p_j2k->m_cp.tcps[p_j2k->m_current_tile_number] :
+                        p_j2k->m_specific_param.m_decoder.m_default_tcp;
+
+        if (p_header_size < 2) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error reading MCC marker\n");
+                return OPJ_FALSE;
+        }
+
+        /* first marker */
+        opj_read_bytes(p_header_data,&l_tmp,2);                         /* Zmcc */
+        p_header_data += 2;
+        if (l_tmp != 0) {
+                opj_event_msg(p_manager, EVT_WARNING, "Cannot take in charge multiple data spanning\n");
+                return OPJ_TRUE;
+        }
+
+        if (p_header_size < 7) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error reading MCC marker\n");
+                return OPJ_FALSE;
+        }
+
+        opj_read_bytes(p_header_data,&l_indix,1); /* Imcc -> no need for other values, take the first */
+        ++p_header_data;
+
+        l_mcc_record = l_tcp->m_mcc_records;
+
+        for(i=0;i<l_tcp->m_nb_mcc_records;++i) {
+                if (l_mcc_record->m_index == l_indix) {
+                        break;
+                }
+                ++l_mcc_record;
+        }
+
+        /** NOT FOUND */
+        if (i == l_tcp->m_nb_mcc_records) {
+                if (l_tcp->m_nb_mcc_records == l_tcp->m_nb_max_mcc_records) {
+                        opj_simple_mcc_decorrelation_data_t *new_mcc_records;
+                        l_tcp->m_nb_max_mcc_records += OPJ_J2K_MCC_DEFAULT_NB_RECORDS;
+
+                        new_mcc_records = (opj_simple_mcc_decorrelation_data_t *) opj_realloc(
+                                        l_tcp->m_mcc_records, l_tcp->m_nb_max_mcc_records * sizeof(opj_simple_mcc_decorrelation_data_t));
+                        if (! new_mcc_records) {
+                                opj_free(l_tcp->m_mcc_records);
+                                l_tcp->m_mcc_records = NULL;
+                                l_tcp->m_nb_max_mcc_records = 0;
+                                l_tcp->m_nb_mcc_records = 0;
+                                opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read MCC marker\n");
+                                return OPJ_FALSE;
+                        }
+                        l_tcp->m_mcc_records = new_mcc_records;
+                        l_mcc_record = l_tcp->m_mcc_records + l_tcp->m_nb_mcc_records;
+                        memset(l_mcc_record,0,(l_tcp->m_nb_max_mcc_records-l_tcp->m_nb_mcc_records) * sizeof(opj_simple_mcc_decorrelation_data_t));
+                }
+                l_mcc_record = l_tcp->m_mcc_records + l_tcp->m_nb_mcc_records;
+        }
+        l_mcc_record->m_index = l_indix;
+
+        /* only one marker atm */
+        opj_read_bytes(p_header_data,&l_tmp,2);                         /* Ymcc */
+        p_header_data+=2;
+        if (l_tmp != 0) {
+                opj_event_msg(p_manager, EVT_WARNING, "Cannot take in charge multiple data spanning\n");
+                return OPJ_TRUE;
+        }
+
+        opj_read_bytes(p_header_data,&l_nb_collections,2);                              /* Qmcc -> number of collections -> 1 */
+        p_header_data+=2;
+
+        if (l_nb_collections > 1) {
+                opj_event_msg(p_manager, EVT_WARNING, "Cannot take in charge multiple collections\n");
+                return OPJ_TRUE;
+        }
+
+        p_header_size -= 7;
+
+        for (i=0;i<l_nb_collections;++i) {
+                if (p_header_size < 3) {
+                        opj_event_msg(p_manager, EVT_ERROR, "Error reading MCC marker\n");
+                        return OPJ_FALSE;
+                }
+
+                opj_read_bytes(p_header_data,&l_tmp,1); /* Xmcci type of component transformation -> array based decorrelation */
+                ++p_header_data;
+
+                if (l_tmp != 1) {
+                        opj_event_msg(p_manager, EVT_WARNING, "Cannot take in charge collections other than array decorrelation\n");
+                        return OPJ_TRUE;
+                }
+
+                opj_read_bytes(p_header_data,&l_nb_comps,2);
+
+                p_header_data+=2;
+                p_header_size-=3;
+
+                l_nb_bytes_by_comp = 1 + (l_nb_comps>>15);
+                l_mcc_record->m_nb_comps = l_nb_comps & 0x7fff;
+
+                if (p_header_size < (l_nb_bytes_by_comp * l_mcc_record->m_nb_comps + 2)) {
+                        opj_event_msg(p_manager, EVT_ERROR, "Error reading MCC marker\n");
+                        return OPJ_FALSE;
+                }
+
+                p_header_size -= (l_nb_bytes_by_comp * l_mcc_record->m_nb_comps + 2);
+
+                for (j=0;j<l_mcc_record->m_nb_comps;++j) {
+                        opj_read_bytes(p_header_data,&l_tmp,l_nb_bytes_by_comp);        /* Cmccij Component offset*/
+                        p_header_data+=l_nb_bytes_by_comp;
+
+                        if (l_tmp != j) {
+                                opj_event_msg(p_manager, EVT_WARNING, "Cannot take in charge collections with indix shuffle\n");
+                                return OPJ_TRUE;
+                        }
+                }
+
+                opj_read_bytes(p_header_data,&l_nb_comps,2);
+                p_header_data+=2;
+
+                l_nb_bytes_by_comp = 1 + (l_nb_comps>>15);
+                l_nb_comps &= 0x7fff;
+
+                if (l_nb_comps != l_mcc_record->m_nb_comps) {
+                        opj_event_msg(p_manager, EVT_WARNING, "Cannot take in charge collections without same number of indixes\n");
+                        return OPJ_TRUE;
+                }
+
+                if (p_header_size < (l_nb_bytes_by_comp * l_mcc_record->m_nb_comps + 3)) {
+                        opj_event_msg(p_manager, EVT_ERROR, "Error reading MCC marker\n");
+                        return OPJ_FALSE;
+                }
+
+                p_header_size -= (l_nb_bytes_by_comp * l_mcc_record->m_nb_comps + 3);
+
+                for (j=0;j<l_mcc_record->m_nb_comps;++j) {
+                        opj_read_bytes(p_header_data,&l_tmp,l_nb_bytes_by_comp);        /* Wmccij Component offset*/
+                        p_header_data+=l_nb_bytes_by_comp;
+
+                        if (l_tmp != j) {
+                                opj_event_msg(p_manager, EVT_WARNING, "Cannot take in charge collections with indix shuffle\n");
+                                return OPJ_TRUE;
+                        }
+                }
+
+                opj_read_bytes(p_header_data,&l_tmp,3); /* Wmccij Component offset*/
+                p_header_data += 3;
+
+                l_mcc_record->m_is_irreversible = ! ((l_tmp>>16) & 1);
+                l_mcc_record->m_decorrelation_array = 00;
+                l_mcc_record->m_offset_array = 00;
+
+                l_indix = l_tmp & 0xff;
+                if (l_indix != 0) {
+                        l_mct_data = l_tcp->m_mct_records;
+                        for (j=0;j<l_tcp->m_nb_mct_records;++j) {
+                                if (l_mct_data->m_index == l_indix) {
+                                        l_mcc_record->m_decorrelation_array = l_mct_data;
+                                        break;
+                                }
+                                ++l_mct_data;
+                        }
+
+                        if (l_mcc_record->m_decorrelation_array == 00) {
+                                opj_event_msg(p_manager, EVT_ERROR, "Error reading MCC marker\n");
+                                return OPJ_FALSE;
+                        }
+                }
+
+                l_indix = (l_tmp >> 8) & 0xff;
+                if (l_indix != 0) {
+                        l_mct_data = l_tcp->m_mct_records;
+                        for (j=0;j<l_tcp->m_nb_mct_records;++j) {
+                                if (l_mct_data->m_index == l_indix) {
+                                        l_mcc_record->m_offset_array = l_mct_data;
+                                        break;
+                                }
+                                ++l_mct_data;
+                        }
+
+                        if (l_mcc_record->m_offset_array == 00) {
+                                opj_event_msg(p_manager, EVT_ERROR, "Error reading MCC marker\n");
+                                return OPJ_FALSE;
+                        }
+                }
+        }
+
+        if (p_header_size != 0) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error reading MCC marker\n");
+                return OPJ_FALSE;
+        }
+
+        ++l_tcp->m_nb_mcc_records;
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_write_mco(     opj_j2k_t *p_j2k,
+                                                struct opj_stream_private *p_stream,
+                                                struct opj_event_mgr * p_manager
+                                  )
+{
+        OPJ_BYTE * l_current_data = 00;
+        OPJ_UINT32 l_mco_size;
+        opj_tcp_t * l_tcp = 00;
+        opj_simple_mcc_decorrelation_data_t * l_mcc_record;
+        OPJ_UINT32 i;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+        assert(p_stream != 00);
+
+        l_tcp =&(p_j2k->m_cp.tcps[p_j2k->m_current_tile_number]);
+        l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
+
+        l_mco_size = 5 + l_tcp->m_nb_mcc_records;
+        if (l_mco_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) {
+
+                OPJ_BYTE *new_header_tile_data = (OPJ_BYTE *) opj_realloc(p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_mco_size);
+                if (! new_header_tile_data) {
+                        opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data);
+                        p_j2k->m_specific_param.m_encoder.m_header_tile_data = NULL;
+                        p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0;
+                        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to write MCO marker\n");
+                        return OPJ_FALSE;
+                }
+                p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data;
+                p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_mco_size;
+        }
+
+        opj_write_bytes(l_current_data,J2K_MS_MCO,2);                   /* MCO */
+        l_current_data += 2;
+
+        opj_write_bytes(l_current_data,l_mco_size-2,2);                 /* Lmco */
+        l_current_data += 2;
+
+        opj_write_bytes(l_current_data,l_tcp->m_nb_mcc_records,1);      /* Nmco : only one tranform stage*/
+        ++l_current_data;
+
+        l_mcc_record = l_tcp->m_mcc_records;
+        for     (i=0;i<l_tcp->m_nb_mcc_records;++i) {
+                opj_write_bytes(l_current_data,l_mcc_record->m_index,1);/* Imco -> use the mcc indicated by 1*/
+                ++l_current_data;
+
+                ++l_mcc_record;
+        }
+
+        if (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_mco_size,p_manager) != l_mco_size) {
+                return OPJ_FALSE;
+        }
+
+        return OPJ_TRUE;
+}
+
+/**
+ * Reads a MCO marker (Multiple Component Transform Ordering)
+ *
+ * @param       p_header_data   the data contained in the MCO box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the MCO marker.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_mco (      opj_j2k_t *p_j2k,
+                                                                    OPJ_BYTE * p_header_data,
+                                                                    OPJ_UINT32 p_header_size,
+                                                                    opj_event_mgr_t * p_manager
+                                    )
+{
+        OPJ_UINT32 l_tmp, i;
+        OPJ_UINT32 l_nb_stages;
+        opj_tcp_t * l_tcp;
+        opj_tccp_t * l_tccp;
+        opj_image_t * l_image;
+
+        /* preconditions */
+        assert(p_header_data != 00);
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+
+        l_image = p_j2k->m_private_image;
+        l_tcp = p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH ?
+                        &p_j2k->m_cp.tcps[p_j2k->m_current_tile_number] :
+                        p_j2k->m_specific_param.m_decoder.m_default_tcp;
+
+        if (p_header_size < 1) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error reading MCO marker\n");
+                return OPJ_FALSE;
+        }
+
+        opj_read_bytes(p_header_data,&l_nb_stages,1);                           /* Nmco : only one tranform stage*/
+        ++p_header_data;
+
+        if (l_nb_stages > 1) {
+                opj_event_msg(p_manager, EVT_WARNING, "Cannot take in charge multiple transformation stages.\n");
+                return OPJ_TRUE;
+        }
+
+        if (p_header_size != l_nb_stages + 1) {
+                opj_event_msg(p_manager, EVT_WARNING, "Error reading MCO marker\n");
+                return OPJ_FALSE;
+        }
+
+        l_tccp = l_tcp->tccps;
+
+        for (i=0;i<l_image->numcomps;++i) {
+                l_tccp->m_dc_level_shift = 0;
+                ++l_tccp;
+        }
+
+        if (l_tcp->m_mct_decoding_matrix) {
+                opj_free(l_tcp->m_mct_decoding_matrix);
+                l_tcp->m_mct_decoding_matrix = 00;
+        }
+
+        for (i=0;i<l_nb_stages;++i) {
+                opj_read_bytes(p_header_data,&l_tmp,1);
+                ++p_header_data;
+
+                if (! opj_j2k_add_mct(l_tcp,p_j2k->m_private_image,l_tmp)) {
+                        return OPJ_FALSE;
+                }
+        }
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_add_mct(opj_tcp_t * p_tcp, opj_image_t * p_image, OPJ_UINT32 p_index)
+{
+        OPJ_UINT32 i;
+        opj_simple_mcc_decorrelation_data_t * l_mcc_record;
+        opj_mct_data_t * l_deco_array, * l_offset_array;
+        OPJ_UINT32 l_data_size,l_mct_size, l_offset_size;
+        OPJ_UINT32 l_nb_elem;
+        OPJ_UINT32 * l_offset_data, * l_current_offset_data;
+        opj_tccp_t * l_tccp;
+
+        /* preconditions */
+        assert(p_tcp != 00);
+
+        l_mcc_record = p_tcp->m_mcc_records;
+
+        for (i=0;i<p_tcp->m_nb_mcc_records;++i) {
+                if (l_mcc_record->m_index == p_index) {
+                        break;
+                }
+        }
+
+        if (i==p_tcp->m_nb_mcc_records) {
+                /** element discarded **/
+                return OPJ_TRUE;
+        }
+
+        if (l_mcc_record->m_nb_comps != p_image->numcomps) {
+                /** do not support number of comps != image */
+                return OPJ_TRUE;
+        }
+
+        l_deco_array = l_mcc_record->m_decorrelation_array;
+
+        if (l_deco_array) {
+                l_data_size = MCT_ELEMENT_SIZE[l_deco_array->m_element_type] * p_image->numcomps * p_image->numcomps;
+                if (l_deco_array->m_data_size != l_data_size) {
+                        return OPJ_FALSE;
+                }
+
+                l_nb_elem = p_image->numcomps * p_image->numcomps;
+                l_mct_size = l_nb_elem * (OPJ_UINT32)sizeof(OPJ_FLOAT32);
+                p_tcp->m_mct_decoding_matrix = (OPJ_FLOAT32*)opj_malloc(l_mct_size);
+
+                if (! p_tcp->m_mct_decoding_matrix ) {
+                        return OPJ_FALSE;
+                }
+
+                j2k_mct_read_functions_to_float[l_deco_array->m_element_type](l_deco_array->m_data,p_tcp->m_mct_decoding_matrix,l_nb_elem);
+        }
+
+        l_offset_array = l_mcc_record->m_offset_array;
+
+        if (l_offset_array) {
+                l_data_size = MCT_ELEMENT_SIZE[l_offset_array->m_element_type] * p_image->numcomps;
+                if (l_offset_array->m_data_size != l_data_size) {
+                        return OPJ_FALSE;
+                }
+
+                l_nb_elem = p_image->numcomps;
+                l_offset_size = l_nb_elem * (OPJ_UINT32)sizeof(OPJ_UINT32);
+                l_offset_data = (OPJ_UINT32*)opj_malloc(l_offset_size);
+
+                if (! l_offset_data ) {
+                        return OPJ_FALSE;
+                }
+
+                j2k_mct_read_functions_to_int32[l_offset_array->m_element_type](l_offset_array->m_data,l_offset_data,l_nb_elem);
+
+                l_tccp = p_tcp->tccps;
+                l_current_offset_data = l_offset_data;
+
+                for (i=0;i<p_image->numcomps;++i) {
+                        l_tccp->m_dc_level_shift = (OPJ_INT32)*(l_current_offset_data++);
+                        ++l_tccp;
+                }
+
+                opj_free(l_offset_data);
+        }
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_write_cbd( opj_j2k_t *p_j2k,
+                                                struct opj_stream_private *p_stream,
+                                                struct opj_event_mgr * p_manager )
+{
+        OPJ_UINT32 i;
+        OPJ_UINT32 l_cbd_size;
+        OPJ_BYTE * l_current_data = 00;
+        opj_image_t *l_image = 00;
+        opj_image_comp_t * l_comp = 00;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+        assert(p_stream != 00);
+
+        l_image = p_j2k->m_private_image;
+        l_cbd_size = 6 + p_j2k->m_private_image->numcomps;
+
+        if (l_cbd_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) {
+                OPJ_BYTE *new_header_tile_data = (OPJ_BYTE *) opj_realloc(p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_cbd_size);
+                if (! new_header_tile_data) {
+                        opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data);
+                        p_j2k->m_specific_param.m_encoder.m_header_tile_data = NULL;
+                        p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0;
+                        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to write CBD marker\n");
+                        return OPJ_FALSE;
+                }
+                p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data;
+                p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_cbd_size;
+        }
+
+        l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
+
+        opj_write_bytes(l_current_data,J2K_MS_CBD,2);                   /* CBD */
+        l_current_data += 2;
+
+        opj_write_bytes(l_current_data,l_cbd_size-2,2);                 /* L_CBD */
+        l_current_data += 2;
+
+        opj_write_bytes(l_current_data,l_image->numcomps, 2);           /* Ncbd */
+        l_current_data+=2;
+
+        l_comp = l_image->comps;
+
+        for (i=0;i<l_image->numcomps;++i) {
+                opj_write_bytes(l_current_data, (l_comp->sgnd << 7) | (l_comp->prec - 1), 1);           /* Component bit depth */
+                ++l_current_data;
+
+                ++l_comp;
+        }
+
+        if (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_cbd_size,p_manager) != l_cbd_size) {
+                return OPJ_FALSE;
+        }
+
+        return OPJ_TRUE;
+}
+
+/**
+ * Reads a CBD marker (Component bit depth definition)
+ * @param       p_header_data   the data contained in the CBD box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the CBD marker.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_cbd (      opj_j2k_t *p_j2k,
+                                                                OPJ_BYTE * p_header_data,
+                                                                OPJ_UINT32 p_header_size,
+                                                                opj_event_mgr_t * p_manager
+                                    )
+{
+        OPJ_UINT32 l_nb_comp,l_num_comp;
+        OPJ_UINT32 l_comp_def;
+        OPJ_UINT32 i;
+        opj_image_comp_t * l_comp = 00;
+
+        /* preconditions */
+        assert(p_header_data != 00);
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+
+        l_num_comp = p_j2k->m_private_image->numcomps;
+
+        if (p_header_size != (p_j2k->m_private_image->numcomps + 2)) {
+                opj_event_msg(p_manager, EVT_ERROR, "Crror reading CBD marker\n");
+                return OPJ_FALSE;
+        }
+
+        opj_read_bytes(p_header_data,&l_nb_comp,2);                             /* Ncbd */
+        p_header_data+=2;
+
+        if (l_nb_comp != l_num_comp) {
+                opj_event_msg(p_manager, EVT_ERROR, "Crror reading CBD marker\n");
+                return OPJ_FALSE;
+        }
+
+        l_comp = p_j2k->m_private_image->comps;
+        for (i=0;i<l_num_comp;++i) {
+                opj_read_bytes(p_header_data,&l_comp_def,1);                    /* Component bit depth */
+                ++p_header_data;
+        l_comp->sgnd = (l_comp_def>>7) & 1;
+                l_comp->prec = (l_comp_def&0x7f) + 1;
+                ++l_comp;
+        }
+
+        return OPJ_TRUE;
+}
+
+/* ----------------------------------------------------------------------- */
+/* J2K / JPT decoder interface                                             */
+/* ----------------------------------------------------------------------- */
+
+void opj_j2k_setup_decoder(opj_j2k_t *j2k, opj_dparameters_t *parameters)
+{
+        if(j2k && parameters) {
+                j2k->m_cp.m_specific_param.m_dec.m_layer = parameters->cp_layer;
+                j2k->m_cp.m_specific_param.m_dec.m_reduce = parameters->cp_reduce;
+
+#ifdef USE_JPWL
+                j2k->m_cp.correct = parameters->jpwl_correct;
+                j2k->m_cp.exp_comps = parameters->jpwl_exp_comps;
+                j2k->m_cp.max_tiles = parameters->jpwl_max_tiles;
+#endif /* USE_JPWL */
+        }
+}
+
+/* ----------------------------------------------------------------------- */
+/* J2K encoder interface                                                       */
+/* ----------------------------------------------------------------------- */
+
+opj_j2k_t* opj_j2k_create_compress(void)
+{
+        opj_j2k_t *l_j2k = (opj_j2k_t*) opj_malloc(sizeof(opj_j2k_t));
+        if (!l_j2k) {
+                return NULL;
+        }
+
+        memset(l_j2k,0,sizeof(opj_j2k_t));
+
+        l_j2k->m_is_decoder = 0;
+        l_j2k->m_cp.m_is_decoder = 0;
+
+        l_j2k->m_specific_param.m_encoder.m_header_tile_data = (OPJ_BYTE *) opj_malloc(OPJ_J2K_DEFAULT_HEADER_SIZE);
+        if (! l_j2k->m_specific_param.m_encoder.m_header_tile_data) {
+                opj_j2k_destroy(l_j2k);
+                return NULL;
+        }
+
+        l_j2k->m_specific_param.m_encoder.m_header_tile_data_size = OPJ_J2K_DEFAULT_HEADER_SIZE;
+
+        /* validation list creation*/
+        l_j2k->m_validation_list = opj_procedure_list_create();
+        if (! l_j2k->m_validation_list) {
+                opj_j2k_destroy(l_j2k);
+                return NULL;
+        }
+
+        /* execution list creation*/
+        l_j2k->m_procedure_list = opj_procedure_list_create();
+        if (! l_j2k->m_procedure_list) {
+                opj_j2k_destroy(l_j2k);
+                return NULL;
+        }
+
+        return l_j2k;
+}
+
+int opj_j2k_initialise_4K_poc(opj_poc_t *POC, int numres){
+    POC[0].tile  = 1;
+    POC[0].resno0  = 0;
+    POC[0].compno0 = 0;
+    POC[0].layno1  = 1;
+    POC[0].resno1  = (OPJ_UINT32)(numres-1);
+    POC[0].compno1 = 3;
+    POC[0].prg1 = OPJ_CPRL;
+    POC[1].tile  = 1;
+    POC[1].resno0  = (OPJ_UINT32)(numres-1);
+    POC[1].compno0 = 0;
+    POC[1].layno1  = 1;
+    POC[1].resno1  = (OPJ_UINT32)numres;
+    POC[1].compno1 = 3;
+    POC[1].prg1 = OPJ_CPRL;
+    return 2;
+}
+
+void opj_j2k_set_cinema_parameters(opj_cparameters_t *parameters, opj_image_t *image, opj_event_mgr_t *p_manager)
+{
+    /* Configure cinema parameters */
+    OPJ_FLOAT32 max_rate = 0;
+    OPJ_FLOAT32 temp_rate = 0;
+    int i;
+
+    /* profile (Rsiz) */
+    switch (parameters->cp_cinema){
+    case OPJ_CINEMA2K_24:
+    case OPJ_CINEMA2K_48:
+        parameters->cp_rsiz = OPJ_CINEMA2K;
+        break;
+    case OPJ_CINEMA4K_24:
+        parameters->cp_rsiz = OPJ_CINEMA4K;
+        break;
+    case OPJ_OFF:
+        assert(0);
+        break;
+    }
+
+    /* No tiling */
+    parameters->tile_size_on = OPJ_FALSE;
+    parameters->cp_tdx=1;
+    parameters->cp_tdy=1;
+
+    /* One tile part for each component */
+    parameters->tp_flag = 'C';
+    parameters->tp_on = 1;
+
+    /* Tile and Image shall be at (0,0) */
+    parameters->cp_tx0 = 0;
+    parameters->cp_ty0 = 0;
+    parameters->image_offset_x0 = 0;
+    parameters->image_offset_y0 = 0;
+
+    /* Codeblock size= 32*32 */
+    parameters->cblockw_init = 32;
+    parameters->cblockh_init = 32;
+
+    /* Codeblock style: no mode switch enabled */
+    parameters->mode = 0;
+
+    /* No ROI */
+    parameters->roi_compno = -1;
+
+    /* No subsampling */
+    parameters->subsampling_dx = 1;
+    parameters->subsampling_dy = 1;
+
+    /* 9-7 transform */
+    parameters->irreversible = 1;
+
+    /* Number of layers */
+    if (parameters->tcp_numlayers > 1){
+        opj_event_msg(p_manager, EVT_WARNING,
+                "JPEG 2000 Profile-3 and 4 (2k/4k dc profile) requires:\n"
+                "1 single quality layer"
+                "-> Number of layers forced to 1 (rather than %d)\n",
+                parameters->tcp_numlayers);
+        parameters->tcp_numlayers = 1;
+    }
+
+    /* Resolution levels */
+    switch (parameters->cp_cinema){
+    case OPJ_CINEMA2K_24:
+    case OPJ_CINEMA2K_48:
+        if(parameters->numresolution > 6){
+            opj_event_msg(p_manager, EVT_WARNING,
+                    "JPEG 2000 Profile-3 (2k dc profile) requires:\n"
+                    "Number of decomposition levels <= 5\n"
+                    "-> Number of decomposition levels forced to 5 (rather than %d)\n",
+                    parameters->numresolution+1);
+            parameters->numresolution = 6;
+        }
+        break;
+    case OPJ_CINEMA4K_24:
+        if(parameters->numresolution < 2){
+            opj_event_msg(p_manager, EVT_WARNING,
+                    "JPEG 2000 Profile-4 (4k dc profile) requires:\n"
+                    "Number of decomposition levels >= 1 && <= 6\n"
+                    "-> Number of decomposition levels forced to 1 (rather than %d)\n",
+                    parameters->numresolution+1);
+            parameters->numresolution = 1;
+        }else if(parameters->numresolution > 7){
+            opj_event_msg(p_manager, EVT_WARNING,
+                    "JPEG 2000 Profile-4 (4k dc profile) requires:\n"
+                    "Number of decomposition levels >= 1 && <= 6\n"
+                    "-> Number of decomposition levels forced to 6 (rather than %d)\n",
+                    parameters->numresolution+1);
+            parameters->numresolution = 7;
+        }
+        break;
+    default :
+        break;
+    }
+
+    /* Precincts */
+    parameters->csty |= 0x01;
+    parameters->res_spec = parameters->numresolution-1;
+    for (i = 0; i<parameters->res_spec; i++) {
+        parameters->prcw_init[i] = 256;
+        parameters->prch_init[i] = 256;
+    }
+
+    /* The progression order shall be CPRL */
+    parameters->prog_order = OPJ_CPRL;
+
+    /* Progression order changes for 4K, disallowed for 2K */
+    if (parameters->cp_cinema == OPJ_CINEMA4K_24) {
+        parameters->numpocs = (OPJ_UINT32)opj_j2k_initialise_4K_poc(parameters->POC,parameters->numresolution);
+    } else {
+        parameters->numpocs = 0;
+    }
+
+    /* Limited bit-rate */
+    parameters->cp_disto_alloc = 1;
+    switch (parameters->cp_cinema){
+    case OPJ_CINEMA2K_24:
+    case OPJ_CINEMA4K_24:
+        max_rate = (OPJ_FLOAT32) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec)/
+                (OPJ_FLOAT32)(CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy);
+        if (parameters->tcp_rates[0] == 0){
+            parameters->tcp_rates[0] = max_rate;
+        }else{
+            temp_rate =(OPJ_FLOAT32)(image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec)/
+                    (parameters->tcp_rates[0] * 8 * (OPJ_FLOAT32)image->comps[0].dx * (OPJ_FLOAT32)image->comps[0].dy);
+            if (temp_rate > CINEMA_24_CS ){
+                opj_event_msg(p_manager, EVT_WARNING,
+                        "JPEG 2000 Profile-3 and 4 (2k/4k dc profile) requires:\n"
+                        "Maximum 1302083 compressed bytes @ 24fps\n"
+                        "-> Specified rate (%3.1f) exceeds this limit. Rate will be forced to %3.1f.\n",
+                        parameters->tcp_rates[0], max_rate);
+                parameters->tcp_rates[0]= max_rate;
+            }else{
+                opj_event_msg(p_manager, EVT_WARNING,
+                        "JPEG 2000 Profile-3 and 4 (2k/4k dc profile):\n"
+                        "INFO : Specified rate (%3.1f) is below the 2k/4k limit @ 24fps.\n",
+                        parameters->tcp_rates[0]);
+            }
+        }
+        parameters->max_comp_size = COMP_24_CS;
+        break;
+    case OPJ_CINEMA2K_48:
+        max_rate = ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
+                (float)(CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy);
+        if (parameters->tcp_rates[0] == 0){
+            parameters->tcp_rates[0] = max_rate;
+        }else{
+            temp_rate =((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
+                    (parameters->tcp_rates[0] * 8 * (float)image->comps[0].dx * (float)image->comps[0].dy);
+            if (temp_rate > CINEMA_48_CS ){
+                opj_event_msg(p_manager, EVT_WARNING,
+                        "JPEG 2000 Profile-3 (2k dc profile) requires:\n"
+                        "Maximum 651041 compressed bytes @ 48fps\n"
+                        "-> Specified rate (%3.1f) exceeds this limit. Rate will be forced to %3.1f.\n",
+                        parameters->tcp_rates[0], max_rate);
+                parameters->tcp_rates[0]= max_rate;
+            }else{
+                opj_event_msg(p_manager, EVT_WARNING,
+                        "JPEG 2000 Profile-3 (2k dc profile):\n"
+                        "INFO : Specified rate (%3.1f) is below the 2k limit @ 48 fps.\n",
+                        parameters->tcp_rates[0]);
+            }
+        }
+        parameters->max_comp_size = COMP_48_CS;
+        break;
+    default:
+        break;
+    }
+}
+
+OPJ_BOOL opj_j2k_is_cinema_compliant(opj_image_t *image, OPJ_CINEMA_MODE cinema_mode, opj_event_mgr_t *p_manager)
+{
+    OPJ_UINT32 i;
+
+    /* Number of components */
+    if (image->numcomps != 3){
+        opj_event_msg(p_manager, EVT_WARNING,
+                "JPEG 2000 Profile-3 (2k dc profile) requires:\n"
+                "3 components"
+                "-> Number of components of input image (%d) is not compliant\n"
+                "-> Non-profile-3 codestream will be generated\n",
+                image->numcomps);
+        return OPJ_FALSE;
+    }
+
+    /* Bitdepth */
+    for (i = 0; i < image->numcomps; i++) {
+        if ((image->comps[i].bpp != 12) | (image->comps[i].sgnd)){
+            char signed_str[] = "signed";
+            char unsigned_str[] = "unsigned";
+            char *tmp_str = image->comps[i].sgnd?signed_str:unsigned_str;
+            opj_event_msg(p_manager, EVT_WARNING,
+                    "JPEG 2000 Profile-3 (2k dc profile) requires:\n"
+                    "Precision of each component shall be 12 bits unsigned"
+                    "-> At least component %d of input image (%d bits, %s) is not compliant\n"
+                    "-> Non-profile-3 codestream will be generated\n",
+                    i,image->comps[i].bpp, tmp_str);
+            return OPJ_FALSE;
+        }
+    }
+
+    /* Image size */
+    switch (cinema_mode){
+    case OPJ_CINEMA2K_24:
+    case OPJ_CINEMA2K_48:
+        if (((image->comps[0].w > 2048) | (image->comps[0].h > 1080))){
+            opj_event_msg(p_manager, EVT_WARNING,
+                    "JPEG 2000 Profile-3 (2k dc profile) requires:\n"
+                    "width <= 2048 and height <= 1080\n"
+                    "-> Input image size %d x %d is not compliant\n"
+                    "-> Non-profile-3 codestream will be generated\n",
+                    image->comps[0].w,image->comps[0].h);
+            return OPJ_FALSE;
+        }
+        break;
+    case OPJ_CINEMA4K_24:
+        if (((image->comps[0].w > 4096) | (image->comps[0].h > 2160))){
+            opj_event_msg(p_manager, EVT_WARNING,
+                    "JPEG 2000 Profile-4 (4k dc profile) requires:\n"
+                    "width <= 4096 and height <= 2160\n"
+                    "-> Image size %d x %d is not compliant\n"
+                    "-> Non-profile-4 codestream will be generated\n",
+                    image->comps[0].w,image->comps[0].h);
+            return OPJ_FALSE;
+        }
+        break;
+    default :
+        break;
+    }
+
+    return OPJ_TRUE;
+}
+
+void opj_j2k_setup_encoder(     opj_j2k_t *p_j2k,
+                                                    opj_cparameters_t *parameters,
+                                                    opj_image_t *image,
+                                                    opj_event_mgr_t * p_manager)
+{
+        OPJ_UINT32 i, j, tileno, numpocs_tile;
+        opj_cp_t *cp = 00;
+
+        if(!p_j2k || !parameters || ! image) {
+                return;
+        }
+
+        /* keep a link to cp so that we can destroy it later in j2k_destroy_compress */
+        cp = &(p_j2k->m_cp);
+
+        /* set default values for cp */
+        cp->tw = 1;
+        cp->th = 1;
+
+        /* set cinema parameters if required */
+        if (parameters->cp_cinema){
+            opj_j2k_set_cinema_parameters(parameters,image,p_manager);
+            if (!opj_j2k_is_cinema_compliant(image,parameters->cp_cinema,p_manager)) {
+                parameters->cp_rsiz = OPJ_STD_RSIZ;
+            }
+        }
+
+        /*
+        copy user encoding parameters
+        */
+        cp->m_specific_param.m_enc.m_cinema = parameters->cp_cinema;
+        cp->m_specific_param.m_enc.m_max_comp_size = (OPJ_UINT32)parameters->max_comp_size;
+        cp->rsiz   = parameters->cp_rsiz;
+        cp->m_specific_param.m_enc.m_disto_alloc = (OPJ_UINT32)parameters->cp_disto_alloc & 1u;
+        cp->m_specific_param.m_enc.m_fixed_alloc = (OPJ_UINT32)parameters->cp_fixed_alloc & 1u;
+        cp->m_specific_param.m_enc.m_fixed_quality = (OPJ_UINT32)parameters->cp_fixed_quality & 1u;
+
+        /* mod fixed_quality */
+        if (parameters->cp_fixed_alloc && parameters->cp_matrice) {
+                size_t array_size = (size_t)parameters->tcp_numlayers * (size_t)parameters->numresolution * 3 * sizeof(OPJ_INT32);
+                cp->m_specific_param.m_enc.m_matrice = (OPJ_INT32 *) opj_malloc(array_size);
+                memcpy(cp->m_specific_param.m_enc.m_matrice, parameters->cp_matrice, array_size);
+        }
+
+        /* tiles */
+        cp->tdx = (OPJ_UINT32)parameters->cp_tdx;
+        cp->tdy = (OPJ_UINT32)parameters->cp_tdy;
+
+        /* tile offset */
+        cp->tx0 = (OPJ_UINT32)parameters->cp_tx0;
+        cp->ty0 = (OPJ_UINT32)parameters->cp_ty0;
+
+        /* comment string */
+        if(parameters->cp_comment) {
+                cp->comment = (char*)opj_malloc(strlen(parameters->cp_comment) + 1);
+                if(cp->comment) {
+                        strcpy(cp->comment, parameters->cp_comment);
+                }
+        }
+
+        /*
+        calculate other encoding parameters
+        */
+
+        if (parameters->tile_size_on) {
+                cp->tw = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)(image->x1 - cp->tx0), (OPJ_INT32)cp->tdx);
+                cp->th = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)(image->y1 - cp->ty0), (OPJ_INT32)cp->tdy);
+        } else {
+                cp->tdx = image->x1 - cp->tx0;
+                cp->tdy = image->y1 - cp->ty0;
+        }
+
+        if (parameters->tp_on) {
+                cp->m_specific_param.m_enc.m_tp_flag = (OPJ_BYTE)parameters->tp_flag;
+                cp->m_specific_param.m_enc.m_tp_on = 1;
+        }
+
+#ifdef USE_JPWL
+        /*
+        calculate JPWL encoding parameters
+        */
+
+        if (parameters->jpwl_epc_on) {
+                OPJ_INT32 i;
+
+                /* set JPWL on */
+                cp->epc_on = OPJ_TRUE;
+                cp->info_on = OPJ_FALSE; /* no informative technique */
+
+                /* set EPB on */
+                if ((parameters->jpwl_hprot_MH > 0) || (parameters->jpwl_hprot_TPH[0] > 0)) {
+                        cp->epb_on = OPJ_TRUE;
+
+                        cp->hprot_MH = parameters->jpwl_hprot_MH;
+                        for (i = 0; i < JPWL_MAX_NO_TILESPECS; i++) {
+                                cp->hprot_TPH_tileno[i] = parameters->jpwl_hprot_TPH_tileno[i];
+                                cp->hprot_TPH[i] = parameters->jpwl_hprot_TPH[i];
+                        }
+                        /* if tile specs are not specified, copy MH specs */
+                        if (cp->hprot_TPH[0] == -1) {
+                                cp->hprot_TPH_tileno[0] = 0;
+                                cp->hprot_TPH[0] = parameters->jpwl_hprot_MH;
+                        }
+                        for (i = 0; i < JPWL_MAX_NO_PACKSPECS; i++) {
+                                cp->pprot_tileno[i] = parameters->jpwl_pprot_tileno[i];
+                                cp->pprot_packno[i] = parameters->jpwl_pprot_packno[i];
+                                cp->pprot[i] = parameters->jpwl_pprot[i];
+                        }
+                }
+
+                /* set ESD writing */
+                if ((parameters->jpwl_sens_size == 1) || (parameters->jpwl_sens_size == 2)) {
+                        cp->esd_on = OPJ_TRUE;
+
+                        cp->sens_size = parameters->jpwl_sens_size;
+                        cp->sens_addr = parameters->jpwl_sens_addr;
+                        cp->sens_range = parameters->jpwl_sens_range;
+
+                        cp->sens_MH = parameters->jpwl_sens_MH;
+                        for (i = 0; i < JPWL_MAX_NO_TILESPECS; i++) {
+                                cp->sens_TPH_tileno[i] = parameters->jpwl_sens_TPH_tileno[i];
+                                cp->sens_TPH[i] = parameters->jpwl_sens_TPH[i];
+                        }
+                }
+
+                /* always set RED writing to false: we are at the encoder */
+                cp->red_on = OPJ_FALSE;
+
+        } else {
+                cp->epc_on = OPJ_FALSE;
+        }
+#endif /* USE_JPWL */
+
+        /* initialize the mutiple tiles */
+        /* ---------------------------- */
+        cp->tcps = (opj_tcp_t*) opj_calloc(cp->tw * cp->th, sizeof(opj_tcp_t));
+        if (parameters->numpocs) {
+                /* initialisation of POC */
+                opj_j2k_check_poc_val(parameters->POC,parameters->numpocs, (OPJ_UINT32)parameters->numresolution, image->numcomps, (OPJ_UINT32)parameters->tcp_numlayers, p_manager);
+                /* TODO MSD use the return value*/
+        }
+
+        for (tileno = 0; tileno < cp->tw * cp->th; tileno++) {
+                opj_tcp_t *tcp = &cp->tcps[tileno];
+                tcp->numlayers = (OPJ_UINT32)parameters->tcp_numlayers;
+
+                for (j = 0; j < tcp->numlayers; j++) {
+                        if(cp->m_specific_param.m_enc.m_cinema){
+                                if (cp->m_specific_param.m_enc.m_fixed_quality) {
+                                        tcp->distoratio[j] = parameters->tcp_distoratio[j];
+                                }
+                                tcp->rates[j] = parameters->tcp_rates[j];
+                        }else{
+                                if (cp->m_specific_param.m_enc.m_fixed_quality) {       /* add fixed_quality */
+                                        tcp->distoratio[j] = parameters->tcp_distoratio[j];
+                                } else {
+                                        tcp->rates[j] = parameters->tcp_rates[j];
+                                }
+                        }
+                }
+
+                tcp->csty = (OPJ_UINT32)parameters->csty;
+                tcp->prg = parameters->prog_order;
+                tcp->mct = (OPJ_UINT32)parameters->tcp_mct;
+
+                numpocs_tile = 0;
+                tcp->POC = 0;
+
+                if (parameters->numpocs) {
+                        /* initialisation of POC */
+                        tcp->POC = 1;
+                        for (i = 0; i < parameters->numpocs; i++) {
+                                if (tileno + 1 == parameters->POC[i].tile )  {
+                                        opj_poc_t *tcp_poc = &tcp->pocs[numpocs_tile];
+
+                                        tcp_poc->resno0         = parameters->POC[numpocs_tile].resno0;
+                                        tcp_poc->compno0        = parameters->POC[numpocs_tile].compno0;
+                                        tcp_poc->layno1         = parameters->POC[numpocs_tile].layno1;
+                                        tcp_poc->resno1         = parameters->POC[numpocs_tile].resno1;
+                                        tcp_poc->compno1        = parameters->POC[numpocs_tile].compno1;
+                                        tcp_poc->prg1           = parameters->POC[numpocs_tile].prg1;
+                                        tcp_poc->tile           = parameters->POC[numpocs_tile].tile;
+
+                                        numpocs_tile++;
+                                }
+                        }
+
+                        tcp->numpocs = numpocs_tile -1 ;
+                }else{
+                        tcp->numpocs = 0;
+                }
+
+                tcp->tccps = (opj_tccp_t*) opj_calloc(image->numcomps, sizeof(opj_tccp_t));
+
+                if (parameters->mct_data) {
+                      
+                    OPJ_UINT32 lMctSize = image->numcomps * image->numcomps * (OPJ_UINT32)sizeof(OPJ_FLOAT32);
+                    OPJ_FLOAT32 * lTmpBuf = (OPJ_FLOAT32*)opj_malloc(lMctSize);
+                    OPJ_INT32 * l_dc_shift = (OPJ_INT32 *) ((OPJ_BYTE *) parameters->mct_data + lMctSize);
+
+                    tcp->mct = 2;
+                    tcp->m_mct_coding_matrix = (OPJ_FLOAT32*)opj_malloc(lMctSize);
+                    memcpy(tcp->m_mct_coding_matrix,parameters->mct_data,lMctSize);
+                    memcpy(lTmpBuf,parameters->mct_data,lMctSize);
+
+                    tcp->m_mct_decoding_matrix = (OPJ_FLOAT32*)opj_malloc(lMctSize);
+                    assert(opj_matrix_inversion_f(lTmpBuf,(tcp->m_mct_decoding_matrix),image->numcomps));
+
+                    tcp->mct_norms = (OPJ_FLOAT64*)
+                                    opj_malloc(image->numcomps * sizeof(OPJ_FLOAT64));
+
+                    opj_calculate_norms(tcp->mct_norms,image->numcomps,tcp->m_mct_decoding_matrix);
+                    opj_free(lTmpBuf);
+
+                    for (i = 0; i < image->numcomps; i++) {
+                            opj_tccp_t *tccp = &tcp->tccps[i];
+                            tccp->m_dc_level_shift = l_dc_shift[i];
+                    }
+
+                    opj_j2k_setup_mct_encoding(tcp,image);                        
+                }
+                else {
+                        for (i = 0; i < image->numcomps; i++) {
+                                opj_tccp_t *tccp = &tcp->tccps[i];
+                                opj_image_comp_t * l_comp = &(image->comps[i]);
+
+                                if (! l_comp->sgnd) {
+                                        tccp->m_dc_level_shift = 1 << (l_comp->prec - 1);
+                                }
+                        }
+                }
+
+                for (i = 0; i < image->numcomps; i++) {
+                        opj_tccp_t *tccp = &tcp->tccps[i];
+
+                        tccp->csty = parameters->csty & 0x01;   /* 0 => one precinct || 1 => custom precinct  */
+                        tccp->numresolutions = (OPJ_UINT32)parameters->numresolution;
+                        tccp->cblkw = (OPJ_UINT32)opj_int_floorlog2(parameters->cblockw_init);
+                        tccp->cblkh = (OPJ_UINT32)opj_int_floorlog2(parameters->cblockh_init);
+                        tccp->cblksty = (OPJ_UINT32)parameters->mode;
+                        tccp->qmfbid = parameters->irreversible ? 0 : 1;
+                        tccp->qntsty = parameters->irreversible ? J2K_CCP_QNTSTY_SEQNT : J2K_CCP_QNTSTY_NOQNT;
+                        tccp->numgbits = 2;
+
+                        if ((OPJ_INT32)i == parameters->roi_compno) {
+                                tccp->roishift = parameters->roi_shift;
+                        } else {
+                                tccp->roishift = 0;
+                        }
+
+                                if (parameters->csty & J2K_CCP_CSTY_PRT) {
+                                        OPJ_INT32 p = 0, it_res;
+                                        assert( tccp->numresolutions > 0 );
+                                        for (it_res = (OPJ_INT32)tccp->numresolutions - 1; it_res >= 0; it_res--) {
+                                                if (p < parameters->res_spec) {
+
+                                                        if (parameters->prcw_init[p] < 1) {
+                                                                tccp->prcw[it_res] = 1;
+                                                        } else {
+                                                                tccp->prcw[it_res] = (OPJ_UINT32)opj_int_floorlog2(parameters->prcw_init[p]);
+                                                        }
+
+                                                        if (parameters->prch_init[p] < 1) {
+                                                                tccp->prch[it_res] = 1;
+                                                        }else {
+                                                                tccp->prch[it_res] = (OPJ_UINT32)opj_int_floorlog2(parameters->prch_init[p]);
+                                                        }
+
+                                                } else {
+                                                        OPJ_INT32 res_spec = parameters->res_spec;
+                                                        OPJ_INT32 size_prcw = 0;
+                                                        OPJ_INT32 size_prch = 0;
+
+                                                        assert(res_spec>0); /* issue 189 */
+                                                        size_prcw = parameters->prcw_init[res_spec - 1] >> (p - (res_spec - 1));
+                                                        size_prch = parameters->prch_init[res_spec - 1] >> (p - (res_spec - 1));
+
+
+                                                        if (size_prcw < 1) {
+                                                                tccp->prcw[it_res] = 1;
+                                                        } else {
+                                                                tccp->prcw[it_res] = (OPJ_UINT32)opj_int_floorlog2(size_prcw);
+                                                        }
+
+                                                        if (size_prch < 1) {
+                                                                tccp->prch[it_res] = 1;
+                                                        } else {
+                                                                tccp->prch[it_res] = (OPJ_UINT32)opj_int_floorlog2(size_prch);
+                                                        }
+                                                }
+                                                p++;
+                                                /*printf("\nsize precinct for level %d : %d,%d\n", it_res,tccp->prcw[it_res], tccp->prch[it_res]); */
+                                        }       /*end for*/
+                                } else {
+                                        for (j = 0; j < tccp->numresolutions; j++) {
+                                                tccp->prcw[j] = 15;
+                                                tccp->prch[j] = 15;
+                                        }
+                                }
+
+                        opj_dwt_calc_explicit_stepsizes(tccp, image->comps[i].prec);
+                }
+        }
+
+        if (parameters->mct_data) {
+                opj_free(parameters->mct_data);
+                parameters->mct_data = 00;
+        }
+}
+
+static OPJ_BOOL opj_j2k_add_mhmarker(opj_codestream_index_t *cstr_index, OPJ_UINT32 type, OPJ_OFF_T pos, OPJ_UINT32 len)
+{
+        assert(cstr_index != 00);
+
+        /* expand the list? */
+        if ((cstr_index->marknum + 1) > cstr_index->maxmarknum) {
+                opj_marker_info_t *new_marker;
+                cstr_index->maxmarknum = (OPJ_UINT32)(100 + (OPJ_FLOAT32) cstr_index->maxmarknum);
+                new_marker = (opj_marker_info_t *) opj_realloc(cstr_index->marker, cstr_index->maxmarknum *sizeof(opj_marker_info_t));
+                if (! new_marker) {
+                        opj_free(cstr_index->marker);
+                        cstr_index->marker = NULL;
+                        cstr_index->maxmarknum = 0;
+                        cstr_index->marknum = 0;
+                        /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to add mh marker\n"); */
+                        return OPJ_FALSE;
+                }
+                cstr_index->marker = new_marker;
+        }
+
+        /* add the marker */
+        cstr_index->marker[cstr_index->marknum].type = (OPJ_UINT16)type;
+        cstr_index->marker[cstr_index->marknum].pos = (OPJ_INT32)pos;
+        cstr_index->marker[cstr_index->marknum].len = (OPJ_INT32)len;
+        cstr_index->marknum++;
+        return OPJ_TRUE;
+}
+
+static OPJ_BOOL opj_j2k_add_tlmarker(OPJ_UINT32 tileno, opj_codestream_index_t *cstr_index, OPJ_UINT32 type, OPJ_OFF_T pos, OPJ_UINT32 len)
+{
+        assert(cstr_index != 00);
+        assert(cstr_index->tile_index != 00);
+
+        /* expand the list? */
+        if ((cstr_index->tile_index[tileno].marknum + 1) > cstr_index->tile_index[tileno].maxmarknum) {
+                opj_marker_info_t *new_marker;
+                cstr_index->tile_index[tileno].maxmarknum = (OPJ_UINT32)(100 + (OPJ_FLOAT32) cstr_index->tile_index[tileno].maxmarknum);
+                new_marker = (opj_marker_info_t *) opj_realloc(
+                                cstr_index->tile_index[tileno].marker,
+                                cstr_index->tile_index[tileno].maxmarknum *sizeof(opj_marker_info_t));
+                if (! new_marker) {
+                        opj_free(cstr_index->tile_index[tileno].marker);
+                        cstr_index->tile_index[tileno].marker = NULL;
+                        cstr_index->tile_index[tileno].maxmarknum = 0;
+                        cstr_index->tile_index[tileno].marknum = 0;
+                        /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to add tl marker\n"); */
+                        return OPJ_FALSE;
+                }
+                cstr_index->tile_index[tileno].marker = new_marker;
+        }
+
+        /* add the marker */
+        cstr_index->tile_index[tileno].marker[cstr_index->tile_index[tileno].marknum].type = (OPJ_UINT16)type;
+        cstr_index->tile_index[tileno].marker[cstr_index->tile_index[tileno].marknum].pos = (OPJ_INT32)pos;
+        cstr_index->tile_index[tileno].marker[cstr_index->tile_index[tileno].marknum].len = (OPJ_INT32)len;
+        cstr_index->tile_index[tileno].marknum++;
+
+        if (type == J2K_MS_SOT) {
+                OPJ_UINT32 l_current_tile_part = cstr_index->tile_index[tileno].current_tpsno;
+
+                if (cstr_index->tile_index[tileno].tp_index)
+                        cstr_index->tile_index[tileno].tp_index[l_current_tile_part].start_pos = pos;
+
+        }
+        return OPJ_TRUE;
+}
+
+/*
+ * -----------------------------------------------------------------------
+ * -----------------------------------------------------------------------
+ * -----------------------------------------------------------------------
+ */
+
+OPJ_BOOL opj_j2k_end_decompress(opj_j2k_t *p_j2k,
+                                opj_stream_private_t *p_stream,
+                                opj_event_mgr_t * p_manager
+                                )
+{
+    (void)p_j2k;
+    (void)p_stream;
+    (void)p_manager;
+    return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_read_header(   opj_stream_private_t *p_stream,
+                                                            opj_j2k_t* p_j2k,
+                                                            opj_image_t** p_image,
+                                                            opj_event_mgr_t* p_manager )
+{
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_stream != 00);
+        assert(p_manager != 00);
+
+        /* create an empty image header */
+        p_j2k->m_private_image = opj_image_create0();
+        if (! p_j2k->m_private_image) {
+                return OPJ_FALSE;
+        }
+
+        /* customization of the validation */
+        opj_j2k_setup_decoding_validation(p_j2k);
+
+        /* validation of the parameters codec */
+        if (! opj_j2k_exec(p_j2k, p_j2k->m_validation_list, p_stream,p_manager)) {
+                opj_image_destroy(p_j2k->m_private_image);
+                p_j2k->m_private_image = NULL;
+                return OPJ_FALSE;
+        }
+
+        /* customization of the encoding */
+        opj_j2k_setup_header_reading(p_j2k);
+
+        /* read header */
+        if (! opj_j2k_exec (p_j2k,p_j2k->m_procedure_list,p_stream,p_manager)) {
+                opj_image_destroy(p_j2k->m_private_image);
+                p_j2k->m_private_image = NULL;
+                return OPJ_FALSE;
+        }
+
+        *p_image = opj_image_create0();
+        if (! (*p_image)) {
+                return OPJ_FALSE;
+        }
+
+        /* Copy codestream image information to the output image */
+        opj_copy_image_header(p_j2k->m_private_image, *p_image);
+
+    /*Allocate and initialize some elements of codestrem index*/
+        if (!opj_j2k_allocate_tile_element_cstr_index(p_j2k)){
+                return OPJ_FALSE;
+        }
+
+        return OPJ_TRUE;
+}
+
+void opj_j2k_setup_header_reading (opj_j2k_t *p_j2k)
+{
+        /* preconditions*/
+        assert(p_j2k != 00);
+
+        opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_read_header_procedure);
+
+        /* DEVELOPER CORNER, add your custom procedures */
+        opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_copy_default_tcp_and_create_tcd);
+
+}
+
+void opj_j2k_setup_decoding_validation (opj_j2k_t *p_j2k)
+{
+        /* preconditions*/
+        assert(p_j2k != 00);
+
+        opj_procedure_list_add_procedure(p_j2k->m_validation_list, (opj_procedure)opj_j2k_build_decoder);
+        opj_procedure_list_add_procedure(p_j2k->m_validation_list, (opj_procedure)opj_j2k_decoding_validation);
+        /* DEVELOPER CORNER, add your custom validation procedure */
+
+}
+
+OPJ_BOOL opj_j2k_mct_validation (       opj_j2k_t * p_j2k,
+                                                                opj_stream_private_t *p_stream,
+                                                                opj_event_mgr_t * p_manager )
+{
+        OPJ_BOOL l_is_valid = OPJ_TRUE;
+        OPJ_UINT32 i,j;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_stream != 00);
+        assert(p_manager != 00);
+
+        if ((p_j2k->m_cp.rsiz & 0x8200) == 0x8200) {
+                OPJ_UINT32 l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw;
+                opj_tcp_t * l_tcp = p_j2k->m_cp.tcps;
+
+                for (i=0;i<l_nb_tiles;++i) {
+                        if (l_tcp->mct == 2) {
+                                opj_tccp_t * l_tccp = l_tcp->tccps;
+                                l_is_valid &= (l_tcp->m_mct_coding_matrix != 00);
+
+                                for (j=0;j<p_j2k->m_private_image->numcomps;++j) {
+                                        l_is_valid &= ! (l_tccp->qmfbid & 1);
+                                        ++l_tccp;
+                                }
+                        }
+                        ++l_tcp;
+                }
+        }
+
+        return l_is_valid;
+}
+
+OPJ_BOOL opj_j2k_setup_mct_encoding(opj_tcp_t * p_tcp, opj_image_t * p_image)
+{
+        OPJ_UINT32 i;
+        OPJ_UINT32 l_indix = 1;
+        opj_mct_data_t * l_mct_deco_data = 00,* l_mct_offset_data = 00;
+        opj_simple_mcc_decorrelation_data_t * l_mcc_data;
+        OPJ_UINT32 l_mct_size,l_nb_elem;
+        OPJ_FLOAT32 * l_data, * l_current_data;
+        opj_tccp_t * l_tccp;
+
+        /* preconditions */
+        assert(p_tcp != 00);
+
+        if (p_tcp->mct != 2) {
+                return OPJ_TRUE;
+        }
+
+        if (p_tcp->m_mct_decoding_matrix) {
+                if (p_tcp->m_nb_mct_records == p_tcp->m_nb_max_mct_records) {
+                        opj_mct_data_t *new_mct_records;
+                        p_tcp->m_nb_max_mct_records += OPJ_J2K_MCT_DEFAULT_NB_RECORDS;
+
+                        new_mct_records = (opj_mct_data_t *) opj_realloc(p_tcp->m_mct_records, p_tcp->m_nb_max_mct_records * sizeof(opj_mct_data_t));
+                        if (! new_mct_records) {
+                                opj_free(p_tcp->m_mct_records);
+                                p_tcp->m_mct_records = NULL;
+                                p_tcp->m_nb_max_mct_records = 0;
+                                p_tcp->m_nb_mct_records = 0;
+                                /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to setup mct encoding\n"); */
+                                return OPJ_FALSE;
+                        }
+                        p_tcp->m_mct_records = new_mct_records;
+                        l_mct_deco_data = p_tcp->m_mct_records + p_tcp->m_nb_mct_records;
+
+                        memset(l_mct_deco_data ,0,(p_tcp->m_nb_max_mct_records - p_tcp->m_nb_mct_records) * sizeof(opj_mct_data_t));
+                }
+                l_mct_deco_data = p_tcp->m_mct_records + p_tcp->m_nb_mct_records;
+
+                if (l_mct_deco_data->m_data) {
+                        opj_free(l_mct_deco_data->m_data);
+                        l_mct_deco_data->m_data = 00;
+                }
+
+                l_mct_deco_data->m_index = l_indix++;
+                l_mct_deco_data->m_array_type = MCT_TYPE_DECORRELATION;
+                l_mct_deco_data->m_element_type = MCT_TYPE_FLOAT;
+                l_nb_elem = p_image->numcomps * p_image->numcomps;
+                l_mct_size = l_nb_elem * MCT_ELEMENT_SIZE[l_mct_deco_data->m_element_type];
+                l_mct_deco_data->m_data = (OPJ_BYTE*)opj_malloc(l_mct_size );
+
+                if (! l_mct_deco_data->m_data) {
+                        return OPJ_FALSE;
+                }
+
+                j2k_mct_write_functions_from_float[l_mct_deco_data->m_element_type](p_tcp->m_mct_decoding_matrix,l_mct_deco_data->m_data,l_nb_elem);
+
+                l_mct_deco_data->m_data_size = l_mct_size;
+                ++p_tcp->m_nb_mct_records;
+        }
+
+        if (p_tcp->m_nb_mct_records == p_tcp->m_nb_max_mct_records) {
+                opj_mct_data_t *new_mct_records;
+                p_tcp->m_nb_max_mct_records += OPJ_J2K_MCT_DEFAULT_NB_RECORDS;
+                new_mct_records = (opj_mct_data_t *) opj_realloc(p_tcp->m_mct_records, p_tcp->m_nb_max_mct_records * sizeof(opj_mct_data_t));
+                if (! new_mct_records) {
+                        opj_free(p_tcp->m_mct_records);
+                        p_tcp->m_mct_records = NULL;
+                        p_tcp->m_nb_max_mct_records = 0;
+                        p_tcp->m_nb_mct_records = 0;
+                        /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to setup mct encoding\n"); */
+                        return OPJ_FALSE;
+                }
+                p_tcp->m_mct_records = new_mct_records;
+                l_mct_offset_data = p_tcp->m_mct_records + p_tcp->m_nb_mct_records;
+
+                memset(l_mct_offset_data ,0,(p_tcp->m_nb_max_mct_records - p_tcp->m_nb_mct_records) * sizeof(opj_mct_data_t));
+
+                if (l_mct_deco_data) {
+                        l_mct_deco_data = l_mct_offset_data - 1;
+                }
+        }
+
+        l_mct_offset_data = p_tcp->m_mct_records + p_tcp->m_nb_mct_records;
+
+        if (l_mct_offset_data->m_data) {
+                opj_free(l_mct_offset_data->m_data);
+                l_mct_offset_data->m_data = 00;
+        }
+
+        l_mct_offset_data->m_index = l_indix++;
+        l_mct_offset_data->m_array_type = MCT_TYPE_OFFSET;
+        l_mct_offset_data->m_element_type = MCT_TYPE_FLOAT;
+        l_nb_elem = p_image->numcomps;
+        l_mct_size = l_nb_elem * MCT_ELEMENT_SIZE[l_mct_offset_data->m_element_type];
+        l_mct_offset_data->m_data = (OPJ_BYTE*)opj_malloc(l_mct_size );
+
+        if (! l_mct_offset_data->m_data) {
+                return OPJ_FALSE;
+        }
+
+        l_data = (OPJ_FLOAT32*)opj_malloc(l_nb_elem * sizeof(OPJ_FLOAT32));
+        if (! l_data) {
+                opj_free(l_mct_offset_data->m_data);
+                l_mct_offset_data->m_data = 00;
+                return OPJ_FALSE;
+        }
+
+        l_tccp = p_tcp->tccps;
+        l_current_data = l_data;
+
+        for (i=0;i<l_nb_elem;++i) {
+                *(l_current_data++) = (OPJ_FLOAT32) (l_tccp->m_dc_level_shift);
+                ++l_tccp;
+        }
+
+        j2k_mct_write_functions_from_float[l_mct_offset_data->m_element_type](l_data,l_mct_offset_data->m_data,l_nb_elem);
+
+        opj_free(l_data);
+
+        l_mct_offset_data->m_data_size = l_mct_size;
+
+        ++p_tcp->m_nb_mct_records;
+
+        if (p_tcp->m_nb_mcc_records == p_tcp->m_nb_max_mcc_records) {
+                opj_simple_mcc_decorrelation_data_t *new_mcc_records;
+                p_tcp->m_nb_max_mcc_records += OPJ_J2K_MCT_DEFAULT_NB_RECORDS;
+                new_mcc_records = (opj_simple_mcc_decorrelation_data_t *) opj_realloc(
+                                p_tcp->m_mcc_records, p_tcp->m_nb_max_mcc_records * sizeof(opj_simple_mcc_decorrelation_data_t));
+                if (! new_mcc_records) {
+                        opj_free(p_tcp->m_mcc_records);
+                        p_tcp->m_mcc_records = NULL;
+                        p_tcp->m_nb_max_mcc_records = 0;
+                        p_tcp->m_nb_mcc_records = 0;
+                        /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to setup mct encoding\n"); */
+                        return OPJ_FALSE;
+                }
+                p_tcp->m_mcc_records = new_mcc_records;
+                l_mcc_data = p_tcp->m_mcc_records + p_tcp->m_nb_mcc_records;
+                memset(l_mcc_data ,0,(p_tcp->m_nb_max_mcc_records - p_tcp->m_nb_mcc_records) * sizeof(opj_simple_mcc_decorrelation_data_t));
+
+        }
+
+        l_mcc_data = p_tcp->m_mcc_records + p_tcp->m_nb_mcc_records;
+        l_mcc_data->m_decorrelation_array = l_mct_deco_data;
+        l_mcc_data->m_is_irreversible = 1;
+        l_mcc_data->m_nb_comps = p_image->numcomps;
+        l_mcc_data->m_index = l_indix++;
+        l_mcc_data->m_offset_array = l_mct_offset_data;
+        ++p_tcp->m_nb_mcc_records;
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_build_decoder (opj_j2k_t * p_j2k,
+                                                            opj_stream_private_t *p_stream,
+                                                            opj_event_mgr_t * p_manager )
+{
+        /* add here initialization of cp
+           copy paste of setup_decoder */
+  (void)p_j2k;
+  (void)p_stream;
+  (void)p_manager;
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_build_encoder (opj_j2k_t * p_j2k,
+                                                        opj_stream_private_t *p_stream,
+                                                        opj_event_mgr_t * p_manager )
+{
+        /* add here initialization of cp
+           copy paste of setup_encoder */
+  (void)p_j2k;
+  (void)p_stream;
+  (void)p_manager;
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_encoding_validation (  opj_j2k_t * p_j2k,
+                                                                            opj_stream_private_t *p_stream,
+                                                                            opj_event_mgr_t * p_manager )
+{
+        OPJ_BOOL l_is_valid = OPJ_TRUE;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_stream != 00);
+        assert(p_manager != 00);
+
+        /* STATE checking */
+        /* make sure the state is at 0 */
+        l_is_valid &= (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_NONE);
+
+        /* POINTER validation */
+        /* make sure a p_j2k codec is present */
+        l_is_valid &= (p_j2k->m_procedure_list != 00);
+        /* make sure a validation list is present */
+        l_is_valid &= (p_j2k->m_validation_list != 00);
+
+        if ((p_j2k->m_cp.tdx) < (OPJ_UINT32) (1 << p_j2k->m_cp.tcps->tccps->numresolutions)) {
+                opj_event_msg(p_manager, EVT_ERROR, "Number of resolutions is too high in comparison to the size of tiles\n");
+                return OPJ_FALSE;
+        }
+
+        if ((p_j2k->m_cp.tdy) < (OPJ_UINT32) (1 << p_j2k->m_cp.tcps->tccps->numresolutions)) {
+                opj_event_msg(p_manager, EVT_ERROR, "Number of resolutions is too high in comparison to the size of tiles\n");
+                return OPJ_FALSE;
+        }
+
+        /* PARAMETER VALIDATION */
+        return l_is_valid;
+}
+
+OPJ_BOOL opj_j2k_decoding_validation (  opj_j2k_t *p_j2k,
+                                        opj_stream_private_t *p_stream,
+                                        opj_event_mgr_t * p_manager
+                                        )
+{
+        OPJ_BOOL l_is_valid = OPJ_TRUE;
+
+        /* preconditions*/
+        assert(p_j2k != 00);
+        assert(p_stream != 00);
+        assert(p_manager != 00);
+
+        /* STATE checking */
+        /* make sure the state is at 0 */
+#ifdef TODO_MSD
+        l_is_valid &= (p_j2k->m_specific_param.m_decoder.m_state == J2K_DEC_STATE_NONE);
+#endif
+        l_is_valid &= (p_j2k->m_specific_param.m_decoder.m_state == 0x0000);
+
+        /* POINTER validation */
+        /* make sure a p_j2k codec is present */
+        /* make sure a procedure list is present */
+        l_is_valid &= (p_j2k->m_procedure_list != 00);
+        /* make sure a validation list is present */
+        l_is_valid &= (p_j2k->m_validation_list != 00);
+
+        /* PARAMETER VALIDATION */
+        return l_is_valid;
+}
+
+OPJ_BOOL opj_j2k_read_header_procedure( opj_j2k_t *p_j2k,
+                                                                            opj_stream_private_t *p_stream,
+                                                                            opj_event_mgr_t * p_manager)
+{
+        OPJ_UINT32 l_current_marker;
+        OPJ_UINT32 l_marker_size;
+        const opj_dec_memory_marker_handler_t * l_marker_handler = 00;
+
+        /* preconditions */
+        assert(p_stream != 00);
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+
+        /*  We enter in the main header */
+        p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_MHSOC;
+
+        /* Try to read the SOC marker, the codestream must begin with SOC marker */
+        if (! opj_j2k_read_soc(p_j2k,p_stream,p_manager)) {
+                opj_event_msg(p_manager, EVT_ERROR, "Expected a SOC marker \n");
+                return OPJ_FALSE;
+        }
+
+        /* Try to read 2 bytes (the next marker ID) from stream and copy them into the buffer */
+        if (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2) {
+                opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n");
+                return OPJ_FALSE;
+        }
+
+        /* Read 2 bytes as the new marker ID */
+        opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data,&l_current_marker,2);
+
+        /* Try to read until the SOT is detected */
+        while (l_current_marker != J2K_MS_SOT) {
+
+                /* Check if the current marker ID is valid */
+                if (l_current_marker < 0xff00) {
+                        opj_event_msg(p_manager, EVT_ERROR, "We expected read a marker ID (0xff--) instead of %.8x\n", l_current_marker);
+                        return OPJ_FALSE;
+                }
+
+                /* Get the marker handler from the marker ID */
+                l_marker_handler = opj_j2k_get_marker_handler(l_current_marker);
+
+                /* Manage case where marker is unknown */
+                if (l_marker_handler->id == J2K_MS_UNK) {
+                        if (! opj_j2k_read_unk(p_j2k, p_stream, &l_current_marker, p_manager)){
+                                opj_event_msg(p_manager, EVT_ERROR, "Unknow marker have been detected and generated error.\n");
+                                return OPJ_FALSE;
+                        }
+
+                        if (l_current_marker == J2K_MS_SOT)
+                                break; /* SOT marker is detected main header is completely read */
+                        else    /* Get the marker handler from the marker ID */
+                                l_marker_handler = opj_j2k_get_marker_handler(l_current_marker);
+                }
+
+                /* Check if the marker is known and if it is the right place to find it */
+                if (! (p_j2k->m_specific_param.m_decoder.m_state & l_marker_handler->states) ) {
+                        opj_event_msg(p_manager, EVT_ERROR, "Marker is not compliant with its position\n");
+                        return OPJ_FALSE;
+                }
+
+                /* Try to read 2 bytes (the marker size) from stream and copy them into the buffer */
+                if (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2) {
+                        opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n");
+                        return OPJ_FALSE;
+                }
+
+                /* read 2 bytes as the marker size */
+                opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data,&l_marker_size,2);
+                l_marker_size -= 2; /* Subtract the size of the marker ID already read */
+
+                /* Check if the marker size is compatible with the header data size */
+                if (l_marker_size > p_j2k->m_specific_param.m_decoder.m_header_data_size) {
+                        OPJ_BYTE *new_header_data = (OPJ_BYTE *) opj_realloc(p_j2k->m_specific_param.m_decoder.m_header_data, l_marker_size);
+                        if (! new_header_data) {
+                                opj_free(p_j2k->m_specific_param.m_decoder.m_header_data);
+                                p_j2k->m_specific_param.m_decoder.m_header_data = NULL;
+                                p_j2k->m_specific_param.m_decoder.m_header_data_size = 0;
+                                opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read header\n");
+                                return OPJ_FALSE;
+                        }
+                        p_j2k->m_specific_param.m_decoder.m_header_data = new_header_data;
+                        p_j2k->m_specific_param.m_decoder.m_header_data_size = l_marker_size;
+                }
+
+                /* Try to read the rest of the marker segment from stream and copy them into the buffer */
+                if (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,l_marker_size,p_manager) != l_marker_size) {
+                        opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n");
+                        return OPJ_FALSE;
+                }
+
+                /* Read the marker segment with the correct marker handler */
+                if (! (*(l_marker_handler->handler))(p_j2k,p_j2k->m_specific_param.m_decoder.m_header_data,l_marker_size,p_manager)) {
+                        opj_event_msg(p_manager, EVT_ERROR, "Marker handler function failed to read the marker segment\n");
+                        return OPJ_FALSE;
+                }
+
+                /* Add the marker to the codestream index*/
+                if (OPJ_FALSE == opj_j2k_add_mhmarker(
+                                        p_j2k->cstr_index,
+                                        l_marker_handler->id,
+                                        (OPJ_UINT32) opj_stream_tell(p_stream) - l_marker_size - 4,
+                                        l_marker_size + 4 )) {
+                        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to add mh marker\n");
+                        return OPJ_FALSE;
+                }
+
+                /* Try to read 2 bytes (the next marker ID) from stream and copy them into the buffer */
+                if (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2) {
+                        opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n");
+                        return OPJ_FALSE;
+                }
+
+                /* read 2 bytes as the new marker ID */
+                opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data,&l_current_marker,2);
+        }
+
+        opj_event_msg(p_manager, EVT_INFO, "Main header has been correctly decoded.\n");
+
+        /* Position of the last element if the main header */
+        p_j2k->cstr_index->main_head_end = (OPJ_UINT32) opj_stream_tell(p_stream) - 2;
+
+        /* Next step: read a tile-part header */
+        p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_TPHSOT;
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_exec ( opj_j2k_t * p_j2k,
+                                        opj_procedure_list_t * p_procedure_list,
+                                        opj_stream_private_t *p_stream,
+                                        opj_event_mgr_t * p_manager )
+{
+        OPJ_BOOL (** l_procedure) (opj_j2k_t * ,opj_stream_private_t *,opj_event_mgr_t *) = 00;
+        OPJ_BOOL l_result = OPJ_TRUE;
+        OPJ_UINT32 l_nb_proc, i;
+
+        /* preconditions*/
+        assert(p_procedure_list != 00);
+        assert(p_j2k != 00);
+        assert(p_stream != 00);
+        assert(p_manager != 00);
+
+        l_nb_proc = opj_procedure_list_get_nb_procedures(p_procedure_list);
+        l_procedure = (OPJ_BOOL (**) (opj_j2k_t * ,opj_stream_private_t *,opj_event_mgr_t *)) opj_procedure_list_get_first_procedure(p_procedure_list);
+
+        for     (i=0;i<l_nb_proc;++i) {
+                l_result = l_result && ((*l_procedure) (p_j2k,p_stream,p_manager));
+                ++l_procedure;
+        }
+
+        /* and clear the procedure list at the end.*/
+        opj_procedure_list_clear(p_procedure_list);
+        return l_result;
+}
+
+/* FIXME DOC*/
+static OPJ_BOOL opj_j2k_copy_default_tcp_and_create_tcd (       opj_j2k_t * p_j2k,
+                                                            opj_stream_private_t *p_stream,
+                                                            opj_event_mgr_t * p_manager
+                                                            )
+{
+        opj_tcp_t * l_tcp = 00;
+        opj_tcp_t * l_default_tcp = 00;
+        OPJ_UINT32 l_nb_tiles;
+        OPJ_UINT32 i,j;
+        opj_tccp_t *l_current_tccp = 00;
+        OPJ_UINT32 l_tccp_size;
+        OPJ_UINT32 l_mct_size;
+        opj_image_t * l_image;
+        OPJ_UINT32 l_mcc_records_size,l_mct_records_size;
+        opj_mct_data_t * l_src_mct_rec, *l_dest_mct_rec;
+        opj_simple_mcc_decorrelation_data_t * l_src_mcc_rec, *l_dest_mcc_rec;
+        OPJ_UINT32 l_offset;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_stream != 00);
+        assert(p_manager != 00);
+
+        l_image = p_j2k->m_private_image;
+        l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw;
+        l_tcp = p_j2k->m_cp.tcps;
+        l_tccp_size = l_image->numcomps * (OPJ_UINT32)sizeof(opj_tccp_t);
+        l_default_tcp = p_j2k->m_specific_param.m_decoder.m_default_tcp;
+        l_mct_size = l_image->numcomps * l_image->numcomps * (OPJ_UINT32)sizeof(OPJ_FLOAT32);
+
+        /* For each tile */
+        for (i=0; i<l_nb_tiles; ++i) {
+                /* keep the tile-compo coding parameters pointer of the current tile coding parameters*/
+                l_current_tccp = l_tcp->tccps;
+                /*Copy default coding parameters into the current tile coding parameters*/
+                memcpy(l_tcp, l_default_tcp, sizeof(opj_tcp_t));
+                /* Initialize some values of the current tile coding parameters*/
+                l_tcp->ppt = 0;
+                l_tcp->ppt_data = 00;
+                /* Reconnect the tile-compo coding parameters pointer to the current tile coding parameters*/
+                l_tcp->tccps = l_current_tccp;
+
+                /* Get the mct_decoding_matrix of the dflt_tile_cp and copy them into the current tile cp*/
+                if (l_default_tcp->m_mct_decoding_matrix) {
+                        l_tcp->m_mct_decoding_matrix = (OPJ_FLOAT32*)opj_malloc(l_mct_size);
+                        if (! l_tcp->m_mct_decoding_matrix ) {
+                                return OPJ_FALSE;
+                        }
+                        memcpy(l_tcp->m_mct_decoding_matrix,l_default_tcp->m_mct_decoding_matrix,l_mct_size);
+                }
+
+                /* Get the mct_record of the dflt_tile_cp and copy them into the current tile cp*/
+                l_mct_records_size = l_default_tcp->m_nb_max_mct_records * (OPJ_UINT32)sizeof(opj_mct_data_t);
+                l_tcp->m_mct_records = (opj_mct_data_t*)opj_malloc(l_mct_records_size);
+                if (! l_tcp->m_mct_records) {
+                        return OPJ_FALSE;
+                }
+                memcpy(l_tcp->m_mct_records, l_default_tcp->m_mct_records,l_mct_records_size);
+
+                /* Copy the mct record data from dflt_tile_cp to the current tile*/
+                l_src_mct_rec = l_default_tcp->m_mct_records;
+                l_dest_mct_rec = l_tcp->m_mct_records;
+
+                for (j=0;j<l_default_tcp->m_nb_mct_records;++j) {
+
+                        if (l_src_mct_rec->m_data) {
+
+                                l_dest_mct_rec->m_data = (OPJ_BYTE*) opj_malloc(l_src_mct_rec->m_data_size);
+                                if(! l_dest_mct_rec->m_data) {
+                                        return OPJ_FALSE;
+                                }
+                                memcpy(l_dest_mct_rec->m_data,l_src_mct_rec->m_data,l_src_mct_rec->m_data_size);
+                        }
+
+                        ++l_src_mct_rec;
+                        ++l_dest_mct_rec;
+                }
+
+                /* Get the mcc_record of the dflt_tile_cp and copy them into the current tile cp*/
+                l_mcc_records_size = l_default_tcp->m_nb_max_mcc_records * (OPJ_UINT32)sizeof(opj_simple_mcc_decorrelation_data_t);
+                l_tcp->m_mcc_records = (opj_simple_mcc_decorrelation_data_t*) opj_malloc(l_mcc_records_size);
+                if (! l_tcp->m_mcc_records) {
+                        return OPJ_FALSE;
+                }
+                memcpy(l_tcp->m_mcc_records,l_default_tcp->m_mcc_records,l_mcc_records_size);
+
+                /* Copy the mcc record data from dflt_tile_cp to the current tile*/
+                l_src_mcc_rec = l_default_tcp->m_mcc_records;
+                l_dest_mcc_rec = l_tcp->m_mcc_records;
+
+                for (j=0;j<l_default_tcp->m_nb_max_mcc_records;++j) {
+
+                        if (l_src_mcc_rec->m_decorrelation_array) {
+                                l_offset = (OPJ_UINT32)(l_src_mcc_rec->m_decorrelation_array - l_default_tcp->m_mct_records);
+                                l_dest_mcc_rec->m_decorrelation_array = l_tcp->m_mct_records + l_offset;
+                        }
+
+                        if (l_src_mcc_rec->m_offset_array) {
+                                l_offset = (OPJ_UINT32)(l_src_mcc_rec->m_offset_array - l_default_tcp->m_mct_records);
+                                l_dest_mcc_rec->m_offset_array = l_tcp->m_mct_records + l_offset;
+                        }
+
+                        ++l_src_mcc_rec;
+                        ++l_dest_mcc_rec;
+                }
+
+                /* Copy all the dflt_tile_compo_cp to the current tile cp */
+                memcpy(l_current_tccp,l_default_tcp->tccps,l_tccp_size);
+
+                /* Move to next tile cp*/
+                ++l_tcp;
+        }
+
+        /* Create the current tile decoder*/
+        p_j2k->m_tcd = (opj_tcd_t*)opj_tcd_create(OPJ_TRUE); /* FIXME why a cast ? */
+        if (! p_j2k->m_tcd ) {
+                return OPJ_FALSE;
+        }
+
+        if ( !opj_tcd_init(p_j2k->m_tcd, l_image, &(p_j2k->m_cp)) ) {
+                opj_tcd_destroy(p_j2k->m_tcd);
+                p_j2k->m_tcd = 00;
+                opj_event_msg(p_manager, EVT_ERROR, "Cannot decode tile, memory error\n");
+                return OPJ_FALSE;
+        }
+
+        return OPJ_TRUE;
+}
+
+const opj_dec_memory_marker_handler_t * opj_j2k_get_marker_handler (OPJ_UINT32 p_id)
+{
+        const opj_dec_memory_marker_handler_t *e;
+        for (e = j2k_memory_marker_handler_tab; e->id != 0; ++e) {
+                if (e->id == p_id) {
+                        break; /* we find a handler corresponding to the marker ID*/
+                }
+        }
+        return e;
+}
+
+void opj_j2k_destroy (opj_j2k_t *p_j2k)
+{
+        if (p_j2k == 00) {
+                return;
+        }
+
+        if (p_j2k->m_is_decoder) {
+
+                if (p_j2k->m_specific_param.m_decoder.m_default_tcp != 00) {
+                        opj_j2k_tcp_destroy(p_j2k->m_specific_param.m_decoder.m_default_tcp);
+                        opj_free(p_j2k->m_specific_param.m_decoder.m_default_tcp);
+                        p_j2k->m_specific_param.m_decoder.m_default_tcp = 00;
+                }
+
+                if (p_j2k->m_specific_param.m_decoder.m_header_data != 00) {
+                        opj_free(p_j2k->m_specific_param.m_decoder.m_header_data);
+                        p_j2k->m_specific_param.m_decoder.m_header_data = 00;
+                        p_j2k->m_specific_param.m_decoder.m_header_data_size = 0;
+                }
+        }
+        else {
+
+                if (p_j2k->m_specific_param.m_encoder.m_encoded_tile_data) {
+                        opj_free(p_j2k->m_specific_param.m_encoder.m_encoded_tile_data);
+                        p_j2k->m_specific_param.m_encoder.m_encoded_tile_data = 00;
+                }
+
+                if (p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer) {
+                        opj_free(p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer);
+                        p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer = 00;
+                        p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current = 00;
+                }
+
+                if (p_j2k->m_specific_param.m_encoder.m_header_tile_data) {
+                        opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data);
+                        p_j2k->m_specific_param.m_encoder.m_header_tile_data = 00;
+                        p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0;
+                }
+        }
+
+        opj_tcd_destroy(p_j2k->m_tcd);
+
+        opj_j2k_cp_destroy(&(p_j2k->m_cp));
+        memset(&(p_j2k->m_cp),0,sizeof(opj_cp_t));
+
+        opj_procedure_list_destroy(p_j2k->m_procedure_list);
+        p_j2k->m_procedure_list = 00;
+
+        opj_procedure_list_destroy(p_j2k->m_validation_list);
+        p_j2k->m_procedure_list = 00;
+
+        j2k_destroy_cstr_index(p_j2k->cstr_index);
+        p_j2k->cstr_index = NULL;
+
+        opj_image_destroy(p_j2k->m_private_image);
+        p_j2k->m_private_image = NULL;
+
+        opj_image_destroy(p_j2k->m_output_image);
+        p_j2k->m_output_image = NULL;
+
+        opj_free(p_j2k);
+}
+
+void j2k_destroy_cstr_index (opj_codestream_index_t *p_cstr_ind)
+{
+        if (p_cstr_ind) {
+
+                if (p_cstr_ind->marker) {
+                        opj_free(p_cstr_ind->marker);
+                        p_cstr_ind->marker = NULL;
+                }
+
+                if (p_cstr_ind->tile_index) {
+                        OPJ_UINT32 it_tile = 0;
+
+                        for (it_tile=0; it_tile < p_cstr_ind->nb_of_tiles; it_tile++) {
+
+                                if(p_cstr_ind->tile_index[it_tile].packet_index) {
+                                        opj_free(p_cstr_ind->tile_index[it_tile].packet_index);
+                                        p_cstr_ind->tile_index[it_tile].packet_index = NULL;
+                                }
+
+                                if(p_cstr_ind->tile_index[it_tile].tp_index){
+                                        opj_free(p_cstr_ind->tile_index[it_tile].tp_index);
+                                        p_cstr_ind->tile_index[it_tile].tp_index = NULL;
+                                }
+
+                                if(p_cstr_ind->tile_index[it_tile].marker){
+                                        opj_free(p_cstr_ind->tile_index[it_tile].marker);
+                                        p_cstr_ind->tile_index[it_tile].marker = NULL;
+
+                                }
+                        }
+
+                        opj_free( p_cstr_ind->tile_index);
+                        p_cstr_ind->tile_index = NULL;
+                }
+
+                opj_free(p_cstr_ind);
+        }
+}
+
+void opj_j2k_tcp_destroy (opj_tcp_t *p_tcp)
+{
+        if (p_tcp == 00) {
+                return;
+        }
+
+        if (p_tcp->ppt_buffer != 00) {
+                opj_free(p_tcp->ppt_buffer);
+                p_tcp->ppt_buffer = 00;
+        }
+
+        if (p_tcp->tccps != 00) {
+                opj_free(p_tcp->tccps);
+                p_tcp->tccps = 00;
+        }
+
+        if (p_tcp->m_mct_coding_matrix != 00) {
+                opj_free(p_tcp->m_mct_coding_matrix);
+                p_tcp->m_mct_coding_matrix = 00;
+        }
+
+        if (p_tcp->m_mct_decoding_matrix != 00) {
+                opj_free(p_tcp->m_mct_decoding_matrix);
+                p_tcp->m_mct_decoding_matrix = 00;
+        }
+
+        if (p_tcp->m_mcc_records) {
+                opj_free(p_tcp->m_mcc_records);
+                p_tcp->m_mcc_records = 00;
+                p_tcp->m_nb_max_mcc_records = 0;
+                p_tcp->m_nb_mcc_records = 0;
+        }
+
+        if (p_tcp->m_mct_records) {
+                opj_mct_data_t * l_mct_data = p_tcp->m_mct_records;
+                OPJ_UINT32 i;
+
+                for (i=0;i<p_tcp->m_nb_mct_records;++i) {
+                        if (l_mct_data->m_data) {
+                                opj_free(l_mct_data->m_data);
+                                l_mct_data->m_data = 00;
+                        }
+
+                        ++l_mct_data;
+                }
+
+                opj_free(p_tcp->m_mct_records);
+                p_tcp->m_mct_records = 00;
+        }
+
+        if (p_tcp->mct_norms != 00) {
+                opj_free(p_tcp->mct_norms);
+                p_tcp->mct_norms = 00;
+        }
+
+        opj_j2k_tcp_data_destroy(p_tcp);
+
+}
+
+void opj_j2k_tcp_data_destroy (opj_tcp_t *p_tcp)
+{
+        if (p_tcp->m_data) {
+                opj_free(p_tcp->m_data);
+                p_tcp->m_data = NULL;
+                p_tcp->m_data_size = 0;
+        }
+}
+
+void opj_j2k_cp_destroy (opj_cp_t *p_cp)
+{
+        OPJ_UINT32 l_nb_tiles;
+        opj_tcp_t * l_current_tile = 00;
+        OPJ_UINT32 i;
+
+        if (p_cp == 00)
+        {
+                return;
+        }
+        if (p_cp->tcps != 00)
+        {
+                l_current_tile = p_cp->tcps;
+                l_nb_tiles = p_cp->th * p_cp->tw;
+
+                for (i = 0; i < l_nb_tiles; ++i)
+                {
+                        opj_j2k_tcp_destroy(l_current_tile);
+                        ++l_current_tile;
+                }
+                opj_free(p_cp->tcps);
+                p_cp->tcps = 00;
+        }
+        opj_free(p_cp->ppm_buffer);
+        p_cp->ppm_buffer = 00;
+        p_cp->ppm_data = NULL; /* ppm_data belongs to the allocated buffer pointed by ppm_buffer */
+        opj_free(p_cp->comment);
+        p_cp->comment = 00;
+        if (! p_cp->m_is_decoder)
+        {
+                opj_free(p_cp->m_specific_param.m_enc.m_matrice);
+                p_cp->m_specific_param.m_enc.m_matrice = 00;
+        }
+}
+
+OPJ_BOOL opj_j2k_read_tile_header(      opj_j2k_t * p_j2k,
+                                                                    OPJ_UINT32 * p_tile_index,
+                                                                    OPJ_UINT32 * p_data_size,
+                                                                    OPJ_INT32 * p_tile_x0, OPJ_INT32 * p_tile_y0,
+                                                                    OPJ_INT32 * p_tile_x1, OPJ_INT32 * p_tile_y1,
+                                                                    OPJ_UINT32 * p_nb_comps,
+                                                                    OPJ_BOOL * p_go_on,
+                                                                    opj_stream_private_t *p_stream,
+                                                                    opj_event_mgr_t * p_manager )
+{
+        OPJ_UINT32 l_current_marker = J2K_MS_SOT;
+        OPJ_UINT32 l_marker_size;
+        const opj_dec_memory_marker_handler_t * l_marker_handler = 00;
+        opj_tcp_t * l_tcp = NULL;
+        OPJ_UINT32 l_nb_tiles;
+
+        /* preconditions */
+        assert(p_stream != 00);
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+
+        /* Reach the End Of Codestream ?*/
+        if (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_EOC){
+                l_current_marker = J2K_MS_EOC;
+        }
+        /* We need to encounter a SOT marker (a new tile-part header) */
+        else if (p_j2k->m_specific_param.m_decoder.m_state != J2K_STATE_TPHSOT){
+                return OPJ_FALSE;
+        }
+
+        /* Read into the codestream until reach the EOC or ! can_decode ??? FIXME */
+        while ( (!p_j2k->m_specific_param.m_decoder.m_can_decode) && (l_current_marker != J2K_MS_EOC) ) {
+
+                /* Try to read until the Start Of Data is detected */
+                while (l_current_marker != J2K_MS_SOD) {
+                    
+                    if(opj_stream_get_number_byte_left(p_stream) == 0)
+                    {
+                        p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_NEOC;
+                        break;
+                    }
+
+                        /* Try to read 2 bytes (the marker size) from stream and copy them into the buffer */
+                        if (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2) {
+                                opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n");
+                                return OPJ_FALSE;
+                        }
+
+                        /* Read 2 bytes from the buffer as the marker size */
+                        opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data,&l_marker_size,2);
+
+                        /* cf. https://code.google.com/p/openjpeg/issues/detail?id=226 */
+                        if (l_current_marker == 0x8080 && opj_stream_get_number_byte_left(p_stream) == 0) {
+                                p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_NEOC;
+                                break;
+                        }
+
+                        /* Why this condition? FIXME */
+                        if (p_j2k->m_specific_param.m_decoder.m_state & J2K_STATE_TPH){
+                                p_j2k->m_specific_param.m_decoder.m_sot_length -= (l_marker_size + 2);
+                        }
+                        l_marker_size -= 2; /* Subtract the size of the marker ID already read */
+
+                        /* Get the marker handler from the marker ID */
+                        l_marker_handler = opj_j2k_get_marker_handler(l_current_marker);
+
+                        /* Check if the marker is known and if it is the right place to find it */
+                        if (! (p_j2k->m_specific_param.m_decoder.m_state & l_marker_handler->states) ) {
+                                opj_event_msg(p_manager, EVT_ERROR, "Marker is not compliant with its position\n");
+                                return OPJ_FALSE;
+                        }
+/* FIXME manage case of unknown marker as in the main header ? */
+
+                        /* Check if the marker size is compatible with the header data size */
+                        if (l_marker_size > p_j2k->m_specific_param.m_decoder.m_header_data_size) {
+                                OPJ_BYTE *new_header_data = (OPJ_BYTE *) opj_realloc(p_j2k->m_specific_param.m_decoder.m_header_data, l_marker_size);
+                                if (! new_header_data) {
+                                        opj_free(p_j2k->m_specific_param.m_decoder.m_header_data);
+                                        p_j2k->m_specific_param.m_decoder.m_header_data = NULL;
+                                        p_j2k->m_specific_param.m_decoder.m_header_data_size = 0;
+                                        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read header\n");
+                                        return OPJ_FALSE;
+                                }
+                                p_j2k->m_specific_param.m_decoder.m_header_data = new_header_data;
+                                p_j2k->m_specific_param.m_decoder.m_header_data_size = l_marker_size;
+                        }
+
+                        /* Try to read the rest of the marker segment from stream and copy them into the buffer */
+                        if (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,l_marker_size,p_manager) != l_marker_size) {
+                                opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n");
+                                return OPJ_FALSE;
+                        }
+
+                        if (!l_marker_handler->handler) {
+                                /* See issue #175 */
+                                opj_event_msg(p_manager, EVT_ERROR, "Not sure how that happened.\n");
+                                return OPJ_FALSE;
+                        }
+                        /* Read the marker segment with the correct marker handler */
+                        if (! (*(l_marker_handler->handler))(p_j2k,p_j2k->m_specific_param.m_decoder.m_header_data,l_marker_size,p_manager)) {
+                                opj_event_msg(p_manager, EVT_ERROR, "Fail to read the current marker segment (%#x)\n", l_current_marker);
+                                return OPJ_FALSE;
+                        }
+
+                        /* Add the marker to the codestream index*/
+                        if (OPJ_FALSE == opj_j2k_add_tlmarker(p_j2k->m_current_tile_number,
+                                                p_j2k->cstr_index,
+                                                l_marker_handler->id,
+                                                (OPJ_UINT32) opj_stream_tell(p_stream) - l_marker_size - 4,
+                                                l_marker_size + 4 )) {
+                                opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to add tl marker\n");
+                                return OPJ_FALSE;
+                        }
+
+                        /* Keep the position of the last SOT marker read */
+                        if ( l_marker_handler->id == J2K_MS_SOT ) {
+                                OPJ_UINT32 sot_pos = (OPJ_UINT32) opj_stream_tell(p_stream) - l_marker_size - 4 ;
+                                if (sot_pos > p_j2k->m_specific_param.m_decoder.m_last_sot_read_pos)
+                                {
+                                        p_j2k->m_specific_param.m_decoder.m_last_sot_read_pos = sot_pos;
+                                }
+                        }
+
+                        if (p_j2k->m_specific_param.m_decoder.m_skip_data) {
+                                /* Skip the rest of the tile part header*/
+                                if (opj_stream_skip(p_stream,p_j2k->m_specific_param.m_decoder.m_sot_length,p_manager) != p_j2k->m_specific_param.m_decoder.m_sot_length) {
+                                        opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n");
+                                        return OPJ_FALSE;
+                                }
+                                l_current_marker = J2K_MS_SOD; /* Normally we reached a SOD */
+                        }
+                        else {
+                                /* Try to read 2 bytes (the next marker ID) from stream and copy them into the buffer*/
+                                if (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2) {
+                                        opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n");
+                                        return OPJ_FALSE;
+                                }
+                                /* Read 2 bytes from the buffer as the new marker ID */
+                                opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data,&l_current_marker,2);
+                        }
+                }
+                if(opj_stream_get_number_byte_left(p_stream) == 0
+                    && p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_NEOC)
+                    break;
+
+                /* If we didn't skip data before, we need to read the SOD marker*/
+                if (! p_j2k->m_specific_param.m_decoder.m_skip_data) {
+                        /* Try to read the SOD marker and skip data ? FIXME */
+                        if (! opj_j2k_read_sod(p_j2k, p_stream, p_manager)) {
+                                return OPJ_FALSE;
+                        }
+
+                        if (! p_j2k->m_specific_param.m_decoder.m_can_decode){
+                                /* Try to read 2 bytes (the next marker ID) from stream and copy them into the buffer */
+                                if (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2) {
+                                        opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n");
+                                        return OPJ_FALSE;
+                                }
+
+                                /* Read 2 bytes from buffer as the new marker ID */
+                                opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data,&l_current_marker,2);
+                        }
+                }
+                else {
+                        /* Indicate we will try to read a new tile-part header*/
+                        p_j2k->m_specific_param.m_decoder.m_skip_data = 0;
+                        p_j2k->m_specific_param.m_decoder.m_can_decode = 0;
+                        p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_TPHSOT;
+
+                        /* Try to read 2 bytes (the next marker ID) from stream and copy them into the buffer */
+                        if (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2) {
+                                opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n");
+                                return OPJ_FALSE;
+                        }
+
+                        /* Read 2 bytes from buffer as the new marker ID */
+                        opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data,&l_current_marker,2);
+                }
+        }
+
+        /* Current marker is the EOC marker ?*/
+        if (l_current_marker == J2K_MS_EOC) {
+                if (p_j2k->m_specific_param.m_decoder.m_state != J2K_STATE_EOC ){
+                        p_j2k->m_current_tile_number = 0;
+                        p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_EOC;
+                }
+        }
+
+        /* FIXME DOC ???*/
+        if ( ! p_j2k->m_specific_param.m_decoder.m_can_decode) {
+                l_tcp = p_j2k->m_cp.tcps + p_j2k->m_current_tile_number;
+                l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw;
+
+                while( (p_j2k->m_current_tile_number < l_nb_tiles) && (l_tcp->m_data == 00) ) {
+                        ++p_j2k->m_current_tile_number;
+                        ++l_tcp;
+                }
+
+                if (p_j2k->m_current_tile_number == l_nb_tiles) {
+                        *p_go_on = OPJ_FALSE;
+                        return OPJ_TRUE;
+                }
+        }
+
+        /*FIXME ???*/
+        if (! opj_tcd_init_decode_tile(p_j2k->m_tcd, p_j2k->m_current_tile_number)) {
+                opj_event_msg(p_manager, EVT_ERROR, "Cannot decode tile, memory error\n");
+                return OPJ_FALSE;
+        }
+
+        opj_event_msg(p_manager, EVT_INFO, "Header of tile %d / %d has been read.\n",
+                        p_j2k->m_current_tile_number, (p_j2k->m_cp.th * p_j2k->m_cp.tw) - 1);
+
+        *p_tile_index = p_j2k->m_current_tile_number;
+        *p_go_on = OPJ_TRUE;
+        *p_data_size = opj_tcd_get_decoded_tile_size(p_j2k->m_tcd);
+        *p_tile_x0 = p_j2k->m_tcd->tcd_image->tiles->x0;
+        *p_tile_y0 = p_j2k->m_tcd->tcd_image->tiles->y0;
+        *p_tile_x1 = p_j2k->m_tcd->tcd_image->tiles->x1;
+        *p_tile_y1 = p_j2k->m_tcd->tcd_image->tiles->y1;
+        *p_nb_comps = p_j2k->m_tcd->tcd_image->tiles->numcomps;
+
+         p_j2k->m_specific_param.m_decoder.m_state |= 0x0080;/* FIXME J2K_DEC_STATE_DATA;*/
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_decode_tile (  opj_j2k_t * p_j2k,
+                                                        OPJ_UINT32 p_tile_index,
+                                                        OPJ_BYTE * p_data,
+                                                        OPJ_UINT32 p_data_size,
+                                                        opj_stream_private_t *p_stream,
+                                                        opj_event_mgr_t * p_manager )
+{
+        OPJ_UINT32 l_current_marker;
+        OPJ_BYTE l_data [2];
+        opj_tcp_t * l_tcp;
+
+        /* preconditions */
+        assert(p_stream != 00);
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+
+        if ( !(p_j2k->m_specific_param.m_decoder.m_state & 0x0080/*FIXME J2K_DEC_STATE_DATA*/)
+                || (p_tile_index != p_j2k->m_current_tile_number) ) {
+                return OPJ_FALSE;
+        }
+
+        l_tcp = &(p_j2k->m_cp.tcps[p_tile_index]);
+        if (! l_tcp->m_data) {
+                opj_j2k_tcp_destroy(l_tcp);
+                return OPJ_FALSE;
+        }
+
+        if (! opj_tcd_decode_tile(      p_j2k->m_tcd,
+                                                                l_tcp->m_data,
+                                                                l_tcp->m_data_size,
+                                                                p_tile_index,
+                                                                p_j2k->cstr_index) ) {
+                opj_j2k_tcp_destroy(l_tcp);
+                p_j2k->m_specific_param.m_decoder.m_state |= 0x8000;/*FIXME J2K_DEC_STATE_ERR;*/
+                opj_event_msg(p_manager, EVT_ERROR, "Failed to decode.\n");
+                return OPJ_FALSE;
+        }
+
+        if (! opj_tcd_update_tile_data(p_j2k->m_tcd,p_data,p_data_size)) {
+                return OPJ_FALSE;
+        }
+
+        /* To avoid to destroy the tcp which can be useful when we try to decode a tile decoded before (cf j2k_random_tile_access)
+         * we destroy just the data which will be re-read in read_tile_header*/
+        /*opj_j2k_tcp_destroy(l_tcp);
+        p_j2k->m_tcd->tcp = 0;*/
+        opj_j2k_tcp_data_destroy(l_tcp);
+
+        p_j2k->m_specific_param.m_decoder.m_can_decode = 0;
+        p_j2k->m_specific_param.m_decoder.m_state &= (~ (0x0080u));/* FIXME J2K_DEC_STATE_DATA);*/
+
+        if(opj_stream_get_number_byte_left(p_stream) == 0 
+            && p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_NEOC){
+            return OPJ_TRUE;
+        }
+
+        if (p_j2k->m_specific_param.m_decoder.m_state != 0x0100){ /*FIXME J2K_DEC_STATE_EOC)*/
+                if (opj_stream_read_data(p_stream,l_data,2,p_manager) != 2) {
+                        opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n");
+                        return OPJ_FALSE;
+                }
+
+                opj_read_bytes(l_data,&l_current_marker,2);
+
+                if (l_current_marker == J2K_MS_EOC) {
+                        p_j2k->m_current_tile_number = 0;
+                        p_j2k->m_specific_param.m_decoder.m_state =  0x0100;/*FIXME J2K_DEC_STATE_EOC;*/
+                }
+                else if (l_current_marker != J2K_MS_SOT)
+                {
+                        opj_event_msg(p_manager, EVT_ERROR, "Stream too short, expected SOT\n");
+                        
+                        if(opj_stream_get_number_byte_left(p_stream) == 0) {
+                            p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_NEOC;
+                            return OPJ_TRUE;
+                        }
+                        return OPJ_FALSE;
+                }
+        }
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_update_image_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data, opj_image_t* p_output_image)
+{
+        OPJ_UINT32 i,j,k = 0;
+        OPJ_UINT32 l_width_src,l_height_src;
+        OPJ_UINT32 l_width_dest,l_height_dest;
+        OPJ_INT32 l_offset_x0_src, l_offset_y0_src, l_offset_x1_src, l_offset_y1_src;
+        OPJ_INT32 l_start_offset_src, l_line_offset_src, l_end_offset_src ;
+        OPJ_UINT32 l_start_x_dest , l_start_y_dest;
+        OPJ_UINT32 l_x0_dest, l_y0_dest, l_x1_dest, l_y1_dest;
+        OPJ_INT32 l_start_offset_dest, l_line_offset_dest;
+
+        opj_image_comp_t * l_img_comp_src = 00;
+        opj_image_comp_t * l_img_comp_dest = 00;
+
+        opj_tcd_tilecomp_t * l_tilec = 00;
+        opj_image_t * l_image_src = 00;
+        OPJ_UINT32 l_size_comp, l_remaining;
+        OPJ_INT32 * l_dest_ptr;
+        opj_tcd_resolution_t* l_res= 00;
+
+        l_tilec = p_tcd->tcd_image->tiles->comps;
+        l_image_src = p_tcd->image;
+        l_img_comp_src = l_image_src->comps;
+
+        l_img_comp_dest = p_output_image->comps;
+
+        for (i=0; i<l_image_src->numcomps; i++) {
+
+                /* Allocate output component buffer if necessary */
+                if (!l_img_comp_dest->data) {
+
+                        l_img_comp_dest->data = (OPJ_INT32*) opj_calloc(l_img_comp_dest->w * l_img_comp_dest->h, sizeof(OPJ_INT32));
+                        if (! l_img_comp_dest->data) {
+                                return OPJ_FALSE;
+                        }
+                }
+
+                /* Copy info from decoded comp image to output image */
+                l_img_comp_dest->resno_decoded = l_img_comp_src->resno_decoded;
+
+                /*-----*/
+                /* Compute the precision of the output buffer */
+                l_size_comp = l_img_comp_src->prec >> 3; /*(/ 8)*/
+                l_remaining = l_img_comp_src->prec & 7;  /* (%8) */
+                l_res = l_tilec->resolutions + l_img_comp_src->resno_decoded;
+
+                if (l_remaining) {
+                        ++l_size_comp;
+                }
+
+                if (l_size_comp == 3) {
+                        l_size_comp = 4;
+                }
+                /*-----*/
+
+                /* Current tile component size*/
+                /*if (i == 0) {
+                fprintf(stdout, "SRC: l_res_x0=%d, l_res_x1=%d, l_res_y0=%d, l_res_y1=%d\n",
+                                l_res->x0, l_res->x1, l_res->y0, l_res->y1);
+                }*/
+
+                l_width_src = (OPJ_UINT32)(l_res->x1 - l_res->x0);
+                l_height_src = (OPJ_UINT32)(l_res->y1 - l_res->y0);
+
+                /* Border of the current output component*/
+                l_x0_dest = (OPJ_UINT32)opj_int_ceildivpow2((OPJ_INT32)l_img_comp_dest->x0, (OPJ_INT32)l_img_comp_dest->factor);
+                l_y0_dest = (OPJ_UINT32)opj_int_ceildivpow2((OPJ_INT32)l_img_comp_dest->y0, (OPJ_INT32)l_img_comp_dest->factor);
+                l_x1_dest = l_x0_dest + l_img_comp_dest->w;
+                l_y1_dest = l_y0_dest + l_img_comp_dest->h;
+
+                /*if (i == 0) {
+                fprintf(stdout, "DEST: l_x0_dest=%d, l_x1_dest=%d, l_y0_dest=%d, l_y1_dest=%d (%d)\n",
+                                l_x0_dest, l_x1_dest, l_y0_dest, l_y1_dest, l_img_comp_dest->factor );
+                }*/
+
+                /*-----*/
+                /* Compute the area (l_offset_x0_src, l_offset_y0_src, l_offset_x1_src, l_offset_y1_src)
+                 * of the input buffer (decoded tile component) which will be move
+                 * in the output buffer. Compute the area of the output buffer (l_start_x_dest,
+                 * l_start_y_dest, l_width_dest, l_height_dest)  which will be modified
+                 * by this input area.
+                 * */
+                assert( l_res->x0 >= 0);
+                assert( l_res->x1 >= 0);
+                if ( l_x0_dest < (OPJ_UINT32)l_res->x0 ) {
+                        l_start_x_dest = (OPJ_UINT32)l_res->x0 - l_x0_dest;
+                        l_offset_x0_src = 0;
+
+                        if ( l_x1_dest >= (OPJ_UINT32)l_res->x1 ) {
+                                l_width_dest = l_width_src;
+                                l_offset_x1_src = 0;
+                        }
+                        else {
+                                l_width_dest = l_x1_dest - (OPJ_UINT32)l_res->x0 ;
+                                l_offset_x1_src = (OPJ_INT32)(l_width_src - l_width_dest);
+                        }
+                }
+                else {
+                        l_start_x_dest = 0 ;
+                        l_offset_x0_src = (OPJ_INT32)l_x0_dest - l_res->x0;
+
+                        if ( l_x1_dest >= (OPJ_UINT32)l_res->x1 ) {
+                                l_width_dest = l_width_src - (OPJ_UINT32)l_offset_x0_src;
+                                l_offset_x1_src = 0;
+                        }
+                        else {
+                                l_width_dest = l_img_comp_dest->w ;
+                                l_offset_x1_src = l_res->x1 - (OPJ_INT32)l_x1_dest;
+                        }
+                }
+
+                if ( l_y0_dest < (OPJ_UINT32)l_res->y0 ) {
+                        l_start_y_dest = (OPJ_UINT32)l_res->y0 - l_y0_dest;
+                        l_offset_y0_src = 0;
+
+                        if ( l_y1_dest >= (OPJ_UINT32)l_res->y1 ) {
+                                l_height_dest = l_height_src;
+                                l_offset_y1_src = 0;
+                        }
+                        else {
+                                l_height_dest = l_y1_dest - (OPJ_UINT32)l_res->y0 ;
+                                l_offset_y1_src =  (OPJ_INT32)(l_height_src - l_height_dest);
+                        }
+                }
+                else {
+                        l_start_y_dest = 0 ;
+                        l_offset_y0_src = (OPJ_INT32)l_y0_dest - l_res->y0;
+
+                        if ( l_y1_dest >= (OPJ_UINT32)l_res->y1 ) {
+                                l_height_dest = l_height_src - (OPJ_UINT32)l_offset_y0_src;
+                                l_offset_y1_src = 0;
+                        }
+                        else {
+                                l_height_dest = l_img_comp_dest->h ;
+                                l_offset_y1_src = l_res->y1 - (OPJ_INT32)l_y1_dest;
+                        }
+                }
+
+                if( (l_offset_x0_src < 0 ) || (l_offset_y0_src < 0 ) || (l_offset_x1_src < 0 ) || (l_offset_y1_src < 0 ) ){
+                        return OPJ_FALSE;
+                }
+                /* testcase 2977.pdf.asan.67.2198 */
+                if ((OPJ_INT32)l_width_dest < 0 || (OPJ_INT32)l_height_dest < 0) {
+                        return OPJ_FALSE;
+                }
+                /*-----*/
+
+                /* Compute the input buffer offset */
+                l_start_offset_src = l_offset_x0_src + l_offset_y0_src * (OPJ_INT32)l_width_src;
+                l_line_offset_src = l_offset_x1_src + l_offset_x0_src;
+                l_end_offset_src = l_offset_y1_src * (OPJ_INT32)l_width_src - l_offset_x0_src;
+
+                /* Compute the output buffer offset */
+                l_start_offset_dest = (OPJ_INT32)(l_start_x_dest + l_start_y_dest * l_img_comp_dest->w);
+                l_line_offset_dest = (OPJ_INT32)(l_img_comp_dest->w - l_width_dest);
+
+                /* Move the output buffer to the first place where we will write*/
+                l_dest_ptr = l_img_comp_dest->data + l_start_offset_dest;
+
+                /*if (i == 0) {
+                        fprintf(stdout, "COMPO[%d]:\n",i);
+                        fprintf(stdout, "SRC: l_start_x_src=%d, l_start_y_src=%d, l_width_src=%d, l_height_src=%d\n"
+                                        "\t tile offset:%d, %d, %d, %d\n"
+                                        "\t buffer offset: %d; %d, %d\n",
+                                        l_res->x0, l_res->y0, l_width_src, l_height_src,
+                                        l_offset_x0_src, l_offset_y0_src, l_offset_x1_src, l_offset_y1_src,
+                                        l_start_offset_src, l_line_offset_src, l_end_offset_src);
+
+                        fprintf(stdout, "DEST: l_start_x_dest=%d, l_start_y_dest=%d, l_width_dest=%d, l_height_dest=%d\n"
+                                        "\t start offset: %d, line offset= %d\n",
+                                        l_start_x_dest, l_start_y_dest, l_width_dest, l_height_dest, l_start_offset_dest, l_line_offset_dest);
+                }*/
+
+                switch (l_size_comp) {
+                        case 1:
+                                {
+                                        OPJ_CHAR * l_src_ptr = (OPJ_CHAR*) p_data;
+                                        l_src_ptr += l_start_offset_src; /* Move to the first place where we will read*/
+
+                                        if (l_img_comp_src->sgnd) {
+                                                for (j = 0 ; j < l_height_dest ; ++j) {
+                                                        for ( k = 0 ; k < l_width_dest ; ++k) {
+                                                                *(l_dest_ptr++) = (OPJ_INT32) (*(l_src_ptr++)); /* Copy only the data needed for the output image */
+                                                        }
+
+                                                        l_dest_ptr+= l_line_offset_dest; /* Move to the next place where we will write */
+                                                        l_src_ptr += l_line_offset_src ; /* Move to the next place where we will read */
+                                                }
+                                        }
+                                        else {
+                                                for ( j = 0 ; j < l_height_dest ; ++j ) {
+                                                        for ( k = 0 ; k < l_width_dest ; ++k) {
+                                                                *(l_dest_ptr++) = (OPJ_INT32) ((*(l_src_ptr++))&0xff);
+                                                        }
+
+                                                        l_dest_ptr+= l_line_offset_dest;
+                                                        l_src_ptr += l_line_offset_src;
+                                                }
+                                        }
+
+                                        l_src_ptr += l_end_offset_src; /* Move to the end of this component-part of the input buffer */
+                                        p_data = (OPJ_BYTE*) l_src_ptr; /* Keep the current position for the next component-part */
+                                }
+                                break;
+                        case 2:
+                                {
+                                        OPJ_INT16 * l_src_ptr = (OPJ_INT16 *) p_data;
+                                        l_src_ptr += l_start_offset_src;
+
+                                        if (l_img_comp_src->sgnd) {
+                                                for (j=0;j<l_height_dest;++j) {
+                                                        for (k=0;k<l_width_dest;++k) {
+                                                                *(l_dest_ptr++) = *(l_src_ptr++);
+                                                        }
+
+                                                        l_dest_ptr+= l_line_offset_dest;
+                                                        l_src_ptr += l_line_offset_src ;
+                                                }
+                                        }
+                                        else {
+                                                for (j=0;j<l_height_dest;++j) {
+                                                        for (k=0;k<l_width_dest;++k) {
+                                                                *(l_dest_ptr++) = (*(l_src_ptr++))&0xffff;
+                                                        }
+
+                                                        l_dest_ptr+= l_line_offset_dest;
+                                                        l_src_ptr += l_line_offset_src ;
+                                                }
+                                        }
+
+                                        l_src_ptr += l_end_offset_src;
+                                        p_data = (OPJ_BYTE*) l_src_ptr;
+                                }
+                                break;
+                        case 4:
+                                {
+                                        OPJ_INT32 * l_src_ptr = (OPJ_INT32 *) p_data;
+                                        l_src_ptr += l_start_offset_src;
+
+                                        for (j=0;j<l_height_dest;++j) {
+                                                for (k=0;k<l_width_dest;++k) {
+                                                        *(l_dest_ptr++) = (*(l_src_ptr++));
+                                                }
+
+                                                l_dest_ptr+= l_line_offset_dest;
+                                                l_src_ptr += l_line_offset_src ;
+                                        }
+
+                                        l_src_ptr += l_end_offset_src;
+                                        p_data = (OPJ_BYTE*) l_src_ptr;
+                                }
+                                break;
+                }
+
+                ++l_img_comp_dest;
+                ++l_img_comp_src;
+                ++l_tilec;
+        }
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_set_decode_area(       opj_j2k_t *p_j2k,
+                                                                    opj_image_t* p_image,
+                                                                    OPJ_INT32 p_start_x, OPJ_INT32 p_start_y,
+                                                                    OPJ_INT32 p_end_x, OPJ_INT32 p_end_y,
+                                                                    opj_event_mgr_t * p_manager )
+{
+        opj_cp_t * l_cp = &(p_j2k->m_cp);
+        opj_image_t * l_image = p_j2k->m_private_image;
+
+        OPJ_UINT32 it_comp;
+        OPJ_INT32 l_comp_x1, l_comp_y1;
+        opj_image_comp_t* l_img_comp = NULL;
+
+        /* Check if we are read the main header */
+        if (p_j2k->m_specific_param.m_decoder.m_state != J2K_STATE_TPHSOT) { /* FIXME J2K_DEC_STATE_TPHSOT)*/
+                opj_event_msg(p_manager, EVT_ERROR, "Need to decode the main header before begin to decode the remaining codestream");
+                return OPJ_FALSE;
+        }
+
+        if ( !p_start_x && !p_start_y && !p_end_x && !p_end_y){
+                opj_event_msg(p_manager, EVT_INFO, "No decoded area parameters, set the decoded area to the whole image\n");
+
+                p_j2k->m_specific_param.m_decoder.m_start_tile_x = 0;
+                p_j2k->m_specific_param.m_decoder.m_start_tile_y = 0;
+                p_j2k->m_specific_param.m_decoder.m_end_tile_x = l_cp->tw;
+                p_j2k->m_specific_param.m_decoder.m_end_tile_y = l_cp->th;
+
+                return OPJ_TRUE;
+        }
+
+        /* ----- */
+        /* Check if the positions provided by the user are correct */
+
+        /* Left */
+        assert(p_start_x >= 0 );
+        assert(p_start_y >= 0 );
+
+        if ((OPJ_UINT32)p_start_x > l_image->x1 ) {
+                opj_event_msg(p_manager, EVT_ERROR,
+                        "Left position of the decoded area (region_x0=%d) is outside the image area (Xsiz=%d).\n",
+                        p_start_x, l_image->x1);
+                return OPJ_FALSE;
+        }
+        else if ((OPJ_UINT32)p_start_x < l_image->x0){
+                opj_event_msg(p_manager, EVT_WARNING,
+                                "Left position of the decoded area (region_x0=%d) is outside the image area (XOsiz=%d).\n",
+                                p_start_x, l_image->x0);
+                p_j2k->m_specific_param.m_decoder.m_start_tile_x = 0;
+                p_image->x0 = l_image->x0;
+        }
+        else {
+                p_j2k->m_specific_param.m_decoder.m_start_tile_x = ((OPJ_UINT32)p_start_x - l_cp->tx0) / l_cp->tdx;
+                p_image->x0 = (OPJ_UINT32)p_start_x;
+        }
+
+        /* Up */
+        if ((OPJ_UINT32)p_start_y > l_image->y1){
+                opj_event_msg(p_manager, EVT_ERROR,
+                                "Up position of the decoded area (region_y0=%d) is outside the image area (Ysiz=%d).\n",
+                                p_start_y, l_image->y1);
+                return OPJ_FALSE;
+        }
+        else if ((OPJ_UINT32)p_start_y < l_image->y0){
+                opj_event_msg(p_manager, EVT_WARNING,
+                                "Up position of the decoded area (region_y0=%d) is outside the image area (YOsiz=%d).\n",
+                                p_start_y, l_image->y0);
+                p_j2k->m_specific_param.m_decoder.m_start_tile_y = 0;
+                p_image->y0 = l_image->y0;
+        }
+        else {
+                p_j2k->m_specific_param.m_decoder.m_start_tile_y = ((OPJ_UINT32)p_start_y - l_cp->ty0) / l_cp->tdy;
+                p_image->y0 = (OPJ_UINT32)p_start_y;
+        }
+
+        /* Right */
+        assert((OPJ_UINT32)p_end_x > 0);
+        assert((OPJ_UINT32)p_end_y > 0);
+        if ((OPJ_UINT32)p_end_x < l_image->x0) {
+                opj_event_msg(p_manager, EVT_ERROR,
+                        "Right position of the decoded area (region_x1=%d) is outside the image area (XOsiz=%d).\n",
+                        p_end_x, l_image->x0);
+                return OPJ_FALSE;
+        }
+        else if ((OPJ_UINT32)p_end_x > l_image->x1) {
+                opj_event_msg(p_manager, EVT_WARNING,
+                        "Right position of the decoded area (region_x1=%d) is outside the image area (Xsiz=%d).\n",
+                        p_end_x, l_image->x1);
+                p_j2k->m_specific_param.m_decoder.m_end_tile_x = l_cp->tw;
+                p_image->x1 = l_image->x1;
+        }
+        else {
+                p_j2k->m_specific_param.m_decoder.m_end_tile_x = (OPJ_UINT32)opj_int_ceildiv(p_end_x - (OPJ_INT32)l_cp->tx0, (OPJ_INT32)l_cp->tdx);
+                p_image->x1 = (OPJ_UINT32)p_end_x;
+        }
+
+        /* Bottom */
+        if ((OPJ_UINT32)p_end_y < l_image->y0) {
+                opj_event_msg(p_manager, EVT_ERROR,
+                        "Bottom position of the decoded area (region_y1=%d) is outside the image area (YOsiz=%d).\n",
+                        p_end_y, l_image->y0);
+                return OPJ_FALSE;
+        }
+        if ((OPJ_UINT32)p_end_y > l_image->y1){
+                opj_event_msg(p_manager, EVT_WARNING,
+                        "Bottom position of the decoded area (region_y1=%d) is outside the image area (Ysiz=%d).\n",
+                        p_end_y, l_image->y1);
+                p_j2k->m_specific_param.m_decoder.m_end_tile_y = l_cp->th;
+                p_image->y1 = l_image->y1;
+        }
+        else{
+                p_j2k->m_specific_param.m_decoder.m_end_tile_y = (OPJ_UINT32)opj_int_ceildiv(p_end_y - (OPJ_INT32)l_cp->ty0, (OPJ_INT32)l_cp->tdy);
+                p_image->y1 = (OPJ_UINT32)p_end_y;
+        }
+        /* ----- */
+
+        p_j2k->m_specific_param.m_decoder.m_discard_tiles = 1;
+
+        l_img_comp = p_image->comps;
+        for (it_comp=0; it_comp < p_image->numcomps; ++it_comp)
+        {
+                OPJ_INT32 l_h,l_w;
+
+                l_img_comp->x0 = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)p_image->x0, (OPJ_INT32)l_img_comp->dx);
+                l_img_comp->y0 = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)p_image->y0, (OPJ_INT32)l_img_comp->dy);
+                l_comp_x1 = opj_int_ceildiv((OPJ_INT32)p_image->x1, (OPJ_INT32)l_img_comp->dx);
+                l_comp_y1 = opj_int_ceildiv((OPJ_INT32)p_image->y1, (OPJ_INT32)l_img_comp->dy);
+
+                l_w = opj_int_ceildivpow2(l_comp_x1, (OPJ_INT32)l_img_comp->factor)
+                                - opj_int_ceildivpow2((OPJ_INT32)l_img_comp->x0, (OPJ_INT32)l_img_comp->factor);
+                if (l_w < 0){
+                        opj_event_msg(p_manager, EVT_ERROR,
+                                "Size x of the decoded component image is incorrect (comp[%d].w=%d).\n",
+                                it_comp, l_w);
+                        return OPJ_FALSE;
+                }
+                l_img_comp->w = (OPJ_UINT32)l_w;
+
+                l_h = opj_int_ceildivpow2(l_comp_y1, (OPJ_INT32)l_img_comp->factor)
+                                - opj_int_ceildivpow2((OPJ_INT32)l_img_comp->y0, (OPJ_INT32)l_img_comp->factor);
+                if (l_h < 0){
+                        opj_event_msg(p_manager, EVT_ERROR,
+                                "Size y of the decoded component image is incorrect (comp[%d].h=%d).\n",
+                                it_comp, l_h);
+                        return OPJ_FALSE;
+                }
+                l_img_comp->h = (OPJ_UINT32)l_h;
+
+                l_img_comp++;
+        }
+
+        opj_event_msg( p_manager, EVT_INFO,"Setting decoding area to %d,%d,%d,%d\n",
+                        p_image->x0, p_image->y0, p_image->x1, p_image->y1);
+
+        return OPJ_TRUE;
+}
+
+opj_j2k_t* opj_j2k_create_decompress(void)
+{
+        opj_j2k_t *l_j2k = (opj_j2k_t*) opj_malloc(sizeof(opj_j2k_t));
+        if (!l_j2k) {
+                return 00;
+        }
+        memset(l_j2k,0,sizeof(opj_j2k_t));
+
+        l_j2k->m_is_decoder = 1;
+        l_j2k->m_cp.m_is_decoder = 1;
+
+        l_j2k->m_specific_param.m_decoder.m_default_tcp = (opj_tcp_t*) opj_malloc(sizeof(opj_tcp_t));
+        if (!l_j2k->m_specific_param.m_decoder.m_default_tcp) {
+                opj_j2k_destroy(l_j2k);
+                return 00;
+        }
+        memset(l_j2k->m_specific_param.m_decoder.m_default_tcp,0,sizeof(opj_tcp_t));
+
+        l_j2k->m_specific_param.m_decoder.m_header_data = (OPJ_BYTE *) opj_malloc(OPJ_J2K_DEFAULT_HEADER_SIZE);
+        if (! l_j2k->m_specific_param.m_decoder.m_header_data) {
+                opj_j2k_destroy(l_j2k);
+                return 00;
+        }
+
+        l_j2k->m_specific_param.m_decoder.m_header_data_size = OPJ_J2K_DEFAULT_HEADER_SIZE;
+
+        l_j2k->m_specific_param.m_decoder.m_tile_ind_to_dec = -1 ;
+
+        l_j2k->m_specific_param.m_decoder.m_last_sot_read_pos = 0 ;
+
+        /* codestream index creation */
+        l_j2k->cstr_index = opj_j2k_create_cstr_index();
+
+                        /*(opj_codestream_index_t*) opj_malloc(sizeof(opj_codestream_index_t));
+        if (!l_j2k->cstr_index){
+                opj_j2k_destroy(l_j2k);
+                return NULL;
+        }
+
+        l_j2k->cstr_index->marker = (opj_marker_info_t*) opj_malloc(100 * sizeof(opj_marker_info_t));
+*/
+
+        /* validation list creation */
+        l_j2k->m_validation_list = opj_procedure_list_create();
+        if (! l_j2k->m_validation_list) {
+                opj_j2k_destroy(l_j2k);
+                return 00;
+        }
+
+        /* execution list creation */
+        l_j2k->m_procedure_list = opj_procedure_list_create();
+        if (! l_j2k->m_procedure_list) {
+                opj_j2k_destroy(l_j2k);
+                return 00;
+        }
+
+        return l_j2k;
+}
+
+opj_codestream_index_t* opj_j2k_create_cstr_index(void)
+{
+        opj_codestream_index_t* cstr_index = (opj_codestream_index_t*)
+                        opj_calloc(1,sizeof(opj_codestream_index_t));
+        if (!cstr_index)
+                return NULL;
+
+        cstr_index->maxmarknum = 100;
+        cstr_index->marknum = 0;
+        cstr_index->marker = (opj_marker_info_t*)
+                        opj_calloc(cstr_index->maxmarknum, sizeof(opj_marker_info_t));
+        if (!cstr_index-> marker)
+                return NULL;
+
+        cstr_index->tile_index = NULL;
+
+        return cstr_index;
+}
+
+OPJ_UINT32 opj_j2k_get_SPCod_SPCoc_size (       opj_j2k_t *p_j2k,
+                                                                                OPJ_UINT32 p_tile_no,
+                                                                                OPJ_UINT32 p_comp_no )
+{
+        opj_cp_t *l_cp = 00;
+        opj_tcp_t *l_tcp = 00;
+        opj_tccp_t *l_tccp = 00;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+
+        l_cp = &(p_j2k->m_cp);
+        l_tcp = &l_cp->tcps[p_tile_no];
+        l_tccp = &l_tcp->tccps[p_comp_no];
+
+        /* preconditions again */
+        assert(p_tile_no < (l_cp->tw * l_cp->th));
+        assert(p_comp_no < p_j2k->m_private_image->numcomps);
+
+        if (l_tccp->csty & J2K_CCP_CSTY_PRT) {
+                return 5 + l_tccp->numresolutions;
+        }
+        else {
+                return 5;
+        }
+}
+
+OPJ_BOOL opj_j2k_write_SPCod_SPCoc(     opj_j2k_t *p_j2k,
+                                                                    OPJ_UINT32 p_tile_no,
+                                                                    OPJ_UINT32 p_comp_no,
+                                                                    OPJ_BYTE * p_data,
+                                                                    OPJ_UINT32 * p_header_size,
+                                                                    struct opj_event_mgr * p_manager )
+{
+        OPJ_UINT32 i;
+        opj_cp_t *l_cp = 00;
+        opj_tcp_t *l_tcp = 00;
+        opj_tccp_t *l_tccp = 00;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_header_size != 00);
+        assert(p_manager != 00);
+        assert(p_data != 00);
+
+        l_cp = &(p_j2k->m_cp);
+        l_tcp = &l_cp->tcps[p_tile_no];
+        l_tccp = &l_tcp->tccps[p_comp_no];
+
+        /* preconditions again */
+        assert(p_tile_no < (l_cp->tw * l_cp->th));
+        assert(p_comp_no <(p_j2k->m_private_image->numcomps));
+
+        if (*p_header_size < 5) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error writing SPCod SPCoc element\n");
+                return OPJ_FALSE;
+        }
+
+        opj_write_bytes(p_data,l_tccp->numresolutions - 1, 1);  /* SPcoc (D) */
+        ++p_data;
+
+        opj_write_bytes(p_data,l_tccp->cblkw - 2, 1);                   /* SPcoc (E) */
+        ++p_data;
+
+        opj_write_bytes(p_data,l_tccp->cblkh - 2, 1);                   /* SPcoc (F) */
+        ++p_data;
+
+        opj_write_bytes(p_data,l_tccp->cblksty, 1);                             /* SPcoc (G) */
+        ++p_data;
+
+        opj_write_bytes(p_data,l_tccp->qmfbid, 1);                              /* SPcoc (H) */
+        ++p_data;
+
+        *p_header_size = *p_header_size - 5;
+
+        if (l_tccp->csty & J2K_CCP_CSTY_PRT) {
+
+                if (*p_header_size < l_tccp->numresolutions) {
+                        opj_event_msg(p_manager, EVT_ERROR, "Error writing SPCod SPCoc element\n");
+                        return OPJ_FALSE;
+                }
+
+                for (i = 0; i < l_tccp->numresolutions; ++i) {
+                        opj_write_bytes(p_data,l_tccp->prcw[i] + (l_tccp->prch[i] << 4), 1);    /* SPcoc (I_i) */
+                        ++p_data;
+                }
+
+                *p_header_size = *p_header_size - l_tccp->numresolutions;
+        }
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_read_SPCod_SPCoc(  opj_j2k_t *p_j2k,
+                                                                OPJ_UINT32 compno,
+                                                                OPJ_BYTE * p_header_data,
+                                                                OPJ_UINT32 * p_header_size,
+                                                                opj_event_mgr_t * p_manager)
+{
+        OPJ_UINT32 i, l_tmp;
+        opj_cp_t *l_cp = NULL;
+        opj_tcp_t *l_tcp = NULL;
+        opj_tccp_t *l_tccp = NULL;
+        OPJ_BYTE * l_current_ptr = NULL;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+        assert(p_header_data != 00);
+
+        l_cp = &(p_j2k->m_cp);
+        l_tcp = (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH) ?
+                                &l_cp->tcps[p_j2k->m_current_tile_number] :
+                                p_j2k->m_specific_param.m_decoder.m_default_tcp;
+
+        /* precondition again */
+        assert(compno < p_j2k->m_private_image->numcomps);
+
+        l_tccp = &l_tcp->tccps[compno];
+        l_current_ptr = p_header_data;
+
+        /* make sure room is sufficient */
+        if (*p_header_size < 5) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error reading SPCod SPCoc element\n");
+                return OPJ_FALSE;
+        }
+
+        opj_read_bytes(l_current_ptr, &l_tccp->numresolutions ,1);              /* SPcox (D) */
+        ++l_tccp->numresolutions;                                                                               /* tccp->numresolutions = read() + 1 */
+        if (l_tccp->numresolutions > OPJ_J2K_MAXRLVLS) {
+                opj_event_msg(p_manager, EVT_ERROR,
+                              "Invalid value for numresolutions : %d, max value is set in openjpeg.h at %d\n",
+                              l_tccp->numresolutions, OPJ_J2K_MAXRLVLS);
+                return OPJ_FALSE;
+        }
+        ++l_current_ptr;
+
+        /* If user wants to remove more resolutions than the codestream contains, return error */
+        if (l_cp->m_specific_param.m_dec.m_reduce >= l_tccp->numresolutions) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error decoding component %d.\nThe number of resolutions to remove is higher than the number "
+                                        "of resolutions of this component\nModify the cp_reduce parameter.\n\n", compno);
+                p_j2k->m_specific_param.m_decoder.m_state |= 0x8000;/* FIXME J2K_DEC_STATE_ERR;*/
+                return OPJ_FALSE;
+        }
+
+        opj_read_bytes(l_current_ptr,&l_tccp->cblkw ,1);                /* SPcoc (E) */
+        ++l_current_ptr;
+        l_tccp->cblkw += 2;
+
+        opj_read_bytes(l_current_ptr,&l_tccp->cblkh ,1);                /* SPcoc (F) */
+        ++l_current_ptr;
+        l_tccp->cblkh += 2;
+
+        opj_read_bytes(l_current_ptr,&l_tccp->cblksty ,1);              /* SPcoc (G) */
+        ++l_current_ptr;
+
+        opj_read_bytes(l_current_ptr,&l_tccp->qmfbid ,1);               /* SPcoc (H) */
+        ++l_current_ptr;
+
+        *p_header_size = *p_header_size - 5;
+
+        /* use custom precinct size ? */
+        if (l_tccp->csty & J2K_CCP_CSTY_PRT) {
+                if (*p_header_size < l_tccp->numresolutions) {
+                        opj_event_msg(p_manager, EVT_ERROR, "Error reading SPCod SPCoc element\n");
+                        return OPJ_FALSE;
+                }
+
+                for     (i = 0; i < l_tccp->numresolutions; ++i) {
+                        opj_read_bytes(l_current_ptr,&l_tmp ,1);                /* SPcoc (I_i) */
+                        ++l_current_ptr;
+                        l_tccp->prcw[i] = l_tmp & 0xf;
+                        l_tccp->prch[i] = l_tmp >> 4;
+                }
+
+                *p_header_size = *p_header_size - l_tccp->numresolutions;
+        }
+        else {
+                /* set default size for the precinct width and height */
+                for     (i = 0; i < l_tccp->numresolutions; ++i) {
+                        l_tccp->prcw[i] = 15;
+                        l_tccp->prch[i] = 15;
+                }
+        }
+
+#ifdef WIP_REMOVE_MSD
+        /* INDEX >> */
+        if (p_j2k->cstr_info && compno == 0) {
+                OPJ_UINT32 l_data_size = l_tccp->numresolutions * sizeof(OPJ_UINT32);
+
+                p_j2k->cstr_info->tile[p_j2k->m_current_tile_number].tccp_info[compno].cblkh = l_tccp->cblkh;
+                p_j2k->cstr_info->tile[p_j2k->m_current_tile_number].tccp_info[compno].cblkw = l_tccp->cblkw;
+                p_j2k->cstr_info->tile[p_j2k->m_current_tile_number].tccp_info[compno].numresolutions = l_tccp->numresolutions;
+                p_j2k->cstr_info->tile[p_j2k->m_current_tile_number].tccp_info[compno].cblksty = l_tccp->cblksty;
+                p_j2k->cstr_info->tile[p_j2k->m_current_tile_number].tccp_info[compno].qmfbid = l_tccp->qmfbid;
+
+                memcpy(p_j2k->cstr_info->tile[p_j2k->m_current_tile_number].pdx,l_tccp->prcw, l_data_size);
+                memcpy(p_j2k->cstr_info->tile[p_j2k->m_current_tile_number].pdy,l_tccp->prch, l_data_size);
+        }
+        /* << INDEX */
+#endif
+
+        return OPJ_TRUE;
+}
+
+void opj_j2k_copy_tile_component_parameters( opj_j2k_t *p_j2k )
+{
+        /* loop */
+        OPJ_UINT32 i;
+        opj_cp_t *l_cp = NULL;
+        opj_tcp_t *l_tcp = NULL;
+        opj_tccp_t *l_ref_tccp = NULL, *l_copied_tccp = NULL;
+        OPJ_UINT32 l_prc_size;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+
+        l_cp = &(p_j2k->m_cp);
+        l_tcp = (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH) ? /* FIXME J2K_DEC_STATE_TPH*/
+                                &l_cp->tcps[p_j2k->m_current_tile_number] :
+                                p_j2k->m_specific_param.m_decoder.m_default_tcp;
+
+        l_ref_tccp = &l_tcp->tccps[0];
+        l_copied_tccp = l_ref_tccp + 1;
+        l_prc_size = l_ref_tccp->numresolutions * (OPJ_UINT32)sizeof(OPJ_UINT32);
+
+        for     (i=1; i<p_j2k->m_private_image->numcomps; ++i) {
+                l_copied_tccp->numresolutions = l_ref_tccp->numresolutions;
+                l_copied_tccp->cblkw = l_ref_tccp->cblkw;
+                l_copied_tccp->cblkh = l_ref_tccp->cblkh;
+                l_copied_tccp->cblksty = l_ref_tccp->cblksty;
+                l_copied_tccp->qmfbid = l_ref_tccp->qmfbid;
+                memcpy(l_copied_tccp->prcw,l_ref_tccp->prcw,l_prc_size);
+                memcpy(l_copied_tccp->prch,l_ref_tccp->prch,l_prc_size);
+                ++l_copied_tccp;
+        }
+}
+
+OPJ_UINT32 opj_j2k_get_SQcd_SQcc_size ( opj_j2k_t *p_j2k,
+                                                                        OPJ_UINT32 p_tile_no,
+                                                                        OPJ_UINT32 p_comp_no )
+{
+        OPJ_UINT32 l_num_bands;
+
+        opj_cp_t *l_cp = 00;
+        opj_tcp_t *l_tcp = 00;
+        opj_tccp_t *l_tccp = 00;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+
+        l_cp = &(p_j2k->m_cp);
+        l_tcp = &l_cp->tcps[p_tile_no];
+        l_tccp = &l_tcp->tccps[p_comp_no];
+
+        /* preconditions again */
+        assert(p_tile_no < l_cp->tw * l_cp->th);
+        assert(p_comp_no < p_j2k->m_private_image->numcomps);
+
+        l_num_bands = (l_tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) ? 1 : (l_tccp->numresolutions * 3 - 2);
+
+        if (l_tccp->qntsty == J2K_CCP_QNTSTY_NOQNT)  {
+                return 1 + l_num_bands;
+        }
+        else {
+                return 1 + 2*l_num_bands;
+        }
+}
+
+OPJ_BOOL opj_j2k_write_SQcd_SQcc(       opj_j2k_t *p_j2k,
+                                                                OPJ_UINT32 p_tile_no,
+                                                                OPJ_UINT32 p_comp_no,
+                                                                OPJ_BYTE * p_data,
+                                                                OPJ_UINT32 * p_header_size,
+                                                                struct opj_event_mgr * p_manager )
+{
+        OPJ_UINT32 l_header_size;
+        OPJ_UINT32 l_band_no, l_num_bands;
+        OPJ_UINT32 l_expn,l_mant;
+
+        opj_cp_t *l_cp = 00;
+        opj_tcp_t *l_tcp = 00;
+        opj_tccp_t *l_tccp = 00;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_header_size != 00);
+        assert(p_manager != 00);
+        assert(p_data != 00);
+
+        l_cp = &(p_j2k->m_cp);
+        l_tcp = &l_cp->tcps[p_tile_no];
+        l_tccp = &l_tcp->tccps[p_comp_no];
+
+        /* preconditions again */
+        assert(p_tile_no < l_cp->tw * l_cp->th);
+        assert(p_comp_no <p_j2k->m_private_image->numcomps);
+
+        l_num_bands = (l_tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) ? 1 : (l_tccp->numresolutions * 3 - 2);
+
+        if (l_tccp->qntsty == J2K_CCP_QNTSTY_NOQNT)  {
+                l_header_size = 1 + l_num_bands;
+
+                if (*p_header_size < l_header_size) {
+                        opj_event_msg(p_manager, EVT_ERROR, "Error writing SQcd SQcc element\n");
+                        return OPJ_FALSE;
+                }
+
+                opj_write_bytes(p_data,l_tccp->qntsty + (l_tccp->numgbits << 5), 1);    /* Sqcx */
+                ++p_data;
+
+                for (l_band_no = 0; l_band_no < l_num_bands; ++l_band_no) {
+                        l_expn = (OPJ_UINT32)l_tccp->stepsizes[l_band_no].expn;
+                        opj_write_bytes(p_data, l_expn << 3, 1);        /* SPqcx_i */
+                        ++p_data;
+                }
+        }
+        else {
+                l_header_size = 1 + 2*l_num_bands;
+
+                if (*p_header_size < l_header_size) {
+                        opj_event_msg(p_manager, EVT_ERROR, "Error writing SQcd SQcc element\n");
+                        return OPJ_FALSE;
+                }
+
+                opj_write_bytes(p_data,l_tccp->qntsty + (l_tccp->numgbits << 5), 1);    /* Sqcx */
+                ++p_data;
+
+                for (l_band_no = 0; l_band_no < l_num_bands; ++l_band_no) {
+                        l_expn = (OPJ_UINT32)l_tccp->stepsizes[l_band_no].expn;
+                        l_mant = (OPJ_UINT32)l_tccp->stepsizes[l_band_no].mant;
+
+                        opj_write_bytes(p_data, (l_expn << 11) + l_mant, 2);    /* SPqcx_i */
+                        p_data += 2;
+                }
+        }
+
+        *p_header_size = *p_header_size - l_header_size;
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_read_SQcd_SQcc(opj_j2k_t *p_j2k,
+                                                            OPJ_UINT32 p_comp_no,
+                                                            OPJ_BYTE* p_header_data,
+                                                            OPJ_UINT32 * p_header_size,
+                                                            opj_event_mgr_t * p_manager
+                                                            )
+{
+        /* loop*/
+        OPJ_UINT32 l_band_no;
+        opj_cp_t *l_cp = 00;
+        opj_tcp_t *l_tcp = 00;
+        opj_tccp_t *l_tccp = 00;
+        OPJ_BYTE * l_current_ptr = 00;
+        OPJ_UINT32 l_tmp, l_num_band;
+
+        /* preconditions*/
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+        assert(p_header_data != 00);
+
+        l_cp = &(p_j2k->m_cp);
+        /* come from tile part header or main header ?*/
+        l_tcp = (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH) ? /*FIXME J2K_DEC_STATE_TPH*/
+                                &l_cp->tcps[p_j2k->m_current_tile_number] :
+                                p_j2k->m_specific_param.m_decoder.m_default_tcp;
+
+        /* precondition again*/
+        assert(p_comp_no <  p_j2k->m_private_image->numcomps);
+
+        l_tccp = &l_tcp->tccps[p_comp_no];
+        l_current_ptr = p_header_data;
+
+        if (*p_header_size < 1) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error reading SQcd or SQcc element\n");
+                return OPJ_FALSE;
+        }
+        *p_header_size -= 1;
+
+        opj_read_bytes(l_current_ptr, &l_tmp ,1);                       /* Sqcx */
+        ++l_current_ptr;
+
+        l_tccp->qntsty = l_tmp & 0x1f;
+        l_tccp->numgbits = l_tmp >> 5;
+        if (l_tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) {
+        l_num_band = 1;
+        }
+        else {
+                l_num_band = (l_tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) ?
+                        (*p_header_size) :
+                        (*p_header_size) / 2;
+
+                if( l_num_band > OPJ_J2K_MAXBANDS ) {
+                        opj_event_msg(p_manager, EVT_WARNING, "While reading CCP_QNTSTY element inside QCD or QCC marker segment, "
+                                "number of subbands (%d) is greater to OPJ_J2K_MAXBANDS (%d). So we limit the number of elements stored to "
+                                "OPJ_J2K_MAXBANDS (%d) and skip the rest. \n", l_num_band, OPJ_J2K_MAXBANDS, OPJ_J2K_MAXBANDS);
+                        /*return OPJ_FALSE;*/
+                }
+        }
+
+#ifdef USE_JPWL
+        if (l_cp->correct) {
+
+                /* if JPWL is on, we check whether there are too many subbands */
+                if (/*(l_num_band < 0) ||*/ (l_num_band >= OPJ_J2K_MAXBANDS)) {
+                        opj_event_msg(p_manager, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
+                                "JPWL: bad number of subbands in Sqcx (%d)\n",
+                                l_num_band);
+                        if (!JPWL_ASSUME) {
+                                opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n");
+                                return OPJ_FALSE;
+                        }
+                        /* we try to correct */
+                        l_num_band = 1;
+                        opj_event_msg(p_manager, EVT_WARNING, "- trying to adjust them\n"
+                                "- setting number of bands to %d => HYPOTHESIS!!!\n",
+                                l_num_band);
+                };
+
+        };
+#endif /* USE_JPWL */
+
+        if (l_tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) {
+                for     (l_band_no = 0; l_band_no < l_num_band; l_band_no++) {
+                        opj_read_bytes(l_current_ptr, &l_tmp ,1);                       /* SPqcx_i */
+                        ++l_current_ptr;
+                        if (l_band_no < OPJ_J2K_MAXBANDS){
+                                l_tccp->stepsizes[l_band_no].expn = (OPJ_INT32)(l_tmp >> 3);
+                                l_tccp->stepsizes[l_band_no].mant = 0;
+                        }
+                }
+                *p_header_size = *p_header_size - l_num_band;
+        }
+        else {
+                for     (l_band_no = 0; l_band_no < l_num_band; l_band_no++) {
+                        opj_read_bytes(l_current_ptr, &l_tmp ,2);                       /* SPqcx_i */
+                        l_current_ptr+=2;
+                        if (l_band_no < OPJ_J2K_MAXBANDS){
+                                l_tccp->stepsizes[l_band_no].expn = (OPJ_INT32)(l_tmp >> 11);
+                                l_tccp->stepsizes[l_band_no].mant = l_tmp & 0x7ff;
+                        }
+                }
+                *p_header_size = *p_header_size - 2*l_num_band;
+        }
+
+        /* Add Antonin : if scalar_derived -> compute other stepsizes */
+        if (l_tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) {
+                for (l_band_no = 1; l_band_no < OPJ_J2K_MAXBANDS; l_band_no++) {
+                        l_tccp->stepsizes[l_band_no].expn =
+                                ((OPJ_INT32)(l_tccp->stepsizes[0].expn) - (OPJ_INT32)((l_band_no - 1) / 3) > 0) ?
+                                        (OPJ_INT32)(l_tccp->stepsizes[0].expn) - (OPJ_INT32)((l_band_no - 1) / 3) : 0;
+                        l_tccp->stepsizes[l_band_no].mant = l_tccp->stepsizes[0].mant;
+                }
+        }
+
+        return OPJ_TRUE;
+}
+
+void opj_j2k_copy_tile_quantization_parameters( opj_j2k_t *p_j2k )
+{
+        OPJ_UINT32 i;
+        opj_cp_t *l_cp = NULL;
+        opj_tcp_t *l_tcp = NULL;
+        opj_tccp_t *l_ref_tccp = NULL;
+        opj_tccp_t *l_copied_tccp = NULL;
+        OPJ_UINT32 l_size;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+
+        l_cp = &(p_j2k->m_cp);
+        l_tcp = p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH ?
+                        &l_cp->tcps[p_j2k->m_current_tile_number] :
+                        p_j2k->m_specific_param.m_decoder.m_default_tcp;
+
+        l_ref_tccp = &l_tcp->tccps[0];
+        l_copied_tccp = l_ref_tccp + 1;
+        l_size = OPJ_J2K_MAXBANDS * sizeof(opj_stepsize_t);
+
+        for     (i=1;i<p_j2k->m_private_image->numcomps;++i) {
+                l_copied_tccp->qntsty = l_ref_tccp->qntsty;
+                l_copied_tccp->numgbits = l_ref_tccp->numgbits;
+                memcpy(l_copied_tccp->stepsizes,l_ref_tccp->stepsizes,l_size);
+                ++l_copied_tccp;
+        }
+}
+
+static void opj_j2k_dump_tile_info( opj_tcp_t * l_default_tile,OPJ_INT32 numcomps,FILE* out_stream)
+{
+        if (l_default_tile)
+        {
+                OPJ_INT32 compno;
+
+                fprintf(out_stream, "\t default tile {\n");
+                fprintf(out_stream, "\t\t csty=%#x\n", l_default_tile->csty);
+                fprintf(out_stream, "\t\t prg=%#x\n", l_default_tile->prg);
+                fprintf(out_stream, "\t\t numlayers=%d\n", l_default_tile->numlayers);
+                fprintf(out_stream, "\t\t mct=%x\n", l_default_tile->mct);
+
+                for (compno = 0; compno < numcomps; compno++) {
+                        opj_tccp_t *l_tccp = &(l_default_tile->tccps[compno]);
+                        OPJ_UINT32 resno;
+      OPJ_INT32 bandno, numbands;
+
+                        /* coding style*/
+                        fprintf(out_stream, "\t\t comp %d {\n", compno);
+                        fprintf(out_stream, "\t\t\t csty=%#x\n", l_tccp->csty);
+                        fprintf(out_stream, "\t\t\t numresolutions=%d\n", l_tccp->numresolutions);
+                        fprintf(out_stream, "\t\t\t cblkw=2^%d\n", l_tccp->cblkw);
+                        fprintf(out_stream, "\t\t\t cblkh=2^%d\n", l_tccp->cblkh);
+                        fprintf(out_stream, "\t\t\t cblksty=%#x\n", l_tccp->cblksty);
+                        fprintf(out_stream, "\t\t\t qmfbid=%d\n", l_tccp->qmfbid);
+
+                        fprintf(out_stream, "\t\t\t preccintsize (w,h)=");
+                        for (resno = 0; resno < l_tccp->numresolutions; resno++) {
+                                fprintf(out_stream, "(%d,%d) ", l_tccp->prcw[resno], l_tccp->prch[resno]);
+                        }
+                        fprintf(out_stream, "\n");
+
+                        /* quantization style*/
+                        fprintf(out_stream, "\t\t\t qntsty=%d\n", l_tccp->qntsty);
+                        fprintf(out_stream, "\t\t\t numgbits=%d\n", l_tccp->numgbits);
+                        fprintf(out_stream, "\t\t\t stepsizes (m,e)=");
+                        numbands = (l_tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) ? 1 : (OPJ_INT32)l_tccp->numresolutions * 3 - 2;
+                        for (bandno = 0; bandno < numbands; bandno++) {
+                                fprintf(out_stream, "(%d,%d) ", l_tccp->stepsizes[bandno].mant,
+                                        l_tccp->stepsizes[bandno].expn);
+                        }
+                        fprintf(out_stream, "\n");
+
+                        /* RGN value*/
+                        fprintf(out_stream, "\t\t\t roishift=%d\n", l_tccp->roishift);
+
+                        fprintf(out_stream, "\t\t }\n");
+                } /*end of component of default tile*/
+                fprintf(out_stream, "\t }\n"); /*end of default tile*/
+            }
+}
+
+void j2k_dump (opj_j2k_t* p_j2k, OPJ_INT32 flag, FILE* out_stream)
+{
+        /* Check if the flag is compatible with j2k file*/
+        if ( (flag & OPJ_JP2_INFO) || (flag & OPJ_JP2_IND)){
+                fprintf(out_stream, "Wrong flag\n");
+                return;
+        }
+
+        /* Dump the image_header */
+        if (flag & OPJ_IMG_INFO){
+                if (p_j2k->m_private_image)
+                        j2k_dump_image_header(p_j2k->m_private_image, 0, out_stream);
+        }
+
+        /* Dump the codestream info from main header */
+        if (flag & OPJ_J2K_MH_INFO){
+                opj_j2k_dump_MH_info(p_j2k, out_stream);
+        }
+        /* Dump all tile/codestream info */
+        if (flag & OPJ_J2K_TCH_INFO){
+          OPJ_UINT32 l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw;
+          OPJ_UINT32 i;
+          opj_tcp_t * l_tcp = p_j2k->m_cp.tcps;
+          for (i=0;i<l_nb_tiles;++i) {
+            opj_j2k_dump_tile_info( l_tcp,(OPJ_INT32)p_j2k->m_private_image->numcomps, out_stream);
+            ++l_tcp;
+          }
+        }
+
+        /* Dump the codestream info of the current tile */
+        if (flag & OPJ_J2K_TH_INFO){
+
+        }
+
+        /* Dump the codestream index from main header */
+        if (flag & OPJ_J2K_MH_IND){
+                opj_j2k_dump_MH_index(p_j2k, out_stream);
+        }
+
+        /* Dump the codestream index of the current tile */
+        if (flag & OPJ_J2K_TH_IND){
+
+        }
+
+}
+
+void opj_j2k_dump_MH_index(opj_j2k_t* p_j2k, FILE* out_stream)
+{
+        opj_codestream_index_t* cstr_index = p_j2k->cstr_index;
+        OPJ_UINT32 it_marker, it_tile, it_tile_part;
+
+        fprintf(out_stream, "Codestream index from main header: {\n");
+
+        fprintf(out_stream, "\t Main header start position=%" PRIi64 "\n"
+                                    "\t Main header end position=%" PRIi64 "\n",
+                        cstr_index->main_head_start, cstr_index->main_head_end);
+
+        fprintf(out_stream, "\t Marker list: {\n");
+
+        if (cstr_index->marker){
+                for (it_marker=0; it_marker < cstr_index->marknum ; it_marker++){
+                        fprintf(out_stream, "\t\t type=%#x, pos=%" PRIi64 ", len=%d\n",
+                                        cstr_index->marker[it_marker].type,
+                                        cstr_index->marker[it_marker].pos,
+                                        cstr_index->marker[it_marker].len );
+                }
+        }
+
+        fprintf(out_stream, "\t }\n");
+
+        if (cstr_index->tile_index){
+
+        /* Simple test to avoid to write empty information*/
+        OPJ_UINT32 l_acc_nb_of_tile_part = 0;
+        for (it_tile=0; it_tile < cstr_index->nb_of_tiles ; it_tile++){
+                        l_acc_nb_of_tile_part += cstr_index->tile_index[it_tile].nb_tps;
+        }
+
+        if (l_acc_nb_of_tile_part)
+        {
+            fprintf(out_stream, "\t Tile index: {\n");
+
+                    for (it_tile=0; it_tile < cstr_index->nb_of_tiles ; it_tile++){
+                            OPJ_UINT32 nb_of_tile_part = cstr_index->tile_index[it_tile].nb_tps;
+
+                            fprintf(out_stream, "\t\t nb of tile-part in tile [%d]=%d\n", it_tile, nb_of_tile_part);
+
+                            if (cstr_index->tile_index[it_tile].tp_index){
+                                    for (it_tile_part =0; it_tile_part < nb_of_tile_part; it_tile_part++){
+                                            fprintf(out_stream, "\t\t\t tile-part[%d]: star_pos=%" PRIi64 ", end_header=%" PRIi64 ", end_pos=%" PRIi64 ".\n",
+                                                            it_tile_part,
+                                                            cstr_index->tile_index[it_tile].tp_index[it_tile_part].start_pos,
+                                                            cstr_index->tile_index[it_tile].tp_index[it_tile_part].end_header,
+                                                            cstr_index->tile_index[it_tile].tp_index[it_tile_part].end_pos);
+                                    }
+                            }
+
+                            if (cstr_index->tile_index[it_tile].marker){
+                                    for (it_marker=0; it_marker < cstr_index->tile_index[it_tile].marknum ; it_marker++){
+                                            fprintf(out_stream, "\t\t type=%#x, pos=%" PRIi64 ", len=%d\n",
+                                                            cstr_index->tile_index[it_tile].marker[it_marker].type,
+                                                            cstr_index->tile_index[it_tile].marker[it_marker].pos,
+                                                            cstr_index->tile_index[it_tile].marker[it_marker].len );
+                                    }
+                            }
+                    }
+                    fprintf(out_stream,"\t }\n");
+        }
+        }
+
+        fprintf(out_stream,"}\n");
+
+}
+
+
+void opj_j2k_dump_MH_info(opj_j2k_t* p_j2k, FILE* out_stream)
+{
+
+        fprintf(out_stream, "Codestream info from main header: {\n");
+
+        fprintf(out_stream, "\t tx0=%d, ty0=%d\n", p_j2k->m_cp.tx0, p_j2k->m_cp.ty0);
+        fprintf(out_stream, "\t tdx=%d, tdy=%d\n", p_j2k->m_cp.tdx, p_j2k->m_cp.tdy);
+        fprintf(out_stream, "\t tw=%d, th=%d\n", p_j2k->m_cp.tw, p_j2k->m_cp.th);
+        opj_j2k_dump_tile_info(p_j2k->m_specific_param.m_decoder.m_default_tcp,(OPJ_INT32)p_j2k->m_private_image->numcomps, out_stream);
+        fprintf(out_stream, "}\n");
+}
+
+void j2k_dump_image_header(opj_image_t* img_header, OPJ_BOOL dev_dump_flag, FILE* out_stream)
+{
+        char tab[2];
+
+        if (dev_dump_flag){
+                fprintf(stdout, "[DEV] Dump an image_header struct {\n");
+                tab[0] = '\0';
+        }
+        else {
+                fprintf(out_stream, "Image info {\n");
+                tab[0] = '\t';tab[1] = '\0';
+        }
+
+        fprintf(out_stream, "%s x0=%d, y0=%d\n", tab, img_header->x0, img_header->y0);
+        fprintf(out_stream,     "%s x1=%d, y1=%d\n", tab, img_header->x1, img_header->y1);
+        fprintf(out_stream, "%s numcomps=%d\n", tab, img_header->numcomps);
+
+        if (img_header->comps){
+                OPJ_UINT32 compno;
+                for (compno = 0; compno < img_header->numcomps; compno++) {
+                        fprintf(out_stream, "%s\t component %d {\n", tab, compno);
+                        j2k_dump_image_comp_header(&(img_header->comps[compno]), dev_dump_flag, out_stream);
+                        fprintf(out_stream,"%s}\n",tab);
+                }
+        }
+
+        fprintf(out_stream, "}\n");
+}
+
+void j2k_dump_image_comp_header(opj_image_comp_t* comp_header, OPJ_BOOL dev_dump_flag, FILE* out_stream)
+{
+        char tab[3];
+
+        if (dev_dump_flag){
+                fprintf(stdout, "[DEV] Dump an image_comp_header struct {\n");
+                tab[0] = '\0';
+        }       else {
+                tab[0] = '\t';tab[1] = '\t';tab[2] = '\0';
+        }
+
+        fprintf(out_stream, "%s dx=%d, dy=%d\n", tab, comp_header->dx, comp_header->dy);
+        fprintf(out_stream, "%s prec=%d\n", tab, comp_header->prec);
+        fprintf(out_stream, "%s sgnd=%d\n", tab, comp_header->sgnd);
+
+        if (dev_dump_flag)
+                fprintf(out_stream, "}\n");
+}
+
+opj_codestream_info_v2_t* j2k_get_cstr_info(opj_j2k_t* p_j2k)
+{
+        OPJ_UINT32 compno;
+        OPJ_UINT32 numcomps = p_j2k->m_private_image->numcomps;
+        opj_tcp_t *l_default_tile;
+        opj_codestream_info_v2_t* cstr_info = (opj_codestream_info_v2_t*) opj_calloc(1,sizeof(opj_codestream_info_v2_t));
+		if (!cstr_info)
+			return NULL;
+
+        cstr_info->nbcomps = p_j2k->m_private_image->numcomps;
+
+        cstr_info->tx0 = p_j2k->m_cp.tx0;
+        cstr_info->ty0 = p_j2k->m_cp.ty0;
+        cstr_info->tdx = p_j2k->m_cp.tdx;
+        cstr_info->tdy = p_j2k->m_cp.tdy;
+        cstr_info->tw = p_j2k->m_cp.tw;
+        cstr_info->th = p_j2k->m_cp.th;
+
+        cstr_info->tile_info = NULL; /* Not fill from the main header*/
+
+        l_default_tile = p_j2k->m_specific_param.m_decoder.m_default_tcp;
+
+        cstr_info->m_default_tile_info.csty = l_default_tile->csty;
+        cstr_info->m_default_tile_info.prg = l_default_tile->prg;
+        cstr_info->m_default_tile_info.numlayers = l_default_tile->numlayers;
+        cstr_info->m_default_tile_info.mct = l_default_tile->mct;
+
+        cstr_info->m_default_tile_info.tccp_info = (opj_tccp_info_t*) opj_calloc(cstr_info->nbcomps, sizeof(opj_tccp_info_t));
+		if (!cstr_info->m_default_tile_info.tccp_info)
+		{
+			opj_destroy_cstr_info(&cstr_info);
+			return NULL;
+		}
+
+        for (compno = 0; compno < numcomps; compno++) {
+                opj_tccp_t *l_tccp = &(l_default_tile->tccps[compno]);
+                opj_tccp_info_t *l_tccp_info = &(cstr_info->m_default_tile_info.tccp_info[compno]);
+                OPJ_INT32 bandno, numbands;
+
+                /* coding style*/
+                l_tccp_info->csty = l_tccp->csty;
+                l_tccp_info->numresolutions = l_tccp->numresolutions;
+                l_tccp_info->cblkw = l_tccp->cblkw;
+                l_tccp_info->cblkh = l_tccp->cblkh;
+                l_tccp_info->cblksty = l_tccp->cblksty;
+                l_tccp_info->qmfbid = l_tccp->qmfbid;
+                if (l_tccp->numresolutions < OPJ_J2K_MAXRLVLS)
+                {
+                        memcpy(l_tccp_info->prch, l_tccp->prch, l_tccp->numresolutions);
+                        memcpy(l_tccp_info->prcw, l_tccp->prcw, l_tccp->numresolutions);
+                }
+
+                /* quantization style*/
+                l_tccp_info->qntsty = l_tccp->qntsty;
+                l_tccp_info->numgbits = l_tccp->numgbits;
+
+                numbands = (l_tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) ? 1 : (OPJ_INT32)l_tccp->numresolutions * 3 - 2;
+                if (numbands < OPJ_J2K_MAXBANDS) {
+                        for (bandno = 0; bandno < numbands; bandno++) {
+                                l_tccp_info->stepsizes_mant[bandno] = (OPJ_UINT32)l_tccp->stepsizes[bandno].mant;
+                                l_tccp_info->stepsizes_expn[bandno] = (OPJ_UINT32)l_tccp->stepsizes[bandno].expn;
+                        }
+                }
+
+                /* RGN value*/
+                l_tccp_info->roishift = l_tccp->roishift;
+        }
+
+        return cstr_info;
+}
+
+opj_codestream_index_t* j2k_get_cstr_index(opj_j2k_t* p_j2k)
+{
+        opj_codestream_index_t* l_cstr_index = (opj_codestream_index_t*)
+                        opj_calloc(1,sizeof(opj_codestream_index_t));
+        if (!l_cstr_index)
+                return NULL;
+
+        l_cstr_index->main_head_start = p_j2k->cstr_index->main_head_start;
+        l_cstr_index->main_head_end = p_j2k->cstr_index->main_head_end;
+        l_cstr_index->codestream_size = p_j2k->cstr_index->codestream_size;
+
+        l_cstr_index->marknum = p_j2k->cstr_index->marknum;
+        l_cstr_index->marker = (opj_marker_info_t*)opj_malloc(l_cstr_index->marknum*sizeof(opj_marker_info_t));
+        if (!l_cstr_index->marker){
+                opj_free( l_cstr_index);
+                return NULL;
+        }
+
+        if (p_j2k->cstr_index->marker)
+                memcpy(l_cstr_index->marker, p_j2k->cstr_index->marker, l_cstr_index->marknum * sizeof(opj_marker_info_t) );
+        else{
+                opj_free(l_cstr_index->marker);
+                l_cstr_index->marker = NULL;
+        }
+
+        l_cstr_index->nb_of_tiles = p_j2k->cstr_index->nb_of_tiles;
+        l_cstr_index->tile_index = (opj_tile_index_t*)opj_calloc(l_cstr_index->nb_of_tiles, sizeof(opj_tile_index_t) );
+        if (!l_cstr_index->tile_index){
+                opj_free( l_cstr_index->marker);
+                opj_free( l_cstr_index);
+                return NULL;
+        }
+
+        if (!p_j2k->cstr_index->tile_index){
+                opj_free(l_cstr_index->tile_index);
+                l_cstr_index->tile_index = NULL;
+        }
+        else {
+                OPJ_UINT32 it_tile = 0;
+                for (it_tile = 0; it_tile < l_cstr_index->nb_of_tiles; it_tile++ ){
+
+                        /* Tile Marker*/
+                        l_cstr_index->tile_index[it_tile].marknum = p_j2k->cstr_index->tile_index[it_tile].marknum;
+
+                        l_cstr_index->tile_index[it_tile].marker =
+                                (opj_marker_info_t*)opj_malloc(l_cstr_index->tile_index[it_tile].marknum*sizeof(opj_marker_info_t));
+
+                        if (!l_cstr_index->tile_index[it_tile].marker) {
+                                OPJ_UINT32 it_tile_free;
+
+                                for (it_tile_free=0; it_tile_free < it_tile; it_tile_free++){
+                                        opj_free(l_cstr_index->tile_index[it_tile_free].marker);
+                                }
+
+                                opj_free( l_cstr_index->tile_index);
+                                opj_free( l_cstr_index->marker);
+                                opj_free( l_cstr_index);
+                                return NULL;
+                        }
+
+                        if (p_j2k->cstr_index->tile_index[it_tile].marker)
+                                memcpy( l_cstr_index->tile_index[it_tile].marker,
+                                                p_j2k->cstr_index->tile_index[it_tile].marker,
+                                                l_cstr_index->tile_index[it_tile].marknum * sizeof(opj_marker_info_t) );
+                        else{
+                                opj_free(l_cstr_index->tile_index[it_tile].marker);
+                                l_cstr_index->tile_index[it_tile].marker = NULL;
+                        }
+
+                        /* Tile part index*/
+                        l_cstr_index->tile_index[it_tile].nb_tps = p_j2k->cstr_index->tile_index[it_tile].nb_tps;
+
+                        l_cstr_index->tile_index[it_tile].tp_index =
+                                (opj_tp_index_t*)opj_malloc(l_cstr_index->tile_index[it_tile].nb_tps*sizeof(opj_tp_index_t));
+
+                        if(!l_cstr_index->tile_index[it_tile].tp_index){
+                                OPJ_UINT32 it_tile_free;
+
+                                for (it_tile_free=0; it_tile_free < it_tile; it_tile_free++){
+                                        opj_free(l_cstr_index->tile_index[it_tile_free].marker);
+                                        opj_free(l_cstr_index->tile_index[it_tile_free].tp_index);
+                                }
+
+                                opj_free( l_cstr_index->tile_index);
+                                opj_free( l_cstr_index->marker);
+                                opj_free( l_cstr_index);
+                                return NULL;
+                        }
+
+                        if (p_j2k->cstr_index->tile_index[it_tile].tp_index){
+                                memcpy( l_cstr_index->tile_index[it_tile].tp_index,
+                                                p_j2k->cstr_index->tile_index[it_tile].tp_index,
+                                                l_cstr_index->tile_index[it_tile].nb_tps * sizeof(opj_tp_index_t) );
+                        }
+                        else{
+                                opj_free(l_cstr_index->tile_index[it_tile].tp_index);
+                                l_cstr_index->tile_index[it_tile].tp_index = NULL;
+                        }
+
+                        /* Packet index (NOT USED)*/
+                        l_cstr_index->tile_index[it_tile].nb_packet = 0;
+                        l_cstr_index->tile_index[it_tile].packet_index = NULL;
+
+                }
+        }
+
+        return l_cstr_index;
+}
+
+OPJ_BOOL opj_j2k_allocate_tile_element_cstr_index(opj_j2k_t *p_j2k)
+{
+        OPJ_UINT32 it_tile=0;
+
+        p_j2k->cstr_index->nb_of_tiles = p_j2k->m_cp.tw * p_j2k->m_cp.th;
+        p_j2k->cstr_index->tile_index = (opj_tile_index_t*)opj_calloc(p_j2k->cstr_index->nb_of_tiles, sizeof(opj_tile_index_t));
+        if (!p_j2k->cstr_index->tile_index)
+                return OPJ_FALSE;
+
+        for (it_tile=0; it_tile < p_j2k->cstr_index->nb_of_tiles; it_tile++){
+                p_j2k->cstr_index->tile_index[it_tile].maxmarknum = 100;
+                p_j2k->cstr_index->tile_index[it_tile].marknum = 0;
+                p_j2k->cstr_index->tile_index[it_tile].marker = (opj_marker_info_t*)
+                                opj_calloc(p_j2k->cstr_index->tile_index[it_tile].maxmarknum, sizeof(opj_marker_info_t));
+                if (!p_j2k->cstr_index->tile_index[it_tile].marker)
+                        return OPJ_FALSE;
+        }
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_decode_tiles ( opj_j2k_t *p_j2k,
+                                                            opj_stream_private_t *p_stream,
+                                                            opj_event_mgr_t * p_manager)
+{
+        OPJ_BOOL l_go_on = OPJ_TRUE;
+        OPJ_UINT32 l_current_tile_no;
+        OPJ_UINT32 l_data_size,l_max_data_size;
+        OPJ_INT32 l_tile_x0,l_tile_y0,l_tile_x1,l_tile_y1;
+        OPJ_UINT32 l_nb_comps;
+        OPJ_BYTE * l_current_data;
+        OPJ_UINT32 nr_tiles = 0;
+
+        l_current_data = (OPJ_BYTE*)opj_malloc(1000);
+        if (! l_current_data) {
+                opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to decode tiles\n");
+                return OPJ_FALSE;
+        }
+        l_max_data_size = 1000;
+
+        while (OPJ_TRUE) {
+                if (! opj_j2k_read_tile_header( p_j2k,
+                                        &l_current_tile_no,
+                                        &l_data_size,
+                                        &l_tile_x0, &l_tile_y0,
+                                        &l_tile_x1, &l_tile_y1,
+                                        &l_nb_comps,
+                                        &l_go_on,
+                                        p_stream,
+                                        p_manager)) {
+                        opj_free(l_current_data);
+                        return OPJ_FALSE;
+                }
+
+                if (! l_go_on) {
+                        break;
+                }
+
+                if (l_data_size > l_max_data_size) {
+                        OPJ_BYTE *l_new_current_data = (OPJ_BYTE *) opj_realloc(l_current_data, l_data_size);
+                        if (! l_new_current_data) {
+                                opj_free(l_current_data);
+                                opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to decode tile %d/%d\n", l_current_tile_no +1, p_j2k->m_cp.th * p_j2k->m_cp.tw);
+                                return OPJ_FALSE;
+                        }
+                        l_current_data = l_new_current_data;
+                        l_max_data_size = l_data_size;
+                }
+
+                if (! opj_j2k_decode_tile(p_j2k,l_current_tile_no,l_current_data,l_data_size,p_stream,p_manager)) {
+                        opj_free(l_current_data);
+                        opj_event_msg(p_manager, EVT_ERROR, "Failed to decode tile %d/%d\n", l_current_tile_no +1, p_j2k->m_cp.th * p_j2k->m_cp.tw);
+                        return OPJ_FALSE;
+                }
+                opj_event_msg(p_manager, EVT_INFO, "Tile %d/%d has been decoded.\n", l_current_tile_no +1, p_j2k->m_cp.th * p_j2k->m_cp.tw);
+
+                if (! opj_j2k_update_image_data(p_j2k->m_tcd,l_current_data, p_j2k->m_output_image)) {
+                        opj_free(l_current_data);
+                        return OPJ_FALSE;
+                }
+                opj_event_msg(p_manager, EVT_INFO, "Image data has been updated with tile %d.\n\n", l_current_tile_no + 1);
+                
+                if(opj_stream_get_number_byte_left(p_stream) == 0  
+                    && p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_NEOC)
+                    break;
+                if(++nr_tiles ==  p_j2k->m_cp.th * p_j2k->m_cp.tw) 
+                    break;
+        }
+
+        opj_free(l_current_data);
+
+        return OPJ_TRUE;
+}
+
+/**
+ * Sets up the procedures to do on decoding data. Developpers wanting to extend the library can add their own reading procedures.
+ */
+static void opj_j2k_setup_decoding (opj_j2k_t *p_j2k)
+{
+        /* preconditions*/
+        assert(p_j2k != 00);
+
+        opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_decode_tiles);
+        /* DEVELOPER CORNER, add your custom procedures */
+
+}
+
+/*
+ * Read and decode one tile.
+ */
+static OPJ_BOOL opj_j2k_decode_one_tile (       opj_j2k_t *p_j2k,
+                                                                            opj_stream_private_t *p_stream,
+                                                                            opj_event_mgr_t * p_manager)
+{
+        OPJ_BOOL l_go_on = OPJ_TRUE;
+        OPJ_UINT32 l_current_tile_no;
+        OPJ_UINT32 l_tile_no_to_dec;
+        OPJ_UINT32 l_data_size,l_max_data_size;
+        OPJ_INT32 l_tile_x0,l_tile_y0,l_tile_x1,l_tile_y1;
+        OPJ_UINT32 l_nb_comps;
+        OPJ_BYTE * l_current_data;
+
+        l_current_data = (OPJ_BYTE*)opj_malloc(1000);
+        if (! l_current_data) {
+                opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to decode one tile\n");
+                return OPJ_FALSE;
+        }
+        l_max_data_size = 1000;
+
+        /*Allocate and initialize some elements of codestrem index if not already done*/
+        if( !p_j2k->cstr_index->tile_index)
+        {
+                if (!opj_j2k_allocate_tile_element_cstr_index(p_j2k)){
+                        opj_free(l_current_data);
+                        return OPJ_FALSE;
+                }
+        }
+        /* Move into the codestream to the first SOT used to decode the desired tile */
+        l_tile_no_to_dec = (OPJ_UINT32)p_j2k->m_specific_param.m_decoder.m_tile_ind_to_dec;
+        if (p_j2k->cstr_index->tile_index)
+                if(p_j2k->cstr_index->tile_index->tp_index)
+                {
+                        if ( ! p_j2k->cstr_index->tile_index[l_tile_no_to_dec].nb_tps) {
+                                /* the index for this tile has not been built,
+                                 *  so move to the last SOT read */
+                                if ( !(opj_stream_read_seek(p_stream, p_j2k->m_specific_param.m_decoder.m_last_sot_read_pos+2, p_manager)) ){
+                                        opj_event_msg(p_manager, EVT_ERROR, "Problem with seek function\n");
+                        opj_free(l_current_data);
+                                        return OPJ_FALSE;
+                                }
+                        }
+                        else{
+                                if ( !(opj_stream_read_seek(p_stream, p_j2k->cstr_index->tile_index[l_tile_no_to_dec].tp_index[0].start_pos+2, p_manager)) ) {
+                                        opj_event_msg(p_manager, EVT_ERROR, "Problem with seek function\n");
+                        opj_free(l_current_data);
+                                        return OPJ_FALSE;
+                                }
+                        }
+                        /* Special case if we have previously read the EOC marker (if the previous tile getted is the last ) */
+                        if(p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_EOC)
+                                p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_TPHSOT;
+                }
+
+        while (OPJ_TRUE) {
+                if (! opj_j2k_read_tile_header( p_j2k,
+                                        &l_current_tile_no,
+                                        &l_data_size,
+                                        &l_tile_x0, &l_tile_y0,
+                                        &l_tile_x1, &l_tile_y1,
+                                        &l_nb_comps,
+                                        &l_go_on,
+                                        p_stream,
+                                        p_manager)) {
+                        opj_free(l_current_data);
+                        return OPJ_FALSE;
+                }
+
+                if (! l_go_on) {
+                        break;
+                }
+
+                if (l_data_size > l_max_data_size) {
+                        OPJ_BYTE *l_new_current_data = (OPJ_BYTE *) opj_realloc(l_current_data, l_data_size);
+                        if (! l_new_current_data) {
+                                opj_free(l_current_data);
+                                l_current_data = NULL;
+                                /* TODO: LH: why tile numbering policy used in messages differs from
+                                   the one used in opj_j2k_decode_tiles() ? */
+                                opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to decode tile %d/%d\n", l_current_tile_no, (p_j2k->m_cp.th * p_j2k->m_cp.tw) - 1);
+                                return OPJ_FALSE;
+                        }
+                        l_current_data = l_new_current_data;
+                        l_max_data_size = l_data_size;
+                }
+
+                if (! opj_j2k_decode_tile(p_j2k,l_current_tile_no,l_current_data,l_data_size,p_stream,p_manager)) {
+                        opj_free(l_current_data);
+                        return OPJ_FALSE;
+                }
+                opj_event_msg(p_manager, EVT_INFO, "Tile %d/%d has been decoded.\n", l_current_tile_no, (p_j2k->m_cp.th * p_j2k->m_cp.tw) - 1);
+
+                if (! opj_j2k_update_image_data(p_j2k->m_tcd,l_current_data, p_j2k->m_output_image)) {
+                        opj_free(l_current_data);
+                        return OPJ_FALSE;
+                }
+                opj_event_msg(p_manager, EVT_INFO, "Image data has been updated with tile %d.\n\n", l_current_tile_no);
+
+                if(l_current_tile_no == l_tile_no_to_dec)
+                {
+                        /* move into the codestream to the the first SOT (FIXME or not move?)*/
+                        if (!(opj_stream_read_seek(p_stream, p_j2k->cstr_index->main_head_end + 2, p_manager) ) ) {
+                                opj_event_msg(p_manager, EVT_ERROR, "Problem with seek function\n");
+                                return OPJ_FALSE;
+                        }
+                        break;
+                }
+                else {
+                        opj_event_msg(p_manager, EVT_WARNING, "Tile read, decode and updated is not the desired (%d vs %d).\n", l_current_tile_no, l_tile_no_to_dec);
+                }
+
+        }
+
+        opj_free(l_current_data);
+
+        return OPJ_TRUE;
+}
+
+/**
+ * Sets up the procedures to do on decoding one tile. Developpers wanting to extend the library can add their own reading procedures.
+ */
+static void opj_j2k_setup_decoding_tile (opj_j2k_t *p_j2k)
+{
+        /* preconditions*/
+        assert(p_j2k != 00);
+
+        opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_decode_one_tile);
+        /* DEVELOPER CORNER, add your custom procedures */
+
+}
+
+OPJ_BOOL opj_j2k_decode(opj_j2k_t * p_j2k,
+                                                opj_stream_private_t * p_stream,
+                                                opj_image_t * p_image,
+                                                opj_event_mgr_t * p_manager)
+{
+        OPJ_UINT32 compno;
+
+        if (!p_image)
+                return OPJ_FALSE;
+
+        p_j2k->m_output_image = opj_image_create0();
+        if (! (p_j2k->m_output_image)) {
+                return OPJ_FALSE;
+        }
+        opj_copy_image_header(p_image, p_j2k->m_output_image);
+
+        /* customization of the decoding */
+        opj_j2k_setup_decoding(p_j2k);
+
+        /* Decode the codestream */
+        if (! opj_j2k_exec (p_j2k,p_j2k->m_procedure_list,p_stream,p_manager)) {
+                opj_image_destroy(p_j2k->m_private_image);
+                p_j2k->m_private_image = NULL;
+                return OPJ_FALSE;
+        }
+
+        /* Move data and copy one information from codec to output image*/
+        for (compno = 0; compno < p_image->numcomps; compno++) {
+                p_image->comps[compno].resno_decoded = p_j2k->m_output_image->comps[compno].resno_decoded;
+                p_image->comps[compno].data = p_j2k->m_output_image->comps[compno].data;
+#if 0
+                char fn[256];
+                sprintf( fn, "/tmp/%d.raw", compno );
+                FILE *debug = fopen( fn, "wb" );
+                fwrite( p_image->comps[compno].data, sizeof(OPJ_INT32), p_image->comps[compno].w * p_image->comps[compno].h, debug );
+                fclose( debug );
+#endif
+                p_j2k->m_output_image->comps[compno].data = NULL;
+        }
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_get_tile(      opj_j2k_t *p_j2k,
+                                                    opj_stream_private_t *p_stream,
+                                                    opj_image_t* p_image,
+                                                    opj_event_mgr_t * p_manager,
+                                                    OPJ_UINT32 tile_index )
+{
+        OPJ_UINT32 compno;
+        OPJ_UINT32 l_tile_x, l_tile_y;
+        opj_image_comp_t* l_img_comp;
+
+        if (!p_image) {
+                opj_event_msg(p_manager, EVT_ERROR, "We need an image previously created.\n");
+                return OPJ_FALSE;
+        }
+
+        if ( /*(tile_index < 0) &&*/ (tile_index >= p_j2k->m_cp.tw * p_j2k->m_cp.th) ){
+                opj_event_msg(p_manager, EVT_ERROR, "Tile index provided by the user is incorrect %d (max = %d) \n", tile_index, (p_j2k->m_cp.tw * p_j2k->m_cp.th) - 1);
+                return OPJ_FALSE;
+        }
+
+        /* Compute the dimension of the desired tile*/
+        l_tile_x = tile_index % p_j2k->m_cp.tw;
+        l_tile_y = tile_index / p_j2k->m_cp.tw;
+
+        p_image->x0 = l_tile_x * p_j2k->m_cp.tdx + p_j2k->m_cp.tx0;
+        if (p_image->x0 < p_j2k->m_private_image->x0)
+                p_image->x0 = p_j2k->m_private_image->x0;
+        p_image->x1 = (l_tile_x + 1) * p_j2k->m_cp.tdx + p_j2k->m_cp.tx0;
+        if (p_image->x1 > p_j2k->m_private_image->x1)
+                p_image->x1 = p_j2k->m_private_image->x1;
+
+        p_image->y0 = l_tile_y * p_j2k->m_cp.tdy + p_j2k->m_cp.ty0;
+        if (p_image->y0 < p_j2k->m_private_image->y0)
+                p_image->y0 = p_j2k->m_private_image->y0;
+        p_image->y1 = (l_tile_y + 1) * p_j2k->m_cp.tdy + p_j2k->m_cp.ty0;
+        if (p_image->y1 > p_j2k->m_private_image->y1)
+                p_image->y1 = p_j2k->m_private_image->y1;
+
+        l_img_comp = p_image->comps;
+        for (compno=0; compno < p_image->numcomps; ++compno)
+        {
+                OPJ_INT32 l_comp_x1, l_comp_y1;
+
+                l_img_comp->factor = p_j2k->m_private_image->comps[compno].factor;
+
+                l_img_comp->x0 = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)p_image->x0, (OPJ_INT32)l_img_comp->dx);
+                l_img_comp->y0 = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)p_image->y0, (OPJ_INT32)l_img_comp->dy);
+                l_comp_x1 = opj_int_ceildiv((OPJ_INT32)p_image->x1, (OPJ_INT32)l_img_comp->dx);
+                l_comp_y1 = opj_int_ceildiv((OPJ_INT32)p_image->y1, (OPJ_INT32)l_img_comp->dy);
+
+                l_img_comp->w = (OPJ_UINT32)(opj_int_ceildivpow2(l_comp_x1, (OPJ_INT32)l_img_comp->factor) - opj_int_ceildivpow2((OPJ_INT32)l_img_comp->x0, (OPJ_INT32)l_img_comp->factor));
+                l_img_comp->h = (OPJ_UINT32)(opj_int_ceildivpow2(l_comp_y1, (OPJ_INT32)l_img_comp->factor) - opj_int_ceildivpow2((OPJ_INT32)l_img_comp->y0, (OPJ_INT32)l_img_comp->factor));
+
+                l_img_comp++;
+        }
+
+        /* Destroy the previous output image*/
+        if (p_j2k->m_output_image)
+                opj_image_destroy(p_j2k->m_output_image);
+
+        /* Create the ouput image from the information previously computed*/
+        p_j2k->m_output_image = opj_image_create0();
+        if (! (p_j2k->m_output_image)) {
+                return OPJ_FALSE;
+        }
+        opj_copy_image_header(p_image, p_j2k->m_output_image);
+
+        p_j2k->m_specific_param.m_decoder.m_tile_ind_to_dec = (OPJ_INT32)tile_index;
+
+        /* customization of the decoding */
+        opj_j2k_setup_decoding_tile(p_j2k);
+
+        /* Decode the codestream */
+        if (! opj_j2k_exec (p_j2k,p_j2k->m_procedure_list,p_stream,p_manager)) {
+                opj_image_destroy(p_j2k->m_private_image);
+                p_j2k->m_private_image = NULL;
+                return OPJ_FALSE;
+        }
+
+        /* Move data and copy one information from codec to output image*/
+        for (compno = 0; compno < p_image->numcomps; compno++) {
+                p_image->comps[compno].resno_decoded = p_j2k->m_output_image->comps[compno].resno_decoded;
+
+                if (p_image->comps[compno].data)
+                        opj_free(p_image->comps[compno].data);
+
+                p_image->comps[compno].data = p_j2k->m_output_image->comps[compno].data;
+
+                p_j2k->m_output_image->comps[compno].data = NULL;
+        }
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_set_decoded_resolution_factor(opj_j2k_t *p_j2k,
+                                               OPJ_UINT32 res_factor,
+                                               opj_event_mgr_t * p_manager)
+{
+        OPJ_UINT32 it_comp;
+
+        p_j2k->m_cp.m_specific_param.m_dec.m_reduce = res_factor;
+
+        if (p_j2k->m_private_image) {
+                if (p_j2k->m_private_image->comps) {
+                        if (p_j2k->m_specific_param.m_decoder.m_default_tcp) {
+                                if (p_j2k->m_specific_param.m_decoder.m_default_tcp->tccps) {
+                                        for (it_comp = 0 ; it_comp < p_j2k->m_private_image->numcomps; it_comp++) {
+                                                OPJ_UINT32 max_res = p_j2k->m_specific_param.m_decoder.m_default_tcp->tccps[it_comp].numresolutions;
+                                                if ( res_factor >= max_res){
+                                                        opj_event_msg(p_manager, EVT_ERROR, "Resolution factor is greater than the maximum resolution in the component.\n");
+                                                        return OPJ_FALSE;
+                                                }
+                                                p_j2k->m_private_image->comps[it_comp].factor = res_factor;
+                                        }
+                                        return OPJ_TRUE;
+                                }
+                        }
+                }
+        }
+
+        return OPJ_FALSE;
+}
+
+OPJ_BOOL opj_j2k_encode(opj_j2k_t * p_j2k,
+                        opj_stream_private_t *p_stream,
+                        opj_event_mgr_t * p_manager )
+{
+        OPJ_UINT32 i;
+        OPJ_UINT32 l_nb_tiles;
+        OPJ_UINT32 l_max_tile_size, l_current_tile_size;
+        OPJ_BYTE * l_current_data;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_stream != 00);
+        assert(p_manager != 00);
+
+        l_current_data = (OPJ_BYTE*)opj_malloc(1000);
+        if (! l_current_data) {
+                opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to encode all tiles\n");
+                return OPJ_FALSE;
+        }
+        l_max_tile_size = 1000;
+
+        l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw;
+        for (i=0;i<l_nb_tiles;++i) {
+                if (! opj_j2k_pre_write_tile(p_j2k,i,p_stream,p_manager)) {
+                        opj_free(l_current_data);
+                        return OPJ_FALSE;
+                }
+
+                l_current_tile_size = opj_tcd_get_encoded_tile_size(p_j2k->m_tcd);
+                if (l_current_tile_size > l_max_tile_size) {
+                        OPJ_BYTE *l_new_current_data = (OPJ_BYTE *) opj_realloc(l_current_data, l_current_tile_size);
+                        if (! l_new_current_data) {
+                                opj_free(l_current_data);
+                                opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to encode all tiles\n");
+                                return OPJ_FALSE;
+                        }
+                        l_current_data = l_new_current_data;
+                        l_max_tile_size = l_current_tile_size;
+                }
+
+                opj_j2k_get_tile_data(p_j2k->m_tcd,l_current_data);
+
+                if (! opj_j2k_post_write_tile (p_j2k,l_current_data,l_current_tile_size,p_stream,p_manager)) {
+                        return OPJ_FALSE;
+                }
+        }
+
+        opj_free(l_current_data);
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_end_compress(  opj_j2k_t *p_j2k,
+                                                        opj_stream_private_t *p_stream,
+                                                        opj_event_mgr_t * p_manager)
+{
+        /* customization of the encoding */
+        opj_j2k_setup_end_compress(p_j2k);
+
+        if (! opj_j2k_exec (p_j2k, p_j2k->m_procedure_list, p_stream, p_manager))
+        {
+                return OPJ_FALSE;
+        }
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_start_compress(opj_j2k_t *p_j2k,
+                                                            opj_stream_private_t *p_stream,
+                                                            opj_image_t * p_image,
+                                                            opj_event_mgr_t * p_manager)
+{
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_stream != 00);
+        assert(p_manager != 00);
+
+        p_j2k->m_private_image = opj_image_create0();
+        opj_copy_image_header(p_image, p_j2k->m_private_image);
+
+        /* TODO_MSD: Find a better way */
+        if (p_image->comps) {
+                OPJ_UINT32 it_comp;
+                for (it_comp = 0 ; it_comp < p_image->numcomps; it_comp++) {
+                        if (p_image->comps[it_comp].data) {
+                                p_j2k->m_private_image->comps[it_comp].data =p_image->comps[it_comp].data;
+                                p_image->comps[it_comp].data = NULL;
+
+                        }
+                }
+        }
+
+        /* customization of the validation */
+        opj_j2k_setup_encoding_validation (p_j2k);
+
+        /* validation of the parameters codec */
+        if (! opj_j2k_exec(p_j2k,p_j2k->m_validation_list,p_stream,p_manager)) {
+                return OPJ_FALSE;
+        }
+
+        /* customization of the encoding */
+        opj_j2k_setup_header_writing(p_j2k);
+
+        /* write header */
+        if (! opj_j2k_exec (p_j2k,p_j2k->m_procedure_list,p_stream,p_manager)) {
+                return OPJ_FALSE;
+        }
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_pre_write_tile (       opj_j2k_t * p_j2k,
+                                                                OPJ_UINT32 p_tile_index,
+                                                                opj_stream_private_t *p_stream,
+                                                                opj_event_mgr_t * p_manager )
+{
+  (void)p_stream;
+        if (p_tile_index != p_j2k->m_current_tile_number) {
+                opj_event_msg(p_manager, EVT_ERROR, "The given tile index does not match." );
+                return OPJ_FALSE;
+        }
+
+        opj_event_msg(p_manager, EVT_INFO, "tile number %d / %d\n", p_j2k->m_current_tile_number + 1, p_j2k->m_cp.tw * p_j2k->m_cp.th);
+
+        p_j2k->m_specific_param.m_encoder.m_current_tile_part_number = 0;
+        p_j2k->m_tcd->cur_totnum_tp = p_j2k->m_cp.tcps[p_tile_index].m_nb_tile_parts;
+        p_j2k->m_specific_param.m_encoder.m_current_poc_tile_part_number = 0;
+
+        /* initialisation before tile encoding  */
+        if (! opj_tcd_init_encode_tile(p_j2k->m_tcd, p_j2k->m_current_tile_number)) {
+                return OPJ_FALSE;
+        }
+
+        return OPJ_TRUE;
+}
+
+void opj_j2k_get_tile_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data)
+{
+        OPJ_UINT32 i,j,k = 0;
+        OPJ_UINT32 l_width,l_height,l_stride, l_offset_x,l_offset_y, l_image_width;
+        opj_image_comp_t * l_img_comp = 00;
+        opj_tcd_tilecomp_t * l_tilec = 00;
+        opj_image_t * l_image = 00;
+        OPJ_UINT32 l_size_comp, l_remaining;
+        OPJ_INT32 * l_src_ptr;
+        l_tilec = p_tcd->tcd_image->tiles->comps;
+        l_image = p_tcd->image;
+        l_img_comp = l_image->comps;
+
+        for (i=0;i<p_tcd->image->numcomps;++i) {
+                l_size_comp = l_img_comp->prec >> 3; /* (/8) */
+                l_remaining = l_img_comp->prec & 7;  /* (%8) */
+                if (l_remaining) {
+                        ++l_size_comp;
+                }
+
+                if (l_size_comp == 3) {
+                        l_size_comp = 4;
+                }
+
+                l_width  = (OPJ_UINT32)(l_tilec->x1 - l_tilec->x0);
+                l_height = (OPJ_UINT32)(l_tilec->y1 - l_tilec->y0);
+                l_offset_x = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)l_image->x0, (OPJ_INT32)l_img_comp->dx);
+                l_offset_y = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)l_image->y0, (OPJ_INT32)l_img_comp->dy);
+                l_image_width = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)l_image->x1 - (OPJ_INT32)l_image->x0, (OPJ_INT32)l_img_comp->dx);
+                l_stride = l_image_width - l_width;
+                l_src_ptr = l_img_comp->data + ((OPJ_UINT32)l_tilec->x0 - l_offset_x) + ((OPJ_UINT32)l_tilec->y0 - l_offset_y) * l_image_width;
+
+                switch (l_size_comp) {
+                        case 1:
+                                {
+                                        OPJ_CHAR * l_dest_ptr = (OPJ_CHAR*) p_data;
+                                        if (l_img_comp->sgnd) {
+                                                for     (j=0;j<l_height;++j) {
+                                                        for (k=0;k<l_width;++k) {
+                                                                *(l_dest_ptr) = (OPJ_CHAR) (*l_src_ptr);
+                                                                ++l_dest_ptr;
+                                                                ++l_src_ptr;
+                                                        }
+                                                        l_src_ptr += l_stride;
+                                                }
+                                        }
+                                        else {
+                                                for (j=0;j<l_height;++j) {
+                                                        for (k=0;k<l_width;++k) {
+                                                                *(l_dest_ptr) = (OPJ_CHAR)((*l_src_ptr)&0xff);
+                                                                ++l_dest_ptr;
+                                                                ++l_src_ptr;
+                                                        }
+                                                        l_src_ptr += l_stride;
+                                                }
+                                        }
+
+                                        p_data = (OPJ_BYTE*) l_dest_ptr;
+                                }
+                                break;
+                        case 2:
+                                {
+                                        OPJ_INT16 * l_dest_ptr = (OPJ_INT16 *) p_data;
+                                        if (l_img_comp->sgnd) {
+                                                for (j=0;j<l_height;++j) {
+                                                        for (k=0;k<l_width;++k) {
+                                                                *(l_dest_ptr++) = (OPJ_INT16) (*(l_src_ptr++));
+                                                        }
+                                                        l_src_ptr += l_stride;
+                                                }
+                                        }
+                                        else {
+                                                for (j=0;j<l_height;++j) {
+                                                        for (k=0;k<l_width;++k) {
+                                                                *(l_dest_ptr++) = (OPJ_INT16)((*(l_src_ptr++)) & 0xffff);
+                                                        }
+                                                        l_src_ptr += l_stride;
+                                                }
+                                        }
+
+                                        p_data = (OPJ_BYTE*) l_dest_ptr;
+                                }
+                                break;
+                        case 4:
+                                {
+                                        OPJ_INT32 * l_dest_ptr = (OPJ_INT32 *) p_data;
+                                        for (j=0;j<l_height;++j) {
+                                                for (k=0;k<l_width;++k) {
+                                                        *(l_dest_ptr++) = *(l_src_ptr++);
+                                                }
+                                                l_src_ptr += l_stride;
+                                        }
+
+                                        p_data = (OPJ_BYTE*) l_dest_ptr;
+                                }
+                                break;
+                }
+
+                ++l_img_comp;
+                ++l_tilec;
+        }
+}
+
+OPJ_BOOL opj_j2k_post_write_tile (      opj_j2k_t * p_j2k,
+                                                                OPJ_BYTE * p_data,
+                                                                OPJ_UINT32 p_data_size,
+                                                                opj_stream_private_t *p_stream,
+                                                                opj_event_mgr_t * p_manager )
+{
+        opj_tcd_t * l_tcd = 00;
+        OPJ_UINT32 l_nb_bytes_written;
+        OPJ_BYTE * l_current_data = 00;
+        OPJ_UINT32 l_tile_size = 0;
+        OPJ_UINT32 l_available_data;
+
+        /* preconditions */
+        assert(p_j2k->m_specific_param.m_encoder.m_encoded_tile_data);
+
+        l_tcd = p_j2k->m_tcd;
+        
+        l_tile_size = p_j2k->m_specific_param.m_encoder.m_encoded_tile_size;
+        l_available_data = l_tile_size;
+        l_current_data = p_j2k->m_specific_param.m_encoder.m_encoded_tile_data;
+
+        if (! opj_tcd_copy_tile_data(l_tcd,p_data,p_data_size)) {
+                opj_event_msg(p_manager, EVT_ERROR, "Size mismatch between tile data and sent data." );
+                return OPJ_FALSE;
+        }
+
+        l_nb_bytes_written = 0;
+        if (! opj_j2k_write_first_tile_part(p_j2k,l_current_data,&l_nb_bytes_written,l_available_data,p_stream,p_manager)) {
+                return OPJ_FALSE;
+        }
+        l_current_data += l_nb_bytes_written;
+        l_available_data -= l_nb_bytes_written;
+
+        l_nb_bytes_written = 0;
+        if (! opj_j2k_write_all_tile_parts(p_j2k,l_current_data,&l_nb_bytes_written,l_available_data,p_stream,p_manager)) {
+                return OPJ_FALSE;
+        }
+
+        l_available_data -= l_nb_bytes_written;
+        l_nb_bytes_written = l_tile_size - l_available_data;
+
+        if ( opj_stream_write_data(     p_stream,
+                                                                p_j2k->m_specific_param.m_encoder.m_encoded_tile_data,
+                                                                l_nb_bytes_written,p_manager) != l_nb_bytes_written) {
+                return OPJ_FALSE;
+        }
+
+        ++p_j2k->m_current_tile_number;
+
+        return OPJ_TRUE;
+}
+
+void opj_j2k_setup_end_compress (opj_j2k_t *p_j2k)
+{
+        /* preconditions */
+        assert(p_j2k != 00);
+
+        /* DEVELOPER CORNER, insert your custom procedures */
+        opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_eoc );
+
+        if (p_j2k->m_cp.m_specific_param.m_enc.m_cinema) {
+                opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_updated_tlm);
+        }
+
+        opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_epc );
+        opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_end_encoding );
+        opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_destroy_header_memory);
+}
+
+void opj_j2k_setup_encoding_validation (opj_j2k_t *p_j2k)
+{
+        /* preconditions */
+        assert(p_j2k != 00);
+
+        opj_procedure_list_add_procedure(p_j2k->m_validation_list, (opj_procedure)opj_j2k_build_encoder);
+        opj_procedure_list_add_procedure(p_j2k->m_validation_list, (opj_procedure)opj_j2k_encoding_validation);
+
+        /* DEVELOPER CORNER, add your custom validation procedure */
+        opj_procedure_list_add_procedure(p_j2k->m_validation_list, (opj_procedure)opj_j2k_mct_validation);
+}
+
+void opj_j2k_setup_header_writing (opj_j2k_t *p_j2k)
+{
+        /* preconditions */
+        assert(p_j2k != 00);
+
+        opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_init_info );
+        opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_soc );
+        opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_siz );
+        opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_cod );
+        opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_qcd );
+
+        if (p_j2k->m_cp.m_specific_param.m_enc.m_cinema) {
+                /* No need for COC or QCC, QCD and COD are used
+                opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_all_coc );
+                opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_all_qcc );
+                */
+                opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_tlm );
+
+                if (p_j2k->m_cp.m_specific_param.m_enc.m_cinema == OPJ_CINEMA4K_24) {
+                        opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_poc );
+                }
+        }
+
+        opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_regions);
+
+        if (p_j2k->m_cp.comment != 00)  {
+                opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_com);
+        }
+
+        /* DEVELOPER CORNER, insert your custom procedures */
+        if (p_j2k->m_cp.rsiz & OPJ_MCT) {
+                opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_mct_data_group );
+        }
+        /* End of Developer Corner */
+
+        if (p_j2k->cstr_index) {
+                opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_get_end_header );
+        }
+
+        opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_create_tcd);
+        opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_update_rates);
+}
+
+OPJ_BOOL opj_j2k_write_first_tile_part (opj_j2k_t *p_j2k,
+                                                                        OPJ_BYTE * p_data,
+                                                                        OPJ_UINT32 * p_data_written,
+                                                                        OPJ_UINT32 p_total_data_size,
+                                                                        opj_stream_private_t *p_stream,
+                                                                        struct opj_event_mgr * p_manager )
+{
+        OPJ_UINT32 l_nb_bytes_written = 0;
+        OPJ_UINT32 l_current_nb_bytes_written;
+        OPJ_BYTE * l_begin_data = 00;
+
+        opj_tcd_t * l_tcd = 00;
+        opj_cp_t * l_cp = 00;
+
+        l_tcd = p_j2k->m_tcd;
+        l_cp = &(p_j2k->m_cp);
+
+        l_tcd->cur_pino = 0;
+
+        /*Get number of tile parts*/
+        p_j2k->m_specific_param.m_encoder.m_current_poc_tile_part_number = 0;
+
+        /* INDEX >> */
+        /* << INDEX */
+
+        l_current_nb_bytes_written = 0;
+        l_begin_data = p_data;
+        if (! opj_j2k_write_sot(p_j2k,p_data,&l_current_nb_bytes_written,p_stream,p_manager))
+        {
+                return OPJ_FALSE;
+        }
+
+        l_nb_bytes_written += l_current_nb_bytes_written;
+        p_data += l_current_nb_bytes_written;
+        p_total_data_size -= l_current_nb_bytes_written;
+
+        if (l_cp->m_specific_param.m_enc.m_cinema == 0) {
+#if 0
+                for (compno = 1; compno < p_j2k->m_private_image->numcomps; compno++) {
+                        l_current_nb_bytes_written = 0;
+                        opj_j2k_write_coc_in_memory(p_j2k,compno,p_data,&l_current_nb_bytes_written,p_manager);
+                        l_nb_bytes_written += l_current_nb_bytes_written;
+                        p_data += l_current_nb_bytes_written;
+                        p_total_data_size -= l_current_nb_bytes_written;
+
+                        l_current_nb_bytes_written = 0;
+                        opj_j2k_write_qcc_in_memory(p_j2k,compno,p_data,&l_current_nb_bytes_written,p_manager);
+                        l_nb_bytes_written += l_current_nb_bytes_written;
+                        p_data += l_current_nb_bytes_written;
+                        p_total_data_size -= l_current_nb_bytes_written;
+                }
+#endif
+
+                if (l_cp->tcps[p_j2k->m_current_tile_number].numpocs) {
+                        l_current_nb_bytes_written = 0;
+                        opj_j2k_write_poc_in_memory(p_j2k,p_data,&l_current_nb_bytes_written,p_manager);
+                        l_nb_bytes_written += l_current_nb_bytes_written;
+                        p_data += l_current_nb_bytes_written;
+                        p_total_data_size -= l_current_nb_bytes_written;
+                }
+        }
+
+        l_current_nb_bytes_written = 0;
+        if (! opj_j2k_write_sod(p_j2k,l_tcd,p_data,&l_current_nb_bytes_written,p_total_data_size,p_stream,p_manager)) {
+                return OPJ_FALSE;
+        }
+
+        l_nb_bytes_written += l_current_nb_bytes_written;
+        * p_data_written = l_nb_bytes_written;
+
+        /* Writing Psot in SOT marker */
+        opj_write_bytes(l_begin_data + 6,l_nb_bytes_written,4);                                 /* PSOT */
+
+        if (l_cp->m_specific_param.m_enc.m_cinema){
+                opj_j2k_update_tlm(p_j2k,l_nb_bytes_written);
+        }
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_write_all_tile_parts(  opj_j2k_t *p_j2k,
+                                                                        OPJ_BYTE * p_data,
+                                                                        OPJ_UINT32 * p_data_written,
+                                                                        OPJ_UINT32 p_total_data_size,
+                                                                        opj_stream_private_t *p_stream,
+                                                                        struct opj_event_mgr * p_manager
+                                                                )
+{
+        OPJ_UINT32 tilepartno=0;
+        OPJ_UINT32 l_nb_bytes_written = 0;
+        OPJ_UINT32 l_current_nb_bytes_written;
+        OPJ_UINT32 l_part_tile_size;
+        OPJ_UINT32 tot_num_tp;
+        OPJ_UINT32 pino;
+
+        OPJ_BYTE * l_begin_data;
+        opj_tcp_t *l_tcp = 00;
+        opj_tcd_t * l_tcd = 00;
+        opj_cp_t * l_cp = 00;
+
+        l_tcd = p_j2k->m_tcd;
+        l_cp = &(p_j2k->m_cp);
+        l_tcp = l_cp->tcps + p_j2k->m_current_tile_number;
+
+        /*Get number of tile parts*/
+        tot_num_tp = opj_j2k_get_num_tp(l_cp,0,p_j2k->m_current_tile_number);
+
+        /* start writing remaining tile parts */
+        ++p_j2k->m_specific_param.m_encoder.m_current_tile_part_number;
+        for (tilepartno = 1; tilepartno < tot_num_tp ; ++tilepartno) {
+                p_j2k->m_specific_param.m_encoder.m_current_poc_tile_part_number = tilepartno;
+                l_current_nb_bytes_written = 0;
+                l_part_tile_size = 0;
+                l_begin_data = p_data;
+
+                if (! opj_j2k_write_sot(p_j2k,p_data,&l_current_nb_bytes_written,p_stream,p_manager)) {
+                        return OPJ_FALSE;
+                }
+
+                l_nb_bytes_written += l_current_nb_bytes_written;
+                p_data += l_current_nb_bytes_written;
+                p_total_data_size -= l_current_nb_bytes_written;
+                l_part_tile_size += l_current_nb_bytes_written;
+
+                l_current_nb_bytes_written = 0;
+                if (! opj_j2k_write_sod(p_j2k,l_tcd,p_data,&l_current_nb_bytes_written,p_total_data_size,p_stream,p_manager)) {
+                        return OPJ_FALSE;
+                }
+
+                p_data += l_current_nb_bytes_written;
+                l_nb_bytes_written += l_current_nb_bytes_written;
+                p_total_data_size -= l_current_nb_bytes_written;
+                l_part_tile_size += l_current_nb_bytes_written;
+
+                /* Writing Psot in SOT marker */
+                opj_write_bytes(l_begin_data + 6,l_part_tile_size,4);                                   /* PSOT */
+
+                if (l_cp->m_specific_param.m_enc.m_cinema) {
+                        opj_j2k_update_tlm(p_j2k,l_part_tile_size);
+                }
+
+                ++p_j2k->m_specific_param.m_encoder.m_current_tile_part_number;
+        }
+
+        for (pino = 1; pino <= l_tcp->numpocs; ++pino) {
+                l_tcd->cur_pino = pino;
+
+                /*Get number of tile parts*/
+                tot_num_tp = opj_j2k_get_num_tp(l_cp,pino,p_j2k->m_current_tile_number);
+                for (tilepartno = 0; tilepartno < tot_num_tp ; ++tilepartno) {
+                        p_j2k->m_specific_param.m_encoder.m_current_poc_tile_part_number = tilepartno;
+                        l_current_nb_bytes_written = 0;
+                        l_part_tile_size = 0;
+                        l_begin_data = p_data;
+
+                        if (! opj_j2k_write_sot(p_j2k,p_data,&l_current_nb_bytes_written,p_stream,p_manager)) {
+                                return OPJ_FALSE;
+                        }
+
+                        l_nb_bytes_written += l_current_nb_bytes_written;
+                        p_data += l_current_nb_bytes_written;
+                        p_total_data_size -= l_current_nb_bytes_written;
+                        l_part_tile_size += l_current_nb_bytes_written;
+
+                        l_current_nb_bytes_written = 0;
+
+                        if (! opj_j2k_write_sod(p_j2k,l_tcd,p_data,&l_current_nb_bytes_written,p_total_data_size,p_stream,p_manager)) {
+                                return OPJ_FALSE;
+                        }
+
+                        l_nb_bytes_written += l_current_nb_bytes_written;
+                        p_data += l_current_nb_bytes_written;
+                        p_total_data_size -= l_current_nb_bytes_written;
+                        l_part_tile_size += l_current_nb_bytes_written;
+
+                        /* Writing Psot in SOT marker */
+                        opj_write_bytes(l_begin_data + 6,l_part_tile_size,4);                                   /* PSOT */
+
+                        if (l_cp->m_specific_param.m_enc.m_cinema) {
+                                opj_j2k_update_tlm(p_j2k,l_part_tile_size);
+                        }
+
+                        ++p_j2k->m_specific_param.m_encoder.m_current_tile_part_number;
+                }
+        }
+
+        *p_data_written = l_nb_bytes_written;
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_write_updated_tlm( opj_j2k_t *p_j2k,
+                                                                    struct opj_stream_private *p_stream,
+                                                                    struct opj_event_mgr * p_manager )
+{
+        OPJ_UINT32 l_tlm_size;
+        OPJ_OFF_T l_tlm_position, l_current_position;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+        assert(p_stream != 00);
+
+        l_tlm_size = 5 * p_j2k->m_specific_param.m_encoder.m_total_tile_parts;
+        l_tlm_position = 6 + p_j2k->m_specific_param.m_encoder.m_tlm_start;
+        l_current_position = opj_stream_tell(p_stream);
+
+        if (! opj_stream_seek(p_stream,l_tlm_position,p_manager)) {
+                return OPJ_FALSE;
+        }
+
+        if (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer,l_tlm_size,p_manager) != l_tlm_size) {
+                return OPJ_FALSE;
+        }
+
+        if (! opj_stream_seek(p_stream,l_current_position,p_manager)) {
+                return OPJ_FALSE;
+        }
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_end_encoding(  opj_j2k_t *p_j2k,
+                                                        struct opj_stream_private *p_stream,
+                                                        struct opj_event_mgr * p_manager )
+{
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+        assert(p_stream != 00);
+
+        opj_tcd_destroy(p_j2k->m_tcd);
+        p_j2k->m_tcd = 00;
+
+        if (p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer) {
+                opj_free(p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer);
+                p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer = 0;
+                p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current = 0;
+        }
+
+        if (p_j2k->m_specific_param.m_encoder.m_encoded_tile_data) {
+                opj_free(p_j2k->m_specific_param.m_encoder.m_encoded_tile_data);
+                p_j2k->m_specific_param.m_encoder.m_encoded_tile_data = 0;
+        }
+
+        p_j2k->m_specific_param.m_encoder.m_encoded_tile_size = 0;
+
+        return OPJ_TRUE;
+}
+
+/**
+ * Destroys the memory associated with the decoding of headers.
+ */
+static OPJ_BOOL opj_j2k_destroy_header_memory ( opj_j2k_t * p_j2k,
+                                                opj_stream_private_t *p_stream,
+                                                opj_event_mgr_t * p_manager
+                                                )
+{
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_stream != 00);
+        assert(p_manager != 00);
+
+        if (p_j2k->m_specific_param.m_encoder.m_header_tile_data) {
+                opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data);
+                p_j2k->m_specific_param.m_encoder.m_header_tile_data = 0;
+        }
+
+        p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0;
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_init_info(     opj_j2k_t *p_j2k,
+                                                struct opj_stream_private *p_stream,
+                                                struct opj_event_mgr * p_manager )
+{
+        opj_codestream_info_t * l_cstr_info = 00;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+        assert(p_stream != 00);
+  (void)l_cstr_info;
+
+        /* TODO mergeV2: check this part which use cstr_info */
+        /*l_cstr_info = p_j2k->cstr_info;
+
+        if (l_cstr_info)  {
+                OPJ_UINT32 compno;
+                l_cstr_info->tile = (opj_tile_info_t *) opj_malloc(p_j2k->m_cp.tw * p_j2k->m_cp.th * sizeof(opj_tile_info_t));
+
+                l_cstr_info->image_w = p_j2k->m_image->x1 - p_j2k->m_image->x0;
+                l_cstr_info->image_h = p_j2k->m_image->y1 - p_j2k->m_image->y0;
+
+                l_cstr_info->prog = (&p_j2k->m_cp.tcps[0])->prg;
+
+                l_cstr_info->tw = p_j2k->m_cp.tw;
+                l_cstr_info->th = p_j2k->m_cp.th;
+
+                l_cstr_info->tile_x = p_j2k->m_cp.tdx;*/        /* new version parser */
+                /*l_cstr_info->tile_y = p_j2k->m_cp.tdy;*/      /* new version parser */
+                /*l_cstr_info->tile_Ox = p_j2k->m_cp.tx0;*/     /* new version parser */
+                /*l_cstr_info->tile_Oy = p_j2k->m_cp.ty0;*/     /* new version parser */
+
+                /*l_cstr_info->numcomps = p_j2k->m_image->numcomps;
+
+                l_cstr_info->numlayers = (&p_j2k->m_cp.tcps[0])->numlayers;
+
+                l_cstr_info->numdecompos = (OPJ_INT32*) opj_malloc(p_j2k->m_image->numcomps * sizeof(OPJ_INT32));
+
+                for (compno=0; compno < p_j2k->m_image->numcomps; compno++) {
+                        l_cstr_info->numdecompos[compno] = (&p_j2k->m_cp.tcps[0])->tccps->numresolutions - 1;
+                }
+
+                l_cstr_info->D_max = 0.0;       */      /* ADD Marcela */
+
+                /*l_cstr_info->main_head_start = opj_stream_tell(p_stream);*/ /* position of SOC */
+
+                /*l_cstr_info->maxmarknum = 100;
+                l_cstr_info->marker = (opj_marker_info_t *) opj_malloc(l_cstr_info->maxmarknum * sizeof(opj_marker_info_t));
+                l_cstr_info->marknum = 0;
+        }*/
+
+        return opj_j2k_calculate_tp(p_j2k,&(p_j2k->m_cp),&p_j2k->m_specific_param.m_encoder.m_total_tile_parts,p_j2k->m_private_image,p_manager);
+}
+
+/**
+ * Creates a tile-coder decoder.
+ *
+ * @param       p_stream                the stream to write data to.
+ * @param       p_j2k                   J2K codec.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_create_tcd(     opj_j2k_t *p_j2k,
+                                                                    opj_stream_private_t *p_stream,
+                                                                    opj_event_mgr_t * p_manager
+                                    )
+{
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+        assert(p_stream != 00);
+
+        p_j2k->m_tcd = opj_tcd_create(OPJ_FALSE);
+
+        if (! p_j2k->m_tcd) {
+                opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to create Tile Coder\n");
+                return OPJ_FALSE;
+        }
+
+        if (!opj_tcd_init(p_j2k->m_tcd,p_j2k->m_private_image,&p_j2k->m_cp)) {
+                opj_tcd_destroy(p_j2k->m_tcd);
+                p_j2k->m_tcd = 00;
+                return OPJ_FALSE;
+        }
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_write_tile (opj_j2k_t * p_j2k,
+                                                 OPJ_UINT32 p_tile_index,
+                                                 OPJ_BYTE * p_data,
+                                                 OPJ_UINT32 p_data_size,
+                                                 opj_stream_private_t *p_stream,
+                                                 opj_event_mgr_t * p_manager )
+{
+        if (! opj_j2k_pre_write_tile(p_j2k,p_tile_index,p_stream,p_manager)) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error while opj_j2k_pre_write_tile with tile index = %d\n", p_tile_index);
+                return OPJ_FALSE;
+        }
+        else {
+                if (! opj_j2k_post_write_tile(p_j2k,p_data,p_data_size,p_stream,p_manager)) {
+                        opj_event_msg(p_manager, EVT_ERROR, "Error while opj_j2k_post_write_tile with tile index = %d\n", p_tile_index);
+                        return OPJ_FALSE;
+                }
+        }
+
+        return OPJ_TRUE;
+}
diff --git a/Source/LibOpenJPEG/j2k.h b/Source/LibOpenJPEG/j2k.h
index 00be481..22d3876 100644
--- a/Source/LibOpenJPEG/j2k.h
+++ b/Source/LibOpenJPEG/j2k.h
@@ -1,446 +1,838 @@
-/*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
- * Copyright (c) 2001-2003, David Janssens
- * Copyright (c) 2002-2003, Yannick Verschueren
- * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * Copyright (c) 2006-2007, Parvatha Elangovan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef __J2K_H
-#define __J2K_H
-/**
- at file j2k.h
- at brief The JPEG-2000 Codestream Reader/Writer (J2K)
-
-The functions in J2K.C have for goal to read/write the several parts of the codestream: markers and data.
-*/
-
-/** @defgroup J2K J2K - JPEG-2000 codestream reader/writer */
-/*@{*/
-
-#define J2K_CP_CSTY_PRT 0x01
-#define J2K_CP_CSTY_SOP 0x02
-#define J2K_CP_CSTY_EPH 0x04
-#define J2K_CCP_CSTY_PRT 0x01
-#define J2K_CCP_CBLKSTY_LAZY 0x01     /**< Selective arithmetic coding bypass */
-#define J2K_CCP_CBLKSTY_RESET 0x02    /**< Reset context probabilities on coding pass boundaries */
-#define J2K_CCP_CBLKSTY_TERMALL 0x04  /**< Termination on each coding pass */
-#define J2K_CCP_CBLKSTY_VSC 0x08      /**< Vertically stripe causal context */
-#define J2K_CCP_CBLKSTY_PTERM 0x10    /**< Predictable termination */
-#define J2K_CCP_CBLKSTY_SEGSYM 0x20   /**< Segmentation symbols are used */
-#define J2K_CCP_QNTSTY_NOQNT 0
-#define J2K_CCP_QNTSTY_SIQNT 1
-#define J2K_CCP_QNTSTY_SEQNT 2
-
-/* ----------------------------------------------------------------------- */
-
-#define J2K_MS_SOC 0xff4f	/**< SOC marker value */
-#define J2K_MS_SOT 0xff90	/**< SOT marker value */
-#define J2K_MS_SOD 0xff93	/**< SOD marker value */
-#define J2K_MS_EOC 0xffd9	/**< EOC marker value */
-#define J2K_MS_SIZ 0xff51	/**< SIZ marker value */
-#define J2K_MS_COD 0xff52	/**< COD marker value */
-#define J2K_MS_COC 0xff53	/**< COC marker value */
-#define J2K_MS_RGN 0xff5e	/**< RGN marker value */
-#define J2K_MS_QCD 0xff5c	/**< QCD marker value */
-#define J2K_MS_QCC 0xff5d	/**< QCC marker value */
-#define J2K_MS_POC 0xff5f	/**< POC marker value */
-#define J2K_MS_TLM 0xff55	/**< TLM marker value */
-#define J2K_MS_PLM 0xff57	/**< PLM marker value */
-#define J2K_MS_PLT 0xff58	/**< PLT marker value */
-#define J2K_MS_PPM 0xff60	/**< PPM marker value */
-#define J2K_MS_PPT 0xff61	/**< PPT marker value */
-#define J2K_MS_SOP 0xff91	/**< SOP marker value */
-#define J2K_MS_EPH 0xff92	/**< EPH marker value */
-#define J2K_MS_CRG 0xff63	/**< CRG marker value */
-#define J2K_MS_COM 0xff64	/**< COM marker value */
-/* UniPG>> */
-#ifdef USE_JPWL
-#define J2K_MS_EPC 0xff68	/**< EPC marker value (Part 11: JPEG 2000 for Wireless) */
-#define J2K_MS_EPB 0xff66	/**< EPB marker value (Part 11: JPEG 2000 for Wireless) */ 
-#define J2K_MS_ESD 0xff67	/**< ESD marker value (Part 11: JPEG 2000 for Wireless) */ 
-#define J2K_MS_RED 0xff69	/**< RED marker value (Part 11: JPEG 2000 for Wireless) */
-#endif /* USE_JPWL */
-#ifdef USE_JPSEC
-#define J2K_MS_SEC 0xff65    /**< SEC marker value (Part 8: Secure JPEG 2000) */
-#define J2K_MS_INSEC 0xff94  /**< INSEC marker value (Part 8: Secure JPEG 2000) */
-#endif /* USE_JPSEC */
-/* <<UniPG */
-
-
-/* ----------------------------------------------------------------------- */
-
-/**
-Values that specify the status of the decoding process when decoding the main header. 
-These values may be combined with a | operator. 
-*/
-typedef enum J2K_STATUS {
-	J2K_STATE_MHSOC  = 0x0001, /**< a SOC marker is expected */
-	J2K_STATE_MHSIZ  = 0x0002, /**< a SIZ marker is expected */
-	J2K_STATE_MH     = 0x0004, /**< the decoding process is in the main header */
-	J2K_STATE_TPHSOT = 0x0008, /**< the decoding process is in a tile part header and expects a SOT marker */
-	J2K_STATE_TPH    = 0x0010, /**< the decoding process is in a tile part header */
-	J2K_STATE_MT     = 0x0020, /**< the EOC marker has just been read */
-	J2K_STATE_NEOC   = 0x0040, /**< the decoding process must not expect a EOC marker because the codestream is truncated */
-	J2K_STATE_ERR    = 0x0080  /**< the decoding process has encountered an error */
-} J2K_STATUS;
-
-/* ----------------------------------------------------------------------- */
-
-/** 
-T2 encoding mode 
-*/
-typedef enum T2_MODE {
-	THRESH_CALC = 0,	/** Function called in Rate allocation process*/
-	FINAL_PASS = 1		/** Function called in Tier 2 process*/
-}J2K_T2_MODE;
-
-/**
-Quantization stepsize
-*/
-typedef struct opj_stepsize {
-	/** exponent */
-	int expn;
-	/** mantissa */
-	int mant;
-} opj_stepsize_t;
-
-/**
-Tile-component coding parameters
-*/
-typedef struct opj_tccp {
-	/** coding style */
-	int csty;
-	/** number of resolutions */
-	int numresolutions;
-	/** code-blocks width */
-	int cblkw;
-	/** code-blocks height */
-	int cblkh;
-	/** code-block coding style */
-	int cblksty;
-	/** discrete wavelet transform identifier */
-	int qmfbid;
-	/** quantisation style */
-	int qntsty;
-	/** stepsizes used for quantization */
-	opj_stepsize_t stepsizes[J2K_MAXBANDS];
-	/** number of guard bits */
-	int numgbits;
-	/** Region Of Interest shift */
-	int roishift;
-	/** precinct width */
-	int prcw[J2K_MAXRLVLS];
-	/** precinct height */
-	int prch[J2K_MAXRLVLS];	
-} opj_tccp_t;
-
-/**
-Tile coding parameters : 
-this structure is used to store coding/decoding parameters common to all
-tiles (information like COD, COC in main header)
-*/
-typedef struct opj_tcp {
-	/** 1 : first part-tile of a tile */
-	int first;
-	/** coding style */
-	int csty;
-	/** progression order */
-	OPJ_PROG_ORDER prg;
-	/** number of layers */
-	int numlayers;
-	/** multi-component transform identifier */
-	int mct;
-	/** rates of layers */
-	float rates[100];
-	/** number of progression order changes */
-	int numpocs;
-	/** indicates if a POC marker has been used O:NO, 1:YES */
-	int POC;
-	/** progression order changes */
-	opj_poc_t pocs[32];
-	/** packet header store there for futur use in t2_decode_packet */
-	unsigned char *ppt_data;
-	/** pointer remaining on the first byte of the first header if ppt is used */
-	unsigned char *ppt_data_first;
-	/** If ppt == 1 --> there was a PPT marker for the present tile */
-	int ppt;
-	/** used in case of multiple marker PPT (number of info already stored) */
-	int ppt_store;
-	/** ppmbug1 */
-	int ppt_len;
-	/** add fixed_quality */
-	float distoratio[100];
-	/** tile-component coding parameters */
-	opj_tccp_t *tccps;
-} opj_tcp_t;
-
-/**
-Coding parameters
-*/
-typedef struct opj_cp {
-	/** Digital cinema profile*/
-	OPJ_CINEMA_MODE cinema;
-	/** Maximum rate for each component. If == 0, component size limitation is not considered */
-	int max_comp_size;
-	/** Size of the image in bits*/
-	int img_size;
-	/** Rsiz*/
-	OPJ_RSIZ_CAPABILITIES rsiz;
-	/** Enabling Tile part generation*/
-	char tp_on;
-	/** Flag determining tile part generation*/
-	char tp_flag;
-	/** Position of tile part flag in progression order*/
-	int tp_pos;
-	/** allocation by rate/distortion */
-	int disto_alloc;
-	/** allocation by fixed layer */
-	int fixed_alloc;
-	/** add fixed_quality */
-	int fixed_quality;
-	/** if != 0, then original dimension divided by 2^(reduce); if == 0 or not used, image is decoded to the full resolution */
-	int reduce;
-	/** if != 0, then only the first "layer" layers are decoded; if == 0 or not used, all the quality layers are decoded */
-	int layer;
-	/** if == NO_LIMITATION, decode entire codestream; if == LIMIT_TO_MAIN_HEADER then only decode the main header */
-	OPJ_LIMIT_DECODING limit_decoding;
-	/** XTOsiz */
-	int tx0;
-	/** YTOsiz */
-	int ty0;
-	/** XTsiz */
-	int tdx;
-	/** YTsiz */
-	int tdy;
-	/** comment for coding */
-	char *comment;
-	/** number of tiles in width */
-	int tw;
-	/** number of tiles in heigth */
-	int th;
-	/** ID number of the tiles present in the codestream */
-	int *tileno;
-	/** size of the vector tileno */
-	int tileno_size;
-	/** packet header store there for futur use in t2_decode_packet */
-	unsigned char *ppm_data;
-	/** pointer remaining on the first byte of the first header if ppm is used */
-	unsigned char *ppm_data_first;
-	/** if ppm == 1 --> there was a PPM marker for the present tile */
-	int ppm;
-	/** use in case of multiple marker PPM (number of info already store) */
-	int ppm_store;
-	/** use in case of multiple marker PPM (case on non-finished previous info) */
-	int ppm_previous;
-	/** ppmbug1 */
-	int ppm_len;
-	/** tile coding parameters */
-	opj_tcp_t *tcps;
-	/** fixed layer */
-	int *matrice;
-/* UniPG>> */
-#ifdef USE_JPWL
-	/** enables writing of EPC in MH, thus activating JPWL */
-	opj_bool epc_on;
-	/** enables writing of EPB, in case of activated JPWL */
-	opj_bool epb_on;
-	/** enables writing of ESD, in case of activated JPWL */
-	opj_bool esd_on;
-	/** enables writing of informative techniques of ESD, in case of activated JPWL */
-	opj_bool info_on;
-	/** enables writing of RED, in case of activated JPWL */
-	opj_bool red_on;
-	/** error protection method for MH (0,1,16,32,37-128) */
-	int hprot_MH;
-	/** tile number of header protection specification (>=0) */
-	int hprot_TPH_tileno[JPWL_MAX_NO_TILESPECS];
-	/** error protection methods for TPHs (0,1,16,32,37-128) */
-	int hprot_TPH[JPWL_MAX_NO_TILESPECS];
-	/** tile number of packet protection specification (>=0) */
-	int pprot_tileno[JPWL_MAX_NO_PACKSPECS];
-	/** packet number of packet protection specification (>=0) */
-	int pprot_packno[JPWL_MAX_NO_PACKSPECS];
-	/** error protection methods for packets (0,1,16,32,37-128) */
-	int pprot[JPWL_MAX_NO_PACKSPECS];
-	/** enables writing of ESD, (0/2/4 bytes) */
-	int sens_size;
-	/** sensitivity addressing size (0=auto/2/4 bytes) */
-	int sens_addr;
-	/** sensitivity range (0-3) */
-	int sens_range;
-	/** sensitivity method for MH (-1,0-7) */
-	int sens_MH;
-	/** tile number of sensitivity specification (>=0) */
-	int sens_TPH_tileno[JPWL_MAX_NO_TILESPECS];
-	/** sensitivity methods for TPHs (-1,0-7) */
-	int sens_TPH[JPWL_MAX_NO_TILESPECS];
-	/** enables JPWL correction at the decoder */
-	opj_bool correct;
-	/** expected number of components at the decoder */
-	int exp_comps;
-	/** maximum number of tiles at the decoder */
-	int max_tiles;
-#endif /* USE_JPWL */
-/* <<UniPG */
-} opj_cp_t;
-
-/**
-JPEG-2000 codestream reader/writer
-*/
-typedef struct opj_j2k {
-	/** codec context */
-	opj_common_ptr cinfo;
-
-	/** locate in which part of the codestream the decoder is (main header, tile header, end) */
-	int state;
-	/** number of the tile curently concern by coding/decoding */
-	int curtileno;
-	/** Tile part number*/
-	int tp_num;
-	/** Tilepart number currently coding*/
-	int cur_tp_num;
-	/** Total number of tileparts of the current tile*/
-	int *cur_totnum_tp;
-	/**
-	locate the start position of the TLM marker  
-	after encoding the tilepart, a jump (in j2k_write_sod) is done to the TLM marker to store the value of its length. 
-	*/
-	int tlm_start;
-	/** Total num of tile parts in whole image = num tiles* num tileparts in each tile*/
-	/** used in TLMmarker*/
-	int totnum_tp;	
-	/** 
-	locate the position of the end of the tile in the codestream, 
-	used to detect a truncated codestream (in j2k_read_sod)
-	*/
-	unsigned char *eot;
-	/**
-	locate the start position of the SOT marker of the current coded tile:  
-	after encoding the tile, a jump (in j2k_write_sod) is done to the SOT marker to store the value of its length. 
-	*/
-	int sot_start;
-	int sod_start;
-	/**
-	as the J2K-file is written in several parts during encoding, 
-	it enables to make the right correction in position return by cio_tell
-	*/
-	int pos_correction;
-	/** array used to store the data of each tile */
-	unsigned char **tile_data;
-	/** array used to store the length of each tile */
-	int *tile_len;
-	/** 
-	decompression only : 
-	store decoding parameters common to all tiles (information like COD, COC in main header)
-	*/
-	opj_tcp_t *default_tcp;
-	/** pointer to the encoded / decoded image */
-	opj_image_t *image;
-	/** pointer to the coding parameters */
-	opj_cp_t *cp;
-	/** helper used to write the index file */
-	opj_codestream_info_t *cstr_info;
-	/** pointer to the byte i/o stream */
-	opj_cio_t *cio;
-} opj_j2k_t;
-
-/** @name Exported functions */
-/*@{*/
-/* ----------------------------------------------------------------------- */
-/**
-Creates a J2K decompression structure
- at param cinfo Codec context info
- at return Returns a handle to a J2K decompressor if successful, returns NULL otherwise
-*/
-opj_j2k_t* j2k_create_decompress(opj_common_ptr cinfo);
-/**
-Destroy a J2K decompressor handle
- at param j2k J2K decompressor handle to destroy
-*/
-void j2k_destroy_decompress(opj_j2k_t *j2k);
-/**
-Setup the decoder decoding parameters using user parameters.
-Decoding parameters are returned in j2k->cp. 
- at param j2k J2K decompressor handle
- at param parameters decompression parameters
-*/
-void j2k_setup_decoder(opj_j2k_t *j2k, opj_dparameters_t *parameters);
-/**
-Decode an image from a JPEG-2000 codestream
- at param j2k J2K decompressor handle
- at param cio Input buffer stream
- at param cstr_info Codestream information structure if required, NULL otherwise
- at return Returns a decoded image if successful, returns NULL otherwise
-*/
-opj_image_t* j2k_decode(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestream_info_t *cstr_info);
-/**
-Decode an image form a JPT-stream (JPEG 2000, JPIP)
- at param j2k J2K decompressor handle
- at param cio Input buffer stream
- at param cstr_info Codestream information structure if required, NULL otherwise
- at return Returns a decoded image if successful, returns NULL otherwise
-*/
-opj_image_t* j2k_decode_jpt_stream(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestream_info_t *cstr_info);
-/**
-Creates a J2K compression structure
- at param cinfo Codec context info
- at return Returns a handle to a J2K compressor if successful, returns NULL otherwise
-*/
-opj_j2k_t* j2k_create_compress(opj_common_ptr cinfo);
-/**
-Destroy a J2K compressor handle
- at param j2k J2K compressor handle to destroy
-*/
-void j2k_destroy_compress(opj_j2k_t *j2k);
-/**
-Setup the encoder parameters using the current image and using user parameters. 
-Coding parameters are returned in j2k->cp. 
- at param j2k J2K compressor handle
- at param parameters compression parameters
- at param image input filled image
-*/
-void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_t *image);
-/**
-Converts an enum type progression order to string type
-*/
-char *j2k_convert_progression_order(OPJ_PROG_ORDER prg_order);
-/**
-Encode an image into a JPEG-2000 codestream
- at param j2k J2K compressor handle
- at param cio Output buffer stream
- at param image Image to encode
- at param cstr_info Codestream information structure if required, NULL otherwise
- at return Returns true if successful, returns false otherwise
-*/
-opj_bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info);
-
-/* ----------------------------------------------------------------------- */
-/*@}*/
-
-/*@}*/
-
-#endif /* __J2K_H */
+/*
+ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2007, Professor Benoit Macq
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2006-2007, Parvatha Elangovan
+ * Copyright (c) 2008, Jerome Fimes, Communications & Systemes <jerome.fimes at c-s.fr>
+ * Copyright (c) 2011-2012, Centre National d'Etudes Spatiales (CNES), France 
+ * Copyright (c) 2012, CS Systemes d'Information, France
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef __J2K_H
+#define __J2K_H
+/**
+ at file j2k.h
+ at brief The JPEG-2000 Codestream Reader/Writer (J2K)
+
+The functions in J2K.C have for goal to read/write the several parts of the codestream: markers and data.
+*/
+
+/** @defgroup J2K J2K - JPEG-2000 codestream reader/writer */
+/*@{*/
+
+#define J2K_CP_CSTY_PRT 0x01
+#define J2K_CP_CSTY_SOP 0x02
+#define J2K_CP_CSTY_EPH 0x04
+#define J2K_CCP_CSTY_PRT 0x01
+#define J2K_CCP_CBLKSTY_LAZY 0x01     /**< Selective arithmetic coding bypass */
+#define J2K_CCP_CBLKSTY_RESET 0x02    /**< Reset context probabilities on coding pass boundaries */
+#define J2K_CCP_CBLKSTY_TERMALL 0x04  /**< Termination on each coding pass */
+#define J2K_CCP_CBLKSTY_VSC 0x08      /**< Vertically stripe causal context */
+#define J2K_CCP_CBLKSTY_PTERM 0x10    /**< Predictable termination */
+#define J2K_CCP_CBLKSTY_SEGSYM 0x20   /**< Segmentation symbols are used */
+#define J2K_CCP_QNTSTY_NOQNT 0
+#define J2K_CCP_QNTSTY_SIQNT 1
+#define J2K_CCP_QNTSTY_SEQNT 2
+
+#define OPJ_J2K_DEFAULT_CBLK_DATA_SIZE 8192
+
+/* ----------------------------------------------------------------------- */
+
+#define J2K_MS_SOC 0xff4f	/**< SOC marker value */
+#define J2K_MS_SOT 0xff90	/**< SOT marker value */
+#define J2K_MS_SOD 0xff93	/**< SOD marker value */
+#define J2K_MS_EOC 0xffd9	/**< EOC marker value */
+#define J2K_MS_SIZ 0xff51	/**< SIZ marker value */
+#define J2K_MS_COD 0xff52	/**< COD marker value */
+#define J2K_MS_COC 0xff53	/**< COC marker value */
+#define J2K_MS_RGN 0xff5e	/**< RGN marker value */
+#define J2K_MS_QCD 0xff5c	/**< QCD marker value */
+#define J2K_MS_QCC 0xff5d	/**< QCC marker value */
+#define J2K_MS_POC 0xff5f	/**< POC marker value */
+#define J2K_MS_TLM 0xff55	/**< TLM marker value */
+#define J2K_MS_PLM 0xff57	/**< PLM marker value */
+#define J2K_MS_PLT 0xff58	/**< PLT marker value */
+#define J2K_MS_PPM 0xff60	/**< PPM marker value */
+#define J2K_MS_PPT 0xff61	/**< PPT marker value */
+#define J2K_MS_SOP 0xff91	/**< SOP marker value */
+#define J2K_MS_EPH 0xff92	/**< EPH marker value */
+#define J2K_MS_CRG 0xff63	/**< CRG marker value */
+#define J2K_MS_COM 0xff64	/**< COM marker value */
+#define J2K_MS_CBD 0xff78	/**< CBD marker value */
+#define J2K_MS_MCC 0xff75	/**< MCC marker value */
+#define J2K_MS_MCT 0xff74	/**< MCT marker value */
+#define J2K_MS_MCO 0xff77	/**< MCO marker value */
+
+#define J2K_MS_UNK 0		/**< UNKNOWN marker value */
+
+/* UniPG>> */
+#ifdef USE_JPWL
+#define J2K_MS_EPC 0xff68	/**< EPC marker value (Part 11: JPEG 2000 for Wireless) */
+#define J2K_MS_EPB 0xff66	/**< EPB marker value (Part 11: JPEG 2000 for Wireless) */ 
+#define J2K_MS_ESD 0xff67	/**< ESD marker value (Part 11: JPEG 2000 for Wireless) */ 
+#define J2K_MS_RED 0xff69	/**< RED marker value (Part 11: JPEG 2000 for Wireless) */
+#endif /* USE_JPWL */
+#ifdef USE_JPSEC
+#define J2K_MS_SEC 0xff65    /**< SEC marker value (Part 8: Secure JPEG 2000) */
+#define J2K_MS_INSEC 0xff94  /**< INSEC marker value (Part 8: Secure JPEG 2000) */
+#endif /* USE_JPSEC */
+/* <<UniPG */
+
+/* ----------------------------------------------------------------------- */
+
+/**
+ * Values that specify the status of the decoding process when decoding the main header.
+ * These values may be combined with a | operator.
+ * */
+typedef enum J2K_STATUS {
+	J2K_STATE_NONE  =  0x0000, /**< a SOC marker is expected */
+	J2K_STATE_MHSOC  = 0x0001, /**< a SOC marker is expected */
+	J2K_STATE_MHSIZ  = 0x0002, /**< a SIZ marker is expected */
+	J2K_STATE_MH     = 0x0004, /**< the decoding process is in the main header */
+	J2K_STATE_TPHSOT = 0x0008, /**< the decoding process is in a tile part header and expects a SOT marker */
+	J2K_STATE_TPH    = 0x0010, /**< the decoding process is in a tile part header */
+	J2K_STATE_MT     = 0x0020, /**< the EOC marker has just been read */
+	J2K_STATE_NEOC   = 0x0040, /**< the decoding process must not expect a EOC marker because the codestream is truncated */
+
+	J2K_STATE_EOC	 = 0x0100, /**< the decoding process has encountered the EOC marker */
+	J2K_STATE_ERR    = 0x8000  /**< the decoding process has encountered an error (FIXME warning V1 = 0x0080)*/
+} J2K_STATUS;
+
+/**
+ * Type of elements storing in the MCT data
+ */
+typedef enum MCT_ELEMENT_TYPE
+{
+	MCT_TYPE_INT16 = 0,		/** MCT data is stored as signed shorts*/
+	MCT_TYPE_INT32 = 1,		/** MCT data is stored as signed integers*/
+	MCT_TYPE_FLOAT = 2,		/** MCT data is stored as floats*/
+	MCT_TYPE_DOUBLE = 3		/** MCT data is stored as doubles*/
+} J2K_MCT_ELEMENT_TYPE;
+
+/**
+ * Type of MCT array
+ */
+typedef enum MCT_ARRAY_TYPE
+{
+	MCT_TYPE_DEPENDENCY = 0,
+	MCT_TYPE_DECORRELATION = 1,
+	MCT_TYPE_OFFSET = 2
+} J2K_MCT_ARRAY_TYPE;
+
+/* ----------------------------------------------------------------------- */
+
+/** 
+T2 encoding mode 
+*/
+typedef enum T2_MODE {
+	THRESH_CALC = 0,	/** Function called in Rate allocation process*/
+	FINAL_PASS = 1		/** Function called in Tier 2 process*/
+}J2K_T2_MODE;
+
+/**
+ * Quantization stepsize
+ */
+typedef struct opj_stepsize {
+	/** exponent */
+	OPJ_INT32 expn;
+	/** mantissa */
+	OPJ_INT32 mant;
+} opj_stepsize_t;
+
+/**
+Tile-component coding parameters
+*/
+typedef struct opj_tccp
+{
+	/** coding style */
+	OPJ_UINT32 csty;
+	/** number of resolutions */
+	OPJ_UINT32 numresolutions;
+	/** code-blocks width */
+	OPJ_UINT32 cblkw;
+	/** code-blocks height */
+	OPJ_UINT32 cblkh;
+	/** code-block coding style */
+	OPJ_UINT32 cblksty;
+	/** discrete wavelet transform identifier */
+	OPJ_UINT32 qmfbid;
+	/** quantisation style */
+	OPJ_UINT32 qntsty;
+	/** stepsizes used for quantization */
+	opj_stepsize_t stepsizes[OPJ_J2K_MAXBANDS];
+	/** number of guard bits */
+	OPJ_UINT32 numgbits;
+	/** Region Of Interest shift */
+	OPJ_INT32 roishift;
+	/** precinct width */
+	OPJ_UINT32 prcw[OPJ_J2K_MAXRLVLS];
+	/** precinct height */
+	OPJ_UINT32 prch[OPJ_J2K_MAXRLVLS];
+	/** the dc_level_shift **/
+	OPJ_INT32 m_dc_level_shift;
+}
+opj_tccp_t;
+
+
+
+/**
+ * FIXME DOC
+ */
+typedef struct opj_mct_data
+{
+	J2K_MCT_ELEMENT_TYPE m_element_type;
+	J2K_MCT_ARRAY_TYPE	 m_array_type;
+	OPJ_UINT32			 m_index;
+	OPJ_BYTE *			 m_data;
+	OPJ_UINT32			 m_data_size;
+}
+opj_mct_data_t;
+
+/**
+ * FIXME DOC
+ */
+typedef struct opj_simple_mcc_decorrelation_data
+{
+	OPJ_UINT32			 m_index;
+	OPJ_UINT32			 m_nb_comps;
+	opj_mct_data_t *	 m_decorrelation_array;
+	opj_mct_data_t *	 m_offset_array;
+	OPJ_UINT32			 m_is_irreversible : 1;
+}
+opj_simple_mcc_decorrelation_data_t;
+
+/**
+Tile coding parameters :
+this structure is used to store coding/decoding parameters common to all
+tiles (information like COD, COC in main header)
+*/
+typedef struct opj_tcp
+{
+	/** coding style */
+	OPJ_UINT32 csty;
+	/** progression order */
+	OPJ_PROG_ORDER prg;
+	/** number of layers */
+	OPJ_UINT32 numlayers;
+	OPJ_UINT32 num_layers_to_decode;
+	/** multi-component transform identifier */
+	OPJ_UINT32 mct;
+	/** rates of layers */
+	OPJ_FLOAT32 rates[100];
+	/** number of progression order changes */
+	OPJ_UINT32 numpocs;
+	/** progression order changes */
+	opj_poc_t pocs[32];
+	/** packet header store there for futur use in t2_decode_packet */
+	OPJ_BYTE *ppt_data;
+	/** used to keep a track of the allocated memory */
+	OPJ_BYTE *ppt_buffer;
+	/** Number of bytes stored inside ppt_data*/
+	OPJ_UINT32 ppt_data_size;
+	/** size of ppt_data*/
+	OPJ_UINT32 ppt_len;
+	/** add fixed_quality */
+	OPJ_FLOAT32 distoratio[100];
+	/** tile-component coding parameters */
+	opj_tccp_t *tccps;
+	/** number of tile parts for the tile. */
+	OPJ_UINT32 m_nb_tile_parts;
+	/** data for the tile */
+	OPJ_BYTE *		m_data;
+	/** size of data */
+	OPJ_UINT32		m_data_size;
+	/** encoding norms */
+	OPJ_FLOAT64 *	mct_norms;
+	/** the mct decoding matrix */
+	OPJ_FLOAT32 *	m_mct_decoding_matrix;
+	/** the mct coding matrix */
+	OPJ_FLOAT32 *	m_mct_coding_matrix;
+	/** mct records */
+	opj_mct_data_t * m_mct_records;
+	/** the number of mct records. */
+	OPJ_UINT32 m_nb_mct_records;
+	/** the max number of mct records. */
+	OPJ_UINT32 m_nb_max_mct_records;
+	/** mcc records */
+	opj_simple_mcc_decorrelation_data_t * m_mcc_records;
+	/** the number of mct records. */
+	OPJ_UINT32 m_nb_mcc_records;
+	/** the max number of mct records. */
+	OPJ_UINT32 m_nb_max_mcc_records;
+
+
+	/***** FLAGS *******/
+	/** If ppt == 1 --> there was a PPT marker for the present tile */
+	OPJ_UINT32 ppt : 1;
+	/** indicates if a POC marker has been used O:NO, 1:YES */
+	OPJ_UINT32 POC : 1;
+} opj_tcp_t;
+
+
+
+
+typedef struct opj_encoding_param
+{
+	/** Digital cinema profile*/
+	OPJ_CINEMA_MODE m_cinema;
+	/** Maximum rate for each component. If == 0, component size limitation is not considered */
+	OPJ_UINT32 m_max_comp_size;
+	/** Position of tile part flag in progression order*/
+	OPJ_INT32 m_tp_pos;
+	/** fixed layer */
+	OPJ_INT32 *m_matrice;
+	/** Flag determining tile part generation*/
+	OPJ_BYTE m_tp_flag;
+	/** allocation by rate/distortion */
+	OPJ_UINT32 m_disto_alloc : 1;
+	/** allocation by fixed layer */
+	OPJ_UINT32 m_fixed_alloc : 1;
+	/** add fixed_quality */
+	OPJ_UINT32 m_fixed_quality : 1;
+	/** Enabling Tile part generation*/
+	OPJ_UINT32 m_tp_on : 1;
+}
+opj_encoding_param_t;
+
+typedef struct opj_decoding_param
+{
+	/** if != 0, then original dimension divided by 2^(reduce); if == 0 or not used, image is decoded to the full resolution */
+	OPJ_UINT32 m_reduce;
+	/** if != 0, then only the first "layer" layers are decoded; if == 0 or not used, all the quality layers are decoded */
+	OPJ_UINT32 m_layer;
+}
+opj_decoding_param_t;
+
+
+/**
+ * Coding parameters
+ */
+typedef struct opj_cp
+{
+	/** Size of the image in bits*/
+	/*int img_size;*/
+	/** Rsiz*/
+	OPJ_RSIZ_CAPABILITIES rsiz;
+	/** XTOsiz */
+	OPJ_UINT32 tx0; /* MSD see norm */
+	/** YTOsiz */
+	OPJ_UINT32 ty0; /* MSD see norm */
+	/** XTsiz */
+	OPJ_UINT32 tdx;
+	/** YTsiz */
+	OPJ_UINT32 tdy;
+	/** comment */
+	OPJ_CHAR *comment;
+	/** number of tiles in width */
+	OPJ_UINT32 tw;
+	/** number of tiles in heigth */
+	OPJ_UINT32 th;
+
+	/** packet header store there for futur use in t2_decode_packet */
+	OPJ_BYTE *ppm_data;
+	/** size of the ppm_data*/
+	OPJ_UINT32 ppm_len;
+	/** size of the ppm_data*/
+	OPJ_UINT32 ppm_data_read;
+
+	OPJ_BYTE *ppm_data_current;
+
+	/** packet header storage original buffer */
+	OPJ_BYTE *ppm_buffer;
+	/** pointer remaining on the first byte of the first header if ppm is used */
+	OPJ_BYTE *ppm_data_first;
+	/** Number of bytes actually stored inside the ppm_data */
+	OPJ_UINT32 ppm_data_size;
+	/** use in case of multiple marker PPM (number of info already store) */
+	OPJ_INT32 ppm_store;
+	/** use in case of multiple marker PPM (case on non-finished previous info) */
+	OPJ_INT32 ppm_previous;
+
+	/** tile coding parameters */
+	opj_tcp_t *tcps;
+
+	union
+	{
+		opj_decoding_param_t m_dec;
+		opj_encoding_param_t m_enc;
+	}
+	m_specific_param;
+
+
+/* UniPG>> */
+#ifdef USE_JPWL
+	/** enables writing of EPC in MH, thus activating JPWL */
+	OPJ_BOOL epc_on;
+	/** enables writing of EPB, in case of activated JPWL */
+	OPJ_BOOL epb_on;
+	/** enables writing of ESD, in case of activated JPWL */
+	OPJ_BOOL esd_on;
+	/** enables writing of informative techniques of ESD, in case of activated JPWL */
+	OPJ_BOOL info_on;
+	/** enables writing of RED, in case of activated JPWL */
+	OPJ_BOOL red_on;
+	/** error protection method for MH (0,1,16,32,37-128) */
+	int hprot_MH;
+	/** tile number of header protection specification (>=0) */
+	int hprot_TPH_tileno[JPWL_MAX_NO_TILESPECS];
+	/** error protection methods for TPHs (0,1,16,32,37-128) */
+	int hprot_TPH[JPWL_MAX_NO_TILESPECS];
+	/** tile number of packet protection specification (>=0) */
+	int pprot_tileno[JPWL_MAX_NO_PACKSPECS];
+	/** packet number of packet protection specification (>=0) */
+	int pprot_packno[JPWL_MAX_NO_PACKSPECS];
+	/** error protection methods for packets (0,1,16,32,37-128) */
+	int pprot[JPWL_MAX_NO_PACKSPECS];
+	/** enables writing of ESD, (0/2/4 bytes) */
+	int sens_size;
+	/** sensitivity addressing size (0=auto/2/4 bytes) */
+	int sens_addr;
+	/** sensitivity range (0-3) */
+	int sens_range;
+	/** sensitivity method for MH (-1,0-7) */
+	int sens_MH;
+	/** tile number of sensitivity specification (>=0) */
+	int sens_TPH_tileno[JPWL_MAX_NO_TILESPECS];
+	/** sensitivity methods for TPHs (-1,0-7) */
+	int sens_TPH[JPWL_MAX_NO_TILESPECS];
+	/** enables JPWL correction at the decoder */
+	OPJ_BOOL correct;
+	/** expected number of components at the decoder */
+	int exp_comps;
+	/** maximum number of tiles at the decoder */
+	OPJ_UINT32 max_tiles;
+#endif /* USE_JPWL */
+
+	/******** FLAGS *********/
+	/** if ppm == 1 --> there was a PPM marker*/
+	OPJ_UINT32 ppm : 1;
+	/** tells if the parameter is a coding or decoding one */
+	OPJ_UINT32 m_is_decoder : 1;
+/* <<UniPG */
+} opj_cp_t;
+
+
+typedef struct opj_j2k_dec
+{
+	/** locate in which part of the codestream the decoder is (main header, tile header, end) */
+	OPJ_UINT32 m_state;
+	/**
+	 * store decoding parameters common to all tiles (information like COD, COC in main header)
+	 */
+	opj_tcp_t *m_default_tcp;
+	OPJ_BYTE  *m_header_data;
+	OPJ_UINT32 m_header_data_size;
+	/** to tell the tile part length */
+	OPJ_UINT32 m_sot_length;
+	/** Only tiles index in the correct range will be decoded.*/
+	OPJ_UINT32 m_start_tile_x;
+	OPJ_UINT32 m_start_tile_y;
+	OPJ_UINT32 m_end_tile_x;
+	OPJ_UINT32 m_end_tile_y;
+	/**
+	 * Decoded area set by the user
+	 */
+	OPJ_UINT32 m_DA_x0;
+	OPJ_UINT32 m_DA_y0;
+	OPJ_UINT32 m_DA_x1;
+	OPJ_UINT32 m_DA_y1;
+
+	/** Index of the tile to decode (used in get_tile) */
+	OPJ_INT32 m_tile_ind_to_dec;
+	/** Position of the last SOT marker read */
+	OPJ_OFF_T m_last_sot_read_pos;
+
+	/**
+	 * Indicate that the current tile-part is assume as the last tile part of the codestream.
+	 * It is useful in the case of PSot is equal to zero. The sot length will be compute in the
+	 * SOD reader function. FIXME NOT USED for the moment
+	 */
+	OPJ_BOOL   m_last_tile_part;
+	/** to tell that a tile can be decoded. */
+	OPJ_UINT32 m_can_decode			: 1;
+	OPJ_UINT32 m_discard_tiles		: 1;
+	OPJ_UINT32 m_skip_data			: 1;
+
+} opj_j2k_dec_t;
+
+typedef struct opj_j2k_enc
+{
+	/** Tile part number, regardless of poc, for each new poc, tp is reset to 1*/
+	OPJ_UINT32 m_current_poc_tile_part_number; /* tp_num */
+
+	/** Tile part number currently coding, taking into account POC. m_current_tile_part_number holds the total number of tile parts while encoding the last tile part.*/
+	OPJ_UINT32 m_current_tile_part_number; /*cur_tp_num */
+
+	/**
+	locate the start position of the TLM marker
+	after encoding the tilepart, a jump (in j2k_write_sod) is done to the TLM marker to store the value of its length.
+	*/
+    OPJ_OFF_T m_tlm_start;
+	/**
+	 * Stores the sizes of the tlm.
+	 */
+	OPJ_BYTE * m_tlm_sot_offsets_buffer;
+	/**
+	 * The current offset of the tlm buffer.
+	 */
+	OPJ_BYTE * m_tlm_sot_offsets_current;
+
+	/** Total num of tile parts in whole image = num tiles* num tileparts in each tile*/
+	/** used in TLMmarker*/
+	OPJ_UINT32 m_total_tile_parts;	 /* totnum_tp */
+
+	/* encoded data for a tile */
+	OPJ_BYTE * m_encoded_tile_data;
+
+	/* size of the encoded_data */
+	OPJ_UINT32 m_encoded_tile_size;
+
+	/* encoded data for a tile */
+	OPJ_BYTE * m_header_tile_data;
+
+	/* size of the encoded_data */
+	OPJ_UINT32 m_header_tile_data_size;
+
+
+} opj_j2k_enc_t;
+
+
+
+struct opj_tcd;
+/**
+JPEG-2000 codestream reader/writer
+*/
+typedef struct opj_j2k
+{
+	/* J2K codestream is decoded*/
+	OPJ_BOOL m_is_decoder;
+
+	/* FIXME DOC*/
+	union
+	{
+		opj_j2k_dec_t m_decoder;
+		opj_j2k_enc_t m_encoder;
+	}
+	m_specific_param;
+
+	/** pointer to the internal/private encoded / decoded image */
+	opj_image_t* m_private_image;
+
+	/* pointer to the output image (decoded)*/
+	opj_image_t* m_output_image;
+
+	/** Coding parameters */
+	opj_cp_t m_cp;
+
+	/** the list of procedures to exec **/
+	opj_procedure_list_t *	m_procedure_list;
+
+	/** the list of validation procedures to follow to make sure the code is valid **/
+	opj_procedure_list_t *	m_validation_list;
+
+	/** helper used to write the index file */
+	opj_codestream_index_t *cstr_index;
+
+	/** number of the tile curently concern by coding/decoding */
+	OPJ_UINT32 m_current_tile_number;
+
+	/** the current tile coder/decoder **/
+	struct opj_tcd *	m_tcd;
+
+}
+opj_j2k_t;
+
+
+
+
+/** @name Exported functions */
+/*@{*/
+/* ----------------------------------------------------------------------- */
+
+/**
+Setup the decoder decoding parameters using user parameters.
+Decoding parameters are returned in j2k->cp. 
+ at param j2k J2K decompressor handle
+ at param parameters decompression parameters
+*/
+void opj_j2k_setup_decoder(opj_j2k_t *j2k, opj_dparameters_t *parameters);
+
+/**
+ * Creates a J2K compression structure
+ *
+ * @return Returns a handle to a J2K compressor if successful, returns NULL otherwise
+*/
+opj_j2k_t* opj_j2k_create_compress(void);
+
+
+void opj_j2k_setup_encoder(	opj_j2k_t *p_j2k,
+						    opj_cparameters_t *parameters,
+						    opj_image_t *image,
+						    opj_event_mgr_t * p_manager);
+
+/**
+Converts an enum type progression order to string type
+*/
+char *opj_j2k_convert_progression_order(OPJ_PROG_ORDER prg_order);
+
+/* ----------------------------------------------------------------------- */
+/*@}*/
+
+/*@}*/
+
+/**
+ * Ends the decompression procedures and possibiliy add data to be read after the
+ * codestream.
+ */
+OPJ_BOOL opj_j2k_end_decompress(opj_j2k_t *j2k,
+                                opj_stream_private_t *p_stream,
+                                opj_event_mgr_t * p_manager);
+
+/**
+ * Reads a jpeg2000 codestream header structure.
+ *
+ * @param p_stream the stream to read data from.
+ * @param p_j2k the jpeg2000 codec.
+ * @param p_image FIXME DOC
+ * @param p_manager the user event manager.
+ *
+ * @return true if the box is valid.
+ */
+OPJ_BOOL opj_j2k_read_header(	opj_stream_private_t *p_stream,
+                                opj_j2k_t* p_j2k,
+                                opj_image_t** p_image,
+                                opj_event_mgr_t* p_manager );
+
+
+/**
+ * Destroys a jpeg2000 codec.
+ *
+ * @param	p_j2k	the jpeg20000 structure to destroy.
+ */
+void opj_j2k_destroy (opj_j2k_t *p_j2k);
+
+/**
+ * Destroys a codestream index structure.
+ *
+ * @param	p_cstr_ind	the codestream index parameter to destroy.
+ */
+void j2k_destroy_cstr_index (opj_codestream_index_t *p_cstr_ind);
+
+/**
+ * Decode tile data.
+ * @param	p_j2k		the jpeg2000 codec.
+ * @param	p_tile_index
+ * @param p_data       FIXME DOC
+ * @param p_data_size  FIXME DOC
+ * @param	p_stream			the stream to write data to.
+ * @param	p_manager	the user event manager.
+ */
+OPJ_BOOL opj_j2k_decode_tile (  opj_j2k_t * p_j2k,
+                                OPJ_UINT32 p_tile_index,
+                                OPJ_BYTE * p_data,
+                                OPJ_UINT32 p_data_size,
+                                opj_stream_private_t *p_stream,
+                                opj_event_mgr_t * p_manager );
+
+/**
+ * Reads a tile header.
+ * @param	p_j2k		the jpeg2000 codec.
+ * @param	p_tile_index FIXME DOC
+ * @param	p_data_size FIXME DOC
+ * @param	p_tile_x0 FIXME DOC
+ * @param	p_tile_y0 FIXME DOC
+ * @param	p_tile_x1 FIXME DOC
+ * @param	p_tile_y1 FIXME DOC
+ * @param	p_nb_comps FIXME DOC
+ * @param	p_go_on FIXME DOC
+ * @param	p_stream			the stream to write data to.
+ * @param	p_manager	the user event manager.
+ */
+OPJ_BOOL opj_j2k_read_tile_header ( opj_j2k_t * p_j2k,
+                                    OPJ_UINT32 * p_tile_index,
+                                    OPJ_UINT32 * p_data_size,
+                                    OPJ_INT32 * p_tile_x0,
+                                    OPJ_INT32 * p_tile_y0,
+                                    OPJ_INT32 * p_tile_x1,
+                                    OPJ_INT32 * p_tile_y1,
+                                    OPJ_UINT32 * p_nb_comps,
+                                    OPJ_BOOL * p_go_on,
+                                    opj_stream_private_t *p_stream,
+                                    opj_event_mgr_t * p_manager );
+
+
+/**
+ * Sets the given area to be decoded. This function should be called right after opj_read_header and before any tile header reading.
+ *
+ * @param	p_j2k			the jpeg2000 codec.
+ * @param	p_image     FIXME DOC
+ * @param	p_start_x		the left position of the rectangle to decode (in image coordinates).
+ * @param	p_start_y		the up position of the rectangle to decode (in image coordinates).
+ * @param	p_end_x			the right position of the rectangle to decode (in image coordinates).
+ * @param	p_end_y			the bottom position of the rectangle to decode (in image coordinates).
+ * @param	p_manager		the user event manager
+ *
+ * @return	true			if the area could be set.
+ */
+OPJ_BOOL opj_j2k_set_decode_area(	opj_j2k_t *p_j2k,
+								    opj_image_t* p_image,
+								    OPJ_INT32 p_start_x, OPJ_INT32 p_start_y,
+								    OPJ_INT32 p_end_x, OPJ_INT32 p_end_y,
+								    opj_event_mgr_t * p_manager );
+
+/**
+ * Creates a J2K decompression structure.
+ *
+ * @return a handle to a J2K decompressor if successful, NULL otherwise.
+ */
+opj_j2k_t* opj_j2k_create_decompress(void);
+
+
+/**
+ * Dump some elements from the J2K decompression structure .
+ *
+ *@param p_j2k				the jpeg2000 codec.
+ *@param flag				flag to describe what elments are dump.
+ *@param out_stream			output stream where dump the elements.
+ *
+*/
+void j2k_dump (opj_j2k_t* p_j2k, OPJ_INT32 flag, FILE* out_stream);
+
+
+
+/**
+ * Dump an image header structure.
+ *
+ *@param image			the image header to dump.
+ *@param dev_dump_flag		flag to describe if we are in the case of this function is use outside j2k_dump function
+ *@param out_stream			output stream where dump the elements.
+ */
+void j2k_dump_image_header(opj_image_t* image, OPJ_BOOL dev_dump_flag, FILE* out_stream);
+
+/**
+ * Dump a component image header structure.
+ *
+ *@param comp		the component image header to dump.
+ *@param dev_dump_flag		flag to describe if we are in the case of this function is use outside j2k_dump function
+ *@param out_stream			output stream where dump the elements.
+ */
+void j2k_dump_image_comp_header(opj_image_comp_t* comp, OPJ_BOOL dev_dump_flag, FILE* out_stream);
+
+/**
+ * Get the codestream info from a JPEG2000 codec.
+ *
+ *@param	p_j2k				the component image header to dump.
+ *
+ *@return	the codestream information extract from the jpg2000 codec
+ */
+opj_codestream_info_v2_t* j2k_get_cstr_info(opj_j2k_t* p_j2k);
+
+/**
+ * Get the codestream index from a JPEG2000 codec.
+ *
+ *@param	p_j2k				the component image header to dump.
+ *
+ *@return	the codestream index extract from the jpg2000 codec
+ */
+opj_codestream_index_t* j2k_get_cstr_index(opj_j2k_t* p_j2k);
+
+/**
+ * Decode an image from a JPEG-2000 codestream
+ * @param j2k J2K decompressor handle
+ * @param p_stream  FIXME DOC
+ * @param p_image   FIXME DOC
+ * @param p_manager FIXME DOC
+ * @return FIXME DOC
+*/
+OPJ_BOOL opj_j2k_decode(opj_j2k_t *j2k,
+                        opj_stream_private_t *p_stream,
+                        opj_image_t *p_image,
+                        opj_event_mgr_t *p_manager);
+
+
+OPJ_BOOL opj_j2k_get_tile(	opj_j2k_t *p_j2k,
+			    			opj_stream_private_t *p_stream,
+				    		opj_image_t* p_image,
+					    	opj_event_mgr_t * p_manager,
+						    OPJ_UINT32 tile_index );
+
+OPJ_BOOL opj_j2k_set_decoded_resolution_factor(opj_j2k_t *p_j2k, 
+                                               OPJ_UINT32 res_factor,
+                                               opj_event_mgr_t * p_manager);
+
+
+/**
+ * Writes a tile.
+ * @param	p_j2k		the jpeg2000 codec.
+ * @param p_tile_index FIXME DOC
+ * @param p_data FIXME DOC
+ * @param p_data_size FIXME DOC
+ * @param	p_stream			the stream to write data to.
+ * @param	p_manager	the user event manager.
+ */
+OPJ_BOOL opj_j2k_write_tile (	opj_j2k_t * p_j2k,
+							    OPJ_UINT32 p_tile_index,
+							    OPJ_BYTE * p_data,
+							    OPJ_UINT32 p_data_size,
+							    opj_stream_private_t *p_stream,
+							    opj_event_mgr_t * p_manager );
+
+/**
+ * Encodes an image into a JPEG-2000 codestream
+ */
+OPJ_BOOL opj_j2k_encode(	opj_j2k_t * p_j2k,
+			    			opj_stream_private_t *cio,
+				    		opj_event_mgr_t * p_manager );
+
+/**
+ * Starts a compression scheme, i.e. validates the codec parameters, writes the header.
+ *
+ * @param	p_j2k		the jpeg2000 codec.
+ * @param	p_stream			the stream object.
+ * @param	p_image FIXME DOC
+ * @param	p_manager	the user event manager.
+ *
+ * @return true if the codec is valid.
+ */
+OPJ_BOOL opj_j2k_start_compress(opj_j2k_t *p_j2k,
+							    opj_stream_private_t *p_stream,
+							    opj_image_t * p_image,
+							    opj_event_mgr_t * p_manager);
+
+/**
+ * Ends the compression procedures and possibiliy add data to be read after the
+ * codestream.
+ */
+OPJ_BOOL opj_j2k_end_compress( 	opj_j2k_t *p_j2k,
+							    opj_stream_private_t *cio,
+							    opj_event_mgr_t * p_manager);
+
+OPJ_BOOL opj_j2k_setup_mct_encoding (opj_tcp_t * p_tcp, opj_image_t * p_image);
+
+
+#endif /* __J2K_H */
diff --git a/Source/LibOpenJPEG/j2k_lib.c b/Source/LibOpenJPEG/j2k_lib.c
deleted file mode 100644
index 5589803..0000000
--- a/Source/LibOpenJPEG/j2k_lib.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifdef _WIN32
-#include <windows.h>
-#else
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <sys/times.h>
-#endif /* _WIN32 */
-#include "opj_includes.h"
-
-double opj_clock(void) {
-#ifdef _WIN32
-	/* _WIN32: use QueryPerformance (very accurate) */
-    LARGE_INTEGER freq , t ;
-    /* freq is the clock speed of the CPU */
-    QueryPerformanceFrequency(&freq) ;
-	/* cout << "freq = " << ((double) freq.QuadPart) << endl; */
-    /* t is the high resolution performance counter (see MSDN) */
-    QueryPerformanceCounter ( & t ) ;
-    return ( t.QuadPart /(double) freq.QuadPart ) ;
-#else
-	/* Unix or Linux: use resource usage */
-    struct rusage t;
-    double procTime;
-    /* (1) Get the rusage data structure at this moment (man getrusage) */
-    getrusage(0,&t);
-    /* (2) What is the elapsed time ? - CPU time = User time + System time */
-	/* (2a) Get the seconds */
-    procTime = t.ru_utime.tv_sec + t.ru_stime.tv_sec;
-    /* (2b) More precisely! Get the microseconds part ! */
-    return ( procTime + (t.ru_utime.tv_usec + t.ru_stime.tv_usec) * 1e-6 ) ;
-#endif
-}
-
diff --git a/Source/LibOpenJPEG/j2k_lib.h b/Source/LibOpenJPEG/j2k_lib.h
deleted file mode 100644
index ea5e1e6..0000000
--- a/Source/LibOpenJPEG/j2k_lib.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef __J2K_LIB_H
-#define __J2K_LIB_H
-/**
- at file j2k_lib.h
- at brief Internal functions
-
-The functions in J2K_LIB.C are internal utilities mainly used for timing.
-*/
-
-/** @defgroup MISC MISC - Miscellaneous internal functions */
-/*@{*/
-
-/** @name Exported functions */
-/*@{*/
-/* ----------------------------------------------------------------------- */
-
-/**
-Difference in successive opj_clock() calls tells you the elapsed time
- at return Returns time in seconds
-*/
-double opj_clock(void);
-
-/* ----------------------------------------------------------------------- */
-/*@}*/
-
-/*@}*/
-
-#endif /* __J2K_LIB_H */
-
diff --git a/Source/LibOpenJPEG/jp2.c b/Source/LibOpenJPEG/jp2.c
index ee28913..32ddd4f 100644
--- a/Source/LibOpenJPEG/jp2.c
+++ b/Source/LibOpenJPEG/jp2.c
@@ -1,1223 +1,2776 @@
-/*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
- * Copyright (c) 2001-2003, David Janssens
- * Copyright (c) 2002-2003, Yannick Verschueren
- * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * Copyright (c) 2010-2011, Kaori Hagihara
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-#include "opj_includes.h"
-
-/** @defgroup JP2 JP2 - JPEG-2000 file format reader/writer */
-/*@{*/
-
-/** @name Local static functions */
-/*@{*/
-
-/**
-Read box headers
- at param cinfo Codec context info
- at param cio Input stream
- at param box
- at return Returns true if successful, returns false otherwise
-*/
-static opj_bool jp2_read_boxhdr(opj_common_ptr cinfo, opj_cio_t *cio, opj_jp2_box_t *box);
-/*static void jp2_write_url(opj_cio_t *cio, char *Idx_file);*/
-/**
-Read the IHDR box - Image Header box
- at param jp2 JP2 handle
- at param cio Input buffer stream
- at return Returns true if successful, returns false otherwise
-*/
-static opj_bool jp2_read_ihdr(opj_jp2_t *jp2, opj_cio_t *cio);
-static void jp2_write_ihdr(opj_jp2_t *jp2, opj_cio_t *cio);
-static void jp2_write_bpcc(opj_jp2_t *jp2, opj_cio_t *cio);
-static opj_bool jp2_read_bpcc(opj_jp2_t *jp2, opj_cio_t *cio);
-static void jp2_write_colr(opj_jp2_t *jp2, opj_cio_t *cio);
-/**
-Write the FTYP box - File type box
- at param jp2 JP2 handle
- at param cio Output buffer stream
-*/
-static void jp2_write_ftyp(opj_jp2_t *jp2, opj_cio_t *cio);
-/**
-Read the FTYP box - File type box
- at param jp2 JP2 handle
- at param cio Input buffer stream
- at return Returns true if successful, returns false otherwise
-*/
-static opj_bool jp2_read_ftyp(opj_jp2_t *jp2, opj_cio_t *cio);
-static int jp2_write_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info);
-static opj_bool jp2_read_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, unsigned int *j2k_codestream_length, unsigned int *j2k_codestream_offset);
-static void jp2_write_jp(opj_cio_t *cio);
-/**
-Read the JP box - JPEG 2000 signature
- at param jp2 JP2 handle
- at param cio Input buffer stream
- at return Returns true if successful, returns false otherwise
-*/
-static opj_bool jp2_read_jp(opj_jp2_t *jp2, opj_cio_t *cio);
-/**
-Decode the structure of a JP2 file
- at param jp2 JP2 handle
- at param cio Input buffer stream
- at param color Collector for profile, cdef and pclr data
- at return Returns true if successful, returns false otherwise
-*/
-static opj_bool jp2_read_struct(opj_jp2_t *jp2, opj_cio_t *cio,
-	opj_jp2_color_t *color);
-/**
-Apply collected palette data
- at param color Collector for profile, cdef and pclr data
- at param image 
-*/
-static void jp2_apply_pclr(opj_jp2_color_t *color, opj_image_t *image, opj_common_ptr cinfo);
-/**
-Collect palette data
- at param jp2 JP2 handle
- at param cio Input buffer stream
- at param box
- at param color Collector for profile, cdef and pclr data
- at return Returns true if successful, returns false otherwise
-*/
-static opj_bool jp2_read_pclr(opj_jp2_t *jp2, opj_cio_t *cio,
-    opj_jp2_box_t *box, opj_jp2_color_t *color);
-/**
-Collect component mapping data
- at param jp2 JP2 handle
- at param cio Input buffer stream
- at param box
- at param color Collector for profile, cdef and pclr data
- at return Returns true if successful, returns false otherwise
-*/
-static opj_bool jp2_read_cmap(opj_jp2_t *jp2, opj_cio_t *cio,
-    opj_jp2_box_t *box, opj_jp2_color_t *color);
-/**
-Collect colour specification data
- at param jp2 JP2 handle
- at param cio Input buffer stream
- at param box
- at param color Collector for profile, cdef and pclr data
- at return Returns true if successful, returns false otherwise
-*/
-static opj_bool jp2_read_colr(opj_jp2_t *jp2, opj_cio_t *cio,
-    opj_jp2_box_t *box, opj_jp2_color_t *color);
-/**
-Write file Index (superbox)
- at param[in] offset_jp2c offset of jp2c box
- at param[in] length_jp2c length of jp2c box
- at param[in] offset_idx  offset of cidx box
- at param[in] length_idx  length of cidx box
- at param[in] cio         file output handle
- at return                length of fidx box
-*/
-static int write_fidx( int offset_jp2c, int length_jp2c, int offset_idx, int length_idx, opj_cio_t *cio);
-/**
-Write index Finder box
- at param[in] offset offset of fidx box
- at param[in] length length of fidx box
- at param[in] cio         file output handle
-*/
-static void write_iptr( int offset, int length, opj_cio_t *cio);
-/**
-Write proxy box
- at param[in] offset_jp2c offset of jp2c box
- at param[in] length_jp2c length of jp2c box
- at param[in] offset_idx  offset of cidx box
- at param[in] length_idx  length of cidx box
- at param[in] cio         file output handle
-*/
-static void write_prxy( int offset_jp2c, int length_jp2c, int offset_idx, int length_idx, opj_cio_t *cio);
-/*@}*/
-
-/*@}*/
-
-/* ----------------------------------------------------------------------- */
-
-static opj_bool jp2_read_boxhdr(opj_common_ptr cinfo, opj_cio_t *cio, opj_jp2_box_t *box) {
-	box->init_pos = cio_tell(cio);
-	box->length = cio_read(cio, 4);
-	box->type = cio_read(cio, 4);
-	if (box->length == 1) {
-		if (cio_read(cio, 4) != 0) {
-			opj_event_msg(cinfo, EVT_ERROR, "Cannot handle box sizes higher than 2^32\n");
-			return OPJ_FALSE;
-		}
-		box->length = cio_read(cio, 4);
-		if (box->length == 0) 
-			box->length = cio_numbytesleft(cio) + 12;
-	}
-	else if (box->length == 0) {
-		box->length = cio_numbytesleft(cio) + 8;
-	}
-	
-	return OPJ_TRUE;
-}
-
-#if 0
-static void jp2_write_url(opj_cio_t *cio, char *Idx_file) {
-	unsigned int i;
-	opj_jp2_box_t box;
-
-	box.init_pos = cio_tell(cio);
-	cio_skip(cio, 4);
-	cio_write(cio, JP2_URL, 4);	/* DBTL */
-	cio_write(cio, 0, 1);		/* VERS */
-	cio_write(cio, 0, 3);		/* FLAG */
-
-	if(Idx_file) {
-		for (i = 0; i < strlen(Idx_file); i++) {
-			cio_write(cio, Idx_file[i], 1);
-		}
-	}
-
-	box.length = cio_tell(cio) - box.init_pos;
-	cio_seek(cio, box.init_pos);
-	cio_write(cio, box.length, 4);	/* L */
-	cio_seek(cio, box.init_pos + box.length);
-}
-#endif
-
-static opj_bool jp2_read_ihdr(opj_jp2_t *jp2, opj_cio_t *cio) {
-	opj_jp2_box_t box;
-
-	opj_common_ptr cinfo = jp2->cinfo;
-
-  if(jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) {
-    opj_event_msg(cinfo, EVT_ERROR, "Failed to read boxhdr\n");
-    return OPJ_FALSE;
-  }
-	if (JP2_IHDR != box.type) {
-		opj_event_msg(cinfo, EVT_ERROR, "Expected IHDR Marker\n");
-		return OPJ_FALSE;
-	}
-
-	jp2->h = cio_read(cio, 4);			/* HEIGHT */
-	jp2->w = cio_read(cio, 4);			/* WIDTH */
-	jp2->numcomps = cio_read(cio, 2);	/* NC */
-	jp2->comps = (opj_jp2_comps_t*) opj_malloc(jp2->numcomps * sizeof(opj_jp2_comps_t));
-
-	jp2->bpc = cio_read(cio, 1);		/* BPC */
-
-	jp2->C = cio_read(cio, 1);			/* C */
-	jp2->UnkC = cio_read(cio, 1);		/* UnkC */
-	jp2->IPR = cio_read(cio, 1);		/* IPR */
-
-	if (cio_tell(cio) - box.init_pos != box.length) {
-		opj_event_msg(cinfo, EVT_ERROR, "Error with IHDR Box\n");
-		return OPJ_FALSE;
-	}
-
-	return OPJ_TRUE;
-}
-
-static void jp2_write_ihdr(opj_jp2_t *jp2, opj_cio_t *cio) {
-	opj_jp2_box_t box;
-
-	box.init_pos = cio_tell(cio);
-	cio_skip(cio, 4);
-	cio_write(cio, JP2_IHDR, 4);		/* IHDR */
-
-	cio_write(cio, jp2->h, 4);			/* HEIGHT */
-	cio_write(cio, jp2->w, 4);			/* WIDTH */
-	cio_write(cio, jp2->numcomps, 2);	/* NC */
-
-	cio_write(cio, jp2->bpc, 1);		/* BPC */
-
-	cio_write(cio, jp2->C, 1);			/* C : Always 7 */
-	cio_write(cio, jp2->UnkC, 1);		/* UnkC, colorspace unknown */
-	cio_write(cio, jp2->IPR, 1);		/* IPR, no intellectual property */
-
-	box.length = cio_tell(cio) - box.init_pos;
-	cio_seek(cio, box.init_pos);
-	cio_write(cio, box.length, 4);	/* L */
-	cio_seek(cio, box.init_pos + box.length);
-}
-
-static void jp2_write_bpcc(opj_jp2_t *jp2, opj_cio_t *cio) {
-	unsigned int i;
-	opj_jp2_box_t box;
-
-	box.init_pos = cio_tell(cio);
-	cio_skip(cio, 4);
-	cio_write(cio, JP2_BPCC, 4);	/* BPCC */
-
-	for (i = 0; i < jp2->numcomps; i++) {
-		cio_write(cio, jp2->comps[i].bpcc, 1);
-	}
-
-	box.length = cio_tell(cio) - box.init_pos;
-	cio_seek(cio, box.init_pos);
-	cio_write(cio, box.length, 4);	/* L */
-	cio_seek(cio, box.init_pos + box.length);
-}
-
-
-static opj_bool jp2_read_bpcc(opj_jp2_t *jp2, opj_cio_t *cio) {
-	unsigned int i;
-	opj_jp2_box_t box;
-
-	opj_common_ptr cinfo = jp2->cinfo;
-
-  if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) {
-    opj_event_msg(cinfo, EVT_ERROR, "Failed to read boxhdr\n");
-    return OPJ_FALSE;
-  }
-	if (JP2_BPCC != box.type) {
-		opj_event_msg(cinfo, EVT_ERROR, "Expected BPCC Marker\n");
-		return OPJ_FALSE;
-	}
-
-	for (i = 0; i < jp2->numcomps; i++) {
-		jp2->comps[i].bpcc = cio_read(cio, 1);
-	}
-
-	if (cio_tell(cio) - box.init_pos != box.length) {
-		opj_event_msg(cinfo, EVT_ERROR, "Error with BPCC Box\n");
-		return OPJ_FALSE;
-	}
-
-	return OPJ_TRUE;
-}
-
-static void jp2_write_colr(opj_jp2_t *jp2, opj_cio_t *cio) {
-	opj_jp2_box_t box;
-
-	box.init_pos = cio_tell(cio);
-	cio_skip(cio, 4);
-	cio_write(cio, JP2_COLR, 4);		/* COLR */
-
-	cio_write(cio, jp2->meth, 1);		/* METH */
-	cio_write(cio, jp2->precedence, 1);	/* PRECEDENCE */
-	cio_write(cio, jp2->approx, 1);		/* APPROX */
-
-	if(jp2->meth == 2)
-	 jp2->enumcs = 0;
-
-	cio_write(cio, jp2->enumcs, 4);	/* EnumCS */
-
-	box.length = cio_tell(cio) - box.init_pos;
-	cio_seek(cio, box.init_pos);
-	cio_write(cio, box.length, 4);	/* L */
-	cio_seek(cio, box.init_pos + box.length);
-}
-
-static void jp2_free_pclr(opj_jp2_color_t *color)
-{
-    opj_free(color->jp2_pclr->channel_sign);
-    opj_free(color->jp2_pclr->channel_size);
-    opj_free(color->jp2_pclr->entries);
-
-	if(color->jp2_pclr->cmap) opj_free(color->jp2_pclr->cmap);
-
-    opj_free(color->jp2_pclr); color->jp2_pclr = NULL;
-}
-
-static void free_color_data(opj_jp2_color_t *color)
-{
-	if(color->jp2_pclr)
-   {
-	jp2_free_pclr(color);
-   }
-	if(color->jp2_cdef) 
-   {
-	if(color->jp2_cdef->info) opj_free(color->jp2_cdef->info);
-	opj_free(color->jp2_cdef);
-   }
-	if(color->icc_profile_buf) opj_free(color->icc_profile_buf);
-}
-
-static void jp2_apply_pclr(opj_jp2_color_t *color, opj_image_t *image, opj_common_ptr cinfo)
-{
-	opj_image_comp_t *old_comps, *new_comps;
-	unsigned char *channel_size, *channel_sign;
-	unsigned int *entries;
-	opj_jp2_cmap_comp_t *cmap;
-	int *src, *dst;
-	unsigned int j, max;
-	unsigned short i, nr_channels, cmp, pcol;
-	int k, top_k;
-
-	channel_size = color->jp2_pclr->channel_size;
-	channel_sign = color->jp2_pclr->channel_sign;
-	entries = color->jp2_pclr->entries;
-	cmap = color->jp2_pclr->cmap;
-	nr_channels = color->jp2_pclr->nr_channels;
-
-	old_comps = image->comps;
-	new_comps = (opj_image_comp_t*)
-	 opj_malloc(nr_channels * sizeof(opj_image_comp_t));
-
-	for(i = 0; i < nr_channels; ++i)
-   {
-	pcol = cmap[i].pcol; cmp = cmap[i].cmp;
-
-  if( pcol < nr_channels )
-    new_comps[pcol] = old_comps[cmp];
-  else
-    {
-    opj_event_msg(cinfo, EVT_ERROR, "Error with pcol value %d (max: %d). skipping\n", pcol, nr_channels);
-    continue;
-    }
-
-	if(cmap[i].mtyp == 0) /* Direct use */
-  {
-	old_comps[cmp].data = NULL; continue;
-  }
-/* Palette mapping: */
-	new_comps[pcol].data = (int*)
-	 opj_malloc(old_comps[cmp].w * old_comps[cmp].h * sizeof(int));
-	new_comps[pcol].prec = channel_size[i];
-	new_comps[pcol].sgnd = channel_sign[i];
-   }
-	top_k = color->jp2_pclr->nr_entries - 1;
-
-	for(i = 0; i < nr_channels; ++i)
-   {
-/* Direct use: */
-	if(cmap[i].mtyp == 0) continue;
-
-/* Palette mapping: */
-	cmp = cmap[i].cmp; pcol = cmap[i].pcol;
-	src = old_comps[cmp].data; 
-	dst = new_comps[pcol].data;
-	max = new_comps[pcol].w * new_comps[pcol].h;
-
-	for(j = 0; j < max; ++j)
-  {
-/* The index */
-	if((k = src[j]) < 0) k = 0; else if(k > top_k) k = top_k;
-/* The colour */
-	dst[j] = entries[k * nr_channels + pcol];
-  }
-   }
-	max = image->numcomps;
-	for(i = 0; i < max; ++i)
-   {
-	if(old_comps[i].data) opj_free(old_comps[i].data);
-   }
-	opj_free(old_comps);
-	image->comps = new_comps;
-	image->numcomps = nr_channels;
-
-	jp2_free_pclr(color);
-
-}/* apply_pclr() */
-
-static opj_bool jp2_read_pclr(opj_jp2_t *jp2, opj_cio_t *cio,
-	opj_jp2_box_t *box, opj_jp2_color_t *color)
-{
-	opj_jp2_pclr_t *jp2_pclr;
-	unsigned char *channel_size, *channel_sign;
-	unsigned int *entries;
-	unsigned short nr_entries, nr_channels;
-	unsigned short i, j;
-	unsigned char uc;
-
-	OPJ_ARG_NOT_USED(box);
-	OPJ_ARG_NOT_USED(jp2);
-
-/* Part 1, I.5.3.4: 'There shall be at most one Palette box inside
- * a JP2 Header box' :
-*/
-	if(color->jp2_pclr) return OPJ_FALSE;
-
-	nr_entries = (unsigned short)cio_read(cio, 2); /* NE */
-	nr_channels = (unsigned short)cio_read(cio, 1);/* NPC */
-
-	entries = (unsigned int*)
-	 opj_malloc(nr_channels * nr_entries * sizeof(unsigned int));
-	channel_size = (unsigned char*)opj_malloc(nr_channels);
-	channel_sign = (unsigned char*)opj_malloc(nr_channels);
-
-	jp2_pclr = (opj_jp2_pclr_t*)opj_malloc(sizeof(opj_jp2_pclr_t));
-	jp2_pclr->channel_sign = channel_sign;
-	jp2_pclr->channel_size = channel_size;
-	jp2_pclr->entries = entries;
-	jp2_pclr->nr_entries = nr_entries;
-	jp2_pclr->nr_channels = nr_channels;
-	jp2_pclr->cmap = NULL;
-
-	color->jp2_pclr = jp2_pclr;
-
-	for(i = 0; i < nr_channels; ++i)
-   {
-	uc = cio_read(cio, 1); /* Bi */
-	channel_size[i] = (uc & 0x7f) + 1;
-	channel_sign[i] = (uc & 0x80)?1:0;
-   }
-
-	for(j = 0; j < nr_entries; ++j)
-   {
-	for(i = 0; i < nr_channels; ++i)
-  {
-/* Cji */
-	*entries++ = cio_read(cio, (channel_size[i]+7)>>3);
-  }
-   }
-
-	return OPJ_TRUE;
-}/* jp2_read_pclr() */
-
-static opj_bool jp2_read_cmap(opj_jp2_t *jp2, opj_cio_t *cio,
-	opj_jp2_box_t *box, opj_jp2_color_t *color)
-{
-	opj_jp2_cmap_comp_t *cmap;
-	unsigned short i, nr_channels;
-
-	OPJ_ARG_NOT_USED(box);
-	OPJ_ARG_NOT_USED(jp2);
-
-/* Need nr_channels: */
-	if(color->jp2_pclr == NULL) return OPJ_FALSE;
-
-/* Part 1, I.5.3.5: 'There shall be at most one Component Mapping box
- * inside a JP2 Header box' :
-*/
-	if(color->jp2_pclr->cmap) return OPJ_FALSE;
-
-	nr_channels = color->jp2_pclr->nr_channels;
-	cmap = (opj_jp2_cmap_comp_t*)
-	 opj_malloc(nr_channels * sizeof(opj_jp2_cmap_comp_t));
-
-	for(i = 0; i < nr_channels; ++i)
-   {
-	cmap[i].cmp = (unsigned short)cio_read(cio, 2);
-	cmap[i].mtyp = cio_read(cio, 1);
-	cmap[i].pcol = cio_read(cio, 1);
-
-   }
-	color->jp2_pclr->cmap = cmap;
-
-	return OPJ_TRUE;
-}/* jp2_read_cmap() */
-
-static void jp2_apply_cdef(opj_image_t *image, opj_jp2_color_t *color)
-{
-	opj_jp2_cdef_info_t *info;
-	int color_space;
-	unsigned short i, n, cn, typ, asoc, acn;
-
-	color_space = image->color_space;
-	info = color->jp2_cdef->info;
-	n = color->jp2_cdef->n;
-
-	for(i = 0; i < n; ++i)
-   {
-/* WATCH: acn = asoc - 1 ! */
-	if((asoc = info[i].asoc) == 0) continue;
-
-	cn = info[i].cn; typ = info[i].typ; acn = asoc - 1;
-
-	if(cn != acn)
-  {
-	opj_image_comp_t saved;
-
-	memcpy(&saved, &image->comps[cn], sizeof(opj_image_comp_t));
-	memcpy(&image->comps[cn], &image->comps[acn], sizeof(opj_image_comp_t));
-	memcpy(&image->comps[acn], &saved, sizeof(opj_image_comp_t));
-
-	info[i].asoc = cn + 1;
-	info[acn].asoc = info[acn].cn + 1;
-  }
-   }
-	if(color->jp2_cdef->info) opj_free(color->jp2_cdef->info);
-
-	opj_free(color->jp2_cdef); color->jp2_cdef = NULL;
-
-}/* jp2_apply_cdef() */
-
-static opj_bool jp2_read_cdef(opj_jp2_t *jp2, opj_cio_t *cio,
-	opj_jp2_box_t *box, opj_jp2_color_t *color)
-{
-	opj_jp2_cdef_info_t *info;
-	unsigned short i, n;
-
-	OPJ_ARG_NOT_USED(box);
-	OPJ_ARG_NOT_USED(jp2);
-
-/* Part 1, I.5.3.6: 'The shall be at most one Channel Definition box
- * inside a JP2 Header box.' 
-*/
-	if(color->jp2_cdef) return OPJ_FALSE;
-
-	if((n = (unsigned short)cio_read(cio, 2)) == 0) return OPJ_FALSE; /* szukw000: FIXME */
-
-	info = (opj_jp2_cdef_info_t*)
-	 opj_malloc(n * sizeof(opj_jp2_cdef_info_t));
-
-	color->jp2_cdef = (opj_jp2_cdef_t*)opj_malloc(sizeof(opj_jp2_cdef_t));
-	color->jp2_cdef->info = info;
-	color->jp2_cdef->n = n;
-
-	for(i = 0; i < n; ++i)
-   {
-	info[i].cn = (unsigned short)cio_read(cio, 2);
-	info[i].typ = (unsigned short)cio_read(cio, 2);
-	info[i].asoc = (unsigned short)cio_read(cio, 2);
-
-   }
-	return OPJ_TRUE;
-}/* jp2_read_cdef() */
-
-static opj_bool jp2_read_colr(opj_jp2_t *jp2, opj_cio_t *cio,
-	opj_jp2_box_t *box, opj_jp2_color_t *color) 
-{
-	int skip_len;
-    opj_common_ptr cinfo;
-
-/* Part 1, I.5.3.3 : 'A conforming JP2 reader shall ignore all Colour
- * Specification boxes after the first.' 
-*/
-	if(color->jp2_has_colr) return OPJ_FALSE;
-
-	cinfo = jp2->cinfo;
-
-	jp2->meth = cio_read(cio, 1);		/* METH */
-	jp2->precedence = cio_read(cio, 1);	/* PRECEDENCE */
-	jp2->approx = cio_read(cio, 1);		/* APPROX */
-
-	if (jp2->meth == 1) 
-   {
-	jp2->enumcs = cio_read(cio, 4);	/* EnumCS */
-   } 
-	else
-	if (jp2->meth == 2) 
-   {
-/* skip PROFILE */
-	skip_len = box->init_pos + box->length - cio_tell(cio);
-	if (skip_len < 0) 
-  {
-	opj_event_msg(cinfo, EVT_ERROR, "Error with COLR box size\n");
-	return OPJ_FALSE;
-  }
-	if(skip_len > 0)
-  {
-	unsigned char *start;
-
-	start = cio_getbp(cio);
-	color->icc_profile_buf = (unsigned char*)opj_malloc(skip_len);
-	color->icc_profile_len = skip_len;
-
-	cio_skip(cio, box->init_pos + box->length - cio_tell(cio));
-
-	memcpy(color->icc_profile_buf, start, skip_len);
-  }
-   }
-
-	if (cio_tell(cio) - box->init_pos != box->length) 
-   {
-	opj_event_msg(cinfo, EVT_ERROR, "Error with COLR Box\n");
-	return OPJ_FALSE;
-   }
-	color->jp2_has_colr = 1;
-
-	return OPJ_TRUE;
-}/* jp2_read_colr() */
-
-opj_bool jp2_read_jp2h(opj_jp2_t *jp2, opj_cio_t *cio, opj_jp2_color_t *color) 
-{
-	opj_jp2_box_t box;
-	int jp2h_end;
-
-	opj_common_ptr cinfo = jp2->cinfo;
-
-  if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE;
-  do {
-    if (JP2_JP2H != box.type) 
-      {
-      if (box.type == JP2_JP2C) 
-        {
-        opj_event_msg(cinfo, EVT_ERROR, "Expected JP2H Marker\n");
-        return OPJ_FALSE;
-        }
-      cio_skip(cio, box.length - 8);
-
-      if(cio->bp >= cio->end) return OPJ_FALSE;
-
-      if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE;
-      }
-  } while(JP2_JP2H != box.type);
-
-	if (!jp2_read_ihdr(jp2, cio))
-		return OPJ_FALSE;
-	jp2h_end = box.init_pos + box.length;
-
-  if (jp2->bpc == 255) 
-    {
-    if (!jp2_read_bpcc(jp2, cio))
-      return OPJ_FALSE;
-    }
-  if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE;
-
-  while(cio_tell(cio) < jp2h_end)
-    {
-    if(box.type == JP2_COLR)
-      {
-      if( !jp2_read_colr(jp2, cio, &box, color))
-        {
-        cio_seek(cio, box.init_pos + 8);
-        cio_skip(cio, box.length - 8);
-        }
-      if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE;
-      continue;
-      }
-    if(box.type == JP2_CDEF && !jp2->ignore_pclr_cmap_cdef)
-      {
-      if( !jp2_read_cdef(jp2, cio, &box, color))
-        {
-        cio_seek(cio, box.init_pos + 8);
-        cio_skip(cio, box.length - 8);
-        }
-      if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE;
-      continue;
-      }
-    if(box.type == JP2_PCLR && !jp2->ignore_pclr_cmap_cdef)
-      {
-      if( !jp2_read_pclr(jp2, cio, &box, color))
-        {
-        cio_seek(cio, box.init_pos + 8);
-        cio_skip(cio, box.length - 8);
-        }
-      if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE;
-      continue;
-      }
-    if(box.type == JP2_CMAP && !jp2->ignore_pclr_cmap_cdef)
-      {
-      if( !jp2_read_cmap(jp2, cio, &box, color))
-        {
-        cio_seek(cio, box.init_pos + 8);
-        cio_skip(cio, box.length - 8);
-        }
-      if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE;
-      continue;
-      }
-    cio_seek(cio, box.init_pos + 8);
-    cio_skip(cio, box.length - 8);
-    if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE;
-
-    }/* while(cio_tell(cio) < box_end) */
-
-  cio_seek(cio, jp2h_end);
-
-  /* Part 1, I.5.3.3 : 'must contain at least one' */
-  return (color->jp2_has_colr == 1);
-
-}/* jp2_read_jp2h() */
-
-opj_image_t* opj_jp2_decode(opj_jp2_t *jp2, opj_cio_t *cio, 
-	opj_codestream_info_t *cstr_info) 
-{
-	opj_common_ptr cinfo;
-	opj_image_t *image = NULL;
-	opj_jp2_color_t color;
-
-	if(!jp2 || !cio) 
-   {
-	return NULL;
-   }
-	memset(&color, 0, sizeof(opj_jp2_color_t));
-	cinfo = jp2->cinfo;
-
-/* JP2 decoding */
-	if(!jp2_read_struct(jp2, cio, &color)) 
-   {
-	free_color_data(&color);
-	opj_event_msg(cinfo, EVT_ERROR, "Failed to decode jp2 structure\n");
-	return NULL;
-   }
-
-/* J2K decoding */
-	image = j2k_decode(jp2->j2k, cio, cstr_info);
-
-	if(!image) 
-   {
-	free_color_data(&color);
-	opj_event_msg(cinfo, EVT_ERROR, "Failed to decode J2K image\n");
-	return NULL;
-   }
-   
-    if (!jp2->ignore_pclr_cmap_cdef){
-
-    /* Set Image Color Space */
-	if (jp2->enumcs == 16)
-		image->color_space = CLRSPC_SRGB;
-	else if (jp2->enumcs == 17)
-		image->color_space = CLRSPC_GRAY;
-	else if (jp2->enumcs == 18)
-		image->color_space = CLRSPC_SYCC;
-	else
-		image->color_space = CLRSPC_UNKNOWN;
-
-	if(color.jp2_cdef)
-   {
-	jp2_apply_cdef(image, &color);
-   }
-	if(color.jp2_pclr)
-   {
-/* Part 1, I.5.3.4: Either both or none : */
-	if( !color.jp2_pclr->cmap) 
-	 jp2_free_pclr(&color);
-	else
-	 jp2_apply_pclr(&color, image, cinfo);
-   }
-	if(color.icc_profile_buf)
-   {
-	image->icc_profile_buf = color.icc_profile_buf;
-	color.icc_profile_buf = NULL;
-	image->icc_profile_len = color.icc_profile_len;
-   }
-   }
-   
-	return image;
-
-}/* opj_jp2_decode() */
-
-
-void jp2_write_jp2h(opj_jp2_t *jp2, opj_cio_t *cio) {
-	opj_jp2_box_t box;
-
-	box.init_pos = cio_tell(cio);
-	cio_skip(cio, 4);
-	cio_write(cio, JP2_JP2H, 4);	/* JP2H */
-
-	jp2_write_ihdr(jp2, cio);
-
-	if (jp2->bpc == 255) {
-		jp2_write_bpcc(jp2, cio);
-	}
-	jp2_write_colr(jp2, cio);
-
-	box.length = cio_tell(cio) - box.init_pos;
-	cio_seek(cio, box.init_pos);
-	cio_write(cio, box.length, 4);	/* L */
-	cio_seek(cio, box.init_pos + box.length);
-}
-
-static void jp2_write_ftyp(opj_jp2_t *jp2, opj_cio_t *cio) {
-	unsigned int i;
-	opj_jp2_box_t box;
-
-	box.init_pos = cio_tell(cio);
-	cio_skip(cio, 4);
-	cio_write(cio, JP2_FTYP, 4);		/* FTYP */
-
-	cio_write(cio, jp2->brand, 4);		/* BR */
-	cio_write(cio, jp2->minversion, 4);	/* MinV */
-
-	for (i = 0; i < jp2->numcl; i++) {
-		cio_write(cio, jp2->cl[i], 4);	/* CL */
-	}
-
-	box.length = cio_tell(cio) - box.init_pos;
-	cio_seek(cio, box.init_pos);
-	cio_write(cio, box.length, 4);	/* L */
-	cio_seek(cio, box.init_pos + box.length);
-}
-
-static opj_bool jp2_read_ftyp(opj_jp2_t *jp2, opj_cio_t *cio) {
-	int i;
-	opj_jp2_box_t box;
-
-	opj_common_ptr cinfo = jp2->cinfo;
-
-  if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) {
-    opj_event_msg(cinfo, EVT_ERROR, "Failed to read boxhdr\n");
-    return OPJ_FALSE;
-  }
-	if (JP2_FTYP != box.type) {
-		opj_event_msg(cinfo, EVT_ERROR, "Expected FTYP Marker\n");
-		return OPJ_FALSE;
-	}
-
-	jp2->brand = cio_read(cio, 4);		/* BR */
-	jp2->minversion = cio_read(cio, 4);	/* MinV */
-	jp2->numcl = (box.length - 16) / 4;
-	jp2->cl = (unsigned int *) opj_malloc(jp2->numcl * sizeof(unsigned int));
-
-	for (i = 0; i < (int)jp2->numcl; i++) {
-		jp2->cl[i] = cio_read(cio, 4);	/* CLi */
-	}
-
-	if (cio_tell(cio) - box.init_pos != box.length) {
-		opj_event_msg(cinfo, EVT_ERROR, "Error with FTYP Box\n");
-		return OPJ_FALSE;
-	}
-
-	return OPJ_TRUE;
-}
-
-static int jp2_write_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) {
-	unsigned int j2k_codestream_offset, j2k_codestream_length;
-	opj_jp2_box_t box;
-
-	opj_j2k_t *j2k = jp2->j2k;
-
-	box.init_pos = cio_tell(cio);
-	cio_skip(cio, 4);
-	cio_write(cio, JP2_JP2C, 4);	/* JP2C */
-
-	/* J2K encoding */
-	j2k_codestream_offset = cio_tell(cio);
-	if(!j2k_encode(j2k, cio, image, cstr_info)) {
-		opj_event_msg(j2k->cinfo, EVT_ERROR, "Failed to encode image\n");
-		return 0;
-	}
-	j2k_codestream_length = cio_tell(cio) - j2k_codestream_offset;
-
-	jp2->j2k_codestream_offset = j2k_codestream_offset;
-	jp2->j2k_codestream_length = j2k_codestream_length;
-
-	box.length = 8 + jp2->j2k_codestream_length;
-	cio_seek(cio, box.init_pos);
-	cio_write(cio, box.length, 4);	/* L */
-	cio_seek(cio, box.init_pos + box.length);
-
-	return box.length;
-}
-
-static opj_bool jp2_read_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, unsigned int *j2k_codestream_length, unsigned int *j2k_codestream_offset) {
-	opj_jp2_box_t box;
-
-	opj_common_ptr cinfo = jp2->cinfo;
-
-  if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) {
-    opj_event_msg(cinfo, EVT_ERROR, "Failed to read boxhdr\n");
-    return OPJ_FALSE;
-  }
-	do {
-		if(JP2_JP2C != box.type) {
-			cio_skip(cio, box.length - 8);
-			if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE;
-		}
-	} while(JP2_JP2C != box.type);
-
-	*j2k_codestream_offset = cio_tell(cio);
-	*j2k_codestream_length = box.length - 8;
-
-	return OPJ_TRUE;
-}
-
-static void jp2_write_jp(opj_cio_t *cio) {
-	opj_jp2_box_t box;
-
-	box.init_pos = cio_tell(cio);
-	cio_skip(cio, 4);
-	cio_write(cio, JP2_JP, 4);		/* JP2 signature */
-	cio_write(cio, 0x0d0a870a, 4);
-
-	box.length = cio_tell(cio) - box.init_pos;
-	cio_seek(cio, box.init_pos);
-	cio_write(cio, box.length, 4);	/* L */
-	cio_seek(cio, box.init_pos + box.length);
-}
-
-static opj_bool jp2_read_jp(opj_jp2_t *jp2, opj_cio_t *cio) {
-	opj_jp2_box_t box;
-
-	opj_common_ptr cinfo = jp2->cinfo;
-
-  if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) {
-    opj_event_msg(cinfo, EVT_ERROR, "Failed to read boxhdr\n");
-    return OPJ_FALSE;
-  }
-	if (JP2_JP != box.type) {
-		opj_event_msg(cinfo, EVT_ERROR, "Expected JP Marker\n");
-		return OPJ_FALSE;
-	}
-	if (0x0d0a870a != cio_read(cio, 4)) {
-		opj_event_msg(cinfo, EVT_ERROR, "Error with JP Marker\n");
-		return OPJ_FALSE;
-	}
-	if (cio_tell(cio) - box.init_pos != box.length) {
-		opj_event_msg(cinfo, EVT_ERROR, "Error with JP Box size\n");
-		return OPJ_FALSE;
-	}
-
-	return OPJ_TRUE;
-}
-
-
-static opj_bool jp2_read_struct(opj_jp2_t *jp2, opj_cio_t *cio,
-	opj_jp2_color_t *color) {
-	if (!jp2_read_jp(jp2, cio))
-		return OPJ_FALSE;
-	if (!jp2_read_ftyp(jp2, cio))
-		return OPJ_FALSE;
-	if (!jp2_read_jp2h(jp2, cio, color))
-		return OPJ_FALSE;
-	if (!jp2_read_jp2c(jp2, cio, &jp2->j2k_codestream_length, &jp2->j2k_codestream_offset))
-		return OPJ_FALSE;
-	
-	return OPJ_TRUE;
-}
-
-
-static int write_fidx( int offset_jp2c, int length_jp2c, int offset_idx, int length_idx, opj_cio_t *cio)
-{  
-  int len, lenp;
-  
-  lenp = cio_tell( cio);
-  cio_skip( cio, 4);              /* L [at the end] */
-  cio_write( cio, JPIP_FIDX, 4);  /* IPTR           */
-  
-  write_prxy( offset_jp2c, length_jp2c, offset_idx, length_idx, cio);
-
-  len = cio_tell( cio)-lenp;
-  cio_seek( cio, lenp);
-  cio_write( cio, len, 4);        /* L              */
-  cio_seek( cio, lenp+len);  
-
-  return len;
-}
-
-static void write_prxy( int offset_jp2c, int length_jp2c, int offset_idx, int length_idx, opj_cio_t *cio)
-{
-  int len, lenp;
-
-  lenp = cio_tell( cio);
-  cio_skip( cio, 4);              /* L [at the end] */
-  cio_write( cio, JPIP_PRXY, 4);  /* IPTR           */
-  
-  cio_write( cio, offset_jp2c, 8); /* OOFF           */
-  cio_write( cio, length_jp2c, 4); /* OBH part 1     */
-  cio_write( cio, JP2_JP2C, 4);        /* OBH part 2     */
-  
-  cio_write( cio, 1,1);           /* NI             */
-
-  cio_write( cio, offset_idx, 8);  /* IOFF           */
-  cio_write( cio, length_idx, 4);  /* IBH part 1     */
-  cio_write( cio, JPIP_CIDX, 4);   /* IBH part 2     */
-
-  len = cio_tell( cio)-lenp;
-  cio_seek( cio, lenp);
-  cio_write( cio, len, 4);        /* L              */
-  cio_seek( cio, lenp+len);
-}
-
-static void write_iptr( int offset, int length, opj_cio_t *cio)
-{
-  int len, lenp;
-  
-  lenp = cio_tell( cio);
-  cio_skip( cio, 4);              /* L [at the end] */
-  cio_write( cio, JPIP_IPTR, 4);  /* IPTR           */
-  
-  cio_write( cio, offset, 8);
-  cio_write( cio, length, 8);
-
-  len = cio_tell( cio)-lenp;
-  cio_seek( cio, lenp);
-  cio_write( cio, len, 4);        /* L             */
-  cio_seek( cio, lenp+len);
-}
-
-
-/* ----------------------------------------------------------------------- */
-/* JP2 decoder interface                                             */
-/* ----------------------------------------------------------------------- */
-
-opj_jp2_t* jp2_create_decompress(opj_common_ptr cinfo) {
-	opj_jp2_t *jp2 = (opj_jp2_t*) opj_calloc(1, sizeof(opj_jp2_t));
-	if(jp2) {
-		jp2->cinfo = cinfo;
-		/* create the J2K codec */
-		jp2->j2k = j2k_create_decompress(cinfo);
-		if(jp2->j2k == NULL) {
-			jp2_destroy_decompress(jp2);
-			return NULL;
-		}
-	}
-	return jp2;
-}
-
-void jp2_destroy_decompress(opj_jp2_t *jp2) {
-	if(jp2) {
-		/* destroy the J2K codec */
-		j2k_destroy_decompress(jp2->j2k);
-
-		if(jp2->comps) {
-			opj_free(jp2->comps);
-		}
-		if(jp2->cl) {
-			opj_free(jp2->cl);
-		}
-		opj_free(jp2);
-	}
-}
-
-void jp2_setup_decoder(opj_jp2_t *jp2, opj_dparameters_t *parameters) {
-	/* setup the J2K codec */
-	j2k_setup_decoder(jp2->j2k, parameters);
-	/* further JP2 initializations go here */
-	jp2->ignore_pclr_cmap_cdef = parameters->flags & OPJ_DPARAMETERS_IGNORE_PCLR_CMAP_CDEF_FLAG;
-}
-
-/* ----------------------------------------------------------------------- */
-/* JP2 encoder interface                                             */
-/* ----------------------------------------------------------------------- */
-
-opj_jp2_t* jp2_create_compress(opj_common_ptr cinfo) {
-	opj_jp2_t *jp2 = (opj_jp2_t*)opj_malloc(sizeof(opj_jp2_t));
-	if(jp2) {
-		jp2->cinfo = cinfo;
-		/* create the J2K codec */
-		jp2->j2k = j2k_create_compress(cinfo);
-		if(jp2->j2k == NULL) {
-			jp2_destroy_compress(jp2);
-			return NULL;
-		}
-	}
-	return jp2;
-}
-
-void jp2_destroy_compress(opj_jp2_t *jp2) {
-	if(jp2) {
-		/* destroy the J2K codec */
-		j2k_destroy_compress(jp2->j2k);
-
-		if(jp2->comps) {
-			opj_free(jp2->comps);
-		}
-		if(jp2->cl) {
-			opj_free(jp2->cl);
-		}
-		opj_free(jp2);
-	}
-}
-
-void jp2_setup_encoder(opj_jp2_t *jp2, opj_cparameters_t *parameters, opj_image_t *image) {
-	int i;
-	int depth_0, sign;
-
-	if(!jp2 || !parameters || !image)
-		return;
-
-	/* setup the J2K codec */
-	/* ------------------- */
-
-	/* Check if number of components respects standard */
-	if (image->numcomps < 1 || image->numcomps > 16384) {
-		opj_event_msg(jp2->cinfo, EVT_ERROR, "Invalid number of components specified while setting up JP2 encoder\n");
-		return;
-	}
-
-	j2k_setup_encoder(jp2->j2k, parameters, image);
-
-	/* setup the JP2 codec */
-	/* ------------------- */
-	
-	/* Profile box */
-
-	jp2->brand = JP2_JP2;	/* BR */
-	jp2->minversion = 0;	/* MinV */
-	jp2->numcl = 1;
-	jp2->cl = (unsigned int*) opj_malloc(jp2->numcl * sizeof(unsigned int));
-	jp2->cl[0] = JP2_JP2;	/* CL0 : JP2 */
-
-	/* Image Header box */
-
-	jp2->numcomps = image->numcomps;	/* NC */
-	jp2->comps = (opj_jp2_comps_t*) opj_malloc(jp2->numcomps * sizeof(opj_jp2_comps_t));
-	jp2->h = image->y1 - image->y0;		/* HEIGHT */
-	jp2->w = image->x1 - image->x0;		/* WIDTH */
-	/* BPC */
-	depth_0 = image->comps[0].prec - 1;
-	sign = image->comps[0].sgnd;
-	jp2->bpc = depth_0 + (sign << 7);
-	for (i = 1; i < image->numcomps; i++) {
-		int depth = image->comps[i].prec - 1;
-		sign = image->comps[i].sgnd;
-		if (depth_0 != depth)
-			jp2->bpc = 255;
-	}
-	jp2->C = 7;			/* C : Always 7 */
-	jp2->UnkC = 0;		/* UnkC, colorspace specified in colr box */
-	jp2->IPR = 0;		/* IPR, no intellectual property */
-	
-	/* BitsPerComponent box */
-
-	for (i = 0; i < image->numcomps; i++) {
-		jp2->comps[i].bpcc = image->comps[i].prec - 1 + (image->comps[i].sgnd << 7);
-	}
-	jp2->meth = 1;
-	if (image->color_space == 1)
-		jp2->enumcs = 16;	/* sRGB as defined by IEC 61966-2.1 */
-	else if (image->color_space == 2)
-		jp2->enumcs = 17;	/* greyscale */
-	else if (image->color_space == 3)
-		jp2->enumcs = 18;	/* YUV */
-	jp2->precedence = 0;	/* PRECEDENCE */
-	jp2->approx = 0;		/* APPROX */
-	
-	jp2->jpip_on = parameters->jpip_on;
-}
-
-opj_bool opj_jp2_encode(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) {
-
-	int pos_iptr, pos_cidx, pos_jp2c, len_jp2c, len_cidx, end_pos, pos_fidx, len_fidx;
-	pos_jp2c = pos_iptr = -1; /* remove a warning */
-
-	/* JP2 encoding */
-
-	/* JPEG 2000 Signature box */
-	jp2_write_jp(cio);
-	/* File Type box */
-	jp2_write_ftyp(jp2, cio);
-	/* JP2 Header box */
-	jp2_write_jp2h(jp2, cio);
-
-	if( jp2->jpip_on){
-	  pos_iptr = cio_tell( cio);
-	  cio_skip( cio, 24); /* IPTR further ! */
-	  
-	  pos_jp2c = cio_tell( cio);
-	}
-
-	/* J2K encoding */
-	if(!(len_jp2c = jp2_write_jp2c( jp2, cio, image, cstr_info))){
-	    opj_event_msg(jp2->cinfo, EVT_ERROR, "Failed to encode image\n");
-	    return OPJ_FALSE;
-	}
-
-	if( jp2->jpip_on){
-	  pos_cidx = cio_tell( cio);
-	  
-	  len_cidx = write_cidx( pos_jp2c+8, cio, image, *cstr_info, len_jp2c-8);
-	  
-	  pos_fidx = cio_tell( cio);
-	  len_fidx = write_fidx( pos_jp2c, len_jp2c, pos_cidx, len_cidx, cio);
-	  
-	  end_pos = cio_tell( cio);
-	  
-	  cio_seek( cio, pos_iptr);
-	  write_iptr( pos_fidx, len_fidx, cio);
-	  
-	  cio_seek( cio, end_pos);
-	}
-
-	return OPJ_TRUE;
-}
+/*
+ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2007, Professor Benoit Macq
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2010-2011, Kaori Hagihara
+ * Copyright (c) 2008;2011-2012, Centre National d'Etudes Spatiales (CNES), France 
+ * Copyright (c) 2012, CS Systemes d'Information, France
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "opj_includes.h"
+
+/** @defgroup JP2 JP2 - JPEG-2000 file format reader/writer */
+/*@{*/
+
+#define OPJ_BOX_SIZE	1024
+
+/** @name Local static functions */
+/*@{*/
+
+/*static void jp2_write_url(opj_cio_t *cio, char *Idx_file);*/
+
+/**
+ * Reads a IHDR box - Image Header box
+ *
+ * @param	p_image_header_data			pointer to actual data (already read from file)
+ * @param	jp2							the jpeg2000 file codec.
+ * @param	p_image_header_size			the size of the image header
+ * @param	p_manager					the user event manager.
+ *
+ * @return	true if the image header is valid, false else.
+ */
+static OPJ_BOOL opj_jp2_read_ihdr(  opj_jp2_t *jp2,
+                                    OPJ_BYTE *p_image_header_data,
+                                    OPJ_UINT32 p_image_header_size,
+                                    opj_event_mgr_t * p_manager );
+
+/**
+ * Writes the Image Header box - Image Header box.
+ *
+ * @param jp2					jpeg2000 file codec.
+ * @param p_nb_bytes_written	pointer to store the nb of bytes written by the function.
+ *
+ * @return	the data being copied.
+*/
+static OPJ_BYTE * opj_jp2_write_ihdr(opj_jp2_t *jp2,
+                                     OPJ_UINT32 * p_nb_bytes_written );
+
+/**
+ * Writes the Bit per Component box.
+ *
+ * @param	jp2						jpeg2000 file codec.
+ * @param	p_nb_bytes_written		pointer to store the nb of bytes written by the function.
+ *
+ * @return	the data being copied.
+*/
+static OPJ_BYTE * opj_jp2_write_bpcc(	opj_jp2_t *jp2,
+								        OPJ_UINT32 * p_nb_bytes_written );
+
+/**
+ * Reads a Bit per Component box.
+ *
+ * @param	p_bpc_header_data			pointer to actual data (already read from file)
+ * @param	jp2							the jpeg2000 file codec.
+ * @param	p_bpc_header_size			the size of the bpc header
+ * @param	p_manager					the user event manager.
+ *
+ * @return	true if the bpc header is valid, fale else.
+ */
+static OPJ_BOOL opj_jp2_read_bpcc(  opj_jp2_t *jp2,
+                                    OPJ_BYTE * p_bpc_header_data,
+                                    OPJ_UINT32 p_bpc_header_size,
+                                    opj_event_mgr_t * p_manager );
+
+static OPJ_BOOL opj_jp2_read_cdef(	opj_jp2_t * jp2,
+                                    OPJ_BYTE * p_cdef_header_data,
+									OPJ_UINT32 p_cdef_header_size,
+									opj_event_mgr_t * p_manager );
+
+static void opj_jp2_apply_cdef(opj_image_t *image, opj_jp2_color_t *color);
+
+/**
+ * Writes the Colour Specification box.
+ *
+ * @param jp2					jpeg2000 file codec.
+ * @param p_nb_bytes_written	pointer to store the nb of bytes written by the function.
+ *
+ * @return	the data being copied.
+*/
+static OPJ_BYTE * opj_jp2_write_colr(   opj_jp2_t *jp2,
+									    OPJ_UINT32 * p_nb_bytes_written );
+
+/**
+ * Writes a FTYP box - File type box
+ *
+ * @param	cio			the stream to write data to.
+ * @param	jp2			the jpeg2000 file codec.
+ * @param	p_manager	the user event manager.
+ *
+ * @return	true if writing was successful.
+ */
+static OPJ_BOOL opj_jp2_write_ftyp(	opj_jp2_t *jp2,
+									opj_stream_private_t *cio,
+									opj_event_mgr_t * p_manager );
+
+/**
+ * Reads a a FTYP box - File type box
+ *
+ * @param	p_header_data	the data contained in the FTYP box.
+ * @param	jp2				the jpeg2000 file codec.
+ * @param	p_header_size	the size of the data contained in the FTYP box.
+ * @param	p_manager		the user event manager.
+ *
+ * @return true if the FTYP box is valid.
+ */
+static OPJ_BOOL opj_jp2_read_ftyp(	opj_jp2_t *jp2,
+									OPJ_BYTE * p_header_data,
+									OPJ_UINT32 p_header_size,
+									opj_event_mgr_t * p_manager );
+
+OPJ_BOOL opj_jp2_skip_jp2c(	opj_jp2_t *jp2,
+						    opj_stream_private_t *cio,
+						    opj_event_mgr_t * p_manager );
+
+/**
+ * Reads the Jpeg2000 file Header box - JP2 Header box (warning, this is a super box).
+ *
+ * @param	p_header_data	the data contained in the file header box.
+ * @param	jp2				the jpeg2000 file codec.
+ * @param	p_header_size	the size of the data contained in the file header box.
+ * @param	p_manager		the user event manager.
+ *
+ * @return true if the JP2 Header box was successfully reconized.
+*/
+static OPJ_BOOL opj_jp2_read_jp2h(  opj_jp2_t *jp2,
+                                    OPJ_BYTE *p_header_data,
+                                    OPJ_UINT32 p_header_size,
+                                    opj_event_mgr_t * p_manager );
+
+/**
+ * Writes the Jpeg2000 codestream Header box - JP2C Header box. This function must be called AFTER the coding has been done.
+ *
+ * @param	cio			the stream to write data to.
+ * @param	jp2			the jpeg2000 file codec.
+ * @param	p_manager	user event manager.
+ *
+ * @return true if writing was successful.
+*/
+static OPJ_BOOL opj_jp2_write_jp2c(	opj_jp2_t *jp2,
+								    opj_stream_private_t *cio,
+								    opj_event_mgr_t * p_manager );
+
+#ifdef USE_JPIP
+/**
+ * Write index Finder box
+ * @param cio     the stream to write to.
+ * @param	jp2			the jpeg2000 file codec.
+ * @param	p_manager	user event manager.
+*/
+static OPJ_BOOL opj_jpip_write_iptr(	opj_jp2_t *jp2,
+								    opj_stream_private_t *cio,
+								    opj_event_mgr_t * p_manager );
+
+/**
+ * Write index Finder box
+ * @param cio     the stream to write to.
+ * @param	jp2			the jpeg2000 file codec.
+ * @param	p_manager	user event manager.
+ */
+static OPJ_BOOL opj_jpip_write_cidx(opj_jp2_t *jp2,
+  opj_stream_private_t *cio,
+  opj_event_mgr_t * p_manager );
+
+/**
+ * Write file Index (superbox)
+ * @param cio     the stream to write to.
+ * @param	jp2			the jpeg2000 file codec.
+ * @param	p_manager	user event manager.
+ */
+static OPJ_BOOL opj_jpip_write_fidx(opj_jp2_t *jp2,
+  opj_stream_private_t *cio,
+  opj_event_mgr_t * p_manager );
+#endif /* USE_JPIP */
+
+/**
+ * Reads a jpeg2000 file signature box.
+ *
+ * @param	p_header_data	the data contained in the signature box.
+ * @param	jp2				the jpeg2000 file codec.
+ * @param	p_header_size	the size of the data contained in the signature box.
+ * @param	p_manager		the user event manager.
+ *
+ * @return true if the file signature box is valid.
+ */
+static OPJ_BOOL opj_jp2_read_jp(opj_jp2_t *jp2,
+                                OPJ_BYTE * p_header_data,
+                                OPJ_UINT32 p_header_size,
+                                opj_event_mgr_t * p_manager);
+
+/**
+ * Writes a jpeg2000 file signature box.
+ *
+ * @param cio the stream to write data to.
+ * @param	jp2			the jpeg2000 file codec.
+ * @param p_manager the user event manager.
+ *
+ * @return true if writing was successful.
+ */
+static OPJ_BOOL opj_jp2_write_jp(	opj_jp2_t *jp2,
+			    	        	    opj_stream_private_t *cio,
+				            		opj_event_mgr_t * p_manager );
+
+/**
+Apply collected palette data
+ at param color Collector for profile, cdef and pclr data
+ at param image
+*/
+static void opj_jp2_apply_pclr(opj_image_t *image, opj_jp2_color_t *color);
+
+static void opj_jp2_free_pclr(opj_jp2_color_t *color);
+
+/**
+ * Collect palette data
+ *
+ * @param jp2 JP2 handle
+ * @param p_pclr_header_data    FIXME DOC
+ * @param p_pclr_header_size    FIXME DOC
+ * @param p_manager
+ *
+ * @return Returns true if successful, returns false otherwise
+*/
+static OPJ_BOOL opj_jp2_read_pclr(	opj_jp2_t *jp2,
+                                    OPJ_BYTE * p_pclr_header_data,
+                                    OPJ_UINT32 p_pclr_header_size,
+                                    opj_event_mgr_t * p_manager );
+
+/**
+ * Collect component mapping data
+ *
+ * @param jp2                 JP2 handle
+ * @param p_cmap_header_data  FIXME DOC
+ * @param p_cmap_header_size  FIXME DOC
+ * @param p_manager           FIXME DOC
+ *
+ * @return Returns true if successful, returns false otherwise
+*/
+
+static OPJ_BOOL opj_jp2_read_cmap(	opj_jp2_t * jp2,
+                                    OPJ_BYTE * p_cmap_header_data,
+                                    OPJ_UINT32 p_cmap_header_size,
+                                    opj_event_mgr_t * p_manager );
+
+/**
+ * Reads the Color Specification box.
+ *
+ * @param	p_colr_header_data			pointer to actual data (already read from file)
+ * @param	jp2							the jpeg2000 file codec.
+ * @param	p_colr_header_size			the size of the color header
+ * @param	p_manager					the user event manager.
+ *
+ * @return	true if the bpc header is valid, fale else.
+*/
+static OPJ_BOOL opj_jp2_read_colr(  opj_jp2_t *jp2,
+                                    OPJ_BYTE * p_colr_header_data,
+                                    OPJ_UINT32 p_colr_header_size,
+                                    opj_event_mgr_t * p_manager );
+
+/*@}*/
+
+/*@}*/
+
+/**
+ * Sets up the procedures to do on writing header after the codestream.
+ * Developpers wanting to extend the library can add their own writing procedures.
+ */
+static void opj_jp2_setup_end_header_writing (opj_jp2_t *jp2);
+
+/**
+ * Sets up the procedures to do on reading header after the codestream.
+ * Developpers wanting to extend the library can add their own writing procedures.
+ */
+static void opj_jp2_setup_end_header_reading (opj_jp2_t *jp2);
+
+/**
+ * Reads a jpeg2000 file header structure.
+ *
+ * @param jp2 the jpeg2000 file header structure.
+ * @param stream the stream to read data from.
+ * @param p_manager the user event manager.
+ *
+ * @return true if the box is valid.
+ */
+static OPJ_BOOL opj_jp2_read_header_procedure(  opj_jp2_t *jp2,
+                                                opj_stream_private_t *stream,
+                                                opj_event_mgr_t * p_manager );
+
+/**
+ * Excutes the given procedures on the given codec.
+ *
+ * @param	p_procedure_list	the list of procedures to execute
+ * @param	jp2					the jpeg2000 file codec to execute the procedures on.
+ * @param	stream					the stream to execute the procedures on.
+ * @param	p_manager			the user manager.
+ *
+ * @return	true				if all the procedures were successfully executed.
+ */
+static OPJ_BOOL opj_jp2_exec (  opj_jp2_t * jp2,
+                                opj_procedure_list_t * p_procedure_list,
+                                opj_stream_private_t *stream,
+                                opj_event_mgr_t * p_manager );
+
+/**
+ * Reads a box header. The box is the way data is packed inside a jpeg2000 file structure.
+ *
+ * @param	cio						the input stream to read data from.
+ * @param	box						the box structure to fill.
+ * @param	p_number_bytes_read		pointer to an int that will store the number of bytes read from the stream (shoul usually be 2).
+ * @param	p_manager				user event manager.
+ *
+ * @return	true if the box is reconized, false otherwise
+*/
+static OPJ_BOOL opj_jp2_read_boxhdr(opj_jp2_box_t *box,
+                                    OPJ_UINT32 * p_number_bytes_read,
+                                    opj_stream_private_t *cio,
+                                    opj_event_mgr_t * p_manager);
+
+/**
+ * Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters
+ * are valid. Developpers wanting to extend the library can add their own validation procedures.
+ */
+static void opj_jp2_setup_encoding_validation (opj_jp2_t *jp2);
+
+/**
+ * Sets up the procedures to do on writing header. Developpers wanting to extend the library can add their own writing procedures.
+ */
+static void opj_jp2_setup_header_writing (opj_jp2_t *jp2);
+
+OPJ_BOOL opj_jp2_default_validation (	opj_jp2_t * jp2,
+                                        opj_stream_private_t *cio,
+                                        opj_event_mgr_t * p_manager );
+
+/**
+ * Finds the image execution function related to the given box id.
+ *
+ * @param	p_id	the id of the handler to fetch.
+ *
+ * @return	the given handler or NULL if it could not be found.
+ */
+static const opj_jp2_header_handler_t * opj_jp2_img_find_handler (OPJ_UINT32 p_id);
+
+/**
+ * Finds the execution function related to the given box id.
+ *
+ * @param	p_id	the id of the handler to fetch.
+ *
+ * @return	the given handler or NULL if it could not be found.
+ */
+static const opj_jp2_header_handler_t * opj_jp2_find_handler (OPJ_UINT32 p_id );
+
+const opj_jp2_header_handler_t jp2_header [] =
+{
+	{JP2_JP,opj_jp2_read_jp},
+	{JP2_FTYP,opj_jp2_read_ftyp},
+	{JP2_JP2H,opj_jp2_read_jp2h}
+};
+
+const opj_jp2_header_handler_t jp2_img_header [] =
+{
+	{JP2_IHDR,opj_jp2_read_ihdr},
+	{JP2_COLR,opj_jp2_read_colr},
+	{JP2_BPCC,opj_jp2_read_bpcc},
+	{JP2_PCLR,opj_jp2_read_pclr},
+	{JP2_CMAP,opj_jp2_read_cmap},
+	{JP2_CDEF,opj_jp2_read_cdef}
+
+};
+
+/**
+ * Reads a box header. The box is the way data is packed inside a jpeg2000 file structure. Data is read from a character string
+ *
+ * @param	box						the box structure to fill.
+ * @param	p_data					the character string to read data from.
+ * @param	p_number_bytes_read		pointer to an int that will store the number of bytes read from the stream (shoul usually be 2).
+ * @param	p_box_max_size			the maximum number of bytes in the box.
+ * @param	p_manager         FIXME DOC
+ *
+ * @return	true if the box is reconized, false otherwise
+*/
+static OPJ_BOOL opj_jp2_read_boxhdr_char(   opj_jp2_box_t *box,
+                                            OPJ_BYTE * p_data,
+                                            OPJ_UINT32 * p_number_bytes_read,
+                                            OPJ_UINT32 p_box_max_size,
+                                            opj_event_mgr_t * p_manager );
+
+/**
+ * Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters
+ * are valid. Developpers wanting to extend the library can add their own validation procedures.
+ */
+static void opj_jp2_setup_decoding_validation (opj_jp2_t *jp2);
+
+/**
+ * Sets up the procedures to do on reading header.
+ * Developpers wanting to extend the library can add their own writing procedures.
+ */
+static void opj_jp2_setup_header_reading (opj_jp2_t *jp2);
+
+/* ----------------------------------------------------------------------- */
+ OPJ_BOOL opj_jp2_read_boxhdr(opj_jp2_box_t *box,
+                              OPJ_UINT32 * p_number_bytes_read,
+                              opj_stream_private_t *cio,
+                              opj_event_mgr_t * p_manager )
+{
+	/* read header from file */
+	OPJ_BYTE l_data_header [8];
+
+	/* preconditions */
+	assert(cio != 00);
+	assert(box != 00);
+	assert(p_number_bytes_read != 00);
+	assert(p_manager != 00);
+
+	*p_number_bytes_read = (OPJ_UINT32)opj_stream_read_data(cio,l_data_header,8,p_manager);
+	if (*p_number_bytes_read != 8) {
+		return OPJ_FALSE;
+	}
+
+	/* process read data */
+	opj_read_bytes(l_data_header,&(box->length), 4);
+	opj_read_bytes(l_data_header+4,&(box->type), 4);
+    
+  if(box->length == 0)/* last box */
+    {
+    const OPJ_OFF_T bleft = opj_stream_get_number_byte_left(cio);
+    box->length = (OPJ_UINT32)bleft;
+    assert( (OPJ_OFF_T)box->length == bleft );
+    return OPJ_TRUE;
+    }
+
+	/* do we have a "special very large box ?" */
+	/* read then the XLBox */
+	if (box->length == 1) {
+		OPJ_UINT32 l_xl_part_size;
+
+		OPJ_UINT32 l_nb_bytes_read = (OPJ_UINT32)opj_stream_read_data(cio,l_data_header,8,p_manager);
+		if (l_nb_bytes_read != 8) {
+			if (l_nb_bytes_read > 0) {
+				*p_number_bytes_read += l_nb_bytes_read;
+			}
+
+			return OPJ_FALSE;
+		}
+
+        *p_number_bytes_read = 16;
+		opj_read_bytes(l_data_header,&l_xl_part_size, 4);
+		if (l_xl_part_size != 0) {
+			opj_event_msg(p_manager, EVT_ERROR, "Cannot handle box sizes higher than 2^32\n");
+			return OPJ_FALSE;
+		}
+		opj_read_bytes(l_data_header+4,&(box->length), 4);
+	}
+    return OPJ_TRUE;
+}
+
+#if 0
+static void jp2_write_url(opj_cio_t *cio, char *Idx_file) {
+	OPJ_UINT32 i;
+	opj_jp2_box_t box;
+
+	box.init_pos = cio_tell(cio);
+	cio_skip(cio, 4);
+	cio_write(cio, JP2_URL, 4);	/* DBTL */
+	cio_write(cio, 0, 1);		/* VERS */
+	cio_write(cio, 0, 3);		/* FLAG */
+
+	if(Idx_file) {
+		for (i = 0; i < strlen(Idx_file); i++) {
+			cio_write(cio, Idx_file[i], 1);
+		}
+	}
+
+	box.length = cio_tell(cio) - box.init_pos;
+	cio_seek(cio, box.init_pos);
+	cio_write(cio, box.length, 4);	/* L */
+	cio_seek(cio, box.init_pos + box.length);
+}
+#endif
+
+OPJ_BOOL opj_jp2_read_ihdr( opj_jp2_t *jp2,
+                            OPJ_BYTE *p_image_header_data,
+                            OPJ_UINT32 p_image_header_size,
+                            opj_event_mgr_t * p_manager )
+{
+	/* preconditions */
+	assert(p_image_header_data != 00);
+	assert(jp2 != 00);
+	assert(p_manager != 00);
+
+	if (p_image_header_size != 14) {
+		opj_event_msg(p_manager, EVT_ERROR, "Bad image header box (bad size)\n");
+		return OPJ_FALSE;
+	}
+
+	opj_read_bytes(p_image_header_data,&(jp2->h),4);			/* HEIGHT */
+	p_image_header_data += 4;
+	opj_read_bytes(p_image_header_data,&(jp2->w),4);			/* WIDTH */
+	p_image_header_data += 4;
+	opj_read_bytes(p_image_header_data,&(jp2->numcomps),2);		/* NC */
+	p_image_header_data += 2;
+
+	/* allocate memory for components */
+	jp2->comps = (opj_jp2_comps_t*) opj_malloc(jp2->numcomps * sizeof(opj_jp2_comps_t));
+	if (jp2->comps == 0) {
+		opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to handle image header (ihdr)\n");
+		return OPJ_FALSE;
+	}
+	memset(jp2->comps,0,jp2->numcomps * sizeof(opj_jp2_comps_t));
+
+	opj_read_bytes(p_image_header_data,&(jp2->bpc),1);			/* BPC */
+	++ p_image_header_data;
+
+	opj_read_bytes(p_image_header_data,&(jp2->C),1);			/* C */
+	++ p_image_header_data;
+
+	/* Should be equal to 7 cf. chapter about image header box of the norm */
+	if (jp2->C != 7){
+		opj_event_msg(p_manager, EVT_INFO, "JP2 IHDR box: compression type indicate that the file is not a conforming JP2 file (%d) \n", jp2->C);
+	}
+
+	opj_read_bytes(p_image_header_data,&(jp2->UnkC),1);			/* UnkC */
+	++ p_image_header_data;
+	opj_read_bytes(p_image_header_data,&(jp2->IPR),1);			/* IPR */
+	++ p_image_header_data;
+
+	return OPJ_TRUE;
+}
+
+OPJ_BYTE * opj_jp2_write_ihdr(opj_jp2_t *jp2,
+                              OPJ_UINT32 * p_nb_bytes_written
+                              )
+{
+	OPJ_BYTE * l_ihdr_data,* l_current_ihdr_ptr;
+	
+	/* preconditions */
+	assert(jp2 != 00);
+	assert(p_nb_bytes_written != 00);
+
+	/* default image header is 22 bytes wide */
+	l_ihdr_data = (OPJ_BYTE *) opj_malloc(22);
+	if (l_ihdr_data == 00) {
+		return 00;
+	}
+	memset(l_ihdr_data,0,22);
+
+	l_current_ihdr_ptr = l_ihdr_data;
+	
+	opj_write_bytes(l_current_ihdr_ptr,22,4);				/* write box size */
+	l_current_ihdr_ptr+=4;
+
+	opj_write_bytes(l_current_ihdr_ptr,JP2_IHDR, 4);		/* IHDR */
+	l_current_ihdr_ptr+=4;
+	
+	opj_write_bytes(l_current_ihdr_ptr,jp2->h, 4);		/* HEIGHT */
+	l_current_ihdr_ptr+=4;
+	
+	opj_write_bytes(l_current_ihdr_ptr, jp2->w, 4);		/* WIDTH */
+	l_current_ihdr_ptr+=4;
+	
+	opj_write_bytes(l_current_ihdr_ptr, jp2->numcomps, 2);		/* NC */
+	l_current_ihdr_ptr+=2;
+	
+	opj_write_bytes(l_current_ihdr_ptr, jp2->bpc, 1);		/* BPC */
+	++l_current_ihdr_ptr;
+	
+	opj_write_bytes(l_current_ihdr_ptr, jp2->C, 1);		/* C : Always 7 */
+	++l_current_ihdr_ptr;
+	
+	opj_write_bytes(l_current_ihdr_ptr, jp2->UnkC, 1);		/* UnkC, colorspace unknown */
+	++l_current_ihdr_ptr;
+	
+	opj_write_bytes(l_current_ihdr_ptr, jp2->IPR, 1);		/* IPR, no intellectual property */
+	++l_current_ihdr_ptr;
+	
+	*p_nb_bytes_written = 22;
+	
+	return l_ihdr_data;
+}
+
+OPJ_BYTE * opj_jp2_write_bpcc(	opj_jp2_t *jp2,
+						        OPJ_UINT32 * p_nb_bytes_written
+                                )
+{
+	OPJ_UINT32 i;
+	/* room for 8 bytes for box and 1 byte for each component */
+	OPJ_UINT32 l_bpcc_size = 8 + jp2->numcomps;
+	OPJ_BYTE * l_bpcc_data,* l_current_bpcc_ptr;
+	
+	/* preconditions */
+	assert(jp2 != 00);
+	assert(p_nb_bytes_written != 00);
+
+	l_bpcc_data = (OPJ_BYTE *) opj_malloc(l_bpcc_size);
+	if (l_bpcc_data == 00) {
+		return 00;
+	}
+	memset(l_bpcc_data,0,l_bpcc_size);
+
+	l_current_bpcc_ptr = l_bpcc_data;
+
+	opj_write_bytes(l_current_bpcc_ptr,l_bpcc_size,4);				/* write box size */
+	l_current_bpcc_ptr += 4;
+	
+	opj_write_bytes(l_current_bpcc_ptr,JP2_BPCC,4);					/* BPCC */
+	l_current_bpcc_ptr += 4;
+
+	for (i = 0; i < jp2->numcomps; ++i)  {
+		opj_write_bytes(l_current_bpcc_ptr, jp2->comps[i].bpcc, 1); /* write each component information */
+		++l_current_bpcc_ptr;
+	}
+
+	*p_nb_bytes_written = l_bpcc_size;
+	
+	return l_bpcc_data;
+}
+
+OPJ_BOOL opj_jp2_read_bpcc( opj_jp2_t *jp2,
+                            OPJ_BYTE * p_bpc_header_data,
+                            OPJ_UINT32 p_bpc_header_size,
+                            opj_event_mgr_t * p_manager
+                            )
+{
+	OPJ_UINT32 i;
+
+	/* preconditions */
+	assert(p_bpc_header_data != 00);
+	assert(jp2 != 00);
+	assert(p_manager != 00);
+
+	
+	if (jp2->bpc != 255 ){
+		opj_event_msg(p_manager, EVT_WARNING, "A BPCC header box is available although BPC given by the IHDR box (%d) indicate components bit depth is constant\n",jp2->bpc);
+	}
+
+	/* and length is relevant */
+	if (p_bpc_header_size != jp2->numcomps) {
+		opj_event_msg(p_manager, EVT_ERROR, "Bad BPCC header box (bad size)\n");
+		return OPJ_FALSE;
+	}
+
+	/* read info for each component */
+	for (i = 0; i < jp2->numcomps; ++i) {
+		opj_read_bytes(p_bpc_header_data,&jp2->comps[i].bpcc ,1);	/* read each BPCC component */
+		++p_bpc_header_data;
+	}
+
+	return OPJ_TRUE;
+}
+
+OPJ_BYTE * opj_jp2_write_colr(  opj_jp2_t *jp2,
+							    OPJ_UINT32 * p_nb_bytes_written
+                                )
+{
+	/* room for 8 bytes for box 3 for common data and variable upon profile*/
+	OPJ_UINT32 l_colr_size = 11;
+	OPJ_BYTE * l_colr_data,* l_current_colr_ptr;
+	
+	/* preconditions */
+	assert(jp2 != 00);
+	assert(p_nb_bytes_written != 00);
+    assert(jp2->meth == 1 || jp2->meth == 2);
+
+	switch (jp2->meth) { 
+		case 1 :
+			l_colr_size += 4; /* EnumCS */
+			break;
+		case 2 :
+            assert(jp2->color.icc_profile_len);	/* ICC profile */
+            l_colr_size += jp2->color.icc_profile_len;
+			break;
+		default :
+			return 00;
+	}
+
+	l_colr_data = (OPJ_BYTE *) opj_malloc(l_colr_size);
+	if (l_colr_data == 00) {
+		return 00;
+	}
+	memset(l_colr_data,0,l_colr_size);
+	
+	l_current_colr_ptr = l_colr_data;
+
+	opj_write_bytes(l_current_colr_ptr,l_colr_size,4);				/* write box size */
+	l_current_colr_ptr += 4;
+	
+	opj_write_bytes(l_current_colr_ptr,JP2_COLR,4);					/* BPCC */
+	l_current_colr_ptr += 4;
+	
+	opj_write_bytes(l_current_colr_ptr, jp2->meth,1);				/* METH */
+	++l_current_colr_ptr;
+	
+	opj_write_bytes(l_current_colr_ptr, jp2->precedence,1);			/* PRECEDENCE */
+	++l_current_colr_ptr;
+	
+	opj_write_bytes(l_current_colr_ptr, jp2->approx,1);				/* APPROX */
+	++l_current_colr_ptr;
+	
+	if (jp2->meth == 1) { /* Meth value is restricted to 1 or 2 (Table I.9 of part 1) */
+        opj_write_bytes(l_current_colr_ptr, jp2->enumcs,4); }       /* EnumCS */
+    else {
+        if (jp2->meth == 2) {                                      /* ICC profile */
+            OPJ_UINT32 i;
+            for(i = 0; i < jp2->color.icc_profile_len; ++i) {
+                opj_write_bytes(l_current_colr_ptr, jp2->color.icc_profile_buf[i], 1);
+                ++l_current_colr_ptr;
+            }
+        }
+	}
+
+	*p_nb_bytes_written = l_colr_size;
+	
+	return l_colr_data;
+}
+
+void opj_jp2_free_pclr(opj_jp2_color_t *color)
+{
+    opj_free(color->jp2_pclr->channel_sign);
+    opj_free(color->jp2_pclr->channel_size);
+    opj_free(color->jp2_pclr->entries);
+
+	if(color->jp2_pclr->cmap) opj_free(color->jp2_pclr->cmap);
+
+    opj_free(color->jp2_pclr); color->jp2_pclr = NULL;
+}
+
+static OPJ_BOOL opj_jp2_check_color(opj_image_t *image, opj_jp2_color_t *color, opj_event_mgr_t *p_manager)
+{
+	OPJ_UINT16 i;
+
+	/* testcase 4149.pdf.SIGSEGV.cf7.3501 */
+	if (color->jp2_cdef) {
+		opj_jp2_cdef_info_t *info = color->jp2_cdef->info;
+		OPJ_UINT16 n = color->jp2_cdef->n;
+
+		for (i = 0; i < n; i++) {
+			if (info[i].cn >= image->numcomps) {
+				opj_event_msg(p_manager, EVT_ERROR, "Invalid component index %d (>= %d).\n", info[i].cn, image->numcomps);
+				return OPJ_FALSE;
+			}
+			if (info[i].asoc > 0 && (OPJ_UINT32)(info[i].asoc - 1) >= image->numcomps) {
+				opj_event_msg(p_manager, EVT_ERROR, "Invalid component index %d (>= %d).\n", info[i].asoc - 1, image->numcomps);
+				return OPJ_FALSE;
+			}
+		}
+	}
+
+	/* testcases 451.pdf.SIGSEGV.f4c.3723, 451.pdf.SIGSEGV.5b5.3723 and
+	   66ea31acbb0f23a2bbc91f64d69a03f5_signal_sigsegv_13937c0_7030_5725.pdf */
+	if (color->jp2_pclr && color->jp2_pclr->cmap) {
+		OPJ_UINT16 nr_channels = color->jp2_pclr->nr_channels;
+		opj_jp2_cmap_comp_t *cmap = color->jp2_pclr->cmap;
+		OPJ_BOOL *pcol_usage, is_sane = OPJ_TRUE;
+
+		/* verify that all original components match an existing one */
+		for (i = 0; i < nr_channels; i++) {
+			if (cmap[i].cmp >= image->numcomps) {
+				opj_event_msg(p_manager, EVT_ERROR, "Invalid component index %d (>= %d).\n", cmap[i].cmp, image->numcomps);
+				is_sane = OPJ_FALSE;
+			}
+		}
+
+		pcol_usage = opj_calloc(nr_channels, sizeof(OPJ_BOOL));
+		if (!pcol_usage) {
+			opj_event_msg(p_manager, EVT_ERROR, "Unexpected OOM.\n");
+			return OPJ_FALSE;
+		}
+		/* verify that no component is targeted more than once */
+		for (i = 0; i < nr_channels; i++) {
+      OPJ_UINT16 pcol = cmap[i].pcol;
+      assert(cmap[i].mtyp == 0 || cmap[i].mtyp == 1);
+			if (pcol >= nr_channels) {
+				opj_event_msg(p_manager, EVT_ERROR, "Invalid component/palette index for direct mapping %d.\n", pcol);
+				is_sane = OPJ_FALSE;
+			}
+			else if (pcol_usage[pcol] && cmap[i].mtyp == 1) {
+				opj_event_msg(p_manager, EVT_ERROR, "Component %d is mapped twice.\n", pcol);
+				is_sane = OPJ_FALSE;
+			}
+      else if (cmap[i].mtyp == 0 && cmap[i].pcol != 0) {
+        /* I.5.3.5 PCOL: If the value of the MTYP field for this channel is 0, then
+         * the value of this field shall be 0. */
+				opj_event_msg(p_manager, EVT_ERROR, "Direct use at #%d however pcol=%d.\n", i, pcol);
+				is_sane = OPJ_FALSE;
+      }
+			else
+				pcol_usage[pcol] = OPJ_TRUE;
+		}
+		/* verify that all components are targeted at least once */
+		for (i = 0; i < nr_channels; i++) {
+			if (!pcol_usage[i] && cmap[i].mtyp != 0) {
+				opj_event_msg(p_manager, EVT_ERROR, "Component %d doesn't have a mapping.\n", i);
+				is_sane = OPJ_FALSE;
+			}
+		}
+		opj_free(pcol_usage);
+		if (!is_sane) {
+			return OPJ_FALSE;
+		}
+	}
+
+	return OPJ_TRUE;
+}
+
+/* file9.jp2 */
+void opj_jp2_apply_pclr(opj_image_t *image, opj_jp2_color_t *color)
+{
+	opj_image_comp_t *old_comps, *new_comps;
+	OPJ_BYTE *channel_size, *channel_sign;
+	OPJ_UINT32 *entries;
+	opj_jp2_cmap_comp_t *cmap;
+	OPJ_INT32 *src, *dst;
+	OPJ_UINT32 j, max;
+	OPJ_UINT16 i, nr_channels, cmp, pcol;
+	OPJ_INT32 k, top_k;
+
+	channel_size = color->jp2_pclr->channel_size;
+	channel_sign = color->jp2_pclr->channel_sign;
+	entries = color->jp2_pclr->entries;
+	cmap = color->jp2_pclr->cmap;
+	nr_channels = color->jp2_pclr->nr_channels;
+
+	old_comps = image->comps;
+	new_comps = (opj_image_comp_t*)
+			opj_malloc(nr_channels * sizeof(opj_image_comp_t));
+
+	for(i = 0; i < nr_channels; ++i) {
+		pcol = cmap[i].pcol; cmp = cmap[i].cmp;
+
+		/* Direct use */
+    if(cmap[i].mtyp == 0){
+      assert( pcol == 0 );
+      new_comps[i] = old_comps[cmp];
+    } else {
+      assert( i == pcol );
+      new_comps[pcol] = old_comps[cmp];
+    }
+
+		/* Palette mapping: */
+		new_comps[i].data = (OPJ_INT32*)
+				opj_malloc(old_comps[cmp].w * old_comps[cmp].h * sizeof(OPJ_INT32));
+		new_comps[i].prec = channel_size[i];
+		new_comps[i].sgnd = channel_sign[i];
+	}
+
+	top_k = color->jp2_pclr->nr_entries - 1;
+
+	for(i = 0; i < nr_channels; ++i) {
+		/* Palette mapping: */
+		cmp = cmap[i].cmp; pcol = cmap[i].pcol;
+		src = old_comps[cmp].data;
+    assert( src );
+		max = new_comps[pcol].w * new_comps[pcol].h;
+
+		/* Direct use: */
+    if(cmap[i].mtyp == 0) {
+      assert( cmp == 0 );
+      dst = new_comps[i].data;
+      assert( dst );
+      for(j = 0; j < max; ++j) {
+        dst[j] = src[j];
+      }
+    }
+    else {
+      assert( i == pcol );
+      dst = new_comps[pcol].data;
+      assert( dst );
+      for(j = 0; j < max; ++j) {
+        /* The index */
+        if((k = src[j]) < 0) k = 0; else if(k > top_k) k = top_k;
+
+        /* The colour */
+        dst[j] = (OPJ_INT32)entries[k * nr_channels + pcol];
+        }
+    }
+	}
+
+	max = image->numcomps;
+	for(i = 0; i < max; ++i) {
+		if(old_comps[i].data) opj_free(old_comps[i].data);
+	}
+
+	opj_free(old_comps);
+	image->comps = new_comps;
+	image->numcomps = nr_channels;
+
+	opj_jp2_free_pclr(color);
+
+}/* apply_pclr() */
+
+OPJ_BOOL opj_jp2_read_pclr(	opj_jp2_t *jp2,
+                            OPJ_BYTE * p_pclr_header_data,
+                            OPJ_UINT32 p_pclr_header_size,
+                            opj_event_mgr_t * p_manager
+                            )
+{
+	opj_jp2_pclr_t *jp2_pclr;
+	OPJ_BYTE *channel_size, *channel_sign;
+	OPJ_UINT32 *entries;
+	OPJ_UINT16 nr_entries,nr_channels;
+	OPJ_UINT16 i, j;
+	OPJ_UINT32 l_value;
+	OPJ_BYTE *orig_header_data = p_pclr_header_data;
+
+	/* preconditions */
+	assert(p_pclr_header_data != 00);
+	assert(jp2 != 00);
+	assert(p_manager != 00);
+    (void)p_pclr_header_size;
+
+	if(jp2->color.jp2_pclr)
+		return OPJ_FALSE;
+
+	if (p_pclr_header_size < 3)
+		return OPJ_FALSE;
+
+	opj_read_bytes(p_pclr_header_data, &l_value , 2);	/* NE */
+	p_pclr_header_data += 2;
+	nr_entries = (OPJ_UINT16) l_value;
+
+	opj_read_bytes(p_pclr_header_data, &l_value , 1);	/* NPC */
+	++p_pclr_header_data;
+	nr_channels = (OPJ_UINT16) l_value;
+
+	if (p_pclr_header_size < 3 + (OPJ_UINT32)nr_channels || nr_channels == 0 || nr_entries >= (OPJ_UINT32)-1 / nr_channels)
+		return OPJ_FALSE;
+
+	entries = (OPJ_UINT32*) opj_malloc((size_t)nr_channels * nr_entries * sizeof(OPJ_UINT32));
+    if (!entries)
+        return OPJ_FALSE;
+	channel_size = (OPJ_BYTE*) opj_malloc(nr_channels);
+    if (!channel_size)
+    {
+        opj_free(entries);
+        return OPJ_FALSE;
+    }
+	channel_sign = (OPJ_BYTE*) opj_malloc(nr_channels);
+	if (!channel_sign)
+	{
+        opj_free(entries);
+        opj_free(channel_size);
+        return OPJ_FALSE;
+	}
+
+	jp2_pclr = (opj_jp2_pclr_t*)opj_malloc(sizeof(opj_jp2_pclr_t));
+    if (!jp2_pclr)
+    {
+        opj_free(entries);
+        opj_free(channel_size);
+        opj_free(channel_sign);
+        return OPJ_FALSE;
+    }
+
+	jp2_pclr->channel_sign = channel_sign;
+	jp2_pclr->channel_size = channel_size;
+	jp2_pclr->entries = entries;
+	jp2_pclr->nr_entries = nr_entries;
+	jp2_pclr->nr_channels = (OPJ_BYTE) l_value;
+	jp2_pclr->cmap = NULL;
+
+	jp2->color.jp2_pclr = jp2_pclr;
+
+	for(i = 0; i < nr_channels; ++i) {
+		opj_read_bytes(p_pclr_header_data, &l_value , 1);	/* Bi */
+		++p_pclr_header_data;
+
+		channel_size[i] = (OPJ_BYTE)((l_value & 0x7f) + 1);
+		channel_sign[i] = (l_value & 0x80) ? 1 : 0;
+	}
+
+	for(j = 0; j < nr_entries; ++j) {
+		for(i = 0; i < nr_channels; ++i) {
+			OPJ_UINT32 bytes_to_read = (OPJ_UINT32)((channel_size[i]+7)>>3);
+
+			if (bytes_to_read > sizeof(OPJ_UINT32))
+				bytes_to_read = sizeof(OPJ_UINT32);
+			if ((ptrdiff_t)p_pclr_header_size < p_pclr_header_data - orig_header_data + (ptrdiff_t)bytes_to_read)
+				return OPJ_FALSE;
+
+			opj_read_bytes(p_pclr_header_data, &l_value , bytes_to_read);	/* Cji */
+			p_pclr_header_data += bytes_to_read;
+			*entries = (OPJ_UINT32) l_value;
+			entries++;
+		}
+	}
+
+	return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_jp2_read_cmap(	opj_jp2_t * jp2,
+                            OPJ_BYTE * p_cmap_header_data,
+                            OPJ_UINT32 p_cmap_header_size,
+                            opj_event_mgr_t * p_manager
+                            )
+{
+	opj_jp2_cmap_comp_t *cmap;
+	OPJ_BYTE i, nr_channels;
+	OPJ_UINT32 l_value;
+
+	/* preconditions */
+	assert(jp2 != 00);
+	assert(p_cmap_header_data != 00);
+	assert(p_manager != 00);
+    (void)p_cmap_header_size;
+
+	/* Need nr_channels: */
+	if(jp2->color.jp2_pclr == NULL) {
+		opj_event_msg(p_manager, EVT_ERROR, "Need to read a PCLR box before the CMAP box.\n");
+		return OPJ_FALSE;
+	}
+
+	/* Part 1, I.5.3.5: 'There shall be at most one Component Mapping box
+	 * inside a JP2 Header box' :
+	*/
+	if(jp2->color.jp2_pclr->cmap) {
+		opj_event_msg(p_manager, EVT_ERROR, "Only one CMAP box is allowed.\n");
+		return OPJ_FALSE;
+	}
+
+	nr_channels = jp2->color.jp2_pclr->nr_channels;
+	if (p_cmap_header_size < (OPJ_UINT32)nr_channels * 4) {
+		opj_event_msg(p_manager, EVT_ERROR, "Insufficient data for CMAP box.\n");
+		return OPJ_FALSE;
+	}
+
+	cmap = (opj_jp2_cmap_comp_t*) opj_malloc(nr_channels * sizeof(opj_jp2_cmap_comp_t));
+    if (!cmap)
+        return OPJ_FALSE;
+
+
+	for(i = 0; i < nr_channels; ++i) {
+		opj_read_bytes(p_cmap_header_data, &l_value, 2);			/* CMP^i */
+		p_cmap_header_data +=2;
+		cmap[i].cmp = (OPJ_UINT16) l_value;
+
+		opj_read_bytes(p_cmap_header_data, &l_value, 1);			/* MTYP^i */
+		++p_cmap_header_data;
+		cmap[i].mtyp = (OPJ_BYTE) l_value;
+
+		opj_read_bytes(p_cmap_header_data, &l_value, 1);			/* PCOL^i */
+		++p_cmap_header_data;
+		cmap[i].pcol = (OPJ_BYTE) l_value;
+	}
+
+	jp2->color.jp2_pclr->cmap = cmap;
+
+	return OPJ_TRUE;
+}
+
+void opj_jp2_apply_cdef(opj_image_t *image, opj_jp2_color_t *color)
+{
+	opj_jp2_cdef_info_t *info;
+	OPJ_UINT16 i, n, cn, asoc, acn;
+
+	info = color->jp2_cdef->info;
+	n = color->jp2_cdef->n;
+
+  for(i = 0; i < n; ++i)
+    {
+    /* WATCH: acn = asoc - 1 ! */
+    asoc = info[i].asoc;
+    if(asoc == 0 || asoc == 65535)
+      {
+      if (i < image->numcomps)
+        image->comps[i].alpha = info[i].typ;
+      continue;
+      }
+
+    cn = info[i].cn; 
+    acn = (OPJ_UINT16)(asoc - 1);
+    if( cn >= image->numcomps || acn >= image->numcomps )
+      {
+      fprintf(stderr, "cn=%d, acn=%d, numcomps=%d\n", cn, acn, image->numcomps);
+      continue;
+      }
+
+		if(cn != acn)
+		{
+			opj_image_comp_t saved;
+
+			memcpy(&saved, &image->comps[cn], sizeof(opj_image_comp_t));
+			memcpy(&image->comps[cn], &image->comps[acn], sizeof(opj_image_comp_t));
+			memcpy(&image->comps[acn], &saved, sizeof(opj_image_comp_t));
+
+			info[i].asoc = (OPJ_UINT16)(cn + 1);
+			info[acn].asoc = (OPJ_UINT16)(info[acn].cn + 1);
+		}
+
+		image->comps[cn].alpha = info[i].typ;
+	}
+
+	if(color->jp2_cdef->info) opj_free(color->jp2_cdef->info);
+
+	opj_free(color->jp2_cdef); color->jp2_cdef = NULL;
+
+}/* jp2_apply_cdef() */
+
+OPJ_BOOL opj_jp2_read_cdef(	opj_jp2_t * jp2,
+                            OPJ_BYTE * p_cdef_header_data,
+							OPJ_UINT32 p_cdef_header_size,
+							opj_event_mgr_t * p_manager
+                            )
+{
+	opj_jp2_cdef_info_t *cdef_info;
+	OPJ_UINT16 i;
+	OPJ_UINT32 l_value;
+
+	/* preconditions */
+	assert(jp2 != 00);
+	assert(p_cdef_header_data != 00);
+	assert(p_manager != 00);
+    (void)p_cdef_header_size;
+
+	/* Part 1, I.5.3.6: 'The shall be at most one Channel Definition box
+	 * inside a JP2 Header box.'*/
+	if(jp2->color.jp2_cdef) return OPJ_FALSE;
+
+	if (p_cdef_header_size < 2) {
+		opj_event_msg(p_manager, EVT_ERROR, "Insufficient data for CDEF box.\n");
+		return OPJ_FALSE;
+	}
+
+	opj_read_bytes(p_cdef_header_data,&l_value ,2);			/* N */
+	p_cdef_header_data+= 2;
+
+	if ( (OPJ_UINT16)l_value == 0){ /* szukw000: FIXME */
+		opj_event_msg(p_manager, EVT_ERROR, "Number of channel description is equal to zero in CDEF box.\n");
+		return OPJ_FALSE;
+	}
+
+	if (p_cdef_header_size < 2 + (OPJ_UINT32)(OPJ_UINT16)l_value * 6) {
+		opj_event_msg(p_manager, EVT_ERROR, "Insufficient data for CDEF box.\n");
+		return OPJ_FALSE;
+	}
+
+	cdef_info = (opj_jp2_cdef_info_t*) opj_malloc(l_value * sizeof(opj_jp2_cdef_info_t));
+    if (!cdef_info)
+        return OPJ_FALSE;
+
+	jp2->color.jp2_cdef = (opj_jp2_cdef_t*)opj_malloc(sizeof(opj_jp2_cdef_t));
+    if(!jp2->color.jp2_cdef)
+    {
+        opj_free(cdef_info);
+        return OPJ_FALSE;
+    }
+	jp2->color.jp2_cdef->info = cdef_info;
+	jp2->color.jp2_cdef->n = (OPJ_UINT16) l_value;
+
+	for(i = 0; i < jp2->color.jp2_cdef->n; ++i) {
+		opj_read_bytes(p_cdef_header_data, &l_value, 2);			/* Cn^i */
+		p_cdef_header_data +=2;
+		cdef_info[i].cn = (OPJ_UINT16) l_value;
+
+		opj_read_bytes(p_cdef_header_data, &l_value, 2);			/* Typ^i */
+		p_cdef_header_data +=2;
+		cdef_info[i].typ = (OPJ_UINT16) l_value;
+
+		opj_read_bytes(p_cdef_header_data, &l_value, 2);			/* Asoc^i */
+		p_cdef_header_data +=2;
+		cdef_info[i].asoc = (OPJ_UINT16) l_value;
+   }
+
+	return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_jp2_read_colr( opj_jp2_t *jp2,
+                            OPJ_BYTE * p_colr_header_data,
+                            OPJ_UINT32 p_colr_header_size,
+                            opj_event_mgr_t * p_manager
+                            )
+{
+	OPJ_UINT32 l_value;
+
+	/* preconditions */
+	assert(jp2 != 00);
+	assert(p_colr_header_data != 00);
+	assert(p_manager != 00);
+
+	if (p_colr_header_size < 3) {
+		opj_event_msg(p_manager, EVT_ERROR, "Bad COLR header box (bad size)\n");
+		return OPJ_FALSE;
+	}
+
+	/* Part 1, I.5.3.3 : 'A conforming JP2 reader shall ignore all Colour
+	 * Specification boxes after the first.'
+	*/
+	if(jp2->color.jp2_has_colr) {
+		opj_event_msg(p_manager, EVT_INFO, "A conforming JP2 reader shall ignore all Colour Specification boxes after the first, so we ignore this one.\n");
+		p_colr_header_data += p_colr_header_size;
+		return OPJ_TRUE;
+	}
+
+	opj_read_bytes(p_colr_header_data,&jp2->meth ,1);			/* METH */
+	++p_colr_header_data;
+
+	opj_read_bytes(p_colr_header_data,&jp2->precedence ,1);		/* PRECEDENCE */
+	++p_colr_header_data;
+
+	opj_read_bytes(p_colr_header_data,&jp2->approx ,1);			/* APPROX */
+	++p_colr_header_data;
+
+	if (jp2->meth == 1) {
+		if (p_colr_header_size < 7) {
+			opj_event_msg(p_manager, EVT_ERROR, "Bad COLR header box (bad size: %d)\n", p_colr_header_size);
+			return OPJ_FALSE;
+		}
+		if (p_colr_header_size > 7) {
+			/* testcase Altona_Technical_v20_x4.pdf */
+			opj_event_msg(p_manager, EVT_WARNING, "Bad COLR header box (bad size: %d)\n", p_colr_header_size);
+		}
+
+		opj_read_bytes(p_colr_header_data,&jp2->enumcs ,4);			/* EnumCS */
+        
+        jp2->color.jp2_has_colr = 1;
+	}
+	else if (jp2->meth == 2) {
+		/* ICC profile */
+		OPJ_INT32 it_icc_value = 0;
+		OPJ_INT32 icc_len = (OPJ_INT32)p_colr_header_size - 3;
+
+		jp2->color.icc_profile_len = (OPJ_UINT32)icc_len;
+		jp2->color.icc_profile_buf = (OPJ_BYTE*) opj_malloc((size_t)icc_len);
+        if (!jp2->color.icc_profile_buf)
+        {
+            jp2->color.icc_profile_len = 0;
+            return OPJ_FALSE;
+        }
+		memset(jp2->color.icc_profile_buf, 0, (size_t)icc_len * sizeof(OPJ_BYTE));
+
+		for (it_icc_value = 0; it_icc_value < icc_len; ++it_icc_value)
+		{
+			opj_read_bytes(p_colr_header_data,&l_value,1);		/* icc values */
+			++p_colr_header_data;
+			jp2->color.icc_profile_buf[it_icc_value] = (OPJ_BYTE) l_value;
+		}
+	    
+        jp2->color.jp2_has_colr = 1;
+	}
+	else if (jp2->meth > 2)
+    {
+        /*	ISO/IEC 15444-1:2004 (E), Table I.9 � Legal METH values:
+        conforming JP2 reader shall ignore the entire Colour Specification box.*/
+        opj_event_msg(p_manager, EVT_INFO, "COLR BOX meth value is not a regular value (%d), " 
+            "so we will ignore the entire Colour Specification box. \n", jp2->meth);
+    }
+    return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_jp2_decode(opj_jp2_t *jp2,
+                        opj_stream_private_t *p_stream,
+                        opj_image_t* p_image,
+                        opj_event_mgr_t * p_manager)
+{
+	if (!p_image)
+		return OPJ_FALSE;
+
+	/* J2K decoding */
+	if( ! opj_j2k_decode(jp2->j2k, p_stream, p_image, p_manager) ) {
+		opj_event_msg(p_manager, EVT_ERROR, "Failed to decode the codestream in the JP2 file\n");
+		return OPJ_FALSE;
+	}
+
+    if (!jp2->ignore_pclr_cmap_cdef){
+	    if (!opj_jp2_check_color(p_image, &(jp2->color), p_manager)) {
+		    return OPJ_FALSE;
+	    }
+
+	    /* Set Image Color Space */
+	    if (jp2->enumcs == 16)
+		    p_image->color_space = OPJ_CLRSPC_SRGB;
+	    else if (jp2->enumcs == 17)
+		    p_image->color_space = OPJ_CLRSPC_GRAY;
+	    else if (jp2->enumcs == 18)
+		    p_image->color_space = OPJ_CLRSPC_SYCC;
+            else if (jp2->enumcs == 24)
+                    p_image->color_space = OPJ_CLRSPC_EYCC;
+	    else
+		    p_image->color_space = OPJ_CLRSPC_UNKNOWN;
+
+	    /* Apply the color space if needed */
+	    if(jp2->color.jp2_cdef) {
+		    opj_jp2_apply_cdef(p_image, &(jp2->color));
+	    }
+
+	    if(jp2->color.jp2_pclr) {
+		    /* Part 1, I.5.3.4: Either both or none : */
+		    if( !jp2->color.jp2_pclr->cmap)
+			    opj_jp2_free_pclr(&(jp2->color));
+		    else
+			    opj_jp2_apply_pclr(p_image, &(jp2->color));
+	    }
+
+	    if(jp2->color.icc_profile_buf) {
+		    p_image->icc_profile_buf = jp2->color.icc_profile_buf;
+		    p_image->icc_profile_len = jp2->color.icc_profile_len;
+		    jp2->color.icc_profile_buf = NULL;
+	    }
+    }
+
+	return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_jp2_write_jp2h(opj_jp2_t *jp2,
+                            opj_stream_private_t *stream,
+                            opj_event_mgr_t * p_manager
+                            )
+{
+	opj_jp2_img_header_writer_handler_t l_writers [3];
+	opj_jp2_img_header_writer_handler_t * l_current_writer;
+
+	OPJ_INT32 i, l_nb_pass;
+	/* size of data for super box*/
+	OPJ_UINT32 l_jp2h_size = 8;
+	OPJ_BOOL l_result = OPJ_TRUE;
+
+	/* to store the data of the super box */
+	OPJ_BYTE l_jp2h_data [8];
+	
+	/* preconditions */
+	assert(stream != 00);
+	assert(jp2 != 00);
+	assert(p_manager != 00);
+
+	memset(l_writers,0,sizeof(l_writers));
+
+	if (jp2->bpc == 255) {
+		l_nb_pass = 3;
+		l_writers[0].handler = opj_jp2_write_ihdr;
+		l_writers[1].handler = opj_jp2_write_bpcc;
+		l_writers[2].handler = opj_jp2_write_colr;
+	}
+	else {
+		l_nb_pass = 2;
+		l_writers[0].handler = opj_jp2_write_ihdr;
+		l_writers[1].handler = opj_jp2_write_colr;
+	}
+	
+	/* write box header */
+	/* write JP2H type */
+	opj_write_bytes(l_jp2h_data+4,JP2_JP2H,4);
+
+	l_current_writer = l_writers;
+	for (i=0;i<l_nb_pass;++i) {
+		l_current_writer->m_data = l_current_writer->handler(jp2,&(l_current_writer->m_size));
+		if (l_current_writer->m_data == 00) {
+			opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to hold JP2 Header data\n");
+			l_result = OPJ_FALSE;
+			break;
+		}
+
+		l_jp2h_size += l_current_writer->m_size;
+		++l_current_writer;
+	}
+
+	if (! l_result) {
+		l_current_writer = l_writers;
+		for (i=0;i<l_nb_pass;++i) {
+			if (l_current_writer->m_data != 00) {
+				opj_free(l_current_writer->m_data );
+			}
+			++l_current_writer;
+		}
+
+		return OPJ_FALSE;
+	}
+
+	/* write super box size */
+	opj_write_bytes(l_jp2h_data,l_jp2h_size,4);
+	
+	/* write super box data on stream */
+	if (opj_stream_write_data(stream,l_jp2h_data,8,p_manager) != 8) {
+		opj_event_msg(p_manager, EVT_ERROR, "Stream error while writing JP2 Header box\n");
+		l_result = OPJ_FALSE;
+	}
+	
+	if (l_result) {
+		l_current_writer = l_writers;
+		for (i=0;i<l_nb_pass;++i) {
+			if (opj_stream_write_data(stream,l_current_writer->m_data,l_current_writer->m_size,p_manager) != l_current_writer->m_size) {
+				opj_event_msg(p_manager, EVT_ERROR, "Stream error while writing JP2 Header box\n");
+				l_result = OPJ_FALSE;
+				break;
+			}
+			++l_current_writer;
+		}
+	}
+
+	l_current_writer = l_writers;
+	
+	/* cleanup */
+	for (i=0;i<l_nb_pass;++i) {
+		if (l_current_writer->m_data != 00) {
+			opj_free(l_current_writer->m_data );
+		}
+		++l_current_writer;
+	}
+
+	return l_result;
+}
+
+OPJ_BOOL opj_jp2_write_ftyp(opj_jp2_t *jp2,
+							opj_stream_private_t *cio,
+							opj_event_mgr_t * p_manager )
+{
+	OPJ_UINT32 i;
+	OPJ_UINT32 l_ftyp_size = 16 + 4 * jp2->numcl;
+	OPJ_BYTE * l_ftyp_data, * l_current_data_ptr;
+	OPJ_BOOL l_result;
+
+	/* preconditions */
+	assert(cio != 00);
+	assert(jp2 != 00);
+	assert(p_manager != 00);
+
+	l_ftyp_data = (OPJ_BYTE *) opj_malloc(l_ftyp_size);
+	
+	if (l_ftyp_data == 00) {
+		opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to handle ftyp data\n");
+		return OPJ_FALSE;
+	}
+
+	memset(l_ftyp_data,0,l_ftyp_size);
+
+	l_current_data_ptr = l_ftyp_data;
+
+	opj_write_bytes(l_current_data_ptr, l_ftyp_size,4); /* box size */
+	l_current_data_ptr += 4;
+
+	opj_write_bytes(l_current_data_ptr, JP2_FTYP,4); /* FTYP */
+	l_current_data_ptr += 4;
+
+	opj_write_bytes(l_current_data_ptr, jp2->brand,4); /* BR */
+	l_current_data_ptr += 4;
+
+	opj_write_bytes(l_current_data_ptr, jp2->minversion,4); /* MinV */
+	l_current_data_ptr += 4;
+
+	for (i = 0; i < jp2->numcl; i++)  {
+		opj_write_bytes(l_current_data_ptr, jp2->cl[i],4);	/* CL */
+	}
+	
+	l_result = (opj_stream_write_data(cio,l_ftyp_data,l_ftyp_size,p_manager) == l_ftyp_size);
+	if (! l_result)
+	{
+		opj_event_msg(p_manager, EVT_ERROR, "Error while writing ftyp data to stream\n");
+	}
+
+	opj_free(l_ftyp_data);
+	
+	return l_result;
+}
+
+OPJ_BOOL opj_jp2_write_jp2c(opj_jp2_t *jp2,
+							opj_stream_private_t *cio,
+							opj_event_mgr_t * p_manager )
+{
+	OPJ_OFF_T j2k_codestream_exit;
+	OPJ_BYTE l_data_header [8];
+	
+	/* preconditions */
+	assert(jp2 != 00);
+	assert(cio != 00);
+	assert(p_manager != 00);
+	assert(opj_stream_has_seek(cio));
+	
+	j2k_codestream_exit = opj_stream_tell(cio);
+	opj_write_bytes(l_data_header,
+                    (OPJ_UINT32) (j2k_codestream_exit - jp2->j2k_codestream_offset),
+                    4); /* size of codestream */
+	opj_write_bytes(l_data_header + 4,JP2_JP2C,4);									   /* JP2C */
+
+	if (! opj_stream_seek(cio,jp2->j2k_codestream_offset,p_manager)) {
+		opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
+		return OPJ_FALSE;
+	}
+	
+	if (opj_stream_write_data(cio,l_data_header,8,p_manager) != 8) {
+		opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
+		return OPJ_FALSE;
+	}
+
+	if (! opj_stream_seek(cio,j2k_codestream_exit,p_manager)) {
+		opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
+		return OPJ_FALSE;
+	}
+
+	return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_jp2_write_jp(	opj_jp2_t *jp2,
+			    		    opj_stream_private_t *cio,
+				    		opj_event_mgr_t * p_manager )
+{
+	/* 12 bytes will be read */
+	OPJ_BYTE l_signature_data [12];
+
+	/* preconditions */
+	assert(cio != 00);
+	assert(jp2 != 00);
+	assert(p_manager != 00);
+
+	/* write box length */
+	opj_write_bytes(l_signature_data,12,4);
+	/* writes box type */
+	opj_write_bytes(l_signature_data+4,JP2_JP,4);
+	/* writes magic number*/
+	opj_write_bytes(l_signature_data+8,0x0d0a870a,4);
+	
+	if (opj_stream_write_data(cio,l_signature_data,12,p_manager) != 12) {
+		return OPJ_FALSE;
+	}
+
+	return OPJ_TRUE;
+}
+
+/* ----------------------------------------------------------------------- */
+/* JP2 decoder interface                                             */
+/* ----------------------------------------------------------------------- */
+
+void opj_jp2_setup_decoder(opj_jp2_t *jp2, opj_dparameters_t *parameters)
+{
+	/* setup the J2K codec */
+	opj_j2k_setup_decoder(jp2->j2k, parameters);
+
+	/* further JP2 initializations go here */
+	jp2->color.jp2_has_colr = 0;
+    jp2->ignore_pclr_cmap_cdef = parameters->flags & OPJ_DPARAMETERS_IGNORE_PCLR_CMAP_CDEF_FLAG;
+}
+
+/* ----------------------------------------------------------------------- */
+/* JP2 encoder interface                                             */
+/* ----------------------------------------------------------------------- */
+
+void opj_jp2_setup_encoder(	opj_jp2_t *jp2,
+                            opj_cparameters_t *parameters,
+                            opj_image_t *image,
+                            opj_event_mgr_t * p_manager)
+{
+    OPJ_UINT32 i;
+	OPJ_UINT32 depth_0;
+  OPJ_UINT32 sign;
+
+	if(!jp2 || !parameters || !image)
+		return;
+
+	/* setup the J2K codec */
+	/* ------------------- */
+
+	/* Check if number of components respects standard */
+	if (image->numcomps < 1 || image->numcomps > 16384) {
+		opj_event_msg(p_manager, EVT_ERROR, "Invalid number of components specified while setting up JP2 encoder\n");
+		return;
+	}
+
+	opj_j2k_setup_encoder(jp2->j2k, parameters, image, p_manager );
+
+	/* setup the JP2 codec */
+	/* ------------------- */
+	
+	/* Profile box */
+
+	jp2->brand = JP2_JP2;	/* BR */
+	jp2->minversion = 0;	/* MinV */
+	jp2->numcl = 1;
+	jp2->cl = (OPJ_UINT32*) opj_malloc(jp2->numcl * sizeof(OPJ_UINT32));
+    if (!jp2->cl){
+        jp2->cl = NULL;
+        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory when setup the JP2 encoder\n");
+        return;
+    }
+	jp2->cl[0] = JP2_JP2;	/* CL0 : JP2 */
+
+	/* Image Header box */
+
+	jp2->numcomps = image->numcomps;	/* NC */
+	jp2->comps = (opj_jp2_comps_t*) opj_malloc(jp2->numcomps * sizeof(opj_jp2_comps_t));
+    if (!jp2->comps) {
+        jp2->comps = NULL;
+        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory when setup the JP2 encoder\n");
+        return;
+    }
+
+	jp2->h = image->y1 - image->y0;		/* HEIGHT */
+	jp2->w = image->x1 - image->x0;		/* WIDTH */
+	/* BPC */
+	depth_0 = image->comps[0].prec - 1;
+	sign = image->comps[0].sgnd;
+	jp2->bpc = depth_0 + (sign << 7);
+	for (i = 1; i < image->numcomps; i++) {
+		OPJ_UINT32 depth = image->comps[i].prec - 1;
+		sign = image->comps[i].sgnd;
+		if (depth_0 != depth)
+			jp2->bpc = 255;
+	}
+	jp2->C = 7;			/* C : Always 7 */
+	jp2->UnkC = 0;		/* UnkC, colorspace specified in colr box */
+	jp2->IPR = 0;		/* IPR, no intellectual property */
+	
+	/* BitsPerComponent box */
+	for (i = 0; i < image->numcomps; i++) {
+		jp2->comps[i].bpcc = image->comps[i].prec - 1 + (image->comps[i].sgnd << 7);
+	}
+
+	/* Colour Specification box */
+    if(image->icc_profile_len) {
+        jp2->meth = 2;
+        jp2->enumcs = 0;
+    } 
+    else {
+        jp2->meth = 1;
+        if (image->color_space == 1)
+            jp2->enumcs = 16;	/* sRGB as defined by IEC 61966-2-1 */
+        else if (image->color_space == 2)
+            jp2->enumcs = 17;	/* greyscale */
+        else if (image->color_space == 3)
+            jp2->enumcs = 18;	/* YUV */
+    }
+
+
+	jp2->precedence = 0;	/* PRECEDENCE */
+	jp2->approx = 0;		/* APPROX */
+
+	jp2->jpip_on = parameters->jpip_on;
+}
+
+OPJ_BOOL opj_jp2_encode(opj_jp2_t *jp2,
+						opj_stream_private_t *stream,
+						opj_event_mgr_t * p_manager)
+{
+	return opj_j2k_encode(jp2->j2k, stream, p_manager);
+}
+
+OPJ_BOOL opj_jp2_end_decompress(opj_jp2_t *jp2,
+                                opj_stream_private_t *cio,
+                                opj_event_mgr_t * p_manager
+                                )
+{
+	/* preconditions */
+	assert(jp2 != 00);
+	assert(cio != 00);
+	assert(p_manager != 00);
+
+	/* customization of the end encoding */
+	opj_jp2_setup_end_header_reading(jp2);
+
+	/* write header */
+	if (! opj_jp2_exec (jp2,jp2->m_procedure_list,cio,p_manager)) {
+		return OPJ_FALSE;
+	}
+
+	return opj_j2k_end_decompress(jp2->j2k, cio, p_manager);
+}
+
+OPJ_BOOL opj_jp2_end_compress(	opj_jp2_t *jp2,
+							    opj_stream_private_t *cio,
+							    opj_event_mgr_t * p_manager
+                                )
+{
+	/* preconditions */
+	assert(jp2 != 00);
+	assert(cio != 00);
+	assert(p_manager != 00);
+
+	/* customization of the end encoding */
+	opj_jp2_setup_end_header_writing(jp2);
+
+	if (! opj_j2k_end_compress(jp2->j2k,cio,p_manager)) {
+		return OPJ_FALSE;
+	}
+
+	/* write header */
+	return opj_jp2_exec(jp2,jp2->m_procedure_list,cio,p_manager);
+}
+
+void opj_jp2_setup_end_header_writing (opj_jp2_t *jp2)
+{
+	/* preconditions */
+	assert(jp2 != 00);
+
+#ifdef USE_JPIP
+  if( jp2->jpip_on )
+    opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jpip_write_iptr );
+#endif
+	opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_write_jp2c );
+	/* DEVELOPER CORNER, add your custom procedures */
+#ifdef USE_JPIP
+  if( jp2->jpip_on )
+    {
+    opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jpip_write_cidx );
+    opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jpip_write_fidx );
+    }
+#endif
+}
+
+void opj_jp2_setup_end_header_reading (opj_jp2_t *jp2)
+{
+	/* preconditions */
+	assert(jp2 != 00);
+	opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_read_header_procedure );
+	/* DEVELOPER CORNER, add your custom procedures */
+}
+
+OPJ_BOOL opj_jp2_default_validation (	opj_jp2_t * jp2,
+                                        opj_stream_private_t *cio,
+                                        opj_event_mgr_t * p_manager
+                                        )
+{
+	OPJ_BOOL l_is_valid = OPJ_TRUE;
+	OPJ_UINT32 i;
+
+	/* preconditions */
+	assert(jp2 != 00);
+	assert(cio != 00);
+	assert(p_manager != 00);
+
+	/* JPEG2000 codec validation */
+
+	/* STATE checking */
+	/* make sure the state is at 0 */
+	l_is_valid &= (jp2->jp2_state == JP2_STATE_NONE);
+
+	/* make sure not reading a jp2h ???? WEIRD */
+	l_is_valid &= (jp2->jp2_img_state == JP2_IMG_STATE_NONE);
+
+	/* POINTER validation */
+	/* make sure a j2k codec is present */
+	l_is_valid &= (jp2->j2k != 00);
+
+	/* make sure a procedure list is present */
+	l_is_valid &= (jp2->m_procedure_list != 00);
+
+	/* make sure a validation list is present */
+	l_is_valid &= (jp2->m_validation_list != 00);
+
+	/* PARAMETER VALIDATION */
+	/* number of components */
+	l_is_valid &= (jp2->numcl > 0);
+	/* width */
+	l_is_valid &= (jp2->h > 0);
+	/* height */
+	l_is_valid &= (jp2->w > 0);
+	/* precision */
+	for (i = 0; i < jp2->numcomps; ++i)	{
+		l_is_valid &= (jp2->comps[i].bpcc > 0);
+	}
+
+	/* METH */
+	l_is_valid &= ((jp2->meth > 0) && (jp2->meth < 3));
+
+	/* stream validation */
+	/* back and forth is needed */
+	l_is_valid &= opj_stream_has_seek(cio);
+
+	return l_is_valid;
+}
+
+OPJ_BOOL opj_jp2_read_header_procedure(  opj_jp2_t *jp2,
+                                                opj_stream_private_t *stream,
+                                                opj_event_mgr_t * p_manager
+                                                )
+{
+	opj_jp2_box_t box;
+	OPJ_UINT32 l_nb_bytes_read;
+	const opj_jp2_header_handler_t * l_current_handler;
+	OPJ_UINT32 l_last_data_size = OPJ_BOX_SIZE;
+	OPJ_UINT32 l_current_data_size;
+	OPJ_BYTE * l_current_data = 00;
+
+	/* preconditions */
+	assert(stream != 00);
+	assert(jp2 != 00);
+	assert(p_manager != 00);
+
+	l_current_data = (OPJ_BYTE*)opj_malloc(l_last_data_size);
+
+	if (l_current_data == 00) {
+		opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to handle jpeg2000 file header\n");
+		return OPJ_FALSE;
+	}
+	memset(l_current_data, 0 , l_last_data_size);
+
+	while (opj_jp2_read_boxhdr(&box,&l_nb_bytes_read,stream,p_manager)) {
+		/* is it the codestream box ? */
+		if (box.type == JP2_JP2C) {
+			if (jp2->jp2_state & JP2_STATE_HEADER) {
+				jp2->jp2_state |= JP2_STATE_CODESTREAM;
+                                opj_free(l_current_data);
+				return OPJ_TRUE;
+			}
+			else {
+				opj_event_msg(p_manager, EVT_ERROR, "bad placed jpeg codestream\n");
+				opj_free(l_current_data);
+				return OPJ_FALSE;
+			}
+		}
+		else if	(box.length == 0) {
+			opj_event_msg(p_manager, EVT_ERROR, "Cannot handle box of undefined sizes\n");
+			opj_free(l_current_data);
+			return OPJ_FALSE;
+		}
+		/* testcase 1851.pdf.SIGSEGV.ce9.948 */
+		else if	(box.length < l_nb_bytes_read) {
+			opj_event_msg(p_manager, EVT_ERROR, "invalid box size %d (%x)\n", box.length, box.type);
+			opj_free(l_current_data);
+			return OPJ_FALSE;
+		}
+
+		l_current_handler = opj_jp2_find_handler(box.type);
+		l_current_data_size = box.length - l_nb_bytes_read;
+
+		if (l_current_handler != 00) {
+			if (l_current_data_size > l_last_data_size) {
+				OPJ_BYTE* new_current_data = (OPJ_BYTE*)opj_realloc(l_current_data,l_current_data_size);
+				if (!new_current_data) {
+					opj_free(l_current_data);
+                    opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to handle jpeg2000 box\n");
+					return OPJ_FALSE;
+				}
+                l_current_data = new_current_data;
+				l_last_data_size = l_current_data_size;
+			}
+
+			l_nb_bytes_read = (OPJ_UINT32)opj_stream_read_data(stream,l_current_data,l_current_data_size,p_manager);
+			if (l_nb_bytes_read != l_current_data_size) {
+				opj_event_msg(p_manager, EVT_ERROR, "Problem with reading JPEG2000 box, stream error\n");
+                opj_free(l_current_data);                
+				return OPJ_FALSE;
+			}
+
+			if (! l_current_handler->handler(jp2,l_current_data,l_current_data_size,p_manager)) {
+				opj_free(l_current_data);
+				return OPJ_FALSE;
+			}
+		}
+		else {
+			jp2->jp2_state |= JP2_STATE_UNKNOWN;
+			if (opj_stream_skip(stream,l_current_data_size,p_manager) != l_current_data_size) {
+				opj_event_msg(p_manager, EVT_ERROR, "Problem with skipping JPEG2000 box, stream error\n");
+				opj_free(l_current_data);
+				return OPJ_FALSE;
+			}
+		}
+	}
+
+	opj_free(l_current_data);
+
+	return OPJ_TRUE;
+}
+
+/**
+ * Excutes the given procedures on the given codec.
+ *
+ * @param	p_procedure_list	the list of procedures to execute
+ * @param	jp2					the jpeg2000 file codec to execute the procedures on.
+ * @param	stream					the stream to execute the procedures on.
+ * @param	p_manager			the user manager.
+ *
+ * @return	true				if all the procedures were successfully executed.
+ */
+static OPJ_BOOL opj_jp2_exec (  opj_jp2_t * jp2,
+                                opj_procedure_list_t * p_procedure_list,
+                                opj_stream_private_t *stream,
+                                opj_event_mgr_t * p_manager
+                                )
+
+{
+	OPJ_BOOL (** l_procedure) (opj_jp2_t * jp2, opj_stream_private_t *, opj_event_mgr_t *) = 00;
+	OPJ_BOOL l_result = OPJ_TRUE;
+	OPJ_UINT32 l_nb_proc, i;
+
+	/* preconditions */
+	assert(p_procedure_list != 00);
+	assert(jp2 != 00);
+	assert(stream != 00);
+	assert(p_manager != 00);
+
+	l_nb_proc = opj_procedure_list_get_nb_procedures(p_procedure_list);
+	l_procedure = (OPJ_BOOL (**) (opj_jp2_t * jp2, opj_stream_private_t *, opj_event_mgr_t *)) opj_procedure_list_get_first_procedure(p_procedure_list);
+
+	for	(i=0;i<l_nb_proc;++i) {
+		l_result = l_result && (*l_procedure) (jp2,stream,p_manager);
+		++l_procedure;
+	}
+
+	/* and clear the procedure list at the end. */
+	opj_procedure_list_clear(p_procedure_list);
+	return l_result;
+}
+
+OPJ_BOOL opj_jp2_start_compress(opj_jp2_t *jp2,
+                                opj_stream_private_t *stream,
+                                opj_image_t * p_image,
+                                opj_event_mgr_t * p_manager
+                                )
+{
+	/* preconditions */
+	assert(jp2 != 00);
+	assert(stream != 00);
+	assert(p_manager != 00);
+
+	/* customization of the validation */
+	opj_jp2_setup_encoding_validation (jp2);
+
+	/* validation of the parameters codec */
+	if (! opj_jp2_exec(jp2,jp2->m_validation_list,stream,p_manager)) {
+		return OPJ_FALSE;
+	}
+
+	/* customization of the encoding */
+	opj_jp2_setup_header_writing(jp2);
+
+	/* write header */
+	if (! opj_jp2_exec (jp2,jp2->m_procedure_list,stream,p_manager)) {
+		return OPJ_FALSE;
+	}
+
+	return opj_j2k_start_compress(jp2->j2k,stream,p_image,p_manager);
+}
+
+const opj_jp2_header_handler_t * opj_jp2_find_handler (OPJ_UINT32 p_id)
+{
+	OPJ_UINT32 i, l_handler_size = sizeof(jp2_header) / sizeof(opj_jp2_header_handler_t);
+
+	for (i=0;i<l_handler_size;++i) {
+		if (jp2_header[i].id == p_id) {
+			return &jp2_header[i];
+		}
+	}
+	return NULL;
+}
+
+/**
+ * Finds the image execution function related to the given box id.
+ *
+ * @param	p_id	the id of the handler to fetch.
+ *
+ * @return	the given handler or 00 if it could not be found.
+ */
+static const opj_jp2_header_handler_t * opj_jp2_img_find_handler (OPJ_UINT32 p_id)
+{
+	OPJ_UINT32 i, l_handler_size = sizeof(jp2_img_header) / sizeof(opj_jp2_header_handler_t);
+	for (i=0;i<l_handler_size;++i)
+	{
+		if (jp2_img_header[i].id == p_id) {
+			return &jp2_img_header[i];
+		}
+	}
+
+	return NULL;
+}
+
+/**
+ * Reads a jpeg2000 file signature box.
+ *
+ * @param	p_header_data	the data contained in the signature box.
+ * @param	jp2				the jpeg2000 file codec.
+ * @param	p_header_size	the size of the data contained in the signature box.
+ * @param	p_manager		the user event manager.
+ *
+ * @return true if the file signature box is valid.
+ */
+static OPJ_BOOL opj_jp2_read_jp(opj_jp2_t *jp2,
+                                OPJ_BYTE * p_header_data,
+                                OPJ_UINT32 p_header_size,
+                                opj_event_mgr_t * p_manager
+                                )
+
+{
+	OPJ_UINT32 l_magic_number;
+
+	/* preconditions */
+	assert(p_header_data != 00);
+	assert(jp2 != 00);
+	assert(p_manager != 00);
+
+	if (jp2->jp2_state != JP2_STATE_NONE) {
+		opj_event_msg(p_manager, EVT_ERROR, "The signature box must be the first box in the file.\n");
+		return OPJ_FALSE;
+	}
+
+	/* assure length of data is correct (4 -> magic number) */
+	if (p_header_size != 4) {
+		opj_event_msg(p_manager, EVT_ERROR, "Error with JP signature Box size\n");
+		return OPJ_FALSE;
+	}
+
+	/* rearrange data */
+	opj_read_bytes(p_header_data,&l_magic_number,4);
+	if (l_magic_number != 0x0d0a870a ) {
+		opj_event_msg(p_manager, EVT_ERROR, "Error with JP Signature : bad magic number\n");
+		return OPJ_FALSE;
+	}
+
+	jp2->jp2_state |= JP2_STATE_SIGNATURE;
+
+	return OPJ_TRUE;
+}
+
+/**
+ * Reads a a FTYP box - File type box
+ *
+ * @param	p_header_data	the data contained in the FTYP box.
+ * @param	jp2				the jpeg2000 file codec.
+ * @param	p_header_size	the size of the data contained in the FTYP box.
+ * @param	p_manager		the user event manager.
+ *
+ * @return true if the FTYP box is valid.
+ */
+static OPJ_BOOL opj_jp2_read_ftyp(	opj_jp2_t *jp2,
+									OPJ_BYTE * p_header_data,
+									OPJ_UINT32 p_header_size,
+									opj_event_mgr_t * p_manager
+                                    )
+{
+	OPJ_UINT32 i, l_remaining_bytes;
+
+	/* preconditions */
+	assert(p_header_data != 00);
+	assert(jp2 != 00);
+	assert(p_manager != 00);
+
+	if (jp2->jp2_state != JP2_STATE_SIGNATURE) {
+		opj_event_msg(p_manager, EVT_ERROR, "The ftyp box must be the second box in the file.\n");
+		return OPJ_FALSE;
+	}
+
+	/* assure length of data is correct */
+	if (p_header_size < 8) {
+		opj_event_msg(p_manager, EVT_ERROR, "Error with FTYP signature Box size\n");
+		return OPJ_FALSE;
+	}
+
+	opj_read_bytes(p_header_data,&jp2->brand,4);		/* BR */
+	p_header_data += 4;
+
+	opj_read_bytes(p_header_data,&jp2->minversion,4);		/* MinV */
+	p_header_data += 4;
+
+	l_remaining_bytes = p_header_size - 8;
+
+	/* the number of remaining bytes should be a multiple of 4 */
+	if ((l_remaining_bytes & 0x3) != 0) {
+		opj_event_msg(p_manager, EVT_ERROR, "Error with FTYP signature Box size\n");
+		return OPJ_FALSE;
+	}
+
+	/* div by 4 */
+	jp2->numcl = l_remaining_bytes >> 2;
+	if (jp2->numcl) {
+		jp2->cl = (OPJ_UINT32 *) opj_malloc(jp2->numcl * sizeof(OPJ_UINT32));
+		if (jp2->cl == 00) {
+			opj_event_msg(p_manager, EVT_ERROR, "Not enough memory with FTYP Box\n");
+			return OPJ_FALSE;
+		}
+		memset(jp2->cl,0,jp2->numcl * sizeof(OPJ_UINT32));
+	}
+
+	for (i = 0; i < jp2->numcl; ++i)
+	{
+		opj_read_bytes(p_header_data,&jp2->cl[i],4);		/* CLi */
+		p_header_data += 4;
+	}
+
+	jp2->jp2_state |= JP2_STATE_FILE_TYPE;
+
+	return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_jp2_skip_jp2c(	opj_jp2_t *jp2,
+					    	opj_stream_private_t *stream,
+					    	opj_event_mgr_t * p_manager )
+{
+	/* preconditions */
+	assert(jp2 != 00);
+	assert(stream != 00);
+	assert(p_manager != 00);
+
+	jp2->j2k_codestream_offset = opj_stream_tell(stream);
+
+	if (opj_stream_skip(stream,8,p_manager) != 8) {
+		return OPJ_FALSE;
+	}
+
+	return OPJ_TRUE;
+}
+
+static OPJ_BOOL opj_jpip_skip_iptr(	opj_jp2_t *jp2,
+  opj_stream_private_t *stream,
+  opj_event_mgr_t * p_manager )
+{
+  /* preconditions */
+  assert(jp2 != 00);
+  assert(stream != 00);
+  assert(p_manager != 00);
+
+  jp2->jpip_iptr_offset = opj_stream_tell(stream);
+
+  if (opj_stream_skip(stream,24,p_manager) != 24) {
+    return OPJ_FALSE;
+  }
+
+  return OPJ_TRUE;
+}
+
+/**
+ * Reads the Jpeg2000 file Header box - JP2 Header box (warning, this is a super box).
+ *
+ * @param	p_header_data	the data contained in the file header box.
+ * @param	jp2				the jpeg2000 file codec.
+ * @param	p_header_size	the size of the data contained in the file header box.
+ * @param	p_manager		the user event manager.
+ *
+ * @return true if the JP2 Header box was successfully reconized.
+*/
+static OPJ_BOOL opj_jp2_read_jp2h(  opj_jp2_t *jp2,
+                                    OPJ_BYTE *p_header_data,
+                                    OPJ_UINT32 p_header_size,
+                                    opj_event_mgr_t * p_manager
+                                    )
+{
+	OPJ_UINT32 l_box_size=0, l_current_data_size = 0;
+	opj_jp2_box_t box;
+	const opj_jp2_header_handler_t * l_current_handler;
+
+	/* preconditions */
+	assert(p_header_data != 00);
+	assert(jp2 != 00);
+	assert(p_manager != 00);
+
+	/* make sure the box is well placed */
+	if ((jp2->jp2_state & JP2_STATE_FILE_TYPE) != JP2_STATE_FILE_TYPE ) {
+		opj_event_msg(p_manager, EVT_ERROR, "The  box must be the first box in the file.\n");
+		return OPJ_FALSE;
+	}
+
+	jp2->jp2_img_state = JP2_IMG_STATE_NONE;
+
+	/* iterate while remaining data */
+	while (p_header_size > 0) {
+
+		if (! opj_jp2_read_boxhdr_char(&box,p_header_data,&l_box_size,p_header_size, p_manager)) {
+			opj_event_msg(p_manager, EVT_ERROR, "Stream error while reading JP2 Header box\n");
+			return OPJ_FALSE;
+		}
+
+		if (box.length > p_header_size) {
+			opj_event_msg(p_manager, EVT_ERROR, "Stream error while reading JP2 Header box: box length is inconsistent.\n");
+			return OPJ_FALSE;
+		}
+
+		l_current_handler = opj_jp2_img_find_handler(box.type);
+		l_current_data_size = box.length - l_box_size;
+		p_header_data += l_box_size;
+
+		if (l_current_handler != 00) {
+			if (! l_current_handler->handler(jp2,p_header_data,l_current_data_size,p_manager)) {
+				return OPJ_FALSE;
+			}
+		}
+		else {
+			jp2->jp2_img_state |= JP2_IMG_STATE_UNKNOWN;
+		}
+
+		p_header_data += l_current_data_size;
+		p_header_size -= box.length;
+	}
+
+	jp2->jp2_state |= JP2_STATE_HEADER;
+
+	return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_jp2_read_boxhdr_char(   opj_jp2_box_t *box,
+                                     OPJ_BYTE * p_data,
+                                     OPJ_UINT32 * p_number_bytes_read,
+                                     OPJ_UINT32 p_box_max_size,
+                                     opj_event_mgr_t * p_manager
+                                     )
+{
+	OPJ_UINT32 l_value;
+
+	/* preconditions */
+	assert(p_data != 00);
+	assert(box != 00);
+	assert(p_number_bytes_read != 00);
+	assert(p_manager != 00);
+
+	if (p_box_max_size < 8) {
+		opj_event_msg(p_manager, EVT_ERROR, "Cannot handle box of less than 8 bytes\n");
+		return OPJ_FALSE;
+	}
+
+	/* process read data */
+	opj_read_bytes(p_data, &l_value, 4);
+	p_data += 4;
+	box->length = (OPJ_UINT32)(l_value);
+
+	opj_read_bytes(p_data, &l_value, 4);
+	p_data += 4;
+	box->type = (OPJ_UINT32)(l_value);
+
+	*p_number_bytes_read = 8;
+
+	/* do we have a "special very large box ?" */
+	/* read then the XLBox */
+	if (box->length == 1) {
+		OPJ_UINT32 l_xl_part_size;
+
+		if (p_box_max_size < 16) {
+			opj_event_msg(p_manager, EVT_ERROR, "Cannot handle XL box of less than 16 bytes\n");
+			return OPJ_FALSE;
+		}
+
+		opj_read_bytes(p_data,&l_xl_part_size, 4);
+		p_data += 4;
+		*p_number_bytes_read += 4;
+
+		if (l_xl_part_size != 0) {
+			opj_event_msg(p_manager, EVT_ERROR, "Cannot handle box sizes higher than 2^32\n");
+			return OPJ_FALSE;
+		}
+
+		opj_read_bytes(p_data, &l_value, 4);
+		*p_number_bytes_read += 4;
+		box->length = (OPJ_UINT32)(l_value);
+
+		if (box->length == 0) {
+			opj_event_msg(p_manager, EVT_ERROR, "Cannot handle box of undefined sizes\n");
+			return OPJ_FALSE;
+		}
+	}
+	else if (box->length == 0) {
+		opj_event_msg(p_manager, EVT_ERROR, "Cannot handle box of undefined sizes\n");
+		return OPJ_FALSE;
+	}
+
+	return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_jp2_read_header(	opj_stream_private_t *p_stream,
+                                opj_jp2_t *jp2,
+                                opj_image_t ** p_image,
+                                opj_event_mgr_t * p_manager
+                                )
+{
+	/* preconditions */
+	assert(jp2 != 00);
+	assert(p_stream != 00);
+	assert(p_manager != 00);
+
+	/* customization of the validation */
+	opj_jp2_setup_decoding_validation (jp2);
+
+	/* customization of the encoding */
+	opj_jp2_setup_header_reading(jp2);
+
+	/* validation of the parameters codec */
+	if (! opj_jp2_exec(jp2,jp2->m_validation_list,p_stream,p_manager)) {
+		return OPJ_FALSE;
+	}
+
+	/* read header */
+	if (! opj_jp2_exec (jp2,jp2->m_procedure_list,p_stream,p_manager)) {
+		return OPJ_FALSE;
+	}
+
+	return opj_j2k_read_header(	p_stream,
+							jp2->j2k,
+							p_image,
+							p_manager);
+}
+
+void opj_jp2_setup_encoding_validation (opj_jp2_t *jp2)
+{
+	/* preconditions */
+	assert(jp2 != 00);
+
+	opj_procedure_list_add_procedure(jp2->m_validation_list, (opj_procedure)opj_jp2_default_validation);
+	/* DEVELOPER CORNER, add your custom validation procedure */
+}
+
+void opj_jp2_setup_decoding_validation (opj_jp2_t *jp2)
+{
+	/* preconditions */
+	assert(jp2 != 00);
+	/* DEVELOPER CORNER, add your custom validation procedure */
+}
+
+void opj_jp2_setup_header_writing (opj_jp2_t *jp2)
+{
+	/* preconditions */
+	assert(jp2 != 00);
+
+	opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_write_jp );
+	opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_write_ftyp );
+	opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_write_jp2h );
+  if( jp2->jpip_on )
+    opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jpip_skip_iptr );
+	opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_skip_jp2c );
+
+	/* DEVELOPER CORNER, insert your custom procedures */
+
+}
+
+void opj_jp2_setup_header_reading (opj_jp2_t *jp2)
+{
+	/* preconditions */
+	assert(jp2 != 00);
+
+	opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_read_header_procedure );
+	/* DEVELOPER CORNER, add your custom procedures */
+}
+
+OPJ_BOOL opj_jp2_read_tile_header ( opj_jp2_t * p_jp2,
+                                    OPJ_UINT32 * p_tile_index,
+                                    OPJ_UINT32 * p_data_size,
+                                    OPJ_INT32 * p_tile_x0,
+                                    OPJ_INT32 * p_tile_y0,
+                                    OPJ_INT32 * p_tile_x1,
+                                    OPJ_INT32 * p_tile_y1,
+                                    OPJ_UINT32 * p_nb_comps,
+                                    OPJ_BOOL * p_go_on,
+                                    opj_stream_private_t *p_stream,
+                                    opj_event_mgr_t * p_manager
+                                    )
+{
+	return opj_j2k_read_tile_header(p_jp2->j2k,
+								p_tile_index,
+								p_data_size,
+								p_tile_x0, p_tile_y0,
+								p_tile_x1, p_tile_y1,
+								p_nb_comps,
+								p_go_on,
+								p_stream,
+								p_manager);
+}
+
+OPJ_BOOL opj_jp2_write_tile (	opj_jp2_t *p_jp2,
+					 	 	    OPJ_UINT32 p_tile_index,
+					 	 	    OPJ_BYTE * p_data,
+					 	 	    OPJ_UINT32 p_data_size,
+					 	 	    opj_stream_private_t *p_stream,
+					 	 	    opj_event_mgr_t * p_manager
+                                )
+
+{
+	return opj_j2k_write_tile (p_jp2->j2k,p_tile_index,p_data,p_data_size,p_stream,p_manager);
+}
+
+OPJ_BOOL opj_jp2_decode_tile (  opj_jp2_t * p_jp2,
+                                OPJ_UINT32 p_tile_index,
+                                OPJ_BYTE * p_data,
+                                OPJ_UINT32 p_data_size,
+                                opj_stream_private_t *p_stream,
+                                opj_event_mgr_t * p_manager
+                                )
+{
+	return opj_j2k_decode_tile (p_jp2->j2k,p_tile_index,p_data,p_data_size,p_stream,p_manager);
+}
+
+void opj_jp2_destroy(opj_jp2_t *jp2)
+{
+	if (jp2) {
+		/* destroy the J2K codec */
+		opj_j2k_destroy(jp2->j2k);
+		jp2->j2k = 00;
+
+		if (jp2->comps) {
+			opj_free(jp2->comps);
+			jp2->comps = 00;
+		}
+
+		if (jp2->cl) {
+			opj_free(jp2->cl);
+			jp2->cl = 00;
+		}
+
+		if (jp2->color.icc_profile_buf) {
+			opj_free(jp2->color.icc_profile_buf);
+			jp2->color.icc_profile_buf = 00;
+		}
+
+		if (jp2->color.jp2_cdef) {
+			if (jp2->color.jp2_cdef->info) {
+				opj_free(jp2->color.jp2_cdef->info);
+				jp2->color.jp2_cdef->info = NULL;
+			}
+
+			opj_free(jp2->color.jp2_cdef);
+			jp2->color.jp2_cdef = 00;
+		}
+
+		if (jp2->color.jp2_pclr) {
+			if (jp2->color.jp2_pclr->cmap) {
+				opj_free(jp2->color.jp2_pclr->cmap);
+				jp2->color.jp2_pclr->cmap = NULL;
+			}
+			if (jp2->color.jp2_pclr->channel_sign) {
+				opj_free(jp2->color.jp2_pclr->channel_sign);
+				jp2->color.jp2_pclr->channel_sign = NULL;
+			}
+			if (jp2->color.jp2_pclr->channel_size) {
+				opj_free(jp2->color.jp2_pclr->channel_size);
+				jp2->color.jp2_pclr->channel_size = NULL;
+			}
+			if (jp2->color.jp2_pclr->entries) {
+				opj_free(jp2->color.jp2_pclr->entries);
+				jp2->color.jp2_pclr->entries = NULL;
+			}
+
+			opj_free(jp2->color.jp2_pclr);
+			jp2->color.jp2_pclr = 00;
+		}
+
+		if (jp2->m_validation_list) {
+			opj_procedure_list_destroy(jp2->m_validation_list);
+			jp2->m_validation_list = 00;
+		}
+
+		if (jp2->m_procedure_list) {
+			opj_procedure_list_destroy(jp2->m_procedure_list);
+			jp2->m_procedure_list = 00;
+		}
+
+		opj_free(jp2);
+	}
+}
+
+OPJ_BOOL opj_jp2_set_decode_area(	opj_jp2_t *p_jp2,
+								    opj_image_t* p_image,
+								    OPJ_INT32 p_start_x, OPJ_INT32 p_start_y,
+								    OPJ_INT32 p_end_x, OPJ_INT32 p_end_y,
+								    opj_event_mgr_t * p_manager
+                                    )
+{
+	return opj_j2k_set_decode_area(p_jp2->j2k, p_image, p_start_x, p_start_y, p_end_x, p_end_y, p_manager);
+}
+
+OPJ_BOOL opj_jp2_get_tile(	opj_jp2_t *p_jp2,
+                            opj_stream_private_t *p_stream,
+                            opj_image_t* p_image,
+                            opj_event_mgr_t * p_manager,
+                            OPJ_UINT32 tile_index
+                            )
+{
+	if (!p_image)
+		return OPJ_FALSE;
+
+	opj_event_msg(p_manager, EVT_WARNING, "JP2 box which are after the codestream will not be read by this function.\n");
+
+	if (! opj_j2k_get_tile(p_jp2->j2k, p_stream, p_image, p_manager, tile_index) ){
+		opj_event_msg(p_manager, EVT_ERROR, "Failed to decode the codestream in the JP2 file\n");
+		return OPJ_FALSE;
+	}
+
+	if (!opj_jp2_check_color(p_image, &(p_jp2->color), p_manager)) {
+		return OPJ_FALSE;
+	}
+
+	/* Set Image Color Space */
+	if (p_jp2->enumcs == 16)
+		p_image->color_space = OPJ_CLRSPC_SRGB;
+	else if (p_jp2->enumcs == 17)
+		p_image->color_space = OPJ_CLRSPC_GRAY;
+	else if (p_jp2->enumcs == 18)
+		p_image->color_space = OPJ_CLRSPC_SYCC;
+	else
+		p_image->color_space = OPJ_CLRSPC_UNKNOWN;
+
+	/* Apply the color space if needed */
+	if(p_jp2->color.jp2_cdef) {
+		opj_jp2_apply_cdef(p_image, &(p_jp2->color));
+	}
+
+	if(p_jp2->color.jp2_pclr) {
+		/* Part 1, I.5.3.4: Either both or none : */
+		if( !p_jp2->color.jp2_pclr->cmap)
+			opj_jp2_free_pclr(&(p_jp2->color));
+		else
+			opj_jp2_apply_pclr(p_image, &(p_jp2->color));
+	}
+
+	if(p_jp2->color.icc_profile_buf) {
+		p_image->icc_profile_buf = p_jp2->color.icc_profile_buf;
+		p_image->icc_profile_len = p_jp2->color.icc_profile_len;
+		p_jp2->color.icc_profile_buf = NULL;
+	}
+
+	return OPJ_TRUE;
+}
+
+/* ----------------------------------------------------------------------- */
+/* JP2 encoder interface                                             */
+/* ----------------------------------------------------------------------- */
+
+opj_jp2_t* opj_jp2_create(OPJ_BOOL p_is_decoder)
+{
+	opj_jp2_t *jp2 = (opj_jp2_t*)opj_malloc(sizeof(opj_jp2_t));
+	if (jp2) {
+		memset(jp2,0,sizeof(opj_jp2_t));
+
+		/* create the J2K codec */
+		if (! p_is_decoder) {
+			jp2->j2k = opj_j2k_create_compress();
+		}
+		else {
+			jp2->j2k = opj_j2k_create_decompress();
+		}
+
+		if (jp2->j2k == 00) {
+			opj_jp2_destroy(jp2);
+			return 00;
+		}
+
+		/* Color structure */
+		jp2->color.icc_profile_buf = NULL;
+		jp2->color.icc_profile_len = 0;
+		jp2->color.jp2_cdef = NULL;
+		jp2->color.jp2_pclr = NULL;
+		jp2->color.jp2_has_colr = 0;
+
+		/* validation list creation */
+		jp2->m_validation_list = opj_procedure_list_create();
+		if (! jp2->m_validation_list) {
+			opj_jp2_destroy(jp2);
+			return 00;
+		}
+
+		/* execution list creation */
+		jp2->m_procedure_list = opj_procedure_list_create();
+		if (! jp2->m_procedure_list) {
+			opj_jp2_destroy(jp2);
+			return 00;
+		}
+	}
+
+	return jp2;
+}
+
+void jp2_dump(opj_jp2_t* p_jp2, OPJ_INT32 flag, FILE* out_stream)
+{
+	/* preconditions */
+	assert(p_jp2 != 00);
+
+	j2k_dump(p_jp2->j2k,
+					flag,
+					out_stream);
+}
+
+opj_codestream_index_t* jp2_get_cstr_index(opj_jp2_t* p_jp2)
+{
+	return j2k_get_cstr_index(p_jp2->j2k);
+}
+
+opj_codestream_info_v2_t* jp2_get_cstr_info(opj_jp2_t* p_jp2)
+{
+	return j2k_get_cstr_info(p_jp2->j2k);
+}
+
+OPJ_BOOL opj_jp2_set_decoded_resolution_factor(opj_jp2_t *p_jp2,
+                                               OPJ_UINT32 res_factor,
+                                               opj_event_mgr_t * p_manager)
+{
+	return opj_j2k_set_decoded_resolution_factor(p_jp2->j2k, res_factor, p_manager);
+}
+
+/* JPIP specific */
+
+#ifdef USE_JPIP
+static OPJ_BOOL opj_jpip_write_iptr(opj_jp2_t *jp2,
+  opj_stream_private_t *cio,
+  opj_event_mgr_t * p_manager )
+{
+  OPJ_OFF_T j2k_codestream_exit;
+  OPJ_BYTE l_data_header [24];
+
+  /* preconditions */
+  assert(jp2 != 00);
+  assert(cio != 00);
+  assert(p_manager != 00);
+  assert(opj_stream_has_seek(cio));
+
+  j2k_codestream_exit = opj_stream_tell(cio);
+  opj_write_bytes(l_data_header, 24, 4); /* size of iptr */
+  opj_write_bytes(l_data_header + 4,JPIP_IPTR,4);									   /* IPTR */
+#if 0
+  opj_write_bytes(l_data_header + 4 + 4, 0, 8); /* offset */
+  opj_write_bytes(l_data_header + 8 + 8, 0, 8); /* length */
+#else
+  opj_write_double(l_data_header + 4 + 4, 0); /* offset */
+  opj_write_double(l_data_header + 8 + 8, 0); /* length */
+#endif
+
+  if (! opj_stream_seek(cio,jp2->jpip_iptr_offset,p_manager)) {
+    opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
+    return OPJ_FALSE;
+  }
+
+  if (opj_stream_write_data(cio,l_data_header,24,p_manager) != 24) {
+    opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
+    return OPJ_FALSE;
+  }
+
+  if (! opj_stream_seek(cio,j2k_codestream_exit,p_manager)) {
+    opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
+    return OPJ_FALSE;
+  }
+
+  return OPJ_TRUE;
+}
+
+static OPJ_BOOL opj_jpip_write_fidx(opj_jp2_t *jp2,
+  opj_stream_private_t *cio,
+  opj_event_mgr_t * p_manager )
+{
+  OPJ_OFF_T j2k_codestream_exit;
+  OPJ_BYTE l_data_header [24];
+
+  /* preconditions */
+  assert(jp2 != 00);
+  assert(cio != 00);
+  assert(p_manager != 00);
+  assert(opj_stream_has_seek(cio));
+
+  opj_write_bytes(l_data_header, 24, 4); /* size of iptr */
+  opj_write_bytes(l_data_header + 4,JPIP_FIDX,4);									   /* IPTR */
+  opj_write_double(l_data_header + 4 + 4, 0); /* offset */
+  opj_write_double(l_data_header + 8 + 8, 0); /* length */
+
+  if (opj_stream_write_data(cio,l_data_header,24,p_manager) != 24) {
+    opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
+    return OPJ_FALSE;
+  }
+
+  j2k_codestream_exit = opj_stream_tell(cio);
+  if (! opj_stream_seek(cio,j2k_codestream_exit,p_manager)) {
+    opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
+    return OPJ_FALSE;
+  }
+
+  return OPJ_TRUE;
+}
+
+static OPJ_BOOL opj_jpip_write_cidx(opj_jp2_t *jp2,
+  opj_stream_private_t *cio,
+  opj_event_mgr_t * p_manager )
+{
+  OPJ_OFF_T j2k_codestream_exit;
+  OPJ_BYTE l_data_header [24];
+
+  /* preconditions */
+  assert(jp2 != 00);
+  assert(cio != 00);
+  assert(p_manager != 00);
+  assert(opj_stream_has_seek(cio));
+
+  j2k_codestream_exit = opj_stream_tell(cio);
+  opj_write_bytes(l_data_header, 24, 4); /* size of iptr */
+  opj_write_bytes(l_data_header + 4,JPIP_CIDX,4);									   /* IPTR */
+#if 0
+  opj_write_bytes(l_data_header + 4 + 4, 0, 8); /* offset */
+  opj_write_bytes(l_data_header + 8 + 8, 0, 8); /* length */
+#else
+  opj_write_double(l_data_header + 4 + 4, 0); /* offset */
+  opj_write_double(l_data_header + 8 + 8, 0); /* length */
+#endif
+
+  if (! opj_stream_seek(cio,j2k_codestream_exit,p_manager)) {
+    opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
+    return OPJ_FALSE;
+  }
+
+  if (opj_stream_write_data(cio,l_data_header,24,p_manager) != 24) {
+    opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
+    return OPJ_FALSE;
+  }
+
+  j2k_codestream_exit = opj_stream_tell(cio);
+  if (! opj_stream_seek(cio,j2k_codestream_exit,p_manager)) {
+    opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
+    return OPJ_FALSE;
+  }
+
+  return OPJ_TRUE;
+}
+
+#if 0
+static void write_prxy( int offset_jp2c, int length_jp2c, int offset_idx, int length_idx, opj_stream_private_t *cio,
+  opj_event_mgr_t * p_manager )
+{
+  OPJ_BYTE l_data_header [8];
+  OPJ_OFF_T len, lenp;
+
+  lenp = opj_stream_tell(cio);
+  opj_stream_skip(cio, 4, p_manager);         /* L [at the end] */
+  opj_write_bytes(l_data_header,JPIP_PRXY,4); /* IPTR           */
+  opj_stream_write_data(cio,l_data_header,4,p_manager);
+
+  opj_write_bytes( l_data_header, offset_jp2c, 8); /* OOFF           */
+  opj_stream_write_data(cio,l_data_header,8,p_manager);
+  opj_write_bytes( l_data_header, length_jp2c, 4); /* OBH part 1     */
+  opj_write_bytes( l_data_header+4, JP2_JP2C, 4);  /* OBH part 2     */
+  opj_stream_write_data(cio,l_data_header,8,p_manager);
+
+  opj_write_bytes( l_data_header, 1, 1);/* NI             */
+  opj_stream_write_data(cio,l_data_header,1,p_manager);
+
+  opj_write_bytes( l_data_header, offset_idx, 8);  /* IOFF           */
+  opj_stream_write_data(cio,l_data_header,8,p_manager);
+  opj_write_bytes( l_data_header, length_idx, 4);  /* IBH part 1     */
+  opj_write_bytes( l_data_header+4, JPIP_CIDX, 4);   /* IBH part 2     */
+  opj_stream_write_data(cio,l_data_header,8,p_manager);
+
+  len = opj_stream_tell(cio)-lenp;
+  opj_stream_skip(cio, lenp, p_manager);
+  opj_write_bytes(l_data_header,len,4);/* L              */
+  opj_stream_write_data(cio,l_data_header,4,p_manager);
+  opj_stream_seek(cio, lenp+len,p_manager);
+}
+#endif
+
+
+#if 0
+static int write_fidx( int offset_jp2c, int length_jp2c, int offset_idx, int length_idx, opj_stream_private_t *cio,
+  opj_event_mgr_t * p_manager )
+{
+  OPJ_BYTE l_data_header [4];
+  OPJ_OFF_T len, lenp;
+
+  lenp = opj_stream_tell(cio);
+  opj_stream_skip(cio, 4, p_manager);
+  opj_write_bytes(l_data_header,JPIP_FIDX,4); /* FIDX */
+  opj_stream_write_data(cio,l_data_header,4,p_manager);
+
+  write_prxy( offset_jp2c, length_jp2c, offset_idx, length_idx, cio,p_manager);
+
+  len = opj_stream_tell(cio)-lenp;
+  opj_stream_skip(cio, lenp, p_manager);
+  opj_write_bytes(l_data_header,len,4);/* L              */
+  opj_stream_write_data(cio,l_data_header,4,p_manager);
+  opj_stream_seek(cio, lenp+len,p_manager);
+
+  return len;
+}
+#endif
+#endif /* USE_JPIP */
diff --git a/Source/LibOpenJPEG/jp2.h b/Source/LibOpenJPEG/jp2.h
index 94153ee..e793d9a 100644
--- a/Source/LibOpenJPEG/jp2.h
+++ b/Source/LibOpenJPEG/jp2.h
@@ -1,234 +1,490 @@
-/*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
- * Copyright (c) 2002-2003, Yannick Verschueren
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef __JP2_H
-#define __JP2_H
-/**
- at file jp2.h
- at brief The JPEG-2000 file format Reader/Writer (JP2)
-
-*/
-
-/** @defgroup JP2 JP2 - JPEG-2000 file format reader/writer */
-/*@{*/
-
-#define JPIP_JPIP 0x6a706970
-
-#define JP2_JP   0x6a502020		/**< JPEG 2000 signature box */
-#define JP2_FTYP 0x66747970		/**< File type box */
-#define JP2_JP2H 0x6a703268		/**< JP2 header box */
-#define JP2_IHDR 0x69686472		/**< Image header box */
-#define JP2_COLR 0x636f6c72		/**< Colour specification box */
-#define JP2_JP2C 0x6a703263		/**< Contiguous codestream box */
-#define JP2_URL  0x75726c20		/**< URL box */
-#define JP2_DTBL 0x6474626c		/**< Data Reference box */
-#define JP2_BPCC 0x62706363		/**< Bits per component box */
-#define JP2_JP2  0x6a703220		/**< File type fields */
-#define JP2_PCLR 0x70636c72		/**< Palette box */
-#define JP2_CMAP 0x636d6170		/**< Component Mapping box */
-#define JP2_CDEF 0x63646566		/**< Channel Definition box */
-
-/* ----------------------------------------------------------------------- */
-/** 
-Channel description: channel index, type, assocation
-*/
-typedef struct opj_jp2_cdef_info
-{
-    unsigned short cn, typ, asoc;
-} opj_jp2_cdef_info_t;
-
-/** 
-Channel descriptions and number of descriptions
-*/
-typedef struct opj_jp2_cdef
-{
-    opj_jp2_cdef_info_t *info;
-    unsigned short n;
-} opj_jp2_cdef_t;
-
-/** 
-Component mappings: channel index, mapping type, palette index
-*/
-typedef struct opj_jp2_cmap_comp
-{
-    unsigned short cmp;
-    unsigned char mtyp, pcol;
-} opj_jp2_cmap_comp_t;
-
-/** 
-Palette data: table entries, palette columns
-*/
-typedef struct opj_jp2_pclr
-{
-    unsigned int *entries;
-    unsigned char *channel_sign;
-    unsigned char *channel_size;
-    opj_jp2_cmap_comp_t *cmap;
-    unsigned short nr_entries, nr_channels;
-} opj_jp2_pclr_t;
-
-/** 
-Collector for ICC profile, palette, component mapping, channel description 
-*/
-typedef struct opj_jp2_color
-{
-    unsigned char *icc_profile_buf;
-    int icc_profile_len;
-
-    opj_jp2_cdef_t *jp2_cdef;
-    opj_jp2_pclr_t *jp2_pclr;
-    unsigned char jp2_has_colr;
-} opj_jp2_color_t;
-
-/** 
-JP2 component
-*/
-typedef struct opj_jp2_comps {
-  int depth;		  
-  int sgnd;		   
-  int bpcc;
-} opj_jp2_comps_t;
-
-/**
-JPEG-2000 file format reader/writer
-*/
-typedef struct opj_jp2 {
-	/** codec context */
-	opj_common_ptr cinfo;
-	/** handle to the J2K codec  */
-	opj_j2k_t *j2k;
-	unsigned int w;
-	unsigned int h;
-	unsigned int numcomps;
-	unsigned int bpc;
-	unsigned int C;
-	unsigned int UnkC;
-	unsigned int IPR;
-	unsigned int meth;
-	unsigned int approx;
-	unsigned int enumcs;
-	unsigned int precedence;
-	unsigned int brand;
-	unsigned int minversion;
-	unsigned int numcl;
-	unsigned int *cl;
-	opj_jp2_comps_t *comps;
-	unsigned int j2k_codestream_offset;
-	unsigned int j2k_codestream_length;
-	opj_bool jpip_on;
-	opj_bool ignore_pclr_cmap_cdef;
-} opj_jp2_t;
-
-/**
-JP2 Box
-*/
-typedef struct opj_jp2_box {
-  int length;
-  int type;
-  int init_pos;
-} opj_jp2_box_t;
-
-/** @name Exported functions */
-/*@{*/
-/* ----------------------------------------------------------------------- */
-/**
-Write the JP2H box - JP2 Header box (used in MJ2)
- at param jp2 JP2 handle
- at param cio Output buffer stream
-*/
-void jp2_write_jp2h(opj_jp2_t *jp2, opj_cio_t *cio);
-/**
-Read the JP2H box - JP2 Header box (used in MJ2)
- at param jp2 JP2 handle
- at param cio Input buffer stream
- at param ext Collector for profile, cdef and pclr data
- at return Returns true if successful, returns false otherwise
-*/
-opj_bool jp2_read_jp2h(opj_jp2_t *jp2, opj_cio_t *cio, opj_jp2_color_t *color);
-/**
-Creates a JP2 decompression structure
- at param cinfo Codec context info
- at return Returns a handle to a JP2 decompressor if successful, returns NULL otherwise
-*/
-opj_jp2_t* jp2_create_decompress(opj_common_ptr cinfo);
-/**
-Destroy a JP2 decompressor handle
- at param jp2 JP2 decompressor handle to destroy
-*/
-void jp2_destroy_decompress(opj_jp2_t *jp2);
-/**
-Setup the decoder decoding parameters using user parameters.
-Decoding parameters are returned in jp2->j2k->cp. 
- at param jp2 JP2 decompressor handle
- at param parameters decompression parameters
-*/
-void jp2_setup_decoder(opj_jp2_t *jp2, opj_dparameters_t *parameters);
-/**
-Decode an image from a JPEG-2000 file stream
- at param jp2 JP2 decompressor handle
- at param cio Input buffer stream
- at param cstr_info Codestream information structure if required, NULL otherwise
- at return Returns a decoded image if successful, returns NULL otherwise
-*/
-opj_image_t* opj_jp2_decode(opj_jp2_t *jp2, opj_cio_t *cio, opj_codestream_info_t *cstr_info);
-/**
-Creates a JP2 compression structure
- at param cinfo Codec context info
- at return Returns a handle to a JP2 compressor if successful, returns NULL otherwise
-*/
-opj_jp2_t* jp2_create_compress(opj_common_ptr cinfo);
-/**
-Destroy a JP2 compressor handle
- at param jp2 JP2 compressor handle to destroy
-*/
-void jp2_destroy_compress(opj_jp2_t *jp2);
-/**
-Setup the encoder parameters using the current image and using user parameters. 
-Coding parameters are returned in jp2->j2k->cp. 
- at param jp2 JP2 compressor handle
- at param parameters compression parameters
- at param image input filled image
-*/
-void jp2_setup_encoder(opj_jp2_t *jp2, opj_cparameters_t *parameters, opj_image_t *image);
-/**
-Encode an image into a JPEG-2000 file stream
- at param jp2 JP2 compressor handle
- at param cio Output buffer stream
- at param image Image to encode
- at param cstr_info Codestream information structure if required, NULL otherwise
- at return Returns true if successful, returns false otherwise
-*/
-opj_bool opj_jp2_encode(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info);
-
-/* ----------------------------------------------------------------------- */
-/*@}*/
-
-/*@}*/
-
-#endif /* __JP2_H */
-
+/*
+ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2007, Professor Benoit Macq
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2008;2011-2012, Centre National d'Etudes Spatiales (CNES), France 
+ * Copyright (c) 2012, CS Systemes d'Information, France
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef __JP2_H
+#define __JP2_H
+/**
+ at file jp2.h
+ at brief The JPEG-2000 file format Reader/Writer (JP2)
+
+*/
+
+/** @defgroup JP2 JP2 - JPEG-2000 file format reader/writer */
+/*@{*/
+
+/*#define JPIP_JPIP 0x6a706970*/
+
+#define     JP2_JP   0x6a502020    /**< JPEG 2000 signature box */
+#define     JP2_FTYP 0x66747970    /**< File type box */
+#define     JP2_JP2H 0x6a703268    /**< JP2 header box (super-box) */
+#define     JP2_IHDR 0x69686472    /**< Image header box */
+#define     JP2_COLR 0x636f6c72    /**< Colour specification box */
+#define     JP2_JP2C 0x6a703263    /**< Contiguous codestream box */
+#define     JP2_URL  0x75726c20    /**< Data entry URL box */
+#define     JP2_PCLR 0x70636c72    /**< Palette box */
+#define     JP2_CMAP 0x636d6170    /**< Component Mapping box */
+#define     JP2_CDEF 0x63646566    /**< Channel Definition box */
+#define     JP2_DTBL 0x6474626c    /**< Data Reference box */
+#define     JP2_BPCC 0x62706363    /**< Bits per component box */
+#define     JP2_JP2  0x6a703220    /**< File type fields */
+
+/* For the future */
+/* #define JP2_RES 0x72657320 */  /**< Resolution box (super-box) */
+/* #define JP2_JP2I 0x6a703269 */  /**< Intellectual property box */
+/* #define JP2_XML  0x786d6c20 */  /**< XML box */
+/* #define JP2_UUID 0x75756994 */  /**< UUID box */
+/* #define JP2_UINF 0x75696e66 */  /**< UUID info box (super-box) */
+/* #define JP2_ULST 0x756c7374 */  /**< UUID list box */
+
+/* ----------------------------------------------------------------------- */
+
+typedef enum
+{
+  JP2_STATE_NONE            = 0x0,
+  JP2_STATE_SIGNATURE       = 0x1,
+  JP2_STATE_FILE_TYPE       = 0x2,
+  JP2_STATE_HEADER          = 0x4,
+  JP2_STATE_CODESTREAM      = 0x8,
+  JP2_STATE_END_CODESTREAM  = 0x10,
+  JP2_STATE_UNKNOWN         = 0x7fffffff /* ISO C restricts enumerator values to range of 'int' */
+}
+JP2_STATE;
+
+typedef enum
+{
+  JP2_IMG_STATE_NONE        = 0x0,
+  JP2_IMG_STATE_UNKNOWN     = 0x7fffffff
+}
+JP2_IMG_STATE;
+
+/** 
+Channel description: channel index, type, assocation
+*/
+typedef struct opj_jp2_cdef_info
+{
+    OPJ_UINT16 cn, typ, asoc;
+} opj_jp2_cdef_info_t;
+
+/** 
+Channel descriptions and number of descriptions
+*/
+typedef struct opj_jp2_cdef
+{
+    opj_jp2_cdef_info_t *info;
+    OPJ_UINT16 n;
+} opj_jp2_cdef_t;
+
+/** 
+Component mappings: channel index, mapping type, palette index
+*/
+typedef struct opj_jp2_cmap_comp
+{
+    OPJ_UINT16 cmp;
+    OPJ_BYTE mtyp, pcol;
+} opj_jp2_cmap_comp_t;
+
+/** 
+Palette data: table entries, palette columns
+*/
+typedef struct opj_jp2_pclr
+{
+    OPJ_UINT32 *entries;
+    OPJ_BYTE *channel_sign;
+    OPJ_BYTE *channel_size;
+    opj_jp2_cmap_comp_t *cmap;
+    OPJ_UINT16 nr_entries;
+    OPJ_BYTE nr_channels;
+} opj_jp2_pclr_t;
+
+/** 
+Collector for ICC profile, palette, component mapping, channel description 
+*/
+typedef struct opj_jp2_color
+{
+    OPJ_BYTE *icc_profile_buf;
+    OPJ_UINT32 icc_profile_len;
+
+    opj_jp2_cdef_t *jp2_cdef;
+    opj_jp2_pclr_t *jp2_pclr;
+    OPJ_BYTE jp2_has_colr;
+} opj_jp2_color_t;
+
+/** 
+JP2 component
+*/
+typedef struct opj_jp2_comps {
+  OPJ_UINT32 depth;      
+  OPJ_UINT32 sgnd;       
+  OPJ_UINT32 bpcc;
+} opj_jp2_comps_t;
+
+/**
+JPEG-2000 file format reader/writer
+*/
+typedef struct opj_jp2
+{
+  /** handle to the J2K codec  */
+  opj_j2k_t *j2k;
+  /** list of validation procedures */
+  struct opj_procedure_list * m_validation_list;
+  /** list of execution procedures */
+  struct opj_procedure_list * m_procedure_list;
+
+  /* width of image */
+  OPJ_UINT32 w;
+  /* height of image */
+  OPJ_UINT32 h;
+  /* number of components in the image */
+  OPJ_UINT32 numcomps;
+  OPJ_UINT32 bpc;
+  OPJ_UINT32 C;
+  OPJ_UINT32 UnkC;
+  OPJ_UINT32 IPR;
+  OPJ_UINT32 meth;
+  OPJ_UINT32 approx;
+  OPJ_UINT32 enumcs;
+  OPJ_UINT32 precedence;
+  OPJ_UINT32 brand;
+  OPJ_UINT32 minversion;
+  OPJ_UINT32 numcl;
+  OPJ_UINT32 *cl;
+  opj_jp2_comps_t *comps;
+  /* FIXME: The following two variables are used to save offset
+    as we write out a JP2 file to disk. This mecanism is not flexible
+    as codec writers will need to extand those fields as new part
+    of the standard are implemented.
+  */
+    OPJ_OFF_T j2k_codestream_offset;
+    OPJ_OFF_T jpip_iptr_offset;
+	OPJ_BOOL jpip_on;
+  OPJ_UINT32 jp2_state;
+  OPJ_UINT32 jp2_img_state;
+
+  opj_jp2_color_t color;
+    
+    OPJ_BOOL ignore_pclr_cmap_cdef;
+}
+opj_jp2_t;
+
+/**
+JP2 Box
+*/
+typedef struct opj_jp2_box {
+    OPJ_UINT32 length;
+    OPJ_UINT32 type;
+    OPJ_INT32 init_pos;
+} opj_jp2_box_t;
+
+typedef struct opj_jp2_header_handler
+{
+  /* marker value */
+  OPJ_UINT32 id;
+  /* action linked to the marker */
+  OPJ_BOOL (*handler) (     opj_jp2_t *jp2, 
+                            OPJ_BYTE *p_header_data, 
+                            OPJ_UINT32 p_header_size, 
+                            opj_event_mgr_t * p_manager);
+}
+opj_jp2_header_handler_t;
+
+
+typedef struct opj_jp2_img_header_writer_handler 
+{
+  /* action to perform */
+  OPJ_BYTE*   (*handler) (opj_jp2_t *jp2, OPJ_UINT32 * p_data_size);
+  /* result of the action : data */
+  OPJ_BYTE*   m_data;
+  /* size of data */
+  OPJ_UINT32  m_size;
+} 
+opj_jp2_img_header_writer_handler_t;
+
+/** @name Exported functions */
+/*@{*/
+/* ----------------------------------------------------------------------- */
+
+/**
+ * Writes the Jpeg2000 file Header box - JP2 Header box (warning, this is a super box).
+ *
+ * @param  jp2      the jpeg2000 file codec.
+ * @param  stream      the stream to write data to.
+ * @param  p_manager  user event manager.
+ *
+ * @return true if writing was successful.
+*/
+OPJ_BOOL opj_jp2_write_jp2h(opj_jp2_t *jp2,
+                            opj_stream_private_t *stream,
+                            opj_event_mgr_t * p_manager );
+
+/**
+Setup the decoder decoding parameters using user parameters.
+Decoding parameters are returned in jp2->j2k->cp.
+ at param jp2 JP2 decompressor handle
+ at param parameters decompression parameters
+*/
+void opj_jp2_setup_decoder(opj_jp2_t *jp2, opj_dparameters_t *parameters);
+
+/**
+ * Decode an image from a JPEG-2000 file stream
+ * @param jp2 JP2 decompressor handle
+ * @param p_stream  FIXME DOC
+ * @param p_image   FIXME DOC
+ * @param p_manager FIXME DOC
+ *
+ * @return Returns a decoded image if successful, returns NULL otherwise
+*/
+OPJ_BOOL opj_jp2_decode(opj_jp2_t *jp2,
+                        opj_stream_private_t *p_stream,
+            opj_image_t* p_image,
+            opj_event_mgr_t * p_manager);
+
+/**
+ * Setup the encoder parameters using the current image and using user parameters. 
+ * Coding parameters are returned in jp2->j2k->cp. 
+ *
+ * @param jp2 JP2 compressor handle
+ * @param parameters compression parameters
+ * @param image input filled image
+ * @param p_manager  FIXME DOC
+*/
+void opj_jp2_setup_encoder(  opj_jp2_t *jp2, 
+                            opj_cparameters_t *parameters, 
+                            opj_image_t *image, 
+                            opj_event_mgr_t * p_manager);
+
+/**
+Encode an image into a JPEG-2000 file stream
+ at param jp2      JP2 compressor handle
+ at param stream    Output buffer stream
+ at param p_manager  event manager
+ at return Returns true if successful, returns false otherwise
+*/
+OPJ_BOOL opj_jp2_encode(  opj_jp2_t *jp2, 
+              opj_stream_private_t *stream, 
+              opj_event_mgr_t * p_manager);
+
+
+/**
+ * Starts a compression scheme, i.e. validates the codec parameters, writes the header.
+ *
+ * @param  jp2    the jpeg2000 file codec.
+ * @param  stream    the stream object.
+ * @param  p_image   FIXME DOC
+ * @param p_manager FIXME DOC
+ *
+ * @return true if the codec is valid.
+ */
+OPJ_BOOL opj_jp2_start_compress(opj_jp2_t *jp2,
+                                opj_stream_private_t *stream,
+                                opj_image_t * p_image,
+                                opj_event_mgr_t * p_manager);
+
+
+/**
+ * Ends the compression procedures and possibiliy add data to be read after the
+ * codestream.
+ */
+OPJ_BOOL opj_jp2_end_compress(  opj_jp2_t *jp2,
+                  opj_stream_private_t *cio,
+                  opj_event_mgr_t * p_manager);
+
+/* ----------------------------------------------------------------------- */
+
+/**
+ * Ends the decompression procedures and possibiliy add data to be read after the
+ * codestream.
+ */
+OPJ_BOOL opj_jp2_end_decompress(opj_jp2_t *jp2, 
+                                opj_stream_private_t *cio,
+                                opj_event_mgr_t * p_manager);
+
+/**
+ * Reads a jpeg2000 file header structure.
+ *
+ * @param p_stream the stream to read data from.
+ * @param jp2 the jpeg2000 file header structure.
+ * @param p_image   FIXME DOC
+ * @param p_manager the user event manager.
+ *
+ * @return true if the box is valid.
+ */
+OPJ_BOOL opj_jp2_read_header(  opj_stream_private_t *p_stream,
+                                opj_jp2_t *jp2,
+                                opj_image_t ** p_image,
+                                opj_event_mgr_t * p_manager );
+
+/**
+ * Reads a tile header.
+ * @param  p_jp2         the jpeg2000 codec.
+ * @param  p_tile_index  FIXME DOC
+ * @param  p_data_size   FIXME DOC
+ * @param  p_tile_x0     FIXME DOC
+ * @param  p_tile_y0     FIXME DOC
+ * @param  p_tile_x1     FIXME DOC
+ * @param  p_tile_y1     FIXME DOC
+ * @param  p_nb_comps    FIXME DOC
+ * @param  p_go_on       FIXME DOC
+ * @param  p_stream      the stream to write data to.
+ * @param  p_manager     the user event manager.
+ */
+OPJ_BOOL opj_jp2_read_tile_header ( opj_jp2_t * p_jp2,
+                                    OPJ_UINT32 * p_tile_index,
+                                    OPJ_UINT32 * p_data_size,
+                                    OPJ_INT32 * p_tile_x0,
+                                    OPJ_INT32 * p_tile_y0,
+                                    OPJ_INT32 * p_tile_x1,
+                                    OPJ_INT32 * p_tile_y1,
+                                    OPJ_UINT32 * p_nb_comps,
+                                    OPJ_BOOL * p_go_on,
+                                    opj_stream_private_t *p_stream,
+                                    opj_event_mgr_t * p_manager );
+
+/**
+ * Writes a tile.
+ *
+ * @param  p_jp2    the jpeg2000 codec.
+ * @param p_tile_index  FIXME DOC
+ * @param p_data        FIXME DOC
+ * @param p_data_size   FIXME DOC
+ * @param  p_stream      the stream to write data to.
+ * @param  p_manager  the user event manager.
+ */
+OPJ_BOOL opj_jp2_write_tile (  opj_jp2_t *p_jp2,
+                    OPJ_UINT32 p_tile_index,
+                    OPJ_BYTE * p_data,
+                    OPJ_UINT32 p_data_size,
+                    opj_stream_private_t *p_stream,
+                    opj_event_mgr_t * p_manager );
+
+/**
+ * Decode tile data.
+ * @param  p_jp2    the jpeg2000 codec.
+ * @param  p_tile_index FIXME DOC
+ * @param  p_data       FIXME DOC
+ * @param  p_data_size  FIXME DOC
+ * @param  p_stream      the stream to write data to.
+ * @param  p_manager  the user event manager.
+ *
+ * @return FIXME DOC
+ */
+OPJ_BOOL opj_jp2_decode_tile (  opj_jp2_t * p_jp2,
+                                OPJ_UINT32 p_tile_index,
+                                OPJ_BYTE * p_data,
+                                OPJ_UINT32 p_data_size,
+                                opj_stream_private_t *p_stream,
+                                opj_event_mgr_t * p_manager );
+
+/**
+ * Creates a jpeg2000 file decompressor.
+ *
+ * @return  an empty jpeg2000 file codec.
+ */
+opj_jp2_t* opj_jp2_create (OPJ_BOOL p_is_decoder);
+
+/**
+Destroy a JP2 decompressor handle
+ at param jp2 JP2 decompressor handle to destroy
+*/
+void opj_jp2_destroy(opj_jp2_t *jp2);
+
+
+/**
+ * Sets the given area to be decoded. This function should be called right after opj_read_header and before any tile header reading.
+ *
+ * @param  p_jp2      the jpeg2000 codec.
+ * @param  p_image     FIXME DOC
+ * @param  p_start_x   the left position of the rectangle to decode (in image coordinates).
+ * @param  p_start_y    the up position of the rectangle to decode (in image coordinates).
+ * @param  p_end_x      the right position of the rectangle to decode (in image coordinates).
+ * @param  p_end_y      the bottom position of the rectangle to decode (in image coordinates).
+ * @param  p_manager    the user event manager
+ *
+ * @return  true      if the area could be set.
+ */
+OPJ_BOOL opj_jp2_set_decode_area(  opj_jp2_t *p_jp2,
+                    opj_image_t* p_image,
+                    OPJ_INT32 p_start_x, OPJ_INT32 p_start_y,
+                    OPJ_INT32 p_end_x, OPJ_INT32 p_end_y,
+                    opj_event_mgr_t * p_manager );
+
+ /**
+ * 
+ */
+OPJ_BOOL opj_jp2_get_tile(  opj_jp2_t *p_jp2,
+                            opj_stream_private_t *p_stream,
+                            opj_image_t* p_image,
+                            opj_event_mgr_t * p_manager,
+                            OPJ_UINT32 tile_index );
+
+
+/**
+ * 
+ */
+OPJ_BOOL opj_jp2_set_decoded_resolution_factor(opj_jp2_t *p_jp2, 
+                                               OPJ_UINT32 res_factor, 
+                                               opj_event_mgr_t * p_manager);
+
+
+/* TODO MSD: clean these 3 functions */
+/**
+ * Dump some elements from the JP2 decompression structure .
+ *
+ *@param p_jp2        the jp2 codec.
+ *@param flag        flag to describe what elments are dump.
+ *@param out_stream      output stream where dump the elements.
+ *
+*/
+void jp2_dump (opj_jp2_t* p_jp2, OPJ_INT32 flag, FILE* out_stream);
+
+/**
+ * Get the codestream info from a JPEG2000 codec.
+ *
+ *@param  p_jp2        jp2 codec.
+ *
+ *@return  the codestream information extract from the jpg2000 codec
+ */
+opj_codestream_info_v2_t* jp2_get_cstr_info(opj_jp2_t* p_jp2);
+
+/**
+ * Get the codestream index from a JPEG2000 codec.
+ *
+ *@param  p_jp2        jp2 codec.
+ *
+ *@return  the codestream index extract from the jpg2000 codec
+ */
+opj_codestream_index_t* jp2_get_cstr_index(opj_jp2_t* p_jp2);
+
+
+/*@}*/
+
+/*@}*/
+
+#endif /* __JP2_H */
+
diff --git a/Source/LibOpenJPEG/jpt.c b/Source/LibOpenJPEG/jpt.c
deleted file mode 100644
index 54898ec..0000000
--- a/Source/LibOpenJPEG/jpt.c
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
- * Copyright (c) 2002-2003, Yannick Verschueren
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "opj_includes.h"
-
-/*
- * Read the information contains in VBAS [JPP/JPT stream message header]
- * Store information (7 bits) in value
- *
- */
-unsigned int jpt_read_VBAS_info(opj_cio_t *cio, unsigned int value) {
-	unsigned char elmt;
-
-	elmt = cio_read(cio, 1);
-	while ((elmt >> 7) == 1) {
-		value = (value << 7);
-		value |= (elmt & 0x7f);
-		elmt = cio_read(cio, 1);
-	}
-	value = (value << 7);
-	value |= (elmt & 0x7f);
-
-	return value;
-}
-
-/*
- * Initialize the value of the message header structure 
- *
- */
-void jpt_init_msg_header(opj_jpt_msg_header_t * header) {
-	header->Id = 0;		/* In-class Identifier    */
-	header->last_byte = 0;	/* Last byte information  */
-	header->Class_Id = 0;		/* Class Identifier       */
-	header->CSn_Id = 0;		/* CSn : index identifier */
-	header->Msg_offset = 0;	/* Message offset         */
-	header->Msg_length = 0;	/* Message length         */
-	header->Layer_nb = 0;		/* Auxiliary for JPP case */
-}
-
-/*
- * Re-initialize the value of the message header structure
- *
- * Only parameters always present in message header
- *
- */
-void jpt_reinit_msg_header(opj_jpt_msg_header_t * header) {
-	header->Id = 0;		/* In-class Identifier    */
-	header->last_byte = 0;	/* Last byte information  */
-	header->Msg_offset = 0;	/* Message offset         */
-	header->Msg_length = 0;	/* Message length         */
-}
-
-/*
- * Read the message header for a JPP/JPT - stream
- *
- */
-void jpt_read_msg_header(opj_common_ptr cinfo, opj_cio_t *cio, opj_jpt_msg_header_t *header) {
-	unsigned char elmt, Class = 0, CSn = 0;
-	jpt_reinit_msg_header(header);
-
-	/* ------------- */
-	/* VBAS : Bin-ID */
-	/* ------------- */
-	elmt = cio_read(cio, 1);
-
-	/* See for Class and CSn */
-	switch ((elmt >> 5) & 0x03) {
-		case 0:
-			opj_event_msg(cinfo, EVT_ERROR, "Forbidden value encounter in message header !!\n");
-			break;
-		case 1:
-			Class = 0;
-			CSn = 0;
-			break;
-		case 2:
-			Class = 1;
-			CSn = 0;
-			break;
-		case 3:
-			Class = 1;
-			CSn = 1;
-			break;
-		default:
-			break;
-	}
-
-	/* see information on bits 'c' [p 10 : A.2.1 general, ISO/IEC FCD 15444-9] */
-	if (((elmt >> 4) & 0x01) == 1)
-		header->last_byte = 1;
-
-	/* In-class identifier */
-	header->Id |= (elmt & 0x0f);
-	if ((elmt >> 7) == 1)
-		header->Id = jpt_read_VBAS_info(cio, header->Id);
-
-	/* ------------ */
-	/* VBAS : Class */
-	/* ------------ */
-	if (Class == 1) {
-		header->Class_Id = 0;
-		header->Class_Id = jpt_read_VBAS_info(cio, header->Class_Id);
-	}
-
-	/* ---------- */
-	/* VBAS : CSn */
-	/* ---------- */
-	if (CSn == 1) {
-		header->CSn_Id = 0;
-		header->CSn_Id = jpt_read_VBAS_info(cio, header->CSn_Id);
-	}
-
-	/* ----------------- */
-	/* VBAS : Msg_offset */
-	/* ----------------- */
-	header->Msg_offset = jpt_read_VBAS_info(cio, header->Msg_offset);
-
-	/* ----------------- */
-	/* VBAS : Msg_length */
-	/* ----------------- */
-	header->Msg_length = jpt_read_VBAS_info(cio, header->Msg_length);
-
-	/* ---------- */
-	/* VBAS : Aux */
-	/* ---------- */
-	if ((header->Class_Id & 0x01) == 1) {
-		header->Layer_nb = 0;
-		header->Layer_nb = jpt_read_VBAS_info(cio, header->Layer_nb);
-	}
-}
diff --git a/Source/LibOpenJPEG/jpt.h b/Source/LibOpenJPEG/jpt.h
deleted file mode 100644
index eeac700..0000000
--- a/Source/LibOpenJPEG/jpt.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
- * Copyright (c) 2002-2003, Yannick Verschueren
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __JPT_H
-#define __JPT_H
-/**
- at file jpt.h
- at brief JPT-stream reader (JPEG 2000, JPIP)
-
-JPT-stream functions are implemented in J2K.C. 
-*/
-
-/**
-Message Header JPT stream structure
-*/
-typedef struct opj_jpt_msg_header {
-	/** In-class Identifier */
-	unsigned int Id;
-	/** Last byte information */
-	unsigned int last_byte;	
-	/** Class Identifier */
-	unsigned int Class_Id;	
-	/** CSn : index identifier */
-	unsigned int CSn_Id;
-	/** Message offset */
-	unsigned int Msg_offset;
-	/** Message length */
-	unsigned int Msg_length;
-	/** Auxiliary for JPP case */
-	unsigned int Layer_nb;
-} opj_jpt_msg_header_t;
-
-/* ----------------------------------------------------------------------- */
-
-/**
-Initialize the value of the message header structure 
- at param header Message header structure
-*/
-void jpt_init_msg_header(opj_jpt_msg_header_t * header);
-
-/**
-Read the message header for a JPP/JPT - stream
- at param cinfo Codec context info
- at param cio CIO handle
- at param header Message header structure
-*/
-void jpt_read_msg_header(opj_common_ptr cinfo, opj_cio_t *cio, opj_jpt_msg_header_t *header);
-
-#endif
diff --git a/Source/LibOpenJPEG/mct.c b/Source/LibOpenJPEG/mct.c
index 152a005..d2754dc 100644
--- a/Source/LibOpenJPEG/mct.c
+++ b/Source/LibOpenJPEG/mct.c
@@ -1,190 +1,319 @@
-/*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
- * Copyright (c) 2001-2003, David Janssens
- * Copyright (c) 2002-2003, Yannick Verschueren
- * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifdef __SSE__
-#include <xmmintrin.h>
-#endif
-
-#include "opj_includes.h"
-
-/* <summary> */
-/* This table contains the norms of the basis function of the reversible MCT. */
-/* </summary> */
-static const double mct_norms[3] = { 1.732, .8292, .8292 };
-
-/* <summary> */
-/* This table contains the norms of the basis function of the irreversible MCT. */
-/* </summary> */
-static const double mct_norms_real[3] = { 1.732, 1.805, 1.573 };
-
-/* <summary> */
-/* Foward reversible MCT. */
-/* </summary> */
-void mct_encode(
-		int* restrict c0,
-		int* restrict c1,
-		int* restrict c2,
-		int n)
-{
-	int i;
-	for(i = 0; i < n; ++i) {
-		int r = c0[i];
-		int g = c1[i];
-		int b = c2[i];
-		int y = (r + (g * 2) + b) >> 2;
-		int u = b - g;
-		int v = r - g;
-		c0[i] = y;
-		c1[i] = u;
-		c2[i] = v;
-	}
-}
-
-/* <summary> */
-/* Inverse reversible MCT. */
-/* </summary> */
-void mct_decode(
-		int* restrict c0,
-		int* restrict c1, 
-		int* restrict c2, 
-		int n)
-{
-	int i;
-	for (i = 0; i < n; ++i) {
-		int y = c0[i];
-		int u = c1[i];
-		int v = c2[i];
-		int g = y - ((u + v) >> 2);
-		int r = v + g;
-		int b = u + g;
-		c0[i] = r;
-		c1[i] = g;
-		c2[i] = b;
-	}
-}
-
-/* <summary> */
-/* Get norm of basis function of reversible MCT. */
-/* </summary> */
-double mct_getnorm(int compno) {
-	return mct_norms[compno];
-}
-
-/* <summary> */
-/* Foward irreversible MCT. */
-/* </summary> */
-void mct_encode_real(
-		int* restrict c0,
-		int* restrict c1,
-		int* restrict c2,
-		int n)
-{
-	int i;
-	for(i = 0; i < n; ++i) {
-		int r = c0[i];
-		int g = c1[i];
-		int b = c2[i];
-		int y =  fix_mul(r, 2449) + fix_mul(g, 4809) + fix_mul(b, 934);
-		int u = -fix_mul(r, 1382) - fix_mul(g, 2714) + fix_mul(b, 4096);
-		int v =  fix_mul(r, 4096) - fix_mul(g, 3430) - fix_mul(b, 666);
-		c0[i] = y;
-		c1[i] = u;
-		c2[i] = v;
-	}
-}
-
-/* <summary> */
-/* Inverse irreversible MCT. */
-/* </summary> */
-void mct_decode_real(
-		float* restrict c0,
-		float* restrict c1,
-		float* restrict c2,
-		int n)
-{
-	int i;
-#ifdef __SSE__
-	__m128 vrv, vgu, vgv, vbu;
-	vrv = _mm_set1_ps(1.402f);
-	vgu = _mm_set1_ps(0.34413f);
-	vgv = _mm_set1_ps(0.71414f);
-	vbu = _mm_set1_ps(1.772f);
-	for (i = 0; i < (n >> 3); ++i) {
-		__m128 vy, vu, vv;
-		__m128 vr, vg, vb;
-
-		vy = _mm_load_ps(c0);
-		vu = _mm_load_ps(c1);
-		vv = _mm_load_ps(c2);
-		vr = _mm_add_ps(vy, _mm_mul_ps(vv, vrv));
-		vg = _mm_sub_ps(_mm_sub_ps(vy, _mm_mul_ps(vu, vgu)), _mm_mul_ps(vv, vgv));
-		vb = _mm_add_ps(vy, _mm_mul_ps(vu, vbu));
-		_mm_store_ps(c0, vr);
-		_mm_store_ps(c1, vg);
-		_mm_store_ps(c2, vb);
-		c0 += 4;
-		c1 += 4;
-		c2 += 4;
-
-		vy = _mm_load_ps(c0);
-		vu = _mm_load_ps(c1);
-		vv = _mm_load_ps(c2);
-		vr = _mm_add_ps(vy, _mm_mul_ps(vv, vrv));
-		vg = _mm_sub_ps(_mm_sub_ps(vy, _mm_mul_ps(vu, vgu)), _mm_mul_ps(vv, vgv));
-		vb = _mm_add_ps(vy, _mm_mul_ps(vu, vbu));
-		_mm_store_ps(c0, vr);
-		_mm_store_ps(c1, vg);
-		_mm_store_ps(c2, vb);
-		c0 += 4;
-		c1 += 4;
-		c2 += 4;
-	}
-	n &= 7;
-#endif
-	for(i = 0; i < n; ++i) {
-		float y = c0[i];
-		float u = c1[i];
-		float v = c2[i];
-		float r = y + (v * 1.402f);
-		float g = y - (u * 0.34413f) - (v * (0.71414f));
-		float b = y + (u * 1.772f);
-		c0[i] = r;
-		c1[i] = g;
-		c2[i] = b;
-	}
-}
-
-/* <summary> */
-/* Get norm of basis function of irreversible MCT. */
-/* </summary> */
-double mct_getnorm_real(int compno) {
-	return mct_norms_real[compno];
-}
+/*
+ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2007, Professor Benoit Macq
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2008;2011-2012, Centre National d'Etudes Spatiales (CNES), France 
+ * Copyright (c) 2012, CS Systemes d'Information, France
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef __SSE__
+#include <xmmintrin.h>
+#endif
+
+#include "opj_includes.h"
+
+/* <summary> */
+/* This table contains the norms of the basis function of the reversible MCT. */
+/* </summary> */
+static const OPJ_FLOAT64 opj_mct_norms[3] = { 1.732, .8292, .8292 };
+
+/* <summary> */
+/* This table contains the norms of the basis function of the irreversible MCT. */
+/* </summary> */
+static const OPJ_FLOAT64 opj_mct_norms_real[3] = { 1.732, 1.805, 1.573 };
+
+const OPJ_FLOAT64 * opj_mct_get_mct_norms ()
+{
+	return opj_mct_norms;
+}
+
+const OPJ_FLOAT64 * opj_mct_get_mct_norms_real ()
+{
+	return opj_mct_norms_real;
+}
+
+/* <summary> */
+/* Foward reversible MCT. */
+/* </summary> */
+void opj_mct_encode(
+		OPJ_INT32* restrict c0,
+		OPJ_INT32* restrict c1,
+		OPJ_INT32* restrict c2,
+		OPJ_UINT32 n)
+{
+	OPJ_UINT32 i;
+	for(i = 0; i < n; ++i) {
+		OPJ_INT32 r = c0[i];
+		OPJ_INT32 g = c1[i];
+		OPJ_INT32 b = c2[i];
+		OPJ_INT32 y = (r + (g * 2) + b) >> 2;
+		OPJ_INT32 u = b - g;
+		OPJ_INT32 v = r - g;
+		c0[i] = y;
+		c1[i] = u;
+		c2[i] = v;
+	}
+}
+
+/* <summary> */
+/* Inverse reversible MCT. */
+/* </summary> */
+void opj_mct_decode(
+		OPJ_INT32* restrict c0,
+		OPJ_INT32* restrict c1, 
+		OPJ_INT32* restrict c2, 
+		OPJ_UINT32 n)
+{
+	OPJ_UINT32 i;
+	for (i = 0; i < n; ++i) {
+		OPJ_INT32 y = c0[i];
+		OPJ_INT32 u = c1[i];
+		OPJ_INT32 v = c2[i];
+		OPJ_INT32 g = y - ((u + v) >> 2);
+		OPJ_INT32 r = v + g;
+		OPJ_INT32 b = u + g;
+		c0[i] = r;
+		c1[i] = g;
+		c2[i] = b;
+	}
+}
+
+/* <summary> */
+/* Get norm of basis function of reversible MCT. */
+/* </summary> */
+OPJ_FLOAT64 opj_mct_getnorm(OPJ_UINT32 compno) {
+	return opj_mct_norms[compno];
+}
+
+/* <summary> */
+/* Foward irreversible MCT. */
+/* </summary> */
+void opj_mct_encode_real(
+		OPJ_INT32* restrict c0,
+		OPJ_INT32* restrict c1,
+		OPJ_INT32* restrict c2,
+		OPJ_UINT32 n)
+{
+	OPJ_UINT32 i;
+	for(i = 0; i < n; ++i) {
+		OPJ_INT32 r = c0[i];
+		OPJ_INT32 g = c1[i];
+		OPJ_INT32 b = c2[i];
+		OPJ_INT32 y =  opj_int_fix_mul(r, 2449) + opj_int_fix_mul(g, 4809) + opj_int_fix_mul(b, 934);
+		OPJ_INT32 u = -opj_int_fix_mul(r, 1382) - opj_int_fix_mul(g, 2714) + opj_int_fix_mul(b, 4096);
+		OPJ_INT32 v =  opj_int_fix_mul(r, 4096) - opj_int_fix_mul(g, 3430) - opj_int_fix_mul(b, 666);
+		c0[i] = y;
+		c1[i] = u;
+		c2[i] = v;
+	}
+}
+
+/* <summary> */
+/* Inverse irreversible MCT. */
+/* </summary> */
+void opj_mct_decode_real(
+		OPJ_FLOAT32* restrict c0,
+		OPJ_FLOAT32* restrict c1,
+		OPJ_FLOAT32* restrict c2,
+		OPJ_UINT32 n)
+{
+	OPJ_UINT32 i;
+#ifdef __SSE__
+	__m128 vrv, vgu, vgv, vbu;
+	vrv = _mm_set1_ps(1.402f);
+	vgu = _mm_set1_ps(0.34413f);
+	vgv = _mm_set1_ps(0.71414f);
+	vbu = _mm_set1_ps(1.772f);
+	for (i = 0; i < (n >> 3); ++i) {
+		__m128 vy, vu, vv;
+		__m128 vr, vg, vb;
+
+		vy = _mm_load_ps(c0);
+		vu = _mm_load_ps(c1);
+		vv = _mm_load_ps(c2);
+		vr = _mm_add_ps(vy, _mm_mul_ps(vv, vrv));
+		vg = _mm_sub_ps(_mm_sub_ps(vy, _mm_mul_ps(vu, vgu)), _mm_mul_ps(vv, vgv));
+		vb = _mm_add_ps(vy, _mm_mul_ps(vu, vbu));
+		_mm_store_ps(c0, vr);
+		_mm_store_ps(c1, vg);
+		_mm_store_ps(c2, vb);
+		c0 += 4;
+		c1 += 4;
+		c2 += 4;
+
+		vy = _mm_load_ps(c0);
+		vu = _mm_load_ps(c1);
+		vv = _mm_load_ps(c2);
+		vr = _mm_add_ps(vy, _mm_mul_ps(vv, vrv));
+		vg = _mm_sub_ps(_mm_sub_ps(vy, _mm_mul_ps(vu, vgu)), _mm_mul_ps(vv, vgv));
+		vb = _mm_add_ps(vy, _mm_mul_ps(vu, vbu));
+		_mm_store_ps(c0, vr);
+		_mm_store_ps(c1, vg);
+		_mm_store_ps(c2, vb);
+		c0 += 4;
+		c1 += 4;
+		c2 += 4;
+	}
+	n &= 7;
+#endif
+	for(i = 0; i < n; ++i) {
+		OPJ_FLOAT32 y = c0[i];
+		OPJ_FLOAT32 u = c1[i];
+		OPJ_FLOAT32 v = c2[i];
+		OPJ_FLOAT32 r = y + (v * 1.402f);
+		OPJ_FLOAT32 g = y - (u * 0.34413f) - (v * (0.71414f));
+		OPJ_FLOAT32 b = y + (u * 1.772f);
+		c0[i] = r;
+		c1[i] = g;
+		c2[i] = b;
+	}
+}
+
+/* <summary> */
+/* Get norm of basis function of irreversible MCT. */
+/* </summary> */
+OPJ_FLOAT64 opj_mct_getnorm_real(OPJ_UINT32 compno) {
+	return opj_mct_norms_real[compno];
+}
+
+
+OPJ_BOOL opj_mct_encode_custom(
+					   OPJ_BYTE * pCodingdata,
+					   OPJ_UINT32 n,
+					   OPJ_BYTE ** pData,
+					   OPJ_UINT32 pNbComp,
+					   OPJ_UINT32 isSigned)
+{
+	OPJ_FLOAT32 * lMct = (OPJ_FLOAT32 *) pCodingdata;
+	OPJ_UINT32 i;
+	OPJ_UINT32 j;
+	OPJ_UINT32 k;
+	OPJ_UINT32 lNbMatCoeff = pNbComp * pNbComp;
+	OPJ_INT32 * lCurrentData = 00;
+	OPJ_INT32 * lCurrentMatrix = 00;
+	OPJ_INT32 ** lData = (OPJ_INT32 **) pData;
+	OPJ_UINT32 lMultiplicator = 1 << 13;
+	OPJ_INT32 * lMctPtr;
+
+    OPJ_ARG_NOT_USED(isSigned);
+
+	lCurrentData = (OPJ_INT32 *) opj_malloc((pNbComp + lNbMatCoeff) * sizeof(OPJ_INT32));
+	if (! lCurrentData) {
+		return OPJ_FALSE;
+	}
+
+	lCurrentMatrix = lCurrentData + pNbComp;
+
+	for (i =0;i<lNbMatCoeff;++i) {
+		lCurrentMatrix[i] = (OPJ_INT32) (*(lMct++) * (OPJ_FLOAT32)lMultiplicator);
+	}
+
+	for (i = 0; i < n; ++i)  {
+		lMctPtr = lCurrentMatrix;
+		for (j=0;j<pNbComp;++j) {
+			lCurrentData[j] = (*(lData[j]));
+		}
+
+		for (j=0;j<pNbComp;++j) {
+			*(lData[j]) = 0;
+			for (k=0;k<pNbComp;++k) {
+				*(lData[j]) += opj_int_fix_mul(*lMctPtr, lCurrentData[k]);
+				++lMctPtr;
+			}
+
+			++lData[j];
+		}
+	}
+
+	opj_free(lCurrentData);
+
+	return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_mct_decode_custom(
+					   OPJ_BYTE * pDecodingData,
+					   OPJ_UINT32 n,
+					   OPJ_BYTE ** pData,
+					   OPJ_UINT32 pNbComp,
+					   OPJ_UINT32 isSigned)
+{
+	OPJ_FLOAT32 * lMct;
+	OPJ_UINT32 i;
+	OPJ_UINT32 j;
+	OPJ_UINT32 k;
+
+	OPJ_FLOAT32 * lCurrentData = 00;
+	OPJ_FLOAT32 * lCurrentResult = 00;
+	OPJ_FLOAT32 ** lData = (OPJ_FLOAT32 **) pData;
+
+    OPJ_ARG_NOT_USED(isSigned);
+
+	lCurrentData = (OPJ_FLOAT32 *) opj_malloc (2 * pNbComp * sizeof(OPJ_FLOAT32));
+	if (! lCurrentData) {
+		return OPJ_FALSE;
+	}
+	lCurrentResult = lCurrentData + pNbComp;
+
+	for (i = 0; i < n; ++i) {
+		lMct = (OPJ_FLOAT32 *) pDecodingData;
+		for (j=0;j<pNbComp;++j) {
+			lCurrentData[j] = (OPJ_FLOAT32) (*(lData[j]));
+		}
+		for (j=0;j<pNbComp;++j) {
+			lCurrentResult[j] = 0;
+			for	(k=0;k<pNbComp;++k)	{
+				lCurrentResult[j] += *(lMct++) * lCurrentData[k];
+			}
+			*(lData[j]++) = (OPJ_FLOAT32) (lCurrentResult[j]);
+		}
+	}
+	opj_free(lCurrentData);
+	return OPJ_TRUE;
+}
+
+void opj_calculate_norms(	OPJ_FLOAT64 * pNorms,
+							OPJ_UINT32 pNbComps,
+							OPJ_FLOAT32 * pMatrix)
+{
+	OPJ_UINT32 i,j,lIndex;
+	OPJ_FLOAT32 lCurrentValue;
+	OPJ_FLOAT64 * lNorms = (OPJ_FLOAT64 *) pNorms;
+	OPJ_FLOAT32 * lMatrix = (OPJ_FLOAT32 *) pMatrix;
+
+	for	(i=0;i<pNbComps;++i) {
+		lNorms[i] = 0;
+		lIndex = i;
+
+		for	(j=0;j<pNbComps;++j) {
+			lCurrentValue = lMatrix[lIndex];
+			lIndex += pNbComps;
+			lNorms[i] += lCurrentValue * lCurrentValue;
+		}
+		lNorms[i] = sqrt(lNorms[i]);
+	}
+}
diff --git a/Source/LibOpenJPEG/mct.h b/Source/LibOpenJPEG/mct.h
index 361388e..1764e2b 100644
--- a/Source/LibOpenJPEG/mct.h
+++ b/Source/LibOpenJPEG/mct.h
@@ -1,98 +1,149 @@
-/*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
- * Copyright (c) 2001-2003, David Janssens
- * Copyright (c) 2002-2003, Yannick Verschueren
- * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __MCT_H
-#define __MCT_H
-/**
- at file mct.h
- at brief Implementation of a multi-component transforms (MCT)
-
-The functions in MCT.C have for goal to realize reversible and irreversible multicomponent
-transform. The functions in MCT.C are used by some function in TCD.C.
-*/
-
-/** @defgroup MCT MCT - Implementation of a multi-component transform */
-/*@{*/
-
-/** @name Exported functions */
-/*@{*/
-/* ----------------------------------------------------------------------- */
-/**
-Apply a reversible multi-component transform to an image
- at param c0 Samples for red component
- at param c1 Samples for green component
- at param c2 Samples blue component
- at param n Number of samples for each component
-*/
-void mct_encode(int *c0, int *c1, int *c2, int n);
-/**
-Apply a reversible multi-component inverse transform to an image
- at param c0 Samples for luminance component
- at param c1 Samples for red chrominance component
- at param c2 Samples for blue chrominance component
- at param n Number of samples for each component
-*/
-void mct_decode(int *c0, int *c1, int *c2, int n);
-/**
-Get norm of the basis function used for the reversible multi-component transform
- at param compno Number of the component (0->Y, 1->U, 2->V)
- at return 
-*/
-double mct_getnorm(int compno);
-
-/**
-Apply an irreversible multi-component transform to an image
- at param c0 Samples for red component
- at param c1 Samples for green component
- at param c2 Samples blue component
- at param n Number of samples for each component
-*/
-void mct_encode_real(int *c0, int *c1, int *c2, int n);
-/**
-Apply an irreversible multi-component inverse transform to an image
- at param c0 Samples for luminance component
- at param c1 Samples for red chrominance component
- at param c2 Samples for blue chrominance component
- at param n Number of samples for each component
-*/
-void mct_decode_real(float* c0, float* c1, float* c2, int n);
-/**
-Get norm of the basis function used for the irreversible multi-component transform
- at param compno Number of the component (0->Y, 1->U, 2->V)
- at return 
-*/
-double mct_getnorm_real(int compno);
-/* ----------------------------------------------------------------------- */
-/*@}*/
-
-/*@}*/
-
-#endif /* __MCT_H */
+/*
+ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2007, Professor Benoit Macq
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2008;2011-2012, Centre National d'Etudes Spatiales (CNES), France 
+ * Copyright (c) 2012, CS Systemes d'Information, France
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __MCT_H
+#define __MCT_H
+/**
+ at file mct.h
+ at brief Implementation of a multi-component transforms (MCT)
+
+The functions in MCT.C have for goal to realize reversible and irreversible multicomponent
+transform. The functions in MCT.C are used by some function in TCD.C.
+*/
+
+/** @defgroup MCT MCT - Implementation of a multi-component transform */
+/*@{*/
+
+/** @name Exported functions */
+/*@{*/
+/* ----------------------------------------------------------------------- */
+/**
+Apply a reversible multi-component transform to an image
+ at param c0 Samples for red component
+ at param c1 Samples for green component
+ at param c2 Samples blue component
+ at param n Number of samples for each component
+*/
+void opj_mct_encode(OPJ_INT32 *c0, OPJ_INT32 *c1, OPJ_INT32 *c2, OPJ_UINT32 n);
+/**
+Apply a reversible multi-component inverse transform to an image
+ at param c0 Samples for luminance component
+ at param c1 Samples for red chrominance component
+ at param c2 Samples for blue chrominance component
+ at param n Number of samples for each component
+*/
+void opj_mct_decode(OPJ_INT32 *c0, OPJ_INT32 *c1, OPJ_INT32 *c2, OPJ_UINT32 n);
+/**
+Get norm of the basis function used for the reversible multi-component transform
+ at param compno Number of the component (0->Y, 1->U, 2->V)
+ at return 
+*/
+OPJ_FLOAT64 opj_mct_getnorm(OPJ_UINT32 compno);
+
+/**
+Apply an irreversible multi-component transform to an image
+ at param c0 Samples for red component
+ at param c1 Samples for green component
+ at param c2 Samples blue component
+ at param n Number of samples for each component
+*/
+void opj_mct_encode_real(OPJ_INT32 *c0, OPJ_INT32 *c1, OPJ_INT32 *c2, OPJ_UINT32 n);
+/**
+Apply an irreversible multi-component inverse transform to an image
+ at param c0 Samples for luminance component
+ at param c1 Samples for red chrominance component
+ at param c2 Samples for blue chrominance component
+ at param n Number of samples for each component
+*/
+void opj_mct_decode_real(OPJ_FLOAT32* c0, OPJ_FLOAT32* c1, OPJ_FLOAT32* c2, OPJ_UINT32 n);
+/**
+Get norm of the basis function used for the irreversible multi-component transform
+ at param compno Number of the component (0->Y, 1->U, 2->V)
+ at return 
+*/
+OPJ_FLOAT64 opj_mct_getnorm_real(OPJ_UINT32 compno);
+
+/**
+FIXME DOC
+ at param p_coding_data    MCT data
+ at param n                size of components
+ at param p_data           components
+ at param p_nb_comp        nb of components (i.e. size of p_data)
+ at param is_signed        tells if the data is signed
+ at return OPJ_FALSE if function encounter a problem, OPJ_TRUE otherwise
+*/
+OPJ_BOOL opj_mct_encode_custom(
+					   OPJ_BYTE * p_coding_data,
+					   OPJ_UINT32 n,
+					   OPJ_BYTE ** p_data,
+					   OPJ_UINT32 p_nb_comp,
+					   OPJ_UINT32 is_signed);
+/**
+FIXME DOC
+ at param pDecodingData    MCT data
+ at param n                size of components
+ at param pData            components
+ at param pNbComp          nb of components (i.e. size of p_data)
+ at param isSigned         tells if the data is signed
+ at return OPJ_FALSE if function encounter a problem, OPJ_TRUE otherwise
+*/
+OPJ_BOOL opj_mct_decode_custom(
+					   OPJ_BYTE * pDecodingData,
+					   OPJ_UINT32 n,
+					   OPJ_BYTE ** pData,
+					   OPJ_UINT32 pNbComp,
+					   OPJ_UINT32 isSigned);
+/**
+FIXME DOC
+ at param pNorms           MCT data
+ at param p_nb_comps       size of components
+ at param pMatrix          components
+ at return 
+*/
+void opj_calculate_norms(   OPJ_FLOAT64 * pNorms,
+                            OPJ_UINT32 p_nb_comps,
+                            OPJ_FLOAT32 * pMatrix);
+/**
+FIXME DOC 
+*/
+const OPJ_FLOAT64 * opj_mct_get_mct_norms (void);
+/**
+FIXME DOC 
+*/
+const OPJ_FLOAT64 * opj_mct_get_mct_norms_real (void);
+/* ----------------------------------------------------------------------- */
+/*@}*/
+
+/*@}*/
+
+#endif /* __MCT_H */
diff --git a/Source/LibOpenJPEG/mqc.c b/Source/LibOpenJPEG/mqc.c
index e35b539..677884c 100644
--- a/Source/LibOpenJPEG/mqc.c
+++ b/Source/LibOpenJPEG/mqc.c
@@ -1,592 +1,604 @@
-/*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
- * Copyright (c) 2001-2003, David Janssens
- * Copyright (c) 2002-2003, Yannick Verschueren
- * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "opj_includes.h"
-
-/** @defgroup MQC MQC - Implementation of an MQ-Coder */
-/*@{*/
-
-/** @name Local static functions */
-/*@{*/
-
-/**
-Output a byte, doing bit-stuffing if necessary.
-After a 0xff byte, the next byte must be smaller than 0x90.
- at param mqc MQC handle
-*/
-static void mqc_byteout(opj_mqc_t *mqc);
-/**
-Renormalize mqc->a and mqc->c while encoding, so that mqc->a stays between 0x8000 and 0x10000
- at param mqc MQC handle
-*/
-static void mqc_renorme(opj_mqc_t *mqc);
-/**
-Encode the most probable symbol
- at param mqc MQC handle
-*/
-static void mqc_codemps(opj_mqc_t *mqc);
-/**
-Encode the most least symbol
- at param mqc MQC handle
-*/
-static void mqc_codelps(opj_mqc_t *mqc);
-/**
-Fill mqc->c with 1's for flushing
- at param mqc MQC handle
-*/
-static void mqc_setbits(opj_mqc_t *mqc);
-/**
-FIXME: documentation ???
- at param mqc MQC handle
- at return 
-*/
-static INLINE int mqc_mpsexchange(opj_mqc_t *const mqc);
-/**
-FIXME: documentation ???
- at param mqc MQC handle
- at return 
-*/
-static INLINE int mqc_lpsexchange(opj_mqc_t *const mqc);
-/**
-Input a byte
- at param mqc MQC handle
-*/
-static INLINE void mqc_bytein(opj_mqc_t *const mqc);
-/**
-Renormalize mqc->a and mqc->c while decoding
- at param mqc MQC handle
-*/
-static INLINE void mqc_renormd(opj_mqc_t *const mqc);
-/*@}*/
-
-/*@}*/
-
-/* <summary> */
-/* This array defines all the possible states for a context. */
-/* </summary> */
-static opj_mqc_state_t mqc_states[47 * 2] = {
-	{0x5601, 0, &mqc_states[2], &mqc_states[3]},
-	{0x5601, 1, &mqc_states[3], &mqc_states[2]},
-	{0x3401, 0, &mqc_states[4], &mqc_states[12]},
-	{0x3401, 1, &mqc_states[5], &mqc_states[13]},
-	{0x1801, 0, &mqc_states[6], &mqc_states[18]},
-	{0x1801, 1, &mqc_states[7], &mqc_states[19]},
-	{0x0ac1, 0, &mqc_states[8], &mqc_states[24]},
-	{0x0ac1, 1, &mqc_states[9], &mqc_states[25]},
-	{0x0521, 0, &mqc_states[10], &mqc_states[58]},
-	{0x0521, 1, &mqc_states[11], &mqc_states[59]},
-	{0x0221, 0, &mqc_states[76], &mqc_states[66]},
-	{0x0221, 1, &mqc_states[77], &mqc_states[67]},
-	{0x5601, 0, &mqc_states[14], &mqc_states[13]},
-	{0x5601, 1, &mqc_states[15], &mqc_states[12]},
-	{0x5401, 0, &mqc_states[16], &mqc_states[28]},
-	{0x5401, 1, &mqc_states[17], &mqc_states[29]},
-	{0x4801, 0, &mqc_states[18], &mqc_states[28]},
-	{0x4801, 1, &mqc_states[19], &mqc_states[29]},
-	{0x3801, 0, &mqc_states[20], &mqc_states[28]},
-	{0x3801, 1, &mqc_states[21], &mqc_states[29]},
-	{0x3001, 0, &mqc_states[22], &mqc_states[34]},
-	{0x3001, 1, &mqc_states[23], &mqc_states[35]},
-	{0x2401, 0, &mqc_states[24], &mqc_states[36]},
-	{0x2401, 1, &mqc_states[25], &mqc_states[37]},
-	{0x1c01, 0, &mqc_states[26], &mqc_states[40]},
-	{0x1c01, 1, &mqc_states[27], &mqc_states[41]},
-	{0x1601, 0, &mqc_states[58], &mqc_states[42]},
-	{0x1601, 1, &mqc_states[59], &mqc_states[43]},
-	{0x5601, 0, &mqc_states[30], &mqc_states[29]},
-	{0x5601, 1, &mqc_states[31], &mqc_states[28]},
-	{0x5401, 0, &mqc_states[32], &mqc_states[28]},
-	{0x5401, 1, &mqc_states[33], &mqc_states[29]},
-	{0x5101, 0, &mqc_states[34], &mqc_states[30]},
-	{0x5101, 1, &mqc_states[35], &mqc_states[31]},
-	{0x4801, 0, &mqc_states[36], &mqc_states[32]},
-	{0x4801, 1, &mqc_states[37], &mqc_states[33]},
-	{0x3801, 0, &mqc_states[38], &mqc_states[34]},
-	{0x3801, 1, &mqc_states[39], &mqc_states[35]},
-	{0x3401, 0, &mqc_states[40], &mqc_states[36]},
-	{0x3401, 1, &mqc_states[41], &mqc_states[37]},
-	{0x3001, 0, &mqc_states[42], &mqc_states[38]},
-	{0x3001, 1, &mqc_states[43], &mqc_states[39]},
-	{0x2801, 0, &mqc_states[44], &mqc_states[38]},
-	{0x2801, 1, &mqc_states[45], &mqc_states[39]},
-	{0x2401, 0, &mqc_states[46], &mqc_states[40]},
-	{0x2401, 1, &mqc_states[47], &mqc_states[41]},
-	{0x2201, 0, &mqc_states[48], &mqc_states[42]},
-	{0x2201, 1, &mqc_states[49], &mqc_states[43]},
-	{0x1c01, 0, &mqc_states[50], &mqc_states[44]},
-	{0x1c01, 1, &mqc_states[51], &mqc_states[45]},
-	{0x1801, 0, &mqc_states[52], &mqc_states[46]},
-	{0x1801, 1, &mqc_states[53], &mqc_states[47]},
-	{0x1601, 0, &mqc_states[54], &mqc_states[48]},
-	{0x1601, 1, &mqc_states[55], &mqc_states[49]},
-	{0x1401, 0, &mqc_states[56], &mqc_states[50]},
-	{0x1401, 1, &mqc_states[57], &mqc_states[51]},
-	{0x1201, 0, &mqc_states[58], &mqc_states[52]},
-	{0x1201, 1, &mqc_states[59], &mqc_states[53]},
-	{0x1101, 0, &mqc_states[60], &mqc_states[54]},
-	{0x1101, 1, &mqc_states[61], &mqc_states[55]},
-	{0x0ac1, 0, &mqc_states[62], &mqc_states[56]},
-	{0x0ac1, 1, &mqc_states[63], &mqc_states[57]},
-	{0x09c1, 0, &mqc_states[64], &mqc_states[58]},
-	{0x09c1, 1, &mqc_states[65], &mqc_states[59]},
-	{0x08a1, 0, &mqc_states[66], &mqc_states[60]},
-	{0x08a1, 1, &mqc_states[67], &mqc_states[61]},
-	{0x0521, 0, &mqc_states[68], &mqc_states[62]},
-	{0x0521, 1, &mqc_states[69], &mqc_states[63]},
-	{0x0441, 0, &mqc_states[70], &mqc_states[64]},
-	{0x0441, 1, &mqc_states[71], &mqc_states[65]},
-	{0x02a1, 0, &mqc_states[72], &mqc_states[66]},
-	{0x02a1, 1, &mqc_states[73], &mqc_states[67]},
-	{0x0221, 0, &mqc_states[74], &mqc_states[68]},
-	{0x0221, 1, &mqc_states[75], &mqc_states[69]},
-	{0x0141, 0, &mqc_states[76], &mqc_states[70]},
-	{0x0141, 1, &mqc_states[77], &mqc_states[71]},
-	{0x0111, 0, &mqc_states[78], &mqc_states[72]},
-	{0x0111, 1, &mqc_states[79], &mqc_states[73]},
-	{0x0085, 0, &mqc_states[80], &mqc_states[74]},
-	{0x0085, 1, &mqc_states[81], &mqc_states[75]},
-	{0x0049, 0, &mqc_states[82], &mqc_states[76]},
-	{0x0049, 1, &mqc_states[83], &mqc_states[77]},
-	{0x0025, 0, &mqc_states[84], &mqc_states[78]},
-	{0x0025, 1, &mqc_states[85], &mqc_states[79]},
-	{0x0015, 0, &mqc_states[86], &mqc_states[80]},
-	{0x0015, 1, &mqc_states[87], &mqc_states[81]},
-	{0x0009, 0, &mqc_states[88], &mqc_states[82]},
-	{0x0009, 1, &mqc_states[89], &mqc_states[83]},
-	{0x0005, 0, &mqc_states[90], &mqc_states[84]},
-	{0x0005, 1, &mqc_states[91], &mqc_states[85]},
-	{0x0001, 0, &mqc_states[90], &mqc_states[86]},
-	{0x0001, 1, &mqc_states[91], &mqc_states[87]},
-	{0x5601, 0, &mqc_states[92], &mqc_states[92]},
-	{0x5601, 1, &mqc_states[93], &mqc_states[93]},
-};
-
-/* 
-==========================================================
-   local functions
-==========================================================
-*/
-
-static void mqc_byteout(opj_mqc_t *mqc) {
-	if (*mqc->bp == 0xff) {
-		mqc->bp++;
-		*mqc->bp = mqc->c >> 20;
-		mqc->c &= 0xfffff;
-		mqc->ct = 7;
-	} else {
-		if ((mqc->c & 0x8000000) == 0) {	/* ((mqc->c&0x8000000)==0) CHANGE */
-			mqc->bp++;
-			*mqc->bp = mqc->c >> 19;
-			mqc->c &= 0x7ffff;
-			mqc->ct = 8;
-		} else {
-			(*mqc->bp)++;
-			if (*mqc->bp == 0xff) {
-				mqc->c &= 0x7ffffff;
-				mqc->bp++;
-				*mqc->bp = mqc->c >> 20;
-				mqc->c &= 0xfffff;
-				mqc->ct = 7;
-			} else {
-				mqc->bp++;
-				*mqc->bp = mqc->c >> 19;
-				mqc->c &= 0x7ffff;
-				mqc->ct = 8;
-			}
-		}
-	}
-}
-
-static void mqc_renorme(opj_mqc_t *mqc) {
-	do {
-		mqc->a <<= 1;
-		mqc->c <<= 1;
-		mqc->ct--;
-		if (mqc->ct == 0) {
-			mqc_byteout(mqc);
-		}
-	} while ((mqc->a & 0x8000) == 0);
-}
-
-static void mqc_codemps(opj_mqc_t *mqc) {
-	mqc->a -= (*mqc->curctx)->qeval;
-	if ((mqc->a & 0x8000) == 0) {
-		if (mqc->a < (*mqc->curctx)->qeval) {
-			mqc->a = (*mqc->curctx)->qeval;
-		} else {
-			mqc->c += (*mqc->curctx)->qeval;
-		}
-		*mqc->curctx = (*mqc->curctx)->nmps;
-		mqc_renorme(mqc);
-	} else {
-		mqc->c += (*mqc->curctx)->qeval;
-	}
-}
-
-static void mqc_codelps(opj_mqc_t *mqc) {
-	mqc->a -= (*mqc->curctx)->qeval;
-	if (mqc->a < (*mqc->curctx)->qeval) {
-		mqc->c += (*mqc->curctx)->qeval;
-	} else {
-		mqc->a = (*mqc->curctx)->qeval;
-	}
-	*mqc->curctx = (*mqc->curctx)->nlps;
-	mqc_renorme(mqc);
-}
-
-static void mqc_setbits(opj_mqc_t *mqc) {
-	unsigned int tempc = mqc->c + mqc->a;
-	mqc->c |= 0xffff;
-	if (mqc->c >= tempc) {
-		mqc->c -= 0x8000;
-	}
-}
-
-static INLINE int mqc_mpsexchange(opj_mqc_t *const mqc) {
-	int d;
-	if (mqc->a < (*mqc->curctx)->qeval) {
-		d = 1 - (*mqc->curctx)->mps;
-		*mqc->curctx = (*mqc->curctx)->nlps;
-	} else {
-		d = (*mqc->curctx)->mps;
-		*mqc->curctx = (*mqc->curctx)->nmps;
-	}
-	
-	return d;
-}
-
-static INLINE int mqc_lpsexchange(opj_mqc_t *const mqc) {
-	int d;
-	if (mqc->a < (*mqc->curctx)->qeval) {
-		mqc->a = (*mqc->curctx)->qeval;
-		d = (*mqc->curctx)->mps;
-		*mqc->curctx = (*mqc->curctx)->nmps;
-	} else {
-		mqc->a = (*mqc->curctx)->qeval;
-		d = 1 - (*mqc->curctx)->mps;
-		*mqc->curctx = (*mqc->curctx)->nlps;
-	}
-	
-	return d;
-}
-
-#ifdef MQC_PERF_OPT
-static INLINE void mqc_bytein(opj_mqc_t *const mqc) {
-	unsigned int i = *((unsigned int *) mqc->bp);
-	mqc->c += i & 0xffff00;
-	mqc->ct = i & 0x0f;
-	mqc->bp += (i >> 2) & 0x04;
-}
-#else
-static void mqc_bytein(opj_mqc_t *const mqc) {
-	if (mqc->bp != mqc->end) {
-		unsigned int c;
-		if (mqc->bp + 1 != mqc->end) {
-			c = *(mqc->bp + 1);
-		} else {
-			c = 0xff;
-		}
-		if (*mqc->bp == 0xff) {
-			if (c > 0x8f) {
-				mqc->c += 0xff00;
-				mqc->ct = 8;
-			} else {
-				mqc->bp++;
-				mqc->c += c << 9;
-				mqc->ct = 7;
-			}
-		} else {
-			mqc->bp++;
-			mqc->c += c << 8;
-			mqc->ct = 8;
-		}
-	} else {
-		mqc->c += 0xff00;
-		mqc->ct = 8;
-	}
-}
-#endif
-
-static INLINE void mqc_renormd(opj_mqc_t *const mqc) {
-	do {
-		if (mqc->ct == 0) {
-			mqc_bytein(mqc);
-		}
-		mqc->a <<= 1;
-		mqc->c <<= 1;
-		mqc->ct--;
-	} while (mqc->a < 0x8000);
-}
-
-/* 
-==========================================================
-   MQ-Coder interface
-==========================================================
-*/
-
-opj_mqc_t* mqc_create(void) {
-	opj_mqc_t *mqc = (opj_mqc_t*)opj_malloc(sizeof(opj_mqc_t));
-#ifdef MQC_PERF_OPT
-	mqc->buffer = NULL;
-#endif
-	return mqc;
-}
-
-void mqc_destroy(opj_mqc_t *mqc) {
-	if(mqc) {
-#ifdef MQC_PERF_OPT
-		if (mqc->buffer) {
-			opj_free(mqc->buffer);
-		}
-#endif
-		opj_free(mqc);
-	}
-}
-
-int mqc_numbytes(opj_mqc_t *mqc) {
-	return mqc->bp - mqc->start;
-}
-
-void mqc_init_enc(opj_mqc_t *mqc, unsigned char *bp) {
-	mqc_setcurctx(mqc, 0);
-	mqc->a = 0x8000;
-	mqc->c = 0;
-	mqc->bp = bp - 1;
-	mqc->ct = 12;
-	if (*mqc->bp == 0xff) {
-		mqc->ct = 13;
-	}
-	mqc->start = bp;
-}
-
-void mqc_encode(opj_mqc_t *mqc, int d) {
-	if ((*mqc->curctx)->mps == d) {
-		mqc_codemps(mqc);
-	} else {
-		mqc_codelps(mqc);
-	}
-}
-
-void mqc_flush(opj_mqc_t *mqc) {
-	mqc_setbits(mqc);
-	mqc->c <<= mqc->ct;
-	mqc_byteout(mqc);
-	mqc->c <<= mqc->ct;
-	mqc_byteout(mqc);
-	
-	if (*mqc->bp != 0xff) {
-		mqc->bp++;
-	}
-}
-
-void mqc_bypass_init_enc(opj_mqc_t *mqc) {
-	mqc->c = 0;
-	mqc->ct = 8;
-	/*if (*mqc->bp == 0xff) {
-	mqc->ct = 7;
-     } */
-}
-
-void mqc_bypass_enc(opj_mqc_t *mqc, int d) {
-	mqc->ct--;
-	mqc->c = mqc->c + (d << mqc->ct);
-	if (mqc->ct == 0) {
-		mqc->bp++;
-		*mqc->bp = mqc->c;
-		mqc->ct = 8;
-		if (*mqc->bp == 0xff) {
-			mqc->ct = 7;
-		}
-		mqc->c = 0;
-	}
-}
-
-int mqc_bypass_flush_enc(opj_mqc_t *mqc) {
-	unsigned char bit_padding;
-	
-	bit_padding = 0;
-	
-	if (mqc->ct != 0) {
-		while (mqc->ct > 0) {
-			mqc->ct--;
-			mqc->c += bit_padding << mqc->ct;
-			bit_padding = (bit_padding + 1) & 0x01;
-		}
-		mqc->bp++;
-		*mqc->bp = mqc->c;
-		mqc->ct = 8;
-		mqc->c = 0;
-	}
-	
-	return 1;
-}
-
-void mqc_reset_enc(opj_mqc_t *mqc) {
-	mqc_resetstates(mqc);
-	mqc_setstate(mqc, T1_CTXNO_UNI, 0, 46);
-	mqc_setstate(mqc, T1_CTXNO_AGG, 0, 3);
-	mqc_setstate(mqc, T1_CTXNO_ZC, 0, 4);
-}
-
-int mqc_restart_enc(opj_mqc_t *mqc) {
-	int correction = 1;
-	
-	/* <flush part> */
-	int n = 27 - 15 - mqc->ct;
-	mqc->c <<= mqc->ct;
-	while (n > 0) {
-		mqc_byteout(mqc);
-		n -= mqc->ct;
-		mqc->c <<= mqc->ct;
-	}
-	mqc_byteout(mqc);
-	
-	return correction;
-}
-
-void mqc_restart_init_enc(opj_mqc_t *mqc) {
-	/* <Re-init part> */
-	mqc_setcurctx(mqc, 0);
-	mqc->a = 0x8000;
-	mqc->c = 0;
-	mqc->ct = 12;
-	mqc->bp--;
-	if (*mqc->bp == 0xff) {
-		mqc->ct = 13;
-	}
-}
-
-void mqc_erterm_enc(opj_mqc_t *mqc) {
-	int k = 11 - mqc->ct + 1;
-	
-	while (k > 0) {
-		mqc->c <<= mqc->ct;
-		mqc->ct = 0;
-		mqc_byteout(mqc);
-		k -= mqc->ct;
-	}
-	
-	if (*mqc->bp != 0xff) {
-		mqc_byteout(mqc);
-	}
-}
-
-void mqc_segmark_enc(opj_mqc_t *mqc) {
-	int i;
-	mqc_setcurctx(mqc, 18);
-	
-	for (i = 1; i < 5; i++) {
-		mqc_encode(mqc, i % 2);
-	}
-}
-
-void mqc_init_dec(opj_mqc_t *mqc, unsigned char *bp, int len) {
-	mqc_setcurctx(mqc, 0);
-	mqc->start = bp;
-	mqc->end = bp + len;
-	mqc->bp = bp;
-	if (len==0) mqc->c = 0xff << 16;
-	else mqc->c = *mqc->bp << 16;
-
-#ifdef MQC_PERF_OPT
-	{
-		unsigned int c;
-		unsigned int *ip;
-		unsigned char *end = mqc->end - 1;
-		mqc->buffer = opj_realloc(mqc->buffer, (len + 1) * sizeof(unsigned int));
-		ip = (unsigned int *) mqc->buffer;
-
-		while (bp < end) {
-			c = *(bp + 1);
-			if (*bp == 0xff) {
-				if (c > 0x8f) {
-					break;
-				} else {
-					*ip = 0x00000017 | (c << 9);
-				}
-			} else {
-				*ip = 0x00000018 | (c << 8);
-			}
-			bp++;
-			ip++;
-		}
-
-		/* Handle last byte of data */
-		c = 0xff;
-		if (*bp == 0xff) {
-			*ip = 0x0000ff18;
-		} else {
-			bp++;
-			*ip = 0x00000018 | (c << 8);
-		}
-		ip++;
-
-		*ip = 0x0000ff08;
-		mqc->bp = mqc->buffer;
-	}
-#endif
-	mqc_bytein(mqc);
-	mqc->c <<= 7;
-	mqc->ct -= 7;
-	mqc->a = 0x8000;
-}
-
-int mqc_decode(opj_mqc_t *const mqc) {
-	int d;
-	mqc->a -= (*mqc->curctx)->qeval;
-	if ((mqc->c >> 16) < (*mqc->curctx)->qeval) {
-		d = mqc_lpsexchange(mqc);
-		mqc_renormd(mqc);
-	} else {
-		mqc->c -= (*mqc->curctx)->qeval << 16;
-		if ((mqc->a & 0x8000) == 0) {
-			d = mqc_mpsexchange(mqc);
-			mqc_renormd(mqc);
-		} else {
-			d = (*mqc->curctx)->mps;
-		}
-	}
-
-	return d;
-}
-
-void mqc_resetstates(opj_mqc_t *mqc) {
-	int i;
-	for (i = 0; i < MQC_NUMCTXS; i++) {
-		mqc->ctxs[i] = mqc_states;
-	}
-}
-
-void mqc_setstate(opj_mqc_t *mqc, int ctxno, int msb, int prob) {
-	mqc->ctxs[ctxno] = &mqc_states[msb + (prob << 1)];
-}
-
-
+/*
+ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2007, Professor Benoit Macq
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2008, Jerome Fimes, Communications & Systemes <jerome.fimes at c-s.fr>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "opj_includes.h"
+
+/** @defgroup MQC MQC - Implementation of an MQ-Coder */
+/*@{*/
+
+/** @name Local static functions */
+/*@{*/
+
+/**
+Output a byte, doing bit-stuffing if necessary.
+After a 0xff byte, the next byte must be smaller than 0x90.
+ at param mqc MQC handle
+*/
+static void opj_mqc_byteout(opj_mqc_t *mqc);
+/**
+Renormalize mqc->a and mqc->c while encoding, so that mqc->a stays between 0x8000 and 0x10000
+ at param mqc MQC handle
+*/
+static void opj_mqc_renorme(opj_mqc_t *mqc);
+/**
+Encode the most probable symbol
+ at param mqc MQC handle
+*/
+static void opj_mqc_codemps(opj_mqc_t *mqc);
+/**
+Encode the most least symbol
+ at param mqc MQC handle
+*/
+static void opj_mqc_codelps(opj_mqc_t *mqc);
+/**
+Fill mqc->c with 1's for flushing
+ at param mqc MQC handle
+*/
+static void opj_mqc_setbits(opj_mqc_t *mqc);
+/**
+FIXME DOC
+ at param mqc MQC handle
+ at return 
+*/
+static INLINE OPJ_INT32 opj_mqc_mpsexchange(opj_mqc_t *const mqc);
+/**
+FIXME DOC
+ at param mqc MQC handle
+ at return 
+*/
+static INLINE OPJ_INT32 opj_mqc_lpsexchange(opj_mqc_t *const mqc);
+/**
+Input a byte
+ at param mqc MQC handle
+*/
+static INLINE void opj_mqc_bytein(opj_mqc_t *const mqc);
+/**
+Renormalize mqc->a and mqc->c while decoding
+ at param mqc MQC handle
+*/
+static INLINE void opj_mqc_renormd(opj_mqc_t *const mqc);
+/*@}*/
+
+/*@}*/
+
+/* <summary> */
+/* This array defines all the possible states for a context. */
+/* </summary> */
+static opj_mqc_state_t mqc_states[47 * 2] = {
+	{0x5601, 0, &mqc_states[2], &mqc_states[3]},
+	{0x5601, 1, &mqc_states[3], &mqc_states[2]},
+	{0x3401, 0, &mqc_states[4], &mqc_states[12]},
+	{0x3401, 1, &mqc_states[5], &mqc_states[13]},
+	{0x1801, 0, &mqc_states[6], &mqc_states[18]},
+	{0x1801, 1, &mqc_states[7], &mqc_states[19]},
+	{0x0ac1, 0, &mqc_states[8], &mqc_states[24]},
+	{0x0ac1, 1, &mqc_states[9], &mqc_states[25]},
+	{0x0521, 0, &mqc_states[10], &mqc_states[58]},
+	{0x0521, 1, &mqc_states[11], &mqc_states[59]},
+	{0x0221, 0, &mqc_states[76], &mqc_states[66]},
+	{0x0221, 1, &mqc_states[77], &mqc_states[67]},
+	{0x5601, 0, &mqc_states[14], &mqc_states[13]},
+	{0x5601, 1, &mqc_states[15], &mqc_states[12]},
+	{0x5401, 0, &mqc_states[16], &mqc_states[28]},
+	{0x5401, 1, &mqc_states[17], &mqc_states[29]},
+	{0x4801, 0, &mqc_states[18], &mqc_states[28]},
+	{0x4801, 1, &mqc_states[19], &mqc_states[29]},
+	{0x3801, 0, &mqc_states[20], &mqc_states[28]},
+	{0x3801, 1, &mqc_states[21], &mqc_states[29]},
+	{0x3001, 0, &mqc_states[22], &mqc_states[34]},
+	{0x3001, 1, &mqc_states[23], &mqc_states[35]},
+	{0x2401, 0, &mqc_states[24], &mqc_states[36]},
+	{0x2401, 1, &mqc_states[25], &mqc_states[37]},
+	{0x1c01, 0, &mqc_states[26], &mqc_states[40]},
+	{0x1c01, 1, &mqc_states[27], &mqc_states[41]},
+	{0x1601, 0, &mqc_states[58], &mqc_states[42]},
+	{0x1601, 1, &mqc_states[59], &mqc_states[43]},
+	{0x5601, 0, &mqc_states[30], &mqc_states[29]},
+	{0x5601, 1, &mqc_states[31], &mqc_states[28]},
+	{0x5401, 0, &mqc_states[32], &mqc_states[28]},
+	{0x5401, 1, &mqc_states[33], &mqc_states[29]},
+	{0x5101, 0, &mqc_states[34], &mqc_states[30]},
+	{0x5101, 1, &mqc_states[35], &mqc_states[31]},
+	{0x4801, 0, &mqc_states[36], &mqc_states[32]},
+	{0x4801, 1, &mqc_states[37], &mqc_states[33]},
+	{0x3801, 0, &mqc_states[38], &mqc_states[34]},
+	{0x3801, 1, &mqc_states[39], &mqc_states[35]},
+	{0x3401, 0, &mqc_states[40], &mqc_states[36]},
+	{0x3401, 1, &mqc_states[41], &mqc_states[37]},
+	{0x3001, 0, &mqc_states[42], &mqc_states[38]},
+	{0x3001, 1, &mqc_states[43], &mqc_states[39]},
+	{0x2801, 0, &mqc_states[44], &mqc_states[38]},
+	{0x2801, 1, &mqc_states[45], &mqc_states[39]},
+	{0x2401, 0, &mqc_states[46], &mqc_states[40]},
+	{0x2401, 1, &mqc_states[47], &mqc_states[41]},
+	{0x2201, 0, &mqc_states[48], &mqc_states[42]},
+	{0x2201, 1, &mqc_states[49], &mqc_states[43]},
+	{0x1c01, 0, &mqc_states[50], &mqc_states[44]},
+	{0x1c01, 1, &mqc_states[51], &mqc_states[45]},
+	{0x1801, 0, &mqc_states[52], &mqc_states[46]},
+	{0x1801, 1, &mqc_states[53], &mqc_states[47]},
+	{0x1601, 0, &mqc_states[54], &mqc_states[48]},
+	{0x1601, 1, &mqc_states[55], &mqc_states[49]},
+	{0x1401, 0, &mqc_states[56], &mqc_states[50]},
+	{0x1401, 1, &mqc_states[57], &mqc_states[51]},
+	{0x1201, 0, &mqc_states[58], &mqc_states[52]},
+	{0x1201, 1, &mqc_states[59], &mqc_states[53]},
+	{0x1101, 0, &mqc_states[60], &mqc_states[54]},
+	{0x1101, 1, &mqc_states[61], &mqc_states[55]},
+	{0x0ac1, 0, &mqc_states[62], &mqc_states[56]},
+	{0x0ac1, 1, &mqc_states[63], &mqc_states[57]},
+	{0x09c1, 0, &mqc_states[64], &mqc_states[58]},
+	{0x09c1, 1, &mqc_states[65], &mqc_states[59]},
+	{0x08a1, 0, &mqc_states[66], &mqc_states[60]},
+	{0x08a1, 1, &mqc_states[67], &mqc_states[61]},
+	{0x0521, 0, &mqc_states[68], &mqc_states[62]},
+	{0x0521, 1, &mqc_states[69], &mqc_states[63]},
+	{0x0441, 0, &mqc_states[70], &mqc_states[64]},
+	{0x0441, 1, &mqc_states[71], &mqc_states[65]},
+	{0x02a1, 0, &mqc_states[72], &mqc_states[66]},
+	{0x02a1, 1, &mqc_states[73], &mqc_states[67]},
+	{0x0221, 0, &mqc_states[74], &mqc_states[68]},
+	{0x0221, 1, &mqc_states[75], &mqc_states[69]},
+	{0x0141, 0, &mqc_states[76], &mqc_states[70]},
+	{0x0141, 1, &mqc_states[77], &mqc_states[71]},
+	{0x0111, 0, &mqc_states[78], &mqc_states[72]},
+	{0x0111, 1, &mqc_states[79], &mqc_states[73]},
+	{0x0085, 0, &mqc_states[80], &mqc_states[74]},
+	{0x0085, 1, &mqc_states[81], &mqc_states[75]},
+	{0x0049, 0, &mqc_states[82], &mqc_states[76]},
+	{0x0049, 1, &mqc_states[83], &mqc_states[77]},
+	{0x0025, 0, &mqc_states[84], &mqc_states[78]},
+	{0x0025, 1, &mqc_states[85], &mqc_states[79]},
+	{0x0015, 0, &mqc_states[86], &mqc_states[80]},
+	{0x0015, 1, &mqc_states[87], &mqc_states[81]},
+	{0x0009, 0, &mqc_states[88], &mqc_states[82]},
+	{0x0009, 1, &mqc_states[89], &mqc_states[83]},
+	{0x0005, 0, &mqc_states[90], &mqc_states[84]},
+	{0x0005, 1, &mqc_states[91], &mqc_states[85]},
+	{0x0001, 0, &mqc_states[90], &mqc_states[86]},
+	{0x0001, 1, &mqc_states[91], &mqc_states[87]},
+	{0x5601, 0, &mqc_states[92], &mqc_states[92]},
+	{0x5601, 1, &mqc_states[93], &mqc_states[93]},
+};
+
+/* 
+==========================================================
+   local functions
+==========================================================
+*/
+
+void opj_mqc_byteout(opj_mqc_t *mqc) {
+	if (*mqc->bp == 0xff) {
+		mqc->bp++;
+		*mqc->bp = (OPJ_BYTE)(mqc->c >> 20);
+		mqc->c &= 0xfffff;
+		mqc->ct = 7;
+	} else {
+		if ((mqc->c & 0x8000000) == 0) {	/* ((mqc->c&0x8000000)==0) CHANGE */
+			mqc->bp++;
+			*mqc->bp = (OPJ_BYTE)(mqc->c >> 19);
+			mqc->c &= 0x7ffff;
+			mqc->ct = 8;
+		} else {
+			(*mqc->bp)++;
+			if (*mqc->bp == 0xff) {
+				mqc->c &= 0x7ffffff;
+				mqc->bp++;
+				*mqc->bp = (OPJ_BYTE)(mqc->c >> 20);
+				mqc->c &= 0xfffff;
+				mqc->ct = 7;
+			} else {
+				mqc->bp++;
+				*mqc->bp = (OPJ_BYTE)(mqc->c >> 19);
+				mqc->c &= 0x7ffff;
+				mqc->ct = 8;
+			}
+		}
+	}
+}
+
+void opj_mqc_renorme(opj_mqc_t *mqc) {
+	do {
+		mqc->a <<= 1;
+		mqc->c <<= 1;
+		mqc->ct--;
+		if (mqc->ct == 0) {
+			opj_mqc_byteout(mqc);
+		}
+	} while ((mqc->a & 0x8000) == 0);
+}
+
+void opj_mqc_codemps(opj_mqc_t *mqc) {
+	mqc->a -= (*mqc->curctx)->qeval;
+	if ((mqc->a & 0x8000) == 0) {
+		if (mqc->a < (*mqc->curctx)->qeval) {
+			mqc->a = (*mqc->curctx)->qeval;
+		} else {
+			mqc->c += (*mqc->curctx)->qeval;
+		}
+		*mqc->curctx = (*mqc->curctx)->nmps;
+		opj_mqc_renorme(mqc);
+	} else {
+		mqc->c += (*mqc->curctx)->qeval;
+	}
+}
+
+void opj_mqc_codelps(opj_mqc_t *mqc) {
+	mqc->a -= (*mqc->curctx)->qeval;
+	if (mqc->a < (*mqc->curctx)->qeval) {
+		mqc->c += (*mqc->curctx)->qeval;
+	} else {
+		mqc->a = (*mqc->curctx)->qeval;
+	}
+	*mqc->curctx = (*mqc->curctx)->nlps;
+	opj_mqc_renorme(mqc);
+}
+
+void opj_mqc_setbits(opj_mqc_t *mqc) {
+	OPJ_UINT32 tempc = mqc->c + mqc->a;
+	mqc->c |= 0xffff;
+	if (mqc->c >= tempc) {
+		mqc->c -= 0x8000;
+	}
+}
+
+static INLINE OPJ_INT32 opj_mqc_mpsexchange(opj_mqc_t *const mqc) {
+	OPJ_INT32 d;
+	if (mqc->a < (*mqc->curctx)->qeval) {
+		d = (OPJ_INT32)(1 - (*mqc->curctx)->mps);
+		*mqc->curctx = (*mqc->curctx)->nlps;
+	} else {
+		d = (OPJ_INT32)(*mqc->curctx)->mps;
+		*mqc->curctx = (*mqc->curctx)->nmps;
+	}
+	
+	return d;
+}
+
+static INLINE OPJ_INT32 opj_mqc_lpsexchange(opj_mqc_t *const mqc) {
+	OPJ_INT32 d;
+	if (mqc->a < (*mqc->curctx)->qeval) {
+		mqc->a = (*mqc->curctx)->qeval;
+		d = (OPJ_INT32)(*mqc->curctx)->mps;
+		*mqc->curctx = (*mqc->curctx)->nmps;
+	} else {
+		mqc->a = (*mqc->curctx)->qeval;
+		d = (OPJ_INT32)(1 - (*mqc->curctx)->mps);
+		*mqc->curctx = (*mqc->curctx)->nlps;
+	}
+	
+	return d;
+}
+
+#ifdef MQC_PERF_OPT
+static INLINE void opj_mqc_bytein(opj_mqc_t *const mqc) {
+	unsigned int i = *((unsigned int *) mqc->bp);
+	mqc->c += i & 0xffff00;
+	mqc->ct = i & 0x0f;
+	mqc->bp += (i >> 2) & 0x04;
+}
+#else
+static void opj_mqc_bytein(opj_mqc_t *const mqc) {
+	if (mqc->bp != mqc->end) {
+		OPJ_UINT32 c;
+		if (mqc->bp + 1 != mqc->end) {
+			c = *(mqc->bp + 1);
+		} else {
+			c = 0xff;
+		}
+		if (*mqc->bp == 0xff) {
+			if (c > 0x8f) {
+				mqc->c += 0xff00;
+				mqc->ct = 8;
+			} else {
+				mqc->bp++;
+				mqc->c += c << 9;
+				mqc->ct = 7;
+			}
+		} else {
+			mqc->bp++;
+			mqc->c += c << 8;
+			mqc->ct = 8;
+		}
+	} else {
+		mqc->c += 0xff00;
+		mqc->ct = 8;
+	}
+}
+#endif
+
+static INLINE void opj_mqc_renormd(opj_mqc_t *const mqc) {
+	do {
+		if (mqc->ct == 0) {
+			opj_mqc_bytein(mqc);
+		}
+		mqc->a <<= 1;
+		mqc->c <<= 1;
+		mqc->ct--;
+	} while (mqc->a < 0x8000);
+}
+
+/* 
+==========================================================
+   MQ-Coder interface
+==========================================================
+*/
+
+opj_mqc_t* opj_mqc_create(void) {
+	opj_mqc_t *mqc = (opj_mqc_t*)opj_malloc(sizeof(opj_mqc_t));
+#ifdef MQC_PERF_OPT
+	mqc->buffer = NULL;
+#endif
+	return mqc;
+}
+
+void opj_mqc_destroy(opj_mqc_t *mqc) {
+	if(mqc) {
+#ifdef MQC_PERF_OPT
+		opj_free(mqc->buffer);
+#endif
+		opj_free(mqc);
+	}
+}
+
+OPJ_UINT32 opj_mqc_numbytes(opj_mqc_t *mqc) {
+	const ptrdiff_t diff = mqc->bp - mqc->start;
+#if 0
+  assert( diff <= 0xffffffff && diff >= 0 ); /* UINT32_MAX */
+#endif
+	return (OPJ_UINT32)diff;
+}
+
+void opj_mqc_init_enc(opj_mqc_t *mqc, OPJ_BYTE *bp) {
+    /* TODO MSD: need to take a look to the v2 version */
+	opj_mqc_setcurctx(mqc, 0);
+	mqc->a = 0x8000;
+	mqc->c = 0;
+	mqc->bp = bp - 1;
+	mqc->ct = 12;
+	if (*mqc->bp == 0xff) {
+		mqc->ct = 13;
+	}
+	mqc->start = bp;
+}
+
+void opj_mqc_encode(opj_mqc_t *mqc, OPJ_UINT32 d) {
+	if ((*mqc->curctx)->mps == d) {
+		opj_mqc_codemps(mqc);
+	} else {
+		opj_mqc_codelps(mqc);
+	}
+}
+
+void opj_mqc_flush(opj_mqc_t *mqc) {
+	opj_mqc_setbits(mqc);
+	mqc->c <<= mqc->ct;
+	opj_mqc_byteout(mqc);
+	mqc->c <<= mqc->ct;
+	opj_mqc_byteout(mqc);
+	
+	if (*mqc->bp != 0xff) {
+		mqc->bp++;
+	}
+}
+
+void opj_mqc_bypass_init_enc(opj_mqc_t *mqc) {
+	mqc->c = 0;
+	mqc->ct = 8;
+	/*if (*mqc->bp == 0xff) {
+	mqc->ct = 7;
+     } */
+}
+
+void opj_mqc_bypass_enc(opj_mqc_t *mqc, OPJ_UINT32 d) {
+	mqc->ct--;
+	mqc->c = mqc->c + (d << mqc->ct);
+	if (mqc->ct == 0) {
+		mqc->bp++;
+		*mqc->bp = (OPJ_BYTE)mqc->c;
+		mqc->ct = 8;
+		if (*mqc->bp == 0xff) {
+			mqc->ct = 7;
+		}
+		mqc->c = 0;
+	}
+}
+
+OPJ_UINT32 opj_mqc_bypass_flush_enc(opj_mqc_t *mqc) {
+	OPJ_BYTE bit_padding;
+	
+	bit_padding = 0;
+	
+	if (mqc->ct != 0) {
+		while (mqc->ct > 0) {
+			mqc->ct--;
+			mqc->c += (OPJ_UINT32)(bit_padding << mqc->ct);
+			bit_padding = (bit_padding + 1) & 0x01;
+		}
+		mqc->bp++;
+		*mqc->bp = (OPJ_BYTE)mqc->c;
+		mqc->ct = 8;
+		mqc->c = 0;
+	}
+	
+	return 1;
+}
+
+void opj_mqc_reset_enc(opj_mqc_t *mqc) {
+	opj_mqc_resetstates(mqc);
+	opj_mqc_setstate(mqc, T1_CTXNO_UNI, 0, 46);
+	opj_mqc_setstate(mqc, T1_CTXNO_AGG, 0, 3);
+	opj_mqc_setstate(mqc, T1_CTXNO_ZC, 0, 4);
+}
+
+OPJ_UINT32 opj_mqc_restart_enc(opj_mqc_t *mqc) {
+	OPJ_UINT32 correction = 1;
+	
+	/* <flush part> */
+	OPJ_INT32 n = (OPJ_INT32)(27 - 15 - mqc->ct);
+	mqc->c <<= mqc->ct;
+	while (n > 0) {
+		opj_mqc_byteout(mqc);
+		n -= (OPJ_INT32)mqc->ct;
+		mqc->c <<= mqc->ct;
+	}
+	opj_mqc_byteout(mqc);
+	
+	return correction;
+}
+
+void opj_mqc_restart_init_enc(opj_mqc_t *mqc) {
+	/* <Re-init part> */
+	opj_mqc_setcurctx(mqc, 0);
+	mqc->a = 0x8000;
+	mqc->c = 0;
+	mqc->ct = 12;
+	mqc->bp--;
+	if (*mqc->bp == 0xff) {
+		mqc->ct = 13;
+	}
+}
+
+void opj_mqc_erterm_enc(opj_mqc_t *mqc) {
+	OPJ_INT32 k = (OPJ_INT32)(11 - mqc->ct + 1);
+	
+	while (k > 0) {
+		mqc->c <<= mqc->ct;
+		mqc->ct = 0;
+		opj_mqc_byteout(mqc);
+		k -= (OPJ_INT32)mqc->ct;
+	}
+	
+	if (*mqc->bp != 0xff) {
+		opj_mqc_byteout(mqc);
+	}
+}
+
+void opj_mqc_segmark_enc(opj_mqc_t *mqc) {
+	OPJ_UINT32 i;
+	opj_mqc_setcurctx(mqc, 18);
+	
+	for (i = 1; i < 5; i++) {
+		opj_mqc_encode(mqc, i % 2);
+	}
+}
+
+OPJ_BOOL opj_mqc_init_dec(opj_mqc_t *mqc, OPJ_BYTE *bp, OPJ_UINT32 len) {
+	opj_mqc_setcurctx(mqc, 0);
+	mqc->start = bp;
+	mqc->end = bp + len;
+	mqc->bp = bp;
+	if (len==0) mqc->c = 0xff << 16;
+	else mqc->c = (OPJ_UINT32)(*mqc->bp << 16);
+
+#ifdef MQC_PERF_OPT /* TODO_MSD: check this option and put in experimental */
+	{
+        OPJ_UINT32 c;
+		OPJ_UINT32 *ip;
+		OPJ_BYTE *end = mqc->end - 1;
+        void* new_buffer = opj_realloc(mqc->buffer, (len + 1) * sizeof(OPJ_UINT32));
+        if (! new_buffer) {
+            opj_free(mqc->buffer);
+            mqc->buffer = NULL;
+            return OPJ_FALSE;
+        }
+        mqc->buffer = new_buffer;
+		
+        ip = (OPJ_UINT32 *) mqc->buffer;
+
+		while (bp < end) {
+			c = *(bp + 1);
+			if (*bp == 0xff) {
+				if (c > 0x8f) {
+					break;
+				} else {
+					*ip = 0x00000017 | (c << 9);
+				}
+			} else {
+				*ip = 0x00000018 | (c << 8);
+			}
+			bp++;
+			ip++;
+		}
+
+		/* Handle last byte of data */
+		c = 0xff;
+		if (*bp == 0xff) {
+			*ip = 0x0000ff18;
+		} else {
+			bp++;
+			*ip = 0x00000018 | (c << 8);
+		}
+		ip++;
+
+		*ip = 0x0000ff08;
+		mqc->bp = mqc->buffer;
+	}
+#endif
+	opj_mqc_bytein(mqc);
+	mqc->c <<= 7;
+	mqc->ct -= 7;
+	mqc->a = 0x8000;
+        return OPJ_TRUE;
+}
+
+OPJ_INT32 opj_mqc_decode(opj_mqc_t *const mqc) {
+	OPJ_INT32 d;
+	mqc->a -= (*mqc->curctx)->qeval;
+	if ((mqc->c >> 16) < (*mqc->curctx)->qeval) {
+		d = opj_mqc_lpsexchange(mqc);
+		opj_mqc_renormd(mqc);
+	} else {
+		mqc->c -= (*mqc->curctx)->qeval << 16;
+		if ((mqc->a & 0x8000) == 0) {
+			d = opj_mqc_mpsexchange(mqc);
+			opj_mqc_renormd(mqc);
+		} else {
+			d = (OPJ_INT32)(*mqc->curctx)->mps;
+		}
+	}
+
+	return d;
+}
+
+void opj_mqc_resetstates(opj_mqc_t *mqc) {
+	OPJ_UINT32 i;
+	for (i = 0; i < MQC_NUMCTXS; i++) {
+		mqc->ctxs[i] = mqc_states;
+	}
+}
+
+void opj_mqc_setstate(opj_mqc_t *mqc, OPJ_UINT32 ctxno, OPJ_UINT32 msb, OPJ_INT32 prob) {
+	mqc->ctxs[ctxno] = &mqc_states[msb + (OPJ_UINT32)(prob << 1)];
+}
+
+
diff --git a/Source/LibOpenJPEG/mqc.h b/Source/LibOpenJPEG/mqc.h
index 976460e..b75ef39 100644
--- a/Source/LibOpenJPEG/mqc.h
+++ b/Source/LibOpenJPEG/mqc.h
@@ -1,200 +1,201 @@
-/*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
- * Copyright (c) 2001-2003, David Janssens
- * Copyright (c) 2002-2003, Yannick Verschueren
- * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __MQC_H
-#define __MQC_H
-/**
- at file mqc.h
- at brief Implementation of an MQ-Coder (MQC)
-
-The functions in MQC.C have for goal to realize the MQ-coder operations. The functions
-in MQC.C are used by some function in T1.C.
-*/
-
-/** @defgroup MQC MQC - Implementation of an MQ-Coder */
-/*@{*/
-
-/**
-This struct defines the state of a context.
-*/
-typedef struct opj_mqc_state {
-	/** the probability of the Least Probable Symbol (0.75->0x8000, 1.5->0xffff) */
-	unsigned int qeval;
-	/** the Most Probable Symbol (0 or 1) */
-	int mps;
-	/** next state if the next encoded symbol is the MPS */
-	struct opj_mqc_state *nmps;
-	/** next state if the next encoded symbol is the LPS */
-	struct opj_mqc_state *nlps;
-} opj_mqc_state_t;
-
-#define MQC_NUMCTXS 19
-
-/**
-MQ coder
-*/
-typedef struct opj_mqc {
-	unsigned int c;
-	unsigned int a;
-	unsigned int ct;
-	unsigned char *bp;
-	unsigned char *start;
-	unsigned char *end;
-	opj_mqc_state_t *ctxs[MQC_NUMCTXS];
-	opj_mqc_state_t **curctx;
-#ifdef MQC_PERF_OPT
-	unsigned char *buffer;
-#endif
-} opj_mqc_t;
-
-/** @name Exported functions */
-/*@{*/
-/* ----------------------------------------------------------------------- */
-/**
-Create a new MQC handle 
- at return Returns a new MQC handle if successful, returns NULL otherwise
-*/
-opj_mqc_t* mqc_create(void);
-/**
-Destroy a previously created MQC handle
- at param mqc MQC handle to destroy
-*/
-void mqc_destroy(opj_mqc_t *mqc);
-/**
-Return the number of bytes written/read since initialisation
- at param mqc MQC handle
- at return Returns the number of bytes already encoded
-*/
-int mqc_numbytes(opj_mqc_t *mqc);
-/**
-Reset the states of all the context of the coder/decoder 
-(each context is set to a state where 0 and 1 are more or less equiprobable)
- at param mqc MQC handle
-*/
-void mqc_resetstates(opj_mqc_t *mqc);
-/**
-Set the state of a particular context
- at param mqc MQC handle
- at param ctxno Number that identifies the context
- at param msb The MSB of the new state of the context
- at param prob Number that identifies the probability of the symbols for the new state of the context
-*/
-void mqc_setstate(opj_mqc_t *mqc, int ctxno, int msb, int prob);
-/**
-Initialize the encoder
- at param mqc MQC handle
- at param bp Pointer to the start of the buffer where the bytes will be written
-*/
-void mqc_init_enc(opj_mqc_t *mqc, unsigned char *bp);
-/**
-Set the current context used for coding/decoding
- at param mqc MQC handle
- at param ctxno Number that identifies the context
-*/
-#define mqc_setcurctx(mqc, ctxno)	(mqc)->curctx = &(mqc)->ctxs[(int)(ctxno)]
-/**
-Encode a symbol using the MQ-coder
- at param mqc MQC handle
- at param d The symbol to be encoded (0 or 1)
-*/
-void mqc_encode(opj_mqc_t *mqc, int d);
-/**
-Flush the encoder, so that all remaining data is written
- at param mqc MQC handle
-*/
-void mqc_flush(opj_mqc_t *mqc);
-/**
-BYPASS mode switch, initialization operation. 
-JPEG 2000 p 505. 
-<h2>Not fully implemented and tested !!</h2>
- at param mqc MQC handle
-*/
-void mqc_bypass_init_enc(opj_mqc_t *mqc);
-/**
-BYPASS mode switch, coding operation. 
-JPEG 2000 p 505. 
-<h2>Not fully implemented and tested !!</h2>
- at param mqc MQC handle
- at param d The symbol to be encoded (0 or 1)
-*/
-void mqc_bypass_enc(opj_mqc_t *mqc, int d);
-/**
-BYPASS mode switch, flush operation
-<h2>Not fully implemented and tested !!</h2>
- at param mqc MQC handle
- at return Returns 1 (always)
-*/
-int mqc_bypass_flush_enc(opj_mqc_t *mqc);
-/**
-RESET mode switch
- at param mqc MQC handle
-*/
-void mqc_reset_enc(opj_mqc_t *mqc);
-/**
-RESTART mode switch (TERMALL)
- at param mqc MQC handle
- at return Returns 1 (always)
-*/
-int mqc_restart_enc(opj_mqc_t *mqc);
-/**
-RESTART mode switch (TERMALL) reinitialisation
- at param mqc MQC handle
-*/
-void mqc_restart_init_enc(opj_mqc_t *mqc);
-/**
-ERTERM mode switch (PTERM)
- at param mqc MQC handle
-*/
-void mqc_erterm_enc(opj_mqc_t *mqc);
-/**
-SEGMARK mode switch (SEGSYM)
- at param mqc MQC handle
-*/
-void mqc_segmark_enc(opj_mqc_t *mqc);
-/**
-Initialize the decoder
- at param mqc MQC handle
- at param bp Pointer to the start of the buffer from which the bytes will be read
- at param len Length of the input buffer
-*/
-void mqc_init_dec(opj_mqc_t *mqc, unsigned char *bp, int len);
-/**
-Decode a symbol
- at param mqc MQC handle
- at return Returns the decoded symbol (0 or 1)
-*/
-int mqc_decode(opj_mqc_t *const mqc);
-/* ----------------------------------------------------------------------- */
-/*@}*/
-
-/*@}*/
-
-#endif /* __MQC_H */
+/*
+ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2007, Professor Benoit Macq
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2008, Jerome Fimes, Communications & Systemes <jerome.fimes at c-s.fr>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __MQC_H
+#define __MQC_H
+/**
+ at file mqc.h
+ at brief Implementation of an MQ-Coder (MQC)
+
+The functions in MQC.C have for goal to realize the MQ-coder operations. The functions
+in MQC.C are used by some function in T1.C.
+*/
+
+/** @defgroup MQC MQC - Implementation of an MQ-Coder */
+/*@{*/
+
+/**
+This struct defines the state of a context.
+*/
+typedef struct opj_mqc_state {
+	/** the probability of the Least Probable Symbol (0.75->0x8000, 1.5->0xffff) */
+	OPJ_UINT32 qeval;
+	/** the Most Probable Symbol (0 or 1) */
+	OPJ_UINT32 mps;
+	/** next state if the next encoded symbol is the MPS */
+	struct opj_mqc_state *nmps;
+	/** next state if the next encoded symbol is the LPS */
+	struct opj_mqc_state *nlps;
+} opj_mqc_state_t;
+
+#define MQC_NUMCTXS 19
+
+/**
+MQ coder
+*/
+typedef struct opj_mqc {
+	OPJ_UINT32 c;
+	OPJ_UINT32 a;
+	OPJ_UINT32 ct;
+	OPJ_BYTE *bp;
+	OPJ_BYTE *start;
+	OPJ_BYTE *end;
+	opj_mqc_state_t *ctxs[MQC_NUMCTXS];
+	opj_mqc_state_t **curctx;
+#ifdef MQC_PERF_OPT
+	unsigned char *buffer;
+#endif
+} opj_mqc_t;
+
+/** @name Exported functions */
+/*@{*/
+/* ----------------------------------------------------------------------- */
+/**
+Create a new MQC handle 
+ at return Returns a new MQC handle if successful, returns NULL otherwise
+*/
+opj_mqc_t* opj_mqc_create(void);
+/**
+Destroy a previously created MQC handle
+ at param mqc MQC handle to destroy
+*/
+void opj_mqc_destroy(opj_mqc_t *mqc);
+/**
+Return the number of bytes written/read since initialisation
+ at param mqc MQC handle
+ at return Returns the number of bytes already encoded
+*/
+OPJ_UINT32 opj_mqc_numbytes(opj_mqc_t *mqc);
+/**
+Reset the states of all the context of the coder/decoder 
+(each context is set to a state where 0 and 1 are more or less equiprobable)
+ at param mqc MQC handle
+*/
+void opj_mqc_resetstates(opj_mqc_t *mqc);
+/**
+Set the state of a particular context
+ at param mqc MQC handle
+ at param ctxno Number that identifies the context
+ at param msb The MSB of the new state of the context
+ at param prob Number that identifies the probability of the symbols for the new state of the context
+*/
+void opj_mqc_setstate(opj_mqc_t *mqc, OPJ_UINT32 ctxno, OPJ_UINT32 msb, OPJ_INT32 prob);
+/**
+Initialize the encoder
+ at param mqc MQC handle
+ at param bp Pointer to the start of the buffer where the bytes will be written
+*/
+void opj_mqc_init_enc(opj_mqc_t *mqc, OPJ_BYTE *bp);
+/**
+Set the current context used for coding/decoding
+ at param mqc MQC handle
+ at param ctxno Number that identifies the context
+*/
+#define opj_mqc_setcurctx(mqc, ctxno)	(mqc)->curctx = &(mqc)->ctxs[(OPJ_UINT32)(ctxno)]
+/**
+Encode a symbol using the MQ-coder
+ at param mqc MQC handle
+ at param d The symbol to be encoded (0 or 1)
+*/
+void opj_mqc_encode(opj_mqc_t *mqc, OPJ_UINT32 d);
+/**
+Flush the encoder, so that all remaining data is written
+ at param mqc MQC handle
+*/
+void opj_mqc_flush(opj_mqc_t *mqc);
+/**
+BYPASS mode switch, initialization operation. 
+JPEG 2000 p 505. 
+<h2>Not fully implemented and tested !!</h2>
+ at param mqc MQC handle
+*/
+void opj_mqc_bypass_init_enc(opj_mqc_t *mqc);
+/**
+BYPASS mode switch, coding operation. 
+JPEG 2000 p 505. 
+<h2>Not fully implemented and tested !!</h2>
+ at param mqc MQC handle
+ at param d The symbol to be encoded (0 or 1)
+*/
+void opj_mqc_bypass_enc(opj_mqc_t *mqc, OPJ_UINT32 d);
+/**
+BYPASS mode switch, flush operation
+<h2>Not fully implemented and tested !!</h2>
+ at param mqc MQC handle
+ at return Returns 1 (always)
+*/
+OPJ_UINT32 opj_mqc_bypass_flush_enc(opj_mqc_t *mqc);
+/**
+RESET mode switch
+ at param mqc MQC handle
+*/
+void opj_mqc_reset_enc(opj_mqc_t *mqc);
+/**
+RESTART mode switch (TERMALL)
+ at param mqc MQC handle
+ at return Returns 1 (always)
+*/
+OPJ_UINT32 opj_mqc_restart_enc(opj_mqc_t *mqc);
+/**
+RESTART mode switch (TERMALL) reinitialisation
+ at param mqc MQC handle
+*/
+void opj_mqc_restart_init_enc(opj_mqc_t *mqc);
+/**
+ERTERM mode switch (PTERM)
+ at param mqc MQC handle
+*/
+void opj_mqc_erterm_enc(opj_mqc_t *mqc);
+/**
+SEGMARK mode switch (SEGSYM)
+ at param mqc MQC handle
+*/
+void opj_mqc_segmark_enc(opj_mqc_t *mqc);
+/**
+Initialize the decoder
+ at param mqc MQC handle
+ at param bp Pointer to the start of the buffer from which the bytes will be read
+ at param len Length of the input buffer
+*/
+OPJ_BOOL opj_mqc_init_dec(opj_mqc_t *mqc, OPJ_BYTE *bp, OPJ_UINT32 len);
+/**
+Decode a symbol
+ at param mqc MQC handle
+ at return Returns the decoded symbol (0 or 1)
+*/
+OPJ_INT32 opj_mqc_decode(opj_mqc_t * const mqc);
+/* ----------------------------------------------------------------------- */
+/*@}*/
+
+/*@}*/
+
+#endif /* __MQC_H */
diff --git a/Source/LibOpenJPEG/openjpeg.c b/Source/LibOpenJPEG/openjpeg.c
index 847b08d..0522acb 100644
--- a/Source/LibOpenJPEG/openjpeg.c
+++ b/Source/LibOpenJPEG/openjpeg.c
@@ -1,343 +1,955 @@
-/*
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifdef _WIN32
-#include <windows.h>
-#endif /* _WIN32 */
-
-#include "opj_config.h"
-#include "opj_includes.h"
-
-/* ---------------------------------------------------------------------- */
-#ifdef _WIN32
-#ifndef OPJ_STATIC
-BOOL APIENTRY
-DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
-
-	OPJ_ARG_NOT_USED(lpReserved);
-	OPJ_ARG_NOT_USED(hModule);
-
-	switch (ul_reason_for_call) {
-		case DLL_PROCESS_ATTACH :
-			break;
-		case DLL_PROCESS_DETACH :
-			break;
-		case DLL_THREAD_ATTACH :
-		case DLL_THREAD_DETACH :
-			break;
-    }
-
-    return TRUE;
-}
-#endif /* OPJ_STATIC */
-#endif /* _WIN32 */
-
-/* ---------------------------------------------------------------------- */
-
-
-const char* OPJ_CALLCONV opj_version(void) {
-    return PACKAGE_VERSION;
-}
-
-opj_dinfo_t* OPJ_CALLCONV opj_create_decompress(OPJ_CODEC_FORMAT format) {
-	opj_dinfo_t *dinfo = (opj_dinfo_t*)opj_calloc(1, sizeof(opj_dinfo_t));
-	if(!dinfo) return NULL;
-	dinfo->is_decompressor = OPJ_TRUE;
-	switch(format) {
-		case CODEC_J2K:
-		case CODEC_JPT:
-			/* get a J2K decoder handle */
-			dinfo->j2k_handle = (void*)j2k_create_decompress((opj_common_ptr)dinfo);
-			if(!dinfo->j2k_handle) {
-				opj_free(dinfo);
-				return NULL;
-			}
-			break;
-		case CODEC_JP2:
-			/* get a JP2 decoder handle */
-			dinfo->jp2_handle = (void*)jp2_create_decompress((opj_common_ptr)dinfo);
-			if(!dinfo->jp2_handle) {
-				opj_free(dinfo);
-				return NULL;
-			}
-			break;
-		case CODEC_UNKNOWN:
-		default:
-			opj_free(dinfo);
-			return NULL;
-	}
-
-	dinfo->codec_format = format;
-
-	return dinfo;
-}
-
-void OPJ_CALLCONV opj_destroy_decompress(opj_dinfo_t *dinfo) {
-	if(dinfo) {
-		/* destroy the codec */
-		switch(dinfo->codec_format) {
-			case CODEC_J2K:
-			case CODEC_JPT:
-				j2k_destroy_decompress((opj_j2k_t*)dinfo->j2k_handle);
-				break;
-			case CODEC_JP2:
-				jp2_destroy_decompress((opj_jp2_t*)dinfo->jp2_handle);
-				break;
-			case CODEC_UNKNOWN:
-			default:
-				break;
-		}
-		/* destroy the decompressor */
-		opj_free(dinfo);
-	}
-}
-
-void OPJ_CALLCONV opj_set_default_decoder_parameters(opj_dparameters_t *parameters) {
-	if(parameters) {
-		memset(parameters, 0, sizeof(opj_dparameters_t));
-		/* default decoding parameters */
-		parameters->cp_layer = 0;
-		parameters->cp_reduce = 0;
-		parameters->cp_limit_decoding = NO_LIMITATION;
-
-		parameters->decod_format = -1;
-		parameters->cod_format = -1;
-		parameters->flags = 0;		
-/* UniPG>> */
-#ifdef USE_JPWL
-		parameters->jpwl_correct = OPJ_FALSE;
-		parameters->jpwl_exp_comps = JPWL_EXPECTED_COMPONENTS;
-		parameters->jpwl_max_tiles = JPWL_MAXIMUM_TILES;
-#endif /* USE_JPWL */
-/* <<UniPG */
-	}
-}
-
-void OPJ_CALLCONV opj_setup_decoder(opj_dinfo_t *dinfo, opj_dparameters_t *parameters) {
-	if(dinfo && parameters) {
-		switch(dinfo->codec_format) {
-			case CODEC_J2K:
-			case CODEC_JPT:
-				j2k_setup_decoder((opj_j2k_t*)dinfo->j2k_handle, parameters);
-				break;
-			case CODEC_JP2:
-				jp2_setup_decoder((opj_jp2_t*)dinfo->jp2_handle, parameters);
-				break;
-			case CODEC_UNKNOWN:
-			default:
-				break;
-		}
-	}
-}
-
-opj_image_t* OPJ_CALLCONV opj_decode(opj_dinfo_t *dinfo, opj_cio_t *cio) {
-	return opj_decode_with_info(dinfo, cio, NULL);
-}
-
-opj_image_t* OPJ_CALLCONV opj_decode_with_info(opj_dinfo_t *dinfo, opj_cio_t *cio, opj_codestream_info_t *cstr_info) {
-	if(dinfo && cio) {
-		switch(dinfo->codec_format) {
-			case CODEC_J2K:
-				return j2k_decode((opj_j2k_t*)dinfo->j2k_handle, cio, cstr_info);
-			case CODEC_JPT:
-				return j2k_decode_jpt_stream((opj_j2k_t*)dinfo->j2k_handle, cio, cstr_info);
-			case CODEC_JP2:
-				return opj_jp2_decode((opj_jp2_t*)dinfo->jp2_handle, cio, cstr_info);
-			case CODEC_UNKNOWN:
-			default:
-				break;
-		}
-	}
-	return NULL;
-}
-
-opj_cinfo_t* OPJ_CALLCONV opj_create_compress(OPJ_CODEC_FORMAT format) {
-	opj_cinfo_t *cinfo = (opj_cinfo_t*)opj_calloc(1, sizeof(opj_cinfo_t));
-	if(!cinfo) return NULL;
-	cinfo->is_decompressor = OPJ_FALSE;
-	switch(format) {
-		case CODEC_J2K:
-			/* get a J2K coder handle */
-			cinfo->j2k_handle = (void*)j2k_create_compress((opj_common_ptr)cinfo);
-			if(!cinfo->j2k_handle) {
-				opj_free(cinfo);
-				return NULL;
-			}
-			break;
-		case CODEC_JP2:
-			/* get a JP2 coder handle */
-			cinfo->jp2_handle = (void*)jp2_create_compress((opj_common_ptr)cinfo);
-			if(!cinfo->jp2_handle) {
-				opj_free(cinfo);
-				return NULL;
-			}
-			break;
-		case CODEC_JPT:
-		case CODEC_UNKNOWN:
-		default:
-			opj_free(cinfo);
-			return NULL;
-	}
-
-	cinfo->codec_format = format;
-
-	return cinfo;
-}
-
-void OPJ_CALLCONV opj_destroy_compress(opj_cinfo_t *cinfo) {
-	if(cinfo) {
-		/* destroy the codec */
-		switch(cinfo->codec_format) {
-			case CODEC_J2K:
-				j2k_destroy_compress((opj_j2k_t*)cinfo->j2k_handle);
-				break;
-			case CODEC_JP2:
-				jp2_destroy_compress((opj_jp2_t*)cinfo->jp2_handle);
-				break;
-			case CODEC_JPT:
-			case CODEC_UNKNOWN:
-			default:
-				break;
-		}
-		/* destroy the decompressor */
-		opj_free(cinfo);
-	}
-}
-
-void OPJ_CALLCONV opj_set_default_encoder_parameters(opj_cparameters_t *parameters) {
-	if(parameters) {
-		memset(parameters, 0, sizeof(opj_cparameters_t));
-		/* default coding parameters */
-		parameters->cp_cinema = OFF; 
-		parameters->max_comp_size = 0;
-		parameters->numresolution = 6;
-		parameters->cp_rsiz = STD_RSIZ;
-		parameters->cblockw_init = 64;
-		parameters->cblockh_init = 64;
-		parameters->prog_order = LRCP;
-		parameters->roi_compno = -1;		/* no ROI */
-		parameters->subsampling_dx = 1;
-		parameters->subsampling_dy = 1;
-		parameters->tp_on = 0;
-		parameters->decod_format = -1;
-		parameters->cod_format = -1;
-		parameters->tcp_rates[0] = 0;   
-		parameters->tcp_numlayers = 0;
-    parameters->cp_disto_alloc = 0;
-		parameters->cp_fixed_alloc = 0;
-		parameters->cp_fixed_quality = 0;
-		parameters->jpip_on = OPJ_FALSE;
-/* UniPG>> */
-#ifdef USE_JPWL
-		parameters->jpwl_epc_on = OPJ_FALSE;
-		parameters->jpwl_hprot_MH = -1; /* -1 means unassigned */
-		{
-			int i;
-			for (i = 0; i < JPWL_MAX_NO_TILESPECS; i++) {
-				parameters->jpwl_hprot_TPH_tileno[i] = -1; /* unassigned */
-				parameters->jpwl_hprot_TPH[i] = 0; /* absent */
-			}
-		};
-		{
-			int i;
-			for (i = 0; i < JPWL_MAX_NO_PACKSPECS; i++) {
-				parameters->jpwl_pprot_tileno[i] = -1; /* unassigned */
-				parameters->jpwl_pprot_packno[i] = -1; /* unassigned */
-				parameters->jpwl_pprot[i] = 0; /* absent */
-			}
-		};
-		parameters->jpwl_sens_size = 0; /* 0 means no ESD */
-		parameters->jpwl_sens_addr = 0; /* 0 means auto */
-		parameters->jpwl_sens_range = 0; /* 0 means packet */
-		parameters->jpwl_sens_MH = -1; /* -1 means unassigned */
-		{
-			int i;
-			for (i = 0; i < JPWL_MAX_NO_TILESPECS; i++) {
-				parameters->jpwl_sens_TPH_tileno[i] = -1; /* unassigned */
-				parameters->jpwl_sens_TPH[i] = -1; /* absent */
-			}
-		};
-#endif /* USE_JPWL */
-/* <<UniPG */
-	}
-}
-
-void OPJ_CALLCONV opj_setup_encoder(opj_cinfo_t *cinfo, opj_cparameters_t *parameters, opj_image_t *image) {
-	if(cinfo && parameters && image) {
-		switch(cinfo->codec_format) {
-			case CODEC_J2K:
-				j2k_setup_encoder((opj_j2k_t*)cinfo->j2k_handle, parameters, image);
-				break;
-			case CODEC_JP2:
-				jp2_setup_encoder((opj_jp2_t*)cinfo->jp2_handle, parameters, image);
-				break;
-			case CODEC_JPT:
-			case CODEC_UNKNOWN:
-			default:
-				break;
-		}
-	}
-}
-
-opj_bool OPJ_CALLCONV opj_encode(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *image, char *index) {
-	if (index != NULL)
-		opj_event_msg((opj_common_ptr)cinfo, EVT_WARNING, "Set index to NULL when calling the opj_encode function.\n"
-		"To extract the index, use the opj_encode_with_info() function.\n"
-		"No index will be generated during this encoding\n");
-	return opj_encode_with_info(cinfo, cio, image, NULL);
-}
-
-opj_bool OPJ_CALLCONV opj_encode_with_info(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) {
-	if(cinfo && cio && image) {
-		switch(cinfo->codec_format) {
-			case CODEC_J2K:
-				return j2k_encode((opj_j2k_t*)cinfo->j2k_handle, cio, image, cstr_info);
-			case CODEC_JP2:
-				return opj_jp2_encode((opj_jp2_t*)cinfo->jp2_handle, cio, image, cstr_info);	    
-			case CODEC_JPT:
-			case CODEC_UNKNOWN:
-			default:
-				break;
-		}
-	}
-	return OPJ_FALSE;
-}
-
-void OPJ_CALLCONV opj_destroy_cstr_info(opj_codestream_info_t *cstr_info) {
-	if (cstr_info) {
-		int tileno;
-		for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {
-			opj_tile_info_t *tile_info = &cstr_info->tile[tileno];
-			opj_free(tile_info->thresh);
-			opj_free(tile_info->packet);
-			opj_free(tile_info->tp);
-			opj_free(tile_info->marker);
-		}
-		opj_free(cstr_info->tile);
-		opj_free(cstr_info->marker);
-		opj_free(cstr_info->numdecompos);
-	}
-}
+/*
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2008;2011-2012, Centre National d'Etudes Spatiales (CNES), France 
+ * Copyright (c) 2012, CS Systemes d'Information, France
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef _WIN32
+#include <windows.h>
+#endif /* _WIN32 */
+
+#include "opj_includes.h"
+
+
+/* ---------------------------------------------------------------------- */
+/* Functions to set the message handlers */
+
+OPJ_BOOL OPJ_CALLCONV opj_set_info_handler(	opj_codec_t * p_codec, 
+											opj_msg_callback p_callback,
+											void * p_user_data)
+{
+	opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec;
+	if(! l_codec){
+		return OPJ_FALSE;
+	}
+	
+	l_codec->m_event_mgr.info_handler = p_callback;
+	l_codec->m_event_mgr.m_info_data = p_user_data;
+	
+	return OPJ_TRUE;
+}
+
+OPJ_BOOL OPJ_CALLCONV opj_set_warning_handler(	opj_codec_t * p_codec, 
+												opj_msg_callback p_callback,
+												void * p_user_data)
+{
+	opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec;
+	if (! l_codec) {
+		return OPJ_FALSE;
+	}
+	
+	l_codec->m_event_mgr.warning_handler = p_callback;
+	l_codec->m_event_mgr.m_warning_data = p_user_data;
+	
+	return OPJ_TRUE;
+}
+
+OPJ_BOOL OPJ_CALLCONV opj_set_error_handler(opj_codec_t * p_codec, 
+											opj_msg_callback p_callback,
+											void * p_user_data)
+{
+	opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec;
+	if (! l_codec) {
+		return OPJ_FALSE;
+	}
+	
+	l_codec->m_event_mgr.error_handler = p_callback;
+	l_codec->m_event_mgr.m_error_data = p_user_data;
+	
+	return OPJ_TRUE;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static OPJ_SIZE_T opj_read_from_file (void * p_buffer, OPJ_SIZE_T p_nb_bytes, FILE * p_file)
+{
+	OPJ_SIZE_T l_nb_read = fread(p_buffer,1,p_nb_bytes,p_file);
+	return l_nb_read ? l_nb_read : (OPJ_SIZE_T)-1;
+}
+
+static OPJ_UINT64 opj_get_data_length_from_file (FILE * p_file)
+{
+	OPJ_OFF_T file_length = 0;
+
+	OPJ_FSEEK(p_file, 0, SEEK_END);
+	file_length = (OPJ_OFF_T)OPJ_FTELL(p_file);
+	OPJ_FSEEK(p_file, 0, SEEK_SET);
+
+	return (OPJ_UINT64)file_length;
+}
+
+static OPJ_SIZE_T opj_write_from_file (void * p_buffer, OPJ_SIZE_T p_nb_bytes, FILE * p_file)
+{
+	return fwrite(p_buffer,1,p_nb_bytes,p_file);
+}
+
+static OPJ_OFF_T opj_skip_from_file (OPJ_OFF_T p_nb_bytes, FILE * p_user_data)
+{
+	if (OPJ_FSEEK(p_user_data,p_nb_bytes,SEEK_CUR)) {
+		return -1;
+	}
+
+	return p_nb_bytes;
+}
+
+static OPJ_BOOL opj_seek_from_file (OPJ_OFF_T p_nb_bytes, FILE * p_user_data)
+{
+	if (OPJ_FSEEK(p_user_data,p_nb_bytes,SEEK_SET)) {
+		return OPJ_FALSE;
+	}
+
+	return OPJ_TRUE;
+}
+
+/* ---------------------------------------------------------------------- */
+#ifdef _WIN32
+#ifndef OPJ_STATIC
+BOOL APIENTRY
+DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
+
+	OPJ_ARG_NOT_USED(lpReserved);
+	OPJ_ARG_NOT_USED(hModule);
+
+	switch (ul_reason_for_call) {
+		case DLL_PROCESS_ATTACH :
+			break;
+		case DLL_PROCESS_DETACH :
+			break;
+		case DLL_THREAD_ATTACH :
+		case DLL_THREAD_DETACH :
+			break;
+    }
+
+    return TRUE;
+}
+#endif /* OPJ_STATIC */
+#endif /* _WIN32 */
+
+/* ---------------------------------------------------------------------- */
+
+const char* OPJ_CALLCONV opj_version(void) {
+    return OPJ_PACKAGE_VERSION;
+}
+
+/* ---------------------------------------------------------------------- */
+/* DECOMPRESSION FUNCTIONS*/
+
+opj_codec_t* OPJ_CALLCONV opj_create_decompress(OPJ_CODEC_FORMAT p_format)
+{
+	opj_codec_private_t *l_codec = 00;
+
+	l_codec = (opj_codec_private_t*) opj_calloc(1, sizeof(opj_codec_private_t));
+	if (!l_codec){
+		return 00;
+	}
+	memset(l_codec, 0, sizeof(opj_codec_private_t));
+
+	l_codec->is_decompressor = 1;
+
+	switch (p_format) {
+		case OPJ_CODEC_J2K:
+			l_codec->opj_dump_codec = (void (*) (void*, OPJ_INT32, FILE*)) j2k_dump;
+
+			l_codec->opj_get_codec_info = (opj_codestream_info_v2_t* (*) (void*) ) j2k_get_cstr_info;
+
+			l_codec->opj_get_codec_index = (opj_codestream_index_t* (*) (void*) ) j2k_get_cstr_index;
+
+			l_codec->m_codec_data.m_decompression.opj_decode =
+					(OPJ_BOOL (*) (	void *,
+									struct opj_stream_private *,
+									opj_image_t*, struct opj_event_mgr * )) opj_j2k_decode;
+
+			l_codec->m_codec_data.m_decompression.opj_end_decompress =
+					(OPJ_BOOL (*) (	void *,
+									struct opj_stream_private *,
+									struct opj_event_mgr *)) opj_j2k_end_decompress;
+
+			l_codec->m_codec_data.m_decompression.opj_read_header =
+					(OPJ_BOOL (*) (	struct opj_stream_private *,
+									void *,
+									opj_image_t **,
+									struct opj_event_mgr * )) opj_j2k_read_header;
+
+			l_codec->m_codec_data.m_decompression.opj_destroy =
+					(void (*) (void *))opj_j2k_destroy;
+
+			l_codec->m_codec_data.m_decompression.opj_setup_decoder =
+					(void (*) (void * , opj_dparameters_t * )) opj_j2k_setup_decoder;
+
+			l_codec->m_codec_data.m_decompression.opj_read_tile_header =
+					(OPJ_BOOL (*) (	void *,
+									OPJ_UINT32*,
+									OPJ_UINT32*,
+									OPJ_INT32*, OPJ_INT32*,
+									OPJ_INT32*, OPJ_INT32*,
+									OPJ_UINT32*,
+									OPJ_BOOL*,
+									struct opj_stream_private *,
+									struct opj_event_mgr * )) opj_j2k_read_tile_header;
+
+			l_codec->m_codec_data.m_decompression.opj_decode_tile_data =
+					(OPJ_BOOL (*) ( void *, 
+                                    OPJ_UINT32, 
+                                    OPJ_BYTE*, 
+                                    OPJ_UINT32, 
+                                    struct opj_stream_private *,
+                                    struct opj_event_mgr *)) opj_j2k_decode_tile;
+
+			l_codec->m_codec_data.m_decompression.opj_set_decode_area =
+					(OPJ_BOOL (*) ( void *, 
+                                    opj_image_t*, 
+                                    OPJ_INT32, OPJ_INT32, OPJ_INT32, OPJ_INT32, 
+                                    struct opj_event_mgr *)) opj_j2k_set_decode_area;
+
+			l_codec->m_codec_data.m_decompression.opj_get_decoded_tile = 
+                    (OPJ_BOOL (*) ( void *p_codec,
+								    opj_stream_private_t *p_cio,
+								    opj_image_t *p_image,
+								    struct opj_event_mgr * p_manager,
+								    OPJ_UINT32 tile_index)) opj_j2k_get_tile;
+
+			l_codec->m_codec_data.m_decompression.opj_set_decoded_resolution_factor = 
+                    (OPJ_BOOL (*) ( void * p_codec,
+									OPJ_UINT32 res_factor,
+									struct opj_event_mgr * p_manager)) opj_j2k_set_decoded_resolution_factor;
+
+			l_codec->m_codec = opj_j2k_create_decompress();
+
+			if (! l_codec->m_codec) {
+				opj_free(l_codec);
+				return NULL;
+			}
+
+			break;
+
+		case OPJ_CODEC_JP2:
+			/* get a JP2 decoder handle */
+			l_codec->opj_dump_codec = (void (*) (void*, OPJ_INT32, FILE*)) jp2_dump;
+
+			l_codec->opj_get_codec_info = (opj_codestream_info_v2_t* (*) (void*) ) jp2_get_cstr_info;
+
+			l_codec->opj_get_codec_index = (opj_codestream_index_t* (*) (void*) ) jp2_get_cstr_index;
+
+			l_codec->m_codec_data.m_decompression.opj_decode =
+					(OPJ_BOOL (*) (	void *,
+									struct opj_stream_private *,
+									opj_image_t*,
+									struct opj_event_mgr * )) opj_jp2_decode;
+
+			l_codec->m_codec_data.m_decompression.opj_end_decompress =  
+                    (OPJ_BOOL (*) ( void *,
+                                    struct opj_stream_private *,
+                                    struct opj_event_mgr *)) opj_jp2_end_decompress;
+
+			l_codec->m_codec_data.m_decompression.opj_read_header =  
+                    (OPJ_BOOL (*) ( struct opj_stream_private *,
+					                void *,
+					                opj_image_t **,
+					                struct opj_event_mgr * )) opj_jp2_read_header;
+
+			l_codec->m_codec_data.m_decompression.opj_read_tile_header = 
+                    (OPJ_BOOL (*) ( void *,
+					                OPJ_UINT32*,
+					                OPJ_UINT32*,
+					                OPJ_INT32*,
+					                OPJ_INT32*,
+					                OPJ_INT32 * ,
+					                OPJ_INT32 * ,
+					                OPJ_UINT32 * ,
+					                OPJ_BOOL *,
+					                struct opj_stream_private *,
+					                struct opj_event_mgr * )) opj_jp2_read_tile_header;
+
+			l_codec->m_codec_data.m_decompression.opj_decode_tile_data = 
+                    (OPJ_BOOL (*) ( void *,
+                                    OPJ_UINT32,OPJ_BYTE*,OPJ_UINT32,
+                                    struct opj_stream_private *,
+                                    struct opj_event_mgr * )) opj_jp2_decode_tile;
+
+			l_codec->m_codec_data.m_decompression.opj_destroy = (void (*) (void *))opj_jp2_destroy;
+
+			l_codec->m_codec_data.m_decompression.opj_setup_decoder = 
+                    (void (*) (void * ,opj_dparameters_t * )) opj_jp2_setup_decoder;
+
+			l_codec->m_codec_data.m_decompression.opj_set_decode_area = 
+                    (OPJ_BOOL (*) ( void *,
+                                    opj_image_t*, 
+                                    OPJ_INT32,OPJ_INT32,OPJ_INT32,OPJ_INT32,
+                                    struct opj_event_mgr * )) opj_jp2_set_decode_area;
+
+			l_codec->m_codec_data.m_decompression.opj_get_decoded_tile = 
+                    (OPJ_BOOL (*) ( void *p_codec,
+									opj_stream_private_t *p_cio,
+									opj_image_t *p_image,
+									struct opj_event_mgr * p_manager,
+									OPJ_UINT32 tile_index)) opj_jp2_get_tile;
+
+			l_codec->m_codec_data.m_decompression.opj_set_decoded_resolution_factor = 
+                    (OPJ_BOOL (*) ( void * p_codec,
+						    		OPJ_UINT32 res_factor,
+							    	opj_event_mgr_t * p_manager)) opj_jp2_set_decoded_resolution_factor;
+
+			l_codec->m_codec = opj_jp2_create(OPJ_TRUE);
+
+			if (! l_codec->m_codec) {
+				opj_free(l_codec);
+				return 00;
+			}
+
+			break;
+		case OPJ_CODEC_UNKNOWN:
+		case OPJ_CODEC_JPT:
+		default:
+			opj_free(l_codec);
+			return 00;
+	}
+
+	opj_set_default_event_handler(&(l_codec->m_event_mgr));
+	return (opj_codec_t*) l_codec;
+}
+
+void OPJ_CALLCONV opj_set_default_decoder_parameters(opj_dparameters_t *parameters) {
+	if(parameters) {
+		memset(parameters, 0, sizeof(opj_dparameters_t));
+		/* default decoding parameters */
+		parameters->cp_layer = 0;
+		parameters->cp_reduce = 0;
+
+		parameters->decod_format = -1;
+		parameters->cod_format = -1;
+		parameters->flags = 0;		
+/* UniPG>> */
+#ifdef USE_JPWL
+		parameters->jpwl_correct = OPJ_FALSE;
+		parameters->jpwl_exp_comps = JPWL_EXPECTED_COMPONENTS;
+		parameters->jpwl_max_tiles = JPWL_MAXIMUM_TILES;
+#endif /* USE_JPWL */
+/* <<UniPG */
+	}
+}
+
+OPJ_BOOL OPJ_CALLCONV opj_setup_decoder(opj_codec_t *p_codec,
+                                        opj_dparameters_t *parameters 
+										)
+{
+	if (p_codec && parameters) { 
+		opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec;
+
+		if (! l_codec->is_decompressor) {
+			opj_event_msg(&(l_codec->m_event_mgr), EVT_ERROR, 
+                "Codec provided to the opj_setup_decoder function is not a decompressor handler.\n");
+			return OPJ_FALSE;
+		}
+
+		l_codec->m_codec_data.m_decompression.opj_setup_decoder(l_codec->m_codec,
+																parameters);
+		return OPJ_TRUE;
+	}
+	return OPJ_FALSE;
+}
+
+OPJ_BOOL OPJ_CALLCONV opj_read_header (	opj_stream_t *p_stream,
+										opj_codec_t *p_codec,
+										opj_image_t **p_image )
+{
+	if (p_codec && p_stream) {
+		opj_codec_private_t* l_codec = (opj_codec_private_t*) p_codec;
+		opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
+
+		if(! l_codec->is_decompressor) {
+			opj_event_msg(&(l_codec->m_event_mgr), EVT_ERROR, 
+                "Codec provided to the opj_read_header function is not a decompressor handler.\n");
+			return OPJ_FALSE;
+		}
+
+		return l_codec->m_codec_data.m_decompression.opj_read_header(	l_stream,
+																		l_codec->m_codec,
+																		p_image,
+																		&(l_codec->m_event_mgr) );
+	}
+
+	return OPJ_FALSE;
+}
+
+OPJ_BOOL OPJ_CALLCONV opj_decode(   opj_codec_t *p_codec,
+                                    opj_stream_t *p_stream,
+                                    opj_image_t* p_image)
+{
+	if (p_codec && p_stream) {
+		opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec;
+		opj_stream_private_t * l_stream = (opj_stream_private_t *) p_stream;
+
+		if (! l_codec->is_decompressor) {
+			return OPJ_FALSE;
+		}
+
+		return l_codec->m_codec_data.m_decompression.opj_decode(l_codec->m_codec,
+																l_stream,
+																p_image,
+																&(l_codec->m_event_mgr) );
+	}
+
+	return OPJ_FALSE;
+}
+
+OPJ_BOOL OPJ_CALLCONV opj_set_decode_area(	opj_codec_t *p_codec,
+											opj_image_t* p_image,
+											OPJ_INT32 p_start_x, OPJ_INT32 p_start_y,
+											OPJ_INT32 p_end_x, OPJ_INT32 p_end_y
+											)
+{
+	if (p_codec) {
+		opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec;
+		
+		if (! l_codec->is_decompressor) {
+			return OPJ_FALSE;
+		}
+
+		return  l_codec->m_codec_data.m_decompression.opj_set_decode_area(	l_codec->m_codec,
+																			p_image,
+																			p_start_x, p_start_y,
+																			p_end_x, p_end_y,
+																			&(l_codec->m_event_mgr) );
+	}
+	return OPJ_FALSE;
+}
+
+OPJ_BOOL OPJ_CALLCONV opj_read_tile_header(	opj_codec_t *p_codec,
+											opj_stream_t * p_stream,
+											OPJ_UINT32 * p_tile_index,
+											OPJ_UINT32 * p_data_size,
+											OPJ_INT32 * p_tile_x0, OPJ_INT32 * p_tile_y0,
+											OPJ_INT32 * p_tile_x1, OPJ_INT32 * p_tile_y1,
+											OPJ_UINT32 * p_nb_comps,
+											OPJ_BOOL * p_should_go_on)
+{
+	if (p_codec && p_stream && p_data_size && p_tile_index) {
+		opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec;
+		opj_stream_private_t * l_stream = (opj_stream_private_t *) p_stream;
+
+		if (! l_codec->is_decompressor) {
+			return OPJ_FALSE;
+		}
+
+		return l_codec->m_codec_data.m_decompression.opj_read_tile_header(	l_codec->m_codec,
+																			p_tile_index,
+																			p_data_size,
+																			p_tile_x0, p_tile_y0,
+																			p_tile_x1, p_tile_y1,
+																			p_nb_comps,
+																			p_should_go_on,
+																			l_stream,
+																			&(l_codec->m_event_mgr));
+	}
+	return OPJ_FALSE;
+}
+
+OPJ_BOOL OPJ_CALLCONV opj_decode_tile_data(	opj_codec_t *p_codec,
+											OPJ_UINT32 p_tile_index,
+											OPJ_BYTE * p_data,
+											OPJ_UINT32 p_data_size,
+											opj_stream_t *p_stream
+											)
+{
+	if (p_codec && p_data && p_stream) {
+		opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec;
+		opj_stream_private_t * l_stream = (opj_stream_private_t *) p_stream;
+
+		if (! l_codec->is_decompressor) {
+			return OPJ_FALSE;
+		}
+
+		return l_codec->m_codec_data.m_decompression.opj_decode_tile_data(	l_codec->m_codec,
+																			p_tile_index,
+																			p_data,
+																			p_data_size,
+																			l_stream,
+																			&(l_codec->m_event_mgr) );
+	}
+	return OPJ_FALSE;
+}
+
+OPJ_BOOL OPJ_CALLCONV opj_get_decoded_tile(	opj_codec_t *p_codec,
+											opj_stream_t *p_stream,
+											opj_image_t *p_image,
+											OPJ_UINT32 tile_index)
+{
+	if (p_codec && p_stream) {
+		opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec;
+		opj_stream_private_t * l_stream = (opj_stream_private_t *) p_stream;
+
+		if (! l_codec->is_decompressor) {
+			return OPJ_FALSE;
+		}
+		
+		return l_codec->m_codec_data.m_decompression.opj_get_decoded_tile(	l_codec->m_codec,
+																			l_stream,
+																			p_image,
+																			&(l_codec->m_event_mgr),
+																			tile_index);
+	}
+
+	return OPJ_FALSE;
+}
+
+OPJ_BOOL OPJ_CALLCONV opj_set_decoded_resolution_factor(opj_codec_t *p_codec, 
+														OPJ_UINT32 res_factor )
+{
+	opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec;
+
+	if ( !l_codec ){
+		fprintf(stderr, "[ERROR] Input parameters of the setup_decoder function are incorrect.\n");
+		return OPJ_FALSE;
+	}
+
+	l_codec->m_codec_data.m_decompression.opj_set_decoded_resolution_factor(l_codec->m_codec, 
+																			res_factor,
+																			&(l_codec->m_event_mgr) );
+	return OPJ_TRUE;
+}
+
+/* ---------------------------------------------------------------------- */
+/* COMPRESSION FUNCTIONS*/
+
+opj_codec_t* OPJ_CALLCONV opj_create_compress(OPJ_CODEC_FORMAT p_format)
+{
+	opj_codec_private_t *l_codec = 00;
+
+	l_codec = (opj_codec_private_t*)opj_calloc(1, sizeof(opj_codec_private_t));
+	if (!l_codec) {
+		return 00;
+	}
+	memset(l_codec, 0, sizeof(opj_codec_private_t));
+	
+	l_codec->is_decompressor = 0;
+
+	switch(p_format) {
+		case OPJ_CODEC_J2K:
+			l_codec->m_codec_data.m_compression.opj_encode = (OPJ_BOOL (*) (void *,
+																			struct opj_stream_private *,
+																			struct opj_event_mgr * )) opj_j2k_encode;
+
+			l_codec->m_codec_data.m_compression.opj_end_compress = (OPJ_BOOL (*) (	void *,
+																					struct opj_stream_private *,
+																					struct opj_event_mgr *)) opj_j2k_end_compress;
+
+			l_codec->m_codec_data.m_compression.opj_start_compress = (OPJ_BOOL (*) (void *,
+																					struct opj_stream_private *,
+																					struct opj_image * ,
+																					struct opj_event_mgr *)) opj_j2k_start_compress;
+
+			l_codec->m_codec_data.m_compression.opj_write_tile = (OPJ_BOOL (*) (void *,
+																				OPJ_UINT32,
+																				OPJ_BYTE*,
+																				OPJ_UINT32,
+																				struct opj_stream_private *,
+																				struct opj_event_mgr *) ) opj_j2k_write_tile;
+
+			l_codec->m_codec_data.m_compression.opj_destroy = (void (*) (void *)) opj_j2k_destroy;
+
+			l_codec->m_codec_data.m_compression.opj_setup_encoder = (void (*) (	void *,
+																				opj_cparameters_t *,
+																				struct opj_image *,
+																				struct opj_event_mgr * )) opj_j2k_setup_encoder;
+
+			l_codec->m_codec = opj_j2k_create_compress();
+			if (! l_codec->m_codec) {
+				opj_free(l_codec);
+				return 00;
+			}
+
+			break;
+
+		case OPJ_CODEC_JP2:
+			/* get a JP2 decoder handle */
+			l_codec->m_codec_data.m_compression.opj_encode = (OPJ_BOOL (*) (void *,
+																			struct opj_stream_private *,
+																			struct opj_event_mgr * )) opj_jp2_encode;
+
+			l_codec->m_codec_data.m_compression.opj_end_compress = (OPJ_BOOL (*) (	void *,
+																					struct opj_stream_private *,
+																					struct opj_event_mgr *)) opj_jp2_end_compress;
+
+			l_codec->m_codec_data.m_compression.opj_start_compress = (OPJ_BOOL (*) (void *,
+																					struct opj_stream_private *,
+																					struct opj_image * ,
+																					struct opj_event_mgr *))  opj_jp2_start_compress;
+
+			l_codec->m_codec_data.m_compression.opj_write_tile = (OPJ_BOOL (*) (void *,
+																				OPJ_UINT32,
+																				OPJ_BYTE*,
+																				OPJ_UINT32,
+																				struct opj_stream_private *,
+																				struct opj_event_mgr *)) opj_jp2_write_tile;
+
+			l_codec->m_codec_data.m_compression.opj_destroy = (void (*) (void *)) opj_jp2_destroy;
+
+			l_codec->m_codec_data.m_compression.opj_setup_encoder = (void (*) (	void *,
+																				opj_cparameters_t *,
+																				struct opj_image *,
+																				struct opj_event_mgr * )) opj_jp2_setup_encoder;
+
+			l_codec->m_codec = opj_jp2_create(OPJ_FALSE);
+			if (! l_codec->m_codec) {
+				opj_free(l_codec);
+				return 00;
+			}
+
+			break;
+
+		case OPJ_CODEC_UNKNOWN:
+		case OPJ_CODEC_JPT:
+		default:
+			opj_free(l_codec);
+			return 00;
+	}
+
+	opj_set_default_event_handler(&(l_codec->m_event_mgr));
+	return (opj_codec_t*) l_codec;
+}
+
+void OPJ_CALLCONV opj_set_default_encoder_parameters(opj_cparameters_t *parameters) {
+	if(parameters) {
+		memset(parameters, 0, sizeof(opj_cparameters_t));
+		/* default coding parameters */
+		parameters->cp_cinema = OPJ_OFF; 
+		parameters->max_comp_size = 0;
+		parameters->numresolution = 6;
+		parameters->cp_rsiz = OPJ_STD_RSIZ;
+		parameters->cblockw_init = 64;
+		parameters->cblockh_init = 64;
+		parameters->prog_order = OPJ_LRCP;
+		parameters->roi_compno = -1;		/* no ROI */
+		parameters->subsampling_dx = 1;
+		parameters->subsampling_dy = 1;
+		parameters->tp_on = 0;
+		parameters->decod_format = -1;
+		parameters->cod_format = -1;
+		parameters->tcp_rates[0] = 0;   
+		parameters->tcp_numlayers = 0;
+		parameters->cp_disto_alloc = 0;
+		parameters->cp_fixed_alloc = 0;
+		parameters->cp_fixed_quality = 0;
+		parameters->jpip_on = OPJ_FALSE;
+/* UniPG>> */
+#ifdef USE_JPWL
+		parameters->jpwl_epc_on = OPJ_FALSE;
+		parameters->jpwl_hprot_MH = -1; /* -1 means unassigned */
+		{
+			int i;
+			for (i = 0; i < JPWL_MAX_NO_TILESPECS; i++) {
+				parameters->jpwl_hprot_TPH_tileno[i] = -1; /* unassigned */
+				parameters->jpwl_hprot_TPH[i] = 0; /* absent */
+			}
+		};
+		{
+			int i;
+			for (i = 0; i < JPWL_MAX_NO_PACKSPECS; i++) {
+				parameters->jpwl_pprot_tileno[i] = -1; /* unassigned */
+				parameters->jpwl_pprot_packno[i] = -1; /* unassigned */
+				parameters->jpwl_pprot[i] = 0; /* absent */
+			}
+		};
+		parameters->jpwl_sens_size = 0; /* 0 means no ESD */
+		parameters->jpwl_sens_addr = 0; /* 0 means auto */
+		parameters->jpwl_sens_range = 0; /* 0 means packet */
+		parameters->jpwl_sens_MH = -1; /* -1 means unassigned */
+		{
+			int i;
+			for (i = 0; i < JPWL_MAX_NO_TILESPECS; i++) {
+				parameters->jpwl_sens_TPH_tileno[i] = -1; /* unassigned */
+				parameters->jpwl_sens_TPH[i] = -1; /* absent */
+			}
+		};
+#endif /* USE_JPWL */
+/* <<UniPG */
+	}
+}
+
+OPJ_BOOL OPJ_CALLCONV opj_setup_encoder(opj_codec_t *p_codec, 
+										opj_cparameters_t *parameters, 
+										opj_image_t *p_image)
+{
+	if (p_codec && parameters && p_image) {
+		opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec;
+
+		if (! l_codec->is_decompressor) {
+			l_codec->m_codec_data.m_compression.opj_setup_encoder(	l_codec->m_codec,
+																	parameters,
+																	p_image,
+																	&(l_codec->m_event_mgr) );
+			return OPJ_TRUE;
+		}
+	}
+
+	return OPJ_FALSE;
+}
+
+OPJ_BOOL OPJ_CALLCONV opj_start_compress (	opj_codec_t *p_codec,
+											opj_image_t * p_image,
+											opj_stream_t *p_stream)
+{
+	if (p_codec && p_stream) {
+		opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec;
+		opj_stream_private_t * l_stream = (opj_stream_private_t *) p_stream;
+
+		if (! l_codec->is_decompressor) {
+			return l_codec->m_codec_data.m_compression.opj_start_compress(	l_codec->m_codec,
+																			l_stream,
+																			p_image,
+																			&(l_codec->m_event_mgr));
+		}
+	}
+
+	return OPJ_FALSE;
+}
+
+OPJ_BOOL OPJ_CALLCONV opj_encode(opj_codec_t *p_info, opj_stream_t *p_stream)
+{
+	if (p_info && p_stream) {
+		opj_codec_private_t * l_codec = (opj_codec_private_t *) p_info;
+		opj_stream_private_t * l_stream = (opj_stream_private_t *) p_stream;
+
+		if (! l_codec->is_decompressor) {
+			return l_codec->m_codec_data.m_compression.opj_encode(	l_codec->m_codec,
+															l_stream,
+															&(l_codec->m_event_mgr));
+		}
+	}
+
+	return OPJ_FALSE;
+
+}
+
+OPJ_BOOL OPJ_CALLCONV opj_end_compress (opj_codec_t *p_codec,
+										opj_stream_t *p_stream)
+{
+	if (p_codec && p_stream) {
+		opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec;
+		opj_stream_private_t * l_stream = (opj_stream_private_t *) p_stream;
+
+		if (! l_codec->is_decompressor) {
+			return l_codec->m_codec_data.m_compression.opj_end_compress(l_codec->m_codec,
+																		l_stream,
+																		&(l_codec->m_event_mgr));
+		}
+	}
+	return OPJ_FALSE;
+
+}
+
+OPJ_BOOL OPJ_CALLCONV opj_end_decompress (	opj_codec_t *p_codec,
+											opj_stream_t *p_stream)
+{
+	if (p_codec && p_stream) {
+		opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec;
+		opj_stream_private_t * l_stream = (opj_stream_private_t *) p_stream;
+
+		if (! l_codec->is_decompressor) {
+			return OPJ_FALSE;
+		}
+		
+		return l_codec->m_codec_data.m_decompression.opj_end_decompress(l_codec->m_codec,
+																		l_stream,
+																		&(l_codec->m_event_mgr) );
+	}
+
+	return OPJ_FALSE;
+}
+
+OPJ_BOOL OPJ_CALLCONV opj_set_MCT(opj_cparameters_t *parameters,
+                                  OPJ_FLOAT32 * pEncodingMatrix,
+                                  OPJ_INT32 * p_dc_shift,OPJ_UINT32 pNbComp)
+{
+	OPJ_UINT32 l_matrix_size = pNbComp * pNbComp * (OPJ_UINT32)sizeof(OPJ_FLOAT32);
+	OPJ_UINT32 l_dc_shift_size = pNbComp * (OPJ_UINT32)sizeof(OPJ_INT32);
+	OPJ_UINT32 l_mct_total_size = l_matrix_size + l_dc_shift_size;
+
+	/* add MCT capability */
+	OPJ_INT32 rsiz = (OPJ_INT32)parameters->cp_rsiz | (OPJ_INT32)OPJ_MCT;
+	parameters->cp_rsiz = (OPJ_RSIZ_CAPABILITIES)rsiz;
+	parameters->irreversible = 1;
+
+	/* use array based MCT */
+	parameters->tcp_mct = 2;
+	parameters->mct_data = opj_malloc(l_mct_total_size);
+	if (! parameters->mct_data) {
+		return OPJ_FALSE;
+	}
+
+	memcpy(parameters->mct_data,pEncodingMatrix,l_matrix_size);
+	memcpy(((OPJ_BYTE *) parameters->mct_data) +  l_matrix_size,p_dc_shift,l_dc_shift_size);
+
+	return OPJ_TRUE;
+}
+
+OPJ_BOOL OPJ_CALLCONV opj_write_tile (	opj_codec_t *p_codec,
+										OPJ_UINT32 p_tile_index,
+										OPJ_BYTE * p_data,
+										OPJ_UINT32 p_data_size,
+										opj_stream_t *p_stream )
+{
+	if (p_codec && p_stream && p_data) {
+		opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec;
+		opj_stream_private_t * l_stream = (opj_stream_private_t *) p_stream;
+
+		if (l_codec->is_decompressor) {
+			return OPJ_FALSE;
+		}
+
+		return l_codec->m_codec_data.m_compression.opj_write_tile(	l_codec->m_codec,
+																	p_tile_index,
+																	p_data,
+																	p_data_size,
+																	l_stream,
+																	&(l_codec->m_event_mgr) );
+	}
+
+	return OPJ_FALSE;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void OPJ_CALLCONV opj_destroy_codec(opj_codec_t *p_codec)
+{
+	if (p_codec) {
+		opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec;
+
+		if (l_codec->is_decompressor) {
+			l_codec->m_codec_data.m_decompression.opj_destroy(l_codec->m_codec);
+		}
+		else {
+			l_codec->m_codec_data.m_compression.opj_destroy(l_codec->m_codec);
+		}
+
+		l_codec->m_codec = 00;
+		opj_free(l_codec);
+	}
+}
+
+/* ---------------------------------------------------------------------- */
+
+void OPJ_CALLCONV opj_dump_codec(	opj_codec_t *p_codec,
+									OPJ_INT32 info_flag,
+									FILE* output_stream)
+{
+	if (p_codec) {
+		opj_codec_private_t* l_codec = (opj_codec_private_t*) p_codec;
+
+		l_codec->opj_dump_codec(l_codec->m_codec, info_flag, output_stream);
+		return;
+	}
+
+	fprintf(stderr, "[ERROR] Input parameter of the dump_codec function are incorrect.\n");
+	return;
+}
+
+opj_codestream_info_v2_t* OPJ_CALLCONV opj_get_cstr_info(opj_codec_t *p_codec)
+{
+	if (p_codec) {
+		opj_codec_private_t* l_codec = (opj_codec_private_t*) p_codec;
+
+		return l_codec->opj_get_codec_info(l_codec->m_codec);
+	}
+
+	return NULL;
+}
+
+void OPJ_CALLCONV opj_destroy_cstr_info(opj_codestream_info_v2_t **cstr_info) {
+	if (cstr_info) {
+
+		if ((*cstr_info)->m_default_tile_info.tccp_info){
+			opj_free((*cstr_info)->m_default_tile_info.tccp_info);
+		}
+
+		if ((*cstr_info)->tile_info){
+			/* FIXME not used for the moment*/
+		}
+
+		opj_free((*cstr_info));
+		(*cstr_info) = NULL;
+	}
+}
+
+opj_codestream_index_t * OPJ_CALLCONV opj_get_cstr_index(opj_codec_t *p_codec)
+{
+	if (p_codec) {
+		opj_codec_private_t* l_codec = (opj_codec_private_t*) p_codec;
+
+		return l_codec->opj_get_codec_index(l_codec->m_codec);
+	}
+
+	return NULL;
+}
+
+void OPJ_CALLCONV opj_destroy_cstr_index(opj_codestream_index_t **p_cstr_index)
+{
+	if (*p_cstr_index){
+		j2k_destroy_cstr_index(*p_cstr_index);
+		(*p_cstr_index) = NULL;
+	}
+}
+
+opj_stream_t* OPJ_CALLCONV opj_stream_create_default_file_stream_v3 (const char *fname, OPJ_BOOL p_is_read_stream)
+{
+    return opj_stream_create_file_stream_v3(fname, OPJ_J2K_STREAM_CHUNK_SIZE, p_is_read_stream);
+}
+
+opj_stream_t* OPJ_CALLCONV opj_stream_create_file_stream_v3 (
+        const char *fname, 
+		OPJ_SIZE_T p_size, 
+        OPJ_BOOL p_is_read_stream)
+{
+    opj_stream_t* l_stream = 00;
+    FILE *p_file;
+    const char *mode;
+
+    if (! fname) {
+        return NULL;
+    }
+    
+    if(p_is_read_stream) mode = "rb"; else mode = "wb";
+
+    p_file = fopen(fname, mode);
+
+    if (! p_file) {
+	    return NULL;
+    }
+
+    l_stream = opj_stream_create(p_size,p_is_read_stream);
+    if (! l_stream) {
+        fclose(p_file);
+        return NULL;
+    }
+
+    opj_stream_set_user_data(l_stream, p_file, (opj_stream_free_user_data_fn) fclose);
+    opj_stream_set_user_data_length(l_stream, opj_get_data_length_from_file(p_file));
+    opj_stream_set_read_function(l_stream, (opj_stream_read_fn) opj_read_from_file);
+    opj_stream_set_write_function(l_stream, (opj_stream_write_fn) opj_write_from_file);
+    opj_stream_set_skip_function(l_stream, (opj_stream_skip_fn) opj_skip_from_file);
+    opj_stream_set_seek_function(l_stream, (opj_stream_seek_fn) opj_seek_from_file);
+
+    return l_stream;
+}
diff --git a/Source/LibOpenJPEG/openjpeg.h b/Source/LibOpenJPEG/openjpeg.h
index bbc35c2..0d03b1f 100644
--- a/Source/LibOpenJPEG/openjpeg.h
+++ b/Source/LibOpenJPEG/openjpeg.h
@@ -1,914 +1,1475 @@
- /*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
- * Copyright (c) 2001-2003, David Janssens
- * Copyright (c) 2002-2003, Yannick Verschueren
- * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * Copyright (c) 2006-2007, Parvatha Elangovan
- * Copyright (c) 2010-2011, Kaori Hagihara
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef OPENJPEG_H
-#define OPENJPEG_H
-
-
-/* 
-==========================================================
-   Compiler directives
-==========================================================
-*/
-
-#if defined(OPJ_STATIC) || !defined(_WIN32)
-#define OPJ_API
-#define OPJ_CALLCONV
-#else
-#define OPJ_CALLCONV __stdcall
-/*
-The following ifdef block is the standard way of creating macros which make exporting 
-from a DLL simpler. All files within this DLL are compiled with the OPJ_EXPORTS
-symbol defined on the command line. this symbol should not be defined on any project
-that uses this DLL. This way any other project whose source files include this file see 
-OPJ_API functions as being imported from a DLL, wheras this DLL sees symbols
-defined with this macro as being exported.
-*/
-#if defined(OPJ_EXPORTS) || defined(DLL_EXPORT)
-#define OPJ_API __declspec(dllexport)
-#else
-#define OPJ_API __declspec(dllimport)
-#endif /* OPJ_EXPORTS */
-#endif /* !OPJ_STATIC || !_WIN32 */
-
-typedef int opj_bool;
-#define OPJ_TRUE 1
-#define OPJ_FALSE 0
-
-/* Avoid compile-time warning because parameter is not used */
-#define OPJ_ARG_NOT_USED(x) (void)(x)
-/* 
-==========================================================
-   Useful constant definitions
-==========================================================
-*/
-
-#define OPJ_PATH_LEN 4096 /**< Maximum allowed size for filenames */
-
-#define J2K_MAXRLVLS 33					/**< Number of maximum resolution level authorized */
-#define J2K_MAXBANDS (3*J2K_MAXRLVLS-2)	/**< Number of maximum sub-band linked to number of resolution level */
-
-/* UniPG>> */
-#define JPWL_MAX_NO_TILESPECS	16 /**< Maximum number of tile parts expected by JPWL: increase at your will */
-#define JPWL_MAX_NO_PACKSPECS	16 /**< Maximum number of packet parts expected by JPWL: increase at your will */
-#define JPWL_MAX_NO_MARKERS	512 /**< Maximum number of JPWL markers: increase at your will */
-#define JPWL_PRIVATEINDEX_NAME "jpwl_index_privatefilename" /**< index file name used when JPWL is on */
-#define JPWL_EXPECTED_COMPONENTS 3 /**< Expect this number of components, so you'll find better the first EPB */
-#define JPWL_MAXIMUM_TILES 8192 /**< Expect this maximum number of tiles, to avoid some crashes */
-#define JPWL_MAXIMUM_HAMMING 2 /**< Expect this maximum number of bit errors in marker id's */
-#define JPWL_MAXIMUM_EPB_ROOM 65450 /**< Expect this maximum number of bytes for composition of EPBs */
-/* <<UniPG */
-
-/* 
-==========================================================
-   enum definitions
-==========================================================
-*/
-/** 
-Rsiz Capabilities
-*/
-typedef enum RSIZ_CAPABILITIES {
-	STD_RSIZ = 0,		/** Standard JPEG2000 profile*/
-	CINEMA2K = 3,		/** Profile name for a 2K image*/
-	CINEMA4K = 4		/** Profile name for a 4K image*/
-} OPJ_RSIZ_CAPABILITIES;
-
-/** 
-Digital cinema operation mode 
-*/
-typedef enum CINEMA_MODE {
-	OFF = 0,					/** Not Digital Cinema*/
-	CINEMA2K_24 = 1,	/** 2K Digital Cinema at 24 fps*/
-	CINEMA2K_48 = 2,	/** 2K Digital Cinema at 48 fps*/
-	CINEMA4K_24 = 3		/** 4K Digital Cinema at 24 fps*/
-}OPJ_CINEMA_MODE;
-
-/** 
-Progression order 
-*/
-typedef enum PROG_ORDER {
-	PROG_UNKNOWN = -1,	/**< place-holder */
-	LRCP = 0,		/**< layer-resolution-component-precinct order */
-	RLCP = 1,		/**< resolution-layer-component-precinct order */
-	RPCL = 2,		/**< resolution-precinct-component-layer order */
-	PCRL = 3,		/**< precinct-component-resolution-layer order */
-	CPRL = 4		/**< component-precinct-resolution-layer order */
-} OPJ_PROG_ORDER;
-
-/**
-Supported image color spaces
-*/
-typedef enum COLOR_SPACE {
-	CLRSPC_UNKNOWN = -1,	/**< not supported by the library */
-	CLRSPC_UNSPECIFIED = 0, /**< not specified in the codestream */ 
-	CLRSPC_SRGB = 1,		/**< sRGB */
-	CLRSPC_GRAY = 2,		/**< grayscale */
-	CLRSPC_SYCC = 3			/**< YUV */
-} OPJ_COLOR_SPACE;
-
-#define ENUMCS_SRGB 16
-#define ENUMCS_GRAY 17
-#define ENUMCS_SYCC 18
-
-/**
-Supported codec
-*/
-typedef enum CODEC_FORMAT {
-	CODEC_UNKNOWN = -1,	/**< place-holder */
-	CODEC_J2K  = 0,		/**< JPEG-2000 codestream : read/write */
-	CODEC_JPT  = 1,		/**< JPT-stream (JPEG 2000, JPIP) : read only */
-	CODEC_JP2  = 2 		/**< JPEG-2000 file format : read/write */
-} OPJ_CODEC_FORMAT;
-
-/** 
-Limit decoding to certain portions of the codestream. 
-*/
-typedef enum LIMIT_DECODING {
-	NO_LIMITATION = 0,				  /**< No limitation for the decoding. The entire codestream will de decoded */
-	LIMIT_TO_MAIN_HEADER = 1,		/**< The decoding is limited to the Main Header */
-	DECODE_ALL_BUT_PACKETS = 2	/**< Decode everything except the JPEG 2000 packets */
-} OPJ_LIMIT_DECODING;
-
-/* 
-==========================================================
-   event manager typedef definitions
-==========================================================
-*/
-
-/**
-Callback function prototype for events
- at param msg Event message
- at param client_data 
-*/
-typedef void (*opj_msg_callback) (const char *msg, void *client_data);
-
-/**
-Message handler object
-used for 
-<ul>
-<li>Error messages
-<li>Warning messages
-<li>Debugging messages
-</ul>
-*/
-typedef struct opj_event_mgr {
-	/** Error message callback if available, NULL otherwise */
-	opj_msg_callback error_handler;
-	/** Warning message callback if available, NULL otherwise */
-	opj_msg_callback warning_handler;
-	/** Debug message callback if available, NULL otherwise */
-	opj_msg_callback info_handler;
-} opj_event_mgr_t;
-
-
-/* 
-==========================================================
-   codec typedef definitions
-==========================================================
-*/
-
-/**
-Progression order changes
-*/
-typedef struct opj_poc {
-	/** Resolution num start, Component num start, given by POC */
-	int resno0, compno0;
-	/** Layer num end,Resolution num end, Component num end, given by POC */
-	int layno1, resno1, compno1;
-	/** Layer num start,Precinct num start, Precinct num end */
-	int layno0, precno0, precno1;
-	/** Progression order enum*/
-	OPJ_PROG_ORDER prg1,prg;
-	/** Progression order string*/
-	char progorder[5];
-	/** Tile number */
-	int tile;
-	/** Start and end values for Tile width and height*/
-	int tx0,tx1,ty0,ty1;
-	/** Start value, initialised in pi_initialise_encode*/
-	int layS, resS, compS, prcS;
-	/** End value, initialised in pi_initialise_encode */
-	int layE, resE, compE, prcE;
-	/** Start and end values of Tile width and height, initialised in pi_initialise_encode*/
-	int txS,txE,tyS,tyE,dx,dy;
-	/** Temporary values for Tile parts, initialised in pi_create_encode */
-	int lay_t, res_t, comp_t, prc_t,tx0_t,ty0_t;
-} opj_poc_t;
-
-/**
-Compression parameters
-*/
-typedef struct opj_cparameters {
-	/** size of tile: tile_size_on = false (not in argument) or = true (in argument) */
-	opj_bool tile_size_on;
-	/** XTOsiz */
-	int cp_tx0;
-	/** YTOsiz */
-	int cp_ty0;
-	/** XTsiz */
-	int cp_tdx;
-	/** YTsiz */
-	int cp_tdy;
-	/** allocation by rate/distortion */
-	int cp_disto_alloc;
-	/** allocation by fixed layer */
-	int cp_fixed_alloc;
-	/** add fixed_quality */
-	int cp_fixed_quality;
-	/** fixed layer */
-	int *cp_matrice;
-	/** comment for coding */
-	char *cp_comment;
-	/** csty : coding style */
-	int csty;
-	/** progression order (default LRCP) */
-	OPJ_PROG_ORDER prog_order;
-	/** progression order changes */
-	opj_poc_t POC[32];
-	/** number of progression order changes (POC), default to 0 */
-	int numpocs;
-	/** number of layers */
-	int tcp_numlayers;
-	/** rates of layers */
-	float tcp_rates[100];
-	/** different psnr for successive layers */
-	float tcp_distoratio[100];
-	/** number of resolutions */
-	int numresolution;
-	/** initial code block width, default to 64 */
- 	int cblockw_init;
-	/** initial code block height, default to 64 */
-	int cblockh_init;
-	/** mode switch (cblk_style) */
-	int mode;
-	/** 1 : use the irreversible DWT 9-7, 0 : use lossless compression (default) */
-	int irreversible;
-	/** region of interest: affected component in [0..3], -1 means no ROI */
-	int roi_compno;
-	/** region of interest: upshift value */
-	int roi_shift;
-	/* number of precinct size specifications */
-	int res_spec;
-	/** initial precinct width */
-	int prcw_init[J2K_MAXRLVLS];
-	/** initial precinct height */
-	int prch_init[J2K_MAXRLVLS];
-
-	/**@name command line encoder parameters (not used inside the library) */
-	/*@{*/
-	/** input file name */
-	char infile[OPJ_PATH_LEN];
-	/** output file name */
-	char outfile[OPJ_PATH_LEN];
-	/** DEPRECATED. Index generation is now handeld with the opj_encode_with_info() function. Set to NULL */
-	int index_on;
-	/** DEPRECATED. Index generation is now handeld with the opj_encode_with_info() function. Set to NULL */
-	char index[OPJ_PATH_LEN];
-	/** subimage encoding: origin image offset in x direction */
-	int image_offset_x0;
-	/** subimage encoding: origin image offset in y direction */
-	int image_offset_y0;
-	/** subsampling value for dx */
-	int subsampling_dx;
-	/** subsampling value for dy */
-	int subsampling_dy;
-	/** input file format 0: PGX, 1: PxM, 2: BMP 3:TIF*/
-	int decod_format;
-	/** output file format 0: J2K, 1: JP2, 2: JPT */
-	int cod_format;
-	/*@}*/
-
-/* UniPG>> */
-	/**@name JPWL encoding parameters */
-	/*@{*/
-	/** enables writing of EPC in MH, thus activating JPWL */
-	opj_bool jpwl_epc_on;
-	/** error protection method for MH (0,1,16,32,37-128) */
-	int jpwl_hprot_MH;
-	/** tile number of header protection specification (>=0) */
-	int jpwl_hprot_TPH_tileno[JPWL_MAX_NO_TILESPECS];
-	/** error protection methods for TPHs (0,1,16,32,37-128) */
-	int jpwl_hprot_TPH[JPWL_MAX_NO_TILESPECS];
-	/** tile number of packet protection specification (>=0) */
-	int jpwl_pprot_tileno[JPWL_MAX_NO_PACKSPECS];
-	/** packet number of packet protection specification (>=0) */
-	int jpwl_pprot_packno[JPWL_MAX_NO_PACKSPECS];
-	/** error protection methods for packets (0,1,16,32,37-128) */
-	int jpwl_pprot[JPWL_MAX_NO_PACKSPECS];
-	/** enables writing of ESD, (0=no/1/2 bytes) */
-	int jpwl_sens_size;
-	/** sensitivity addressing size (0=auto/2/4 bytes) */
-	int jpwl_sens_addr;
-	/** sensitivity range (0-3) */
-	int jpwl_sens_range;
-	/** sensitivity method for MH (-1=no,0-7) */
-	int jpwl_sens_MH;
-	/** tile number of sensitivity specification (>=0) */
-	int jpwl_sens_TPH_tileno[JPWL_MAX_NO_TILESPECS];
-	/** sensitivity methods for TPHs (-1=no,0-7) */
-	int jpwl_sens_TPH[JPWL_MAX_NO_TILESPECS];
-	/*@}*/
-/* <<UniPG */
-
-	/** Digital Cinema compliance 0-not compliant, 1-compliant*/
-	OPJ_CINEMA_MODE cp_cinema;
-	/** Maximum rate for each component. If == 0, component size limitation is not considered */
-	int max_comp_size;
-	/** Profile name*/
-	OPJ_RSIZ_CAPABILITIES cp_rsiz;
-	/** Tile part generation*/
-	char tp_on;
-	/** Flag for Tile part generation*/
-	char tp_flag;
-	/** MCT (multiple component transform) */
-	char tcp_mct;
-	/** Enable JPIP indexing*/
-	opj_bool jpip_on;
-} opj_cparameters_t;
-
-#define OPJ_DPARAMETERS_IGNORE_PCLR_CMAP_CDEF_FLAG	0x0001
-
-/**
-Decompression parameters
-*/
-typedef struct opj_dparameters {
-	/** 
-	Set the number of highest resolution levels to be discarded. 
-	The image resolution is effectively divided by 2 to the power of the number of discarded levels. 
-	The reduce factor is limited by the smallest total number of decomposition levels among tiles.
-	if != 0, then original dimension divided by 2^(reduce); 
-	if == 0 or not used, image is decoded to the full resolution 
-	*/
-	int cp_reduce;
-	/** 
-	Set the maximum number of quality layers to decode. 
-	If there are less quality layers than the specified number, all the quality layers are decoded.
-	if != 0, then only the first "layer" layers are decoded; 
-	if == 0 or not used, all the quality layers are decoded 
-	*/
-	int cp_layer;
-
-	/**@name command line encoder parameters (not used inside the library) */
-	/*@{*/
-	/** input file name */
-	char infile[OPJ_PATH_LEN];
-	/** output file name */
-	char outfile[OPJ_PATH_LEN];
-	/** input file format 0: J2K, 1: JP2, 2: JPT */
-	int decod_format;
-	/** output file format 0: PGX, 1: PxM, 2: BMP */
-	int cod_format;
-	/*@}*/
-
-/* UniPG>> */
-	/**@name JPWL decoding parameters */
-	/*@{*/
-	/** activates the JPWL correction capabilities */
-	opj_bool jpwl_correct;
-	/** expected number of components */
-	int jpwl_exp_comps;
-	/** maximum number of tiles */
-	int jpwl_max_tiles;
-	/*@}*/
-/* <<UniPG */
-
-	/** 
-	Specify whether the decoding should be done on the entire codestream, or be limited to the main header
-	Limiting the decoding to the main header makes it possible to extract the characteristics of the codestream
-	if == NO_LIMITATION, the entire codestream is decoded; 
-	if == LIMIT_TO_MAIN_HEADER, only the main header is decoded; 
-	*/
-	OPJ_LIMIT_DECODING cp_limit_decoding;
-
-	unsigned int flags;
-} opj_dparameters_t;
-
-/** Common fields between JPEG-2000 compression and decompression master structs. */
-
-#define opj_common_fields \
-	opj_event_mgr_t *event_mgr;	/**< pointer to the event manager */\
-	void * client_data;			/**< Available for use by application */\
-	opj_bool is_decompressor;	/**< So common code can tell which is which */\
-	OPJ_CODEC_FORMAT codec_format;	/**< selected codec */\
-	void *j2k_handle;			/**< pointer to the J2K codec */\
-	void *jp2_handle;			/**< pointer to the JP2 codec */\
-	void *mj2_handle			/**< pointer to the MJ2 codec */
-	
-/* Routines that are to be used by both halves of the library are declared
- * to receive a pointer to this structure.  There are no actual instances of
- * opj_common_struct_t, only of opj_cinfo_t and opj_dinfo_t.
- */
-typedef struct opj_common_struct {
-  opj_common_fields;		/* Fields common to both master struct types */
-  /* Additional fields follow in an actual opj_cinfo_t or
-   * opj_dinfo_t.  All three structs must agree on these
-   * initial fields!  (This would be a lot cleaner in C++.)
-   */
-} opj_common_struct_t;
-
-typedef opj_common_struct_t * opj_common_ptr;
-
-/**
-Compression context info
-*/
-typedef struct opj_cinfo {
-	/** Fields shared with opj_dinfo_t */
-	opj_common_fields;	
-	/* other specific fields go here */
-} opj_cinfo_t;
-
-/**
-Decompression context info
-*/
-typedef struct opj_dinfo {
-	/** Fields shared with opj_cinfo_t */
-	opj_common_fields;	
-	/* other specific fields go here */
-} opj_dinfo_t;
-
-/* 
-==========================================================
-   I/O stream typedef definitions
-==========================================================
-*/
-
-/*
- * Stream open flags.
- */
-/** The stream was opened for reading. */
-#define OPJ_STREAM_READ	0x0001
-/** The stream was opened for writing. */
-#define OPJ_STREAM_WRITE 0x0002
-
-/**
-Byte input-output stream (CIO)
-*/
-typedef struct opj_cio {
-	/** codec context */
-	opj_common_ptr cinfo;
-
-	/** open mode (read/write) either OPJ_STREAM_READ or OPJ_STREAM_WRITE */
-	int openmode;
-	/** pointer to the start of the buffer */
-	unsigned char *buffer;
-	/** buffer size in bytes */
-	int length;
-
-	/** pointer to the start of the stream */
-	unsigned char *start;
-	/** pointer to the end of the stream */
-	unsigned char *end;
-	/** pointer to the current position */
-	unsigned char *bp;
-} opj_cio_t;
-
-/* 
-==========================================================
-   image typedef definitions
-==========================================================
-*/
-
-/**
-Defines a single image component
-*/
-typedef struct opj_image_comp {
-	/** XRsiz: horizontal separation of a sample of ith component with respect to the reference grid */
-	int dx;
-	/** YRsiz: vertical separation of a sample of ith component with respect to the reference grid */
-	int dy;
-	/** data width */
-	int w;
-	/** data height */
-	int h;
-	/** x component offset compared to the whole image */
-	int x0;
-	/** y component offset compared to the whole image */
-	int y0;
-	/** precision */
-	int prec;
-	/** image depth in bits */
-	int bpp;
-	/** signed (1) / unsigned (0) */
-	int sgnd;
-	/** number of decoded resolution */
-	int resno_decoded;
-	/** number of division by 2 of the out image compared to the original size of image */
-	int factor;
-	/** image component data */
-	int *data;
-} opj_image_comp_t;
-
-/** 
-Defines image data and characteristics
-*/
-typedef struct opj_image {
-	/** XOsiz: horizontal offset from the origin of the reference grid to the left side of the image area */
-	int x0;
-	/** YOsiz: vertical offset from the origin of the reference grid to the top side of the image area */
-	int y0;
-	/** Xsiz: width of the reference grid */
-	int x1;
-	/** Ysiz: height of the reference grid */
-	int y1;
-	/** number of components in the image */
-	int numcomps;
-	/** color space: sRGB, Greyscale or YUV */
-	OPJ_COLOR_SPACE color_space;
-	/** image components */
-	opj_image_comp_t *comps;
-	/** 'restricted' ICC profile */
-	unsigned char *icc_profile_buf;
-	/** size of ICC profile */
-	int icc_profile_len;
-} opj_image_t;
-
-/**
-Component parameters structure used by the opj_image_create function
-*/
-typedef struct opj_image_comptparm {
-	/** XRsiz: horizontal separation of a sample of ith component with respect to the reference grid */
-	int dx;
-	/** YRsiz: vertical separation of a sample of ith component with respect to the reference grid */
-	int dy;
-	/** data width */
-	int w;
-	/** data height */
-	int h;
-	/** x component offset compared to the whole image */
-	int x0;
-	/** y component offset compared to the whole image */
-	int y0;
-	/** precision */
-	int prec;
-	/** image depth in bits */
-	int bpp;
-	/** signed (1) / unsigned (0) */
-	int sgnd;
-} opj_image_cmptparm_t;
-
-/* 
-==========================================================
-   Information on the JPEG 2000 codestream
-==========================================================
-*/
-
-/**
-Index structure : Information concerning a packet inside tile
-*/
-typedef struct opj_packet_info {
-	/** packet start position (including SOP marker if it exists) */
-	int start_pos;
-	/** end of packet header position (including EPH marker if it exists)*/
-	int end_ph_pos;
-	/** packet end position */
-	int end_pos;
-	/** packet distorsion */
-	double disto;
-} opj_packet_info_t;
-
-
-/* UniPG>> */
-/**
-Marker structure
-*/
-typedef struct opj_marker_info_t {
-	/** marker type */
-	unsigned short int type;
-	/** position in codestream */
-	int pos;
-	/** length, marker val included */
-	int len;
-} opj_marker_info_t;
-/* <<UniPG */
-
-/**
-Index structure : Information concerning tile-parts
-*/
-typedef struct opj_tp_info {
-	/** start position of tile part */
-	int tp_start_pos;
-	/** end position of tile part header */
-	int tp_end_header;
-	/** end position of tile part */
-	int tp_end_pos;
-	/** start packet of tile part */
-	int tp_start_pack;
-	/** number of packets of tile part */
-	int tp_numpacks;
-} opj_tp_info_t;
-
-/**
-Index structure : information regarding tiles 
-*/
-typedef struct opj_tile_info {
-	/** value of thresh for each layer by tile cfr. Marcela   */
-	double *thresh;
-	/** number of tile */
-	int tileno;
-	/** start position */
-	int start_pos;
-	/** end position of the header */
-	int end_header;
-	/** end position */
-	int end_pos;
-	/** precinct number for each resolution level (width) */
-	int pw[33];
-	/** precinct number for each resolution level (height) */
-	int ph[33];
-	/** precinct size (in power of 2), in X for each resolution level */
-	int pdx[33];
-	/** precinct size (in power of 2), in Y for each resolution level */
-	int pdy[33];
-	/** information concerning packets inside tile */
-	opj_packet_info_t *packet;
-	/** add fixed_quality */
-	int numpix;
-	/** add fixed_quality */
-	double distotile;
-  	/** number of markers */
-	int marknum;
-	/** list of markers */
-	opj_marker_info_t *marker;
-	/** actual size of markers array */
-	int maxmarknum;
-	/** number of tile parts */
-	int num_tps;
-	/** information concerning tile parts */
-	opj_tp_info_t *tp;
-} opj_tile_info_t;
-
-/**
-Index structure of the codestream
-*/
-typedef struct opj_codestream_info {
-	/** maximum distortion reduction on the whole image (add for Marcela) */
-	double D_max;
-	/** packet number */
-	int packno;
-	/** writing the packet in the index with t2_encode_packets */
-	int index_write;
-	/** image width */
-	int image_w;
-	/** image height */
-	int image_h;
-	/** progression order */
-	OPJ_PROG_ORDER prog;
-	/** tile size in x */
-	int tile_x;
-	/** tile size in y */
-	int tile_y;
-	/** */
-	int tile_Ox;
-	/** */
-	int tile_Oy;
-	/** number of tiles in X */
-	int tw;
-	/** number of tiles in Y */
-	int th;
-	/** component numbers */
-	int numcomps;
-	/** number of layer */
-	int numlayers;
-	/** number of decomposition for each component */
-	int *numdecompos;
-/* UniPG>> */
-	/** number of markers */
-	int marknum;
-	/** list of markers */
-	opj_marker_info_t *marker;
-	/** actual size of markers array */
-	int maxmarknum;
-/* <<UniPG */
-	/** main header position */
-	int main_head_start;
-	/** main header position */
-	int main_head_end;
-	/** codestream's size */
-	int codestream_size;
-	/** information regarding tiles inside image */
-	opj_tile_info_t *tile;
-} opj_codestream_info_t;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/* 
-==========================================================
-   openjpeg version
-==========================================================
-*/
-
-OPJ_API const char * OPJ_CALLCONV opj_version(void);
-
-/* 
-==========================================================
-   image functions definitions
-==========================================================
-*/
-
-/**
-Create an image
- at param numcmpts number of components
- at param cmptparms components parameters
- at param clrspc image color space
- at return returns a new image structure if successful, returns NULL otherwise
-*/
-OPJ_API opj_image_t* OPJ_CALLCONV opj_image_create(int numcmpts, opj_image_cmptparm_t *cmptparms, OPJ_COLOR_SPACE clrspc);
-
-/**
-Deallocate any resources associated with an image
- at param image image to be destroyed
-*/
-OPJ_API void OPJ_CALLCONV opj_image_destroy(opj_image_t *image);
-
-/* 
-==========================================================
-   stream functions definitions
-==========================================================
-*/
-
-/**
-Open and allocate a memory stream for read / write. 
-On reading, the user must provide a buffer containing encoded data. The buffer will be 
-wrapped by the returned CIO handle. 
-On writing, buffer parameters must be set to 0: a buffer will be allocated by the library 
-to contain encoded data. 
- at param cinfo Codec context info
- at param buffer Reading: buffer address. Writing: NULL
- at param length Reading: buffer length. Writing: 0
- at return Returns a CIO handle if successful, returns NULL otherwise
-*/
-OPJ_API opj_cio_t* OPJ_CALLCONV opj_cio_open(opj_common_ptr cinfo, unsigned char *buffer, int length);
-
-/**
-Close and free a CIO handle
- at param cio CIO handle to free
-*/
-OPJ_API void OPJ_CALLCONV opj_cio_close(opj_cio_t *cio);
-
-/**
-Get position in byte stream
- at param cio CIO handle
- at return Returns the position in bytes
-*/
-OPJ_API int OPJ_CALLCONV cio_tell(opj_cio_t *cio);
-/**
-Set position in byte stream
- at param cio CIO handle
- at param pos Position, in number of bytes, from the beginning of the stream
-*/
-OPJ_API void OPJ_CALLCONV cio_seek(opj_cio_t *cio, int pos);
-
-/* 
-==========================================================
-   event manager functions definitions
-==========================================================
-*/
-
-OPJ_API opj_event_mgr_t* OPJ_CALLCONV opj_set_event_mgr(opj_common_ptr cinfo, opj_event_mgr_t *event_mgr, void *context);
-
-/* 
-==========================================================
-   codec functions definitions
-==========================================================
-*/
-/**
-Creates a J2K/JPT/JP2 decompression structure
- at param format Decoder to select
- at return Returns a handle to a decompressor if successful, returns NULL otherwise
-*/
-OPJ_API opj_dinfo_t* OPJ_CALLCONV opj_create_decompress(OPJ_CODEC_FORMAT format);
-/**
-Destroy a decompressor handle
- at param dinfo decompressor handle to destroy
-*/
-OPJ_API void OPJ_CALLCONV opj_destroy_decompress(opj_dinfo_t *dinfo);
-/**
-Set decoding parameters to default values
- at param parameters Decompression parameters
-*/
-OPJ_API void OPJ_CALLCONV opj_set_default_decoder_parameters(opj_dparameters_t *parameters);
-/**
-Setup the decoder decoding parameters using user parameters.
-Decoding parameters are returned in j2k->cp. 
- at param dinfo decompressor handle
- at param parameters decompression parameters
-*/
-OPJ_API void OPJ_CALLCONV opj_setup_decoder(opj_dinfo_t *dinfo, opj_dparameters_t *parameters);
-/**
-Decode an image from a JPEG-2000 codestream 
- at param dinfo decompressor handle
- at param cio Input buffer stream
- at return Returns a decoded image if successful, returns NULL otherwise
-*/
-OPJ_API opj_image_t* OPJ_CALLCONV opj_decode(opj_dinfo_t *dinfo, opj_cio_t *cio);
-
-/**
-Decode an image from a JPEG-2000 codestream and extract the codestream information
- at param dinfo decompressor handle
- at param cio Input buffer stream
- at param cstr_info Codestream information structure if needed afterwards, NULL otherwise
- at return Returns a decoded image if successful, returns NULL otherwise
-*/
-OPJ_API opj_image_t* OPJ_CALLCONV opj_decode_with_info(opj_dinfo_t *dinfo, opj_cio_t *cio, opj_codestream_info_t *cstr_info);
-/**
-Creates a J2K/JP2 compression structure
- at param format Coder to select
- at return Returns a handle to a compressor if successful, returns NULL otherwise
-*/
-OPJ_API opj_cinfo_t* OPJ_CALLCONV opj_create_compress(OPJ_CODEC_FORMAT format);
-/**
-Destroy a compressor handle
- at param cinfo compressor handle to destroy
-*/
-OPJ_API void OPJ_CALLCONV opj_destroy_compress(opj_cinfo_t *cinfo);
-/**
-Set encoding parameters to default values, that means : 
-<ul>
-<li>Lossless
-<li>1 tile
-<li>Size of precinct : 2^15 x 2^15 (means 1 precinct)
-<li>Size of code-block : 64 x 64
-<li>Number of resolutions: 6
-<li>No SOP marker in the codestream
-<li>No EPH marker in the codestream
-<li>No sub-sampling in x or y direction
-<li>No mode switch activated
-<li>Progression order: LRCP
-<li>No index file
-<li>No ROI upshifted
-<li>No offset of the origin of the image
-<li>No offset of the origin of the tiles
-<li>Reversible DWT 5-3
-</ul>
- at param parameters Compression parameters
-*/
-OPJ_API void OPJ_CALLCONV opj_set_default_encoder_parameters(opj_cparameters_t *parameters);
-/**
-Setup the encoder parameters using the current image and using user parameters. 
- at param cinfo Compressor handle
- at param parameters Compression parameters
- at param image Input filled image
-*/
-OPJ_API void OPJ_CALLCONV opj_setup_encoder(opj_cinfo_t *cinfo, opj_cparameters_t *parameters, opj_image_t *image);
-/**
-Encode an image into a JPEG-2000 codestream
-3 at param cinfo compressor handle
- at param cio Output buffer stream
- at param image Image to encode
- at param index Depreacted -> Set to NULL. To extract index, used opj_encode_wci()
- at return Returns true if successful, returns false otherwise
-*/
-OPJ_API opj_bool OPJ_CALLCONV opj_encode(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *image, char *index);
-/**
-Encode an image into a JPEG-2000 codestream and extract the codestream information
- at param cinfo compressor handle
- at param cio Output buffer stream
- at param image Image to encode
- at param cstr_info Codestream information structure if needed afterwards, NULL otherwise
- at return Returns true if successful, returns false otherwise
-*/
-OPJ_API opj_bool OPJ_CALLCONV opj_encode_with_info(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info);
-/**
-Destroy Codestream information after compression or decompression
- at param cstr_info Codestream information structure
-*/
-OPJ_API void OPJ_CALLCONV opj_destroy_cstr_info(opj_codestream_info_t *cstr_info);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* OPENJPEG_H */
+ /*
+ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2007, Professor Benoit Macq
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2006-2007, Parvatha Elangovan
+ * Copyright (c) 2008, Jerome Fimes, Communications & Systemes <jerome.fimes at c-s.fr>
+ * Copyright (c) 2010-2011, Kaori Hagihara
+ * Copyright (c) 2011-2012, Centre National d'Etudes Spatiales (CNES), France 
+ * Copyright (c) 2012, CS Systemes d'Information, France
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef OPENJPEG_H
+#define OPENJPEG_H
+
+
+/* 
+==========================================================
+   Compiler directives
+==========================================================
+*/
+
+/*
+The inline keyword is supported by C99 but not by C90. 
+Most compilers implement their own version of this keyword ... 
+*/
+#ifndef INLINE
+	#if defined(_MSC_VER)
+		#define INLINE __forceinline
+	#elif defined(__GNUC__)
+		#define INLINE __inline__
+	#elif defined(__MWERKS__)
+		#define INLINE inline
+	#else 
+		/* add other compilers here ... */
+		#define INLINE 
+	#endif /* defined(<Compiler>) */
+#endif /* INLINE */
+
+/* deprecated attribute */
+#ifdef __GNUC__
+	#define OPJ_DEPRECATED(func) func __attribute__ ((deprecated))
+#elif defined(_MSC_VER)
+	#define OPJ_DEPRECATED(func) __declspec(deprecated) func
+#else
+	#pragma message("WARNING: You need to implement DEPRECATED for this compiler")
+	#define OPJ_DEPRECATED(func) func
+#endif
+
+#if defined(OPJ_STATIC) || !defined(_WIN32)
+#define OPJ_API
+#define OPJ_LOCAL
+#define OPJ_CALLCONV
+#else
+#define OPJ_CALLCONV __stdcall
+/*
+The following ifdef block is the standard way of creating macros which make exporting 
+from a DLL simpler. All files within this DLL are compiled with the OPJ_EXPORTS
+symbol defined on the command line. this symbol should not be defined on any project
+that uses this DLL. This way any other project whose source files include this file see 
+OPJ_API functions as being imported from a DLL, wheras this DLL sees symbols
+defined with this macro as being exported.
+*/
+#if defined(OPJ_EXPORTS) || defined(DLL_EXPORT)
+#define OPJ_API __declspec(dllexport)
+#else
+#define OPJ_API __declspec(dllimport)
+#endif /* OPJ_EXPORTS */
+#endif /* !OPJ_STATIC || !_WIN32 */
+
+typedef int OPJ_BOOL;
+#define OPJ_TRUE 1
+#define OPJ_FALSE 0
+
+typedef char          OPJ_CHAR;
+typedef float         OPJ_FLOAT32;
+typedef double        OPJ_FLOAT64;
+typedef unsigned char OPJ_BYTE;
+
+#include "opj_stdint.h"
+
+typedef int8_t   OPJ_INT8;
+typedef uint8_t  OPJ_UINT8;
+typedef int16_t  OPJ_INT16;
+typedef uint16_t OPJ_UINT16;
+typedef int32_t  OPJ_INT32;
+typedef uint32_t OPJ_UINT32;
+typedef int64_t  OPJ_INT64;
+typedef uint64_t OPJ_UINT64;
+
+typedef int64_t  OPJ_OFF_T; /* 64-bit file offset type */
+
+#include <stdio.h>
+typedef size_t   OPJ_SIZE_T;
+
+/* Avoid compile-time warning because parameter is not used */
+#define OPJ_ARG_NOT_USED(x) (void)(x)
+
+/* 
+==========================================================
+   Useful constant definitions
+==========================================================
+*/
+
+#define OPJ_PATH_LEN 4096 /**< Maximum allowed size for filenames */
+
+#define OPJ_J2K_MAXRLVLS 33					/**< Number of maximum resolution level authorized */
+#define OPJ_J2K_MAXBANDS (3*OPJ_J2K_MAXRLVLS-2)	/**< Number of maximum sub-band linked to number of resolution level */
+
+#define OPJ_J2K_DEFAULT_NB_SEGS				10
+#define OPJ_J2K_STREAM_CHUNK_SIZE			0x100000 /** 1 mega by default */
+#define OPJ_J2K_DEFAULT_HEADER_SIZE			1000
+#define OPJ_J2K_MCC_DEFAULT_NB_RECORDS		10
+#define OPJ_J2K_MCT_DEFAULT_NB_RECORDS		10
+
+/* UniPG>> */ /* NOT YET USED IN THE V2 VERSION OF OPENJPEG */
+#define JPWL_MAX_NO_TILESPECS	16 /**< Maximum number of tile parts expected by JPWL: increase at your will */
+#define JPWL_MAX_NO_PACKSPECS	16 /**< Maximum number of packet parts expected by JPWL: increase at your will */
+#define JPWL_MAX_NO_MARKERS	512 /**< Maximum number of JPWL markers: increase at your will */
+#define JPWL_PRIVATEINDEX_NAME "jpwl_index_privatefilename" /**< index file name used when JPWL is on */
+#define JPWL_EXPECTED_COMPONENTS 3 /**< Expect this number of components, so you'll find better the first EPB */
+#define JPWL_MAXIMUM_TILES 8192 /**< Expect this maximum number of tiles, to avoid some crashes */
+#define JPWL_MAXIMUM_HAMMING 2 /**< Expect this maximum number of bit errors in marker id's */
+#define JPWL_MAXIMUM_EPB_ROOM 65450 /**< Expect this maximum number of bytes for composition of EPBs */
+/* <<UniPG */
+
+/**
+ * EXPERIMENTAL FOR THE MOMENT
+ * Supported options about file information used only in j2k_dump
+*/
+#define OPJ_IMG_INFO		1	/**< Basic image information provided to the user */
+#define OPJ_J2K_MH_INFO		2	/**< Codestream information based only on the main header */
+#define OPJ_J2K_TH_INFO		4	/**< Tile information based on the current tile header */
+#define OPJ_J2K_TCH_INFO	8	/**< Tile/Component information of all tiles */
+#define OPJ_J2K_MH_IND		16	/**< Codestream index based only on the main header */
+#define OPJ_J2K_TH_IND		32	/**< Tile index based on the current tile */
+/*FIXME #define OPJ_J2K_CSTR_IND	48*/	/**<  */
+#define OPJ_JP2_INFO		128	/**< JP2 file information */
+#define OPJ_JP2_IND			256	/**< JP2 file index */
+
+
+/* 
+==========================================================
+   enum definitions
+==========================================================
+*/
+/** 
+ * Rsiz Capabilities
+ * */
+typedef enum RSIZ_CAPABILITIES {
+	OPJ_STD_RSIZ = 0,		/** Standard JPEG2000 profile*/
+	OPJ_CINEMA2K = 3,		/** Profile name for a 2K image*/
+	OPJ_CINEMA4K = 4,		/** Profile name for a 4K image*/
+	OPJ_MCT = 0x8100
+} OPJ_RSIZ_CAPABILITIES;
+
+/** 
+ * Digital cinema operation mode
+ * */
+typedef enum CINEMA_MODE {
+	OPJ_OFF = 0,			/** Not Digital Cinema*/
+	OPJ_CINEMA2K_24 = 1,	/** 2K Digital Cinema at 24 fps*/
+	OPJ_CINEMA2K_48 = 2,	/** 2K Digital Cinema at 48 fps*/
+	OPJ_CINEMA4K_24 = 3		/** 4K Digital Cinema at 24 fps*/
+}OPJ_CINEMA_MODE;
+
+/** 
+ * Progression order
+ * */
+typedef enum PROG_ORDER {
+	OPJ_PROG_UNKNOWN = -1,	/**< place-holder */
+	OPJ_LRCP = 0,			/**< layer-resolution-component-precinct order */
+	OPJ_RLCP = 1,			/**< resolution-layer-component-precinct order */
+	OPJ_RPCL = 2,			/**< resolution-precinct-component-layer order */
+	OPJ_PCRL = 3,			/**< precinct-component-resolution-layer order */
+	OPJ_CPRL = 4			/**< component-precinct-resolution-layer order */
+} OPJ_PROG_ORDER;
+
+/**
+ * Supported image color spaces
+*/
+typedef enum COLOR_SPACE {
+	OPJ_CLRSPC_UNKNOWN = -1,	/**< not supported by the library */
+	OPJ_CLRSPC_UNSPECIFIED = 0,	/**< not specified in the codestream */ 
+	OPJ_CLRSPC_SRGB = 1,		/**< sRGB */
+	OPJ_CLRSPC_GRAY = 2,		/**< grayscale */
+	OPJ_CLRSPC_SYCC = 3,		/**< YUV */
+  OPJ_CLRSPC_EYCC = 4		/**< e-YCC */
+} OPJ_COLOR_SPACE;
+
+/**
+ * Supported codec
+*/
+typedef enum CODEC_FORMAT {
+	OPJ_CODEC_UNKNOWN = -1,	/**< place-holder */
+	OPJ_CODEC_J2K  = 0,		/**< JPEG-2000 codestream : read/write */
+	OPJ_CODEC_JPT  = 1,		/**< JPT-stream (JPEG 2000, JPIP) : read only */
+	OPJ_CODEC_JP2  = 2 		/**< JPEG-2000 file format : read/write */
+} OPJ_CODEC_FORMAT;
+
+
+/* 
+==========================================================
+   event manager typedef definitions
+==========================================================
+*/
+
+/**
+ * Callback function prototype for events
+ * @param msg               Event message
+ * @param client_data       Client object where will be return the event message 
+ * */
+typedef void (*opj_msg_callback) (const char *msg, void *client_data);
+
+/* 
+==========================================================
+   codec typedef definitions
+==========================================================
+*/
+
+/**
+ * Progression order changes
+ * 
+ */
+typedef struct opj_poc {
+	/** Resolution num start, Component num start, given by POC */
+	OPJ_UINT32 resno0, compno0;
+	/** Layer num end,Resolution num end, Component num end, given by POC */
+	OPJ_UINT32 layno1, resno1, compno1;
+	/** Layer num start,Precinct num start, Precinct num end */
+	OPJ_UINT32 layno0, precno0, precno1;
+	/** Progression order enum*/
+	OPJ_PROG_ORDER prg1,prg;
+	/** Progression order string*/
+	OPJ_CHAR progorder[5];
+	/** Tile number */
+	OPJ_UINT32 tile;
+	/** Start and end values for Tile width and height*/
+	OPJ_INT32 tx0,tx1,ty0,ty1;
+	/** Start value, initialised in pi_initialise_encode*/
+	OPJ_UINT32 layS, resS, compS, prcS;
+	/** End value, initialised in pi_initialise_encode */
+	OPJ_UINT32 layE, resE, compE, prcE;
+	/** Start and end values of Tile width and height, initialised in pi_initialise_encode*/
+	OPJ_UINT32 txS,txE,tyS,tyE,dx,dy;
+	/** Temporary values for Tile parts, initialised in pi_create_encode */
+	OPJ_UINT32 lay_t, res_t, comp_t, prc_t,tx0_t,ty0_t;
+} opj_poc_t;
+
+/**
+ * Compression parameters
+ * */
+typedef struct opj_cparameters {
+	/** size of tile: tile_size_on = false (not in argument) or = true (in argument) */
+	OPJ_BOOL tile_size_on;
+	/** XTOsiz */
+	int cp_tx0;
+	/** YTOsiz */
+	int cp_ty0;
+	/** XTsiz */
+	int cp_tdx;
+	/** YTsiz */
+	int cp_tdy;
+	/** allocation by rate/distortion */
+	int cp_disto_alloc;
+	/** allocation by fixed layer */
+	int cp_fixed_alloc;
+	/** add fixed_quality */
+	int cp_fixed_quality;
+	/** fixed layer */
+	int *cp_matrice;
+	/** comment for coding */
+	char *cp_comment;
+	/** csty : coding style */
+	int csty;
+	/** progression order (default OPJ_LRCP) */
+	OPJ_PROG_ORDER prog_order;
+	/** progression order changes */
+	opj_poc_t POC[32];
+	/** number of progression order changes (POC), default to 0 */
+	OPJ_UINT32 numpocs;
+	/** number of layers */
+	int tcp_numlayers;
+	/** rates of layers */
+	float tcp_rates[100];
+	/** different psnr for successive layers */
+	float tcp_distoratio[100];
+	/** number of resolutions */
+	int numresolution;
+	/** initial code block width, default to 64 */
+ 	int cblockw_init;
+	/** initial code block height, default to 64 */
+	int cblockh_init;
+	/** mode switch (cblk_style) */
+	int mode;
+	/** 1 : use the irreversible DWT 9-7, 0 : use lossless compression (default) */
+	int irreversible;
+	/** region of interest: affected component in [0..3], -1 means no ROI */
+	int roi_compno;
+	/** region of interest: upshift value */
+	int roi_shift;
+	/* number of precinct size specifications */
+	int res_spec;
+	/** initial precinct width */
+	int prcw_init[OPJ_J2K_MAXRLVLS];
+	/** initial precinct height */
+	int prch_init[OPJ_J2K_MAXRLVLS];
+
+	/**@name command line encoder parameters (not used inside the library) */
+	/*@{*/
+	/** input file name */
+	char infile[OPJ_PATH_LEN];
+	/** output file name */
+	char outfile[OPJ_PATH_LEN];
+	/** DEPRECATED. Index generation is now handeld with the opj_encode_with_info() function. Set to NULL */
+	int index_on;
+	/** DEPRECATED. Index generation is now handeld with the opj_encode_with_info() function. Set to NULL */
+	char index[OPJ_PATH_LEN];
+	/** subimage encoding: origin image offset in x direction */
+	int image_offset_x0;
+	/** subimage encoding: origin image offset in y direction */
+	int image_offset_y0;
+	/** subsampling value for dx */
+	int subsampling_dx;
+	/** subsampling value for dy */
+	int subsampling_dy;
+	/** input file format 0: PGX, 1: PxM, 2: BMP 3:TIF*/
+	int decod_format;
+	/** output file format 0: J2K, 1: JP2, 2: JPT */
+	int cod_format;
+	/*@}*/
+
+/* UniPG>> */ /* NOT YET USED IN THE V2 VERSION OF OPENJPEG */
+	/**@name JPWL encoding parameters */
+	/*@{*/
+	/** enables writing of EPC in MH, thus activating JPWL */
+	OPJ_BOOL jpwl_epc_on;
+	/** error protection method for MH (0,1,16,32,37-128) */
+	int jpwl_hprot_MH;
+	/** tile number of header protection specification (>=0) */
+	int jpwl_hprot_TPH_tileno[JPWL_MAX_NO_TILESPECS];
+	/** error protection methods for TPHs (0,1,16,32,37-128) */
+	int jpwl_hprot_TPH[JPWL_MAX_NO_TILESPECS];
+	/** tile number of packet protection specification (>=0) */
+	int jpwl_pprot_tileno[JPWL_MAX_NO_PACKSPECS];
+	/** packet number of packet protection specification (>=0) */
+	int jpwl_pprot_packno[JPWL_MAX_NO_PACKSPECS];
+	/** error protection methods for packets (0,1,16,32,37-128) */
+	int jpwl_pprot[JPWL_MAX_NO_PACKSPECS];
+	/** enables writing of ESD, (0=no/1/2 bytes) */
+	int jpwl_sens_size;
+	/** sensitivity addressing size (0=auto/2/4 bytes) */
+	int jpwl_sens_addr;
+	/** sensitivity range (0-3) */
+	int jpwl_sens_range;
+	/** sensitivity method for MH (-1=no,0-7) */
+	int jpwl_sens_MH;
+	/** tile number of sensitivity specification (>=0) */
+	int jpwl_sens_TPH_tileno[JPWL_MAX_NO_TILESPECS];
+	/** sensitivity methods for TPHs (-1=no,0-7) */
+	int jpwl_sens_TPH[JPWL_MAX_NO_TILESPECS];
+	/*@}*/
+/* <<UniPG */
+
+	/** Digital Cinema compliance 0-not compliant, 1-compliant*/
+	OPJ_CINEMA_MODE cp_cinema;
+	/** Maximum rate for each component. If == 0, component size limitation is not considered */
+	int max_comp_size;
+	/** Profile name*/
+	OPJ_RSIZ_CAPABILITIES cp_rsiz;
+	/** Tile part generation*/
+	char tp_on;
+	/** Flag for Tile part generation*/
+	char tp_flag;
+	/** MCT (multiple component transform) */
+	char tcp_mct;
+	/** Enable JPIP indexing*/
+	OPJ_BOOL jpip_on;
+	/** Naive implementation of MCT restricted to a single reversible array based 
+        encoding without offset concerning all the components. */
+	void * mct_data;
+} opj_cparameters_t;  
+
+#define OPJ_DPARAMETERS_IGNORE_PCLR_CMAP_CDEF_FLAG	0x0001
+
+/**
+ * Decompression parameters
+ * */
+typedef struct opj_dparameters {
+	/** 
+	Set the number of highest resolution levels to be discarded. 
+	The image resolution is effectively divided by 2 to the power of the number of discarded levels. 
+	The reduce factor is limited by the smallest total number of decomposition levels among tiles.
+	if != 0, then original dimension divided by 2^(reduce); 
+	if == 0 or not used, image is decoded to the full resolution 
+	*/
+	OPJ_UINT32 cp_reduce;
+	/** 
+	Set the maximum number of quality layers to decode. 
+	If there are less quality layers than the specified number, all the quality layers are decoded.
+	if != 0, then only the first "layer" layers are decoded; 
+	if == 0 or not used, all the quality layers are decoded 
+	*/
+	OPJ_UINT32 cp_layer;
+
+	/**@name command line decoder parameters (not used inside the library) */
+	/*@{*/
+	/** input file name */
+	char infile[OPJ_PATH_LEN];
+	/** output file name */
+	char outfile[OPJ_PATH_LEN];
+	/** input file format 0: J2K, 1: JP2, 2: JPT */
+	int decod_format;
+	/** output file format 0: PGX, 1: PxM, 2: BMP */
+	int cod_format;
+
+	/** Decoding area left boundary */
+	OPJ_UINT32 DA_x0;
+	/** Decoding area right boundary */
+	OPJ_UINT32 DA_x1;
+	/** Decoding area up boundary */
+	OPJ_UINT32 DA_y0;
+	/** Decoding area bottom boundary */
+	OPJ_UINT32 DA_y1;
+	/** Verbose mode */
+	OPJ_BOOL m_verbose;
+
+	/** tile number ot the decoded tile*/
+	OPJ_UINT32 tile_index;
+	/** Nb of tile to decode */
+	OPJ_UINT32 nb_tile_to_decode;
+
+	/*@}*/
+
+/* UniPG>> */ /* NOT YET USED IN THE V2 VERSION OF OPENJPEG */
+	/**@name JPWL decoding parameters */
+	/*@{*/
+	/** activates the JPWL correction capabilities */
+	OPJ_BOOL jpwl_correct;
+	/** expected number of components */
+	int jpwl_exp_comps;
+	/** maximum number of tiles */
+	int jpwl_max_tiles;
+	/*@}*/
+/* <<UniPG */
+
+	unsigned int flags;
+
+} opj_dparameters_t;
+
+
+/**
+ * JPEG2000 codec V2.
+ * */
+typedef void * opj_codec_t;
+
+/* 
+==========================================================
+   I/O stream typedef definitions
+==========================================================
+*/
+
+/**
+ * Stream open flags.
+ * */
+/** The stream was opened for reading. */
+#define OPJ_STREAM_READ	OPJ_TRUE
+/** The stream was opened for writing. */
+#define OPJ_STREAM_WRITE OPJ_FALSE
+
+/*
+ * Callback function prototype for read function
+ */
+typedef OPJ_SIZE_T (* opj_stream_read_fn) (void * p_buffer, OPJ_SIZE_T p_nb_bytes, void * p_user_data) ;
+
+/*
+ * Callback function prototype for write function
+ */
+typedef OPJ_SIZE_T (* opj_stream_write_fn) (void * p_buffer, OPJ_SIZE_T p_nb_bytes, void * p_user_data) ;
+
+/*
+ * Callback function prototype for skip function
+ */
+typedef OPJ_OFF_T (* opj_stream_skip_fn) (OPJ_OFF_T p_nb_bytes, void * p_user_data) ;
+
+/*
+ * Callback function prototype for seek function
+ */
+typedef OPJ_BOOL (* opj_stream_seek_fn) (OPJ_OFF_T p_nb_bytes, void * p_user_data) ;
+
+/*
+ * Callback function prototype for free user data function
+ */
+typedef void (* opj_stream_free_user_data_fn) (void * p_user_data) ;
+
+/*
+ * JPEG2000 Stream.
+ */
+typedef void * opj_stream_t;
+
+/* 
+==========================================================
+   image typedef definitions
+==========================================================
+*/
+
+/**
+ * Defines a single image component
+ * */
+typedef struct opj_image_comp {
+	/** XRsiz: horizontal separation of a sample of ith component with respect to the reference grid */
+	OPJ_UINT32 dx;
+	/** YRsiz: vertical separation of a sample of ith component with respect to the reference grid */
+	OPJ_UINT32 dy;
+	/** data width */
+	OPJ_UINT32 w;
+	/** data height */
+	OPJ_UINT32 h;
+	/** x component offset compared to the whole image */
+	OPJ_UINT32 x0;
+	/** y component offset compared to the whole image */
+	OPJ_UINT32 y0;
+	/** precision */
+	OPJ_UINT32 prec;
+	/** image depth in bits */
+	OPJ_UINT32 bpp;
+	/** signed (1) / unsigned (0) */
+	OPJ_UINT32 sgnd;
+	/** number of decoded resolution */
+	OPJ_UINT32 resno_decoded;
+	/** number of division by 2 of the out image compared to the original size of image */
+	OPJ_UINT32 factor;
+	/** image component data */
+	OPJ_INT32 *data;
+  /** alpha channel */
+  OPJ_UINT16 alpha;
+} opj_image_comp_t;
+
+/** 
+ * Defines image data and characteristics
+ * */
+typedef struct opj_image {
+	/** XOsiz: horizontal offset from the origin of the reference grid to the left side of the image area */
+	OPJ_UINT32 x0;
+	/** YOsiz: vertical offset from the origin of the reference grid to the top side of the image area */
+	OPJ_UINT32 y0;
+	/** Xsiz: width of the reference grid */
+	OPJ_UINT32 x1;
+	/** Ysiz: height of the reference grid */
+	OPJ_UINT32 y1;
+	/** number of components in the image */
+	OPJ_UINT32 numcomps;
+	/** color space: sRGB, Greyscale or YUV */
+	OPJ_COLOR_SPACE color_space;
+	/** image components */
+	opj_image_comp_t *comps;
+	/** 'restricted' ICC profile */
+	OPJ_BYTE *icc_profile_buf;
+	/** size of ICC profile */
+	OPJ_UINT32 icc_profile_len;
+} opj_image_t;
+
+
+/**
+ * Component parameters structure used by the opj_image_create function
+ * */
+typedef struct opj_image_comptparm {
+	/** XRsiz: horizontal separation of a sample of ith component with respect to the reference grid */
+	OPJ_UINT32 dx;
+	/** YRsiz: vertical separation of a sample of ith component with respect to the reference grid */
+	OPJ_UINT32 dy;
+	/** data width */
+	OPJ_UINT32 w;
+	/** data height */
+	OPJ_UINT32 h;
+	/** x component offset compared to the whole image */
+	OPJ_UINT32 x0;
+	/** y component offset compared to the whole image */
+	OPJ_UINT32 y0;
+	/** precision */
+	OPJ_UINT32 prec;
+	/** image depth in bits */
+	OPJ_UINT32 bpp;
+	/** signed (1) / unsigned (0) */
+	OPJ_UINT32 sgnd;
+} opj_image_cmptparm_t;
+
+
+/* 
+==========================================================
+   Information on the JPEG 2000 codestream
+==========================================================
+*/
+/* QUITE EXPERIMENTAL FOR THE MOMENT */
+
+/**
+ * Index structure : Information concerning a packet inside tile
+ * */
+typedef struct opj_packet_info {
+	/** packet start position (including SOP marker if it exists) */
+	OPJ_OFF_T start_pos;
+	/** end of packet header position (including EPH marker if it exists)*/
+	OPJ_OFF_T end_ph_pos;
+	/** packet end position */
+	OPJ_OFF_T end_pos;
+	/** packet distorsion */
+	double disto;
+} opj_packet_info_t;
+
+
+/* UniPG>> */
+/**
+ * Marker structure
+ * */
+typedef struct opj_marker_info {
+	/** marker type */
+	unsigned short int type;
+	/** position in codestream */
+	OPJ_OFF_T pos;
+	/** length, marker val included */
+	int len;
+} opj_marker_info_t;
+/* <<UniPG */
+
+/**
+ * Index structure : Information concerning tile-parts
+*/
+typedef struct opj_tp_info {
+	/** start position of tile part */
+	int tp_start_pos;
+	/** end position of tile part header */
+	int tp_end_header;
+	/** end position of tile part */
+	int tp_end_pos;
+	/** start packet of tile part */
+	int tp_start_pack;
+	/** number of packets of tile part */
+	int tp_numpacks;
+} opj_tp_info_t;
+
+/**
+ * Index structure : information regarding tiles
+*/
+typedef struct opj_tile_info {
+	/** value of thresh for each layer by tile cfr. Marcela   */
+	double *thresh;
+	/** number of tile */
+	int tileno;
+	/** start position */
+	int start_pos;
+	/** end position of the header */
+	int end_header;
+	/** end position */
+	int end_pos;
+	/** precinct number for each resolution level (width) */
+	int pw[33];
+	/** precinct number for each resolution level (height) */
+	int ph[33];
+	/** precinct size (in power of 2), in X for each resolution level */
+	int pdx[33];
+	/** precinct size (in power of 2), in Y for each resolution level */
+	int pdy[33];
+	/** information concerning packets inside tile */
+	opj_packet_info_t *packet;
+	/** add fixed_quality */
+	int numpix;
+	/** add fixed_quality */
+	double distotile;
+  	/** number of markers */
+	int marknum;
+	/** list of markers */
+	opj_marker_info_t *marker;
+	/** actual size of markers array */
+	int maxmarknum;
+	/** number of tile parts */
+	int num_tps;
+	/** information concerning tile parts */
+	opj_tp_info_t *tp;
+} opj_tile_info_t;
+
+/**
+ * Index structure of the codestream
+*/
+typedef struct opj_codestream_info {
+	/** maximum distortion reduction on the whole image (add for Marcela) */
+	double D_max;
+	/** packet number */
+	int packno;
+	/** writing the packet in the index with t2_encode_packets */
+	int index_write;
+	/** image width */
+	int image_w;
+	/** image height */
+	int image_h;
+	/** progression order */
+	OPJ_PROG_ORDER prog;
+	/** tile size in x */
+	int tile_x;
+	/** tile size in y */
+	int tile_y;
+	/** */
+	int tile_Ox;
+	/** */
+	int tile_Oy;
+	/** number of tiles in X */
+	int tw;
+	/** number of tiles in Y */
+	int th;
+	/** component numbers */
+	int numcomps;
+	/** number of layer */
+	int numlayers;
+	/** number of decomposition for each component */
+	int *numdecompos;
+/* UniPG>> */
+	/** number of markers */
+	int marknum;
+	/** list of markers */
+	opj_marker_info_t *marker;
+	/** actual size of markers array */
+	int maxmarknum;
+/* <<UniPG */
+	/** main header position */
+	int main_head_start;
+	/** main header position */
+	int main_head_end;
+	/** codestream's size */
+	int codestream_size;
+	/** information regarding tiles inside image */
+	opj_tile_info_t *tile;
+} opj_codestream_info_t;
+
+/* <----------------------------------------------------------- */
+/* new output managment of the codestream information and index */
+
+/**
+ * Tile-component coding parameters information
+ */
+typedef struct opj_tccp_info
+{
+	/** component index */
+	OPJ_UINT32 compno;
+	/** coding style */
+	OPJ_UINT32 csty;
+	/** number of resolutions */
+	OPJ_UINT32 numresolutions;
+	/** code-blocks width */
+	OPJ_UINT32 cblkw;
+	/** code-blocks height */
+	OPJ_UINT32 cblkh;
+	/** code-block coding style */
+	OPJ_UINT32 cblksty;
+	/** discrete wavelet transform identifier */
+	OPJ_UINT32 qmfbid;
+	/** quantisation style */
+	OPJ_UINT32 qntsty;
+	/** stepsizes used for quantization */
+	OPJ_UINT32 stepsizes_mant[OPJ_J2K_MAXBANDS];
+	/** stepsizes used for quantization */
+	OPJ_UINT32 stepsizes_expn[OPJ_J2K_MAXBANDS];
+	/** number of guard bits */
+	OPJ_UINT32 numgbits;
+	/** Region Of Interest shift */
+	OPJ_INT32 roishift;
+	/** precinct width */
+	OPJ_UINT32 prcw[OPJ_J2K_MAXRLVLS];
+	/** precinct height */
+	OPJ_UINT32 prch[OPJ_J2K_MAXRLVLS];
+}
+opj_tccp_info_t;
+
+/**
+ * Tile coding parameters information
+ */
+typedef struct opj_tile_v2_info {
+
+	/** number (index) of tile */
+	int tileno;
+	/** coding style */
+	OPJ_UINT32 csty;
+	/** progression order */
+	OPJ_PROG_ORDER prg;
+	/** number of layers */
+	OPJ_UINT32 numlayers;
+	/** multi-component transform identifier */
+	OPJ_UINT32 mct;
+
+	/** information concerning tile component parameters*/
+	opj_tccp_info_t *tccp_info;
+
+} opj_tile_info_v2_t;
+
+/**
+ * Information structure about the codestream (FIXME should be expand and enhance)
+ */
+typedef struct opj_codestream_info_v2 {
+	/* Tile info */
+	/** tile origin in x = XTOsiz */
+	OPJ_UINT32 tx0;
+	/** tile origin in y = YTOsiz */
+	OPJ_UINT32 ty0;
+	/** tile size in x = XTsiz */
+	OPJ_UINT32 tdx;
+	/** tile size in y = YTsiz */
+	OPJ_UINT32 tdy;
+	/** number of tiles in X */
+	OPJ_UINT32 tw;
+	/** number of tiles in Y */
+	OPJ_UINT32 th;
+
+	/** number of components*/
+	OPJ_UINT32 nbcomps;
+
+	/** Default information regarding tiles inside image */
+	opj_tile_info_v2_t m_default_tile_info;
+
+	/** information regarding tiles inside image */
+	opj_tile_info_v2_t *tile_info; /* FIXME not used for the moment */
+
+} opj_codestream_info_v2_t;
+
+
+/**
+ * Index structure about a tile part
+ */
+typedef struct opj_tp_index {
+	/** start position */
+	OPJ_OFF_T start_pos;
+	/** end position of the header */
+	OPJ_OFF_T end_header;
+	/** end position */
+	OPJ_OFF_T end_pos;
+
+} opj_tp_index_t;
+
+/**
+ * Index structure about a tile
+ */
+typedef struct opj_tile_index {
+	/** tile index */
+	OPJ_UINT32 tileno;
+
+	/** number of tile parts */
+	OPJ_UINT32 nb_tps;
+	/** current nb of tile part (allocated)*/
+	OPJ_UINT32 current_nb_tps;
+	/** current tile-part index */
+	OPJ_UINT32 current_tpsno;
+	/** information concerning tile parts */
+	opj_tp_index_t *tp_index;
+
+	/* UniPG>> */ /* NOT USED FOR THE MOMENT IN THE V2 VERSION */
+		/** number of markers */
+		OPJ_UINT32 marknum;
+		/** list of markers */
+		opj_marker_info_t *marker;
+		/** actual size of markers array */
+		OPJ_UINT32 maxmarknum;
+	/* <<UniPG */
+
+	/** packet number */
+	OPJ_UINT32 nb_packet;
+	/** information concerning packets inside tile */
+	opj_packet_info_t *packet_index;
+
+} opj_tile_index_t;
+
+/**
+ * Index structure of the codestream (FIXME should be expand and enhance)
+ */
+typedef struct opj_codestream_index {
+	/** main header start position (SOC position) */
+	OPJ_OFF_T main_head_start;
+	/** main header end position (first SOT position) */
+	OPJ_OFF_T main_head_end;
+
+	/** codestream's size */
+	OPJ_UINT64 codestream_size;
+
+/* UniPG>> */ /* NOT USED FOR THE MOMENT IN THE V2 VERSION */
+	/** number of markers */
+	OPJ_UINT32 marknum;
+	/** list of markers */
+	opj_marker_info_t *marker;
+	/** actual size of markers array */
+	OPJ_UINT32 maxmarknum;
+/* <<UniPG */
+
+	/** */
+	OPJ_UINT32 nb_of_tiles;
+	/** */
+	opj_tile_index_t *tile_index; /* FIXME not used for the moment */
+
+}opj_codestream_index_t;
+/* -----------------------------------------------------------> */
+
+/*
+==========================================================
+   Metadata from the JP2file
+==========================================================
+*/
+
+/**
+ * Info structure of the JP2 file
+ * EXPERIMENTAL FOR THE MOMENT
+ */
+typedef struct opj_jp2_metadata {
+	/** */
+	OPJ_INT32	not_used;
+
+} opj_jp2_metadata_t;
+
+/**
+ * Index structure of the JP2 file
+ * EXPERIMENTAL FOR THE MOMENT
+ */
+typedef struct opj_jp2_index {
+	/** */
+	OPJ_INT32	not_used;
+
+} opj_jp2_index_t;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* 
+==========================================================
+   openjpeg version
+==========================================================
+*/
+
+/* Get the version of the openjpeg library*/
+OPJ_API const char * OPJ_CALLCONV opj_version(void);
+
+/* 
+==========================================================
+   image functions definitions
+==========================================================
+*/
+
+/**
+ * Create an image
+ *
+ * @param numcmpts      number of components
+ * @param cmptparms     components parameters
+ * @param clrspc        image color space
+ * @return returns      a new image structure if successful, returns NULL otherwise
+ * */
+OPJ_API opj_image_t* OPJ_CALLCONV opj_image_create(OPJ_UINT32 numcmpts, opj_image_cmptparm_t *cmptparms, OPJ_COLOR_SPACE clrspc);
+
+/**
+ * Deallocate any resources associated with an image
+ *
+ * @param image         image to be destroyed
+ */
+OPJ_API void OPJ_CALLCONV opj_image_destroy(opj_image_t *image);
+
+/**
+ * Creates an image without allocating memory for the image (used in the new version of the library).
+ *
+ * @param	numcmpts    the number of components
+ * @param	cmptparms   the components parameters
+ * @param	clrspc      the image color space
+ *
+ * @return	a new image structure if successful, NULL otherwise.
+*/
+OPJ_API opj_image_t* OPJ_CALLCONV opj_image_tile_create(OPJ_UINT32 numcmpts, opj_image_cmptparm_t *cmptparms, OPJ_COLOR_SPACE clrspc);
+
+/* 
+==========================================================
+   stream functions definitions
+==========================================================
+*/
+
+/**
+ * Creates an abstract stream. This function does nothing except allocating memory and initializing the abstract stream.
+ *
+ * @param	p_is_input		if set to true then the stream will be an input stream, an output stream else.
+ *
+ * @return	a stream object.
+*/
+OPJ_API opj_stream_t* OPJ_CALLCONV opj_stream_default_create(OPJ_BOOL p_is_input);
+
+/**
+ * Creates an abstract stream. This function does nothing except allocating memory and initializing the abstract stream.
+ *
+ * @param	p_buffer_size  FIXME DOC
+ * @param	p_is_input		if set to true then the stream will be an input stream, an output stream else.
+ *
+ * @return	a stream object.
+*/
+OPJ_API opj_stream_t* OPJ_CALLCONV opj_stream_create(OPJ_SIZE_T p_buffer_size, OPJ_BOOL p_is_input);
+
+/**
+ * Destroys a stream created by opj_create_stream. This function does NOT close the abstract stream. If needed the user must
+ * close its own implementation of the stream.
+ *
+ * @param	p_stream	the stream to destroy.
+ */
+OPJ_API void OPJ_CALLCONV opj_stream_destroy(opj_stream_t* p_stream);
+
+/**
+ * Destroys a stream created by opj_create_stream. This function does NOT close the abstract stream. 
+ * If needed the user must close its own implementation of the stream.
+ *
+ * @param	p_stream	the stream to destroy.
+ */
+OPJ_API void OPJ_CALLCONV opj_stream_destroy_v3(opj_stream_t* p_stream);
+ 
+/**
+ * Sets the given function to be used as a read function.
+ * @param		p_stream	the stream to modify
+ * @param		p_function	the function to use a read function.
+*/
+OPJ_API void OPJ_CALLCONV opj_stream_set_read_function(opj_stream_t* p_stream, opj_stream_read_fn p_function);
+
+/**
+ * Sets the given function to be used as a write function.
+ * @param		p_stream	the stream to modify
+ * @param		p_function	the function to use a write function.
+*/
+OPJ_API void OPJ_CALLCONV opj_stream_set_write_function(opj_stream_t* p_stream, opj_stream_write_fn p_function);
+
+/**
+ * Sets the given function to be used as a skip function.
+ * @param		p_stream	the stream to modify
+ * @param		p_function	the function to use a skip function.
+*/
+OPJ_API void OPJ_CALLCONV opj_stream_set_skip_function(opj_stream_t* p_stream, opj_stream_skip_fn p_function);
+
+/**
+ * Sets the given function to be used as a seek function, the stream is then seekable.
+ * @param		p_stream	the stream to modify
+ * @param		p_function	the function to use a skip function.
+*/
+OPJ_API void OPJ_CALLCONV opj_stream_set_seek_function(opj_stream_t* p_stream, opj_stream_seek_fn p_function);
+
+/**
+ * Sets the given data to be used as a user data for the stream.
+ * @param		p_stream	the stream to modify
+ * @param		p_data		the data to set.
+ * @param		p_function	the function to free p_data when opj_stream_destroy() is called.
+*/
+OPJ_API void OPJ_CALLCONV opj_stream_set_user_data (opj_stream_t* p_stream, void * p_data, opj_stream_free_user_data_fn p_function);
+
+/**
+ * Sets the length of the user data for the stream.
+ *
+ * @param p_stream    the stream to modify
+ * @param data_length length of the user_data.
+*/
+OPJ_API void OPJ_CALLCONV opj_stream_set_user_data_length(opj_stream_t* p_stream, OPJ_UINT64 data_length);
+
+/**
+ * Create a stream from a file identified with its filename with default parameters (helper function)
+ * @param fname             the filename of the file to stream
+ * @param p_is_read_stream  whether the stream is a read stream (true) or not (false)
+*/
+OPJ_API opj_stream_t* OPJ_CALLCONV opj_stream_create_default_file_stream_v3 (const char *fname, OPJ_BOOL p_is_read_stream);
+ 
+/** Create a stream from a file identified with its filename with a specific buffer size
+ * @param fname             the filename of the file to stream
+ * @param p_buffer_size     size of the chunk used to stream
+ * @param p_is_read_stream  whether the stream is a read stream (true) or not (false)
+*/
+OPJ_API opj_stream_t* OPJ_CALLCONV opj_stream_create_file_stream_v3 (const char *fname, 
+                                                                     OPJ_SIZE_T p_buffer_size,
+                                                                     OPJ_BOOL p_is_read_stream);
+ 
+/* 
+==========================================================
+   event manager functions definitions
+==========================================================
+*/
+/**
+ * Set the info handler use by openjpeg.
+ * @param p_codec       the codec previously initialise
+ * @param p_callback    the callback function which will be used
+ * @param p_user_data   client object where will be returned the message
+*/
+OPJ_API OPJ_BOOL OPJ_CALLCONV opj_set_info_handler(opj_codec_t * p_codec, 
+                                                   opj_msg_callback p_callback,
+                                                   void * p_user_data);
+/**
+ * Set the warning handler use by openjpeg.
+ * @param p_codec       the codec previously initialise
+ * @param p_callback    the callback function which will be used
+ * @param p_user_data   client object where will be returned the message
+*/
+OPJ_API OPJ_BOOL OPJ_CALLCONV opj_set_warning_handler(opj_codec_t * p_codec,
+                                                      opj_msg_callback p_callback,
+                                                      void * p_user_data);
+/**
+ * Set the error handler use by openjpeg.
+ * @param p_codec       the codec previously initialise
+ * @param p_callback    the callback function which will be used
+ * @param p_user_data   client object where will be returned the message
+*/
+OPJ_API OPJ_BOOL OPJ_CALLCONV opj_set_error_handler(opj_codec_t * p_codec, 
+                                                    opj_msg_callback p_callback,
+                                                    void * p_user_data);
+
+/* 
+==========================================================
+   codec functions definitions
+==========================================================
+*/
+
+/**
+ * Creates a J2K/JP2 decompression structure
+ * @param format 		Decoder to select
+ *
+ * @return Returns a handle to a decompressor if successful, returns NULL otherwise
+ * */
+OPJ_API opj_codec_t* OPJ_CALLCONV opj_create_decompress(OPJ_CODEC_FORMAT format);
+
+/**
+ * Destroy a decompressor handle
+ *
+ * @param	p_codec			decompressor handle to destroy
+ */
+OPJ_API void OPJ_CALLCONV opj_destroy_codec(opj_codec_t * p_codec);
+
+/**
+ * Read after the codestream if necessary
+ * @param	p_codec			the JPEG2000 codec to read.
+ * @param	p_stream		the JPEG2000 stream.
+ */
+OPJ_API OPJ_BOOL OPJ_CALLCONV opj_end_decompress (	opj_codec_t *p_codec,
+													opj_stream_t *p_stream);
+
+
+/**
+ * Set decoding parameters to default values
+ * @param parameters Decompression parameters
+ */
+OPJ_API void OPJ_CALLCONV opj_set_default_decoder_parameters(opj_dparameters_t *parameters);
+
+/**
+ * Setup the decoder with decompression parameters provided by the user and with the message handler
+ * provided by the user.
+ *
+ * @param p_codec 		decompressor handler
+ * @param parameters 	decompression parameters
+ *
+ * @return true			if the decoder is correctly set
+ */
+OPJ_API OPJ_BOOL OPJ_CALLCONV opj_setup_decoder(opj_codec_t *p_codec,
+												opj_dparameters_t *parameters );
+
+/**
+ * Decodes an image header.
+ *
+ * @param	p_stream		the jpeg2000 stream.
+ * @param	p_codec			the jpeg2000 codec to read.
+ * @param	p_image			the image structure initialized with the characteristics of encoded image.
+ *
+ * @return true				if the main header of the codestream and the JP2 header is correctly read.
+ */
+OPJ_API OPJ_BOOL OPJ_CALLCONV opj_read_header (	opj_stream_t *p_stream,
+												opj_codec_t *p_codec,
+												opj_image_t **p_image);
+
+/**
+ * Sets the given area to be decoded. This function should be called right after opj_read_header and before any tile header reading.
+ *
+ * @param	p_codec			the jpeg2000 codec.
+ * @param	p_image         the decoded image previously setted by opj_read_header
+ * @param	p_start_x		the left position of the rectangle to decode (in image coordinates).
+ * @param	p_end_x			the right position of the rectangle to decode (in image coordinates).
+ * @param	p_start_y		the up position of the rectangle to decode (in image coordinates).
+ * @param	p_end_y			the bottom position of the rectangle to decode (in image coordinates).
+ *
+ * @return	true			if the area could be set.
+ */
+OPJ_API OPJ_BOOL OPJ_CALLCONV opj_set_decode_area(	opj_codec_t *p_codec,
+													opj_image_t* p_image,
+													OPJ_INT32 p_start_x, OPJ_INT32 p_start_y,
+													OPJ_INT32 p_end_x, OPJ_INT32 p_end_y );
+
+/**
+ * Decode an image from a JPEG-2000 codestream
+ *
+ * @param p_decompressor 	decompressor handle
+ * @param p_stream			Input buffer stream
+ * @param p_image 			the decoded image
+ * @return 					true if success, otherwise false
+ * */
+OPJ_API OPJ_BOOL OPJ_CALLCONV opj_decode(   opj_codec_t *p_decompressor,
+                                            opj_stream_t *p_stream,
+                                            opj_image_t *p_image);
+
+/**
+ * Get the decoded tile from the codec
+ *
+ * @param	p_codec			the jpeg2000 codec.
+ * @param	p_stream		input streamm
+ * @param	p_image			output image
+ * @param	tile_index		index of the tile which will be decode
+ *
+ * @return					true if success, otherwise false
+ */
+OPJ_API OPJ_BOOL OPJ_CALLCONV opj_get_decoded_tile(	opj_codec_t *p_codec,
+													opj_stream_t *p_stream,
+													opj_image_t *p_image,
+													OPJ_UINT32 tile_index);
+
+/**
+ * Set the resolution factor of the decoded image
+ * @param	p_codec			the jpeg2000 codec.
+ * @param	res_factor		resolution factor to set
+ *
+ * @return					true if success, otherwise false
+ */
+OPJ_API OPJ_BOOL OPJ_CALLCONV opj_set_decoded_resolution_factor(opj_codec_t *p_codec, OPJ_UINT32 res_factor);
+
+/**
+ * Writes a tile with the given data.
+ *
+ * @param	p_codec		        the jpeg2000 codec.
+ * @param	p_tile_index		the index of the tile to write. At the moment, the tiles must be written from 0 to n-1 in sequence.
+ * @param	p_data				pointer to the data to write. Data is arranged in sequence, data_comp0, then data_comp1, then ... NO INTERLEAVING should be set.
+ * @param	p_data_size			this value os used to make sure the data being written is correct. The size must be equal to the sum for each component of 
+ *                              tile_width * tile_height * component_size. component_size can be 1,2 or 4 bytes, depending on the precision of the given component.
+ * @param	p_stream			the stream to write data to.
+ *
+ * @return	true if the data could be written.
+ */
+OPJ_API OPJ_BOOL OPJ_CALLCONV opj_write_tile (	opj_codec_t *p_codec,
+												OPJ_UINT32 p_tile_index,
+												OPJ_BYTE * p_data,
+												OPJ_UINT32 p_data_size,
+												opj_stream_t *p_stream );
+
+/**
+ * Reads a tile header. This function is compulsory and allows one to know the size of the tile thta will be decoded.
+ * The user may need to refer to the image got by opj_read_header to understand the size being taken by the tile.
+ *
+ * @param	p_codec			the jpeg2000 codec.
+ * @param	p_tile_index	pointer to a value that will hold the index of the tile being decoded, in case of success.
+ * @param	p_data_size		pointer to a value that will hold the maximum size of the decoded data, in case of success. In case
+ *							of truncated codestreams, the actual number of bytes decoded may be lower. The computation of the size is the same
+ *							as depicted in opj_write_tile.
+ * @param	p_tile_x0		pointer to a value that will hold the x0 pos of the tile (in the image).
+ * @param	p_tile_y0		pointer to a value that will hold the y0 pos of the tile (in the image).
+ * @param	p_tile_x1		pointer to a value that will hold the x1 pos of the tile (in the image).
+ * @param	p_tile_y1		pointer to a value that will hold the y1 pos of the tile (in the image).
+ * @param	p_nb_comps		pointer to a value that will hold the number of components in the tile.
+ * @param	p_should_go_on	pointer to a boolean that will hold the fact that the decoding should go on. In case the
+ *							codestream is over at the time of the call, the value will be set to false. The user should then stop
+ *							the decoding.
+ * @param	p_stream		the stream to decode.
+ * @return	true			if the tile header could be decoded. In case the decoding should end, the returned value is still true.
+ *							returning false may be the result of a shortage of memory or an internal error.
+ */
+OPJ_API OPJ_BOOL OPJ_CALLCONV opj_read_tile_header(	opj_codec_t *p_codec,
+												opj_stream_t * p_stream,
+												OPJ_UINT32 * p_tile_index,
+												OPJ_UINT32 * p_data_size,
+												OPJ_INT32 * p_tile_x0, OPJ_INT32 * p_tile_y0,
+												OPJ_INT32 * p_tile_x1, OPJ_INT32 * p_tile_y1,
+												OPJ_UINT32 * p_nb_comps,
+												OPJ_BOOL * p_should_go_on );
+
+/**
+ * Reads a tile data. This function is compulsory and allows one to decode tile data. opj_read_tile_header should be called before.
+ * The user may need to refer to the image got by opj_read_header to understand the size being taken by the tile.
+ *
+ * @param	p_codec			the jpeg2000 codec.
+ * @param	p_tile_index	the index of the tile being decoded, this should be the value set by opj_read_tile_header.
+ * @param	p_data			pointer to a memory block that will hold the decoded data.
+ * @param	p_data_size		size of p_data. p_data_size should be bigger or equal to the value set by opj_read_tile_header.
+ * @param	p_stream		the stream to decode.
+ *
+ * @return	true			if the data could be decoded.
+ */
+OPJ_API OPJ_BOOL OPJ_CALLCONV opj_decode_tile_data(	opj_codec_t *p_codec,
+													OPJ_UINT32 p_tile_index,
+													OPJ_BYTE * p_data,
+													OPJ_UINT32 p_data_size,
+													opj_stream_t *p_stream );
+
+/* COMPRESSION FUNCTIONS*/
+
+/**
+ * Creates a J2K/JP2 compression structure
+ * @param 	format 		Coder to select
+ * @return 				Returns a handle to a compressor if successful, returns NULL otherwise
+ */
+OPJ_API opj_codec_t* OPJ_CALLCONV opj_create_compress(OPJ_CODEC_FORMAT format);
+
+/**
+Set encoding parameters to default values, that means : 
+<ul>
+<li>Lossless
+<li>1 tile
+<li>Size of precinct : 2^15 x 2^15 (means 1 precinct)
+<li>Size of code-block : 64 x 64
+<li>Number of resolutions: 6
+<li>No SOP marker in the codestream
+<li>No EPH marker in the codestream
+<li>No sub-sampling in x or y direction
+<li>No mode switch activated
+<li>Progression order: LRCP
+<li>No index file
+<li>No ROI upshifted
+<li>No offset of the origin of the image
+<li>No offset of the origin of the tiles
+<li>Reversible DWT 5-3
+</ul>
+ at param parameters Compression parameters
+*/
+OPJ_API void OPJ_CALLCONV opj_set_default_encoder_parameters(opj_cparameters_t *parameters);
+
+/**
+ * Setup the encoder parameters using the current image and using user parameters.
+ * @param p_codec 		Compressor handle
+ * @param parameters 	Compression parameters
+ * @param image 		Input filled image
+ */
+OPJ_API OPJ_BOOL OPJ_CALLCONV opj_setup_encoder(opj_codec_t *p_codec, 
+												opj_cparameters_t *parameters, 
+												opj_image_t *image);
+
+/**
+ * Start to compress the current image.
+ * @param p_codec 		Compressor handle
+ * @param image 	    Input filled image
+ * @param p_stream 		Input stgream
+ */
+OPJ_API OPJ_BOOL OPJ_CALLCONV opj_start_compress (	opj_codec_t *p_codec,
+													opj_image_t * p_image,
+													opj_stream_t *p_stream);
+
+/**
+ * End to compress the current image.
+ * @param p_codec 		Compressor handle
+ * @param p_stream 		Input stgream
+ */
+OPJ_API OPJ_BOOL OPJ_CALLCONV opj_end_compress (opj_codec_t *p_codec,
+												opj_stream_t *p_stream);
+
+/**
+ * Encode an image into a JPEG-2000 codestream
+ * @param p_codec 		compressor handle
+ * @param p_stream 		Output buffer stream
+ *
+ * @return 				Returns true if successful, returns false otherwise
+ */
+OPJ_API OPJ_BOOL OPJ_CALLCONV opj_encode(opj_codec_t *p_codec,
+                                         opj_stream_t *p_stream);
+/*
+==========================================================
+   codec output functions definitions
+==========================================================
+*/
+/* EXPERIMENTAL FUNCTIONS FOR NOW, USED ONLY IN J2K_DUMP*/
+
+/**
+Destroy Codestream information after compression or decompression
+ at param cstr_info Codestream information structure
+*/
+OPJ_API void OPJ_CALLCONV opj_destroy_cstr_info(opj_codestream_info_v2_t **cstr_info);
+
+
+/**
+ * Dump the codec information into the output stream
+ *
+ * @param	p_codec			the jpeg2000 codec.
+ * @param	info_flag		type of information dump.
+ * @param	output_stream	output stream where dump the informations get from the codec.
+ *
+ */
+OPJ_API void OPJ_CALLCONV opj_dump_codec(	opj_codec_t *p_codec,
+											OPJ_INT32 info_flag,
+											FILE* output_stream);
+
+/**
+ * Get the codestream information from the codec
+ *
+ * @param	p_codec			the jpeg2000 codec.
+ *
+ * @return					a pointer to a codestream information structure.
+ *
+ */
+OPJ_API opj_codestream_info_v2_t* OPJ_CALLCONV opj_get_cstr_info(opj_codec_t *p_codec);
+
+/**
+ * Get the codestream index from the codec
+ *
+ * @param	p_codec			the jpeg2000 codec.
+ *
+ * @return					a pointer to a codestream index structure.
+ *
+ */
+OPJ_API opj_codestream_index_t * OPJ_CALLCONV opj_get_cstr_index(opj_codec_t *p_codec);
+
+OPJ_API void OPJ_CALLCONV opj_destroy_cstr_index(opj_codestream_index_t **p_cstr_index);
+
+
+/**
+ * Get the JP2 file information from the codec FIXME
+ *
+ * @param	p_codec			the jpeg2000 codec.
+ *
+ * @return					a pointer to a JP2 metadata structure.
+ *
+ */
+OPJ_API opj_jp2_metadata_t* OPJ_CALLCONV opj_get_jp2_metadata(opj_codec_t *p_codec);
+
+/**
+ * Get the JP2 file index from the codec FIXME
+ *
+ * @param	p_codec			the jpeg2000 codec.
+ *
+ * @return					a pointer to a JP2 index structure.
+ *
+ */
+OPJ_API opj_jp2_index_t* OPJ_CALLCONV opj_get_jp2_index(opj_codec_t *p_codec);
+
+
+/*
+==========================================================
+   MCT functions
+==========================================================
+*/
+
+/**
+ * Sets the MCT matrix to use.
+ *
+ * @param	parameters		the parameters to change.
+ * @param	pEncodingMatrix	the encoding matrix.
+ * @param	p_dc_shift		the dc shift coefficients to use.
+ * @param	pNbComp			the number of components of the image.
+ *
+ * @return	true if the parameters could be set.
+ */
+OPJ_API OPJ_BOOL OPJ_CALLCONV opj_set_MCT( opj_cparameters_t *parameters,
+		                               	   OPJ_FLOAT32 * pEncodingMatrix,
+		                               	   OPJ_INT32 * p_dc_shift,
+		                               	   OPJ_UINT32 pNbComp);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OPENJPEG_H */
diff --git a/Source/LibOpenJPEG/opj_clock.c b/Source/LibOpenJPEG/opj_clock.c
new file mode 100644
index 0000000..5f2ab9d
--- /dev/null
+++ b/Source/LibOpenJPEG/opj_clock.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/times.h>
+#endif /* _WIN32 */
+#include "opj_includes.h"
+
+OPJ_FLOAT64 opj_clock(void) {
+#ifdef _WIN32
+	/* _WIN32: use QueryPerformance (very accurate) */
+    LARGE_INTEGER freq , t ;
+    /* freq is the clock speed of the CPU */
+    QueryPerformanceFrequency(&freq) ;
+	/* cout << "freq = " << ((double) freq.QuadPart) << endl; */
+    /* t is the high resolution performance counter (see MSDN) */
+    QueryPerformanceCounter ( & t ) ;
+    return ( t.QuadPart /(OPJ_FLOAT64) freq.QuadPart ) ;
+#else
+	/* Unix or Linux: use resource usage */
+    struct rusage t;
+    OPJ_FLOAT64 procTime;
+    /* (1) Get the rusage data structure at this moment (man getrusage) */
+    getrusage(0,&t);
+    /* (2) What is the elapsed time ? - CPU time = User time + System time */
+	/* (2a) Get the seconds */
+    procTime = (OPJ_FLOAT64)(t.ru_utime.tv_sec + t.ru_stime.tv_sec);
+    /* (2b) More precisely! Get the microseconds part ! */
+    return ( procTime + (OPJ_FLOAT64)(t.ru_utime.tv_usec + t.ru_stime.tv_usec) * 1e-6 ) ;
+#endif
+}
+
diff --git a/Source/LibOpenJPEG/opj_clock.h b/Source/LibOpenJPEG/opj_clock.h
new file mode 100644
index 0000000..d3fcec3
--- /dev/null
+++ b/Source/LibOpenJPEG/opj_clock.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef __OPJ_CLOCK_H
+#define __OPJ_CLOCK_H
+/**
+ at file opj_clock.h
+ at brief Internal function for timing
+
+The functions in OPJ_CLOCK.C are internal utilities mainly used for timing.
+*/
+
+/** @defgroup MISC MISC - Miscellaneous internal functions */
+/*@{*/
+
+/** @name Exported functions */
+/*@{*/
+/* ----------------------------------------------------------------------- */
+
+/**
+Difference in successive opj_clock() calls tells you the elapsed time
+ at return Returns time in seconds
+*/
+OPJ_FLOAT64 opj_clock(void);
+
+/* ----------------------------------------------------------------------- */
+/*@}*/
+
+/*@}*/
+
+#endif /* __OPJ_CLOCK_H */
+
diff --git a/Source/LibOpenJPEG/opj_codec.h b/Source/LibOpenJPEG/opj_codec.h
new file mode 100644
index 0000000..6ac0f28
--- /dev/null
+++ b/Source/LibOpenJPEG/opj_codec.h
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2007, Professor Benoit Macq
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef __OPJ_CODEC_H
+#define __OPJ_CODEC_H
+/**
+ at file opj_codec.h
+*/
+
+
+/**
+ * Main codec handler used for compression or decompression.
+ */
+typedef struct opj_codec_private
+{
+    /** FIXME DOC */
+    union
+    {
+        /**
+         * Decompression handler.
+         */
+        struct opj_decompression
+        {
+            /** Main header reading function handler */
+            OPJ_BOOL (*opj_read_header) ( struct opj_stream_private * cio,
+                                          void * p_codec,
+                                          opj_image_t **p_image,
+                                          struct opj_event_mgr * p_manager);
+
+            /** Decoding function */
+            OPJ_BOOL (*opj_decode) ( void * p_codec,
+                                     struct opj_stream_private * p_cio,
+                                     opj_image_t * p_image,
+                                     struct opj_event_mgr * p_manager);
+
+            /** FIXME DOC */
+            OPJ_BOOL (*opj_read_tile_header)( void * p_codec,
+                                              OPJ_UINT32 * p_tile_index,
+                                              OPJ_UINT32 * p_data_size,
+                                              OPJ_INT32 * p_tile_x0,
+                                              OPJ_INT32 * p_tile_y0,
+                                              OPJ_INT32 * p_tile_x1,
+                                              OPJ_INT32 * p_tile_y1,
+                                              OPJ_UINT32 * p_nb_comps,
+                                              OPJ_BOOL * p_should_go_on,
+                                              struct opj_stream_private * p_cio,
+                                              struct opj_event_mgr * p_manager);
+
+            /** FIXME DOC */
+            OPJ_BOOL (*opj_decode_tile_data)( void * p_codec,
+                                              OPJ_UINT32 p_tile_index,
+                                              OPJ_BYTE * p_data,
+                                              OPJ_UINT32 p_data_size,
+                                              struct opj_stream_private * p_cio,
+                                              struct opj_event_mgr * p_manager);
+
+            /** Reading function used after codestream if necessary */
+            OPJ_BOOL (* opj_end_decompress) ( void *p_codec,
+                                              struct opj_stream_private * cio,
+                                              struct opj_event_mgr * p_manager);
+
+            /** Codec destroy function handler */
+            void (*opj_destroy) (void * p_codec);
+
+            /** Setup decoder function handler */
+            void (*opj_setup_decoder) ( void * p_codec, opj_dparameters_t * p_param);
+
+            /** Set decode area function handler */
+            OPJ_BOOL (*opj_set_decode_area) ( void * p_codec,
+                                              opj_image_t * p_image,
+                                              OPJ_INT32 p_start_x,
+                                              OPJ_INT32 p_end_x,
+                                              OPJ_INT32 p_start_y,
+                                              OPJ_INT32 p_end_y,
+                                              struct opj_event_mgr * p_manager);
+
+            /** Get tile function */
+            OPJ_BOOL (*opj_get_decoded_tile) ( void *p_codec,
+                                               opj_stream_private_t * p_cio,
+                                               opj_image_t *p_image,
+                                               struct opj_event_mgr * p_manager,
+                                               OPJ_UINT32 tile_index);
+
+            /** Set the decoded resolution factor */
+            OPJ_BOOL (*opj_set_decoded_resolution_factor) ( void * p_codec,
+                                                            OPJ_UINT32 res_factor,
+                                                            opj_event_mgr_t * p_manager);
+        } m_decompression;
+
+        /**
+         * Compression handler. FIXME DOC
+         */
+        struct opj_compression
+        {
+            OPJ_BOOL (* opj_start_compress) ( void *p_codec,
+                                              struct opj_stream_private * cio,
+                                              struct opj_image * p_image,
+                                              struct opj_event_mgr * p_manager);
+
+            OPJ_BOOL (* opj_encode) ( void * p_codec,
+                                      struct opj_stream_private *p_cio,
+                                      struct opj_event_mgr * p_manager);
+
+            OPJ_BOOL (* opj_write_tile) ( void * p_codec,
+                                          OPJ_UINT32 p_tile_index,
+                                          OPJ_BYTE * p_data,
+                                          OPJ_UINT32 p_data_size,
+                                          struct opj_stream_private * p_cio,
+                                          struct opj_event_mgr * p_manager);
+
+            OPJ_BOOL (* opj_end_compress) (	void * p_codec,
+                                            struct opj_stream_private * p_cio,
+                                            struct opj_event_mgr * p_manager);
+
+            void (* opj_destroy) (void * p_codec);
+
+            void (* opj_setup_encoder) ( void * p_codec,
+                                         opj_cparameters_t * p_param,
+                                         struct opj_image * p_image,
+                                         struct opj_event_mgr * p_manager);
+        } m_compression;
+    } m_codec_data;
+    /** FIXME DOC*/
+    void * m_codec;
+    /** Event handler */
+    opj_event_mgr_t m_event_mgr;
+    /** Flag to indicate if the codec is used to decode or encode*/
+    OPJ_BOOL is_decompressor;
+    void (*opj_dump_codec) (void * p_codec, OPJ_INT32 info_flag, FILE* output_stream);
+    opj_codestream_info_v2_t* (*opj_get_codec_info)(void* p_codec);
+    opj_codestream_index_t* (*opj_get_codec_index)(void* p_codec);
+}
+opj_codec_private_t;
+
+
+#endif /* __OPJ_CODEC_H */
+
diff --git a/Source/LibOpenJPEG/opj_config.h b/Source/LibOpenJPEG/opj_config.h
index b36f4e7..216e1cf 100644
--- a/Source/LibOpenJPEG/opj_config.h
+++ b/Source/LibOpenJPEG/opj_config.h
@@ -1,41 +1,9 @@
-/* If you want to build the library manually without using
- * 'configure' or 'CMake'
- * then copy this file 
- * 'opj_config.h.in.user' 
- *       to
- * 'opj_config.h'
- * 
- * Open 'opj_config.h' and change the file contents
- * if you want to define something because you know you have 
- * BOTH installed the library AND the header file(s).
- * Then e.g. write
-#define HAVE_LIBPNG 1
- *  
- *
- * The file 'opj_config.h' will be included in some source files.
- * ==== YOU CAN NOT COMPILE WITHOUT IT. ====
- * === DO NOT FOREGET TO CHANGE 'config.nix' APPROPRIATELY. ====
-*/
+#ifndef OPJ_CONFIG_H
+#define OPJ_CONFIG_H
 
-/* DO NOT DEFINE BOTH VERSIONS OF LCMS */
-/* define to 1 if you have both liblcms and lcms.h installed */
-#undef HAVE_LIBLCMS1
-/* #define HAVE_LIBLCMS1 1 */
+#ifndef _MSC_VER
+#define OPJ_HAVE_STDINT_H
+#define OPJ_HAVE_INTTYPES_H
+#endif
 
-/* define to 1 if you have both liblcms2 and lcms2.h installed */
-#undef HAVE_LIBLCMS2
-/* #define HAVE_LIBLCMS2 1 */
-
-/* define to 1 if you have both libpng and png.h installed */
-#undef HAVE_LIBPNG
-/* #define HAVE_LIBPNG 1 */
-
-/* define to 1 if you have both libtiff and tiff.h installed */
-#undef HAVE_LIBTIFF
-/* #define HAVE_LIBTIFF 1 */
-
-/*---------------- DO NOT CHANGE BELOW THIS LINE ----------------*/
-#define PACKAGE_URL "http://www.openjpeg.org/"
-#define PACKAGE_BUGREPORT "http://code.google.com/p/openjpeg/"
-
-#define PACKAGE_VERSION "1.5.0"
+#endif /* OPJ_CONFIG_H */
diff --git a/Source/LibOpenJPEG/opj_config_private.h b/Source/LibOpenJPEG/opj_config_private.h
new file mode 100644
index 0000000..a4a6f2f
--- /dev/null
+++ b/Source/LibOpenJPEG/opj_config_private.h
@@ -0,0 +1,16 @@
+#ifndef OPJ_CONFIG_PRIVATE_H
+#define OPJ_CONFIG_PRIVATE_H
+
+#define OPJ_PACKAGE_VERSION "2.0.0"
+
+/**
+Some versions of gcc may have BYTE_ORDER or __BYTE_ORDER defined
+If your big endian system isn't being detected, add an OS specific check
+*/
+#if (defined(BYTE_ORDER) && BYTE_ORDER==BIG_ENDIAN) || \
+	(defined(__BYTE_ORDER) && __BYTE_ORDER==__BIG_ENDIAN) || \
+	defined(__BIG_ENDIAN__)
+#define OPJ_BIG_ENDIAN
+#endif /* BYTE_ORDER */
+
+#endif /* OPJ_CONFIG_PRIVATE_H */
diff --git a/Source/LibOpenJPEG/opj_includes.h b/Source/LibOpenJPEG/opj_includes.h
index aaca54e..7638096 100644
--- a/Source/LibOpenJPEG/opj_includes.h
+++ b/Source/LibOpenJPEG/opj_includes.h
@@ -1,140 +1,175 @@
-/*
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef OPJ_INCLUDES_H
-#define OPJ_INCLUDES_H
-
-/*
- ==========================================================
-   Standard includes used by the library
- ==========================================================
-*/
-#include <memory.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include <float.h>
-#include <time.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <ctype.h>
-
-/*
- ==========================================================
-   OpenJPEG interface
- ==========================================================
- */
-#include "openjpeg.h"
-
-/*
- ==========================================================
-   OpenJPEG modules
- ==========================================================
-*/
-
-/* Ignore GCC attributes if this is not GCC */
-#ifndef __GNUC__
-	#define __attribute__(x) /* __attribute__(x) */
-#endif
-
-/*
-The inline keyword is supported by C99 but not by C90. 
-Most compilers implement their own version of this keyword ... 
-*/
-#ifndef INLINE
-	#if defined(_MSC_VER)
-		#define INLINE __forceinline
-	#elif defined(__GNUC__)
-		#define INLINE __inline__
-	#elif defined(__MWERKS__)
-		#define INLINE inline
-	#else 
-		/* add other compilers here ... */
-		#define INLINE 
-	#endif /* defined(<Compiler>) */
-#endif /* INLINE */
-
-/* Are restricted pointers available? (C99) */
-#if (__STDC_VERSION__ != 199901L)
-	/* Not a C99 compiler */
-	#ifdef __GNUC__
-		#define restrict __restrict__
-	#else
-		#define restrict /* restrict */
-	#endif
-#endif
-
-/* MSVC and Borland C do not have lrintf */
-#if defined(_MSC_VER) || defined(__BORLANDC__)
-static INLINE long lrintf(float f){
-#ifdef _M_X64
-    return (long)((f>0.0f) ? (f + 0.5f):(f -0.5f));
-#else
-    int i;
- 
-    _asm{
-        fld f
-        fistp i
-    };
- 
-    return i;
-#endif
-}
-#endif
-
-#include "j2k_lib.h"
-#include "opj_malloc.h"
-#include "event.h"
-#include "bio.h"
-#include "cio.h"
-
-#include "image.h"
-#include "j2k.h"
-#include "jp2.h"
-#include "jpt.h"
-
-#include "mqc.h"
-#include "raw.h"
-#include "bio.h"
-#include "tgt.h"
-#include "pi.h"
-#include "tcd.h"
-#include "t1.h"
-#include "dwt.h"
-#include "t2.h"
-#include "mct.h"
-#include "int.h"
-#include "fix.h"
-
-#include "cidx_manager.h"
-#include "indexbox_manager.h"
-
-/* JPWL>> */
-#ifdef USE_JPWL
-#include "./jpwl/jpwl.h"
-#endif /* USE_JPWL */
-/* <<JPWL */
-
-#endif /* OPJ_INCLUDES_H */
+/*
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2008;2011-2012, Centre National d'Etudes Spatiales (CNES), France 
+ * Copyright (c) 2012, CS Systemes d'Information, France
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef OPJ_INCLUDES_H
+#define OPJ_INCLUDES_H
+
+/*
+ * This must be included before any system headers,
+ * since they can react to macro defined there
+ */
+#include "opj_config_private.h"
+
+/*
+ ==========================================================
+   Standard includes used by the library
+ ==========================================================
+*/
+#include <memory.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <float.h>
+#include <time.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <assert.h>
+
+/*
+  Use fseeko() and ftello() if they are available since they use
+  'off_t' rather than 'long'.  It is wrong to use fseeko() and
+  ftello() only on systems with special LFS support since some systems
+  (e.g. FreeBSD) support a 64-bit off_t by default.
+*/
+#if defined(OPJ_HAVE_FSEEKO) && !defined(fseek)
+#  define fseek  fseeko
+#  define ftell  ftello
+#endif
+
+
+#if defined(WIN32) && !defined(Windows95) && !defined(__BORLANDC__) && \
+  !(defined(_MSC_VER) && _MSC_VER < 1400) && \
+  !(defined(__MINGW32__) && __MSVCRT_VERSION__ < 0x800)
+  /*
+    Windows '95 and Borland C do not support _lseeki64
+    Visual Studio does not support _fseeki64 and _ftelli64 until the 2005 release.
+    Without these interfaces, files over 2GB in size are not supported for Windows.
+  */
+#  define OPJ_FSEEK(stream,offset,whence) _fseeki64(stream,/* __int64 */ offset,whence)
+#  define OPJ_FSTAT(fildes,stat_buff) _fstati64(fildes,/* struct _stati64 */ stat_buff)
+#  define OPJ_FTELL(stream) /* __int64 */ _ftelli64(stream)
+#  define OPJ_STAT_STRUCT_T struct _stati64
+#  define OPJ_STAT(path,stat_buff) _stati64(path,/* struct _stati64 */ stat_buff)
+#else
+#  define OPJ_FSEEK(stream,offset,whence) fseek(stream,offset,whence)
+#  define OPJ_FSTAT(fildes,stat_buff) fstat(fildes,stat_buff)
+#  define OPJ_FTELL(stream) ftell(stream)
+#  define OPJ_STAT_STRUCT_T struct stat
+#  define OPJ_STAT(path,stat_buff) stat(path,stat_buff)
+#endif
+
+
+/*
+ ==========================================================
+   OpenJPEG interface
+ ==========================================================
+ */
+#include "openjpeg.h"
+
+/*
+ ==========================================================
+   OpenJPEG modules
+ ==========================================================
+*/
+
+/* Ignore GCC attributes if this is not GCC */
+#ifndef __GNUC__
+	#define __attribute__(x) /* __attribute__(x) */
+#endif
+
+
+/* Are restricted pointers available? (C99) */
+#if (__STDC_VERSION__ != 199901L)
+	/* Not a C99 compiler */
+	#ifdef __GNUC__
+		#define restrict __restrict__
+	#else
+		#define restrict /* restrict */
+	#endif
+#endif
+
+/* MSVC before 2013 and Borland C do not have lrintf */
+#if defined(_MSC_VER) && (_MSC_VER < 1800) || defined(__BORLANDC__)
+static INLINE long lrintf(float f){
+#ifdef _M_X64
+    return (long)((f>0.0f) ? (f + 0.5f):(f -0.5f));
+#else
+    int i;
+ 
+    _asm{
+        fld f
+        fistp i
+    };
+ 
+    return i;
+#endif
+}
+#endif
+
+#include "opj_inttypes.h"
+#include "opj_clock.h"
+#include "opj_malloc.h"
+#include "function_list.h"
+#include "event.h"
+#include "bio.h"
+#include "cio.h"
+
+#include "image.h"
+#include "invert.h"
+#include "j2k.h"
+#include "jp2.h"
+
+#include "mqc.h"
+#include "raw.h"
+#include "bio.h"
+
+#include "pi.h"
+#include "tgt.h"
+#include "tcd.h"
+#include "t1.h"
+#include "dwt.h"
+#include "t2.h"
+#include "mct.h"
+#include "opj_intmath.h"
+
+#ifdef USE_JPIP
+#include "cidx_manager.h"
+#include "indexbox_manager.h"
+#endif
+
+/* JPWL>> */
+#ifdef USE_JPWL
+#include "openjpwl/jpwl.h"
+#endif /* USE_JPWL */
+/* <<JPWL */
+
+/* V2 */
+#include "opj_codec.h"
+
+
+#endif /* OPJ_INCLUDES_H */
diff --git a/Source/LibOpenJPEG/opj_intmath.h b/Source/LibOpenJPEG/opj_intmath.h
new file mode 100644
index 0000000..38edf3f
--- /dev/null
+++ b/Source/LibOpenJPEG/opj_intmath.h
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2007, Professor Benoit Macq
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef __INT_H
+#define __INT_H
+/**
+ at file opj_intmath.h
+ at brief Implementation of operations on integers (INT)
+
+The functions in OPJ_INTMATH.H have for goal to realize operations on integers.
+*/
+
+/** @defgroup OPJ_INTMATH OPJ_INTMATH - Implementation of operations on integers */
+/*@{*/
+
+/** @name Exported functions (see also openjpeg.h) */
+/*@{*/
+/* ----------------------------------------------------------------------- */
+/**
+Get the minimum of two integers
+ at return Returns a if a < b else b
+*/
+static INLINE OPJ_INT32 opj_int_min(OPJ_INT32 a, OPJ_INT32 b) {
+	return a < b ? a : b;
+}
+
+/**
+Get the minimum of two integers
+ at return Returns a if a < b else b
+*/
+static INLINE OPJ_UINT32 opj_uint_min(OPJ_UINT32 a, OPJ_UINT32 b) {
+	return a < b ? a : b;
+}
+
+/**
+Get the maximum of two integers
+ at return Returns a if a > b else b
+*/
+static INLINE OPJ_INT32 opj_int_max(OPJ_INT32 a, OPJ_INT32 b) {
+	return (a > b) ? a : b;
+}
+
+/**
+Get the maximum of two integers
+ at return Returns a if a > b else b
+*/
+static INLINE OPJ_UINT32 opj_uint_max(OPJ_UINT32  a, OPJ_UINT32  b) {
+	return (a > b) ? a : b;
+}
+
+/**
+Clamp an integer inside an interval
+ at return
+<ul>
+<li>Returns a if (min < a < max)
+<li>Returns max if (a > max)
+<li>Returns min if (a < min) 
+</ul>
+*/
+static INLINE OPJ_INT32 opj_int_clamp(OPJ_INT32 a, OPJ_INT32 min, OPJ_INT32 max) {
+	if (a < min)
+		return min;
+	if (a > max)
+		return max;
+	return a;
+}
+/**
+ at return Get absolute value of integer
+*/
+static INLINE OPJ_INT32 opj_int_abs(OPJ_INT32 a) {
+	return a < 0 ? -a : a;
+}
+/**
+Divide an integer and round upwards
+ at return Returns a divided by b
+*/
+static INLINE OPJ_INT32 opj_int_ceildiv(OPJ_INT32 a, OPJ_INT32 b) {
+  assert(b);
+	return (a + b - 1) / b;
+}
+
+/**
+Divide an integer and round upwards
+ at return Returns a divided by b
+*/
+static INLINE OPJ_UINT32  opj_uint_ceildiv(OPJ_UINT32  a, OPJ_UINT32  b) {
+	return (a + b - 1) / b;
+}
+
+/**
+Divide an integer by a power of 2 and round upwards
+ at return Returns a divided by 2^b
+*/
+static INLINE OPJ_INT32 opj_int_ceildivpow2(OPJ_INT32 a, OPJ_INT32 b) {
+	return (OPJ_INT32)((a + (OPJ_INT64)(1 << b) - 1) >> b);
+}
+/**
+Divide an integer by a power of 2 and round downwards
+ at return Returns a divided by 2^b
+*/
+static INLINE OPJ_INT32 opj_int_floordivpow2(OPJ_INT32 a, OPJ_INT32 b) {
+	return a >> b;
+}
+/**
+Get logarithm of an integer and round downwards
+ at return Returns log2(a)
+*/
+static INLINE OPJ_INT32 opj_int_floorlog2(OPJ_INT32 a) {
+	OPJ_INT32 l;
+	for (l = 0; a > 1; l++) {
+		a >>= 1;
+	}
+	return l;
+}
+/**
+Get logarithm of an integer and round downwards
+ at return Returns log2(a)
+*/
+static INLINE OPJ_UINT32  opj_uint_floorlog2(OPJ_UINT32  a) {
+	OPJ_UINT32  l;
+	for (l = 0; a > 1; ++l)
+	{
+		a >>= 1;
+	}
+	return l;
+}
+
+/**
+Multiply two fixed-precision rational numbers.
+ at param a
+ at param b
+ at return Returns a * b
+*/
+static INLINE OPJ_INT32 opj_int_fix_mul(OPJ_INT32 a, OPJ_INT32 b) {
+    OPJ_INT64 temp = (OPJ_INT64) a * (OPJ_INT64) b ;
+    temp += temp & 4096;
+    return (OPJ_INT32) (temp >> 13) ;
+}
+
+/* ----------------------------------------------------------------------- */
+/*@}*/
+
+/*@}*/
+
+#endif
diff --git a/Source/LibOpenJPEG/opj_inttypes.h b/Source/LibOpenJPEG/opj_inttypes.h
new file mode 100644
index 0000000..6121513
--- /dev/null
+++ b/Source/LibOpenJPEG/opj_inttypes.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2012, Mathieu Malaterre <mathieu.malaterre at gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef OPJ_INTTYPES_H
+#define OPJ_INTTYPES_H
+
+#include "opj_config_private.h"
+#ifdef OPJ_HAVE_INTTYPES_H
+#include <inttypes.h>
+#else
+#if defined(_WIN32)
+#define PRId64 "I64d"
+#define PRIi64 "I64i"
+#define PRIu64 "I64u"
+#define PRIx64 "I64x"
+#else
+#error unsupported platform
+#endif
+#endif
+
+#endif /* OPJ_INTTYPES_H */
diff --git a/Source/LibOpenJPEG/opj_malloc.h b/Source/LibOpenJPEG/opj_malloc.h
index 9e4af23..95ad147 100644
--- a/Source/LibOpenJPEG/opj_malloc.h
+++ b/Source/LibOpenJPEG/opj_malloc.h
@@ -1,165 +1,180 @@
-/*
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * Copyright (c) 2007, Callum Lerwick <seg at haxxed.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef __OPJ_MALLOC_H
-#define __OPJ_MALLOC_H
-/**
- at file opj_malloc.h
- at brief Internal functions
-
-The functions in opj_malloc.h are internal utilities used for memory management.
-*/
-
-/** @defgroup MISC MISC - Miscellaneous internal functions */
-/*@{*/
-
-/** @name Exported functions */
-/*@{*/
-/* ----------------------------------------------------------------------- */
-
-/**
-Allocate an uninitialized memory block
- at param size Bytes to allocate
- at return Returns a void pointer to the allocated space, or NULL if there is insufficient memory available
-*/
-#ifdef ALLOC_PERF_OPT
-void * OPJ_CALLCONV opj_malloc(size_t size);
-#else
-#define opj_malloc(size) malloc(size)
-#endif
-
-/**
-Allocate a memory block with elements initialized to 0
- at param num Blocks to allocate
- at param size Bytes per block to allocate
- at return Returns a void pointer to the allocated space, or NULL if there is insufficient memory available
-*/
-#ifdef ALLOC_PERF_OPT
-void * OPJ_CALLCONV opj_calloc(size_t _NumOfElements, size_t _SizeOfElements);
-#else
-#define opj_calloc(num, size) calloc(num, size)
-#endif
-
-/**
-Allocate memory aligned to a 16 byte boundry
- at param size Bytes to allocate
- at return Returns a void pointer to the allocated space, or NULL if there is insufficient memory available
-*/
-/* FIXME: These should be set with cmake tests, but we're currently not requiring use of cmake */
-#ifdef _WIN32
-	/* Someone should tell the mingw people that their malloc.h ought to provide _mm_malloc() */
-	#ifdef __GNUC__
-		#include <mm_malloc.h>
-		#define HAVE_MM_MALLOC
-	#else /* MSVC, Intel C++ */
-		#include <malloc.h>
-		#ifdef _mm_malloc
-			#define HAVE_MM_MALLOC
-		#endif
-	#endif
-#else /* Not _WIN32 */
-	#if defined(__sun)
-		#define HAVE_MEMALIGN
-  #elif defined(__FreeBSD__)
-    #define HAVE_POSIX_MEMALIGN
-	/* Linux x86_64 and OSX always align allocations to 16 bytes */
-	#elif !defined(__amd64__) && !defined(__APPLE__) && !defined(_AIX)
-		#define HAVE_MEMALIGN
-		#include <malloc.h>			
-	#endif
-#endif
-
-#define opj_aligned_malloc(size) malloc(size)
-#define opj_aligned_free(m) free(m)
-
-#ifdef HAVE_MM_MALLOC
-	#undef opj_aligned_malloc
-	#define opj_aligned_malloc(size) _mm_malloc(size, 16)
-	#undef opj_aligned_free
-	#define opj_aligned_free(m) _mm_free(m)
-#endif
-
-#ifdef HAVE_MEMALIGN
-	extern void* memalign(size_t, size_t);
-	#undef opj_aligned_malloc
-	#define opj_aligned_malloc(size) memalign(16, (size))
-	#undef opj_aligned_free
-	#define opj_aligned_free(m) free(m)
-#endif
-
-#ifdef HAVE_POSIX_MEMALIGN
-	#undef opj_aligned_malloc
-	extern int posix_memalign(void**, size_t, size_t);
-
-	static INLINE void* __attribute__ ((malloc)) opj_aligned_malloc(size_t size){
-		void* mem = NULL;
-		posix_memalign(&mem, 16, size);
-		return mem;
-	}
-	#undef opj_aligned_free
-	#define opj_aligned_free(m) free(m)
-#endif
-
-#ifdef ALLOC_PERF_OPT
-	#undef opj_aligned_malloc
-	#define opj_aligned_malloc(size) opj_malloc(size)
-	#undef opj_aligned_free
-	#define opj_aligned_free(m) opj_free(m)
-#endif
-
-/**
-Reallocate memory blocks.
- at param m Pointer to previously allocated memory block
- at param s New size in bytes
- at return Returns a void pointer to the reallocated (and possibly moved) memory block
-*/
-#ifdef ALLOC_PERF_OPT
-void * OPJ_CALLCONV opj_realloc(void * m, size_t s);
-#else
-#define opj_realloc(m, s) realloc(m, s)
-#endif
-
-/**
-Deallocates or frees a memory block.
- at param m Previously allocated memory block to be freed
-*/
-#ifdef ALLOC_PERF_OPT
-void OPJ_CALLCONV opj_free(void * m);
-#else
-#define opj_free(m) free(m)
-#endif
-
-#ifdef __GNUC__
-#pragma GCC poison malloc calloc realloc free
-#endif
-
-/* ----------------------------------------------------------------------- */
-/*@}*/
-
-/*@}*/
-
-#endif /* __OPJ_MALLOC_H */
-
+/*
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2007, Callum Lerwick <seg at haxxed.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef __OPJ_MALLOC_H
+#define __OPJ_MALLOC_H
+/**
+ at file opj_malloc.h
+ at brief Internal functions
+
+The functions in opj_malloc.h are internal utilities used for memory management.
+*/
+
+/** @defgroup MISC MISC - Miscellaneous internal functions */
+/*@{*/
+
+/** @name Exported functions */
+/*@{*/
+/* ----------------------------------------------------------------------- */
+
+/**
+Allocate an uninitialized memory block
+ at param size Bytes to allocate
+ at return Returns a void pointer to the allocated space, or NULL if there is insufficient memory available
+*/
+#ifdef ALLOC_PERF_OPT
+void * OPJ_CALLCONV opj_malloc(size_t size);
+#else
+/* prevent assertion on overflow for MSVC */
+#ifdef _MSC_VER
+#define opj_malloc(size) ((size_t)(size) >= (size_t)-0x100 ? NULL : malloc(size))
+#else
+#define opj_malloc(size) malloc(size)
+#endif
+#endif
+
+/**
+Allocate a memory block with elements initialized to 0
+ at param num Blocks to allocate
+ at param size Bytes per block to allocate
+ at return Returns a void pointer to the allocated space, or NULL if there is insufficient memory available
+*/
+#ifdef ALLOC_PERF_OPT
+void * OPJ_CALLCONV opj_calloc(size_t _NumOfElements, size_t _SizeOfElements);
+#else
+/* prevent assertion on overflow for MSVC */
+#ifdef _MSC_VER
+#define opj_calloc(num, size) ((size_t)(num) != 0 && (size_t)(num) >= (size_t)-0x100 / (size_t)(size) ? NULL : calloc(num, size))
+#else
+#define opj_calloc(num, size) calloc(num, size)
+#endif
+#endif
+
+/**
+Allocate memory aligned to a 16 byte boundry
+ at param size Bytes to allocate
+ at return Returns a void pointer to the allocated space, or NULL if there is insufficient memory available
+*/
+/* FIXME: These should be set with cmake tests, but we're currently not requiring use of cmake */
+#ifdef _WIN32
+	/* Someone should tell the mingw people that their malloc.h ought to provide _mm_malloc() */
+	#ifdef __GNUC__
+		#include <mm_malloc.h>
+		#define HAVE_MM_MALLOC
+	#else /* MSVC, Intel C++ */
+		#include <malloc.h>
+		#ifdef _mm_malloc
+			#define HAVE_MM_MALLOC
+		#endif
+	#endif
+#else /* Not _WIN32 */
+	#if defined(__sun)
+		#define HAVE_MEMALIGN
+  #elif defined(__FreeBSD__)
+    #define HAVE_POSIX_MEMALIGN
+	/* Linux x86_64 and OSX always align allocations to 16 bytes */
+	#elif !defined(__amd64__) && !defined(__APPLE__) && !defined(_AIX)
+		#define HAVE_MEMALIGN
+		#include <malloc.h>			
+	#endif
+#endif
+
+#define opj_aligned_malloc(size) malloc(size)
+#define opj_aligned_free(m) free(m)
+
+#ifdef HAVE_MM_MALLOC
+	#undef opj_aligned_malloc
+	#define opj_aligned_malloc(size) _mm_malloc(size, 16)
+	#undef opj_aligned_free
+	#define opj_aligned_free(m) _mm_free(m)
+#endif
+
+#ifdef HAVE_MEMALIGN
+	extern void* memalign(size_t, size_t);
+	#undef opj_aligned_malloc
+	#define opj_aligned_malloc(size) memalign(16, (size))
+	#undef opj_aligned_free
+	#define opj_aligned_free(m) free(m)
+#endif
+
+#ifdef HAVE_POSIX_MEMALIGN
+	#undef opj_aligned_malloc
+	extern int posix_memalign(void**, size_t, size_t);
+
+	static INLINE void* __attribute__ ((malloc)) opj_aligned_malloc(size_t size){
+		void* mem = NULL;
+		posix_memalign(&mem, 16, size);
+		return mem;
+	}
+	#undef opj_aligned_free
+	#define opj_aligned_free(m) free(m)
+#endif
+
+#ifdef ALLOC_PERF_OPT
+	#undef opj_aligned_malloc
+	#define opj_aligned_malloc(size) opj_malloc(size)
+	#undef opj_aligned_free
+	#define opj_aligned_free(m) opj_free(m)
+#endif
+
+/**
+Reallocate memory blocks.
+ at param m Pointer to previously allocated memory block
+ at param s New size in bytes
+ at return Returns a void pointer to the reallocated (and possibly moved) memory block
+*/
+#ifdef ALLOC_PERF_OPT
+void * OPJ_CALLCONV opj_realloc(void * m, size_t s);
+#else
+/* prevent assertion on overflow for MSVC */
+#ifdef _MSC_VER
+#define opj_realloc(m, s) ((size_t)(s) >= (size_t)-0x100 ? NULL : realloc(m, s))
+#else
+#define opj_realloc(m, s) realloc(m, s)
+#endif
+#endif
+
+/**
+Deallocates or frees a memory block.
+ at param m Previously allocated memory block to be freed
+*/
+#ifdef ALLOC_PERF_OPT
+void OPJ_CALLCONV opj_free(void * m);
+#else
+#define opj_free(m) free(m)
+#endif
+
+#ifdef __GNUC__
+#pragma GCC poison malloc calloc realloc free
+#endif
+
+/* ----------------------------------------------------------------------- */
+/*@}*/
+
+/*@}*/
+
+#endif /* __OPJ_MALLOC_H */
+
diff --git a/Source/LibOpenJPEG/opj_stdint.h b/Source/LibOpenJPEG/opj_stdint.h
new file mode 100644
index 0000000..2d12180
--- /dev/null
+++ b/Source/LibOpenJPEG/opj_stdint.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2012, Mathieu Malaterre <mathieu.malaterre at gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef OPJ_STDINT_H
+#define OPJ_STDINT_H
+
+#include "opj_config.h"
+#ifdef OPJ_HAVE_STDINT_H
+#include <stdint.h>
+#else
+#if defined(_WIN32)
+typedef   signed __int8   int8_t;
+typedef unsigned __int8   uint8_t;
+typedef   signed __int16  int16_t;
+typedef unsigned __int16  uint16_t;
+typedef   signed __int32  int32_t;
+typedef unsigned __int32  uint32_t;
+typedef   signed __int64  int64_t;
+typedef unsigned __int64  uint64_t;
+#else
+#error unsupported platform
+#endif
+#endif
+
+#endif /* OPJ_STDINT_H */
diff --git a/Source/LibOpenJPEG/phix_manager.c b/Source/LibOpenJPEG/phix_manager.c
index f022773..5063a3c 100644
--- a/Source/LibOpenJPEG/phix_manager.c
+++ b/Source/LibOpenJPEG/phix_manager.c
@@ -1,5 +1,5 @@
 /*
- * $Id: phix_manager.c,v 1.2 2012/09/23 12:44:41 drolon Exp $
+ * $Id: phix_manager.c,v 1.4 2014/03/16 12:29:52 drolon Exp $
  *
  * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
  * Copyright (c) 2002-2011, Professor Benoit Macq
@@ -33,10 +33,9 @@
  *  \brief Modification of jpip.c from 2KAN indexer
  */
 
-#include <stdlib.h>
-#include <math.h>
 #include "opj_includes.h"
 
+
 /* 
  * Write faix box of phix
  *
@@ -48,50 +47,63 @@
  * @param[in] cio       file output handle
  * @return              length of faix box
  */
-int write_phixfaix( int coff, int compno, opj_codestream_info_t cstr_info, opj_bool EPHused, int j2klen, opj_cio_t *cio);
 
-int write_phix( int coff, opj_codestream_info_t cstr_info, opj_bool EPHused, int j2klen, opj_cio_t *cio)
+int opj_write_phix( int coff, opj_codestream_info_t cstr_info, OPJ_BOOL EPHused, int j2klen, opj_stream_private_t *cio,
+              opj_event_mgr_t * p_manager )
 {
-  int len, lenp=0, compno, i;
+  OPJ_BYTE l_data_header [8];
+  OPJ_UINT32 len, compno, i;
   opj_jp2_box_t *box;
+  OPJ_OFF_T lenp = 0;
 
-  box = (opj_jp2_box_t *)opj_calloc( cstr_info.numcomps, sizeof(opj_jp2_box_t));
+  box = (opj_jp2_box_t *)opj_calloc( (size_t)cstr_info.numcomps, sizeof(opj_jp2_box_t));
   
   for( i=0;i<2;i++){
-    if (i) cio_seek( cio, lenp);
+    if (i)
+      opj_stream_seek( cio, lenp, p_manager);
       
-    lenp = cio_tell( cio);
-    cio_skip( cio, 4);              /* L [at the end] */
-    cio_write( cio, JPIP_PHIX, 4);  /* PHIX           */
+    lenp = opj_stream_tell(cio);
+    opj_stream_skip(cio, 4, p_manager);         /* L [at the end]      */
+    opj_write_bytes(l_data_header,JPIP_PHIX,4); /* PHIX */
+    opj_stream_write_data(cio,l_data_header,4,p_manager);
       
-    write_manf( i, cstr_info.numcomps, box, cio);
+    opj_write_manf( (int)i, cstr_info.numcomps, box, cio, p_manager );
 
-    for( compno=0; compno<cstr_info.numcomps; compno++){       
-      box[compno].length = write_phixfaix( coff, compno, cstr_info, EPHused, j2klen, cio);
+    for( compno=0; compno<(OPJ_UINT32)cstr_info.numcomps; compno++){       
+      box[compno].length = (OPJ_UINT32)opj_write_phixfaix( coff, (int)compno, cstr_info, EPHused, j2klen, cio,p_manager);
       box[compno].type = JPIP_FAIX;
     }
 
-    len = cio_tell( cio)-lenp;
-    cio_seek( cio, lenp);
-    cio_write( cio, len, 4);        /* L              */
-    cio_seek( cio, lenp+len);
+    len = (OPJ_UINT32)(opj_stream_tell(cio)-lenp);
+    opj_stream_seek(cio, 4, p_manager);
+    opj_write_bytes(l_data_header,len,4);/* L              */
+    opj_stream_write_data(cio,l_data_header,4,p_manager);
+    opj_stream_seek( cio, lenp+len,p_manager);
   }
 
   opj_free(box);
 
-  return len;
+  return (int)len;
 }
 
-int write_phixfaix( int coff, int compno, opj_codestream_info_t cstr_info, opj_bool EPHused, int j2klen, opj_cio_t *cio)
+
+int opj_write_phixfaix( int coff, int compno, opj_codestream_info_t cstr_info, OPJ_BOOL EPHused, int j2klen, opj_stream_private_t *cio,
+              opj_event_mgr_t * p_manager )
 {
-  int len, lenp, tileno, version, i, nmax, size_of_coding; /* 4 or 8 */
+  OPJ_UINT32 tileno, version, i, nmax, size_of_coding; /* 4 or 8 */
   opj_tile_info_t *tile_Idx;
   opj_packet_info_t packet;
-  int resno, precno, layno, num_packet;
+  int resno, precno, layno;
+  OPJ_UINT32 num_packet;
   int numOfres, numOfprec, numOflayers;
+  OPJ_BYTE l_data_header [8];
+  OPJ_OFF_T lenp;
+  OPJ_UINT32 len;
+
   packet.end_ph_pos = packet.start_pos = -1;
   (void)EPHused; /* unused ? */
 
+
   if( j2klen > pow( 2, 32)){
     size_of_coding =  8;
     version = 1;
@@ -101,19 +113,23 @@ int write_phixfaix( int coff, int compno, opj_codestream_info_t cstr_info, opj_b
     version = 0;
   }
 
-  lenp = cio_tell( cio);
-  cio_skip( cio, 4);              /* L [at the end]      */
-  cio_write( cio, JPIP_FAIX, 4);  /* FAIX                */ 
-  cio_write( cio, version,1);     /* Version 0 = 4 bytes */
+  lenp = opj_stream_tell(cio);
+  opj_stream_skip(cio, 4, p_manager);         /* L [at the end]      */
+  opj_write_bytes(l_data_header,JPIP_FAIX,4); /* FAIX */
+  opj_stream_write_data(cio,l_data_header,4,p_manager);
+  opj_write_bytes(l_data_header,version,1);   /* Version 0 = 4 bytes */
+  opj_stream_write_data(cio,l_data_header,1,p_manager);
 
   nmax = 0;
-  for( i=0; i<=cstr_info.numdecompos[compno]; i++)
-    nmax += cstr_info.tile[0].ph[i] * cstr_info.tile[0].pw[i] * cstr_info.numlayers;
+  for( i=0; i<=(OPJ_UINT32)cstr_info.numdecompos[compno]; i++)
+    nmax += (OPJ_UINT32)(cstr_info.tile[0].ph[i] * cstr_info.tile[0].pw[i] * cstr_info.numlayers);
   
-  cio_write( cio, nmax, size_of_coding); /* NMAX */
-  cio_write( cio, cstr_info.tw*cstr_info.th, size_of_coding);      /* M    */
+  opj_write_bytes(l_data_header,nmax,size_of_coding);         /* NMAX           */
+  opj_stream_write_data(cio,l_data_header,size_of_coding,p_manager);
+  opj_write_bytes(l_data_header,(OPJ_UINT32)(cstr_info.tw*cstr_info.th),size_of_coding);  /* M              */
+  opj_stream_write_data(cio,l_data_header,size_of_coding,p_manager);
   
-  for( tileno=0; tileno<cstr_info.tw*cstr_info.th; tileno++){
+  for( tileno=0; tileno<(OPJ_UINT32)(cstr_info.tw*cstr_info.th); tileno++){
     tile_Idx = &cstr_info.tile[ tileno];
     
     num_packet = 0;
@@ -126,27 +142,29 @@ int write_phixfaix( int coff, int compno, opj_codestream_info_t cstr_info, opj_b
 	for( layno=0; layno<numOflayers; layno++){
 	  
 	  switch ( cstr_info.prog){
-	  case LRCP:
+	  case OPJ_LRCP:
 	    packet = tile_Idx->packet[ ((layno*numOfres+resno)*cstr_info.numcomps+compno)*numOfprec+precno];
 	    break;
-	  case RLCP:
+	  case OPJ_RLCP:
 	    packet = tile_Idx->packet[ ((resno*numOflayers+layno)*cstr_info.numcomps+compno)*numOfprec+precno];
 	    break;
-	  case RPCL:
+	  case OPJ_RPCL:
 	    packet = tile_Idx->packet[ ((resno*numOfprec+precno)*cstr_info.numcomps+compno)*numOflayers+layno];
 	    break;
-	  case PCRL:
+	  case OPJ_PCRL:
 	    packet = tile_Idx->packet[ ((precno*cstr_info.numcomps+compno)*numOfres+resno)*numOflayers + layno];
 	    break;
-	  case CPRL:
+	  case OPJ_CPRL:
 	    packet = tile_Idx->packet[ ((compno*numOfprec+precno)*numOfres+resno)*numOflayers + layno];
 	    break;
 	  default:
 	    fprintf( stderr, "failed to ppix indexing\n");
 	  }
 
-	  cio_write( cio, packet.start_pos-coff, size_of_coding);                /* start position */
-	  cio_write( cio, packet.end_ph_pos-packet.start_pos+1, size_of_coding); /* length         */
+    opj_write_bytes(l_data_header,(OPJ_UINT32)(packet.start_pos-coff),size_of_coding);            /* start position */
+    opj_stream_write_data(cio,l_data_header,size_of_coding,p_manager);
+    opj_write_bytes(l_data_header,(OPJ_UINT32)(packet.end_ph_pos-packet.start_pos+1),size_of_coding); /* length         */
+    opj_stream_write_data(cio,l_data_header,size_of_coding,p_manager);
 	  
 	  num_packet++;
 	}
@@ -155,16 +173,19 @@ int write_phixfaix( int coff, int compno, opj_codestream_info_t cstr_info, opj_b
 
     /* PADDING */
     while( num_packet < nmax){
-      cio_write( cio, 0, size_of_coding); /* start position            */
-      cio_write( cio, 0, size_of_coding); /* length                    */
+      opj_write_bytes(l_data_header,0,size_of_coding);/* start position            */
+      opj_stream_write_data(cio,l_data_header,size_of_coding,p_manager);
+      opj_write_bytes(l_data_header,0,size_of_coding);/* length                    */
+      opj_stream_write_data(cio,l_data_header,size_of_coding,p_manager);
       num_packet++;
     }
   }
 
-  len = cio_tell( cio)-lenp;
-  cio_seek( cio, lenp);
-  cio_write( cio, len, 4);        /* L  */
-  cio_seek( cio, lenp+len);
+  len = (OPJ_UINT32)(opj_stream_tell(cio)-lenp);
+  opj_stream_seek(cio, lenp,p_manager);
+  opj_write_bytes(l_data_header,len,4);/* L  */
+  opj_stream_write_data(cio,l_data_header,4,p_manager);
+  opj_stream_seek(cio, lenp+len,p_manager);
 
-  return len;
+  return (int)len;
 }
diff --git a/Source/LibOpenJPEG/pi.c b/Source/LibOpenJPEG/pi.c
index 706053b..2606051 100644
--- a/Source/LibOpenJPEG/pi.c
+++ b/Source/LibOpenJPEG/pi.c
@@ -1,963 +1,1870 @@
-/*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
- * Copyright (c) 2001-2003, David Janssens
- * Copyright (c) 2002-2003, Yannick Verschueren
- * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * Copyright (c) 2006-2007, Parvatha Elangovan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "opj_includes.h"
-
-/** @defgroup PI PI - Implementation of a packet iterator */
-/*@{*/
-
-/** @name Local static functions */
-/*@{*/
-
-/**
-Get next packet in layer-resolution-component-precinct order.
- at param pi packet iterator to modify
- at return returns false if pi pointed to the last packet or else returns true 
-*/
-static opj_bool pi_next_lrcp(opj_pi_iterator_t * pi);
-/**
-Get next packet in resolution-layer-component-precinct order.
- at param pi packet iterator to modify
- at return returns false if pi pointed to the last packet or else returns true 
-*/
-static opj_bool pi_next_rlcp(opj_pi_iterator_t * pi);
-/**
-Get next packet in resolution-precinct-component-layer order.
- at param pi packet iterator to modify
- at return returns false if pi pointed to the last packet or else returns true 
-*/
-static opj_bool pi_next_rpcl(opj_pi_iterator_t * pi);
-/**
-Get next packet in precinct-component-resolution-layer order.
- at param pi packet iterator to modify
- at return returns false if pi pointed to the last packet or else returns true 
-*/
-static opj_bool pi_next_pcrl(opj_pi_iterator_t * pi);
-/**
-Get next packet in component-precinct-resolution-layer order.
- at param pi packet iterator to modify
- at return returns false if pi pointed to the last packet or else returns true 
-*/
-static opj_bool pi_next_cprl(opj_pi_iterator_t * pi);
-
-/*@}*/
-
-/*@}*/
-
-/* 
-==========================================================
-   local functions
-==========================================================
-*/
-
-static opj_bool pi_next_lrcp(opj_pi_iterator_t * pi) {
-	opj_pi_comp_t *comp = NULL;
-	opj_pi_resolution_t *res = NULL;
-	long index = 0;
-	
-	if (!pi->first) {
-		comp = &pi->comps[pi->compno];
-		res = &comp->resolutions[pi->resno];
-		goto LABEL_SKIP;
-	} else {
-		pi->first = 0;
-	}
-
-	for (pi->layno = pi->poc.layno0; pi->layno < pi->poc.layno1; pi->layno++) {
-		for (pi->resno = pi->poc.resno0; pi->resno < pi->poc.resno1;
-		pi->resno++) {
-			for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) {
-				comp = &pi->comps[pi->compno];
-				if (pi->resno >= comp->numresolutions) {
-					continue;
-				}
-				res = &comp->resolutions[pi->resno];
-				if (!pi->tp_on){
-					pi->poc.precno1 = res->pw * res->ph;
-				}
-				for (pi->precno = pi->poc.precno0; pi->precno < pi->poc.precno1; pi->precno++) {
-					index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;
-					if (!pi->include[index]) {
-						pi->include[index] = 1;
-						return OPJ_TRUE;
-					}
-LABEL_SKIP:;
-				}
-			}
-		}
-	}
-	
-	return OPJ_FALSE;
-}
-
-static opj_bool pi_next_rlcp(opj_pi_iterator_t * pi) {
-	opj_pi_comp_t *comp = NULL;
-	opj_pi_resolution_t *res = NULL;
-	long index = 0;
-
-	if (!pi->first) {
-		comp = &pi->comps[pi->compno];
-		res = &comp->resolutions[pi->resno];
-		goto LABEL_SKIP;
-	} else {
-		pi->first = 0;
-	}
-
-	for (pi->resno = pi->poc.resno0; pi->resno < pi->poc.resno1; pi->resno++) {
-		for (pi->layno = pi->poc.layno0; pi->layno < pi->poc.layno1; pi->layno++) {
-			for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) {
-				comp = &pi->comps[pi->compno];
-				if (pi->resno >= comp->numresolutions) {
-					continue;
-				}
-				res = &comp->resolutions[pi->resno];
-				if(!pi->tp_on){
-					pi->poc.precno1 = res->pw * res->ph;
-				}
-				for (pi->precno = pi->poc.precno0; pi->precno < pi->poc.precno1; pi->precno++) {
-					index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;
-					if (!pi->include[index]) {
-						pi->include[index] = 1;
-						return OPJ_TRUE;
-					}
-LABEL_SKIP:;
-				}
-			}
-		}
-	}
-	
-	return OPJ_FALSE;
-}
-
-static opj_bool pi_next_rpcl(opj_pi_iterator_t * pi) {
-	opj_pi_comp_t *comp = NULL;
-	opj_pi_resolution_t *res = NULL;
-	long index = 0;
-
-	if (!pi->first) {
-		goto LABEL_SKIP;
-	} else {
-		int compno, resno;
-		pi->first = 0;
-		pi->dx = 0;
-		pi->dy = 0;
-		for (compno = 0; compno < pi->numcomps; compno++) {
-			comp = &pi->comps[compno];
-			for (resno = 0; resno < comp->numresolutions; resno++) {
-				int dx, dy;
-				res = &comp->resolutions[resno];
-				dx = comp->dx * (1 << (res->pdx + comp->numresolutions - 1 - resno));
-				dy = comp->dy * (1 << (res->pdy + comp->numresolutions - 1 - resno));
-				pi->dx = !pi->dx ? dx : int_min(pi->dx, dx);
-				pi->dy = !pi->dy ? dy : int_min(pi->dy, dy);
-			}
-		}
-	}
-if (!pi->tp_on){
-			pi->poc.ty0 = pi->ty0;
-			pi->poc.tx0 = pi->tx0;
-			pi->poc.ty1 = pi->ty1;
-			pi->poc.tx1 = pi->tx1;
-		}
-	for (pi->resno = pi->poc.resno0; pi->resno < pi->poc.resno1; pi->resno++) {
-		for (pi->y = pi->poc.ty0; pi->y < pi->poc.ty1; pi->y += pi->dy - (pi->y % pi->dy)) {
-			for (pi->x = pi->poc.tx0; pi->x < pi->poc.tx1; pi->x += pi->dx - (pi->x % pi->dx)) {
-				for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) {
-					int levelno;
-					int trx0, try0;
-					int trx1, try1;
-					int rpx, rpy;
-					int prci, prcj;
-					comp = &pi->comps[pi->compno];
-					if (pi->resno >= comp->numresolutions) {
-						continue;
-					}
-					res = &comp->resolutions[pi->resno];
-					levelno = comp->numresolutions - 1 - pi->resno;
-					trx0 = int_ceildiv(pi->tx0, comp->dx << levelno);
-					try0 = int_ceildiv(pi->ty0, comp->dy << levelno);
-					trx1 = int_ceildiv(pi->tx1, comp->dx << levelno);
-					try1 = int_ceildiv(pi->ty1, comp->dy << levelno);
-					rpx = res->pdx + levelno;
-					rpy = res->pdy + levelno;
-					if (!((pi->y % (comp->dy << rpy) == 0) || ((pi->y == pi->ty0) && ((try0 << levelno) % (1 << rpy))))){
-						continue;	
-					}
-					if (!((pi->x % (comp->dx << rpx) == 0) || ((pi->x == pi->tx0) && ((trx0 << levelno) % (1 << rpx))))){
-						continue; 
-					}
-					
-					if ((res->pw==0)||(res->ph==0)) continue;
-					
-					if ((trx0==trx1)||(try0==try1)) continue;
-					
-					prci = int_floordivpow2(int_ceildiv(pi->x, comp->dx << levelno), res->pdx) 
-						 - int_floordivpow2(trx0, res->pdx);
-					prcj = int_floordivpow2(int_ceildiv(pi->y, comp->dy << levelno), res->pdy) 
-						 - int_floordivpow2(try0, res->pdy);
-					pi->precno = prci + prcj * res->pw;
-					for (pi->layno = pi->poc.layno0; pi->layno < pi->poc.layno1; pi->layno++) {
-						index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;
-						if (!pi->include[index]) {
-							pi->include[index] = 1;
-							return OPJ_TRUE;
-						}
-LABEL_SKIP:;
-					}
-				}
-			}
-		}
-	}
-	
-	return OPJ_FALSE;
-}
-
-static opj_bool pi_next_pcrl(opj_pi_iterator_t * pi) {
-	opj_pi_comp_t *comp = NULL;
-	opj_pi_resolution_t *res = NULL;
-	long index = 0;
-
-	if (!pi->first) {
-		comp = &pi->comps[pi->compno];
-		goto LABEL_SKIP;
-	} else {
-		int compno, resno;
-		pi->first = 0;
-		pi->dx = 0;
-		pi->dy = 0;
-		for (compno = 0; compno < pi->numcomps; compno++) {
-			comp = &pi->comps[compno];
-			for (resno = 0; resno < comp->numresolutions; resno++) {
-				int dx, dy;
-				res = &comp->resolutions[resno];
-				dx = comp->dx * (1 << (res->pdx + comp->numresolutions - 1 - resno));
-				dy = comp->dy * (1 << (res->pdy + comp->numresolutions - 1 - resno));
-				pi->dx = !pi->dx ? dx : int_min(pi->dx, dx);
-				pi->dy = !pi->dy ? dy : int_min(pi->dy, dy);
-			}
-		}
-	}
-	if (!pi->tp_on){
-			pi->poc.ty0 = pi->ty0;
-			pi->poc.tx0 = pi->tx0;
-			pi->poc.ty1 = pi->ty1;
-			pi->poc.tx1 = pi->tx1;
-		}
-	for (pi->y = pi->poc.ty0; pi->y < pi->poc.ty1; pi->y += pi->dy - (pi->y % pi->dy)) {
-		for (pi->x = pi->poc.tx0; pi->x < pi->poc.tx1; pi->x += pi->dx - (pi->x % pi->dx)) {
-			for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) {
-				comp = &pi->comps[pi->compno];
-				for (pi->resno = pi->poc.resno0; pi->resno < int_min(pi->poc.resno1, comp->numresolutions); pi->resno++) {
-					int levelno;
-					int trx0, try0;
-					int trx1, try1;
-					int rpx, rpy;
-					int prci, prcj;
-					res = &comp->resolutions[pi->resno];
-					levelno = comp->numresolutions - 1 - pi->resno;
-					trx0 = int_ceildiv(pi->tx0, comp->dx << levelno);
-					try0 = int_ceildiv(pi->ty0, comp->dy << levelno);
-					trx1 = int_ceildiv(pi->tx1, comp->dx << levelno);
-					try1 = int_ceildiv(pi->ty1, comp->dy << levelno);
-					rpx = res->pdx + levelno;
-					rpy = res->pdy + levelno;
-					if (!((pi->y % (comp->dy << rpy) == 0) || ((pi->y == pi->ty0) && ((try0 << levelno) % (1 << rpy))))){
-						continue;	
-					}
-					if (!((pi->x % (comp->dx << rpx) == 0) || ((pi->x == pi->tx0) && ((trx0 << levelno) % (1 << rpx))))){
-						continue; 
-					}
-					
-					if ((res->pw==0)||(res->ph==0)) continue;
-					
-					if ((trx0==trx1)||(try0==try1)) continue;
-					
-					prci = int_floordivpow2(int_ceildiv(pi->x, comp->dx << levelno), res->pdx) 
-						 - int_floordivpow2(trx0, res->pdx);
-					prcj = int_floordivpow2(int_ceildiv(pi->y, comp->dy << levelno), res->pdy) 
-						 - int_floordivpow2(try0, res->pdy);
-					pi->precno = prci + prcj * res->pw;
-					for (pi->layno = pi->poc.layno0; pi->layno < pi->poc.layno1; pi->layno++) {
-						index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;
-						if (!pi->include[index]) {
-							pi->include[index] = 1;
-							return OPJ_TRUE;
-						}	
-LABEL_SKIP:;
-					}
-				}
-			}
-		}
-	}
-	
-	return OPJ_FALSE;
-}
-
-static opj_bool pi_next_cprl(opj_pi_iterator_t * pi) {
-	opj_pi_comp_t *comp = NULL;
-	opj_pi_resolution_t *res = NULL;
-	long index = 0;
-
-	if (!pi->first) {
-		comp = &pi->comps[pi->compno];
-		goto LABEL_SKIP;
-	} else {
-		pi->first = 0;
-	}
-
-	for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) {
-		int resno;
-		comp = &pi->comps[pi->compno];
-		pi->dx = 0;
-		pi->dy = 0;
-		for (resno = 0; resno < comp->numresolutions; resno++) {
-			int dx, dy;
-			res = &comp->resolutions[resno];
-			dx = comp->dx * (1 << (res->pdx + comp->numresolutions - 1 - resno));
-			dy = comp->dy * (1 << (res->pdy + comp->numresolutions - 1 - resno));
-			pi->dx = !pi->dx ? dx : int_min(pi->dx, dx);
-			pi->dy = !pi->dy ? dy : int_min(pi->dy, dy);
-		}
-		if (!pi->tp_on){
-			pi->poc.ty0 = pi->ty0;
-			pi->poc.tx0 = pi->tx0;
-			pi->poc.ty1 = pi->ty1;
-			pi->poc.tx1 = pi->tx1;
-		}
-		for (pi->y = pi->poc.ty0; pi->y < pi->poc.ty1; pi->y += pi->dy - (pi->y % pi->dy)) {
-			for (pi->x = pi->poc.tx0; pi->x < pi->poc.tx1; pi->x += pi->dx - (pi->x % pi->dx)) {
-				for (pi->resno = pi->poc.resno0; pi->resno < int_min(pi->poc.resno1, comp->numresolutions); pi->resno++) {
-					int levelno;
-					int trx0, try0;
-					int trx1, try1;
-					int rpx, rpy;
-					int prci, prcj;
-					res = &comp->resolutions[pi->resno];
-					levelno = comp->numresolutions - 1 - pi->resno;
-					trx0 = int_ceildiv(pi->tx0, comp->dx << levelno);
-					try0 = int_ceildiv(pi->ty0, comp->dy << levelno);
-					trx1 = int_ceildiv(pi->tx1, comp->dx << levelno);
-					try1 = int_ceildiv(pi->ty1, comp->dy << levelno);
-					rpx = res->pdx + levelno;
-					rpy = res->pdy + levelno;
-					if (!((pi->y % (comp->dy << rpy) == 0) || ((pi->y == pi->ty0) && ((try0 << levelno) % (1 << rpy))))){
-						continue;	
-					}
-					if (!((pi->x % (comp->dx << rpx) == 0) || ((pi->x == pi->tx0) && ((trx0 << levelno) % (1 << rpx))))){
-						continue; 
-					}
-					
-					if ((res->pw==0)||(res->ph==0)) continue;
-					
-					if ((trx0==trx1)||(try0==try1)) continue;
-					
-					prci = int_floordivpow2(int_ceildiv(pi->x, comp->dx << levelno), res->pdx) 
-						 - int_floordivpow2(trx0, res->pdx);
-					prcj = int_floordivpow2(int_ceildiv(pi->y, comp->dy << levelno), res->pdy) 
-						 - int_floordivpow2(try0, res->pdy);
-					pi->precno = prci + prcj * res->pw;
-					for (pi->layno = pi->poc.layno0; pi->layno < pi->poc.layno1; pi->layno++) {
-						index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;
-						if (!pi->include[index]) {
-							pi->include[index] = 1;
-							return OPJ_TRUE;
-						}
-LABEL_SKIP:;
-					}
-				}
-			}
-		}
-	}
-	
-	return OPJ_FALSE;
-}
-
-/* 
-==========================================================
-   Packet iterator interface
-==========================================================
-*/
-
-opj_pi_iterator_t *pi_create_decode(opj_image_t *image, opj_cp_t *cp, int tileno) {
-	int p, q;
-	int compno, resno, pino;
-	opj_pi_iterator_t *pi = NULL;
-	opj_tcp_t *tcp = NULL;
-	opj_tccp_t *tccp = NULL;
-
-	tcp = &cp->tcps[tileno];
-
-	pi = (opj_pi_iterator_t*) opj_calloc((tcp->numpocs + 1), sizeof(opj_pi_iterator_t));
-	if(!pi) {
-		/* TODO: throw an error */
-		return NULL;
-	}
-
-	for (pino = 0; pino < tcp->numpocs + 1; pino++) {	/* change */
-		int maxres = 0;
-		int maxprec = 0;
-		p = tileno % cp->tw;
-		q = tileno / cp->tw;
-
-		pi[pino].tx0 = int_max(cp->tx0 + p * cp->tdx, image->x0);
-		pi[pino].ty0 = int_max(cp->ty0 + q * cp->tdy, image->y0);
-		pi[pino].tx1 = int_min(cp->tx0 + (p + 1) * cp->tdx, image->x1);
-		pi[pino].ty1 = int_min(cp->ty0 + (q + 1) * cp->tdy, image->y1);
-		pi[pino].numcomps = image->numcomps;
-
-		pi[pino].comps = (opj_pi_comp_t*) opj_calloc(image->numcomps, sizeof(opj_pi_comp_t));
-		if(!pi[pino].comps) {
-			/* TODO: throw an error */
-			pi_destroy(pi, cp, tileno);
-			return NULL;
-		}
-		
-		for (compno = 0; compno < pi->numcomps; compno++) {
-			int tcx0, tcy0, tcx1, tcy1;
-			opj_pi_comp_t *comp = &pi[pino].comps[compno];
-			tccp = &tcp->tccps[compno];
-			comp->dx = image->comps[compno].dx;
-			comp->dy = image->comps[compno].dy;
-			comp->numresolutions = tccp->numresolutions;
-
-			comp->resolutions = (opj_pi_resolution_t*) opj_calloc(comp->numresolutions, sizeof(opj_pi_resolution_t));
-			if(!comp->resolutions) {
-				/* TODO: throw an error */
-				pi_destroy(pi, cp, tileno);
-				return NULL;
-			}
-
-			tcx0 = int_ceildiv(pi->tx0, comp->dx);
-			tcy0 = int_ceildiv(pi->ty0, comp->dy);
-			tcx1 = int_ceildiv(pi->tx1, comp->dx);
-			tcy1 = int_ceildiv(pi->ty1, comp->dy);
-			if (comp->numresolutions > maxres) {
-				maxres = comp->numresolutions;
-			}
-
-			for (resno = 0; resno < comp->numresolutions; resno++) {
-				int levelno;
-				int rx0, ry0, rx1, ry1;
-				int px0, py0, px1, py1;
-				opj_pi_resolution_t *res = &comp->resolutions[resno];
-				if (tccp->csty & J2K_CCP_CSTY_PRT) {
-					res->pdx = tccp->prcw[resno];
-					res->pdy = tccp->prch[resno];
-				} else {
-					res->pdx = 15;
-					res->pdy = 15;
-				}
-				levelno = comp->numresolutions - 1 - resno;
-				rx0 = int_ceildivpow2(tcx0, levelno);
-				ry0 = int_ceildivpow2(tcy0, levelno);
-				rx1 = int_ceildivpow2(tcx1, levelno);
-				ry1 = int_ceildivpow2(tcy1, levelno);
-				px0 = int_floordivpow2(rx0, res->pdx) << res->pdx;
-				py0 = int_floordivpow2(ry0, res->pdy) << res->pdy;
-				px1 = int_ceildivpow2(rx1, res->pdx) << res->pdx;
-				py1 = int_ceildivpow2(ry1, res->pdy) << res->pdy;
-				res->pw = (rx0==rx1)?0:((px1 - px0) >> res->pdx);
-				res->ph = (ry0==ry1)?0:((py1 - py0) >> res->pdy);
-				
-				if (res->pw*res->ph > maxprec) {
-					maxprec = res->pw*res->ph;
-				}
-				
-			}
-		}
-		
-		tccp = &tcp->tccps[0];
-		pi[pino].step_p = 1;
-		pi[pino].step_c = maxprec * pi[pino].step_p;
-		pi[pino].step_r = image->numcomps * pi[pino].step_c;
-		pi[pino].step_l = maxres * pi[pino].step_r;
-		
-		if (pino == 0) {
-			pi[pino].include = (short int*) opj_calloc(image->numcomps * maxres * tcp->numlayers * maxprec, sizeof(short int));
-			if(!pi[pino].include) {
-				/* TODO: throw an error */
-				pi_destroy(pi, cp, tileno);
-				return NULL;
-			}
-		}
-		else {
-			pi[pino].include = pi[pino - 1].include;
-		}
-		
-		if (tcp->POC == 0) {
-			pi[pino].first = 1;
-			pi[pino].poc.resno0 = 0;
-			pi[pino].poc.compno0 = 0;
-			pi[pino].poc.layno1 = tcp->numlayers;
-			pi[pino].poc.resno1 = maxres;
-			pi[pino].poc.compno1 = image->numcomps;
-			pi[pino].poc.prg = tcp->prg;
-		} else {
-			pi[pino].first = 1;
-			pi[pino].poc.resno0 = tcp->pocs[pino].resno0;
-			pi[pino].poc.compno0 = tcp->pocs[pino].compno0;
-			pi[pino].poc.layno1 = tcp->pocs[pino].layno1;
-			pi[pino].poc.resno1 = tcp->pocs[pino].resno1;
-			pi[pino].poc.compno1 = tcp->pocs[pino].compno1;
-			pi[pino].poc.prg = tcp->pocs[pino].prg;
-		}
-		pi[pino].poc.layno0  = 0;
-		pi[pino].poc.precno0 = 0; 
-		pi[pino].poc.precno1 = maxprec;
-			
-	}
-	
-	return pi;
-}
-
-
-opj_pi_iterator_t *pi_initialise_encode(opj_image_t *image, opj_cp_t *cp, int tileno, J2K_T2_MODE t2_mode){ 
-	int p, q, pino;
-	int compno, resno;
-	int maxres = 0;
-	int maxprec = 0;
-	opj_pi_iterator_t *pi = NULL;
-	opj_tcp_t *tcp = NULL;
-	opj_tccp_t *tccp = NULL;
-	
-	tcp = &cp->tcps[tileno];
-
-	pi = (opj_pi_iterator_t*) opj_calloc((tcp->numpocs + 1), sizeof(opj_pi_iterator_t));
-	if(!pi) {	return NULL;}
-	pi->tp_on = cp->tp_on;
-
-	for(pino = 0;pino < tcp->numpocs+1 ; pino ++){
-		p = tileno % cp->tw;
-		q = tileno / cp->tw;
-
-		pi[pino].tx0 = int_max(cp->tx0 + p * cp->tdx, image->x0);
-		pi[pino].ty0 = int_max(cp->ty0 + q * cp->tdy, image->y0);
-		pi[pino].tx1 = int_min(cp->tx0 + (p + 1) * cp->tdx, image->x1);
-		pi[pino].ty1 = int_min(cp->ty0 + (q + 1) * cp->tdy, image->y1);
-		pi[pino].numcomps = image->numcomps;
-		
-		pi[pino].comps = (opj_pi_comp_t*) opj_calloc(image->numcomps, sizeof(opj_pi_comp_t));
-		if(!pi[pino].comps) {
-			pi_destroy(pi, cp, tileno);
-			return NULL;
-		}
-		
-		for (compno = 0; compno < pi[pino].numcomps; compno++) {
-			int tcx0, tcy0, tcx1, tcy1;
-			opj_pi_comp_t *comp = &pi[pino].comps[compno];
-			tccp = &tcp->tccps[compno];
-			comp->dx = image->comps[compno].dx;
-			comp->dy = image->comps[compno].dy;
-			comp->numresolutions = tccp->numresolutions;
-
-			comp->resolutions = (opj_pi_resolution_t*) opj_malloc(comp->numresolutions * sizeof(opj_pi_resolution_t));
-			if(!comp->resolutions) {
-				pi_destroy(pi, cp, tileno);
-				return NULL;
-			}
-
-			tcx0 = int_ceildiv(pi[pino].tx0, comp->dx);
-			tcy0 = int_ceildiv(pi[pino].ty0, comp->dy);
-			tcx1 = int_ceildiv(pi[pino].tx1, comp->dx);
-			tcy1 = int_ceildiv(pi[pino].ty1, comp->dy);
-			if (comp->numresolutions > maxres) {
-				maxres = comp->numresolutions;
-			}
-
-			for (resno = 0; resno < comp->numresolutions; resno++) {
-				int levelno;
-				int rx0, ry0, rx1, ry1;
-				int px0, py0, px1, py1;
-				opj_pi_resolution_t *res = &comp->resolutions[resno];
-				if (tccp->csty & J2K_CCP_CSTY_PRT) {
-					res->pdx = tccp->prcw[resno];
-					res->pdy = tccp->prch[resno];
-				} else {
-					res->pdx = 15;
-					res->pdy = 15;
-				}
-				levelno = comp->numresolutions - 1 - resno;
-				rx0 = int_ceildivpow2(tcx0, levelno);
-				ry0 = int_ceildivpow2(tcy0, levelno);
-				rx1 = int_ceildivpow2(tcx1, levelno);
-				ry1 = int_ceildivpow2(tcy1, levelno);
-				px0 = int_floordivpow2(rx0, res->pdx) << res->pdx;
-				py0 = int_floordivpow2(ry0, res->pdy) << res->pdy;
-				px1 = int_ceildivpow2(rx1, res->pdx) << res->pdx;
-				py1 = int_ceildivpow2(ry1, res->pdy) << res->pdy;
-				res->pw = (rx0==rx1)?0:((px1 - px0) >> res->pdx);
-				res->ph = (ry0==ry1)?0:((py1 - py0) >> res->pdy);
-
-				if (res->pw*res->ph > maxprec) {
-					maxprec = res->pw * res->ph;
-				}
-			}
-		}
-		
-		tccp = &tcp->tccps[0];
-		pi[pino].step_p = 1;
-		pi[pino].step_c = maxprec * pi[pino].step_p;
-		pi[pino].step_r = image->numcomps * pi[pino].step_c;
-		pi[pino].step_l = maxres * pi[pino].step_r;
-		
-		for (compno = 0; compno < pi->numcomps; compno++) {
-			opj_pi_comp_t *comp = &pi->comps[compno];
-			for (resno = 0; resno < comp->numresolutions; resno++) {
-				int dx, dy;
-				opj_pi_resolution_t *res = &comp->resolutions[resno];
-				dx = comp->dx * (1 << (res->pdx + comp->numresolutions - 1 - resno));
-				dy = comp->dy * (1 << (res->pdy + comp->numresolutions - 1 - resno));
-				pi[pino].dx = !pi->dx ? dx : int_min(pi->dx, dx);
-				pi[pino].dy = !pi->dy ? dy : int_min(pi->dy, dy);
-			}
-		}
-
-		if (pino == 0) {
-			pi[pino].include = (short int*) opj_calloc(tcp->numlayers * pi[pino].step_l, sizeof(short int));
-			if(!pi[pino].include) {
-				pi_destroy(pi, cp, tileno);
-				return NULL;
-			}
-		}
-		else {
-			pi[pino].include = pi[pino - 1].include;
-		}
-		
-		/* Generation of boundaries for each prog flag*/
-			if(tcp->POC && ( cp->cinema || ((!cp->cinema) && (t2_mode == FINAL_PASS)))){
-				tcp->pocs[pino].compS= tcp->pocs[pino].compno0;
-				tcp->pocs[pino].compE= tcp->pocs[pino].compno1;
-				tcp->pocs[pino].resS = tcp->pocs[pino].resno0;
-				tcp->pocs[pino].resE = tcp->pocs[pino].resno1;
-				tcp->pocs[pino].layE = tcp->pocs[pino].layno1;
-				tcp->pocs[pino].prg  = tcp->pocs[pino].prg1;
-				if (pino > 0)
-					tcp->pocs[pino].layS = (tcp->pocs[pino].layE > tcp->pocs[pino - 1].layE) ? tcp->pocs[pino - 1].layE : 0;
-			}else {
-				tcp->pocs[pino].compS= 0;
-				tcp->pocs[pino].compE= image->numcomps;
-				tcp->pocs[pino].resS = 0;
-				tcp->pocs[pino].resE = maxres;
-				tcp->pocs[pino].layS = 0;
-				tcp->pocs[pino].layE = tcp->numlayers;
-				tcp->pocs[pino].prg  = tcp->prg;
-			}
-			tcp->pocs[pino].prcS = 0;
-			tcp->pocs[pino].prcE = maxprec;;
-			tcp->pocs[pino].txS = pi[pino].tx0;
-			tcp->pocs[pino].txE = pi[pino].tx1;
-			tcp->pocs[pino].tyS = pi[pino].ty0;
-			tcp->pocs[pino].tyE = pi[pino].ty1;
-			tcp->pocs[pino].dx = pi[pino].dx;
-			tcp->pocs[pino].dy = pi[pino].dy;
-		}
-			return pi;
-	}
-
-
-
-void pi_destroy(opj_pi_iterator_t *pi, opj_cp_t *cp, int tileno) {
-	int compno, pino;
-	opj_tcp_t *tcp = &cp->tcps[tileno];
-	if(pi) {
-		for (pino = 0; pino < tcp->numpocs + 1; pino++) {	
-			if(pi[pino].comps) {
-				for (compno = 0; compno < pi->numcomps; compno++) {
-					opj_pi_comp_t *comp = &pi[pino].comps[compno];
-					if(comp->resolutions) {
-						opj_free(comp->resolutions);
-					}
-				}
-				opj_free(pi[pino].comps);
-			}
-		}
-		if(pi->include) {
-			opj_free(pi->include);
-		}
-		opj_free(pi);
-	}
-}
-
-opj_bool pi_next(opj_pi_iterator_t * pi) {
-	switch (pi->poc.prg) {
-		case LRCP:
-			return pi_next_lrcp(pi);
-		case RLCP:
-			return pi_next_rlcp(pi);
-		case RPCL:
-			return pi_next_rpcl(pi);
-		case PCRL:
-			return pi_next_pcrl(pi);
-		case CPRL:
-			return pi_next_cprl(pi);
-		case PROG_UNKNOWN:
-			return OPJ_FALSE;
-	}
-	
-	return OPJ_FALSE;
-}
-
-opj_bool pi_create_encode( opj_pi_iterator_t *pi, opj_cp_t *cp,int tileno, int pino,int tpnum, int tppos, J2K_T2_MODE t2_mode,int cur_totnum_tp){
-	char prog[4];
-	int i;
-	int incr_top=1,resetX=0;
-	opj_tcp_t *tcps =&cp->tcps[tileno];
-	opj_poc_t *tcp= &tcps->pocs[pino];
-
-	pi[pino].first = 1;
-	pi[pino].poc.prg = tcp->prg;
-
-	switch(tcp->prg){
-		case CPRL: strncpy(prog, "CPRL",4);
-			break;
-		case LRCP: strncpy(prog, "LRCP",4);
-			break;
-		case PCRL: strncpy(prog, "PCRL",4);
-			break;
-		case RLCP: strncpy(prog, "RLCP",4);
-			break;
-		case RPCL: strncpy(prog, "RPCL",4);
-			break;
-		case PROG_UNKNOWN: 
-			return OPJ_TRUE;
-	}
-
-	if(!(cp->tp_on && ((!cp->cinema && (t2_mode == FINAL_PASS)) || cp->cinema))){
-		pi[pino].poc.resno0 = tcp->resS;
-		pi[pino].poc.resno1 = tcp->resE;
-		pi[pino].poc.compno0 = tcp->compS;
-		pi[pino].poc.compno1 = tcp->compE;
-		pi[pino].poc.layno0 = tcp->layS;
-		pi[pino].poc.layno1 = tcp->layE;
-		pi[pino].poc.precno0 = tcp->prcS;
-		pi[pino].poc.precno1 = tcp->prcE;
-		pi[pino].poc.tx0 = tcp->txS;
-		pi[pino].poc.ty0 = tcp->tyS;
-		pi[pino].poc.tx1 = tcp->txE;
-		pi[pino].poc.ty1 = tcp->tyE;
-	}else {
-		if( tpnum < cur_totnum_tp){
-			for(i=3;i>=0;i--){
-				switch(prog[i]){
-				case 'C':
-					if (i > tppos){
-						pi[pino].poc.compno0 = tcp->compS;
-						pi[pino].poc.compno1 = tcp->compE;
-					}else{
-						if (tpnum == 0){
-							tcp->comp_t = tcp->compS;
-							pi[pino].poc.compno0 = tcp->comp_t;
-							pi[pino].poc.compno1 = tcp->comp_t+1;
-							tcp->comp_t+=1;
-						}else{
-							if (incr_top == 1){
-								if(tcp->comp_t ==tcp->compE){
-									tcp->comp_t = tcp->compS;
-									pi[pino].poc.compno0 = tcp->comp_t;
-									pi[pino].poc.compno1 = tcp->comp_t+1;
-									tcp->comp_t+=1;
-									incr_top=1;
-								}else{
-									pi[pino].poc.compno0 = tcp->comp_t;
-									pi[pino].poc.compno1 = tcp->comp_t+1;
-									tcp->comp_t+=1;
-									incr_top=0;
-								}
-							}else{
-								pi[pino].poc.compno0 = tcp->comp_t-1;
-								pi[pino].poc.compno1 = tcp->comp_t;
-							}
-						}
-					}
-					break;
-
-				case 'R':
-					if (i > tppos){
-						pi[pino].poc.resno0 = tcp->resS;
-						pi[pino].poc.resno1 = tcp->resE;
-					}else{
-						if (tpnum == 0){
-							tcp->res_t = tcp->resS;
-							pi[pino].poc.resno0 = tcp->res_t;
-							pi[pino].poc.resno1 = tcp->res_t+1;
-							tcp->res_t+=1;
-						}else{
-							if (incr_top == 1){
-								if(tcp->res_t==tcp->resE){
-									tcp->res_t = tcp->resS;
-									pi[pino].poc.resno0 = tcp->res_t;
-									pi[pino].poc.resno1 = tcp->res_t+1;
-									tcp->res_t+=1;
-									incr_top=1;
-								}else{
-									pi[pino].poc.resno0 = tcp->res_t;
-									pi[pino].poc.resno1 = tcp->res_t+1;
-									tcp->res_t+=1;
-									incr_top=0;
-								}
-							}else{
-								pi[pino].poc.resno0 = tcp->res_t - 1;
-								pi[pino].poc.resno1 = tcp->res_t;
-							}
-						}
-					}
-					break;
-
-				case 'L':
-					if (i > tppos){
-						pi[pino].poc.layno0 = tcp->layS;
-						pi[pino].poc.layno1 = tcp->layE;
-					}else{
-						if (tpnum == 0){
-							tcp->lay_t = tcp->layS;
-							pi[pino].poc.layno0 = tcp->lay_t;
-							pi[pino].poc.layno1 = tcp->lay_t+1;
-							tcp->lay_t+=1;
-						}else{
-							if (incr_top == 1){
-								if(tcp->lay_t == tcp->layE){
-									tcp->lay_t = tcp->layS;
-									pi[pino].poc.layno0 = tcp->lay_t;
-									pi[pino].poc.layno1 = tcp->lay_t+1;
-									tcp->lay_t+=1;
-									incr_top=1;
-								}else{
-									pi[pino].poc.layno0 = tcp->lay_t;
-									pi[pino].poc.layno1 = tcp->lay_t+1;
-									tcp->lay_t+=1;
-									incr_top=0;
-								}
-							}else{
-								pi[pino].poc.layno0 = tcp->lay_t - 1;
-								pi[pino].poc.layno1 = tcp->lay_t;
-							}
-						}
-					}
-					break;
-
-				case 'P':
-					switch(tcp->prg){
-						case LRCP:
-						case RLCP:
-							if (i > tppos){
-								pi[pino].poc.precno0 = tcp->prcS;
-								pi[pino].poc.precno1 = tcp->prcE;
-							}else{
-								if (tpnum == 0){
-									tcp->prc_t = tcp->prcS;
-									pi[pino].poc.precno0 = tcp->prc_t;
-									pi[pino].poc.precno1 = tcp->prc_t+1;
-									tcp->prc_t+=1; 
-								}else{
-									if (incr_top == 1){
-										if(tcp->prc_t == tcp->prcE){
-											tcp->prc_t = tcp->prcS;
-											pi[pino].poc.precno0 = tcp->prc_t;
-											pi[pino].poc.precno1 = tcp->prc_t+1;
-											tcp->prc_t+=1;
-											incr_top=1;
-										}else{
-											pi[pino].poc.precno0 = tcp->prc_t;
-											pi[pino].poc.precno1 = tcp->prc_t+1;
-											tcp->prc_t+=1;
-											incr_top=0;
-										}
-									}else{
-										pi[pino].poc.precno0 = tcp->prc_t - 1;
-										pi[pino].poc.precno1 = tcp->prc_t;
-									}
-								}
-							}
-						break;
-						default:
-							if (i > tppos){
-								pi[pino].poc.tx0 = tcp->txS;
-								pi[pino].poc.ty0 = tcp->tyS;
-								pi[pino].poc.tx1 = tcp->txE;
-								pi[pino].poc.ty1 = tcp->tyE;
-							}else{
-								if (tpnum == 0){
-									tcp->tx0_t = tcp->txS;
-									tcp->ty0_t = tcp->tyS;
-									pi[pino].poc.tx0 = tcp->tx0_t;
-									pi[pino].poc.tx1 = tcp->tx0_t + tcp->dx - (tcp->tx0_t % tcp->dx);
-									pi[pino].poc.ty0 = tcp->ty0_t;
-									pi[pino].poc.ty1 = tcp->ty0_t + tcp->dy - (tcp->ty0_t % tcp->dy);
-									tcp->tx0_t = pi[pino].poc.tx1;
-									tcp->ty0_t = pi[pino].poc.ty1;
-								}else{
-									if (incr_top == 1){
-										if(tcp->tx0_t >= tcp->txE){
-											if(tcp->ty0_t >= tcp->tyE){
-												tcp->ty0_t = tcp->tyS;
-												pi[pino].poc.ty0 = tcp->ty0_t;
-												pi[pino].poc.ty1 = tcp->ty0_t + tcp->dy - (tcp->ty0_t % tcp->dy);
-												tcp->ty0_t = pi[pino].poc.ty1;
-												incr_top=1;resetX=1;
-											}else{
-												pi[pino].poc.ty0 = tcp->ty0_t;
-												pi[pino].poc.ty1 = tcp->ty0_t + tcp->dy - (tcp->ty0_t % tcp->dy);
-												tcp->ty0_t = pi[pino].poc.ty1;
-												incr_top=0;resetX=1;
-											}
-											if(resetX==1){
-												tcp->tx0_t = tcp->txS;
-												pi[pino].poc.tx0 = tcp->tx0_t;
-												pi[pino].poc.tx1 = tcp->tx0_t + tcp->dx- (tcp->tx0_t % tcp->dx);
-												tcp->tx0_t = pi[pino].poc.tx1;
-											}
-										}else{
-											pi[pino].poc.tx0 = tcp->tx0_t;
-											pi[pino].poc.tx1 = tcp->tx0_t + tcp->dx- (tcp->tx0_t % tcp->dx);
-											tcp->tx0_t = pi[pino].poc.tx1;
-											pi[pino].poc.ty0 = tcp->ty0_t - tcp->dy - (tcp->ty0_t % tcp->dy);
-											pi[pino].poc.ty1 = tcp->ty0_t ;
-											incr_top=0;
-										}
-									}else{
-										pi[pino].poc.tx0 = tcp->tx0_t - tcp->dx - (tcp->tx0_t % tcp->dx);
-										pi[pino].poc.tx1 = tcp->tx0_t ;
-										pi[pino].poc.ty0 = tcp->ty0_t - tcp->dy - (tcp->ty0_t % tcp->dy);
-										pi[pino].poc.ty1 = tcp->ty0_t ;
-									}
-								}
-							}
-						break;
-						}
-						break;
-				}		
-			} 
-		}
-	}	
-	return OPJ_FALSE;
-}
-
+/*
+ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2007, Professor Benoit Macq
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2006-2007, Parvatha Elangovan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "opj_includes.h"
+
+/** @defgroup PI PI - Implementation of a packet iterator */
+/*@{*/
+
+/** @name Local static functions */
+/*@{*/
+
+/**
+Get next packet in layer-resolution-component-precinct order.
+ at param pi packet iterator to modify
+ at return returns false if pi pointed to the last packet or else returns true
+*/
+static OPJ_BOOL opj_pi_next_lrcp(opj_pi_iterator_t * pi);
+/**
+Get next packet in resolution-layer-component-precinct order.
+ at param pi packet iterator to modify
+ at return returns false if pi pointed to the last packet or else returns true
+*/
+static OPJ_BOOL opj_pi_next_rlcp(opj_pi_iterator_t * pi);
+/**
+Get next packet in resolution-precinct-component-layer order.
+ at param pi packet iterator to modify
+ at return returns false if pi pointed to the last packet or else returns true
+*/
+static OPJ_BOOL opj_pi_next_rpcl(opj_pi_iterator_t * pi);
+/**
+Get next packet in precinct-component-resolution-layer order.
+ at param pi packet iterator to modify
+ at return returns false if pi pointed to the last packet or else returns true
+*/
+static OPJ_BOOL opj_pi_next_pcrl(opj_pi_iterator_t * pi);
+/**
+Get next packet in component-precinct-resolution-layer order.
+ at param pi packet iterator to modify
+ at return returns false if pi pointed to the last packet or else returns true
+*/
+static OPJ_BOOL opj_pi_next_cprl(opj_pi_iterator_t * pi);
+
+/**
+ * Updates the coding parameters if the encoding is used with Progression order changes and final (or cinema parameters are used).
+ *
+ * @param	p_cp		the coding parameters to modify
+ * @param	p_tileno	the tile index being concerned.
+ * @param	p_tx0		X0 parameter for the tile
+ * @param	p_tx1		X1 parameter for the tile
+ * @param	p_ty0		Y0 parameter for the tile
+ * @param	p_ty1		Y1 parameter for the tile
+ * @param	p_max_prec	the maximum precision for all the bands of the tile
+ * @param	p_max_res	the maximum number of resolutions for all the poc inside the tile.
+ * @param	p_dx_min		the minimum dx of all the components of all the resolutions for the tile.
+ * @param	p_dy_min		the minimum dy of all the components of all the resolutions for the tile.
+ */
+static void opj_pi_update_encode_poc_and_final ( opj_cp_t *p_cp,
+                                                 OPJ_UINT32 p_tileno,
+                                                 OPJ_INT32 p_tx0,
+                                                 OPJ_INT32 p_tx1,
+                                                 OPJ_INT32 p_ty0,
+                                                 OPJ_INT32 p_ty1,
+                                                 OPJ_UINT32 p_max_prec,
+                                                 OPJ_UINT32 p_max_res,
+                                                 OPJ_UINT32 p_dx_min,
+                                                 OPJ_UINT32 p_dy_min);
+
+/**
+ * Updates the coding parameters if the encoding is not used with Progression order changes and final (and cinema parameters are used).
+ *
+ * @param	p_cp		the coding parameters to modify
+ * @param	p_num_comps		the number of components
+ * @param	p_tileno	the tile index being concerned.
+ * @param	p_tx0		X0 parameter for the tile
+ * @param	p_tx1		X1 parameter for the tile
+ * @param	p_ty0		Y0 parameter for the tile
+ * @param	p_ty1		Y1 parameter for the tile
+ * @param	p_max_prec	the maximum precision for all the bands of the tile
+ * @param	p_max_res	the maximum number of resolutions for all the poc inside the tile.
+ * @param	p_dx_min		the minimum dx of all the components of all the resolutions for the tile.
+ * @param	p_dy_min		the minimum dy of all the components of all the resolutions for the tile.
+ */
+static void opj_pi_update_encode_not_poc (  opj_cp_t *p_cp,
+                                            OPJ_UINT32 p_num_comps,
+                                            OPJ_UINT32 p_tileno,
+                                            OPJ_INT32 p_tx0,
+                                            OPJ_INT32 p_tx1,
+                                            OPJ_INT32 p_ty0,
+                                            OPJ_INT32 p_ty1,
+                                            OPJ_UINT32 p_max_prec,
+                                            OPJ_UINT32 p_max_res,
+                                            OPJ_UINT32 p_dx_min,
+                                            OPJ_UINT32 p_dy_min);
+/**
+ * Gets the encoding parameters needed to update the coding parameters and all the pocs.
+ * 
+ * @param	p_image			the image being encoded.
+ * @param	p_cp			the coding parameters.
+ * @param	tileno			the tile index of the tile being encoded.
+ * @param	p_tx0			pointer that will hold the X0 parameter for the tile
+ * @param	p_tx1			pointer that will hold the X1 parameter for the tile
+ * @param	p_ty0			pointer that will hold the Y0 parameter for the tile
+ * @param	p_ty1			pointer that will hold the Y1 parameter for the tile
+ * @param	p_max_prec		pointer that will hold the the maximum precision for all the bands of the tile
+ * @param	p_max_res		pointer that will hold the the maximum number of resolutions for all the poc inside the tile.
+ * @param	p_dx_min			pointer that will hold the the minimum dx of all the components of all the resolutions for the tile.
+ * @param	p_dy_min			pointer that will hold the the minimum dy of all the components of all the resolutions for the tile.
+ */
+static void opj_get_encoding_parameters(const opj_image_t *p_image,
+                                        const opj_cp_t *p_cp,
+                                        OPJ_UINT32  tileno,
+                                        OPJ_INT32  * p_tx0,
+                                        OPJ_INT32 * p_tx1,
+                                        OPJ_INT32 * p_ty0,
+                                        OPJ_INT32 * p_ty1,
+                                        OPJ_UINT32 * p_dx_min,
+                                        OPJ_UINT32 * p_dy_min,
+                                        OPJ_UINT32 * p_max_prec,
+                                        OPJ_UINT32 * p_max_res );
+
+/**
+ * Gets the encoding parameters needed to update the coding parameters and all the pocs.
+ * The precinct widths, heights, dx and dy for each component at each resolution will be stored as well.
+ * the last parameter of the function should be an array of pointers of size nb components, each pointer leading
+ * to an area of size 4 * max_res. The data is stored inside this area with the following pattern :
+ * dx_compi_res0 , dy_compi_res0 , w_compi_res0, h_compi_res0 , dx_compi_res1 , dy_compi_res1 , w_compi_res1, h_compi_res1 , ...
+ *
+ * @param	p_image			the image being encoded.
+ * @param	p_cp			the coding parameters.
+ * @param	tileno			the tile index of the tile being encoded.
+ * @param	p_tx0			pointer that will hold the X0 parameter for the tile
+ * @param	p_tx1			pointer that will hold the X1 parameter for the tile
+ * @param	p_ty0			pointer that will hold the Y0 parameter for the tile
+ * @param	p_ty1			pointer that will hold the Y1 parameter for the tile
+ * @param	p_max_prec		pointer that will hold the the maximum precision for all the bands of the tile
+ * @param	p_max_res		pointer that will hold the the maximum number of resolutions for all the poc inside the tile.
+ * @param	p_dx_min		pointer that will hold the the minimum dx of all the components of all the resolutions for the tile.
+ * @param	p_dy_min		pointer that will hold the the minimum dy of all the components of all the resolutions for the tile.
+ * @param	p_resolutions	pointer to an area corresponding to the one described above.
+ */
+static void opj_get_all_encoding_parameters(const opj_image_t *p_image,
+                                            const opj_cp_t *p_cp,
+                                            OPJ_UINT32 tileno,
+                                            OPJ_INT32 * p_tx0,
+                                            OPJ_INT32 * p_tx1,
+                                            OPJ_INT32 * p_ty0,
+                                            OPJ_INT32 * p_ty1,
+                                            OPJ_UINT32 * p_dx_min,
+                                            OPJ_UINT32 * p_dy_min,
+                                            OPJ_UINT32 * p_max_prec,
+                                            OPJ_UINT32 * p_max_res,
+                                            OPJ_UINT32 ** p_resolutions );
+/**
+ * Allocates memory for a packet iterator. Data and data sizes are set by this operation.
+ * No other data is set. The include section of the packet  iterator is not allocated.
+ * 
+ * @param	p_image		the image used to initialize the packet iterator (in fact only the number of components is relevant.
+ * @param	p_cp		the coding parameters.
+ * @param	tileno	the index of the tile from which creating the packet iterator.
+ */
+static opj_pi_iterator_t * opj_pi_create(	const opj_image_t *p_image,
+                                            const opj_cp_t *p_cp,
+                                            OPJ_UINT32 tileno );
+/**
+ * FIXME DOC
+ */
+static void opj_pi_update_decode_not_poc (opj_pi_iterator_t * p_pi,
+                                          opj_tcp_t * p_tcp,
+                                          OPJ_UINT32 p_max_precision,
+                                          OPJ_UINT32 p_max_res);
+/**
+ * FIXME DOC
+ */
+static void opj_pi_update_decode_poc (  opj_pi_iterator_t * p_pi,
+                                        opj_tcp_t * p_tcp,
+                                        OPJ_UINT32 p_max_precision,
+                                        OPJ_UINT32 p_max_res);
+
+/**
+ * FIXME DOC
+ */
+OPJ_BOOL opj_pi_check_next_level(	OPJ_INT32 pos,
+								opj_cp_t *cp,
+								OPJ_UINT32 tileno,
+								OPJ_UINT32 pino,
+								const OPJ_CHAR *prog);
+
+/*@}*/
+
+/*@}*/
+
+/*
+==========================================================
+   local functions
+==========================================================
+*/
+
+OPJ_BOOL opj_pi_next_lrcp(opj_pi_iterator_t * pi) {
+	opj_pi_comp_t *comp = NULL;
+	opj_pi_resolution_t *res = NULL;
+	OPJ_UINT32 index = 0;
+	
+	if (!pi->first) {
+		comp = &pi->comps[pi->compno];
+		res = &comp->resolutions[pi->resno];
+		goto LABEL_SKIP;
+	} else {
+		pi->first = 0;
+	}
+
+	for (pi->layno = pi->poc.layno0; pi->layno < pi->poc.layno1; pi->layno++) {
+		for (pi->resno = pi->poc.resno0; pi->resno < pi->poc.resno1;
+		pi->resno++) {
+			for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) {
+				comp = &pi->comps[pi->compno];
+				if (pi->resno >= comp->numresolutions) {
+					continue;
+				}
+				res = &comp->resolutions[pi->resno];
+				if (!pi->tp_on){
+					pi->poc.precno1 = res->pw * res->ph;
+				}
+				for (pi->precno = pi->poc.precno0; pi->precno < pi->poc.precno1; pi->precno++) {
+					index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;
+					if (!pi->include[index]) {
+						pi->include[index] = 1;
+						return OPJ_TRUE;
+					}
+LABEL_SKIP:;
+				}
+			}
+		}
+	}
+	
+	return OPJ_FALSE;
+}
+
+OPJ_BOOL opj_pi_next_rlcp(opj_pi_iterator_t * pi) {
+	opj_pi_comp_t *comp = NULL;
+	opj_pi_resolution_t *res = NULL;
+	OPJ_UINT32 index = 0;
+
+	if (!pi->first) {
+		comp = &pi->comps[pi->compno];
+		res = &comp->resolutions[pi->resno];
+		goto LABEL_SKIP;
+	} else {
+		pi->first = 0;
+	}
+
+	for (pi->resno = pi->poc.resno0; pi->resno < pi->poc.resno1; pi->resno++) {
+		for (pi->layno = pi->poc.layno0; pi->layno < pi->poc.layno1; pi->layno++) {
+			for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) {
+				comp = &pi->comps[pi->compno];
+				if (pi->resno >= comp->numresolutions) {
+					continue;
+				}
+				res = &comp->resolutions[pi->resno];
+				if(!pi->tp_on){
+					pi->poc.precno1 = res->pw * res->ph;
+				}
+				for (pi->precno = pi->poc.precno0; pi->precno < pi->poc.precno1; pi->precno++) {
+					index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;
+					if (!pi->include[index]) {
+						pi->include[index] = 1;
+						return OPJ_TRUE;
+					}
+LABEL_SKIP:;
+				}
+			}
+		}
+	}
+	
+	return OPJ_FALSE;
+}
+
+OPJ_BOOL opj_pi_next_rpcl(opj_pi_iterator_t * pi) {
+	opj_pi_comp_t *comp = NULL;
+	opj_pi_resolution_t *res = NULL;
+	OPJ_UINT32 index = 0;
+
+	if (!pi->first) {
+		goto LABEL_SKIP;
+	} else {
+		OPJ_UINT32 compno, resno;
+		pi->first = 0;
+		pi->dx = 0;
+		pi->dy = 0;
+		for (compno = 0; compno < pi->numcomps; compno++) {
+			comp = &pi->comps[compno];
+			for (resno = 0; resno < comp->numresolutions; resno++) {
+				OPJ_UINT32 dx, dy;
+				res = &comp->resolutions[resno];
+				dx = comp->dx * (1u << (res->pdx + comp->numresolutions - 1 - resno));
+				dy = comp->dy * (1u << (res->pdy + comp->numresolutions - 1 - resno));
+				pi->dx = !pi->dx ? dx : opj_uint_min(pi->dx, dx);
+				pi->dy = !pi->dy ? dy : opj_uint_min(pi->dy, dy);
+			}
+		}
+	}
+if (!pi->tp_on){
+			pi->poc.ty0 = pi->ty0;
+			pi->poc.tx0 = pi->tx0;
+			pi->poc.ty1 = pi->ty1;
+			pi->poc.tx1 = pi->tx1;
+		}
+	for (pi->resno = pi->poc.resno0; pi->resno < pi->poc.resno1; pi->resno++) {
+		for (pi->y = pi->poc.ty0; pi->y < pi->poc.ty1; pi->y += (OPJ_INT32)(pi->dy - (OPJ_UINT32)(pi->y % (OPJ_INT32)pi->dy))) {
+			for (pi->x = pi->poc.tx0; pi->x < pi->poc.tx1; pi->x += (OPJ_INT32)(pi->dx - (OPJ_UINT32)(pi->x % (OPJ_INT32)pi->dx))) {
+				for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) {
+					OPJ_UINT32 levelno;
+					OPJ_INT32 trx0, try0;
+					OPJ_INT32  trx1, try1;
+					OPJ_UINT32  rpx, rpy;
+					OPJ_INT32  prci, prcj;
+					comp = &pi->comps[pi->compno];
+					if (pi->resno >= comp->numresolutions) {
+						continue;
+					}
+					res = &comp->resolutions[pi->resno];
+					levelno = comp->numresolutions - 1 - pi->resno;
+					trx0 = opj_int_ceildiv(pi->tx0, (OPJ_INT32)(comp->dx << levelno));
+					try0 = opj_int_ceildiv(pi->ty0, (OPJ_INT32)(comp->dy << levelno));
+					trx1 = opj_int_ceildiv(pi->tx1, (OPJ_INT32)(comp->dx << levelno));
+					try1 = opj_int_ceildiv(pi->ty1, (OPJ_INT32)(comp->dy << levelno));
+					rpx = res->pdx + levelno;
+					rpy = res->pdy + levelno;
+					if (!((pi->y % (OPJ_INT32)(comp->dy << rpy) == 0) || ((pi->y == pi->ty0) && ((try0 << levelno) % (1 << rpy))))){
+						continue;	
+					}
+					if (!((pi->x % (OPJ_INT32)(comp->dx << rpx) == 0) || ((pi->x == pi->tx0) && ((trx0 << levelno) % (1 << rpx))))){
+						continue;
+					}
+					
+					if ((res->pw==0)||(res->ph==0)) continue;
+					
+					if ((trx0==trx1)||(try0==try1)) continue;
+					
+					prci = opj_int_floordivpow2(opj_int_ceildiv(pi->x, (OPJ_INT32)(comp->dx << levelno)), (OPJ_INT32)res->pdx)
+						 - opj_int_floordivpow2(trx0, (OPJ_INT32)res->pdx);
+					prcj = opj_int_floordivpow2(opj_int_ceildiv(pi->y, (OPJ_INT32)(comp->dy << levelno)), (OPJ_INT32)res->pdy)
+						 - opj_int_floordivpow2(try0, (OPJ_INT32)res->pdy);
+					pi->precno = (OPJ_UINT32)(prci + prcj * (OPJ_INT32)res->pw);
+					for (pi->layno = pi->poc.layno0; pi->layno < pi->poc.layno1; pi->layno++) {
+						index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;
+						if (!pi->include[index]) {
+							pi->include[index] = 1;
+							return OPJ_TRUE;
+						}
+LABEL_SKIP:;
+					}
+				}
+			}
+		}
+	}
+	
+	return OPJ_FALSE;
+}
+
+OPJ_BOOL opj_pi_next_pcrl(opj_pi_iterator_t * pi) {
+	opj_pi_comp_t *comp = NULL;
+	opj_pi_resolution_t *res = NULL;
+	OPJ_UINT32 index = 0;
+
+	if (!pi->first) {
+		comp = &pi->comps[pi->compno];
+		goto LABEL_SKIP;
+	} else {
+		OPJ_UINT32 compno, resno;
+		pi->first = 0;
+		pi->dx = 0;
+		pi->dy = 0;
+		for (compno = 0; compno < pi->numcomps; compno++) {
+			comp = &pi->comps[compno];
+			for (resno = 0; resno < comp->numresolutions; resno++) {
+				OPJ_UINT32 dx, dy;
+				res = &comp->resolutions[resno];
+				dx = comp->dx * (1u << (res->pdx + comp->numresolutions - 1 - resno));
+				dy = comp->dy * (1u << (res->pdy + comp->numresolutions - 1 - resno));
+				pi->dx = !pi->dx ? dx : opj_uint_min(pi->dx, dx);
+				pi->dy = !pi->dy ? dy : opj_uint_min(pi->dy, dy);
+			}
+		}
+	}
+	if (!pi->tp_on){
+			pi->poc.ty0 = pi->ty0;
+			pi->poc.tx0 = pi->tx0;
+			pi->poc.ty1 = pi->ty1;
+			pi->poc.tx1 = pi->tx1;
+		}
+	for (pi->y = pi->poc.ty0; pi->y < pi->poc.ty1; pi->y += (OPJ_INT32)(pi->dy - (OPJ_UINT32)(pi->y % (OPJ_INT32)pi->dy))) {
+		for (pi->x = pi->poc.tx0; pi->x < pi->poc.tx1; pi->x += (OPJ_INT32)(pi->dx - (OPJ_UINT32)(pi->x % (OPJ_INT32)pi->dx))) {
+			for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) {
+				comp = &pi->comps[pi->compno];
+				for (pi->resno = pi->poc.resno0; pi->resno < opj_uint_min(pi->poc.resno1, comp->numresolutions); pi->resno++) {
+					OPJ_UINT32 levelno;
+					OPJ_INT32 trx0, try0;
+					OPJ_INT32 trx1, try1;
+					OPJ_UINT32 rpx, rpy;
+					OPJ_INT32 prci, prcj;
+					res = &comp->resolutions[pi->resno];
+					levelno = comp->numresolutions - 1 - pi->resno;
+					trx0 = opj_int_ceildiv(pi->tx0, (OPJ_INT32)(comp->dx << levelno));
+					try0 = opj_int_ceildiv(pi->ty0, (OPJ_INT32)(comp->dy << levelno));
+					trx1 = opj_int_ceildiv(pi->tx1, (OPJ_INT32)(comp->dx << levelno));
+					try1 = opj_int_ceildiv(pi->ty1, (OPJ_INT32)(comp->dy << levelno));
+					rpx = res->pdx + levelno;
+					rpy = res->pdy + levelno;
+					if (!((pi->y % (OPJ_INT32)(comp->dy << rpy) == 0) || ((pi->y == pi->ty0) && ((try0 << levelno) % (1 << rpy))))){
+						continue;	
+					}
+					if (!((pi->x % (OPJ_INT32)(comp->dx << rpx) == 0) || ((pi->x == pi->tx0) && ((trx0 << levelno) % (1 << rpx))))){
+						continue;
+					}
+					
+					if ((res->pw==0)||(res->ph==0)) continue;
+					
+					if ((trx0==trx1)||(try0==try1)) continue;
+					
+					prci = opj_int_floordivpow2(opj_int_ceildiv(pi->x, (OPJ_INT32)(comp->dx << levelno)), (OPJ_INT32)res->pdx)
+						 - opj_int_floordivpow2(trx0, (OPJ_INT32)res->pdx);
+					prcj = opj_int_floordivpow2(opj_int_ceildiv(pi->y, (OPJ_INT32)(comp->dy << levelno)), (OPJ_INT32)res->pdy)
+						 - opj_int_floordivpow2(try0, (OPJ_INT32)res->pdy);
+					pi->precno = (OPJ_UINT32)(prci + prcj * (OPJ_INT32)res->pw);
+					for (pi->layno = pi->poc.layno0; pi->layno < pi->poc.layno1; pi->layno++) {
+						index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;
+						if (!pi->include[index]) {
+							pi->include[index] = 1;
+							return OPJ_TRUE;
+						}	
+LABEL_SKIP:;
+					}
+				}
+			}
+		}
+	}
+	
+	return OPJ_FALSE;
+}
+
+OPJ_BOOL opj_pi_next_cprl(opj_pi_iterator_t * pi) {
+	opj_pi_comp_t *comp = NULL;
+	opj_pi_resolution_t *res = NULL;
+	OPJ_UINT32 index = 0;
+
+	if (!pi->first) {
+		comp = &pi->comps[pi->compno];
+		goto LABEL_SKIP;
+	} else {
+		pi->first = 0;
+	}
+
+	for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) {
+		OPJ_UINT32 resno;
+		comp = &pi->comps[pi->compno];
+		pi->dx = 0;
+		pi->dy = 0;
+		for (resno = 0; resno < comp->numresolutions; resno++) {
+			OPJ_UINT32 dx, dy;
+			res = &comp->resolutions[resno];
+			dx = comp->dx * (1u << (res->pdx + comp->numresolutions - 1 - resno));
+			dy = comp->dy * (1u << (res->pdy + comp->numresolutions - 1 - resno));
+			pi->dx = !pi->dx ? dx : opj_uint_min(pi->dx, dx);
+			pi->dy = !pi->dy ? dy : opj_uint_min(pi->dy, dy);
+		}
+		if (!pi->tp_on){
+			pi->poc.ty0 = pi->ty0;
+			pi->poc.tx0 = pi->tx0;
+			pi->poc.ty1 = pi->ty1;
+			pi->poc.tx1 = pi->tx1;
+		}
+		for (pi->y = pi->poc.ty0; pi->y < pi->poc.ty1; pi->y += (OPJ_INT32)(pi->dy - (OPJ_UINT32)(pi->y % (OPJ_INT32)pi->dy))) {
+			for (pi->x = pi->poc.tx0; pi->x < pi->poc.tx1; pi->x += (OPJ_INT32)(pi->dx - (OPJ_UINT32)(pi->x % (OPJ_INT32)pi->dx))) {
+				for (pi->resno = pi->poc.resno0; pi->resno < opj_uint_min(pi->poc.resno1, comp->numresolutions); pi->resno++) {
+					OPJ_UINT32 levelno;
+					OPJ_INT32 trx0, try0;
+					OPJ_INT32 trx1, try1;
+					OPJ_UINT32 rpx, rpy;
+					OPJ_INT32 prci, prcj;
+					res = &comp->resolutions[pi->resno];
+					levelno = comp->numresolutions - 1 - pi->resno;
+					trx0 = opj_int_ceildiv(pi->tx0, (OPJ_INT32)(comp->dx << levelno));
+					try0 = opj_int_ceildiv(pi->ty0, (OPJ_INT32)(comp->dy << levelno));
+					trx1 = opj_int_ceildiv(pi->tx1, (OPJ_INT32)(comp->dx << levelno));
+					try1 = opj_int_ceildiv(pi->ty1, (OPJ_INT32)(comp->dy << levelno));
+					rpx = res->pdx + levelno;
+					rpy = res->pdy + levelno;
+					if (!((pi->y % (OPJ_INT32)(comp->dy << rpy) == 0) || ((pi->y == pi->ty0) && ((try0 << levelno) % (1 << rpy))))){
+						continue;	
+					}
+					if (!((pi->x % (OPJ_INT32)(comp->dx << rpx) == 0) || ((pi->x == pi->tx0) && ((trx0 << levelno) % (1 << rpx))))){
+						continue;
+					}
+					
+					if ((res->pw==0)||(res->ph==0)) continue;
+					
+					if ((trx0==trx1)||(try0==try1)) continue;
+					
+					prci = opj_int_floordivpow2(opj_int_ceildiv(pi->x, (OPJ_INT32)(comp->dx << levelno)), (OPJ_INT32)res->pdx)
+						 - opj_int_floordivpow2(trx0, (OPJ_INT32)res->pdx);
+					prcj = opj_int_floordivpow2(opj_int_ceildiv(pi->y, (OPJ_INT32)(comp->dy << levelno)), (OPJ_INT32)res->pdy)
+						 - opj_int_floordivpow2(try0, (OPJ_INT32)res->pdy);
+					pi->precno = (OPJ_UINT32)(prci + prcj * (OPJ_INT32)res->pw);
+					for (pi->layno = pi->poc.layno0; pi->layno < pi->poc.layno1; pi->layno++) {
+						index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;
+						if (!pi->include[index]) {
+							pi->include[index] = 1;
+							return OPJ_TRUE;
+						}
+LABEL_SKIP:;
+					}
+				}
+			}
+		}
+	}
+	
+	return OPJ_FALSE;
+}
+
+void opj_get_encoding_parameters(	const opj_image_t *p_image,
+                                    const opj_cp_t *p_cp,
+                                    OPJ_UINT32 p_tileno,
+                                    OPJ_INT32 * p_tx0,
+                                    OPJ_INT32  * p_tx1,
+                                    OPJ_INT32  * p_ty0,
+                                    OPJ_INT32  * p_ty1,
+                                    OPJ_UINT32 * p_dx_min,
+                                    OPJ_UINT32 * p_dy_min,
+                                    OPJ_UINT32 * p_max_prec,
+                                    OPJ_UINT32 * p_max_res )
+{
+	/* loop */
+	OPJ_UINT32  compno, resno;
+	/* pointers */
+	const opj_tcp_t *l_tcp = 00;
+	const opj_tccp_t * l_tccp = 00;
+	const opj_image_comp_t * l_img_comp = 00;
+
+	/* position in x and y of tile */
+	OPJ_UINT32 p, q;
+
+	/* preconditions */
+	assert(p_cp != 00);
+	assert(p_image != 00);
+	assert(p_tileno < p_cp->tw * p_cp->th);
+
+	/* initializations */
+	l_tcp = &p_cp->tcps [p_tileno];
+	l_img_comp = p_image->comps;
+	l_tccp = l_tcp->tccps;
+
+	/* here calculation of tx0, tx1, ty0, ty1, maxprec, dx and dy */
+	p = p_tileno % p_cp->tw;
+	q = p_tileno / p_cp->tw;
+
+	/* find extent of tile */
+	*p_tx0 = opj_int_max((OPJ_INT32)(p_cp->tx0 + p * p_cp->tdx), (OPJ_INT32)p_image->x0);
+	*p_tx1 = opj_int_min((OPJ_INT32)(p_cp->tx0 + (p + 1) * p_cp->tdx), (OPJ_INT32)p_image->x1);
+	*p_ty0 = opj_int_max((OPJ_INT32)(p_cp->ty0 + q * p_cp->tdy), (OPJ_INT32)p_image->y0);
+	*p_ty1 = opj_int_min((OPJ_INT32)(p_cp->ty0 + (q + 1) * p_cp->tdy), (OPJ_INT32)p_image->y1);
+
+	/* max precision is 0 (can only grow) */
+	*p_max_prec = 0;
+	*p_max_res = 0;
+
+	/* take the largest value for dx_min and dy_min */
+	*p_dx_min = 0x7fffffff;
+	*p_dy_min  = 0x7fffffff;
+
+	for (compno = 0; compno < p_image->numcomps; ++compno) {
+		/* arithmetic variables to calculate */
+		OPJ_UINT32 l_level_no;
+		OPJ_INT32 l_rx0, l_ry0, l_rx1, l_ry1;
+		OPJ_INT32 l_px0, l_py0, l_px1, py1;
+		OPJ_UINT32 l_pdx, l_pdy;
+		OPJ_UINT32 l_pw, l_ph;
+		OPJ_UINT32 l_product;
+		OPJ_INT32 l_tcx0, l_tcy0, l_tcx1, l_tcy1;
+
+		l_tcx0 = opj_int_ceildiv(*p_tx0, (OPJ_INT32)l_img_comp->dx);
+		l_tcy0 = opj_int_ceildiv(*p_ty0, (OPJ_INT32)l_img_comp->dy);
+		l_tcx1 = opj_int_ceildiv(*p_tx1, (OPJ_INT32)l_img_comp->dx);
+		l_tcy1 = opj_int_ceildiv(*p_ty1, (OPJ_INT32)l_img_comp->dy);
+
+		if (l_tccp->numresolutions > *p_max_res) {
+			*p_max_res = l_tccp->numresolutions;
+		}
+
+		/* use custom size for precincts */
+		for (resno = 0; resno < l_tccp->numresolutions; ++resno) {
+			OPJ_UINT32 l_dx, l_dy;
+
+			/* precinct width and height */
+			l_pdx = l_tccp->prcw[resno];
+			l_pdy = l_tccp->prch[resno];
+
+			l_dx = l_img_comp->dx * (1u << (l_pdx + l_tccp->numresolutions - 1 - resno));
+			l_dy = l_img_comp->dy * (1u << (l_pdy + l_tccp->numresolutions - 1 - resno));
+
+			/* take the minimum size for dx for each comp and resolution */
+			*p_dx_min = opj_uint_min(*p_dx_min, l_dx);
+			*p_dy_min = opj_uint_min(*p_dy_min, l_dy);
+
+			/* various calculations of extents */
+			l_level_no = l_tccp->numresolutions - 1 - resno;
+
+			l_rx0 = opj_int_ceildivpow2(l_tcx0, (OPJ_INT32)l_level_no);
+			l_ry0 = opj_int_ceildivpow2(l_tcy0, (OPJ_INT32)l_level_no);
+			l_rx1 = opj_int_ceildivpow2(l_tcx1, (OPJ_INT32)l_level_no);
+			l_ry1 = opj_int_ceildivpow2(l_tcy1, (OPJ_INT32)l_level_no);
+
+			l_px0 = opj_int_floordivpow2(l_rx0, (OPJ_INT32)l_pdx) << l_pdx;
+			l_py0 = opj_int_floordivpow2(l_ry0, (OPJ_INT32)l_pdy) << l_pdy;
+			l_px1 = opj_int_ceildivpow2(l_rx1, (OPJ_INT32)l_pdx) << l_pdx;
+
+			py1 = opj_int_ceildivpow2(l_ry1, (OPJ_INT32)l_pdy) << l_pdy;
+
+			l_pw = (l_rx0==l_rx1)?0:(OPJ_UINT32)((l_px1 - l_px0) >> l_pdx);
+			l_ph = (l_ry0==l_ry1)?0:(OPJ_UINT32)((py1 - l_py0) >> l_pdy);
+
+			l_product = l_pw * l_ph;
+
+			/* update precision */
+			if (l_product > *p_max_prec) {
+				*p_max_prec = l_product;
+			}
+		}
+		++l_img_comp;
+		++l_tccp;
+	}
+}
+
+
+void opj_get_all_encoding_parameters(   const opj_image_t *p_image,
+                                        const opj_cp_t *p_cp,
+                                        OPJ_UINT32 tileno,
+                                        OPJ_INT32 * p_tx0,
+                                        OPJ_INT32 * p_tx1,
+                                        OPJ_INT32 * p_ty0,
+                                        OPJ_INT32 * p_ty1,
+                                        OPJ_UINT32 * p_dx_min,
+                                        OPJ_UINT32 * p_dy_min,
+                                        OPJ_UINT32 * p_max_prec,
+                                        OPJ_UINT32 * p_max_res,
+                                        OPJ_UINT32 ** p_resolutions )
+{
+	/* loop*/
+	OPJ_UINT32 compno, resno;
+
+	/* pointers*/
+	const opj_tcp_t *tcp = 00;
+	const opj_tccp_t * l_tccp = 00;
+	const opj_image_comp_t * l_img_comp = 00;
+
+	/* to store l_dx, l_dy, w and h for each resolution and component.*/
+	OPJ_UINT32 * lResolutionPtr;
+
+	/* position in x and y of tile*/
+	OPJ_UINT32 p, q;
+
+	/* preconditions in debug*/
+	assert(p_cp != 00);
+	assert(p_image != 00);
+	assert(tileno < p_cp->tw * p_cp->th);
+
+	/* initializations*/
+	tcp = &p_cp->tcps [tileno];
+	l_tccp = tcp->tccps;
+	l_img_comp = p_image->comps;
+
+	/* position in x and y of tile*/
+	p = tileno % p_cp->tw;
+	q = tileno / p_cp->tw;
+
+	/* here calculation of tx0, tx1, ty0, ty1, maxprec, l_dx and l_dy */
+	*p_tx0 = opj_int_max((OPJ_INT32)(p_cp->tx0 + p * p_cp->tdx), (OPJ_INT32)p_image->x0);
+	*p_tx1 = opj_int_min((OPJ_INT32)(p_cp->tx0 + (p + 1) * p_cp->tdx), (OPJ_INT32)p_image->x1);
+	*p_ty0 = opj_int_max((OPJ_INT32)(p_cp->ty0 + q * p_cp->tdy), (OPJ_INT32)p_image->y0);
+	*p_ty1 = opj_int_min((OPJ_INT32)(p_cp->ty0 + (q + 1) * p_cp->tdy), (OPJ_INT32)p_image->y1);
+
+	/* max precision and resolution is 0 (can only grow)*/
+	*p_max_prec = 0;
+	*p_max_res = 0;
+
+	/* take the largest value for dx_min and dy_min*/
+	*p_dx_min = 0x7fffffff;
+	*p_dy_min = 0x7fffffff;
+
+	for (compno = 0; compno < p_image->numcomps; ++compno) {
+		/* aritmetic variables to calculate*/
+		OPJ_UINT32 l_level_no;
+		OPJ_INT32 l_rx0, l_ry0, l_rx1, l_ry1;
+		OPJ_INT32 l_px0, l_py0, l_px1, py1;
+		OPJ_UINT32 l_product;
+		OPJ_INT32 l_tcx0, l_tcy0, l_tcx1, l_tcy1;
+		OPJ_UINT32 l_pdx, l_pdy , l_pw , l_ph;
+
+		lResolutionPtr = p_resolutions[compno];
+
+		l_tcx0 = opj_int_ceildiv(*p_tx0, (OPJ_INT32)l_img_comp->dx);
+		l_tcy0 = opj_int_ceildiv(*p_ty0, (OPJ_INT32)l_img_comp->dy);
+		l_tcx1 = opj_int_ceildiv(*p_tx1, (OPJ_INT32)l_img_comp->dx);
+		l_tcy1 = opj_int_ceildiv(*p_ty1, (OPJ_INT32)l_img_comp->dy);
+
+		if (l_tccp->numresolutions > *p_max_res) {
+			*p_max_res = l_tccp->numresolutions;
+		}
+
+		/* use custom size for precincts*/
+		l_level_no = l_tccp->numresolutions - 1;
+		for (resno = 0; resno < l_tccp->numresolutions; ++resno) {
+			OPJ_UINT32 l_dx, l_dy;
+
+			/* precinct width and height*/
+			l_pdx = l_tccp->prcw[resno];
+			l_pdy = l_tccp->prch[resno];
+			*lResolutionPtr++ = l_pdx;
+			*lResolutionPtr++ = l_pdy;
+			l_dx = l_img_comp->dx * (1u << (l_pdx + l_level_no));
+			l_dy = l_img_comp->dy * (1u << (l_pdy + l_level_no));
+			/* take the minimum size for l_dx for each comp and resolution*/
+			*p_dx_min = (OPJ_UINT32)opj_int_min((OPJ_INT32)*p_dx_min, (OPJ_INT32)l_dx);
+			*p_dy_min = (OPJ_UINT32)opj_int_min((OPJ_INT32)*p_dy_min, (OPJ_INT32)l_dy);
+
+			/* various calculations of extents*/
+			l_rx0 = opj_int_ceildivpow2(l_tcx0, (OPJ_INT32)l_level_no);
+			l_ry0 = opj_int_ceildivpow2(l_tcy0, (OPJ_INT32)l_level_no);
+			l_rx1 = opj_int_ceildivpow2(l_tcx1, (OPJ_INT32)l_level_no);
+			l_ry1 = opj_int_ceildivpow2(l_tcy1, (OPJ_INT32)l_level_no);
+			l_px0 = opj_int_floordivpow2(l_rx0, (OPJ_INT32)l_pdx) << l_pdx;
+			l_py0 = opj_int_floordivpow2(l_ry0, (OPJ_INT32)l_pdy) << l_pdy;
+			l_px1 = opj_int_ceildivpow2(l_rx1, (OPJ_INT32)l_pdx) << l_pdx;
+			py1 = opj_int_ceildivpow2(l_ry1, (OPJ_INT32)l_pdy) << l_pdy;
+			l_pw = (l_rx0==l_rx1)?0:(OPJ_UINT32)((l_px1 - l_px0) >> l_pdx);
+			l_ph = (l_ry0==l_ry1)?0:(OPJ_UINT32)((py1 - l_py0) >> l_pdy);
+			*lResolutionPtr++ = l_pw;
+			*lResolutionPtr++ = l_ph;
+			l_product = l_pw * l_ph;
+			
+            /* update precision*/
+			if (l_product > *p_max_prec) {
+				*p_max_prec = l_product;
+			}
+
+			--l_level_no;
+		}
+		++l_tccp;
+		++l_img_comp;
+	}
+}
+
+opj_pi_iterator_t * opj_pi_create(	const opj_image_t *image,
+                                    const opj_cp_t *cp,
+                                    OPJ_UINT32 tileno )
+{
+	/* loop*/
+	OPJ_UINT32 pino, compno;
+	/* number of poc in the p_pi*/
+	OPJ_UINT32 l_poc_bound;
+
+	/* pointers to tile coding parameters and components.*/
+	opj_pi_iterator_t *l_pi = 00;
+	opj_tcp_t *tcp = 00;
+	const opj_tccp_t *tccp = 00;
+
+	/* current packet iterator being allocated*/
+	opj_pi_iterator_t *l_current_pi = 00;
+
+	/* preconditions in debug*/
+	assert(cp != 00);
+	assert(image != 00);
+	assert(tileno < cp->tw * cp->th);
+
+	/* initializations*/
+	tcp = &cp->tcps[tileno];
+	l_poc_bound = tcp->numpocs+1;
+
+	/* memory allocations*/
+	l_pi = (opj_pi_iterator_t*) opj_calloc((l_poc_bound), sizeof(opj_pi_iterator_t));
+	if (!l_pi) {
+		return NULL;
+	}
+	memset(l_pi,0,l_poc_bound * sizeof(opj_pi_iterator_t));
+
+	l_current_pi = l_pi;
+	for (pino = 0; pino < l_poc_bound ; ++pino) {
+
+		l_current_pi->comps = (opj_pi_comp_t*) opj_calloc(image->numcomps, sizeof(opj_pi_comp_t));
+		if (! l_current_pi->comps) {
+			opj_pi_destroy(l_pi, l_poc_bound);
+			return NULL;
+		}
+
+		l_current_pi->numcomps = image->numcomps;
+		memset(l_current_pi->comps,0,image->numcomps * sizeof(opj_pi_comp_t));
+
+		for (compno = 0; compno < image->numcomps; ++compno) {
+			opj_pi_comp_t *comp = &l_current_pi->comps[compno];
+
+			tccp = &tcp->tccps[compno];
+
+			comp->resolutions = (opj_pi_resolution_t*) opj_malloc(tccp->numresolutions * sizeof(opj_pi_resolution_t));
+			if (!comp->resolutions) {
+				opj_pi_destroy(l_pi, l_poc_bound);
+				return 00;
+			}
+
+			comp->numresolutions = tccp->numresolutions;
+			memset(comp->resolutions,0,tccp->numresolutions * sizeof(opj_pi_resolution_t));
+		}
+		++l_current_pi;
+	}
+	return l_pi;
+}
+
+void opj_pi_update_encode_poc_and_final (   opj_cp_t *p_cp,
+                                            OPJ_UINT32 p_tileno,
+                                            OPJ_INT32 p_tx0,
+                                            OPJ_INT32 p_tx1,
+                                            OPJ_INT32 p_ty0,
+                                            OPJ_INT32 p_ty1,
+                                            OPJ_UINT32 p_max_prec,
+                                            OPJ_UINT32 p_max_res,
+                                            OPJ_UINT32 p_dx_min,
+                                            OPJ_UINT32 p_dy_min)
+{
+	/* loop*/
+	OPJ_UINT32 pino;
+	/* tile coding parameter*/
+	opj_tcp_t *l_tcp = 00;
+	/* current poc being updated*/
+	opj_poc_t * l_current_poc = 00;
+
+	/* number of pocs*/
+	OPJ_UINT32 l_poc_bound;
+
+    OPJ_ARG_NOT_USED(p_max_res);
+
+	/* preconditions in debug*/
+	assert(p_cp != 00);
+	assert(p_tileno < p_cp->tw * p_cp->th);
+
+	/* initializations*/
+	l_tcp = &p_cp->tcps [p_tileno];
+	/* number of iterations in the loop */
+	l_poc_bound = l_tcp->numpocs+1;
+
+	/* start at first element, and to make sure the compiler will not make a calculation each time in the loop
+	   store a pointer to the current element to modify rather than l_tcp->pocs[i]*/
+	l_current_poc = l_tcp->pocs;
+
+	l_current_poc->compS = l_current_poc->compno0;
+	l_current_poc->compE = l_current_poc->compno1;
+	l_current_poc->resS = l_current_poc->resno0;
+	l_current_poc->resE = l_current_poc->resno1;
+	l_current_poc->layE = l_current_poc->layno1;
+
+	/* special treatment for the first element*/
+	l_current_poc->layS = 0;
+	l_current_poc->prg  = l_current_poc->prg1;
+	l_current_poc->prcS = 0;
+
+	l_current_poc->prcE = p_max_prec;
+	l_current_poc->txS = (OPJ_UINT32)p_tx0;
+	l_current_poc->txE = (OPJ_UINT32)p_tx1;
+	l_current_poc->tyS = (OPJ_UINT32)p_ty0;
+	l_current_poc->tyE = (OPJ_UINT32)p_ty1;
+	l_current_poc->dx = p_dx_min;
+	l_current_poc->dy = p_dy_min;
+
+	++ l_current_poc;
+	for (pino = 1;pino < l_poc_bound ; ++pino) {
+		l_current_poc->compS = l_current_poc->compno0;
+		l_current_poc->compE= l_current_poc->compno1;
+		l_current_poc->resS = l_current_poc->resno0;
+		l_current_poc->resE = l_current_poc->resno1;
+		l_current_poc->layE = l_current_poc->layno1;
+		l_current_poc->prg  = l_current_poc->prg1;
+		l_current_poc->prcS = 0;
+		/* special treatment here different from the first element*/
+		l_current_poc->layS = (l_current_poc->layE > (l_current_poc-1)->layE) ? l_current_poc->layE : 0;
+
+		l_current_poc->prcE = p_max_prec;
+		l_current_poc->txS = (OPJ_UINT32)p_tx0;
+		l_current_poc->txE = (OPJ_UINT32)p_tx1;
+		l_current_poc->tyS = (OPJ_UINT32)p_ty0;
+		l_current_poc->tyE = (OPJ_UINT32)p_ty1;
+		l_current_poc->dx = p_dx_min;
+		l_current_poc->dy = p_dy_min;
+		++ l_current_poc;
+	}
+}
+
+void opj_pi_update_encode_not_poc (	opj_cp_t *p_cp,
+                                    OPJ_UINT32 p_num_comps,
+                                    OPJ_UINT32 p_tileno,
+                                    OPJ_INT32 p_tx0,
+                                    OPJ_INT32 p_tx1,
+                                    OPJ_INT32 p_ty0,
+                                    OPJ_INT32 p_ty1,
+                                    OPJ_UINT32 p_max_prec,
+                                    OPJ_UINT32 p_max_res,
+                                    OPJ_UINT32 p_dx_min,
+                                    OPJ_UINT32 p_dy_min)
+{
+	/* loop*/
+	OPJ_UINT32 pino;
+	/* tile coding parameter*/
+	opj_tcp_t *l_tcp = 00;
+	/* current poc being updated*/
+	opj_poc_t * l_current_poc = 00;
+	/* number of pocs*/
+	OPJ_UINT32 l_poc_bound;
+
+	/* preconditions in debug*/
+	assert(p_cp != 00);
+	assert(p_tileno < p_cp->tw * p_cp->th);
+
+	/* initializations*/
+	l_tcp = &p_cp->tcps [p_tileno];
+
+	/* number of iterations in the loop */
+	l_poc_bound = l_tcp->numpocs+1;
+
+	/* start at first element, and to make sure the compiler will not make a calculation each time in the loop
+	   store a pointer to the current element to modify rather than l_tcp->pocs[i]*/
+	l_current_poc = l_tcp->pocs;
+
+	for (pino = 0; pino < l_poc_bound ; ++pino) {
+		l_current_poc->compS = 0;
+		l_current_poc->compE = p_num_comps;/*p_image->numcomps;*/
+		l_current_poc->resS = 0;
+		l_current_poc->resE = p_max_res;
+		l_current_poc->layS = 0;
+		l_current_poc->layE = l_tcp->numlayers;
+		l_current_poc->prg  = l_tcp->prg;
+		l_current_poc->prcS = 0;
+		l_current_poc->prcE = p_max_prec;
+		l_current_poc->txS = (OPJ_UINT32)p_tx0;
+		l_current_poc->txE = (OPJ_UINT32)p_tx1;
+		l_current_poc->tyS = (OPJ_UINT32)p_ty0;
+		l_current_poc->tyE = (OPJ_UINT32)p_ty1;
+		l_current_poc->dx = p_dx_min;
+		l_current_poc->dy = p_dy_min;
+		++ l_current_poc;
+	}
+}
+
+void opj_pi_update_decode_poc (opj_pi_iterator_t * p_pi,
+                               opj_tcp_t * p_tcp,
+                               OPJ_UINT32 p_max_precision,
+                               OPJ_UINT32 p_max_res)
+{
+	/* loop*/
+	OPJ_UINT32 pino;
+
+	/* encoding prameters to set*/
+	OPJ_UINT32 l_bound;
+
+	opj_pi_iterator_t * l_current_pi = 00;
+	opj_poc_t* l_current_poc = 0;
+
+    OPJ_ARG_NOT_USED(p_max_res);
+
+	/* preconditions in debug*/
+	assert(p_pi != 00);
+	assert(p_tcp != 00);
+
+	/* initializations*/
+	l_bound = p_tcp->numpocs+1;
+	l_current_pi = p_pi;
+	l_current_poc = p_tcp->pocs;
+
+	for	(pino = 0;pino<l_bound;++pino) {
+		l_current_pi->poc.prg = l_current_poc->prg; /* Progression Order #0 */
+		l_current_pi->first = 1;
+
+		l_current_pi->poc.resno0 = l_current_poc->resno0; /* Resolution Level Index #0 (Start) */
+		l_current_pi->poc.compno0 = l_current_poc->compno0; /* Component Index #0 (Start) */
+		l_current_pi->poc.layno0 = 0;
+		l_current_pi->poc.precno0 = 0;
+		l_current_pi->poc.resno1 = l_current_poc->resno1; /* Resolution Level Index #0 (End) */
+		l_current_pi->poc.compno1 = l_current_poc->compno1; /* Component Index #0 (End) */
+		l_current_pi->poc.layno1 = l_current_poc->layno1; /* Layer Index #0 (End) */
+		l_current_pi->poc.precno1 = p_max_precision;
+		++l_current_pi;
+		++l_current_poc;
+	}
+}
+
+void opj_pi_update_decode_not_poc (opj_pi_iterator_t * p_pi,
+                                   opj_tcp_t * p_tcp,
+                                   OPJ_UINT32 p_max_precision,
+                                   OPJ_UINT32 p_max_res)
+{
+	/* loop*/
+	OPJ_UINT32 pino;
+
+	/* encoding prameters to set*/
+	OPJ_UINT32 l_bound;
+
+	opj_pi_iterator_t * l_current_pi = 00;
+	/* preconditions in debug*/
+	assert(p_tcp != 00);
+	assert(p_pi != 00);
+
+	/* initializations*/
+	l_bound = p_tcp->numpocs+1;
+	l_current_pi = p_pi;
+
+	for (pino = 0;pino<l_bound;++pino) {
+		l_current_pi->poc.prg = p_tcp->prg;
+		l_current_pi->first = 1;
+		l_current_pi->poc.resno0 = 0;
+		l_current_pi->poc.compno0 = 0;
+		l_current_pi->poc.layno0 = 0;
+		l_current_pi->poc.precno0 = 0;
+		l_current_pi->poc.resno1 = p_max_res;
+		l_current_pi->poc.compno1 = l_current_pi->numcomps;
+		l_current_pi->poc.layno1 = p_tcp->numlayers;
+		l_current_pi->poc.precno1 = p_max_precision;
+		++l_current_pi;
+	}
+}
+
+
+
+OPJ_BOOL opj_pi_check_next_level(	OPJ_INT32 pos,
+								opj_cp_t *cp,
+								OPJ_UINT32 tileno,
+								OPJ_UINT32 pino,
+								const OPJ_CHAR *prog)
+{
+	OPJ_INT32 i;
+	opj_tcp_t *tcps =&cp->tcps[tileno];
+	opj_poc_t *tcp = &tcps->pocs[pino];
+
+	if(pos>=0){
+		for(i=pos;pos>=0;i--){
+			switch(prog[i]){
+		    case 'R':
+			    if(tcp->res_t==tcp->resE){
+				    if(opj_pi_check_next_level(pos-1,cp,tileno,pino,prog)){
+					    return OPJ_TRUE;
+				    }else{
+					    return OPJ_FALSE;
+				    }
+			    }else{
+				    return OPJ_TRUE;
+			    }
+			    break;
+		    case 'C':
+			    if(tcp->comp_t==tcp->compE){
+				    if(opj_pi_check_next_level(pos-1,cp,tileno,pino,prog)){
+					    return OPJ_TRUE;
+				    }else{
+					    return OPJ_FALSE;
+				    }
+			    }else{
+				    return OPJ_TRUE;
+			    }
+			    break;
+		    case 'L':
+			    if(tcp->lay_t==tcp->layE){
+				    if(opj_pi_check_next_level(pos-1,cp,tileno,pino,prog)){
+					    return OPJ_TRUE;
+				    }else{
+					    return OPJ_FALSE;
+				    }
+			    }else{
+				    return OPJ_TRUE;
+			    }
+			    break;
+		    case 'P':
+			    switch(tcp->prg){
+				    case OPJ_LRCP||OPJ_RLCP:
+					    if(tcp->prc_t == tcp->prcE){
+						    if(opj_pi_check_next_level(i-1,cp,tileno,pino,prog)){
+							    return OPJ_TRUE;
+						    }else{
+							    return OPJ_FALSE;
+						    }
+					    }else{
+						    return OPJ_TRUE;
+					    }
+					    break;
+			    default:
+				    if(tcp->tx0_t == tcp->txE){
+					    /*TY*/
+					    if(tcp->ty0_t == tcp->tyE){
+						    if(opj_pi_check_next_level(i-1,cp,tileno,pino,prog)){
+							    return OPJ_TRUE;
+						    }else{
+							    return OPJ_FALSE;
+						    }
+					    }else{
+						    return OPJ_TRUE;
+					    }/*TY*/
+				    }else{
+					    return OPJ_TRUE;
+				    }
+				    break;
+			    }/*end case P*/
+		    }/*end switch*/
+		}/*end for*/
+	}/*end if*/
+	return OPJ_FALSE;
+}
+
+
+/*
+==========================================================
+   Packet iterator interface
+==========================================================
+*/
+opj_pi_iterator_t *opj_pi_create_decode(opj_image_t *p_image,
+										opj_cp_t *p_cp,
+										OPJ_UINT32 p_tile_no)
+{
+	/* loop */
+	OPJ_UINT32 pino;
+	OPJ_UINT32 compno, resno;
+
+	/* to store w, h, dx and dy fro all components and resolutions */
+	OPJ_UINT32 * l_tmp_data;
+	OPJ_UINT32 ** l_tmp_ptr;
+
+	/* encoding prameters to set */
+	OPJ_UINT32 l_max_res;
+	OPJ_UINT32 l_max_prec;
+	OPJ_INT32 l_tx0,l_tx1,l_ty0,l_ty1;
+	OPJ_UINT32 l_dx_min,l_dy_min;
+	OPJ_UINT32 l_bound;
+	OPJ_UINT32 l_step_p , l_step_c , l_step_r , l_step_l ;
+	OPJ_UINT32 l_data_stride;
+
+	/* pointers */
+	opj_pi_iterator_t *l_pi = 00;
+	opj_tcp_t *l_tcp = 00;
+	const opj_tccp_t *l_tccp = 00;
+	opj_pi_comp_t *l_current_comp = 00;
+	opj_image_comp_t * l_img_comp = 00;
+	opj_pi_iterator_t * l_current_pi = 00;
+	OPJ_UINT32 * l_encoding_value_ptr = 00;
+
+	/* preconditions in debug */
+	assert(p_cp != 00);
+	assert(p_image != 00);
+	assert(p_tile_no < p_cp->tw * p_cp->th);
+
+	/* initializations */
+	l_tcp = &p_cp->tcps[p_tile_no];
+	l_bound = l_tcp->numpocs+1;
+
+	l_data_stride = 4 * OPJ_J2K_MAXRLVLS;
+	l_tmp_data = (OPJ_UINT32*)opj_malloc(
+		l_data_stride * p_image->numcomps * sizeof(OPJ_UINT32));
+	if
+		(! l_tmp_data)
+	{
+		return 00;
+	}
+	l_tmp_ptr = (OPJ_UINT32**)opj_malloc(
+		p_image->numcomps * sizeof(OPJ_UINT32 *));
+	if
+		(! l_tmp_ptr)
+	{
+		opj_free(l_tmp_data);
+		return 00;
+	}
+
+	/* memory allocation for pi */
+	l_pi = opj_pi_create(p_image, p_cp, p_tile_no);
+	if (!l_pi) {
+		opj_free(l_tmp_data);
+		opj_free(l_tmp_ptr);
+		return 00;
+	}
+
+	l_encoding_value_ptr = l_tmp_data;
+	/* update pointer array */
+	for
+		(compno = 0; compno < p_image->numcomps; ++compno)
+	{
+		l_tmp_ptr[compno] = l_encoding_value_ptr;
+		l_encoding_value_ptr += l_data_stride;
+	}
+	/* get encoding parameters */
+	opj_get_all_encoding_parameters(p_image,p_cp,p_tile_no,&l_tx0,&l_tx1,&l_ty0,&l_ty1,&l_dx_min,&l_dy_min,&l_max_prec,&l_max_res,l_tmp_ptr);
+
+	/* step calculations */
+	l_step_p = 1;
+	l_step_c = l_max_prec * l_step_p;
+	l_step_r = p_image->numcomps * l_step_c;
+	l_step_l = l_max_res * l_step_r;
+
+	/* set values for first packet iterator */
+	l_current_pi = l_pi;
+
+	/* memory allocation for include */
+	l_current_pi->include = (OPJ_INT16*) opj_calloc((l_tcp->numlayers +1) * l_step_l, sizeof(OPJ_INT16));
+	if
+		(!l_current_pi->include)
+	{
+		opj_free(l_tmp_data);
+		opj_free(l_tmp_ptr);
+		opj_pi_destroy(l_pi, l_bound);
+		return 00;
+	}
+	memset(l_current_pi->include,0, (l_tcp->numlayers + 1) * l_step_l* sizeof(OPJ_INT16));
+
+	/* special treatment for the first packet iterator */
+	l_current_comp = l_current_pi->comps;
+	l_img_comp = p_image->comps;
+	l_tccp = l_tcp->tccps;
+
+	l_current_pi->tx0 = l_tx0;
+	l_current_pi->ty0 = l_ty0;
+	l_current_pi->tx1 = l_tx1;
+	l_current_pi->ty1 = l_ty1;
+
+	/*l_current_pi->dx = l_img_comp->dx;*/
+	/*l_current_pi->dy = l_img_comp->dy;*/
+
+	l_current_pi->step_p = l_step_p;
+	l_current_pi->step_c = l_step_c;
+	l_current_pi->step_r = l_step_r;
+	l_current_pi->step_l = l_step_l;
+
+	/* allocation for components and number of components has already been calculated by opj_pi_create */
+	for
+		(compno = 0; compno < l_current_pi->numcomps; ++compno)
+	{
+		opj_pi_resolution_t *l_res = l_current_comp->resolutions;
+		l_encoding_value_ptr = l_tmp_ptr[compno];
+
+		l_current_comp->dx = l_img_comp->dx;
+		l_current_comp->dy = l_img_comp->dy;
+		/* resolutions have already been initialized */
+		for
+			(resno = 0; resno < l_current_comp->numresolutions; resno++)
+		{
+			l_res->pdx = *(l_encoding_value_ptr++);
+			l_res->pdy = *(l_encoding_value_ptr++);
+			l_res->pw =  *(l_encoding_value_ptr++);
+			l_res->ph =  *(l_encoding_value_ptr++);
+			++l_res;
+		}
+		++l_current_comp;
+		++l_img_comp;
+		++l_tccp;
+	}
+	++l_current_pi;
+
+	for (pino = 1 ; pino<l_bound ; ++pino )
+	{
+		l_current_comp = l_current_pi->comps;
+		l_img_comp = p_image->comps;
+		l_tccp = l_tcp->tccps;
+
+		l_current_pi->tx0 = l_tx0;
+		l_current_pi->ty0 = l_ty0;
+		l_current_pi->tx1 = l_tx1;
+		l_current_pi->ty1 = l_ty1;
+		/*l_current_pi->dx = l_dx_min;*/
+		/*l_current_pi->dy = l_dy_min;*/
+		l_current_pi->step_p = l_step_p;
+		l_current_pi->step_c = l_step_c;
+		l_current_pi->step_r = l_step_r;
+		l_current_pi->step_l = l_step_l;
+
+		/* allocation for components and number of components has already been calculated by opj_pi_create */
+		for
+			(compno = 0; compno < l_current_pi->numcomps; ++compno)
+		{
+			opj_pi_resolution_t *l_res = l_current_comp->resolutions;
+			l_encoding_value_ptr = l_tmp_ptr[compno];
+
+			l_current_comp->dx = l_img_comp->dx;
+			l_current_comp->dy = l_img_comp->dy;
+			/* resolutions have already been initialized */
+			for
+				(resno = 0; resno < l_current_comp->numresolutions; resno++)
+			{
+				l_res->pdx = *(l_encoding_value_ptr++);
+				l_res->pdy = *(l_encoding_value_ptr++);
+				l_res->pw =  *(l_encoding_value_ptr++);
+				l_res->ph =  *(l_encoding_value_ptr++);
+				++l_res;
+			}
+			++l_current_comp;
+			++l_img_comp;
+			++l_tccp;
+		}
+		/* special treatment*/
+		l_current_pi->include = (l_current_pi-1)->include;
+		++l_current_pi;
+	}
+	opj_free(l_tmp_data);
+	l_tmp_data = 00;
+	opj_free(l_tmp_ptr);
+	l_tmp_ptr = 00;
+	if
+		(l_tcp->POC)
+	{
+		opj_pi_update_decode_poc (l_pi,l_tcp,l_max_prec,l_max_res);
+	}
+	else
+	{
+		opj_pi_update_decode_not_poc(l_pi,l_tcp,l_max_prec,l_max_res);
+	}
+	return l_pi;
+}
+
+
+
+opj_pi_iterator_t *opj_pi_initialise_encode(const opj_image_t *p_image,
+                                            opj_cp_t *p_cp,
+                                            OPJ_UINT32 p_tile_no,
+                                            J2K_T2_MODE p_t2_mode )
+{
+	/* loop*/
+	OPJ_UINT32 pino;
+	OPJ_UINT32 compno, resno;
+
+	/* to store w, h, dx and dy fro all components and resolutions*/
+	OPJ_UINT32 * l_tmp_data;
+	OPJ_UINT32 ** l_tmp_ptr;
+
+	/* encoding prameters to set*/
+	OPJ_UINT32 l_max_res;
+	OPJ_UINT32 l_max_prec;
+	OPJ_INT32 l_tx0,l_tx1,l_ty0,l_ty1;
+	OPJ_UINT32 l_dx_min,l_dy_min;
+	OPJ_UINT32 l_bound;
+	OPJ_UINT32 l_step_p , l_step_c , l_step_r , l_step_l ;
+	OPJ_UINT32 l_data_stride;
+
+	/* pointers*/
+	opj_pi_iterator_t *l_pi = 00;
+	opj_tcp_t *l_tcp = 00;
+	const opj_tccp_t *l_tccp = 00;
+	opj_pi_comp_t *l_current_comp = 00;
+	opj_image_comp_t * l_img_comp = 00;
+	opj_pi_iterator_t * l_current_pi = 00;
+	OPJ_UINT32 * l_encoding_value_ptr = 00;
+
+	/* preconditions in debug*/
+	assert(p_cp != 00);
+	assert(p_image != 00);
+	assert(p_tile_no < p_cp->tw * p_cp->th);
+
+	/* initializations*/
+	l_tcp = &p_cp->tcps[p_tile_no];
+	l_bound = l_tcp->numpocs+1;
+
+	l_data_stride = 4 * OPJ_J2K_MAXRLVLS;
+	l_tmp_data = (OPJ_UINT32*)opj_malloc(
+		l_data_stride * p_image->numcomps * sizeof(OPJ_UINT32));
+	if (! l_tmp_data) {
+		return 00;
+	}
+
+	l_tmp_ptr = (OPJ_UINT32**)opj_malloc(
+		p_image->numcomps * sizeof(OPJ_UINT32 *));
+	if (! l_tmp_ptr) {
+		opj_free(l_tmp_data);
+		return 00;
+	}
+
+	/* memory allocation for pi*/
+	l_pi = opj_pi_create(p_image,p_cp,p_tile_no);
+	if (!l_pi) {
+		opj_free(l_tmp_data);
+		opj_free(l_tmp_ptr);
+		return 00;
+	}
+
+	l_encoding_value_ptr = l_tmp_data;
+	/* update pointer array*/
+	for (compno = 0; compno < p_image->numcomps; ++compno) {
+		l_tmp_ptr[compno] = l_encoding_value_ptr;
+		l_encoding_value_ptr += l_data_stride;
+	}
+
+	/* get encoding parameters*/
+	opj_get_all_encoding_parameters(p_image,p_cp,p_tile_no,&l_tx0,&l_tx1,&l_ty0,&l_ty1,&l_dx_min,&l_dy_min,&l_max_prec,&l_max_res,l_tmp_ptr);
+
+	/* step calculations*/
+	l_step_p = 1;
+	l_step_c = l_max_prec * l_step_p;
+	l_step_r = p_image->numcomps * l_step_c;
+	l_step_l = l_max_res * l_step_r;
+
+	/* set values for first packet iterator*/
+	l_pi->tp_on = p_cp->m_specific_param.m_enc.m_tp_on;
+	l_current_pi = l_pi;
+
+	/* memory allocation for include*/
+	l_current_pi->include = (OPJ_INT16*) opj_calloc(l_tcp->numlayers * l_step_l, sizeof(OPJ_INT16));
+	if (!l_current_pi->include) {
+		opj_free(l_tmp_data);
+		opj_free(l_tmp_ptr);
+		opj_pi_destroy(l_pi, l_bound);
+		return 00;
+	}
+	memset(l_current_pi->include,0,l_tcp->numlayers * l_step_l* sizeof(OPJ_INT16));
+
+	/* special treatment for the first packet iterator*/
+	l_current_comp = l_current_pi->comps;
+	l_img_comp = p_image->comps;
+	l_tccp = l_tcp->tccps;
+	l_current_pi->tx0 = l_tx0;
+	l_current_pi->ty0 = l_ty0;
+	l_current_pi->tx1 = l_tx1;
+	l_current_pi->ty1 = l_ty1;
+	l_current_pi->dx = l_dx_min;
+	l_current_pi->dy = l_dy_min;
+	l_current_pi->step_p = l_step_p;
+	l_current_pi->step_c = l_step_c;
+	l_current_pi->step_r = l_step_r;
+	l_current_pi->step_l = l_step_l;
+
+	/* allocation for components and number of components has already been calculated by opj_pi_create */
+	for (compno = 0; compno < l_current_pi->numcomps; ++compno) {
+		opj_pi_resolution_t *l_res = l_current_comp->resolutions;
+		l_encoding_value_ptr = l_tmp_ptr[compno];
+
+		l_current_comp->dx = l_img_comp->dx;
+		l_current_comp->dy = l_img_comp->dy;
+
+		/* resolutions have already been initialized */
+		for (resno = 0; resno < l_current_comp->numresolutions; resno++) {
+			l_res->pdx = *(l_encoding_value_ptr++);
+			l_res->pdy = *(l_encoding_value_ptr++);
+			l_res->pw =  *(l_encoding_value_ptr++);
+			l_res->ph =  *(l_encoding_value_ptr++);
+			++l_res;
+		}
+
+		++l_current_comp;
+		++l_img_comp;
+		++l_tccp;
+	}
+	++l_current_pi;
+
+	for (pino = 1 ; pino<l_bound ; ++pino ) {
+		l_current_comp = l_current_pi->comps;
+		l_img_comp = p_image->comps;
+		l_tccp = l_tcp->tccps;
+
+		l_current_pi->tx0 = l_tx0;
+		l_current_pi->ty0 = l_ty0;
+		l_current_pi->tx1 = l_tx1;
+		l_current_pi->ty1 = l_ty1;
+		l_current_pi->dx = l_dx_min;
+		l_current_pi->dy = l_dy_min;
+		l_current_pi->step_p = l_step_p;
+		l_current_pi->step_c = l_step_c;
+		l_current_pi->step_r = l_step_r;
+		l_current_pi->step_l = l_step_l;
+
+		/* allocation for components and number of components has already been calculated by opj_pi_create */
+		for (compno = 0; compno < l_current_pi->numcomps; ++compno) {
+			opj_pi_resolution_t *l_res = l_current_comp->resolutions;
+			l_encoding_value_ptr = l_tmp_ptr[compno];
+
+			l_current_comp->dx = l_img_comp->dx;
+			l_current_comp->dy = l_img_comp->dy;
+			/* resolutions have already been initialized */
+			for (resno = 0; resno < l_current_comp->numresolutions; resno++) {
+				l_res->pdx = *(l_encoding_value_ptr++);
+				l_res->pdy = *(l_encoding_value_ptr++);
+				l_res->pw =  *(l_encoding_value_ptr++);
+				l_res->ph =  *(l_encoding_value_ptr++);
+				++l_res;
+			}
+			++l_current_comp;
+			++l_img_comp;
+			++l_tccp;
+		}
+
+		/* special treatment*/
+		l_current_pi->include = (l_current_pi-1)->include;
+		++l_current_pi;
+	}
+
+	opj_free(l_tmp_data);
+	l_tmp_data = 00;
+	opj_free(l_tmp_ptr);
+	l_tmp_ptr = 00;
+
+	if (l_tcp->POC && ( p_cp->m_specific_param.m_enc.m_cinema || p_t2_mode == FINAL_PASS)) {
+		opj_pi_update_encode_poc_and_final(p_cp,p_tile_no,l_tx0,l_tx1,l_ty0,l_ty1,l_max_prec,l_max_res,l_dx_min,l_dy_min);
+	}
+	else {
+		opj_pi_update_encode_not_poc(p_cp,p_image->numcomps,p_tile_no,l_tx0,l_tx1,l_ty0,l_ty1,l_max_prec,l_max_res,l_dx_min,l_dy_min);
+	}
+
+	return l_pi;
+}
+
+void opj_pi_create_encode( 	opj_pi_iterator_t *pi,
+							opj_cp_t *cp,
+							OPJ_UINT32 tileno,
+							OPJ_UINT32 pino,
+							OPJ_UINT32 tpnum,
+							OPJ_INT32 tppos,
+							J2K_T2_MODE t2_mode)
+{
+	const OPJ_CHAR *prog;
+	OPJ_INT32 i;
+	OPJ_UINT32 incr_top=1,resetX=0;
+	opj_tcp_t *tcps =&cp->tcps[tileno];
+	opj_poc_t *tcp= &tcps->pocs[pino];
+
+	prog = opj_j2k_convert_progression_order(tcp->prg);
+
+	pi[pino].first = 1;
+	pi[pino].poc.prg = tcp->prg;
+
+	if(!(cp->m_specific_param.m_enc.m_tp_on && ((!cp->m_specific_param.m_enc.m_cinema && (t2_mode == FINAL_PASS)) || cp->m_specific_param.m_enc.m_cinema))){
+		pi[pino].poc.resno0 = tcp->resS;
+		pi[pino].poc.resno1 = tcp->resE;
+		pi[pino].poc.compno0 = tcp->compS;
+		pi[pino].poc.compno1 = tcp->compE;
+		pi[pino].poc.layno0 = tcp->layS;
+		pi[pino].poc.layno1 = tcp->layE;
+		pi[pino].poc.precno0 = tcp->prcS;
+		pi[pino].poc.precno1 = tcp->prcE;
+		pi[pino].poc.tx0 = (OPJ_INT32)tcp->txS;
+		pi[pino].poc.ty0 = (OPJ_INT32)tcp->tyS;
+		pi[pino].poc.tx1 = (OPJ_INT32)tcp->txE;
+		pi[pino].poc.ty1 = (OPJ_INT32)tcp->tyE;
+	}else {
+		for(i=tppos+1;i<4;i++){
+			switch(prog[i]){
+			case 'R':
+				pi[pino].poc.resno0 = tcp->resS;
+				pi[pino].poc.resno1 = tcp->resE;
+				break;
+			case 'C':
+				pi[pino].poc.compno0 = tcp->compS;
+				pi[pino].poc.compno1 = tcp->compE;
+				break;
+			case 'L':
+				pi[pino].poc.layno0 = tcp->layS;
+				pi[pino].poc.layno1 = tcp->layE;
+				break;
+			case 'P':
+				switch(tcp->prg){
+				case OPJ_LRCP:
+				case OPJ_RLCP:
+					pi[pino].poc.precno0 = tcp->prcS;
+					pi[pino].poc.precno1 = tcp->prcE;
+					break;
+				default:
+					pi[pino].poc.tx0 = (OPJ_INT32)tcp->txS;
+					pi[pino].poc.ty0 = (OPJ_INT32)tcp->tyS;
+					pi[pino].poc.tx1 = (OPJ_INT32)tcp->txE;
+					pi[pino].poc.ty1 = (OPJ_INT32)tcp->tyE;
+					break;
+				}
+				break;
+			}
+		}
+
+		if(tpnum==0){
+			for(i=tppos;i>=0;i--){
+				switch(prog[i]){
+				case 'C':
+					tcp->comp_t = tcp->compS;
+					pi[pino].poc.compno0 = tcp->comp_t;
+					pi[pino].poc.compno1 = tcp->comp_t+1;
+					tcp->comp_t+=1;
+					break;
+				case 'R':
+					tcp->res_t = tcp->resS;
+					pi[pino].poc.resno0 = tcp->res_t;
+					pi[pino].poc.resno1 = tcp->res_t+1;
+					tcp->res_t+=1;
+					break;
+				case 'L':
+					tcp->lay_t = tcp->layS;
+					pi[pino].poc.layno0 = tcp->lay_t;
+					pi[pino].poc.layno1 = tcp->lay_t+1;
+					tcp->lay_t+=1;
+					break;
+				case 'P':
+					switch(tcp->prg){
+					case OPJ_LRCP:
+					case OPJ_RLCP:
+						tcp->prc_t = tcp->prcS;
+						pi[pino].poc.precno0 = tcp->prc_t;
+						pi[pino].poc.precno1 = tcp->prc_t+1;
+						tcp->prc_t+=1;
+						break;
+					default:
+						tcp->tx0_t = tcp->txS;
+						tcp->ty0_t = tcp->tyS;
+						pi[pino].poc.tx0 = (OPJ_INT32)tcp->tx0_t;
+						pi[pino].poc.tx1 = (OPJ_INT32)(tcp->tx0_t + tcp->dx - (tcp->tx0_t % tcp->dx));
+						pi[pino].poc.ty0 = (OPJ_INT32)tcp->ty0_t;
+						pi[pino].poc.ty1 = (OPJ_INT32)(tcp->ty0_t + tcp->dy - (tcp->ty0_t % tcp->dy));
+						tcp->tx0_t = (OPJ_UINT32)pi[pino].poc.tx1;
+						tcp->ty0_t = (OPJ_UINT32)pi[pino].poc.ty1;
+						break;
+					}
+					break;
+				}
+			}
+			incr_top=1;
+		}else{
+			for(i=tppos;i>=0;i--){
+				switch(prog[i]){
+				case 'C':
+					pi[pino].poc.compno0 = tcp->comp_t-1;
+					pi[pino].poc.compno1 = tcp->comp_t;
+					break;
+				case 'R':
+					pi[pino].poc.resno0 = tcp->res_t-1;
+					pi[pino].poc.resno1 = tcp->res_t;
+					break;
+				case 'L':
+					pi[pino].poc.layno0 = tcp->lay_t-1;
+					pi[pino].poc.layno1 = tcp->lay_t;
+					break;
+				case 'P':
+					switch(tcp->prg){
+					case OPJ_LRCP:
+					case OPJ_RLCP:
+						pi[pino].poc.precno0 = tcp->prc_t-1;
+						pi[pino].poc.precno1 = tcp->prc_t;
+						break;
+					default:
+						pi[pino].poc.tx0 = (OPJ_INT32)(tcp->tx0_t - tcp->dx - (tcp->tx0_t % tcp->dx));
+						pi[pino].poc.tx1 = (OPJ_INT32)tcp->tx0_t ;
+						pi[pino].poc.ty0 = (OPJ_INT32)(tcp->ty0_t - tcp->dy - (tcp->ty0_t % tcp->dy));
+						pi[pino].poc.ty1 = (OPJ_INT32)tcp->ty0_t ;
+						break;
+					}
+					break;
+				}
+				if(incr_top==1){
+					switch(prog[i]){
+					case 'R':
+						if(tcp->res_t==tcp->resE){
+							if(opj_pi_check_next_level(i-1,cp,tileno,pino,prog)){
+								tcp->res_t = tcp->resS;
+								pi[pino].poc.resno0 = tcp->res_t;
+								pi[pino].poc.resno1 = tcp->res_t+1;
+								tcp->res_t+=1;
+								incr_top=1;
+							}else{
+								incr_top=0;
+							}
+						}else{
+							pi[pino].poc.resno0 = tcp->res_t;
+							pi[pino].poc.resno1 = tcp->res_t+1;
+							tcp->res_t+=1;
+							incr_top=0;
+						}
+						break;
+					case 'C':
+						if(tcp->comp_t ==tcp->compE){
+							if(opj_pi_check_next_level(i-1,cp,tileno,pino,prog)){
+								tcp->comp_t = tcp->compS;
+								pi[pino].poc.compno0 = tcp->comp_t;
+								pi[pino].poc.compno1 = tcp->comp_t+1;
+								tcp->comp_t+=1;
+								incr_top=1;
+							}else{
+								incr_top=0;
+							}
+						}else{
+							pi[pino].poc.compno0 = tcp->comp_t;
+							pi[pino].poc.compno1 = tcp->comp_t+1;
+							tcp->comp_t+=1;
+							incr_top=0;
+						}
+						break;
+					case 'L':
+						if(tcp->lay_t == tcp->layE){
+							if(opj_pi_check_next_level(i-1,cp,tileno,pino,prog)){
+								tcp->lay_t = tcp->layS;
+								pi[pino].poc.layno0 = tcp->lay_t;
+								pi[pino].poc.layno1 = tcp->lay_t+1;
+								tcp->lay_t+=1;
+								incr_top=1;
+							}else{
+								incr_top=0;
+							}
+						}else{
+							pi[pino].poc.layno0 = tcp->lay_t;
+							pi[pino].poc.layno1 = tcp->lay_t+1;
+							tcp->lay_t+=1;
+							incr_top=0;
+						}
+						break;
+					case 'P':
+						switch(tcp->prg){
+						case OPJ_LRCP:
+						case OPJ_RLCP:
+							if(tcp->prc_t == tcp->prcE){
+								if(opj_pi_check_next_level(i-1,cp,tileno,pino,prog)){
+									tcp->prc_t = tcp->prcS;
+									pi[pino].poc.precno0 = tcp->prc_t;
+									pi[pino].poc.precno1 = tcp->prc_t+1;
+									tcp->prc_t+=1;
+									incr_top=1;
+								}else{
+									incr_top=0;
+								}
+							}else{
+								pi[pino].poc.precno0 = tcp->prc_t;
+								pi[pino].poc.precno1 = tcp->prc_t+1;
+								tcp->prc_t+=1;
+								incr_top=0;
+							}
+							break;
+						default:
+							if(tcp->tx0_t >= tcp->txE){
+								if(tcp->ty0_t >= tcp->tyE){
+									if(opj_pi_check_next_level(i-1,cp,tileno,pino,prog)){
+										tcp->ty0_t = tcp->tyS;
+										pi[pino].poc.ty0 = (OPJ_INT32)tcp->ty0_t;
+										pi[pino].poc.ty1 = (OPJ_INT32)(tcp->ty0_t + tcp->dy - (tcp->ty0_t % tcp->dy));
+										tcp->ty0_t = (OPJ_UINT32)pi[pino].poc.ty1;
+										incr_top=1;resetX=1;
+									}else{
+										incr_top=0;resetX=0;
+									}
+								}else{
+									pi[pino].poc.ty0 = (OPJ_INT32)tcp->ty0_t;
+									pi[pino].poc.ty1 = (OPJ_INT32)(tcp->ty0_t + tcp->dy - (tcp->ty0_t % tcp->dy));
+									tcp->ty0_t = (OPJ_UINT32)pi[pino].poc.ty1;
+									incr_top=0;resetX=1;
+								}
+								if(resetX==1){
+									tcp->tx0_t = tcp->txS;
+									pi[pino].poc.tx0 = (OPJ_INT32)tcp->tx0_t;
+									pi[pino].poc.tx1 = (OPJ_INT32)(tcp->tx0_t + tcp->dx- (tcp->tx0_t % tcp->dx));
+									tcp->tx0_t = (OPJ_UINT32)pi[pino].poc.tx1;
+								}
+							}else{
+								pi[pino].poc.tx0 = (OPJ_INT32)tcp->tx0_t;
+								pi[pino].poc.tx1 = (OPJ_INT32)(tcp->tx0_t + tcp->dx- (tcp->tx0_t % tcp->dx));
+								tcp->tx0_t = (OPJ_UINT32)pi[pino].poc.tx1;
+								incr_top=0;
+							}
+							break;
+						}
+						break;
+					}
+				}
+			}
+		}
+	}
+}
+
+void opj_pi_destroy(opj_pi_iterator_t *p_pi,
+                    OPJ_UINT32 p_nb_elements)
+{
+	OPJ_UINT32 compno, pino;
+	opj_pi_iterator_t *l_current_pi = p_pi;
+    if (p_pi) {
+		if (p_pi->include) {
+			opj_free(p_pi->include);
+			p_pi->include = 00;
+		}
+		for (pino = 0; pino < p_nb_elements; ++pino){
+			if(l_current_pi->comps) {
+				opj_pi_comp_t *l_current_component = l_current_pi->comps;
+                for (compno = 0; compno < l_current_pi->numcomps; compno++){
+                    if(l_current_component->resolutions) {
+						opj_free(l_current_component->resolutions);
+						l_current_component->resolutions = 00;
+					}
+
+					++l_current_component;
+				}
+				opj_free(l_current_pi->comps);
+				l_current_pi->comps = 0;
+			}
+			++l_current_pi;
+		}
+		opj_free(p_pi);
+	}
+}
+
+
+
+void opj_pi_update_encoding_parameters(	const opj_image_t *p_image,
+                                        opj_cp_t *p_cp,
+                                        OPJ_UINT32 p_tile_no )
+{
+	/* encoding parameters to set */
+	OPJ_UINT32 l_max_res;
+	OPJ_UINT32 l_max_prec;
+	OPJ_INT32 l_tx0,l_tx1,l_ty0,l_ty1;
+	OPJ_UINT32 l_dx_min,l_dy_min;
+
+	/* pointers */
+	opj_tcp_t *l_tcp = 00;
+
+	/* preconditions */
+	assert(p_cp != 00);
+	assert(p_image != 00);
+	assert(p_tile_no < p_cp->tw * p_cp->th);
+
+	l_tcp = &(p_cp->tcps[p_tile_no]);
+
+	/* get encoding parameters */
+	opj_get_encoding_parameters(p_image,p_cp,p_tile_no,&l_tx0,&l_tx1,&l_ty0,&l_ty1,&l_dx_min,&l_dy_min,&l_max_prec,&l_max_res);
+
+	if (l_tcp->POC) {
+		opj_pi_update_encode_poc_and_final(p_cp,p_tile_no,l_tx0,l_tx1,l_ty0,l_ty1,l_max_prec,l_max_res,l_dx_min,l_dy_min);
+	}
+	else {
+		opj_pi_update_encode_not_poc(p_cp,p_image->numcomps,p_tile_no,l_tx0,l_tx1,l_ty0,l_ty1,l_max_prec,l_max_res,l_dx_min,l_dy_min);
+	}
+}
+
+OPJ_BOOL opj_pi_next(opj_pi_iterator_t * pi) {
+	switch (pi->poc.prg) {
+		case OPJ_LRCP:
+			return opj_pi_next_lrcp(pi);
+		case OPJ_RLCP:
+			return opj_pi_next_rlcp(pi);
+		case OPJ_RPCL:
+			return opj_pi_next_rpcl(pi);
+		case OPJ_PCRL:
+			return opj_pi_next_pcrl(pi);
+		case OPJ_CPRL:
+			return opj_pi_next_cprl(pi);
+		case OPJ_PROG_UNKNOWN:
+			return OPJ_FALSE;
+	}
+	
+	return OPJ_FALSE;
+}
diff --git a/Source/LibOpenJPEG/pi.h b/Source/LibOpenJPEG/pi.h
index d90bf53..605ddbc 100644
--- a/Source/LibOpenJPEG/pi.h
+++ b/Source/LibOpenJPEG/pi.h
@@ -1,156 +1,182 @@
-/*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
- * Copyright (c) 2001-2003, David Janssens
- * Copyright (c) 2002-2003, Yannick Verschueren
- * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __PI_H
-#define __PI_H
-/**
- at file pi.h
- at brief Implementation of a packet iterator (PI)
-
-The functions in PI.C have for goal to realize a packet iterator that permits to get the next
-packet following the progression order and change of it. The functions in PI.C are used
-by some function in T2.C.
-*/
-
-/** @defgroup PI PI - Implementation of a packet iterator */
-/*@{*/
-
-/**
-FIXME: documentation
-*/
-typedef struct opj_pi_resolution {
-  int pdx, pdy;
-  int pw, ph;
-} opj_pi_resolution_t;
-
-/**
-FIXME: documentation
-*/
-typedef struct opj_pi_comp {
-  int dx, dy;
-  /** number of resolution levels */
-  int numresolutions;
-  opj_pi_resolution_t *resolutions;
-} opj_pi_comp_t;
-
-/** 
-Packet iterator 
-*/
-typedef struct opj_pi_iterator {
-	/** Enabling Tile part generation*/
-	char tp_on;
-	/** precise if the packet has been already used (usefull for progression order change) */
-	short int *include;
-	/** layer step used to localize the packet in the include vector */
-	int step_l;
-	/** resolution step used to localize the packet in the include vector */
-	int step_r;	
-	/** component step used to localize the packet in the include vector */
-	int step_c;	
-	/** precinct step used to localize the packet in the include vector */
-	int step_p;	
-	/** component that identify the packet */
-	int compno;
-	/** resolution that identify the packet */
-	int resno;
-	/** precinct that identify the packet */
-	int precno;
-	/** layer that identify the packet */
-	int layno;   
-	/** 0 if the first packet */
-	int first;
-	/** progression order change information */
-	opj_poc_t poc;
-	/** number of components in the image */
-	int numcomps;
-	/** Components*/
-	opj_pi_comp_t *comps;
-	int tx0, ty0, tx1, ty1;
-	int x, y, dx, dy;
-} opj_pi_iterator_t;
-
-/** @name Exported functions */
-/*@{*/
-/* ----------------------------------------------------------------------- */
-/**
-Create a packet iterator for Encoder
- at param image Raw image for which the packets will be listed
- at param cp Coding parameters
- at param tileno Number that identifies the tile for which to list the packets
- at param t2_mode If == 0 In Threshold calculation ,If == 1 Final pass
- at return Returns a packet iterator that points to the first packet of the tile
- at see pi_destroy
-*/
-opj_pi_iterator_t *pi_initialise_encode(opj_image_t *image, opj_cp_t *cp, int tileno,J2K_T2_MODE t2_mode);
-/**
-Modify the packet iterator for enabling tile part generation
- at param pi Handle to the packet iterator generated in pi_initialise_encode  
- at param cp Coding parameters
- at param tileno Number that identifies the tile for which to list the packets
- at param pino Iterator index for pi
- at param tpnum Tile part number of the current tile
- at param tppos The position of the tile part flag in the progression order
- at param t2_mode If == 0 In Threshold calculation ,If == 1 Final pass
- at param cur_totnum_tp The total number of tile parts in the current tile
- at return Returns true if an error is detected 
-*/
-opj_bool pi_create_encode(opj_pi_iterator_t *pi, opj_cp_t *cp,int tileno, int pino,int tpnum, int tppos, J2K_T2_MODE t2_mode,int cur_totnum_tp);
-/**
-Create a packet iterator for Decoder
- at param image Raw image for which the packets will be listed
- at param cp Coding parameters
- at param tileno Number that identifies the tile for which to list the packets
- at return Returns a packet iterator that points to the first packet of the tile
- at see pi_destroy
-*/
-opj_pi_iterator_t *pi_create_decode(opj_image_t * image, opj_cp_t * cp, int tileno);
-
-/**
-Destroy a packet iterator
- at param pi Previously created packet iterator
- at param cp Coding parameters
- at param tileno Number that identifies the tile for which the packets were listed
- at see pi_create
-*/
-void pi_destroy(opj_pi_iterator_t *pi, opj_cp_t *cp, int tileno);
-
-/**
-Modify the packet iterator to point to the next packet
- at param pi Packet iterator to modify
- at return Returns false if pi pointed to the last packet or else returns true 
-*/
-opj_bool pi_next(opj_pi_iterator_t * pi);
-/* ----------------------------------------------------------------------- */
-/*@}*/
-
-/*@}*/
-
-#endif /* __PI_H */
+/*
+ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2007, Professor Benoit Macq
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __PI_H
+#define __PI_H
+/**
+ at file pi.h
+ at brief Implementation of a packet iterator (PI)
+
+The functions in PI.C have for goal to realize a packet iterator that permits to get the next
+packet following the progression order and change of it. The functions in PI.C are used
+by some function in T2.C.
+*/
+
+/** @defgroup PI PI - Implementation of a packet iterator */
+/*@{*/
+
+/**
+FIXME DOC
+*/
+typedef struct opj_pi_resolution {
+  OPJ_UINT32 pdx, pdy;
+  OPJ_UINT32 pw, ph;
+} opj_pi_resolution_t;
+
+/**
+FIXME DOC
+*/
+typedef struct opj_pi_comp {
+  OPJ_UINT32 dx, dy;
+  /** number of resolution levels */
+  OPJ_UINT32 numresolutions;
+  opj_pi_resolution_t *resolutions;
+} opj_pi_comp_t;
+
+/**
+Packet iterator
+*/
+typedef struct opj_pi_iterator {
+  /** Enabling Tile part generation*/
+  OPJ_BYTE tp_on;
+  /** precise if the packet has been already used (usefull for progression order change) */
+  OPJ_INT16 *include;
+  /** layer step used to localize the packet in the include vector */
+  OPJ_UINT32 step_l;
+  /** resolution step used to localize the packet in the include vector */
+  OPJ_UINT32 step_r;
+  /** component step used to localize the packet in the include vector */
+  OPJ_UINT32 step_c;
+  /** precinct step used to localize the packet in the include vector */
+  OPJ_UINT32 step_p;
+  /** component that identify the packet */
+  OPJ_UINT32 compno;
+  /** resolution that identify the packet */
+  OPJ_UINT32 resno;
+  /** precinct that identify the packet */
+  OPJ_UINT32 precno;
+  /** layer that identify the packet */
+  OPJ_UINT32 layno;
+  /** 0 if the first packet */
+  OPJ_BOOL first;
+  /** progression order change information */
+  opj_poc_t poc;
+  /** number of components in the image */
+  OPJ_UINT32 numcomps;
+  /** Components*/
+  opj_pi_comp_t *comps;
+  /** FIXME DOC*/
+  OPJ_INT32 tx0, ty0, tx1, ty1;
+  /** FIXME DOC*/
+  OPJ_INT32 x, y;
+  /** FIXME DOC*/
+  OPJ_UINT32 dx, dy;
+} opj_pi_iterator_t;
+
+/** @name Exported functions */
+/*@{*/
+/* ----------------------------------------------------------------------- */
+/**
+ * Creates a packet iterator for encoding.
+ *
+ * @param	image		the image being encoded.
+ * @param	cp		the coding parameters.
+ * @param	tileno	index of the tile being encoded.
+ * @param	t2_mode	the type of pass for generating the packet iterator
+ *
+ * @return	a list of packet iterator that points to the first packet of the tile (not true).
+*/
+opj_pi_iterator_t *opj_pi_initialise_encode(const opj_image_t *image,
+                                            opj_cp_t *cp,
+                                            OPJ_UINT32 tileno,
+                                            J2K_T2_MODE t2_mode);
+
+/**
+ * Updates the encoding parameters of the codec.
+ *
+ * @param	p_image		the image being encoded.
+ * @param	p_cp		the coding parameters.
+ * @param	p_tile_no	index of the tile being encoded.
+*/
+void opj_pi_update_encoding_parameters(	const opj_image_t *p_image,
+                                        opj_cp_t *p_cp,
+                                        OPJ_UINT32 p_tile_no );
+
+/**
+Modify the packet iterator for enabling tile part generation
+ at param pi Handle to the packet iterator generated in pi_initialise_encode
+ at param cp Coding parameters
+ at param tileno Number that identifies the tile for which to list the packets
+ at param pino   FIXME DOC
+ at param tpnum Tile part number of the current tile
+ at param tppos The position of the tile part flag in the progression order
+ at param t2_mode FIXME DOC
+*/
+void opj_pi_create_encode(  opj_pi_iterator_t *pi, 
+                            opj_cp_t *cp,
+                            OPJ_UINT32 tileno, 
+                            OPJ_UINT32 pino,
+                            OPJ_UINT32 tpnum, 
+                            OPJ_INT32 tppos, 
+                            J2K_T2_MODE t2_mode);
+
+/**
+Create a packet iterator for Decoder
+ at param image Raw image for which the packets will be listed
+ at param cp Coding parameters
+ at param tileno Number that identifies the tile for which to list the packets
+ at return Returns a packet iterator that points to the first packet of the tile
+ at see opj_pi_destroy
+*/
+opj_pi_iterator_t *opj_pi_create_decode(opj_image_t * image, 
+                                        opj_cp_t * cp,
+                                        OPJ_UINT32 tileno);
+/**
+ * Destroys a packet iterator array.
+ *
+ * @param	p_pi			the packet iterator array to destroy.
+ * @param	p_nb_elements	the number of elements in the array.
+ */
+void opj_pi_destroy(opj_pi_iterator_t *p_pi,
+                    OPJ_UINT32 p_nb_elements);
+
+/**
+Modify the packet iterator to point to the next packet
+ at param pi Packet iterator to modify
+ at return Returns false if pi pointed to the last packet or else returns true
+*/
+OPJ_BOOL opj_pi_next(opj_pi_iterator_t * pi);
+/* ----------------------------------------------------------------------- */
+/*@}*/
+
+/*@}*/
+
+#endif /* __PI_H */
diff --git a/Source/LibOpenJPEG/ppix_manager.c b/Source/LibOpenJPEG/ppix_manager.c
index 96e35ff..e93db2d 100644
--- a/Source/LibOpenJPEG/ppix_manager.c
+++ b/Source/LibOpenJPEG/ppix_manager.c
@@ -1,5 +1,5 @@
 /*
- * $Id: ppix_manager.c,v 1.2 2012/09/23 12:44:41 drolon Exp $
+ * $Id: ppix_manager.c,v 1.4 2014/03/16 12:29:52 drolon Exp $
  *
  * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
  * Copyright (c) 2002-2011, Professor Benoit Macq
@@ -33,9 +33,6 @@
  *  \brief Modification of jpip.c from 2KAN indexer
  */
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
 #include "opj_includes.h"
 
 /* 
@@ -49,49 +46,65 @@
  * @param[in] cio       file output handle
  * @return              length of faix box
  */
-int write_ppixfaix( int coff, int compno, opj_codestream_info_t cstr_info, opj_bool EPHused, int j2klen, opj_cio_t *cio);
 
-int write_ppix( int coff, opj_codestream_info_t cstr_info, opj_bool EPHused, int j2klen, opj_cio_t *cio)
+
+int opj_write_ppix( int coff, opj_codestream_info_t cstr_info, OPJ_BOOL EPHused, int j2klen, opj_stream_private_t *cio,
+              opj_event_mgr_t * p_manager )
 {
-  int len, lenp, compno, i;
+  OPJ_BYTE l_data_header [4];
+  int compno, i;
   opj_jp2_box_t *box;
+  OPJ_OFF_T lenp;
+  OPJ_UINT32 len;
 
   /*  printf("cstr_info.packno %d\n", cstr_info.packno); //NMAX? */
 
   lenp = -1;
-  box = (opj_jp2_box_t *)opj_calloc( cstr_info.numcomps, sizeof(opj_jp2_box_t));
+  box = (opj_jp2_box_t *)opj_calloc( (size_t)cstr_info.numcomps, sizeof(opj_jp2_box_t));
   
   for (i=0;i<2;i++){
-    if (i) cio_seek( cio, lenp);
+    if (i)
+
+      opj_stream_seek( cio, lenp, p_manager);
     
-    lenp = cio_tell( cio);
-    cio_skip( cio, 4);              /* L [at the end] */
-    cio_write( cio, JPIP_PPIX, 4);  /* PPIX           */
+    lenp = (OPJ_UINT32)(opj_stream_tell(cio));
+    opj_stream_skip( cio, 4, p_manager);       /* L [at the end] */
+    opj_write_bytes(l_data_header,JPIP_PPIX,4);/* PPIX           */
+    opj_stream_write_data(cio,l_data_header,4,p_manager);
 
-    write_manf( i, cstr_info.numcomps, box, cio);
+    opj_write_manf( i, cstr_info.numcomps, box, cio, p_manager);
     
     for (compno=0; compno<cstr_info.numcomps; compno++){
-      box[compno].length = write_ppixfaix( coff, compno, cstr_info, EPHused, j2klen, cio);
+      box[compno].length = (OPJ_UINT32)opj_write_ppixfaix( coff, compno, cstr_info, EPHused, j2klen, cio,p_manager);
       box[compno].type = JPIP_FAIX;
     }
    
-    len = cio_tell( cio)-lenp;
-    cio_seek( cio, lenp);
-    cio_write( cio, len, 4);        /* L              */
-    cio_seek( cio, lenp+len);
+
+  len = (OPJ_UINT32)(opj_stream_tell(cio)-lenp);
+  opj_stream_seek(cio, lenp,p_manager);
+  opj_write_bytes(l_data_header,len,4);/* L              */
+  opj_stream_write_data(cio,l_data_header,4,p_manager);
+  opj_stream_seek(cio, lenp+len,p_manager);
   }
   
   opj_free(box);
 
-  return len;
+  return (int)len;
 }
 
-int write_ppixfaix( int coff, int compno, opj_codestream_info_t cstr_info, opj_bool EPHused, int j2klen, opj_cio_t *cio)
+
+
+int opj_write_ppixfaix( int coff, int compno, opj_codestream_info_t cstr_info, OPJ_BOOL EPHused, int j2klen, opj_stream_private_t *cio,
+              opj_event_mgr_t * p_manager )
 {
-  int len, lenp, tileno, version, i, nmax, size_of_coding; /* 4 or 8*/
+  OPJ_BYTE l_data_header [8];
+  OPJ_UINT32 tileno, version, i, nmax, size_of_coding; /* 4 or 8*/
+  OPJ_UINT32 len;
+  OPJ_OFF_T lenp;
   opj_tile_info_t *tile_Idx;
   opj_packet_info_t packet;
-  int resno, precno, layno, num_packet;
+  int resno, precno, layno;
+  OPJ_UINT32 num_packet;
   int numOfres, numOfprec, numOflayers;
   packet.end_pos = packet.end_ph_pos = packet.start_pos = -1;
   (void)EPHused; /* unused ? */
@@ -105,19 +118,22 @@ int write_ppixfaix( int coff, int compno, opj_codestream_info_t cstr_info, opj_b
     version = 0;
   }
   
-  lenp = cio_tell( cio);
-  cio_skip( cio, 4);              /* L [at the end]      */
-  cio_write( cio, JPIP_FAIX, 4);  /* FAIX                */ 
-  cio_write( cio, version, 1);     /* Version 0 = 4 bytes */
+  lenp = opj_stream_tell(cio);
+  opj_stream_skip(cio, 4, p_manager);         /* L [at the end]      */
+  opj_write_bytes(l_data_header,JPIP_FAIX,4); /* FAIX */
+  opj_write_bytes(l_data_header,version,1);
+  opj_stream_write_data(cio,l_data_header,1,p_manager);/* Version 0 = 4 bytes */
 
   nmax = 0;
-  for( i=0; i<=cstr_info.numdecompos[compno]; i++)
-    nmax += cstr_info.tile[0].ph[i] * cstr_info.tile[0].pw[i] * cstr_info.numlayers;
+  for( i=0; i<=(OPJ_UINT32)cstr_info.numdecompos[compno]; i++)
+    nmax += (OPJ_UINT32)(cstr_info.tile[0].ph[i] * cstr_info.tile[0].pw[i] * cstr_info.numlayers);
   
-  cio_write( cio, nmax, size_of_coding); /* NMAX */
-  cio_write( cio, cstr_info.tw*cstr_info.th, size_of_coding);      /* M    */
+  opj_write_bytes(l_data_header,nmax,size_of_coding);         /* NMAX           */
+  opj_stream_write_data(cio,l_data_header,size_of_coding,p_manager);
+  opj_write_bytes(l_data_header,(OPJ_UINT32)(cstr_info.tw*cstr_info.th),size_of_coding);  /* M              */
+  opj_stream_write_data(cio,l_data_header,size_of_coding,p_manager);
 
-  for( tileno=0; tileno<cstr_info.tw*cstr_info.th; tileno++){
+  for( tileno=0; tileno<(OPJ_UINT32)(cstr_info.tw*cstr_info.th); tileno++){
     tile_Idx = &cstr_info.tile[ tileno];
  
     num_packet=0;
@@ -130,27 +146,29 @@ int write_ppixfaix( int coff, int compno, opj_codestream_info_t cstr_info, opj_b
 	for( layno=0; layno<numOflayers; layno++){
 
 	  switch ( cstr_info.prog){
-	  case LRCP:
+	  case OPJ_LRCP:
 	    packet = tile_Idx->packet[ ((layno*numOfres+resno)*cstr_info.numcomps+compno)*numOfprec+precno];
 	    break;
-	  case RLCP:
+	  case OPJ_RLCP:
 	    packet = tile_Idx->packet[ ((resno*numOflayers+layno)*cstr_info.numcomps+compno)*numOfprec+precno];
 	    break;
-	  case RPCL:
+	  case OPJ_RPCL:
 	    packet = tile_Idx->packet[ ((resno*numOfprec+precno)*cstr_info.numcomps+compno)*numOflayers+layno];
 	    break;
-	  case PCRL:
+	  case OPJ_PCRL:
 	    packet = tile_Idx->packet[ ((precno*cstr_info.numcomps+compno)*numOfres+resno)*numOflayers + layno];
 	    break;
-	  case CPRL:
+	  case OPJ_CPRL:
 	    packet = tile_Idx->packet[ ((compno*numOfprec+precno)*numOfres+resno)*numOflayers + layno];
 	    break;
 	  default:
 	    fprintf( stderr, "failed to ppix indexing\n");
 	  }
 
-	  cio_write( cio, packet.start_pos-coff, size_of_coding);             /* start position */
-	  cio_write( cio, packet.end_pos-packet.start_pos+1, size_of_coding); /* length         */
+    opj_write_bytes(l_data_header,(OPJ_UINT32)(packet.start_pos-coff),size_of_coding);            /* start position */
+    opj_stream_write_data(cio,l_data_header,size_of_coding,p_manager);
+    opj_write_bytes(l_data_header,(OPJ_UINT32)(packet.end_pos-packet.start_pos+1),size_of_coding); /* length         */
+    opj_stream_write_data(cio,l_data_header,size_of_coding,p_manager);
 	  
 	  num_packet++;
 	}
@@ -158,16 +176,19 @@ int write_ppixfaix( int coff, int compno, opj_codestream_info_t cstr_info, opj_b
     }
   
     while( num_packet < nmax){     /* PADDING */
-      cio_write( cio, 0, size_of_coding); /* start position            */
-      cio_write( cio, 0, size_of_coding); /* length                    */
+      opj_write_bytes(l_data_header,0,size_of_coding);/* start position            */
+      opj_stream_write_data(cio,l_data_header,size_of_coding,p_manager);
+      opj_write_bytes(l_data_header,0,size_of_coding);/* length                    */
+      opj_stream_write_data(cio,l_data_header,size_of_coding,p_manager);
       num_packet++;
     }   
   }
 
-  len = cio_tell( cio)-lenp;
-  cio_seek( cio, lenp);
-  cio_write( cio, len, 4);        /* L  */
-  cio_seek( cio, lenp+len);
+  len = (OPJ_UINT32)(opj_stream_tell(cio)-lenp);
+  opj_stream_seek(cio, lenp,p_manager);
+  opj_write_bytes(l_data_header,len,4);/* L  */
+  opj_stream_write_data(cio,l_data_header,4,p_manager);
+  opj_stream_seek(cio, lenp+len,p_manager);
 
-  return len;
+  return (int)len;
 }
diff --git a/Source/LibOpenJPEG/raw.c b/Source/LibOpenJPEG/raw.c
index 265ecbd..8e705cc 100644
--- a/Source/LibOpenJPEG/raw.c
+++ b/Source/LibOpenJPEG/raw.c
@@ -1,87 +1,89 @@
-/*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
- * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "opj_includes.h"
-
-/* 
-==========================================================
-   local functions
-==========================================================
-*/
-
-
-/* 
-==========================================================
-   RAW encoding interface
-==========================================================
-*/
-
-opj_raw_t* raw_create(void) {
-	opj_raw_t *raw = (opj_raw_t*)opj_malloc(sizeof(opj_raw_t));
-	return raw;
-}
-
-void raw_destroy(opj_raw_t *raw) {
-	if(raw) {
-		opj_free(raw);
-	}
-}
-
-int raw_numbytes(opj_raw_t *raw) {
-	return raw->bp - raw->start;
-}
-
-void raw_init_dec(opj_raw_t *raw, unsigned char *bp, int len) {
-	raw->start = bp;
-	raw->lenmax = len;
-	raw->len = 0;
-	raw->c = 0;
-	raw->ct = 0;
-}
-
-int raw_decode(opj_raw_t *raw) {
-	int d;
-	if (raw->ct == 0) {
-		raw->ct = 8;
-		if (raw->len == raw->lenmax) {
-			raw->c = 0xff;
-		} else {
-			if (raw->c == 0xff) {
-				raw->ct = 7;
-			}
-			raw->c = *(raw->start + raw->len);
-			raw->len++;
-		}
-	}
-	raw->ct--;
-	d = (raw->c >> raw->ct) & 0x01;
-	
-	return d;
-}
-
+/*
+ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2007, Professor Benoit Macq
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "opj_includes.h"
+
+/* 
+==========================================================
+   local functions
+==========================================================
+*/
+
+
+/* 
+==========================================================
+   RAW encoding interface
+==========================================================
+*/
+
+opj_raw_t* opj_raw_create(void) {
+	opj_raw_t *raw = (opj_raw_t*)opj_malloc(sizeof(opj_raw_t));
+	return raw;
+}
+
+void opj_raw_destroy(opj_raw_t *raw) {
+	if(raw) {
+		opj_free(raw);
+	}
+}
+
+OPJ_UINT32 opj_raw_numbytes(opj_raw_t *raw) {
+	const ptrdiff_t diff = raw->bp - raw->start;
+  assert( diff <= (ptrdiff_t)0xffffffff && diff >= 0 ); /* UINT32_MAX */
+	return (OPJ_UINT32)diff;
+}
+
+void opj_raw_init_dec(opj_raw_t *raw, OPJ_BYTE *bp, OPJ_UINT32 len) {
+	raw->start = bp;
+	raw->lenmax = len;
+	raw->len = 0;
+	raw->c = 0;
+	raw->ct = 0;
+}
+
+OPJ_UINT32 opj_raw_decode(opj_raw_t *raw) {
+	OPJ_UINT32 d;
+	if (raw->ct == 0) {
+		raw->ct = 8;
+		if (raw->len == raw->lenmax) {
+			raw->c = 0xff;
+		} else {
+			if (raw->c == 0xff) {
+				raw->ct = 7;
+			}
+			raw->c = *(raw->start + raw->len);
+			raw->len++;
+		}
+	}
+	raw->ct--;
+	d = (raw->c >> raw->ct) & 0x01;
+	
+	return d;
+}
+
diff --git a/Source/LibOpenJPEG/raw.h b/Source/LibOpenJPEG/raw.h
index f873ac5..6ae6239 100644
--- a/Source/LibOpenJPEG/raw.h
+++ b/Source/LibOpenJPEG/raw.h
@@ -1,100 +1,100 @@
-/*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
- * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __RAW_H
-#define __RAW_H
-/**
- at file raw.h
- at brief Implementation of operations for raw encoding (RAW)
-
-The functions in RAW.C have for goal to realize the operation of raw encoding linked
-with the corresponding mode switch.
-*/
-
-/** @defgroup RAW RAW - Implementation of operations for raw encoding */
-/*@{*/
-
-/**
-RAW encoding operations
-*/
-typedef struct opj_raw {
-	/** temporary buffer where bits are coded or decoded */
-	unsigned char c;
-	/** number of bits already read or free to write */
-	unsigned int ct;
-	/** maximum length to decode */
-	unsigned int lenmax;
-	/** length decoded */
-	unsigned int len;
-	/** pointer to the current position in the buffer */
-	unsigned char *bp;
-	/** pointer to the start of the buffer */
-	unsigned char *start;
-	/** pointer to the end of the buffer */
-	unsigned char *end;
-} opj_raw_t;
-
-/** @name Exported functions */
-/*@{*/
-/* ----------------------------------------------------------------------- */
-/**
-Create a new RAW handle 
- at return Returns a new RAW handle if successful, returns NULL otherwise
-*/
-opj_raw_t* raw_create(void);
-/**
-Destroy a previously created RAW handle
- at param raw RAW handle to destroy
-*/
-void raw_destroy(opj_raw_t *raw);
-/**
-Return the number of bytes written/read since initialisation
- at param raw RAW handle to destroy
- at return Returns the number of bytes already encoded
-*/
-int raw_numbytes(opj_raw_t *raw);
-/**
-Initialize the decoder
- at param raw RAW handle
- at param bp Pointer to the start of the buffer from which the bytes will be read
- at param len Length of the input buffer
-*/
-void raw_init_dec(opj_raw_t *raw, unsigned char *bp, int len);
-/**
-Decode a symbol using raw-decoder. Cfr p.506 TAUBMAN
- at param raw RAW handle
- at return Returns the decoded symbol (0 or 1)
-*/
-int raw_decode(opj_raw_t *raw);
-/* ----------------------------------------------------------------------- */
-/*@}*/
-
-/*@}*/
-
-#endif /* __RAW_H */
+/*
+ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2007, Professor Benoit Macq
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __RAW_H
+#define __RAW_H
+/**
+ at file raw.h
+ at brief Implementation of operations for raw encoding (RAW)
+
+The functions in RAW.C have for goal to realize the operation of raw encoding linked
+with the corresponding mode switch.
+*/
+
+/** @defgroup RAW RAW - Implementation of operations for raw encoding */
+/*@{*/
+
+/**
+RAW encoding operations
+*/
+typedef struct opj_raw {
+	/** temporary buffer where bits are coded or decoded */
+	OPJ_BYTE c;
+	/** number of bits already read or free to write */
+	OPJ_UINT32 ct;
+	/** maximum length to decode */
+	OPJ_UINT32 lenmax;
+	/** length decoded */
+	OPJ_UINT32 len;
+	/** pointer to the current position in the buffer */
+	OPJ_BYTE *bp;
+	/** pointer to the start of the buffer */
+	OPJ_BYTE *start;
+	/** pointer to the end of the buffer */
+	OPJ_BYTE *end;
+} opj_raw_t;
+
+/** @name Exported functions */
+/*@{*/
+/* ----------------------------------------------------------------------- */
+/**
+Create a new RAW handle 
+ at return Returns a new RAW handle if successful, returns NULL otherwise
+*/
+opj_raw_t* opj_raw_create(void);
+/**
+Destroy a previously created RAW handle
+ at param raw RAW handle to destroy
+*/
+void opj_raw_destroy(opj_raw_t *raw);
+/**
+Return the number of bytes written/read since initialisation
+ at param raw RAW handle to destroy
+ at return Returns the number of bytes already encoded
+*/
+OPJ_UINT32 opj_raw_numbytes(opj_raw_t *raw);
+/**
+Initialize the decoder
+ at param raw RAW handle
+ at param bp Pointer to the start of the buffer from which the bytes will be read
+ at param len Length of the input buffer
+*/
+void opj_raw_init_dec(opj_raw_t *raw, OPJ_BYTE *bp, OPJ_UINT32 len);
+/**
+Decode a symbol using raw-decoder. Cfr p.506 TAUBMAN
+ at param raw RAW handle
+ at return Returns the decoded symbol (0 or 1)
+*/
+OPJ_UINT32 opj_raw_decode(opj_raw_t *raw);
+/* ----------------------------------------------------------------------- */
+/*@}*/
+
+/*@}*/
+
+#endif /* __RAW_H */
diff --git a/Source/LibOpenJPEG/t1.c b/Source/LibOpenJPEG/t1.c
index 4b0f5c4..59a219d 100644
--- a/Source/LibOpenJPEG/t1.c
+++ b/Source/LibOpenJPEG/t1.c
@@ -1,1585 +1,1751 @@
-/*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
- * Copyright (c) 2001-2003, David Janssens
- * Copyright (c) 2002-2003, Yannick Verschueren
- * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * Copyright (c) 2007, Callum Lerwick <seg at haxxed.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "opj_includes.h"
-#include "t1_luts.h"
-
-/** @defgroup T1 T1 - Implementation of the tier-1 coding */
-/*@{*/
-
-/** @name Local static functions */
-/*@{*/
-
-static INLINE char t1_getctxno_zc(int f, int orient);
-static char t1_getctxno_sc(int f);
-static INLINE int t1_getctxno_mag(int f);
-static char t1_getspb(int f);
-static short t1_getnmsedec_sig(int x, int bitpos);
-static short t1_getnmsedec_ref(int x, int bitpos);
-static void t1_updateflags(flag_t *flagsp, int s, int stride);
-/**
-Encode significant pass
-*/
-static void t1_enc_sigpass_step(
-		opj_t1_t *t1,
-		flag_t *flagsp,
-		int *datap,
-		int orient,
-		int bpno,
-		int one,
-		int *nmsedec,
-		char type,
-		int vsc);
-/**
-Decode significant pass
-*/
-static INLINE void t1_dec_sigpass_step_raw(
-		opj_t1_t *t1,
-		flag_t *flagsp,
-		int *datap,
-		int orient,
-		int oneplushalf,
-		int vsc);
-static INLINE void t1_dec_sigpass_step_mqc(
-		opj_t1_t *t1,
-		flag_t *flagsp,
-		int *datap,
-		int orient,
-		int oneplushalf);
-static INLINE void t1_dec_sigpass_step_mqc_vsc(
-		opj_t1_t *t1,
-		flag_t *flagsp,
-		int *datap,
-		int orient,
-		int oneplushalf,
-		int vsc);
-/**
-Encode significant pass
-*/
-static void t1_enc_sigpass(
-		opj_t1_t *t1,
-		int bpno,
-		int orient,
-		int *nmsedec,
-		char type,
-		int cblksty);
-/**
-Decode significant pass
-*/
-static void t1_dec_sigpass_raw(
-		opj_t1_t *t1,
-		int bpno,
-		int orient,
-		int cblksty);
-static void t1_dec_sigpass_mqc(
-		opj_t1_t *t1,
-		int bpno,
-		int orient);
-static void t1_dec_sigpass_mqc_vsc(
-		opj_t1_t *t1,
-		int bpno,
-		int orient);
-/**
-Encode refinement pass
-*/
-static void t1_enc_refpass_step(
-		opj_t1_t *t1,
-		flag_t *flagsp,
-		int *datap,
-		int bpno,
-		int one,
-		int *nmsedec,
-		char type,
-		int vsc);
-/**
-Decode refinement pass
-*/
-static INLINE void t1_dec_refpass_step_raw(
-		opj_t1_t *t1,
-		flag_t *flagsp,
-		int *datap,
-		int poshalf,
-		int neghalf,
-		int vsc);
-static INLINE void t1_dec_refpass_step_mqc(
-		opj_t1_t *t1,
-		flag_t *flagsp,
-		int *datap,
-		int poshalf,
-		int neghalf);
-static INLINE void t1_dec_refpass_step_mqc_vsc(
-		opj_t1_t *t1,
-		flag_t *flagsp,
-		int *datap,
-		int poshalf,
-		int neghalf,
-		int vsc);
-
-/**
-Encode refinement pass
-*/
-static void t1_enc_refpass(
-		opj_t1_t *t1,
-		int bpno,
-		int *nmsedec,
-		char type,
-		int cblksty);
-/**
-Decode refinement pass
-*/
-static void t1_dec_refpass_raw(
-		opj_t1_t *t1,
-		int bpno,
-		int cblksty);
-static void t1_dec_refpass_mqc(
-		opj_t1_t *t1,
-		int bpno);
-static void t1_dec_refpass_mqc_vsc(
-		opj_t1_t *t1,
-		int bpno);
-/**
-Encode clean-up pass
-*/
-static void t1_enc_clnpass_step(
-		opj_t1_t *t1,
-		flag_t *flagsp,
-		int *datap,
-		int orient,
-		int bpno,
-		int one,
-		int *nmsedec,
-		int partial,
-		int vsc);
-/**
-Decode clean-up pass
-*/
-static void t1_dec_clnpass_step_partial(
-		opj_t1_t *t1,
-		flag_t *flagsp,
-		int *datap,
-		int orient,
-		int oneplushalf);
-static void t1_dec_clnpass_step(
-		opj_t1_t *t1,
-		flag_t *flagsp,
-		int *datap,
-		int orient,
-		int oneplushalf);
-static void t1_dec_clnpass_step_vsc(
-		opj_t1_t *t1,
-		flag_t *flagsp,
-		int *datap,
-		int orient,
-		int oneplushalf,
-		int partial,
-		int vsc);
-/**
-Encode clean-up pass
-*/
-static void t1_enc_clnpass(
-		opj_t1_t *t1,
-		int bpno,
-		int orient,
-		int *nmsedec,
-		int cblksty);
-/**
-Decode clean-up pass
-*/
-static void t1_dec_clnpass(
-		opj_t1_t *t1,
-		int bpno,
-		int orient,
-		int cblksty);
-static double t1_getwmsedec(
-		int nmsedec,
-		int compno,
-		int level,
-		int orient,
-		int bpno,
-		int qmfbid,
-		double stepsize,
-		int numcomps,
-		int mct);
-/**
-Encode 1 code-block
- at param t1 T1 handle
- at param cblk Code-block coding parameters
- at param orient
- at param compno Component number
- at param level
- at param qmfbid
- at param stepsize
- at param cblksty Code-block style
- at param numcomps
- at param mct
- at param tile
-*/
-static void t1_encode_cblk(
-		opj_t1_t *t1,
-		opj_tcd_cblk_enc_t* cblk,
-		int orient,
-		int compno,
-		int level,
-		int qmfbid,
-		double stepsize,
-		int cblksty,
-		int numcomps,
-		int mct,
-		opj_tcd_tile_t * tile);
-/**
-Decode 1 code-block
- at param t1 T1 handle
- at param cblk Code-block coding parameters
- at param orient
- at param roishift Region of interest shifting value
- at param cblksty Code-block style
-*/
-static void t1_decode_cblk(
-		opj_t1_t *t1,
-		opj_tcd_cblk_dec_t* cblk,
-		int orient,
-		int roishift,
-		int cblksty);
-
-/*@}*/
-
-/*@}*/
-
-/* ----------------------------------------------------------------------- */
-
-static char t1_getctxno_zc(int f, int orient) {
-	return lut_ctxno_zc[(orient << 8) | (f & T1_SIG_OTH)];
-}
-
-static char t1_getctxno_sc(int f) {
-	return lut_ctxno_sc[(f & (T1_SIG_PRIM | T1_SGN)) >> 4];
-}
-
-static int t1_getctxno_mag(int f) {
-	int tmp1 = (f & T1_SIG_OTH) ? T1_CTXNO_MAG + 1 : T1_CTXNO_MAG;
-	int tmp2 = (f & T1_REFINE) ? T1_CTXNO_MAG + 2 : tmp1;
-	return (tmp2);
-}
-
-static char t1_getspb(int f) {
-	return lut_spb[(f & (T1_SIG_PRIM | T1_SGN)) >> 4];
-}
-
-static short t1_getnmsedec_sig(int x, int bitpos) {
-	if (bitpos > T1_NMSEDEC_FRACBITS) {
-		return lut_nmsedec_sig[(x >> (bitpos - T1_NMSEDEC_FRACBITS)) & ((1 << T1_NMSEDEC_BITS) - 1)];
-	}
-	
-	return lut_nmsedec_sig0[x & ((1 << T1_NMSEDEC_BITS) - 1)];
-}
-
-static short t1_getnmsedec_ref(int x, int bitpos) {
-	if (bitpos > T1_NMSEDEC_FRACBITS) {
-		return lut_nmsedec_ref[(x >> (bitpos - T1_NMSEDEC_FRACBITS)) & ((1 << T1_NMSEDEC_BITS) - 1)];
-	}
-
-    return lut_nmsedec_ref0[x & ((1 << T1_NMSEDEC_BITS) - 1)];
-}
-
-static void t1_updateflags(flag_t *flagsp, int s, int stride) {
-	flag_t *np = flagsp - stride;
-	flag_t *sp = flagsp + stride;
-
-	static const flag_t mod[] = {
-		T1_SIG_S, T1_SIG_S|T1_SGN_S,
-		T1_SIG_E, T1_SIG_E|T1_SGN_E,
-		T1_SIG_W, T1_SIG_W|T1_SGN_W,
-		T1_SIG_N, T1_SIG_N|T1_SGN_N
-	};
-
-	np[-1] |= T1_SIG_SE;
-	np[0]  |= mod[s];
-	np[1]  |= T1_SIG_SW;
-
-	flagsp[-1] |= mod[s+2];
-	flagsp[0]  |= T1_SIG;
-	flagsp[1]  |= mod[s+4];
-
-	sp[-1] |= T1_SIG_NE;
-	sp[0]  |= mod[s+6];
-	sp[1]  |= T1_SIG_NW;
-}
-
-static void t1_enc_sigpass_step(
-		opj_t1_t *t1,
-		flag_t *flagsp,
-		int *datap,
-		int orient,
-		int bpno,
-		int one,
-		int *nmsedec,
-		char type,
-		int vsc)
-{
-	int v, flag;
-	
-	opj_mqc_t *mqc = t1->mqc;	/* MQC component */
-	
-	flag = vsc ? ((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*flagsp);
-	if ((flag & T1_SIG_OTH) && !(flag & (T1_SIG | T1_VISIT))) {
-		v = int_abs(*datap) & one ? 1 : 0;
-		mqc_setcurctx(mqc, t1_getctxno_zc(flag, orient));	/* ESSAI */
-		if (type == T1_TYPE_RAW) {	/* BYPASS/LAZY MODE */
-			mqc_bypass_enc(mqc, v);
-		} else {
-			mqc_encode(mqc, v);
-		}
-		if (v) {
-			v = *datap < 0 ? 1 : 0;
-			*nmsedec +=	t1_getnmsedec_sig(int_abs(*datap), bpno + T1_NMSEDEC_FRACBITS);
-			mqc_setcurctx(mqc, t1_getctxno_sc(flag));	/* ESSAI */
-			if (type == T1_TYPE_RAW) {	/* BYPASS/LAZY MODE */
-				mqc_bypass_enc(mqc, v);
-			} else {
-				mqc_encode(mqc, v ^ t1_getspb(flag));
-			}
-			t1_updateflags(flagsp, v, t1->flags_stride);
-		}
-		*flagsp |= T1_VISIT;
-	}
-}
-
-static INLINE void t1_dec_sigpass_step_raw(
-		opj_t1_t *t1,
-		flag_t *flagsp,
-		int *datap,
-		int orient,
-		int oneplushalf,
-		int vsc)
-{
-	int v, flag;
-	opj_raw_t *raw = t1->raw;	/* RAW component */
-	
-	OPJ_ARG_NOT_USED(orient);
-	
-	flag = vsc ? ((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*flagsp);
-	if ((flag & T1_SIG_OTH) && !(flag & (T1_SIG | T1_VISIT))) {
-			if (raw_decode(raw)) {
-				v = raw_decode(raw);	/* ESSAI */
-				*datap = v ? -oneplushalf : oneplushalf;
-				t1_updateflags(flagsp, v, t1->flags_stride);
-			}
-		*flagsp |= T1_VISIT;
-	}
-}				/* VSC and  BYPASS by Antonin */
-
-static INLINE void t1_dec_sigpass_step_mqc(
-		opj_t1_t *t1,
-		flag_t *flagsp,
-		int *datap,
-		int orient,
-		int oneplushalf)
-{
-	int v, flag;
-	
-	opj_mqc_t *mqc = t1->mqc;	/* MQC component */
-	
-	flag = *flagsp;
-	if ((flag & T1_SIG_OTH) && !(flag & (T1_SIG | T1_VISIT))) {
-			mqc_setcurctx(mqc, t1_getctxno_zc(flag, orient));
-			if (mqc_decode(mqc)) {
-				mqc_setcurctx(mqc, t1_getctxno_sc(flag));
-				v = mqc_decode(mqc) ^ t1_getspb(flag);
-				*datap = v ? -oneplushalf : oneplushalf;
-				t1_updateflags(flagsp, v, t1->flags_stride);
-			}
-		*flagsp |= T1_VISIT;
-	}
-}				/* VSC and  BYPASS by Antonin */
-
-static INLINE void t1_dec_sigpass_step_mqc_vsc(
-		opj_t1_t *t1,
-		flag_t *flagsp,
-		int *datap,
-		int orient,
-		int oneplushalf,
-		int vsc)
-{
-	int v, flag;
-	
-	opj_mqc_t *mqc = t1->mqc;	/* MQC component */
-	
-	flag = vsc ? ((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*flagsp);
-	if ((flag & T1_SIG_OTH) && !(flag & (T1_SIG | T1_VISIT))) {
-		mqc_setcurctx(mqc, t1_getctxno_zc(flag, orient));
-		if (mqc_decode(mqc)) {
-			mqc_setcurctx(mqc, t1_getctxno_sc(flag));
-			v = mqc_decode(mqc) ^ t1_getspb(flag);
-			*datap = v ? -oneplushalf : oneplushalf;
-			t1_updateflags(flagsp, v, t1->flags_stride);
-		}
-		*flagsp |= T1_VISIT;
-	}
-}				/* VSC and  BYPASS by Antonin */
-
-static void t1_enc_sigpass(
-		opj_t1_t *t1,
-		int bpno,
-		int orient,
-		int *nmsedec,
-		char type,
-		int cblksty)
-{
-	int i, j, k, one, vsc;
-	*nmsedec = 0;
-	one = 1 << (bpno + T1_NMSEDEC_FRACBITS);
-	for (k = 0; k < t1->h; k += 4) {
-		for (i = 0; i < t1->w; ++i) {
-			for (j = k; j < k + 4 && j < t1->h; ++j) {
-				vsc = ((cblksty & J2K_CCP_CBLKSTY_VSC) && (j == k + 3 || j == t1->h - 1)) ? 1 : 0;
-				t1_enc_sigpass_step(
-						t1,
-						&t1->flags[((j+1) * t1->flags_stride) + i + 1],
-						&t1->data[(j * t1->w) + i],
-						orient,
-						bpno,
-						one,
-						nmsedec,
-						type,
-						vsc);
-			}
-		}
-	}
-}
-
-static void t1_dec_sigpass_raw(
-		opj_t1_t *t1,
-		int bpno,
-		int orient,
-		int cblksty)
-{
-	int i, j, k, one, half, oneplushalf, vsc;
-	one = 1 << bpno;
-	half = one >> 1;
-	oneplushalf = one | half;
-	for (k = 0; k < t1->h; k += 4) {
-		for (i = 0; i < t1->w; ++i) {
-			for (j = k; j < k + 4 && j < t1->h; ++j) {
-				vsc = ((cblksty & J2K_CCP_CBLKSTY_VSC) && (j == k + 3 || j == t1->h - 1)) ? 1 : 0;
-				t1_dec_sigpass_step_raw(
-						t1,
-						&t1->flags[((j+1) * t1->flags_stride) + i + 1],
-						&t1->data[(j * t1->w) + i],
-						orient,
-						oneplushalf,
-						vsc);
-			}
-		}
-	}
-}				/* VSC and  BYPASS by Antonin */
-
-static void t1_dec_sigpass_mqc(
-		opj_t1_t *t1,
-		int bpno,
-		int orient)
-{
-	int i, j, k, one, half, oneplushalf;
-	int *data1 = t1->data;
-	flag_t *flags1 = &t1->flags[1];
-	one = 1 << bpno;
-	half = one >> 1;
-	oneplushalf = one | half;
-	for (k = 0; k < (t1->h & ~3); k += 4) {
-		for (i = 0; i < t1->w; ++i) {
-			int *data2 = data1 + i;
-			flag_t *flags2 = flags1 + i;
-			flags2 += t1->flags_stride;
-			t1_dec_sigpass_step_mqc(t1, flags2, data2, orient, oneplushalf);
-			data2 += t1->w;
-			flags2 += t1->flags_stride;
-			t1_dec_sigpass_step_mqc(t1, flags2, data2, orient, oneplushalf);
-			data2 += t1->w;
-			flags2 += t1->flags_stride;
-			t1_dec_sigpass_step_mqc(t1, flags2, data2, orient, oneplushalf);
-			data2 += t1->w;
-			flags2 += t1->flags_stride;
-			t1_dec_sigpass_step_mqc(t1, flags2, data2, orient, oneplushalf);
-			data2 += t1->w;
-		}
-		data1 += t1->w << 2;
-		flags1 += t1->flags_stride << 2;
-	}
-	for (i = 0; i < t1->w; ++i) {
-		int *data2 = data1 + i;
-		flag_t *flags2 = flags1 + i;
-		for (j = k; j < t1->h; ++j) {
-			flags2 += t1->flags_stride;
-			t1_dec_sigpass_step_mqc(t1, flags2, data2, orient, oneplushalf);
-			data2 += t1->w;
-		}
-	}
-}				/* VSC and  BYPASS by Antonin */
-
-static void t1_dec_sigpass_mqc_vsc(
-		opj_t1_t *t1,
-		int bpno,
-		int orient)
-{
-	int i, j, k, one, half, oneplushalf, vsc;
-	one = 1 << bpno;
-	half = one >> 1;
-	oneplushalf = one | half;
-	for (k = 0; k < t1->h; k += 4) {
-		for (i = 0; i < t1->w; ++i) {
-			for (j = k; j < k + 4 && j < t1->h; ++j) {
-				vsc = (j == k + 3 || j == t1->h - 1) ? 1 : 0;
-				t1_dec_sigpass_step_mqc_vsc(
-						t1,
-						&t1->flags[((j+1) * t1->flags_stride) + i + 1],
-						&t1->data[(j * t1->w) + i],
-						orient,
-						oneplushalf,
-						vsc);
-			}
-		}
-	}
-}				/* VSC and  BYPASS by Antonin */
-
-static void t1_enc_refpass_step(
-		opj_t1_t *t1,
-		flag_t *flagsp,
-		int *datap,
-		int bpno,
-		int one,
-		int *nmsedec,
-		char type,
-		int vsc)
-{
-	int v, flag;
-	
-	opj_mqc_t *mqc = t1->mqc;	/* MQC component */
-	
-	flag = vsc ? ((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*flagsp);
-	if ((flag & (T1_SIG | T1_VISIT)) == T1_SIG) {
-		*nmsedec += t1_getnmsedec_ref(int_abs(*datap), bpno + T1_NMSEDEC_FRACBITS);
-		v = int_abs(*datap) & one ? 1 : 0;
-		mqc_setcurctx(mqc, t1_getctxno_mag(flag));	/* ESSAI */
-		if (type == T1_TYPE_RAW) {	/* BYPASS/LAZY MODE */
-			mqc_bypass_enc(mqc, v);
-		} else {
-			mqc_encode(mqc, v);
-		}
-		*flagsp |= T1_REFINE;
-	}
-}
-
-static INLINE void t1_dec_refpass_step_raw(
-		opj_t1_t *t1,
-		flag_t *flagsp,
-		int *datap,
-		int poshalf,
-		int neghalf,
-		int vsc)
-{
-	int v, t, flag;
-	
-	opj_raw_t *raw = t1->raw;	/* RAW component */
-	
-	flag = vsc ? ((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*flagsp);
-	if ((flag & (T1_SIG | T1_VISIT)) == T1_SIG) {
-			v = raw_decode(raw);
-		t = v ? poshalf : neghalf;
-		*datap += *datap < 0 ? -t : t;
-		*flagsp |= T1_REFINE;
-	}
-}				/* VSC and  BYPASS by Antonin  */
-
-static INLINE void t1_dec_refpass_step_mqc(
-		opj_t1_t *t1,
-		flag_t *flagsp,
-		int *datap,
-		int poshalf,
-		int neghalf)
-{
-	int v, t, flag;
-	
-	opj_mqc_t *mqc = t1->mqc;	/* MQC component */
-	
-	flag = *flagsp;
-	if ((flag & (T1_SIG | T1_VISIT)) == T1_SIG) {
-		mqc_setcurctx(mqc, t1_getctxno_mag(flag));	/* ESSAI */
-			v = mqc_decode(mqc);
-		t = v ? poshalf : neghalf;
-		*datap += *datap < 0 ? -t : t;
-		*flagsp |= T1_REFINE;
-		}
-}				/* VSC and  BYPASS by Antonin  */
-
-static INLINE void t1_dec_refpass_step_mqc_vsc(
-		opj_t1_t *t1,
-		flag_t *flagsp,
-		int *datap,
-		int poshalf,
-		int neghalf,
-		int vsc)
-{
-	int v, t, flag;
-	
-	opj_mqc_t *mqc = t1->mqc;	/* MQC component */
-	
-	flag = vsc ? ((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*flagsp);
-	if ((flag & (T1_SIG | T1_VISIT)) == T1_SIG) {
-		mqc_setcurctx(mqc, t1_getctxno_mag(flag));	/* ESSAI */
-		v = mqc_decode(mqc);
-		t = v ? poshalf : neghalf;
-		*datap += *datap < 0 ? -t : t;
-		*flagsp |= T1_REFINE;
-	}
-}				/* VSC and  BYPASS by Antonin  */
-
-static void t1_enc_refpass(
-		opj_t1_t *t1,
-		int bpno,
-		int *nmsedec,
-		char type,
-		int cblksty)
-{
-	int i, j, k, one, vsc;
-	*nmsedec = 0;
-	one = 1 << (bpno + T1_NMSEDEC_FRACBITS);
-	for (k = 0; k < t1->h; k += 4) {
-		for (i = 0; i < t1->w; ++i) {
-			for (j = k; j < k + 4 && j < t1->h; ++j) {
-				vsc = ((cblksty & J2K_CCP_CBLKSTY_VSC) && (j == k + 3 || j == t1->h - 1)) ? 1 : 0;
-				t1_enc_refpass_step(
-						t1,
-						&t1->flags[((j+1) * t1->flags_stride) + i + 1],
-						&t1->data[(j * t1->w) + i],
-						bpno,
-						one,
-						nmsedec,
-						type,
-						vsc);
-			}
-		}
-	}
-}
-
-static void t1_dec_refpass_raw(
-		opj_t1_t *t1,
-		int bpno,
-		int cblksty)
-{
-	int i, j, k, one, poshalf, neghalf;
-	int vsc;
-	one = 1 << bpno;
-	poshalf = one >> 1;
-	neghalf = bpno > 0 ? -poshalf : -1;
-	for (k = 0; k < t1->h; k += 4) {
-		for (i = 0; i < t1->w; ++i) {
-			for (j = k; j < k + 4 && j < t1->h; ++j) {
-				vsc = ((cblksty & J2K_CCP_CBLKSTY_VSC) && (j == k + 3 || j == t1->h - 1)) ? 1 : 0;
-				t1_dec_refpass_step_raw(
-						t1,
-						&t1->flags[((j+1) * t1->flags_stride) + i + 1],
-						&t1->data[(j * t1->w) + i],
-						poshalf,
-						neghalf,
-						vsc);
-			}
-		}
-	}
-}				/* VSC and  BYPASS by Antonin */
-
-static void t1_dec_refpass_mqc(
-		opj_t1_t *t1,
-		int bpno)
-{
-	int i, j, k, one, poshalf, neghalf;
-	int *data1 = t1->data;
-	flag_t *flags1 = &t1->flags[1];
-	one = 1 << bpno;
-	poshalf = one >> 1;
-	neghalf = bpno > 0 ? -poshalf : -1;
-	for (k = 0; k < (t1->h & ~3); k += 4) {
-		for (i = 0; i < t1->w; ++i) {
-			int *data2 = data1 + i;
-			flag_t *flags2 = flags1 + i;
-			flags2 += t1->flags_stride;
-			t1_dec_refpass_step_mqc(t1, flags2, data2, poshalf, neghalf);
-			data2 += t1->w;
-			flags2 += t1->flags_stride;
-			t1_dec_refpass_step_mqc(t1, flags2, data2, poshalf, neghalf);
-			data2 += t1->w;
-			flags2 += t1->flags_stride;
-			t1_dec_refpass_step_mqc(t1, flags2, data2, poshalf, neghalf);
-			data2 += t1->w;
-			flags2 += t1->flags_stride;
-			t1_dec_refpass_step_mqc(t1, flags2, data2, poshalf, neghalf);
-			data2 += t1->w;
-		}
-		data1 += t1->w << 2;
-		flags1 += t1->flags_stride << 2;
-	}
-	for (i = 0; i < t1->w; ++i) {
-		int *data2 = data1 + i;
-		flag_t *flags2 = flags1 + i;
-		for (j = k; j < t1->h; ++j) {
-			flags2 += t1->flags_stride;
-			t1_dec_refpass_step_mqc(t1, flags2, data2, poshalf, neghalf);
-			data2 += t1->w;
-		}
-	}
-}				/* VSC and  BYPASS by Antonin */
-
-static void t1_dec_refpass_mqc_vsc(
-		opj_t1_t *t1,
-		int bpno)
-{
-	int i, j, k, one, poshalf, neghalf;
-	int vsc;
-	one = 1 << bpno;
-	poshalf = one >> 1;
-	neghalf = bpno > 0 ? -poshalf : -1;
-	for (k = 0; k < t1->h; k += 4) {
-		for (i = 0; i < t1->w; ++i) {
-			for (j = k; j < k + 4 && j < t1->h; ++j) {
-				vsc = ((j == k + 3 || j == t1->h - 1)) ? 1 : 0;
-				t1_dec_refpass_step_mqc_vsc(
-						t1,
-						&t1->flags[((j+1) * t1->flags_stride) + i + 1],
-						&t1->data[(j * t1->w) + i],
-						poshalf,
-						neghalf,
-						vsc);
-			}
-		}
-	}
-}				/* VSC and  BYPASS by Antonin */
-
-static void t1_enc_clnpass_step(
-		opj_t1_t *t1,
-		flag_t *flagsp,
-		int *datap,
-		int orient,
-		int bpno,
-		int one,
-		int *nmsedec,
-		int partial,
-		int vsc)
-{
-	int v, flag;
-	
-	opj_mqc_t *mqc = t1->mqc;	/* MQC component */
-	
-	flag = vsc ? ((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*flagsp);
-	if (partial) {
-		goto LABEL_PARTIAL;
-	}
-	if (!(*flagsp & (T1_SIG | T1_VISIT))) {
-		mqc_setcurctx(mqc, t1_getctxno_zc(flag, orient));
-		v = int_abs(*datap) & one ? 1 : 0;
-		mqc_encode(mqc, v);
-		if (v) {
-LABEL_PARTIAL:
-			*nmsedec += t1_getnmsedec_sig(int_abs(*datap), bpno + T1_NMSEDEC_FRACBITS);
-			mqc_setcurctx(mqc, t1_getctxno_sc(flag));
-			v = *datap < 0 ? 1 : 0;
-			mqc_encode(mqc, v ^ t1_getspb(flag));
-			t1_updateflags(flagsp, v, t1->flags_stride);
-		}
-	}
-	*flagsp &= ~T1_VISIT;
-}
-
-static void t1_dec_clnpass_step_partial(
-		opj_t1_t *t1,
-		flag_t *flagsp,
-		int *datap,
-		int orient,
-		int oneplushalf)
-{
-	int v, flag;
-	opj_mqc_t *mqc = t1->mqc;	/* MQC component */
-	
-	OPJ_ARG_NOT_USED(orient);
-	
-	flag = *flagsp;
-	mqc_setcurctx(mqc, t1_getctxno_sc(flag));
-	v = mqc_decode(mqc) ^ t1_getspb(flag);
-	*datap = v ? -oneplushalf : oneplushalf;
-	t1_updateflags(flagsp, v, t1->flags_stride);
-	*flagsp &= ~T1_VISIT;
-}				/* VSC and  BYPASS by Antonin */
-
-static void t1_dec_clnpass_step(
-		opj_t1_t *t1,
-		flag_t *flagsp,
-		int *datap,
-		int orient,
-		int oneplushalf)
-{
-	int v, flag;
-	
-	opj_mqc_t *mqc = t1->mqc;	/* MQC component */
-	
-	flag = *flagsp;
-	if (!(flag & (T1_SIG | T1_VISIT))) {
-		mqc_setcurctx(mqc, t1_getctxno_zc(flag, orient));
-		if (mqc_decode(mqc)) {
-			mqc_setcurctx(mqc, t1_getctxno_sc(flag));
-			v = mqc_decode(mqc) ^ t1_getspb(flag);
-			*datap = v ? -oneplushalf : oneplushalf;
-			t1_updateflags(flagsp, v, t1->flags_stride);
-		}
-	}
-	*flagsp &= ~T1_VISIT;
-}				/* VSC and  BYPASS by Antonin */
-
-static void t1_dec_clnpass_step_vsc(
-		opj_t1_t *t1,
-		flag_t *flagsp,
-		int *datap,
-		int orient,
-		int oneplushalf,
-		int partial,
-		int vsc)
-{
-	int v, flag;
-	
-	opj_mqc_t *mqc = t1->mqc;	/* MQC component */
-	
-	flag = vsc ? ((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*flagsp);
-	if (partial) {
-		goto LABEL_PARTIAL;
-	}
-	if (!(flag & (T1_SIG | T1_VISIT))) {
-		mqc_setcurctx(mqc, t1_getctxno_zc(flag, orient));
-		if (mqc_decode(mqc)) {
-LABEL_PARTIAL:
-			mqc_setcurctx(mqc, t1_getctxno_sc(flag));
-			v = mqc_decode(mqc) ^ t1_getspb(flag);
-			*datap = v ? -oneplushalf : oneplushalf;
-			t1_updateflags(flagsp, v, t1->flags_stride);
-		}
-	}
-	*flagsp &= ~T1_VISIT;
-}
-
-static void t1_enc_clnpass(
-		opj_t1_t *t1,
-		int bpno,
-		int orient,
-		int *nmsedec,
-		int cblksty)
-{
-	int i, j, k, one, agg, runlen, vsc;
-	
-	opj_mqc_t *mqc = t1->mqc;	/* MQC component */
-	
-	*nmsedec = 0;
-	one = 1 << (bpno + T1_NMSEDEC_FRACBITS);
-	for (k = 0; k < t1->h; k += 4) {
-		for (i = 0; i < t1->w; ++i) {
-			if (k + 3 < t1->h) {
-				if (cblksty & J2K_CCP_CBLKSTY_VSC) {
-					agg = !(MACRO_t1_flags(1 + k,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH)
-						|| MACRO_t1_flags(1 + k + 1,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH)
-						|| MACRO_t1_flags(1 + k + 2,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH)
-						|| (MACRO_t1_flags(1 + k + 3,1 + i) 
-						& (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW |	T1_SGN_S))) & (T1_SIG | T1_VISIT | T1_SIG_OTH));
-				} else {
-					agg = !(MACRO_t1_flags(1 + k,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH)
-						|| MACRO_t1_flags(1 + k + 1,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH)
-						|| MACRO_t1_flags(1 + k + 2,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH)
-						|| MACRO_t1_flags(1 + k + 3,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH));
-				}
-			} else {
-				agg = 0;
-			}
-			if (agg) {
-				for (runlen = 0; runlen < 4; ++runlen) {
-					if (int_abs(t1->data[((k + runlen)*t1->w) + i]) & one)
-						break;
-				}
-				mqc_setcurctx(mqc, T1_CTXNO_AGG);
-				mqc_encode(mqc, runlen != 4);
-				if (runlen == 4) {
-					continue;
-				}
-				mqc_setcurctx(mqc, T1_CTXNO_UNI);
-				mqc_encode(mqc, runlen >> 1);
-				mqc_encode(mqc, runlen & 1);
-			} else {
-				runlen = 0;
-			}
-			for (j = k + runlen; j < k + 4 && j < t1->h; ++j) {
-				vsc = ((cblksty & J2K_CCP_CBLKSTY_VSC) && (j == k + 3 || j == t1->h - 1)) ? 1 : 0;
-				t1_enc_clnpass_step(
-						t1,
-						&t1->flags[((j+1) * t1->flags_stride) + i + 1],
-						&t1->data[(j * t1->w) + i],
-						orient,
-						bpno,
-						one,
-						nmsedec,
-						agg && (j == k + runlen),
-						vsc);
-			}
-		}
-	}
-}
-
-static void t1_dec_clnpass(
-		opj_t1_t *t1,
-		int bpno,
-		int orient,
-		int cblksty)
-{
-	int i, j, k, one, half, oneplushalf, agg, runlen, vsc;
-	int segsym = cblksty & J2K_CCP_CBLKSTY_SEGSYM;
-	
-	opj_mqc_t *mqc = t1->mqc;	/* MQC component */
-	
-	one = 1 << bpno;
-	half = one >> 1;
-	oneplushalf = one | half;
-	if (cblksty & J2K_CCP_CBLKSTY_VSC) {
-	for (k = 0; k < t1->h; k += 4) {
-		for (i = 0; i < t1->w; ++i) {
-			if (k + 3 < t1->h) {
-					agg = !(MACRO_t1_flags(1 + k,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH)
-						|| MACRO_t1_flags(1 + k + 1,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH)
-						|| MACRO_t1_flags(1 + k + 2,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH)
-						|| (MACRO_t1_flags(1 + k + 3,1 + i) 
-						& (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW |	T1_SGN_S))) & (T1_SIG | T1_VISIT | T1_SIG_OTH));
-				} else {
-				agg = 0;
-			}
-			if (agg) {
-				mqc_setcurctx(mqc, T1_CTXNO_AGG);
-				if (!mqc_decode(mqc)) {
-					continue;
-				}
-				mqc_setcurctx(mqc, T1_CTXNO_UNI);
-				runlen = mqc_decode(mqc);
-				runlen = (runlen << 1) | mqc_decode(mqc);
-			} else {
-				runlen = 0;
-			}
-			for (j = k + runlen; j < k + 4 && j < t1->h; ++j) {
-					vsc = (j == k + 3 || j == t1->h - 1) ? 1 : 0;
-					t1_dec_clnpass_step_vsc(
-						t1,
-						&t1->flags[((j+1) * t1->flags_stride) + i + 1],
-						&t1->data[(j * t1->w) + i],
-						orient,
-						oneplushalf,
-						agg && (j == k + runlen),
-						vsc);
-			}
-		}
-	}
-	} else {
-		int *data1 = t1->data;
-		flag_t *flags1 = &t1->flags[1];
-		for (k = 0; k < (t1->h & ~3); k += 4) {
-			for (i = 0; i < t1->w; ++i) {
-				int *data2 = data1 + i;
-				flag_t *flags2 = flags1 + i;
-				agg = !(MACRO_t1_flags(1 + k,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH)
-					|| MACRO_t1_flags(1 + k + 1,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH)
-					|| MACRO_t1_flags(1 + k + 2,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH)
-					|| MACRO_t1_flags(1 + k + 3,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH));
-				if (agg) {
-					mqc_setcurctx(mqc, T1_CTXNO_AGG);
-					if (!mqc_decode(mqc)) {
-						continue;
-					}
-					mqc_setcurctx(mqc, T1_CTXNO_UNI);
-					runlen = mqc_decode(mqc);
-					runlen = (runlen << 1) | mqc_decode(mqc);
-					flags2 += runlen * t1->flags_stride;
-					data2 += runlen * t1->w;
-					for (j = k + runlen; j < k + 4 && j < t1->h; ++j) {
-						flags2 += t1->flags_stride;
-						if (agg && (j == k + runlen)) {
-							t1_dec_clnpass_step_partial(t1, flags2, data2, orient, oneplushalf);
-						} else {
-							t1_dec_clnpass_step(t1, flags2, data2, orient, oneplushalf);
-						}
-						data2 += t1->w;
-					}
-				} else {
-					flags2 += t1->flags_stride;
-					t1_dec_clnpass_step(t1, flags2, data2, orient, oneplushalf);
-					data2 += t1->w;
-					flags2 += t1->flags_stride;
-					t1_dec_clnpass_step(t1, flags2, data2, orient, oneplushalf);
-					data2 += t1->w;
-					flags2 += t1->flags_stride;
-					t1_dec_clnpass_step(t1, flags2, data2, orient, oneplushalf);
-					data2 += t1->w;
-					flags2 += t1->flags_stride;
-					t1_dec_clnpass_step(t1, flags2, data2, orient, oneplushalf);
-					data2 += t1->w;
-				}
-			}
-			data1 += t1->w << 2;
-			flags1 += t1->flags_stride << 2;
-		}
-		for (i = 0; i < t1->w; ++i) {
-			int *data2 = data1 + i;
-			flag_t *flags2 = flags1 + i;
-			for (j = k; j < t1->h; ++j) {
-				flags2 += t1->flags_stride;
-				t1_dec_clnpass_step(t1, flags2, data2, orient, oneplushalf);
-				data2 += t1->w;
-			}
-		}
-	}
-
-	if (segsym) {
-		int v = 0;
-		mqc_setcurctx(mqc, T1_CTXNO_UNI);
-		v = mqc_decode(mqc);
-		v = (v << 1) | mqc_decode(mqc);
-		v = (v << 1) | mqc_decode(mqc);
-		v = (v << 1) | mqc_decode(mqc);
-		/*
-		if (v!=0xa) {
-			opj_event_msg(t1->cinfo, EVT_WARNING, "Bad segmentation symbol %x\n", v);
-		} 
-		*/
-	}
-}				/* VSC and  BYPASS by Antonin */
-
-
-/** mod fixed_quality */
-static double t1_getwmsedec(
-		int nmsedec,
-		int compno,
-		int level,
-		int orient,
-		int bpno,
-		int qmfbid,
-		double stepsize,
-		int numcomps,
-		int mct)
-{
-	double w1, w2, wmsedec;
-	if (qmfbid == 1) {
-		w1 = (mct && numcomps==3) ? mct_getnorm(compno) : 1.0;
-		w2 = dwt_getnorm(level, orient);
-	} else {			/* if (qmfbid == 0) */
-		w1 = (mct && numcomps==3) ? mct_getnorm_real(compno) : 1.0;
-		w2 = dwt_getnorm_real(level, orient);
-	}
-	wmsedec = w1 * w2 * stepsize * (1 << bpno);
-	wmsedec *= wmsedec * nmsedec / 8192.0;
-	
-	return wmsedec;
-}
-
-static opj_bool allocate_buffers(
-		opj_t1_t *t1,
-		int w,
-		int h)
-{
-	int datasize=w * h;
-	int flagssize;
-
-	if(datasize > t1->datasize){
-		opj_aligned_free(t1->data);
-		t1->data = (int*) opj_aligned_malloc(datasize * sizeof(int));
-		if(!t1->data){
-			return OPJ_FALSE;
-		}
-		t1->datasize=datasize;
-	}
-	memset(t1->data,0,datasize * sizeof(int));
-
-	t1->flags_stride=w+2;
-	flagssize=t1->flags_stride * (h+2);
-
-	if(flagssize > t1->flagssize){
-		opj_aligned_free(t1->flags);
-		t1->flags = (flag_t*) opj_aligned_malloc(flagssize * sizeof(flag_t));
-		if(!t1->flags){
-			return OPJ_FALSE;
-		}
-		t1->flagssize=flagssize;
-	}
-	memset(t1->flags,0,flagssize * sizeof(flag_t));
-
-	t1->w=w;
-	t1->h=h;
-
-	return OPJ_TRUE;
-}
-
-/** mod fixed_quality */
-static void t1_encode_cblk(
-		opj_t1_t *t1,
-		opj_tcd_cblk_enc_t* cblk,
-		int orient,
-		int compno,
-		int level,
-		int qmfbid,
-		double stepsize,
-		int cblksty,
-		int numcomps,
-		int mct,
-		opj_tcd_tile_t * tile)
-{
-	double cumwmsedec = 0.0;
-
-	opj_mqc_t *mqc = t1->mqc;	/* MQC component */
-
-	int passno, bpno, passtype;
-	int nmsedec = 0;
-	int i, max;
-	char type = T1_TYPE_MQ;
-	double tempwmsedec;
-
-	max = 0;
-	for (i = 0; i < t1->w * t1->h; ++i) {
-		int tmp = abs(t1->data[i]);
-		max = int_max(max, tmp);
-	}
-
-	cblk->numbps = max ? (int_floorlog2(max) + 1) - T1_NMSEDEC_FRACBITS : 0;
-	
-	bpno = cblk->numbps - 1;
-	passtype = 2;
-	
-	mqc_resetstates(mqc);
-	mqc_setstate(mqc, T1_CTXNO_UNI, 0, 46);
-	mqc_setstate(mqc, T1_CTXNO_AGG, 0, 3);
-	mqc_setstate(mqc, T1_CTXNO_ZC, 0, 4);
-	mqc_init_enc(mqc, cblk->data);
-	
-	for (passno = 0; bpno >= 0; ++passno) {
-		opj_tcd_pass_t *pass = &cblk->passes[passno];
-		int correction = 3;
-		type = ((bpno < (cblk->numbps - 4)) && (passtype < 2) && (cblksty & J2K_CCP_CBLKSTY_LAZY)) ? T1_TYPE_RAW : T1_TYPE_MQ;
-		
-		switch (passtype) {
-			case 0:
-				t1_enc_sigpass(t1, bpno, orient, &nmsedec, type, cblksty);
-				break;
-			case 1:
-				t1_enc_refpass(t1, bpno, &nmsedec, type, cblksty);
-				break;
-			case 2:
-				t1_enc_clnpass(t1, bpno, orient, &nmsedec, cblksty);
-				/* code switch SEGMARK (i.e. SEGSYM) */
-				if (cblksty & J2K_CCP_CBLKSTY_SEGSYM)
-					mqc_segmark_enc(mqc);
-				break;
-		}
-		
-		/* fixed_quality */
-		tempwmsedec = t1_getwmsedec(nmsedec, compno, level, orient, bpno, qmfbid, stepsize, numcomps, mct);
-		cumwmsedec += tempwmsedec;
-		tile->distotile += tempwmsedec;
-		
-		/* Code switch "RESTART" (i.e. TERMALL) */
-		if ((cblksty & J2K_CCP_CBLKSTY_TERMALL)	&& !((passtype == 2) && (bpno - 1 < 0))) {
-			if (type == T1_TYPE_RAW) {
-				mqc_flush(mqc);
-				correction = 1;
-				/* correction = mqc_bypass_flush_enc(); */
-			} else {			/* correction = mqc_restart_enc(); */
-				mqc_flush(mqc);
-				correction = 1;
-			}
-			pass->term = 1;
-		} else {
-			if (((bpno < (cblk->numbps - 4) && (passtype > 0)) 
-				|| ((bpno == (cblk->numbps - 4)) && (passtype == 2))) && (cblksty & J2K_CCP_CBLKSTY_LAZY)) {
-				if (type == T1_TYPE_RAW) {
-					mqc_flush(mqc);
-					correction = 1;
-					/* correction = mqc_bypass_flush_enc(); */
-				} else {		/* correction = mqc_restart_enc(); */
-					mqc_flush(mqc);
-					correction = 1;
-				}
-				pass->term = 1;
-			} else {
-				pass->term = 0;
-			}
-		}
-		
-		if (++passtype == 3) {
-			passtype = 0;
-			bpno--;
-		}
-		
-		if (pass->term && bpno > 0) {
-			type = ((bpno < (cblk->numbps - 4)) && (passtype < 2) && (cblksty & J2K_CCP_CBLKSTY_LAZY)) ? T1_TYPE_RAW : T1_TYPE_MQ;
-			if (type == T1_TYPE_RAW)
-				mqc_bypass_init_enc(mqc);
-			else
-				mqc_restart_init_enc(mqc);
-		}
-		
-		pass->distortiondec = cumwmsedec;
-		pass->rate = mqc_numbytes(mqc) + correction;	/* FIXME */
-		
-		/* Code-switch "RESET" */
-		if (cblksty & J2K_CCP_CBLKSTY_RESET)
-			mqc_reset_enc(mqc);
-	}
-	
-	/* Code switch "ERTERM" (i.e. PTERM) */
-	if (cblksty & J2K_CCP_CBLKSTY_PTERM)
-		mqc_erterm_enc(mqc);
-	else /* Default coding */ if (!(cblksty & J2K_CCP_CBLKSTY_LAZY))
-		mqc_flush(mqc);
-	
-	cblk->totalpasses = passno;
-
-	for (passno = 0; passno<cblk->totalpasses; passno++) {
-		opj_tcd_pass_t *pass = &cblk->passes[passno];
-		if (pass->rate > mqc_numbytes(mqc))
-			pass->rate = mqc_numbytes(mqc);
-		/*Preventing generation of FF as last data byte of a pass*/
-		if((pass->rate>1) && (cblk->data[pass->rate - 1] == 0xFF)){
-			pass->rate--;
-		}
-		pass->len = pass->rate - (passno == 0 ? 0 : cblk->passes[passno - 1].rate);		
-	}
-}
-
-static void t1_decode_cblk(
-		opj_t1_t *t1,
-		opj_tcd_cblk_dec_t* cblk,
-		int orient,
-		int roishift,
-		int cblksty)
-{
-	opj_raw_t *raw = t1->raw;	/* RAW component */
-	opj_mqc_t *mqc = t1->mqc;	/* MQC component */
-
-	int bpno, passtype;
-	int segno, passno;
-	char type = T1_TYPE_MQ; /* BYPASS mode */
-
-	if(!allocate_buffers(
-				t1,
-				cblk->x1 - cblk->x0,
-				cblk->y1 - cblk->y0))
-	{
-		return;
-	}
-
-	bpno = roishift + cblk->numbps - 1;
-	passtype = 2;
-	
-	mqc_resetstates(mqc);
-	mqc_setstate(mqc, T1_CTXNO_UNI, 0, 46);
-	mqc_setstate(mqc, T1_CTXNO_AGG, 0, 3);
-	mqc_setstate(mqc, T1_CTXNO_ZC, 0, 4);
-	
-	for (segno = 0; segno < cblk->numsegs; ++segno) {
-		opj_tcd_seg_t *seg = &cblk->segs[segno];
-		
-		/* BYPASS mode */
-		type = ((bpno <= (cblk->numbps - 1) - 4) && (passtype < 2) && (cblksty & J2K_CCP_CBLKSTY_LAZY)) ? T1_TYPE_RAW : T1_TYPE_MQ;
-		/* FIXME: slviewer gets here with a null pointer. Why? Partially downloaded and/or corrupt textures? */
-		if(seg->data == NULL){
-			continue;
-		}
-		if (type == T1_TYPE_RAW) {
-			raw_init_dec(raw, (*seg->data) + seg->dataindex, seg->len);
-		} else {
-			mqc_init_dec(mqc, (*seg->data) + seg->dataindex, seg->len);
-		}
-		
-		for (passno = 0; passno < seg->numpasses; ++passno) {
-			switch (passtype) {
-				case 0:
-					if (type == T1_TYPE_RAW) {
-						t1_dec_sigpass_raw(t1, bpno+1, orient, cblksty);
-					} else {
-						if (cblksty & J2K_CCP_CBLKSTY_VSC) {
-							t1_dec_sigpass_mqc_vsc(t1, bpno+1, orient);
-						} else {
-							t1_dec_sigpass_mqc(t1, bpno+1, orient);
-						}
-					}
-					break;
-				case 1:
-					if (type == T1_TYPE_RAW) {
-						t1_dec_refpass_raw(t1, bpno+1, cblksty);
-					} else {
-						if (cblksty & J2K_CCP_CBLKSTY_VSC) {
-							t1_dec_refpass_mqc_vsc(t1, bpno+1);
-						} else {
-							t1_dec_refpass_mqc(t1, bpno+1);
-						}
-					}
-					break;
-				case 2:
-					t1_dec_clnpass(t1, bpno+1, orient, cblksty);
-					break;
-			}
-			
-			if ((cblksty & J2K_CCP_CBLKSTY_RESET) && type == T1_TYPE_MQ) {
-				mqc_resetstates(mqc);
-				mqc_setstate(mqc, T1_CTXNO_UNI, 0, 46);				
-				mqc_setstate(mqc, T1_CTXNO_AGG, 0, 3);
-				mqc_setstate(mqc, T1_CTXNO_ZC, 0, 4);
-			}
-			if (++passtype == 3) {
-				passtype = 0;
-				bpno--;
-			}
-		}
-	}
-}
-
-/* ----------------------------------------------------------------------- */
-
-opj_t1_t* t1_create(opj_common_ptr cinfo) {
-	opj_t1_t *t1 = (opj_t1_t*) opj_malloc(sizeof(opj_t1_t));
-	if(!t1)
-		return NULL;
-
-	t1->cinfo = cinfo;
-	/* create MQC and RAW handles */
-	t1->mqc = mqc_create();
-	t1->raw = raw_create();
-
-	t1->data=NULL;
-	t1->flags=NULL;
-	t1->datasize=0;
-	t1->flagssize=0;
-
-	return t1;
-}
-
-void t1_destroy(opj_t1_t *t1) {
-	if(t1) {
-		/* destroy MQC and RAW handles */
-		mqc_destroy(t1->mqc);
-		raw_destroy(t1->raw);
-		opj_aligned_free(t1->data);
-		opj_aligned_free(t1->flags);
-		opj_free(t1);
-	}
-}
-
-void t1_encode_cblks(
-		opj_t1_t *t1,
-		opj_tcd_tile_t *tile,
-		opj_tcp_t *tcp)
-{
-	int compno, resno, bandno, precno, cblkno;
-
-	tile->distotile = 0;		/* fixed_quality */
-
-	for (compno = 0; compno < tile->numcomps; ++compno) {
-		opj_tcd_tilecomp_t* tilec = &tile->comps[compno];
-		opj_tccp_t* tccp = &tcp->tccps[compno];
-		int tile_w = tilec->x1 - tilec->x0;
-
-		for (resno = 0; resno < tilec->numresolutions; ++resno) {
-			opj_tcd_resolution_t *res = &tilec->resolutions[resno];
-
-			for (bandno = 0; bandno < res->numbands; ++bandno) {
-				opj_tcd_band_t* restrict band = &res->bands[bandno];
-        int bandconst = 8192 * 8192 / ((int) floor(band->stepsize * 8192));
-
-				for (precno = 0; precno < res->pw * res->ph; ++precno) {
-					opj_tcd_precinct_t *prc = &band->precincts[precno];
-
-					for (cblkno = 0; cblkno < prc->cw * prc->ch; ++cblkno) {
-						opj_tcd_cblk_enc_t* cblk = &prc->cblks.enc[cblkno];
-						int* restrict datap;
-						int* restrict tiledp;
-						int cblk_w;
-						int cblk_h;
-						int i, j;
-
-						int x = cblk->x0 - band->x0;
-						int y = cblk->y0 - band->y0;
-						if (band->bandno & 1) {
-							opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1];
-							x += pres->x1 - pres->x0;
-						}
-						if (band->bandno & 2) {
-							opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1];
-							y += pres->y1 - pres->y0;
-						}
-
-						if(!allocate_buffers(
-									t1,
-									cblk->x1 - cblk->x0,
-									cblk->y1 - cblk->y0))
-						{
-							return;
-						}
-
-						datap=t1->data;
-						cblk_w = t1->w;
-						cblk_h = t1->h;
-
-						tiledp=&tilec->data[(y * tile_w) + x];
-						if (tccp->qmfbid == 1) {
-							for (j = 0; j < cblk_h; ++j) {
-								for (i = 0; i < cblk_w; ++i) {
-									int tmp = tiledp[(j * tile_w) + i];
-									datap[(j * cblk_w) + i] = tmp << T1_NMSEDEC_FRACBITS;
-								}
-							}
-						} else {		/* if (tccp->qmfbid == 0) */
-							for (j = 0; j < cblk_h; ++j) {
-								for (i = 0; i < cblk_w; ++i) {
-									int tmp = tiledp[(j * tile_w) + i];
-									datap[(j * cblk_w) + i] =
-										fix_mul(
-										tmp,
-										bandconst) >> (11 - T1_NMSEDEC_FRACBITS);
-								}
-							}
-						}
-
-						t1_encode_cblk(
-								t1,
-								cblk,
-								band->bandno,
-								compno,
-								tilec->numresolutions - 1 - resno,
-								tccp->qmfbid,
-								band->stepsize,
-								tccp->cblksty,
-								tile->numcomps,
-								tcp->mct,
-								tile);
-
-					} /* cblkno */
-				} /* precno */
-			} /* bandno */
-		} /* resno  */
-	} /* compno  */
-}
-
-void t1_decode_cblks(
-		opj_t1_t* t1,
-		opj_tcd_tilecomp_t* tilec,
-		opj_tccp_t* tccp)
-{
-	int resno, bandno, precno, cblkno;
-
-	int tile_w = tilec->x1 - tilec->x0;
-
-	for (resno = 0; resno < tilec->numresolutions; ++resno) {
-		opj_tcd_resolution_t* res = &tilec->resolutions[resno];
-
-		for (bandno = 0; bandno < res->numbands; ++bandno) {
-			opj_tcd_band_t* restrict band = &res->bands[bandno];
-
-			for (precno = 0; precno < res->pw * res->ph; ++precno) {
-				opj_tcd_precinct_t* precinct = &band->precincts[precno];
-
-				for (cblkno = 0; cblkno < precinct->cw * precinct->ch; ++cblkno) {
-					opj_tcd_cblk_dec_t* cblk = &precinct->cblks.dec[cblkno];
-					int* restrict datap;
-					int cblk_w, cblk_h;
-					int x, y;
-					int i, j;
-
-					t1_decode_cblk(
-							t1,
-							cblk,
-							band->bandno,
-							tccp->roishift,
-							tccp->cblksty);
-
-					x = cblk->x0 - band->x0;
-					y = cblk->y0 - band->y0;
-					if (band->bandno & 1) {
-						opj_tcd_resolution_t* pres = &tilec->resolutions[resno - 1];
-						x += pres->x1 - pres->x0;
-					}
-					if (band->bandno & 2) {
-						opj_tcd_resolution_t* pres = &tilec->resolutions[resno - 1];
-						y += pres->y1 - pres->y0;
-					}
-
-					datap=t1->data;
-					cblk_w = t1->w;
-					cblk_h = t1->h;
-
-					if (tccp->roishift) {
-						int thresh = 1 << tccp->roishift;
-						for (j = 0; j < cblk_h; ++j) {
-							for (i = 0; i < cblk_w; ++i) {
-								int val = datap[(j * cblk_w) + i];
-								int mag = abs(val);
-								if (mag >= thresh) {
-									mag >>= tccp->roishift;
-									datap[(j * cblk_w) + i] = val < 0 ? -mag : mag;
-								}
-							}
-						}
-					}
-
-					if (tccp->qmfbid == 1) {
-						int* restrict tiledp = &tilec->data[(y * tile_w) + x];
-						for (j = 0; j < cblk_h; ++j) {
-							for (i = 0; i < cblk_w; ++i) {
-								int tmp = datap[(j * cblk_w) + i];
-								((int*)tiledp)[(j * tile_w) + i] = tmp / 2;
-							}
-						}
-					} else {		/* if (tccp->qmfbid == 0) */
-						float* restrict tiledp = (float*) &tilec->data[(y * tile_w) + x];
-						for (j = 0; j < cblk_h; ++j) {
-							float* restrict tiledp2 = tiledp;
-							for (i = 0; i < cblk_w; ++i) {
-								float tmp = *datap * band->stepsize;
-								*tiledp2 = tmp;
-								datap++;
-								tiledp2++;
-							}
-							tiledp += tile_w;
-						}
-					}
-					opj_free(cblk->data);
-					opj_free(cblk->segs);
-				} /* cblkno */
-				opj_free(precinct->cblks.dec);
-                precinct->cblks.dec = NULL;
-			} /* precno */
-		} /* bandno */
-	} /* resno */
-}
-
+/*
+ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2007, Professor Benoit Macq
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2007, Callum Lerwick <seg at haxxed.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "opj_includes.h"
+#include "t1_luts.h"
+
+/** @defgroup T1 T1 - Implementation of the tier-1 coding */
+/*@{*/
+
+/** @name Local static functions */
+/*@{*/
+
+static INLINE OPJ_BYTE opj_t1_getctxno_zc(OPJ_UINT32 f, OPJ_UINT32 orient);
+static OPJ_BYTE opj_t1_getctxno_sc(OPJ_UINT32 f);
+static INLINE OPJ_UINT32 opj_t1_getctxno_mag(OPJ_UINT32 f);
+static OPJ_BYTE opj_t1_getspb(OPJ_UINT32 f);
+static OPJ_INT16 opj_t1_getnmsedec_sig(OPJ_UINT32 x, OPJ_UINT32 bitpos);
+static OPJ_INT16 opj_t1_getnmsedec_ref(OPJ_UINT32 x, OPJ_UINT32 bitpos);
+static void opj_t1_updateflags(opj_flag_t *flagsp, OPJ_UINT32 s, OPJ_UINT32 stride);
+/**
+Encode significant pass
+*/
+static void opj_t1_enc_sigpass_step(opj_t1_t *t1,
+                                    opj_flag_t *flagsp,
+                                    OPJ_INT32 *datap,
+                                    OPJ_UINT32 orient,
+                                    OPJ_INT32 bpno,
+                                    OPJ_INT32 one,
+                                    OPJ_INT32 *nmsedec,
+                                    OPJ_BYTE type,
+                                    OPJ_UINT32 vsc);
+
+/**
+Decode significant pass
+*/
+#if 0
+static void opj_t1_dec_sigpass_step(opj_t1_t *t1,
+                                    opj_flag_t *flagsp,
+                                    OPJ_INT32 *datap,
+                                    OPJ_UINT32 orient,
+                                    OPJ_INT32 oneplushalf,
+                                    OPJ_BYTE type,
+                                    OPJ_UINT32 vsc);
+#endif
+
+static INLINE void opj_t1_dec_sigpass_step_raw(
+                opj_t1_t *t1,
+                opj_flag_t *flagsp,
+                OPJ_INT32 *datap,
+                OPJ_INT32 orient,
+                OPJ_INT32 oneplushalf,
+                OPJ_INT32 vsc);
+static INLINE void opj_t1_dec_sigpass_step_mqc(
+                opj_t1_t *t1,
+                opj_flag_t *flagsp,
+                OPJ_INT32 *datap,
+                OPJ_INT32 orient,
+                OPJ_INT32 oneplushalf);
+static INLINE void opj_t1_dec_sigpass_step_mqc_vsc(
+                opj_t1_t *t1,
+                opj_flag_t *flagsp,
+                OPJ_INT32 *datap,
+                OPJ_INT32 orient,
+                OPJ_INT32 oneplushalf,
+                OPJ_INT32 vsc);
+
+
+/**
+Encode significant pass
+*/
+static void opj_t1_enc_sigpass( opj_t1_t *t1,
+                                OPJ_INT32 bpno,
+                                OPJ_UINT32 orient,
+                                OPJ_INT32 *nmsedec,
+                                OPJ_BYTE type,
+                                OPJ_UINT32 cblksty);
+
+/**
+Decode significant pass
+*/
+static void opj_t1_dec_sigpass_raw(
+                opj_t1_t *t1,
+                OPJ_INT32 bpno,
+                OPJ_INT32 orient,
+                OPJ_INT32 cblksty);
+static void opj_t1_dec_sigpass_mqc(
+                opj_t1_t *t1,
+                OPJ_INT32 bpno,
+                OPJ_INT32 orient);
+static void opj_t1_dec_sigpass_mqc_vsc(
+                opj_t1_t *t1,
+                OPJ_INT32 bpno,
+                OPJ_INT32 orient);
+
+
+
+/**
+Encode refinement pass
+*/
+static void opj_t1_enc_refpass_step(opj_t1_t *t1,
+                                    opj_flag_t *flagsp,
+                                    OPJ_INT32 *datap,
+                                    OPJ_INT32 bpno,
+                                    OPJ_INT32 one,
+                                    OPJ_INT32 *nmsedec,
+                                    OPJ_BYTE type,
+                                    OPJ_UINT32 vsc);
+
+
+/**
+Encode refinement pass
+*/
+static void opj_t1_enc_refpass( opj_t1_t *t1,
+                                OPJ_INT32 bpno,
+                                OPJ_INT32 *nmsedec,
+                                OPJ_BYTE type,
+                                OPJ_UINT32 cblksty);
+
+/**
+Decode refinement pass
+*/
+static void opj_t1_dec_refpass_raw(
+                opj_t1_t *t1,
+                OPJ_INT32 bpno,
+                OPJ_INT32 cblksty);
+static void opj_t1_dec_refpass_mqc(
+                opj_t1_t *t1,
+                OPJ_INT32 bpno);
+static void opj_t1_dec_refpass_mqc_vsc(
+                opj_t1_t *t1,
+                OPJ_INT32 bpno);
+
+
+/**
+Decode refinement pass
+*/
+#if 0
+static void opj_t1_dec_refpass_step(opj_t1_t *t1,
+                                    opj_flag_t *flagsp,
+                                    OPJ_INT32 *datap,
+                                    OPJ_INT32 poshalf,
+                                    OPJ_INT32 neghalf,
+                                    OPJ_BYTE type,
+                                    OPJ_UINT32 vsc);
+#endif
+
+static INLINE void  opj_t1_dec_refpass_step_raw(
+                opj_t1_t *t1,
+                opj_flag_t *flagsp,
+                OPJ_INT32 *datap,
+                OPJ_INT32 poshalf,
+                OPJ_INT32 neghalf,
+                OPJ_INT32 vsc);
+static INLINE void opj_t1_dec_refpass_step_mqc(
+                opj_t1_t *t1,
+                opj_flag_t *flagsp,
+                OPJ_INT32 *datap,
+                OPJ_INT32 poshalf,
+                OPJ_INT32 neghalf);
+static INLINE void opj_t1_dec_refpass_step_mqc_vsc(
+                opj_t1_t *t1,
+                opj_flag_t *flagsp,
+                OPJ_INT32 *datap,
+                OPJ_INT32 poshalf,
+                OPJ_INT32 neghalf,
+                OPJ_INT32 vsc);
+
+
+
+/**
+Encode clean-up pass
+*/
+static void opj_t1_enc_clnpass_step(
+		opj_t1_t *t1,
+		opj_flag_t *flagsp,
+		OPJ_INT32 *datap,
+		OPJ_UINT32 orient,
+		OPJ_INT32 bpno,
+		OPJ_INT32 one,
+		OPJ_INT32 *nmsedec,
+		OPJ_UINT32 partial,
+		OPJ_UINT32 vsc);
+/**
+Decode clean-up pass
+*/
+static void opj_t1_dec_clnpass_step_partial(
+		opj_t1_t *t1,
+		opj_flag_t *flagsp,
+		OPJ_INT32 *datap,
+		OPJ_INT32 orient,
+		OPJ_INT32 oneplushalf);
+static void opj_t1_dec_clnpass_step(
+		opj_t1_t *t1,
+		opj_flag_t *flagsp,
+		OPJ_INT32 *datap,
+		OPJ_INT32 orient,
+		OPJ_INT32 oneplushalf);
+static void opj_t1_dec_clnpass_step_vsc(
+		opj_t1_t *t1,
+		opj_flag_t *flagsp,
+		OPJ_INT32 *datap,
+		OPJ_INT32 orient,
+		OPJ_INT32 oneplushalf,
+		OPJ_INT32 partial,
+		OPJ_INT32 vsc);
+/**
+Encode clean-up pass
+*/
+static void opj_t1_enc_clnpass(
+		opj_t1_t *t1,
+		OPJ_INT32 bpno,
+		OPJ_UINT32 orient,
+		OPJ_INT32 *nmsedec,
+		OPJ_UINT32 cblksty);
+/**
+Decode clean-up pass
+*/
+static void opj_t1_dec_clnpass(
+		opj_t1_t *t1,
+		OPJ_INT32 bpno,
+		OPJ_INT32 orient,
+		OPJ_INT32 cblksty);
+
+static OPJ_FLOAT64 opj_t1_getwmsedec(
+		OPJ_INT32 nmsedec,
+		OPJ_UINT32 compno,
+		OPJ_UINT32 level,
+		OPJ_UINT32 orient,
+		OPJ_INT32 bpno,
+		OPJ_UINT32 qmfbid,
+		OPJ_FLOAT64 stepsize,
+		OPJ_UINT32 numcomps,
+		const OPJ_FLOAT64 * mct_norms);
+
+static void opj_t1_encode_cblk( opj_t1_t *t1,
+                                opj_tcd_cblk_enc_t* cblk,
+                                OPJ_UINT32 orient,
+                                OPJ_UINT32 compno,
+                                OPJ_UINT32 level,
+                                OPJ_UINT32 qmfbid,
+                                OPJ_FLOAT64 stepsize,
+                                OPJ_UINT32 cblksty,
+                                OPJ_UINT32 numcomps,
+                                opj_tcd_tile_t * tile,
+                                const OPJ_FLOAT64 * mct_norms);
+
+/**
+Decode 1 code-block
+ at param t1 T1 handle
+ at param cblk Code-block coding parameters
+ at param orient
+ at param roishift Region of interest shifting value
+ at param cblksty Code-block style
+*/
+static OPJ_BOOL opj_t1_decode_cblk( opj_t1_t *t1,
+                                    opj_tcd_cblk_dec_t* cblk,
+                                    OPJ_UINT32 orient,
+                                    OPJ_UINT32 roishift,
+                                    OPJ_UINT32 cblksty);
+
+OPJ_BOOL opj_t1_allocate_buffers(   opj_t1_t *t1,
+                                    OPJ_UINT32 w,
+                                    OPJ_UINT32 h);
+
+/*@}*/
+
+/*@}*/
+
+/* ----------------------------------------------------------------------- */
+
+OPJ_BYTE opj_t1_getctxno_zc(OPJ_UINT32 f, OPJ_UINT32 orient) {
+	return lut_ctxno_zc[(orient << 8) | (f & T1_SIG_OTH)];
+}
+
+OPJ_BYTE opj_t1_getctxno_sc(OPJ_UINT32 f) {
+	return lut_ctxno_sc[(f & (T1_SIG_PRIM | T1_SGN)) >> 4];
+}
+
+OPJ_UINT32 opj_t1_getctxno_mag(OPJ_UINT32 f) {
+	OPJ_UINT32 tmp1 = (f & T1_SIG_OTH) ? T1_CTXNO_MAG + 1 : T1_CTXNO_MAG;
+	OPJ_UINT32 tmp2 = (f & T1_REFINE) ? T1_CTXNO_MAG + 2 : tmp1;
+	return (tmp2);
+}
+
+OPJ_BYTE opj_t1_getspb(OPJ_UINT32 f) {
+	return lut_spb[(f & (T1_SIG_PRIM | T1_SGN)) >> 4];
+}
+
+OPJ_INT16 opj_t1_getnmsedec_sig(OPJ_UINT32 x, OPJ_UINT32 bitpos) {
+	if (bitpos > T1_NMSEDEC_FRACBITS) {
+		return lut_nmsedec_sig[(x >> (bitpos - T1_NMSEDEC_FRACBITS)) & ((1 << T1_NMSEDEC_BITS) - 1)];
+	}
+	
+	return lut_nmsedec_sig0[x & ((1 << T1_NMSEDEC_BITS) - 1)];
+}
+
+OPJ_INT16 opj_t1_getnmsedec_ref(OPJ_UINT32 x, OPJ_UINT32 bitpos) {
+	if (bitpos > T1_NMSEDEC_FRACBITS) {
+		return lut_nmsedec_ref[(x >> (bitpos - T1_NMSEDEC_FRACBITS)) & ((1 << T1_NMSEDEC_BITS) - 1)];
+	}
+
+    return lut_nmsedec_ref0[x & ((1 << T1_NMSEDEC_BITS) - 1)];
+}
+
+void opj_t1_updateflags(opj_flag_t *flagsp, OPJ_UINT32 s, OPJ_UINT32 stride) {
+	opj_flag_t *np = flagsp - stride;
+	opj_flag_t *sp = flagsp + stride;
+
+	static const opj_flag_t mod[] = {
+		T1_SIG_S, T1_SIG_S|T1_SGN_S,
+		T1_SIG_E, T1_SIG_E|T1_SGN_E,
+		T1_SIG_W, T1_SIG_W|T1_SGN_W,
+		T1_SIG_N, T1_SIG_N|T1_SGN_N
+	};
+
+	np[-1] |= T1_SIG_SE;
+	np[0]  |= mod[s];
+	np[1]  |= T1_SIG_SW;
+
+	flagsp[-1] |= mod[s+2];
+	flagsp[0]  |= T1_SIG;
+	flagsp[1]  |= mod[s+4];
+
+	sp[-1] |= T1_SIG_NE;
+	sp[0]  |= mod[s+6];
+	sp[1]  |= T1_SIG_NW;
+}
+
+void opj_t1_enc_sigpass_step(   opj_t1_t *t1,
+                                opj_flag_t *flagsp,
+                                OPJ_INT32 *datap,
+                                OPJ_UINT32 orient,
+                                OPJ_INT32 bpno,
+                                OPJ_INT32 one,
+                                OPJ_INT32 *nmsedec,
+                                OPJ_BYTE type,
+                                OPJ_UINT32 vsc
+                                )
+{
+	OPJ_INT32 v;
+    OPJ_UINT32 flag;
+	
+	opj_mqc_t *mqc = t1->mqc;	/* MQC component */
+	
+	flag = vsc ? (OPJ_UINT32)((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (OPJ_UINT32)(*flagsp);
+	if ((flag & T1_SIG_OTH) && !(flag & (T1_SIG | T1_VISIT))) {
+		v = opj_int_abs(*datap) & one ? 1 : 0;
+		opj_mqc_setcurctx(mqc, opj_t1_getctxno_zc(flag, orient));	/* ESSAI */
+		if (type == T1_TYPE_RAW) {	/* BYPASS/LAZY MODE */
+			opj_mqc_bypass_enc(mqc, (OPJ_UINT32)v);
+		} else {
+			opj_mqc_encode(mqc, (OPJ_UINT32)v);
+		}
+		if (v) {
+			v = *datap < 0 ? 1 : 0;
+			*nmsedec +=	opj_t1_getnmsedec_sig((OPJ_UINT32)opj_int_abs(*datap), (OPJ_UINT32)(bpno + T1_NMSEDEC_FRACBITS));
+			opj_mqc_setcurctx(mqc, opj_t1_getctxno_sc(flag));	/* ESSAI */
+			if (type == T1_TYPE_RAW) {	/* BYPASS/LAZY MODE */
+				opj_mqc_bypass_enc(mqc, (OPJ_UINT32)v);
+			} else {
+				opj_mqc_encode(mqc, (OPJ_UINT32)(v ^ opj_t1_getspb((OPJ_UINT32)flag)));
+			}
+			opj_t1_updateflags(flagsp, (OPJ_UINT32)v, t1->flags_stride);
+		}
+		*flagsp |= T1_VISIT;
+	}
+}
+
+
+static INLINE void opj_t1_dec_sigpass_step_raw(
+                opj_t1_t *t1,
+                opj_flag_t *flagsp,
+                OPJ_INT32 *datap,
+                OPJ_INT32 orient,
+                OPJ_INT32 oneplushalf,
+                OPJ_INT32 vsc)
+{
+        OPJ_INT32 v, flag;
+        opj_raw_t *raw = t1->raw;       /* RAW component */
+        OPJ_ARG_NOT_USED(orient);
+       
+        flag = vsc ? ((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*flagsp);
+        if ((flag & T1_SIG_OTH) && !(flag & (T1_SIG | T1_VISIT))) {
+                        if (opj_raw_decode(raw)) {
+                                v = (OPJ_INT32)opj_raw_decode(raw);    /* ESSAI */
+                                *datap = v ? -oneplushalf : oneplushalf;
+                                opj_t1_updateflags(flagsp, (OPJ_UINT32)v, t1->flags_stride);
+                        }
+                *flagsp |= T1_VISIT;
+        }
+}      
+
+INLINE void opj_t1_dec_sigpass_step_mqc(
+                opj_t1_t *t1,
+                opj_flag_t *flagsp,
+                OPJ_INT32 *datap,
+                OPJ_INT32 orient,
+                OPJ_INT32 oneplushalf)
+{
+        OPJ_INT32 v, flag;
+       
+        opj_mqc_t *mqc = t1->mqc;       /* MQC component */
+       
+        flag = *flagsp;
+        if ((flag & T1_SIG_OTH) && !(flag & (T1_SIG | T1_VISIT))) {
+                        opj_mqc_setcurctx(mqc, opj_t1_getctxno_zc((OPJ_UINT32)flag, (OPJ_UINT32)orient));
+                        if (opj_mqc_decode(mqc)) {
+                                opj_mqc_setcurctx(mqc, opj_t1_getctxno_sc((OPJ_UINT32)flag));
+                                v = opj_mqc_decode(mqc) ^ opj_t1_getspb((OPJ_UINT32)flag);
+                                *datap = v ? -oneplushalf : oneplushalf;
+                                opj_t1_updateflags(flagsp, (OPJ_UINT32)v, t1->flags_stride);
+                        }
+                *flagsp |= T1_VISIT;
+        }
+}                               /* VSC and  BYPASS by Antonin */
+
+INLINE void opj_t1_dec_sigpass_step_mqc_vsc(
+                opj_t1_t *t1,
+                opj_flag_t *flagsp,
+                OPJ_INT32 *datap,
+                OPJ_INT32 orient,
+                OPJ_INT32 oneplushalf,
+                OPJ_INT32 vsc)
+{
+        OPJ_INT32 v, flag;
+       
+        opj_mqc_t *mqc = t1->mqc;       /* MQC component */
+       
+        flag = vsc ? ((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*flagsp);
+        if ((flag & T1_SIG_OTH) && !(flag & (T1_SIG | T1_VISIT))) {
+                opj_mqc_setcurctx(mqc, opj_t1_getctxno_zc((OPJ_UINT32)flag, (OPJ_UINT32)orient));
+                if (opj_mqc_decode(mqc)) {
+                        opj_mqc_setcurctx(mqc, opj_t1_getctxno_sc((OPJ_UINT32)flag));
+                        v = opj_mqc_decode(mqc) ^ opj_t1_getspb((OPJ_UINT32)flag);
+                        *datap = v ? -oneplushalf : oneplushalf;
+                        opj_t1_updateflags(flagsp, (OPJ_UINT32)v, t1->flags_stride);
+                }
+                *flagsp |= T1_VISIT;
+        }
+}                               /* VSC and  BYPASS by Antonin */
+
+
+
+void opj_t1_enc_sigpass(opj_t1_t *t1,
+                        OPJ_INT32 bpno,
+                        OPJ_UINT32 orient,
+                        OPJ_INT32 *nmsedec,
+                        OPJ_BYTE type,
+                        OPJ_UINT32 cblksty
+                        )
+{
+	OPJ_UINT32 i, j, k, vsc; 
+    OPJ_INT32 one;
+
+	*nmsedec = 0;
+	one = 1 << (bpno + T1_NMSEDEC_FRACBITS);
+	for (k = 0; k < t1->h; k += 4) {
+		for (i = 0; i < t1->w; ++i) {
+			for (j = k; j < k + 4 && j < t1->h; ++j) {
+				vsc = ((cblksty & J2K_CCP_CBLKSTY_VSC) && (j == k + 3 || j == t1->h - 1)) ? 1 : 0;
+				opj_t1_enc_sigpass_step(
+						t1,
+						&t1->flags[((j+1) * t1->flags_stride) + i + 1],
+						&t1->data[(j * t1->w) + i],
+						orient,
+						bpno,
+						one,
+						nmsedec,
+						type,
+						vsc);
+			}
+		}
+	}
+}
+
+void opj_t1_dec_sigpass_raw(
+                opj_t1_t *t1,
+                OPJ_INT32 bpno,
+                OPJ_INT32 orient,
+                OPJ_INT32 cblksty)
+{
+        OPJ_INT32 one, half, oneplushalf, vsc;
+        OPJ_UINT32 i, j, k; 
+        one = 1 << bpno;
+        half = one >> 1;
+        oneplushalf = one | half;
+        for (k = 0; k < t1->h; k += 4) {
+                for (i = 0; i < t1->w; ++i) {
+                        for (j = k; j < k + 4 && j < t1->h; ++j) {
+                                vsc = ((cblksty & J2K_CCP_CBLKSTY_VSC) && (j == k + 3 || j == t1->h - 1)) ? 1 : 0;
+                                opj_t1_dec_sigpass_step_raw(
+                                                t1,
+                                                &t1->flags[((j+1) * t1->flags_stride) + i + 1],
+                                                &t1->data[(j * t1->w) + i],
+                                                orient,
+                                                oneplushalf,
+                                                vsc);
+                        }
+                }
+        }
+}                               /* VSC and  BYPASS by Antonin */
+
+void opj_t1_dec_sigpass_mqc(
+                opj_t1_t *t1,
+                OPJ_INT32 bpno,
+                OPJ_INT32 orient)
+{
+        OPJ_INT32 one, half, oneplushalf;
+        OPJ_UINT32 i, j, k;
+        OPJ_INT32 *data1 = t1->data;
+        opj_flag_t *flags1 = &t1->flags[1];
+        one = 1 << bpno;
+        half = one >> 1;
+        oneplushalf = one | half;
+        for (k = 0; k < (t1->h & ~3u); k += 4) {
+                for (i = 0; i < t1->w; ++i) {
+                        OPJ_INT32 *data2 = data1 + i;
+                        opj_flag_t *flags2 = flags1 + i;
+                        flags2 += t1->flags_stride;
+                        opj_t1_dec_sigpass_step_mqc(t1, flags2, data2, orient, oneplushalf);
+                        data2 += t1->w;
+                        flags2 += t1->flags_stride;
+                        opj_t1_dec_sigpass_step_mqc(t1, flags2, data2, orient, oneplushalf);
+                        data2 += t1->w;
+                        flags2 += t1->flags_stride;
+                        opj_t1_dec_sigpass_step_mqc(t1, flags2, data2, orient, oneplushalf);
+                        data2 += t1->w;
+                        flags2 += t1->flags_stride;
+                        opj_t1_dec_sigpass_step_mqc(t1, flags2, data2, orient, oneplushalf);
+                        data2 += t1->w;
+                }
+                data1 += t1->w << 2;
+                flags1 += t1->flags_stride << 2;
+        }
+        for (i = 0; i < t1->w; ++i) {
+                OPJ_INT32 *data2 = data1 + i;
+                opj_flag_t *flags2 = flags1 + i;
+                for (j = k; j < t1->h; ++j) {
+                        flags2 += t1->flags_stride;
+                        opj_t1_dec_sigpass_step_mqc(t1, flags2, data2, orient, oneplushalf);
+                        data2 += t1->w;
+                }
+        }
+}                               /* VSC and  BYPASS by Antonin */
+
+void opj_t1_dec_sigpass_mqc_vsc(
+                opj_t1_t *t1,
+                OPJ_INT32 bpno,
+                OPJ_INT32 orient)
+{
+        OPJ_INT32 one, half, oneplushalf, vsc;
+        OPJ_UINT32 i, j, k;
+        one = 1 << bpno;
+        half = one >> 1;
+        oneplushalf = one | half;
+        for (k = 0; k < t1->h; k += 4) {
+                for (i = 0; i < t1->w; ++i) {
+                        for (j = k; j < k + 4 && j < t1->h; ++j) {
+                                vsc = (j == k + 3 || j == t1->h - 1) ? 1 : 0;
+                                opj_t1_dec_sigpass_step_mqc_vsc(
+                                                t1,
+                                                &t1->flags[((j+1) * t1->flags_stride) + i + 1],
+                                                &t1->data[(j * t1->w) + i],
+                                                orient,
+                                                oneplushalf,
+                                                vsc);
+                        }
+                }
+        }
+}                               /* VSC and  BYPASS by Antonin */
+
+
+
+void opj_t1_enc_refpass_step(   opj_t1_t *t1,
+                                opj_flag_t *flagsp,
+                                OPJ_INT32 *datap,
+                                OPJ_INT32 bpno,
+                                OPJ_INT32 one,
+                                OPJ_INT32 *nmsedec,
+                                OPJ_BYTE type,
+                                OPJ_UINT32 vsc)
+{
+	OPJ_INT32 v;
+	OPJ_UINT32 flag;
+	
+	opj_mqc_t *mqc = t1->mqc;	/* MQC component */
+	
+	flag = vsc ? (OPJ_UINT32)((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (OPJ_UINT32)(*flagsp);
+	if ((flag & (T1_SIG | T1_VISIT)) == T1_SIG) {
+		*nmsedec += opj_t1_getnmsedec_ref((OPJ_UINT32)opj_int_abs(*datap), (OPJ_UINT32)(bpno + T1_NMSEDEC_FRACBITS));
+		v = opj_int_abs(*datap) & one ? 1 : 0;
+		opj_mqc_setcurctx(mqc, opj_t1_getctxno_mag(flag));	/* ESSAI */
+		if (type == T1_TYPE_RAW) {	/* BYPASS/LAZY MODE */
+			opj_mqc_bypass_enc(mqc, (OPJ_UINT32)v);
+		} else {
+			opj_mqc_encode(mqc, (OPJ_UINT32)v);
+		}
+		*flagsp |= T1_REFINE;
+	}
+}
+
+INLINE void opj_t1_dec_refpass_step_raw(
+                opj_t1_t *t1,
+                opj_flag_t *flagsp,
+                OPJ_INT32 *datap,
+                OPJ_INT32 poshalf,
+                OPJ_INT32 neghalf,
+                OPJ_INT32 vsc)
+{
+        OPJ_INT32 v, t, flag;
+       
+        opj_raw_t *raw = t1->raw;       /* RAW component */
+       
+        flag = vsc ? ((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*flagsp);
+        if ((flag & (T1_SIG | T1_VISIT)) == T1_SIG) {
+                        v = (OPJ_INT32)opj_raw_decode(raw);
+                t = v ? poshalf : neghalf;
+                *datap += *datap < 0 ? -t : t;
+                *flagsp |= T1_REFINE;
+        }
+}                               /* VSC and  BYPASS by Antonin  */
+
+INLINE void opj_t1_dec_refpass_step_mqc(
+                opj_t1_t *t1,
+                opj_flag_t *flagsp,
+                OPJ_INT32 *datap,
+                OPJ_INT32 poshalf,
+                OPJ_INT32 neghalf)
+{
+        OPJ_INT32 v, t, flag;
+       
+        opj_mqc_t *mqc = t1->mqc;       /* MQC component */
+       
+        flag = *flagsp;
+        if ((flag & (T1_SIG | T1_VISIT)) == T1_SIG) {
+                opj_mqc_setcurctx(mqc, opj_t1_getctxno_mag((OPJ_UINT32)flag));      /* ESSAI */
+                        v = opj_mqc_decode(mqc);
+                t = v ? poshalf : neghalf;
+                *datap += *datap < 0 ? -t : t;
+                *flagsp |= T1_REFINE;
+                }
+}                               /* VSC and  BYPASS by Antonin  */
+
+INLINE void opj_t1_dec_refpass_step_mqc_vsc(
+                opj_t1_t *t1,
+                opj_flag_t *flagsp,
+                OPJ_INT32 *datap,
+                OPJ_INT32 poshalf,
+                OPJ_INT32 neghalf,
+                OPJ_INT32 vsc)
+{
+        OPJ_INT32 v, t, flag;
+       
+        opj_mqc_t *mqc = t1->mqc;       /* MQC component */
+       
+        flag = vsc ? ((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*flagsp);
+        if ((flag & (T1_SIG | T1_VISIT)) == T1_SIG) {
+                opj_mqc_setcurctx(mqc, opj_t1_getctxno_mag((OPJ_UINT32)flag));      /* ESSAI */
+                v = opj_mqc_decode(mqc);
+                t = v ? poshalf : neghalf;
+                *datap += *datap < 0 ? -t : t;
+                *flagsp |= T1_REFINE;
+        }
+}                               /* VSC and  BYPASS by Antonin  */
+
+
+void opj_t1_enc_refpass(
+		opj_t1_t *t1,
+		OPJ_INT32 bpno,
+		OPJ_INT32 *nmsedec,
+		OPJ_BYTE type,
+		OPJ_UINT32 cblksty)
+{
+	OPJ_UINT32 i, j, k, vsc;
+    OPJ_INT32 one;
+
+	*nmsedec = 0;
+	one = 1 << (bpno + T1_NMSEDEC_FRACBITS);
+	for (k = 0; k < t1->h; k += 4) {
+		for (i = 0; i < t1->w; ++i) {
+			for (j = k; j < k + 4 && j < t1->h; ++j) {
+				vsc = ((cblksty & J2K_CCP_CBLKSTY_VSC) && (j == k + 3 || j == t1->h - 1)) ? 1 : 0;
+				opj_t1_enc_refpass_step(
+						t1,
+						&t1->flags[((j+1) * t1->flags_stride) + i + 1],
+						&t1->data[(j * t1->w) + i],
+						bpno,
+						one,
+						nmsedec,
+						type,
+						vsc);
+			}
+		}
+	}
+}
+
+void opj_t1_dec_refpass_raw(
+                opj_t1_t *t1,
+                OPJ_INT32 bpno,
+                OPJ_INT32 cblksty)
+{
+        OPJ_INT32 one, poshalf, neghalf;
+        OPJ_UINT32 i, j, k;
+        OPJ_INT32 vsc;
+        one = 1 << bpno;
+        poshalf = one >> 1;
+        neghalf = bpno > 0 ? -poshalf : -1;
+        for (k = 0; k < t1->h; k += 4) {
+                for (i = 0; i < t1->w; ++i) {
+                        for (j = k; j < k + 4 && j < t1->h; ++j) {
+                                vsc = ((cblksty & J2K_CCP_CBLKSTY_VSC) && (j == k + 3 || j == t1->h - 1)) ? 1 : 0;
+                                opj_t1_dec_refpass_step_raw(
+                                                t1,
+                                                &t1->flags[((j+1) * t1->flags_stride) + i + 1],
+                                                &t1->data[(j * t1->w) + i],
+                                                poshalf,
+                                                neghalf,
+                                                vsc);
+                        }
+                }
+        }
+}                               /* VSC and  BYPASS by Antonin */
+
+void opj_t1_dec_refpass_mqc(
+                opj_t1_t *t1,
+                OPJ_INT32 bpno)
+{
+        OPJ_INT32 one, poshalf, neghalf;
+        OPJ_UINT32 i, j, k;
+        OPJ_INT32 *data1 = t1->data;
+        opj_flag_t *flags1 = &t1->flags[1];
+        one = 1 << bpno;
+        poshalf = one >> 1;
+        neghalf = bpno > 0 ? -poshalf : -1;
+        for (k = 0; k < (t1->h & ~3u); k += 4) {
+                for (i = 0; i < t1->w; ++i) {
+                        OPJ_INT32 *data2 = data1 + i;
+                        opj_flag_t *flags2 = flags1 + i;
+                        flags2 += t1->flags_stride;
+                        opj_t1_dec_refpass_step_mqc(t1, flags2, data2, poshalf, neghalf);
+                        data2 += t1->w;
+                        flags2 += t1->flags_stride;
+                        opj_t1_dec_refpass_step_mqc(t1, flags2, data2, poshalf, neghalf);
+                        data2 += t1->w;
+                        flags2 += t1->flags_stride;
+                        opj_t1_dec_refpass_step_mqc(t1, flags2, data2, poshalf, neghalf);
+                        data2 += t1->w;
+                        flags2 += t1->flags_stride;
+                        opj_t1_dec_refpass_step_mqc(t1, flags2, data2, poshalf, neghalf);
+                        data2 += t1->w;
+                }
+                data1 += t1->w << 2;
+                flags1 += t1->flags_stride << 2;
+        }
+        for (i = 0; i < t1->w; ++i) {
+                OPJ_INT32 *data2 = data1 + i;
+                opj_flag_t *flags2 = flags1 + i;
+                for (j = k; j < t1->h; ++j) {
+                        flags2 += t1->flags_stride;
+                        opj_t1_dec_refpass_step_mqc(t1, flags2, data2, poshalf, neghalf);
+                        data2 += t1->w;
+                }
+        }
+}                               /* VSC and  BYPASS by Antonin */
+
+void opj_t1_dec_refpass_mqc_vsc(
+                opj_t1_t *t1,
+                OPJ_INT32 bpno)
+{
+        OPJ_INT32 one, poshalf, neghalf;
+        OPJ_UINT32 i, j, k;
+        OPJ_INT32 vsc;
+        one = 1 << bpno;
+        poshalf = one >> 1;
+        neghalf = bpno > 0 ? -poshalf : -1;
+        for (k = 0; k < t1->h; k += 4) {
+                for (i = 0; i < t1->w; ++i) {
+                        for (j = k; j < k + 4 && j < t1->h; ++j) {
+                                vsc = ((j == k + 3 || j == t1->h - 1)) ? 1 : 0;
+                                opj_t1_dec_refpass_step_mqc_vsc(
+                                                t1,
+                                                &t1->flags[((j+1) * t1->flags_stride) + i + 1],
+                                                &t1->data[(j * t1->w) + i],
+                                                poshalf,
+                                                neghalf,
+                                                vsc);
+                        }
+                }
+        }
+}                               /* VSC and  BYPASS by Antonin */
+
+
+void opj_t1_enc_clnpass_step(
+		opj_t1_t *t1,
+		opj_flag_t *flagsp,
+		OPJ_INT32 *datap,
+		OPJ_UINT32 orient,
+		OPJ_INT32 bpno,
+		OPJ_INT32 one,
+		OPJ_INT32 *nmsedec,
+		OPJ_UINT32 partial,
+		OPJ_UINT32 vsc)
+{
+	OPJ_INT32 v;
+	OPJ_UINT32 flag;
+	
+	opj_mqc_t *mqc = t1->mqc;	/* MQC component */
+	
+	flag = vsc ? (OPJ_UINT32)((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (OPJ_UINT32)(*flagsp);
+	if (partial) {
+		goto LABEL_PARTIAL;
+	}
+	if (!(*flagsp & (T1_SIG | T1_VISIT))) {
+		opj_mqc_setcurctx(mqc, opj_t1_getctxno_zc(flag, orient));
+		v = opj_int_abs(*datap) & one ? 1 : 0;
+		opj_mqc_encode(mqc, (OPJ_UINT32)v);
+		if (v) {
+LABEL_PARTIAL:
+			*nmsedec += opj_t1_getnmsedec_sig((OPJ_UINT32)opj_int_abs(*datap), (OPJ_UINT32)(bpno + T1_NMSEDEC_FRACBITS));
+			opj_mqc_setcurctx(mqc, opj_t1_getctxno_sc(flag));
+			v = *datap < 0 ? 1 : 0;
+			opj_mqc_encode(mqc, (OPJ_UINT32)(v ^ opj_t1_getspb((OPJ_UINT32)flag)));
+			opj_t1_updateflags(flagsp, (OPJ_UINT32)v, t1->flags_stride);
+		}
+	}
+	*flagsp &= ~T1_VISIT;
+}
+
+static void opj_t1_dec_clnpass_step_partial(
+		opj_t1_t *t1,
+		opj_flag_t *flagsp,
+		OPJ_INT32 *datap,
+		OPJ_INT32 orient,
+		OPJ_INT32 oneplushalf)
+{
+	OPJ_INT32 v, flag;
+	opj_mqc_t *mqc = t1->mqc;	/* MQC component */
+	
+	OPJ_ARG_NOT_USED(orient);
+	
+	flag = *flagsp;
+	opj_mqc_setcurctx(mqc, opj_t1_getctxno_sc((OPJ_UINT32)flag));
+	v = opj_mqc_decode(mqc) ^ opj_t1_getspb((OPJ_UINT32)flag);
+	*datap = v ? -oneplushalf : oneplushalf;
+	opj_t1_updateflags(flagsp, (OPJ_UINT32)v, t1->flags_stride);
+	*flagsp &= ~T1_VISIT;
+}				/* VSC and  BYPASS by Antonin */
+
+static void opj_t1_dec_clnpass_step(
+		opj_t1_t *t1,
+		opj_flag_t *flagsp,
+		OPJ_INT32 *datap,
+		OPJ_INT32 orient,
+		OPJ_INT32 oneplushalf)
+{
+	OPJ_INT32 v, flag;
+	
+	opj_mqc_t *mqc = t1->mqc;	/* MQC component */
+	
+	flag = *flagsp;
+	if (!(flag & (T1_SIG | T1_VISIT))) {
+		opj_mqc_setcurctx(mqc, opj_t1_getctxno_zc((OPJ_UINT32)flag, (OPJ_UINT32)orient));
+		if (opj_mqc_decode(mqc)) {
+			opj_mqc_setcurctx(mqc, opj_t1_getctxno_sc((OPJ_UINT32)flag));
+			v = opj_mqc_decode(mqc) ^ opj_t1_getspb((OPJ_UINT32)flag);
+			*datap = v ? -oneplushalf : oneplushalf;
+			opj_t1_updateflags(flagsp, (OPJ_UINT32)v, t1->flags_stride);
+		}
+	}
+	*flagsp &= ~T1_VISIT;
+}				/* VSC and  BYPASS by Antonin */
+
+static void opj_t1_dec_clnpass_step_vsc(
+		opj_t1_t *t1,
+		opj_flag_t *flagsp,
+		OPJ_INT32 *datap,
+		OPJ_INT32 orient,
+		OPJ_INT32 oneplushalf,
+		OPJ_INT32 partial,
+		OPJ_INT32 vsc)
+{
+	OPJ_INT32 v, flag;
+	
+	opj_mqc_t *mqc = t1->mqc;	/* MQC component */
+	
+	flag = vsc ? ((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*flagsp);
+	if (partial) {
+		goto LABEL_PARTIAL;
+	}
+	if (!(flag & (T1_SIG | T1_VISIT))) {
+		opj_mqc_setcurctx(mqc, opj_t1_getctxno_zc((OPJ_UINT32)flag, (OPJ_UINT32)orient));
+		if (opj_mqc_decode(mqc)) {
+LABEL_PARTIAL:
+			opj_mqc_setcurctx(mqc, opj_t1_getctxno_sc((OPJ_UINT32)flag));
+			v = opj_mqc_decode(mqc) ^ opj_t1_getspb((OPJ_UINT32)flag);
+			*datap = v ? -oneplushalf : oneplushalf;
+			opj_t1_updateflags(flagsp, (OPJ_UINT32)v, t1->flags_stride);
+		}
+	}
+	*flagsp &= ~T1_VISIT;
+}
+
+void opj_t1_enc_clnpass(
+		opj_t1_t *t1,
+		OPJ_INT32 bpno,
+		OPJ_UINT32 orient,
+		OPJ_INT32 *nmsedec,
+		OPJ_UINT32 cblksty)
+{
+	OPJ_UINT32 i, j, k;
+	OPJ_INT32 one;
+	OPJ_UINT32 agg, runlen, vsc;
+	
+	opj_mqc_t *mqc = t1->mqc;	/* MQC component */
+	
+	*nmsedec = 0;
+	one = 1 << (bpno + T1_NMSEDEC_FRACBITS);
+	for (k = 0; k < t1->h; k += 4) {
+		for (i = 0; i < t1->w; ++i) {
+			if (k + 3 < t1->h) {
+				if (cblksty & J2K_CCP_CBLKSTY_VSC) {
+					agg = !(MACRO_t1_flags(1 + k,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH)
+						|| MACRO_t1_flags(1 + k + 1,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH)
+						|| MACRO_t1_flags(1 + k + 2,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH)
+						|| (MACRO_t1_flags(1 + k + 3,1 + i) 
+						& (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW |	T1_SGN_S))) & (T1_SIG | T1_VISIT | T1_SIG_OTH));
+				} else {
+					agg = !(MACRO_t1_flags(1 + k,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH)
+						|| MACRO_t1_flags(1 + k + 1,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH)
+						|| MACRO_t1_flags(1 + k + 2,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH)
+						|| MACRO_t1_flags(1 + k + 3,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH));
+				}
+			} else {
+				agg = 0;
+			}
+			if (agg) {
+				for (runlen = 0; runlen < 4; ++runlen) {
+					if (opj_int_abs(t1->data[((k + runlen)*t1->w) + i]) & one)
+						break;
+				}
+				opj_mqc_setcurctx(mqc, T1_CTXNO_AGG);
+				opj_mqc_encode(mqc, runlen != 4);
+				if (runlen == 4) {
+					continue;
+				}
+				opj_mqc_setcurctx(mqc, T1_CTXNO_UNI);
+				opj_mqc_encode(mqc, runlen >> 1);
+				opj_mqc_encode(mqc, runlen & 1);
+			} else {
+				runlen = 0;
+			}
+			for (j = k + runlen; j < k + 4 && j < t1->h; ++j) {
+				vsc = ((cblksty & J2K_CCP_CBLKSTY_VSC) && (j == k + 3 || j == t1->h - 1)) ? 1 : 0;
+				opj_t1_enc_clnpass_step(
+						t1,
+						&t1->flags[((j+1) * t1->flags_stride) + i + 1],
+						&t1->data[(j * t1->w) + i],
+						orient,
+						bpno,
+						one,
+						nmsedec,
+						agg && (j == k + runlen),
+						vsc);
+			}
+		}
+	}
+}
+
+static void opj_t1_dec_clnpass(
+		opj_t1_t *t1,
+		OPJ_INT32 bpno,
+		OPJ_INT32 orient,
+		OPJ_INT32 cblksty)
+{
+	OPJ_INT32 one, half, oneplushalf, agg, runlen, vsc;
+    OPJ_UINT32 i, j, k;
+	OPJ_INT32 segsym = cblksty & J2K_CCP_CBLKSTY_SEGSYM;
+	
+	opj_mqc_t *mqc = t1->mqc;	/* MQC component */
+	
+	one = 1 << bpno;
+	half = one >> 1;
+	oneplushalf = one | half;
+	if (cblksty & J2K_CCP_CBLKSTY_VSC) {
+	for (k = 0; k < t1->h; k += 4) {
+		for (i = 0; i < t1->w; ++i) {
+			if (k + 3 < t1->h) {
+					agg = !(MACRO_t1_flags(1 + k,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH)
+						|| MACRO_t1_flags(1 + k + 1,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH)
+						|| MACRO_t1_flags(1 + k + 2,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH)
+						|| (MACRO_t1_flags(1 + k + 3,1 + i) 
+						& (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW |	T1_SGN_S))) & (T1_SIG | T1_VISIT | T1_SIG_OTH));
+				} else {
+				agg = 0;
+			}
+			if (agg) {
+				opj_mqc_setcurctx(mqc, T1_CTXNO_AGG);
+				if (!opj_mqc_decode(mqc)) {
+					continue;
+				}
+				opj_mqc_setcurctx(mqc, T1_CTXNO_UNI);
+				runlen = opj_mqc_decode(mqc);
+				runlen = (runlen << 1) | opj_mqc_decode(mqc);
+			} else {
+				runlen = 0;
+			}
+			for (j = k + (OPJ_UINT32)runlen; j < k + 4 && j < t1->h; ++j) {
+					vsc = (j == k + 3 || j == t1->h - 1) ? 1 : 0;
+					opj_t1_dec_clnpass_step_vsc(
+						t1,
+						&t1->flags[((j+1) * t1->flags_stride) + i + 1],
+						&t1->data[(j * t1->w) + i],
+						orient,
+						oneplushalf,
+						agg && (j == k + (OPJ_UINT32)runlen),
+						vsc);
+			}
+		}
+	}
+	} else {
+		OPJ_INT32 *data1 = t1->data;
+		opj_flag_t *flags1 = &t1->flags[1];
+		for (k = 0; k < (t1->h & ~3u); k += 4) {
+			for (i = 0; i < t1->w; ++i) {
+				OPJ_INT32 *data2 = data1 + i;
+				opj_flag_t *flags2 = flags1 + i;
+				agg = !(MACRO_t1_flags(1 + k,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH)
+					|| MACRO_t1_flags(1 + k + 1,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH)
+					|| MACRO_t1_flags(1 + k + 2,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH)
+					|| MACRO_t1_flags(1 + k + 3,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH));
+				if (agg) {
+					opj_mqc_setcurctx(mqc, T1_CTXNO_AGG);
+					if (!opj_mqc_decode(mqc)) {
+						continue;
+					}
+					opj_mqc_setcurctx(mqc, T1_CTXNO_UNI);
+					runlen = opj_mqc_decode(mqc);
+					runlen = (runlen << 1) | opj_mqc_decode(mqc);
+					flags2 += (OPJ_UINT32)runlen * t1->flags_stride;
+					data2 += (OPJ_UINT32)runlen * t1->w;
+					for (j = k + (OPJ_UINT32)runlen; j < k + 4 && j < t1->h; ++j) {
+						flags2 += t1->flags_stride;
+						if (agg && (j == k + (OPJ_UINT32)runlen)) {
+							opj_t1_dec_clnpass_step_partial(t1, flags2, data2, orient, oneplushalf);
+						} else {
+							opj_t1_dec_clnpass_step(t1, flags2, data2, orient, oneplushalf);
+						}
+						data2 += t1->w;
+					}
+				} else {
+					flags2 += t1->flags_stride;
+					opj_t1_dec_clnpass_step(t1, flags2, data2, orient, oneplushalf);
+					data2 += t1->w;
+					flags2 += t1->flags_stride;
+					opj_t1_dec_clnpass_step(t1, flags2, data2, orient, oneplushalf);
+					data2 += t1->w;
+					flags2 += t1->flags_stride;
+					opj_t1_dec_clnpass_step(t1, flags2, data2, orient, oneplushalf);
+					data2 += t1->w;
+					flags2 += t1->flags_stride;
+					opj_t1_dec_clnpass_step(t1, flags2, data2, orient, oneplushalf);
+					data2 += t1->w;
+				}
+			}
+			data1 += t1->w << 2;
+			flags1 += t1->flags_stride << 2;
+		}
+		for (i = 0; i < t1->w; ++i) {
+			OPJ_INT32 *data2 = data1 + i;
+			opj_flag_t *flags2 = flags1 + i;
+			for (j = k; j < t1->h; ++j) {
+				flags2 += t1->flags_stride;
+				opj_t1_dec_clnpass_step(t1, flags2, data2, orient, oneplushalf);
+				data2 += t1->w;
+			}
+		}
+	}
+
+	if (segsym) {
+		OPJ_INT32 v = 0;
+		opj_mqc_setcurctx(mqc, T1_CTXNO_UNI);
+		v = opj_mqc_decode(mqc);
+		v = (v << 1) | opj_mqc_decode(mqc);
+		v = (v << 1) | opj_mqc_decode(mqc);
+		v = (v << 1) | opj_mqc_decode(mqc);
+		/*
+		if (v!=0xa) {
+			opj_event_msg(t1->cinfo, EVT_WARNING, "Bad segmentation symbol %x\n", v);
+		} 
+		*/
+	}
+}				/* VSC and  BYPASS by Antonin */
+
+
+/** mod fixed_quality */
+static OPJ_FLOAT64 opj_t1_getwmsedec(
+		OPJ_INT32 nmsedec,
+		OPJ_UINT32 compno,
+		OPJ_UINT32 level,
+		OPJ_UINT32 orient,
+		OPJ_INT32 bpno,
+		OPJ_UINT32 qmfbid,
+		OPJ_FLOAT64 stepsize,
+		OPJ_UINT32 numcomps,
+		const OPJ_FLOAT64 * mct_norms)
+{
+	OPJ_FLOAT64 w1 = 1, w2, wmsedec;
+    OPJ_ARG_NOT_USED(numcomps);
+
+	if (mct_norms) {
+		w1 = mct_norms[compno];
+	}
+
+	if (qmfbid == 1) {
+		w2 = opj_dwt_getnorm(level, orient);
+	} else {	/* if (qmfbid == 0) */
+		w2 = opj_dwt_getnorm_real(level, orient);
+	}
+
+	wmsedec = w1 * w2 * stepsize * (1 << bpno);
+	wmsedec *= wmsedec * nmsedec / 8192.0;
+
+	return wmsedec;
+}
+
+OPJ_BOOL opj_t1_allocate_buffers(
+		opj_t1_t *t1,
+		OPJ_UINT32 w,
+		OPJ_UINT32 h)
+{
+	OPJ_UINT32 datasize=w * h;
+	OPJ_UINT32 flagssize;
+
+	if(datasize > t1->datasize){
+		opj_aligned_free(t1->data);
+		t1->data = (OPJ_INT32*) opj_aligned_malloc(datasize * sizeof(OPJ_INT32));
+		if(!t1->data){
+			return OPJ_FALSE;
+		}
+		t1->datasize=datasize;
+	}
+	memset(t1->data,0,datasize * sizeof(OPJ_INT32));
+
+	t1->flags_stride=w+2;
+	flagssize=t1->flags_stride * (h+2);
+
+	if(flagssize > t1->flagssize){
+		opj_aligned_free(t1->flags);
+		t1->flags = (opj_flag_t*) opj_aligned_malloc(flagssize * sizeof(opj_flag_t));
+		if(!t1->flags){
+			return OPJ_FALSE;
+		}
+		t1->flagssize=flagssize;
+	}
+	memset(t1->flags,0,flagssize * sizeof(opj_flag_t));
+
+	t1->w=w;
+	t1->h=h;
+
+	return OPJ_TRUE;
+}
+
+/* ----------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------- */
+/**
+ * Creates a new Tier 1 handle
+ * and initializes the look-up tables of the Tier-1 coder/decoder
+ * @return a new T1 handle if successful, returns NULL otherwise
+*/
+opj_t1_t* opj_t1_create()
+{
+	opj_t1_t *l_t1 = 00;
+
+	l_t1 = (opj_t1_t*) opj_malloc(sizeof(opj_t1_t));
+	if (!l_t1) {
+		return 00;
+	}
+	memset(l_t1,0,sizeof(opj_t1_t));
+
+	/* create MQC and RAW handles */
+	l_t1->mqc = opj_mqc_create();
+	if (! l_t1->mqc) {
+		opj_t1_destroy(l_t1);
+		return 00;
+	}
+
+	l_t1->raw = opj_raw_create();
+	if (! l_t1->raw) {
+		opj_t1_destroy(l_t1);
+		return 00;
+	}
+
+	return l_t1;
+}
+
+
+/**
+ * Destroys a previously created T1 handle
+ *
+ * @param p_t1 Tier 1 handle to destroy
+*/
+void opj_t1_destroy(opj_t1_t *p_t1)
+{
+	if (! p_t1) {
+		return;
+	}
+
+	/* destroy MQC and RAW handles */
+	opj_mqc_destroy(p_t1->mqc);
+	p_t1->mqc = 00;
+	opj_raw_destroy(p_t1->raw);
+	p_t1->raw = 00;
+	
+    if (p_t1->data) {
+		opj_aligned_free(p_t1->data);
+		p_t1->data = 00;
+	}
+
+	if (p_t1->flags) {
+		opj_aligned_free(p_t1->flags);
+		p_t1->flags = 00;
+	}
+
+	opj_free(p_t1);
+}
+
+OPJ_BOOL opj_t1_decode_cblks(   opj_t1_t* t1,
+                            opj_tcd_tilecomp_t* tilec,
+                            opj_tccp_t* tccp
+                            )
+{
+	OPJ_UINT32 resno, bandno, precno, cblkno;
+	OPJ_UINT32 tile_w = (OPJ_UINT32)(tilec->x1 - tilec->x0);
+
+	for (resno = 0; resno < tilec->minimum_num_resolutions; ++resno) {
+		opj_tcd_resolution_t* res = &tilec->resolutions[resno];
+
+		for (bandno = 0; bandno < res->numbands; ++bandno) {
+			opj_tcd_band_t* restrict band = &res->bands[bandno];
+
+			for (precno = 0; precno < res->pw * res->ph; ++precno) {
+				opj_tcd_precinct_t* precinct = &band->precincts[precno];
+
+				for (cblkno = 0; cblkno < precinct->cw * precinct->ch; ++cblkno) {
+					opj_tcd_cblk_dec_t* cblk = &precinct->cblks.dec[cblkno];
+					OPJ_INT32* restrict datap;
+					/*void* restrict tiledp;*/
+					OPJ_UINT32 cblk_w, cblk_h;
+					OPJ_INT32 x, y;
+					OPJ_UINT32 i, j;
+
+                    if (OPJ_FALSE == opj_t1_decode_cblk(
+                                            t1,
+                                            cblk,
+                                            band->bandno,
+                                            (OPJ_UINT32)tccp->roishift,
+                                            tccp->cblksty)) {
+                            return OPJ_FALSE;
+                    }
+
+					x = cblk->x0 - band->x0;
+					y = cblk->y0 - band->y0;
+					if (band->bandno & 1) {
+						opj_tcd_resolution_t* pres = &tilec->resolutions[resno - 1];
+						x += pres->x1 - pres->x0;
+					}
+					if (band->bandno & 2) {
+						opj_tcd_resolution_t* pres = &tilec->resolutions[resno - 1];
+						y += pres->y1 - pres->y0;
+					}
+
+					datap=t1->data;
+					cblk_w = t1->w;
+					cblk_h = t1->h;
+
+					if (tccp->roishift) {
+						OPJ_INT32 thresh = 1 << tccp->roishift;
+						for (j = 0; j < cblk_h; ++j) {
+							for (i = 0; i < cblk_w; ++i) {
+								OPJ_INT32 val = datap[(j * cblk_w) + i];
+								OPJ_INT32 mag = abs(val);
+								if (mag >= thresh) {
+									mag >>= tccp->roishift;
+									datap[(j * cblk_w) + i] = val < 0 ? -mag : mag;
+								}
+							}
+						}
+					}
+
+					/*tiledp=(void*)&tilec->data[(y * tile_w) + x];*/
+					if (tccp->qmfbid == 1) {
+                        OPJ_INT32* restrict tiledp = &tilec->data[(OPJ_UINT32)y * tile_w + (OPJ_UINT32)x];
+						for (j = 0; j < cblk_h; ++j) {
+							for (i = 0; i < cblk_w; ++i) {
+								OPJ_INT32 tmp = datap[(j * cblk_w) + i];
+								((OPJ_INT32*)tiledp)[(j * tile_w) + i] = tmp / 2;
+							}
+						}
+					} else {		/* if (tccp->qmfbid == 0) */
+                        OPJ_FLOAT32* restrict tiledp = (OPJ_FLOAT32*) &tilec->data[(OPJ_UINT32)y * tile_w + (OPJ_UINT32)x];
+						for (j = 0; j < cblk_h; ++j) {
+                            OPJ_FLOAT32* restrict tiledp2 = tiledp;
+							for (i = 0; i < cblk_w; ++i) {
+                                OPJ_FLOAT32 tmp = (OPJ_FLOAT32)*datap * band->stepsize;
+                                *tiledp2 = tmp;
+                                datap++;
+                                tiledp2++;
+								/*float tmp = datap[(j * cblk_w) + i] * band->stepsize;
+								((float*)tiledp)[(j * tile_w) + i] = tmp;*/
+
+							}
+                            tiledp += tile_w;
+						}
+					}
+                    /*opj_free(cblk->data);
+					opj_free(cblk->segs);*/
+					/*cblk->segs = 00;*/
+				} /* cblkno */
+                /*opj_free(precinct->cblks.dec);*/
+			} /* precno */
+		} /* bandno */
+	} /* resno */
+        return OPJ_TRUE;
+}
+
+
+OPJ_BOOL opj_t1_decode_cblk(opj_t1_t *t1,
+                            opj_tcd_cblk_dec_t* cblk,
+                            OPJ_UINT32 orient,
+                            OPJ_UINT32 roishift,
+                            OPJ_UINT32 cblksty)
+{
+	opj_raw_t *raw = t1->raw;	/* RAW component */
+	opj_mqc_t *mqc = t1->mqc;	/* MQC component */
+
+	OPJ_INT32 bpno;
+	OPJ_UINT32 passtype;
+	OPJ_UINT32 segno, passno;
+	OPJ_BYTE type = T1_TYPE_MQ; /* BYPASS mode */
+
+	if(!opj_t1_allocate_buffers(
+				t1,
+				(OPJ_UINT32)(cblk->x1 - cblk->x0),
+				(OPJ_UINT32)(cblk->y1 - cblk->y0)))
+	{
+		return OPJ_FALSE;
+	}
+
+	bpno = (OPJ_INT32)(roishift + cblk->numbps - 1);
+	passtype = 2;
+
+	opj_mqc_resetstates(mqc);
+	opj_mqc_setstate(mqc, T1_CTXNO_UNI, 0, 46);
+	opj_mqc_setstate(mqc, T1_CTXNO_AGG, 0, 3);
+	opj_mqc_setstate(mqc, T1_CTXNO_ZC, 0, 4);
+
+	for (segno = 0; segno < cblk->real_num_segs; ++segno) {
+		opj_tcd_seg_t *seg = &cblk->segs[segno];
+
+		/* BYPASS mode */
+		type = ((bpno <= ((OPJ_INT32) (cblk->numbps) - 1) - 4) && (passtype < 2) && (cblksty & J2K_CCP_CBLKSTY_LAZY)) ? T1_TYPE_RAW : T1_TYPE_MQ;
+		/* FIXME: slviewer gets here with a null pointer. Why? Partially downloaded and/or corrupt textures? */
+		if(seg->data == 00){
+			continue;
+		}
+		if (type == T1_TYPE_RAW) {
+			opj_raw_init_dec(raw, (*seg->data) + seg->dataindex, seg->len);
+		} else {
+            if (OPJ_FALSE == opj_mqc_init_dec(mqc, (*seg->data) + seg->dataindex, seg->len)) {
+                    return OPJ_FALSE;
+            }
+		}
+
+		for (passno = 0; passno < seg->real_num_passes; ++passno) {
+            switch (passtype) {
+                case 0:
+                    if (type == T1_TYPE_RAW) {
+                        opj_t1_dec_sigpass_raw(t1, bpno+1, (OPJ_INT32)orient, (OPJ_INT32)cblksty);
+                    } else {
+                        if (cblksty & J2K_CCP_CBLKSTY_VSC) {
+                            opj_t1_dec_sigpass_mqc_vsc(t1, bpno+1, (OPJ_INT32)orient);
+                        } else {
+                            opj_t1_dec_sigpass_mqc(t1, bpno+1, (OPJ_INT32)orient);
+                        }
+                    }
+                    break;
+                case 1:
+                    if (type == T1_TYPE_RAW) {
+                            opj_t1_dec_refpass_raw(t1, bpno+1, (OPJ_INT32)cblksty);
+                    } else {
+                        if (cblksty & J2K_CCP_CBLKSTY_VSC) {
+                            opj_t1_dec_refpass_mqc_vsc(t1, bpno+1);
+                        } else {
+                            opj_t1_dec_refpass_mqc(t1, bpno+1);
+                        }
+                    }
+                    break;
+                case 2:
+                    opj_t1_dec_clnpass(t1, bpno+1, (OPJ_INT32)orient, (OPJ_INT32)cblksty);
+                    break;
+            }
+
+			if ((cblksty & J2K_CCP_CBLKSTY_RESET) && type == T1_TYPE_MQ) {
+				opj_mqc_resetstates(mqc);
+				opj_mqc_setstate(mqc, T1_CTXNO_UNI, 0, 46);
+				opj_mqc_setstate(mqc, T1_CTXNO_AGG, 0, 3);
+				opj_mqc_setstate(mqc, T1_CTXNO_ZC, 0, 4);
+			}
+			if (++passtype == 3) {
+				passtype = 0;
+				bpno--;
+			}
+		}
+	}
+        return OPJ_TRUE;
+}
+
+
+
+
+OPJ_BOOL opj_t1_encode_cblks(   opj_t1_t *t1,
+                                opj_tcd_tile_t *tile,
+                                opj_tcp_t *tcp,
+                                const OPJ_FLOAT64 * mct_norms
+                                )
+{
+	OPJ_UINT32 compno, resno, bandno, precno, cblkno;
+
+	tile->distotile = 0;		/* fixed_quality */
+
+	for (compno = 0; compno < tile->numcomps; ++compno) {
+		opj_tcd_tilecomp_t* tilec = &tile->comps[compno];
+		opj_tccp_t* tccp = &tcp->tccps[compno];
+		OPJ_UINT32 tile_w = (OPJ_UINT32)(tilec->x1 - tilec->x0);
+
+		for (resno = 0; resno < tilec->numresolutions; ++resno) {
+			opj_tcd_resolution_t *res = &tilec->resolutions[resno];
+
+			for (bandno = 0; bandno < res->numbands; ++bandno) {
+				opj_tcd_band_t* restrict band = &res->bands[bandno];
+                OPJ_INT32 bandconst = 8192 * 8192 / ((OPJ_INT32) floor(band->stepsize * 8192));
+
+				for (precno = 0; precno < res->pw * res->ph; ++precno) {
+					opj_tcd_precinct_t *prc = &band->precincts[precno];
+
+					for (cblkno = 0; cblkno < prc->cw * prc->ch; ++cblkno) {
+						opj_tcd_cblk_enc_t* cblk = &prc->cblks.enc[cblkno];
+						OPJ_INT32 * restrict datap;
+						OPJ_INT32* restrict tiledp;
+						OPJ_UINT32 cblk_w;
+						OPJ_UINT32 cblk_h;
+						OPJ_UINT32 i, j;
+
+						OPJ_INT32 x = cblk->x0 - band->x0;
+						OPJ_INT32 y = cblk->y0 - band->y0;
+						if (band->bandno & 1) {
+							opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1];
+							x += pres->x1 - pres->x0;
+						}
+						if (band->bandno & 2) {
+							opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1];
+							y += pres->y1 - pres->y0;
+						}
+
+						if(!opj_t1_allocate_buffers(
+									t1,
+									(OPJ_UINT32)(cblk->x1 - cblk->x0),
+									(OPJ_UINT32)(cblk->y1 - cblk->y0)))
+						{
+							return OPJ_FALSE;
+						}
+
+						datap=t1->data;
+						cblk_w = t1->w;
+						cblk_h = t1->h;
+
+						tiledp=&tilec->data[(OPJ_UINT32)y * tile_w + (OPJ_UINT32)x];
+						if (tccp->qmfbid == 1) {
+							for (j = 0; j < cblk_h; ++j) {
+								for (i = 0; i < cblk_w; ++i) {
+									OPJ_INT32 tmp = tiledp[(j * tile_w) + i];
+									datap[(j * cblk_w) + i] = tmp << T1_NMSEDEC_FRACBITS;
+								}
+							}
+						} else {		/* if (tccp->qmfbid == 0) */
+							for (j = 0; j < cblk_h; ++j) {
+								for (i = 0; i < cblk_w; ++i) {
+									OPJ_INT32 tmp = tiledp[(j * tile_w) + i];
+									datap[(j * cblk_w) + i] =
+										opj_int_fix_mul(
+										tmp,
+										bandconst) >> (11 - T1_NMSEDEC_FRACBITS);
+								}
+							}
+						}
+
+						opj_t1_encode_cblk(
+								t1,
+								cblk,
+								band->bandno,
+								compno,
+								tilec->numresolutions - 1 - resno,
+								tccp->qmfbid,
+								band->stepsize,
+								tccp->cblksty,
+								tile->numcomps,
+								tile,
+								mct_norms);
+
+					} /* cblkno */
+				} /* precno */
+			} /* bandno */
+		} /* resno  */
+	} /* compno  */
+	return OPJ_TRUE;
+}
+
+/** mod fixed_quality */
+void opj_t1_encode_cblk(opj_t1_t *t1,
+                        opj_tcd_cblk_enc_t* cblk,
+                        OPJ_UINT32 orient,
+                        OPJ_UINT32 compno,
+                        OPJ_UINT32 level,
+                        OPJ_UINT32 qmfbid,
+                        OPJ_FLOAT64 stepsize,
+                        OPJ_UINT32 cblksty,
+                        OPJ_UINT32 numcomps,
+                        opj_tcd_tile_t * tile,
+                        const OPJ_FLOAT64 * mct_norms)
+{
+	OPJ_FLOAT64 cumwmsedec = 0.0;
+
+	opj_mqc_t *mqc = t1->mqc;	/* MQC component */
+
+	OPJ_UINT32 passno;
+	OPJ_INT32 bpno;
+	OPJ_UINT32 passtype;
+	OPJ_INT32 nmsedec = 0;
+	OPJ_INT32 max;
+	OPJ_UINT32 i;
+	OPJ_BYTE type = T1_TYPE_MQ;
+	OPJ_FLOAT64 tempwmsedec;
+
+	max = 0;
+	for (i = 0; i < t1->w * t1->h; ++i) {
+		OPJ_INT32 tmp = abs(t1->data[i]);
+		max = opj_int_max(max, tmp);
+	}
+
+	cblk->numbps = max ? (OPJ_UINT32)((opj_int_floorlog2(max) + 1) - T1_NMSEDEC_FRACBITS) : 0;
+
+	bpno = (OPJ_INT32)(cblk->numbps - 1);
+	passtype = 2;
+
+	opj_mqc_resetstates(mqc);
+	opj_mqc_setstate(mqc, T1_CTXNO_UNI, 0, 46);
+	opj_mqc_setstate(mqc, T1_CTXNO_AGG, 0, 3);
+	opj_mqc_setstate(mqc, T1_CTXNO_ZC, 0, 4);
+	opj_mqc_init_enc(mqc, cblk->data);
+
+	for (passno = 0; bpno >= 0; ++passno) {
+		opj_tcd_pass_t *pass = &cblk->passes[passno];
+		OPJ_UINT32 correction = 3;
+		type = ((bpno < ((OPJ_INT32) (cblk->numbps) - 4)) && (passtype < 2) && (cblksty & J2K_CCP_CBLKSTY_LAZY)) ? T1_TYPE_RAW : T1_TYPE_MQ;
+
+		switch (passtype) {
+			case 0:
+				opj_t1_enc_sigpass(t1, bpno, orient, &nmsedec, type, cblksty);
+				break;
+			case 1:
+				opj_t1_enc_refpass(t1, bpno, &nmsedec, type, cblksty);
+				break;
+			case 2:
+				opj_t1_enc_clnpass(t1, bpno, orient, &nmsedec, cblksty);
+				/* code switch SEGMARK (i.e. SEGSYM) */
+				if (cblksty & J2K_CCP_CBLKSTY_SEGSYM)
+					opj_mqc_segmark_enc(mqc);
+				break;
+		}
+
+		/* fixed_quality */
+		tempwmsedec = opj_t1_getwmsedec(nmsedec, compno, level, orient, bpno, qmfbid, stepsize, numcomps,mct_norms) ;
+		cumwmsedec += tempwmsedec;
+		tile->distotile += tempwmsedec;
+
+		/* Code switch "RESTART" (i.e. TERMALL) */
+		if ((cblksty & J2K_CCP_CBLKSTY_TERMALL)	&& !((passtype == 2) && (bpno - 1 < 0))) {
+			if (type == T1_TYPE_RAW) {
+				opj_mqc_flush(mqc);
+				correction = 1;
+				/* correction = mqc_bypass_flush_enc(); */
+			} else {			/* correction = mqc_restart_enc(); */
+				opj_mqc_flush(mqc);
+				correction = 1;
+			}
+			pass->term = 1;
+		} else {
+			if (((bpno < ((OPJ_INT32) (cblk->numbps) - 4) && (passtype > 0))
+				|| ((bpno == ((OPJ_INT32)cblk->numbps - 4)) && (passtype == 2))) && (cblksty & J2K_CCP_CBLKSTY_LAZY)) {
+				if (type == T1_TYPE_RAW) {
+					opj_mqc_flush(mqc);
+					correction = 1;
+					/* correction = mqc_bypass_flush_enc(); */
+				} else {		/* correction = mqc_restart_enc(); */
+					opj_mqc_flush(mqc);
+					correction = 1;
+				}
+				pass->term = 1;
+			} else {
+				pass->term = 0;
+			}
+		}
+
+		if (++passtype == 3) {
+			passtype = 0;
+			bpno--;
+		}
+
+		if (pass->term && bpno > 0) {
+			type = ((bpno < ((OPJ_INT32) (cblk->numbps) - 4)) && (passtype < 2) && (cblksty & J2K_CCP_CBLKSTY_LAZY)) ? T1_TYPE_RAW : T1_TYPE_MQ;
+			if (type == T1_TYPE_RAW)
+				opj_mqc_bypass_init_enc(mqc);
+			else
+				opj_mqc_restart_init_enc(mqc);
+		}
+
+		pass->distortiondec = cumwmsedec;
+		pass->rate = opj_mqc_numbytes(mqc) + correction;	/* FIXME */
+
+		/* Code-switch "RESET" */
+		if (cblksty & J2K_CCP_CBLKSTY_RESET)
+			opj_mqc_reset_enc(mqc);
+	}
+
+	/* Code switch "ERTERM" (i.e. PTERM) */
+	if (cblksty & J2K_CCP_CBLKSTY_PTERM)
+		opj_mqc_erterm_enc(mqc);
+	else /* Default coding */ if (!(cblksty & J2K_CCP_CBLKSTY_LAZY))
+		opj_mqc_flush(mqc);
+
+	cblk->totalpasses = passno;
+
+	for (passno = 0; passno<cblk->totalpasses; passno++) {
+		opj_tcd_pass_t *pass = &cblk->passes[passno];
+		if (pass->rate > opj_mqc_numbytes(mqc))
+			pass->rate = opj_mqc_numbytes(mqc);
+		/*Preventing generation of FF as last data byte of a pass*/
+		if((pass->rate>1) && (cblk->data[pass->rate - 1] == 0xFF)){
+			pass->rate--;
+		}
+		pass->len = pass->rate - (passno == 0 ? 0 : cblk->passes[passno - 1].rate);
+	}
+}
+
+#if 0
+void opj_t1_dec_refpass_step(   opj_t1_t *t1,
+                                opj_flag_t *flagsp,
+                                OPJ_INT32 *datap,
+                                OPJ_INT32 poshalf,
+                                OPJ_INT32 neghalf,
+                                OPJ_BYTE type,
+                                OPJ_UINT32 vsc)
+{
+	OPJ_INT32  t;
+	OPJ_UINT32 v,flag;
+
+	opj_mqc_t *mqc = t1->mqc;	/* MQC component */
+	opj_raw_t *raw = t1->raw;	/* RAW component */
+
+	flag = vsc ? ((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*flagsp);
+	if ((flag & (T1_SIG | T1_VISIT)) == T1_SIG) {
+		opj_mqc_setcurctx(mqc, opj_t1_getctxno_mag(flag));	/* ESSAI */
+		if (type == T1_TYPE_RAW) {
+			v = opj_raw_decode(raw);
+		} else {
+			v = opj_mqc_decode(mqc);
+		}
+		t = v ? poshalf : neghalf;
+		*datap += *datap < 0 ? -t : t;
+		*flagsp |= T1_REFINE;
+	}
+}				/* VSC and  BYPASS by Antonin  */
+#endif
+
+
+
+#if 0
+void opj_t1_dec_sigpass_step(   opj_t1_t *t1,
+                                opj_flag_t *flagsp,
+                                OPJ_INT32 *datap,
+                                OPJ_UINT32 orient,
+                                OPJ_INT32 oneplushalf,
+                                OPJ_BYTE type,
+                                OPJ_UINT32 vsc)
+{
+	OPJ_UINT32 v, flag;
+
+	opj_raw_t *raw = t1->raw;	/* RAW component */
+	opj_mqc_t *mqc = t1->mqc;	/* MQC component */
+
+	flag = vsc ? ((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*flagsp);
+	if ((flag & T1_SIG_OTH) && !(flag & (T1_SIG | T1_VISIT))) {
+		if (type == T1_TYPE_RAW) {
+			if (opj_raw_decode(raw)) {
+				v = opj_raw_decode(raw);	/* ESSAI */
+				*datap = v ? -oneplushalf : oneplushalf;
+				opj_t1_updateflags(flagsp, v, t1->flags_stride);
+			}
+		} else {
+			opj_mqc_setcurctx(mqc, opj_t1_getctxno_zc(flag, orient));
+			if (opj_mqc_decode(mqc)) {
+				opj_mqc_setcurctx(mqc, opj_t1_getctxno_sc(flag));
+				v = opj_mqc_decode(mqc) ^ opj_t1_getspb(flag);
+				*datap = v ? -oneplushalf : oneplushalf;
+				opj_t1_updateflags(flagsp, v, t1->flags_stride);
+			}
+		}
+		*flagsp |= T1_VISIT;
+	}
+}				/* VSC and  BYPASS by Antonin */
+#endif
diff --git a/Source/LibOpenJPEG/t1.h b/Source/LibOpenJPEG/t1.h
index 1c93fa7..0de117a 100644
--- a/Source/LibOpenJPEG/t1.h
+++ b/Source/LibOpenJPEG/t1.h
@@ -1,147 +1,157 @@
-/*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
- * Copyright (c) 2001-2003, David Janssens
- * Copyright (c) 2002-2003, Yannick Verschueren
- * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef __T1_H
-#define __T1_H
-/**
- at file t1.h
- at brief Implementation of the tier-1 coding (coding of code-block coefficients) (T1)
-
-The functions in T1.C have for goal to realize the tier-1 coding operation. The functions
-in T1.C are used by some function in TCD.C.
-*/
-
-/** @defgroup T1 T1 - Implementation of the tier-1 coding */
-/*@{*/
-
-/* ----------------------------------------------------------------------- */
-#define T1_NMSEDEC_BITS 7
-
-#define T1_SIG_NE 0x0001	/**< Context orientation : North-East direction */
-#define T1_SIG_SE 0x0002	/**< Context orientation : South-East direction */
-#define T1_SIG_SW 0x0004	/**< Context orientation : South-West direction */
-#define T1_SIG_NW 0x0008	/**< Context orientation : North-West direction */
-#define T1_SIG_N 0x0010		/**< Context orientation : North direction */
-#define T1_SIG_E 0x0020		/**< Context orientation : East direction */
-#define T1_SIG_S 0x0040		/**< Context orientation : South direction */
-#define T1_SIG_W 0x0080		/**< Context orientation : West direction */
-#define T1_SIG_OTH (T1_SIG_N|T1_SIG_NE|T1_SIG_E|T1_SIG_SE|T1_SIG_S|T1_SIG_SW|T1_SIG_W|T1_SIG_NW)
-#define T1_SIG_PRIM (T1_SIG_N|T1_SIG_E|T1_SIG_S|T1_SIG_W)
-
-#define T1_SGN_N 0x0100
-#define T1_SGN_E 0x0200
-#define T1_SGN_S 0x0400
-#define T1_SGN_W 0x0800
-#define T1_SGN (T1_SGN_N|T1_SGN_E|T1_SGN_S|T1_SGN_W)
-
-#define T1_SIG 0x1000
-#define T1_REFINE 0x2000
-#define T1_VISIT 0x4000
-
-#define T1_NUMCTXS_ZC 9
-#define T1_NUMCTXS_SC 5
-#define T1_NUMCTXS_MAG 3
-#define T1_NUMCTXS_AGG 1
-#define T1_NUMCTXS_UNI 1
-
-#define T1_CTXNO_ZC 0
-#define T1_CTXNO_SC (T1_CTXNO_ZC+T1_NUMCTXS_ZC)
-#define T1_CTXNO_MAG (T1_CTXNO_SC+T1_NUMCTXS_SC)
-#define T1_CTXNO_AGG (T1_CTXNO_MAG+T1_NUMCTXS_MAG)
-#define T1_CTXNO_UNI (T1_CTXNO_AGG+T1_NUMCTXS_AGG)
-#define T1_NUMCTXS (T1_CTXNO_UNI+T1_NUMCTXS_UNI)
-
-#define T1_NMSEDEC_FRACBITS (T1_NMSEDEC_BITS-1)
-
-#define T1_TYPE_MQ 0	/**< Normal coding using entropy coder */
-#define T1_TYPE_RAW 1	/**< No encoding the information is store under raw format in codestream (mode switch RAW)*/
-
-/* ----------------------------------------------------------------------- */
-
-typedef short flag_t;
-
-/**
-Tier-1 coding (coding of code-block coefficients)
-*/
-typedef struct opj_t1 {
-	/** codec context */
-	opj_common_ptr cinfo;
-
-	/** MQC component */
-	opj_mqc_t *mqc;
-	/** RAW component */
-	opj_raw_t *raw;
-
-	int *data;
-	flag_t *flags;
-	int w;
-	int h;
-	int datasize;
-	int flagssize;
-	int flags_stride;
-} opj_t1_t;
-
-#define MACRO_t1_flags(x,y) t1->flags[((x)*(t1->flags_stride))+(y)]
-
-/** @name Exported functions */
-/*@{*/
-/* ----------------------------------------------------------------------- */
-/**
-Create a new T1 handle 
-and initialize the look-up tables of the Tier-1 coder/decoder
- at return Returns a new T1 handle if successful, returns NULL otherwise
- at see t1_init_luts
-*/
-opj_t1_t* t1_create(opj_common_ptr cinfo);
-/**
-Destroy a previously created T1 handle
- at param t1 T1 handle to destroy
-*/
-void t1_destroy(opj_t1_t *t1);
-/**
-Encode the code-blocks of a tile
- at param t1 T1 handle
- at param tile The tile to encode
- at param tcp Tile coding parameters
-*/
-void t1_encode_cblks(opj_t1_t *t1, opj_tcd_tile_t *tile, opj_tcp_t *tcp);
-/**
-Decode the code-blocks of a tile
- at param t1 T1 handle
- at param tilec The tile to decode
- at param tccp Tile coding parameters
-*/
-void t1_decode_cblks(opj_t1_t* t1, opj_tcd_tilecomp_t* tilec, opj_tccp_t* tccp);
-/* ----------------------------------------------------------------------- */
-/*@}*/
-
-/*@}*/
-
-#endif /* __T1_H */
+/*
+ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2007, Professor Benoit Macq
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef __T1_H
+#define __T1_H
+/**
+ at file t1.h
+ at brief Implementation of the tier-1 coding (coding of code-block coefficients) (T1)
+
+The functions in T1.C have for goal to realize the tier-1 coding operation. The functions
+in T1.C are used by some function in TCD.C.
+*/
+
+/** @defgroup T1 T1 - Implementation of the tier-1 coding */
+/*@{*/
+
+/* ----------------------------------------------------------------------- */
+#define T1_NMSEDEC_BITS 7
+
+#define T1_SIG_NE 0x0001	/**< Context orientation : North-East direction */
+#define T1_SIG_SE 0x0002	/**< Context orientation : South-East direction */
+#define T1_SIG_SW 0x0004	/**< Context orientation : South-West direction */
+#define T1_SIG_NW 0x0008	/**< Context orientation : North-West direction */
+#define T1_SIG_N 0x0010		/**< Context orientation : North direction */
+#define T1_SIG_E 0x0020		/**< Context orientation : East direction */
+#define T1_SIG_S 0x0040		/**< Context orientation : South direction */
+#define T1_SIG_W 0x0080		/**< Context orientation : West direction */
+#define T1_SIG_OTH (T1_SIG_N|T1_SIG_NE|T1_SIG_E|T1_SIG_SE|T1_SIG_S|T1_SIG_SW|T1_SIG_W|T1_SIG_NW)
+#define T1_SIG_PRIM (T1_SIG_N|T1_SIG_E|T1_SIG_S|T1_SIG_W)
+
+#define T1_SGN_N 0x0100
+#define T1_SGN_E 0x0200
+#define T1_SGN_S 0x0400
+#define T1_SGN_W 0x0800
+#define T1_SGN (T1_SGN_N|T1_SGN_E|T1_SGN_S|T1_SGN_W)
+
+#define T1_SIG 0x1000
+#define T1_REFINE 0x2000
+#define T1_VISIT 0x4000
+
+#define T1_NUMCTXS_ZC 9
+#define T1_NUMCTXS_SC 5
+#define T1_NUMCTXS_MAG 3
+#define T1_NUMCTXS_AGG 1
+#define T1_NUMCTXS_UNI 1
+
+#define T1_CTXNO_ZC 0
+#define T1_CTXNO_SC (T1_CTXNO_ZC+T1_NUMCTXS_ZC)
+#define T1_CTXNO_MAG (T1_CTXNO_SC+T1_NUMCTXS_SC)
+#define T1_CTXNO_AGG (T1_CTXNO_MAG+T1_NUMCTXS_MAG)
+#define T1_CTXNO_UNI (T1_CTXNO_AGG+T1_NUMCTXS_AGG)
+#define T1_NUMCTXS (T1_CTXNO_UNI+T1_NUMCTXS_UNI)
+
+#define T1_NMSEDEC_FRACBITS (T1_NMSEDEC_BITS-1)
+
+#define T1_TYPE_MQ 0	/**< Normal coding using entropy coder */
+#define T1_TYPE_RAW 1	/**< No encoding the information is store under raw format in codestream (mode switch RAW)*/
+
+/* ----------------------------------------------------------------------- */
+
+typedef OPJ_INT16 opj_flag_t;
+
+/**
+Tier-1 coding (coding of code-block coefficients)
+*/
+typedef struct opj_t1 {
+
+	/** MQC component */
+	opj_mqc_t *mqc;
+	/** RAW component */
+	opj_raw_t *raw;
+
+    OPJ_INT32 *data;
+	opj_flag_t *flags;
+	OPJ_UINT32 w;
+	OPJ_UINT32 h;
+	OPJ_UINT32 datasize;
+	OPJ_UINT32 flagssize;
+	OPJ_UINT32 flags_stride;
+} opj_t1_t;
+
+#define MACRO_t1_flags(x,y) t1->flags[((x)*(t1->flags_stride))+(y)]
+
+/** @name Exported functions */
+/*@{*/
+/* ----------------------------------------------------------------------- */
+
+/**
+Encode the code-blocks of a tile
+ at param t1 T1 handle
+ at param tile The tile to encode
+ at param tcp Tile coding parameters
+ at param mct_norms  FIXME DOC
+*/
+OPJ_BOOL opj_t1_encode_cblks(   opj_t1_t *t1,
+                                opj_tcd_tile_t *tile,
+                                opj_tcp_t *tcp,
+                                const OPJ_FLOAT64 * mct_norms);
+
+/**
+Decode the code-blocks of a tile
+ at param t1 T1 handle
+ at param tilec The tile to decode
+ at param tccp Tile coding parameters
+*/
+OPJ_BOOL opj_t1_decode_cblks(   opj_t1_t* t1,
+                                opj_tcd_tilecomp_t* tilec,
+                                opj_tccp_t* tccp);
+
+
+
+/**
+ * Creates a new Tier 1 handle
+ * and initializes the look-up tables of the Tier-1 coder/decoder
+ * @return a new T1 handle if successful, returns NULL otherwise
+*/
+opj_t1_t* opj_t1_create(void);
+
+/**
+ * Destroys a previously created T1 handle
+ *
+ * @param p_t1 Tier 1 handle to destroy
+*/
+void opj_t1_destroy(opj_t1_t *p_t1);
+/* ----------------------------------------------------------------------- */
+/*@}*/
+
+/*@}*/
+
+#endif /* __T1_H */
diff --git a/Source/LibOpenJPEG/t1_generate_luts.c b/Source/LibOpenJPEG/t1_generate_luts.c
index 3988041..b2944d8 100644
--- a/Source/LibOpenJPEG/t1_generate_luts.c
+++ b/Source/LibOpenJPEG/t1_generate_luts.c
@@ -31,7 +31,6 @@
  */
 
 #include "opj_includes.h"
-#include <math.h>
 
 static int t1_init_ctxno_zc(int f, int orient) {
 	int h, v, d, n, t, hv;
@@ -109,16 +108,16 @@ static int t1_init_ctxno_sc(int f) {
 	int hc, vc, n;
 	n = 0;
 
-	hc = int_min(((f & (T1_SIG_E | T1_SGN_E)) ==
+	hc = opj_int_min(((f & (T1_SIG_E | T1_SGN_E)) ==
 				T1_SIG_E) + ((f & (T1_SIG_W | T1_SGN_W)) == T1_SIG_W),
-			1) - int_min(((f & (T1_SIG_E | T1_SGN_E)) ==
+			1) - opj_int_min(((f & (T1_SIG_E | T1_SGN_E)) ==
 					(T1_SIG_E | T1_SGN_E)) +
 				((f & (T1_SIG_W | T1_SGN_W)) ==
 				 (T1_SIG_W | T1_SGN_W)), 1);
 
-	vc = int_min(((f & (T1_SIG_N | T1_SGN_N)) ==
+	vc = opj_int_min(((f & (T1_SIG_N | T1_SGN_N)) ==
 				T1_SIG_N) + ((f & (T1_SIG_S | T1_SGN_S)) == T1_SIG_S),
-			1) - int_min(((f & (T1_SIG_N | T1_SGN_N)) ==
+			1) - opj_int_min(((f & (T1_SIG_N | T1_SGN_N)) ==
 					(T1_SIG_N | T1_SGN_N)) +
 				((f & (T1_SIG_S | T1_SGN_S)) ==
 				 (T1_SIG_S | T1_SGN_S)), 1);
@@ -149,16 +148,16 @@ static int t1_init_ctxno_sc(int f) {
 static int t1_init_spb(int f) {
 	int hc, vc, n;
 
-	hc = int_min(((f & (T1_SIG_E | T1_SGN_E)) ==
+	hc = opj_int_min(((f & (T1_SIG_E | T1_SGN_E)) ==
 				T1_SIG_E) + ((f & (T1_SIG_W | T1_SGN_W)) == T1_SIG_W),
-			1) - int_min(((f & (T1_SIG_E | T1_SGN_E)) ==
+			1) - opj_int_min(((f & (T1_SIG_E | T1_SGN_E)) ==
 					(T1_SIG_E | T1_SGN_E)) +
 				((f & (T1_SIG_W | T1_SGN_W)) ==
 				 (T1_SIG_W | T1_SGN_W)), 1);
 
-	vc = int_min(((f & (T1_SIG_N | T1_SGN_N)) ==
+	vc = opj_int_min(((f & (T1_SIG_N | T1_SGN_N)) ==
 				T1_SIG_N) + ((f & (T1_SIG_S | T1_SGN_S)) == T1_SIG_S),
-			1) - int_min(((f & (T1_SIG_N | T1_SGN_N)) ==
+			1) - opj_int_min(((f & (T1_SIG_N | T1_SGN_N)) ==
 					(T1_SIG_N | T1_SGN_N)) +
 				((f & (T1_SIG_S | T1_SGN_S)) ==
 				 (T1_SIG_S | T1_SGN_S)), 1);
@@ -171,7 +170,7 @@ static int t1_init_spb(int f) {
 	return n;
 }
 
-void dump_array16(int array[],int size){
+static void dump_array16(int array[],int size){
 	int i;
 	--size;
 	for (i = 0; i < size; ++i) {
@@ -182,7 +181,8 @@ void dump_array16(int array[],int size){
 	printf("0x%04x\n};\n\n", array[size]);
 }
 
-int main(){
+int main(int argc, char **argv)
+{
 	int i, j;
 	double u, v, t;
 
@@ -191,10 +191,11 @@ int main(){
 	int lut_nmsedec_sig0[1 << T1_NMSEDEC_BITS];
 	int lut_nmsedec_ref[1 << T1_NMSEDEC_BITS];
 	int lut_nmsedec_ref0[1 << T1_NMSEDEC_BITS];
+  (void)argc; (void)argv;
 
 	printf("/* This file was automatically generated by t1_generate_luts.c */\n\n");
 
-	// lut_ctxno_zc
+	/* lut_ctxno_zc */
 	for (j = 0; j < 4; ++j) {
 		for (i = 0; i < 256; ++i) {
 			int orient = j;
@@ -207,7 +208,7 @@ int main(){
 		}
 	}
 
-	printf("static char lut_ctxno_zc[1024] = {\n  ");
+	printf("static OPJ_BYTE lut_ctxno_zc[1024] = {\n  ");
 	for (i = 0; i < 1023; ++i) {
 		printf("%i, ", lut_ctxno_zc[i]);
 		if(!((i+1)&0x1f))
@@ -215,8 +216,8 @@ int main(){
 	}
 	printf("%i\n};\n\n", lut_ctxno_zc[1023]);
 
-	// lut_ctxno_sc
-	printf("static char lut_ctxno_sc[256] = {\n  ");
+	/* lut_ctxno_sc */
+	printf("static OPJ_BYTE lut_ctxno_sc[256] = {\n  ");
 	for (i = 0; i < 255; ++i) {
 		printf("0x%x, ", t1_init_ctxno_sc(i << 4));
 		if(!((i+1)&0xf))
@@ -224,8 +225,8 @@ int main(){
 	}
 	printf("0x%x\n};\n\n", t1_init_ctxno_sc(255 << 4));
 
-	// lut_spb
-	printf("static char lut_spb[256] = {\n  ");
+	/* lut_spb */
+	printf("static OPJ_BYTE lut_spb[256] = {\n  ");
 	for (i = 0; i < 255; ++i) {
 		printf("%i, ", t1_init_spb(i << 4));
 		if(!((i+1)&0x1f))
@@ -240,10 +241,10 @@ int main(){
 		u = t;
 		v = t - 1.5;
 		lut_nmsedec_sig[i] = 
-			int_max(0, 
+			opj_int_max(0, 
 					(int) (floor((u * u - v * v) * pow(2, T1_NMSEDEC_FRACBITS) + 0.5) / pow(2, T1_NMSEDEC_FRACBITS) * 8192.0));
 		lut_nmsedec_sig0[i] =
-			int_max(0,
+			opj_int_max(0,
 					(int) (floor((u * u) * pow(2, T1_NMSEDEC_FRACBITS) + 0.5) / pow(2, T1_NMSEDEC_FRACBITS) * 8192.0));
 		u = t - 1.0;
 		if (i & (1 << (T1_NMSEDEC_BITS - 1))) {
@@ -252,23 +253,23 @@ int main(){
 			v = t - 0.5;
 		}
 		lut_nmsedec_ref[i] =
-			int_max(0,
+			opj_int_max(0,
 					(int) (floor((u * u - v * v) * pow(2, T1_NMSEDEC_FRACBITS) + 0.5) / pow(2, T1_NMSEDEC_FRACBITS) * 8192.0));
 		lut_nmsedec_ref0[i] =
-			int_max(0,
+			opj_int_max(0,
 					(int) (floor((u * u) * pow(2, T1_NMSEDEC_FRACBITS) + 0.5) / pow(2, T1_NMSEDEC_FRACBITS) * 8192.0));
 	}
 
-	printf("static short lut_nmsedec_sig[1 << T1_NMSEDEC_BITS] = {\n  ");
+	printf("static OPJ_INT16 lut_nmsedec_sig[1 << T1_NMSEDEC_BITS] = {\n  ");
 	dump_array16(lut_nmsedec_sig, 1 << T1_NMSEDEC_BITS);
 
-	printf("static short lut_nmsedec_sig0[1 << T1_NMSEDEC_BITS] = {\n  ");
+	printf("static OPJ_INT16 lut_nmsedec_sig0[1 << T1_NMSEDEC_BITS] = {\n  ");
 	dump_array16(lut_nmsedec_sig0, 1 << T1_NMSEDEC_BITS);
 
-	printf("static short lut_nmsedec_ref[1 << T1_NMSEDEC_BITS] = {\n  ");
+	printf("static OPJ_INT16 lut_nmsedec_ref[1 << T1_NMSEDEC_BITS] = {\n  ");
 	dump_array16(lut_nmsedec_ref, 1 << T1_NMSEDEC_BITS);
 
-	printf("static short lut_nmsedec_ref0[1 << T1_NMSEDEC_BITS] = {\n  ");
+	printf("static OPJ_INT16 lut_nmsedec_ref0[1 << T1_NMSEDEC_BITS] = {\n  ");
 	dump_array16(lut_nmsedec_ref0, 1 << T1_NMSEDEC_BITS);
 
 	return 0;
diff --git a/Source/LibOpenJPEG/t1_luts.h b/Source/LibOpenJPEG/t1_luts.h
index e5e33f6..37776b6 100644
--- a/Source/LibOpenJPEG/t1_luts.h
+++ b/Source/LibOpenJPEG/t1_luts.h
@@ -1,6 +1,6 @@
 /* This file was automatically generated by t1_generate_luts.c */
 
-static char lut_ctxno_zc[1024] = {
+static OPJ_BYTE lut_ctxno_zc[1024] = {
   0, 1, 1, 2, 1, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 
   5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
   3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
@@ -35,7 +35,7 @@ static char lut_ctxno_zc[1024] = {
   2, 5, 5, 7, 5, 7, 7, 8, 5, 7, 7, 8, 7, 8, 8, 8, 2, 5, 5, 7, 5, 7, 7, 8, 5, 7, 7, 8, 7, 8, 8, 8
 };
 
-static char lut_ctxno_sc[256] = {
+static OPJ_BYTE lut_ctxno_sc[256] = {
   0x9, 0xa, 0xc, 0xd, 0xa, 0xa, 0xd, 0xd, 0xc, 0xd, 0xc, 0xd, 0xd, 0xd, 0xd, 0xd, 
   0x9, 0xa, 0xc, 0xb, 0xa, 0x9, 0xd, 0xc, 0xc, 0xb, 0xc, 0xb, 0xd, 0xc, 0xd, 0xc, 
   0x9, 0xa, 0xc, 0xb, 0xa, 0xa, 0xb, 0xb, 0xc, 0xd, 0x9, 0xa, 0xd, 0xd, 0xa, 0xa, 
@@ -54,7 +54,7 @@ static char lut_ctxno_sc[256] = {
   0x9, 0xa, 0xc, 0xd, 0xa, 0xa, 0xd, 0xd, 0xc, 0xd, 0xc, 0xd, 0xd, 0xd, 0xd, 0xd
 };
 
-static char lut_spb[256] = {
+static OPJ_BYTE lut_spb[256] = {
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
   0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 
   0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
@@ -65,7 +65,7 @@ static char lut_spb[256] = {
   0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
 };
 
-static short lut_nmsedec_sig[1 << T1_NMSEDEC_BITS] = {
+static OPJ_INT16 lut_nmsedec_sig[1 << T1_NMSEDEC_BITS] = {
   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
@@ -84,7 +84,7 @@ static short lut_nmsedec_sig[1 << T1_NMSEDEC_BITS] = {
   0x6c00, 0x6d80, 0x6f00, 0x7080, 0x7200, 0x7380, 0x7500, 0x7680
 };
 
-static short lut_nmsedec_sig0[1 << T1_NMSEDEC_BITS] = {
+static OPJ_INT16 lut_nmsedec_sig0[1 << T1_NMSEDEC_BITS] = {
   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0080, 0x0080, 
   0x0080, 0x0080, 0x0100, 0x0100, 0x0100, 0x0180, 0x0180, 0x0200, 
   0x0200, 0x0280, 0x0280, 0x0300, 0x0300, 0x0380, 0x0400, 0x0400, 
@@ -103,7 +103,7 @@ static short lut_nmsedec_sig0[1 << T1_NMSEDEC_BITS] = {
   0x7080, 0x7280, 0x7480, 0x7600, 0x7800, 0x7a00, 0x7c00, 0x7e00
 };
 
-static short lut_nmsedec_ref[1 << T1_NMSEDEC_BITS] = {
+static OPJ_INT16 lut_nmsedec_ref[1 << T1_NMSEDEC_BITS] = {
   0x1800, 0x1780, 0x1700, 0x1680, 0x1600, 0x1580, 0x1500, 0x1480, 
   0x1400, 0x1380, 0x1300, 0x1280, 0x1200, 0x1180, 0x1100, 0x1080, 
   0x1000, 0x0f80, 0x0f00, 0x0e80, 0x0e00, 0x0d80, 0x0d00, 0x0c80, 
@@ -122,7 +122,7 @@ static short lut_nmsedec_ref[1 << T1_NMSEDEC_BITS] = {
   0x1400, 0x1480, 0x1500, 0x1580, 0x1600, 0x1680, 0x1700, 0x1780
 };
 
-static short lut_nmsedec_ref0[1 << T1_NMSEDEC_BITS] = {
+static OPJ_INT16 lut_nmsedec_ref0[1 << T1_NMSEDEC_BITS] = {
   0x2000, 0x1f00, 0x1e00, 0x1d00, 0x1c00, 0x1b00, 0x1a80, 0x1980, 
   0x1880, 0x1780, 0x1700, 0x1600, 0x1500, 0x1480, 0x1380, 0x1300, 
   0x1200, 0x1180, 0x1080, 0x1000, 0x0f00, 0x0e80, 0x0e00, 0x0d00, 
diff --git a/Source/LibOpenJPEG/t2.c b/Source/LibOpenJPEG/t2.c
index fe8720b..82d7a78 100644
--- a/Source/LibOpenJPEG/t2.c
+++ b/Source/LibOpenJPEG/t2.c
@@ -1,822 +1,1334 @@
-/*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
- * Copyright (c) 2001-2003, David Janssens
- * Copyright (c) 2002-2003, Yannick Verschueren
- * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "opj_includes.h"
-
-/** @defgroup T2 T2 - Implementation of a tier-2 coding */
-/*@{*/
-
-/** @name Local static functions */
-/*@{*/
-
-static void t2_putcommacode(opj_bio_t *bio, int n);
-static int t2_getcommacode(opj_bio_t *bio);
-/**
-Variable length code for signalling delta Zil (truncation point)
- at param bio Bit Input/Output component
- at param n delta Zil
-*/
-static void t2_putnumpasses(opj_bio_t *bio, int n);
-static int t2_getnumpasses(opj_bio_t *bio);
-/**
-Encode a packet of a tile to a destination buffer
- at param tile Tile for which to write the packets
- at param tcp Tile coding parameters
- at param pi Packet identity
- at param dest Destination buffer
- at param len Length of the destination buffer
- at param cstr_info Codestream information structure 
- at param tileno Number of the tile encoded
- at return 
-*/
-static int t2_encode_packet(opj_tcd_tile_t *tile, opj_tcp_t *tcp, opj_pi_iterator_t *pi, unsigned char *dest, int len, opj_codestream_info_t *cstr_info, int tileno);
-/**
- at param cblk
- at param index
- at param cblksty
- at param first
-*/
-static opj_bool t2_init_seg(opj_tcd_cblk_dec_t* cblk, int index, int cblksty, int first);
-/**
-Decode a packet of a tile from a source buffer
- at param t2 T2 handle
- at param src Source buffer
- at param len Length of the source buffer
- at param tile Tile for which to write the packets
- at param tcp Tile coding parameters
- at param pi Packet identity
- at param pack_info Packet information
- at return 
-*/
-static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_tile_t *tile, 
-														opj_tcp_t *tcp, opj_pi_iterator_t *pi, opj_packet_info_t *pack_info);
-
-/*@}*/
-
-/*@}*/
-
-/* ----------------------------------------------------------------------- */
-
-/* #define RESTART 0x04 */
-
-static void t2_putcommacode(opj_bio_t *bio, int n) {
-	while (--n >= 0) {
-		bio_write(bio, 1, 1);
-	}
-	bio_write(bio, 0, 1);
-}
-
-static int t2_getcommacode(opj_bio_t *bio) {
-	int n;
-	for (n = 0; bio_read(bio, 1); n++) {
-		;
-	}
-	return n;
-}
-
-static void t2_putnumpasses(opj_bio_t *bio, int n) {
-	if (n == 1) {
-		bio_write(bio, 0, 1);
-	} else if (n == 2) {
-		bio_write(bio, 2, 2);
-	} else if (n <= 5) {
-		bio_write(bio, 0xc | (n - 3), 4);
-	} else if (n <= 36) {
-		bio_write(bio, 0x1e0 | (n - 6), 9);
-	} else if (n <= 164) {
-		bio_write(bio, 0xff80 | (n - 37), 16);
-	}
-}
-
-static int t2_getnumpasses(opj_bio_t *bio) {
-	int n;
-	if (!bio_read(bio, 1))
-		return 1;
-	if (!bio_read(bio, 1))
-		return 2;
-	if ((n = bio_read(bio, 2)) != 3)
-		return (3 + n);
-	if ((n = bio_read(bio, 5)) != 31)
-		return (6 + n);
-	return (37 + bio_read(bio, 7));
-}
-
-static int t2_encode_packet(opj_tcd_tile_t * tile, opj_tcp_t * tcp, opj_pi_iterator_t *pi, unsigned char *dest, int length, opj_codestream_info_t *cstr_info, int tileno) {
-	int bandno, cblkno;
-	unsigned char *c = dest;
-
-	int compno = pi->compno;	/* component value */
-	int resno  = pi->resno;		/* resolution level value */
-	int precno = pi->precno;	/* precinct value */
-	int layno  = pi->layno;		/* quality layer value */
-
-	opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
-	opj_tcd_resolution_t *res = &tilec->resolutions[resno];
-	
-	opj_bio_t *bio = NULL;	/* BIO component */
-	
-	/* <SOP 0xff91> */
-	if (tcp->csty & J2K_CP_CSTY_SOP) {
-		c[0] = 255;
-		c[1] = 145;
-		c[2] = 0;
-		c[3] = 4;
-		c[4] = (unsigned char)((tile->packno % 65536) / 256);
-		c[5] = (unsigned char)((tile->packno % 65536) % 256);
-		c += 6;
-	}
-	/* </SOP> */
-	
-	if (!layno) {
-		for (bandno = 0; bandno < res->numbands; bandno++) {
-			opj_tcd_band_t *band = &res->bands[bandno];
-			opj_tcd_precinct_t *prc = &band->precincts[precno];
-			tgt_reset(prc->incltree);
-			tgt_reset(prc->imsbtree);
-			for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
-				opj_tcd_cblk_enc_t* cblk = &prc->cblks.enc[cblkno];
-				cblk->numpasses = 0;
-				tgt_setvalue(prc->imsbtree, cblkno, band->numbps - cblk->numbps);
-			}
-		}
-	}
-	
-	bio = bio_create();
-	bio_init_enc(bio, c, length);
-	bio_write(bio, 1, 1);		/* Empty header bit */
-	
-	/* Writing Packet header */
-	for (bandno = 0; bandno < res->numbands; bandno++) {
-		opj_tcd_band_t *band = &res->bands[bandno];
-		opj_tcd_precinct_t *prc = &band->precincts[precno];
-		for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
-			opj_tcd_cblk_enc_t* cblk = &prc->cblks.enc[cblkno];
-			opj_tcd_layer_t *layer = &cblk->layers[layno];
-			if (!cblk->numpasses && layer->numpasses) {
-				tgt_setvalue(prc->incltree, cblkno, layno);
-			}
-		}
-		for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
-			opj_tcd_cblk_enc_t* cblk = &prc->cblks.enc[cblkno];
-			opj_tcd_layer_t *layer = &cblk->layers[layno];
-			int increment = 0;
-			int nump = 0;
-			int len = 0, passno;
-			/* cblk inclusion bits */
-			if (!cblk->numpasses) {
-				tgt_encode(bio, prc->incltree, cblkno, layno + 1);
-			} else {
-				bio_write(bio, layer->numpasses != 0, 1);
-			}
-			/* if cblk not included, go to the next cblk  */
-			if (!layer->numpasses) {
-				continue;
-			}
-			/* if first instance of cblk --> zero bit-planes information */
-			if (!cblk->numpasses) {
-				cblk->numlenbits = 3;
-				tgt_encode(bio, prc->imsbtree, cblkno, 999);
-			}
-			/* number of coding passes included */
-			t2_putnumpasses(bio, layer->numpasses);
-			
-			/* computation of the increase of the length indicator and insertion in the header     */
-			for (passno = cblk->numpasses; passno < cblk->numpasses + layer->numpasses; passno++) {
-				opj_tcd_pass_t *pass = &cblk->passes[passno];
-				nump++;
-				len += pass->len;
-				if (pass->term || passno == (cblk->numpasses + layer->numpasses) - 1) {
-					increment = int_max(increment, int_floorlog2(len) + 1 - (cblk->numlenbits + int_floorlog2(nump)));
-					len = 0;
-					nump = 0;
-				}
-			}
-			t2_putcommacode(bio, increment);
-
-			/* computation of the new Length indicator */
-			cblk->numlenbits += increment;
-
-			/* insertion of the codeword segment length */
-			for (passno = cblk->numpasses; passno < cblk->numpasses + layer->numpasses; passno++) {
-				opj_tcd_pass_t *pass = &cblk->passes[passno];
-				nump++;
-				len += pass->len;
-				if (pass->term || passno == (cblk->numpasses + layer->numpasses) - 1) {
-					bio_write(bio, len, cblk->numlenbits + int_floorlog2(nump));
-					len = 0;
-					nump = 0;
-				}
-			}
-		}
-	}
-
-	if (bio_flush(bio)) {
-		bio_destroy(bio);
-		return -999;		/* modified to eliminate longjmp !! */
-	}
-
-	c += bio_numbytes(bio);
-	bio_destroy(bio);
-	
-	/* <EPH 0xff92> */
-	if (tcp->csty & J2K_CP_CSTY_EPH) {
-		c[0] = 255;
-		c[1] = 146;
-		c += 2;
-	}
-	/* </EPH> */
-
-	/* << INDEX */
-	/* End of packet header position. Currently only represents the distance to start of packet
-	// Will be updated later by incrementing with packet start value */
-	if(cstr_info && cstr_info->index_write) {
-		opj_packet_info_t *info_PK = &cstr_info->tile[tileno].packet[cstr_info->packno];
-		info_PK->end_ph_pos = (int)(c - dest);
-	}
-	/* INDEX >> */
-	
-	/* Writing the packet body */
-	
-	for (bandno = 0; bandno < res->numbands; bandno++) {
-		opj_tcd_band_t *band = &res->bands[bandno];
-		opj_tcd_precinct_t *prc = &band->precincts[precno];
-		for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
-			opj_tcd_cblk_enc_t* cblk = &prc->cblks.enc[cblkno];
-			opj_tcd_layer_t *layer = &cblk->layers[layno];
-			if (!layer->numpasses) {
-				continue;
-			}
-			if (c + layer->len > dest + length) {
-				return -999;
-			}
-			
-			memcpy(c, layer->data, layer->len);
-			cblk->numpasses += layer->numpasses;
-			c += layer->len;
-			/* << INDEX */ 
-			if(cstr_info && cstr_info->index_write) {
-				opj_packet_info_t *info_PK = &cstr_info->tile[tileno].packet[cstr_info->packno];
-				info_PK->disto += layer->disto;
-				if (cstr_info->D_max < info_PK->disto) {
-					cstr_info->D_max = info_PK->disto;
-				}
-			}
-			/* INDEX >> */
-		}
-	}
-	
-	return (c - dest);
-}
-
-static opj_bool t2_init_seg(opj_tcd_cblk_dec_t* cblk, int index, int cblksty, int first) {
-	opj_tcd_seg_t* seg;
-    opj_tcd_seg_t* segs;
-    segs = (opj_tcd_seg_t*) opj_realloc(cblk->segs, (index + 1) * sizeof(opj_tcd_seg_t));
-
-    if (segs == NULL)
-    {
-        return OPJ_FALSE;
-    }
-    cblk->segs = segs;
-
-	seg = &cblk->segs[index];
-	seg->data = NULL;
-	seg->dataindex = 0;
-	seg->numpasses = 0;
-	seg->len = 0;
-	if (cblksty & J2K_CCP_CBLKSTY_TERMALL) {
-		seg->maxpasses = 1;
-	}
-	else if (cblksty & J2K_CCP_CBLKSTY_LAZY) {
-		if (first) {
-			seg->maxpasses = 10;
-		} else {
-			seg->maxpasses = (((seg - 1)->maxpasses == 1) || ((seg - 1)->maxpasses == 10)) ? 2 : 1;
-		}
-	} else {
-		seg->maxpasses = 109;
-	}
-
-    return OPJ_TRUE;
-}
-
-static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_tile_t *tile, 
-														opj_tcp_t *tcp, opj_pi_iterator_t *pi, opj_packet_info_t *pack_info) {
-	int bandno, cblkno;
-	unsigned char *c = src;
-
-	opj_cp_t *cp = t2->cp;
-
-	int compno = pi->compno;	/* component value */
-	int resno  = pi->resno;		/* resolution level value */
-	int precno = pi->precno;	/* precinct value */
-	int layno  = pi->layno;		/* quality layer value */
-
-	opj_tcd_resolution_t* res = &tile->comps[compno].resolutions[resno];
-
-	unsigned char *hd = NULL;
-	int present;
-	
-	opj_bio_t *bio = NULL;	/* BIO component */
-	
-	if (layno == 0) {
-		for (bandno = 0; bandno < res->numbands; bandno++) {
-			opj_tcd_band_t *band = &res->bands[bandno];
-			opj_tcd_precinct_t *prc = &band->precincts[precno];
-			
-			if ((band->x1-band->x0 == 0)||(band->y1-band->y0 == 0)) continue;
-			
-			tgt_reset(prc->incltree);
-			tgt_reset(prc->imsbtree);
-			for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
-				opj_tcd_cblk_dec_t* cblk = &prc->cblks.dec[cblkno];
-				cblk->numsegs = 0;
-			}
-		}
-	}
-	
-	/* SOP markers */
-	
-	if (tcp->csty & J2K_CP_CSTY_SOP) {
-		if ((*c) != 0xff || (*(c + 1) != 0x91)) {
-			opj_event_msg(t2->cinfo, EVT_WARNING, "Expected SOP marker\n");
-		} else {
-			c += 6;
-		}
-		
-		/** TODO : check the Nsop value */
-	}
-	
-	/* 
-	When the marker PPT/PPM is used the packet header are store in PPT/PPM marker
-	This part deal with this caracteristic
-	step 1: Read packet header in the saved structure
-	step 2: Return to codestream for decoding 
-	*/
-
-	bio = bio_create();
-	
-	if (cp->ppm == 1) {		/* PPM */
-		hd = cp->ppm_data;
-		bio_init_dec(bio, hd, cp->ppm_len);
-	} else if (tcp->ppt == 1) {	/* PPT */
-		hd = tcp->ppt_data;
-		bio_init_dec(bio, hd, tcp->ppt_len);
-	} else {			/* Normal Case */
-		hd = c;
-		bio_init_dec(bio, hd, src+len-hd);
-	}
-	
-	present = bio_read(bio, 1);
-	
-	if (!present) {
-		bio_inalign(bio);
-		hd += bio_numbytes(bio);
-		bio_destroy(bio);
-		
-		/* EPH markers */
-		
-		if (tcp->csty & J2K_CP_CSTY_EPH) {
-			if ((*hd) != 0xff || (*(hd + 1) != 0x92)) {
-				printf("Error : expected EPH marker\n");
-			} else {
-				hd += 2;
-			}
-		}
-
-		/* << INDEX */
-		/* End of packet header position. Currently only represents the distance to start of packet
-		// Will be updated later by incrementing with packet start value*/
-		if(pack_info) {
-			pack_info->end_ph_pos = (int)(c - src);
-		}
-		/* INDEX >> */
-		
-		if (cp->ppm == 1) {		/* PPM case */
-			cp->ppm_len += cp->ppm_data-hd;
-			cp->ppm_data = hd;
-			return (c - src);
-		}
-		if (tcp->ppt == 1) {	/* PPT case */
-			tcp->ppt_len+=tcp->ppt_data-hd;
-			tcp->ppt_data = hd;
-			return (c - src);
-		}
-		
-		return (hd - src);
-	}
-	
-	for (bandno = 0; bandno < res->numbands; bandno++) {
-		opj_tcd_band_t *band = &res->bands[bandno];
-		opj_tcd_precinct_t *prc = &band->precincts[precno];
-		
-		if ((band->x1-band->x0 == 0)||(band->y1-band->y0 == 0)) continue;
-		
-		for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
-			int included, increment, n, segno;
-			opj_tcd_cblk_dec_t* cblk = &prc->cblks.dec[cblkno];
-			/* if cblk not yet included before --> inclusion tagtree */
-			if (!cblk->numsegs) {
-				included = tgt_decode(bio, prc->incltree, cblkno, layno + 1);
-				/* else one bit */
-			} else {
-				included = bio_read(bio, 1);
-			}
-			/* if cblk not included */
-			if (!included) {
-				cblk->numnewpasses = 0;
-				continue;
-			}
-			/* if cblk not yet included --> zero-bitplane tagtree */
-			if (!cblk->numsegs) {
-				int i, numimsbs;
-				for (i = 0; !tgt_decode(bio, prc->imsbtree, cblkno, i); i++) {
-					;
-				}
-				numimsbs = i - 1;
-				cblk->numbps = band->numbps - numimsbs;
-				cblk->numlenbits = 3;
-			}
-			/* number of coding passes */
-			cblk->numnewpasses = t2_getnumpasses(bio);
-			increment = t2_getcommacode(bio);
-			/* length indicator increment */
-			cblk->numlenbits += increment;
-			segno = 0;
-			if (!cblk->numsegs) {
-                if (!t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 1))
-                {
-                    opj_event_msg(t2->cinfo, EVT_ERROR, "Out of memory\n");
-                    bio_destroy(bio);
-                    return -999;
-                }
-			} else {
-				segno = cblk->numsegs - 1;
-				if (cblk->segs[segno].numpasses == cblk->segs[segno].maxpasses) {
-					++segno;
-                    if (!t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 0))
-                    {
-                        opj_event_msg(t2->cinfo, EVT_ERROR, "Out of memory\n");
-                        bio_destroy(bio);
-                        return -999;
-                    }
-				}
-			}
-			n = cblk->numnewpasses;
-			
-			do {
-				cblk->segs[segno].numnewpasses = int_min(cblk->segs[segno].maxpasses - cblk->segs[segno].numpasses, n);
-				cblk->segs[segno].newlen = bio_read(bio, cblk->numlenbits + int_floorlog2(cblk->segs[segno].numnewpasses));
-				n -= cblk->segs[segno].numnewpasses;
-				if (n > 0) {
-					++segno;
-                    if (!t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 0))
-                    {
-                        opj_event_msg(t2->cinfo, EVT_ERROR, "Out of memory\n");
-                        bio_destroy(bio);
-                        return -999;
-                    }
-				}
-			} while (n > 0);
-		}
-	}
-	
-	if (bio_inalign(bio)) {
-		bio_destroy(bio);
-		return -999;
-	}
-	
-	hd += bio_numbytes(bio);
-	bio_destroy(bio);
-	
-	/* EPH markers */
-	if (tcp->csty & J2K_CP_CSTY_EPH) {
-		if ((*hd) != 0xff || (*(hd + 1) != 0x92)) {
-			opj_event_msg(t2->cinfo, EVT_ERROR, "Expected EPH marker\n");
-			return -999;
-		} else {
-			hd += 2;
-		}
-	}
-
-	/* << INDEX */
-	/* End of packet header position. Currently only represents the distance to start of packet
-	// Will be updated later by incrementing with packet start value*/
-	if(pack_info) {
-		pack_info->end_ph_pos = (int)(hd - src);
-	}
-	/* INDEX >> */
-	
-	if (cp->ppm==1) {
-		cp->ppm_len+=cp->ppm_data-hd;
-		cp->ppm_data = hd;
-	} else if (tcp->ppt == 1) {
-		tcp->ppt_len+=tcp->ppt_data-hd;
-		tcp->ppt_data = hd;
-	} else {
-		c=hd;
-	}
-	
-	for (bandno = 0; bandno < res->numbands; bandno++) {
-		opj_tcd_band_t *band = &res->bands[bandno];
-		opj_tcd_precinct_t *prc = &band->precincts[precno];
-		
-		if ((band->x1-band->x0 == 0)||(band->y1-band->y0 == 0)) continue;
-		
-		for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
-			opj_tcd_cblk_dec_t* cblk = &prc->cblks.dec[cblkno];
-			opj_tcd_seg_t *seg = NULL;
-			if (!cblk->numnewpasses)
-				continue;
-			if (!cblk->numsegs) {
-				seg = &cblk->segs[0];
-				cblk->numsegs++;
-				cblk->len = 0;
-			} else {
-				seg = &cblk->segs[cblk->numsegs - 1];
-				if (seg->numpasses == seg->maxpasses) {
-					seg++;
-					cblk->numsegs++;
-				}
-			}
-			
-			do {
-				if (c + seg->newlen > src + len) {
-					return -999;
-				}
-
-#ifdef USE_JPWL
-			/* we need here a j2k handle to verify if making a check to
-			the validity of cblocks parameters is selected from user (-W) */
-
-				/* let's check that we are not exceeding */
-				if ((cblk->len + seg->newlen) > 8192) {
-					opj_event_msg(t2->cinfo, EVT_WARNING,
-						"JPWL: segment too long (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n",
-						seg->newlen, cblkno, precno, bandno, resno, compno);
-					if (!JPWL_ASSUME) {
-						opj_event_msg(t2->cinfo, EVT_ERROR, "JPWL: giving up\n");
-						return -999;
-					}
-					seg->newlen = 8192 - cblk->len;
-					opj_event_msg(t2->cinfo, EVT_WARNING, "      - truncating segment to %d\n", seg->newlen);
-					break;
-				};
-
-#endif /* USE_JPWL */
-				
-				cblk->data = (unsigned char*) opj_realloc(cblk->data, (cblk->len + seg->newlen) * sizeof(unsigned char));
-				memcpy(cblk->data + cblk->len, c, seg->newlen);
-				if (seg->numpasses == 0) {
-					seg->data = &cblk->data;
-					seg->dataindex = cblk->len;
-				}
-				c += seg->newlen;
-				cblk->len += seg->newlen;
-				seg->len += seg->newlen;
-				seg->numpasses += seg->numnewpasses;
-				cblk->numnewpasses -= seg->numnewpasses;
-				if (cblk->numnewpasses > 0) {
-					seg++;
-					cblk->numsegs++;
-				}
-			} while (cblk->numnewpasses > 0);
-		}
-	}
-	
-	return (c - src);
-}
-
-/* ----------------------------------------------------------------------- */
-
-int t2_encode_packets(opj_t2_t* t2,int tileno, opj_tcd_tile_t *tile, int maxlayers, unsigned char *dest, int len, opj_codestream_info_t *cstr_info,int tpnum, int tppos,int pino, J2K_T2_MODE t2_mode, int cur_totnum_tp){
-	unsigned char *c = dest;
-	int e = 0;
-	int compno;
-	opj_pi_iterator_t *pi = NULL;
-	int poc;
-	opj_image_t *image = t2->image;
-	opj_cp_t *cp = t2->cp;
-	opj_tcp_t *tcp = &cp->tcps[tileno];
-	int pocno = cp->cinema == CINEMA4K_24? 2: 1;
-	int maxcomp = cp->max_comp_size > 0 ? image->numcomps : 1;
-	
-	pi = pi_initialise_encode(image, cp, tileno, t2_mode);
-	if(!pi) {
-		/* TODO: throw an error */
-		return -999;
-	}
-	
-	if(t2_mode == THRESH_CALC ){ /* Calculating threshold */
-		for(compno = 0; compno < maxcomp; compno++ ){
-			for(poc = 0; poc < pocno ; poc++){
-				int comp_len = 0;
-				int tpnum = compno;
-				if (pi_create_encode(pi, cp,tileno,poc,tpnum,tppos,t2_mode,cur_totnum_tp)) {
-					opj_event_msg(t2->cinfo, EVT_ERROR, "Error initializing Packet Iterator\n");
-					pi_destroy(pi, cp, tileno);
-					return -999;
-				}
-				while (pi_next(&pi[poc])) {
-					if (pi[poc].layno < maxlayers) {
-						e = t2_encode_packet(tile, &cp->tcps[tileno], &pi[poc], c, dest + len - c, cstr_info, tileno);
-						comp_len = comp_len + e;
-						if (e == -999) {
-							break;
-						} else {
-							c += e;
-						}
-					}
-				}
-				if (e == -999) break;
-				if (cp->max_comp_size){
-					if (comp_len > cp->max_comp_size){
-						e = -999;
-						break;
-					}
-				}
-			}
-			if (e == -999)  break;
-		}
-	}else{  /* t2_mode == FINAL_PASS  */
-		pi_create_encode(pi, cp,tileno,pino,tpnum,tppos,t2_mode,cur_totnum_tp);
-		while (pi_next(&pi[pino])) {
-			if (pi[pino].layno < maxlayers) {
-				e = t2_encode_packet(tile, &cp->tcps[tileno], &pi[pino], c, dest + len - c, cstr_info, tileno);
-				if (e == -999) {
-					break;
-				} else {
-					c += e;
-				}
-				/* INDEX >> */
-				if(cstr_info) {
-					if(cstr_info->index_write) {
-						opj_tile_info_t *info_TL = &cstr_info->tile[tileno];
-						opj_packet_info_t *info_PK = &info_TL->packet[cstr_info->packno];
-						if (!cstr_info->packno) {
-							info_PK->start_pos = info_TL->end_header + 1;
-						} else {
-							info_PK->start_pos = ((cp->tp_on | tcp->POC)&& info_PK->start_pos) ? info_PK->start_pos : info_TL->packet[cstr_info->packno - 1].end_pos + 1;
-						}
-						info_PK->end_pos = info_PK->start_pos + e - 1;
-						info_PK->end_ph_pos += info_PK->start_pos - 1;	/* End of packet header which now only represents the distance 
-																														// to start of packet is incremented by value of start of packet*/
-					}
-					
-					cstr_info->packno++;
-				}
-				/* << INDEX */
-				tile->packno++;
-			}
-		}
-	}
-	
-	pi_destroy(pi, cp, tileno);
-	
-	if (e == -999) {
-		return e;
-	}
-	
-  return (c - dest);
-}
-
-int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj_tcd_tile_t *tile, opj_codestream_info_t *cstr_info) {
-	unsigned char *c = src;
-	opj_pi_iterator_t *pi;
-	int pino, e = 0;
-	int n = 0, curtp = 0;
-	int tp_start_packno;
-
-	opj_image_t *image = t2->image;
-	opj_cp_t *cp = t2->cp;
-	
-	/* create a packet iterator */
-	pi = pi_create_decode(image, cp, tileno);
-	if(!pi) {
-		/* TODO: throw an error */
-		return -999;
-	}
-
-	tp_start_packno = 0;
-	
-	for (pino = 0; pino <= cp->tcps[tileno].numpocs; pino++) {
-		while (pi_next(&pi[pino])) {
-			if ((cp->layer==0) || (cp->layer>=((pi[pino].layno)+1))) {
-				opj_packet_info_t *pack_info;
-				if (cstr_info)
-					pack_info = &cstr_info->tile[tileno].packet[cstr_info->packno];
-				else
-					pack_info = NULL;
-				e = t2_decode_packet(t2, c, src + len - c, tile, &cp->tcps[tileno], &pi[pino], pack_info);
-			} else {
-				e = 0;
-			}
-            if(e == -999)
-            {
-                pi_destroy(pi, cp, tileno);
-                return -999;
-            }
-			/* progression in resolution */
-			image->comps[pi[pino].compno].resno_decoded =	
-				(e > 0) ? 
-				int_max(pi[pino].resno, image->comps[pi[pino].compno].resno_decoded) 
-				: image->comps[pi[pino].compno].resno_decoded;
-			n++;
-
-			/* INDEX >> */
-			if(cstr_info) {
-				opj_tile_info_t *info_TL = &cstr_info->tile[tileno];
-				opj_packet_info_t *info_PK = &info_TL->packet[cstr_info->packno];
-				if (!cstr_info->packno) {
-					info_PK->start_pos = info_TL->end_header + 1;
-				} else if (info_TL->packet[cstr_info->packno-1].end_pos >= (int)cstr_info->tile[tileno].tp[curtp].tp_end_pos){ /* New tile part*/
-					info_TL->tp[curtp].tp_numpacks = cstr_info->packno - tp_start_packno; /* Number of packets in previous tile-part*/
-          info_TL->tp[curtp].tp_start_pack = tp_start_packno;
-					tp_start_packno = cstr_info->packno;
-					curtp++;
-					info_PK->start_pos = cstr_info->tile[tileno].tp[curtp].tp_end_header+1;
-				} else {
-					info_PK->start_pos = (cp->tp_on && info_PK->start_pos) ? info_PK->start_pos : info_TL->packet[cstr_info->packno - 1].end_pos + 1;
-				}
-				info_PK->end_pos = info_PK->start_pos + e - 1;
-				info_PK->end_ph_pos += info_PK->start_pos - 1;	/* End of packet header which now only represents the distance 
-																												// to start of packet is incremented by value of start of packet*/
-				cstr_info->packno++;
-			}
-			/* << INDEX */
-			
-			if (e == -999) {		/* ADD */
-				break;
-			} else {
-				c += e;
-			}			
-		}
-	}
-	/* INDEX >> */
-	if(cstr_info) {
-		cstr_info->tile[tileno].tp[curtp].tp_numpacks = cstr_info->packno - tp_start_packno; /* Number of packets in last tile-part*/
-    cstr_info->tile[tileno].tp[curtp].tp_start_pack = tp_start_packno;
-	}
-	/* << INDEX */
-
-	/* don't forget to release pi */
-	pi_destroy(pi, cp, tileno);
-	
-	if (e == -999) {
-		return e;
-	}
-	
-	return (c - src);
-}
-
-/* ----------------------------------------------------------------------- */
-
-opj_t2_t* t2_create(opj_common_ptr cinfo, opj_image_t *image, opj_cp_t *cp) {
-	/* create the tcd structure */
-	opj_t2_t *t2 = (opj_t2_t*)opj_malloc(sizeof(opj_t2_t));
-	if(!t2) return NULL;
-	t2->cinfo = cinfo;
-	t2->image = image;
-	t2->cp = cp;
-
-	return t2;
-}
-
-void t2_destroy(opj_t2_t *t2) {
-	if(t2) {
-		opj_free(t2);
-	}
-}
-
-
-
-
-
+/*
+ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2007, Professor Benoit Macq
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2008;2011-2012, Centre National d'Etudes Spatiales (CNES), France 
+ * Copyright (c) 2012, CS Systemes d'Information, France
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "opj_includes.h"
+
+/** @defgroup T2 T2 - Implementation of a tier-2 coding */
+/*@{*/
+
+/** @name Local static functions */
+/*@{*/
+
+static void opj_t2_putcommacode(opj_bio_t *bio, OPJ_INT32 n);
+
+static OPJ_UINT32 opj_t2_getcommacode(opj_bio_t *bio); 
+/**
+Variable length code for signalling delta Zil (truncation point)
+ at param bio  Bit Input/Output component
+ at param n    delta Zil
+*/
+static void opj_t2_putnumpasses(opj_bio_t *bio, OPJ_UINT32 n);
+static OPJ_UINT32 opj_t2_getnumpasses(opj_bio_t *bio);
+
+/**
+Encode a packet of a tile to a destination buffer
+ at param tileno Number of the tile encoded
+ at param tile Tile for which to write the packets
+ at param tcp Tile coding parameters
+ at param pi Packet identity
+ at param dest Destination buffer
+ at param p_data_written   FIXME DOC
+ at param len Length of the destination buffer
+ at param cstr_info Codestream information structure
+ at return
+*/
+static OPJ_BOOL opj_t2_encode_packet(   OPJ_UINT32 tileno,
+                                        opj_tcd_tile_t *tile,
+                                        opj_tcp_t *tcp,
+                                        opj_pi_iterator_t *pi,
+                                        OPJ_BYTE *dest,
+                                        OPJ_UINT32 * p_data_written,
+                                        OPJ_UINT32 len,
+                                        opj_codestream_info_t *cstr_info);
+
+/**
+Decode a packet of a tile from a source buffer
+ at param t2 T2 handle
+ at param tile Tile for which to write the packets
+ at param tcp Tile coding parameters
+ at param pi Packet identity
+ at param src Source buffer
+ at param data_read   FIXME DOC
+ at param max_length  FIXME DOC
+ at param pack_info Packet information
+
+ at return  FIXME DOC
+*/
+static OPJ_BOOL opj_t2_decode_packet(   opj_t2_t* t2,
+                                        opj_tcd_tile_t *tile,
+                                        opj_tcp_t *tcp,
+                                        opj_pi_iterator_t *pi,
+                                        OPJ_BYTE *src,
+                                        OPJ_UINT32 * data_read,
+                                        OPJ_UINT32 max_length,
+                                        opj_packet_info_t *pack_info);
+
+static OPJ_BOOL opj_t2_skip_packet( opj_t2_t* p_t2,
+                                    opj_tcd_tile_t *p_tile,
+                                    opj_tcp_t *p_tcp,
+                                    opj_pi_iterator_t *p_pi,
+                                    OPJ_BYTE *p_src,
+                                    OPJ_UINT32 * p_data_read,
+                                    OPJ_UINT32 p_max_length,
+                                    opj_packet_info_t *p_pack_info);
+
+static OPJ_BOOL opj_t2_read_packet_header(  opj_t2_t* p_t2,
+                                            opj_tcd_tile_t *p_tile,
+                                            opj_tcp_t *p_tcp,
+                                            opj_pi_iterator_t *p_pi,
+                                            OPJ_BOOL * p_is_data_present,
+                                            OPJ_BYTE *p_src_data,
+                                            OPJ_UINT32 * p_data_read,
+                                            OPJ_UINT32 p_max_length,
+                                            opj_packet_info_t *p_pack_info);
+
+static OPJ_BOOL opj_t2_read_packet_data(opj_t2_t* p_t2,
+                                        opj_tcd_tile_t *p_tile,
+                                        opj_pi_iterator_t *p_pi,
+                                        OPJ_BYTE *p_src_data,
+                                        OPJ_UINT32 * p_data_read,
+                                        OPJ_UINT32 p_max_length,
+                                        opj_packet_info_t *pack_info);
+
+static OPJ_BOOL opj_t2_skip_packet_data(opj_t2_t* p_t2,
+                                        opj_tcd_tile_t *p_tile,
+                                        opj_pi_iterator_t *p_pi,
+                                        OPJ_UINT32 * p_data_read,
+                                        OPJ_UINT32 p_max_length,
+                                        opj_packet_info_t *pack_info);
+
+/**
+ at param cblk
+ at param index
+ at param cblksty
+ at param first
+*/
+static OPJ_BOOL opj_t2_init_seg(    opj_tcd_cblk_dec_t* cblk,
+                                    OPJ_UINT32 index,
+                                    OPJ_UINT32 cblksty,
+                                    OPJ_UINT32 first);
+
+/*@}*/
+
+/*@}*/
+
+/* ----------------------------------------------------------------------- */
+
+/* #define RESTART 0x04 */
+static void opj_t2_putcommacode(opj_bio_t *bio, OPJ_INT32 n) {
+        while (--n >= 0) {
+                opj_bio_write(bio, 1, 1);
+        }
+        opj_bio_write(bio, 0, 1);
+}
+
+OPJ_UINT32 opj_t2_getcommacode(opj_bio_t *bio) 
+{
+    OPJ_UINT32 n = 0;
+    while (opj_bio_read(bio, 1)) {
+	    ++n;
+    }
+    return n;
+}
+
+void opj_t2_putnumpasses(opj_bio_t *bio, OPJ_UINT32 n) {
+        if (n == 1) {
+                opj_bio_write(bio, 0, 1);
+        } else if (n == 2) {
+                opj_bio_write(bio, 2, 2);
+        } else if (n <= 5) {
+                opj_bio_write(bio, 0xc | (n - 3), 4);
+        } else if (n <= 36) {
+                opj_bio_write(bio, 0x1e0 | (n - 6), 9);
+        } else if (n <= 164) {
+                opj_bio_write(bio, 0xff80 | (n - 37), 16);
+        }
+}
+
+OPJ_UINT32 opj_t2_getnumpasses(opj_bio_t *bio) {
+        OPJ_UINT32 n;
+        if (!opj_bio_read(bio, 1))
+                return 1;
+        if (!opj_bio_read(bio, 1))
+                return 2;
+        if ((n = opj_bio_read(bio, 2)) != 3)
+                return (3 + n);
+        if ((n = opj_bio_read(bio, 5)) != 31)
+                return (6 + n);
+        return (37 + opj_bio_read(bio, 7));
+}
+
+/* ----------------------------------------------------------------------- */
+
+OPJ_BOOL opj_t2_encode_packets( opj_t2_t* p_t2,
+                                OPJ_UINT32 p_tile_no,
+                                opj_tcd_tile_t *p_tile,
+                                OPJ_UINT32 p_maxlayers,
+                                OPJ_BYTE *p_dest,
+                                OPJ_UINT32 * p_data_written,
+                                OPJ_UINT32 p_max_len,
+                                opj_codestream_info_t *cstr_info,
+                                OPJ_UINT32 p_tp_num,
+                                OPJ_INT32 p_tp_pos,
+                                OPJ_UINT32 p_pino,
+                                J2K_T2_MODE p_t2_mode)
+{
+        OPJ_BYTE *l_current_data = p_dest;
+        OPJ_UINT32 l_nb_bytes = 0;
+        OPJ_UINT32 compno;
+        OPJ_UINT32 poc;
+        opj_pi_iterator_t *l_pi = 00;
+        opj_pi_iterator_t *l_current_pi = 00;
+        opj_image_t *l_image = p_t2->image;
+        opj_cp_t *l_cp = p_t2->cp;
+        opj_tcp_t *l_tcp = &l_cp->tcps[p_tile_no];
+        OPJ_UINT32 pocno = l_cp->m_specific_param.m_enc.m_cinema == OPJ_CINEMA4K_24? 2: 1;
+        OPJ_UINT32 l_max_comp = l_cp->m_specific_param.m_enc.m_max_comp_size > 0 ? l_image->numcomps : 1;
+        OPJ_UINT32 l_nb_pocs = l_tcp->numpocs + 1;
+
+        l_pi = opj_pi_initialise_encode(l_image, l_cp, p_tile_no, p_t2_mode);
+        if (!l_pi) {
+                return OPJ_FALSE;
+        }
+
+        * p_data_written = 0;
+
+        if (p_t2_mode == THRESH_CALC ){ /* Calculating threshold */
+                l_current_pi = l_pi;
+
+                for     (compno = 0; compno < l_max_comp; ++compno) {
+                        OPJ_UINT32 l_comp_len = 0;
+                        l_current_pi = l_pi;
+
+                        for (poc = 0; poc < pocno ; ++poc) {
+                                OPJ_UINT32 l_tp_num = compno;
+
+                                /* TODO MSD : check why this function cannot fail (cf. v1) */
+                                opj_pi_create_encode(l_pi, l_cp,p_tile_no,poc,l_tp_num,p_tp_pos,p_t2_mode);
+
+                                while (opj_pi_next(l_current_pi)) {
+                                        if (l_current_pi->layno < p_maxlayers) {
+                                                l_nb_bytes = 0;
+
+                                                if (! opj_t2_encode_packet(p_tile_no,p_tile, l_tcp, l_current_pi, l_current_data, &l_nb_bytes, p_max_len, cstr_info)) {
+                                                        opj_pi_destroy(l_pi, l_nb_pocs);
+                                                        return OPJ_FALSE;
+                                                }
+
+                                                l_comp_len += l_nb_bytes;
+                                                l_current_data += l_nb_bytes;
+                                                p_max_len -= l_nb_bytes;
+
+                                                * p_data_written += l_nb_bytes;
+                                        }
+                                }
+
+                                if (l_cp->m_specific_param.m_enc.m_max_comp_size) {
+                                        if (l_comp_len > l_cp->m_specific_param.m_enc.m_max_comp_size) {
+                                                opj_pi_destroy(l_pi, l_nb_pocs);
+                                                return OPJ_FALSE;
+                                        }
+                                }
+
+                                ++l_current_pi;
+                        }
+                }
+        }
+        else {  /* t2_mode == FINAL_PASS  */
+                opj_pi_create_encode(l_pi, l_cp,p_tile_no,p_pino,p_tp_num,p_tp_pos,p_t2_mode);
+
+                l_current_pi = &l_pi[p_pino];
+
+                while (opj_pi_next(l_current_pi)) {
+                        if (l_current_pi->layno < p_maxlayers) {
+                                l_nb_bytes=0;
+
+                                if (! opj_t2_encode_packet(p_tile_no,p_tile, l_tcp, l_current_pi, l_current_data, &l_nb_bytes, p_max_len, cstr_info)) {
+                                        opj_pi_destroy(l_pi, l_nb_pocs);
+                                        return OPJ_FALSE;
+                                }
+
+                                l_current_data += l_nb_bytes;
+                                p_max_len -= l_nb_bytes;
+
+                                * p_data_written += l_nb_bytes;
+
+                                /* INDEX >> */
+                                if(cstr_info) {
+                                        if(cstr_info->index_write) {
+                                                opj_tile_info_t *info_TL = &cstr_info->tile[p_tile_no];
+                                                opj_packet_info_t *info_PK = &info_TL->packet[cstr_info->packno];
+                                                if (!cstr_info->packno) {
+                                                        info_PK->start_pos = info_TL->end_header + 1;
+                                                } else {
+                                                        info_PK->start_pos = ((l_cp->m_specific_param.m_enc.m_tp_on | l_tcp->POC)&& info_PK->start_pos) ? info_PK->start_pos : info_TL->packet[cstr_info->packno - 1].end_pos + 1;
+                                                }
+                                                info_PK->end_pos = info_PK->start_pos + l_nb_bytes - 1;
+                                                info_PK->end_ph_pos += info_PK->start_pos - 1;  /* End of packet header which now only represents the distance
+                                                                                                                                                                                                                                                   to start of packet is incremented by value of start of packet*/
+                                        }
+
+                                        cstr_info->packno++;
+                                }
+                                /* << INDEX */
+                                ++p_tile->packno;
+                        }
+                }
+        }
+
+        opj_pi_destroy(l_pi, l_nb_pocs);
+
+        return OPJ_TRUE;
+}
+
+/* see issue 80 */
+#if 0
+#define JAS_FPRINTF fprintf
+#else
+/* issue 290 */
+static void opj_null_jas_fprintf(FILE* file, const char * format, ...)
+{
+  (void)file;
+  (void)format;
+}
+#define JAS_FPRINTF opj_null_jas_fprintf
+#endif
+
+OPJ_BOOL opj_t2_decode_packets( opj_t2_t *p_t2,
+                                OPJ_UINT32 p_tile_no,
+                                opj_tcd_tile_t *p_tile,
+                                OPJ_BYTE *p_src,
+                                OPJ_UINT32 * p_data_read,
+                                OPJ_UINT32 p_max_len,
+                                opj_codestream_index_t *p_cstr_index)
+{
+        OPJ_BYTE *l_current_data = p_src;
+        opj_pi_iterator_t *l_pi = 00;
+        OPJ_UINT32 pino;
+        opj_image_t *l_image = p_t2->image;
+        opj_cp_t *l_cp = p_t2->cp;
+        opj_tcp_t *l_tcp = &(p_t2->cp->tcps[p_tile_no]);
+        OPJ_UINT32 l_nb_bytes_read;
+        OPJ_UINT32 l_nb_pocs = l_tcp->numpocs + 1;
+        opj_pi_iterator_t *l_current_pi = 00;
+#ifdef TODO_MSD
+        OPJ_UINT32 curtp = 0;
+        OPJ_UINT32 tp_start_packno;
+#endif 
+        opj_packet_info_t *l_pack_info = 00;
+        opj_image_comp_t* l_img_comp = 00;
+
+        OPJ_ARG_NOT_USED(p_cstr_index);
+
+#ifdef TODO_MSD
+        if (p_cstr_index) {
+                l_pack_info = p_cstr_index->tile_index[p_tile_no].packet;
+        }
+#endif
+
+        /* create a packet iterator */
+        l_pi = opj_pi_create_decode(l_image, l_cp, p_tile_no);
+        if (!l_pi) {
+                return OPJ_FALSE;
+        }
+
+
+        l_current_pi = l_pi;
+
+        for     (pino = 0; pino <= l_tcp->numpocs; ++pino) {
+
+                /* if the resolution needed is too low, one dim of the tilec could be equal to zero
+                 * and no packets are used to decode this resolution and
+                 * l_current_pi->resno is always >= p_tile->comps[l_current_pi->compno].minimum_num_resolutions
+                 * and no l_img_comp->resno_decoded are computed
+                 */
+                OPJ_BOOL* first_pass_failed = (OPJ_BOOL*)opj_malloc(l_image->numcomps * sizeof(OPJ_BOOL));
+                if (!first_pass_failed)
+                {
+                    opj_pi_destroy(l_pi,l_nb_pocs);
+                    return OPJ_FALSE;
+                }
+                memset(first_pass_failed, OPJ_TRUE, l_image->numcomps * sizeof(OPJ_BOOL));
+
+                while (opj_pi_next(l_current_pi)) {
+                  JAS_FPRINTF( stderr, "packet offset=00000166 prg=%d cmptno=%02d rlvlno=%02d prcno=%03d lyrno=%02d\n\n",
+                    l_current_pi->poc.prg1, l_current_pi->compno, l_current_pi->resno, l_current_pi->precno, l_current_pi->layno );
+
+                        if (l_tcp->num_layers_to_decode > l_current_pi->layno
+                                        && l_current_pi->resno < p_tile->comps[l_current_pi->compno].minimum_num_resolutions) {
+                                l_nb_bytes_read = 0;
+
+                                first_pass_failed[l_current_pi->compno] = OPJ_FALSE;
+
+                                if (! opj_t2_decode_packet(p_t2,p_tile,l_tcp,l_current_pi,l_current_data,&l_nb_bytes_read,p_max_len,l_pack_info)) {
+                                        opj_pi_destroy(l_pi,l_nb_pocs);
+                                        opj_free(first_pass_failed);
+                                        return OPJ_FALSE;
+                                }
+
+                                l_img_comp = &(l_image->comps[l_current_pi->compno]);
+                                l_img_comp->resno_decoded = opj_uint_max(l_current_pi->resno, l_img_comp->resno_decoded);
+                        }
+                        else {
+                                l_nb_bytes_read = 0;
+                                if (! opj_t2_skip_packet(p_t2,p_tile,l_tcp,l_current_pi,l_current_data,&l_nb_bytes_read,p_max_len,l_pack_info)) {
+                                        opj_pi_destroy(l_pi,l_nb_pocs);
+                                        opj_free(first_pass_failed);
+                                        return OPJ_FALSE;
+                                }
+                        }
+
+                        if (first_pass_failed[l_current_pi->compno]) {
+                                l_img_comp = &(l_image->comps[l_current_pi->compno]);
+                                if (l_img_comp->resno_decoded == 0)
+                                        l_img_comp->resno_decoded = p_tile->comps[l_current_pi->compno].minimum_num_resolutions - 1;
+                        }
+
+                        l_current_data += l_nb_bytes_read;
+                        p_max_len -= l_nb_bytes_read;
+
+                        /* INDEX >> */
+#ifdef TODO_MSD
+                        if(p_cstr_info) {
+                                opj_tile_info_v2_t *info_TL = &p_cstr_info->tile[p_tile_no];
+                                opj_packet_info_t *info_PK = &info_TL->packet[p_cstr_info->packno];
+                                tp_start_packno = 0;
+                                if (!p_cstr_info->packno) {
+                                        info_PK->start_pos = info_TL->end_header + 1;
+                                } else if (info_TL->packet[p_cstr_info->packno-1].end_pos >= (OPJ_INT32)p_cstr_info->tile[p_tile_no].tp[curtp].tp_end_pos){ /* New tile part */
+                                        info_TL->tp[curtp].tp_numpacks = p_cstr_info->packno - tp_start_packno; /* Number of packets in previous tile-part */
+                                        tp_start_packno = p_cstr_info->packno;
+                                        curtp++;
+                                        info_PK->start_pos = p_cstr_info->tile[p_tile_no].tp[curtp].tp_end_header+1;
+                                } else {
+                                        info_PK->start_pos = (l_cp->m_specific_param.m_enc.m_tp_on && info_PK->start_pos) ? info_PK->start_pos : info_TL->packet[p_cstr_info->packno - 1].end_pos + 1;
+                                }
+                                info_PK->end_pos = info_PK->start_pos + l_nb_bytes_read - 1;
+                                info_PK->end_ph_pos += info_PK->start_pos - 1;  /* End of packet header which now only represents the distance */
+                                ++p_cstr_info->packno;
+                        }
+#endif
+                        /* << INDEX */
+                }
+                ++l_current_pi;
+
+                opj_free(first_pass_failed);
+        }
+        /* INDEX >> */
+#ifdef TODO_MSD
+        if
+                (p_cstr_info) {
+                p_cstr_info->tile[p_tile_no].tp[curtp].tp_numpacks = p_cstr_info->packno - tp_start_packno; /* Number of packets in last tile-part */
+        }
+#endif
+        /* << INDEX */
+
+        /* don't forget to release pi */
+        opj_pi_destroy(l_pi,l_nb_pocs);
+        *p_data_read = (OPJ_UINT32)(l_current_data - p_src);
+        return OPJ_TRUE;
+}
+
+/* ----------------------------------------------------------------------- */
+
+/**
+ * Creates a Tier 2 handle
+ *
+ * @param       p_image         Source or destination image
+ * @param       p_cp            Image coding parameters.
+ * @return              a new T2 handle if successful, NULL otherwise.
+*/
+opj_t2_t* opj_t2_create(opj_image_t *p_image, opj_cp_t *p_cp)
+{
+        /* create the t2 structure */
+        opj_t2_t *l_t2 = (opj_t2_t*)opj_malloc(sizeof(opj_t2_t));
+        if (!l_t2) {
+                return NULL;
+        }
+        memset(l_t2,0,sizeof(opj_t2_t));
+
+        l_t2->image = p_image;
+        l_t2->cp = p_cp;
+
+        return l_t2;
+}
+
+void opj_t2_destroy(opj_t2_t *t2) {
+        if(t2) {
+                opj_free(t2);
+        }
+}
+
+OPJ_BOOL opj_t2_decode_packet(  opj_t2_t* p_t2,
+                                opj_tcd_tile_t *p_tile,
+                                opj_tcp_t *p_tcp,
+                                opj_pi_iterator_t *p_pi,
+                                OPJ_BYTE *p_src,
+                                OPJ_UINT32 * p_data_read,
+                                OPJ_UINT32 p_max_length,
+                                opj_packet_info_t *p_pack_info)
+{
+        OPJ_BOOL l_read_data;
+        OPJ_UINT32 l_nb_bytes_read = 0;
+        OPJ_UINT32 l_nb_total_bytes_read = 0;
+
+        *p_data_read = 0;
+
+        if (! opj_t2_read_packet_header(p_t2,p_tile,p_tcp,p_pi,&l_read_data,p_src,&l_nb_bytes_read,p_max_length,p_pack_info)) {
+                return OPJ_FALSE;
+        }
+
+        p_src += l_nb_bytes_read;
+        l_nb_total_bytes_read += l_nb_bytes_read;
+        p_max_length -= l_nb_bytes_read;
+
+        /* we should read data for the packet */
+        if (l_read_data) {
+                l_nb_bytes_read = 0;
+
+                if (! opj_t2_read_packet_data(p_t2,p_tile,p_pi,p_src,&l_nb_bytes_read,p_max_length,p_pack_info)) {
+                        return OPJ_FALSE;
+                }
+
+                l_nb_total_bytes_read += l_nb_bytes_read;
+        }
+
+        *p_data_read = l_nb_total_bytes_read;
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_t2_encode_packet(  OPJ_UINT32 tileno,
+                                opj_tcd_tile_t * tile,
+                                opj_tcp_t * tcp,
+                                opj_pi_iterator_t *pi,
+                                OPJ_BYTE *dest,
+                                OPJ_UINT32 * p_data_written,
+                                OPJ_UINT32 length,
+                                opj_codestream_info_t *cstr_info)
+{
+        OPJ_UINT32 bandno, cblkno;
+        OPJ_BYTE* c = dest;
+        OPJ_UINT32 l_nb_bytes;
+        OPJ_UINT32 compno = pi->compno;     /* component value */
+        OPJ_UINT32 resno  = pi->resno;      /* resolution level value */
+        OPJ_UINT32 precno = pi->precno;     /* precinct value */
+        OPJ_UINT32 layno  = pi->layno;      /* quality layer value */
+        OPJ_UINT32 l_nb_blocks;
+        opj_tcd_band_t *band = 00;
+        opj_tcd_cblk_enc_t* cblk = 00;
+        opj_tcd_pass_t *pass = 00;
+
+        opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
+        opj_tcd_resolution_t *res = &tilec->resolutions[resno];
+
+        opj_bio_t *bio = 00;    /* BIO component */
+
+        /* <SOP 0xff91> */
+        if (tcp->csty & J2K_CP_CSTY_SOP) {
+                c[0] = 255;
+                c[1] = 145;
+                c[2] = 0;
+                c[3] = 4;
+#if 0
+                c[4] = (tile->packno % 65536) / 256;
+                c[5] = (tile->packno % 65536) % 256;
+#else
+                c[4] = (tile->packno >> 8) & 0xff; /* packno is uint32_t */
+                c[5] = tile->packno & 0xff;
+#endif
+                c += 6;
+                length -= 6;
+        }
+        /* </SOP> */
+
+        if (!layno) {
+                band = res->bands;
+
+                for(bandno = 0; bandno < res->numbands; ++bandno) {
+                        opj_tcd_precinct_t *prc = &band->precincts[precno];
+
+                        opj_tgt_reset(prc->incltree);
+                        opj_tgt_reset(prc->imsbtree);
+
+                        l_nb_blocks = prc->cw * prc->ch;
+                        for     (cblkno = 0; cblkno < l_nb_blocks; ++cblkno) {
+                                cblk = &prc->cblks.enc[cblkno];
+
+                                cblk->numpasses = 0;
+                                opj_tgt_setvalue(prc->imsbtree, cblkno, band->numbps - (OPJ_INT32)cblk->numbps);
+                        }
+                        ++band;
+                }
+        }
+
+        bio = opj_bio_create();
+        opj_bio_init_enc(bio, c, length);
+        opj_bio_write(bio, 1, 1);           /* Empty header bit */
+
+        /* Writing Packet header */
+        band = res->bands;
+        for (bandno = 0; bandno < res->numbands; ++bandno)      {
+                opj_tcd_precinct_t *prc = &band->precincts[precno];
+
+                l_nb_blocks = prc->cw * prc->ch;
+                cblk = prc->cblks.enc;
+
+                for (cblkno = 0; cblkno < l_nb_blocks; ++cblkno) {
+                        opj_tcd_layer_t *layer = &cblk->layers[layno];
+
+                        if (!cblk->numpasses && layer->numpasses) {
+                                opj_tgt_setvalue(prc->incltree, cblkno, (OPJ_INT32)layno);
+                        }
+
+                        ++cblk;
+                }
+
+                cblk = prc->cblks.enc;
+                for (cblkno = 0; cblkno < l_nb_blocks; cblkno++) {
+                        opj_tcd_layer_t *layer = &cblk->layers[layno];
+                        OPJ_UINT32 increment = 0;
+                        OPJ_UINT32 nump = 0;
+                        OPJ_UINT32 len = 0, passno;
+                        OPJ_UINT32 l_nb_passes;
+
+                        /* cblk inclusion bits */
+                        if (!cblk->numpasses) {
+                                opj_tgt_encode(bio, prc->incltree, cblkno, (OPJ_INT32)(layno + 1));
+                        } else {
+                                opj_bio_write(bio, layer->numpasses != 0, 1);
+                        }
+
+                        /* if cblk not included, go to the next cblk  */
+                        if (!layer->numpasses) {
+                                ++cblk;
+                                continue;
+                        }
+
+                        /* if first instance of cblk --> zero bit-planes information */
+                        if (!cblk->numpasses) {
+                                cblk->numlenbits = 3;
+                                opj_tgt_encode(bio, prc->imsbtree, cblkno, 999);
+                        }
+
+                        /* number of coding passes included */
+                        opj_t2_putnumpasses(bio, layer->numpasses);
+                        l_nb_passes = cblk->numpasses + layer->numpasses;
+                        pass = cblk->passes +  cblk->numpasses;
+
+                        /* computation of the increase of the length indicator and insertion in the header     */
+                        for (passno = cblk->numpasses; passno < l_nb_passes; ++passno) {
+                                ++nump;
+                                len += pass->len;
+
+                                if (pass->term || passno == (cblk->numpasses + layer->numpasses) - 1) {
+                                  increment = (OPJ_UINT32)opj_int_max((OPJ_INT32)increment, opj_int_floorlog2((OPJ_INT32)len) + 1
+                                    - ((OPJ_INT32)cblk->numlenbits + opj_int_floorlog2((OPJ_INT32)nump)));
+                                        len = 0;
+                                        nump = 0;
+                                }
+
+                                ++pass;
+                        }
+                        opj_t2_putcommacode(bio, (OPJ_INT32)increment);
+
+                        /* computation of the new Length indicator */
+                        cblk->numlenbits += increment;
+
+                        pass = cblk->passes +  cblk->numpasses;
+                        /* insertion of the codeword segment length */
+                        for (passno = cblk->numpasses; passno < l_nb_passes; ++passno) {
+                                nump++;
+                                len += pass->len;
+
+                                if (pass->term || passno == (cblk->numpasses + layer->numpasses) - 1) {
+                                        opj_bio_write(bio, (OPJ_UINT32)len, cblk->numlenbits + (OPJ_UINT32)opj_int_floorlog2((OPJ_INT32)nump));
+                                        len = 0;
+                                        nump = 0;
+                                }
+                                ++pass;
+                        }
+
+                        ++cblk;
+                }
+
+                ++band;
+        }
+
+        if (!opj_bio_flush(bio)) {
+                opj_bio_destroy(bio);
+                return OPJ_FALSE;               /* modified to eliminate longjmp !! */
+        }
+
+        l_nb_bytes = (OPJ_UINT32)opj_bio_numbytes(bio);
+        c += l_nb_bytes;
+        length -= l_nb_bytes;
+
+        opj_bio_destroy(bio);
+
+        /* <EPH 0xff92> */
+        if (tcp->csty & J2K_CP_CSTY_EPH) {
+                c[0] = 255;
+                c[1] = 146;
+                c += 2;
+                length -= 2;
+        }
+        /* </EPH> */
+
+        /* << INDEX */
+        /* End of packet header position. Currently only represents the distance to start of packet
+           Will be updated later by incrementing with packet start value*/
+        if(cstr_info && cstr_info->index_write) {
+                opj_packet_info_t *info_PK = &cstr_info->tile[tileno].packet[cstr_info->packno];
+                info_PK->end_ph_pos = (OPJ_INT32)(c - dest);
+        }
+        /* INDEX >> */
+
+        /* Writing the packet body */
+        band = res->bands;
+        for (bandno = 0; bandno < res->numbands; bandno++) {
+                opj_tcd_precinct_t *prc = &band->precincts[precno];
+
+                l_nb_blocks = prc->cw * prc->ch;
+                cblk = prc->cblks.enc;
+
+                for (cblkno = 0; cblkno < l_nb_blocks; ++cblkno) {
+                        opj_tcd_layer_t *layer = &cblk->layers[layno];
+
+                        if (!layer->numpasses) {
+                                ++cblk;
+                                continue;
+                        }
+
+                        if (layer->len > length) {
+                                return OPJ_FALSE;
+                        }
+
+                        memcpy(c, layer->data, layer->len);
+                        cblk->numpasses += layer->numpasses;
+                        c += layer->len;
+                        length -= layer->len;
+
+                        /* << INDEX */
+                        if(cstr_info && cstr_info->index_write) {
+                                opj_packet_info_t *info_PK = &cstr_info->tile[tileno].packet[cstr_info->packno];
+                                info_PK->disto += layer->disto;
+                                if (cstr_info->D_max < info_PK->disto) {
+                                        cstr_info->D_max = info_PK->disto;
+                                }
+                        }
+
+                        ++cblk;
+                        /* INDEX >> */
+                }
+                ++band;
+        }
+
+        assert( c >= dest );
+        * p_data_written += (OPJ_UINT32)(c - dest);
+
+        return OPJ_TRUE;
+}
+
+static OPJ_BOOL opj_t2_skip_packet( opj_t2_t* p_t2,
+                                    opj_tcd_tile_t *p_tile,
+                                    opj_tcp_t *p_tcp,
+                                    opj_pi_iterator_t *p_pi,
+                                    OPJ_BYTE *p_src,
+                                    OPJ_UINT32 * p_data_read,
+                                    OPJ_UINT32 p_max_length,
+                                    opj_packet_info_t *p_pack_info)
+{
+        OPJ_BOOL l_read_data;
+        OPJ_UINT32 l_nb_bytes_read = 0;
+        OPJ_UINT32 l_nb_total_bytes_read = 0;
+
+        *p_data_read = 0;
+
+        if (! opj_t2_read_packet_header(p_t2,p_tile,p_tcp,p_pi,&l_read_data,p_src,&l_nb_bytes_read,p_max_length,p_pack_info)) {
+                return OPJ_FALSE;
+        }
+
+        p_src += l_nb_bytes_read;
+        l_nb_total_bytes_read += l_nb_bytes_read;
+        p_max_length -= l_nb_bytes_read;
+
+        /* we should read data for the packet */
+        if (l_read_data) {
+                l_nb_bytes_read = 0;
+
+                if (! opj_t2_skip_packet_data(p_t2,p_tile,p_pi,&l_nb_bytes_read,p_max_length,p_pack_info)) {
+                        return OPJ_FALSE;
+                }
+
+                l_nb_total_bytes_read += l_nb_bytes_read;
+        }
+        *p_data_read = l_nb_total_bytes_read;
+
+        return OPJ_TRUE;
+}
+
+
+OPJ_BOOL opj_t2_read_packet_header( opj_t2_t* p_t2,
+                                    opj_tcd_tile_t *p_tile,
+                                    opj_tcp_t *p_tcp,
+                                    opj_pi_iterator_t *p_pi,
+                                    OPJ_BOOL * p_is_data_present,
+                                    OPJ_BYTE *p_src_data,
+                                    OPJ_UINT32 * p_data_read,
+                                    OPJ_UINT32 p_max_length,
+                                    opj_packet_info_t *p_pack_info)
+
+{
+        /* loop */
+        OPJ_UINT32 bandno, cblkno;
+        OPJ_UINT32 l_nb_code_blocks;
+        OPJ_UINT32 l_remaining_length;
+        OPJ_UINT32 l_header_length;
+        OPJ_UINT32 * l_modified_length_ptr = 00;
+        OPJ_BYTE *l_current_data = p_src_data;
+        opj_cp_t *l_cp = p_t2->cp;
+        opj_bio_t *l_bio = 00;  /* BIO component */
+        opj_tcd_band_t *l_band = 00;
+        opj_tcd_cblk_dec_t* l_cblk = 00;
+        opj_tcd_resolution_t* l_res = &p_tile->comps[p_pi->compno].resolutions[p_pi->resno];
+
+        OPJ_BYTE *l_header_data = 00;
+        OPJ_BYTE **l_header_data_start = 00;
+
+        OPJ_UINT32 l_present;
+
+        if (p_pi->layno == 0) {
+                l_band = l_res->bands;
+
+                /* reset tagtrees */
+                for (bandno = 0; bandno < l_res->numbands; ++bandno) {
+                        opj_tcd_precinct_t *l_prc = &l_band->precincts[p_pi->precno];
+
+                        if ( ! ((l_band->x1-l_band->x0 == 0)||(l_band->y1-l_band->y0 == 0)) ) {
+                                opj_tgt_reset(l_prc->incltree);
+                                opj_tgt_reset(l_prc->imsbtree);
+                                l_cblk = l_prc->cblks.dec;
+
+                                l_nb_code_blocks = l_prc->cw * l_prc->ch;
+                                for (cblkno = 0; cblkno < l_nb_code_blocks; ++cblkno) {
+                                        l_cblk->numsegs = 0;
+                                        l_cblk->real_num_segs = 0;
+                                        ++l_cblk;
+                                }
+                        }
+
+                        ++l_band;
+                }
+        }
+
+        /* SOP markers */
+
+        if (p_tcp->csty & J2K_CP_CSTY_SOP) {
+                if ((*l_current_data) != 0xff || (*(l_current_data + 1) != 0x91)) {
+                        /* TODO opj_event_msg(t2->cinfo->event_mgr, EVT_WARNING, "Expected SOP marker\n"); */
+                        fprintf(stderr, "Error : expected SOP marker\n");
+                } else {
+                        l_current_data += 6;
+                }
+
+                /** TODO : check the Nsop value */
+        }
+
+        /*
+        When the marker PPT/PPM is used the packet header are store in PPT/PPM marker
+        This part deal with this caracteristic
+        step 1: Read packet header in the saved structure
+        step 2: Return to codestream for decoding
+        */
+
+        l_bio = opj_bio_create();
+        if (! l_bio) {
+                return OPJ_FALSE;
+        }
+
+        if (l_cp->ppm == 1) { /* PPM */
+                l_header_data_start = &l_cp->ppm_data;
+                l_header_data = *l_header_data_start;
+                l_modified_length_ptr = &(l_cp->ppm_len);
+
+        }
+        else if (p_tcp->ppt == 1) { /* PPT */
+                l_header_data_start = &(p_tcp->ppt_data);
+                l_header_data = *l_header_data_start;
+                l_modified_length_ptr = &(p_tcp->ppt_len);
+        }
+        else {  /* Normal Case */
+                l_header_data_start = &(l_current_data);
+                l_header_data = *l_header_data_start;
+                l_remaining_length = (OPJ_UINT32)(p_src_data+p_max_length-l_header_data);
+                l_modified_length_ptr = &(l_remaining_length);
+        }
+
+        opj_bio_init_dec(l_bio, l_header_data,*l_modified_length_ptr);
+
+        l_present = opj_bio_read(l_bio, 1);
+        JAS_FPRINTF(stderr, "present=%d \n", l_present );
+        if (!l_present) {
+            /* TODO MSD: no test to control the output of this function*/
+                opj_bio_inalign(l_bio);
+                l_header_data += opj_bio_numbytes(l_bio);
+                opj_bio_destroy(l_bio);
+
+                /* EPH markers */
+                if (p_tcp->csty & J2K_CP_CSTY_EPH) {
+                        if (p_max_length < 2) {
+                                fprintf(stderr, "Not enough space for expected EPH marker\n");
+                        } else if ((*l_header_data) != 0xff || (*(l_header_data + 1) != 0x92)) {
+                                fprintf(stderr, "Error : expected EPH marker\n");
+                        } else {
+                                l_header_data += 2;
+                        }
+                }
+
+                l_header_length = (OPJ_UINT32)(l_header_data - *l_header_data_start);
+                *l_modified_length_ptr -= l_header_length;
+                *l_header_data_start += l_header_length;
+
+                /* << INDEX */
+                /* End of packet header position. Currently only represents the distance to start of packet
+                   Will be updated later by incrementing with packet start value */
+                if (p_pack_info) {
+                        p_pack_info->end_ph_pos = (OPJ_INT32)(l_current_data - p_src_data);
+                }
+                /* INDEX >> */
+
+                * p_is_data_present = OPJ_FALSE;
+                *p_data_read = (OPJ_UINT32)(l_current_data - p_src_data);
+                return OPJ_TRUE;
+        }
+
+        l_band = l_res->bands;
+        for (bandno = 0; bandno < l_res->numbands; ++bandno) {
+                opj_tcd_precinct_t *l_prc = &(l_band->precincts[p_pi->precno]);
+
+                if ((l_band->x1-l_band->x0 == 0)||(l_band->y1-l_band->y0 == 0)) {
+                        ++l_band;
+                        continue;
+                }
+
+                l_nb_code_blocks = l_prc->cw * l_prc->ch;
+                l_cblk = l_prc->cblks.dec;
+                for (cblkno = 0; cblkno < l_nb_code_blocks; cblkno++) {
+                        OPJ_UINT32 l_included,l_increment, l_segno;
+                        OPJ_INT32 n;
+
+                        /* if cblk not yet included before --> inclusion tagtree */
+                        if (!l_cblk->numsegs) {
+                                l_included = opj_tgt_decode(l_bio, l_prc->incltree, cblkno, (OPJ_INT32)(p_pi->layno + 1));
+                                /* else one bit */
+                        }
+                        else {
+                                l_included = opj_bio_read(l_bio, 1);
+                        }
+
+                        /* if cblk not included */
+                        if (!l_included) {
+                                l_cblk->numnewpasses = 0;
+                                ++l_cblk;
+        JAS_FPRINTF(stderr, "included=%d \n", l_included);
+                                continue;
+                        }
+
+                        /* if cblk not yet included --> zero-bitplane tagtree */
+                        if (!l_cblk->numsegs) {
+                                OPJ_UINT32 i = 0;
+
+                                while (!opj_tgt_decode(l_bio, l_prc->imsbtree, cblkno, (OPJ_INT32)i)) {
+                                        ++i;
+                                }
+
+                                l_cblk->numbps = (OPJ_UINT32)l_band->numbps + 1 - i;
+                                l_cblk->numlenbits = 3;
+                        }
+
+                        /* number of coding passes */
+                        l_cblk->numnewpasses = opj_t2_getnumpasses(l_bio);
+                        l_increment = opj_t2_getcommacode(l_bio);
+
+                        /* length indicator increment */
+                        l_cblk->numlenbits += l_increment;
+                        l_segno = 0;
+
+                        if (!l_cblk->numsegs) {
+                                if (! opj_t2_init_seg(l_cblk, l_segno, p_tcp->tccps[p_pi->compno].cblksty, 1)) {
+                                        opj_bio_destroy(l_bio);
+                                        return OPJ_FALSE;
+                                }
+                        }
+                        else {
+                                l_segno = l_cblk->numsegs - 1;
+                                if (l_cblk->segs[l_segno].numpasses == l_cblk->segs[l_segno].maxpasses) {
+                                        ++l_segno;
+                                        if (! opj_t2_init_seg(l_cblk, l_segno, p_tcp->tccps[p_pi->compno].cblksty, 0)) {
+                                                opj_bio_destroy(l_bio);
+                                                return OPJ_FALSE;
+                                        }
+                                }
+                        }
+                        n = (OPJ_INT32)l_cblk->numnewpasses;
+
+                        do {
+                                l_cblk->segs[l_segno].numnewpasses = (OPJ_UINT32)opj_int_min((OPJ_INT32)(l_cblk->segs[l_segno].maxpasses - l_cblk->segs[l_segno].numpasses), n);
+                                l_cblk->segs[l_segno].newlen = opj_bio_read(l_bio, l_cblk->numlenbits + opj_uint_floorlog2(l_cblk->segs[l_segno].numnewpasses));
+                                        JAS_FPRINTF(stderr, "included=%d numnewpasses=%d increment=%d len=%d \n", l_included, l_cblk->segs[l_segno].numnewpasses, l_increment, l_cblk->segs[l_segno].newlen );
+
+                                n -= (OPJ_INT32)l_cblk->segs[l_segno].numnewpasses;
+                                if (n > 0) {
+                                        ++l_segno;
+
+                                        if (! opj_t2_init_seg(l_cblk, l_segno, p_tcp->tccps[p_pi->compno].cblksty, 0)) {
+                                                opj_bio_destroy(l_bio);
+                                                return OPJ_FALSE;
+                                        }
+                                }
+                        } while (n > 0);
+
+                        ++l_cblk;
+                }
+
+                ++l_band;
+        }
+
+        if (!opj_bio_inalign(l_bio)) {
+                opj_bio_destroy(l_bio);
+                return OPJ_FALSE;
+        }
+
+        l_header_data += opj_bio_numbytes(l_bio);
+        opj_bio_destroy(l_bio);
+
+        /* EPH markers */
+        if (p_tcp->csty & J2K_CP_CSTY_EPH) {
+                if (p_max_length < 2) {
+                        fprintf(stderr, "Not enough space for expected EPH marker\n");
+                } else if ((*l_header_data) != 0xff || (*(l_header_data + 1) != 0x92)) {
+                        /* TODO opj_event_msg(t2->cinfo->event_mgr, EVT_ERROR, "Expected EPH marker\n"); */
+                        fprintf(stderr, "Error : expected EPH marker\n");
+                } else {
+                        l_header_data += 2;
+                }
+        }
+
+        l_header_length = (OPJ_UINT32)(l_header_data - *l_header_data_start);
+        JAS_FPRINTF( stderr, "hdrlen=%d \n", l_header_length );
+        JAS_FPRINTF( stderr, "packet body\n");
+        *l_modified_length_ptr -= l_header_length;
+        *l_header_data_start += l_header_length;
+
+        /* << INDEX */
+        /* End of packet header position. Currently only represents the distance to start of packet
+         Will be updated later by incrementing with packet start value */
+        if (p_pack_info) {
+                p_pack_info->end_ph_pos = (OPJ_INT32)(l_current_data - p_src_data);
+        }
+        /* INDEX >> */
+
+        *p_is_data_present = OPJ_TRUE;
+        *p_data_read = (OPJ_UINT32)(l_current_data - p_src_data);
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_t2_read_packet_data(   opj_t2_t* p_t2,
+                                    opj_tcd_tile_t *p_tile,
+                                    opj_pi_iterator_t *p_pi,
+                                    OPJ_BYTE *p_src_data,
+                                    OPJ_UINT32 * p_data_read,
+                                    OPJ_UINT32 p_max_length,
+                                    opj_packet_info_t *pack_info)
+{
+        OPJ_UINT32 bandno, cblkno;
+        OPJ_UINT32 l_nb_code_blocks;
+        OPJ_BYTE *l_current_data = p_src_data;
+        opj_tcd_band_t *l_band = 00;
+        opj_tcd_cblk_dec_t* l_cblk = 00;
+        opj_tcd_resolution_t* l_res = &p_tile->comps[p_pi->compno].resolutions[p_pi->resno];
+
+        OPJ_ARG_NOT_USED(p_t2);
+        OPJ_ARG_NOT_USED(pack_info);
+
+        l_band = l_res->bands;
+        for (bandno = 0; bandno < l_res->numbands; ++bandno) {
+                opj_tcd_precinct_t *l_prc = &l_band->precincts[p_pi->precno];
+
+                if ((l_band->x1-l_band->x0 == 0)||(l_band->y1-l_band->y0 == 0)) {
+                        ++l_band;
+                        continue;
+                }
+
+                l_nb_code_blocks = l_prc->cw * l_prc->ch;
+                l_cblk = l_prc->cblks.dec;
+
+                for (cblkno = 0; cblkno < l_nb_code_blocks; ++cblkno) {
+                        opj_tcd_seg_t *l_seg = 00;
+
+                        if (!l_cblk->numnewpasses) {
+                                /* nothing to do */
+                                ++l_cblk;
+                                continue;
+                        }
+
+                        if (!l_cblk->numsegs) {
+                                l_seg = l_cblk->segs;
+                                ++l_cblk->numsegs;
+                                l_cblk->data_current_size = 0;
+                        }
+                        else {
+                                l_seg = &l_cblk->segs[l_cblk->numsegs - 1];
+
+                                if (l_seg->numpasses == l_seg->maxpasses) {
+                                        ++l_seg;
+                                        ++l_cblk->numsegs;
+                                }
+                        }
+
+                        do {
+                                if (l_current_data + l_seg->newlen > p_src_data + p_max_length) {
+                                        fprintf(stderr, "read: segment too long (%d) with max (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n",
+                                                l_seg->newlen, p_max_length, cblkno, p_pi->precno, bandno, p_pi->resno, p_pi->compno);
+                                        return OPJ_FALSE;
+                                }
+
+#ifdef USE_JPWL
+                        /* we need here a j2k handle to verify if making a check to
+                        the validity of cblocks parameters is selected from user (-W) */
+
+                                /* let's check that we are not exceeding */
+                                if ((l_cblk->len + l_seg->newlen) > 8192) {
+                                        opj_event_msg(p_t2->cinfo, EVT_WARNING,
+                                                "JPWL: segment too long (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n",
+                                                l_seg->newlen, cblkno, p_pi->precno, bandno, p_pi->resno, p_pi->compno);
+                                        if (!JPWL_ASSUME) {
+                                                opj_event_msg(p_t2->cinfo, EVT_ERROR, "JPWL: giving up\n");
+                                                return OPJ_FALSE;
+                                        }
+                                        l_seg->newlen = 8192 - l_cblk->len;
+                                        opj_event_msg(p_t2->cinfo, EVT_WARNING, "      - truncating segment to %d\n", l_seg->newlen);
+                                        break;
+                                };
+
+#endif /* USE_JPWL */
+                                /* Check if the cblk->data have allocated enough memory */
+                                if ((l_cblk->data_current_size + l_seg->newlen) > l_cblk->data_max_size) {
+                                    OPJ_BYTE* new_cblk_data = (OPJ_BYTE*) opj_realloc(l_cblk->data, l_cblk->data_current_size + l_seg->newlen);
+                                    if(! new_cblk_data) {
+                                        opj_free(l_cblk->data);
+                                        l_cblk->data_max_size = 0;
+                                        /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to realloc code block cata!\n"); */
+                                        return OPJ_FALSE;
+                                    }
+                                    l_cblk->data_max_size = l_cblk->data_current_size + l_seg->newlen;
+                                    l_cblk->data = new_cblk_data;
+                                }
+                               
+                                memcpy(l_cblk->data + l_cblk->data_current_size, l_current_data, l_seg->newlen);
+
+                                if (l_seg->numpasses == 0) {
+                                        l_seg->data = &l_cblk->data;
+                                        l_seg->dataindex = l_cblk->data_current_size;
+                                }
+
+                                l_current_data += l_seg->newlen;
+                                l_seg->numpasses += l_seg->numnewpasses;
+                                l_cblk->numnewpasses -= l_seg->numnewpasses;
+
+                                l_seg->real_num_passes = l_seg->numpasses;
+                                l_cblk->data_current_size += l_seg->newlen;
+                                l_seg->len += l_seg->newlen;
+
+                                if (l_cblk->numnewpasses > 0) {
+                                        ++l_seg;
+                                        ++l_cblk->numsegs;
+                                }
+                        } while (l_cblk->numnewpasses > 0);
+
+                        l_cblk->real_num_segs = l_cblk->numsegs;
+                        ++l_cblk;
+                } /* next code_block */
+
+                ++l_band;
+        }
+
+        *(p_data_read) = (OPJ_UINT32)(l_current_data - p_src_data);
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_t2_skip_packet_data(   opj_t2_t* p_t2,
+                                    opj_tcd_tile_t *p_tile,
+                                    opj_pi_iterator_t *p_pi,
+                                    OPJ_UINT32 * p_data_read,
+                                    OPJ_UINT32 p_max_length,
+                                    opj_packet_info_t *pack_info)
+{
+        OPJ_UINT32 bandno, cblkno;
+        OPJ_UINT32 l_nb_code_blocks;
+        opj_tcd_band_t *l_band = 00;
+        opj_tcd_cblk_dec_t* l_cblk = 00;
+        opj_tcd_resolution_t* l_res = &p_tile->comps[p_pi->compno].resolutions[p_pi->resno];
+
+        OPJ_ARG_NOT_USED(p_t2);
+        OPJ_ARG_NOT_USED(pack_info);
+
+        *p_data_read = 0;
+        l_band = l_res->bands;
+
+        for (bandno = 0; bandno < l_res->numbands; ++bandno) {
+                opj_tcd_precinct_t *l_prc = &l_band->precincts[p_pi->precno];
+
+                if ((l_band->x1-l_band->x0 == 0)||(l_band->y1-l_band->y0 == 0)) {
+                        ++l_band;
+                        continue;
+                }
+
+                l_nb_code_blocks = l_prc->cw * l_prc->ch;
+                l_cblk = l_prc->cblks.dec;
+
+                for (cblkno = 0; cblkno < l_nb_code_blocks; ++cblkno) {
+                        opj_tcd_seg_t *l_seg = 00;
+
+                        if (!l_cblk->numnewpasses) {
+                                /* nothing to do */
+                                ++l_cblk;
+                                continue;
+                        }
+
+                        if (!l_cblk->numsegs) {
+                                l_seg = l_cblk->segs;
+                                ++l_cblk->numsegs;
+                                l_cblk->data_current_size = 0;
+                        }
+                        else {
+                                l_seg = &l_cblk->segs[l_cblk->numsegs - 1];
+
+                                if (l_seg->numpasses == l_seg->maxpasses) {
+                                        ++l_seg;
+                                        ++l_cblk->numsegs;
+                                }
+                        }
+
+                        do {
+                                if (* p_data_read + l_seg->newlen > p_max_length) {
+                                        fprintf(stderr, "skip: segment too long (%d) with max (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n",
+                                                l_seg->newlen, p_max_length, cblkno, p_pi->precno, bandno, p_pi->resno, p_pi->compno);
+                                        return OPJ_FALSE;
+                                }
+
+#ifdef USE_JPWL
+                        /* we need here a j2k handle to verify if making a check to
+                        the validity of cblocks parameters is selected from user (-W) */
+
+                                /* let's check that we are not exceeding */
+                                if ((l_cblk->len + l_seg->newlen) > 8192) {
+                                        opj_event_msg(p_t2->cinfo, EVT_WARNING,
+                                                "JPWL: segment too long (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n",
+                                                l_seg->newlen, cblkno, p_pi->precno, bandno, p_pi->resno, p_pi->compno);
+                                        if (!JPWL_ASSUME) {
+                                                opj_event_msg(p_t2->cinfo, EVT_ERROR, "JPWL: giving up\n");
+                                                return -999;
+                                        }
+                                        l_seg->newlen = 8192 - l_cblk->len;
+                                        opj_event_msg(p_t2->cinfo, EVT_WARNING, "      - truncating segment to %d\n", l_seg->newlen);
+                                        break;
+                                };
+
+#endif /* USE_JPWL */
+                                        JAS_FPRINTF(stderr, "p_data_read (%d) newlen (%d) \n", *p_data_read, l_seg->newlen );
+                                *(p_data_read) += l_seg->newlen;
+
+                                l_seg->numpasses += l_seg->numnewpasses;
+                                l_cblk->numnewpasses -= l_seg->numnewpasses;
+                                if (l_cblk->numnewpasses > 0)
+                                {
+                                        ++l_seg;
+                                        ++l_cblk->numsegs;
+                                }
+                        } while (l_cblk->numnewpasses > 0);
+
+                        ++l_cblk;
+                }
+
+                ++l_band;
+        }
+
+        return OPJ_TRUE;
+}
+
+
+OPJ_BOOL opj_t2_init_seg(   opj_tcd_cblk_dec_t* cblk,
+                            OPJ_UINT32 index, 
+                            OPJ_UINT32 cblksty, 
+                            OPJ_UINT32 first)
+{
+        opj_tcd_seg_t* seg = 00;
+        OPJ_UINT32 l_nb_segs = index + 1;
+
+        if (l_nb_segs > cblk->m_current_max_segs) {
+                opj_tcd_seg_t* new_segs;
+                cblk->m_current_max_segs += OPJ_J2K_DEFAULT_NB_SEGS;
+
+                new_segs = (opj_tcd_seg_t*) opj_realloc(cblk->segs, cblk->m_current_max_segs * sizeof(opj_tcd_seg_t));
+                if(! new_segs) {
+                        opj_free(cblk->segs);
+                        cblk->segs = NULL;
+                        cblk->m_current_max_segs = 0;
+                        /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to initialize segment %d\n", l_nb_segs); */
+                        return OPJ_FALSE;
+                }
+                cblk->segs = new_segs;
+        }
+
+        seg = &cblk->segs[index];
+        memset(seg,0,sizeof(opj_tcd_seg_t));
+
+        if (cblksty & J2K_CCP_CBLKSTY_TERMALL) {
+                seg->maxpasses = 1;
+        }
+        else if (cblksty & J2K_CCP_CBLKSTY_LAZY) {
+                if (first) {
+                        seg->maxpasses = 10;
+                } else {
+                        seg->maxpasses = (((seg - 1)->maxpasses == 1) || ((seg - 1)->maxpasses == 10)) ? 2 : 1;
+                }
+        } else {
+                seg->maxpasses = 109;
+        }
+
+        return OPJ_TRUE;
+}
diff --git a/Source/LibOpenJPEG/t2.h b/Source/LibOpenJPEG/t2.h
index bdb0d97..936073a 100644
--- a/Source/LibOpenJPEG/t2.h
+++ b/Source/LibOpenJPEG/t2.h
@@ -1,105 +1,127 @@
-/*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
- * Copyright (c) 2001-2003, David Janssens
- * Copyright (c) 2002-2003, Yannick Verschueren
- * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef __T2_H
-#define __T2_H
-/**
- at file t2.h
- at brief Implementation of a tier-2 coding (packetization of code-block data) (T2)
-
-*/
-
-/** @defgroup T2 T2 - Implementation of a tier-2 coding */
-/*@{*/
-
-/**
-Tier-2 coding
-*/
-typedef struct opj_t2 {
-	/** codec context */
-	opj_common_ptr cinfo;
-
-	/** Encoding: pointer to the src image. Decoding: pointer to the dst image. */
-	opj_image_t *image;
-	/** pointer to the image coding parameters */
-	opj_cp_t *cp;
-} opj_t2_t;
-
-/** @name Exported functions */
-/*@{*/
-/* ----------------------------------------------------------------------- */
-
-/**
-Encode the packets of a tile to a destination buffer
- at param t2 T2 handle
- at param tileno number of the tile encoded
- at param tile the tile for which to write the packets
- at param maxlayers maximum number of layers
- at param dest the destination buffer
- at param len the length of the destination buffer
- at param cstr_info Codestream information structure 
- at param tpnum Tile part number of the current tile
- at param tppos The position of the tile part flag in the progression order
- at param pino 
- at param t2_mode If == 0 In Threshold calculation ,If == 1 Final pass
- at param cur_totnum_tp The total number of tile parts in the current tile
-*/
-int t2_encode_packets(opj_t2_t* t2,int tileno, opj_tcd_tile_t *tile, int maxlayers, unsigned char *dest, int len, opj_codestream_info_t *cstr_info,int tpnum, int tppos,int pino,J2K_T2_MODE t2_mode,int cur_totnum_tp);
-/**
-Decode the packets of a tile from a source buffer
- at param t2 T2 handle
- at param src the source buffer
- at param len length of the source buffer
- at param tileno number that identifies the tile for which to decode the packets
- at param tile tile for which to decode the packets
- at param cstr_info Codestream information structure
- */
-int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj_tcd_tile_t *tile, opj_codestream_info_t *cstr_info);
-
-/**
-Create a T2 handle
- at param cinfo Codec context info
- at param image Source or destination image
- at param cp Image coding parameters
- at return Returns a new T2 handle if successful, returns NULL otherwise
-*/
-opj_t2_t* t2_create(opj_common_ptr cinfo, opj_image_t *image, opj_cp_t *cp);
-/**
-Destroy a T2 handle
- at param t2 T2 handle to destroy
-*/
-void t2_destroy(opj_t2_t *t2);
-
-/* ----------------------------------------------------------------------- */
-/*@}*/
-
-/*@}*/
-
-#endif /* __T2_H */
+/*
+ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2007, Professor Benoit Macq
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2008;2011-2012, Centre National d'Etudes Spatiales (CNES), France 
+ * Copyright (c) 2012, CS Systemes d'Information, France
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef __T2_H
+#define __T2_H
+/**
+ at file t2.h
+ at brief Implementation of a tier-2 coding (packetization of code-block data) (T2)
+
+*/
+
+/** @defgroup T2 T2 - Implementation of a tier-2 coding */
+/*@{*/
+
+/**
+Tier-2 coding
+*/
+typedef struct opj_t2 {
+
+	/** Encoding: pointer to the src image. Decoding: pointer to the dst image. */
+	opj_image_t *image;
+	/** pointer to the image coding parameters */
+	opj_cp_t *cp;
+} opj_t2_t;
+
+/** @name Exported functions */
+/*@{*/
+/* ----------------------------------------------------------------------- */
+
+/**
+Encode the packets of a tile to a destination buffer
+ at param t2               T2 handle
+ at param tileno           number of the tile encoded
+ at param tile             the tile for which to write the packets
+ at param maxlayers        maximum number of layers
+ at param dest             the destination buffer
+ at param p_data_written   FIXME DOC
+ at param len              the length of the destination buffer
+ at param cstr_info        Codestream information structure
+ at param tpnum            Tile part number of the current tile
+ at param tppos            The position of the tile part flag in the progression order
+ at param pino             FIXME DOC
+ at param t2_mode          If == 0 In Threshold calculation ,If == 1 Final pass
+*/
+OPJ_BOOL opj_t2_encode_packets(	opj_t2_t* t2,
+								OPJ_UINT32 tileno,
+								opj_tcd_tile_t *tile,
+								OPJ_UINT32 maxlayers,
+								OPJ_BYTE *dest,
+								OPJ_UINT32 * p_data_written,
+								OPJ_UINT32 len,
+								opj_codestream_info_t *cstr_info,
+								OPJ_UINT32 tpnum,
+								OPJ_INT32 tppos,
+								OPJ_UINT32 pino,
+								J2K_T2_MODE t2_mode);
+
+/**
+Decode the packets of a tile from a source buffer
+ at param t2 T2 handle
+ at param tileno number that identifies the tile for which to decode the packets
+ at param tile tile for which to decode the packets
+ at param src         FIXME DOC
+ at param p_data_read the source buffer
+ at param len length of the source buffer
+ at param cstr_info   FIXME DOC
+
+ at return FIXME DOC
+ */
+OPJ_BOOL opj_t2_decode_packets(	opj_t2_t *t2,
+                                OPJ_UINT32 tileno,
+                                opj_tcd_tile_t *tile,
+                                OPJ_BYTE *src,
+                                OPJ_UINT32 * p_data_read,
+                                OPJ_UINT32 len,
+                                opj_codestream_index_t *cstr_info);
+
+/**
+ * Creates a Tier 2 handle
+ *
+ * @param	p_image		Source or destination image
+ * @param	p_cp		Image coding parameters.
+ * @return		a new T2 handle if successful, NULL otherwise.
+*/
+opj_t2_t* opj_t2_create(opj_image_t *p_image, opj_cp_t *p_cp);
+
+/**
+Destroy a T2 handle
+ at param t2 T2 handle to destroy
+*/
+void opj_t2_destroy(opj_t2_t *t2);
+
+/* ----------------------------------------------------------------------- */
+/*@}*/
+
+/*@}*/
+
+#endif /* __T2_H */
diff --git a/Source/LibOpenJPEG/tcd.c b/Source/LibOpenJPEG/tcd.c
index 211ee32..147bc68 100644
--- a/Source/LibOpenJPEG/tcd.c
+++ b/Source/LibOpenJPEG/tcd.c
@@ -1,1574 +1,2123 @@
-/*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
- * Copyright (c) 2001-2003, David Janssens
- * Copyright (c) 2002-2003, Yannick Verschueren
- * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * Copyright (c) 2006-2007, Parvatha Elangovan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#define _ISOC99_SOURCE /* lrintf is C99 */
-#include "opj_includes.h"
-
-void tcd_dump(FILE *fd, opj_tcd_t *tcd, opj_tcd_image_t * img) {
-	int tileno, compno, resno, bandno, precno;/*, cblkno;*/
-
-	fprintf(fd, "image {\n");
-	fprintf(fd, "  tw=%d, th=%d x0=%d x1=%d y0=%d y1=%d\n", 
-		img->tw, img->th, tcd->image->x0, tcd->image->x1, tcd->image->y0, tcd->image->y1);
-
-	for (tileno = 0; tileno < img->th * img->tw; tileno++) {
-		opj_tcd_tile_t *tile = &tcd->tcd_image->tiles[tileno];
-		fprintf(fd, "  tile {\n");
-		fprintf(fd, "    x0=%d, y0=%d, x1=%d, y1=%d, numcomps=%d\n",
-			tile->x0, tile->y0, tile->x1, tile->y1, tile->numcomps);
-		for (compno = 0; compno < tile->numcomps; compno++) {
-			opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
-			fprintf(fd, "    tilec {\n");
-			fprintf(fd,
-				"      x0=%d, y0=%d, x1=%d, y1=%d, numresolutions=%d\n",
-				tilec->x0, tilec->y0, tilec->x1, tilec->y1, tilec->numresolutions);
-			for (resno = 0; resno < tilec->numresolutions; resno++) {
-				opj_tcd_resolution_t *res = &tilec->resolutions[resno];
-				fprintf(fd, "\n   res {\n");
-				fprintf(fd,
-					"          x0=%d, y0=%d, x1=%d, y1=%d, pw=%d, ph=%d, numbands=%d\n",
-					res->x0, res->y0, res->x1, res->y1, res->pw, res->ph, res->numbands);
-				for (bandno = 0; bandno < res->numbands; bandno++) {
-					opj_tcd_band_t *band = &res->bands[bandno];
-					fprintf(fd, "        band {\n");
-					fprintf(fd,
-						"          x0=%d, y0=%d, x1=%d, y1=%d, stepsize=%f, numbps=%d\n",
-						band->x0, band->y0, band->x1, band->y1, band->stepsize, band->numbps);
-					for (precno = 0; precno < res->pw * res->ph; precno++) {
-						opj_tcd_precinct_t *prec = &band->precincts[precno];
-						fprintf(fd, "          prec {\n");
-						fprintf(fd,
-							"            x0=%d, y0=%d, x1=%d, y1=%d, cw=%d, ch=%d\n",
-							prec->x0, prec->y0, prec->x1, prec->y1, prec->cw, prec->ch);
-						/*
-						for (cblkno = 0; cblkno < prec->cw * prec->ch; cblkno++) {
-							opj_tcd_cblk_t *cblk = &prec->cblks[cblkno];
-							fprintf(fd, "            cblk {\n");
-							fprintf(fd,
-								"              x0=%d, y0=%d, x1=%d, y1=%d\n",
-								cblk->x0, cblk->y0, cblk->x1, cblk->y1);
-							fprintf(fd, "            }\n");
-						}
-						*/
-						fprintf(fd, "          }\n");
-					}
-					fprintf(fd, "        }\n");
-				}
-				fprintf(fd, "      }\n");
-			}
-			fprintf(fd, "    }\n");
-		}
-		fprintf(fd, "  }\n");
-	}
-	fprintf(fd, "}\n");
-}
-
-/* ----------------------------------------------------------------------- */
-
-/**
-Create a new TCD handle
-*/
-opj_tcd_t* tcd_create(opj_common_ptr cinfo) {
-	/* create the tcd structure */
-	opj_tcd_t *tcd = (opj_tcd_t*)opj_malloc(sizeof(opj_tcd_t));
-	if(!tcd) return NULL;
-	tcd->cinfo = cinfo;
-	tcd->tcd_image = (opj_tcd_image_t*)opj_malloc(sizeof(opj_tcd_image_t));
-	if(!tcd->tcd_image) {
-		opj_free(tcd);
-		return NULL;
-	}
-
-	return tcd;
-}
-
-/**
-Destroy a previously created TCD handle
-*/
-void tcd_destroy(opj_tcd_t *tcd) {
-	if(tcd) {
-		opj_free(tcd->tcd_image);
-		opj_free(tcd);
-	}
-}
-
-/* ----------------------------------------------------------------------- */
-
-void tcd_malloc_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int curtileno) {
-	int tileno, compno, resno, bandno, precno, cblkno;
-
-	tcd->image = image;
-	tcd->cp = cp;
-	tcd->tcd_image->tw = cp->tw;
-	tcd->tcd_image->th = cp->th;
-	tcd->tcd_image->tiles = (opj_tcd_tile_t *) opj_malloc(sizeof(opj_tcd_tile_t));
-	
-	for (tileno = 0; tileno < 1; tileno++) {
-		opj_tcp_t *tcp = &cp->tcps[curtileno];
-		int j;
-
-		/* cfr p59 ISO/IEC FDIS15444-1 : 2000 (18 august 2000) */
-		int p = curtileno % cp->tw;	/* si numerotation matricielle .. */
-		int q = curtileno / cp->tw;	/* .. coordonnees de la tile (q,p) q pour ligne et p pour colonne */
-
-		/* opj_tcd_tile_t *tile=&tcd->tcd_image->tiles[tileno]; */
-		opj_tcd_tile_t *tile = tcd->tcd_image->tiles;
-
-		/* 4 borders of the tile rescale on the image if necessary */
-		tile->x0 = int_max(cp->tx0 + p * cp->tdx, image->x0);
-		tile->y0 = int_max(cp->ty0 + q * cp->tdy, image->y0);
-		tile->x1 = int_min(cp->tx0 + (p + 1) * cp->tdx, image->x1);
-		tile->y1 = int_min(cp->ty0 + (q + 1) * cp->tdy, image->y1);
-		tile->numcomps = image->numcomps;
-		/* tile->PPT=image->PPT;  */
-
-		/* Modification of the RATE >> */
-		for (j = 0; j < tcp->numlayers; j++) {
-			tcp->rates[j] = tcp->rates[j] ? 
-				cp->tp_on ? 
-					(((float) (tile->numcomps 
-					* (tile->x1 - tile->x0) 
-					* (tile->y1 - tile->y0)
-					* image->comps[0].prec))
-					/(tcp->rates[j] * 8 * image->comps[0].dx * image->comps[0].dy)) - (((tcd->cur_totnum_tp - 1) * 14 )/ tcp->numlayers)
-					:
-				((float) (tile->numcomps 
-					* (tile->x1 - tile->x0) 
-					* (tile->y1 - tile->y0) 
-					* image->comps[0].prec))/ 
-					(tcp->rates[j] * 8 * image->comps[0].dx * image->comps[0].dy)
-					: 0;
-
-			if (tcp->rates[j]) {
-				if (j && tcp->rates[j] < tcp->rates[j - 1] + 10) {
-					tcp->rates[j] = tcp->rates[j - 1] + 20;
-				} else {
-					if (!j && tcp->rates[j] < 30)
-						tcp->rates[j] = 30;
-				}
-				
-				if(j == (tcp->numlayers-1)){
-					tcp->rates[j] = tcp->rates[j]- 2;
-				}
-			}
-		}
-		/* << Modification of the RATE */
-		
-		tile->comps = (opj_tcd_tilecomp_t *) opj_malloc(image->numcomps * sizeof(opj_tcd_tilecomp_t));
-		for (compno = 0; compno < tile->numcomps; compno++) {
-			opj_tccp_t *tccp = &tcp->tccps[compno];
-
-			opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
-
-			/* border of each tile component (global) */
-			tilec->x0 = int_ceildiv(tile->x0, image->comps[compno].dx);
-			tilec->y0 = int_ceildiv(tile->y0, image->comps[compno].dy);
-			tilec->x1 = int_ceildiv(tile->x1, image->comps[compno].dx);
-			tilec->y1 = int_ceildiv(tile->y1, image->comps[compno].dy);
-			
-			tilec->data = (int *) opj_aligned_malloc((tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0) * sizeof(int));
-			tilec->numresolutions = tccp->numresolutions;
-
-			tilec->resolutions = (opj_tcd_resolution_t *) opj_malloc(tilec->numresolutions * sizeof(opj_tcd_resolution_t));
-			
-			for (resno = 0; resno < tilec->numresolutions; resno++) {
-				int pdx, pdy;
-				int levelno = tilec->numresolutions - 1 - resno;
-				int tlprcxstart, tlprcystart, brprcxend, brprcyend;
-				int tlcbgxstart, tlcbgystart, brcbgxend, brcbgyend;
-				int cbgwidthexpn, cbgheightexpn;
-				int cblkwidthexpn, cblkheightexpn;
-
-				opj_tcd_resolution_t *res = &tilec->resolutions[resno];
-				
-				/* border for each resolution level (global) */
-				res->x0 = int_ceildivpow2(tilec->x0, levelno);
-				res->y0 = int_ceildivpow2(tilec->y0, levelno);
-				res->x1 = int_ceildivpow2(tilec->x1, levelno);
-				res->y1 = int_ceildivpow2(tilec->y1, levelno);
-				
-				res->numbands = resno == 0 ? 1 : 3;
-				/* p. 35, table A-23, ISO/IEC FDIS154444-1 : 2000 (18 august 2000) */
-				if (tccp->csty & J2K_CCP_CSTY_PRT) {
-					pdx = tccp->prcw[resno];
-					pdy = tccp->prch[resno];
-				} else {
-					pdx = 15;
-					pdy = 15;
-				}
-				/* p. 64, B.6, ISO/IEC FDIS15444-1 : 2000 (18 august 2000)  */
-				tlprcxstart = int_floordivpow2(res->x0, pdx) << pdx;
-				tlprcystart = int_floordivpow2(res->y0, pdy) << pdy;
-				
-				brprcxend = int_ceildivpow2(res->x1, pdx) << pdx;
-				brprcyend = int_ceildivpow2(res->y1, pdy) << pdy;
-				
-				res->pw = (brprcxend - tlprcxstart) >> pdx;
-				res->ph = (brprcyend - tlprcystart) >> pdy;
-				
-				if (resno == 0) {
-					tlcbgxstart = tlprcxstart;
-					tlcbgystart = tlprcystart;
-					brcbgxend = brprcxend;
-					brcbgyend = brprcyend;
-					cbgwidthexpn = pdx;
-					cbgheightexpn = pdy;
-				} else {
-					tlcbgxstart = int_ceildivpow2(tlprcxstart, 1);
-					tlcbgystart = int_ceildivpow2(tlprcystart, 1);
-					brcbgxend = int_ceildivpow2(brprcxend, 1);
-					brcbgyend = int_ceildivpow2(brprcyend, 1);
-					cbgwidthexpn = pdx - 1;
-					cbgheightexpn = pdy - 1;
-				}
-				
-				cblkwidthexpn = int_min(tccp->cblkw, cbgwidthexpn);
-				cblkheightexpn = int_min(tccp->cblkh, cbgheightexpn);
-				
-				for (bandno = 0; bandno < res->numbands; bandno++) {
-					int x0b, y0b, i;
-					int gain, numbps;
-					opj_stepsize_t *ss = NULL;
-
-					opj_tcd_band_t *band = &res->bands[bandno];
-
-					band->bandno = resno == 0 ? 0 : bandno + 1;
-					x0b = (band->bandno == 1) || (band->bandno == 3) ? 1 : 0;
-					y0b = (band->bandno == 2) || (band->bandno == 3) ? 1 : 0;
-					
-					if (band->bandno == 0) {
-						/* band border (global) */
-						band->x0 = int_ceildivpow2(tilec->x0, levelno);
-						band->y0 = int_ceildivpow2(tilec->y0, levelno);
-						band->x1 = int_ceildivpow2(tilec->x1, levelno);
-						band->y1 = int_ceildivpow2(tilec->y1, levelno);
-					} else {
-						/* band border (global) */
-						band->x0 = int_ceildivpow2(tilec->x0 - (1 << levelno) * x0b, levelno + 1);
-						band->y0 = int_ceildivpow2(tilec->y0 - (1 << levelno) * y0b, levelno + 1);
-						band->x1 = int_ceildivpow2(tilec->x1 - (1 << levelno) * x0b, levelno + 1);
-						band->y1 = int_ceildivpow2(tilec->y1 - (1 << levelno) * y0b, levelno + 1);
-					}
-					
-					ss = &tccp->stepsizes[resno == 0 ? 0 : 3 * (resno - 1) + bandno + 1];
-					gain = tccp->qmfbid == 0 ? dwt_getgain_real(band->bandno) : dwt_getgain(band->bandno);					
-					numbps = image->comps[compno].prec + gain;
-					
-					band->stepsize = (float)((1.0 + ss->mant / 2048.0) * pow(2.0, numbps - ss->expn));
-					band->numbps = ss->expn + tccp->numgbits - 1;	/* WHY -1 ? */
-					
-					band->precincts = (opj_tcd_precinct_t *) opj_malloc(3 * res->pw * res->ph * sizeof(opj_tcd_precinct_t));
-					
-					for (i = 0; i < res->pw * res->ph * 3; i++) {
-						band->precincts[i].imsbtree = NULL;
-						band->precincts[i].incltree = NULL;
-						band->precincts[i].cblks.enc = NULL;
-					}
-					
-					for (precno = 0; precno < res->pw * res->ph; precno++) {
-						int tlcblkxstart, tlcblkystart, brcblkxend, brcblkyend;
-
-						int cbgxstart = tlcbgxstart + (precno % res->pw) * (1 << cbgwidthexpn);
-						int cbgystart = tlcbgystart + (precno / res->pw) * (1 << cbgheightexpn);
-						int cbgxend = cbgxstart + (1 << cbgwidthexpn);
-						int cbgyend = cbgystart + (1 << cbgheightexpn);
-
-						opj_tcd_precinct_t *prc = &band->precincts[precno];
-
-						/* precinct size (global) */
-						prc->x0 = int_max(cbgxstart, band->x0);
-						prc->y0 = int_max(cbgystart, band->y0);
-						prc->x1 = int_min(cbgxend, band->x1);
-						prc->y1 = int_min(cbgyend, band->y1);
-
-						tlcblkxstart = int_floordivpow2(prc->x0, cblkwidthexpn) << cblkwidthexpn;
-						tlcblkystart = int_floordivpow2(prc->y0, cblkheightexpn) << cblkheightexpn;
-						brcblkxend = int_ceildivpow2(prc->x1, cblkwidthexpn) << cblkwidthexpn;
-						brcblkyend = int_ceildivpow2(prc->y1, cblkheightexpn) << cblkheightexpn;
-						prc->cw = (brcblkxend - tlcblkxstart) >> cblkwidthexpn;
-						prc->ch = (brcblkyend - tlcblkystart) >> cblkheightexpn;
-
-						prc->cblks.enc = (opj_tcd_cblk_enc_t*) opj_calloc((prc->cw * prc->ch), sizeof(opj_tcd_cblk_enc_t));
-						prc->incltree = tgt_create(prc->cw, prc->ch);
-						prc->imsbtree = tgt_create(prc->cw, prc->ch);
-						
-						for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
-							int cblkxstart = tlcblkxstart + (cblkno % prc->cw) * (1 << cblkwidthexpn);
-							int cblkystart = tlcblkystart + (cblkno / prc->cw) * (1 << cblkheightexpn);
-							int cblkxend = cblkxstart + (1 << cblkwidthexpn);
-							int cblkyend = cblkystart + (1 << cblkheightexpn);
-							
-							opj_tcd_cblk_enc_t* cblk = &prc->cblks.enc[cblkno];
-
-							/* code-block size (global) */
-							cblk->x0 = int_max(cblkxstart, prc->x0);
-							cblk->y0 = int_max(cblkystart, prc->y0);
-							cblk->x1 = int_min(cblkxend, prc->x1);
-							cblk->y1 = int_min(cblkyend, prc->y1);
-							cblk->data = (unsigned char*) opj_calloc(9728+2, sizeof(unsigned char));
-							/* FIXME: mqc_init_enc and mqc_byteout underrun the buffer if we don't do this. Why? */
-							cblk->data[0] = 0;
-							cblk->data[1] = 0;
-							cblk->data += 2;
-							cblk->layers = (opj_tcd_layer_t*) opj_calloc(100, sizeof(opj_tcd_layer_t));
-							cblk->passes = (opj_tcd_pass_t*) opj_calloc(100, sizeof(opj_tcd_pass_t));
-						}
-					}
-				}
-			}
-		}
-	}
-	
-	/* tcd_dump(stdout, tcd, &tcd->tcd_image); */
-}
-
-void tcd_free_encode(opj_tcd_t *tcd) {
-	int tileno, compno, resno, bandno, precno, cblkno;
-
-	for (tileno = 0; tileno < 1; tileno++) {
-		opj_tcd_tile_t *tile = tcd->tcd_image->tiles;
-
-		for (compno = 0; compno < tile->numcomps; compno++) {
-			opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
-
-			for (resno = 0; resno < tilec->numresolutions; resno++) {
-				opj_tcd_resolution_t *res = &tilec->resolutions[resno];
-
-				for (bandno = 0; bandno < res->numbands; bandno++) {
-					opj_tcd_band_t *band = &res->bands[bandno];
-
-					for (precno = 0; precno < res->pw * res->ph; precno++) {
-						opj_tcd_precinct_t *prc = &band->precincts[precno];
-
-						if (prc->incltree != NULL) {
-							tgt_destroy(prc->incltree);
-							prc->incltree = NULL;
-						}
-						if (prc->imsbtree != NULL) {
-							tgt_destroy(prc->imsbtree);	
-							prc->imsbtree = NULL;
-						}
-						for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
-							opj_free(prc->cblks.enc[cblkno].data - 2);
-							opj_free(prc->cblks.enc[cblkno].layers);
-							opj_free(prc->cblks.enc[cblkno].passes);
-						}
-						opj_free(prc->cblks.enc);
-					} /* for (precno */
-					opj_free(band->precincts);
-					band->precincts = NULL;
-				} /* for (bandno */
-			} /* for (resno */
-			opj_free(tilec->resolutions);
-			tilec->resolutions = NULL;
-		} /* for (compno */
-		opj_free(tile->comps);
-		tile->comps = NULL;
-	} /* for (tileno */
-	opj_free(tcd->tcd_image->tiles);
-	tcd->tcd_image->tiles = NULL;
-}
-
-void tcd_init_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int curtileno) {
-	int tileno, compno, resno, bandno, precno, cblkno;
-
-	for (tileno = 0; tileno < 1; tileno++) {
-		opj_tcp_t *tcp = &cp->tcps[curtileno];
-		int j;
-		/* cfr p59 ISO/IEC FDIS15444-1 : 2000 (18 august 2000) */
-		int p = curtileno % cp->tw;
-		int q = curtileno / cp->tw;
-
-		opj_tcd_tile_t *tile = tcd->tcd_image->tiles;
-		
-		/* 4 borders of the tile rescale on the image if necessary */
-		tile->x0 = int_max(cp->tx0 + p * cp->tdx, image->x0);
-		tile->y0 = int_max(cp->ty0 + q * cp->tdy, image->y0);
-		tile->x1 = int_min(cp->tx0 + (p + 1) * cp->tdx, image->x1);
-		tile->y1 = int_min(cp->ty0 + (q + 1) * cp->tdy, image->y1);
-		
-		tile->numcomps = image->numcomps;
-		/* tile->PPT=image->PPT; */
-
-		/* Modification of the RATE >> */
-		for (j = 0; j < tcp->numlayers; j++) {
-			tcp->rates[j] = tcp->rates[j] ? 
-				cp->tp_on ? 
-					(((float) (tile->numcomps 
-					* (tile->x1 - tile->x0) 
-					* (tile->y1 - tile->y0)
-					* image->comps[0].prec))
-					/(tcp->rates[j] * 8 * image->comps[0].dx * image->comps[0].dy)) - (((tcd->cur_totnum_tp - 1) * 14 )/ tcp->numlayers)
-					:
-				((float) (tile->numcomps 
-					* (tile->x1 - tile->x0) 
-					* (tile->y1 - tile->y0) 
-					* image->comps[0].prec))/ 
-					(tcp->rates[j] * 8 * image->comps[0].dx * image->comps[0].dy)
-					: 0;
-
-			if (tcp->rates[j]) {
-				if (j && tcp->rates[j] < tcp->rates[j - 1] + 10) {
-					tcp->rates[j] = tcp->rates[j - 1] + 20;
-				} else {
-					if (!j && tcp->rates[j] < 30)
-						tcp->rates[j] = 30;
-				}
-			}
-		}
-		/* << Modification of the RATE */
-
-		/* tile->comps=(opj_tcd_tilecomp_t*)opj_realloc(tile->comps,image->numcomps*sizeof(opj_tcd_tilecomp_t)); */
-		for (compno = 0; compno < tile->numcomps; compno++) {
-			opj_tccp_t *tccp = &tcp->tccps[compno];
-			
-			opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
-
-			/* border of each tile component (global) */
-			tilec->x0 = int_ceildiv(tile->x0, image->comps[compno].dx);
-			tilec->y0 = int_ceildiv(tile->y0, image->comps[compno].dy);
-			tilec->x1 = int_ceildiv(tile->x1, image->comps[compno].dx);
-			tilec->y1 = int_ceildiv(tile->y1, image->comps[compno].dy);
-			
-			tilec->data = (int *) opj_aligned_malloc((tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0) * sizeof(int));
-			tilec->numresolutions = tccp->numresolutions;
-			/* tilec->resolutions=(opj_tcd_resolution_t*)opj_realloc(tilec->resolutions,tilec->numresolutions*sizeof(opj_tcd_resolution_t)); */
-			for (resno = 0; resno < tilec->numresolutions; resno++) {
-				int pdx, pdy;
-
-				int levelno = tilec->numresolutions - 1 - resno;
-				int tlprcxstart, tlprcystart, brprcxend, brprcyend;
-				int tlcbgxstart, tlcbgystart, brcbgxend, brcbgyend;
-				int cbgwidthexpn, cbgheightexpn;
-				int cblkwidthexpn, cblkheightexpn;
-				
-				opj_tcd_resolution_t *res = &tilec->resolutions[resno];
-
-				/* border for each resolution level (global) */
-				res->x0 = int_ceildivpow2(tilec->x0, levelno);
-				res->y0 = int_ceildivpow2(tilec->y0, levelno);
-				res->x1 = int_ceildivpow2(tilec->x1, levelno);
-				res->y1 = int_ceildivpow2(tilec->y1, levelno);	
-				res->numbands = resno == 0 ? 1 : 3;
-
-				/* p. 35, table A-23, ISO/IEC FDIS154444-1 : 2000 (18 august 2000) */
-				if (tccp->csty & J2K_CCP_CSTY_PRT) {
-					pdx = tccp->prcw[resno];
-					pdy = tccp->prch[resno];
-				} else {
-					pdx = 15;
-					pdy = 15;
-				}
-				/* p. 64, B.6, ISO/IEC FDIS15444-1 : 2000 (18 august 2000)  */
-				tlprcxstart = int_floordivpow2(res->x0, pdx) << pdx;
-				tlprcystart = int_floordivpow2(res->y0, pdy) << pdy;
-				brprcxend = int_ceildivpow2(res->x1, pdx) << pdx;
-				brprcyend = int_ceildivpow2(res->y1, pdy) << pdy;
-				
-				res->pw = (brprcxend - tlprcxstart) >> pdx;
-				res->ph = (brprcyend - tlprcystart) >> pdy;
-				
-				if (resno == 0) {
-					tlcbgxstart = tlprcxstart;
-					tlcbgystart = tlprcystart;
-					brcbgxend = brprcxend;
-					brcbgyend = brprcyend;
-					cbgwidthexpn = pdx;
-					cbgheightexpn = pdy;
-				} else {
-					tlcbgxstart = int_ceildivpow2(tlprcxstart, 1);
-					tlcbgystart = int_ceildivpow2(tlprcystart, 1);
-					brcbgxend = int_ceildivpow2(brprcxend, 1);
-					brcbgyend = int_ceildivpow2(brprcyend, 1);
-					cbgwidthexpn = pdx - 1;
-					cbgheightexpn = pdy - 1;
-				}
-				
-				cblkwidthexpn = int_min(tccp->cblkw, cbgwidthexpn);
-				cblkheightexpn = int_min(tccp->cblkh, cbgheightexpn);
-				
-				for (bandno = 0; bandno < res->numbands; bandno++) {
-					int x0b, y0b;
-					int gain, numbps;
-					opj_stepsize_t *ss = NULL;
-
-					opj_tcd_band_t *band = &res->bands[bandno];
-
-					band->bandno = resno == 0 ? 0 : bandno + 1;
-					x0b = (band->bandno == 1) || (band->bandno == 3) ? 1 : 0;
-					y0b = (band->bandno == 2) || (band->bandno == 3) ? 1 : 0;
-					
-					if (band->bandno == 0) {
-						/* band border */
-						band->x0 = int_ceildivpow2(tilec->x0, levelno);
-						band->y0 = int_ceildivpow2(tilec->y0, levelno);
-						band->x1 = int_ceildivpow2(tilec->x1, levelno);
-						band->y1 = int_ceildivpow2(tilec->y1, levelno);
-					} else {
-						band->x0 = int_ceildivpow2(tilec->x0 - (1 << levelno) * x0b, levelno + 1);
-						band->y0 = int_ceildivpow2(tilec->y0 - (1 << levelno) * y0b, levelno + 1);
-						band->x1 = int_ceildivpow2(tilec->x1 - (1 << levelno) * x0b, levelno + 1);
-						band->y1 = int_ceildivpow2(tilec->y1 - (1 << levelno) * y0b, levelno + 1);
-					}
-					
-					ss = &tccp->stepsizes[resno == 0 ? 0 : 3 * (resno - 1) + bandno + 1];
-					gain = tccp->qmfbid == 0 ? dwt_getgain_real(band->bandno) : dwt_getgain(band->bandno);
-					numbps = image->comps[compno].prec + gain;
-					band->stepsize = (float)((1.0 + ss->mant / 2048.0) * pow(2.0, numbps - ss->expn));
-					band->numbps = ss->expn + tccp->numgbits - 1;	/* WHY -1 ? */
-					
-					for (precno = 0; precno < res->pw * res->ph; precno++) {
-						int tlcblkxstart, tlcblkystart, brcblkxend, brcblkyend;
-
-						int cbgxstart = tlcbgxstart + (precno % res->pw) * (1 << cbgwidthexpn);
-						int cbgystart = tlcbgystart + (precno / res->pw) * (1 << cbgheightexpn);
-						int cbgxend = cbgxstart + (1 << cbgwidthexpn);
-						int cbgyend = cbgystart + (1 << cbgheightexpn);
-						
-						opj_tcd_precinct_t *prc = &band->precincts[precno];
-
-						/* precinct size (global) */
-						prc->x0 = int_max(cbgxstart, band->x0);
-						prc->y0 = int_max(cbgystart, band->y0);
-						prc->x1 = int_min(cbgxend, band->x1);
-						prc->y1 = int_min(cbgyend, band->y1);
-
-						tlcblkxstart = int_floordivpow2(prc->x0, cblkwidthexpn) << cblkwidthexpn;
-						tlcblkystart = int_floordivpow2(prc->y0, cblkheightexpn) << cblkheightexpn;
-						brcblkxend = int_ceildivpow2(prc->x1, cblkwidthexpn) << cblkwidthexpn;
-						brcblkyend = int_ceildivpow2(prc->y1, cblkheightexpn) << cblkheightexpn;
-						prc->cw = (brcblkxend - tlcblkxstart) >> cblkwidthexpn;
-						prc->ch = (brcblkyend - tlcblkystart) >> cblkheightexpn;
-
-						opj_free(prc->cblks.enc);
-						prc->cblks.enc = (opj_tcd_cblk_enc_t*) opj_calloc(prc->cw * prc->ch, sizeof(opj_tcd_cblk_enc_t));
-
-						if (prc->incltree != NULL) {
-							tgt_destroy(prc->incltree);
-						}
-						if (prc->imsbtree != NULL) {
-							tgt_destroy(prc->imsbtree);
-						}
-						
-						prc->incltree = tgt_create(prc->cw, prc->ch);
-						prc->imsbtree = tgt_create(prc->cw, prc->ch);
-
-						for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
-							int cblkxstart = tlcblkxstart + (cblkno % prc->cw) * (1 << cblkwidthexpn);
-							int cblkystart = tlcblkystart + (cblkno / prc->cw) * (1 << cblkheightexpn);
-							int cblkxend = cblkxstart + (1 << cblkwidthexpn);
-							int cblkyend = cblkystart + (1 << cblkheightexpn);
-
-							opj_tcd_cblk_enc_t* cblk = &prc->cblks.enc[cblkno];
-
-							/* code-block size (global) */
-							cblk->x0 = int_max(cblkxstart, prc->x0);
-							cblk->y0 = int_max(cblkystart, prc->y0);
-							cblk->x1 = int_min(cblkxend, prc->x1);
-							cblk->y1 = int_min(cblkyend, prc->y1);
-							cblk->data = (unsigned char*) opj_calloc(8192+2, sizeof(unsigned char));
-							/* FIXME: mqc_init_enc and mqc_byteout underrun the buffer if we don't do this. Why? */
-							cblk->data[0] = 0;
-							cblk->data[1] = 0;
-							cblk->data += 2;
-							cblk->layers = (opj_tcd_layer_t*) opj_calloc(100, sizeof(opj_tcd_layer_t));
-							cblk->passes = (opj_tcd_pass_t*) opj_calloc(100, sizeof(opj_tcd_pass_t));
-						}
-					} /* precno */
-				} /* bandno */
-			} /* resno */
-		} /* compno */
-	} /* tileno */
-
-	/* tcd_dump(stdout, tcd, &tcd->tcd_image); */
-}
-
-void tcd_malloc_decode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp) {
-	int i, j, tileno, p, q;
-	unsigned int x0 = 0, y0 = 0, x1 = 0, y1 = 0, w, h;
-
-	tcd->image = image;
-	tcd->tcd_image->tw = cp->tw;
-	tcd->tcd_image->th = cp->th;
-    tcd->tcd_image->tiles = (opj_tcd_tile_t *) opj_calloc(cp->tw * cp->th, sizeof(opj_tcd_tile_t));
-
-	/* 
-	Allocate place to store the decoded data = final image
-	Place limited by the tile really present in the codestream 
-	*/
-
-	for (j = 0; j < cp->tileno_size; j++) {
-		opj_tcd_tile_t *tile;
-		
-		tileno = cp->tileno[j];		
-		tile = &(tcd->tcd_image->tiles[cp->tileno[tileno]]);		
-		tile->numcomps = image->numcomps;
-		tile->comps = (opj_tcd_tilecomp_t*) opj_calloc(image->numcomps, sizeof(opj_tcd_tilecomp_t));
-	}
-
-	for (i = 0; i < image->numcomps; i++) {
-		for (j = 0; j < cp->tileno_size; j++) {
-			opj_tcd_tile_t *tile;
-			opj_tcd_tilecomp_t *tilec;
-			
-			/* cfr p59 ISO/IEC FDIS15444-1 : 2000 (18 august 2000) */
-			
-			tileno = cp->tileno[j];
-			
-			tile = &(tcd->tcd_image->tiles[cp->tileno[tileno]]);
-			tilec = &tile->comps[i];
-			
-			p = tileno % cp->tw;	/* si numerotation matricielle .. */
-			q = tileno / cp->tw;	/* .. coordonnees de la tile (q,p) q pour ligne et p pour colonne */
-			
-			/* 4 borders of the tile rescale on the image if necessary */
-			tile->x0 = int_max(cp->tx0 + p * cp->tdx, image->x0);
-			tile->y0 = int_max(cp->ty0 + q * cp->tdy, image->y0);
-			tile->x1 = int_min(cp->tx0 + (p + 1) * cp->tdx, image->x1);
-			tile->y1 = int_min(cp->ty0 + (q + 1) * cp->tdy, image->y1);
-
-			tilec->x0 = int_ceildiv(tile->x0, image->comps[i].dx);
-			tilec->y0 = int_ceildiv(tile->y0, image->comps[i].dy);
-			tilec->x1 = int_ceildiv(tile->x1, image->comps[i].dx);
-			tilec->y1 = int_ceildiv(tile->y1, image->comps[i].dy);
-
-			x0 = j == 0 ? tilec->x0 : int_min(x0, (unsigned int) tilec->x0);
-			y0 = j == 0 ? tilec->y0 : int_min(y0,	(unsigned int) tilec->y0);
-			x1 = j == 0 ? tilec->x1 : int_max(x1,	(unsigned int) tilec->x1);
-			y1 = j == 0 ? tilec->y1 : int_max(y1,	(unsigned int) tilec->y1);
-		}
-
-		w = int_ceildivpow2(x1 - x0, image->comps[i].factor);
-		h = int_ceildivpow2(y1 - y0, image->comps[i].factor);
-
-		image->comps[i].w = w;
-		image->comps[i].h = h;
-		image->comps[i].x0 = x0;
-		image->comps[i].y0 = y0;
-	}
-}
-
-void tcd_malloc_decode_tile(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int tileno, opj_codestream_info_t *cstr_info) {
-	int compno, resno, bandno, precno, cblkno;
-	opj_tcp_t *tcp;
-	opj_tcd_tile_t *tile;
-
-	OPJ_ARG_NOT_USED(cstr_info);
-
-	tcd->cp = cp;
-	
-	tcp = &(cp->tcps[cp->tileno[tileno]]);
-	tile = &(tcd->tcd_image->tiles[cp->tileno[tileno]]);
-	
-	tileno = cp->tileno[tileno];
-	
-	for (compno = 0; compno < tile->numcomps; compno++) {
-		opj_tccp_t *tccp = &tcp->tccps[compno];
-		opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
-		
-		if (tccp->numresolutions <= 0)
-		{
-			cp->tileno[tileno] = -1;
-			return;
-		}
-
-		/* border of each tile component (global) */
-		tilec->x0 = int_ceildiv(tile->x0, image->comps[compno].dx);
-		tilec->y0 = int_ceildiv(tile->y0, image->comps[compno].dy);
-		tilec->x1 = int_ceildiv(tile->x1, image->comps[compno].dx);
-		tilec->y1 = int_ceildiv(tile->y1, image->comps[compno].dy);
-
-		tilec->numresolutions = tccp->numresolutions;
-		tilec->resolutions = (opj_tcd_resolution_t *) opj_malloc(tilec->numresolutions * sizeof(opj_tcd_resolution_t));
-		
-		for (resno = 0; resno < tilec->numresolutions; resno++) {
-			int pdx, pdy;
-			int levelno = tilec->numresolutions - 1 - resno;
-			int tlprcxstart, tlprcystart, brprcxend, brprcyend;
-			int tlcbgxstart, tlcbgystart, brcbgxend, brcbgyend;
-			int cbgwidthexpn, cbgheightexpn;
-			int cblkwidthexpn, cblkheightexpn;
-			
-			opj_tcd_resolution_t *res = &tilec->resolutions[resno];
-			
-			/* border for each resolution level (global) */
-			res->x0 = int_ceildivpow2(tilec->x0, levelno);
-			res->y0 = int_ceildivpow2(tilec->y0, levelno);
-			res->x1 = int_ceildivpow2(tilec->x1, levelno);
-			res->y1 = int_ceildivpow2(tilec->y1, levelno);
-			res->numbands = resno == 0 ? 1 : 3;
-			
-			/* p. 35, table A-23, ISO/IEC FDIS154444-1 : 2000 (18 august 2000) */
-			if (tccp->csty & J2K_CCP_CSTY_PRT) {
-				pdx = tccp->prcw[resno];
-				pdy = tccp->prch[resno];
-			} else {
-				pdx = 15;
-				pdy = 15;
-			}			
-			
-			/* p. 64, B.6, ISO/IEC FDIS15444-1 : 2000 (18 august 2000)  */
-			tlprcxstart = int_floordivpow2(res->x0, pdx) << pdx;
-			tlprcystart = int_floordivpow2(res->y0, pdy) << pdy;
-			brprcxend = int_ceildivpow2(res->x1, pdx) << pdx;
-			brprcyend = int_ceildivpow2(res->y1, pdy) << pdy;
-			
-			res->pw = (res->x0 == res->x1) ? 0 : ((brprcxend - tlprcxstart) >> pdx);
-			res->ph = (res->y0 == res->y1) ? 0 : ((brprcyend - tlprcystart) >> pdy);
-			
-			if (resno == 0) {
-				tlcbgxstart = tlprcxstart;
-				tlcbgystart = tlprcystart;
-				brcbgxend = brprcxend;
-				brcbgyend = brprcyend;
-				cbgwidthexpn = pdx;
-				cbgheightexpn = pdy;
-			} else {
-				tlcbgxstart = int_ceildivpow2(tlprcxstart, 1);
-				tlcbgystart = int_ceildivpow2(tlprcystart, 1);
-				brcbgxend = int_ceildivpow2(brprcxend, 1);
-				brcbgyend = int_ceildivpow2(brprcyend, 1);
-				cbgwidthexpn = pdx - 1;
-				cbgheightexpn = pdy - 1;
-			}
-			
-			cblkwidthexpn = int_min(tccp->cblkw, cbgwidthexpn);
-			cblkheightexpn = int_min(tccp->cblkh, cbgheightexpn);
-			
-			for (bandno = 0; bandno < res->numbands; bandno++) {
-				int x0b, y0b;
-				int gain, numbps;
-				opj_stepsize_t *ss = NULL;
-				
-				opj_tcd_band_t *band = &res->bands[bandno];
-				band->bandno = resno == 0 ? 0 : bandno + 1;
-				x0b = (band->bandno == 1) || (band->bandno == 3) ? 1 : 0;
-				y0b = (band->bandno == 2) || (band->bandno == 3) ? 1 : 0;
-				
-				if (band->bandno == 0) {
-					/* band border (global) */
-					band->x0 = int_ceildivpow2(tilec->x0, levelno);
-					band->y0 = int_ceildivpow2(tilec->y0, levelno);
-					band->x1 = int_ceildivpow2(tilec->x1, levelno);
-					band->y1 = int_ceildivpow2(tilec->y1, levelno);
-				} else {
-					/* band border (global) */
-					band->x0 = int_ceildivpow2(tilec->x0 - (1 << levelno) * x0b, levelno + 1);
-					band->y0 = int_ceildivpow2(tilec->y0 - (1 << levelno) * y0b, levelno + 1);
-					band->x1 = int_ceildivpow2(tilec->x1 - (1 << levelno) * x0b, levelno + 1);
-					band->y1 = int_ceildivpow2(tilec->y1 - (1 << levelno) * y0b, levelno + 1);
-				}
-				
-				ss = &tccp->stepsizes[resno == 0 ? 0 : 3 * (resno - 1) + bandno + 1];
-				gain = tccp->qmfbid == 0 ? dwt_getgain_real(band->bandno) : dwt_getgain(band->bandno);
-				numbps = image->comps[compno].prec + gain;
-				band->stepsize = (float)(((1.0 + ss->mant / 2048.0) * pow(2.0, numbps - ss->expn)) * 0.5);
-				band->numbps = ss->expn + tccp->numgbits - 1;	/* WHY -1 ? */
-				
-				band->precincts = (opj_tcd_precinct_t *) opj_malloc(res->pw * res->ph * sizeof(opj_tcd_precinct_t));
-				
-				for (precno = 0; precno < res->pw * res->ph; precno++) {
-					int tlcblkxstart, tlcblkystart, brcblkxend, brcblkyend;
-					int cbgxstart = tlcbgxstart + (precno % res->pw) * (1 << cbgwidthexpn);
-					int cbgystart = tlcbgystart + (precno / res->pw) * (1 << cbgheightexpn);
-					int cbgxend = cbgxstart + (1 << cbgwidthexpn);
-					int cbgyend = cbgystart + (1 << cbgheightexpn);
-					
-					opj_tcd_precinct_t *prc = &band->precincts[precno];
-					/* precinct size (global) */
-					prc->x0 = int_max(cbgxstart, band->x0);
-					prc->y0 = int_max(cbgystart, band->y0);
-					prc->x1 = int_min(cbgxend, band->x1);
-					prc->y1 = int_min(cbgyend, band->y1);
-					
-					tlcblkxstart = int_floordivpow2(prc->x0, cblkwidthexpn) << cblkwidthexpn;
-					tlcblkystart = int_floordivpow2(prc->y0, cblkheightexpn) << cblkheightexpn;
-					brcblkxend = int_ceildivpow2(prc->x1, cblkwidthexpn) << cblkwidthexpn;
-					brcblkyend = int_ceildivpow2(prc->y1, cblkheightexpn) << cblkheightexpn;
-					prc->cw = (brcblkxend - tlcblkxstart) >> cblkwidthexpn;
-					prc->ch = (brcblkyend - tlcblkystart) >> cblkheightexpn;
-
-					prc->cblks.dec = (opj_tcd_cblk_dec_t*) opj_malloc(prc->cw * prc->ch * sizeof(opj_tcd_cblk_dec_t));
-
-					prc->incltree = tgt_create(prc->cw, prc->ch);
-					prc->imsbtree = tgt_create(prc->cw, prc->ch);
-					
-					for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
-						int cblkxstart = tlcblkxstart + (cblkno % prc->cw) * (1 << cblkwidthexpn);
-						int cblkystart = tlcblkystart + (cblkno / prc->cw) * (1 << cblkheightexpn);
-						int cblkxend = cblkxstart + (1 << cblkwidthexpn);
-						int cblkyend = cblkystart + (1 << cblkheightexpn);					
-
-						opj_tcd_cblk_dec_t* cblk = &prc->cblks.dec[cblkno];
-						cblk->data = NULL;
-						cblk->segs = NULL;
-						/* code-block size (global) */
-						cblk->x0 = int_max(cblkxstart, prc->x0);
-						cblk->y0 = int_max(cblkystart, prc->y0);
-						cblk->x1 = int_min(cblkxend, prc->x1);
-						cblk->y1 = int_min(cblkyend, prc->y1);
-						cblk->numsegs = 0;
-					}
-				} /* precno */
-			} /* bandno */
-		} /* resno */
-	} /* compno */
-	/* tcd_dump(stdout, tcd, &tcd->tcd_image); */
-}
-
-void tcd_makelayer_fixed(opj_tcd_t *tcd, int layno, int final) {
-	int compno, resno, bandno, precno, cblkno;
-	int value;			/*, matrice[tcd_tcp->numlayers][tcd_tile->comps[0].numresolutions][3]; */
-	int matrice[10][10][3];
-	int i, j, k;
-
-	opj_cp_t *cp = tcd->cp;
-	opj_tcd_tile_t *tcd_tile = tcd->tcd_tile;
-	opj_tcp_t *tcd_tcp = tcd->tcp;
-
-	/*matrice=(int*)opj_malloc(tcd_tcp->numlayers*tcd_tile->comps[0].numresolutions*3*sizeof(int)); */
-	
-	for (compno = 0; compno < tcd_tile->numcomps; compno++) {
-		opj_tcd_tilecomp_t *tilec = &tcd_tile->comps[compno];
-		for (i = 0; i < tcd_tcp->numlayers; i++) {
-			for (j = 0; j < tilec->numresolutions; j++) {
-				for (k = 0; k < 3; k++) {
-					matrice[i][j][k] =
-						(int) (cp->matrice[i * tilec->numresolutions * 3 + j * 3 + k] 
-						* (float) (tcd->image->comps[compno].prec / 16.0));
-				}
-			}
-		}
-        
-		for (resno = 0; resno < tilec->numresolutions; resno++) {
-			opj_tcd_resolution_t *res = &tilec->resolutions[resno];
-			for (bandno = 0; bandno < res->numbands; bandno++) {
-				opj_tcd_band_t *band = &res->bands[bandno];
-				for (precno = 0; precno < res->pw * res->ph; precno++) {
-					opj_tcd_precinct_t *prc = &band->precincts[precno];
-					for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
-						opj_tcd_cblk_enc_t *cblk = &prc->cblks.enc[cblkno];
-						opj_tcd_layer_t *layer = &cblk->layers[layno];
-						int n;
-						int imsb = tcd->image->comps[compno].prec - cblk->numbps;	/* number of bit-plan equal to zero */
-						/* Correction of the matrix of coefficient to include the IMSB information */
-						if (layno == 0) {
-							value = matrice[layno][resno][bandno];
-							if (imsb >= value) {
-								value = 0;
-							} else {
-								value -= imsb;
-							}
-						} else {
-							value =	matrice[layno][resno][bandno] -	matrice[layno - 1][resno][bandno];
-							if (imsb >= matrice[layno - 1][resno][bandno]) {
-								value -= (imsb - matrice[layno - 1][resno][bandno]);
-								if (value < 0) {
-									value = 0;
-								}
-							}
-						}
-						
-						if (layno == 0) {
-							cblk->numpassesinlayers = 0;
-						}
-						
-						n = cblk->numpassesinlayers;
-						if (cblk->numpassesinlayers == 0) {
-							if (value != 0) {
-								n = 3 * value - 2 + cblk->numpassesinlayers;
-							} else {
-								n = cblk->numpassesinlayers;
-							}
-						} else {
-							n = 3 * value + cblk->numpassesinlayers;
-						}
-						
-						layer->numpasses = n - cblk->numpassesinlayers;
-						
-						if (!layer->numpasses)
-							continue;
-						
-						if (cblk->numpassesinlayers == 0) {
-							layer->len = cblk->passes[n - 1].rate;
-							layer->data = cblk->data;
-						} else {
-							layer->len = cblk->passes[n - 1].rate - cblk->passes[cblk->numpassesinlayers - 1].rate;
-							layer->data = cblk->data + cblk->passes[cblk->numpassesinlayers - 1].rate;
-						}
-						if (final)
-							cblk->numpassesinlayers = n;
-					}
-				}
-			}
-		}
-	}
-}
-
-void tcd_rateallocate_fixed(opj_tcd_t *tcd) {
-	int layno;
-	for (layno = 0; layno < tcd->tcp->numlayers; layno++) {
-		tcd_makelayer_fixed(tcd, layno, 1);
-	}
-}
-
-void tcd_makelayer(opj_tcd_t *tcd, int layno, double thresh, int final) {
-	int compno, resno, bandno, precno, cblkno, passno;
-	
-	opj_tcd_tile_t *tcd_tile = tcd->tcd_tile;
-
-	tcd_tile->distolayer[layno] = 0;	/* fixed_quality */
-	
-	for (compno = 0; compno < tcd_tile->numcomps; compno++) {
-		opj_tcd_tilecomp_t *tilec = &tcd_tile->comps[compno];
-		for (resno = 0; resno < tilec->numresolutions; resno++) {
-			opj_tcd_resolution_t *res = &tilec->resolutions[resno];
-			for (bandno = 0; bandno < res->numbands; bandno++) {
-				opj_tcd_band_t *band = &res->bands[bandno];
-				for (precno = 0; precno < res->pw * res->ph; precno++) {
-					opj_tcd_precinct_t *prc = &band->precincts[precno];
-					for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
-						opj_tcd_cblk_enc_t *cblk = &prc->cblks.enc[cblkno];
-						opj_tcd_layer_t *layer = &cblk->layers[layno];
-						
-						int n;
-						if (layno == 0) {
-							cblk->numpassesinlayers = 0;
-						}
-						n = cblk->numpassesinlayers;
-						for (passno = cblk->numpassesinlayers; passno < cblk->totalpasses; passno++) {
-							int dr;
-							double dd;
-							opj_tcd_pass_t *pass = &cblk->passes[passno];
-							if (n == 0) {
-								dr = pass->rate;
-								dd = pass->distortiondec;
-							} else {
-								dr = pass->rate - cblk->passes[n - 1].rate;
-								dd = pass->distortiondec - cblk->passes[n - 1].distortiondec;
-							}
-							if (!dr) {
-								if (dd != 0)
-									n = passno + 1;
-								continue;
-							}
-							if (dd / dr >= thresh)
-								n = passno + 1;
-						}
-						layer->numpasses = n - cblk->numpassesinlayers;
-						
-						if (!layer->numpasses) {
-							layer->disto = 0;
-							continue;
-						}
-						if (cblk->numpassesinlayers == 0) {
-							layer->len = cblk->passes[n - 1].rate;
-							layer->data = cblk->data;
-							layer->disto = cblk->passes[n - 1].distortiondec;
-						} else {
-							layer->len = cblk->passes[n - 1].rate -	cblk->passes[cblk->numpassesinlayers - 1].rate;
-							layer->data = cblk->data + cblk->passes[cblk->numpassesinlayers - 1].rate;
-							layer->disto = cblk->passes[n - 1].distortiondec - cblk->passes[cblk->numpassesinlayers - 1].distortiondec;
-						}
-						
-						tcd_tile->distolayer[layno] += layer->disto;	/* fixed_quality */
-						
-						if (final)
-							cblk->numpassesinlayers = n;
-					}
-				}
-			}
-		}
-	}
-}
-
-opj_bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_codestream_info_t *cstr_info) {
-	int compno, resno, bandno, precno, cblkno, passno, layno;
-	double min, max;
-	double cumdisto[100];	/* fixed_quality */
-	const double K = 1;		/* 1.1; fixed_quality */
-	double maxSE = 0;
-
-	opj_cp_t *cp = tcd->cp;
-	opj_tcd_tile_t *tcd_tile = tcd->tcd_tile;
-	opj_tcp_t *tcd_tcp = tcd->tcp;
-
-	min = DBL_MAX;
-	max = 0;
-	
-	tcd_tile->numpix = 0;		/* fixed_quality */
-	
-	for (compno = 0; compno < tcd_tile->numcomps; compno++) {
-		opj_tcd_tilecomp_t *tilec = &tcd_tile->comps[compno];
-		tilec->numpix = 0;
-
-		for (resno = 0; resno < tilec->numresolutions; resno++) {
-			opj_tcd_resolution_t *res = &tilec->resolutions[resno];
-
-			for (bandno = 0; bandno < res->numbands; bandno++) {
-				opj_tcd_band_t *band = &res->bands[bandno];
-
-				for (precno = 0; precno < res->pw * res->ph; precno++) {
-					opj_tcd_precinct_t *prc = &band->precincts[precno];
-
-					for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
-						opj_tcd_cblk_enc_t *cblk = &prc->cblks.enc[cblkno];
-
-						for (passno = 0; passno < cblk->totalpasses; passno++) {
-							opj_tcd_pass_t *pass = &cblk->passes[passno];
-							int dr;
-							double dd, rdslope;
-							if (passno == 0) {
-								dr = pass->rate;
-								dd = pass->distortiondec;
-							} else {
-								dr = pass->rate - cblk->passes[passno - 1].rate;
-								dd = pass->distortiondec - cblk->passes[passno - 1].distortiondec;
-							}
-							if (dr == 0) {
-								continue;
-							}
-							rdslope = dd / dr;
-							if (rdslope < min) {
-								min = rdslope;
-							}
-							if (rdslope > max) {
-								max = rdslope;
-							}
-						} /* passno */
-						
-						/* fixed_quality */
-						tcd_tile->numpix += ((cblk->x1 - cblk->x0) * (cblk->y1 - cblk->y0));
-						tilec->numpix += ((cblk->x1 - cblk->x0) * (cblk->y1 - cblk->y0));
-					} /* cbklno */
-				} /* precno */
-			} /* bandno */
-		} /* resno */
-		
-		maxSE += (((double)(1 << tcd->image->comps[compno].prec) - 1.0) 
-			* ((double)(1 << tcd->image->comps[compno].prec) -1.0)) 
-			* ((double)(tilec->numpix));
-	} /* compno */
-	
-	/* index file */
-	if(cstr_info) {
-		opj_tile_info_t *tile_info = &cstr_info->tile[tcd->tcd_tileno];
-		tile_info->numpix = tcd_tile->numpix;
-		tile_info->distotile = tcd_tile->distotile;
-		tile_info->thresh = (double *) opj_malloc(tcd_tcp->numlayers * sizeof(double));
-	}
-	
-	for (layno = 0; layno < tcd_tcp->numlayers; layno++) {
-		double lo = min;
-		double hi = max;
-		int success = 0;
-		int maxlen = tcd_tcp->rates[layno] ? int_min(((int) ceil(tcd_tcp->rates[layno])), len) : len;
-		double goodthresh = 0;
-		double stable_thresh = 0;
-		int i;
-		double distotarget;		/* fixed_quality */
-		
-		/* fixed_quality */
-		distotarget = tcd_tile->distotile - ((K * maxSE) / pow((float)10, tcd_tcp->distoratio[layno] / 10));
-        
-		/* Don't try to find an optimal threshold but rather take everything not included yet, if
-		  -r xx,yy,zz,0   (disto_alloc == 1 and rates == 0)
-		  -q xx,yy,zz,0	  (fixed_quality == 1 and distoratio == 0)
-		  ==> possible to have some lossy layers and the last layer for sure lossless */
-		if ( ((cp->disto_alloc==1) && (tcd_tcp->rates[layno]>0)) || ((cp->fixed_quality==1) && (tcd_tcp->distoratio[layno]>0))) {
-			opj_t2_t *t2 = t2_create(tcd->cinfo, tcd->image, cp);
-			double thresh = 0;
-
-			for (i = 0; i < 128; i++) {
-				int l = 0;
-				double distoachieved = 0;	/* fixed_quality */
-				thresh = (lo + hi) / 2;
-				
-				tcd_makelayer(tcd, layno, thresh, 0);
-				
-				if (cp->fixed_quality) {	/* fixed_quality */
-					if(cp->cinema){
-						l = t2_encode_packets(t2,tcd->tcd_tileno, tcd_tile, layno + 1, dest, maxlen, cstr_info,tcd->cur_tp_num,tcd->tp_pos,tcd->cur_pino,THRESH_CALC, tcd->cur_totnum_tp);
-						if (l == -999) {
-							lo = thresh;
-							continue;
-						}else{
-           		distoachieved =	layno == 0 ? 
-							tcd_tile->distolayer[0]	: cumdisto[layno - 1] + tcd_tile->distolayer[layno];
-							if (distoachieved < distotarget) {
-								hi=thresh; 
-								stable_thresh = thresh;
-								continue;
-							}else{
-								lo=thresh;
-							}
-						}
-					}else{
-						distoachieved =	(layno == 0) ? 
-							tcd_tile->distolayer[0]	: (cumdisto[layno - 1] + tcd_tile->distolayer[layno]);
-						if (distoachieved < distotarget) {
-							hi = thresh;
-							stable_thresh = thresh;
-							continue;
-						}
-						lo = thresh;
-					}
-				} else {
-					l = t2_encode_packets(t2, tcd->tcd_tileno, tcd_tile, layno + 1, dest, maxlen, cstr_info,tcd->cur_tp_num,tcd->tp_pos,tcd->cur_pino,THRESH_CALC, tcd->cur_totnum_tp);
-					/* TODO: what to do with l ??? seek / tell ??? */
-					/* opj_event_msg(tcd->cinfo, EVT_INFO, "rate alloc: len=%d, max=%d\n", l, maxlen); */
-					if (l == -999) {
-						lo = thresh;
-						continue;
-					}
-					hi = thresh;
-					stable_thresh = thresh;
-				}
-			}
-			success = 1;
-			goodthresh = stable_thresh == 0? thresh : stable_thresh;
-			t2_destroy(t2);
-		} else {
-			success = 1;
-			goodthresh = min;
-		}
-		
-		if (!success) {
-			return OPJ_FALSE;
-		}
-		
-		if(cstr_info) {	/* Threshold for Marcela Index */
-			cstr_info->tile[tcd->tcd_tileno].thresh[layno] = goodthresh;
-		}
-		tcd_makelayer(tcd, layno, goodthresh, 1);
-        
-		/* fixed_quality */
-		cumdisto[layno] = (layno == 0) ? tcd_tile->distolayer[0] : (cumdisto[layno - 1] + tcd_tile->distolayer[layno]);	
-	}
-
-	return OPJ_TRUE;
-}
-
-int tcd_encode_tile(opj_tcd_t *tcd, int tileno, unsigned char *dest, int len, opj_codestream_info_t *cstr_info) {
-	int compno;
-	int l, i, numpacks = 0;
-	opj_tcd_tile_t *tile = NULL;
-	opj_tcp_t *tcd_tcp = NULL;
-	opj_cp_t *cp = NULL;
-
-	opj_tcp_t *tcp = &tcd->cp->tcps[0];
-	opj_tccp_t *tccp = &tcp->tccps[0];
-	opj_image_t *image = tcd->image;
-	
-	opj_t1_t *t1 = NULL;		/* T1 component */
-	opj_t2_t *t2 = NULL;		/* T2 component */
-
-	tcd->tcd_tileno = tileno;
-	tcd->tcd_tile = tcd->tcd_image->tiles;
-	tcd->tcp = &tcd->cp->tcps[tileno];
-
-	tile = tcd->tcd_tile;
-	tcd_tcp = tcd->tcp;
-	cp = tcd->cp;
-
-	if(tcd->cur_tp_num == 0){
-		tcd->encoding_time = opj_clock();	/* time needed to encode a tile */
-		/* INDEX >> "Precinct_nb_X et Precinct_nb_Y" */
-		if(cstr_info) {
-			opj_tcd_tilecomp_t *tilec_idx = &tile->comps[0];	/* based on component 0 */
-			for (i = 0; i < tilec_idx->numresolutions; i++) {
-				opj_tcd_resolution_t *res_idx = &tilec_idx->resolutions[i];
-				
-				cstr_info->tile[tileno].pw[i] = res_idx->pw;
-				cstr_info->tile[tileno].ph[i] = res_idx->ph;
-				
-				numpacks += res_idx->pw * res_idx->ph;
-				
-				cstr_info->tile[tileno].pdx[i] = tccp->prcw[i];
-				cstr_info->tile[tileno].pdy[i] = tccp->prch[i];
-			}
-			cstr_info->tile[tileno].packet = (opj_packet_info_t*) opj_calloc(cstr_info->numcomps * cstr_info->numlayers * numpacks, sizeof(opj_packet_info_t));
-		}
-		/* << INDEX */
-		
-		/*---------------TILE-------------------*/
-		
-		for (compno = 0; compno < tile->numcomps; compno++) {
-			int x, y;
-			
-			int adjust = image->comps[compno].sgnd ? 0 : 1 << (image->comps[compno].prec - 1);
-			int offset_x = int_ceildiv(image->x0, image->comps[compno].dx);
-			int offset_y = int_ceildiv(image->y0, image->comps[compno].dy);
-			
-			opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
-			int tw = tilec->x1 - tilec->x0;
-			int w = int_ceildiv(image->x1 - image->x0, image->comps[compno].dx);
-			
-			/* extract tile data */
-			
-			if (tcd_tcp->tccps[compno].qmfbid == 1) {
-				for (y = tilec->y0; y < tilec->y1; y++) {
-					/* start of the src tile scanline */
-					int *data = &image->comps[compno].data[(tilec->x0 - offset_x) + (y - offset_y) * w];
-					/* start of the dst tile scanline */
-					int *tile_data = &tilec->data[(y - tilec->y0) * tw];
-					for (x = tilec->x0; x < tilec->x1; x++) {
-						*tile_data++ = *data++ - adjust;
-					}
-				}
-			} else if (tcd_tcp->tccps[compno].qmfbid == 0) {
-				for (y = tilec->y0; y < tilec->y1; y++) {
-					/* start of the src tile scanline */
-					int *data = &image->comps[compno].data[(tilec->x0 - offset_x) + (y - offset_y) * w];
-					/* start of the dst tile scanline */
-					int *tile_data = &tilec->data[(y - tilec->y0) * tw];
-					for (x = tilec->x0; x < tilec->x1; x++) {
-						*tile_data++ = (*data++ - adjust) << 11;
-					}
-					
-				}
-			}
-		}
-		
-		/*----------------MCT-------------------*/
-		if (tcd_tcp->mct) {
-			int samples = (tile->comps[0].x1 - tile->comps[0].x0) * (tile->comps[0].y1 - tile->comps[0].y0);
-			if (tcd_tcp->tccps[0].qmfbid == 0) {
-				mct_encode_real(tile->comps[0].data, tile->comps[1].data, tile->comps[2].data, samples);
-			} else {
-				mct_encode(tile->comps[0].data, tile->comps[1].data, tile->comps[2].data, samples);
-			}
-		}
-		
-		/*----------------DWT---------------------*/
-		
-		for (compno = 0; compno < tile->numcomps; compno++) {
-			opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
-			if (tcd_tcp->tccps[compno].qmfbid == 1) {
-				dwt_encode(tilec);
-			} else if (tcd_tcp->tccps[compno].qmfbid == 0) {
-				dwt_encode_real(tilec);
-			}
-		}
-		
-		/*------------------TIER1-----------------*/
-		t1 = t1_create(tcd->cinfo);
-		t1_encode_cblks(t1, tile, tcd_tcp);
-		t1_destroy(t1);
-		
-		/*-----------RATE-ALLOCATE------------------*/
-		
-		/* INDEX */
-		if(cstr_info) {
-			cstr_info->index_write = 0;
-		}
-		if (cp->disto_alloc || cp->fixed_quality) {	/* fixed_quality */
-			/* Normal Rate/distortion allocation */
-			tcd_rateallocate(tcd, dest, len, cstr_info);
-		} else {
-			/* Fixed layer allocation */
-			tcd_rateallocate_fixed(tcd);
-		}
-	}
-	/*--------------TIER2------------------*/
-
-	/* INDEX */
-	if(cstr_info) {
-		cstr_info->index_write = 1;
-	}
-
-	t2 = t2_create(tcd->cinfo, image, cp);
-	l = t2_encode_packets(t2,tileno, tile, tcd_tcp->numlayers, dest, len, cstr_info,tcd->tp_num,tcd->tp_pos,tcd->cur_pino,FINAL_PASS,tcd->cur_totnum_tp);
-	t2_destroy(t2);
-	
-	/*---------------CLEAN-------------------*/
-
-	
-	if(tcd->cur_tp_num == tcd->cur_totnum_tp - 1){
-		tcd->encoding_time = opj_clock() - tcd->encoding_time;
-		opj_event_msg(tcd->cinfo, EVT_INFO, "- tile encoded in %f s\n", tcd->encoding_time);
-
-		/* cleaning memory */
-		for (compno = 0; compno < tile->numcomps; compno++) {
-			opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
-			opj_aligned_free(tilec->data);
-		}
-	}
-
-	return l;
-}
-
-opj_bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno, opj_codestream_info_t *cstr_info) {
-	int l;
-	int compno;
-	int eof = 0;
-	double tile_time, t1_time, dwt_time;
-	opj_tcd_tile_t *tile = NULL;
-
-	opj_t1_t *t1 = NULL;		/* T1 component */
-	opj_t2_t *t2 = NULL;		/* T2 component */
-	
-	tcd->tcd_tileno = tileno;
-	tcd->tcd_tile = &(tcd->tcd_image->tiles[tileno]);
-	tcd->tcp = &(tcd->cp->tcps[tileno]);
-	tile = tcd->tcd_tile;
-	
-	tile_time = opj_clock();	/* time needed to decode a tile */
-	opj_event_msg(tcd->cinfo, EVT_INFO, "tile %d of %d\n", tileno + 1, tcd->cp->tw * tcd->cp->th);
-
-	/* INDEX >>  */
-	if(cstr_info) {
-		int resno, compno, numprec = 0;
-		for (compno = 0; compno < cstr_info->numcomps; compno++) {
-			opj_tcp_t *tcp = &tcd->cp->tcps[0];
-			opj_tccp_t *tccp = &tcp->tccps[compno];
-			opj_tcd_tilecomp_t *tilec_idx = &tile->comps[compno];	
-			for (resno = 0; resno < tilec_idx->numresolutions; resno++) {
-				opj_tcd_resolution_t *res_idx = &tilec_idx->resolutions[resno];
-				cstr_info->tile[tileno].pw[resno] = res_idx->pw;
-				cstr_info->tile[tileno].ph[resno] = res_idx->ph;
-				numprec += res_idx->pw * res_idx->ph;
-				if (tccp->csty & J2K_CP_CSTY_PRT) {
-					cstr_info->tile[tileno].pdx[resno] = tccp->prcw[resno];
-					cstr_info->tile[tileno].pdy[resno] = tccp->prch[resno];
-				}
-				else {
-					cstr_info->tile[tileno].pdx[resno] = 15;
-					cstr_info->tile[tileno].pdy[resno] = 15;
-				}
-			}
-		}
-		cstr_info->tile[tileno].packet = (opj_packet_info_t *) opj_malloc(cstr_info->numlayers * numprec * sizeof(opj_packet_info_t));
-		cstr_info->packno = 0;
-	}
-	/* << INDEX */
-	
-	/*--------------TIER2------------------*/
-	
-	t2 = t2_create(tcd->cinfo, tcd->image, tcd->cp);
-	l = t2_decode_packets(t2, src, len, tileno, tile, cstr_info);
-	t2_destroy(t2);
-
-	if (l == -999) {
-		eof = 1;
-		opj_event_msg(tcd->cinfo, EVT_ERROR, "tcd_decode: incomplete bistream\n");
-	}
-	
-	/*------------------TIER1-----------------*/
-	
-	t1_time = opj_clock();	/* time needed to decode a tile */
-	t1 = t1_create(tcd->cinfo);
-    if (t1 == NULL)
-    {
-        opj_event_msg(tcd->cinfo, EVT_ERROR, "Out of memory\n");
-        t1_destroy(t1);
-        return OPJ_FALSE;
-    }
-
-	for (compno = 0; compno < tile->numcomps; ++compno) {
-		opj_tcd_tilecomp_t* tilec = &tile->comps[compno];
-		/* The +3 is headroom required by the vectorized DWT */
-		tilec->data = (int*) opj_aligned_malloc((((tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0))+3) * sizeof(int));
-        if (tilec->data == NULL)
-        {
-            opj_event_msg(tcd->cinfo, EVT_ERROR, "Out of memory\n");
-            return OPJ_FALSE;
-        }
-
-		t1_decode_cblks(t1, tilec, &tcd->tcp->tccps[compno]);
-	}
-	t1_destroy(t1);
-	t1_time = opj_clock() - t1_time;
-	opj_event_msg(tcd->cinfo, EVT_INFO, "- tiers-1 took %f s\n", t1_time);
-	
-	/*----------------DWT---------------------*/
-
-	dwt_time = opj_clock();	/* time needed to decode a tile */
-	for (compno = 0; compno < tile->numcomps; compno++) {
-		opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
-		int numres2decode;
-
-		if (tcd->cp->reduce != 0) {
-			if ( tile->comps[compno].numresolutions < ( tcd->cp->reduce - 1 ) ) {				
-				opj_event_msg(tcd->cinfo, EVT_ERROR, "Error decoding tile. The number of resolutions to remove [%d+1] is higher than the number "
-					" of resolutions in the original codestream [%d]\nModify the cp_reduce parameter.\n", tcd->cp->reduce, tile->comps[compno].numresolutions);
-				return OPJ_FALSE;
-			}
-      else {
-		  	tcd->image->comps[compno].resno_decoded =
-				tile->comps[compno].numresolutions - tcd->cp->reduce - 1;
-      }
-		}
-
-		numres2decode = tcd->image->comps[compno].resno_decoded + 1;
-		if(numres2decode > 0){
-			if (tcd->tcp->tccps[compno].qmfbid == 1) {
-				dwt_decode(tilec, numres2decode);
-			} else {
-				dwt_decode_real(tilec, numres2decode);
-			}
-		}
-	}
-	dwt_time = opj_clock() - dwt_time;
-	opj_event_msg(tcd->cinfo, EVT_INFO, "- dwt took %f s\n", dwt_time);
-
-	/*----------------MCT-------------------*/
-
-	if (tcd->tcp->mct) {
-		int n = (tile->comps[0].x1 - tile->comps[0].x0) * (tile->comps[0].y1 - tile->comps[0].y0);
-
-		if (tile->numcomps >= 3 ){
-			if (tcd->tcp->tccps[0].qmfbid == 1) {
-				mct_decode(
-						tile->comps[0].data,
-						tile->comps[1].data,
-						tile->comps[2].data,
-						n);
-			} else {
-				mct_decode_real(
-						(float*)tile->comps[0].data,
-						(float*)tile->comps[1].data,
-						(float*)tile->comps[2].data,
-						n);
-			}
-		} else{
-			opj_event_msg(tcd->cinfo, EVT_WARNING,"Number of components (%d) is inconsistent with a MCT. Skip the MCT step.\n",tile->numcomps);
-		}
-	}
-
-	/*---------------TILE-------------------*/
-
-	for (compno = 0; compno < tile->numcomps; ++compno) {
-		opj_tcd_tilecomp_t* tilec = &tile->comps[compno];
-		opj_image_comp_t* imagec = &tcd->image->comps[compno];
-		opj_tcd_resolution_t* res = &tilec->resolutions[imagec->resno_decoded];
-		int adjust = imagec->sgnd ? 0 : 1 << (imagec->prec - 1);
-		int min = imagec->sgnd ? -(1 << (imagec->prec - 1)) : 0;
-		int max = imagec->sgnd ?  (1 << (imagec->prec - 1)) - 1 : (1 << imagec->prec) - 1;
-
-		int tw = tilec->x1 - tilec->x0;
-		int w = imagec->w;
-
-		int offset_x = int_ceildivpow2(imagec->x0, imagec->factor);
-		int offset_y = int_ceildivpow2(imagec->y0, imagec->factor);
-
-		int i, j;
-		if(!imagec->data){
-			imagec->data = (int*) opj_malloc(imagec->w * imagec->h * sizeof(int));
-		}
-        if (!imagec->data)
-        {
-            opj_event_msg(tcd->cinfo, EVT_ERROR, "Out of memory\n");
-            return OPJ_FALSE;
-        }
-		if(tcd->tcp->tccps[compno].qmfbid == 1) {
-			for(j = res->y0; j < res->y1; ++j) {
-				for(i = res->x0; i < res->x1; ++i) {
-					int v = tilec->data[i - res->x0 + (j - res->y0) * tw];
-					v += adjust;
-					imagec->data[(i - offset_x) + (j - offset_y) * w] = int_clamp(v, min, max);
-				}
-			}
-		}else{
-			for(j = res->y0; j < res->y1; ++j) {
-				for(i = res->x0; i < res->x1; ++i) {
-					float tmp = ((float*)tilec->data)[i - res->x0 + (j - res->y0) * tw];
-					int v = lrintf(tmp);
-					v += adjust;
-					imagec->data[(i - offset_x) + (j - offset_y) * w] = int_clamp(v, min, max);
-				}
-			}
-		}
-		opj_aligned_free(tilec->data);
-	}
-
-	tile_time = opj_clock() - tile_time;	/* time needed to decode a tile */
-	opj_event_msg(tcd->cinfo, EVT_INFO, "- tile decoded in %f s\n", tile_time);
-
-	if (eof) {
-		return OPJ_FALSE;
-	}
-	
-	return OPJ_TRUE;
-}
-
-void tcd_free_decode(opj_tcd_t *tcd) {
-	opj_tcd_image_t *tcd_image = tcd->tcd_image;	
-    int i = 0;
-    for (i = 0; i < tcd_image->tw * tcd_image->th; i++)
-    {
-        tcd_free_decode_tile(tcd, i);
-    }
-
-	opj_free(tcd_image->tiles);
-}
-
-void tcd_free_decode_tile(opj_tcd_t *tcd, int tileno) {
-    int compno,resno,bandno,precno,cblkno;
-
-	opj_tcd_image_t *tcd_image = tcd->tcd_image;
-
-	opj_tcd_tile_t *tile = &tcd_image->tiles[tileno];
-    if (tile->comps != NULL) {
-        for (compno = 0; compno < tile->numcomps; compno++) {
-            opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
-            for (resno = 0; resno < tilec->numresolutions; resno++) {
-                opj_tcd_resolution_t *res = &tilec->resolutions[resno];
-                for (bandno = 0; bandno < res->numbands; bandno++) {
-                    opj_tcd_band_t *band = &res->bands[bandno];
-                    for (precno = 0; precno < res->ph * res->pw; precno++) {
-                        opj_tcd_precinct_t *prec = &band->precincts[precno];
-                        if (prec->cblks.dec != NULL) {
-                            for (cblkno = 0; cblkno < prec->cw * prec->ch; ++cblkno) {
-                                opj_tcd_cblk_dec_t* cblk = &prec->cblks.dec[cblkno];
-                                opj_free(cblk->data);
-                                opj_free(cblk->segs);
-                            }
-                            opj_free(prec->cblks.dec);
-                        }
-                        if (prec->imsbtree != NULL) tgt_destroy(prec->imsbtree);
-                        if (prec->incltree != NULL) tgt_destroy(prec->incltree);
-
-
-                    }
-                    opj_free(band->precincts);
-				}
-			}
-            opj_free(tilec->resolutions);
-		}
-        opj_free(tile->comps);
-        tile->comps = NULL;
-	}
-}
-
-
-
+/*
+ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2007, Professor Benoit Macq
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2006-2007, Parvatha Elangovan
+ * Copyright (c) 2008;2011-2012, Centre National d'Etudes Spatiales (CNES), France 
+ * Copyright (c) 2012, CS Systemes d'Information, France
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "opj_includes.h"
+
+/* ----------------------------------------------------------------------- */
+
+/* TODO MSD: */
+#ifdef TODO_MSD 
+void tcd_dump(FILE *fd, opj_tcd_t *tcd, opj_tcd_image_t * img) {
+        int tileno, compno, resno, bandno, precno;/*, cblkno;*/
+
+        fprintf(fd, "image {\n");
+        fprintf(fd, "  tw=%d, th=%d x0=%d x1=%d y0=%d y1=%d\n", 
+                img->tw, img->th, tcd->image->x0, tcd->image->x1, tcd->image->y0, tcd->image->y1);
+
+        for (tileno = 0; tileno < img->th * img->tw; tileno++) {
+                opj_tcd_tile_t *tile = &tcd->tcd_image->tiles[tileno];
+                fprintf(fd, "  tile {\n");
+                fprintf(fd, "    x0=%d, y0=%d, x1=%d, y1=%d, numcomps=%d\n",
+                        tile->x0, tile->y0, tile->x1, tile->y1, tile->numcomps);
+                for (compno = 0; compno < tile->numcomps; compno++) {
+                        opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
+                        fprintf(fd, "    tilec {\n");
+                        fprintf(fd,
+                                "      x0=%d, y0=%d, x1=%d, y1=%d, numresolutions=%d\n",
+                                tilec->x0, tilec->y0, tilec->x1, tilec->y1, tilec->numresolutions);
+                        for (resno = 0; resno < tilec->numresolutions; resno++) {
+                                opj_tcd_resolution_t *res = &tilec->resolutions[resno];
+                                fprintf(fd, "\n   res {\n");
+                                fprintf(fd,
+                                        "          x0=%d, y0=%d, x1=%d, y1=%d, pw=%d, ph=%d, numbands=%d\n",
+                                        res->x0, res->y0, res->x1, res->y1, res->pw, res->ph, res->numbands);
+                                for (bandno = 0; bandno < res->numbands; bandno++) {
+                                        opj_tcd_band_t *band = &res->bands[bandno];
+                                        fprintf(fd, "        band {\n");
+                                        fprintf(fd,
+                                                "          x0=%d, y0=%d, x1=%d, y1=%d, stepsize=%f, numbps=%d\n",
+                                                band->x0, band->y0, band->x1, band->y1, band->stepsize, band->numbps);
+                                        for (precno = 0; precno < res->pw * res->ph; precno++) {
+                                                opj_tcd_precinct_t *prec = &band->precincts[precno];
+                                                fprintf(fd, "          prec {\n");
+                                                fprintf(fd,
+                                                        "            x0=%d, y0=%d, x1=%d, y1=%d, cw=%d, ch=%d\n",
+                                                        prec->x0, prec->y0, prec->x1, prec->y1, prec->cw, prec->ch);
+                                                /*
+                                                for (cblkno = 0; cblkno < prec->cw * prec->ch; cblkno++) {
+                                                        opj_tcd_cblk_t *cblk = &prec->cblks[cblkno];
+                                                        fprintf(fd, "            cblk {\n");
+                                                        fprintf(fd,
+                                                                "              x0=%d, y0=%d, x1=%d, y1=%d\n",
+                                                                cblk->x0, cblk->y0, cblk->x1, cblk->y1);
+                                                        fprintf(fd, "            }\n");
+                                                }
+                                                */
+                                                fprintf(fd, "          }\n");
+                                        }
+                                        fprintf(fd, "        }\n");
+                                }
+                                fprintf(fd, "      }\n");
+                        }
+                        fprintf(fd, "    }\n");
+                }
+                fprintf(fd, "  }\n");
+        }
+        fprintf(fd, "}\n");
+}
+#endif
+/**
+* Allocates memory for a decoding code block.
+*/
+static OPJ_BOOL opj_tcd_code_block_dec_allocate (opj_tcd_cblk_dec_t * p_code_block);
+
+/**
+ * Deallocates the decoding data of the given precinct.
+ */
+static void opj_tcd_code_block_dec_deallocate (opj_tcd_precinct_t * p_precinct);
+
+/**
+ * Allocates memory for an encoding code block.
+ */
+static OPJ_BOOL opj_tcd_code_block_enc_allocate (opj_tcd_cblk_enc_t * p_code_block);
+
+/**
+ * Deallocates the encoding data of the given precinct.
+ */
+static void opj_tcd_code_block_enc_deallocate (opj_tcd_precinct_t * p_precinct);
+
+
+/**
+Free the memory allocated for encoding
+ at param tcd TCD handle
+*/
+static void opj_tcd_free_tile(opj_tcd_t *tcd);
+
+
+static OPJ_BOOL opj_tcd_t2_decode ( opj_tcd_t *p_tcd,
+                                    OPJ_BYTE * p_src_data,
+                                    OPJ_UINT32 * p_data_read,
+                                    OPJ_UINT32 p_max_src_size,
+                                    opj_codestream_index_t *p_cstr_index );
+
+static OPJ_BOOL opj_tcd_t1_decode (opj_tcd_t *p_tcd);
+
+static OPJ_BOOL opj_tcd_dwt_decode (opj_tcd_t *p_tcd);
+
+static OPJ_BOOL opj_tcd_mct_decode (opj_tcd_t *p_tcd);
+
+static OPJ_BOOL opj_tcd_dc_level_shift_decode (opj_tcd_t *p_tcd);
+
+
+static OPJ_BOOL opj_tcd_dc_level_shift_encode ( opj_tcd_t *p_tcd );
+
+static OPJ_BOOL opj_tcd_mct_encode ( opj_tcd_t *p_tcd );
+
+static OPJ_BOOL opj_tcd_dwt_encode ( opj_tcd_t *p_tcd );
+
+static OPJ_BOOL opj_tcd_t1_encode ( opj_tcd_t *p_tcd );
+
+static OPJ_BOOL opj_tcd_t2_encode (     opj_tcd_t *p_tcd,
+                                                                    OPJ_BYTE * p_dest_data,
+                                                                    OPJ_UINT32 * p_data_written,
+                                                                    OPJ_UINT32 p_max_dest_size,
+                                                                    opj_codestream_info_t *p_cstr_info );
+
+static OPJ_BOOL opj_tcd_rate_allocate_encode(   opj_tcd_t *p_tcd,
+                                                                                        OPJ_BYTE * p_dest_data,
+                                                                                        OPJ_UINT32 p_max_dest_size,
+                                                                                        opj_codestream_info_t *p_cstr_info );
+
+/* ----------------------------------------------------------------------- */
+
+/**
+Create a new TCD handle
+*/
+opj_tcd_t* opj_tcd_create(OPJ_BOOL p_is_decoder)
+{
+        opj_tcd_t *l_tcd = 00;
+
+        /* create the tcd structure */
+        l_tcd = (opj_tcd_t*) opj_malloc(sizeof(opj_tcd_t));
+        if (!l_tcd) {
+                return 00;
+        }
+        memset(l_tcd,0,sizeof(opj_tcd_t));
+
+        l_tcd->m_is_decoder = p_is_decoder ? 1 : 0;
+
+        l_tcd->tcd_image = (opj_tcd_image_t*)opj_malloc(sizeof(opj_tcd_image_t));
+        if (!l_tcd->tcd_image) {
+                opj_free(l_tcd);
+                return 00;
+        }
+        memset(l_tcd->tcd_image,0,sizeof(opj_tcd_image_t));
+
+        return l_tcd;
+}
+
+
+/* ----------------------------------------------------------------------- */
+
+void opj_tcd_rateallocate_fixed(opj_tcd_t *tcd) {
+        OPJ_UINT32 layno;
+
+        for (layno = 0; layno < tcd->tcp->numlayers; layno++) {
+                opj_tcd_makelayer_fixed(tcd, layno, 1);
+        }
+}
+
+
+void opj_tcd_makelayer( opj_tcd_t *tcd,
+                                                OPJ_UINT32 layno,
+                                                OPJ_FLOAT64 thresh,
+                                                OPJ_UINT32 final)
+{
+        OPJ_UINT32 compno, resno, bandno, precno, cblkno;
+        OPJ_UINT32 passno;
+
+        opj_tcd_tile_t *tcd_tile = tcd->tcd_image->tiles;
+
+        tcd_tile->distolayer[layno] = 0;        /* fixed_quality */
+
+        for (compno = 0; compno < tcd_tile->numcomps; compno++) {
+                opj_tcd_tilecomp_t *tilec = &tcd_tile->comps[compno];
+
+                for (resno = 0; resno < tilec->numresolutions; resno++) {
+                        opj_tcd_resolution_t *res = &tilec->resolutions[resno];
+
+                        for (bandno = 0; bandno < res->numbands; bandno++) {
+                                opj_tcd_band_t *band = &res->bands[bandno];
+
+                                for (precno = 0; precno < res->pw * res->ph; precno++) {
+                                        opj_tcd_precinct_t *prc = &band->precincts[precno];
+
+                                        for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
+                                                opj_tcd_cblk_enc_t *cblk = &prc->cblks.enc[cblkno];
+                                                opj_tcd_layer_t *layer = &cblk->layers[layno];
+                                                OPJ_UINT32 n;
+
+                                                if (layno == 0) {
+                                                        cblk->numpassesinlayers = 0;
+                                                }
+
+                                                n = cblk->numpassesinlayers;
+
+                                                for (passno = cblk->numpassesinlayers; passno < cblk->totalpasses; passno++) {
+                                                        OPJ_UINT32 dr;
+                                                        OPJ_FLOAT64 dd;
+                                                        opj_tcd_pass_t *pass = &cblk->passes[passno];
+
+                                                        if (n == 0) {
+                                                                dr = pass->rate;
+                                                                dd = pass->distortiondec;
+                                                        } else {
+                                                                dr = pass->rate - cblk->passes[n - 1].rate;
+                                                                dd = pass->distortiondec - cblk->passes[n - 1].distortiondec;
+                                                        }
+
+                                                        if (!dr) {
+                                                                if (dd != 0)
+                                                                        n = passno + 1;
+                                                                continue;
+                                                        }
+                                                        if (dd / dr >= thresh)
+                                                                n = passno + 1;
+                                                }
+
+                                                layer->numpasses = n - cblk->numpassesinlayers;
+
+                                                if (!layer->numpasses) {
+                                                        layer->disto = 0;
+                                                        continue;
+                                                }
+
+                                                if (cblk->numpassesinlayers == 0) {
+                                                        layer->len = cblk->passes[n - 1].rate;
+                                                        layer->data = cblk->data;
+                                                        layer->disto = cblk->passes[n - 1].distortiondec;
+                                                } else {
+                                                        layer->len = cblk->passes[n - 1].rate - cblk->passes[cblk->numpassesinlayers - 1].rate;
+                                                        layer->data = cblk->data + cblk->passes[cblk->numpassesinlayers - 1].rate;
+                                                        layer->disto = cblk->passes[n - 1].distortiondec - cblk->passes[cblk->numpassesinlayers - 1].distortiondec;
+                                                }
+
+                                                tcd_tile->distolayer[layno] += layer->disto;    /* fixed_quality */
+
+                                                if (final)
+                                                        cblk->numpassesinlayers = n;
+                                        }
+                                }
+                        }
+                }
+        }
+}
+
+void opj_tcd_makelayer_fixed(opj_tcd_t *tcd, OPJ_UINT32 layno, OPJ_UINT32 final) {
+        OPJ_UINT32 compno, resno, bandno, precno, cblkno;
+        OPJ_INT32 value;                        /*, matrice[tcd_tcp->numlayers][tcd_tile->comps[0].numresolutions][3]; */
+        OPJ_INT32 matrice[10][10][3];
+        OPJ_UINT32 i, j, k;
+
+        opj_cp_t *cp = tcd->cp;
+        opj_tcd_tile_t *tcd_tile = tcd->tcd_image->tiles;
+        opj_tcp_t *tcd_tcp = tcd->tcp;
+
+        for (compno = 0; compno < tcd_tile->numcomps; compno++) {
+                opj_tcd_tilecomp_t *tilec = &tcd_tile->comps[compno];
+
+                for (i = 0; i < tcd_tcp->numlayers; i++) {
+                        for (j = 0; j < tilec->numresolutions; j++) {
+                                for (k = 0; k < 3; k++) {
+                                        matrice[i][j][k] =
+                                                (OPJ_INT32) ((OPJ_FLOAT32)cp->m_specific_param.m_enc.m_matrice[i * tilec->numresolutions * 3 + j * 3 + k]
+                                                * (OPJ_FLOAT32) (tcd->image->comps[compno].prec / 16.0));
+                                }
+                        }
+                }
+
+                for (resno = 0; resno < tilec->numresolutions; resno++) {
+                        opj_tcd_resolution_t *res = &tilec->resolutions[resno];
+
+                        for (bandno = 0; bandno < res->numbands; bandno++) {
+                                opj_tcd_band_t *band = &res->bands[bandno];
+
+                                for (precno = 0; precno < res->pw * res->ph; precno++) {
+                                        opj_tcd_precinct_t *prc = &band->precincts[precno];
+
+                                        for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
+                                                opj_tcd_cblk_enc_t *cblk = &prc->cblks.enc[cblkno];
+                                                opj_tcd_layer_t *layer = &cblk->layers[layno];
+                                                OPJ_UINT32 n;
+                                                OPJ_INT32 imsb = (OPJ_INT32)(tcd->image->comps[compno].prec - cblk->numbps); /* number of bit-plan equal to zero */
+
+                                                /* Correction of the matrix of coefficient to include the IMSB information */
+                                                if (layno == 0) {
+                                                        value = matrice[layno][resno][bandno];
+                                                        if (imsb >= value) {
+                                                                value = 0;
+                                                        } else {
+                                                                value -= imsb;
+                                                        }
+                                                } else {
+                                                        value = matrice[layno][resno][bandno] - matrice[layno - 1][resno][bandno];
+                                                        if (imsb >= matrice[layno - 1][resno][bandno]) {
+                                                                value -= (imsb - matrice[layno - 1][resno][bandno]);
+                                                                if (value < 0) {
+                                                                        value = 0;
+                                                                }
+                                                        }
+                                                }
+
+                                                if (layno == 0) {
+                                                        cblk->numpassesinlayers = 0;
+                                                }
+
+                                                n = cblk->numpassesinlayers;
+                                                if (cblk->numpassesinlayers == 0) {
+                                                        if (value != 0) {
+                                                                n = 3 * (OPJ_UINT32)value - 2 + cblk->numpassesinlayers;
+                                                        } else {
+                                                                n = cblk->numpassesinlayers;
+                                                        }
+                                                } else {
+                                                        n = 3 * (OPJ_UINT32)value + cblk->numpassesinlayers;
+                                                }
+
+                                                layer->numpasses = n - cblk->numpassesinlayers;
+
+                                                if (!layer->numpasses)
+                                                        continue;
+
+                                                if (cblk->numpassesinlayers == 0) {
+                                                        layer->len = cblk->passes[n - 1].rate;
+                                                        layer->data = cblk->data;
+                                                } else {
+                                                        layer->len = cblk->passes[n - 1].rate - cblk->passes[cblk->numpassesinlayers - 1].rate;
+                                                        layer->data = cblk->data + cblk->passes[cblk->numpassesinlayers - 1].rate;
+                                                }
+
+                                                if (final)
+                                                        cblk->numpassesinlayers = n;
+                                        }
+                                }
+                        }
+                }
+        }
+}
+
+OPJ_BOOL opj_tcd_rateallocate(  opj_tcd_t *tcd,
+                                                                OPJ_BYTE *dest,
+                                                                OPJ_UINT32 * p_data_written,
+                                                                OPJ_UINT32 len,
+                                                                opj_codestream_info_t *cstr_info)
+{
+        OPJ_UINT32 compno, resno, bandno, precno, cblkno, layno;
+        OPJ_UINT32 passno;
+        OPJ_FLOAT64 min, max;
+        OPJ_FLOAT64 cumdisto[100];      /* fixed_quality */
+        const OPJ_FLOAT64 K = 1;                /* 1.1; fixed_quality */
+        OPJ_FLOAT64 maxSE = 0;
+
+        opj_cp_t *cp = tcd->cp;
+        opj_tcd_tile_t *tcd_tile = tcd->tcd_image->tiles;
+        opj_tcp_t *tcd_tcp = tcd->tcp;
+
+        min = DBL_MAX;
+        max = 0;
+
+        tcd_tile->numpix = 0;           /* fixed_quality */
+
+        for (compno = 0; compno < tcd_tile->numcomps; compno++) {
+                opj_tcd_tilecomp_t *tilec = &tcd_tile->comps[compno];
+                tilec->numpix = 0;
+
+                for (resno = 0; resno < tilec->numresolutions; resno++) {
+                        opj_tcd_resolution_t *res = &tilec->resolutions[resno];
+
+                        for (bandno = 0; bandno < res->numbands; bandno++) {
+                                opj_tcd_band_t *band = &res->bands[bandno];
+
+                                for (precno = 0; precno < res->pw * res->ph; precno++) {
+                                        opj_tcd_precinct_t *prc = &band->precincts[precno];
+
+                                        for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
+                                                opj_tcd_cblk_enc_t *cblk = &prc->cblks.enc[cblkno];
+
+                                                for (passno = 0; passno < cblk->totalpasses; passno++) {
+                                                        opj_tcd_pass_t *pass = &cblk->passes[passno];
+                                                        OPJ_INT32 dr;
+                                                        OPJ_FLOAT64 dd, rdslope;
+
+                                                        if (passno == 0) {
+                                                                dr = (OPJ_INT32)pass->rate;
+                                                                dd = pass->distortiondec;
+                                                        } else {
+                                                                dr = (OPJ_INT32)(pass->rate - cblk->passes[passno - 1].rate);
+                                                                dd = pass->distortiondec - cblk->passes[passno - 1].distortiondec;
+                                                        }
+
+                                                        if (dr == 0) {
+                                                                continue;
+                                                        }
+
+                                                        rdslope = dd / dr;
+                                                        if (rdslope < min) {
+                                                                min = rdslope;
+                                                        }
+
+                                                        if (rdslope > max) {
+                                                                max = rdslope;
+                                                        }
+                                                } /* passno */
+
+                                                /* fixed_quality */
+                                                tcd_tile->numpix += ((cblk->x1 - cblk->x0) * (cblk->y1 - cblk->y0));
+                                                tilec->numpix += ((cblk->x1 - cblk->x0) * (cblk->y1 - cblk->y0));
+                                        } /* cbklno */
+                                } /* precno */
+                        } /* bandno */
+                } /* resno */
+
+                maxSE += (((OPJ_FLOAT64)(1 << tcd->image->comps[compno].prec) - 1.0)
+                        * ((OPJ_FLOAT64)(1 << tcd->image->comps[compno].prec) -1.0))
+                        * ((OPJ_FLOAT64)(tilec->numpix));
+        } /* compno */
+
+        /* index file */
+        if(cstr_info) {
+                opj_tile_info_t *tile_info = &cstr_info->tile[tcd->tcd_tileno];
+                tile_info->numpix = tcd_tile->numpix;
+                tile_info->distotile = tcd_tile->distotile;
+                tile_info->thresh = (OPJ_FLOAT64 *) opj_malloc(tcd_tcp->numlayers * sizeof(OPJ_FLOAT64));
+        }
+
+        for (layno = 0; layno < tcd_tcp->numlayers; layno++) {
+                OPJ_FLOAT64 lo = min;
+                OPJ_FLOAT64 hi = max;
+                OPJ_BOOL success = OPJ_FALSE;
+                OPJ_UINT32 maxlen = tcd_tcp->rates[layno] ? opj_uint_min(((OPJ_UINT32) ceil(tcd_tcp->rates[layno])), len) : len;
+                OPJ_FLOAT64 goodthresh = 0;
+                OPJ_FLOAT64 stable_thresh = 0;
+                OPJ_UINT32 i;
+                OPJ_FLOAT64 distotarget;                /* fixed_quality */
+
+                /* fixed_quality */
+                distotarget = tcd_tile->distotile - ((K * maxSE) / pow((OPJ_FLOAT32)10, tcd_tcp->distoratio[layno] / 10));
+
+                /* Don't try to find an optimal threshold but rather take everything not included yet, if
+                  -r xx,yy,zz,0   (disto_alloc == 1 and rates == 0)
+                  -q xx,yy,zz,0   (fixed_quality == 1 and distoratio == 0)
+                  ==> possible to have some lossy layers and the last layer for sure lossless */
+                if ( ((cp->m_specific_param.m_enc.m_disto_alloc==1) && (tcd_tcp->rates[layno]>0)) || ((cp->m_specific_param.m_enc.m_fixed_quality==1) && (tcd_tcp->distoratio[layno]>0))) {
+                        opj_t2_t*t2 = opj_t2_create(tcd->image, cp);
+                        OPJ_FLOAT64 thresh = 0;
+
+                        if (t2 == 00) {
+                                return OPJ_FALSE;
+                        }
+
+                        for     (i = 0; i < 128; ++i) {
+                                OPJ_FLOAT64 distoachieved = 0;  /* fixed_quality */
+
+                                thresh = (lo + hi) / 2;
+
+                                opj_tcd_makelayer(tcd, layno, thresh, 0);
+
+                                if (cp->m_specific_param.m_enc.m_fixed_quality) {       /* fixed_quality */
+                                        if(cp->m_specific_param.m_enc.m_cinema){
+                                                if (! opj_t2_encode_packets(t2,tcd->tcd_tileno, tcd_tile, layno + 1, dest, p_data_written, maxlen, cstr_info,tcd->cur_tp_num,tcd->tp_pos,tcd->cur_pino,THRESH_CALC)) {
+
+                                                        lo = thresh;
+                                                        continue;
+                                                }
+                                                else {
+                                                        distoachieved = layno == 0 ?
+                                                                        tcd_tile->distolayer[0] : cumdisto[layno - 1] + tcd_tile->distolayer[layno];
+
+                                                        if (distoachieved < distotarget) {
+                                                                hi=thresh;
+                                                                stable_thresh = thresh;
+                                                                continue;
+                                                        }else{
+                                                                lo=thresh;
+                                                        }
+                                                }
+                                        }else{
+                                                distoachieved = (layno == 0) ?
+                                                                tcd_tile->distolayer[0] : (cumdisto[layno - 1] + tcd_tile->distolayer[layno]);
+
+                                                if (distoachieved < distotarget) {
+                                                        hi = thresh;
+                                                        stable_thresh = thresh;
+                                                        continue;
+                                                }
+                                                lo = thresh;
+                                        }
+                                } else {
+                                        if (! opj_t2_encode_packets(t2, tcd->tcd_tileno, tcd_tile, layno + 1, dest,p_data_written, maxlen, cstr_info,tcd->cur_tp_num,tcd->tp_pos,tcd->cur_pino,THRESH_CALC))
+                                        {
+                                                /* TODO: what to do with l ??? seek / tell ??? */
+                                                /* opj_event_msg(tcd->cinfo, EVT_INFO, "rate alloc: len=%d, max=%d\n", l, maxlen); */
+                                                lo = thresh;
+                                                continue;
+                                        }
+
+                                        hi = thresh;
+                                        stable_thresh = thresh;
+                                }
+                        }
+
+                        success = OPJ_TRUE;
+                        goodthresh = stable_thresh == 0? thresh : stable_thresh;
+
+                        opj_t2_destroy(t2);
+                } else {
+                        success = OPJ_TRUE;
+                        goodthresh = min;
+                }
+
+                if (!success) {
+                        return OPJ_FALSE;
+                }
+
+                if(cstr_info) { /* Threshold for Marcela Index */
+                        cstr_info->tile[tcd->tcd_tileno].thresh[layno] = goodthresh;
+                }
+
+                opj_tcd_makelayer(tcd, layno, goodthresh, 1);
+
+                /* fixed_quality */
+                cumdisto[layno] = (layno == 0) ? tcd_tile->distolayer[0] : (cumdisto[layno - 1] + tcd_tile->distolayer[layno]);
+        }
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_tcd_init( opj_tcd_t *p_tcd,
+                                           opj_image_t * p_image,
+                                           opj_cp_t * p_cp )
+{
+        OPJ_UINT32 l_tile_comp_size;
+
+        p_tcd->image = p_image;
+        p_tcd->cp = p_cp;
+
+        p_tcd->tcd_image->tiles = (opj_tcd_tile_t *) opj_malloc(sizeof(opj_tcd_tile_t));
+        if (! p_tcd->tcd_image->tiles) {
+                return OPJ_FALSE;
+        }
+        memset(p_tcd->tcd_image->tiles,0, sizeof(opj_tcd_tile_t));
+
+        l_tile_comp_size = p_image->numcomps * (OPJ_UINT32)sizeof(opj_tcd_tilecomp_t);
+        p_tcd->tcd_image->tiles->comps = (opj_tcd_tilecomp_t *) opj_malloc(l_tile_comp_size);
+        if (! p_tcd->tcd_image->tiles->comps ) {
+                return OPJ_FALSE;
+        }
+        memset( p_tcd->tcd_image->tiles->comps , 0 , l_tile_comp_size);
+
+        p_tcd->tcd_image->tiles->numcomps = p_image->numcomps;
+        p_tcd->tp_pos = p_cp->m_specific_param.m_enc.m_tp_pos;
+
+        return OPJ_TRUE;
+}
+
+/**
+Destroy a previously created TCD handle
+*/
+void opj_tcd_destroy(opj_tcd_t *tcd) {
+        if (tcd) {
+                opj_tcd_free_tile(tcd);
+
+                if (tcd->tcd_image) {
+                        opj_free(tcd->tcd_image);
+                        tcd->tcd_image = 00;
+                }
+                opj_free(tcd);
+        }
+}
+
+/* ----------------------------------------------------------------------- */
+#define OPJ_MACRO_TCD_ALLOCATE(FUNCTION,TYPE,FRACTION,ELEMENT,FUNCTION_ELEMENT)                                                                                                                                       \
+OPJ_BOOL FUNCTION (     opj_tcd_t *p_tcd,                        \
+                        OPJ_UINT32 p_tile_no                        \
+                        )                                           \
+{                                                                   \
+        OPJ_UINT32 (*l_gain_ptr)(OPJ_UINT32) = 00;                  \
+        OPJ_UINT32 compno, resno, bandno, precno, cblkno;           \
+        opj_tcp_t * l_tcp = 00;                                  \
+        opj_cp_t * l_cp = 00;                                    \
+        opj_tcd_tile_t * l_tile = 00;                            \
+        opj_tccp_t *l_tccp = 00;                                    \
+        opj_tcd_tilecomp_t *l_tilec = 00;                        \
+        opj_image_comp_t * l_image_comp = 00;                       \
+        opj_tcd_resolution_t *l_res = 00;                        \
+        opj_tcd_band_t *l_band = 00;                             \
+        opj_stepsize_t * l_step_size = 00;                          \
+        opj_tcd_precinct_t *l_current_precinct = 00;             \
+        TYPE* l_code_block = 00;                                    \
+        opj_image_t *l_image = 00;                                  \
+        OPJ_UINT32 p,q;                                             \
+        OPJ_UINT32 l_level_no;                                      \
+        OPJ_UINT32 l_pdx, l_pdy;                                    \
+        OPJ_UINT32 l_gain;                                          \
+        OPJ_INT32 l_x0b, l_y0b;                                     \
+        /* extent of precincts , top left, bottom right**/          \
+        OPJ_INT32 l_tl_prc_x_start, l_tl_prc_y_start, l_br_prc_x_end, l_br_prc_y_end;                                                                                                                             \
+        /* number of precinct for a resolution */                   \
+        OPJ_UINT32 l_nb_precincts;                                  \
+        /* room needed to store l_nb_precinct precinct for a resolution */                                                                                                                                        \
+        OPJ_UINT32 l_nb_precinct_size;                              \
+        /* number of code blocks for a precinct*/                   \
+        OPJ_UINT32 l_nb_code_blocks;                                \
+        /* room needed to store l_nb_code_blocks code blocks for a precinct*/                                                                                                                                     \
+        OPJ_UINT32 l_nb_code_blocks_size;                           \
+        /* size of data for a tile */                               \
+        OPJ_UINT32 l_data_size;                                     \
+                                                                    \
+        l_cp = p_tcd->cp;                                           \
+        l_tcp = &(l_cp->tcps[p_tile_no]);                           \
+        l_tile = p_tcd->tcd_image->tiles;                           \
+        l_tccp = l_tcp->tccps;                                      \
+        l_tilec = l_tile->comps;                                    \
+        l_image = p_tcd->image;                                     \
+        l_image_comp = p_tcd->image->comps;                         \
+                                                                    \
+        p = p_tile_no % l_cp->tw;       /* tile coordinates */      \
+        q = p_tile_no / l_cp->tw;                                   \
+        /*fprintf(stderr, "Tile coordinate = %d,%d\n", p, q);*/     \
+                                                                    \
+        /* 4 borders of the tile rescale on the image if necessary */                                                                                                                                             \
+        l_tile->x0 = opj_int_max((OPJ_INT32)(l_cp->tx0 + p * l_cp->tdx), (OPJ_INT32)l_image->x0);                                                                                                                                             \
+        l_tile->y0 = opj_int_max((OPJ_INT32)(l_cp->ty0 + q * l_cp->tdy), (OPJ_INT32)l_image->y0);                                                                                                                                             \
+        l_tile->x1 = opj_int_min((OPJ_INT32)(l_cp->tx0 + (p + 1) * l_cp->tdx), (OPJ_INT32)l_image->x1);                                                                                                                                       \
+        l_tile->y1 = opj_int_min((OPJ_INT32)(l_cp->ty0 + (q + 1) * l_cp->tdy), (OPJ_INT32)l_image->y1);                                                                                                                                       \
+        /* testcase 1888.pdf.asan.35.988 */ \
+        if (l_tccp->numresolutions == 0) { \
+            fprintf(stderr, "tiles require at least one resolution\n"); \
+            return OPJ_FALSE; \
+        } \
+        /*fprintf(stderr, "Tile border = %d,%d,%d,%d\n", l_tile->x0, l_tile->y0,l_tile->x1,l_tile->y1);*/                                                                                                         \
+                                                                    \
+        /*tile->numcomps = image->numcomps; */                      \
+        for(compno = 0; compno < l_tile->numcomps; ++compno) {      \
+                /*fprintf(stderr, "compno = %d/%d\n", compno, l_tile->numcomps);*/                                                                                                                                \
+                                                                    \
+                /* border of each l_tile component (global) */      \
+                l_tilec->x0 = opj_int_ceildiv(l_tile->x0, (OPJ_INT32)l_image_comp->dx);                                                                                                                                          \
+                l_tilec->y0 = opj_int_ceildiv(l_tile->y0, (OPJ_INT32)l_image_comp->dy);                                                                                                                                          \
+                l_tilec->x1 = opj_int_ceildiv(l_tile->x1, (OPJ_INT32)l_image_comp->dx);                                                                                                                                          \
+                l_tilec->y1 = opj_int_ceildiv(l_tile->y1, (OPJ_INT32)l_image_comp->dy);                                                                                                                                          \
+                /*fprintf(stderr, "\tTile compo border = %d,%d,%d,%d\n", l_tilec->x0, l_tilec->y0,l_tilec->x1,l_tilec->y1);*/                                                                                     \
+                                                                    \
+                l_data_size = (OPJ_UINT32)(l_tilec->x1 - l_tilec->x0)           \
+                * (OPJ_UINT32)(l_tilec->y1 - l_tilec->y0) * (OPJ_UINT32)sizeof(OPJ_UINT32 );\
+                l_tilec->numresolutions = l_tccp->numresolutions;   \
+                if (l_tccp->numresolutions < l_cp->m_specific_param.m_dec.m_reduce) {                                                                                                                             \
+                        l_tilec->minimum_num_resolutions = 1;       \
+                }                                                   \
+                else {                                              \
+                        l_tilec->minimum_num_resolutions = l_tccp->numresolutions                                                                                                                                 \
+                        - l_cp->m_specific_param.m_dec.m_reduce;    \
+                }                                                   \
+                                                                    \
+                if (l_tilec->data == 00) {                          \
+                        l_tilec->data = (OPJ_INT32 *) opj_malloc(l_data_size);                                                                                                                                    \
+                        if (! l_tilec->data ) {                     \
+                                return OPJ_FALSE;                   \
+                        }                                           \
+                        /*fprintf(stderr, "\tAllocate data of tilec (int): %d x OPJ_UINT32\n",l_data_size);*/                                                                                                     \
+                                                                    \
+                        l_tilec->data_size = l_data_size;           \
+                }                                                   \
+                else if (l_data_size > l_tilec->data_size) {        \
+                        OPJ_INT32 * new_data = (OPJ_INT32 *) opj_realloc(l_tilec->data, l_data_size);                                                                                                             \
+                        /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to handle tile data\n");                                                                                                 */  \
+                        fprintf(stderr, "Not enough memory to handle tile data\n");                                                                                                                               \
+                        if (! new_data) {                           \
+                                opj_free(l_tilec->data);            \
+                                l_tilec->data = NULL;               \
+                                l_tilec->data_size = 0;             \
+                                return OPJ_FALSE;                   \
+                        }                                           \
+                        l_tilec->data = new_data;                   \
+                        /*fprintf(stderr, "\tReallocate data of tilec (int): from %d to %d x OPJ_UINT32\n", l_tilec->data_size, l_data_size);*/                                                                   \
+                        l_tilec->data_size = l_data_size;           \
+                }                                                   \
+                                                                    \
+                l_data_size = l_tilec->numresolutions * (OPJ_UINT32)sizeof(opj_tcd_resolution_t);                                                                                                                          \
+                                                                    \
+                if (l_tilec->resolutions == 00) {                   \
+                        l_tilec->resolutions = (opj_tcd_resolution_t *) opj_malloc(l_data_size);                                                                                                               \
+                        if (! l_tilec->resolutions ) {              \
+                                return OPJ_FALSE;                   \
+                        }                                           \
+                        /*fprintf(stderr, "\tAllocate resolutions of tilec (opj_tcd_resolution_t): %d\n",l_data_size);*/                                                                                       \
+                        l_tilec->resolutions_size = l_data_size;    \
+                        memset(l_tilec->resolutions,0,l_data_size); \
+                }                                                   \
+                else if (l_data_size > l_tilec->resolutions_size) { \
+                        opj_tcd_resolution_t* new_resolutions = (opj_tcd_resolution_t *) opj_realloc(l_tilec->resolutions, l_data_size);                                                                    \
+                        if (! new_resolutions) {                    \
+                                /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to tile resolutions\n");                                                                                         */  \
+                                fprintf(stderr, "Not enough memory to tile resolutions\n");                                                                                                                       \
+                                opj_free(l_tilec->resolutions);     \
+                                l_tilec->resolutions = NULL;        \
+                                l_tilec->resolutions_size = 0;      \
+                                return OPJ_FALSE;                   \
+                        }                                           \
+                        l_tilec->resolutions = new_resolutions;     \
+                        /*fprintf(stderr, "\tReallocate data of tilec (int): from %d to %d x OPJ_UINT32\n", l_tilec->resolutions_size, l_data_size);*/                                                            \
+                        memset(((OPJ_BYTE*) l_tilec->resolutions)+l_tilec->resolutions_size,0,l_data_size - l_tilec->resolutions_size);                                                                           \
+                        l_tilec->resolutions_size = l_data_size;    \
+                }                                                   \
+                                                                    \
+                l_level_no = l_tilec->numresolutions - 1;           \
+                l_res = l_tilec->resolutions;                       \
+                l_step_size = l_tccp->stepsizes;                    \
+                if (l_tccp->qmfbid == 0) {                          \
+                        l_gain_ptr = &opj_dwt_getgain_real;         \
+                }                                                   \
+                else {                                              \
+                        l_gain_ptr  = &opj_dwt_getgain;             \
+                }                                                   \
+                /*fprintf(stderr, "\tlevel_no=%d\n",l_level_no);*/  \
+                                                                                                                                                                                                                  \
+                for(resno = 0; resno < l_tilec->numresolutions; ++resno) {                                                                                                                                        \
+                        /*fprintf(stderr, "\t\tresno = %d/%d\n", resno, l_tilec->numresolutions);*/                                                                                                               \
+                        OPJ_INT32 tlcbgxstart, tlcbgystart /*, brcbgxend, brcbgyend*/;                                                                                                                                 \
+                        OPJ_UINT32 cbgwidthexpn, cbgheightexpn;                                                                                                                                                   \
+                        OPJ_UINT32 cblkwidthexpn, cblkheightexpn;                                                                                                                                                 \
+                                                                                                                                                                                                                  \
+                        /* border for each resolution level (global) */                                                                                                                                           \
+                        l_res->x0 = opj_int_ceildivpow2(l_tilec->x0, (OPJ_INT32)l_level_no);                                                                                                                                     \
+                        l_res->y0 = opj_int_ceildivpow2(l_tilec->y0, (OPJ_INT32)l_level_no);                                                                                                                                     \
+                        l_res->x1 = opj_int_ceildivpow2(l_tilec->x1, (OPJ_INT32)l_level_no);                                                                                                                                     \
+                        l_res->y1 = opj_int_ceildivpow2(l_tilec->y1, (OPJ_INT32)l_level_no);                                                                                                                                     \
+                        /*fprintf(stderr, "\t\t\tres_x0= %d, res_y0 =%d, res_x1=%d, res_y1=%d\n", l_res->x0, l_res->y0, l_res->x1, l_res->y1);*/                                                                  \
+                        /* p. 35, table A-23, ISO/IEC FDIS154444-1 : 2000 (18 august 2000) */                                                                                                                     \
+                        l_pdx = l_tccp->prcw[resno];                                                                                                                                                              \
+                        l_pdy = l_tccp->prch[resno];                                                                                                                                                              \
+                        /*fprintf(stderr, "\t\t\tpdx=%d, pdy=%d\n", l_pdx, l_pdy);*/                                                                                                                              \
+                        /* p. 64, B.6, ISO/IEC FDIS15444-1 : 2000 (18 august 2000)  */                                                                                                                            \
+                        l_tl_prc_x_start = opj_int_floordivpow2(l_res->x0, (OPJ_INT32)l_pdx) << l_pdx;                                                                                                                           \
+                        l_tl_prc_y_start = opj_int_floordivpow2(l_res->y0, (OPJ_INT32)l_pdy) << l_pdy;                                                                                                                           \
+                        l_br_prc_x_end = opj_int_ceildivpow2(l_res->x1, (OPJ_INT32)l_pdx) << l_pdx;                                                                                                                              \
+                        l_br_prc_y_end = opj_int_ceildivpow2(l_res->y1, (OPJ_INT32)l_pdy) << l_pdy;                                                                                                                              \
+                        /*fprintf(stderr, "\t\t\tprc_x_start=%d, prc_y_start=%d, br_prc_x_end=%d, br_prc_y_end=%d \n", l_tl_prc_x_start, l_tl_prc_y_start, l_br_prc_x_end ,l_br_prc_y_end );*/                    \
+                                                                                                                                                                                                                  \
+                        l_res->pw = (l_res->x0 == l_res->x1) ? 0 : (OPJ_UINT32)((l_br_prc_x_end - l_tl_prc_x_start) >> l_pdx);                                                                                                \
+                        l_res->ph = (l_res->y0 == l_res->y1) ? 0 : (OPJ_UINT32)((l_br_prc_y_end - l_tl_prc_y_start) >> l_pdy);                                                                                                \
+                        /*fprintf(stderr, "\t\t\tres_pw=%d, res_ph=%d\n", l_res->pw, l_res->ph );*/                                                                                                               \
+                                                                                                                                                                                                                  \
+                        l_nb_precincts = l_res->pw * l_res->ph;                                                                                                                                                   \
+                        l_nb_precinct_size = l_nb_precincts * (OPJ_UINT32)sizeof(opj_tcd_precinct_t);                                                                                                                      \
+                        if (resno == 0) {                                                                                                                                                                         \
+                                tlcbgxstart = l_tl_prc_x_start;                                                                                                                                                   \
+                                tlcbgystart = l_tl_prc_y_start;                                                                                                                                                   \
+                                /*brcbgxend = l_br_prc_x_end;*/                                                                                                                                                       \
+                               /* brcbgyend = l_br_prc_y_end;*/                                                                                                                                                       \
+                                cbgwidthexpn = l_pdx;                                                                                                                                                             \
+                                cbgheightexpn = l_pdy;                                                                                                                                                            \
+                                l_res->numbands = 1;                                                                                                                                                              \
+                        }                                                                                                                                                                                         \
+                        else {                                                                                                                                                                                    \
+                                tlcbgxstart = opj_int_ceildivpow2(l_tl_prc_x_start, 1);                                                                                                                               \
+                                tlcbgystart = opj_int_ceildivpow2(l_tl_prc_y_start, 1);                                                                                                                               \
+                                /*brcbgxend = opj_int_ceildivpow2(l_br_prc_x_end, 1);*/                                                                                                                            \
+                                /*brcbgyend = opj_int_ceildivpow2(l_br_prc_y_end, 1);*/                                                                                                                            \
+                                cbgwidthexpn = l_pdx - 1;                                                                                                                                                         \
+                                cbgheightexpn = l_pdy - 1;                                                                                                                                                        \
+                                l_res->numbands = 3;                                                                                                                                                              \
+                        }                                                                                                                                                                                         \
+                                                                                                                                                                                                                  \
+                        cblkwidthexpn = opj_uint_min(l_tccp->cblkw, cbgwidthexpn);                                                                                                                                    \
+                        cblkheightexpn = opj_uint_min(l_tccp->cblkh, cbgheightexpn);                                                                                                                                  \
+                        l_band = l_res->bands;                                                                                                                                                                    \
+                                                                                                                                                                                                                  \
+                        for (bandno = 0; bandno < l_res->numbands; ++bandno) {                                                                                                                                    \
+                                OPJ_INT32 numbps;                                                                                                                                                                 \
+                                /*fprintf(stderr, "\t\t\tband_no=%d/%d\n", bandno, l_res->numbands );*/                                                                                                           \
+                                                                                                                                                                                                                  \
+                                if (resno == 0) {                                                                                                                                                                 \
+                                        l_band->bandno = 0 ;                                                                                                                                                      \
+                                        l_band->x0 = opj_int_ceildivpow2(l_tilec->x0, (OPJ_INT32)l_level_no);                                                                                                                    \
+                                        l_band->y0 = opj_int_ceildivpow2(l_tilec->y0, (OPJ_INT32)l_level_no);                                                                                                                    \
+                                        l_band->x1 = opj_int_ceildivpow2(l_tilec->x1, (OPJ_INT32)l_level_no);                                                                                                                    \
+                                        l_band->y1 = opj_int_ceildivpow2(l_tilec->y1, (OPJ_INT32)l_level_no);                                                                                                                    \
+                                }                                                                                                                                                                                 \
+                                else {                                                                                                                                                                            \
+                                        l_band->bandno = bandno + 1;                                                                                                                                              \
+                                        /* x0b = 1 if bandno = 1 or 3 */                                                                                                                                          \
+                                        l_x0b = l_band->bandno&1;                                                                                                                                                 \
+                                        /* y0b = 1 if bandno = 2 or 3 */                                                                                                                                          \
+                                        l_y0b = (OPJ_INT32)((l_band->bandno)>>1);                                                                                                                                              \
+                                        /* l_band border (global) */                                                                                                                                              \
+                                        l_band->x0 = opj_int_ceildivpow2(l_tilec->x0 - (1 << l_level_no) * l_x0b, (OPJ_INT32)(l_level_no + 1));                                                                                    \
+                                        l_band->y0 = opj_int_ceildivpow2(l_tilec->y0 - (1 << l_level_no) * l_y0b, (OPJ_INT32)(l_level_no + 1));                                                                                    \
+                                        l_band->x1 = opj_int_ceildivpow2(l_tilec->x1 - (1 << l_level_no) * l_x0b, (OPJ_INT32)(l_level_no + 1));                                                                                    \
+                                        l_band->y1 = opj_int_ceildivpow2(l_tilec->y1 - (1 << l_level_no) * l_y0b, (OPJ_INT32)(l_level_no + 1));                                                                                    \
+                                }                                                                                                                                                                                 \
+                                                                                                                                                                                                                  \
+                                /** avoid an if with storing function pointer */                                                                                                                                  \
+                                l_gain = (*l_gain_ptr) (l_band->bandno);                                                                                                                                          \
+                                numbps = (OPJ_INT32)(l_image_comp->prec + l_gain);                                                                                                                                             \
+                                l_band->stepsize = (OPJ_FLOAT32)(((1.0 + l_step_size->mant / 2048.0) * pow(2.0, (OPJ_INT32) (numbps - l_step_size->expn)))) * FRACTION;                                           \
+                                l_band->numbps = l_step_size->expn + (OPJ_INT32)l_tccp->numgbits - 1;      /* WHY -1 ? */                                                                                                    \
+                                                                                                                                                                                                                  \
+                                if (! l_band->precincts) {                                                                                                                                                        \
+                                        l_band->precincts = (opj_tcd_precinct_t *) opj_malloc( /*3 * */ l_nb_precinct_size);                                                                                   \
+                                        if (! l_band->precincts) {                                                                                                                                                \
+                                                return OPJ_FALSE;                                                                                                                                                 \
+                                        }                                                                                                                                                                         \
+                                        /*fprintf(stderr, "\t\t\t\tAllocate precincts of a band (opj_tcd_precinct_t): %d\n",l_nb_precinct_size);     */                                                        \
+                                        memset(l_band->precincts,0,l_nb_precinct_size);                                                                                                                           \
+                                        l_band->precincts_data_size = l_nb_precinct_size;                                                                                                                         \
+                                }                                                                                                                                                                                 \
+                                else if (l_band->precincts_data_size < l_nb_precinct_size) {                                                                                                                      \
+                                                                                                                                                                                                                  \
+                                        opj_tcd_precinct_t * new_precincts = (opj_tcd_precinct_t *) opj_realloc(l_band->precincts,/*3 * */ l_nb_precinct_size);                                             \
+                                        if (! new_precincts) {                                                                                                                                                    \
+                                                /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to handle band precints\n");                                                                    */   \
+                                                fprintf(stderr, "Not enough memory to handle band precints\n");                                                                                                   \
+                                                opj_free(l_band->precincts);                                                                                                                                      \
+                                                l_band->precincts = NULL;                                                                                                                                         \
+                                                l_band->precincts_data_size = 0;                                                                                                                                  \
+                                                return OPJ_FALSE;                                                                                                                                                 \
+                                        }                                                                                                                                                                         \
+                                        l_band->precincts = new_precincts;                                                                                                                                        \
+                                        /*fprintf(stderr, "\t\t\t\tReallocate precincts of a band (opj_tcd_precinct_t): from %d to %d\n",l_band->precincts_data_size, l_nb_precinct_size);*/                   \
+                                        memset(((OPJ_BYTE *) l_band->precincts) + l_band->precincts_data_size,0,l_nb_precinct_size - l_band->precincts_data_size);                                                \
+                                        l_band->precincts_data_size = l_nb_precinct_size;                                                                                                                         \
+                                }                                                                                                                                                                                 \
+                                                                                                                                                                                                                  \
+                                l_current_precinct = l_band->precincts;                                                                                                                                           \
+                                for     (precno = 0; precno < l_nb_precincts; ++precno) {                                                                                                                         \
+                                        OPJ_INT32 tlcblkxstart, tlcblkystart, brcblkxend, brcblkyend;                                                                                                             \
+                                        OPJ_INT32 cbgxstart = tlcbgxstart + (OPJ_INT32)(precno % l_res->pw) * (1 << cbgwidthexpn);                                                                                           \
+                                        OPJ_INT32 cbgystart = tlcbgystart + (OPJ_INT32)(precno / l_res->pw) * (1 << cbgheightexpn);                                                                                          \
+                                        OPJ_INT32 cbgxend = cbgxstart + (1 << cbgwidthexpn);                                                                                                                      \
+                                        OPJ_INT32 cbgyend = cbgystart + (1 << cbgheightexpn);                                                                                                                     \
+                                        /*fprintf(stderr, "\t precno=%d; bandno=%d, resno=%d; compno=%d\n", precno, bandno , resno, compno);*/                                                                    \
+                                        /*fprintf(stderr, "\t tlcbgxstart(=%d) + (precno(=%d) percent res->pw(=%d)) * (1 << cbgwidthexpn(=%d)) \n",tlcbgxstart,precno,l_res->pw,cbgwidthexpn);*/                  \
+                                                                                                                                                                                                                  \
+                                        /* precinct size (global) */                                                                                                                                              \
+                                        /*fprintf(stderr, "\t cbgxstart=%d, l_band->x0 = %d \n",cbgxstart, l_band->x0);*/                                                                                         \
+                                                                                                                                                                                                                  \
+                                        l_current_precinct->x0 = opj_int_max(cbgxstart, l_band->x0);                                                                                                                  \
+                                        l_current_precinct->y0 = opj_int_max(cbgystart, l_band->y0);                                                                                                                  \
+                                        l_current_precinct->x1 = opj_int_min(cbgxend, l_band->x1);                                                                                                                    \
+                                        l_current_precinct->y1 = opj_int_min(cbgyend, l_band->y1);                                                                                                                    \
+                                        /*fprintf(stderr, "\t prc_x0=%d; prc_y0=%d, prc_x1=%d; prc_y1=%d\n",l_current_precinct->x0, l_current_precinct->y0 ,l_current_precinct->x1, l_current_precinct->y1);*/    \
+                                                                                                                                                                                                                  \
+                                        tlcblkxstart = opj_int_floordivpow2(l_current_precinct->x0, (OPJ_INT32)cblkwidthexpn) << cblkwidthexpn;                                                                                  \
+                                        /*fprintf(stderr, "\t tlcblkxstart =%d\n",tlcblkxstart );*/                                                                                                               \
+                                        tlcblkystart = opj_int_floordivpow2(l_current_precinct->y0, (OPJ_INT32)cblkheightexpn) << cblkheightexpn;                                                                                \
+                                        /*fprintf(stderr, "\t tlcblkystart =%d\n",tlcblkystart );*/                                                                                                               \
+                                        brcblkxend = opj_int_ceildivpow2(l_current_precinct->x1, (OPJ_INT32)cblkwidthexpn) << cblkwidthexpn;                                                                                     \
+                                        /*fprintf(stderr, "\t brcblkxend =%d\n",brcblkxend );*/                                                                                                                   \
+                                        brcblkyend = opj_int_ceildivpow2(l_current_precinct->y1, (OPJ_INT32)cblkheightexpn) << cblkheightexpn;                                                                                   \
+                                        /*fprintf(stderr, "\t brcblkyend =%d\n",brcblkyend );*/                                                                                                                   \
+                                        l_current_precinct->cw = (OPJ_UINT32)((brcblkxend - tlcblkxstart) >> cblkwidthexpn);                                                                                                    \
+                                        l_current_precinct->ch = (OPJ_UINT32)((brcblkyend - tlcblkystart) >> cblkheightexpn);                                                                                                   \
+                                                                                                                                                                                                                  \
+                                        l_nb_code_blocks = l_current_precinct->cw * l_current_precinct->ch;                                                                                                       \
+                                        /*fprintf(stderr, "\t\t\t\t precinct_cw = %d x recinct_ch = %d\n",l_current_precinct->cw, l_current_precinct->ch);      */                                                \
+                                        l_nb_code_blocks_size = l_nb_code_blocks * (OPJ_UINT32)sizeof(TYPE);                                                                                                                  \
+                                                                                                                                                                                                                  \
+                                        if (! l_current_precinct->cblks.ELEMENT) {                                                                                                                                \
+                                                l_current_precinct->cblks.ELEMENT = (TYPE*) opj_malloc(l_nb_code_blocks_size);                                                                                    \
+                                                if (! l_current_precinct->cblks.ELEMENT ) {                                                                                                                       \
+                                                        return OPJ_FALSE;                                                                                                                                         \
+                                                }                                                                                                                                                                 \
+                                                /*fprintf(stderr, "\t\t\t\tAllocate cblks of a precinct (opj_tcd_cblk_dec_t): %d\n",l_nb_code_blocks_size);*/                                                  \
+                                                                                                                                                                                                                  \
+                                                memset(l_current_precinct->cblks.ELEMENT,0,l_nb_code_blocks_size);                                                                                                \
+                                                                                                                                                                                                                  \
+                                                l_current_precinct->block_size = l_nb_code_blocks_size;                                                                                                           \
+                                        }                                                                                                                                                                         \
+                                        else if (l_nb_code_blocks_size > l_current_precinct->block_size) {                                                                                                        \
+                                                TYPE *new_ELEMENT = (TYPE*) opj_realloc(l_current_precinct->cblks.ELEMENT, l_nb_code_blocks_size);                                                                \
+                                                if (! new_ELEMENT) {                                                                                                                                              \
+                                                        opj_free(l_current_precinct->cblks.ELEMENT);                                                                                                              \
+                                                        l_current_precinct->cblks.ELEMENT = NULL;                                                                                                                 \
+                                                        l_current_precinct->block_size = 0;                                                                                                                       \
+                                                        /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory for current precinct codeblock element\n");                                              */  \
+                                                        fprintf(stderr, "Not enough memory for current precinct codeblock element\n");                                                                            \
+                                                        return OPJ_FALSE;                                                                                                                                         \
+                                                }                                                                                                                                                                 \
+                                                l_current_precinct->cblks.ELEMENT = new_ELEMENT;                                                                                                                  \
+                                                /*fprintf(stderr, "\t\t\t\tReallocate cblks of a precinct (opj_tcd_cblk_dec_t): from %d to %d\n",l_current_precinct->block_size, l_nb_code_blocks_size);     */\
+                                                                                                                                                                                                                  \
+                                                memset(((OPJ_BYTE *) l_current_precinct->cblks.ELEMENT) + l_current_precinct->block_size                                                                          \
+                                                                ,0                                                                                                                                                \
+                                                                ,l_nb_code_blocks_size - l_current_precinct->block_size);                                                                                         \
+                                                                                                                                                                                                                  \
+                                                l_current_precinct->block_size = l_nb_code_blocks_size;                                                                                                           \
+                                        }                                                                                                                                                                         \
+                                                                                                                                                                                                                  \
+                                        if (! l_current_precinct->incltree) {                                                                                                                                     \
+                                                l_current_precinct->incltree = opj_tgt_create(l_current_precinct->cw,                                                                                              \
+                                                                l_current_precinct->ch);                                                                                                                          \
+                                        }                                                                                                                                                                         \
+                                        else{                                                                                                                                                                     \
+                                                l_current_precinct->incltree = opj_tgt_init(l_current_precinct->incltree,                                                                                             \
+                                                                l_current_precinct->cw,                                                                                                                           \
+                                                                l_current_precinct->ch);                                                                                                                          \
+                                        }                                                                                                                                                                         \
+                                                                                                                                                                                                                  \
+                                        if (! l_current_precinct->incltree)     {                                                                                                                                 \
+                                                fprintf(stderr, "WARNING: No incltree created.\n");                                                                                                               \
+                                                /*return OPJ_FALSE;*/                                                                                                                                             \
+                                        }                                                                                                                                                                         \
+                                                                                                                                                                                                                  \
+                                        if (! l_current_precinct->imsbtree) {                                                                                                                                     \
+                                                l_current_precinct->imsbtree = opj_tgt_create(                                                                                                                     \
+                                                                l_current_precinct->cw,                                                                                                                           \
+                                                                l_current_precinct->ch);                                                                                                                          \
+                                        }                                                                                                                                                                         \
+                                        else {                                                                                                                                                                    \
+                                                l_current_precinct->imsbtree = opj_tgt_init(                                                                                                                          \
+                                                                l_current_precinct->imsbtree,                                                                                                                     \
+                                                                l_current_precinct->cw,                                                                                                                           \
+                                                                l_current_precinct->ch);                                                                                                                          \
+                                        }                                                                                                                                                                         \
+                                                                                                                                                                                                                  \
+                                        if (! l_current_precinct->imsbtree) {                                                                                                                                     \
+                                                fprintf(stderr, "WARNING: No imsbtree created.\n");                                                                                                               \
+                                                /*return OPJ_FALSE;*/                                                                                                                                             \
+                                        }                                                                                                                                                                         \
+                                                                                                                                                                                                                  \
+                                        l_code_block = l_current_precinct->cblks.ELEMENT;                                                                                                                         \
+                                                                                                                                                                                                                  \
+                                        for (cblkno = 0; cblkno < l_nb_code_blocks; ++cblkno) {                                                                                                                   \
+                                                OPJ_INT32 cblkxstart = tlcblkxstart + (OPJ_INT32)(cblkno % l_current_precinct->cw) * (1 << cblkwidthexpn);                                                                   \
+                                                OPJ_INT32 cblkystart = tlcblkystart + (OPJ_INT32)(cblkno / l_current_precinct->cw) * (1 << cblkheightexpn);                                                                  \
+                                                OPJ_INT32 cblkxend = cblkxstart + (1 << cblkwidthexpn);                                                                                                           \
+                                                OPJ_INT32 cblkyend = cblkystart + (1 << cblkheightexpn);                                                                                                          \
+                                                                                                                                                                                                                  \
+                                                /* code-block size (global) */                                                                                                                                    \
+                                                l_code_block->x0 = opj_int_max(cblkxstart, l_current_precinct->x0);                                                                                                   \
+                                                l_code_block->y0 = opj_int_max(cblkystart, l_current_precinct->y0);                                                                                                   \
+                                                l_code_block->x1 = opj_int_min(cblkxend, l_current_precinct->x1);                                                                                                     \
+                                                l_code_block->y1 = opj_int_min(cblkyend, l_current_precinct->y1);                                                                                                     \
+                                                                                                                                                                                                                  \
+                                                if (! FUNCTION_ELEMENT(l_code_block)) {                                                                                                                           \
+                                                        return OPJ_FALSE;                                                                                                                                         \
+                                                }                                                                                                                                                                 \
+                                                ++l_code_block;                                                                                                                                                   \
+                                        }                                                                                                                                                                         \
+                                        ++l_current_precinct;                                                                                                                                                     \
+                                } /* precno */                                                                                                                                                                    \
+                                ++l_band;                                                                                                                                                                         \
+                                ++l_step_size;                                                                                                                                                                    \
+                        } /* bandno */                                                                                                                                                                            \
+                        ++l_res;                                                                                                                                                                                  \
+                        --l_level_no;                                                                                                                                                                             \
+                } /* resno */                                                                                                                                                                                     \
+                ++l_tccp;                                                                                                                                                                                         \
+                ++l_tilec;                                                                                                                                                                                        \
+                ++l_image_comp;                                                                                                                                                                                   \
+        } /* compno */                                                                                                                                                                                            \
+        return OPJ_TRUE;                                                                                                                                                                                          \
+}                                                                                                                                                                                                                 \
+
+
+OPJ_MACRO_TCD_ALLOCATE(opj_tcd_init_encode_tile, opj_tcd_cblk_enc_t, 1.f, enc, opj_tcd_code_block_enc_allocate)
+OPJ_MACRO_TCD_ALLOCATE(opj_tcd_init_decode_tile, opj_tcd_cblk_dec_t, 0.5f, dec, opj_tcd_code_block_dec_allocate)
+
+#undef OPJ_MACRO_TCD_ALLOCATE
+
+/**
+ * Allocates memory for an encoding code block.
+ */
+OPJ_BOOL opj_tcd_code_block_enc_allocate (opj_tcd_cblk_enc_t * p_code_block)
+{
+        if (! p_code_block->data) {
+
+                p_code_block->data = (OPJ_BYTE*) opj_malloc(OPJ_J2K_DEFAULT_CBLK_DATA_SIZE*2); /*why +1 ?*/
+                if(! p_code_block->data) {
+                        return OPJ_FALSE;
+                }
+
+                p_code_block->data[0] = 0;
+                p_code_block->data+=1;
+
+                /* no memset since data */
+                p_code_block->layers = (opj_tcd_layer_t*) opj_malloc(100 * sizeof(opj_tcd_layer_t));
+                if (! p_code_block->layers) {
+                        return OPJ_FALSE;
+                }
+
+                p_code_block->passes = (opj_tcd_pass_t*) opj_malloc(100 * sizeof(opj_tcd_pass_t));
+                if (! p_code_block->passes) {
+                        return OPJ_FALSE;
+                }
+        }
+
+        memset(p_code_block->layers,0,100 * sizeof(opj_tcd_layer_t));
+        memset(p_code_block->passes,0,100 * sizeof(opj_tcd_pass_t));
+
+        return OPJ_TRUE;
+}
+
+/**
+ * Allocates memory for a decoding code block.
+ */
+OPJ_BOOL opj_tcd_code_block_dec_allocate (opj_tcd_cblk_dec_t * p_code_block)
+{
+        OPJ_UINT32 l_seg_size;
+
+        if (! p_code_block->data) {
+
+                p_code_block->data = (OPJ_BYTE*) opj_malloc(OPJ_J2K_DEFAULT_CBLK_DATA_SIZE);
+                if (! p_code_block->data) {
+                        return OPJ_FALSE;
+                }
+                p_code_block->data_max_size = OPJ_J2K_DEFAULT_CBLK_DATA_SIZE;
+                /*fprintf(stderr, "Allocate 8192 elements of code_block->data\n");*/
+
+                l_seg_size = OPJ_J2K_DEFAULT_NB_SEGS * sizeof(opj_tcd_seg_t);
+                p_code_block->segs = (opj_tcd_seg_t *) opj_malloc(l_seg_size);
+                if (! p_code_block->segs) {
+                        return OPJ_FALSE;
+                }
+                memset(p_code_block->segs,0,l_seg_size);
+                /*fprintf(stderr, "Allocate %d elements of code_block->data\n", OPJ_J2K_DEFAULT_NB_SEGS * sizeof(opj_tcd_seg_t));*/
+
+                p_code_block->m_current_max_segs = OPJ_J2K_DEFAULT_NB_SEGS;
+                /*fprintf(stderr, "m_current_max_segs of code_block->data = %d\n", p_code_block->m_current_max_segs);*/
+        }
+        /* TODO */
+        /*p_code_block->numsegs = 0; */
+
+        return OPJ_TRUE;
+}
+
+OPJ_UINT32 opj_tcd_get_decoded_tile_size ( opj_tcd_t *p_tcd )
+{
+        OPJ_UINT32 i;
+        OPJ_UINT32 l_data_size = 0;
+        opj_image_comp_t * l_img_comp = 00;
+        opj_tcd_tilecomp_t * l_tile_comp = 00;
+        opj_tcd_resolution_t * l_res = 00;
+        OPJ_UINT32 l_size_comp, l_remaining;
+
+        l_tile_comp = p_tcd->tcd_image->tiles->comps;
+        l_img_comp = p_tcd->image->comps;
+
+        for (i=0;i<p_tcd->image->numcomps;++i) {
+                l_size_comp = l_img_comp->prec >> 3; /*(/ 8)*/
+                l_remaining = l_img_comp->prec & 7;  /* (%8) */
+
+                if(l_remaining) {
+                        ++l_size_comp;
+                }
+
+                if (l_size_comp == 3) {
+                        l_size_comp = 4;
+                }
+
+                l_res = l_tile_comp->resolutions + l_tile_comp->minimum_num_resolutions - 1;
+                l_data_size += l_size_comp * (OPJ_UINT32)((l_res->x1 - l_res->x0) * (l_res->y1 - l_res->y0));
+                ++l_img_comp;
+                ++l_tile_comp;
+        }
+
+        return l_data_size;
+}
+
+OPJ_BOOL opj_tcd_encode_tile(   opj_tcd_t *p_tcd,
+                                                        OPJ_UINT32 p_tile_no,
+                                                        OPJ_BYTE *p_dest,
+                                                        OPJ_UINT32 * p_data_written,
+                                                        OPJ_UINT32 p_max_length,
+                                                        opj_codestream_info_t *p_cstr_info)
+{
+
+        if (p_tcd->cur_tp_num == 0) {
+
+                p_tcd->tcd_tileno = p_tile_no;
+                p_tcd->tcp = &p_tcd->cp->tcps[p_tile_no];
+
+                /* INDEX >> "Precinct_nb_X et Precinct_nb_Y" */
+                if(p_cstr_info)  {
+                        OPJ_UINT32 l_num_packs = 0;
+                        OPJ_UINT32 i;
+                        opj_tcd_tilecomp_t *l_tilec_idx = &p_tcd->tcd_image->tiles->comps[0];        /* based on component 0 */
+                        opj_tccp_t *l_tccp = p_tcd->tcp->tccps; /* based on component 0 */
+
+                        for (i = 0; i < l_tilec_idx->numresolutions; i++) {
+                                opj_tcd_resolution_t *l_res_idx = &l_tilec_idx->resolutions[i];
+
+                                p_cstr_info->tile[p_tile_no].pw[i] = (int)l_res_idx->pw;
+                                p_cstr_info->tile[p_tile_no].ph[i] = (int)l_res_idx->ph;
+
+                                l_num_packs += l_res_idx->pw * l_res_idx->ph;
+                                p_cstr_info->tile[p_tile_no].pdx[i] = (int)l_tccp->prcw[i];
+                                p_cstr_info->tile[p_tile_no].pdy[i] = (int)l_tccp->prch[i];
+                        }
+                        p_cstr_info->tile[p_tile_no].packet = (opj_packet_info_t*) opj_calloc((size_t)p_cstr_info->numcomps * (size_t)p_cstr_info->numlayers * l_num_packs, sizeof(opj_packet_info_t));
+                }
+                /* << INDEX */
+
+                /* FIXME _ProfStart(PGROUP_DC_SHIFT); */
+                /*---------------TILE-------------------*/
+                if (! opj_tcd_dc_level_shift_encode(p_tcd)) {
+                        return OPJ_FALSE;
+                }
+                /* FIXME _ProfStop(PGROUP_DC_SHIFT); */
+
+                /* FIXME _ProfStart(PGROUP_MCT); */
+                if (! opj_tcd_mct_encode(p_tcd)) {
+                        return OPJ_FALSE;
+                }
+                /* FIXME _ProfStop(PGROUP_MCT); */
+
+                /* FIXME _ProfStart(PGROUP_DWT); */
+                if (! opj_tcd_dwt_encode(p_tcd)) {
+                        return OPJ_FALSE;
+                }
+                /* FIXME  _ProfStop(PGROUP_DWT); */
+
+                /* FIXME  _ProfStart(PGROUP_T1); */
+                if (! opj_tcd_t1_encode(p_tcd)) {
+                        return OPJ_FALSE;
+                }
+                /* FIXME _ProfStop(PGROUP_T1); */
+
+                /* FIXME _ProfStart(PGROUP_RATE); */
+                if (! opj_tcd_rate_allocate_encode(p_tcd,p_dest,p_max_length,p_cstr_info)) {
+                        return OPJ_FALSE;
+                }
+                /* FIXME _ProfStop(PGROUP_RATE); */
+
+        }
+        /*--------------TIER2------------------*/
+
+        /* INDEX */
+        if (p_cstr_info) {
+                p_cstr_info->index_write = 1;
+        }
+        /* FIXME _ProfStart(PGROUP_T2); */
+
+        if (! opj_tcd_t2_encode(p_tcd,p_dest,p_data_written,p_max_length,p_cstr_info)) {
+                return OPJ_FALSE;
+        }
+        /* FIXME _ProfStop(PGROUP_T2); */
+
+        /*---------------CLEAN-------------------*/
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_tcd_decode_tile(   opj_tcd_t *p_tcd,
+                                OPJ_BYTE *p_src,
+                                OPJ_UINT32 p_max_length,
+                                OPJ_UINT32 p_tile_no,
+                                opj_codestream_index_t *p_cstr_index
+                                )
+{
+        OPJ_UINT32 l_data_read;
+        p_tcd->tcd_tileno = p_tile_no;
+        p_tcd->tcp = &(p_tcd->cp->tcps[p_tile_no]);
+
+#ifdef TODO_MSD /* FIXME */
+        /* INDEX >>  */
+        if(p_cstr_info) {
+                OPJ_UINT32 resno, compno, numprec = 0;
+                for (compno = 0; compno < (OPJ_UINT32) p_cstr_info->numcomps; compno++) {
+                        opj_tcp_t *tcp = &p_tcd->cp->tcps[0];
+                        opj_tccp_t *tccp = &tcp->tccps[compno];
+                        opj_tcd_tilecomp_t *tilec_idx = &p_tcd->tcd_image->tiles->comps[compno];
+                        for (resno = 0; resno < tilec_idx->numresolutions; resno++) {
+                                opj_tcd_resolution_t *res_idx = &tilec_idx->resolutions[resno];
+                                p_cstr_info->tile[p_tile_no].pw[resno] = res_idx->pw;
+                                p_cstr_info->tile[p_tile_no].ph[resno] = res_idx->ph;
+                                numprec += res_idx->pw * res_idx->ph;
+                                p_cstr_info->tile[p_tile_no].pdx[resno] = tccp->prcw[resno];
+                                p_cstr_info->tile[p_tile_no].pdy[resno] = tccp->prch[resno];
+                        }
+                }
+                p_cstr_info->tile[p_tile_no].packet = (opj_packet_info_t *) opj_malloc(p_cstr_info->numlayers * numprec * sizeof(opj_packet_info_t));
+                p_cstr_info->packno = 0;
+        }
+        /* << INDEX */
+#endif
+
+        /*--------------TIER2------------------*/
+        /* FIXME _ProfStart(PGROUP_T2); */
+        l_data_read = 0;
+        if (! opj_tcd_t2_decode(p_tcd, p_src, &l_data_read, p_max_length, p_cstr_index))
+        {
+                return OPJ_FALSE;
+        }
+        /* FIXME _ProfStop(PGROUP_T2); */
+
+        /*------------------TIER1-----------------*/
+
+        /* FIXME _ProfStart(PGROUP_T1); */
+        if
+                (! opj_tcd_t1_decode(p_tcd))
+        {
+                return OPJ_FALSE;
+        }
+        /* FIXME _ProfStop(PGROUP_T1); */
+
+        /*----------------DWT---------------------*/
+
+        /* FIXME _ProfStart(PGROUP_DWT); */
+        if
+                (! opj_tcd_dwt_decode(p_tcd))
+        {
+                return OPJ_FALSE;
+        }
+        /* FIXME _ProfStop(PGROUP_DWT); */
+
+        /*----------------MCT-------------------*/
+        /* FIXME _ProfStart(PGROUP_MCT); */
+        if
+                (! opj_tcd_mct_decode(p_tcd))
+        {
+                return OPJ_FALSE;
+        }
+        /* FIXME _ProfStop(PGROUP_MCT); */
+
+        /* FIXME _ProfStart(PGROUP_DC_SHIFT); */
+        if
+                (! opj_tcd_dc_level_shift_decode(p_tcd))
+        {
+                return OPJ_FALSE;
+        }
+        /* FIXME _ProfStop(PGROUP_DC_SHIFT); */
+
+
+        /*---------------TILE-------------------*/
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_tcd_update_tile_data ( opj_tcd_t *p_tcd,
+                                    OPJ_BYTE * p_dest,
+                                    OPJ_UINT32 p_dest_length
+                                    )
+{
+        OPJ_UINT32 i,j,k,l_data_size = 0;
+        opj_image_comp_t * l_img_comp = 00;
+        opj_tcd_tilecomp_t * l_tilec = 00;
+        opj_tcd_resolution_t * l_res;
+        OPJ_UINT32 l_size_comp, l_remaining;
+        OPJ_UINT32 l_stride, l_width,l_height;
+
+        l_data_size = opj_tcd_get_decoded_tile_size(p_tcd);
+        if (l_data_size > p_dest_length) {
+                return OPJ_FALSE;
+        }
+
+        l_tilec = p_tcd->tcd_image->tiles->comps;
+        l_img_comp = p_tcd->image->comps;
+
+        for (i=0;i<p_tcd->image->numcomps;++i) {
+                l_size_comp = l_img_comp->prec >> 3; /*(/ 8)*/
+                l_remaining = l_img_comp->prec & 7;  /* (%8) */
+                l_res = l_tilec->resolutions + l_img_comp->resno_decoded;
+                l_width = (OPJ_UINT32)(l_res->x1 - l_res->x0);
+                l_height = (OPJ_UINT32)(l_res->y1 - l_res->y0);
+                l_stride = (OPJ_UINT32)(l_tilec->x1 - l_tilec->x0) - l_width;
+
+                if (l_remaining) {
+                        ++l_size_comp;
+                }
+
+                if (l_size_comp == 3) {
+                        l_size_comp = 4;
+                }
+
+                switch (l_size_comp)
+                        {
+                        case 1:
+                                {
+                                        OPJ_CHAR * l_dest_ptr = (OPJ_CHAR *) p_dest;
+                                        const OPJ_INT32 * l_src_ptr = l_tilec->data;
+
+                                        if (l_img_comp->sgnd) {
+                                                for (j=0;j<l_height;++j) {
+                                                        for (k=0;k<l_width;++k) {
+                                                                *(l_dest_ptr++) = (OPJ_CHAR) (*(l_src_ptr++));
+                                                        }
+                                                        l_src_ptr += l_stride;
+                                                }
+                                        }
+                                        else {
+                                                for (j=0;j<l_height;++j) {
+                                                        for     (k=0;k<l_width;++k) {
+                                                                *(l_dest_ptr++) = (OPJ_CHAR) ((*(l_src_ptr++))&0xff);
+                                                        }
+                                                        l_src_ptr += l_stride;
+                                                }
+                                        }
+
+                                        p_dest = (OPJ_BYTE *)l_dest_ptr;
+                                }
+                                break;
+                        case 2:
+                                {
+                                        const OPJ_INT32 * l_src_ptr = l_tilec->data;
+                                        OPJ_INT16 * l_dest_ptr = (OPJ_INT16 *) p_dest;
+
+                                        if (l_img_comp->sgnd) {
+                                                for (j=0;j<l_height;++j) {
+                                                        for (k=0;k<l_width;++k) {
+                                                                *(l_dest_ptr++) = (OPJ_INT16) (*(l_src_ptr++));
+                                                        }
+                                                        l_src_ptr += l_stride;
+                                                }
+                                        }
+                                        else {
+                                                for (j=0;j<l_height;++j) {
+                                                        for (k=0;k<l_width;++k) {
+                                                                *(l_dest_ptr++) = (OPJ_INT16) ((*(l_src_ptr++))&0xffff);
+                                                        }
+                                                        l_src_ptr += l_stride;
+                                                }
+                                        }
+
+                                        p_dest = (OPJ_BYTE*) l_dest_ptr;
+                                }
+                                break;
+                        case 4:
+                                {
+                                        OPJ_INT32 * l_dest_ptr = (OPJ_INT32 *) p_dest;
+                                        OPJ_INT32 * l_src_ptr = l_tilec->data;
+
+                                        for (j=0;j<l_height;++j) {
+                                                for (k=0;k<l_width;++k) {
+                                                        *(l_dest_ptr++) = (*(l_src_ptr++));
+                                                }
+                                                l_src_ptr += l_stride;
+                                        }
+
+                                        p_dest = (OPJ_BYTE*) l_dest_ptr;
+                                }
+                                break;
+                }
+
+                ++l_img_comp;
+                ++l_tilec;
+        }
+
+        return OPJ_TRUE;
+}
+
+
+
+
+void opj_tcd_free_tile(opj_tcd_t *p_tcd)
+{
+        OPJ_UINT32 compno, resno, bandno, precno;
+        opj_tcd_tile_t *l_tile = 00;
+        opj_tcd_tilecomp_t *l_tile_comp = 00;
+        opj_tcd_resolution_t *l_res = 00;
+        opj_tcd_band_t *l_band = 00;
+        opj_tcd_precinct_t *l_precinct = 00;
+        OPJ_UINT32 l_nb_resolutions, l_nb_precincts;
+        void (* l_tcd_code_block_deallocate) (opj_tcd_precinct_t *) = 00;
+
+        if (! p_tcd) {
+                return;
+        }
+
+        if (! p_tcd->tcd_image) {
+                return;
+        }
+
+        if (p_tcd->m_is_decoder) {
+                l_tcd_code_block_deallocate = opj_tcd_code_block_dec_deallocate;
+        }
+        else {
+                l_tcd_code_block_deallocate = opj_tcd_code_block_enc_deallocate;
+        }
+
+        l_tile = p_tcd->tcd_image->tiles;
+        if (! l_tile) {
+                return;
+        }
+
+        l_tile_comp = l_tile->comps;
+
+        for (compno = 0; compno < l_tile->numcomps; ++compno) {
+                l_res = l_tile_comp->resolutions;
+                if (l_res) {
+
+                        l_nb_resolutions = l_tile_comp->resolutions_size / sizeof(opj_tcd_resolution_t);
+                        for (resno = 0; resno < l_nb_resolutions; ++resno) {
+                                l_band = l_res->bands;
+                                for     (bandno = 0; bandno < 3; ++bandno) {
+                                        l_precinct = l_band->precincts;
+                                        if (l_precinct) {
+
+                                                l_nb_precincts = l_band->precincts_data_size / sizeof(opj_tcd_precinct_t);
+                                                for (precno = 0; precno < l_nb_precincts; ++precno) {
+                                                        opj_tgt_destroy(l_precinct->incltree);
+                                                        l_precinct->incltree = 00;
+                                                        opj_tgt_destroy(l_precinct->imsbtree);
+                                                        l_precinct->imsbtree = 00;
+                                                        (*l_tcd_code_block_deallocate) (l_precinct);
+                                                        ++l_precinct;
+                                                }
+
+                                                opj_free(l_band->precincts);
+                                                l_band->precincts = 00;
+                                        }
+                                        ++l_band;
+                                } /* for (resno */
+                                ++l_res;
+                        }
+
+                        opj_free(l_tile_comp->resolutions);
+                        l_tile_comp->resolutions = 00;
+                }
+
+                if (l_tile_comp->data) {
+                        opj_free(l_tile_comp->data);
+                        l_tile_comp->data = 00;
+                }
+                ++l_tile_comp;
+        }
+
+        opj_free(l_tile->comps);
+        l_tile->comps = 00;
+        opj_free(p_tcd->tcd_image->tiles);
+        p_tcd->tcd_image->tiles = 00;
+}
+
+
+OPJ_BOOL opj_tcd_t2_decode (opj_tcd_t *p_tcd,
+                            OPJ_BYTE * p_src_data,
+                            OPJ_UINT32 * p_data_read,
+                            OPJ_UINT32 p_max_src_size,
+                            opj_codestream_index_t *p_cstr_index
+                            )
+{
+        opj_t2_t * l_t2;
+
+        l_t2 = opj_t2_create(p_tcd->image, p_tcd->cp);
+        if (l_t2 == 00) {
+                return OPJ_FALSE;
+        }
+
+        if (! opj_t2_decode_packets(
+                                        l_t2,
+                                        p_tcd->tcd_tileno,
+                                        p_tcd->tcd_image->tiles,
+                                        p_src_data,
+                                        p_data_read,
+                                        p_max_src_size,
+                                        p_cstr_index)) {
+                opj_t2_destroy(l_t2);
+                return OPJ_FALSE;
+        }
+
+        opj_t2_destroy(l_t2);
+
+        /*---------------CLEAN-------------------*/
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_tcd_t1_decode ( opj_tcd_t *p_tcd )
+{
+        OPJ_UINT32 compno;
+        opj_t1_t * l_t1;
+        opj_tcd_tile_t * l_tile = p_tcd->tcd_image->tiles;
+        opj_tcd_tilecomp_t* l_tile_comp = l_tile->comps;
+        opj_tccp_t * l_tccp = p_tcd->tcp->tccps;
+
+
+        l_t1 = opj_t1_create();
+        if (l_t1 == 00) {
+                return OPJ_FALSE;
+        }
+
+        for (compno = 0; compno < l_tile->numcomps; ++compno) {
+                /* The +3 is headroom required by the vectorized DWT */
+                if (OPJ_FALSE == opj_t1_decode_cblks(l_t1, l_tile_comp, l_tccp)) {
+                        opj_t1_destroy(l_t1);
+                        return OPJ_FALSE;
+                }
+                ++l_tile_comp;
+                ++l_tccp;
+        }
+
+        opj_t1_destroy(l_t1);
+
+        return OPJ_TRUE;
+}
+
+
+OPJ_BOOL opj_tcd_dwt_decode ( opj_tcd_t *p_tcd )
+{
+        OPJ_UINT32 compno;
+        opj_tcd_tile_t * l_tile = p_tcd->tcd_image->tiles;
+        opj_tcd_tilecomp_t * l_tile_comp = l_tile->comps;
+        opj_tccp_t * l_tccp = p_tcd->tcp->tccps;
+        opj_image_comp_t * l_img_comp = p_tcd->image->comps;
+
+        for (compno = 0; compno < l_tile->numcomps; compno++) {
+                /*
+                if (tcd->cp->reduce != 0) {
+                        tcd->image->comps[compno].resno_decoded =
+                                tile->comps[compno].numresolutions - tcd->cp->reduce - 1;
+                        if (tcd->image->comps[compno].resno_decoded < 0)
+                        {
+                                return false;
+                        }
+                }
+                numres2decode = tcd->image->comps[compno].resno_decoded + 1;
+                if(numres2decode > 0){
+                */
+
+                if (l_tccp->qmfbid == 1) {
+                        if (! opj_dwt_decode(l_tile_comp, l_img_comp->resno_decoded+1)) {
+                                return OPJ_FALSE;
+                        }
+                }
+                else {
+                        if (! opj_dwt_decode_real(l_tile_comp, l_img_comp->resno_decoded+1)) {
+                                return OPJ_FALSE;
+                        }
+                }
+
+                ++l_tile_comp;
+                ++l_img_comp;
+                ++l_tccp;
+        }
+
+        return OPJ_TRUE;
+}
+OPJ_BOOL opj_tcd_mct_decode ( opj_tcd_t *p_tcd )
+{
+        opj_tcd_tile_t * l_tile = p_tcd->tcd_image->tiles;
+        opj_tcp_t * l_tcp = p_tcd->tcp;
+        opj_tcd_tilecomp_t * l_tile_comp = l_tile->comps;
+        OPJ_UINT32 l_samples,i;
+
+        if (! l_tcp->mct) {
+                return OPJ_TRUE;
+        }
+
+        l_samples = (OPJ_UINT32)((l_tile_comp->x1 - l_tile_comp->x0) * (l_tile_comp->y1 - l_tile_comp->y0));
+
+        if (l_tile->numcomps >= 3 ){
+                /* testcase 1336.pdf.asan.47.376 */
+                if ((l_tile->comps[0].x1 - l_tile->comps[0].x0) * (l_tile->comps[0].y1 - l_tile->comps[0].y0) < (OPJ_INT32)l_samples ||
+                    (l_tile->comps[1].x1 - l_tile->comps[1].x0) * (l_tile->comps[1].y1 - l_tile->comps[1].y0) < (OPJ_INT32)l_samples ||
+                    (l_tile->comps[2].x1 - l_tile->comps[2].x0) * (l_tile->comps[2].y1 - l_tile->comps[2].y0) < (OPJ_INT32)l_samples) {
+                        fprintf(stderr, "Tiles don't all have the same dimension. Skip the MCT step.\n");
+                        return OPJ_FALSE;
+                }
+                else if (l_tcp->mct == 2) {
+                        OPJ_BYTE ** l_data;
+
+                        if (! l_tcp->m_mct_decoding_matrix) {
+                                return OPJ_TRUE;
+                        }
+
+                        l_data = (OPJ_BYTE **) opj_malloc(l_tile->numcomps*sizeof(OPJ_BYTE*));
+                        if (! l_data) {
+                                return OPJ_FALSE;
+                        }
+
+                        for (i=0;i<l_tile->numcomps;++i) {
+                                l_data[i] = (OPJ_BYTE*) l_tile_comp->data;
+                                ++l_tile_comp;
+                        }
+
+                        if (! opj_mct_decode_custom(/* MCT data */
+                                                                        (OPJ_BYTE*) l_tcp->m_mct_decoding_matrix,
+                                                                        /* size of components */
+                                                                        l_samples,
+                                                                        /* components */
+                                                                        l_data,
+                                                                        /* nb of components (i.e. size of pData) */
+                                                                        l_tile->numcomps,
+                                                                        /* tells if the data is signed */
+                                                                        p_tcd->image->comps->sgnd)) {
+                                opj_free(l_data);
+                                return OPJ_FALSE;
+                        }
+
+                        opj_free(l_data);
+                }
+                else {
+                        if (l_tcp->tccps->qmfbid == 1) {
+                                opj_mct_decode(     l_tile->comps[0].data,
+                                                        l_tile->comps[1].data,
+                                                        l_tile->comps[2].data,
+                                                        l_samples);
+                        }
+                        else {
+                            opj_mct_decode_real((OPJ_FLOAT32*)l_tile->comps[0].data,
+                                                (OPJ_FLOAT32*)l_tile->comps[1].data,
+                                                (OPJ_FLOAT32*)l_tile->comps[2].data,
+                                                l_samples);
+                        }
+                }
+        }
+        else {
+                /* FIXME need to use opj_event_msg function */
+                fprintf(stderr,"Number of components (%d) is inconsistent with a MCT. Skip the MCT step.\n",l_tile->numcomps);
+        }
+
+        return OPJ_TRUE;
+}
+
+
+OPJ_BOOL opj_tcd_dc_level_shift_decode ( opj_tcd_t *p_tcd )
+{
+        OPJ_UINT32 compno;
+        opj_tcd_tilecomp_t * l_tile_comp = 00;
+        opj_tccp_t * l_tccp = 00;
+        opj_image_comp_t * l_img_comp = 00;
+        opj_tcd_resolution_t* l_res = 00;
+        opj_tcd_tile_t * l_tile;
+        OPJ_UINT32 l_width,l_height,i,j;
+        OPJ_INT32 * l_current_ptr;
+        OPJ_INT32 l_min, l_max;
+        OPJ_UINT32 l_stride;
+
+        l_tile = p_tcd->tcd_image->tiles;
+        l_tile_comp = l_tile->comps;
+        l_tccp = p_tcd->tcp->tccps;
+        l_img_comp = p_tcd->image->comps;
+
+        for (compno = 0; compno < l_tile->numcomps; compno++) {
+                l_res = l_tile_comp->resolutions + l_img_comp->resno_decoded;
+                l_width = (OPJ_UINT32)(l_res->x1 - l_res->x0);
+                l_height = (OPJ_UINT32)(l_res->y1 - l_res->y0);
+                l_stride = (OPJ_UINT32)(l_tile_comp->x1 - l_tile_comp->x0) - l_width;
+
+                assert(l_height == 0 || l_width + l_stride <= l_tile_comp->data_size / l_height); /*MUPDF*/
+
+                if (l_img_comp->sgnd) {
+                        l_min = -(1 << (l_img_comp->prec - 1));
+                        l_max = (1 << (l_img_comp->prec - 1)) - 1;
+                }
+                else {
+            l_min = 0;
+                        l_max = (1 << l_img_comp->prec) - 1;
+                }
+
+                l_current_ptr = l_tile_comp->data;
+
+                if (l_tccp->qmfbid == 1) {
+                        for (j=0;j<l_height;++j) {
+                                for (i = 0; i < l_width; ++i) {
+                                        *l_current_ptr = opj_int_clamp(*l_current_ptr + l_tccp->m_dc_level_shift, l_min, l_max);
+                                        ++l_current_ptr;
+                                }
+                                l_current_ptr += l_stride;
+                        }
+                }
+                else {
+                        for (j=0;j<l_height;++j) {
+                                for (i = 0; i < l_width; ++i) {
+                                        OPJ_FLOAT32 l_value = *((OPJ_FLOAT32 *) l_current_ptr);
+                                        *l_current_ptr = opj_int_clamp((OPJ_INT32)lrintf(l_value) + l_tccp->m_dc_level_shift, l_min, l_max); ;
+                                        ++l_current_ptr;
+                                }
+                                l_current_ptr += l_stride;
+                        }
+                }
+
+                ++l_img_comp;
+                ++l_tccp;
+                ++l_tile_comp;
+        }
+
+        return OPJ_TRUE;
+}
+
+
+
+/**
+ * Deallocates the encoding data of the given precinct.
+ */
+void opj_tcd_code_block_dec_deallocate (opj_tcd_precinct_t * p_precinct)
+{
+        OPJ_UINT32 cblkno , l_nb_code_blocks;
+
+        opj_tcd_cblk_dec_t * l_code_block = p_precinct->cblks.dec;
+        if (l_code_block) {
+                /*fprintf(stderr,"deallocate codeblock:{\n");*/
+                /*fprintf(stderr,"\t x0=%d, y0=%d, x1=%d, y1=%d\n",l_code_block->x0, l_code_block->y0, l_code_block->x1, l_code_block->y1);*/
+                /*fprintf(stderr,"\t numbps=%d, numlenbits=%d, len=%d, numnewpasses=%d, real_num_segs=%d, m_current_max_segs=%d\n ",
+                                l_code_block->numbps, l_code_block->numlenbits, l_code_block->len, l_code_block->numnewpasses, l_code_block->real_num_segs, l_code_block->m_current_max_segs );*/
+
+
+                l_nb_code_blocks = p_precinct->block_size / sizeof(opj_tcd_cblk_dec_t);
+                /*fprintf(stderr,"nb_code_blocks =%d\t}\n", l_nb_code_blocks);*/
+
+                for (cblkno = 0; cblkno < l_nb_code_blocks; ++cblkno) {
+
+                        if (l_code_block->data) {
+                                opj_free(l_code_block->data);
+                                l_code_block->data = 00;
+                        }
+
+                        if (l_code_block->segs) {
+                                opj_free(l_code_block->segs );
+                                l_code_block->segs = 00;
+                        }
+
+                        ++l_code_block;
+                }
+
+                opj_free(p_precinct->cblks.dec);
+                p_precinct->cblks.dec = 00;
+        }
+}
+
+/**
+ * Deallocates the encoding data of the given precinct.
+ */
+void opj_tcd_code_block_enc_deallocate (opj_tcd_precinct_t * p_precinct)
+{       
+        OPJ_UINT32 cblkno , l_nb_code_blocks;
+
+        opj_tcd_cblk_enc_t * l_code_block = p_precinct->cblks.enc;
+        if (l_code_block) {
+                l_nb_code_blocks = p_precinct->block_size / sizeof(opj_tcd_cblk_enc_t);
+                
+                for     (cblkno = 0; cblkno < l_nb_code_blocks; ++cblkno)  {
+                        if (l_code_block->data) {
+                                opj_free(l_code_block->data - 1);
+                                l_code_block->data = 00;
+                        }
+
+                        if (l_code_block->layers) {
+                                opj_free(l_code_block->layers );
+                                l_code_block->layers = 00;
+                        }
+
+                        if (l_code_block->passes) {
+                                opj_free(l_code_block->passes );
+                                l_code_block->passes = 00;
+                        }
+                        ++l_code_block;
+                }
+
+                opj_free(p_precinct->cblks.enc);
+                
+                p_precinct->cblks.enc = 00;
+        }
+}
+
+OPJ_UINT32 opj_tcd_get_encoded_tile_size ( opj_tcd_t *p_tcd )
+{
+        OPJ_UINT32 i,l_data_size = 0;
+        opj_image_comp_t * l_img_comp = 00;
+        opj_tcd_tilecomp_t * l_tilec = 00;
+        OPJ_UINT32 l_size_comp, l_remaining;
+
+        l_tilec = p_tcd->tcd_image->tiles->comps;
+        l_img_comp = p_tcd->image->comps;
+        for (i=0;i<p_tcd->image->numcomps;++i) {
+                l_size_comp = l_img_comp->prec >> 3; /*(/ 8)*/
+                l_remaining = l_img_comp->prec & 7;  /* (%8) */
+
+                if (l_remaining) {
+                        ++l_size_comp;
+                }
+
+                if (l_size_comp == 3) {
+                        l_size_comp = 4;
+                }
+
+                l_data_size += l_size_comp * (OPJ_UINT32)((l_tilec->x1 - l_tilec->x0) * (l_tilec->y1 - l_tilec->y0));
+                ++l_img_comp;
+                ++l_tilec;
+        }
+
+        return l_data_size;
+}
+                
+OPJ_BOOL opj_tcd_dc_level_shift_encode ( opj_tcd_t *p_tcd )
+{
+        OPJ_UINT32 compno;
+        opj_tcd_tilecomp_t * l_tile_comp = 00;
+        opj_tccp_t * l_tccp = 00;
+        opj_image_comp_t * l_img_comp = 00;
+        opj_tcd_tile_t * l_tile;
+        OPJ_UINT32 l_nb_elem,i;
+        OPJ_INT32 * l_current_ptr;
+
+        l_tile = p_tcd->tcd_image->tiles;
+        l_tile_comp = l_tile->comps;
+        l_tccp = p_tcd->tcp->tccps;
+        l_img_comp = p_tcd->image->comps;
+
+        for (compno = 0; compno < l_tile->numcomps; compno++) {
+                l_current_ptr = l_tile_comp->data;
+                l_nb_elem = (OPJ_UINT32)((l_tile_comp->x1 - l_tile_comp->x0) * (l_tile_comp->y1 - l_tile_comp->y0));
+
+                if (l_tccp->qmfbid == 1) {
+                        for     (i = 0; i < l_nb_elem; ++i) {
+                                *l_current_ptr -= l_tccp->m_dc_level_shift ;
+                                ++l_current_ptr;
+                        }
+                }
+                else {
+                        for (i = 0; i < l_nb_elem; ++i) {
+                                *l_current_ptr = (*l_current_ptr - l_tccp->m_dc_level_shift) << 11 ;
+                                ++l_current_ptr;
+                        }
+                }
+
+                ++l_img_comp;
+                ++l_tccp;
+                ++l_tile_comp;
+        }
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_tcd_mct_encode ( opj_tcd_t *p_tcd )
+{
+        opj_tcd_tile_t * l_tile = p_tcd->tcd_image->tiles;
+        opj_tcd_tilecomp_t * l_tile_comp = p_tcd->tcd_image->tiles->comps;
+        OPJ_UINT32 samples = (OPJ_UINT32)((l_tile_comp->x1 - l_tile_comp->x0) * (l_tile_comp->y1 - l_tile_comp->y0));
+        OPJ_UINT32 i;
+        OPJ_BYTE ** l_data = 00;
+        opj_tcp_t * l_tcp = p_tcd->tcp;
+
+        if(!p_tcd->tcp->mct) {
+                return OPJ_TRUE;
+        }
+
+        if (p_tcd->tcp->mct == 2) {
+                if (! p_tcd->tcp->m_mct_coding_matrix) {
+                        return OPJ_TRUE;
+                }
+
+        l_data = (OPJ_BYTE **) opj_malloc(l_tile->numcomps*sizeof(OPJ_BYTE*));
+                if (! l_data) {
+                        return OPJ_FALSE;
+                }
+
+                for (i=0;i<l_tile->numcomps;++i) {
+                        l_data[i] = (OPJ_BYTE*) l_tile_comp->data;
+                        ++l_tile_comp;
+                }
+
+                if (! opj_mct_encode_custom(/* MCT data */
+                                        (OPJ_BYTE*) p_tcd->tcp->m_mct_coding_matrix,
+                                        /* size of components */
+                                        samples,
+                                        /* components */
+                                        l_data,
+                                        /* nb of components (i.e. size of pData) */
+                                        l_tile->numcomps,
+                                        /* tells if the data is signed */
+                                        p_tcd->image->comps->sgnd) )
+                {
+            opj_free(l_data);
+                        return OPJ_FALSE;
+                }
+
+                opj_free(l_data);
+        }
+        else if (l_tcp->tccps->qmfbid == 0) {
+                opj_mct_encode_real(l_tile->comps[0].data, l_tile->comps[1].data, l_tile->comps[2].data, samples);
+        }
+        else {
+                opj_mct_encode(l_tile->comps[0].data, l_tile->comps[1].data, l_tile->comps[2].data, samples);
+        }
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_tcd_dwt_encode ( opj_tcd_t *p_tcd )
+{
+        opj_tcd_tile_t * l_tile = p_tcd->tcd_image->tiles;
+        opj_tcd_tilecomp_t * l_tile_comp = p_tcd->tcd_image->tiles->comps;
+        opj_tccp_t * l_tccp = p_tcd->tcp->tccps;
+        OPJ_UINT32 compno;
+
+        for (compno = 0; compno < l_tile->numcomps; ++compno) {
+                if (l_tccp->qmfbid == 1) {
+                        if (! opj_dwt_encode(l_tile_comp)) {
+                                return OPJ_FALSE;
+                        }
+                }
+                else if (l_tccp->qmfbid == 0) {
+                        if (! opj_dwt_encode_real(l_tile_comp)) {
+                                return OPJ_FALSE;
+                        }
+                }
+
+                ++l_tile_comp;
+                ++l_tccp;
+        }
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_tcd_t1_encode ( opj_tcd_t *p_tcd )
+{
+        opj_t1_t * l_t1;
+        const OPJ_FLOAT64 * l_mct_norms;
+        opj_tcp_t * l_tcp = p_tcd->tcp;
+
+        l_t1 = opj_t1_create();
+        if (l_t1 == 00) {
+                return OPJ_FALSE;
+        }
+
+        if (l_tcp->mct == 1) {
+                /* irreversible encoding */
+                if (l_tcp->tccps->qmfbid == 0) {
+                        l_mct_norms = opj_mct_get_mct_norms_real();
+                }
+                else {
+                        l_mct_norms = opj_mct_get_mct_norms();
+                }
+        }
+        else {
+                l_mct_norms = (const OPJ_FLOAT64 *) (l_tcp->mct_norms);
+        }
+
+        if (! opj_t1_encode_cblks(l_t1, p_tcd->tcd_image->tiles , l_tcp, l_mct_norms)) {
+        opj_t1_destroy(l_t1);
+                return OPJ_FALSE;
+        }
+
+        opj_t1_destroy(l_t1);
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_tcd_t2_encode (opj_tcd_t *p_tcd,
+                                                OPJ_BYTE * p_dest_data,
+                                                OPJ_UINT32 * p_data_written,
+                                                OPJ_UINT32 p_max_dest_size,
+                                                opj_codestream_info_t *p_cstr_info )
+{
+        opj_t2_t * l_t2;
+
+        l_t2 = opj_t2_create(p_tcd->image, p_tcd->cp);
+        if (l_t2 == 00) {
+                return OPJ_FALSE;
+        }
+
+        if (! opj_t2_encode_packets(
+                                        l_t2,
+                                        p_tcd->tcd_tileno,
+                                        p_tcd->tcd_image->tiles,
+                                        p_tcd->tcp->numlayers,
+                                        p_dest_data,
+                                        p_data_written,
+                                        p_max_dest_size,
+                                        p_cstr_info,
+                                        p_tcd->tp_num,
+                                        p_tcd->tp_pos,
+                                        p_tcd->cur_pino,
+                                        FINAL_PASS))
+        {
+                opj_t2_destroy(l_t2);
+                return OPJ_FALSE;
+        }
+
+        opj_t2_destroy(l_t2);
+
+        /*---------------CLEAN-------------------*/
+        return OPJ_TRUE;
+}
+
+
+OPJ_BOOL opj_tcd_rate_allocate_encode(  opj_tcd_t *p_tcd,
+                                                                            OPJ_BYTE * p_dest_data,
+                                                                            OPJ_UINT32 p_max_dest_size,
+                                                                            opj_codestream_info_t *p_cstr_info )
+{
+        opj_cp_t * l_cp = p_tcd->cp;
+        OPJ_UINT32 l_nb_written = 0;
+
+        if (p_cstr_info)  {
+                p_cstr_info->index_write = 0;
+        }
+
+        if (l_cp->m_specific_param.m_enc.m_disto_alloc|| l_cp->m_specific_param.m_enc.m_fixed_quality)  {
+                /* fixed_quality */
+                /* Normal Rate/distortion allocation */
+                if (! opj_tcd_rateallocate(p_tcd, p_dest_data,&l_nb_written, p_max_dest_size, p_cstr_info)) {
+                        return OPJ_FALSE;
+                }
+        }
+        else {
+                /* Fixed layer allocation */
+                opj_tcd_rateallocate_fixed(p_tcd);
+        }
+
+        return OPJ_TRUE;
+}
+
+
+OPJ_BOOL opj_tcd_copy_tile_data (       opj_tcd_t *p_tcd,
+                                                                    OPJ_BYTE * p_src,
+                                                                    OPJ_UINT32 p_src_length )
+{
+        OPJ_UINT32 i,j,l_data_size = 0;
+        opj_image_comp_t * l_img_comp = 00;
+        opj_tcd_tilecomp_t * l_tilec = 00;
+        OPJ_UINT32 l_size_comp, l_remaining;
+        OPJ_UINT32 l_nb_elem;
+
+        l_data_size = opj_tcd_get_encoded_tile_size(p_tcd);
+        if (l_data_size != p_src_length) {
+                return OPJ_FALSE;
+        }
+
+        l_tilec = p_tcd->tcd_image->tiles->comps;
+        l_img_comp = p_tcd->image->comps;
+        for (i=0;i<p_tcd->image->numcomps;++i) {
+                l_size_comp = l_img_comp->prec >> 3; /*(/ 8)*/
+                l_remaining = l_img_comp->prec & 7;  /* (%8) */
+                l_nb_elem = (OPJ_UINT32)((l_tilec->x1 - l_tilec->x0) * (l_tilec->y1 - l_tilec->y0));
+
+                if (l_remaining) {
+                        ++l_size_comp;
+                }
+
+                if (l_size_comp == 3) {
+                        l_size_comp = 4;
+                }
+
+                switch (l_size_comp) {
+                        case 1:
+                                {
+                                        OPJ_CHAR * l_src_ptr = (OPJ_CHAR *) p_src;
+                                        OPJ_INT32 * l_dest_ptr = l_tilec->data;
+
+                                        if (l_img_comp->sgnd) {
+                                                for (j=0;j<l_nb_elem;++j) {
+                                                        *(l_dest_ptr++) = (OPJ_INT32) (*(l_src_ptr++));
+                                                }
+                                        }
+                                        else {
+                                                for (j=0;j<l_nb_elem;++j) {
+                                                        *(l_dest_ptr++) = (*(l_src_ptr++))&0xff;
+                                                }
+                                        }
+
+                                        p_src = (OPJ_BYTE*) l_src_ptr;
+                                }
+                                break;
+                        case 2:
+                                {
+                                        OPJ_INT32 * l_dest_ptr = l_tilec->data;
+                                        OPJ_INT16 * l_src_ptr = (OPJ_INT16 *) p_src;
+
+                                        if (l_img_comp->sgnd) {
+                                                for (j=0;j<l_nb_elem;++j) {
+                                                        *(l_dest_ptr++) = (OPJ_INT32) (*(l_src_ptr++));
+                                                }
+                                        }
+                                        else {
+                                                for (j=0;j<l_nb_elem;++j) {
+                                                        *(l_dest_ptr++) = (*(l_src_ptr++))&0xffff;
+                                                }
+                                        }
+
+                                        p_src = (OPJ_BYTE*) l_src_ptr;
+                                }
+                                break;
+                        case 4:
+                                {
+                                        OPJ_INT32 * l_src_ptr = (OPJ_INT32 *) p_src;
+                                        OPJ_INT32 * l_dest_ptr = l_tilec->data;
+
+                                        for (j=0;j<l_nb_elem;++j) {
+                                                *(l_dest_ptr++) = (OPJ_INT32) (*(l_src_ptr++));
+                                        }
+
+                                        p_src = (OPJ_BYTE*) l_src_ptr;
+                                }
+                                break;
+                }
+
+                ++l_img_comp;
+                ++l_tilec;
+        }
+
+        return OPJ_TRUE;
+}
diff --git a/Source/LibOpenJPEG/tcd.h b/Source/LibOpenJPEG/tcd.h
index 6333a73..11aec81 100644
--- a/Source/LibOpenJPEG/tcd.h
+++ b/Source/LibOpenJPEG/tcd.h
@@ -1,286 +1,348 @@
-/*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
- * Copyright (c) 2001-2003, David Janssens
- * Copyright (c) 2002-2003, Yannick Verschueren
- * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef __TCD_H
-#define __TCD_H
-/**
- at file tcd.h
- at brief Implementation of a tile coder/decoder (TCD)
-
-The functions in TCD.C have for goal to encode or decode each tile independently from
-each other. The functions in TCD.C are used by some function in J2K.C.
-*/
-
-/** @defgroup TCD TCD - Implementation of a tile coder/decoder */
-/*@{*/
-
-/**
-FIXME: documentation
-*/
-typedef struct opj_tcd_seg {
-  unsigned char** data;
-  int dataindex;
-  int numpasses;
-  int len;
-  int maxpasses;
-  int numnewpasses;
-  int newlen;
-} opj_tcd_seg_t;
-
-/**
-FIXME: documentation
-*/
-typedef struct opj_tcd_pass {
-  int rate;
-  double distortiondec;
-  int term, len;
-} opj_tcd_pass_t;
-
-/**
-FIXME: documentation
-*/
-typedef struct opj_tcd_layer {
-  int numpasses;		/* Number of passes in the layer */
-  int len;			/* len of information */
-  double disto;			/* add for index (Cfr. Marcela) */
-  unsigned char *data;		/* data */
-} opj_tcd_layer_t;
-
-/**
-FIXME: documentation
-*/
-typedef struct opj_tcd_cblk_enc {
-  unsigned char* data;	/* Data */
-  opj_tcd_layer_t* layers;	/* layer information */
-  opj_tcd_pass_t* passes;	/* information about the passes */
-  int x0, y0, x1, y1;		/* dimension of the code-blocks : left upper corner (x0, y0) right low corner (x1,y1) */
-  int numbps;
-  int numlenbits;
-  int numpasses;		/* number of pass already done for the code-blocks */
-  int numpassesinlayers;	/* number of passes in the layer */
-  int totalpasses;		/* total number of passes */
-} opj_tcd_cblk_enc_t;
-
-typedef struct opj_tcd_cblk_dec {
-  unsigned char* data;	/* Data */
-  opj_tcd_seg_t* segs;		/* segments informations */
-	int x0, y0, x1, y1;		/* dimension of the code-blocks : left upper corner (x0, y0) right low corner (x1,y1) */
-  int numbps;
-  int numlenbits;
-  int len;			/* length */
-  int numnewpasses;		/* number of pass added to the code-blocks */
-  int numsegs;			/* number of segments */
-} opj_tcd_cblk_dec_t;
-
-/**
-FIXME: documentation
-*/
-typedef struct opj_tcd_precinct {
-  int x0, y0, x1, y1;		/* dimension of the precinct : left upper corner (x0, y0) right low corner (x1,y1) */
-  int cw, ch;			/* number of precinct in width and heigth */
-  union{		/* code-blocks informations */
-	  opj_tcd_cblk_enc_t* enc;
-	  opj_tcd_cblk_dec_t* dec;
-  } cblks;
-  opj_tgt_tree_t *incltree;		/* inclusion tree */
-  opj_tgt_tree_t *imsbtree;		/* IMSB tree */
-} opj_tcd_precinct_t;
-
-/**
-FIXME: documentation
-*/
-typedef struct opj_tcd_band {
-  int x0, y0, x1, y1;		/* dimension of the subband : left upper corner (x0, y0) right low corner (x1,y1) */
-  int bandno;
-  opj_tcd_precinct_t *precincts;	/* precinct information */
-  int numbps;
-  float stepsize;
-} opj_tcd_band_t;
-
-/**
-FIXME: documentation
-*/
-typedef struct opj_tcd_resolution {
-  int x0, y0, x1, y1;		/* dimension of the resolution level : left upper corner (x0, y0) right low corner (x1,y1) */
-  int pw, ph;
-  int numbands;			/* number sub-band for the resolution level */
-  opj_tcd_band_t bands[3];		/* subband information */
-} opj_tcd_resolution_t;
-
-/**
-FIXME: documentation
-*/
-typedef struct opj_tcd_tilecomp {
-  int x0, y0, x1, y1;		/* dimension of component : left upper corner (x0, y0) right low corner (x1,y1) */
-  int numresolutions;		/* number of resolutions level */
-  opj_tcd_resolution_t *resolutions;	/* resolutions information */
-  int *data;			/* data of the component */
-  int numpix;			/* add fixed_quality */
-} opj_tcd_tilecomp_t;
-
-/**
-FIXME: documentation
-*/
-typedef struct opj_tcd_tile {
-  int x0, y0, x1, y1;		/* dimension of the tile : left upper corner (x0, y0) right low corner (x1,y1) */
-  int numcomps;			/* number of components in tile */
-  opj_tcd_tilecomp_t *comps;	/* Components information */
-  int numpix;			/* add fixed_quality */
-  double distotile;		/* add fixed_quality */
-  double distolayer[100];	/* add fixed_quality */
-  /** packet number */
-  int packno;
-} opj_tcd_tile_t;
-
-/**
-FIXME: documentation
-*/
-typedef struct opj_tcd_image {
-  int tw, th;			/* number of tiles in width and heigth */
-  opj_tcd_tile_t *tiles;		/* Tiles information */
-} opj_tcd_image_t;
-
-/**
-Tile coder/decoder
-*/
-typedef struct opj_tcd {
-	/** Position of the tilepart flag in Progression order*/
-	int tp_pos;
-	/** Tile part number*/
-	int tp_num;
-	/** Current tile part number*/
-	int cur_tp_num;
-	/** Total number of tileparts of the current tile*/
-	int cur_totnum_tp;
-	/** Current Packet iterator number */
-	int cur_pino;
-	/** codec context */
-	opj_common_ptr cinfo;
-
-	/** info on each image tile */
-	opj_tcd_image_t *tcd_image;
-	/** image */
-	opj_image_t *image;
-	/** coding parameters */
-	opj_cp_t *cp;
-	/** pointer to the current encoded/decoded tile */
-	opj_tcd_tile_t *tcd_tile;
-	/** coding/decoding parameters common to all tiles */
-	opj_tcp_t *tcp;
-	/** current encoded/decoded tile */
-	int tcd_tileno;
-	/** Time taken to encode a tile*/
-	double encoding_time;
-} opj_tcd_t;
-
-/** @name Exported functions */
-/*@{*/
-/* ----------------------------------------------------------------------- */
-
-/**
-Dump the content of a tcd structure
-*/
-void tcd_dump(FILE *fd, opj_tcd_t *tcd, opj_tcd_image_t *img);
-/**
-Create a new TCD handle
- at param cinfo Codec context info
- at return Returns a new TCD handle if successful returns NULL otherwise
-*/
-opj_tcd_t* tcd_create(opj_common_ptr cinfo);
-/**
-Destroy a previously created TCD handle
- at param tcd TCD handle to destroy
-*/
-void tcd_destroy(opj_tcd_t *tcd);
-/**
-Initialize the tile coder (allocate the memory)
- at param tcd TCD handle
- at param image Raw image
- at param cp Coding parameters
- at param curtileno Number that identifies the tile that will be encoded
-*/
-void tcd_malloc_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int curtileno);
-/**
-Free the memory allocated for encoding
- at param tcd TCD handle
-*/
-void tcd_free_encode(opj_tcd_t *tcd);
-/**
-Initialize the tile coder (reuses the memory allocated by tcd_malloc_encode)
- at param tcd TCD handle
- at param image Raw image
- at param cp Coding parameters
- at param curtileno Number that identifies the tile that will be encoded
-*/
-void tcd_init_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int curtileno);
-/**
-Initialize the tile decoder
- at param tcd TCD handle
- at param image Raw image
- at param cp Coding parameters
-*/
-void tcd_malloc_decode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp);
-void tcd_malloc_decode_tile(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int tileno, opj_codestream_info_t *cstr_info);
-void tcd_makelayer_fixed(opj_tcd_t *tcd, int layno, int final);
-void tcd_rateallocate_fixed(opj_tcd_t *tcd);
-void tcd_makelayer(opj_tcd_t *tcd, int layno, double thresh, int final);
-opj_bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_codestream_info_t *cstr_info);
-/**
-Encode a tile from the raw image into a buffer
- at param tcd TCD handle
- at param tileno Number that identifies one of the tiles to be encoded
- at param dest Destination buffer
- at param len Length of destination buffer
- at param cstr_info Codestream information structure 
- at return 
-*/
-int tcd_encode_tile(opj_tcd_t *tcd, int tileno, unsigned char *dest, int len, opj_codestream_info_t *cstr_info);
-/**
-Decode a tile from a buffer into a raw image
- at param tcd TCD handle
- at param src Source buffer
- at param len Length of source buffer
- at param tileno Number that identifies one of the tiles to be decoded
- at param cstr_info Codestream information structure
-*/
-opj_bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno, opj_codestream_info_t *cstr_info);
-/**
-Free the memory allocated for decoding
- at param tcd TCD handle
-*/
-void tcd_free_decode(opj_tcd_t *tcd);
-void tcd_free_decode_tile(opj_tcd_t *tcd, int tileno);
-
-/* ----------------------------------------------------------------------- */
-/*@}*/
-
-/*@}*/
-
-#endif /* __TCD_H */
+/*
+ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2007, Professor Benoit Macq
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2008;2011-2012, Centre National d'Etudes Spatiales (CNES), France 
+ * Copyright (c) 2012, CS Systemes d'Information, France
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef __TCD_H
+#define __TCD_H
+/**
+ at file tcd.h
+ at brief Implementation of a tile coder/decoder (TCD)
+
+The functions in TCD.C encode or decode each tile independently from
+each other. The functions in TCD.C are used by other functions in J2K.C.
+*/
+
+/** @defgroup TCD TCD - Implementation of a tile coder/decoder */
+/*@{*/
+
+/**
+FIXME DOC
+*/
+typedef struct opj_tcd_seg {
+	OPJ_BYTE ** data;
+	OPJ_UINT32 dataindex;
+	OPJ_UINT32 numpasses;
+	OPJ_UINT32 real_num_passes;
+	OPJ_UINT32 len;
+	OPJ_UINT32 maxpasses;
+	OPJ_UINT32 numnewpasses;
+	OPJ_UINT32 newlen;
+} opj_tcd_seg_t;
+
+/**
+FIXME DOC
+*/
+typedef struct opj_tcd_pass {
+	OPJ_UINT32 rate;
+	OPJ_FLOAT64 distortiondec;
+	OPJ_UINT32 len;
+	OPJ_UINT32 term : 1;
+} opj_tcd_pass_t;
+
+/**
+FIXME DOC
+*/
+typedef struct opj_tcd_layer {
+	OPJ_UINT32 numpasses;		/* Number of passes in the layer */
+	OPJ_UINT32 len;				/* len of information */
+	OPJ_FLOAT64 disto;			/* add for index (Cfr. Marcela) */
+	OPJ_BYTE *data;				/* data */
+} opj_tcd_layer_t;
+
+/**
+FIXME DOC
+*/
+typedef struct opj_tcd_cblk_enc {
+	OPJ_BYTE* data;					/* Data */
+	opj_tcd_layer_t* layers;		/* layer information */
+	opj_tcd_pass_t* passes;		/* information about the passes */
+	OPJ_INT32 x0, y0, x1, y1;		/* dimension of the code-blocks : left upper corner (x0, y0) right low corner (x1,y1) */
+	OPJ_UINT32 numbps;
+	OPJ_UINT32 numlenbits;
+	OPJ_UINT32 numpasses;			/* number of pass already done for the code-blocks */
+	OPJ_UINT32 numpassesinlayers;	/* number of passes in the layer */
+	OPJ_UINT32 totalpasses;			/* total number of passes */
+} opj_tcd_cblk_enc_t;
+
+
+typedef struct opj_tcd_cblk_dec {
+	OPJ_BYTE * data;				/* Data */
+	opj_tcd_seg_t* segs;			/* segments information */
+	OPJ_INT32 x0, y0, x1, y1;		/* position of the code-blocks : left upper corner (x0, y0) right low corner (x1,y1) */
+	OPJ_UINT32 numbps;
+	OPJ_UINT32 numlenbits;
+    OPJ_UINT32 data_max_size;		/* Size of allocated data buffer */
+	OPJ_UINT32 data_current_size;	/* Size of used data buffer */
+	OPJ_UINT32 numnewpasses;		/* number of pass added to the code-blocks */
+	OPJ_UINT32 numsegs;				/* number of segments */
+	OPJ_UINT32 real_num_segs;
+	OPJ_UINT32 m_current_max_segs;
+} opj_tcd_cblk_dec_t;
+
+/**
+FIXME DOC
+*/
+typedef struct opj_tcd_precinct {
+	OPJ_INT32 x0, y0, x1, y1;		/* dimension of the precinct : left upper corner (x0, y0) right low corner (x1,y1) */
+	OPJ_UINT32 cw, ch;				/* number of precinct in width and height */
+	union{							/* code-blocks information */
+		opj_tcd_cblk_enc_t* enc;
+		opj_tcd_cblk_dec_t* dec;
+	} cblks;
+	OPJ_UINT32 block_size;			/* size taken by cblks (in bytes) */
+	opj_tgt_tree_t *incltree;	    /* inclusion tree */
+	opj_tgt_tree_t *imsbtree;	    /* IMSB tree */
+} opj_tcd_precinct_t;
+
+/**
+FIXME DOC
+*/
+typedef struct opj_tcd_band {
+	OPJ_INT32 x0, y0, x1, y1;		/* dimension of the subband : left upper corner (x0, y0) right low corner (x1,y1) */
+	OPJ_UINT32 bandno;
+	opj_tcd_precinct_t *precincts;	/* precinct information */
+	OPJ_UINT32 precincts_data_size;	/* size of data taken by precincts */
+	OPJ_INT32 numbps;
+	OPJ_FLOAT32 stepsize;
+} opj_tcd_band_t;
+
+/**
+FIXME DOC
+*/
+typedef struct opj_tcd_resolution {
+	OPJ_INT32 x0, y0, x1, y1;		/* dimension of the resolution level : left upper corner (x0, y0) right low corner (x1,y1) */
+	OPJ_UINT32 pw, ph;
+	OPJ_UINT32 numbands;			/* number sub-band for the resolution level */
+	opj_tcd_band_t bands[3];		/* subband information */
+} opj_tcd_resolution_t;
+
+/**
+FIXME DOC
+*/
+typedef struct opj_tcd_tilecomp
+{
+	OPJ_INT32 x0, y0, x1, y1;				/* dimension of component : left upper corner (x0, y0) right low corner (x1,y1) */
+	OPJ_UINT32 numresolutions;				/* number of resolutions level */
+	OPJ_UINT32 minimum_num_resolutions;		/* number of resolutions level to decode (at max)*/
+	opj_tcd_resolution_t *resolutions;	/* resolutions information */
+	OPJ_UINT32 resolutions_size;			/* size of data for resolutions (in bytes) */
+	OPJ_INT32 *data;						/* data of the component */
+	OPJ_UINT32 data_size;					/* size of the data of the component */
+	OPJ_INT32 numpix;						/* add fixed_quality */
+} opj_tcd_tilecomp_t;
+
+
+/**
+FIXME DOC
+*/
+typedef struct opj_tcd_tile {
+	OPJ_INT32 x0, y0, x1, y1;		/* dimension of the tile : left upper corner (x0, y0) right low corner (x1,y1) */
+	OPJ_UINT32 numcomps;			/* number of components in tile */
+	opj_tcd_tilecomp_t *comps;	/* Components information */
+	OPJ_INT32 numpix;				/* add fixed_quality */
+	OPJ_FLOAT64 distotile;			/* add fixed_quality */
+	OPJ_FLOAT64 distolayer[100];	/* add fixed_quality */
+	OPJ_UINT32 packno;              /* packet number */
+} opj_tcd_tile_t;
+
+/**
+FIXME DOC
+*/
+typedef struct opj_tcd_image
+{
+	opj_tcd_tile_t *tiles;		/* Tiles information */
+}
+opj_tcd_image_t;
+
+
+/**
+Tile coder/decoder
+*/
+typedef struct opj_tcd
+{
+	/** Position of the tilepart flag in Progression order*/
+	OPJ_INT32 tp_pos;
+	/** Tile part number*/
+	OPJ_UINT32 tp_num;
+	/** Current tile part number*/
+	OPJ_UINT32 cur_tp_num;
+	/** Total number of tileparts of the current tile*/
+	OPJ_UINT32 cur_totnum_tp;
+	/** Current Packet iterator number */
+	OPJ_UINT32 cur_pino;
+	/** info on each image tile */
+	opj_tcd_image_t *tcd_image;
+	/** image header */
+	opj_image_t *image;
+	/** coding parameters */
+	opj_cp_t *cp;
+	/** coding/decoding parameters common to all tiles */
+	opj_tcp_t *tcp;
+	/** current encoded/decoded tile */
+	OPJ_UINT32 tcd_tileno;
+	/** tell if the tcd is a decoder. */
+	OPJ_UINT32 m_is_decoder : 1;
+} opj_tcd_t;
+
+/** @name Exported functions */
+/*@{*/
+/* ----------------------------------------------------------------------- */
+
+/**
+Dump the content of a tcd structure
+*/
+/*void tcd_dump(FILE *fd, opj_tcd_t *tcd, opj_tcd_image_t *img);*/ /* TODO MSD shoul use the new v2 structures */ 
+
+/**
+Create a new TCD handle
+ at param p_is_decoder FIXME DOC
+ at return Returns a new TCD handle if successful returns NULL otherwise
+*/
+opj_tcd_t* opj_tcd_create(OPJ_BOOL p_is_decoder);
+
+/**
+Destroy a previously created TCD handle
+ at param tcd TCD handle to destroy
+*/
+void opj_tcd_destroy(opj_tcd_t *tcd);
+
+/**
+ * Initialize the tile coder and may reuse some memory.
+ * @param	p_tcd		TCD handle.
+ * @param	p_image		raw image.
+ * @param	p_cp		coding parameters.
+ *
+ * @return true if the encoding values could be set (false otherwise).
+*/
+OPJ_BOOL opj_tcd_init(	opj_tcd_t *p_tcd,
+						opj_image_t * p_image,
+						opj_cp_t * p_cp );
+
+/**
+ * Allocates memory for decoding a specific tile.
+ *
+ * @param	p_tcd		the tile decoder.
+ * @param	p_tile_no	the index of the tile received in sequence. This not necessarily lead to the
+ * tile at index p_tile_no.
+ *
+ * @return	true if the remaining data is sufficient.
+ */
+OPJ_BOOL opj_tcd_init_decode_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no);
+
+void opj_tcd_makelayer_fixed(opj_tcd_t *tcd, OPJ_UINT32 layno, OPJ_UINT32 final);
+
+void opj_tcd_rateallocate_fixed(opj_tcd_t *tcd);
+
+void opj_tcd_makelayer(	opj_tcd_t *tcd,
+						OPJ_UINT32 layno,
+						OPJ_FLOAT64 thresh,
+						OPJ_UINT32 final);
+
+OPJ_BOOL opj_tcd_rateallocate(	opj_tcd_t *tcd,
+								OPJ_BYTE *dest,
+								OPJ_UINT32 * p_data_written,
+								OPJ_UINT32 len,
+								opj_codestream_info_t *cstr_info);
+
+/**
+ * Gets the maximum tile size that will be taken by the tile once decoded.
+ */
+OPJ_UINT32 opj_tcd_get_decoded_tile_size (opj_tcd_t *p_tcd );
+
+/**
+ * Encodes a tile from the raw image into the given buffer.
+ * @param	p_tcd			Tile Coder handle
+ * @param	p_tile_no		Index of the tile to encode.
+ * @param	p_dest			Destination buffer
+ * @param	p_data_written	pointer to an int that is incremented by the number of bytes really written on p_dest
+ * @param	p_len			Maximum length of the destination buffer
+ * @param	p_cstr_info		Codestream information structure
+ * @return  true if the coding is successfull.
+*/
+OPJ_BOOL opj_tcd_encode_tile(   opj_tcd_t *p_tcd,
+							    OPJ_UINT32 p_tile_no,
+							    OPJ_BYTE *p_dest,
+							    OPJ_UINT32 * p_data_written,
+							    OPJ_UINT32 p_len,
+							    struct opj_codestream_info *p_cstr_info);
+
+
+/**
+Decode a tile from a buffer into a raw image
+ at param tcd TCD handle
+ at param src Source buffer
+ at param len Length of source buffer
+ at param tileno Number that identifies one of the tiles to be decoded
+ at param cstr_info  FIXME DOC
+*/
+OPJ_BOOL opj_tcd_decode_tile(   opj_tcd_t *tcd,
+							    OPJ_BYTE *src,
+							    OPJ_UINT32 len,
+							    OPJ_UINT32 tileno,
+							    opj_codestream_index_t *cstr_info);
+
+
+/**
+ * Copies tile data from the system onto the given memory block.
+ */
+OPJ_BOOL opj_tcd_update_tile_data (	opj_tcd_t *p_tcd,
+								    OPJ_BYTE * p_dest,
+								    OPJ_UINT32 p_dest_length );
+
+/**
+ *
+ */
+OPJ_UINT32 opj_tcd_get_encoded_tile_size ( opj_tcd_t *p_tcd );
+
+/**
+ * Initialize the tile coder and may reuse some meory.
+ *
+ * @param	p_tcd		TCD handle.
+ * @param	p_tile_no	current tile index to encode.
+ *
+ * @return true if the encoding values could be set (false otherwise).
+*/
+OPJ_BOOL opj_tcd_init_encode_tile (	opj_tcd_t *p_tcd,
+								    OPJ_UINT32 p_tile_no );
+
+/**
+ * Copies tile data from the given memory block onto the system.
+ */
+OPJ_BOOL opj_tcd_copy_tile_data (opj_tcd_t *p_tcd,
+                                 OPJ_BYTE * p_src,
+                                 OPJ_UINT32 p_src_length );
+
+/* ----------------------------------------------------------------------- */
+/*@}*/
+
+/*@}*/
+
+#endif /* __TCD_H */
diff --git a/Source/LibOpenJPEG/tgt.c b/Source/LibOpenJPEG/tgt.c
index f1329ca..44252ba 100644
--- a/Source/LibOpenJPEG/tgt.c
+++ b/Source/LibOpenJPEG/tgt.c
@@ -1,213 +1,331 @@
-/*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
- * Copyright (c) 2001-2003, David Janssens
- * Copyright (c) 2002-2003, Yannick Verschueren
- * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "opj_includes.h"
-
-/* 
-==========================================================
-   Tag-tree coder interface
-==========================================================
-*/
-
-opj_tgt_tree_t *tgt_create(int numleafsh, int numleafsv) {
-	int nplh[32];
-	int nplv[32];
-	opj_tgt_node_t *node = NULL;
-	opj_tgt_node_t *parentnode = NULL;
-	opj_tgt_node_t *parentnode0 = NULL;
-	opj_tgt_tree_t *tree = NULL;
-	int i, j, k;
-	int numlvls;
-	int n;
-
-	tree = (opj_tgt_tree_t *) opj_malloc(sizeof(opj_tgt_tree_t));
-	if(!tree) return NULL;
-	tree->numleafsh = numleafsh;
-	tree->numleafsv = numleafsv;
-
-	numlvls = 0;
-	nplh[0] = numleafsh;
-	nplv[0] = numleafsv;
-	tree->numnodes = 0;
-	do {
-		n = nplh[numlvls] * nplv[numlvls];
-		nplh[numlvls + 1] = (nplh[numlvls] + 1) / 2;
-		nplv[numlvls + 1] = (nplv[numlvls] + 1) / 2;
-		tree->numnodes += n;
-		++numlvls;
-	} while (n > 1);
-	
-	/* ADD */
-	if (tree->numnodes == 0) {
-		opj_free(tree);
-		return NULL;
-	}
-
-	tree->nodes = (opj_tgt_node_t*) opj_calloc(tree->numnodes, sizeof(opj_tgt_node_t));
-	if(!tree->nodes) {
-		opj_free(tree);
-		return NULL;
-	}
-
-	node = tree->nodes;
-	parentnode = &tree->nodes[tree->numleafsh * tree->numleafsv];
-	parentnode0 = parentnode;
-	
-	for (i = 0; i < numlvls - 1; ++i) {
-		for (j = 0; j < nplv[i]; ++j) {
-			k = nplh[i];
-			while (--k >= 0) {
-				node->parent = parentnode;
-				++node;
-				if (--k >= 0) {
-					node->parent = parentnode;
-					++node;
-				}
-				++parentnode;
-			}
-			if ((j & 1) || j == nplv[i] - 1) {
-				parentnode0 = parentnode;
-			} else {
-				parentnode = parentnode0;
-				parentnode0 += nplh[i];
-			}
-		}
-	}
-	node->parent = 0;
-	
-	tgt_reset(tree);
-	
-	return tree;
-}
-
-void tgt_destroy(opj_tgt_tree_t *tree) {
-	opj_free(tree->nodes);
-	opj_free(tree);
-}
-
-void tgt_reset(opj_tgt_tree_t *tree) {
-	int i;
-
-	if (NULL == tree)
-		return;
-	
-	for (i = 0; i < tree->numnodes; i++) {
-		tree->nodes[i].value = 999;
-		tree->nodes[i].low = 0;
-		tree->nodes[i].known = 0;
-	}
-}
-
-void tgt_setvalue(opj_tgt_tree_t *tree, int leafno, int value) {
-	opj_tgt_node_t *node;
-	node = &tree->nodes[leafno];
-	while (node && node->value > value) {
-		node->value = value;
-		node = node->parent;
-	}
-}
-
-void tgt_encode(opj_bio_t *bio, opj_tgt_tree_t *tree, int leafno, int threshold) {
-	opj_tgt_node_t *stk[31];
-	opj_tgt_node_t **stkptr;
-	opj_tgt_node_t *node;
-	int low;
-
-	stkptr = stk;
-	node = &tree->nodes[leafno];
-	while (node->parent) {
-		*stkptr++ = node;
-		node = node->parent;
-	}
-	
-	low = 0;
-	for (;;) {
-		if (low > node->low) {
-			node->low = low;
-		} else {
-			low = node->low;
-		}
-		
-		while (low < threshold) {
-			if (low >= node->value) {
-				if (!node->known) {
-					bio_write(bio, 1, 1);
-					node->known = 1;
-				}
-				break;
-			}
-			bio_write(bio, 0, 1);
-			++low;
-		}
-		
-		node->low = low;
-		if (stkptr == stk)
-			break;
-		node = *--stkptr;
-	}
-}
-
-int tgt_decode(opj_bio_t *bio, opj_tgt_tree_t *tree, int leafno, int threshold) {
-	opj_tgt_node_t *stk[31];
-	opj_tgt_node_t **stkptr;
-	opj_tgt_node_t *node;
-	int low;
-
-	stkptr = stk;
-	node = &tree->nodes[leafno];
-	while (node->parent) {
-		*stkptr++ = node;
-		node = node->parent;
-	}
-	
-	low = 0;
-	for (;;) {
-		if (low > node->low) {
-			node->low = low;
-		} else {
-			low = node->low;
-		}
-		while (low < threshold && low < node->value) {
-			if (bio_read(bio, 1)) {
-				node->value = low;
-			} else {
-				++low;
-			}
-		}
-		node->low = low;
-		if (stkptr == stk) {
-			break;
-		}
-		node = *--stkptr;
-	}
-	
-	return (node->value < threshold) ? 1 : 0;
-}
+/*
+ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2007, Professor Benoit Macq
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2008;2011-2012, Centre National d'Etudes Spatiales (CNES), France 
+ * Copyright (c) 2012, CS Systemes d'Information, France
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "opj_includes.h"
+
+/* 
+==========================================================
+   Tag-tree coder interface
+==========================================================
+*/
+
+opj_tgt_tree_t *opj_tgt_create(OPJ_UINT32 numleafsh, OPJ_UINT32 numleafsv) {
+        OPJ_INT32 nplh[32];
+        OPJ_INT32 nplv[32];
+        opj_tgt_node_t *node = 00;
+        opj_tgt_node_t *l_parent_node = 00;
+        opj_tgt_node_t *l_parent_node0 = 00;
+        opj_tgt_tree_t *tree = 00;
+        OPJ_UINT32 i;
+        OPJ_INT32  j,k;
+        OPJ_UINT32 numlvls;
+        OPJ_UINT32 n;
+
+        tree = (opj_tgt_tree_t *) opj_malloc(sizeof(opj_tgt_tree_t));
+        if(!tree) {
+                fprintf(stderr, "ERROR in tgt_create while allocating tree\n");
+                return 00;
+        }
+        memset(tree,0,sizeof(opj_tgt_tree_t));
+
+        tree->numleafsh = numleafsh;
+        tree->numleafsv = numleafsv;
+
+        numlvls = 0;
+        nplh[0] = (OPJ_INT32)numleafsh;
+        nplv[0] = (OPJ_INT32)numleafsv;
+        tree->numnodes = 0;
+        do {
+                n = (OPJ_UINT32)(nplh[numlvls] * nplv[numlvls]);
+                nplh[numlvls + 1] = (nplh[numlvls] + 1) / 2;
+                nplv[numlvls + 1] = (nplv[numlvls] + 1) / 2;
+                tree->numnodes += n;
+                ++numlvls;
+        } while (n > 1);
+
+        /* ADD */
+        if (tree->numnodes == 0) {
+                opj_free(tree);
+                fprintf(stderr, "WARNING in tgt_create tree->numnodes == 0, no tree created.\n");
+                return 00;
+        }
+
+        tree->nodes = (opj_tgt_node_t*) opj_calloc(tree->numnodes, sizeof(opj_tgt_node_t));
+        if(!tree->nodes) {
+                fprintf(stderr, "ERROR in tgt_create while allocating node of the tree\n");
+                opj_free(tree);
+                return 00;
+        }
+        memset(tree->nodes,0,tree->numnodes * sizeof(opj_tgt_node_t));
+        tree->nodes_size = tree->numnodes * (OPJ_UINT32)sizeof(opj_tgt_node_t);
+
+        node = tree->nodes;
+        l_parent_node = &tree->nodes[tree->numleafsh * tree->numleafsv];
+        l_parent_node0 = l_parent_node;
+
+        for (i = 0; i < numlvls - 1; ++i) {
+                for (j = 0; j < nplv[i]; ++j) {
+                        k = nplh[i];
+                        while (--k >= 0) {
+                                node->parent = l_parent_node;
+                                ++node;
+                                if (--k >= 0) {
+                                        node->parent = l_parent_node;
+                                        ++node;
+                                }
+                                ++l_parent_node;
+                        }
+                        if ((j & 1) || j == nplv[i] - 1) {
+                                l_parent_node0 = l_parent_node;
+                        } else {
+                                l_parent_node = l_parent_node0;
+                                l_parent_node0 += nplh[i];
+                        }
+                }
+        }
+        node->parent = 0;
+        opj_tgt_reset(tree);
+        return tree;
+}
+
+/**
+ * Reinitialises a tag-tree from an existing one.
+ *
+ * @param       p_tree                          the tree to reinitialize.
+ * @param       p_num_leafs_h           the width of the array of leafs of the tree
+ * @param       p_num_leafs_v           the height of the array of leafs of the tree
+ * @return      a new tag-tree if successful, NULL otherwise
+*/
+opj_tgt_tree_t *opj_tgt_init(opj_tgt_tree_t * p_tree,OPJ_UINT32 p_num_leafs_h, OPJ_UINT32 p_num_leafs_v)
+{
+        OPJ_INT32 l_nplh[32];
+        OPJ_INT32 l_nplv[32];
+        opj_tgt_node_t *l_node = 00;
+        opj_tgt_node_t *l_parent_node = 00;
+        opj_tgt_node_t *l_parent_node0 = 00;
+        OPJ_UINT32 i;
+        OPJ_INT32 j,k;
+        OPJ_UINT32 l_num_levels;
+        OPJ_UINT32 n;
+        OPJ_UINT32 l_node_size;
+
+        if (! p_tree){
+                return 00;
+        }
+
+        if ((p_tree->numleafsh != p_num_leafs_h) || (p_tree->numleafsv != p_num_leafs_v)) {
+                p_tree->numleafsh = p_num_leafs_h;
+                p_tree->numleafsv = p_num_leafs_v;
+
+                l_num_levels = 0;
+                l_nplh[0] = (OPJ_INT32)p_num_leafs_h;
+                l_nplv[0] = (OPJ_INT32)p_num_leafs_v;
+                p_tree->numnodes = 0;
+                do
+                {
+                        n = (OPJ_UINT32)(l_nplh[l_num_levels] * l_nplv[l_num_levels]);
+                        l_nplh[l_num_levels + 1] = (l_nplh[l_num_levels] + 1) / 2;
+                        l_nplv[l_num_levels + 1] = (l_nplv[l_num_levels] + 1) / 2;
+                        p_tree->numnodes += n;
+                        ++l_num_levels;
+                }
+                while (n > 1);
+
+                /* ADD */
+                if (p_tree->numnodes == 0) {
+                        opj_tgt_destroy(p_tree);
+                        return 00;
+                }
+                l_node_size = p_tree->numnodes * (OPJ_UINT32)sizeof(opj_tgt_node_t);
+                
+                if (l_node_size > p_tree->nodes_size) {
+                        opj_tgt_node_t* new_nodes = (opj_tgt_node_t*) opj_realloc(p_tree->nodes, l_node_size);
+                        if (! new_nodes) {
+                                fprintf(stderr, "ERROR Not enough memory to reinitialize the tag tree\n");
+                                opj_tgt_destroy(p_tree);
+                                return 00;
+                        }
+                        p_tree->nodes = new_nodes;
+                        memset(((char *) p_tree->nodes) + p_tree->nodes_size, 0 , l_node_size - p_tree->nodes_size);
+                        p_tree->nodes_size = l_node_size;
+                }
+                l_node = p_tree->nodes;
+                l_parent_node = &p_tree->nodes[p_tree->numleafsh * p_tree->numleafsv];
+                l_parent_node0 = l_parent_node;
+
+                for (i = 0; i < l_num_levels - 1; ++i) {
+                        for (j = 0; j < l_nplv[i]; ++j) {
+                                k = l_nplh[i];
+                                while (--k >= 0) {
+                                        l_node->parent = l_parent_node;
+                                        ++l_node;
+                                        if (--k >= 0) {
+                                                l_node->parent = l_parent_node;
+                                                ++l_node;
+                                        }
+                                        ++l_parent_node;
+                                        }
+                                if ((j & 1) || j == l_nplv[i] - 1)
+                                {
+                                        l_parent_node0 = l_parent_node;
+                                }
+                                else
+                                {
+                                        l_parent_node = l_parent_node0;
+                                        l_parent_node0 += l_nplh[i];
+                                }
+                        }
+                }
+                l_node->parent = 0;
+        }
+        opj_tgt_reset(p_tree);
+
+        return p_tree;
+}
+
+void opj_tgt_destroy(opj_tgt_tree_t *p_tree)
+{
+        if (! p_tree) {
+                return;
+        }
+
+        if (p_tree->nodes) {
+                opj_free(p_tree->nodes);
+                p_tree->nodes = 00;
+        }
+        opj_free(p_tree);
+}
+
+void opj_tgt_reset(opj_tgt_tree_t *p_tree) {
+        OPJ_UINT32 i;
+        opj_tgt_node_t * l_current_node = 00;;
+
+        if (! p_tree) {
+                return;
+        }
+
+        l_current_node = p_tree->nodes;
+        for     (i = 0; i < p_tree->numnodes; ++i)
+        {
+                l_current_node->value = 999;
+                l_current_node->low = 0;
+                l_current_node->known = 0;
+                ++l_current_node;
+        }
+}
+
+void opj_tgt_setvalue(opj_tgt_tree_t *tree, OPJ_UINT32 leafno, OPJ_INT32 value) {
+        opj_tgt_node_t *node;
+        node = &tree->nodes[leafno];
+        while (node && node->value > value) {
+                node->value = value;
+                node = node->parent;
+        }
+}
+
+void opj_tgt_encode(opj_bio_t *bio, opj_tgt_tree_t *tree, OPJ_UINT32 leafno, OPJ_INT32 threshold) {
+        opj_tgt_node_t *stk[31];
+        opj_tgt_node_t **stkptr;
+        opj_tgt_node_t *node;
+        OPJ_INT32 low;
+
+        stkptr = stk;
+        node = &tree->nodes[leafno];
+        while (node->parent) {
+                *stkptr++ = node;
+                node = node->parent;
+        }
+        
+        low = 0;
+        for (;;) {
+                if (low > node->low) {
+                        node->low = low;
+                } else {
+                        low = node->low;
+                }
+                
+                while (low < threshold) {
+                        if (low >= node->value) {
+                                if (!node->known) {
+                                        opj_bio_write(bio, 1, 1);
+                                        node->known = 1;
+                                }
+                                break;
+                        }
+                        opj_bio_write(bio, 0, 1);
+                        ++low;
+                }
+                
+                node->low = low;
+                if (stkptr == stk)
+                        break;
+                node = *--stkptr;
+        }
+}
+
+OPJ_UINT32 opj_tgt_decode(opj_bio_t *bio, opj_tgt_tree_t *tree, OPJ_UINT32 leafno, OPJ_INT32 threshold) {
+        opj_tgt_node_t *stk[31];
+        opj_tgt_node_t **stkptr;
+        opj_tgt_node_t *node;
+        OPJ_INT32 low;
+
+        stkptr = stk;
+        node = &tree->nodes[leafno];
+        while (node->parent) {
+                *stkptr++ = node;
+                node = node->parent;
+        }
+        
+        low = 0;
+        for (;;) {
+                if (low > node->low) {
+                        node->low = low;
+                } else {
+                        low = node->low;
+                }
+                while (low < threshold && low < node->value) {
+                        if (opj_bio_read(bio, 1)) {
+                                node->value = low;
+                        } else {
+                                ++low;
+                        }
+                }
+                node->low = low;
+                if (stkptr == stk) {
+                        break;
+                }
+                node = *--stkptr;
+        }
+        
+        return (node->value < threshold) ? 1 : 0;
+}
diff --git a/Source/LibOpenJPEG/tgt.h b/Source/LibOpenJPEG/tgt.h
index 2544767..0eeb304 100644
--- a/Source/LibOpenJPEG/tgt.h
+++ b/Source/LibOpenJPEG/tgt.h
@@ -1,114 +1,140 @@
-/*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
- * Copyright (c) 2001-2003, David Janssens
- * Copyright (c) 2002-2003, Yannick Verschueren
- * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __TGT_H
-#define __TGT_H
-/**
- at file tgt.h
- at brief Implementation of a tag-tree coder (TGT)
-
-The functions in TGT.C have for goal to realize a tag-tree coder. The functions in TGT.C
-are used by some function in T2.C.
-*/
-
-/** @defgroup TGT TGT - Implementation of a tag-tree coder */
-/*@{*/
-
-/**
-Tag node
-*/
-typedef struct opj_tgt_node {
-  struct opj_tgt_node *parent;
-  int value;
-  int low;
-  int known;
-} opj_tgt_node_t;
-
-/**
-Tag tree
-*/
-typedef struct opj_tgt_tree {
-  int numleafsh;
-  int numleafsv;
-  int numnodes;
-  opj_tgt_node_t *nodes;
-} opj_tgt_tree_t;
-
-/** @name Exported functions */
-/*@{*/
-/* ----------------------------------------------------------------------- */
-/**
-Create a tag-tree
- at param numleafsh Width of the array of leafs of the tree
- at param numleafsv Height of the array of leafs of the tree
- at return Returns a new tag-tree if successful, returns NULL otherwise
-*/
-opj_tgt_tree_t *tgt_create(int numleafsh, int numleafsv);
-/**
-Destroy a tag-tree, liberating memory
- at param tree Tag-tree to destroy
-*/
-void tgt_destroy(opj_tgt_tree_t *tree);
-/**
-Reset a tag-tree (set all leaves to 0)
- at param tree Tag-tree to reset
-*/
-void tgt_reset(opj_tgt_tree_t *tree);
-/**
-Set the value of a leaf of a tag-tree
- at param tree Tag-tree to modify
- at param leafno Number that identifies the leaf to modify
- at param value New value of the leaf
-*/
-void tgt_setvalue(opj_tgt_tree_t *tree, int leafno, int value);
-/**
-Encode the value of a leaf of the tag-tree up to a given threshold
- at param bio Pointer to a BIO handle
- at param tree Tag-tree to modify
- at param leafno Number that identifies the leaf to encode
- at param threshold Threshold to use when encoding value of the leaf
-*/
-void tgt_encode(opj_bio_t *bio, opj_tgt_tree_t *tree, int leafno, int threshold);
-/**
-Decode the value of a leaf of the tag-tree up to a given threshold
- at param bio Pointer to a BIO handle
- at param tree Tag-tree to decode
- at param leafno Number that identifies the leaf to decode
- at param threshold Threshold to use when decoding value of the leaf
- at return Returns 1 if the node's value < threshold, returns 0 otherwise
-*/
-int tgt_decode(opj_bio_t *bio, opj_tgt_tree_t *tree, int leafno, int threshold);
-/* ----------------------------------------------------------------------- */
-/*@}*/
-
-/*@}*/
-
-#endif /* __TGT_H */
+/*
+ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2007, Professor Benoit Macq
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2008, Jerome Fimes, Communications & Systemes <jerome.fimes at c-s.fr>
+ * Copyright (c) 2011-2012, Centre National d'Etudes Spatiales (CNES), France 
+ * Copyright (c) 2012, CS Systemes d'Information, France
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __TGT_H
+#define __TGT_H
+/**
+ at file tgt.h
+ at brief Implementation of a tag-tree coder (TGT)
+
+The functions in TGT.C have for goal to realize a tag-tree coder. The functions in TGT.C
+are used by some function in T2.C.
+*/
+
+/** @defgroup TGT TGT - Implementation of a tag-tree coder */
+/*@{*/
+
+/**
+Tag node
+*/
+typedef struct opj_tgt_node {
+    struct opj_tgt_node *parent;
+    OPJ_INT32 value;
+    OPJ_INT32 low;
+    OPJ_UINT32 known;
+} opj_tgt_node_t;
+
+/**
+Tag tree
+*/
+typedef struct opj_tgt_tree
+{
+	OPJ_UINT32  numleafsh;
+	OPJ_UINT32  numleafsv;
+	OPJ_UINT32 numnodes;
+	opj_tgt_node_t *nodes;
+	OPJ_UINT32  nodes_size;		/* maximum size taken by nodes */
+} opj_tgt_tree_t;
+
+
+/** @name Exported functions */
+/*@{*/
+/* ----------------------------------------------------------------------- */
+/**
+Create a tag-tree
+ at param numleafsh Width of the array of leafs of the tree
+ at param numleafsv Height of the array of leafs of the tree
+ at return Returns a new tag-tree if successful, returns NULL otherwise
+*/
+opj_tgt_tree_t *opj_tgt_create(OPJ_UINT32 numleafsh, OPJ_UINT32 numleafsv);
+
+/**
+ * Reinitialises a tag-tree from an exixting one.
+ *
+ * @param	p_tree				the tree to reinitialize.
+ * @param	p_num_leafs_h		the width of the array of leafs of the tree
+ * @param	p_num_leafs_v		the height of the array of leafs of the tree
+ * @return	a new tag-tree if successful, NULL otherwise
+*/
+opj_tgt_tree_t *opj_tgt_init(opj_tgt_tree_t * p_tree, 
+                             OPJ_UINT32  p_num_leafs_h, 
+                             OPJ_UINT32  p_num_leafs_v);
+/**
+Destroy a tag-tree, liberating memory
+ at param tree Tag-tree to destroy
+*/
+void opj_tgt_destroy(opj_tgt_tree_t *tree);
+/**
+Reset a tag-tree (set all leaves to 0)
+ at param tree Tag-tree to reset
+*/
+void opj_tgt_reset(opj_tgt_tree_t *tree);
+/**
+Set the value of a leaf of a tag-tree
+ at param tree Tag-tree to modify
+ at param leafno Number that identifies the leaf to modify
+ at param value New value of the leaf
+*/
+void opj_tgt_setvalue(opj_tgt_tree_t *tree, 
+                      OPJ_UINT32 leafno, 
+                      OPJ_INT32 value);
+/**
+Encode the value of a leaf of the tag-tree up to a given threshold
+ at param bio Pointer to a BIO handle
+ at param tree Tag-tree to modify
+ at param leafno Number that identifies the leaf to encode
+ at param threshold Threshold to use when encoding value of the leaf
+*/
+void opj_tgt_encode(opj_bio_t *bio, 
+                    opj_tgt_tree_t *tree, 
+                    OPJ_UINT32 leafno, 
+                    OPJ_INT32 threshold);
+/**
+Decode the value of a leaf of the tag-tree up to a given threshold
+ at param bio Pointer to a BIO handle
+ at param tree Tag-tree to decode
+ at param leafno Number that identifies the leaf to decode
+ at param threshold Threshold to use when decoding value of the leaf
+ at return Returns 1 if the node's value < threshold, returns 0 otherwise
+*/
+OPJ_UINT32 opj_tgt_decode(opj_bio_t *bio, 
+                          opj_tgt_tree_t *tree, 
+                          OPJ_UINT32 leafno, 
+                          OPJ_INT32 threshold);
+/* ----------------------------------------------------------------------- */
+/*@}*/
+
+/*@}*/
+
+#endif /* __TGT_H */
diff --git a/Source/LibOpenJPEG/thix_manager.c b/Source/LibOpenJPEG/thix_manager.c
index ed6e9f9..47c79d6 100644
--- a/Source/LibOpenJPEG/thix_manager.c
+++ b/Source/LibOpenJPEG/thix_manager.c
@@ -1,5 +1,5 @@
 /*
- * $Id: thix_manager.c,v 1.2 2012/09/23 12:44:41 drolon Exp $
+ * $Id: thix_manager.c,v 1.4 2014/03/16 12:29:52 drolon Exp $
  *
  * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
  * Copyright (c) 2002-2011, Professor Benoit Macq
@@ -33,88 +33,102 @@
  *  \brief Modification of jpip.c from 2KAN indexer
  */
 
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
 #include "opj_includes.h"
 
-/* 
- * Write tile-part headers mhix box
- *
- * @param[in] coff      offset of j2k codestream
- * @param[in] cstr_info codestream information
- * @param[in] tileno    tile number
- * @param[in] cio       file output handle
- * @return              length of mhix box
- */
-int write_tilemhix( int coff, opj_codestream_info_t cstr_info, int tileno, opj_cio_t *cio);
 
-int write_thix( int coff, opj_codestream_info_t cstr_info, opj_cio_t *cio)
+
+int opj_write_thix( int coff, opj_codestream_info_t cstr_info, opj_stream_private_t *cio,
+              opj_event_mgr_t * p_manager )
 {
-  int len, lenp, i;
+  OPJ_BYTE l_data_header [4];
+  int i;
   int tileno;
   opj_jp2_box_t *box;
+  OPJ_UINT32 len;
+  OPJ_OFF_T lenp;
 
   lenp = 0;
-  box = (opj_jp2_box_t *)opj_calloc( cstr_info.tw*cstr_info.th, sizeof(opj_jp2_box_t));
+  box = (opj_jp2_box_t *)opj_calloc( (size_t)(cstr_info.tw*cstr_info.th), sizeof(opj_jp2_box_t));
 
   for ( i = 0; i < 2 ; i++ ){
     if (i)
-      cio_seek( cio, lenp);
+      opj_stream_seek( cio, lenp, p_manager);
 
-    lenp = cio_tell( cio);
-    cio_skip( cio, 4);              /* L [at the end] */
-    cio_write( cio, JPIP_THIX, 4);  /* THIX           */
-    write_manf( i, cstr_info.tw*cstr_info.th, box, cio);
+    lenp = opj_stream_tell(cio);
+    opj_stream_skip(cio, 4, p_manager);             /* L [at the end] */
+    opj_write_bytes(l_data_header,JPIP_THIX,4); /* THIX */
+    opj_stream_write_data(cio,l_data_header,4,p_manager);
+
+    opj_write_manf( i, cstr_info.tw*cstr_info.th, box, cio, p_manager);
     
     for (tileno = 0; tileno < cstr_info.tw*cstr_info.th; tileno++){
-      box[tileno].length = write_tilemhix( coff, cstr_info, tileno, cio);
+      box[tileno].length = (OPJ_UINT32)opj_write_tilemhix( coff, cstr_info, tileno, cio,p_manager);
       box[tileno].type = JPIP_MHIX;
     }
  
-    len = cio_tell( cio)-lenp;
-    cio_seek( cio, lenp);
-    cio_write( cio, len, 4);        /* L              */
-    cio_seek( cio, lenp+len);
+    len = (OPJ_UINT32)(opj_stream_tell(cio)-lenp);
+    opj_stream_seek(cio, lenp, p_manager);
+    opj_write_bytes(l_data_header,len,4); /* L              */
+    opj_stream_write_data(cio,l_data_header,4,p_manager);
+    opj_stream_seek( cio, lenp+len,p_manager);
+
   }
 
   opj_free(box);
 
-  return len;
+  return (int)len;
 }
 
-int write_tilemhix( int coff, opj_codestream_info_t cstr_info, int tileno, opj_cio_t *cio)
+/* 
+ * Write tile-part headers mhix box
+ *
+ * @param[in] coff      offset of j2k codestream
+ * @param[in] cstr_info codestream information
+ * @param[in] tileno    tile number
+ * @param[in] cio       file output handle
+ * @return              length of mhix box
+ */
+int opj_write_tilemhix( int coff, opj_codestream_info_t cstr_info, int tileno, opj_stream_private_t *cio,
+              opj_event_mgr_t * p_manager )
 {
+  OPJ_BYTE l_data_header [8];
   int i;
   opj_tile_info_t tile;
   opj_tp_info_t tp;
-  int len, lenp;
   opj_marker_info_t *marker;
+  OPJ_UINT32 len;
+  OPJ_OFF_T lenp;
 
-  lenp = cio_tell( cio);
-  cio_skip( cio, 4);                               /* L [at the end]                    */
-  cio_write( cio, JPIP_MHIX, 4);                   /* MHIX                              */
+  lenp = opj_stream_tell (cio);
+  opj_stream_skip(cio, 4, p_manager);               /* L [at the end]                    */
+  opj_write_bytes(l_data_header,JPIP_MHIX,4);       /* MHIX                              */
+  opj_stream_write_data(cio,l_data_header,4,p_manager);
 
   tile = cstr_info.tile[tileno];
   tp = tile.tp[0];
 
-  cio_write( cio, tp.tp_end_header-tp.tp_start_pos+1, 8);  /* TLEN                              */ 
+  opj_write_bytes(l_data_header,(OPJ_UINT32)(tp.tp_end_header-tp.tp_start_pos+1), 8);        /* TLEN                              */
+  opj_stream_write_data(cio,l_data_header,8,p_manager);
 
   marker = cstr_info.tile[tileno].marker;
 
   for( i=0; i<cstr_info.tile[tileno].marknum; i++){             /* Marker restricted to 1 apparition */
-    cio_write( cio, marker[i].type, 2);
-    cio_write( cio, 0, 2);
-    cio_write( cio, marker[i].pos-coff, 8);
-    cio_write( cio, marker[i].len, 2);
+    opj_write_bytes( l_data_header, marker[i].type, 2);
+    opj_write_bytes( l_data_header+2, 0, 2);
+    opj_stream_write_data(cio,l_data_header,4,p_manager);
+    opj_write_bytes( l_data_header, (OPJ_UINT32)(marker[i].pos-coff), 8);
+    opj_stream_write_data(cio,l_data_header,8,p_manager);
+    opj_write_bytes( l_data_header, (OPJ_UINT32)marker[i].len, 2);
+    opj_stream_write_data(cio,l_data_header,2,p_manager);
   }
      
   /*  free( marker);*/
 
-  len = cio_tell( cio) - lenp;
-  cio_seek( cio, lenp);
-  cio_write( cio, len, 4);        /* L           */
-  cio_seek( cio, lenp+len);
+  len = (OPJ_UINT32)(opj_stream_tell(cio)-lenp);
+  opj_stream_seek(cio, lenp,p_manager);
+  opj_write_bytes(l_data_header,len,4);/* L  */
+  opj_stream_write_data(cio,l_data_header,4,p_manager);
+  opj_stream_seek(cio, lenp+len,p_manager);
 
-  return len;
+  return (int)len;
 }
diff --git a/Source/LibOpenJPEG/tpix_manager.c b/Source/LibOpenJPEG/tpix_manager.c
index 0b4f17a..6786775 100644
--- a/Source/LibOpenJPEG/tpix_manager.c
+++ b/Source/LibOpenJPEG/tpix_manager.c
@@ -1,5 +1,5 @@
 /*
- * $Id: tpix_manager.c,v 1.2 2012/09/23 12:44:41 drolon Exp $
+ * $Id: tpix_manager.c,v 1.4 2014/03/16 12:29:52 drolon Exp $
  *
  * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
  * Copyright (c) 2002-2011, Professor Benoit Macq
@@ -33,11 +33,18 @@
  *  \brief Modification of jpip.c from 2KAN indexer
  */
 
-#include <math.h>
 #include "opj_includes.h"
 
 #define MAX(a,b) ((a)>(b)?(a):(b))
 
+/* 
+ * Get number of maximum tile parts per tile
+ *
+ * @param[in] cstr_info codestream information
+ * @return              number of maximum tile parts per tile
+ */
+int get_num_max_tile_parts( opj_codestream_info_t cstr_info);
+
 
 /* 
  * Write faix box of tpix
@@ -49,46 +56,51 @@
  * @param[in] cio       file output handle
  * @return              length of faix box
  */
-int write_tpixfaix( int coff, int compno, opj_codestream_info_t cstr_info, int j2klen, opj_cio_t *cio);
 
-
-int write_tpix( int coff, opj_codestream_info_t cstr_info, int j2klen, opj_cio_t *cio)
+int opj_write_tpix( int coff, 
+                    opj_codestream_info_t cstr_info, 
+                    int j2klen, opj_stream_private_t *cio,
+                    opj_event_mgr_t * p_manager )
 {
-  int len, lenp;
-  lenp = cio_tell( cio);
-  cio_skip( cio, 4);              /* L [at the end] */
-  cio_write( cio, JPIP_TPIX, 4);  /* TPIX           */
+  OPJ_BYTE l_data_header [4];
+  OPJ_UINT32 len;
+  OPJ_OFF_T lenp;
+
+  lenp = opj_stream_tell(cio);
+  opj_stream_skip(cio, 4, p_manager);
+  opj_write_bytes(l_data_header,JPIP_TPIX,4); /* TPIX */
+  opj_stream_write_data(cio,l_data_header,4,p_manager);
   
-  write_tpixfaix( coff, 0, cstr_info, j2klen, cio);
+  opj_write_tpixfaix( coff, 0, cstr_info, j2klen, cio,p_manager);
 
-  len = cio_tell( cio)-lenp;
-  cio_seek( cio, lenp);
-  cio_write( cio, len, 4);        /* L              */
-  cio_seek( cio, lenp+len);
+  len = (OPJ_UINT32)(opj_stream_tell(cio)-lenp);
+ 
+  opj_stream_skip(cio, lenp, p_manager);
+  opj_write_bytes(l_data_header,len,4);/* L              */
+  opj_stream_write_data(cio,l_data_header,4,p_manager);
+  opj_stream_seek(cio, lenp+len,p_manager);
 
-  return len;
+  return (int)len;
 }
 
-
-/* 
- * Get number of maximum tile parts per tile
- *
- * @param[in] cstr_info codestream information
- * @return              number of maximum tile parts per tile
- */
-int get_num_max_tile_parts( opj_codestream_info_t cstr_info);
-
-int write_tpixfaix( int coff, int compno, opj_codestream_info_t cstr_info, int j2klen, opj_cio_t *cio)
+int opj_write_tpixfaix( int coff,
+                        int compno, 
+                        opj_codestream_info_t cstr_info, 
+                        int j2klen, 
+                        opj_stream_private_t *cio,
+                        opj_event_mgr_t * p_manager )
 {
-  int len, lenp;
-  int i, j;
-  int Aux;
-  int num_max_tile_parts;
-  int size_of_coding; /* 4 or 8 */
+  OPJ_UINT32 len;
+  OPJ_OFF_T lenp;
+  OPJ_UINT32 i, j;
+  OPJ_UINT32 Aux;
+  OPJ_UINT32 num_max_tile_parts;
+  OPJ_UINT32 size_of_coding; /* 4 or 8 */
   opj_tp_info_t tp;
-  int version;
+  OPJ_BYTE l_data_header [8];
+  OPJ_UINT32 version;
 
-  num_max_tile_parts = get_num_max_tile_parts( cstr_info);
+  num_max_tile_parts = (OPJ_UINT32)get_num_max_tile_parts( cstr_info);
 
   if( j2klen > pow( 2, 32)){
     size_of_coding =  8;
@@ -99,47 +111,67 @@ int write_tpixfaix( int coff, int compno, opj_codestream_info_t cstr_info, int j
     version = num_max_tile_parts == 1 ? 0:2;
   }
 
-  lenp = cio_tell( cio);
-  cio_skip( cio, 4);              /* L [at the end]      */
-  cio_write( cio, JPIP_FAIX, 4);  /* FAIX                */ 
-  cio_write( cio, version, 1);     /* Version 0 = 4 bytes */
-
-  cio_write( cio, num_max_tile_parts, size_of_coding);                      /* NMAX           */
-  cio_write( cio, cstr_info.tw*cstr_info.th, size_of_coding);                               /* M              */
-  for (i = 0; i < cstr_info.tw*cstr_info.th; i++){
-    for (j = 0; j < cstr_info.tile[i].num_tps; j++){
+  lenp = opj_stream_tell(cio);
+  opj_stream_skip(cio, 4, p_manager);         /* L [at the end]      */
+  opj_write_bytes(l_data_header,JPIP_FAIX,4); /* FAIX */
+  opj_stream_write_data(cio,l_data_header,4,p_manager);
+  opj_write_bytes(l_data_header,version,1);   /* Version 0 = 4 bytes */
+  opj_stream_write_data(cio,l_data_header,1,p_manager);
+
+  opj_write_bytes(l_data_header,num_max_tile_parts,size_of_coding);         /* NMAX           */
+  opj_stream_write_data(cio,l_data_header,size_of_coding,p_manager);
+  opj_write_bytes(l_data_header,(OPJ_UINT32)(cstr_info.tw*cstr_info.th),size_of_coding);  /* M              */
+  opj_stream_write_data(cio,l_data_header,size_of_coding,p_manager);
+
+  for (i = 0; i < (OPJ_UINT32)(cstr_info.tw*cstr_info.th); i++)
+    {
+    for (j = 0; j < (OPJ_UINT32)cstr_info.tile[i].num_tps; j++)
+      {
       tp = cstr_info.tile[i].tp[j];
-      cio_write( cio, tp.tp_start_pos-coff, size_of_coding); /* start position */
-      cio_write( cio, tp.tp_end_pos-tp.tp_start_pos+1, size_of_coding);    /* length         */
-      if (version & 0x02){
-	if( cstr_info.tile[i].num_tps == 1 && cstr_info.numdecompos[compno] > 1)
-	  Aux = cstr_info.numdecompos[compno] + 1;
-	else
-	  Aux = j + 1;
-		  
-	cio_write( cio, Aux,4);
-	/*cio_write(img.tile[i].tile_parts[j].num_reso_AUX,4);*/ /* Aux_i,j : Auxiliary value */
-	/* fprintf(stderr,"AUX value %d\n",Aux);*/
-      }
+
+      opj_write_bytes(l_data_header,(OPJ_UINT32)(tp.tp_start_pos-coff),size_of_coding);            /* start position */
+      opj_stream_write_data(cio,l_data_header,size_of_coding,p_manager);
+      opj_write_bytes(l_data_header,(OPJ_UINT32)(tp.tp_end_pos-tp.tp_start_pos+1),size_of_coding); /* length         */
+      opj_stream_write_data(cio,l_data_header,size_of_coding,p_manager);
+
+      if (version & 0x02)
+        {
+        if( cstr_info.tile[i].num_tps == 1 && cstr_info.numdecompos[compno] > 1)
+          Aux = (OPJ_UINT32)(cstr_info.numdecompos[compno] + 1);
+        else
+          Aux = j + 1;
+
+        opj_write_bytes(l_data_header,Aux,4);
+        opj_stream_write_data(cio,l_data_header,4,p_manager);
+
+        /*cio_write(img.tile[i].tile_parts[j].num_reso_AUX,4);*/ /* Aux_i,j : Auxiliary value */
+        /* fprintf(stderr,"AUX value %d\n",Aux);*/
+        }
       /*cio_write(0,4);*/
-    }
+      }
     /* PADDING */
-    while (j < num_max_tile_parts){
-      cio_write( cio, 0, size_of_coding); /* start position            */
-      cio_write( cio, 0, size_of_coding); /* length                    */
+    while (j < num_max_tile_parts)
+      {
+
+          opj_write_bytes(l_data_header,0,size_of_coding);/* start position            */
+      opj_stream_write_data(cio,l_data_header,size_of_coding,p_manager);
+      opj_write_bytes(l_data_header,0,size_of_coding);/* length                    */
+      opj_stream_write_data(cio,l_data_header,size_of_coding,p_manager);
+
       if (version & 0x02)
-	cio_write( cio, 0,4);                  /* Aux_i,j : Auxiliary value */
+      opj_write_bytes(l_data_header,0,4);      /* Aux_i,j : Auxiliary value */
+      opj_stream_write_data(cio,l_data_header,4,p_manager);
       j++;
+      }
     }
-  }
   
-  len = cio_tell( cio)-lenp;
-  cio_seek( cio, lenp);
-  cio_write( cio, len, 4);        /* L  */
-  cio_seek( cio, lenp+len);
-
-  return len;
+  len = (OPJ_UINT32)(opj_stream_tell(cio)-lenp);
+  opj_stream_seek(cio, lenp,p_manager);
+  opj_write_bytes(l_data_header,len,4);/* L  */
+  opj_stream_write_data(cio,l_data_header,4,p_manager);
+  opj_stream_seek(cio, lenp+len,p_manager);
 
+  return (int)len;
 }
 
 int get_num_max_tile_parts( opj_codestream_info_t cstr_info)
diff --git a/Source/LibPNG/ANNOUNCE b/Source/LibPNG/ANNOUNCE
index 346383d..b0331df 100644
--- a/Source/LibPNG/ANNOUNCE
+++ b/Source/LibPNG/ANNOUNCE
@@ -1,5 +1,4 @@
-
-Libpng 1.5.13 - September 27, 2012
+Libpng 1.6.16 - December 22, 2014
 
 This is a public release of libpng, intended for use in production codes.
 
@@ -8,35 +7,30 @@ Files available for download:
 Source files with LF line endings (for Unix/Linux) and with a
 "configure" script
 
-   libpng-1.5.13.tar.xz (LZMA-compressed, recommended)
-   libpng-1.5.13.tar.gz
-   libpng-1.5.13.tar.bz2
+   libpng-1.6.16.tar.xz (LZMA-compressed, recommended)
+   libpng-1.6.16.tar.gz
 
 Source files with CRLF line endings (for Windows), without the
 "configure" script
 
-   lpng1513.7z  (LZMA-compressed, recommended)
-   lpng1513.zip
+   lpng1616.7z  (LZMA-compressed, recommended)
+   lpng1616.zip
 
 Other information:
 
-   libpng-1.5.13-README.txt
-   libpng-1.5.13-LICENSE.txt
-
-Changes since the last public release (1.5.12):
-  Do not compile PNG_DEPRECATED, PNG_ALLOC and PNG_PRIVATE when __GNUC__ < 3.
-  Removed references to png_zalloc() and png_zfree() from the manual.
-  Revised PNG_FP_EXPORT and PNG_FIXED_EXPORT macros to avoid generating
-    lone semicolons (patch ported from libpng-1.6.0beta11).
-  Corrected handling of the image array and the row_pointers array in example.c
-  When png_set_filler is used to strip a filler channel during write, the
-    code prior to 1.5 would ignore the case where the output required an
-    alpha channel or when the output was a palettized PNG.  In libpng-1.5 the
-    ignorance was lost and libpng proceeded to strip the channel resulting
-    in a bad (potential memory overwrite) failure later.  This reverts
-    the behavior to the pre-1.5 state but issues a warning. libpng-1.6 is
-    expected to issue an error on the erroneous png_set_filler call.
-  Use png_memset() consistently (pngmem.c contained some bare "memset" calls).
+   libpng-1.6.16-README.txt
+   libpng-1.6.16-LICENSE.txt
+   libpng-1.6.16-*.asc (armored detached GPG signatures)
+
+Changes since the last public release (1.6.15):
+  Added ".align 2" to arm/filter_neon.S to support old GAS assemblers that
+    don't do alignment correctly.
+  Revised Makefile.am and scripts/*.dfn to work with MinGW/MSYS;
+    renamed scripts/*.dfn to scripts/*.c (Bob Friesenhahn and John Bowler).
+  Quiet a "comparison always true" warning in pngstest.c (John Bowler).
+  Restored a test on width that was removed from png.c at libpng-1.6.9
+    (Bug report by Alex Eubanks).
+  Fixed an overflow in png_combine_row with very wide interlaced images.
 
 Send comments/corrections/commendations to png-mng-implement at lists.sf.net
 (subscription required; visit
diff --git a/Source/LibPNG/CHANGES b/Source/LibPNG/CHANGES
index d3c0ccc..7488f99 100644
--- a/Source/LibPNG/CHANGES
+++ b/Source/LibPNG/CHANGES
@@ -1,4 +1,4 @@
-#if 0
+
 CHANGES - changes for libpng
 
 Version 0.2
@@ -3672,7 +3672,8 @@ Version 1.5.6 [November 3, 2011]
   No changes.
 
 Version 1.5.7beta01 [November 4, 2011]
-  Added support for ARM processor (Mans Rullgard)
+  Added support for ARM processor, when decoding all PNG up-filtered rows
+    and any other-filtered rows with 3 or 4 bytes per pixel (Mans Rullgard).
   Fixed bug in pngvalid on early allocation failure; fixed type cast in
     pngmem.c; pngvalid would attempt to call png_error() if the allocation
     of a png_struct or png_info failed. This would probably have led to a
@@ -3775,148 +3776,1353 @@ Version 1.5.7rc03 [December 7, 2011]
 Version 1.5.7 [December 15, 2011]
   Minor fixes to pngvalid.c for gcc 4.6.2 compatibility to remove warnings
     reported by earlier versions.
-
-Version 1.5.8beta01 [January 15, 2011]
-  Removed '#include config.h"' from contrib/libtests/pngvalid.c.  It's not
-    needed and causes trouble for VPATH building.
+  Fixed minor memset/sizeof errors in pngvalid.c.
+
+Version 1.6.0beta01 [December 15, 2011]
+  Removed machine-generated configure files from the GIT repository (they will
+    continue to appear in the tarball distributions and in the libpng15 and
+    earlier GIT branches).
+  Restored the new 'simplified' API, which was started in libpng-1.5.7beta02
+    but later deleted from libpng-1.5.7beta05.
+  Added example programs for the new 'simplified' API.
+  Added ANSI-C (C90) headers and require them, and take advantage of the
+    change. Also fixed some of the projects/* and contrib/* files that needed
+    updates for libpng16 and the move of pngvalid.c.
+    With this change the required ANSI-C header files are assumed to exist: the
+    implementation must provide float.h, limits.h, stdarg.h and stddef.h and
+    libpng relies on limits.h and stddef.h existing and behaving as defined
+    (the other two required headers aren't used).  Non-ANSI systems that don't
+    have stddef.h or limits.h will have to provide an appropriate fake
+    containing the relevant types and #defines.
+  The use of FAR/far has been eliminated and the definition of png_alloc_size_t
+    is now controlled by a flag so that 'small size_t' systems can select it
+    if necessary.  Libpng 1.6 may not currently work on such systems -- it
+    seems likely that it will ask 'malloc' for more than 65535 bytes with any
+    image that has a sufficiently large row size (rather than simply failing
+    to read such images).
+  New tools directory containing tools used to generate libpng code.
+  Fixed race conditions in parallel make builds. With higher degrees of
+    parallelism during 'make' the use of the same temporary file names such
+    as 'dfn*' can result in a race where a temporary file from one arm of the
+    build is deleted or overwritten in another arm.  This changes the
+    temporary files for suffix rules to always use $* and ensures that the
+    non-suffix rules use unique file names.
+
+Version 1.6.0beta02 [December 21, 2011]
+  Correct configure builds where build and source directories are separate.
+    The include path of 'config.h' was erroneously made relative in pngvalid.c
+    in libpng 1.5.7.
+
+Version 1.6.0beta03 [December 22, 2011]
+  Start-up code size improvements, error handler flexibility. These changes
+    alter how the tricky allocation of the initial png_struct and png_info
+    structures are handled. png_info is now handled in pretty much the same
+    way as everything else, except that the allocations handle NULL return
+    silently.  png_struct is changed in a similar way on allocation and on
+    deallocation a 'safety' error handler is put in place (which should never
+    be required).  The error handler itself is changed to permit mismatches
+    in the application and libpng error buffer size; however, this means a
+    silent change to the API to return the jmp_buf if the size doesn't match
+    the size from the libpng compilation; libpng now allocates the memory and
+    this may fail.  Overall these changes result in slight code size
+    reductions; however, this is a reduction in code that is always executed
+    so is particularly valuable.  Overall on a 64-bit system the libpng DLL
+    decreases in code size by 1733 bytes.  pngerror.o increases in size by
+    about 465 bytes because of the new functionality.
+  Added png_convert_to_rfc1123_buffer() and deprecated png_convert_to_rfc1123()
+    to avoid including a spurious buffer in the png_struct.
+
+Version 1.6.0beta04 [December 30, 2011]
+  Regenerated configure scripts with automake-1.11.2
+  Eliminated png_info_destroy(). It is now used only in png.c and only calls
+    one other internal function and memset().
+  Enabled png_get_sCAL_fixed() if floating point APIs are enabled. Previously
+    it was disabled whenever internal fixed point arithmetic was selected,
+    which meant it didn't exist even on systems where FP was available but not
+    preferred.
+  Added pngvalid.c compile time checks for const APIs.
+  Implemented 'restrict' for png_info and png_struct. Because of the way
+    libpng works both png_info and png_struct are always accessed via a
+    single pointer.  This means adding C99 'restrict' to the pointer gives
+    the compiler some opportunity to optimize the code.  This change allows
+    that.
   Moved AC_MSG_CHECKING([if libraries can be versioned]) later to the proper
     location in configure.ac (Gilles Espinasse).
+  Changed png_memcpy to C assignment where appropriate. Changed all those
+    uses of png_memcpy that were doing a simple assignment to assignments
+    (all those cases where the thing being copied is a non-array C L-value).
+  Added some error checking to png_set_*() routines.
+  Removed the reference to the non-exported function png_memcpy() from
+    example.c.
+  Fixed the Visual C 64-bit build - it requires jmp_buf to be aligned, but
+    it had become misaligned.
+  Revised contrib/pngminus/pnm2png.c to avoid warnings when png_uint_32
+    and unsigned long are of different sizes.
+
+Version 1.6.0beta05 [January 15, 2012]
+  Updated manual with description of the simplified API (copied from png.h)
   Fix bug in pngerror.c: some long warnings were being improperly truncated
     (CVE-2011-3464, bug introduced in libpng-1.5.3beta05).
 
-Version 1.5.8rc01 [January 21, 2012]
-  No changes.
-
-Version 1.5.8rc02 [January 25, 2012]
+Version 1.6.0beta06 [January 24, 2012]
+  Added palette support to the simplified APIs. This commit
+    changes some of the macro definitions in png.h, app code
+    may need corresponding changes.
+  Increased the formatted warning buffer to 192 bytes.
+  Added color-map support to simplified API. This is an initial version for
+    review; the documentation has not yet been updated.
   Fixed Min/GW uninstall to remove libpng.dll.a
-  Conditionalize the install rules for MINGW and CYGWIN in CMakeLists.txt
-
-Version 1.5.8 [February 1, 2012]
-  No changes.
 
-Version 1.5.9beta01 [February 3, 2012]
-  Rebuilt configure scripts in the tar distributions.
+Version 1.6.0beta07 [January 28, 2012]
+  Eliminated Intel icc/icl compiler warnings. The Intel (GCC derived)
+    compiler issues slightly different warnings from those issued by the
+    current vesions of GCC. This eliminates those warnings by
+    adding/removing casts and small code rewrites.
+  Updated configure.ac from autoupdate: added --enable-werror option.
+    Also some layout regularization and removal of introduced tab characters
+    (replaced with 3-character indentation).  Obsolete macros identified by
+    autoupdate have been removed; the replacements are all in 2.59 so
+    the pre-req hasn't been changed.  --enable-werror checks for support
+    for -Werror (or the given argument) in the compiler.  This mimics the
+    gcc configure option by allowing -Werror to be turned on safely; without
+    the option the tests written in configure itself fail compilation because
+    they cause compiler warnings.
+  Rewrote autogen.sh to run autoreconf instead of running tools one-by-one.
+  Conditionalize the install rules for MINGW and CYGWIN in CMakeLists.txt and
+    set CMAKE_LIBRARY_OUTPUT_DIRECTORY to "lib" on all platforms (C. Yapp).
+  Freeze libtool files in the 'scripts' directory. This version of autogen.sh
+    attempts to dissuade people from running it when it is not, or should not,
+    be necessary.  In fact, autogen.sh does not work when run in a libpng
+    directory extracted from a tar distribution anymore. You must run it in
+    a GIT clone instead.
+  Added two images to contrib/pngsuite (1-bit and 2-bit transparent grayscale),
+    and renamed three whose names were inconsistent with those in
+    pngsuite/README.txt.
 
-Version 1.5.9beta02 [February 16, 2012]
-  Removed two unused definitions from scripts/pnglibconf.h.prebuilt
+Version 1.6.0beta08 [February 1, 2012]
+  Fixed Image::colormap misalignment in pngstest.c
+  Check libtool/libtoolize version number (2.4.2) in configure.ac
+  Divide test-pngstest.sh into separate pngstest runs for basic and
+    transparent images.
+  Moved automake options to AM_INIT_AUTOMAKE in configure.ac
+  Added color-tests, silent-rules (Not yet implemented in Makefile.am) and
+    version checking to configure.ac
+  Improved pngstest speed by not doing redundant tests and add const to
+    the background parameter of png_image_finish_read. The --background
+    option is now done automagically only when required, so that commandline
+    option no longer exists.
+  Cleaned up pngpriv.h to consistently declare all functions and data.
+    Also eliminated PNG_CONST_DATA, which is apparently not needed but we
+    can't be sure until it is gone.
+  Added symbol prefixing that allows all the libpng external symbols
+    to be prefixed (suggested by Reuben Hawkins).
+  Updated "ftbb*.png" list in the owatcom and vstudio projects.
+  Fixed 'prefix' builds on clean systems. The generation of pngprefix.h
+    should not require itself.
+  Updated INSTALL to explain that autogen.sh must be run in a GIT clone,
+    not in a libpng directory extracted from a tar distribution.
+
+Version 1.6.0beta09 [February 1, 2012]
+  Reverted the prebuilt configure files to libpng-1.6.0beta05 condition.
+
+Version 1.6.0beta10 [February 3, 2012]
+  Added Z_SOLO for zlib-1.2.6+ and correct pngstest tests
+  Updated list of test images in CMakeLists.txt
+  Updated the prebuilt configure files to current condition.
+  Revised INSTALL information about autogen.sh; it works in tar distributions.
+
+Version 1.6.0beta11 [February 16, 2012]
+  Fix character count in pngstest command in projects/owatcom/pngstest.tgt
+  Revised test-pngstest.sh to report PASS/FAIL for each image.
+  Updated documentation about the simplified API.
+  Corrected estimate of error in libpng png_set_rgb_to_gray API.  The API is
+    extremely inaccurate for sRGB conversions because it uses an 8-bit
+    intermediate linear value and it does not use the sRGB transform, so it
+    suffers from the known instability in gamma transforms for values close
+    to 0 (see Poynton).  The net result is that the calculation has a maximum
+    error of 14.99/255; 0.5/255^(1/2.2).  pngstest now uses 15 for the
+    permitted 8-bit error. This may still not be enough because of arithmetic
+    error.
   Removed some unused arrays (with #ifdef) from png_read_push_finish_row().
+  Fixed a memory overwrite bug in simplified read of RGB PNG with
+    non-linear gamma Also bugs in the error checking in pngread.c and changed
+    quite a lot of the checks in pngstest.c to be correct; either correctly
+    written or not over-optimistic.  The pngstest changes are insufficient to
+    allow all possible RGB transforms to be passed; pngstest cmppixel needs
+    to be rewritten to make it clearer which errors it allows and then changed
+    to permit known inaccuracies.
   Removed tests for no-longer-used *_EMPTY_PLTE_SUPPORTED from pngstruct.h
-
-Version 1.5.9rc01 [February 17, 2012]
+  Fixed fixed/float API export conditionals. 1) If FIXED_POINT or
+    FLOATING_POINT options were switched off, png.h ended up with lone ';'
+    characters.  This is not valid ANSI-C outside a function.  The ';'
+    characters have been moved inside the definition of PNG_FP_EXPORT and
+    PNG_FIXED_EXPORT. 2) If either option was switched off, the declaration
+    of the corresponding functions were completely omitted, even though some
+    of them are still used internally.  The result is still valid, but
+    produces warnings from gcc with some warning options (including -Wall). The
+    fix is to cause png.h to declare the functions with PNG_INTERNAL_FUNCTION
+    when png.h is included from pngpriv.h.
+  Check for invalid palette index while reading paletted PNG.  When one is
+    found, issue a warning and increase png_ptr->num_palette accordingly.
+    Apps are responsible for checking to see if that happened.
+
+Version 1.6.0beta12 [February 18, 2012]
+  Do not increase num_palette on invalid_index.
+  Relocated check for invalid palette index to pngrtran.c, after unpacking
+    the sub-8-bit pixels.
   Fixed CVE-2011-3026 buffer overrun bug.  This bug was introduced when
     iCCP chunk support was added at libpng-1.0.6. Deal more correctly with the
     test on iCCP chunk length. Also removed spurious casts that may hide
     problems on 16-bit systems.
 
-Version 1.5.9 [February 18, 2012]
-  No changes.
-
-Version 1.5.10beta01 [February 24, 2012]
-  Removed two useless #ifdef directives from pngread.c and one from pngrutil.c
-  Always put the CMAKE_LIBRARY in "lib" (removed special WIN32 case).
-  Removed empty vstudio/pngstest directory (Clifford Yapp).
+Version 1.6.0beta13 [February 24, 2012]
   Eliminated redundant png_push_read_tEXt|zTXt|iTXt|unknown code from
     pngpread.c and use the sequential png_handle_tEXt, etc., in pngrutil.c;
     now that png_ptr->buffer is inaccessible to applications, the special
     handling is no longer useful.
-  Fixed bug with png_handle_hIST with odd chunk length (Frank Busse).
-  Added PNG_SAFE_LIMITS feature to pnglibconf.dfa and code in pngconf.h
-    to reset the user limits to safe ones if PNG_SAFE_LIMITS is defined.
-    To enable, use "CPPFLAGS=-DPNG_SAFE_LIMITS_SUPPORTED" on the configure
-    command or put "#define PNG_SAFE_LIMITS_SUPPORTED" in pnglibconf.h.
-  Revised the SAFE_LIMITS feature to be the same as the feature in libpng16.
-  Added information about the new limits in the manual.
+  Added PNG_SAFE_LIMITS feature to pnglibconf.dfa, pngpriv.h, and new
+    pngusr.dfa to reset the user limits to safe ones if PNG_SAFE_LIMITS is
+    defined.  To enable, use "CPPFLAGS=-DPNG_SAFE_LIMITS_SUPPORTED=1" on the
+    configure command or put #define PNG_SAFE_LIMITS_SUPPORTED in
+    pnglibconf.h.prebuilt and pnglibconf.h.
 
-Version 1.5.10beta02 [February 27, 2012]
+Version 1.6.0beta14 [February 27, 2012]
+  Added information about the new limits in the manual.
   Updated Makefile.in
 
-Version 1.5.10beta03 [March 6, 2012]
+Version 1.6.0beta15 [March 2, 2012]
   Removed unused "current_text" members of png_struct and the png_free()
     of png_ptr->current_text from pngread.c
-  Added palette-index checking. Issue a png_warning() if an invalid index is
-    found.
-
-Version 1.5.10beta04 [March 10, 2012]
-  Fixed PNG_LIBPNG_BUILD_BASE_TYPE definition.
-  Fixed CMF optimization of non-IDAT compressed chunks, which was added at
-    libpng-1.5.4.  It sometimes produced too small of a window.
-
-Version 1.5.10beta05 [March 10, 2012]
+  Rewrote pngstest.c for substantial speed improvement.
+  Fixed transparent pixel and 16-bit rgb tests in pngstest and removed a
+    spurious check in pngwrite.c
+  Added PNG_IMAGE_FLAG_FAST for the benefit of applications that store
+    intermediate files, or intermediate in-memory data, while processing
+    image data with the simplified API.  The option makes the files larger
+    but faster to write and read.  pngstest now uses this by default; this
+    can be disabled with the --slow option.
+  Improved pngstest fine tuning of error numbers, new test file generator.
+    The generator generates images that test the full range of sample values,
+    allow the error numbers in pngstest to be tuned and checked.  makepng
+    also allows generation of images with extra chunks, although this is
+    still work-in-progress.
+  Added check for invalid palette index while reading.
+  Fixed some bugs in ICC profile writing. The code should now accept
+    all potentially valid ICC profiles and reject obviously invalid ones.
+    It now uses png_error() to do so rather than casually writing a PNG
+    without the necessary color data.
+  Removed whitespace from the end of lines in all source files and scripts.
+
+Version 1.6.0beta16 [March 6, 2012]
+  Relocated palette-index checking function from pngrutil.c to pngtrans.c
+  Added palette-index checking while writing.
+  Changed png_inflate() and calling routines to avoid overflow problems.
+    This is an intermediate check-in that solves the immediate problems and
+    introduces one performance improvement (avoiding a copy via png_ptr->zbuf.)
+    Further changes will be made to make ICC profile handling more secure.
+  Fixed build warnings (MSVC, GCC, GCC v3). Cygwin GCC with default options
+    declares 'index' as a global, causing a warning if it is used as a local
+    variable.  GCC 64-bit warns about assigning a (size_t) (unsigned 64-bit)
+    to an (int) (signed 32-bit).  MSVC, however, warns about using the
+    unary '-' operator on an unsigned value (even though it is well defined
+    by ANSI-C to be ~x+1).  The padding calculation was changed to use a
+    different method.  Removed the tests on png_ptr->pass.
+  Added contrib/libtests/tarith.c to test internal arithmetic functions from
+    png.c. This is a libpng maintainer program used to validate changes to the
+    internal arithmetic functions.
+  Made read 'inflate' handling like write 'deflate' handling. The read
+    code now claims and releases png_ptr->zstream, like the write code.
+    The bug whereby the progressive reader failed to release the zstream
+    is now fixed, all initialization is delayed, and the code checks for
+    changed parameters on deflate rather than always calling
+    deflatedEnd/deflateInit.
+  Validate the zTXt strings in pngvalid.
+  Added code to validate the windowBits value passed to deflateInit2().
+    If the call to deflateInit2() is wrong a png_warning will be issued
+    (in fact this is harmless, but the PNG data produced may be sub-optimal).
+
+Version 1.6.0beta17 [March 10, 2012]
+  Fixed PNG_LIBPNG_BUILD_BASE_TYPE definition. 
   Reject all iCCP chunks after the first, even if the first one is invalid.
+  Deflate/inflate was reworked to move common zlib calls into single
+    functions [rw]util.c.  A new shared keyword check routine was also added
+    and the 'zbuf' is no longer allocated on progressive read.  It is now
+    possible to call png_inflate() incrementally.  A warning is no longer
+    issued if the language tag or translated keyword in the iTXt chunk
+    has zero length.
+  If benign errors are disabled use maximum window on ancilliary inflate.
+    This works round a bug introduced in 1.5.4 where compressed ancillary
+    chunks could end up with a too-small windowBits value in the deflate
+    header.
+
+Version 1.6.0beta18 [March 16, 2012]
   Issue a png_benign_error() instead of png_warning() about bad palette index.
+  In pngtest, treat benign errors as errors if "-strict" is present.
   Fixed an off-by-one error in the palette index checking function.
+  Fixed a compiler warning under Cygwin (Windows-7, 32-bit system)
   Revised example.c to put text strings in a temporary character array
     instead of directly assigning string constants to png_textp members.
     This avoids compiler warnings when -Wwrite-strings is enabled.
-
-Version 1.5.10 [March 29, 2012]
+  Added output flushing to aid debugging under Visual Studio. Unfortunately
+    this is necessary because the VS2010 output window otherwise simply loses
+    the error messages on error (they weren't flushed to the window before
+    the process exited, apparently!)
+  Added configuration support for benign errors and changed the read
+    default. Also changed some warnings in the iCCP and sRGB handling
+    from to benign errors. Configuration now makes read benign
+    errors warnings and write benign errors to errors by default (thus
+    changing the behavior on read).  The simplified API always forces
+    read benign errors to warnings (regardless of the system default, unless
+    this is disabled in which case the simplified API can't be built.)
+
+Version 1.6.0beta19 [March 18, 2012]
+  Work around for duplicate row start calls; added warning messages.
+    This turns on PNG_FLAG_DETECT_UNINITIALIZED to detect app code that
+    fails to call one of the 'start' routines (not enabled in libpng-1.5
+    because it is technically an API change, since it did normally work
+    before.)  It also makes duplicate calls to png_read_start_row (an
+    internal function called at the start of the image read) benign, as
+    they were before changes to use png_inflate_claim. Somehow webkit is
+    causing this to happen; this is probably a mis-feature in the zlib
+    changes so this commit is only a work-round.
+  Removed erroneous setting of DETECT_UNINITIALIZED and added more
+    checks. The code now does a png_error if an attempt is made to do the
+    row initialization twice; this is an application error and it has
+    serious consequences because the transform data in png_struct is
+    changed by each call.
+  Added application error reporting and added chunk names to read
+    benign errors; also added --strict to pngstest - not enabled
+    yet because a warning is produced.
+  Avoid the double gamma correction warning in the simplified API.
+    This allows the --strict option to pass in the pngstest checks
+
+Version 1.6.0beta20 [March 29, 2012]
+  Changed chunk handler warnings into benign errors, incrementally load iCCP
+  Added checksum-icc.c to contrib/tools
   Prevent PNG_EXPAND+PNG_SHIFT doing the shift twice.
+  Recognize known sRGB ICC profiles while reading; prefer writing the
+    iCCP profile over writing the sRGB chunk, controlled by the
+    PNG_sRGB_PROFILE_CHECKS option.
   Revised png_set_text_2() to avoid potential memory corruption (fixes
     CVE-2011-3048, also known as CVE-2012-3425).
 
-Version 1.5.11beta01 [April 28, 2012]
+Version 1.6.0beta21 [April 27, 2012]
   Revised scripts/makefile.darwin: use system zlib; remove quotes around
     architecture list; add missing ppc architecture; add architecture options
     to shared library link; don't try to create a shared lib based on missing
     RELEASE variable.
   Enable png_set_check_for_invalid_index() for both read and write.
-  Removed #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED/#endif in pngpriv.h around
+  Removed #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED in pngpriv.h around
     declaration of png_handle_unknown().
   Added -lssp_nonshared in a comment in scripts/makefile.freebsd
     and changed deprecated NOOBJ and NOPROFILE to NO_OBJ and NO_PROFILE.
 
-Version 1.5.11rc01 [May 23, 2012]
-  No changes.
+Version 1.6.0beta22 [May 23, 2012]
+  Removed need for -Wno-cast-align with clang.  clang correctly warns on
+    alignment increasing pointer casts when -Wcast-align is passed. This
+    fixes the cases that clang warns about either by eliminating the
+    casts from png_bytep to png_uint_16p (pngread.c), or, for pngrutil.c
+    where the cast is previously verified or pngstest.c where it is OK, by
+    introducing new png_aligncast macros to do the cast in a way that clang
+    accepts.
 
-Version 1.5.11rc02 [May 29, 2012]
-  Fixed some typos in comments.
+Version 1.6.0beta23 [June 6, 2012]
   Revised CMakeLists.txt to not attempt to make a symlink under mingw.
-  Added two images to contrib/pngsuite (1-bit and 2-bit transparent grayscale),
-    and renamed three whose names were inconsistent with those in
-    pngsuite/README.txt.
-
-Version 1.5.11rc03 [June 4, 2012]
-  Do not depend upon a GCC feature macro being available for use in generating
-    the linker mapfile symbol prefix.
   Made fixes for new optimization warnings from gcc 4.7.0. The compiler
-    performed an optimization which is safe but then warned about it.
+    performs an optimization which is safe; however it then warns about it.
     Changing the type of 'palette_number' in pngvalid.c removes the warning.
+  Do not depend upon a GCC feature macro being available for use in generating
+    the linker mapfile symbol prefix.
+  Improved performance of new do_check_palette_indexes() function (only
+    update the value when it actually increases, move test for whether
+    the check is wanted out of the function.
 
-Version 1.5.11rc04 [June 6, 2012]
-  Improved performance of new do_check_palette_indexes() function.
-
-Version 1.5.11rc05 [June 7, 2012]
+Version 1.6.0beta24 [June 7, 2012]
   Don't check palette indexes if num_palette is 0 (as it can be in MNG files).
 
-Version 1.5.11 [June 14, 2012]
-  Include zlib.h in contrib/gregbook and contrib/visupng examples.
+Version 1.6.0beta25 [June 16, 2012]
+  Revised png_set_keep_unknown_chunks() so num_chunks < 0 means ignore all
+    unknown chunks and all known chunks except for IHDR, PLTE, tRNS, IDAT,
+    and IEND.  Previously it only meant ignore all unknown chunks, the
+    same as num_chunks == 0. Revised png_image_skip_unused_chunks() to
+    provide a list of chunks to be processed instead of a list of chunks to
+    ignore.  Revised contrib/gregbook/readpng2.c accordingly.
 
-Version 1.5.12 [July 11, 2012]
+Version 1.6.0beta26 [July 10, 2012]
   Removed scripts/makefile.cegcc from the *.zip and *.7z distributions; it
     depends on configure, which is not included in those archives.
+  Moved scripts/chkfmt to contrib/tools.
   Changed "a+w" to "u+w" in Makefile.in to fix CVE-2012-3386.
 
-Version 1.5.13beta01 [August 8, 2012]
+Version 1.6.0beta27 [August 11, 2012]
   Do not compile PNG_DEPRECATED, PNG_ALLOC and PNG_PRIVATE when __GNUC__ < 3.
+  Do not use __restrict when GNUC is <= 3.1
   Removed references to png_zalloc() and png_zfree() from the manual.
-  Revised PNG_FP_EXPORT and PNG_FIXED_EXPORT macros to avoid generating
-    lone semicolons (patch ported from libpng-1.6.0beta11).
-
-Version 1.5.13beta02 [September 10, 2012]
-  Corrected handling of the image array and the row_pointers array in example.c
-  When png_set_filler is used to strip a filler channel during write, the
-    code prior to 1.5 would ignore the case where the output required an
-    alpha channel or when the output was a palettized PNG.  In libpng-1.5 the
-    ignorance was lost and libpng proceeded to strip the channel resulting
-    in a bad (potential memory overwrite) failure later.  This reverts
-    the behavior to the pre-1.5 state but issues a warning. libpng-1.6 is
-    expected to issue an error on the erroneous png_set_filler call.
-  Use png_memset() consistently (pngmem.c contained some bare "memset" calls).
-
-Version 1.5.13rc01 [September 17, 2012]
+  Fixed configurations where floating point is completely disabled.  Because
+    of the changes to support symbol prefixing PNG_INTERNAL_FUNCTION declares
+    floating point APIs during libpng builds even if they are completely
+    disabled. This requires the png floating point types (png_double*) to be
+    declared even though the functions are never actually defined.  This
+    change provides a dummy definition so that the declarations work, yet any
+    implementation will fail to compile because of an incomplete type.
+  Re-eliminated the use of strcpy() in pngtest.c.  An unncessary use of
+    strcpy() was accidentally re-introduced in libpng16; this change replaces
+    it with strncpy().
+  Eliminated use of png_sizeof(); use sizeof() instead.
+  Use a consistent style for (sizeof type) and (sizeof (array))
+  Cleanup of png_set_filler().  This function does very different things on
+    read and write.  In libpng 1.6 the two cases can be distinguished and
+    considerable code cleanup, and extra error checking, is possible.  This
+    makes calls on the write side that have no effect be ignored with a
+    png_app_error(), which can be disabled in the app using
+    png_set_benign_errors(), and removes the spurious use of usr_channels
+    on the read side.
+  Insist on autotools 1.12.1 for git builds because there are security issues
+    with 1.12 and insisting on anything less would allow 1.12 to be used.
+  Removed info_ptr->signature[8] from WRITE-only builds.
+  Add some conditions for compiling png_fixed().  This is a small function
+    but it requires "-lm" on some platforms.
+  Cause pngtest --strict to fail on any warning from libpng (not just errors)
+    and cause it not to fail at the comparison step if libpng lacks support
+    for writing chunks that it reads from the input (currently only implemented
+    for compressed text chunks).
+  Make all three "make check" test programs work without READ or WRITE support.
+    Now "make check" will succeed even if libpng is compiled with -DPNG_NO_READ
+    or -DPNG_NO_WRITE.  The tests performed are reduced, but the basic reading
+    and writing of a PNG file is always tested by one or more of the tests.
+  Consistently use strlen(), memset(), memcpy(), and memcmp() instead of the
+    png_strlen(), png_memset(), png_memcpy(), and png_memcmp() macros.
+  Removed the png_sizeof(), png_strlen(), png_memset(), png_memcpy(), and
+    png_memcmp() macros.
+  Work around gcc 3.x and Microsoft Visual Studio 2010 complaints. Both object
+    to the split initialization of num_chunks.
+
+Version 1.6.0beta28 [August 29, 2012]
+  Unknown handling fixes and clean up. This adds more correct option
+    control of the unknown handling, corrects the pre-existing bug where
+    the per-chunk 'keep' setting is ignored and makes it possible to skip
+    IDAT chunks in the sequential reader (broken in earlier 1.6 versions).
+    There is a new test program, test-unknown.c, which is a work in progress
+    (not currently part of the test suite).  Comments in the header files now
+    explain how the unknown handling works.
+  Allow fine grain control of unknown chunk APIs. This change allows
+    png_set_keep_unknown_chunks() to be turned off if not required and causes
+    both read and write to behave appropriately (on read this is only possible
+    if the user callback is used to handle unknown chunks).  The change
+    also removes the support for storing unknown chunks in the info_struct
+    if the only unknown handling enabled is via the callback, allowing libpng
+    to be configured with callback reading and none of the unnecessary code.
+  Corrected fix for unknown handling in pngtest. This reinstates the
+    libpng handling of unknown chunks other than vpAg and sTER (including
+    unsafe-to-copy chunks which were dropped before) and eliminates the
+    repositioning of vpAg and sTER in pngtest.png by changing pngtest.png
+    (so the chunks are where libpng would put them).
+  Added "tunknown" test and corrected a logic error in png_handle_unknown()
+    when SAVE support is absent.  Moved the shell test scripts for
+    contrib/libtests from the libpng top directory to contrib/libtests.
+    png_handle_unknown() must always read or skip the chunk, if
+    SAVE_UNKNOWN_CHUNKS is turned off *and* the application does not set
+    a user callback an unknown chunk will not be read, leading to a read
+    error, which was revealed by the "tunknown" test.
+  Cleaned up and corrected ICC profile handling.
+    contrib/libtests/makepng: corrected 'rgb' and 'gray' cases.  profile_error
+    messages could be truncated; made a correct buffer size calculation and
+    adjusted pngerror.c appropriately. png_icc_check_* checking improved;
+    changed the functions to receive the correct color type of the PNG on read
+    or write and check that it matches the color space of the profile (despite
+    what the comments said before, there is danger in assuming the app will
+    cope correctly with an RGB profile on a grayscale image and, since it
+    violates the PNG spec, allowing it is certain to produce inconsistent
+    app behavior and might even cause app crashes.) Check that profiles
+    contain the tags needed to process the PNG (tags all required by the ICC
+    spec). Removed unused PNG_STATIC from pngpriv.h.
+
+Version 1.6.0beta29 [September 4, 2012]
+  Fixed the simplified API example programs to add the *colormap parameter
+    to several of he API and improved the error message if the version field
+    is not set.
+  Added contrib/examples/* to the *.zip and *.7z distributions.
+  Updated simplified API synopses and description of the png_image structure
+    in the manual.
+  Made makepng and pngtest produce identical PNGs, add "--relaxed" option
+    to pngtest. The "--relaxed" option turns off the benign errors that are
+    enabled by default in pre-RC builds. makepng can now write ICC profiles
+    where the length has not been extended to a multiple of 4, and pngtest
+    now intercepts all libpng errors, allowing the previously-introduced
+    "--strict test" on no warnings to actually work.
+  Improved ICC profile handling including cHRM chunk generation and fixed
+    Cygwin+MSVC build errors. The ICC profile handling now includes more
+    checking.  Several errors that caused rejection of the profile are now
+    handled with a warning in such a way that the invalid profiles will be
+    read by default in release (but not pre-RC) builds but will not be
+    written by default.  The easy part of handling the cHRM chunk is written,
+    where the ICC profile contains the required data.  The more difficult
+    part plus guessing a gAMA value requires code to pass selected RGB values
+    through the profile.
+
+Version 1.6.0beta30 [October 24, 2012]
+  Changed ICC profile matrix/vector types to not depend on array type rules.
+    By the ANSI-C standard the new types should be identical to the previous
+    versions, and all known versions of gcc tested with the previous versions
+    except for GCC-4.2.1 work with this version.  The change makes the ANSI-C
+    rule that const applied to an array of elements applies instead to the
+    elements in the array moot by explicitly applying const to the base
+    elements of the png_icc_matrix and png_icc_vector types. The accidental
+    (harmless) 'const' previously applied to the parameters of two of the
+    functions have also been removed.
+  Added a work around for GCC 4.2 optimization bug.
+  Marked the broken (bad white point) original HP sRGB profiles correctly and
+    correct comments.
+  Added -DZ_SOLO to contrib/pngminim/*/makefile to work with zlib-1.2.7
+  Use /MDd for vstudio debug builds. Also added pngunkown to the vstudio
+    builds, fixed build errors and corrected a minor exit code error in
+    pngvalid if the 'touch' file name is invalid.
+  Add updated WARNING file to projects/vstudio from libpng 1.5/vstudio
+  Fixed build when using #define PNG_NO_READ_GAMMA in png_do_compose() in
+    pngrtran.c (Domani Hannes).
+
+Version 1.6.0beta31 [November 1, 2012]
+  Undid the erroneous change to vstudio/pngvalid build in libpng-1.6.0beta30.
+  Made pngvalid so that it will build outside the libpng source tree.
+  Made builds -DPNG_NO_READ_GAMMA compile (the unit tests still fail).
+  Made PNG_NO_READ_GAMMA switch off interfaces that depend on READ_GAMMA.
+    Prior to 1.6.0 switching off READ_GAMMA did unpredictable things to the
+    interfaces that use it (specifically, png_do_background in 1.4 would
+    simply display composite for grayscale images but do composition
+    with the incorrect arithmetic for color ones). In 1.6 the semantic
+    of -DPNG_NO_READ_GAMMA is changed to simply disable any interface that
+    depends on it; this obliges people who set it to consider whether they
+    really want it off if they happen to use any of the interfaces in
+    question (typically most users who disable it won't).
+  Fixed GUIDs in projects/vstudio. Some were duplicated or missing,
+    resulting in VS2010 having to update the files.
+  Removed non-working ICC profile support code that was mostly added to
+    libpng-1.6.0beta29 and beta30. There was too much code for too little
+    gain; implementing full ICC color correction may be desireable but is left
+    up to applications.
+
+Version 1.6.0beta32 [November 25, 2012]
+  Fixed an intermittent SEGV in pngstest due to an uninitialized array element.
+  Added the ability for contrib/libtests/makepng.c to make a PNG with just one
+    color. This is useful for debugging pngstest color inaccuracy reports.
+  Fixed error checking in the simplified write API (Olaf van der Spek)
+  Made png_user_version_check() ok to use with libpng version 1.10.x and later.
+
+Version 1.6.0beta33 [December 15, 2012]
+  Fixed typo in png.c (PNG_SET_CHUNK_MALLOC_MAX should be PNG_CHUNK_MALLOC_MAX)
+    that causes the MALLOC_MAX limit not to work (John Bowler)
+  Change png_warning() to png_app_error() in pngwrite.c and comment the
+    fall-through condition.
+  Change png_warning() to png_app_warning() in png_write_tRNS().
+  Rearranged the ARM-NEON optimizations: Isolated the machine specific code
+    to the hardware subdirectory and added comments to pngrutil.c so that
+    implementors of other optimizations know what to do.
+  Fixed cases of unquoted DESTDIR in Makefile.am
+  Rebuilt Makefile.in, etc., with autoconf-2.69 and automake-1.12.5.
+
+Version 1.6.0beta34 [December 19, 2012]
+  Cleaned up whitespace in the synopsis portion of the manpage "libpng.3"
+  Disassembled the version number in scripts/options.awk (necessary for
+    building on SunOs).
+
+Version 1.6.0beta35 [December 23, 2012]
+  Made default Zlib compression settings be configurable. This adds #defines to
+    pnglibconf.h to control the defaults.
+  Fixed Windows build issues, enabled ARM compilation. Various warnings issued
+    by earlier versions of GCC fixed for Cygwin and Min/GW (which both use old
+    GCCs.) ARM support is enabled by default in zlib.props (unsupported by
+    Microsoft) and ARM compilation is made possible by deleting the check for
+    x86. The test programs cannot be run because they are not signed.
+
+Version 1.6.0beta36 [January 2, 2013]
+  Discontinued distributing libpng-1.x.x.tar.bz2.
+  Discontinued distributing libpng-1.7.0-1.6.0-diff.txt and similar.
+  Rebuilt configure with autoconf-2.69 (inadvertently not done in beta33)
+  Fixed 'make distcheck' on SUN OS - libpng.so was not being removed
+
+Version 1.6.0beta37 [January 10, 2013]
+  Fixed conceivable but difficult to repro overflow. Also added two test
+    programs to generate and test a PNG which should have the problem.
+
+Version 1.6.0beta39 [January 19, 2013]
+  Again corrected attempt at overflow detection in png_set_unknown_chunks()
+  (CVE-2013-7353).  Added overflow detection in png_set_sPLT() and
+  png_set_text_2() (CVE-2013-7354).
+
+Version 1.6.0beta40 [January 20, 2013]
+  Use consistent handling of overflows in text, sPLT and unknown png_set_* APIs
+
+Version 1.6.0rc01 [January 26, 2013]
+  No changes.
+
+Version 1.6.0rc02 [February 4, 2013]
+  Added png_get_palette_max() function.
+
+Version 1.6.0rc03 [February 5, 2013]
+  Fixed the png_get_palette_max API.
+
+Version 1.6.0rc04 [February 7, 2013]
+  Turn serial tests back on (recently turned off by autotools upgrade).
+
+Version 1.6.0rc05 [February 8, 2013]
+  Update manual about png_get_palette_max().
+
+Version 1.6.0rc06 [February 9, 2013]
+  Fixed missing dependency in --prefix builds The intermediate
+    internal 'prefix.h' file can only be generated correctly after
+    pnglibconf.h, however the dependency was not in Makefile.am.  The
+    symptoms are unpredictable depending on the order make chooses to
+    build pngprefix.h and pnglibconf.h, often the error goes unnoticed
+    because there is a system pnglibconf.h to use instead.
+
+Version 1.6.0rc07 [February 10, 2013]
+  Enclosed the new png_get_palette_max in #ifdef PNG_GET_PALETTE_MAX_SUPPORTED
+    block, and revised pnglibconf.h and pnglibconf.h.prebuilt accordingly.
+
+Version 1.6.0rc08 [February 10, 2013]
+  Fix typo in png.h #ifdef
+
+Version 1.6.0 [February 14, 2013]
+  No changes.
+
+Version 1.6.1beta01 [February 16, 2013]
+  Made symbol prefixing work with the ARM neon optimizations. Also allow
+    pngpriv.h to be included for preprocessor definitions only, so it can
+    be used in non-C/C++ files. Back ported from libpng 1.7.
+  Made sRGB check numbers consistent.
+  Ported libpng 1.5 options.awk/dfn file handling to 1.6, fixed one bug.
+  Removed cc -E workround, corrected png_get_palette_max API Tested on
+    SUN OS cc 5.9, which demonstrates the tokenization problem previously
+    avoided by using /lib/cpp.  Since all .dfn output is now protected in
+    double quotes unless it is to be macro substituted the fix should
+    work everywhere.
+  Enabled parallel tests - back ported from libpng-1.7.
+  scripts/pnglibconf.dfa formatting improvements back ported from libpng17.
+  Fixed a race condition in the creation of the build 'scripts' directory
+    while building with a parallel make.
+  Use approved/supported Android method to check for NEON, use Linux/POSIX
+    1003.1 API to check /proc/self/auxv avoiding buffer allocation and other
+    library calls (ported from libpng15).
+
+Version 1.6.1beta02 [February 19, 2013]
+  Use parentheses more consistently in "#if defined(MACRO)" tests.
+  Folded long lines.
+  Reenabled code to allow zero length PLTE chunks for MNG.
+
+Version 1.6.1beta03 [February 22, 2013]
+  Fixed ALIGNED_MEMORY support.
+  Allow run-time ARM NEON checking to be disabled. A new configure option:
+    --enable-arm-neon=always will stop the run-time checks. New checks
+    within arm/arm_init.c will cause the code not to be compiled unless
+    __ARM_NEON__ is set. This should make it fail safe (if someone asks
+    for it on then the build will fail if it can't be done.)
+  Updated the INSTALL document.
+
+Version 1.6.1beta04 [February 27, 2013]
+  Revised INSTALL to recommend using CPPFLAGS instead of INCLUDES.
+  Revised scripts/makefile.freebsd to respect ZLIBLIB and ZLIBINC.
+  Revised scripts/dfn.awk to work with the buggy MSYS awk that has trouble
+    with CRLF line endings.
+
+Version 1.6.1beta05 [March 1, 2013]
+  Avoid a possible memory leak in contrib/gregbook/readpng.c
+
+Version 1.6.1beta06 [March 4, 2013]
+  Better documentation of unknown handling API interactions.
+  Corrected Android builds and corrected libpng.vers with symbol
+    prefixing. This adds an API to set optimization options externally,
+    providing an alternative and general solution for the non-portable
+    run-time tests used by the ARM Neon code.  It also makes those tests
+    compile and link on Android.
+  The order of settings vs options in pnglibconf.h is reversed to allow
+    settings to depend on options and options can now set (or override) the
+    defaults for settings.
+
+Version 1.6.1beta07 [March 7, 2013]
+  Corrected simplified API default gamma for color-mapped output, added
+    a flag to change default. In 1.6.0 when the simplified API was used
+    to produce color-mapped output from an input image with no gamma
+    information the gamma assumed for the input could be different from
+    that assumed for non-color-mapped output.  In particular 16-bit depth
+    input files were assumed to be sRGB encoded, whereas in the 'direct'
+    case they were assumed to have linear data.  This was an error.  The
+    fix makes the simplified API treat all input files the same way and
+    adds a new flag to the png_image::flags member to allow the
+    application/user to specify that 16-bit files contain sRGB data
+    rather than the default linear.
+  Fixed bugs in the pngpixel and makepng test programs.
+
+Version 1.6.1beta08 [March 7, 2013]
+  Fixed CMakelists.txt to allow building a single variant of the library
+    (Claudio Bley):
+  Introduced a PNG_LIB_TARGETS variable that lists all activated library
+    targets.  It is an error if this variable ends up empty, ie. you have
+    to build at least one library variant.
+  Made the *_COPY targets only depend on library targets actually being build.
+  Use PNG_LIB_TARGETS to unify a code path.
+  Changed the CREATE_SYMLINK macro to expect the full path to a file as the
+    first argument. When symlinking the filename component of that path is
+    determined and used as the link target.
+  Use copy_if_different in the CREATE_SYMLINK macro.
+
+Version 1.6.1beta09 [March 13, 2013]
+  Eliminated two warnings from the Intel C compiler. The warnings are
+    technically valid, although a reasonable treatment of division would
+    show it to be incorrect.
+
+Version 1.6.1rc01 [March 21, 2013]
+  No changes.
+
+Version 1.6.1 [March 28, 2013]
+  No changes.
+
+Version 1.6.2beta01 [April 14, 2013]
+  Updated documentation of 1.5.x to 1.6.x changes in iCCP chunk handling.
+  Fixed incorrect warning of excess deflate data. End condition - the
+    warning would be produced if the end of the deflate stream wasn't read
+    in the last row.  The warning is harmless.
+  Corrected the test on user transform changes on read. It was in the
+    png_set of the transform function, but that doesn't matter unless the
+    transform function changes the rowbuf size, and that is only valid if
+    transform_info is called.
+  Corrected a misplaced closing bracket in contrib/libtests/pngvalid.c
+    (Flavio Medeiros).
+  Corrected length written to uncompressed iTXt chunks (Samuli Suominen).
+    Bug was introduced in libpng-1.6.0.
+
+Version 1.6.2rc01 [April 18, 2013]
+  Added contrib/tools/fixitxt.c, to repair the erroneous iTXt chunk length
+    written by libpng-1.6.0 and 1.6.1.
+  Disallow storing sRGB information when the sRGB is not supported.
+
+Version 1.6.2rc02 [April 18, 2013]
+  Merge pngtest.c with libpng-1.7.0
+
+Version 1.6.2rc03 [April 22, 2013]
+  Trivial spelling cleanup.
+
+Version 1.6.2rc04 and 1.6.2rc05 [omitted]
+
+Version 1.6.2rc06 [April 24, 2013]
+  Reverted to version 1.6.2rc03.  Recent changes to arm/neon support
+    have been ported to libpng-1.7.0beta09 and will reappear in version
+    1.6.3beta01.
+
+Version 1.6.2 [April 25, 2013]
+  No changes.
+
+Version 1.6.3beta01 [April 25, 2013]
+  Revised stack marking in arm/filter_neon.S and configure.ac.
+  Ensure that NEON filter stuff is completely disabled when switched 'off'.
+    Previously the ARM NEON specific files were still built if the option
+    was switched 'off' as opposed to being explicitly disabled.
+
+Version 1.6.3beta02 [April 26, 2013]
+  Test for 'arm*' not just 'arm' in the host_cpu configure variable.
+  Rebuilt the configure scripts.
+
+Version 1.6.3beta03 [April 30, 2013]
+  Expanded manual paragraph about writing private chunks, particularly
+    the need to call png_set_keep_unknown_chunks() when writing them.
+  Avoid dereferencing NULL pointer possibly returned from
+     png_create_write_struct() (Andrew Church).
+
+Version 1.6.3beta05 [May 9, 2013]
+  Calculate our own zlib windowBits when decoding rather than trusting the
+    CMF bytes in the PNG datastream.
+  Added an option to force maximum window size for inflating, which was
+    the behavior of libpng15 and earlier.
+  Added png-fix-itxt and png-fix-too-far-back to the built programs and
+    removed warnings from the source code and timepng that are revealed as
+    a result.
+  Detect wrong libpng versions linked to png-fix-too-far-back, which currently
+    only works with libpng versions that can be made to reliably fail when
+    the deflate data contains an out-of-window reference.  This means only
+    1.6 and later.
+  Fixed gnu issues: g++ needs a static_cast, gcc 4.4.7 has a broken warning
+    message which it is easier to work round than ignore.
+  Updated contrib/pngminus/pnm2png.c (Paul Stewart):
+    Check for EOF
+    Ignore "#" delimited comments in input file to pnm2png.c.
+    Fixed whitespace handling
+    Added a call to png_set_packing()
+    Initialize dimension values so if sscanf fails at least we have known
+      invalid values.
+  Attempt to detect configuration issues with png-fix-too-far-back, which
+    requires both the correct libpng and the correct zlib to function
+    correctly.
+  Check ZLIB_VERNUM for mismatches, enclose #error in quotes
+  Added information in the documentation about problems with and fixes for
+    the bad CRC and bad iTXt chunk situations.
+
+Version 1.6.3beta06 [May 12, 2013]
+  Allow contrib/pngminus/pnm2png.c to compile without WRITE_INVERT and
+    WRITE_PACK supported (writes error message that it can't read P1 or
+    P4 PBM files).
+  Improved png-fix-too-far-back usage message, added --suffix option.
+  Revised contrib/pngminim/*/makefile to generate pnglibconf.h with the
+    right zlib header files.
+  Separated CPPFLAGS and CFLAGS in contrib/pngminim/*/makefile
+
+Version 1.6.3beta07 [June 8, 2013]
+  Removed a redundant test in png_set_IHDR().
+  Added set(CMAKE_CONFIGURATION_TYPES ...) to CMakeLists.txt (Andrew Hundt)
+  Deleted set(CMAKE_BUILD_TYPE) block from CMakeLists.txt
+  Enclose the prototypes for the simplified write API in
+    #ifdef PNG_STDIO_SUPPORTED/#endif
+  Make ARM NEON support work at compile time (not just configure time).
+    This moves the test on __ARM_NEON__ into pngconf.h to avoid issues when
+    using a compiler that compiles for multiple architectures at one time.
+  Removed PNG_FILTER_OPTIMIZATIONS and PNG_ARM_NEON_SUPPORTED from
+    pnglibconf.h, allowing more of the decisions to be made internally
+    (pngpriv.h) during the compile.  Without this, symbol prefixing is broken
+    under certain circumstances on ARM platforms.  Now only the API parts of
+    the optimizations ('check' vs 'api') are exposed in the public header files
+    except that the new setting PNG_ARM_NEON_OPT documents how libpng makes the
+    decision about whether or not to use the optimizations.
+  Protect symbol prefixing against CC/CPPFLAGS/CFLAGS useage.
+    Previous iOS/Xcode fixes for the ARM NEON optimizations moved the test
+    on __ARM_NEON__ from configure time to compile time.  This breaks symbol
+    prefixing because the definition of the special png_init_filter_functions
+    call was hidden at configure time if the relevant compiler arguments are
+    passed in CFLAGS as opposed to CC.  This change attempts to avoid all
+    the confusion that would result by declaring the init function even when
+    it is not used, so that it will always get prefixed.
+
+Version 1.6.3beta08 [June 18, 2013]
+  Revised libpng.3 so that "doclifter" can process it.
+
+Version 1.6.3beta09 [June 27, 2013]
+  Revised example.c to illustrate use of PNG_DEFAULT_sRGB and PNG_GAMMA_MAC_18
+    as parameters for png_set_gamma().  These have been available since
+    libpng-1.5.4.
+  Renamed contrib/tools/png-fix-too-far-back.c to pngfix.c and revised it
+    to check all compressed chunks known to libpng.
+
+Version 1.6.3beta10 [July 5, 2013]
+  Updated documentation to show default behavior of benign errors correctly.
+  Only compile ARM code when PNG_READ_SUPPORTED is defined.
+  Fixed undefined behavior in contrib/tools/pngfix.c and added new strip
+    option. pngfix relied on undefined behavior and even a simple change from
+    gcc to g++ caused it to fail.  The new strip option 'unsafe' has been
+    implemented and is the default if --max is given.  Option names have
+    been clarified, with --strip=transform now stripping the bKGD chunk,
+    which was stripped previously with --strip=unused.
+  Added all documented chunk types to pngpriv.h
+  Unified pngfix.c source with libpng17.
+
+Version 1.6.3rc01 [July 11, 2013]
+  No changes.
+
+Version 1.6.3 [July 18, 2013]
+  Revised manual about changes in iTXt chunk handling made in libpng-1.6.0.
+  Added "/* SAFE */" comments in pngrutil.c and pngrtran.c where warnings
+    may be erroneously issued by code-checking applications.
+
+Version 1.6.4beta01 [August 21, 2013]
+  Added information about png_set_options() to the manual.
+  Delay calling png_init_filter_functions() until a row with nonzero filter
+    is found.
+
+Version 1.6.4beta02 [August 30, 2013]
+  Fixed inconsistent conditional compilation of png_chunk_unknown_handling()
+    prototype, definition, and usage.  Made it depend on
+    PNG_HANDLE_AS_UNKNOWN_SUPPORTED everywhere.
+
+Version 1.6.4rc01 [September 5, 2013]
+  No changes.
+
+Version 1.6.4 [September 12, 2013]
+  No changes.
+
+Version 1.6.5 [September 14, 2013]
+  Removed two stray lines of code from arm/arm_init.c.
+
+Version 1.6.6 [September 16, 2013]
+  Removed two stray lines of code from arm/arm_init.c, again.
+
+Version 1.6.7beta01 [September 30, 2013]
+  Revised unknown chunk code to correct several bugs in the NO_SAVE_/NO_WRITE
+    combination
+  Allow HANDLE_AS_UNKNOWN to work when other options are configured off. Also
+    fixed the pngminim makefiles to work when $(MAKEFLAGS) contains stuff
+    which terminates the make options (as by default in recent versions of
+    Gentoo).
+  Avoid up-cast warnings in pngvalid.c. On ARM the alignment requirements of
+    png_modifier are greater than that of png_store and as a consequence
+    compilation of pngvalid.c results in a warning about increased alignment
+    requirements because of the bare cast to (png_modifier*). The code is safe,
+    because the pointer is known to point to a stack allocated png_modifier,
+    but this change avoids the warning.
+  Fixed default behavior of ARM_NEON_API. If the ARM NEON API option was
+    compiled without the CHECK option it defaulted to on, not off.
+  Check user callback behavior in pngunknown.c. Previous versions compiled
+    if SAVE_UNKNOWN was not available but did nothing since the callback
+    was never implemented.
+  Merged pngunknown.c with 1.7 version and back ported 1.7 improvements/fixes
+
+Version 1.6.7beta02 [October 12, 2013]
+  Made changes for compatibility with automake 1.14:
+    1) Added the 'compile' program to the list of programs that must be cleaned
+       in autogen.sh
+    2) Added 'subdir-objects' which causes .c files in sub-directories to be
+       compiled such that the corresponding .o files are also in the
+       sub-directory.  This is because automake 1.14 warns that the
+       current behavior of compiling to the top level directory may be removed
+       in the future.
+    3) Updated dependencies on pnglibconf.h to match the new .o locations and
+       added all the files in contrib/libtests and contrib/tools that depend
+       on pnglibconf.h
+    4) Added 'BUILD_SOURCES = pnglibconf.h'; this is the automake recommended
+       way of handling the dependencies of sources that are machine generated;
+       unfortunately it only works if the user does 'make all' or 'make check',
+       so the dependencies (3) are still required.
+  Cleaned up (char*) casts of zlib messages. The latest version of the Intel C
+    compiler complains about casting a string literal as (char*), so copied the
+    treatment of z_const from the library code into pngfix.c
+  Simplified error message code in pngunknown. The simplification has the
+    useful side effect of avoiding a bogus warning generated by the latest
+    version of the Intel C compiler (it objects to
+    condition ? string-literal : string-literal).
+  Make autogen.sh work with automake 1.13 as well as 1.14. Do this by always
+    removing the 1.14 'compile' script but never checking for it.
+
+Version 1.6.7beta03 [October 19, 2013]
+  Added ARMv8 support (James Yu <james.yu at linaro.org>).  Added file
+    arm/filter_neon_intrinsics.c; enable with -mfpu=neon.
+  Revised pngvalid to generate size images with as many filters as it can
+    manage, limited by the number of rows.
+  Cleaned up ARM NEON compilation handling. The tests are now in pngpriv.h
+    and detect the broken GCC compilers.
+
+Version 1.6.7beta04 [October 26, 2013]
+  Allow clang derived from older GCC versions to use ARM intrinsics. This
+    causes all clang builds that use -mfpu=neon to use the intrinsics code,
+    not the assembler code.  This has only been tested on iOS 7. It may be
+    necessary to exclude some earlier clang versions but this seems unlikely.
+  Changed NEON implementation selection mechanism. This allows assembler
+    or intrinsics to be turned on at compile time during the build by defining
+    PNG_ARM_NEON_IMPLEMENTATION to the correct value (2 or 1).  This macro
+    is undefined by default and the build type is selected in pngpriv.h.
+
+Version 1.6.7rc01 [November 2, 2013]
+  No changes.
+
+Version 1.6.7rc02 [November 7, 2013]
+  Fixed #include in filter_neon_intrinsics.c and ctype macros. The ctype char
+    checking macros take an unsigned char argument, not a signed char.
+
+Version 1.6.7 [November 14, 2013]
+  No changes.
+
+Version 1.6.8beta01 [November 24, 2013]
+  Moved prototype for png_handle_unknown() in pngpriv.h outside of
+    the #ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED/#endif block.
+  Added "-Wall" to CFLAGS in contrib/pngminim/*/makefile
+  Conditionally compile some unused functions reported by -Wall in
+    pngminim.
+  Fixed 'minimal' builds. Various obviously useful minimal configurations
+    don't build because of missing contrib/libtests test programs and
+    overly complex dependencies in scripts/pnglibconf.dfa. This change
+    adds contrib/conftest/*.dfa files that can be used in automatic build
+    scripts to ensure that these configurations continue to build.
+  Enabled WRITE_INVERT and WRITE_PACK in contrib/pngminim/encoder.
+  Fixed pngvalid 'fail' function declaration on the Intel C Compiler.
+    This reverts to the previous 'static' implementation and works round
+    the 'unused static function' warning by using PNG_UNUSED().
+
+Version 1.6.8beta02 [November 30, 2013]
+  Removed or marked PNG_UNUSED some harmless "dead assignments" reported
+    by clang scan-build.
+  Changed tabs to 3 spaces in png_debug macros and changed '"%s"m'
+    to '"%s" m' to improve portability among compilers.
+  Changed png_free_default() to free() in pngtest.c
+
+Version 1.6.8rc01 [December 12, 2013]
+  Tidied up pngfix inits and fixed pngtest no-write builds.
+
+Version 1.6.8rc02 [December 14, 2013]
+  Handle zero-length PLTE chunk or NULL palette with png_error()
+    instead of png_chunk_report(), which by default issues a warning
+    rather than an error, leading to later reading from a NULL pointer
+    (png_ptr->palette) in png_do_expand_palette(). This is CVE-2013-6954
+    and VU#650142.  Libpng-1.6.1 through 1.6.7 are vulnerable.
+    Libpng-1.6.0 and earlier do not have this bug.
+
+Version 1.6.8 [December 19, 2013]
+  No changes.
+
+Version 1.6.9beta01 [December 26, 2013]
+  Bookkeeping: Moved functions around (no changes). Moved transform
+    function definitions before the place where they are called so that
+    they can be made static. Move the intrapixel functions and the
+    grayscale palette builder out of the png?tran.c files. The latter
+    isn't a transform function and is no longer used internally, and the
+    former MNG specific functions are better placed in pngread/pngwrite.c
+  Made transform implementation functions static. This makes the internal
+    functions called by png_do_{read|write}_transformations static. On an
+    x86-64 DLL build (Gentoo Linux) this reduces the size of the text
+    segment of the DLL by 1208 bytes, about 0.6%. It also simplifies
+    maintenance by removing the declarations from pngpriv.h and allowing
+    easier changes to the internal interfaces.
+  Rebuilt configure scripts with automake-1.14.1 and autoconf-2.69
+    in the tar distributions.
+
+Version 1.6.9beta02 [January 1, 2014]
+  Added checks for libpng 1.5 to pngvalid.c.  This supports the use of
+    this version of pngvalid in libpng 1.5
+  Merged with pngvalid.c from libpng-1.7 changes to create a single
+    pngvalid.c
+  Removed #error macro from contrib/tools/pngfix.c (Thomas Klausner).
+  Merged pngrio.c, pngtrans.c, pngwio.c, and pngerror.c with libpng-1.7.0
+  Merged libpng-1.7.0 changes to make no-interlace configurations work
+    with test programs.
+  Revised pngvalid.c to support libpng 1.5, which does not support the
+    PNG_MAXIMUM_INFLATE_WINDOW option, so #define it out when appropriate in
+    pngvalid.c
+  Allow unversioned links created on install to be disabled in configure.
+    In configure builds 'make install' changes/adds links like png.h
+    and libpng.a to point to the newly installed, versioned, files (e.g.
+    libpng17/png.h and libpng17.a). Three new configure options and some
+    rearrangement of Makefile.am allow creation of these links to be disabled.
+
+Version 1.6.9beta03 [January 10, 2014]
+  Removed potentially misleading warning from png_check_IHDR().
+
+Version 1.6.9beta04 [January 20, 2014]
+  Updated scripts/makefile.* to use CPPFLAGS (Cosmin).
+  Added clang attribute support (Cosmin).
+
+Version 1.6.9rc01 [January 28, 2014]
+  No changes.
+
+Version 1.6.9rc02 [January 30, 2014]
+  Quiet an uninitialized memory warning from VC2013 in png_get_png().
+
+Version 1.6.9 [February 6, 2014]
+
+Version 1.6.10beta01 [February 9, 2014]
+  Backported changes from libpng-1.7.0beta30 and beta31:
+  Fixed a large number of instances where PNGCBAPI was omitted from
+    function definitions.
+  Added pngimage test program for png_read_png() and png_write_png()
+    with two new test scripts.
+  Removed dependence on !PNG_READ_EXPAND_SUPPORTED for calling
+    png_set_packing() in png_read_png().
+  Fixed combination of ~alpha with shift. On read invert alpha, processing
+    occurred after shift processing, which causes the final values to be
+    outside the range that should be produced by the shift. Reversing the
+    order on read makes the two transforms work together correctly and mirrors
+    the order used on write.
+  Do not read invalid sBIT chunks. Previously libpng only checked sBIT
+    values on write, so a malicious PNG writer could therefore cause
+    the read code to return an invalid sBIT chunk, which might lead to
+    application errors or crashes.  Such chunks are now skipped (with
+    chunk_benign_error).
+  Make png_read_png() and png_write_png() prototypes in png.h depend
+    upon PNG_READ_SUPPORTED and PNG_WRITE_SUPPORTED.
+  Support builds with unsupported PNG_TRANSFORM_* values.  All of the
+    PNG_TRANSFORM_* values are always defined in png.h and, because they
+    are used for both read and write in some cases, it is not reliable
+    to #if out ones that are totally unsupported. This change adds error
+    detection in png_read_image() and png_write_image() to do a
+    png_app_error() if the app requests something that cannot be done
+    and it adds corresponding code to pngimage.c to handle such options
+    by not attempting to test them.
+
+Version 1.6.10beta02 [February 23, 2014]
+  Moved redefines of png_error(), png_warning(), png_chunk_error(),
+    and png_chunk_warning() from pngpriv.h to png.h to make them visible
+    to libpng-calling applications.
+  Moved OS dependent code from arm/arm_init.c, to allow the included
+    implementation of the ARM NEON discovery function to be set at
+    build-time and provide sample implementations from the current code in the
+    contrib/arm-neon subdirectory. The __linux__ code has also been changed to
+    compile and link on Android by using /proc/cpuinfo, and the old linux code
+    is in contrib/arm-neon/linux-auxv.c.  The new code avoids POSIX and Linux
+    dependencies apart from opening /proc/cpuinfo and is C90 compliant.
+  Check for info_ptr == NULL early in png_read_end() so we don't need to
+    run all the png_handle_*() and depend on them to return if info_ptr == NULL.
+    This improves the performance of png_read_end(png_ptr, NULL) and makes
+    it more robust against future programming errors.
+  Check for __has_extension before using it in pngconf.h, to
+    support older Clang versions (Jeremy Sequoia).
+  Treat CRC error handling with png_set_crc_action(), instead of with
+    png_set_benign_errors(), which has been the case since libpng-1.6.0beta18.
+  Use a user warning handler in contrib/gregbook/readpng2.c instead of default,
+    so warnings will be put on stderr even if libpng has CONSOLE_IO disabled.
+  Added png_ptr->process_mode = PNG_READ_IDAT_MODE in png_push_read_chunk
+    after recognizing the IDAT chunk, which avoids an infinite loop while
+    reading a datastream whose first IDAT chunk is of zero-length.
+    This fixes CERT VU#684412 and CVE-2014-0333.
+  Don't recognize known sRGB profiles as sRGB if they have been hacked,
+    but don't reject them and don't issue a copyright violation warning.
+
+Version 1.6.10beta03 [February 25, 2014]
+  Moved some documentation from png.h to libpng.3 and libpng-manual.txt
+  Minor editing of contrib/arm-neon/README and contrib/examples/*.c
+
+Version 1.6.10rc01 [February 27, 2014]
+  Fixed typos in the manual and in scripts/pnglibconf.dfa (CFLAGS -> CPPFLAGS
+    and PNG_USR_CONFIG -> PNG_USER_CONFIG).
+
+Version 1.6.10rc02 [February 28, 2014]
+  Removed unreachable return statement after png_chunk_error()
+    in pngrutil.c
+
+Version 1.6.10rc03 [March 4, 2014]
+  Un-deprecated png_data_freer().
+
+Version 1.6.10 [March 6, 2014]
+  No changes.
+
+Version 1.6.11beta01 [March 17, 2014]
+  Use "if (value != 0)" instead of "if (value)" consistently.
+  Changed ZlibSrcDir from 1.2.5 to 1.2.8 in projects/vstudio.
+  Moved configuration information from the manual to the INSTALL file.
+
+Version 1.6.11beta02 [April 6, 2014]
+  Removed #if/#else/#endif from inside two pow() calls in pngvalid.c because
+    they were handled improperly by Portland Group's PGI-14.1 - PGI-14.3
+    when using its "__builtin_pow()" function.
+  Silence 'unused parameter' build warnings (Cosmin Truta).
+  $(CP) is now used alongside $(RM_F).  Also, use 'copy' instead of 'cp'
+    where applicable, and applied other minor makefile changes (Cosmin).
+  Don't warn about invalid dimensions exceeding user limits (Cosmin).
+  Allow an easy replacement of the default pre-built configuration
+    header with a custom header, via the make PNGLIBCONF_H_PREBUILT
+    macro (Cosmin).
+
+Version 1.6.11beta03 [April 6, 2014]
+  Fixed a typo in pngrutil.c, introduced in libpng-1.5.6, that interferes
+    with "blocky" expansion of sub-8-bit interlaced PNG files (Eric Huss).
+  Optionally use  __builtin_bswap16() in png_do_swap().
+
+Version 1.6.11beta04 [April 19, 2014]
+  Made progressive reading of interlaced images consistent with the
+    behavior of the sequential reader and consistent with the manual, by
+    moving some code out of the PNG_READ_INTERLACING_SUPPORTED blocks. The
+    row_callback now receives the proper pass number and unexpanded rows, when
+    png_combine_row() isn't built or used, and png_set_interlace_handling()
+    is not called.
+  Allow PNG_sRGB_PROFILE_CHECKING = (-1) to mean no sRGB profile checking.
+
+Version 1.6.11beta05 [April 26, 2014]
+  Do not reject ICC V2 profiles that lack padding (Kai-Uwe Behrmann).
+  Relocated closing bracket of the sRGB profile test loop to avoid getting
+    "Not recognizing known sRGB profile that has been edited" warning for
+    ICC V2 profiles that lack the MD5 signature in the profile header.
+
+Version 1.6.11beta06 [May 19, 2014]
+  Added PNG_SKIP_sRGB_CHECK_PROFILE choice for png_set_option().
+
+Version 1.6.11rc01 [May 27, 2014]
+  No changes.
+
+Version 1.6.11rc02 [June 3, 2014]
+  Test ZLIB_VERNUM instead of PNG_ZLIB_VERNUM in contrib/tools/pngfix.c
+
+Version 1.6.11 [June 5, 2014]
+  No changes.
+
+Version 1.6.12rc01 [June 6, 2014]
+  Relocated new code from 1.6.11beta06 in png.c to a point after the
+    declarations (Max Stepin).
+
+Version 1.6.12rc02 [June 7, 2014]
+  Changed file permissions of contrib/tools/intgamma.sh,
+    test-driver, and compile from 0644 to 0755 (Cosmin).
+
+Version 1.6.12rc03 [June 8, 2014]
+  Ensure "__has_attribute()" macro exists before trying to use it with
+    old clang compilers (MacPorts Ticket #43939).
+
+Version 1.6.12 [June 12, 2014]
+  No changes.
+
+Version 1.6.13beta01 [July 4, 2014]
+  Quieted -Wsign-compare and -Wclobber compiler warnings in
+    contrib/pngminus/*.c
+  Added "(void) png_ptr;" where needed in contrib/gregbook to quiet
+    compiler complaints about unused pointers.
+  Split a long output string in contrib/gregbook/rpng2-x.c.
+  Added "PNG_SET_OPTION" requirement for sRGB chunk support to pnglibconf.dfa,
+    Needed for write-only support (John Bowler).
+  Changed "if defined(__ARM_NEON__)" to
+    "if (defined(__ARM_NEON__) || defined(__ARM_NEON))" (James Wu).
+  Fixed clang no-warning builds: png_digit was defined but never used.
+    
+Version 1.6.13beta02 [July 21, 2014]
+  Fixed an incorrect separator ("/" should be "\") in scripts/makefile.vcwin32
+    (bug report from Wolfgang S. Kechel).  Bug was introduced in libpng-1.6.11.
+    Also fixed makefile.bc32, makefile.bor, makefile.msc, makefile.intel, and
+    makefile.tc3 similarly.
+
+Version 1.6.13beta03 [August 3, 2014]
+  Removed scripts/makefile.elf. It has not worked since libpng-1.5.0beta14
+    due to elimination of the PNG_FUNCTION_EXPORT and PNG_DATA_EXPORT
+    definitions from pngconf.h.
+  Ensure that CMakeLists.txt makes the target "lib" directory before making
+    symbolic link into it (SourceForge bug report #226 by Rolf Timmermans).
+
+Version 1.6.13beta04 [August 8, 2014]
+  Added opinion that the ECCN (Export Control Classification Number) for
+    libpng is EAR99 to the README file.
+  Eliminated use of "$<" in makefile explicit rules, when copying
+    $PNGLIBCONF_H_PREBUILT.  This does not work on some versions of make;
+    bug introduced in libpng version 1.6.11.
+
+Version 1.6.13rc01 [August 14, 2014]
+  Made "ccopts" agree with "CFLAGS" in scripts/makefile.hp* and makefile.*sunu
+
+Version 1.6.13 [August 21, 2014]
+  No changes.
+
+Version 1.6.14beta01 [September 14, 2014]
+  Guard usage of png_ptr->options with #ifdef PNG_SET_OPTION_SUPPORTED.
+  Do not build contrib/tools/pngfix.c when PNG_SETJMP_NOT_SUPPORTED,
+    to allow "make" to complete without setjmp support (bug report by
+    Claudio Fontana)
+  Add "#include <setjmp.h>" to contrib/tools/pngfix.c (John Bowler)
+
+Version 1.6.14beta02 [September 18, 2014]
+  Use nanosleep() instead of usleep() in contrib/gregbook/rpng2-x.c
+    because usleep() is deprecated.
+  Define usleep() in contrib/gregbook/rpng2-x.c if not already defined
+    in unistd.h and nanosleep() is not available; fixes error introduced
+    in libpng-1.6.13.
+  Disable floating point exception handling in pngvalid.c when
+    PNG_FLOATING_ARITHMETIC is not supported (bug report by "zootus
+    at users.sourceforge.net").
+
+Version 1.6.14beta03 [September 19, 2014]
+  Define FE_DIVBYZERO, FE_INVALID, and FE_OVERFLOW in pngvalid.c if not
+    already defined.  Revert floating point exception handling in pngvalid.c
+    to version 1.6.14beta01 behavior.
+
+Version 1.6.14beta04 [September 27, 2014]
+  Fixed incorrect handling of the iTXt compression flag in pngrutil.c
+    (bug report by Shunsaku Hirata).  Bug was introduced in libpng-1.6.0.
+
+Version 1.6.14beta05 [October 1, 2014]
+  Added "option READ_iCCP enables READ_COMPRESSED_TEXT" to pnglibconf.dfa
+
+Version 1.6.14beta06 [October 5, 2014]
+  Removed unused "text_len" parameter from private function png_write_zTXt().
+  Conditionally compile some code in png_deflate_claim(), when
+    PNG_WARNINGS_SUPPORTED and PNG_ERROR_TEXT_SUPPORTED are disabled.
+  Replaced repeated code in pngpread.c with PNG_PUSH_SAVE_BUFFER_IF_FULL.
+  Added "chunk iTXt enables TEXT" and "chunk zTXt enables TEXT"
+    to pnglibconf.dfa.
+  Removed "option READ_COMPRESSED_TEXT enables READ_TEXT" from pnglibconf.dfa,
+    to make it possible to configure a libpng that supports iCCP but not TEXT.
+
+Version 1.6.14beta07 [October 7, 2014]
+  Removed "option WRITE_COMPRESSED_TEXT enables WRITE_TEXT" from pnglibconf.dfa
+  Only mark text chunks as written after successfully writing them.
+
+Version 1.6.14rc01 [October 15, 2014]
+  Fixed some typos in comments.
+
+Version 1.6.14rc02 [October 17, 2014]
+  Changed png_convert_to_rfc_1123() to png_convert_to_rfc_1123_buffer()
+    in the manual, to reflect the change made in libpng-1.6.0.
+  Updated README file to explain that direct access to the png_struct
+    and info_struct members has not been permitted since libpng-1.5.0.
+
+Version 1.6.14 [October 23, 2014]
   No changes.
 
-Version 1.5.13 [September 27, 2012]
+Version 1.6.15beta01 [October 29, 2014]
+  Changed "if (!x)" to "if (x == 0)" and "if (x)" to "if (x != 0)"
+  Simplified png_free_data().
+  Added missing "ptr = NULL" after some instances of png_free().
+
+Version 1.6.15beta02 [November 1, 2014]
+  Changed remaining "if (!x)" to "if (x == 0)" and "if (x)" to "if (x != 0)"
+
+Version 1.6.15beta03 [November 3, 2014]
+  Added PNG_USE_ARM_NEON configuration flag (Marcin Juszkiewicz).
+
+Version 1.6.15beta04 [November 4, 2014]
+  Removed new PNG_USE_ARM_NEON configuration flag and made a one-line
+    revision to configure.ac to support ARM on aarch64 instead (John Bowler).
+
+Version 1.6.15beta05 [November 5, 2014]
+  Use png_get_libpng_ver(NULL) instead of PNG_LIBPNG_VER_STRING in
+    example.c, pngtest.c, and applications in the contrib directory.
+  Avoid out-of-bounds memory access in png_user_version_check().
+  Simplified and future-proofed png_user_version_check().
+  Fixed GCC unsigned int->float warnings. Various versions of GCC
+    seem to generate warnings when an unsigned value is implicitly
+    converted to double. This is probably a GCC bug but this change
+    avoids the issue by explicitly converting to (int) where safe.
+  Free all allocated memory in pngimage. The file buffer cache was left
+    allocated at the end of the program, harmless but it causes memory
+    leak reports from clang.
+  Fixed array size calculations to avoid warnings. At various points
+    in the code the number of elements in an array is calculated using
+    sizeof.  This generates a compile time constant of type (size_t) which
+    is then typically assigned to an (unsigned int) or (int). Some versions
+    of GCC on 64-bit systems warn about the apparent narrowing, even though
+    the same compiler does apparently generate the correct, in-range,
+    numeric constant.  This adds appropriate, safe, casts to make the
+    warnings go away.
+
+Version 1.6.15beta06 [November 6, 2014]
+  Reverted use png_get_libpng_ver(NULL) instead of PNG_LIBPNG_VER_STRING
+    in the manual, example.c, pngtest.c, and applications in the contrib
+    directory.  It was incorrect advice.
+
+Version 1.6.15beta07 [November 7, 2014]
+  Removed #ifdef PNG_16BIT_SUPPORTED/#endif around png_product2(); it is
+    needed by png_reciprocal2().
+  Added #ifdef PNG_16BIT_SUPPORTED/#endif around png_log16bit() and
+    png_do_swap().
+  Changed all "#endif /* PNG_FEATURE_SUPPORTED */" to "#endif /* FEATURE */"
+
+Version 1.6.15beta08 [November 8, 2014]
+  More housecleaning in *.h
+
+Version 1.6.15rc01 [November 13, 2014]
+
+Version 1.6.15rc02 [November 14, 2014]
+  The macros passed in the command line to Borland make were ignored if
+    similarly-named macros were already defined in makefiles. This behavior
+    is different from POSIX make and other make programs.  Surround the
+    macro definitions with ifndef guards (Cosmin).
+
+Version 1.6.15rc03 [November 16, 2014]
+  Added "-D_CRT_SECURE_NO_WARNINGS" to CFLAGS in scripts/makefile.vcwin32.
+  Removed the obsolete $ARCH variable from scripts/makefile.darwin.
+
+Version 1.6.15 [November 20, 2014]
+  No changes.
+
+Version 1.6.16beta01 [December 14, 2014]
+  Added ".align 2" to arm/filter_neon.S to support old GAS assemblers that
+    don't do alignment correctly.
+  Revised Makefile.am and scripts/symbols.dfn to work with MinGW/MSYS
+    (Bob Friesenhahn).
+
+Version 1.6.16beta02 [December 15, 2014]
+  Revised Makefile.am and scripts/*.dfn again to work with MinGW/MSYS;
+    renamed scripts/*.dfn to scripts/*.c (John Bowler).
+
+Version 1.6.16beta03 [December 21, 2014]
+  Quiet a "comparison always true" warning in pngstest.c (John Bowler).
+
+Version 1.6.16rc01 [December 21, 2014]
+  Restored a test on width that was removed from png.c at libpng-1.6.9
+    (Bug report by Alex Eubanks).
+
+Version 1.6.16rc02 [December 21, 2014]
+  Undid the update to pngrutil.c in 1.6.16rc01.
+
+Version 1.6.16rc03 [December 21, 2014]
+  Fixed an overflow in png_combine_row with very wide interlaced images.
+
+Version 1.6.16 [December 22, 2014]
   No changes.
 
 Send comments/corrections/commendations to png-mng-implement at lists.sf.net
@@ -3926,4 +5132,3 @@ to subscribe)
 or to glennrp at users.sourceforge.net
 
 Glenn R-P
-#endif
diff --git a/Source/LibPNG/CMakeLists.txt b/Source/LibPNG/CMakeLists.txt
new file mode 100644
index 0000000..e01ebd3
--- /dev/null
+++ b/Source/LibPNG/CMakeLists.txt
@@ -0,0 +1,365 @@
+# CMakeLists.txt
+
+# Copyright (C) 2007-2014 Glenn Randers-Pehrson
+
+# This code is released under the libpng license.
+# For conditions of distribution and use, see the disclaimer
+# and license in png.h
+
+cmake_minimum_required(VERSION 2.4.4)
+set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
+
+set(CMAKE_CONFIGURATION_TYPES "Release;Debug;MinSizeRel;RelWithDebInfo")
+
+project(libpng C)
+enable_testing()
+
+set(PNGLIB_MAJOR 1)
+set(PNGLIB_MINOR 6)
+set(PNGLIB_RELEASE 16)
+set(PNGLIB_NAME libpng${PNGLIB_MAJOR}${PNGLIB_MINOR})
+set(PNGLIB_VERSION ${PNGLIB_MAJOR}.${PNGLIB_MINOR}.${PNGLIB_RELEASE})
+
+# needed packages
+find_package(ZLIB REQUIRED)
+include_directories(${ZLIB_INCLUDE_DIR})
+
+if(NOT WIN32)
+  find_library(M_LIBRARY
+    NAMES m
+    PATHS /usr/lib /usr/local/lib
+  )
+  if(NOT M_LIBRARY)
+    message(STATUS
+      "math library 'libm' not found - floating point support disabled")
+  endif()
+else()
+  # not needed on windows
+  set(M_LIBRARY "")
+endif()
+
+# COMMAND LINE OPTIONS
+if(DEFINED PNG_SHARED)
+  option(PNG_SHARED "Build shared lib" ${PNG_SHARED})
+else()
+  option(PNG_SHARED "Build shared lib" ON)
+endif()
+if(DEFINED PNG_STATIC)
+  option(PNG_STATIC "Build static lib" ${PNG_STATIC})
+else()
+  option(PNG_STATIC "Build static lib" ON)
+endif()
+
+option(PNG_TESTS  "Build libpng tests" YES)
+
+# Many more configuration options could be added here
+option(PNG_DEBUG         "Build with debug output" NO)
+option(PNGARG            "Disable ANSI-C prototypes" NO)
+
+# SET LIBNAME
+set(PNG_LIB_NAME png${PNGLIB_MAJOR}${PNGLIB_MINOR})
+
+# to distinguish between debug and release lib
+set(CMAKE_DEBUG_POSTFIX "d")
+
+# Use the prebuilt pnglibconf.h file from the scripts folder
+# TODO: fix this by building with awk; without this no cmake build can be
+# configured directly (to do so indirectly use your local awk to build a
+# pnglibconf.h in the build directory.)
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.h.prebuilt
+               ${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h)
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+# OUR SOURCES
+set(libpng_public_hdrs
+  png.h
+  pngconf.h
+  ${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h
+)
+set(libpng_sources
+  ${libpng_public_hdrs}
+  pngdebug.h
+  pnginfo.h
+  pngpriv.h
+  pngstruct.h
+  png.c
+  pngerror.c
+  pngget.c
+  pngmem.c
+  pngpread.c
+  pngread.c
+  pngrio.c
+  pngrtran.c
+  pngrutil.c
+  pngset.c
+  pngtrans.c
+  pngwio.c
+  pngwrite.c
+  pngwtran.c
+  pngwutil.c
+)
+set(pngtest_sources
+  pngtest.c
+)
+set(pngvalid_sources
+  contrib/libtests/pngvalid.c
+)
+set(pngstest_sources
+  contrib/libtests/pngstest.c
+)
+# SOME NEEDED DEFINITIONS
+
+if(MSVC)
+  add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
+endif(MSVC)
+
+if(PNG_DEBUG)
+  add_definitions(-DPNG_DEBUG)
+endif()
+
+# NOW BUILD OUR TARGET
+include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${ZLIB_INCLUDE_DIR})
+
+unset(PNG_LIB_TARGETS)
+
+if(PNG_SHARED)
+  add_library(${PNG_LIB_NAME} SHARED ${libpng_sources})
+  set(PNG_LIB_TARGETS ${PNG_LIB_NAME})
+  if(MSVC)
+    # msvc does not append 'lib' - do it here to have consistent name
+    set_target_properties(${PNG_LIB_NAME} PROPERTIES PREFIX "lib")
+    set_target_properties(${PNG_LIB_NAME} PROPERTIES IMPORT_PREFIX "lib")
+  endif()
+  target_link_libraries(${PNG_LIB_NAME} ${ZLIB_LIBRARY} ${M_LIBRARY})
+endif()
+
+if(PNG_STATIC)
+# does not work without changing name
+  set(PNG_LIB_NAME_STATIC ${PNG_LIB_NAME}_static)
+  add_library(${PNG_LIB_NAME_STATIC} STATIC ${libpng_sources})
+  list(APPEND PNG_LIB_TARGETS ${PNG_LIB_NAME_STATIC})
+  if(MSVC)
+    # msvc does not append 'lib' - do it here to have consistent name
+    set_target_properties(${PNG_LIB_NAME_STATIC} PROPERTIES PREFIX "lib")
+  endif()
+  target_link_libraries(${PNG_LIB_NAME_STATIC} ${ZLIB_LIBRARY} ${M_LIBRARY})
+endif()
+
+if(NOT PNG_LIB_TARGETS)
+  message(SEND_ERROR
+    "No library variant selected to build. "
+    "Please enable at least one of the following options: PNG_STATIC, PNG_SHARED")
+endif()
+
+if(PNG_SHARED AND WIN32)
+  set_target_properties(${PNG_LIB_NAME} PROPERTIES DEFINE_SYMBOL PNG_BUILD_DLL)
+endif()
+
+if(PNG_TESTS AND PNG_SHARED)
+  # does not work with msvc due to png_lib_ver issue
+  add_executable(pngtest ${pngtest_sources})
+  target_link_libraries(pngtest ${PNG_LIB_NAME})
+  add_test(pngtest ./pngtest ${CMAKE_CURRENT_SOURCE_DIR}/pngtest.png)
+  #
+  add_executable(pngvalid ${pngvalid_sources})
+  target_link_libraries(pngvalid ${PNG_LIB_NAME})
+  add_test(pngvalid ./pngvalid)
+  add_executable(pngstest ${pngstest_sources})
+  target_link_libraries(pngstest ${PNG_LIB_NAME})
+  add_test(pngstest ./pngstest
+    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn0g01.png
+    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn0g02.png
+    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn0g04.png
+    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn0g08.png
+    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn0g16.png
+    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn2c08.png
+    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn2c16.png
+    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn3p01.png
+    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn3p02.png
+    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn3p04.png
+    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn3p08.png
+    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn4a08.png
+    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn4a16.png
+    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn6a08.png
+    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn6a16.png
+    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftbbn0g01.png
+    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftbbn0g02.png
+    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftbbn0g04.png
+    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftbbn2c16.png
+    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftbbn3p08.png
+    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftbgn2c16.png
+    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftbgn3p08.png
+    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftbrn2c08.png
+    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftbwn0g16.png
+    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftbwn3p08.png
+    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftbyn3p08.png
+    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftp0n0g08.png
+    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftp0n2c08.png
+    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftp0n3p08.png
+    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftp1n3p08.png
+  )
+endif()
+
+# Ensure the CMAKE_LIBRARY_OUTPUT_DIRECTORY is set
+IF(NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY)
+  SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY "lib")
+ENDIF(NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY)
+
+# Set a variable with CMake code which:
+# Creates a symlink from src to dest (if possible) or alternatively
+# copies if different.
+macro(CREATE_SYMLINK SRC_FILE DEST_FILE)
+  FILE(REMOVE ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${DEST_FILE})
+  if(WIN32 AND NOT CYGWIN AND NOT MSYS)
+    ADD_CUSTOM_COMMAND(
+        OUTPUT ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${DEST_FILE}   ${CMAKE_CURRENT_BINARY_DIR}/${DEST_FILE}
+        COMMAND ${CMAKE_COMMAND} -E copy_if_different  "${SRC_FILE}" ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${DEST_FILE}
+        COMMAND ${CMAKE_COMMAND} -E copy_if_different  "${SRC_FILE}" ${CMAKE_CURRENT_BINARY_DIR}/${DEST_FILE}
+        DEPENDS ${PNG_LIB_TARGETS}
+        )
+    ADD_CUSTOM_TARGET(${DEST_FILE}_COPY ALL DEPENDS ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${DEST_FILE})
+  else(WIN32 AND NOT CYGWIN AND NOT MSYS)
+    get_filename_component(LINK_TARGET "${SRC_FILE}" NAME)
+    execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
+    execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${LINK_TARGET}" ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${DEST_FILE} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
+    execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${LINK_TARGET}" ${DEST_FILE} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
+  endif(WIN32 AND NOT CYGWIN AND NOT MSYS)
+endmacro()
+
+# libpng is a library so default to 'lib'
+if(NOT DEFINED CMAKE_INSTALL_LIBDIR)
+  set(CMAKE_INSTALL_LIBDIR lib)
+endif(NOT DEFINED CMAKE_INSTALL_LIBDIR)
+
+# CREATE PKGCONFIG FILES
+# we use the same files like ./configure, so we have to set its vars
+# Only do this on Windows for Cygwin - the files don't make much sense outside
+# a UNIX look alike
+if(NOT WIN32 OR CYGWIN OR MINGW)
+  set(prefix      ${CMAKE_INSTALL_PREFIX})
+  set(exec_prefix ${CMAKE_INSTALL_PREFIX})
+  set(libdir      ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR})
+  set(includedir  ${CMAKE_INSTALL_PREFIX}/include)
+  set(LIBS        "-lz -lm")
+  configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libpng.pc.in
+    ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}.pc @ONLY)
+  CREATE_SYMLINK(${PNGLIB_NAME}.pc libpng.pc)
+
+  configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libpng-config.in
+    ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}-config @ONLY)
+  CREATE_SYMLINK(${PNGLIB_NAME}-config libpng-config)
+endif(NOT WIN32 OR CYGWIN OR MINGW)
+
+# SET UP LINKS
+if(PNG_SHARED)
+  set_target_properties(${PNG_LIB_NAME} PROPERTIES
+#   VERSION 16.${PNGLIB_RELEASE}.1.6.16
+    VERSION 16.${PNGLIB_RELEASE}.0
+    SOVERSION 16
+    CLEAN_DIRECT_OUTPUT 1)
+endif()
+if(PNG_STATIC)
+  # MSVC doesn't use a different file extension for shared vs. static
+  # libs.  We are able to change OUTPUT_NAME to remove the _static
+  # for all other platforms.
+  if(NOT MSVC)
+    set_target_properties(${PNG_LIB_NAME_STATIC} PROPERTIES
+      OUTPUT_NAME ${PNG_LIB_NAME}
+      CLEAN_DIRECT_OUTPUT 1)
+  endif()
+endif()
+
+# If CMake > 2.4.x, we set a variable used below to export
+# targets to an export file.
+# TODO: Use VERSION_GREATER after our cmake_minimum_required >= 2.6.2
+if(CMAKE_MAJOR_VERSION GREATER 1 AND CMAKE_MINOR_VERSION GREATER 4)
+  set(PNG_EXPORT_RULE EXPORT libpng)
+elseif(CMAKE_MAJOR_VERSION GREATER 2) # future proof
+  set(PNG_EXPORT_RULE EXPORT libpng)
+endif()
+
+# INSTALL
+if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL )
+  install(TARGETS ${PNG_LIB_TARGETS}
+      ${PNG_EXPORT_RULE}
+      RUNTIME DESTINATION bin
+      LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+      ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
+
+  if(PNG_SHARED)
+    # Create a symlink for libpng.dll.a => libpng16.dll.a on Cygwin
+    if(CYGWIN OR MINGW)
+       get_target_property(BUILD_TARGET_LOCATION ${PNG_LIB_NAME} LOCATION_${CMAKE_BUILD_TYPE})
+       CREATE_SYMLINK(${BUILD_TARGET_LOCATION} libpng${CMAKE_IMPORT_LIBRARY_SUFFIX})
+       install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libpng${CMAKE_IMPORT_LIBRARY_SUFFIX}
+         DESTINATION ${CMAKE_INSTALL_LIBDIR})
+    endif(CYGWIN OR MINGW)
+
+    if(NOT WIN32)
+      get_target_property(BUILD_TARGET_LOCATION ${PNG_LIB_NAME} LOCATION_${CMAKE_BUILD_TYPE})
+      CREATE_SYMLINK(${BUILD_TARGET_LOCATION} libpng${CMAKE_SHARED_LIBRARY_SUFFIX})
+      install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libpng${CMAKE_SHARED_LIBRARY_SUFFIX}
+         DESTINATION ${CMAKE_INSTALL_LIBDIR})
+    endif(NOT WIN32)
+  endif(PNG_SHARED)
+
+  if(PNG_STATIC)
+    if(NOT WIN32 OR CYGWIN OR MINGW)
+      get_target_property(BUILD_TARGET_LOCATION ${PNG_LIB_NAME_STATIC} LOCATION_${CMAKE_BUILD_TYPE})
+      CREATE_SYMLINK(${BUILD_TARGET_LOCATION} libpng${CMAKE_STATIC_LIBRARY_SUFFIX})
+      install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libpng${CMAKE_STATIC_LIBRARY_SUFFIX}
+         DESTINATION ${CMAKE_INSTALL_LIBDIR})
+    endif(NOT WIN32 OR CYGWIN OR MINGW)
+ endif()
+endif()
+
+if(NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL )
+  install(FILES ${libpng_public_hdrs}   DESTINATION include)
+  install(FILES ${libpng_public_hdrs}   DESTINATION include/${PNGLIB_NAME})
+endif()
+if(NOT SKIP_INSTALL_EXECUTABLES AND NOT SKIP_INSTALL_ALL )
+  if(NOT WIN32 OR CYGWIN OR MINGW)
+    install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/libpng-config DESTINATION bin)
+    install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}-config
+            DESTINATION bin)
+  endif(NOT WIN32 OR CYGWIN OR MINGW)
+endif()
+
+if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL )
+  # Install man pages
+  if(NOT PNG_MAN_DIR)
+    set(PNG_MAN_DIR "share/man")
+  endif()
+  install(FILES libpng.3 libpngpf.3      DESTINATION ${PNG_MAN_DIR}/man3)
+  install(FILES png.5                    DESTINATION ${PNG_MAN_DIR}/man5)
+  # Install pkg-config files
+  if(NOT WIN32 OR CYGWIN OR MINGW)
+    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libpng.pc
+            DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
+    install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/libpng-config
+            DESTINATION bin)
+    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}.pc
+            DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
+    install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}-config
+            DESTINATION bin)
+  endif(NOT WIN32 OR CYGWIN OR MINGW)
+endif()
+
+# On versions of CMake that support it, create an export file CMake
+# users can include() to import our targets
+if(PNG_EXPORT_RULE AND NOT SKIP_INSTALL_EXPORT AND NOT SKIP_INSTALL_ALL )
+  install(EXPORT libpng DESTINATION lib/libpng FILE lib${PNG_LIB_NAME}.cmake)
+endif()
+
+# what's with libpng-manual.txt and all the extra files?
+
+# UNINSTALL
+# do we need this?
+
+# DIST
+# do we need this?
+
+# to create msvc import lib for mingw compiled shared lib
+# pexports libpng.dll > libpng.def
+# lib /def:libpng.def /machine:x86
+
diff --git a/Source/LibPNG/INSTALL b/Source/LibPNG/INSTALL
index c2d6c9e..26852c4 100644
--- a/Source/LibPNG/INSTALL
+++ b/Source/LibPNG/INSTALL
@@ -1,32 +1,69 @@
 
 Installing libpng
 
+Contents
+
+   I. Simple installation
+  II. Rebuilding the configure scripts
+ III. Using scripts/makefile*
+  IV. Using cmake
+   V. Directory structure
+  VI. Building with project files
+ VII. Building with makefiles
+VIII. Configuring libpng for 16-bit platforms
+  IX. Configuring for DOS
+   X. Configuring for Medium Model
+  XI. Prepending a prefix to exported symbols
+ XII. Configuring for compiler xxx:
+XIII. Removing unwanted object code
+ XIV. Changes to the build and configuration of libpng in libpng-1.5.x
+  XV. Configuring libpng for multiprocessing
+ XVI. Other sources of information about libpng
+
+I. Simple installation
+
 On Unix/Linux and similar systems, you can simply type
 
     ./configure [--prefix=/path]
     make check
     make install
 
-and ignore the rest of this document.
+and ignore the rest of this document.  "/path" is the path to the directory
+where you want to install the libpng "lib", "include", and "bin"
+subdirectories.
+
+If you downloaded a GIT clone, you will need to run ./autogen.sh before
+running ./configure, to create "configure" and "Makefile.in" which are
+not included in the GIT repository.
 
-If configure does not work on your system and you have a reasonably
-up-to-date set of tools, running ./autogen.sh before running ./configure
-may fix the problem.  You can also run the individual commands in
-autogen.sh with the --force option, if supported by your version of
-the tools.  To be really sure that you aren't using any of the included
-pre-built scripts, you can do this:
+Note that "configure" is only included in the "*.tar" distributions and not
+in the "*.zip" or "*.7z" distributions. If you downloaded one of those
+distributions, see "Building with project files" or "Building with makefiles",
+below.
+
+II. Rebuilding the configure scripts
+
+If configure does not work on your system, or if you have a need to
+change configure.ac or Makefile.am, and you have a reasonably
+up-to-date set of tools, running ./autogen.sh in a git clone before
+running ./configure may fix the problem.  To be really sure that you
+aren't using any of the included pre-built scripts, you can do this:
 
     ./configure --enable-maintainer-mode
     make maintainer-clean
-    ./autogen.sh
+    ./autogen.sh --maintainer --clean
+    ./autogen.sh --maintainer
     ./configure [--prefix=/path] [other options]
     make
     make install
     make check
 
+III. Using scripts/makefile*
+
 Instead, you can use one of the custom-built makefiles in the
 "scripts" directory
 
+    cp scripts/pnglibconf.h.prebuilt pnglibconf.h
     cp scripts/makefile.system makefile
     make test
     make install
@@ -38,8 +75,28 @@ Or you can use one of the "projects" in the "projects" directory.
 
 Before installing libpng, you must first install zlib, if it
 is not already on your system.  zlib can usually be found
-wherever you got libpng.  zlib can be placed in another directory,
-at the same level as libpng.
+wherever you got libpng; otherwise go to http://zlib.net.  You can place
+zlib in in the same directory as libpng or in another directory.
+
+If your system already has a preinstalled zlib you will still need
+to have access to the zlib.h and zconf.h include files that
+correspond to the version of zlib that's installed.
+
+If you wish to test with a particular zlib that is not first in the
+standard library search path, put ZLIBLIB, ZLIBINC, CPPFLAGS, LDFLAGS,
+and LD_LIBRARY_PATH in your environment before running "make test"
+or "make distcheck":
+
+ZLIBLIB=/path/to/lib export ZLIBLIB
+ZLIBINC=/path/to/include export ZLIBINC
+CPPFLAGS="-I$ZLIBINC" export CPPFLAGS
+LDFLAGS="-L$ZLIBLIB" export LDFLAGS
+LD_LIBRARY_PATH="$ZLIBLIB:$LD_LIBRARY_PATH" export LD_LIBRARY_PATH
+
+If you are using one of the makefile scripts, put ZLIBLIB and ZLIBINC
+in your environment and type "make ZLIBLIB=$ZLIBLIB ZLIBINC=$ZLIBINC test".
+
+IV. Using cmake
 
 If you want to use "cmake" (see www.cmake.org), type
 
@@ -47,13 +104,15 @@ If you want to use "cmake" (see www.cmake.org), type
    make
    make install
 
-If your system already has a preinstalled zlib you will still need
-to have access to the zlib.h and zconf.h include files that
-correspond to the version of zlib that's installed.
+As when using the simple configure method described above, "/path" points to
+the installation directory where you want to put the libpng "lib", "include",
+and "bin" subdirectories.
+
+V. Directory structure
 
 You can rename the directories that you downloaded (they
-might be called "libpng-x.y.z" or "libpngNN" and "zlib-1.2.5"
-or "zlib125") so that you have directories called "zlib" and "libpng".
+might be called "libpng-x.y.z" or "libpngNN" and "zlib-1.2.8"
+or "zlib128") so that you have directories called "zlib" and "libpng".
 
 Your directory structure should look like this:
 
@@ -61,8 +120,7 @@ Your directory structure should look like this:
       libpng  (this directory)
           INSTALL (this file)
           README
-          *.h
-          *.c
+          *.h, *.c  => libpng source files
           CMakeLists.txt    =>  "cmake" script
           configuration files:
              configure.ac, configure, Makefile.am, Makefile.in,
@@ -70,14 +128,10 @@ Your directory structure should look like this:
              libpng-config.in, aclocal.m4, config.h.in, config.sub,
              depcomp, install-sh, mkinstalldirs, test-pngtest.sh
           contrib
-             gregbook
-             pngminim
-             pngminus
-             pngsuite
-             visupng
+             arm-neon, conftest, examples, gregbook, libtests, pngminim,
+             pngminus, pngsuite, tools, visupng
           projects
-             visualc71
-             vstudio
+             cbuilder5, owatcom, visualc71, vstudio, xcode
           scripts
              makefile.*
              *.def (module definition files)
@@ -85,29 +139,31 @@ Your directory structure should look like this:
           pngtest.png
           etc.
       zlib
-          README
-          *.h
-          *.c
-          contrib
-          etc.
+          README, *.h, *.c contrib, etc.
 
 If the line endings in the files look funny, you may wish to get the other
 distribution of libpng.  It is available in both tar.gz (UNIX style line
 endings) and zip (DOS style line endings) formats.
 
+VI. Building with project files
+
 If you are building libpng with MSVC, you can enter the
-libpng projects\visualc6 or visualc71 directory and follow the instructions
+libpng projects\visualc71 or vstudio directory and follow the instructions
 in README.txt.
 
 Otherwise enter the zlib directory and follow the instructions in zlib/README,
 then come back here and run "configure" or choose the appropriate
 makefile.sys in the scripts directory.
 
+VII. Building with makefiles
+
 Copy the file (or files) that you need from the
 scripts directory into this directory, for example
 
    MSDOS example: copy scripts\makefile.msc makefile
-   UNIX example:    cp scripts/makefile.std makefile
+                  copy scripts\pnglibconf.h.prebuilt pnglibconf.h
+   UNIX example:  cp scripts/makefile.std makefile
+                  cp scripts/pnglibconf.h.prebuilt pnglibconf.h
 
 Read the makefile to see if you need to change any source or
 target directories to match your preferences.
@@ -130,6 +186,197 @@ do that, run "make install" in the zlib directory first if necessary).
 Some also allow you to run "make test-installed" after you have
 run "make install".
 
+VIII. Configuring libpng for 16-bit platforms
+
+You will want to look into zconf.h to tell zlib (and thus libpng) that
+it cannot allocate more then 64K at a time.  Even if you can, the memory
+won't be accessible.  So limit zlib and libpng to 64K by defining MAXSEG_64K.
+
+IX. Configuring for DOS
+
+For DOS users who only have access to the lower 640K, you will
+have to limit zlib's memory usage via a png_set_compression_mem_level()
+call.  See zlib.h or zconf.h in the zlib library for more information.
+
+X. Configuring for Medium Model
+
+Libpng's support for medium model has been tested on most of the popular
+compilers.  Make sure MAXSEG_64K gets defined, USE_FAR_KEYWORD gets
+defined, and FAR gets defined to far in pngconf.h, and you should be
+all set.  Everything in the library (except for zlib's structure) is
+expecting far data.  You must use the typedefs with the p or pp on
+the end for pointers (or at least look at them and be careful).  Make
+note that the rows of data are defined as png_bytepp, which is
+an "unsigned char far * far *".
+
+XI. Prepending a prefix to exported symbols
+
+Starting with libpng-1.6.0, you can configure libpng (when using the
+"configure" script) to prefix all exported symbols by means of the
+configuration option "--with-libpng-prefix=FOO_", where FOO_ can be any
+string beginning with a letter and containing only uppercase
+and lowercase letters, digits, and the underscore (i.e., a C language
+identifier).  This creates a set of macros in pnglibconf.h, so this is
+transparent to applications; their function calls get transformed by
+the macros to use the modified names.
+
+XII. Configuring for compiler xxx:
+
+All includes for libpng are in pngconf.h.  If you need to add, change
+or delete an include, this is the place to do it.
+The includes that are not needed outside libpng are placed in pngpriv.h,
+which is only used by the routines inside libpng itself.
+The files in libpng proper only include pngpriv.h and png.h, which
+in turn includes pngconf.h and, as of libpng-1.5.0, pnglibconf.h.
+As of libpng-1.5.0, pngpriv.h also includes three other private header
+files, pngstruct.h, pnginfo.h, and pngdebug.h, which contain material
+that previously appeared in the public headers.
+
+XIII. Removing unwanted object code
+
+There are a bunch of #define's in pngconf.h that control what parts of
+libpng are compiled.  All the defines end in _SUPPORTED.  If you are
+never going to use a capability, you can change the #define to #undef
+before recompiling libpng and save yourself code and data space, or
+you can turn off individual capabilities with defines that begin with
+PNG_NO_.
+
+In libpng-1.5.0 and later, the #define's are in pnglibconf.h instead.
+
+You can also turn all of the transforms and ancillary chunk capabilities
+off en masse with compiler directives that define
+PNG_NO_READ[or WRITE]_TRANSFORMS, or PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS,
+or all four, along with directives to turn on any of the capabilities that
+you do want.  The PNG_NO_READ[or WRITE]_TRANSFORMS directives disable the
+extra transformations but still leave the library fully capable of reading
+and writing PNG files with all known public chunks. Use of the
+PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS directive produces a library
+that is incapable of reading or writing ancillary chunks.  If you are
+not using the progressive reading capability, you can turn that off
+with PNG_NO_PROGRESSIVE_READ (don't confuse this with the INTERLACING
+capability, which you'll still have).
+
+All the reading and writing specific code are in separate files, so the
+linker should only grab the files it needs.  However, if you want to
+make sure, or if you are building a stand alone library, all the
+reading files start with "pngr" and all the writing files start with "pngw".
+The files that don't match either (like png.c, pngtrans.c, etc.)
+are used for both reading and writing, and always need to be included.
+The progressive reader is in pngpread.c
+
+If you are creating or distributing a dynamically linked library (a .so
+or DLL file), you should not remove or disable any parts of the library,
+as this will cause applications linked with different versions of the
+library to fail if they call functions not available in your library.
+The size of the library itself should not be an issue, because only
+those sections that are actually used will be loaded into memory.
+
+XIV. Changes to the build and configuration of libpng in libpng-1.5.x
+
+Details of internal changes to the library code can be found in the CHANGES
+file and in the GIT repository logs.  These will be of no concern to the vast
+majority of library users or builders; however, the few who configure libpng
+to a non-default feature set may need to change how this is done.
+
+There should be no need for library builders to alter build scripts if
+these use the distributed build support - configure or the makefiles -
+however, users of the makefiles may care to update their build scripts
+to build pnglibconf.h where the corresponding makefile does not do so.
+
+Building libpng with a non-default configuration has changed completely.
+The old method using pngusr.h should still work correctly even though the
+way pngusr.h is used in the build has been changed; however, library
+builders will probably want to examine the changes to take advantage of
+new capabilities and to simplify their build system.
+
+A. Specific changes to library configuration capabilities
+
+The exact mechanism used to control attributes of API functions has
+changed.  A single set of operating system independent macro definitions
+is used and operating system specific directives are defined in
+pnglibconf.h
+
+As part of this the mechanism used to choose procedure call standards on
+those systems that allow a choice has been changed.  At present this only
+affects certain Microsoft (DOS, Windows) and IBM (OS/2) operating systems
+running on Intel processors.  As before, PNGAPI is defined where required
+to control the exported API functions; however, two new macros, PNGCBAPI
+and PNGCAPI, are used instead for callback functions (PNGCBAPI) and
+(PNGCAPI) for functions that must match a C library prototype (currently
+only png_longjmp_ptr, which must match the C longjmp function.)  The new
+approach is documented in pngconf.h
+
+Despite these changes, libpng 1.5.0 only supports the native C function
+calling standard on those platforms tested so far (__cdecl on Microsoft
+Windows).  This is because the support requirements for alternative
+calling conventions seem to no longer exist.  Developers who find it
+necessary to set PNG_API_RULE to 1 should advise the mailing list
+(png-mng-implement) of this and library builders who use Openwatcom and
+therefore set PNG_API_RULE to 2 should also contact the mailing list.
+
+B. Changes to the configuration mechanism
+
+Prior to libpng-1.5.0 library builders who needed to configure libpng
+had either to modify the exported pngconf.h header file to add system
+specific configuration or had to write feature selection macros into
+pngusr.h and cause this to be included into pngconf.h by defining
+PNG_USER_CONFIG. The latter mechanism had the disadvantage that an
+application built without PNG_USER_CONFIG defined would see the
+unmodified, default, libpng API and thus would probably fail to link.
+
+These mechanisms still work in the configure build and in any makefile
+build that builds pnglibconf.h, although the feature selection macros
+have changed somewhat as described above.  In 1.5.0, however, pngusr.h is
+processed only once, at the time the exported header file pnglibconf.h is
+built.  pngconf.h no longer includes pngusr.h; therefore, pngusr.h is ignored
+after the build of pnglibconf.h and it is never included in an application
+build.
+
+The formerly used alternative of adding a list of feature macros to the
+CPPFLAGS setting in the build also still works; however, the macros will be
+copied to pnglibconf.h and this may produce macro redefinition warnings
+when the individual C files are compiled.
+
+All configuration now only works if pnglibconf.h is built from
+scripts/pnglibconf.dfa.  This requires the program awk.  Brian Kernighan
+(the original author of awk) maintains C source code of that awk and this
+and all known later implementations (often called by subtly different
+names - nawk and gawk for example) are adequate to build pnglibconf.h.
+The Sun Microsystems (now Oracle) program 'awk' is an earlier version
+and does not work; this may also apply to other systems that have a
+functioning awk called 'nawk'.
+
+Configuration options are now documented in scripts/pnglibconf.dfa.  This
+file also includes dependency information that ensures a configuration is
+consistent; that is, if a feature is switched off, dependent features are
+also switched off.  As a recommended alternative to using feature macros in
+pngusr.h a system builder may also define equivalent options in pngusr.dfa
+(or, indeed, any file) and add that to the configuration by setting
+DFA_XTRA to the file name.  The makefiles in contrib/pngminim illustrate
+how to do this, and also illustrate a case where pngusr.h is still required.
+
+After you have built libpng, the definitions that were recorded in
+pnglibconf.h are available to your application (pnglibconf.h is included
+in png.h and gets installed alongside png.h and pngconf.h in your
+$PREFIX/include directory).  Do not edit pnglibconf.h after you have built
+libpng, because than the settings would not accurately reflect the settings
+that were used to build libpng.
+
+XV. Configuring libpng for multiprocessing
+
+Libpng uses setjmp()/longjmp() for error handling.  Unfortunately setjmp()
+is known to be not thread-safe on some platforms and we don't know of
+any platform where it is guaranteed to be thread-safe.  Therefore, if
+your application is going to be using multiple threads, you should
+configure libpng with PNG_NO_SETJMP in your pngusr.dfa file, with
+-DPNG_NO_SETJMP on your compile line, or with
+
+  #undef PNG_SETJMP_SUPPORTED
+
+in your pnglibconf.h or pngusr.h.
+
+XVI. Other sources of information about libpng:
+
 Further information can be found in the README and libpng-manual.txt
 files, in the individual makefiles, in png.h, and the manual pages
 libpng.3 and png.5.
diff --git a/Source/LibPNG/LICENSE b/Source/LibPNG/LICENSE
index 853fb2c..eec9c17 100644
--- a/Source/LibPNG/LICENSE
+++ b/Source/LibPNG/LICENSE
@@ -10,8 +10,8 @@ this sentence.
 
 This code is released under the libpng license.
 
-libpng versions 1.2.6, August 15, 2004, through 1.5.13, September 27, 2012, are
-Copyright (c) 2004, 2006-2012 Glenn Randers-Pehrson, and are
+libpng versions 1.2.6, August 15, 2004, through 1.6.16, December 22, 2014, are
+Copyright (c) 2004, 2006-2014 Glenn Randers-Pehrson, and are
 distributed according to the same disclaimer and license as libpng-1.2.5
 with the following individual added to the list of Contributing Authors
 
@@ -108,4 +108,4 @@ certification mark of the Open Source Initiative.
 
 Glenn Randers-Pehrson
 glennrp at users.sourceforge.net
-September 27, 2012
+December 22, 2014
diff --git a/Source/LibPNG/LibPNG.2003.vcproj b/Source/LibPNG/LibPNG.2003.vcproj
deleted file mode 100644
index 2abf944..0000000
--- a/Source/LibPNG/LibPNG.2003.vcproj
+++ /dev/null
@@ -1,203 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="7.10"
-	Name="LibPNG"
-	SccProjectName=""$/FreeImage/LibPNG", PJAAAAAA"
-	SccLocalPath=".">
-	<Platforms>
-		<Platform
-			Name="Win32"/>
-	</Platforms>
-	<Configurations>
-		<Configuration
-			Name="Release|Win32"
-			OutputDirectory=".\Release"
-			IntermediateDirectory=".\Release"
-			ConfigurationType="4"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="FALSE"
-			CharacterSet="2">
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="2"
-				GlobalOptimizations="TRUE"
-				InlineFunctionExpansion="2"
-				EnableIntrinsicFunctions="TRUE"
-				FavorSizeOrSpeed="1"
-				OmitFramePointers="TRUE"
-				OptimizeForProcessor="3"
-				AdditionalIncludeDirectories="..\zlib"
-				PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
-				StringPooling="TRUE"
-				RuntimeLibrary="0"
-				BufferSecurityCheck="FALSE"
-				UsePrecompiledHeader="2"
-				PrecompiledHeaderFile=".\Release/LibPNG.pch"
-				AssemblerListingLocation=".\Release/"
-				ObjectFile=".\Release/"
-				ProgramDataBaseFileName=".\Release/"
-				WarningLevel="3"
-				SuppressStartupBanner="TRUE"
-				CompileAs="0"/>
-			<Tool
-				Name="VCCustomBuildTool"/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile=".\Release\LibPNG.lib"
-				SuppressStartupBanner="TRUE"/>
-			<Tool
-				Name="VCMIDLTool"/>
-			<Tool
-				Name="VCPostBuildEventTool"/>
-			<Tool
-				Name="VCPreBuildEventTool"/>
-			<Tool
-				Name="VCPreLinkEventTool"/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="1033"/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"/>
-			<Tool
-				Name="VCManagedWrapperGeneratorTool"/>
-			<Tool
-				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
-		</Configuration>
-		<Configuration
-			Name="Debug|Win32"
-			OutputDirectory=".\Debug"
-			IntermediateDirectory=".\Debug"
-			ConfigurationType="4"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="FALSE"
-			CharacterSet="2">
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="0"
-				AdditionalIncludeDirectories="..\zlib"
-				PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
-				StringPooling="TRUE"
-				BasicRuntimeChecks="3"
-				RuntimeLibrary="1"
-				UsePrecompiledHeader="2"
-				PrecompiledHeaderFile=".\Debug/LibPNG.pch"
-				AssemblerListingLocation=".\Debug/"
-				ObjectFile=".\Debug/"
-				ProgramDataBaseFileName=".\Debug/"
-				WarningLevel="3"
-				SuppressStartupBanner="TRUE"
-				DebugInformationFormat="4"
-				CompileAs="0"/>
-			<Tool
-				Name="VCCustomBuildTool"/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile=".\Debug\LibPNG.lib"
-				SuppressStartupBanner="TRUE"/>
-			<Tool
-				Name="VCMIDLTool"/>
-			<Tool
-				Name="VCPostBuildEventTool"/>
-			<Tool
-				Name="VCPreBuildEventTool"/>
-			<Tool
-				Name="VCPreLinkEventTool"/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="_DEBUG"
-				Culture="1033"/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"/>
-			<Tool
-				Name="VCManagedWrapperGeneratorTool"/>
-			<Tool
-				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Source Files"
-			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
-			<File
-				RelativePath=".\png.c">
-			</File>
-			<File
-				RelativePath=".\pngerror.c">
-			</File>
-			<File
-				RelativePath=".\pngget.c">
-			</File>
-			<File
-				RelativePath=".\pngmem.c">
-			</File>
-			<File
-				RelativePath=".\pngpread.c">
-			</File>
-			<File
-				RelativePath=".\pngread.c">
-			</File>
-			<File
-				RelativePath=".\pngrio.c">
-			</File>
-			<File
-				RelativePath=".\pngrtran.c">
-			</File>
-			<File
-				RelativePath=".\pngrutil.c">
-			</File>
-			<File
-				RelativePath=".\pngset.c">
-			</File>
-			<File
-				RelativePath=".\pngtrans.c">
-			</File>
-			<File
-				RelativePath=".\pngwio.c">
-			</File>
-			<File
-				RelativePath=".\pngwrite.c">
-			</File>
-			<File
-				RelativePath=".\pngwtran.c">
-			</File>
-			<File
-				RelativePath=".\pngwutil.c">
-			</File>
-		</Filter>
-		<Filter
-			Name="Header Files"
-			Filter="h;hpp;hxx;hm;inl">
-			<File
-				RelativePath=".\png.h">
-			</File>
-			<File
-				RelativePath=".\pngconf.h">
-			</File>
-			<File
-				RelativePath=".\pngdebug.h">
-			</File>
-			<File
-				RelativePath=".\pnginfo.h">
-			</File>
-			<File
-				RelativePath=".\pnglibconf.h">
-			</File>
-			<File
-				RelativePath=".\pngpriv.h">
-			</File>
-			<File
-				RelativePath=".\pngstruct.h">
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
diff --git a/Source/LibPNG/LibPNG.2013.vcxproj b/Source/LibPNG/LibPNG.2013.vcxproj
new file mode 100644
index 0000000..c60ec24
--- /dev/null
+++ b/Source/LibPNG/LibPNG.2013.vcxproj
@@ -0,0 +1,233 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectName>LibPNG</ProjectName>
+    <ProjectGuid>{7DB10B50-CE00-4D7A-B322-6824F05D2FCB}</ProjectGuid>
+    <RootNamespace>LibPNG</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>12.0.21005.1</_ProjectFileVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <Optimization>Full</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>..\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <CompileAs>Default</CompileAs>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+      <DebugInformationFormat>None</DebugInformationFormat>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0409</Culture>
+    </ResourceCompile>
+    <Lib>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <LinkTimeCodeGeneration>true</LinkTimeCodeGeneration>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>Full</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>..\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <CompileAs>Default</CompileAs>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+      <DebugInformationFormat>None</DebugInformationFormat>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0409</Culture>
+    </ResourceCompile>
+    <Lib>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <LinkTimeCodeGeneration>true</LinkTimeCodeGeneration>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+      <CompileAs>Default</CompileAs>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0409</Culture>
+    </ResourceCompile>
+    <Lib>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <CompileAs>Default</CompileAs>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0409</Culture>
+    </ResourceCompile>
+    <Lib>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="png.c" />
+    <ClCompile Include="pngerror.c" />
+    <ClCompile Include="pngget.c" />
+    <ClCompile Include="pngmem.c" />
+    <ClCompile Include="pngpread.c" />
+    <ClCompile Include="pngread.c" />
+    <ClCompile Include="pngrio.c" />
+    <ClCompile Include="pngrtran.c" />
+    <ClCompile Include="pngrutil.c" />
+    <ClCompile Include="pngset.c" />
+    <ClCompile Include="pngtrans.c" />
+    <ClCompile Include="pngwio.c" />
+    <ClCompile Include="pngwrite.c" />
+    <ClCompile Include="pngwtran.c" />
+    <ClCompile Include="pngwutil.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="png.h" />
+    <ClInclude Include="pngconf.h" />
+    <ClInclude Include="pngdebug.h" />
+    <ClInclude Include="pnginfo.h" />
+    <ClInclude Include="pnglibconf.h" />
+    <ClInclude Include="pngpriv.h" />
+    <ClInclude Include="pngstruct.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\ZLib\ZLib.2013.vcxproj">
+      <Project>{33134f61-c1ad-4b6f-9cea-503a9f140c52}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/Source/LibPNG/LibPNG.2013.vcxproj.filters b/Source/LibPNG/LibPNG.2013.vcxproj.filters
new file mode 100644
index 0000000..4c5890e
--- /dev/null
+++ b/Source/LibPNG/LibPNG.2013.vcxproj.filters
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{926522ec-b3d4-40ac-b675-698e38162f26}</UniqueIdentifier>
+      <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{ce0089ae-5e1e-4a2c-b359-88ef4dec8309}</UniqueIdentifier>
+      <Extensions>h;hpp;hxx;hm;inl</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="png.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="pngerror.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="pngget.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="pngmem.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="pngpread.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="pngread.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="pngrio.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="pngrtran.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="pngrutil.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="pngset.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="pngtrans.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="pngwio.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="pngwrite.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="pngwtran.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="pngwutil.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="png.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="pngconf.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="pngdebug.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="pnginfo.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="pnglibconf.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="pngpriv.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="pngstruct.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/Source/LibPNG/README b/Source/LibPNG/README
index 5afeae8..d052755 100644
--- a/Source/LibPNG/README
+++ b/Source/LibPNG/README
@@ -1,11 +1,11 @@
-README for libpng version 1.5.13 - September 27, 2012 (shared library 15.0)
+README for libpng version 1.6.16 - December 22, 2014 (shared library 16.0)
 See the note about version numbers near the top of png.h
 
 See INSTALL for instructions on how to install libpng.
 
-Libpng comes in several distribution formats.  Get libpng-*.tar.gz,
-libpng-*.tar.xz or libpng-*.tar.bz2 if you want UNIX-style line endings
-in the text files, or lpng*.zip if you want DOS-style line endings.
+Libpng comes in several distribution formats.  Get libpng-*.tar.gz or
+libpng-*.tar.xz or if you want UNIX-style line endings in the text files,
+or lpng*.7z or lpng*.zip if you want DOS-style line endings.
 
 Version 0.89 was the first official release of libpng.  Don't let the
 fact that it's the first release fool you.  The libpng library has been in
@@ -23,18 +23,25 @@ earlier versions if you are using a shared library.  The type of the
 png_uint_32, which will affect shared-library applications that use
 this function.
 
-To avoid problems with changes to the internals of png_info_struct,
+To avoid problems with changes to the internals of png info_struct,
 new APIs have been made available in 0.95 to avoid direct application
 access to info_ptr.  These functions are the png_set_<chunk> and
 png_get_<chunk> functions.  These functions should be used when
 accessing/storing the info_struct data, rather than manipulating it
 directly, to avoid such problems in the future.
 
-It is important to note that the APIs do not make current programs
+It is important to note that the APIs did not make current programs
 that access the info struct directly incompatible with the new
-library.  However, it is strongly suggested that new programs use
-the new APIs (as shown in example.c and pngtest.c), and older programs
-be converted to the new format, to facilitate upgrades in the future.
+library, through libpng-1.2.x.  In libpng-1.4.x, which was meant to
+be a transitional release, members of the png_struct and the
+info_struct can still be accessed, but the compiler will issue a
+warning about deprecated usage.  Since libpng-1.5.0, direct access
+to these structs is not allowed, and the definitions of the structs
+reside in private pngstruct.h and pnginfo.h header files that are not
+accessible to applications.  It is strongly suggested that new
+programs use the new APIs (as shown in example.c and pngtest.c), and
+older programs be converted to the new format, to facilitate upgrades
+in the future.
 ****
 
 Additions since 0.90 include the ability to compile libpng as a
@@ -77,17 +84,21 @@ compression library that is useful for more things than just PNG files.
 You can use zlib as a drop-in replacement for fread() and fwrite() if
 you are so inclined.
 
-zlib should be available at the same place that libpng is, or at.
-ftp://ftp.info-zip.org/pub/infozip/zlib
+zlib should be available at the same place that libpng is, or at zlib.net.
 
 You may also want a copy of the PNG specification.  It is available
 as an RFC, a W3C Recommendation, and an ISO/IEC Standard.  You can find
 these at http://www.libpng.org/pub/png/documents/
 
 This code is currently being archived at libpng.sf.net in the
-[DOWNLOAD] area, and on CompuServe, Lib 20 (PNG SUPPORT)
-at GO GRAPHSUP.  If you can't find it in any of those places,
-e-mail me, and I'll help you find it.
+[DOWNLOAD] area, and at ftp://ftp.simplesystems.org.  If you can't find it
+in any of those places, e-mail me, and I'll help you find it.
+
+I am not a lawyer, but I believe that the Export Control Classification
+Number (ECCN) for libpng is EAR99, which means not subject to export
+controls or International Traffic in Arms Regulations (ITAR) because it
+is open source, publicly available software, that does not contain any
+encryption software.  See the EAR, paragraphs 734.3(b)(3) and 734.7(b).
 
 If you have any code changes, requests, problems, etc., please e-mail
 them to me.  Also, I'd appreciate any make files or project files,
@@ -105,7 +116,7 @@ based in a large way on Guy's and Andreas' earlier work), and the PNG
 development group.
 
 Send comments/corrections/commendations to png-mng-implement at
-lists.sourceforge.net (subscription required; visit 
+lists.sourceforge.net (subscription required; visit
 https://lists.sourceforge.net/lists/listinfo/png-mng-implement
 to subscribe) or to glennrp at users.sourceforge.net
 
@@ -123,7 +134,7 @@ and ...".  If in doubt, send questions to me.  I'll bounce them
 to others, if necessary.
 
 Please do not send suggestions on how to change PNG.  We have
-been discussing PNG for sixteen years now, and it is official and
+been discussing PNG for nineteen years now, and it is official and
 finished.  If you have suggestions for libpng, however, I'll
 gladly listen.  Even if your suggestion is not used immediately,
 it may be used later.
@@ -167,23 +178,25 @@ Files in this distribution:
       pngwrite.c    =>  High-level write functions
       pngwtran.c    =>  Write data transformations
       pngwutil.c    =>  Write utility functions
+      arm           =>  Contains optimized code for the ARM platform
       contrib       =>  Contributions
+       examples         =>  Example programs
        gregbook         =>  source code for PNG reading and writing, from
                             Greg Roelofs' "PNG: The Definitive Guide",
                             O'Reilly, 1999
-       msvctest     =>  Builds and runs pngtest using a MSVC workspace
-       pngminus     =>  Simple pnm2png and png2pnm programs
-       pngsuite     =>  Test images
-       visupng      =>  Contains a MSVC workspace for VisualPng
+       libtests         =>  Test programs
+       pngminim         =>  Minimal decoder, encoder, and progressive decoder
+                            programs demonstrating use of pngusr.dfa
+       pngminus         =>  Simple pnm2png and png2pnm programs
+       pngsuite         =>  Test images
+       tools            =>  Various tools
+       visupng          =>  Contains a MSVC workspace for VisualPng
       projects      =>  Contains project files and workspaces for
                         building a DLL
-       cbuilder5        =>  Contains a Borland workspace for building
-                            libpng and zlib
-       visualc6         =>  Contains a Microsoft Visual C++ (MSVC)
-                            workspace for building libpng and zlib
+       owatcom          =>  Contains a WATCOM project for building libpng
        visualc71        =>  Contains a Microsoft Visual C++ (MSVC)
                             workspace for building libpng and zlib
-       xcode            =>  Contains an Apple xcode
+       vstudio          =>  Contains a Microsoft Visual C++ (MSVC)
                             workspace for building libpng and zlib
       scripts       =>  Directory containing scripts for building libpng:
                             (see scripts/README.txt for the list of scripts)
diff --git a/Source/LibPNG/TODO b/Source/LibPNG/TODO
index b1660a4..fc18bba 100644
--- a/Source/LibPNG/TODO
+++ b/Source/LibPNG/TODO
@@ -6,10 +6,12 @@ Better C++ wrapper/full C++ implementation?
 Fix problem with C++ and EXTERN "C".
 cHRM transformation.
 Remove setjmp/longjmp usage in favor of returning error codes.
+Palette creation.
 Add "grayscale->palette" transformation and "palette->grayscale" detection.
 Improved dithering.
 Multi-lingual error and warning message support.
 Complete sRGB transformation (presently it simply uses gamma=0.45455).
+Make profile checking optional via a png_set_something() call.
 Man pages for function calls.
 Better documentation.
 Better filter selection
diff --git a/Source/LibPNG/configure b/Source/LibPNG/configure
index 218dddd..c33452b 100644
--- a/Source/LibPNG/configure
+++ b/Source/LibPNG/configure
@@ -1,14 +1,14 @@
 
 echo "
   There is no \"configure\" script in this distribution (*.zip or *.7z) of
-  libpng-1.5.13.
+  libpng-1.6.16.
 
   Instead, please copy the appropriate makefile for your system from the
   \"scripts\" directory.  Read the INSTALL file for more details.
 
   Update, July 2004: you can get a \"configure\" based distribution
   from the libpng distribution sites.  Download the file
-  libpng-1.5.13.tar.gz, libpng-1.5.13.tar.xz, or libpng-1.5.13.tar.bz2
+  libpng-1.6.16.tar.gz, libpng-1.6.16.tar.xz, or libpng-1.6.16.tar.bz2
 
   If the line endings in the files look funny, which is likely to be the
   case if you were trying to run \"configure\" on a Linux machine, you may
diff --git a/Source/LibPNG/example.c b/Source/LibPNG/example.c
index 04241ef..0337cdb 100644
--- a/Source/LibPNG/example.c
+++ b/Source/LibPNG/example.c
@@ -2,10 +2,13 @@
 #if 0 /* in case someone actually tries to compile this */
 
 /* example.c - an example of using libpng
- * Last changed in libpng 1.5.10 [March 8, 2012]
- * Maintained 1998-2012 Glenn Randers-Pehrson
- * Maintained 1996, 1997 Andreas Dilger
- * Written 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+ * Last changed in libpng 1.6.15 [November 20, 2014]
+ * Maintained 1998-2014 Glenn Randers-Pehrson
+ * Maintained 1996, 1997 Andreas Dilger)
+ * Written 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ * To the extent possible under law, the authors have waived
+ * all copyright and related or neighboring rights to this file.
+ * This work is published from: United States.
  */
 
 /* This is an example of how to use libpng to read and write PNG files.
@@ -13,8 +16,6 @@
  * read it, do so first.  This was designed to be a starting point of an
  * implementation.  This is not officially part of libpng, is hereby placed
  * in the public domain, and therefore does not require a copyright notice.
- * To the extent possible under law, the authors have waived all copyright and
- * related or neighboring rights to this file.
  *
  * This file does not currently compile, because it is missing certain
  * parts, like allocating memory to hold an image.  You will have to
@@ -23,11 +24,192 @@
  * see also the programs in the contrib directory.
  */
 
-#define _POSIX_SOURCE 1  /* libpng and zlib are POSIX-compliant.  You may
-                          * change this if your application uses non-POSIX
-                          * extensions. */
+/* The simple, but restricted, approach to reading a PNG file or data stream
+ * just requires two function calls, as in the following complete program.
+ * Writing a file just needs one function call, so long as the data has an
+ * appropriate layout.
+ *
+ * The following code reads PNG image data from a file and writes it, in a
+ * potentially new format, to a new file.  While this code will compile there is
+ * minimal (insufficient) error checking; for a more realistic version look at
+ * contrib/examples/pngtopng.c
+ */
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <png.h>
+#include <zlib.h>
+
+int main(int argc, const char **argv)
+{
+   if (argc == 3)
+   {
+      png_image image; /* The control structure used by libpng */
+
+      /* Initialize the 'png_image' structure. */
+      memset(&image, 0, (sizeof image));
+      image.version = PNG_IMAGE_VERSION;
+
+      /* The first argument is the file to read: */
+      if (png_image_begin_read_from_file(&image, argv[1]) != 0)
+      {
+         png_bytep buffer;
+
+         /* Set the format in which to read the PNG file; this code chooses a
+          * simple sRGB format with a non-associated alpha channel, adequate to
+          * store most images.
+          */
+         image.format = PNG_FORMAT_RGBA;
+
+         /* Now allocate enough memory to hold the image in this format; the
+          * PNG_IMAGE_SIZE macro uses the information about the image (width,
+          * height and format) stored in 'image'.
+          */
+         buffer = malloc(PNG_IMAGE_SIZE(image));
+
+         /* If enough memory was available read the image in the desired format
+          * then write the result out to the new file.  'background' is not
+          * necessary when reading the image because the alpha channel is
+          * preserved; if it were to be removed, for example if we requested
+          * PNG_FORMAT_RGB, then either a solid background color would have to
+          * be supplied or the output buffer would have to be initialized to the
+          * actual background of the image.
+          *
+          * The fourth argument to png_image_finish_read is the 'row_stride' -
+          * this is the number of components allocated for the image in each
+          * row.  It has to be at least as big as the value returned by
+          * PNG_IMAGE_ROW_STRIDE, but if you just allocate space for the
+          * default, minimum, size using PNG_IMAGE_SIZE as above you can pass
+          * zero.
+          *
+          * The final argument is a pointer to a buffer for the colormap;
+          * colormaps have exactly the same format as a row of image pixels (so
+          * you choose what format to make the colormap by setting
+          * image.format).  A colormap is only returned if
+          * PNG_FORMAT_FLAG_COLORMAP is also set in image.format, so in this
+          * case NULL is passed as the final argument.  If you do want to force
+          * all images into an index/color-mapped format then you can use:
+          *
+          *    PNG_IMAGE_COLORMAP_SIZE(image)
+          *
+          * to find the maximum size of the colormap in bytes.
+          */
+         if (buffer != NULL &&
+            png_image_finish_read(&image, NULL/*background*/, buffer,
+               0/*row_stride*/, NULL/*colormap*/) != 0)
+         {
+            /* Now write the image out to the second argument.  In the write
+             * call 'convert_to_8bit' allows 16-bit data to be squashed down to
+             * 8 bits; this isn't necessary here because the original read was
+             * to the 8-bit format.
+             */
+            if (png_image_write_to_file(&image, argv[2], 0/*convert_to_8bit*/,
+               buffer, 0/*row_stride*/, NULL/*colormap*/) != 0)
+            {
+               /* The image has been written successfully. */
+               exit(0);
+            }
+         }
+
+         else
+         {
+            /* Calling png_free_image is optional unless the simplified API was
+             * not run to completion.  In this case if there wasn't enough
+             * memory for 'buffer' we didn't complete the read, so we must free
+             * the image:
+             */
+            if (buffer == NULL)
+               png_free_image(&image);
+
+            else
+               free(buffer);
+      }
+
+      /* Something went wrong reading or writing the image.  libpng stores a
+       * textual message in the 'png_image' structure:
+       */
+      fprintf(stderr, "pngtopng: error: %s\n", image.message);
+      exit (1);
+   }
+
+   fprintf(stderr, "pngtopng: usage: pngtopng input-file output-file\n");
+   exit(1);
+}
+
+/* That's it ;-)  Of course you probably want to do more with PNG files than
+ * just converting them all to 32-bit RGBA PNG files; you can do that between
+ * the call to png_image_finish_read and png_image_write_to_file.  You can also
+ * ask for the image data to be presented in a number of different formats.  You
+ * do this by simply changing the 'format' parameter set before allocating the
+ * buffer.
+ *
+ * The format parameter consists of five flags that define various aspects of
+ * the image, you can simply add these together to get the format or you can use
+ * one of the predefined macros from png.h (as above):
+ *
+ * PNG_FORMAT_FLAG_COLOR: if set the image will have three color components per
+ *    pixel (red, green and blue), if not set the image will just have one
+ *    luminance (grayscale) component.
+ *
+ * PNG_FORMAT_FLAG_ALPHA: if set each pixel in the image will have an additional
+ *    alpha value; a linear value that describes the degree the image pixel
+ *    covers (overwrites) the contents of the existing pixel on the display.
+ *
+ * PNG_FORMAT_FLAG_LINEAR: if set the components of each pixel will be returned
+ *    as a series of 16-bit linear values, if not set the components will be
+ *    returned as a series of 8-bit values encoded according to the 'sRGB'
+ *    standard.  The 8-bit format is the normal format for images intended for
+ *    direct display, because almost all display devices do the inverse of the
+ *    sRGB transformation to the data they receive.  The 16-bit format is more
+ *    common for scientific data and image data that must be further processed;
+ *    because it is linear simple math can be done on the component values.
+ *    Regardless of the setting of this flag the alpha channel is always linear,
+ *    although it will be 8 bits or 16 bits wide as specified by the flag.
+ *
+ * PNG_FORMAT_FLAG_BGR: if set the components of a color pixel will be returned
+ *    in the order blue, then green, then red.  If not set the pixel components
+ *    are in the order red, then green, then blue.
+ *
+ * PNG_FORMAT_FLAG_AFIRST: if set the alpha channel (if present) precedes the
+ *    color or grayscale components.  If not set the alpha channel follows the
+ *    components.
+ *
+ * You do not have to read directly from a file.  You can read from memory or,
+ * on systems that support it, from a <stdio.h> FILE*.  This is controlled by
+ * the particular png_image_read_from_ function you call at the start.  Likewise
+ * on write you can write to a FILE* if your system supports it.  Check the
+ * macro PNG_STDIO_SUPPORTED to see if stdio support has been included in your
+ * libpng build.
+ *
+ * If you read 16-bit (PNG_FORMAT_FLAG_LINEAR) data you may need to write it in
+ * the 8-bit format for display.  You do this by setting the convert_to_8bit
+ * flag to 'true'.
+ *
+ * Don't repeatedly convert between the 8-bit and 16-bit forms.  There is
+ * significant data loss when 16-bit data is converted to the 8-bit encoding and
+ * the current libpng implementation of conversion to 16-bit is also
+ * significantly lossy.  The latter will be fixed in the future, but the former
+ * is unavoidable - the 8-bit format just doesn't have enough resolution.
+ */
 
-#include "png.h"
+/* If your program needs more information from the PNG data it reads, or if you
+ * need to do more complex transformations, or minimize transformations, on the
+ * data you read, then you must use one of the several lower level libpng
+ * interfaces.
+ *
+ * All these interfaces require that you do your own error handling - your
+ * program must be able to arrange for control to return to your own code any
+ * time libpng encounters a problem.  There are several ways to do this, but the
+ * standard way is to use the ANSI-C (C90) <setjmp.h> interface to establish a
+ * return point within your own code.  You must do this if you do not use the
+ * simplified interface (above).
+ *
+ * The first step is to include the header files you need, including the libpng
+ * header file.  Include any standard headers and feature test macros your
+ * program requires before including png.h:
+ */
+#include <png.h>
 
  /* The png_jmpbuf() macro, used in error handling, became available in
   * libpng version 1.0.6.  If you want to be able to run your code with older
@@ -223,7 +405,7 @@ void read_png(FILE *fp, unsigned int sig_read)  /* File is already open */
    /* Expand paletted or RGB images with transparency to full alpha channels
     * so the data will be available as RGBA quartets.
     */
-   if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
+   if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) != 0)
       png_set_tRNS_to_alpha(png_ptr);
 
    /* Set the background color to draw transparent and alpha images over.
@@ -235,7 +417,7 @@ void read_png(FILE *fp, unsigned int sig_read)  /* File is already open */
 
    png_color_16 my_background, *image_background;
 
-   if (png_get_bKGD(png_ptr, info_ptr, &image_background))
+   if (png_get_bKGD(png_ptr, info_ptr, &image_background) != 0)
       png_set_background(png_ptr, image_background,
                          PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
    else
@@ -259,9 +441,9 @@ void read_png(FILE *fp, unsigned int sig_read)  /* File is already open */
    /* If we don't have another value */
    else
    {
-      screen_gamma = 2.2;  /* A good guess for a PC monitor in a dimly
-                              lit room */
-      screen_gamma = 1.7 or 1.0;  /* A good guess for Mac systems */
+      screen_gamma = PNG_DEFAULT_sRGB;  /* A good guess for a PC monitor
+                                           in a dimly lit room */
+      screen_gamma = PNG_GAMMA_MAC_18 or 1.0; /* Good guesses for Mac systems */
    }
 
    /* Tell libpng to handle the gamma conversion for you.  The final call
@@ -272,12 +454,12 @@ void read_png(FILE *fp, unsigned int sig_read)  /* File is already open */
 
    int intent;
 
-   if (png_get_sRGB(png_ptr, info_ptr, &intent))
-      png_set_gamma(png_ptr, screen_gamma, 0.45455);
+   if (png_get_sRGB(png_ptr, info_ptr, &intent) != 0)
+      png_set_gamma(png_ptr, screen_gamma, PNG_DEFAULT_sRGB);
    else
    {
       double image_gamma;
-      if (png_get_gAMA(png_ptr, info_ptr, &image_gamma))
+      if (png_get_gAMA(png_ptr, info_ptr, &image_gamma) != 0)
          png_set_gamma(png_ptr, screen_gamma, image_gamma);
       else
          png_set_gamma(png_ptr, screen_gamma, 0.45455);
@@ -287,7 +469,7 @@ void read_png(FILE *fp, unsigned int sig_read)  /* File is already open */
    /* Quantize RGB files down to 8 bit palette or reduce palettes
     * to the number of colors available on your screen.
     */
-   if (color_type & PNG_COLOR_MASK_COLOR)
+   if ((color_type & PNG_COLOR_MASK_COLOR) != 0)
    {
       int num_palette;
       png_colorp palette;
@@ -302,7 +484,7 @@ void read_png(FILE *fp, unsigned int sig_read)  /* File is already open */
             MAX_SCREEN_COLORS, NULL, 0);
       }
       /* This reduces the image to the palette supplied in the file */
-      else if (png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette))
+      else if (png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette) != 0)
       {
          png_uint_16p histogram = NULL;
 
@@ -312,7 +494,7 @@ void read_png(FILE *fp, unsigned int sig_read)  /* File is already open */
                         max_screen_colors, histogram, 0);
       }
    }
-#endif /* PNG_READ_QUANTIZE_SUPPORTED */
+#endif /* READ_QUANTIZE */
 
    /* Invert monochrome files to have 0 as white and 1 as black */
    png_set_invert_mono(png_ptr);
@@ -321,7 +503,7 @@ void read_png(FILE *fp, unsigned int sig_read)  /* File is already open */
     * [0,65535] to the original [0,7] or [0,31], or whatever range the
     * colors were originally in:
     */
-   if (png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT))
+   if (png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT) != 0)
    {
       png_color_8p sig_bit_p;
 
@@ -330,7 +512,7 @@ void read_png(FILE *fp, unsigned int sig_read)  /* File is already open */
    }
 
    /* Flip the RGB pixels to BGR (or RGBA to BGRA) */
-   if (color_type & PNG_COLOR_MASK_COLOR)
+   if ((color_type & PNG_COLOR_MASK_COLOR) != 0)
       png_set_bgr(png_ptr);
 
    /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */
@@ -350,7 +532,7 @@ void read_png(FILE *fp, unsigned int sig_read)  /* File is already open */
    number_passes = png_set_interlace_handling(png_ptr);
 #else
    number_passes = 1;
-#endif /* PNG_READ_INTERLACING_SUPPORTED */
+#endif /* READ_INTERLACING */
 
 
    /* Optional call to gamma correct and add the background to the palette
@@ -549,7 +731,7 @@ row_callback(png_structp png_ptr, png_bytep new_row,
     * png_progressive_combine_row() passing in the new row and the
     * old row, as demonstrated above.  You can call this function for
     * NULL rows (it will just return) and for non-interlaced images
-    * (it just does the png_memcpy for you) if it will make the code
+    * (it just does the memcpy for you) if it will make the code
     * easier.  Thus, you can just do this for all cases:
     */
 
@@ -562,7 +744,7 @@ row_callback(png_structp png_ptr, png_bytep new_row,
     * to pass the current row as new_row, and the function will combine
     * the old row and the new row.
     */
-#endif /* PNG_READ_INTERLACING_SUPPORTED */
+#endif /* READ_INTERLACING */
 }
 
 end_callback(png_structp png_ptr, png_infop info)
@@ -664,7 +846,7 @@ void write_png(char *file_name /* , ... other image information ... */)
 
    /* Set the palette if there is one.  REQUIRED for indexed-color images */
    palette = (png_colorp)png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH
-             * png_sizeof(png_color));
+             * (sizeof (png_color)));
    /* ... Set palette colors ... */
    png_set_PLTE(png_ptr, info_ptr, palette, PNG_MAX_PALETTE_LENGTH);
    /* You must not free palette here, because png_set_PLTE only makes a link to
@@ -750,7 +932,7 @@ void write_png(char *file_name /* , ... other image information ... */)
     */
 
    /* Once we write out the header, the compression type on the text
-    * chunks gets changed to PNG_TEXT_COMPRESSION_NONE_WR or
+    * chunk gets changed to PNG_TEXT_COMPRESSION_NONE_WR or
     * PNG_TEXT_COMPRESSION_zTXt_WR, so it doesn't get written out again
     * at the end.
     */
@@ -788,7 +970,7 @@ void write_png(char *file_name /* , ... other image information ... */)
    png_set_packswap(png_ptr);
 
    /* Turn on interlace handling if you are not using png_write_image() */
-   if (interlacing)
+   if (interlacing != 0)
       number_passes = png_set_interlace_handling(png_ptr);
 
    else
@@ -805,7 +987,7 @@ void write_png(char *file_name /* , ... other image information ... */)
 
    png_bytep row_pointers[height];
 
-   if (height > PNG_UINT_32_MAX/png_sizeof(png_bytep))
+   if (height > PNG_UINT_32_MAX/(sizeof (png_bytep)))
      png_error (png_ptr, "Image is too tall to process in memory");
 
    /* Set up pointers into your "image" byte array */
diff --git a/Source/LibPNG/libpng-manual.txt b/Source/LibPNG/libpng-manual.txt
index 82afe70..06f7774 100644
--- a/Source/LibPNG/libpng-manual.txt
+++ b/Source/LibPNG/libpng-manual.txt
@@ -1,9 +1,9 @@
-Libpng-manual.txt - A description on how to use and modify libpng
+libpng-manual.txt - A description on how to use and modify libpng
 
- libpng version 1.5.13 - September 27, 2012
+ libpng version 1.6.16 - December 22, 2014
  Updated and distributed by Glenn Randers-Pehrson
  <glennrp at users.sourceforge.net>
- Copyright (c) 1998-2012 Glenn Randers-Pehrson
+ Copyright (c) 1998-2014 Glenn Randers-Pehrson
 
  This document is released under the libpng license.
  For conditions of distribution and use, see the disclaimer
@@ -11,15 +11,15 @@ Libpng-manual.txt - A description on how to use and modify libpng
 
  Based on:
 
- libpng versions 0.97, January 1998, through 1.5.13 - September 27, 2012
+ libpng versions 0.97, January 1998, through 1.6.16 - December 22, 2014
  Updated and distributed by Glenn Randers-Pehrson
- Copyright (c) 1998-2012 Glenn Randers-Pehrson
+ Copyright (c) 1998-2014 Glenn Randers-Pehrson
 
- libpng 1.0 beta 6  version 0.96 May 28, 1997
+ libpng 1.0 beta 6 - version 0.96 - May 28, 1997
  Updated and distributed by Andreas Dilger
  Copyright (c) 1996, 1997 Andreas Dilger
 
- libpng 1.0 beta 2 - version 0.88  January 26, 1996
+ libpng 1.0 beta 2 - version 0.88 - January 26, 1996
  For conditions of distribution and use, see copyright
  notice in png.h. Copyright (c) 1995, 1996 Guy Eric
  Schalnat, Group 42, Inc.
@@ -28,16 +28,33 @@ Libpng-manual.txt - A description on how to use and modify libpng
  Copyright (c) 1995, 1996 Frank J. T. Wojcik
  December 18, 1995 & January 20, 1996
 
+ TABLE OF CONTENTS
+
+    I. Introduction
+   II. Structures
+  III. Reading
+   IV. Writing
+    V. Simplified API
+   VI. Modifying/Customizing libpng
+  VII. MNG support
+ VIII. Changes to Libpng from version 0.88
+   IX. Changes to Libpng from version 1.0.x to 1.2.x
+    X. Changes to Libpng from version 1.0.x/1.2.x to 1.4.x
+   XI. Changes to Libpng from version 1.4.x to 1.5.x
+  XII. Changes to Libpng from version 1.5.x to 1.6.x
+ XIII. Detecting libpng
+  XIV. Source code repository
+   XV. Coding style
+  XVI. Y2K Compliance in libpng
+
 I. Introduction
 
 This file describes how to use and modify the PNG reference library
-(known as libpng) for your own use.  There are five sections to this
-file: introduction, structures, reading, writing, and modification and
-configuration notes for various special platforms.  In addition to this
+(known as libpng) for your own use.  In addition to this
 file, example.c is a good starting point for using the library, as
 it is heavily commented and should include everything most people
 will need.  We assume that libpng is already installed; see the
-INSTALL file for instructions on how to install libpng.
+INSTALL file for instructions on how to configure and install libpng.
 
 For examples of libpng usage, see the files "example.c", "pngtest.c",
 and the files in the "contrib" directory, all of which are included in
@@ -48,7 +65,7 @@ of reducing the amount of time and effort it takes to support the PNG
 file format in application programs.
 
 The PNG specification (second edition), November 2003, is available as
-a W3C Recommendation and as an ISO Standard (ISO/IEC 15948:2003 (E)) at
+a W3C Recommendation and as an ISO Standard (ISO/IEC 15948:2004 (E)) at
 <http://www.w3.org/TR/2003/REC-PNG-20031110/
 The W3C and ISO documents have identical technical content.
 
@@ -257,10 +274,10 @@ This method of building a customized pnglibconf.h is illustrated in
 contrib/pngminim/*.  See the "$(PNGCONF):" target in the makefile and
 pngusr.dfa in these directories.
 
-C. Configuration using PNG_USR_CONFIG
+C. Configuration using PNG_USER_CONFIG
 
-If -DPNG_USR_CONFIG is added to the CFLAGS when pnglibconf.h is built the file
-pngusr.h will automatically be included before the options in
+If -DPNG_USER_CONFIG is added to the CPPFLAGS when pnglibconf.h is built,
+the file pngusr.h will automatically be included before the options in
 scripts/pnglibconf.dfa are processed.  Your pngusr.h file should contain only
 macro definitions turning features on or off or setting settings.
 
@@ -508,9 +525,14 @@ you can retrieve with
     png_get_user_chunk_ptr(png_ptr);
 
 If you call the png_set_read_user_chunk_fn() function, then all unknown
-chunks will be saved when read, in case your callback function will need
-one or more of them.  This behavior can be changed with the
-png_set_keep_unknown_chunks() function, described below.
+chunks which the callback does not handle will be saved when read.  You can
+cause them to be discarded by returning '1' ("handled") instead of '0'.  This
+behavior will change in libpng 1.7 and the default handling set by the
+png_set_keep_unknown_chunks() function, described below, will be used when the
+callback returns 0.  If you want the existing behavior you should set the global
+default to PNG_HANDLE_CHUNK_IF_SAFE now; this is compatible with all current
+versions of libpng and with 1.7.  Libpng 1.6 issues a warning if you keep the
+default, or PNG_HANDLE_CHUNK_NEVER, and the callback returns 0.
 
 At this point, you can set up a callback function that will be
 called after each row has been read, which you can use to control
@@ -553,6 +575,7 @@ chunk types. To change this, you can call:
 
     png_set_keep_unknown_chunks(png_ptr, keep,
         chunk_list, num_chunks);
+
     keep       - 0: default unknown chunk handling
                  1: ignore; do not keep
                  2: keep only if safe-to-copy
@@ -566,11 +589,16 @@ chunk types. To change this, you can call:
 
     chunk_list - list of chunks affected (a byte string,
                  five bytes per chunk, NULL or '\0' if
-                 num_chunks is 0)
+                 num_chunks is positive; ignored if
+                 numchunks <= 0).
 
     num_chunks - number of chunks affected; if 0, all
-                 unknown chunks are affected.  If nonzero,
-                 only the chunks in the list are affected
+                 unknown chunks are affected.  If positive,
+                 only the chunks in the list are affected,
+                 and if negative all unknown chunks and
+                 all known chunks except for the IHDR,
+                 PLTE, tRNS, IDAT, and IEND chunks are
+                 affected.
 
 Unknown chunks declared in this way will be saved as raw data onto a
 list of png_unknown_chunk structures.  If a chunk that is normally
@@ -603,30 +631,29 @@ callback function:
     ...
 
     #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
-      /* ignore all unknown chunks: */
-      png_set_keep_unknown_chunks(read_ptr, 1, NULL, 0);
+      /* ignore all unknown chunks
+       * (use global setting "2" for libpng16 and earlier):
+       */
+      png_set_keep_unknown_chunks(read_ptr, 2, NULL, 0);
 
       /* except for vpAg: */
       png_set_keep_unknown_chunks(read_ptr, 2, vpAg, 1);
 
       /* also ignore unused known chunks: */
       png_set_keep_unknown_chunks(read_ptr, 1, unused_chunks,
-         (int)sizeof(unused_chunks)/5);
+         (int)(sizeof unused_chunks)/5);
     #endif
 
 User limits
 
 The PNG specification allows the width and height of an image to be as
 large as 2^31-1 (0x7fffffff), or about 2.147 billion rows and columns.
-Since very few applications really need to process such large images,
-we have imposed an arbitrary 1-million limit on rows and columns.
 Larger images will be rejected immediately with a png_error() call. If
-you wish to change this limit, you can use
+you wish to reduce these limits, you can use
 
    png_set_user_limits(png_ptr, width_max, height_max);
 
-to set your own limits, or use width_max = height_max = 0x7fffffffL
-to allow all valid dimensions (libpng may reject some very large images
+to set your own limits (libpng may reject some very wide images
 anyway because of potential buffer overflow conditions).
 
 You should put this statement after you create the PNG structure and
@@ -650,9 +677,6 @@ where 0x7fffffffL means unlimited.  You can retrieve this limit with
 
    chunk_cache_max = png_get_chunk_cache_max(png_ptr);
 
-This limit also applies to the number of buffers that can be allocated
-by png_decompress_chunk() while decompressing iTXt, zTXt, and iCCP chunks.
-
 You can also set a limit on the amount of memory that a compressed chunk
 other than IDAT can occupy, with
 
@@ -685,11 +709,12 @@ value.  You can also specify a default encoding for the PNG file in
 case the required information is missing from the file.  By default libpng
 assumes that the PNG data matches your system, to keep this default call:
 
-   png_set_gamma(png_ptr, screen_gamma, 1/screen_gamma/*file gamma*/);
+   png_set_gamma(png_ptr, screen_gamma, output_gamma);
 
 or you can use the fixed point equivalent:
 
-   png_set_gamma_fixed(png_ptr, PNG_FP_1*screen_gamma, PNG_FP_1/screen_gamma);
+   png_set_gamma_fixed(png_ptr, PNG_FP_1*screen_gamma,
+      PNG_FP_1*output_gamma);
 
 If you don't know the gamma for your system it is probably 2.2 - a good
 approximation to the IEC standard for display systems (sRGB).  If images are
@@ -701,19 +726,86 @@ display driver, a few systems, including older Macs, change the response by
 default.  As of 1.5.4 three special values are available to handle common
 situations:
 
-   PNG_DEFAULT_sRGB: Indicates that the system conforms to the IEC 61966-2-1
-                     standard.  This matches almost all systems.
-   PNG_GAMMA_MAC_18: Indicates that the system is an older (pre Mac OS 10.6)
-                     Apple Macintosh system with the default settings.
-   PNG_GAMMA_LINEAR: Just the fixed point value for 1.0 - indicates that the
-                     system expects data with no gamma encoding.
+   PNG_DEFAULT_sRGB: Indicates that the system conforms to the
+                     IEC 61966-2-1 standard.  This matches almost
+                     all systems.
+   PNG_GAMMA_MAC_18: Indicates that the system is an older
+                     (pre Mac OS 10.6) Apple Macintosh system with
+                     the default settings.
+   PNG_GAMMA_LINEAR: Just the fixed point value for 1.0 - indicates
+                     that the system expects data with no gamma
+                     encoding.
 
 You would use the linear (unencoded) value if you need to process the pixel
-values further because this avoids the need to decode and reencode each
+values further because this avoids the need to decode and re-encode each
 component value whenever arithmetic is performed.  A lot of graphics software
 uses linear values for this reason, often with higher precision component values
 to preserve overall accuracy.
 
+
+The output_gamma value expresses how to decode the output values, not how
+they are encoded.  The values used correspond to the normal numbers used to
+describe the overall gamma of a computer display system; for example 2.2 for
+an sRGB conformant system.  The values are scaled by 100000 in the _fixed
+version of the API (so 220000 for sRGB.)
+
+The inverse of the value is always used to provide a default for the PNG file
+encoding if it has no gAMA chunk and if png_set_gamma() has not been called
+to override the PNG gamma information.
+
+When the ALPHA_OPTIMIZED mode is selected the output gamma is used to encode
+opaque pixels however pixels with lower alpha values are not encoded,
+regardless of the output gamma setting.
+
+When the standard Porter Duff handling is requested with mode 1 the output
+encoding is set to be linear and the output_gamma value is only relevant
+as a default for input data that has no gamma information.  The linear output
+encoding will be overridden if png_set_gamma() is called - the results may be
+highly unexpected!
+
+The following numbers are derived from the sRGB standard and the research
+behind it.  sRGB is defined to be approximated by a PNG gAMA chunk value of
+0.45455 (1/2.2) for PNG.  The value implicitly includes any viewing
+correction required to take account of any differences in the color
+environment of the original scene and the intended display environment; the
+value expresses how to *decode* the image for display, not how the original
+data was *encoded*.
+
+sRGB provides a peg for the PNG standard by defining a viewing environment.
+sRGB itself, and earlier TV standards, actually use a more complex transform
+(a linear portion then a gamma 2.4 power law) than PNG can express.  (PNG is
+limited to simple power laws.)  By saying that an image for direct display on
+an sRGB conformant system should be stored with a gAMA chunk value of 45455
+(11.3.3.2 and 11.3.3.5 of the ISO PNG specification) the PNG specification
+makes it possible to derive values for other display systems and
+environments.
+
+The Mac value is deduced from the sRGB based on an assumption that the actual
+extra viewing correction used in early Mac display systems was implemented as
+a power 1.45 lookup table.
+
+Any system where a programmable lookup table is used or where the behavior of
+the final display device characteristics can be changed requires system
+specific code to obtain the current characteristic.  However this can be
+difficult and most PNG gamma correction only requires an approximate value.
+
+By default, if png_set_alpha_mode() is not called, libpng assumes that all
+values are unencoded, linear, values and that the output device also has a
+linear characteristic.  This is only very rarely correct - it is invariably
+better to call png_set_alpha_mode() with PNG_DEFAULT_sRGB than rely on the
+default if you don't know what the right answer is!
+
+The special value PNG_GAMMA_MAC_18 indicates an older Mac system (pre Mac OS
+10.6) which used a correction table to implement a somewhat lower gamma on an
+otherwise sRGB system.
+
+Both these values are reserved (not simple gamma values) in order to allow
+more precise correction internally in the future.
+
+NOTE: the values can be passed to either the fixed or floating
+point APIs, but the floating point API will also accept floating point
+values.
+
 The second thing you may need to tell libpng about is how your system handles
 alpha channel information.  Some, but not all, PNG files contain an alpha
 channel.  To display these files correctly you need to compose the data onto a
@@ -723,11 +815,11 @@ Libpng only supports composing onto a single color (using png_set_background;
 see below).  Otherwise you must do the composition yourself and, in this case,
 you may need to call png_set_alpha_mode:
 
-    #if PNG_LIBPNG_VER >= 10504
-       png_set_alpha_mode(png_ptr, mode, screen_gamma);
-    #else
-       png_set_gamma(png_ptr, screen_gamma, 1.0/screen_gamma);
-    #endif
+   #if PNG_LIBPNG_VER >= 10504
+      png_set_alpha_mode(png_ptr, mode, screen_gamma);
+   #else
+      png_set_gamma(png_ptr, screen_gamma, 1.0/screen_gamma);
+   #endif
 
 The screen_gamma value is the same as the argument to png_set_gamma; however,
 how it affects the output depends on the mode.  png_set_alpha_mode() sets the
@@ -738,11 +830,11 @@ by png_set_alpha_mode().
 
 The mode is as follows:
 
-    PNG_ALPHA_PNG: The data is encoded according to the PNG specification.  Red,
-green and blue, or gray, components are gamma encoded color
-values and are not premultiplied by the alpha value.  The
-alpha value is a linear measure of the contribution of the
-pixel to the corresponding final output pixel.
+    PNG_ALPHA_PNG: The data is encoded according to the PNG
+specification.  Red, green and blue, or gray, components are
+gamma encoded color values and are not premultiplied by the
+alpha value.  The alpha value is a linear measure of the
+contribution of the pixel to the corresponding final output pixel.
 
 You should normally use this format if you intend to perform
 color correction on the color values; most, maybe all, color
@@ -759,11 +851,35 @@ be used!
 
 The remaining modes assume you don't need to do any further color correction or
 that if you do, your color correction software knows all about alpha (it
-probably doesn't!)
-
-    PNG_ALPHA_STANDARD:  The data libpng produces
-is encoded in the standard way
-assumed by most correctly written graphics software.
+probably doesn't!).  They 'associate' the alpha with the color information by
+storing color channel values that have been scaled by the alpha.  The
+advantage is that the color channels can be resampled (the image can be
+scaled) in this form.  The disadvantage is that normal practice is to store
+linear, not (gamma) encoded, values and this requires 16-bit channels for
+still images rather than the 8-bit channels that are just about sufficient if
+gamma encoding is used.  In addition all non-transparent pixel values,
+including completely opaque ones, must be gamma encoded to produce the final
+image.  These are the 'STANDARD', 'ASSOCIATED' or 'PREMULTIPLIED' modes
+described below (the latter being the two common names for associated alpha
+color channels). Note that PNG files always contain non-associated color
+channels; png_set_alpha_mode() with one of the modes causes the decoder to
+convert the pixels to an associated form before returning them to your
+application. 
+
+Since it is not necessary to perform arithmetic on opaque color values so
+long as they are not to be resampled and are in the final color space it is
+possible to optimize the handling of alpha by storing the opaque pixels in
+the PNG format (adjusted for the output color space) while storing partially
+opaque pixels in the standard, linear, format.  The accuracy required for
+standard alpha composition is relatively low, because the pixels are
+isolated, therefore typically the accuracy loss in storing 8-bit linear
+values is acceptable.  (This is not true if the alpha channel is used to
+simulate transparency over large areas - use 16 bits or the PNG mode in
+this case!)  This is the 'OPTIMIZED' mode.  For this mode a pixel is
+treated as opaque only if the alpha value is equal to the maximum value.
+
+    PNG_ALPHA_STANDARD:  The data libpng produces is encoded in the
+standard way assumed by most correctly written graphics software.
 The gamma encoding will be removed by libpng and the
 linear component values will be pre-multiplied by the
 alpha channel.
@@ -792,9 +908,8 @@ dynamic range.  To avoid problems, and if your software
 supports it, use png_set_expand_16() to force all
 components to 16 bits.
 
-    PNG_ALPHA_OPTIMIZED: This mode is the same
-as PNG_ALPHA_STANDARD except that
-completely opaque pixels are gamma encoded according to
+    PNG_ALPHA_OPTIMIZED: This mode is the same as PNG_ALPHA_STANDARD
+except that completely opaque pixels are gamma encoded according to
 the screen_gamma value.  Pixels with alpha less than 1.0
 will still have linear components.
 
@@ -813,18 +928,16 @@ representation of non-opaque pixels are irrelevant.
 You can also try this format if your software is broken;
 it might look better.
 
-    PNG_ALPHA_BROKEN: This is PNG_ALPHA_STANDARD;
-however, all component values,
-including the alpha channel are gamma encoded.  This is
-an appropriate format to try if your software, or more
-likely hardware, is totally broken, i.e., if it performs
-linear arithmetic directly on gamma encoded values.
-
-In most cases of broken software or hardware the bug in the final display
-manifests as a subtle halo around composited parts of the image.  You may not
-even perceive this as a halo; the composited part of the image may simply appear
-separate from the background, as though it had been cut out of paper and pasted
-on afterward.
+    PNG_ALPHA_BROKEN: This is PNG_ALPHA_STANDARD; however, all component
+values, including the alpha channel are gamma encoded.  This is
+broken because, in practice, no implementation that uses this choice
+correctly undoes the encoding before handling alpha composition.  Use this
+choice only if other serious errors in the software or hardware you use
+mandate it.  In most cases of broken software or hardware the bug in the
+final display manifests as a subtle halo around composited parts of the
+image.  You may not even perceive this as a halo; the composited part of
+the image may simply appear separate from the background, as though it had
+been cut out of paper and pasted on afterward.
 
 If you don't have to deal with bugs in software or hardware, or if you can fix
 them, there are three recommended ways of using png_set_alpha_mode():
@@ -855,6 +968,89 @@ All you can do is compose the result onto a matching output.  Since this
 mode is libpng-specific you also need to write your own composition
 software.
 
+The following are examples of calls to png_set_alpha_mode to achieve the
+required overall gamma correction and, where necessary, alpha
+premultiplication.
+
+    png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB);
+
+This is the default libpng handling of the alpha channel - it is not
+pre-multiplied into the color components.  In addition the call states
+that the output is for a sRGB system and causes all PNG files without gAMA
+chunks to be assumed to be encoded using sRGB.
+
+    png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC);
+
+In this case the output is assumed to be something like an sRGB conformant
+display preceeded by a power-law lookup table of power 1.45.  This is how
+early Mac systems behaved.
+
+    png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_GAMMA_LINEAR);
+
+This is the classic Jim Blinn approach and will work in academic
+environments where everything is done by the book.  It has the shortcoming
+of assuming that input PNG data with no gamma information is linear - this
+is unlikely to be correct unless the PNG files where generated locally.
+Most of the time the output precision will be so low as to show
+significant banding in dark areas of the image.
+
+    png_set_expand_16(pp);
+    png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_DEFAULT_sRGB);
+
+This is a somewhat more realistic Jim Blinn inspired approach.  PNG files
+are assumed to have the sRGB encoding if not marked with a gamma value and
+the output is always 16 bits per component.  This permits accurate scaling
+and processing of the data.  If you know that your input PNG files were
+generated locally you might need to replace PNG_DEFAULT_sRGB with the
+correct value for your system.
+
+    png_set_alpha_mode(pp, PNG_ALPHA_OPTIMIZED, PNG_DEFAULT_sRGB);
+
+If you just need to composite the PNG image onto an existing background
+and if you control the code that does this you can use the optimization
+setting.  In this case you just copy completely opaque pixels to the
+output.  For pixels that are not completely transparent (you just skip
+those) you do the composition math using png_composite or png_composite_16
+below then encode the resultant 8-bit or 16-bit values to match the output
+encoding.
+
+    Other cases
+
+If neither the PNG nor the standard linear encoding work for you because
+of the software or hardware you use then you have a big problem.  The PNG
+case will probably result in halos around the image.  The linear encoding
+will probably result in a washed out, too bright, image (it's actually too
+contrasty.)  Try the ALPHA_OPTIMIZED mode above - this will probably
+substantially reduce the halos.  Alternatively try:
+
+    png_set_alpha_mode(pp, PNG_ALPHA_BROKEN, PNG_DEFAULT_sRGB);
+
+This option will also reduce the halos, but there will be slight dark
+halos round the opaque parts of the image where the background is light.
+In the OPTIMIZED mode the halos will be light halos where the background
+is dark.  Take your pick - the halos are unavoidable unless you can get
+your hardware/software fixed!  (The OPTIMIZED approach is slightly
+faster.)
+
+When the default gamma of PNG files doesn't match the output gamma.
+If you have PNG files with no gamma information png_set_alpha_mode allows
+you to provide a default gamma, but it also sets the ouput gamma to the
+matching value.  If you know your PNG files have a gamma that doesn't
+match the output you can take advantage of the fact that
+png_set_alpha_mode always sets the output gamma but only sets the PNG
+default if it is not already set:
+
+    png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB);
+    png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC);
+
+The first call sets both the default and the output gamma values, the
+second call overrides the output gamma without changing the default.  This
+is easier than achieving the same effect with png_set_gamma.  You must use
+PNG_ALPHA_PNG for the first call - internal checking in png_set_alpha will
+fire if more than one call to png_set_alpha_mode and png_set_background is
+made in the same read operation, however multiple calls with PNG_ALPHA_PNG
+are ignored.
+
 If you don't need, or can't handle, the alpha channel you can call
 png_set_background() to remove it by compositing against a fixed color.  Don't
 call png_set_strip_alpha() to do this - it will leave spurious pixel values in
@@ -962,7 +1158,7 @@ where row_pointers is an array of pointers to the pixel data for each row:
 If you know your image size and pixel size ahead of time, you can allocate
 row_pointers prior to calling png_read_png() with
 
-   if (height > PNG_UINT_32_MAX/png_sizeof(png_byte))
+   if (height > PNG_UINT_32_MAX/(sizeof (png_byte)))
       png_error (png_ptr,
           "Image is too tall to process in memory");
 
@@ -971,7 +1167,7 @@ row_pointers prior to calling png_read_png() with
           "Image is too wide to process in memory");
 
    row_pointers = png_malloc(png_ptr,
-       height*png_sizeof(png_bytep));
+       height*(sizeof (png_bytep)));
 
    for (int i=0; i<height, i++)
       row_pointers[i]=NULL;  /* security precaution */
@@ -1133,7 +1329,11 @@ pointer into the info_ptr is returned for any complex types.
 The colorspace data from gAMA, cHRM, sRGB, iCCP, and sBIT chunks
 is simply returned to give the application information about how the
 image was encoded.  Libpng itself only does transformations using the file
-gamma when combining semitransparent pixels with the background color.
+gamma when combining semitransparent pixels with the background color, and,
+since libpng-1.6.0, when converting between 8-bit sRGB and 16-bit linear pixels
+within the simplified API.  Libpng also uses the file gamma when converting
+RGB to gray, beginning with libpng-1.0.5, if the application calls
+png_set_rgb_to_gray()).
 
     png_get_PLTE(png_ptr, info_ptr, &palette,
                      &num_palette);
@@ -1146,7 +1346,7 @@ gamma when combining semitransparent pixels with the background color.
     png_get_gAMA(png_ptr, info_ptr, &file_gamma);
     png_get_gAMA_fixed(png_ptr, info_ptr, &int_file_gamma);
 
-    file_gamma     - the gamma at which the file was
+    file_gamma     - the gamma at which the file is
                      written (PNG_INFO_gAMA)
 
     int_file_gamma - 100,000 times the gamma at which the
@@ -1154,14 +1354,17 @@ gamma when combining semitransparent pixels with the background color.
 
     png_get_cHRM(png_ptr, info_ptr,  &white_x, &white_y, &red_x,
                      &red_y, &green_x, &green_y, &blue_x, &blue_y)
-    png_get_cHRM_XYZ(png_ptr, info_ptr, &red_X, &red_Y, &red_Z, &green_X,
-                     &green_Y, &green_Z, &blue_X, &blue_Y, &blue_Z)
-    png_get_cHRM_fixed(png_ptr, info_ptr, &int_white_x, &int_white_y,
-                     &int_red_x, &int_red_y, &int_green_x, &int_green_y,
-                     &int_blue_x, &int_blue_y)
+    png_get_cHRM_XYZ(png_ptr, info_ptr, &red_X, &red_Y, &red_Z,
+                     &green_X, &green_Y, &green_Z, &blue_X, &blue_Y,
+                     &blue_Z)
+    png_get_cHRM_fixed(png_ptr, info_ptr, &int_white_x,
+                     &int_white_y, &int_red_x, &int_red_y,
+                     &int_green_x, &int_green_y, &int_blue_x,
+                     &int_blue_y)
     png_get_cHRM_XYZ_fixed(png_ptr, info_ptr, &int_red_X, &int_red_Y,
-                     &int_red_Z, &int_green_X, &int_green_Y, &int_green_Z,
-                     &int_blue_X, &int_blue_Y, &int_blue_Z)
+                     &int_red_Z, &int_green_X, &int_green_Y,
+                     &int_green_Z, &int_blue_X, &int_blue_Y,
+                     &int_blue_Z)
 
     {white,red,green,blue}_{x,y}
                      A color space encoding specified using the
@@ -1169,15 +1372,16 @@ gamma when combining semitransparent pixels with the background color.
                      white point. (PNG_INFO_cHRM)
 
     {red,green,blue}_{X,Y,Z}
-                     A color space encoding specified using the encoding end
-                     points - the CIE tristimulus specification of the intended
-                     color of the red, green and blue channels in the PNG RGB
-                     data.  The white point is simply the sum of the three end
-                     points. (PNG_INFO_cHRM)
+                     A color space encoding specified using the
+                     encoding end points - the CIE tristimulus
+                     specification of the intended color of the red,
+                     green and blue channels in the PNG RGB data.
+                     The white point is simply the sum of the three
+                     end points. (PNG_INFO_cHRM)
 
     png_get_sRGB(png_ptr, info_ptr, &srgb_intent);
 
-    file_srgb_intent - the rendering intent (PNG_INFO_sRGB)
+    srgb_intent -    the rendering intent (PNG_INFO_sRGB)
                      The presence of the sRGB chunk
                      means that the pixel data is in the
                      sRGB color space.  This chunk also
@@ -2127,10 +2331,15 @@ how pngvalid.c does it.
 Finishing a sequential read
 
 After you are finished reading the image through the
-low-level interface, you can finish reading the file.  If you are
-interested in comments or time, which may be stored either before or
-after the image data, you should pass the separate png_info struct if
-you want to keep the comments from before and after the image
+low-level interface, you can finish reading the file.
+
+If you want to use a different crc action for handling CRC errors in
+chunks after the image data, you can call png_set_crc_action()
+again at this point.
+
+If you are interested in comments or time, which may be stored either
+before or after the image data, you should pass the separate png_info
+struct if you want to keep the comments from before and after the image
 separate.
 
     png_infop end_info = png_create_info_struct(png_ptr);
@@ -2146,6 +2355,9 @@ separate.
 
 If you are not interested, you should still call png_read_end()
 but you can pass NULL, avoiding the need to create an end_info structure.
+If you do this, libpng will not process any chunks after IDAT other than
+skipping over them and perhaps (depending on whether you have called
+png_set_crc_action) checking their CRCs while looking for the IEND chunk.
 
    png_read_end(png_ptr, (png_infop)NULL);
 
@@ -2250,7 +2462,7 @@ For a more compact example of reading a PNG image, see the file example.c.
 
 Reading PNG files progressively
 
-The progressive reader is slightly different then the non-progressive
+The progressive reader is slightly different from the non-progressive
 reader.  Instead of calling png_read_info(), png_read_rows(), and
 png_read_end(), you make one call to png_process_data(), which calls
 callbacks when it has the info, a row, or the end of the image.  You
@@ -2421,7 +2633,7 @@ png_infop info_ptr;
         png_progressive_combine_row(png_ptr, old_row,
           new_row);
 
-    /* where old_row is what was displayed for
+    /* where old_row is what was displayed
        previously for the row.  Note that the first
        pass (pass == 0, really) will completely cover
        the old row, so the rows do not have to be
@@ -2530,6 +2742,20 @@ You can #define PNG_ABORT() to a function that does something
 more useful than abort(), as long as your function does not
 return.
 
+Checking for invalid palette index on write was added at libpng
+1.5.10.  If a pixel contains an invalid (out-of-range) index libpng issues
+a benign error.  This is enabled by default because this condition is an
+error according to the PNG specification, Clause 11.3.2, but the error can
+be ignored in each png_ptr with
+
+   png_set_check_for_invalid_index(png_ptr, 0);
+
+If the error is ignored, or if png_benign_error() treats it as a warning,
+any invalid pixels are written as-is by the encoder, resulting in an
+invalid PNG datastream as output.  In this case the application is
+responsible for ensuring that the pixel indexes are in range when it writes
+a PLTE chunk with fewer entries than the bit depth would allow.
+
 Now you need to set up the output code.  The default for libpng is to
 use the C function fwrite().  If you use this, you will need to pass a
 valid FILE * in the function png_init_io().  Be sure that the file is
@@ -3032,18 +3258,53 @@ tEXt chunk use RFC 1123 format dates (e.g. "22 May 1997 18:07:10 GMT"),
 although this isn't a requirement.  Unlike the tIME chunk, the
 "Creation Time" tEXt chunk is not expected to be automatically changed
 by the software.  To facilitate the use of RFC 1123 dates, a function
-png_convert_to_rfc1123(png_ptr, png_timep) is provided to convert
-from PNG time to an RFC 1123 format string.
+png_convert_to_rfc1123_buffer(buffer, png_timep) is provided to
+convert from PNG time to an RFC 1123 format string.  The caller must provide
+a writeable buffer of at least 29 bytes.
 
 Writing unknown chunks
 
-You can use the png_set_unknown_chunks function to queue up chunks
-for writing.  You give it a chunk name, raw data, and a size; that's
-all there is to it.  The chunks will be written by the next following
-png_write_info_before_PLTE, png_write_info, or png_write_end function.
-Any chunks previously read into the info structure's unknown-chunk
-list will also be written out in a sequence that satisfies the PNG
-specification's ordering rules.
+You can use the png_set_unknown_chunks function to queue up private chunks
+for writing.  You give it a chunk name, location, raw data, and a size.  You
+also must use png_set_keep_unknown_chunks() to ensure that libpng will
+handle them.  That's all there is to it.  The chunks will be written by the
+next following png_write_info_before_PLTE, png_write_info, or png_write_end
+function, depending upon the specified location.  Any chunks previously
+read into the info structure's unknown-chunk list will also be written out
+in a sequence that satisfies the PNG specification's ordering rules.
+
+Here is an example of writing two private chunks, prVt and miNE:
+
+    #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+    /* Set unknown chunk data */
+    png_unknown_chunk unk_chunk[2];
+    strcpy((char *) unk_chunk[0].name, "prVt";
+    unk_chunk[0].data = (unsigned char *) "PRIVATE DATA";
+    unk_chunk[0].size = strlen(unk_chunk[0].data)+1;
+    unk_chunk[0].location = PNG_HAVE_IHDR;
+    strcpy((char *) unk_chunk[1].name, "miNE";
+    unk_chunk[1].data = (unsigned char *) "MY CHUNK DATA";
+    unk_chunk[1].size = strlen(unk_chunk[0].data)+1;
+    unk_chunk[1].location = PNG_AFTER_IDAT;
+    png_set_unknown_chunks(write_ptr, write_info_ptr,
+        unk_chunk, 2);
+    /* Needed because miNE is not safe-to-copy */
+    png_set_keep_unknown_chunks(png, PNG_HANDLE_CHUNK_ALWAYS,
+       (png_bytep) "miNE", 1);
+    # if PNG_LIBPNG_VER < 10600
+      /* Deal with unknown chunk location bug in 1.5.x and earlier */
+      png_set_unknown_chunk_location(png, info, 0, PNG_HAVE_IHDR);
+      png_set_unknown_chunk_location(png, info, 1, PNG_AFTER_IDAT);
+    # endif
+    # if PNG_LIBPNG_VER < 10500
+      /* PNG_AFTER_IDAT writes two copies of the chunk prior to libpng-1.5.0,
+       * one before IDAT and another after IDAT, so don't use it; only use
+       * PNG_HAVE_IHDR location.  This call resets the location previously
+       * set by assignment and png_set_unknown_chunk_location() for chunk 1.
+       */
+      png_set_unknown_chunk_location(png, info, 1, PNG_HAVE_IHDR);
+    # endif
+    #endif
 
 The high-level write interface
 
@@ -3441,7 +3702,374 @@ if you transfer responsibility for free'ing text_ptr from libpng to your
 application, your application must not separately free those members.
 For a more compact example of writing a PNG image, see the file example.c.
 
-V. Modifying/Customizing libpng:
+V. Simplified API
+
+The simplified API, which became available in libpng-1.6.0, hides the details
+of both libpng and the PNG file format itself.
+It allows PNG files to be read into a very limited number of
+in-memory bitmap formats or to be written from the same formats.  If these
+formats do not accommodate your needs then you can, and should, use the more
+sophisticated APIs above - these support a wide variety of in-memory formats
+and a wide variety of sophisticated transformations to those formats as well
+as a wide variety of APIs to manipulate ancilliary information.
+
+To read a PNG file using the simplified API:
+
+  1) Declare a 'png_image' structure (see below) on the
+     stack and memset() it to all zero.
+
+  2) Call the appropriate png_image_begin_read... function.
+
+  3) Set the png_image 'format' member to the required
+     format and allocate a buffer for the image.
+
+  4) Call png_image_finish_read to read the image into
+     your buffer.
+
+There are no restrictions on the format of the PNG input itself; all valid
+color types, bit depths, and interlace methods are acceptable, and the
+input image is transformed as necessary to the requested in-memory format
+during the png_image_finish_read() step.
+
+To write a PNG file using the simplified API:
+
+  1) Declare a 'png_image' structure on the stack and memset()
+     it to all zero.
+
+  2) Initialize the members of the structure that describe the
+     image, setting the 'format' member to the format of the
+     image in memory.
+
+  3) Call the appropriate png_image_write... function with a
+     pointer to the image to write the PNG data.
+
+png_image is a structure that describes the in-memory format of an image
+when it is being read or define the in-memory format of an image that you
+need to write.  The "png_image" structure contains the following members:
+
+   png_uint_32  version Set to PNG_IMAGE_VERSION
+   png_uint_32  width   Image width in pixels (columns)
+   png_uint_32  height  Image height in pixels (rows)
+   png_uint_32  format  Image format as defined below
+   png_uint_32  flags   A bit mask containing informational flags
+   png_controlp opaque  Initialize to NULL, free with png_image_free
+   png_uint_32  colormap_entries; Number of entries in the color-map
+   png_uint_32  warning_or_error;
+   char         message[64];
+
+In the event of an error or warning the following field warning_or_error
+field will be set to a non-zero value and the 'message' field will contain
+a '\0' terminated string with the libpng error or warning message.  If both
+warnings and an error were encountered, only the error is recorded.  If there
+are multiple warnings, only the first one is recorded.
+
+The upper 30 bits of this value are reserved; the low two bits contain
+a two bit code such that a value more than 1 indicates a failure in the API
+just called:
+
+   0 - no warning or error
+   1 - warning
+   2 - error
+   3 - error preceded by warning
+
+The pixels (samples) of the image have one to four channels whose components
+have original values in the range 0 to 1.0:
+
+  1: A single gray or luminance channel (G).
+  2: A gray/luminance channel and an alpha channel (GA).
+  3: Three red, green, blue color channels (RGB).
+  4: Three color channels and an alpha channel (RGBA).
+
+The channels are encoded in one of two ways:
+
+  a) As a small integer, value 0..255, contained in a single byte.  For the
+alpha channel the original value is simply value/255.  For the color or
+luminance channels the value is encoded according to the sRGB specification
+and matches the 8-bit format expected by typical display devices.
+
+The color/gray channels are not scaled (pre-multiplied) by the alpha
+channel and are suitable for passing to color management software.
+
+  b) As a value in the range 0..65535, contained in a 2-byte integer, in
+the native byte order of the platform on which the application is running.
+All channels can be converted to the original value by dividing by 65535; all
+channels are linear.  Color channels use the RGB encoding (RGB end-points) of
+the sRGB specification.  This encoding is identified by the
+PNG_FORMAT_FLAG_LINEAR flag below.
+
+When an alpha channel is present it is expected to denote pixel coverage
+of the color or luminance channels and is returned as an associated alpha
+channel: the color/gray channels are scaled (pre-multiplied) by the alpha
+value.
+
+When a color-mapped image is used as a result of calling
+png_image_read_colormap or png_image_write_colormap the channels are encoded
+in the color-map and the descriptions above apply to the color-map entries.
+The image data is encoded as small integers, value 0..255, that index the
+entries in the color-map.  One integer (one byte) is stored for each pixel.
+
+PNG_FORMAT_*
+
+The #defines to be used in png_image::format.  Each #define identifies a
+particular layout of channel data and, if present, alpha values.  There are
+separate defines for each of the two channel encodings.
+
+A format is built up using single bit flag values.  Not all combinations are
+valid: use the bit flag values below for testing a format returned by the
+read APIs, but set formats from the derived values.
+
+When reading or writing color-mapped images the format should be set to the
+format of the entries in the color-map then png_image_{read,write}_colormap
+called to read or write the color-map and set the format correctly for the
+image data.  Do not set the PNG_FORMAT_FLAG_COLORMAP bit directly!
+
+NOTE: libpng can be built with particular features disabled, if you see
+compiler errors because the definition of one of the following flags has been
+compiled out it is because libpng does not have the required support.  It is
+possible, however, for the libpng configuration to enable the format on just
+read or just write; in that case you may see an error at run time.  You can
+guard against this by checking for the definition of:
+
+   PNG_SIMPLIFIED_{READ,WRITE}_{BGR,AFIRST}_SUPPORTED
+
+   PNG_FORMAT_FLAG_ALPHA    0x01 format with an alpha channel
+   PNG_FORMAT_FLAG_COLOR    0x02 color format: otherwise grayscale
+   PNG_FORMAT_FLAG_LINEAR   0x04 png_uint_16 channels else png_byte
+   PNG_FORMAT_FLAG_COLORMAP 0x08 libpng use only
+   PNG_FORMAT_FLAG_BGR      0x10 BGR colors, else order is RGB
+   PNG_FORMAT_FLAG_AFIRST   0x20 alpha channel comes first
+
+Supported formats are as follows.  Future versions of libpng may support more
+formats; for compatibility with older versions simply check if the format
+macro is defined using #ifdef.  These defines describe the in-memory layout
+of the components of the pixels of the image.
+
+First the single byte formats:
+
+   PNG_FORMAT_GRAY 0
+   PNG_FORMAT_GA   PNG_FORMAT_FLAG_ALPHA
+   PNG_FORMAT_AG   (PNG_FORMAT_GA|PNG_FORMAT_FLAG_AFIRST)
+   PNG_FORMAT_RGB  PNG_FORMAT_FLAG_COLOR
+   PNG_FORMAT_BGR  (PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_BGR)
+   PNG_FORMAT_RGBA (PNG_FORMAT_RGB|PNG_FORMAT_FLAG_ALPHA)
+   PNG_FORMAT_ARGB (PNG_FORMAT_RGBA|PNG_FORMAT_FLAG_AFIRST)
+   PNG_FORMAT_BGRA (PNG_FORMAT_BGR|PNG_FORMAT_FLAG_ALPHA)
+   PNG_FORMAT_ABGR (PNG_FORMAT_BGRA|PNG_FORMAT_FLAG_AFIRST)
+
+Then the linear 2-byte formats.  When naming these "Y" is used to
+indicate a luminance (gray) channel.  The component order within the pixel
+is always the same - there is no provision for swapping the order of the
+components in the linear format.  The components are 16-bit integers in
+the native byte order for your platform, and there is no provision for
+swapping the bytes to a different endian condition.
+
+   PNG_FORMAT_LINEAR_Y PNG_FORMAT_FLAG_LINEAR
+   PNG_FORMAT_LINEAR_Y_ALPHA
+      (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_ALPHA)
+   PNG_FORMAT_LINEAR_RGB
+      (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR)
+   PNG_FORMAT_LINEAR_RGB_ALPHA
+      (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR|
+      PNG_FORMAT_FLAG_ALPHA)
+
+Color-mapped formats are obtained by calling png_image_{read,write}_colormap,
+as appropriate after setting png_image::format to the format of the color-map
+to be read or written.  Applications may check the value of
+PNG_FORMAT_FLAG_COLORMAP to see if they have called the colormap API.  The
+format of the color-map may be extracted using the following macro.
+
+   PNG_FORMAT_OF_COLORMAP(fmt) ((fmt) & ~PNG_FORMAT_FLAG_COLORMAP)
+
+PNG_IMAGE macros
+
+These are convenience macros to derive information from a png_image
+structure.  The PNG_IMAGE_SAMPLE_ macros return values appropriate to the
+actual image sample values - either the entries in the color-map or the
+pixels in the image.  The PNG_IMAGE_PIXEL_ macros return corresponding values
+for the pixels and will always return 1 after a call to
+png_image_{read,write}_colormap.  The remaining macros return information
+about the rows in the image and the complete image.
+
+NOTE: All the macros that take a png_image::format parameter are compile time
+constants if the format parameter is, itself, a constant.  Therefore these
+macros can be used in array declarations and case labels where required.
+Similarly the macros are also pre-processor constants (sizeof is not used) so
+they can be used in #if tests.
+
+First the information about the samples.
+
+  PNG_IMAGE_SAMPLE_CHANNELS(fmt)
+    Returns the total number of channels in a given format: 1..4
+
+  PNG_IMAGE_SAMPLE_COMPONENT_SIZE(fmt)
+    Returns the size in bytes of a single component of a pixel or color-map
+    entry (as appropriate) in the image.
+
+  PNG_IMAGE_SAMPLE_SIZE(fmt)
+    This is the size of the sample data for one sample.  If the image is
+    color-mapped it is the size of one color-map entry (and image pixels are
+    one byte in size), otherwise it is the size of one image pixel.
+
+  PNG_IMAGE_COLORMAP_SIZE(fmt)
+   The size of the color-map required by the format; this is the size of the
+   color-map buffer passed to the png_image_{read,write}_colormap APIs, it is
+   a fixed number determined by the format so can easily be allocated on the
+   stack if necessary.
+
+#define PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(fmt)\
+   (PNG_IMAGE_SAMPLE_CHANNELS(fmt) * 256)
+   /* The maximum size of the color-map required by the format expressed in a
+    * count of components.  This can be used to compile-time allocate a
+    * color-map:
+    *
+    * png_uint_16 colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(linear_fmt)];
+    *
+    * png_byte colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(sRGB_fmt)];
+    *
+    * Alternatively, use the PNG_IMAGE_COLORMAP_SIZE macro below to use the
+    * information from one of the png_image_begin_read_ APIs and dynamically
+    * allocate the required memory.
+    */
+
+
+Corresponding information about the pixels
+
+  PNG_IMAGE_PIXEL_(test,fmt)
+
+  PNG_IMAGE_PIXEL_CHANNELS(fmt)
+   The number of separate channels (components) in a pixel; 1 for a
+   color-mapped image.
+
+  PNG_IMAGE_PIXEL_COMPONENT_SIZE(fmt)\
+   The size, in bytes, of each component in a pixel; 1 for a color-mapped
+   image.
+
+  PNG_IMAGE_PIXEL_SIZE(fmt)
+   The size, in bytes, of a complete pixel; 1 for a color-mapped image.
+
+Information about the whole row, or whole image
+
+  PNG_IMAGE_ROW_STRIDE(image)
+   Returns the total number of components in a single row of the image; this
+   is the minimum 'row stride', the minimum count of components between each
+   row.  For a color-mapped image this is the minimum number of bytes in a
+   row.
+
+   If you need the stride measured in bytes, row_stride_bytes is
+   PNG_IMAGE_ROW_STRIDE(image) * PNG_IMAGE_PIXEL_COMPONENT_SIZE(fmt)
+   plus any padding bytes that your application might need, for example
+   to start the next row on a 4-byte boundary.
+
+  PNG_IMAGE_BUFFER_SIZE(image, row_stride)
+    Returns the size, in bytes, of an image buffer given a png_image and a row
+    stride - the number of components to leave space for in each row.  This
+    macro takes care of multiplying row_stride by PNG_IMAGE_PIXEL_COMONENT_SIZE
+    when the image has 2-byte components.
+
+  PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB == 0x01
+    This indicates the the RGB values of the in-memory bitmap do not
+    correspond to the red, green and blue end-points defined by sRGB.
+
+  PNG_IMAGE_FLAG_COLORMAP == 0x02
+    The PNG is color-mapped.  If this flag is set png_image_read_colormap
+    can be used without further loss of image information.  If it is not set
+    png_image_read_colormap will cause significant loss if the image has any
+
+READ APIs
+
+   The png_image passed to the read APIs must have been initialized by setting
+   the png_controlp field 'opaque' to NULL (or, better, memset the whole thing.)
+
+   int png_image_begin_read_from_file( png_imagep image,
+     const char *file_name)
+
+     The named file is opened for read and the image header
+     is filled in from the PNG header in the file.
+
+   int png_image_begin_read_from_stdio (png_imagep image,
+     FILE* file)
+
+      The PNG header is read from the stdio FILE object.
+
+   int png_image_begin_read_from_memory(png_imagep image,
+      png_const_voidp memory, png_size_t size)
+
+      The PNG header is read from the given memory buffer.
+
+   int png_image_finish_read(png_imagep image,
+      png_colorp background, void *buffer,
+      png_int_32 row_stride, void *colormap));
+
+      Finish reading the image into the supplied buffer and
+      clean up the png_image structure.
+
+      row_stride is the step, in png_byte or png_uint_16 units
+      as appropriate, between adjacent rows.  A positive stride
+      indicates that the top-most row is first in the buffer -
+      the normal top-down arrangement.  A negative stride
+      indicates that the bottom-most row is first in the buffer.
+
+      background need only be supplied if an alpha channel must
+      be removed from a png_byte format and the removal is to be
+      done by compositing on a solid color; otherwise it may be
+      NULL and any composition will be done directly onto the
+      buffer.  The value is an sRGB color to use for the
+      background, for grayscale output the green channel is used.
+
+      For linear output removing the alpha channel is always done
+      by compositing on black.
+
+   void png_image_free(png_imagep image)
+
+      Free any data allocated by libpng in image->opaque,
+      setting the pointer to NULL.  May be called at any time
+      after the structure is initialized.
+
+When the simplified API needs to convert between sRGB and linear colorspaces,
+the actual sRGB transfer curve defined in the sRGB specification (see the
+article at http://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2
+approximation used elsewhere in libpng.
+
+WRITE APIS
+
+For write you must initialize a png_image structure to describe the image to
+be written:
+
+   version: must be set to PNG_IMAGE_VERSION
+   opaque: must be initialized to NULL
+   width: image width in pixels
+   height: image height in rows
+   format: the format of the data you wish to write
+   flags: set to 0 unless one of the defined flags applies; set
+      PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB for color format images
+      where the RGB values do not correspond to the colors in sRGB.
+   colormap_entries: set to the number of entries in the color-map (0 to 256)
+
+   int png_image_write_to_file, (png_imagep image,
+      const char *file, int convert_to_8bit, const void *buffer,
+      png_int_32 row_stride, const void *colormap));
+
+      Write the image to the named file.
+
+   int png_image_write_to_stdio(png_imagep image, FILE *file,
+      int convert_to_8_bit, const void *buffer,
+      png_int_32 row_stride, const void *colormap)
+
+      Write the image to the given (FILE*).
+
+With all write APIs if image is in one of the linear formats with
+(png_uint_16) data then setting convert_to_8_bit will cause the output to be
+a (png_byte) PNG gamma encoded according to the sRGB specification, otherwise
+a 16-bit linear encoded PNG file is written.
+
+With all APIs row_stride is handled as in the read APIs - it is the spacing
+from one row to the next in component sized units (float) and if negative
+indicates a bottom-up row layout in the buffer.
+
+Note that the write API does not support interlacing, sub-8-bit pixels,
+and indexed (paletted) images.
+
+VI. Modifying/Customizing libpng
 
 There are two issues here.  The first is changing how libpng does
 standard things like memory allocation, input/output, and error handling.
@@ -3465,14 +4093,11 @@ clears the newly allocated memory to zero; note that png_calloc(png_ptr, size)
 is not the same as the calloc(number, size) function provided by stdlib.h.
 There is limited support for certain systems with segmented memory
 architectures and the types of pointers declared by png.h match this; you
-will have to use appropriate pointers in your application.  Since it is
-unlikely that the method of handling memory allocation on a platform
-will change between applications, these functions must be modified in
-the library at compile time.  If you prefer to use a different method
-of allocating and freeing data, you can use png_create_read_struct_2() or
-png_create_write_struct_2() to register your own functions as described
-above.  These functions also provide a void pointer that can be retrieved
-via
+will have to use appropriate pointers in your application.  If you prefer
+to use a different method of allocating and freeing data, you can use
+png_create_read_struct_2() or png_create_write_struct_2() to register your
+own functions as described above.  These functions also provide a void
+pointer that can be retrieved via
 
     mem_ptr=png_get_mem_ptr(png_ptr);
 
@@ -3575,6 +4200,18 @@ compiler documentation for more details.  For an alternative approach, you
 may wish to use the "cexcept" facility (see http://cexcept.sourceforge.net),
 which is illustrated in pngvalid.c and in contrib/visupng.
 
+Beginning in libpng-1.4.0, the png_set_benign_errors() API became available.
+You can use this to handle certain errors (normally handled as errors)
+as warnings.
+
+    png_set_benign_errors (png_ptr, int allowed);
+
+    allowed: 0: treat png_benign_error() as an error.
+             1: treat png_benign_error() as a warning.
+
+As of libpng-1.6.0, the default condition is to treat benign errors as
+warnings while reading and as errors while writing.
+
 Custom chunks
 
 If you need to read or write custom chunks, you may need to get deeper
@@ -3603,29 +4240,6 @@ the simpler ones to get an idea of how they work.  Try to find a similar
 transformation to the one you want to add and copy off of it.  More details
 can be found in the comments inside the code itself.
 
-Configuring for 16-bit platforms
-
-You will want to look into zconf.h to tell zlib (and thus libpng) that
-it cannot allocate more then 64K at a time.  Even if you can, the memory
-won't be accessible.  So limit zlib and libpng to 64K by defining MAXSEG_64K.
-
-Configuring for DOS
-
-For DOS users who only have access to the lower 640K, you will
-have to limit zlib's memory usage via a png_set_compression_mem_level()
-call.  See zlib.h or zconf.h in the zlib library for more information.
-
-Configuring for Medium Model
-
-Libpng's support for medium model has been tested on most of the popular
-compilers.  Make sure MAXSEG_64K gets defined, USE_FAR_KEYWORD gets
-defined, and FAR gets defined to far in pngconf.h, and you should be
-all set.  Everything in the library (except for zlib's structure) is
-expecting far data.  You must use the typedefs with the p or pp on
-the end for pointers (or at least look at them and be careful).  Make
-note that the rows of data are defined as png_bytepp, which is
-an "unsigned char far * far *".
-
 Configuring for gui/windowing platforms:
 
 You will need to write new error and warning functions that use the GUI
@@ -3635,18 +4249,6 @@ in order to have them available during the structure initialization.
 They can be changed later via png_set_error_fn().  On some compilers,
 you may also have to change the memory allocators (png_malloc, etc.).
 
-Configuring for compiler xxx:
-
-All includes for libpng are in pngconf.h.  If you need to add, change
-or delete an include, this is the place to do it.
-The includes that are not needed outside libpng are placed in pngpriv.h,
-which is only used by the routines inside libpng itself.
-The files in libpng proper only include pngpriv.h and png.h, which
-in turn includes pngconf.h and, as of libpng-1.5.0, pnglibconf.h.
-As of libpng-1.5.0, pngpriv.h also includes three other private header
-files, pngstruct.h, pnginfo.h, and pngdebug.h, which contain material
-that previously appeared in the public headers.
-
 Configuring zlib:
 
 There are special functions to configure the compression.  Perhaps the
@@ -3688,6 +4290,8 @@ zlib.h for more information on what these mean.
 
     png_set_compression_method(png_ptr, method);
 
+This controls the size of the IDAT chunks (default 8192):
+
     png_set_compression_buffer_size(png_ptr, size);
 
 As of libpng version 1.5.4, additional APIs became
@@ -3786,46 +4390,6 @@ Note that the numbers above were invented purely for this example and
 are given only to help explain the function usage.  Little testing has
 been done to find optimum values for either the costs or the weights.
 
-Removing unwanted object code
-
-There are a bunch of #define's in pngconf.h that control what parts of
-libpng are compiled.  All the defines end in _SUPPORTED.  If you are
-never going to use a capability, you can change the #define to #undef
-before recompiling libpng and save yourself code and data space, or
-you can turn off individual capabilities with defines that begin with
-PNG_NO_.
-
-In libpng-1.5.0 and later, the #define's are in pnglibconf.h instead.
-
-You can also turn all of the transforms and ancillary chunk capabilities
-off en masse with compiler directives that define
-PNG_NO_READ[or WRITE]_TRANSFORMS, or PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS,
-or all four,
-along with directives to turn on any of the capabilities that you do
-want.  The PNG_NO_READ[or WRITE]_TRANSFORMS directives disable the extra
-transformations but still leave the library fully capable of reading
-and writing PNG files with all known public chunks. Use of the
-PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS directive produces a library
-that is incapable of reading or writing ancillary chunks.  If you are
-not using the progressive reading capability, you can turn that off
-with PNG_NO_PROGRESSIVE_READ (don't confuse this with the INTERLACING
-capability, which you'll still have).
-
-All the reading and writing specific code are in separate files, so the
-linker should only grab the files it needs.  However, if you want to
-make sure, or if you are building a stand alone library, all the
-reading files start with "pngr" and all the writing files start with "pngw".
-The files that don't match either (like png.c, pngtrans.c, etc.)
-are used for both reading and writing, and always need to be included.
-The progressive reader is in pngpread.c
-
-If you are creating or distributing a dynamically linked library (a .so
-or DLL file), you should not remove or disable any parts of the library,
-as this will cause applications linked with different versions of the
-library to fail if they call functions not available in your library.
-The size of the library itself should not be an issue, because only
-those sections that are actually used will be loaded into memory.
-
 Requesting debug printout
 
 The macro definition PNG_DEBUG can be used to request debugging
@@ -3845,7 +4409,7 @@ the message, "message" is the formatted string to be printed,
 and p1 and p2 are parameters that are to be embedded in the string
 according to printf-style formatting directives.  For example,
 
-   png_debug1(2, "foo=%d\n", foo);
+   png_debug1(2, "foo=%d", foo);
 
 is expanded to
 
@@ -3863,7 +4427,7 @@ When PNG_DEBUG = 1, the macros are defined, but only png_debug statements
 having level = 0 will be printed.  There aren't any such statements in
 this version of libpng, but if you insert some they will be printed.
 
-VI.  MNG support
+VII.  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.
@@ -3890,7 +4454,7 @@ 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
+VIII.  Changes to Libpng from version 0.88
 
 It should be noted that versions of libpng later than 0.96 are not
 distributed by the original libpng author, Guy Schalnat, nor by
@@ -3925,6 +4489,9 @@ png_set_error_fn(), which is essentially the same function, but with a new
 name to force compilation errors with applications that try to use the old
 method.
 
+Support for the sCAL, iCCP, iTXt, and sPLT chunks was added at libpng-1.0.6;
+however, iTXt support was not enabled by default.
+
 Starting with version 1.0.7, you can find out which version of the library
 you are using at run-time:
 
@@ -3942,7 +4509,7 @@ application:
 
    png_uint_32 application_vn = PNG_LIBPNG_VER;
 
-VIII.  Changes to Libpng from version 1.0.x to 1.2.x
+IX.  Changes to Libpng from version 1.0.x to 1.2.x
 
 Support for user memory management was enabled by default.  To
 accomplish this, the functions png_create_read_struct_2(),
@@ -4039,7 +4606,7 @@ which also expands tRNS to alpha was replaced with
     png_set_expand_gray_1_2_4_to_8()
 which does not. It has been deprecated since libpng-1.0.18 and 1.2.9.
 
-IX.  Changes to Libpng from version 1.0.x/1.2.x to 1.4.x
+X.  Changes to Libpng from version 1.0.x/1.2.x to 1.4.x
 
 Private libpng prototypes and macro definitions were moved from
 png.h and pngconf.h into a new pngpriv.h header file.
@@ -4094,8 +4661,8 @@ png_get_mmx_bitdepth_threshold(), png_get_mmx_rowbytes_threshold(),
 png_set_asm_flags(), and png_mmx_supported()
 
 We removed the obsolete png_check_sig(), png_memcpy_check(), and
-png_memset_check() functions.  Instead use !png_sig_cmp(), png_memcpy(),
-and png_memset(), respectively.
+png_memset_check() functions.  Instead use !png_sig_cmp(), memcpy(),
+and memset(), respectively.
 
 The function png_set_gray_1_2_4_to_8() was removed. It has been
 deprecated since libpng-1.0.18 and 1.2.9, when it was replaced with
@@ -4141,7 +4708,7 @@ it has not been well tested and doesn't actually "dither".
 The code was not
 removed, however, and could be enabled by building libpng with
 PNG_READ_DITHER_SUPPORTED defined.  In libpng-1.4.2, this support
-was reenabled, but the function was renamed png_set_quantize() to
+was re-enabled, but the function was renamed png_set_quantize() to
 reflect more accurately what it actually does.  At the same time,
 the PNG_DITHER_[RED,GREEN_BLUE]_BITS macros were also renamed to
 PNG_QUANTIZE_[RED,GREEN,BLUE]_BITS, and PNG_READ_DITHER_SUPPORTED
@@ -4149,22 +4716,42 @@ was renamed to PNG_READ_QUANTIZE_SUPPORTED.
 
 We removed the trailing '.' from the warning and error messages.
 
-X.  Changes to Libpng from version 1.4.x to 1.5.x
+XI.  Changes to Libpng from version 1.4.x to 1.5.x
 
 From libpng-1.4.0 until 1.4.4, the png_get_uint_16 macro (but not the
 function) incorrectly returned a value of type png_uint_32.
+The incorrect macro was removed from libpng-1.4.5.
 
-Checking for invalid palette index on read or write was added at libpng
-1.5.10.  When an invalid index is found, libpng issues a benign error.
-This is enabled by default but can be disabled in each png_ptr with
+Checking for invalid palette index on write was added at libpng
+1.5.10.  If a pixel contains an invalid (out-of-range) index libpng issues
+a benign error.  This is enabled by default because this condition is an
+error according to the PNG specification, Clause 11.3.2, but the error can
+be ignored in each png_ptr with
 
    png_set_check_for_invalid_index(png_ptr, allowed);
 
       allowed  - one of
-                 0: disable
-                 1: enable
+                 0: disable benign error (accept the
+                    invalid data without warning).
+                 1: enable benign error (treat the
+                    invalid data as an error or a
+                    warning).
+
+If the error is ignored, or if png_benign_error() treats it as a warning,
+any invalid pixels are decoded as opaque black by the decoder and written
+as-is by the encoder.
+
+Retrieving the maximum palette index found was added at libpng-1.5.15.
+This statement must appear after png_read_png() or png_read_image() while
+reading, and after png_write_png() or png_write_image() while writing.
 
-A. Changes that affect users of libpng
+   int max_palette = png_get_palette_max(png_ptr, info_ptr);
+
+This will return the maximum palette index found in the image, or "-1" if
+the palette was not checked, or "0" if no palette was found.  Note that this
+does not account for any palette index used by ancillary chunks such as the
+bKGD chunk; you must check those separately to determine the maximum
+palette index actually used.
 
 There are no substantial API changes between the non-deprecated parts of
 the 1.4.5 API and the 1.5.0 API; however, the ability to directly access
@@ -4172,9 +4759,10 @@ members of the main libpng control structures, png_struct and png_info,
 deprecated in earlier versions of libpng, has been completely removed from
 libpng 1.5.
 
-We no longer include zlib.h in png.h.  Applications that need access
-to information in zlib.h will need to add the '#include "zlib.h"'
-directive.  It does not matter whether it is placed prior to or after
+We no longer include zlib.h in png.h.  The include statement has been moved
+to pngstruct.h, where it is not accessible by applications. Applications that
+need access to information in zlib.h will need to add the '#include "zlib.h"'
+directive.  It does not matter whether this is placed prior to or after
 the '"#include png.h"' directive.
 
 The png_sprintf(), png_strcpy(), and png_strncpy() macros are no longer used
@@ -4235,7 +4823,10 @@ and the accuracy of PNG fixed point values is insufficient for
 representation of these values. Consequently a "string" API
 (png_get_sCAL_s and png_set_sCAL_s) is the only reliable way of reading
 arbitrary sCAL chunks in the absence of either the floating point API or
-internal floating point calculations.
+internal floating point calculations.  Starting with libpng-1.5.0, both
+of these functions are present when PNG_sCAL_SUPPORTED is defined.  Prior
+to libpng-1.5.0, their presence also depended upon PNG_FIXED_POINT_SUPPORTED
+being defined and PNG_FLOATING_POINT_SUPPORTED not being defined.
 
 Applications no longer need to include the optional distribution header
 file pngusr.h or define the corresponding macros during application
@@ -4255,15 +4846,10 @@ reset by pngusr.h or by explicit settings on the compiler command line.
 These settings may produce compiler warnings or errors in 1.5.0 because
 of macro redefinition.
 
-From libpng-1.4.0 until 1.4.4, the png_get_uint_16 macro (but not the
-function) incorrectly returned a value of type png_uint_32.  libpng 1.5.0
-is consistent with the implementation in 1.4.5 and 1.2.x (where the macro
-did not exist.)
-
 Applications can now choose whether to use these macros or to call the
 corresponding function by defining PNG_USE_READ_MACROS or
 PNG_NO_USE_READ_MACROS before including png.h.  Notice that this is
-only supported from 1.5.0 -defining PNG_NO_USE_READ_MACROS prior to 1.5.0
+only supported from 1.5.0; defining PNG_NO_USE_READ_MACROS prior to 1.5.0
 will lead to a link failure.
 
 Prior to libpng-1.5.4, the zlib compressor used the same set of parameters
@@ -4277,7 +4863,10 @@ option was off by default, and slightly inaccurate scaling occurred.
 This option can no longer be turned off, and the choice of accurate
 or inaccurate 16-to-8 scaling is by using the new png_set_scale_16_to_8()
 API for accurate scaling or the old png_set_strip_16_to_8() API for simple
-chopping.
+chopping.  In libpng-1.5.4, the PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED
+macro became PNG_READ_SCALE_16_TO_8_SUPPORTED, and the PNG_READ_16_TO_8
+macro became PNG_READ_STRIP_16_TO_8_SUPPORTED, to enable the two
+png_set_*_16_to_8() functions separately.
 
 Prior to libpng-1.5.4, the png_set_user_limits() function could only be
 used to reduce the width and height limits from the value of
@@ -4299,25 +4888,8 @@ limits are now
    png_user_chunk_cache_max  0 (unlimited)   128
    png_user_chunk_malloc_max 0 (unlimited) 8,000,000
 
-B. Changes to the build and configuration of libpng
-
-Details of internal changes to the library code can be found in the CHANGES
-file and in the GIT repository logs.  These will be of no concern to the vast
-majority of library users or builders; however, the few who configure libpng
-to a non-default feature set may need to change how this is done.
-
-There should be no need for library builders to alter build scripts if
-these use the distributed build support - configure or the makefiles -
-however, users of the makefiles may care to update their build scripts
-to build pnglibconf.h where the corresponding makefile does not do so.
-
-Building libpng with a non-default configuration has changed completely.
-The old method using pngusr.h should still work correctly even though the
-way pngusr.h is used in the build has been changed; however, library
-builders will probably want to examine the changes to take advantage of
-new capabilities and to simplify their build system.
-
-B.1 Specific changes to library configuration capabilities
+The png_set_option() function (and the "options" member of the png struct) was
+added to libpng-1.5.15.
 
 The library now supports a complete fixed point implementation and can
 thus be used on systems that have no floating point support or very
@@ -4329,27 +4901,7 @@ independent of the choice of fixed versus floating point APIs and all the
 missing fixed point APIs have been implemented.
 
 The exact mechanism used to control attributes of API functions has
-changed.  A single set of operating system independent macro definitions
-is used and operating system specific directives are defined in
-pnglibconf.h
-
-As part of this the mechanism used to choose procedure call standards on
-those systems that allow a choice has been changed.  At present this only
-affects certain Microsoft (DOS, Windows) and IBM (OS/2) operating systems
-running on Intel processors.  As before, PNGAPI is defined where required
-to control the exported API functions; however, two new macros, PNGCBAPI
-and PNGCAPI, are used instead for callback functions (PNGCBAPI) and
-(PNGCAPI) for functions that must match a C library prototype (currently
-only png_longjmp_ptr, which must match the C longjmp function.)  The new
-approach is documented in pngconf.h
-
-Despite these changes, libpng 1.5.0 only supports the native C function
-calling standard on those platforms tested so far (__cdecl on Microsoft
-Windows).  This is because the support requirements for alternative
-calling conventions seem to no longer exist.  Developers who find it
-necessary to set PNG_API_RULE to 1 should advise the mailing list
-(png-mng-implement) of this and library builders who use Openwatcom and
-therefore set PNG_API_RULE to 2 should also contact the mailing list.
+changed, as described in the INSTALL file.
 
 A new test program, pngvalid, is provided in addition to pngtest.
 pngvalid validates the arithmetic accuracy of the gamma correction
@@ -4425,47 +4977,134 @@ even though the default is to use the macros - this allows applications
 to choose at app buildtime whether or not to use macros (previously
 impossible because the functions weren't in the default build.)
 
-B.2 Changes to the configuration mechanism
-
-Prior to libpng-1.5.0 library builders who needed to configure libpng
-had either to modify the exported pngconf.h header file to add system
-specific configuration or had to write feature selection macros into
-pngusr.h and cause this to be included into pngconf.h by defining
-PNG_USER_CONFIG. The latter mechanism had the disadvantage that an
-application built without PNG_USER_CONFIG defined would see the
-unmodified, default, libpng API and thus would probably fail to link.
-
-These mechanisms still work in the configure build and in any makefile
-build that builds pnglibconf.h, although the feature selection macros
-have changed somewhat as described above.  In 1.5.0, however, pngusr.h is
-processed only once, when the exported header file pnglibconf.h is built.
-pngconf.h no longer includes pngusr.h, therefore pngusr.h is ignored after the
-build of pnglibconf.h and it is never included in an application build.
-
-The rarely used alternative of adding a list of feature macros to the
-CFLAGS setting in the build also still works; however, the macros will be
-copied to pnglibconf.h and this may produce macro redefinition warnings
-when the individual C files are compiled.
-
-All configuration now only works if pnglibconf.h is built from
-scripts/pnglibconf.dfa.  This requires the program awk.  Brian Kernighan
-(the original author of awk) maintains C source code of that awk and this
-and all known later implementations (often called by subtly different
-names - nawk and gawk for example) are adequate to build pnglibconf.h.
-The Sun Microsystems (now Oracle) program 'awk' is an earlier version
-and does not work; this may also apply to other systems that have a
-functioning awk called 'nawk'.
-
-Configuration options are now documented in scripts/pnglibconf.dfa.  This
-file also includes dependency information that ensures a configuration is
-consistent; that is, if a feature is switched off dependent features are
-also removed.  As a recommended alternative to using feature macros in
-pngusr.h a system builder may also define equivalent options in pngusr.dfa
-(or, indeed, any file) and add that to the configuration by setting
-DFA_XTRA to the file name.  The makefiles in contrib/pngminim illustrate
-how to do this, and a case where pngusr.h is still required.
-
-XI. Detecting libpng
+XII.  Changes to Libpng from version 1.5.x to 1.6.x
+
+A "simplified API" has been added (see documentation in png.h and a simple
+example in contrib/examples/pngtopng.c).  The new publicly visible API
+includes the following:
+
+   macros:
+     PNG_FORMAT_*
+     PNG_IMAGE_*
+   structures:
+     png_control
+     png_image
+   read functions
+     png_image_begin_read_from_file()
+     png_image_begin_read_from_stdio()
+     png_image_begin_read_from_memory()
+     png_image_finish_read()
+     png_image_free()
+   write functions
+     png_image_write_to_file()
+     png_image_write_to_stdio()
+
+Starting with libpng-1.6.0, you can configure libpng to prefix all exported
+symbols, using the PNG_PREFIX macro.
+
+We no longer include string.h in png.h.  The include statement has been moved
+to pngpriv.h, where it is not accessible by applications.  Applications that
+need access to information in string.h must add an '#include <string.h>'
+directive.  It does not matter whether this is placed prior to or after
+the '#include "png.h"' directive.
+
+The following API are now DEPRECATED:
+   png_info_init_3()
+   png_convert_to_rfc1123() which has been replaced
+     with png_convert_to_rfc1123_buffer()
+   png_malloc_default()
+   png_free_default()
+   png_reset_zstream()
+
+The following have been removed:
+   png_get_io_chunk_name(), which has been replaced
+     with png_get_io_chunk_type().  The new
+     function returns a 32-bit integer instead of
+     a string.
+   The png_sizeof(), png_strlen(), png_memcpy(), png_memcmp(), and
+     png_memset() macros are no longer used in the libpng sources and
+     have been removed.  These had already been made invisible to applications
+     (i.e., defined in the private pngpriv.h header file) since libpng-1.5.0.
+
+The signatures of many exported functions were changed, such that
+   png_structp became png_structrp or png_const_structrp
+   png_infop became png_inforp or png_const_inforp
+where "rp" indicates a "restricted pointer".
+
+Error detection in some chunks has improved; in particular the iCCP chunk
+reader now does pretty complete validation of the basic format.  Some bad
+profiles that were previously accepted are now accepted with a warning or
+rejected, depending upon the png_set_benign_errors() setting, in particular
+the very old broken Microsoft/HP 3144-byte sRGB profile.  Starting with
+libpng-1.6.11, recognizing and checking sRGB profiles can be avoided by
+means of
+
+    #if defined(PNG_SKIP_sRGB_CHECK_PROFILE) && \
+        defined(PNG_SET_OPTION_SUPPORTED)
+       png_set_option(png_ptr, PNG_SKIP_sRGB_CHECK_PROFILE,
+           PNG_OPTION_ON);
+    #endif
+
+It's not a good idea to do this if you are using the new "simplified API",
+which needs to be able to recognize sRGB profiles conveyed via the iCCP
+chunk.
+
+The PNG spec requirement that only grayscale profiles may appear in images
+with color type 0 or 4 and that even if the image only contains gray pixels,
+only RGB profiles may appear in images with color type 2, 3, or 6, is now
+enforced.  The sRGB chunk is allowed to appear in images with any color type
+and is interpreted by libpng to convey a one-tracer-curve gray profile or a
+three-tracer-curve RGB profile as appropriate.
+
+Prior to libpng-1.6.0 a warning would be issued if the iTXt chunk contained
+an empty language field or an empty translated keyword.  Both of these
+are allowed by the PNG specification, so these warnings are no longer issued.
+
+The library now issues an error if the application attempts to set a
+transform after it calls png_read_update_info() or if it attempts to call
+both png_read_update_info() and png_start_read_image() or to call either
+of them more than once.
+
+The default condition for benign_errors is now to treat benign errors as
+warnings while reading and as errors while writing.
+
+The library now issues a warning if both background processing and RGB to
+gray are used when gamma correction happens. As with previous versions of
+the library the results are numerically very incorrect in this case.
+
+There are some minor arithmetic changes in some transforms such as
+png_set_background(), that might be detected by certain regression tests.
+
+Unknown chunk handling has been improved internally, without any API change.
+This adds more correct option control of the unknown handling, corrects
+a pre-existing bug where the per-chunk 'keep' setting is ignored, and makes
+it possible to skip IDAT chunks in the sequential reader.
+
+The machine-generated configure files are no longer included in branches
+libpng16 and later of the GIT repository.  They continue to be included
+in the tarball releases, however.
+
+Libpng-1.6.0 through 1.6.2 used the CMF bytes at the beginning of the IDAT
+stream to set the size of the sliding window for reading instead of using the
+default 32-kbyte sliding window size.  It was discovered that there are
+hundreds of PNG files in the wild that have incorrect CMF bytes that caused
+zlib to issue the "invalid distance too far back" error and reject the file.
+Libpng-1.6.3 and later calculate their own safe CMF from the image dimensions,
+provide a way to revert to the libpng-1.5.x behavior (ignoring the CMF bytes
+and using a 32-kbyte sliding window), by using
+
+    png_set_option(png_ptr, PNG_MAXIMUM_INFLATE_WINDOW,
+        PNG_OPTION_ON);
+
+and provide a tool (contrib/tools/pngfix) for rewriting a PNG file while
+optimizing the CMF bytes in its IDAT chunk correctly.
+
+Libpng-1.6.0 and libpng-1.6.1 wrote uncompressed iTXt chunks with the wrong
+length, which resulted in PNG files that cannot be read beyond the bad iTXt
+chunk.  This error was fixed in libpng-1.6.3, and a tool (called
+contrib/tools/png-fix-itxt) has been added to the libpng distribution.
+
+XIII.  Detecting libpng
 
 The png_get_io_ptr() function has been present since libpng-0.88, has never
 changed, and is unaffected by conditional compilation macros.  It is the
@@ -4474,18 +5113,18 @@ libpng version since 0.88.  In an autoconf "configure.in" you could use
 
     AC_CHECK_LIB(png, png_get_io_ptr, ...
 
-XII. Source code repository
+XV. Source code repository
 
 Since about February 2009, version 1.2.34, libpng has been under "git" source
 control.  The git repository was built from old libpng-x.y.z.tar.gz files
 going back to version 0.70.  You can access the git repository (read only)
 at
 
-    git://libpng.git.sourceforge.net/gitroot/libpng
+    git://git.code.sf.net/p/libpng/code
 
-or you can browse it via "gitweb" at
+or you can browse it with a web browser by selecting the "code" button at
 
-    http://libpng.git.sourceforge.net/git/gitweb.cgi?p=libpng
+    https://sourceforge.net/projects/libpng
 
 Patches can be sent to glennrp at users.sourceforge.net or to
 png-mng-implement at lists.sourceforge.net or you can upload them to
@@ -4498,9 +5137,10 @@ simple verbal discriptions of bug fixes, reported either to the
 SourceForge bug tracker, to the png-mng-implement at lists.sf.net
 mailing list, or directly to glennrp.
 
-XIII. Coding style
+XV. Coding style
 
-Our coding style is similar to the "Allman" style, with curly
+Our coding style is similar to the "Allman" style
+(See http://en.wikipedia.org/wiki/Indent_style#Allman_style), with curly
 braces on separate lines:
 
     if (condition)
@@ -4563,6 +5203,9 @@ exported functions are marked with PNGAPI:
     body;
  }
 
+The return type and decorations are placed on a separate line
+ahead of the function name, as illustrated above.
+
 The prototypes for all exported functions appear in png.h,
 above the comment that says
 
@@ -4577,17 +5220,29 @@ We mark all non-exported functions with "/* PRIVATE */"":
  }
 
 The prototypes for non-exported functions (except for those in
-pngtest) appear in
-pngpriv.h
-above the comment that says
+pngtest) appear in pngpriv.h above the comment that says
 
-  /* Maintainer: Put new private prototypes here ^ and in libpngpf.3 */
+  /* Maintainer: Put new private prototypes here ^ */
 
 To avoid polluting the global namespace, the names of all exported
 functions and variables begin with "png_", and all publicly visible C
 preprocessor macros begin with "PNG".  We request that applications that
 use libpng *not* begin any of their own symbols with either of these strings.
 
+We put a space after the "sizeof" operator and we omit the
+optional parentheses around its argument when the argument
+is an expression, not a type name, and we always enclose the
+sizeof operator, with its argument, in parentheses:
+
+  (sizeof (png_uint_32))
+  (sizeof array)
+
+Prior to libpng-1.6.0 we used a "png_sizeof()" macro, formatted as
+though it were a function.
+
+Control keywords if, for, while, and switch are always followed by a space
+to distinguish them from function calls, which have no trailing space. 
+
 We put a space after each comma and after each semicolon
 in "for" statements, and we put spaces before and after each
 C binary operator and after "for" or "while", and before
@@ -4598,44 +5253,52 @@ left parenthesis that follows it:
     for (i = 2; i > 0; --i)
        y[i] = a(x) + (int)b;
 
-We prefer #ifdef and #ifndef to #if defined() and if !defined()
-when there is only one macro being tested.
+We prefer #ifdef and #ifndef to #if defined() and #if !defined()
+when there is only one macro being tested.  We always use parentheses
+with "defined".
 
 We prefer to express integers that are used as bit masks in hex format,
 with an even number of lower-case hex digits (e.g., 0x00, 0xff, 0x0100).
 
+We prefer to use underscores in variable names rather than camelCase, except
+for a few type names that we inherit from zlib.h.
+
+We prefer "if (something != 0)" and "if (something == 0)"
+over "if (something)" and if "(!something)", respectively.
+
 We do not use the TAB character for indentation in the C sources.
 
 Lines do not exceed 80 characters.
 
 Other rules can be inferred by inspecting the libpng source.
 
-XIV. Y2K Compliance in libpng
+XVI. Y2K Compliance in libpng
 
-September 27, 2012
+December 22, 2014
 
 Since the PNG Development group is an ad-hoc body, we can't make
 an official declaration.
 
 This is your unofficial assurance that libpng from version 0.71 and
-upward through 1.5.13 are Y2K compliant.  It is my belief that earlier
+upward through 1.6.16 are Y2K compliant.  It is my belief that earlier
 versions were also Y2K compliant.
 
-Libpng only has two year fields.  One is a 2-byte unsigned integer that
-will hold years up to 65535.  The other holds the date in text
-format, and will hold years up to 9999.
+Libpng only has two year fields.  One is a 2-byte unsigned integer
+that will hold years up to 65535.  The other, which is deprecated,
+holds the date in text format, and will hold years up to 9999.
 
 The integer is
     "png_uint_16 year" in png_time_struct.
 
 The string is
-    "char time_buffer[29]" in png_struct.  This will no
-longer be used in libpng-1.6.x and will be removed from libpng-1.7.0.
+    "char time_buffer[29]" in png_struct.  This is no longer used
+in libpng-1.6.x and will be removed from libpng-1.7.0.
 
 There are seven time-related functions:
 
-    png_convert_to_rfc_1123() in png.c
-      (formerly png_convert_to_rfc_1152() in error)
+    png_convert_to_rfc_1123_buffer() in png.c
+      (formerly png_convert_to_rfc_1152() in error, and
+      also formerly png_convert_to_rfc_1123())
     png_convert_from_struct_tm() in pngwrite.c, called
       in pngwrite.c
     png_convert_from_time_t() in pngwrite.c
diff --git a/Source/LibPNG/libpng.3 b/Source/LibPNG/libpng.3
index e0e0aec..24c7d77 100644
--- a/Source/LibPNG/libpng.3
+++ b/Source/LibPNG/libpng.3
@@ -1,967 +1,498 @@
-.TH LIBPNG 3 "September 27, 2012"
+.TH LIBPNG 3 "December 22, 2014"
 .SH NAME
-libpng \- Portable Network Graphics (PNG) Reference Library 1.5.13
+libpng \- Portable Network Graphics (PNG) Reference Library 1.6.16
 .SH SYNOPSIS
-\fI\fB
-
-\fB#include <png.h>\fP
-
-\fI\fB
+\fB
+#include <png.h>\fP
 
 \fBpng_uint_32 png_access_version_number \fI(void\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_benign_error (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fIerror\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_build_grayscale_palette (int \fP\fIbit_depth\fP\fB, png_colorp \fIpalette\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_voidp png_calloc (png_structp \fP\fIpng_ptr\fP\fB, png_alloc_size_t \fIsize\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_chunk_benign_error (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fIerror\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_chunk_error (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fIerror\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_chunk_warning (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fImessage\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_convert_from_struct_tm (png_timep \fP\fIptime\fP\fB, struct tm FAR * \fIttime\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_convert_from_time_t (png_timep \fP\fIptime\fP\fB, time_t \fIttime\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_charp png_convert_to_rfc1123 (png_structp \fP\fIpng_ptr\fP\fB, png_timep \fIptime\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_infop png_create_info_struct (png_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_structp png_create_read_struct (png_const_charp \fP\fIuser_png_ver\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fIwarn_fn\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_structp png_create_read_struct_2 (png_const_charp \fP\fIuser_png_ver\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fP\fIwarn_fn\fP\fB, png_voidp \fP\fImem_ptr\fP\fB, png_malloc_ptr \fP\fImalloc_fn\fP\fB, png_free_ptr \fIfree_fn\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_structp png_create_write_struct (png_const_charp \fP\fIuser_png_ver\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fIwarn_fn\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_structp png_create_write_struct_2 (png_const_charp \fP\fIuser_png_ver\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fP\fIwarn_fn\fP\fB, png_voidp \fP\fImem_ptr\fP\fB, png_malloc_ptr \fP\fImalloc_fn\fP\fB, png_free_ptr \fIfree_fn\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_data_freer (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fP\fIfreer\fP\fB, png_uint_32 \fImask)\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_destroy_info_struct (png_structp \fP\fIpng_ptr\fP\fB, png_infopp \fIinfo_ptr_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_destroy_read_struct (png_structpp \fP\fIpng_ptr_ptr\fP\fB, png_infopp \fP\fIinfo_ptr_ptr\fP\fB, png_infopp \fIend_info_ptr_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_destroy_write_struct (png_structpp \fP\fIpng_ptr_ptr\fP\fB, png_infopp \fIinfo_ptr_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_err (png_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_error (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fIerror\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_free (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fIptr\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_free_chunk_list (png_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_free_default (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fIptr\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_free_data (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fInum\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_byte png_get_bit_depth (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fIinfo_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_uint_32 png_get_bKGD (png_const_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_color_16p \fI*background\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_byte png_get_channels (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fIinfo_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_uint_32 png_get_cHRM (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fP\fIinfo_ptr\fP\fB, double \fP\fI*white_x\fP\fB, double \fP\fI*white_y\fP\fB, double \fP\fI*red_x\fP\fB, double \fP\fI*red_y\fP\fB, double \fP\fI*green_x\fP\fB, double \fP\fI*green_y\fP\fB, double \fP\fI*blue_x\fP\fB, double \fI*blue_y\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_uint_32 png_get_cHRM_fixed (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fI*white_x\fP\fB, png_uint_32 \fP\fI*white_y\fP\fB, png_uint_32 \fP\fI*red_x\fP\fB, png_uint_32 \fP\fI*red_y\fP\fB, png_uint_32 \fP\fI*green_x\fP\fB, png_uint_32 \fP\fI*green_y\fP\fB, png_uint_32 \fP\fI*blue_x\fP\fB, png_uint_32 \fI*blue_y\fP\fB);\fP
 
-\fI\fB
-
-\fBpng_uint_32 png_get_cHRM_XYZ (png_structp \fIpng_ptr,
-
-\fBpng_const_infop \fP\fIinfo_ptr\fP\fB, double \fP\fI*red_X\fP\fB, double \fP\fI*red_Y\fP\fB, double \fI*red_Z,
-
-\fBdouble \fP\fI*green_X\fP\fB, double \fP\fI*green_Y\fP\fB, double \fP\fI*green_Z\fP\fB, double \fI*blue_X,
-
-\fBdouble \fP\fI*blue_Y\fP\fB, double \fI*blue_Z\fP\fB);\fP
-
-\fI\fB
+\fBpng_uint_32 png_get_cHRM_XYZ (png_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fP\fIinfo_ptr\fP\fB, double \fP\fI*red_X\fP\fB, double \fP\fI*red_Y\fP\fB, double \fP\fI*red_Z\fP\fB, double \fP\fI*green_X\fP\fB, double \fP\fI*green_Y\fP\fB, double \fP\fI*green_Z\fP\fB, double \fP\fI*blue_X\fP\fB, double \fP\fI*blue_Y\fP\fB, double \fI*blue_Z\fP\fB);\fP
 
 \fBpng_uint_32 png_get_cHRM_XYZ_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fP\fIinfo_ptr\fP\fB, png_fixed_point \fP\fI*int_red_X\fP\fB, png_fixed_point \fP\fI*int_red_Y\fP\fB, png_fixed_point \fP\fI*int_red_Z\fP\fB, png_fixed_point \fP\fI*int_green_X\fP\fB, png_fixed_point \fP\fI*int_green_Y\fP\fB, png_fixed_point \fP\fI*int_green_Z\fP\fB, png_fixed_point \fP\fI*int_blue_X\fP\fB, png_fixed_point \fP\fI*int_blue_Y\fP\fB, png_fixed_point \fI*int_blue_Z\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_uint_32 png_get_chunk_cache_max (png_const_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_alloc_size_t png_get_chunk_malloc_max (png_const_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_byte png_get_color_type (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fIinfo_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_uint_32 png_get_compression_buffer_size (png_const_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_byte png_get_compression_type (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fIinfo_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_byte png_get_copyright (png_const_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_uint_32 png_get_current_row_number \fI(png_const_structp\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_byte png_get_current_pass_number \fI(png_const_structp\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_voidp png_get_error_ptr (png_const_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_byte png_get_filter_type (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fIinfo_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_uint_32 png_get_gAMA (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fP\fIinfo_ptr\fP\fB, double \fI*file_gamma\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_uint_32 png_get_gAMA_fixed (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fI*int_file_gamma\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_byte png_get_header_ver (png_const_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_byte png_get_header_version (png_const_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_uint_32 png_get_hIST (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fP\fIinfo_ptr\fP\fB, png_uint_16p \fI*hist\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_uint_32 png_get_iCCP (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fP\fIinfo_ptr\fP\fB, png_charpp \fP\fIname\fP\fB, int \fP\fI*compression_type\fP\fB, png_bytepp \fP\fIprofile\fP\fB, png_uint_32 \fI*proflen\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_uint_32 png_get_IHDR (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fI*width\fP\fB, png_uint_32 \fP\fI*height\fP\fB, int \fP\fI*bit_depth\fP\fB, int \fP\fI*color_type\fP\fB, int \fP\fI*interlace_type\fP\fB, int \fP\fI*compression_type\fP\fB, int \fI*filter_type\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_uint_32 png_get_image_height (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fIinfo_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_uint_32 png_get_image_width (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fIinfo_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_int_32 png_get_int_32 (png_bytep \fIbuf\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_byte png_get_interlace_type (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fIinfo_ptr\fP\fB);\fP
 
-\fI\fB
-
-\fBpng_const_bytep png_get_io_chunk_name (png_structp \fIpng_ptr\fP\fB);\fP
-
-\fI\fB
-
 \fBpng_uint_32 png_get_io_chunk_type (png_const_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_voidp png_get_io_ptr (png_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_uint_32 png_get_io_state (png_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_byte png_get_libpng_ver (png_const_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_voidp png_get_mem_ptr (png_const_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_uint_32 png_get_oFFs (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fI*offset_x\fP\fB, png_uint_32 \fP\fI*offset_y\fP\fB, int \fI*unit_type\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_uint_32 png_get_pCAL (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fP\fIinfo_ptr\fP\fB, png_charp \fP\fI*purpose\fP\fB, png_int_32 \fP\fI*X0\fP\fB, png_int_32 \fP\fI*X1\fP\fB, int \fP\fI*type\fP\fB, int \fP\fI*nparams\fP\fB, png_charp \fP\fI*units\fP\fB, png_charpp \fI*params\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_uint_32 png_get_pHYs (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fI*res_x\fP\fB, png_uint_32 \fP\fI*res_y\fP\fB, int \fI*unit_type\fP\fB);\fP
 
-\fI\fB
-
 \fBfloat png_get_pixel_aspect_ratio (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fIinfo_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_uint_32 png_get_pHYs_dpi (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fI*res_x\fP\fB, png_uint_32 \fP\fI*res_y\fP\fB, int \fI*unit_type\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_fixed_point png_get_pixel_aspect_ratio_fixed (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fIinfo_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_uint_32 png_get_pixels_per_inch (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fIinfo_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_uint_32 png_get_pixels_per_meter (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fIinfo_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_voidp png_get_progressive_ptr (png_const_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_uint_32 png_get_PLTE (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fP\fIinfo_ptr\fP\fB, png_colorp \fP\fI*palette\fP\fB, int \fI*num_palette\fP\fB);\fP
 
-\fI\fB
-
-\fBpng_byte png_get_rgb_to_gray_status (png_const_structp \fIpng_ptr)
+\fBpng_byte png_get_rgb_to_gray_status (png_const_structp \fIpng_ptr\fP\fB);\fP
 
 \fBpng_uint_32 png_get_rowbytes (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fIinfo_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_bytepp png_get_rows (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fIinfo_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_uint_32 png_get_sBIT (png_const_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_color_8p \fI*sig_bit\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_get_sCAL (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fP\fIinfo_ptr\fP\fB, int* \fP\fIunit\fP\fB, double* \fP\fIwidth\fP\fB, double* \fIheight\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_get_sCAL_fixed (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fP\fIinfo_ptr\fP\fB, int* \fP\fIunit\fP\fB, png_fixed_pointp \fP\fIwidth\fP\fB, png_fixed_pointp \fIheight\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_get_sCAL_s (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fP\fIinfo_ptr\fP\fB, int* \fP\fIunit\fP\fB, png_charpp \fP\fIwidth\fP\fB, png_charpp \fIheight\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_bytep png_get_signature (png_const_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_uint_32 png_get_sPLT (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fP\fIinfo_ptr\fP\fB, png_spalette_p \fI*splt_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_uint_32 png_get_sRGB (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fP\fIinfo_ptr\fP\fB, int \fI*file_srgb_intent\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_uint_32 png_get_text (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fP\fIinfo_ptr\fP\fB, png_textp \fP\fI*text_ptr\fP\fB, int \fI*num_text\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_uint_32 png_get_tIME (png_const_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_timep \fI*mod_time\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_uint_32 png_get_tRNS (png_const_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytep \fP\fI*trans_alpha\fP\fB, int \fP\fI*num_trans\fP\fB, png_color_16p \fI*trans_color\fP\fB);\fP
 
-\fI\fB
-
 \fB/* This function is really an inline macro. \fI*/
 
 \fBpng_uint_16 png_get_uint_16 (png_bytep \fIbuf\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_uint_32 png_get_uint_31 (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fIbuf\fP\fB);\fP
 
-\fI\fB
-
 \fB/* This function is really an inline macro. \fI*/
 
 \fBpng_uint_32 png_get_uint_32 (png_bytep \fIbuf\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_uint_32 png_get_unknown_chunks (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fP\fIinfo_ptr\fP\fB, png_unknown_chunkpp \fIunknowns\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_voidp png_get_user_chunk_ptr (png_const_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_uint_32 png_get_user_height_max (png_const_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_voidp png_get_user_transform_ptr (png_const_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_uint_32 png_get_user_width_max (png_const_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_uint_32 png_get_valid (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIflag\fP\fB);\fP
 
-\fI\fB
-
 \fBfloat png_get_x_offset_inches (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fIinfo_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_fixed_point png_get_x_offset_inches_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fIinfo_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_int_32 png_get_x_offset_microns (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fIinfo_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_int_32 png_get_x_offset_pixels (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fIinfo_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_uint_32 png_get_x_pixels_per_inch (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fIinfo_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_uint_32 png_get_x_pixels_per_meter (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fIinfo_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBfloat png_get_y_offset_inches (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fIinfo_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_fixed_point png_get_y_offset_inches_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fIinfo_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_int_32 png_get_y_offset_microns (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fIinfo_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_int_32 png_get_y_offset_pixels (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fIinfo_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_uint_32 png_get_y_pixels_per_inch (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fIinfo_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_uint_32 png_get_y_pixels_per_meter (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fIinfo_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBint png_handle_as_unknown (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fIchunk_name\fP\fB);\fP
 
-\fI\fB
+\fBint png_image_begin_read_from_file (png_imagep \fP\fIimage\fP\fB, const char \fI*file_name\fP\fB);\fP
 
-\fBvoid png_info_init_3 (png_infopp \fP\fIinfo_ptr\fP\fB, png_size_t \fIpng_info_struct_size\fP\fB);\fP
+\fBint png_image_begin_read_from_stdio (png_imagep \fP\fIimage\fP\fB, FILE* \fIfile\fP\fB);\fP
 
-\fI\fB
+\fBint, png_image_begin_read_from_memory (png_imagep \fP\fIimage\fP\fB, png_const_voidp \fP\fImemory\fP\fB, png_size_t \fIsize\fP\fB);\fP
 
-\fBvoid png_init_io (png_structp \fP\fIpng_ptr\fP\fB, FILE \fI*fp\fP\fB);\fP
+\fBint png_image_finish_read (png_imagep \fP\fIimage\fP\fB, png_colorp \fP\fIbackground\fP\fB, void \fP\fI*buffer\fP\fB, png_int_32 \fP\fIrow_stride\fP\fB, void \fI*colormap\fP\fB);\fP
 
-\fI\fB
+\fBvoid png_image_free (png_imagep \fIimage\fP\fB);\fP
 
-\fBvoid png_longjmp (png_structp \fP\fIpng_ptr\fP\fB, int \fIval\fP\fB);\fP
+\fBint png_image_write_to_file (png_imagep \fP\fIimage\fP\fB, const char \fP\fI*file\fP\fB, int \fP\fIconvert_to_8bit\fP\fB, const void \fP\fI*buffer\fP\fB, png_int_32 \fP\fIrow_stride\fP\fB, void \fI*colormap\fP\fB);\fP
 
-\fI\fB
+\fBint png_image_write_to_stdio (png_imagep \fP\fIimage\fP\fB, FILE \fP\fI*file\fP\fB, int \fP\fIconvert_to_8_bit\fP\fB, const void \fP\fI*buffer\fP\fB, png_int_32 \fP\fIrow_stride\fP\fB, void \fI*colormap)\fP\fB);\fP
 
-\fBpng_voidp png_malloc (png_structp \fP\fIpng_ptr\fP\fB, png_alloc_size_t \fIsize\fP\fB);\fP
+\fBvoid png_info_init_3 (png_infopp \fP\fIinfo_ptr\fP\fB, png_size_t \fIpng_info_struct_size\fP\fB);\fP
 
-\fI\fB
+\fBvoid png_init_io (png_structp \fP\fIpng_ptr\fP\fB, FILE \fI*fp\fP\fB);\fP
 
-\fBpng_voidp png_malloc_default (png_structp \fP\fIpng_ptr\fP\fB, png_alloc_size_t \fIsize\fP\fB);\fP
+\fBvoid png_longjmp (png_structp \fP\fIpng_ptr\fP\fB, int \fIval\fP\fB);\fP
+
+\fBpng_voidp png_malloc (png_structp \fP\fIpng_ptr\fP\fB, png_alloc_size_t \fIsize\fP\fB);\fP
 
-\fI\fB
+\fBpng_voidp png_malloc_default (png_structp \fP\fIpng_ptr\fP\fB, png_alloc_size_t \fIsize\fP\fB);\fP
 
 \fBpng_voidp png_malloc_warn (png_structp \fP\fIpng_ptr\fP\fB, png_alloc_size_t \fIsize\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_uint_32 png_permit_mng_features (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fImng_features_permitted\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_process_data (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytep \fP\fIbuffer\fP\fB, png_size_t \fIbuffer_size\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_size_t png_process_data_pause \fP\fI(png_structp\fP\fB, int \fIsave\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_uint_32 png_process_data_skip \fI(png_structp\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_progressive_combine_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIold_row\fP\fB, png_bytep \fInew_row\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_read_end (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_read_image (png_structp \fP\fIpng_ptr\fP\fB, png_bytepp \fIimage\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_read_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_read_png (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fP\fItransforms\fP\fB, png_voidp \fIparams\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_read_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIrow\fP\fB, png_bytep \fIdisplay_row\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_read_rows (png_structp \fP\fIpng_ptr\fP\fB, png_bytepp \fP\fIrow\fP\fB, png_bytepp \fP\fIdisplay_row\fP\fB, png_uint_32 \fInum_rows\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_read_update_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBint png_reset_zstream (png_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_save_int_32 (png_bytep \fP\fIbuf\fP\fB, png_int_32 \fIi\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_save_uint_16 (png_bytep \fP\fIbuf\fP\fB, unsigned int \fIi\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_save_uint_32 (png_bytep \fP\fIbuf\fP\fB, png_uint_32 \fIi\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_add_alpha (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIfiller\fP\fB, int \fIflags\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_alpha_mode (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fImode\fP\fB, double \fIoutput_gamma\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_alpha_mode_fixed (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fImode\fP\fB, png_fixed_point \fIoutput_gamma\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_background (png_structp \fP\fIpng_ptr\fP\fB, png_color_16p \fP\fIbackground_color\fP\fB, int \fP\fIbackground_gamma_code\fP\fB, int \fP\fIneed_expand\fP\fB, double \fIbackground_gamma\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_background_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_color_16p \fP\fIbackground_color\fP\fB, int \fP\fIbackground_gamma_code\fP\fB, int \fP\fIneed_expand\fP\fB, png_uint_32 \fIbackground_gamma\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_benign_errors (png_structp \fP\fIpng_ptr\fP\fB, int \fIallowed\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_bgr (png_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_bKGD (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_color_16p \fIbackground\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_check_for_invalid_index(png_structrp \fP\fIpng_ptr\fP\fB, int \fIallowed\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_cHRM (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fP\fIwhite_x\fP\fB, double \fP\fIwhite_y\fP\fB, double \fP\fIred_x\fP\fB, double \fP\fIred_y\fP\fB, double \fP\fIgreen_x\fP\fB, double \fP\fIgreen_y\fP\fB, double \fP\fIblue_x\fP\fB, double \fIblue_y\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_cHRM_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fIwhite_x\fP\fB, png_uint_32 \fP\fIwhite_y\fP\fB, png_uint_32 \fP\fIred_x\fP\fB, png_uint_32 \fP\fIred_y\fP\fB, png_uint_32 \fP\fIgreen_x\fP\fB, png_uint_32 \fP\fIgreen_y\fP\fB, png_uint_32 \fP\fIblue_x\fP\fB, png_uint_32 \fIblue_y\fP\fB);\fP
 
-\fI\fB
-
-\fBvoid png_set_cHRM_XYZ (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fP\fIred_X\fP\fB, double \fP\fIred_Y\fP\fB, double \fP\fIred_Z\fP\fB, double \fP\fIgreen_X\fP\fB, double \fIgreen_Y,
-
-\fBdouble \fP\fIgreen_Z\fP\fB, double \fP\fIblue_X\fP\fB, double \fP\fIblue_Y\fP\fB, double \fIblue_Z\fP\fB);\fP
-
-\fI\fB
+\fBvoid png_set_cHRM_XYZ (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fP\fIred_X\fP\fB, double \fP\fIred_Y\fP\fB, double \fP\fIred_Z\fP\fB, double \fP\fIgreen_X\fP\fB, double \fP\fIgreen_Y\fP\fB, double \fP\fIgreen_Z\fP\fB, double \fP\fIblue_X\fP\fB, double \fP\fIblue_Y\fP\fB, double \fIblue_Z\fP\fB);\fP
 
 \fBvoid png_set_cHRM_XYZ_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_fixed_point \fP\fIint_red_X\fP\fB, png_fixed_point \fP\fIint_red_Y\fP\fB, png_fixed_point \fP\fIint_red_Z\fP\fB, png_fixed_point \fP\fIint_green_X\fP\fB, png_fixed_point \fP\fIint_green_Y\fP\fB, png_fixed_point \fP\fIint_green_Z\fP\fB, png_fixed_point \fP\fIint_blue_X\fP\fB, png_fixed_point \fP\fIint_blue_Y\fP\fB, png_fixed_point \fIint_blue_Z\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_chunk_cache_max (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIuser_chunk_cache_max\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_compression_level (png_structp \fP\fIpng_ptr\fP\fB, int \fIlevel\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_compression_mem_level (png_structp \fP\fIpng_ptr\fP\fB, int \fImem_level\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_compression_method (png_structp \fP\fIpng_ptr\fP\fB, int \fImethod\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_compression_strategy (png_structp \fP\fIpng_ptr\fP\fB, int \fIstrategy\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_compression_window_bits (png_structp \fP\fIpng_ptr\fP\fB, int \fIwindow_bits\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_crc_action (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIcrit_action\fP\fB, int \fIancil_action\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_error_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fIwarning_fn\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_expand (png_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_expand_16 (png_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_expand_gray_1_2_4_to_8 (png_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_filler (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIfiller\fP\fB, int \fIflags\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_filter (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fImethod\fP\fB, int \fIfilters\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_filter_heuristics (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIheuristic_method\fP\fB, int \fP\fInum_weights\fP\fB, png_doublep \fP\fIfilter_weights\fP\fB, png_doublep \fIfilter_costs\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_filter_heuristics_fixed (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIheuristic_method\fP\fB, int \fP\fInum_weights\fP\fB, png_fixed_point_p \fP\fIfilter_weights\fP\fB, png_fixed_point_p \fIfilter_costs\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_flush (png_structp \fP\fIpng_ptr\fP\fB, int \fInrows\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_gamma (png_structp \fP\fIpng_ptr\fP\fB, double \fP\fIscreen_gamma\fP\fB, double \fIdefault_file_gamma\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_gamma_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIscreen_gamma\fP\fB, png_uint_32 \fIdefault_file_gamma\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_gAMA (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fIfile_gamma\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_gAMA_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIfile_gamma\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_gray_1_2_4_to_8 (png_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_gray_to_rgb (png_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_hIST (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_16p \fIhist\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_iCCP (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_const_charp \fP\fIname\fP\fB, int \fP\fIcompression_type\fP\fB, png_const_bytep \fP\fIprofile\fP\fB, png_uint_32 \fIproflen\fP\fB);\fP
 
-\fI\fB
-
 \fBint png_set_interlace_handling (png_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_invalid (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fImask\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_invert_alpha (png_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_invert_mono (png_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_IHDR (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fIwidth\fP\fB, png_uint_32 \fP\fIheight\fP\fB, int \fP\fIbit_depth\fP\fB, int \fP\fIcolor_type\fP\fB, int \fP\fIinterlace_type\fP\fB, int \fP\fIcompression_type\fP\fB, int \fIfilter_type\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_keep_unknown_chunks (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIkeep\fP\fB, png_bytep \fP\fIchunk_list\fP\fB, int \fInum_chunks\fP\fB);\fP
 
-\fI\fB
-
 \fBjmp_buf* png_set_longjmp_fn (png_structp \fP\fIpng_ptr\fP\fB, png_longjmp_ptr \fP\fIlongjmp_fn\fP\fB, size_t \fIjmp_buf_size\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_chunk_malloc_max (png_structp \fP\fIpng_ptr\fP\fB, png_alloc_size_t \fIuser_chunk_cache_max\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_compression_buffer_size (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIsize\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_mem_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fImem_ptr\fP\fB, png_malloc_ptr \fP\fImalloc_fn\fP\fB, png_free_ptr \fIfree_fn\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_oFFs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fIoffset_x\fP\fB, png_uint_32 \fP\fIoffset_y\fP\fB, int \fIunit_type\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_packing (png_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_packswap (png_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_palette_to_rgb (png_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_pCAL (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_charp \fP\fIpurpose\fP\fB, png_int_32 \fP\fIX0\fP\fB, png_int_32 \fP\fIX1\fP\fB, int \fP\fItype\fP\fB, int \fP\fInparams\fP\fB, png_charp \fP\fIunits\fP\fB, png_charpp \fIparams\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_pHYs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fIres_x\fP\fB, png_uint_32 \fP\fIres_y\fP\fB, int \fIunit_type\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_progressive_read_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIprogressive_ptr\fP\fB, png_progressive_info_ptr \fP\fIinfo_fn\fP\fB, png_progressive_row_ptr \fP\fIrow_fn\fP\fB, png_progressive_end_ptr \fIend_fn\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_PLTE (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_colorp \fP\fIpalette\fP\fB, int \fInum_palette\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_quantize (png_structp \fP\fIpng_ptr\fP\fB, png_colorp \fP\fIpalette\fP\fB, int \fP\fInum_palette\fP\fB, int \fP\fImaximum_colors\fP\fB, png_uint_16p \fP\fIhistogram\fP\fB, int \fIfull_quantize\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_read_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIio_ptr\fP\fB, png_rw_ptr \fIread_data_fn\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_read_status_fn (png_structp \fP\fIpng_ptr\fP\fB, png_read_status_ptr \fIread_row_fn\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_read_user_chunk_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIuser_chunk_ptr\fP\fB, png_user_chunk_ptr \fIread_user_chunk_fn\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_read_user_transform_fn (png_structp \fP\fIpng_ptr\fP\fB, png_user_transform_ptr \fIread_user_transform_fn\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_rgb_to_gray (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIerror_action\fP\fB, double \fP\fIred\fP\fB, double \fIgreen\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_rgb_to_gray_fixed (png_structp \fP\fIpng_ptr\fP\fB, int error_action png_uint_32 \fP\fIred\fP\fB, png_uint_32 \fIgreen\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_rows (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytepp \fIrow_pointers\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_sBIT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_color_8p \fIsig_bit\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_sCAL (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fP\fIunit\fP\fB, double \fP\fIwidth\fP\fB, double \fIheight\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_sCAL_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fP\fIunit\fP\fB, png_fixed_point \fP\fIwidth\fP\fB, png_fixed_point \fIheight\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_sCAL_s (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fP\fIunit\fP\fB, png_charp \fP\fIwidth\fP\fB, png_charp \fIheight\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_scale_16 (png_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_shift (png_structp \fP\fIpng_ptr\fP\fB, png_color_8p \fItrue_bits\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_sig_bytes (png_structp \fP\fIpng_ptr\fP\fB, int \fInum_bytes\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_sPLT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_spalette_p \fP\fIsplt_ptr\fP\fB, int \fInum_spalettes\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_sRGB (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fIsrgb_intent\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_sRGB_gAMA_and_cHRM (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fIsrgb_intent\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_strip_16 (png_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_strip_alpha (png_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_strip_error_numbers (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIstrip_mode\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_swap (png_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_swap_alpha (png_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_text (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_textp \fP\fItext_ptr\fP\fB, int \fInum_text\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_text_compression_level (png_structp \fP\fIpng_ptr\fP\fB, int \fIlevel\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_text_compression_mem_level (png_structp \fP\fIpng_ptr\fP\fB, int \fImem_level\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_text_compression_strategy (png_structp \fP\fIpng_ptr\fP\fB, int \fIstrategy\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_text_compression_window_bits (png_structp \fP\fIpng_ptr\fP\fB, int \fIwindow_bits\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid \fP\fIpng_set_text_compression_method\fP\fB, (png_structp \fP\fIpng_ptr\fP\fB, int \fImethod)\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_tIME (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_timep \fImod_time\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_tRNS (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytep \fP\fItrans_alpha\fP\fB, int \fP\fInum_trans\fP\fB, png_color_16p \fItrans_color\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_tRNS_to_alpha (png_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBpng_uint_32 png_set_unknown_chunks (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_unknown_chunkp \fP\fIunknowns\fP\fB, int \fP\fInum\fP\fB, int \fIlocation\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_unknown_chunk_location (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fP\fIchunk\fP\fB, int \fIlocation\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_user_limits (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIuser_width_max\fP\fB, png_uint_32 \fIuser_height_max\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_user_transform_info (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIuser_transform_ptr\fP\fB, int \fP\fIuser_transform_depth\fP\fB, int \fIuser_transform_channels\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_write_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIio_ptr\fP\fB, png_rw_ptr \fP\fIwrite_data_fn\fP\fB, png_flush_ptr \fIoutput_flush_fn\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_write_status_fn (png_structp \fP\fIpng_ptr\fP\fB, png_write_status_ptr \fIwrite_row_fn\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_set_write_user_transform_fn (png_structp \fP\fIpng_ptr\fP\fB, png_user_transform_ptr \fIwrite_user_transform_fn\fP\fB);\fP
 
-\fI\fB
-
 \fBint png_sig_cmp (png_bytep \fP\fIsig\fP\fB, png_size_t \fP\fIstart\fP\fB, png_size_t \fInum_to_check\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_start_read_image (png_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_warning (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fImessage\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_write_chunk (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIchunk_name\fP\fB, png_bytep \fP\fIdata\fP\fB, png_size_t \fIlength\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_write_chunk_data (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIdata\fP\fB, png_size_t \fIlength\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_write_chunk_end (png_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_write_chunk_start (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIchunk_name\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_write_end (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_write_flush (png_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_write_image (png_structp \fP\fIpng_ptr\fP\fB, png_bytepp \fIimage\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_write_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_write_info_before_PLTE (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_write_png (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fP\fItransforms\fP\fB, png_voidp \fIparams\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_write_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fIrow\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_write_rows (png_structp \fP\fIpng_ptr\fP\fB, png_bytepp \fP\fIrow\fP\fB, png_uint_32 \fInum_rows\fP\fB);\fP
 
-\fI\fB
-
 \fBvoid png_write_sig (png_structp \fIpng_ptr\fP\fB);\fP
 
-\fI\fB
-
 .SH DESCRIPTION
 The
 .I libpng
@@ -971,12 +502,12 @@ the Portable Network Graphics (PNG) format image files.  It uses the
 compression library.
 Following is a copy of the libpng-manual.txt file that accompanies libpng.
 .SH LIBPNG.TXT
-Libpng-manual.txt - A description on how to use and modify libpng
+libpng-manual.txt - A description on how to use and modify libpng
 
- libpng version 1.5.13 - September 27, 2012
+ libpng version 1.6.16 - December 22, 2014
  Updated and distributed by Glenn Randers-Pehrson
  <glennrp at users.sourceforge.net>
- Copyright (c) 1998-2012 Glenn Randers-Pehrson
+ Copyright (c) 1998-2014 Glenn Randers-Pehrson
 
  This document is released under the libpng license.
  For conditions of distribution and use, see the disclaimer
@@ -984,15 +515,15 @@ Libpng-manual.txt - A description on how to use and modify libpng
 
  Based on:
 
- libpng versions 0.97, January 1998, through 1.5.13 - September 27, 2012
+ libpng versions 0.97, January 1998, through 1.6.16 - December 22, 2014
  Updated and distributed by Glenn Randers-Pehrson
- Copyright (c) 1998-2012 Glenn Randers-Pehrson
+ Copyright (c) 1998-2014 Glenn Randers-Pehrson
 
- libpng 1.0 beta 6  version 0.96 May 28, 1997
+ libpng 1.0 beta 6 - version 0.96 - May 28, 1997
  Updated and distributed by Andreas Dilger
  Copyright (c) 1996, 1997 Andreas Dilger
 
- libpng 1.0 beta 2 - version 0.88  January 26, 1996
+ libpng 1.0 beta 2 - version 0.88 - January 26, 1996
  For conditions of distribution and use, see copyright
  notice in png.h. Copyright (c) 1995, 1996 Guy Eric
  Schalnat, Group 42, Inc.
@@ -1001,16 +532,33 @@ Libpng-manual.txt - A description on how to use and modify libpng
  Copyright (c) 1995, 1996 Frank J. T. Wojcik
  December 18, 1995 & January 20, 1996
 
+ TABLE OF CONTENTS
+
+    I. Introduction
+   II. Structures
+  III. Reading
+   IV. Writing
+    V. Simplified API
+   VI. Modifying/Customizing libpng
+  VII. MNG support
+ VIII. Changes to Libpng from version 0.88
+   IX. Changes to Libpng from version 1.0.x to 1.2.x
+    X. Changes to Libpng from version 1.0.x/1.2.x to 1.4.x
+   XI. Changes to Libpng from version 1.4.x to 1.5.x
+  XII. Changes to Libpng from version 1.5.x to 1.6.x
+ XIII. Detecting libpng
+  XIV. Source code repository
+   XV. Coding style
+  XVI. Y2K Compliance in libpng
+
 .SH I. Introduction
 
 This file describes how to use and modify the PNG reference library
-(known as libpng) for your own use.  There are five sections to this
-file: introduction, structures, reading, writing, and modification and
-configuration notes for various special platforms.  In addition to this
+(known as libpng) for your own use.  In addition to this
 file, example.c is a good starting point for using the library, as
 it is heavily commented and should include everything most people
 will need.  We assume that libpng is already installed; see the
-INSTALL file for instructions on how to install libpng.
+INSTALL file for instructions on how to configure and install libpng.
 
 For examples of libpng usage, see the files "example.c", "pngtest.c",
 and the files in the "contrib" directory, all of which are included in
@@ -1021,7 +569,7 @@ of reducing the amount of time and effort it takes to support the PNG
 file format in application programs.
 
 The PNG specification (second edition), November 2003, is available as
-a W3C Recommendation and as an ISO Standard (ISO/IEC 15948:2003 (E)) at
+a W3C Recommendation and as an ISO Standard (ISO/IEC 15948:2004 (E)) at
 <http://www.w3.org/TR/2003/REC-PNG-20031110/
 The W3C and ISO documents have identical technical content.
 
@@ -1124,7 +672,7 @@ All APIs that take (double) arguments also have a matching API that
 takes the corresponding fixed point integer arguments.  The fixed point
 API has the same name as the floating point one with "_fixed" appended.
 The actual range of values permitted in the APIs is frequently less than
-the full range of (png_fixed_point) (-21474 to +21474).  When APIs require
+the full range of (png_fixed_point) (\-21474 to +21474).  When APIs require
 a non-negative argument the type is recorded as png_uint_32 above.  Consult
 the header file and the text below for more information.
 
@@ -1165,7 +713,7 @@ The easiest way to make minor changes to the libpng configuration when
 auto-configuration is supported is to add definitions to the command line
 using (typically) CPPFLAGS.  For example:
 
-CPPFLAGS=-DPNG_NO_FLOATING_ARITHMETIC
+CPPFLAGS=\-DPNG_NO_FLOATING_ARITHMETIC
 
 will change the internal libpng math implementation for gamma correction and
 other arithmetic calculations to fixed point, avoiding the need for fast
@@ -1173,7 +721,7 @@ floating point support.  The result can be seen in the generated pnglibconf.h -
 make sure it contains the changed feature macro setting.
 
 If you need to make more extensive configuration changes - more than one or two
-feature macro settings - you can either add -DPNG_USER_CONFIG to the build
+feature macro settings - you can either add \-DPNG_USER_CONFIG to the build
 command line and put a list of feature macro settings in pngusr.h or you can set
 DFA_XTRA (a makefile variable) to a file containing the same information in the
 form of 'option' settings.
@@ -1230,10 +778,10 @@ This method of building a customized pnglibconf.h is illustrated in
 contrib/pngminim/*.  See the "$(PNGCONF):" target in the makefile and
 pngusr.dfa in these directories.
 
-C. Configuration using PNG_USR_CONFIG
+C. Configuration using PNG_USER_CONFIG
 
-If -DPNG_USR_CONFIG is added to the CFLAGS when pnglibconf.h is built the file
-pngusr.h will automatically be included before the options in
+If \-DPNG_USER_CONFIG is added to the CPPFLAGS when pnglibconf.h is built,
+the file pngusr.h will automatically be included before the options in
 scripts/pnglibconf.dfa are processed.  Your pngusr.h file should contain only
 macro definitions turning features on or off or setting settings.
 
@@ -1462,7 +1010,7 @@ input stream. You must supply the function
           unknown chunk structure, process it, and return one
           of the following: */
 
-       return (-n); /* chunk had an error */
+       return (\-n); /* chunk had an error */
        return (0); /* did not recognize */
        return (n); /* success */
     }
@@ -1481,9 +1029,14 @@ you can retrieve with
     png_get_user_chunk_ptr(png_ptr);
 
 If you call the png_set_read_user_chunk_fn() function, then all unknown
-chunks will be saved when read, in case your callback function will need
-one or more of them.  This behavior can be changed with the
-png_set_keep_unknown_chunks() function, described below.
+chunks which the callback does not handle will be saved when read.  You can
+cause them to be discarded by returning '1' ("handled") instead of '0'.  This
+behavior will change in libpng 1.7 and the default handling set by the
+png_set_keep_unknown_chunks() function, described below, will be used when the
+callback returns 0.  If you want the existing behavior you should set the global
+default to PNG_HANDLE_CHUNK_IF_SAFE now; this is compatible with all current
+versions of libpng and with 1.7.  Libpng 1.6 issues a warning if you keep the
+default, or PNG_HANDLE_CHUNK_NEVER, and the callback returns 0.
 
 At this point, you can set up a callback function that will be
 called after each row has been read, which you can use to control
@@ -1508,7 +1061,7 @@ non-interlaced case the row that was just handled is simply one less than the
 passed in row number, and pass will always be 0.  For the interlaced case the
 same applies unless the row value is 0, in which case the row just handled was
 the last one from one of the preceding passes.  Because interlacing may skip a
-pass you cannot be sure that the preceding pass is just 'pass-1', if you really
+pass you cannot be sure that the preceding pass is just 'pass\-1', if you really
 need to know what the last pass is record (row,pass) from the callback and use
 the last recorded value each time.
 
@@ -1526,6 +1079,7 @@ chunk types. To change this, you can call:
 
     png_set_keep_unknown_chunks(png_ptr, keep,
         chunk_list, num_chunks);
+
     keep       - 0: default unknown chunk handling
                  1: ignore; do not keep
                  2: keep only if safe-to-copy
@@ -1539,11 +1093,16 @@ chunk types. To change this, you can call:
 
     chunk_list - list of chunks affected (a byte string,
                  five bytes per chunk, NULL or '\0' if
-                 num_chunks is 0)
+                 num_chunks is positive; ignored if
+                 numchunks <= 0).
 
     num_chunks - number of chunks affected; if 0, all
-                 unknown chunks are affected.  If nonzero,
-                 only the chunks in the list are affected
+                 unknown chunks are affected.  If positive,
+                 only the chunks in the list are affected,
+                 and if negative all unknown chunks and
+                 all known chunks except for the IHDR,
+                 PLTE, tRNS, IDAT, and IEND chunks are
+                 affected.
 
 Unknown chunks declared in this way will be saved as raw data onto a
 list of png_unknown_chunk structures.  If a chunk that is normally
@@ -1576,30 +1135,29 @@ callback function:
     ...
 
     #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
-      /* ignore all unknown chunks: */
-      png_set_keep_unknown_chunks(read_ptr, 1, NULL, 0);
+      /* ignore all unknown chunks
+       * (use global setting "2" for libpng16 and earlier):
+       */
+      png_set_keep_unknown_chunks(read_ptr, 2, NULL, 0);
 
       /* except for vpAg: */
       png_set_keep_unknown_chunks(read_ptr, 2, vpAg, 1);
 
       /* also ignore unused known chunks: */
       png_set_keep_unknown_chunks(read_ptr, 1, unused_chunks,
-         (int)sizeof(unused_chunks)/5);
+         (int)(sizeof unused_chunks)/5);
     #endif
 
 .SS User limits
 
 The PNG specification allows the width and height of an image to be as
-large as 2^31-1 (0x7fffffff), or about 2.147 billion rows and columns.
-Since very few applications really need to process such large images,
-we have imposed an arbitrary 1-million limit on rows and columns.
+large as 2^(31\-1 (0x7fffffff), or about 2.147 billion rows and columns.
 Larger images will be rejected immediately with a png_error() call. If
-you wish to change this limit, you can use
+you wish to reduce these limits, you can use
 
    png_set_user_limits(png_ptr, width_max, height_max);
 
-to set your own limits, or use width_max = height_max = 0x7fffffffL
-to allow all valid dimensions (libpng may reject some very large images
+to set your own limits (libpng may reject some very wide images
 anyway because of potential buffer overflow conditions).
 
 You should put this statement after you create the PNG structure and
@@ -1623,9 +1181,6 @@ where 0x7fffffffL means unlimited.  You can retrieve this limit with
 
    chunk_cache_max = png_get_chunk_cache_max(png_ptr);
 
-This limit also applies to the number of buffers that can be allocated
-by png_decompress_chunk() while decompressing iTXt, zTXt, and iCCP chunks.
-
 You can also set a limit on the amount of memory that a compressed chunk
 other than IDAT can occupy, with
 
@@ -1658,11 +1213,12 @@ value.  You can also specify a default encoding for the PNG file in
 case the required information is missing from the file.  By default libpng
 assumes that the PNG data matches your system, to keep this default call:
 
-   png_set_gamma(png_ptr, screen_gamma, 1/screen_gamma/*file gamma*/);
+   png_set_gamma(png_ptr, screen_gamma, output_gamma);
 
 or you can use the fixed point equivalent:
 
-   png_set_gamma_fixed(png_ptr, PNG_FP_1*screen_gamma, PNG_FP_1/screen_gamma);
+   png_set_gamma_fixed(png_ptr, PNG_FP_1*screen_gamma,
+      PNG_FP_1*output_gamma);
 
 If you don't know the gamma for your system it is probably 2.2 - a good
 approximation to the IEC standard for display systems (sRGB).  If images are
@@ -1674,19 +1230,86 @@ display driver, a few systems, including older Macs, change the response by
 default.  As of 1.5.4 three special values are available to handle common
 situations:
 
-   PNG_DEFAULT_sRGB: Indicates that the system conforms to the IEC 61966-2-1
-                     standard.  This matches almost all systems.
-   PNG_GAMMA_MAC_18: Indicates that the system is an older (pre Mac OS 10.6)
-                     Apple Macintosh system with the default settings.
-   PNG_GAMMA_LINEAR: Just the fixed point value for 1.0 - indicates that the
-                     system expects data with no gamma encoding.
+   PNG_DEFAULT_sRGB: Indicates that the system conforms to the
+                     IEC 61966-2-1 standard.  This matches almost
+                     all systems.
+   PNG_GAMMA_MAC_18: Indicates that the system is an older
+                     (pre Mac OS 10.6) Apple Macintosh system with
+                     the default settings.
+   PNG_GAMMA_LINEAR: Just the fixed point value for 1.0 - indicates
+                     that the system expects data with no gamma
+                     encoding.
 
 You would use the linear (unencoded) value if you need to process the pixel
-values further because this avoids the need to decode and reencode each
+values further because this avoids the need to decode and re-encode each
 component value whenever arithmetic is performed.  A lot of graphics software
 uses linear values for this reason, often with higher precision component values
 to preserve overall accuracy.
 
+
+The output_gamma value expresses how to decode the output values, not how
+they are encoded.  The values used correspond to the normal numbers used to
+describe the overall gamma of a computer display system; for example 2.2 for
+an sRGB conformant system.  The values are scaled by 100000 in the _fixed
+version of the API (so 220000 for sRGB.)
+
+The inverse of the value is always used to provide a default for the PNG file
+encoding if it has no gAMA chunk and if png_set_gamma() has not been called
+to override the PNG gamma information.
+
+When the ALPHA_OPTIMIZED mode is selected the output gamma is used to encode
+opaque pixels however pixels with lower alpha values are not encoded,
+regardless of the output gamma setting.
+
+When the standard Porter Duff handling is requested with mode 1 the output
+encoding is set to be linear and the output_gamma value is only relevant
+as a default for input data that has no gamma information.  The linear output
+encoding will be overridden if png_set_gamma() is called - the results may be
+highly unexpected!
+
+The following numbers are derived from the sRGB standard and the research
+behind it.  sRGB is defined to be approximated by a PNG gAMA chunk value of
+0.45455 (1/2.2) for PNG.  The value implicitly includes any viewing
+correction required to take account of any differences in the color
+environment of the original scene and the intended display environment; the
+value expresses how to *decode* the image for display, not how the original
+data was *encoded*.
+
+sRGB provides a peg for the PNG standard by defining a viewing environment.
+sRGB itself, and earlier TV standards, actually use a more complex transform
+(a linear portion then a gamma 2.4 power law) than PNG can express.  (PNG is
+limited to simple power laws.)  By saying that an image for direct display on
+an sRGB conformant system should be stored with a gAMA chunk value of 45455
+(11.3.3.2 and 11.3.3.5 of the ISO PNG specification) the PNG specification
+makes it possible to derive values for other display systems and
+environments.
+
+The Mac value is deduced from the sRGB based on an assumption that the actual
+extra viewing correction used in early Mac display systems was implemented as
+a power 1.45 lookup table.
+
+Any system where a programmable lookup table is used or where the behavior of
+the final display device characteristics can be changed requires system
+specific code to obtain the current characteristic.  However this can be
+difficult and most PNG gamma correction only requires an approximate value.
+
+By default, if png_set_alpha_mode() is not called, libpng assumes that all
+values are unencoded, linear, values and that the output device also has a
+linear characteristic.  This is only very rarely correct - it is invariably
+better to call png_set_alpha_mode() with PNG_DEFAULT_sRGB than rely on the
+default if you don't know what the right answer is!
+
+The special value PNG_GAMMA_MAC_18 indicates an older Mac system (pre Mac OS
+10.6) which used a correction table to implement a somewhat lower gamma on an
+otherwise sRGB system.
+
+Both these values are reserved (not simple gamma values) in order to allow
+more precise correction internally in the future.
+
+NOTE: the values can be passed to either the fixed or floating
+point APIs, but the floating point API will also accept floating point
+values.
+
 The second thing you may need to tell libpng about is how your system handles
 alpha channel information.  Some, but not all, PNG files contain an alpha
 channel.  To display these files correctly you need to compose the data onto a
@@ -1696,11 +1319,11 @@ Libpng only supports composing onto a single color (using png_set_background;
 see below).  Otherwise you must do the composition yourself and, in this case,
 you may need to call png_set_alpha_mode:
 
-    #if PNG_LIBPNG_VER >= 10504
-       png_set_alpha_mode(png_ptr, mode, screen_gamma);
-    #else
-       png_set_gamma(png_ptr, screen_gamma, 1.0/screen_gamma);
-    #endif
+   #if PNG_LIBPNG_VER >= 10504
+      png_set_alpha_mode(png_ptr, mode, screen_gamma);
+   #else
+      png_set_gamma(png_ptr, screen_gamma, 1.0/screen_gamma);
+   #endif
 
 The screen_gamma value is the same as the argument to png_set_gamma; however,
 how it affects the output depends on the mode.  png_set_alpha_mode() sets the
@@ -1711,11 +1334,11 @@ by png_set_alpha_mode().
 
 The mode is as follows:
 
-    PNG_ALPHA_PNG: The data is encoded according to the PNG specification.  Red,
-green and blue, or gray, components are gamma encoded color
-values and are not premultiplied by the alpha value.  The
-alpha value is a linear measure of the contribution of the
-pixel to the corresponding final output pixel.
+    PNG_ALPHA_PNG: The data is encoded according to the PNG
+specification.  Red, green and blue, or gray, components are
+gamma encoded color values and are not premultiplied by the
+alpha value.  The alpha value is a linear measure of the
+contribution of the pixel to the corresponding final output pixel.
 
 You should normally use this format if you intend to perform
 color correction on the color values; most, maybe all, color
@@ -1732,11 +1355,35 @@ be used!
 
 The remaining modes assume you don't need to do any further color correction or
 that if you do, your color correction software knows all about alpha (it
-probably doesn't!)
-
-    PNG_ALPHA_STANDARD:  The data libpng produces
-is encoded in the standard way
-assumed by most correctly written graphics software.
+probably doesn't!).  They 'associate' the alpha with the color information by
+storing color channel values that have been scaled by the alpha.  The
+advantage is that the color channels can be resampled (the image can be
+scaled) in this form.  The disadvantage is that normal practice is to store
+linear, not (gamma) encoded, values and this requires 16-bit channels for
+still images rather than the 8-bit channels that are just about sufficient if
+gamma encoding is used.  In addition all non-transparent pixel values,
+including completely opaque ones, must be gamma encoded to produce the final
+image.  These are the 'STANDARD', 'ASSOCIATED' or 'PREMULTIPLIED' modes
+described below (the latter being the two common names for associated alpha
+color channels). Note that PNG files always contain non-associated color
+channels; png_set_alpha_mode() with one of the modes causes the decoder to
+convert the pixels to an associated form before returning them to your
+application. 
+
+Since it is not necessary to perform arithmetic on opaque color values so
+long as they are not to be resampled and are in the final color space it is
+possible to optimize the handling of alpha by storing the opaque pixels in
+the PNG format (adjusted for the output color space) while storing partially
+opaque pixels in the standard, linear, format.  The accuracy required for
+standard alpha composition is relatively low, because the pixels are
+isolated, therefore typically the accuracy loss in storing 8-bit linear
+values is acceptable.  (This is not true if the alpha channel is used to
+simulate transparency over large areas - use 16 bits or the PNG mode in
+this case!)  This is the 'OPTIMIZED' mode.  For this mode a pixel is
+treated as opaque only if the alpha value is equal to the maximum value.
+
+    PNG_ALPHA_STANDARD:  The data libpng produces is encoded in the
+standard way assumed by most correctly written graphics software.
 The gamma encoding will be removed by libpng and the
 linear component values will be pre-multiplied by the
 alpha channel.
@@ -1765,9 +1412,8 @@ dynamic range.  To avoid problems, and if your software
 supports it, use png_set_expand_16() to force all
 components to 16 bits.
 
-    PNG_ALPHA_OPTIMIZED: This mode is the same
-as PNG_ALPHA_STANDARD except that
-completely opaque pixels are gamma encoded according to
+    PNG_ALPHA_OPTIMIZED: This mode is the same as PNG_ALPHA_STANDARD
+except that completely opaque pixels are gamma encoded according to
 the screen_gamma value.  Pixels with alpha less than 1.0
 will still have linear components.
 
@@ -1786,18 +1432,16 @@ representation of non-opaque pixels are irrelevant.
 You can also try this format if your software is broken;
 it might look better.
 
-    PNG_ALPHA_BROKEN: This is PNG_ALPHA_STANDARD;
-however, all component values,
-including the alpha channel are gamma encoded.  This is
-an appropriate format to try if your software, or more
-likely hardware, is totally broken, i.e., if it performs
-linear arithmetic directly on gamma encoded values.
-
-In most cases of broken software or hardware the bug in the final display
-manifests as a subtle halo around composited parts of the image.  You may not
-even perceive this as a halo; the composited part of the image may simply appear
-separate from the background, as though it had been cut out of paper and pasted
-on afterward.
+    PNG_ALPHA_BROKEN: This is PNG_ALPHA_STANDARD; however, all component
+values, including the alpha channel are gamma encoded.  This is
+broken because, in practice, no implementation that uses this choice
+correctly undoes the encoding before handling alpha composition.  Use this
+choice only if other serious errors in the software or hardware you use
+mandate it.  In most cases of broken software or hardware the bug in the
+final display manifests as a subtle halo around composited parts of the
+image.  You may not even perceive this as a halo; the composited part of
+the image may simply appear separate from the background, as though it had
+been cut out of paper and pasted on afterward.
 
 If you don't have to deal with bugs in software or hardware, or if you can fix
 them, there are three recommended ways of using png_set_alpha_mode():
@@ -1828,6 +1472,89 @@ All you can do is compose the result onto a matching output.  Since this
 mode is libpng-specific you also need to write your own composition
 software.
 
+The following are examples of calls to png_set_alpha_mode to achieve the
+required overall gamma correction and, where necessary, alpha
+premultiplication.
+
+    png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB);
+
+This is the default libpng handling of the alpha channel - it is not
+pre-multiplied into the color components.  In addition the call states
+that the output is for a sRGB system and causes all PNG files without gAMA
+chunks to be assumed to be encoded using sRGB.
+
+    png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC);
+
+In this case the output is assumed to be something like an sRGB conformant
+display preceeded by a power-law lookup table of power 1.45.  This is how
+early Mac systems behaved.
+
+    png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_GAMMA_LINEAR);
+
+This is the classic Jim Blinn approach and will work in academic
+environments where everything is done by the book.  It has the shortcoming
+of assuming that input PNG data with no gamma information is linear - this
+is unlikely to be correct unless the PNG files where generated locally.
+Most of the time the output precision will be so low as to show
+significant banding in dark areas of the image.
+
+    png_set_expand_16(pp);
+    png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_DEFAULT_sRGB);
+
+This is a somewhat more realistic Jim Blinn inspired approach.  PNG files
+are assumed to have the sRGB encoding if not marked with a gamma value and
+the output is always 16 bits per component.  This permits accurate scaling
+and processing of the data.  If you know that your input PNG files were
+generated locally you might need to replace PNG_DEFAULT_sRGB with the
+correct value for your system.
+
+    png_set_alpha_mode(pp, PNG_ALPHA_OPTIMIZED, PNG_DEFAULT_sRGB);
+
+If you just need to composite the PNG image onto an existing background
+and if you control the code that does this you can use the optimization
+setting.  In this case you just copy completely opaque pixels to the
+output.  For pixels that are not completely transparent (you just skip
+those) you do the composition math using png_composite or png_composite_16
+below then encode the resultant 8-bit or 16-bit values to match the output
+encoding.
+
+    Other cases
+
+If neither the PNG nor the standard linear encoding work for you because
+of the software or hardware you use then you have a big problem.  The PNG
+case will probably result in halos around the image.  The linear encoding
+will probably result in a washed out, too bright, image (it's actually too
+contrasty.)  Try the ALPHA_OPTIMIZED mode above - this will probably
+substantially reduce the halos.  Alternatively try:
+
+    png_set_alpha_mode(pp, PNG_ALPHA_BROKEN, PNG_DEFAULT_sRGB);
+
+This option will also reduce the halos, but there will be slight dark
+halos round the opaque parts of the image where the background is light.
+In the OPTIMIZED mode the halos will be light halos where the background
+is dark.  Take your pick - the halos are unavoidable unless you can get
+your hardware/software fixed!  (The OPTIMIZED approach is slightly
+faster.)
+
+When the default gamma of PNG files doesn't match the output gamma.
+If you have PNG files with no gamma information png_set_alpha_mode allows
+you to provide a default gamma, but it also sets the ouput gamma to the
+matching value.  If you know your PNG files have a gamma that doesn't
+match the output you can take advantage of the fact that
+png_set_alpha_mode always sets the output gamma but only sets the PNG
+default if it is not already set:
+
+    png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB);
+    png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC);
+
+The first call sets both the default and the output gamma values, the
+second call overrides the output gamma without changing the default.  This
+is easier than achieving the same effect with png_set_gamma.  You must use
+PNG_ALPHA_PNG for the first call - internal checking in png_set_alpha will
+fire if more than one call to png_set_alpha_mode and png_set_background is
+made in the same read operation, however multiple calls with PNG_ALPHA_PNG
+are ignored.
+
 If you don't need, or can't handle, the alpha channel you can call
 png_set_background() to remove it by compositing against a fixed color.  Don't
 call png_set_strip_alpha() to do this - it will leave spurious pixel values in
@@ -1935,7 +1662,7 @@ where row_pointers is an array of pointers to the pixel data for each row:
 If you know your image size and pixel size ahead of time, you can allocate
 row_pointers prior to calling png_read_png() with
 
-   if (height > PNG_UINT_32_MAX/png_sizeof(png_byte))
+   if (height > PNG_UINT_32_MAX/(sizeof (png_byte)))
       png_error (png_ptr,
           "Image is too tall to process in memory");
 
@@ -1944,7 +1671,7 @@ row_pointers prior to calling png_read_png() with
           "Image is too wide to process in memory");
 
    row_pointers = png_malloc(png_ptr,
-       height*png_sizeof(png_bytep));
+       height*(sizeof (png_bytep)));
 
    for (int i=0; i<height, i++)
       row_pointers[i]=NULL;  /* security precaution */
@@ -2106,7 +1833,11 @@ pointer into the info_ptr is returned for any complex types.
 The colorspace data from gAMA, cHRM, sRGB, iCCP, and sBIT chunks
 is simply returned to give the application information about how the
 image was encoded.  Libpng itself only does transformations using the file
-gamma when combining semitransparent pixels with the background color.
+gamma when combining semitransparent pixels with the background color, and,
+since libpng-1.6.0, when converting between 8-bit sRGB and 16-bit linear pixels
+within the simplified API.  Libpng also uses the file gamma when converting
+RGB to gray, beginning with libpng-1.0.5, if the application calls
+png_set_rgb_to_gray()).
 
     png_get_PLTE(png_ptr, info_ptr, &palette,
                      &num_palette);
@@ -2119,7 +1850,7 @@ gamma when combining semitransparent pixels with the background color.
     png_get_gAMA(png_ptr, info_ptr, &file_gamma);
     png_get_gAMA_fixed(png_ptr, info_ptr, &int_file_gamma);
 
-    file_gamma     - the gamma at which the file was
+    file_gamma     - the gamma at which the file is
                      written (PNG_INFO_gAMA)
 
     int_file_gamma - 100,000 times the gamma at which the
@@ -2127,14 +1858,17 @@ gamma when combining semitransparent pixels with the background color.
 
     png_get_cHRM(png_ptr, info_ptr,  &white_x, &white_y, &red_x,
                      &red_y, &green_x, &green_y, &blue_x, &blue_y)
-    png_get_cHRM_XYZ(png_ptr, info_ptr, &red_X, &red_Y, &red_Z, &green_X,
-                     &green_Y, &green_Z, &blue_X, &blue_Y, &blue_Z)
-    png_get_cHRM_fixed(png_ptr, info_ptr, &int_white_x, &int_white_y,
-                     &int_red_x, &int_red_y, &int_green_x, &int_green_y,
-                     &int_blue_x, &int_blue_y)
+    png_get_cHRM_XYZ(png_ptr, info_ptr, &red_X, &red_Y, &red_Z,
+                     &green_X, &green_Y, &green_Z, &blue_X, &blue_Y,
+                     &blue_Z)
+    png_get_cHRM_fixed(png_ptr, info_ptr, &int_white_x,
+                     &int_white_y, &int_red_x, &int_red_y,
+                     &int_green_x, &int_green_y, &int_blue_x,
+                     &int_blue_y)
     png_get_cHRM_XYZ_fixed(png_ptr, info_ptr, &int_red_X, &int_red_Y,
-                     &int_red_Z, &int_green_X, &int_green_Y, &int_green_Z,
-                     &int_blue_X, &int_blue_Y, &int_blue_Z)
+                     &int_red_Z, &int_green_X, &int_green_Y,
+                     &int_green_Z, &int_blue_X, &int_blue_Y,
+                     &int_blue_Z)
 
     {white,red,green,blue}_{x,y}
                      A color space encoding specified using the
@@ -2142,15 +1876,16 @@ gamma when combining semitransparent pixels with the background color.
                      white point. (PNG_INFO_cHRM)
 
     {red,green,blue}_{X,Y,Z}
-                     A color space encoding specified using the encoding end
-                     points - the CIE tristimulus specification of the intended
-                     color of the red, green and blue channels in the PNG RGB
-                     data.  The white point is simply the sum of the three end
-                     points. (PNG_INFO_cHRM)
+                     A color space encoding specified using the
+                     encoding end points - the CIE tristimulus
+                     specification of the intended color of the red,
+                     green and blue channels in the PNG RGB data.
+                     The white point is simply the sum of the three
+                     end points. (PNG_INFO_cHRM)
 
     png_get_sRGB(png_ptr, info_ptr, &srgb_intent);
 
-    file_srgb_intent - the rendering intent (PNG_INFO_sRGB)
+    srgb_intent -    the rendering intent (PNG_INFO_sRGB)
                      The presence of the sRGB chunk
                      means that the pixel data is in the
                      sRGB color space.  This chunk also
@@ -3100,10 +2835,15 @@ how pngvalid.c does it.
 .SS Finishing a sequential read
 
 After you are finished reading the image through the
-low-level interface, you can finish reading the file.  If you are
-interested in comments or time, which may be stored either before or
-after the image data, you should pass the separate png_info struct if
-you want to keep the comments from before and after the image
+low-level interface, you can finish reading the file.
+
+If you want to use a different crc action for handling CRC errors in
+chunks after the image data, you can call png_set_crc_action()
+again at this point.
+
+If you are interested in comments or time, which may be stored either
+before or after the image data, you should pass the separate png_info
+struct if you want to keep the comments from before and after the image
 separate.
 
     png_infop end_info = png_create_info_struct(png_ptr);
@@ -3119,6 +2859,9 @@ separate.
 
 If you are not interested, you should still call png_read_end()
 but you can pass NULL, avoiding the need to create an end_info structure.
+If you do this, libpng will not process any chunks after IDAT other than
+skipping over them and perhaps (depending on whether you have called
+png_set_crc_action) checking their CRCs while looking for the IEND chunk.
 
    png_read_end(png_ptr, (png_infop)NULL);
 
@@ -3153,13 +2896,13 @@ point to libpng-allocated storage with the following function:
            or simply PNG_FREE_ALL
 
     seq  - sequence number of item to be freed
-           (-1 for all items)
+           (\-1 for all items)
 
 This function may be safely called when the relevant storage has
 already been freed, or has not yet been allocated, or was allocated
 by the user and not by libpng,  and will in those cases do nothing.
 The "seq" parameter is ignored if only one item of the selected data
-type, such as PLTE, is allowed.  If "seq" is not -1, and multiple items
+type, such as PLTE, is allowed.  If "seq" is not \-1, and multiple items
 are allowed for the data type identified in the mask, such as text or
 sPLT, only the n'th item in the structure is freed, where n is "seq".
 
@@ -3223,7 +2966,7 @@ For a more compact example of reading a PNG image, see the file example.c.
 
 .SS Reading PNG files progressively
 
-The progressive reader is slightly different then the non-progressive
+The progressive reader is slightly different from the non-progressive
 reader.  Instead of calling png_read_info(), png_read_rows(), and
 png_read_end(), you make one call to png_process_data(), which calls
 callbacks when it has the info, a row, or the end of the image.  You
@@ -3394,7 +3137,7 @@ png_infop info_ptr;
         png_progressive_combine_row(png_ptr, old_row,
           new_row);
 
-    /* where old_row is what was displayed for
+    /* where old_row is what was displayed
        previously for the row.  Note that the first
        pass (pass == 0, really) will completely cover
        the old row, so the rows do not have to be
@@ -3503,6 +3246,20 @@ You can #define PNG_ABORT() to a function that does something
 more useful than abort(), as long as your function does not
 return.
 
+Checking for invalid palette index on write was added at libpng
+1.5.10.  If a pixel contains an invalid (out-of-range) index libpng issues
+a benign error.  This is enabled by default because this condition is an
+error according to the PNG specification, Clause 11.3.2, but the error can
+be ignored in each png_ptr with
+
+   png_set_check_for_invalid_index(png_ptr, 0);
+
+If the error is ignored, or if png_benign_error() treats it as a warning,
+any invalid pixels are written as-is by the encoder, resulting in an
+invalid PNG datastream as output.  In this case the application is
+responsible for ensuring that the pixel indexes are in range when it writes
+a PLTE chunk with fewer entries than the bit depth would allow.
+
 Now you need to set up the output code.  The default for libpng is to
 use the C function fwrite().  If you use this, you will need to pass a
 valid FILE * in the function png_init_io().  Be sure that the file is
@@ -3546,7 +3303,7 @@ non-interlaced case the row that was just handled is simply one less than the
 passed in row number, and pass will always be 0.  For the interlaced case the
 same applies unless the row value is 0, in which case the row just handled was
 the last one from one of the preceding passes.  Because interlacing may skip a
-pass you cannot be sure that the preceding pass is just 'pass-1', if you really
+pass you cannot be sure that the preceding pass is just 'pass\-1', if you really
 need to know what the last pass is record (row,pass) from the callback and use
 the last recorded value each time.
 
@@ -4005,18 +3762,53 @@ tEXt chunk use RFC 1123 format dates (e.g. "22 May 1997 18:07:10 GMT"),
 although this isn't a requirement.  Unlike the tIME chunk, the
 "Creation Time" tEXt chunk is not expected to be automatically changed
 by the software.  To facilitate the use of RFC 1123 dates, a function
-png_convert_to_rfc1123(png_ptr, png_timep) is provided to convert
-from PNG time to an RFC 1123 format string.
+png_convert_to_rfc1123_buffer(buffer, png_timep) is provided to
+convert from PNG time to an RFC 1123 format string.  The caller must provide
+a writeable buffer of at least 29 bytes.
 
 .SS Writing unknown chunks
 
-You can use the png_set_unknown_chunks function to queue up chunks
-for writing.  You give it a chunk name, raw data, and a size; that's
-all there is to it.  The chunks will be written by the next following
-png_write_info_before_PLTE, png_write_info, or png_write_end function.
-Any chunks previously read into the info structure's unknown-chunk
-list will also be written out in a sequence that satisfies the PNG
-specification's ordering rules.
+You can use the png_set_unknown_chunks function to queue up private chunks
+for writing.  You give it a chunk name, location, raw data, and a size.  You
+also must use png_set_keep_unknown_chunks() to ensure that libpng will
+handle them.  That's all there is to it.  The chunks will be written by the
+next following png_write_info_before_PLTE, png_write_info, or png_write_end
+function, depending upon the specified location.  Any chunks previously
+read into the info structure's unknown-chunk list will also be written out
+in a sequence that satisfies the PNG specification's ordering rules.
+
+Here is an example of writing two private chunks, prVt and miNE:
+
+    #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+    /* Set unknown chunk data */
+    png_unknown_chunk unk_chunk[2];
+    strcpy((char *) unk_chunk[0].name, "prVt";
+    unk_chunk[0].data = (unsigned char *) "PRIVATE DATA";
+    unk_chunk[0].size = strlen(unk_chunk[0].data)+1;
+    unk_chunk[0].location = PNG_HAVE_IHDR;
+    strcpy((char *) unk_chunk[1].name, "miNE";
+    unk_chunk[1].data = (unsigned char *) "MY CHUNK DATA";
+    unk_chunk[1].size = strlen(unk_chunk[0].data)+1;
+    unk_chunk[1].location = PNG_AFTER_IDAT;
+    png_set_unknown_chunks(write_ptr, write_info_ptr,
+        unk_chunk, 2);
+    /* Needed because miNE is not safe-to-copy */
+    png_set_keep_unknown_chunks(png, PNG_HANDLE_CHUNK_ALWAYS,
+       (png_bytep) "miNE", 1);
+    # if PNG_LIBPNG_VER < 10600
+      /* Deal with unknown chunk location bug in 1.5.x and earlier */
+      png_set_unknown_chunk_location(png, info, 0, PNG_HAVE_IHDR);
+      png_set_unknown_chunk_location(png, info, 1, PNG_AFTER_IDAT);
+    # endif
+    # if PNG_LIBPNG_VER < 10500
+      /* PNG_AFTER_IDAT writes two copies of the chunk prior to libpng-1.5.0,
+       * one before IDAT and another after IDAT, so don't use it; only use
+       * PNG_HAVE_IHDR location.  This call resets the location previously
+       * set by assignment and png_set_unknown_chunk_location() for chunk 1.
+       */
+      png_set_unknown_chunk_location(png, info, 1, PNG_HAVE_IHDR);
+    # endif
+    #endif
 
 .SS The high-level write interface
 
@@ -4351,13 +4143,13 @@ point to libpng-allocated storage with the following function:
             or simply PNG_FREE_ALL
 
     seq   - sequence number of item to be freed
-            (-1 for all items)
+            (\-1 for all items)
 
 This function may be safely called when the relevant storage has
 already been freed, or has not yet been allocated, or was allocated
 by the user  and not by libpng,  and will in those cases do nothing.
 The "seq" parameter is ignored if only one item of the selected data
-type, such as PLTE, is allowed.  If "seq" is not -1, and multiple items
+type, such as PLTE, is allowed.  If "seq" is not \-1, and multiple items
 are allowed for the data type identified in the mask, such as text or
 sPLT, only the n'th item in the structure is freed, where n is "seq".
 
@@ -4414,7 +4206,374 @@ if you transfer responsibility for free'ing text_ptr from libpng to your
 application, your application must not separately free those members.
 For a more compact example of writing a PNG image, see the file example.c.
 
-.SH V. Modifying/Customizing libpng:
+.SH V. Simplified API
+
+The simplified API, which became available in libpng-1.6.0, hides the details
+of both libpng and the PNG file format itself.
+It allows PNG files to be read into a very limited number of
+in-memory bitmap formats or to be written from the same formats.  If these
+formats do not accommodate your needs then you can, and should, use the more
+sophisticated APIs above - these support a wide variety of in-memory formats
+and a wide variety of sophisticated transformations to those formats as well
+as a wide variety of APIs to manipulate ancilliary information.
+
+To read a PNG file using the simplified API:
+
+  1) Declare a 'png_image' structure (see below) on the
+     stack and memset() it to all zero.
+
+  2) Call the appropriate png_image_begin_read... function.
+
+  3) Set the png_image 'format' member to the required
+     format and allocate a buffer for the image.
+
+  4) Call png_image_finish_read to read the image into
+     your buffer.
+
+There are no restrictions on the format of the PNG input itself; all valid
+color types, bit depths, and interlace methods are acceptable, and the
+input image is transformed as necessary to the requested in-memory format
+during the png_image_finish_read() step.
+
+To write a PNG file using the simplified API:
+
+  1) Declare a 'png_image' structure on the stack and memset()
+     it to all zero.
+
+  2) Initialize the members of the structure that describe the
+     image, setting the 'format' member to the format of the
+     image in memory.
+
+  3) Call the appropriate png_image_write... function with a
+     pointer to the image to write the PNG data.
+
+png_image is a structure that describes the in-memory format of an image
+when it is being read or define the in-memory format of an image that you
+need to write.  The "png_image" structure contains the following members:
+
+   png_uint_32  version Set to PNG_IMAGE_VERSION
+   png_uint_32  width   Image width in pixels (columns)
+   png_uint_32  height  Image height in pixels (rows)
+   png_uint_32  format  Image format as defined below
+   png_uint_32  flags   A bit mask containing informational flags
+   png_controlp opaque  Initialize to NULL, free with png_image_free
+   png_uint_32  colormap_entries; Number of entries in the color-map
+   png_uint_32  warning_or_error;
+   char         message[64];
+
+In the event of an error or warning the following field warning_or_error
+field will be set to a non-zero value and the 'message' field will contain
+a '\0' terminated string with the libpng error or warning message.  If both
+warnings and an error were encountered, only the error is recorded.  If there
+are multiple warnings, only the first one is recorded.
+
+The upper 30 bits of this value are reserved; the low two bits contain
+a two bit code such that a value more than 1 indicates a failure in the API
+just called:
+
+   0 - no warning or error
+   1 - warning
+   2 - error
+   3 - error preceded by warning
+
+The pixels (samples) of the image have one to four channels whose components
+have original values in the range 0 to 1.0:
+
+  1: A single gray or luminance channel (G).
+  2: A gray/luminance channel and an alpha channel (GA).
+  3: Three red, green, blue color channels (RGB).
+  4: Three color channels and an alpha channel (RGBA).
+
+The channels are encoded in one of two ways:
+
+  a) As a small integer, value 0..255, contained in a single byte.  For the
+alpha channel the original value is simply value/255.  For the color or
+luminance channels the value is encoded according to the sRGB specification
+and matches the 8-bit format expected by typical display devices.
+
+The color/gray channels are not scaled (pre-multiplied) by the alpha
+channel and are suitable for passing to color management software.
+
+  b) As a value in the range 0..65535, contained in a 2-byte integer, in
+the native byte order of the platform on which the application is running.
+All channels can be converted to the original value by dividing by 65535; all
+channels are linear.  Color channels use the RGB encoding (RGB end-points) of
+the sRGB specification.  This encoding is identified by the
+PNG_FORMAT_FLAG_LINEAR flag below.
+
+When an alpha channel is present it is expected to denote pixel coverage
+of the color or luminance channels and is returned as an associated alpha
+channel: the color/gray channels are scaled (pre-multiplied) by the alpha
+value.
+
+When a color-mapped image is used as a result of calling
+png_image_read_colormap or png_image_write_colormap the channels are encoded
+in the color-map and the descriptions above apply to the color-map entries.
+The image data is encoded as small integers, value 0..255, that index the
+entries in the color-map.  One integer (one byte) is stored for each pixel.
+
+PNG_FORMAT_*
+
+The #defines to be used in png_image::format.  Each #define identifies a
+particular layout of channel data and, if present, alpha values.  There are
+separate defines for each of the two channel encodings.
+
+A format is built up using single bit flag values.  Not all combinations are
+valid: use the bit flag values below for testing a format returned by the
+read APIs, but set formats from the derived values.
+
+When reading or writing color-mapped images the format should be set to the
+format of the entries in the color-map then png_image_{read,write}_colormap
+called to read or write the color-map and set the format correctly for the
+image data.  Do not set the PNG_FORMAT_FLAG_COLORMAP bit directly!
+
+NOTE: libpng can be built with particular features disabled, if you see
+compiler errors because the definition of one of the following flags has been
+compiled out it is because libpng does not have the required support.  It is
+possible, however, for the libpng configuration to enable the format on just
+read or just write; in that case you may see an error at run time.  You can
+guard against this by checking for the definition of:
+
+   PNG_SIMPLIFIED_{READ,WRITE}_{BGR,AFIRST}_SUPPORTED
+
+   PNG_FORMAT_FLAG_ALPHA    0x01 format with an alpha channel
+   PNG_FORMAT_FLAG_COLOR    0x02 color format: otherwise grayscale
+   PNG_FORMAT_FLAG_LINEAR   0x04 png_uint_16 channels else png_byte
+   PNG_FORMAT_FLAG_COLORMAP 0x08 libpng use only
+   PNG_FORMAT_FLAG_BGR      0x10 BGR colors, else order is RGB
+   PNG_FORMAT_FLAG_AFIRST   0x20 alpha channel comes first
+
+Supported formats are as follows.  Future versions of libpng may support more
+formats; for compatibility with older versions simply check if the format
+macro is defined using #ifdef.  These defines describe the in-memory layout
+of the components of the pixels of the image.
+
+First the single byte formats:
+
+   PNG_FORMAT_GRAY 0
+   PNG_FORMAT_GA   PNG_FORMAT_FLAG_ALPHA
+   PNG_FORMAT_AG   (PNG_FORMAT_GA|PNG_FORMAT_FLAG_AFIRST)
+   PNG_FORMAT_RGB  PNG_FORMAT_FLAG_COLOR
+   PNG_FORMAT_BGR  (PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_BGR)
+   PNG_FORMAT_RGBA (PNG_FORMAT_RGB|PNG_FORMAT_FLAG_ALPHA)
+   PNG_FORMAT_ARGB (PNG_FORMAT_RGBA|PNG_FORMAT_FLAG_AFIRST)
+   PNG_FORMAT_BGRA (PNG_FORMAT_BGR|PNG_FORMAT_FLAG_ALPHA)
+   PNG_FORMAT_ABGR (PNG_FORMAT_BGRA|PNG_FORMAT_FLAG_AFIRST)
+
+Then the linear 2-byte formats.  When naming these "Y" is used to
+indicate a luminance (gray) channel.  The component order within the pixel
+is always the same - there is no provision for swapping the order of the
+components in the linear format.  The components are 16-bit integers in
+the native byte order for your platform, and there is no provision for
+swapping the bytes to a different endian condition.
+
+   PNG_FORMAT_LINEAR_Y PNG_FORMAT_FLAG_LINEAR
+   PNG_FORMAT_LINEAR_Y_ALPHA
+      (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_ALPHA)
+   PNG_FORMAT_LINEAR_RGB
+      (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR)
+   PNG_FORMAT_LINEAR_RGB_ALPHA
+      (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR|
+      PNG_FORMAT_FLAG_ALPHA)
+
+Color-mapped formats are obtained by calling png_image_{read,write}_colormap,
+as appropriate after setting png_image::format to the format of the color-map
+to be read or written.  Applications may check the value of
+PNG_FORMAT_FLAG_COLORMAP to see if they have called the colormap API.  The
+format of the color-map may be extracted using the following macro.
+
+   PNG_FORMAT_OF_COLORMAP(fmt) ((fmt) & ~PNG_FORMAT_FLAG_COLORMAP)
+
+PNG_IMAGE macros
+
+These are convenience macros to derive information from a png_image
+structure.  The PNG_IMAGE_SAMPLE_ macros return values appropriate to the
+actual image sample values - either the entries in the color-map or the
+pixels in the image.  The PNG_IMAGE_PIXEL_ macros return corresponding values
+for the pixels and will always return 1 after a call to
+png_image_{read,write}_colormap.  The remaining macros return information
+about the rows in the image and the complete image.
+
+NOTE: All the macros that take a png_image::format parameter are compile time
+constants if the format parameter is, itself, a constant.  Therefore these
+macros can be used in array declarations and case labels where required.
+Similarly the macros are also pre-processor constants (sizeof is not used) so
+they can be used in #if tests.
+
+First the information about the samples.
+
+  PNG_IMAGE_SAMPLE_CHANNELS(fmt)
+    Returns the total number of channels in a given format: 1..4
+
+  PNG_IMAGE_SAMPLE_COMPONENT_SIZE(fmt)
+    Returns the size in bytes of a single component of a pixel or color-map
+    entry (as appropriate) in the image.
+
+  PNG_IMAGE_SAMPLE_SIZE(fmt)
+    This is the size of the sample data for one sample.  If the image is
+    color-mapped it is the size of one color-map entry (and image pixels are
+    one byte in size), otherwise it is the size of one image pixel.
+
+  PNG_IMAGE_COLORMAP_SIZE(fmt)
+   The size of the color-map required by the format; this is the size of the
+   color-map buffer passed to the png_image_{read,write}_colormap APIs, it is
+   a fixed number determined by the format so can easily be allocated on the
+   stack if necessary.
+
+#define PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(fmt)\
+   (PNG_IMAGE_SAMPLE_CHANNELS(fmt) * 256)
+   /* The maximum size of the color-map required by the format expressed in a
+    * count of components.  This can be used to compile-time allocate a
+    * color-map:
+    *
+    * png_uint_16 colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(linear_fmt)];
+    *
+    * png_byte colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(sRGB_fmt)];
+    *
+    * Alternatively, use the PNG_IMAGE_COLORMAP_SIZE macro below to use the
+    * information from one of the png_image_begin_read_ APIs and dynamically
+    * allocate the required memory.
+    */
+
+
+Corresponding information about the pixels
+
+  PNG_IMAGE_PIXEL_(test,fmt)
+
+  PNG_IMAGE_PIXEL_CHANNELS(fmt)
+   The number of separate channels (components) in a pixel; 1 for a
+   color-mapped image.
+
+  PNG_IMAGE_PIXEL_COMPONENT_SIZE(fmt)\
+   The size, in bytes, of each component in a pixel; 1 for a color-mapped
+   image.
+
+  PNG_IMAGE_PIXEL_SIZE(fmt)
+   The size, in bytes, of a complete pixel; 1 for a color-mapped image.
+
+Information about the whole row, or whole image
+
+  PNG_IMAGE_ROW_STRIDE(image)
+   Returns the total number of components in a single row of the image; this
+   is the minimum 'row stride', the minimum count of components between each
+   row.  For a color-mapped image this is the minimum number of bytes in a
+   row.
+
+   If you need the stride measured in bytes, row_stride_bytes is
+   PNG_IMAGE_ROW_STRIDE(image) * PNG_IMAGE_PIXEL_COMPONENT_SIZE(fmt)
+   plus any padding bytes that your application might need, for example
+   to start the next row on a 4-byte boundary.
+
+  PNG_IMAGE_BUFFER_SIZE(image, row_stride)
+    Returns the size, in bytes, of an image buffer given a png_image and a row
+    stride - the number of components to leave space for in each row.  This
+    macro takes care of multiplying row_stride by PNG_IMAGE_PIXEL_COMONENT_SIZE
+    when the image has 2-byte components.
+
+  PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB == 0x01
+    This indicates the the RGB values of the in-memory bitmap do not
+    correspond to the red, green and blue end-points defined by sRGB.
+
+  PNG_IMAGE_FLAG_COLORMAP == 0x02
+    The PNG is color-mapped.  If this flag is set png_image_read_colormap
+    can be used without further loss of image information.  If it is not set
+    png_image_read_colormap will cause significant loss if the image has any
+
+READ APIs
+
+   The png_image passed to the read APIs must have been initialized by setting
+   the png_controlp field 'opaque' to NULL (or, better, memset the whole thing.)
+
+   int png_image_begin_read_from_file( png_imagep image,
+     const char *file_name)
+
+     The named file is opened for read and the image header
+     is filled in from the PNG header in the file.
+
+   int png_image_begin_read_from_stdio (png_imagep image,
+     FILE* file)
+
+      The PNG header is read from the stdio FILE object.
+
+   int png_image_begin_read_from_memory(png_imagep image,
+      png_const_voidp memory, png_size_t size)
+
+      The PNG header is read from the given memory buffer.
+
+   int png_image_finish_read(png_imagep image,
+      png_colorp background, void *buffer,
+      png_int_32 row_stride, void *colormap));
+
+      Finish reading the image into the supplied buffer and
+      clean up the png_image structure.
+
+      row_stride is the step, in png_byte or png_uint_16 units
+      as appropriate, between adjacent rows.  A positive stride
+      indicates that the top-most row is first in the buffer -
+      the normal top-down arrangement.  A negative stride
+      indicates that the bottom-most row is first in the buffer.
+
+      background need only be supplied if an alpha channel must
+      be removed from a png_byte format and the removal is to be
+      done by compositing on a solid color; otherwise it may be
+      NULL and any composition will be done directly onto the
+      buffer.  The value is an sRGB color to use for the
+      background, for grayscale output the green channel is used.
+
+      For linear output removing the alpha channel is always done
+      by compositing on black.
+
+   void png_image_free(png_imagep image)
+
+      Free any data allocated by libpng in image->opaque,
+      setting the pointer to NULL.  May be called at any time
+      after the structure is initialized.
+
+When the simplified API needs to convert between sRGB and linear colorspaces,
+the actual sRGB transfer curve defined in the sRGB specification (see the
+article at http://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2
+approximation used elsewhere in libpng.
+
+WRITE APIS
+
+For write you must initialize a png_image structure to describe the image to
+be written:
+
+   version: must be set to PNG_IMAGE_VERSION
+   opaque: must be initialized to NULL
+   width: image width in pixels
+   height: image height in rows
+   format: the format of the data you wish to write
+   flags: set to 0 unless one of the defined flags applies; set
+      PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB for color format images
+      where the RGB values do not correspond to the colors in sRGB.
+   colormap_entries: set to the number of entries in the color-map (0 to 256)
+
+   int png_image_write_to_file, (png_imagep image,
+      const char *file, int convert_to_8bit, const void *buffer,
+      png_int_32 row_stride, const void *colormap));
+
+      Write the image to the named file.
+
+   int png_image_write_to_stdio(png_imagep image, FILE *file,
+      int convert_to_8_bit, const void *buffer,
+      png_int_32 row_stride, const void *colormap)
+
+      Write the image to the given (FILE*).
+
+With all write APIs if image is in one of the linear formats with
+(png_uint_16) data then setting convert_to_8_bit will cause the output to be
+a (png_byte) PNG gamma encoded according to the sRGB specification, otherwise
+a 16-bit linear encoded PNG file is written.
+
+With all APIs row_stride is handled as in the read APIs - it is the spacing
+from one row to the next in component sized units (float) and if negative
+indicates a bottom-up row layout in the buffer.
+
+Note that the write API does not support interlacing, sub-8-bit pixels,
+and indexed (paletted) images.
+
+.SH VI. Modifying/Customizing libpng
 
 There are two issues here.  The first is changing how libpng does
 standard things like memory allocation, input/output, and error handling.
@@ -4438,14 +4597,11 @@ clears the newly allocated memory to zero; note that png_calloc(png_ptr, size)
 is not the same as the calloc(number, size) function provided by stdlib.h.
 There is limited support for certain systems with segmented memory
 architectures and the types of pointers declared by png.h match this; you
-will have to use appropriate pointers in your application.  Since it is
-unlikely that the method of handling memory allocation on a platform
-will change between applications, these functions must be modified in
-the library at compile time.  If you prefer to use a different method
-of allocating and freeing data, you can use png_create_read_struct_2() or
-png_create_write_struct_2() to register your own functions as described
-above.  These functions also provide a void pointer that can be retrieved
-via
+will have to use appropriate pointers in your application.  If you prefer
+to use a different method of allocating and freeing data, you can use
+png_create_read_struct_2() or png_create_write_struct_2() to register your
+own functions as described above.  These functions also provide a void
+pointer that can be retrieved via
 
     mem_ptr=png_get_mem_ptr(png_ptr);
 
@@ -4548,6 +4704,18 @@ compiler documentation for more details.  For an alternative approach, you
 may wish to use the "cexcept" facility (see http://cexcept.sourceforge.net),
 which is illustrated in pngvalid.c and in contrib/visupng.
 
+Beginning in libpng-1.4.0, the png_set_benign_errors() API became available.
+You can use this to handle certain errors (normally handled as errors)
+as warnings.
+
+    png_set_benign_errors (png_ptr, int allowed);
+
+    allowed: 0: treat png_benign_error() as an error.
+             1: treat png_benign_error() as a warning.
+
+As of libpng-1.6.0, the default condition is to treat benign errors as
+warnings while reading and as errors while writing.
+
 .SS Custom chunks
 
 If you need to read or write custom chunks, you may need to get deeper
@@ -4576,29 +4744,6 @@ the simpler ones to get an idea of how they work.  Try to find a similar
 transformation to the one you want to add and copy off of it.  More details
 can be found in the comments inside the code itself.
 
-.SS Configuring for 16-bit platforms
-
-You will want to look into zconf.h to tell zlib (and thus libpng) that
-it cannot allocate more then 64K at a time.  Even if you can, the memory
-won't be accessible.  So limit zlib and libpng to 64K by defining MAXSEG_64K.
-
-.SS Configuring for DOS
-
-For DOS users who only have access to the lower 640K, you will
-have to limit zlib's memory usage via a png_set_compression_mem_level()
-call.  See zlib.h or zconf.h in the zlib library for more information.
-
-.SS Configuring for Medium Model
-
-Libpng's support for medium model has been tested on most of the popular
-compilers.  Make sure MAXSEG_64K gets defined, USE_FAR_KEYWORD gets
-defined, and FAR gets defined to far in pngconf.h, and you should be
-all set.  Everything in the library (except for zlib's structure) is
-expecting far data.  You must use the typedefs with the p or pp on
-the end for pointers (or at least look at them and be careful).  Make
-note that the rows of data are defined as png_bytepp, which is
-an "unsigned char far * far *".
-
 .SS Configuring for gui/windowing platforms:
 
 You will need to write new error and warning functions that use the GUI
@@ -4608,19 +4753,6 @@ in order to have them available during the structure initialization.
 They can be changed later via png_set_error_fn().  On some compilers,
 you may also have to change the memory allocators (png_malloc, etc.).
 
-.SS Configuring for compiler xxx:
-
-All includes for libpng are in pngconf.h.  If you need to add, change
-or delete an include, this is the place to do it.
-The includes that are not needed outside libpng are placed in pngpriv.h,
-which is only used by the routines inside libpng itself.
-The files in libpng proper only include pngpriv.h and png.h, which
-%14%in turn includes pngconf.h.
-in turn includes pngconf.h and, as of libpng-1.5.0, pnglibconf.h.
-As of libpng-1.5.0, pngpriv.h also includes three other private header
-files, pngstruct.h, pnginfo.h, and pngdebug.h, which contain material
-that previously appeared in the public headers.
-
 .SS Configuring zlib:
 
 There are special functions to configure the compression.  Perhaps the
@@ -4662,6 +4794,8 @@ zlib.h for more information on what these mean.
 
     png_set_compression_method(png_ptr, method);
 
+This controls the size of the IDAT chunks (default 8192):
+
     png_set_compression_buffer_size(png_ptr, size);
 
 As of libpng version 1.5.4, additional APIs became
@@ -4760,46 +4894,6 @@ Note that the numbers above were invented purely for this example and
 are given only to help explain the function usage.  Little testing has
 been done to find optimum values for either the costs or the weights.
 
-.SS Removing unwanted object code
-
-There are a bunch of #define's in pngconf.h that control what parts of
-libpng are compiled.  All the defines end in _SUPPORTED.  If you are
-never going to use a capability, you can change the #define to #undef
-before recompiling libpng and save yourself code and data space, or
-you can turn off individual capabilities with defines that begin with
-PNG_NO_.
-
-In libpng-1.5.0 and later, the #define's are in pnglibconf.h instead.
-
-You can also turn all of the transforms and ancillary chunk capabilities
-off en masse with compiler directives that define
-PNG_NO_READ[or WRITE]_TRANSFORMS, or PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS,
-or all four,
-along with directives to turn on any of the capabilities that you do
-want.  The PNG_NO_READ[or WRITE]_TRANSFORMS directives disable the extra
-transformations but still leave the library fully capable of reading
-and writing PNG files with all known public chunks. Use of the
-PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS directive produces a library
-that is incapable of reading or writing ancillary chunks.  If you are
-not using the progressive reading capability, you can turn that off
-with PNG_NO_PROGRESSIVE_READ (don't confuse this with the INTERLACING
-capability, which you'll still have).
-
-All the reading and writing specific code are in separate files, so the
-linker should only grab the files it needs.  However, if you want to
-make sure, or if you are building a stand alone library, all the
-reading files start with "pngr" and all the writing files start with "pngw".
-The files that don't match either (like png.c, pngtrans.c, etc.)
-are used for both reading and writing, and always need to be included.
-The progressive reader is in pngpread.c
-
-If you are creating or distributing a dynamically linked library (a .so
-or DLL file), you should not remove or disable any parts of the library,
-as this will cause applications linked with different versions of the
-library to fail if they call functions not available in your library.
-The size of the library itself should not be an issue, because only
-those sections that are actually used will be loaded into memory.
-
 .SS Requesting debug printout
 
 The macro definition PNG_DEBUG can be used to request debugging
@@ -4819,12 +4913,12 @@ the message, "message" is the formatted string to be printed,
 and p1 and p2 are parameters that are to be embedded in the string
 according to printf-style formatting directives.  For example,
 
-   png_debug1(2, "foo=%d\n", foo);
+   png_debug1(2, "foo=%d", foo);
 
 is expanded to
 
    if (PNG_DEBUG > 2)
-      fprintf(PNG_DEBUG_FILE, "foo=%d\n", foo);
+      fprintf(PNG_DEBUG_FILE, "foo=%d\en", foo);
 
 When PNG_DEBUG is defined but is zero, the macros aren't defined, but you
 can still use PNG_DEBUG to control your own debugging:
@@ -4837,7 +4931,7 @@ When PNG_DEBUG = 1, the macros are defined, but only png_debug statements
 having level = 0 will be printed.  There aren't any such statements in
 this version of libpng, but if you insert some they will be printed.
 
-.SH VI.  MNG support
+.SH VII.  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.
@@ -4864,7 +4958,7 @@ 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.
 
-.SH VII.  Changes to Libpng from version 0.88
+.SH VIII.  Changes to Libpng from version 0.88
 
 It should be noted that versions of libpng later than 0.96 are not
 distributed by the original libpng author, Guy Schalnat, nor by
@@ -4899,6 +4993,9 @@ png_set_error_fn(), which is essentially the same function, but with a new
 name to force compilation errors with applications that try to use the old
 method.
 
+Support for the sCAL, iCCP, iTXt, and sPLT chunks was added at libpng-1.0.6;
+however, iTXt support was not enabled by default.
+
 Starting with version 1.0.7, you can find out which version of the library
 you are using at run-time:
 
@@ -4916,7 +5013,7 @@ application:
 
    png_uint_32 application_vn = PNG_LIBPNG_VER;
 
-.SH VIII.  Changes to Libpng from version 1.0.x to 1.2.x
+.SH IX.  Changes to Libpng from version 1.0.x to 1.2.x
 
 Support for user memory management was enabled by default.  To
 accomplish this, the functions png_create_read_struct_2(),
@@ -5013,7 +5110,7 @@ which also expands tRNS to alpha was replaced with
     png_set_expand_gray_1_2_4_to_8()
 which does not. It has been deprecated since libpng-1.0.18 and 1.2.9.
 
-.SH IX.  Changes to Libpng from version 1.0.x/1.2.x to 1.4.x
+.SH X.  Changes to Libpng from version 1.0.x/1.2.x to 1.4.x
 
 Private libpng prototypes and macro definitions were moved from
 png.h and pngconf.h into a new pngpriv.h header file.
@@ -5068,8 +5165,8 @@ png_get_mmx_bitdepth_threshold(), png_get_mmx_rowbytes_threshold(),
 png_set_asm_flags(), and png_mmx_supported()
 
 We removed the obsolete png_check_sig(), png_memcpy_check(), and
-png_memset_check() functions.  Instead use !png_sig_cmp(), png_memcpy(),
-and png_memset(), respectively.
+png_memset_check() functions.  Instead use !png_sig_cmp(), memcpy(),
+and memset(), respectively.
 
 The function png_set_gray_1_2_4_to_8() was removed. It has been
 deprecated since libpng-1.0.18 and 1.2.9, when it was replaced with
@@ -5115,7 +5212,7 @@ it has not been well tested and doesn't actually "dither".
 The code was not
 removed, however, and could be enabled by building libpng with
 PNG_READ_DITHER_SUPPORTED defined.  In libpng-1.4.2, this support
-was reenabled, but the function was renamed png_set_quantize() to
+was re-enabled, but the function was renamed png_set_quantize() to
 reflect more accurately what it actually does.  At the same time,
 the PNG_DITHER_[RED,GREEN_BLUE]_BITS macros were also renamed to
 PNG_QUANTIZE_[RED,GREEN,BLUE]_BITS, and PNG_READ_DITHER_SUPPORTED
@@ -5123,22 +5220,42 @@ was renamed to PNG_READ_QUANTIZE_SUPPORTED.
 
 We removed the trailing '.' from the warning and error messages.
 
-.SH X.  Changes to Libpng from version 1.4.x to 1.5.x
+.SH XI.  Changes to Libpng from version 1.4.x to 1.5.x
 
 From libpng-1.4.0 until 1.4.4, the png_get_uint_16 macro (but not the
 function) incorrectly returned a value of type png_uint_32.
+The incorrect macro was removed from libpng-1.4.5.
 
-Checking for invalid palette index on read or write was added at libpng
-1.5.10.  When an invalid index is found, libpng issues a benign error.
-This is enabled by default but can be disabled in each png_ptr with
+Checking for invalid palette index on write was added at libpng
+1.5.10.  If a pixel contains an invalid (out-of-range) index libpng issues
+a benign error.  This is enabled by default because this condition is an
+error according to the PNG specification, Clause 11.3.2, but the error can
+be ignored in each png_ptr with
 
    png_set_check_for_invalid_index(png_ptr, allowed);
 
       allowed  - one of
-                 0: disable
-                 1: enable
+                 0: disable benign error (accept the
+                    invalid data without warning).
+                 1: enable benign error (treat the
+                    invalid data as an error or a
+                    warning).
 
-A. Changes that affect users of libpng
+If the error is ignored, or if png_benign_error() treats it as a warning,
+any invalid pixels are decoded as opaque black by the decoder and written
+as-is by the encoder.
+
+Retrieving the maximum palette index found was added at libpng-1.5.15.
+This statement must appear after png_read_png() or png_read_image() while
+reading, and after png_write_png() or png_write_image() while writing.
+
+   int max_palette = png_get_palette_max(png_ptr, info_ptr);
+
+This will return the maximum palette index found in the image, or "\-1" if
+the palette was not checked, or "0" if no palette was found.  Note that this
+does not account for any palette index used by ancillary chunks such as the
+bKGD chunk; you must check those separately to determine the maximum
+palette index actually used.
 
 There are no substantial API changes between the non-deprecated parts of
 the 1.4.5 API and the 1.5.0 API; however, the ability to directly access
@@ -5146,9 +5263,10 @@ members of the main libpng control structures, png_struct and png_info,
 deprecated in earlier versions of libpng, has been completely removed from
 libpng 1.5.
 
-We no longer include zlib.h in png.h.  Applications that need access
-to information in zlib.h will need to add the '#include "zlib.h"'
-directive.  It does not matter whether it is placed prior to or after
+We no longer include zlib.h in png.h.  The include statement has been moved
+to pngstruct.h, where it is not accessible by applications. Applications that
+need access to information in zlib.h will need to add the '#include "zlib.h"'
+directive.  It does not matter whether this is placed prior to or after
 the '"#include png.h"' directive.
 
 The png_sprintf(), png_strcpy(), and png_strncpy() macros are no longer used
@@ -5209,7 +5327,10 @@ and the accuracy of PNG fixed point values is insufficient for
 representation of these values. Consequently a "string" API
 (png_get_sCAL_s and png_set_sCAL_s) is the only reliable way of reading
 arbitrary sCAL chunks in the absence of either the floating point API or
-internal floating point calculations.
+internal floating point calculations.  Starting with libpng-1.5.0, both
+of these functions are present when PNG_sCAL_SUPPORTED is defined.  Prior
+to libpng-1.5.0, their presence also depended upon PNG_FIXED_POINT_SUPPORTED
+being defined and PNG_FLOATING_POINT_SUPPORTED not being defined.
 
 Applications no longer need to include the optional distribution header
 file pngusr.h or define the corresponding macros during application
@@ -5229,15 +5350,10 @@ reset by pngusr.h or by explicit settings on the compiler command line.
 These settings may produce compiler warnings or errors in 1.5.0 because
 of macro redefinition.
 
-From libpng-1.4.0 until 1.4.4, the png_get_uint_16 macro (but not the
-function) incorrectly returned a value of type png_uint_32.  libpng 1.5.0
-is consistent with the implementation in 1.4.5 and 1.2.x (where the macro
-did not exist.)
-
 Applications can now choose whether to use these macros or to call the
 corresponding function by defining PNG_USE_READ_MACROS or
 PNG_NO_USE_READ_MACROS before including png.h.  Notice that this is
-only supported from 1.5.0 -defining PNG_NO_USE_READ_MACROS prior to 1.5.0
+only supported from 1.5.0; defining PNG_NO_USE_READ_MACROS prior to 1.5.0
 will lead to a link failure.
 
 Prior to libpng-1.5.4, the zlib compressor used the same set of parameters
@@ -5251,7 +5367,10 @@ option was off by default, and slightly inaccurate scaling occurred.
 This option can no longer be turned off, and the choice of accurate
 or inaccurate 16-to-8 scaling is by using the new png_set_scale_16_to_8()
 API for accurate scaling or the old png_set_strip_16_to_8() API for simple
-chopping.
+chopping.  In libpng-1.5.4, the PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED
+macro became PNG_READ_SCALE_16_TO_8_SUPPORTED, and the PNG_READ_16_TO_8
+macro became PNG_READ_STRIP_16_TO_8_SUPPORTED, to enable the two
+png_set_*_16_to_8() functions separately.
 
 Prior to libpng-1.5.4, the png_set_user_limits() function could only be
 used to reduce the width and height limits from the value of
@@ -5273,25 +5392,8 @@ limits are now
    png_user_chunk_cache_max  0 (unlimited)   128
    png_user_chunk_malloc_max 0 (unlimited) 8,000,000
 
-B. Changes to the build and configuration of libpng
-
-Details of internal changes to the library code can be found in the CHANGES
-file and in the GIT repository logs.  These will be of no concern to the vast
-majority of library users or builders; however, the few who configure libpng
-to a non-default feature set may need to change how this is done.
-
-There should be no need for library builders to alter build scripts if
-these use the distributed build support - configure or the makefiles -
-however, users of the makefiles may care to update their build scripts
-to build pnglibconf.h where the corresponding makefile does not do so.
-
-Building libpng with a non-default configuration has changed completely.
-The old method using pngusr.h should still work correctly even though the
-way pngusr.h is used in the build has been changed; however, library
-builders will probably want to examine the changes to take advantage of
-new capabilities and to simplify their build system.
-
-B.1 Specific changes to library configuration capabilities
+The png_set_option() function (and the "options" member of the png struct) was
+added to libpng-1.5.15.
 
 The library now supports a complete fixed point implementation and can
 thus be used on systems that have no floating point support or very
@@ -5303,27 +5405,7 @@ independent of the choice of fixed versus floating point APIs and all the
 missing fixed point APIs have been implemented.
 
 The exact mechanism used to control attributes of API functions has
-changed.  A single set of operating system independent macro definitions
-is used and operating system specific directives are defined in
-pnglibconf.h
-
-As part of this the mechanism used to choose procedure call standards on
-those systems that allow a choice has been changed.  At present this only
-affects certain Microsoft (DOS, Windows) and IBM (OS/2) operating systems
-running on Intel processors.  As before, PNGAPI is defined where required
-to control the exported API functions; however, two new macros, PNGCBAPI
-and PNGCAPI, are used instead for callback functions (PNGCBAPI) and
-(PNGCAPI) for functions that must match a C library prototype (currently
-only png_longjmp_ptr, which must match the C longjmp function.)  The new
-approach is documented in pngconf.h
-
-Despite these changes, libpng 1.5.0 only supports the native C function
-calling standard on those platforms tested so far (__cdecl on Microsoft
-Windows).  This is because the support requirements for alternative
-calling conventions seem to no longer exist.  Developers who find it
-necessary to set PNG_API_RULE to 1 should advise the mailing list
-(png-mng-implement) of this and library builders who use Openwatcom and
-therefore set PNG_API_RULE to 2 should also contact the mailing list.
+changed, as described in the INSTALL file.
 
 A new test program, pngvalid, is provided in addition to pngtest.
 pngvalid validates the arithmetic accuracy of the gamma correction
@@ -5399,47 +5481,134 @@ even though the default is to use the macros - this allows applications
 to choose at app buildtime whether or not to use macros (previously
 impossible because the functions weren't in the default build.)
 
-B.2 Changes to the configuration mechanism
-
-Prior to libpng-1.5.0 library builders who needed to configure libpng
-had either to modify the exported pngconf.h header file to add system
-specific configuration or had to write feature selection macros into
-pngusr.h and cause this to be included into pngconf.h by defining
-PNG_USER_CONFIG. The latter mechanism had the disadvantage that an
-application built without PNG_USER_CONFIG defined would see the
-unmodified, default, libpng API and thus would probably fail to link.
-
-These mechanisms still work in the configure build and in any makefile
-build that builds pnglibconf.h, although the feature selection macros
-have changed somewhat as described above.  In 1.5.0, however, pngusr.h is
-processed only once, when the exported header file pnglibconf.h is built.
-pngconf.h no longer includes pngusr.h, therefore pngusr.h is ignored after the
-build of pnglibconf.h and it is never included in an application build.
-
-The rarely used alternative of adding a list of feature macros to the
-CFLAGS setting in the build also still works; however, the macros will be
-copied to pnglibconf.h and this may produce macro redefinition warnings
-when the individual C files are compiled.
-
-All configuration now only works if pnglibconf.h is built from
-scripts/pnglibconf.dfa.  This requires the program awk.  Brian Kernighan
-(the original author of awk) maintains C source code of that awk and this
-and all known later implementations (often called by subtly different
-names - nawk and gawk for example) are adequate to build pnglibconf.h.
-The Sun Microsystems (now Oracle) program 'awk' is an earlier version
-and does not work; this may also apply to other systems that have a
-functioning awk called 'nawk'.
-
-Configuration options are now documented in scripts/pnglibconf.dfa.  This
-file also includes dependency information that ensures a configuration is
-consistent; that is, if a feature is switched off dependent features are
-also removed.  As a recommended alternative to using feature macros in
-pngusr.h a system builder may also define equivalent options in pngusr.dfa
-(or, indeed, any file) and add that to the configuration by setting
-DFA_XTRA to the file name.  The makefiles in contrib/pngminim illustrate
-how to do this, and a case where pngusr.h is still required.
-
-.SH XI. Detecting libpng
+.SH XII.  Changes to Libpng from version 1.5.x to 1.6.x
+
+A "simplified API" has been added (see documentation in png.h and a simple
+example in contrib/examples/pngtopng.c).  The new publicly visible API
+includes the following:
+
+   macros:
+     PNG_FORMAT_*
+     PNG_IMAGE_*
+   structures:
+     png_control
+     png_image
+   read functions
+     png_image_begin_read_from_file()
+     png_image_begin_read_from_stdio()
+     png_image_begin_read_from_memory()
+     png_image_finish_read()
+     png_image_free()
+   write functions
+     png_image_write_to_file()
+     png_image_write_to_stdio()
+
+Starting with libpng-1.6.0, you can configure libpng to prefix all exported
+symbols, using the PNG_PREFIX macro.
+
+We no longer include string.h in png.h.  The include statement has been moved
+to pngpriv.h, where it is not accessible by applications.  Applications that
+need access to information in string.h must add an '#include <string.h>'
+directive.  It does not matter whether this is placed prior to or after
+the '#include "png.h"' directive.
+
+The following API are now DEPRECATED:
+   png_info_init_3()
+   png_convert_to_rfc1123() which has been replaced
+     with png_convert_to_rfc1123_buffer()
+   png_malloc_default()
+   png_free_default()
+   png_reset_zstream()
+
+The following have been removed:
+   png_get_io_chunk_name(), which has been replaced
+     with png_get_io_chunk_type().  The new
+     function returns a 32-bit integer instead of
+     a string.
+   The png_sizeof(), png_strlen(), png_memcpy(), png_memcmp(), and
+     png_memset() macros are no longer used in the libpng sources and
+     have been removed.  These had already been made invisible to applications
+     (i.e., defined in the private pngpriv.h header file) since libpng-1.5.0.
+
+The signatures of many exported functions were changed, such that
+   png_structp became png_structrp or png_const_structrp
+   png_infop became png_inforp or png_const_inforp
+where "rp" indicates a "restricted pointer".
+
+Error detection in some chunks has improved; in particular the iCCP chunk
+reader now does pretty complete validation of the basic format.  Some bad
+profiles that were previously accepted are now accepted with a warning or
+rejected, depending upon the png_set_benign_errors() setting, in particular
+the very old broken Microsoft/HP 3144-byte sRGB profile.  Starting with
+libpng-1.6.11, recognizing and checking sRGB profiles can be avoided by
+means of
+
+    #if defined(PNG_SKIP_sRGB_CHECK_PROFILE) && \
+        defined(PNG_SET_OPTION_SUPPORTED)
+       png_set_option(png_ptr, PNG_SKIP_sRGB_CHECK_PROFILE,
+           PNG_OPTION_ON);
+    #endif
+
+It's not a good idea to do this if you are using the new "simplified API",
+which needs to be able to recognize sRGB profiles conveyed via the iCCP
+chunk.
+
+The PNG spec requirement that only grayscale profiles may appear in images
+with color type 0 or 4 and that even if the image only contains gray pixels,
+only RGB profiles may appear in images with color type 2, 3, or 6, is now
+enforced.  The sRGB chunk is allowed to appear in images with any color type
+and is interpreted by libpng to convey a one-tracer-curve gray profile or a
+three-tracer-curve RGB profile as appropriate.
+
+Prior to libpng-1.6.0 a warning would be issued if the iTXt chunk contained
+an empty language field or an empty translated keyword.  Both of these
+are allowed by the PNG specification, so these warnings are no longer issued.
+
+The library now issues an error if the application attempts to set a
+transform after it calls png_read_update_info() or if it attempts to call
+both png_read_update_info() and png_start_read_image() or to call either
+of them more than once.
+
+The default condition for benign_errors is now to treat benign errors as
+warnings while reading and as errors while writing.
+
+The library now issues a warning if both background processing and RGB to
+gray are used when gamma correction happens. As with previous versions of
+the library the results are numerically very incorrect in this case.
+
+There are some minor arithmetic changes in some transforms such as
+png_set_background(), that might be detected by certain regression tests.
+
+Unknown chunk handling has been improved internally, without any API change.
+This adds more correct option control of the unknown handling, corrects
+a pre-existing bug where the per-chunk 'keep' setting is ignored, and makes
+it possible to skip IDAT chunks in the sequential reader.
+
+The machine-generated configure files are no longer included in branches
+libpng16 and later of the GIT repository.  They continue to be included
+in the tarball releases, however.
+
+Libpng-1.6.0 through 1.6.2 used the CMF bytes at the beginning of the IDAT
+stream to set the size of the sliding window for reading instead of using the
+default 32-kbyte sliding window size.  It was discovered that there are
+hundreds of PNG files in the wild that have incorrect CMF bytes that caused
+zlib to issue the "invalid distance too far back" error and reject the file.
+Libpng-1.6.3 and later calculate their own safe CMF from the image dimensions,
+provide a way to revert to the libpng-1.5.x behavior (ignoring the CMF bytes
+and using a 32-kbyte sliding window), by using
+
+    png_set_option(png_ptr, PNG_MAXIMUM_INFLATE_WINDOW,
+        PNG_OPTION_ON);
+
+and provide a tool (contrib/tools/pngfix) for rewriting a PNG file while
+optimizing the CMF bytes in its IDAT chunk correctly.
+
+Libpng-1.6.0 and libpng-1.6.1 wrote uncompressed iTXt chunks with the wrong
+length, which resulted in PNG files that cannot be read beyond the bad iTXt
+chunk.  This error was fixed in libpng-1.6.3, and a tool (called
+contrib/tools/png-fix-itxt) has been added to the libpng distribution.
+
+.SH XIII.  Detecting libpng
 
 The png_get_io_ptr() function has been present since libpng-0.88, has never
 changed, and is unaffected by conditional compilation macros.  It is the
@@ -5448,18 +5617,18 @@ libpng version since 0.88.  In an autoconf "configure.in" you could use
 
     AC_CHECK_LIB(png, png_get_io_ptr, ...
 
-.SH XII. Source code repository
+.SH XV. Source code repository
 
 Since about February 2009, version 1.2.34, libpng has been under "git" source
 control.  The git repository was built from old libpng-x.y.z.tar.gz files
 going back to version 0.70.  You can access the git repository (read only)
 at
 
-    git://libpng.git.sourceforge.net/gitroot/libpng
+    git://git.code.sf.net/p/libpng/code
 
-or you can browse it via "gitweb" at
+or you can browse it with a web browser by selecting the "code" button at
 
-    http://libpng.git.sourceforge.net/git/gitweb.cgi?p=libpng
+    https://sourceforge.net/projects/libpng
 
 Patches can be sent to glennrp at users.sourceforge.net or to
 png-mng-implement at lists.sourceforge.net or you can upload them to
@@ -5472,9 +5641,10 @@ simple verbal discriptions of bug fixes, reported either to the
 SourceForge bug tracker, to the png-mng-implement at lists.sf.net
 mailing list, or directly to glennrp.
 
-.SH XIII. Coding style
+.SH XV. Coding style
 
-Our coding style is similar to the "Allman" style, with curly
+Our coding style is similar to the "Allman" style
+(See http://en.wikipedia.org/wiki/Indent_style#Allman_style), with curly
 braces on separate lines:
 
     if (condition)
@@ -5537,6 +5707,9 @@ exported functions are marked with PNGAPI:
     body;
  }
 
+The return type and decorations are placed on a separate line
+ahead of the function name, as illustrated above.
+
 The prototypes for all exported functions appear in png.h,
 above the comment that says
 
@@ -5551,17 +5724,29 @@ We mark all non-exported functions with "/* PRIVATE */"":
  }
 
 The prototypes for non-exported functions (except for those in
-pngtest) appear in
-pngpriv.h
-above the comment that says
+pngtest) appear in pngpriv.h above the comment that says
 
-  /* Maintainer: Put new private prototypes here ^ and in libpngpf.3 */
+  /* Maintainer: Put new private prototypes here ^ */
 
 To avoid polluting the global namespace, the names of all exported
 functions and variables begin with "png_", and all publicly visible C
 preprocessor macros begin with "PNG".  We request that applications that
 use libpng *not* begin any of their own symbols with either of these strings.
 
+We put a space after the "sizeof" operator and we omit the
+optional parentheses around its argument when the argument
+is an expression, not a type name, and we always enclose the
+sizeof operator, with its argument, in parentheses:
+
+  (sizeof (png_uint_32))
+  (sizeof array)
+
+Prior to libpng-1.6.0 we used a "png_sizeof()" macro, formatted as
+though it were a function.
+
+Control keywords if, for, while, and switch are always followed by a space
+to distinguish them from function calls, which have no trailing space. 
+
 We put a space after each comma and after each semicolon
 in "for" statements, and we put spaces before and after each
 C binary operator and after "for" or "while", and before
@@ -5569,47 +5754,55 @@ C binary operator and after "for" or "while", and before
 being cast, nor do we put one between a function name and the
 left parenthesis that follows it:
 
-    for (i = 2; i > 0; --i)
+    for (i = 2; i > 0; \-\-i)
        y[i] = a(x) + (int)b;
 
-We prefer #ifdef and #ifndef to #if defined() and if !defined()
-when there is only one macro being tested.
+We prefer #ifdef and #ifndef to #if defined() and #if !defined()
+when there is only one macro being tested.  We always use parentheses
+with "defined".
 
 We prefer to express integers that are used as bit masks in hex format,
 with an even number of lower-case hex digits (e.g., 0x00, 0xff, 0x0100).
 
+We prefer to use underscores in variable names rather than camelCase, except
+for a few type names that we inherit from zlib.h.
+
+We prefer "if (something != 0)" and "if (something == 0)"
+over "if (something)" and if "(!something)", respectively.
+
 We do not use the TAB character for indentation in the C sources.
 
 Lines do not exceed 80 characters.
 
 Other rules can be inferred by inspecting the libpng source.
 
-.SH XIV. Y2K Compliance in libpng
+.SH XVI. Y2K Compliance in libpng
 
-September 27, 2012
+December 22, 2014
 
 Since the PNG Development group is an ad-hoc body, we can't make
 an official declaration.
 
 This is your unofficial assurance that libpng from version 0.71 and
-upward through 1.5.13 are Y2K compliant.  It is my belief that earlier
+upward through 1.6.16 are Y2K compliant.  It is my belief that earlier
 versions were also Y2K compliant.
 
-Libpng only has two year fields.  One is a 2-byte unsigned integer that
-will hold years up to 65535.  The other holds the date in text
-format, and will hold years up to 9999.
+Libpng only has two year fields.  One is a 2-byte unsigned integer
+that will hold years up to 65535.  The other, which is deprecated,
+holds the date in text format, and will hold years up to 9999.
 
 The integer is
     "png_uint_16 year" in png_time_struct.
 
 The string is
-    "char time_buffer[29]" in png_struct.  This will no
-longer be used in libpng-1.6.x and will be removed from libpng-1.7.0.
+    "char time_buffer[29]" in png_struct.  This is no longer used
+in libpng-1.6.x and will be removed from libpng-1.7.0.
 
 There are seven time-related functions:
 
-    png_convert_to_rfc_1123() in png.c
-      (formerly png_convert_to_rfc_1152() in error)
+    png_convert_to_rfc_1123_buffer() in png.c
+      (formerly png_convert_to_rfc_1152() in error, and
+      also formerly png_convert_to_rfc_1123())
     png_convert_from_struct_tm() in pngwrite.c, called
       in pngwrite.c
     png_convert_from_time_t() in pngwrite.c
@@ -5797,21 +5990,52 @@ the first widely used release:
  1.5.7beta01-05      15    10507  15.so.15.7[.0]
  1.5.7rc01-03        15    10507  15.so.15.7[.0]
  1.5.7               15    10507  15.so.15.7[.0]
- 1.5.8beta01         15    10508  15.so.15.8[.0]
- 1.5.8rc01           15    10508  15.so.15.8[.0]
- 1.5.8               15    10508  15.so.15.8[.0]
- 1.5.9beta01-02      15    10509  15.so.15.9[.0]
- 1.5.9rc01           15    10509  15.so.15.9[.0]
- 1.5.9               15    10509  15.so.15.9[.0]
- 1.5.10beta01-05     15    10510  15.so.15.10[.0]
- 1.5.10              15    10510  15.so.15.10[.0]
- 1.5.11beta01        15    10511  15.so.15.11[.0]
- 1.5.11rc01-05       15    10511  15.so.15.11[.0]
- 1.5.11              15    10511  15.so.15.11[.0]
- 1.5.12              15    10512  15.so.15.12[.0]
- 1.5.13beta01-02     15    10513  15.so.15.13[.0]
- 1.5.13rc01          15    10513  15.so.15.13[.0]
- 1.5.13              15    10513  15.so.15.13[.0]
+ 1.6.0beta01-40      16    10600  16.so.16.0[.0]
+ 1.6.0rc01-08        16    10600  16.so.16.0[.0]
+ 1.6.0               16    10600  16.so.16.0[.0]
+ 1.6.1beta01-09      16    10601  16.so.16.1[.0]
+ 1.6.1rc01           16    10601  16.so.16.1[.0]
+ 1.6.1               16    10601  16.so.16.1[.0]
+ 1.6.2beta01         16    10602  16.so.16.2[.0]
+ 1.6.2rc01-06        16    10602  16.so.16.2[.0]
+ 1.6.2               16    10602  16.so.16.2[.0]
+ 1.6.3beta01-11      16    10603  16.so.16.3[.0]
+ 1.6.3rc01           16    10603  16.so.16.3[.0]
+ 1.6.3               16    10603  16.so.16.3[.0]
+ 1.6.4beta01-02      16    10604  16.so.16.4[.0]
+ 1.6.4rc01           16    10604  16.so.16.4[.0]
+ 1.6.4               16    10604  16.so.16.4[.0]
+ 1.6.5               16    10605  16.so.16.5[.0]
+ 1.6.6               16    10606  16.so.16.6[.0]
+ 1.6.7beta01-04      16    10607  16.so.16.7[.0]
+ 1.6.7rc01-02        16    10607  16.so.16.7[.0]
+ 1.6.7               16    10607  16.so.16.7[.0]
+ 1.6.8beta01-02      16    10608  16.so.16.8[.0]
+ 1.6.8rc01-02        16    10608  16.so.16.8[.0]
+ 1.6.8               16    10608  16.so.16.8[.0]
+ 1.6.9beta01-04      16    10609  16.so.16.9[.0]
+ 1.6.9rc01-02        16    10609  16.so.16.9[.0]
+ 1.6.9               16    10609  16.so.16.9[.0]
+ 1.6.10beta01-03     16    10610  16.so.16.10[.0]
+ 1.6.10rc01-03       16    10610  16.so.16.10[.0]
+ 1.6.10              16    10610  16.so.16.10[.0]
+ 1.6.11beta01-06     16    10611  16.so.16.11[.0]
+ 1.6.11rc01-02       16    10611  16.so.16.11[.0]
+ 1.6.11              16    10611  16.so.16.11[.0]
+ 1.6.12rc01          16    10612  16.so.16.12[.0]
+ 1.6.12              16    10612  16.so.16.12[.0]
+ 1.6.13beta01-04     16    10613  16.so.16.13[.0]
+ 1.6.13rc01-02       16    10613  16.so.16.13[.0]
+ 1.6.13              16    10613  16.so.16.13[.0]
+ 1.6.14beta01-07     16    10614  16.so.16.14[.0]
+ 1.6.14rc01-02       16    10614  16.so.16.14[.0]
+ 1.6.14              16    10614  16.so.16.14[.0]
+ 1.6.15beta01-08     16    10615  16.so.16.15[.0]
+ 1.6.15rc01-03       16    10615  16.so.16.15[.0]
+ 1.6.15              16    10615  16.so.16.15[.0]
+ 1.6.16beta01-03     16    10616  16.so.16.16[.0]
+ 1.6.16rc01-02       16    10616  16.so.16.16[.0]
+ 1.6.16              16    10616  16.so.16.16[.0]
 
 Henceforth the source version will match the shared-library minor
 and patch numbers; the shared-library major version number will be
@@ -5868,7 +6092,7 @@ possible without all of you.
 
 Thanks to Frank J. T. Wojcik for helping with the documentation.
 
-Libpng version 1.5.13 - September 27, 2012:
+Libpng version 1.6.16 - December 22, 2014:
 Initially created in 1995 by Guy Eric Schalnat, then of Group 42, Inc.
 Currently maintained by Glenn Randers-Pehrson (glennrp at users.sourceforge.net).
 
@@ -5891,8 +6115,8 @@ this sentence.
 
 This code is released under the libpng license.
 
-libpng versions 1.2.6, August 15, 2004, through 1.5.13, September 27, 2012, are
-Copyright (c) 2004,2006-2007 Glenn Randers-Pehrson, and are
+libpng versions 1.2.6, August 15, 2004, through 1.6.16, December 22, 2014, are
+Copyright (c) 2004,2006-2014 Glenn Randers-Pehrson, and are
 distributed according to the same disclaimer and license as libpng-1.2.5
 with the following individual added to the list of Contributing Authors
 
@@ -5990,7 +6214,7 @@ certification mark of the Open Source Initiative.
 
 Glenn Randers-Pehrson
 glennrp at users.sourceforge.net
-September 27, 2012
+December 22, 2014
 
 .\" end of man page
 
diff --git a/Source/LibPNG/libpngpf.3 b/Source/LibPNG/libpngpf.3
index f6b62a0..ec1d12b 100644
--- a/Source/LibPNG/libpngpf.3
+++ b/Source/LibPNG/libpngpf.3
@@ -1,26 +1,16 @@
-.TH LIBPNGPF 3 "September 27, 2012"
+.TH LIBPNGPF 3 "December 22, 2014"
 .SH NAME
-libpng \- Portable Network Graphics (PNG) Reference Library 1.5.13
+libpng \- Portable Network Graphics (PNG) Reference Library 1.6.16
 (private functions)
 .SH SYNOPSIS
 \fB#include \fI"pngpriv.h"
 
-\fI\fB
-
-\fBAs of libpng version \fP\fI1.5.1\fP\fB, this section is no longer \fP\fImaintained\fP\fB, now \fIthat
-
-\fBthe private function prototypes are hidden in pngpriv.h and not \fIaccessible
-
-\fBto applications. Look in pngpriv.h for the prototypes and a short \fIdescription
-
-\fBof each \fIfunction.
-
-\fI\fB
+\fBAs of libpng version \fP\fI1.5.1\fP\fB, this section is no longer \fP\fImaintained\fP\fB, now that the private function prototypes are hidden in pngpriv.h and not accessible to applications. Look in pngpriv.h for the prototypes and a short description of each \fIfunction.
 
 .SH DESCRIPTION
-The functions previously listed here are used privately by libpng
-and are not recommended for use by applications.  They are
-not "exported" to applications using shared libraries.
+The functions previously listed here are used privately by libpng and are not
+available for use by applications.  They are not "exported" to applications
+using shared libraries.
 
 .SH SEE ALSO
 .BR "png"(5), " libpng"(3), " zlib"(3), " deflate"(5), " " and " zlib"(5)
diff --git a/Source/LibPNG/png.5 b/Source/LibPNG/png.5
index cfd109f..879b3f7 100644
--- a/Source/LibPNG/png.5
+++ b/Source/LibPNG/png.5
@@ -1,4 +1,4 @@
-.TH PNG 5 "September 27, 2012"
+.TH PNG 5 "December 22, 2014"
 .SH NAME
 png \- Portable Network Graphics (PNG) format
 .SH DESCRIPTION
diff --git a/Source/LibPNG/png.c b/Source/LibPNG/png.c
index 55fbc8f..4d93dfa 100644
--- a/Source/LibPNG/png.c
+++ b/Source/LibPNG/png.c
@@ -1,2874 +1,4493 @@
-
-/* png.c - location for general purpose libpng functions
- *
- * Last changed in libpng 1.5.11 [June 14, 2012]
- * Copyright (c) 1998-2012 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- */
-
-#include "pngpriv.h"
-
-/* Generate a compiler error if there is an old png.h in the search path. */
-typedef png_libpng_version_1_5_13 Your_png_h_is_not_version_1_5_13;
-
-/* Tells libpng that we have already handled the first "num_bytes" bytes
- * of the PNG file signature.  If the PNG data is embedded into another
- * stream we can set num_bytes = 8 so that libpng will not attempt to read
- * or write any of the magic bytes before it starts on the IHDR.
- */
-
-#ifdef PNG_READ_SUPPORTED
-void PNGAPI
-png_set_sig_bytes(png_structp png_ptr, int num_bytes)
-{
-   png_debug(1, "in png_set_sig_bytes");
-
-   if (png_ptr == NULL)
-      return;
-
-   if (num_bytes > 8)
-      png_error(png_ptr, "Too many bytes for PNG signature");
-
-   png_ptr->sig_bytes = (png_byte)(num_bytes < 0 ? 0 : num_bytes);
-}
-
-/* Checks whether the supplied bytes match the PNG signature.  We allow
- * checking less than the full 8-byte signature so that those apps that
- * already read the first few bytes of a file to determine the file type
- * can simply check the remaining bytes for extra assurance.  Returns
- * an integer less than, equal to, or greater than zero if sig is found,
- * respectively, to be less than, to match, or be greater than the correct
- * PNG signature (this is the same behavior as strcmp, memcmp, etc).
- */
-int PNGAPI
-png_sig_cmp(png_const_bytep sig, png_size_t start, png_size_t num_to_check)
-{
-   png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
-
-   if (num_to_check > 8)
-      num_to_check = 8;
-
-   else if (num_to_check < 1)
-      return (-1);
-
-   if (start > 7)
-      return (-1);
-
-   if (start + num_to_check > 8)
-      num_to_check = 8 - start;
-
-   return ((int)(png_memcmp(&sig[start], &png_signature[start], num_to_check)));
-}
-
-#endif /* PNG_READ_SUPPORTED */
-
-#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
-/* Function to allocate memory for zlib */
-PNG_FUNCTION(voidpf /* PRIVATE */,
-png_zalloc,(voidpf png_ptr, uInt items, uInt size),PNG_ALLOCATED)
-{
-   png_voidp ptr;
-   png_structp p=(png_structp)png_ptr;
-   png_uint_32 save_flags=p->flags;
-   png_alloc_size_t num_bytes;
-
-   if (png_ptr == NULL)
-      return (NULL);
-
-   if (items > PNG_UINT_32_MAX/size)
-   {
-     png_warning (p, "Potential overflow in png_zalloc()");
-     return (NULL);
-   }
-   num_bytes = (png_alloc_size_t)items * size;
-
-   p->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK;
-   ptr = (png_voidp)png_malloc((png_structp)png_ptr, num_bytes);
-   p->flags=save_flags;
-
-   return ((voidpf)ptr);
-}
-
-/* Function to free memory for zlib */
-void /* PRIVATE */
-png_zfree(voidpf png_ptr, voidpf ptr)
-{
-   png_free((png_structp)png_ptr, (png_voidp)ptr);
-}
-
-/* Reset the CRC variable to 32 bits of 1's.  Care must be taken
- * in case CRC is > 32 bits to leave the top bits 0.
- */
-void /* PRIVATE */
-png_reset_crc(png_structp png_ptr)
-{
-   /* The cast is safe because the crc is a 32 bit value. */
-   png_ptr->crc = (png_uint_32)crc32(0, Z_NULL, 0);
-}
-
-/* Calculate the CRC over a section of data.  We can only pass as
- * much data to this routine as the largest single buffer size.  We
- * also check that this data will actually be used before going to the
- * trouble of calculating it.
- */
-void /* PRIVATE */
-png_calculate_crc(png_structp png_ptr, png_const_bytep ptr, png_size_t length)
-{
-   int need_crc = 1;
-
-   if (PNG_CHUNK_ANCILLIARY(png_ptr->chunk_name))
-   {
-      if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
-          (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
-         need_crc = 0;
-   }
-
-   else /* critical */
-   {
-      if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
-         need_crc = 0;
-   }
-
-   /* 'uLong' is defined as unsigned long, this means that on some systems it is
-    * a 64 bit value.  crc32, however, returns 32 bits so the following cast is
-    * safe.  'uInt' may be no more than 16 bits, so it is necessary to perform a
-    * loop here.
-    */
-   if (need_crc && length > 0)
-   {
-      uLong crc = png_ptr->crc; /* Should never issue a warning */
-
-      do
-      {
-         uInt safeLength = (uInt)length;
-         if (safeLength == 0)
-            safeLength = (uInt)-1; /* evil, but safe */
-
-         crc = crc32(crc, ptr, safeLength);
-
-         /* The following should never issue compiler warnings, if they do the
-          * target system has characteristics that will probably violate other
-          * assumptions within the libpng code.
-          */
-         ptr += safeLength;
-         length -= safeLength;
-      }
-      while (length > 0);
-
-      /* And the following is always safe because the crc is only 32 bits. */
-      png_ptr->crc = (png_uint_32)crc;
-   }
-}
-
-/* Check a user supplied version number, called from both read and write
- * functions that create a png_struct
- */
-int
-png_user_version_check(png_structp png_ptr, png_const_charp user_png_ver)
-{
-   if (user_png_ver)
-   {
-      int i = 0;
-
-      do
-      {
-         if (user_png_ver[i] != png_libpng_ver[i])
-            png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
-      } while (png_libpng_ver[i++]);
-   }
-
-   else
-      png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
-
-   if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH)
-   {
-     /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
-      * we must recompile any applications that use any older library version.
-      * For versions after libpng 1.0, we will be compatible, so we need
-      * only check the first digit.
-      */
-      if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
-          (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) ||
-          (user_png_ver[0] == '0' && user_png_ver[2] < '9'))
-      {
-#ifdef PNG_WARNINGS_SUPPORTED
-         size_t pos = 0;
-         char m[128];
-
-         pos = png_safecat(m, sizeof m, pos, "Application built with libpng-");
-         pos = png_safecat(m, sizeof m, pos, user_png_ver);
-         pos = png_safecat(m, sizeof m, pos, " but running with ");
-         pos = png_safecat(m, sizeof m, pos, png_libpng_ver);
-
-         png_warning(png_ptr, m);
-#endif
-
-#ifdef PNG_ERROR_NUMBERS_SUPPORTED
-         png_ptr->flags = 0;
-#endif
-
-         return 0;
-      }
-   }
-
-   /* Success return. */
-   return 1;
-}
-
-/* Allocate the memory for an info_struct for the application.  We don't
- * really need the png_ptr, but it could potentially be useful in the
- * future.  This should be used in favour of malloc(png_sizeof(png_info))
- * and png_info_init() so that applications that want to use a shared
- * libpng don't have to be recompiled if png_info changes size.
- */
-PNG_FUNCTION(png_infop,PNGAPI
-png_create_info_struct,(png_structp png_ptr),PNG_ALLOCATED)
-{
-   png_infop info_ptr;
-
-   png_debug(1, "in png_create_info_struct");
-
-   if (png_ptr == NULL)
-      return (NULL);
-
-#ifdef PNG_USER_MEM_SUPPORTED
-   info_ptr = (png_infop)png_create_struct_2(PNG_STRUCT_INFO,
-      png_ptr->malloc_fn, png_ptr->mem_ptr);
-#else
-   info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO);
-#endif
-   if (info_ptr != NULL)
-      png_info_init_3(&info_ptr, png_sizeof(png_info));
-
-   return (info_ptr);
-}
-
-/* This function frees the memory associated with a single info struct.
- * Normally, one would use either png_destroy_read_struct() or
- * png_destroy_write_struct() to free an info struct, but this may be
- * useful for some applications.
- */
-void PNGAPI
-png_destroy_info_struct(png_structp png_ptr, png_infopp info_ptr_ptr)
-{
-   png_infop info_ptr = NULL;
-
-   png_debug(1, "in png_destroy_info_struct");
-
-   if (png_ptr == NULL)
-      return;
-
-   if (info_ptr_ptr != NULL)
-      info_ptr = *info_ptr_ptr;
-
-   if (info_ptr != NULL)
-   {
-      png_info_destroy(png_ptr, info_ptr);
-
-#ifdef PNG_USER_MEM_SUPPORTED
-      png_destroy_struct_2((png_voidp)info_ptr, png_ptr->free_fn,
-          png_ptr->mem_ptr);
-#else
-      png_destroy_struct((png_voidp)info_ptr);
-#endif
-      *info_ptr_ptr = NULL;
-   }
-}
-
-/* Initialize the info structure.  This is now an internal function (0.89)
- * and applications using it are urged to use png_create_info_struct()
- * instead.
- */
-
-void PNGAPI
-png_info_init_3(png_infopp ptr_ptr, png_size_t png_info_struct_size)
-{
-   png_infop info_ptr = *ptr_ptr;
-
-   png_debug(1, "in png_info_init_3");
-
-   if (info_ptr == NULL)
-      return;
-
-   if (png_sizeof(png_info) > png_info_struct_size)
-   {
-      png_destroy_struct(info_ptr);
-      info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO);
-      *ptr_ptr = info_ptr;
-   }
-
-   /* Set everything to 0 */
-   png_memset(info_ptr, 0, png_sizeof(png_info));
-}
-
-void PNGAPI
-png_data_freer(png_structp png_ptr, png_infop info_ptr,
-   int freer, png_uint_32 mask)
-{
-   png_debug(1, "in png_data_freer");
-
-   if (png_ptr == NULL || info_ptr == NULL)
-      return;
-
-   if (freer == PNG_DESTROY_WILL_FREE_DATA)
-      info_ptr->free_me |= mask;
-
-   else if (freer == PNG_USER_WILL_FREE_DATA)
-      info_ptr->free_me &= ~mask;
-
-   else
-      png_warning(png_ptr,
-         "Unknown freer parameter in png_data_freer");
-}
-
-void PNGAPI
-png_free_data(png_structp png_ptr, png_infop info_ptr, png_uint_32 mask,
-   int num)
-{
-   png_debug(1, "in png_free_data");
-
-   if (png_ptr == NULL || info_ptr == NULL)
-      return;
-
-#ifdef PNG_TEXT_SUPPORTED
-   /* Free text item num or (if num == -1) all text items */
-   if ((mask & PNG_FREE_TEXT) & info_ptr->free_me)
-   {
-      if (num != -1)
-      {
-         if (info_ptr->text && info_ptr->text[num].key)
-         {
-            png_free(png_ptr, info_ptr->text[num].key);
-            info_ptr->text[num].key = NULL;
-         }
-      }
-
-      else
-      {
-         int i;
-         for (i = 0; i < info_ptr->num_text; i++)
-             png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, i);
-         png_free(png_ptr, info_ptr->text);
-         info_ptr->text = NULL;
-         info_ptr->num_text=0;
-      }
-   }
-#endif
-
-#ifdef PNG_tRNS_SUPPORTED
-   /* Free any tRNS entry */
-   if ((mask & PNG_FREE_TRNS) & info_ptr->free_me)
-   {
-      png_free(png_ptr, info_ptr->trans_alpha);
-      info_ptr->trans_alpha = NULL;
-      info_ptr->valid &= ~PNG_INFO_tRNS;
-   }
-#endif
-
-#ifdef PNG_sCAL_SUPPORTED
-   /* Free any sCAL entry */
-   if ((mask & PNG_FREE_SCAL) & info_ptr->free_me)
-   {
-      png_free(png_ptr, info_ptr->scal_s_width);
-      png_free(png_ptr, info_ptr->scal_s_height);
-      info_ptr->scal_s_width = NULL;
-      info_ptr->scal_s_height = NULL;
-      info_ptr->valid &= ~PNG_INFO_sCAL;
-   }
-#endif
-
-#ifdef PNG_pCAL_SUPPORTED
-   /* Free any pCAL entry */
-   if ((mask & PNG_FREE_PCAL) & info_ptr->free_me)
-   {
-      png_free(png_ptr, info_ptr->pcal_purpose);
-      png_free(png_ptr, info_ptr->pcal_units);
-      info_ptr->pcal_purpose = NULL;
-      info_ptr->pcal_units = NULL;
-      if (info_ptr->pcal_params != NULL)
-         {
-            int i;
-            for (i = 0; i < (int)info_ptr->pcal_nparams; i++)
-            {
-               png_free(png_ptr, info_ptr->pcal_params[i]);
-               info_ptr->pcal_params[i] = NULL;
-            }
-            png_free(png_ptr, info_ptr->pcal_params);
-            info_ptr->pcal_params = NULL;
-         }
-      info_ptr->valid &= ~PNG_INFO_pCAL;
-   }
-#endif
-
-#ifdef PNG_iCCP_SUPPORTED
-   /* Free any iCCP entry */
-   if ((mask & PNG_FREE_ICCP) & info_ptr->free_me)
-   {
-      png_free(png_ptr, info_ptr->iccp_name);
-      png_free(png_ptr, info_ptr->iccp_profile);
-      info_ptr->iccp_name = NULL;
-      info_ptr->iccp_profile = NULL;
-      info_ptr->valid &= ~PNG_INFO_iCCP;
-   }
-#endif
-
-#ifdef PNG_sPLT_SUPPORTED
-   /* Free a given sPLT entry, or (if num == -1) all sPLT entries */
-   if ((mask & PNG_FREE_SPLT) & info_ptr->free_me)
-   {
-      if (num != -1)
-      {
-         if (info_ptr->splt_palettes)
-         {
-            png_free(png_ptr, info_ptr->splt_palettes[num].name);
-            png_free(png_ptr, info_ptr->splt_palettes[num].entries);
-            info_ptr->splt_palettes[num].name = NULL;
-            info_ptr->splt_palettes[num].entries = NULL;
-         }
-      }
-
-      else
-      {
-         if (info_ptr->splt_palettes_num)
-         {
-            int i;
-            for (i = 0; i < (int)info_ptr->splt_palettes_num; i++)
-               png_free_data(png_ptr, info_ptr, PNG_FREE_SPLT, i);
-
-            png_free(png_ptr, info_ptr->splt_palettes);
-            info_ptr->splt_palettes = NULL;
-            info_ptr->splt_palettes_num = 0;
-         }
-         info_ptr->valid &= ~PNG_INFO_sPLT;
-      }
-   }
-#endif
-
-#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
-   if (png_ptr->unknown_chunk.data)
-   {
-      png_free(png_ptr, png_ptr->unknown_chunk.data);
-      png_ptr->unknown_chunk.data = NULL;
-   }
-
-   if ((mask & PNG_FREE_UNKN) & info_ptr->free_me)
-   {
-      if (num != -1)
-      {
-          if (info_ptr->unknown_chunks)
-          {
-             png_free(png_ptr, info_ptr->unknown_chunks[num].data);
-             info_ptr->unknown_chunks[num].data = NULL;
-          }
-      }
-
-      else
-      {
-         int i;
-
-         if (info_ptr->unknown_chunks_num)
-         {
-            for (i = 0; i < info_ptr->unknown_chunks_num; i++)
-               png_free_data(png_ptr, info_ptr, PNG_FREE_UNKN, i);
-
-            png_free(png_ptr, info_ptr->unknown_chunks);
-            info_ptr->unknown_chunks = NULL;
-            info_ptr->unknown_chunks_num = 0;
-         }
-      }
-   }
-#endif
-
-#ifdef PNG_hIST_SUPPORTED
-   /* Free any hIST entry */
-   if ((mask & PNG_FREE_HIST)  & info_ptr->free_me)
-   {
-      png_free(png_ptr, info_ptr->hist);
-      info_ptr->hist = NULL;
-      info_ptr->valid &= ~PNG_INFO_hIST;
-   }
-#endif
-
-   /* Free any PLTE entry that was internally allocated */
-   if ((mask & PNG_FREE_PLTE) & info_ptr->free_me)
-   {
-      png_zfree(png_ptr, info_ptr->palette);
-      info_ptr->palette = NULL;
-      info_ptr->valid &= ~PNG_INFO_PLTE;
-      info_ptr->num_palette = 0;
-   }
-
-#ifdef PNG_INFO_IMAGE_SUPPORTED
-   /* Free any image bits attached to the info structure */
-   if ((mask & PNG_FREE_ROWS) & info_ptr->free_me)
-   {
-      if (info_ptr->row_pointers)
-      {
-         int row;
-         for (row = 0; row < (int)info_ptr->height; row++)
-         {
-            png_free(png_ptr, info_ptr->row_pointers[row]);
-            info_ptr->row_pointers[row] = NULL;
-         }
-         png_free(png_ptr, info_ptr->row_pointers);
-         info_ptr->row_pointers = NULL;
-      }
-      info_ptr->valid &= ~PNG_INFO_IDAT;
-   }
-#endif
-
-   if (num != -1)
-      mask &= ~PNG_FREE_MUL;
-
-   info_ptr->free_me &= ~mask;
-}
-
-/* This is an internal routine to free any memory that the info struct is
- * pointing to before re-using it or freeing the struct itself.  Recall
- * that png_free() checks for NULL pointers for us.
- */
-void /* PRIVATE */
-png_info_destroy(png_structp png_ptr, png_infop info_ptr)
-{
-   png_debug(1, "in png_info_destroy");
-
-   png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
-
-#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
-   if (png_ptr->num_chunk_list)
-   {
-      png_free(png_ptr, png_ptr->chunk_list);
-      png_ptr->chunk_list = NULL;
-      png_ptr->num_chunk_list = 0;
-   }
-#endif
-
-   png_info_init_3(&info_ptr, png_sizeof(png_info));
-}
-#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
-
-/* This function returns a pointer to the io_ptr associated with the user
- * functions.  The application should free any memory associated with this
- * pointer before png_write_destroy() or png_read_destroy() are called.
- */
-png_voidp PNGAPI
-png_get_io_ptr(png_structp png_ptr)
-{
-   if (png_ptr == NULL)
-      return (NULL);
-
-   return (png_ptr->io_ptr);
-}
-
-#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
-#  ifdef PNG_STDIO_SUPPORTED
-/* Initialize the default input/output functions for the PNG file.  If you
- * use your own read or write routines, you can call either png_set_read_fn()
- * or png_set_write_fn() instead of png_init_io().  If you have defined
- * PNG_NO_STDIO or otherwise disabled PNG_STDIO_SUPPORTED, you must use a
- * function of your own because "FILE *" isn't necessarily available.
- */
-void PNGAPI
-png_init_io(png_structp png_ptr, png_FILE_p fp)
-{
-   png_debug(1, "in png_init_io");
-
-   if (png_ptr == NULL)
-      return;
-
-   png_ptr->io_ptr = (png_voidp)fp;
-}
-#  endif
-
-#  ifdef PNG_TIME_RFC1123_SUPPORTED
-/* Convert the supplied time into an RFC 1123 string suitable for use in
- * a "Creation Time" or other text-based time string.
- */
-png_const_charp PNGAPI
-png_convert_to_rfc1123(png_structp png_ptr, png_const_timep ptime)
-{
-   static PNG_CONST char short_months[12][4] =
-        {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
-         "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
-
-   if (png_ptr == NULL)
-      return (NULL);
-
-   if (ptime->year > 9999 /* RFC1123 limitation */ ||
-       ptime->month == 0    ||  ptime->month > 12  ||
-       ptime->day   == 0    ||  ptime->day   > 31  ||
-       ptime->hour  > 23    ||  ptime->minute > 59 ||
-       ptime->second > 60)
-   {
-      png_warning(png_ptr, "Ignoring invalid time value");
-      return (NULL);
-   }
-
-   {
-      size_t pos = 0;
-      char number_buf[5]; /* enough for a four-digit year */
-
-#     define APPEND_STRING(string)\
-         pos = png_safecat(png_ptr->time_buffer, sizeof png_ptr->time_buffer,\
-            pos, (string))
-#     define APPEND_NUMBER(format, value)\
-         APPEND_STRING(PNG_FORMAT_NUMBER(number_buf, format, (value)))
-#     define APPEND(ch)\
-         if (pos < (sizeof png_ptr->time_buffer)-1)\
-            png_ptr->time_buffer[pos++] = (ch)
-
-      APPEND_NUMBER(PNG_NUMBER_FORMAT_u, (unsigned)ptime->day);
-      APPEND(' ');
-      APPEND_STRING(short_months[(ptime->month - 1)]);
-      APPEND(' ');
-      APPEND_NUMBER(PNG_NUMBER_FORMAT_u, ptime->year);
-      APPEND(' ');
-      APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->hour);
-      APPEND(':');
-      APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->minute);
-      APPEND(':');
-      APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->second);
-      APPEND_STRING(" +0000"); /* This reliably terminates the buffer */
-
-#     undef APPEND
-#     undef APPEND_NUMBER
-#     undef APPEND_STRING
-   }
-
-   return png_ptr->time_buffer;
-}
-#  endif /* PNG_TIME_RFC1123_SUPPORTED */
-
-#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
-
-png_const_charp PNGAPI
-png_get_copyright(png_const_structp png_ptr)
-{
-   PNG_UNUSED(png_ptr)  /* Silence compiler warning about unused png_ptr */
-#ifdef PNG_STRING_COPYRIGHT
-   return PNG_STRING_COPYRIGHT
-#else
-#  ifdef __STDC__
-   return PNG_STRING_NEWLINE \
-     "libpng version 1.5.13 - September 27, 2012" PNG_STRING_NEWLINE \
-     "Copyright (c) 1998-2012 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \
-     "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
-     "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \
-     PNG_STRING_NEWLINE;
-#  else
-      return "libpng version 1.5.13 - September 27, 2012\
-      Copyright (c) 1998-2012 Glenn Randers-Pehrson\
-      Copyright (c) 1996-1997 Andreas Dilger\
-      Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.";
-#  endif
-#endif
-}
-
-/* The following return the library version as a short string in the
- * format 1.0.0 through 99.99.99zz.  To get the version of *.h files
- * used with your application, print out PNG_LIBPNG_VER_STRING, which
- * is defined in png.h.
- * Note: now there is no difference between png_get_libpng_ver() and
- * png_get_header_ver().  Due to the version_nn_nn_nn typedef guard,
- * it is guaranteed that png.c uses the correct version of png.h.
- */
-png_const_charp PNGAPI
-png_get_libpng_ver(png_const_structp png_ptr)
-{
-   /* Version of *.c files used when building libpng */
-   return png_get_header_ver(png_ptr);
-}
-
-png_const_charp PNGAPI
-png_get_header_ver(png_const_structp png_ptr)
-{
-   /* Version of *.h files used when building libpng */
-   PNG_UNUSED(png_ptr)  /* Silence compiler warning about unused png_ptr */
-   return PNG_LIBPNG_VER_STRING;
-}
-
-png_const_charp PNGAPI
-png_get_header_version(png_const_structp png_ptr)
-{
-   /* Returns longer string containing both version and date */
-   PNG_UNUSED(png_ptr)  /* Silence compiler warning about unused png_ptr */
-#ifdef __STDC__
-   return PNG_HEADER_VERSION_STRING
-#  ifndef PNG_READ_SUPPORTED
-   "     (NO READ SUPPORT)"
-#  endif
-   PNG_STRING_NEWLINE;
-#else
-   return PNG_HEADER_VERSION_STRING;
-#endif
-}
-
-#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
-int PNGAPI
-png_handle_as_unknown(png_structp png_ptr, png_const_bytep chunk_name)
-{
-   /* Check chunk_name and return "keep" value if it's on the list, else 0 */
-   png_const_bytep p, p_end;
-
-   if (png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list <= 0)
-      return PNG_HANDLE_CHUNK_AS_DEFAULT;
-
-   p_end = png_ptr->chunk_list;
-   p = p_end + png_ptr->num_chunk_list*5; /* beyond end */
-
-   /* The code is the fifth byte after each four byte string.  Historically this
-    * code was always searched from the end of the list, so it should continue
-    * to do so in case there are duplicated entries.
-    */
-   do /* num_chunk_list > 0, so at least one */
-   {
-      p -= 5;
-      if (!png_memcmp(chunk_name, p, 4))
-         return p[4];
-   }
-   while (p > p_end);
-
-   return PNG_HANDLE_CHUNK_AS_DEFAULT;
-}
-
-int /* PRIVATE */
-png_chunk_unknown_handling(png_structp png_ptr, png_uint_32 chunk_name)
-{
-   png_byte chunk_string[5];
-
-   PNG_CSTRING_FROM_CHUNK(chunk_string, chunk_name);
-   return png_handle_as_unknown(png_ptr, chunk_string);
-}
-#endif
-
-#ifdef PNG_READ_SUPPORTED
-/* This function, added to libpng-1.0.6g, is untested. */
-int PNGAPI
-png_reset_zstream(png_structp png_ptr)
-{
-   if (png_ptr == NULL)
-      return Z_STREAM_ERROR;
-
-   return (inflateReset(&png_ptr->zstream));
-}
-#endif /* PNG_READ_SUPPORTED */
-
-/* This function was added to libpng-1.0.7 */
-png_uint_32 PNGAPI
-png_access_version_number(void)
-{
-   /* Version of *.c files used when building libpng */
-   return((png_uint_32)PNG_LIBPNG_VER);
-}
-
-
-
-#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
-/* png_convert_size: a PNGAPI but no longer in png.h, so deleted
- * at libpng 1.5.5!
- */
-
-/* Added at libpng version 1.2.34 and 1.4.0 (moved from pngset.c) */
-#  ifdef PNG_CHECK_cHRM_SUPPORTED
-
-int /* PRIVATE */
-png_check_cHRM_fixed(png_structp png_ptr,
-   png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x,
-   png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y,
-   png_fixed_point blue_x, png_fixed_point blue_y)
-{
-   int ret = 1;
-   unsigned long xy_hi,xy_lo,yx_hi,yx_lo;
-
-   png_debug(1, "in function png_check_cHRM_fixed");
-
-   if (png_ptr == NULL)
-      return 0;
-
-   /* (x,y,z) values are first limited to 0..100000 (PNG_FP_1), the white
-    * y must also be greater than 0.  To test for the upper limit calculate
-    * (PNG_FP_1-y) - x must be <= to this for z to be >= 0 (and the expression
-    * cannot overflow.)  At this point we know x and y are >= 0 and (x+y) is
-    * <= PNG_FP_1.  The previous test on PNG_MAX_UINT_31 is removed because it
-    * pointless (and it produces compiler warnings!)
-    */
-   if (white_x < 0 || white_y <= 0 ||
-         red_x < 0 ||   red_y <  0 ||
-       green_x < 0 || green_y <  0 ||
-        blue_x < 0 ||  blue_y <  0)
-   {
-      png_warning(png_ptr,
-        "Ignoring attempt to set negative chromaticity value");
-      ret = 0;
-   }
-   /* And (x+y) must be <= PNG_FP_1 (so z is >= 0) */
-   if (white_x > PNG_FP_1 - white_y)
-   {
-      png_warning(png_ptr, "Invalid cHRM white point");
-      ret = 0;
-   }
-
-   if (red_x > PNG_FP_1 - red_y)
-   {
-      png_warning(png_ptr, "Invalid cHRM red point");
-      ret = 0;
-   }
-
-   if (green_x > PNG_FP_1 - green_y)
-   {
-      png_warning(png_ptr, "Invalid cHRM green point");
-      ret = 0;
-   }
-
-   if (blue_x > PNG_FP_1 - blue_y)
-   {
-      png_warning(png_ptr, "Invalid cHRM blue point");
-      ret = 0;
-   }
-
-   png_64bit_product(green_x - red_x, blue_y - red_y, &xy_hi, &xy_lo);
-   png_64bit_product(green_y - red_y, blue_x - red_x, &yx_hi, &yx_lo);
-
-   if (xy_hi == yx_hi && xy_lo == yx_lo)
-   {
-      png_warning(png_ptr,
-         "Ignoring attempt to set cHRM RGB triangle with zero area");
-      ret = 0;
-   }
-
-   return ret;
-}
-#  endif /* PNG_CHECK_cHRM_SUPPORTED */
-
-#ifdef PNG_cHRM_SUPPORTED
-/* Added at libpng-1.5.5 to support read and write of true CIEXYZ values for
- * cHRM, as opposed to using chromaticities.  These internal APIs return
- * non-zero on a parameter error.  The X, Y and Z values are required to be
- * positive and less than 1.0.
- */
-int png_xy_from_XYZ(png_xy *xy, png_XYZ XYZ)
-{
-   png_int_32 d, dwhite, whiteX, whiteY;
-
-   d = XYZ.redX + XYZ.redY + XYZ.redZ;
-   if (!png_muldiv(&xy->redx, XYZ.redX, PNG_FP_1, d)) return 1;
-   if (!png_muldiv(&xy->redy, XYZ.redY, PNG_FP_1, d)) return 1;
-   dwhite = d;
-   whiteX = XYZ.redX;
-   whiteY = XYZ.redY;
-
-   d = XYZ.greenX + XYZ.greenY + XYZ.greenZ;
-   if (!png_muldiv(&xy->greenx, XYZ.greenX, PNG_FP_1, d)) return 1;
-   if (!png_muldiv(&xy->greeny, XYZ.greenY, PNG_FP_1, d)) return 1;
-   dwhite += d;
-   whiteX += XYZ.greenX;
-   whiteY += XYZ.greenY;
-
-   d = XYZ.blueX + XYZ.blueY + XYZ.blueZ;
-   if (!png_muldiv(&xy->bluex, XYZ.blueX, PNG_FP_1, d)) return 1;
-   if (!png_muldiv(&xy->bluey, XYZ.blueY, PNG_FP_1, d)) return 1;
-   dwhite += d;
-   whiteX += XYZ.blueX;
-   whiteY += XYZ.blueY;
-
-   /* The reference white is simply the same of the end-point (X,Y,Z) vectors,
-    * thus:
-    */
-   if (!png_muldiv(&xy->whitex, whiteX, PNG_FP_1, dwhite)) return 1;
-   if (!png_muldiv(&xy->whitey, whiteY, PNG_FP_1, dwhite)) return 1;
-
-   return 0;
-}
-
-int png_XYZ_from_xy(png_XYZ *XYZ, png_xy xy)
-{
-   png_fixed_point red_inverse, green_inverse, blue_scale;
-   png_fixed_point left, right, denominator;
-
-   /* Check xy and, implicitly, z.  Note that wide gamut color spaces typically
-    * have end points with 0 tristimulus values (these are impossible end
-    * points, but they are used to cover the possible colors.)
-    */
-   if (xy.redx < 0 || xy.redx > PNG_FP_1) return 1;
-   if (xy.redy < 0 || xy.redy > PNG_FP_1-xy.redx) return 1;
-   if (xy.greenx < 0 || xy.greenx > PNG_FP_1) return 1;
-   if (xy.greeny < 0 || xy.greeny > PNG_FP_1-xy.greenx) return 1;
-   if (xy.bluex < 0 || xy.bluex > PNG_FP_1) return 1;
-   if (xy.bluey < 0 || xy.bluey > PNG_FP_1-xy.bluex) return 1;
-   if (xy.whitex < 0 || xy.whitex > PNG_FP_1) return 1;
-   if (xy.whitey < 0 || xy.whitey > PNG_FP_1-xy.whitex) return 1;
-
-   /* The reverse calculation is more difficult because the original tristimulus
-    * value had 9 independent values (red,green,blue)x(X,Y,Z) however only 8
-    * derived values were recorded in the cHRM chunk;
-    * (red,green,blue,white)x(x,y).  This loses one degree of freedom and
-    * therefore an arbitrary ninth value has to be introduced to undo the
-    * original transformations.
-    *
-    * Think of the original end-points as points in (X,Y,Z) space.  The
-    * chromaticity values (c) have the property:
-    *
-    *           C
-    *   c = ---------
-    *       X + Y + Z
-    *
-    * For each c (x,y,z) from the corresponding original C (X,Y,Z).  Thus the
-    * three chromaticity values (x,y,z) for each end-point obey the
-    * relationship:
-    *
-    *   x + y + z = 1
-    *
-    * This describes the plane in (X,Y,Z) space that intersects each axis at the
-    * value 1.0; call this the chromaticity plane.  Thus the chromaticity
-    * calculation has scaled each end-point so that it is on the x+y+z=1 plane
-    * and chromaticity is the intersection of the vector from the origin to the
-    * (X,Y,Z) value with the chromaticity plane.
-    *
-    * To fully invert the chromaticity calculation we would need the three
-    * end-point scale factors, (red-scale, green-scale, blue-scale), but these
-    * were not recorded.  Instead we calculated the reference white (X,Y,Z) and
-    * recorded the chromaticity of this.  The reference white (X,Y,Z) would have
-    * given all three of the scale factors since:
-    *
-    *    color-C = color-c * color-scale
-    *    white-C = red-C + green-C + blue-C
-    *            = red-c*red-scale + green-c*green-scale + blue-c*blue-scale
-    *
-    * But cHRM records only white-x and white-y, so we have lost the white scale
-    * factor:
-    *
-    *    white-C = white-c*white-scale
-    *
-    * To handle this the inverse transformation makes an arbitrary assumption
-    * about white-scale:
-    *
-    *    Assume: white-Y = 1.0
-    *    Hence:  white-scale = 1/white-y
-    *    Or:     red-Y + green-Y + blue-Y = 1.0
-    *
-    * Notice the last statement of the assumption gives an equation in three of
-    * the nine values we want to calculate.  8 more equations come from the
-    * above routine as summarised at the top above (the chromaticity
-    * calculation):
-    *
-    *    Given: color-x = color-X / (color-X + color-Y + color-Z)
-    *    Hence: (color-x - 1)*color-X + color.x*color-Y + color.x*color-Z = 0
-    *
-    * This is 9 simultaneous equations in the 9 variables "color-C" and can be
-    * solved by Cramer's rule.  Cramer's rule requires calculating 10 9x9 matrix
-    * determinants, however this is not as bad as it seems because only 28 of
-    * the total of 90 terms in the various matrices are non-zero.  Nevertheless
-    * Cramer's rule is notoriously numerically unstable because the determinant
-    * calculation involves the difference of large, but similar, numbers.  It is
-    * difficult to be sure that the calculation is stable for real world values
-    * and it is certain that it becomes unstable where the end points are close
-    * together.
-    *
-    * So this code uses the perhaps slightly less optimal but more
-    * understandable and totally obvious approach of calculating color-scale.
-    *
-    * This algorithm depends on the precision in white-scale and that is
-    * (1/white-y), so we can immediately see that as white-y approaches 0 the
-    * accuracy inherent in the cHRM chunk drops off substantially.
-    *
-    * libpng arithmetic: a simple invertion of the above equations
-    * ------------------------------------------------------------
-    *
-    *    white_scale = 1/white-y
-    *    white-X = white-x * white-scale
-    *    white-Y = 1.0
-    *    white-Z = (1 - white-x - white-y) * white_scale
-    *
-    *    white-C = red-C + green-C + blue-C
-    *            = red-c*red-scale + green-c*green-scale + blue-c*blue-scale
-    *
-    * This gives us three equations in (red-scale,green-scale,blue-scale) where
-    * all the coefficients are now known:
-    *
-    *    red-x*red-scale + green-x*green-scale + blue-x*blue-scale
-    *       = white-x/white-y
-    *    red-y*red-scale + green-y*green-scale + blue-y*blue-scale = 1
-    *    red-z*red-scale + green-z*green-scale + blue-z*blue-scale
-    *       = (1 - white-x - white-y)/white-y
-    *
-    * In the last equation color-z is (1 - color-x - color-y) so we can add all
-    * three equations together to get an alternative third:
-    *
-    *    red-scale + green-scale + blue-scale = 1/white-y = white-scale
-    *
-    * So now we have a Cramer's rule solution where the determinants are just
-    * 3x3 - far more tractible.  Unfortunately 3x3 determinants still involve
-    * multiplication of three coefficients so we can't guarantee to avoid
-    * overflow in the libpng fixed point representation.  Using Cramer's rule in
-    * floating point is probably a good choice here, but it's not an option for
-    * fixed point.  Instead proceed to simplify the first two equations by
-    * eliminating what is likely to be the largest value, blue-scale:
-    *
-    *    blue-scale = white-scale - red-scale - green-scale
-    *
-    * Hence:
-    *
-    *    (red-x - blue-x)*red-scale + (green-x - blue-x)*green-scale =
-    *                (white-x - blue-x)*white-scale
-    *
-    *    (red-y - blue-y)*red-scale + (green-y - blue-y)*green-scale =
-    *                1 - blue-y*white-scale
-    *
-    * And now we can trivially solve for (red-scale,green-scale):
-    *
-    *    green-scale =
-    *                (white-x - blue-x)*white-scale - (red-x - blue-x)*red-scale
-    *                -----------------------------------------------------------
-    *                                  green-x - blue-x
-    *
-    *    red-scale =
-    *                1 - blue-y*white-scale - (green-y - blue-y) * green-scale
-    *                ---------------------------------------------------------
-    *                                  red-y - blue-y
-    *
-    * Hence:
-    *
-    *    red-scale =
-    *          ( (green-x - blue-x) * (white-y - blue-y) -
-    *            (green-y - blue-y) * (white-x - blue-x) ) / white-y
-    * -------------------------------------------------------------------------
-    *  (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x)
-    *
-    *    green-scale =
-    *          ( (red-y - blue-y) * (white-x - blue-x) -
-    *            (red-x - blue-x) * (white-y - blue-y) ) / white-y
-    * -------------------------------------------------------------------------
-    *  (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x)
-    *
-    * Accuracy:
-    * The input values have 5 decimal digits of accuracy.  The values are all in
-    * the range 0 < value < 1, so simple products are in the same range but may
-    * need up to 10 decimal digits to preserve the original precision and avoid
-    * underflow.  Because we are using a 32-bit signed representation we cannot
-    * match this; the best is a little over 9 decimal digits, less than 10.
-    *
-    * The approach used here is to preserve the maximum precision within the
-    * signed representation.  Because the red-scale calculation above uses the
-    * difference between two products of values that must be in the range -1..+1
-    * it is sufficient to divide the product by 7; ceil(100,000/32767*2).  The
-    * factor is irrelevant in the calculation because it is applied to both
-    * numerator and denominator.
-    *
-    * Note that the values of the differences of the products of the
-    * chromaticities in the above equations tend to be small, for example for
-    * the sRGB chromaticities they are:
-    *
-    * red numerator:    -0.04751
-    * green numerator:  -0.08788
-    * denominator:      -0.2241 (without white-y multiplication)
-    *
-    *  The resultant Y coefficients from the chromaticities of some widely used
-    *  color space definitions are (to 15 decimal places):
-    *
-    *  sRGB
-    *    0.212639005871510 0.715168678767756 0.072192315360734
-    *  Kodak ProPhoto
-    *    0.288071128229293 0.711843217810102 0.000085653960605
-    *  Adobe RGB
-    *    0.297344975250536 0.627363566255466 0.075291458493998
-    *  Adobe Wide Gamut RGB
-    *    0.258728243040113 0.724682314948566 0.016589442011321
-    */
-   /* By the argument, above overflow should be impossible here. The return
-    * value of 2 indicates an internal error to the caller.
-    */
-   if (!png_muldiv(&left, xy.greenx-xy.bluex, xy.redy - xy.bluey, 7)) return 2;
-   if (!png_muldiv(&right, xy.greeny-xy.bluey, xy.redx - xy.bluex, 7)) return 2;
-   denominator = left - right;
-
-   /* Now find the red numerator. */
-   if (!png_muldiv(&left, xy.greenx-xy.bluex, xy.whitey-xy.bluey, 7)) return 2;
-   if (!png_muldiv(&right, xy.greeny-xy.bluey, xy.whitex-xy.bluex, 7)) return 2;
-
-   /* Overflow is possible here and it indicates an extreme set of PNG cHRM
-    * chunk values.  This calculation actually returns the reciprocal of the
-    * scale value because this allows us to delay the multiplication of white-y
-    * into the denominator, which tends to produce a small number.
-    */
-   if (!png_muldiv(&red_inverse, xy.whitey, denominator, left-right) ||
-       red_inverse <= xy.whitey /* r+g+b scales = white scale */)
-      return 1;
-
-   /* Similarly for green_inverse: */
-   if (!png_muldiv(&left, xy.redy-xy.bluey, xy.whitex-xy.bluex, 7)) return 2;
-   if (!png_muldiv(&right, xy.redx-xy.bluex, xy.whitey-xy.bluey, 7)) return 2;
-   if (!png_muldiv(&green_inverse, xy.whitey, denominator, left-right) ||
-       green_inverse <= xy.whitey)
-      return 1;
-
-   /* And the blue scale, the checks above guarantee this can't overflow but it
-    * can still produce 0 for extreme cHRM values.
-    */
-   blue_scale = png_reciprocal(xy.whitey) - png_reciprocal(red_inverse) -
-      png_reciprocal(green_inverse);
-   if (blue_scale <= 0) return 1;
-
-
-   /* And fill in the png_XYZ: */
-   if (!png_muldiv(&XYZ->redX, xy.redx, PNG_FP_1, red_inverse)) return 1;
-   if (!png_muldiv(&XYZ->redY, xy.redy, PNG_FP_1, red_inverse)) return 1;
-   if (!png_muldiv(&XYZ->redZ, PNG_FP_1 - xy.redx - xy.redy, PNG_FP_1,
-      red_inverse))
-      return 1;
-
-   if (!png_muldiv(&XYZ->greenX, xy.greenx, PNG_FP_1, green_inverse)) return 1;
-   if (!png_muldiv(&XYZ->greenY, xy.greeny, PNG_FP_1, green_inverse)) return 1;
-   if (!png_muldiv(&XYZ->greenZ, PNG_FP_1 - xy.greenx - xy.greeny, PNG_FP_1,
-      green_inverse))
-      return 1;
-
-   if (!png_muldiv(&XYZ->blueX, xy.bluex, blue_scale, PNG_FP_1)) return 1;
-   if (!png_muldiv(&XYZ->blueY, xy.bluey, blue_scale, PNG_FP_1)) return 1;
-   if (!png_muldiv(&XYZ->blueZ, PNG_FP_1 - xy.bluex - xy.bluey, blue_scale,
-      PNG_FP_1))
-      return 1;
-
-   return 0; /*success*/
-}
-
-int png_XYZ_from_xy_checked(png_structp png_ptr, png_XYZ *XYZ, png_xy xy)
-{
-   switch (png_XYZ_from_xy(XYZ, xy))
-   {
-      case 0: /* success */
-         return 1;
-
-      case 1:
-         /* The chunk may be technically valid, but we got png_fixed_point
-          * overflow while trying to get XYZ values out of it.  This is
-          * entirely benign - the cHRM chunk is pretty extreme.
-          */
-         png_warning(png_ptr,
-            "extreme cHRM chunk cannot be converted to tristimulus values");
-         break;
-
-      default:
-         /* libpng is broken; this should be a warning but if it happens we
-          * want error reports so for the moment it is an error.
-          */
-         png_error(png_ptr, "internal error in png_XYZ_from_xy");
-         break;
-   }
-
-   /* ERROR RETURN */
-   return 0;
-}
-#endif
-
-void /* PRIVATE */
-png_check_IHDR(png_structp png_ptr,
-   png_uint_32 width, png_uint_32 height, int bit_depth,
-   int color_type, int interlace_type, int compression_type,
-   int filter_type)
-{
-   int error = 0;
-
-   /* Check for width and height valid values */
-   if (width == 0)
-   {
-      png_warning(png_ptr, "Image width is zero in IHDR");
-      error = 1;
-   }
-
-   if (height == 0)
-   {
-      png_warning(png_ptr, "Image height is zero in IHDR");
-      error = 1;
-   }
-
-#  ifdef PNG_SET_USER_LIMITS_SUPPORTED
-   if (width > png_ptr->user_width_max)
-
-#  else
-   if (width > PNG_USER_WIDTH_MAX)
-#  endif
-   {
-      png_warning(png_ptr, "Image width exceeds user limit in IHDR");
-      error = 1;
-   }
-
-#  ifdef PNG_SET_USER_LIMITS_SUPPORTED
-   if (height > png_ptr->user_height_max)
-#  else
-   if (height > PNG_USER_HEIGHT_MAX)
-#  endif
-   {
-      png_warning(png_ptr, "Image height exceeds user limit in IHDR");
-      error = 1;
-   }
-
-   if (width > PNG_UINT_31_MAX)
-   {
-      png_warning(png_ptr, "Invalid image width in IHDR");
-      error = 1;
-   }
-
-   if (height > PNG_UINT_31_MAX)
-   {
-      png_warning(png_ptr, "Invalid image height in IHDR");
-      error = 1;
-   }
-
-   if (width > (PNG_UINT_32_MAX
-                 >> 3)      /* 8-byte RGBA pixels */
-                 - 48       /* bigrowbuf hack */
-                 - 1        /* filter byte */
-                 - 7*8      /* rounding of width to multiple of 8 pixels */
-                 - 8)       /* extra max_pixel_depth pad */
-      png_warning(png_ptr, "Width is too large for libpng to process pixels");
-
-   /* Check other values */
-   if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 &&
-       bit_depth != 8 && bit_depth != 16)
-   {
-      png_warning(png_ptr, "Invalid bit depth in IHDR");
-      error = 1;
-   }
-
-   if (color_type < 0 || color_type == 1 ||
-       color_type == 5 || color_type > 6)
-   {
-      png_warning(png_ptr, "Invalid color type in IHDR");
-      error = 1;
-   }
-
-   if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) ||
-       ((color_type == PNG_COLOR_TYPE_RGB ||
-         color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
-         color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8))
-   {
-      png_warning(png_ptr, "Invalid color type/bit depth combination in IHDR");
-      error = 1;
-   }
-
-   if (interlace_type >= PNG_INTERLACE_LAST)
-   {
-      png_warning(png_ptr, "Unknown interlace method in IHDR");
-      error = 1;
-   }
-
-   if (compression_type != PNG_COMPRESSION_TYPE_BASE)
-   {
-      png_warning(png_ptr, "Unknown compression method in IHDR");
-      error = 1;
-   }
-
-#  ifdef PNG_MNG_FEATURES_SUPPORTED
-   /* Accept filter_method 64 (intrapixel differencing) only if
-    * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
-    * 2. Libpng did not read a PNG signature (this filter_method is only
-    *    used in PNG datastreams that are embedded in MNG datastreams) and
-    * 3. The application called png_permit_mng_features with a mask that
-    *    included PNG_FLAG_MNG_FILTER_64 and
-    * 4. The filter_method is 64 and
-    * 5. The color_type is RGB or RGBA
-    */
-   if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) &&
-       png_ptr->mng_features_permitted)
-      png_warning(png_ptr, "MNG features are not allowed in a PNG datastream");
-
-   if (filter_type != PNG_FILTER_TYPE_BASE)
-   {
-      if (!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
-          (filter_type == PNG_INTRAPIXEL_DIFFERENCING) &&
-          ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) &&
-          (color_type == PNG_COLOR_TYPE_RGB ||
-          color_type == PNG_COLOR_TYPE_RGB_ALPHA)))
-      {
-         png_warning(png_ptr, "Unknown filter method in IHDR");
-         error = 1;
-      }
-
-      if (png_ptr->mode & PNG_HAVE_PNG_SIGNATURE)
-      {
-         png_warning(png_ptr, "Invalid filter method in IHDR");
-         error = 1;
-      }
-   }
-
-#  else
-   if (filter_type != PNG_FILTER_TYPE_BASE)
-   {
-      png_warning(png_ptr, "Unknown filter method in IHDR");
-      error = 1;
-   }
-#  endif
-
-   if (error == 1)
-      png_error(png_ptr, "Invalid IHDR data");
-}
-
-#if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED)
-/* ASCII to fp functions */
-/* Check an ASCII formated floating point value, see the more detailed
- * comments in pngpriv.h
- */
-/* The following is used internally to preserve the sticky flags */
-#define png_fp_add(state, flags) ((state) |= (flags))
-#define png_fp_set(state, value) ((state) = (value) | ((state) & PNG_FP_STICKY))
-
-int /* PRIVATE */
-png_check_fp_number(png_const_charp string, png_size_t size, int *statep,
-   png_size_tp whereami)
-{
-   int state = *statep;
-   png_size_t i = *whereami;
-
-   while (i < size)
-   {
-      int type;
-      /* First find the type of the next character */
-      switch (string[i])
-      {
-      case 43:  type = PNG_FP_SAW_SIGN;                   break;
-      case 45:  type = PNG_FP_SAW_SIGN + PNG_FP_NEGATIVE; break;
-      case 46:  type = PNG_FP_SAW_DOT;                    break;
-      case 48:  type = PNG_FP_SAW_DIGIT;                  break;
-      case 49: case 50: case 51: case 52:
-      case 53: case 54: case 55: case 56:
-      case 57:  type = PNG_FP_SAW_DIGIT + PNG_FP_NONZERO; break;
-      case 69:
-      case 101: type = PNG_FP_SAW_E;                      break;
-      default:  goto PNG_FP_End;
-      }
-
-      /* Now deal with this type according to the current
-       * state, the type is arranged to not overlap the
-       * bits of the PNG_FP_STATE.
-       */
-      switch ((state & PNG_FP_STATE) + (type & PNG_FP_SAW_ANY))
-      {
-      case PNG_FP_INTEGER + PNG_FP_SAW_SIGN:
-         if (state & PNG_FP_SAW_ANY)
-            goto PNG_FP_End; /* not a part of the number */
-
-         png_fp_add(state, type);
-         break;
-
-      case PNG_FP_INTEGER + PNG_FP_SAW_DOT:
-         /* Ok as trailer, ok as lead of fraction. */
-         if (state & PNG_FP_SAW_DOT) /* two dots */
-            goto PNG_FP_End;
-
-         else if (state & PNG_FP_SAW_DIGIT) /* trailing dot? */
-            png_fp_add(state, type);
-
-         else
-            png_fp_set(state, PNG_FP_FRACTION | type);
-
-         break;
-
-      case PNG_FP_INTEGER + PNG_FP_SAW_DIGIT:
-         if (state & PNG_FP_SAW_DOT) /* delayed fraction */
-            png_fp_set(state, PNG_FP_FRACTION | PNG_FP_SAW_DOT);
-
-         png_fp_add(state, type | PNG_FP_WAS_VALID);
-
-         break;
-
-      case PNG_FP_INTEGER + PNG_FP_SAW_E:
-         if ((state & PNG_FP_SAW_DIGIT) == 0)
-            goto PNG_FP_End;
-
-         png_fp_set(state, PNG_FP_EXPONENT);
-
-         break;
-
-   /* case PNG_FP_FRACTION + PNG_FP_SAW_SIGN:
-         goto PNG_FP_End; ** no sign in fraction */
-
-   /* case PNG_FP_FRACTION + PNG_FP_SAW_DOT:
-         goto PNG_FP_End; ** Because SAW_DOT is always set */
-
-      case PNG_FP_FRACTION + PNG_FP_SAW_DIGIT:
-         png_fp_add(state, type | PNG_FP_WAS_VALID);
-         break;
-
-      case PNG_FP_FRACTION + PNG_FP_SAW_E:
-         /* This is correct because the trailing '.' on an
-          * integer is handled above - so we can only get here
-          * with the sequence ".E" (with no preceding digits).
-          */
-         if ((state & PNG_FP_SAW_DIGIT) == 0)
-            goto PNG_FP_End;
-
-         png_fp_set(state, PNG_FP_EXPONENT);
-
-         break;
-
-      case PNG_FP_EXPONENT + PNG_FP_SAW_SIGN:
-         if (state & PNG_FP_SAW_ANY)
-            goto PNG_FP_End; /* not a part of the number */
-
-         png_fp_add(state, PNG_FP_SAW_SIGN);
-
-         break;
-
-   /* case PNG_FP_EXPONENT + PNG_FP_SAW_DOT:
-         goto PNG_FP_End; */
-
-      case PNG_FP_EXPONENT + PNG_FP_SAW_DIGIT:
-         png_fp_add(state, PNG_FP_SAW_DIGIT | PNG_FP_WAS_VALID);
-
-         break;
-
-   /* case PNG_FP_EXPONEXT + PNG_FP_SAW_E:
-         goto PNG_FP_End; */
-
-      default: goto PNG_FP_End; /* I.e. break 2 */
-      }
-
-      /* The character seems ok, continue. */
-      ++i;
-   }
-
-PNG_FP_End:
-   /* Here at the end, update the state and return the correct
-    * return code.
-    */
-   *statep = state;
-   *whereami = i;
-
-   return (state & PNG_FP_SAW_DIGIT) != 0;
-}
-
-
-/* The same but for a complete string. */
-int
-png_check_fp_string(png_const_charp string, png_size_t size)
-{
-   int        state=0;
-   png_size_t char_index=0;
-
-   if (png_check_fp_number(string, size, &state, &char_index) &&
-      (char_index == size || string[char_index] == 0))
-      return state /* must be non-zero - see above */;
-
-   return 0; /* i.e. fail */
-}
-#endif /* pCAL or sCAL */
-
-#ifdef PNG_READ_sCAL_SUPPORTED
-#  ifdef PNG_FLOATING_POINT_SUPPORTED
-/* Utility used below - a simple accurate power of ten from an integral
- * exponent.
- */
-static double
-png_pow10(int power)
-{
-   int recip = 0;
-   double d = 1.0;
-
-   /* Handle negative exponent with a reciprocal at the end because
-    * 10 is exact whereas .1 is inexact in base 2
-    */
-   if (power < 0)
-   {
-      if (power < DBL_MIN_10_EXP) return 0;
-      recip = 1, power = -power;
-   }
-
-   if (power > 0)
-   {
-      /* Decompose power bitwise. */
-      double mult = 10.0;
-      do
-      {
-         if (power & 1) d *= mult;
-         mult *= mult;
-         power >>= 1;
-      }
-      while (power > 0);
-
-      if (recip) d = 1/d;
-   }
-   /* else power is 0 and d is 1 */
-
-   return d;
-}
-
-/* Function to format a floating point value in ASCII with a given
- * precision.
- */
-void /* PRIVATE */
-png_ascii_from_fp(png_structp png_ptr, png_charp ascii, png_size_t size,
-    double fp, unsigned int precision)
-{
-   /* We use standard functions from math.h, but not printf because
-    * that would require stdio.  The caller must supply a buffer of
-    * sufficient size or we will png_error.  The tests on size and
-    * the space in ascii[] consumed are indicated below.
-    */
-   if (precision < 1)
-      precision = DBL_DIG;
-
-   /* Enforce the limit of the implementation precision too. */
-   if (precision > DBL_DIG+1)
-      precision = DBL_DIG+1;
-
-   /* Basic sanity checks */
-   if (size >= precision+5) /* See the requirements below. */
-   {
-      if (fp < 0)
-      {
-         fp = -fp;
-         *ascii++ = 45; /* '-'  PLUS 1 TOTAL 1 */
-         --size;
-      }
-
-      if (fp >= DBL_MIN && fp <= DBL_MAX)
-      {
-         int exp_b10;       /* A base 10 exponent */
-         double base;   /* 10^exp_b10 */
-
-         /* First extract a base 10 exponent of the number,
-          * the calculation below rounds down when converting
-          * from base 2 to base 10 (multiply by log10(2) -
-          * 0.3010, but 77/256 is 0.3008, so exp_b10 needs to
-          * be increased.  Note that the arithmetic shift
-          * performs a floor() unlike C arithmetic - using a
-          * C multiply would break the following for negative
-          * exponents.
-          */
-         (void)frexp(fp, &exp_b10); /* exponent to base 2 */
-
-         exp_b10 = (exp_b10 * 77) >> 8; /* <= exponent to base 10 */
-
-         /* Avoid underflow here. */
-         base = png_pow10(exp_b10); /* May underflow */
-
-         while (base < DBL_MIN || base < fp)
-         {
-            /* And this may overflow. */
-            double test = png_pow10(exp_b10+1);
-
-            if (test <= DBL_MAX)
-               ++exp_b10, base = test;
-
-            else
-               break;
-         }
-
-         /* Normalize fp and correct exp_b10, after this fp is in the
-          * range [.1,1) and exp_b10 is both the exponent and the digit
-          * *before* which the decimal point should be inserted
-          * (starting with 0 for the first digit).  Note that this
-          * works even if 10^exp_b10 is out of range because of the
-          * test on DBL_MAX above.
-          */
-         fp /= base;
-         while (fp >= 1) fp /= 10, ++exp_b10;
-
-         /* Because of the code above fp may, at this point, be
-          * less than .1, this is ok because the code below can
-          * handle the leading zeros this generates, so no attempt
-          * is made to correct that here.
-          */
-
-         {
-            int czero, clead, cdigits;
-            char exponent[10];
-
-            /* Allow up to two leading zeros - this will not lengthen
-             * the number compared to using E-n.
-             */
-            if (exp_b10 < 0 && exp_b10 > -3) /* PLUS 3 TOTAL 4 */
-            {
-               czero = -exp_b10; /* PLUS 2 digits: TOTAL 3 */
-               exp_b10 = 0;      /* Dot added below before first output. */
-            }
-            else
-               czero = 0;    /* No zeros to add */
-
-            /* Generate the digit list, stripping trailing zeros and
-             * inserting a '.' before a digit if the exponent is 0.
-             */
-            clead = czero; /* Count of leading zeros */
-            cdigits = 0;   /* Count of digits in list. */
-
-            do
-            {
-               double d;
-
-               fp *= 10.0;
-
-               /* Use modf here, not floor and subtract, so that
-                * the separation is done in one step.  At the end
-                * of the loop don't break the number into parts so
-                * that the final digit is rounded.
-                */
-               if (cdigits+czero-clead+1 < (int)precision)
-                  fp = modf(fp, &d);
-
-               else
-               {
-                  d = floor(fp + .5);
-
-                  if (d > 9.0)
-                  {
-                     /* Rounding up to 10, handle that here. */
-                     if (czero > 0)
-                     {
-                        --czero, d = 1;
-                        if (cdigits == 0) --clead;
-                     }
-
-                     else
-                     {
-                        while (cdigits > 0 && d > 9.0)
-                        {
-                           int ch = *--ascii;
-
-                           if (exp_b10 != (-1))
-                              ++exp_b10;
-
-                           else if (ch == 46)
-                           {
-                              ch = *--ascii, ++size;
-                              /* Advance exp_b10 to '1', so that the
-                               * decimal point happens after the
-                               * previous digit.
-                               */
-                              exp_b10 = 1;
-                           }
-
-                           --cdigits;
-                           d = ch - 47;  /* I.e. 1+(ch-48) */
-                        }
-
-                        /* Did we reach the beginning? If so adjust the
-                         * exponent but take into account the leading
-                         * decimal point.
-                         */
-                        if (d > 9.0)  /* cdigits == 0 */
-                        {
-                           if (exp_b10 == (-1))
-                           {
-                              /* Leading decimal point (plus zeros?), if
-                               * we lose the decimal point here it must
-                               * be reentered below.
-                               */
-                              int ch = *--ascii;
-
-                              if (ch == 46)
-                                 ++size, exp_b10 = 1;
-
-                              /* Else lost a leading zero, so 'exp_b10' is
-                               * still ok at (-1)
-                               */
-                           }
-                           else
-                              ++exp_b10;
-
-                           /* In all cases we output a '1' */
-                           d = 1.0;
-                        }
-                     }
-                  }
-                  fp = 0; /* Guarantees termination below. */
-               }
-
-               if (d == 0.0)
-               {
-                  ++czero;
-                  if (cdigits == 0) ++clead;
-               }
-
-               else
-               {
-                  /* Included embedded zeros in the digit count. */
-                  cdigits += czero - clead;
-                  clead = 0;
-
-                  while (czero > 0)
-                  {
-                     /* exp_b10 == (-1) means we just output the decimal
-                      * place - after the DP don't adjust 'exp_b10' any
-                      * more!
-                      */
-                     if (exp_b10 != (-1))
-                     {
-                        if (exp_b10 == 0) *ascii++ = 46, --size;
-                        /* PLUS 1: TOTAL 4 */
-                        --exp_b10;
-                     }
-                     *ascii++ = 48, --czero;
-                  }
-
-                  if (exp_b10 != (-1))
-                  {
-                     if (exp_b10 == 0) *ascii++ = 46, --size; /* counted
-                                                                 above */
-                     --exp_b10;
-                  }
-
-                  *ascii++ = (char)(48 + (int)d), ++cdigits;
-               }
-            }
-            while (cdigits+czero-clead < (int)precision && fp > DBL_MIN);
-
-            /* The total output count (max) is now 4+precision */
-
-            /* Check for an exponent, if we don't need one we are
-             * done and just need to terminate the string.  At
-             * this point exp_b10==(-1) is effectively if flag - it got
-             * to '-1' because of the decrement after outputing
-             * the decimal point above (the exponent required is
-             * *not* -1!)
-             */
-            if (exp_b10 >= (-1) && exp_b10 <= 2)
-            {
-               /* The following only happens if we didn't output the
-                * leading zeros above for negative exponent, so this
-                * doest add to the digit requirement.  Note that the
-                * two zeros here can only be output if the two leading
-                * zeros were *not* output, so this doesn't increase
-                * the output count.
-                */
-               while (--exp_b10 >= 0) *ascii++ = 48;
-
-               *ascii = 0;
-
-               /* Total buffer requirement (including the '\0') is
-                * 5+precision - see check at the start.
-                */
-               return;
-            }
-
-            /* Here if an exponent is required, adjust size for
-             * the digits we output but did not count.  The total
-             * digit output here so far is at most 1+precision - no
-             * decimal point and no leading or trailing zeros have
-             * been output.
-             */
-            size -= cdigits;
-
-            *ascii++ = 69, --size;    /* 'E': PLUS 1 TOTAL 2+precision */
-
-            /* The following use of an unsigned temporary avoids ambiguities in
-             * the signed arithmetic on exp_b10 and permits GCC at least to do
-             * better optimization.
-             */
-            {
-               unsigned int uexp_b10;
-
-               if (exp_b10 < 0)
-               {
-                  *ascii++ = 45, --size; /* '-': PLUS 1 TOTAL 3+precision */
-                  uexp_b10 = -exp_b10;
-               }
-
-               else
-                  uexp_b10 = exp_b10;
-
-               cdigits = 0;
-
-               while (uexp_b10 > 0)
-               {
-                  exponent[cdigits++] = (char)(48 + uexp_b10 % 10);
-                  uexp_b10 /= 10;
-               }
-            }
-
-            /* Need another size check here for the exponent digits, so
-             * this need not be considered above.
-             */
-            if ((int)size > cdigits)
-            {
-               while (cdigits > 0) *ascii++ = exponent[--cdigits];
-
-               *ascii = 0;
-
-               return;
-            }
-         }
-      }
-      else if (!(fp >= DBL_MIN))
-      {
-         *ascii++ = 48; /* '0' */
-         *ascii = 0;
-         return;
-      }
-      else
-      {
-         *ascii++ = 105; /* 'i' */
-         *ascii++ = 110; /* 'n' */
-         *ascii++ = 102; /* 'f' */
-         *ascii = 0;
-         return;
-      }
-   }
-
-   /* Here on buffer too small. */
-   png_error(png_ptr, "ASCII conversion buffer too small");
-}
-
-#  endif /* FLOATING_POINT */
-
-#  ifdef PNG_FIXED_POINT_SUPPORTED
-/* Function to format a fixed point value in ASCII.
- */
-void /* PRIVATE */
-png_ascii_from_fixed(png_structp png_ptr, png_charp ascii, png_size_t size,
-    png_fixed_point fp)
-{
-   /* Require space for 10 decimal digits, a decimal point, a minus sign and a
-    * trailing \0, 13 characters:
-    */
-   if (size > 12)
-   {
-      png_uint_32 num;
-
-      /* Avoid overflow here on the minimum integer. */
-      if (fp < 0)
-         *ascii++ = 45, --size, num = -fp;
-      else
-         num = fp;
-
-      if (num <= 0x80000000) /* else overflowed */
-      {
-         unsigned int ndigits = 0, first = 16 /* flag value */;
-         char digits[10];
-
-         while (num)
-         {
-            /* Split the low digit off num: */
-            unsigned int tmp = num/10;
-            num -= tmp*10;
-            digits[ndigits++] = (char)(48 + num);
-            /* Record the first non-zero digit, note that this is a number
-             * starting at 1, it's not actually the array index.
-             */
-            if (first == 16 && num > 0)
-               first = ndigits;
-            num = tmp;
-         }
-
-         if (ndigits > 0)
-         {
-            while (ndigits > 5) *ascii++ = digits[--ndigits];
-            /* The remaining digits are fractional digits, ndigits is '5' or
-             * smaller at this point.  It is certainly not zero.  Check for a
-             * non-zero fractional digit:
-             */
-            if (first <= 5)
-            {
-               unsigned int i;
-               *ascii++ = 46; /* decimal point */
-               /* ndigits may be <5 for small numbers, output leading zeros
-                * then ndigits digits to first:
-                */
-               i = 5;
-               while (ndigits < i) *ascii++ = 48, --i;
-               while (ndigits >= first) *ascii++ = digits[--ndigits];
-               /* Don't output the trailing zeros! */
-            }
-         }
-         else
-            *ascii++ = 48;
-
-         /* And null terminate the string: */
-         *ascii = 0;
-         return;
-      }
-   }
-
-   /* Here on buffer too small. */
-   png_error(png_ptr, "ASCII conversion buffer too small");
-}
-#   endif /* FIXED_POINT */
-#endif /* READ_SCAL */
-
-#if defined(PNG_FLOATING_POINT_SUPPORTED) && \
-   !defined(PNG_FIXED_POINT_MACRO_SUPPORTED)
-png_fixed_point
-png_fixed(png_structp png_ptr, double fp, png_const_charp text)
-{
-   double r = floor(100000 * fp + .5);
-
-   if (r > 2147483647. || r < -2147483648.)
-      png_fixed_error(png_ptr, text);
-
-   return (png_fixed_point)r;
-}
-#endif
-
-#if defined(PNG_READ_GAMMA_SUPPORTED) || \
-    defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG__READ_pHYs_SUPPORTED)
-/* muldiv functions */
-/* This API takes signed arguments and rounds the result to the nearest
- * integer (or, for a fixed point number - the standard argument - to
- * the nearest .00001).  Overflow and divide by zero are signalled in
- * the result, a boolean - true on success, false on overflow.
- */
-int
-png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times,
-    png_int_32 divisor)
-{
-   /* Return a * times / divisor, rounded. */
-   if (divisor != 0)
-   {
-      if (a == 0 || times == 0)
-      {
-         *res = 0;
-         return 1;
-      }
-      else
-      {
-#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
-         double r = a;
-         r *= times;
-         r /= divisor;
-         r = floor(r+.5);
-
-         /* A png_fixed_point is a 32-bit integer. */
-         if (r <= 2147483647. && r >= -2147483648.)
-         {
-            *res = (png_fixed_point)r;
-            return 1;
-         }
-#else
-         int negative = 0;
-         png_uint_32 A, T, D;
-         png_uint_32 s16, s32, s00;
-
-         if (a < 0)
-            negative = 1, A = -a;
-         else
-            A = a;
-
-         if (times < 0)
-            negative = !negative, T = -times;
-         else
-            T = times;
-
-         if (divisor < 0)
-            negative = !negative, D = -divisor;
-         else
-            D = divisor;
-
-         /* Following can't overflow because the arguments only
-          * have 31 bits each, however the result may be 32 bits.
-          */
-         s16 = (A >> 16) * (T & 0xffff) +
-                           (A & 0xffff) * (T >> 16);
-         /* Can't overflow because the a*times bit is only 30
-          * bits at most.
-          */
-         s32 = (A >> 16) * (T >> 16) + (s16 >> 16);
-         s00 = (A & 0xffff) * (T & 0xffff);
-
-         s16 = (s16 & 0xffff) << 16;
-         s00 += s16;
-
-         if (s00 < s16)
-            ++s32; /* carry */
-
-         if (s32 < D) /* else overflow */
-         {
-            /* s32.s00 is now the 64-bit product, do a standard
-             * division, we know that s32 < D, so the maximum
-             * required shift is 31.
-             */
-            int bitshift = 32;
-            png_fixed_point result = 0; /* NOTE: signed */
-
-            while (--bitshift >= 0)
-            {
-               png_uint_32 d32, d00;
-
-               if (bitshift > 0)
-                  d32 = D >> (32-bitshift), d00 = D << bitshift;
-
-               else
-                  d32 = 0, d00 = D;
-
-               if (s32 > d32)
-               {
-                  if (s00 < d00) --s32; /* carry */
-                  s32 -= d32, s00 -= d00, result += 1<<bitshift;
-               }
-
-               else
-                  if (s32 == d32 && s00 >= d00)
-                     s32 = 0, s00 -= d00, result += 1<<bitshift;
-            }
-
-            /* Handle the rounding. */
-            if (s00 >= (D >> 1))
-               ++result;
-
-            if (negative)
-               result = -result;
-
-            /* Check for overflow. */
-            if ((negative && result <= 0) || (!negative && result >= 0))
-            {
-               *res = result;
-               return 1;
-            }
-         }
-#endif
-      }
-   }
-
-   return 0;
-}
-#endif /* READ_GAMMA || INCH_CONVERSIONS */
-
-#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED)
-/* The following is for when the caller doesn't much care about the
- * result.
- */
-png_fixed_point
-png_muldiv_warn(png_structp png_ptr, png_fixed_point a, png_int_32 times,
-    png_int_32 divisor)
-{
-   png_fixed_point result;
-
-   if (png_muldiv(&result, a, times, divisor))
-      return result;
-
-   png_warning(png_ptr, "fixed point overflow ignored");
-   return 0;
-}
-#endif
-
-#ifdef PNG_READ_GAMMA_SUPPORTED /* more fixed point functions for gamma */
-/* Calculate a reciprocal, return 0 on div-by-zero or overflow. */
-png_fixed_point
-png_reciprocal(png_fixed_point a)
-{
-#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
-   double r = floor(1E10/a+.5);
-
-   if (r <= 2147483647. && r >= -2147483648.)
-      return (png_fixed_point)r;
-#else
-   png_fixed_point res;
-
-   if (png_muldiv(&res, 100000, 100000, a))
-      return res;
-#endif
-
-   return 0; /* error/overflow */
-}
-
-/* A local convenience routine. */
-static png_fixed_point
-png_product2(png_fixed_point a, png_fixed_point b)
-{
-   /* The required result is 1/a * 1/b; the following preserves accuracy. */
-#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
-   double r = a * 1E-5;
-   r *= b;
-   r = floor(r+.5);
-
-   if (r <= 2147483647. && r >= -2147483648.)
-      return (png_fixed_point)r;
-#else
-   png_fixed_point res;
-
-   if (png_muldiv(&res, a, b, 100000))
-      return res;
-#endif
-
-   return 0; /* overflow */
-}
-
-/* The inverse of the above. */
-png_fixed_point
-png_reciprocal2(png_fixed_point a, png_fixed_point b)
-{
-   /* The required result is 1/a * 1/b; the following preserves accuracy. */
-#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
-   double r = 1E15/a;
-   r /= b;
-   r = floor(r+.5);
-
-   if (r <= 2147483647. && r >= -2147483648.)
-      return (png_fixed_point)r;
-#else
-   /* This may overflow because the range of png_fixed_point isn't symmetric,
-    * but this API is only used for the product of file and screen gamma so it
-    * doesn't matter that the smallest number it can produce is 1/21474, not
-    * 1/100000
-    */
-   png_fixed_point res = png_product2(a, b);
-
-   if (res != 0)
-      return png_reciprocal(res);
-#endif
-
-   return 0; /* overflow */
-}
-#endif /* READ_GAMMA */
-
-#ifdef PNG_CHECK_cHRM_SUPPORTED
-/* Added at libpng version 1.2.34 (Dec 8, 2008) and 1.4.0 (Jan 2,
- * 2010: moved from pngset.c) */
-/*
- *    Multiply two 32-bit numbers, V1 and V2, using 32-bit
- *    arithmetic, to produce a 64-bit result in the HI/LO words.
- *
- *                  A B
- *                x C D
- *               ------
- *              AD || BD
- *        AC || CB || 0
- *
- *    where A and B are the high and low 16-bit words of V1,
- *    C and D are the 16-bit words of V2, AD is the product of
- *    A and D, and X || Y is (X << 16) + Y.
-*/
-
-void /* PRIVATE */
-png_64bit_product (long v1, long v2, unsigned long *hi_product,
-    unsigned long *lo_product)
-{
-   int a, b, c, d;
-   long lo, hi, x, y;
-
-   a = (v1 >> 16) & 0xffff;
-   b = v1 & 0xffff;
-   c = (v2 >> 16) & 0xffff;
-   d = v2 & 0xffff;
-
-   lo = b * d;                   /* BD */
-   x = a * d + c * b;            /* AD + CB */
-   y = ((lo >> 16) & 0xffff) + x;
-
-   lo = (lo & 0xffff) | ((y & 0xffff) << 16);
-   hi = (y >> 16) & 0xffff;
-
-   hi += a * c;                  /* AC */
-
-   *hi_product = (unsigned long)hi;
-   *lo_product = (unsigned long)lo;
-}
-#endif /* CHECK_cHRM */
-
-#ifdef PNG_READ_GAMMA_SUPPORTED /* gamma table code */
-#ifndef PNG_FLOATING_ARITHMETIC_SUPPORTED
-/* Fixed point gamma.
- *
- * To calculate gamma this code implements fast log() and exp() calls using only
- * fixed point arithmetic.  This code has sufficient precision for either 8-bit
- * or 16-bit sample values.
- *
- * The tables used here were calculated using simple 'bc' programs, but C double
- * precision floating point arithmetic would work fine.  The programs are given
- * at the head of each table.
- *
- * 8-bit log table
- *   This is a table of -log(value/255)/log(2) for 'value' in the range 128 to
- *   255, so it's the base 2 logarithm of a normalized 8-bit floating point
- *   mantissa.  The numbers are 32-bit fractions.
- */
-static png_uint_32
-png_8bit_l2[128] =
-{
-#  ifdef PNG_DO_BC
-      for (i=128;i<256;++i) { .5 - l(i/255)/l(2)*65536*65536; }
-#  else
-   4270715492U, 4222494797U, 4174646467U, 4127164793U, 4080044201U, 4033279239U,
-   3986864580U, 3940795015U, 3895065449U, 3849670902U, 3804606499U, 3759867474U,
-   3715449162U, 3671346997U, 3627556511U, 3584073329U, 3540893168U, 3498011834U,
-   3455425220U, 3413129301U, 3371120137U, 3329393864U, 3287946700U, 3246774933U,
-   3205874930U, 3165243125U, 3124876025U, 3084770202U, 3044922296U, 3005329011U,
-   2965987113U, 2926893432U, 2888044853U, 2849438323U, 2811070844U, 2772939474U,
-   2735041326U, 2697373562U, 2659933400U, 2622718104U, 2585724991U, 2548951424U,
-   2512394810U, 2476052606U, 2439922311U, 2404001468U, 2368287663U, 2332778523U,
-   2297471715U, 2262364947U, 2227455964U, 2192742551U, 2158222529U, 2123893754U,
-   2089754119U, 2055801552U, 2022034013U, 1988449497U, 1955046031U, 1921821672U,
-   1888774511U, 1855902668U, 1823204291U, 1790677560U, 1758320682U, 1726131893U,
-   1694109454U, 1662251657U, 1630556815U, 1599023271U, 1567649391U, 1536433567U,
-   1505374214U, 1474469770U, 1443718700U, 1413119487U, 1382670639U, 1352370686U,
-   1322218179U, 1292211689U, 1262349810U, 1232631153U, 1203054352U, 1173618059U,
-   1144320946U, 1115161701U, 1086139034U, 1057251672U, 1028498358U, 999877854U,
-   971388940U, 943030410U, 914801076U, 886699767U, 858725327U, 830876614U,
-   803152505U, 775551890U, 748073672U, 720716771U, 693480120U, 666362667U,
-   639363374U, 612481215U, 585715177U, 559064263U, 532527486U, 506103872U,
-   479792461U, 453592303U, 427502463U, 401522014U, 375650043U, 349885648U,
-   324227938U, 298676034U, 273229066U, 247886176U, 222646516U, 197509248U,
-   172473545U, 147538590U, 122703574U, 97967701U, 73330182U, 48790236U,
-   24347096U, 0U
-#  endif
-
-#if 0
-   /* The following are the values for 16-bit tables - these work fine for the
-    * 8-bit conversions but produce very slightly larger errors in the 16-bit
-    * log (about 1.2 as opposed to 0.7 absolute error in the final value).  To
-    * use these all the shifts below must be adjusted appropriately.
-    */
-   65166, 64430, 63700, 62976, 62257, 61543, 60835, 60132, 59434, 58741, 58054,
-   57371, 56693, 56020, 55352, 54689, 54030, 53375, 52726, 52080, 51439, 50803,
-   50170, 49542, 48918, 48298, 47682, 47070, 46462, 45858, 45257, 44661, 44068,
-   43479, 42894, 42312, 41733, 41159, 40587, 40020, 39455, 38894, 38336, 37782,
-   37230, 36682, 36137, 35595, 35057, 34521, 33988, 33459, 32932, 32408, 31887,
-   31369, 30854, 30341, 29832, 29325, 28820, 28319, 27820, 27324, 26830, 26339,
-   25850, 25364, 24880, 24399, 23920, 23444, 22970, 22499, 22029, 21562, 21098,
-   20636, 20175, 19718, 19262, 18808, 18357, 17908, 17461, 17016, 16573, 16132,
-   15694, 15257, 14822, 14390, 13959, 13530, 13103, 12678, 12255, 11834, 11415,
-   10997, 10582, 10168, 9756, 9346, 8937, 8531, 8126, 7723, 7321, 6921, 6523,
-   6127, 5732, 5339, 4947, 4557, 4169, 3782, 3397, 3014, 2632, 2251, 1872, 1495,
-   1119, 744, 372
-#endif
-};
-
-PNG_STATIC png_int_32
-png_log8bit(unsigned int x)
-{
-   unsigned int lg2 = 0;
-   /* Each time 'x' is multiplied by 2, 1 must be subtracted off the final log,
-    * because the log is actually negate that means adding 1.  The final
-    * returned value thus has the range 0 (for 255 input) to 7.994 (for 1
-    * input), return 7.99998 for the overflow (log 0) case - so the result is
-    * always at most 19 bits.
-    */
-   if ((x &= 0xff) == 0)
-      return 0xffffffff;
-
-   if ((x & 0xf0) == 0)
-      lg2  = 4, x <<= 4;
-
-   if ((x & 0xc0) == 0)
-      lg2 += 2, x <<= 2;
-
-   if ((x & 0x80) == 0)
-      lg2 += 1, x <<= 1;
-
-   /* result is at most 19 bits, so this cast is safe: */
-   return (png_int_32)((lg2 << 16) + ((png_8bit_l2[x-128]+32768)>>16));
-}
-
-/* The above gives exact (to 16 binary places) log2 values for 8-bit images,
- * for 16-bit images we use the most significant 8 bits of the 16-bit value to
- * get an approximation then multiply the approximation by a correction factor
- * determined by the remaining up to 8 bits.  This requires an additional step
- * in the 16-bit case.
- *
- * We want log2(value/65535), we have log2(v'/255), where:
- *
- *    value = v' * 256 + v''
- *          = v' * f
- *
- * So f is value/v', which is equal to (256+v''/v') since v' is in the range 128
- * to 255 and v'' is in the range 0 to 255 f will be in the range 256 to less
- * than 258.  The final factor also needs to correct for the fact that our 8-bit
- * value is scaled by 255, whereas the 16-bit values must be scaled by 65535.
- *
- * This gives a final formula using a calculated value 'x' which is value/v' and
- * scaling by 65536 to match the above table:
- *
- *   log2(x/257) * 65536
- *
- * Since these numbers are so close to '1' we can use simple linear
- * interpolation between the two end values 256/257 (result -368.61) and 258/257
- * (result 367.179).  The values used below are scaled by a further 64 to give
- * 16-bit precision in the interpolation:
- *
- * Start (256): -23591
- * Zero  (257):      0
- * End   (258):  23499
- */
-PNG_STATIC png_int_32
-png_log16bit(png_uint_32 x)
-{
-   unsigned int lg2 = 0;
-
-   /* As above, but now the input has 16 bits. */
-   if ((x &= 0xffff) == 0)
-      return 0xffffffff;
-
-   if ((x & 0xff00) == 0)
-      lg2  = 8, x <<= 8;
-
-   if ((x & 0xf000) == 0)
-      lg2 += 4, x <<= 4;
-
-   if ((x & 0xc000) == 0)
-      lg2 += 2, x <<= 2;
-
-   if ((x & 0x8000) == 0)
-      lg2 += 1, x <<= 1;
-
-   /* Calculate the base logarithm from the top 8 bits as a 28-bit fractional
-    * value.
-    */
-   lg2 <<= 28;
-   lg2 += (png_8bit_l2[(x>>8)-128]+8) >> 4;
-
-   /* Now we need to interpolate the factor, this requires a division by the top
-    * 8 bits.  Do this with maximum precision.
-    */
-   x = ((x << 16) + (x >> 9)) / (x >> 8);
-
-   /* Since we divided by the top 8 bits of 'x' there will be a '1' at 1<<24,
-    * the value at 1<<16 (ignoring this) will be 0 or 1; this gives us exactly
-    * 16 bits to interpolate to get the low bits of the result.  Round the
-    * answer.  Note that the end point values are scaled by 64 to retain overall
-    * precision and that 'lg2' is current scaled by an extra 12 bits, so adjust
-    * the overall scaling by 6-12.  Round at every step.
-    */
-   x -= 1U << 24;
-
-   if (x <= 65536U) /* <= '257' */
-      lg2 += ((23591U * (65536U-x)) + (1U << (16+6-12-1))) >> (16+6-12);
-
-   else
-      lg2 -= ((23499U * (x-65536U)) + (1U << (16+6-12-1))) >> (16+6-12);
-
-   /* Safe, because the result can't have more than 20 bits: */
-   return (png_int_32)((lg2 + 2048) >> 12);
-}
-
-/* The 'exp()' case must invert the above, taking a 20-bit fixed point
- * logarithmic value and returning a 16 or 8-bit number as appropriate.  In
- * each case only the low 16 bits are relevant - the fraction - since the
- * integer bits (the top 4) simply determine a shift.
- *
- * The worst case is the 16-bit distinction between 65535 and 65534, this
- * requires perhaps spurious accuracy in the decoding of the logarithm to
- * distinguish log2(65535/65534.5) - 10^-5 or 17 bits.  There is little chance
- * of getting this accuracy in practice.
- *
- * To deal with this the following exp() function works out the exponent of the
- * frational part of the logarithm by using an accurate 32-bit value from the
- * top four fractional bits then multiplying in the remaining bits.
- */
-static png_uint_32
-png_32bit_exp[16] =
-{
-#  ifdef PNG_DO_BC
-      for (i=0;i<16;++i) { .5 + e(-i/16*l(2))*2^32; }
-#  else
-   /* NOTE: the first entry is deliberately set to the maximum 32-bit value. */
-   4294967295U, 4112874773U, 3938502376U, 3771522796U, 3611622603U, 3458501653U,
-   3311872529U, 3171459999U, 3037000500U, 2908241642U, 2784941738U, 2666869345U,
-   2553802834U, 2445529972U, 2341847524U, 2242560872U
-#  endif
-};
-
-/* Adjustment table; provided to explain the numbers in the code below. */
-#ifdef PNG_DO_BC
-for (i=11;i>=0;--i){ print i, " ", (1 - e(-(2^i)/65536*l(2))) * 2^(32-i), "\n"}
-   11 44937.64284865548751208448
-   10 45180.98734845585101160448
-    9 45303.31936980687359311872
-    8 45364.65110595323018870784
-    7 45395.35850361789624614912
-    6 45410.72259715102037508096
-    5 45418.40724413220722311168
-    4 45422.25021786898173001728
-    3 45424.17186732298419044352
-    2 45425.13273269940811464704
-    1 45425.61317555035558641664
-    0 45425.85339951654943850496
-#endif
-
-PNG_STATIC png_uint_32
-png_exp(png_fixed_point x)
-{
-   if (x > 0 && x <= 0xfffff) /* Else overflow or zero (underflow) */
-   {
-      /* Obtain a 4-bit approximation */
-      png_uint_32 e = png_32bit_exp[(x >> 12) & 0xf];
-
-      /* Incorporate the low 12 bits - these decrease the returned value by
-       * multiplying by a number less than 1 if the bit is set.  The multiplier
-       * is determined by the above table and the shift. Notice that the values
-       * converge on 45426 and this is used to allow linear interpolation of the
-       * low bits.
-       */
-      if (x & 0x800)
-         e -= (((e >> 16) * 44938U) +  16U) >> 5;
-
-      if (x & 0x400)
-         e -= (((e >> 16) * 45181U) +  32U) >> 6;
-
-      if (x & 0x200)
-         e -= (((e >> 16) * 45303U) +  64U) >> 7;
-
-      if (x & 0x100)
-         e -= (((e >> 16) * 45365U) + 128U) >> 8;
-
-      if (x & 0x080)
-         e -= (((e >> 16) * 45395U) + 256U) >> 9;
-
-      if (x & 0x040)
-         e -= (((e >> 16) * 45410U) + 512U) >> 10;
-
-      /* And handle the low 6 bits in a single block. */
-      e -= (((e >> 16) * 355U * (x & 0x3fU)) + 256U) >> 9;
-
-      /* Handle the upper bits of x. */
-      e >>= x >> 16;
-      return e;
-   }
-
-   /* Check for overflow */
-   if (x <= 0)
-      return png_32bit_exp[0];
-
-   /* Else underflow */
-   return 0;
-}
-
-PNG_STATIC png_byte
-png_exp8bit(png_fixed_point lg2)
-{
-   /* Get a 32-bit value: */
-   png_uint_32 x = png_exp(lg2);
-
-   /* Convert the 32-bit value to 0..255 by multiplying by 256-1, note that the
-    * second, rounding, step can't overflow because of the first, subtraction,
-    * step.
-    */
-   x -= x >> 8;
-   return (png_byte)((x + 0x7fffffU) >> 24);
-}
-
-PNG_STATIC png_uint_16
-png_exp16bit(png_fixed_point lg2)
-{
-   /* Get a 32-bit value: */
-   png_uint_32 x = png_exp(lg2);
-
-   /* Convert the 32-bit value to 0..65535 by multiplying by 65536-1: */
-   x -= x >> 16;
-   return (png_uint_16)((x + 32767U) >> 16);
-}
-#endif /* FLOATING_ARITHMETIC */
-
-png_byte
-png_gamma_8bit_correct(unsigned int value, png_fixed_point gamma_val)
-{
-   if (value > 0 && value < 255)
-   {
-#     ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
-         double r = floor(255*pow(value/255.,gamma_val*.00001)+.5);
-         return (png_byte)r;
-#     else
-         png_int_32 lg2 = png_log8bit(value);
-         png_fixed_point res;
-
-         if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1))
-            return png_exp8bit(res);
-
-         /* Overflow. */
-         value = 0;
-#     endif
-   }
-
-   return (png_byte)value;
-}
-
-png_uint_16
-png_gamma_16bit_correct(unsigned int value, png_fixed_point gamma_val)
-{
-   if (value > 0 && value < 65535)
-   {
-#     ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
-         double r = floor(65535*pow(value/65535.,gamma_val*.00001)+.5);
-         return (png_uint_16)r;
-#     else
-         png_int_32 lg2 = png_log16bit(value);
-         png_fixed_point res;
-
-         if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1))
-            return png_exp16bit(res);
-
-         /* Overflow. */
-         value = 0;
-#     endif
-   }
-
-   return (png_uint_16)value;
-}
-
-/* This does the right thing based on the bit_depth field of the
- * png_struct, interpreting values as 8-bit or 16-bit.  While the result
- * is nominally a 16-bit value if bit depth is 8 then the result is
- * 8-bit (as are the arguments.)
- */
-png_uint_16 /* PRIVATE */
-png_gamma_correct(png_structp png_ptr, unsigned int value,
-    png_fixed_point gamma_val)
-{
-   if (png_ptr->bit_depth == 8)
-      return png_gamma_8bit_correct(value, gamma_val);
-
-   else
-      return png_gamma_16bit_correct(value, gamma_val);
-}
-
-/* This is the shared test on whether a gamma value is 'significant' - whether
- * it is worth doing gamma correction.
- */
-int /* PRIVATE */
-png_gamma_significant(png_fixed_point gamma_val)
-{
-   return gamma_val < PNG_FP_1 - PNG_GAMMA_THRESHOLD_FIXED ||
-       gamma_val > PNG_FP_1 + PNG_GAMMA_THRESHOLD_FIXED;
-}
-
-/* Internal function to build a single 16-bit table - the table consists of
- * 'num' 256-entry subtables, where 'num' is determined by 'shift' - the amount
- * to shift the input values right (or 16-number_of_signifiant_bits).
- *
- * The caller is responsible for ensuring that the table gets cleaned up on
- * png_error (i.e. if one of the mallocs below fails) - i.e. the *table argument
- * should be somewhere that will be cleaned.
- */
-static void
-png_build_16bit_table(png_structp png_ptr, png_uint_16pp *ptable,
-   PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val)
-{
-   /* Various values derived from 'shift': */
-   PNG_CONST unsigned int num = 1U << (8U - shift);
-   PNG_CONST unsigned int max = (1U << (16U - shift))-1U;
-   PNG_CONST unsigned int max_by_2 = 1U << (15U-shift);
-   unsigned int i;
-
-   png_uint_16pp table = *ptable =
-       (png_uint_16pp)png_calloc(png_ptr, num * png_sizeof(png_uint_16p));
-
-   for (i = 0; i < num; i++)
-   {
-      png_uint_16p sub_table = table[i] =
-          (png_uint_16p)png_malloc(png_ptr, 256 * png_sizeof(png_uint_16));
-
-      /* The 'threshold' test is repeated here because it can arise for one of
-       * the 16-bit tables even if the others don't hit it.
-       */
-      if (png_gamma_significant(gamma_val))
-      {
-         /* The old code would overflow at the end and this would cause the
-          * 'pow' function to return a result >1, resulting in an
-          * arithmetic error.  This code follows the spec exactly; ig is
-          * the recovered input sample, it always has 8-16 bits.
-          *
-          * We want input * 65535/max, rounded, the arithmetic fits in 32
-          * bits (unsigned) so long as max <= 32767.
-          */
-         unsigned int j;
-         for (j = 0; j < 256; j++)
-         {
-            png_uint_32 ig = (j << (8-shift)) + i;
-#           ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
-               /* Inline the 'max' scaling operation: */
-               double d = floor(65535*pow(ig/(double)max, gamma_val*.00001)+.5);
-               sub_table[j] = (png_uint_16)d;
-#           else
-               if (shift)
-                  ig = (ig * 65535U + max_by_2)/max;
-
-               sub_table[j] = png_gamma_16bit_correct(ig, gamma_val);
-#           endif
-         }
-      }
-      else
-      {
-         /* We must still build a table, but do it the fast way. */
-         unsigned int j;
-
-         for (j = 0; j < 256; j++)
-         {
-            png_uint_32 ig = (j << (8-shift)) + i;
-
-            if (shift)
-               ig = (ig * 65535U + max_by_2)/max;
-
-            sub_table[j] = (png_uint_16)ig;
-         }
-      }
-   }
-}
-
-/* NOTE: this function expects the *inverse* of the overall gamma transformation
- * required.
- */
-static void
-png_build_16to8_table(png_structp png_ptr, png_uint_16pp *ptable,
-   PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val)
-{
-   PNG_CONST unsigned int num = 1U << (8U - shift);
-   PNG_CONST unsigned int max = (1U << (16U - shift))-1U;
-   unsigned int i;
-   png_uint_32 last;
-
-   png_uint_16pp table = *ptable =
-       (png_uint_16pp)png_calloc(png_ptr, num * png_sizeof(png_uint_16p));
-
-   /* 'num' is the number of tables and also the number of low bits of the
-    * input 16-bit value used to select a table.  Each table is itself indexed
-    * by the high 8 bits of the value.
-    */
-   for (i = 0; i < num; i++)
-      table[i] = (png_uint_16p)png_malloc(png_ptr,
-          256 * png_sizeof(png_uint_16));
-
-   /* 'gamma_val' is set to the reciprocal of the value calculated above, so
-    * pow(out,g) is an *input* value.  'last' is the last input value set.
-    *
-    * In the loop 'i' is used to find output values.  Since the output is
-    * 8-bit there are only 256 possible values.  The tables are set up to
-    * select the closest possible output value for each input by finding
-    * the input value at the boundary between each pair of output values
-    * and filling the table up to that boundary with the lower output
-    * value.
-    *
-    * The boundary values are 0.5,1.5..253.5,254.5.  Since these are 9-bit
-    * values the code below uses a 16-bit value in i; the values start at
-    * 128.5 (for 0.5) and step by 257, for a total of 254 values (the last
-    * entries are filled with 255).  Start i at 128 and fill all 'last'
-    * table entries <= 'max'
-    */
-   last = 0;
-   for (i = 0; i < 255; ++i) /* 8-bit output value */
-   {
-      /* Find the corresponding maximum input value */
-      png_uint_16 out = (png_uint_16)(i * 257U); /* 16-bit output value */
-
-      /* Find the boundary value in 16 bits: */
-      png_uint_32 bound = png_gamma_16bit_correct(out+128U, gamma_val);
-
-      /* Adjust (round) to (16-shift) bits: */
-      bound = (bound * max + 32768U)/65535U + 1U;
-
-      while (last < bound)
-      {
-         table[last & (0xffU >> shift)][last >> (8U - shift)] = out;
-         last++;
-      }
-   }
-
-   /* And fill in the final entries. */
-   while (last < (num << 8))
-   {
-      table[last & (0xff >> shift)][last >> (8U - shift)] = 65535U;
-      last++;
-   }
-}
-
-/* Build a single 8-bit table: same as the 16-bit case but much simpler (and
- * typically much faster).  Note that libpng currently does no sBIT processing
- * (apparently contrary to the spec) so a 256-entry table is always generated.
- */
-static void
-png_build_8bit_table(png_structp png_ptr, png_bytepp ptable,
-   PNG_CONST png_fixed_point gamma_val)
-{
-   unsigned int i;
-   png_bytep table = *ptable = (png_bytep)png_malloc(png_ptr, 256);
-
-   if (png_gamma_significant(gamma_val)) for (i=0; i<256; i++)
-      table[i] = png_gamma_8bit_correct(i, gamma_val);
-
-   else for (i=0; i<256; ++i)
-      table[i] = (png_byte)i;
-}
-
-/* Used from png_read_destroy and below to release the memory used by the gamma
- * tables.
- */
-void /* PRIVATE */
-png_destroy_gamma_table(png_structp png_ptr)
-{
-   png_free(png_ptr, png_ptr->gamma_table);
-   png_ptr->gamma_table = NULL;
-
-   if (png_ptr->gamma_16_table != NULL)
-   {
-      int i;
-      int istop = (1 << (8 - png_ptr->gamma_shift));
-      for (i = 0; i < istop; i++)
-      {
-         png_free(png_ptr, png_ptr->gamma_16_table[i]);
-      }
-   png_free(png_ptr, png_ptr->gamma_16_table);
-   png_ptr->gamma_16_table = NULL;
-   }
-
-#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
-   defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
-   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
-   png_free(png_ptr, png_ptr->gamma_from_1);
-   png_ptr->gamma_from_1 = NULL;
-   png_free(png_ptr, png_ptr->gamma_to_1);
-   png_ptr->gamma_to_1 = NULL;
-
-   if (png_ptr->gamma_16_from_1 != NULL)
-   {
-      int i;
-      int istop = (1 << (8 - png_ptr->gamma_shift));
-      for (i = 0; i < istop; i++)
-      {
-         png_free(png_ptr, png_ptr->gamma_16_from_1[i]);
-      }
-   png_free(png_ptr, png_ptr->gamma_16_from_1);
-   png_ptr->gamma_16_from_1 = NULL;
-   }
-   if (png_ptr->gamma_16_to_1 != NULL)
-   {
-      int i;
-      int istop = (1 << (8 - png_ptr->gamma_shift));
-      for (i = 0; i < istop; i++)
-      {
-         png_free(png_ptr, png_ptr->gamma_16_to_1[i]);
-      }
-   png_free(png_ptr, png_ptr->gamma_16_to_1);
-   png_ptr->gamma_16_to_1 = NULL;
-   }
-#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
-}
-
-/* We build the 8- or 16-bit gamma tables here.  Note that for 16-bit
- * tables, we don't make a full table if we are reducing to 8-bit in
- * the future.  Note also how the gamma_16 tables are segmented so that
- * we don't need to allocate > 64K chunks for a full 16-bit table.
- */
-void /* PRIVATE */
-png_build_gamma_table(png_structp png_ptr, int bit_depth)
-{
-  png_debug(1, "in png_build_gamma_table");
-
-  /* Remove any existing table; this copes with multiple calls to
-   * png_read_update_info.  The warning is because building the gamma tables
-   * multiple times is a performance hit - it's harmless but the ability to call
-   * png_read_update_info() multiple times is new in 1.5.6 so it seems sensible
-   * to warn if the app introduces such a hit.
-   */
-  if (png_ptr->gamma_table != NULL || png_ptr->gamma_16_table != NULL)
-  {
-    png_warning(png_ptr, "gamma table being rebuilt");
-    png_destroy_gamma_table(png_ptr);
-  }
-
-  if (bit_depth <= 8)
-  {
-     png_build_8bit_table(png_ptr, &png_ptr->gamma_table,
-         png_ptr->screen_gamma > 0 ?  png_reciprocal2(png_ptr->gamma,
-         png_ptr->screen_gamma) : PNG_FP_1);
-
-#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
-   defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
-   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
-     if (png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY))
-     {
-        png_build_8bit_table(png_ptr, &png_ptr->gamma_to_1,
-            png_reciprocal(png_ptr->gamma));
-
-        png_build_8bit_table(png_ptr, &png_ptr->gamma_from_1,
-            png_ptr->screen_gamma > 0 ?  png_reciprocal(png_ptr->screen_gamma) :
-            png_ptr->gamma/* Probably doing rgb_to_gray */);
-     }
-#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
-  }
-  else
-  {
-     png_byte shift, sig_bit;
-
-     if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
-     {
-        sig_bit = png_ptr->sig_bit.red;
-
-        if (png_ptr->sig_bit.green > sig_bit)
-           sig_bit = png_ptr->sig_bit.green;
-
-        if (png_ptr->sig_bit.blue > sig_bit)
-           sig_bit = png_ptr->sig_bit.blue;
-     }
-     else
-        sig_bit = png_ptr->sig_bit.gray;
-
-     /* 16-bit gamma code uses this equation:
-      *
-      *   ov = table[(iv & 0xff) >> gamma_shift][iv >> 8]
-      *
-      * Where 'iv' is the input color value and 'ov' is the output value -
-      * pow(iv, gamma).
-      *
-      * Thus the gamma table consists of up to 256 256-entry tables.  The table
-      * is selected by the (8-gamma_shift) most significant of the low 8 bits of
-      * the color value then indexed by the upper 8 bits:
-      *
-      *   table[low bits][high 8 bits]
-      *
-      * So the table 'n' corresponds to all those 'iv' of:
-      *
-      *   <all high 8-bit values><n << gamma_shift>..<(n+1 << gamma_shift)-1>
-      *
-      */
-     if (sig_bit > 0 && sig_bit < 16U)
-        shift = (png_byte)(16U - sig_bit); /* shift == insignificant bits */
-
-     else
-        shift = 0; /* keep all 16 bits */
-
-     if (png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8))
-     {
-        /* PNG_MAX_GAMMA_8 is the number of bits to keep - effectively
-         * the significant bits in the *input* when the output will
-         * eventually be 8 bits.  By default it is 11.
-         */
-        if (shift < (16U - PNG_MAX_GAMMA_8))
-           shift = (16U - PNG_MAX_GAMMA_8);
-     }
-
-     if (shift > 8U)
-        shift = 8U; /* Guarantees at least one table! */
-
-     png_ptr->gamma_shift = shift;
-
-#ifdef PNG_16BIT_SUPPORTED
-     /* NOTE: prior to 1.5.4 this test used to include PNG_BACKGROUND (now
-      * PNG_COMPOSE).  This effectively smashed the background calculation for
-      * 16-bit output because the 8-bit table assumes the result will be reduced
-      * to 8 bits.
-      */
-     if (png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8))
-#endif
-         png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift,
-         png_ptr->screen_gamma > 0 ? png_product2(png_ptr->gamma,
-         png_ptr->screen_gamma) : PNG_FP_1);
-
-#ifdef PNG_16BIT_SUPPORTED
-     else
-         png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift,
-         png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->gamma,
-         png_ptr->screen_gamma) : PNG_FP_1);
-#endif
-
-#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
-   defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
-   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
-     if (png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY))
-     {
-        png_build_16bit_table(png_ptr, &png_ptr->gamma_16_to_1, shift,
-            png_reciprocal(png_ptr->gamma));
-
-        /* Notice that the '16 from 1' table should be full precision, however
-         * the lookup on this table still uses gamma_shift, so it can't be.
-         * TODO: fix this.
-         */
-        png_build_16bit_table(png_ptr, &png_ptr->gamma_16_from_1, shift,
-            png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) :
-            png_ptr->gamma/* Probably doing rgb_to_gray */);
-     }
-#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
-  }
-}
-#endif /* READ_GAMMA */
-#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
+
+/* png.c - location for general purpose libpng functions
+ *
+ * Last changed in libpng 1.6.16 [December 22, 2014]
+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+#include "pngpriv.h"
+
+/* Generate a compiler error if there is an old png.h in the search path. */
+typedef png_libpng_version_1_6_16 Your_png_h_is_not_version_1_6_16;
+
+/* Tells libpng that we have already handled the first "num_bytes" bytes
+ * of the PNG file signature.  If the PNG data is embedded into another
+ * stream we can set num_bytes = 8 so that libpng will not attempt to read
+ * or write any of the magic bytes before it starts on the IHDR.
+ */
+
+#ifdef PNG_READ_SUPPORTED
+void PNGAPI
+png_set_sig_bytes(png_structrp png_ptr, int num_bytes)
+{
+   png_debug(1, "in png_set_sig_bytes");
+
+   if (png_ptr == NULL)
+      return;
+
+   if (num_bytes > 8)
+      png_error(png_ptr, "Too many bytes for PNG signature");
+
+   png_ptr->sig_bytes = (png_byte)(num_bytes < 0 ? 0 : num_bytes);
+}
+
+/* Checks whether the supplied bytes match the PNG signature.  We allow
+ * checking less than the full 8-byte signature so that those apps that
+ * already read the first few bytes of a file to determine the file type
+ * can simply check the remaining bytes for extra assurance.  Returns
+ * an integer less than, equal to, or greater than zero if sig is found,
+ * respectively, to be less than, to match, or be greater than the correct
+ * PNG signature (this is the same behavior as strcmp, memcmp, etc).
+ */
+int PNGAPI
+png_sig_cmp(png_const_bytep sig, png_size_t start, png_size_t num_to_check)
+{
+   png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
+
+   if (num_to_check > 8)
+      num_to_check = 8;
+
+   else if (num_to_check < 1)
+      return (-1);
+
+   if (start > 7)
+      return (-1);
+
+   if (start + num_to_check > 8)
+      num_to_check = 8 - start;
+
+   return ((int)(memcmp(&sig[start], &png_signature[start], num_to_check)));
+}
+
+#endif /* READ */
+
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+/* Function to allocate memory for zlib */
+PNG_FUNCTION(voidpf /* PRIVATE */,
+png_zalloc,(voidpf png_ptr, uInt items, uInt size),PNG_ALLOCATED)
+{
+   png_alloc_size_t num_bytes = size;
+
+   if (png_ptr == NULL)
+      return NULL;
+
+   if (items >= (~(png_alloc_size_t)0)/size)
+   {
+      png_warning (png_voidcast(png_structrp, png_ptr),
+         "Potential overflow in png_zalloc()");
+      return NULL;
+   }
+
+   num_bytes *= items;
+   return png_malloc_warn(png_voidcast(png_structrp, png_ptr), num_bytes);
+}
+
+/* Function to free memory for zlib */
+void /* PRIVATE */
+png_zfree(voidpf png_ptr, voidpf ptr)
+{
+   png_free(png_voidcast(png_const_structrp,png_ptr), ptr);
+}
+
+/* Reset the CRC variable to 32 bits of 1's.  Care must be taken
+ * in case CRC is > 32 bits to leave the top bits 0.
+ */
+void /* PRIVATE */
+png_reset_crc(png_structrp png_ptr)
+{
+   /* The cast is safe because the crc is a 32 bit value. */
+   png_ptr->crc = (png_uint_32)crc32(0, Z_NULL, 0);
+}
+
+/* Calculate the CRC over a section of data.  We can only pass as
+ * much data to this routine as the largest single buffer size.  We
+ * also check that this data will actually be used before going to the
+ * trouble of calculating it.
+ */
+void /* PRIVATE */
+png_calculate_crc(png_structrp png_ptr, png_const_bytep ptr, png_size_t length)
+{
+   int need_crc = 1;
+
+   if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0)
+   {
+      if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
+          (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
+         need_crc = 0;
+   }
+
+   else /* critical */
+   {
+      if ((png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) != 0)
+         need_crc = 0;
+   }
+
+   /* 'uLong' is defined in zlib.h as unsigned long; this means that on some
+    * systems it is a 64 bit value.  crc32, however, returns 32 bits so the
+    * following cast is safe.  'uInt' may be no more than 16 bits, so it is
+    * necessary to perform a loop here.
+    */
+   if (need_crc != 0 && length > 0)
+   {
+      uLong crc = png_ptr->crc; /* Should never issue a warning */
+
+      do
+      {
+         uInt safe_length = (uInt)length;
+         if (safe_length == 0)
+            safe_length = (uInt)-1; /* evil, but safe */
+
+         crc = crc32(crc, ptr, safe_length);
+
+         /* The following should never issue compiler warnings; if they do the
+          * target system has characteristics that will probably violate other
+          * assumptions within the libpng code.
+          */
+         ptr += safe_length;
+         length -= safe_length;
+      }
+      while (length > 0);
+
+      /* And the following is always safe because the crc is only 32 bits. */
+      png_ptr->crc = (png_uint_32)crc;
+   }
+}
+
+/* Check a user supplied version number, called from both read and write
+ * functions that create a png_struct.
+ */
+int
+png_user_version_check(png_structrp png_ptr, png_const_charp user_png_ver)
+{
+     /* Libpng versions 1.0.0 and later are binary compatible if the version
+      * string matches through the second '.'; we must recompile any
+      * applications that use any older library version.
+      */
+
+   if (user_png_ver != NULL)
+   {
+      int i = -1;
+      int found_dots = 0;
+
+      do
+      {
+         i++;
+         if (user_png_ver[i] != PNG_LIBPNG_VER_STRING[i])
+            png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
+         if (user_png_ver[i] == '.')
+            found_dots++;
+      } while (found_dots < 2 && user_png_ver[i] != 0 &&
+            PNG_LIBPNG_VER_STRING[i] != 0);
+   }
+
+   else
+      png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
+
+   if ((png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH) != 0)
+   {
+#ifdef PNG_WARNINGS_SUPPORTED
+      size_t pos = 0;
+      char m[128];
+
+      pos = png_safecat(m, (sizeof m), pos,
+          "Application built with libpng-");
+      pos = png_safecat(m, (sizeof m), pos, user_png_ver);
+      pos = png_safecat(m, (sizeof m), pos, " but running with ");
+      pos = png_safecat(m, (sizeof m), pos, PNG_LIBPNG_VER_STRING);
+      PNG_UNUSED(pos)
+
+      png_warning(png_ptr, m);
+#endif
+
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+      png_ptr->flags = 0;
+#endif
+
+      return 0;
+   }
+
+   /* Success return. */
+   return 1;
+}
+
+/* Generic function to create a png_struct for either read or write - this
+ * contains the common initialization.
+ */
+PNG_FUNCTION(png_structp /* PRIVATE */,
+png_create_png_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
+    png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
+    png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED)
+{
+   png_struct create_struct;
+#  ifdef PNG_SETJMP_SUPPORTED
+      jmp_buf create_jmp_buf;
+#  endif
+
+   /* This temporary stack-allocated structure is used to provide a place to
+    * build enough context to allow the user provided memory allocator (if any)
+    * to be called.
+    */
+   memset(&create_struct, 0, (sizeof create_struct));
+
+   /* Added at libpng-1.2.6 */
+#  ifdef PNG_USER_LIMITS_SUPPORTED
+      create_struct.user_width_max = PNG_USER_WIDTH_MAX;
+      create_struct.user_height_max = PNG_USER_HEIGHT_MAX;
+
+#     ifdef PNG_USER_CHUNK_CACHE_MAX
+         /* Added at libpng-1.2.43 and 1.4.0 */
+         create_struct.user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX;
+#     endif
+
+#     ifdef PNG_USER_CHUNK_MALLOC_MAX
+         /* Added at libpng-1.2.43 and 1.4.1, required only for read but exists
+          * in png_struct regardless.
+          */
+         create_struct.user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX;
+#     endif
+#  endif
+
+   /* The following two API calls simply set fields in png_struct, so it is safe
+    * to do them now even though error handling is not yet set up.
+    */
+#  ifdef PNG_USER_MEM_SUPPORTED
+      png_set_mem_fn(&create_struct, mem_ptr, malloc_fn, free_fn);
+#  else
+      PNG_UNUSED(mem_ptr)
+      PNG_UNUSED(malloc_fn)
+      PNG_UNUSED(free_fn)
+#  endif
+
+   /* (*error_fn) can return control to the caller after the error_ptr is set,
+    * this will result in a memory leak unless the error_fn does something
+    * extremely sophisticated.  The design lacks merit but is implicit in the
+    * API.
+    */
+   png_set_error_fn(&create_struct, error_ptr, error_fn, warn_fn);
+
+#  ifdef PNG_SETJMP_SUPPORTED
+      if (!setjmp(create_jmp_buf))
+      {
+         /* Temporarily fake out the longjmp information until we have
+          * successfully completed this function.  This only works if we have
+          * setjmp() support compiled in, but it is safe - this stuff should
+          * never happen.
+          */
+         create_struct.jmp_buf_ptr = &create_jmp_buf;
+         create_struct.jmp_buf_size = 0; /*stack allocation*/
+         create_struct.longjmp_fn = longjmp;
+#  else
+      {
+#  endif
+         /* Call the general version checker (shared with read and write code):
+          */
+         if (png_user_version_check(&create_struct, user_png_ver) != 0)
+         {
+            png_structrp png_ptr = png_voidcast(png_structrp,
+               png_malloc_warn(&create_struct, (sizeof *png_ptr)));
+
+            if (png_ptr != NULL)
+            {
+               /* png_ptr->zstream holds a back-pointer to the png_struct, so
+                * this can only be done now:
+                */
+               create_struct.zstream.zalloc = png_zalloc;
+               create_struct.zstream.zfree = png_zfree;
+               create_struct.zstream.opaque = png_ptr;
+
+#              ifdef PNG_SETJMP_SUPPORTED
+                  /* Eliminate the local error handling: */
+                  create_struct.jmp_buf_ptr = NULL;
+                  create_struct.jmp_buf_size = 0;
+                  create_struct.longjmp_fn = 0;
+#              endif
+
+               *png_ptr = create_struct;
+
+               /* This is the successful return point */
+               return png_ptr;
+            }
+         }
+      }
+
+   /* A longjmp because of a bug in the application storage allocator or a
+    * simple failure to allocate the png_struct.
+    */
+   return NULL;
+}
+
+/* Allocate the memory for an info_struct for the application. */
+PNG_FUNCTION(png_infop,PNGAPI
+png_create_info_struct,(png_const_structrp png_ptr),PNG_ALLOCATED)
+{
+   png_inforp info_ptr;
+
+   png_debug(1, "in png_create_info_struct");
+
+   if (png_ptr == NULL)
+      return NULL;
+
+   /* Use the internal API that does not (or at least should not) error out, so
+    * that this call always returns ok.  The application typically sets up the
+    * error handling *after* creating the info_struct because this is the way it
+    * has always been done in 'example.c'.
+    */
+   info_ptr = png_voidcast(png_inforp, png_malloc_base(png_ptr,
+      (sizeof *info_ptr)));
+
+   if (info_ptr != NULL)
+      memset(info_ptr, 0, (sizeof *info_ptr));
+
+   return info_ptr;
+}
+
+/* This function frees the memory associated with a single info struct.
+ * Normally, one would use either png_destroy_read_struct() or
+ * png_destroy_write_struct() to free an info struct, but this may be
+ * useful for some applications.  From libpng 1.6.0 this function is also used
+ * internally to implement the png_info release part of the 'struct' destroy
+ * APIs.  This ensures that all possible approaches free the same data (all of
+ * it).
+ */
+void PNGAPI
+png_destroy_info_struct(png_const_structrp png_ptr, png_infopp info_ptr_ptr)
+{
+   png_inforp info_ptr = NULL;
+
+   png_debug(1, "in png_destroy_info_struct");
+
+   if (png_ptr == NULL)
+      return;
+
+   if (info_ptr_ptr != NULL)
+      info_ptr = *info_ptr_ptr;
+
+   if (info_ptr != NULL)
+   {
+      /* Do this first in case of an error below; if the app implements its own
+       * memory management this can lead to png_free calling png_error, which
+       * will abort this routine and return control to the app error handler.
+       * An infinite loop may result if it then tries to free the same info
+       * ptr.
+       */
+      *info_ptr_ptr = NULL;
+
+      png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
+      memset(info_ptr, 0, (sizeof *info_ptr));
+      png_free(png_ptr, info_ptr);
+   }
+}
+
+/* Initialize the info structure.  This is now an internal function (0.89)
+ * and applications using it are urged to use png_create_info_struct()
+ * instead.  Use deprecated in 1.6.0, internal use removed (used internally it
+ * is just a memset).
+ *
+ * NOTE: it is almost inconceivable that this API is used because it bypasses
+ * the user-memory mechanism and the user error handling/warning mechanisms in
+ * those cases where it does anything other than a memset.
+ */
+PNG_FUNCTION(void,PNGAPI
+png_info_init_3,(png_infopp ptr_ptr, png_size_t png_info_struct_size),
+   PNG_DEPRECATED)
+{
+   png_inforp info_ptr = *ptr_ptr;
+
+   png_debug(1, "in png_info_init_3");
+
+   if (info_ptr == NULL)
+      return;
+
+   if ((sizeof (png_info)) > png_info_struct_size)
+   {
+      *ptr_ptr = NULL;
+      /* The following line is why this API should not be used: */
+      free(info_ptr);
+      info_ptr = png_voidcast(png_inforp, png_malloc_base(NULL,
+         (sizeof *info_ptr)));
+      *ptr_ptr = info_ptr;
+   }
+
+   /* Set everything to 0 */
+   memset(info_ptr, 0, (sizeof *info_ptr));
+}
+
+/* The following API is not called internally */
+void PNGAPI
+png_data_freer(png_const_structrp png_ptr, png_inforp info_ptr,
+   int freer, png_uint_32 mask)
+{
+   png_debug(1, "in png_data_freer");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   if (freer == PNG_DESTROY_WILL_FREE_DATA)
+      info_ptr->free_me |= mask;
+
+   else if (freer == PNG_USER_WILL_FREE_DATA)
+      info_ptr->free_me &= ~mask;
+
+   else
+      png_error(png_ptr, "Unknown freer parameter in png_data_freer");
+}
+
+void PNGAPI
+png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask,
+   int num)
+{
+   png_debug(1, "in png_free_data");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+#ifdef PNG_TEXT_SUPPORTED
+   /* Free text item num or (if num == -1) all text items */
+   if (info_ptr->text != 0 &&
+       ((mask & PNG_FREE_TEXT) & info_ptr->free_me) != 0)
+   {
+      if (num != -1)
+      {
+         png_free(png_ptr, info_ptr->text[num].key);
+         info_ptr->text[num].key = NULL;
+      }
+
+      else
+      {
+         int i;
+
+         for (i = 0; i < info_ptr->num_text; i++)
+            png_free(png_ptr, info_ptr->text[i].key);
+
+         png_free(png_ptr, info_ptr->text);
+         info_ptr->text = NULL;
+         info_ptr->num_text = 0;
+      }
+   }
+#endif
+
+#ifdef PNG_tRNS_SUPPORTED
+   /* Free any tRNS entry */
+   if (((mask & PNG_FREE_TRNS) & info_ptr->free_me) != 0)
+   {
+      png_free(png_ptr, info_ptr->trans_alpha);
+      info_ptr->trans_alpha = NULL;
+      info_ptr->valid &= ~PNG_INFO_tRNS;
+   }
+#endif
+
+#ifdef PNG_sCAL_SUPPORTED
+   /* Free any sCAL entry */
+   if (((mask & PNG_FREE_SCAL) & info_ptr->free_me) != 0)
+   {
+      png_free(png_ptr, info_ptr->scal_s_width);
+      png_free(png_ptr, info_ptr->scal_s_height);
+      info_ptr->scal_s_width = NULL;
+      info_ptr->scal_s_height = NULL;
+      info_ptr->valid &= ~PNG_INFO_sCAL;
+   }
+#endif
+
+#ifdef PNG_pCAL_SUPPORTED
+   /* Free any pCAL entry */
+   if (((mask & PNG_FREE_PCAL) & info_ptr->free_me) != 0)
+   {
+      png_free(png_ptr, info_ptr->pcal_purpose);
+      png_free(png_ptr, info_ptr->pcal_units);
+      info_ptr->pcal_purpose = NULL;
+      info_ptr->pcal_units = NULL;
+
+      if (info_ptr->pcal_params != NULL)
+         {
+            int i;
+
+            for (i = 0; i < info_ptr->pcal_nparams; i++)
+               png_free(png_ptr, info_ptr->pcal_params[i]);
+
+            png_free(png_ptr, info_ptr->pcal_params);
+            info_ptr->pcal_params = NULL;
+         }
+      info_ptr->valid &= ~PNG_INFO_pCAL;
+   }
+#endif
+
+#ifdef PNG_iCCP_SUPPORTED
+   /* Free any profile entry */
+   if (((mask & PNG_FREE_ICCP) & info_ptr->free_me) != 0)
+   {
+      png_free(png_ptr, info_ptr->iccp_name);
+      png_free(png_ptr, info_ptr->iccp_profile);
+      info_ptr->iccp_name = NULL;
+      info_ptr->iccp_profile = NULL;
+      info_ptr->valid &= ~PNG_INFO_iCCP;
+   }
+#endif
+
+#ifdef PNG_sPLT_SUPPORTED
+   /* Free a given sPLT entry, or (if num == -1) all sPLT entries */
+   if (info_ptr->splt_palettes != 0 &&
+       ((mask & PNG_FREE_SPLT) & info_ptr->free_me) != 0)
+   {
+      if (num != -1)
+      {
+         png_free(png_ptr, info_ptr->splt_palettes[num].name);
+         png_free(png_ptr, info_ptr->splt_palettes[num].entries);
+         info_ptr->splt_palettes[num].name = NULL;
+         info_ptr->splt_palettes[num].entries = NULL;
+      }
+
+      else
+      {
+         if (info_ptr->splt_palettes_num != 0)
+         {
+            int i;
+
+            for (i = 0; i < info_ptr->splt_palettes_num; i++)
+            {
+               png_free(png_ptr, info_ptr->splt_palettes[i].name);
+               png_free(png_ptr, info_ptr->splt_palettes[i].entries);
+            }
+
+            png_free(png_ptr, info_ptr->splt_palettes);
+            info_ptr->splt_palettes = NULL;
+            info_ptr->splt_palettes_num = 0;
+         }
+         info_ptr->valid &= ~PNG_INFO_sPLT;
+      }
+   }
+#endif
+
+#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
+   if (info_ptr->unknown_chunks != 0 &&
+       ((mask & PNG_FREE_UNKN) & info_ptr->free_me) != 0)
+   {
+      if (num != -1)
+      {
+          png_free(png_ptr, info_ptr->unknown_chunks[num].data);
+          info_ptr->unknown_chunks[num].data = NULL;
+      }
+
+      else
+      {
+         int i;
+
+         if (info_ptr->unknown_chunks_num != 0)
+         {
+            for (i = 0; i < info_ptr->unknown_chunks_num; i++)
+               png_free(png_ptr, info_ptr->unknown_chunks[i].data);
+
+            png_free(png_ptr, info_ptr->unknown_chunks);
+            info_ptr->unknown_chunks = NULL;
+            info_ptr->unknown_chunks_num = 0;
+         }
+      }
+   }
+#endif
+
+#ifdef PNG_hIST_SUPPORTED
+   /* Free any hIST entry */
+   if (((mask & PNG_FREE_HIST) & info_ptr->free_me) != 0)
+   {
+      png_free(png_ptr, info_ptr->hist);
+      info_ptr->hist = NULL;
+      info_ptr->valid &= ~PNG_INFO_hIST;
+   }
+#endif
+
+   /* Free any PLTE entry that was internally allocated */
+   if (((mask & PNG_FREE_PLTE) & info_ptr->free_me) != 0)
+   {
+      png_free(png_ptr, info_ptr->palette);
+      info_ptr->palette = NULL;
+      info_ptr->valid &= ~PNG_INFO_PLTE;
+      info_ptr->num_palette = 0;
+   }
+
+#ifdef PNG_INFO_IMAGE_SUPPORTED
+   /* Free any image bits attached to the info structure */
+   if (((mask & PNG_FREE_ROWS) & info_ptr->free_me) != 0)
+   {
+      if (info_ptr->row_pointers != 0)
+      {
+         png_uint_32 row;
+         for (row = 0; row < info_ptr->height; row++)
+            png_free(png_ptr, info_ptr->row_pointers[row]);
+
+         png_free(png_ptr, info_ptr->row_pointers);
+         info_ptr->row_pointers = NULL;
+      }
+      info_ptr->valid &= ~PNG_INFO_IDAT;
+   }
+#endif
+
+   if (num != -1)
+      mask &= ~PNG_FREE_MUL;
+
+   info_ptr->free_me &= ~mask;
+}
+#endif /* READ || WRITE */
+
+/* This function returns a pointer to the io_ptr associated with the user
+ * functions.  The application should free any memory associated with this
+ * pointer before png_write_destroy() or png_read_destroy() are called.
+ */
+png_voidp PNGAPI
+png_get_io_ptr(png_const_structrp png_ptr)
+{
+   if (png_ptr == NULL)
+      return (NULL);
+
+   return (png_ptr->io_ptr);
+}
+
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+#  ifdef PNG_STDIO_SUPPORTED
+/* Initialize the default input/output functions for the PNG file.  If you
+ * use your own read or write routines, you can call either png_set_read_fn()
+ * or png_set_write_fn() instead of png_init_io().  If you have defined
+ * PNG_NO_STDIO or otherwise disabled PNG_STDIO_SUPPORTED, you must use a
+ * function of your own because "FILE *" isn't necessarily available.
+ */
+void PNGAPI
+png_init_io(png_structrp png_ptr, png_FILE_p fp)
+{
+   png_debug(1, "in png_init_io");
+
+   if (png_ptr == NULL)
+      return;
+
+   png_ptr->io_ptr = (png_voidp)fp;
+}
+#  endif
+
+#ifdef PNG_SAVE_INT_32_SUPPORTED
+/* The png_save_int_32 function assumes integers are stored in two's
+ * complement format.  If this isn't the case, then this routine needs to
+ * be modified to write data in two's complement format.  Note that,
+ * the following works correctly even if png_int_32 has more than 32 bits
+ * (compare the more complex code required on read for sign extension.)
+ */
+void PNGAPI
+png_save_int_32(png_bytep buf, png_int_32 i)
+{
+   buf[0] = (png_byte)((i >> 24) & 0xff);
+   buf[1] = (png_byte)((i >> 16) & 0xff);
+   buf[2] = (png_byte)((i >> 8) & 0xff);
+   buf[3] = (png_byte)(i & 0xff);
+}
+#endif
+
+#  ifdef PNG_TIME_RFC1123_SUPPORTED
+/* Convert the supplied time into an RFC 1123 string suitable for use in
+ * a "Creation Time" or other text-based time string.
+ */
+int PNGAPI
+png_convert_to_rfc1123_buffer(char out[29], png_const_timep ptime)
+{
+   static PNG_CONST char short_months[12][4] =
+        {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
+         "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
+
+   if (out == NULL)
+      return 0;
+
+   if (ptime->year > 9999 /* RFC1123 limitation */ ||
+       ptime->month == 0    ||  ptime->month > 12  ||
+       ptime->day   == 0    ||  ptime->day   > 31  ||
+       ptime->hour  > 23    ||  ptime->minute > 59 ||
+       ptime->second > 60)
+      return 0;
+
+   {
+      size_t pos = 0;
+      char number_buf[5]; /* enough for a four-digit year */
+
+#     define APPEND_STRING(string) pos = png_safecat(out, 29, pos, (string))
+#     define APPEND_NUMBER(format, value)\
+         APPEND_STRING(PNG_FORMAT_NUMBER(number_buf, format, (value)))
+#     define APPEND(ch) if (pos < 28) out[pos++] = (ch)
+
+      APPEND_NUMBER(PNG_NUMBER_FORMAT_u, (unsigned)ptime->day);
+      APPEND(' ');
+      APPEND_STRING(short_months[(ptime->month - 1)]);
+      APPEND(' ');
+      APPEND_NUMBER(PNG_NUMBER_FORMAT_u, ptime->year);
+      APPEND(' ');
+      APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->hour);
+      APPEND(':');
+      APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->minute);
+      APPEND(':');
+      APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->second);
+      APPEND_STRING(" +0000"); /* This reliably terminates the buffer */
+
+#     undef APPEND
+#     undef APPEND_NUMBER
+#     undef APPEND_STRING
+   }
+
+   return 1;
+}
+
+#     if PNG_LIBPNG_VER < 10700
+/* To do: remove the following from libpng-1.7 */
+/* Original API that uses a private buffer in png_struct.
+ * Deprecated because it causes png_struct to carry a spurious temporary
+ * buffer (png_struct::time_buffer), better to have the caller pass this in.
+ */
+png_const_charp PNGAPI
+png_convert_to_rfc1123(png_structrp png_ptr, png_const_timep ptime)
+{
+   if (png_ptr != NULL)
+   {
+      /* The only failure above if png_ptr != NULL is from an invalid ptime */
+      if (png_convert_to_rfc1123_buffer(png_ptr->time_buffer, ptime) == 0)
+         png_warning(png_ptr, "Ignoring invalid time value");
+
+      else
+         return png_ptr->time_buffer;
+   }
+
+   return NULL;
+}
+#     endif
+#  endif /* TIME_RFC1123 */
+
+#endif /* READ || WRITE */
+
+png_const_charp PNGAPI
+png_get_copyright(png_const_structrp png_ptr)
+{
+   PNG_UNUSED(png_ptr)  /* Silence compiler warning about unused png_ptr */
+#ifdef PNG_STRING_COPYRIGHT
+   return PNG_STRING_COPYRIGHT
+#else
+#  ifdef __STDC__
+   return PNG_STRING_NEWLINE \
+     "libpng version 1.6.16 - December 22, 2014" PNG_STRING_NEWLINE \
+     "Copyright (c) 1998-2014 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \
+     "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
+     "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \
+     PNG_STRING_NEWLINE;
+#  else
+      return "libpng version 1.6.16 - December 22, 2014\
+      Copyright (c) 1998-2014 Glenn Randers-Pehrson\
+      Copyright (c) 1996-1997 Andreas Dilger\
+      Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.";
+#  endif
+#endif
+}
+
+/* The following return the library version as a short string in the
+ * format 1.0.0 through 99.99.99zz.  To get the version of *.h files
+ * used with your application, print out PNG_LIBPNG_VER_STRING, which
+ * is defined in png.h.
+ * Note: now there is no difference between png_get_libpng_ver() and
+ * png_get_header_ver().  Due to the version_nn_nn_nn typedef guard,
+ * it is guaranteed that png.c uses the correct version of png.h.
+ */
+png_const_charp PNGAPI
+png_get_libpng_ver(png_const_structrp png_ptr)
+{
+   /* Version of *.c files used when building libpng */
+   return png_get_header_ver(png_ptr);
+}
+
+png_const_charp PNGAPI
+png_get_header_ver(png_const_structrp png_ptr)
+{
+   /* Version of *.h files used when building libpng */
+   PNG_UNUSED(png_ptr)  /* Silence compiler warning about unused png_ptr */
+   return PNG_LIBPNG_VER_STRING;
+}
+
+png_const_charp PNGAPI
+png_get_header_version(png_const_structrp png_ptr)
+{
+   /* Returns longer string containing both version and date */
+   PNG_UNUSED(png_ptr)  /* Silence compiler warning about unused png_ptr */
+#ifdef __STDC__
+   return PNG_HEADER_VERSION_STRING
+#  ifndef PNG_READ_SUPPORTED
+   "     (NO READ SUPPORT)"
+#  endif
+   PNG_STRING_NEWLINE;
+#else
+   return PNG_HEADER_VERSION_STRING;
+#endif
+}
+
+#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED
+/* NOTE: this routine is not used internally! */
+/* Build a grayscale palette.  Palette is assumed to be 1 << bit_depth
+ * large of png_color.  This lets grayscale images be treated as
+ * paletted.  Most useful for gamma correction and simplification
+ * of code.  This API is not used internally.
+ */
+void PNGAPI
+png_build_grayscale_palette(int bit_depth, png_colorp palette)
+{
+   int num_palette;
+   int color_inc;
+   int i;
+   int v;
+
+   png_debug(1, "in png_do_build_grayscale_palette");
+
+   if (palette == NULL)
+      return;
+
+   switch (bit_depth)
+   {
+      case 1:
+         num_palette = 2;
+         color_inc = 0xff;
+         break;
+
+      case 2:
+         num_palette = 4;
+         color_inc = 0x55;
+         break;
+
+      case 4:
+         num_palette = 16;
+         color_inc = 0x11;
+         break;
+
+      case 8:
+         num_palette = 256;
+         color_inc = 1;
+         break;
+
+      default:
+         num_palette = 0;
+         color_inc = 0;
+         break;
+   }
+
+   for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
+   {
+      palette[i].red = (png_byte)v;
+      palette[i].green = (png_byte)v;
+      palette[i].blue = (png_byte)v;
+   }
+}
+#endif
+
+#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
+int PNGAPI
+png_handle_as_unknown(png_const_structrp png_ptr, png_const_bytep chunk_name)
+{
+   /* Check chunk_name and return "keep" value if it's on the list, else 0 */
+   png_const_bytep p, p_end;
+
+   if (png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list == 0)
+      return PNG_HANDLE_CHUNK_AS_DEFAULT;
+
+   p_end = png_ptr->chunk_list;
+   p = p_end + png_ptr->num_chunk_list*5; /* beyond end */
+
+   /* The code is the fifth byte after each four byte string.  Historically this
+    * code was always searched from the end of the list, this is no longer
+    * necessary because the 'set' routine handles duplicate entries correcty.
+    */
+   do /* num_chunk_list > 0, so at least one */
+   {
+      p -= 5;
+
+      if (memcmp(chunk_name, p, 4) == 0)
+         return p[4];
+   }
+   while (p > p_end);
+
+   /* This means that known chunks should be processed and unknown chunks should
+    * be handled according to the value of png_ptr->unknown_default; this can be
+    * confusing because, as a result, there are two levels of defaulting for
+    * unknown chunks.
+    */
+   return PNG_HANDLE_CHUNK_AS_DEFAULT;
+}
+
+#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) ||\
+   defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED)
+int /* PRIVATE */
+png_chunk_unknown_handling(png_const_structrp png_ptr, png_uint_32 chunk_name)
+{
+   png_byte chunk_string[5];
+
+   PNG_CSTRING_FROM_CHUNK(chunk_string, chunk_name);
+   return png_handle_as_unknown(png_ptr, chunk_string);
+}
+#endif /* READ_UNKNOWN_CHUNKS || HANDLE_AS_UNKNOWN */
+#endif /* SET_UNKNOWN_CHUNKS */
+
+#ifdef PNG_READ_SUPPORTED
+/* This function, added to libpng-1.0.6g, is untested. */
+int PNGAPI
+png_reset_zstream(png_structrp png_ptr)
+{
+   if (png_ptr == NULL)
+      return Z_STREAM_ERROR;
+
+   /* WARNING: this resets the window bits to the maximum! */
+   return (inflateReset(&png_ptr->zstream));
+}
+#endif /* READ */
+
+/* This function was added to libpng-1.0.7 */
+png_uint_32 PNGAPI
+png_access_version_number(void)
+{
+   /* Version of *.c files used when building libpng */
+   return((png_uint_32)PNG_LIBPNG_VER);
+}
+
+
+
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+/* Ensure that png_ptr->zstream.msg holds some appropriate error message string.
+ * If it doesn't 'ret' is used to set it to something appropriate, even in cases
+ * like Z_OK or Z_STREAM_END where the error code is apparently a success code.
+ */
+void /* PRIVATE */
+png_zstream_error(png_structrp png_ptr, int ret)
+{
+   /* Translate 'ret' into an appropriate error string, priority is given to the
+    * one in zstream if set.  This always returns a string, even in cases like
+    * Z_OK or Z_STREAM_END where the error code is a success code.
+    */
+   if (png_ptr->zstream.msg == NULL) switch (ret)
+   {
+      default:
+      case Z_OK:
+         png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected zlib return code");
+         break;
+
+      case Z_STREAM_END:
+         /* Normal exit */
+         png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected end of LZ stream");
+         break;
+
+      case Z_NEED_DICT:
+         /* This means the deflate stream did not have a dictionary; this
+          * indicates a bogus PNG.
+          */
+         png_ptr->zstream.msg = PNGZ_MSG_CAST("missing LZ dictionary");
+         break;
+
+      case Z_ERRNO:
+         /* gz APIs only: should not happen */
+         png_ptr->zstream.msg = PNGZ_MSG_CAST("zlib IO error");
+         break;
+
+      case Z_STREAM_ERROR:
+         /* internal libpng error */
+         png_ptr->zstream.msg = PNGZ_MSG_CAST("bad parameters to zlib");
+         break;
+
+      case Z_DATA_ERROR:
+         png_ptr->zstream.msg = PNGZ_MSG_CAST("damaged LZ stream");
+         break;
+
+      case Z_MEM_ERROR:
+         png_ptr->zstream.msg = PNGZ_MSG_CAST("insufficient memory");
+         break;
+
+      case Z_BUF_ERROR:
+         /* End of input or output; not a problem if the caller is doing
+          * incremental read or write.
+          */
+         png_ptr->zstream.msg = PNGZ_MSG_CAST("truncated");
+         break;
+
+      case Z_VERSION_ERROR:
+         png_ptr->zstream.msg = PNGZ_MSG_CAST("unsupported zlib version");
+         break;
+
+      case PNG_UNEXPECTED_ZLIB_RETURN:
+         /* Compile errors here mean that zlib now uses the value co-opted in
+          * pngpriv.h for PNG_UNEXPECTED_ZLIB_RETURN; update the switch above
+          * and change pngpriv.h.  Note that this message is "... return",
+          * whereas the default/Z_OK one is "... return code".
+          */
+         png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected zlib return");
+         break;
+   }
+}
+
+/* png_convert_size: a PNGAPI but no longer in png.h, so deleted
+ * at libpng 1.5.5!
+ */
+
+/* Added at libpng version 1.2.34 and 1.4.0 (moved from pngset.c) */
+#ifdef PNG_GAMMA_SUPPORTED /* always set if COLORSPACE */
+static int
+png_colorspace_check_gamma(png_const_structrp png_ptr,
+   png_colorspacerp colorspace, png_fixed_point gAMA, int from)
+   /* This is called to check a new gamma value against an existing one.  The
+    * routine returns false if the new gamma value should not be written.
+    *
+    * 'from' says where the new gamma value comes from:
+    *
+    *    0: the new gamma value is the libpng estimate for an ICC profile
+    *    1: the new gamma value comes from a gAMA chunk
+    *    2: the new gamma value comes from an sRGB chunk
+    */
+{
+   png_fixed_point gtest;
+
+   if ((colorspace->flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 &&
+      (png_muldiv(&gtest, colorspace->gamma, PNG_FP_1, gAMA) == 0  ||
+      png_gamma_significant(gtest) != 0))
+   {
+      /* Either this is an sRGB image, in which case the calculated gamma
+       * approximation should match, or this is an image with a profile and the
+       * value libpng calculates for the gamma of the profile does not match the
+       * value recorded in the file.  The former, sRGB, case is an error, the
+       * latter is just a warning.
+       */
+      if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0 || from == 2)
+      {
+         png_chunk_report(png_ptr, "gamma value does not match sRGB",
+            PNG_CHUNK_ERROR);
+         /* Do not overwrite an sRGB value */
+         return from == 2;
+      }
+
+      else /* sRGB tag not involved */
+      {
+         png_chunk_report(png_ptr, "gamma value does not match libpng estimate",
+            PNG_CHUNK_WARNING);
+         return from == 1;
+      }
+   }
+
+   return 1;
+}
+
+void /* PRIVATE */
+png_colorspace_set_gamma(png_const_structrp png_ptr,
+   png_colorspacerp colorspace, png_fixed_point gAMA)
+{
+   /* Changed in libpng-1.5.4 to limit the values to ensure overflow can't
+    * occur.  Since the fixed point representation is asymetrical it is
+    * possible for 1/gamma to overflow the limit of 21474 and this means the
+    * gamma value must be at least 5/100000 and hence at most 20000.0.  For
+    * safety the limits here are a little narrower.  The values are 0.00016 to
+    * 6250.0, which are truly ridiculous gamma values (and will produce
+    * displays that are all black or all white.)
+    *
+    * In 1.6.0 this test replaces the ones in pngrutil.c, in the gAMA chunk
+    * handling code, which only required the value to be >0.
+    */
+   png_const_charp errmsg;
+
+   if (gAMA < 16 || gAMA > 625000000)
+      errmsg = "gamma value out of range";
+
+#  ifdef PNG_READ_gAMA_SUPPORTED
+      /* Allow the application to set the gamma value more than once */
+      else if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
+         (colorspace->flags & PNG_COLORSPACE_FROM_gAMA) != 0)
+         errmsg = "duplicate";
+#  endif
+
+   /* Do nothing if the colorspace is already invalid */
+   else if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)
+      return;
+
+   else
+   {
+      if (png_colorspace_check_gamma(png_ptr, colorspace, gAMA,
+          1/*from gAMA*/) != 0)
+      {
+         /* Store this gamma value. */
+         colorspace->gamma = gAMA;
+         colorspace->flags |=
+            (PNG_COLORSPACE_HAVE_GAMMA | PNG_COLORSPACE_FROM_gAMA);
+      }
+
+      /* At present if the check_gamma test fails the gamma of the colorspace is
+       * not updated however the colorspace is not invalidated.  This
+       * corresponds to the case where the existing gamma comes from an sRGB
+       * chunk or profile.  An error message has already been output.
+       */
+      return;
+   }
+
+   /* Error exit - errmsg has been set. */
+   colorspace->flags |= PNG_COLORSPACE_INVALID;
+   png_chunk_report(png_ptr, errmsg, PNG_CHUNK_WRITE_ERROR);
+}
+
+void /* PRIVATE */
+png_colorspace_sync_info(png_const_structrp png_ptr, png_inforp info_ptr)
+{
+   if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0)
+   {
+      /* Everything is invalid */
+      info_ptr->valid &= ~(PNG_INFO_gAMA|PNG_INFO_cHRM|PNG_INFO_sRGB|
+         PNG_INFO_iCCP);
+
+#     ifdef PNG_COLORSPACE_SUPPORTED
+         /* Clean up the iCCP profile now if it won't be used. */
+         png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, -1/*not used*/);
+#     else
+         PNG_UNUSED(png_ptr)
+#     endif
+   }
+
+   else
+   {
+#     ifdef PNG_COLORSPACE_SUPPORTED
+         /* Leave the INFO_iCCP flag set if the pngset.c code has already set
+          * it; this allows a PNG to contain a profile which matches sRGB and
+          * yet still have that profile retrievable by the application.
+          */
+         if ((info_ptr->colorspace.flags & PNG_COLORSPACE_MATCHES_sRGB) != 0)
+            info_ptr->valid |= PNG_INFO_sRGB;
+
+         else
+            info_ptr->valid &= ~PNG_INFO_sRGB;
+
+         if ((info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
+            info_ptr->valid |= PNG_INFO_cHRM;
+
+         else
+            info_ptr->valid &= ~PNG_INFO_cHRM;
+#     endif
+
+      if ((info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0)
+         info_ptr->valid |= PNG_INFO_gAMA;
+
+      else
+         info_ptr->valid &= ~PNG_INFO_gAMA;
+   }
+}
+
+#ifdef PNG_READ_SUPPORTED
+void /* PRIVATE */
+png_colorspace_sync(png_const_structrp png_ptr, png_inforp info_ptr)
+{
+   if (info_ptr == NULL) /* reduce code size; check here not in the caller */
+      return;
+
+   info_ptr->colorspace = png_ptr->colorspace;
+   png_colorspace_sync_info(png_ptr, info_ptr);
+}
+#endif
+#endif
+
+#ifdef PNG_COLORSPACE_SUPPORTED
+/* Added at libpng-1.5.5 to support read and write of true CIEXYZ values for
+ * cHRM, as opposed to using chromaticities.  These internal APIs return
+ * non-zero on a parameter error.  The X, Y and Z values are required to be
+ * positive and less than 1.0.
+ */
+static int
+png_xy_from_XYZ(png_xy *xy, const png_XYZ *XYZ)
+{
+   png_int_32 d, dwhite, whiteX, whiteY;
+
+   d = XYZ->red_X + XYZ->red_Y + XYZ->red_Z;
+   if (png_muldiv(&xy->redx, XYZ->red_X, PNG_FP_1, d) == 0)
+      return 1;
+   if (png_muldiv(&xy->redy, XYZ->red_Y, PNG_FP_1, d) == 0)
+      return 1;
+   dwhite = d;
+   whiteX = XYZ->red_X;
+   whiteY = XYZ->red_Y;
+
+   d = XYZ->green_X + XYZ->green_Y + XYZ->green_Z;
+   if (png_muldiv(&xy->greenx, XYZ->green_X, PNG_FP_1, d) == 0)
+      return 1;
+   if (png_muldiv(&xy->greeny, XYZ->green_Y, PNG_FP_1, d) == 0)
+      return 1;
+   dwhite += d;
+   whiteX += XYZ->green_X;
+   whiteY += XYZ->green_Y;
+
+   d = XYZ->blue_X + XYZ->blue_Y + XYZ->blue_Z;
+   if (png_muldiv(&xy->bluex, XYZ->blue_X, PNG_FP_1, d) == 0)
+      return 1;
+   if (png_muldiv(&xy->bluey, XYZ->blue_Y, PNG_FP_1, d) == 0)
+      return 1;
+   dwhite += d;
+   whiteX += XYZ->blue_X;
+   whiteY += XYZ->blue_Y;
+
+   /* The reference white is simply the sum of the end-point (X,Y,Z) vectors,
+    * thus:
+    */
+   if (png_muldiv(&xy->whitex, whiteX, PNG_FP_1, dwhite) == 0)
+      return 1;
+   if (png_muldiv(&xy->whitey, whiteY, PNG_FP_1, dwhite) == 0)
+      return 1;
+
+   return 0;
+}
+
+static int
+png_XYZ_from_xy(png_XYZ *XYZ, const png_xy *xy)
+{
+   png_fixed_point red_inverse, green_inverse, blue_scale;
+   png_fixed_point left, right, denominator;
+
+   /* Check xy and, implicitly, z.  Note that wide gamut color spaces typically
+    * have end points with 0 tristimulus values (these are impossible end
+    * points, but they are used to cover the possible colors.)
+    */
+   if (xy->redx < 0 || xy->redx > PNG_FP_1) return 1;
+   if (xy->redy < 0 || xy->redy > PNG_FP_1-xy->redx) return 1;
+   if (xy->greenx < 0 || xy->greenx > PNG_FP_1) return 1;
+   if (xy->greeny < 0 || xy->greeny > PNG_FP_1-xy->greenx) return 1;
+   if (xy->bluex < 0 || xy->bluex > PNG_FP_1) return 1;
+   if (xy->bluey < 0 || xy->bluey > PNG_FP_1-xy->bluex) return 1;
+   if (xy->whitex < 0 || xy->whitex > PNG_FP_1) return 1;
+   if (xy->whitey < 0 || xy->whitey > PNG_FP_1-xy->whitex) return 1;
+
+   /* The reverse calculation is more difficult because the original tristimulus
+    * value had 9 independent values (red,green,blue)x(X,Y,Z) however only 8
+    * derived values were recorded in the cHRM chunk;
+    * (red,green,blue,white)x(x,y).  This loses one degree of freedom and
+    * therefore an arbitrary ninth value has to be introduced to undo the
+    * original transformations.
+    *
+    * Think of the original end-points as points in (X,Y,Z) space.  The
+    * chromaticity values (c) have the property:
+    *
+    *           C
+    *   c = ---------
+    *       X + Y + Z
+    *
+    * For each c (x,y,z) from the corresponding original C (X,Y,Z).  Thus the
+    * three chromaticity values (x,y,z) for each end-point obey the
+    * relationship:
+    *
+    *   x + y + z = 1
+    *
+    * This describes the plane in (X,Y,Z) space that intersects each axis at the
+    * value 1.0; call this the chromaticity plane.  Thus the chromaticity
+    * calculation has scaled each end-point so that it is on the x+y+z=1 plane
+    * and chromaticity is the intersection of the vector from the origin to the
+    * (X,Y,Z) value with the chromaticity plane.
+    *
+    * To fully invert the chromaticity calculation we would need the three
+    * end-point scale factors, (red-scale, green-scale, blue-scale), but these
+    * were not recorded.  Instead we calculated the reference white (X,Y,Z) and
+    * recorded the chromaticity of this.  The reference white (X,Y,Z) would have
+    * given all three of the scale factors since:
+    *
+    *    color-C = color-c * color-scale
+    *    white-C = red-C + green-C + blue-C
+    *            = red-c*red-scale + green-c*green-scale + blue-c*blue-scale
+    *
+    * But cHRM records only white-x and white-y, so we have lost the white scale
+    * factor:
+    *
+    *    white-C = white-c*white-scale
+    *
+    * To handle this the inverse transformation makes an arbitrary assumption
+    * about white-scale:
+    *
+    *    Assume: white-Y = 1.0
+    *    Hence:  white-scale = 1/white-y
+    *    Or:     red-Y + green-Y + blue-Y = 1.0
+    *
+    * Notice the last statement of the assumption gives an equation in three of
+    * the nine values we want to calculate.  8 more equations come from the
+    * above routine as summarised at the top above (the chromaticity
+    * calculation):
+    *
+    *    Given: color-x = color-X / (color-X + color-Y + color-Z)
+    *    Hence: (color-x - 1)*color-X + color.x*color-Y + color.x*color-Z = 0
+    *
+    * This is 9 simultaneous equations in the 9 variables "color-C" and can be
+    * solved by Cramer's rule.  Cramer's rule requires calculating 10 9x9 matrix
+    * determinants, however this is not as bad as it seems because only 28 of
+    * the total of 90 terms in the various matrices are non-zero.  Nevertheless
+    * Cramer's rule is notoriously numerically unstable because the determinant
+    * calculation involves the difference of large, but similar, numbers.  It is
+    * difficult to be sure that the calculation is stable for real world values
+    * and it is certain that it becomes unstable where the end points are close
+    * together.
+    *
+    * So this code uses the perhaps slightly less optimal but more
+    * understandable and totally obvious approach of calculating color-scale.
+    *
+    * This algorithm depends on the precision in white-scale and that is
+    * (1/white-y), so we can immediately see that as white-y approaches 0 the
+    * accuracy inherent in the cHRM chunk drops off substantially.
+    *
+    * libpng arithmetic: a simple inversion of the above equations
+    * ------------------------------------------------------------
+    *
+    *    white_scale = 1/white-y
+    *    white-X = white-x * white-scale
+    *    white-Y = 1.0
+    *    white-Z = (1 - white-x - white-y) * white_scale
+    *
+    *    white-C = red-C + green-C + blue-C
+    *            = red-c*red-scale + green-c*green-scale + blue-c*blue-scale
+    *
+    * This gives us three equations in (red-scale,green-scale,blue-scale) where
+    * all the coefficients are now known:
+    *
+    *    red-x*red-scale + green-x*green-scale + blue-x*blue-scale
+    *       = white-x/white-y
+    *    red-y*red-scale + green-y*green-scale + blue-y*blue-scale = 1
+    *    red-z*red-scale + green-z*green-scale + blue-z*blue-scale
+    *       = (1 - white-x - white-y)/white-y
+    *
+    * In the last equation color-z is (1 - color-x - color-y) so we can add all
+    * three equations together to get an alternative third:
+    *
+    *    red-scale + green-scale + blue-scale = 1/white-y = white-scale
+    *
+    * So now we have a Cramer's rule solution where the determinants are just
+    * 3x3 - far more tractible.  Unfortunately 3x3 determinants still involve
+    * multiplication of three coefficients so we can't guarantee to avoid
+    * overflow in the libpng fixed point representation.  Using Cramer's rule in
+    * floating point is probably a good choice here, but it's not an option for
+    * fixed point.  Instead proceed to simplify the first two equations by
+    * eliminating what is likely to be the largest value, blue-scale:
+    *
+    *    blue-scale = white-scale - red-scale - green-scale
+    *
+    * Hence:
+    *
+    *    (red-x - blue-x)*red-scale + (green-x - blue-x)*green-scale =
+    *                (white-x - blue-x)*white-scale
+    *
+    *    (red-y - blue-y)*red-scale + (green-y - blue-y)*green-scale =
+    *                1 - blue-y*white-scale
+    *
+    * And now we can trivially solve for (red-scale,green-scale):
+    *
+    *    green-scale =
+    *                (white-x - blue-x)*white-scale - (red-x - blue-x)*red-scale
+    *                -----------------------------------------------------------
+    *                                  green-x - blue-x
+    *
+    *    red-scale =
+    *                1 - blue-y*white-scale - (green-y - blue-y) * green-scale
+    *                ---------------------------------------------------------
+    *                                  red-y - blue-y
+    *
+    * Hence:
+    *
+    *    red-scale =
+    *          ( (green-x - blue-x) * (white-y - blue-y) -
+    *            (green-y - blue-y) * (white-x - blue-x) ) / white-y
+    * -------------------------------------------------------------------------
+    *  (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x)
+    *
+    *    green-scale =
+    *          ( (red-y - blue-y) * (white-x - blue-x) -
+    *            (red-x - blue-x) * (white-y - blue-y) ) / white-y
+    * -------------------------------------------------------------------------
+    *  (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x)
+    *
+    * Accuracy:
+    * The input values have 5 decimal digits of accuracy.  The values are all in
+    * the range 0 < value < 1, so simple products are in the same range but may
+    * need up to 10 decimal digits to preserve the original precision and avoid
+    * underflow.  Because we are using a 32-bit signed representation we cannot
+    * match this; the best is a little over 9 decimal digits, less than 10.
+    *
+    * The approach used here is to preserve the maximum precision within the
+    * signed representation.  Because the red-scale calculation above uses the
+    * difference between two products of values that must be in the range -1..+1
+    * it is sufficient to divide the product by 7; ceil(100,000/32767*2).  The
+    * factor is irrelevant in the calculation because it is applied to both
+    * numerator and denominator.
+    *
+    * Note that the values of the differences of the products of the
+    * chromaticities in the above equations tend to be small, for example for
+    * the sRGB chromaticities they are:
+    *
+    * red numerator:    -0.04751
+    * green numerator:  -0.08788
+    * denominator:      -0.2241 (without white-y multiplication)
+    *
+    *  The resultant Y coefficients from the chromaticities of some widely used
+    *  color space definitions are (to 15 decimal places):
+    *
+    *  sRGB
+    *    0.212639005871510 0.715168678767756 0.072192315360734
+    *  Kodak ProPhoto
+    *    0.288071128229293 0.711843217810102 0.000085653960605
+    *  Adobe RGB
+    *    0.297344975250536 0.627363566255466 0.075291458493998
+    *  Adobe Wide Gamut RGB
+    *    0.258728243040113 0.724682314948566 0.016589442011321
+    */
+   /* By the argument, above overflow should be impossible here. The return
+    * value of 2 indicates an internal error to the caller.
+    */
+   if (png_muldiv(&left, xy->greenx-xy->bluex, xy->redy - xy->bluey, 7) == 0)
+      return 2;
+   if (png_muldiv(&right, xy->greeny-xy->bluey, xy->redx - xy->bluex, 7) == 0)
+      return 2;
+   denominator = left - right;
+
+   /* Now find the red numerator. */
+   if (png_muldiv(&left, xy->greenx-xy->bluex, xy->whitey-xy->bluey, 7) == 0)
+      return 2;
+   if (png_muldiv(&right, xy->greeny-xy->bluey, xy->whitex-xy->bluex, 7) == 0)
+      return 2;
+
+   /* Overflow is possible here and it indicates an extreme set of PNG cHRM
+    * chunk values.  This calculation actually returns the reciprocal of the
+    * scale value because this allows us to delay the multiplication of white-y
+    * into the denominator, which tends to produce a small number.
+    */
+   if (png_muldiv(&red_inverse, xy->whitey, denominator, left-right) == 0 ||
+       red_inverse <= xy->whitey /* r+g+b scales = white scale */)
+      return 1;
+
+   /* Similarly for green_inverse: */
+   if (png_muldiv(&left, xy->redy-xy->bluey, xy->whitex-xy->bluex, 7) == 0)
+      return 2;
+   if (png_muldiv(&right, xy->redx-xy->bluex, xy->whitey-xy->bluey, 7) == 0)
+      return 2;
+   if (png_muldiv(&green_inverse, xy->whitey, denominator, left-right) == 0 ||
+       green_inverse <= xy->whitey)
+      return 1;
+
+   /* And the blue scale, the checks above guarantee this can't overflow but it
+    * can still produce 0 for extreme cHRM values.
+    */
+   blue_scale = png_reciprocal(xy->whitey) - png_reciprocal(red_inverse) -
+       png_reciprocal(green_inverse);
+   if (blue_scale <= 0)
+      return 1;
+
+
+   /* And fill in the png_XYZ: */
+   if (png_muldiv(&XYZ->red_X, xy->redx, PNG_FP_1, red_inverse) == 0)
+      return 1;
+   if (png_muldiv(&XYZ->red_Y, xy->redy, PNG_FP_1, red_inverse) == 0)
+      return 1;
+   if (png_muldiv(&XYZ->red_Z, PNG_FP_1 - xy->redx - xy->redy, PNG_FP_1,
+       red_inverse) == 0)
+      return 1;
+
+   if (png_muldiv(&XYZ->green_X, xy->greenx, PNG_FP_1, green_inverse) == 0)
+      return 1;
+   if (png_muldiv(&XYZ->green_Y, xy->greeny, PNG_FP_1, green_inverse) == 0)
+      return 1;
+   if (png_muldiv(&XYZ->green_Z, PNG_FP_1 - xy->greenx - xy->greeny, PNG_FP_1,
+       green_inverse) == 0)
+      return 1;
+
+   if (png_muldiv(&XYZ->blue_X, xy->bluex, blue_scale, PNG_FP_1) == 0)
+      return 1;
+   if (png_muldiv(&XYZ->blue_Y, xy->bluey, blue_scale, PNG_FP_1) == 0)
+      return 1;
+   if (png_muldiv(&XYZ->blue_Z, PNG_FP_1 - xy->bluex - xy->bluey, blue_scale,
+       PNG_FP_1) == 0)
+      return 1;
+
+   return 0; /*success*/
+}
+
+static int
+png_XYZ_normalize(png_XYZ *XYZ)
+{
+   png_int_32 Y;
+
+   if (XYZ->red_Y < 0 || XYZ->green_Y < 0 || XYZ->blue_Y < 0 ||
+      XYZ->red_X < 0 || XYZ->green_X < 0 || XYZ->blue_X < 0 ||
+      XYZ->red_Z < 0 || XYZ->green_Z < 0 || XYZ->blue_Z < 0)
+      return 1;
+
+   /* Normalize by scaling so the sum of the end-point Y values is PNG_FP_1.
+    * IMPLEMENTATION NOTE: ANSI requires signed overflow not to occur, therefore
+    * relying on addition of two positive values producing a negative one is not
+    * safe.
+    */
+   Y = XYZ->red_Y;
+   if (0x7fffffff - Y < XYZ->green_X)
+      return 1;
+   Y += XYZ->green_Y;
+   if (0x7fffffff - Y < XYZ->blue_X)
+      return 1;
+   Y += XYZ->blue_Y;
+
+   if (Y != PNG_FP_1)
+   {
+      if (png_muldiv(&XYZ->red_X, XYZ->red_X, PNG_FP_1, Y) == 0)
+         return 1;
+      if (png_muldiv(&XYZ->red_Y, XYZ->red_Y, PNG_FP_1, Y) == 0)
+         return 1;
+      if (png_muldiv(&XYZ->red_Z, XYZ->red_Z, PNG_FP_1, Y) == 0)
+         return 1;
+
+      if (png_muldiv(&XYZ->green_X, XYZ->green_X, PNG_FP_1, Y) == 0)
+         return 1;
+      if (png_muldiv(&XYZ->green_Y, XYZ->green_Y, PNG_FP_1, Y) == 0)
+         return 1;
+      if (png_muldiv(&XYZ->green_Z, XYZ->green_Z, PNG_FP_1, Y) == 0)
+         return 1;
+
+      if (png_muldiv(&XYZ->blue_X, XYZ->blue_X, PNG_FP_1, Y) == 0)
+         return 1;
+      if (png_muldiv(&XYZ->blue_Y, XYZ->blue_Y, PNG_FP_1, Y) == 0)
+         return 1;
+      if (png_muldiv(&XYZ->blue_Z, XYZ->blue_Z, PNG_FP_1, Y) == 0)
+         return 1;
+   }
+
+   return 0;
+}
+
+static int
+png_colorspace_endpoints_match(const png_xy *xy1, const png_xy *xy2, int delta)
+{
+   /* Allow an error of +/-0.01 (absolute value) on each chromaticity */
+   if (PNG_OUT_OF_RANGE(xy1->whitex, xy2->whitex,delta) ||
+       PNG_OUT_OF_RANGE(xy1->whitey, xy2->whitey,delta) ||
+       PNG_OUT_OF_RANGE(xy1->redx,   xy2->redx,  delta) ||
+       PNG_OUT_OF_RANGE(xy1->redy,   xy2->redy,  delta) ||
+       PNG_OUT_OF_RANGE(xy1->greenx, xy2->greenx,delta) ||
+       PNG_OUT_OF_RANGE(xy1->greeny, xy2->greeny,delta) ||
+       PNG_OUT_OF_RANGE(xy1->bluex,  xy2->bluex, delta) ||
+       PNG_OUT_OF_RANGE(xy1->bluey,  xy2->bluey, delta))
+      return 0;
+   return 1;
+}
+
+/* Added in libpng-1.6.0, a different check for the validity of a set of cHRM
+ * chunk chromaticities.  Earlier checks used to simply look for the overflow
+ * condition (where the determinant of the matrix to solve for XYZ ends up zero
+ * because the chromaticity values are not all distinct.)  Despite this it is
+ * theoretically possible to produce chromaticities that are apparently valid
+ * but that rapidly degrade to invalid, potentially crashing, sets because of
+ * arithmetic inaccuracies when calculations are performed on them.  The new
+ * check is to round-trip xy -> XYZ -> xy and then check that the result is
+ * within a small percentage of the original.
+ */
+static int
+png_colorspace_check_xy(png_XYZ *XYZ, const png_xy *xy)
+{
+   int result;
+   png_xy xy_test;
+
+   /* As a side-effect this routine also returns the XYZ endpoints. */
+   result = png_XYZ_from_xy(XYZ, xy);
+   if (result != 0)
+      return result;
+
+   result = png_xy_from_XYZ(&xy_test, XYZ);
+   if (result != 0)
+      return result;
+
+   if (png_colorspace_endpoints_match(xy, &xy_test,
+       5/*actually, the math is pretty accurate*/) != 0)
+      return 0;
+
+   /* Too much slip */
+   return 1;
+}
+
+/* This is the check going the other way.  The XYZ is modified to normalize it
+ * (another side-effect) and the xy chromaticities are returned.
+ */
+static int
+png_colorspace_check_XYZ(png_xy *xy, png_XYZ *XYZ)
+{
+   int result;
+   png_XYZ XYZtemp;
+
+   result = png_XYZ_normalize(XYZ);
+   if (result != 0)
+      return result;
+
+   result = png_xy_from_XYZ(xy, XYZ);
+   if (result != 0)
+      return result;
+
+   XYZtemp = *XYZ;
+   return png_colorspace_check_xy(&XYZtemp, xy);
+}
+
+/* Used to check for an endpoint match against sRGB */
+static const png_xy sRGB_xy = /* From ITU-R BT.709-3 */
+{
+   /* color      x       y */
+   /* red   */ 64000, 33000,
+   /* green */ 30000, 60000,
+   /* blue  */ 15000,  6000,
+   /* white */ 31270, 32900
+};
+
+static int
+png_colorspace_set_xy_and_XYZ(png_const_structrp png_ptr,
+   png_colorspacerp colorspace, const png_xy *xy, const png_XYZ *XYZ,
+   int preferred)
+{
+   if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)
+      return 0;
+
+   /* The consistency check is performed on the chromaticities; this factors out
+    * variations because of the normalization (or not) of the end point Y
+    * values.
+    */
+   if (preferred < 2 &&
+       (colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
+   {
+      /* The end points must be reasonably close to any we already have.  The
+       * following allows an error of up to +/-.001
+       */
+      if (png_colorspace_endpoints_match(xy, &colorspace->end_points_xy,
+          100) == 0)
+      {
+         colorspace->flags |= PNG_COLORSPACE_INVALID;
+         png_benign_error(png_ptr, "inconsistent chromaticities");
+         return 0; /* failed */
+      }
+
+      /* Only overwrite with preferred values */
+      if (preferred == 0)
+         return 1; /* ok, but no change */
+   }
+
+   colorspace->end_points_xy = *xy;
+   colorspace->end_points_XYZ = *XYZ;
+   colorspace->flags |= PNG_COLORSPACE_HAVE_ENDPOINTS;
+
+   /* The end points are normally quoted to two decimal digits, so allow +/-0.01
+    * on this test.
+    */
+   if (png_colorspace_endpoints_match(xy, &sRGB_xy, 1000) != 0)
+      colorspace->flags |= PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB;
+
+   else
+      colorspace->flags &= PNG_COLORSPACE_CANCEL(
+         PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB);
+
+   return 2; /* ok and changed */
+}
+
+int /* PRIVATE */
+png_colorspace_set_chromaticities(png_const_structrp png_ptr,
+   png_colorspacerp colorspace, const png_xy *xy, int preferred)
+{
+   /* We must check the end points to ensure they are reasonable - in the past
+    * color management systems have crashed as a result of getting bogus
+    * colorant values, while this isn't the fault of libpng it is the
+    * responsibility of libpng because PNG carries the bomb and libpng is in a
+    * position to protect against it.
+    */
+   png_XYZ XYZ;
+
+   switch (png_colorspace_check_xy(&XYZ, xy))
+   {
+      case 0: /* success */
+         return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, xy, &XYZ,
+            preferred);
+
+      case 1:
+         /* We can't invert the chromaticities so we can't produce value XYZ
+          * values.  Likely as not a color management system will fail too.
+          */
+         colorspace->flags |= PNG_COLORSPACE_INVALID;
+         png_benign_error(png_ptr, "invalid chromaticities");
+         break;
+
+      default:
+         /* libpng is broken; this should be a warning but if it happens we
+          * want error reports so for the moment it is an error.
+          */
+         colorspace->flags |= PNG_COLORSPACE_INVALID;
+         png_error(png_ptr, "internal error checking chromaticities");
+         break;
+   }
+
+   return 0; /* failed */
+}
+
+int /* PRIVATE */
+png_colorspace_set_endpoints(png_const_structrp png_ptr,
+   png_colorspacerp colorspace, const png_XYZ *XYZ_in, int preferred)
+{
+   png_XYZ XYZ = *XYZ_in;
+   png_xy xy;
+
+   switch (png_colorspace_check_XYZ(&xy, &XYZ))
+   {
+      case 0:
+         return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, &xy, &XYZ,
+            preferred);
+
+      case 1:
+         /* End points are invalid. */
+         colorspace->flags |= PNG_COLORSPACE_INVALID;
+         png_benign_error(png_ptr, "invalid end points");
+         break;
+
+      default:
+         colorspace->flags |= PNG_COLORSPACE_INVALID;
+         png_error(png_ptr, "internal error checking chromaticities");
+         break;
+   }
+
+   return 0; /* failed */
+}
+
+#if defined(PNG_sRGB_SUPPORTED) || defined(PNG_iCCP_SUPPORTED)
+/* Error message generation */
+static char
+png_icc_tag_char(png_uint_32 byte)
+{
+   byte &= 0xff;
+   if (byte >= 32 && byte <= 126)
+      return (char)byte;
+   else
+      return '?';
+}
+
+static void
+png_icc_tag_name(char *name, png_uint_32 tag)
+{
+   name[0] = '\'';
+   name[1] = png_icc_tag_char(tag >> 24);
+   name[2] = png_icc_tag_char(tag >> 16);
+   name[3] = png_icc_tag_char(tag >>  8);
+   name[4] = png_icc_tag_char(tag      );
+   name[5] = '\'';
+}
+
+static int
+is_ICC_signature_char(png_alloc_size_t it)
+{
+   return it == 32 || (it >= 48 && it <= 57) || (it >= 65 && it <= 90) ||
+      (it >= 97 && it <= 122);
+}
+
+static int
+is_ICC_signature(png_alloc_size_t it)
+{
+   return is_ICC_signature_char(it >> 24) /* checks all the top bits */ &&
+      is_ICC_signature_char((it >> 16) & 0xff) &&
+      is_ICC_signature_char((it >> 8) & 0xff) &&
+      is_ICC_signature_char(it & 0xff);
+}
+
+static int
+png_icc_profile_error(png_const_structrp png_ptr, png_colorspacerp colorspace,
+   png_const_charp name, png_alloc_size_t value, png_const_charp reason)
+{
+   size_t pos;
+   char message[196]; /* see below for calculation */
+
+   if (colorspace != NULL)
+      colorspace->flags |= PNG_COLORSPACE_INVALID;
+
+   pos = png_safecat(message, (sizeof message), 0, "profile '"); /* 9 chars */
+   pos = png_safecat(message, pos+79, pos, name); /* Truncate to 79 chars */
+   pos = png_safecat(message, (sizeof message), pos, "': "); /* +2 = 90 */
+   if (is_ICC_signature(value) != 0)
+   {
+      /* So 'value' is at most 4 bytes and the following cast is safe */
+      png_icc_tag_name(message+pos, (png_uint_32)value);
+      pos += 6; /* total +8; less than the else clause */
+      message[pos++] = ':';
+      message[pos++] = ' ';
+   }
+#  ifdef PNG_WARNINGS_SUPPORTED
+   else
+      {
+         char number[PNG_NUMBER_BUFFER_SIZE]; /* +24 = 114*/
+
+         pos = png_safecat(message, (sizeof message), pos,
+            png_format_number(number, number+(sizeof number),
+               PNG_NUMBER_FORMAT_x, value));
+         pos = png_safecat(message, (sizeof message), pos, "h: "); /*+2 = 116*/
+      }
+#  endif
+   /* The 'reason' is an arbitrary message, allow +79 maximum 195 */
+   pos = png_safecat(message, (sizeof message), pos, reason);
+   PNG_UNUSED(pos)
+
+   /* This is recoverable, but make it unconditionally an app_error on write to
+    * avoid writing invalid ICC profiles into PNG files (i.e., we handle them
+    * on read, with a warning, but on write unless the app turns off
+    * application errors the PNG won't be written.)
+    */
+   png_chunk_report(png_ptr, message,
+      (colorspace != NULL) ? PNG_CHUNK_ERROR : PNG_CHUNK_WRITE_ERROR);
+
+   return 0;
+}
+#endif /* sRGB || iCCP */
+
+#ifdef PNG_sRGB_SUPPORTED
+int /* PRIVATE */
+png_colorspace_set_sRGB(png_const_structrp png_ptr, png_colorspacerp colorspace,
+   int intent)
+{
+   /* sRGB sets known gamma, end points and (from the chunk) intent. */
+   /* IMPORTANT: these are not necessarily the values found in an ICC profile
+    * because ICC profiles store values adapted to a D50 environment; it is
+    * expected that the ICC profile mediaWhitePointTag will be D50; see the
+    * checks and code elsewhere to understand this better.
+    *
+    * These XYZ values, which are accurate to 5dp, produce rgb to gray
+    * coefficients of (6968,23435,2366), which are reduced (because they add up
+    * to 32769 not 32768) to (6968,23434,2366).  These are the values that
+    * libpng has traditionally used (and are the best values given the 15bit
+    * algorithm used by the rgb to gray code.)
+    */
+   static const png_XYZ sRGB_XYZ = /* D65 XYZ (*not* the D50 adapted values!) */
+   {
+      /* color      X      Y      Z */
+      /* red   */ 41239, 21264,  1933,
+      /* green */ 35758, 71517, 11919,
+      /* blue  */ 18048,  7219, 95053
+   };
+
+   /* Do nothing if the colorspace is already invalidated. */
+   if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)
+      return 0;
+
+   /* Check the intent, then check for existing settings.  It is valid for the
+    * PNG file to have cHRM or gAMA chunks along with sRGB, but the values must
+    * be consistent with the correct values.  If, however, this function is
+    * called below because an iCCP chunk matches sRGB then it is quite
+    * conceivable that an older app recorded incorrect gAMA and cHRM because of
+    * an incorrect calculation based on the values in the profile - this does
+    * *not* invalidate the profile (though it still produces an error, which can
+    * be ignored.)
+    */
+   if (intent < 0 || intent >= PNG_sRGB_INTENT_LAST)
+      return png_icc_profile_error(png_ptr, colorspace, "sRGB",
+         (unsigned)intent, "invalid sRGB rendering intent");
+
+   if ((colorspace->flags & PNG_COLORSPACE_HAVE_INTENT) != 0 &&
+      colorspace->rendering_intent != intent)
+      return png_icc_profile_error(png_ptr, colorspace, "sRGB",
+         (unsigned)intent, "inconsistent rendering intents");
+
+   if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0)
+   {
+      png_benign_error(png_ptr, "duplicate sRGB information ignored");
+      return 0;
+   }
+
+   /* If the standard sRGB cHRM chunk does not match the one from the PNG file
+    * warn but overwrite the value with the correct one.
+    */
+   if ((colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0 &&
+      !png_colorspace_endpoints_match(&sRGB_xy, &colorspace->end_points_xy,
+         100))
+      png_chunk_report(png_ptr, "cHRM chunk does not match sRGB",
+         PNG_CHUNK_ERROR);
+
+   /* This check is just done for the error reporting - the routine always
+    * returns true when the 'from' argument corresponds to sRGB (2).
+    */
+   (void)png_colorspace_check_gamma(png_ptr, colorspace, PNG_GAMMA_sRGB_INVERSE,
+      2/*from sRGB*/);
+
+   /* intent: bugs in GCC force 'int' to be used as the parameter type. */
+   colorspace->rendering_intent = (png_uint_16)intent;
+   colorspace->flags |= PNG_COLORSPACE_HAVE_INTENT;
+
+   /* endpoints */
+   colorspace->end_points_xy = sRGB_xy;
+   colorspace->end_points_XYZ = sRGB_XYZ;
+   colorspace->flags |=
+      (PNG_COLORSPACE_HAVE_ENDPOINTS|PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB);
+
+   /* gamma */
+   colorspace->gamma = PNG_GAMMA_sRGB_INVERSE;
+   colorspace->flags |= PNG_COLORSPACE_HAVE_GAMMA;
+
+   /* Finally record that we have an sRGB profile */
+   colorspace->flags |=
+      (PNG_COLORSPACE_MATCHES_sRGB|PNG_COLORSPACE_FROM_sRGB);
+
+   return 1; /* set */
+}
+#endif /* sRGB */
+
+#ifdef PNG_iCCP_SUPPORTED
+/* Encoded value of D50 as an ICC XYZNumber.  From the ICC 2010 spec the value
+ * is XYZ(0.9642,1.0,0.8249), which scales to:
+ *
+ *    (63189.8112, 65536, 54060.6464)
+ */
+static const png_byte D50_nCIEXYZ[12] =
+   { 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d };
+
+int /* PRIVATE */
+png_icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace,
+   png_const_charp name, png_uint_32 profile_length)
+{
+   if (profile_length < 132)
+      return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
+         "too short");
+
+   return 1;
+}
+
+int /* PRIVATE */
+png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace,
+   png_const_charp name, png_uint_32 profile_length,
+   png_const_bytep profile/* first 132 bytes only */, int color_type)
+{
+   png_uint_32 temp;
+
+   /* Length check; this cannot be ignored in this code because profile_length
+    * is used later to check the tag table, so even if the profile seems over
+    * long profile_length from the caller must be correct.  The caller can fix
+    * this up on read or write by just passing in the profile header length.
+    */
+   temp = png_get_uint_32(profile);
+   if (temp != profile_length)
+      return png_icc_profile_error(png_ptr, colorspace, name, temp,
+         "length does not match profile");
+
+   temp = (png_uint_32) (*(profile+8));
+   if (temp > 3 && (profile_length & 3))
+      return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
+         "invalid length");
+
+   temp = png_get_uint_32(profile+128); /* tag count: 12 bytes/tag */
+   if (temp > 357913930 || /* (2^32-4-132)/12: maximum possible tag count */
+      profile_length < 132+12*temp) /* truncated tag table */
+      return png_icc_profile_error(png_ptr, colorspace, name, temp,
+         "tag count too large");
+
+   /* The 'intent' must be valid or we can't store it, ICC limits the intent to
+    * 16 bits.
+    */
+   temp = png_get_uint_32(profile+64);
+   if (temp >= 0xffff) /* The ICC limit */
+      return png_icc_profile_error(png_ptr, colorspace, name, temp,
+         "invalid rendering intent");
+
+   /* This is just a warning because the profile may be valid in future
+    * versions.
+    */
+   if (temp >= PNG_sRGB_INTENT_LAST)
+      (void)png_icc_profile_error(png_ptr, NULL, name, temp,
+         "intent outside defined range");
+
+   /* At this point the tag table can't be checked because it hasn't necessarily
+    * been loaded; however, various header fields can be checked.  These checks
+    * are for values permitted by the PNG spec in an ICC profile; the PNG spec
+    * restricts the profiles that can be passed in an iCCP chunk (they must be
+    * appropriate to processing PNG data!)
+    */
+
+   /* Data checks (could be skipped).  These checks must be independent of the
+    * version number; however, the version number doesn't accomodate changes in
+    * the header fields (just the known tags and the interpretation of the
+    * data.)
+    */
+   temp = png_get_uint_32(profile+36); /* signature 'ascp' */
+   if (temp != 0x61637370)
+      return png_icc_profile_error(png_ptr, colorspace, name, temp,
+         "invalid signature");
+
+   /* Currently the PCS illuminant/adopted white point (the computational
+    * white point) are required to be D50,
+    * however the profile contains a record of the illuminant so perhaps ICC
+    * expects to be able to change this in the future (despite the rationale in
+    * the introduction for using a fixed PCS adopted white.)  Consequently the
+    * following is just a warning.
+    */
+   if (memcmp(profile+68, D50_nCIEXYZ, 12) != 0)
+      (void)png_icc_profile_error(png_ptr, NULL, name, 0/*no tag value*/,
+         "PCS illuminant is not D50");
+
+   /* The PNG spec requires this:
+    * "If the iCCP chunk is present, the image samples conform to the colour
+    * space represented by the embedded ICC profile as defined by the
+    * International Color Consortium [ICC]. The colour space of the ICC profile
+    * shall be an RGB colour space for colour images (PNG colour types 2, 3, and
+    * 6), or a greyscale colour space for greyscale images (PNG colour types 0
+    * and 4)."
+    *
+    * This checking code ensures the embedded profile (on either read or write)
+    * conforms to the specification requirements.  Notice that an ICC 'gray'
+    * color-space profile contains the information to transform the monochrome
+    * data to XYZ or L*a*b (according to which PCS the profile uses) and this
+    * should be used in preference to the standard libpng K channel replication
+    * into R, G and B channels.
+    *
+    * Previously it was suggested that an RGB profile on grayscale data could be
+    * handled.  However it it is clear that using an RGB profile in this context
+    * must be an error - there is no specification of what it means.  Thus it is
+    * almost certainly more correct to ignore the profile.
+    */
+   temp = png_get_uint_32(profile+16); /* data colour space field */
+   switch (temp)
+   {
+      case 0x52474220: /* 'RGB ' */
+         if ((color_type & PNG_COLOR_MASK_COLOR) == 0)
+            return png_icc_profile_error(png_ptr, colorspace, name, temp,
+               "RGB color space not permitted on grayscale PNG");
+         break;
+
+      case 0x47524159: /* 'GRAY' */
+         if ((color_type & PNG_COLOR_MASK_COLOR) != 0)
+            return png_icc_profile_error(png_ptr, colorspace, name, temp,
+               "Gray color space not permitted on RGB PNG");
+         break;
+
+      default:
+         return png_icc_profile_error(png_ptr, colorspace, name, temp,
+            "invalid ICC profile color space");
+   }
+
+   /* It is up to the application to check that the profile class matches the
+    * application requirements; the spec provides no guidance, but it's pretty
+    * weird if the profile is not scanner ('scnr'), monitor ('mntr'), printer
+    * ('prtr') or 'spac' (for generic color spaces).  Issue a warning in these
+    * cases.  Issue an error for device link or abstract profiles - these don't
+    * contain the records necessary to transform the color-space to anything
+    * other than the target device (and not even that for an abstract profile).
+    * Profiles of these classes may not be embedded in images.
+    */
+   temp = png_get_uint_32(profile+12); /* profile/device class */
+   switch (temp)
+   {
+      case 0x73636E72: /* 'scnr' */
+      case 0x6D6E7472: /* 'mntr' */
+      case 0x70727472: /* 'prtr' */
+      case 0x73706163: /* 'spac' */
+         /* All supported */
+         break;
+
+      case 0x61627374: /* 'abst' */
+         /* May not be embedded in an image */
+         return png_icc_profile_error(png_ptr, colorspace, name, temp,
+            "invalid embedded Abstract ICC profile");
+
+      case 0x6C696E6B: /* 'link' */
+         /* DeviceLink profiles cannot be interpreted in a non-device specific
+          * fashion, if an app uses the AToB0Tag in the profile the results are
+          * undefined unless the result is sent to the intended device,
+          * therefore a DeviceLink profile should not be found embedded in a
+          * PNG.
+          */
+         return png_icc_profile_error(png_ptr, colorspace, name, temp,
+            "unexpected DeviceLink ICC profile class");
+
+      case 0x6E6D636C: /* 'nmcl' */
+         /* A NamedColor profile is also device specific, however it doesn't
+          * contain an AToB0 tag that is open to misinterpretation.  Almost
+          * certainly it will fail the tests below.
+          */
+         (void)png_icc_profile_error(png_ptr, NULL, name, temp,
+            "unexpected NamedColor ICC profile class");
+         break;
+
+      default:
+         /* To allow for future enhancements to the profile accept unrecognized
+          * profile classes with a warning, these then hit the test below on the
+          * tag content to ensure they are backward compatible with one of the
+          * understood profiles.
+          */
+         (void)png_icc_profile_error(png_ptr, NULL, name, temp,
+            "unrecognized ICC profile class");
+         break;
+   }
+
+   /* For any profile other than a device link one the PCS must be encoded
+    * either in XYZ or Lab.
+    */
+   temp = png_get_uint_32(profile+20);
+   switch (temp)
+   {
+      case 0x58595A20: /* 'XYZ ' */
+      case 0x4C616220: /* 'Lab ' */
+         break;
+
+      default:
+         return png_icc_profile_error(png_ptr, colorspace, name, temp,
+            "unexpected ICC PCS encoding");
+   }
+
+   return 1;
+}
+
+int /* PRIVATE */
+png_icc_check_tag_table(png_const_structrp png_ptr, png_colorspacerp colorspace,
+   png_const_charp name, png_uint_32 profile_length,
+   png_const_bytep profile /* header plus whole tag table */)
+{
+   png_uint_32 tag_count = png_get_uint_32(profile+128);
+   png_uint_32 itag;
+   png_const_bytep tag = profile+132; /* The first tag */
+
+   /* First scan all the tags in the table and add bits to the icc_info value
+    * (temporarily in 'tags').
+    */
+   for (itag=0; itag < tag_count; ++itag, tag += 12)
+   {
+      png_uint_32 tag_id = png_get_uint_32(tag+0);
+      png_uint_32 tag_start = png_get_uint_32(tag+4); /* must be aligned */
+      png_uint_32 tag_length = png_get_uint_32(tag+8);/* not padded */
+
+      /* The ICC specification does not exclude zero length tags, therefore the
+       * start might actually be anywhere if there is no data, but this would be
+       * a clear abuse of the intent of the standard so the start is checked for
+       * being in range.  All defined tag types have an 8 byte header - a 4 byte
+       * type signature then 0.
+       */
+      if ((tag_start & 3) != 0)
+      {
+         /* CNHP730S.icc shipped with Microsoft Windows 64 violates this, it is
+          * only a warning here because libpng does not care about the
+          * alignment.
+          */
+         (void)png_icc_profile_error(png_ptr, NULL, name, tag_id,
+            "ICC profile tag start not a multiple of 4");
+      }
+
+      /* This is a hard error; potentially it can cause read outside the
+       * profile.
+       */
+      if (tag_start > profile_length || tag_length > profile_length - tag_start)
+         return png_icc_profile_error(png_ptr, colorspace, name, tag_id,
+            "ICC profile tag outside profile");
+   }
+
+   return 1; /* success, maybe with warnings */
+}
+
+#if defined(PNG_sRGB_SUPPORTED) && PNG_sRGB_PROFILE_CHECKS >= 0
+/* Information about the known ICC sRGB profiles */
+static const struct
+{
+   png_uint_32 adler, crc, length;
+   png_uint_32 md5[4];
+   png_byte    have_md5;
+   png_byte    is_broken;
+   png_uint_16 intent;
+
+#  define PNG_MD5(a,b,c,d) { a, b, c, d }, (a!=0)||(b!=0)||(c!=0)||(d!=0)
+#  define PNG_ICC_CHECKSUM(adler, crc, md5, intent, broke, date, length, fname)\
+      { adler, crc, length, md5, broke, intent },
+
+} png_sRGB_checks[] =
+{
+   /* This data comes from contrib/tools/checksum-icc run on downloads of
+    * all four ICC sRGB profiles from www.color.org.
+    */
+   /* adler32, crc32, MD5[4], intent, date, length, file-name */
+   PNG_ICC_CHECKSUM(0x0a3fd9f6, 0x3b8772b9,
+      PNG_MD5(0x29f83dde, 0xaff255ae, 0x7842fae4, 0xca83390d), 0, 0,
+      "2009/03/27 21:36:31", 3048, "sRGB_IEC61966-2-1_black_scaled.icc")
+
+   /* ICC sRGB v2 perceptual no black-compensation: */
+   PNG_ICC_CHECKSUM(0x4909e5e1, 0x427ebb21,
+      PNG_MD5(0xc95bd637, 0xe95d8a3b, 0x0df38f99, 0xc1320389), 1, 0,
+      "2009/03/27 21:37:45", 3052, "sRGB_IEC61966-2-1_no_black_scaling.icc")
+
+   PNG_ICC_CHECKSUM(0xfd2144a1, 0x306fd8ae,
+      PNG_MD5(0xfc663378, 0x37e2886b, 0xfd72e983, 0x8228f1b8), 0, 0,
+      "2009/08/10 17:28:01", 60988, "sRGB_v4_ICC_preference_displayclass.icc")
+
+   /* ICC sRGB v4 perceptual */
+   PNG_ICC_CHECKSUM(0x209c35d2, 0xbbef7812,
+      PNG_MD5(0x34562abf, 0x994ccd06, 0x6d2c5721, 0xd0d68c5d), 0, 0,
+      "2007/07/25 00:05:37", 60960, "sRGB_v4_ICC_preference.icc")
+
+   /* The following profiles have no known MD5 checksum. If there is a match
+    * on the (empty) MD5 the other fields are used to attempt a match and
+    * a warning is produced.  The first two of these profiles have a 'cprt' tag
+    * which suggests that they were also made by Hewlett Packard.
+    */
+   PNG_ICC_CHECKSUM(0xa054d762, 0x5d5129ce,
+      PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 0,
+      "2004/07/21 18:57:42", 3024, "sRGB_IEC61966-2-1_noBPC.icc")
+
+   /* This is a 'mntr' (display) profile with a mediaWhitePointTag that does not
+    * match the D50 PCS illuminant in the header (it is in fact the D65 values,
+    * so the white point is recorded as the un-adapted value.)  The profiles
+    * below only differ in one byte - the intent - and are basically the same as
+    * the previous profile except for the mediaWhitePointTag error and a missing
+    * chromaticAdaptationTag.
+    */
+   PNG_ICC_CHECKSUM(0xf784f3fb, 0x182ea552,
+      PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 0, 1/*broken*/,
+      "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 perceptual")
+
+   PNG_ICC_CHECKSUM(0x0398f3fc, 0xf29e526d,
+      PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 1/*broken*/,
+      "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 media-relative")
+};
+
+static int
+png_compare_ICC_profile_with_sRGB(png_const_structrp png_ptr,
+   png_const_bytep profile, uLong adler)
+{
+   /* The quick check is to verify just the MD5 signature and trust the
+    * rest of the data.  Because the profile has already been verified for
+    * correctness this is safe.  png_colorspace_set_sRGB will check the 'intent'
+    * field too, so if the profile has been edited with an intent not defined
+    * by sRGB (but maybe defined by a later ICC specification) the read of
+    * the profile will fail at that point.
+    */
+
+   png_uint_32 length = 0;
+   png_uint_32 intent = 0x10000; /* invalid */
+#if PNG_sRGB_PROFILE_CHECKS > 1
+   uLong crc = 0; /* the value for 0 length data */
+#endif
+   unsigned int i;
+
+#ifdef PNG_SET_OPTION_SUPPORTED
+   /* First see if PNG_SKIP_sRGB_CHECK_PROFILE has been set to "on" */
+   if (((png_ptr->options >> PNG_SKIP_sRGB_CHECK_PROFILE) & 3) ==
+               PNG_OPTION_ON)
+      return 0;
+#endif
+
+   for (i=0; i < (sizeof png_sRGB_checks) / (sizeof png_sRGB_checks[0]); ++i)
+   {
+      if (png_get_uint_32(profile+84) == png_sRGB_checks[i].md5[0] &&
+         png_get_uint_32(profile+88) == png_sRGB_checks[i].md5[1] &&
+         png_get_uint_32(profile+92) == png_sRGB_checks[i].md5[2] &&
+         png_get_uint_32(profile+96) == png_sRGB_checks[i].md5[3])
+      {
+         /* This may be one of the old HP profiles without an MD5, in that
+          * case we can only use the length and Adler32 (note that these
+          * are not used by default if there is an MD5!)
+          */
+#        if PNG_sRGB_PROFILE_CHECKS == 0
+            if (png_sRGB_checks[i].have_md5 != 0)
+               return 1+png_sRGB_checks[i].is_broken;
+#        endif
+
+         /* Profile is unsigned or more checks have been configured in. */
+         if (length == 0)
+         {
+            length = png_get_uint_32(profile);
+            intent = png_get_uint_32(profile+64);
+         }
+
+         /* Length *and* intent must match */
+         if (length == png_sRGB_checks[i].length &&
+            intent == png_sRGB_checks[i].intent)
+         {
+            /* Now calculate the adler32 if not done already. */
+            if (adler == 0)
+            {
+               adler = adler32(0, NULL, 0);
+               adler = adler32(adler, profile, length);
+            }
+
+            if (adler == png_sRGB_checks[i].adler)
+            {
+               /* These basic checks suggest that the data has not been
+                * modified, but if the check level is more than 1 perform
+                * our own crc32 checksum on the data.
+                */
+#              if PNG_sRGB_PROFILE_CHECKS > 1
+                  if (crc == 0)
+                  {
+                     crc = crc32(0, NULL, 0);
+                     crc = crc32(crc, profile, length);
+                  }
+
+                  /* So this check must pass for the 'return' below to happen.
+                   */
+                  if (crc == png_sRGB_checks[i].crc)
+#              endif
+               {
+                  if (png_sRGB_checks[i].is_broken != 0)
+                  {
+                     /* These profiles are known to have bad data that may cause
+                      * problems if they are used, therefore attempt to
+                      * discourage their use, skip the 'have_md5' warning below,
+                      * which is made irrelevant by this error.
+                      */
+                     png_chunk_report(png_ptr, "known incorrect sRGB profile",
+                        PNG_CHUNK_ERROR);
+                  }
+
+                  /* Warn that this being done; this isn't even an error since
+                   * the profile is perfectly valid, but it would be nice if
+                   * people used the up-to-date ones.
+                   */
+                  else if (png_sRGB_checks[i].have_md5 == 0)
+                  {
+                     png_chunk_report(png_ptr, "out-of-date sRGB profile with"
+                        " no signature",
+                        PNG_CHUNK_WARNING);
+                  }
+
+                  return 1+png_sRGB_checks[i].is_broken;
+               }
+            }
+
+# if PNG_sRGB_PROFILE_CHECKS > 0
+         /* The signature matched, but the profile had been changed in some
+          * way.  This probably indicates a data error or uninformed hacking.
+          * Fall through to "no match".
+          */
+         png_chunk_report(png_ptr, "Not recognizing known sRGB profile that"
+             " has been edited", 
+             PNG_CHUNK_WARNING);
+         break;
+# endif
+         }
+      }
+   }
+
+   return 0; /* no match */
+}
+#endif
+
+#ifdef PNG_sRGB_SUPPORTED
+void /* PRIVATE */
+png_icc_set_sRGB(png_const_structrp png_ptr,
+   png_colorspacerp colorspace, png_const_bytep profile, uLong adler)
+{
+   /* Is this profile one of the known ICC sRGB profiles?  If it is, just set
+    * the sRGB information.
+    */
+#if PNG_sRGB_PROFILE_CHECKS >= 0
+   if (png_compare_ICC_profile_with_sRGB(png_ptr, profile, adler) != 0)
+#endif
+      (void)png_colorspace_set_sRGB(png_ptr, colorspace,
+         (int)/*already checked*/png_get_uint_32(profile+64));
+}
+#endif /* READ_sRGB */
+
+int /* PRIVATE */
+png_colorspace_set_ICC(png_const_structrp png_ptr, png_colorspacerp colorspace,
+   png_const_charp name, png_uint_32 profile_length, png_const_bytep profile,
+   int color_type)
+{
+   if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)
+      return 0;
+
+   if (png_icc_check_length(png_ptr, colorspace, name, profile_length) != 0 &&
+       png_icc_check_header(png_ptr, colorspace, name, profile_length, profile,
+          color_type) != 0 &&
+       png_icc_check_tag_table(png_ptr, colorspace, name, profile_length,
+          profile) != 0)
+   {
+#     ifdef PNG_sRGB_SUPPORTED
+         /* If no sRGB support, don't try storing sRGB information */
+         png_icc_set_sRGB(png_ptr, colorspace, profile, 0);
+#     endif
+      return 1;
+   }
+
+   /* Failure case */
+   return 0;
+}
+#endif /* iCCP */
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+void /* PRIVATE */
+png_colorspace_set_rgb_coefficients(png_structrp png_ptr)
+{
+   /* Set the rgb_to_gray coefficients from the colorspace. */
+   if (png_ptr->rgb_to_gray_coefficients_set == 0 &&
+      (png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
+   {
+      /* png_set_background has not been called, get the coefficients from the Y
+       * values of the colorspace colorants.
+       */
+      png_fixed_point r = png_ptr->colorspace.end_points_XYZ.red_Y;
+      png_fixed_point g = png_ptr->colorspace.end_points_XYZ.green_Y;
+      png_fixed_point b = png_ptr->colorspace.end_points_XYZ.blue_Y;
+      png_fixed_point total = r+g+b;
+
+      if (total > 0 &&
+         r >= 0 && png_muldiv(&r, r, 32768, total) && r >= 0 && r <= 32768 &&
+         g >= 0 && png_muldiv(&g, g, 32768, total) && g >= 0 && g <= 32768 &&
+         b >= 0 && png_muldiv(&b, b, 32768, total) && b >= 0 && b <= 32768 &&
+         r+g+b <= 32769)
+      {
+         /* We allow 0 coefficients here.  r+g+b may be 32769 if two or
+          * all of the coefficients were rounded up.  Handle this by
+          * reducing the *largest* coefficient by 1; this matches the
+          * approach used for the default coefficients in pngrtran.c
+          */
+         int add = 0;
+
+         if (r+g+b > 32768)
+            add = -1;
+         else if (r+g+b < 32768)
+            add = 1;
+
+         if (add != 0)
+         {
+            if (g >= r && g >= b)
+               g += add;
+            else if (r >= g && r >= b)
+               r += add;
+            else
+               b += add;
+         }
+
+         /* Check for an internal error. */
+         if (r+g+b != 32768)
+            png_error(png_ptr,
+               "internal error handling cHRM coefficients");
+
+         else
+         {
+            png_ptr->rgb_to_gray_red_coeff   = (png_uint_16)r;
+            png_ptr->rgb_to_gray_green_coeff = (png_uint_16)g;
+         }
+      }
+
+      /* This is a png_error at present even though it could be ignored -
+       * it should never happen, but it is important that if it does, the
+       * bug is fixed.
+       */
+      else
+         png_error(png_ptr, "internal error handling cHRM->XYZ");
+   }
+}
+#endif
+
+#endif /* COLORSPACE */
+
+#ifdef __GNUC__
+/* This exists solely to work round a warning from GNU C. */
+static int /* PRIVATE */
+png_gt(size_t a, size_t b)
+{
+    return a > b;
+}
+#else
+#   define png_gt(a,b) ((a) > (b))
+#endif
+
+void /* PRIVATE */
+png_check_IHDR(png_const_structrp png_ptr,
+   png_uint_32 width, png_uint_32 height, int bit_depth,
+   int color_type, int interlace_type, int compression_type,
+   int filter_type)
+{
+   int error = 0;
+
+   /* Check for width and height valid values */
+   if (width == 0)
+   {
+      png_warning(png_ptr, "Image width is zero in IHDR");
+      error = 1;
+   }
+   else if (width > PNG_UINT_31_MAX)
+   {
+      png_warning(png_ptr, "Invalid image width in IHDR");
+      error = 1;
+   }
+
+   else if (png_gt(width,
+                   (PNG_SIZE_MAX >> 3) /* 8-byte RGBA pixels */
+                   - 48                /* big_row_buf hack */
+                   - 1                 /* filter byte */
+                   - 7*8               /* rounding width to multiple of 8 pix */
+                   - 8))               /* extra max_pixel_depth pad */
+   {
+      /* The size of the row must be within the limits of this architecture.
+       * Because the read code can perform arbitrary transformations the
+       * maximum size is checked here.  Because the code in png_read_start_row
+       * adds extra space "for safety's sake" in several places a conservative
+       * limit is used here.
+       *
+       * NOTE: it would be far better to check the size that is actually used,
+       * but the effect in the real world is minor and the changes are more
+       * extensive, therefore much more dangerous and much more difficult to
+       * write in a way that avoids compiler warnings.
+       */
+      png_warning(png_ptr, "Image width is too large for this architecture");
+      error = 1;
+   }
+   else
+   {
+#     ifdef PNG_SET_USER_LIMITS_SUPPORTED
+      if (width > png_ptr->user_width_max)
+#     else
+      if (width > PNG_USER_WIDTH_MAX)
+#     endif
+      {
+         png_warning(png_ptr, "Image width exceeds user limit in IHDR");
+         error = 1;
+      }
+   }
+
+   if (height == 0)
+   {
+      png_warning(png_ptr, "Image height is zero in IHDR");
+      error = 1;
+   }
+   else if (height > PNG_UINT_31_MAX)
+   {
+      png_warning(png_ptr, "Invalid image height in IHDR");
+      error = 1;
+   }
+   else
+   {
+#     ifdef PNG_SET_USER_LIMITS_SUPPORTED
+      if (height > png_ptr->user_height_max)
+#     else
+      if (height > PNG_USER_HEIGHT_MAX)
+#     endif
+      {
+         png_warning(png_ptr, "Image height exceeds user limit in IHDR");
+         error = 1;
+      }
+   }
+
+   /* Check other values */
+   if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 &&
+       bit_depth != 8 && bit_depth != 16)
+   {
+      png_warning(png_ptr, "Invalid bit depth in IHDR");
+      error = 1;
+   }
+
+   if (color_type < 0 || color_type == 1 ||
+       color_type == 5 || color_type > 6)
+   {
+      png_warning(png_ptr, "Invalid color type in IHDR");
+      error = 1;
+   }
+
+   if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) ||
+       ((color_type == PNG_COLOR_TYPE_RGB ||
+         color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
+         color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8))
+   {
+      png_warning(png_ptr, "Invalid color type/bit depth combination in IHDR");
+      error = 1;
+   }
+
+   if (interlace_type >= PNG_INTERLACE_LAST)
+   {
+      png_warning(png_ptr, "Unknown interlace method in IHDR");
+      error = 1;
+   }
+
+   if (compression_type != PNG_COMPRESSION_TYPE_BASE)
+   {
+      png_warning(png_ptr, "Unknown compression method in IHDR");
+      error = 1;
+   }
+
+#  ifdef PNG_MNG_FEATURES_SUPPORTED
+   /* Accept filter_method 64 (intrapixel differencing) only if
+    * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
+    * 2. Libpng did not read a PNG signature (this filter_method is only
+    *    used in PNG datastreams that are embedded in MNG datastreams) and
+    * 3. The application called png_permit_mng_features with a mask that
+    *    included PNG_FLAG_MNG_FILTER_64 and
+    * 4. The filter_method is 64 and
+    * 5. The color_type is RGB or RGBA
+    */
+   if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0 &&
+       png_ptr->mng_features_permitted != 0)
+      png_warning(png_ptr, "MNG features are not allowed in a PNG datastream");
+
+   if (filter_type != PNG_FILTER_TYPE_BASE)
+   {
+      if (!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 &&
+          (filter_type == PNG_INTRAPIXEL_DIFFERENCING) &&
+          ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) &&
+          (color_type == PNG_COLOR_TYPE_RGB ||
+          color_type == PNG_COLOR_TYPE_RGB_ALPHA)))
+      {
+         png_warning(png_ptr, "Unknown filter method in IHDR");
+         error = 1;
+      }
+
+      if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0)
+      {
+         png_warning(png_ptr, "Invalid filter method in IHDR");
+         error = 1;
+      }
+   }
+
+#  else
+   if (filter_type != PNG_FILTER_TYPE_BASE)
+   {
+      png_warning(png_ptr, "Unknown filter method in IHDR");
+      error = 1;
+   }
+#  endif
+
+   if (error == 1)
+      png_error(png_ptr, "Invalid IHDR data");
+}
+
+#if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED)
+/* ASCII to fp functions */
+/* Check an ASCII formated floating point value, see the more detailed
+ * comments in pngpriv.h
+ */
+/* The following is used internally to preserve the sticky flags */
+#define png_fp_add(state, flags) ((state) |= (flags))
+#define png_fp_set(state, value) ((state) = (value) | ((state) & PNG_FP_STICKY))
+
+int /* PRIVATE */
+png_check_fp_number(png_const_charp string, png_size_t size, int *statep,
+   png_size_tp whereami)
+{
+   int state = *statep;
+   png_size_t i = *whereami;
+
+   while (i < size)
+   {
+      int type;
+      /* First find the type of the next character */
+      switch (string[i])
+      {
+      case 43:  type = PNG_FP_SAW_SIGN;                   break;
+      case 45:  type = PNG_FP_SAW_SIGN + PNG_FP_NEGATIVE; break;
+      case 46:  type = PNG_FP_SAW_DOT;                    break;
+      case 48:  type = PNG_FP_SAW_DIGIT;                  break;
+      case 49: case 50: case 51: case 52:
+      case 53: case 54: case 55: case 56:
+      case 57:  type = PNG_FP_SAW_DIGIT + PNG_FP_NONZERO; break;
+      case 69:
+      case 101: type = PNG_FP_SAW_E;                      break;
+      default:  goto PNG_FP_End;
+      }
+
+      /* Now deal with this type according to the current
+       * state, the type is arranged to not overlap the
+       * bits of the PNG_FP_STATE.
+       */
+      switch ((state & PNG_FP_STATE) + (type & PNG_FP_SAW_ANY))
+      {
+      case PNG_FP_INTEGER + PNG_FP_SAW_SIGN:
+         if ((state & PNG_FP_SAW_ANY) != 0)
+            goto PNG_FP_End; /* not a part of the number */
+
+         png_fp_add(state, type);
+         break;
+
+      case PNG_FP_INTEGER + PNG_FP_SAW_DOT:
+         /* Ok as trailer, ok as lead of fraction. */
+         if ((state & PNG_FP_SAW_DOT) != 0) /* two dots */
+            goto PNG_FP_End;
+
+         else if ((state & PNG_FP_SAW_DIGIT) != 0) /* trailing dot? */
+            png_fp_add(state, type);
+
+         else
+            png_fp_set(state, PNG_FP_FRACTION | type);
+
+         break;
+
+      case PNG_FP_INTEGER + PNG_FP_SAW_DIGIT:
+         if ((state & PNG_FP_SAW_DOT) != 0) /* delayed fraction */
+            png_fp_set(state, PNG_FP_FRACTION | PNG_FP_SAW_DOT);
+
+         png_fp_add(state, type | PNG_FP_WAS_VALID);
+
+         break;
+
+      case PNG_FP_INTEGER + PNG_FP_SAW_E:
+         if ((state & PNG_FP_SAW_DIGIT) == 0)
+            goto PNG_FP_End;
+
+         png_fp_set(state, PNG_FP_EXPONENT);
+
+         break;
+
+   /* case PNG_FP_FRACTION + PNG_FP_SAW_SIGN:
+         goto PNG_FP_End; ** no sign in fraction */
+
+   /* case PNG_FP_FRACTION + PNG_FP_SAW_DOT:
+         goto PNG_FP_End; ** Because SAW_DOT is always set */
+
+      case PNG_FP_FRACTION + PNG_FP_SAW_DIGIT:
+         png_fp_add(state, type | PNG_FP_WAS_VALID);
+         break;
+
+      case PNG_FP_FRACTION + PNG_FP_SAW_E:
+         /* This is correct because the trailing '.' on an
+          * integer is handled above - so we can only get here
+          * with the sequence ".E" (with no preceding digits).
+          */
+         if ((state & PNG_FP_SAW_DIGIT) == 0)
+            goto PNG_FP_End;
+
+         png_fp_set(state, PNG_FP_EXPONENT);
+
+         break;
+
+      case PNG_FP_EXPONENT + PNG_FP_SAW_SIGN:
+         if ((state & PNG_FP_SAW_ANY) != 0)
+            goto PNG_FP_End; /* not a part of the number */
+
+         png_fp_add(state, PNG_FP_SAW_SIGN);
+
+         break;
+
+   /* case PNG_FP_EXPONENT + PNG_FP_SAW_DOT:
+         goto PNG_FP_End; */
+
+      case PNG_FP_EXPONENT + PNG_FP_SAW_DIGIT:
+         png_fp_add(state, PNG_FP_SAW_DIGIT | PNG_FP_WAS_VALID);
+
+         break;
+
+   /* case PNG_FP_EXPONEXT + PNG_FP_SAW_E:
+         goto PNG_FP_End; */
+
+      default: goto PNG_FP_End; /* I.e. break 2 */
+      }
+
+      /* The character seems ok, continue. */
+      ++i;
+   }
+
+PNG_FP_End:
+   /* Here at the end, update the state and return the correct
+    * return code.
+    */
+   *statep = state;
+   *whereami = i;
+
+   return (state & PNG_FP_SAW_DIGIT) != 0;
+}
+
+
+/* The same but for a complete string. */
+int
+png_check_fp_string(png_const_charp string, png_size_t size)
+{
+   int        state=0;
+   png_size_t char_index=0;
+
+   if (png_check_fp_number(string, size, &state, &char_index) != 0 &&
+      (char_index == size || string[char_index] == 0))
+      return state /* must be non-zero - see above */;
+
+   return 0; /* i.e. fail */
+}
+#endif /* pCAL || sCAL */
+
+#ifdef PNG_sCAL_SUPPORTED
+#  ifdef PNG_FLOATING_POINT_SUPPORTED
+/* Utility used below - a simple accurate power of ten from an integral
+ * exponent.
+ */
+static double
+png_pow10(int power)
+{
+   int recip = 0;
+   double d = 1;
+
+   /* Handle negative exponent with a reciprocal at the end because
+    * 10 is exact whereas .1 is inexact in base 2
+    */
+   if (power < 0)
+   {
+      if (power < DBL_MIN_10_EXP) return 0;
+      recip = 1, power = -power;
+   }
+
+   if (power > 0)
+   {
+      /* Decompose power bitwise. */
+      double mult = 10;
+      do
+      {
+         if (power & 1) d *= mult;
+         mult *= mult;
+         power >>= 1;
+      }
+      while (power > 0);
+
+      if (recip != 0) d = 1/d;
+   }
+   /* else power is 0 and d is 1 */
+
+   return d;
+}
+
+/* Function to format a floating point value in ASCII with a given
+ * precision.
+ */
+void /* PRIVATE */
+png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
+    double fp, unsigned int precision)
+{
+   /* We use standard functions from math.h, but not printf because
+    * that would require stdio.  The caller must supply a buffer of
+    * sufficient size or we will png_error.  The tests on size and
+    * the space in ascii[] consumed are indicated below.
+    */
+   if (precision < 1)
+      precision = DBL_DIG;
+
+   /* Enforce the limit of the implementation precision too. */
+   if (precision > DBL_DIG+1)
+      precision = DBL_DIG+1;
+
+   /* Basic sanity checks */
+   if (size >= precision+5) /* See the requirements below. */
+   {
+      if (fp < 0)
+      {
+         fp = -fp;
+         *ascii++ = 45; /* '-'  PLUS 1 TOTAL 1 */
+         --size;
+      }
+
+      if (fp >= DBL_MIN && fp <= DBL_MAX)
+      {
+         int exp_b10;       /* A base 10 exponent */
+         double base;   /* 10^exp_b10 */
+
+         /* First extract a base 10 exponent of the number,
+          * the calculation below rounds down when converting
+          * from base 2 to base 10 (multiply by log10(2) -
+          * 0.3010, but 77/256 is 0.3008, so exp_b10 needs to
+          * be increased.  Note that the arithmetic shift
+          * performs a floor() unlike C arithmetic - using a
+          * C multiply would break the following for negative
+          * exponents.
+          */
+         (void)frexp(fp, &exp_b10); /* exponent to base 2 */
+
+         exp_b10 = (exp_b10 * 77) >> 8; /* <= exponent to base 10 */
+
+         /* Avoid underflow here. */
+         base = png_pow10(exp_b10); /* May underflow */
+
+         while (base < DBL_MIN || base < fp)
+         {
+            /* And this may overflow. */
+            double test = png_pow10(exp_b10+1);
+
+            if (test <= DBL_MAX)
+               ++exp_b10, base = test;
+
+            else
+               break;
+         }
+
+         /* Normalize fp and correct exp_b10, after this fp is in the
+          * range [.1,1) and exp_b10 is both the exponent and the digit
+          * *before* which the decimal point should be inserted
+          * (starting with 0 for the first digit).  Note that this
+          * works even if 10^exp_b10 is out of range because of the
+          * test on DBL_MAX above.
+          */
+         fp /= base;
+         while (fp >= 1) fp /= 10, ++exp_b10;
+
+         /* Because of the code above fp may, at this point, be
+          * less than .1, this is ok because the code below can
+          * handle the leading zeros this generates, so no attempt
+          * is made to correct that here.
+          */
+
+         {
+            int czero, clead, cdigits;
+            char exponent[10];
+
+            /* Allow up to two leading zeros - this will not lengthen
+             * the number compared to using E-n.
+             */
+            if (exp_b10 < 0 && exp_b10 > -3) /* PLUS 3 TOTAL 4 */
+            {
+               czero = -exp_b10; /* PLUS 2 digits: TOTAL 3 */
+               exp_b10 = 0;      /* Dot added below before first output. */
+            }
+            else
+               czero = 0;    /* No zeros to add */
+
+            /* Generate the digit list, stripping trailing zeros and
+             * inserting a '.' before a digit if the exponent is 0.
+             */
+            clead = czero; /* Count of leading zeros */
+            cdigits = 0;   /* Count of digits in list. */
+
+            do
+            {
+               double d;
+
+               fp *= 10;
+               /* Use modf here, not floor and subtract, so that
+                * the separation is done in one step.  At the end
+                * of the loop don't break the number into parts so
+                * that the final digit is rounded.
+                */
+               if (cdigits+czero-clead+1 < (int)precision)
+                  fp = modf(fp, &d);
+
+               else
+               {
+                  d = floor(fp + .5);
+
+                  if (d > 9)
+                  {
+                     /* Rounding up to 10, handle that here. */
+                     if (czero > 0)
+                     {
+                        --czero, d = 1;
+                        if (cdigits == 0) --clead;
+                     }
+                     else
+                     {
+                        while (cdigits > 0 && d > 9)
+                        {
+                           int ch = *--ascii;
+
+                           if (exp_b10 != (-1))
+                              ++exp_b10;
+
+                           else if (ch == 46)
+                           {
+                              ch = *--ascii, ++size;
+                              /* Advance exp_b10 to '1', so that the
+                               * decimal point happens after the
+                               * previous digit.
+                               */
+                              exp_b10 = 1;
+                           }
+
+                           --cdigits;
+                           d = ch - 47;  /* I.e. 1+(ch-48) */
+                        }
+
+                        /* Did we reach the beginning? If so adjust the
+                         * exponent but take into account the leading
+                         * decimal point.
+                         */
+                        if (d > 9)  /* cdigits == 0 */
+                        {
+                           if (exp_b10 == (-1))
+                           {
+                              /* Leading decimal point (plus zeros?), if
+                               * we lose the decimal point here it must
+                               * be reentered below.
+                               */
+                              int ch = *--ascii;
+
+                              if (ch == 46)
+                                 ++size, exp_b10 = 1;
+
+                              /* Else lost a leading zero, so 'exp_b10' is
+                               * still ok at (-1)
+                               */
+                           }
+                           else
+                              ++exp_b10;
+
+                           /* In all cases we output a '1' */
+                           d = 1;
+                        }
+                     }
+                  }
+                  fp = 0; /* Guarantees termination below. */
+               }
+
+               if (d == 0)
+               {
+                  ++czero;
+                  if (cdigits == 0) ++clead;
+               }
+               else
+               {
+                  /* Included embedded zeros in the digit count. */
+                  cdigits += czero - clead;
+                  clead = 0;
+
+                  while (czero > 0)
+                  {
+                     /* exp_b10 == (-1) means we just output the decimal
+                      * place - after the DP don't adjust 'exp_b10' any
+                      * more!
+                      */
+                     if (exp_b10 != (-1))
+                     {
+                        if (exp_b10 == 0) *ascii++ = 46, --size;
+                        /* PLUS 1: TOTAL 4 */
+                        --exp_b10;
+                     }
+                     *ascii++ = 48, --czero;
+                  }
+
+                  if (exp_b10 != (-1))
+                  {
+                     if (exp_b10 == 0)
+                        *ascii++ = 46, --size; /* counted above */
+
+                     --exp_b10;
+                  }
+                  *ascii++ = (char)(48 + (int)d), ++cdigits;
+               }
+            }
+            while (cdigits+czero-clead < (int)precision && fp > DBL_MIN);
+
+            /* The total output count (max) is now 4+precision */
+
+            /* Check for an exponent, if we don't need one we are
+             * done and just need to terminate the string.  At
+             * this point exp_b10==(-1) is effectively if flag - it got
+             * to '-1' because of the decrement after outputing
+             * the decimal point above (the exponent required is
+             * *not* -1!)
+             */
+            if (exp_b10 >= (-1) && exp_b10 <= 2)
+            {
+               /* The following only happens if we didn't output the
+                * leading zeros above for negative exponent, so this
+                * doest add to the digit requirement.  Note that the
+                * two zeros here can only be output if the two leading
+                * zeros were *not* output, so this doesn't increase
+                * the output count.
+                */
+               while (--exp_b10 >= 0) *ascii++ = 48;
+
+               *ascii = 0;
+
+               /* Total buffer requirement (including the '\0') is
+                * 5+precision - see check at the start.
+                */
+               return;
+            }
+
+            /* Here if an exponent is required, adjust size for
+             * the digits we output but did not count.  The total
+             * digit output here so far is at most 1+precision - no
+             * decimal point and no leading or trailing zeros have
+             * been output.
+             */
+            size -= cdigits;
+
+            *ascii++ = 69, --size;    /* 'E': PLUS 1 TOTAL 2+precision */
+
+            /* The following use of an unsigned temporary avoids ambiguities in
+             * the signed arithmetic on exp_b10 and permits GCC at least to do
+             * better optimization.
+             */
+            {
+               unsigned int uexp_b10;
+
+               if (exp_b10 < 0)
+               {
+                  *ascii++ = 45, --size; /* '-': PLUS 1 TOTAL 3+precision */
+                  uexp_b10 = -exp_b10;
+               }
+
+               else
+                  uexp_b10 = exp_b10;
+
+               cdigits = 0;
+
+               while (uexp_b10 > 0)
+               {
+                  exponent[cdigits++] = (char)(48 + uexp_b10 % 10);
+                  uexp_b10 /= 10;
+               }
+            }
+
+            /* Need another size check here for the exponent digits, so
+             * this need not be considered above.
+             */
+            if ((int)size > cdigits)
+            {
+               while (cdigits > 0) *ascii++ = exponent[--cdigits];
+
+               *ascii = 0;
+
+               return;
+            }
+         }
+      }
+      else if (!(fp >= DBL_MIN))
+      {
+         *ascii++ = 48; /* '0' */
+         *ascii = 0;
+         return;
+      }
+      else
+      {
+         *ascii++ = 105; /* 'i' */
+         *ascii++ = 110; /* 'n' */
+         *ascii++ = 102; /* 'f' */
+         *ascii = 0;
+         return;
+      }
+   }
+
+   /* Here on buffer too small. */
+   png_error(png_ptr, "ASCII conversion buffer too small");
+}
+
+#  endif /* FLOATING_POINT */
+
+#  ifdef PNG_FIXED_POINT_SUPPORTED
+/* Function to format a fixed point value in ASCII.
+ */
+void /* PRIVATE */
+png_ascii_from_fixed(png_const_structrp png_ptr, png_charp ascii,
+    png_size_t size, png_fixed_point fp)
+{
+   /* Require space for 10 decimal digits, a decimal point, a minus sign and a
+    * trailing \0, 13 characters:
+    */
+   if (size > 12)
+   {
+      png_uint_32 num;
+
+      /* Avoid overflow here on the minimum integer. */
+      if (fp < 0)
+         *ascii++ = 45, --size, num = -fp;
+      else
+         num = fp;
+
+      if (num <= 0x80000000) /* else overflowed */
+      {
+         unsigned int ndigits = 0, first = 16 /* flag value */;
+         char digits[10];
+
+         while (num)
+         {
+            /* Split the low digit off num: */
+            unsigned int tmp = num/10;
+            num -= tmp*10;
+            digits[ndigits++] = (char)(48 + num);
+            /* Record the first non-zero digit, note that this is a number
+             * starting at 1, it's not actually the array index.
+             */
+            if (first == 16 && num > 0)
+               first = ndigits;
+            num = tmp;
+         }
+
+         if (ndigits > 0)
+         {
+            while (ndigits > 5) *ascii++ = digits[--ndigits];
+            /* The remaining digits are fractional digits, ndigits is '5' or
+             * smaller at this point.  It is certainly not zero.  Check for a
+             * non-zero fractional digit:
+             */
+            if (first <= 5)
+            {
+               unsigned int i;
+               *ascii++ = 46; /* decimal point */
+               /* ndigits may be <5 for small numbers, output leading zeros
+                * then ndigits digits to first:
+                */
+               i = 5;
+               while (ndigits < i) *ascii++ = 48, --i;
+               while (ndigits >= first) *ascii++ = digits[--ndigits];
+               /* Don't output the trailing zeros! */
+            }
+         }
+         else
+            *ascii++ = 48;
+
+         /* And null terminate the string: */
+         *ascii = 0;
+         return;
+      }
+   }
+
+   /* Here on buffer too small. */
+   png_error(png_ptr, "ASCII conversion buffer too small");
+}
+#   endif /* FIXED_POINT */
+#endif /* READ_SCAL */
+
+#if defined(PNG_FLOATING_POINT_SUPPORTED) && \
+   !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \
+   (defined(PNG_gAMA_SUPPORTED) || defined(PNG_cHRM_SUPPORTED) || \
+   defined(PNG_sCAL_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) || \
+   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)) || \
+   (defined(PNG_sCAL_SUPPORTED) && \
+   defined(PNG_FLOATING_ARITHMETIC_SUPPORTED))
+png_fixed_point
+png_fixed(png_const_structrp png_ptr, double fp, png_const_charp text)
+{
+   double r = floor(100000 * fp + .5);
+
+   if (r > 2147483647. || r < -2147483648.)
+      png_fixed_error(png_ptr, text);
+
+#  ifndef PNG_ERROR_TEXT_SUPPORTED
+      PNG_UNUSED(text)
+#  endif
+
+   return (png_fixed_point)r;
+}
+#endif
+
+#if defined(PNG_GAMMA_SUPPORTED) || defined(PNG_COLORSPACE_SUPPORTED) ||\
+    defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG_READ_pHYs_SUPPORTED)
+/* muldiv functions */
+/* This API takes signed arguments and rounds the result to the nearest
+ * integer (or, for a fixed point number - the standard argument - to
+ * the nearest .00001).  Overflow and divide by zero are signalled in
+ * the result, a boolean - true on success, false on overflow.
+ */
+int
+png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times,
+    png_int_32 divisor)
+{
+   /* Return a * times / divisor, rounded. */
+   if (divisor != 0)
+   {
+      if (a == 0 || times == 0)
+      {
+         *res = 0;
+         return 1;
+      }
+      else
+      {
+#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
+         double r = a;
+         r *= times;
+         r /= divisor;
+         r = floor(r+.5);
+
+         /* A png_fixed_point is a 32-bit integer. */
+         if (r <= 2147483647. && r >= -2147483648.)
+         {
+            *res = (png_fixed_point)r;
+            return 1;
+         }
+#else
+         int negative = 0;
+         png_uint_32 A, T, D;
+         png_uint_32 s16, s32, s00;
+
+         if (a < 0)
+            negative = 1, A = -a;
+         else
+            A = a;
+
+         if (times < 0)
+            negative = !negative, T = -times;
+         else
+            T = times;
+
+         if (divisor < 0)
+            negative = !negative, D = -divisor;
+         else
+            D = divisor;
+
+         /* Following can't overflow because the arguments only
+          * have 31 bits each, however the result may be 32 bits.
+          */
+         s16 = (A >> 16) * (T & 0xffff) +
+                           (A & 0xffff) * (T >> 16);
+         /* Can't overflow because the a*times bit is only 30
+          * bits at most.
+          */
+         s32 = (A >> 16) * (T >> 16) + (s16 >> 16);
+         s00 = (A & 0xffff) * (T & 0xffff);
+
+         s16 = (s16 & 0xffff) << 16;
+         s00 += s16;
+
+         if (s00 < s16)
+            ++s32; /* carry */
+
+         if (s32 < D) /* else overflow */
+         {
+            /* s32.s00 is now the 64-bit product, do a standard
+             * division, we know that s32 < D, so the maximum
+             * required shift is 31.
+             */
+            int bitshift = 32;
+            png_fixed_point result = 0; /* NOTE: signed */
+
+            while (--bitshift >= 0)
+            {
+               png_uint_32 d32, d00;
+
+               if (bitshift > 0)
+                  d32 = D >> (32-bitshift), d00 = D << bitshift;
+
+               else
+                  d32 = 0, d00 = D;
+
+               if (s32 > d32)
+               {
+                  if (s00 < d00) --s32; /* carry */
+                  s32 -= d32, s00 -= d00, result += 1<<bitshift;
+               }
+
+               else
+                  if (s32 == d32 && s00 >= d00)
+                     s32 = 0, s00 -= d00, result += 1<<bitshift;
+            }
+
+            /* Handle the rounding. */
+            if (s00 >= (D >> 1))
+               ++result;
+
+            if (negative != 0)
+               result = -result;
+
+            /* Check for overflow. */
+            if ((negative != 0 && result <= 0) ||
+                (negative == 0 && result >= 0))
+            {
+               *res = result;
+               return 1;
+            }
+         }
+#endif
+      }
+   }
+
+   return 0;
+}
+#endif /* READ_GAMMA || INCH_CONVERSIONS */
+
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED)
+/* The following is for when the caller doesn't much care about the
+ * result.
+ */
+png_fixed_point
+png_muldiv_warn(png_const_structrp png_ptr, png_fixed_point a, png_int_32 times,
+    png_int_32 divisor)
+{
+   png_fixed_point result;
+
+   if (png_muldiv(&result, a, times, divisor) != 0)
+      return result;
+
+   png_warning(png_ptr, "fixed point overflow ignored");
+   return 0;
+}
+#endif
+
+#ifdef PNG_GAMMA_SUPPORTED /* more fixed point functions for gamma */
+/* Calculate a reciprocal, return 0 on div-by-zero or overflow. */
+png_fixed_point
+png_reciprocal(png_fixed_point a)
+{
+#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
+   double r = floor(1E10/a+.5);
+
+   if (r <= 2147483647. && r >= -2147483648.)
+      return (png_fixed_point)r;
+#else
+   png_fixed_point res;
+
+   if (png_muldiv(&res, 100000, 100000, a) != 0)
+      return res;
+#endif
+
+   return 0; /* error/overflow */
+}
+
+/* This is the shared test on whether a gamma value is 'significant' - whether
+ * it is worth doing gamma correction.
+ */
+int /* PRIVATE */
+png_gamma_significant(png_fixed_point gamma_val)
+{
+   return gamma_val < PNG_FP_1 - PNG_GAMMA_THRESHOLD_FIXED ||
+       gamma_val > PNG_FP_1 + PNG_GAMMA_THRESHOLD_FIXED;
+}
+#endif
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+#if defined(PNG_16BIT_SUPPORTED) || !defined(PNG_FLOATING_ARITHMETIC_SUPPORTED)
+/* A local convenience routine. */
+static png_fixed_point
+png_product2(png_fixed_point a, png_fixed_point b)
+{
+   /* The required result is 1/a * 1/b; the following preserves accuracy. */
+#    ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
+   double r = a * 1E-5;
+   r *= b;
+   r = floor(r+.5);
+
+   if (r <= 2147483647. && r >= -2147483648.)
+      return (png_fixed_point)r;
+#    else
+   png_fixed_point res;
+
+   if (png_muldiv(&res, a, b, 100000) != 0)
+      return res;
+#    endif
+
+   return 0; /* overflow */
+}
+#endif /* 16BIT || !FLOATING_ARITHMETIC */
+
+/* The inverse of the above. */
+png_fixed_point
+png_reciprocal2(png_fixed_point a, png_fixed_point b)
+{
+   /* The required result is 1/a * 1/b; the following preserves accuracy. */
+#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
+   double r = 1E15/a;
+   r /= b;
+   r = floor(r+.5);
+
+   if (r <= 2147483647. && r >= -2147483648.)
+      return (png_fixed_point)r;
+#else
+   /* This may overflow because the range of png_fixed_point isn't symmetric,
+    * but this API is only used for the product of file and screen gamma so it
+    * doesn't matter that the smallest number it can produce is 1/21474, not
+    * 1/100000
+    */
+   png_fixed_point res = png_product2(a, b);
+
+   if (res != 0)
+      return png_reciprocal(res);
+#endif
+
+   return 0; /* overflow */
+}
+#endif /* READ_GAMMA */
+
+#ifdef PNG_READ_GAMMA_SUPPORTED /* gamma table code */
+#ifndef PNG_FLOATING_ARITHMETIC_SUPPORTED
+/* Fixed point gamma.
+ *
+ * The code to calculate the tables used below can be found in the shell script
+ * contrib/tools/intgamma.sh
+ *
+ * To calculate gamma this code implements fast log() and exp() calls using only
+ * fixed point arithmetic.  This code has sufficient precision for either 8-bit
+ * or 16-bit sample values.
+ *
+ * The tables used here were calculated using simple 'bc' programs, but C double
+ * precision floating point arithmetic would work fine.
+ *
+ * 8-bit log table
+ *   This is a table of -log(value/255)/log(2) for 'value' in the range 128 to
+ *   255, so it's the base 2 logarithm of a normalized 8-bit floating point
+ *   mantissa.  The numbers are 32-bit fractions.
+ */
+static const png_uint_32
+png_8bit_l2[128] =
+{
+   4270715492U, 4222494797U, 4174646467U, 4127164793U, 4080044201U, 4033279239U,
+   3986864580U, 3940795015U, 3895065449U, 3849670902U, 3804606499U, 3759867474U,
+   3715449162U, 3671346997U, 3627556511U, 3584073329U, 3540893168U, 3498011834U,
+   3455425220U, 3413129301U, 3371120137U, 3329393864U, 3287946700U, 3246774933U,
+   3205874930U, 3165243125U, 3124876025U, 3084770202U, 3044922296U, 3005329011U,
+   2965987113U, 2926893432U, 2888044853U, 2849438323U, 2811070844U, 2772939474U,
+   2735041326U, 2697373562U, 2659933400U, 2622718104U, 2585724991U, 2548951424U,
+   2512394810U, 2476052606U, 2439922311U, 2404001468U, 2368287663U, 2332778523U,
+   2297471715U, 2262364947U, 2227455964U, 2192742551U, 2158222529U, 2123893754U,
+   2089754119U, 2055801552U, 2022034013U, 1988449497U, 1955046031U, 1921821672U,
+   1888774511U, 1855902668U, 1823204291U, 1790677560U, 1758320682U, 1726131893U,
+   1694109454U, 1662251657U, 1630556815U, 1599023271U, 1567649391U, 1536433567U,
+   1505374214U, 1474469770U, 1443718700U, 1413119487U, 1382670639U, 1352370686U,
+   1322218179U, 1292211689U, 1262349810U, 1232631153U, 1203054352U, 1173618059U,
+   1144320946U, 1115161701U, 1086139034U, 1057251672U, 1028498358U, 999877854U,
+   971388940U, 943030410U, 914801076U, 886699767U, 858725327U, 830876614U,
+   803152505U, 775551890U, 748073672U, 720716771U, 693480120U, 666362667U,
+   639363374U, 612481215U, 585715177U, 559064263U, 532527486U, 506103872U,
+   479792461U, 453592303U, 427502463U, 401522014U, 375650043U, 349885648U,
+   324227938U, 298676034U, 273229066U, 247886176U, 222646516U, 197509248U,
+   172473545U, 147538590U, 122703574U, 97967701U, 73330182U, 48790236U,
+   24347096U, 0U
+
+#if 0
+   /* The following are the values for 16-bit tables - these work fine for the
+    * 8-bit conversions but produce very slightly larger errors in the 16-bit
+    * log (about 1.2 as opposed to 0.7 absolute error in the final value).  To
+    * use these all the shifts below must be adjusted appropriately.
+    */
+   65166, 64430, 63700, 62976, 62257, 61543, 60835, 60132, 59434, 58741, 58054,
+   57371, 56693, 56020, 55352, 54689, 54030, 53375, 52726, 52080, 51439, 50803,
+   50170, 49542, 48918, 48298, 47682, 47070, 46462, 45858, 45257, 44661, 44068,
+   43479, 42894, 42312, 41733, 41159, 40587, 40020, 39455, 38894, 38336, 37782,
+   37230, 36682, 36137, 35595, 35057, 34521, 33988, 33459, 32932, 32408, 31887,
+   31369, 30854, 30341, 29832, 29325, 28820, 28319, 27820, 27324, 26830, 26339,
+   25850, 25364, 24880, 24399, 23920, 23444, 22970, 22499, 22029, 21562, 21098,
+   20636, 20175, 19718, 19262, 18808, 18357, 17908, 17461, 17016, 16573, 16132,
+   15694, 15257, 14822, 14390, 13959, 13530, 13103, 12678, 12255, 11834, 11415,
+   10997, 10582, 10168, 9756, 9346, 8937, 8531, 8126, 7723, 7321, 6921, 6523,
+   6127, 5732, 5339, 4947, 4557, 4169, 3782, 3397, 3014, 2632, 2251, 1872, 1495,
+   1119, 744, 372
+#endif
+};
+
+static png_int_32
+png_log8bit(unsigned int x)
+{
+   unsigned int lg2 = 0;
+   /* Each time 'x' is multiplied by 2, 1 must be subtracted off the final log,
+    * because the log is actually negate that means adding 1.  The final
+    * returned value thus has the range 0 (for 255 input) to 7.994 (for 1
+    * input), return -1 for the overflow (log 0) case, - so the result is
+    * always at most 19 bits.
+    */
+   if ((x &= 0xff) == 0)
+      return -1;
+
+   if ((x & 0xf0) == 0)
+      lg2  = 4, x <<= 4;
+
+   if ((x & 0xc0) == 0)
+      lg2 += 2, x <<= 2;
+
+   if ((x & 0x80) == 0)
+      lg2 += 1, x <<= 1;
+
+   /* result is at most 19 bits, so this cast is safe: */
+   return (png_int_32)((lg2 << 16) + ((png_8bit_l2[x-128]+32768)>>16));
+}
+
+/* The above gives exact (to 16 binary places) log2 values for 8-bit images,
+ * for 16-bit images we use the most significant 8 bits of the 16-bit value to
+ * get an approximation then multiply the approximation by a correction factor
+ * determined by the remaining up to 8 bits.  This requires an additional step
+ * in the 16-bit case.
+ *
+ * We want log2(value/65535), we have log2(v'/255), where:
+ *
+ *    value = v' * 256 + v''
+ *          = v' * f
+ *
+ * So f is value/v', which is equal to (256+v''/v') since v' is in the range 128
+ * to 255 and v'' is in the range 0 to 255 f will be in the range 256 to less
+ * than 258.  The final factor also needs to correct for the fact that our 8-bit
+ * value is scaled by 255, whereas the 16-bit values must be scaled by 65535.
+ *
+ * This gives a final formula using a calculated value 'x' which is value/v' and
+ * scaling by 65536 to match the above table:
+ *
+ *   log2(x/257) * 65536
+ *
+ * Since these numbers are so close to '1' we can use simple linear
+ * interpolation between the two end values 256/257 (result -368.61) and 258/257
+ * (result 367.179).  The values used below are scaled by a further 64 to give
+ * 16-bit precision in the interpolation:
+ *
+ * Start (256): -23591
+ * Zero  (257):      0
+ * End   (258):  23499
+ */
+#ifdef PNG_16BIT_SUPPORTED
+static png_int_32
+png_log16bit(png_uint_32 x)
+{
+   unsigned int lg2 = 0;
+
+   /* As above, but now the input has 16 bits. */
+   if ((x &= 0xffff) == 0)
+      return -1;
+
+   if ((x & 0xff00) == 0)
+      lg2  = 8, x <<= 8;
+
+   if ((x & 0xf000) == 0)
+      lg2 += 4, x <<= 4;
+
+   if ((x & 0xc000) == 0)
+      lg2 += 2, x <<= 2;
+
+   if ((x & 0x8000) == 0)
+      lg2 += 1, x <<= 1;
+
+   /* Calculate the base logarithm from the top 8 bits as a 28-bit fractional
+    * value.
+    */
+   lg2 <<= 28;
+   lg2 += (png_8bit_l2[(x>>8)-128]+8) >> 4;
+
+   /* Now we need to interpolate the factor, this requires a division by the top
+    * 8 bits.  Do this with maximum precision.
+    */
+   x = ((x << 16) + (x >> 9)) / (x >> 8);
+
+   /* Since we divided by the top 8 bits of 'x' there will be a '1' at 1<<24,
+    * the value at 1<<16 (ignoring this) will be 0 or 1; this gives us exactly
+    * 16 bits to interpolate to get the low bits of the result.  Round the
+    * answer.  Note that the end point values are scaled by 64 to retain overall
+    * precision and that 'lg2' is current scaled by an extra 12 bits, so adjust
+    * the overall scaling by 6-12.  Round at every step.
+    */
+   x -= 1U << 24;
+
+   if (x <= 65536U) /* <= '257' */
+      lg2 += ((23591U * (65536U-x)) + (1U << (16+6-12-1))) >> (16+6-12);
+
+   else
+      lg2 -= ((23499U * (x-65536U)) + (1U << (16+6-12-1))) >> (16+6-12);
+
+   /* Safe, because the result can't have more than 20 bits: */
+   return (png_int_32)((lg2 + 2048) >> 12);
+}
+#endif /* 16BIT */
+
+/* The 'exp()' case must invert the above, taking a 20-bit fixed point
+ * logarithmic value and returning a 16 or 8-bit number as appropriate.  In
+ * each case only the low 16 bits are relevant - the fraction - since the
+ * integer bits (the top 4) simply determine a shift.
+ *
+ * The worst case is the 16-bit distinction between 65535 and 65534. This
+ * requires perhaps spurious accuracy in the decoding of the logarithm to
+ * distinguish log2(65535/65534.5) - 10^-5 or 17 bits.  There is little chance
+ * of getting this accuracy in practice.
+ *
+ * To deal with this the following exp() function works out the exponent of the
+ * frational part of the logarithm by using an accurate 32-bit value from the
+ * top four fractional bits then multiplying in the remaining bits.
+ */
+static const png_uint_32
+png_32bit_exp[16] =
+{
+   /* NOTE: the first entry is deliberately set to the maximum 32-bit value. */
+   4294967295U, 4112874773U, 3938502376U, 3771522796U, 3611622603U, 3458501653U,
+   3311872529U, 3171459999U, 3037000500U, 2908241642U, 2784941738U, 2666869345U,
+   2553802834U, 2445529972U, 2341847524U, 2242560872U
+};
+
+/* Adjustment table; provided to explain the numbers in the code below. */
+#if 0
+for (i=11;i>=0;--i){ print i, " ", (1 - e(-(2^i)/65536*l(2))) * 2^(32-i), "\n"}
+   11 44937.64284865548751208448
+   10 45180.98734845585101160448
+    9 45303.31936980687359311872
+    8 45364.65110595323018870784
+    7 45395.35850361789624614912
+    6 45410.72259715102037508096
+    5 45418.40724413220722311168
+    4 45422.25021786898173001728
+    3 45424.17186732298419044352
+    2 45425.13273269940811464704
+    1 45425.61317555035558641664
+    0 45425.85339951654943850496
+#endif
+
+static png_uint_32
+png_exp(png_fixed_point x)
+{
+   if (x > 0 && x <= 0xfffff) /* Else overflow or zero (underflow) */
+   {
+      /* Obtain a 4-bit approximation */
+      png_uint_32 e = png_32bit_exp[(x >> 12) & 0xf];
+
+      /* Incorporate the low 12 bits - these decrease the returned value by
+       * multiplying by a number less than 1 if the bit is set.  The multiplier
+       * is determined by the above table and the shift. Notice that the values
+       * converge on 45426 and this is used to allow linear interpolation of the
+       * low bits.
+       */
+      if (x & 0x800)
+         e -= (((e >> 16) * 44938U) +  16U) >> 5;
+
+      if (x & 0x400)
+         e -= (((e >> 16) * 45181U) +  32U) >> 6;
+
+      if (x & 0x200)
+         e -= (((e >> 16) * 45303U) +  64U) >> 7;
+
+      if (x & 0x100)
+         e -= (((e >> 16) * 45365U) + 128U) >> 8;
+
+      if (x & 0x080)
+         e -= (((e >> 16) * 45395U) + 256U) >> 9;
+
+      if (x & 0x040)
+         e -= (((e >> 16) * 45410U) + 512U) >> 10;
+
+      /* And handle the low 6 bits in a single block. */
+      e -= (((e >> 16) * 355U * (x & 0x3fU)) + 256U) >> 9;
+
+      /* Handle the upper bits of x. */
+      e >>= x >> 16;
+      return e;
+   }
+
+   /* Check for overflow */
+   if (x <= 0)
+      return png_32bit_exp[0];
+
+   /* Else underflow */
+   return 0;
+}
+
+static png_byte
+png_exp8bit(png_fixed_point lg2)
+{
+   /* Get a 32-bit value: */
+   png_uint_32 x = png_exp(lg2);
+
+   /* Convert the 32-bit value to 0..255 by multiplying by 256-1. Note that the
+    * second, rounding, step can't overflow because of the first, subtraction,
+    * step.
+    */
+   x -= x >> 8;
+   return (png_byte)((x + 0x7fffffU) >> 24);
+}
+
+#ifdef PNG_16BIT_SUPPORTED
+static png_uint_16
+png_exp16bit(png_fixed_point lg2)
+{
+   /* Get a 32-bit value: */
+   png_uint_32 x = png_exp(lg2);
+
+   /* Convert the 32-bit value to 0..65535 by multiplying by 65536-1: */
+   x -= x >> 16;
+   return (png_uint_16)((x + 32767U) >> 16);
+}
+#endif /* 16BIT */
+#endif /* FLOATING_ARITHMETIC */
+
+png_byte
+png_gamma_8bit_correct(unsigned int value, png_fixed_point gamma_val)
+{
+   if (value > 0 && value < 255)
+   {
+#     ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
+         /* 'value' is unsigned, ANSI-C90 requires the compiler to correctly
+          * convert this to a floating point value.  This includes values that
+          * would overflow if 'value' were to be converted to 'int'.
+          *
+          * Apparently GCC, however, does an intermediate conversion to (int)
+          * on some (ARM) but not all (x86) platforms, possibly because of
+          * hardware FP limitations.  (E.g. if the hardware conversion always
+          * assumes the integer register contains a signed value.)  This results
+          * in ANSI-C undefined behavior for large values.
+          *
+          * Other implementations on the same machine might actually be ANSI-C90
+          * conformant and therefore compile spurious extra code for the large
+          * values.
+          *
+          * We can be reasonably sure that an unsigned to float conversion
+          * won't be faster than an int to float one.  Therefore this code
+          * assumes responsibility for the undefined behavior, which it knows
+          * can't happen because of the check above.
+          *
+          * Note the argument to this routine is an (unsigned int) because, on
+          * 16-bit platforms, it is assigned a value which might be out of
+          * range for an (int); that would result in undefined behavior in the
+          * caller if the *argument* ('value') were to be declared (int).
+          */
+         double r = floor(255*pow((int)/*SAFE*/value/255.,gamma_val*.00001)+.5);
+         return (png_byte)r;
+#     else
+         png_int_32 lg2 = png_log8bit(value);
+         png_fixed_point res;
+
+         if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1) != 0)
+            return png_exp8bit(res);
+
+         /* Overflow. */
+         value = 0;
+#     endif
+   }
+
+   return (png_byte)value;
+}
+
+#ifdef PNG_16BIT_SUPPORTED
+png_uint_16
+png_gamma_16bit_correct(unsigned int value, png_fixed_point gamma_val)
+{
+   if (value > 0 && value < 65535)
+   {
+#     ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
+         /* The same (unsigned int)->(double) constraints apply here as above,
+          * however in this case the (unsigned int) to (int) conversion can
+          * overflow on an ANSI-C90 compliant system so the cast needs to ensure
+          * that this is not possible.
+          */
+         double r = floor(65535*pow((png_int_32)value/65535.,
+                     gamma_val*.00001)+.5);
+         return (png_uint_16)r;
+#     else
+         png_int_32 lg2 = png_log16bit(value);
+         png_fixed_point res;
+
+         if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1) != 0)
+            return png_exp16bit(res);
+
+         /* Overflow. */
+         value = 0;
+#     endif
+   }
+
+   return (png_uint_16)value;
+}
+#endif /* 16BIT */
+
+/* This does the right thing based on the bit_depth field of the
+ * png_struct, interpreting values as 8-bit or 16-bit.  While the result
+ * is nominally a 16-bit value if bit depth is 8 then the result is
+ * 8-bit (as are the arguments.)
+ */
+png_uint_16 /* PRIVATE */
+png_gamma_correct(png_structrp png_ptr, unsigned int value,
+    png_fixed_point gamma_val)
+{
+   if (png_ptr->bit_depth == 8)
+      return png_gamma_8bit_correct(value, gamma_val);
+
+#ifdef PNG_16BIT_SUPPORTED
+   else
+      return png_gamma_16bit_correct(value, gamma_val);
+#else
+      /* should not reach this */
+      return 0;
+#endif /* 16BIT */
+}
+
+#ifdef PNG_16BIT_SUPPORTED
+/* Internal function to build a single 16-bit table - the table consists of
+ * 'num' 256 entry subtables, where 'num' is determined by 'shift' - the amount
+ * to shift the input values right (or 16-number_of_signifiant_bits).
+ *
+ * The caller is responsible for ensuring that the table gets cleaned up on
+ * png_error (i.e. if one of the mallocs below fails) - i.e. the *table argument
+ * should be somewhere that will be cleaned.
+ */
+static void
+png_build_16bit_table(png_structrp png_ptr, png_uint_16pp *ptable,
+   PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val)
+{
+   /* Various values derived from 'shift': */
+   PNG_CONST unsigned int num = 1U << (8U - shift);
+#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
+   /* CSE the division and work round wacky GCC warnings (see the comments
+    * in png_gamma_8bit_correct for where these come from.)
+    */
+   PNG_CONST double fmax = 1./(((png_int_32)1 << (16U - shift))-1);
+#endif
+   PNG_CONST unsigned int max = (1U << (16U - shift))-1U;
+   PNG_CONST unsigned int max_by_2 = 1U << (15U-shift);
+   unsigned int i;
+
+   png_uint_16pp table = *ptable =
+       (png_uint_16pp)png_calloc(png_ptr, num * (sizeof (png_uint_16p)));
+
+   for (i = 0; i < num; i++)
+   {
+      png_uint_16p sub_table = table[i] =
+          (png_uint_16p)png_malloc(png_ptr, 256 * (sizeof (png_uint_16)));
+
+      /* The 'threshold' test is repeated here because it can arise for one of
+       * the 16-bit tables even if the others don't hit it.
+       */
+      if (png_gamma_significant(gamma_val) != 0)
+      {
+         /* The old code would overflow at the end and this would cause the
+          * 'pow' function to return a result >1, resulting in an
+          * arithmetic error.  This code follows the spec exactly; ig is
+          * the recovered input sample, it always has 8-16 bits.
+          *
+          * We want input * 65535/max, rounded, the arithmetic fits in 32
+          * bits (unsigned) so long as max <= 32767.
+          */
+         unsigned int j;
+         for (j = 0; j < 256; j++)
+         {
+            png_uint_32 ig = (j << (8-shift)) + i;
+#           ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
+               /* Inline the 'max' scaling operation: */
+               /* See png_gamma_8bit_correct for why the cast to (int) is
+                * required here.
+                */
+               double d = floor(65535.*pow(ig*fmax, gamma_val*.00001)+.5);
+               sub_table[j] = (png_uint_16)d;
+#           else
+               if (shift != 0)
+                  ig = (ig * 65535U + max_by_2)/max;
+
+               sub_table[j] = png_gamma_16bit_correct(ig, gamma_val);
+#           endif
+         }
+      }
+      else
+      {
+         /* We must still build a table, but do it the fast way. */
+         unsigned int j;
+
+         for (j = 0; j < 256; j++)
+         {
+            png_uint_32 ig = (j << (8-shift)) + i;
+
+            if (shift != 0)
+               ig = (ig * 65535U + max_by_2)/max;
+
+            sub_table[j] = (png_uint_16)ig;
+         }
+      }
+   }
+}
+
+/* NOTE: this function expects the *inverse* of the overall gamma transformation
+ * required.
+ */
+static void
+png_build_16to8_table(png_structrp png_ptr, png_uint_16pp *ptable,
+   PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val)
+{
+   PNG_CONST unsigned int num = 1U << (8U - shift);
+   PNG_CONST unsigned int max = (1U << (16U - shift))-1U;
+   unsigned int i;
+   png_uint_32 last;
+
+   png_uint_16pp table = *ptable =
+       (png_uint_16pp)png_calloc(png_ptr, num * (sizeof (png_uint_16p)));
+
+   /* 'num' is the number of tables and also the number of low bits of low
+    * bits of the input 16-bit value used to select a table.  Each table is
+    * itself indexed by the high 8 bits of the value.
+    */
+   for (i = 0; i < num; i++)
+      table[i] = (png_uint_16p)png_malloc(png_ptr,
+          256 * (sizeof (png_uint_16)));
+
+   /* 'gamma_val' is set to the reciprocal of the value calculated above, so
+    * pow(out,g) is an *input* value.  'last' is the last input value set.
+    *
+    * In the loop 'i' is used to find output values.  Since the output is
+    * 8-bit there are only 256 possible values.  The tables are set up to
+    * select the closest possible output value for each input by finding
+    * the input value at the boundary between each pair of output values
+    * and filling the table up to that boundary with the lower output
+    * value.
+    *
+    * The boundary values are 0.5,1.5..253.5,254.5.  Since these are 9-bit
+    * values the code below uses a 16-bit value in i; the values start at
+    * 128.5 (for 0.5) and step by 257, for a total of 254 values (the last
+    * entries are filled with 255).  Start i at 128 and fill all 'last'
+    * table entries <= 'max'
+    */
+   last = 0;
+   for (i = 0; i < 255; ++i) /* 8-bit output value */
+   {
+      /* Find the corresponding maximum input value */
+      png_uint_16 out = (png_uint_16)(i * 257U); /* 16-bit output value */
+
+      /* Find the boundary value in 16 bits: */
+      png_uint_32 bound = png_gamma_16bit_correct(out+128U, gamma_val);
+
+      /* Adjust (round) to (16-shift) bits: */
+      bound = (bound * max + 32768U)/65535U + 1U;
+
+      while (last < bound)
+      {
+         table[last & (0xffU >> shift)][last >> (8U - shift)] = out;
+         last++;
+      }
+   }
+
+   /* And fill in the final entries. */
+   while (last < (num << 8))
+   {
+      table[last & (0xff >> shift)][last >> (8U - shift)] = 65535U;
+      last++;
+   }
+}
+#endif /* 16BIT */
+
+/* Build a single 8-bit table: same as the 16-bit case but much simpler (and
+ * typically much faster).  Note that libpng currently does no sBIT processing
+ * (apparently contrary to the spec) so a 256-entry table is always generated.
+ */
+static void
+png_build_8bit_table(png_structrp png_ptr, png_bytepp ptable,
+   PNG_CONST png_fixed_point gamma_val)
+{
+   unsigned int i;
+   png_bytep table = *ptable = (png_bytep)png_malloc(png_ptr, 256);
+
+   if (png_gamma_significant(gamma_val) != 0)
+      for (i=0; i<256; i++)
+         table[i] = png_gamma_8bit_correct(i, gamma_val);
+
+   else
+      for (i=0; i<256; ++i)
+         table[i] = (png_byte)i;
+}
+
+/* Used from png_read_destroy and below to release the memory used by the gamma
+ * tables.
+ */
+void /* PRIVATE */
+png_destroy_gamma_table(png_structrp png_ptr)
+{
+   png_free(png_ptr, png_ptr->gamma_table);
+   png_ptr->gamma_table = NULL;
+
+#ifdef PNG_16BIT_SUPPORTED
+   if (png_ptr->gamma_16_table != NULL)
+   {
+      int i;
+      int istop = (1 << (8 - png_ptr->gamma_shift));
+      for (i = 0; i < istop; i++)
+      {
+         png_free(png_ptr, png_ptr->gamma_16_table[i]);
+      }
+   png_free(png_ptr, png_ptr->gamma_16_table);
+   png_ptr->gamma_16_table = NULL;
+   }
+#endif /* 16BIT */
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
+   defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
+   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+   png_free(png_ptr, png_ptr->gamma_from_1);
+   png_ptr->gamma_from_1 = NULL;
+   png_free(png_ptr, png_ptr->gamma_to_1);
+   png_ptr->gamma_to_1 = NULL;
+
+#ifdef PNG_16BIT_SUPPORTED
+   if (png_ptr->gamma_16_from_1 != NULL)
+   {
+      int i;
+      int istop = (1 << (8 - png_ptr->gamma_shift));
+      for (i = 0; i < istop; i++)
+      {
+         png_free(png_ptr, png_ptr->gamma_16_from_1[i]);
+      }
+   png_free(png_ptr, png_ptr->gamma_16_from_1);
+   png_ptr->gamma_16_from_1 = NULL;
+   }
+   if (png_ptr->gamma_16_to_1 != NULL)
+   {
+      int i;
+      int istop = (1 << (8 - png_ptr->gamma_shift));
+      for (i = 0; i < istop; i++)
+      {
+         png_free(png_ptr, png_ptr->gamma_16_to_1[i]);
+      }
+   png_free(png_ptr, png_ptr->gamma_16_to_1);
+   png_ptr->gamma_16_to_1 = NULL;
+   }
+#endif /* 16BIT */
+#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
+}
+
+/* We build the 8- or 16-bit gamma tables here.  Note that for 16-bit
+ * tables, we don't make a full table if we are reducing to 8-bit in
+ * the future.  Note also how the gamma_16 tables are segmented so that
+ * we don't need to allocate > 64K chunks for a full 16-bit table.
+ */
+void /* PRIVATE */
+png_build_gamma_table(png_structrp png_ptr, int bit_depth)
+{
+  png_debug(1, "in png_build_gamma_table");
+
+  /* Remove any existing table; this copes with multiple calls to
+   * png_read_update_info.  The warning is because building the gamma tables
+   * multiple times is a performance hit - it's harmless but the ability to call
+   * png_read_update_info() multiple times is new in 1.5.6 so it seems sensible
+   * to warn if the app introduces such a hit.
+   */
+  if (png_ptr->gamma_table != NULL || png_ptr->gamma_16_table != NULL)
+  {
+    png_warning(png_ptr, "gamma table being rebuilt");
+    png_destroy_gamma_table(png_ptr);
+  }
+
+  if (bit_depth <= 8)
+  {
+     png_build_8bit_table(png_ptr, &png_ptr->gamma_table,
+         png_ptr->screen_gamma > 0 ?  png_reciprocal2(png_ptr->colorspace.gamma,
+         png_ptr->screen_gamma) : PNG_FP_1);
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
+   defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
+   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+     if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0)
+     {
+        png_build_8bit_table(png_ptr, &png_ptr->gamma_to_1,
+            png_reciprocal(png_ptr->colorspace.gamma));
+
+        png_build_8bit_table(png_ptr, &png_ptr->gamma_from_1,
+            png_ptr->screen_gamma > 0 ?  png_reciprocal(png_ptr->screen_gamma) :
+            png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */);
+     }
+#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
+  }
+#ifdef PNG_16BIT_SUPPORTED
+  else
+  {
+     png_byte shift, sig_bit;
+
+     if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
+     {
+        sig_bit = png_ptr->sig_bit.red;
+
+        if (png_ptr->sig_bit.green > sig_bit)
+           sig_bit = png_ptr->sig_bit.green;
+
+        if (png_ptr->sig_bit.blue > sig_bit)
+           sig_bit = png_ptr->sig_bit.blue;
+     }
+     else
+        sig_bit = png_ptr->sig_bit.gray;
+
+     /* 16-bit gamma code uses this equation:
+      *
+      *   ov = table[(iv & 0xff) >> gamma_shift][iv >> 8]
+      *
+      * Where 'iv' is the input color value and 'ov' is the output value -
+      * pow(iv, gamma).
+      *
+      * Thus the gamma table consists of up to 256 256-entry tables.  The table
+      * is selected by the (8-gamma_shift) most significant of the low 8 bits of
+      * the color value then indexed by the upper 8 bits:
+      *
+      *   table[low bits][high 8 bits]
+      *
+      * So the table 'n' corresponds to all those 'iv' of:
+      *
+      *   <all high 8-bit values><n << gamma_shift>..<(n+1 << gamma_shift)-1>
+      *
+      */
+     if (sig_bit > 0 && sig_bit < 16U)
+        shift = (png_byte)(16U - sig_bit); /* shift == insignificant bits */
+
+     else
+        shift = 0; /* keep all 16 bits */
+
+     if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0)
+     {
+        /* PNG_MAX_GAMMA_8 is the number of bits to keep - effectively
+         * the significant bits in the *input* when the output will
+         * eventually be 8 bits.  By default it is 11.
+         */
+        if (shift < (16U - PNG_MAX_GAMMA_8))
+           shift = (16U - PNG_MAX_GAMMA_8);
+     }
+
+     if (shift > 8U)
+        shift = 8U; /* Guarantees at least one table! */
+
+     png_ptr->gamma_shift = shift;
+
+     /* NOTE: prior to 1.5.4 this test used to include PNG_BACKGROUND (now
+      * PNG_COMPOSE).  This effectively smashed the background calculation for
+      * 16-bit output because the 8-bit table assumes the result will be reduced
+      * to 8 bits.
+      */
+     if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0)
+         png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift,
+         png_ptr->screen_gamma > 0 ? png_product2(png_ptr->colorspace.gamma,
+         png_ptr->screen_gamma) : PNG_FP_1);
+
+     else
+         png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift,
+         png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->colorspace.gamma,
+         png_ptr->screen_gamma) : PNG_FP_1);
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
+   defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
+   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+     if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0)
+     {
+        png_build_16bit_table(png_ptr, &png_ptr->gamma_16_to_1, shift,
+            png_reciprocal(png_ptr->colorspace.gamma));
+
+        /* Notice that the '16 from 1' table should be full precision, however
+         * the lookup on this table still uses gamma_shift, so it can't be.
+         * TODO: fix this.
+         */
+        png_build_16bit_table(png_ptr, &png_ptr->gamma_16_from_1, shift,
+            png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) :
+            png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */);
+     }
+#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
+  }
+#endif /* 16BIT */
+}
+#endif /* READ_GAMMA */
+
+/* HARDWARE OR SOFTWARE OPTION SUPPORT */
+#ifdef PNG_SET_OPTION_SUPPORTED
+int PNGAPI
+png_set_option(png_structrp png_ptr, int option, int onoff)
+{
+   if (png_ptr != NULL && option >= 0 && option < PNG_OPTION_NEXT &&
+      (option & 1) == 0)
+   {
+      int mask = 3 << option;
+      int setting = (2 + (onoff != 0)) << option;
+      int current = png_ptr->options;
+
+      png_ptr->options = (png_byte)((current & ~mask) | setting);
+
+      return (current & mask) >> option;
+   }
+
+   return PNG_OPTION_INVALID;
+}
+#endif
+
+/* sRGB support */
+#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\
+   defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
+/* sRGB conversion tables; these are machine generated with the code in
+ * contrib/tools/makesRGB.c.  The actual sRGB transfer curve defined in the
+ * specification (see the article at http://en.wikipedia.org/wiki/SRGB)
+ * is used, not the gamma=1/2.2 approximation use elsewhere in libpng.
+ * The sRGB to linear table is exact (to the nearest 16 bit linear fraction).
+ * The inverse (linear to sRGB) table has accuracies as follows:
+ *
+ * For all possible (255*65535+1) input values:
+ *
+ *    error: -0.515566 - 0.625971, 79441 (0.475369%) of readings inexact
+ *
+ * For the input values corresponding to the 65536 16-bit values:
+ *
+ *    error: -0.513727 - 0.607759, 308 (0.469978%) of readings inexact
+ *
+ * In all cases the inexact readings are only off by one.
+ */
+
+#ifdef PNG_SIMPLIFIED_READ_SUPPORTED
+/* The convert-to-sRGB table is only currently required for read. */
+const png_uint_16 png_sRGB_table[256] =
+{
+   0,20,40,60,80,99,119,139,
+   159,179,199,219,241,264,288,313,
+   340,367,396,427,458,491,526,562,
+   599,637,677,718,761,805,851,898,
+   947,997,1048,1101,1156,1212,1270,1330,
+   1391,1453,1517,1583,1651,1720,1790,1863,
+   1937,2013,2090,2170,2250,2333,2418,2504,
+   2592,2681,2773,2866,2961,3058,3157,3258,
+   3360,3464,3570,3678,3788,3900,4014,4129,
+   4247,4366,4488,4611,4736,4864,4993,5124,
+   5257,5392,5530,5669,5810,5953,6099,6246,
+   6395,6547,6700,6856,7014,7174,7335,7500,
+   7666,7834,8004,8177,8352,8528,8708,8889,
+   9072,9258,9445,9635,9828,10022,10219,10417,
+   10619,10822,11028,11235,11446,11658,11873,12090,
+   12309,12530,12754,12980,13209,13440,13673,13909,
+   14146,14387,14629,14874,15122,15371,15623,15878,
+   16135,16394,16656,16920,17187,17456,17727,18001,
+   18277,18556,18837,19121,19407,19696,19987,20281,
+   20577,20876,21177,21481,21787,22096,22407,22721,
+   23038,23357,23678,24002,24329,24658,24990,25325,
+   25662,26001,26344,26688,27036,27386,27739,28094,
+   28452,28813,29176,29542,29911,30282,30656,31033,
+   31412,31794,32179,32567,32957,33350,33745,34143,
+   34544,34948,35355,35764,36176,36591,37008,37429,
+   37852,38278,38706,39138,39572,40009,40449,40891,
+   41337,41785,42236,42690,43147,43606,44069,44534,
+   45002,45473,45947,46423,46903,47385,47871,48359,
+   48850,49344,49841,50341,50844,51349,51858,52369,
+   52884,53401,53921,54445,54971,55500,56032,56567,
+   57105,57646,58190,58737,59287,59840,60396,60955,
+   61517,62082,62650,63221,63795,64372,64952,65535
+};
+#endif /* SIMPLIFIED_READ */
+
+/* The base/delta tables are required for both read and write (but currently
+ * only the simplified versions.)
+ */
+const png_uint_16 png_sRGB_base[512] =
+{
+   128,1782,3383,4644,5675,6564,7357,8074,
+   8732,9346,9921,10463,10977,11466,11935,12384,
+   12816,13233,13634,14024,14402,14769,15125,15473,
+   15812,16142,16466,16781,17090,17393,17690,17981,
+   18266,18546,18822,19093,19359,19621,19879,20133,
+   20383,20630,20873,21113,21349,21583,21813,22041,
+   22265,22487,22707,22923,23138,23350,23559,23767,
+   23972,24175,24376,24575,24772,24967,25160,25352,
+   25542,25730,25916,26101,26284,26465,26645,26823,
+   27000,27176,27350,27523,27695,27865,28034,28201,
+   28368,28533,28697,28860,29021,29182,29341,29500,
+   29657,29813,29969,30123,30276,30429,30580,30730,
+   30880,31028,31176,31323,31469,31614,31758,31902,
+   32045,32186,32327,32468,32607,32746,32884,33021,
+   33158,33294,33429,33564,33697,33831,33963,34095,
+   34226,34357,34486,34616,34744,34873,35000,35127,
+   35253,35379,35504,35629,35753,35876,35999,36122,
+   36244,36365,36486,36606,36726,36845,36964,37083,
+   37201,37318,37435,37551,37668,37783,37898,38013,
+   38127,38241,38354,38467,38580,38692,38803,38915,
+   39026,39136,39246,39356,39465,39574,39682,39790,
+   39898,40005,40112,40219,40325,40431,40537,40642,
+   40747,40851,40955,41059,41163,41266,41369,41471,
+   41573,41675,41777,41878,41979,42079,42179,42279,
+   42379,42478,42577,42676,42775,42873,42971,43068,
+   43165,43262,43359,43456,43552,43648,43743,43839,
+   43934,44028,44123,44217,44311,44405,44499,44592,
+   44685,44778,44870,44962,45054,45146,45238,45329,
+   45420,45511,45601,45692,45782,45872,45961,46051,
+   46140,46229,46318,46406,46494,46583,46670,46758,
+   46846,46933,47020,47107,47193,47280,47366,47452,
+   47538,47623,47709,47794,47879,47964,48048,48133,
+   48217,48301,48385,48468,48552,48635,48718,48801,
+   48884,48966,49048,49131,49213,49294,49376,49458,
+   49539,49620,49701,49782,49862,49943,50023,50103,
+   50183,50263,50342,50422,50501,50580,50659,50738,
+   50816,50895,50973,51051,51129,51207,51285,51362,
+   51439,51517,51594,51671,51747,51824,51900,51977,
+   52053,52129,52205,52280,52356,52432,52507,52582,
+   52657,52732,52807,52881,52956,53030,53104,53178,
+   53252,53326,53400,53473,53546,53620,53693,53766,
+   53839,53911,53984,54056,54129,54201,54273,54345,
+   54417,54489,54560,54632,54703,54774,54845,54916,
+   54987,55058,55129,55199,55269,55340,55410,55480,
+   55550,55620,55689,55759,55828,55898,55967,56036,
+   56105,56174,56243,56311,56380,56448,56517,56585,
+   56653,56721,56789,56857,56924,56992,57059,57127,
+   57194,57261,57328,57395,57462,57529,57595,57662,
+   57728,57795,57861,57927,57993,58059,58125,58191,
+   58256,58322,58387,58453,58518,58583,58648,58713,
+   58778,58843,58908,58972,59037,59101,59165,59230,
+   59294,59358,59422,59486,59549,59613,59677,59740,
+   59804,59867,59930,59993,60056,60119,60182,60245,
+   60308,60370,60433,60495,60558,60620,60682,60744,
+   60806,60868,60930,60992,61054,61115,61177,61238,
+   61300,61361,61422,61483,61544,61605,61666,61727,
+   61788,61848,61909,61969,62030,62090,62150,62211,
+   62271,62331,62391,62450,62510,62570,62630,62689,
+   62749,62808,62867,62927,62986,63045,63104,63163,
+   63222,63281,63340,63398,63457,63515,63574,63632,
+   63691,63749,63807,63865,63923,63981,64039,64097,
+   64155,64212,64270,64328,64385,64443,64500,64557,
+   64614,64672,64729,64786,64843,64900,64956,65013,
+   65070,65126,65183,65239,65296,65352,65409,65465
+};
+
+const png_byte png_sRGB_delta[512] =
+{
+   207,201,158,129,113,100,90,82,77,72,68,64,61,59,56,54,
+   52,50,49,47,46,45,43,42,41,40,39,39,38,37,36,36,
+   35,34,34,33,33,32,32,31,31,30,30,30,29,29,28,28,
+   28,27,27,27,27,26,26,26,25,25,25,25,24,24,24,24,
+   23,23,23,23,23,22,22,22,22,22,22,21,21,21,21,21,
+   21,20,20,20,20,20,20,20,20,19,19,19,19,19,19,19,
+   19,18,18,18,18,18,18,18,18,18,18,17,17,17,17,17,
+   17,17,17,17,17,17,16,16,16,16,16,16,16,16,16,16,
+   16,16,16,16,15,15,15,15,15,15,15,15,15,15,15,15,
+   15,15,15,15,14,14,14,14,14,14,14,14,14,14,14,14,
+   14,14,14,14,14,14,14,13,13,13,13,13,13,13,13,13,
+   13,13,13,13,13,13,13,13,13,13,13,13,13,13,12,12,
+   12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
+   12,12,12,12,12,12,12,12,12,12,12,12,11,11,11,11,
+   11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
+   11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
+   11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
+   10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
+   10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
+   10,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
+   9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
+   9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
+   9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
+   9,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+   8,8,8,8,8,8,8,8,8,7,7,7,7,7,7,7,
+   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
+};
+#endif /* SIMPLIFIED READ/WRITE sRGB support */
+
+/* SIMPLIFIED READ/WRITE SUPPORT */
+#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\
+   defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
+static int
+png_image_free_function(png_voidp argument)
+{
+   png_imagep image = png_voidcast(png_imagep, argument);
+   png_controlp cp = image->opaque;
+   png_control c;
+
+   /* Double check that we have a png_ptr - it should be impossible to get here
+    * without one.
+    */
+   if (cp->png_ptr == NULL)
+      return 0;
+
+   /* First free any data held in the control structure. */
+#  ifdef PNG_STDIO_SUPPORTED
+      if (cp->owned_file != 0)
+      {
+         FILE *fp = png_voidcast(FILE*, cp->png_ptr->io_ptr);
+         cp->owned_file = 0;
+
+         /* Ignore errors here. */
+         if (fp != NULL)
+         {
+            cp->png_ptr->io_ptr = NULL;
+            (void)fclose(fp);
+         }
+      }
+#  endif
+
+   /* Copy the control structure so that the original, allocated, version can be
+    * safely freed.  Notice that a png_error here stops the remainder of the
+    * cleanup, but this is probably fine because that would indicate bad memory
+    * problems anyway.
+    */
+   c = *cp;
+   image->opaque = &c;
+   png_free(c.png_ptr, cp);
+
+   /* Then the structures, calling the correct API. */
+   if (c.for_write != 0)
+   {
+#     ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED
+         png_destroy_write_struct(&c.png_ptr, &c.info_ptr);
+#     else
+         png_error(c.png_ptr, "simplified write not supported");
+#     endif
+   }
+   else
+   {
+#     ifdef PNG_SIMPLIFIED_READ_SUPPORTED
+         png_destroy_read_struct(&c.png_ptr, &c.info_ptr, NULL);
+#     else
+         png_error(c.png_ptr, "simplified read not supported");
+#     endif
+   }
+
+   /* Success. */
+   return 1;
+}
+
+void PNGAPI
+png_image_free(png_imagep image)
+{
+   /* Safely call the real function, but only if doing so is safe at this point
+    * (if not inside an error handling context).  Otherwise assume
+    * png_safe_execute will call this API after the return.
+    */
+   if (image != NULL && image->opaque != NULL &&
+      image->opaque->error_buf == NULL)
+   {
+      /* Ignore errors here: */
+      (void)png_safe_execute(image, png_image_free_function, image);
+      image->opaque = NULL;
+   }
+}
+
+int /* PRIVATE */
+png_image_error(png_imagep image, png_const_charp error_message)
+{
+   /* Utility to log an error. */
+   png_safecat(image->message, (sizeof image->message), 0, error_message);
+   image->warning_or_error |= PNG_IMAGE_ERROR;
+   png_image_free(image);
+   return 0;
+}
+
+#endif /* SIMPLIFIED READ/WRITE */
+#endif /* READ || WRITE */
diff --git a/Source/LibPNG/png.h b/Source/LibPNG/png.h
index 6d762fc..997130d 100644
--- a/Source/LibPNG/png.h
+++ b/Source/LibPNG/png.h
@@ -1,2674 +1,3282 @@
-
-/* png.h - header file for PNG reference library
- *
- * libpng version 1.5.13 - September 27, 2012
- * Copyright (c) 1998-2012 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- *
- * This code is released under the libpng license (See LICENSE, below)
- *
- * Authors and maintainers:
- *   libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
- *   libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger
- *   libpng versions 0.97, January 1998, through 1.5.13 - September 27, 2012: Glenn
- *   See also "Contributing Authors", below.
- *
- * Note about libpng version numbers:
- *
- *   Due to various miscommunications, unforeseen code incompatibilities
- *   and occasional factors outside the authors' control, version numbering
- *   on the library has not always been consistent and straightforward.
- *   The following table summarizes matters since version 0.89c, which was
- *   the first widely used release:
- *
- *    source                 png.h  png.h  shared-lib
- *    version                string   int  version
- *    -------                ------ -----  ----------
- *    0.89c "1.0 beta 3"     0.89      89  1.0.89
- *    0.90  "1.0 beta 4"     0.90      90  0.90  [should have been 2.0.90]
- *    0.95  "1.0 beta 5"     0.95      95  0.95  [should have been 2.0.95]
- *    0.96  "1.0 beta 6"     0.96      96  0.96  [should have been 2.0.96]
- *    0.97b "1.00.97 beta 7" 1.00.97   97  1.0.1 [should have been 2.0.97]
- *    0.97c                  0.97      97  2.0.97
- *    0.98                   0.98      98  2.0.98
- *    0.99                   0.99      98  2.0.99
- *    0.99a-m                0.99      99  2.0.99
- *    1.00                   1.00     100  2.1.0 [100 should be 10000]
- *    1.0.0      (from here on, the   100  2.1.0 [100 should be 10000]
- *    1.0.1       png.h string is   10001  2.1.0
- *    1.0.1a-e    identical to the  10002  from here on, the shared library
- *    1.0.2       source version)   10002  is 2.V where V is the source code
- *    1.0.2a-b                      10003  version, except as noted.
- *    1.0.3                         10003
- *    1.0.3a-d                      10004
- *    1.0.4                         10004
- *    1.0.4a-f                      10005
- *    1.0.5 (+ 2 patches)           10005
- *    1.0.5a-d                      10006
- *    1.0.5e-r                      10100 (not source compatible)
- *    1.0.5s-v                      10006 (not binary compatible)
- *    1.0.6 (+ 3 patches)           10006 (still binary incompatible)
- *    1.0.6d-f                      10007 (still binary incompatible)
- *    1.0.6g                        10007
- *    1.0.6h                        10007  10.6h (testing xy.z so-numbering)
- *    1.0.6i                        10007  10.6i
- *    1.0.6j                        10007  2.1.0.6j (incompatible with 1.0.0)
- *    1.0.7beta11-14        DLLNUM  10007  2.1.0.7beta11-14 (binary compatible)
- *    1.0.7beta15-18           1    10007  2.1.0.7beta15-18 (binary compatible)
- *    1.0.7rc1-2               1    10007  2.1.0.7rc1-2 (binary compatible)
- *    1.0.7                    1    10007  (still compatible)
- *    1.0.8beta1-4             1    10008  2.1.0.8beta1-4
- *    1.0.8rc1                 1    10008  2.1.0.8rc1
- *    1.0.8                    1    10008  2.1.0.8
- *    1.0.9beta1-6             1    10009  2.1.0.9beta1-6
- *    1.0.9rc1                 1    10009  2.1.0.9rc1
- *    1.0.9beta7-10            1    10009  2.1.0.9beta7-10
- *    1.0.9rc2                 1    10009  2.1.0.9rc2
- *    1.0.9                    1    10009  2.1.0.9
- *    1.0.10beta1              1    10010  2.1.0.10beta1
- *    1.0.10rc1                1    10010  2.1.0.10rc1
- *    1.0.10                   1    10010  2.1.0.10
- *    1.0.11beta1-3            1    10011  2.1.0.11beta1-3
- *    1.0.11rc1                1    10011  2.1.0.11rc1
- *    1.0.11                   1    10011  2.1.0.11
- *    1.0.12beta1-2            2    10012  2.1.0.12beta1-2
- *    1.0.12rc1                2    10012  2.1.0.12rc1
- *    1.0.12                   2    10012  2.1.0.12
- *    1.1.0a-f                 -    10100  2.1.1.0a-f (branch abandoned)
- *    1.2.0beta1-2             2    10200  2.1.2.0beta1-2
- *    1.2.0beta3-5             3    10200  3.1.2.0beta3-5
- *    1.2.0rc1                 3    10200  3.1.2.0rc1
- *    1.2.0                    3    10200  3.1.2.0
- *    1.2.1beta1-4             3    10201  3.1.2.1beta1-4
- *    1.2.1rc1-2               3    10201  3.1.2.1rc1-2
- *    1.2.1                    3    10201  3.1.2.1
- *    1.2.2beta1-6            12    10202  12.so.0.1.2.2beta1-6
- *    1.0.13beta1             10    10013  10.so.0.1.0.13beta1
- *    1.0.13rc1               10    10013  10.so.0.1.0.13rc1
- *    1.2.2rc1                12    10202  12.so.0.1.2.2rc1
- *    1.0.13                  10    10013  10.so.0.1.0.13
- *    1.2.2                   12    10202  12.so.0.1.2.2
- *    1.2.3rc1-6              12    10203  12.so.0.1.2.3rc1-6
- *    1.2.3                   12    10203  12.so.0.1.2.3
- *    1.2.4beta1-3            13    10204  12.so.0.1.2.4beta1-3
- *    1.0.14rc1               13    10014  10.so.0.1.0.14rc1
- *    1.2.4rc1                13    10204  12.so.0.1.2.4rc1
- *    1.0.14                  10    10014  10.so.0.1.0.14
- *    1.2.4                   13    10204  12.so.0.1.2.4
- *    1.2.5beta1-2            13    10205  12.so.0.1.2.5beta1-2
- *    1.0.15rc1-3             10    10015  10.so.0.1.0.15rc1-3
- *    1.2.5rc1-3              13    10205  12.so.0.1.2.5rc1-3
- *    1.0.15                  10    10015  10.so.0.1.0.15
- *    1.2.5                   13    10205  12.so.0.1.2.5
- *    1.2.6beta1-4            13    10206  12.so.0.1.2.6beta1-4
- *    1.0.16                  10    10016  10.so.0.1.0.16
- *    1.2.6                   13    10206  12.so.0.1.2.6
- *    1.2.7beta1-2            13    10207  12.so.0.1.2.7beta1-2
- *    1.0.17rc1               10    10017  12.so.0.1.0.17rc1
- *    1.2.7rc1                13    10207  12.so.0.1.2.7rc1
- *    1.0.17                  10    10017  12.so.0.1.0.17
- *    1.2.7                   13    10207  12.so.0.1.2.7
- *    1.2.8beta1-5            13    10208  12.so.0.1.2.8beta1-5
- *    1.0.18rc1-5             10    10018  12.so.0.1.0.18rc1-5
- *    1.2.8rc1-5              13    10208  12.so.0.1.2.8rc1-5
- *    1.0.18                  10    10018  12.so.0.1.0.18
- *    1.2.8                   13    10208  12.so.0.1.2.8
- *    1.2.9beta1-3            13    10209  12.so.0.1.2.9beta1-3
- *    1.2.9beta4-11           13    10209  12.so.0.9[.0]
- *    1.2.9rc1                13    10209  12.so.0.9[.0]
- *    1.2.9                   13    10209  12.so.0.9[.0]
- *    1.2.10beta1-7           13    10210  12.so.0.10[.0]
- *    1.2.10rc1-2             13    10210  12.so.0.10[.0]
- *    1.2.10                  13    10210  12.so.0.10[.0]
- *    1.4.0beta1-5            14    10400  14.so.0.0[.0]
- *    1.2.11beta1-4           13    10211  12.so.0.11[.0]
- *    1.4.0beta7-8            14    10400  14.so.0.0[.0]
- *    1.2.11                  13    10211  12.so.0.11[.0]
- *    1.2.12                  13    10212  12.so.0.12[.0]
- *    1.4.0beta9-14           14    10400  14.so.0.0[.0]
- *    1.2.13                  13    10213  12.so.0.13[.0]
- *    1.4.0beta15-36          14    10400  14.so.0.0[.0]
- *    1.4.0beta37-87          14    10400  14.so.14.0[.0]
- *    1.4.0rc01               14    10400  14.so.14.0[.0]
- *    1.4.0beta88-109         14    10400  14.so.14.0[.0]
- *    1.4.0rc02-08            14    10400  14.so.14.0[.0]
- *    1.4.0                   14    10400  14.so.14.0[.0]
- *    1.4.1beta01-03          14    10401  14.so.14.1[.0]
- *    1.4.1rc01               14    10401  14.so.14.1[.0]
- *    1.4.1beta04-12          14    10401  14.so.14.1[.0]
- *    1.4.1                   14    10401  14.so.14.1[.0]
- *    1.4.2                   14    10402  14.so.14.2[.0]
- *    1.4.3                   14    10403  14.so.14.3[.0]
- *    1.4.4                   14    10404  14.so.14.4[.0]
- *    1.5.0beta01-58          15    10500  15.so.15.0[.0]
- *    1.5.0rc01-07            15    10500  15.so.15.0[.0]
- *    1.5.0                   15    10500  15.so.15.0[.0]
- *    1.5.1beta01-11          15    10501  15.so.15.1[.0]
- *    1.5.1rc01-02            15    10501  15.so.15.1[.0]
- *    1.5.1                   15    10501  15.so.15.1[.0]
- *    1.5.2beta01-03          15    10502  15.so.15.2[.0]
- *    1.5.2rc01-03            15    10502  15.so.15.2[.0]
- *    1.5.2                   15    10502  15.so.15.2[.0]
- *    1.5.3beta01-10          15    10503  15.so.15.3[.0]
- *    1.5.3rc01-02            15    10503  15.so.15.3[.0]
- *    1.5.3beta11             15    10503  15.so.15.3[.0]
- *    1.5.3 [omitted]
- *    1.5.4beta01-08          15    10504  15.so.15.4[.0]
- *    1.5.4rc01               15    10504  15.so.15.4[.0]
- *    1.5.4                   15    10504  15.so.15.4[.0]
- *    1.5.5beta01-08          15    10505  15.so.15.5[.0]
- *    1.5.5rc01               15    10505  15.so.15.5[.0]
- *    1.5.5                   15    10505  15.so.15.5[.0]
- *    1.5.6beta01-07          15    10506  15.so.15.6[.0]
- *    1.5.6rc01-03            15    10506  15.so.15.6[.0]
- *    1.5.6                   15    10506  15.so.15.6[.0]
- *    1.5.7beta01-05          15    10507  15.so.15.7[.0]
- *    1.5.7rc01-03            15    10507  15.so.15.7[.0]
- *    1.5.7                   15    10507  15.so.15.7[.0]
- *    1.5.8beta01             15    10508  15.so.15.8[.0]
- *    1.5.8rc01               15    10508  15.so.15.8[.0]
- *    1.5.8                   15    10508  15.so.15.8[.0]
- *    1.5.9beta01-02          15    10509  15.so.15.9[.0]
- *    1.5.9rc01               15    10509  15.so.15.9[.0]
- *    1.5.9                   15    10509  15.so.15.9[.0]
- *    1.5.10beta01-05         15    10510  15.so.15.10[.0]
- *    1.5.10                  15    10510  15.so.15.10[.0]
- *    1.5.11beta01            15    10511  15.so.15.11[.0]
- *    1.5.11rc01-05           15    10511  15.so.15.11[.0]
- *    1.5.11                  15    10511  15.so.15.11[.0]
- *    1.5.12                  15    10512  15.so.15.12[.0]
- *    1.5.13beta01-02         15    10513  15.so.15.13[.0]
- *    1.5.13rc01              15    10513  15.so.15.13[.0]
- *    1.5.13                  15    10513  15.so.15.13[.0]
- *
- *   Henceforth the source version will match the shared-library major
- *   and minor numbers; the shared-library major version number will be
- *   used for changes in backward compatibility, as it is intended.  The
- *   PNG_LIBPNG_VER macro, which is not used within libpng but is available
- *   for applications, is an unsigned integer of the form xyyzz corresponding
- *   to the source version x.y.z (leading zeros in y and z).  Beta versions
- *   were given the previous public release number plus a letter, until
- *   version 1.0.6j; from then on they were given the upcoming public
- *   release number plus "betaNN" or "rcNN".
- *
- *   Binary incompatibility exists only when applications make direct access
- *   to the info_ptr or png_ptr members through png.h, and the compiled
- *   application is loaded with a different version of the library.
- *
- *   DLLNUM will change each time there are forward or backward changes
- *   in binary compatibility (e.g., when a new feature is added).
- *
- * See libpng-manual.txt or libpng.3 for more information.  The PNG
- * specification is available as a W3C Recommendation and as an ISO
- * Specification, <http://www.w3.org/TR/2003/REC-PNG-20031110/
- */
-
-/*
- * COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
- *
- * If you modify libpng you may insert additional notices immediately following
- * this sentence.
- *
- * This code is released under the libpng license.
- *
- * libpng versions 1.2.6, August 15, 2004, through 1.5.13, September 27, 2012, are
- * Copyright (c) 2004, 2006-2012 Glenn Randers-Pehrson, and are
- * distributed according to the same disclaimer and license as libpng-1.2.5
- * with the following individual added to the list of Contributing Authors:
- *
- *    Cosmin Truta
- *
- * libpng versions 1.0.7, July 1, 2000, through 1.2.5, October 3, 2002, are
- * Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are
- * distributed according to the same disclaimer and license as libpng-1.0.6
- * with the following individuals added to the list of Contributing Authors:
- *
- *    Simon-Pierre Cadieux
- *    Eric S. Raymond
- *    Gilles Vollant
- *
- * and with the following additions to the disclaimer:
- *
- *    There is no warranty against interference with your enjoyment of the
- *    library or against infringement.  There is no warranty that our
- *    efforts or the library will fulfill any of your particular purposes
- *    or needs.  This library is provided with all faults, and the entire
- *    risk of satisfactory quality, performance, accuracy, and effort is with
- *    the user.
- *
- * libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
- * Copyright (c) 1998, 1999, 2000 Glenn Randers-Pehrson, and are
- * distributed according to the same disclaimer and license as libpng-0.96,
- * with the following individuals added to the list of Contributing Authors:
- *
- *    Tom Lane
- *    Glenn Randers-Pehrson
- *    Willem van Schaik
- *
- * libpng versions 0.89, June 1996, through 0.96, May 1997, are
- * Copyright (c) 1996, 1997 Andreas Dilger
- * Distributed according to the same disclaimer and license as libpng-0.88,
- * with the following individuals added to the list of Contributing Authors:
- *
- *    John Bowler
- *    Kevin Bracey
- *    Sam Bushell
- *    Magnus Holmgren
- *    Greg Roelofs
- *    Tom Tanner
- *
- * libpng versions 0.5, May 1995, through 0.88, January 1996, are
- * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
- *
- * For the purposes of this copyright and license, "Contributing Authors"
- * is defined as the following set of individuals:
- *
- *    Andreas Dilger
- *    Dave Martindale
- *    Guy Eric Schalnat
- *    Paul Schmidt
- *    Tim Wegner
- *
- * The PNG Reference Library is supplied "AS IS".  The Contributing Authors
- * and Group 42, Inc. disclaim all warranties, expressed or implied,
- * including, without limitation, the warranties of merchantability and of
- * fitness for any purpose.  The Contributing Authors and Group 42, Inc.
- * assume no liability for direct, indirect, incidental, special, exemplary,
- * or consequential damages, which may result from the use of the PNG
- * Reference Library, even if advised of the possibility of such damage.
- *
- * Permission is hereby granted to use, copy, modify, and distribute this
- * source code, or portions hereof, for any purpose, without fee, subject
- * to the following restrictions:
- *
- *   1. The origin of this source code must not be misrepresented.
- *
- *   2. Altered versions must be plainly marked as such and must not
- *      be misrepresented as being the original source.
- *
- *   3. This Copyright notice may not be removed or altered from
- *      any source or altered source distribution.
- *
- * The Contributing Authors and Group 42, Inc. specifically permit, without
- * fee, and encourage the use of this source code as a component to
- * supporting the PNG file format in commercial products.  If you use this
- * source code in a product, acknowledgment is not required but would be
- * appreciated.
- */
-
-/*
- * A "png_get_copyright" function is available, for convenient use in "about"
- * boxes and the like:
- *
- *     printf("%s", png_get_copyright(NULL));
- *
- * Also, the PNG logo (in PNG format, of course) is supplied in the
- * files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
- */
-
-/*
- * Libpng is OSI Certified Open Source Software.  OSI Certified is a
- * certification mark of the Open Source Initiative.
- */
-
-/*
- * The contributing authors would like to thank all those who helped
- * with testing, bug fixes, and patience.  This wouldn't have been
- * possible without all of you.
- *
- * Thanks to Frank J. T. Wojcik for helping with the documentation.
- */
-
-/*
- * Y2K compliance in libpng:
- * =========================
- *
- *    September 27, 2012
- *
- *    Since the PNG Development group is an ad-hoc body, we can't make
- *    an official declaration.
- *
- *    This is your unofficial assurance that libpng from version 0.71 and
- *    upward through 1.5.13 are Y2K compliant.  It is my belief that
- *    earlier versions were also Y2K compliant.
- *
- *    Libpng only has two year fields.  One is a 2-byte unsigned integer
- *    that will hold years up to 65535.  The other holds the date in text
- *    format, and will hold years up to 9999.
- *
- *    The integer is
- *        "png_uint_16 year" in png_time_struct.
- *
- *    The string is
- *        "char time_buffer[29]" in png_struct.  This will be no
- *    longer used in libpng-1.6.0 and will be removed from libpng-1.7.0.
- *
- *    There are seven time-related functions:
- *        png.c: png_convert_to_rfc_1123() in png.c
- *          (formerly png_convert_to_rfc_1152() in error)
- *        png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.c
- *        png_convert_from_time_t() in pngwrite.c
- *        png_get_tIME() in pngget.c
- *        png_handle_tIME() in pngrutil.c, called in pngread.c
- *        png_set_tIME() in pngset.c
- *        png_write_tIME() in pngwutil.c, called in pngwrite.c
- *
- *    All handle dates properly in a Y2K environment.  The
- *    png_convert_from_time_t() function calls gmtime() to convert from system
- *    clock time, which returns (year - 1900), which we properly convert to
- *    the full 4-digit year.  There is a possibility that applications using
- *    libpng are not passing 4-digit years into the png_convert_to_rfc_1123()
- *    function, or that they are incorrectly passing only a 2-digit year
- *    instead of "year - 1900" into the png_convert_from_struct_tm() function,
- *    but this is not under our control.  The libpng documentation has always
- *    stated that it works with 4-digit years, and the APIs have been
- *    documented as such.
- *
- *    The tIME chunk itself is also Y2K compliant.  It uses a 2-byte unsigned
- *    integer to hold the year, and can hold years as large as 65535.
- *
- *    zlib, upon which libpng depends, is also Y2K compliant.  It contains
- *    no date-related code.
- *
- *       Glenn Randers-Pehrson
- *       libpng maintainer
- *       PNG Development Group
- */
-
-#ifndef PNG_H
-#define PNG_H
-
-/* This is not the place to learn how to use libpng. The file libpng-manual.txt
- * describes how to use libpng, and the file example.c summarizes it
- * with some code on which to build.  This file is useful for looking
- * at the actual function definitions and structure components.
- *
- * If you just need to read a PNG file and don't want to read the documentation
- * skip to the end of this file and read the section entitled 'simplified API'.
- */
-
-/* Version information for png.h - this should match the version in png.c */
-#define PNG_LIBPNG_VER_STRING "1.5.13"
-#define PNG_HEADER_VERSION_STRING \
-     " libpng version 1.5.13 - September 27, 2012\n"
-
-#define PNG_LIBPNG_VER_SONUM   15
-#define PNG_LIBPNG_VER_DLLNUM  15
-
-/* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
-#define PNG_LIBPNG_VER_MAJOR   1
-#define PNG_LIBPNG_VER_MINOR   5
-#define PNG_LIBPNG_VER_RELEASE 13
-
-/* This should match the numeric part of the final component of
- * PNG_LIBPNG_VER_STRING, omitting any leading zero:
- */
-
-#define PNG_LIBPNG_VER_BUILD  0
-
-/* Release Status */
-#define PNG_LIBPNG_BUILD_ALPHA    1
-#define PNG_LIBPNG_BUILD_BETA     2
-#define PNG_LIBPNG_BUILD_RC       3
-#define PNG_LIBPNG_BUILD_STABLE   4
-#define PNG_LIBPNG_BUILD_RELEASE_STATUS_MASK 7
-
-/* Release-Specific Flags */
-#define PNG_LIBPNG_BUILD_PATCH    8 /* Can be OR'ed with
-                                       PNG_LIBPNG_BUILD_STABLE only */
-#define PNG_LIBPNG_BUILD_PRIVATE 16 /* Cannot be OR'ed with
-                                       PNG_LIBPNG_BUILD_SPECIAL */
-#define PNG_LIBPNG_BUILD_SPECIAL 32 /* Cannot be OR'ed with
-                                       PNG_LIBPNG_BUILD_PRIVATE */
-
-#define PNG_LIBPNG_BUILD_BASE_TYPE PNG_LIBPNG_BUILD_STABLE
-
-/* Careful here.  At one time, Guy wanted to use 082, but that would be octal.
- * We must not include leading zeros.
- * Versions 0.7 through 1.0.0 were in the range 0 to 100 here (only
- * version 1.0.0 was mis-numbered 100 instead of 10000).  From
- * version 1.0.1 it's    xxyyzz, where x=major, y=minor, z=release
- */
-#define PNG_LIBPNG_VER 10513 /* 1.5.13 */
-
-/* Library configuration: these options cannot be changed after
- * the library has been built.
- */
-#ifndef PNGLCONF_H
-    /* If pnglibconf.h is missing, you can
-     * copy scripts/pnglibconf.h.prebuilt to pnglibconf.h
-     */
-#   include "pnglibconf.h"
-#endif
-
-#ifndef PNG_VERSION_INFO_ONLY
-#  ifndef PNG_BUILDING_SYMBOL_TABLE
-  /*
-   *   Standard header files (not needed for the version info or while
-   *   building symbol table -- see scripts/pnglibconf.dfa)
-   */
-#    ifdef PNG_SETJMP_SUPPORTED
-#      include <setjmp.h>
-#    endif
-
-    /* Need the time information for converting tIME chunks, it
-     * defines struct tm:
-     */
-#    ifdef PNG_CONVERT_tIME_SUPPORTED
-       /* "time.h" functions are not supported on all operating systems */
-#      include <time.h>
-#    endif
-#  endif
-
-/* Machine specific configuration. */
-#  include "pngconf.h"
-#endif
-
-/*
- * Added at libpng-1.2.8
- *
- * Ref MSDN: Private as priority over Special
- * VS_FF_PRIVATEBUILD File *was not* built using standard release
- * procedures. If this value is given, the StringFileInfo block must
- * contain a PrivateBuild string.
- *
- * VS_FF_SPECIALBUILD File *was* built by the original company using
- * standard release procedures but is a variation of the standard
- * file of the same version number. If this value is given, the
- * StringFileInfo block must contain a SpecialBuild string.
- */
-
-#ifdef PNG_USER_PRIVATEBUILD /* From pnglibconf.h */
-#  define PNG_LIBPNG_BUILD_TYPE \
-       (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_PRIVATE)
-#else
-#  ifdef PNG_LIBPNG_SPECIALBUILD
-#    define PNG_LIBPNG_BUILD_TYPE \
-         (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_SPECIAL)
-#  else
-#    define PNG_LIBPNG_BUILD_TYPE (PNG_LIBPNG_BUILD_BASE_TYPE)
-#  endif
-#endif
-
-#ifndef PNG_VERSION_INFO_ONLY
-
-/* Inhibit C++ name-mangling for libpng functions but not for system calls. */
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-/* Version information for C files, stored in png.c.  This had better match
- * the version above.
- */
-#define png_libpng_ver png_get_header_ver(NULL)
-
-/* This file is arranged in several sections:
- *
- * 1. Any configuration options that can be specified by for the application
- *    code when it is built.  (Build time configuration is in pnglibconf.h)
- * 2. Type definitions (base types are defined in pngconf.h), structure
- *    definitions.
- * 3. Exported library functions.
- *
- * The library source code has additional files (principally pngpriv.h) that
- * allow configuration of the library.
- */
-/* Section 1: run time configuration
- * See pnglibconf.h for build time configuration
- *
- * Run time configuration allows the application to choose between
- * implementations of certain arithmetic APIs.  The default is set
- * at build time and recorded in pnglibconf.h, but it is safe to
- * override these (and only these) settings.  Note that this won't
- * change what the library does, only application code, and the
- * settings can (and probably should) be made on a per-file basis
- * by setting the #defines before including png.h
- *
- * Use macros to read integers from PNG data or use the exported
- * functions?
- *   PNG_USE_READ_MACROS: use the macros (see below)  Note that
- *     the macros evaluate their argument multiple times.
- *   PNG_NO_USE_READ_MACROS: call the relevant library function.
- *
- * Use the alternative algorithm for compositing alpha samples that
- * does not use division?
- *   PNG_READ_COMPOSITE_NODIV_SUPPORTED: use the 'no division'
- *      algorithm.
- *   PNG_NO_READ_COMPOSITE_NODIV: use the 'division' algorithm.
- *
- * How to handle benign errors if PNG_ALLOW_BENIGN_ERRORS is
- * false?
- *   PNG_ALLOW_BENIGN_ERRORS: map calls to the benign error
- *      APIs to png_warning.
- * Otherwise the calls are mapped to png_error.
- */
-
-/* Section 2: type definitions, including structures and compile time
- * constants.
- * See pngconf.h for base types that vary by machine/system
- */
-
-/* This triggers a compiler error in png.c, if png.c and png.h
- * do not agree upon the version number.
- */
-typedef char* png_libpng_version_1_5_13;
-
-/* Three color definitions.  The order of the red, green, and blue, (and the
- * exact size) is not important, although the size of the fields need to
- * be png_byte or png_uint_16 (as defined below).
- */
-typedef struct png_color_struct
-{
-   png_byte red;
-   png_byte green;
-   png_byte blue;
-} png_color;
-typedef png_color FAR * png_colorp;
-typedef PNG_CONST png_color FAR * png_const_colorp;
-typedef png_color FAR * FAR * png_colorpp;
-
-typedef struct png_color_16_struct
-{
-   png_byte index;    /* used for palette files */
-   png_uint_16 red;   /* for use in red green blue files */
-   png_uint_16 green;
-   png_uint_16 blue;
-   png_uint_16 gray;  /* for use in grayscale files */
-} png_color_16;
-typedef png_color_16 FAR * png_color_16p;
-typedef PNG_CONST png_color_16 FAR * png_const_color_16p;
-typedef png_color_16 FAR * FAR * png_color_16pp;
-
-typedef struct png_color_8_struct
-{
-   png_byte red;   /* for use in red green blue files */
-   png_byte green;
-   png_byte blue;
-   png_byte gray;  /* for use in grayscale files */
-   png_byte alpha; /* for alpha channel files */
-} png_color_8;
-typedef png_color_8 FAR * png_color_8p;
-typedef PNG_CONST png_color_8 FAR * png_const_color_8p;
-typedef png_color_8 FAR * FAR * png_color_8pp;
-
-/*
- * The following two structures are used for the in-core representation
- * of sPLT chunks.
- */
-typedef struct png_sPLT_entry_struct
-{
-   png_uint_16 red;
-   png_uint_16 green;
-   png_uint_16 blue;
-   png_uint_16 alpha;
-   png_uint_16 frequency;
-} png_sPLT_entry;
-typedef png_sPLT_entry FAR * png_sPLT_entryp;
-typedef PNG_CONST png_sPLT_entry FAR * png_const_sPLT_entryp;
-typedef png_sPLT_entry FAR * FAR * png_sPLT_entrypp;
-
-/*  When the depth of the sPLT palette is 8 bits, the color and alpha samples
- *  occupy the LSB of their respective members, and the MSB of each member
- *  is zero-filled.  The frequency member always occupies the full 16 bits.
- */
-
-typedef struct png_sPLT_struct
-{
-   png_charp name;           /* palette name */
-   png_byte depth;           /* depth of palette samples */
-   png_sPLT_entryp entries;  /* palette entries */
-   png_int_32 nentries;      /* number of palette entries */
-} png_sPLT_t;
-typedef png_sPLT_t FAR * png_sPLT_tp;
-typedef PNG_CONST png_sPLT_t FAR * png_const_sPLT_tp;
-typedef png_sPLT_t FAR * FAR * png_sPLT_tpp;
-
-#ifdef PNG_TEXT_SUPPORTED
-/* png_text holds the contents of a text/ztxt/itxt chunk in a PNG file,
- * and whether that contents is compressed or not.  The "key" field
- * points to a regular zero-terminated C string.  The "text" fields can be a
- * regular C string, an empty string, or a NULL pointer.
- * However, the structure returned by png_get_text() will always contain
- * the "text" field as a regular zero-terminated C string (possibly
- * empty), never a NULL pointer, so it can be safely used in printf() and
- * other string-handling functions.  Note that the "itxt_length", "lang", and
- * "lang_key" members of the structure only exist when the library is built
- * with iTXt chunk support.  Prior to libpng-1.4.0 the library was built by
- * default without iTXt support. Also note that when iTXt *is* supported,
- * the "lang" and "lang_key" fields contain NULL pointers when the
- * "compression" field contains * PNG_TEXT_COMPRESSION_NONE or
- * PNG_TEXT_COMPRESSION_zTXt. Note that the "compression value" is not the
- * same as what appears in the PNG tEXt/zTXt/iTXt chunk's "compression flag"
- * which is always 0 or 1, or its "compression method" which is always 0.
- */
-typedef struct png_text_struct
-{
-   int  compression;       /* compression value:
-                             -1: tEXt, none
-                              0: zTXt, deflate
-                              1: iTXt, none
-                              2: iTXt, deflate  */
-   png_charp key;          /* keyword, 1-79 character description of "text" */
-   png_charp text;         /* comment, may be an empty string (ie "")
-                              or a NULL pointer */
-   png_size_t text_length; /* length of the text string */
-   png_size_t itxt_length; /* length of the itxt string */
-   png_charp lang;         /* language code, 0-79 characters
-                              or a NULL pointer */
-   png_charp lang_key;     /* keyword translated UTF-8 string, 0 or more
-                              chars or a NULL pointer */
-} png_text;
-typedef png_text FAR * png_textp;
-typedef PNG_CONST png_text FAR * png_const_textp;
-typedef png_text FAR * FAR * png_textpp;
-#endif
-
-/* Supported compression types for text in PNG files (tEXt, and zTXt).
- * The values of the PNG_TEXT_COMPRESSION_ defines should NOT be changed. */
-#define PNG_TEXT_COMPRESSION_NONE_WR -3
-#define PNG_TEXT_COMPRESSION_zTXt_WR -2
-#define PNG_TEXT_COMPRESSION_NONE    -1
-#define PNG_TEXT_COMPRESSION_zTXt     0
-#define PNG_ITXT_COMPRESSION_NONE     1
-#define PNG_ITXT_COMPRESSION_zTXt     2
-#define PNG_TEXT_COMPRESSION_LAST     3  /* Not a valid value */
-
-/* png_time is a way to hold the time in an machine independent way.
- * Two conversions are provided, both from time_t and struct tm.  There
- * is no portable way to convert to either of these structures, as far
- * as I know.  If you know of a portable way, send it to me.  As a side
- * note - PNG has always been Year 2000 compliant!
- */
-typedef struct png_time_struct
-{
-   png_uint_16 year; /* full year, as in, 1995 */
-   png_byte month;   /* month of year, 1 - 12 */
-   png_byte day;     /* day of month, 1 - 31 */
-   png_byte hour;    /* hour of day, 0 - 23 */
-   png_byte minute;  /* minute of hour, 0 - 59 */
-   png_byte second;  /* second of minute, 0 - 60 (for leap seconds) */
-} png_time;
-typedef png_time FAR * png_timep;
-typedef PNG_CONST png_time FAR * png_const_timep;
-typedef png_time FAR * FAR * png_timepp;
-
-#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) || \
-    defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED)
-/* png_unknown_chunk is a structure to hold queued chunks for which there is
- * no specific support.  The idea is that we can use this to queue
- * up private chunks for output even though the library doesn't actually
- * know about their semantics.
- */
-typedef struct png_unknown_chunk_t
-{
-    png_byte name[5];
-    png_byte *data;
-    png_size_t size;
-
-    /* libpng-using applications should NOT directly modify this byte. */
-    png_byte location; /* mode of operation at read time */
-}
-
-
-png_unknown_chunk;
-typedef png_unknown_chunk FAR * png_unknown_chunkp;
-typedef PNG_CONST png_unknown_chunk FAR * png_const_unknown_chunkp;
-typedef png_unknown_chunk FAR * FAR * png_unknown_chunkpp;
-#endif
-
-/* Values for the unknown chunk location byte */
-
-#define PNG_HAVE_IHDR  0x01
-#define PNG_HAVE_PLTE  0x02
-#define PNG_AFTER_IDAT 0x08
-
-/* The complete definition of png_info has, as of libpng-1.5.0,
- * been moved into a separate header file that is not accessible to
- * applications.  Read libpng-manual.txt or libpng.3 for more info.
- */
-typedef struct png_info_def png_info;
-typedef png_info FAR * png_infop;
-typedef PNG_CONST png_info FAR * png_const_infop;
-typedef png_info FAR * FAR * png_infopp;
-
-/* Maximum positive integer used in PNG is (2^31)-1 */
-#define PNG_UINT_31_MAX ((png_uint_32)0x7fffffffL)
-#define PNG_UINT_32_MAX ((png_uint_32)(-1))
-#define PNG_SIZE_MAX ((png_size_t)(-1))
-
-/* These are constants for fixed point values encoded in the
- * PNG specification manner (x100000)
- */
-#define PNG_FP_1    100000
-#define PNG_FP_HALF  50000
-#define PNG_FP_MAX  ((png_fixed_point)0x7fffffffL)
-#define PNG_FP_MIN  (-PNG_FP_MAX)
-
-/* These describe the color_type field in png_info. */
-/* color type masks */
-#define PNG_COLOR_MASK_PALETTE    1
-#define PNG_COLOR_MASK_COLOR      2
-#define PNG_COLOR_MASK_ALPHA      4
-
-/* color types.  Note that not all combinations are legal */
-#define PNG_COLOR_TYPE_GRAY 0
-#define PNG_COLOR_TYPE_PALETTE  (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE)
-#define PNG_COLOR_TYPE_RGB        (PNG_COLOR_MASK_COLOR)
-#define PNG_COLOR_TYPE_RGB_ALPHA  (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA)
-#define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA)
-/* aliases */
-#define PNG_COLOR_TYPE_RGBA  PNG_COLOR_TYPE_RGB_ALPHA
-#define PNG_COLOR_TYPE_GA  PNG_COLOR_TYPE_GRAY_ALPHA
-
-/* This is for compression type. PNG 1.0-1.2 only define the single type. */
-#define PNG_COMPRESSION_TYPE_BASE 0 /* Deflate method 8, 32K window */
-#define PNG_COMPRESSION_TYPE_DEFAULT PNG_COMPRESSION_TYPE_BASE
-
-/* This is for filter type. PNG 1.0-1.2 only define the single type. */
-#define PNG_FILTER_TYPE_BASE      0 /* Single row per-byte filtering */
-#define PNG_INTRAPIXEL_DIFFERENCING 64 /* Used only in MNG datastreams */
-#define PNG_FILTER_TYPE_DEFAULT   PNG_FILTER_TYPE_BASE
-
-/* These are for the interlacing type.  These values should NOT be changed. */
-#define PNG_INTERLACE_NONE        0 /* Non-interlaced image */
-#define PNG_INTERLACE_ADAM7       1 /* Adam7 interlacing */
-#define PNG_INTERLACE_LAST        2 /* Not a valid value */
-
-/* These are for the oFFs chunk.  These values should NOT be changed. */
-#define PNG_OFFSET_PIXEL          0 /* Offset in pixels */
-#define PNG_OFFSET_MICROMETER     1 /* Offset in micrometers (1/10^6 meter) */
-#define PNG_OFFSET_LAST           2 /* Not a valid value */
-
-/* These are for the pCAL chunk.  These values should NOT be changed. */
-#define PNG_EQUATION_LINEAR       0 /* Linear transformation */
-#define PNG_EQUATION_BASE_E       1 /* Exponential base e transform */
-#define PNG_EQUATION_ARBITRARY    2 /* Arbitrary base exponential transform */
-#define PNG_EQUATION_HYPERBOLIC   3 /* Hyperbolic sine transformation */
-#define PNG_EQUATION_LAST         4 /* Not a valid value */
-
-/* These are for the sCAL chunk.  These values should NOT be changed. */
-#define PNG_SCALE_UNKNOWN         0 /* unknown unit (image scale) */
-#define PNG_SCALE_METER           1 /* meters per pixel */
-#define PNG_SCALE_RADIAN          2 /* radians per pixel */
-#define PNG_SCALE_LAST            3 /* Not a valid value */
-
-/* These are for the pHYs chunk.  These values should NOT be changed. */
-#define PNG_RESOLUTION_UNKNOWN    0 /* pixels/unknown unit (aspect ratio) */
-#define PNG_RESOLUTION_METER      1 /* pixels/meter */
-#define PNG_RESOLUTION_LAST       2 /* Not a valid value */
-
-/* These are for the sRGB chunk.  These values should NOT be changed. */
-#define PNG_sRGB_INTENT_PERCEPTUAL 0
-#define PNG_sRGB_INTENT_RELATIVE   1
-#define PNG_sRGB_INTENT_SATURATION 2
-#define PNG_sRGB_INTENT_ABSOLUTE   3
-#define PNG_sRGB_INTENT_LAST       4 /* Not a valid value */
-
-/* This is for text chunks */
-#define PNG_KEYWORD_MAX_LENGTH     79
-
-/* Maximum number of entries in PLTE/sPLT/tRNS arrays */
-#define PNG_MAX_PALETTE_LENGTH    256
-
-/* These determine if an ancillary chunk's data has been successfully read
- * from the PNG header, or if the application has filled in the corresponding
- * data in the info_struct to be written into the output file.  The values
- * of the PNG_INFO_<chunk> defines should NOT be changed.
- */
-#define PNG_INFO_gAMA 0x0001
-#define PNG_INFO_sBIT 0x0002
-#define PNG_INFO_cHRM 0x0004
-#define PNG_INFO_PLTE 0x0008
-#define PNG_INFO_tRNS 0x0010
-#define PNG_INFO_bKGD 0x0020
-#define PNG_INFO_hIST 0x0040
-#define PNG_INFO_pHYs 0x0080
-#define PNG_INFO_oFFs 0x0100
-#define PNG_INFO_tIME 0x0200
-#define PNG_INFO_pCAL 0x0400
-#define PNG_INFO_sRGB 0x0800   /* GR-P, 0.96a */
-#define PNG_INFO_iCCP 0x1000   /* ESR, 1.0.6 */
-#define PNG_INFO_sPLT 0x2000   /* ESR, 1.0.6 */
-#define PNG_INFO_sCAL 0x4000   /* ESR, 1.0.6 */
-#define PNG_INFO_IDAT 0x8000   /* ESR, 1.0.6 */
-
-/* This is used for the transformation routines, as some of them
- * change these values for the row.  It also should enable using
- * the routines for other purposes.
- */
-typedef struct png_row_info_struct
-{
-   png_uint_32 width;    /* width of row */
-   png_size_t rowbytes;  /* number of bytes in row */
-   png_byte color_type;  /* color type of row */
-   png_byte bit_depth;   /* bit depth of row */
-   png_byte channels;    /* number of channels (1, 2, 3, or 4) */
-   png_byte pixel_depth; /* bits per pixel (depth * channels) */
-} png_row_info;
-
-typedef png_row_info FAR * png_row_infop;
-typedef png_row_info FAR * FAR * png_row_infopp;
-
-/* The complete definition of png_struct has, as of libpng-1.5.0,
- * been moved into a separate header file that is not accessible to
- * applications.  Read libpng-manual.txt or libpng.3 for more info.
- */
-typedef struct png_struct_def png_struct;
-typedef PNG_CONST png_struct FAR * png_const_structp;
-typedef png_struct FAR * png_structp;
-
-/* These are the function types for the I/O functions and for the functions
- * that allow the user to override the default I/O functions with his or her
- * own.  The png_error_ptr type should match that of user-supplied warning
- * and error functions, while the png_rw_ptr type should match that of the
- * user read/write data functions.  Note that the 'write' function must not
- * modify the buffer it is passed. The 'read' function, on the other hand, is
- * expected to return the read data in the buffer.
- */
-typedef PNG_CALLBACK(void, *png_error_ptr, (png_structp, png_const_charp));
-typedef PNG_CALLBACK(void, *png_rw_ptr, (png_structp, png_bytep, png_size_t));
-typedef PNG_CALLBACK(void, *png_flush_ptr, (png_structp));
-typedef PNG_CALLBACK(void, *png_read_status_ptr, (png_structp, png_uint_32,
-    int));
-typedef PNG_CALLBACK(void, *png_write_status_ptr, (png_structp, png_uint_32,
-    int));
-
-#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
-typedef PNG_CALLBACK(void, *png_progressive_info_ptr, (png_structp, png_infop));
-typedef PNG_CALLBACK(void, *png_progressive_end_ptr, (png_structp, png_infop));
-
-/* The following callback receives png_uint_32 row_number, int pass for the
- * png_bytep data of the row.  When transforming an interlaced image the
- * row number is the row number within the sub-image of the interlace pass, so
- * the value will increase to the height of the sub-image (not the full image)
- * then reset to 0 for the next pass.
- *
- * Use PNG_ROW_FROM_PASS_ROW(row, pass) and PNG_COL_FROM_PASS_COL(col, pass) to
- * find the output pixel (x,y) given an interlaced sub-image pixel
- * (row,col,pass).  (See below for these macros.)
- */
-typedef PNG_CALLBACK(void, *png_progressive_row_ptr, (png_structp, png_bytep,
-    png_uint_32, int));
-#endif
-
-#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
-    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
-typedef PNG_CALLBACK(void, *png_user_transform_ptr, (png_structp, png_row_infop,
-    png_bytep));
-#endif
-
-#ifdef PNG_USER_CHUNKS_SUPPORTED
-typedef PNG_CALLBACK(int, *png_user_chunk_ptr, (png_structp,
-    png_unknown_chunkp));
-#endif
-#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
-typedef PNG_CALLBACK(void, *png_unknown_chunk_ptr, (png_structp));
-#endif
-
-#ifdef PNG_SETJMP_SUPPORTED
-/* This must match the function definition in <setjmp.h>, and the application
- * must include this before png.h to obtain the definition of jmp_buf.  The
- * function is required to be PNG_NORETURN, but this is not checked.  If the
- * function does return the application will crash via an abort() or similar
- * system level call.
- *
- * If you get a warning here while building the library you may need to make
- * changes to ensure that pnglibconf.h records the calling convention used by
- * your compiler.  This may be very difficult - try using a different compiler
- * to build the library!
- */
-PNG_FUNCTION(void, (PNGCAPI *png_longjmp_ptr), PNGARG((jmp_buf, int)), typedef);
-#endif
-
-/* Transform masks for the high-level interface */
-#define PNG_TRANSFORM_IDENTITY       0x0000    /* read and write */
-#define PNG_TRANSFORM_STRIP_16       0x0001    /* read only */
-#define PNG_TRANSFORM_STRIP_ALPHA    0x0002    /* read only */
-#define PNG_TRANSFORM_PACKING        0x0004    /* read and write */
-#define PNG_TRANSFORM_PACKSWAP       0x0008    /* read and write */
-#define PNG_TRANSFORM_EXPAND         0x0010    /* read only */
-#define PNG_TRANSFORM_INVERT_MONO    0x0020    /* read and write */
-#define PNG_TRANSFORM_SHIFT          0x0040    /* read and write */
-#define PNG_TRANSFORM_BGR            0x0080    /* read and write */
-#define PNG_TRANSFORM_SWAP_ALPHA     0x0100    /* read and write */
-#define PNG_TRANSFORM_SWAP_ENDIAN    0x0200    /* read and write */
-#define PNG_TRANSFORM_INVERT_ALPHA   0x0400    /* read and write */
-#define PNG_TRANSFORM_STRIP_FILLER   0x0800    /* write only */
-/* Added to libpng-1.2.34 */
-#define PNG_TRANSFORM_STRIP_FILLER_BEFORE PNG_TRANSFORM_STRIP_FILLER
-#define PNG_TRANSFORM_STRIP_FILLER_AFTER 0x1000 /* write only */
-/* Added to libpng-1.4.0 */
-#define PNG_TRANSFORM_GRAY_TO_RGB   0x2000      /* read only */
-/* Added to libpng-1.5.4 */
-#define PNG_TRANSFORM_EXPAND_16     0x4000      /* read only */
-#define PNG_TRANSFORM_SCALE_16      0x8000      /* read only */
-
-/* Flags for MNG supported features */
-#define PNG_FLAG_MNG_EMPTY_PLTE     0x01
-#define PNG_FLAG_MNG_FILTER_64      0x04
-#define PNG_ALL_MNG_FEATURES        0x05
-
-/* NOTE: prior to 1.5 these functions had no 'API' style declaration,
- * this allowed the zlib default functions to be used on Windows
- * platforms.  In 1.5 the zlib default malloc (which just calls malloc and
- * ignores the first argument) should be completely compatible with the
- * following.
- */
-typedef PNG_CALLBACK(png_voidp, *png_malloc_ptr, (png_structp,
-    png_alloc_size_t));
-typedef PNG_CALLBACK(void, *png_free_ptr, (png_structp, png_voidp));
-
-typedef png_struct FAR * FAR * png_structpp;
-
-/* Section 3: exported functions
- * Here are the function definitions most commonly used.  This is not
- * the place to find out how to use libpng.  See libpng-manual.txt for the
- * full explanation, see example.c for the summary.  This just provides
- * a simple one line description of the use of each function.
- *
- * The PNG_EXPORT() and PNG_EXPORTA() macros used below are defined in
- * pngconf.h and in the *.dfn files in the scripts directory.
- *
- *   PNG_EXPORT(ordinal, type, name, (args));
- *
- *       ordinal:    ordinal that is used while building
- *                   *.def files. The ordinal value is only
- *                   relevant when preprocessing png.h with
- *                   the *.dfn files for building symbol table
- *                   entries, and are removed by pngconf.h.
- *       type:       return type of the function
- *       name:       function name
- *       args:       function arguments, with types
- *
- * When we wish to append attributes to a function prototype we use
- * the PNG_EXPORTA() macro instead.
- *
- *   PNG_EXPORTA(ordinal, type, name, (args), attributes);
- *
- *       ordinal, type, name, and args: same as in PNG_EXPORT().
- *       attributes: function attributes
- */
-
-/* Returns the version number of the library */
-PNG_EXPORT(1, png_uint_32, png_access_version_number, (void));
-
-/* Tell lib we have already handled the first <num_bytes> magic bytes.
- * Handling more than 8 bytes from the beginning of the file is an error.
- */
-PNG_EXPORT(2, void, png_set_sig_bytes, (png_structp png_ptr, int num_bytes));
-
-/* Check sig[start] through sig[start + num_to_check - 1] to see if it's a
- * PNG file.  Returns zero if the supplied bytes match the 8-byte PNG
- * signature, and non-zero otherwise.  Having num_to_check == 0 or
- * start > 7 will always fail (ie return non-zero).
- */
-PNG_EXPORT(3, int, png_sig_cmp, (png_const_bytep sig, png_size_t start,
-    png_size_t num_to_check));
-
-/* Simple signature checking function.  This is the same as calling
- * png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n).
- */
-#define png_check_sig(sig, n) !png_sig_cmp((sig), 0, (n))
-
-/* Allocate and initialize png_ptr struct for reading, and any other memory. */
-PNG_EXPORTA(4, png_structp, png_create_read_struct,
-    (png_const_charp user_png_ver, png_voidp error_ptr,
-    png_error_ptr error_fn, png_error_ptr warn_fn),
-    PNG_ALLOCATED);
-
-/* Allocate and initialize png_ptr struct for writing, and any other memory */
-PNG_EXPORTA(5, png_structp, png_create_write_struct,
-    (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn,
-    png_error_ptr warn_fn),
-    PNG_ALLOCATED);
-
-PNG_EXPORT(6, png_size_t, png_get_compression_buffer_size,
-    (png_const_structp png_ptr));
-
-PNG_EXPORT(7, void, png_set_compression_buffer_size, (png_structp png_ptr,
-    png_size_t size));
-
-/* Moved from pngconf.h in 1.4.0 and modified to ensure setjmp/longjmp
- * match up.
- */
-#ifdef PNG_SETJMP_SUPPORTED
-/* This function returns the jmp_buf built in to *png_ptr.  It must be
- * supplied with an appropriate 'longjmp' function to use on that jmp_buf
- * unless the default error function is overridden in which case NULL is
- * acceptable.  The size of the jmp_buf is checked against the actual size
- * allocated by the library - the call will return NULL on a mismatch
- * indicating an ABI mismatch.
- */
-PNG_EXPORT(8, jmp_buf*, png_set_longjmp_fn, (png_structp png_ptr,
-    png_longjmp_ptr longjmp_fn, size_t jmp_buf_size));
-#  define png_jmpbuf(png_ptr) \
-      (*png_set_longjmp_fn((png_ptr), longjmp, sizeof (jmp_buf)))
-#else
-#  define png_jmpbuf(png_ptr) \
-      (LIBPNG_WAS_COMPILED_WITH__PNG_NO_SETJMP)
-#endif
-/* This function should be used by libpng applications in place of
- * longjmp(png_ptr->jmpbuf, val).  If longjmp_fn() has been set, it
- * will use it; otherwise it will call PNG_ABORT().  This function was
- * added in libpng-1.5.0.
- */
-PNG_EXPORTA(9, void, png_longjmp, (png_structp png_ptr, int val),
-    PNG_NORETURN);
-
-#ifdef PNG_READ_SUPPORTED
-/* Reset the compression stream */
-PNG_EXPORT(10, int, png_reset_zstream, (png_structp png_ptr));
-#endif
-
-/* New functions added in libpng-1.0.2 (not enabled by default until 1.2.0) */
-#ifdef PNG_USER_MEM_SUPPORTED
-PNG_EXPORTA(11, png_structp, png_create_read_struct_2,
-    (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn,
-    png_error_ptr warn_fn,
-    png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn),
-    PNG_ALLOCATED);
-PNG_EXPORTA(12, png_structp, png_create_write_struct_2,
-    (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn,
-    png_error_ptr warn_fn,
-    png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn),
-    PNG_ALLOCATED);
-#endif
-
-/* Write the PNG file signature. */
-PNG_EXPORT(13, void, png_write_sig, (png_structp png_ptr));
-
-/* Write a PNG chunk - size, type, (optional) data, CRC. */
-PNG_EXPORT(14, void, png_write_chunk, (png_structp png_ptr, png_const_bytep
-    chunk_name, png_const_bytep data, png_size_t length));
-
-/* Write the start of a PNG chunk - length and chunk name. */
-PNG_EXPORT(15, void, png_write_chunk_start, (png_structp png_ptr,
-    png_const_bytep chunk_name, png_uint_32 length));
-
-/* Write the data of a PNG chunk started with png_write_chunk_start(). */
-PNG_EXPORT(16, void, png_write_chunk_data, (png_structp png_ptr,
-    png_const_bytep data, png_size_t length));
-
-/* Finish a chunk started with png_write_chunk_start() (includes CRC). */
-PNG_EXPORT(17, void, png_write_chunk_end, (png_structp png_ptr));
-
-/* Allocate and initialize the info structure */
-PNG_EXPORTA(18, png_infop, png_create_info_struct, (png_structp png_ptr),
-    PNG_ALLOCATED);
-
-PNG_EXPORT(19, void, png_info_init_3, (png_infopp info_ptr,
-    png_size_t png_info_struct_size));
-
-/* Writes all the PNG information before the image. */
-PNG_EXPORT(20, void, png_write_info_before_PLTE,
-    (png_structp png_ptr, png_infop info_ptr));
-PNG_EXPORT(21, void, png_write_info,
-    (png_structp png_ptr, png_infop info_ptr));
-
-#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
-/* Read the information before the actual image data. */
-PNG_EXPORT(22, void, png_read_info,
-    (png_structp png_ptr, png_infop info_ptr));
-#endif
-
-#ifdef PNG_TIME_RFC1123_SUPPORTED
-PNG_EXPORT(23, png_const_charp, png_convert_to_rfc1123,
-    (png_structp png_ptr,
-    png_const_timep ptime));
-#endif
-
-#ifdef PNG_CONVERT_tIME_SUPPORTED
-/* Convert from a struct tm to png_time */
-PNG_EXPORT(24, void, png_convert_from_struct_tm, (png_timep ptime,
-    PNG_CONST struct tm FAR * ttime));
-
-/* Convert from time_t to png_time.  Uses gmtime() */
-PNG_EXPORT(25, void, png_convert_from_time_t,
-    (png_timep ptime, time_t ttime));
-#endif /* PNG_CONVERT_tIME_SUPPORTED */
-
-#ifdef PNG_READ_EXPAND_SUPPORTED
-/* Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available. */
-PNG_EXPORT(26, void, png_set_expand, (png_structp png_ptr));
-PNG_EXPORT(27, void, png_set_expand_gray_1_2_4_to_8, (png_structp png_ptr));
-PNG_EXPORT(28, void, png_set_palette_to_rgb, (png_structp png_ptr));
-PNG_EXPORT(29, void, png_set_tRNS_to_alpha, (png_structp png_ptr));
-#endif
-
-#ifdef PNG_READ_EXPAND_16_SUPPORTED
-/* Expand to 16-bit channels, forces conversion of palette to RGB and expansion
- * of a tRNS chunk if present.
- */
-PNG_EXPORT(221, void, png_set_expand_16, (png_structp png_ptr));
-#endif
-
-#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
-/* Use blue, green, red order for pixels. */
-PNG_EXPORT(30, void, png_set_bgr, (png_structp png_ptr));
-#endif
-
-#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
-/* Expand the grayscale to 24-bit RGB if necessary. */
-PNG_EXPORT(31, void, png_set_gray_to_rgb, (png_structp png_ptr));
-#endif
-
-#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
-/* Reduce RGB to grayscale. */
-#define PNG_ERROR_ACTION_NONE  1
-#define PNG_ERROR_ACTION_WARN  2
-#define PNG_ERROR_ACTION_ERROR 3
-#define PNG_RGB_TO_GRAY_DEFAULT (-1)/*for red/green coefficients*/
-
-PNG_FP_EXPORT(32, void, png_set_rgb_to_gray, (png_structp png_ptr,
-    int error_action, double red, double green))
-PNG_FIXED_EXPORT(33, void, png_set_rgb_to_gray_fixed, (png_structp png_ptr,
-    int error_action, png_fixed_point red, png_fixed_point green))
-
-PNG_EXPORT(34, png_byte, png_get_rgb_to_gray_status, (png_const_structp
-    png_ptr));
-#endif
-
-#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED
-PNG_EXPORT(35, void, png_build_grayscale_palette, (int bit_depth,
-    png_colorp palette));
-#endif
-
-#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
-/* How the alpha channel is interpreted - this affects how the color channels of
- * a PNG file are returned when an alpha channel, or tRNS chunk in a palette
- * file, is present.
- *
- * This has no effect on the way pixels are written into a PNG output
- * datastream. The color samples in a PNG datastream are never premultiplied
- * with the alpha samples.
- *
- * The default is to return data according to the PNG specification: the alpha
- * channel is a linear measure of the contribution of the pixel to the
- * corresponding composited pixel.  The gamma encoded color channels must be
- * scaled according to the contribution and to do this it is necessary to undo
- * the encoding, scale the color values, perform the composition and reencode
- * the values.  This is the 'PNG' mode.
- *
- * The alternative is to 'associate' the alpha with the color information by
- * storing color channel values that have been scaled by the alpha.  The
- * advantage is that the color channels can be resampled (the image can be
- * scaled) in this form.  The disadvantage is that normal practice is to store
- * linear, not (gamma) encoded, values and this requires 16-bit channels for
- * still images rather than the 8-bit channels that are just about sufficient if
- * gamma encoding is used.  In addition all non-transparent pixel values,
- * including completely opaque ones, must be gamma encoded to produce the final
- * image.  This is the 'STANDARD', 'ASSOCIATED' or 'PREMULTIPLIED' mode (the
- * latter being the two common names for associated alpha color channels.)
- *
- * Since it is not necessary to perform arithmetic on opaque color values so
- * long as they are not to be resampled and are in the final color space it is
- * possible to optimize the handling of alpha by storing the opaque pixels in
- * the PNG format (adjusted for the output color space) while storing partially
- * opaque pixels in the standard, linear, format.  The accuracy required for
- * standard alpha composition is relatively low, because the pixels are
- * isolated, therefore typically the accuracy loss in storing 8-bit linear
- * values is acceptable.  (This is not true if the alpha channel is used to
- * simulate transparency over large areas - use 16 bits or the PNG mode in
- * this case!)  This is the 'OPTIMIZED' mode.  For this mode a pixel is
- * treated as opaque only if the alpha value is equal to the maximum value.
- *
- * The final choice is to gamma encode the alpha channel as well.  This is
- * broken because, in practice, no implementation that uses this choice
- * correctly undoes the encoding before handling alpha composition.  Use this
- * choice only if other serious errors in the software or hardware you use
- * mandate it; the typical serious error is for dark halos to appear around
- * opaque areas of the composited PNG image because of arithmetic overflow.
- *
- * The API function png_set_alpha_mode specifies which of these choices to use
- * with an enumerated 'mode' value and the gamma of the required output:
- */
-#define PNG_ALPHA_PNG           0 /* according to the PNG standard */
-#define PNG_ALPHA_STANDARD      1 /* according to Porter/Duff */
-#define PNG_ALPHA_ASSOCIATED    1 /* as above; this is the normal practice */
-#define PNG_ALPHA_PREMULTIPLIED 1 /* as above */
-#define PNG_ALPHA_OPTIMIZED     2 /* 'PNG' for opaque pixels, else 'STANDARD' */
-#define PNG_ALPHA_BROKEN        3 /* the alpha channel is gamma encoded */
-
-PNG_FP_EXPORT(227, void, png_set_alpha_mode, (png_structp png_ptr, int mode,
-    double output_gamma))
-PNG_FIXED_EXPORT(228, void, png_set_alpha_mode_fixed, (png_structp png_ptr,
-    int mode, png_fixed_point output_gamma))
-#endif
-
-#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_ALPHA_MODE_SUPPORTED)
-/* The output_gamma value is a screen gamma in libpng terminology: it expresses
- * how to decode the output values, not how they are encoded.  The values used
- * correspond to the normal numbers used to describe the overall gamma of a
- * computer display system; for example 2.2 for an sRGB conformant system.  The
- * values are scaled by 100000 in the _fixed version of the API (so 220000 for
- * sRGB.)
- *
- * The inverse of the value is always used to provide a default for the PNG file
- * encoding if it has no gAMA chunk and if png_set_gamma() has not been called
- * to override the PNG gamma information.
- *
- * When the ALPHA_OPTIMIZED mode is selected the output gamma is used to encode
- * opaque pixels however pixels with lower alpha values are not encoded,
- * regardless of the output gamma setting.
- *
- * When the standard Porter Duff handling is requested with mode 1 the output
- * encoding is set to be linear and the output_gamma value is only relevant
- * as a default for input data that has no gamma information.  The linear output
- * encoding will be overridden if png_set_gamma() is called - the results may be
- * highly unexpected!
- *
- * The following numbers are derived from the sRGB standard and the research
- * behind it.  sRGB is defined to be approximated by a PNG gAMA chunk value of
- * 0.45455 (1/2.2) for PNG.  The value implicitly includes any viewing
- * correction required to take account of any differences in the color
- * environment of the original scene and the intended display environment; the
- * value expresses how to *decode* the image for display, not how the original
- * data was *encoded*.
- *
- * sRGB provides a peg for the PNG standard by defining a viewing environment.
- * sRGB itself, and earlier TV standards, actually use a more complex transform
- * (a linear portion then a gamma 2.4 power law) than PNG can express.  (PNG is
- * limited to simple power laws.)  By saying that an image for direct display on
- * an sRGB conformant system should be stored with a gAMA chunk value of 45455
- * (11.3.3.2 and 11.3.3.5 of the ISO PNG specification) the PNG specification
- * makes it possible to derive values for other display systems and
- * environments.
- *
- * The Mac value is deduced from the sRGB based on an assumption that the actual
- * extra viewing correction used in early Mac display systems was implemented as
- * a power 1.45 lookup table.
- *
- * Any system where a programmable lookup table is used or where the behavior of
- * the final display device characteristics can be changed requires system
- * specific code to obtain the current characteristic.  However this can be
- * difficult and most PNG gamma correction only requires an approximate value.
- *
- * By default, if png_set_alpha_mode() is not called, libpng assumes that all
- * values are unencoded, linear, values and that the output device also has a
- * linear characteristic.  This is only very rarely correct - it is invariably
- * better to call png_set_alpha_mode() with PNG_DEFAULT_sRGB than rely on the
- * default if you don't know what the right answer is!
- *
- * The special value PNG_GAMMA_MAC_18 indicates an older Mac system (pre Mac OS
- * 10.6) which used a correction table to implement a somewhat lower gamma on an
- * otherwise sRGB system.
- *
- * Both these values are reserved (not simple gamma values) in order to allow
- * more precise correction internally in the future.
- *
- * NOTE: the following values can be passed to either the fixed or floating
- * point APIs, but the floating point API will also accept floating point
- * values.
- */
-#define PNG_DEFAULT_sRGB -1       /* sRGB gamma and color space */
-#define PNG_GAMMA_MAC_18 -2       /* Old Mac '1.8' gamma and color space */
-#define PNG_GAMMA_sRGB   220000   /* Television standards--matches sRGB gamma */
-#define PNG_GAMMA_LINEAR PNG_FP_1 /* Linear */
-#endif
-
-/* The following are examples of calls to png_set_alpha_mode to achieve the
- * required overall gamma correction and, where necessary, alpha
- * premultiplication.
- *
- * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB);
- *    This is the default libpng handling of the alpha channel - it is not
- *    pre-multiplied into the color components.  In addition the call states
- *    that the output is for a sRGB system and causes all PNG files without gAMA
- *    chunks to be assumed to be encoded using sRGB.
- *
- * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC);
- *    In this case the output is assumed to be something like an sRGB conformant
- *    display preceeded by a power-law lookup table of power 1.45.  This is how
- *    early Mac systems behaved.
- *
- * png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_GAMMA_LINEAR);
- *    This is the classic Jim Blinn approach and will work in academic
- *    environments where everything is done by the book.  It has the shortcoming
- *    of assuming that input PNG data with no gamma information is linear - this
- *    is unlikely to be correct unless the PNG files where generated locally.
- *    Most of the time the output precision will be so low as to show
- *    significant banding in dark areas of the image.
- *
- * png_set_expand_16(pp);
- * png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_DEFAULT_sRGB);
- *    This is a somewhat more realistic Jim Blinn inspired approach.  PNG files
- *    are assumed to have the sRGB encoding if not marked with a gamma value and
- *    the output is always 16 bits per component.  This permits accurate scaling
- *    and processing of the data.  If you know that your input PNG files were
- *    generated locally you might need to replace PNG_DEFAULT_sRGB with the
- *    correct value for your system.
- *
- * png_set_alpha_mode(pp, PNG_ALPHA_OPTIMIZED, PNG_DEFAULT_sRGB);
- *    If you just need to composite the PNG image onto an existing background
- *    and if you control the code that does this you can use the optimization
- *    setting.  In this case you just copy completely opaque pixels to the
- *    output.  For pixels that are not completely transparent (you just skip
- *    those) you do the composition math using png_composite or png_composite_16
- *    below then encode the resultant 8-bit or 16-bit values to match the output
- *    encoding.
- *
- * Other cases
- *    If neither the PNG nor the standard linear encoding work for you because
- *    of the software or hardware you use then you have a big problem.  The PNG
- *    case will probably result in halos around the image.  The linear encoding
- *    will probably result in a washed out, too bright, image (it's actually too
- *    contrasty.)  Try the ALPHA_OPTIMIZED mode above - this will probably
- *    substantially reduce the halos.  Alternatively try:
- *
- * png_set_alpha_mode(pp, PNG_ALPHA_BROKEN, PNG_DEFAULT_sRGB);
- *    This option will also reduce the halos, but there will be slight dark
- *    halos round the opaque parts of the image where the background is light.
- *    In the OPTIMIZED mode the halos will be light halos where the background
- *    is dark.  Take your pick - the halos are unavoidable unless you can get
- *    your hardware/software fixed!  (The OPTIMIZED approach is slightly
- *    faster.)
- *
- * When the default gamma of PNG files doesn't match the output gamma.
- *    If you have PNG files with no gamma information png_set_alpha_mode allows
- *    you to provide a default gamma, but it also sets the ouput gamma to the
- *    matching value.  If you know your PNG files have a gamma that doesn't
- *    match the output you can take advantage of the fact that
- *    png_set_alpha_mode always sets the output gamma but only sets the PNG
- *    default if it is not already set:
- *
- * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB);
- * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC);
- *    The first call sets both the default and the output gamma values, the
- *    second call overrides the output gamma without changing the default.  This
- *    is easier than achieving the same effect with png_set_gamma.  You must use
- *    PNG_ALPHA_PNG for the first call - internal checking in png_set_alpha will
- *    fire if more than one call to png_set_alpha_mode and png_set_background is
- *    made in the same read operation, however multiple calls with PNG_ALPHA_PNG
- *    are ignored.
- */
-
-#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
-PNG_EXPORT(36, void, png_set_strip_alpha, (png_structp png_ptr));
-#endif
-
-#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
-    defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
-PNG_EXPORT(37, void, png_set_swap_alpha, (png_structp png_ptr));
-#endif
-
-#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
-    defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
-PNG_EXPORT(38, void, png_set_invert_alpha, (png_structp png_ptr));
-#endif
-
-#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
-/* Add a filler byte to 8-bit Gray or 24-bit RGB images. */
-PNG_EXPORT(39, void, png_set_filler, (png_structp png_ptr, png_uint_32 filler,
-    int flags));
-/* The values of the PNG_FILLER_ defines should NOT be changed */
-#  define PNG_FILLER_BEFORE 0
-#  define PNG_FILLER_AFTER 1
-/* Add an alpha byte to 8-bit Gray or 24-bit RGB images. */
-PNG_EXPORT(40, void, png_set_add_alpha,
-    (png_structp png_ptr, png_uint_32 filler,
-    int flags));
-#endif /* PNG_READ_FILLER_SUPPORTED || PNG_WRITE_FILLER_SUPPORTED */
-
-#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
-/* Swap bytes in 16-bit depth files. */
-PNG_EXPORT(41, void, png_set_swap, (png_structp png_ptr));
-#endif
-
-#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
-/* Use 1 byte per pixel in 1, 2, or 4-bit depth files. */
-PNG_EXPORT(42, void, png_set_packing, (png_structp png_ptr));
-#endif
-
-#if defined(PNG_READ_PACKSWAP_SUPPORTED) || \
-    defined(PNG_WRITE_PACKSWAP_SUPPORTED)
-/* Swap packing order of pixels in bytes. */
-PNG_EXPORT(43, void, png_set_packswap, (png_structp png_ptr));
-#endif
-
-#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
-/* Converts files to legal bit depths. */
-PNG_EXPORT(44, void, png_set_shift, (png_structp png_ptr, png_const_color_8p
-    true_bits));
-#endif
-
-#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
-    defined(PNG_WRITE_INTERLACING_SUPPORTED)
-/* Have the code handle the interlacing.  Returns the number of passes.
- * MUST be called before png_read_update_info or png_start_read_image,
- * otherwise it will not have the desired effect.  Note that it is still
- * necessary to call png_read_row or png_read_rows png_get_image_height
- * times for each pass.
-*/
-PNG_EXPORT(45, int, png_set_interlace_handling, (png_structp png_ptr));
-#endif
-
-#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
-/* Invert monochrome files */
-PNG_EXPORT(46, void, png_set_invert_mono, (png_structp png_ptr));
-#endif
-
-#ifdef PNG_READ_BACKGROUND_SUPPORTED
-/* Handle alpha and tRNS by replacing with a background color.  Prior to
- * libpng-1.5.4 this API must not be called before the PNG file header has been
- * read.  Doing so will result in unexpected behavior and possible warnings or
- * errors if the PNG file contains a bKGD chunk.
- */
-PNG_FP_EXPORT(47, void, png_set_background, (png_structp png_ptr,
-    png_const_color_16p background_color, int background_gamma_code,
-    int need_expand, double background_gamma))
-PNG_FIXED_EXPORT(215, void, png_set_background_fixed, (png_structp png_ptr,
-    png_const_color_16p background_color, int background_gamma_code,
-    int need_expand, png_fixed_point background_gamma))
-#endif
-#ifdef PNG_READ_BACKGROUND_SUPPORTED
-#  define PNG_BACKGROUND_GAMMA_UNKNOWN 0
-#  define PNG_BACKGROUND_GAMMA_SCREEN  1
-#  define PNG_BACKGROUND_GAMMA_FILE    2
-#  define PNG_BACKGROUND_GAMMA_UNIQUE  3
-#endif
-
-#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
-/* Scale a 16-bit depth file down to 8-bit, accurately. */
-PNG_EXPORT(229, void, png_set_scale_16, (png_structp png_ptr));
-#endif
-
-#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
-#define PNG_READ_16_TO_8 SUPPORTED /* Name prior to 1.5.4 */
-/* Strip the second byte of information from a 16-bit depth file. */
-PNG_EXPORT(48, void, png_set_strip_16, (png_structp png_ptr));
-#endif
-
-#ifdef PNG_READ_QUANTIZE_SUPPORTED
-/* Turn on quantizing, and reduce the palette to the number of colors
- * available.
- */
-PNG_EXPORT(49, void, png_set_quantize,
-    (png_structp png_ptr, png_colorp palette,
-    int num_palette, int maximum_colors, png_const_uint_16p histogram,
-    int full_quantize));
-#endif
-
-#ifdef PNG_READ_GAMMA_SUPPORTED
-/* The threshold on gamma processing is configurable but hard-wired into the
- * library.  The following is the floating point variant.
- */
-#define PNG_GAMMA_THRESHOLD (PNG_GAMMA_THRESHOLD_FIXED*.00001)
-
-/* Handle gamma correction. Screen_gamma=(display_exponent).
- * NOTE: this API simply sets the screen and file gamma values. It will
- * therefore override the value for gamma in a PNG file if it is called after
- * the file header has been read - use with care  - call before reading the PNG
- * file for best results!
- *
- * These routines accept the same gamma values as png_set_alpha_mode (described
- * above).  The PNG_GAMMA_ defines and PNG_DEFAULT_sRGB can be passed to either
- * API (floating point or fixed.)  Notice, however, that the 'file_gamma' value
- * is the inverse of a 'screen gamma' value.
- */
-PNG_FP_EXPORT(50, void, png_set_gamma,
-    (png_structp png_ptr, double screen_gamma,
-    double override_file_gamma))
-PNG_FIXED_EXPORT(208, void, png_set_gamma_fixed, (png_structp png_ptr,
-    png_fixed_point screen_gamma, png_fixed_point override_file_gamma))
-#endif
-
-#ifdef PNG_WRITE_FLUSH_SUPPORTED
-/* Set how many lines between output flushes - 0 for no flushing */
-PNG_EXPORT(51, void, png_set_flush, (png_structp png_ptr, int nrows));
-/* Flush the current PNG output buffer */
-PNG_EXPORT(52, void, png_write_flush, (png_structp png_ptr));
-#endif
-
-/* Optional update palette with requested transformations */
-PNG_EXPORT(53, void, png_start_read_image, (png_structp png_ptr));
-
-/* Optional call to update the users info structure */
-PNG_EXPORT(54, void, png_read_update_info,
-    (png_structp png_ptr, png_infop info_ptr));
-
-#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
-/* Read one or more rows of image data. */
-PNG_EXPORT(55, void, png_read_rows, (png_structp png_ptr, png_bytepp row,
-    png_bytepp display_row, png_uint_32 num_rows));
-#endif
-
-#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
-/* Read a row of data. */
-PNG_EXPORT(56, void, png_read_row, (png_structp png_ptr, png_bytep row,
-    png_bytep display_row));
-#endif
-
-#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
-/* Read the whole image into memory at once. */
-PNG_EXPORT(57, void, png_read_image, (png_structp png_ptr, png_bytepp image));
-#endif
-
-/* Write a row of image data */
-PNG_EXPORT(58, void, png_write_row,
-    (png_structp png_ptr, png_const_bytep row));
-
-/* Write a few rows of image data: (*row) is not written; however, the type
- * is declared as writeable to maintain compatibility with previous versions
- * of libpng and to allow the 'display_row' array from read_rows to be passed
- * unchanged to write_rows.
- */
-PNG_EXPORT(59, void, png_write_rows, (png_structp png_ptr, png_bytepp row,
-    png_uint_32 num_rows));
-
-/* Write the image data */
-PNG_EXPORT(60, void, png_write_image,
-    (png_structp png_ptr, png_bytepp image));
-
-/* Write the end of the PNG file. */
-PNG_EXPORT(61, void, png_write_end,
-    (png_structp png_ptr, png_infop info_ptr));
-
-#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
-/* Read the end of the PNG file. */
-PNG_EXPORT(62, void, png_read_end, (png_structp png_ptr, png_infop info_ptr));
-#endif
-
-/* Free any memory associated with the png_info_struct */
-PNG_EXPORT(63, void, png_destroy_info_struct, (png_structp png_ptr,
-    png_infopp info_ptr_ptr));
-
-/* Free any memory associated with the png_struct and the png_info_structs */
-PNG_EXPORT(64, void, png_destroy_read_struct, (png_structpp png_ptr_ptr,
-    png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr));
-
-/* Free any memory associated with the png_struct and the png_info_structs */
-PNG_EXPORT(65, void, png_destroy_write_struct, (png_structpp png_ptr_ptr,
-    png_infopp info_ptr_ptr));
-
-/* Set the libpng method of handling chunk CRC errors */
-PNG_EXPORT(66, void, png_set_crc_action,
-    (png_structp png_ptr, int crit_action, int ancil_action));
-
-/* Values for png_set_crc_action() say how to handle CRC errors in
- * ancillary and critical chunks, and whether to use the data contained
- * therein.  Note that it is impossible to "discard" data in a critical
- * chunk.  For versions prior to 0.90, the action was always error/quit,
- * whereas in version 0.90 and later, the action for CRC errors in ancillary
- * chunks is warn/discard.  These values should NOT be changed.
- *
- *      value                       action:critical     action:ancillary
- */
-#define PNG_CRC_DEFAULT       0  /* error/quit          warn/discard data */
-#define PNG_CRC_ERROR_QUIT    1  /* error/quit          error/quit        */
-#define PNG_CRC_WARN_DISCARD  2  /* (INVALID)           warn/discard data */
-#define PNG_CRC_WARN_USE      3  /* warn/use data       warn/use data     */
-#define PNG_CRC_QUIET_USE     4  /* quiet/use data      quiet/use data    */
-#define PNG_CRC_NO_CHANGE     5  /* use current value   use current value */
-
-/* These functions give the user control over the scan-line filtering in
- * libpng and the compression methods used by zlib.  These functions are
- * mainly useful for testing, as the defaults should work with most users.
- * Those users who are tight on memory or want faster performance at the
- * expense of compression can modify them.  See the compression library
- * header file (zlib.h) for an explination of the compression functions.
- */
-
-/* Set the filtering method(s) used by libpng.  Currently, the only valid
- * value for "method" is 0.
- */
-PNG_EXPORT(67, void, png_set_filter,
-    (png_structp png_ptr, int method, int filters));
-
-/* Flags for png_set_filter() to say which filters to use.  The flags
- * are chosen so that they don't conflict with real filter types
- * below, in case they are supplied instead of the #defined constants.
- * These values should NOT be changed.
- */
-#define PNG_NO_FILTERS     0x00
-#define PNG_FILTER_NONE    0x08
-#define PNG_FILTER_SUB     0x10
-#define PNG_FILTER_UP      0x20
-#define PNG_FILTER_AVG     0x40
-#define PNG_FILTER_PAETH   0x80
-#define PNG_ALL_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | \
-                         PNG_FILTER_AVG | PNG_FILTER_PAETH)
-
-/* Filter values (not flags) - used in pngwrite.c, pngwutil.c for now.
- * These defines should NOT be changed.
- */
-#define PNG_FILTER_VALUE_NONE  0
-#define PNG_FILTER_VALUE_SUB   1
-#define PNG_FILTER_VALUE_UP    2
-#define PNG_FILTER_VALUE_AVG   3
-#define PNG_FILTER_VALUE_PAETH 4
-#define PNG_FILTER_VALUE_LAST  5
-
-#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* EXPERIMENTAL */
-/* The "heuristic_method" is given by one of the PNG_FILTER_HEURISTIC_
- * defines, either the default (minimum-sum-of-absolute-differences), or
- * the experimental method (weighted-minimum-sum-of-absolute-differences).
- *
- * Weights are factors >= 1.0, indicating how important it is to keep the
- * filter type consistent between rows.  Larger numbers mean the current
- * filter is that many times as likely to be the same as the "num_weights"
- * previous filters.  This is cumulative for each previous row with a weight.
- * There needs to be "num_weights" values in "filter_weights", or it can be
- * NULL if the weights aren't being specified.  Weights have no influence on
- * the selection of the first row filter.  Well chosen weights can (in theory)
- * improve the compression for a given image.
- *
- * Costs are factors >= 1.0 indicating the relative decoding costs of a
- * filter type.  Higher costs indicate more decoding expense, and are
- * therefore less likely to be selected over a filter with lower computational
- * costs.  There needs to be a value in "filter_costs" for each valid filter
- * type (given by PNG_FILTER_VALUE_LAST), or it can be NULL if you aren't
- * setting the costs.  Costs try to improve the speed of decompression without
- * unduly increasing the compressed image size.
- *
- * A negative weight or cost indicates the default value is to be used, and
- * values in the range [0.0, 1.0) indicate the value is to remain unchanged.
- * The default values for both weights and costs are currently 1.0, but may
- * change if good general weighting/cost heuristics can be found.  If both
- * the weights and costs are set to 1.0, this degenerates the WEIGHTED method
- * to the UNWEIGHTED method, but with added encoding time/computation.
- */
-PNG_FP_EXPORT(68, void, png_set_filter_heuristics, (png_structp png_ptr,
-    int heuristic_method, int num_weights, png_const_doublep filter_weights,
-    png_const_doublep filter_costs))
-PNG_FIXED_EXPORT(209, void, png_set_filter_heuristics_fixed,
-    (png_structp png_ptr,
-    int heuristic_method, int num_weights, png_const_fixed_point_p
-    filter_weights, png_const_fixed_point_p filter_costs))
-#endif /*  PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */
-
-/* Heuristic used for row filter selection.  These defines should NOT be
- * changed.
- */
-#define PNG_FILTER_HEURISTIC_DEFAULT    0  /* Currently "UNWEIGHTED" */
-#define PNG_FILTER_HEURISTIC_UNWEIGHTED 1  /* Used by libpng < 0.95 */
-#define PNG_FILTER_HEURISTIC_WEIGHTED   2  /* Experimental feature */
-#define PNG_FILTER_HEURISTIC_LAST       3  /* Not a valid value */
-
-#ifdef PNG_WRITE_SUPPORTED
-/* Set the library compression level.  Currently, valid values range from
- * 0 - 9, corresponding directly to the zlib compression levels 0 - 9
- * (0 - no compression, 9 - "maximal" compression).  Note that tests have
- * shown that zlib compression levels 3-6 usually perform as well as level 9
- * for PNG images, and do considerably fewer caclulations.  In the future,
- * these values may not correspond directly to the zlib compression levels.
- */
-PNG_EXPORT(69, void, png_set_compression_level,
-    (png_structp png_ptr, int level));
-
-PNG_EXPORT(70, void, png_set_compression_mem_level, (png_structp png_ptr,
-    int mem_level));
-
-PNG_EXPORT(71, void, png_set_compression_strategy, (png_structp png_ptr,
-    int strategy));
-
-/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a
- * smaller value of window_bits if it can do so safely.
- */
-PNG_EXPORT(72, void, png_set_compression_window_bits, (png_structp png_ptr,
-    int window_bits));
-
-PNG_EXPORT(73, void, png_set_compression_method, (png_structp png_ptr,
-    int method));
-#endif
-
-#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
-/* Also set zlib parameters for compressing non-IDAT chunks */
-PNG_EXPORT(222, void, png_set_text_compression_level,
-    (png_structp png_ptr, int level));
-
-PNG_EXPORT(223, void, png_set_text_compression_mem_level, (png_structp png_ptr,
-    int mem_level));
-
-PNG_EXPORT(224, void, png_set_text_compression_strategy, (png_structp png_ptr,
-    int strategy));
-
-/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a
- * smaller value of window_bits if it can do so safely.
- */
-PNG_EXPORT(225, void, png_set_text_compression_window_bits, (png_structp
-    png_ptr, int window_bits));
-
-PNG_EXPORT(226, void, png_set_text_compression_method, (png_structp png_ptr,
-    int method));
-#endif /* PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED */
-
-/* These next functions are called for input/output, memory, and error
- * handling.  They are in the file pngrio.c, pngwio.c, and pngerror.c,
- * and call standard C I/O routines such as fread(), fwrite(), and
- * fprintf().  These functions can be made to use other I/O routines
- * at run time for those applications that need to handle I/O in a
- * different manner by calling png_set_???_fn().  See libpng-manual.txt for
- * more information.
- */
-
-#ifdef PNG_STDIO_SUPPORTED
-/* Initialize the input/output for the PNG file to the default functions. */
-PNG_EXPORT(74, void, png_init_io, (png_structp png_ptr, png_FILE_p fp));
-#endif
-
-/* Replace the (error and abort), and warning functions with user
- * supplied functions.  If no messages are to be printed you must still
- * write and use replacement functions. The replacement error_fn should
- * still do a longjmp to the last setjmp location if you are using this
- * method of error handling.  If error_fn or warning_fn is NULL, the
- * default function will be used.
- */
-
-PNG_EXPORT(75, void, png_set_error_fn,
-    (png_structp png_ptr, png_voidp error_ptr,
-    png_error_ptr error_fn, png_error_ptr warning_fn));
-
-/* Return the user pointer associated with the error functions */
-PNG_EXPORT(76, png_voidp, png_get_error_ptr, (png_const_structp png_ptr));
-
-/* Replace the default data output functions with a user supplied one(s).
- * If buffered output is not used, then output_flush_fn can be set to NULL.
- * If PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile time
- * output_flush_fn will be ignored (and thus can be NULL).
- * It is probably a mistake to use NULL for output_flush_fn if
- * write_data_fn is not also NULL unless you have built libpng with
- * PNG_WRITE_FLUSH_SUPPORTED undefined, because in this case libpng's
- * default flush function, which uses the standard *FILE structure, will
- * be used.
- */
-PNG_EXPORT(77, void, png_set_write_fn, (png_structp png_ptr, png_voidp io_ptr,
-    png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn));
-
-/* Replace the default data input function with a user supplied one. */
-PNG_EXPORT(78, void, png_set_read_fn, (png_structp png_ptr, png_voidp io_ptr,
-    png_rw_ptr read_data_fn));
-
-/* Return the user pointer associated with the I/O functions */
-PNG_EXPORT(79, png_voidp, png_get_io_ptr, (png_structp png_ptr));
-
-PNG_EXPORT(80, void, png_set_read_status_fn, (png_structp png_ptr,
-    png_read_status_ptr read_row_fn));
-
-PNG_EXPORT(81, void, png_set_write_status_fn, (png_structp png_ptr,
-    png_write_status_ptr write_row_fn));
-
-#ifdef PNG_USER_MEM_SUPPORTED
-/* Replace the default memory allocation functions with user supplied one(s). */
-PNG_EXPORT(82, void, png_set_mem_fn, (png_structp png_ptr, png_voidp mem_ptr,
-    png_malloc_ptr malloc_fn, png_free_ptr free_fn));
-/* Return the user pointer associated with the memory functions */
-PNG_EXPORT(83, png_voidp, png_get_mem_ptr, (png_const_structp png_ptr));
-#endif
-
-#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
-PNG_EXPORT(84, void, png_set_read_user_transform_fn, (png_structp png_ptr,
-    png_user_transform_ptr read_user_transform_fn));
-#endif
-
-#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
-PNG_EXPORT(85, void, png_set_write_user_transform_fn, (png_structp png_ptr,
-    png_user_transform_ptr write_user_transform_fn));
-#endif
-
-#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
-PNG_EXPORT(86, void, png_set_user_transform_info, (png_structp png_ptr,
-    png_voidp user_transform_ptr, int user_transform_depth,
-    int user_transform_channels));
-/* Return the user pointer associated with the user transform functions */
-PNG_EXPORT(87, png_voidp, png_get_user_transform_ptr,
-    (png_const_structp png_ptr));
-#endif
-
-#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED
-/* Return information about the row currently being processed.  Note that these
- * APIs do not fail but will return unexpected results if called outside a user
- * transform callback.  Also note that when transforming an interlaced image the
- * row number is the row number within the sub-image of the interlace pass, so
- * the value will increase to the height of the sub-image (not the full image)
- * then reset to 0 for the next pass.
- *
- * Use PNG_ROW_FROM_PASS_ROW(row, pass) and PNG_COL_FROM_PASS_COL(col, pass) to
- * find the output pixel (x,y) given an interlaced sub-image pixel
- * (row,col,pass).  (See below for these macros.)
- */
-PNG_EXPORT(217, png_uint_32, png_get_current_row_number, (png_const_structp));
-PNG_EXPORT(218, png_byte, png_get_current_pass_number, (png_const_structp));
-#endif
-
-#ifdef PNG_USER_CHUNKS_SUPPORTED
-PNG_EXPORT(88, void, png_set_read_user_chunk_fn, (png_structp png_ptr,
-    png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn));
-PNG_EXPORT(89, png_voidp, png_get_user_chunk_ptr, (png_const_structp png_ptr));
-#endif
-
-#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
-/* Sets the function callbacks for the push reader, and a pointer to a
- * user-defined structure available to the callback functions.
- */
-PNG_EXPORT(90, void, png_set_progressive_read_fn, (png_structp png_ptr,
-    png_voidp progressive_ptr, png_progressive_info_ptr info_fn,
-    png_progressive_row_ptr row_fn, png_progressive_end_ptr end_fn));
-
-/* Returns the user pointer associated with the push read functions */
-PNG_EXPORT(91, png_voidp, png_get_progressive_ptr, (png_const_structp png_ptr));
-
-/* Function to be called when data becomes available */
-PNG_EXPORT(92, void, png_process_data,
-    (png_structp png_ptr, png_infop info_ptr,
-    png_bytep buffer, png_size_t buffer_size));
-
-/* A function which may be called *only* within png_process_data to stop the
- * processing of any more data.  The function returns the number of bytes
- * remaining, excluding any that libpng has cached internally.  A subsequent
- * call to png_process_data must supply these bytes again.  If the argument
- * 'save' is set to true the routine will first save all the pending data and
- * will always return 0.
- */
-PNG_EXPORT(219, png_size_t, png_process_data_pause, (png_structp, int save));
-
-/* A function which may be called *only* outside (after) a call to
- * png_process_data.  It returns the number of bytes of data to skip in the
- * input.  Normally it will return 0, but if it returns a non-zero value the
- * application must skip than number of bytes of input data and pass the
- * following data to the next call to png_process_data.
- */
-PNG_EXPORT(220, png_uint_32, png_process_data_skip, (png_structp));
-
-#ifdef PNG_READ_INTERLACING_SUPPORTED
-/* Function that combines rows.  'new_row' is a flag that should come from
- * the callback and be non-NULL if anything needs to be done; the library
- * stores its own version of the new data internally and ignores the passed
- * in value.
- */
-PNG_EXPORT(93, void, png_progressive_combine_row, (png_structp png_ptr,
-    png_bytep old_row, png_const_bytep new_row));
-#endif /* PNG_READ_INTERLACING_SUPPORTED */
-#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
-
-PNG_EXPORTA(94, png_voidp, png_malloc,
-    (png_structp png_ptr, png_alloc_size_t size),
-    PNG_ALLOCATED);
-/* Added at libpng version 1.4.0 */
-PNG_EXPORTA(95, png_voidp, png_calloc,
-    (png_structp png_ptr, png_alloc_size_t size),
-    PNG_ALLOCATED);
-
-/* Added at libpng version 1.2.4 */
-PNG_EXPORTA(96, png_voidp, png_malloc_warn, (png_structp png_ptr,
-    png_alloc_size_t size), PNG_ALLOCATED);
-
-/* Frees a pointer allocated by png_malloc() */
-PNG_EXPORT(97, void, png_free, (png_structp png_ptr, png_voidp ptr));
-
-/* Free data that was allocated internally */
-PNG_EXPORT(98, void, png_free_data,
-    (png_structp png_ptr, png_infop info_ptr, png_uint_32 free_me, int num));
-
-/* Reassign responsibility for freeing existing data, whether allocated
- * by libpng or by the application */
-PNG_EXPORT(99, void, png_data_freer,
-    (png_structp png_ptr, png_infop info_ptr, int freer, png_uint_32 mask));
-
-/* Assignments for png_data_freer */
-#define PNG_DESTROY_WILL_FREE_DATA 1
-#define PNG_SET_WILL_FREE_DATA 1
-#define PNG_USER_WILL_FREE_DATA 2
-/* Flags for png_ptr->free_me and info_ptr->free_me */
-#define PNG_FREE_HIST 0x0008
-#define PNG_FREE_ICCP 0x0010
-#define PNG_FREE_SPLT 0x0020
-#define PNG_FREE_ROWS 0x0040
-#define PNG_FREE_PCAL 0x0080
-#define PNG_FREE_SCAL 0x0100
-#define PNG_FREE_UNKN 0x0200
-#define PNG_FREE_LIST 0x0400
-#define PNG_FREE_PLTE 0x1000
-#define PNG_FREE_TRNS 0x2000
-#define PNG_FREE_TEXT 0x4000
-#define PNG_FREE_ALL  0x7fff
-#define PNG_FREE_MUL  0x4220 /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */
-
-#ifdef PNG_USER_MEM_SUPPORTED
-PNG_EXPORTA(100, png_voidp, png_malloc_default, (png_structp png_ptr,
-    png_alloc_size_t size), PNG_ALLOCATED);
-PNG_EXPORT(101, void, png_free_default, (png_structp png_ptr, png_voidp ptr));
-#endif
-
-#ifdef PNG_ERROR_TEXT_SUPPORTED
-/* Fatal error in PNG image of libpng - can't continue */
-PNG_EXPORTA(102, void, png_error,
-    (png_structp png_ptr, png_const_charp error_message),
-    PNG_NORETURN);
-
-/* The same, but the chunk name is prepended to the error string. */
-PNG_EXPORTA(103, void, png_chunk_error, (png_structp png_ptr,
-    png_const_charp error_message), PNG_NORETURN);
-
-#else
-/* Fatal error in PNG image of libpng - can't continue */
-PNG_EXPORTA(104, void, png_err, (png_structp png_ptr), PNG_NORETURN);
-#endif
-
-#ifdef PNG_WARNINGS_SUPPORTED
-/* Non-fatal error in libpng.  Can continue, but may have a problem. */
-PNG_EXPORT(105, void, png_warning, (png_structp png_ptr,
-    png_const_charp warning_message));
-
-/* Non-fatal error in libpng, chunk name is prepended to message. */
-PNG_EXPORT(106, void, png_chunk_warning, (png_structp png_ptr,
-    png_const_charp warning_message));
-#endif
-
-#ifdef PNG_BENIGN_ERRORS_SUPPORTED
-/* Benign error in libpng.  Can continue, but may have a problem.
- * User can choose whether to handle as a fatal error or as a warning. */
-#  undef png_benign_error
-PNG_EXPORT(107, void, png_benign_error, (png_structp png_ptr,
-    png_const_charp warning_message));
-
-/* Same, chunk name is prepended to message. */
-#  undef png_chunk_benign_error
-PNG_EXPORT(108, void, png_chunk_benign_error, (png_structp png_ptr,
-    png_const_charp warning_message));
-
-PNG_EXPORT(109, void, png_set_benign_errors,
-    (png_structp png_ptr, int allowed));
-#else
-#  ifdef PNG_ALLOW_BENIGN_ERRORS
-#    define png_benign_error png_warning
-#    define png_chunk_benign_error png_chunk_warning
-#  else
-#    define png_benign_error png_error
-#    define png_chunk_benign_error png_chunk_error
-#  endif
-#endif
-
-/* The png_set_<chunk> functions are for storing values in the png_info_struct.
- * Similarly, the png_get_<chunk> calls are used to read values from the
- * png_info_struct, either storing the parameters in the passed variables, or
- * setting pointers into the png_info_struct where the data is stored.  The
- * png_get_<chunk> functions return a non-zero value if the data was available
- * in info_ptr, or return zero and do not change any of the parameters if the
- * data was not available.
- *
- * These functions should be used instead of directly accessing png_info
- * to avoid problems with future changes in the size and internal layout of
- * png_info_struct.
- */
-/* Returns "flag" if chunk data is valid in info_ptr. */
-PNG_EXPORT(110, png_uint_32, png_get_valid,
-    (png_const_structp png_ptr, png_const_infop info_ptr,
-    png_uint_32 flag));
-
-/* Returns number of bytes needed to hold a transformed row. */
-PNG_EXPORT(111, png_size_t, png_get_rowbytes, (png_const_structp png_ptr,
-    png_const_infop info_ptr));
-
-#ifdef PNG_INFO_IMAGE_SUPPORTED
-/* Returns row_pointers, which is an array of pointers to scanlines that was
- * returned from png_read_png().
- */
-PNG_EXPORT(112, png_bytepp, png_get_rows,
-    (png_const_structp png_ptr, png_const_infop info_ptr));
-/* Set row_pointers, which is an array of pointers to scanlines for use
- * by png_write_png().
- */
-PNG_EXPORT(113, void, png_set_rows, (png_structp png_ptr,
-    png_infop info_ptr, png_bytepp row_pointers));
-#endif
-
-/* Returns number of color channels in image. */
-PNG_EXPORT(114, png_byte, png_get_channels,
-    (png_const_structp png_ptr, png_const_infop info_ptr));
-
-#ifdef PNG_EASY_ACCESS_SUPPORTED
-/* Returns image width in pixels. */
-PNG_EXPORT(115, png_uint_32, png_get_image_width, (png_const_structp png_ptr,
-    png_const_infop info_ptr));
-
-/* Returns image height in pixels. */
-PNG_EXPORT(116, png_uint_32, png_get_image_height, (png_const_structp png_ptr,
-    png_const_infop info_ptr));
-
-/* Returns image bit_depth. */
-PNG_EXPORT(117, png_byte, png_get_bit_depth,
-    (png_const_structp png_ptr, png_const_infop info_ptr));
-
-/* Returns image color_type. */
-PNG_EXPORT(118, png_byte, png_get_color_type, (png_const_structp png_ptr,
-    png_const_infop info_ptr));
-
-/* Returns image filter_type. */
-PNG_EXPORT(119, png_byte, png_get_filter_type, (png_const_structp png_ptr,
-    png_const_infop info_ptr));
-
-/* Returns image interlace_type. */
-PNG_EXPORT(120, png_byte, png_get_interlace_type, (png_const_structp png_ptr,
-    png_const_infop info_ptr));
-
-/* Returns image compression_type. */
-PNG_EXPORT(121, png_byte, png_get_compression_type, (png_const_structp png_ptr,
-    png_const_infop info_ptr));
-
-/* Returns image resolution in pixels per meter, from pHYs chunk data. */
-PNG_EXPORT(122, png_uint_32, png_get_pixels_per_meter,
-    (png_const_structp png_ptr, png_const_infop info_ptr));
-PNG_EXPORT(123, png_uint_32, png_get_x_pixels_per_meter,
-    (png_const_structp png_ptr, png_const_infop info_ptr));
-PNG_EXPORT(124, png_uint_32, png_get_y_pixels_per_meter,
-    (png_const_structp png_ptr, png_const_infop info_ptr));
-
-/* Returns pixel aspect ratio, computed from pHYs chunk data.  */
-PNG_FP_EXPORT(125, float, png_get_pixel_aspect_ratio,
-    (png_const_structp png_ptr, png_const_infop info_ptr))
-PNG_FIXED_EXPORT(210, png_fixed_point, png_get_pixel_aspect_ratio_fixed,
-    (png_const_structp png_ptr, png_const_infop info_ptr))
-
-/* Returns image x, y offset in pixels or microns, from oFFs chunk data. */
-PNG_EXPORT(126, png_int_32, png_get_x_offset_pixels,
-    (png_const_structp png_ptr, png_const_infop info_ptr));
-PNG_EXPORT(127, png_int_32, png_get_y_offset_pixels,
-    (png_const_structp png_ptr, png_const_infop info_ptr));
-PNG_EXPORT(128, png_int_32, png_get_x_offset_microns,
-    (png_const_structp png_ptr, png_const_infop info_ptr));
-PNG_EXPORT(129, png_int_32, png_get_y_offset_microns,
-    (png_const_structp png_ptr, png_const_infop info_ptr));
-
-#endif /* PNG_EASY_ACCESS_SUPPORTED */
-
-/* Returns pointer to signature string read from PNG header */
-PNG_EXPORT(130, png_const_bytep, png_get_signature,
-    (png_const_structp png_ptr, png_infop info_ptr));
-
-#ifdef PNG_bKGD_SUPPORTED
-PNG_EXPORT(131, png_uint_32, png_get_bKGD,
-    (png_const_structp png_ptr, png_infop info_ptr,
-    png_color_16p *background));
-#endif
-
-#ifdef PNG_bKGD_SUPPORTED
-PNG_EXPORT(132, void, png_set_bKGD, (png_structp png_ptr, png_infop info_ptr,
-    png_const_color_16p background));
-#endif
-
-#ifdef PNG_cHRM_SUPPORTED
-PNG_FP_EXPORT(133, png_uint_32, png_get_cHRM, (png_const_structp png_ptr,
-   png_const_infop info_ptr, double *white_x, double *white_y, double *red_x,
-    double *red_y, double *green_x, double *green_y, double *blue_x,
-    double *blue_y))
-PNG_FP_EXPORT(230, png_uint_32, png_get_cHRM_XYZ, (png_structp png_ptr,
-    png_const_infop info_ptr, double *red_X, double *red_Y, double *red_Z,
-    double *green_X, double *green_Y, double *green_Z, double *blue_X,
-    double *blue_Y, double *blue_Z))
-#ifdef PNG_FIXED_POINT_SUPPORTED /* Otherwise not implemented */
-PNG_FIXED_EXPORT(134, png_uint_32, png_get_cHRM_fixed,
-    (png_const_structp png_ptr,
-    png_const_infop info_ptr, png_fixed_point *int_white_x,
-    png_fixed_point *int_white_y, png_fixed_point *int_red_x,
-    png_fixed_point *int_red_y, png_fixed_point *int_green_x,
-    png_fixed_point *int_green_y, png_fixed_point *int_blue_x,
-    png_fixed_point *int_blue_y))
-#endif
-PNG_FIXED_EXPORT(231, png_uint_32, png_get_cHRM_XYZ_fixed,
-    (png_structp png_ptr, png_const_infop info_ptr,
-    png_fixed_point *int_red_X, png_fixed_point *int_red_Y,
-    png_fixed_point *int_red_Z, png_fixed_point *int_green_X,
-    png_fixed_point *int_green_Y, png_fixed_point *int_green_Z,
-    png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y,
-    png_fixed_point *int_blue_Z))
-#endif
-
-#ifdef PNG_cHRM_SUPPORTED
-PNG_FP_EXPORT(135, void, png_set_cHRM,
-    (png_structp png_ptr, png_infop info_ptr,
-    double white_x, double white_y, double red_x, double red_y, double green_x,
-    double green_y, double blue_x, double blue_y))
-PNG_FP_EXPORT(232, void, png_set_cHRM_XYZ, (png_structp png_ptr,
-    png_infop info_ptr, double red_X, double red_Y, double red_Z,
-    double green_X, double green_Y, double green_Z, double blue_X,
-    double blue_Y, double blue_Z))
-PNG_FIXED_EXPORT(136, void, png_set_cHRM_fixed, (png_structp png_ptr,
-    png_infop info_ptr, png_fixed_point int_white_x,
-    png_fixed_point int_white_y, png_fixed_point int_red_x,
-    png_fixed_point int_red_y, png_fixed_point int_green_x,
-    png_fixed_point int_green_y, png_fixed_point int_blue_x,
-    png_fixed_point int_blue_y))
-PNG_FIXED_EXPORT(233, void, png_set_cHRM_XYZ_fixed, (png_structp png_ptr,
-    png_infop info_ptr, png_fixed_point int_red_X, png_fixed_point int_red_Y,
-    png_fixed_point int_red_Z, png_fixed_point int_green_X,
-    png_fixed_point int_green_Y, png_fixed_point int_green_Z,
-    png_fixed_point int_blue_X, png_fixed_point int_blue_Y,
-    png_fixed_point int_blue_Z))
-#endif
-
-#ifdef PNG_gAMA_SUPPORTED
-PNG_FP_EXPORT(137, png_uint_32, png_get_gAMA,
-    (png_const_structp png_ptr, png_const_infop info_ptr,
-    double *file_gamma))
-PNG_FIXED_EXPORT(138, png_uint_32, png_get_gAMA_fixed,
-    (png_const_structp png_ptr, png_const_infop info_ptr,
-    png_fixed_point *int_file_gamma))
-#endif
-
-#ifdef PNG_gAMA_SUPPORTED
-PNG_FP_EXPORT(139, void, png_set_gAMA, (png_structp png_ptr,
-    png_infop info_ptr, double file_gamma))
-PNG_FIXED_EXPORT(140, void, png_set_gAMA_fixed, (png_structp png_ptr,
-    png_infop info_ptr, png_fixed_point int_file_gamma))
-#endif
-
-#ifdef PNG_hIST_SUPPORTED
-PNG_EXPORT(141, png_uint_32, png_get_hIST,
-    (png_const_structp png_ptr, png_const_infop info_ptr,
-    png_uint_16p *hist));
-#endif
-
-#ifdef PNG_hIST_SUPPORTED
-PNG_EXPORT(142, void, png_set_hIST, (png_structp png_ptr,
-    png_infop info_ptr, png_const_uint_16p hist));
-#endif
-
-PNG_EXPORT(143, png_uint_32, png_get_IHDR,
-    (png_structp png_ptr, png_infop info_ptr,
-    png_uint_32 *width, png_uint_32 *height, int *bit_depth, int *color_type,
-    int *interlace_method, int *compression_method, int *filter_method));
-
-PNG_EXPORT(144, void, png_set_IHDR,
-    (png_structp png_ptr, png_infop info_ptr,
-    png_uint_32 width, png_uint_32 height, int bit_depth, int color_type,
-    int interlace_method, int compression_method, int filter_method));
-
-#ifdef PNG_oFFs_SUPPORTED
-PNG_EXPORT(145, png_uint_32, png_get_oFFs,
-    (png_const_structp png_ptr, png_const_infop info_ptr,
-    png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type));
-#endif
-
-#ifdef PNG_oFFs_SUPPORTED
-PNG_EXPORT(146, void, png_set_oFFs,
-    (png_structp png_ptr, png_infop info_ptr,
-    png_int_32 offset_x, png_int_32 offset_y, int unit_type));
-#endif
-
-#ifdef PNG_pCAL_SUPPORTED
-PNG_EXPORT(147, png_uint_32, png_get_pCAL,
-    (png_const_structp png_ptr, png_const_infop info_ptr,
-    png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type,
-    int *nparams,
-    png_charp *units, png_charpp *params));
-#endif
-
-#ifdef PNG_pCAL_SUPPORTED
-PNG_EXPORT(148, void, png_set_pCAL, (png_structp png_ptr,
-    png_infop info_ptr,
-    png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type,
-    int nparams, png_const_charp units, png_charpp params));
-#endif
-
-#ifdef PNG_pHYs_SUPPORTED
-PNG_EXPORT(149, png_uint_32, png_get_pHYs,
-    (png_const_structp png_ptr, png_const_infop info_ptr,
-    png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type));
-#endif
-
-#ifdef PNG_pHYs_SUPPORTED
-PNG_EXPORT(150, void, png_set_pHYs,
-    (png_structp png_ptr, png_infop info_ptr,
-    png_uint_32 res_x, png_uint_32 res_y, int unit_type));
-#endif
-
-PNG_EXPORT(151, png_uint_32, png_get_PLTE,
-    (png_const_structp png_ptr, png_const_infop info_ptr,
-    png_colorp *palette, int *num_palette));
-
-PNG_EXPORT(152, void, png_set_PLTE,
-    (png_structp png_ptr, png_infop info_ptr,
-    png_const_colorp palette, int num_palette));
-
-#ifdef PNG_sBIT_SUPPORTED
-PNG_EXPORT(153, png_uint_32, png_get_sBIT,
-    (png_const_structp png_ptr, png_infop info_ptr,
-    png_color_8p *sig_bit));
-#endif
-
-#ifdef PNG_sBIT_SUPPORTED
-PNG_EXPORT(154, void, png_set_sBIT,
-    (png_structp png_ptr, png_infop info_ptr, png_const_color_8p sig_bit));
-#endif
-
-#ifdef PNG_sRGB_SUPPORTED
-PNG_EXPORT(155, png_uint_32, png_get_sRGB, (png_const_structp png_ptr,
-    png_const_infop info_ptr, int *file_srgb_intent));
-#endif
-
-#ifdef PNG_sRGB_SUPPORTED
-PNG_EXPORT(156, void, png_set_sRGB,
-    (png_structp png_ptr, png_infop info_ptr, int srgb_intent));
-PNG_EXPORT(157, void, png_set_sRGB_gAMA_and_cHRM, (png_structp png_ptr,
-    png_infop info_ptr, int srgb_intent));
-#endif
-
-#ifdef PNG_iCCP_SUPPORTED
-PNG_EXPORT(158, png_uint_32, png_get_iCCP,
-    (png_const_structp png_ptr, png_const_infop info_ptr,
-    png_charpp name, int *compression_type, png_bytepp profile,
-    png_uint_32 *proflen));
-#endif
-
-#ifdef PNG_iCCP_SUPPORTED
-PNG_EXPORT(159, void, png_set_iCCP,
-    (png_structp png_ptr, png_infop info_ptr,
-    png_const_charp name, int compression_type, png_const_bytep profile,
-    png_uint_32 proflen));
-#endif
-
-#ifdef PNG_sPLT_SUPPORTED
-PNG_EXPORT(160, png_uint_32, png_get_sPLT,
-    (png_const_structp png_ptr, png_const_infop info_ptr,
-    png_sPLT_tpp entries));
-#endif
-
-#ifdef PNG_sPLT_SUPPORTED
-PNG_EXPORT(161, void, png_set_sPLT,
-    (png_structp png_ptr, png_infop info_ptr,
-    png_const_sPLT_tp entries, int nentries));
-#endif
-
-#ifdef PNG_TEXT_SUPPORTED
-/* png_get_text also returns the number of text chunks in *num_text */
-PNG_EXPORT(162, png_uint_32, png_get_text,
-    (png_const_structp png_ptr, png_const_infop info_ptr,
-    png_textp *text_ptr, int *num_text));
-#endif
-
-/* Note while png_set_text() will accept a structure whose text,
- * language, and  translated keywords are NULL pointers, the structure
- * returned by png_get_text will always contain regular
- * zero-terminated C strings.  They might be empty strings but
- * they will never be NULL pointers.
- */
-
-#ifdef PNG_TEXT_SUPPORTED
-PNG_EXPORT(163, void, png_set_text,
-    (png_structp png_ptr, png_infop info_ptr,
-    png_const_textp text_ptr, int num_text));
-#endif
-
-#ifdef PNG_tIME_SUPPORTED
-PNG_EXPORT(164, png_uint_32, png_get_tIME,
-    (png_const_structp png_ptr, png_infop info_ptr, png_timep *mod_time));
-#endif
-
-#ifdef PNG_tIME_SUPPORTED
-PNG_EXPORT(165, void, png_set_tIME,
-    (png_structp png_ptr, png_infop info_ptr, png_const_timep mod_time));
-#endif
-
-#ifdef PNG_tRNS_SUPPORTED
-PNG_EXPORT(166, png_uint_32, png_get_tRNS,
-    (png_const_structp png_ptr, png_infop info_ptr,
-    png_bytep *trans_alpha, int *num_trans, png_color_16p *trans_color));
-#endif
-
-#ifdef PNG_tRNS_SUPPORTED
-PNG_EXPORT(167, void, png_set_tRNS,
-    (png_structp png_ptr, png_infop info_ptr,
-    png_const_bytep trans_alpha, int num_trans,
-    png_const_color_16p trans_color));
-#endif
-
-#ifdef PNG_sCAL_SUPPORTED
-PNG_FP_EXPORT(168, png_uint_32, png_get_sCAL,
-    (png_const_structp png_ptr, png_const_infop info_ptr,
-    int *unit, double *width, double *height))
-#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
-/* NOTE: this API is currently implemented using floating point arithmetic,
- * consequently it can only be used on systems with floating point support.
- * In any case the range of values supported by png_fixed_point is small and it
- * is highly recommended that png_get_sCAL_s be used instead.
- */
-PNG_FIXED_EXPORT(214, png_uint_32, png_get_sCAL_fixed,
-    (png_structp png_ptr, png_const_infop info_ptr, int *unit,
-    png_fixed_point *width,
-    png_fixed_point *height))
-#endif
-PNG_EXPORT(169, png_uint_32, png_get_sCAL_s,
-    (png_const_structp png_ptr, png_const_infop info_ptr,
-    int *unit, png_charpp swidth, png_charpp sheight));
-
-PNG_FP_EXPORT(170, void, png_set_sCAL,
-    (png_structp png_ptr, png_infop info_ptr,
-    int unit, double width, double height))
-PNG_FIXED_EXPORT(213, void, png_set_sCAL_fixed, (png_structp png_ptr,
-   png_infop info_ptr, int unit, png_fixed_point width,
-   png_fixed_point height))
-PNG_EXPORT(171, void, png_set_sCAL_s,
-    (png_structp png_ptr, png_infop info_ptr,
-    int unit, png_const_charp swidth, png_const_charp sheight));
-#endif /* PNG_sCAL_SUPPORTED */
-
-#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
-/* Provide a list of chunks and how they are to be handled, if the built-in
-   handling or default unknown chunk handling is not desired.  Any chunks not
-   listed will be handled in the default manner.  The IHDR and IEND chunks
-   must not be listed.  Because this turns off the default handling for chunks
-   that would otherwise be recognized the behavior of libpng transformations may
-   well become incorrect!
-      keep = 0: PNG_HANDLE_CHUNK_AS_DEFAULT: follow default behavior
-           = 1: PNG_HANDLE_CHUNK_NEVER:      do not keep
-           = 2: PNG_HANDLE_CHUNK_IF_SAFE:    keep only if safe-to-copy
-           = 3: PNG_HANDLE_CHUNK_ALWAYS:     keep even if unsafe-to-copy
-*/
-PNG_EXPORT(172, void, png_set_keep_unknown_chunks,
-    (png_structp png_ptr, int keep,
-    png_const_bytep chunk_list, int num_chunks));
-
-/* The handling code is returned; the result is therefore true (non-zero) if
- * special handling is required, false for the default handling.
- */
-PNG_EXPORT(173, int, png_handle_as_unknown, (png_structp png_ptr,
-    png_const_bytep chunk_name));
-#endif
-#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
-PNG_EXPORT(174, void, png_set_unknown_chunks, (png_structp png_ptr,
-    png_infop info_ptr, png_const_unknown_chunkp unknowns,
-    int num_unknowns));
-PNG_EXPORT(175, void, png_set_unknown_chunk_location,
-    (png_structp png_ptr, png_infop info_ptr, int chunk, int location));
-PNG_EXPORT(176, int, png_get_unknown_chunks, (png_const_structp png_ptr,
-    png_const_infop info_ptr, png_unknown_chunkpp entries));
-#endif
-
-/* Png_free_data() will turn off the "valid" flag for anything it frees.
- * If you need to turn it off for a chunk that your application has freed,
- * you can use png_set_invalid(png_ptr, info_ptr, PNG_INFO_CHNK);
- */
-PNG_EXPORT(177, void, png_set_invalid,
-    (png_structp png_ptr, png_infop info_ptr, int mask));
-
-#ifdef PNG_INFO_IMAGE_SUPPORTED
-/* The "params" pointer is currently not used and is for future expansion. */
-PNG_EXPORT(178, void, png_read_png, (png_structp png_ptr, png_infop info_ptr,
-    int transforms, png_voidp params));
-PNG_EXPORT(179, void, png_write_png, (png_structp png_ptr, png_infop info_ptr,
-    int transforms, png_voidp params));
-#endif
-
-PNG_EXPORT(180, png_const_charp, png_get_copyright,
-    (png_const_structp png_ptr));
-PNG_EXPORT(181, png_const_charp, png_get_header_ver,
-    (png_const_structp png_ptr));
-PNG_EXPORT(182, png_const_charp, png_get_header_version,
-    (png_const_structp png_ptr));
-PNG_EXPORT(183, png_const_charp, png_get_libpng_ver,
-    (png_const_structp png_ptr));
-
-#ifdef PNG_MNG_FEATURES_SUPPORTED
-PNG_EXPORT(184, png_uint_32, png_permit_mng_features, (png_structp png_ptr,
-    png_uint_32 mng_features_permitted));
-#endif
-
-/* For use in png_set_keep_unknown, added to version 1.2.6 */
-#define PNG_HANDLE_CHUNK_AS_DEFAULT   0
-#define PNG_HANDLE_CHUNK_NEVER        1
-#define PNG_HANDLE_CHUNK_IF_SAFE      2
-#define PNG_HANDLE_CHUNK_ALWAYS       3
-
-/* Strip the prepended error numbers ("#nnn ") from error and warning
- * messages before passing them to the error or warning handler.
- */
-#ifdef PNG_ERROR_NUMBERS_SUPPORTED
-PNG_EXPORT(185, void, png_set_strip_error_numbers,
-    (png_structp png_ptr,
-    png_uint_32 strip_mode));
-#endif
-
-/* Added in libpng-1.2.6 */
-#ifdef PNG_SET_USER_LIMITS_SUPPORTED
-PNG_EXPORT(186, void, png_set_user_limits, (png_structp png_ptr,
-    png_uint_32 user_width_max, png_uint_32 user_height_max));
-PNG_EXPORT(187, png_uint_32, png_get_user_width_max,
-    (png_const_structp png_ptr));
-PNG_EXPORT(188, png_uint_32, png_get_user_height_max,
-    (png_const_structp png_ptr));
-/* Added in libpng-1.4.0 */
-PNG_EXPORT(189, void, png_set_chunk_cache_max, (png_structp png_ptr,
-    png_uint_32 user_chunk_cache_max));
-PNG_EXPORT(190, png_uint_32, png_get_chunk_cache_max,
-    (png_const_structp png_ptr));
-/* Added in libpng-1.4.1 */
-PNG_EXPORT(191, void, png_set_chunk_malloc_max, (png_structp png_ptr,
-    png_alloc_size_t user_chunk_cache_max));
-PNG_EXPORT(192, png_alloc_size_t, png_get_chunk_malloc_max,
-    (png_const_structp png_ptr));
-#endif
-
-#if defined(PNG_INCH_CONVERSIONS_SUPPORTED)
-PNG_EXPORT(193, png_uint_32, png_get_pixels_per_inch,
-    (png_const_structp png_ptr, png_const_infop info_ptr));
-
-PNG_EXPORT(194, png_uint_32, png_get_x_pixels_per_inch,
-    (png_const_structp png_ptr, png_const_infop info_ptr));
-
-PNG_EXPORT(195, png_uint_32, png_get_y_pixels_per_inch,
-    (png_const_structp png_ptr, png_const_infop info_ptr));
-
-PNG_FP_EXPORT(196, float, png_get_x_offset_inches,
-    (png_const_structp png_ptr, png_const_infop info_ptr))
-#ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */
-PNG_FIXED_EXPORT(211, png_fixed_point, png_get_x_offset_inches_fixed,
-    (png_structp png_ptr, png_const_infop info_ptr))
-#endif
-
-PNG_FP_EXPORT(197, float, png_get_y_offset_inches, (png_const_structp png_ptr,
-    png_const_infop info_ptr))
-#ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */
-PNG_FIXED_EXPORT(212, png_fixed_point, png_get_y_offset_inches_fixed,
-    (png_structp png_ptr, png_const_infop info_ptr))
-#endif
-
-#  ifdef PNG_pHYs_SUPPORTED
-PNG_EXPORT(198, png_uint_32, png_get_pHYs_dpi, (png_const_structp png_ptr,
-    png_const_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y,
-    int *unit_type));
-#  endif /* PNG_pHYs_SUPPORTED */
-#endif  /* PNG_INCH_CONVERSIONS_SUPPORTED */
-
-/* Added in libpng-1.4.0 */
-#ifdef PNG_IO_STATE_SUPPORTED
-PNG_EXPORT(199, png_uint_32, png_get_io_state, (png_structp png_ptr));
-
-PNG_EXPORTA(200, png_const_bytep, png_get_io_chunk_name,
-    (png_structp png_ptr), PNG_DEPRECATED);
-PNG_EXPORT(216, png_uint_32, png_get_io_chunk_type,
-    (png_const_structp png_ptr));
-
-/* The flags returned by png_get_io_state() are the following: */
-#  define PNG_IO_NONE        0x0000   /* no I/O at this moment */
-#  define PNG_IO_READING     0x0001   /* currently reading */
-#  define PNG_IO_WRITING     0x0002   /* currently writing */
-#  define PNG_IO_SIGNATURE   0x0010   /* currently at the file signature */
-#  define PNG_IO_CHUNK_HDR   0x0020   /* currently at the chunk header */
-#  define PNG_IO_CHUNK_DATA  0x0040   /* currently at the chunk data */
-#  define PNG_IO_CHUNK_CRC   0x0080   /* currently at the chunk crc */
-#  define PNG_IO_MASK_OP     0x000f   /* current operation: reading/writing */
-#  define PNG_IO_MASK_LOC    0x00f0   /* current location: sig/hdr/data/crc */
-#endif /* ?PNG_IO_STATE_SUPPORTED */
-
-/* Interlace support.  The following macros are always defined so that if
- * libpng interlace handling is turned off the macros may be used to handle
- * interlaced images within the application.
- */
-#define PNG_INTERLACE_ADAM7_PASSES 7
-
-/* Two macros to return the first row and first column of the original,
- * full, image which appears in a given pass.  'pass' is in the range 0
- * to 6 and the result is in the range 0 to 7.
- */
-#define PNG_PASS_START_ROW(pass) (((1&~(pass))<<(3-((pass)>>1)))&7)
-#define PNG_PASS_START_COL(pass) (((1& (pass))<<(3-(((pass)+1)>>1)))&7)
-
-/* A macro to return the offset between pixels in the output row for a pair of
- * pixels in the input - effectively the inverse of the 'COL_SHIFT' macro that
- * follows.  Note that ROW_OFFSET is the offset from one row to the next whereas
- * COL_OFFSET is from one column to the next, within a row.
- */
-#define PNG_PASS_ROW_OFFSET(pass) ((pass)>2?(8>>(((pass)-1)>>1)):8)
-#define PNG_PASS_COL_OFFSET(pass) (1<<((7-(pass))>>1))
-
-/* Two macros to help evaluate the number of rows or columns in each
- * pass.  This is expressed as a shift - effectively log2 of the number or
- * rows or columns in each 8x8 tile of the original image.
- */
-#define PNG_PASS_ROW_SHIFT(pass) ((pass)>2?(8-(pass))>>1:3)
-#define PNG_PASS_COL_SHIFT(pass) ((pass)>1?(7-(pass))>>1:3)
-
-/* Hence two macros to determine the number of rows or columns in a given
- * pass of an image given its height or width.  In fact these macros may
- * return non-zero even though the sub-image is empty, because the other
- * dimension may be empty for a small image.
- */
-#define PNG_PASS_ROWS(height, pass) (((height)+(((1<<PNG_PASS_ROW_SHIFT(pass))\
-   -1)-PNG_PASS_START_ROW(pass)))>>PNG_PASS_ROW_SHIFT(pass))
-#define PNG_PASS_COLS(width, pass) (((width)+(((1<<PNG_PASS_COL_SHIFT(pass))\
-   -1)-PNG_PASS_START_COL(pass)))>>PNG_PASS_COL_SHIFT(pass))
-
-/* For the reader row callbacks (both progressive and sequential) it is
- * necessary to find the row in the output image given a row in an interlaced
- * image, so two more macros:
- */
-#define PNG_ROW_FROM_PASS_ROW(yIn, pass) \
-   (((yIn)<<PNG_PASS_ROW_SHIFT(pass))+PNG_PASS_START_ROW(pass))
-#define PNG_COL_FROM_PASS_COL(xIn, pass) \
-   (((xIn)<<PNG_PASS_COL_SHIFT(pass))+PNG_PASS_START_COL(pass))
-
-/* Two macros which return a boolean (0 or 1) saying whether the given row
- * or column is in a particular pass.  These use a common utility macro that
- * returns a mask for a given pass - the offset 'off' selects the row or
- * column version.  The mask has the appropriate bit set for each column in
- * the tile.
- */
-#define PNG_PASS_MASK(pass,off) ( \
-   ((0x110145AF>>(((7-(off))-(pass))<<2)) & 0xF) | \
-   ((0x01145AF0>>(((7-(off))-(pass))<<2)) & 0xF0))
-
-#define PNG_ROW_IN_INTERLACE_PASS(y, pass) \
-   ((PNG_PASS_MASK(pass,0) >> ((y)&7)) & 1)
-#define PNG_COL_IN_INTERLACE_PASS(x, pass) \
-   ((PNG_PASS_MASK(pass,1) >> ((x)&7)) & 1)
-
-#ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED
-/* With these routines we avoid an integer divide, which will be slower on
- * most machines.  However, it does take more operations than the corresponding
- * divide method, so it may be slower on a few RISC systems.  There are two
- * shifts (by 8 or 16 bits) and an addition, versus a single integer divide.
- *
- * Note that the rounding factors are NOT supposed to be the same!  128 and
- * 32768 are correct for the NODIV code; 127 and 32767 are correct for the
- * standard method.
- *
- * [Optimized code by Greg Roelofs and Mark Adler...blame us for bugs. :-) ]
- */
-
- /* fg and bg should be in `gamma 1.0' space; alpha is the opacity */
-
-#  define png_composite(composite, fg, alpha, bg)         \
-     { png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) \
-           * (png_uint_16)(alpha)                         \
-           + (png_uint_16)(bg)*(png_uint_16)(255          \
-           - (png_uint_16)(alpha)) + 128);                \
-       (composite) = (png_byte)((temp + (temp >> 8)) >> 8); }
-
-#  define png_composite_16(composite, fg, alpha, bg)       \
-     { png_uint_32 temp = (png_uint_32)((png_uint_32)(fg)  \
-           * (png_uint_32)(alpha)                          \
-           + (png_uint_32)(bg)*(65535                      \
-           - (png_uint_32)(alpha)) + 32768);               \
-       (composite) = (png_uint_16)((temp + (temp >> 16)) >> 16); }
-
-#else  /* Standard method using integer division */
-
-#  define png_composite(composite, fg, alpha, bg)                          \
-     (composite) = (png_byte)(((png_uint_16)(fg) * (png_uint_16)(alpha) +  \
-     (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) +       \
-     127) / 255)
-
-#  define png_composite_16(composite, fg, alpha, bg)                         \
-     (composite) = (png_uint_16)(((png_uint_32)(fg) * (png_uint_32)(alpha) + \
-     (png_uint_32)(bg)*(png_uint_32)(65535 - (png_uint_32)(alpha)) +         \
-     32767) / 65535)
-#endif /* PNG_READ_COMPOSITE_NODIV_SUPPORTED */
-
-#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED
-PNG_EXPORT(201, png_uint_32, png_get_uint_32, (png_const_bytep buf));
-PNG_EXPORT(202, png_uint_16, png_get_uint_16, (png_const_bytep buf));
-PNG_EXPORT(203, png_int_32, png_get_int_32, (png_const_bytep buf));
-#endif
-
-PNG_EXPORT(204, png_uint_32, png_get_uint_31, (png_structp png_ptr,
-    png_const_bytep buf));
-/* No png_get_int_16 -- may be added if there's a real need for it. */
-
-/* Place a 32-bit number into a buffer in PNG byte order (big-endian). */
-#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED
-PNG_EXPORT(205, void, png_save_uint_32, (png_bytep buf, png_uint_32 i));
-#endif
-#ifdef PNG_SAVE_INT_32_SUPPORTED
-PNG_EXPORT(206, void, png_save_int_32, (png_bytep buf, png_int_32 i));
-#endif
-
-/* Place a 16-bit number into a buffer in PNG byte order.
- * The parameter is declared unsigned int, not png_uint_16,
- * just to avoid potential problems on pre-ANSI C compilers.
- */
-#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED
-PNG_EXPORT(207, void, png_save_uint_16, (png_bytep buf, unsigned int i));
-/* No png_save_int_16 -- may be added if there's a real need for it. */
-#endif
-
-#ifdef PNG_USE_READ_MACROS
-/* Inline macros to do direct reads of bytes from the input buffer.
- * The png_get_int_32() routine assumes we are using two's complement
- * format for negative values, which is almost certainly true.
- */
-#  define png_get_uint_32(buf) \
-     (((png_uint_32)(*(buf)) << 24) + \
-      ((png_uint_32)(*((buf) + 1)) << 16) + \
-      ((png_uint_32)(*((buf) + 2)) << 8) + \
-      ((png_uint_32)(*((buf) + 3))))
-
-   /* From libpng-1.4.0 until 1.4.4, the png_get_uint_16 macro (but not the
-    * function) incorrectly returned a value of type png_uint_32.
-    */
-#  define png_get_uint_16(buf) \
-     ((png_uint_16) \
-      (((unsigned int)(*(buf)) << 8) + \
-       ((unsigned int)(*((buf) + 1)))))
-
-#  define png_get_int_32(buf) \
-     ((png_int_32)((*(buf) & 0x80) \
-      ? -((png_int_32)((png_get_uint_32(buf) ^ 0xffffffffL) + 1)) \
-      : (png_int_32)png_get_uint_32(buf)))
-#endif
-
-#if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \
-    defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED)
-PNG_EXPORT(234, void, png_set_check_for_invalid_index, (png_structp png_ptr,
-    int allowed));
-#endif
-
-/* Maintainer: Put new public prototypes here ^, in libpng.3, and project
- * defs
- */
-
-/* The last ordinal number (this is the *last* one already used; the next
- * one to use is one more than this.)  Maintainer, remember to add an entry to
- * scripts/symbols.def as well.
- */
-#ifdef PNG_EXPORT_LAST_ORDINAL
-  PNG_EXPORT_LAST_ORDINAL(234);
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* PNG_VERSION_INFO_ONLY */
-/* Do not put anything past this line */
-#endif /* PNG_H */
+
+/* png.h - header file for PNG reference library
+ *
+ * libpng version 1.6.16, December 22, 2014
+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license (See LICENSE, below)
+ *
+ * Authors and maintainers:
+ *   libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
+ *   libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger
+ *   libpng versions 0.97, January 1998, through 1.6.16, December 22, 2014: Glenn
+ *   See also "Contributing Authors", below.
+ *
+ * Note about libpng version numbers:
+ *
+ *   Due to various miscommunications, unforeseen code incompatibilities
+ *   and occasional factors outside the authors' control, version numbering
+ *   on the library has not always been consistent and straightforward.
+ *   The following table summarizes matters since version 0.89c, which was
+ *   the first widely used release:
+ *
+ *    source                 png.h  png.h  shared-lib
+ *    version                string   int  version
+ *    -------                ------ -----  ----------
+ *    0.89c "1.0 beta 3"     0.89      89  1.0.89
+ *    0.90  "1.0 beta 4"     0.90      90  0.90  [should have been 2.0.90]
+ *    0.95  "1.0 beta 5"     0.95      95  0.95  [should have been 2.0.95]
+ *    0.96  "1.0 beta 6"     0.96      96  0.96  [should have been 2.0.96]
+ *    0.97b "1.00.97 beta 7" 1.00.97   97  1.0.1 [should have been 2.0.97]
+ *    0.97c                  0.97      97  2.0.97
+ *    0.98                   0.98      98  2.0.98
+ *    0.99                   0.99      98  2.0.99
+ *    0.99a-m                0.99      99  2.0.99
+ *    1.00                   1.00     100  2.1.0 [100 should be 10000]
+ *    1.0.0      (from here on, the   100  2.1.0 [100 should be 10000]
+ *    1.0.1       png.h string is   10001  2.1.0
+ *    1.0.1a-e    identical to the  10002  from here on, the shared library
+ *    1.0.2       source version)   10002  is 2.V where V is the source code
+ *    1.0.2a-b                      10003  version, except as noted.
+ *    1.0.3                         10003
+ *    1.0.3a-d                      10004
+ *    1.0.4                         10004
+ *    1.0.4a-f                      10005
+ *    1.0.5 (+ 2 patches)           10005
+ *    1.0.5a-d                      10006
+ *    1.0.5e-r                      10100 (not source compatible)
+ *    1.0.5s-v                      10006 (not binary compatible)
+ *    1.0.6 (+ 3 patches)           10006 (still binary incompatible)
+ *    1.0.6d-f                      10007 (still binary incompatible)
+ *    1.0.6g                        10007
+ *    1.0.6h                        10007  10.6h (testing xy.z so-numbering)
+ *    1.0.6i                        10007  10.6i
+ *    1.0.6j                        10007  2.1.0.6j (incompatible with 1.0.0)
+ *    1.0.7beta11-14        DLLNUM  10007  2.1.0.7beta11-14 (binary compatible)
+ *    1.0.7beta15-18           1    10007  2.1.0.7beta15-18 (binary compatible)
+ *    1.0.7rc1-2               1    10007  2.1.0.7rc1-2 (binary compatible)
+ *    1.0.7                    1    10007  (still compatible)
+ *    1.0.8beta1-4             1    10008  2.1.0.8beta1-4
+ *    1.0.8rc1                 1    10008  2.1.0.8rc1
+ *    1.0.8                    1    10008  2.1.0.8
+ *    1.0.9beta1-6             1    10009  2.1.0.9beta1-6
+ *    1.0.9rc1                 1    10009  2.1.0.9rc1
+ *    1.0.9beta7-10            1    10009  2.1.0.9beta7-10
+ *    1.0.9rc2                 1    10009  2.1.0.9rc2
+ *    1.0.9                    1    10009  2.1.0.9
+ *    1.0.10beta1              1    10010  2.1.0.10beta1
+ *    1.0.10rc1                1    10010  2.1.0.10rc1
+ *    1.0.10                   1    10010  2.1.0.10
+ *    1.0.11beta1-3            1    10011  2.1.0.11beta1-3
+ *    1.0.11rc1                1    10011  2.1.0.11rc1
+ *    1.0.11                   1    10011  2.1.0.11
+ *    1.0.12beta1-2            2    10012  2.1.0.12beta1-2
+ *    1.0.12rc1                2    10012  2.1.0.12rc1
+ *    1.0.12                   2    10012  2.1.0.12
+ *    1.1.0a-f                 -    10100  2.1.1.0a-f (branch abandoned)
+ *    1.2.0beta1-2             2    10200  2.1.2.0beta1-2
+ *    1.2.0beta3-5             3    10200  3.1.2.0beta3-5
+ *    1.2.0rc1                 3    10200  3.1.2.0rc1
+ *    1.2.0                    3    10200  3.1.2.0
+ *    1.2.1beta1-4             3    10201  3.1.2.1beta1-4
+ *    1.2.1rc1-2               3    10201  3.1.2.1rc1-2
+ *    1.2.1                    3    10201  3.1.2.1
+ *    1.2.2beta1-6            12    10202  12.so.0.1.2.2beta1-6
+ *    1.0.13beta1             10    10013  10.so.0.1.0.13beta1
+ *    1.0.13rc1               10    10013  10.so.0.1.0.13rc1
+ *    1.2.2rc1                12    10202  12.so.0.1.2.2rc1
+ *    1.0.13                  10    10013  10.so.0.1.0.13
+ *    1.2.2                   12    10202  12.so.0.1.2.2
+ *    1.2.3rc1-6              12    10203  12.so.0.1.2.3rc1-6
+ *    1.2.3                   12    10203  12.so.0.1.2.3
+ *    1.2.4beta1-3            13    10204  12.so.0.1.2.4beta1-3
+ *    1.0.14rc1               13    10014  10.so.0.1.0.14rc1
+ *    1.2.4rc1                13    10204  12.so.0.1.2.4rc1
+ *    1.0.14                  10    10014  10.so.0.1.0.14
+ *    1.2.4                   13    10204  12.so.0.1.2.4
+ *    1.2.5beta1-2            13    10205  12.so.0.1.2.5beta1-2
+ *    1.0.15rc1-3             10    10015  10.so.0.1.0.15rc1-3
+ *    1.2.5rc1-3              13    10205  12.so.0.1.2.5rc1-3
+ *    1.0.15                  10    10015  10.so.0.1.0.15
+ *    1.2.5                   13    10205  12.so.0.1.2.5
+ *    1.2.6beta1-4            13    10206  12.so.0.1.2.6beta1-4
+ *    1.0.16                  10    10016  10.so.0.1.0.16
+ *    1.2.6                   13    10206  12.so.0.1.2.6
+ *    1.2.7beta1-2            13    10207  12.so.0.1.2.7beta1-2
+ *    1.0.17rc1               10    10017  12.so.0.1.0.17rc1
+ *    1.2.7rc1                13    10207  12.so.0.1.2.7rc1
+ *    1.0.17                  10    10017  12.so.0.1.0.17
+ *    1.2.7                   13    10207  12.so.0.1.2.7
+ *    1.2.8beta1-5            13    10208  12.so.0.1.2.8beta1-5
+ *    1.0.18rc1-5             10    10018  12.so.0.1.0.18rc1-5
+ *    1.2.8rc1-5              13    10208  12.so.0.1.2.8rc1-5
+ *    1.0.18                  10    10018  12.so.0.1.0.18
+ *    1.2.8                   13    10208  12.so.0.1.2.8
+ *    1.2.9beta1-3            13    10209  12.so.0.1.2.9beta1-3
+ *    1.2.9beta4-11           13    10209  12.so.0.9[.0]
+ *    1.2.9rc1                13    10209  12.so.0.9[.0]
+ *    1.2.9                   13    10209  12.so.0.9[.0]
+ *    1.2.10beta1-7           13    10210  12.so.0.10[.0]
+ *    1.2.10rc1-2             13    10210  12.so.0.10[.0]
+ *    1.2.10                  13    10210  12.so.0.10[.0]
+ *    1.4.0beta1-5            14    10400  14.so.0.0[.0]
+ *    1.2.11beta1-4           13    10211  12.so.0.11[.0]
+ *    1.4.0beta7-8            14    10400  14.so.0.0[.0]
+ *    1.2.11                  13    10211  12.so.0.11[.0]
+ *    1.2.12                  13    10212  12.so.0.12[.0]
+ *    1.4.0beta9-14           14    10400  14.so.0.0[.0]
+ *    1.2.13                  13    10213  12.so.0.13[.0]
+ *    1.4.0beta15-36          14    10400  14.so.0.0[.0]
+ *    1.4.0beta37-87          14    10400  14.so.14.0[.0]
+ *    1.4.0rc01               14    10400  14.so.14.0[.0]
+ *    1.4.0beta88-109         14    10400  14.so.14.0[.0]
+ *    1.4.0rc02-08            14    10400  14.so.14.0[.0]
+ *    1.4.0                   14    10400  14.so.14.0[.0]
+ *    1.4.1beta01-03          14    10401  14.so.14.1[.0]
+ *    1.4.1rc01               14    10401  14.so.14.1[.0]
+ *    1.4.1beta04-12          14    10401  14.so.14.1[.0]
+ *    1.4.1                   14    10401  14.so.14.1[.0]
+ *    1.4.2                   14    10402  14.so.14.2[.0]
+ *    1.4.3                   14    10403  14.so.14.3[.0]
+ *    1.4.4                   14    10404  14.so.14.4[.0]
+ *    1.5.0beta01-58          15    10500  15.so.15.0[.0]
+ *    1.5.0rc01-07            15    10500  15.so.15.0[.0]
+ *    1.5.0                   15    10500  15.so.15.0[.0]
+ *    1.5.1beta01-11          15    10501  15.so.15.1[.0]
+ *    1.5.1rc01-02            15    10501  15.so.15.1[.0]
+ *    1.5.1                   15    10501  15.so.15.1[.0]
+ *    1.5.2beta01-03          15    10502  15.so.15.2[.0]
+ *    1.5.2rc01-03            15    10502  15.so.15.2[.0]
+ *    1.5.2                   15    10502  15.so.15.2[.0]
+ *    1.5.3beta01-10          15    10503  15.so.15.3[.0]
+ *    1.5.3rc01-02            15    10503  15.so.15.3[.0]
+ *    1.5.3beta11             15    10503  15.so.15.3[.0]
+ *    1.5.3 [omitted]
+ *    1.5.4beta01-08          15    10504  15.so.15.4[.0]
+ *    1.5.4rc01               15    10504  15.so.15.4[.0]
+ *    1.5.4                   15    10504  15.so.15.4[.0]
+ *    1.5.5beta01-08          15    10505  15.so.15.5[.0]
+ *    1.5.5rc01               15    10505  15.so.15.5[.0]
+ *    1.5.5                   15    10505  15.so.15.5[.0]
+ *    1.5.6beta01-07          15    10506  15.so.15.6[.0]
+ *    1.5.6rc01-03            15    10506  15.so.15.6[.0]
+ *    1.5.6                   15    10506  15.so.15.6[.0]
+ *    1.5.7beta01-05          15    10507  15.so.15.7[.0]
+ *    1.5.7rc01-03            15    10507  15.so.15.7[.0]
+ *    1.5.7                   15    10507  15.so.15.7[.0]
+ *    1.6.0beta01-40          16    10600  16.so.16.0[.0]
+ *    1.6.0rc01-08            16    10600  16.so.16.0[.0]
+ *    1.6.0                   16    10600  16.so.16.0[.0]
+ *    1.6.1beta01-09          16    10601  16.so.16.1[.0]
+ *    1.6.1rc01               16    10601  16.so.16.1[.0]
+ *    1.6.1                   16    10601  16.so.16.1[.0]
+ *    1.6.2beta01             16    10602  16.so.16.2[.0]
+ *    1.6.2rc01-06            16    10602  16.so.16.2[.0]
+ *    1.6.2                   16    10602  16.so.16.2[.0]
+ *    1.6.3beta01-11          16    10603  16.so.16.3[.0]
+ *    1.6.3rc01               16    10603  16.so.16.3[.0]
+ *    1.6.3                   16    10603  16.so.16.3[.0]
+ *    1.6.4beta01-02          16    10604  16.so.16.4[.0]
+ *    1.6.4rc01               16    10604  16.so.16.4[.0]
+ *    1.6.4                   16    10604  16.so.16.4[.0]
+ *    1.6.5                   16    10605  16.so.16.5[.0]
+ *    1.6.6                   16    10606  16.so.16.6[.0]
+ *    1.6.7beta01-04          16    10607  16.so.16.7[.0]
+ *    1.6.7rc01-03            16    10607  16.so.16.7[.0]
+ *    1.6.7                   16    10607  16.so.16.7[.0]
+ *    1.6.8beta01-02          16    10608  16.so.16.8[.0]
+ *    1.6.8rc01-02            16    10608  16.so.16.8[.0]
+ *    1.6.8                   16    10608  16.so.16.8[.0]
+ *    1.6.9beta01-04          16    10609  16.so.16.9[.0]
+ *    1.6.9rc01-02            16    10609  16.so.16.9[.0]
+ *    1.6.9                   16    10609  16.so.16.9[.0]
+ *    1.6.10beta01-03         16    10610  16.so.16.10[.0]
+ *    1.6.10rc01-03           16    10610  16.so.16.10[.0]
+ *    1.6.10                  16    10610  16.so.16.10[.0]
+ *    1.6.11beta01-06         16    10611  16.so.16.11[.0]
+ *    1.6.11rc01-02           16    10611  16.so.16.11[.0]
+ *    1.6.11                  16    10611  16.so.16.11[.0]
+ *    1.6.12rc01-03           16    10612  16.so.16.12[.0]
+ *    1.6.12                  16    10612  16.so.16.12[.0]
+ *    1.6.13beta01-04         16    10613  16.so.16.13[.0]
+ *    1.6.13rc01-02           16    10613  16.so.16.13[.0]
+ *    1.6.13                  16    10613  16.so.16.13[.0]
+ *    1.6.14beta01-07         16    10614  16.so.16.14[.0]
+ *    1.6.14rc01-02           16    10614  16.so.16.14[.0]
+ *    1.6.14                  16    10614  16.so.16.14[.0]
+ *    1.6.15beta01-08         16    10615  16.so.16.15[.0]
+ *    1.6.15rc01-03           16    10615  16.so.16.15[.0]
+ *    1.6.15                  16    10615  16.so.16.15[.0]
+ *    1.6.16beta01-03         16    10616  16.so.16.16[.0]
+ *    1.6.16rc01-02           16    10616  16.so.16.16[.0]
+ *    1.6.16                  16    10616  16.so.16.16[.0]
+ *
+ *   Henceforth the source version will match the shared-library major
+ *   and minor numbers; the shared-library major version number will be
+ *   used for changes in backward compatibility, as it is intended.  The
+ *   PNG_LIBPNG_VER macro, which is not used within libpng but is available
+ *   for applications, is an unsigned integer of the form xyyzz corresponding
+ *   to the source version x.y.z (leading zeros in y and z).  Beta versions
+ *   were given the previous public release number plus a letter, until
+ *   version 1.0.6j; from then on they were given the upcoming public
+ *   release number plus "betaNN" or "rcNN".
+ *
+ *   Binary incompatibility exists only when applications make direct access
+ *   to the info_ptr or png_ptr members through png.h, and the compiled
+ *   application is loaded with a different version of the library.
+ *
+ *   DLLNUM will change each time there are forward or backward changes
+ *   in binary compatibility (e.g., when a new feature is added).
+ *
+ * See libpng-manual.txt or libpng.3 for more information.  The PNG
+ * specification is available as a W3C Recommendation and as an ISO
+ * Specification, <http://www.w3.org/TR/2003/REC-PNG-20031110/
+ */
+
+/*
+ * COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
+ *
+ * If you modify libpng you may insert additional notices immediately following
+ * this sentence.
+ *
+ * This code is released under the libpng license.
+ *
+ * libpng versions 1.2.6, August 15, 2004, through 1.6.16, December 22, 2014, are
+ * Copyright (c) 2004, 2006-2014 Glenn Randers-Pehrson, and are
+ * distributed according to the same disclaimer and license as libpng-1.2.5
+ * with the following individual added to the list of Contributing Authors:
+ *
+ *    Cosmin Truta
+ *
+ * libpng versions 1.0.7, July 1, 2000, through 1.2.5, October 3, 2002, are
+ * Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are
+ * distributed according to the same disclaimer and license as libpng-1.0.6
+ * with the following individuals added to the list of Contributing Authors:
+ *
+ *    Simon-Pierre Cadieux
+ *    Eric S. Raymond
+ *    Gilles Vollant
+ *
+ * and with the following additions to the disclaimer:
+ *
+ *    There is no warranty against interference with your enjoyment of the
+ *    library or against infringement.  There is no warranty that our
+ *    efforts or the library will fulfill any of your particular purposes
+ *    or needs.  This library is provided with all faults, and the entire
+ *    risk of satisfactory quality, performance, accuracy, and effort is with
+ *    the user.
+ *
+ * libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
+ * Copyright (c) 1998, 1999, 2000 Glenn Randers-Pehrson, and are
+ * distributed according to the same disclaimer and license as libpng-0.96,
+ * with the following individuals added to the list of Contributing Authors:
+ *
+ *    Tom Lane
+ *    Glenn Randers-Pehrson
+ *    Willem van Schaik
+ *
+ * libpng versions 0.89, June 1996, through 0.96, May 1997, are
+ * Copyright (c) 1996, 1997 Andreas Dilger
+ * Distributed according to the same disclaimer and license as libpng-0.88,
+ * with the following individuals added to the list of Contributing Authors:
+ *
+ *    John Bowler
+ *    Kevin Bracey
+ *    Sam Bushell
+ *    Magnus Holmgren
+ *    Greg Roelofs
+ *    Tom Tanner
+ *
+ * libpng versions 0.5, May 1995, through 0.88, January 1996, are
+ * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+ *
+ * For the purposes of this copyright and license, "Contributing Authors"
+ * is defined as the following set of individuals:
+ *
+ *    Andreas Dilger
+ *    Dave Martindale
+ *    Guy Eric Schalnat
+ *    Paul Schmidt
+ *    Tim Wegner
+ *
+ * The PNG Reference Library is supplied "AS IS".  The Contributing Authors
+ * and Group 42, Inc. disclaim all warranties, expressed or implied,
+ * including, without limitation, the warranties of merchantability and of
+ * fitness for any purpose.  The Contributing Authors and Group 42, Inc.
+ * assume no liability for direct, indirect, incidental, special, exemplary,
+ * or consequential damages, which may result from the use of the PNG
+ * Reference Library, even if advised of the possibility of such damage.
+ *
+ * Permission is hereby granted to use, copy, modify, and distribute this
+ * source code, or portions hereof, for any purpose, without fee, subject
+ * to the following restrictions:
+ *
+ *   1. The origin of this source code must not be misrepresented.
+ *
+ *   2. Altered versions must be plainly marked as such and must not
+ *      be misrepresented as being the original source.
+ *
+ *   3. This Copyright notice may not be removed or altered from
+ *      any source or altered source distribution.
+ *
+ * The Contributing Authors and Group 42, Inc. specifically permit, without
+ * fee, and encourage the use of this source code as a component to
+ * supporting the PNG file format in commercial products.  If you use this
+ * source code in a product, acknowledgment is not required but would be
+ * appreciated.
+ */
+
+/*
+ * A "png_get_copyright" function is available, for convenient use in "about"
+ * boxes and the like:
+ *
+ *     printf("%s", png_get_copyright(NULL));
+ *
+ * Also, the PNG logo (in PNG format, of course) is supplied in the
+ * files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
+ */
+
+/*
+ * Libpng is OSI Certified Open Source Software.  OSI Certified is a
+ * certification mark of the Open Source Initiative.
+ */
+
+/*
+ * The contributing authors would like to thank all those who helped
+ * with testing, bug fixes, and patience.  This wouldn't have been
+ * possible without all of you.
+ *
+ * Thanks to Frank J. T. Wojcik for helping with the documentation.
+ */
+
+/*
+ * Y2K compliance in libpng:
+ * =========================
+ *
+ *    December 22, 2014
+ *
+ *    Since the PNG Development group is an ad-hoc body, we can't make
+ *    an official declaration.
+ *
+ *    This is your unofficial assurance that libpng from version 0.71 and
+ *    upward through 1.6.16 are Y2K compliant.  It is my belief that
+ *    earlier versions were also Y2K compliant.
+ *
+ *    Libpng only has two year fields.  One is a 2-byte unsigned integer
+ *    that will hold years up to 65535.  The other, which is deprecated,
+ *    holds the date in text format, and will hold years up to 9999.
+ *
+ *    The integer is
+ *        "png_uint_16 year" in png_time_struct.
+ *
+ *    The string is
+ *        "char time_buffer[29]" in png_struct.  This is no longer used
+ *    in libpng-1.6.x and will be removed from libpng-1.7.0.
+ *
+ *    There are seven time-related functions:
+ *        png.c: png_convert_to_rfc_1123_buffer() in png.c
+ *          (formerly png_convert_to_rfc_1123() prior to libpng-1.5.x and
+ *          png_convert_to_rfc_1152() in error prior to libpng-0.98)
+ *        png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.c
+ *        png_convert_from_time_t() in pngwrite.c
+ *        png_get_tIME() in pngget.c
+ *        png_handle_tIME() in pngrutil.c, called in pngread.c
+ *        png_set_tIME() in pngset.c
+ *        png_write_tIME() in pngwutil.c, called in pngwrite.c
+ *
+ *    All handle dates properly in a Y2K environment.  The
+ *    png_convert_from_time_t() function calls gmtime() to convert from system
+ *    clock time, which returns (year - 1900), which we properly convert to
+ *    the full 4-digit year.  There is a possibility that libpng applications
+ *    are not passing 4-digit years into the png_convert_to_rfc_1123_buffer()
+ *    function, or that they are incorrectly passing only a 2-digit year
+ *    instead of "year - 1900" into the png_convert_from_struct_tm() function,
+ *    but this is not under our control.  The libpng documentation has always
+ *    stated that it works with 4-digit years, and the APIs have been
+ *    documented as such.
+ *
+ *    The tIME chunk itself is also Y2K compliant.  It uses a 2-byte unsigned
+ *    integer to hold the year, and can hold years as large as 65535.
+ *
+ *    zlib, upon which libpng depends, is also Y2K compliant.  It contains
+ *    no date-related code.
+ *
+ *       Glenn Randers-Pehrson
+ *       libpng maintainer
+ *       PNG Development Group
+ */
+
+#ifndef PNG_H
+#define PNG_H
+
+/* This is not the place to learn how to use libpng. The file libpng-manual.txt
+ * describes how to use libpng, and the file example.c summarizes it
+ * with some code on which to build.  This file is useful for looking
+ * at the actual function definitions and structure components.  If that
+ * file has been stripped from your copy of libpng, you can find it at
+ * <http://www.libpng.org/pub/png/libpng-manual.txt>
+ *
+ * If you just need to read a PNG file and don't want to read the documentation
+ * skip to the end of this file and read the section entitled 'simplified API'.
+ */
+
+/* Version information for png.h - this should match the version in png.c */
+#define PNG_LIBPNG_VER_STRING "1.6.16"
+#define PNG_HEADER_VERSION_STRING \
+     " libpng version 1.6.16 - December 22, 2014\n"
+
+#define PNG_LIBPNG_VER_SONUM   16
+#define PNG_LIBPNG_VER_DLLNUM  16
+
+/* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
+#define PNG_LIBPNG_VER_MAJOR   1
+#define PNG_LIBPNG_VER_MINOR   6
+#define PNG_LIBPNG_VER_RELEASE 16
+
+/* This should match the numeric part of the final component of
+ * PNG_LIBPNG_VER_STRING, omitting any leading zero:
+ */
+
+#define PNG_LIBPNG_VER_BUILD  0
+
+/* Release Status */
+#define PNG_LIBPNG_BUILD_ALPHA    1
+#define PNG_LIBPNG_BUILD_BETA     2
+#define PNG_LIBPNG_BUILD_RC       3
+#define PNG_LIBPNG_BUILD_STABLE   4
+#define PNG_LIBPNG_BUILD_RELEASE_STATUS_MASK 7
+
+/* Release-Specific Flags */
+#define PNG_LIBPNG_BUILD_PATCH    8 /* Can be OR'ed with
+                                       PNG_LIBPNG_BUILD_STABLE only */
+#define PNG_LIBPNG_BUILD_PRIVATE 16 /* Cannot be OR'ed with
+                                       PNG_LIBPNG_BUILD_SPECIAL */
+#define PNG_LIBPNG_BUILD_SPECIAL 32 /* Cannot be OR'ed with
+                                       PNG_LIBPNG_BUILD_PRIVATE */
+
+#define PNG_LIBPNG_BUILD_BASE_TYPE PNG_LIBPNG_BUILD_STABLE
+
+/* Careful here.  At one time, Guy wanted to use 082, but that would be octal.
+ * We must not include leading zeros.
+ * Versions 0.7 through 1.0.0 were in the range 0 to 100 here (only
+ * version 1.0.0 was mis-numbered 100 instead of 10000).  From
+ * version 1.0.1 it's    xxyyzz, where x=major, y=minor, z=release
+ */
+#define PNG_LIBPNG_VER 10616 /* 1.6.16 */
+
+/* Library configuration: these options cannot be changed after
+ * the library has been built.
+ */
+#ifndef PNGLCONF_H
+    /* If pnglibconf.h is missing, you can
+     * copy scripts/pnglibconf.h.prebuilt to pnglibconf.h
+     */
+#   include "pnglibconf.h"
+#endif
+
+#ifndef PNG_VERSION_INFO_ONLY
+   /* Machine specific configuration. */
+#  include "pngconf.h"
+#endif
+
+/*
+ * Added at libpng-1.2.8
+ *
+ * Ref MSDN: Private as priority over Special
+ * VS_FF_PRIVATEBUILD File *was not* built using standard release
+ * procedures. If this value is given, the StringFileInfo block must
+ * contain a PrivateBuild string.
+ *
+ * VS_FF_SPECIALBUILD File *was* built by the original company using
+ * standard release procedures but is a variation of the standard
+ * file of the same version number. If this value is given, the
+ * StringFileInfo block must contain a SpecialBuild string.
+ */
+
+#ifdef PNG_USER_PRIVATEBUILD /* From pnglibconf.h */
+#  define PNG_LIBPNG_BUILD_TYPE \
+       (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_PRIVATE)
+#else
+#  ifdef PNG_LIBPNG_SPECIALBUILD
+#    define PNG_LIBPNG_BUILD_TYPE \
+         (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_SPECIAL)
+#  else
+#    define PNG_LIBPNG_BUILD_TYPE (PNG_LIBPNG_BUILD_BASE_TYPE)
+#  endif
+#endif
+
+#ifndef PNG_VERSION_INFO_ONLY
+
+/* Inhibit C++ name-mangling for libpng functions but not for system calls. */
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Version information for C files, stored in png.c.  This had better match
+ * the version above.
+ */
+#define png_libpng_ver png_get_header_ver(NULL)
+
+/* This file is arranged in several sections:
+ *
+ * 1. Any configuration options that can be specified by for the application
+ *    code when it is built.  (Build time configuration is in pnglibconf.h)
+ * 2. Type definitions (base types are defined in pngconf.h), structure
+ *    definitions.
+ * 3. Exported library functions.
+ * 4. Simplified API.
+ *
+ * The library source code has additional files (principally pngpriv.h) that
+ * allow configuration of the library.
+ */
+/* Section 1: run time configuration
+ * See pnglibconf.h for build time configuration
+ *
+ * Run time configuration allows the application to choose between
+ * implementations of certain arithmetic APIs.  The default is set
+ * at build time and recorded in pnglibconf.h, but it is safe to
+ * override these (and only these) settings.  Note that this won't
+ * change what the library does, only application code, and the
+ * settings can (and probably should) be made on a per-file basis
+ * by setting the #defines before including png.h
+ *
+ * Use macros to read integers from PNG data or use the exported
+ * functions?
+ *   PNG_USE_READ_MACROS: use the macros (see below)  Note that
+ *     the macros evaluate their argument multiple times.
+ *   PNG_NO_USE_READ_MACROS: call the relevant library function.
+ *
+ * Use the alternative algorithm for compositing alpha samples that
+ * does not use division?
+ *   PNG_READ_COMPOSITE_NODIV_SUPPORTED: use the 'no division'
+ *      algorithm.
+ *   PNG_NO_READ_COMPOSITE_NODIV: use the 'division' algorithm.
+ *
+ * How to handle benign errors if PNG_ALLOW_BENIGN_ERRORS is
+ * false?
+ *   PNG_ALLOW_BENIGN_ERRORS: map calls to the benign error
+ *      APIs to png_warning.
+ * Otherwise the calls are mapped to png_error.
+ */
+
+/* Section 2: type definitions, including structures and compile time
+ * constants.
+ * See pngconf.h for base types that vary by machine/system
+ */
+
+/* This triggers a compiler error in png.c, if png.c and png.h
+ * do not agree upon the version number.
+ */
+typedef char* png_libpng_version_1_6_16;
+
+/* Basic control structions.  Read libpng-manual.txt or libpng.3 for more info.
+ *
+ * png_struct is the cache of information used while reading or writing a single
+ * PNG file.  One of these is always required, although the simplified API
+ * (below) hides the creation and destruction of it.
+ */
+typedef struct png_struct_def png_struct;
+typedef const png_struct * png_const_structp;
+typedef png_struct * png_structp;
+typedef png_struct * * png_structpp;
+
+/* png_info contains information read from or to be written to a PNG file.  One
+ * or more of these must exist while reading or creating a PNG file.  The
+ * information is not used by libpng during read but is used to control what
+ * gets written when a PNG file is created.  "png_get_" function calls read
+ * information during read and "png_set_" functions calls write information
+ * when creating a PNG.
+ * been moved into a separate header file that is not accessible to
+ * applications.  Read libpng-manual.txt or libpng.3 for more info.
+ */
+typedef struct png_info_def png_info;
+typedef png_info * png_infop;
+typedef const png_info * png_const_infop;
+typedef png_info * * png_infopp;
+
+/* Types with names ending 'p' are pointer types.  The corresponding types with
+ * names ending 'rp' are identical pointer types except that the pointer is
+ * marked 'restrict', which means that it is the only pointer to the object
+ * passed to the function.  Applications should not use the 'restrict' types;
+ * it is always valid to pass 'p' to a pointer with a function argument of the
+ * corresponding 'rp' type.  Different compilers have different rules with
+ * regard to type matching in the presence of 'restrict'.  For backward
+ * compatibility libpng callbacks never have 'restrict' in their parameters and,
+ * consequentially, writing portable application code is extremely difficult if
+ * an attempt is made to use 'restrict'.
+ */
+typedef png_struct * PNG_RESTRICT png_structrp;
+typedef const png_struct * PNG_RESTRICT png_const_structrp;
+typedef png_info * PNG_RESTRICT png_inforp;
+typedef const png_info * PNG_RESTRICT png_const_inforp;
+
+/* Three color definitions.  The order of the red, green, and blue, (and the
+ * exact size) is not important, although the size of the fields need to
+ * be png_byte or png_uint_16 (as defined below).
+ */
+typedef struct png_color_struct
+{
+   png_byte red;
+   png_byte green;
+   png_byte blue;
+} png_color;
+typedef png_color * png_colorp;
+typedef const png_color * png_const_colorp;
+typedef png_color * * png_colorpp;
+
+typedef struct png_color_16_struct
+{
+   png_byte index;    /* used for palette files */
+   png_uint_16 red;   /* for use in red green blue files */
+   png_uint_16 green;
+   png_uint_16 blue;
+   png_uint_16 gray;  /* for use in grayscale files */
+} png_color_16;
+typedef png_color_16 * png_color_16p;
+typedef const png_color_16 * png_const_color_16p;
+typedef png_color_16 * * png_color_16pp;
+
+typedef struct png_color_8_struct
+{
+   png_byte red;   /* for use in red green blue files */
+   png_byte green;
+   png_byte blue;
+   png_byte gray;  /* for use in grayscale files */
+   png_byte alpha; /* for alpha channel files */
+} png_color_8;
+typedef png_color_8 * png_color_8p;
+typedef const png_color_8 * png_const_color_8p;
+typedef png_color_8 * * png_color_8pp;
+
+/*
+ * The following two structures are used for the in-core representation
+ * of sPLT chunks.
+ */
+typedef struct png_sPLT_entry_struct
+{
+   png_uint_16 red;
+   png_uint_16 green;
+   png_uint_16 blue;
+   png_uint_16 alpha;
+   png_uint_16 frequency;
+} png_sPLT_entry;
+typedef png_sPLT_entry * png_sPLT_entryp;
+typedef const png_sPLT_entry * png_const_sPLT_entryp;
+typedef png_sPLT_entry * * png_sPLT_entrypp;
+
+/*  When the depth of the sPLT palette is 8 bits, the color and alpha samples
+ *  occupy the LSB of their respective members, and the MSB of each member
+ *  is zero-filled.  The frequency member always occupies the full 16 bits.
+ */
+
+typedef struct png_sPLT_struct
+{
+   png_charp name;           /* palette name */
+   png_byte depth;           /* depth of palette samples */
+   png_sPLT_entryp entries;  /* palette entries */
+   png_int_32 nentries;      /* number of palette entries */
+} png_sPLT_t;
+typedef png_sPLT_t * png_sPLT_tp;
+typedef const png_sPLT_t * png_const_sPLT_tp;
+typedef png_sPLT_t * * png_sPLT_tpp;
+
+#ifdef PNG_TEXT_SUPPORTED
+/* png_text holds the contents of a text/ztxt/itxt chunk in a PNG file,
+ * and whether that contents is compressed or not.  The "key" field
+ * points to a regular zero-terminated C string.  The "text" fields can be a
+ * regular C string, an empty string, or a NULL pointer.
+ * However, the structure returned by png_get_text() will always contain
+ * the "text" field as a regular zero-terminated C string (possibly
+ * empty), never a NULL pointer, so it can be safely used in printf() and
+ * other string-handling functions.  Note that the "itxt_length", "lang", and
+ * "lang_key" members of the structure only exist when the library is built
+ * with iTXt chunk support.  Prior to libpng-1.4.0 the library was built by
+ * default without iTXt support. Also note that when iTXt *is* supported,
+ * the "lang" and "lang_key" fields contain NULL pointers when the
+ * "compression" field contains * PNG_TEXT_COMPRESSION_NONE or
+ * PNG_TEXT_COMPRESSION_zTXt. Note that the "compression value" is not the
+ * same as what appears in the PNG tEXt/zTXt/iTXt chunk's "compression flag"
+ * which is always 0 or 1, or its "compression method" which is always 0.
+ */
+typedef struct png_text_struct
+{
+   int  compression;       /* compression value:
+                             -1: tEXt, none
+                              0: zTXt, deflate
+                              1: iTXt, none
+                              2: iTXt, deflate  */
+   png_charp key;          /* keyword, 1-79 character description of "text" */
+   png_charp text;         /* comment, may be an empty string (ie "")
+                              or a NULL pointer */
+   png_size_t text_length; /* length of the text string */
+   png_size_t itxt_length; /* length of the itxt string */
+   png_charp lang;         /* language code, 0-79 characters
+                              or a NULL pointer */
+   png_charp lang_key;     /* keyword translated UTF-8 string, 0 or more
+                              chars or a NULL pointer */
+} png_text;
+typedef png_text * png_textp;
+typedef const png_text * png_const_textp;
+typedef png_text * * png_textpp;
+#endif
+
+/* Supported compression types for text in PNG files (tEXt, and zTXt).
+ * The values of the PNG_TEXT_COMPRESSION_ defines should NOT be changed. */
+#define PNG_TEXT_COMPRESSION_NONE_WR -3
+#define PNG_TEXT_COMPRESSION_zTXt_WR -2
+#define PNG_TEXT_COMPRESSION_NONE    -1
+#define PNG_TEXT_COMPRESSION_zTXt     0
+#define PNG_ITXT_COMPRESSION_NONE     1
+#define PNG_ITXT_COMPRESSION_zTXt     2
+#define PNG_TEXT_COMPRESSION_LAST     3  /* Not a valid value */
+
+/* png_time is a way to hold the time in an machine independent way.
+ * Two conversions are provided, both from time_t and struct tm.  There
+ * is no portable way to convert to either of these structures, as far
+ * as I know.  If you know of a portable way, send it to me.  As a side
+ * note - PNG has always been Year 2000 compliant!
+ */
+typedef struct png_time_struct
+{
+   png_uint_16 year; /* full year, as in, 1995 */
+   png_byte month;   /* month of year, 1 - 12 */
+   png_byte day;     /* day of month, 1 - 31 */
+   png_byte hour;    /* hour of day, 0 - 23 */
+   png_byte minute;  /* minute of hour, 0 - 59 */
+   png_byte second;  /* second of minute, 0 - 60 (for leap seconds) */
+} png_time;
+typedef png_time * png_timep;
+typedef const png_time * png_const_timep;
+typedef png_time * * png_timepp;
+
+#if defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) ||\
+   defined(PNG_USER_CHUNKS_SUPPORTED)
+/* png_unknown_chunk is a structure to hold queued chunks for which there is
+ * no specific support.  The idea is that we can use this to queue
+ * up private chunks for output even though the library doesn't actually
+ * know about their semantics.
+ *
+ * The data in the structure is set by libpng on read and used on write.
+ */
+typedef struct png_unknown_chunk_t
+{
+    png_byte name[5]; /* Textual chunk name with '\0' terminator */
+    png_byte *data;   /* Data, should not be modified on read! */
+    png_size_t size;
+
+    /* On write 'location' must be set using the flag values listed below.
+     * Notice that on read it is set by libpng however the values stored have
+     * more bits set than are listed below.  Always treat the value as a
+     * bitmask.  On write set only one bit - setting multiple bits may cause the
+     * chunk to be written in multiple places.
+     */
+    png_byte location; /* mode of operation at read time */
+}
+png_unknown_chunk;
+
+typedef png_unknown_chunk * png_unknown_chunkp;
+typedef const png_unknown_chunk * png_const_unknown_chunkp;
+typedef png_unknown_chunk * * png_unknown_chunkpp;
+#endif
+
+/* Flag values for the unknown chunk location byte. */
+#define PNG_HAVE_IHDR  0x01
+#define PNG_HAVE_PLTE  0x02
+#define PNG_AFTER_IDAT 0x08
+
+/* Maximum positive integer used in PNG is (2^31)-1 */
+#define PNG_UINT_31_MAX ((png_uint_32)0x7fffffffL)
+#define PNG_UINT_32_MAX ((png_uint_32)(-1))
+#define PNG_SIZE_MAX ((png_size_t)(-1))
+
+/* These are constants for fixed point values encoded in the
+ * PNG specification manner (x100000)
+ */
+#define PNG_FP_1    100000
+#define PNG_FP_HALF  50000
+#define PNG_FP_MAX  ((png_fixed_point)0x7fffffffL)
+#define PNG_FP_MIN  (-PNG_FP_MAX)
+
+/* These describe the color_type field in png_info. */
+/* color type masks */
+#define PNG_COLOR_MASK_PALETTE    1
+#define PNG_COLOR_MASK_COLOR      2
+#define PNG_COLOR_MASK_ALPHA      4
+
+/* color types.  Note that not all combinations are legal */
+#define PNG_COLOR_TYPE_GRAY 0
+#define PNG_COLOR_TYPE_PALETTE  (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE)
+#define PNG_COLOR_TYPE_RGB        (PNG_COLOR_MASK_COLOR)
+#define PNG_COLOR_TYPE_RGB_ALPHA  (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA)
+#define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA)
+/* aliases */
+#define PNG_COLOR_TYPE_RGBA  PNG_COLOR_TYPE_RGB_ALPHA
+#define PNG_COLOR_TYPE_GA  PNG_COLOR_TYPE_GRAY_ALPHA
+
+/* This is for compression type. PNG 1.0-1.2 only define the single type. */
+#define PNG_COMPRESSION_TYPE_BASE 0 /* Deflate method 8, 32K window */
+#define PNG_COMPRESSION_TYPE_DEFAULT PNG_COMPRESSION_TYPE_BASE
+
+/* This is for filter type. PNG 1.0-1.2 only define the single type. */
+#define PNG_FILTER_TYPE_BASE      0 /* Single row per-byte filtering */
+#define PNG_INTRAPIXEL_DIFFERENCING 64 /* Used only in MNG datastreams */
+#define PNG_FILTER_TYPE_DEFAULT   PNG_FILTER_TYPE_BASE
+
+/* These are for the interlacing type.  These values should NOT be changed. */
+#define PNG_INTERLACE_NONE        0 /* Non-interlaced image */
+#define PNG_INTERLACE_ADAM7       1 /* Adam7 interlacing */
+#define PNG_INTERLACE_LAST        2 /* Not a valid value */
+
+/* These are for the oFFs chunk.  These values should NOT be changed. */
+#define PNG_OFFSET_PIXEL          0 /* Offset in pixels */
+#define PNG_OFFSET_MICROMETER     1 /* Offset in micrometers (1/10^6 meter) */
+#define PNG_OFFSET_LAST           2 /* Not a valid value */
+
+/* These are for the pCAL chunk.  These values should NOT be changed. */
+#define PNG_EQUATION_LINEAR       0 /* Linear transformation */
+#define PNG_EQUATION_BASE_E       1 /* Exponential base e transform */
+#define PNG_EQUATION_ARBITRARY    2 /* Arbitrary base exponential transform */
+#define PNG_EQUATION_HYPERBOLIC   3 /* Hyperbolic sine transformation */
+#define PNG_EQUATION_LAST         4 /* Not a valid value */
+
+/* These are for the sCAL chunk.  These values should NOT be changed. */
+#define PNG_SCALE_UNKNOWN         0 /* unknown unit (image scale) */
+#define PNG_SCALE_METER           1 /* meters per pixel */
+#define PNG_SCALE_RADIAN          2 /* radians per pixel */
+#define PNG_SCALE_LAST            3 /* Not a valid value */
+
+/* These are for the pHYs chunk.  These values should NOT be changed. */
+#define PNG_RESOLUTION_UNKNOWN    0 /* pixels/unknown unit (aspect ratio) */
+#define PNG_RESOLUTION_METER      1 /* pixels/meter */
+#define PNG_RESOLUTION_LAST       2 /* Not a valid value */
+
+/* These are for the sRGB chunk.  These values should NOT be changed. */
+#define PNG_sRGB_INTENT_PERCEPTUAL 0
+#define PNG_sRGB_INTENT_RELATIVE   1
+#define PNG_sRGB_INTENT_SATURATION 2
+#define PNG_sRGB_INTENT_ABSOLUTE   3
+#define PNG_sRGB_INTENT_LAST       4 /* Not a valid value */
+
+/* This is for text chunks */
+#define PNG_KEYWORD_MAX_LENGTH     79
+
+/* Maximum number of entries in PLTE/sPLT/tRNS arrays */
+#define PNG_MAX_PALETTE_LENGTH    256
+
+/* These determine if an ancillary chunk's data has been successfully read
+ * from the PNG header, or if the application has filled in the corresponding
+ * data in the info_struct to be written into the output file.  The values
+ * of the PNG_INFO_<chunk> defines should NOT be changed.
+ */
+#define PNG_INFO_gAMA 0x0001
+#define PNG_INFO_sBIT 0x0002
+#define PNG_INFO_cHRM 0x0004
+#define PNG_INFO_PLTE 0x0008
+#define PNG_INFO_tRNS 0x0010
+#define PNG_INFO_bKGD 0x0020
+#define PNG_INFO_hIST 0x0040
+#define PNG_INFO_pHYs 0x0080
+#define PNG_INFO_oFFs 0x0100
+#define PNG_INFO_tIME 0x0200
+#define PNG_INFO_pCAL 0x0400
+#define PNG_INFO_sRGB 0x0800   /* GR-P, 0.96a */
+#define PNG_INFO_iCCP 0x1000   /* ESR, 1.0.6 */
+#define PNG_INFO_sPLT 0x2000   /* ESR, 1.0.6 */
+#define PNG_INFO_sCAL 0x4000   /* ESR, 1.0.6 */
+#define PNG_INFO_IDAT 0x8000   /* ESR, 1.0.6 */
+
+/* This is used for the transformation routines, as some of them
+ * change these values for the row.  It also should enable using
+ * the routines for other purposes.
+ */
+typedef struct png_row_info_struct
+{
+   png_uint_32 width;    /* width of row */
+   png_size_t rowbytes;  /* number of bytes in row */
+   png_byte color_type;  /* color type of row */
+   png_byte bit_depth;   /* bit depth of row */
+   png_byte channels;    /* number of channels (1, 2, 3, or 4) */
+   png_byte pixel_depth; /* bits per pixel (depth * channels) */
+} png_row_info;
+
+typedef png_row_info * png_row_infop;
+typedef png_row_info * * png_row_infopp;
+
+/* These are the function types for the I/O functions and for the functions
+ * that allow the user to override the default I/O functions with his or her
+ * own.  The png_error_ptr type should match that of user-supplied warning
+ * and error functions, while the png_rw_ptr type should match that of the
+ * user read/write data functions.  Note that the 'write' function must not
+ * modify the buffer it is passed. The 'read' function, on the other hand, is
+ * expected to return the read data in the buffer.
+ */
+typedef PNG_CALLBACK(void, *png_error_ptr, (png_structp, png_const_charp));
+typedef PNG_CALLBACK(void, *png_rw_ptr, (png_structp, png_bytep, png_size_t));
+typedef PNG_CALLBACK(void, *png_flush_ptr, (png_structp));
+typedef PNG_CALLBACK(void, *png_read_status_ptr, (png_structp, png_uint_32,
+    int));
+typedef PNG_CALLBACK(void, *png_write_status_ptr, (png_structp, png_uint_32,
+    int));
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+typedef PNG_CALLBACK(void, *png_progressive_info_ptr, (png_structp, png_infop));
+typedef PNG_CALLBACK(void, *png_progressive_end_ptr, (png_structp, png_infop));
+
+/* The following callback receives png_uint_32 row_number, int pass for the
+ * png_bytep data of the row.  When transforming an interlaced image the
+ * row number is the row number within the sub-image of the interlace pass, so
+ * the value will increase to the height of the sub-image (not the full image)
+ * then reset to 0 for the next pass.
+ *
+ * Use PNG_ROW_FROM_PASS_ROW(row, pass) and PNG_COL_FROM_PASS_COL(col, pass) to
+ * find the output pixel (x,y) given an interlaced sub-image pixel
+ * (row,col,pass).  (See below for these macros.)
+ */
+typedef PNG_CALLBACK(void, *png_progressive_row_ptr, (png_structp, png_bytep,
+    png_uint_32, int));
+#endif
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+typedef PNG_CALLBACK(void, *png_user_transform_ptr, (png_structp, png_row_infop,
+    png_bytep));
+#endif
+
+#ifdef PNG_USER_CHUNKS_SUPPORTED
+typedef PNG_CALLBACK(int, *png_user_chunk_ptr, (png_structp,
+    png_unknown_chunkp));
+#endif
+#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
+/* not used anywhere */
+/* typedef PNG_CALLBACK(void, *png_unknown_chunk_ptr, (png_structp)); */
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+/* This must match the function definition in <setjmp.h>, and the application
+ * must include this before png.h to obtain the definition of jmp_buf.  The
+ * function is required to be PNG_NORETURN, but this is not checked.  If the
+ * function does return the application will crash via an abort() or similar
+ * system level call.
+ *
+ * If you get a warning here while building the library you may need to make
+ * changes to ensure that pnglibconf.h records the calling convention used by
+ * your compiler.  This may be very difficult - try using a different compiler
+ * to build the library!
+ */
+PNG_FUNCTION(void, (PNGCAPI *png_longjmp_ptr), PNGARG((jmp_buf, int)), typedef);
+#endif
+
+/* Transform masks for the high-level interface */
+#define PNG_TRANSFORM_IDENTITY       0x0000    /* read and write */
+#define PNG_TRANSFORM_STRIP_16       0x0001    /* read only */
+#define PNG_TRANSFORM_STRIP_ALPHA    0x0002    /* read only */
+#define PNG_TRANSFORM_PACKING        0x0004    /* read and write */
+#define PNG_TRANSFORM_PACKSWAP       0x0008    /* read and write */
+#define PNG_TRANSFORM_EXPAND         0x0010    /* read only */
+#define PNG_TRANSFORM_INVERT_MONO    0x0020    /* read and write */
+#define PNG_TRANSFORM_SHIFT          0x0040    /* read and write */
+#define PNG_TRANSFORM_BGR            0x0080    /* read and write */
+#define PNG_TRANSFORM_SWAP_ALPHA     0x0100    /* read and write */
+#define PNG_TRANSFORM_SWAP_ENDIAN    0x0200    /* read and write */
+#define PNG_TRANSFORM_INVERT_ALPHA   0x0400    /* read and write */
+#define PNG_TRANSFORM_STRIP_FILLER   0x0800    /* write only */
+/* Added to libpng-1.2.34 */
+#define PNG_TRANSFORM_STRIP_FILLER_BEFORE PNG_TRANSFORM_STRIP_FILLER
+#define PNG_TRANSFORM_STRIP_FILLER_AFTER 0x1000 /* write only */
+/* Added to libpng-1.4.0 */
+#define PNG_TRANSFORM_GRAY_TO_RGB   0x2000      /* read only */
+/* Added to libpng-1.5.4 */
+#define PNG_TRANSFORM_EXPAND_16     0x4000      /* read only */
+#define PNG_TRANSFORM_SCALE_16      0x8000      /* read only */
+
+/* Flags for MNG supported features */
+#define PNG_FLAG_MNG_EMPTY_PLTE     0x01
+#define PNG_FLAG_MNG_FILTER_64      0x04
+#define PNG_ALL_MNG_FEATURES        0x05
+
+/* NOTE: prior to 1.5 these functions had no 'API' style declaration,
+ * this allowed the zlib default functions to be used on Windows
+ * platforms.  In 1.5 the zlib default malloc (which just calls malloc and
+ * ignores the first argument) should be completely compatible with the
+ * following.
+ */
+typedef PNG_CALLBACK(png_voidp, *png_malloc_ptr, (png_structp,
+    png_alloc_size_t));
+typedef PNG_CALLBACK(void, *png_free_ptr, (png_structp, png_voidp));
+
+/* Section 3: exported functions
+ * Here are the function definitions most commonly used.  This is not
+ * the place to find out how to use libpng.  See libpng-manual.txt for the
+ * full explanation, see example.c for the summary.  This just provides
+ * a simple one line description of the use of each function.
+ *
+ * The PNG_EXPORT() and PNG_EXPORTA() macros used below are defined in
+ * pngconf.h and in the *.dfn files in the scripts directory.
+ *
+ *   PNG_EXPORT(ordinal, type, name, (args));
+ *
+ *       ordinal:    ordinal that is used while building
+ *                   *.def files. The ordinal value is only
+ *                   relevant when preprocessing png.h with
+ *                   the *.dfn files for building symbol table
+ *                   entries, and are removed by pngconf.h.
+ *       type:       return type of the function
+ *       name:       function name
+ *       args:       function arguments, with types
+ *
+ * When we wish to append attributes to a function prototype we use
+ * the PNG_EXPORTA() macro instead.
+ *
+ *   PNG_EXPORTA(ordinal, type, name, (args), attributes);
+ *
+ *       ordinal, type, name, and args: same as in PNG_EXPORT().
+ *       attributes: function attributes
+ */
+
+/* Returns the version number of the library */
+PNG_EXPORT(1, png_uint_32, png_access_version_number, (void));
+
+/* Tell lib we have already handled the first <num_bytes> magic bytes.
+ * Handling more than 8 bytes from the beginning of the file is an error.
+ */
+PNG_EXPORT(2, void, png_set_sig_bytes, (png_structrp png_ptr, int num_bytes));
+
+/* Check sig[start] through sig[start + num_to_check - 1] to see if it's a
+ * PNG file.  Returns zero if the supplied bytes match the 8-byte PNG
+ * signature, and non-zero otherwise.  Having num_to_check == 0 or
+ * start > 7 will always fail (ie return non-zero).
+ */
+PNG_EXPORT(3, int, png_sig_cmp, (png_const_bytep sig, png_size_t start,
+    png_size_t num_to_check));
+
+/* Simple signature checking function.  This is the same as calling
+ * png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n).
+ */
+#define png_check_sig(sig, n) !png_sig_cmp((sig), 0, (n))
+
+/* Allocate and initialize png_ptr struct for reading, and any other memory. */
+PNG_EXPORTA(4, png_structp, png_create_read_struct,
+    (png_const_charp user_png_ver, png_voidp error_ptr,
+    png_error_ptr error_fn, png_error_ptr warn_fn),
+    PNG_ALLOCATED);
+
+/* Allocate and initialize png_ptr struct for writing, and any other memory */
+PNG_EXPORTA(5, png_structp, png_create_write_struct,
+    (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn,
+    png_error_ptr warn_fn),
+    PNG_ALLOCATED);
+
+PNG_EXPORT(6, png_size_t, png_get_compression_buffer_size,
+    (png_const_structrp png_ptr));
+
+PNG_EXPORT(7, void, png_set_compression_buffer_size, (png_structrp png_ptr,
+    png_size_t size));
+
+/* Moved from pngconf.h in 1.4.0 and modified to ensure setjmp/longjmp
+ * match up.
+ */
+#ifdef PNG_SETJMP_SUPPORTED
+/* This function returns the jmp_buf built in to *png_ptr.  It must be
+ * supplied with an appropriate 'longjmp' function to use on that jmp_buf
+ * unless the default error function is overridden in which case NULL is
+ * acceptable.  The size of the jmp_buf is checked against the actual size
+ * allocated by the library - the call will return NULL on a mismatch
+ * indicating an ABI mismatch.
+ */
+PNG_EXPORT(8, jmp_buf*, png_set_longjmp_fn, (png_structrp png_ptr,
+    png_longjmp_ptr longjmp_fn, size_t jmp_buf_size));
+#  define png_jmpbuf(png_ptr) \
+      (*png_set_longjmp_fn((png_ptr), longjmp, (sizeof (jmp_buf))))
+#else
+#  define png_jmpbuf(png_ptr) \
+      (LIBPNG_WAS_COMPILED_WITH__PNG_NO_SETJMP)
+#endif
+/* This function should be used by libpng applications in place of
+ * longjmp(png_ptr->jmpbuf, val).  If longjmp_fn() has been set, it
+ * will use it; otherwise it will call PNG_ABORT().  This function was
+ * added in libpng-1.5.0.
+ */
+PNG_EXPORTA(9, void, png_longjmp, (png_const_structrp png_ptr, int val),
+    PNG_NORETURN);
+
+#ifdef PNG_READ_SUPPORTED
+/* Reset the compression stream */
+PNG_EXPORTA(10, int, png_reset_zstream, (png_structrp png_ptr), PNG_DEPRECATED);
+#endif
+
+/* New functions added in libpng-1.0.2 (not enabled by default until 1.2.0) */
+#ifdef PNG_USER_MEM_SUPPORTED
+PNG_EXPORTA(11, png_structp, png_create_read_struct_2,
+    (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn,
+    png_error_ptr warn_fn,
+    png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn),
+    PNG_ALLOCATED);
+PNG_EXPORTA(12, png_structp, png_create_write_struct_2,
+    (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn,
+    png_error_ptr warn_fn,
+    png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn),
+    PNG_ALLOCATED);
+#endif
+
+/* Write the PNG file signature. */
+PNG_EXPORT(13, void, png_write_sig, (png_structrp png_ptr));
+
+/* Write a PNG chunk - size, type, (optional) data, CRC. */
+PNG_EXPORT(14, void, png_write_chunk, (png_structrp png_ptr, png_const_bytep
+    chunk_name, png_const_bytep data, png_size_t length));
+
+/* Write the start of a PNG chunk - length and chunk name. */
+PNG_EXPORT(15, void, png_write_chunk_start, (png_structrp png_ptr,
+    png_const_bytep chunk_name, png_uint_32 length));
+
+/* Write the data of a PNG chunk started with png_write_chunk_start(). */
+PNG_EXPORT(16, void, png_write_chunk_data, (png_structrp png_ptr,
+    png_const_bytep data, png_size_t length));
+
+/* Finish a chunk started with png_write_chunk_start() (includes CRC). */
+PNG_EXPORT(17, void, png_write_chunk_end, (png_structrp png_ptr));
+
+/* Allocate and initialize the info structure */
+PNG_EXPORTA(18, png_infop, png_create_info_struct, (png_const_structrp png_ptr),
+    PNG_ALLOCATED);
+
+/* DEPRECATED: this function allowed init structures to be created using the
+ * default allocation method (typically malloc).  Use is deprecated in 1.6.0 and
+ * the API will be removed in the future.
+ */
+PNG_EXPORTA(19, void, png_info_init_3, (png_infopp info_ptr,
+    png_size_t png_info_struct_size), PNG_DEPRECATED);
+
+/* Writes all the PNG information before the image. */
+PNG_EXPORT(20, void, png_write_info_before_PLTE,
+    (png_structrp png_ptr, png_const_inforp info_ptr));
+PNG_EXPORT(21, void, png_write_info,
+    (png_structrp png_ptr, png_const_inforp info_ptr));
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Read the information before the actual image data. */
+PNG_EXPORT(22, void, png_read_info,
+    (png_structrp png_ptr, png_inforp info_ptr));
+#endif
+
+#ifdef PNG_TIME_RFC1123_SUPPORTED
+   /* Convert to a US string format: there is no localization support in this
+    * routine.  The original implementation used a 29 character buffer in
+    * png_struct, this will be removed in future versions.
+    */
+#if PNG_LIBPNG_VER < 10700
+/* To do: remove this from libpng17 (and from libpng17/png.c and pngstruct.h) */
+PNG_EXPORTA(23, png_const_charp, png_convert_to_rfc1123, (png_structrp png_ptr,
+    png_const_timep ptime),PNG_DEPRECATED);
+#endif
+PNG_EXPORT(241, int, png_convert_to_rfc1123_buffer, (char out[29],
+    png_const_timep ptime));
+#endif
+
+#ifdef PNG_CONVERT_tIME_SUPPORTED
+/* Convert from a struct tm to png_time */
+PNG_EXPORT(24, void, png_convert_from_struct_tm, (png_timep ptime,
+    const struct tm * ttime));
+
+/* Convert from time_t to png_time.  Uses gmtime() */
+PNG_EXPORT(25, void, png_convert_from_time_t, (png_timep ptime, time_t ttime));
+#endif /* CONVERT_tIME */
+
+#ifdef PNG_READ_EXPAND_SUPPORTED
+/* Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available. */
+PNG_EXPORT(26, void, png_set_expand, (png_structrp png_ptr));
+PNG_EXPORT(27, void, png_set_expand_gray_1_2_4_to_8, (png_structrp png_ptr));
+PNG_EXPORT(28, void, png_set_palette_to_rgb, (png_structrp png_ptr));
+PNG_EXPORT(29, void, png_set_tRNS_to_alpha, (png_structrp png_ptr));
+#endif
+
+#ifdef PNG_READ_EXPAND_16_SUPPORTED
+/* Expand to 16-bit channels, forces conversion of palette to RGB and expansion
+ * of a tRNS chunk if present.
+ */
+PNG_EXPORT(221, void, png_set_expand_16, (png_structrp png_ptr));
+#endif
+
+#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
+/* Use blue, green, red order for pixels. */
+PNG_EXPORT(30, void, png_set_bgr, (png_structrp png_ptr));
+#endif
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+/* Expand the grayscale to 24-bit RGB if necessary. */
+PNG_EXPORT(31, void, png_set_gray_to_rgb, (png_structrp png_ptr));
+#endif
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+/* Reduce RGB to grayscale. */
+#define PNG_ERROR_ACTION_NONE  1
+#define PNG_ERROR_ACTION_WARN  2
+#define PNG_ERROR_ACTION_ERROR 3
+#define PNG_RGB_TO_GRAY_DEFAULT (-1)/*for red/green coefficients*/
+
+PNG_FP_EXPORT(32, void, png_set_rgb_to_gray, (png_structrp png_ptr,
+    int error_action, double red, double green))
+PNG_FIXED_EXPORT(33, void, png_set_rgb_to_gray_fixed, (png_structrp png_ptr,
+    int error_action, png_fixed_point red, png_fixed_point green))
+
+PNG_EXPORT(34, png_byte, png_get_rgb_to_gray_status, (png_const_structrp
+    png_ptr));
+#endif
+
+#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED
+PNG_EXPORT(35, void, png_build_grayscale_palette, (int bit_depth,
+    png_colorp palette));
+#endif
+
+#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
+/* How the alpha channel is interpreted - this affects how the color channels
+ * of a PNG file are returned to the calling application when an alpha channel,
+ * or a tRNS chunk in a palette file, is present.
+ *
+ * This has no effect on the way pixels are written into a PNG output
+ * datastream. The color samples in a PNG datastream are never premultiplied
+ * with the alpha samples.
+ *
+ * The default is to return data according to the PNG specification: the alpha
+ * channel is a linear measure of the contribution of the pixel to the
+ * corresponding composited pixel, and the color channels are unassociated
+ * (not premultiplied).  The gamma encoded color channels must be scaled
+ * according to the contribution and to do this it is necessary to undo
+ * the encoding, scale the color values, perform the composition and reencode
+ * the values.  This is the 'PNG' mode.
+ *
+ * The alternative is to 'associate' the alpha with the color information by
+ * storing color channel values that have been scaled by the alpha.
+ * image.  These are the 'STANDARD', 'ASSOCIATED' or 'PREMULTIPLIED' modes
+ * (the latter being the two common names for associated alpha color channels).
+ *
+ * For the 'OPTIMIZED' mode, a pixel is treated as opaque only if the alpha
+ * value is equal to the maximum value.
+ *
+ * The final choice is to gamma encode the alpha channel as well.  This is
+ * broken because, in practice, no implementation that uses this choice
+ * correctly undoes the encoding before handling alpha composition.  Use this
+ * choice only if other serious errors in the software or hardware you use
+ * mandate it; the typical serious error is for dark halos to appear around
+ * opaque areas of the composited PNG image because of arithmetic overflow.
+ *
+ * The API function png_set_alpha_mode specifies which of these choices to use
+ * with an enumerated 'mode' value and the gamma of the required output:
+ */
+#define PNG_ALPHA_PNG           0 /* according to the PNG standard */
+#define PNG_ALPHA_STANDARD      1 /* according to Porter/Duff */
+#define PNG_ALPHA_ASSOCIATED    1 /* as above; this is the normal practice */
+#define PNG_ALPHA_PREMULTIPLIED 1 /* as above */
+#define PNG_ALPHA_OPTIMIZED     2 /* 'PNG' for opaque pixels, else 'STANDARD' */
+#define PNG_ALPHA_BROKEN        3 /* the alpha channel is gamma encoded */
+
+PNG_FP_EXPORT(227, void, png_set_alpha_mode, (png_structrp png_ptr, int mode,
+    double output_gamma))
+PNG_FIXED_EXPORT(228, void, png_set_alpha_mode_fixed, (png_structrp png_ptr,
+    int mode, png_fixed_point output_gamma))
+#endif
+
+#if defined(PNG_GAMMA_SUPPORTED) || defined(PNG_READ_ALPHA_MODE_SUPPORTED)
+/* The output_gamma value is a screen gamma in libpng terminology: it expresses
+ * how to decode the output values, not how they are encoded.
+ */
+#define PNG_DEFAULT_sRGB -1       /* sRGB gamma and color space */
+#define PNG_GAMMA_MAC_18 -2       /* Old Mac '1.8' gamma and color space */
+#define PNG_GAMMA_sRGB   220000   /* Television standards--matches sRGB gamma */
+#define PNG_GAMMA_LINEAR PNG_FP_1 /* Linear */
+#endif
+
+/* The following are examples of calls to png_set_alpha_mode to achieve the
+ * required overall gamma correction and, where necessary, alpha
+ * premultiplication.
+ *
+ * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB);
+ *    This is the default libpng handling of the alpha channel - it is not
+ *    pre-multiplied into the color components.  In addition the call states
+ *    that the output is for a sRGB system and causes all PNG files without gAMA
+ *    chunks to be assumed to be encoded using sRGB.
+ *
+ * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC);
+ *    In this case the output is assumed to be something like an sRGB conformant
+ *    display preceeded by a power-law lookup table of power 1.45.  This is how
+ *    early Mac systems behaved.
+ *
+ * png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_GAMMA_LINEAR);
+ *    This is the classic Jim Blinn approach and will work in academic
+ *    environments where everything is done by the book.  It has the shortcoming
+ *    of assuming that input PNG data with no gamma information is linear - this
+ *    is unlikely to be correct unless the PNG files where generated locally.
+ *    Most of the time the output precision will be so low as to show
+ *    significant banding in dark areas of the image.
+ *
+ * png_set_expand_16(pp);
+ * png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_DEFAULT_sRGB);
+ *    This is a somewhat more realistic Jim Blinn inspired approach.  PNG files
+ *    are assumed to have the sRGB encoding if not marked with a gamma value and
+ *    the output is always 16 bits per component.  This permits accurate scaling
+ *    and processing of the data.  If you know that your input PNG files were
+ *    generated locally you might need to replace PNG_DEFAULT_sRGB with the
+ *    correct value for your system.
+ *
+ * png_set_alpha_mode(pp, PNG_ALPHA_OPTIMIZED, PNG_DEFAULT_sRGB);
+ *    If you just need to composite the PNG image onto an existing background
+ *    and if you control the code that does this you can use the optimization
+ *    setting.  In this case you just copy completely opaque pixels to the
+ *    output.  For pixels that are not completely transparent (you just skip
+ *    those) you do the composition math using png_composite or png_composite_16
+ *    below then encode the resultant 8-bit or 16-bit values to match the output
+ *    encoding.
+ *
+ * Other cases
+ *    If neither the PNG nor the standard linear encoding work for you because
+ *    of the software or hardware you use then you have a big problem.  The PNG
+ *    case will probably result in halos around the image.  The linear encoding
+ *    will probably result in a washed out, too bright, image (it's actually too
+ *    contrasty.)  Try the ALPHA_OPTIMIZED mode above - this will probably
+ *    substantially reduce the halos.  Alternatively try:
+ *
+ * png_set_alpha_mode(pp, PNG_ALPHA_BROKEN, PNG_DEFAULT_sRGB);
+ *    This option will also reduce the halos, but there will be slight dark
+ *    halos round the opaque parts of the image where the background is light.
+ *    In the OPTIMIZED mode the halos will be light halos where the background
+ *    is dark.  Take your pick - the halos are unavoidable unless you can get
+ *    your hardware/software fixed!  (The OPTIMIZED approach is slightly
+ *    faster.)
+ *
+ * When the default gamma of PNG files doesn't match the output gamma.
+ *    If you have PNG files with no gamma information png_set_alpha_mode allows
+ *    you to provide a default gamma, but it also sets the ouput gamma to the
+ *    matching value.  If you know your PNG files have a gamma that doesn't
+ *    match the output you can take advantage of the fact that
+ *    png_set_alpha_mode always sets the output gamma but only sets the PNG
+ *    default if it is not already set:
+ *
+ * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB);
+ * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC);
+ *    The first call sets both the default and the output gamma values, the
+ *    second call overrides the output gamma without changing the default.  This
+ *    is easier than achieving the same effect with png_set_gamma.  You must use
+ *    PNG_ALPHA_PNG for the first call - internal checking in png_set_alpha will
+ *    fire if more than one call to png_set_alpha_mode and png_set_background is
+ *    made in the same read operation, however multiple calls with PNG_ALPHA_PNG
+ *    are ignored.
+ */
+
+#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
+PNG_EXPORT(36, void, png_set_strip_alpha, (png_structrp png_ptr));
+#endif
+
+#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
+    defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
+PNG_EXPORT(37, void, png_set_swap_alpha, (png_structrp png_ptr));
+#endif
+
+#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
+    defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
+PNG_EXPORT(38, void, png_set_invert_alpha, (png_structrp png_ptr));
+#endif
+
+#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
+/* Add a filler byte to 8-bit Gray or 24-bit RGB images. */
+PNG_EXPORT(39, void, png_set_filler, (png_structrp png_ptr, png_uint_32 filler,
+    int flags));
+/* The values of the PNG_FILLER_ defines should NOT be changed */
+#  define PNG_FILLER_BEFORE 0
+#  define PNG_FILLER_AFTER 1
+/* Add an alpha byte to 8-bit Gray or 24-bit RGB images. */
+PNG_EXPORT(40, void, png_set_add_alpha, (png_structrp png_ptr,
+    png_uint_32 filler, int flags));
+#endif /* READ_FILLER || WRITE_FILLER */
+
+#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
+/* Swap bytes in 16-bit depth files. */
+PNG_EXPORT(41, void, png_set_swap, (png_structrp png_ptr));
+#endif
+
+#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
+/* Use 1 byte per pixel in 1, 2, or 4-bit depth files. */
+PNG_EXPORT(42, void, png_set_packing, (png_structrp png_ptr));
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED) || \
+    defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+/* Swap packing order of pixels in bytes. */
+PNG_EXPORT(43, void, png_set_packswap, (png_structrp png_ptr));
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
+/* Converts files to legal bit depths. */
+PNG_EXPORT(44, void, png_set_shift, (png_structrp png_ptr, png_const_color_8p
+    true_bits));
+#endif
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
+    defined(PNG_WRITE_INTERLACING_SUPPORTED)
+/* Have the code handle the interlacing.  Returns the number of passes.
+ * MUST be called before png_read_update_info or png_start_read_image,
+ * otherwise it will not have the desired effect.  Note that it is still
+ * necessary to call png_read_row or png_read_rows png_get_image_height
+ * times for each pass.
+*/
+PNG_EXPORT(45, int, png_set_interlace_handling, (png_structrp png_ptr));
+#endif
+
+#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
+/* Invert monochrome files */
+PNG_EXPORT(46, void, png_set_invert_mono, (png_structrp png_ptr));
+#endif
+
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+/* Handle alpha and tRNS by replacing with a background color.  Prior to
+ * libpng-1.5.4 this API must not be called before the PNG file header has been
+ * read.  Doing so will result in unexpected behavior and possible warnings or
+ * errors if the PNG file contains a bKGD chunk.
+ */
+PNG_FP_EXPORT(47, void, png_set_background, (png_structrp png_ptr,
+    png_const_color_16p background_color, int background_gamma_code,
+    int need_expand, double background_gamma))
+PNG_FIXED_EXPORT(215, void, png_set_background_fixed, (png_structrp png_ptr,
+    png_const_color_16p background_color, int background_gamma_code,
+    int need_expand, png_fixed_point background_gamma))
+#endif
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+#  define PNG_BACKGROUND_GAMMA_UNKNOWN 0
+#  define PNG_BACKGROUND_GAMMA_SCREEN  1
+#  define PNG_BACKGROUND_GAMMA_FILE    2
+#  define PNG_BACKGROUND_GAMMA_UNIQUE  3
+#endif
+
+#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
+/* Scale a 16-bit depth file down to 8-bit, accurately. */
+PNG_EXPORT(229, void, png_set_scale_16, (png_structrp png_ptr));
+#endif
+
+#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
+#define PNG_READ_16_TO_8 SUPPORTED /* Name prior to 1.5.4 */
+/* Strip the second byte of information from a 16-bit depth file. */
+PNG_EXPORT(48, void, png_set_strip_16, (png_structrp png_ptr));
+#endif
+
+#ifdef PNG_READ_QUANTIZE_SUPPORTED
+/* Turn on quantizing, and reduce the palette to the number of colors
+ * available.
+ */
+PNG_EXPORT(49, void, png_set_quantize, (png_structrp png_ptr,
+    png_colorp palette, int num_palette, int maximum_colors,
+    png_const_uint_16p histogram, int full_quantize));
+#endif
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+/* The threshold on gamma processing is configurable but hard-wired into the
+ * library.  The following is the floating point variant.
+ */
+#define PNG_GAMMA_THRESHOLD (PNG_GAMMA_THRESHOLD_FIXED*.00001)
+
+/* Handle gamma correction. Screen_gamma=(display_exponent).
+ * NOTE: this API simply sets the screen and file gamma values. It will
+ * therefore override the value for gamma in a PNG file if it is called after
+ * the file header has been read - use with care  - call before reading the PNG
+ * file for best results!
+ *
+ * These routines accept the same gamma values as png_set_alpha_mode (described
+ * above).  The PNG_GAMMA_ defines and PNG_DEFAULT_sRGB can be passed to either
+ * API (floating point or fixed.)  Notice, however, that the 'file_gamma' value
+ * is the inverse of a 'screen gamma' value.
+ */
+PNG_FP_EXPORT(50, void, png_set_gamma, (png_structrp png_ptr,
+    double screen_gamma, double override_file_gamma))
+PNG_FIXED_EXPORT(208, void, png_set_gamma_fixed, (png_structrp png_ptr,
+    png_fixed_point screen_gamma, png_fixed_point override_file_gamma))
+#endif
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+/* Set how many lines between output flushes - 0 for no flushing */
+PNG_EXPORT(51, void, png_set_flush, (png_structrp png_ptr, int nrows));
+/* Flush the current PNG output buffer */
+PNG_EXPORT(52, void, png_write_flush, (png_structrp png_ptr));
+#endif
+
+/* Optional update palette with requested transformations */
+PNG_EXPORT(53, void, png_start_read_image, (png_structrp png_ptr));
+
+/* Optional call to update the users info structure */
+PNG_EXPORT(54, void, png_read_update_info, (png_structrp png_ptr,
+    png_inforp info_ptr));
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Read one or more rows of image data. */
+PNG_EXPORT(55, void, png_read_rows, (png_structrp png_ptr, png_bytepp row,
+    png_bytepp display_row, png_uint_32 num_rows));
+#endif
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Read a row of data. */
+PNG_EXPORT(56, void, png_read_row, (png_structrp png_ptr, png_bytep row,
+    png_bytep display_row));
+#endif
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Read the whole image into memory at once. */
+PNG_EXPORT(57, void, png_read_image, (png_structrp png_ptr, png_bytepp image));
+#endif
+
+/* Write a row of image data */
+PNG_EXPORT(58, void, png_write_row, (png_structrp png_ptr,
+    png_const_bytep row));
+
+/* Write a few rows of image data: (*row) is not written; however, the type
+ * is declared as writeable to maintain compatibility with previous versions
+ * of libpng and to allow the 'display_row' array from read_rows to be passed
+ * unchanged to write_rows.
+ */
+PNG_EXPORT(59, void, png_write_rows, (png_structrp png_ptr, png_bytepp row,
+    png_uint_32 num_rows));
+
+/* Write the image data */
+PNG_EXPORT(60, void, png_write_image, (png_structrp png_ptr, png_bytepp image));
+
+/* Write the end of the PNG file. */
+PNG_EXPORT(61, void, png_write_end, (png_structrp png_ptr,
+    png_inforp info_ptr));
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Read the end of the PNG file. */
+PNG_EXPORT(62, void, png_read_end, (png_structrp png_ptr, png_inforp info_ptr));
+#endif
+
+/* Free any memory associated with the png_info_struct */
+PNG_EXPORT(63, void, png_destroy_info_struct, (png_const_structrp png_ptr,
+    png_infopp info_ptr_ptr));
+
+/* Free any memory associated with the png_struct and the png_info_structs */
+PNG_EXPORT(64, void, png_destroy_read_struct, (png_structpp png_ptr_ptr,
+    png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr));
+
+/* Free any memory associated with the png_struct and the png_info_structs */
+PNG_EXPORT(65, void, png_destroy_write_struct, (png_structpp png_ptr_ptr,
+    png_infopp info_ptr_ptr));
+
+/* Set the libpng method of handling chunk CRC errors */
+PNG_EXPORT(66, void, png_set_crc_action, (png_structrp png_ptr, int crit_action,
+    int ancil_action));
+
+/* Values for png_set_crc_action() say how to handle CRC errors in
+ * ancillary and critical chunks, and whether to use the data contained
+ * therein.  Note that it is impossible to "discard" data in a critical
+ * chunk.  For versions prior to 0.90, the action was always error/quit,
+ * whereas in version 0.90 and later, the action for CRC errors in ancillary
+ * chunks is warn/discard.  These values should NOT be changed.
+ *
+ *      value                       action:critical     action:ancillary
+ */
+#define PNG_CRC_DEFAULT       0  /* error/quit          warn/discard data */
+#define PNG_CRC_ERROR_QUIT    1  /* error/quit          error/quit        */
+#define PNG_CRC_WARN_DISCARD  2  /* (INVALID)           warn/discard data */
+#define PNG_CRC_WARN_USE      3  /* warn/use data       warn/use data     */
+#define PNG_CRC_QUIET_USE     4  /* quiet/use data      quiet/use data    */
+#define PNG_CRC_NO_CHANGE     5  /* use current value   use current value */
+
+/* These functions give the user control over the scan-line filtering in
+ * libpng and the compression methods used by zlib.  These functions are
+ * mainly useful for testing, as the defaults should work with most users.
+ * Those users who are tight on memory or want faster performance at the
+ * expense of compression can modify them.  See the compression library
+ * header file (zlib.h) for an explination of the compression functions.
+ */
+
+/* Set the filtering method(s) used by libpng.  Currently, the only valid
+ * value for "method" is 0.
+ */
+PNG_EXPORT(67, void, png_set_filter, (png_structrp png_ptr, int method,
+    int filters));
+
+/* Flags for png_set_filter() to say which filters to use.  The flags
+ * are chosen so that they don't conflict with real filter types
+ * below, in case they are supplied instead of the #defined constants.
+ * These values should NOT be changed.
+ */
+#define PNG_NO_FILTERS     0x00
+#define PNG_FILTER_NONE    0x08
+#define PNG_FILTER_SUB     0x10
+#define PNG_FILTER_UP      0x20
+#define PNG_FILTER_AVG     0x40
+#define PNG_FILTER_PAETH   0x80
+#define PNG_ALL_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | \
+                         PNG_FILTER_AVG | PNG_FILTER_PAETH)
+
+/* Filter values (not flags) - used in pngwrite.c, pngwutil.c for now.
+ * These defines should NOT be changed.
+ */
+#define PNG_FILTER_VALUE_NONE  0
+#define PNG_FILTER_VALUE_SUB   1
+#define PNG_FILTER_VALUE_UP    2
+#define PNG_FILTER_VALUE_AVG   3
+#define PNG_FILTER_VALUE_PAETH 4
+#define PNG_FILTER_VALUE_LAST  5
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* EXPERIMENTAL */
+/* The "heuristic_method" is given by one of the PNG_FILTER_HEURISTIC_
+ * defines, either the default (minimum-sum-of-absolute-differences), or
+ * the experimental method (weighted-minimum-sum-of-absolute-differences).
+ *
+ * Weights are factors >= 1.0, indicating how important it is to keep the
+ * filter type consistent between rows.  Larger numbers mean the current
+ * filter is that many times as likely to be the same as the "num_weights"
+ * previous filters.  This is cumulative for each previous row with a weight.
+ * There needs to be "num_weights" values in "filter_weights", or it can be
+ * NULL if the weights aren't being specified.  Weights have no influence on
+ * the selection of the first row filter.  Well chosen weights can (in theory)
+ * improve the compression for a given image.
+ *
+ * Costs are factors >= 1.0 indicating the relative decoding costs of a
+ * filter type.  Higher costs indicate more decoding expense, and are
+ * therefore less likely to be selected over a filter with lower computational
+ * costs.  There needs to be a value in "filter_costs" for each valid filter
+ * type (given by PNG_FILTER_VALUE_LAST), or it can be NULL if you aren't
+ * setting the costs.  Costs try to improve the speed of decompression without
+ * unduly increasing the compressed image size.
+ *
+ * A negative weight or cost indicates the default value is to be used, and
+ * values in the range [0.0, 1.0) indicate the value is to remain unchanged.
+ * The default values for both weights and costs are currently 1.0, but may
+ * change if good general weighting/cost heuristics can be found.  If both
+ * the weights and costs are set to 1.0, this degenerates the WEIGHTED method
+ * to the UNWEIGHTED method, but with added encoding time/computation.
+ */
+PNG_FP_EXPORT(68, void, png_set_filter_heuristics, (png_structrp png_ptr,
+    int heuristic_method, int num_weights, png_const_doublep filter_weights,
+    png_const_doublep filter_costs))
+PNG_FIXED_EXPORT(209, void, png_set_filter_heuristics_fixed,
+    (png_structrp png_ptr, int heuristic_method, int num_weights,
+    png_const_fixed_point_p filter_weights,
+    png_const_fixed_point_p filter_costs))
+#endif /* WRITE_WEIGHTED_FILTER */
+
+/* Heuristic used for row filter selection.  These defines should NOT be
+ * changed.
+ */
+#define PNG_FILTER_HEURISTIC_DEFAULT    0  /* Currently "UNWEIGHTED" */
+#define PNG_FILTER_HEURISTIC_UNWEIGHTED 1  /* Used by libpng < 0.95 */
+#define PNG_FILTER_HEURISTIC_WEIGHTED   2  /* Experimental feature */
+#define PNG_FILTER_HEURISTIC_LAST       3  /* Not a valid value */
+
+#ifdef PNG_WRITE_SUPPORTED
+/* Set the library compression level.  Currently, valid values range from
+ * 0 - 9, corresponding directly to the zlib compression levels 0 - 9
+ * (0 - no compression, 9 - "maximal" compression).  Note that tests have
+ * shown that zlib compression levels 3-6 usually perform as well as level 9
+ * for PNG images, and do considerably fewer caclulations.  In the future,
+ * these values may not correspond directly to the zlib compression levels.
+ */
+PNG_EXPORT(69, void, png_set_compression_level, (png_structrp png_ptr,
+    int level));
+
+PNG_EXPORT(70, void, png_set_compression_mem_level, (png_structrp png_ptr,
+    int mem_level));
+
+PNG_EXPORT(71, void, png_set_compression_strategy, (png_structrp png_ptr,
+    int strategy));
+
+/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a
+ * smaller value of window_bits if it can do so safely.
+ */
+PNG_EXPORT(72, void, png_set_compression_window_bits, (png_structrp png_ptr,
+    int window_bits));
+
+PNG_EXPORT(73, void, png_set_compression_method, (png_structrp png_ptr,
+    int method));
+#endif
+
+#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
+/* Also set zlib parameters for compressing non-IDAT chunks */
+PNG_EXPORT(222, void, png_set_text_compression_level, (png_structrp png_ptr,
+    int level));
+
+PNG_EXPORT(223, void, png_set_text_compression_mem_level, (png_structrp png_ptr,
+    int mem_level));
+
+PNG_EXPORT(224, void, png_set_text_compression_strategy, (png_structrp png_ptr,
+    int strategy));
+
+/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a
+ * smaller value of window_bits if it can do so safely.
+ */
+PNG_EXPORT(225, void, png_set_text_compression_window_bits,
+    (png_structrp png_ptr, int window_bits));
+
+PNG_EXPORT(226, void, png_set_text_compression_method, (png_structrp png_ptr,
+    int method));
+#endif /* WRITE_CUSTOMIZE_ZTXT_COMPRESSION */
+
+/* These next functions are called for input/output, memory, and error
+ * handling.  They are in the file pngrio.c, pngwio.c, and pngerror.c,
+ * and call standard C I/O routines such as fread(), fwrite(), and
+ * fprintf().  These functions can be made to use other I/O routines
+ * at run time for those applications that need to handle I/O in a
+ * different manner by calling png_set_???_fn().  See libpng-manual.txt for
+ * more information.
+ */
+
+#ifdef PNG_STDIO_SUPPORTED
+/* Initialize the input/output for the PNG file to the default functions. */
+PNG_EXPORT(74, void, png_init_io, (png_structrp png_ptr, png_FILE_p fp));
+#endif
+
+/* Replace the (error and abort), and warning functions with user
+ * supplied functions.  If no messages are to be printed you must still
+ * write and use replacement functions. The replacement error_fn should
+ * still do a longjmp to the last setjmp location if you are using this
+ * method of error handling.  If error_fn or warning_fn is NULL, the
+ * default function will be used.
+ */
+
+PNG_EXPORT(75, void, png_set_error_fn, (png_structrp png_ptr,
+    png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn));
+
+/* Return the user pointer associated with the error functions */
+PNG_EXPORT(76, png_voidp, png_get_error_ptr, (png_const_structrp png_ptr));
+
+/* Replace the default data output functions with a user supplied one(s).
+ * If buffered output is not used, then output_flush_fn can be set to NULL.
+ * If PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile time
+ * output_flush_fn will be ignored (and thus can be NULL).
+ * It is probably a mistake to use NULL for output_flush_fn if
+ * write_data_fn is not also NULL unless you have built libpng with
+ * PNG_WRITE_FLUSH_SUPPORTED undefined, because in this case libpng's
+ * default flush function, which uses the standard *FILE structure, will
+ * be used.
+ */
+PNG_EXPORT(77, void, png_set_write_fn, (png_structrp png_ptr, png_voidp io_ptr,
+    png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn));
+
+/* Replace the default data input function with a user supplied one. */
+PNG_EXPORT(78, void, png_set_read_fn, (png_structrp png_ptr, png_voidp io_ptr,
+    png_rw_ptr read_data_fn));
+
+/* Return the user pointer associated with the I/O functions */
+PNG_EXPORT(79, png_voidp, png_get_io_ptr, (png_const_structrp png_ptr));
+
+PNG_EXPORT(80, void, png_set_read_status_fn, (png_structrp png_ptr,
+    png_read_status_ptr read_row_fn));
+
+PNG_EXPORT(81, void, png_set_write_status_fn, (png_structrp png_ptr,
+    png_write_status_ptr write_row_fn));
+
+#ifdef PNG_USER_MEM_SUPPORTED
+/* Replace the default memory allocation functions with user supplied one(s). */
+PNG_EXPORT(82, void, png_set_mem_fn, (png_structrp png_ptr, png_voidp mem_ptr,
+    png_malloc_ptr malloc_fn, png_free_ptr free_fn));
+/* Return the user pointer associated with the memory functions */
+PNG_EXPORT(83, png_voidp, png_get_mem_ptr, (png_const_structrp png_ptr));
+#endif
+
+#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
+PNG_EXPORT(84, void, png_set_read_user_transform_fn, (png_structrp png_ptr,
+    png_user_transform_ptr read_user_transform_fn));
+#endif
+
+#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
+PNG_EXPORT(85, void, png_set_write_user_transform_fn, (png_structrp png_ptr,
+    png_user_transform_ptr write_user_transform_fn));
+#endif
+
+#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
+PNG_EXPORT(86, void, png_set_user_transform_info, (png_structrp png_ptr,
+    png_voidp user_transform_ptr, int user_transform_depth,
+    int user_transform_channels));
+/* Return the user pointer associated with the user transform functions */
+PNG_EXPORT(87, png_voidp, png_get_user_transform_ptr,
+    (png_const_structrp png_ptr));
+#endif
+
+#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED
+/* Return information about the row currently being processed.  Note that these
+ * APIs do not fail but will return unexpected results if called outside a user
+ * transform callback.  Also note that when transforming an interlaced image the
+ * row number is the row number within the sub-image of the interlace pass, so
+ * the value will increase to the height of the sub-image (not the full image)
+ * then reset to 0 for the next pass.
+ *
+ * Use PNG_ROW_FROM_PASS_ROW(row, pass) and PNG_COL_FROM_PASS_COL(col, pass) to
+ * find the output pixel (x,y) given an interlaced sub-image pixel
+ * (row,col,pass).  (See below for these macros.)
+ */
+PNG_EXPORT(217, png_uint_32, png_get_current_row_number, (png_const_structrp));
+PNG_EXPORT(218, png_byte, png_get_current_pass_number, (png_const_structrp));
+#endif
+
+#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
+/* This callback is called only for *unknown* chunks.  If
+ * PNG_HANDLE_AS_UNKNOWN_SUPPORTED is set then it is possible to set known
+ * chunks to be treated as unknown, however in this case the callback must do
+ * any processing required by the chunk (e.g. by calling the appropriate
+ * png_set_ APIs.)
+ *
+ * There is no write support - on write, by default, all the chunks in the
+ * 'unknown' list are written in the specified position.
+ *
+ * The integer return from the callback function is interpreted thus:
+ *
+ * negative: An error occured, png_chunk_error will be called.
+ *     zero: The chunk was not handled, the chunk will be saved. A critical
+ *           chunk will cause an error at this point unless it is to be saved.
+ * positive: The chunk was handled, libpng will ignore/discard it.
+ *
+ * See "INTERACTION WTIH USER CHUNK CALLBACKS" below for important notes about
+ * how this behavior will change in libpng 1.7
+ */
+PNG_EXPORT(88, void, png_set_read_user_chunk_fn, (png_structrp png_ptr,
+    png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn));
+#endif
+
+#ifdef PNG_USER_CHUNKS_SUPPORTED
+PNG_EXPORT(89, png_voidp, png_get_user_chunk_ptr, (png_const_structrp png_ptr));
+#endif
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+/* Sets the function callbacks for the push reader, and a pointer to a
+ * user-defined structure available to the callback functions.
+ */
+PNG_EXPORT(90, void, png_set_progressive_read_fn, (png_structrp png_ptr,
+    png_voidp progressive_ptr, png_progressive_info_ptr info_fn,
+    png_progressive_row_ptr row_fn, png_progressive_end_ptr end_fn));
+
+/* Returns the user pointer associated with the push read functions */
+PNG_EXPORT(91, png_voidp, png_get_progressive_ptr,
+    (png_const_structrp png_ptr));
+
+/* Function to be called when data becomes available */
+PNG_EXPORT(92, void, png_process_data, (png_structrp png_ptr,
+    png_inforp info_ptr, png_bytep buffer, png_size_t buffer_size));
+
+/* A function which may be called *only* within png_process_data to stop the
+ * processing of any more data.  The function returns the number of bytes
+ * remaining, excluding any that libpng has cached internally.  A subsequent
+ * call to png_process_data must supply these bytes again.  If the argument
+ * 'save' is set to true the routine will first save all the pending data and
+ * will always return 0.
+ */
+PNG_EXPORT(219, png_size_t, png_process_data_pause, (png_structrp, int save));
+
+/* A function which may be called *only* outside (after) a call to
+ * png_process_data.  It returns the number of bytes of data to skip in the
+ * input.  Normally it will return 0, but if it returns a non-zero value the
+ * application must skip than number of bytes of input data and pass the
+ * following data to the next call to png_process_data.
+ */
+PNG_EXPORT(220, png_uint_32, png_process_data_skip, (png_structrp));
+
+/* Function that combines rows.  'new_row' is a flag that should come from
+ * the callback and be non-NULL if anything needs to be done; the library
+ * stores its own version of the new data internally and ignores the passed
+ * in value.
+ */
+PNG_EXPORT(93, void, png_progressive_combine_row, (png_const_structrp png_ptr,
+    png_bytep old_row, png_const_bytep new_row));
+#endif /* PROGRESSIVE_READ */
+
+PNG_EXPORTA(94, png_voidp, png_malloc, (png_const_structrp png_ptr,
+    png_alloc_size_t size), PNG_ALLOCATED);
+/* Added at libpng version 1.4.0 */
+PNG_EXPORTA(95, png_voidp, png_calloc, (png_const_structrp png_ptr,
+    png_alloc_size_t size), PNG_ALLOCATED);
+
+/* Added at libpng version 1.2.4 */
+PNG_EXPORTA(96, png_voidp, png_malloc_warn, (png_const_structrp png_ptr,
+    png_alloc_size_t size), PNG_ALLOCATED);
+
+/* Frees a pointer allocated by png_malloc() */
+PNG_EXPORT(97, void, png_free, (png_const_structrp png_ptr, png_voidp ptr));
+
+/* Free data that was allocated internally */
+PNG_EXPORT(98, void, png_free_data, (png_const_structrp png_ptr,
+    png_inforp info_ptr, png_uint_32 free_me, int num));
+
+/* Reassign responsibility for freeing existing data, whether allocated
+ * by libpng or by the application; this works on the png_info structure passed
+ * in, it does not change the state for other png_info structures.
+ *
+ * It is unlikely that this function works correctly as of 1.6.0 and using it
+ * may result either in memory leaks or double free of allocated data.
+ */
+PNG_EXPORT(99, void, png_data_freer, (png_const_structrp png_ptr,
+    png_inforp info_ptr, int freer, png_uint_32 mask));
+
+/* Assignments for png_data_freer */
+#define PNG_DESTROY_WILL_FREE_DATA 1
+#define PNG_SET_WILL_FREE_DATA 1
+#define PNG_USER_WILL_FREE_DATA 2
+/* Flags for png_ptr->free_me and info_ptr->free_me */
+#define PNG_FREE_HIST 0x0008
+#define PNG_FREE_ICCP 0x0010
+#define PNG_FREE_SPLT 0x0020
+#define PNG_FREE_ROWS 0x0040
+#define PNG_FREE_PCAL 0x0080
+#define PNG_FREE_SCAL 0x0100
+#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
+#  define PNG_FREE_UNKN 0x0200
+#endif
+/*      PNG_FREE_LIST 0x0400    removed in 1.6.0 because it is ignored */
+#define PNG_FREE_PLTE 0x1000
+#define PNG_FREE_TRNS 0x2000
+#define PNG_FREE_TEXT 0x4000
+#define PNG_FREE_ALL  0x7fff
+#define PNG_FREE_MUL  0x4220 /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */
+
+#ifdef PNG_USER_MEM_SUPPORTED
+PNG_EXPORTA(100, png_voidp, png_malloc_default, (png_const_structrp png_ptr,
+    png_alloc_size_t size), PNG_ALLOCATED PNG_DEPRECATED);
+PNG_EXPORTA(101, void, png_free_default, (png_const_structrp png_ptr,
+    png_voidp ptr), PNG_DEPRECATED);
+#endif
+
+#ifdef PNG_ERROR_TEXT_SUPPORTED
+/* Fatal error in PNG image of libpng - can't continue */
+PNG_EXPORTA(102, void, png_error, (png_const_structrp png_ptr,
+    png_const_charp error_message), PNG_NORETURN);
+
+/* The same, but the chunk name is prepended to the error string. */
+PNG_EXPORTA(103, void, png_chunk_error, (png_const_structrp png_ptr,
+    png_const_charp error_message), PNG_NORETURN);
+
+#else
+/* Fatal error in PNG image of libpng - can't continue */
+PNG_EXPORTA(104, void, png_err, (png_const_structrp png_ptr), PNG_NORETURN);
+#  define png_error(s1,s2) png_err(s1)
+#  define png_chunk_error(s1,s2) png_err(s1)
+#endif
+
+#ifdef PNG_WARNINGS_SUPPORTED
+/* Non-fatal error in libpng.  Can continue, but may have a problem. */
+PNG_EXPORT(105, void, png_warning, (png_const_structrp png_ptr,
+    png_const_charp warning_message));
+
+/* Non-fatal error in libpng, chunk name is prepended to message. */
+PNG_EXPORT(106, void, png_chunk_warning, (png_const_structrp png_ptr,
+    png_const_charp warning_message));
+#else
+#  define png_warning(s1,s2) ((void)(s1))
+#  define png_chunk_warning(s1,s2) ((void)(s1))
+#endif
+
+#ifdef PNG_BENIGN_ERRORS_SUPPORTED
+/* Benign error in libpng.  Can continue, but may have a problem.
+ * User can choose whether to handle as a fatal error or as a warning. */
+PNG_EXPORT(107, void, png_benign_error, (png_const_structrp png_ptr,
+    png_const_charp warning_message));
+
+#ifdef PNG_READ_SUPPORTED
+/* Same, chunk name is prepended to message (only during read) */
+PNG_EXPORT(108, void, png_chunk_benign_error, (png_const_structrp png_ptr,
+    png_const_charp warning_message));
+#endif
+
+PNG_EXPORT(109, void, png_set_benign_errors,
+    (png_structrp png_ptr, int allowed));
+#else
+#  ifdef PNG_ALLOW_BENIGN_ERRORS
+#    define png_benign_error png_warning
+#    define png_chunk_benign_error png_chunk_warning
+#  else
+#    define png_benign_error png_error
+#    define png_chunk_benign_error png_chunk_error
+#  endif
+#endif
+
+/* The png_set_<chunk> functions are for storing values in the png_info_struct.
+ * Similarly, the png_get_<chunk> calls are used to read values from the
+ * png_info_struct, either storing the parameters in the passed variables, or
+ * setting pointers into the png_info_struct where the data is stored.  The
+ * png_get_<chunk> functions return a non-zero value if the data was available
+ * in info_ptr, or return zero and do not change any of the parameters if the
+ * data was not available.
+ *
+ * These functions should be used instead of directly accessing png_info
+ * to avoid problems with future changes in the size and internal layout of
+ * png_info_struct.
+ */
+/* Returns "flag" if chunk data is valid in info_ptr. */
+PNG_EXPORT(110, png_uint_32, png_get_valid, (png_const_structrp png_ptr,
+    png_const_inforp info_ptr, png_uint_32 flag));
+
+/* Returns number of bytes needed to hold a transformed row. */
+PNG_EXPORT(111, png_size_t, png_get_rowbytes, (png_const_structrp png_ptr,
+    png_const_inforp info_ptr));
+
+#ifdef PNG_INFO_IMAGE_SUPPORTED
+/* Returns row_pointers, which is an array of pointers to scanlines that was
+ * returned from png_read_png().
+ */
+PNG_EXPORT(112, png_bytepp, png_get_rows, (png_const_structrp png_ptr,
+    png_const_inforp info_ptr));
+
+/* Set row_pointers, which is an array of pointers to scanlines for use
+ * by png_write_png().
+ */
+PNG_EXPORT(113, void, png_set_rows, (png_const_structrp png_ptr,
+    png_inforp info_ptr, png_bytepp row_pointers));
+#endif
+
+/* Returns number of color channels in image. */
+PNG_EXPORT(114, png_byte, png_get_channels, (png_const_structrp png_ptr,
+    png_const_inforp info_ptr));
+
+#ifdef PNG_EASY_ACCESS_SUPPORTED
+/* Returns image width in pixels. */
+PNG_EXPORT(115, png_uint_32, png_get_image_width, (png_const_structrp png_ptr,
+    png_const_inforp info_ptr));
+
+/* Returns image height in pixels. */
+PNG_EXPORT(116, png_uint_32, png_get_image_height, (png_const_structrp png_ptr,
+    png_const_inforp info_ptr));
+
+/* Returns image bit_depth. */
+PNG_EXPORT(117, png_byte, png_get_bit_depth, (png_const_structrp png_ptr,
+    png_const_inforp info_ptr));
+
+/* Returns image color_type. */
+PNG_EXPORT(118, png_byte, png_get_color_type, (png_const_structrp png_ptr,
+    png_const_inforp info_ptr));
+
+/* Returns image filter_type. */
+PNG_EXPORT(119, png_byte, png_get_filter_type, (png_const_structrp png_ptr,
+    png_const_inforp info_ptr));
+
+/* Returns image interlace_type. */
+PNG_EXPORT(120, png_byte, png_get_interlace_type, (png_const_structrp png_ptr,
+    png_const_inforp info_ptr));
+
+/* Returns image compression_type. */
+PNG_EXPORT(121, png_byte, png_get_compression_type, (png_const_structrp png_ptr,
+    png_const_inforp info_ptr));
+
+/* Returns image resolution in pixels per meter, from pHYs chunk data. */
+PNG_EXPORT(122, png_uint_32, png_get_pixels_per_meter,
+    (png_const_structrp png_ptr, png_const_inforp info_ptr));
+PNG_EXPORT(123, png_uint_32, png_get_x_pixels_per_meter,
+    (png_const_structrp png_ptr, png_const_inforp info_ptr));
+PNG_EXPORT(124, png_uint_32, png_get_y_pixels_per_meter,
+    (png_const_structrp png_ptr, png_const_inforp info_ptr));
+
+/* Returns pixel aspect ratio, computed from pHYs chunk data.  */
+PNG_FP_EXPORT(125, float, png_get_pixel_aspect_ratio,
+    (png_const_structrp png_ptr, png_const_inforp info_ptr))
+PNG_FIXED_EXPORT(210, png_fixed_point, png_get_pixel_aspect_ratio_fixed,
+    (png_const_structrp png_ptr, png_const_inforp info_ptr))
+
+/* Returns image x, y offset in pixels or microns, from oFFs chunk data. */
+PNG_EXPORT(126, png_int_32, png_get_x_offset_pixels,
+    (png_const_structrp png_ptr, png_const_inforp info_ptr));
+PNG_EXPORT(127, png_int_32, png_get_y_offset_pixels,
+    (png_const_structrp png_ptr, png_const_inforp info_ptr));
+PNG_EXPORT(128, png_int_32, png_get_x_offset_microns,
+    (png_const_structrp png_ptr, png_const_inforp info_ptr));
+PNG_EXPORT(129, png_int_32, png_get_y_offset_microns,
+    (png_const_structrp png_ptr, png_const_inforp info_ptr));
+
+#endif /* EASY_ACCESS */
+
+#ifdef PNG_READ_SUPPORTED
+/* Returns pointer to signature string read from PNG header */
+PNG_EXPORT(130, png_const_bytep, png_get_signature, (png_const_structrp png_ptr,
+    png_const_inforp info_ptr));
+#endif
+
+#ifdef PNG_bKGD_SUPPORTED
+PNG_EXPORT(131, png_uint_32, png_get_bKGD, (png_const_structrp png_ptr,
+    png_inforp info_ptr, png_color_16p *background));
+#endif
+
+#ifdef PNG_bKGD_SUPPORTED
+PNG_EXPORT(132, void, png_set_bKGD, (png_const_structrp png_ptr,
+    png_inforp info_ptr, png_const_color_16p background));
+#endif
+
+#ifdef PNG_cHRM_SUPPORTED
+PNG_FP_EXPORT(133, png_uint_32, png_get_cHRM, (png_const_structrp png_ptr,
+    png_const_inforp info_ptr, double *white_x, double *white_y, double *red_x,
+    double *red_y, double *green_x, double *green_y, double *blue_x,
+    double *blue_y))
+PNG_FP_EXPORT(230, png_uint_32, png_get_cHRM_XYZ, (png_const_structrp png_ptr,
+    png_const_inforp info_ptr, double *red_X, double *red_Y, double *red_Z,
+    double *green_X, double *green_Y, double *green_Z, double *blue_X,
+    double *blue_Y, double *blue_Z))
+PNG_FIXED_EXPORT(134, png_uint_32, png_get_cHRM_fixed,
+    (png_const_structrp png_ptr, png_const_inforp info_ptr,
+    png_fixed_point *int_white_x, png_fixed_point *int_white_y,
+    png_fixed_point *int_red_x, png_fixed_point *int_red_y,
+    png_fixed_point *int_green_x, png_fixed_point *int_green_y,
+    png_fixed_point *int_blue_x, png_fixed_point *int_blue_y))
+PNG_FIXED_EXPORT(231, png_uint_32, png_get_cHRM_XYZ_fixed,
+    (png_const_structrp png_ptr, png_const_inforp info_ptr,
+    png_fixed_point *int_red_X, png_fixed_point *int_red_Y,
+    png_fixed_point *int_red_Z, png_fixed_point *int_green_X,
+    png_fixed_point *int_green_Y, png_fixed_point *int_green_Z,
+    png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y,
+    png_fixed_point *int_blue_Z))
+#endif
+
+#ifdef PNG_cHRM_SUPPORTED
+PNG_FP_EXPORT(135, void, png_set_cHRM, (png_const_structrp png_ptr,
+    png_inforp info_ptr,
+    double white_x, double white_y, double red_x, double red_y, double green_x,
+    double green_y, double blue_x, double blue_y))
+PNG_FP_EXPORT(232, void, png_set_cHRM_XYZ, (png_const_structrp png_ptr,
+    png_inforp info_ptr, double red_X, double red_Y, double red_Z,
+    double green_X, double green_Y, double green_Z, double blue_X,
+    double blue_Y, double blue_Z))
+PNG_FIXED_EXPORT(136, void, png_set_cHRM_fixed, (png_const_structrp png_ptr,
+    png_inforp info_ptr, png_fixed_point int_white_x,
+    png_fixed_point int_white_y, png_fixed_point int_red_x,
+    png_fixed_point int_red_y, png_fixed_point int_green_x,
+    png_fixed_point int_green_y, png_fixed_point int_blue_x,
+    png_fixed_point int_blue_y))
+PNG_FIXED_EXPORT(233, void, png_set_cHRM_XYZ_fixed, (png_const_structrp png_ptr,
+    png_inforp info_ptr, png_fixed_point int_red_X, png_fixed_point int_red_Y,
+    png_fixed_point int_red_Z, png_fixed_point int_green_X,
+    png_fixed_point int_green_Y, png_fixed_point int_green_Z,
+    png_fixed_point int_blue_X, png_fixed_point int_blue_Y,
+    png_fixed_point int_blue_Z))
+#endif
+
+#ifdef PNG_gAMA_SUPPORTED
+PNG_FP_EXPORT(137, png_uint_32, png_get_gAMA, (png_const_structrp png_ptr,
+    png_const_inforp info_ptr, double *file_gamma))
+PNG_FIXED_EXPORT(138, png_uint_32, png_get_gAMA_fixed,
+    (png_const_structrp png_ptr, png_const_inforp info_ptr,
+    png_fixed_point *int_file_gamma))
+#endif
+
+#ifdef PNG_gAMA_SUPPORTED
+PNG_FP_EXPORT(139, void, png_set_gAMA, (png_const_structrp png_ptr,
+    png_inforp info_ptr, double file_gamma))
+PNG_FIXED_EXPORT(140, void, png_set_gAMA_fixed, (png_const_structrp png_ptr,
+    png_inforp info_ptr, png_fixed_point int_file_gamma))
+#endif
+
+#ifdef PNG_hIST_SUPPORTED
+PNG_EXPORT(141, png_uint_32, png_get_hIST, (png_const_structrp png_ptr,
+    png_inforp info_ptr, png_uint_16p *hist));
+#endif
+
+#ifdef PNG_hIST_SUPPORTED
+PNG_EXPORT(142, void, png_set_hIST, (png_const_structrp png_ptr,
+    png_inforp info_ptr, png_const_uint_16p hist));
+#endif
+
+PNG_EXPORT(143, png_uint_32, png_get_IHDR, (png_const_structrp png_ptr,
+    png_const_inforp info_ptr, png_uint_32 *width, png_uint_32 *height,
+    int *bit_depth, int *color_type, int *interlace_method,
+    int *compression_method, int *filter_method));
+
+PNG_EXPORT(144, void, png_set_IHDR, (png_const_structrp png_ptr,
+    png_inforp info_ptr, png_uint_32 width, png_uint_32 height, int bit_depth,
+    int color_type, int interlace_method, int compression_method,
+    int filter_method));
+
+#ifdef PNG_oFFs_SUPPORTED
+PNG_EXPORT(145, png_uint_32, png_get_oFFs, (png_const_structrp png_ptr,
+   png_const_inforp info_ptr, png_int_32 *offset_x, png_int_32 *offset_y,
+   int *unit_type));
+#endif
+
+#ifdef PNG_oFFs_SUPPORTED
+PNG_EXPORT(146, void, png_set_oFFs, (png_const_structrp png_ptr,
+    png_inforp info_ptr, png_int_32 offset_x, png_int_32 offset_y,
+    int unit_type));
+#endif
+
+#ifdef PNG_pCAL_SUPPORTED
+PNG_EXPORT(147, png_uint_32, png_get_pCAL, (png_const_structrp png_ptr,
+    png_inforp info_ptr, png_charp *purpose, png_int_32 *X0,
+    png_int_32 *X1, int *type, int *nparams, png_charp *units,
+    png_charpp *params));
+#endif
+
+#ifdef PNG_pCAL_SUPPORTED
+PNG_EXPORT(148, void, png_set_pCAL, (png_const_structrp png_ptr,
+    png_inforp info_ptr, png_const_charp purpose, png_int_32 X0, png_int_32 X1,
+    int type, int nparams, png_const_charp units, png_charpp params));
+#endif
+
+#ifdef PNG_pHYs_SUPPORTED
+PNG_EXPORT(149, png_uint_32, png_get_pHYs, (png_const_structrp png_ptr,
+    png_const_inforp info_ptr, png_uint_32 *res_x, png_uint_32 *res_y,
+    int *unit_type));
+#endif
+
+#ifdef PNG_pHYs_SUPPORTED
+PNG_EXPORT(150, void, png_set_pHYs, (png_const_structrp png_ptr,
+    png_inforp info_ptr, png_uint_32 res_x, png_uint_32 res_y, int unit_type));
+#endif
+
+PNG_EXPORT(151, png_uint_32, png_get_PLTE, (png_const_structrp png_ptr,
+   png_inforp info_ptr, png_colorp *palette, int *num_palette));
+
+PNG_EXPORT(152, void, png_set_PLTE, (png_structrp png_ptr,
+    png_inforp info_ptr, png_const_colorp palette, int num_palette));
+
+#ifdef PNG_sBIT_SUPPORTED
+PNG_EXPORT(153, png_uint_32, png_get_sBIT, (png_const_structrp png_ptr,
+    png_inforp info_ptr, png_color_8p *sig_bit));
+#endif
+
+#ifdef PNG_sBIT_SUPPORTED
+PNG_EXPORT(154, void, png_set_sBIT, (png_const_structrp png_ptr,
+    png_inforp info_ptr, png_const_color_8p sig_bit));
+#endif
+
+#ifdef PNG_sRGB_SUPPORTED
+PNG_EXPORT(155, png_uint_32, png_get_sRGB, (png_const_structrp png_ptr,
+    png_const_inforp info_ptr, int *file_srgb_intent));
+#endif
+
+#ifdef PNG_sRGB_SUPPORTED
+PNG_EXPORT(156, void, png_set_sRGB, (png_const_structrp png_ptr,
+    png_inforp info_ptr, int srgb_intent));
+PNG_EXPORT(157, void, png_set_sRGB_gAMA_and_cHRM, (png_const_structrp png_ptr,
+    png_inforp info_ptr, int srgb_intent));
+#endif
+
+#ifdef PNG_iCCP_SUPPORTED
+PNG_EXPORT(158, png_uint_32, png_get_iCCP, (png_const_structrp png_ptr,
+    png_inforp info_ptr, png_charpp name, int *compression_type,
+    png_bytepp profile, png_uint_32 *proflen));
+#endif
+
+#ifdef PNG_iCCP_SUPPORTED
+PNG_EXPORT(159, void, png_set_iCCP, (png_const_structrp png_ptr,
+    png_inforp info_ptr, png_const_charp name, int compression_type,
+    png_const_bytep profile, png_uint_32 proflen));
+#endif
+
+#ifdef PNG_sPLT_SUPPORTED
+PNG_EXPORT(160, int, png_get_sPLT, (png_const_structrp png_ptr,
+    png_inforp info_ptr, png_sPLT_tpp entries));
+#endif
+
+#ifdef PNG_sPLT_SUPPORTED
+PNG_EXPORT(161, void, png_set_sPLT, (png_const_structrp png_ptr,
+    png_inforp info_ptr, png_const_sPLT_tp entries, int nentries));
+#endif
+
+#ifdef PNG_TEXT_SUPPORTED
+/* png_get_text also returns the number of text chunks in *num_text */
+PNG_EXPORT(162, int, png_get_text, (png_const_structrp png_ptr,
+    png_inforp info_ptr, png_textp *text_ptr, int *num_text));
+#endif
+
+/* Note while png_set_text() will accept a structure whose text,
+ * language, and  translated keywords are NULL pointers, the structure
+ * returned by png_get_text will always contain regular
+ * zero-terminated C strings.  They might be empty strings but
+ * they will never be NULL pointers.
+ */
+
+#ifdef PNG_TEXT_SUPPORTED
+PNG_EXPORT(163, void, png_set_text, (png_const_structrp png_ptr,
+    png_inforp info_ptr, png_const_textp text_ptr, int num_text));
+#endif
+
+#ifdef PNG_tIME_SUPPORTED
+PNG_EXPORT(164, png_uint_32, png_get_tIME, (png_const_structrp png_ptr,
+    png_inforp info_ptr, png_timep *mod_time));
+#endif
+
+#ifdef PNG_tIME_SUPPORTED
+PNG_EXPORT(165, void, png_set_tIME, (png_const_structrp png_ptr,
+    png_inforp info_ptr, png_const_timep mod_time));
+#endif
+
+#ifdef PNG_tRNS_SUPPORTED
+PNG_EXPORT(166, png_uint_32, png_get_tRNS, (png_const_structrp png_ptr,
+    png_inforp info_ptr, png_bytep *trans_alpha, int *num_trans,
+    png_color_16p *trans_color));
+#endif
+
+#ifdef PNG_tRNS_SUPPORTED
+PNG_EXPORT(167, void, png_set_tRNS, (png_structrp png_ptr,
+    png_inforp info_ptr, png_const_bytep trans_alpha, int num_trans,
+    png_const_color_16p trans_color));
+#endif
+
+#ifdef PNG_sCAL_SUPPORTED
+PNG_FP_EXPORT(168, png_uint_32, png_get_sCAL, (png_const_structrp png_ptr,
+    png_const_inforp info_ptr, int *unit, double *width, double *height))
+#if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || \
+   defined(PNG_FLOATING_POINT_SUPPORTED)
+/* NOTE: this API is currently implemented using floating point arithmetic,
+ * consequently it can only be used on systems with floating point support.
+ * In any case the range of values supported by png_fixed_point is small and it
+ * is highly recommended that png_get_sCAL_s be used instead.
+ */
+PNG_FIXED_EXPORT(214, png_uint_32, png_get_sCAL_fixed,
+    (png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit,
+    png_fixed_point *width, png_fixed_point *height))
+#endif
+PNG_EXPORT(169, png_uint_32, png_get_sCAL_s,
+    (png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit,
+    png_charpp swidth, png_charpp sheight));
+
+PNG_FP_EXPORT(170, void, png_set_sCAL, (png_const_structrp png_ptr,
+    png_inforp info_ptr, int unit, double width, double height))
+PNG_FIXED_EXPORT(213, void, png_set_sCAL_fixed, (png_const_structrp png_ptr,
+   png_inforp info_ptr, int unit, png_fixed_point width,
+   png_fixed_point height))
+PNG_EXPORT(171, void, png_set_sCAL_s, (png_const_structrp png_ptr,
+    png_inforp info_ptr, int unit,
+    png_const_charp swidth, png_const_charp sheight));
+#endif /* sCAL */
+
+#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
+/* Provide the default handling for all unknown chunks or, optionally, for
+ * specific unknown chunks.
+ *
+ * NOTE: prior to 1.6.0 the handling specified for particular chunks on read was
+ * ignored and the default was used, the per-chunk setting only had an effect on
+ * write.  If you wish to have chunk-specific handling on read in code that must
+ * work on earlier versions you must use a user chunk callback to specify the
+ * desired handling (keep or discard.)
+ *
+ * The 'keep' parameter is a PNG_HANDLE_CHUNK_ value as listed below.  The
+ * parameter is interpreted as follows:
+ *
+ * READ:
+ *    PNG_HANDLE_CHUNK_AS_DEFAULT:
+ *       Known chunks: do normal libpng processing, do not keep the chunk (but
+ *          see the comments below about PNG_HANDLE_AS_UNKNOWN_SUPPORTED)
+ *       Unknown chunks: for a specific chunk use the global default, when used
+ *          as the default discard the chunk data.
+ *    PNG_HANDLE_CHUNK_NEVER:
+ *       Discard the chunk data.
+ *    PNG_HANDLE_CHUNK_IF_SAFE:
+ *       Keep the chunk data if the chunk is not critical else raise a chunk
+ *       error.
+ *    PNG_HANDLE_CHUNK_ALWAYS:
+ *       Keep the chunk data.
+ *
+ * If the chunk data is saved it can be retrieved using png_get_unknown_chunks,
+ * below.  Notice that specifying "AS_DEFAULT" as a global default is equivalent
+ * to specifying "NEVER", however when "AS_DEFAULT" is used for specific chunks
+ * it simply resets the behavior to the libpng default.
+ *
+ * INTERACTION WTIH USER CHUNK CALLBACKS:
+ * The per-chunk handling is always used when there is a png_user_chunk_ptr
+ * callback and the callback returns 0; the chunk is then always stored *unless*
+ * it is critical and the per-chunk setting is other than ALWAYS.  Notice that
+ * the global default is *not* used in this case.  (In effect the per-chunk
+ * value is incremented to at least IF_SAFE.)
+ *
+ * IMPORTANT NOTE: this behavior will change in libpng 1.7 - the global and
+ * per-chunk defaults will be honored.  If you want to preserve the current
+ * behavior when your callback returns 0 you must set PNG_HANDLE_CHUNK_IF_SAFE
+ * as the default - if you don't do this libpng 1.6 will issue a warning.
+ *
+ * If you want unhandled unknown chunks to be discarded in libpng 1.6 and
+ * earlier simply return '1' (handled).
+ *
+ * PNG_HANDLE_AS_UNKNOWN_SUPPORTED:
+ *    If this is *not* set known chunks will always be handled by libpng and
+ *    will never be stored in the unknown chunk list.  Known chunks listed to
+ *    png_set_keep_unknown_chunks will have no effect.  If it is set then known
+ *    chunks listed with a keep other than AS_DEFAULT will *never* be processed
+ *    by libpng, in addition critical chunks must either be processed by the
+ *    callback or saved.
+ *
+ *    The IHDR and IEND chunks must not be listed.  Because this turns off the
+ *    default handling for chunks that would otherwise be recognized the
+ *    behavior of libpng transformations may well become incorrect!
+ *
+ * WRITE:
+ *    When writing chunks the options only apply to the chunks specified by
+ *    png_set_unknown_chunks (below), libpng will *always* write known chunks
+ *    required by png_set_ calls and will always write the core critical chunks
+ *    (as required for PLTE).
+ *
+ *    Each chunk in the png_set_unknown_chunks list is looked up in the
+ *    png_set_keep_unknown_chunks list to find the keep setting, this is then
+ *    interpreted as follows:
+ *
+ *    PNG_HANDLE_CHUNK_AS_DEFAULT:
+ *       Write safe-to-copy chunks and write other chunks if the global
+ *       default is set to _ALWAYS, otherwise don't write this chunk.
+ *    PNG_HANDLE_CHUNK_NEVER:
+ *       Do not write the chunk.
+ *    PNG_HANDLE_CHUNK_IF_SAFE:
+ *       Write the chunk if it is safe-to-copy, otherwise do not write it.
+ *    PNG_HANDLE_CHUNK_ALWAYS:
+ *       Write the chunk.
+ *
+ * Note that the default behavior is effectively the opposite of the read case -
+ * in read unknown chunks are not stored by default, in write they are written
+ * by default.  Also the behavior of PNG_HANDLE_CHUNK_IF_SAFE is very different
+ * - on write the safe-to-copy bit is checked, on read the critical bit is
+ * checked and on read if the chunk is critical an error will be raised.
+ *
+ * num_chunks:
+ * ===========
+ *    If num_chunks is positive, then the "keep" parameter specifies the manner
+ *    for handling only those chunks appearing in the chunk_list array,
+ *    otherwise the chunk list array is ignored.
+ *
+ *    If num_chunks is 0 the "keep" parameter specifies the default behavior for
+ *    unknown chunks, as described above.
+ *
+ *    If num_chunks is negative, then the "keep" parameter specifies the manner
+ *    for handling all unknown chunks plus all chunks recognized by libpng
+ *    except for the IHDR, PLTE, tRNS, IDAT, and IEND chunks (which continue to
+ *    be processed by libpng.
+ */
+PNG_EXPORT(172, void, png_set_keep_unknown_chunks, (png_structrp png_ptr,
+    int keep, png_const_bytep chunk_list, int num_chunks));
+
+/* The "keep" PNG_HANDLE_CHUNK_ parameter for the specified chunk is returned;
+ * the result is therefore true (non-zero) if special handling is required,
+ * false for the default handling.
+ */
+PNG_EXPORT(173, int, png_handle_as_unknown, (png_const_structrp png_ptr,
+    png_const_bytep chunk_name));
+#endif
+
+#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
+PNG_EXPORT(174, void, png_set_unknown_chunks, (png_const_structrp png_ptr,
+    png_inforp info_ptr, png_const_unknown_chunkp unknowns,
+    int num_unknowns));
+   /* NOTE: prior to 1.6.0 this routine set the 'location' field of the added
+    * unknowns to the location currently stored in the png_struct.  This is
+    * invariably the wrong value on write.  To fix this call the following API
+    * for each chunk in the list with the correct location.  If you know your
+    * code won't be compiled on earlier versions you can rely on
+    * png_set_unknown_chunks(write-ptr, png_get_unknown_chunks(read-ptr)) doing
+    * the correct thing.
+    */
+
+PNG_EXPORT(175, void, png_set_unknown_chunk_location,
+    (png_const_structrp png_ptr, png_inforp info_ptr, int chunk, int location));
+
+PNG_EXPORT(176, int, png_get_unknown_chunks, (png_const_structrp png_ptr,
+    png_inforp info_ptr, png_unknown_chunkpp entries));
+#endif
+
+/* Png_free_data() will turn off the "valid" flag for anything it frees.
+ * If you need to turn it off for a chunk that your application has freed,
+ * you can use png_set_invalid(png_ptr, info_ptr, PNG_INFO_CHNK);
+ */
+PNG_EXPORT(177, void, png_set_invalid, (png_const_structrp png_ptr,
+    png_inforp info_ptr, int mask));
+
+#ifdef PNG_INFO_IMAGE_SUPPORTED
+/* The "params" pointer is currently not used and is for future expansion. */
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+PNG_EXPORT(178, void, png_read_png, (png_structrp png_ptr, png_inforp info_ptr,
+    int transforms, png_voidp params));
+#endif
+#ifdef PNG_WRITE_SUPPORTED
+PNG_EXPORT(179, void, png_write_png, (png_structrp png_ptr, png_inforp info_ptr,
+    int transforms, png_voidp params));
+#endif
+#endif
+
+PNG_EXPORT(180, png_const_charp, png_get_copyright,
+    (png_const_structrp png_ptr));
+PNG_EXPORT(181, png_const_charp, png_get_header_ver,
+    (png_const_structrp png_ptr));
+PNG_EXPORT(182, png_const_charp, png_get_header_version,
+    (png_const_structrp png_ptr));
+PNG_EXPORT(183, png_const_charp, png_get_libpng_ver,
+    (png_const_structrp png_ptr));
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+PNG_EXPORT(184, png_uint_32, png_permit_mng_features, (png_structrp png_ptr,
+    png_uint_32 mng_features_permitted));
+#endif
+
+/* For use in png_set_keep_unknown, added to version 1.2.6 */
+#define PNG_HANDLE_CHUNK_AS_DEFAULT   0
+#define PNG_HANDLE_CHUNK_NEVER        1
+#define PNG_HANDLE_CHUNK_IF_SAFE      2
+#define PNG_HANDLE_CHUNK_ALWAYS       3
+#define PNG_HANDLE_CHUNK_LAST         4
+
+/* Strip the prepended error numbers ("#nnn ") from error and warning
+ * messages before passing them to the error or warning handler.
+ */
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+PNG_EXPORT(185, void, png_set_strip_error_numbers, (png_structrp png_ptr,
+    png_uint_32 strip_mode));
+#endif
+
+/* Added in libpng-1.2.6 */
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+PNG_EXPORT(186, void, png_set_user_limits, (png_structrp png_ptr,
+    png_uint_32 user_width_max, png_uint_32 user_height_max));
+PNG_EXPORT(187, png_uint_32, png_get_user_width_max,
+    (png_const_structrp png_ptr));
+PNG_EXPORT(188, png_uint_32, png_get_user_height_max,
+    (png_const_structrp png_ptr));
+/* Added in libpng-1.4.0 */
+PNG_EXPORT(189, void, png_set_chunk_cache_max, (png_structrp png_ptr,
+    png_uint_32 user_chunk_cache_max));
+PNG_EXPORT(190, png_uint_32, png_get_chunk_cache_max,
+    (png_const_structrp png_ptr));
+/* Added in libpng-1.4.1 */
+PNG_EXPORT(191, void, png_set_chunk_malloc_max, (png_structrp png_ptr,
+    png_alloc_size_t user_chunk_cache_max));
+PNG_EXPORT(192, png_alloc_size_t, png_get_chunk_malloc_max,
+    (png_const_structrp png_ptr));
+#endif
+
+#if defined(PNG_INCH_CONVERSIONS_SUPPORTED)
+PNG_EXPORT(193, png_uint_32, png_get_pixels_per_inch,
+    (png_const_structrp png_ptr, png_const_inforp info_ptr));
+
+PNG_EXPORT(194, png_uint_32, png_get_x_pixels_per_inch,
+    (png_const_structrp png_ptr, png_const_inforp info_ptr));
+
+PNG_EXPORT(195, png_uint_32, png_get_y_pixels_per_inch,
+    (png_const_structrp png_ptr, png_const_inforp info_ptr));
+
+PNG_FP_EXPORT(196, float, png_get_x_offset_inches,
+    (png_const_structrp png_ptr, png_const_inforp info_ptr))
+#ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */
+PNG_FIXED_EXPORT(211, png_fixed_point, png_get_x_offset_inches_fixed,
+    (png_const_structrp png_ptr, png_const_inforp info_ptr))
+#endif
+
+PNG_FP_EXPORT(197, float, png_get_y_offset_inches, (png_const_structrp png_ptr,
+    png_const_inforp info_ptr))
+#ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */
+PNG_FIXED_EXPORT(212, png_fixed_point, png_get_y_offset_inches_fixed,
+    (png_const_structrp png_ptr, png_const_inforp info_ptr))
+#endif
+
+#  ifdef PNG_pHYs_SUPPORTED
+PNG_EXPORT(198, png_uint_32, png_get_pHYs_dpi, (png_const_structrp png_ptr,
+    png_const_inforp info_ptr, png_uint_32 *res_x, png_uint_32 *res_y,
+    int *unit_type));
+#  endif /* pHYs */
+#endif  /* INCH_CONVERSIONS */
+
+/* Added in libpng-1.4.0 */
+#ifdef PNG_IO_STATE_SUPPORTED
+PNG_EXPORT(199, png_uint_32, png_get_io_state, (png_const_structrp png_ptr));
+
+/* Removed from libpng 1.6; use png_get_io_chunk_type. */
+PNG_REMOVED(200, png_const_bytep, png_get_io_chunk_name, (png_structrp png_ptr),
+    PNG_DEPRECATED)
+
+PNG_EXPORT(216, png_uint_32, png_get_io_chunk_type,
+    (png_const_structrp png_ptr));
+
+/* The flags returned by png_get_io_state() are the following: */
+#  define PNG_IO_NONE        0x0000   /* no I/O at this moment */
+#  define PNG_IO_READING     0x0001   /* currently reading */
+#  define PNG_IO_WRITING     0x0002   /* currently writing */
+#  define PNG_IO_SIGNATURE   0x0010   /* currently at the file signature */
+#  define PNG_IO_CHUNK_HDR   0x0020   /* currently at the chunk header */
+#  define PNG_IO_CHUNK_DATA  0x0040   /* currently at the chunk data */
+#  define PNG_IO_CHUNK_CRC   0x0080   /* currently at the chunk crc */
+#  define PNG_IO_MASK_OP     0x000f   /* current operation: reading/writing */
+#  define PNG_IO_MASK_LOC    0x00f0   /* current location: sig/hdr/data/crc */
+#endif /* IO_STATE */
+
+/* Interlace support.  The following macros are always defined so that if
+ * libpng interlace handling is turned off the macros may be used to handle
+ * interlaced images within the application.
+ */
+#define PNG_INTERLACE_ADAM7_PASSES 7
+
+/* Two macros to return the first row and first column of the original,
+ * full, image which appears in a given pass.  'pass' is in the range 0
+ * to 6 and the result is in the range 0 to 7.
+ */
+#define PNG_PASS_START_ROW(pass) (((1&~(pass))<<(3-((pass)>>1)))&7)
+#define PNG_PASS_START_COL(pass) (((1& (pass))<<(3-(((pass)+1)>>1)))&7)
+
+/* A macro to return the offset between pixels in the output row for a pair of
+ * pixels in the input - effectively the inverse of the 'COL_SHIFT' macro that
+ * follows.  Note that ROW_OFFSET is the offset from one row to the next whereas
+ * COL_OFFSET is from one column to the next, within a row.
+ */
+#define PNG_PASS_ROW_OFFSET(pass) ((pass)>2?(8>>(((pass)-1)>>1)):8)
+#define PNG_PASS_COL_OFFSET(pass) (1<<((7-(pass))>>1))
+
+/* Two macros to help evaluate the number of rows or columns in each
+ * pass.  This is expressed as a shift - effectively log2 of the number or
+ * rows or columns in each 8x8 tile of the original image.
+ */
+#define PNG_PASS_ROW_SHIFT(pass) ((pass)>2?(8-(pass))>>1:3)
+#define PNG_PASS_COL_SHIFT(pass) ((pass)>1?(7-(pass))>>1:3)
+
+/* Hence two macros to determine the number of rows or columns in a given
+ * pass of an image given its height or width.  In fact these macros may
+ * return non-zero even though the sub-image is empty, because the other
+ * dimension may be empty for a small image.
+ */
+#define PNG_PASS_ROWS(height, pass) (((height)+(((1<<PNG_PASS_ROW_SHIFT(pass))\
+   -1)-PNG_PASS_START_ROW(pass)))>>PNG_PASS_ROW_SHIFT(pass))
+#define PNG_PASS_COLS(width, pass) (((width)+(((1<<PNG_PASS_COL_SHIFT(pass))\
+   -1)-PNG_PASS_START_COL(pass)))>>PNG_PASS_COL_SHIFT(pass))
+
+/* For the reader row callbacks (both progressive and sequential) it is
+ * necessary to find the row in the output image given a row in an interlaced
+ * image, so two more macros:
+ */
+#define PNG_ROW_FROM_PASS_ROW(y_in, pass) \
+   (((y_in)<<PNG_PASS_ROW_SHIFT(pass))+PNG_PASS_START_ROW(pass))
+#define PNG_COL_FROM_PASS_COL(x_in, pass) \
+   (((x_in)<<PNG_PASS_COL_SHIFT(pass))+PNG_PASS_START_COL(pass))
+
+/* Two macros which return a boolean (0 or 1) saying whether the given row
+ * or column is in a particular pass.  These use a common utility macro that
+ * returns a mask for a given pass - the offset 'off' selects the row or
+ * column version.  The mask has the appropriate bit set for each column in
+ * the tile.
+ */
+#define PNG_PASS_MASK(pass,off) ( \
+   ((0x110145AF>>(((7-(off))-(pass))<<2)) & 0xF) | \
+   ((0x01145AF0>>(((7-(off))-(pass))<<2)) & 0xF0))
+
+#define PNG_ROW_IN_INTERLACE_PASS(y, pass) \
+   ((PNG_PASS_MASK(pass,0) >> ((y)&7)) & 1)
+#define PNG_COL_IN_INTERLACE_PASS(x, pass) \
+   ((PNG_PASS_MASK(pass,1) >> ((x)&7)) & 1)
+
+#ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED
+/* With these routines we avoid an integer divide, which will be slower on
+ * most machines.  However, it does take more operations than the corresponding
+ * divide method, so it may be slower on a few RISC systems.  There are two
+ * shifts (by 8 or 16 bits) and an addition, versus a single integer divide.
+ *
+ * Note that the rounding factors are NOT supposed to be the same!  128 and
+ * 32768 are correct for the NODIV code; 127 and 32767 are correct for the
+ * standard method.
+ *
+ * [Optimized code by Greg Roelofs and Mark Adler...blame us for bugs. :-) ]
+ */
+
+ /* fg and bg should be in `gamma 1.0' space; alpha is the opacity */
+
+#  define png_composite(composite, fg, alpha, bg)         \
+     { png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) \
+           * (png_uint_16)(alpha)                         \
+           + (png_uint_16)(bg)*(png_uint_16)(255          \
+           - (png_uint_16)(alpha)) + 128);                \
+       (composite) = (png_byte)((temp + (temp >> 8)) >> 8); }
+
+#  define png_composite_16(composite, fg, alpha, bg)       \
+     { png_uint_32 temp = (png_uint_32)((png_uint_32)(fg)  \
+           * (png_uint_32)(alpha)                          \
+           + (png_uint_32)(bg)*(65535                      \
+           - (png_uint_32)(alpha)) + 32768);               \
+       (composite) = (png_uint_16)((temp + (temp >> 16)) >> 16); }
+
+#else  /* Standard method using integer division */
+
+#  define png_composite(composite, fg, alpha, bg)                          \
+     (composite) = (png_byte)(((png_uint_16)(fg) * (png_uint_16)(alpha) +  \
+     (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) +       \
+     127) / 255)
+
+#  define png_composite_16(composite, fg, alpha, bg)                         \
+     (composite) = (png_uint_16)(((png_uint_32)(fg) * (png_uint_32)(alpha) + \
+     (png_uint_32)(bg)*(png_uint_32)(65535 - (png_uint_32)(alpha)) +         \
+     32767) / 65535)
+#endif /* READ_COMPOSITE_NODIV */
+
+#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED
+PNG_EXPORT(201, png_uint_32, png_get_uint_32, (png_const_bytep buf));
+PNG_EXPORT(202, png_uint_16, png_get_uint_16, (png_const_bytep buf));
+PNG_EXPORT(203, png_int_32, png_get_int_32, (png_const_bytep buf));
+#endif
+
+PNG_EXPORT(204, png_uint_32, png_get_uint_31, (png_const_structrp png_ptr,
+    png_const_bytep buf));
+/* No png_get_int_16 -- may be added if there's a real need for it. */
+
+/* Place a 32-bit number into a buffer in PNG byte order (big-endian). */
+#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED
+PNG_EXPORT(205, void, png_save_uint_32, (png_bytep buf, png_uint_32 i));
+#endif
+#ifdef PNG_SAVE_INT_32_SUPPORTED
+PNG_EXPORT(206, void, png_save_int_32, (png_bytep buf, png_int_32 i));
+#endif
+
+/* Place a 16-bit number into a buffer in PNG byte order.
+ * The parameter is declared unsigned int, not png_uint_16,
+ * just to avoid potential problems on pre-ANSI C compilers.
+ */
+#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED
+PNG_EXPORT(207, void, png_save_uint_16, (png_bytep buf, unsigned int i));
+/* No png_save_int_16 -- may be added if there's a real need for it. */
+#endif
+
+#ifdef PNG_USE_READ_MACROS
+/* Inline macros to do direct reads of bytes from the input buffer.
+ * The png_get_int_32() routine assumes we are using two's complement
+ * format for negative values, which is almost certainly true.
+ */
+#  define PNG_get_uint_32(buf) \
+     (((png_uint_32)(*(buf)) << 24) + \
+      ((png_uint_32)(*((buf) + 1)) << 16) + \
+      ((png_uint_32)(*((buf) + 2)) << 8) + \
+      ((png_uint_32)(*((buf) + 3))))
+
+   /* From libpng-1.4.0 until 1.4.4, the png_get_uint_16 macro (but not the
+    * function) incorrectly returned a value of type png_uint_32.
+    */
+#  define PNG_get_uint_16(buf) \
+     ((png_uint_16) \
+      (((unsigned int)(*(buf)) << 8) + \
+       ((unsigned int)(*((buf) + 1)))))
+
+#  define PNG_get_int_32(buf) \
+     ((png_int_32)((*(buf) & 0x80) \
+      ? -((png_int_32)((png_get_uint_32(buf) ^ 0xffffffffL) + 1)) \
+      : (png_int_32)png_get_uint_32(buf)))
+
+   /* If PNG_PREFIX is defined the same thing as below happens in pnglibconf.h,
+    * but defining a macro name prefixed with PNG_PREFIX.
+    */
+#  ifndef PNG_PREFIX
+#     define png_get_uint_32(buf) PNG_get_uint_32(buf)
+#     define png_get_uint_16(buf) PNG_get_uint_16(buf)
+#     define png_get_int_32(buf)  PNG_get_int_32(buf)
+#  endif
+#else
+#  ifdef PNG_PREFIX
+      /* No macros; revert to the (redefined) function */
+#     define PNG_get_uint_32 (png_get_uint_32)
+#     define PNG_get_uint_16 (png_get_uint_16)
+#     define PNG_get_int_32  (png_get_int_32)
+#  endif
+#endif
+
+#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) || \
+    defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
+/*******************************************************************************
+ *  SIMPLIFIED API
+ *******************************************************************************
+ *
+ * Please read the documentation in libpng-manual.txt (TODO: write said
+ * documentation) if you don't understand what follows.
+ *
+ * The simplified API hides the details of both libpng and the PNG file format
+ * itself.  It allows PNG files to be read into a very limited number of
+ * in-memory bitmap formats or to be written from the same formats.  If these
+ * formats do not accomodate your needs then you can, and should, use the more
+ * sophisticated APIs above - these support a wide variety of in-memory formats
+ * and a wide variety of sophisticated transformations to those formats as well
+ * as a wide variety of APIs to manipulate ancillary information.
+ *
+ * To read a PNG file using the simplified API:
+ *
+ * 1) Declare a 'png_image' structure (see below) on the stack and set the
+ *    version field to PNG_IMAGE_VERSION.
+ * 2) Call the appropriate png_image_begin_read... function.
+ * 3) Set the png_image 'format' member to the required sample format.
+ * 4) Allocate a buffer for the image and, if required, the color-map.
+ * 5) Call png_image_finish_read to read the image and, if required, the
+ *    color-map into your buffers.
+ *
+ * There are no restrictions on the format of the PNG input itself; all valid
+ * color types, bit depths, and interlace methods are acceptable, and the
+ * input image is transformed as necessary to the requested in-memory format
+ * during the png_image_finish_read() step.  The only caveat is that if you
+ * request a color-mapped image from a PNG that is full-color or makes
+ * complex use of an alpha channel the transformation is extremely lossy and the
+ * result may look terrible.
+ *
+ * To write a PNG file using the simplified API:
+ *
+ * 1) Declare a 'png_image' structure on the stack and memset() it to all zero.
+ * 2) Initialize the members of the structure that describe the image, setting
+ *    the 'format' member to the format of the image samples.
+ * 3) Call the appropriate png_image_write... function with a pointer to the
+ *    image and, if necessary, the color-map to write the PNG data.
+ *
+ * png_image is a structure that describes the in-memory format of an image
+ * when it is being read or defines the in-memory format of an image that you
+ * need to write:
+ */
+#define PNG_IMAGE_VERSION 1
+
+typedef struct png_control *png_controlp;
+typedef struct
+{
+   png_controlp opaque;    /* Initialize to NULL, free with png_image_free */
+   png_uint_32  version;   /* Set to PNG_IMAGE_VERSION */
+   png_uint_32  width;     /* Image width in pixels (columns) */
+   png_uint_32  height;    /* Image height in pixels (rows) */
+   png_uint_32  format;    /* Image format as defined below */
+   png_uint_32  flags;     /* A bit mask containing informational flags */
+   png_uint_32  colormap_entries;
+                           /* Number of entries in the color-map */
+
+   /* In the event of an error or warning the following field will be set to a
+    * non-zero value and the 'message' field will contain a '\0' terminated
+    * string with the libpng error or warning message.  If both warnings and
+    * an error were encountered, only the error is recorded.  If there
+    * are multiple warnings, only the first one is recorded.
+    *
+    * The upper 30 bits of this value are reserved, the low two bits contain
+    * a value as follows:
+    */
+#  define PNG_IMAGE_WARNING 1
+#  define PNG_IMAGE_ERROR 2
+   /*
+    * The result is a two-bit code such that a value more than 1 indicates
+    * a failure in the API just called:
+    *
+    *    0 - no warning or error
+    *    1 - warning
+    *    2 - error
+    *    3 - error preceded by warning
+    */
+#  define PNG_IMAGE_FAILED(png_cntrl) ((((png_cntrl).warning_or_error)&0x03)>1)
+
+   png_uint_32  warning_or_error;
+
+   char         message[64];
+} png_image, *png_imagep;
+
+/* The samples of the image have one to four channels whose components have
+ * original values in the range 0 to 1.0:
+ *
+ * 1: A single gray or luminance channel (G).
+ * 2: A gray/luminance channel and an alpha channel (GA).
+ * 3: Three red, green, blue color channels (RGB).
+ * 4: Three color channels and an alpha channel (RGBA).
+ *
+ * The components are encoded in one of two ways:
+ *
+ * a) As a small integer, value 0..255, contained in a single byte.  For the
+ * alpha channel the original value is simply value/255.  For the color or
+ * luminance channels the value is encoded according to the sRGB specification
+ * and matches the 8-bit format expected by typical display devices.
+ *
+ * The color/gray channels are not scaled (pre-multiplied) by the alpha
+ * channel and are suitable for passing to color management software.
+ *
+ * b) As a value in the range 0..65535, contained in a 2-byte integer.  All
+ * channels can be converted to the original value by dividing by 65535; all
+ * channels are linear.  Color channels use the RGB encoding (RGB end-points) of
+ * the sRGB specification.  This encoding is identified by the
+ * PNG_FORMAT_FLAG_LINEAR flag below.
+ *
+ * When the simplified API needs to convert between sRGB and linear colorspaces,
+ * the actual sRGB transfer curve defined in the sRGB specification (see the
+ * article at http://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2
+ * approximation used elsewhere in libpng.
+ *
+ * When an alpha channel is present it is expected to denote pixel coverage
+ * of the color or luminance channels and is returned as an associated alpha
+ * channel: the color/gray channels are scaled (pre-multiplied) by the alpha
+ * value.
+ *
+ * The samples are either contained directly in the image data, between 1 and 8
+ * bytes per pixel according to the encoding, or are held in a color-map indexed
+ * by bytes in the image data.  In the case of a color-map the color-map entries
+ * are individual samples, encoded as above, and the image data has one byte per
+ * pixel to select the relevant sample from the color-map.
+ */
+
+/* PNG_FORMAT_*
+ *
+ * #defines to be used in png_image::format.  Each #define identifies a
+ * particular layout of sample data and, if present, alpha values.  There are
+ * separate defines for each of the two component encodings.
+ *
+ * A format is built up using single bit flag values.  All combinations are
+ * valid.  Formats can be built up from the flag values or you can use one of
+ * the predefined values below.  When testing formats always use the FORMAT_FLAG
+ * macros to test for individual features - future versions of the library may
+ * add new flags.
+ *
+ * When reading or writing color-mapped images the format should be set to the
+ * format of the entries in the color-map then png_image_{read,write}_colormap
+ * called to read or write the color-map and set the format correctly for the
+ * image data.  Do not set the PNG_FORMAT_FLAG_COLORMAP bit directly!
+ *
+ * NOTE: libpng can be built with particular features disabled, if you see
+ * compiler errors because the definition of one of the following flags has been
+ * compiled out it is because libpng does not have the required support.  It is
+ * possible, however, for the libpng configuration to enable the format on just
+ * read or just write; in that case you may see an error at run time.  You can
+ * guard against this by checking for the definition of the appropriate
+ * "_SUPPORTED" macro, one of:
+ *
+ *    PNG_SIMPLIFIED_{READ,WRITE}_{BGR,AFIRST}_SUPPORTED
+ */
+#define PNG_FORMAT_FLAG_ALPHA    0x01U /* format with an alpha channel */
+#define PNG_FORMAT_FLAG_COLOR    0x02U /* color format: otherwise grayscale */
+#define PNG_FORMAT_FLAG_LINEAR   0x04U /* 2 byte channels else 1 byte */
+#define PNG_FORMAT_FLAG_COLORMAP 0x08U /* image data is color-mapped */
+
+#ifdef PNG_FORMAT_BGR_SUPPORTED
+#  define PNG_FORMAT_FLAG_BGR    0x10U /* BGR colors, else order is RGB */
+#endif
+
+#ifdef PNG_FORMAT_AFIRST_SUPPORTED
+#  define PNG_FORMAT_FLAG_AFIRST 0x20U /* alpha channel comes first */
+#endif
+
+/* Commonly used formats have predefined macros.
+ *
+ * First the single byte (sRGB) formats:
+ */
+#define PNG_FORMAT_GRAY 0
+#define PNG_FORMAT_GA   PNG_FORMAT_FLAG_ALPHA
+#define PNG_FORMAT_AG   (PNG_FORMAT_GA|PNG_FORMAT_FLAG_AFIRST)
+#define PNG_FORMAT_RGB  PNG_FORMAT_FLAG_COLOR
+#define PNG_FORMAT_BGR  (PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_BGR)
+#define PNG_FORMAT_RGBA (PNG_FORMAT_RGB|PNG_FORMAT_FLAG_ALPHA)
+#define PNG_FORMAT_ARGB (PNG_FORMAT_RGBA|PNG_FORMAT_FLAG_AFIRST)
+#define PNG_FORMAT_BGRA (PNG_FORMAT_BGR|PNG_FORMAT_FLAG_ALPHA)
+#define PNG_FORMAT_ABGR (PNG_FORMAT_BGRA|PNG_FORMAT_FLAG_AFIRST)
+
+/* Then the linear 2-byte formats.  When naming these "Y" is used to
+ * indicate a luminance (gray) channel.
+ */
+#define PNG_FORMAT_LINEAR_Y PNG_FORMAT_FLAG_LINEAR
+#define PNG_FORMAT_LINEAR_Y_ALPHA (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_ALPHA)
+#define PNG_FORMAT_LINEAR_RGB (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR)
+#define PNG_FORMAT_LINEAR_RGB_ALPHA \
+   (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_ALPHA)
+
+/* With color-mapped formats the image data is one byte for each pixel, the byte
+ * is an index into the color-map which is formatted as above.  To obtain a
+ * color-mapped format it is sufficient just to add the PNG_FOMAT_FLAG_COLORMAP
+ * to one of the above definitions, or you can use one of the definitions below.
+ */
+#define PNG_FORMAT_RGB_COLORMAP  (PNG_FORMAT_RGB|PNG_FORMAT_FLAG_COLORMAP)
+#define PNG_FORMAT_BGR_COLORMAP  (PNG_FORMAT_BGR|PNG_FORMAT_FLAG_COLORMAP)
+#define PNG_FORMAT_RGBA_COLORMAP (PNG_FORMAT_RGBA|PNG_FORMAT_FLAG_COLORMAP)
+#define PNG_FORMAT_ARGB_COLORMAP (PNG_FORMAT_ARGB|PNG_FORMAT_FLAG_COLORMAP)
+#define PNG_FORMAT_BGRA_COLORMAP (PNG_FORMAT_BGRA|PNG_FORMAT_FLAG_COLORMAP)
+#define PNG_FORMAT_ABGR_COLORMAP (PNG_FORMAT_ABGR|PNG_FORMAT_FLAG_COLORMAP)
+
+/* PNG_IMAGE macros
+ *
+ * These are convenience macros to derive information from a png_image
+ * structure.  The PNG_IMAGE_SAMPLE_ macros return values appropriate to the
+ * actual image sample values - either the entries in the color-map or the
+ * pixels in the image.  The PNG_IMAGE_PIXEL_ macros return corresponding values
+ * for the pixels and will always return 1 for color-mapped formats.  The
+ * remaining macros return information about the rows in the image and the
+ * complete image.
+ *
+ * NOTE: All the macros that take a png_image::format parameter are compile time
+ * constants if the format parameter is, itself, a constant.  Therefore these
+ * macros can be used in array declarations and case labels where required.
+ * Similarly the macros are also pre-processor constants (sizeof is not used) so
+ * they can be used in #if tests.
+ *
+ * First the information about the samples.
+ */
+#define PNG_IMAGE_SAMPLE_CHANNELS(fmt)\
+   (((fmt)&(PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_ALPHA))+1)
+   /* Return the total number of channels in a given format: 1..4 */
+
+#define PNG_IMAGE_SAMPLE_COMPONENT_SIZE(fmt)\
+   ((((fmt) & PNG_FORMAT_FLAG_LINEAR) >> 2)+1)
+   /* Return the size in bytes of a single component of a pixel or color-map
+    * entry (as appropriate) in the image: 1 or 2.
+    */
+
+#define PNG_IMAGE_SAMPLE_SIZE(fmt)\
+   (PNG_IMAGE_SAMPLE_CHANNELS(fmt) * PNG_IMAGE_SAMPLE_COMPONENT_SIZE(fmt))
+   /* This is the size of the sample data for one sample.  If the image is
+    * color-mapped it is the size of one color-map entry (and image pixels are
+    * one byte in size), otherwise it is the size of one image pixel.
+    */
+
+#define PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(fmt)\
+   (PNG_IMAGE_SAMPLE_CHANNELS(fmt) * 256)
+   /* The maximum size of the color-map required by the format expressed in a
+    * count of components.  This can be used to compile-time allocate a
+    * color-map:
+    *
+    * png_uint_16 colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(linear_fmt)];
+    *
+    * png_byte colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(sRGB_fmt)];
+    *
+    * Alternatively use the PNG_IMAGE_COLORMAP_SIZE macro below to use the
+    * information from one of the png_image_begin_read_ APIs and dynamically
+    * allocate the required memory.
+    */
+
+/* Corresponding information about the pixels */
+#define PNG_IMAGE_PIXEL_(test,fmt)\
+   (((fmt)&PNG_FORMAT_FLAG_COLORMAP)?1:test(fmt))
+
+#define PNG_IMAGE_PIXEL_CHANNELS(fmt)\
+   PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_CHANNELS,fmt)
+   /* The number of separate channels (components) in a pixel; 1 for a
+    * color-mapped image.
+    */
+
+#define PNG_IMAGE_PIXEL_COMPONENT_SIZE(fmt)\
+   PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_COMPONENT_SIZE,fmt)
+   /* The size, in bytes, of each component in a pixel; 1 for a color-mapped
+    * image.
+    */
+
+#define PNG_IMAGE_PIXEL_SIZE(fmt) PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_SIZE,fmt)
+   /* The size, in bytes, of a complete pixel; 1 for a color-mapped image. */
+
+/* Information about the whole row, or whole image */
+#define PNG_IMAGE_ROW_STRIDE(image)\
+   (PNG_IMAGE_PIXEL_CHANNELS((image).format) * (image).width)
+   /* Return the total number of components in a single row of the image; this
+    * is the minimum 'row stride', the minimum count of components between each
+    * row.  For a color-mapped image this is the minimum number of bytes in a
+    * row.
+    */
+
+#define PNG_IMAGE_BUFFER_SIZE(image, row_stride)\
+   (PNG_IMAGE_PIXEL_COMPONENT_SIZE((image).format)*(image).height*(row_stride))
+   /* Return the size, in bytes, of an image buffer given a png_image and a row
+    * stride - the number of components to leave space for in each row.
+    */
+
+#define PNG_IMAGE_SIZE(image)\
+   PNG_IMAGE_BUFFER_SIZE(image, PNG_IMAGE_ROW_STRIDE(image))
+   /* Return the size, in bytes, of the image in memory given just a png_image;
+    * the row stride is the minimum stride required for the image.
+    */
+
+#define PNG_IMAGE_COLORMAP_SIZE(image)\
+   (PNG_IMAGE_SAMPLE_SIZE((image).format) * (image).colormap_entries)
+   /* Return the size, in bytes, of the color-map of this image.  If the image
+    * format is not a color-map format this will return a size sufficient for
+    * 256 entries in the given format; check PNG_FORMAT_FLAG_COLORMAP if
+    * you don't want to allocate a color-map in this case.
+    */
+
+/* PNG_IMAGE_FLAG_*
+ *
+ * Flags containing additional information about the image are held in the
+ * 'flags' field of png_image.
+ */
+#define PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB 0x01
+   /* This indicates the the RGB values of the in-memory bitmap do not
+    * correspond to the red, green and blue end-points defined by sRGB.
+    */
+
+#define PNG_IMAGE_FLAG_FAST 0x02
+   /* On write emphasise speed over compression; the resultant PNG file will be
+    * larger but will be produced significantly faster, particular for large
+    * images.  Do not use this option for images which will be distributed, only
+    * used it when producing intermediate files that will be read back in
+    * repeatedly.  For a typical 24-bit image the option will double the read
+    * speed at the cost of increasing the image size by 25%, however for many
+    * more compressible images the PNG file can be 10 times larger with only a
+    * slight speed gain.
+    */
+
+#define PNG_IMAGE_FLAG_16BIT_sRGB 0x04
+   /* On read if the image is a 16-bit per component image and there is no gAMA
+    * or sRGB chunk assume that the components are sRGB encoded.  Notice that
+    * images output by the simplified API always have gamma information; setting
+    * this flag only affects the interpretation of 16-bit images from an
+    * external source.  It is recommended that the application expose this flag
+    * to the user; the user can normally easily recognize the difference between
+    * linear and sRGB encoding.  This flag has no effect on write - the data
+    * passed to the write APIs must have the correct encoding (as defined
+    * above.)
+    *
+    * If the flag is not set (the default) input 16-bit per component data is
+    * assumed to be linear.
+    *
+    * NOTE: the flag can only be set after the png_image_begin_read_ call,
+    * because that call initializes the 'flags' field.
+    */
+
+#ifdef PNG_SIMPLIFIED_READ_SUPPORTED
+/* READ APIs
+ * ---------
+ *
+ * The png_image passed to the read APIs must have been initialized by setting
+ * the png_controlp field 'opaque' to NULL (or, safer, memset the whole thing.)
+ */
+#ifdef PNG_STDIO_SUPPORTED
+PNG_EXPORT(234, int, png_image_begin_read_from_file, (png_imagep image,
+   const char *file_name));
+   /* The named file is opened for read and the image header is filled in
+    * from the PNG header in the file.
+    */
+
+PNG_EXPORT(235, int, png_image_begin_read_from_stdio, (png_imagep image,
+   FILE* file));
+   /* The PNG header is read from the stdio FILE object. */
+#endif /* STDIO */
+
+PNG_EXPORT(236, int, png_image_begin_read_from_memory, (png_imagep image,
+   png_const_voidp memory, png_size_t size));
+   /* The PNG header is read from the given memory buffer. */
+
+PNG_EXPORT(237, int, png_image_finish_read, (png_imagep image,
+   png_const_colorp background, void *buffer, png_int_32 row_stride,
+   void *colormap));
+   /* Finish reading the image into the supplied buffer and clean up the
+    * png_image structure.
+    *
+    * row_stride is the step, in byte or 2-byte units as appropriate,
+    * between adjacent rows.  A positive stride indicates that the top-most row
+    * is first in the buffer - the normal top-down arrangement.  A negative
+    * stride indicates that the bottom-most row is first in the buffer.
+    *
+    * background need only be supplied if an alpha channel must be removed from
+    * a png_byte format and the removal is to be done by compositing on a solid
+    * color; otherwise it may be NULL and any composition will be done directly
+    * onto the buffer.  The value is an sRGB color to use for the background,
+    * for grayscale output the green channel is used.
+    *
+    * background must be supplied when an alpha channel must be removed from a
+    * single byte color-mapped output format, in other words if:
+    *
+    * 1) The original format from png_image_begin_read_from_* had
+    *    PNG_FORMAT_FLAG_ALPHA set.
+    * 2) The format set by the application does not.
+    * 3) The format set by the application has PNG_FORMAT_FLAG_COLORMAP set and
+    *    PNG_FORMAT_FLAG_LINEAR *not* set.
+    *
+    * For linear output removing the alpha channel is always done by compositing
+    * on black and background is ignored.
+    *
+    * colormap must be supplied when PNG_FORMAT_FLAG_COLORMAP is set.  It must
+    * be at least the size (in bytes) returned by PNG_IMAGE_COLORMAP_SIZE.
+    * image->colormap_entries will be updated to the actual number of entries
+    * written to the colormap; this may be less than the original value.
+    */
+
+PNG_EXPORT(238, void, png_image_free, (png_imagep image));
+   /* Free any data allocated by libpng in image->opaque, setting the pointer to
+    * NULL.  May be called at any time after the structure is initialized.
+    */
+#endif /* SIMPLIFIED_READ */
+
+#ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED
+#ifdef PNG_STDIO_SUPPORTED
+/* WRITE APIS
+ * ----------
+ * For write you must initialize a png_image structure to describe the image to
+ * be written.  To do this use memset to set the whole structure to 0 then
+ * initialize fields describing your image.
+ *
+ * version: must be set to PNG_IMAGE_VERSION
+ * opaque: must be initialized to NULL
+ * width: image width in pixels
+ * height: image height in rows
+ * format: the format of the data (image and color-map) you wish to write
+ * flags: set to 0 unless one of the defined flags applies; set
+ *    PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB for color format images where the RGB
+ *    values do not correspond to the colors in sRGB.
+ * colormap_entries: set to the number of entries in the color-map (0 to 256)
+ */
+PNG_EXPORT(239, int, png_image_write_to_file, (png_imagep image,
+   const char *file, int convert_to_8bit, const void *buffer,
+   png_int_32 row_stride, const void *colormap));
+   /* Write the image to the named file. */
+
+PNG_EXPORT(240, int, png_image_write_to_stdio, (png_imagep image, FILE *file,
+   int convert_to_8_bit, const void *buffer, png_int_32 row_stride,
+   const void *colormap));
+   /* Write the image to the given (FILE*). */
+
+/* With both write APIs if image is in one of the linear formats with 16-bit
+ * data then setting convert_to_8_bit will cause the output to be an 8-bit PNG
+ * gamma encoded according to the sRGB specification, otherwise a 16-bit linear
+ * encoded PNG file is written.
+ *
+ * With color-mapped data formats the colormap parameter point to a color-map
+ * with at least image->colormap_entries encoded in the specified format.  If
+ * the format is linear the written PNG color-map will be converted to sRGB
+ * regardless of the convert_to_8_bit flag.
+ *
+ * With all APIs row_stride is handled as in the read APIs - it is the spacing
+ * from one row to the next in component sized units (1 or 2 bytes) and if
+ * negative indicates a bottom-up row layout in the buffer.
+ *
+ * Note that the write API does not support interlacing or sub-8-bit pixels.
+ */
+#endif /* STDIO */
+#endif /* SIMPLIFIED_WRITE */
+/*******************************************************************************
+ *  END OF SIMPLIFIED API
+ ******************************************************************************/
+#endif /* SIMPLIFIED_{READ|WRITE} */
+
+#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
+PNG_EXPORT(242, void, png_set_check_for_invalid_index,
+    (png_structrp png_ptr, int allowed));
+#  ifdef PNG_GET_PALETTE_MAX_SUPPORTED
+PNG_EXPORT(243, int, png_get_palette_max, (png_const_structp png_ptr,
+    png_const_infop info_ptr));
+#  endif
+#endif /* CHECK_FOR_INVALID_INDEX */
+
+/*******************************************************************************
+ *  IMPLEMENTATION OPTIONS
+ *******************************************************************************
+ *
+ * Support for arbitrary implementation-specific optimizations.  The API allows
+ * particular options to be turned on or off.  'Option' is the number of the
+ * option and 'onoff' is 0 (off) or non-0 (on).  The value returned is given
+ * by the PNG_OPTION_ defines below.
+ *
+ * HARDWARE: normally hardware capabilites, such as the Intel SSE instructions,
+ *           are detected at run time, however sometimes it may be impossible
+ *           to do this in user mode, in which case it is necessary to discover
+ *           the capabilities in an OS specific way.  Such capabilities are
+ *           listed here when libpng has support for them and must be turned
+ *           ON by the application if present.
+ *
+ * SOFTWARE: sometimes software optimizations actually result in performance
+ *           decrease on some architectures or systems, or with some sets of
+ *           PNG images.  'Software' options allow such optimizations to be
+ *           selected at run time.
+ */
+#ifdef PNG_SET_OPTION_SUPPORTED
+#ifdef PNG_ARM_NEON_API_SUPPORTED
+#  define PNG_ARM_NEON   0 /* HARDWARE: ARM Neon SIMD instructions supported */
+#endif
+#define PNG_MAXIMUM_INFLATE_WINDOW 2 /* SOFTWARE: force maximum window */
+#define PNG_SKIP_sRGB_CHECK_PROFILE 4 /* SOFTWARE: Check ICC profile for sRGB */
+#define PNG_OPTION_NEXT  6 /* Next option - numbers must be even */
+
+/* Return values: NOTE: there are four values and 'off' is *not* zero */
+#define PNG_OPTION_UNSET   0 /* Unset - defaults to off */
+#define PNG_OPTION_INVALID 1 /* Option number out of range */
+#define PNG_OPTION_OFF     2
+#define PNG_OPTION_ON      3
+
+PNG_EXPORT(244, int, png_set_option, (png_structrp png_ptr, int option,
+   int onoff));
+#endif /* SET_OPTION */
+
+/*******************************************************************************
+ *  END OF HARDWARE AND SOFTWARE OPTIONS
+ ******************************************************************************/
+
+/* Maintainer: Put new public prototypes here ^, in libpng.3, in project
+ * defs, and in scripts/symbols.def.
+ */
+
+/* The last ordinal number (this is the *last* one already used; the next
+ * one to use is one more than this.)
+ */
+#ifdef PNG_EXPORT_LAST_ORDINAL
+  PNG_EXPORT_LAST_ORDINAL(244);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PNG_VERSION_INFO_ONLY */
+/* Do not put anything past this line */
+#endif /* PNG_H */
diff --git a/Source/LibPNG/pngconf.h b/Source/LibPNG/pngconf.h
index 5298e66..03615f0 100644
--- a/Source/LibPNG/pngconf.h
+++ b/Source/LibPNG/pngconf.h
@@ -1,598 +1,644 @@
-
-/* pngconf.h - machine configurable file for libpng
- *
- * libpng version 1.5.13 - September 27, 2012
- *
- * Copyright (c) 1998-2012 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- *
- */
-
-/* Any machine specific code is near the front of this file, so if you
- * are configuring libpng for a machine, you may want to read the section
- * starting here down to where it starts to typedef png_color, png_text,
- * and png_info.
- */
-
-#ifndef PNGCONF_H
-#define PNGCONF_H
-
-#ifndef PNG_BUILDING_SYMBOL_TABLE
-/* PNG_NO_LIMITS_H may be used to turn off the use of the standard C
- * definition file for  machine specific limits, this may impact the
- * correctness of the definitions below (see uses of INT_MAX).
- */
-#  ifndef PNG_NO_LIMITS_H
-#    include <limits.h>
-#  endif
-
-/* For the memory copy APIs (i.e. the standard definitions of these),
- * because this file defines png_memcpy and so on the base APIs must
- * be defined here.
- */
-#  ifdef BSD
-#    include <strings.h>
-#  else
-#    include <string.h>
-#  endif
-
-/* For png_FILE_p - this provides the standard definition of a
- * FILE
- */
-#  ifdef PNG_STDIO_SUPPORTED
-#    include <stdio.h>
-#  endif
-#endif
-
-/* This controls optimization of the reading of 16 and 32 bit values
- * from PNG files.  It can be set on a per-app-file basis - it
- * just changes whether a macro is used when the function is called.
- * The library builder sets the default; if read functions are not
- * built into the library the macro implementation is forced on.
- */
-#ifndef PNG_READ_INT_FUNCTIONS_SUPPORTED
-#  define PNG_USE_READ_MACROS
-#endif
-#if !defined(PNG_NO_USE_READ_MACROS) && !defined(PNG_USE_READ_MACROS)
-#  if PNG_DEFAULT_READ_MACROS
-#    define PNG_USE_READ_MACROS
-#  endif
-#endif
-
-/* COMPILER SPECIFIC OPTIONS.
- *
- * These options are provided so that a variety of difficult compilers
- * can be used.  Some are fixed at build time (e.g. PNG_API_RULE
- * below) but still have compiler specific implementations, others
- * may be changed on a per-file basis when compiling against libpng.
- */
-
-/* The PNGARG macro protects us against machines that don't have function
- * prototypes (ie K&R style headers).  If your compiler does not handle
- * function prototypes, define this macro and use the included ansi2knr.
- * I've always been able to use _NO_PROTO as the indicator, but you may
- * need to drag the empty declaration out in front of here, or change the
- * ifdef to suit your own needs.
- */
-#ifndef PNGARG
-
-#  ifdef OF /* zlib prototype munger */
-#    define PNGARG(arglist) OF(arglist)
-#  else
-
-#    ifdef _NO_PROTO
-#      define PNGARG(arglist) ()
-#    else
-#      define PNGARG(arglist) arglist
-#    endif /* _NO_PROTO */
-
-#  endif /* OF */
-
-#endif /* PNGARG */
-
-/* Function calling conventions.
- * =============================
- * Normally it is not necessary to specify to the compiler how to call
- * a function - it just does it - however on x86 systems derived from
- * Microsoft and Borland C compilers ('IBM PC', 'DOS', 'Windows' systems
- * and some others) there are multiple ways to call a function and the
- * default can be changed on the compiler command line.  For this reason
- * libpng specifies the calling convention of every exported function and
- * every function called via a user supplied function pointer.  This is
- * done in this file by defining the following macros:
- *
- * PNGAPI    Calling convention for exported functions.
- * PNGCBAPI  Calling convention for user provided (callback) functions.
- * PNGCAPI   Calling convention used by the ANSI-C library (required
- *           for longjmp callbacks and sometimes used internally to
- *           specify the calling convention for zlib).
- *
- * These macros should never be overridden.  If it is necessary to
- * change calling convention in a private build this can be done
- * by setting PNG_API_RULE (which defaults to 0) to one of the values
- * below to select the correct 'API' variants.
- *
- * PNG_API_RULE=0 Use PNGCAPI - the 'C' calling convention - throughout.
- *                This is correct in every known environment.
- * PNG_API_RULE=1 Use the operating system convention for PNGAPI and
- *                the 'C' calling convention (from PNGCAPI) for
- *                callbacks (PNGCBAPI).  This is no longer required
- *                in any known environment - if it has to be used
- *                please post an explanation of the problem to the
- *                libpng mailing list.
- *
- * These cases only differ if the operating system does not use the C
- * calling convention, at present this just means the above cases
- * (x86 DOS/Windows sytems) and, even then, this does not apply to
- * Cygwin running on those systems.
- *
- * Note that the value must be defined in pnglibconf.h so that what
- * the application uses to call the library matches the conventions
- * set when building the library.
- */
-
-/* Symbol export
- * =============
- * When building a shared library it is almost always necessary to tell
- * the compiler which symbols to export.  The png.h macro 'PNG_EXPORT'
- * is used to mark the symbols.  On some systems these symbols can be
- * extracted at link time and need no special processing by the compiler,
- * on other systems the symbols are flagged by the compiler and just
- * the declaration requires a special tag applied (unfortunately) in a
- * compiler dependent way.  Some systems can do either.
- *
- * A small number of older systems also require a symbol from a DLL to
- * be flagged to the program that calls it.  This is a problem because
- * we do not know in the header file included by application code that
- * the symbol will come from a shared library, as opposed to a statically
- * linked one.  For this reason the application must tell us by setting
- * the magic flag PNG_USE_DLL to turn on the special processing before
- * it includes png.h.
- *
- * Four additional macros are used to make this happen:
- *
- * PNG_IMPEXP The magic (if any) to cause a symbol to be exported from
- *            the build or imported if PNG_USE_DLL is set - compiler
- *            and system specific.
- *
- * PNG_EXPORT_TYPE(type) A macro that pre or appends PNG_IMPEXP to
- *                       'type', compiler specific.
- *
- * PNG_DLL_EXPORT Set to the magic to use during a libpng build to
- *                make a symbol exported from the DLL.  Not used in the
- *                public header files; see pngpriv.h for how it is used
- *                in the libpng build.
- *
- * PNG_DLL_IMPORT Set to the magic to force the libpng symbols to come
- *                from a DLL - used to define PNG_IMPEXP when
- *                PNG_USE_DLL is set.
- */
-
-/* System specific discovery.
- * ==========================
- * This code is used at build time to find PNG_IMPEXP, the API settings
- * and PNG_EXPORT_TYPE(), it may also set a macro to indicate the DLL
- * import processing is possible.  On Windows/x86 systems it also sets
- * compiler-specific macros to the values required to change the calling
- * conventions of the various functions.
- */
-#if ( defined(_Windows) || defined(_WINDOWS) || defined(WIN32) ||\
-      defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) ) &&\
-    ( defined(_X86_) || defined(_X64_) || defined(_M_IX86) ||\
-      defined(_M_X64) || defined(_M_IA64) )
-  /* Windows system (DOS doesn't support DLLs) running on x86/x64.  Includes
-   * builds under Cygwin or MinGW.  Also includes Watcom builds but these need
-   * special treatment because they are not compatible with GCC or Visual C
-   * because of different calling conventions.
-   */
-#  if PNG_API_RULE == 2
-    /* If this line results in an error, either because __watcall is not
-     * understood or because of a redefine just below you cannot use *this*
-     * build of the library with the compiler you are using.  *This* build was
-     * build using Watcom and applications must also be built using Watcom!
-     */
-#    define PNGCAPI __watcall
-#  endif
-
-#  if defined(__GNUC__) || (defined (_MSC_VER) && (_MSC_VER >= 800))
-#    define PNGCAPI __cdecl
-#    if PNG_API_RULE == 1
-#      define PNGAPI __stdcall
-#    endif
-#  else
-    /* An older compiler, or one not detected (erroneously) above,
-     * if necessary override on the command line to get the correct
-     * variants for the compiler.
-     */
-#    ifndef PNGCAPI
-#      define PNGCAPI _cdecl
-#    endif
-#    if PNG_API_RULE == 1 && !defined(PNGAPI)
-#      define PNGAPI _stdcall
-#    endif
-#  endif /* compiler/api */
-  /* NOTE: PNGCBAPI always defaults to PNGCAPI. */
-
-#  if defined(PNGAPI) && !defined(PNG_USER_PRIVATEBUILD)
-   ERROR: PNG_USER_PRIVATEBUILD must be defined if PNGAPI is changed
-#  endif
-
-#  if (defined(_MSC_VER) && _MSC_VER < 800) ||\
-      (defined(__BORLANDC__) && __BORLANDC__ < 0x500)
-    /* older Borland and MSC
-     * compilers used '__export' and required this to be after
-     * the type.
-     */
-#    ifndef PNG_EXPORT_TYPE
-#      define PNG_EXPORT_TYPE(type) type PNG_IMPEXP
-#    endif
-#    define PNG_DLL_EXPORT __export
-#  else /* newer compiler */
-#    define PNG_DLL_EXPORT __declspec(dllexport)
-#    ifndef PNG_DLL_IMPORT
-#      define PNG_DLL_IMPORT __declspec(dllimport)
-#    endif
-#  endif /* compiler */
-
-#else /* !Windows/x86 */
-#  if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__)
-#    define PNGAPI _System
-#  else /* !Windows/x86 && !OS/2 */
-    /* Use the defaults, or define PNG*API on the command line (but
-     * this will have to be done for every compile!)
-     */
-#  endif /* other system, !OS/2 */
-#endif /* !Windows/x86 */
-
-/* Now do all the defaulting . */
-#ifndef PNGCAPI
-#  define PNGCAPI
-#endif
-#ifndef PNGCBAPI
-#  define PNGCBAPI PNGCAPI
-#endif
-#ifndef PNGAPI
-#  define PNGAPI PNGCAPI
-#endif
-
-/* PNG_IMPEXP may be set on the compilation system command line or (if not set)
- * then in an internal header file when building the library, otherwise (when
- * using the library) it is set here.
- */
-#ifndef PNG_IMPEXP
-#  if defined(PNG_USE_DLL) && defined(PNG_DLL_IMPORT)
-     /* This forces use of a DLL, disallowing static linking */
-#    define PNG_IMPEXP PNG_DLL_IMPORT
-#  endif
-
-#  ifndef PNG_IMPEXP
-#    define PNG_IMPEXP
-#  endif
-#endif
-
-/* In 1.5.2 the definition of PNG_FUNCTION has been changed to always treat
- * 'attributes' as a storage class - the attributes go at the start of the
- * function definition, and attributes are always appended regardless of the
- * compiler.  This considerably simplifies these macros but may cause problems
- * if any compilers both need function attributes and fail to handle them as
- * a storage class (this is unlikely.)
- */
-#ifndef PNG_FUNCTION
-#  define PNG_FUNCTION(type, name, args, attributes) attributes type name args
-#endif
-
-#ifndef PNG_EXPORT_TYPE
-#  define PNG_EXPORT_TYPE(type) PNG_IMPEXP type
-#endif
-
-   /* The ordinal value is only relevant when preprocessing png.h for symbol
-    * table entries, so we discard it here.  See the .dfn files in the
-    * scripts directory.
-    */
-#ifndef PNG_EXPORTA
-
-#  define PNG_EXPORTA(ordinal, type, name, args, attributes)\
-      PNG_FUNCTION(PNG_EXPORT_TYPE(type),(PNGAPI name),PNGARG(args), \
-        extern attributes)
-#endif
-
-/* ANSI-C (C90) does not permit a macro to be invoked with an empty argument,
- * so make something non-empty to satisfy the requirement:
- */
-#define PNG_EMPTY /*empty list*/
-
-#define PNG_EXPORT(ordinal, type, name, args)\
-   PNG_EXPORTA(ordinal, type, name, args, PNG_EMPTY)
-
-/* Use PNG_REMOVED to comment out a removed interface. */
-#ifndef PNG_REMOVED
-#  define PNG_REMOVED(ordinal, type, name, args, attributes)
-#endif
-
-#ifndef PNG_CALLBACK
-#  define PNG_CALLBACK(type, name, args) type (PNGCBAPI name) PNGARG(args)
-#endif
-
-/* Support for compiler specific function attributes.  These are used
- * so that where compiler support is available incorrect use of API
- * functions in png.h will generate compiler warnings.
- *
- * Added at libpng-1.2.41.
- */
-
-#ifndef PNG_NO_PEDANTIC_WARNINGS
-#  ifndef PNG_PEDANTIC_WARNINGS_SUPPORTED
-#    define PNG_PEDANTIC_WARNINGS_SUPPORTED
-#  endif
-#endif
-
-#ifdef PNG_PEDANTIC_WARNINGS_SUPPORTED
-  /* Support for compiler specific function attributes.  These are used
-   * so that where compiler support is available incorrect use of API
-   * functions in png.h will generate compiler warnings.  Added at libpng
-   * version 1.2.41.
-   */
-#  if defined(__GNUC__)
-#    ifndef PNG_USE_RESULT
-#      define PNG_USE_RESULT __attribute__((__warn_unused_result__))
-#    endif
-#    ifndef PNG_NORETURN
-#      define PNG_NORETURN   __attribute__((__noreturn__))
-#    endif
-#    if __GNUC__ >= 3
-#      ifndef PNG_ALLOCATED
-#        define PNG_ALLOCATED  __attribute__((__malloc__))
-#      endif
-#      ifndef PNG_DEPRECATED
-#        define PNG_DEPRECATED __attribute__((__deprecated__))
-#      endif
-#      ifndef PNG_PRIVATE
-#        if 0 /* Doesn't work so we use deprecated instead*/
-#          define PNG_PRIVATE \
-            __attribute__((warning("This function is not exported by libpng.")))
-#        else
-#          define PNG_PRIVATE \
-            __attribute__((__deprecated__))
-#        endif
-#      endif
-#    endif /*  __GNUC__ >= 3 */
-#  endif /* __GNUC__ */
-
-#  if defined(_MSC_VER)  && (_MSC_VER >= 1300)
-#    ifndef PNG_USE_RESULT
-#      define PNG_USE_RESULT /* not supported */
-#    endif
-#    ifndef PNG_NORETURN
-#      define PNG_NORETURN __declspec(noreturn)
-#    endif
-#    ifndef PNG_ALLOCATED
-#      if (_MSC_VER >= 1400)
-#        define PNG_ALLOCATED __declspec(restrict)
-#      endif
-#    endif
-#    ifndef PNG_DEPRECATED
-#      define PNG_DEPRECATED __declspec(deprecated)
-#    endif
-#    ifndef PNG_PRIVATE
-#      define PNG_PRIVATE __declspec(deprecated)
-#    endif
-#  endif /* _MSC_VER */
-#endif /* PNG_PEDANTIC_WARNINGS */
-
-#ifndef PNG_DEPRECATED
-#  define PNG_DEPRECATED  /* Use of this function is deprecated */
-#endif
-#ifndef PNG_USE_RESULT
-#  define PNG_USE_RESULT  /* The result of this function must be checked */
-#endif
-#ifndef PNG_NORETURN
-#  define PNG_NORETURN    /* This function does not return */
-#endif
-#ifndef PNG_ALLOCATED
-#  define PNG_ALLOCATED   /* The result of the function is new memory */
-#endif
-#ifndef PNG_PRIVATE
-#  define PNG_PRIVATE     /* This is a private libpng function */
-#endif
-#ifndef PNG_FP_EXPORT     /* A floating point API. */
-#  ifdef PNG_FLOATING_POINT_SUPPORTED
-#     define PNG_FP_EXPORT(ordinal, type, name, args)\
-         PNG_EXPORT(ordinal, type, name, args);
-#  else                   /* No floating point APIs */
-#     define PNG_FP_EXPORT(ordinal, type, name, args)
-#  endif
-#endif
-#ifndef PNG_FIXED_EXPORT  /* A fixed point API. */
-#  ifdef PNG_FIXED_POINT_SUPPORTED
-#     define PNG_FIXED_EXPORT(ordinal, type, name, args)\
-         PNG_EXPORT(ordinal, type, name, args);
-#  else                   /* No fixed point APIs */
-#     define PNG_FIXED_EXPORT(ordinal, type, name, args)
-#  endif
-#endif
-
-/* The following uses const char * instead of char * for error
- * and warning message functions, so some compilers won't complain.
- * If you do not want to use const, define PNG_NO_CONST here.
- *
- * This should not change how the APIs are called, so it can be done
- * on a per-file basis in the application.
- */
-#ifndef PNG_CONST
-#  ifndef PNG_NO_CONST
-#    define PNG_CONST const
-#  else
-#    define PNG_CONST
-#  endif
-#endif
-
-/* Some typedefs to get us started.  These should be safe on most of the
- * common platforms.  The typedefs should be at least as large as the
- * numbers suggest (a png_uint_32 must be at least 32 bits long), but they
- * don't have to be exactly that size.  Some compilers dislike passing
- * unsigned shorts as function parameters, so you may be better off using
- * unsigned int for png_uint_16.
- */
-
-#if defined(INT_MAX) && (INT_MAX > 0x7ffffffeL)
-typedef unsigned int png_uint_32;
-typedef int png_int_32;
-#else
-typedef unsigned long png_uint_32;
-typedef long png_int_32;
-#endif
-typedef unsigned short png_uint_16;
-typedef short png_int_16;
-typedef unsigned char png_byte;
-
-#ifdef PNG_NO_SIZE_T
-typedef unsigned int png_size_t;
-#else
-typedef size_t png_size_t;
-#endif
-#define png_sizeof(x) (sizeof (x))
-
-/* The following is needed for medium model support.  It cannot be in the
- * pngpriv.h header.  Needs modification for other compilers besides
- * MSC.  Model independent support declares all arrays and pointers to be
- * large using the far keyword.  The zlib version used must also support
- * model independent data.  As of version zlib 1.0.4, the necessary changes
- * have been made in zlib.  The USE_FAR_KEYWORD define triggers other
- * changes that are needed. (Tim Wegner)
- */
-
-/* Separate compiler dependencies (problem here is that zlib.h always
- * defines FAR. (SJT)
- */
-#ifdef __BORLANDC__
-#  if defined(__LARGE__) || defined(__HUGE__) || defined(__COMPACT__)
-#    define LDATA 1
-#  else
-#    define LDATA 0
-#  endif
-  /* GRR:  why is Cygwin in here?  Cygwin is not Borland C... */
-#  if !defined(__WIN32__) && !defined(__FLAT__) && !defined(__CYGWIN__)
-#    define PNG_MAX_MALLOC_64K /* only used in build */
-#    if (LDATA != 1)
-#      ifndef FAR
-#        define FAR __far
-#      endif
-#      define USE_FAR_KEYWORD
-#    endif   /* LDATA != 1 */
-         /* Possibly useful for moving data out of default segment.
-          * Uncomment it if you want. Could also define FARDATA as
-          * const if your compiler supports it. (SJT)
-#        define FARDATA FAR
-          */
-#  endif  /* __WIN32__, __FLAT__, __CYGWIN__ */
-#endif   /* __BORLANDC__ */
-
-
-/* Suggest testing for specific compiler first before testing for
- * FAR.  The Watcom compiler defines both __MEDIUM__ and M_I86MM,
- * making reliance oncertain keywords suspect. (SJT)
- */
-
-/* MSC Medium model */
-#ifdef FAR
-#  ifdef M_I86MM
-#    define USE_FAR_KEYWORD
-#    define FARDATA FAR
-#    include <dos.h>
-#  endif
-#endif
-
-/* SJT: default case */
-#ifndef FAR
-#  define FAR
-#endif
-
-/* At this point FAR is always defined */
-#ifndef FARDATA
-#  define FARDATA
-#endif
-
-/* Typedef for floating-point numbers that are converted
- * to fixed-point with a multiple of 100,000, e.g., gamma
- */
-typedef png_int_32 png_fixed_point;
-
-/* Add typedefs for pointers */
-typedef void                      FAR * png_voidp;
-typedef PNG_CONST void            FAR * png_const_voidp;
-typedef png_byte                  FAR * png_bytep;
-typedef PNG_CONST png_byte        FAR * png_const_bytep;
-typedef png_uint_32               FAR * png_uint_32p;
-typedef PNG_CONST png_uint_32     FAR * png_const_uint_32p;
-typedef png_int_32                FAR * png_int_32p;
-typedef PNG_CONST png_int_32      FAR * png_const_int_32p;
-typedef png_uint_16               FAR * png_uint_16p;
-typedef PNG_CONST png_uint_16     FAR * png_const_uint_16p;
-typedef png_int_16                FAR * png_int_16p;
-typedef PNG_CONST png_int_16      FAR * png_const_int_16p;
-typedef char                      FAR * png_charp;
-typedef PNG_CONST char            FAR * png_const_charp;
-typedef png_fixed_point           FAR * png_fixed_point_p;
-typedef PNG_CONST png_fixed_point FAR * png_const_fixed_point_p;
-typedef png_size_t                FAR * png_size_tp;
-typedef PNG_CONST png_size_t      FAR * png_const_size_tp;
-
-#ifdef PNG_STDIO_SUPPORTED
-typedef FILE            * png_FILE_p;
-#endif
-
-#ifdef PNG_FLOATING_POINT_SUPPORTED
-typedef double           FAR * png_doublep;
-typedef PNG_CONST double FAR * png_const_doublep;
-#endif
-
-/* Pointers to pointers; i.e. arrays */
-typedef png_byte        FAR * FAR * png_bytepp;
-typedef png_uint_32     FAR * FAR * png_uint_32pp;
-typedef png_int_32      FAR * FAR * png_int_32pp;
-typedef png_uint_16     FAR * FAR * png_uint_16pp;
-typedef png_int_16      FAR * FAR * png_int_16pp;
-typedef PNG_CONST char  FAR * FAR * png_const_charpp;
-typedef char            FAR * FAR * png_charpp;
-typedef png_fixed_point FAR * FAR * png_fixed_point_pp;
-#ifdef PNG_FLOATING_POINT_SUPPORTED
-typedef double          FAR * FAR * png_doublepp;
-#endif
-
-/* Pointers to pointers to pointers; i.e., pointer to array */
-typedef char            FAR * FAR * FAR * png_charppp;
-
-/* png_alloc_size_t is guaranteed to be no smaller than png_size_t,
- * and no smaller than png_uint_32.  Casts from png_size_t or png_uint_32
- * to png_alloc_size_t are not necessary; in fact, it is recommended
- * not to use them at all so that the compiler can complain when something
- * turns out to be problematic.
- * Casts in the other direction (from png_alloc_size_t to png_size_t or
- * png_uint_32) should be explicitly applied; however, we do not expect
- * to encounter practical situations that require such conversions.
- */
-#if defined(__TURBOC__) && !defined(__FLAT__)
-   typedef unsigned long png_alloc_size_t;
-#else
-#  if defined(_MSC_VER) && defined(MAXSEG_64K)
-     typedef unsigned long    png_alloc_size_t;
-#  else
-     /* This is an attempt to detect an old Windows system where (int) is
-      * actually 16 bits, in that case png_malloc must have an argument with a
-      * bigger size to accomodate the requirements of the library.
-      */
-#    if (defined(_Windows) || defined(_WINDOWS) || defined(_WINDOWS_)) && \
-        (!defined(INT_MAX) || INT_MAX <= 0x7ffffffeL)
-       typedef DWORD         png_alloc_size_t;
-#    else
-       typedef png_size_t    png_alloc_size_t;
-#    endif
-#  endif
-#endif
-
-#endif /* PNGCONF_H */
+
+/* pngconf.h - machine configurable file for libpng
+ *
+ * libpng version 1.6.16,December 22, 2014
+ *
+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ */
+
+/* Any machine specific code is near the front of this file, so if you
+ * are configuring libpng for a machine, you may want to read the section
+ * starting here down to where it starts to typedef png_color, png_text,
+ * and png_info.
+ */
+
+#ifndef PNGCONF_H
+#define PNGCONF_H
+
+/* To do: Do all of this in scripts/pnglibconf.dfa */
+#ifdef PNG_SAFE_LIMITS_SUPPORTED
+#  ifdef PNG_USER_WIDTH_MAX
+#    undef PNG_USER_WIDTH_MAX
+#    define PNG_USER_WIDTH_MAX 1000000L
+#  endif
+#  ifdef PNG_USER_HEIGHT_MAX
+#    undef PNG_USER_HEIGHT_MAX
+#    define PNG_USER_HEIGHT_MAX 1000000L
+#  endif
+#  ifdef PNG_USER_CHUNK_MALLOC_MAX
+#    undef PNG_USER_CHUNK_MALLOC_MAX
+#    define PNG_USER_CHUNK_MALLOC_MAX 4000000L
+#  endif
+#  ifdef PNG_USER_CHUNK_CACHE_MAX
+#    undef PNG_USER_CHUNK_CACHE_MAX
+#    define PNG_USER_CHUNK_CACHE_MAX 128
+#  endif
+#endif
+
+#ifndef PNG_BUILDING_SYMBOL_TABLE /* else includes may cause problems */
+
+/* From libpng 1.6.0 libpng requires an ANSI X3.159-1989 ("ISOC90") compliant C
+ * compiler for correct compilation.  The following header files are required by
+ * the standard.  If your compiler doesn't provide these header files, or they
+ * do not match the standard, you will need to provide/improve them.
+ */
+#include <limits.h>
+#include <stddef.h>
+
+/* Library header files.  These header files are all defined by ISOC90; libpng
+ * expects conformant implementations, however, an ISOC90 conformant system need
+ * not provide these header files if the functionality cannot be implemented.
+ * In this case it will be necessary to disable the relevant parts of libpng in
+ * the build of pnglibconf.h.
+ *
+ * Prior to 1.6.0 string.h was included here; the API changes in 1.6.0 to not
+ * include this unnecessary header file.
+ */
+
+#ifdef PNG_STDIO_SUPPORTED
+   /* Required for the definition of FILE: */
+#  include <stdio.h>
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+   /* Required for the definition of jmp_buf and the declaration of longjmp: */
+#  include <setjmp.h>
+#endif
+
+#ifdef PNG_CONVERT_tIME_SUPPORTED
+   /* Required for struct tm: */
+#  include <time.h>
+#endif
+
+#endif /* PNG_BUILDING_SYMBOL_TABLE */
+
+/* Prior to 1.6.0 it was possible to turn off 'const' in declarations using
+ * PNG_NO_CONST; this is no longer supported except for data declarations which
+ * apparently still cause problems in 2011 on some compilers.
+ */
+#define PNG_CONST const /* backward compatibility only */
+
+/* This controls optimization of the reading of 16 and 32 bit values
+ * from PNG files.  It can be set on a per-app-file basis - it
+ * just changes whether a macro is used when the function is called.
+ * The library builder sets the default; if read functions are not
+ * built into the library the macro implementation is forced on.
+ */
+#ifndef PNG_READ_INT_FUNCTIONS_SUPPORTED
+#  define PNG_USE_READ_MACROS
+#endif
+#if !defined(PNG_NO_USE_READ_MACROS) && !defined(PNG_USE_READ_MACROS)
+#  if PNG_DEFAULT_READ_MACROS
+#    define PNG_USE_READ_MACROS
+#  endif
+#endif
+
+/* COMPILER SPECIFIC OPTIONS.
+ *
+ * These options are provided so that a variety of difficult compilers
+ * can be used.  Some are fixed at build time (e.g. PNG_API_RULE
+ * below) but still have compiler specific implementations, others
+ * may be changed on a per-file basis when compiling against libpng.
+ */
+
+/* The PNGARG macro was used in versions of libpng prior to 1.6.0 to protect
+ * against legacy (pre ISOC90) compilers that did not understand function
+ * prototypes.  It is not required for modern C compilers.
+ */
+#ifndef PNGARG
+#  define PNGARG(arglist) arglist
+#endif
+
+/* Function calling conventions.
+ * =============================
+ * Normally it is not necessary to specify to the compiler how to call
+ * a function - it just does it - however on x86 systems derived from
+ * Microsoft and Borland C compilers ('IBM PC', 'DOS', 'Windows' systems
+ * and some others) there are multiple ways to call a function and the
+ * default can be changed on the compiler command line.  For this reason
+ * libpng specifies the calling convention of every exported function and
+ * every function called via a user supplied function pointer.  This is
+ * done in this file by defining the following macros:
+ *
+ * PNGAPI    Calling convention for exported functions.
+ * PNGCBAPI  Calling convention for user provided (callback) functions.
+ * PNGCAPI   Calling convention used by the ANSI-C library (required
+ *           for longjmp callbacks and sometimes used internally to
+ *           specify the calling convention for zlib).
+ *
+ * These macros should never be overridden.  If it is necessary to
+ * change calling convention in a private build this can be done
+ * by setting PNG_API_RULE (which defaults to 0) to one of the values
+ * below to select the correct 'API' variants.
+ *
+ * PNG_API_RULE=0 Use PNGCAPI - the 'C' calling convention - throughout.
+ *                This is correct in every known environment.
+ * PNG_API_RULE=1 Use the operating system convention for PNGAPI and
+ *                the 'C' calling convention (from PNGCAPI) for
+ *                callbacks (PNGCBAPI).  This is no longer required
+ *                in any known environment - if it has to be used
+ *                please post an explanation of the problem to the
+ *                libpng mailing list.
+ *
+ * These cases only differ if the operating system does not use the C
+ * calling convention, at present this just means the above cases
+ * (x86 DOS/Windows sytems) and, even then, this does not apply to
+ * Cygwin running on those systems.
+ *
+ * Note that the value must be defined in pnglibconf.h so that what
+ * the application uses to call the library matches the conventions
+ * set when building the library.
+ */
+
+/* Symbol export
+ * =============
+ * When building a shared library it is almost always necessary to tell
+ * the compiler which symbols to export.  The png.h macro 'PNG_EXPORT'
+ * is used to mark the symbols.  On some systems these symbols can be
+ * extracted at link time and need no special processing by the compiler,
+ * on other systems the symbols are flagged by the compiler and just
+ * the declaration requires a special tag applied (unfortunately) in a
+ * compiler dependent way.  Some systems can do either.
+ *
+ * A small number of older systems also require a symbol from a DLL to
+ * be flagged to the program that calls it.  This is a problem because
+ * we do not know in the header file included by application code that
+ * the symbol will come from a shared library, as opposed to a statically
+ * linked one.  For this reason the application must tell us by setting
+ * the magic flag PNG_USE_DLL to turn on the special processing before
+ * it includes png.h.
+ *
+ * Four additional macros are used to make this happen:
+ *
+ * PNG_IMPEXP The magic (if any) to cause a symbol to be exported from
+ *            the build or imported if PNG_USE_DLL is set - compiler
+ *            and system specific.
+ *
+ * PNG_EXPORT_TYPE(type) A macro that pre or appends PNG_IMPEXP to
+ *                       'type', compiler specific.
+ *
+ * PNG_DLL_EXPORT Set to the magic to use during a libpng build to
+ *                make a symbol exported from the DLL.  Not used in the
+ *                public header files; see pngpriv.h for how it is used
+ *                in the libpng build.
+ *
+ * PNG_DLL_IMPORT Set to the magic to force the libpng symbols to come
+ *                from a DLL - used to define PNG_IMPEXP when
+ *                PNG_USE_DLL is set.
+ */
+
+/* System specific discovery.
+ * ==========================
+ * This code is used at build time to find PNG_IMPEXP, the API settings
+ * and PNG_EXPORT_TYPE(), it may also set a macro to indicate the DLL
+ * import processing is possible.  On Windows systems it also sets
+ * compiler-specific macros to the values required to change the calling
+ * conventions of the various functions.
+ */
+#if defined(_Windows) || defined(_WINDOWS) || defined(WIN32) ||\
+    defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
+  /* Windows system (DOS doesn't support DLLs).  Includes builds under Cygwin or
+   * MinGW on any architecture currently supported by Windows.  Also includes
+   * Watcom builds but these need special treatment because they are not
+   * compatible with GCC or Visual C because of different calling conventions.
+   */
+#  if PNG_API_RULE == 2
+    /* If this line results in an error, either because __watcall is not
+     * understood or because of a redefine just below you cannot use *this*
+     * build of the library with the compiler you are using.  *This* build was
+     * build using Watcom and applications must also be built using Watcom!
+     */
+#    define PNGCAPI __watcall
+#  endif
+
+#  if defined(__GNUC__) || (defined(_MSC_VER) && (_MSC_VER >= 800))
+#    define PNGCAPI __cdecl
+#    if PNG_API_RULE == 1
+       /* If this line results in an error __stdcall is not understood and
+        * PNG_API_RULE should not have been set to '1'.
+        */
+#      define PNGAPI __stdcall
+#    endif
+#  else
+    /* An older compiler, or one not detected (erroneously) above,
+     * if necessary override on the command line to get the correct
+     * variants for the compiler.
+     */
+#    ifndef PNGCAPI
+#      define PNGCAPI _cdecl
+#    endif
+#    if PNG_API_RULE == 1 && !defined(PNGAPI)
+#      define PNGAPI _stdcall
+#    endif
+#  endif /* compiler/api */
+
+  /* NOTE: PNGCBAPI always defaults to PNGCAPI. */
+
+#  if defined(PNGAPI) && !defined(PNG_USER_PRIVATEBUILD)
+#     error "PNG_USER_PRIVATEBUILD must be defined if PNGAPI is changed"
+#  endif
+
+#  if (defined(_MSC_VER) && _MSC_VER < 800) ||\
+      (defined(__BORLANDC__) && __BORLANDC__ < 0x500)
+    /* older Borland and MSC
+     * compilers used '__export' and required this to be after
+     * the type.
+     */
+#    ifndef PNG_EXPORT_TYPE
+#      define PNG_EXPORT_TYPE(type) type PNG_IMPEXP
+#    endif
+#    define PNG_DLL_EXPORT __export
+#  else /* newer compiler */
+#    define PNG_DLL_EXPORT __declspec(dllexport)
+#    ifndef PNG_DLL_IMPORT
+#      define PNG_DLL_IMPORT __declspec(dllimport)
+#    endif
+#  endif /* compiler */
+
+#else /* !Windows */
+#  if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__)
+#    define PNGAPI _System
+#  else /* !Windows/x86 && !OS/2 */
+    /* Use the defaults, or define PNG*API on the command line (but
+     * this will have to be done for every compile!)
+     */
+#  endif /* other system, !OS/2 */
+#endif /* !Windows/x86 */
+
+/* Now do all the defaulting . */
+#ifndef PNGCAPI
+#  define PNGCAPI
+#endif
+#ifndef PNGCBAPI
+#  define PNGCBAPI PNGCAPI
+#endif
+#ifndef PNGAPI
+#  define PNGAPI PNGCAPI
+#endif
+
+/* PNG_IMPEXP may be set on the compilation system command line or (if not set)
+ * then in an internal header file when building the library, otherwise (when
+ * using the library) it is set here.
+ */
+#ifndef PNG_IMPEXP
+#  if defined(PNG_USE_DLL) && defined(PNG_DLL_IMPORT)
+     /* This forces use of a DLL, disallowing static linking */
+#    define PNG_IMPEXP PNG_DLL_IMPORT
+#  endif
+
+#  ifndef PNG_IMPEXP
+#    define PNG_IMPEXP
+#  endif
+#endif
+
+/* In 1.5.2 the definition of PNG_FUNCTION has been changed to always treat
+ * 'attributes' as a storage class - the attributes go at the start of the
+ * function definition, and attributes are always appended regardless of the
+ * compiler.  This considerably simplifies these macros but may cause problems
+ * if any compilers both need function attributes and fail to handle them as
+ * a storage class (this is unlikely.)
+ */
+#ifndef PNG_FUNCTION
+#  define PNG_FUNCTION(type, name, args, attributes) attributes type name args
+#endif
+
+#ifndef PNG_EXPORT_TYPE
+#  define PNG_EXPORT_TYPE(type) PNG_IMPEXP type
+#endif
+
+   /* The ordinal value is only relevant when preprocessing png.h for symbol
+    * table entries, so we discard it here.  See the .dfn files in the
+    * scripts directory.
+    */
+#ifndef PNG_EXPORTA
+
+#  define PNG_EXPORTA(ordinal, type, name, args, attributes)\
+      PNG_FUNCTION(PNG_EXPORT_TYPE(type),(PNGAPI name),PNGARG(args), \
+        extern attributes)
+#endif
+
+/* ANSI-C (C90) does not permit a macro to be invoked with an empty argument,
+ * so make something non-empty to satisfy the requirement:
+ */
+#define PNG_EMPTY /*empty list*/
+
+#define PNG_EXPORT(ordinal, type, name, args)\
+   PNG_EXPORTA(ordinal, type, name, args, PNG_EMPTY)
+
+/* Use PNG_REMOVED to comment out a removed interface. */
+#ifndef PNG_REMOVED
+#  define PNG_REMOVED(ordinal, type, name, args, attributes)
+#endif
+
+#ifndef PNG_CALLBACK
+#  define PNG_CALLBACK(type, name, args) type (PNGCBAPI name) PNGARG(args)
+#endif
+
+/* Support for compiler specific function attributes.  These are used
+ * so that where compiler support is available incorrect use of API
+ * functions in png.h will generate compiler warnings.
+ *
+ * Added at libpng-1.2.41.
+ */
+
+#ifndef PNG_NO_PEDANTIC_WARNINGS
+#  ifndef PNG_PEDANTIC_WARNINGS_SUPPORTED
+#    define PNG_PEDANTIC_WARNINGS_SUPPORTED
+#  endif
+#endif
+
+#ifdef PNG_PEDANTIC_WARNINGS_SUPPORTED
+  /* Support for compiler specific function attributes.  These are used
+   * so that where compiler support is available, incorrect use of API
+   * functions in png.h will generate compiler warnings.  Added at libpng
+   * version 1.2.41.  Disabling these removes the warnings but may also produce
+   * less efficient code.
+   */
+#  if defined(__clang__) && defined(__has_attribute)
+     /* Clang defines both __clang__ and __GNUC__. Check __clang__ first. */
+#    if !defined(PNG_USE_RESULT) && __has_attribute(__warn_unused_result__)
+#      define PNG_USE_RESULT __attribute__((__warn_unused_result__))
+#    endif
+#    if !defined(PNG_NORETURN) && __has_attribute(__noreturn__)
+#      define PNG_NORETURN __attribute__((__noreturn__))
+#    endif
+#    if !defined(PNG_ALLOCATED) && __has_attribute(__malloc__)
+#      define PNG_ALLOCATED __attribute__((__malloc__))
+#    endif
+#    if !defined(PNG_DEPRECATED) && __has_attribute(__deprecated__)
+#      define PNG_DEPRECATED __attribute__((__deprecated__))
+#    endif
+#    if !defined(PNG_PRIVATE)
+#      ifdef __has_extension
+#        if __has_extension(attribute_unavailable_with_message)
+#          define PNG_PRIVATE __attribute__((__unavailable__(\
+             "This function is not exported by libpng.")))
+#        endif
+#      endif
+#    endif
+#    ifndef PNG_RESTRICT
+#      define PNG_RESTRICT __restrict
+#    endif
+
+#  elif defined(__GNUC__)
+#    ifndef PNG_USE_RESULT
+#      define PNG_USE_RESULT __attribute__((__warn_unused_result__))
+#    endif
+#    ifndef PNG_NORETURN
+#      define PNG_NORETURN   __attribute__((__noreturn__))
+#    endif
+#    if __GNUC__ >= 3
+#      ifndef PNG_ALLOCATED
+#        define PNG_ALLOCATED  __attribute__((__malloc__))
+#      endif
+#      ifndef PNG_DEPRECATED
+#        define PNG_DEPRECATED __attribute__((__deprecated__))
+#      endif
+#      ifndef PNG_PRIVATE
+#        if 0 /* Doesn't work so we use deprecated instead*/
+#          define PNG_PRIVATE \
+            __attribute__((warning("This function is not exported by libpng.")))
+#        else
+#          define PNG_PRIVATE \
+            __attribute__((__deprecated__))
+#        endif
+#      endif
+#      if ((__GNUC__ > 3) || !defined(__GNUC_MINOR__) || (__GNUC_MINOR__ >= 1))
+#        ifndef PNG_RESTRICT
+#          define PNG_RESTRICT __restrict
+#        endif
+#      endif /* __GNUC__.__GNUC_MINOR__ > 3.0 */
+#    endif /* __GNUC__ >= 3 */
+
+#  elif defined(_MSC_VER)  && (_MSC_VER >= 1300)
+#    ifndef PNG_USE_RESULT
+#      define PNG_USE_RESULT /* not supported */
+#    endif
+#    ifndef PNG_NORETURN
+#      define PNG_NORETURN   __declspec(noreturn)
+#    endif
+#    ifndef PNG_ALLOCATED
+#      if (_MSC_VER >= 1400)
+#        define PNG_ALLOCATED __declspec(restrict)
+#      endif
+#    endif
+#    ifndef PNG_DEPRECATED
+#      define PNG_DEPRECATED __declspec(deprecated)
+#    endif
+#    ifndef PNG_PRIVATE
+#      define PNG_PRIVATE __declspec(deprecated)
+#    endif
+#    ifndef PNG_RESTRICT
+#      if (_MSC_VER >= 1400)
+#        define PNG_RESTRICT __restrict
+#      endif
+#    endif
+
+#  elif defined(__WATCOMC__)
+#    ifndef PNG_RESTRICT
+#      define PNG_RESTRICT __restrict
+#    endif
+#  endif
+#endif /* PNG_PEDANTIC_WARNINGS */
+
+#ifndef PNG_DEPRECATED
+#  define PNG_DEPRECATED  /* Use of this function is deprecated */
+#endif
+#ifndef PNG_USE_RESULT
+#  define PNG_USE_RESULT  /* The result of this function must be checked */
+#endif
+#ifndef PNG_NORETURN
+#  define PNG_NORETURN    /* This function does not return */
+#endif
+#ifndef PNG_ALLOCATED
+#  define PNG_ALLOCATED   /* The result of the function is new memory */
+#endif
+#ifndef PNG_PRIVATE
+#  define PNG_PRIVATE     /* This is a private libpng function */
+#endif
+#ifndef PNG_RESTRICT
+#  define PNG_RESTRICT    /* The C99 "restrict" feature */
+#endif
+
+#ifndef PNG_FP_EXPORT     /* A floating point API. */
+#  ifdef PNG_FLOATING_POINT_SUPPORTED
+#     define PNG_FP_EXPORT(ordinal, type, name, args)\
+         PNG_EXPORT(ordinal, type, name, args);
+#  else                   /* No floating point APIs */
+#     define PNG_FP_EXPORT(ordinal, type, name, args)
+#  endif
+#endif
+#ifndef PNG_FIXED_EXPORT  /* A fixed point API. */
+#  ifdef PNG_FIXED_POINT_SUPPORTED
+#     define PNG_FIXED_EXPORT(ordinal, type, name, args)\
+         PNG_EXPORT(ordinal, type, name, args);
+#  else                   /* No fixed point APIs */
+#     define PNG_FIXED_EXPORT(ordinal, type, name, args)
+#  endif
+#endif
+
+#ifndef PNG_BUILDING_SYMBOL_TABLE
+/* Some typedefs to get us started.  These should be safe on most of the common
+ * platforms.
+ *
+ * png_uint_32 and png_int_32 may, currently, be larger than required to hold a
+ * 32-bit value however this is not normally advisable.
+ *
+ * png_uint_16 and png_int_16 should always be two bytes in size - this is
+ * verified at library build time.
+ *
+ * png_byte must always be one byte in size.
+ *
+ * The checks below use constants from limits.h, as defined by the ISOC90
+ * standard.
+ */
+#if CHAR_BIT == 8 && UCHAR_MAX == 255
+   typedef unsigned char png_byte;
+#else
+#  error "libpng requires 8 bit bytes"
+#endif
+
+#if INT_MIN == -32768 && INT_MAX == 32767
+   typedef int png_int_16;
+#elif SHRT_MIN == -32768 && SHRT_MAX == 32767
+   typedef short png_int_16;
+#else
+#  error "libpng requires a signed 16 bit type"
+#endif
+
+#if UINT_MAX == 65535
+   typedef unsigned int png_uint_16;
+#elif USHRT_MAX == 65535
+   typedef unsigned short png_uint_16;
+#else
+#  error "libpng requires an unsigned 16 bit type"
+#endif
+
+#if INT_MIN < -2147483646 && INT_MAX > 2147483646
+   typedef int png_int_32;
+#elif LONG_MIN < -2147483646 && LONG_MAX > 2147483646
+   typedef long int png_int_32;
+#else
+#  error "libpng requires a signed 32 bit (or more) type"
+#endif
+
+#if UINT_MAX > 4294967294
+   typedef unsigned int png_uint_32;
+#elif ULONG_MAX > 4294967294
+   typedef unsigned long int png_uint_32;
+#else
+#  error "libpng requires an unsigned 32 bit (or more) type"
+#endif
+
+/* Prior to 1.6.0 it was possible to disable the use of size_t, 1.6.0, however,
+ * requires an ISOC90 compiler and relies on consistent behavior of sizeof.
+ */
+typedef size_t png_size_t;
+typedef ptrdiff_t png_ptrdiff_t;
+
+/* libpng needs to know the maximum value of 'size_t' and this controls the
+ * definition of png_alloc_size_t, below.  This maximum value of size_t limits
+ * but does not control the maximum allocations the library makes - there is
+ * direct application control of this through png_set_user_limits().
+ */
+#ifndef PNG_SMALL_SIZE_T
+   /* Compiler specific tests for systems where size_t is known to be less than
+    * 32 bits (some of these systems may no longer work because of the lack of
+    * 'far' support; see above.)
+    */
+#  if (defined(__TURBOC__) && !defined(__FLAT__)) ||\
+   (defined(_MSC_VER) && defined(MAXSEG_64K))
+#     define PNG_SMALL_SIZE_T
+#  endif
+#endif
+
+/* png_alloc_size_t is guaranteed to be no smaller than png_size_t, and no
+ * smaller than png_uint_32.  Casts from png_size_t or png_uint_32 to
+ * png_alloc_size_t are not necessary; in fact, it is recommended not to use
+ * them at all so that the compiler can complain when something turns out to be
+ * problematic.
+ *
+ * Casts in the other direction (from png_alloc_size_t to png_size_t or
+ * png_uint_32) should be explicitly applied; however, we do not expect to
+ * encounter practical situations that require such conversions.
+ *
+ * PNG_SMALL_SIZE_T must be defined if the maximum value of size_t is less than
+ * 4294967295 - i.e. less than the maximum value of png_uint_32.
+ */
+#ifdef PNG_SMALL_SIZE_T
+   typedef png_uint_32 png_alloc_size_t;
+#else
+   typedef png_size_t png_alloc_size_t;
+#endif
+
+/* Prior to 1.6.0 libpng offered limited support for Microsoft C compiler
+ * implementations of Intel CPU specific support of user-mode segmented address
+ * spaces, where 16-bit pointers address more than 65536 bytes of memory using
+ * separate 'segment' registers.  The implementation requires two different
+ * types of pointer (only one of which includes the segment value.)
+ *
+ * If required this support is available in version 1.2 of libpng and may be
+ * available in versions through 1.5, although the correctness of the code has
+ * not been verified recently.
+ */
+
+/* Typedef for floating-point numbers that are converted to fixed-point with a
+ * multiple of 100,000, e.g., gamma
+ */
+typedef png_int_32 png_fixed_point;
+
+/* Add typedefs for pointers */
+typedef void                  * png_voidp;
+typedef const void            * png_const_voidp;
+typedef png_byte              * png_bytep;
+typedef const png_byte        * png_const_bytep;
+typedef png_uint_32           * png_uint_32p;
+typedef const png_uint_32     * png_const_uint_32p;
+typedef png_int_32            * png_int_32p;
+typedef const png_int_32      * png_const_int_32p;
+typedef png_uint_16           * png_uint_16p;
+typedef const png_uint_16     * png_const_uint_16p;
+typedef png_int_16            * png_int_16p;
+typedef const png_int_16      * png_const_int_16p;
+typedef char                  * png_charp;
+typedef const char            * png_const_charp;
+typedef png_fixed_point       * png_fixed_point_p;
+typedef const png_fixed_point * png_const_fixed_point_p;
+typedef png_size_t            * png_size_tp;
+typedef const png_size_t      * png_const_size_tp;
+
+#ifdef PNG_STDIO_SUPPORTED
+typedef FILE            * png_FILE_p;
+#endif
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+typedef double       * png_doublep;
+typedef const double * png_const_doublep;
+#endif
+
+/* Pointers to pointers; i.e. arrays */
+typedef png_byte        * * png_bytepp;
+typedef png_uint_32     * * png_uint_32pp;
+typedef png_int_32      * * png_int_32pp;
+typedef png_uint_16     * * png_uint_16pp;
+typedef png_int_16      * * png_int_16pp;
+typedef const char      * * png_const_charpp;
+typedef char            * * png_charpp;
+typedef png_fixed_point * * png_fixed_point_pp;
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+typedef double          * * png_doublepp;
+#endif
+
+/* Pointers to pointers to pointers; i.e., pointer to array */
+typedef char            * * * png_charppp;
+
+#endif /* PNG_BUILDING_SYMBOL_TABLE */
+
+#endif /* PNGCONF_H */
diff --git a/Source/LibPNG/pngdebug.h b/Source/LibPNG/pngdebug.h
index 96c1ea4..b43c59c 100644
--- a/Source/LibPNG/pngdebug.h
+++ b/Source/LibPNG/pngdebug.h
@@ -1,157 +1,154 @@
-
-/* pngdebug.h - Debugging macros for libpng, also used in pngtest.c
- *
- * Copyright (c) 1998-2011 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- *
- * Last changed in libpng 1.5.0 [January 6, 2011]
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- */
-
-/* Define PNG_DEBUG at compile time for debugging information.  Higher
- * numbers for PNG_DEBUG mean more debugging information.  This has
- * only been added since version 0.95 so it is not implemented throughout
- * libpng yet, but more support will be added as needed.
- *
- * png_debug[1-2]?(level, message ,arg{0-2})
- *   Expands to a statement (either a simple expression or a compound
- *   do..while(0) statement) that outputs a message with parameter
- *   substitution if PNG_DEBUG is defined to 2 or more.  If PNG_DEBUG
- *   is undefined, 0 or 1 every png_debug expands to a simple expression
- *   (actually ((void)0)).
- *
- *   level: level of detail of message, starting at 0.  A level 'n'
- *          message is preceded by 'n' tab characters (not implemented
- *          on Microsoft compilers unless PNG_DEBUG_FILE is also
- *          defined, to allow debug DLL compilation with no standard IO).
- *   message: a printf(3) style text string.  A trailing '\n' is added
- *            to the message.
- *   arg: 0 to 2 arguments for printf(3) style substitution in message.
- */
-#ifndef PNGDEBUG_H
-#define PNGDEBUG_H
-/* These settings control the formatting of messages in png.c and pngerror.c */
-/* Moved to pngdebug.h at 1.5.0 */
-#  ifndef PNG_LITERAL_SHARP
-#    define PNG_LITERAL_SHARP 0x23
-#  endif
-#  ifndef PNG_LITERAL_LEFT_SQUARE_BRACKET
-#    define PNG_LITERAL_LEFT_SQUARE_BRACKET 0x5b
-#  endif
-#  ifndef PNG_LITERAL_RIGHT_SQUARE_BRACKET
-#    define PNG_LITERAL_RIGHT_SQUARE_BRACKET 0x5d
-#  endif
-#  ifndef PNG_STRING_NEWLINE
-#    define PNG_STRING_NEWLINE "\n"
-#  endif
-
-#ifdef PNG_DEBUG
-#  if (PNG_DEBUG > 0)
-#    if !defined(PNG_DEBUG_FILE) && defined(_MSC_VER)
-#      include <crtdbg.h>
-#      if (PNG_DEBUG > 1)
-#        ifndef _DEBUG
-#          define _DEBUG
-#        endif
-#        ifndef png_debug
-#          define png_debug(l,m)  _RPT0(_CRT_WARN,m PNG_STRING_NEWLINE)
-#        endif
-#        ifndef png_debug1
-#          define png_debug1(l,m,p1)  _RPT1(_CRT_WARN,m PNG_STRING_NEWLINE,p1)
-#        endif
-#        ifndef png_debug2
-#          define png_debug2(l,m,p1,p2) \
-             _RPT2(_CRT_WARN,m PNG_STRING_NEWLINE,p1,p2)
-#        endif
-#      endif
-#    else /* PNG_DEBUG_FILE || !_MSC_VER */
-#      ifndef PNG_STDIO_SUPPORTED
-#        include <stdio.h> /* not included yet */
-#      endif
-#      ifndef PNG_DEBUG_FILE
-#        define PNG_DEBUG_FILE stderr
-#      endif /* PNG_DEBUG_FILE */
-
-#      if (PNG_DEBUG > 1)
-/* Note: ["%s"m PNG_STRING_NEWLINE] probably does not work on
- * non-ISO compilers
- */
-#        ifdef __STDC__
-#          ifndef png_debug
-#            define png_debug(l,m) \
-       do { \
-       int num_tabs=l; \
-       fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \
-         (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":"")))); \
-       } while (0)
-#          endif
-#          ifndef png_debug1
-#            define png_debug1(l,m,p1) \
-       do { \
-       int num_tabs=l; \
-       fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \
-         (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1); \
-       } while (0)
-#          endif
-#          ifndef png_debug2
-#            define png_debug2(l,m,p1,p2) \
-       do { \
-       int num_tabs=l; \
-       fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \
-         (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1,p2); \
-       } while (0)
-#          endif
-#        else /* __STDC __ */
-#          ifndef png_debug
-#            define png_debug(l,m) \
-       do { \
-       int num_tabs=l; \
-       char format[256]; \
-       snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \
-         (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \
-         m,PNG_STRING_NEWLINE); \
-       fprintf(PNG_DEBUG_FILE,format); \
-       } while (0)
-#          endif
-#          ifndef png_debug1
-#            define png_debug1(l,m,p1) \
-       do { \
-       int num_tabs=l; \
-       char format[256]; \
-       snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \
-         (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \
-         m,PNG_STRING_NEWLINE); \
-       fprintf(PNG_DEBUG_FILE,format,p1); \
-       } while (0)
-#          endif
-#          ifndef png_debug2
-#            define png_debug2(l,m,p1,p2) \
-       do { \
-       int num_tabs=l; \
-       char format[256]; \
-       snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \
-         (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \
-         m,PNG_STRING_NEWLINE); \
-       fprintf(PNG_DEBUG_FILE,format,p1,p2); \
-       } while (0)
-#          endif
-#        endif /* __STDC __ */
-#      endif /* (PNG_DEBUG > 1) */
-
-#    endif /* _MSC_VER */
-#  endif /* (PNG_DEBUG > 0) */
-#endif /* PNG_DEBUG */
-#ifndef png_debug
-#  define png_debug(l, m) ((void)0)
-#endif
-#ifndef png_debug1
-#  define png_debug1(l, m, p1) ((void)0)
-#endif
-#ifndef png_debug2
-#  define png_debug2(l, m, p1, p2) ((void)0)
-#endif
-#endif /* PNGDEBUG_H */
+
+/* pngdebug.h - Debugging macros for libpng, also used in pngtest.c
+ *
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * Last changed in libpng 1.6.8 [December 19, 2013]
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+/* Define PNG_DEBUG at compile time for debugging information.  Higher
+ * numbers for PNG_DEBUG mean more debugging information.  This has
+ * only been added since version 0.95 so it is not implemented throughout
+ * libpng yet, but more support will be added as needed.
+ *
+ * png_debug[1-2]?(level, message ,arg{0-2})
+ *   Expands to a statement (either a simple expression or a compound
+ *   do..while(0) statement) that outputs a message with parameter
+ *   substitution if PNG_DEBUG is defined to 2 or more.  If PNG_DEBUG
+ *   is undefined, 0 or 1 every png_debug expands to a simple expression
+ *   (actually ((void)0)).
+ *
+ *   level: level of detail of message, starting at 0.  A level 'n'
+ *          message is preceded by 'n' 3-space indentations (not implemented
+ *          on Microsoft compilers unless PNG_DEBUG_FILE is also
+ *          defined, to allow debug DLL compilation with no standard IO).
+ *   message: a printf(3) style text string.  A trailing '\n' is added
+ *            to the message.
+ *   arg: 0 to 2 arguments for printf(3) style substitution in message.
+ */
+#ifndef PNGDEBUG_H
+#define PNGDEBUG_H
+/* These settings control the formatting of messages in png.c and pngerror.c */
+/* Moved to pngdebug.h at 1.5.0 */
+#  ifndef PNG_LITERAL_SHARP
+#    define PNG_LITERAL_SHARP 0x23
+#  endif
+#  ifndef PNG_LITERAL_LEFT_SQUARE_BRACKET
+#    define PNG_LITERAL_LEFT_SQUARE_BRACKET 0x5b
+#  endif
+#  ifndef PNG_LITERAL_RIGHT_SQUARE_BRACKET
+#    define PNG_LITERAL_RIGHT_SQUARE_BRACKET 0x5d
+#  endif
+#  ifndef PNG_STRING_NEWLINE
+#    define PNG_STRING_NEWLINE "\n"
+#  endif
+
+#ifdef PNG_DEBUG
+#  if (PNG_DEBUG > 0)
+#    if !defined(PNG_DEBUG_FILE) && defined(_MSC_VER)
+#      include <crtdbg.h>
+#      if (PNG_DEBUG > 1)
+#        ifndef _DEBUG
+#          define _DEBUG
+#        endif
+#        ifndef png_debug
+#          define png_debug(l,m)  _RPT0(_CRT_WARN,m PNG_STRING_NEWLINE)
+#        endif
+#        ifndef png_debug1
+#          define png_debug1(l,m,p1)  _RPT1(_CRT_WARN,m PNG_STRING_NEWLINE,p1)
+#        endif
+#        ifndef png_debug2
+#          define png_debug2(l,m,p1,p2) \
+             _RPT2(_CRT_WARN,m PNG_STRING_NEWLINE,p1,p2)
+#        endif
+#      endif
+#    else /* PNG_DEBUG_FILE || !_MSC_VER */
+#      ifndef PNG_STDIO_SUPPORTED
+#        include <stdio.h> /* not included yet */
+#      endif
+#      ifndef PNG_DEBUG_FILE
+#        define PNG_DEBUG_FILE stderr
+#      endif /* PNG_DEBUG_FILE */
+
+#      if (PNG_DEBUG > 1)
+#        ifdef __STDC__
+#          ifndef png_debug
+#            define png_debug(l,m) \
+       do { \
+       int num_tabs=l; \
+       fprintf(PNG_DEBUG_FILE,"%s" m PNG_STRING_NEWLINE,(num_tabs==1 ? "   " : \
+         (num_tabs==2 ? "      " : (num_tabs>2 ? "         " : "")))); \
+       } while (0)
+#          endif
+#          ifndef png_debug1
+#            define png_debug1(l,m,p1) \
+       do { \
+       int num_tabs=l; \
+       fprintf(PNG_DEBUG_FILE,"%s" m PNG_STRING_NEWLINE,(num_tabs==1 ? "   " : \
+         (num_tabs==2 ? "      " : (num_tabs>2 ? "         " : ""))),p1); \
+       } while (0)
+#          endif
+#          ifndef png_debug2
+#            define png_debug2(l,m,p1,p2) \
+       do { \
+       int num_tabs=l; \
+       fprintf(PNG_DEBUG_FILE,"%s" m PNG_STRING_NEWLINE,(num_tabs==1 ? "   " : \
+         (num_tabs==2 ? "      " : (num_tabs>2 ? "         " : ""))),p1,p2);\
+       } while (0)
+#          endif
+#        else /* __STDC __ */
+#          ifndef png_debug
+#            define png_debug(l,m) \
+       do { \
+       int num_tabs=l; \
+       char format[256]; \
+       snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \
+         (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \
+         m,PNG_STRING_NEWLINE); \
+       fprintf(PNG_DEBUG_FILE,format); \
+       } while (0)
+#          endif
+#          ifndef png_debug1
+#            define png_debug1(l,m,p1) \
+       do { \
+       int num_tabs=l; \
+       char format[256]; \
+       snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \
+         (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \
+         m,PNG_STRING_NEWLINE); \
+       fprintf(PNG_DEBUG_FILE,format,p1); \
+       } while (0)
+#          endif
+#          ifndef png_debug2
+#            define png_debug2(l,m,p1,p2) \
+       do { \
+       int num_tabs=l; \
+       char format[256]; \
+       snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \
+         (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \
+         m,PNG_STRING_NEWLINE); \
+       fprintf(PNG_DEBUG_FILE,format,p1,p2); \
+       } while (0)
+#          endif
+#        endif /* __STDC __ */
+#      endif /* (PNG_DEBUG > 1) */
+
+#    endif /* _MSC_VER */
+#  endif /* (PNG_DEBUG > 0) */
+#endif /* PNG_DEBUG */
+#ifndef png_debug
+#  define png_debug(l, m) ((void)0)
+#endif
+#ifndef png_debug1
+#  define png_debug1(l, m, p1) ((void)0)
+#endif
+#ifndef png_debug2
+#  define png_debug2(l, m, p1, p2) ((void)0)
+#endif
+#endif /* PNGDEBUG_H */
diff --git a/Source/LibPNG/pngerror.c b/Source/LibPNG/pngerror.c
index ef60d55..0781866 100644
--- a/Source/LibPNG/pngerror.c
+++ b/Source/LibPNG/pngerror.c
@@ -1,685 +1,963 @@
-
-/* pngerror.c - stub functions for i/o and memory allocation
- *
- * Last changed in libpng 1.5.8 [February 1, 2011]
- * Copyright (c) 1998-2011 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- *
- * This file provides a location for all error handling.  Users who
- * need special error handling are expected to write replacement functions
- * and use png_set_error_fn() to use those functions.  See the instructions
- * at each function.
- */
-
-#include "pngpriv.h"
-
-#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
-
-static PNG_FUNCTION(void, png_default_error,PNGARG((png_structp png_ptr,
-    png_const_charp error_message)),PNG_NORETURN);
-
-#ifdef PNG_WARNINGS_SUPPORTED
-static void /* PRIVATE */
-png_default_warning PNGARG((png_structp png_ptr,
-   png_const_charp warning_message));
-#endif /* PNG_WARNINGS_SUPPORTED */
-
-/* This function is called whenever there is a fatal error.  This function
- * should not be changed.  If there is a need to handle errors differently,
- * you should supply a replacement error function and use png_set_error_fn()
- * to replace the error function at run-time.
- */
-#ifdef PNG_ERROR_TEXT_SUPPORTED
-PNG_FUNCTION(void,PNGAPI
-png_error,(png_structp png_ptr, png_const_charp error_message),PNG_NORETURN)
-{
-#ifdef PNG_ERROR_NUMBERS_SUPPORTED
-   char msg[16];
-   if (png_ptr != NULL)
-   {
-      if (png_ptr->flags&
-         (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
-      {
-         if (*error_message == PNG_LITERAL_SHARP)
-         {
-            /* Strip "#nnnn " from beginning of error message. */
-            int offset;
-            for (offset = 1; offset<15; offset++)
-               if (error_message[offset] == ' ')
-                  break;
-
-            if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
-            {
-               int i;
-               for (i = 0; i < offset - 1; i++)
-                  msg[i] = error_message[i + 1];
-               msg[i - 1] = '\0';
-               error_message = msg;
-            }
-
-            else
-               error_message += offset;
-      }
-
-      else
-      {
-         if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
-         {
-            msg[0] = '0';
-            msg[1] = '\0';
-            error_message = msg;
-         }
-       }
-     }
-   }
-#endif
-   if (png_ptr != NULL && png_ptr->error_fn != NULL)
-      (*(png_ptr->error_fn))(png_ptr, error_message);
-
-   /* If the custom handler doesn't exist, or if it returns,
-      use the default handler, which will not return. */
-   png_default_error(png_ptr, error_message);
-}
-#else
-PNG_FUNCTION(void,PNGAPI
-png_err,(png_structp png_ptr),PNG_NORETURN)
-{
-   /* Prior to 1.5.2 the error_fn received a NULL pointer, expressed
-    * erroneously as '\0', instead of the empty string "".  This was
-    * apparently an error, introduced in libpng-1.2.20, and png_default_error
-    * will crash in this case.
-    */
-   if (png_ptr != NULL && png_ptr->error_fn != NULL)
-      (*(png_ptr->error_fn))(png_ptr, "");
-
-   /* If the custom handler doesn't exist, or if it returns,
-      use the default handler, which will not return. */
-   png_default_error(png_ptr, "");
-}
-#endif /* PNG_ERROR_TEXT_SUPPORTED */
-
-/* Utility to safely appends strings to a buffer.  This never errors out so
- * error checking is not required in the caller.
- */
-size_t
-png_safecat(png_charp buffer, size_t bufsize, size_t pos,
-   png_const_charp string)
-{
-   if (buffer != NULL && pos < bufsize)
-   {
-      if (string != NULL)
-         while (*string != '\0' && pos < bufsize-1)
-           buffer[pos++] = *string++;
-
-      buffer[pos] = '\0';
-   }
-
-   return pos;
-}
-
-#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_TIME_RFC1123_SUPPORTED)
-/* Utility to dump an unsigned value into a buffer, given a start pointer and
- * and end pointer (which should point just *beyond* the end of the buffer!)
- * Returns the pointer to the start of the formatted string.
- */
-png_charp
-png_format_number(png_const_charp start, png_charp end, int format,
-   png_alloc_size_t number)
-{
-   int count = 0;    /* number of digits output */
-   int mincount = 1; /* minimum number required */
-   int output = 0;   /* digit output (for the fixed point format) */
-
-   *--end = '\0';
-
-   /* This is written so that the loop always runs at least once, even with
-    * number zero.
-    */
-   while (end > start && (number != 0 || count < mincount))
-   {
-
-      static const char digits[] = "0123456789ABCDEF";
-
-      switch (format)
-      {
-         case PNG_NUMBER_FORMAT_fixed:
-            /* Needs five digits (the fraction) */
-            mincount = 5;
-            if (output || number % 10 != 0)
-            {
-               *--end = digits[number % 10];
-               output = 1;
-            }
-            number /= 10;
-            break;
-
-         case PNG_NUMBER_FORMAT_02u:
-            /* Expects at least 2 digits. */
-            mincount = 2;
-            /* fall through */
-
-         case PNG_NUMBER_FORMAT_u:
-            *--end = digits[number % 10];
-            number /= 10;
-            break;
-
-         case PNG_NUMBER_FORMAT_02x:
-            /* This format expects at least two digits */
-            mincount = 2;
-            /* fall through */
-
-         case PNG_NUMBER_FORMAT_x:
-            *--end = digits[number & 0xf];
-            number >>= 4;
-            break;
-
-         default: /* an error */
-            number = 0;
-            break;
-      }
-
-      /* Keep track of the number of digits added */
-      ++count;
-
-      /* Float a fixed number here: */
-      if (format == PNG_NUMBER_FORMAT_fixed) if (count == 5) if (end > start)
-      {
-         /* End of the fraction, but maybe nothing was output?  In that case
-          * drop the decimal point.  If the number is a true zero handle that
-          * here.
-          */
-         if (output)
-            *--end = '.';
-         else if (number == 0) /* and !output */
-            *--end = '0';
-      }
-   }
-
-   return end;
-}
-#endif
-
-#ifdef PNG_WARNINGS_SUPPORTED
-/* This function is called whenever there is a non-fatal error.  This function
- * should not be changed.  If there is a need to handle warnings differently,
- * you should supply a replacement warning function and use
- * png_set_error_fn() to replace the warning function at run-time.
- */
-void PNGAPI
-png_warning(png_structp png_ptr, png_const_charp warning_message)
-{
-   int offset = 0;
-   if (png_ptr != NULL)
-   {
-#ifdef PNG_ERROR_NUMBERS_SUPPORTED
-   if (png_ptr->flags&
-       (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
-#endif
-      {
-         if (*warning_message == PNG_LITERAL_SHARP)
-         {
-            for (offset = 1; offset < 15; offset++)
-               if (warning_message[offset] == ' ')
-                  break;
-         }
-      }
-   }
-   if (png_ptr != NULL && png_ptr->warning_fn != NULL)
-      (*(png_ptr->warning_fn))(png_ptr, warning_message + offset);
-   else
-      png_default_warning(png_ptr, warning_message + offset);
-}
-
-/* These functions support 'formatted' warning messages with up to
- * PNG_WARNING_PARAMETER_COUNT parameters.  In the format string the parameter
- * is introduced by @<number>, where 'number' starts at 1.  This follows the
- * standard established by X/Open for internationalizable error messages.
- */
-void
-png_warning_parameter(png_warning_parameters p, int number,
-   png_const_charp string)
-{
-   if (number > 0 && number <= PNG_WARNING_PARAMETER_COUNT)
-      (void)png_safecat(p[number-1], (sizeof p[number-1]), 0, string);
-}
-
-void
-png_warning_parameter_unsigned(png_warning_parameters p, int number, int format,
-   png_alloc_size_t value)
-{
-   char buffer[PNG_NUMBER_BUFFER_SIZE];
-   png_warning_parameter(p, number, PNG_FORMAT_NUMBER(buffer, format, value));
-}
-
-void
-png_warning_parameter_signed(png_warning_parameters p, int number, int format,
-   png_int_32 value)
-{
-   png_alloc_size_t u;
-   png_charp str;
-   char buffer[PNG_NUMBER_BUFFER_SIZE];
-
-   /* Avoid overflow by doing the negate in a png_alloc_size_t: */
-   u = (png_alloc_size_t)value;
-   if (value < 0)
-      u = ~u + 1;
-
-   str = PNG_FORMAT_NUMBER(buffer, format, u);
-
-   if (value < 0 && str > buffer)
-      *--str = '-';
-
-   png_warning_parameter(p, number, str);
-}
-
-void
-png_formatted_warning(png_structp png_ptr, png_warning_parameters p,
-   png_const_charp message)
-{
-   /* The internal buffer is just 192 bytes - enough for all our messages,
-    * overflow doesn't happen because this code checks!  If someone figures
-    * out how to send us a message longer than 192 bytes, all that will
-    * happen is that the message will be truncated appropriately.
-    */
-   size_t i = 0; /* Index in the msg[] buffer: */
-   char msg[192];
-
-   /* Each iteration through the following loop writes at most one character
-    * to msg[i++] then returns here to validate that there is still space for
-    * the trailing '\0'.  It may (in the case of a parameter) read more than
-    * one character from message[]; it must check for '\0' and continue to the
-    * test if it finds the end of string.
-    */
-   while (i<(sizeof msg)-1 && *message != '\0')
-   {
-      /* '@' at end of string is now just printed (previously it was skipped);
-       * it is an error in the calling code to terminate the string with @.
-       */
-      if (p != NULL && *message == '@' && message[1] != '\0')
-      {
-         int parameter_char = *++message; /* Consume the '@' */
-         static const char valid_parameters[] = "123456789";
-         int parameter = 0;
-
-         /* Search for the parameter digit, the index in the string is the
-          * parameter to use.
-          */
-         while (valid_parameters[parameter] != parameter_char &&
-            valid_parameters[parameter] != '\0')
-            ++parameter;
-
-         /* If the parameter digit is out of range it will just get printed. */
-         if (parameter < PNG_WARNING_PARAMETER_COUNT)
-         {
-            /* Append this parameter */
-            png_const_charp parm = p[parameter];
-            png_const_charp pend = p[parameter] + (sizeof p[parameter]);
-
-            /* No need to copy the trailing '\0' here, but there is no guarantee
-             * that parm[] has been initialized, so there is no guarantee of a
-             * trailing '\0':
-             */
-            while (i<(sizeof msg)-1 && *parm != '\0' && parm < pend)
-               msg[i++] = *parm++;
-
-            /* Consume the parameter digit too: */
-            ++message;
-            continue;
-         }
-
-         /* else not a parameter and there is a character after the @ sign; just
-          * copy that.  This is known not to be '\0' because of the test above.
-          */
-      }
-
-      /* At this point *message can't be '\0', even in the bad parameter case
-       * above where there is a lone '@' at the end of the message string.
-       */
-      msg[i++] = *message++;
-   }
-
-   /* i is always less than (sizeof msg), so: */
-   msg[i] = '\0';
-
-   /* And this is the formatted message, it may be larger than
-    * PNG_MAX_ERROR_TEXT, but that is only used for 'chunk' errors and these are
-    * not (currently) formatted.
-    */
-   png_warning(png_ptr, msg);
-}
-#endif /* PNG_WARNINGS_SUPPORTED */
-
-#ifdef PNG_BENIGN_ERRORS_SUPPORTED
-void PNGAPI
-png_benign_error(png_structp png_ptr, png_const_charp error_message)
-{
-  if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN)
-     png_warning(png_ptr, error_message);
-  else
-     png_error(png_ptr, error_message);
-}
-#endif
-
-/* These utilities are used internally to build an error message that relates
- * to the current chunk.  The chunk name comes from png_ptr->chunk_name,
- * this is used to prefix the message.  The message is limited in length
- * to 63 bytes, the name characters are output as hex digits wrapped in []
- * if the character is invalid.
- */
-#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
-static PNG_CONST char png_digit[16] = {
-   '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-   'A', 'B', 'C', 'D', 'E', 'F'
-};
-
-#define PNG_MAX_ERROR_TEXT 64
-#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_ERROR_TEXT_SUPPORTED)
-static void /* PRIVATE */
-png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp
-    error_message)
-{
-   png_uint_32 chunk_name = png_ptr->chunk_name;
-   int iout = 0, ishift = 24;
-
-   while (ishift >= 0)
-   {
-      int c = (int)(chunk_name >> ishift) & 0xff;
-
-      ishift -= 8;
-      if (isnonalpha(c))
-      {
-         buffer[iout++] = PNG_LITERAL_LEFT_SQUARE_BRACKET;
-         buffer[iout++] = png_digit[(c & 0xf0) >> 4];
-         buffer[iout++] = png_digit[c & 0x0f];
-         buffer[iout++] = PNG_LITERAL_RIGHT_SQUARE_BRACKET;
-      }
-
-      else
-      {
-         buffer[iout++] = (char)c;
-      }
-   }
-
-   if (error_message == NULL)
-      buffer[iout] = '\0';
-
-   else
-   {
-      int iin = 0;
-
-      buffer[iout++] = ':';
-      buffer[iout++] = ' ';
-
-      while (iin < PNG_MAX_ERROR_TEXT-1 && error_message[iin] != '\0')
-         buffer[iout++] = error_message[iin++];
-
-      /* iin < PNG_MAX_ERROR_TEXT, so the following is safe: */
-      buffer[iout] = '\0';
-   }
-}
-#endif /* PNG_WARNINGS_SUPPORTED || PNG_ERROR_TEXT_SUPPORTED */
-
-#if defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED)
-PNG_FUNCTION(void,PNGAPI
-png_chunk_error,(png_structp png_ptr, png_const_charp error_message),
-   PNG_NORETURN)
-{
-   char msg[18+PNG_MAX_ERROR_TEXT];
-   if (png_ptr == NULL)
-      png_error(png_ptr, error_message);
-
-   else
-   {
-      png_format_buffer(png_ptr, msg, error_message);
-      png_error(png_ptr, msg);
-   }
-}
-#endif /* PNG_READ_SUPPORTED && PNG_ERROR_TEXT_SUPPORTED */
-
-#ifdef PNG_WARNINGS_SUPPORTED
-void PNGAPI
-png_chunk_warning(png_structp png_ptr, png_const_charp warning_message)
-{
-   char msg[18+PNG_MAX_ERROR_TEXT];
-   if (png_ptr == NULL)
-      png_warning(png_ptr, warning_message);
-
-   else
-   {
-      png_format_buffer(png_ptr, msg, warning_message);
-      png_warning(png_ptr, msg);
-   }
-}
-#endif /* PNG_WARNINGS_SUPPORTED */
-
-#ifdef PNG_READ_SUPPORTED
-#ifdef PNG_BENIGN_ERRORS_SUPPORTED
-void PNGAPI
-png_chunk_benign_error(png_structp png_ptr, png_const_charp error_message)
-{
-   if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN)
-      png_chunk_warning(png_ptr, error_message);
-
-   else
-      png_chunk_error(png_ptr, error_message);
-}
-#endif
-#endif /* PNG_READ_SUPPORTED */
-
-#ifdef PNG_ERROR_TEXT_SUPPORTED
-#ifdef PNG_FLOATING_POINT_SUPPORTED
-PNG_FUNCTION(void,
-png_fixed_error,(png_structp png_ptr, png_const_charp name),PNG_NORETURN)
-{
-#  define fixed_message "fixed point overflow in "
-#  define fixed_message_ln ((sizeof fixed_message)-1)
-   int  iin;
-   char msg[fixed_message_ln+PNG_MAX_ERROR_TEXT];
-   png_memcpy(msg, fixed_message, fixed_message_ln);
-   iin = 0;
-   if (name != NULL) while (iin < (PNG_MAX_ERROR_TEXT-1) && name[iin] != 0)
-   {
-      msg[fixed_message_ln + iin] = name[iin];
-      ++iin;
-   }
-   msg[fixed_message_ln + iin] = 0;
-   png_error(png_ptr, msg);
-}
-#endif
-#endif
-
-#ifdef PNG_SETJMP_SUPPORTED
-/* This API only exists if ANSI-C style error handling is used,
- * otherwise it is necessary for png_default_error to be overridden.
- */
-jmp_buf* PNGAPI
-png_set_longjmp_fn(png_structp png_ptr, png_longjmp_ptr longjmp_fn,
-    size_t jmp_buf_size)
-{
-   if (png_ptr == NULL || jmp_buf_size != png_sizeof(jmp_buf))
-      return NULL;
-
-   png_ptr->longjmp_fn = longjmp_fn;
-   return &png_ptr->longjmp_buffer;
-}
-#endif
-
-/* This is the default error handling function.  Note that replacements for
- * this function MUST NOT RETURN, or the program will likely crash.  This
- * function is used by default, or if the program supplies NULL for the
- * error function pointer in png_set_error_fn().
- */
-static PNG_FUNCTION(void /* PRIVATE */,
-png_default_error,(png_structp png_ptr, png_const_charp error_message),
-   PNG_NORETURN)
-{
-#ifdef PNG_CONSOLE_IO_SUPPORTED
-#ifdef PNG_ERROR_NUMBERS_SUPPORTED
-   /* Check on NULL only added in 1.5.4 */
-   if (error_message != NULL && *error_message == PNG_LITERAL_SHARP)
-   {
-      /* Strip "#nnnn " from beginning of error message. */
-      int offset;
-      char error_number[16];
-      for (offset = 0; offset<15; offset++)
-      {
-         error_number[offset] = error_message[offset + 1];
-         if (error_message[offset] == ' ')
-            break;
-      }
-
-      if ((offset > 1) && (offset < 15))
-      {
-         error_number[offset - 1] = '\0';
-         fprintf(stderr, "libpng error no. %s: %s",
-             error_number, error_message + offset + 1);
-         fprintf(stderr, PNG_STRING_NEWLINE);
-      }
-
-      else
-      {
-         fprintf(stderr, "libpng error: %s, offset=%d",
-             error_message, offset);
-         fprintf(stderr, PNG_STRING_NEWLINE);
-      }
-   }
-   else
-#endif
-   {
-      fprintf(stderr, "libpng error: %s", error_message ? error_message :
-         "undefined");
-      fprintf(stderr, PNG_STRING_NEWLINE);
-   }
-#else
-   PNG_UNUSED(error_message) /* Make compiler happy */
-#endif
-   png_longjmp(png_ptr, 1);
-}
-
-PNG_FUNCTION(void,PNGAPI
-png_longjmp,(png_structp png_ptr, int val),PNG_NORETURN)
-{
-#ifdef PNG_SETJMP_SUPPORTED
-   if (png_ptr && png_ptr->longjmp_fn)
-   {
-#  ifdef USE_FAR_KEYWORD
-      {
-         jmp_buf tmp_jmpbuf;
-         png_memcpy(tmp_jmpbuf, png_ptr->longjmp_buffer, png_sizeof(jmp_buf));
-         png_ptr->longjmp_fn(tmp_jmpbuf, val);
-      }
-
-#  else
-   png_ptr->longjmp_fn(png_ptr->longjmp_buffer, val);
-#  endif
-   }
-#endif
-   /* Here if not setjmp support or if png_ptr is null. */
-   PNG_ABORT();
-}
-
-#ifdef PNG_WARNINGS_SUPPORTED
-/* This function is called when there is a warning, but the library thinks
- * it can continue anyway.  Replacement functions don't have to do anything
- * here if you don't want them to.  In the default configuration, png_ptr is
- * not used, but it is passed in case it may be useful.
- */
-static void /* PRIVATE */
-png_default_warning(png_structp png_ptr, png_const_charp warning_message)
-{
-#ifdef PNG_CONSOLE_IO_SUPPORTED
-#  ifdef PNG_ERROR_NUMBERS_SUPPORTED
-   if (*warning_message == PNG_LITERAL_SHARP)
-   {
-      int offset;
-      char warning_number[16];
-      for (offset = 0; offset < 15; offset++)
-      {
-         warning_number[offset] = warning_message[offset + 1];
-         if (warning_message[offset] == ' ')
-            break;
-      }
-
-      if ((offset > 1) && (offset < 15))
-      {
-         warning_number[offset + 1] = '\0';
-         fprintf(stderr, "libpng warning no. %s: %s",
-             warning_number, warning_message + offset);
-         fprintf(stderr, PNG_STRING_NEWLINE);
-      }
-
-      else
-      {
-         fprintf(stderr, "libpng warning: %s",
-             warning_message);
-         fprintf(stderr, PNG_STRING_NEWLINE);
-      }
-   }
-   else
-#  endif
-
-   {
-      fprintf(stderr, "libpng warning: %s", warning_message);
-      fprintf(stderr, PNG_STRING_NEWLINE);
-   }
-#else
-   PNG_UNUSED(warning_message) /* Make compiler happy */
-#endif
-   PNG_UNUSED(png_ptr) /* Make compiler happy */
-}
-#endif /* PNG_WARNINGS_SUPPORTED */
-
-/* This function is called when the application wants to use another method
- * of handling errors and warnings.  Note that the error function MUST NOT
- * return to the calling routine or serious problems will occur.  The return
- * method used in the default routine calls longjmp(png_ptr->longjmp_buffer, 1)
- */
-void PNGAPI
-png_set_error_fn(png_structp png_ptr, png_voidp error_ptr,
-    png_error_ptr error_fn, png_error_ptr warning_fn)
-{
-   if (png_ptr == NULL)
-      return;
-
-   png_ptr->error_ptr = error_ptr;
-   png_ptr->error_fn = error_fn;
-#ifdef PNG_WARNINGS_SUPPORTED
-   png_ptr->warning_fn = warning_fn;
-#else
-   PNG_UNUSED(warning_fn)
-#endif
-}
-
-
-/* This function returns a pointer to the error_ptr associated with the user
- * functions.  The application should free any memory associated with this
- * pointer before png_write_destroy and png_read_destroy are called.
- */
-png_voidp PNGAPI
-png_get_error_ptr(png_const_structp png_ptr)
-{
-   if (png_ptr == NULL)
-      return NULL;
-
-   return ((png_voidp)png_ptr->error_ptr);
-}
-
-
-#ifdef PNG_ERROR_NUMBERS_SUPPORTED
-void PNGAPI
-png_set_strip_error_numbers(png_structp png_ptr, png_uint_32 strip_mode)
-{
-   if (png_ptr != NULL)
-   {
-      png_ptr->flags &=
-         ((~(PNG_FLAG_STRIP_ERROR_NUMBERS |
-         PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode);
-   }
-}
-#endif
-#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
+
+/* pngerror.c - stub functions for i/o and memory allocation
+ *
+ * Last changed in libpng 1.6.15 [November 20, 2014]
+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * This file provides a location for all error handling.  Users who
+ * need special error handling are expected to write replacement functions
+ * and use png_set_error_fn() to use those functions.  See the instructions
+ * at each function.
+ */
+
+#include "pngpriv.h"
+
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+
+static PNG_FUNCTION(void, png_default_error,PNGARG((png_const_structrp png_ptr,
+    png_const_charp error_message)),PNG_NORETURN);
+
+#ifdef PNG_WARNINGS_SUPPORTED
+static void /* PRIVATE */
+png_default_warning PNGARG((png_const_structrp png_ptr,
+   png_const_charp warning_message));
+#endif /* WARNINGS */
+
+/* This function is called whenever there is a fatal error.  This function
+ * should not be changed.  If there is a need to handle errors differently,
+ * you should supply a replacement error function and use png_set_error_fn()
+ * to replace the error function at run-time.
+ */
+#ifdef PNG_ERROR_TEXT_SUPPORTED
+PNG_FUNCTION(void,PNGAPI
+png_error,(png_const_structrp png_ptr, png_const_charp error_message),
+   PNG_NORETURN)
+{
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+   char msg[16];
+   if (png_ptr != NULL)
+   {
+      if ((png_ptr->flags &
+         (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) != 0
+      {
+         if (*error_message == PNG_LITERAL_SHARP)
+         {
+            /* Strip "#nnnn " from beginning of error message. */
+            int offset;
+            for (offset = 1; offset<15; offset++)
+               if (error_message[offset] == ' ')
+                  break;
+
+            if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0)
+            {
+               int i;
+               for (i = 0; i < offset - 1; i++)
+                  msg[i] = error_message[i + 1];
+               msg[i - 1] = '\0';
+               error_message = msg;
+            }
+
+            else
+               error_message += offset;
+      }
+
+      else
+      {
+         if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0)
+         {
+            msg[0] = '0';
+            msg[1] = '\0';
+            error_message = msg;
+         }
+       }
+     }
+   }
+#endif
+   if (png_ptr != NULL && png_ptr->error_fn != NULL)
+      (*(png_ptr->error_fn))(png_constcast(png_structrp,png_ptr),
+          error_message);
+
+   /* If the custom handler doesn't exist, or if it returns,
+      use the default handler, which will not return. */
+   png_default_error(png_ptr, error_message);
+}
+#else
+PNG_FUNCTION(void,PNGAPI
+png_err,(png_const_structrp png_ptr),PNG_NORETURN)
+{
+   /* Prior to 1.5.2 the error_fn received a NULL pointer, expressed
+    * erroneously as '\0', instead of the empty string "".  This was
+    * apparently an error, introduced in libpng-1.2.20, and png_default_error
+    * will crash in this case.
+    */
+   if (png_ptr != NULL && png_ptr->error_fn != NULL)
+      (*(png_ptr->error_fn))(png_constcast(png_structrp,png_ptr), "");
+
+   /* If the custom handler doesn't exist, or if it returns,
+      use the default handler, which will not return. */
+   png_default_error(png_ptr, "");
+}
+#endif /* ERROR_TEXT */
+
+/* Utility to safely appends strings to a buffer.  This never errors out so
+ * error checking is not required in the caller.
+ */
+size_t
+png_safecat(png_charp buffer, size_t bufsize, size_t pos,
+   png_const_charp string)
+{
+   if (buffer != NULL && pos < bufsize)
+   {
+      if (string != NULL)
+         while (*string != '\0' && pos < bufsize-1)
+           buffer[pos++] = *string++;
+
+      buffer[pos] = '\0';
+   }
+
+   return pos;
+}
+
+#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_TIME_RFC1123_SUPPORTED)
+/* Utility to dump an unsigned value into a buffer, given a start pointer and
+ * and end pointer (which should point just *beyond* the end of the buffer!)
+ * Returns the pointer to the start of the formatted string.
+ */
+png_charp
+png_format_number(png_const_charp start, png_charp end, int format,
+   png_alloc_size_t number)
+{
+   int count = 0;    /* number of digits output */
+   int mincount = 1; /* minimum number required */
+   int output = 0;   /* digit output (for the fixed point format) */
+
+   *--end = '\0';
+
+   /* This is written so that the loop always runs at least once, even with
+    * number zero.
+    */
+   while (end > start && (number != 0 || count < mincount))
+   {
+
+      static const char digits[] = "0123456789ABCDEF";
+
+      switch (format)
+      {
+         case PNG_NUMBER_FORMAT_fixed:
+            /* Needs five digits (the fraction) */
+            mincount = 5;
+            if (output != 0 || number % 10 != 0)
+            {
+               *--end = digits[number % 10];
+               output = 1;
+            }
+            number /= 10;
+            break;
+
+         case PNG_NUMBER_FORMAT_02u:
+            /* Expects at least 2 digits. */
+            mincount = 2;
+            /* FALL THROUGH */
+
+         case PNG_NUMBER_FORMAT_u:
+            *--end = digits[number % 10];
+            number /= 10;
+            break;
+
+         case PNG_NUMBER_FORMAT_02x:
+            /* This format expects at least two digits */
+            mincount = 2;
+            /* FALL THROUGH */
+
+         case PNG_NUMBER_FORMAT_x:
+            *--end = digits[number & 0xf];
+            number >>= 4;
+            break;
+
+         default: /* an error */
+            number = 0;
+            break;
+      }
+
+      /* Keep track of the number of digits added */
+      ++count;
+
+      /* Float a fixed number here: */
+      if ((format == PNG_NUMBER_FORMAT_fixed) && (count == 5) && (end > start))
+      {
+         /* End of the fraction, but maybe nothing was output?  In that case
+          * drop the decimal point.  If the number is a true zero handle that
+          * here.
+          */
+         if (output != 0)
+            *--end = '.';
+         else if (number == 0) /* and !output */
+            *--end = '0';
+      }
+   }
+
+   return end;
+}
+#endif
+
+#ifdef PNG_WARNINGS_SUPPORTED
+/* This function is called whenever there is a non-fatal error.  This function
+ * should not be changed.  If there is a need to handle warnings differently,
+ * you should supply a replacement warning function and use
+ * png_set_error_fn() to replace the warning function at run-time.
+ */
+void PNGAPI
+png_warning(png_const_structrp png_ptr, png_const_charp warning_message)
+{
+   int offset = 0;
+   if (png_ptr != NULL)
+   {
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+   if ((png_ptr->flags &
+       (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) != 0)
+#endif
+      {
+         if (*warning_message == PNG_LITERAL_SHARP)
+         {
+            for (offset = 1; offset < 15; offset++)
+               if (warning_message[offset] == ' ')
+                  break;
+         }
+      }
+   }
+   if (png_ptr != NULL && png_ptr->warning_fn != NULL)
+      (*(png_ptr->warning_fn))(png_constcast(png_structrp,png_ptr),
+         warning_message + offset);
+   else
+      png_default_warning(png_ptr, warning_message + offset);
+}
+
+/* These functions support 'formatted' warning messages with up to
+ * PNG_WARNING_PARAMETER_COUNT parameters.  In the format string the parameter
+ * is introduced by @<number>, where 'number' starts at 1.  This follows the
+ * standard established by X/Open for internationalizable error messages.
+ */
+void
+png_warning_parameter(png_warning_parameters p, int number,
+   png_const_charp string)
+{
+   if (number > 0 && number <= PNG_WARNING_PARAMETER_COUNT)
+      (void)png_safecat(p[number-1], (sizeof p[number-1]), 0, string);
+}
+
+void
+png_warning_parameter_unsigned(png_warning_parameters p, int number, int format,
+   png_alloc_size_t value)
+{
+   char buffer[PNG_NUMBER_BUFFER_SIZE];
+   png_warning_parameter(p, number, PNG_FORMAT_NUMBER(buffer, format, value));
+}
+
+void
+png_warning_parameter_signed(png_warning_parameters p, int number, int format,
+   png_int_32 value)
+{
+   png_alloc_size_t u;
+   png_charp str;
+   char buffer[PNG_NUMBER_BUFFER_SIZE];
+
+   /* Avoid overflow by doing the negate in a png_alloc_size_t: */
+   u = (png_alloc_size_t)value;
+   if (value < 0)
+      u = ~u + 1;
+
+   str = PNG_FORMAT_NUMBER(buffer, format, u);
+
+   if (value < 0 && str > buffer)
+      *--str = '-';
+
+   png_warning_parameter(p, number, str);
+}
+
+void
+png_formatted_warning(png_const_structrp png_ptr, png_warning_parameters p,
+   png_const_charp message)
+{
+   /* The internal buffer is just 192 bytes - enough for all our messages,
+    * overflow doesn't happen because this code checks!  If someone figures
+    * out how to send us a message longer than 192 bytes, all that will
+    * happen is that the message will be truncated appropriately.
+    */
+   size_t i = 0; /* Index in the msg[] buffer: */
+   char msg[192];
+
+   /* Each iteration through the following loop writes at most one character
+    * to msg[i++] then returns here to validate that there is still space for
+    * the trailing '\0'.  It may (in the case of a parameter) read more than
+    * one character from message[]; it must check for '\0' and continue to the
+    * test if it finds the end of string.
+    */
+   while (i<(sizeof msg)-1 && *message != '\0')
+   {
+      /* '@' at end of string is now just printed (previously it was skipped);
+       * it is an error in the calling code to terminate the string with @.
+       */
+      if (p != NULL && *message == '@' && message[1] != '\0')
+      {
+         int parameter_char = *++message; /* Consume the '@' */
+         static const char valid_parameters[] = "123456789";
+         int parameter = 0;
+
+         /* Search for the parameter digit, the index in the string is the
+          * parameter to use.
+          */
+         while (valid_parameters[parameter] != parameter_char &&
+            valid_parameters[parameter] != '\0')
+            ++parameter;
+
+         /* If the parameter digit is out of range it will just get printed. */
+         if (parameter < PNG_WARNING_PARAMETER_COUNT)
+         {
+            /* Append this parameter */
+            png_const_charp parm = p[parameter];
+            png_const_charp pend = p[parameter] + (sizeof p[parameter]);
+
+            /* No need to copy the trailing '\0' here, but there is no guarantee
+             * that parm[] has been initialized, so there is no guarantee of a
+             * trailing '\0':
+             */
+            while (i<(sizeof msg)-1 && *parm != '\0' && parm < pend)
+               msg[i++] = *parm++;
+
+            /* Consume the parameter digit too: */
+            ++message;
+            continue;
+         }
+
+         /* else not a parameter and there is a character after the @ sign; just
+          * copy that.  This is known not to be '\0' because of the test above.
+          */
+      }
+
+      /* At this point *message can't be '\0', even in the bad parameter case
+       * above where there is a lone '@' at the end of the message string.
+       */
+      msg[i++] = *message++;
+   }
+
+   /* i is always less than (sizeof msg), so: */
+   msg[i] = '\0';
+
+   /* And this is the formatted message. It may be larger than
+    * PNG_MAX_ERROR_TEXT, but that is only used for 'chunk' errors and these
+    * are not (currently) formatted.
+    */
+   png_warning(png_ptr, msg);
+}
+#endif /* WARNINGS */
+
+#ifdef PNG_BENIGN_ERRORS_SUPPORTED
+void PNGAPI
+png_benign_error(png_const_structrp png_ptr, png_const_charp error_message)
+{
+   if ((png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) != 0)
+   {
+#     ifdef PNG_READ_SUPPORTED
+         if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
+            png_ptr->chunk_name != 0)
+            png_chunk_warning(png_ptr, error_message);
+         else
+#     endif
+      png_warning(png_ptr, error_message);
+   }
+
+   else
+   {
+#     ifdef PNG_READ_SUPPORTED
+         if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
+            png_ptr->chunk_name != 0)
+            png_chunk_error(png_ptr, error_message);
+         else
+#     endif
+      png_error(png_ptr, error_message);
+   }
+
+#  ifndef PNG_ERROR_TEXT_SUPPORTED
+      PNG_UNUSED(error_message)
+#  endif
+}
+
+void /* PRIVATE */
+png_app_warning(png_const_structrp png_ptr, png_const_charp error_message)
+{
+  if ((png_ptr->flags & PNG_FLAG_APP_WARNINGS_WARN) != 0)
+     png_warning(png_ptr, error_message);
+  else
+     png_error(png_ptr, error_message);
+
+#  ifndef PNG_ERROR_TEXT_SUPPORTED
+      PNG_UNUSED(error_message)
+#  endif
+}
+
+void /* PRIVATE */
+png_app_error(png_const_structrp png_ptr, png_const_charp error_message)
+{
+  if ((png_ptr->flags & PNG_FLAG_APP_ERRORS_WARN) != 0)
+     png_warning(png_ptr, error_message);
+  else
+     png_error(png_ptr, error_message);
+
+#  ifndef PNG_ERROR_TEXT_SUPPORTED
+      PNG_UNUSED(error_message)
+#  endif
+}
+#endif /* BENIGN_ERRORS */
+
+#define PNG_MAX_ERROR_TEXT 196 /* Currently limited by profile_error in png.c */
+#if defined(PNG_WARNINGS_SUPPORTED) || \
+   (defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED))
+/* These utilities are used internally to build an error message that relates
+ * to the current chunk.  The chunk name comes from png_ptr->chunk_name,
+ * which is used to prefix the message.  The message is limited in length
+ * to 63 bytes. The name characters are output as hex digits wrapped in []
+ * if the character is invalid.
+ */
+#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
+static PNG_CONST char png_digit[16] = {
+   '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+   'A', 'B', 'C', 'D', 'E', 'F'
+};
+
+static void /* PRIVATE */
+png_format_buffer(png_const_structrp png_ptr, png_charp buffer, png_const_charp
+    error_message)
+{
+   png_uint_32 chunk_name = png_ptr->chunk_name;
+   int iout = 0, ishift = 24;
+
+   while (ishift >= 0)
+   {
+      int c = (int)(chunk_name >> ishift) & 0xff;
+
+      ishift -= 8;
+      if (isnonalpha(c) != 0)
+      {
+         buffer[iout++] = PNG_LITERAL_LEFT_SQUARE_BRACKET;
+         buffer[iout++] = png_digit[(c & 0xf0) >> 4];
+         buffer[iout++] = png_digit[c & 0x0f];
+         buffer[iout++] = PNG_LITERAL_RIGHT_SQUARE_BRACKET;
+      }
+
+      else
+      {
+         buffer[iout++] = (char)c;
+      }
+   }
+
+   if (error_message == NULL)
+      buffer[iout] = '\0';
+
+   else
+   {
+      int iin = 0;
+
+      buffer[iout++] = ':';
+      buffer[iout++] = ' ';
+
+      while (iin < PNG_MAX_ERROR_TEXT-1 && error_message[iin] != '\0')
+         buffer[iout++] = error_message[iin++];
+
+      /* iin < PNG_MAX_ERROR_TEXT, so the following is safe: */
+      buffer[iout] = '\0';
+   }
+}
+#endif /* WARNINGS || ERROR_TEXT */
+
+#if defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED)
+PNG_FUNCTION(void,PNGAPI
+png_chunk_error,(png_const_structrp png_ptr, png_const_charp error_message),
+   PNG_NORETURN)
+{
+   char msg[18+PNG_MAX_ERROR_TEXT];
+   if (png_ptr == NULL)
+      png_error(png_ptr, error_message);
+
+   else
+   {
+      png_format_buffer(png_ptr, msg, error_message);
+      png_error(png_ptr, msg);
+   }
+}
+#endif /* READ && ERROR_TEXT */
+
+#ifdef PNG_WARNINGS_SUPPORTED
+void PNGAPI
+png_chunk_warning(png_const_structrp png_ptr, png_const_charp warning_message)
+{
+   char msg[18+PNG_MAX_ERROR_TEXT];
+   if (png_ptr == NULL)
+      png_warning(png_ptr, warning_message);
+
+   else
+   {
+      png_format_buffer(png_ptr, msg, warning_message);
+      png_warning(png_ptr, msg);
+   }
+}
+#endif /* WARNINGS */
+
+#ifdef PNG_READ_SUPPORTED
+#ifdef PNG_BENIGN_ERRORS_SUPPORTED
+void PNGAPI
+png_chunk_benign_error(png_const_structrp png_ptr, png_const_charp
+    error_message)
+{
+   if ((png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) != 0)
+      png_chunk_warning(png_ptr, error_message);
+
+   else
+      png_chunk_error(png_ptr, error_message);
+
+#  ifndef PNG_ERROR_TEXT_SUPPORTED
+      PNG_UNUSED(error_message)
+#  endif
+}
+#endif
+#endif /* READ */
+
+void /* PRIVATE */
+png_chunk_report(png_const_structrp png_ptr, png_const_charp message, int error)
+{
+#  ifndef PNG_WARNINGS_SUPPORTED
+      PNG_UNUSED(message)
+#  endif
+
+   /* This is always supported, but for just read or just write it
+    * unconditionally does the right thing.
+    */
+#  if defined(PNG_READ_SUPPORTED) && defined(PNG_WRITE_SUPPORTED)
+      if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
+#  endif
+
+#  ifdef PNG_READ_SUPPORTED
+      {
+         if (error < PNG_CHUNK_ERROR)
+            png_chunk_warning(png_ptr, message);
+
+         else
+            png_chunk_benign_error(png_ptr, message);
+      }
+#  endif
+
+#  if defined(PNG_READ_SUPPORTED) && defined(PNG_WRITE_SUPPORTED)
+      else if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0)
+#  endif
+
+#  ifdef PNG_WRITE_SUPPORTED
+      {
+         if (error < PNG_CHUNK_WRITE_ERROR)
+            png_app_warning(png_ptr, message);
+
+         else
+            png_app_error(png_ptr, message);
+      }
+#  endif
+}
+
+#ifdef PNG_ERROR_TEXT_SUPPORTED
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+PNG_FUNCTION(void,
+png_fixed_error,(png_const_structrp png_ptr, png_const_charp name),PNG_NORETURN)
+{
+#  define fixed_message "fixed point overflow in "
+#  define fixed_message_ln ((sizeof fixed_message)-1)
+   int  iin;
+   char msg[fixed_message_ln+PNG_MAX_ERROR_TEXT];
+   memcpy(msg, fixed_message, fixed_message_ln);
+   iin = 0;
+   if (name != NULL)
+      while (iin < (PNG_MAX_ERROR_TEXT-1) && name[iin] != 0)
+      {
+         msg[fixed_message_ln + iin] = name[iin];
+         ++iin;
+      }
+   msg[fixed_message_ln + iin] = 0;
+   png_error(png_ptr, msg);
+}
+#endif
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+/* This API only exists if ANSI-C style error handling is used,
+ * otherwise it is necessary for png_default_error to be overridden.
+ */
+jmp_buf* PNGAPI
+png_set_longjmp_fn(png_structrp png_ptr, png_longjmp_ptr longjmp_fn,
+    size_t jmp_buf_size)
+{
+   /* From libpng 1.6.0 the app gets one chance to set a 'jmpbuf_size' value
+    * and it must not change after that.  Libpng doesn't care how big the
+    * buffer is, just that it doesn't change.
+    *
+    * If the buffer size is no *larger* than the size of jmp_buf when libpng is
+    * compiled a built in jmp_buf is returned; this preserves the pre-1.6.0
+    * semantics that this call will not fail.  If the size is larger, however,
+    * the buffer is allocated and this may fail, causing the function to return
+    * NULL.
+    */
+   if (png_ptr == NULL)
+      return NULL;
+
+   if (png_ptr->jmp_buf_ptr == NULL)
+   {
+      png_ptr->jmp_buf_size = 0; /* not allocated */
+
+      if (jmp_buf_size <= (sizeof png_ptr->jmp_buf_local))
+         png_ptr->jmp_buf_ptr = &png_ptr->jmp_buf_local;
+
+      else
+      {
+         png_ptr->jmp_buf_ptr = png_voidcast(jmp_buf *,
+            png_malloc_warn(png_ptr, jmp_buf_size));
+
+         if (png_ptr->jmp_buf_ptr == NULL)
+            return NULL; /* new NULL return on OOM */
+
+         png_ptr->jmp_buf_size = jmp_buf_size;
+      }
+   }
+
+   else /* Already allocated: check the size */
+   {
+      size_t size = png_ptr->jmp_buf_size;
+
+      if (size == 0)
+      {
+         size = (sizeof png_ptr->jmp_buf_local);
+         if (png_ptr->jmp_buf_ptr != &png_ptr->jmp_buf_local)
+         {
+            /* This is an internal error in libpng: somehow we have been left
+             * with a stack allocated jmp_buf when the application regained
+             * control.  It's always possible to fix this up, but for the moment
+             * this is a png_error because that makes it easy to detect.
+             */
+            png_error(png_ptr, "Libpng jmp_buf still allocated");
+            /* png_ptr->jmp_buf_ptr = &png_ptr->jmp_buf_local; */
+         }
+      }
+
+      if (size != jmp_buf_size)
+      {
+         png_warning(png_ptr, "Application jmp_buf size changed");
+         return NULL; /* caller will probably crash: no choice here */
+      }
+   }
+
+   /* Finally fill in the function, now we have a satisfactory buffer. It is
+    * valid to change the function on every call.
+    */
+   png_ptr->longjmp_fn = longjmp_fn;
+   return png_ptr->jmp_buf_ptr;
+}
+
+void /* PRIVATE */
+png_free_jmpbuf(png_structrp png_ptr)
+{
+   if (png_ptr != NULL)
+   {
+      jmp_buf *jb = png_ptr->jmp_buf_ptr;
+
+      /* A size of 0 is used to indicate a local, stack, allocation of the
+       * pointer; used here and in png.c
+       */
+      if (jb != NULL && png_ptr->jmp_buf_size > 0)
+      {
+
+         /* This stuff is so that a failure to free the error control structure
+          * does not leave libpng in a state with no valid error handling: the
+          * free always succeeds, if there is an error it gets ignored.
+          */
+         if (jb != &png_ptr->jmp_buf_local)
+         {
+            /* Make an internal, libpng, jmp_buf to return here */
+            jmp_buf free_jmp_buf;
+
+            if (!setjmp(free_jmp_buf))
+            {
+               png_ptr->jmp_buf_ptr = &free_jmp_buf; /* come back here */
+               png_ptr->jmp_buf_size = 0; /* stack allocation */
+               png_ptr->longjmp_fn = longjmp;
+               png_free(png_ptr, jb); /* Return to setjmp on error */
+            }
+         }
+      }
+
+      /* *Always* cancel everything out: */
+      png_ptr->jmp_buf_size = 0;
+      png_ptr->jmp_buf_ptr = NULL;
+      png_ptr->longjmp_fn = 0;
+   }
+}
+#endif
+
+/* This is the default error handling function.  Note that replacements for
+ * this function MUST NOT RETURN, or the program will likely crash.  This
+ * function is used by default, or if the program supplies NULL for the
+ * error function pointer in png_set_error_fn().
+ */
+static PNG_FUNCTION(void /* PRIVATE */,
+png_default_error,(png_const_structrp png_ptr, png_const_charp error_message),
+   PNG_NORETURN)
+{
+#ifdef PNG_CONSOLE_IO_SUPPORTED
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+   /* Check on NULL only added in 1.5.4 */
+   if (error_message != NULL && *error_message == PNG_LITERAL_SHARP)
+   {
+      /* Strip "#nnnn " from beginning of error message. */
+      int offset;
+      char error_number[16];
+      for (offset = 0; offset<15; offset++)
+      {
+         error_number[offset] = error_message[offset + 1];
+         if (error_message[offset] == ' ')
+            break;
+      }
+
+      if ((offset > 1) && (offset < 15))
+      {
+         error_number[offset - 1] = '\0';
+         fprintf(stderr, "libpng error no. %s: %s",
+             error_number, error_message + offset + 1);
+         fprintf(stderr, PNG_STRING_NEWLINE);
+      }
+
+      else
+      {
+         fprintf(stderr, "libpng error: %s, offset=%d",
+             error_message, offset);
+         fprintf(stderr, PNG_STRING_NEWLINE);
+      }
+   }
+   else
+#endif
+   {
+      fprintf(stderr, "libpng error: %s", error_message ? error_message :
+         "undefined");
+      fprintf(stderr, PNG_STRING_NEWLINE);
+   }
+#else
+   PNG_UNUSED(error_message) /* Make compiler happy */
+#endif
+   png_longjmp(png_ptr, 1);
+}
+
+PNG_FUNCTION(void,PNGAPI
+png_longjmp,(png_const_structrp png_ptr, int val),PNG_NORETURN)
+{
+#ifdef PNG_SETJMP_SUPPORTED
+   if (png_ptr != NULL && png_ptr->longjmp_fn != NULL &&
+       png_ptr->jmp_buf_ptr != NULL)
+      png_ptr->longjmp_fn(*png_ptr->jmp_buf_ptr, val);
+#else
+   PNG_UNUSED(png_ptr)
+   PNG_UNUSED(val)
+#endif
+
+   /* If control reaches this point, png_longjmp() must not return. The only
+    * choice is to terminate the whole process (or maybe the thread); to do
+    * this the ANSI-C abort() function is used unless a different method is 
+    * implemented by overriding the default configuration setting for
+    * PNG_ABORT().
+    */
+   PNG_ABORT();
+}
+
+#ifdef PNG_WARNINGS_SUPPORTED
+/* This function is called when there is a warning, but the library thinks
+ * it can continue anyway.  Replacement functions don't have to do anything
+ * here if you don't want them to.  In the default configuration, png_ptr is
+ * not used, but it is passed in case it may be useful.
+ */
+static void /* PRIVATE */
+png_default_warning(png_const_structrp png_ptr, png_const_charp warning_message)
+{
+#ifdef PNG_CONSOLE_IO_SUPPORTED
+#  ifdef PNG_ERROR_NUMBERS_SUPPORTED
+   if (*warning_message == PNG_LITERAL_SHARP)
+   {
+      int offset;
+      char warning_number[16];
+      for (offset = 0; offset < 15; offset++)
+      {
+         warning_number[offset] = warning_message[offset + 1];
+         if (warning_message[offset] == ' ')
+            break;
+      }
+
+      if ((offset > 1) && (offset < 15))
+      {
+         warning_number[offset + 1] = '\0';
+         fprintf(stderr, "libpng warning no. %s: %s",
+             warning_number, warning_message + offset);
+         fprintf(stderr, PNG_STRING_NEWLINE);
+      }
+
+      else
+      {
+         fprintf(stderr, "libpng warning: %s",
+             warning_message);
+         fprintf(stderr, PNG_STRING_NEWLINE);
+      }
+   }
+   else
+#  endif
+
+   {
+      fprintf(stderr, "libpng warning: %s", warning_message);
+      fprintf(stderr, PNG_STRING_NEWLINE);
+   }
+#else
+   PNG_UNUSED(warning_message) /* Make compiler happy */
+#endif
+   PNG_UNUSED(png_ptr) /* Make compiler happy */
+}
+#endif /* WARNINGS */
+
+/* This function is called when the application wants to use another method
+ * of handling errors and warnings.  Note that the error function MUST NOT
+ * return to the calling routine or serious problems will occur.  The return
+ * method used in the default routine calls longjmp(png_ptr->jmp_buf_ptr, 1)
+ */
+void PNGAPI
+png_set_error_fn(png_structrp png_ptr, png_voidp error_ptr,
+    png_error_ptr error_fn, png_error_ptr warning_fn)
+{
+   if (png_ptr == NULL)
+      return;
+
+   png_ptr->error_ptr = error_ptr;
+   png_ptr->error_fn = error_fn;
+#ifdef PNG_WARNINGS_SUPPORTED
+   png_ptr->warning_fn = warning_fn;
+#else
+   PNG_UNUSED(warning_fn)
+#endif
+}
+
+
+/* This function returns a pointer to the error_ptr associated with the user
+ * functions.  The application should free any memory associated with this
+ * pointer before png_write_destroy and png_read_destroy are called.
+ */
+png_voidp PNGAPI
+png_get_error_ptr(png_const_structrp png_ptr)
+{
+   if (png_ptr == NULL)
+      return NULL;
+
+   return ((png_voidp)png_ptr->error_ptr);
+}
+
+
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+void PNGAPI
+png_set_strip_error_numbers(png_structrp png_ptr, png_uint_32 strip_mode)
+{
+   if (png_ptr != NULL)
+   {
+      png_ptr->flags &=
+         ((~(PNG_FLAG_STRIP_ERROR_NUMBERS |
+         PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode);
+   }
+}
+#endif
+
+#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\
+   defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
+   /* Currently the above both depend on SETJMP_SUPPORTED, however it would be
+    * possible to implement without setjmp support just so long as there is some
+    * way to handle the error return here:
+    */
+PNG_FUNCTION(void /* PRIVATE */, (PNGCBAPI
+png_safe_error),(png_structp png_nonconst_ptr, png_const_charp error_message),
+   PNG_NORETURN)
+{
+   const png_const_structrp png_ptr = png_nonconst_ptr;
+   png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr);
+
+   /* An error is always logged here, overwriting anything (typically a warning)
+    * that is already there:
+    */
+   if (image != NULL)
+   {
+      png_safecat(image->message, (sizeof image->message), 0, error_message);
+      image->warning_or_error |= PNG_IMAGE_ERROR;
+
+      /* Retrieve the jmp_buf from within the png_control, making this work for
+       * C++ compilation too is pretty tricky: C++ wants a pointer to the first
+       * element of a jmp_buf, but C doesn't tell us the type of that.
+       */
+      if (image->opaque != NULL && image->opaque->error_buf != NULL)
+         longjmp(png_control_jmp_buf(image->opaque), 1);
+
+      /* Missing longjmp buffer, the following is to help debugging: */
+      {
+         size_t pos = png_safecat(image->message, (sizeof image->message), 0,
+            "bad longjmp: ");
+         png_safecat(image->message, (sizeof image->message), pos,
+             error_message);
+      }
+   }
+
+   /* Here on an internal programming error. */
+   abort();
+}
+
+#ifdef PNG_WARNINGS_SUPPORTED
+void /* PRIVATE */ PNGCBAPI
+png_safe_warning(png_structp png_nonconst_ptr, png_const_charp warning_message)
+{
+   const png_const_structrp png_ptr = png_nonconst_ptr;
+   png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr);
+
+   /* A warning is only logged if there is no prior warning or error. */
+   if (image->warning_or_error == 0)
+   {
+      png_safecat(image->message, (sizeof image->message), 0, warning_message);
+      image->warning_or_error |= PNG_IMAGE_WARNING;
+   }
+}
+#endif
+
+int /* PRIVATE */
+png_safe_execute(png_imagep image_in, int (*function)(png_voidp), png_voidp arg)
+{
+   volatile png_imagep image = image_in;
+   volatile int result;
+   volatile png_voidp saved_error_buf;
+   jmp_buf safe_jmpbuf;
+
+   /* Safely execute function(arg) with png_error returning to this function. */
+   saved_error_buf = image->opaque->error_buf;
+   result = setjmp(safe_jmpbuf) == 0;
+
+   if (result != 0)
+   {
+
+      image->opaque->error_buf = safe_jmpbuf;
+      result = function(arg);
+   }
+
+   image->opaque->error_buf = saved_error_buf;
+
+   /* And do the cleanup prior to any failure return. */
+   if (result == 0)
+      png_image_free(image);
+
+   return result;
+}
+#endif /* SIMPLIFIED READ || SIMPLIFIED_WRITE */
+#endif /* READ || WRITE */
diff --git a/Source/LibPNG/pngget.c b/Source/LibPNG/pngget.c
index 1889e99..fce126c 100644
--- a/Source/LibPNG/pngget.c
+++ b/Source/LibPNG/pngget.c
@@ -1,1124 +1,1213 @@
-
-/* pngget.c - retrieval of values from info struct
- *
- * Last changed in libpng 1.5.7 [December 15, 2011]
- * Copyright (c) 1998-2011 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- *
- */
-
-#include "pngpriv.h"
-
-#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
-
-png_uint_32 PNGAPI
-png_get_valid(png_const_structp png_ptr, png_const_infop info_ptr,
-    png_uint_32 flag)
-{
-   if (png_ptr != NULL && info_ptr != NULL)
-      return(info_ptr->valid & flag);
-
-   return(0);
-}
-
-png_size_t PNGAPI
-png_get_rowbytes(png_const_structp png_ptr, png_const_infop info_ptr)
-{
-   if (png_ptr != NULL && info_ptr != NULL)
-      return(info_ptr->rowbytes);
-
-   return(0);
-}
-
-#ifdef PNG_INFO_IMAGE_SUPPORTED
-png_bytepp PNGAPI
-png_get_rows(png_const_structp png_ptr, png_const_infop info_ptr)
-{
-   if (png_ptr != NULL && info_ptr != NULL)
-      return(info_ptr->row_pointers);
-
-   return(0);
-}
-#endif
-
-#ifdef PNG_EASY_ACCESS_SUPPORTED
-/* Easy access to info, added in libpng-0.99 */
-png_uint_32 PNGAPI
-png_get_image_width(png_const_structp png_ptr, png_const_infop info_ptr)
-{
-   if (png_ptr != NULL && info_ptr != NULL)
-      return info_ptr->width;
-
-   return (0);
-}
-
-png_uint_32 PNGAPI
-png_get_image_height(png_const_structp png_ptr, png_const_infop info_ptr)
-{
-   if (png_ptr != NULL && info_ptr != NULL)
-      return info_ptr->height;
-
-   return (0);
-}
-
-png_byte PNGAPI
-png_get_bit_depth(png_const_structp png_ptr, png_const_infop info_ptr)
-{
-   if (png_ptr != NULL && info_ptr != NULL)
-      return info_ptr->bit_depth;
-
-   return (0);
-}
-
-png_byte PNGAPI
-png_get_color_type(png_const_structp png_ptr, png_const_infop info_ptr)
-{
-   if (png_ptr != NULL && info_ptr != NULL)
-      return info_ptr->color_type;
-
-   return (0);
-}
-
-png_byte PNGAPI
-png_get_filter_type(png_const_structp png_ptr, png_const_infop info_ptr)
-{
-   if (png_ptr != NULL && info_ptr != NULL)
-      return info_ptr->filter_type;
-
-   return (0);
-}
-
-png_byte PNGAPI
-png_get_interlace_type(png_const_structp png_ptr, png_const_infop info_ptr)
-{
-   if (png_ptr != NULL && info_ptr != NULL)
-      return info_ptr->interlace_type;
-
-   return (0);
-}
-
-png_byte PNGAPI
-png_get_compression_type(png_const_structp png_ptr, png_const_infop info_ptr)
-{
-   if (png_ptr != NULL && info_ptr != NULL)
-      return info_ptr->compression_type;
-
-   return (0);
-}
-
-png_uint_32 PNGAPI
-png_get_x_pixels_per_meter(png_const_structp png_ptr, png_const_infop info_ptr)
-{
-#ifdef PNG_pHYs_SUPPORTED
-   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
-      {
-         png_debug1(1, "in %s retrieval function",
-             "png_get_x_pixels_per_meter");
-
-         if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER)
-            return (info_ptr->x_pixels_per_unit);
-      }
-#endif
-
-   return (0);
-}
-
-png_uint_32 PNGAPI
-png_get_y_pixels_per_meter(png_const_structp png_ptr, png_const_infop info_ptr)
-{
-#ifdef PNG_pHYs_SUPPORTED
-   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
-   {
-      png_debug1(1, "in %s retrieval function",
-          "png_get_y_pixels_per_meter");
-
-      if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER)
-         return (info_ptr->y_pixels_per_unit);
-   }
-#endif
-
-   return (0);
-}
-
-png_uint_32 PNGAPI
-png_get_pixels_per_meter(png_const_structp png_ptr, png_const_infop info_ptr)
-{
-#ifdef PNG_pHYs_SUPPORTED
-   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
-   {
-      png_debug1(1, "in %s retrieval function", "png_get_pixels_per_meter");
-
-      if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER &&
-          info_ptr->x_pixels_per_unit == info_ptr->y_pixels_per_unit)
-         return (info_ptr->x_pixels_per_unit);
-   }
-#endif
-
-   return (0);
-}
-
-#ifdef PNG_FLOATING_POINT_SUPPORTED
-float PNGAPI
-png_get_pixel_aspect_ratio(png_const_structp png_ptr, png_const_infop info_ptr)
-{
-#ifdef PNG_READ_pHYs_SUPPORTED
-   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
-   {
-      png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio");
-
-      if (info_ptr->x_pixels_per_unit != 0)
-         return ((float)((float)info_ptr->y_pixels_per_unit
-             /(float)info_ptr->x_pixels_per_unit));
-   }
-#endif
-
-   return ((float)0.0);
-}
-#endif
-
-#ifdef PNG_FIXED_POINT_SUPPORTED
-png_fixed_point PNGAPI
-png_get_pixel_aspect_ratio_fixed(png_const_structp png_ptr,
-    png_const_infop info_ptr)
-{
-#ifdef PNG_READ_pHYs_SUPPORTED
-   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)
-       && info_ptr->x_pixels_per_unit > 0 && info_ptr->y_pixels_per_unit > 0
-       && info_ptr->x_pixels_per_unit <= PNG_UINT_31_MAX
-       && info_ptr->y_pixels_per_unit <= PNG_UINT_31_MAX)
-   {
-      png_fixed_point res;
-
-      png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio_fixed");
-
-      /* The following casts work because a PNG 4 byte integer only has a valid
-       * range of 0..2^31-1; otherwise the cast might overflow.
-       */
-      if (png_muldiv(&res, (png_int_32)info_ptr->y_pixels_per_unit, PNG_FP_1,
-          (png_int_32)info_ptr->x_pixels_per_unit))
-         return res;
-   }
-#endif
-
-   return 0;
-}
-#endif
-
-png_int_32 PNGAPI
-png_get_x_offset_microns(png_const_structp png_ptr, png_const_infop info_ptr)
-{
-#ifdef PNG_oFFs_SUPPORTED
-   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
-   {
-      png_debug1(1, "in %s retrieval function", "png_get_x_offset_microns");
-
-      if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER)
-         return (info_ptr->x_offset);
-   }
-#endif
-
-   return (0);
-}
-
-png_int_32 PNGAPI
-png_get_y_offset_microns(png_const_structp png_ptr, png_const_infop info_ptr)
-{
-#ifdef PNG_oFFs_SUPPORTED
-   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
-   {
-      png_debug1(1, "in %s retrieval function", "png_get_y_offset_microns");
-
-      if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER)
-         return (info_ptr->y_offset);
-   }
-#endif
-
-   return (0);
-}
-
-png_int_32 PNGAPI
-png_get_x_offset_pixels(png_const_structp png_ptr, png_const_infop info_ptr)
-{
-#ifdef PNG_oFFs_SUPPORTED
-   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
-   {
-      png_debug1(1, "in %s retrieval function", "png_get_x_offset_pixels");
-
-      if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL)
-         return (info_ptr->x_offset);
-   }
-#endif
-
-   return (0);
-}
-
-png_int_32 PNGAPI
-png_get_y_offset_pixels(png_const_structp png_ptr, png_const_infop info_ptr)
-{
-#ifdef PNG_oFFs_SUPPORTED
-   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
-   {
-      png_debug1(1, "in %s retrieval function", "png_get_y_offset_pixels");
-
-      if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL)
-         return (info_ptr->y_offset);
-   }
-#endif
-
-   return (0);
-}
-
-#ifdef PNG_INCH_CONVERSIONS_SUPPORTED
-static png_uint_32
-ppi_from_ppm(png_uint_32 ppm)
-{
-#if 0
-   /* The conversion is *(2.54/100), in binary (32 digits):
-    * .00000110100000001001110101001001
-    */
-   png_uint_32 t1001, t1101;
-   ppm >>= 1;                  /* .1 */
-   t1001 = ppm + (ppm >> 3);   /* .1001 */
-   t1101 = t1001 + (ppm >> 1); /* .1101 */
-   ppm >>= 20;                 /* .000000000000000000001 */
-   t1101 += t1101 >> 15;       /* .1101000000000001101 */
-   t1001 >>= 11;               /* .000000000001001 */
-   t1001 += t1001 >> 12;       /* .000000000001001000000001001 */
-   ppm += t1001;               /* .000000000001001000001001001 */
-   ppm += t1101;               /* .110100000001001110101001001 */
-   return (ppm + 16) >> 5;/* .00000110100000001001110101001001 */
-#else
-   /* The argument is a PNG unsigned integer, so it is not permitted
-    * to be bigger than 2^31.
-    */
-   png_fixed_point result;
-   if (ppm <= PNG_UINT_31_MAX && png_muldiv(&result, (png_int_32)ppm, 127,
-       5000))
-      return result;
-
-   /* Overflow. */
-   return 0;
-#endif
-}
-
-png_uint_32 PNGAPI
-png_get_pixels_per_inch(png_const_structp png_ptr, png_const_infop info_ptr)
-{
-   return ppi_from_ppm(png_get_pixels_per_meter(png_ptr, info_ptr));
-}
-
-png_uint_32 PNGAPI
-png_get_x_pixels_per_inch(png_const_structp png_ptr, png_const_infop info_ptr)
-{
-   return ppi_from_ppm(png_get_x_pixels_per_meter(png_ptr, info_ptr));
-}
-
-png_uint_32 PNGAPI
-png_get_y_pixels_per_inch(png_const_structp png_ptr, png_const_infop info_ptr)
-{
-   return ppi_from_ppm(png_get_y_pixels_per_meter(png_ptr, info_ptr));
-}
-
-#ifdef PNG_FIXED_POINT_SUPPORTED
-static png_fixed_point
-png_fixed_inches_from_microns(png_structp png_ptr, png_int_32 microns)
-{
-   /* Convert from metres * 1,000,000 to inches * 100,000, meters to
-    * inches is simply *(100/2.54), so we want *(10/2.54) == 500/127.
-    * Notice that this can overflow - a warning is output and 0 is
-    * returned.
-    */
-   return png_muldiv_warn(png_ptr, microns, 500, 127);
-}
-
-png_fixed_point PNGAPI
-png_get_x_offset_inches_fixed(png_structp png_ptr,
-    png_const_infop info_ptr)
-{
-   return png_fixed_inches_from_microns(png_ptr,
-       png_get_x_offset_microns(png_ptr, info_ptr));
-}
-#endif
-
-#ifdef PNG_FIXED_POINT_SUPPORTED
-png_fixed_point PNGAPI
-png_get_y_offset_inches_fixed(png_structp png_ptr,
-    png_const_infop info_ptr)
-{
-   return png_fixed_inches_from_microns(png_ptr,
-       png_get_y_offset_microns(png_ptr, info_ptr));
-}
-#endif
-
-#ifdef PNG_FLOATING_POINT_SUPPORTED
-float PNGAPI
-png_get_x_offset_inches(png_const_structp png_ptr, png_const_infop info_ptr)
-{
-   /* To avoid the overflow do the conversion directly in floating
-    * point.
-    */
-   return (float)(png_get_x_offset_microns(png_ptr, info_ptr) * .00003937);
-}
-#endif
-
-#ifdef PNG_FLOATING_POINT_SUPPORTED
-float PNGAPI
-png_get_y_offset_inches(png_const_structp png_ptr, png_const_infop info_ptr)
-{
-   /* To avoid the overflow do the conversion directly in floating
-    * point.
-    */
-   return (float)(png_get_y_offset_microns(png_ptr, info_ptr) * .00003937);
-}
-#endif
-
-#ifdef PNG_pHYs_SUPPORTED
-png_uint_32 PNGAPI
-png_get_pHYs_dpi(png_const_structp png_ptr, png_const_infop info_ptr,
-    png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
-{
-   png_uint_32 retval = 0;
-
-   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
-   {
-      png_debug1(1, "in %s retrieval function", "pHYs");
-
-      if (res_x != NULL)
-      {
-         *res_x = info_ptr->x_pixels_per_unit;
-         retval |= PNG_INFO_pHYs;
-      }
-
-      if (res_y != NULL)
-      {
-         *res_y = info_ptr->y_pixels_per_unit;
-         retval |= PNG_INFO_pHYs;
-      }
-
-      if (unit_type != NULL)
-      {
-         *unit_type = (int)info_ptr->phys_unit_type;
-         retval |= PNG_INFO_pHYs;
-
-         if (*unit_type == 1)
-         {
-            if (res_x != NULL) *res_x = (png_uint_32)(*res_x * .0254 + .50);
-            if (res_y != NULL) *res_y = (png_uint_32)(*res_y * .0254 + .50);
-         }
-      }
-   }
-
-   return (retval);
-}
-#endif /* PNG_pHYs_SUPPORTED */
-#endif  /* PNG_INCH_CONVERSIONS_SUPPORTED */
-
-/* png_get_channels really belongs in here, too, but it's been around longer */
-
-#endif  /* PNG_EASY_ACCESS_SUPPORTED */
-
-png_byte PNGAPI
-png_get_channels(png_const_structp png_ptr, png_const_infop info_ptr)
-{
-   if (png_ptr != NULL && info_ptr != NULL)
-      return(info_ptr->channels);
-
-   return (0);
-}
-
-png_const_bytep PNGAPI
-png_get_signature(png_const_structp png_ptr, png_infop info_ptr)
-{
-   if (png_ptr != NULL && info_ptr != NULL)
-      return(info_ptr->signature);
-
-   return (NULL);
-}
-
-#ifdef PNG_bKGD_SUPPORTED
-png_uint_32 PNGAPI
-png_get_bKGD(png_const_structp png_ptr, png_infop info_ptr,
-   png_color_16p *background)
-{
-   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD)
-       && background != NULL)
-   {
-      png_debug1(1, "in %s retrieval function", "bKGD");
-
-      *background = &(info_ptr->background);
-      return (PNG_INFO_bKGD);
-   }
-
-   return (0);
-}
-#endif
-
-#ifdef PNG_cHRM_SUPPORTED
-/* The XYZ APIs were added in 1.5.5 to take advantage of the code added at the
- * same time to correct the rgb grayscale coefficient defaults obtained from the
- * cHRM chunk in 1.5.4
- */
-png_uint_32 PNGFAPI
-png_get_cHRM_XYZ_fixed(png_structp png_ptr, png_const_infop info_ptr,
-    png_fixed_point *int_red_X, png_fixed_point *int_red_Y,
-    png_fixed_point *int_red_Z, png_fixed_point *int_green_X,
-    png_fixed_point *int_green_Y, png_fixed_point *int_green_Z,
-    png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y,
-    png_fixed_point *int_blue_Z)
-{
-   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
-   {
-      png_xy xy;
-      png_XYZ XYZ;
-
-      png_debug1(1, "in %s retrieval function", "cHRM_XYZ");
-
-      xy.whitex = info_ptr->x_white;
-      xy.whitey = info_ptr->y_white;
-      xy.redx = info_ptr->x_red;
-      xy.redy = info_ptr->y_red;
-      xy.greenx = info_ptr->x_green;
-      xy.greeny = info_ptr->y_green;
-      xy.bluex = info_ptr->x_blue;
-      xy.bluey = info_ptr->y_blue;
-
-      /* The *_checked function handles error reporting, so just return 0 if
-       * there is a failure here.
-       */
-      if (png_XYZ_from_xy_checked(png_ptr, &XYZ, xy))
-      {
-         if (int_red_X != NULL)
-            *int_red_X = XYZ.redX;
-         if (int_red_Y != NULL)
-            *int_red_Y = XYZ.redY;
-         if (int_red_Z != NULL)
-            *int_red_Z = XYZ.redZ;
-         if (int_green_X != NULL)
-            *int_green_X = XYZ.greenX;
-         if (int_green_Y != NULL)
-            *int_green_Y = XYZ.greenY;
-         if (int_green_Z != NULL)
-            *int_green_Z = XYZ.greenZ;
-         if (int_blue_X != NULL)
-            *int_blue_X = XYZ.blueX;
-         if (int_blue_Y != NULL)
-            *int_blue_Y = XYZ.blueY;
-         if (int_blue_Z != NULL)
-            *int_blue_Z = XYZ.blueZ;
-
-         return (PNG_INFO_cHRM);
-      }
-   }
-
-   return (0);
-}
-
-#  ifdef PNG_FLOATING_POINT_SUPPORTED
-png_uint_32 PNGAPI
-png_get_cHRM(png_const_structp png_ptr, png_const_infop info_ptr,
-    double *white_x, double *white_y, double *red_x, double *red_y,
-    double *green_x, double *green_y, double *blue_x, double *blue_y)
-{
-   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
-   {
-      png_debug1(1, "in %s retrieval function", "cHRM");
-
-      if (white_x != NULL)
-         *white_x = png_float(png_ptr, info_ptr->x_white, "cHRM white X");
-      if (white_y != NULL)
-         *white_y = png_float(png_ptr, info_ptr->y_white, "cHRM white Y");
-      if (red_x != NULL)
-         *red_x = png_float(png_ptr, info_ptr->x_red, "cHRM red X");
-      if (red_y != NULL)
-         *red_y = png_float(png_ptr, info_ptr->y_red, "cHRM red Y");
-      if (green_x != NULL)
-         *green_x = png_float(png_ptr, info_ptr->x_green, "cHRM green X");
-      if (green_y != NULL)
-         *green_y = png_float(png_ptr, info_ptr->y_green, "cHRM green Y");
-      if (blue_x != NULL)
-         *blue_x = png_float(png_ptr, info_ptr->x_blue, "cHRM blue X");
-      if (blue_y != NULL)
-         *blue_y = png_float(png_ptr, info_ptr->y_blue, "cHRM blue Y");
-      return (PNG_INFO_cHRM);
-   }
-
-   return (0);
-}
-
-png_uint_32 PNGAPI
-png_get_cHRM_XYZ(png_structp png_ptr, png_const_infop info_ptr,
-   double *red_X, double *red_Y, double *red_Z, double *green_X,
-   double *green_Y, double *green_Z, double *blue_X, double *blue_Y,
-   double *blue_Z)
-{
-   png_XYZ XYZ;
-
-   if (png_get_cHRM_XYZ_fixed(png_ptr, info_ptr,
-      &XYZ.redX, &XYZ.redY, &XYZ.redZ, &XYZ.greenX, &XYZ.greenY, &XYZ.greenZ,
-      &XYZ.blueX, &XYZ.blueY, &XYZ.blueZ) & PNG_INFO_cHRM)
-   {
-      if (red_X != NULL)
-         *red_X = png_float(png_ptr, XYZ.redX, "cHRM red X");
-      if (red_Y != NULL)
-         *red_Y = png_float(png_ptr, XYZ.redY, "cHRM red Y");
-      if (red_Z != NULL)
-         *red_Z = png_float(png_ptr, XYZ.redZ, "cHRM red Z");
-      if (green_X != NULL)
-         *green_X = png_float(png_ptr, XYZ.greenX, "cHRM green X");
-      if (green_Y != NULL)
-         *green_Y = png_float(png_ptr, XYZ.greenY, "cHRM green Y");
-      if (green_Z != NULL)
-         *green_Z = png_float(png_ptr, XYZ.greenZ, "cHRM green Z");
-      if (blue_X != NULL)
-         *blue_X = png_float(png_ptr, XYZ.blueX, "cHRM blue X");
-      if (blue_Y != NULL)
-         *blue_Y = png_float(png_ptr, XYZ.blueY, "cHRM blue Y");
-      if (blue_Z != NULL)
-         *blue_Z = png_float(png_ptr, XYZ.blueZ, "cHRM blue Z");
-      return (PNG_INFO_cHRM);
-   }
-
-   return (0);
-}
-#  endif
-
-#  ifdef PNG_FIXED_POINT_SUPPORTED
-png_uint_32 PNGAPI
-png_get_cHRM_fixed(png_const_structp png_ptr, png_const_infop info_ptr,
-    png_fixed_point *white_x, png_fixed_point *white_y, png_fixed_point *red_x,
-    png_fixed_point *red_y, png_fixed_point *green_x, png_fixed_point *green_y,
-    png_fixed_point *blue_x, png_fixed_point *blue_y)
-{
-   png_debug1(1, "in %s retrieval function", "cHRM");
-
-   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
-   {
-      if (white_x != NULL)
-         *white_x = info_ptr->x_white;
-      if (white_y != NULL)
-         *white_y = info_ptr->y_white;
-      if (red_x != NULL)
-         *red_x = info_ptr->x_red;
-      if (red_y != NULL)
-         *red_y = info_ptr->y_red;
-      if (green_x != NULL)
-         *green_x = info_ptr->x_green;
-      if (green_y != NULL)
-         *green_y = info_ptr->y_green;
-      if (blue_x != NULL)
-         *blue_x = info_ptr->x_blue;
-      if (blue_y != NULL)
-         *blue_y = info_ptr->y_blue;
-      return (PNG_INFO_cHRM);
-   }
-
-   return (0);
-}
-#  endif
-#endif
-
-#ifdef PNG_gAMA_SUPPORTED
-png_uint_32 PNGFAPI
-png_get_gAMA_fixed(png_const_structp png_ptr, png_const_infop info_ptr,
-    png_fixed_point *file_gamma)
-{
-   png_debug1(1, "in %s retrieval function", "gAMA");
-
-   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
-       && file_gamma != NULL)
-   {
-      *file_gamma = info_ptr->gamma;
-      return (PNG_INFO_gAMA);
-   }
-
-   return (0);
-}
-#  ifdef PNG_FLOATING_POINT_SUPPORTED
-png_uint_32 PNGAPI
-png_get_gAMA(png_const_structp png_ptr, png_const_infop info_ptr,
-    double *file_gamma)
-{
-   png_fixed_point igamma;
-   png_uint_32 ok = png_get_gAMA_fixed(png_ptr, info_ptr, &igamma);
-
-   if (ok)
-      *file_gamma = png_float(png_ptr, igamma, "png_get_gAMA");
-
-   return ok;
-}
-
-#  endif
-#endif
-
-#ifdef PNG_sRGB_SUPPORTED
-png_uint_32 PNGAPI
-png_get_sRGB(png_const_structp png_ptr, png_const_infop info_ptr,
-    int *file_srgb_intent)
-{
-   png_debug1(1, "in %s retrieval function", "sRGB");
-
-   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)
-       && file_srgb_intent != NULL)
-   {
-      *file_srgb_intent = (int)info_ptr->srgb_intent;
-      return (PNG_INFO_sRGB);
-   }
-
-   return (0);
-}
-#endif
-
-#ifdef PNG_iCCP_SUPPORTED
-png_uint_32 PNGAPI
-png_get_iCCP(png_const_structp png_ptr, png_const_infop info_ptr,
-    png_charpp name, int *compression_type,
-    png_bytepp profile, png_uint_32 *proflen)
-{
-   png_debug1(1, "in %s retrieval function", "iCCP");
-
-   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP)
-       && name != NULL && compression_type != NULL && profile != NULL &&
-		 proflen != NULL)
-   {
-      *name = info_ptr->iccp_name;
-      *profile = info_ptr->iccp_profile;
-      /* Compression_type is a dummy so the API won't have to change
-       * if we introduce multiple compression types later.
-       */
-      *proflen = info_ptr->iccp_proflen;
-      *compression_type = info_ptr->iccp_compression;
-      return (PNG_INFO_iCCP);
-   }
-
-   return (0);
-}
-#endif
-
-#ifdef PNG_sPLT_SUPPORTED
-png_uint_32 PNGAPI
-png_get_sPLT(png_const_structp png_ptr, png_const_infop info_ptr,
-    png_sPLT_tpp spalettes)
-{
-   if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL)
-   {
-      *spalettes = info_ptr->splt_palettes;
-      return ((png_uint_32)info_ptr->splt_palettes_num);
-   }
-
-   return (0);
-}
-#endif
-
-#ifdef PNG_hIST_SUPPORTED
-png_uint_32 PNGAPI
-png_get_hIST(png_const_structp png_ptr, png_const_infop info_ptr,
-    png_uint_16p *hist)
-{
-   png_debug1(1, "in %s retrieval function", "hIST");
-
-   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST)
-       && hist != NULL)
-   {
-      *hist = info_ptr->hist;
-      return (PNG_INFO_hIST);
-   }
-
-   return (0);
-}
-#endif
-
-png_uint_32 PNGAPI
-png_get_IHDR(png_structp png_ptr, png_infop info_ptr,
-    png_uint_32 *width, png_uint_32 *height, int *bit_depth,
-    int *color_type, int *interlace_type, int *compression_type,
-    int *filter_type)
-
-{
-   png_debug1(1, "in %s retrieval function", "IHDR");
-
-   if (png_ptr == NULL || info_ptr == NULL || width == NULL ||
-       height == NULL || bit_depth == NULL || color_type == NULL)
-      return (0);
-
-   *width = info_ptr->width;
-   *height = info_ptr->height;
-   *bit_depth = info_ptr->bit_depth;
-   *color_type = info_ptr->color_type;
-
-   if (compression_type != NULL)
-      *compression_type = info_ptr->compression_type;
-
-   if (filter_type != NULL)
-      *filter_type = info_ptr->filter_type;
-
-   if (interlace_type != NULL)
-      *interlace_type = info_ptr->interlace_type;
-
-   /* This is redundant if we can be sure that the info_ptr values were all
-    * assigned in png_set_IHDR().  We do the check anyhow in case an
-    * application has ignored our advice not to mess with the members
-    * of info_ptr directly.
-    */
-   png_check_IHDR (png_ptr, info_ptr->width, info_ptr->height,
-       info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type,
-       info_ptr->compression_type, info_ptr->filter_type);
-
-   return (1);
-}
-
-#ifdef PNG_oFFs_SUPPORTED
-png_uint_32 PNGAPI
-png_get_oFFs(png_const_structp png_ptr, png_const_infop info_ptr,
-    png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type)
-{
-   png_debug1(1, "in %s retrieval function", "oFFs");
-
-   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)
-       && offset_x != NULL && offset_y != NULL && unit_type != NULL)
-   {
-      *offset_x = info_ptr->x_offset;
-      *offset_y = info_ptr->y_offset;
-      *unit_type = (int)info_ptr->offset_unit_type;
-      return (PNG_INFO_oFFs);
-   }
-
-   return (0);
-}
-#endif
-
-#ifdef PNG_pCAL_SUPPORTED
-png_uint_32 PNGAPI
-png_get_pCAL(png_const_structp png_ptr, png_const_infop info_ptr,
-    png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams,
-    png_charp *units, png_charpp *params)
-{
-   png_debug1(1, "in %s retrieval function", "pCAL");
-
-   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL)
-       && purpose != NULL && X0 != NULL && X1 != NULL && type != NULL &&
-       nparams != NULL && units != NULL && params != NULL)
-   {
-      *purpose = info_ptr->pcal_purpose;
-      *X0 = info_ptr->pcal_X0;
-      *X1 = info_ptr->pcal_X1;
-      *type = (int)info_ptr->pcal_type;
-      *nparams = (int)info_ptr->pcal_nparams;
-      *units = info_ptr->pcal_units;
-      *params = info_ptr->pcal_params;
-      return (PNG_INFO_pCAL);
-   }
-
-   return (0);
-}
-#endif
-
-#ifdef PNG_sCAL_SUPPORTED
-#  ifdef PNG_FIXED_POINT_SUPPORTED
-#    ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
-png_uint_32 PNGAPI
-png_get_sCAL_fixed(png_structp png_ptr, png_const_infop info_ptr,
-    int *unit, png_fixed_point *width, png_fixed_point *height)
-{
-   if (png_ptr != NULL && info_ptr != NULL &&
-       (info_ptr->valid & PNG_INFO_sCAL))
-   {
-      *unit = info_ptr->scal_unit;
-      /*TODO: make this work without FP support */
-      *width = png_fixed(png_ptr, atof(info_ptr->scal_s_width), "sCAL width");
-      *height = png_fixed(png_ptr, atof(info_ptr->scal_s_height),
-         "sCAL height");
-      return (PNG_INFO_sCAL);
-   }
-
-   return(0);
-}
-#    endif /* FLOATING_ARITHMETIC */
-#  endif /* FIXED_POINT */
-#  ifdef PNG_FLOATING_POINT_SUPPORTED
-png_uint_32 PNGAPI
-png_get_sCAL(png_const_structp png_ptr, png_const_infop info_ptr,
-    int *unit, double *width, double *height)
-{
-   if (png_ptr != NULL && info_ptr != NULL &&
-       (info_ptr->valid & PNG_INFO_sCAL))
-   {
-      *unit = info_ptr->scal_unit;
-      *width = atof(info_ptr->scal_s_width);
-      *height = atof(info_ptr->scal_s_height);
-      return (PNG_INFO_sCAL);
-   }
-
-   return(0);
-}
-#  endif /* FLOATING POINT */
-png_uint_32 PNGAPI
-png_get_sCAL_s(png_const_structp png_ptr, png_const_infop info_ptr,
-    int *unit, png_charpp width, png_charpp height)
-{
-   if (png_ptr != NULL && info_ptr != NULL &&
-       (info_ptr->valid & PNG_INFO_sCAL))
-   {
-      *unit = info_ptr->scal_unit;
-      *width = info_ptr->scal_s_width;
-      *height = info_ptr->scal_s_height;
-      return (PNG_INFO_sCAL);
-   }
-
-   return(0);
-}
-#endif /* sCAL */
-
-#ifdef PNG_pHYs_SUPPORTED
-png_uint_32 PNGAPI
-png_get_pHYs(png_const_structp png_ptr, png_const_infop info_ptr,
-    png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
-{
-   png_uint_32 retval = 0;
-
-   png_debug1(1, "in %s retrieval function", "pHYs");
-
-   if (png_ptr != NULL && info_ptr != NULL &&
-       (info_ptr->valid & PNG_INFO_pHYs))
-   {
-      if (res_x != NULL)
-      {
-         *res_x = info_ptr->x_pixels_per_unit;
-         retval |= PNG_INFO_pHYs;
-      }
-
-      if (res_y != NULL)
-      {
-         *res_y = info_ptr->y_pixels_per_unit;
-         retval |= PNG_INFO_pHYs;
-      }
-
-      if (unit_type != NULL)
-      {
-         *unit_type = (int)info_ptr->phys_unit_type;
-         retval |= PNG_INFO_pHYs;
-      }
-   }
-
-   return (retval);
-}
-#endif /* pHYs */
-
-png_uint_32 PNGAPI
-png_get_PLTE(png_const_structp png_ptr, png_const_infop info_ptr,
-    png_colorp *palette, int *num_palette)
-{
-   png_debug1(1, "in %s retrieval function", "PLTE");
-
-   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_PLTE)
-       && palette != NULL)
-   {
-      *palette = info_ptr->palette;
-      *num_palette = info_ptr->num_palette;
-      png_debug1(3, "num_palette = %d", *num_palette);
-      return (PNG_INFO_PLTE);
-   }
-
-   return (0);
-}
-
-#ifdef PNG_sBIT_SUPPORTED
-png_uint_32 PNGAPI
-png_get_sBIT(png_const_structp png_ptr, png_infop info_ptr,
-    png_color_8p *sig_bit)
-{
-   png_debug1(1, "in %s retrieval function", "sBIT");
-
-   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT)
-       && sig_bit != NULL)
-   {
-      *sig_bit = &(info_ptr->sig_bit);
-      return (PNG_INFO_sBIT);
-   }
-
-   return (0);
-}
-#endif
-
-#ifdef PNG_TEXT_SUPPORTED
-png_uint_32 PNGAPI
-png_get_text(png_const_structp png_ptr, png_const_infop info_ptr,
-    png_textp *text_ptr, int *num_text)
-{
-   if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0)
-   {
-      png_debug1(1, "in 0x%lx retrieval function",
-         (unsigned long)png_ptr->chunk_name);
-
-      if (text_ptr != NULL)
-         *text_ptr = info_ptr->text;
-
-      if (num_text != NULL)
-         *num_text = info_ptr->num_text;
-
-      return ((png_uint_32)info_ptr->num_text);
-   }
-
-   if (num_text != NULL)
-      *num_text = 0;
-
-   return(0);
-}
-#endif
-
-#ifdef PNG_tIME_SUPPORTED
-png_uint_32 PNGAPI
-png_get_tIME(png_const_structp png_ptr, png_infop info_ptr, png_timep *mod_time)
-{
-   png_debug1(1, "in %s retrieval function", "tIME");
-
-   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME)
-       && mod_time != NULL)
-   {
-      *mod_time = &(info_ptr->mod_time);
-      return (PNG_INFO_tIME);
-   }
-
-   return (0);
-}
-#endif
-
-#ifdef PNG_tRNS_SUPPORTED
-png_uint_32 PNGAPI
-png_get_tRNS(png_const_structp png_ptr, png_infop info_ptr,
-    png_bytep *trans_alpha, int *num_trans, png_color_16p *trans_color)
-{
-   png_uint_32 retval = 0;
-   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
-   {
-      png_debug1(1, "in %s retrieval function", "tRNS");
-
-      if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
-      {
-         if (trans_alpha != NULL)
-         {
-            *trans_alpha = info_ptr->trans_alpha;
-            retval |= PNG_INFO_tRNS;
-         }
-
-         if (trans_color != NULL)
-            *trans_color = &(info_ptr->trans_color);
-      }
-
-      else /* if (info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) */
-      {
-         if (trans_color != NULL)
-         {
-            *trans_color = &(info_ptr->trans_color);
-            retval |= PNG_INFO_tRNS;
-         }
-
-         if (trans_alpha != NULL)
-            *trans_alpha = NULL;
-      }
-
-      if (num_trans != NULL)
-      {
-         *num_trans = info_ptr->num_trans;
-         retval |= PNG_INFO_tRNS;
-      }
-   }
-
-   return (retval);
-}
-#endif
-
-#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
-int PNGAPI
-png_get_unknown_chunks(png_const_structp png_ptr, png_const_infop info_ptr,
-    png_unknown_chunkpp unknowns)
-{
-   if (png_ptr != NULL && info_ptr != NULL && unknowns != NULL)
-   {
-      *unknowns = info_ptr->unknown_chunks;
-      return info_ptr->unknown_chunks_num;
-   }
-
-   return (0);
-}
-#endif
-
-#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
-png_byte PNGAPI
-png_get_rgb_to_gray_status (png_const_structp png_ptr)
-{
-   return (png_byte)(png_ptr ? png_ptr->rgb_to_gray_status : 0);
-}
-#endif
-
-#ifdef PNG_USER_CHUNKS_SUPPORTED
-png_voidp PNGAPI
-png_get_user_chunk_ptr(png_const_structp png_ptr)
-{
-   return (png_ptr ? png_ptr->user_chunk_ptr : NULL);
-}
-#endif
-
-png_size_t PNGAPI
-png_get_compression_buffer_size(png_const_structp png_ptr)
-{
-   return (png_ptr ? png_ptr->zbuf_size : 0);
-}
-
-#ifdef PNG_SET_USER_LIMITS_SUPPORTED
-/* These functions were added to libpng 1.2.6 and were enabled
- * by default in libpng-1.4.0 */
-png_uint_32 PNGAPI
-png_get_user_width_max (png_const_structp png_ptr)
-{
-   return (png_ptr ? png_ptr->user_width_max : 0);
-}
-
-png_uint_32 PNGAPI
-png_get_user_height_max (png_const_structp png_ptr)
-{
-   return (png_ptr ? png_ptr->user_height_max : 0);
-}
-
-/* This function was added to libpng 1.4.0 */
-png_uint_32 PNGAPI
-png_get_chunk_cache_max (png_const_structp png_ptr)
-{
-   return (png_ptr ? png_ptr->user_chunk_cache_max : 0);
-}
-
-/* This function was added to libpng 1.4.1 */
-png_alloc_size_t PNGAPI
-png_get_chunk_malloc_max (png_const_structp png_ptr)
-{
-   return (png_ptr ? png_ptr->user_chunk_malloc_max : 0);
-}
-#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */
-
-/* These functions were added to libpng 1.4.0 */
-#ifdef PNG_IO_STATE_SUPPORTED
-png_uint_32 PNGAPI
-png_get_io_state (png_structp png_ptr)
-{
-   return png_ptr->io_state;
-}
-
-png_uint_32 PNGAPI
-png_get_io_chunk_type (png_const_structp png_ptr)
-{
-   return png_ptr->chunk_name;
-}
-
-png_const_bytep PNGAPI
-png_get_io_chunk_name (png_structp png_ptr)
-{
-   PNG_CSTRING_FROM_CHUNK(png_ptr->io_chunk_string, png_ptr->chunk_name);
-   return png_ptr->io_chunk_string;
-}
-#endif /* ?PNG_IO_STATE_SUPPORTED */
-
-#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
+
+/* pngget.c - retrieval of values from info struct
+ *
+ * Last changed in libpng 1.6.15 [November 20, 2014]
+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ */
+
+#include "pngpriv.h"
+
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+
+png_uint_32 PNGAPI
+png_get_valid(png_const_structrp png_ptr, png_const_inforp info_ptr,
+    png_uint_32 flag)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+      return(info_ptr->valid & flag);
+
+   return(0);
+}
+
+png_size_t PNGAPI
+png_get_rowbytes(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+      return(info_ptr->rowbytes);
+
+   return(0);
+}
+
+#ifdef PNG_INFO_IMAGE_SUPPORTED
+png_bytepp PNGAPI
+png_get_rows(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+      return(info_ptr->row_pointers);
+
+   return(0);
+}
+#endif
+
+#ifdef PNG_EASY_ACCESS_SUPPORTED
+/* Easy access to info, added in libpng-0.99 */
+png_uint_32 PNGAPI
+png_get_image_width(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+      return info_ptr->width;
+
+   return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_image_height(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+      return info_ptr->height;
+
+   return (0);
+}
+
+png_byte PNGAPI
+png_get_bit_depth(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+      return info_ptr->bit_depth;
+
+   return (0);
+}
+
+png_byte PNGAPI
+png_get_color_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+      return info_ptr->color_type;
+
+   return (0);
+}
+
+png_byte PNGAPI
+png_get_filter_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+      return info_ptr->filter_type;
+
+   return (0);
+}
+
+png_byte PNGAPI
+png_get_interlace_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+      return info_ptr->interlace_type;
+
+   return (0);
+}
+
+png_byte PNGAPI
+png_get_compression_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+      return info_ptr->compression_type;
+
+   return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_x_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp
+   info_ptr)
+{
+#ifdef PNG_pHYs_SUPPORTED
+   if (png_ptr != NULL && info_ptr != NULL &&
+       (info_ptr->valid & PNG_INFO_pHYs) != 0)
+      {
+         png_debug1(1, "in %s retrieval function",
+             "png_get_x_pixels_per_meter");
+
+         if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER)
+            return (info_ptr->x_pixels_per_unit);
+      }
+#else
+   PNG_UNUSED(png_ptr)
+   PNG_UNUSED(info_ptr)
+#endif
+
+   return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_y_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp
+    info_ptr)
+{
+#ifdef PNG_pHYs_SUPPORTED
+   if (png_ptr != NULL && info_ptr != NULL &&
+       (info_ptr->valid & PNG_INFO_pHYs) != 0)
+   {
+      png_debug1(1, "in %s retrieval function",
+          "png_get_y_pixels_per_meter");
+
+      if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER)
+         return (info_ptr->y_pixels_per_unit);
+   }
+#else
+   PNG_UNUSED(png_ptr)
+   PNG_UNUSED(info_ptr)
+#endif
+
+   return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+#ifdef PNG_pHYs_SUPPORTED
+   if (png_ptr != NULL && info_ptr != NULL &&
+       (info_ptr->valid & PNG_INFO_pHYs) != 0)
+   {
+      png_debug1(1, "in %s retrieval function", "png_get_pixels_per_meter");
+
+      if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER &&
+          info_ptr->x_pixels_per_unit == info_ptr->y_pixels_per_unit)
+         return (info_ptr->x_pixels_per_unit);
+   }
+#else
+   PNG_UNUSED(png_ptr)
+   PNG_UNUSED(info_ptr)
+#endif
+
+   return (0);
+}
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+float PNGAPI
+png_get_pixel_aspect_ratio(png_const_structrp png_ptr, png_const_inforp
+   info_ptr)
+{
+#ifdef PNG_READ_pHYs_SUPPORTED
+   if (png_ptr != NULL && info_ptr != NULL &&
+       (info_ptr->valid & PNG_INFO_pHYs) != 0)
+   {
+      png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio");
+
+      if (info_ptr->x_pixels_per_unit != 0)
+         return ((float)((float)info_ptr->y_pixels_per_unit
+             /(float)info_ptr->x_pixels_per_unit));
+   }
+#else
+   PNG_UNUSED(png_ptr)
+   PNG_UNUSED(info_ptr)
+#endif
+
+   return ((float)0.0);
+}
+#endif
+
+#ifdef PNG_FIXED_POINT_SUPPORTED
+png_fixed_point PNGAPI
+png_get_pixel_aspect_ratio_fixed(png_const_structrp png_ptr,
+    png_const_inforp info_ptr)
+{
+#ifdef PNG_READ_pHYs_SUPPORTED
+   if (png_ptr != NULL && info_ptr != NULL &&
+       (info_ptr->valid & PNG_INFO_pHYs) != 0 &&
+       info_ptr->x_pixels_per_unit > 0 && info_ptr->y_pixels_per_unit > 0 &&
+       info_ptr->x_pixels_per_unit <= PNG_UINT_31_MAX &&
+       info_ptr->y_pixels_per_unit <= PNG_UINT_31_MAX)
+   {
+      png_fixed_point res;
+
+      png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio_fixed");
+
+      /* The following casts work because a PNG 4 byte integer only has a valid
+       * range of 0..2^31-1; otherwise the cast might overflow.
+       */
+      if (png_muldiv(&res, (png_int_32)info_ptr->y_pixels_per_unit, PNG_FP_1,
+          (png_int_32)info_ptr->x_pixels_per_unit) != 0)
+         return res;
+   }
+#else
+   PNG_UNUSED(png_ptr)
+   PNG_UNUSED(info_ptr)
+#endif
+
+   return 0;
+}
+#endif
+
+png_int_32 PNGAPI
+png_get_x_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+#ifdef PNG_oFFs_SUPPORTED
+   if (png_ptr != NULL && info_ptr != NULL &&
+       (info_ptr->valid & PNG_INFO_oFFs) != 0)
+   {
+      png_debug1(1, "in %s retrieval function", "png_get_x_offset_microns");
+
+      if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER)
+         return (info_ptr->x_offset);
+   }
+#else
+   PNG_UNUSED(png_ptr)
+   PNG_UNUSED(info_ptr)
+#endif
+
+   return (0);
+}
+
+png_int_32 PNGAPI
+png_get_y_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+#ifdef PNG_oFFs_SUPPORTED
+   if (png_ptr != NULL && info_ptr != NULL &&
+       (info_ptr->valid & PNG_INFO_oFFs) != 0)
+   {
+      png_debug1(1, "in %s retrieval function", "png_get_y_offset_microns");
+
+      if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER)
+         return (info_ptr->y_offset);
+   }
+#else
+   PNG_UNUSED(png_ptr)
+   PNG_UNUSED(info_ptr)
+#endif
+
+   return (0);
+}
+
+png_int_32 PNGAPI
+png_get_x_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+#ifdef PNG_oFFs_SUPPORTED
+   if (png_ptr != NULL && info_ptr != NULL &&
+       (info_ptr->valid & PNG_INFO_oFFs) != 0)
+   {
+      png_debug1(1, "in %s retrieval function", "png_get_x_offset_pixels");
+
+      if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL)
+         return (info_ptr->x_offset);
+   }
+#else
+   PNG_UNUSED(png_ptr)
+   PNG_UNUSED(info_ptr)
+#endif
+
+   return (0);
+}
+
+png_int_32 PNGAPI
+png_get_y_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+#ifdef PNG_oFFs_SUPPORTED
+   if (png_ptr != NULL && info_ptr != NULL &&
+       (info_ptr->valid & PNG_INFO_oFFs) != 0)
+   {
+      png_debug1(1, "in %s retrieval function", "png_get_y_offset_pixels");
+
+      if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL)
+         return (info_ptr->y_offset);
+   }
+#else
+   PNG_UNUSED(png_ptr)
+   PNG_UNUSED(info_ptr)
+#endif
+
+   return (0);
+}
+
+#ifdef PNG_INCH_CONVERSIONS_SUPPORTED
+static png_uint_32
+ppi_from_ppm(png_uint_32 ppm)
+{
+#if 0
+   /* The conversion is *(2.54/100), in binary (32 digits):
+    * .00000110100000001001110101001001
+    */
+   png_uint_32 t1001, t1101;
+   ppm >>= 1;                  /* .1 */
+   t1001 = ppm + (ppm >> 3);   /* .1001 */
+   t1101 = t1001 + (ppm >> 1); /* .1101 */
+   ppm >>= 20;                 /* .000000000000000000001 */
+   t1101 += t1101 >> 15;       /* .1101000000000001101 */
+   t1001 >>= 11;               /* .000000000001001 */
+   t1001 += t1001 >> 12;       /* .000000000001001000000001001 */
+   ppm += t1001;               /* .000000000001001000001001001 */
+   ppm += t1101;               /* .110100000001001110101001001 */
+   return (ppm + 16) >> 5;/* .00000110100000001001110101001001 */
+#else
+   /* The argument is a PNG unsigned integer, so it is not permitted
+    * to be bigger than 2^31.
+    */
+   png_fixed_point result;
+   if (ppm <= PNG_UINT_31_MAX && png_muldiv(&result, (png_int_32)ppm, 127,
+       5000) != 0)
+      return result;
+
+   /* Overflow. */
+   return 0;
+#endif
+}
+
+png_uint_32 PNGAPI
+png_get_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+   return ppi_from_ppm(png_get_pixels_per_meter(png_ptr, info_ptr));
+}
+
+png_uint_32 PNGAPI
+png_get_x_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+   return ppi_from_ppm(png_get_x_pixels_per_meter(png_ptr, info_ptr));
+}
+
+png_uint_32 PNGAPI
+png_get_y_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+   return ppi_from_ppm(png_get_y_pixels_per_meter(png_ptr, info_ptr));
+}
+
+#ifdef PNG_FIXED_POINT_SUPPORTED
+static png_fixed_point
+png_fixed_inches_from_microns(png_const_structrp png_ptr, png_int_32 microns)
+{
+   /* Convert from metres * 1,000,000 to inches * 100,000, meters to
+    * inches is simply *(100/2.54), so we want *(10/2.54) == 500/127.
+    * Notice that this can overflow - a warning is output and 0 is
+    * returned.
+    */
+   return png_muldiv_warn(png_ptr, microns, 500, 127);
+}
+
+png_fixed_point PNGAPI
+png_get_x_offset_inches_fixed(png_const_structrp png_ptr,
+    png_const_inforp info_ptr)
+{
+   return png_fixed_inches_from_microns(png_ptr,
+       png_get_x_offset_microns(png_ptr, info_ptr));
+}
+#endif
+
+#ifdef PNG_FIXED_POINT_SUPPORTED
+png_fixed_point PNGAPI
+png_get_y_offset_inches_fixed(png_const_structrp png_ptr,
+    png_const_inforp info_ptr)
+{
+   return png_fixed_inches_from_microns(png_ptr,
+       png_get_y_offset_microns(png_ptr, info_ptr));
+}
+#endif
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+float PNGAPI
+png_get_x_offset_inches(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+   /* To avoid the overflow do the conversion directly in floating
+    * point.
+    */
+   return (float)(png_get_x_offset_microns(png_ptr, info_ptr) * .00003937);
+}
+#endif
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+float PNGAPI
+png_get_y_offset_inches(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+   /* To avoid the overflow do the conversion directly in floating
+    * point.
+    */
+   return (float)(png_get_y_offset_microns(png_ptr, info_ptr) * .00003937);
+}
+#endif
+
+#ifdef PNG_pHYs_SUPPORTED
+png_uint_32 PNGAPI
+png_get_pHYs_dpi(png_const_structrp png_ptr, png_const_inforp info_ptr,
+    png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
+{
+   png_uint_32 retval = 0;
+
+   if (png_ptr != NULL && info_ptr != NULL &&
+       (info_ptr->valid & PNG_INFO_pHYs) != 0)
+   {
+      png_debug1(1, "in %s retrieval function", "pHYs");
+
+      if (res_x != NULL)
+      {
+         *res_x = info_ptr->x_pixels_per_unit;
+         retval |= PNG_INFO_pHYs;
+      }
+
+      if (res_y != NULL)
+      {
+         *res_y = info_ptr->y_pixels_per_unit;
+         retval |= PNG_INFO_pHYs;
+      }
+
+      if (unit_type != NULL)
+      {
+         *unit_type = (int)info_ptr->phys_unit_type;
+         retval |= PNG_INFO_pHYs;
+
+         if (*unit_type == 1)
+         {
+            if (res_x != NULL) *res_x = (png_uint_32)(*res_x * .0254 + .50);
+            if (res_y != NULL) *res_y = (png_uint_32)(*res_y * .0254 + .50);
+         }
+      }
+   }
+
+   return (retval);
+}
+#endif /* pHYs */
+#endif  /* INCH_CONVERSIONS */
+
+/* png_get_channels really belongs in here, too, but it's been around longer */
+
+#endif  /* EASY_ACCESS */
+
+
+png_byte PNGAPI
+png_get_channels(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+      return(info_ptr->channels);
+
+   return (0);
+}
+
+#ifdef PNG_READ_SUPPORTED
+png_const_bytep PNGAPI
+png_get_signature(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+      return(info_ptr->signature);
+
+   return (NULL);
+}
+#endif
+
+#ifdef PNG_bKGD_SUPPORTED
+png_uint_32 PNGAPI
+png_get_bKGD(png_const_structrp png_ptr, png_inforp info_ptr,
+   png_color_16p *background)
+{
+   if (png_ptr != NULL && info_ptr != NULL &&
+       (info_ptr->valid & PNG_INFO_bKGD) != 0 &&
+       background != NULL)
+   {
+      png_debug1(1, "in %s retrieval function", "bKGD");
+
+      *background = &(info_ptr->background);
+      return (PNG_INFO_bKGD);
+   }
+
+   return (0);
+}
+#endif
+
+#ifdef PNG_cHRM_SUPPORTED
+/* The XYZ APIs were added in 1.5.5 to take advantage of the code added at the
+ * same time to correct the rgb grayscale coefficient defaults obtained from the
+ * cHRM chunk in 1.5.4
+ */
+#  ifdef PNG_FLOATING_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr,
+    double *white_x, double *white_y, double *red_x, double *red_y,
+    double *green_x, double *green_y, double *blue_x, double *blue_y)
+{
+   /* Quiet API change: this code used to only return the end points if a cHRM
+    * chunk was present, but the end points can also come from iCCP or sRGB
+    * chunks, so in 1.6.0 the png_get_ APIs return the end points regardless and
+    * the png_set_ APIs merely check that set end points are mutually
+    * consistent.
+    */
+   if (png_ptr != NULL && info_ptr != NULL &&
+      (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
+   {
+      png_debug1(1, "in %s retrieval function", "cHRM");
+
+      if (white_x != NULL)
+         *white_x = png_float(png_ptr,
+            info_ptr->colorspace.end_points_xy.whitex, "cHRM white X");
+      if (white_y != NULL)
+         *white_y = png_float(png_ptr,
+            info_ptr->colorspace.end_points_xy.whitey, "cHRM white Y");
+      if (red_x != NULL)
+         *red_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redx,
+            "cHRM red X");
+      if (red_y != NULL)
+         *red_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redy,
+            "cHRM red Y");
+      if (green_x != NULL)
+         *green_x = png_float(png_ptr,
+            info_ptr->colorspace.end_points_xy.greenx, "cHRM green X");
+      if (green_y != NULL)
+         *green_y = png_float(png_ptr,
+            info_ptr->colorspace.end_points_xy.greeny, "cHRM green Y");
+      if (blue_x != NULL)
+         *blue_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluex,
+            "cHRM blue X");
+      if (blue_y != NULL)
+         *blue_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluey,
+            "cHRM blue Y");
+      return (PNG_INFO_cHRM);
+   }
+
+   return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_cHRM_XYZ(png_const_structrp png_ptr, png_const_inforp info_ptr,
+   double *red_X, double *red_Y, double *red_Z, double *green_X,
+   double *green_Y, double *green_Z, double *blue_X, double *blue_Y,
+   double *blue_Z)
+{
+   if (png_ptr != NULL && info_ptr != NULL &&
+      (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
+   {
+      png_debug1(1, "in %s retrieval function", "cHRM_XYZ(float)");
+
+      if (red_X != NULL)
+         *red_X = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_X,
+            "cHRM red X");
+      if (red_Y != NULL)
+         *red_Y = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Y,
+            "cHRM red Y");
+      if (red_Z != NULL)
+         *red_Z = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Z,
+            "cHRM red Z");
+      if (green_X != NULL)
+         *green_X = png_float(png_ptr,
+            info_ptr->colorspace.end_points_XYZ.green_X, "cHRM green X");
+      if (green_Y != NULL)
+         *green_Y = png_float(png_ptr,
+            info_ptr->colorspace.end_points_XYZ.green_Y, "cHRM green Y");
+      if (green_Z != NULL)
+         *green_Z = png_float(png_ptr,
+            info_ptr->colorspace.end_points_XYZ.green_Z, "cHRM green Z");
+      if (blue_X != NULL)
+         *blue_X = png_float(png_ptr,
+            info_ptr->colorspace.end_points_XYZ.blue_X, "cHRM blue X");
+      if (blue_Y != NULL)
+         *blue_Y = png_float(png_ptr,
+            info_ptr->colorspace.end_points_XYZ.blue_Y, "cHRM blue Y");
+      if (blue_Z != NULL)
+         *blue_Z = png_float(png_ptr,
+            info_ptr->colorspace.end_points_XYZ.blue_Z, "cHRM blue Z");
+      return (PNG_INFO_cHRM);
+   }
+
+   return (0);
+}
+#  endif
+
+#  ifdef PNG_FIXED_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
+    png_fixed_point *int_red_X, png_fixed_point *int_red_Y,
+    png_fixed_point *int_red_Z, png_fixed_point *int_green_X,
+    png_fixed_point *int_green_Y, png_fixed_point *int_green_Z,
+    png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y,
+    png_fixed_point *int_blue_Z)
+{
+   if (png_ptr != NULL && info_ptr != NULL &&
+      (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
+   {
+      png_debug1(1, "in %s retrieval function", "cHRM_XYZ");
+
+      if (int_red_X != NULL)
+         *int_red_X = info_ptr->colorspace.end_points_XYZ.red_X;
+      if (int_red_Y != NULL)
+         *int_red_Y = info_ptr->colorspace.end_points_XYZ.red_Y;
+      if (int_red_Z != NULL)
+         *int_red_Z = info_ptr->colorspace.end_points_XYZ.red_Z;
+      if (int_green_X != NULL)
+         *int_green_X = info_ptr->colorspace.end_points_XYZ.green_X;
+      if (int_green_Y != NULL)
+         *int_green_Y = info_ptr->colorspace.end_points_XYZ.green_Y;
+      if (int_green_Z != NULL)
+         *int_green_Z = info_ptr->colorspace.end_points_XYZ.green_Z;
+      if (int_blue_X != NULL)
+         *int_blue_X = info_ptr->colorspace.end_points_XYZ.blue_X;
+      if (int_blue_Y != NULL)
+         *int_blue_Y = info_ptr->colorspace.end_points_XYZ.blue_Y;
+      if (int_blue_Z != NULL)
+         *int_blue_Z = info_ptr->colorspace.end_points_XYZ.blue_Z;
+      return (PNG_INFO_cHRM);
+   }
+
+   return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_cHRM_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
+    png_fixed_point *white_x, png_fixed_point *white_y, png_fixed_point *red_x,
+    png_fixed_point *red_y, png_fixed_point *green_x, png_fixed_point *green_y,
+    png_fixed_point *blue_x, png_fixed_point *blue_y)
+{
+   png_debug1(1, "in %s retrieval function", "cHRM");
+
+   if (png_ptr != NULL && info_ptr != NULL &&
+      (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
+   {
+      if (white_x != NULL)
+         *white_x = info_ptr->colorspace.end_points_xy.whitex;
+      if (white_y != NULL)
+         *white_y = info_ptr->colorspace.end_points_xy.whitey;
+      if (red_x != NULL)
+         *red_x = info_ptr->colorspace.end_points_xy.redx;
+      if (red_y != NULL)
+         *red_y = info_ptr->colorspace.end_points_xy.redy;
+      if (green_x != NULL)
+         *green_x = info_ptr->colorspace.end_points_xy.greenx;
+      if (green_y != NULL)
+         *green_y = info_ptr->colorspace.end_points_xy.greeny;
+      if (blue_x != NULL)
+         *blue_x = info_ptr->colorspace.end_points_xy.bluex;
+      if (blue_y != NULL)
+         *blue_y = info_ptr->colorspace.end_points_xy.bluey;
+      return (PNG_INFO_cHRM);
+   }
+
+   return (0);
+}
+#  endif
+#endif
+
+#ifdef PNG_gAMA_SUPPORTED
+#  ifdef PNG_FIXED_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_gAMA_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
+    png_fixed_point *file_gamma)
+{
+   png_debug1(1, "in %s retrieval function", "gAMA");
+
+   if (png_ptr != NULL && info_ptr != NULL &&
+      (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 &&
+      file_gamma != NULL)
+   {
+      *file_gamma = info_ptr->colorspace.gamma;
+      return (PNG_INFO_gAMA);
+   }
+
+   return (0);
+}
+#  endif
+
+#  ifdef PNG_FLOATING_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_gAMA(png_const_structrp png_ptr, png_const_inforp info_ptr,
+    double *file_gamma)
+{
+   png_debug1(1, "in %s retrieval function", "gAMA(float)");
+
+   if (png_ptr != NULL && info_ptr != NULL &&
+      (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 &&
+      file_gamma != NULL)
+   {
+      *file_gamma = png_float(png_ptr, info_ptr->colorspace.gamma,
+         "png_get_gAMA");
+      return (PNG_INFO_gAMA);
+   }
+
+   return (0);
+}
+#  endif
+#endif
+
+#ifdef PNG_sRGB_SUPPORTED
+png_uint_32 PNGAPI
+png_get_sRGB(png_const_structrp png_ptr, png_const_inforp info_ptr,
+    int *file_srgb_intent)
+{
+   png_debug1(1, "in %s retrieval function", "sRGB");
+
+   if (png_ptr != NULL && info_ptr != NULL &&
+      (info_ptr->valid & PNG_INFO_sRGB) != 0 && file_srgb_intent != NULL)
+   {
+      *file_srgb_intent = info_ptr->colorspace.rendering_intent;
+      return (PNG_INFO_sRGB);
+   }
+
+   return (0);
+}
+#endif
+
+#ifdef PNG_iCCP_SUPPORTED
+png_uint_32 PNGAPI
+png_get_iCCP(png_const_structrp png_ptr, png_inforp info_ptr,
+    png_charpp name, int *compression_type,
+    png_bytepp profile, png_uint_32 *proflen)
+{
+   png_debug1(1, "in %s retrieval function", "iCCP");
+
+   if (png_ptr != NULL && info_ptr != NULL &&
+       (info_ptr->valid & PNG_INFO_iCCP) != 0 &&
+       name != NULL && compression_type != NULL && profile != NULL &&
+           proflen != NULL)
+   {
+      *name = info_ptr->iccp_name;
+      *profile = info_ptr->iccp_profile;
+      *proflen = png_get_uint_32(info_ptr->iccp_profile);
+      /* This is somewhat irrelevant since the profile data returned has
+       * actually been uncompressed.
+       */
+      *compression_type = PNG_COMPRESSION_TYPE_BASE;
+      return (PNG_INFO_iCCP);
+   }
+
+   return (0);
+}
+#endif
+
+#ifdef PNG_sPLT_SUPPORTED
+int PNGAPI
+png_get_sPLT(png_const_structrp png_ptr, png_inforp info_ptr,
+    png_sPLT_tpp spalettes)
+{
+   if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL)
+   {
+      *spalettes = info_ptr->splt_palettes;
+      return info_ptr->splt_palettes_num;
+   }
+
+   return (0);
+}
+#endif
+
+#ifdef PNG_hIST_SUPPORTED
+png_uint_32 PNGAPI
+png_get_hIST(png_const_structrp png_ptr, png_inforp info_ptr,
+    png_uint_16p *hist)
+{
+   png_debug1(1, "in %s retrieval function", "hIST");
+
+   if (png_ptr != NULL && info_ptr != NULL &&
+       (info_ptr->valid & PNG_INFO_hIST) != 0 && hist != NULL)
+   {
+      *hist = info_ptr->hist;
+      return (PNG_INFO_hIST);
+   }
+
+   return (0);
+}
+#endif
+
+png_uint_32 PNGAPI
+png_get_IHDR(png_const_structrp png_ptr, png_const_inforp info_ptr,
+    png_uint_32 *width, png_uint_32 *height, int *bit_depth,
+    int *color_type, int *interlace_type, int *compression_type,
+    int *filter_type)
+{
+   png_debug1(1, "in %s retrieval function", "IHDR");
+
+   if (png_ptr == NULL || info_ptr == NULL || width == NULL ||
+       height == NULL || bit_depth == NULL || color_type == NULL)
+      return (0);
+
+   *width = info_ptr->width;
+   *height = info_ptr->height;
+   *bit_depth = info_ptr->bit_depth;
+   *color_type = info_ptr->color_type;
+
+   if (compression_type != NULL)
+      *compression_type = info_ptr->compression_type;
+
+   if (filter_type != NULL)
+      *filter_type = info_ptr->filter_type;
+
+   if (interlace_type != NULL)
+      *interlace_type = info_ptr->interlace_type;
+
+   /* This is redundant if we can be sure that the info_ptr values were all
+    * assigned in png_set_IHDR().  We do the check anyhow in case an
+    * application has ignored our advice not to mess with the members
+    * of info_ptr directly.
+    */
+   png_check_IHDR(png_ptr, info_ptr->width, info_ptr->height,
+       info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type,
+       info_ptr->compression_type, info_ptr->filter_type);
+
+   return (1);
+}
+
+#ifdef PNG_oFFs_SUPPORTED
+png_uint_32 PNGAPI
+png_get_oFFs(png_const_structrp png_ptr, png_const_inforp info_ptr,
+    png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type)
+{
+   png_debug1(1, "in %s retrieval function", "oFFs");
+
+   if (png_ptr != NULL && info_ptr != NULL &&
+       (info_ptr->valid & PNG_INFO_oFFs) != 0 &&
+       offset_x != NULL && offset_y != NULL && unit_type != NULL)
+   {
+      *offset_x = info_ptr->x_offset;
+      *offset_y = info_ptr->y_offset;
+      *unit_type = (int)info_ptr->offset_unit_type;
+      return (PNG_INFO_oFFs);
+   }
+
+   return (0);
+}
+#endif
+
+#ifdef PNG_pCAL_SUPPORTED
+png_uint_32 PNGAPI
+png_get_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
+    png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams,
+    png_charp *units, png_charpp *params)
+{
+   png_debug1(1, "in %s retrieval function", "pCAL");
+
+   if (png_ptr != NULL && info_ptr != NULL &&
+       (info_ptr->valid & PNG_INFO_pCAL) != 0 &&
+       purpose != NULL && X0 != NULL && X1 != NULL && type != NULL &&
+       nparams != NULL && units != NULL && params != NULL)
+   {
+      *purpose = info_ptr->pcal_purpose;
+      *X0 = info_ptr->pcal_X0;
+      *X1 = info_ptr->pcal_X1;
+      *type = (int)info_ptr->pcal_type;
+      *nparams = (int)info_ptr->pcal_nparams;
+      *units = info_ptr->pcal_units;
+      *params = info_ptr->pcal_params;
+      return (PNG_INFO_pCAL);
+   }
+
+   return (0);
+}
+#endif
+
+#ifdef PNG_sCAL_SUPPORTED
+#  ifdef PNG_FIXED_POINT_SUPPORTED
+#    if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || \
+         defined(PNG_FLOATING_POINT_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_sCAL_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
+    int *unit, png_fixed_point *width, png_fixed_point *height)
+{
+   if (png_ptr != NULL && info_ptr != NULL &&
+       (info_ptr->valid & PNG_INFO_sCAL) != 0)
+   {
+      *unit = info_ptr->scal_unit;
+      /*TODO: make this work without FP support; the API is currently eliminated
+       * if neither floating point APIs nor internal floating point arithmetic
+       * are enabled.
+       */
+      *width = png_fixed(png_ptr, atof(info_ptr->scal_s_width), "sCAL width");
+      *height = png_fixed(png_ptr, atof(info_ptr->scal_s_height),
+         "sCAL height");
+      return (PNG_INFO_sCAL);
+   }
+
+   return(0);
+}
+#    endif /* FLOATING_ARITHMETIC */
+#  endif /* FIXED_POINT */
+#  ifdef PNG_FLOATING_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_sCAL(png_const_structrp png_ptr, png_const_inforp info_ptr,
+    int *unit, double *width, double *height)
+{
+   if (png_ptr != NULL && info_ptr != NULL &&
+       (info_ptr->valid & PNG_INFO_sCAL) != 0)
+   {
+      *unit = info_ptr->scal_unit;
+      *width = atof(info_ptr->scal_s_width);
+      *height = atof(info_ptr->scal_s_height);
+      return (PNG_INFO_sCAL);
+   }
+
+   return(0);
+}
+#  endif /* FLOATING POINT */
+png_uint_32 PNGAPI
+png_get_sCAL_s(png_const_structrp png_ptr, png_const_inforp info_ptr,
+    int *unit, png_charpp width, png_charpp height)
+{
+   if (png_ptr != NULL && info_ptr != NULL &&
+       (info_ptr->valid & PNG_INFO_sCAL) != 0)
+   {
+      *unit = info_ptr->scal_unit;
+      *width = info_ptr->scal_s_width;
+      *height = info_ptr->scal_s_height;
+      return (PNG_INFO_sCAL);
+   }
+
+   return(0);
+}
+#endif /* sCAL */
+
+#ifdef PNG_pHYs_SUPPORTED
+png_uint_32 PNGAPI
+png_get_pHYs(png_const_structrp png_ptr, png_const_inforp info_ptr,
+    png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
+{
+   png_uint_32 retval = 0;
+
+   png_debug1(1, "in %s retrieval function", "pHYs");
+
+   if (png_ptr != NULL && info_ptr != NULL &&
+       (info_ptr->valid & PNG_INFO_pHYs) != 0)
+   {
+      if (res_x != NULL)
+      {
+         *res_x = info_ptr->x_pixels_per_unit;
+         retval |= PNG_INFO_pHYs;
+      }
+
+      if (res_y != NULL)
+      {
+         *res_y = info_ptr->y_pixels_per_unit;
+         retval |= PNG_INFO_pHYs;
+      }
+
+      if (unit_type != NULL)
+      {
+         *unit_type = (int)info_ptr->phys_unit_type;
+         retval |= PNG_INFO_pHYs;
+      }
+   }
+
+   return (retval);
+}
+#endif /* pHYs */
+
+png_uint_32 PNGAPI
+png_get_PLTE(png_const_structrp png_ptr, png_inforp info_ptr,
+    png_colorp *palette, int *num_palette)
+{
+   png_debug1(1, "in %s retrieval function", "PLTE");
+
+   if (png_ptr != NULL && info_ptr != NULL &&
+       (info_ptr->valid & PNG_INFO_PLTE) != 0 && palette != NULL)
+   {
+      *palette = info_ptr->palette;
+      *num_palette = info_ptr->num_palette;
+      png_debug1(3, "num_palette = %d", *num_palette);
+      return (PNG_INFO_PLTE);
+   }
+
+   return (0);
+}
+
+#ifdef PNG_sBIT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_sBIT(png_const_structrp png_ptr, png_inforp info_ptr,
+    png_color_8p *sig_bit)
+{
+   png_debug1(1, "in %s retrieval function", "sBIT");
+
+   if (png_ptr != NULL && info_ptr != NULL &&
+       (info_ptr->valid & PNG_INFO_sBIT) != 0 && sig_bit != NULL)
+   {
+      *sig_bit = &(info_ptr->sig_bit);
+      return (PNG_INFO_sBIT);
+   }
+
+   return (0);
+}
+#endif
+
+#ifdef PNG_TEXT_SUPPORTED
+int PNGAPI
+png_get_text(png_const_structrp png_ptr, png_inforp info_ptr,
+    png_textp *text_ptr, int *num_text)
+{
+   if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0)
+   {
+      png_debug1(1, "in 0x%lx retrieval function",
+         (unsigned long)png_ptr->chunk_name);
+
+      if (text_ptr != NULL)
+         *text_ptr = info_ptr->text;
+
+      if (num_text != NULL)
+         *num_text = info_ptr->num_text;
+
+      return info_ptr->num_text;
+   }
+
+   if (num_text != NULL)
+      *num_text = 0;
+
+   return(0);
+}
+#endif
+
+#ifdef PNG_tIME_SUPPORTED
+png_uint_32 PNGAPI
+png_get_tIME(png_const_structrp png_ptr, png_inforp info_ptr,
+    png_timep *mod_time)
+{
+   png_debug1(1, "in %s retrieval function", "tIME");
+
+   if (png_ptr != NULL && info_ptr != NULL &&
+       (info_ptr->valid & PNG_INFO_tIME) != 0 && mod_time != NULL)
+   {
+      *mod_time = &(info_ptr->mod_time);
+      return (PNG_INFO_tIME);
+   }
+
+   return (0);
+}
+#endif
+
+#ifdef PNG_tRNS_SUPPORTED
+png_uint_32 PNGAPI
+png_get_tRNS(png_const_structrp png_ptr, png_inforp info_ptr,
+    png_bytep *trans_alpha, int *num_trans, png_color_16p *trans_color)
+{
+   png_uint_32 retval = 0;
+   if (png_ptr != NULL && info_ptr != NULL &&
+       (info_ptr->valid & PNG_INFO_tRNS) != 0)
+   {
+      png_debug1(1, "in %s retrieval function", "tRNS");
+
+      if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      {
+         if (trans_alpha != NULL)
+         {
+            *trans_alpha = info_ptr->trans_alpha;
+            retval |= PNG_INFO_tRNS;
+         }
+
+         if (trans_color != NULL)
+            *trans_color = &(info_ptr->trans_color);
+      }
+
+      else /* if (info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) */
+      {
+         if (trans_color != NULL)
+         {
+            *trans_color = &(info_ptr->trans_color);
+            retval |= PNG_INFO_tRNS;
+         }
+
+         if (trans_alpha != NULL)
+            *trans_alpha = NULL;
+      }
+
+      if (num_trans != NULL)
+      {
+         *num_trans = info_ptr->num_trans;
+         retval |= PNG_INFO_tRNS;
+      }
+   }
+
+   return (retval);
+}
+#endif
+
+#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
+int PNGAPI
+png_get_unknown_chunks(png_const_structrp png_ptr, png_inforp info_ptr,
+    png_unknown_chunkpp unknowns)
+{
+   if (png_ptr != NULL && info_ptr != NULL && unknowns != NULL)
+   {
+      *unknowns = info_ptr->unknown_chunks;
+      return info_ptr->unknown_chunks_num;
+   }
+
+   return (0);
+}
+#endif
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+png_byte PNGAPI
+png_get_rgb_to_gray_status (png_const_structrp png_ptr)
+{
+   return (png_byte)(png_ptr ? png_ptr->rgb_to_gray_status : 0);
+}
+#endif
+
+#ifdef PNG_USER_CHUNKS_SUPPORTED
+png_voidp PNGAPI
+png_get_user_chunk_ptr(png_const_structrp png_ptr)
+{
+   return (png_ptr ? png_ptr->user_chunk_ptr : NULL);
+}
+#endif
+
+png_size_t PNGAPI
+png_get_compression_buffer_size(png_const_structrp png_ptr)
+{
+   if (png_ptr == NULL)
+      return 0;
+
+#  ifdef PNG_WRITE_SUPPORTED
+      if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
+#  endif
+   {
+#     ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+         return png_ptr->IDAT_read_size;
+#     else
+         return PNG_IDAT_READ_SIZE;
+#     endif
+   }
+
+#  ifdef PNG_WRITE_SUPPORTED
+      else
+         return png_ptr->zbuffer_size;
+#  endif
+}
+
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+/* These functions were added to libpng 1.2.6 and were enabled
+ * by default in libpng-1.4.0 */
+png_uint_32 PNGAPI
+png_get_user_width_max (png_const_structrp png_ptr)
+{
+   return (png_ptr ? png_ptr->user_width_max : 0);
+}
+
+png_uint_32 PNGAPI
+png_get_user_height_max (png_const_structrp png_ptr)
+{
+   return (png_ptr ? png_ptr->user_height_max : 0);
+}
+
+/* This function was added to libpng 1.4.0 */
+png_uint_32 PNGAPI
+png_get_chunk_cache_max (png_const_structrp png_ptr)
+{
+   return (png_ptr ? png_ptr->user_chunk_cache_max : 0);
+}
+
+/* This function was added to libpng 1.4.1 */
+png_alloc_size_t PNGAPI
+png_get_chunk_malloc_max (png_const_structrp png_ptr)
+{
+   return (png_ptr ? png_ptr->user_chunk_malloc_max : 0);
+}
+#endif /* SET_USER_LIMITS */
+
+/* These functions were added to libpng 1.4.0 */
+#ifdef PNG_IO_STATE_SUPPORTED
+png_uint_32 PNGAPI
+png_get_io_state (png_const_structrp png_ptr)
+{
+   return png_ptr->io_state;
+}
+
+png_uint_32 PNGAPI
+png_get_io_chunk_type (png_const_structrp png_ptr)
+{
+   return png_ptr->chunk_name;
+}
+#endif /* IO_STATE */
+
+#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
+#  ifdef PNG_GET_PALETTE_MAX_SUPPORTED
+int PNGAPI
+png_get_palette_max(png_const_structp png_ptr, png_const_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+      return png_ptr->num_palette_max;
+
+   return (-1);
+}
+#  endif
+#endif
+
+#endif /* READ || WRITE */
diff --git a/Source/LibPNG/pnginfo.h b/Source/LibPNG/pnginfo.h
index bbfb105..122a90a 100644
--- a/Source/LibPNG/pnginfo.h
+++ b/Source/LibPNG/pnginfo.h
@@ -1,269 +1,260 @@
-
-/* pnginfo.h - header file for PNG reference library
- *
- * Copyright (c) 1998-2011 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- *
- * Last changed in libpng 1.5.0 [January 6, 2011]
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- */
-
- /* png_info is a structure that holds the information in a PNG file so
- * that the application can find out the characteristics of the image.
- * If you are reading the file, this structure will tell you what is
- * in the PNG file.  If you are writing the file, fill in the information
- * you want to put into the PNG file, using png_set_*() functions, then
- * call png_write_info().
- *
- * The names chosen should be very close to the PNG specification, so
- * consult that document for information about the meaning of each field.
- *
- * With libpng < 0.95, it was only possible to directly set and read the
- * the values in the png_info_struct, which meant that the contents and
- * order of the values had to remain fixed.  With libpng 0.95 and later,
- * however, there are now functions that abstract the contents of
- * png_info_struct from the application, so this makes it easier to use
- * libpng with dynamic libraries, and even makes it possible to use
- * libraries that don't have all of the libpng ancillary chunk-handing
- * functionality.  In libpng-1.5.0 this was moved into a separate private
- * file that is not visible to applications.
- *
- * The following members may have allocated storage attached that should be
- * cleaned up before the structure is discarded: palette, trans, text,
- * pcal_purpose, pcal_units, pcal_params, hist, iccp_name, iccp_profile,
- * splt_palettes, scal_unit, row_pointers, and unknowns.   By default, these
- * are automatically freed when the info structure is deallocated, if they were
- * allocated internally by libpng.  This behavior can be changed by means
- * of the png_data_freer() function.
- *
- * More allocation details: all the chunk-reading functions that
- * change these members go through the corresponding png_set_*
- * functions.  A function to clear these members is available: see
- * png_free_data().  The png_set_* functions do not depend on being
- * able to point info structure members to any of the storage they are
- * passed (they make their own copies), EXCEPT that the png_set_text
- * functions use the same storage passed to them in the text_ptr or
- * itxt_ptr structure argument, and the png_set_rows and png_set_unknowns
- * functions do not make their own copies.
- */
-#ifndef PNGINFO_H
-#define PNGINFO_H
-
-struct png_info_def
-{
-   /* the following are necessary for every PNG file */
-   png_uint_32 width;  /* width of image in pixels (from IHDR) */
-   png_uint_32 height; /* height of image in pixels (from IHDR) */
-   png_uint_32 valid;  /* valid chunk data (see PNG_INFO_ below) */
-   png_size_t rowbytes; /* bytes needed to hold an untransformed row */
-   png_colorp palette;      /* array of color values (valid & PNG_INFO_PLTE) */
-   png_uint_16 num_palette; /* number of color entries in "palette" (PLTE) */
-   png_uint_16 num_trans;   /* number of transparent palette color (tRNS) */
-   png_byte bit_depth;      /* 1, 2, 4, 8, or 16 bits/channel (from IHDR) */
-   png_byte color_type;     /* see PNG_COLOR_TYPE_ below (from IHDR) */
-   /* The following three should have been named *_method not *_type */
-   png_byte compression_type; /* must be PNG_COMPRESSION_TYPE_BASE (IHDR) */
-   png_byte filter_type;    /* must be PNG_FILTER_TYPE_BASE (from IHDR) */
-   png_byte interlace_type; /* One of PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
-
-   /* The following is informational only on read, and not used on writes. */
-   png_byte channels;       /* number of data channels per pixel (1, 2, 3, 4) */
-   png_byte pixel_depth;    /* number of bits per pixel */
-   png_byte spare_byte;     /* to align the data, and for future use */
-   png_byte signature[8];   /* magic bytes read by libpng from start of file */
-
-   /* The rest of the data is optional.  If you are reading, check the
-    * valid field to see if the information in these are valid.  If you
-    * are writing, set the valid field to those chunks you want written,
-    * and initialize the appropriate fields below.
-    */
-
-#if defined(PNG_gAMA_SUPPORTED)
-   /* The gAMA chunk describes the gamma characteristics of the system
-    * on which the image was created, normally in the range [1.0, 2.5].
-    * Data is valid if (valid & PNG_INFO_gAMA) is non-zero.
-    */
-   png_fixed_point gamma;
-#endif
-
-#ifdef PNG_sRGB_SUPPORTED
-    /* GR-P, 0.96a */
-    /* Data valid if (valid & PNG_INFO_sRGB) non-zero. */
-   png_byte srgb_intent; /* sRGB rendering intent [0, 1, 2, or 3] */
-#endif
-
-#ifdef PNG_TEXT_SUPPORTED
-   /* The tEXt, and zTXt chunks contain human-readable textual data in
-    * uncompressed, compressed, and optionally compressed forms, respectively.
-    * The data in "text" is an array of pointers to uncompressed,
-    * null-terminated C strings. Each chunk has a keyword that describes the
-    * textual data contained in that chunk.  Keywords are not required to be
-    * unique, and the text string may be empty.  Any number of text chunks may
-    * be in an image.
-    */
-   int num_text; /* number of comments read or comments to write */
-   int max_text; /* current size of text array */
-   png_textp text; /* array of comments read or comments to write */
-#endif /* PNG_TEXT_SUPPORTED */
-
-#ifdef PNG_tIME_SUPPORTED
-   /* The tIME chunk holds the last time the displayed image data was
-    * modified.  See the png_time struct for the contents of this struct.
-    */
-   png_time mod_time;
-#endif
-
-#ifdef PNG_sBIT_SUPPORTED
-   /* The sBIT chunk specifies the number of significant high-order bits
-    * in the pixel data.  Values are in the range [1, bit_depth], and are
-    * only specified for the channels in the pixel data.  The contents of
-    * the low-order bits is not specified.  Data is valid if
-    * (valid & PNG_INFO_sBIT) is non-zero.
-    */
-   png_color_8 sig_bit; /* significant bits in color channels */
-#endif
-
-#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_EXPAND_SUPPORTED) || \
-defined(PNG_READ_BACKGROUND_SUPPORTED)
-   /* The tRNS chunk supplies transparency data for paletted images and
-    * other image types that don't need a full alpha channel.  There are
-    * "num_trans" transparency values for a paletted image, stored in the
-    * same order as the palette colors, starting from index 0.  Values
-    * for the data are in the range [0, 255], ranging from fully transparent
-    * to fully opaque, respectively.  For non-paletted images, there is a
-    * single color specified that should be treated as fully transparent.
-    * Data is valid if (valid & PNG_INFO_tRNS) is non-zero.
-    */
-   png_bytep trans_alpha;    /* alpha values for paletted image */
-   png_color_16 trans_color; /* transparent color for non-palette image */
-#endif
-
-#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
-   /* The bKGD chunk gives the suggested image background color if the
-    * display program does not have its own background color and the image
-    * is needs to composited onto a background before display.  The colors
-    * in "background" are normally in the same color space/depth as the
-    * pixel data.  Data is valid if (valid & PNG_INFO_bKGD) is non-zero.
-    */
-   png_color_16 background;
-#endif
-
-#ifdef PNG_oFFs_SUPPORTED
-   /* The oFFs chunk gives the offset in "offset_unit_type" units rightwards
-    * and downwards from the top-left corner of the display, page, or other
-    * application-specific co-ordinate space.  See the PNG_OFFSET_ defines
-    * below for the unit types.  Valid if (valid & PNG_INFO_oFFs) non-zero.
-    */
-   png_int_32 x_offset; /* x offset on page */
-   png_int_32 y_offset; /* y offset on page */
-   png_byte offset_unit_type; /* offset units type */
-#endif
-
-#ifdef PNG_pHYs_SUPPORTED
-   /* The pHYs chunk gives the physical pixel density of the image for
-    * display or printing in "phys_unit_type" units (see PNG_RESOLUTION_
-    * defines below).  Data is valid if (valid & PNG_INFO_pHYs) is non-zero.
-    */
-   png_uint_32 x_pixels_per_unit; /* horizontal pixel density */
-   png_uint_32 y_pixels_per_unit; /* vertical pixel density */
-   png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */
-#endif
-
-#ifdef PNG_hIST_SUPPORTED
-   /* The hIST chunk contains the relative frequency or importance of the
-    * various palette entries, so that a viewer can intelligently select a
-    * reduced-color palette, if required.  Data is an array of "num_palette"
-    * values in the range [0,65535]. Data valid if (valid & PNG_INFO_hIST)
-    * is non-zero.
-    */
-   png_uint_16p hist;
-#endif
-
-#ifdef PNG_cHRM_SUPPORTED
-   /* The cHRM chunk describes the CIE color characteristics of the monitor
-    * on which the PNG was created.  This data allows the viewer to do gamut
-    * mapping of the input image to ensure that the viewer sees the same
-    * colors in the image as the creator.  Values are in the range
-    * [0.0, 0.8].  Data valid if (valid & PNG_INFO_cHRM) non-zero.
-    */
-   png_fixed_point x_white;
-   png_fixed_point y_white;
-   png_fixed_point x_red;
-   png_fixed_point y_red;
-   png_fixed_point x_green;
-   png_fixed_point y_green;
-   png_fixed_point x_blue;
-   png_fixed_point y_blue;
-#endif
-
-#ifdef PNG_pCAL_SUPPORTED
-   /* The pCAL chunk describes a transformation between the stored pixel
-    * values and original physical data values used to create the image.
-    * The integer range [0, 2^bit_depth - 1] maps to the floating-point
-    * range given by [pcal_X0, pcal_X1], and are further transformed by a
-    * (possibly non-linear) transformation function given by "pcal_type"
-    * and "pcal_params" into "pcal_units".  Please see the PNG_EQUATION_
-    * defines below, and the PNG-Group's PNG extensions document for a
-    * complete description of the transformations and how they should be
-    * implemented, and for a description of the ASCII parameter strings.
-    * Data values are valid if (valid & PNG_INFO_pCAL) non-zero.
-    */
-   png_charp pcal_purpose;  /* pCAL chunk description string */
-   png_int_32 pcal_X0;      /* minimum value */
-   png_int_32 pcal_X1;      /* maximum value */
-   png_charp pcal_units;    /* Latin-1 string giving physical units */
-   png_charpp pcal_params;  /* ASCII strings containing parameter values */
-   png_byte pcal_type;      /* equation type (see PNG_EQUATION_ below) */
-   png_byte pcal_nparams;   /* number of parameters given in pcal_params */
-#endif
-
-/* New members added in libpng-1.0.6 */
-   png_uint_32 free_me;     /* flags items libpng is responsible for freeing */
-
-#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) || \
- defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED)
-   /* Storage for unknown chunks that the library doesn't recognize. */
-   png_unknown_chunkp unknown_chunks;
-   int unknown_chunks_num;
-#endif
-
-#ifdef PNG_iCCP_SUPPORTED
-   /* iCCP chunk data. */
-   png_charp iccp_name;     /* profile name */
-   png_bytep iccp_profile;  /* International Color Consortium profile data */
-   png_uint_32 iccp_proflen;  /* ICC profile data length */
-   png_byte iccp_compression; /* Always zero */
-#endif
-
-#ifdef PNG_sPLT_SUPPORTED
-   /* Data on sPLT chunks (there may be more than one). */
-   png_sPLT_tp splt_palettes;
-   png_uint_32 splt_palettes_num;
-#endif
-
-#ifdef PNG_sCAL_SUPPORTED
-   /* The sCAL chunk describes the actual physical dimensions of the
-    * subject matter of the graphic.  The chunk contains a unit specification
-    * a byte value, and two ASCII strings representing floating-point
-    * values.  The values are width and height corresponsing to one pixel
-    * in the image.  Data values are valid if (valid & PNG_INFO_sCAL) is
-    * non-zero.
-    */
-   png_byte scal_unit;         /* unit of physical scale */
-   png_charp scal_s_width;     /* string containing height */
-   png_charp scal_s_height;    /* string containing width */
-#endif
-
-#ifdef PNG_INFO_IMAGE_SUPPORTED
-   /* Memory has been allocated if (valid & PNG_ALLOCATED_INFO_ROWS)
-      non-zero */
-   /* Data valid if (valid & PNG_INFO_IDAT) non-zero */
-   png_bytepp row_pointers;        /* the image bits */
-#endif
-
-};
-#endif /* PNGINFO_H */
+
+/* pnginfo.h - header file for PNG reference library
+ *
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * Last changed in libpng 1.6.1 [March 28, 2013]
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+ /* png_info is a structure that holds the information in a PNG file so
+ * that the application can find out the characteristics of the image.
+ * If you are reading the file, this structure will tell you what is
+ * in the PNG file.  If you are writing the file, fill in the information
+ * you want to put into the PNG file, using png_set_*() functions, then
+ * call png_write_info().
+ *
+ * The names chosen should be very close to the PNG specification, so
+ * consult that document for information about the meaning of each field.
+ *
+ * With libpng < 0.95, it was only possible to directly set and read the
+ * the values in the png_info_struct, which meant that the contents and
+ * order of the values had to remain fixed.  With libpng 0.95 and later,
+ * however, there are now functions that abstract the contents of
+ * png_info_struct from the application, so this makes it easier to use
+ * libpng with dynamic libraries, and even makes it possible to use
+ * libraries that don't have all of the libpng ancillary chunk-handing
+ * functionality.  In libpng-1.5.0 this was moved into a separate private
+ * file that is not visible to applications.
+ *
+ * The following members may have allocated storage attached that should be
+ * cleaned up before the structure is discarded: palette, trans, text,
+ * pcal_purpose, pcal_units, pcal_params, hist, iccp_name, iccp_profile,
+ * splt_palettes, scal_unit, row_pointers, and unknowns.   By default, these
+ * are automatically freed when the info structure is deallocated, if they were
+ * allocated internally by libpng.  This behavior can be changed by means
+ * of the png_data_freer() function.
+ *
+ * More allocation details: all the chunk-reading functions that
+ * change these members go through the corresponding png_set_*
+ * functions.  A function to clear these members is available: see
+ * png_free_data().  The png_set_* functions do not depend on being
+ * able to point info structure members to any of the storage they are
+ * passed (they make their own copies), EXCEPT that the png_set_text
+ * functions use the same storage passed to them in the text_ptr or
+ * itxt_ptr structure argument, and the png_set_rows and png_set_unknowns
+ * functions do not make their own copies.
+ */
+#ifndef PNGINFO_H
+#define PNGINFO_H
+
+struct png_info_def
+{
+   /* The following are necessary for every PNG file */
+   png_uint_32 width;  /* width of image in pixels (from IHDR) */
+   png_uint_32 height; /* height of image in pixels (from IHDR) */
+   png_uint_32 valid;  /* valid chunk data (see PNG_INFO_ below) */
+   png_size_t rowbytes; /* bytes needed to hold an untransformed row */
+   png_colorp palette;      /* array of color values (valid & PNG_INFO_PLTE) */
+   png_uint_16 num_palette; /* number of color entries in "palette" (PLTE) */
+   png_uint_16 num_trans;   /* number of transparent palette color (tRNS) */
+   png_byte bit_depth;      /* 1, 2, 4, 8, or 16 bits/channel (from IHDR) */
+   png_byte color_type;     /* see PNG_COLOR_TYPE_ below (from IHDR) */
+   /* The following three should have been named *_method not *_type */
+   png_byte compression_type; /* must be PNG_COMPRESSION_TYPE_BASE (IHDR) */
+   png_byte filter_type;    /* must be PNG_FILTER_TYPE_BASE (from IHDR) */
+   png_byte interlace_type; /* One of PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
+
+   /* The following are set by png_set_IHDR, called from the application on
+    * write, but the are never actually used by the write code.
+    */
+   png_byte channels;       /* number of data channels per pixel (1, 2, 3, 4) */
+   png_byte pixel_depth;    /* number of bits per pixel */
+   png_byte spare_byte;     /* to align the data, and for future use */
+
+#ifdef PNG_READ_SUPPORTED
+   /* This is never set during write */
+   png_byte signature[8];   /* magic bytes read by libpng from start of file */
+#endif
+
+   /* The rest of the data is optional.  If you are reading, check the
+    * valid field to see if the information in these are valid.  If you
+    * are writing, set the valid field to those chunks you want written,
+    * and initialize the appropriate fields below.
+    */
+
+#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED)
+   /* png_colorspace only contains 'flags' if neither GAMMA or COLORSPACE are
+    * defined.  When COLORSPACE is switched on all the colorspace-defining
+    * chunks should be enabled, when GAMMA is switched on all the gamma-defining
+    * chunks should be enabled.  If this is not done it becomes possible to read
+    * inconsistent PNG files and assign a probably incorrect interpretation to
+    * the information.  (In other words, by carefully choosing which chunks to
+    * recognize the system configuration can select an interpretation for PNG
+    * files containing ambiguous data and this will result in inconsistent
+    * behavior between different libpng builds!)
+    */
+   png_colorspace colorspace;
+#endif
+
+#ifdef PNG_iCCP_SUPPORTED
+   /* iCCP chunk data. */
+   png_charp iccp_name;     /* profile name */
+   png_bytep iccp_profile;  /* International Color Consortium profile data */
+   png_uint_32 iccp_proflen;  /* ICC profile data length */
+#endif
+
+#ifdef PNG_TEXT_SUPPORTED
+   /* The tEXt, and zTXt chunks contain human-readable textual data in
+    * uncompressed, compressed, and optionally compressed forms, respectively.
+    * The data in "text" is an array of pointers to uncompressed,
+    * null-terminated C strings. Each chunk has a keyword that describes the
+    * textual data contained in that chunk.  Keywords are not required to be
+    * unique, and the text string may be empty.  Any number of text chunks may
+    * be in an image.
+    */
+   int num_text; /* number of comments read or comments to write */
+   int max_text; /* current size of text array */
+   png_textp text; /* array of comments read or comments to write */
+#endif /* TEXT */
+
+#ifdef PNG_tIME_SUPPORTED
+   /* The tIME chunk holds the last time the displayed image data was
+    * modified.  See the png_time struct for the contents of this struct.
+    */
+   png_time mod_time;
+#endif
+
+#ifdef PNG_sBIT_SUPPORTED
+   /* The sBIT chunk specifies the number of significant high-order bits
+    * in the pixel data.  Values are in the range [1, bit_depth], and are
+    * only specified for the channels in the pixel data.  The contents of
+    * the low-order bits is not specified.  Data is valid if
+    * (valid & PNG_INFO_sBIT) is non-zero.
+    */
+   png_color_8 sig_bit; /* significant bits in color channels */
+#endif
+
+#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_EXPAND_SUPPORTED) || \
+defined(PNG_READ_BACKGROUND_SUPPORTED)
+   /* The tRNS chunk supplies transparency data for paletted images and
+    * other image types that don't need a full alpha channel.  There are
+    * "num_trans" transparency values for a paletted image, stored in the
+    * same order as the palette colors, starting from index 0.  Values
+    * for the data are in the range [0, 255], ranging from fully transparent
+    * to fully opaque, respectively.  For non-paletted images, there is a
+    * single color specified that should be treated as fully transparent.
+    * Data is valid if (valid & PNG_INFO_tRNS) is non-zero.
+    */
+   png_bytep trans_alpha;    /* alpha values for paletted image */
+   png_color_16 trans_color; /* transparent color for non-palette image */
+#endif
+
+#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+   /* The bKGD chunk gives the suggested image background color if the
+    * display program does not have its own background color and the image
+    * is needs to composited onto a background before display.  The colors
+    * in "background" are normally in the same color space/depth as the
+    * pixel data.  Data is valid if (valid & PNG_INFO_bKGD) is non-zero.
+    */
+   png_color_16 background;
+#endif
+
+#ifdef PNG_oFFs_SUPPORTED
+   /* The oFFs chunk gives the offset in "offset_unit_type" units rightwards
+    * and downwards from the top-left corner of the display, page, or other
+    * application-specific co-ordinate space.  See the PNG_OFFSET_ defines
+    * below for the unit types.  Valid if (valid & PNG_INFO_oFFs) non-zero.
+    */
+   png_int_32 x_offset; /* x offset on page */
+   png_int_32 y_offset; /* y offset on page */
+   png_byte offset_unit_type; /* offset units type */
+#endif
+
+#ifdef PNG_pHYs_SUPPORTED
+   /* The pHYs chunk gives the physical pixel density of the image for
+    * display or printing in "phys_unit_type" units (see PNG_RESOLUTION_
+    * defines below).  Data is valid if (valid & PNG_INFO_pHYs) is non-zero.
+    */
+   png_uint_32 x_pixels_per_unit; /* horizontal pixel density */
+   png_uint_32 y_pixels_per_unit; /* vertical pixel density */
+   png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */
+#endif
+
+#ifdef PNG_hIST_SUPPORTED
+   /* The hIST chunk contains the relative frequency or importance of the
+    * various palette entries, so that a viewer can intelligently select a
+    * reduced-color palette, if required.  Data is an array of "num_palette"
+    * values in the range [0,65535]. Data valid if (valid & PNG_INFO_hIST)
+    * is non-zero.
+    */
+   png_uint_16p hist;
+#endif
+
+#ifdef PNG_pCAL_SUPPORTED
+   /* The pCAL chunk describes a transformation between the stored pixel
+    * values and original physical data values used to create the image.
+    * The integer range [0, 2^bit_depth - 1] maps to the floating-point
+    * range given by [pcal_X0, pcal_X1], and are further transformed by a
+    * (possibly non-linear) transformation function given by "pcal_type"
+    * and "pcal_params" into "pcal_units".  Please see the PNG_EQUATION_
+    * defines below, and the PNG-Group's PNG extensions document for a
+    * complete description of the transformations and how they should be
+    * implemented, and for a description of the ASCII parameter strings.
+    * Data values are valid if (valid & PNG_INFO_pCAL) non-zero.
+    */
+   png_charp pcal_purpose;  /* pCAL chunk description string */
+   png_int_32 pcal_X0;      /* minimum value */
+   png_int_32 pcal_X1;      /* maximum value */
+   png_charp pcal_units;    /* Latin-1 string giving physical units */
+   png_charpp pcal_params;  /* ASCII strings containing parameter values */
+   png_byte pcal_type;      /* equation type (see PNG_EQUATION_ below) */
+   png_byte pcal_nparams;   /* number of parameters given in pcal_params */
+#endif
+
+/* New members added in libpng-1.0.6 */
+   png_uint_32 free_me;     /* flags items libpng is responsible for freeing */
+
+#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
+   /* Storage for unknown chunks that the library doesn't recognize. */
+   png_unknown_chunkp unknown_chunks;
+
+   /* The type of this field is limited by the type of 
+    * png_struct::user_chunk_cache_max, else overflow can occur.
+    */
+   int                unknown_chunks_num;
+#endif
+
+#ifdef PNG_sPLT_SUPPORTED
+   /* Data on sPLT chunks (there may be more than one). */
+   png_sPLT_tp splt_palettes;
+   int         splt_palettes_num; /* Match type returned by png_get API */
+#endif
+
+#ifdef PNG_sCAL_SUPPORTED
+   /* The sCAL chunk describes the actual physical dimensions of the
+    * subject matter of the graphic.  The chunk contains a unit specification
+    * a byte value, and two ASCII strings representing floating-point
+    * values.  The values are width and height corresponsing to one pixel
+    * in the image.  Data values are valid if (valid & PNG_INFO_sCAL) is
+    * non-zero.
+    */
+   png_byte scal_unit;         /* unit of physical scale */
+   png_charp scal_s_width;     /* string containing height */
+   png_charp scal_s_height;    /* string containing width */
+#endif
+
+#ifdef PNG_INFO_IMAGE_SUPPORTED
+   /* Memory has been allocated if (valid & PNG_ALLOCATED_INFO_ROWS)
+      non-zero */
+   /* Data valid if (valid & PNG_INFO_IDAT) non-zero */
+   png_bytepp row_pointers;        /* the image bits */
+#endif
+
+};
+#endif /* PNGINFO_H */
diff --git a/Source/LibPNG/pnglibconf.h b/Source/LibPNG/pnglibconf.h
index 8022a5a..5d65405 100644
--- a/Source/LibPNG/pnglibconf.h
+++ b/Source/LibPNG/pnglibconf.h
@@ -1,51 +1,31 @@
-
-/* libpng STANDARD API DEFINITION */
+/* libpng 1.6.12 STANDARD API DEFINITION */
 
 /* pnglibconf.h - library build configuration */
 
-/* libpng version 1.5.4 - last changed on June 22, 2011 */
+/* Libpng version 1.6.12 - June 12, 2014 */
 
-/* Copyright (c) 1998-2011 Glenn Randers-Pehrson */
+/* Copyright (c) 1998-2014 Glenn Randers-Pehrson */
 
 /* This code is released under the libpng license. */
 /* For conditions of distribution and use, see the disclaimer */
 /* and license in png.h */
 
 /* pnglibconf.h */
+/* Machine generated file: DO NOT EDIT */
 /* Derived from: scripts/pnglibconf.dfa */
-/* If you edit this file by hand you must obey the rules expressed in */
-/* pnglibconf.dfa with respect to the dependencies between the following */
-/* symbols.  It is much better to generate a new file using */
-/* scripts/libpngconf.mak */
-
 #ifndef PNGLCONF_H
 #define PNGLCONF_H
-/* settings */
-#define PNG_API_RULE 0
-#define PNG_CALLOC_SUPPORTED
-#define PNG_COST_SHIFT 3
-#define PNG_DEFAULT_READ_MACROS 1
-#define PNG_GAMMA_THRESHOLD_FIXED 5000
-#define PNG_MAX_GAMMA_8 11
-#define PNG_QUANTIZE_BLUE_BITS 5
-#define PNG_QUANTIZE_GREEN_BITS 5
-#define PNG_QUANTIZE_RED_BITS 5
-#define PNG_sCAL_PRECISION 5
-#define PNG_USER_CHUNK_CACHE_MAX 0
-#define PNG_USER_CHUNK_MALLOC_MAX 0
-#define PNG_USER_HEIGHT_MAX 1000000
-#define PNG_USER_WIDTH_MAX 1000000
-#define PNG_WEIGHT_SHIFT 8
-#define PNG_ZBUF_SIZE 8192
-/* end of settings */
 /* options */
 #define PNG_16BIT_SUPPORTED
-#define PNG_ALIGN_MEMORY_SUPPORTED
+#define PNG_ALIGNED_MEMORY_SUPPORTED
+/*#undef PNG_ARM_NEON_API_SUPPORTED*/
+/*#undef PNG_ARM_NEON_CHECK_SUPPORTED*/
 #define PNG_BENIGN_ERRORS_SUPPORTED
-#define PNG_bKGD_SUPPORTED
+#define PNG_BENIGN_READ_ERRORS_SUPPORTED
+/*#undef PNG_BENIGN_WRITE_ERRORS_SUPPORTED*/
 #define PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED
-#define PNG_CHECK_cHRM_SUPPORTED
-#define PNG_cHRM_SUPPORTED
+#define PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
+#define PNG_COLORSPACE_SUPPORTED
 #define PNG_CONSOLE_IO_SUPPORTED
 #define PNG_CONVERT_tIME_SUPPORTED
 #define PNG_EASY_ACCESS_SUPPORTED
@@ -54,18 +34,15 @@
 #define PNG_FIXED_POINT_SUPPORTED
 #define PNG_FLOATING_ARITHMETIC_SUPPORTED
 #define PNG_FLOATING_POINT_SUPPORTED
-#define PNG_gAMA_SUPPORTED
+#define PNG_FORMAT_AFIRST_SUPPORTED
+#define PNG_FORMAT_BGR_SUPPORTED
+#define PNG_GAMMA_SUPPORTED
+#define PNG_GET_PALETTE_MAX_SUPPORTED
 #define PNG_HANDLE_AS_UNKNOWN_SUPPORTED
-#define PNG_hIST_SUPPORTED
-#define PNG_iCCP_SUPPORTED
 #define PNG_INCH_CONVERSIONS_SUPPORTED
 #define PNG_INFO_IMAGE_SUPPORTED
 #define PNG_IO_STATE_SUPPORTED
-#define PNG_iTXt_SUPPORTED
 #define PNG_MNG_FEATURES_SUPPORTED
-#define PNG_oFFs_SUPPORTED
-#define PNG_pCAL_SUPPORTED
-#define PNG_pHYs_SUPPORTED
 #define PNG_POINTER_INDEXING_SUPPORTED
 #define PNG_PROGRESSIVE_READ_SUPPORTED
 #define PNG_READ_16BIT_SUPPORTED
@@ -73,67 +50,73 @@
 #define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED
 #define PNG_READ_BACKGROUND_SUPPORTED
 #define PNG_READ_BGR_SUPPORTED
-#define PNG_READ_bKGD_SUPPORTED
-#define PNG_READ_cHRM_SUPPORTED
+#define PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
 #define PNG_READ_COMPOSITE_NODIV_SUPPORTED
 #define PNG_READ_COMPRESSED_TEXT_SUPPORTED
 #define PNG_READ_EXPAND_16_SUPPORTED
 #define PNG_READ_EXPAND_SUPPORTED
 #define PNG_READ_FILLER_SUPPORTED
-#define PNG_READ_gAMA_SUPPORTED
 #define PNG_READ_GAMMA_SUPPORTED
+#define PNG_READ_GET_PALETTE_MAX_SUPPORTED
 #define PNG_READ_GRAY_TO_RGB_SUPPORTED
-#define PNG_READ_hIST_SUPPORTED
-#define PNG_READ_iCCP_SUPPORTED
 #define PNG_READ_INTERLACING_SUPPORTED
 #define PNG_READ_INT_FUNCTIONS_SUPPORTED
 #define PNG_READ_INVERT_ALPHA_SUPPORTED
 #define PNG_READ_INVERT_SUPPORTED
-#define PNG_READ_iTXt_SUPPORTED
-#define PNG_READ_oFFs_SUPPORTED
 #define PNG_READ_OPT_PLTE_SUPPORTED
-#define PNG_READ_PACK_SUPPORTED
 #define PNG_READ_PACKSWAP_SUPPORTED
-#define PNG_READ_pCAL_SUPPORTED
-#define PNG_READ_pHYs_SUPPORTED
+#define PNG_READ_PACK_SUPPORTED
 #define PNG_READ_QUANTIZE_SUPPORTED
 #define PNG_READ_RGB_TO_GRAY_SUPPORTED
-#define PNG_READ_sBIT_SUPPORTED
 #define PNG_READ_SCALE_16_TO_8_SUPPORTED
-#define PNG_READ_sCAL_SUPPORTED
 #define PNG_READ_SHIFT_SUPPORTED
-#define PNG_READ_sPLT_SUPPORTED
-#define PNG_READ_sRGB_SUPPORTED
 #define PNG_READ_STRIP_16_TO_8_SUPPORTED
 #define PNG_READ_STRIP_ALPHA_SUPPORTED
 #define PNG_READ_SUPPORTED
 #define PNG_READ_SWAP_ALPHA_SUPPORTED
 #define PNG_READ_SWAP_SUPPORTED
-#define PNG_READ_tEXt_SUPPORTED
 #define PNG_READ_TEXT_SUPPORTED
-#define PNG_READ_tIME_SUPPORTED
 #define PNG_READ_TRANSFORMS_SUPPORTED
-#define PNG_READ_tRNS_SUPPORTED
 #define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
 #define PNG_READ_USER_CHUNKS_SUPPORTED
 #define PNG_READ_USER_TRANSFORM_SUPPORTED
+#define PNG_READ_bKGD_SUPPORTED
+#define PNG_READ_cHRM_SUPPORTED
+#define PNG_READ_gAMA_SUPPORTED
+#define PNG_READ_hIST_SUPPORTED
+#define PNG_READ_iCCP_SUPPORTED
+#define PNG_READ_iTXt_SUPPORTED
+#define PNG_READ_oFFs_SUPPORTED
+#define PNG_READ_pCAL_SUPPORTED
+#define PNG_READ_pHYs_SUPPORTED
+#define PNG_READ_sBIT_SUPPORTED
+#define PNG_READ_sCAL_SUPPORTED
+#define PNG_READ_sPLT_SUPPORTED
+#define PNG_READ_sRGB_SUPPORTED
+#define PNG_READ_tEXt_SUPPORTED
+#define PNG_READ_tIME_SUPPORTED
+#define PNG_READ_tRNS_SUPPORTED
 #define PNG_READ_zTXt_SUPPORTED
+/*#undef PNG_SAFE_LIMITS_SUPPORTED*/
 #define PNG_SAVE_INT_32_SUPPORTED
-#define PNG_sBIT_SUPPORTED
-#define PNG_sCAL_SUPPORTED
+#define PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED
 #define PNG_SEQUENTIAL_READ_SUPPORTED
+#define PNG_SETJMP_SUPPORTED
 #define PNG_SET_CHUNK_CACHE_LIMIT_SUPPORTED
 #define PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED
-#define PNG_SETJMP_SUPPORTED
+#define PNG_SET_OPTION_SUPPORTED
+#define PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
 #define PNG_SET_USER_LIMITS_SUPPORTED
-#define PNG_sPLT_SUPPORTED
-#define PNG_sRGB_SUPPORTED
+#define PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED
+#define PNG_SIMPLIFIED_READ_BGR_SUPPORTED
+#define PNG_SIMPLIFIED_READ_SUPPORTED
+#define PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
+#define PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED
+#define PNG_SIMPLIFIED_WRITE_SUPPORTED
 #define PNG_STDIO_SUPPORTED
-#define PNG_tEXt_SUPPORTED
+#define PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
 #define PNG_TEXT_SUPPORTED
 #define PNG_TIME_RFC1123_SUPPORTED
-#define PNG_tIME_SUPPORTED
-#define PNG_tRNS_SUPPORTED
 #define PNG_UNKNOWN_CHUNKS_SUPPORTED
 #define PNG_USER_CHUNKS_SUPPORTED
 #define PNG_USER_LIMITS_SUPPORTED
@@ -144,44 +127,92 @@
 #define PNG_WRITE_16BIT_SUPPORTED
 #define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED
 #define PNG_WRITE_BGR_SUPPORTED
-#define PNG_WRITE_bKGD_SUPPORTED
-#define PNG_WRITE_cHRM_SUPPORTED
+#define PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
 #define PNG_WRITE_COMPRESSED_TEXT_SUPPORTED
 #define PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
 #define PNG_WRITE_FILLER_SUPPORTED
 #define PNG_WRITE_FILTER_SUPPORTED
 #define PNG_WRITE_FLUSH_SUPPORTED
-#define PNG_WRITE_gAMA_SUPPORTED
-#define PNG_WRITE_hIST_SUPPORTED
-#define PNG_WRITE_iCCP_SUPPORTED
+#define PNG_WRITE_GET_PALETTE_MAX_SUPPORTED
 #define PNG_WRITE_INTERLACING_SUPPORTED
 #define PNG_WRITE_INT_FUNCTIONS_SUPPORTED
 #define PNG_WRITE_INVERT_ALPHA_SUPPORTED
 #define PNG_WRITE_INVERT_SUPPORTED
-#define PNG_WRITE_iTXt_SUPPORTED
-#define PNG_WRITE_oFFs_SUPPORTED
 #define PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
-#define PNG_WRITE_PACK_SUPPORTED
 #define PNG_WRITE_PACKSWAP_SUPPORTED
-#define PNG_WRITE_pCAL_SUPPORTED
-#define PNG_WRITE_pHYs_SUPPORTED
-#define PNG_WRITE_sBIT_SUPPORTED
-#define PNG_WRITE_sCAL_SUPPORTED
+#define PNG_WRITE_PACK_SUPPORTED
 #define PNG_WRITE_SHIFT_SUPPORTED
-#define PNG_WRITE_sPLT_SUPPORTED
-#define PNG_WRITE_sRGB_SUPPORTED
 #define PNG_WRITE_SUPPORTED
 #define PNG_WRITE_SWAP_ALPHA_SUPPORTED
 #define PNG_WRITE_SWAP_SUPPORTED
-#define PNG_WRITE_tEXt_SUPPORTED
 #define PNG_WRITE_TEXT_SUPPORTED
-#define PNG_WRITE_tIME_SUPPORTED
 #define PNG_WRITE_TRANSFORMS_SUPPORTED
-#define PNG_WRITE_tRNS_SUPPORTED
 #define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
 #define PNG_WRITE_USER_TRANSFORM_SUPPORTED
 #define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+#define PNG_WRITE_bKGD_SUPPORTED
+#define PNG_WRITE_cHRM_SUPPORTED
+#define PNG_WRITE_gAMA_SUPPORTED
+#define PNG_WRITE_hIST_SUPPORTED
+#define PNG_WRITE_iCCP_SUPPORTED
+#define PNG_WRITE_iTXt_SUPPORTED
+#define PNG_WRITE_oFFs_SUPPORTED
+#define PNG_WRITE_pCAL_SUPPORTED
+#define PNG_WRITE_pHYs_SUPPORTED
+#define PNG_WRITE_sBIT_SUPPORTED
+#define PNG_WRITE_sCAL_SUPPORTED
+#define PNG_WRITE_sPLT_SUPPORTED
+#define PNG_WRITE_sRGB_SUPPORTED
+#define PNG_WRITE_tEXt_SUPPORTED
+#define PNG_WRITE_tIME_SUPPORTED
+#define PNG_WRITE_tRNS_SUPPORTED
 #define PNG_WRITE_zTXt_SUPPORTED
+#define PNG_bKGD_SUPPORTED
+#define PNG_cHRM_SUPPORTED
+#define PNG_gAMA_SUPPORTED
+#define PNG_hIST_SUPPORTED
+#define PNG_iCCP_SUPPORTED
+#define PNG_iTXt_SUPPORTED
+#define PNG_oFFs_SUPPORTED
+#define PNG_pCAL_SUPPORTED
+#define PNG_pHYs_SUPPORTED
+#define PNG_sBIT_SUPPORTED
+#define PNG_sCAL_SUPPORTED
+#define PNG_sPLT_SUPPORTED
+#define PNG_sRGB_SUPPORTED
+#define PNG_tEXt_SUPPORTED
+#define PNG_tIME_SUPPORTED
+#define PNG_tRNS_SUPPORTED
 #define PNG_zTXt_SUPPORTED
 /* end of options */
+/* settings */
+#define PNG_API_RULE 0
+#define PNG_COST_SHIFT 3
+#define PNG_DEFAULT_READ_MACROS 1
+#define PNG_GAMMA_THRESHOLD_FIXED 5000
+#define PNG_IDAT_READ_SIZE PNG_ZBUF_SIZE
+#define PNG_INFLATE_BUF_SIZE 1024
+#define PNG_MAX_GAMMA_8 11
+#define PNG_QUANTIZE_BLUE_BITS 5
+#define PNG_QUANTIZE_GREEN_BITS 5
+#define PNG_QUANTIZE_RED_BITS 5
+#define PNG_TEXT_Z_DEFAULT_COMPRESSION (-1)
+#define PNG_TEXT_Z_DEFAULT_STRATEGY 0
+#define PNG_WEIGHT_SHIFT 8
+#define PNG_ZBUF_SIZE 8192
+#define PNG_ZLIB_VERNUM 0 /* unknown */
+#define PNG_Z_DEFAULT_COMPRESSION (-1)
+#define PNG_Z_DEFAULT_NOFILTER_STRATEGY 0
+#define PNG_Z_DEFAULT_STRATEGY 1
+#define PNG_sCAL_PRECISION 5
+/**
+PNG_sRGB_PROFILE_CHECKS == 0
+   The MD5 is used if available, nothing else is checked.  No warning messages.
+PNG_sRGB_PROFILE_CHECKS == 1
+   The MD5 is checked and if it matches the adler32 (from the zlib stream)is also checked, the profile is regarded as not-sRGB if the check fails.
+PNG_SRGB_PROFILE_CHECKS == 2
+   In addition to the above a full crc32 is also calculated if everything passes.  The profile is only regarded as sRGB if this passes too.
+*/
+#define PNG_sRGB_PROFILE_CHECKS -1
+/* end of settings */
 #endif /* PNGLCONF_H */
diff --git a/Source/LibPNG/pngmem.c b/Source/LibPNG/pngmem.c
index 3099246..d6caf27 100644
--- a/Source/LibPNG/pngmem.c
+++ b/Source/LibPNG/pngmem.c
@@ -1,667 +1,281 @@
-
-/* pngmem.c - stub functions for memory allocation
- *
- * Last changed in libpng 1.5.13 [September 27, 2012]
- * Copyright (c) 1998-2012 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- *
- * This file provides a location for all memory allocation.  Users who
- * need special memory handling are expected to supply replacement
- * functions for png_malloc() and png_free(), and to use
- * png_create_read_struct_2() and png_create_write_struct_2() to
- * identify the replacement functions.
- */
-
-#include "pngpriv.h"
-
-#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
-
-/* Borland DOS special memory handler */
-#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
-/* If you change this, be sure to change the one in png.h also */
-
-/* Allocate memory for a png_struct.  The malloc and memset can be replaced
-   by a single call to calloc() if this is thought to improve performance. */
-PNG_FUNCTION(png_voidp /* PRIVATE */,
-png_create_struct,(int type),PNG_ALLOCATED)
-{
-#  ifdef PNG_USER_MEM_SUPPORTED
-   return (png_create_struct_2(type, NULL, NULL));
-}
-
-/* Alternate version of png_create_struct, for use with user-defined malloc. */
-PNG_FUNCTION(png_voidp /* PRIVATE */,
-png_create_struct_2,(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr),
-   PNG_ALLOCATED)
-{
-#  endif /* PNG_USER_MEM_SUPPORTED */
-   png_size_t size;
-   png_voidp struct_ptr;
-
-   if (type == PNG_STRUCT_INFO)
-      size = png_sizeof(png_info);
-
-   else if (type == PNG_STRUCT_PNG)
-      size = png_sizeof(png_struct);
-
-   else
-      return (png_get_copyright(NULL));
-
-#  ifdef PNG_USER_MEM_SUPPORTED
-   if (malloc_fn != NULL)
-   {
-      png_struct dummy_struct;
-      png_memset(&dummy_struct, 0, sizeof dummy_struct);
-      dummy_struct.mem_ptr=mem_ptr;
-      struct_ptr = (*(malloc_fn))(&dummy_struct, (png_alloc_size_t)size);
-   }
-
-   else
-#  endif /* PNG_USER_MEM_SUPPORTED */
-   struct_ptr = (png_voidp)farmalloc(size);
-   if (struct_ptr != NULL)
-      png_memset(struct_ptr, 0, size);
-
-   return (struct_ptr);
-}
-
-/* Free memory allocated by a png_create_struct() call */
-void /* PRIVATE */
-png_destroy_struct(png_voidp struct_ptr)
-{
-#  ifdef PNG_USER_MEM_SUPPORTED
-   png_destroy_struct_2(struct_ptr, NULL, NULL);
-}
-
-/* Free memory allocated by a png_create_struct() call */
-void /* PRIVATE */
-png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
-    png_voidp mem_ptr)
-{
-#  endif
-   if (struct_ptr != NULL)
-   {
-#  ifdef PNG_USER_MEM_SUPPORTED
-      if (free_fn != NULL)
-      {
-         png_struct dummy_struct;
-         png_memset(&dummy_struct, 0, sizeof dummy_struct);
-         dummy_struct.mem_ptr=mem_ptr;
-         (*(free_fn))(&dummy_struct, struct_ptr);
-         return;
-      }
-
-#  endif /* PNG_USER_MEM_SUPPORTED */
-      farfree (struct_ptr);
-   }
-}
-
-/* Allocate memory.  For reasonable files, size should never exceed
- * 64K.  However, zlib may allocate more then 64K if you don't tell
- * it not to.  See zconf.h and png.h for more information. zlib does
- * need to allocate exactly 64K, so whatever you call here must
- * have the ability to do that.
- *
- * Borland seems to have a problem in DOS mode for exactly 64K.
- * It gives you a segment with an offset of 8 (perhaps to store its
- * memory stuff).  zlib doesn't like this at all, so we have to
- * detect and deal with it.  This code should not be needed in
- * Windows or OS/2 modes, and only in 16 bit mode.  This code has
- * been updated by Alexander Lehmann for version 0.89 to waste less
- * memory.
- *
- * Note that we can't use png_size_t for the "size" declaration,
- * since on some systems a png_size_t is a 16-bit quantity, and as a
- * result, we would be truncating potentially larger memory requests
- * (which should cause a fatal error) and introducing major problems.
- */
-PNG_FUNCTION(png_voidp,PNGAPI
-png_calloc,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
-{
-   png_voidp ret;
-
-   ret = (png_malloc(png_ptr, size));
-
-   if (ret != NULL)
-      png_memset(ret,0,(png_size_t)size);
-
-   return (ret);
-}
-
-PNG_FUNCTION(png_voidp,PNGAPI
-png_malloc,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
-{
-   png_voidp ret;
-
-   if (png_ptr == NULL || size == 0)
-      return (NULL);
-
-#  ifdef PNG_USER_MEM_SUPPORTED
-   if (png_ptr->malloc_fn != NULL)
-      ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, size));
-
-   else
-      ret = (png_malloc_default(png_ptr, size));
-
-   if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
-       png_error(png_ptr, "Out of memory");
-
-   return (ret);
-}
-
-PNG_FUNCTION(png_voidp,PNGAPI
-png_malloc_default,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
-{
-   png_voidp ret;
-#  endif /* PNG_USER_MEM_SUPPORTED */
-
-   if (png_ptr == NULL || size == 0)
-      return (NULL);
-
-#  ifdef PNG_MAX_MALLOC_64K
-   if (size > (png_uint_32)65536L)
-   {
-      png_warning(png_ptr, "Cannot Allocate > 64K");
-      ret = NULL;
-   }
-
-   else
-#  endif
-
-   if (size != (size_t)size)
-      ret = NULL;
-
-   else if (size == (png_uint_32)65536L)
-   {
-      if (png_ptr->offset_table == NULL)
-      {
-         /* Try to see if we need to do any of this fancy stuff */
-         ret = farmalloc(size);
-         if (ret == NULL || ((png_size_t)ret & 0xffff))
-         {
-            int num_blocks;
-            png_uint_32 total_size;
-            png_bytep table;
-            int i, mem_level, window_bits;
-            png_byte huge * hptr;
-            int window_bits
-
-            if (ret != NULL)
-            {
-               farfree(ret);
-               ret = NULL;
-            }
-
-            window_bits =
-                png_ptr->zlib_window_bits >= png_ptr->zlib_text_window_bits ?
-                png_ptr->zlib_window_bits : png_ptr->zlib_text_window_bits;
-
-            if (window_bits > 14)
-               num_blocks = (int)(1 << (window_bits - 14));
-
-            else
-               num_blocks = 1;
-
-            mem_level =
-                png_ptr->zlib_mem_level >= png_ptr->zlib_text_mem_level ?
-                png_ptr->zlib_mem_level : png_ptr->zlib_text_mem_level;
-
-            if (mem_level >= 7)
-               num_blocks += (int)(1 << (mem_level - 7));
-
-            else
-               num_blocks++;
-
-            total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16;
-
-            table = farmalloc(total_size);
-
-            if (table == NULL)
-            {
-#  ifndef PNG_USER_MEM_SUPPORTED
-               if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
-                  png_error(png_ptr, "Out Of Memory"); /* Note "O", "M" */
-
-               else
-                  png_warning(png_ptr, "Out Of Memory");
-#  endif
-               return (NULL);
-            }
-
-            if ((png_size_t)table & 0xfff0)
-            {
-#  ifndef PNG_USER_MEM_SUPPORTED
-               if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
-                  png_error(png_ptr,
-                    "Farmalloc didn't return normalized pointer");
-
-               else
-                  png_warning(png_ptr,
-                    "Farmalloc didn't return normalized pointer");
-#  endif
-               return (NULL);
-            }
-
-            png_ptr->offset_table = table;
-            png_ptr->offset_table_ptr = farmalloc(num_blocks *
-               png_sizeof(png_bytep));
-
-            if (png_ptr->offset_table_ptr == NULL)
-            {
-#  ifndef PNG_USER_MEM_SUPPORTED
-               if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
-                  png_error(png_ptr, "Out Of memory"); /* Note "O", "m" */
-
-               else
-                  png_warning(png_ptr, "Out Of memory");
-#  endif
-               return (NULL);
-            }
-
-            hptr = (png_byte huge *)table;
-            if ((png_size_t)hptr & 0xf)
-            {
-               hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
-               hptr = hptr + 16L;  /* "hptr += 16L" fails on Turbo C++ 3.0 */
-            }
-
-            for (i = 0; i < num_blocks; i++)
-            {
-               png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
-               hptr = hptr + (png_uint_32)65536L;  /* "+=" fails on TC++3.0 */
-            }
-
-            png_ptr->offset_table_number = num_blocks;
-            png_ptr->offset_table_count = 0;
-            png_ptr->offset_table_count_free = 0;
-         }
-      }
-
-      if (png_ptr->offset_table_count >= png_ptr->offset_table_number)
-      {
-#  ifndef PNG_USER_MEM_SUPPORTED
-         if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
-            png_error(png_ptr, "Out of Memory"); /* Note "O" and "M" */
-
-         else
-            png_warning(png_ptr, "Out of Memory");
-#  endif
-         return (NULL);
-      }
-
-      ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++];
-   }
-
-   else
-      ret = farmalloc(size);
-
-#  ifndef PNG_USER_MEM_SUPPORTED
-   if (ret == NULL)
-   {
-      if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
-         png_error(png_ptr, "Out of memory"); /* Note "o" and "m" */
-
-      else
-         png_warning(png_ptr, "Out of memory"); /* Note "o" and "m" */
-   }
-#  endif
-
-   return (ret);
-}
-
-/* Free a pointer allocated by png_malloc().  In the default
- * configuration, png_ptr is not used, but is passed in case it
- * is needed.  If ptr is NULL, return without taking any action.
- */
-void PNGAPI
-png_free(png_structp png_ptr, png_voidp ptr)
-{
-   if (png_ptr == NULL || ptr == NULL)
-      return;
-
-#  ifdef PNG_USER_MEM_SUPPORTED
-   if (png_ptr->free_fn != NULL)
-   {
-      (*(png_ptr->free_fn))(png_ptr, ptr);
-      return;
-   }
-
-   else
-      png_free_default(png_ptr, ptr);
-}
-
-void PNGAPI
-png_free_default(png_structp png_ptr, png_voidp ptr)
-{
-#  endif /* PNG_USER_MEM_SUPPORTED */
-
-   if (png_ptr == NULL || ptr == NULL)
-      return;
-
-   if (png_ptr->offset_table != NULL)
-   {
-      int i;
-
-      for (i = 0; i < png_ptr->offset_table_count; i++)
-      {
-         if (ptr == png_ptr->offset_table_ptr[i])
-         {
-            ptr = NULL;
-            png_ptr->offset_table_count_free++;
-            break;
-         }
-      }
-      if (png_ptr->offset_table_count_free == png_ptr->offset_table_count)
-      {
-         farfree(png_ptr->offset_table);
-         farfree(png_ptr->offset_table_ptr);
-         png_ptr->offset_table = NULL;
-         png_ptr->offset_table_ptr = NULL;
-      }
-   }
-
-   if (ptr != NULL)
-      farfree(ptr);
-}
-
-#else /* Not the Borland DOS special memory handler */
-
-/* Allocate memory for a png_struct or a png_info.  The malloc and
-   memset can be replaced by a single call to calloc() if this is thought
-   to improve performance noticably. */
-PNG_FUNCTION(png_voidp /* PRIVATE */,
-png_create_struct,(int type),PNG_ALLOCATED)
-{
-#  ifdef PNG_USER_MEM_SUPPORTED
-   return (png_create_struct_2(type, NULL, NULL));
-}
-
-/* Allocate memory for a png_struct or a png_info.  The malloc and
-   memset can be replaced by a single call to calloc() if this is thought
-   to improve performance noticably. */
-PNG_FUNCTION(png_voidp /* PRIVATE */,
-png_create_struct_2,(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr),
-   PNG_ALLOCATED)
-{
-#  endif /* PNG_USER_MEM_SUPPORTED */
-   png_size_t size;
-   png_voidp struct_ptr;
-
-   if (type == PNG_STRUCT_INFO)
-      size = png_sizeof(png_info);
-
-   else if (type == PNG_STRUCT_PNG)
-      size = png_sizeof(png_struct);
-
-   else
-      return (NULL);
-
-#  ifdef PNG_USER_MEM_SUPPORTED
-   if (malloc_fn != NULL)
-   {
-      png_struct dummy_struct;
-      png_structp png_ptr = &dummy_struct;
-      png_ptr->mem_ptr=mem_ptr;
-      struct_ptr = (*(malloc_fn))(png_ptr, size);
-
-      if (struct_ptr != NULL)
-         png_memset(struct_ptr, 0, size);
-
-      return (struct_ptr);
-   }
-#  endif /* PNG_USER_MEM_SUPPORTED */
-
-#  if defined(__TURBOC__) && !defined(__FLAT__)
-   struct_ptr = (png_voidp)farmalloc(size);
-#  else
-#    if defined(_MSC_VER) && defined(MAXSEG_64K)
-   struct_ptr = (png_voidp)halloc(size, 1);
-#    else
-   struct_ptr = (png_voidp)malloc(size);
-#    endif
-#  endif
-
-   if (struct_ptr != NULL)
-      png_memset(struct_ptr, 0, size);
-
-   return (struct_ptr);
-}
-
-
-/* Free memory allocated by a png_create_struct() call */
-void /* PRIVATE */
-png_destroy_struct(png_voidp struct_ptr)
-{
-#  ifdef PNG_USER_MEM_SUPPORTED
-   png_destroy_struct_2(struct_ptr, NULL, NULL);
-}
-
-/* Free memory allocated by a png_create_struct() call */
-void /* PRIVATE */
-png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
-    png_voidp mem_ptr)
-{
-#  endif /* PNG_USER_MEM_SUPPORTED */
-   if (struct_ptr != NULL)
-   {
-#  ifdef PNG_USER_MEM_SUPPORTED
-      if (free_fn != NULL)
-      {
-         png_struct dummy_struct;
-         png_structp png_ptr = &dummy_struct;
-         png_ptr->mem_ptr=mem_ptr;
-         (*(free_fn))(png_ptr, struct_ptr);
-         return;
-      }
-#  endif /* PNG_USER_MEM_SUPPORTED */
-#  if defined(__TURBOC__) && !defined(__FLAT__)
-      farfree(struct_ptr);
-
-#  else
-#    if defined(_MSC_VER) && defined(MAXSEG_64K)
-      hfree(struct_ptr);
-
-#    else
-      free(struct_ptr);
-
-#    endif
-#  endif
-   }
-}
-
-/* Allocate memory.  For reasonable files, size should never exceed
- * 64K.  However, zlib may allocate more then 64K if you don't tell
- * it not to.  See zconf.h and png.h for more information.  zlib does
- * need to allocate exactly 64K, so whatever you call here must
- * have the ability to do that.
- */
-
-PNG_FUNCTION(png_voidp,PNGAPI
-png_calloc,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
-{
-   png_voidp ret;
-
-   ret = (png_malloc(png_ptr, size));
-
-   if (ret != NULL)
-      png_memset(ret,0,(png_size_t)size);
-
-   return (ret);
-}
-
-PNG_FUNCTION(png_voidp,PNGAPI
-png_malloc,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
-{
-   png_voidp ret;
-
-#  ifdef PNG_USER_MEM_SUPPORTED
-   if (png_ptr == NULL || size == 0)
-      return (NULL);
-
-   if (png_ptr->malloc_fn != NULL)
-      ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
-
-   else
-      ret = (png_malloc_default(png_ptr, size));
-
-   if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
-       png_error(png_ptr, "Out of Memory");
-
-   return (ret);
-}
-
-PNG_FUNCTION(png_voidp,PNGAPI
-png_malloc_default,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
-{
-   png_voidp ret;
-#  endif /* PNG_USER_MEM_SUPPORTED */
-
-   if (png_ptr == NULL || size == 0)
-      return (NULL);
-
-#  ifdef PNG_MAX_MALLOC_64K
-   if (size > (png_uint_32)65536L)
-   {
-#    ifndef PNG_USER_MEM_SUPPORTED
-      if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
-         png_error(png_ptr, "Cannot Allocate > 64K");
-
-      else
-#    endif
-         return NULL;
-   }
-#  endif
-
-   /* Check for overflow */
-#  if defined(__TURBOC__) && !defined(__FLAT__)
-
-   if (size != (unsigned long)size)
-      ret = NULL;
-
-   else
-      ret = farmalloc(size);
-
-#  else
-#    if defined(_MSC_VER) && defined(MAXSEG_64K)
-   if (size != (unsigned long)size)
-      ret = NULL;
-
-   else
-      ret = halloc(size, 1);
-
-#    else
-   if (size != (size_t)size)
-      ret = NULL;
-
-   else
-      ret = malloc((size_t)size);
-#    endif
-#  endif
-
-#  ifndef PNG_USER_MEM_SUPPORTED
-   if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
-      png_error(png_ptr, "Out of Memory");
-#  endif
-
-   return (ret);
-}
-
-/* Free a pointer allocated by png_malloc().  If ptr is NULL, return
- * without taking any action.
- */
-void PNGAPI
-png_free(png_structp png_ptr, png_voidp ptr)
-{
-   if (png_ptr == NULL || ptr == NULL)
-      return;
-
-#  ifdef PNG_USER_MEM_SUPPORTED
-   if (png_ptr->free_fn != NULL)
-   {
-      (*(png_ptr->free_fn))(png_ptr, ptr);
-      return;
-   }
-
-   else
-      png_free_default(png_ptr, ptr);
-}
-
-void PNGAPI
-png_free_default(png_structp png_ptr, png_voidp ptr)
-{
-   if (png_ptr == NULL || ptr == NULL)
-      return;
-
-#  endif /* PNG_USER_MEM_SUPPORTED */
-
-#  if defined(__TURBOC__) && !defined(__FLAT__)
-   farfree(ptr);
-
-#  else
-#    if defined(_MSC_VER) && defined(MAXSEG_64K)
-   hfree(ptr);
-
-#    else
-   free(ptr);
-
-#    endif
-#  endif
-}
-#endif /* Not Borland DOS special memory handler */
-
-/* This function was added at libpng version 1.2.3.  The png_malloc_warn()
- * function will set up png_malloc() to issue a png_warning and return NULL
- * instead of issuing a png_error, if it fails to allocate the requested
- * memory.
- */
-PNG_FUNCTION(png_voidp,PNGAPI
-png_malloc_warn,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
-{
-   png_voidp ptr;
-   png_uint_32 save_flags;
-   if (png_ptr == NULL)
-      return (NULL);
-
-   save_flags = png_ptr->flags;
-   png_ptr->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK;
-   ptr = (png_voidp)png_malloc((png_structp)png_ptr, size);
-   png_ptr->flags=save_flags;
-   return(ptr);
-}
-
-
-#ifdef PNG_USER_MEM_SUPPORTED
-/* This function is called when the application wants to use another method
- * of allocating and freeing memory.
- */
-void PNGAPI
-png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr
-  malloc_fn, png_free_ptr free_fn)
-{
-   if (png_ptr != NULL)
-   {
-      png_ptr->mem_ptr = mem_ptr;
-      png_ptr->malloc_fn = malloc_fn;
-      png_ptr->free_fn = free_fn;
-   }
-}
-
-/* This function returns a pointer to the mem_ptr associated with the user
- * functions.  The application should free any memory associated with this
- * pointer before png_write_destroy and png_read_destroy are called.
- */
-png_voidp PNGAPI
-png_get_mem_ptr(png_const_structp png_ptr)
-{
-   if (png_ptr == NULL)
-      return (NULL);
-
-   return ((png_voidp)png_ptr->mem_ptr);
-}
-#endif /* PNG_USER_MEM_SUPPORTED */
-#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
+
+/* pngmem.c - stub functions for memory allocation
+ *
+ * Last changed in libpng 1.6.15 [November 20, 2014]
+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * This file provides a location for all memory allocation.  Users who
+ * need special memory handling are expected to supply replacement
+ * functions for png_malloc() and png_free(), and to use
+ * png_create_read_struct_2() and png_create_write_struct_2() to
+ * identify the replacement functions.
+ */
+
+#include "pngpriv.h"
+
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+/* Free a png_struct */
+void /* PRIVATE */
+png_destroy_png_struct(png_structrp png_ptr)
+{
+   if (png_ptr != NULL)
+   {
+      /* png_free might call png_error and may certainly call
+       * png_get_mem_ptr, so fake a temporary png_struct to support this.
+       */
+      png_struct dummy_struct = *png_ptr;
+      memset(png_ptr, 0, (sizeof *png_ptr));
+      png_free(&dummy_struct, png_ptr);
+
+#     ifdef PNG_SETJMP_SUPPORTED
+         /* We may have a jmp_buf left to deallocate. */
+         png_free_jmpbuf(&dummy_struct);
+#     endif
+   }
+}
+
+/* Allocate memory.  For reasonable files, size should never exceed
+ * 64K.  However, zlib may allocate more then 64K if you don't tell
+ * it not to.  See zconf.h and png.h for more information.  zlib does
+ * need to allocate exactly 64K, so whatever you call here must
+ * have the ability to do that.
+ */
+PNG_FUNCTION(png_voidp,PNGAPI
+png_calloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
+{
+   png_voidp ret;
+
+   ret = png_malloc(png_ptr, size);
+
+   if (ret != NULL)
+      memset(ret, 0, size);
+
+   return ret;
+}
+
+/* png_malloc_base, an internal function added at libpng 1.6.0, does the work of
+ * allocating memory, taking into account limits and PNG_USER_MEM_SUPPORTED.
+ * Checking and error handling must happen outside this routine; it returns NULL
+ * if the allocation cannot be done (for any reason.)
+ */
+PNG_FUNCTION(png_voidp /* PRIVATE */,
+png_malloc_base,(png_const_structrp png_ptr, png_alloc_size_t size),
+   PNG_ALLOCATED)
+{
+   /* Moved to png_malloc_base from png_malloc_default in 1.6.0; the DOS
+    * allocators have also been removed in 1.6.0, so any 16-bit system now has
+    * to implement a user memory handler.  This checks to be sure it isn't
+    * called with big numbers.
+    */
+#ifndef PNG_USER_MEM_SUPPORTED
+   PNG_UNUSED(png_ptr)
+#endif
+
+   if (size > 0 && size <= PNG_SIZE_MAX
+#     ifdef PNG_MAX_MALLOC_64K
+         && size <= 65536U
+#     endif
+      )
+   {
+#ifdef PNG_USER_MEM_SUPPORTED
+      if (png_ptr != NULL && png_ptr->malloc_fn != NULL)
+         return png_ptr->malloc_fn(png_constcast(png_structrp,png_ptr), size);
+
+      else
+#endif
+         return malloc((size_t)size); /* checked for truncation above */
+   }
+
+   else
+      return NULL;
+}
+
+#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) ||\
+   defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED)
+/* This is really here only to work round a spurious warning in GCC 4.6 and 4.7
+ * that arises because of the checks in png_realloc_array that are repeated in
+ * png_malloc_array.
+ */
+static png_voidp
+png_malloc_array_checked(png_const_structrp png_ptr, int nelements,
+   size_t element_size)
+{
+   png_alloc_size_t req = nelements; /* known to be > 0 */
+
+   if (req <= PNG_SIZE_MAX/element_size)
+      return png_malloc_base(png_ptr, req * element_size);
+
+   /* The failure case when the request is too large */
+   return NULL;
+}
+
+PNG_FUNCTION(png_voidp /* PRIVATE */,
+png_malloc_array,(png_const_structrp png_ptr, int nelements,
+   size_t element_size),PNG_ALLOCATED)
+{
+   if (nelements <= 0 || element_size == 0)
+      png_error(png_ptr, "internal error: array alloc");
+
+   return png_malloc_array_checked(png_ptr, nelements, element_size);
+}
+
+PNG_FUNCTION(png_voidp /* PRIVATE */,
+png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array,
+   int old_elements, int add_elements, size_t element_size),PNG_ALLOCATED)
+{
+   /* These are internal errors: */
+   if (add_elements <= 0 || element_size == 0 || old_elements < 0 ||
+      (old_array == NULL && old_elements > 0))
+      png_error(png_ptr, "internal error: array realloc");
+
+   /* Check for overflow on the elements count (so the caller does not have to
+    * check.)
+    */
+   if (add_elements <= INT_MAX - old_elements)
+   {
+      png_voidp new_array = png_malloc_array_checked(png_ptr,
+         old_elements+add_elements, element_size);
+
+      if (new_array != NULL)
+      {
+         /* Because png_malloc_array worked the size calculations below cannot
+          * overflow.
+          */
+         if (old_elements > 0)
+            memcpy(new_array, old_array, element_size*(unsigned)old_elements);
+
+         memset((char*)new_array + element_size*(unsigned)old_elements, 0,
+            element_size*(unsigned)add_elements);
+
+         return new_array;
+      }
+   }
+
+   return NULL; /* error */
+}
+#endif /* TEXT || sPLT || STORE_UNKNOWN_CHUNKS */
+
+/* Various functions that have different error handling are derived from this.
+ * png_malloc always exists, but if PNG_USER_MEM_SUPPORTED is defined a separate
+ * function png_malloc_default is also provided.
+ */
+PNG_FUNCTION(png_voidp,PNGAPI
+png_malloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
+{
+   png_voidp ret;
+
+   if (png_ptr == NULL)
+      return NULL;
+
+   ret = png_malloc_base(png_ptr, size);
+
+   if (ret == NULL)
+       png_error(png_ptr, "Out of memory"); /* 'm' means png_malloc */
+
+   return ret;
+}
+
+#ifdef PNG_USER_MEM_SUPPORTED
+PNG_FUNCTION(png_voidp,PNGAPI
+png_malloc_default,(png_const_structrp png_ptr, png_alloc_size_t size),
+   PNG_ALLOCATED PNG_DEPRECATED)
+{
+   png_voidp ret;
+
+   if (png_ptr == NULL)
+      return NULL;
+
+   /* Passing 'NULL' here bypasses the application provided memory handler. */
+   ret = png_malloc_base(NULL/*use malloc*/, size);
+
+   if (ret == NULL)
+      png_error(png_ptr, "Out of Memory"); /* 'M' means png_malloc_default */
+
+   return ret;
+}
+#endif /* USER_MEM */
+
+/* This function was added at libpng version 1.2.3.  The png_malloc_warn()
+ * function will issue a png_warning and return NULL instead of issuing a
+ * png_error, if it fails to allocate the requested memory.
+ */
+PNG_FUNCTION(png_voidp,PNGAPI
+png_malloc_warn,(png_const_structrp png_ptr, png_alloc_size_t size),
+   PNG_ALLOCATED)
+{
+   if (png_ptr != NULL)
+   {
+      png_voidp ret = png_malloc_base(png_ptr, size);
+
+      if (ret != NULL)
+         return ret;
+
+      png_warning(png_ptr, "Out of memory");
+   }
+
+   return NULL;
+}
+
+/* Free a pointer allocated by png_malloc().  If ptr is NULL, return
+ * without taking any action.
+ */
+void PNGAPI
+png_free(png_const_structrp png_ptr, png_voidp ptr)
+{
+   if (png_ptr == NULL || ptr == NULL)
+      return;
+
+#ifdef PNG_USER_MEM_SUPPORTED
+   if (png_ptr->free_fn != NULL)
+      png_ptr->free_fn(png_constcast(png_structrp,png_ptr), ptr);
+
+   else
+      png_free_default(png_ptr, ptr);
+}
+
+PNG_FUNCTION(void,PNGAPI
+png_free_default,(png_const_structrp png_ptr, png_voidp ptr),PNG_DEPRECATED)
+{
+   if (png_ptr == NULL || ptr == NULL)
+      return;
+#endif /* USER_MEM */
+
+   free(ptr);
+}
+
+#ifdef PNG_USER_MEM_SUPPORTED
+/* This function is called when the application wants to use another method
+ * of allocating and freeing memory.
+ */
+void PNGAPI
+png_set_mem_fn(png_structrp png_ptr, png_voidp mem_ptr, png_malloc_ptr
+  malloc_fn, png_free_ptr free_fn)
+{
+   if (png_ptr != NULL)
+   {
+      png_ptr->mem_ptr = mem_ptr;
+      png_ptr->malloc_fn = malloc_fn;
+      png_ptr->free_fn = free_fn;
+   }
+}
+
+/* This function returns a pointer to the mem_ptr associated with the user
+ * functions.  The application should free any memory associated with this
+ * pointer before png_write_destroy and png_read_destroy are called.
+ */
+png_voidp PNGAPI
+png_get_mem_ptr(png_const_structrp png_ptr)
+{
+   if (png_ptr == NULL)
+      return NULL;
+
+   return png_ptr->mem_ptr;
+}
+#endif /* USER_MEM */
+#endif /* READ || WRITE */
diff --git a/Source/LibPNG/pngpread.c b/Source/LibPNG/pngpread.c
index 39f8f6f..fb40e7d 100644
--- a/Source/LibPNG/pngpread.c
+++ b/Source/LibPNG/pngpread.c
@@ -1,1315 +1,1168 @@
-
-/* pngpread.c - read a png file in push mode
- *
- * Last changed in libpng 1.5.11 [June 14, 2012]
- * Copyright (c) 1998-2012 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- */
-
-#include "pngpriv.h"
-
-#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
-
-/* Push model modes */
-#define PNG_READ_SIG_MODE   0
-#define PNG_READ_CHUNK_MODE 1
-#define PNG_READ_IDAT_MODE  2
-#define PNG_SKIP_MODE       3
-#define PNG_READ_tEXt_MODE  4
-#define PNG_READ_zTXt_MODE  5
-#define PNG_READ_DONE_MODE  6
-#define PNG_READ_iTXt_MODE  7
-#define PNG_ERROR_MODE      8
-
-void PNGAPI
-png_process_data(png_structp png_ptr, png_infop info_ptr,
-    png_bytep buffer, png_size_t buffer_size)
-{
-   if (png_ptr == NULL || info_ptr == NULL)
-      return;
-
-   png_push_restore_buffer(png_ptr, buffer, buffer_size);
-
-   while (png_ptr->buffer_size)
-   {
-      png_process_some_data(png_ptr, info_ptr);
-   }
-}
-
-png_size_t PNGAPI
-png_process_data_pause(png_structp png_ptr, int save)
-{
-   if (png_ptr != NULL)
-   {
-      /* It's easiest for the caller if we do the save, then the caller doesn't
-       * have to supply the same data again:
-       */
-      if (save)
-         png_push_save_buffer(png_ptr);
-      else
-      {
-         /* This includes any pending saved bytes: */
-         png_size_t remaining = png_ptr->buffer_size;
-         png_ptr->buffer_size = 0;
-
-         /* So subtract the saved buffer size, unless all the data
-          * is actually 'saved', in which case we just return 0
-          */
-         if (png_ptr->save_buffer_size < remaining)
-            return remaining - png_ptr->save_buffer_size;
-      }
-   }
-
-   return 0;
-}
-
-png_uint_32 PNGAPI
-png_process_data_skip(png_structp png_ptr)
-{
-   png_uint_32 remaining = 0;
-
-   if (png_ptr != NULL && png_ptr->process_mode == PNG_SKIP_MODE &&
-      png_ptr->skip_length > 0)
-   {
-      /* At the end of png_process_data the buffer size must be 0 (see the loop
-       * above) so we can detect a broken call here:
-       */
-      if (png_ptr->buffer_size != 0)
-         png_error(png_ptr,
-            "png_process_data_skip called inside png_process_data");
-
-      /* If is impossible for there to be a saved buffer at this point -
-       * otherwise we could not be in SKIP mode.  This will also happen if
-       * png_process_skip is called inside png_process_data (but only very
-       * rarely.)
-       */
-      if (png_ptr->save_buffer_size != 0)
-         png_error(png_ptr, "png_process_data_skip called with saved data");
-
-      remaining = png_ptr->skip_length;
-      png_ptr->skip_length = 0;
-      png_ptr->process_mode = PNG_READ_CHUNK_MODE;
-   }
-
-   return remaining;
-}
-
-/* What we do with the incoming data depends on what we were previously
- * doing before we ran out of data...
- */
-void /* PRIVATE */
-png_process_some_data(png_structp png_ptr, png_infop info_ptr)
-{
-   if (png_ptr == NULL)
-      return;
-
-   switch (png_ptr->process_mode)
-   {
-      case PNG_READ_SIG_MODE:
-      {
-         png_push_read_sig(png_ptr, info_ptr);
-         break;
-      }
-
-      case PNG_READ_CHUNK_MODE:
-      {
-         png_push_read_chunk(png_ptr, info_ptr);
-         break;
-      }
-
-      case PNG_READ_IDAT_MODE:
-      {
-         png_push_read_IDAT(png_ptr);
-         break;
-      }
-
-      case PNG_SKIP_MODE:
-      {
-         png_push_crc_finish(png_ptr);
-         break;
-      }
-
-      default:
-      {
-         png_ptr->buffer_size = 0;
-         break;
-      }
-   }
-}
-
-/* Read any remaining signature bytes from the stream and compare them with
- * the correct PNG signature.  It is possible that this routine is called
- * with bytes already read from the signature, either because they have been
- * checked by the calling application, or because of multiple calls to this
- * routine.
- */
-void /* PRIVATE */
-png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
-{
-   png_size_t num_checked = png_ptr->sig_bytes,
-       num_to_check = 8 - num_checked;
-
-   if (png_ptr->buffer_size < num_to_check)
-   {
-      num_to_check = png_ptr->buffer_size;
-   }
-
-   png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
-       num_to_check);
-   png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check);
-
-   if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
-   {
-      if (num_checked < 4 &&
-          png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
-         png_error(png_ptr, "Not a PNG file");
-
-      else
-         png_error(png_ptr, "PNG file corrupted by ASCII conversion");
-   }
-
-   else
-   {
-      if (png_ptr->sig_bytes >= 8)
-      {
-         png_ptr->process_mode = PNG_READ_CHUNK_MODE;
-      }
-   }
-}
-
-void /* PRIVATE */
-png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
-{
-   png_uint_32 chunk_name;
-
-   /* First we make sure we have enough data for the 4 byte chunk name
-    * and the 4 byte chunk length before proceeding with decoding the
-    * chunk data.  To fully decode each of these chunks, we also make
-    * sure we have enough data in the buffer for the 4 byte CRC at the
-    * end of every chunk (except IDAT, which is handled separately).
-    */
-   if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
-   {
-      png_byte chunk_length[4];
-      png_byte chunk_tag[4];
-
-      if (png_ptr->buffer_size < 8)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
-      png_push_fill_buffer(png_ptr, chunk_length, 4);
-      png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
-      png_reset_crc(png_ptr);
-      png_crc_read(png_ptr, chunk_tag, 4);
-      png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
-      png_check_chunk_name(png_ptr, png_ptr->chunk_name);
-      png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
-   }
-
-   chunk_name = png_ptr->chunk_name;
-
-   if (chunk_name == png_IDAT)
-   {
-      /* This is here above the if/else case statement below because if the
-       * unknown handling marks 'IDAT' as unknown then the IDAT handling case is
-       * completely skipped.
-       *
-       * TODO: there must be a better way of doing this.
-       */
-      if (png_ptr->mode & PNG_AFTER_IDAT)
-         png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
-   }
-
-   if (chunk_name == png_IHDR)
-   {
-      if (png_ptr->push_length != 13)
-         png_error(png_ptr, "Invalid IHDR length");
-
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
-      png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
-   }
-
-   else if (chunk_name == png_IEND)
-   {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
-      png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
-
-      png_ptr->process_mode = PNG_READ_DONE_MODE;
-      png_push_have_end(png_ptr, info_ptr);
-   }
-
-#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
-   else if (png_chunk_unknown_handling(png_ptr, chunk_name))
-   {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
-      if (chunk_name == png_IDAT)
-         png_ptr->mode |= PNG_HAVE_IDAT;
-
-      png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
-
-      if (chunk_name == png_PLTE)
-         png_ptr->mode |= PNG_HAVE_PLTE;
-
-      else if (chunk_name == png_IDAT)
-      {
-         if (!(png_ptr->mode & PNG_HAVE_IHDR))
-            png_error(png_ptr, "Missing IHDR before IDAT");
-
-         else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
-             !(png_ptr->mode & PNG_HAVE_PLTE))
-            png_error(png_ptr, "Missing PLTE before IDAT");
-      }
-   }
-#endif
-
-   else if (chunk_name == png_PLTE)
-   {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-      png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
-   }
-
-   else if (chunk_name == png_IDAT)
-   {
-      /* If we reach an IDAT chunk, this means we have read all of the
-       * header chunks, and we can start reading the image (or if this
-       * is called after the image has been read - we have an error).
-       */
-
-      if (!(png_ptr->mode & PNG_HAVE_IHDR))
-         png_error(png_ptr, "Missing IHDR before IDAT");
-
-      else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
-          !(png_ptr->mode & PNG_HAVE_PLTE))
-         png_error(png_ptr, "Missing PLTE before IDAT");
-
-      if (png_ptr->mode & PNG_HAVE_IDAT)
-      {
-         if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
-            if (png_ptr->push_length == 0)
-               return;
-
-         if (png_ptr->mode & PNG_AFTER_IDAT)
-            png_benign_error(png_ptr, "Too many IDATs found");
-      }
-
-      png_ptr->idat_size = png_ptr->push_length;
-      png_ptr->mode |= PNG_HAVE_IDAT;
-      png_ptr->process_mode = PNG_READ_IDAT_MODE;
-      png_push_have_info(png_ptr, info_ptr);
-      png_ptr->zstream.avail_out =
-          (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
-          png_ptr->iwidth) + 1;
-      png_ptr->zstream.next_out = png_ptr->row_buf;
-      return;
-   }
-
-#ifdef PNG_READ_gAMA_SUPPORTED
-   else if (png_ptr->chunk_name == png_gAMA)
-   {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
-      png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
-   }
-
-#endif
-#ifdef PNG_READ_sBIT_SUPPORTED
-   else if (png_ptr->chunk_name == png_sBIT)
-   {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
-      png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
-   }
-
-#endif
-#ifdef PNG_READ_cHRM_SUPPORTED
-   else if (png_ptr->chunk_name == png_cHRM)
-   {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
-      png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
-   }
-
-#endif
-#ifdef PNG_READ_sRGB_SUPPORTED
-   else if (chunk_name == png_sRGB)
-   {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
-      png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
-   }
-
-#endif
-#ifdef PNG_READ_iCCP_SUPPORTED
-   else if (png_ptr->chunk_name == png_iCCP)
-   {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
-      png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);
-   }
-
-#endif
-#ifdef PNG_READ_sPLT_SUPPORTED
-   else if (chunk_name == png_sPLT)
-   {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
-      png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);
-   }
-
-#endif
-#ifdef PNG_READ_tRNS_SUPPORTED
-   else if (chunk_name == png_tRNS)
-   {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
-      png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
-   }
-
-#endif
-#ifdef PNG_READ_bKGD_SUPPORTED
-   else if (chunk_name == png_bKGD)
-   {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
-      png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
-   }
-
-#endif
-#ifdef PNG_READ_hIST_SUPPORTED
-   else if (chunk_name == png_hIST)
-   {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
-      png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
-   }
-
-#endif
-#ifdef PNG_READ_pHYs_SUPPORTED
-   else if (chunk_name == png_pHYs)
-   {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
-      png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
-   }
-
-#endif
-#ifdef PNG_READ_oFFs_SUPPORTED
-   else if (chunk_name == png_oFFs)
-   {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
-      png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
-   }
-#endif
-
-#ifdef PNG_READ_pCAL_SUPPORTED
-   else if (chunk_name == png_pCAL)
-   {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
-      png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
-   }
-
-#endif
-#ifdef PNG_READ_sCAL_SUPPORTED
-   else if (chunk_name == png_sCAL)
-   {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
-      png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);
-   }
-
-#endif
-#ifdef PNG_READ_tIME_SUPPORTED
-   else if (chunk_name == png_tIME)
-   {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
-      png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
-   }
-
-#endif
-#ifdef PNG_READ_tEXt_SUPPORTED
-   else if (chunk_name == png_tEXt)
-   {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
-      png_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
-   }
-
-#endif
-#ifdef PNG_READ_zTXt_SUPPORTED
-   else if (chunk_name == png_zTXt)
-   {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
-      png_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
-   }
-
-#endif
-#ifdef PNG_READ_iTXt_SUPPORTED
-   else if (chunk_name == png_iTXt)
-   {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
-      png_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
-   }
-
-#endif
-
-   else
-   {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-      png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
-   }
-
-   png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
-}
-
-void /* PRIVATE */
-png_push_crc_skip(png_structp png_ptr, png_uint_32 skip)
-{
-   png_ptr->process_mode = PNG_SKIP_MODE;
-   png_ptr->skip_length = skip;
-}
-
-void /* PRIVATE */
-png_push_crc_finish(png_structp png_ptr)
-{
-   if (png_ptr->skip_length && png_ptr->save_buffer_size)
-   {
-      png_size_t save_size = png_ptr->save_buffer_size;
-      png_uint_32 skip_length = png_ptr->skip_length;
-
-      /* We want the smaller of 'skip_length' and 'save_buffer_size', but
-       * they are of different types and we don't know which variable has the
-       * fewest bits.  Carefully select the smaller and cast it to the type of
-       * the larger - this cannot overflow.  Do not cast in the following test
-       * - it will break on either 16 or 64 bit platforms.
-       */
-      if (skip_length < save_size)
-         save_size = (png_size_t)skip_length;
-
-      else
-         skip_length = (png_uint_32)save_size;
-
-      png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
-
-      png_ptr->skip_length -= skip_length;
-      png_ptr->buffer_size -= save_size;
-      png_ptr->save_buffer_size -= save_size;
-      png_ptr->save_buffer_ptr += save_size;
-   }
-
-   if (png_ptr->skip_length && png_ptr->current_buffer_size)
-   {
-      png_size_t save_size = png_ptr->current_buffer_size;
-      png_uint_32 skip_length = png_ptr->skip_length;
-
-      /* We want the smaller of 'skip_length' and 'current_buffer_size', here,
-       * the same problem exists as above and the same solution.
-       */
-      if (skip_length < save_size)
-         save_size = (png_size_t)skip_length;
-
-      else
-         skip_length = (png_uint_32)save_size;
-
-      png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
-
-      png_ptr->skip_length -= skip_length;
-      png_ptr->buffer_size -= save_size;
-      png_ptr->current_buffer_size -= save_size;
-      png_ptr->current_buffer_ptr += save_size;
-   }
-
-   if (!png_ptr->skip_length)
-   {
-      if (png_ptr->buffer_size < 4)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
-      png_crc_finish(png_ptr, 0);
-      png_ptr->process_mode = PNG_READ_CHUNK_MODE;
-   }
-}
-
-void PNGCBAPI
-png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
-{
-   png_bytep ptr;
-
-   if (png_ptr == NULL)
-      return;
-
-   ptr = buffer;
-
-   if (png_ptr->save_buffer_size)
-   {
-      png_size_t save_size;
-
-      if (length < png_ptr->save_buffer_size)
-         save_size = length;
-
-      else
-         save_size = png_ptr->save_buffer_size;
-
-      png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
-      length -= save_size;
-      ptr += save_size;
-      png_ptr->buffer_size -= save_size;
-      png_ptr->save_buffer_size -= save_size;
-      png_ptr->save_buffer_ptr += save_size;
-   }
-
-   if (length && png_ptr->current_buffer_size)
-   {
-      png_size_t save_size;
-
-      if (length < png_ptr->current_buffer_size)
-         save_size = length;
-
-      else
-         save_size = png_ptr->current_buffer_size;
-
-      png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
-      png_ptr->buffer_size -= save_size;
-      png_ptr->current_buffer_size -= save_size;
-      png_ptr->current_buffer_ptr += save_size;
-   }
-}
-
-void /* PRIVATE */
-png_push_save_buffer(png_structp png_ptr)
-{
-   if (png_ptr->save_buffer_size)
-   {
-      if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
-      {
-         png_size_t i, istop;
-         png_bytep sp;
-         png_bytep dp;
-
-         istop = png_ptr->save_buffer_size;
-
-         for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
-             i < istop; i++, sp++, dp++)
-         {
-            *dp = *sp;
-         }
-      }
-   }
-
-   if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
-       png_ptr->save_buffer_max)
-   {
-      png_size_t new_max;
-      png_bytep old_buffer;
-
-      if (png_ptr->save_buffer_size > PNG_SIZE_MAX -
-          (png_ptr->current_buffer_size + 256))
-      {
-         png_error(png_ptr, "Potential overflow of save_buffer");
-      }
-
-      new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
-      old_buffer = png_ptr->save_buffer;
-      png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr, new_max);
-
-      if (png_ptr->save_buffer == NULL)
-      {
-         png_free(png_ptr, old_buffer);
-         png_error(png_ptr, "Insufficient memory for save_buffer");
-      }
-
-      png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
-      png_free(png_ptr, old_buffer);
-      png_ptr->save_buffer_max = new_max;
-   }
-
-   if (png_ptr->current_buffer_size)
-   {
-      png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
-         png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);
-      png_ptr->save_buffer_size += png_ptr->current_buffer_size;
-      png_ptr->current_buffer_size = 0;
-   }
-
-   png_ptr->save_buffer_ptr = png_ptr->save_buffer;
-   png_ptr->buffer_size = 0;
-}
-
-void /* PRIVATE */
-png_push_restore_buffer(png_structp png_ptr, png_bytep buffer,
-   png_size_t buffer_length)
-{
-   png_ptr->current_buffer = buffer;
-   png_ptr->current_buffer_size = buffer_length;
-   png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
-   png_ptr->current_buffer_ptr = png_ptr->current_buffer;
-}
-
-void /* PRIVATE */
-png_push_read_IDAT(png_structp png_ptr)
-{
-   if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
-   {
-      png_byte chunk_length[4];
-      png_byte chunk_tag[4];
-
-      /* TODO: this code can be commoned up with the same code in push_read */
-      if (png_ptr->buffer_size < 8)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
-      png_push_fill_buffer(png_ptr, chunk_length, 4);
-      png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
-      png_reset_crc(png_ptr);
-      png_crc_read(png_ptr, chunk_tag, 4);
-      png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
-      png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
-
-      if (png_ptr->chunk_name != png_IDAT)
-      {
-         png_ptr->process_mode = PNG_READ_CHUNK_MODE;
-
-         if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
-            png_error(png_ptr, "Not enough compressed data");
-
-         return;
-      }
-
-      png_ptr->idat_size = png_ptr->push_length;
-   }
-
-   if (png_ptr->idat_size && png_ptr->save_buffer_size)
-   {
-      png_size_t save_size = png_ptr->save_buffer_size;
-      png_uint_32 idat_size = png_ptr->idat_size;
-
-      /* We want the smaller of 'idat_size' and 'current_buffer_size', but they
-       * are of different types and we don't know which variable has the fewest
-       * bits.  Carefully select the smaller and cast it to the type of the
-       * larger - this cannot overflow.  Do not cast in the following test - it
-       * will break on either 16 or 64 bit platforms.
-       */
-      if (idat_size < save_size)
-         save_size = (png_size_t)idat_size;
-
-      else
-         idat_size = (png_uint_32)save_size;
-
-      png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
-
-      png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
-
-      png_ptr->idat_size -= idat_size;
-      png_ptr->buffer_size -= save_size;
-      png_ptr->save_buffer_size -= save_size;
-      png_ptr->save_buffer_ptr += save_size;
-   }
-
-   if (png_ptr->idat_size && png_ptr->current_buffer_size)
-   {
-      png_size_t save_size = png_ptr->current_buffer_size;
-      png_uint_32 idat_size = png_ptr->idat_size;
-
-      /* We want the smaller of 'idat_size' and 'current_buffer_size', but they
-       * are of different types and we don't know which variable has the fewest
-       * bits.  Carefully select the smaller and cast it to the type of the
-       * larger - this cannot overflow.
-       */
-      if (idat_size < save_size)
-         save_size = (png_size_t)idat_size;
-
-      else
-         idat_size = (png_uint_32)save_size;
-
-      png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
-
-      png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
-
-      png_ptr->idat_size -= idat_size;
-      png_ptr->buffer_size -= save_size;
-      png_ptr->current_buffer_size -= save_size;
-      png_ptr->current_buffer_ptr += save_size;
-   }
-
-   if (!png_ptr->idat_size)
-   {
-      if (png_ptr->buffer_size < 4)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
-      png_crc_finish(png_ptr, 0);
-      png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
-      png_ptr->mode |= PNG_AFTER_IDAT;
-   }
-}
-
-void /* PRIVATE */
-png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
-   png_size_t buffer_length)
-{
-   /* The caller checks for a non-zero buffer length. */
-   if (!(buffer_length > 0) || buffer == NULL)
-      png_error(png_ptr, "No IDAT data (internal error)");
-
-   /* This routine must process all the data it has been given
-    * before returning, calling the row callback as required to
-    * handle the uncompressed results.
-    */
-   png_ptr->zstream.next_in = buffer;
-   png_ptr->zstream.avail_in = (uInt)buffer_length;
-
-   /* Keep going until the decompressed data is all processed
-    * or the stream marked as finished.
-    */
-   while (png_ptr->zstream.avail_in > 0 &&
-          !(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
-   {
-      int ret;
-
-      /* We have data for zlib, but we must check that zlib
-       * has someplace to put the results.  It doesn't matter
-       * if we don't expect any results -- it may be the input
-       * data is just the LZ end code.
-       */
-      if (!(png_ptr->zstream.avail_out > 0))
-      {
-         png_ptr->zstream.avail_out =
-             (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
-             png_ptr->iwidth) + 1;
-
-         png_ptr->zstream.next_out = png_ptr->row_buf;
-      }
-
-      /* Using Z_SYNC_FLUSH here means that an unterminated
-       * LZ stream (a stream with a missing end code) can still
-       * be handled, otherwise (Z_NO_FLUSH) a future zlib
-       * implementation might defer output and therefore
-       * change the current behavior (see comments in inflate.c
-       * for why this doesn't happen at present with zlib 1.2.5).
-       */
-      ret = inflate(&png_ptr->zstream, Z_SYNC_FLUSH);
-
-      /* Check for any failure before proceeding. */
-      if (ret != Z_OK && ret != Z_STREAM_END)
-      {
-         /* Terminate the decompression. */
-         png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
-
-         /* This may be a truncated stream (missing or
-          * damaged end code).  Treat that as a warning.
-          */
-         if (png_ptr->row_number >= png_ptr->num_rows ||
-             png_ptr->pass > 6)
-            png_warning(png_ptr, "Truncated compressed data in IDAT");
-
-         else
-            png_error(png_ptr, "Decompression error in IDAT");
-
-         /* Skip the check on unprocessed input */
-         return;
-      }
-
-      /* Did inflate output any data? */
-      if (png_ptr->zstream.next_out != png_ptr->row_buf)
-      {
-         /* Is this unexpected data after the last row?
-          * If it is, artificially terminate the LZ output
-          * here.
-          */
-         if (png_ptr->row_number >= png_ptr->num_rows ||
-             png_ptr->pass > 6)
-         {
-            /* Extra data. */
-            png_warning(png_ptr, "Extra compressed data in IDAT");
-            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
-
-            /* Do no more processing; skip the unprocessed
-             * input check below.
-             */
-            return;
-         }
-
-         /* Do we have a complete row? */
-         if (png_ptr->zstream.avail_out == 0)
-            png_push_process_row(png_ptr);
-      }
-
-      /* And check for the end of the stream. */
-      if (ret == Z_STREAM_END)
-         png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
-   }
-
-   /* All the data should have been processed, if anything
-    * is left at this point we have bytes of IDAT data
-    * after the zlib end code.
-    */
-   if (png_ptr->zstream.avail_in > 0)
-      png_warning(png_ptr, "Extra compression data in IDAT");
-}
-
-void /* PRIVATE */
-png_push_process_row(png_structp png_ptr)
-{
-   /* 1.5.6: row_info moved out of png_struct to a local here. */
-   png_row_info row_info;
-
-   row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */
-   row_info.color_type = png_ptr->color_type;
-   row_info.bit_depth = png_ptr->bit_depth;
-   row_info.channels = png_ptr->channels;
-   row_info.pixel_depth = png_ptr->pixel_depth;
-   row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width);
-
-   if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE)
-   {
-      if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST)
-         png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1,
-            png_ptr->prev_row + 1, png_ptr->row_buf[0]);
-      else
-         png_error(png_ptr, "bad adaptive filter value");
-   }
-
-   /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before
-    * 1.5.6, while the buffer really is this big in current versions of libpng
-    * it may not be in the future, so this was changed just to copy the
-    * interlaced row count:
-    */
-   png_memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1);
-
-#ifdef PNG_READ_TRANSFORMS_SUPPORTED
-   if (png_ptr->transformations)
-      png_do_read_transformations(png_ptr, &row_info);
-#endif
-
-   /* The transformed pixel depth should match the depth now in row_info. */
-   if (png_ptr->transformed_pixel_depth == 0)
-   {
-      png_ptr->transformed_pixel_depth = row_info.pixel_depth;
-      if (row_info.pixel_depth > png_ptr->maximum_pixel_depth)
-         png_error(png_ptr, "progressive row overflow");
-   }
-
-   else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth)
-      png_error(png_ptr, "internal progressive row size calculation error");
-
-
-#ifdef PNG_READ_INTERLACING_SUPPORTED
-   /* Blow up interlaced rows to full size */
-   if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
-   {
-      if (png_ptr->pass < 6)
-         png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,
-            png_ptr->transformations);
-
-    switch (png_ptr->pass)
-    {
-         case 0:
-         {
-            int i;
-            for (i = 0; i < 8 && png_ptr->pass == 0; i++)
-            {
-               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
-               png_read_push_finish_row(png_ptr); /* Updates png_ptr->pass */
-            }
-
-            if (png_ptr->pass == 2) /* Pass 1 might be empty */
-            {
-               for (i = 0; i < 4 && png_ptr->pass == 2; i++)
-               {
-                  png_push_have_row(png_ptr, NULL);
-                  png_read_push_finish_row(png_ptr);
-               }
-            }
-
-            if (png_ptr->pass == 4 && png_ptr->height <= 4)
-            {
-               for (i = 0; i < 2 && png_ptr->pass == 4; i++)
-               {
-                  png_push_have_row(png_ptr, NULL);
-                  png_read_push_finish_row(png_ptr);
-               }
-            }
-
-            if (png_ptr->pass == 6 && png_ptr->height <= 4)
-            {
-                png_push_have_row(png_ptr, NULL);
-                png_read_push_finish_row(png_ptr);
-            }
-
-            break;
-         }
-
-         case 1:
-         {
-            int i;
-            for (i = 0; i < 8 && png_ptr->pass == 1; i++)
-            {
-               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
-               png_read_push_finish_row(png_ptr);
-            }
-
-            if (png_ptr->pass == 2) /* Skip top 4 generated rows */
-            {
-               for (i = 0; i < 4 && png_ptr->pass == 2; i++)
-               {
-                  png_push_have_row(png_ptr, NULL);
-                  png_read_push_finish_row(png_ptr);
-               }
-            }
-
-            break;
-         }
-
-         case 2:
-         {
-            int i;
-
-            for (i = 0; i < 4 && png_ptr->pass == 2; i++)
-            {
-               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
-               png_read_push_finish_row(png_ptr);
-            }
-
-            for (i = 0; i < 4 && png_ptr->pass == 2; i++)
-            {
-               png_push_have_row(png_ptr, NULL);
-               png_read_push_finish_row(png_ptr);
-            }
-
-            if (png_ptr->pass == 4) /* Pass 3 might be empty */
-            {
-               for (i = 0; i < 2 && png_ptr->pass == 4; i++)
-               {
-                  png_push_have_row(png_ptr, NULL);
-                  png_read_push_finish_row(png_ptr);
-               }
-            }
-
-            break;
-         }
-
-         case 3:
-         {
-            int i;
-
-            for (i = 0; i < 4 && png_ptr->pass == 3; i++)
-            {
-               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
-               png_read_push_finish_row(png_ptr);
-            }
-
-            if (png_ptr->pass == 4) /* Skip top two generated rows */
-            {
-               for (i = 0; i < 2 && png_ptr->pass == 4; i++)
-               {
-                  png_push_have_row(png_ptr, NULL);
-                  png_read_push_finish_row(png_ptr);
-               }
-            }
-
-            break;
-         }
-
-         case 4:
-         {
-            int i;
-
-            for (i = 0; i < 2 && png_ptr->pass == 4; i++)
-            {
-               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
-               png_read_push_finish_row(png_ptr);
-            }
-
-            for (i = 0; i < 2 && png_ptr->pass == 4; i++)
-            {
-               png_push_have_row(png_ptr, NULL);
-               png_read_push_finish_row(png_ptr);
-            }
-
-            if (png_ptr->pass == 6) /* Pass 5 might be empty */
-            {
-               png_push_have_row(png_ptr, NULL);
-               png_read_push_finish_row(png_ptr);
-            }
-
-            break;
-         }
-
-         case 5:
-         {
-            int i;
-
-            for (i = 0; i < 2 && png_ptr->pass == 5; i++)
-            {
-               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
-               png_read_push_finish_row(png_ptr);
-            }
-
-            if (png_ptr->pass == 6) /* Skip top generated row */
-            {
-               png_push_have_row(png_ptr, NULL);
-               png_read_push_finish_row(png_ptr);
-            }
-
-            break;
-         }
-
-         default:
-         case 6:
-         {
-            png_push_have_row(png_ptr, png_ptr->row_buf + 1);
-            png_read_push_finish_row(png_ptr);
-
-            if (png_ptr->pass != 6)
-               break;
-
-            png_push_have_row(png_ptr, NULL);
-            png_read_push_finish_row(png_ptr);
-         }
-      }
-   }
-   else
-#endif
-   {
-      png_push_have_row(png_ptr, png_ptr->row_buf + 1);
-      png_read_push_finish_row(png_ptr);
-   }
-}
-
-void /* PRIVATE */
-png_read_push_finish_row(png_structp png_ptr)
-{
-#ifdef PNG_READ_INTERLACING_SUPPORTED
-   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
-
-   /* Start of interlace block */
-   static PNG_CONST png_byte FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
-
-   /* Offset to next interlace block */
-   static PNG_CONST png_byte FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
-
-   /* Start of interlace block in the y direction */
-   static PNG_CONST png_byte FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
-
-   /* Offset to next interlace block in the y direction */
-   static PNG_CONST png_byte FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
-
-   /* Height of interlace block.  This is not currently used - if you need
-    * it, uncomment it here and in png.h
-   static PNG_CONST png_byte FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
-   */
-#endif
-
-   png_ptr->row_number++;
-   if (png_ptr->row_number < png_ptr->num_rows)
-      return;
-
-#ifdef PNG_READ_INTERLACING_SUPPORTED
-   if (png_ptr->interlaced)
-   {
-      png_ptr->row_number = 0;
-      png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
-
-      do
-      {
-         png_ptr->pass++;
-         if ((png_ptr->pass == 1 && png_ptr->width < 5) ||
-             (png_ptr->pass == 3 && png_ptr->width < 3) ||
-             (png_ptr->pass == 5 && png_ptr->width < 2))
-            png_ptr->pass++;
-
-         if (png_ptr->pass > 7)
-            png_ptr->pass--;
-
-         if (png_ptr->pass >= 7)
-            break;
-
-         png_ptr->iwidth = (png_ptr->width +
-             png_pass_inc[png_ptr->pass] - 1 -
-             png_pass_start[png_ptr->pass]) /
-             png_pass_inc[png_ptr->pass];
-
-         if (png_ptr->transformations & PNG_INTERLACE)
-            break;
-
-         png_ptr->num_rows = (png_ptr->height +
-             png_pass_yinc[png_ptr->pass] - 1 -
-             png_pass_ystart[png_ptr->pass]) /
-             png_pass_yinc[png_ptr->pass];
-
-      } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
-   }
-#endif /* PNG_READ_INTERLACING_SUPPORTED */
-}
-
-void /* PRIVATE */
-png_push_have_info(png_structp png_ptr, png_infop info_ptr)
-{
-   if (png_ptr->info_fn != NULL)
-      (*(png_ptr->info_fn))(png_ptr, info_ptr);
-}
-
-void /* PRIVATE */
-png_push_have_end(png_structp png_ptr, png_infop info_ptr)
-{
-   if (png_ptr->end_fn != NULL)
-      (*(png_ptr->end_fn))(png_ptr, info_ptr);
-}
-
-void /* PRIVATE */
-png_push_have_row(png_structp png_ptr, png_bytep row)
-{
-   if (png_ptr->row_fn != NULL)
-      (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
-         (int)png_ptr->pass);
-}
-
-#ifdef PNG_READ_INTERLACING_SUPPORTED
-void PNGAPI
-png_progressive_combine_row (png_structp png_ptr, png_bytep old_row,
-    png_const_bytep new_row)
-{
-   if (png_ptr == NULL)
-      return;
-
-   /* new_row is a flag here - if it is NULL then the app callback was called
-    * from an empty row (see the calls to png_struct::row_fn below), otherwise
-    * it must be png_ptr->row_buf+1
-    */
-   if (new_row != NULL)
-      png_combine_row(png_ptr, old_row, 1/*display*/);
-}
-#endif /* PNG_READ_INTERLACING_SUPPORTED */
-
-void PNGAPI
-png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
-    png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
-    png_progressive_end_ptr end_fn)
-{
-   if (png_ptr == NULL)
-      return;
-
-   png_ptr->info_fn = info_fn;
-   png_ptr->row_fn = row_fn;
-   png_ptr->end_fn = end_fn;
-
-   png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
-}
-
-png_voidp PNGAPI
-png_get_progressive_ptr(png_const_structp png_ptr)
-{
-   if (png_ptr == NULL)
-      return (NULL);
-
-   return png_ptr->io_ptr;
-}
-#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
+
+/* pngpread.c - read a png file in push mode
+ *
+ * Last changed in libpng 1.6.15 [November 20, 2014]
+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+#include "pngpriv.h"
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+
+/* Push model modes */
+#define PNG_READ_SIG_MODE   0
+#define PNG_READ_CHUNK_MODE 1
+#define PNG_READ_IDAT_MODE  2
+#define PNG_SKIP_MODE       3
+#define PNG_READ_tEXt_MODE  4
+#define PNG_READ_zTXt_MODE  5
+#define PNG_READ_DONE_MODE  6
+#define PNG_READ_iTXt_MODE  7
+#define PNG_ERROR_MODE      8
+
+#define PNG_PUSH_SAVE_BUFFER_IF_FULL \
+if (png_ptr->push_length + 4 > png_ptr->buffer_size) \
+   { png_push_save_buffer(png_ptr); return; }
+#define PNG_PUSH_SAVE_BUFFER_IF_LT(N) \
+if (png_ptr->buffer_size < N) \
+   { png_push_save_buffer(png_ptr); return; }
+
+void PNGAPI
+png_process_data(png_structrp png_ptr, png_inforp info_ptr,
+    png_bytep buffer, png_size_t buffer_size)
+{
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   png_push_restore_buffer(png_ptr, buffer, buffer_size);
+
+   while (png_ptr->buffer_size)
+   {
+      png_process_some_data(png_ptr, info_ptr);
+   }
+}
+
+png_size_t PNGAPI
+png_process_data_pause(png_structrp png_ptr, int save)
+{
+   if (png_ptr != NULL)
+   {
+      /* It's easiest for the caller if we do the save; then the caller doesn't
+       * have to supply the same data again:
+       */
+      if (save != 0)
+         png_push_save_buffer(png_ptr);
+      else
+      {
+         /* This includes any pending saved bytes: */
+         png_size_t remaining = png_ptr->buffer_size;
+         png_ptr->buffer_size = 0;
+
+         /* So subtract the saved buffer size, unless all the data
+          * is actually 'saved', in which case we just return 0
+          */
+         if (png_ptr->save_buffer_size < remaining)
+            return remaining - png_ptr->save_buffer_size;
+      }
+   }
+
+   return 0;
+}
+
+png_uint_32 PNGAPI
+png_process_data_skip(png_structrp png_ptr)
+{
+   png_uint_32 remaining = 0;
+
+   if (png_ptr != NULL && png_ptr->process_mode == PNG_SKIP_MODE &&
+      png_ptr->skip_length > 0)
+   {
+      /* At the end of png_process_data the buffer size must be 0 (see the loop
+       * above) so we can detect a broken call here:
+       */
+      if (png_ptr->buffer_size != 0)
+         png_error(png_ptr,
+            "png_process_data_skip called inside png_process_data");
+
+      /* If is impossible for there to be a saved buffer at this point -
+       * otherwise we could not be in SKIP mode.  This will also happen if
+       * png_process_skip is called inside png_process_data (but only very
+       * rarely.)
+       */
+      if (png_ptr->save_buffer_size != 0)
+         png_error(png_ptr, "png_process_data_skip called with saved data");
+
+      remaining = png_ptr->skip_length;
+      png_ptr->skip_length = 0;
+      png_ptr->process_mode = PNG_READ_CHUNK_MODE;
+   }
+
+   return remaining;
+}
+
+/* What we do with the incoming data depends on what we were previously
+ * doing before we ran out of data...
+ */
+void /* PRIVATE */
+png_process_some_data(png_structrp png_ptr, png_inforp info_ptr)
+{
+   if (png_ptr == NULL)
+      return;
+
+   switch (png_ptr->process_mode)
+   {
+      case PNG_READ_SIG_MODE:
+      {
+         png_push_read_sig(png_ptr, info_ptr);
+         break;
+      }
+
+      case PNG_READ_CHUNK_MODE:
+      {
+         png_push_read_chunk(png_ptr, info_ptr);
+         break;
+      }
+
+      case PNG_READ_IDAT_MODE:
+      {
+         png_push_read_IDAT(png_ptr);
+         break;
+      }
+
+      case PNG_SKIP_MODE:
+      {
+         png_push_crc_finish(png_ptr);
+         break;
+      }
+
+      default:
+      {
+         png_ptr->buffer_size = 0;
+         break;
+      }
+   }
+}
+
+/* Read any remaining signature bytes from the stream and compare them with
+ * the correct PNG signature.  It is possible that this routine is called
+ * with bytes already read from the signature, either because they have been
+ * checked by the calling application, or because of multiple calls to this
+ * routine.
+ */
+void /* PRIVATE */
+png_push_read_sig(png_structrp png_ptr, png_inforp info_ptr)
+{
+   png_size_t num_checked = png_ptr->sig_bytes, /* SAFE, does not exceed 8 */ 
+             num_to_check = 8 - num_checked;
+
+   if (png_ptr->buffer_size < num_to_check)
+   {
+      num_to_check = png_ptr->buffer_size;
+   }
+
+   png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
+       num_to_check);
+   png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check);
+
+   if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
+   {
+      if (num_checked < 4 &&
+          png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
+         png_error(png_ptr, "Not a PNG file");
+
+      else
+         png_error(png_ptr, "PNG file corrupted by ASCII conversion");
+   }
+   else
+   {
+      if (png_ptr->sig_bytes >= 8)
+      {
+         png_ptr->process_mode = PNG_READ_CHUNK_MODE;
+      }
+   }
+}
+
+void /* PRIVATE */
+png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
+{
+   png_uint_32 chunk_name;
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+   int keep; /* unknown handling method */
+#endif
+
+   /* First we make sure we have enough data for the 4-byte chunk name
+    * and the 4-byte chunk length before proceeding with decoding the
+    * chunk data.  To fully decode each of these chunks, we also make
+    * sure we have enough data in the buffer for the 4-byte CRC at the
+    * end of every chunk (except IDAT, which is handled separately).
+    */
+   if ((png_ptr->mode & PNG_HAVE_CHUNK_HEADER) == 0)
+   {
+      png_byte chunk_length[4];
+      png_byte chunk_tag[4];
+
+      PNG_PUSH_SAVE_BUFFER_IF_LT(8)
+      png_push_fill_buffer(png_ptr, chunk_length, 4);
+      png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
+      png_reset_crc(png_ptr);
+      png_crc_read(png_ptr, chunk_tag, 4);
+      png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
+      png_check_chunk_name(png_ptr, png_ptr->chunk_name);
+      png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
+   }
+
+   chunk_name = png_ptr->chunk_name;
+
+   if (chunk_name == png_IDAT)
+   {
+      if ((png_ptr->mode & PNG_AFTER_IDAT) != 0)
+         png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
+
+      /* If we reach an IDAT chunk, this means we have read all of the
+       * header chunks, and we can start reading the image (or if this
+       * is called after the image has been read - we have an error).
+       */
+      if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+         png_error(png_ptr, "Missing IHDR before IDAT");
+
+      else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+          (png_ptr->mode & PNG_HAVE_PLTE) == 0)
+         png_error(png_ptr, "Missing PLTE before IDAT");
+
+      png_ptr->mode |= PNG_HAVE_IDAT;
+      png_ptr->process_mode = PNG_READ_IDAT_MODE;
+
+      if ((png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) == 0)
+         if (png_ptr->push_length == 0)
+            return;
+
+      if ((png_ptr->mode & PNG_AFTER_IDAT) != 0)
+         png_benign_error(png_ptr, "Too many IDATs found");
+   }
+
+   if (chunk_name == png_IHDR)
+   {
+      if (png_ptr->push_length != 13)
+         png_error(png_ptr, "Invalid IHDR length");
+
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
+      png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
+   }
+
+   else if (chunk_name == png_IEND)
+   {
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
+      png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
+
+      png_ptr->process_mode = PNG_READ_DONE_MODE;
+      png_push_have_end(png_ptr, info_ptr);
+   }
+
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+   else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0)
+   {
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
+      png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length, keep);
+
+      if (chunk_name == png_PLTE)
+         png_ptr->mode |= PNG_HAVE_PLTE;
+   }
+#endif
+
+   else if (chunk_name == png_PLTE)
+   {
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
+      png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
+   }
+
+   else if (chunk_name == png_IDAT)
+   {
+      png_ptr->idat_size = png_ptr->push_length;
+      png_ptr->process_mode = PNG_READ_IDAT_MODE;
+      png_push_have_info(png_ptr, info_ptr);
+      png_ptr->zstream.avail_out =
+          (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
+          png_ptr->iwidth) + 1;
+      png_ptr->zstream.next_out = png_ptr->row_buf;
+      return;
+   }
+
+#ifdef PNG_READ_gAMA_SUPPORTED
+   else if (png_ptr->chunk_name == png_gAMA)
+   {
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
+      png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
+   }
+
+#endif
+#ifdef PNG_READ_sBIT_SUPPORTED
+   else if (png_ptr->chunk_name == png_sBIT)
+   {
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
+      png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
+   }
+
+#endif
+#ifdef PNG_READ_cHRM_SUPPORTED
+   else if (png_ptr->chunk_name == png_cHRM)
+   {
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
+      png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
+   }
+
+#endif
+#ifdef PNG_READ_sRGB_SUPPORTED
+   else if (chunk_name == png_sRGB)
+   {
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
+      png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
+   }
+
+#endif
+#ifdef PNG_READ_iCCP_SUPPORTED
+   else if (png_ptr->chunk_name == png_iCCP)
+   {
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
+      png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);
+   }
+
+#endif
+#ifdef PNG_READ_sPLT_SUPPORTED
+   else if (chunk_name == png_sPLT)
+   {
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
+      png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);
+   }
+
+#endif
+#ifdef PNG_READ_tRNS_SUPPORTED
+   else if (chunk_name == png_tRNS)
+   {
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
+      png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
+   }
+
+#endif
+#ifdef PNG_READ_bKGD_SUPPORTED
+   else if (chunk_name == png_bKGD)
+   {
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
+      png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
+   }
+
+#endif
+#ifdef PNG_READ_hIST_SUPPORTED
+   else if (chunk_name == png_hIST)
+   {
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
+      png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
+   }
+
+#endif
+#ifdef PNG_READ_pHYs_SUPPORTED
+   else if (chunk_name == png_pHYs)
+   {
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
+      png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
+   }
+
+#endif
+#ifdef PNG_READ_oFFs_SUPPORTED
+   else if (chunk_name == png_oFFs)
+   {
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
+      png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
+   }
+#endif
+
+#ifdef PNG_READ_pCAL_SUPPORTED
+   else if (chunk_name == png_pCAL)
+   {
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
+      png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
+   }
+
+#endif
+#ifdef PNG_READ_sCAL_SUPPORTED
+   else if (chunk_name == png_sCAL)
+   {
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
+      png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);
+   }
+
+#endif
+#ifdef PNG_READ_tIME_SUPPORTED
+   else if (chunk_name == png_tIME)
+   {
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
+      png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
+   }
+
+#endif
+#ifdef PNG_READ_tEXt_SUPPORTED
+   else if (chunk_name == png_tEXt)
+   {
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
+      png_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
+   }
+
+#endif
+#ifdef PNG_READ_zTXt_SUPPORTED
+   else if (chunk_name == png_zTXt)
+   {
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
+      png_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
+   }
+
+#endif
+#ifdef PNG_READ_iTXt_SUPPORTED
+   else if (chunk_name == png_iTXt)
+   {
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
+      png_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
+   }
+#endif
+
+   else
+   {
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
+      png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length,
+         PNG_HANDLE_CHUNK_AS_DEFAULT);
+   }
+
+   png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
+}
+
+void /* PRIVATE */
+png_push_crc_skip(png_structrp png_ptr, png_uint_32 skip)
+{
+   png_ptr->process_mode = PNG_SKIP_MODE;
+   png_ptr->skip_length = skip;
+}
+
+void /* PRIVATE */
+png_push_crc_finish(png_structrp png_ptr)
+{
+   if (png_ptr->skip_length != 0 && png_ptr->save_buffer_size != 0)
+   {
+      png_size_t save_size = png_ptr->save_buffer_size;
+      png_uint_32 skip_length = png_ptr->skip_length;
+
+      /* We want the smaller of 'skip_length' and 'save_buffer_size', but
+       * they are of different types and we don't know which variable has the
+       * fewest bits.  Carefully select the smaller and cast it to the type of
+       * the larger - this cannot overflow.  Do not cast in the following test
+       * - it will break on either 16 or 64 bit platforms.
+       */
+      if (skip_length < save_size)
+         save_size = (png_size_t)skip_length;
+
+      else
+         skip_length = (png_uint_32)save_size;
+
+      png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
+
+      png_ptr->skip_length -= skip_length;
+      png_ptr->buffer_size -= save_size;
+      png_ptr->save_buffer_size -= save_size;
+      png_ptr->save_buffer_ptr += save_size;
+   }
+   if (png_ptr->skip_length != 0 && png_ptr->current_buffer_size != 0)
+   {
+      png_size_t save_size = png_ptr->current_buffer_size;
+      png_uint_32 skip_length = png_ptr->skip_length;
+
+      /* We want the smaller of 'skip_length' and 'current_buffer_size', here,
+       * the same problem exists as above and the same solution.
+       */
+      if (skip_length < save_size)
+         save_size = (png_size_t)skip_length;
+
+      else
+         skip_length = (png_uint_32)save_size;
+
+      png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
+
+      png_ptr->skip_length -= skip_length;
+      png_ptr->buffer_size -= save_size;
+      png_ptr->current_buffer_size -= save_size;
+      png_ptr->current_buffer_ptr += save_size;
+   }
+   if (png_ptr->skip_length == 0)
+   {
+      PNG_PUSH_SAVE_BUFFER_IF_LT(4)
+      png_crc_finish(png_ptr, 0);
+      png_ptr->process_mode = PNG_READ_CHUNK_MODE;
+   }
+}
+
+void PNGCBAPI
+png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
+{
+   png_bytep ptr;
+
+   if (png_ptr == NULL)
+      return;
+
+   ptr = buffer;
+   if (png_ptr->save_buffer_size != 0)
+   {
+      png_size_t save_size;
+
+      if (length < png_ptr->save_buffer_size)
+         save_size = length;
+
+      else
+         save_size = png_ptr->save_buffer_size;
+
+      memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
+      length -= save_size;
+      ptr += save_size;
+      png_ptr->buffer_size -= save_size;
+      png_ptr->save_buffer_size -= save_size;
+      png_ptr->save_buffer_ptr += save_size;
+   }
+   if (length != 0 && png_ptr->current_buffer_size != 0)
+   {
+      png_size_t save_size;
+
+      if (length < png_ptr->current_buffer_size)
+         save_size = length;
+
+      else
+         save_size = png_ptr->current_buffer_size;
+
+      memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
+      png_ptr->buffer_size -= save_size;
+      png_ptr->current_buffer_size -= save_size;
+      png_ptr->current_buffer_ptr += save_size;
+   }
+}
+
+void /* PRIVATE */
+png_push_save_buffer(png_structrp png_ptr)
+{
+   if (png_ptr->save_buffer_size != 0)
+   {
+      if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
+      {
+         png_size_t i, istop;
+         png_bytep sp;
+         png_bytep dp;
+
+         istop = png_ptr->save_buffer_size;
+         for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
+             i < istop; i++, sp++, dp++)
+         {
+            *dp = *sp;
+         }
+      }
+   }
+   if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
+       png_ptr->save_buffer_max)
+   {
+      png_size_t new_max;
+      png_bytep old_buffer;
+
+      if (png_ptr->save_buffer_size > PNG_SIZE_MAX -
+          (png_ptr->current_buffer_size + 256))
+      {
+         png_error(png_ptr, "Potential overflow of save_buffer");
+      }
+
+      new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
+      old_buffer = png_ptr->save_buffer;
+      png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr,
+          (png_size_t)new_max);
+
+      if (png_ptr->save_buffer == NULL)
+      {
+         png_free(png_ptr, old_buffer);
+         old_buffer = NULL;
+         png_error(png_ptr, "Insufficient memory for save_buffer");
+      }
+
+      memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
+      png_free(png_ptr, old_buffer);
+      old_buffer = NULL;
+      png_ptr->save_buffer_max = new_max;
+   }
+   if (png_ptr->current_buffer_size)
+   {
+      memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
+         png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);
+      png_ptr->save_buffer_size += png_ptr->current_buffer_size;
+      png_ptr->current_buffer_size = 0;
+   }
+   png_ptr->save_buffer_ptr = png_ptr->save_buffer;
+   png_ptr->buffer_size = 0;
+}
+
+void /* PRIVATE */
+png_push_restore_buffer(png_structrp png_ptr, png_bytep buffer,
+   png_size_t buffer_length)
+{
+   png_ptr->current_buffer = buffer;
+   png_ptr->current_buffer_size = buffer_length;
+   png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
+   png_ptr->current_buffer_ptr = png_ptr->current_buffer;
+}
+
+void /* PRIVATE */
+png_push_read_IDAT(png_structrp png_ptr)
+{
+   if ((png_ptr->mode & PNG_HAVE_CHUNK_HEADER) == 0)
+   {
+      png_byte chunk_length[4];
+      png_byte chunk_tag[4];
+
+      /* TODO: this code can be commoned up with the same code in push_read */
+      PNG_PUSH_SAVE_BUFFER_IF_LT(8)
+      png_push_fill_buffer(png_ptr, chunk_length, 4);
+      png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
+      png_reset_crc(png_ptr);
+      png_crc_read(png_ptr, chunk_tag, 4);
+      png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
+      png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
+
+      if (png_ptr->chunk_name != png_IDAT)
+      {
+         png_ptr->process_mode = PNG_READ_CHUNK_MODE;
+
+         if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0)
+            png_error(png_ptr, "Not enough compressed data");
+
+         return;
+      }
+
+      png_ptr->idat_size = png_ptr->push_length;
+   }
+
+   if (png_ptr->idat_size != 0 && png_ptr->save_buffer_size != 0)
+   {
+      png_size_t save_size = png_ptr->save_buffer_size;
+      png_uint_32 idat_size = png_ptr->idat_size;
+
+      /* We want the smaller of 'idat_size' and 'current_buffer_size', but they
+       * are of different types and we don't know which variable has the fewest
+       * bits.  Carefully select the smaller and cast it to the type of the
+       * larger - this cannot overflow.  Do not cast in the following test - it
+       * will break on either 16 or 64 bit platforms.
+       */
+      if (idat_size < save_size)
+         save_size = (png_size_t)idat_size;
+
+      else
+         idat_size = (png_uint_32)save_size;
+
+      png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
+
+      png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
+
+      png_ptr->idat_size -= idat_size;
+      png_ptr->buffer_size -= save_size;
+      png_ptr->save_buffer_size -= save_size;
+      png_ptr->save_buffer_ptr += save_size;
+   }
+
+   if (png_ptr->idat_size != 0 && png_ptr->current_buffer_size != 0)
+   {
+      png_size_t save_size = png_ptr->current_buffer_size;
+      png_uint_32 idat_size = png_ptr->idat_size;
+
+      /* We want the smaller of 'idat_size' and 'current_buffer_size', but they
+       * are of different types and we don't know which variable has the fewest
+       * bits.  Carefully select the smaller and cast it to the type of the
+       * larger - this cannot overflow.
+       */
+      if (idat_size < save_size)
+         save_size = (png_size_t)idat_size;
+
+      else
+         idat_size = (png_uint_32)save_size;
+
+      png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
+
+      png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
+
+      png_ptr->idat_size -= idat_size;
+      png_ptr->buffer_size -= save_size;
+      png_ptr->current_buffer_size -= save_size;
+      png_ptr->current_buffer_ptr += save_size;
+   }
+   if (png_ptr->idat_size == 0)
+   {
+      PNG_PUSH_SAVE_BUFFER_IF_LT(4)
+      png_crc_finish(png_ptr, 0);
+      png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
+      png_ptr->mode |= PNG_AFTER_IDAT;
+      png_ptr->zowner = 0;
+   }
+}
+
+void /* PRIVATE */
+png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer,
+   png_size_t buffer_length)
+{
+   /* The caller checks for a non-zero buffer length. */
+   if (!(buffer_length > 0) || buffer == NULL)
+      png_error(png_ptr, "No IDAT data (internal error)");
+
+   /* This routine must process all the data it has been given
+    * before returning, calling the row callback as required to
+    * handle the uncompressed results.
+    */
+   png_ptr->zstream.next_in = buffer;
+   /* TODO: WARNING: TRUNCATION ERROR: DANGER WILL ROBINSON: */
+   png_ptr->zstream.avail_in = (uInt)buffer_length;
+
+   /* Keep going until the decompressed data is all processed
+    * or the stream marked as finished.
+    */
+   while (png_ptr->zstream.avail_in > 0 &&
+      !(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED))
+   {
+      int ret;
+
+      /* We have data for zlib, but we must check that zlib
+       * has someplace to put the results.  It doesn't matter
+       * if we don't expect any results -- it may be the input
+       * data is just the LZ end code.
+       */
+      if (!(png_ptr->zstream.avail_out > 0))
+      {
+         /* TODO: WARNING: TRUNCATION ERROR: DANGER WILL ROBINSON: */
+         png_ptr->zstream.avail_out = (uInt)(PNG_ROWBYTES(png_ptr->pixel_depth,
+             png_ptr->iwidth) + 1);
+
+         png_ptr->zstream.next_out = png_ptr->row_buf;
+      }
+
+      /* Using Z_SYNC_FLUSH here means that an unterminated
+       * LZ stream (a stream with a missing end code) can still
+       * be handled, otherwise (Z_NO_FLUSH) a future zlib
+       * implementation might defer output and therefore
+       * change the current behavior (see comments in inflate.c
+       * for why this doesn't happen at present with zlib 1.2.5).
+       */
+      ret = inflate(&png_ptr->zstream, Z_SYNC_FLUSH);
+
+      /* Check for any failure before proceeding. */
+      if (ret != Z_OK && ret != Z_STREAM_END)
+      {
+         /* Terminate the decompression. */
+         png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
+         png_ptr->zowner = 0;
+
+         /* This may be a truncated stream (missing or
+          * damaged end code).  Treat that as a warning.
+          */
+         if (png_ptr->row_number >= png_ptr->num_rows ||
+             png_ptr->pass > 6)
+            png_warning(png_ptr, "Truncated compressed data in IDAT");
+
+         else
+            png_error(png_ptr, "Decompression error in IDAT");
+
+         /* Skip the check on unprocessed input */
+         return;
+      }
+
+      /* Did inflate output any data? */
+      if (png_ptr->zstream.next_out != png_ptr->row_buf)
+      {
+         /* Is this unexpected data after the last row?
+          * If it is, artificially terminate the LZ output
+          * here.
+          */
+         if (png_ptr->row_number >= png_ptr->num_rows ||
+             png_ptr->pass > 6)
+         {
+            /* Extra data. */
+            png_warning(png_ptr, "Extra compressed data in IDAT");
+            png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
+            png_ptr->zowner = 0;
+
+            /* Do no more processing; skip the unprocessed
+             * input check below.
+             */
+            return;
+         }
+
+         /* Do we have a complete row? */
+         if (png_ptr->zstream.avail_out == 0)
+            png_push_process_row(png_ptr);
+      }
+
+      /* And check for the end of the stream. */
+      if (ret == Z_STREAM_END)
+         png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
+   }
+
+   /* All the data should have been processed, if anything
+    * is left at this point we have bytes of IDAT data
+    * after the zlib end code.
+    */
+   if (png_ptr->zstream.avail_in > 0)
+      png_warning(png_ptr, "Extra compression data in IDAT");
+}
+
+void /* PRIVATE */
+png_push_process_row(png_structrp png_ptr)
+{
+   /* 1.5.6: row_info moved out of png_struct to a local here. */
+   png_row_info row_info;
+
+   row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */
+   row_info.color_type = png_ptr->color_type;
+   row_info.bit_depth = png_ptr->bit_depth;
+   row_info.channels = png_ptr->channels;
+   row_info.pixel_depth = png_ptr->pixel_depth;
+   row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width);
+
+   if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE)
+   {
+      if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST)
+         png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1,
+            png_ptr->prev_row + 1, png_ptr->row_buf[0]);
+      else
+         png_error(png_ptr, "bad adaptive filter value");
+   }
+
+   /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before
+    * 1.5.6, while the buffer really is this big in current versions of libpng
+    * it may not be in the future, so this was changed just to copy the
+    * interlaced row count:
+    */
+   memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1);
+
+#ifdef PNG_READ_TRANSFORMS_SUPPORTED
+   if (png_ptr->transformations != 0)
+      png_do_read_transformations(png_ptr, &row_info);
+#endif
+
+   /* The transformed pixel depth should match the depth now in row_info. */
+   if (png_ptr->transformed_pixel_depth == 0)
+   {
+      png_ptr->transformed_pixel_depth = row_info.pixel_depth;
+      if (row_info.pixel_depth > png_ptr->maximum_pixel_depth)
+         png_error(png_ptr, "progressive row overflow");
+   }
+
+   else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth)
+      png_error(png_ptr, "internal progressive row size calculation error");
+
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+   /* Expand interlaced rows to full size */
+   if (png_ptr->interlaced != 0 &&
+       (png_ptr->transformations & PNG_INTERLACE) != 0)
+   {
+      if (png_ptr->pass < 6)
+         png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,
+            png_ptr->transformations);
+
+      switch (png_ptr->pass)
+      {
+         case 0:
+         {
+            int i;
+            for (i = 0; i < 8 && png_ptr->pass == 0; i++)
+            {
+               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+               png_read_push_finish_row(png_ptr); /* Updates png_ptr->pass */
+            }
+
+            if (png_ptr->pass == 2) /* Pass 1 might be empty */
+            {
+               for (i = 0; i < 4 && png_ptr->pass == 2; i++)
+               {
+                  png_push_have_row(png_ptr, NULL);
+                  png_read_push_finish_row(png_ptr);
+               }
+            }
+
+            if (png_ptr->pass == 4 && png_ptr->height <= 4)
+            {
+               for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+               {
+                  png_push_have_row(png_ptr, NULL);
+                  png_read_push_finish_row(png_ptr);
+               }
+            }
+
+            if (png_ptr->pass == 6 && png_ptr->height <= 4)
+            {
+                png_push_have_row(png_ptr, NULL);
+                png_read_push_finish_row(png_ptr);
+            }
+
+            break;
+         }
+
+         case 1:
+         {
+            int i;
+            for (i = 0; i < 8 && png_ptr->pass == 1; i++)
+            {
+               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+               png_read_push_finish_row(png_ptr);
+            }
+
+            if (png_ptr->pass == 2) /* Skip top 4 generated rows */
+            {
+               for (i = 0; i < 4 && png_ptr->pass == 2; i++)
+               {
+                  png_push_have_row(png_ptr, NULL);
+                  png_read_push_finish_row(png_ptr);
+               }
+            }
+
+            break;
+         }
+
+         case 2:
+         {
+            int i;
+
+            for (i = 0; i < 4 && png_ptr->pass == 2; i++)
+            {
+               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+               png_read_push_finish_row(png_ptr);
+            }
+
+            for (i = 0; i < 4 && png_ptr->pass == 2; i++)
+            {
+               png_push_have_row(png_ptr, NULL);
+               png_read_push_finish_row(png_ptr);
+            }
+
+            if (png_ptr->pass == 4) /* Pass 3 might be empty */
+            {
+               for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+               {
+                  png_push_have_row(png_ptr, NULL);
+                  png_read_push_finish_row(png_ptr);
+               }
+            }
+
+            break;
+         }
+
+         case 3:
+         {
+            int i;
+
+            for (i = 0; i < 4 && png_ptr->pass == 3; i++)
+            {
+               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+               png_read_push_finish_row(png_ptr);
+            }
+
+            if (png_ptr->pass == 4) /* Skip top two generated rows */
+            {
+               for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+               {
+                  png_push_have_row(png_ptr, NULL);
+                  png_read_push_finish_row(png_ptr);
+               }
+            }
+
+            break;
+         }
+
+         case 4:
+         {
+            int i;
+
+            for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+            {
+               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+               png_read_push_finish_row(png_ptr);
+            }
+
+            for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+            {
+               png_push_have_row(png_ptr, NULL);
+               png_read_push_finish_row(png_ptr);
+            }
+
+            if (png_ptr->pass == 6) /* Pass 5 might be empty */
+            {
+               png_push_have_row(png_ptr, NULL);
+               png_read_push_finish_row(png_ptr);
+            }
+
+            break;
+         }
+
+         case 5:
+         {
+            int i;
+
+            for (i = 0; i < 2 && png_ptr->pass == 5; i++)
+            {
+               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+               png_read_push_finish_row(png_ptr);
+            }
+
+            if (png_ptr->pass == 6) /* Skip top generated row */
+            {
+               png_push_have_row(png_ptr, NULL);
+               png_read_push_finish_row(png_ptr);
+            }
+
+            break;
+         }
+
+         default:
+         case 6:
+         {
+            png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+            png_read_push_finish_row(png_ptr);
+
+            if (png_ptr->pass != 6)
+               break;
+
+            png_push_have_row(png_ptr, NULL);
+            png_read_push_finish_row(png_ptr);
+         }
+      }
+   }
+   else
+   {
+      png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+      png_read_push_finish_row(png_ptr);
+   }
+}
+
+void /* PRIVATE */
+png_read_push_finish_row(png_structrp png_ptr)
+{
+   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+   /* Start of interlace block */
+   static PNG_CONST png_byte png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
+
+   /* Offset to next interlace block */
+   static PNG_CONST png_byte png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
+
+   /* Start of interlace block in the y direction */
+   static PNG_CONST png_byte png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
+
+   /* Offset to next interlace block in the y direction */
+   static PNG_CONST png_byte png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
+
+   /* Height of interlace block.  This is not currently used - if you need
+    * it, uncomment it here and in png.h
+   static PNG_CONST png_byte png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
+   */
+#endif
+
+   png_ptr->row_number++;
+   if (png_ptr->row_number < png_ptr->num_rows)
+      return;
+
+   if (png_ptr->interlaced != 0)
+   {
+      png_ptr->row_number = 0;
+      memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
+
+      do
+      {
+         png_ptr->pass++;
+         if ((png_ptr->pass == 1 && png_ptr->width < 5) ||
+             (png_ptr->pass == 3 && png_ptr->width < 3) ||
+             (png_ptr->pass == 5 && png_ptr->width < 2))
+            png_ptr->pass++;
+
+         if (png_ptr->pass > 7)
+            png_ptr->pass--;
+
+         if (png_ptr->pass >= 7)
+            break;
+
+         png_ptr->iwidth = (png_ptr->width +
+             png_pass_inc[png_ptr->pass] - 1 -
+             png_pass_start[png_ptr->pass]) /
+             png_pass_inc[png_ptr->pass];
+
+         if ((png_ptr->transformations & PNG_INTERLACE) != 0)
+            break;
+
+         png_ptr->num_rows = (png_ptr->height +
+             png_pass_yinc[png_ptr->pass] - 1 -
+             png_pass_ystart[png_ptr->pass]) /
+             png_pass_yinc[png_ptr->pass];
+
+      } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
+   }
+}
+
+void /* PRIVATE */
+png_push_have_info(png_structrp png_ptr, png_inforp info_ptr)
+{
+   if (png_ptr->info_fn != NULL)
+      (*(png_ptr->info_fn))(png_ptr, info_ptr);
+}
+
+void /* PRIVATE */
+png_push_have_end(png_structrp png_ptr, png_inforp info_ptr)
+{
+   if (png_ptr->end_fn != NULL)
+      (*(png_ptr->end_fn))(png_ptr, info_ptr);
+}
+
+void /* PRIVATE */
+png_push_have_row(png_structrp png_ptr, png_bytep row)
+{
+   if (png_ptr->row_fn != NULL)
+      (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
+         (int)png_ptr->pass);
+}
+
+void PNGAPI
+png_progressive_combine_row(png_const_structrp png_ptr, png_bytep old_row,
+    png_const_bytep new_row)
+{
+   if (png_ptr == NULL)
+      return;
+
+   /* new_row is a flag here - if it is NULL then the app callback was called
+    * from an empty row (see the calls to png_struct::row_fn below), otherwise
+    * it must be png_ptr->row_buf+1
+    */
+   if (new_row != NULL)
+      png_combine_row(png_ptr, old_row, 1/*blocky display*/);
+}
+
+void PNGAPI
+png_set_progressive_read_fn(png_structrp png_ptr, png_voidp progressive_ptr,
+    png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
+    png_progressive_end_ptr end_fn)
+{
+   if (png_ptr == NULL)
+      return;
+
+   png_ptr->info_fn = info_fn;
+   png_ptr->row_fn = row_fn;
+   png_ptr->end_fn = end_fn;
+
+   png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
+}
+
+png_voidp PNGAPI
+png_get_progressive_ptr(png_const_structrp png_ptr)
+{
+   if (png_ptr == NULL)
+      return (NULL);
+
+   return png_ptr->io_ptr;
+}
+#endif /* PROGRESSIVE_READ */
diff --git a/Source/LibPNG/pngpriv.h b/Source/LibPNG/pngpriv.h
index 3863f1f..cbd66de 100644
--- a/Source/LibPNG/pngpriv.h
+++ b/Source/LibPNG/pngpriv.h
@@ -1,1675 +1,1944 @@
-
-/* pngpriv.h - private declarations for use inside libpng
- *
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1998-2012 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- *
- * Last changed in libpng 1.5.10 [March 29, 2012]
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- */
-
-/* The symbols declared in this file (including the functions declared
- * as PNG_EXTERN) are PRIVATE.  They are not part of the libpng public
- * interface, and are not recommended for use by regular applications.
- * Some of them may become public in the future; others may stay private,
- * change in an incompatible way, or even disappear.
- * Although the libpng users are not forbidden to include this header,
- * they should be well aware of the issues that may arise from doing so.
- */
-
-#ifndef PNGPRIV_H
-#define PNGPRIV_H
-
-/* Feature Test Macros.  The following are defined here to ensure that correctly
- * implemented libraries reveal the APIs libpng needs to build and hide those
- * that are not needed and potentially damaging to the compilation.
- *
- * Feature Test Macros must be defined before any system header is included (see
- * POSIX 1003.1 2.8.2 "POSIX Symbols."
- *
- * These macros only have an effect if the operating system supports either
- * POSIX 1003.1 or C99, or both.  On other operating systems (particularly
- * Windows/Visual Studio) there is no effect; the OS specific tests below are
- * still required (as of 2011-05-02.)
- */
-#define _POSIX_SOURCE 1 /* Just the POSIX 1003.1 and C89 APIs */
-
-/* This is required for the definition of abort(), used as a last ditch
- * error handler when all else fails.
- */
-#include <stdlib.h>
-
-/* This is used to find 'offsetof', used below for alignment tests. */
-#include <stddef.h>
-
-#define PNGLIB_BUILD /*libpng is being built, not used*/
-
-#ifdef PNG_USER_CONFIG
-#  include "pngusr.h"
-   /* These should have been defined in pngusr.h */
-#  ifndef PNG_USER_PRIVATEBUILD
-#    define PNG_USER_PRIVATEBUILD "Custom libpng build"
-#  endif
-#  ifndef PNG_USER_DLLFNAME_POSTFIX
-#    define PNG_USER_DLLFNAME_POSTFIX "Cb"
-#  endif
-#endif
-
-/* Is this a build of a DLL where compilation of the object modules requires
- * different preprocessor settings to those required for a simple library?  If
- * so PNG_BUILD_DLL must be set.
- *
- * If libpng is used inside a DLL but that DLL does not export the libpng APIs
- * PNG_BUILD_DLL must not be set.  To avoid the code below kicking in build a
- * static library of libpng then link the DLL against that.
- */
-#ifndef PNG_BUILD_DLL
-#  ifdef DLL_EXPORT
-      /* This is set by libtool when files are compiled for a DLL; libtool
-       * always compiles twice, even on systems where it isn't necessary.  Set
-       * PNG_BUILD_DLL in case it is necessary:
-       */
-#     define PNG_BUILD_DLL
-#  else
-#     ifdef _WINDLL
-         /* This is set by the Microsoft Visual Studio IDE in projects that
-          * build a DLL.  It can't easily be removed from those projects (it
-          * isn't visible in the Visual Studio UI) so it is a fairly reliable
-          * indication that PNG_IMPEXP needs to be set to the DLL export
-          * attributes.
-          */
-#        define PNG_BUILD_DLL
-#     else
-#        ifdef __DLL__
-            /* This is set by the Borland C system when compiling for a DLL
-             * (as above.)
-             */
-#           define PNG_BUILD_DLL
-#        else
-            /* Add additional compiler cases here. */
-#        endif
-#     endif
-#  endif
-#endif /* Setting PNG_BUILD_DLL if required */
-
-/* See pngconf.h for more details: the builder of the library may set this on
- * the command line to the right thing for the specific compilation system or it
- * may be automagically set above (at present we know of no system where it does
- * need to be set on the command line.)
- *
- * PNG_IMPEXP must be set here when building the library to prevent pngconf.h
- * setting it to the "import" setting for a DLL build.
- */
-#ifndef PNG_IMPEXP
-#  ifdef PNG_BUILD_DLL
-#     define PNG_IMPEXP PNG_DLL_EXPORT
-#  else
-      /* Not building a DLL, or the DLL doesn't require specific export
-       * definitions.
-       */
-#     define PNG_IMPEXP
-#  endif
-#endif
-
-/* No warnings for private or deprecated functions in the build: */
-#ifndef PNG_DEPRECATED
-#  define PNG_DEPRECATED
-#endif
-#ifndef PNG_PRIVATE
-#  define PNG_PRIVATE
-#endif
-
-#include "png.h"
-#include "pnginfo.h"
-#include "pngstruct.h"
-
-/* pngconf.h does not set PNG_DLL_EXPORT unless it is required, so: */
-#ifndef PNG_DLL_EXPORT
-#  define PNG_DLL_EXPORT
-#endif
-
-/* SECURITY and SAFETY:
- *
- * By default libpng is built without any internal limits on image size,
- * individual heap (png_malloc) allocations or the total amount of memory used.
- * If PNG_SAFE_LIMITS_SUPPORTED is defined, however, the limits below are used
- * (unless individually overridden).  These limits are believed to be fairly
- * safe, but builders of secure systems should verify the values against the
- * real system capabilities.
- */
-
-#ifdef PNG_SAFE_LIMITS_SUPPORTED
-   /* 'safe' limits */
-#  ifndef PNG_USER_WIDTH_MAX
-#     define PNG_USER_WIDTH_MAX 1000000
-#  endif
-#  ifndef PNG_USER_HEIGHT_MAX
-#     define PNG_USER_HEIGHT_MAX 1000000
-#  endif
-#  ifndef PNG_USER_CHUNK_CACHE_MAX
-#     define PNG_USER_CHUNK_CACHE_MAX 128
-#  endif
-#  ifndef PNG_USER_CHUNK_MALLOC_MAX
-#     define PNG_USER_CHUNK_MALLOC_MAX 8000000
-#  endif
-#else
-   /* values for no limits */
-#  ifndef PNG_USER_WIDTH_MAX
-#     define PNG_USER_WIDTH_MAX 0x7fffffff
-#  endif
-#  ifndef PNG_USER_HEIGHT_MAX
-#     define PNG_USER_HEIGHT_MAX 0x7fffffff
-#  endif
-#  ifndef PNG_USER_CHUNK_CACHE_MAX
-#     define PNG_USER_CHUNK_CACHE_MAX 0
-#  endif
-#  ifndef PNG_USER_CHUNK_MALLOC_MAX
-#     define PNG_USER_CHUNK_MALLOC_MAX 0
-#  endif
-#endif
-
-/* This is used for 16 bit gamma tables - only the top level pointers are const,
- * this could be changed:
- */
-typedef PNG_CONST png_uint_16p FAR * png_const_uint_16pp;
-
-/* Added at libpng-1.2.9 */
-/* Moved to pngpriv.h at libpng-1.5.0 */
-
-/* config.h is created by and PNG_CONFIGURE_LIBPNG is set by the "configure"
- * script.  We may need it here to get the correct configuration on things
- * like limits.
- */
-#ifdef PNG_CONFIGURE_LIBPNG
-#  ifdef HAVE_CONFIG_H
-#    include "config.h"
-#  endif
-#endif
-
-/* Moved to pngpriv.h at libpng-1.5.0 */
-/* NOTE: some of these may have been used in external applications as
- * these definitions were exposed in pngconf.h prior to 1.5.
- */
-
-/* If you are running on a machine where you cannot allocate more
- * than 64K of memory at once, uncomment this.  While libpng will not
- * normally need that much memory in a chunk (unless you load up a very
- * large file), zlib needs to know how big of a chunk it can use, and
- * libpng thus makes sure to check any memory allocation to verify it
- * will fit into memory.
- *
- * zlib provides 'MAXSEG_64K' which, if defined, indicates the
- * same limit and pngconf.h (already included) sets the limit
- * if certain operating systems are detected.
- */
-#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K)
-#  define PNG_MAX_MALLOC_64K
-#endif
-
-#ifndef PNG_UNUSED
-/* Unused formal parameter warnings are silenced using the following macro
- * which is expected to have no bad effects on performance (optimizing
- * compilers will probably remove it entirely).  Note that if you replace
- * it with something other than whitespace, you must include the terminating
- * semicolon.
- */
-#  define PNG_UNUSED(param) (void)param;
-#endif
-
-/* Just a little check that someone hasn't tried to define something
- * contradictory.
- */
-#if (PNG_ZBUF_SIZE > 65536L) && defined(PNG_MAX_MALLOC_64K)
-#  undef PNG_ZBUF_SIZE
-#  define PNG_ZBUF_SIZE 65536L
-#endif
-
-/* PNG_STATIC is used to mark internal file scope functions if they need to be
- * accessed for implementation tests (see the code in tests/?*).
- */
-#ifndef PNG_STATIC
-#   define PNG_STATIC static
-#endif
-
-/* C99 restrict is used where possible, to do this 'restrict' is defined as
- * empty if we can't be sure it is supported.  configure builds have already
- * done this work.
- */
-#ifdef PNG_CONFIGURE_LIBPNG
-#  define PNG_RESTRICT restrict
-#else
-   /* Modern compilers support restrict, but assume not for anything not
-    * recognized here:
-    */
-#  if defined __GNUC__ || defined _MSC_VER || defined __WATCOMC__
-#     define PNG_RESTRICT restrict
-#  else
-#     define PNG_RESTRICT
-#  endif
-#endif
-
-/* If warnings or errors are turned off the code is disabled or redirected here.
- * From 1.5.4 functions have been added to allow very limited formatting of
- * error and warning messages - this code will also be disabled here.
- */
-#ifdef PNG_WARNINGS_SUPPORTED
-#  define PNG_WARNING_PARAMETERS(p) png_warning_parameters p;
-#else
-#  define png_warning(s1,s2) ((void)(s1))
-#  define png_chunk_warning(s1,s2) ((void)(s1))
-#  define png_warning_parameter(p,number,string) ((void)0)
-#  define png_warning_parameter_unsigned(p,number,format,value) ((void)0)
-#  define png_warning_parameter_signed(p,number,format,value) ((void)0)
-#  define png_formatted_warning(pp,p,message) ((void)(pp))
-#  define PNG_WARNING_PARAMETERS(p)
-#endif
-#ifndef PNG_ERROR_TEXT_SUPPORTED
-#  define png_error(s1,s2) png_err(s1)
-#  define png_chunk_error(s1,s2) png_err(s1)
-#  define png_fixed_error(s1,s2) png_err(s1)
-#endif
-
-/* C allows up-casts from (void*) to any pointer and (const void*) to any
- * pointer to a const object.  C++ regards this as a type error and requires an
- * explicit, static, cast and provides the static_cast<> rune to ensure that
- * const is not cast away.
- */
-#ifdef __cplusplus
-#  define png_voidcast(type, value) static_cast<type>(value)
-#else
-#  define png_voidcast(type, value) (value)
-#endif /* __cplusplus */
-
-#ifndef PNG_EXTERN
-/* The functions exported by PNG_EXTERN are internal functions, which
- * aren't usually used outside the library (as far as I know), so it is
- * debatable if they should be exported at all.  In the future, when it
- * is possible to have run-time registry of chunk-handling functions,
- * some of these might be made available again.
- *
- * 1.5.7: turned the use of 'extern' back on, since it is localized to pngpriv.h
- * it should be safe now (it is unclear why it was turned off.)
- */
-#  define PNG_EXTERN extern
-#endif
-
-/* Some fixed point APIs are still required even if not exported because
- * they get used by the corresponding floating point APIs.  This magic
- * deals with this:
- */
-#ifdef PNG_FIXED_POINT_SUPPORTED
-#  define PNGFAPI PNGAPI
-#else
-#  define PNGFAPI /* PRIVATE */
-#endif
-
-/* Other defines specific to compilers can go here.  Try to keep
- * them inside an appropriate ifdef/endif pair for portability.
- */
-#if defined(PNG_FLOATING_POINT_SUPPORTED) ||\
-    defined(PNG_FLOATING_ARITHMETIC_SUPPORTED)
-   /* png.c requires the following ANSI-C constants if the conversion of
-    * floating point to ASCII is implemented therein:
-    *
-    *  DBL_DIG  Maximum number of decimal digits (can be set to any constant)
-    *  DBL_MIN  Smallest normalized fp number (can be set to an arbitrary value)
-    *  DBL_MAX  Maximum floating point number (can be set to an arbitrary value)
-    */
-#  include <float.h>
-
-#  if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \
-    defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC)
-     /* We need to check that <math.h> hasn't already been included earlier
-      * as it seems it doesn't agree with <fp.h>, yet we should really use
-      * <fp.h> if possible.
-      */
-#    if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__)
-#      include <fp.h>
-#    endif
-#  else
-#    include <math.h>
-#  endif
-#  if defined(_AMIGA) && defined(__SASC) && defined(_M68881)
-     /* Amiga SAS/C: We must include builtin FPU functions when compiling using
-      * MATH=68881
-      */
-#    include <m68881.h>
-#  endif
-#endif
-
-/* This provides the non-ANSI (far) memory allocation routines. */
-#if defined(__TURBOC__) && defined(__MSDOS__)
-#  include <mem.h>
-#  include <alloc.h>
-#endif
-
-#if defined(WIN32) || defined(_Windows) || defined(_WINDOWS) || \
-    defined(_WIN32) || defined(__WIN32__)
-#  include <windows.h>  /* defines _WINDOWS_ macro */
-#endif
-
-/* Moved here around 1.5.0beta36 from pngconf.h */
-/* Users may want to use these so they are not private.  Any library
- * functions that are passed far data must be model-independent.
- */
-
-/* Memory model/platform independent fns */
-#ifndef PNG_ABORT
-#  ifdef _WINDOWS_
-#    define PNG_ABORT() ExitProcess(0)
-#  else
-#    define PNG_ABORT() abort()
-#  endif
-#endif
-
-#ifdef USE_FAR_KEYWORD
-/* Use this to make far-to-near assignments */
-#  define CHECK   1
-#  define NOCHECK 0
-#  define CVT_PTR(ptr) (png_far_to_near(png_ptr,ptr,CHECK))
-#  define CVT_PTR_NOCHECK(ptr) (png_far_to_near(png_ptr,ptr,NOCHECK))
-#  define png_strlen  _fstrlen
-#  define png_memcmp  _fmemcmp    /* SJT: added */
-#  define png_memcpy  _fmemcpy
-#  define png_memset  _fmemset
-#else
-#  ifdef _WINDOWS_  /* Favor Windows over C runtime fns */
-#    define CVT_PTR(ptr)         (ptr)
-#    define CVT_PTR_NOCHECK(ptr) (ptr)
-#    define png_strlen  lstrlenA
-#    define png_memcmp  memcmp
-#    define png_memcpy  CopyMemory
-#    define png_memset  memset
-#  else
-#    define CVT_PTR(ptr)         (ptr)
-#    define CVT_PTR_NOCHECK(ptr) (ptr)
-#    define png_strlen  strlen
-#    define png_memcmp  memcmp      /* SJT: added */
-#    define png_memcpy  memcpy
-#    define png_memset  memset
-#  endif
-#endif
-
-/* These macros may need to be architecture dependent. */
-#define PNG_ALIGN_NONE   0 /* do not use data alignment */
-#define PNG_ALIGN_ALWAYS 1 /* assume unaligned accesses are OK */
-#ifdef offsetof
-#  define PNG_ALIGN_OFFSET 2 /* use offsetof to determine alignment */
-#else
-#  define PNG_ALIGN_OFFSET -1 /* prevent the use of this */
-#endif
-#define PNG_ALIGN_SIZE   3 /* use sizeof to determine alignment */
-
-#ifndef PNG_ALIGN_TYPE
-   /* Default to using aligned access optimizations and requiring alignment to a
-    * multiple of the data type size.  Override in a compiler specific fashion
-    * if necessary by inserting tests here:
-    */
-#  define PNG_ALIGN_TYPE PNG_ALIGN_SIZE
-#endif
-
-#if PNG_ALIGN_TYPE == PNG_ALIGN_SIZE
-   /* This is used because in some compiler implementations non-aligned
-    * structure members are supported, so the offsetof approach below fails.
-    * Set PNG_ALIGN_TO_SIZE=0 for compiler combinations where unaligned access
-    * is good for performance.  Do not do this unless you have tested the result
-    * and understand it.
-    */
-#  define png_alignof(type) (sizeof (type))
-#else
-#  if PNG_ALIGN_TYPE == PNG_ALIGN_OFFSET
-#     define png_alignof(type) offsetof(struct{char c; type t;}, t)
-#  else
-#     if PNG_ALIGN_TYPE == PNG_ALIGN_ALWAYS
-#        define png_alignof(type) (1)
-#     endif
-      /* Else leave png_alignof undefined to prevent use thereof */
-#  endif
-#endif
-
-/* This implicitly assumes alignment is always to a power of 2. */
-#ifdef png_alignof
-#  define png_isaligned(ptr, type)\
-   ((((const char*)ptr-(const char*)0) & (png_alignof(type)-1)) == 0)
-#else
-#  define png_isaligned(ptr, type) 0
-#endif
-
-/* End of memory model/platform independent support */
-/* End of 1.5.0beta36 move from pngconf.h */
-
-/* CONSTANTS and UTILITY MACROS
- * These are used internally by libpng and not exposed in the API
- */
-
-/* Various modes of operation.  Note that after an init, mode is set to
- * zero automatically when the structure is created.  Three of these
- * are defined in png.h because they need to be visible to applications
- * that call png_set_unknown_chunk().
- */
-/* #define PNG_HAVE_IHDR            0x01 (defined in png.h) */
-/* #define PNG_HAVE_PLTE            0x02 (defined in png.h) */
-#define PNG_HAVE_IDAT               0x04
-/* #define PNG_AFTER_IDAT           0x08 (defined in png.h) */
-#define PNG_HAVE_IEND               0x10
-#define PNG_HAVE_gAMA               0x20
-#define PNG_HAVE_cHRM               0x40
-#define PNG_HAVE_sRGB               0x80
-#define PNG_HAVE_CHUNK_HEADER      0x100
-#define PNG_WROTE_tIME             0x200
-#define PNG_WROTE_INFO_BEFORE_PLTE 0x400
-#define PNG_BACKGROUND_IS_GRAY     0x800
-#define PNG_HAVE_PNG_SIGNATURE    0x1000
-#define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000 /* Have another chunk after IDAT */
-#define PNG_HAVE_iCCP             0x4000
-
-/* Flags for the transformations the PNG library does on the image data */
-#define PNG_BGR                 0x0001
-#define PNG_INTERLACE           0x0002
-#define PNG_PACK                0x0004
-#define PNG_SHIFT               0x0008
-#define PNG_SWAP_BYTES          0x0010
-#define PNG_INVERT_MONO         0x0020
-#define PNG_QUANTIZE            0x0040
-#define PNG_COMPOSE             0x0080     /* Was PNG_BACKGROUND */
-#define PNG_BACKGROUND_EXPAND   0x0100
-#define PNG_EXPAND_16           0x0200     /* Added to libpng 1.5.2 */
-#define PNG_16_TO_8             0x0400     /* Becomes 'chop' in 1.5.4 */
-#define PNG_RGBA                0x0800
-#define PNG_EXPAND              0x1000
-#define PNG_GAMMA               0x2000
-#define PNG_GRAY_TO_RGB         0x4000
-#define PNG_FILLER              0x8000
-#define PNG_PACKSWAP           0x10000
-#define PNG_SWAP_ALPHA         0x20000
-#define PNG_STRIP_ALPHA        0x40000
-#define PNG_INVERT_ALPHA       0x80000
-#define PNG_USER_TRANSFORM    0x100000
-#define PNG_RGB_TO_GRAY_ERR   0x200000
-#define PNG_RGB_TO_GRAY_WARN  0x400000
-#define PNG_RGB_TO_GRAY       0x600000 /* two bits, RGB_TO_GRAY_ERR|WARN */
-#define PNG_ENCODE_ALPHA      0x800000 /* Added to libpng-1.5.4 */
-#define PNG_ADD_ALPHA         0x1000000 /* Added to libpng-1.2.7 */
-#define PNG_EXPAND_tRNS       0x2000000 /* Added to libpng-1.2.9 */
-#define PNG_SCALE_16_TO_8     0x4000000 /* Added to libpng-1.5.4 */
-                       /*   0x8000000 unused */
-                       /*  0x10000000 unused */
-                       /*  0x20000000 unused */
-                       /*  0x40000000 unused */
-/* Flags for png_create_struct */
-#define PNG_STRUCT_PNG   0x0001
-#define PNG_STRUCT_INFO  0x0002
-
-/* Scaling factor for filter heuristic weighting calculations */
-#define PNG_WEIGHT_FACTOR (1<<(PNG_WEIGHT_SHIFT))
-#define PNG_COST_FACTOR (1<<(PNG_COST_SHIFT))
-
-/* Flags for the png_ptr->flags rather than declaring a byte for each one */
-#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY     0x0001
-#define PNG_FLAG_ZLIB_CUSTOM_LEVEL        0x0002
-#define PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL    0x0004
-#define PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS  0x0008
-#define PNG_FLAG_ZLIB_CUSTOM_METHOD       0x0010
-#define PNG_FLAG_ZLIB_FINISHED            0x0020
-#define PNG_FLAG_ROW_INIT                 0x0040
-#define PNG_FLAG_FILLER_AFTER             0x0080
-#define PNG_FLAG_CRC_ANCILLARY_USE        0x0100
-#define PNG_FLAG_CRC_ANCILLARY_NOWARN     0x0200
-#define PNG_FLAG_CRC_CRITICAL_USE         0x0400
-#define PNG_FLAG_CRC_CRITICAL_IGNORE      0x0800
-#define PNG_FLAG_ASSUME_sRGB              0x1000  /* Added to libpng-1.5.4 */
-#define PNG_FLAG_OPTIMIZE_ALPHA           0x2000  /* Added to libpng-1.5.4 */
-#define PNG_FLAG_DETECT_UNINITIALIZED     0x4000  /* Added to libpng-1.5.4 */
-#define PNG_FLAG_KEEP_UNKNOWN_CHUNKS      0x8000
-#define PNG_FLAG_KEEP_UNSAFE_CHUNKS       0x10000
-#define PNG_FLAG_LIBRARY_MISMATCH         0x20000
-#define PNG_FLAG_STRIP_ERROR_NUMBERS      0x40000
-#define PNG_FLAG_STRIP_ERROR_TEXT         0x80000
-#define PNG_FLAG_MALLOC_NULL_MEM_OK       0x100000
-                                  /*      0x200000  unused */
-                                  /*      0x400000  unused */
-#define PNG_FLAG_BENIGN_ERRORS_WARN       0x800000  /* Added to libpng-1.4.0 */
-#define PNG_FLAG_ZTXT_CUSTOM_STRATEGY    0x1000000  /* 5 lines added */
-#define PNG_FLAG_ZTXT_CUSTOM_LEVEL       0x2000000  /* to libpng-1.5.4 */
-#define PNG_FLAG_ZTXT_CUSTOM_MEM_LEVEL   0x4000000
-#define PNG_FLAG_ZTXT_CUSTOM_WINDOW_BITS 0x8000000
-#define PNG_FLAG_ZTXT_CUSTOM_METHOD      0x10000000
-                                  /*     0x20000000  unused */
-                                  /*     0x40000000  unused */
-
-#define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \
-                                     PNG_FLAG_CRC_ANCILLARY_NOWARN)
-
-#define PNG_FLAG_CRC_CRITICAL_MASK  (PNG_FLAG_CRC_CRITICAL_USE | \
-                                     PNG_FLAG_CRC_CRITICAL_IGNORE)
-
-#define PNG_FLAG_CRC_MASK           (PNG_FLAG_CRC_ANCILLARY_MASK | \
-                                     PNG_FLAG_CRC_CRITICAL_MASK)
-
-/* zlib.h declares a magic type 'uInt' that limits the amount of data that zlib
- * can handle at once.  This type need be no larger than 16 bits (so maximum of
- * 65535), this define allows us to discover how big it is, but limited by the
- * maximuum for png_size_t.  The value can be overriden in a library build
- * (pngusr.h, or set it in CPPFLAGS) and it works to set it to a considerably
- * lower value (e.g. 255 works).  A lower value may help memory usage (slightly)
- * and may even improve performance on some systems (and degrade it on others.)
- */
-#ifndef ZLIB_IO_MAX
-#  define ZLIB_IO_MAX ((uInt)-1)
-#endif
-
-/* Save typing and make code easier to understand */
-
-#define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \
-   abs((int)((c1).green) - (int)((c2).green)) + \
-   abs((int)((c1).blue) - (int)((c2).blue)))
-
-/* Added to libpng-1.2.6 JB */
-#define PNG_ROWBYTES(pixel_bits, width) \
-    ((pixel_bits) >= 8 ? \
-    ((png_size_t)(width) * (((png_size_t)(pixel_bits)) >> 3)) : \
-    (( ((png_size_t)(width) * ((png_size_t)(pixel_bits))) + 7) >> 3) )
-
-/* PNG_OUT_OF_RANGE returns true if value is outside the range
- * ideal-delta..ideal+delta.  Each argument is evaluated twice.
- * "ideal" and "delta" should be constants, normally simple
- * integers, "value" a variable. Added to libpng-1.2.6 JB
- */
-#define PNG_OUT_OF_RANGE(value, ideal, delta) \
-   ( (value) < (ideal)-(delta) || (value) > (ideal)+(delta) )
-
-/* Conversions between fixed and floating point, only defined if
- * required (to make sure the code doesn't accidentally use float
- * when it is supposedly disabled.)
- */
-#ifdef PNG_FLOATING_POINT_SUPPORTED
-/* The floating point conversion can't overflow, though it can and
- * does lose accuracy relative to the original fixed point value.
- * In practice this doesn't matter because png_fixed_point only
- * stores numbers with very low precision.  The png_ptr and s
- * arguments are unused by default but are there in case error
- * checking becomes a requirement.
- */
-#define png_float(png_ptr, fixed, s) (.00001 * (fixed))
-
-/* The fixed point conversion performs range checking and evaluates
- * its argument multiple times, so must be used with care.  The
- * range checking uses the PNG specification values for a signed
- * 32 bit fixed point value except that the values are deliberately
- * rounded-to-zero to an integral value - 21474 (21474.83 is roughly
- * (2^31-1) * 100000). 's' is a string that describes the value being
- * converted.
- *
- * NOTE: this macro will raise a png_error if the range check fails,
- * therefore it is normally only appropriate to use this on values
- * that come from API calls or other sources where an out of range
- * error indicates a programming error, not a data error!
- *
- * NOTE: by default this is off - the macro is not used - because the
- * function call saves a lot of code.
- */
-#ifdef PNG_FIXED_POINT_MACRO_SUPPORTED
-#define png_fixed(png_ptr, fp, s) ((fp) <= 21474 && (fp) >= -21474 ?\
-    ((png_fixed_point)(100000 * (fp))) : (png_fixed_error(png_ptr, s),0))
-#else
-PNG_EXTERN png_fixed_point png_fixed PNGARG((png_structp png_ptr, double fp,
-   png_const_charp text));
-#endif
-#endif
-
-/* Constants for known chunk types.  If you need to add a chunk, define the name
- * here.  For historical reasons these constants have the form png_<name>; i.e.
- * the prefix is lower case.  Please use decimal values as the parameters to
- * match the ISO PNG specification and to avoid relying on the C locale
- * interpretation of character values.
- *
- * Prior to 1.5.6 these constants were strings, as of 1.5.6 png_uint_32 values
- * are computed and a new macro (PNG_STRING_FROM_CHUNK) added to allow a string
- * to be generated if required.
- *
- * PNG_32b correctly produces a value shifted by up to 24 bits, even on
- * architectures where (int) is only 16 bits.
- */
-#define PNG_32b(b,s) ((png_uint_32)(b) << (s))
-#define PNG_CHUNK(b1,b2,b3,b4) \
-   (PNG_32b(b1,24) | PNG_32b(b2,16) | PNG_32b(b3,8) | PNG_32b(b4,0))
-
-#define png_IHDR PNG_CHUNK( 73,  72,  68,  82)
-#define png_IDAT PNG_CHUNK( 73,  68,  65,  84)
-#define png_IEND PNG_CHUNK( 73,  69,  78,  68)
-#define png_PLTE PNG_CHUNK( 80,  76,  84,  69)
-#define png_bKGD PNG_CHUNK( 98,  75,  71,  68)
-#define png_cHRM PNG_CHUNK( 99,  72,  82,  77)
-#define png_gAMA PNG_CHUNK(103,  65,  77,  65)
-#define png_hIST PNG_CHUNK(104,  73,  83,  84)
-#define png_iCCP PNG_CHUNK(105,  67,  67,  80)
-#define png_iTXt PNG_CHUNK(105,  84,  88, 116)
-#define png_oFFs PNG_CHUNK(111,  70,  70, 115)
-#define png_pCAL PNG_CHUNK(112,  67,  65,  76)
-#define png_sCAL PNG_CHUNK(115,  67,  65,  76)
-#define png_pHYs PNG_CHUNK(112,  72,  89, 115)
-#define png_sBIT PNG_CHUNK(115,  66,  73,  84)
-#define png_sPLT PNG_CHUNK(115,  80,  76,  84)
-#define png_sRGB PNG_CHUNK(115,  82,  71,  66)
-#define png_sTER PNG_CHUNK(115,  84,  69,  82)
-#define png_tEXt PNG_CHUNK(116,  69,  88, 116)
-#define png_tIME PNG_CHUNK(116,  73,  77,  69)
-#define png_tRNS PNG_CHUNK(116,  82,  78,  83)
-#define png_zTXt PNG_CHUNK(122,  84,  88, 116)
-
-/* The following will work on (signed char*) strings, whereas the get_uint_32
- * macro will fail on top-bit-set values because of the sign extension.
- */
-#define PNG_CHUNK_FROM_STRING(s)\
-   PNG_CHUNK(0xff&(s)[0], 0xff&(s)[1], 0xff&(s)[2], 0xff&(s)[3])
-
-/* This uses (char), not (png_byte) to avoid warnings on systems where (char) is
- * signed and the argument is a (char[])  This macro will fail miserably on
- * systems where (char) is more than 8 bits.
- */
-#define PNG_STRING_FROM_CHUNK(s,c)\
-   (void)(((char*)(s))[0]=(char)((c)>>24), ((char*)(s))[1]=(char)((c)>>16),\
-   ((char*)(s))[2]=(char)((c)>>8), ((char*)(s))[3]=(char)((c)))
-
-/* Do the same but terminate with a null character. */
-#define PNG_CSTRING_FROM_CHUNK(s,c)\
-   (void)(PNG_STRING_FROM_CHUNK(s,c), ((char*)(s))[4] = 0)
-
-/* Test on flag values as defined in the spec (section 5.4): */
-#define PNG_CHUNK_ANCILLIARY(c)   (1 & ((c) >> 29))
-#define PNG_CHUNK_CRITICAL(c)     (!PNG_CHUNK_ANCILLIARY(c))
-#define PNG_CHUNK_PRIVATE(c)      (1 & ((c) >> 21))
-#define PNG_CHUNK_RESERVED(c)     (1 & ((c) >> 13))
-#define PNG_CHUNK_SAFE_TO_COPY(c) (1 & ((c) >>  5))
-
-/* Gamma values (new at libpng-1.5.4): */
-#define PNG_GAMMA_MAC_OLD 151724  /* Assume '1.8' is really 2.2/1.45! */
-#define PNG_GAMMA_MAC_INVERSE 65909
-#define PNG_GAMMA_sRGB_INVERSE 45455
-
-
-/* Inhibit C++ name-mangling for libpng functions but not for system calls. */
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-/* These functions are used internally in the code.  They generally
- * shouldn't be used unless you are writing code to add or replace some
- * functionality in libpng.  More information about most functions can
- * be found in the files where the functions are located.
- */
-
-/* Check the user version string for compatibility, returns false if the version
- * numbers aren't compatible.
- */
-PNG_EXTERN int png_user_version_check(png_structp png_ptr,
-   png_const_charp user_png_ver);
-
-/* Allocate memory for an internal libpng struct */
-PNG_EXTERN PNG_FUNCTION(png_voidp,png_create_struct,PNGARG((int type)),
-   PNG_ALLOCATED);
-
-/* Free memory from internal libpng struct */
-PNG_EXTERN void png_destroy_struct PNGARG((png_voidp struct_ptr));
-
-PNG_EXTERN PNG_FUNCTION(png_voidp,png_create_struct_2,
-   PNGARG((int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)),
-   PNG_ALLOCATED);
-PNG_EXTERN void png_destroy_struct_2 PNGARG((png_voidp struct_ptr,
-    png_free_ptr free_fn, png_voidp mem_ptr));
-
-/* Free any memory that info_ptr points to and reset struct. */
-PNG_EXTERN void png_info_destroy PNGARG((png_structp png_ptr,
-    png_infop info_ptr));
-
-/* Function to allocate memory for zlib.  PNGAPI is disallowed. */
-PNG_EXTERN PNG_FUNCTION(voidpf,png_zalloc,PNGARG((voidpf png_ptr, uInt items,
-   uInt size)),PNG_ALLOCATED);
-
-/* Function to free memory for zlib.  PNGAPI is disallowed. */
-PNG_EXTERN void png_zfree PNGARG((voidpf png_ptr, voidpf ptr));
-
-/* Next four functions are used internally as callbacks.  PNGCBAPI is required
- * but not PNG_EXPORT.  PNGAPI added at libpng version 1.2.3, changed to
- * PNGCBAPI at 1.5.0
- */
-
-PNG_EXTERN void PNGCBAPI png_default_read_data PNGARG((png_structp png_ptr,
-    png_bytep data, png_size_t length));
-
-#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
-PNG_EXTERN void PNGCBAPI png_push_fill_buffer PNGARG((png_structp png_ptr,
-    png_bytep buffer, png_size_t length));
-#endif
-
-PNG_EXTERN void PNGCBAPI png_default_write_data PNGARG((png_structp png_ptr,
-    png_bytep data, png_size_t length));
-
-#ifdef PNG_WRITE_FLUSH_SUPPORTED
-#  ifdef PNG_STDIO_SUPPORTED
-PNG_EXTERN void PNGCBAPI png_default_flush PNGARG((png_structp png_ptr));
-#  endif
-#endif
-
-/* Reset the CRC variable */
-PNG_EXTERN void png_reset_crc PNGARG((png_structp png_ptr));
-
-/* Write the "data" buffer to whatever output you are using */
-PNG_EXTERN void png_write_data PNGARG((png_structp png_ptr,
-    png_const_bytep data, png_size_t length));
-
-/* Read and check the PNG file signature */
-PNG_EXTERN void png_read_sig PNGARG((png_structp png_ptr, png_infop info_ptr));
-
-/* Read the chunk header (length + type name) */
-PNG_EXTERN png_uint_32 png_read_chunk_header PNGARG((png_structp png_ptr));
-
-/* Read data from whatever input you are using into the "data" buffer */
-PNG_EXTERN void png_read_data PNGARG((png_structp png_ptr, png_bytep data,
-    png_size_t length));
-
-/* Read bytes into buf, and update png_ptr->crc */
-PNG_EXTERN void png_crc_read PNGARG((png_structp png_ptr, png_bytep buf,
-    png_size_t length));
-
-/* Decompress data in a chunk that uses compression */
-#if defined(PNG_READ_COMPRESSED_TEXT_SUPPORTED)
-PNG_EXTERN void png_decompress_chunk PNGARG((png_structp png_ptr,
-    int comp_type, png_size_t chunklength, png_size_t prefix_length,
-    png_size_t *data_length));
-#endif
-
-/* Read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */
-PNG_EXTERN int png_crc_finish PNGARG((png_structp png_ptr, png_uint_32 skip));
-
-/* Read the CRC from the file and compare it to the libpng calculated CRC */
-PNG_EXTERN int png_crc_error PNGARG((png_structp png_ptr));
-
-/* Calculate the CRC over a section of data.  Note that we are only
- * passing a maximum of 64K on systems that have this as a memory limit,
- * since this is the maximum buffer size we can specify.
- */
-PNG_EXTERN void png_calculate_crc PNGARG((png_structp png_ptr,
-    png_const_bytep ptr, png_size_t length));
-
-#ifdef PNG_WRITE_FLUSH_SUPPORTED
-PNG_EXTERN void png_flush PNGARG((png_structp png_ptr));
-#endif
-
-/* Write various chunks */
-
-/* Write the IHDR chunk, and update the png_struct with the necessary
- * information.
- */
-PNG_EXTERN void png_write_IHDR PNGARG((png_structp png_ptr, png_uint_32 width,
-    png_uint_32 height,
-    int bit_depth, int color_type, int compression_method, int filter_method,
-    int interlace_method));
-
-PNG_EXTERN void png_write_PLTE PNGARG((png_structp png_ptr,
-    png_const_colorp palette, png_uint_32 num_pal));
-
-PNG_EXTERN void png_write_IDAT PNGARG((png_structp png_ptr, png_bytep data,
-    png_size_t length));
-
-PNG_EXTERN void png_write_IEND PNGARG((png_structp png_ptr));
-
-#ifdef PNG_WRITE_gAMA_SUPPORTED
-#  ifdef PNG_FLOATING_POINT_SUPPORTED
-PNG_EXTERN void png_write_gAMA PNGARG((png_structp png_ptr, double file_gamma));
-#  endif
-#  ifdef PNG_FIXED_POINT_SUPPORTED
-PNG_EXTERN void png_write_gAMA_fixed PNGARG((png_structp png_ptr,
-    png_fixed_point file_gamma));
-#  endif
-#endif
-
-#ifdef PNG_WRITE_sBIT_SUPPORTED
-PNG_EXTERN void png_write_sBIT PNGARG((png_structp png_ptr,
-    png_const_color_8p sbit, int color_type));
-#endif
-
-#ifdef PNG_WRITE_cHRM_SUPPORTED
-#  ifdef PNG_FLOATING_POINT_SUPPORTED
-PNG_EXTERN void png_write_cHRM PNGARG((png_structp png_ptr,
-    double white_x, double white_y,
-    double red_x, double red_y, double green_x, double green_y,
-    double blue_x, double blue_y));
-#  endif
-PNG_EXTERN void png_write_cHRM_fixed PNGARG((png_structp png_ptr,
-    png_fixed_point int_white_x, png_fixed_point int_white_y,
-    png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point
-    int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x,
-    png_fixed_point int_blue_y));
-#endif
-
-#ifdef PNG_WRITE_sRGB_SUPPORTED
-PNG_EXTERN void png_write_sRGB PNGARG((png_structp png_ptr,
-    int intent));
-#endif
-
-#ifdef PNG_WRITE_iCCP_SUPPORTED
-PNG_EXTERN void png_write_iCCP PNGARG((png_structp png_ptr,
-    png_const_charp name, int compression_type,
-    png_const_charp profile, int proflen));
-   /* Note to maintainer: profile should be png_bytep */
-#endif
-
-#ifdef PNG_WRITE_sPLT_SUPPORTED
-PNG_EXTERN void png_write_sPLT PNGARG((png_structp png_ptr,
-    png_const_sPLT_tp palette));
-#endif
-
-#ifdef PNG_WRITE_tRNS_SUPPORTED
-PNG_EXTERN void png_write_tRNS PNGARG((png_structp png_ptr,
-    png_const_bytep trans, png_const_color_16p values, int number,
-    int color_type));
-#endif
-
-#ifdef PNG_WRITE_bKGD_SUPPORTED
-PNG_EXTERN void png_write_bKGD PNGARG((png_structp png_ptr,
-    png_const_color_16p values, int color_type));
-#endif
-
-#ifdef PNG_WRITE_hIST_SUPPORTED
-PNG_EXTERN void png_write_hIST PNGARG((png_structp png_ptr,
-    png_const_uint_16p hist, int num_hist));
-#endif
-
-/* Chunks that have keywords */
-#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \
-    defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
-PNG_EXTERN png_size_t png_check_keyword PNGARG((png_structp png_ptr,
-    png_const_charp key, png_charpp new_key));
-#endif
-
-#ifdef PNG_WRITE_tEXt_SUPPORTED
-PNG_EXTERN void png_write_tEXt PNGARG((png_structp png_ptr, png_const_charp key,
-    png_const_charp text, png_size_t text_len));
-#endif
-
-#ifdef PNG_WRITE_zTXt_SUPPORTED
-PNG_EXTERN void png_write_zTXt PNGARG((png_structp png_ptr, png_const_charp key,
-    png_const_charp text, png_size_t text_len, int compression));
-#endif
-
-#ifdef PNG_WRITE_iTXt_SUPPORTED
-PNG_EXTERN void png_write_iTXt PNGARG((png_structp png_ptr,
-    int compression, png_const_charp key, png_const_charp lang,
-    png_const_charp lang_key, png_const_charp text));
-#endif
-
-#ifdef PNG_TEXT_SUPPORTED  /* Added at version 1.0.14 and 1.2.4 */
-PNG_EXTERN int png_set_text_2 PNGARG((png_structp png_ptr,
-    png_infop info_ptr, png_const_textp text_ptr, int num_text));
-#endif
-
-#ifdef PNG_WRITE_oFFs_SUPPORTED
-PNG_EXTERN void png_write_oFFs PNGARG((png_structp png_ptr,
-    png_int_32 x_offset, png_int_32 y_offset, int unit_type));
-#endif
-
-#ifdef PNG_WRITE_pCAL_SUPPORTED
-PNG_EXTERN void png_write_pCAL PNGARG((png_structp png_ptr, png_charp purpose,
-    png_int_32 X0, png_int_32 X1, int type, int nparams,
-    png_const_charp units, png_charpp params));
-#endif
-
-#ifdef PNG_WRITE_pHYs_SUPPORTED
-PNG_EXTERN void png_write_pHYs PNGARG((png_structp png_ptr,
-    png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit,
-    int unit_type));
-#endif
-
-#ifdef PNG_WRITE_tIME_SUPPORTED
-PNG_EXTERN void png_write_tIME PNGARG((png_structp png_ptr,
-    png_const_timep mod_time));
-#endif
-
-#ifdef PNG_WRITE_sCAL_SUPPORTED
-PNG_EXTERN void png_write_sCAL_s PNGARG((png_structp png_ptr,
-    int unit, png_const_charp width, png_const_charp height));
-#endif
-
-/* Called when finished processing a row of data */
-PNG_EXTERN void png_write_finish_row PNGARG((png_structp png_ptr));
-
-/* Internal use only.   Called before first row of data */
-PNG_EXTERN void png_write_start_row PNGARG((png_structp png_ptr));
-
-/* Combine a row of data, dealing with alpha, etc. if requested.  'row' is an
- * array of png_ptr->width pixels.  If the image is not interlaced or this
- * is the final pass this just does a png_memcpy, otherwise the "display" flag
- * is used to determine whether to copy pixels that are not in the current pass.
- *
- * Because 'png_do_read_interlace' (below) replicates pixels this allows this
- * function to achieve the documented 'blocky' appearance during interlaced read
- * if display is 1 and the 'sparkle' appearance, where existing pixels in 'row'
- * are not changed if they are not in the current pass, when display is 0.
- *
- * 'display' must be 0 or 1, otherwise the memcpy will be done regardless.
- *
- * The API always reads from the png_struct row buffer and always assumes that
- * it is full width (png_do_read_interlace has already been called.)
- *
- * This function is only ever used to write to row buffers provided by the
- * caller of the relevant libpng API and the row must have already been
- * transformed by the read transformations.
- *
- * The PNG_USE_COMPILE_TIME_MASKS option causes generation of pre-computed
- * bitmasks for use within the code, otherwise runtime generated masks are used.
- * The default is compile time masks.
- */
-#ifndef PNG_USE_COMPILE_TIME_MASKS
-#  define PNG_USE_COMPILE_TIME_MASKS 1
-#endif
-PNG_EXTERN void png_combine_row PNGARG((png_structp png_ptr, png_bytep row,
-    int display));
-
-#ifdef PNG_READ_INTERLACING_SUPPORTED
-/* Expand an interlaced row: the 'row_info' describes the pass data that has
- * been read in and must correspond to the pixels in 'row', the pixels are
- * expanded (moved apart) in 'row' to match the final layout, when doing this
- * the pixels are *replicated* to the intervening space.  This is essential for
- * the correct operation of png_combine_row, above.
- */
-PNG_EXTERN void png_do_read_interlace PNGARG((png_row_infop row_info,
-    png_bytep row, int pass, png_uint_32 transformations));
-#endif
-
-/* GRR TO DO (2.0 or whenever):  simplify other internal calling interfaces */
-
-#ifdef PNG_WRITE_INTERLACING_SUPPORTED
-/* Grab pixels out of a row for an interlaced pass */
-PNG_EXTERN void png_do_write_interlace PNGARG((png_row_infop row_info,
-    png_bytep row, int pass));
-#endif
-
-/* Unfilter a row: check the filter value before calling this, there is no point
- * calling it for PNG_FILTER_VALUE_NONE.
- */
-PNG_EXTERN void png_read_filter_row PNGARG((png_structp pp, png_row_infop
-    row_info, png_bytep row, png_const_bytep prev_row, int filter));
-
-PNG_EXTERN void png_read_filter_row_up_neon PNGARG((png_row_infop row_info,
-    png_bytep row, png_const_bytep prev_row));
-PNG_EXTERN void png_read_filter_row_sub3_neon PNGARG((png_row_infop row_info,
-    png_bytep row, png_const_bytep prev_row));
-PNG_EXTERN void png_read_filter_row_sub4_neon PNGARG((png_row_infop row_info,
-    png_bytep row, png_const_bytep prev_row));
-PNG_EXTERN void png_read_filter_row_avg3_neon PNGARG((png_row_infop row_info,
-    png_bytep row, png_const_bytep prev_row));
-PNG_EXTERN void png_read_filter_row_avg4_neon PNGARG((png_row_infop row_info,
-    png_bytep row, png_const_bytep prev_row));
-PNG_EXTERN void png_read_filter_row_paeth3_neon PNGARG((png_row_infop row_info,
-    png_bytep row, png_const_bytep prev_row));
-PNG_EXTERN void png_read_filter_row_paeth4_neon PNGARG((png_row_infop row_info,
-    png_bytep row, png_const_bytep prev_row));
-
-/* Choose the best filter to use and filter the row data */
-PNG_EXTERN void png_write_find_filter PNGARG((png_structp png_ptr,
-    png_row_infop row_info));
-
-/* Finish a row while reading, dealing with interlacing passes, etc. */
-PNG_EXTERN void png_read_finish_row PNGARG((png_structp png_ptr));
-
-/* Initialize the row buffers, etc. */
-PNG_EXTERN void png_read_start_row PNGARG((png_structp png_ptr));
-
-#ifdef PNG_READ_TRANSFORMS_SUPPORTED
-/* Optional call to update the users info structure */
-PNG_EXTERN void png_read_transform_info PNGARG((png_structp png_ptr,
-    png_infop info_ptr));
-#endif
-
-/* These are the functions that do the transformations */
-#ifdef PNG_READ_FILLER_SUPPORTED
-PNG_EXTERN void png_do_read_filler PNGARG((png_row_infop row_info,
-    png_bytep row, png_uint_32 filler, png_uint_32 flags));
-#endif
-
-#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
-PNG_EXTERN void png_do_read_swap_alpha PNGARG((png_row_infop row_info,
-    png_bytep row));
-#endif
-
-#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
-PNG_EXTERN void png_do_write_swap_alpha PNGARG((png_row_infop row_info,
-    png_bytep row));
-#endif
-
-#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
-PNG_EXTERN void png_do_read_invert_alpha PNGARG((png_row_infop row_info,
-    png_bytep row));
-#endif
-
-#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
-PNG_EXTERN void png_do_write_invert_alpha PNGARG((png_row_infop row_info,
-    png_bytep row));
-#endif
-
-#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
-    defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
-PNG_EXTERN void png_do_strip_channel PNGARG((png_row_infop row_info,
-    png_bytep row, int at_start));
-#endif
-
-#ifdef PNG_16BIT_SUPPORTED
-#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
-PNG_EXTERN void png_do_swap PNGARG((png_row_infop row_info,
-    png_bytep row));
-#endif
-#endif
-
-#if defined(PNG_READ_PACKSWAP_SUPPORTED) || \
-    defined(PNG_WRITE_PACKSWAP_SUPPORTED)
-PNG_EXTERN void png_do_packswap PNGARG((png_row_infop row_info,
-    png_bytep row));
-#endif
-
-#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
-PNG_EXTERN int png_do_rgb_to_gray PNGARG((png_structp png_ptr,
-    png_row_infop row_info, png_bytep row));
-#endif
-
-#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
-PNG_EXTERN void png_do_gray_to_rgb PNGARG((png_row_infop row_info,
-    png_bytep row));
-#endif
-
-#ifdef PNG_READ_PACK_SUPPORTED
-PNG_EXTERN void png_do_unpack PNGARG((png_row_infop row_info,
-    png_bytep row));
-#endif
-
-#ifdef PNG_READ_SHIFT_SUPPORTED
-PNG_EXTERN void png_do_unshift PNGARG((png_row_infop row_info,
-    png_bytep row, png_const_color_8p sig_bits));
-#endif
-
-#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
-PNG_EXTERN void png_do_invert PNGARG((png_row_infop row_info,
-    png_bytep row));
-#endif
-
-#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
-PNG_EXTERN void png_do_scale_16_to_8 PNGARG((png_row_infop row_info,
-    png_bytep row));
-#endif
-
-#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
-PNG_EXTERN void png_do_chop PNGARG((png_row_infop row_info,
-    png_bytep row));
-#endif
-
-#ifdef PNG_READ_QUANTIZE_SUPPORTED
-PNG_EXTERN void png_do_quantize PNGARG((png_row_infop row_info,
-    png_bytep row, png_const_bytep palette_lookup,
-    png_const_bytep quantize_lookup));
-
-#  ifdef PNG_CORRECT_PALETTE_SUPPORTED
-PNG_EXTERN void png_correct_palette PNGARG((png_structp png_ptr,
-    png_colorp palette, int num_palette));
-#  endif
-#endif
-
-#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
-PNG_EXTERN void png_do_bgr PNGARG((png_row_infop row_info,
-    png_bytep row));
-#endif
-
-#ifdef PNG_WRITE_PACK_SUPPORTED
-PNG_EXTERN void png_do_pack PNGARG((png_row_infop row_info,
-   png_bytep row, png_uint_32 bit_depth));
-#endif
-
-#ifdef PNG_WRITE_SHIFT_SUPPORTED
-PNG_EXTERN void png_do_shift PNGARG((png_row_infop row_info,
-    png_bytep row, png_const_color_8p bit_depth));
-#endif
-
-#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
-    defined(PNG_READ_ALPHA_MODE_SUPPORTED)
-PNG_EXTERN void png_do_compose PNGARG((png_row_infop row_info,
-    png_bytep row, png_structp png_ptr));
-#endif
-
-#ifdef PNG_READ_GAMMA_SUPPORTED
-PNG_EXTERN void png_do_gamma PNGARG((png_row_infop row_info,
-    png_bytep row, png_structp png_ptr));
-#endif
-
-#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
-PNG_EXTERN void png_do_encode_alpha PNGARG((png_row_infop row_info,
-   png_bytep row, png_structp png_ptr));
-#endif
-
-#ifdef PNG_READ_EXPAND_SUPPORTED
-PNG_EXTERN void png_do_expand_palette PNGARG((png_row_infop row_info,
-    png_bytep row, png_const_colorp palette, png_const_bytep trans,
-    int num_trans));
-PNG_EXTERN void png_do_expand PNGARG((png_row_infop row_info,
-    png_bytep row, png_const_color_16p trans_color));
-#endif
-
-#ifdef PNG_READ_EXPAND_16_SUPPORTED
-PNG_EXTERN void png_do_expand_16 PNGARG((png_row_infop row_info,
-    png_bytep row));
-#endif
-
-/* The following decodes the appropriate chunks, and does error correction,
- * then calls the appropriate callback for the chunk if it is valid.
- */
-
-/* Decode the IHDR chunk */
-PNG_EXTERN void png_handle_IHDR PNGARG((png_structp png_ptr, png_infop info_ptr,
-    png_uint_32 length));
-PNG_EXTERN void png_handle_PLTE PNGARG((png_structp png_ptr, png_infop info_ptr,
-    png_uint_32 length));
-PNG_EXTERN void png_handle_IEND PNGARG((png_structp png_ptr, png_infop info_ptr,
-    png_uint_32 length));
-
-#ifdef PNG_READ_bKGD_SUPPORTED
-PNG_EXTERN void png_handle_bKGD PNGARG((png_structp png_ptr, png_infop info_ptr,
-    png_uint_32 length));
-#endif
-
-#ifdef PNG_READ_cHRM_SUPPORTED
-PNG_EXTERN void png_handle_cHRM PNGARG((png_structp png_ptr, png_infop info_ptr,
-    png_uint_32 length));
-#endif
-
-#ifdef PNG_READ_gAMA_SUPPORTED
-PNG_EXTERN void png_handle_gAMA PNGARG((png_structp png_ptr, png_infop info_ptr,
-    png_uint_32 length));
-#endif
-
-#ifdef PNG_READ_hIST_SUPPORTED
-PNG_EXTERN void png_handle_hIST PNGARG((png_structp png_ptr, png_infop info_ptr,
-    png_uint_32 length));
-#endif
-
-#ifdef PNG_READ_iCCP_SUPPORTED
-PNG_EXTERN void png_handle_iCCP PNGARG((png_structp png_ptr, png_infop info_ptr,
-    png_uint_32 length));
-#endif /* PNG_READ_iCCP_SUPPORTED */
-
-#ifdef PNG_READ_iTXt_SUPPORTED
-PNG_EXTERN void png_handle_iTXt PNGARG((png_structp png_ptr, png_infop info_ptr,
-    png_uint_32 length));
-#endif
-
-#ifdef PNG_READ_oFFs_SUPPORTED
-PNG_EXTERN void png_handle_oFFs PNGARG((png_structp png_ptr, png_infop info_ptr,
-    png_uint_32 length));
-#endif
-
-#ifdef PNG_READ_pCAL_SUPPORTED
-PNG_EXTERN void png_handle_pCAL PNGARG((png_structp png_ptr, png_infop info_ptr,
-    png_uint_32 length));
-#endif
-
-#ifdef PNG_READ_pHYs_SUPPORTED
-PNG_EXTERN void png_handle_pHYs PNGARG((png_structp png_ptr, png_infop info_ptr,
-    png_uint_32 length));
-#endif
-
-#ifdef PNG_READ_sBIT_SUPPORTED
-PNG_EXTERN void png_handle_sBIT PNGARG((png_structp png_ptr, png_infop info_ptr,
-    png_uint_32 length));
-#endif
-
-#ifdef PNG_READ_sCAL_SUPPORTED
-PNG_EXTERN void png_handle_sCAL PNGARG((png_structp png_ptr, png_infop info_ptr,
-    png_uint_32 length));
-#endif
-
-#ifdef PNG_READ_sPLT_SUPPORTED
-PNG_EXTERN void png_handle_sPLT PNGARG((png_structp png_ptr, png_infop info_ptr,
-    png_uint_32 length));
-#endif /* PNG_READ_sPLT_SUPPORTED */
-
-#ifdef PNG_READ_sRGB_SUPPORTED
-PNG_EXTERN void png_handle_sRGB PNGARG((png_structp png_ptr, png_infop info_ptr,
-    png_uint_32 length));
-#endif
-
-#ifdef PNG_READ_tEXt_SUPPORTED
-PNG_EXTERN void png_handle_tEXt PNGARG((png_structp png_ptr, png_infop info_ptr,
-    png_uint_32 length));
-#endif
-
-#ifdef PNG_READ_tIME_SUPPORTED
-PNG_EXTERN void png_handle_tIME PNGARG((png_structp png_ptr, png_infop info_ptr,
-    png_uint_32 length));
-#endif
-
-#ifdef PNG_READ_tRNS_SUPPORTED
-PNG_EXTERN void png_handle_tRNS PNGARG((png_structp png_ptr, png_infop info_ptr,
-    png_uint_32 length));
-#endif
-
-#ifdef PNG_READ_zTXt_SUPPORTED
-PNG_EXTERN void png_handle_zTXt PNGARG((png_structp png_ptr, png_infop info_ptr,
-    png_uint_32 length));
-#endif
-
-PNG_EXTERN void png_handle_unknown PNGARG((png_structp png_ptr,
-    png_infop info_ptr, png_uint_32 length));
-
-PNG_EXTERN void png_check_chunk_name PNGARG((png_structp png_ptr,
-    png_uint_32 chunk_name));
-
-#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
-/* Exactly as png_handle_as_unknown() except that the argument is a 32-bit chunk
- * name, not a string.
- */
-PNG_EXTERN int png_chunk_unknown_handling PNGARG((png_structp png_ptr,
-    png_uint_32 chunk_name));
-#endif
-
-/* Handle the transformations for reading and writing */
-#ifdef PNG_READ_TRANSFORMS_SUPPORTED
-PNG_EXTERN void png_do_read_transformations PNGARG((png_structp png_ptr,
-   png_row_infop row_info));
-#endif
-#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
-PNG_EXTERN void png_do_write_transformations PNGARG((png_structp png_ptr,
-   png_row_infop row_info));
-#endif
-
-#ifdef PNG_READ_TRANSFORMS_SUPPORTED
-PNG_EXTERN void png_init_read_transformations PNGARG((png_structp png_ptr));
-#endif
-
-#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
-PNG_EXTERN void png_push_read_chunk PNGARG((png_structp png_ptr,
-    png_infop info_ptr));
-PNG_EXTERN void png_push_read_sig PNGARG((png_structp png_ptr,
-    png_infop info_ptr));
-PNG_EXTERN void png_push_check_crc PNGARG((png_structp png_ptr));
-PNG_EXTERN void png_push_crc_skip PNGARG((png_structp png_ptr,
-    png_uint_32 length));
-PNG_EXTERN void png_push_crc_finish PNGARG((png_structp png_ptr));
-PNG_EXTERN void png_push_save_buffer PNGARG((png_structp png_ptr));
-PNG_EXTERN void png_push_restore_buffer PNGARG((png_structp png_ptr,
-    png_bytep buffer, png_size_t buffer_length));
-PNG_EXTERN void png_push_read_IDAT PNGARG((png_structp png_ptr));
-PNG_EXTERN void png_process_IDAT_data PNGARG((png_structp png_ptr,
-    png_bytep buffer, png_size_t buffer_length));
-PNG_EXTERN void png_push_process_row PNGARG((png_structp png_ptr));
-PNG_EXTERN void png_push_handle_unknown PNGARG((png_structp png_ptr,
-   png_infop info_ptr, png_uint_32 length));
-PNG_EXTERN void png_push_have_info PNGARG((png_structp png_ptr,
-   png_infop info_ptr));
-PNG_EXTERN void png_push_have_end PNGARG((png_structp png_ptr,
-   png_infop info_ptr));
-PNG_EXTERN void png_push_have_row PNGARG((png_structp png_ptr, png_bytep row));
-PNG_EXTERN void png_push_read_end PNGARG((png_structp png_ptr,
-    png_infop info_ptr));
-PNG_EXTERN void png_process_some_data PNGARG((png_structp png_ptr,
-    png_infop info_ptr));
-PNG_EXTERN void png_read_push_finish_row PNGARG((png_structp png_ptr));
-#  ifdef PNG_READ_tEXt_SUPPORTED
-PNG_EXTERN void png_push_handle_tEXt PNGARG((png_structp png_ptr,
-    png_infop info_ptr, png_uint_32 length));
-PNG_EXTERN void png_push_read_tEXt PNGARG((png_structp png_ptr,
-    png_infop info_ptr));
-#  endif
-#  ifdef PNG_READ_zTXt_SUPPORTED
-PNG_EXTERN void png_push_handle_zTXt PNGARG((png_structp png_ptr,
-    png_infop info_ptr, png_uint_32 length));
-PNG_EXTERN void png_push_read_zTXt PNGARG((png_structp png_ptr,
-    png_infop info_ptr));
-#  endif
-#  ifdef PNG_READ_iTXt_SUPPORTED
-PNG_EXTERN void png_push_handle_iTXt PNGARG((png_structp png_ptr,
-    png_infop info_ptr, png_uint_32 length));
-PNG_EXTERN void png_push_read_iTXt PNGARG((png_structp png_ptr,
-    png_infop info_ptr));
-#  endif
-
-#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
-
-#ifdef PNG_MNG_FEATURES_SUPPORTED
-PNG_EXTERN void png_do_read_intrapixel PNGARG((png_row_infop row_info,
-    png_bytep row));
-PNG_EXTERN void png_do_write_intrapixel PNGARG((png_row_infop row_info,
-    png_bytep row));
-#endif
-
-/* Added at libpng version 1.4.0 */
-#ifdef PNG_CHECK_cHRM_SUPPORTED
-PNG_EXTERN int png_check_cHRM_fixed PNGARG((png_structp png_ptr,
-    png_fixed_point int_white_x, png_fixed_point int_white_y,
-    png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point
-    int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x,
-    png_fixed_point int_blue_y));
-#endif
-
-#ifdef PNG_CHECK_cHRM_SUPPORTED
-/* Added at libpng version 1.2.34 and 1.4.0 */
-/* Currently only used by png_check_cHRM_fixed */
-PNG_EXTERN void png_64bit_product PNGARG((long v1, long v2,
-    unsigned long *hi_product, unsigned long *lo_product));
-#endif
-
-#ifdef PNG_cHRM_SUPPORTED
-/* Added at libpng version 1.5.5 */
-typedef struct png_xy
-{
-   png_fixed_point redx, redy;
-   png_fixed_point greenx, greeny;
-   png_fixed_point bluex, bluey;
-   png_fixed_point whitex, whitey;
-} png_xy;
-
-typedef struct png_XYZ
-{
-   png_fixed_point redX, redY, redZ;
-   png_fixed_point greenX, greenY, greenZ;
-   png_fixed_point blueX, blueY, blueZ;
-} png_XYZ;
-
-/* The conversion APIs return 0 on success, non-zero on a parameter error. They
- * allow conversion between the above representations of a color encoding.  When
- * converting from XYZ end points to chromaticities the absolute magnitude of
- * the end points is lost, when converting back the sum of the Y values of the
- * three end points will be 1.0
- */
-PNG_EXTERN int png_xy_from_XYZ PNGARG((png_xy *xy, png_XYZ XYZ));
-PNG_EXTERN int png_XYZ_from_xy PNGARG((png_XYZ *XYZ, png_xy xy));
-PNG_EXTERN int png_XYZ_from_xy_checked PNGARG((png_structp png_ptr,
-   png_XYZ *XYZ, png_xy xy));
-#endif
-
-/* Added at libpng version 1.4.0 */
-PNG_EXTERN void png_check_IHDR PNGARG((png_structp png_ptr,
-    png_uint_32 width, png_uint_32 height, int bit_depth,
-    int color_type, int interlace_type, int compression_type,
-    int filter_type));
-
-/* Added at libpng version 1.5.10 */
-#if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \
-    defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED)
-PNG_EXTERN void png_do_check_palette_indexes PNGARG((png_structp png_ptr,
-    png_row_infop row_info));
-#endif
-
-/* Free all memory used by the read (old method - NOT DLL EXPORTED) */
-PNG_EXTERN void png_read_destroy PNGARG((png_structp png_ptr,
-    png_infop info_ptr, png_infop end_info_ptr));
-
-/* Free any memory used in png_ptr struct (old method - NOT DLL EXPORTED) */
-PNG_EXTERN void png_write_destroy PNGARG((png_structp png_ptr));
-
-#ifdef USE_FAR_KEYWORD  /* memory model conversion function */
-PNG_EXTERN void *png_far_to_near PNGARG((png_structp png_ptr, png_voidp ptr,
-    int check));
-#endif /* USE_FAR_KEYWORD */
-
-#if defined(PNG_FLOATING_POINT_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED)
-PNG_EXTERN PNG_FUNCTION(void, png_fixed_error, (png_structp png_ptr,
-   png_const_charp name),PNG_NORETURN);
-#endif
-
-/* Puts 'string' into 'buffer' at buffer[pos], taking care never to overwrite
- * the end.  Always leaves the buffer nul terminated.  Never errors out (and
- * there is no error code.)
- */
-PNG_EXTERN size_t png_safecat(png_charp buffer, size_t bufsize, size_t pos,
-    png_const_charp string);
-
-/* Various internal functions to handle formatted warning messages, currently
- * only implemented for warnings.
- */
-#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_TIME_RFC1123_SUPPORTED)
-/* Utility to dump an unsigned value into a buffer, given a start pointer and
- * and end pointer (which should point just *beyond* the end of the buffer!)
- * Returns the pointer to the start of the formatted string.  This utility only
- * does unsigned values.
- */
-PNG_EXTERN png_charp png_format_number(png_const_charp start, png_charp end,
-   int format, png_alloc_size_t number);
-
-/* Convenience macro that takes an array: */
-#define PNG_FORMAT_NUMBER(buffer,format,number) \
-   png_format_number(buffer, buffer + (sizeof buffer), format, number)
-
-/* Suggested size for a number buffer (enough for 64 bits and a sign!) */
-#define PNG_NUMBER_BUFFER_SIZE 24
-
-/* These are the integer formats currently supported, the name is formed from
- * the standard printf(3) format string.
- */
-#define PNG_NUMBER_FORMAT_u     1 /* chose unsigned API! */
-#define PNG_NUMBER_FORMAT_02u   2
-#define PNG_NUMBER_FORMAT_d     1 /* chose signed API! */
-#define PNG_NUMBER_FORMAT_02d   2
-#define PNG_NUMBER_FORMAT_x     3
-#define PNG_NUMBER_FORMAT_02x   4
-#define PNG_NUMBER_FORMAT_fixed 5 /* choose the signed API */
-#endif
-
-#ifdef PNG_WARNINGS_SUPPORTED
-/* New defines and members adding in libpng-1.5.4 */
-#  define PNG_WARNING_PARAMETER_SIZE 32
-#  define PNG_WARNING_PARAMETER_COUNT 8
-
-/* An l-value of this type has to be passed to the APIs below to cache the
- * values of the parameters to a formatted warning message.
- */
-typedef char png_warning_parameters[PNG_WARNING_PARAMETER_COUNT][
-   PNG_WARNING_PARAMETER_SIZE];
-
-PNG_EXTERN void png_warning_parameter(png_warning_parameters p, int number,
-    png_const_charp string);
-    /* Parameters are limited in size to PNG_WARNING_PARAMETER_SIZE characters,
-     * including the trailing '\0'.
-     */
-PNG_EXTERN void png_warning_parameter_unsigned(png_warning_parameters p,
-    int number, int format, png_alloc_size_t value);
-    /* Use png_alloc_size_t because it is an unsigned type as big as any we
-     * need to output.  Use the following for a signed value.
-     */
-PNG_EXTERN void png_warning_parameter_signed(png_warning_parameters p,
-    int number, int format, png_int_32 value);
-
-PNG_EXTERN void png_formatted_warning(png_structp png_ptr,
-    png_warning_parameters p, png_const_charp message);
-    /* 'message' follows the X/Open approach of using @1, @2 to insert
-     * parameters previously supplied using the above functions.  Errors in
-     * specifying the paramters will simple result in garbage substitutions.
-     */
-#endif
-
-/* ASCII to FP interfaces, currently only implemented if sCAL
- * support is required.
- */
-#if defined(PNG_READ_sCAL_SUPPORTED)
-/* MAX_DIGITS is actually the maximum number of characters in an sCAL
- * width or height, derived from the precision (number of significant
- * digits - a build time settable option) and assumpitions about the
- * maximum ridiculous exponent.
- */
-#define PNG_sCAL_MAX_DIGITS (PNG_sCAL_PRECISION+1/*.*/+1/*E*/+10/*exponent*/)
-
-#ifdef PNG_FLOATING_POINT_SUPPORTED
-PNG_EXTERN void png_ascii_from_fp PNGARG((png_structp png_ptr, png_charp ascii,
-    png_size_t size, double fp, unsigned int precision));
-#endif /* FLOATING_POINT */
-
-#ifdef PNG_FIXED_POINT_SUPPORTED
-PNG_EXTERN void png_ascii_from_fixed PNGARG((png_structp png_ptr,
-    png_charp ascii, png_size_t size, png_fixed_point fp));
-#endif /* FIXED_POINT */
-#endif /* READ_sCAL */
-
-#if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED)
-/* An internal API to validate the format of a floating point number.
- * The result is the index of the next character.  If the number is
- * not valid it will be the index of a character in the supposed number.
- *
- * The format of a number is defined in the PNG extensions specification
- * and this API is strictly conformant to that spec, not anyone elses!
- *
- * The format as a regular expression is:
- *
- * [+-]?[0-9]+.?([Ee][+-]?[0-9]+)?
- *
- * or:
- *
- * [+-]?.[0-9]+(.[0-9]+)?([Ee][+-]?[0-9]+)?
- *
- * The complexity is that either integer or fraction must be present and the
- * fraction is permitted to have no digits only if the integer is present.
- *
- * NOTE: The dangling E problem.
- *   There is a PNG valid floating point number in the following:
- *
- *       PNG floating point numb1.ers are not greedy.
- *
- *   Working this out requires *TWO* character lookahead (because of the
- *   sign), the parser does not do this - it will fail at the 'r' - this
- *   doesn't matter for PNG sCAL chunk values, but it requires more care
- *   if the value were ever to be embedded in something more complex.  Use
- *   ANSI-C strtod if you need the lookahead.
- */
-/* State table for the parser. */
-#define PNG_FP_INTEGER    0  /* before or in integer */
-#define PNG_FP_FRACTION   1  /* before or in fraction */
-#define PNG_FP_EXPONENT   2  /* before or in exponent */
-#define PNG_FP_STATE      3  /* mask for the above */
-#define PNG_FP_SAW_SIGN   4  /* Saw +/- in current state */
-#define PNG_FP_SAW_DIGIT  8  /* Saw a digit in current state */
-#define PNG_FP_SAW_DOT   16  /* Saw a dot in current state */
-#define PNG_FP_SAW_E     32  /* Saw an E (or e) in current state */
-#define PNG_FP_SAW_ANY   60  /* Saw any of the above 4 */
-
-/* These three values don't affect the parser.  They are set but not used.
- */
-#define PNG_FP_WAS_VALID 64  /* Preceding substring is a valid fp number */
-#define PNG_FP_NEGATIVE 128  /* A negative number, including "-0" */
-#define PNG_FP_NONZERO  256  /* A non-zero value */
-#define PNG_FP_STICKY   448  /* The above three flags */
-
-/* This is available for the caller to store in 'state' if required.  Do not
- * call the parser after setting it (the parser sometimes clears it.)
- */
-#define PNG_FP_INVALID  512  /* Available for callers as a distinct value */
-
-/* Result codes for the parser (boolean - true meants ok, false means
- * not ok yet.)
- */
-#define PNG_FP_MAYBE      0  /* The number may be valid in the future */
-#define PNG_FP_OK         1  /* The number is valid */
-
-/* Tests on the sticky non-zero and negative flags.  To pass these checks
- * the state must also indicate that the whole number is valid - this is
- * achieved by testing PNG_FP_SAW_DIGIT (see the implementation for why this
- * is equivalent to PNG_FP_OK above.)
- */
-#define PNG_FP_NZ_MASK (PNG_FP_SAW_DIGIT | PNG_FP_NEGATIVE | PNG_FP_NONZERO)
-   /* NZ_MASK: the string is valid and a non-zero negative value */
-#define PNG_FP_Z_MASK (PNG_FP_SAW_DIGIT | PNG_FP_NONZERO)
-   /* Z MASK: the string is valid and a non-zero value. */
-   /* PNG_FP_SAW_DIGIT: the string is valid. */
-#define PNG_FP_IS_ZERO(state) (((state) & PNG_FP_Z_MASK) == PNG_FP_SAW_DIGIT)
-#define PNG_FP_IS_POSITIVE(state) (((state) & PNG_FP_NZ_MASK) == PNG_FP_Z_MASK)
-#define PNG_FP_IS_NEGATIVE(state) (((state) & PNG_FP_NZ_MASK) == PNG_FP_NZ_MASK)
-
-/* The actual parser.  This can be called repeatedly, it updates
- * the index into the string and the state variable (which must
- * be initialzed to 0).  It returns a result code, as above.  There
- * is no point calling the parser any more if it fails to advance to
- * the end of the string - it is stuck on an invalid character (or
- * terminated by '\0').
- *
- * Note that the pointer will consume an E or even an E+ then leave
- * a 'maybe' state even though a preceding integer.fraction is valid.
- * The PNG_FP_WAS_VALID flag indicates that a preceding substring was
- * a valid number.  It's possible to recover from this by calling
- * the parser again (from the start, with state 0) but with a string
- * that omits the last character (i.e. set the size to the index of
- * the problem character.)  This has not been tested within libpng.
- */
-PNG_EXTERN int png_check_fp_number PNGARG((png_const_charp string,
-    png_size_t size, int *statep, png_size_tp whereami));
-
-/* This is the same but it checks a complete string and returns true
- * only if it just contains a floating point number.  As of 1.5.4 this
- * function also returns the state at the end of parsing the number if
- * it was valid (otherwise it returns 0.)  This can be used for testing
- * for negative or zero values using the sticky flag.
- */
-PNG_EXTERN int png_check_fp_string PNGARG((png_const_charp string,
-    png_size_t size));
-#endif /* pCAL || sCAL */
-
-#if defined(PNG_READ_GAMMA_SUPPORTED) ||\
-    defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG_READ_pHYs_SUPPORTED)
-/* Added at libpng version 1.5.0 */
-/* This is a utility to provide a*times/div (rounded) and indicate
- * if there is an overflow.  The result is a boolean - false (0)
- * for overflow, true (1) if no overflow, in which case *res
- * holds the result.
- */
-PNG_EXTERN int png_muldiv PNGARG((png_fixed_point_p res, png_fixed_point a,
-    png_int_32 multiplied_by, png_int_32 divided_by));
-#endif
-
-#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED)
-/* Same deal, but issue a warning on overflow and return 0. */
-PNG_EXTERN png_fixed_point png_muldiv_warn PNGARG((png_structp png_ptr,
-    png_fixed_point a, png_int_32 multiplied_by, png_int_32 divided_by));
-#endif
-
-#ifdef PNG_READ_GAMMA_SUPPORTED
-/* Calculate a reciprocal - used for gamma values.  This returns
- * 0 if the argument is 0 in order to maintain an undefined value,
- * there are no warnings.
- */
-PNG_EXTERN png_fixed_point png_reciprocal PNGARG((png_fixed_point a));
-
-/* The same but gives a reciprocal of the product of two fixed point
- * values.  Accuracy is suitable for gamma calculations but this is
- * not exact - use png_muldiv for that.
- */
-PNG_EXTERN png_fixed_point png_reciprocal2 PNGARG((png_fixed_point a,
-    png_fixed_point b));
-#endif
-
-#ifdef PNG_READ_GAMMA_SUPPORTED
-/* Internal fixed point gamma correction.  These APIs are called as
- * required to convert single values - they don't need to be fast,
- * they are not used when processing image pixel values.
- *
- * While the input is an 'unsigned' value it must actually be the
- * correct bit value - 0..255 or 0..65535 as required.
- */
-PNG_EXTERN png_uint_16 png_gamma_correct PNGARG((png_structp png_ptr,
-    unsigned int value, png_fixed_point gamma_value));
-PNG_EXTERN int png_gamma_significant PNGARG((png_fixed_point gamma_value));
-PNG_EXTERN png_uint_16 png_gamma_16bit_correct PNGARG((unsigned int value,
-    png_fixed_point gamma_value));
-PNG_EXTERN png_byte png_gamma_8bit_correct PNGARG((unsigned int value,
-    png_fixed_point gamma_value));
-PNG_EXTERN void png_destroy_gamma_table(png_structp png_ptr);
-PNG_EXTERN void png_build_gamma_table PNGARG((png_structp png_ptr,
-    int bit_depth));
-#endif
-
-/* Maintainer: Put new private prototypes here ^ and in libpngpf.3 */
-
-#include "pngdebug.h"
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* PNGPRIV_H */
+
+/* pngpriv.h - private declarations for use inside libpng
+ *
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * Last changed in libpng 1.6.10 [March 6, 1014]]
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+/* The symbols declared in this file (including the functions declared
+ * as extern) are PRIVATE.  They are not part of the libpng public
+ * interface, and are not recommended for use by regular applications.
+ * Some of them may become public in the future; others may stay private,
+ * change in an incompatible way, or even disappear.
+ * Although the libpng users are not forbidden to include this header,
+ * they should be well aware of the issues that may arise from doing so.
+ */
+
+#ifndef PNGPRIV_H
+#define PNGPRIV_H
+
+/* Feature Test Macros.  The following are defined here to ensure that correctly
+ * implemented libraries reveal the APIs libpng needs to build and hide those
+ * that are not needed and potentially damaging to the compilation.
+ *
+ * Feature Test Macros must be defined before any system header is included (see
+ * POSIX 1003.1 2.8.2 "POSIX Symbols."
+ *
+ * These macros only have an effect if the operating system supports either
+ * POSIX 1003.1 or C99, or both.  On other operating systems (particularly
+ * Windows/Visual Studio) there is no effect; the OS specific tests below are
+ * still required (as of 2011-05-02.)
+ */
+#define _POSIX_SOURCE 1 /* Just the POSIX 1003.1 and C89 APIs */
+
+#ifndef PNG_VERSION_INFO_ONLY
+/* Standard library headers not required by png.h: */
+#  include <stdlib.h>
+#  include <string.h>
+#endif
+
+#define PNGLIB_BUILD /*libpng is being built, not used*/
+
+/* If HAVE_CONFIG_H is defined during the build then the build system must
+ * provide an appropriate "config.h" file on the include path.  The header file
+ * must provide definitions as required below (search for "HAVE_CONFIG_H");
+ * see configure.ac for more details of the requirements.  The macro
+ * "PNG_NO_CONFIG_H" is provided for maintainers to test for dependencies on
+ * 'configure'; define this macro to prevent the configure build including the
+ * configure generated config.h.  Libpng is expected to compile without *any*
+ * special build system support on a reasonably ANSI-C compliant system.
+ */
+#if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H)
+#  include <config.h>
+
+   /* Pick up the definition of 'restrict' from config.h if it was read: */
+#  define PNG_RESTRICT restrict
+#endif
+
+/* To support symbol prefixing it is necessary to know *before* including png.h
+ * whether the fixed point (and maybe other) APIs are exported, because if they
+ * are not internal definitions may be required.  This is handled below just
+ * before png.h is included, but load the configuration now if it is available.
+ */
+#ifndef PNGLCONF_H
+#  include "pnglibconf.h"
+#endif
+
+/* Local renames may change non-exported API functions from png.h */
+#if defined(PNG_PREFIX) && !defined(PNGPREFIX_H)
+#  include "pngprefix.h"
+#endif
+
+#ifdef PNG_USER_CONFIG
+#  include "pngusr.h"
+   /* These should have been defined in pngusr.h */
+#  ifndef PNG_USER_PRIVATEBUILD
+#    define PNG_USER_PRIVATEBUILD "Custom libpng build"
+#  endif
+#  ifndef PNG_USER_DLLFNAME_POSTFIX
+#    define PNG_USER_DLLFNAME_POSTFIX "Cb"
+#  endif
+#endif
+
+/* Compile time options.
+ * =====================
+ * In a multi-arch build the compiler may compile the code several times for the
+ * same object module, producing different binaries for different architectures.
+ * When this happens configure-time setting of the target host options cannot be
+ * done and this interferes with the handling of the ARM NEON optimizations, and
+ * possibly other similar optimizations.  Put additional tests here; in general
+ * this is needed when the same option can be changed at both compile time and
+ * run time depending on the target OS (i.e. iOS vs Android.)
+ *
+ * NOTE: symbol prefixing does not pass $(CFLAGS) to the preprocessor, because
+ * this is not possible with certain compilers (Oracle SUN OS CC), as a result
+ * it is necessary to ensure that all extern functions that *might* be used
+ * regardless of $(CFLAGS) get declared in this file.  The test on __ARM_NEON__
+ * below is one example of this behavior because it is controlled by the
+ * presence or not of -mfpu=neon on the GCC command line, it is possible to do
+ * this in $(CC), e.g. "CC=gcc -mfpu=neon", but people who build libpng rarely
+ * do this.
+ */
+#ifndef PNG_ARM_NEON_OPT
+   /* ARM NEON optimizations are being controlled by the compiler settings,
+    * typically the target FPU.  If the FPU has been set to NEON (-mfpu=neon
+    * with GCC) then the compiler will define __ARM_NEON__ and we can rely
+    * unconditionally on NEON instructions not crashing, otherwise we must
+    * disable use of NEON instructions.
+    *
+    * NOTE: at present these optimizations depend on 'ALIGNED_MEMORY', so they
+    * can only be turned on automatically if that is supported too.  If
+    * PNG_ARM_NEON_OPT is set in CPPFLAGS (to >0) then arm/arm_init.c will fail
+    * to compile with an appropriate #error if ALIGNED_MEMORY has been turned
+    * off.
+    *
+    * Note that gcc-4.9 defines __ARM_NEON instead of __ARM_NEON__, so we
+    * check both variants.
+    */
+#  if (defined(__ARM_NEON__) || defined(__ARM_NEON)) && \
+   defined(PNG_ALIGNED_MEMORY_SUPPORTED)
+#     define PNG_ARM_NEON_OPT 2
+#  else
+#     define PNG_ARM_NEON_OPT 0
+#  endif
+#endif
+
+#if PNG_ARM_NEON_OPT > 0
+   /* NEON optimizations are to be at least considered by libpng, so enable the
+    * callbacks to do this.
+    */
+#  define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_neon
+
+   /* By default the 'intrinsics' code in arm/filter_neon_intrinsics.c is used
+    * if possible - if __ARM_NEON__ is set and the compiler version is not known
+    * to be broken.  This is controlled by PNG_ARM_NEON_IMPLEMENTATION which can
+    * be:
+    *
+    *    1  The intrinsics code (the default with __ARM_NEON__)
+    *    2  The hand coded assembler (the default without __ARM_NEON__)
+    *
+    * It is possible to set PNG_ARM_NEON_IMPLEMENTATION in CPPFLAGS, however
+    * this is *NOT* supported and may cease to work even after a minor revision
+    * to libpng.  It *is* valid to do this for testing purposes, e.g. speed
+    * testing or a new compiler, but the results should be communicated to the
+    * libpng implementation list for incorporation in the next minor release.
+    */
+#  ifndef PNG_ARM_NEON_IMPLEMENTATION
+#     if defined(__ARM_NEON__) || defined(__ARM_NEON)
+#        if defined(__clang__)
+            /* At present it is unknown by the libpng developers which versions
+             * of clang support the intrinsics, however some or perhaps all
+             * versions do not work with the assembler so this may be
+             * irrelevant, so just use the default (do nothing here.)
+             */
+#        elif defined(__GNUC__)
+            /* GCC 4.5.4 NEON support is known to be broken.  4.6.3 is known to
+             * work, so if this *is* GCC, or G++, look for a version >4.5
+             */
+#           if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 6)
+#              define PNG_ARM_NEON_IMPLEMENTATION 2
+#           endif /* no GNUC support */
+#        endif /* __GNUC__ */
+#     else /* !defined __ARM_NEON__ */
+         /* The 'intrinsics' code simply won't compile without this -mfpu=neon:
+          */
+#        define PNG_ARM_NEON_IMPLEMENTATION 2
+#     endif /* __ARM_NEON__ */
+#  endif /* !PNG_ARM_NEON_IMPLEMENTATION */
+
+#  ifndef PNG_ARM_NEON_IMPLEMENTATION
+      /* Use the intrinsics code by default. */
+#     define PNG_ARM_NEON_IMPLEMENTATION 1
+#  endif
+#endif /* PNG_ARM_NEON_OPT > 0 */
+
+/* Is this a build of a DLL where compilation of the object modules requires
+ * different preprocessor settings to those required for a simple library?  If
+ * so PNG_BUILD_DLL must be set.
+ *
+ * If libpng is used inside a DLL but that DLL does not export the libpng APIs
+ * PNG_BUILD_DLL must not be set.  To avoid the code below kicking in build a
+ * static library of libpng then link the DLL against that.
+ */
+#ifndef PNG_BUILD_DLL
+#  ifdef DLL_EXPORT
+      /* This is set by libtool when files are compiled for a DLL; libtool
+       * always compiles twice, even on systems where it isn't necessary.  Set
+       * PNG_BUILD_DLL in case it is necessary:
+       */
+#     define PNG_BUILD_DLL
+#  else
+#     ifdef _WINDLL
+         /* This is set by the Microsoft Visual Studio IDE in projects that
+          * build a DLL.  It can't easily be removed from those projects (it
+          * isn't visible in the Visual Studio UI) so it is a fairly reliable
+          * indication that PNG_IMPEXP needs to be set to the DLL export
+          * attributes.
+          */
+#        define PNG_BUILD_DLL
+#     else
+#        ifdef __DLL__
+            /* This is set by the Borland C system when compiling for a DLL
+             * (as above.)
+             */
+#           define PNG_BUILD_DLL
+#        else
+            /* Add additional compiler cases here. */
+#        endif
+#     endif
+#  endif
+#endif /* Setting PNG_BUILD_DLL if required */
+
+/* See pngconf.h for more details: the builder of the library may set this on
+ * the command line to the right thing for the specific compilation system or it
+ * may be automagically set above (at present we know of no system where it does
+ * need to be set on the command line.)
+ *
+ * PNG_IMPEXP must be set here when building the library to prevent pngconf.h
+ * setting it to the "import" setting for a DLL build.
+ */
+#ifndef PNG_IMPEXP
+#  ifdef PNG_BUILD_DLL
+#     define PNG_IMPEXP PNG_DLL_EXPORT
+#  else
+      /* Not building a DLL, or the DLL doesn't require specific export
+       * definitions.
+       */
+#     define PNG_IMPEXP
+#  endif
+#endif
+
+/* No warnings for private or deprecated functions in the build: */
+#ifndef PNG_DEPRECATED
+#  define PNG_DEPRECATED
+#endif
+#ifndef PNG_PRIVATE
+#  define PNG_PRIVATE
+#endif
+
+/* Symbol preprocessing support.
+ *
+ * To enable listing global, but internal, symbols the following macros should
+ * always be used to declare an extern data or function object in this file.
+ */
+#ifndef PNG_INTERNAL_DATA
+#  define PNG_INTERNAL_DATA(type, name, array) extern type name array
+#endif
+
+#ifndef PNG_INTERNAL_FUNCTION
+#  define PNG_INTERNAL_FUNCTION(type, name, args, attributes)\
+      extern PNG_FUNCTION(type, name, args, PNG_EMPTY attributes)
+#endif
+
+#ifndef PNG_INTERNAL_CALLBACK
+#  define PNG_INTERNAL_CALLBACK(type, name, args, attributes)\
+      extern PNG_FUNCTION(type, (PNGCBAPI name), args, PNG_EMPTY attributes)
+#endif
+
+/* If floating or fixed point APIs are disabled they may still be compiled
+ * internally.  To handle this make sure they are declared as the appropriate
+ * internal extern function (otherwise the symbol prefixing stuff won't work and
+ * the functions will be used without definitions.)
+ *
+ * NOTE: although all the API functions are declared here they are not all
+ * actually built!  Because the declarations are still made it is necessary to
+ * fake out types that they depend on.
+ */
+#ifndef PNG_FP_EXPORT
+#  ifndef PNG_FLOATING_POINT_SUPPORTED
+#     define PNG_FP_EXPORT(ordinal, type, name, args)\
+         PNG_INTERNAL_FUNCTION(type, name, args, PNG_EMPTY);
+#     ifndef PNG_VERSION_INFO_ONLY
+         typedef struct png_incomplete png_double;
+         typedef png_double*           png_doublep;
+         typedef const png_double*     png_const_doublep;
+         typedef png_double**          png_doublepp;
+#     endif
+#  endif
+#endif
+#ifndef PNG_FIXED_EXPORT
+#  ifndef PNG_FIXED_POINT_SUPPORTED
+#     define PNG_FIXED_EXPORT(ordinal, type, name, args)\
+         PNG_INTERNAL_FUNCTION(type, name, args, PNG_EMPTY);
+#  endif
+#endif
+
+#include "png.h"
+
+/* pngconf.h does not set PNG_DLL_EXPORT unless it is required, so: */
+#ifndef PNG_DLL_EXPORT
+#  define PNG_DLL_EXPORT
+#endif
+
+/* SECURITY and SAFETY:
+ *
+ * By default libpng is built without any internal limits on image size,
+ * individual heap (png_malloc) allocations or the total amount of memory used.
+ * If PNG_SAFE_LIMITS_SUPPORTED is defined, however, the limits below are used
+ * (unless individually overridden).  These limits are believed to be fairly
+ * safe, but builders of secure systems should verify the values against the
+ * real system capabilities.
+ */
+#ifdef PNG_SAFE_LIMITS_SUPPORTED
+   /* 'safe' limits */
+#  ifndef PNG_USER_WIDTH_MAX
+#     define PNG_USER_WIDTH_MAX 1000000
+#  endif
+#  ifndef PNG_USER_HEIGHT_MAX
+#     define PNG_USER_HEIGHT_MAX 1000000
+#  endif
+#  ifndef PNG_USER_CHUNK_CACHE_MAX
+#     define PNG_USER_CHUNK_CACHE_MAX 128
+#  endif
+#  ifndef PNG_USER_CHUNK_MALLOC_MAX
+#     define PNG_USER_CHUNK_MALLOC_MAX 8000000
+#  endif
+#else
+   /* values for no limits */
+#  ifndef PNG_USER_WIDTH_MAX
+#     define PNG_USER_WIDTH_MAX 0x7fffffff
+#  endif
+#  ifndef PNG_USER_HEIGHT_MAX
+#     define PNG_USER_HEIGHT_MAX 0x7fffffff
+#  endif
+#  ifndef PNG_USER_CHUNK_CACHE_MAX
+#     define PNG_USER_CHUNK_CACHE_MAX 0
+#  endif
+#  ifndef PNG_USER_CHUNK_MALLOC_MAX
+#     define PNG_USER_CHUNK_MALLOC_MAX 0
+#  endif
+#endif
+
+/* Moved to pngpriv.h at libpng-1.5.0 */
+/* NOTE: some of these may have been used in external applications as
+ * these definitions were exposed in pngconf.h prior to 1.5.
+ */
+
+/* If you are running on a machine where you cannot allocate more
+ * than 64K of memory at once, uncomment this.  While libpng will not
+ * normally need that much memory in a chunk (unless you load up a very
+ * large file), zlib needs to know how big of a chunk it can use, and
+ * libpng thus makes sure to check any memory allocation to verify it
+ * will fit into memory.
+ *
+ * zlib provides 'MAXSEG_64K' which, if defined, indicates the
+ * same limit and pngconf.h (already included) sets the limit
+ * if certain operating systems are detected.
+ */
+#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K)
+#  define PNG_MAX_MALLOC_64K
+#endif
+
+#ifndef PNG_UNUSED
+/* Unused formal parameter warnings are silenced using the following macro
+ * which is expected to have no bad effects on performance (optimizing
+ * compilers will probably remove it entirely).  Note that if you replace
+ * it with something other than whitespace, you must include the terminating
+ * semicolon.
+ */
+#  define PNG_UNUSED(param) (void)param;
+#endif
+
+/* Just a little check that someone hasn't tried to define something
+ * contradictory.
+ */
+#if (PNG_ZBUF_SIZE > 65536L) && defined(PNG_MAX_MALLOC_64K)
+#  undef PNG_ZBUF_SIZE
+#  define PNG_ZBUF_SIZE 65536L
+#endif
+
+/* If warnings or errors are turned off the code is disabled or redirected here.
+ * From 1.5.4 functions have been added to allow very limited formatting of
+ * error and warning messages - this code will also be disabled here.
+ */
+#ifdef PNG_WARNINGS_SUPPORTED
+#  define PNG_WARNING_PARAMETERS(p) png_warning_parameters p;
+#else
+#  define png_warning_parameter(p,number,string) ((void)0)
+#  define png_warning_parameter_unsigned(p,number,format,value) ((void)0)
+#  define png_warning_parameter_signed(p,number,format,value) ((void)0)
+#  define png_formatted_warning(pp,p,message) ((void)(pp))
+#  define PNG_WARNING_PARAMETERS(p)
+#endif
+#ifndef PNG_ERROR_TEXT_SUPPORTED
+#  define png_fixed_error(s1,s2) png_err(s1)
+#endif
+
+/* C allows up-casts from (void*) to any pointer and (const void*) to any
+ * pointer to a const object.  C++ regards this as a type error and requires an
+ * explicit, static, cast and provides the static_cast<> rune to ensure that
+ * const is not cast away.
+ */
+#ifdef __cplusplus
+#  define png_voidcast(type, value) static_cast<type>(value)
+#  define png_constcast(type, value) const_cast<type>(value)
+#  define png_aligncast(type, value) \
+   static_cast<type>(static_cast<void*>(value))
+#  define png_aligncastconst(type, value) \
+   static_cast<type>(static_cast<const void*>(value))
+#else
+#  define png_voidcast(type, value) (value)
+#  define png_constcast(type, value) ((type)(value))
+#  define png_aligncast(type, value) ((void*)(value))
+#  define png_aligncastconst(type, value) ((const void*)(value))
+#endif /* __cplusplus */
+
+/* Some fixed point APIs are still required even if not exported because
+ * they get used by the corresponding floating point APIs.  This magic
+ * deals with this:
+ */
+#ifdef PNG_FIXED_POINT_SUPPORTED
+#  define PNGFAPI PNGAPI
+#else
+#  define PNGFAPI /* PRIVATE */
+#endif
+
+#ifndef PNG_VERSION_INFO_ONLY
+/* Other defines specific to compilers can go here.  Try to keep
+ * them inside an appropriate ifdef/endif pair for portability.
+ */
+#if defined(PNG_FLOATING_POINT_SUPPORTED) ||\
+    defined(PNG_FLOATING_ARITHMETIC_SUPPORTED)
+   /* png.c requires the following ANSI-C constants if the conversion of
+    * floating point to ASCII is implemented therein:
+    *
+    *  DBL_DIG  Maximum number of decimal digits (can be set to any constant)
+    *  DBL_MIN  Smallest normalized fp number (can be set to an arbitrary value)
+    *  DBL_MAX  Maximum floating point number (can be set to an arbitrary value)
+    */
+#  include <float.h>
+
+#  if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \
+    defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC)
+     /* We need to check that <math.h> hasn't already been included earlier
+      * as it seems it doesn't agree with <fp.h>, yet we should really use
+      * <fp.h> if possible.
+      */
+#    if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__)
+#      include <fp.h>
+#    endif
+#  else
+#    include <math.h>
+#  endif
+#  if defined(_AMIGA) && defined(__SASC) && defined(_M68881)
+     /* Amiga SAS/C: We must include builtin FPU functions when compiling using
+      * MATH=68881
+      */
+#    include <m68881.h>
+#  endif
+#endif
+
+/* This provides the non-ANSI (far) memory allocation routines. */
+#if defined(__TURBOC__) && defined(__MSDOS__)
+#  include <mem.h>
+#  include <alloc.h>
+#endif
+
+#if defined(WIN32) || defined(_Windows) || defined(_WINDOWS) || \
+    defined(_WIN32) || defined(__WIN32__)
+#  include <windows.h>  /* defines _WINDOWS_ macro */
+#endif
+#endif /* PNG_VERSION_INFO_ONLY */
+
+/* Moved here around 1.5.0beta36 from pngconf.h */
+/* Users may want to use these so they are not private.  Any library
+ * functions that are passed far data must be model-independent.
+ */
+
+/* Memory model/platform independent fns */
+#ifndef PNG_ABORT
+#  ifdef _WINDOWS_
+#    define PNG_ABORT() ExitProcess(0)
+#  else
+#    define PNG_ABORT() abort()
+#  endif
+#endif
+
+/* These macros may need to be architecture dependent. */
+#define PNG_ALIGN_NONE   0 /* do not use data alignment */
+#define PNG_ALIGN_ALWAYS 1 /* assume unaligned accesses are OK */
+#ifdef offsetof
+#  define PNG_ALIGN_OFFSET 2 /* use offsetof to determine alignment */
+#else
+#  define PNG_ALIGN_OFFSET -1 /* prevent the use of this */
+#endif
+#define PNG_ALIGN_SIZE   3 /* use sizeof to determine alignment */
+
+#ifndef PNG_ALIGN_TYPE
+   /* Default to using aligned access optimizations and requiring alignment to a
+    * multiple of the data type size.  Override in a compiler specific fashion
+    * if necessary by inserting tests here:
+    */
+#  define PNG_ALIGN_TYPE PNG_ALIGN_SIZE
+#endif
+
+#if PNG_ALIGN_TYPE == PNG_ALIGN_SIZE
+   /* This is used because in some compiler implementations non-aligned
+    * structure members are supported, so the offsetof approach below fails.
+    * Set PNG_ALIGN_SIZE=0 for compiler combinations where unaligned access
+    * is good for performance.  Do not do this unless you have tested the result
+    * and understand it.
+    */
+#  define png_alignof(type) (sizeof (type))
+#else
+#  if PNG_ALIGN_TYPE == PNG_ALIGN_OFFSET
+#     define png_alignof(type) offsetof(struct{char c; type t;}, t)
+#  else
+#     if PNG_ALIGN_TYPE == PNG_ALIGN_ALWAYS
+#        define png_alignof(type) (1)
+#     endif
+      /* Else leave png_alignof undefined to prevent use thereof */
+#  endif
+#endif
+
+/* This implicitly assumes alignment is always to a power of 2. */
+#ifdef png_alignof
+#  define png_isaligned(ptr, type)\
+   ((((const char*)ptr-(const char*)0) & (png_alignof(type)-1)) == 0)
+#else
+#  define png_isaligned(ptr, type) 0
+#endif
+
+/* End of memory model/platform independent support */
+/* End of 1.5.0beta36 move from pngconf.h */
+
+/* CONSTANTS and UTILITY MACROS
+ * These are used internally by libpng and not exposed in the API
+ */
+
+/* Various modes of operation.  Note that after an init, mode is set to
+ * zero automatically when the structure is created.  Three of these
+ * are defined in png.h because they need to be visible to applications
+ * that call png_set_unknown_chunk().
+ */
+/* #define PNG_HAVE_IHDR            0x01 (defined in png.h) */
+/* #define PNG_HAVE_PLTE            0x02 (defined in png.h) */
+#define PNG_HAVE_IDAT               0x04
+/* #define PNG_AFTER_IDAT           0x08 (defined in png.h) */
+#define PNG_HAVE_IEND               0x10
+                   /*               0x20 (unused) */
+                   /*               0x40 (unused) */
+                   /*               0x80 (unused) */
+#define PNG_HAVE_CHUNK_HEADER      0x100
+#define PNG_WROTE_tIME             0x200
+#define PNG_WROTE_INFO_BEFORE_PLTE 0x400
+#define PNG_BACKGROUND_IS_GRAY     0x800
+#define PNG_HAVE_PNG_SIGNATURE    0x1000
+#define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000 /* Have another chunk after IDAT */
+                   /*             0x4000 (unused) */
+#define PNG_IS_READ_STRUCT        0x8000 /* Else is a write struct */
+
+/* Flags for the transformations the PNG library does on the image data */
+#define PNG_BGR                 0x0001
+#define PNG_INTERLACE           0x0002
+#define PNG_PACK                0x0004
+#define PNG_SHIFT               0x0008
+#define PNG_SWAP_BYTES          0x0010
+#define PNG_INVERT_MONO         0x0020
+#define PNG_QUANTIZE            0x0040
+#define PNG_COMPOSE             0x0080     /* Was PNG_BACKGROUND */
+#define PNG_BACKGROUND_EXPAND   0x0100
+#define PNG_EXPAND_16           0x0200     /* Added to libpng 1.5.2 */
+#define PNG_16_TO_8             0x0400     /* Becomes 'chop' in 1.5.4 */
+#define PNG_RGBA                0x0800
+#define PNG_EXPAND              0x1000
+#define PNG_GAMMA               0x2000
+#define PNG_GRAY_TO_RGB         0x4000
+#define PNG_FILLER              0x8000
+#define PNG_PACKSWAP           0x10000
+#define PNG_SWAP_ALPHA         0x20000
+#define PNG_STRIP_ALPHA        0x40000
+#define PNG_INVERT_ALPHA       0x80000
+#define PNG_USER_TRANSFORM    0x100000
+#define PNG_RGB_TO_GRAY_ERR   0x200000
+#define PNG_RGB_TO_GRAY_WARN  0x400000
+#define PNG_RGB_TO_GRAY       0x600000 /* two bits, RGB_TO_GRAY_ERR|WARN */
+#define PNG_ENCODE_ALPHA      0x800000 /* Added to libpng-1.5.4 */
+#define PNG_ADD_ALPHA         0x1000000 /* Added to libpng-1.2.7 */
+#define PNG_EXPAND_tRNS       0x2000000 /* Added to libpng-1.2.9 */
+#define PNG_SCALE_16_TO_8     0x4000000 /* Added to libpng-1.5.4 */
+                       /*   0x8000000 unused */
+                       /*  0x10000000 unused */
+                       /*  0x20000000 unused */
+                       /*  0x40000000 unused */
+/* Flags for png_create_struct */
+#define PNG_STRUCT_PNG   0x0001
+#define PNG_STRUCT_INFO  0x0002
+
+/* Scaling factor for filter heuristic weighting calculations */
+#define PNG_WEIGHT_FACTOR (1<<(PNG_WEIGHT_SHIFT))
+#define PNG_COST_FACTOR (1<<(PNG_COST_SHIFT))
+
+/* Flags for the png_ptr->flags rather than declaring a byte for each one */
+#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY     0x0001
+#define PNG_FLAG_ZSTREAM_INITIALIZED      0x0002 /* Added to libpng-1.6.0 */
+                                  /*      0x0004    unused */
+#define PNG_FLAG_ZSTREAM_ENDED            0x0008 /* Added to libpng-1.6.0 */
+                                  /*      0x0010    unused */
+                                  /*      0x0020    unused */
+#define PNG_FLAG_ROW_INIT                 0x0040
+#define PNG_FLAG_FILLER_AFTER             0x0080
+#define PNG_FLAG_CRC_ANCILLARY_USE        0x0100
+#define PNG_FLAG_CRC_ANCILLARY_NOWARN     0x0200
+#define PNG_FLAG_CRC_CRITICAL_USE         0x0400
+#define PNG_FLAG_CRC_CRITICAL_IGNORE      0x0800
+#define PNG_FLAG_ASSUME_sRGB              0x1000 /* Added to libpng-1.5.4 */
+#define PNG_FLAG_OPTIMIZE_ALPHA           0x2000 /* Added to libpng-1.5.4 */
+#define PNG_FLAG_DETECT_UNINITIALIZED     0x4000 /* Added to libpng-1.5.4 */
+/* #define PNG_FLAG_KEEP_UNKNOWN_CHUNKS      0x8000 */
+/* #define PNG_FLAG_KEEP_UNSAFE_CHUNKS      0x10000 */
+#define PNG_FLAG_LIBRARY_MISMATCH        0x20000
+#define PNG_FLAG_STRIP_ERROR_NUMBERS     0x40000
+#define PNG_FLAG_STRIP_ERROR_TEXT        0x80000
+#define PNG_FLAG_BENIGN_ERRORS_WARN     0x100000 /* Added to libpng-1.4.0 */
+#define PNG_FLAG_APP_WARNINGS_WARN      0x200000 /* Added to libpng-1.6.0 */
+#define PNG_FLAG_APP_ERRORS_WARN        0x400000 /* Added to libpng-1.6.0 */
+                                  /*    0x800000    unused */
+                                  /*   0x1000000    unused */
+                                  /*   0x2000000    unused */
+                                  /*   0x4000000    unused */
+                                  /*   0x8000000    unused */
+                                  /*  0x10000000    unused */
+                                  /*  0x20000000    unused */
+                                  /*  0x40000000    unused */
+
+#define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \
+                                     PNG_FLAG_CRC_ANCILLARY_NOWARN)
+
+#define PNG_FLAG_CRC_CRITICAL_MASK  (PNG_FLAG_CRC_CRITICAL_USE | \
+                                     PNG_FLAG_CRC_CRITICAL_IGNORE)
+
+#define PNG_FLAG_CRC_MASK           (PNG_FLAG_CRC_ANCILLARY_MASK | \
+                                     PNG_FLAG_CRC_CRITICAL_MASK)
+
+/* Save typing and make code easier to understand */
+
+#define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \
+   abs((int)((c1).green) - (int)((c2).green)) + \
+   abs((int)((c1).blue) - (int)((c2).blue)))
+
+/* Added to libpng-1.6.0: scale a 16-bit value in the range 0..65535 to 0..255
+ * by dividing by 257 *with rounding*.  This macro is exact for the given range.
+ * See the discourse in pngrtran.c png_do_scale_16_to_8.  The values in the
+ * macro were established by experiment (modifying the added value).  The macro
+ * has a second variant that takes a value already scaled by 255 and divides by
+ * 65535 - this has a maximum error of .502.  Over the range 0..65535*65535 it
+ * only gives off-by-one errors and only for 0.5% (1 in 200) of the values.
+ */
+#define PNG_DIV65535(v24) (((v24) + 32895) >> 16)
+#define PNG_DIV257(v16) PNG_DIV65535((png_uint_32)(v16) * 255)
+
+/* Added to libpng-1.2.6 JB */
+#define PNG_ROWBYTES(pixel_bits, width) \
+    ((pixel_bits) >= 8 ? \
+    ((png_size_t)(width) * (((png_size_t)(pixel_bits)) >> 3)) : \
+    (( ((png_size_t)(width) * ((png_size_t)(pixel_bits))) + 7) >> 3) )
+
+/* PNG_OUT_OF_RANGE returns true if value is outside the range
+ * ideal-delta..ideal+delta.  Each argument is evaluated twice.
+ * "ideal" and "delta" should be constants, normally simple
+ * integers, "value" a variable. Added to libpng-1.2.6 JB
+ */
+#define PNG_OUT_OF_RANGE(value, ideal, delta) \
+   ( (value) < (ideal)-(delta) || (value) > (ideal)+(delta) )
+
+/* Conversions between fixed and floating point, only defined if
+ * required (to make sure the code doesn't accidentally use float
+ * when it is supposedly disabled.)
+ */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+/* The floating point conversion can't overflow, though it can and
+ * does lose accuracy relative to the original fixed point value.
+ * In practice this doesn't matter because png_fixed_point only
+ * stores numbers with very low precision.  The png_ptr and s
+ * arguments are unused by default but are there in case error
+ * checking becomes a requirement.
+ */
+#define png_float(png_ptr, fixed, s) (.00001 * (fixed))
+
+/* The fixed point conversion performs range checking and evaluates
+ * its argument multiple times, so must be used with care.  The
+ * range checking uses the PNG specification values for a signed
+ * 32 bit fixed point value except that the values are deliberately
+ * rounded-to-zero to an integral value - 21474 (21474.83 is roughly
+ * (2^31-1) * 100000). 's' is a string that describes the value being
+ * converted.
+ *
+ * NOTE: this macro will raise a png_error if the range check fails,
+ * therefore it is normally only appropriate to use this on values
+ * that come from API calls or other sources where an out of range
+ * error indicates a programming error, not a data error!
+ *
+ * NOTE: by default this is off - the macro is not used - because the
+ * function call saves a lot of code.
+ */
+#ifdef PNG_FIXED_POINT_MACRO_SUPPORTED
+#define png_fixed(png_ptr, fp, s) ((fp) <= 21474 && (fp) >= -21474 ?\
+    ((png_fixed_point)(100000 * (fp))) : (png_fixed_error(png_ptr, s),0))
+#endif
+/* else the corresponding function is defined below, inside the scope of the
+ * cplusplus test.
+ */
+#endif
+
+/* Constants for known chunk types.  If you need to add a chunk, define the name
+ * here.  For historical reasons these constants have the form png_<name>; i.e.
+ * the prefix is lower case.  Please use decimal values as the parameters to
+ * match the ISO PNG specification and to avoid relying on the C locale
+ * interpretation of character values.
+ *
+ * Prior to 1.5.6 these constants were strings, as of 1.5.6 png_uint_32 values
+ * are computed and a new macro (PNG_STRING_FROM_CHUNK) added to allow a string
+ * to be generated if required.
+ *
+ * PNG_32b correctly produces a value shifted by up to 24 bits, even on
+ * architectures where (int) is only 16 bits.
+ */
+#define PNG_32b(b,s) ((png_uint_32)(b) << (s))
+#define PNG_U32(b1,b2,b3,b4) \
+   (PNG_32b(b1,24) | PNG_32b(b2,16) | PNG_32b(b3,8) | PNG_32b(b4,0))
+
+/* Constants for known chunk types.
+ *
+ * MAINTAINERS: If you need to add a chunk, define the name here.
+ * For historical reasons these constants have the form png_<name>; i.e.
+ * the prefix is lower case.  Please use decimal values as the parameters to
+ * match the ISO PNG specification and to avoid relying on the C locale
+ * interpretation of character values.  Please keep the list sorted.
+ *
+ * Notice that PNG_U32 is used to define a 32-bit value for the 4 byte chunk
+ * type.  In fact the specification does not express chunk types this way,
+ * however using a 32-bit value means that the chunk type can be read from the
+ * stream using exactly the same code as used for a 32-bit unsigned value and
+ * can be examined far more efficiently (using one arithmetic compare).
+ *
+ * Prior to 1.5.6 the chunk type constants were expressed as C strings.  The
+ * libpng API still uses strings for 'unknown' chunks and a macro,
+ * PNG_STRING_FROM_CHUNK, allows a string to be generated if required.  Notice
+ * that for portable code numeric values must still be used; the string "IHDR"
+ * is not portable and neither is PNG_U32('I', 'H', 'D', 'R').
+ *
+ * In 1.7.0 the definitions will be made public in png.h to avoid having to
+ * duplicate the same definitions in application code.
+ */
+#define png_IDAT PNG_U32( 73,  68,  65,  84)
+#define png_IEND PNG_U32( 73,  69,  78,  68)
+#define png_IHDR PNG_U32( 73,  72,  68,  82)
+#define png_PLTE PNG_U32( 80,  76,  84,  69)
+#define png_bKGD PNG_U32( 98,  75,  71,  68)
+#define png_cHRM PNG_U32( 99,  72,  82,  77)
+#define png_fRAc PNG_U32(102,  82,  65,  99) /* registered, not defined */
+#define png_gAMA PNG_U32(103,  65,  77,  65)
+#define png_gIFg PNG_U32(103,  73,  70, 103)
+#define png_gIFt PNG_U32(103,  73,  70, 116) /* deprecated */
+#define png_gIFx PNG_U32(103,  73,  70, 120)
+#define png_hIST PNG_U32(104,  73,  83,  84)
+#define png_iCCP PNG_U32(105,  67,  67,  80)
+#define png_iTXt PNG_U32(105,  84,  88, 116)
+#define png_oFFs PNG_U32(111,  70,  70, 115)
+#define png_pCAL PNG_U32(112,  67,  65,  76)
+#define png_pHYs PNG_U32(112,  72,  89, 115)
+#define png_sBIT PNG_U32(115,  66,  73,  84)
+#define png_sCAL PNG_U32(115,  67,  65,  76)
+#define png_sPLT PNG_U32(115,  80,  76,  84)
+#define png_sRGB PNG_U32(115,  82,  71,  66)
+#define png_sTER PNG_U32(115,  84,  69,  82)
+#define png_tEXt PNG_U32(116,  69,  88, 116)
+#define png_tIME PNG_U32(116,  73,  77,  69)
+#define png_tRNS PNG_U32(116,  82,  78,  83)
+#define png_zTXt PNG_U32(122,  84,  88, 116)
+
+/* The following will work on (signed char*) strings, whereas the get_uint_32
+ * macro will fail on top-bit-set values because of the sign extension.
+ */
+#define PNG_CHUNK_FROM_STRING(s)\
+   PNG_U32(0xff&(s)[0], 0xff&(s)[1], 0xff&(s)[2], 0xff&(s)[3])
+
+/* This uses (char), not (png_byte) to avoid warnings on systems where (char) is
+ * signed and the argument is a (char[])  This macro will fail miserably on
+ * systems where (char) is more than 8 bits.
+ */
+#define PNG_STRING_FROM_CHUNK(s,c)\
+   (void)(((char*)(s))[0]=(char)((c)>>24), ((char*)(s))[1]=(char)((c)>>16),\
+   ((char*)(s))[2]=(char)((c)>>8), ((char*)(s))[3]=(char)((c)))
+
+/* Do the same but terminate with a null character. */
+#define PNG_CSTRING_FROM_CHUNK(s,c)\
+   (void)(PNG_STRING_FROM_CHUNK(s,c), ((char*)(s))[4] = 0)
+
+/* Test on flag values as defined in the spec (section 5.4): */
+#define PNG_CHUNK_ANCILLARY(c)   (1 & ((c) >> 29))
+#define PNG_CHUNK_CRITICAL(c)     (!PNG_CHUNK_ANCILLARY(c))
+#define PNG_CHUNK_PRIVATE(c)      (1 & ((c) >> 21))
+#define PNG_CHUNK_RESERVED(c)     (1 & ((c) >> 13))
+#define PNG_CHUNK_SAFE_TO_COPY(c) (1 & ((c) >>  5))
+
+/* Gamma values (new at libpng-1.5.4): */
+#define PNG_GAMMA_MAC_OLD 151724  /* Assume '1.8' is really 2.2/1.45! */
+#define PNG_GAMMA_MAC_INVERSE 65909
+#define PNG_GAMMA_sRGB_INVERSE 45455
+
+/* Almost everything below is C specific; the #defines above can be used in
+ * non-C code (so long as it is C-preprocessed) the rest of this stuff cannot.
+ */
+#ifndef PNG_VERSION_INFO_ONLY
+
+#include "pngstruct.h"
+#include "pnginfo.h"
+
+/* Validate the include paths - the include path used to generate pnglibconf.h
+ * must match that used in the build, or we must be using pnglibconf.h.prebuilt:
+ */
+#if PNG_ZLIB_VERNUM != 0 && PNG_ZLIB_VERNUM != ZLIB_VERNUM
+#  error ZLIB_VERNUM != PNG_ZLIB_VERNUM \
+      "-I (include path) error: see the notes in pngpriv.h"
+   /* This means that when pnglibconf.h was built the copy of zlib.h that it
+    * used is not the same as the one being used here.  Because the build of
+    * libpng makes decisions to use inflateInit2 and inflateReset2 based on the
+    * zlib version number and because this affects handling of certain broken
+    * PNG files the -I directives must match.
+    *
+    * The most likely explanation is that you passed a -I in CFLAGS. This will
+    * not work; all the preprocessor directories and in particular all the -I
+    * directives must be in CPPFLAGS.
+    */
+#endif
+
+/* This is used for 16 bit gamma tables -- only the top level pointers are
+ * const; this could be changed:
+ */
+typedef const png_uint_16p * png_const_uint_16pp;
+
+/* Added to libpng-1.5.7: sRGB conversion tables */
+#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\
+   defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
+#ifdef PNG_SIMPLIFIED_READ_SUPPORTED
+PNG_INTERNAL_DATA(const png_uint_16, png_sRGB_table, [256]);
+   /* Convert from an sRGB encoded value 0..255 to a 16-bit linear value,
+    * 0..65535.  This table gives the closest 16-bit answers (no errors).
+    */
+#endif
+
+PNG_INTERNAL_DATA(const png_uint_16, png_sRGB_base, [512]);
+PNG_INTERNAL_DATA(const png_byte, png_sRGB_delta, [512]);
+
+#define PNG_sRGB_FROM_LINEAR(linear) ((png_byte)((png_sRGB_base[(linear)>>15] +\
+   ((((linear)&0x7fff)*png_sRGB_delta[(linear)>>15])>>12)) >> 8))
+   /* Given a value 'linear' in the range 0..255*65535 calculate the 8-bit sRGB
+    * encoded value with maximum error 0.646365.  Note that the input is not a
+    * 16-bit value; it has been multiplied by 255! */
+#endif /* SIMPLIFIED_READ/WRITE */
+
+
+/* Inhibit C++ name-mangling for libpng functions but not for system calls. */
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Internal functions; these are not exported from a DLL however because they
+ * are used within several of the C source files they have to be C extern.
+ *
+ * All of these functions must be declared with PNG_INTERNAL_FUNCTION.
+ */
+
+/* Zlib support */
+#define PNG_UNEXPECTED_ZLIB_RETURN (-7)
+PNG_INTERNAL_FUNCTION(void, png_zstream_error,(png_structrp png_ptr, int ret),
+   PNG_EMPTY);
+   /* Used by the zlib handling functions to ensure that z_stream::msg is always
+    * set before they return.
+    */
+
+#ifdef PNG_WRITE_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_free_buffer_list,(png_structrp png_ptr,
+   png_compression_bufferp *list),PNG_EMPTY);
+   /* Free the buffer list used by the compressed write code. */
+#endif
+
+#if defined(PNG_FLOATING_POINT_SUPPORTED) && \
+   !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \
+   (defined(PNG_gAMA_SUPPORTED) || defined(PNG_cHRM_SUPPORTED) || \
+   defined(PNG_sCAL_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) || \
+   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)) || \
+   (defined(PNG_sCAL_SUPPORTED) && \
+   defined(PNG_FLOATING_ARITHMETIC_SUPPORTED))
+PNG_INTERNAL_FUNCTION(png_fixed_point,png_fixed,(png_const_structrp png_ptr,
+   double fp, png_const_charp text),PNG_EMPTY);
+#endif
+
+/* Check the user version string for compatibility, returns false if the version
+ * numbers aren't compatible.
+ */
+PNG_INTERNAL_FUNCTION(int,png_user_version_check,(png_structrp png_ptr,
+   png_const_charp user_png_ver),PNG_EMPTY);
+
+/* Internal base allocator - no messages, NULL on failure to allocate.  This
+ * does, however, call the application provided allocator and that could call
+ * png_error (although that would be a bug in the application implementation.)
+ */
+PNG_INTERNAL_FUNCTION(png_voidp,png_malloc_base,(png_const_structrp png_ptr,
+   png_alloc_size_t size),PNG_ALLOCATED);
+
+#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) ||\
+   defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED)
+/* Internal array allocator, outputs no error or warning messages on failure,
+ * just returns NULL.  
+ */
+PNG_INTERNAL_FUNCTION(png_voidp,png_malloc_array,(png_const_structrp png_ptr,
+   int nelements, size_t element_size),PNG_ALLOCATED);
+
+/* The same but an existing array is extended by add_elements.  This function
+ * also memsets the new elements to 0 and copies the old elements.  The old
+ * array is not freed or altered.
+ */
+PNG_INTERNAL_FUNCTION(png_voidp,png_realloc_array,(png_const_structrp png_ptr,
+   png_const_voidp array, int old_elements, int add_elements,
+   size_t element_size),PNG_ALLOCATED);
+#endif /* text, sPLT or unknown chunks */
+
+/* Magic to create a struct when there is no struct to call the user supplied
+ * memory allocators.  Because error handling has not been set up the memory
+ * handlers can't safely call png_error, but this is an obscure and undocumented
+ * restriction so libpng has to assume that the 'free' handler, at least, might
+ * call png_error.
+ */
+PNG_INTERNAL_FUNCTION(png_structp,png_create_png_struct,
+   (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn,
+    png_error_ptr warn_fn, png_voidp mem_ptr, png_malloc_ptr malloc_fn,
+    png_free_ptr free_fn),PNG_ALLOCATED);
+
+/* Free memory from internal libpng struct */
+PNG_INTERNAL_FUNCTION(void,png_destroy_png_struct,(png_structrp png_ptr),
+   PNG_EMPTY);
+
+/* Free an allocated jmp_buf (always succeeds) */
+PNG_INTERNAL_FUNCTION(void,png_free_jmpbuf,(png_structrp png_ptr),PNG_EMPTY);
+
+/* Function to allocate memory for zlib.  PNGAPI is disallowed. */
+PNG_INTERNAL_FUNCTION(voidpf,png_zalloc,(voidpf png_ptr, uInt items, uInt size),
+   PNG_ALLOCATED);
+
+/* Function to free memory for zlib.  PNGAPI is disallowed. */
+PNG_INTERNAL_FUNCTION(void,png_zfree,(voidpf png_ptr, voidpf ptr),PNG_EMPTY);
+
+/* Next four functions are used internally as callbacks.  PNGCBAPI is required
+ * but not PNG_EXPORT.  PNGAPI added at libpng version 1.2.3, changed to
+ * PNGCBAPI at 1.5.0
+ */
+
+PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_read_data,(png_structp png_ptr,
+    png_bytep data, png_size_t length),PNG_EMPTY);
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_push_fill_buffer,(png_structp png_ptr,
+    png_bytep buffer, png_size_t length),PNG_EMPTY);
+#endif
+
+PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_write_data,(png_structp png_ptr,
+    png_bytep data, png_size_t length),PNG_EMPTY);
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+#  ifdef PNG_STDIO_SUPPORTED
+PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_flush,(png_structp png_ptr),
+   PNG_EMPTY);
+#  endif
+#endif
+
+/* Reset the CRC variable */
+PNG_INTERNAL_FUNCTION(void,png_reset_crc,(png_structrp png_ptr),PNG_EMPTY);
+
+/* Write the "data" buffer to whatever output you are using */
+PNG_INTERNAL_FUNCTION(void,png_write_data,(png_structrp png_ptr,
+    png_const_bytep data, png_size_t length),PNG_EMPTY);
+
+/* Read and check the PNG file signature */
+PNG_INTERNAL_FUNCTION(void,png_read_sig,(png_structrp png_ptr,
+   png_inforp info_ptr),PNG_EMPTY);
+
+/* Read the chunk header (length + type name) */
+PNG_INTERNAL_FUNCTION(png_uint_32,png_read_chunk_header,(png_structrp png_ptr),
+   PNG_EMPTY);
+
+/* Read data from whatever input you are using into the "data" buffer */
+PNG_INTERNAL_FUNCTION(void,png_read_data,(png_structrp png_ptr, png_bytep data,
+    png_size_t length),PNG_EMPTY);
+
+/* Read bytes into buf, and update png_ptr->crc */
+PNG_INTERNAL_FUNCTION(void,png_crc_read,(png_structrp png_ptr, png_bytep buf,
+    png_uint_32 length),PNG_EMPTY);
+
+/* Read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */
+PNG_INTERNAL_FUNCTION(int,png_crc_finish,(png_structrp png_ptr,
+   png_uint_32 skip),PNG_EMPTY);
+
+/* Read the CRC from the file and compare it to the libpng calculated CRC */
+PNG_INTERNAL_FUNCTION(int,png_crc_error,(png_structrp png_ptr),PNG_EMPTY);
+
+/* Calculate the CRC over a section of data.  Note that we are only
+ * passing a maximum of 64K on systems that have this as a memory limit,
+ * since this is the maximum buffer size we can specify.
+ */
+PNG_INTERNAL_FUNCTION(void,png_calculate_crc,(png_structrp png_ptr,
+   png_const_bytep ptr, png_size_t length),PNG_EMPTY);
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_flush,(png_structrp png_ptr),PNG_EMPTY);
+#endif
+
+/* Write various chunks */
+
+/* Write the IHDR chunk, and update the png_struct with the necessary
+ * information.
+ */
+PNG_INTERNAL_FUNCTION(void,png_write_IHDR,(png_structrp png_ptr,
+   png_uint_32 width, png_uint_32 height, int bit_depth, int color_type,
+   int compression_method, int filter_method, int interlace_method),PNG_EMPTY);
+
+PNG_INTERNAL_FUNCTION(void,png_write_PLTE,(png_structrp png_ptr,
+   png_const_colorp palette, png_uint_32 num_pal),PNG_EMPTY);
+
+PNG_INTERNAL_FUNCTION(void,png_compress_IDAT,(png_structrp png_ptr,
+   png_const_bytep row_data, png_alloc_size_t row_data_length, int flush),
+   PNG_EMPTY);
+
+PNG_INTERNAL_FUNCTION(void,png_write_IEND,(png_structrp png_ptr),PNG_EMPTY);
+
+#ifdef PNG_WRITE_gAMA_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_gAMA_fixed,(png_structrp png_ptr,
+    png_fixed_point file_gamma),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_sBIT_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_sBIT,(png_structrp png_ptr,
+    png_const_color_8p sbit, int color_type),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_cHRM_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_cHRM_fixed,(png_structrp png_ptr,
+    const png_xy *xy), PNG_EMPTY);
+    /* The xy value must have been previously validated */
+#endif
+
+#ifdef PNG_WRITE_sRGB_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_sRGB,(png_structrp png_ptr,
+    int intent),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_iCCP_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_iCCP,(png_structrp png_ptr,
+   png_const_charp name, png_const_bytep profile), PNG_EMPTY);
+   /* The profile must have been previously validated for correctness, the
+    * length comes from the first four bytes.  Only the base, deflate,
+    * compression is supported.
+    */
+#endif
+
+#ifdef PNG_WRITE_sPLT_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_sPLT,(png_structrp png_ptr,
+    png_const_sPLT_tp palette),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_tRNS_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_tRNS,(png_structrp png_ptr,
+    png_const_bytep trans, png_const_color_16p values, int number,
+    int color_type),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_bKGD_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_bKGD,(png_structrp png_ptr,
+    png_const_color_16p values, int color_type),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_hIST_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_hIST,(png_structrp png_ptr,
+    png_const_uint_16p hist, int num_hist),PNG_EMPTY);
+#endif
+
+/* Chunks that have keywords */
+#ifdef PNG_WRITE_tEXt_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_tEXt,(png_structrp png_ptr,
+   png_const_charp key, png_const_charp text, png_size_t text_len),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_zTXt_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_zTXt,(png_structrp png_ptr, png_const_charp
+    key, png_const_charp text, int compression),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_iTXt_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_iTXt,(png_structrp png_ptr,
+    int compression, png_const_charp key, png_const_charp lang,
+    png_const_charp lang_key, png_const_charp text),PNG_EMPTY);
+#endif
+
+#ifdef PNG_TEXT_SUPPORTED  /* Added at version 1.0.14 and 1.2.4 */
+PNG_INTERNAL_FUNCTION(int,png_set_text_2,(png_const_structrp png_ptr,
+    png_inforp info_ptr, png_const_textp text_ptr, int num_text),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_oFFs_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_oFFs,(png_structrp png_ptr,
+    png_int_32 x_offset, png_int_32 y_offset, int unit_type),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_pCAL_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_pCAL,(png_structrp png_ptr,
+    png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams,
+    png_const_charp units, png_charpp params),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_pHYs_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_pHYs,(png_structrp png_ptr,
+    png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit,
+    int unit_type),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_tIME_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_tIME,(png_structrp png_ptr,
+    png_const_timep mod_time),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_sCAL_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_sCAL_s,(png_structrp png_ptr,
+    int unit, png_const_charp width, png_const_charp height),PNG_EMPTY);
+#endif
+
+/* Called when finished processing a row of data */
+PNG_INTERNAL_FUNCTION(void,png_write_finish_row,(png_structrp png_ptr),
+    PNG_EMPTY);
+
+/* Internal use only.   Called before first row of data */
+PNG_INTERNAL_FUNCTION(void,png_write_start_row,(png_structrp png_ptr),
+    PNG_EMPTY);
+
+/* Combine a row of data, dealing with alpha, etc. if requested.  'row' is an
+ * array of png_ptr->width pixels.  If the image is not interlaced or this
+ * is the final pass this just does a memcpy, otherwise the "display" flag
+ * is used to determine whether to copy pixels that are not in the current pass.
+ *
+ * Because 'png_do_read_interlace' (below) replicates pixels this allows this
+ * function to achieve the documented 'blocky' appearance during interlaced read
+ * if display is 1 and the 'sparkle' appearance, where existing pixels in 'row'
+ * are not changed if they are not in the current pass, when display is 0.
+ *
+ * 'display' must be 0 or 1, otherwise the memcpy will be done regardless.
+ *
+ * The API always reads from the png_struct row buffer and always assumes that
+ * it is full width (png_do_read_interlace has already been called.)
+ *
+ * This function is only ever used to write to row buffers provided by the
+ * caller of the relevant libpng API and the row must have already been
+ * transformed by the read transformations.
+ *
+ * The PNG_USE_COMPILE_TIME_MASKS option causes generation of pre-computed
+ * bitmasks for use within the code, otherwise runtime generated masks are used.
+ * The default is compile time masks.
+ */
+#ifndef PNG_USE_COMPILE_TIME_MASKS
+#  define PNG_USE_COMPILE_TIME_MASKS 1
+#endif
+PNG_INTERNAL_FUNCTION(void,png_combine_row,(png_const_structrp png_ptr,
+    png_bytep row, int display),PNG_EMPTY);
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+/* Expand an interlaced row: the 'row_info' describes the pass data that has
+ * been read in and must correspond to the pixels in 'row', the pixels are
+ * expanded (moved apart) in 'row' to match the final layout, when doing this
+ * the pixels are *replicated* to the intervening space.  This is essential for
+ * the correct operation of png_combine_row, above.
+ */
+PNG_INTERNAL_FUNCTION(void,png_do_read_interlace,(png_row_infop row_info,
+    png_bytep row, int pass, png_uint_32 transformations),PNG_EMPTY);
+#endif
+
+/* GRR TO DO (2.0 or whenever):  simplify other internal calling interfaces */
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+/* Grab pixels out of a row for an interlaced pass */
+PNG_INTERNAL_FUNCTION(void,png_do_write_interlace,(png_row_infop row_info,
+    png_bytep row, int pass),PNG_EMPTY);
+#endif
+
+/* Unfilter a row: check the filter value before calling this, there is no point
+ * calling it for PNG_FILTER_VALUE_NONE.
+ */
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row,(png_structrp pp, png_row_infop
+    row_info, png_bytep row, png_const_bytep prev_row, int filter),PNG_EMPTY);
+
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_neon,(png_row_infop row_info,
+    png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_neon,(png_row_infop
+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_neon,(png_row_infop
+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_neon,(png_row_infop
+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_neon,(png_row_infop
+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_neon,(png_row_infop
+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_neon,(png_row_infop
+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+
+/* Choose the best filter to use and filter the row data */
+PNG_INTERNAL_FUNCTION(void,png_write_find_filter,(png_structrp png_ptr,
+    png_row_infop row_info),PNG_EMPTY);
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_read_IDAT_data,(png_structrp png_ptr,
+   png_bytep output, png_alloc_size_t avail_out),PNG_EMPTY);
+   /* Read 'avail_out' bytes of data from the IDAT stream.  If the output buffer
+    * is NULL the function checks, instead, for the end of the stream.  In this
+    * case a benign error will be issued if the stream end is not found or if
+    * extra data has to be consumed.
+    */
+PNG_INTERNAL_FUNCTION(void,png_read_finish_IDAT,(png_structrp png_ptr),
+   PNG_EMPTY);
+   /* This cleans up when the IDAT LZ stream does not end when the last image
+    * byte is read; there is still some pending input.
+    */
+
+PNG_INTERNAL_FUNCTION(void,png_read_finish_row,(png_structrp png_ptr),
+   PNG_EMPTY);
+   /* Finish a row while reading, dealing with interlacing passes, etc. */
+#endif /* SEQUENTIAL_READ */
+
+/* Initialize the row buffers, etc. */
+PNG_INTERNAL_FUNCTION(void,png_read_start_row,(png_structrp png_ptr),PNG_EMPTY);
+
+#ifdef PNG_READ_TRANSFORMS_SUPPORTED
+/* Optional call to update the users info structure */
+PNG_INTERNAL_FUNCTION(void,png_read_transform_info,(png_structrp png_ptr,
+    png_inforp info_ptr),PNG_EMPTY);
+#endif
+
+/* Shared transform functions, defined in pngtran.c */
+#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
+    defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
+PNG_INTERNAL_FUNCTION(void,png_do_strip_channel,(png_row_infop row_info,
+    png_bytep row, int at_start),PNG_EMPTY);
+#endif
+
+#ifdef PNG_16BIT_SUPPORTED
+#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
+PNG_INTERNAL_FUNCTION(void,png_do_swap,(png_row_infop row_info,
+    png_bytep row),PNG_EMPTY);
+#endif
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED) || \
+    defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+PNG_INTERNAL_FUNCTION(void,png_do_packswap,(png_row_infop row_info,
+    png_bytep row),PNG_EMPTY);
+#endif
+
+#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
+PNG_INTERNAL_FUNCTION(void,png_do_invert,(png_row_infop row_info,
+    png_bytep row),PNG_EMPTY);
+#endif
+
+#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
+PNG_INTERNAL_FUNCTION(void,png_do_bgr,(png_row_infop row_info,
+    png_bytep row),PNG_EMPTY);
+#endif
+
+/* The following decodes the appropriate chunks, and does error correction,
+ * then calls the appropriate callback for the chunk if it is valid.
+ */
+
+/* Decode the IHDR chunk */
+PNG_INTERNAL_FUNCTION(void,png_handle_IHDR,(png_structrp png_ptr,
+    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_handle_PLTE,(png_structrp png_ptr,
+    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_handle_IEND,(png_structrp png_ptr,
+    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+
+#ifdef PNG_READ_bKGD_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_bKGD,(png_structrp png_ptr,
+    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_cHRM_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_cHRM,(png_structrp png_ptr,
+    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_gAMA_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_gAMA,(png_structrp png_ptr,
+    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_hIST_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_hIST,(png_structrp png_ptr,
+    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_iCCP_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_iCCP,(png_structrp png_ptr,
+    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif /* READ_iCCP */
+
+#ifdef PNG_READ_iTXt_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_iTXt,(png_structrp png_ptr,
+    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_oFFs_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_oFFs,(png_structrp png_ptr,
+    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_pCAL_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_pCAL,(png_structrp png_ptr,
+    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_pHYs_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_pHYs,(png_structrp png_ptr,
+    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_sBIT_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_sBIT,(png_structrp png_ptr,
+    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_sCAL_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_sCAL,(png_structrp png_ptr,
+    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_sPLT_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_sPLT,(png_structrp png_ptr,
+    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif /* READ_sPLT */
+
+#ifdef PNG_READ_sRGB_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_sRGB,(png_structrp png_ptr,
+    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_tEXt_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_tEXt,(png_structrp png_ptr,
+    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_tIME_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_tIME,(png_structrp png_ptr,
+    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_tRNS_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_tRNS,(png_structrp png_ptr,
+    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_zTXt_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_zTXt,(png_structrp png_ptr,
+    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+PNG_INTERNAL_FUNCTION(void,png_check_chunk_name,(png_structrp png_ptr,
+    png_uint_32 chunk_name),PNG_EMPTY);
+
+PNG_INTERNAL_FUNCTION(void,png_handle_unknown,(png_structrp png_ptr,
+    png_inforp info_ptr, png_uint_32 length, int keep),PNG_EMPTY);
+   /* This is the function that gets called for unknown chunks.  The 'keep'
+    * argument is either non-zero for a known chunk that has been set to be
+    * handled as unknown or zero for an unknown chunk.  By default the function
+    * just skips the chunk or errors out if it is critical.
+    */
+
+#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) ||\
+    defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED)
+PNG_INTERNAL_FUNCTION(int,png_chunk_unknown_handling,
+    (png_const_structrp png_ptr, png_uint_32 chunk_name),PNG_EMPTY);
+   /* Exactly as the API png_handle_as_unknown() except that the argument is a
+    * 32-bit chunk name, not a string.
+    */
+#endif /* READ_UNKNOWN_CHUNKS || HANDLE_AS_UNKNOWN */
+
+/* Handle the transformations for reading and writing */
+#ifdef PNG_READ_TRANSFORMS_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_read_transformations,(png_structrp png_ptr,
+   png_row_infop row_info),PNG_EMPTY);
+#endif
+#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_write_transformations,(png_structrp png_ptr,
+   png_row_infop row_info),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_TRANSFORMS_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_init_read_transformations,(png_structrp png_ptr),
+    PNG_EMPTY);
+#endif
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_push_read_chunk,(png_structrp png_ptr,
+    png_inforp info_ptr),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_read_sig,(png_structrp png_ptr,
+    png_inforp info_ptr),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_check_crc,(png_structrp png_ptr),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_crc_skip,(png_structrp png_ptr,
+    png_uint_32 length),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_crc_finish,(png_structrp png_ptr),
+    PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_save_buffer,(png_structrp png_ptr),
+    PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_restore_buffer,(png_structrp png_ptr,
+    png_bytep buffer, png_size_t buffer_length),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_read_IDAT,(png_structrp png_ptr),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_process_IDAT_data,(png_structrp png_ptr,
+    png_bytep buffer, png_size_t buffer_length),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_process_row,(png_structrp png_ptr),
+    PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_handle_unknown,(png_structrp png_ptr,
+   png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_have_info,(png_structrp png_ptr,
+   png_inforp info_ptr),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_have_end,(png_structrp png_ptr,
+   png_inforp info_ptr),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_have_row,(png_structrp png_ptr,
+     png_bytep row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_read_end,(png_structrp png_ptr,
+    png_inforp info_ptr),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_process_some_data,(png_structrp png_ptr,
+    png_inforp info_ptr),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_push_finish_row,(png_structrp png_ptr),
+    PNG_EMPTY);
+#  ifdef PNG_READ_tEXt_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_push_handle_tEXt,(png_structrp png_ptr,
+    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_read_tEXt,(png_structrp png_ptr,
+    png_inforp info_ptr),PNG_EMPTY);
+#  endif
+#  ifdef PNG_READ_zTXt_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_push_handle_zTXt,(png_structrp png_ptr,
+    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_read_zTXt,(png_structrp png_ptr,
+    png_inforp info_ptr),PNG_EMPTY);
+#  endif
+#  ifdef PNG_READ_iTXt_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_push_handle_iTXt,(png_structrp png_ptr,
+    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_read_iTXt,(png_structrp png_ptr,
+    png_inforp info_ptr),PNG_EMPTY);
+#  endif
+
+#endif /* PROGRESSIVE_READ */
+
+/* Added at libpng version 1.6.0 */
+#ifdef PNG_GAMMA_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_colorspace_set_gamma,(png_const_structrp png_ptr,
+    png_colorspacerp colorspace, png_fixed_point gAMA), PNG_EMPTY);
+   /* Set the colorspace gamma with a value provided by the application or by
+    * the gAMA chunk on read.  The value will override anything set by an ICC
+    * profile.
+    */
+
+PNG_INTERNAL_FUNCTION(void,png_colorspace_sync_info,(png_const_structrp png_ptr,
+    png_inforp info_ptr), PNG_EMPTY);
+    /* Synchronize the info 'valid' flags with the colorspace */
+
+PNG_INTERNAL_FUNCTION(void,png_colorspace_sync,(png_const_structrp png_ptr,
+    png_inforp info_ptr), PNG_EMPTY);
+    /* Copy the png_struct colorspace to the info_struct and call the above to
+     * synchronize the flags.  Checks for NULL info_ptr and does nothing.
+     */
+#endif
+
+/* Added at libpng version 1.4.0 */
+#ifdef PNG_COLORSPACE_SUPPORTED
+/* These internal functions are for maintaining the colorspace structure within
+ * a png_info or png_struct (or, indeed, both).
+ */
+PNG_INTERNAL_FUNCTION(int,png_colorspace_set_chromaticities,
+   (png_const_structrp png_ptr, png_colorspacerp colorspace, const png_xy *xy,
+    int preferred), PNG_EMPTY);
+
+PNG_INTERNAL_FUNCTION(int,png_colorspace_set_endpoints,
+   (png_const_structrp png_ptr, png_colorspacerp colorspace, const png_XYZ *XYZ,
+    int preferred), PNG_EMPTY);
+
+#ifdef PNG_sRGB_SUPPORTED
+PNG_INTERNAL_FUNCTION(int,png_colorspace_set_sRGB,(png_const_structrp png_ptr,
+   png_colorspacerp colorspace, int intent), PNG_EMPTY);
+   /* This does set the colorspace gAMA and cHRM values too, but doesn't set the
+    * flags to write them, if it returns false there was a problem and an error
+    * message has already been output (but the colorspace may still need to be
+    * synced to record the invalid flag).
+    */
+#endif /* sRGB */
+
+#ifdef PNG_iCCP_SUPPORTED
+PNG_INTERNAL_FUNCTION(int,png_colorspace_set_ICC,(png_const_structrp png_ptr,
+   png_colorspacerp colorspace, png_const_charp name,
+   png_uint_32 profile_length, png_const_bytep profile, int color_type),
+   PNG_EMPTY);
+   /* The 'name' is used for information only */
+
+/* Routines for checking parts of an ICC profile. */
+PNG_INTERNAL_FUNCTION(int,png_icc_check_length,(png_const_structrp png_ptr,
+   png_colorspacerp colorspace, png_const_charp name,
+   png_uint_32 profile_length), PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(int,png_icc_check_header,(png_const_structrp png_ptr,
+   png_colorspacerp colorspace, png_const_charp name,
+   png_uint_32 profile_length,
+   png_const_bytep profile /* first 132 bytes only */, int color_type),
+   PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(int,png_icc_check_tag_table,(png_const_structrp png_ptr,
+   png_colorspacerp colorspace, png_const_charp name,
+   png_uint_32 profile_length,
+   png_const_bytep profile /* header plus whole tag table */), PNG_EMPTY);
+#ifdef PNG_sRGB_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_icc_set_sRGB,(
+   png_const_structrp png_ptr, png_colorspacerp colorspace,
+   png_const_bytep profile, uLong adler), PNG_EMPTY);
+   /* 'adler' is the Adler32 checksum of the uncompressed profile data. It may
+    * be zero to indicate that it is not available.  It is used, if provided,
+    * as a fast check on the profile when checking to see if it is sRGB.
+    */
+#endif
+#endif /* iCCP */
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_colorspace_set_rgb_coefficients,
+   (png_structrp png_ptr), PNG_EMPTY);
+   /* Set the rgb_to_gray coefficients from the colorspace Y values */
+#endif /* READ_RGB_TO_GRAY */
+#endif /* COLORSPACE */
+
+/* Added at libpng version 1.4.0 */
+PNG_INTERNAL_FUNCTION(void,png_check_IHDR,(png_const_structrp png_ptr,
+    png_uint_32 width, png_uint_32 height, int bit_depth,
+    int color_type, int interlace_type, int compression_type,
+    int filter_type),PNG_EMPTY);
+
+/* Added at libpng version 1.5.10 */
+#if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \
+    defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED)
+PNG_INTERNAL_FUNCTION(void,png_do_check_palette_indexes,
+   (png_structrp png_ptr, png_row_infop row_info),PNG_EMPTY);
+#endif
+
+#if defined(PNG_FLOATING_POINT_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED)
+PNG_INTERNAL_FUNCTION(void,png_fixed_error,(png_const_structrp png_ptr,
+   png_const_charp name),PNG_NORETURN);
+#endif
+
+/* Puts 'string' into 'buffer' at buffer[pos], taking care never to overwrite
+ * the end.  Always leaves the buffer nul terminated.  Never errors out (and
+ * there is no error code.)
+ */
+PNG_INTERNAL_FUNCTION(size_t,png_safecat,(png_charp buffer, size_t bufsize,
+   size_t pos, png_const_charp string),PNG_EMPTY);
+
+/* Various internal functions to handle formatted warning messages, currently
+ * only implemented for warnings.
+ */
+#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_TIME_RFC1123_SUPPORTED)
+/* Utility to dump an unsigned value into a buffer, given a start pointer and
+ * and end pointer (which should point just *beyond* the end of the buffer!)
+ * Returns the pointer to the start of the formatted string.  This utility only
+ * does unsigned values.
+ */
+PNG_INTERNAL_FUNCTION(png_charp,png_format_number,(png_const_charp start,
+   png_charp end, int format, png_alloc_size_t number),PNG_EMPTY);
+
+/* Convenience macro that takes an array: */
+#define PNG_FORMAT_NUMBER(buffer,format,number) \
+   png_format_number(buffer, buffer + (sizeof buffer), format, number)
+
+/* Suggested size for a number buffer (enough for 64 bits and a sign!) */
+#define PNG_NUMBER_BUFFER_SIZE 24
+
+/* These are the integer formats currently supported, the name is formed from
+ * the standard printf(3) format string.
+ */
+#define PNG_NUMBER_FORMAT_u     1 /* chose unsigned API! */
+#define PNG_NUMBER_FORMAT_02u   2
+#define PNG_NUMBER_FORMAT_d     1 /* chose signed API! */
+#define PNG_NUMBER_FORMAT_02d   2
+#define PNG_NUMBER_FORMAT_x     3
+#define PNG_NUMBER_FORMAT_02x   4
+#define PNG_NUMBER_FORMAT_fixed 5 /* choose the signed API */
+#endif
+
+#ifdef PNG_WARNINGS_SUPPORTED
+/* New defines and members adding in libpng-1.5.4 */
+#  define PNG_WARNING_PARAMETER_SIZE 32
+#  define PNG_WARNING_PARAMETER_COUNT 8 /* Maximum 9; see pngerror.c */
+
+/* An l-value of this type has to be passed to the APIs below to cache the
+ * values of the parameters to a formatted warning message.
+ */
+typedef char png_warning_parameters[PNG_WARNING_PARAMETER_COUNT][
+   PNG_WARNING_PARAMETER_SIZE];
+
+PNG_INTERNAL_FUNCTION(void,png_warning_parameter,(png_warning_parameters p,
+   int number, png_const_charp string),PNG_EMPTY);
+   /* Parameters are limited in size to PNG_WARNING_PARAMETER_SIZE characters,
+    * including the trailing '\0'.
+    */
+PNG_INTERNAL_FUNCTION(void,png_warning_parameter_unsigned,
+   (png_warning_parameters p, int number, int format, png_alloc_size_t value),
+   PNG_EMPTY);
+   /* Use png_alloc_size_t because it is an unsigned type as big as any we
+    * need to output.  Use the following for a signed value.
+    */
+PNG_INTERNAL_FUNCTION(void,png_warning_parameter_signed,
+   (png_warning_parameters p, int number, int format, png_int_32 value),
+   PNG_EMPTY);
+
+PNG_INTERNAL_FUNCTION(void,png_formatted_warning,(png_const_structrp png_ptr,
+   png_warning_parameters p, png_const_charp message),PNG_EMPTY);
+   /* 'message' follows the X/Open approach of using @1, @2 to insert
+    * parameters previously supplied using the above functions.  Errors in
+    * specifying the parameters will simply result in garbage substitutions.
+    */
+#endif
+
+#ifdef PNG_BENIGN_ERRORS_SUPPORTED
+/* Application errors (new in 1.6); use these functions (declared below) for
+ * errors in the parameters or order of API function calls on read.  The
+ * 'warning' should be used for an error that can be handled completely; the
+ * 'error' for one which can be handled safely but which may lose application
+ * information or settings.
+ *
+ * By default these both result in a png_error call prior to release, while in a
+ * released version the 'warning' is just a warning.  However if the application
+ * explicitly disables benign errors (explicitly permitting the code to lose
+ * information) they both turn into warnings.
+ *
+ * If benign errors aren't supported they end up as the corresponding base call
+ * (png_warning or png_error.)
+ */
+PNG_INTERNAL_FUNCTION(void,png_app_warning,(png_const_structrp png_ptr,
+   png_const_charp message),PNG_EMPTY);
+   /* The application provided invalid parameters to an API function or called
+    * an API function at the wrong time, libpng can completely recover.
+    */
+
+PNG_INTERNAL_FUNCTION(void,png_app_error,(png_const_structrp png_ptr,
+   png_const_charp message),PNG_EMPTY);
+   /* As above but libpng will ignore the call, or attempt some other partial
+    * recovery from the error.
+    */
+#else
+#  define png_app_warning(pp,s) png_warning(pp,s)
+#  define png_app_error(pp,s) png_error(pp,s)
+#endif
+
+PNG_INTERNAL_FUNCTION(void,png_chunk_report,(png_const_structrp png_ptr,
+   png_const_charp message, int error),PNG_EMPTY);
+   /* Report a recoverable issue in chunk data.  On read this is used to report
+    * a problem found while reading a particular chunk and the
+    * png_chunk_benign_error or png_chunk_warning function is used as
+    * appropriate.  On write this is used to report an error that comes from
+    * data set via an application call to a png_set_ API and png_app_error or
+    * png_app_warning is used as appropriate.
+    *
+    * The 'error' parameter must have one of the following values:
+    */
+#define PNG_CHUNK_WARNING     0 /* never an error */
+#define PNG_CHUNK_WRITE_ERROR 1 /* an error only on write */
+#define PNG_CHUNK_ERROR       2 /* always an error */
+
+/* ASCII to FP interfaces, currently only implemented if sCAL
+ * support is required.
+ */
+#if defined(PNG_sCAL_SUPPORTED)
+/* MAX_DIGITS is actually the maximum number of characters in an sCAL
+ * width or height, derived from the precision (number of significant
+ * digits - a build time settable option) and assumptions about the
+ * maximum ridiculous exponent.
+ */
+#define PNG_sCAL_MAX_DIGITS (PNG_sCAL_PRECISION+1/*.*/+1/*E*/+10/*exponent*/)
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_ascii_from_fp,(png_const_structrp png_ptr,
+   png_charp ascii, png_size_t size, double fp, unsigned int precision),
+   PNG_EMPTY);
+#endif /* FLOATING_POINT */
+
+#ifdef PNG_FIXED_POINT_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_ascii_from_fixed,(png_const_structrp png_ptr,
+   png_charp ascii, png_size_t size, png_fixed_point fp),PNG_EMPTY);
+#endif /* FIXED_POINT */
+#endif /* sCAL */
+
+#if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED)
+/* An internal API to validate the format of a floating point number.
+ * The result is the index of the next character.  If the number is
+ * not valid it will be the index of a character in the supposed number.
+ *
+ * The format of a number is defined in the PNG extensions specification
+ * and this API is strictly conformant to that spec, not anyone elses!
+ *
+ * The format as a regular expression is:
+ *
+ * [+-]?[0-9]+.?([Ee][+-]?[0-9]+)?
+ *
+ * or:
+ *
+ * [+-]?.[0-9]+(.[0-9]+)?([Ee][+-]?[0-9]+)?
+ *
+ * The complexity is that either integer or fraction must be present and the
+ * fraction is permitted to have no digits only if the integer is present.
+ *
+ * NOTE: The dangling E problem.
+ *   There is a PNG valid floating point number in the following:
+ *
+ *       PNG floating point numbers are not greedy.
+ *
+ *   Working this out requires *TWO* character lookahead (because of the
+ *   sign), the parser does not do this - it will fail at the 'r' - this
+ *   doesn't matter for PNG sCAL chunk values, but it requires more care
+ *   if the value were ever to be embedded in something more complex.  Use
+ *   ANSI-C strtod if you need the lookahead.
+ */
+/* State table for the parser. */
+#define PNG_FP_INTEGER    0  /* before or in integer */
+#define PNG_FP_FRACTION   1  /* before or in fraction */
+#define PNG_FP_EXPONENT   2  /* before or in exponent */
+#define PNG_FP_STATE      3  /* mask for the above */
+#define PNG_FP_SAW_SIGN   4  /* Saw +/- in current state */
+#define PNG_FP_SAW_DIGIT  8  /* Saw a digit in current state */
+#define PNG_FP_SAW_DOT   16  /* Saw a dot in current state */
+#define PNG_FP_SAW_E     32  /* Saw an E (or e) in current state */
+#define PNG_FP_SAW_ANY   60  /* Saw any of the above 4 */
+
+/* These three values don't affect the parser.  They are set but not used.
+ */
+#define PNG_FP_WAS_VALID 64  /* Preceding substring is a valid fp number */
+#define PNG_FP_NEGATIVE 128  /* A negative number, including "-0" */
+#define PNG_FP_NONZERO  256  /* A non-zero value */
+#define PNG_FP_STICKY   448  /* The above three flags */
+
+/* This is available for the caller to store in 'state' if required.  Do not
+ * call the parser after setting it (the parser sometimes clears it.)
+ */
+#define PNG_FP_INVALID  512  /* Available for callers as a distinct value */
+
+/* Result codes for the parser (boolean - true meants ok, false means
+ * not ok yet.)
+ */
+#define PNG_FP_MAYBE      0  /* The number may be valid in the future */
+#define PNG_FP_OK         1  /* The number is valid */
+
+/* Tests on the sticky non-zero and negative flags.  To pass these checks
+ * the state must also indicate that the whole number is valid - this is
+ * achieved by testing PNG_FP_SAW_DIGIT (see the implementation for why this
+ * is equivalent to PNG_FP_OK above.)
+ */
+#define PNG_FP_NZ_MASK (PNG_FP_SAW_DIGIT | PNG_FP_NEGATIVE | PNG_FP_NONZERO)
+   /* NZ_MASK: the string is valid and a non-zero negative value */
+#define PNG_FP_Z_MASK (PNG_FP_SAW_DIGIT | PNG_FP_NONZERO)
+   /* Z MASK: the string is valid and a non-zero value. */
+   /* PNG_FP_SAW_DIGIT: the string is valid. */
+#define PNG_FP_IS_ZERO(state) (((state) & PNG_FP_Z_MASK) == PNG_FP_SAW_DIGIT)
+#define PNG_FP_IS_POSITIVE(state) (((state) & PNG_FP_NZ_MASK) == PNG_FP_Z_MASK)
+#define PNG_FP_IS_NEGATIVE(state) (((state) & PNG_FP_NZ_MASK) == PNG_FP_NZ_MASK)
+
+/* The actual parser.  This can be called repeatedly. It updates
+ * the index into the string and the state variable (which must
+ * be initialized to 0).  It returns a result code, as above.  There
+ * is no point calling the parser any more if it fails to advance to
+ * the end of the string - it is stuck on an invalid character (or
+ * terminated by '\0').
+ *
+ * Note that the pointer will consume an E or even an E+ and then leave
+ * a 'maybe' state even though a preceding integer.fraction is valid.
+ * The PNG_FP_WAS_VALID flag indicates that a preceding substring was
+ * a valid number.  It's possible to recover from this by calling
+ * the parser again (from the start, with state 0) but with a string
+ * that omits the last character (i.e. set the size to the index of
+ * the problem character.)  This has not been tested within libpng.
+ */
+PNG_INTERNAL_FUNCTION(int,png_check_fp_number,(png_const_charp string,
+   png_size_t size, int *statep, png_size_tp whereami),PNG_EMPTY);
+
+/* This is the same but it checks a complete string and returns true
+ * only if it just contains a floating point number.  As of 1.5.4 this
+ * function also returns the state at the end of parsing the number if
+ * it was valid (otherwise it returns 0.)  This can be used for testing
+ * for negative or zero values using the sticky flag.
+ */
+PNG_INTERNAL_FUNCTION(int,png_check_fp_string,(png_const_charp string,
+   png_size_t size),PNG_EMPTY);
+#endif /* pCAL || sCAL */
+
+#if defined(PNG_GAMMA_SUPPORTED) ||\
+    defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG_READ_pHYs_SUPPORTED)
+/* Added at libpng version 1.5.0 */
+/* This is a utility to provide a*times/div (rounded) and indicate
+ * if there is an overflow.  The result is a boolean - false (0)
+ * for overflow, true (1) if no overflow, in which case *res
+ * holds the result.
+ */
+PNG_INTERNAL_FUNCTION(int,png_muldiv,(png_fixed_point_p res, png_fixed_point a,
+   png_int_32 multiplied_by, png_int_32 divided_by),PNG_EMPTY);
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED)
+/* Same deal, but issue a warning on overflow and return 0. */
+PNG_INTERNAL_FUNCTION(png_fixed_point,png_muldiv_warn,
+   (png_const_structrp png_ptr, png_fixed_point a, png_int_32 multiplied_by,
+   png_int_32 divided_by),PNG_EMPTY);
+#endif
+
+#ifdef PNG_GAMMA_SUPPORTED
+/* Calculate a reciprocal - used for gamma values.  This returns
+ * 0 if the argument is 0 in order to maintain an undefined value;
+ * there are no warnings.
+ */
+PNG_INTERNAL_FUNCTION(png_fixed_point,png_reciprocal,(png_fixed_point a),
+   PNG_EMPTY);
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+/* The same but gives a reciprocal of the product of two fixed point
+ * values.  Accuracy is suitable for gamma calculations but this is
+ * not exact - use png_muldiv for that.  Only required at present on read.
+ */
+PNG_INTERNAL_FUNCTION(png_fixed_point,png_reciprocal2,(png_fixed_point a,
+   png_fixed_point b),PNG_EMPTY);
+#endif
+
+/* Return true if the gamma value is significantly different from 1.0 */
+PNG_INTERNAL_FUNCTION(int,png_gamma_significant,(png_fixed_point gamma_value),
+   PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+/* Internal fixed point gamma correction.  These APIs are called as
+ * required to convert single values - they don't need to be fast,
+ * they are not used when processing image pixel values.
+ *
+ * While the input is an 'unsigned' value it must actually be the
+ * correct bit value - 0..255 or 0..65535 as required.
+ */
+PNG_INTERNAL_FUNCTION(png_uint_16,png_gamma_correct,(png_structrp png_ptr,
+   unsigned int value, png_fixed_point gamma_value),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(png_uint_16,png_gamma_16bit_correct,(unsigned int value,
+   png_fixed_point gamma_value),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(png_byte,png_gamma_8bit_correct,(unsigned int value,
+   png_fixed_point gamma_value),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_destroy_gamma_table,(png_structrp png_ptr),
+   PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_build_gamma_table,(png_structrp png_ptr,
+   int bit_depth),PNG_EMPTY);
+#endif
+
+/* SIMPLIFIED READ/WRITE SUPPORT */
+#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\
+   defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
+/* The internal structure that png_image::opaque points to. */
+typedef struct png_control
+{
+   png_structp png_ptr;
+   png_infop   info_ptr;
+   png_voidp   error_buf;           /* Always a jmp_buf at present. */
+
+   png_const_bytep memory;          /* Memory buffer. */
+   png_size_t      size;            /* Size of the memory buffer. */
+
+   unsigned int for_write       :1; /* Otherwise it is a read structure */
+   unsigned int owned_file      :1; /* We own the file in io_ptr */
+} png_control;
+
+/* Return the pointer to the jmp_buf from a png_control: necessary because C
+ * does not reveal the type of the elements of jmp_buf.
+ */
+#ifdef __cplusplus
+#  define png_control_jmp_buf(pc) (((jmp_buf*)((pc)->error_buf))[0])
+#else
+#  define png_control_jmp_buf(pc) ((pc)->error_buf)
+#endif
+
+/* Utility to safely execute a piece of libpng code catching and logging any
+ * errors that might occur.  Returns true on success, false on failure (either
+ * of the function or as a result of a png_error.)
+ */
+PNG_INTERNAL_CALLBACK(void,png_safe_error,(png_structp png_ptr,
+   png_const_charp error_message),PNG_NORETURN);
+
+#ifdef PNG_WARNINGS_SUPPORTED
+PNG_INTERNAL_CALLBACK(void,png_safe_warning,(png_structp png_ptr,
+   png_const_charp warning_message),PNG_EMPTY);
+#else
+#  define png_safe_warning 0/*dummy argument*/
+#endif
+
+PNG_INTERNAL_FUNCTION(int,png_safe_execute,(png_imagep image,
+   int (*function)(png_voidp), png_voidp arg),PNG_EMPTY);
+
+/* Utility to log an error; this also cleans up the png_image; the function
+ * always returns 0 (false).
+ */
+PNG_INTERNAL_FUNCTION(int,png_image_error,(png_imagep image,
+   png_const_charp error_message),PNG_EMPTY);
+
+#ifndef PNG_SIMPLIFIED_READ_SUPPORTED
+/* png_image_free is used by the write code but not exported */
+PNG_INTERNAL_FUNCTION(void, png_image_free, (png_imagep image), PNG_EMPTY);
+#endif /* !SIMPLIFIED_READ */
+
+#endif /* SIMPLIFIED READ/WRITE */
+
+/* These are initialization functions for hardware specific PNG filter
+ * optimizations; list these here then select the appropriate one at compile
+ * time using the macro PNG_FILTER_OPTIMIZATIONS.  If the macro is not defined
+ * the generic code is used.
+ */
+#ifdef PNG_FILTER_OPTIMIZATIONS
+PNG_INTERNAL_FUNCTION(void, PNG_FILTER_OPTIMIZATIONS, (png_structp png_ptr,
+   unsigned int bpp), PNG_EMPTY);
+   /* Just declare the optimization that will be used */
+#else
+   /* List *all* the possible optimizations here - this branch is required if
+    * the builder of libpng passes the definition of PNG_FILTER_OPTIMIZATIONS in
+    * CFLAGS in place of CPPFLAGS *and* uses symbol prefixing.
+    */
+PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_neon,
+   (png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
+#endif
+
+/* Maintainer: Put new private prototypes here ^ */
+
+#include "pngdebug.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PNG_VERSION_INFO_ONLY */
+#endif /* PNGPRIV_H */
diff --git a/Source/LibPNG/pngread.c b/Source/LibPNG/pngread.c
index 96a2a56..87a7891 100644
--- a/Source/LibPNG/pngread.c
+++ b/Source/LibPNG/pngread.c
@@ -1,1305 +1,4121 @@
-
-/* pngread.c - read a PNG file
- *
- * Last changed in libpng 1.5.10 [March 8, 2012]
- * Copyright (c) 1998-2012 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- *
- * This file contains routines that an application calls directly to
- * read a PNG file or stream.
- */
-
-#include "pngpriv.h"
-
-#ifdef PNG_READ_SUPPORTED
-
-/* Create a PNG structure for reading, and allocate any memory needed. */
-PNG_FUNCTION(png_structp,PNGAPI
-png_create_read_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
-    png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED)
-{
-
-#ifdef PNG_USER_MEM_SUPPORTED
-   return (png_create_read_struct_2(user_png_ver, error_ptr, error_fn,
-       warn_fn, NULL, NULL, NULL));
-}
-
-/* Alternate create PNG structure for reading, and allocate any memory
- * needed.
- */
-PNG_FUNCTION(png_structp,PNGAPI
-png_create_read_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr,
-    png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
-    png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED)
-{
-#endif /* PNG_USER_MEM_SUPPORTED */
-
-#ifdef PNG_SETJMP_SUPPORTED
-   volatile
-#endif
-   png_structp png_ptr;
-   volatile int png_cleanup_needed = 0;
-
-#ifdef PNG_SETJMP_SUPPORTED
-#ifdef USE_FAR_KEYWORD
-   jmp_buf tmp_jmpbuf;
-#endif
-#endif
-
-   png_debug(1, "in png_create_read_struct");
-
-#ifdef PNG_USER_MEM_SUPPORTED
-   png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG,
-       malloc_fn, mem_ptr);
-#else
-   png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
-#endif
-   if (png_ptr == NULL)
-      return (NULL);
-
-   /* Added at libpng-1.2.6 */
-#ifdef PNG_USER_LIMITS_SUPPORTED
-   png_ptr->user_width_max = PNG_USER_WIDTH_MAX;
-   png_ptr->user_height_max = PNG_USER_HEIGHT_MAX;
-
-   /* Added at libpng-1.2.43 and 1.4.0 */
-   png_ptr->user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX;
-
-   /* Added at libpng-1.2.43 and 1.4.1 */
-   png_ptr->user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX;
-#endif
-
-#ifdef PNG_SETJMP_SUPPORTED
-/* Applications that neglect to set up their own setjmp() and then
- * encounter a png_error() will longjmp here.  Since the jmpbuf is
- * then meaningless we abort instead of returning.
- */
-#ifdef USE_FAR_KEYWORD
-   if (setjmp(tmp_jmpbuf))
-#else
-   if (setjmp(png_jmpbuf(png_ptr))) /* Sets longjmp to match setjmp */
-#endif
-      PNG_ABORT();
-#ifdef USE_FAR_KEYWORD
-   png_memcpy(png_jmpbuf(png_ptr), tmp_jmpbuf, png_sizeof(jmp_buf));
-#endif
-#endif /* PNG_SETJMP_SUPPORTED */
-
-#ifdef PNG_USER_MEM_SUPPORTED
-   png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
-#endif
-
-   png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);
-
-   /* Call the general version checker (shared with read and write code): */
-   if (!png_user_version_check(png_ptr, user_png_ver))
-      png_cleanup_needed = 1;
-
-   if (!png_cleanup_needed)
-   {
-   /* Initialize zbuf - compression buffer */
-   png_ptr->zbuf_size = PNG_ZBUF_SIZE;
-   png_ptr->zbuf = (png_bytep)png_malloc_warn(png_ptr, png_ptr->zbuf_size);
-
-   if (png_ptr->zbuf == NULL)
-      png_cleanup_needed = 1;
-   }
-
-   png_ptr->zstream.zalloc = png_zalloc;
-   png_ptr->zstream.zfree = png_zfree;
-   png_ptr->zstream.opaque = (voidpf)png_ptr;
-
-   if (!png_cleanup_needed)
-   {
-      switch (inflateInit(&png_ptr->zstream))
-      {
-         case Z_OK:
-            break; /* Do nothing */
-
-         case Z_MEM_ERROR:
-            png_warning(png_ptr, "zlib memory error");
-            png_cleanup_needed = 1;
-            break;
-
-         case Z_STREAM_ERROR:
-            png_warning(png_ptr, "zlib stream error");
-            png_cleanup_needed = 1;
-            break;
-
-         case Z_VERSION_ERROR:
-            png_warning(png_ptr, "zlib version error");
-            png_cleanup_needed = 1;
-            break;
-
-         default: png_warning(png_ptr, "Unknown zlib error");
-            png_cleanup_needed = 1;
-      }
-   }
-
-   if (png_cleanup_needed)
-   {
-      /* Clean up PNG structure and deallocate any memory. */
-      png_free(png_ptr, png_ptr->zbuf);
-      png_ptr->zbuf = NULL;
-#ifdef PNG_USER_MEM_SUPPORTED
-      png_destroy_struct_2((png_voidp)png_ptr,
-          (png_free_ptr)free_fn, (png_voidp)mem_ptr);
-#else
-      png_destroy_struct((png_voidp)png_ptr);
-#endif
-      return (NULL);
-   }
-
-   png_ptr->zstream.next_out = png_ptr->zbuf;
-   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
-
-   png_set_read_fn(png_ptr, NULL, NULL);
-
-
-   return (png_ptr);
-}
-
-
-#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
-/* Read the information before the actual image data.  This has been
- * changed in v0.90 to allow reading a file that already has the magic
- * bytes read from the stream.  You can tell libpng how many bytes have
- * been read from the beginning of the stream (up to the maximum of 8)
- * via png_set_sig_bytes(), and we will only check the remaining bytes
- * here.  The application can then have access to the signature bytes we
- * read if it is determined that this isn't a valid PNG file.
- */
-void PNGAPI
-png_read_info(png_structp png_ptr, png_infop info_ptr)
-{
-   png_debug(1, "in png_read_info");
-
-   if (png_ptr == NULL || info_ptr == NULL)
-      return;
-
-   /* Read and check the PNG file signature. */
-   png_read_sig(png_ptr, info_ptr);
-
-   for (;;)
-   {
-      png_uint_32 length = png_read_chunk_header(png_ptr);
-      png_uint_32 chunk_name = png_ptr->chunk_name;
-
-      /* This should be a binary subdivision search or a hash for
-       * matching the chunk name rather than a linear search.
-       */
-      if (chunk_name == png_IDAT)
-         if (png_ptr->mode & PNG_AFTER_IDAT)
-            png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
-
-      if (chunk_name == png_IHDR)
-         png_handle_IHDR(png_ptr, info_ptr, length);
-
-      else if (chunk_name == png_IEND)
-         png_handle_IEND(png_ptr, info_ptr, length);
-
-#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
-      else if (png_chunk_unknown_handling(png_ptr, chunk_name) !=
-         PNG_HANDLE_CHUNK_AS_DEFAULT)
-      {
-         if (chunk_name == png_IDAT)
-            png_ptr->mode |= PNG_HAVE_IDAT;
-
-         png_handle_unknown(png_ptr, info_ptr, length);
-
-         if (chunk_name == png_PLTE)
-            png_ptr->mode |= PNG_HAVE_PLTE;
-
-         else if (chunk_name == png_IDAT)
-         {
-            if (!(png_ptr->mode & PNG_HAVE_IHDR))
-               png_error(png_ptr, "Missing IHDR before IDAT");
-
-            else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
-                !(png_ptr->mode & PNG_HAVE_PLTE))
-               png_error(png_ptr, "Missing PLTE before IDAT");
-
-            break;
-         }
-      }
-#endif
-      else if (chunk_name == png_PLTE)
-         png_handle_PLTE(png_ptr, info_ptr, length);
-
-      else if (chunk_name == png_IDAT)
-      {
-         if (!(png_ptr->mode & PNG_HAVE_IHDR))
-            png_error(png_ptr, "Missing IHDR before IDAT");
-
-         else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
-             !(png_ptr->mode & PNG_HAVE_PLTE))
-            png_error(png_ptr, "Missing PLTE before IDAT");
-
-         png_ptr->idat_size = length;
-         png_ptr->mode |= PNG_HAVE_IDAT;
-         break;
-      }
-
-#ifdef PNG_READ_bKGD_SUPPORTED
-      else if (chunk_name == png_bKGD)
-         png_handle_bKGD(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_cHRM_SUPPORTED
-      else if (chunk_name == png_cHRM)
-         png_handle_cHRM(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_gAMA_SUPPORTED
-      else if (chunk_name == png_gAMA)
-         png_handle_gAMA(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_hIST_SUPPORTED
-      else if (chunk_name == png_hIST)
-         png_handle_hIST(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_oFFs_SUPPORTED
-      else if (chunk_name == png_oFFs)
-         png_handle_oFFs(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_pCAL_SUPPORTED
-      else if (chunk_name == png_pCAL)
-         png_handle_pCAL(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_sCAL_SUPPORTED
-      else if (chunk_name == png_sCAL)
-         png_handle_sCAL(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_pHYs_SUPPORTED
-      else if (chunk_name == png_pHYs)
-         png_handle_pHYs(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_sBIT_SUPPORTED
-      else if (chunk_name == png_sBIT)
-         png_handle_sBIT(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_sRGB_SUPPORTED
-      else if (chunk_name == png_sRGB)
-         png_handle_sRGB(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_iCCP_SUPPORTED
-      else if (chunk_name == png_iCCP)
-         png_handle_iCCP(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_sPLT_SUPPORTED
-      else if (chunk_name == png_sPLT)
-         png_handle_sPLT(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_tEXt_SUPPORTED
-      else if (chunk_name == png_tEXt)
-         png_handle_tEXt(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_tIME_SUPPORTED
-      else if (chunk_name == png_tIME)
-         png_handle_tIME(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_tRNS_SUPPORTED
-      else if (chunk_name == png_tRNS)
-         png_handle_tRNS(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_zTXt_SUPPORTED
-      else if (chunk_name == png_zTXt)
-         png_handle_zTXt(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_iTXt_SUPPORTED
-      else if (chunk_name == png_iTXt)
-         png_handle_iTXt(png_ptr, info_ptr, length);
-#endif
-
-      else
-         png_handle_unknown(png_ptr, info_ptr, length);
-   }
-}
-#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
-
-/* Optional call to update the users info_ptr structure */
-void PNGAPI
-png_read_update_info(png_structp png_ptr, png_infop info_ptr)
-{
-   png_debug(1, "in png_read_update_info");
-
-   if (png_ptr == NULL)
-      return;
-
-   png_read_start_row(png_ptr);
-
-#ifdef PNG_READ_TRANSFORMS_SUPPORTED
-   png_read_transform_info(png_ptr, info_ptr);
-#else
-   PNG_UNUSED(info_ptr)
-#endif
-}
-
-#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
-/* Initialize palette, background, etc, after transformations
- * are set, but before any reading takes place.  This allows
- * the user to obtain a gamma-corrected palette, for example.
- * If the user doesn't call this, we will do it ourselves.
- */
-void PNGAPI
-png_start_read_image(png_structp png_ptr)
-{
-   png_debug(1, "in png_start_read_image");
-
-   if (png_ptr != NULL)
-     png_read_start_row(png_ptr);
-}
-#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
-
-#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
-void PNGAPI
-png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
-{
-   int ret;
-
-   png_row_info row_info;
-
-   if (png_ptr == NULL)
-      return;
-
-   png_debug2(1, "in png_read_row (row %lu, pass %d)",
-       (unsigned long)png_ptr->row_number, png_ptr->pass);
-
-   /* png_read_start_row sets the information (in particular iwidth) for this
-    * interlace pass.
-    */
-   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
-      png_read_start_row(png_ptr);
-
-   /* 1.5.6: row_info moved out of png_struct to a local here. */
-   row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */
-   row_info.color_type = png_ptr->color_type;
-   row_info.bit_depth = png_ptr->bit_depth;
-   row_info.channels = png_ptr->channels;
-   row_info.pixel_depth = png_ptr->pixel_depth;
-   row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width);
-
-   if (png_ptr->row_number == 0 && png_ptr->pass == 0)
-   {
-   /* Check for transforms that have been set but were defined out */
-#if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED)
-   if (png_ptr->transformations & PNG_INVERT_MONO)
-      png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined");
-#endif
-
-#if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED)
-   if (png_ptr->transformations & PNG_FILLER)
-      png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined");
-#endif
-
-#if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \
-    !defined(PNG_READ_PACKSWAP_SUPPORTED)
-   if (png_ptr->transformations & PNG_PACKSWAP)
-      png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined");
-#endif
-
-#if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED)
-   if (png_ptr->transformations & PNG_PACK)
-      png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined");
-#endif
-
-#if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED)
-   if (png_ptr->transformations & PNG_SHIFT)
-      png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined");
-#endif
-
-#if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED)
-   if (png_ptr->transformations & PNG_BGR)
-      png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined");
-#endif
-
-#if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED)
-   if (png_ptr->transformations & PNG_SWAP_BYTES)
-      png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined");
-#endif
-   }
-
-#ifdef PNG_READ_INTERLACING_SUPPORTED
-   /* If interlaced and we do not need a new row, combine row and return.
-    * Notice that the pixels we have from previous rows have been transformed
-    * already; we can only combine like with like (transformed or
-    * untransformed) and, because of the libpng API for interlaced images, this
-    * means we must transform before de-interlacing.
-    */
-   if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
-   {
-      switch (png_ptr->pass)
-      {
-         case 0:
-            if (png_ptr->row_number & 0x07)
-            {
-               if (dsp_row != NULL)
-                  png_combine_row(png_ptr, dsp_row, 1/*display*/);
-               png_read_finish_row(png_ptr);
-               return;
-            }
-            break;
-
-         case 1:
-            if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
-            {
-               if (dsp_row != NULL)
-                  png_combine_row(png_ptr, dsp_row, 1/*display*/);
-
-               png_read_finish_row(png_ptr);
-               return;
-            }
-            break;
-
-         case 2:
-            if ((png_ptr->row_number & 0x07) != 4)
-            {
-               if (dsp_row != NULL && (png_ptr->row_number & 4))
-                  png_combine_row(png_ptr, dsp_row, 1/*display*/);
-
-               png_read_finish_row(png_ptr);
-               return;
-            }
-            break;
-
-         case 3:
-            if ((png_ptr->row_number & 3) || png_ptr->width < 3)
-            {
-               if (dsp_row != NULL)
-                  png_combine_row(png_ptr, dsp_row, 1/*display*/);
-
-               png_read_finish_row(png_ptr);
-               return;
-            }
-            break;
-
-         case 4:
-            if ((png_ptr->row_number & 3) != 2)
-            {
-               if (dsp_row != NULL && (png_ptr->row_number & 2))
-                  png_combine_row(png_ptr, dsp_row, 1/*display*/);
-
-               png_read_finish_row(png_ptr);
-               return;
-            }
-            break;
-         case 5:
-            if ((png_ptr->row_number & 1) || png_ptr->width < 2)
-            {
-               if (dsp_row != NULL)
-                  png_combine_row(png_ptr, dsp_row, 1/*display*/);
-
-               png_read_finish_row(png_ptr);
-               return;
-            }
-            break;
-
-         default:
-         case 6:
-            if (!(png_ptr->row_number & 1))
-            {
-               png_read_finish_row(png_ptr);
-               return;
-            }
-            break;
-      }
-   }
-#endif
-
-   if (!(png_ptr->mode & PNG_HAVE_IDAT))
-      png_error(png_ptr, "Invalid attempt to read row data");
-
-   png_ptr->zstream.next_out = png_ptr->row_buf;
-   png_ptr->zstream.avail_out =
-       (uInt)(PNG_ROWBYTES(png_ptr->pixel_depth,
-       png_ptr->iwidth) + 1);
-
-   do
-   {
-      if (!(png_ptr->zstream.avail_in))
-      {
-         while (!png_ptr->idat_size)
-         {
-            png_crc_finish(png_ptr, 0);
-
-            png_ptr->idat_size = png_read_chunk_header(png_ptr);
-            if (png_ptr->chunk_name != png_IDAT)
-               png_error(png_ptr, "Not enough image data");
-         }
-         png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
-         png_ptr->zstream.next_in = png_ptr->zbuf;
-         if (png_ptr->zbuf_size > png_ptr->idat_size)
-            png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
-         png_crc_read(png_ptr, png_ptr->zbuf,
-             (png_size_t)png_ptr->zstream.avail_in);
-         png_ptr->idat_size -= png_ptr->zstream.avail_in;
-      }
-
-      ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
-
-      if (ret == Z_STREAM_END)
-      {
-         if (png_ptr->zstream.avail_out || png_ptr->zstream.avail_in ||
-            png_ptr->idat_size)
-            png_benign_error(png_ptr, "Extra compressed data");
-         png_ptr->mode |= PNG_AFTER_IDAT;
-         png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
-         break;
-      }
-
-      if (ret != Z_OK)
-         png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
-             "Decompression error");
-
-   } while (png_ptr->zstream.avail_out);
-
-   if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE)
-   {
-      if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST)
-         png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1,
-            png_ptr->prev_row + 1, png_ptr->row_buf[0]);
-      else
-         png_error(png_ptr, "bad adaptive filter value");
-   }
-
-   /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before
-    * 1.5.6, while the buffer really is this big in current versions of libpng
-    * it may not be in the future, so this was changed just to copy the
-    * interlaced count:
-    */
-   png_memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1);
-
-#ifdef PNG_MNG_FEATURES_SUPPORTED
-   if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
-       (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
-   {
-      /* Intrapixel differencing */
-      png_do_read_intrapixel(&row_info, png_ptr->row_buf + 1);
-   }
-#endif
-
-
-#ifdef PNG_READ_TRANSFORMS_SUPPORTED
-   if (png_ptr->transformations)
-      png_do_read_transformations(png_ptr, &row_info);
-#endif
-
-   /* The transformed pixel depth should match the depth now in row_info. */
-   if (png_ptr->transformed_pixel_depth == 0)
-   {
-      png_ptr->transformed_pixel_depth = row_info.pixel_depth;
-      if (row_info.pixel_depth > png_ptr->maximum_pixel_depth)
-         png_error(png_ptr, "sequential row overflow");
-   }
-
-   else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth)
-      png_error(png_ptr, "internal sequential row size calculation error");
-
-#ifdef PNG_READ_INTERLACING_SUPPORTED
-   /* Blow up interlaced rows to full size */
-   if (png_ptr->interlaced &&
-      (png_ptr->transformations & PNG_INTERLACE))
-   {
-      if (png_ptr->pass < 6)
-         png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,
-            png_ptr->transformations);
-
-      if (dsp_row != NULL)
-         png_combine_row(png_ptr, dsp_row, 1/*display*/);
-
-      if (row != NULL)
-         png_combine_row(png_ptr, row, 0/*row*/);
-   }
-
-   else
-#endif
-   {
-      if (row != NULL)
-         png_combine_row(png_ptr, row, -1/*ignored*/);
-
-      if (dsp_row != NULL)
-         png_combine_row(png_ptr, dsp_row, -1/*ignored*/);
-   }
-   png_read_finish_row(png_ptr);
-
-   if (png_ptr->read_row_fn != NULL)
-      (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
-}
-#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
-
-#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
-/* Read one or more rows of image data.  If the image is interlaced,
- * and png_set_interlace_handling() has been called, the rows need to
- * contain the contents of the rows from the previous pass.  If the
- * image has alpha or transparency, and png_handle_alpha()[*] has been
- * called, the rows contents must be initialized to the contents of the
- * screen.
- *
- * "row" holds the actual image, and pixels are placed in it
- * as they arrive.  If the image is displayed after each pass, it will
- * appear to "sparkle" in.  "display_row" can be used to display a
- * "chunky" progressive image, with finer detail added as it becomes
- * available.  If you do not want this "chunky" display, you may pass
- * NULL for display_row.  If you do not want the sparkle display, and
- * you have not called png_handle_alpha(), you may pass NULL for rows.
- * If you have called png_handle_alpha(), and the image has either an
- * alpha channel or a transparency chunk, you must provide a buffer for
- * rows.  In this case, you do not have to provide a display_row buffer
- * also, but you may.  If the image is not interlaced, or if you have
- * not called png_set_interlace_handling(), the display_row buffer will
- * be ignored, so pass NULL to it.
- *
- * [*] png_handle_alpha() does not exist yet, as of this version of libpng
- */
-
-void PNGAPI
-png_read_rows(png_structp png_ptr, png_bytepp row,
-    png_bytepp display_row, png_uint_32 num_rows)
-{
-   png_uint_32 i;
-   png_bytepp rp;
-   png_bytepp dp;
-
-   png_debug(1, "in png_read_rows");
-
-   if (png_ptr == NULL)
-      return;
-
-   rp = row;
-   dp = display_row;
-   if (rp != NULL && dp != NULL)
-      for (i = 0; i < num_rows; i++)
-      {
-         png_bytep rptr = *rp++;
-         png_bytep dptr = *dp++;
-
-         png_read_row(png_ptr, rptr, dptr);
-      }
-
-   else if (rp != NULL)
-      for (i = 0; i < num_rows; i++)
-      {
-         png_bytep rptr = *rp;
-         png_read_row(png_ptr, rptr, NULL);
-         rp++;
-      }
-
-   else if (dp != NULL)
-      for (i = 0; i < num_rows; i++)
-      {
-         png_bytep dptr = *dp;
-         png_read_row(png_ptr, NULL, dptr);
-         dp++;
-      }
-}
-#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
-
-#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
-/* Read the entire image.  If the image has an alpha channel or a tRNS
- * chunk, and you have called png_handle_alpha()[*], you will need to
- * initialize the image to the current image that PNG will be overlaying.
- * We set the num_rows again here, in case it was incorrectly set in
- * png_read_start_row() by a call to png_read_update_info() or
- * png_start_read_image() if png_set_interlace_handling() wasn't called
- * prior to either of these functions like it should have been.  You can
- * only call this function once.  If you desire to have an image for
- * each pass of a interlaced image, use png_read_rows() instead.
- *
- * [*] png_handle_alpha() does not exist yet, as of this version of libpng
- */
-void PNGAPI
-png_read_image(png_structp png_ptr, png_bytepp image)
-{
-   png_uint_32 i, image_height;
-   int pass, j;
-   png_bytepp rp;
-
-   png_debug(1, "in png_read_image");
-
-   if (png_ptr == NULL)
-      return;
-
-#ifdef PNG_READ_INTERLACING_SUPPORTED
-   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
-   {
-      pass = png_set_interlace_handling(png_ptr);
-      /* And make sure transforms are initialized. */
-      png_start_read_image(png_ptr);
-   }
-   else
-   {
-      if (png_ptr->interlaced && !(png_ptr->transformations & PNG_INTERLACE))
-      {
-         /* Caller called png_start_read_image or png_read_update_info without
-          * first turning on the PNG_INTERLACE transform.  We can fix this here,
-          * but the caller should do it!
-          */
-         png_warning(png_ptr, "Interlace handling should be turned on when "
-            "using png_read_image");
-         /* Make sure this is set correctly */
-         png_ptr->num_rows = png_ptr->height;
-      }
-
-      /* Obtain the pass number, which also turns on the PNG_INTERLACE flag in
-       * the above error case.
-       */
-      pass = png_set_interlace_handling(png_ptr);
-   }
-#else
-   if (png_ptr->interlaced)
-      png_error(png_ptr,
-          "Cannot read interlaced image -- interlace handler disabled");
-
-   pass = 1;
-#endif
-
-   image_height=png_ptr->height;
-
-   for (j = 0; j < pass; j++)
-   {
-      rp = image;
-      for (i = 0; i < image_height; i++)
-      {
-         png_read_row(png_ptr, *rp, NULL);
-         rp++;
-      }
-   }
-}
-#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
-
-#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
-/* Read the end of the PNG file.  Will not read past the end of the
- * file, will verify the end is accurate, and will read any comments
- * or time information at the end of the file, if info is not NULL.
- */
-void PNGAPI
-png_read_end(png_structp png_ptr, png_infop info_ptr)
-{
-   png_debug(1, "in png_read_end");
-
-   if (png_ptr == NULL)
-      return;
-
-   png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */
-
-#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
-   /* Report invalid palette index; added at libng-1.5.10 */
-   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
-      png_ptr->num_palette_max > png_ptr->num_palette)
-     png_benign_error(png_ptr, "Read palette index exceeding num_palette");
-#endif
-
-   do
-   {
-      png_uint_32 length = png_read_chunk_header(png_ptr);
-      png_uint_32 chunk_name = png_ptr->chunk_name;
-
-      if (chunk_name == png_IHDR)
-         png_handle_IHDR(png_ptr, info_ptr, length);
-
-      else if (chunk_name == png_IEND)
-         png_handle_IEND(png_ptr, info_ptr, length);
-
-#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
-      else if (png_chunk_unknown_handling(png_ptr, chunk_name) !=
-         PNG_HANDLE_CHUNK_AS_DEFAULT)
-      {
-         if (chunk_name == png_IDAT)
-         {
-            if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
-               png_benign_error(png_ptr, "Too many IDATs found");
-         }
-         png_handle_unknown(png_ptr, info_ptr, length);
-         if (chunk_name == png_PLTE)
-            png_ptr->mode |= PNG_HAVE_PLTE;
-      }
-#endif
-
-      else if (chunk_name == png_IDAT)
-      {
-         /* Zero length IDATs are legal after the last IDAT has been
-          * read, but not after other chunks have been read.
-          */
-         if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
-            png_benign_error(png_ptr, "Too many IDATs found");
-
-         png_crc_finish(png_ptr, length);
-      }
-      else if (chunk_name == png_PLTE)
-         png_handle_PLTE(png_ptr, info_ptr, length);
-
-#ifdef PNG_READ_bKGD_SUPPORTED
-      else if (chunk_name == png_bKGD)
-         png_handle_bKGD(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_cHRM_SUPPORTED
-      else if (chunk_name == png_cHRM)
-         png_handle_cHRM(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_gAMA_SUPPORTED
-      else if (chunk_name == png_gAMA)
-         png_handle_gAMA(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_hIST_SUPPORTED
-      else if (chunk_name == png_hIST)
-         png_handle_hIST(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_oFFs_SUPPORTED
-      else if (chunk_name == png_oFFs)
-         png_handle_oFFs(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_pCAL_SUPPORTED
-      else if (chunk_name == png_pCAL)
-         png_handle_pCAL(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_sCAL_SUPPORTED
-      else if (chunk_name == png_sCAL)
-         png_handle_sCAL(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_pHYs_SUPPORTED
-      else if (chunk_name == png_pHYs)
-         png_handle_pHYs(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_sBIT_SUPPORTED
-      else if (chunk_name == png_sBIT)
-         png_handle_sBIT(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_sRGB_SUPPORTED
-      else if (chunk_name == png_sRGB)
-         png_handle_sRGB(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_iCCP_SUPPORTED
-      else if (chunk_name == png_iCCP)
-         png_handle_iCCP(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_sPLT_SUPPORTED
-      else if (chunk_name == png_sPLT)
-         png_handle_sPLT(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_tEXt_SUPPORTED
-      else if (chunk_name == png_tEXt)
-         png_handle_tEXt(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_tIME_SUPPORTED
-      else if (chunk_name == png_tIME)
-         png_handle_tIME(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_tRNS_SUPPORTED
-      else if (chunk_name == png_tRNS)
-         png_handle_tRNS(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_zTXt_SUPPORTED
-      else if (chunk_name == png_zTXt)
-         png_handle_zTXt(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_iTXt_SUPPORTED
-      else if (chunk_name == png_iTXt)
-         png_handle_iTXt(png_ptr, info_ptr, length);
-#endif
-
-      else
-         png_handle_unknown(png_ptr, info_ptr, length);
-   } while (!(png_ptr->mode & PNG_HAVE_IEND));
-}
-#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
-
-/* Free all memory used by the read */
-void PNGAPI
-png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
-    png_infopp end_info_ptr_ptr)
-{
-   png_structp png_ptr = NULL;
-   png_infop info_ptr = NULL, end_info_ptr = NULL;
-#ifdef PNG_USER_MEM_SUPPORTED
-   png_free_ptr free_fn = NULL;
-   png_voidp mem_ptr = NULL;
-#endif
-
-   png_debug(1, "in png_destroy_read_struct");
-
-   if (png_ptr_ptr != NULL)
-      png_ptr = *png_ptr_ptr;
-   if (png_ptr == NULL)
-      return;
-
-#ifdef PNG_USER_MEM_SUPPORTED
-   free_fn = png_ptr->free_fn;
-   mem_ptr = png_ptr->mem_ptr;
-#endif
-
-   if (info_ptr_ptr != NULL)
-      info_ptr = *info_ptr_ptr;
-
-   if (end_info_ptr_ptr != NULL)
-      end_info_ptr = *end_info_ptr_ptr;
-
-   png_read_destroy(png_ptr, info_ptr, end_info_ptr);
-
-   if (info_ptr != NULL)
-   {
-#ifdef PNG_TEXT_SUPPORTED
-      png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, -1);
-#endif
-
-#ifdef PNG_USER_MEM_SUPPORTED
-      png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn,
-          (png_voidp)mem_ptr);
-#else
-      png_destroy_struct((png_voidp)info_ptr);
-#endif
-      *info_ptr_ptr = NULL;
-   }
-
-   if (end_info_ptr != NULL)
-   {
-#ifdef PNG_READ_TEXT_SUPPORTED
-      png_free_data(png_ptr, end_info_ptr, PNG_FREE_TEXT, -1);
-#endif
-#ifdef PNG_USER_MEM_SUPPORTED
-      png_destroy_struct_2((png_voidp)end_info_ptr, (png_free_ptr)free_fn,
-          (png_voidp)mem_ptr);
-#else
-      png_destroy_struct((png_voidp)end_info_ptr);
-#endif
-      *end_info_ptr_ptr = NULL;
-   }
-
-   if (png_ptr != NULL)
-   {
-#ifdef PNG_USER_MEM_SUPPORTED
-      png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn,
-          (png_voidp)mem_ptr);
-#else
-      png_destroy_struct((png_voidp)png_ptr);
-#endif
-      *png_ptr_ptr = NULL;
-   }
-}
-
-/* Free all memory used by the read (old method) */
-void /* PRIVATE */
-png_read_destroy(png_structp png_ptr, png_infop info_ptr,
-    png_infop end_info_ptr)
-{
-#ifdef PNG_SETJMP_SUPPORTED
-   jmp_buf tmp_jmp;
-#endif
-   png_error_ptr error_fn;
-#ifdef PNG_WARNINGS_SUPPORTED
-   png_error_ptr warning_fn;
-#endif
-   png_voidp error_ptr;
-#ifdef PNG_USER_MEM_SUPPORTED
-   png_free_ptr free_fn;
-#endif
-
-   png_debug(1, "in png_read_destroy");
-
-   if (info_ptr != NULL)
-      png_info_destroy(png_ptr, info_ptr);
-
-   if (end_info_ptr != NULL)
-      png_info_destroy(png_ptr, end_info_ptr);
-
-#ifdef PNG_READ_GAMMA_SUPPORTED
-   png_destroy_gamma_table(png_ptr);
-#endif
-
-   png_free(png_ptr, png_ptr->zbuf);
-   png_free(png_ptr, png_ptr->big_row_buf);
-   png_free(png_ptr, png_ptr->big_prev_row);
-   png_free(png_ptr, png_ptr->chunkdata);
-
-#ifdef PNG_READ_QUANTIZE_SUPPORTED
-   png_free(png_ptr, png_ptr->palette_lookup);
-   png_free(png_ptr, png_ptr->quantize_index);
-#endif
-
-   if (png_ptr->free_me & PNG_FREE_PLTE)
-      png_zfree(png_ptr, png_ptr->palette);
-   png_ptr->free_me &= ~PNG_FREE_PLTE;
-
-#if defined(PNG_tRNS_SUPPORTED) || \
-    defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
-   if (png_ptr->free_me & PNG_FREE_TRNS)
-      png_free(png_ptr, png_ptr->trans_alpha);
-   png_ptr->free_me &= ~PNG_FREE_TRNS;
-#endif
-
-#ifdef PNG_READ_hIST_SUPPORTED
-   if (png_ptr->free_me & PNG_FREE_HIST)
-      png_free(png_ptr, png_ptr->hist);
-   png_ptr->free_me &= ~PNG_FREE_HIST;
-#endif
-
-   inflateEnd(&png_ptr->zstream);
-
-#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
-   png_free(png_ptr, png_ptr->save_buffer);
-#endif
-
-   /* Save the important info out of the png_struct, in case it is
-    * being used again.
-    */
-#ifdef PNG_SETJMP_SUPPORTED
-   png_memcpy(tmp_jmp, png_ptr->longjmp_buffer, png_sizeof(jmp_buf));
-#endif
-
-   error_fn = png_ptr->error_fn;
-#ifdef PNG_WARNINGS_SUPPORTED
-   warning_fn = png_ptr->warning_fn;
-#endif
-   error_ptr = png_ptr->error_ptr;
-#ifdef PNG_USER_MEM_SUPPORTED
-   free_fn = png_ptr->free_fn;
-#endif
-
-   png_memset(png_ptr, 0, png_sizeof(png_struct));
-
-   png_ptr->error_fn = error_fn;
-#ifdef PNG_WARNINGS_SUPPORTED
-   png_ptr->warning_fn = warning_fn;
-#endif
-   png_ptr->error_ptr = error_ptr;
-#ifdef PNG_USER_MEM_SUPPORTED
-   png_ptr->free_fn = free_fn;
-#endif
-
-#ifdef PNG_SETJMP_SUPPORTED
-   png_memcpy(png_ptr->longjmp_buffer, tmp_jmp, png_sizeof(jmp_buf));
-#endif
-
-}
-
-void PNGAPI
-png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn)
-{
-   if (png_ptr == NULL)
-      return;
-
-   png_ptr->read_row_fn = read_row_fn;
-}
-
-
-#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
-#ifdef PNG_INFO_IMAGE_SUPPORTED
-void PNGAPI
-png_read_png(png_structp png_ptr, png_infop info_ptr,
-                           int transforms,
-                           voidp params)
-{
-   int row;
-
-   if (png_ptr == NULL || info_ptr == NULL)
-      return;
-
-   /* png_read_info() gives us all of the information from the
-    * PNG file before the first IDAT (image data chunk).
-    */
-   png_read_info(png_ptr, info_ptr);
-   if (info_ptr->height > PNG_UINT_32_MAX/png_sizeof(png_bytep))
-      png_error(png_ptr, "Image is too high to process with png_read_png()");
-
-   /* -------------- image transformations start here ------------------- */
-
-#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
-   /* Tell libpng to strip 16-bit/color files down to 8 bits per color.
-    */
-   if (transforms & PNG_TRANSFORM_SCALE_16)
-   {
-     /* Added at libpng-1.5.4. "strip_16" produces the same result that it
-      * did in earlier versions, while "scale_16" is now more accurate.
-      */
-      png_set_scale_16(png_ptr);
-   }
-#endif
-
-#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
-   /* If both SCALE and STRIP are required pngrtran will effectively cancel the
-    * latter by doing SCALE first.  This is ok and allows apps not to check for
-    * which is supported to get the right answer.
-    */
-   if (transforms & PNG_TRANSFORM_STRIP_16)
-      png_set_strip_16(png_ptr);
-#endif
-
-#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
-   /* Strip alpha bytes from the input data without combining with
-    * the background (not recommended).
-    */
-   if (transforms & PNG_TRANSFORM_STRIP_ALPHA)
-      png_set_strip_alpha(png_ptr);
-#endif
-
-#if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED)
-   /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single
-    * byte into separate bytes (useful for paletted and grayscale images).
-    */
-   if (transforms & PNG_TRANSFORM_PACKING)
-      png_set_packing(png_ptr);
-#endif
-
-#ifdef PNG_READ_PACKSWAP_SUPPORTED
-   /* Change the order of packed pixels to least significant bit first
-    * (not useful if you are using png_set_packing).
-    */
-   if (transforms & PNG_TRANSFORM_PACKSWAP)
-      png_set_packswap(png_ptr);
-#endif
-
-#ifdef PNG_READ_EXPAND_SUPPORTED
-   /* Expand paletted colors into true RGB triplets
-    * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel
-    * Expand paletted or RGB images with transparency to full alpha
-    * channels so the data will be available as RGBA quartets.
-    */
-   if (transforms & PNG_TRANSFORM_EXPAND)
-      if ((png_ptr->bit_depth < 8) ||
-          (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ||
-          (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)))
-         png_set_expand(png_ptr);
-#endif
-
-   /* We don't handle background color or gamma transformation or quantizing.
-    */
-
-#ifdef PNG_READ_INVERT_SUPPORTED
-   /* Invert monochrome files to have 0 as white and 1 as black
-    */
-   if (transforms & PNG_TRANSFORM_INVERT_MONO)
-      png_set_invert_mono(png_ptr);
-#endif
-
-#ifdef PNG_READ_SHIFT_SUPPORTED
-   /* If you want to shift the pixel values from the range [0,255] or
-    * [0,65535] to the original [0,7] or [0,31], or whatever range the
-    * colors were originally in:
-    */
-   if ((transforms & PNG_TRANSFORM_SHIFT)
-       && png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT))
-   {
-      png_color_8p sig_bit;
-
-      png_get_sBIT(png_ptr, info_ptr, &sig_bit);
-      png_set_shift(png_ptr, sig_bit);
-   }
-#endif
-
-#ifdef PNG_READ_BGR_SUPPORTED
-   /* Flip the RGB pixels to BGR (or RGBA to BGRA) */
-   if (transforms & PNG_TRANSFORM_BGR)
-      png_set_bgr(png_ptr);
-#endif
-
-#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
-   /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */
-   if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
-      png_set_swap_alpha(png_ptr);
-#endif
-
-#ifdef PNG_READ_SWAP_SUPPORTED
-   /* Swap bytes of 16-bit files to least significant byte first */
-   if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
-      png_set_swap(png_ptr);
-#endif
-
-/* Added at libpng-1.2.41 */
-#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
-   /* Invert the alpha channel from opacity to transparency */
-   if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
-      png_set_invert_alpha(png_ptr);
-#endif
-
-/* Added at libpng-1.2.41 */
-#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
-   /* Expand grayscale image to RGB */
-   if (transforms & PNG_TRANSFORM_GRAY_TO_RGB)
-      png_set_gray_to_rgb(png_ptr);
-#endif
-
-/* Added at libpng-1.5.4 */
-#ifdef PNG_READ_EXPAND_16_SUPPORTED
-   if (transforms & PNG_TRANSFORM_EXPAND_16)
-      png_set_expand_16(png_ptr);
-#endif
-
-   /* We don't handle adding filler bytes */
-
-   /* We use png_read_image and rely on that for interlace handling, but we also
-    * call png_read_update_info therefore must turn on interlace handling now:
-    */
-   (void)png_set_interlace_handling(png_ptr);
-
-   /* Optional call to gamma correct and add the background to the palette
-    * and update info structure.  REQUIRED if you are expecting libpng to
-    * update the palette for you (i.e., you selected such a transform above).
-    */
-   png_read_update_info(png_ptr, info_ptr);
-
-   /* -------------- image transformations end here ------------------- */
-
-   png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
-   if (info_ptr->row_pointers == NULL)
-   {
-      png_uint_32 iptr;
-
-      info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr,
-          info_ptr->height * png_sizeof(png_bytep));
-      for (iptr=0; iptr<info_ptr->height; iptr++)
-         info_ptr->row_pointers[iptr] = NULL;
-
-      info_ptr->free_me |= PNG_FREE_ROWS;
-
-      for (row = 0; row < (int)info_ptr->height; row++)
-         info_ptr->row_pointers[row] = (png_bytep)png_malloc(png_ptr,
-            png_get_rowbytes(png_ptr, info_ptr));
-   }
-
-   png_read_image(png_ptr, info_ptr->row_pointers);
-   info_ptr->valid |= PNG_INFO_IDAT;
-
-   /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */
-   png_read_end(png_ptr, info_ptr);
-
-   PNG_UNUSED(transforms)   /* Quiet compiler warnings */
-   PNG_UNUSED(params)
-
-}
-#endif /* PNG_INFO_IMAGE_SUPPORTED */
-#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
-#endif /* PNG_READ_SUPPORTED */
+
+/* pngread.c - read a PNG file
+ *
+ * Last changed in libpng 1.6.15 [November 20, 2014]
+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * This file contains routines that an application calls directly to
+ * read a PNG file or stream.
+ */
+
+#include "pngpriv.h"
+#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) && defined(PNG_STDIO_SUPPORTED)
+#  include <errno.h>
+#endif
+
+#ifdef PNG_READ_SUPPORTED
+
+/* Create a PNG structure for reading, and allocate any memory needed. */
+PNG_FUNCTION(png_structp,PNGAPI
+png_create_read_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
+    png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED)
+{
+#ifndef PNG_USER_MEM_SUPPORTED
+   png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr,
+      error_fn, warn_fn, NULL, NULL, NULL);
+#else
+   return png_create_read_struct_2(user_png_ver, error_ptr, error_fn,
+       warn_fn, NULL, NULL, NULL);
+}
+
+/* Alternate create PNG structure for reading, and allocate any memory
+ * needed.
+ */
+PNG_FUNCTION(png_structp,PNGAPI
+png_create_read_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr,
+    png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
+    png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED)
+{
+   png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr,
+      error_fn, warn_fn, mem_ptr, malloc_fn, free_fn);
+#endif /* USER_MEM */
+
+   if (png_ptr != NULL)
+   {
+      png_ptr->mode = PNG_IS_READ_STRUCT;
+
+      /* Added in libpng-1.6.0; this can be used to detect a read structure if
+       * required (it will be zero in a write structure.)
+       */
+#     ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+         png_ptr->IDAT_read_size = PNG_IDAT_READ_SIZE;
+#     endif
+
+#     ifdef PNG_BENIGN_READ_ERRORS_SUPPORTED
+         png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN;
+
+         /* In stable builds only warn if an application error can be completely
+          * handled.
+          */
+#        if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC
+            png_ptr->flags |= PNG_FLAG_APP_WARNINGS_WARN;
+#        endif
+#     endif
+
+      /* TODO: delay this, it can be done in png_init_io (if the app doesn't
+       * do it itself) avoiding setting the default function if it is not
+       * required.
+       */
+      png_set_read_fn(png_ptr, NULL, NULL);
+   }
+
+   return png_ptr;
+}
+
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Read the information before the actual image data.  This has been
+ * changed in v0.90 to allow reading a file that already has the magic
+ * bytes read from the stream.  You can tell libpng how many bytes have
+ * been read from the beginning of the stream (up to the maximum of 8)
+ * via png_set_sig_bytes(), and we will only check the remaining bytes
+ * here.  The application can then have access to the signature bytes we
+ * read if it is determined that this isn't a valid PNG file.
+ */
+void PNGAPI
+png_read_info(png_structrp png_ptr, png_inforp info_ptr)
+{
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+   int keep;
+#endif
+
+   png_debug(1, "in png_read_info");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   /* Read and check the PNG file signature. */
+   png_read_sig(png_ptr, info_ptr);
+
+   for (;;)
+   {
+      png_uint_32 length = png_read_chunk_header(png_ptr);
+      png_uint_32 chunk_name = png_ptr->chunk_name;
+
+      /* IDAT logic needs to happen here to simplify getting the two flags
+       * right.
+       */
+      if (chunk_name == png_IDAT)
+      {
+         if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+            png_chunk_error(png_ptr, "Missing IHDR before IDAT");
+
+         else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+             (png_ptr->mode & PNG_HAVE_PLTE) == 0)
+            png_chunk_error(png_ptr, "Missing PLTE before IDAT");
+
+         else if ((png_ptr->mode & PNG_AFTER_IDAT) != 0)
+            png_chunk_benign_error(png_ptr, "Too many IDATs found");
+
+         png_ptr->mode |= PNG_HAVE_IDAT;
+      }
+
+      else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
+         png_ptr->mode |= PNG_AFTER_IDAT;
+
+      /* This should be a binary subdivision search or a hash for
+       * matching the chunk name rather than a linear search.
+       */
+      if (chunk_name == png_IHDR)
+         png_handle_IHDR(png_ptr, info_ptr, length);
+
+      else if (chunk_name == png_IEND)
+         png_handle_IEND(png_ptr, info_ptr, length);
+
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+      else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0)
+      {
+         png_handle_unknown(png_ptr, info_ptr, length, keep);
+
+         if (chunk_name == png_PLTE)
+            png_ptr->mode |= PNG_HAVE_PLTE;
+
+         else if (chunk_name == png_IDAT)
+         {
+            png_ptr->idat_size = 0; /* It has been consumed */
+            break;
+         }
+      }
+#endif
+      else if (chunk_name == png_PLTE)
+         png_handle_PLTE(png_ptr, info_ptr, length);
+
+      else if (chunk_name == png_IDAT)
+      {
+         png_ptr->idat_size = length;
+         break;
+      }
+
+#ifdef PNG_READ_bKGD_SUPPORTED
+      else if (chunk_name == png_bKGD)
+         png_handle_bKGD(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_cHRM_SUPPORTED
+      else if (chunk_name == png_cHRM)
+         png_handle_cHRM(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_gAMA_SUPPORTED
+      else if (chunk_name == png_gAMA)
+         png_handle_gAMA(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_hIST_SUPPORTED
+      else if (chunk_name == png_hIST)
+         png_handle_hIST(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_oFFs_SUPPORTED
+      else if (chunk_name == png_oFFs)
+         png_handle_oFFs(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_pCAL_SUPPORTED
+      else if (chunk_name == png_pCAL)
+         png_handle_pCAL(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_sCAL_SUPPORTED
+      else if (chunk_name == png_sCAL)
+         png_handle_sCAL(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_pHYs_SUPPORTED
+      else if (chunk_name == png_pHYs)
+         png_handle_pHYs(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_sBIT_SUPPORTED
+      else if (chunk_name == png_sBIT)
+         png_handle_sBIT(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_sRGB_SUPPORTED
+      else if (chunk_name == png_sRGB)
+         png_handle_sRGB(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_iCCP_SUPPORTED
+      else if (chunk_name == png_iCCP)
+         png_handle_iCCP(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_sPLT_SUPPORTED
+      else if (chunk_name == png_sPLT)
+         png_handle_sPLT(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_tEXt_SUPPORTED
+      else if (chunk_name == png_tEXt)
+         png_handle_tEXt(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_tIME_SUPPORTED
+      else if (chunk_name == png_tIME)
+         png_handle_tIME(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_tRNS_SUPPORTED
+      else if (chunk_name == png_tRNS)
+         png_handle_tRNS(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_zTXt_SUPPORTED
+      else if (chunk_name == png_zTXt)
+         png_handle_zTXt(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_iTXt_SUPPORTED
+      else if (chunk_name == png_iTXt)
+         png_handle_iTXt(png_ptr, info_ptr, length);
+#endif
+
+      else
+         png_handle_unknown(png_ptr, info_ptr, length,
+            PNG_HANDLE_CHUNK_AS_DEFAULT);
+   }
+}
+#endif /* SEQUENTIAL_READ */
+
+/* Optional call to update the users info_ptr structure */
+void PNGAPI
+png_read_update_info(png_structrp png_ptr, png_inforp info_ptr)
+{
+   png_debug(1, "in png_read_update_info");
+
+   if (png_ptr != NULL)
+   {
+      if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0)
+      {
+         png_read_start_row(png_ptr);
+
+#        ifdef PNG_READ_TRANSFORMS_SUPPORTED
+            png_read_transform_info(png_ptr, info_ptr);
+#        else
+            PNG_UNUSED(info_ptr)
+#        endif
+      }
+
+      /* New in 1.6.0 this avoids the bug of doing the initializations twice */
+      else
+         png_app_error(png_ptr,
+            "png_read_update_info/png_start_read_image: duplicate call");
+   }
+}
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Initialize palette, background, etc, after transformations
+ * are set, but before any reading takes place.  This allows
+ * the user to obtain a gamma-corrected palette, for example.
+ * If the user doesn't call this, we will do it ourselves.
+ */
+void PNGAPI
+png_start_read_image(png_structrp png_ptr)
+{
+   png_debug(1, "in png_start_read_image");
+
+   if (png_ptr != NULL)
+   {
+      if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0)
+         png_read_start_row(png_ptr);
+
+      /* New in 1.6.0 this avoids the bug of doing the initializations twice */
+      else
+         png_app_error(png_ptr,
+            "png_start_read_image/png_read_update_info: duplicate call");
+   }
+}
+#endif /* SEQUENTIAL_READ */
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+/* Undoes intrapixel differencing,
+ * NOTE: this is apparently only supported in the 'sequential' reader.
+ */
+static void
+png_do_read_intrapixel(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_read_intrapixel");
+
+   if (
+       (row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
+   {
+      int bytes_per_pixel;
+      png_uint_32 row_width = row_info->width;
+
+      if (row_info->bit_depth == 8)
+      {
+         png_bytep rp;
+         png_uint_32 i;
+
+         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+            bytes_per_pixel = 3;
+
+         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+            bytes_per_pixel = 4;
+
+         else
+            return;
+
+         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+         {
+            *(rp) = (png_byte)((256 + *rp + *(rp + 1)) & 0xff);
+            *(rp+2) = (png_byte)((256 + *(rp + 2) + *(rp + 1)) & 0xff);
+         }
+      }
+      else if (row_info->bit_depth == 16)
+      {
+         png_bytep rp;
+         png_uint_32 i;
+
+         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+            bytes_per_pixel = 6;
+
+         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+            bytes_per_pixel = 8;
+
+         else
+            return;
+
+         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+         {
+            png_uint_32 s0   = (*(rp    ) << 8) | *(rp + 1);
+            png_uint_32 s1   = (*(rp + 2) << 8) | *(rp + 3);
+            png_uint_32 s2   = (*(rp + 4) << 8) | *(rp + 5);
+            png_uint_32 red  = (s0 + s1 + 65536) & 0xffff;
+            png_uint_32 blue = (s2 + s1 + 65536) & 0xffff;
+            *(rp    ) = (png_byte)((red >> 8) & 0xff);
+            *(rp + 1) = (png_byte)(red & 0xff);
+            *(rp + 4) = (png_byte)((blue >> 8) & 0xff);
+            *(rp + 5) = (png_byte)(blue & 0xff);
+         }
+      }
+   }
+}
+#endif /* MNG_FEATURES */
+
+void PNGAPI
+png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row)
+{
+   png_row_info row_info;
+
+   if (png_ptr == NULL)
+      return;
+
+   png_debug2(1, "in png_read_row (row %lu, pass %d)",
+       (unsigned long)png_ptr->row_number, png_ptr->pass);
+
+   /* png_read_start_row sets the information (in particular iwidth) for this
+    * interlace pass.
+    */
+   if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0)
+      png_read_start_row(png_ptr);
+
+   /* 1.5.6: row_info moved out of png_struct to a local here. */
+   row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */
+   row_info.color_type = png_ptr->color_type;
+   row_info.bit_depth = png_ptr->bit_depth;
+   row_info.channels = png_ptr->channels;
+   row_info.pixel_depth = png_ptr->pixel_depth;
+   row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width);
+
+#ifdef PNG_WARNINGS_SUPPORTED
+   if (png_ptr->row_number == 0 && png_ptr->pass == 0)
+   {
+   /* Check for transforms that have been set but were defined out */
+#if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED)
+   if ((png_ptr->transformations & PNG_INVERT_MONO) != 0)
+      png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined");
+#endif
+
+#if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED)
+   if ((png_ptr->transformations & PNG_FILLER) != 0)
+      png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined");
+#endif
+
+#if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \
+    !defined(PNG_READ_PACKSWAP_SUPPORTED)
+   if ((png_ptr->transformations & PNG_PACKSWAP) != 0)
+      png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined");
+#endif
+
+#if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED)
+   if ((png_ptr->transformations & PNG_PACK) != 0)
+      png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined");
+#endif
+
+#if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED)
+   if ((png_ptr->transformations & PNG_SHIFT) != 0)
+      png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined");
+#endif
+
+#if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED)
+   if ((png_ptr->transformations & PNG_BGR) != 0)
+      png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined");
+#endif
+
+#if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED)
+   if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0)
+      png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined");
+#endif
+   }
+#endif /* WARNINGS */
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+   /* If interlaced and we do not need a new row, combine row and return.
+    * Notice that the pixels we have from previous rows have been transformed
+    * already; we can only combine like with like (transformed or
+    * untransformed) and, because of the libpng API for interlaced images, this
+    * means we must transform before de-interlacing.
+    */
+   if (png_ptr->interlaced != 0 &&
+       (png_ptr->transformations & PNG_INTERLACE) != 0)
+   {
+      switch (png_ptr->pass)
+      {
+         case 0:
+            if (png_ptr->row_number & 0x07)
+            {
+               if (dsp_row != NULL)
+                  png_combine_row(png_ptr, dsp_row, 1/*display*/);
+               png_read_finish_row(png_ptr);
+               return;
+            }
+            break;
+
+         case 1:
+            if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
+            {
+               if (dsp_row != NULL)
+                  png_combine_row(png_ptr, dsp_row, 1/*display*/);
+
+               png_read_finish_row(png_ptr);
+               return;
+            }
+            break;
+
+         case 2:
+            if ((png_ptr->row_number & 0x07) != 4)
+            {
+               if (dsp_row != NULL && (png_ptr->row_number & 4))
+                  png_combine_row(png_ptr, dsp_row, 1/*display*/);
+
+               png_read_finish_row(png_ptr);
+               return;
+            }
+            break;
+
+         case 3:
+            if ((png_ptr->row_number & 3) || png_ptr->width < 3)
+            {
+               if (dsp_row != NULL)
+                  png_combine_row(png_ptr, dsp_row, 1/*display*/);
+
+               png_read_finish_row(png_ptr);
+               return;
+            }
+            break;
+
+         case 4:
+            if ((png_ptr->row_number & 3) != 2)
+            {
+               if (dsp_row != NULL && (png_ptr->row_number & 2))
+                  png_combine_row(png_ptr, dsp_row, 1/*display*/);
+
+               png_read_finish_row(png_ptr);
+               return;
+            }
+            break;
+
+         case 5:
+            if ((png_ptr->row_number & 1) || png_ptr->width < 2)
+            {
+               if (dsp_row != NULL)
+                  png_combine_row(png_ptr, dsp_row, 1/*display*/);
+
+               png_read_finish_row(png_ptr);
+               return;
+            }
+            break;
+
+         default:
+         case 6:
+            if ((png_ptr->row_number & 1) == 0)
+            {
+               png_read_finish_row(png_ptr);
+               return;
+            }
+            break;
+      }
+   }
+#endif
+
+   if ((png_ptr->mode & PNG_HAVE_IDAT) == 0)
+      png_error(png_ptr, "Invalid attempt to read row data");
+
+   /* Fill the row with IDAT data: */
+   png_read_IDAT_data(png_ptr, png_ptr->row_buf, row_info.rowbytes + 1);
+
+   if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE)
+   {
+      if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST)
+         png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1,
+            png_ptr->prev_row + 1, png_ptr->row_buf[0]);
+      else
+         png_error(png_ptr, "bad adaptive filter value");
+   }
+
+   /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before
+    * 1.5.6, while the buffer really is this big in current versions of libpng
+    * it may not be in the future, so this was changed just to copy the
+    * interlaced count:
+    */
+   memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1);
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+   if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 &&
+       (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
+   {
+      /* Intrapixel differencing */
+      png_do_read_intrapixel(&row_info, png_ptr->row_buf + 1);
+   }
+#endif
+
+#ifdef PNG_READ_TRANSFORMS_SUPPORTED
+   if (png_ptr->transformations)
+      png_do_read_transformations(png_ptr, &row_info);
+#endif
+
+   /* The transformed pixel depth should match the depth now in row_info. */
+   if (png_ptr->transformed_pixel_depth == 0)
+   {
+      png_ptr->transformed_pixel_depth = row_info.pixel_depth;
+      if (row_info.pixel_depth > png_ptr->maximum_pixel_depth)
+         png_error(png_ptr, "sequential row overflow");
+   }
+
+   else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth)
+      png_error(png_ptr, "internal sequential row size calculation error");
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+   /* Expand interlaced rows to full size */
+   if (png_ptr->interlaced != 0 &&
+      (png_ptr->transformations & PNG_INTERLACE) != 0)
+   {
+      if (png_ptr->pass < 6)
+         png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,
+            png_ptr->transformations);
+
+      if (dsp_row != NULL)
+         png_combine_row(png_ptr, dsp_row, 1/*display*/);
+
+      if (row != NULL)
+         png_combine_row(png_ptr, row, 0/*row*/);
+   }
+
+   else
+#endif
+   {
+      if (row != NULL)
+         png_combine_row(png_ptr, row, -1/*ignored*/);
+
+      if (dsp_row != NULL)
+         png_combine_row(png_ptr, dsp_row, -1/*ignored*/);
+   }
+   png_read_finish_row(png_ptr);
+
+   if (png_ptr->read_row_fn != NULL)
+      (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
+
+}
+#endif /* SEQUENTIAL_READ */
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Read one or more rows of image data.  If the image is interlaced,
+ * and png_set_interlace_handling() has been called, the rows need to
+ * contain the contents of the rows from the previous pass.  If the
+ * image has alpha or transparency, and png_handle_alpha()[*] has been
+ * called, the rows contents must be initialized to the contents of the
+ * screen.
+ *
+ * "row" holds the actual image, and pixels are placed in it
+ * as they arrive.  If the image is displayed after each pass, it will
+ * appear to "sparkle" in.  "display_row" can be used to display a
+ * "chunky" progressive image, with finer detail added as it becomes
+ * available.  If you do not want this "chunky" display, you may pass
+ * NULL for display_row.  If you do not want the sparkle display, and
+ * you have not called png_handle_alpha(), you may pass NULL for rows.
+ * If you have called png_handle_alpha(), and the image has either an
+ * alpha channel or a transparency chunk, you must provide a buffer for
+ * rows.  In this case, you do not have to provide a display_row buffer
+ * also, but you may.  If the image is not interlaced, or if you have
+ * not called png_set_interlace_handling(), the display_row buffer will
+ * be ignored, so pass NULL to it.
+ *
+ * [*] png_handle_alpha() does not exist yet, as of this version of libpng
+ */
+
+void PNGAPI
+png_read_rows(png_structrp png_ptr, png_bytepp row,
+    png_bytepp display_row, png_uint_32 num_rows)
+{
+   png_uint_32 i;
+   png_bytepp rp;
+   png_bytepp dp;
+
+   png_debug(1, "in png_read_rows");
+
+   if (png_ptr == NULL)
+      return;
+
+   rp = row;
+   dp = display_row;
+   if (rp != NULL && dp != NULL)
+      for (i = 0; i < num_rows; i++)
+      {
+         png_bytep rptr = *rp++;
+         png_bytep dptr = *dp++;
+
+         png_read_row(png_ptr, rptr, dptr);
+      }
+
+   else if (rp != NULL)
+      for (i = 0; i < num_rows; i++)
+      {
+         png_bytep rptr = *rp;
+         png_read_row(png_ptr, rptr, NULL);
+         rp++;
+      }
+
+   else if (dp != NULL)
+      for (i = 0; i < num_rows; i++)
+      {
+         png_bytep dptr = *dp;
+         png_read_row(png_ptr, NULL, dptr);
+         dp++;
+      }
+}
+#endif /* SEQUENTIAL_READ */
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Read the entire image.  If the image has an alpha channel or a tRNS
+ * chunk, and you have called png_handle_alpha()[*], you will need to
+ * initialize the image to the current image that PNG will be overlaying.
+ * We set the num_rows again here, in case it was incorrectly set in
+ * png_read_start_row() by a call to png_read_update_info() or
+ * png_start_read_image() if png_set_interlace_handling() wasn't called
+ * prior to either of these functions like it should have been.  You can
+ * only call this function once.  If you desire to have an image for
+ * each pass of a interlaced image, use png_read_rows() instead.
+ *
+ * [*] png_handle_alpha() does not exist yet, as of this version of libpng
+ */
+void PNGAPI
+png_read_image(png_structrp png_ptr, png_bytepp image)
+{
+   png_uint_32 i, image_height;
+   int pass, j;
+   png_bytepp rp;
+
+   png_debug(1, "in png_read_image");
+
+   if (png_ptr == NULL)
+      return;
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+   if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0)
+   {
+      pass = png_set_interlace_handling(png_ptr);
+      /* And make sure transforms are initialized. */
+      png_start_read_image(png_ptr);
+   }
+   else
+   {
+      if (png_ptr->interlaced != 0 &&
+          (png_ptr->transformations & PNG_INTERLACE) == 0)
+      {
+         /* Caller called png_start_read_image or png_read_update_info without
+          * first turning on the PNG_INTERLACE transform.  We can fix this here,
+          * but the caller should do it!
+          */
+         png_warning(png_ptr, "Interlace handling should be turned on when "
+            "using png_read_image");
+         /* Make sure this is set correctly */
+         png_ptr->num_rows = png_ptr->height;
+      }
+
+      /* Obtain the pass number, which also turns on the PNG_INTERLACE flag in
+       * the above error case.
+       */
+      pass = png_set_interlace_handling(png_ptr);
+   }
+#else
+   if (png_ptr->interlaced)
+      png_error(png_ptr,
+          "Cannot read interlaced image -- interlace handler disabled");
+
+   pass = 1;
+#endif
+
+   image_height=png_ptr->height;
+
+   for (j = 0; j < pass; j++)
+   {
+      rp = image;
+      for (i = 0; i < image_height; i++)
+      {
+         png_read_row(png_ptr, *rp, NULL);
+         rp++;
+      }
+   }
+}
+#endif /* SEQUENTIAL_READ */
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Read the end of the PNG file.  Will not read past the end of the
+ * file, will verify the end is accurate, and will read any comments
+ * or time information at the end of the file, if info is not NULL.
+ */
+void PNGAPI
+png_read_end(png_structrp png_ptr, png_inforp info_ptr)
+{
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+   int keep;
+#endif
+
+   png_debug(1, "in png_read_end");
+
+   if (png_ptr == NULL)
+      return;
+
+   /* If png_read_end is called in the middle of reading the rows there may
+    * still be pending IDAT data and an owned zstream.  Deal with this here.
+    */
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+   if (png_chunk_unknown_handling(png_ptr, png_IDAT) == 0)
+#endif
+      png_read_finish_IDAT(png_ptr);
+
+#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
+   /* Report invalid palette index; added at libng-1.5.10 */
+   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+      png_ptr->num_palette_max > png_ptr->num_palette)
+     png_benign_error(png_ptr, "Read palette index exceeding num_palette");
+#endif
+
+   do
+   {
+      png_uint_32 length = png_read_chunk_header(png_ptr);
+      png_uint_32 chunk_name = png_ptr->chunk_name;
+
+      if (chunk_name == png_IEND)
+         png_handle_IEND(png_ptr, info_ptr, length);
+
+      else if (chunk_name == png_IHDR)
+         png_handle_IHDR(png_ptr, info_ptr, length);
+
+      else if (info_ptr == NULL)
+         png_crc_finish(png_ptr, length);
+
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+      else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0)
+      {
+         if (chunk_name == png_IDAT)
+         {
+            if ((length > 0) ||
+                (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0)
+               png_benign_error(png_ptr, "Too many IDATs found");
+         }
+         png_handle_unknown(png_ptr, info_ptr, length, keep);
+         if (chunk_name == png_PLTE)
+            png_ptr->mode |= PNG_HAVE_PLTE;
+      }
+#endif
+
+      else if (chunk_name == png_IDAT)
+      {
+         /* Zero length IDATs are legal after the last IDAT has been
+          * read, but not after other chunks have been read.
+          */
+         if ((length > 0) ||
+             (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0)
+            png_benign_error(png_ptr, "Too many IDATs found");
+
+         png_crc_finish(png_ptr, length);
+      }
+      else if (chunk_name == png_PLTE)
+         png_handle_PLTE(png_ptr, info_ptr, length);
+
+#ifdef PNG_READ_bKGD_SUPPORTED
+      else if (chunk_name == png_bKGD)
+         png_handle_bKGD(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_cHRM_SUPPORTED
+      else if (chunk_name == png_cHRM)
+         png_handle_cHRM(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_gAMA_SUPPORTED
+      else if (chunk_name == png_gAMA)
+         png_handle_gAMA(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_hIST_SUPPORTED
+      else if (chunk_name == png_hIST)
+         png_handle_hIST(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_oFFs_SUPPORTED
+      else if (chunk_name == png_oFFs)
+         png_handle_oFFs(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_pCAL_SUPPORTED
+      else if (chunk_name == png_pCAL)
+         png_handle_pCAL(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_sCAL_SUPPORTED
+      else if (chunk_name == png_sCAL)
+         png_handle_sCAL(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_pHYs_SUPPORTED
+      else if (chunk_name == png_pHYs)
+         png_handle_pHYs(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_sBIT_SUPPORTED
+      else if (chunk_name == png_sBIT)
+         png_handle_sBIT(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_sRGB_SUPPORTED
+      else if (chunk_name == png_sRGB)
+         png_handle_sRGB(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_iCCP_SUPPORTED
+      else if (chunk_name == png_iCCP)
+         png_handle_iCCP(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_sPLT_SUPPORTED
+      else if (chunk_name == png_sPLT)
+         png_handle_sPLT(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_tEXt_SUPPORTED
+      else if (chunk_name == png_tEXt)
+         png_handle_tEXt(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_tIME_SUPPORTED
+      else if (chunk_name == png_tIME)
+         png_handle_tIME(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_tRNS_SUPPORTED
+      else if (chunk_name == png_tRNS)
+         png_handle_tRNS(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_zTXt_SUPPORTED
+      else if (chunk_name == png_zTXt)
+         png_handle_zTXt(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_iTXt_SUPPORTED
+      else if (chunk_name == png_iTXt)
+         png_handle_iTXt(png_ptr, info_ptr, length);
+#endif
+
+      else
+         png_handle_unknown(png_ptr, info_ptr, length,
+            PNG_HANDLE_CHUNK_AS_DEFAULT);
+   } while ((png_ptr->mode & PNG_HAVE_IEND) == 0);
+}
+#endif /* SEQUENTIAL_READ */
+
+/* Free all memory used in the read struct */
+static void
+png_read_destroy(png_structrp png_ptr)
+{
+   png_debug(1, "in png_read_destroy");
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+   png_destroy_gamma_table(png_ptr);
+#endif
+
+   png_free(png_ptr, png_ptr->big_row_buf);
+   png_ptr->big_row_buf = NULL;
+   png_free(png_ptr, png_ptr->big_prev_row);
+   png_ptr->big_prev_row = NULL;
+   png_free(png_ptr, png_ptr->read_buffer);
+   png_ptr->read_buffer = NULL;
+
+#ifdef PNG_READ_QUANTIZE_SUPPORTED
+   png_free(png_ptr, png_ptr->palette_lookup);
+   png_ptr->palette_lookup = NULL;
+   png_free(png_ptr, png_ptr->quantize_index);
+   png_ptr->quantize_index = NULL;
+#endif
+
+   if ((png_ptr->free_me & PNG_FREE_PLTE) != 0)
+   {
+      png_zfree(png_ptr, png_ptr->palette);
+      png_ptr->palette = NULL;
+   }
+   png_ptr->free_me &= ~PNG_FREE_PLTE;
+
+#if defined(PNG_tRNS_SUPPORTED) || \
+    defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+   if ((png_ptr->free_me & PNG_FREE_TRNS) != 0)
+   {
+      png_free(png_ptr, png_ptr->trans_alpha);
+      png_ptr->trans_alpha = NULL;
+   }
+   png_ptr->free_me &= ~PNG_FREE_TRNS;
+#endif
+
+   inflateEnd(&png_ptr->zstream);
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+   png_free(png_ptr, png_ptr->save_buffer);
+   png_ptr->save_buffer = NULL;
+#endif
+
+#if defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) && \
+   defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
+   png_free(png_ptr, png_ptr->unknown_chunk.data);
+   png_ptr->unknown_chunk.data = NULL;
+#endif
+
+#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
+   png_free(png_ptr, png_ptr->chunk_list);
+   png_ptr->chunk_list = NULL;
+#endif
+
+   /* NOTE: the 'setjmp' buffer may still be allocated and the memory and error
+    * callbacks are still set at this point.  They are required to complete the
+    * destruction of the png_struct itself.
+    */
+}
+
+/* Free all memory used by the read */
+void PNGAPI
+png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
+    png_infopp end_info_ptr_ptr)
+{
+   png_structrp png_ptr = NULL;
+
+   png_debug(1, "in png_destroy_read_struct");
+
+   if (png_ptr_ptr != NULL)
+      png_ptr = *png_ptr_ptr;
+
+   if (png_ptr == NULL)
+      return;
+
+   /* libpng 1.6.0: use the API to destroy info structs to ensure consistent
+    * behavior.  Prior to 1.6.0 libpng did extra 'info' destruction in this API.
+    * The extra was, apparently, unnecessary yet this hides memory leak bugs.
+    */
+   png_destroy_info_struct(png_ptr, end_info_ptr_ptr);
+   png_destroy_info_struct(png_ptr, info_ptr_ptr);
+
+   *png_ptr_ptr = NULL;
+   png_read_destroy(png_ptr);
+   png_destroy_png_struct(png_ptr);
+}
+
+void PNGAPI
+png_set_read_status_fn(png_structrp png_ptr, png_read_status_ptr read_row_fn)
+{
+   if (png_ptr == NULL)
+      return;
+
+   png_ptr->read_row_fn = read_row_fn;
+}
+
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+#ifdef PNG_INFO_IMAGE_SUPPORTED
+void PNGAPI
+png_read_png(png_structrp png_ptr, png_inforp info_ptr,
+                           int transforms,
+                           voidp params)
+{
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   /* png_read_info() gives us all of the information from the
+    * PNG file before the first IDAT (image data chunk).
+    */
+   png_read_info(png_ptr, info_ptr);
+   if (info_ptr->height > PNG_UINT_32_MAX/(sizeof (png_bytep)))
+      png_error(png_ptr, "Image is too high to process with png_read_png()");
+
+   /* -------------- image transformations start here ------------------- */
+   /* libpng 1.6.10: add code to cause a png_app_error if a selected TRANSFORM
+    * is not implemented.  This will only happen in de-configured (non-default)
+    * libpng builds.  The results can be unexpected - png_read_png may return
+    * short or mal-formed rows because the transform is skipped.
+    */
+
+   /* Tell libpng to strip 16-bit/color files down to 8 bits per color.
+    */
+   if ((transforms & PNG_TRANSFORM_SCALE_16) != 0)
+     /* Added at libpng-1.5.4. "strip_16" produces the same result that it
+      * did in earlier versions, while "scale_16" is now more accurate.
+      */
+#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
+      png_set_scale_16(png_ptr);
+#else
+      png_app_error(png_ptr, "PNG_TRANSFORM_SCALE_16 not supported");
+#endif
+
+   /* If both SCALE and STRIP are required pngrtran will effectively cancel the
+    * latter by doing SCALE first.  This is ok and allows apps not to check for
+    * which is supported to get the right answer.
+    */
+   if ((transforms & PNG_TRANSFORM_STRIP_16) != 0)
+#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
+      png_set_strip_16(png_ptr);
+#else
+      png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_16 not supported");
+#endif
+
+   /* Strip alpha bytes from the input data without combining with
+    * the background (not recommended).
+    */
+   if ((transforms & PNG_TRANSFORM_STRIP_ALPHA) != 0)
+#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
+      png_set_strip_alpha(png_ptr);
+#else
+      png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_ALPHA not supported");
+#endif
+
+   /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single
+    * byte into separate bytes (useful for paletted and grayscale images).
+    */
+   if ((transforms & PNG_TRANSFORM_PACKING) != 0)
+#ifdef PNG_READ_PACK_SUPPORTED
+      png_set_packing(png_ptr);
+#else
+      png_app_error(png_ptr, "PNG_TRANSFORM_PACKING not supported");
+#endif
+
+   /* Change the order of packed pixels to least significant bit first
+    * (not useful if you are using png_set_packing).
+    */
+   if ((transforms & PNG_TRANSFORM_PACKSWAP) != 0)
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
+      png_set_packswap(png_ptr);
+#else
+      png_app_error(png_ptr, "PNG_TRANSFORM_PACKSWAP not supported");
+#endif
+
+   /* Expand paletted colors into true RGB triplets
+    * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel
+    * Expand paletted or RGB images with transparency to full alpha
+    * channels so the data will be available as RGBA quartets.
+    */
+   if ((transforms & PNG_TRANSFORM_EXPAND) != 0)
+#ifdef PNG_READ_EXPAND_SUPPORTED
+      png_set_expand(png_ptr);
+#else
+      png_app_error(png_ptr, "PNG_TRANSFORM_EXPAND not supported");
+#endif
+
+   /* We don't handle background color or gamma transformation or quantizing.
+    */
+
+   /* Invert monochrome files to have 0 as white and 1 as black
+    */
+   if ((transforms & PNG_TRANSFORM_INVERT_MONO) != 0)
+#ifdef PNG_READ_INVERT_SUPPORTED
+      png_set_invert_mono(png_ptr);
+#else
+      png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_MONO not supported");
+#endif
+
+   /* If you want to shift the pixel values from the range [0,255] or
+    * [0,65535] to the original [0,7] or [0,31], or whatever range the
+    * colors were originally in:
+    */
+   if ((transforms & PNG_TRANSFORM_SHIFT) != 0)
+#ifdef PNG_READ_SHIFT_SUPPORTED
+      if ((info_ptr->valid & PNG_INFO_sBIT) != 0)
+         png_set_shift(png_ptr, &info_ptr->sig_bit);
+#else
+      png_app_error(png_ptr, "PNG_TRANSFORM_SHIFT not supported");
+#endif
+
+   /* Flip the RGB pixels to BGR (or RGBA to BGRA) */
+   if ((transforms & PNG_TRANSFORM_BGR) != 0)
+#ifdef PNG_READ_BGR_SUPPORTED
+      png_set_bgr(png_ptr);
+#else
+      png_app_error(png_ptr, "PNG_TRANSFORM_BGR not supported");
+#endif
+
+   /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */
+   if ((transforms & PNG_TRANSFORM_SWAP_ALPHA) != 0)
+#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
+      png_set_swap_alpha(png_ptr);
+#else
+      png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ALPHA not supported");
+#endif
+
+   /* Swap bytes of 16-bit files to least significant byte first */
+   if ((transforms & PNG_TRANSFORM_SWAP_ENDIAN) != 0)
+#ifdef PNG_READ_SWAP_SUPPORTED
+      png_set_swap(png_ptr);
+#else
+      png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ENDIAN not supported");
+#endif
+
+/* Added at libpng-1.2.41 */
+   /* Invert the alpha channel from opacity to transparency */
+   if ((transforms & PNG_TRANSFORM_INVERT_ALPHA) != 0)
+#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
+      png_set_invert_alpha(png_ptr);
+#else
+      png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_ALPHA not supported");
+#endif
+
+/* Added at libpng-1.2.41 */
+   /* Expand grayscale image to RGB */
+   if ((transforms & PNG_TRANSFORM_GRAY_TO_RGB) != 0)
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+      png_set_gray_to_rgb(png_ptr);
+#else
+      png_app_error(png_ptr, "PNG_TRANSFORM_GRAY_TO_RGB not supported");
+#endif
+
+/* Added at libpng-1.5.4 */
+   if ((transforms & PNG_TRANSFORM_EXPAND_16) != 0)
+#ifdef PNG_READ_EXPAND_16_SUPPORTED
+      png_set_expand_16(png_ptr);
+#else
+      png_app_error(png_ptr, "PNG_TRANSFORM_EXPAND_16 not supported");
+#endif
+
+   /* We don't handle adding filler bytes */
+
+   /* We use png_read_image and rely on that for interlace handling, but we also
+    * call png_read_update_info therefore must turn on interlace handling now:
+    */
+   (void)png_set_interlace_handling(png_ptr);
+
+   /* Optional call to gamma correct and add the background to the palette
+    * and update info structure.  REQUIRED if you are expecting libpng to
+    * update the palette for you (i.e., you selected such a transform above).
+    */
+   png_read_update_info(png_ptr, info_ptr);
+
+   /* -------------- image transformations end here ------------------- */
+
+   png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
+   if (info_ptr->row_pointers == NULL)
+   {
+      png_uint_32 iptr;
+
+      info_ptr->row_pointers = png_voidcast(png_bytepp, png_malloc(png_ptr,
+          info_ptr->height * (sizeof (png_bytep))));
+
+      for (iptr=0; iptr<info_ptr->height; iptr++)
+         info_ptr->row_pointers[iptr] = NULL;
+
+      info_ptr->free_me |= PNG_FREE_ROWS;
+
+      for (iptr = 0; iptr < info_ptr->height; iptr++)
+         info_ptr->row_pointers[iptr] = png_voidcast(png_bytep,
+            png_malloc(png_ptr, info_ptr->rowbytes));
+   }
+
+   png_read_image(png_ptr, info_ptr->row_pointers);
+   info_ptr->valid |= PNG_INFO_IDAT;
+
+   /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */
+   png_read_end(png_ptr, info_ptr);
+
+   PNG_UNUSED(params)
+}
+#endif /* INFO_IMAGE */
+#endif /* SEQUENTIAL_READ */
+
+#ifdef PNG_SIMPLIFIED_READ_SUPPORTED
+/* SIMPLIFIED READ
+ *
+ * This code currently relies on the sequential reader, though it could easily
+ * be made to work with the progressive one.
+ */
+/* Arguments to png_image_finish_read: */
+
+/* Encoding of PNG data (used by the color-map code) */
+#  define P_NOTSET  0 /* File encoding not yet known */
+#  define P_sRGB    1 /* 8-bit encoded to sRGB gamma */
+#  define P_LINEAR  2 /* 16-bit linear: not encoded, NOT pre-multiplied! */
+#  define P_FILE    3 /* 8-bit encoded to file gamma, not sRGB or linear */
+#  define P_LINEAR8 4 /* 8-bit linear: only from a file value */
+
+/* Color-map processing: after libpng has run on the PNG image further
+ * processing may be needed to convert the data to color-map indices.
+ */
+#define PNG_CMAP_NONE      0
+#define PNG_CMAP_GA        1 /* Process GA data to a color-map with alpha */
+#define PNG_CMAP_TRANS     2 /* Process GA data to a background index */
+#define PNG_CMAP_RGB       3 /* Process RGB data */
+#define PNG_CMAP_RGB_ALPHA 4 /* Process RGBA data */
+
+/* The following document where the background is for each processing case. */
+#define PNG_CMAP_NONE_BACKGROUND      256
+#define PNG_CMAP_GA_BACKGROUND        231
+#define PNG_CMAP_TRANS_BACKGROUND     254
+#define PNG_CMAP_RGB_BACKGROUND       256
+#define PNG_CMAP_RGB_ALPHA_BACKGROUND 216
+
+typedef struct
+{
+   /* Arguments: */
+   png_imagep image;
+   png_voidp  buffer;
+   png_int_32 row_stride;
+   png_voidp  colormap;
+   png_const_colorp background;
+   /* Local variables: */
+   png_voidp       local_row;
+   png_voidp       first_row;
+   ptrdiff_t       row_bytes;           /* step between rows */
+   int             file_encoding;       /* E_ values above */
+   png_fixed_point gamma_to_linear;     /* For P_FILE, reciprocal of gamma */
+   int             colormap_processing; /* PNG_CMAP_ values above */
+} png_image_read_control;
+
+/* Do all the *safe* initialization - 'safe' means that png_error won't be
+ * called, so setting up the jmp_buf is not required.  This means that anything
+ * called from here must *not* call png_malloc - it has to call png_malloc_warn
+ * instead so that control is returned safely back to this routine.
+ */
+static int
+png_image_read_init(png_imagep image)
+{
+   if (image->opaque == NULL)
+   {
+      png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, image,
+          png_safe_error, png_safe_warning);
+
+      /* And set the rest of the structure to NULL to ensure that the various
+       * fields are consistent.
+       */
+      memset(image, 0, (sizeof *image));
+      image->version = PNG_IMAGE_VERSION;
+
+      if (png_ptr != NULL)
+      {
+         png_infop info_ptr = png_create_info_struct(png_ptr);
+
+         if (info_ptr != NULL)
+         {
+            png_controlp control = png_voidcast(png_controlp,
+               png_malloc_warn(png_ptr, (sizeof *control)));
+
+            if (control != NULL)
+            {
+               memset(control, 0, (sizeof *control));
+
+               control->png_ptr = png_ptr;
+               control->info_ptr = info_ptr;
+               control->for_write = 0;
+
+               image->opaque = control;
+               return 1;
+            }
+
+            /* Error clean up */
+            png_destroy_info_struct(png_ptr, &info_ptr);
+         }
+
+         png_destroy_read_struct(&png_ptr, NULL, NULL);
+      }
+
+      return png_image_error(image, "png_image_read: out of memory");
+   }
+
+   return png_image_error(image, "png_image_read: opaque pointer not NULL");
+}
+
+/* Utility to find the base format of a PNG file from a png_struct. */
+static png_uint_32
+png_image_format(png_structrp png_ptr)
+{
+   png_uint_32 format = 0;
+
+   if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
+      format |= PNG_FORMAT_FLAG_COLOR;
+
+   if ((png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)
+      format |= PNG_FORMAT_FLAG_ALPHA;
+
+   /* Use png_ptr here, not info_ptr, because by examination png_handle_tRNS
+    * sets the png_struct fields; that's all we are interested in here.  The
+    * precise interaction with an app call to png_set_tRNS and PNG file reading
+    * is unclear.
+    */
+   else if (png_ptr->num_trans > 0)
+      format |= PNG_FORMAT_FLAG_ALPHA;
+
+   if (png_ptr->bit_depth == 16)
+      format |= PNG_FORMAT_FLAG_LINEAR;
+
+   if ((png_ptr->color_type & PNG_COLOR_MASK_PALETTE) != 0)
+      format |= PNG_FORMAT_FLAG_COLORMAP;
+
+   return format;
+}
+
+/* Is the given gamma significantly different from sRGB?  The test is the same
+ * one used in pngrtran.c when deciding whether to do gamma correction.  The
+ * arithmetic optimizes the division by using the fact that the inverse of the
+ * file sRGB gamma is 2.2
+ */
+static int
+png_gamma_not_sRGB(png_fixed_point g)
+{
+   if (g < PNG_FP_1)
+   {
+      /* An uninitialized gamma is assumed to be sRGB for the simplified API. */
+      if (g == 0)
+         return 0;
+
+      return png_gamma_significant((g * 11 + 2)/5 /* i.e. *2.2, rounded */);
+   }
+
+   return 1;
+}
+
+/* Do the main body of a 'png_image_begin_read' function; read the PNG file
+ * header and fill in all the information.  This is executed in a safe context,
+ * unlike the init routine above.
+ */
+static int
+png_image_read_header(png_voidp argument)
+{
+   png_imagep image = png_voidcast(png_imagep, argument);
+   png_structrp png_ptr = image->opaque->png_ptr;
+   png_inforp info_ptr = image->opaque->info_ptr;
+
+   png_set_benign_errors(png_ptr, 1/*warn*/);
+   png_read_info(png_ptr, info_ptr);
+
+   /* Do this the fast way; just read directly out of png_struct. */
+   image->width = png_ptr->width;
+   image->height = png_ptr->height;
+
+   {
+      png_uint_32 format = png_image_format(png_ptr);
+
+      image->format = format;
+
+#ifdef PNG_COLORSPACE_SUPPORTED
+      /* Does the colorspace match sRGB?  If there is no color endpoint
+       * (colorant) information assume yes, otherwise require the
+       * 'ENDPOINTS_MATCHP_sRGB' colorspace flag to have been set.  If the
+       * colorspace has been determined to be invalid ignore it.
+       */
+      if ((format & PNG_FORMAT_FLAG_COLOR) != 0 && ((png_ptr->colorspace.flags
+         & (PNG_COLORSPACE_HAVE_ENDPOINTS|PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB|
+            PNG_COLORSPACE_INVALID)) == PNG_COLORSPACE_HAVE_ENDPOINTS))
+         image->flags |= PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB;
+#endif
+   }
+
+   /* We need the maximum number of entries regardless of the format the
+    * application sets here.
+    */
+   {
+      png_uint_32 cmap_entries;
+
+      switch (png_ptr->color_type)
+      {
+         case PNG_COLOR_TYPE_GRAY:
+            cmap_entries = 1U << png_ptr->bit_depth;
+            break;
+
+         case PNG_COLOR_TYPE_PALETTE:
+            cmap_entries = png_ptr->num_palette;
+            break;
+
+         default:
+            cmap_entries = 256;
+            break;
+      }
+
+      if (cmap_entries > 256)
+         cmap_entries = 256;
+
+      image->colormap_entries = cmap_entries;
+   }
+
+   return 1;
+}
+
+#ifdef PNG_STDIO_SUPPORTED
+int PNGAPI
+png_image_begin_read_from_stdio(png_imagep image, FILE* file)
+{
+   if (image != NULL && image->version == PNG_IMAGE_VERSION)
+   {
+      if (file != NULL)
+      {
+         if (png_image_read_init(image) != 0)
+         {
+            /* This is slightly evil, but png_init_io doesn't do anything other
+             * than this and we haven't changed the standard IO functions so
+             * this saves a 'safe' function.
+             */
+            image->opaque->png_ptr->io_ptr = file;
+            return png_safe_execute(image, png_image_read_header, image);
+         }
+      }
+
+      else
+         return png_image_error(image,
+            "png_image_begin_read_from_stdio: invalid argument");
+   }
+
+   else if (image != NULL)
+      return png_image_error(image,
+         "png_image_begin_read_from_stdio: incorrect PNG_IMAGE_VERSION");
+
+   return 0;
+}
+
+int PNGAPI
+png_image_begin_read_from_file(png_imagep image, const char *file_name)
+{
+   if (image != NULL && image->version == PNG_IMAGE_VERSION)
+   {
+      if (file_name != NULL)
+      {
+         FILE *fp = fopen(file_name, "rb");
+
+         if (fp != NULL)
+         {
+            if (png_image_read_init(image) != 0)
+            {
+               image->opaque->png_ptr->io_ptr = fp;
+               image->opaque->owned_file = 1;
+               return png_safe_execute(image, png_image_read_header, image);
+            }
+
+            /* Clean up: just the opened file. */
+            (void)fclose(fp);
+         }
+
+         else
+            return png_image_error(image, strerror(errno));
+      }
+
+      else
+         return png_image_error(image,
+            "png_image_begin_read_from_file: invalid argument");
+   }
+
+   else if (image != NULL)
+      return png_image_error(image,
+         "png_image_begin_read_from_file: incorrect PNG_IMAGE_VERSION");
+
+   return 0;
+}
+#endif /* STDIO */
+
+static void PNGCBAPI
+png_image_memory_read(png_structp png_ptr, png_bytep out, png_size_t need)
+{
+   if (png_ptr != NULL)
+   {
+      png_imagep image = png_voidcast(png_imagep, png_ptr->io_ptr);
+      if (image != NULL)
+      {
+         png_controlp cp = image->opaque;
+         if (cp != NULL)
+         {
+            png_const_bytep memory = cp->memory;
+            png_size_t size = cp->size;
+
+            if (memory != NULL && size >= need)
+            {
+               memcpy(out, memory, need);
+               cp->memory = memory + need;
+               cp->size = size - need;
+               return;
+            }
+
+            png_error(png_ptr, "read beyond end of data");
+         }
+      }
+
+      png_error(png_ptr, "invalid memory read");
+   }
+}
+
+int PNGAPI png_image_begin_read_from_memory(png_imagep image,
+   png_const_voidp memory, png_size_t size)
+{
+   if (image != NULL && image->version == PNG_IMAGE_VERSION)
+   {
+      if (memory != NULL && size > 0)
+      {
+         if (png_image_read_init(image) != 0)
+         {
+            /* Now set the IO functions to read from the memory buffer and
+             * store it into io_ptr.  Again do this in-place to avoid calling a
+             * libpng function that requires error handling.
+             */
+            image->opaque->memory = png_voidcast(png_const_bytep, memory);
+            image->opaque->size = size;
+            image->opaque->png_ptr->io_ptr = image;
+            image->opaque->png_ptr->read_data_fn = png_image_memory_read;
+
+            return png_safe_execute(image, png_image_read_header, image);
+         }
+      }
+
+      else
+         return png_image_error(image,
+            "png_image_begin_read_from_memory: invalid argument");
+   }
+
+   else if (image != NULL)
+      return png_image_error(image,
+         "png_image_begin_read_from_memory: incorrect PNG_IMAGE_VERSION");
+
+   return 0;
+}
+
+/* Utility function to skip chunks that are not used by the simplified image
+ * read functions and an appropriate macro to call it.
+ */
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+static void
+png_image_skip_unused_chunks(png_structrp png_ptr)
+{
+   /* Prepare the reader to ignore all recognized chunks whose data will not
+    * be used, i.e., all chunks recognized by libpng except for those
+    * involved in basic image reading:
+    *
+    *    IHDR, PLTE, IDAT, IEND
+    *
+    * Or image data handling:
+    *
+    *    tRNS, bKGD, gAMA, cHRM, sRGB, [iCCP] and sBIT.
+    *
+    * This provides a small performance improvement and eliminates any
+    * potential vulnerability to security problems in the unused chunks.
+    *
+    * At present the iCCP chunk data isn't used, so iCCP chunk can be ignored
+    * too.  This allows the simplified API to be compiled without iCCP support,
+    * however if the support is there the chunk is still checked to detect
+    * errors (which are unfortunately quite common.)
+    */
+   {
+         static PNG_CONST png_byte chunks_to_process[] = {
+            98,  75,  71,  68, '\0',  /* bKGD */
+            99,  72,  82,  77, '\0',  /* cHRM */
+           103,  65,  77,  65, '\0',  /* gAMA */
+#        ifdef PNG_READ_iCCP_SUPPORTED
+           105,  67,  67,  80, '\0',  /* iCCP */
+#        endif
+           115,  66,  73,  84, '\0',  /* sBIT */
+           115,  82,  71,  66, '\0',  /* sRGB */
+           };
+
+       /* Ignore unknown chunks and all other chunks except for the
+        * IHDR, PLTE, tRNS, IDAT, and IEND chunks.
+        */
+       png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_NEVER,
+         NULL, -1);
+
+       /* But do not ignore image data handling chunks */
+       png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_AS_DEFAULT,
+         chunks_to_process, (int)/*SAFE*/(sizeof chunks_to_process)/5);
+    }
+}
+
+#  define PNG_SKIP_CHUNKS(p) png_image_skip_unused_chunks(p)
+#else
+#  define PNG_SKIP_CHUNKS(p) ((void)0)
+#endif /* HANDLE_AS_UNKNOWN */
+
+/* The following macro gives the exact rounded answer for all values in the
+ * range 0..255 (it actually divides by 51.2, but the rounding still generates
+ * the correct numbers 0..5
+ */
+#define PNG_DIV51(v8) (((v8) * 5 + 130) >> 8)
+
+/* Utility functions to make particular color-maps */
+static void
+set_file_encoding(png_image_read_control *display)
+{
+   png_fixed_point g = display->image->opaque->png_ptr->colorspace.gamma;
+   if (png_gamma_significant(g) != 0)
+   {
+      if (png_gamma_not_sRGB(g) != 0)
+      {
+         display->file_encoding = P_FILE;
+         display->gamma_to_linear = png_reciprocal(g);
+      }
+
+      else
+         display->file_encoding = P_sRGB;
+   }
+
+   else
+      display->file_encoding = P_LINEAR8;
+}
+
+static unsigned int
+decode_gamma(png_image_read_control *display, png_uint_32 value, int encoding)
+{
+   if (encoding == P_FILE) /* double check */
+      encoding = display->file_encoding;
+
+   if (encoding == P_NOTSET) /* must be the file encoding */
+   {
+      set_file_encoding(display);
+      encoding = display->file_encoding;
+   }
+
+   switch (encoding)
+   {
+      case P_FILE:
+         value = png_gamma_16bit_correct(value*257, display->gamma_to_linear);
+         break;
+
+      case P_sRGB:
+         value = png_sRGB_table[value];
+         break;
+
+      case P_LINEAR:
+         break;
+
+      case P_LINEAR8:
+         value *= 257;
+         break;
+
+      default:
+         png_error(display->image->opaque->png_ptr,
+            "unexpected encoding (internal error)");
+         break;
+   }
+
+   return value;
+}
+
+static png_uint_32
+png_colormap_compose(png_image_read_control *display,
+   png_uint_32 foreground, int foreground_encoding, png_uint_32 alpha,
+   png_uint_32 background, int encoding)
+{
+   /* The file value is composed on the background, the background has the given
+    * encoding and so does the result, the file is encoded with P_FILE and the
+    * file and alpha are 8-bit values.  The (output) encoding will always be
+    * P_LINEAR or P_sRGB.
+    */
+   png_uint_32 f = decode_gamma(display, foreground, foreground_encoding);
+   png_uint_32 b = decode_gamma(display, background, encoding);
+
+   /* The alpha is always an 8-bit value (it comes from the palette), the value
+    * scaled by 255 is what PNG_sRGB_FROM_LINEAR requires.
+    */
+   f = f * alpha + b * (255-alpha);
+
+   if (encoding == P_LINEAR)
+   {
+      /* Scale to 65535; divide by 255, approximately (in fact this is extremely
+       * accurate, it divides by 255.00000005937181414556, with no overflow.)
+       */
+      f *= 257; /* Now scaled by 65535 */
+      f += f >> 16;
+      f = (f+32768) >> 16;
+   }
+
+   else /* P_sRGB */
+      f = PNG_sRGB_FROM_LINEAR(f);
+
+   return f;
+}
+
+/* NOTE: P_LINEAR values to this routine must be 16-bit, but P_FILE values must
+ * be 8-bit.
+ */
+static void
+png_create_colormap_entry(png_image_read_control *display,
+   png_uint_32 ip, png_uint_32 red, png_uint_32 green, png_uint_32 blue,
+   png_uint_32 alpha, int encoding)
+{
+   png_imagep image = display->image;
+   const int output_encoding = (image->format & PNG_FORMAT_FLAG_LINEAR) != 0 ?
+      P_LINEAR : P_sRGB;
+   const int convert_to_Y = (image->format & PNG_FORMAT_FLAG_COLOR) == 0 &&
+      (red != green || green != blue);
+
+   if (ip > 255)
+      png_error(image->opaque->png_ptr, "color-map index out of range");
+
+   /* Update the cache with whether the file gamma is significantly different
+    * from sRGB.
+    */
+   if (encoding == P_FILE)
+   {
+      if (display->file_encoding == P_NOTSET)
+         set_file_encoding(display);
+
+      /* Note that the cached value may be P_FILE too, but if it is then the
+       * gamma_to_linear member has been set.
+       */
+      encoding = display->file_encoding;
+   }
+
+   if (encoding == P_FILE)
+   {
+      png_fixed_point g = display->gamma_to_linear;
+
+      red = png_gamma_16bit_correct(red*257, g);
+      green = png_gamma_16bit_correct(green*257, g);
+      blue = png_gamma_16bit_correct(blue*257, g);
+
+      if (convert_to_Y != 0 || output_encoding == P_LINEAR)
+      {
+         alpha *= 257;
+         encoding = P_LINEAR;
+      }
+
+      else
+      {
+         red = PNG_sRGB_FROM_LINEAR(red * 255);
+         green = PNG_sRGB_FROM_LINEAR(green * 255);
+         blue = PNG_sRGB_FROM_LINEAR(blue * 255);
+         encoding = P_sRGB;
+      }
+   }
+
+   else if (encoding == P_LINEAR8)
+   {
+      /* This encoding occurs quite frequently in test cases because PngSuite
+       * includes a gAMA 1.0 chunk with most images.
+       */
+      red *= 257;
+      green *= 257;
+      blue *= 257;
+      alpha *= 257;
+      encoding = P_LINEAR;
+   }
+
+   else if (encoding == P_sRGB &&
+       (convert_to_Y  != 0 || output_encoding == P_LINEAR))
+   {
+      /* The values are 8-bit sRGB values, but must be converted to 16-bit
+       * linear.
+       */
+      red = png_sRGB_table[red];
+      green = png_sRGB_table[green];
+      blue = png_sRGB_table[blue];
+      alpha *= 257;
+      encoding = P_LINEAR;
+   }
+
+   /* This is set if the color isn't gray but the output is. */
+   if (encoding == P_LINEAR)
+   {
+      if (convert_to_Y != 0)
+      {
+         /* NOTE: these values are copied from png_do_rgb_to_gray */
+         png_uint_32 y = (png_uint_32)6968 * red  + (png_uint_32)23434 * green +
+            (png_uint_32)2366 * blue;
+
+         if (output_encoding == P_LINEAR)
+            y = (y + 16384) >> 15;
+
+         else
+         {
+            /* y is scaled by 32768, we need it scaled by 255: */
+            y = (y + 128) >> 8;
+            y *= 255;
+            y = PNG_sRGB_FROM_LINEAR((y + 64) >> 7);
+            encoding = P_sRGB;
+         }
+
+         blue = red = green = y;
+      }
+
+      else if (output_encoding == P_sRGB)
+      {
+         red = PNG_sRGB_FROM_LINEAR(red * 255);
+         green = PNG_sRGB_FROM_LINEAR(green * 255);
+         blue = PNG_sRGB_FROM_LINEAR(blue * 255);
+         alpha = PNG_DIV257(alpha);
+         encoding = P_sRGB;
+      }
+   }
+
+   if (encoding != output_encoding)
+      png_error(image->opaque->png_ptr, "bad encoding (internal error)");
+
+   /* Store the value. */
+   {
+#     ifdef PNG_FORMAT_AFIRST_SUPPORTED
+         const int afirst = (image->format & PNG_FORMAT_FLAG_AFIRST) != 0 &&
+            (image->format & PNG_FORMAT_FLAG_ALPHA) != 0;
+#     else
+#        define afirst 0
+#     endif
+#     ifdef PNG_FORMAT_BGR_SUPPORTED
+         const int bgr = (image->format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0;
+#     else
+#        define bgr 0
+#     endif
+
+      if (output_encoding == P_LINEAR)
+      {
+         png_uint_16p entry = png_voidcast(png_uint_16p, display->colormap);
+
+         entry += ip * PNG_IMAGE_SAMPLE_CHANNELS(image->format);
+
+         /* The linear 16-bit values must be pre-multiplied by the alpha channel
+          * value, if less than 65535 (this is, effectively, composite on black
+          * if the alpha channel is removed.)
+          */
+         switch (PNG_IMAGE_SAMPLE_CHANNELS(image->format))
+         {
+            case 4:
+               entry[afirst ? 0 : 3] = (png_uint_16)alpha;
+               /* FALL THROUGH */
+
+            case 3:
+               if (alpha < 65535)
+               {
+                  if (alpha > 0)
+                  {
+                     blue = (blue * alpha + 32767U)/65535U;
+                     green = (green * alpha + 32767U)/65535U;
+                     red = (red * alpha + 32767U)/65535U;
+                  }
+
+                  else
+                     red = green = blue = 0;
+               }
+               entry[afirst + (2 ^ bgr)] = (png_uint_16)blue;
+               entry[afirst + 1] = (png_uint_16)green;
+               entry[afirst + bgr] = (png_uint_16)red;
+               break;
+
+            case 2:
+               entry[1 ^ afirst] = (png_uint_16)alpha;
+               /* FALL THROUGH */
+
+            case 1:
+               if (alpha < 65535)
+               {
+                  if (alpha > 0)
+                     green = (green * alpha + 32767U)/65535U;
+
+                  else
+                     green = 0;
+               }
+               entry[afirst] = (png_uint_16)green;
+               break;
+
+            default:
+               break;
+         }
+      }
+
+      else /* output encoding is P_sRGB */
+      {
+         png_bytep entry = png_voidcast(png_bytep, display->colormap);
+
+         entry += ip * PNG_IMAGE_SAMPLE_CHANNELS(image->format);
+
+         switch (PNG_IMAGE_SAMPLE_CHANNELS(image->format))
+         {
+            case 4:
+               entry[afirst ? 0 : 3] = (png_byte)alpha;
+            case 3:
+               entry[afirst + (2 ^ bgr)] = (png_byte)blue;
+               entry[afirst + 1] = (png_byte)green;
+               entry[afirst + bgr] = (png_byte)red;
+               break;
+
+            case 2:
+               entry[1 ^ afirst] = (png_byte)alpha;
+            case 1:
+               entry[afirst] = (png_byte)green;
+               break;
+
+            default:
+               break;
+         }
+      }
+
+#     ifdef afirst
+#        undef afirst
+#     endif
+#     ifdef bgr
+#        undef bgr
+#     endif
+   }
+}
+
+static int
+make_gray_file_colormap(png_image_read_control *display)
+{
+   unsigned int i;
+
+   for (i=0; i<256; ++i)
+      png_create_colormap_entry(display, i, i, i, i, 255, P_FILE);
+
+   return i;
+}
+
+static int
+make_gray_colormap(png_image_read_control *display)
+{
+   unsigned int i;
+
+   for (i=0; i<256; ++i)
+      png_create_colormap_entry(display, i, i, i, i, 255, P_sRGB);
+
+   return i;
+}
+#define PNG_GRAY_COLORMAP_ENTRIES 256
+
+static int
+make_ga_colormap(png_image_read_control *display)
+{
+   unsigned int i, a;
+
+   /* Alpha is retained, the output will be a color-map with entries
+    * selected by six levels of alpha.  One transparent entry, 6 gray
+    * levels for all the intermediate alpha values, leaving 230 entries
+    * for the opaque grays.  The color-map entries are the six values
+    * [0..5]*51, the GA processing uses PNG_DIV51(value) to find the
+    * relevant entry.
+    *
+    * if (alpha > 229) // opaque
+    * {
+    *    // The 231 entries are selected to make the math below work:
+    *    base = 0;
+    *    entry = (231 * gray + 128) >> 8;
+    * }
+    * else if (alpha < 26) // transparent
+    * {
+    *    base = 231;
+    *    entry = 0;
+    * }
+    * else // partially opaque
+    * {
+    *    base = 226 + 6 * PNG_DIV51(alpha);
+    *    entry = PNG_DIV51(gray);
+    * }
+    */
+   i = 0;
+   while (i < 231)
+   {
+      unsigned int gray = (i * 256 + 115) / 231;
+      png_create_colormap_entry(display, i++, gray, gray, gray, 255, P_sRGB);
+   }
+
+   /* 255 is used here for the component values for consistency with the code
+    * that undoes premultiplication in pngwrite.c.
+    */
+   png_create_colormap_entry(display, i++, 255, 255, 255, 0, P_sRGB);
+
+   for (a=1; a<5; ++a)
+   {
+      unsigned int g;
+
+      for (g=0; g<6; ++g)
+         png_create_colormap_entry(display, i++, g*51, g*51, g*51, a*51,
+            P_sRGB);
+   }
+
+   return i;
+}
+
+#define PNG_GA_COLORMAP_ENTRIES 256
+
+static int
+make_rgb_colormap(png_image_read_control *display)
+{
+   unsigned int i, r;
+
+   /* Build a 6x6x6 opaque RGB cube */
+   for (i=r=0; r<6; ++r)
+   {
+      unsigned int g;
+
+      for (g=0; g<6; ++g)
+      {
+         unsigned int b;
+
+         for (b=0; b<6; ++b)
+            png_create_colormap_entry(display, i++, r*51, g*51, b*51, 255,
+               P_sRGB);
+      }
+   }
+
+   return i;
+}
+
+#define PNG_RGB_COLORMAP_ENTRIES 216
+
+/* Return a palette index to the above palette given three 8-bit sRGB values. */
+#define PNG_RGB_INDEX(r,g,b) \
+   ((png_byte)(6 * (6 * PNG_DIV51(r) + PNG_DIV51(g)) + PNG_DIV51(b)))
+
+static int
+png_image_read_colormap(png_voidp argument)
+{
+   png_image_read_control *display =
+      png_voidcast(png_image_read_control*, argument);
+   const png_imagep image = display->image;
+
+   const png_structrp png_ptr = image->opaque->png_ptr;
+   const png_uint_32 output_format = image->format;
+   const int output_encoding = (output_format & PNG_FORMAT_FLAG_LINEAR) != 0 ?
+      P_LINEAR : P_sRGB;
+
+   unsigned int cmap_entries;
+   unsigned int output_processing;        /* Output processing option */
+   unsigned int data_encoding = P_NOTSET; /* Encoding libpng must produce */
+
+   /* Background information; the background color and the index of this color
+    * in the color-map if it exists (else 256).
+    */
+   unsigned int background_index = 256;
+   png_uint_32 back_r, back_g, back_b;
+
+   /* Flags to accumulate things that need to be done to the input. */
+   int expand_tRNS = 0;
+
+   /* Exclude the NYI feature of compositing onto a color-mapped buffer; it is
+    * very difficult to do, the results look awful, and it is difficult to see
+    * what possible use it is because the application can't control the
+    * color-map.
+    */
+   if (((png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0 ||
+         png_ptr->num_trans > 0) /* alpha in input */ &&
+      ((output_format & PNG_FORMAT_FLAG_ALPHA) == 0) /* no alpha in output */)
+   {
+      if (output_encoding == P_LINEAR) /* compose on black */
+         back_b = back_g = back_r = 0;
+
+      else if (display->background == NULL /* no way to remove it */)
+         png_error(png_ptr,
+            "a background color must be supplied to remove alpha/transparency");
+
+      /* Get a copy of the background color (this avoids repeating the checks
+       * below.)  The encoding is 8-bit sRGB or 16-bit linear, depending on the
+       * output format.
+       */
+      else
+      {
+         back_g = display->background->green;
+         if ((output_format & PNG_FORMAT_FLAG_COLOR) != 0)
+         {
+            back_r = display->background->red;
+            back_b = display->background->blue;
+         }
+         else
+            back_b = back_r = back_g;
+      }
+   }
+
+   else if (output_encoding == P_LINEAR)
+      back_b = back_r = back_g = 65535;
+
+   else
+      back_b = back_r = back_g = 255;
+
+   /* Default the input file gamma if required - this is necessary because
+    * libpng assumes that if no gamma information is present the data is in the
+    * output format, but the simplified API deduces the gamma from the input
+    * format.
+    */
+   if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) == 0)
+   {
+      /* Do this directly, not using the png_colorspace functions, to ensure
+       * that it happens even if the colorspace is invalid (though probably if
+       * it is the setting will be ignored)  Note that the same thing can be
+       * achieved at the application interface with png_set_gAMA.
+       */
+      if (png_ptr->bit_depth == 16 &&
+         (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0)
+         png_ptr->colorspace.gamma = PNG_GAMMA_LINEAR;
+
+      else
+         png_ptr->colorspace.gamma = PNG_GAMMA_sRGB_INVERSE;
+
+      png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;
+   }
+
+   /* Decide what to do based on the PNG color type of the input data.  The
+    * utility function png_create_colormap_entry deals with most aspects of the
+    * output transformations; this code works out how to produce bytes of
+    * color-map entries from the original format.
+    */
+   switch (png_ptr->color_type)
+   {
+      case PNG_COLOR_TYPE_GRAY:
+         if (png_ptr->bit_depth <= 8)
+         {
+            /* There at most 256 colors in the output, regardless of
+             * transparency.
+             */
+            unsigned int step, i, val, trans = 256/*ignore*/, back_alpha = 0;
+
+            cmap_entries = 1U << png_ptr->bit_depth;
+            if (cmap_entries > image->colormap_entries)
+               png_error(png_ptr, "gray[8] color-map: too few entries");
+
+            step = 255 / (cmap_entries - 1);
+            output_processing = PNG_CMAP_NONE;
+
+            /* If there is a tRNS chunk then this either selects a transparent
+             * value or, if the output has no alpha, the background color.
+             */
+            if (png_ptr->num_trans > 0)
+            {
+               trans = png_ptr->trans_color.gray;
+
+               if ((output_format & PNG_FORMAT_FLAG_ALPHA) == 0)
+                  back_alpha = output_encoding == P_LINEAR ? 65535 : 255;
+            }
+
+            /* png_create_colormap_entry just takes an RGBA and writes the
+             * corresponding color-map entry using the format from 'image',
+             * including the required conversion to sRGB or linear as
+             * appropriate.  The input values are always either sRGB (if the
+             * gamma correction flag is 0) or 0..255 scaled file encoded values
+             * (if the function must gamma correct them).
+             */
+            for (i=val=0; i<cmap_entries; ++i, val += step)
+            {
+               /* 'i' is a file value.  While this will result in duplicated
+                * entries for 8-bit non-sRGB encoded files it is necessary to
+                * have non-gamma corrected values to do tRNS handling.
+                */
+               if (i != trans)
+                  png_create_colormap_entry(display, i, val, val, val, 255,
+                     P_FILE/*8-bit with file gamma*/);
+
+               /* Else this entry is transparent.  The colors don't matter if
+                * there is an alpha channel (back_alpha == 0), but it does no
+                * harm to pass them in; the values are not set above so this
+                * passes in white.
+                *
+                * NOTE: this preserves the full precision of the application
+                * supplied background color when it is used.
+                */
+               else
+                  png_create_colormap_entry(display, i, back_r, back_g, back_b,
+                     back_alpha, output_encoding);
+            }
+
+            /* We need libpng to preserve the original encoding. */
+            data_encoding = P_FILE;
+
+            /* The rows from libpng, while technically gray values, are now also
+             * color-map indices; however, they may need to be expanded to 1
+             * byte per pixel.  This is what png_set_packing does (i.e., it
+             * unpacks the bit values into bytes.)
+             */
+            if (png_ptr->bit_depth < 8)
+               png_set_packing(png_ptr);
+         }
+
+         else /* bit depth is 16 */
+         {
+            /* The 16-bit input values can be converted directly to 8-bit gamma
+             * encoded values; however, if a tRNS chunk is present 257 color-map
+             * entries are required.  This means that the extra entry requires
+             * special processing; add an alpha channel, sacrifice gray level
+             * 254 and convert transparent (alpha==0) entries to that.
+             *
+             * Use libpng to chop the data to 8 bits.  Convert it to sRGB at the
+             * same time to minimize quality loss.  If a tRNS chunk is present
+             * this means libpng must handle it too; otherwise it is impossible
+             * to do the exact match on the 16-bit value.
+             *
+             * If the output has no alpha channel *and* the background color is
+             * gray then it is possible to let libpng handle the substitution by
+             * ensuring that the corresponding gray level matches the background
+             * color exactly.
+             */
+            data_encoding = P_sRGB;
+
+            if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries)
+               png_error(png_ptr, "gray[16] color-map: too few entries");
+
+            cmap_entries = make_gray_colormap(display);
+
+            if (png_ptr->num_trans > 0)
+            {
+               unsigned int back_alpha;
+
+               if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0)
+                  back_alpha = 0;
+
+               else
+               {
+                  if (back_r == back_g && back_g == back_b)
+                  {
+                     /* Background is gray; no special processing will be
+                      * required.
+                      */
+                     png_color_16 c;
+                     png_uint_32 gray = back_g;
+
+                     if (output_encoding == P_LINEAR)
+                     {
+                        gray = PNG_sRGB_FROM_LINEAR(gray * 255);
+
+                        /* And make sure the corresponding palette entry
+                         * matches.
+                         */
+                        png_create_colormap_entry(display, gray, back_g, back_g,
+                           back_g, 65535, P_LINEAR);
+                     }
+
+                     /* The background passed to libpng, however, must be the
+                      * sRGB value.
+                      */
+                     c.index = 0; /*unused*/
+                     c.gray = c.red = c.green = c.blue = (png_uint_16)gray;
+
+                     /* NOTE: does this work without expanding tRNS to alpha?
+                      * It should be the color->gray case below apparently
+                      * doesn't.
+                      */
+                     png_set_background_fixed(png_ptr, &c,
+                        PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
+                        0/*gamma: not used*/);
+
+                     output_processing = PNG_CMAP_NONE;
+                     break;
+                  }
+
+                  back_alpha = output_encoding == P_LINEAR ? 65535 : 255;
+               }
+
+               /* output_processing means that the libpng-processed row will be
+                * 8-bit GA and it has to be processing to single byte color-map
+                * values.  Entry 254 is replaced by either a completely
+                * transparent entry or by the background color at full
+                * precision (and the background color is not a simple gray
+                * level in this case.)
+                */
+               expand_tRNS = 1;
+               output_processing = PNG_CMAP_TRANS;
+               background_index = 254;
+
+               /* And set (overwrite) color-map entry 254 to the actual
+                * background color at full precision.
+                */
+               png_create_colormap_entry(display, 254, back_r, back_g, back_b,
+                  back_alpha, output_encoding);
+            }
+
+            else
+               output_processing = PNG_CMAP_NONE;
+         }
+         break;
+
+      case PNG_COLOR_TYPE_GRAY_ALPHA:
+         /* 8-bit or 16-bit PNG with two channels - gray and alpha.  A minimum
+          * of 65536 combinations.  If, however, the alpha channel is to be
+          * removed there are only 256 possibilities if the background is gray.
+          * (Otherwise there is a subset of the 65536 possibilities defined by
+          * the triangle between black, white and the background color.)
+          *
+          * Reduce 16-bit files to 8-bit and sRGB encode the result.  No need to
+          * worry about tRNS matching - tRNS is ignored if there is an alpha
+          * channel.
+          */
+         data_encoding = P_sRGB;
+
+         if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0)
+         {
+            if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries)
+               png_error(png_ptr, "gray+alpha color-map: too few entries");
+
+            cmap_entries = make_ga_colormap(display);
+
+            background_index = PNG_CMAP_GA_BACKGROUND;
+            output_processing = PNG_CMAP_GA;
+         }
+
+         else /* alpha is removed */
+         {
+            /* Alpha must be removed as the PNG data is processed when the
+             * background is a color because the G and A channels are
+             * independent and the vector addition (non-parallel vectors) is a
+             * 2-D problem.
+             *
+             * This can be reduced to the same algorithm as above by making a
+             * colormap containing gray levels (for the opaque grays), a
+             * background entry (for a transparent pixel) and a set of four six
+             * level color values, one set for each intermediate alpha value.
+             * See the comments in make_ga_colormap for how this works in the
+             * per-pixel processing.
+             *
+             * If the background is gray, however, we only need a 256 entry gray
+             * level color map.  It is sufficient to make the entry generated
+             * for the background color be exactly the color specified.
+             */
+            if ((output_format & PNG_FORMAT_FLAG_COLOR) == 0 ||
+               (back_r == back_g && back_g == back_b))
+            {
+               /* Background is gray; no special processing will be required. */
+               png_color_16 c;
+               png_uint_32 gray = back_g;
+
+               if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries)
+                  png_error(png_ptr, "gray-alpha color-map: too few entries");
+
+               cmap_entries = make_gray_colormap(display);
+
+               if (output_encoding == P_LINEAR)
+               {
+                  gray = PNG_sRGB_FROM_LINEAR(gray * 255);
+
+                  /* And make sure the corresponding palette entry matches. */
+                  png_create_colormap_entry(display, gray, back_g, back_g,
+                     back_g, 65535, P_LINEAR);
+               }
+
+               /* The background passed to libpng, however, must be the sRGB
+                * value.
+                */
+               c.index = 0; /*unused*/
+               c.gray = c.red = c.green = c.blue = (png_uint_16)gray;
+
+               png_set_background_fixed(png_ptr, &c,
+                  PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
+                  0/*gamma: not used*/);
+
+               output_processing = PNG_CMAP_NONE;
+            }
+
+            else
+            {
+               png_uint_32 i, a;
+
+               /* This is the same as png_make_ga_colormap, above, except that
+                * the entries are all opaque.
+                */
+               if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries)
+                  png_error(png_ptr, "ga-alpha color-map: too few entries");
+
+               i = 0;
+               while (i < 231)
+               {
+                  png_uint_32 gray = (i * 256 + 115) / 231;
+                  png_create_colormap_entry(display, i++, gray, gray, gray,
+                     255, P_sRGB);
+               }
+
+               /* NOTE: this preserves the full precision of the application
+                * background color.
+                */
+               background_index = i;
+               png_create_colormap_entry(display, i++, back_r, back_g, back_b,
+                  output_encoding == P_LINEAR ? 65535U : 255U, output_encoding);
+
+               /* For non-opaque input composite on the sRGB background - this
+                * requires inverting the encoding for each component.  The input
+                * is still converted to the sRGB encoding because this is a
+                * reasonable approximate to the logarithmic curve of human
+                * visual sensitivity, at least over the narrow range which PNG
+                * represents.  Consequently 'G' is always sRGB encoded, while
+                * 'A' is linear.  We need the linear background colors.
+                */
+               if (output_encoding == P_sRGB) /* else already linear */
+               {
+                  /* This may produce a value not exactly matching the
+                   * background, but that's ok because these numbers are only
+                   * used when alpha != 0
+                   */
+                  back_r = png_sRGB_table[back_r];
+                  back_g = png_sRGB_table[back_g];
+                  back_b = png_sRGB_table[back_b];
+               }
+
+               for (a=1; a<5; ++a)
+               {
+                  unsigned int g;
+
+                  /* PNG_sRGB_FROM_LINEAR expects a 16-bit linear value scaled
+                   * by an 8-bit alpha value (0..255).
+                   */
+                  png_uint_32 alpha = 51 * a;
+                  png_uint_32 back_rx = (255-alpha) * back_r;
+                  png_uint_32 back_gx = (255-alpha) * back_g;
+                  png_uint_32 back_bx = (255-alpha) * back_b;
+
+                  for (g=0; g<6; ++g)
+                  {
+                     png_uint_32 gray = png_sRGB_table[g*51] * alpha;
+
+                     png_create_colormap_entry(display, i++,
+                        PNG_sRGB_FROM_LINEAR(gray + back_rx),
+                        PNG_sRGB_FROM_LINEAR(gray + back_gx),
+                        PNG_sRGB_FROM_LINEAR(gray + back_bx), 255, P_sRGB);
+                  }
+               }
+
+               cmap_entries = i;
+               output_processing = PNG_CMAP_GA;
+            }
+         }
+         break;
+
+      case PNG_COLOR_TYPE_RGB:
+      case PNG_COLOR_TYPE_RGB_ALPHA:
+         /* Exclude the case where the output is gray; we can always handle this
+          * with the cases above.
+          */
+         if ((output_format & PNG_FORMAT_FLAG_COLOR) == 0)
+         {
+            /* The color-map will be grayscale, so we may as well convert the
+             * input RGB values to a simple grayscale and use the grayscale
+             * code above.
+             *
+             * NOTE: calling this apparently damages the recognition of the
+             * transparent color in background color handling; call
+             * png_set_tRNS_to_alpha before png_set_background_fixed.
+             */
+            png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE, -1,
+               -1);
+            data_encoding = P_sRGB;
+
+            /* The output will now be one or two 8-bit gray or gray+alpha
+             * channels.  The more complex case arises when the input has alpha.
+             */
+            if ((png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
+               png_ptr->num_trans > 0) &&
+               (output_format & PNG_FORMAT_FLAG_ALPHA) != 0)
+            {
+               /* Both input and output have an alpha channel, so no background
+                * processing is required; just map the GA bytes to the right
+                * color-map entry.
+                */
+               expand_tRNS = 1;
+
+               if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries)
+                  png_error(png_ptr, "rgb[ga] color-map: too few entries");
+
+               cmap_entries = make_ga_colormap(display);
+               background_index = PNG_CMAP_GA_BACKGROUND;
+               output_processing = PNG_CMAP_GA;
+            }
+
+            else
+            {
+               /* Either the input or the output has no alpha channel, so there
+                * will be no non-opaque pixels in the color-map; it will just be
+                * grayscale.
+                */
+               if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries)
+                  png_error(png_ptr, "rgb[gray] color-map: too few entries");
+
+               /* Ideally this code would use libpng to do the gamma correction,
+                * but if an input alpha channel is to be removed we will hit the
+                * libpng bug in gamma+compose+rgb-to-gray (the double gamma
+                * correction bug).  Fix this by dropping the gamma correction in
+                * this case and doing it in the palette; this will result in
+                * duplicate palette entries, but that's better than the
+                * alternative of double gamma correction.
+                */
+               if ((png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
+                  png_ptr->num_trans > 0) &&
+                  png_gamma_not_sRGB(png_ptr->colorspace.gamma) != 0)
+               {
+                  cmap_entries = make_gray_file_colormap(display);
+                  data_encoding = P_FILE;
+               }
+
+               else
+                  cmap_entries = make_gray_colormap(display);
+
+               /* But if the input has alpha or transparency it must be removed
+                */
+               if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
+                  png_ptr->num_trans > 0)
+               {
+                  png_color_16 c;
+                  png_uint_32 gray = back_g;
+
+                  /* We need to ensure that the application background exists in
+                   * the colormap and that completely transparent pixels map to
+                   * it.  Achieve this simply by ensuring that the entry
+                   * selected for the background really is the background color.
+                   */
+                  if (data_encoding == P_FILE) /* from the fixup above */
+                  {
+                     /* The app supplied a gray which is in output_encoding, we
+                      * need to convert it to a value of the input (P_FILE)
+                      * encoding then set this palette entry to the required
+                      * output encoding.
+                      */
+                     if (output_encoding == P_sRGB)
+                        gray = png_sRGB_table[gray]; /* now P_LINEAR */
+
+                     gray = PNG_DIV257(png_gamma_16bit_correct(gray,
+                        png_ptr->colorspace.gamma)); /* now P_FILE */
+
+                     /* And make sure the corresponding palette entry contains
+                      * exactly the required sRGB value.
+                      */
+                     png_create_colormap_entry(display, gray, back_g, back_g,
+                        back_g, 0/*unused*/, output_encoding);
+                  }
+
+                  else if (output_encoding == P_LINEAR)
+                  {
+                     gray = PNG_sRGB_FROM_LINEAR(gray * 255);
+
+                     /* And make sure the corresponding palette entry matches.
+                      */
+                     png_create_colormap_entry(display, gray, back_g, back_g,
+                        back_g, 0/*unused*/, P_LINEAR);
+                  }
+
+                  /* The background passed to libpng, however, must be the
+                   * output (normally sRGB) value.
+                   */
+                  c.index = 0; /*unused*/
+                  c.gray = c.red = c.green = c.blue = (png_uint_16)gray;
+
+                  /* NOTE: the following is apparently a bug in libpng. Without
+                   * it the transparent color recognition in
+                   * png_set_background_fixed seems to go wrong.
+                   */
+                  expand_tRNS = 1;
+                  png_set_background_fixed(png_ptr, &c,
+                     PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
+                     0/*gamma: not used*/);
+               }
+
+               output_processing = PNG_CMAP_NONE;
+            }
+         }
+
+         else /* output is color */
+         {
+            /* We could use png_quantize here so long as there is no transparent
+             * color or alpha; png_quantize ignores alpha.  Easier overall just
+             * to do it once and using PNG_DIV51 on the 6x6x6 reduced RGB cube.
+             * Consequently we always want libpng to produce sRGB data.
+             */
+            data_encoding = P_sRGB;
+
+            /* Is there any transparency or alpha? */
+            if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
+               png_ptr->num_trans > 0)
+            {
+               /* Is there alpha in the output too?  If so all four channels are
+                * processed into a special RGB cube with alpha support.
+                */
+               if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0)
+               {
+                  png_uint_32 r;
+
+                  if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries)
+                     png_error(png_ptr, "rgb+alpha color-map: too few entries");
+
+                  cmap_entries = make_rgb_colormap(display);
+
+                  /* Add a transparent entry. */
+                  png_create_colormap_entry(display, cmap_entries, 255, 255,
+                     255, 0, P_sRGB);
+
+                  /* This is stored as the background index for the processing
+                   * algorithm.
+                   */
+                  background_index = cmap_entries++;
+
+                  /* Add 27 r,g,b entries each with alpha 0.5. */
+                  for (r=0; r<256; r = (r << 1) | 0x7f)
+                  {
+                     png_uint_32 g;
+
+                     for (g=0; g<256; g = (g << 1) | 0x7f)
+                     {
+                        png_uint_32 b;
+
+                        /* This generates components with the values 0, 127 and
+                         * 255
+                         */
+                        for (b=0; b<256; b = (b << 1) | 0x7f)
+                           png_create_colormap_entry(display, cmap_entries++,
+                              r, g, b, 128, P_sRGB);
+                     }
+                  }
+
+                  expand_tRNS = 1;
+                  output_processing = PNG_CMAP_RGB_ALPHA;
+               }
+
+               else
+               {
+                  /* Alpha/transparency must be removed.  The background must
+                   * exist in the color map (achieved by setting adding it after
+                   * the 666 color-map).  If the standard processing code will
+                   * pick up this entry automatically that's all that is
+                   * required; libpng can be called to do the background
+                   * processing.
+                   */
+                  unsigned int sample_size =
+                     PNG_IMAGE_SAMPLE_SIZE(output_format);
+                  png_uint_32 r, g, b; /* sRGB background */
+
+                  if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries)
+                     png_error(png_ptr, "rgb-alpha color-map: too few entries");
+
+                  cmap_entries = make_rgb_colormap(display);
+
+                  png_create_colormap_entry(display, cmap_entries, back_r,
+                        back_g, back_b, 0/*unused*/, output_encoding);
+
+                  if (output_encoding == P_LINEAR)
+                  {
+                     r = PNG_sRGB_FROM_LINEAR(back_r * 255);
+                     g = PNG_sRGB_FROM_LINEAR(back_g * 255);
+                     b = PNG_sRGB_FROM_LINEAR(back_b * 255);
+                  }
+
+                  else
+                  {
+                     r = back_r;
+                     g = back_g;
+                     b = back_g;
+                  }
+
+                  /* Compare the newly-created color-map entry with the one the
+                   * PNG_CMAP_RGB algorithm will use.  If the two entries don't
+                   * match, add the new one and set this as the background
+                   * index.
+                   */
+                  if (memcmp((png_const_bytep)display->colormap +
+                        sample_size * cmap_entries,
+                     (png_const_bytep)display->colormap +
+                        sample_size * PNG_RGB_INDEX(r,g,b),
+                     sample_size) != 0)
+                  {
+                     /* The background color must be added. */
+                     background_index = cmap_entries++;
+
+                     /* Add 27 r,g,b entries each with created by composing with
+                      * the background at alpha 0.5.
+                      */
+                     for (r=0; r<256; r = (r << 1) | 0x7f)
+                     {
+                        for (g=0; g<256; g = (g << 1) | 0x7f)
+                        {
+                           /* This generates components with the values 0, 127
+                            * and 255
+                            */
+                           for (b=0; b<256; b = (b << 1) | 0x7f)
+                              png_create_colormap_entry(display, cmap_entries++,
+                                 png_colormap_compose(display, r, P_sRGB, 128,
+                                    back_r, output_encoding),
+                                 png_colormap_compose(display, g, P_sRGB, 128,
+                                    back_g, output_encoding),
+                                 png_colormap_compose(display, b, P_sRGB, 128,
+                                    back_b, output_encoding),
+                                 0/*unused*/, output_encoding);
+                        }
+                     }
+
+                     expand_tRNS = 1;
+                     output_processing = PNG_CMAP_RGB_ALPHA;
+                  }
+
+                  else /* background color is in the standard color-map */
+                  {
+                     png_color_16 c;
+
+                     c.index = 0; /*unused*/
+                     c.red = (png_uint_16)back_r;
+                     c.gray = c.green = (png_uint_16)back_g;
+                     c.blue = (png_uint_16)back_b;
+
+                     png_set_background_fixed(png_ptr, &c,
+                        PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
+                        0/*gamma: not used*/);
+
+                     output_processing = PNG_CMAP_RGB;
+                  }
+               }
+            }
+
+            else /* no alpha or transparency in the input */
+            {
+               /* Alpha in the output is irrelevant, simply map the opaque input
+                * pixels to the 6x6x6 color-map.
+                */
+               if (PNG_RGB_COLORMAP_ENTRIES > image->colormap_entries)
+                  png_error(png_ptr, "rgb color-map: too few entries");
+
+               cmap_entries = make_rgb_colormap(display);
+               output_processing = PNG_CMAP_RGB;
+            }
+         }
+         break;
+
+      case PNG_COLOR_TYPE_PALETTE:
+         /* It's already got a color-map.  It may be necessary to eliminate the
+          * tRNS entries though.
+          */
+         {
+            unsigned int num_trans = png_ptr->num_trans;
+            png_const_bytep trans = num_trans > 0 ? png_ptr->trans_alpha : NULL;
+            png_const_colorp colormap = png_ptr->palette;
+            const int do_background = trans != NULL &&
+               (output_format & PNG_FORMAT_FLAG_ALPHA) == 0;
+            unsigned int i;
+
+            /* Just in case: */
+            if (trans == NULL)
+               num_trans = 0;
+
+            output_processing = PNG_CMAP_NONE;
+            data_encoding = P_FILE; /* Don't change from color-map indices */
+            cmap_entries = png_ptr->num_palette;
+            if (cmap_entries > 256)
+               cmap_entries = 256;
+
+            if (cmap_entries > image->colormap_entries)
+               png_error(png_ptr, "palette color-map: too few entries");
+
+            for (i=0; i < cmap_entries; ++i)
+            {
+               if (do_background != 0 && i < num_trans && trans[i] < 255)
+               {
+                  if (trans[i] == 0)
+                     png_create_colormap_entry(display, i, back_r, back_g,
+                        back_b, 0, output_encoding);
+
+                  else
+                  {
+                     /* Must compose the PNG file color in the color-map entry
+                      * on the sRGB color in 'back'.
+                      */
+                     png_create_colormap_entry(display, i,
+                        png_colormap_compose(display, colormap[i].red, P_FILE,
+                           trans[i], back_r, output_encoding),
+                        png_colormap_compose(display, colormap[i].green, P_FILE,
+                           trans[i], back_g, output_encoding),
+                        png_colormap_compose(display, colormap[i].blue, P_FILE,
+                           trans[i], back_b, output_encoding),
+                        output_encoding == P_LINEAR ? trans[i] * 257U :
+                           trans[i],
+                        output_encoding);
+                  }
+               }
+
+               else
+                  png_create_colormap_entry(display, i, colormap[i].red,
+                     colormap[i].green, colormap[i].blue,
+                     i < num_trans ? trans[i] : 255U, P_FILE/*8-bit*/);
+            }
+
+            /* The PNG data may have indices packed in fewer than 8 bits, it
+             * must be expanded if so.
+             */
+            if (png_ptr->bit_depth < 8)
+               png_set_packing(png_ptr);
+         }
+         break;
+
+      default:
+         png_error(png_ptr, "invalid PNG color type");
+         /*NOT REACHED*/
+         break;
+   }
+
+   /* Now deal with the output processing */
+   if (expand_tRNS != 0 && png_ptr->num_trans > 0 &&
+       (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) == 0)
+      png_set_tRNS_to_alpha(png_ptr);
+
+   switch (data_encoding)
+   {
+      default:
+         png_error(png_ptr, "bad data option (internal error)");
+         break;
+
+      case P_sRGB:
+         /* Change to 8-bit sRGB */
+         png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, PNG_GAMMA_sRGB);
+         /* FALL THROUGH */
+
+      case P_FILE:
+         if (png_ptr->bit_depth > 8)
+            png_set_scale_16(png_ptr);
+         break;
+   }
+
+   if (cmap_entries > 256 || cmap_entries > image->colormap_entries)
+      png_error(png_ptr, "color map overflow (BAD internal error)");
+
+   image->colormap_entries = cmap_entries;
+
+   /* Double check using the recorded background index */
+   switch (output_processing)
+   {
+      case PNG_CMAP_NONE:
+         if (background_index != PNG_CMAP_NONE_BACKGROUND)
+            goto bad_background;
+         break;
+
+      case PNG_CMAP_GA:
+         if (background_index != PNG_CMAP_GA_BACKGROUND)
+            goto bad_background;
+         break;
+
+      case PNG_CMAP_TRANS:
+         if (background_index >= cmap_entries ||
+            background_index != PNG_CMAP_TRANS_BACKGROUND)
+            goto bad_background;
+         break;
+
+      case PNG_CMAP_RGB:
+         if (background_index != PNG_CMAP_RGB_BACKGROUND)
+            goto bad_background;
+         break;
+
+      case PNG_CMAP_RGB_ALPHA:
+         if (background_index != PNG_CMAP_RGB_ALPHA_BACKGROUND)
+            goto bad_background;
+         break;
+
+      default:
+         png_error(png_ptr, "bad processing option (internal error)");
+
+      bad_background:
+         png_error(png_ptr, "bad background index (internal error)");
+   }
+
+   display->colormap_processing = output_processing;
+
+   return 1/*ok*/;
+}
+
+/* The final part of the color-map read called from png_image_finish_read. */
+static int
+png_image_read_and_map(png_voidp argument)
+{
+   png_image_read_control *display = png_voidcast(png_image_read_control*,
+      argument);
+   png_imagep image = display->image;
+   png_structrp png_ptr = image->opaque->png_ptr;
+   int passes;
+
+   /* Called when the libpng data must be transformed into the color-mapped
+    * form.  There is a local row buffer in display->local and this routine must
+    * do the interlace handling.
+    */
+   switch (png_ptr->interlaced)
+   {
+      case PNG_INTERLACE_NONE:
+         passes = 1;
+         break;
+
+      case PNG_INTERLACE_ADAM7:
+         passes = PNG_INTERLACE_ADAM7_PASSES;
+         break;
+
+      default:
+         png_error(png_ptr, "unknown interlace type");
+   }
+
+   {
+      png_uint_32  height = image->height;
+      png_uint_32  width = image->width;
+      int          proc = display->colormap_processing;
+      png_bytep    first_row = png_voidcast(png_bytep, display->first_row);
+      ptrdiff_t    step_row = display->row_bytes;
+      int pass;
+
+      for (pass = 0; pass < passes; ++pass)
+      {
+         unsigned int     startx, stepx, stepy;
+         png_uint_32      y;
+
+         if (png_ptr->interlaced == PNG_INTERLACE_ADAM7)
+         {
+            /* The row may be empty for a short image: */
+            if (PNG_PASS_COLS(width, pass) == 0)
+               continue;
+
+            startx = PNG_PASS_START_COL(pass);
+            stepx = PNG_PASS_COL_OFFSET(pass);
+            y = PNG_PASS_START_ROW(pass);
+            stepy = PNG_PASS_ROW_OFFSET(pass);
+         }
+
+         else
+         {
+            y = 0;
+            startx = 0;
+            stepx = stepy = 1;
+         }
+
+         for (; y<height; y += stepy)
+         {
+            png_bytep inrow = png_voidcast(png_bytep, display->local_row);
+            png_bytep outrow = first_row + y * step_row;
+            png_const_bytep end_row = outrow + width;
+
+            /* Read read the libpng data into the temporary buffer. */
+            png_read_row(png_ptr, inrow, NULL);
+
+            /* Now process the row according to the processing option, note
+             * that the caller verifies that the format of the libpng output
+             * data is as required.
+             */
+            outrow += startx;
+            switch (proc)
+            {
+               case PNG_CMAP_GA:
+                  for (; outrow < end_row; outrow += stepx)
+                  {
+                     /* The data is always in the PNG order */
+                     unsigned int gray = *inrow++;
+                     unsigned int alpha = *inrow++;
+                     unsigned int entry;
+
+                     /* NOTE: this code is copied as a comment in
+                      * make_ga_colormap above.  Please update the
+                      * comment if you change this code!
+                      */
+                     if (alpha > 229) /* opaque */
+                     {
+                        entry = (231 * gray + 128) >> 8;
+                     }
+                     else if (alpha < 26) /* transparent */
+                     {
+                        entry = 231;
+                     }
+                     else /* partially opaque */
+                     {
+                        entry = 226 + 6 * PNG_DIV51(alpha) + PNG_DIV51(gray);
+                     }
+
+                     *outrow = (png_byte)entry;
+                  }
+                  break;
+
+               case PNG_CMAP_TRANS:
+                  for (; outrow < end_row; outrow += stepx)
+                  {
+                     png_byte gray = *inrow++;
+                     png_byte alpha = *inrow++;
+
+                     if (alpha == 0)
+                        *outrow = PNG_CMAP_TRANS_BACKGROUND;
+
+                     else if (gray != PNG_CMAP_TRANS_BACKGROUND)
+                        *outrow = gray;
+
+                     else
+                        *outrow = (png_byte)(PNG_CMAP_TRANS_BACKGROUND+1);
+                  }
+                  break;
+
+               case PNG_CMAP_RGB:
+                  for (; outrow < end_row; outrow += stepx)
+                  {
+                     *outrow = PNG_RGB_INDEX(inrow[0], inrow[1], inrow[2]);
+                     inrow += 3;
+                  }
+                  break;
+
+               case PNG_CMAP_RGB_ALPHA:
+                  for (; outrow < end_row; outrow += stepx)
+                  {
+                     unsigned int alpha = inrow[3];
+
+                     /* Because the alpha entries only hold alpha==0.5 values
+                      * split the processing at alpha==0.25 (64) and 0.75
+                      * (196).
+                      */
+
+                     if (alpha >= 196)
+                        *outrow = PNG_RGB_INDEX(inrow[0], inrow[1],
+                           inrow[2]);
+
+                     else if (alpha < 64)
+                        *outrow = PNG_CMAP_RGB_ALPHA_BACKGROUND;
+
+                     else
+                     {
+                        /* Likewise there are three entries for each of r, g
+                         * and b.  We could select the entry by popcount on
+                         * the top two bits on those architectures that
+                         * support it, this is what the code below does,
+                         * crudely.
+                         */
+                        unsigned int back_i = PNG_CMAP_RGB_ALPHA_BACKGROUND+1;
+
+                        /* Here are how the values map:
+                         *
+                         * 0x00 .. 0x3f -> 0
+                         * 0x40 .. 0xbf -> 1
+                         * 0xc0 .. 0xff -> 2
+                         *
+                         * So, as above with the explicit alpha checks, the
+                         * breakpoints are at 64 and 196.
+                         */
+                        if (inrow[0] & 0x80) back_i += 9; /* red */
+                        if (inrow[0] & 0x40) back_i += 9;
+                        if (inrow[0] & 0x80) back_i += 3; /* green */
+                        if (inrow[0] & 0x40) back_i += 3;
+                        if (inrow[0] & 0x80) back_i += 1; /* blue */
+                        if (inrow[0] & 0x40) back_i += 1;
+
+                        *outrow = (png_byte)back_i;
+                     }
+
+                     inrow += 4;
+                  }
+                  break;
+
+               default:
+                  break;
+            }
+         }
+      }
+   }
+
+   return 1;
+}
+
+static int
+png_image_read_colormapped(png_voidp argument)
+{
+   png_image_read_control *display = png_voidcast(png_image_read_control*,
+      argument);
+   png_imagep image = display->image;
+   png_controlp control = image->opaque;
+   png_structrp png_ptr = control->png_ptr;
+   png_inforp info_ptr = control->info_ptr;
+
+   int passes = 0; /* As a flag */
+
+   PNG_SKIP_CHUNKS(png_ptr);
+
+   /* Update the 'info' structure and make sure the result is as required; first
+    * make sure to turn on the interlace handling if it will be required
+    * (because it can't be turned on *after* the call to png_read_update_info!)
+    */
+   if (display->colormap_processing == PNG_CMAP_NONE)
+      passes = png_set_interlace_handling(png_ptr);
+
+   png_read_update_info(png_ptr, info_ptr);
+
+   /* The expected output can be deduced from the colormap_processing option. */
+   switch (display->colormap_processing)
+   {
+      case PNG_CMAP_NONE:
+         /* Output must be one channel and one byte per pixel, the output
+          * encoding can be anything.
+          */
+         if ((info_ptr->color_type == PNG_COLOR_TYPE_PALETTE ||
+            info_ptr->color_type == PNG_COLOR_TYPE_GRAY) &&
+            info_ptr->bit_depth == 8)
+            break;
+
+         goto bad_output;
+
+      case PNG_CMAP_TRANS:
+      case PNG_CMAP_GA:
+         /* Output must be two channels and the 'G' one must be sRGB, the latter
+          * can be checked with an exact number because it should have been set
+          * to this number above!
+          */
+         if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
+            info_ptr->bit_depth == 8 &&
+            png_ptr->screen_gamma == PNG_GAMMA_sRGB &&
+            image->colormap_entries == 256)
+            break;
+
+         goto bad_output;
+
+      case PNG_CMAP_RGB:
+         /* Output must be 8-bit sRGB encoded RGB */
+         if (info_ptr->color_type == PNG_COLOR_TYPE_RGB &&
+            info_ptr->bit_depth == 8 &&
+            png_ptr->screen_gamma == PNG_GAMMA_sRGB &&
+            image->colormap_entries == 216)
+            break;
+
+         goto bad_output;
+
+      case PNG_CMAP_RGB_ALPHA:
+         /* Output must be 8-bit sRGB encoded RGBA */
+         if (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
+            info_ptr->bit_depth == 8 &&
+            png_ptr->screen_gamma == PNG_GAMMA_sRGB &&
+            image->colormap_entries == 244 /* 216 + 1 + 27 */)
+            break;
+
+         /* goto bad_output; */
+         /* FALL THROUGH */
+
+      default:
+      bad_output:
+         png_error(png_ptr, "bad color-map processing (internal error)");
+   }
+
+   /* Now read the rows.  Do this here if it is possible to read directly into
+    * the output buffer, otherwise allocate a local row buffer of the maximum
+    * size libpng requires and call the relevant processing routine safely.
+    */
+   {
+      png_voidp first_row = display->buffer;
+      ptrdiff_t row_bytes = display->row_stride;
+
+      /* The following expression is designed to work correctly whether it gives
+       * a signed or an unsigned result.
+       */
+      if (row_bytes < 0)
+      {
+         char *ptr = png_voidcast(char*, first_row);
+         ptr += (image->height-1) * (-row_bytes);
+         first_row = png_voidcast(png_voidp, ptr);
+      }
+
+      display->first_row = first_row;
+      display->row_bytes = row_bytes;
+   }
+
+   if (passes == 0)
+   {
+      int result;
+      png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr));
+
+      display->local_row = row;
+      result = png_safe_execute(image, png_image_read_and_map, display);
+      display->local_row = NULL;
+      png_free(png_ptr, row);
+
+      return result;
+   }
+
+   else
+   {
+      png_alloc_size_t row_bytes = display->row_bytes;
+
+      while (--passes >= 0)
+      {
+         png_uint_32      y = image->height;
+         png_bytep        row = png_voidcast(png_bytep, display->first_row);
+
+         while (y-- > 0)
+         {
+            png_read_row(png_ptr, row, NULL);
+            row += row_bytes;
+         }
+      }
+
+      return 1;
+   }
+}
+
+/* Just the row reading part of png_image_read. */
+static int
+png_image_read_composite(png_voidp argument)
+{
+   png_image_read_control *display = png_voidcast(png_image_read_control*,
+      argument);
+   png_imagep image = display->image;
+   png_structrp png_ptr = image->opaque->png_ptr;
+   int passes;
+
+   switch (png_ptr->interlaced)
+   {
+      case PNG_INTERLACE_NONE:
+         passes = 1;
+         break;
+
+      case PNG_INTERLACE_ADAM7:
+         passes = PNG_INTERLACE_ADAM7_PASSES;
+         break;
+
+      default:
+         png_error(png_ptr, "unknown interlace type");
+   }
+
+   {
+      png_uint_32  height = image->height;
+      png_uint_32  width = image->width;
+      ptrdiff_t    step_row = display->row_bytes;
+      unsigned int channels =
+         (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1;
+      int pass;
+
+      for (pass = 0; pass < passes; ++pass)
+      {
+         unsigned int     startx, stepx, stepy;
+         png_uint_32      y;
+
+         if (png_ptr->interlaced == PNG_INTERLACE_ADAM7)
+         {
+            /* The row may be empty for a short image: */
+            if (PNG_PASS_COLS(width, pass) == 0)
+               continue;
+
+            startx = PNG_PASS_START_COL(pass) * channels;
+            stepx = PNG_PASS_COL_OFFSET(pass) * channels;
+            y = PNG_PASS_START_ROW(pass);
+            stepy = PNG_PASS_ROW_OFFSET(pass);
+         }
+
+         else
+         {
+            y = 0;
+            startx = 0;
+            stepx = channels;
+            stepy = 1;
+         }
+
+         for (; y<height; y += stepy)
+         {
+            png_bytep inrow = png_voidcast(png_bytep, display->local_row);
+            png_bytep outrow;
+            png_const_bytep end_row;
+
+            /* Read the row, which is packed: */
+            png_read_row(png_ptr, inrow, NULL);
+
+            outrow = png_voidcast(png_bytep, display->first_row);
+            outrow += y * step_row;
+            end_row = outrow + width * channels;
+
+            /* Now do the composition on each pixel in this row. */
+            outrow += startx;
+            for (; outrow < end_row; outrow += stepx)
+            {
+               png_byte alpha = inrow[channels];
+
+               if (alpha > 0) /* else no change to the output */
+               {
+                  unsigned int c;
+
+                  for (c=0; c<channels; ++c)
+                  {
+                     png_uint_32 component = inrow[c];
+
+                     if (alpha < 255) /* else just use component */
+                     {
+                        /* This is PNG_OPTIMIZED_ALPHA, the component value
+                         * is a linear 8-bit value.  Combine this with the
+                         * current outrow[c] value which is sRGB encoded.
+                         * Arithmetic here is 16-bits to preserve the output
+                         * values correctly.
+                         */
+                        component *= 257*255; /* =65535 */
+                        component += (255-alpha)*png_sRGB_table[outrow[c]];
+
+                        /* So 'component' is scaled by 255*65535 and is
+                         * therefore appropriate for the sRGB to linear
+                         * conversion table.
+                         */
+                        component = PNG_sRGB_FROM_LINEAR(component);
+                     }
+
+                     outrow[c] = (png_byte)component;
+                  }
+               }
+
+               inrow += channels+1; /* components and alpha channel */
+            }
+         }
+      }
+   }
+
+   return 1;
+}
+
+/* The do_local_background case; called when all the following transforms are to
+ * be done:
+ *
+ * PNG_RGB_TO_GRAY
+ * PNG_COMPOSITE
+ * PNG_GAMMA
+ *
+ * This is a work-around for the fact that both the PNG_RGB_TO_GRAY and
+ * PNG_COMPOSITE code performs gamma correction, so we get double gamma
+ * correction.  The fix-up is to prevent the PNG_COMPOSITE operation from
+ * happening inside libpng, so this routine sees an 8 or 16-bit gray+alpha
+ * row and handles the removal or pre-multiplication of the alpha channel.
+ */
+static int
+png_image_read_background(png_voidp argument)
+{
+   png_image_read_control *display = png_voidcast(png_image_read_control*,
+      argument);
+   png_imagep image = display->image;
+   png_structrp png_ptr = image->opaque->png_ptr;
+   png_inforp info_ptr = image->opaque->info_ptr;
+   png_uint_32 height = image->height;
+   png_uint_32 width = image->width;
+   int pass, passes;
+
+   /* Double check the convoluted logic below.  We expect to get here with
+    * libpng doing rgb to gray and gamma correction but background processing
+    * left to the png_image_read_background function.  The rows libpng produce
+    * might be 8 or 16-bit but should always have two channels; gray plus alpha.
+    */
+   if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == 0)
+      png_error(png_ptr, "lost rgb to gray");
+
+   if ((png_ptr->transformations & PNG_COMPOSE) != 0)
+      png_error(png_ptr, "unexpected compose");
+
+   if (png_get_channels(png_ptr, info_ptr) != 2)
+      png_error(png_ptr, "lost/gained channels");
+
+   /* Expect the 8-bit case to always remove the alpha channel */
+   if ((image->format & PNG_FORMAT_FLAG_LINEAR) == 0 &&
+      (image->format & PNG_FORMAT_FLAG_ALPHA) != 0)
+      png_error(png_ptr, "unexpected 8-bit transformation");
+
+   switch (png_ptr->interlaced)
+   {
+      case PNG_INTERLACE_NONE:
+         passes = 1;
+         break;
+
+      case PNG_INTERLACE_ADAM7:
+         passes = PNG_INTERLACE_ADAM7_PASSES;
+         break;
+
+      default:
+         png_error(png_ptr, "unknown interlace type");
+   }
+
+   /* Use direct access to info_ptr here because otherwise the simplified API
+    * would require PNG_EASY_ACCESS_SUPPORTED (just for this.)  Note this is
+    * checking the value after libpng expansions, not the original value in the
+    * PNG.
+    */
+   switch (info_ptr->bit_depth)
+   {
+      default:
+         png_error(png_ptr, "unexpected bit depth");
+         break;
+
+      case 8:
+         /* 8-bit sRGB gray values with an alpha channel; the alpha channel is
+          * to be removed by composing on a background: either the row if
+          * display->background is NULL or display->background->green if not.
+          * Unlike the code above ALPHA_OPTIMIZED has *not* been done.
+          */
+         {
+            png_bytep first_row = png_voidcast(png_bytep, display->first_row);
+            ptrdiff_t step_row = display->row_bytes;
+
+            for (pass = 0; pass < passes; ++pass)
+            {
+               png_bytep        row = png_voidcast(png_bytep,
+                                                   display->first_row);
+               unsigned int     startx, stepx, stepy;
+               png_uint_32      y;
+
+               if (png_ptr->interlaced == PNG_INTERLACE_ADAM7)
+               {
+                  /* The row may be empty for a short image: */
+                  if (PNG_PASS_COLS(width, pass) == 0)
+                     continue;
+
+                  startx = PNG_PASS_START_COL(pass);
+                  stepx = PNG_PASS_COL_OFFSET(pass);
+                  y = PNG_PASS_START_ROW(pass);
+                  stepy = PNG_PASS_ROW_OFFSET(pass);
+               }
+
+               else
+               {
+                  y = 0;
+                  startx = 0;
+                  stepx = stepy = 1;
+               }
+
+               if (display->background == NULL)
+               {
+                  for (; y<height; y += stepy)
+                  {
+                     png_bytep inrow = png_voidcast(png_bytep,
+                        display->local_row);
+                     png_bytep outrow = first_row + y * step_row;
+                     png_const_bytep end_row = outrow + width;
+
+                     /* Read the row, which is packed: */
+                     png_read_row(png_ptr, inrow, NULL);
+
+                     /* Now do the composition on each pixel in this row. */
+                     outrow += startx;
+                     for (; outrow < end_row; outrow += stepx)
+                     {
+                        png_byte alpha = inrow[1];
+
+                        if (alpha > 0) /* else no change to the output */
+                        {
+                           png_uint_32 component = inrow[0];
+
+                           if (alpha < 255) /* else just use component */
+                           {
+                              /* Since PNG_OPTIMIZED_ALPHA was not set it is
+                               * necessary to invert the sRGB transfer
+                               * function and multiply the alpha out.
+                               */
+                              component = png_sRGB_table[component] * alpha;
+                              component += png_sRGB_table[outrow[0]] *
+                                 (255-alpha);
+                              component = PNG_sRGB_FROM_LINEAR(component);
+                           }
+
+                           outrow[0] = (png_byte)component;
+                        }
+
+                        inrow += 2; /* gray and alpha channel */
+                     }
+                  }
+               }
+
+               else /* constant background value */
+               {
+                  png_byte background8 = display->background->green;
+                  png_uint_16 background = png_sRGB_table[background8];
+
+                  for (; y<height; y += stepy)
+                  {
+                     png_bytep inrow = png_voidcast(png_bytep,
+                        display->local_row);
+                     png_bytep outrow = first_row + y * step_row;
+                     png_const_bytep end_row = outrow + width;
+
+                     /* Read the row, which is packed: */
+                     png_read_row(png_ptr, inrow, NULL);
+
+                     /* Now do the composition on each pixel in this row. */
+                     outrow += startx;
+                     for (; outrow < end_row; outrow += stepx)
+                     {
+                        png_byte alpha = inrow[1];
+
+                        if (alpha > 0) /* else use background */
+                        {
+                           png_uint_32 component = inrow[0];
+
+                           if (alpha < 255) /* else just use component */
+                           {
+                              component = png_sRGB_table[component] * alpha;
+                              component += background * (255-alpha);
+                              component = PNG_sRGB_FROM_LINEAR(component);
+                           }
+
+                           outrow[0] = (png_byte)component;
+                        }
+
+                        else
+                           outrow[0] = background8;
+
+                        inrow += 2; /* gray and alpha channel */
+                     }
+
+                     row += display->row_bytes;
+                  }
+               }
+            }
+         }
+         break;
+
+      case 16:
+         /* 16-bit linear with pre-multiplied alpha; the pre-multiplication must
+          * still be done and, maybe, the alpha channel removed.  This code also
+          * handles the alpha-first option.
+          */
+         {
+            png_uint_16p first_row = png_voidcast(png_uint_16p,
+               display->first_row);
+            /* The division by two is safe because the caller passed in a
+             * stride which was multiplied by 2 (below) to get row_bytes.
+             */
+            ptrdiff_t    step_row = display->row_bytes / 2;
+            int preserve_alpha = (image->format & PNG_FORMAT_FLAG_ALPHA) != 0;
+            unsigned int outchannels = 1+preserve_alpha;
+            int swap_alpha = 0;
+
+#           ifdef PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED
+               if (preserve_alpha != 0 &&
+                   (image->format & PNG_FORMAT_FLAG_AFIRST) != 0)
+                  swap_alpha = 1;
+#           endif
+
+            for (pass = 0; pass < passes; ++pass)
+            {
+               unsigned int     startx, stepx, stepy;
+               png_uint_32      y;
+
+               /* The 'x' start and step are adjusted to output components here.
+                */
+               if (png_ptr->interlaced == PNG_INTERLACE_ADAM7)
+               {
+                  /* The row may be empty for a short image: */
+                  if (PNG_PASS_COLS(width, pass) == 0)
+                     continue;
+
+                  startx = PNG_PASS_START_COL(pass) * outchannels;
+                  stepx = PNG_PASS_COL_OFFSET(pass) * outchannels;
+                  y = PNG_PASS_START_ROW(pass);
+                  stepy = PNG_PASS_ROW_OFFSET(pass);
+               }
+
+               else
+               {
+                  y = 0;
+                  startx = 0;
+                  stepx = outchannels;
+                  stepy = 1;
+               }
+
+               for (; y<height; y += stepy)
+               {
+                  png_const_uint_16p inrow;
+                  png_uint_16p outrow = first_row + y*step_row;
+                  png_uint_16p end_row = outrow + width * outchannels;
+
+                  /* Read the row, which is packed: */
+                  png_read_row(png_ptr, png_voidcast(png_bytep,
+                     display->local_row), NULL);
+                  inrow = png_voidcast(png_const_uint_16p, display->local_row);
+
+                  /* Now do the pre-multiplication on each pixel in this row.
+                   */
+                  outrow += startx;
+                  for (; outrow < end_row; outrow += stepx)
+                  {
+                     png_uint_32 component = inrow[0];
+                     png_uint_16 alpha = inrow[1];
+
+                     if (alpha > 0) /* else 0 */
+                     {
+                        if (alpha < 65535) /* else just use component */
+                        {
+                           component *= alpha;
+                           component += 32767;
+                           component /= 65535;
+                        }
+                     }
+
+                     else
+                        component = 0;
+
+                     outrow[swap_alpha] = (png_uint_16)component;
+                     if (preserve_alpha != 0)
+                        outrow[1 ^ swap_alpha] = alpha;
+
+                     inrow += 2; /* components and alpha channel */
+                  }
+               }
+            }
+         }
+         break;
+   }
+
+   return 1;
+}
+
+/* The guts of png_image_finish_read as a png_safe_execute callback. */
+static int
+png_image_read_direct(png_voidp argument)
+{
+   png_image_read_control *display = png_voidcast(png_image_read_control*,
+      argument);
+   png_imagep image = display->image;
+   png_structrp png_ptr = image->opaque->png_ptr;
+   png_inforp info_ptr = image->opaque->info_ptr;
+
+   png_uint_32 format = image->format;
+   int linear = (format & PNG_FORMAT_FLAG_LINEAR) != 0;
+   int do_local_compose = 0;
+   int do_local_background = 0; /* to avoid double gamma correction bug */
+   int passes = 0;
+
+   /* Add transforms to ensure the correct output format is produced then check
+    * that the required implementation support is there.  Always expand; always
+    * need 8 bits minimum, no palette and expanded tRNS.
+    */
+   png_set_expand(png_ptr);
+
+   /* Now check the format to see if it was modified. */
+   {
+      png_uint_32 base_format = png_image_format(png_ptr) &
+         ~PNG_FORMAT_FLAG_COLORMAP /* removed by png_set_expand */;
+      png_uint_32 change = format ^ base_format;
+      png_fixed_point output_gamma;
+      int mode; /* alpha mode */
+
+      /* Do this first so that we have a record if rgb to gray is happening. */
+      if ((change & PNG_FORMAT_FLAG_COLOR) != 0)
+      {
+         /* gray<->color transformation required. */
+         if ((format & PNG_FORMAT_FLAG_COLOR) != 0)
+            png_set_gray_to_rgb(png_ptr);
+
+         else
+         {
+            /* libpng can't do both rgb to gray and
+             * background/pre-multiplication if there is also significant gamma
+             * correction, because both operations require linear colors and
+             * the code only supports one transform doing the gamma correction.
+             * Handle this by doing the pre-multiplication or background
+             * operation in this code, if necessary.
+             *
+             * TODO: fix this by rewriting pngrtran.c (!)
+             *
+             * For the moment (given that fixing this in pngrtran.c is an
+             * enormous change) 'do_local_background' is used to indicate that
+             * the problem exists.
+             */
+            if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0)
+               do_local_background = 1/*maybe*/;
+
+            png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE,
+               PNG_RGB_TO_GRAY_DEFAULT, PNG_RGB_TO_GRAY_DEFAULT);
+         }
+
+         change &= ~PNG_FORMAT_FLAG_COLOR;
+      }
+
+      /* Set the gamma appropriately, linear for 16-bit input, sRGB otherwise.
+       */
+      {
+         png_fixed_point input_gamma_default;
+
+         if ((base_format & PNG_FORMAT_FLAG_LINEAR) != 0 &&
+             (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0)
+            input_gamma_default = PNG_GAMMA_LINEAR;
+         else
+            input_gamma_default = PNG_DEFAULT_sRGB;
+
+         /* Call png_set_alpha_mode to set the default for the input gamma; the
+          * output gamma is set by a second call below.
+          */
+         png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, input_gamma_default);
+      }
+
+      if (linear != 0)
+      {
+         /* If there *is* an alpha channel in the input it must be multiplied
+          * out; use PNG_ALPHA_STANDARD, otherwise just use PNG_ALPHA_PNG.
+          */
+         if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0)
+            mode = PNG_ALPHA_STANDARD; /* associated alpha */
+
+         else
+            mode = PNG_ALPHA_PNG;
+
+         output_gamma = PNG_GAMMA_LINEAR;
+      }
+
+      else
+      {
+         mode = PNG_ALPHA_PNG;
+         output_gamma = PNG_DEFAULT_sRGB;
+      }
+
+      /* If 'do_local_background' is set check for the presence of gamma
+       * correction; this is part of the work-round for the libpng bug
+       * described above.
+       *
+       * TODO: fix libpng and remove this.
+       */
+      if (do_local_background != 0)
+      {
+         png_fixed_point gtest;
+
+         /* This is 'png_gamma_threshold' from pngrtran.c; the test used for
+          * gamma correction, the screen gamma hasn't been set on png_struct
+          * yet; it's set below.  png_struct::gamma, however, is set to the
+          * final value.
+          */
+         if (png_muldiv(&gtest, output_gamma, png_ptr->colorspace.gamma,
+               PNG_FP_1) != 0 && png_gamma_significant(gtest) == 0)
+            do_local_background = 0;
+
+         else if (mode == PNG_ALPHA_STANDARD)
+         {
+            do_local_background = 2/*required*/;
+            mode = PNG_ALPHA_PNG; /* prevent libpng doing it */
+         }
+
+         /* else leave as 1 for the checks below */
+      }
+
+      /* If the bit-depth changes then handle that here. */
+      if ((change & PNG_FORMAT_FLAG_LINEAR) != 0)
+      {
+         if (linear != 0 /*16-bit output*/)
+            png_set_expand_16(png_ptr);
+
+         else /* 8-bit output */
+            png_set_scale_16(png_ptr);
+
+         change &= ~PNG_FORMAT_FLAG_LINEAR;
+      }
+
+      /* Now the background/alpha channel changes. */
+      if ((change & PNG_FORMAT_FLAG_ALPHA) != 0)
+      {
+         /* Removing an alpha channel requires composition for the 8-bit
+          * formats; for the 16-bit it is already done, above, by the
+          * pre-multiplication and the channel just needs to be stripped.
+          */
+         if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0)
+         {
+            /* If RGB->gray is happening the alpha channel must be left and the
+             * operation completed locally.
+             *
+             * TODO: fix libpng and remove this.
+             */
+            if (do_local_background != 0)
+               do_local_background = 2/*required*/;
+
+            /* 16-bit output: just remove the channel */
+            else if (linear != 0) /* compose on black (well, pre-multiply) */
+               png_set_strip_alpha(png_ptr);
+
+            /* 8-bit output: do an appropriate compose */
+            else if (display->background != NULL)
+            {
+               png_color_16 c;
+
+               c.index = 0; /*unused*/
+               c.red = display->background->red;
+               c.green = display->background->green;
+               c.blue = display->background->blue;
+               c.gray = display->background->green;
+
+               /* This is always an 8-bit sRGB value, using the 'green' channel
+                * for gray is much better than calculating the luminance here;
+                * we can get off-by-one errors in that calculation relative to
+                * the app expectations and that will show up in transparent
+                * pixels.
+                */
+               png_set_background_fixed(png_ptr, &c,
+                  PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
+                  0/*gamma: not used*/);
+            }
+
+            else /* compose on row: implemented below. */
+            {
+               do_local_compose = 1;
+               /* This leaves the alpha channel in the output, so it has to be
+                * removed by the code below.  Set the encoding to the 'OPTIMIZE'
+                * one so the code only has to hack on the pixels that require
+                * composition.
+                */
+               mode = PNG_ALPHA_OPTIMIZED;
+            }
+         }
+
+         else /* output needs an alpha channel */
+         {
+            /* This is tricky because it happens before the swap operation has
+             * been accomplished; however, the swap does *not* swap the added
+             * alpha channel (weird API), so it must be added in the correct
+             * place.
+             */
+            png_uint_32 filler; /* opaque filler */
+            int where;
+
+            if (linear != 0)
+               filler = 65535;
+
+            else
+               filler = 255;
+
+#           ifdef PNG_FORMAT_AFIRST_SUPPORTED
+               if ((format & PNG_FORMAT_FLAG_AFIRST) != 0)
+               {
+                  where = PNG_FILLER_BEFORE;
+                  change &= ~PNG_FORMAT_FLAG_AFIRST;
+               }
+
+               else
+#           endif
+               where = PNG_FILLER_AFTER;
+
+            png_set_add_alpha(png_ptr, filler, where);
+         }
+
+         /* This stops the (irrelevant) call to swap_alpha below. */
+         change &= ~PNG_FORMAT_FLAG_ALPHA;
+      }
+
+      /* Now set the alpha mode correctly; this is always done, even if there is
+       * no alpha channel in either the input or the output because it correctly
+       * sets the output gamma.
+       */
+      png_set_alpha_mode_fixed(png_ptr, mode, output_gamma);
+
+#     ifdef PNG_FORMAT_BGR_SUPPORTED
+         if ((change & PNG_FORMAT_FLAG_BGR) != 0)
+         {
+            /* Check only the output format; PNG is never BGR; don't do this if
+             * the output is gray, but fix up the 'format' value in that case.
+             */
+            if ((format & PNG_FORMAT_FLAG_COLOR) != 0)
+               png_set_bgr(png_ptr);
+
+            else
+               format &= ~PNG_FORMAT_FLAG_BGR;
+
+            change &= ~PNG_FORMAT_FLAG_BGR;
+         }
+#     endif
+
+#     ifdef PNG_FORMAT_AFIRST_SUPPORTED
+         if ((change & PNG_FORMAT_FLAG_AFIRST) != 0)
+         {
+            /* Only relevant if there is an alpha channel - it's particularly
+             * important to handle this correctly because do_local_compose may
+             * be set above and then libpng will keep the alpha channel for this
+             * code to remove.
+             */
+            if ((format & PNG_FORMAT_FLAG_ALPHA) != 0)
+            {
+               /* Disable this if doing a local background,
+                * TODO: remove this when local background is no longer required.
+                */
+               if (do_local_background != 2)
+                  png_set_swap_alpha(png_ptr);
+            }
+
+            else
+               format &= ~PNG_FORMAT_FLAG_AFIRST;
+
+            change &= ~PNG_FORMAT_FLAG_AFIRST;
+         }
+#     endif
+
+      /* If the *output* is 16-bit then we need to check for a byte-swap on this
+       * architecture.
+       */
+      if (linear != 0)
+      {
+         PNG_CONST png_uint_16 le = 0x0001;
+
+         if ((*(png_const_bytep) & le) != 0)
+            png_set_swap(png_ptr);
+      }
+
+      /* If change is not now 0 some transformation is missing - error out. */
+      if (change != 0)
+         png_error(png_ptr, "png_read_image: unsupported transformation");
+   }
+
+   PNG_SKIP_CHUNKS(png_ptr);
+
+   /* Update the 'info' structure and make sure the result is as required; first
+    * make sure to turn on the interlace handling if it will be required
+    * (because it can't be turned on *after* the call to png_read_update_info!)
+    *
+    * TODO: remove the do_local_background fixup below.
+    */
+   if (do_local_compose == 0 && do_local_background != 2)
+      passes = png_set_interlace_handling(png_ptr);
+
+   png_read_update_info(png_ptr, info_ptr);
+
+   {
+      png_uint_32 info_format = 0;
+
+      if ((info_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
+         info_format |= PNG_FORMAT_FLAG_COLOR;
+
+      if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)
+      {
+         /* do_local_compose removes this channel below. */
+         if (do_local_compose == 0)
+         {
+            /* do_local_background does the same if required. */
+            if (do_local_background != 2 ||
+               (format & PNG_FORMAT_FLAG_ALPHA) != 0)
+               info_format |= PNG_FORMAT_FLAG_ALPHA;
+         }
+      }
+
+      else if (do_local_compose != 0) /* internal error */
+         png_error(png_ptr, "png_image_read: alpha channel lost");
+
+      if (info_ptr->bit_depth == 16)
+         info_format |= PNG_FORMAT_FLAG_LINEAR;
+
+#     ifdef PNG_FORMAT_BGR_SUPPORTED
+         if ((png_ptr->transformations & PNG_BGR) != 0)
+            info_format |= PNG_FORMAT_FLAG_BGR;
+#     endif
+
+#     ifdef PNG_FORMAT_AFIRST_SUPPORTED
+         if (do_local_background == 2)
+         {
+            if ((format & PNG_FORMAT_FLAG_AFIRST) != 0)
+               info_format |= PNG_FORMAT_FLAG_AFIRST;
+         }
+
+         if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0 ||
+            ((png_ptr->transformations & PNG_ADD_ALPHA) != 0 &&
+            (png_ptr->flags & PNG_FLAG_FILLER_AFTER) == 0))
+         {
+            if (do_local_background == 2)
+               png_error(png_ptr, "unexpected alpha swap transformation");
+
+            info_format |= PNG_FORMAT_FLAG_AFIRST;
+         }
+#     endif
+
+      /* This is actually an internal error. */
+      if (info_format != format)
+         png_error(png_ptr, "png_read_image: invalid transformations");
+   }
+
+   /* Now read the rows.  If do_local_compose is set then it is necessary to use
+    * a local row buffer.  The output will be GA, RGBA or BGRA and must be
+    * converted to G, RGB or BGR as appropriate.  The 'local_row' member of the
+    * display acts as a flag.
+    */
+   {
+      png_voidp first_row = display->buffer;
+      ptrdiff_t row_bytes = display->row_stride;
+
+      if (linear != 0)
+         row_bytes *= 2;
+
+      /* The following expression is designed to work correctly whether it gives
+       * a signed or an unsigned result.
+       */
+      if (row_bytes < 0)
+      {
+         char *ptr = png_voidcast(char*, first_row);
+         ptr += (image->height-1) * (-row_bytes);
+         first_row = png_voidcast(png_voidp, ptr);
+      }
+
+      display->first_row = first_row;
+      display->row_bytes = row_bytes;
+   }
+
+   if (do_local_compose != 0)
+   {
+      int result;
+      png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr));
+
+      display->local_row = row;
+      result = png_safe_execute(image, png_image_read_composite, display);
+      display->local_row = NULL;
+      png_free(png_ptr, row);
+
+      return result;
+   }
+
+   else if (do_local_background == 2)
+   {
+      int result;
+      png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr));
+
+      display->local_row = row;
+      result = png_safe_execute(image, png_image_read_background, display);
+      display->local_row = NULL;
+      png_free(png_ptr, row);
+
+      return result;
+   }
+
+   else
+   {
+      png_alloc_size_t row_bytes = display->row_bytes;
+
+      while (--passes >= 0)
+      {
+         png_uint_32      y = image->height;
+         png_bytep        row = png_voidcast(png_bytep, display->first_row);
+
+         while (y-- > 0)
+         {
+            png_read_row(png_ptr, row, NULL);
+            row += row_bytes;
+         }
+      }
+
+      return 1;
+   }
+}
+
+int PNGAPI
+png_image_finish_read(png_imagep image, png_const_colorp background,
+   void *buffer, png_int_32 row_stride, void *colormap)
+{
+   if (image != NULL && image->version == PNG_IMAGE_VERSION)
+   {
+      png_uint_32 check;
+
+      if (row_stride == 0)
+         row_stride = PNG_IMAGE_ROW_STRIDE(*image);
+
+      if (row_stride < 0)
+         check = -row_stride;
+
+      else
+         check = row_stride;
+
+      if (image->opaque != NULL && buffer != NULL &&
+         check >= PNG_IMAGE_ROW_STRIDE(*image))
+      {
+         if ((image->format & PNG_FORMAT_FLAG_COLORMAP) == 0 ||
+            (image->colormap_entries > 0 && colormap != NULL))
+         {
+            int result;
+            png_image_read_control display;
+
+            memset(&display, 0, (sizeof display));
+            display.image = image;
+            display.buffer = buffer;
+            display.row_stride = row_stride;
+            display.colormap = colormap;
+            display.background = background;
+            display.local_row = NULL;
+
+            /* Choose the correct 'end' routine; for the color-map case all the
+             * setup has already been done.
+             */
+            if ((image->format & PNG_FORMAT_FLAG_COLORMAP) != 0)
+               result =
+                  png_safe_execute(image, png_image_read_colormap, &display) &&
+                  png_safe_execute(image, png_image_read_colormapped, &display);
+
+            else
+               result =
+                  png_safe_execute(image, png_image_read_direct, &display);
+
+            png_image_free(image);
+            return result;
+         }
+
+         else
+            return png_image_error(image,
+               "png_image_finish_read[color-map]: no color-map");
+      }
+
+      else
+         return png_image_error(image,
+            "png_image_finish_read: invalid argument");
+   }
+
+   else if (image != NULL)
+      return png_image_error(image,
+         "png_image_finish_read: damaged PNG_IMAGE_VERSION");
+
+   return 0;
+}
+
+#endif /* SIMPLIFIED_READ */
+#endif /* READ */
diff --git a/Source/LibPNG/pngrio.c b/Source/LibPNG/pngrio.c
index d0d9d8a..1e98395 100644
--- a/Source/LibPNG/pngrio.c
+++ b/Source/LibPNG/pngrio.c
@@ -1,176 +1,120 @@
-
-/* pngrio.c - functions for data input
- *
- * Last changed in libpng 1.5.0 [January 6, 2011]
- * Copyright (c) 1998-2011 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- *
- * This file provides a location for all input.  Users who need
- * special handling are expected to write a function that has the same
- * arguments as this and performs a similar function, but that possibly
- * has a different input method.  Note that you shouldn't change this
- * function, but rather write a replacement function and then make
- * libpng use it at run time with png_set_read_fn(...).
- */
-
-#include "pngpriv.h"
-
-#ifdef PNG_READ_SUPPORTED
-
-/* Read the data from whatever input you are using.  The default routine
- * reads from a file pointer.  Note that this routine sometimes gets called
- * with very small lengths, so you should implement some kind of simple
- * buffering if you are using unbuffered reads.  This should never be asked
- * to read more then 64K on a 16 bit machine.
- */
-void /* PRIVATE */
-png_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
-{
-   png_debug1(4, "reading %d bytes", (int)length);
-
-   if (png_ptr->read_data_fn != NULL)
-      (*(png_ptr->read_data_fn))(png_ptr, data, length);
-
-   else
-      png_error(png_ptr, "Call to NULL read function");
-}
-
-#ifdef PNG_STDIO_SUPPORTED
-/* This is the function that does the actual reading of data.  If you are
- * not reading from a standard C stream, you should create a replacement
- * read_data function and use it at run time with png_set_read_fn(), rather
- * than changing the library.
- */
-#  ifndef USE_FAR_KEYWORD
-void PNGCBAPI
-png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
-{
-   png_size_t check;
-
-   if (png_ptr == NULL)
-      return;
-
-   /* fread() returns 0 on error, so it is OK to store this in a png_size_t
-    * instead of an int, which is what fread() actually returns.
-    */
-   check = fread(data, 1, length, (png_FILE_p)png_ptr->io_ptr);
-
-   if (check != length)
-      png_error(png_ptr, "Read Error");
-}
-#  else
-/* This is the model-independent version. Since the standard I/O library
-   can't handle far buffers in the medium and small models, we have to copy
-   the data.
-*/
-
-#define NEAR_BUF_SIZE 1024
-#define MIN(a,b) (a <= b ? a : b)
-
-static void PNGCBAPI
-png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
-{
-   png_size_t check;
-   png_byte *n_data;
-   png_FILE_p io_ptr;
-
-   if (png_ptr == NULL)
-      return;
-
-   /* Check if data really is near. If so, use usual code. */
-   n_data = (png_byte *)CVT_PTR_NOCHECK(data);
-   io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
-
-   if ((png_bytep)n_data == data)
-   {
-      check = fread(n_data, 1, length, io_ptr);
-   }
-
-   else
-   {
-      png_byte buf[NEAR_BUF_SIZE];
-      png_size_t read, remaining, err;
-      check = 0;
-      remaining = length;
-
-      do
-      {
-         read = MIN(NEAR_BUF_SIZE, remaining);
-         err = fread(buf, 1, read, io_ptr);
-         png_memcpy(data, buf, read); /* copy far buffer to near buffer */
-
-         if (err != read)
-            break;
-
-         else
-            check += err;
-
-         data += read;
-         remaining -= read;
-      }
-      while (remaining != 0);
-   }
-
-   if ((png_uint_32)check != (png_uint_32)length)
-      png_error(png_ptr, "read Error");
-}
-#  endif
-#endif
-
-/* This function allows the application to supply a new input function
- * for libpng if standard C streams aren't being used.
- *
- * This function takes as its arguments:
- *
- * png_ptr      - pointer to a png input data structure
- *
- * io_ptr       - pointer to user supplied structure containing info about
- *                the input functions.  May be NULL.
- *
- * read_data_fn - pointer to a new input function that takes as its
- *                arguments a pointer to a png_struct, a pointer to
- *                a location where input data can be stored, and a 32-bit
- *                unsigned int that is the number of bytes to be read.
- *                To exit and output any fatal error messages the new write
- *                function should call png_error(png_ptr, "Error msg").
- *                May be NULL, in which case libpng's default function will
- *                be used.
- */
-void PNGAPI
-png_set_read_fn(png_structp png_ptr, png_voidp io_ptr,
-   png_rw_ptr read_data_fn)
-{
-   if (png_ptr == NULL)
-      return;
-
-   png_ptr->io_ptr = io_ptr;
-
-#ifdef PNG_STDIO_SUPPORTED
-   if (read_data_fn != NULL)
-      png_ptr->read_data_fn = read_data_fn;
-
-   else
-      png_ptr->read_data_fn = png_default_read_data;
-#else
-   png_ptr->read_data_fn = read_data_fn;
-#endif
-
-   /* It is an error to write to a read device */
-   if (png_ptr->write_data_fn != NULL)
-   {
-      png_ptr->write_data_fn = NULL;
-      png_warning(png_ptr,
-          "Can't set both read_data_fn and write_data_fn in the"
-          " same structure");
-   }
-
-#ifdef PNG_WRITE_FLUSH_SUPPORTED
-   png_ptr->output_flush_fn = NULL;
-#endif
-}
-#endif /* PNG_READ_SUPPORTED */
+
+/* pngrio.c - functions for data input
+ *
+ * Last changed in libpng 1.6.15 [November 20, 2014]
+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * This file provides a location for all input.  Users who need
+ * special handling are expected to write a function that has the same
+ * arguments as this and performs a similar function, but that possibly
+ * has a different input method.  Note that you shouldn't change this
+ * function, but rather write a replacement function and then make
+ * libpng use it at run time with png_set_read_fn(...).
+ */
+
+#include "pngpriv.h"
+
+#ifdef PNG_READ_SUPPORTED
+
+/* Read the data from whatever input you are using.  The default routine
+ * reads from a file pointer.  Note that this routine sometimes gets called
+ * with very small lengths, so you should implement some kind of simple
+ * buffering if you are using unbuffered reads.  This should never be asked
+ * to read more then 64K on a 16 bit machine.
+ */
+void /* PRIVATE */
+png_read_data(png_structrp png_ptr, png_bytep data, png_size_t length)
+{
+   png_debug1(4, "reading %d bytes", (int)length);
+
+   if (png_ptr->read_data_fn != NULL)
+      (*(png_ptr->read_data_fn))(png_ptr, data, length);
+
+   else
+      png_error(png_ptr, "Call to NULL read function");
+}
+
+#ifdef PNG_STDIO_SUPPORTED
+/* This is the function that does the actual reading of data.  If you are
+ * not reading from a standard C stream, you should create a replacement
+ * read_data function and use it at run time with png_set_read_fn(), rather
+ * than changing the library.
+ */
+void PNGCBAPI
+png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+   png_size_t check;
+
+   if (png_ptr == NULL)
+      return;
+
+   /* fread() returns 0 on error, so it is OK to store this in a png_size_t
+    * instead of an int, which is what fread() actually returns.
+    */
+   check = fread(data, 1, length, png_voidcast(png_FILE_p, png_ptr->io_ptr));
+
+   if (check != length)
+      png_error(png_ptr, "Read Error");
+}
+#endif
+
+/* This function allows the application to supply a new input function
+ * for libpng if standard C streams aren't being used.
+ *
+ * This function takes as its arguments:
+ *
+ * png_ptr      - pointer to a png input data structure
+ *
+ * io_ptr       - pointer to user supplied structure containing info about
+ *                the input functions.  May be NULL.
+ *
+ * read_data_fn - pointer to a new input function that takes as its
+ *                arguments a pointer to a png_struct, a pointer to
+ *                a location where input data can be stored, and a 32-bit
+ *                unsigned int that is the number of bytes to be read.
+ *                To exit and output any fatal error messages the new write
+ *                function should call png_error(png_ptr, "Error msg").
+ *                May be NULL, in which case libpng's default function will
+ *                be used.
+ */
+void PNGAPI
+png_set_read_fn(png_structrp png_ptr, png_voidp io_ptr,
+   png_rw_ptr read_data_fn)
+{
+   if (png_ptr == NULL)
+      return;
+
+   png_ptr->io_ptr = io_ptr;
+
+#ifdef PNG_STDIO_SUPPORTED
+   if (read_data_fn != NULL)
+      png_ptr->read_data_fn = read_data_fn;
+
+   else
+      png_ptr->read_data_fn = png_default_read_data;
+#else
+   png_ptr->read_data_fn = read_data_fn;
+#endif
+
+#ifdef PNG_WRITE_SUPPORTED
+   /* It is an error to write to a read device */
+   if (png_ptr->write_data_fn != NULL)
+   {
+      png_ptr->write_data_fn = NULL;
+      png_warning(png_ptr,
+          "Can't set both read_data_fn and write_data_fn in the"
+          " same structure");
+   }
+#endif
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+   png_ptr->output_flush_fn = NULL;
+#endif
+}
+#endif /* READ */
diff --git a/Source/LibPNG/pngrtran.c b/Source/LibPNG/pngrtran.c
index 4a40495..e6fe9fd 100644
--- a/Source/LibPNG/pngrtran.c
+++ b/Source/LibPNG/pngrtran.c
@@ -1,5054 +1,4994 @@
-
-/* pngrtran.c - transforms the data in a row for PNG readers
- *
- * Last changed in libpng 1.5.11 [June 14, 2012]
- * Copyright (c) 1998-2012 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- *
- * This file contains functions optionally called by an application
- * in order to tell libpng how to handle data when reading a PNG.
- * Transformations that are used in both reading and writing are
- * in pngtrans.c.
- */
-
-#include "pngpriv.h"
-
-#ifdef PNG_READ_SUPPORTED
-
-/* Set the action on getting a CRC error for an ancillary or critical chunk. */
-void PNGAPI
-png_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action)
-{
-   png_debug(1, "in png_set_crc_action");
-
-   if (png_ptr == NULL)
-      return;
-
-   /* Tell libpng how we react to CRC errors in critical chunks */
-   switch (crit_action)
-   {
-      case PNG_CRC_NO_CHANGE:                        /* Leave setting as is */
-         break;
-
-      case PNG_CRC_WARN_USE:                               /* Warn/use data */
-         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
-         png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE;
-         break;
-
-      case PNG_CRC_QUIET_USE:                             /* Quiet/use data */
-         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
-         png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE |
-                           PNG_FLAG_CRC_CRITICAL_IGNORE;
-         break;
-
-      case PNG_CRC_WARN_DISCARD:    /* Not a valid action for critical data */
-         png_warning(png_ptr,
-            "Can't discard critical data on CRC error");
-      case PNG_CRC_ERROR_QUIT:                                /* Error/quit */
-
-      case PNG_CRC_DEFAULT:
-      default:
-         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
-         break;
-   }
-
-   /* Tell libpng how we react to CRC errors in ancillary chunks */
-   switch (ancil_action)
-   {
-      case PNG_CRC_NO_CHANGE:                       /* Leave setting as is */
-         break;
-
-      case PNG_CRC_WARN_USE:                              /* Warn/use data */
-         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
-         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE;
-         break;
-
-      case PNG_CRC_QUIET_USE:                            /* Quiet/use data */
-         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
-         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE |
-                           PNG_FLAG_CRC_ANCILLARY_NOWARN;
-         break;
-
-      case PNG_CRC_ERROR_QUIT:                               /* Error/quit */
-         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
-         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN;
-         break;
-
-      case PNG_CRC_WARN_DISCARD:                      /* Warn/discard data */
-
-      case PNG_CRC_DEFAULT:
-      default:
-         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
-         break;
-   }
-}
-
-#ifdef PNG_READ_BACKGROUND_SUPPORTED
-/* Handle alpha and tRNS via a background color */
-void PNGFAPI
-png_set_background_fixed(png_structp png_ptr,
-    png_const_color_16p background_color, int background_gamma_code,
-    int need_expand, png_fixed_point background_gamma)
-{
-   png_debug(1, "in png_set_background_fixed");
-
-   if (png_ptr == NULL)
-      return;
-
-   if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN)
-   {
-      png_warning(png_ptr, "Application must supply a known background gamma");
-      return;
-   }
-
-   png_ptr->transformations |= PNG_COMPOSE | PNG_STRIP_ALPHA;
-   png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
-   png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
-
-   png_memcpy(&(png_ptr->background), background_color,
-      png_sizeof(png_color_16));
-   png_ptr->background_gamma = background_gamma;
-   png_ptr->background_gamma_type = (png_byte)(background_gamma_code);
-   if (need_expand)
-      png_ptr->transformations |= PNG_BACKGROUND_EXPAND;
-   else
-      png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND;
-}
-
-#  ifdef PNG_FLOATING_POINT_SUPPORTED
-void PNGAPI
-png_set_background(png_structp png_ptr,
-    png_const_color_16p background_color, int background_gamma_code,
-    int need_expand, double background_gamma)
-{
-   png_set_background_fixed(png_ptr, background_color, background_gamma_code,
-      need_expand, png_fixed(png_ptr, background_gamma, "png_set_background"));
-}
-#  endif  /* FLOATING_POINT */
-#endif /* READ_BACKGROUND */
-
-/* Scale 16-bit depth files to 8-bit depth.  If both of these are set then the
- * one that pngrtran does first (scale) happens.  This is necessary to allow the
- * TRANSFORM and API behavior to be somewhat consistent, and it's simpler.
- */
-#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
-void PNGAPI
-png_set_scale_16(png_structp png_ptr)
-{
-   png_debug(1, "in png_set_scale_16");
-
-   if (png_ptr == NULL)
-      return;
-
-   png_ptr->transformations |= PNG_SCALE_16_TO_8;
-}
-#endif
-
-#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
-/* Chop 16-bit depth files to 8-bit depth */
-void PNGAPI
-png_set_strip_16(png_structp png_ptr)
-{
-   png_debug(1, "in png_set_strip_16");
-
-   if (png_ptr == NULL)
-      return;
-
-   png_ptr->transformations |= PNG_16_TO_8;
-}
-#endif
-
-#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
-void PNGAPI
-png_set_strip_alpha(png_structp png_ptr)
-{
-   png_debug(1, "in png_set_strip_alpha");
-
-   if (png_ptr == NULL)
-      return;
-
-   png_ptr->transformations |= PNG_STRIP_ALPHA;
-}
-#endif
-
-#if defined(PNG_READ_ALPHA_MODE_SUPPORTED) || defined(PNG_READ_GAMMA_SUPPORTED)
-static png_fixed_point
-translate_gamma_flags(png_structp png_ptr, png_fixed_point output_gamma,
-   int is_screen)
-{
-   /* Check for flag values.  The main reason for having the old Mac value as a
-    * flag is that it is pretty near impossible to work out what the correct
-    * value is from Apple documentation - a working Mac system is needed to
-    * discover the value!
-    */
-   if (output_gamma == PNG_DEFAULT_sRGB ||
-      output_gamma == PNG_FP_1 / PNG_DEFAULT_sRGB)
-   {
-      /* If there is no sRGB support this just sets the gamma to the standard
-       * sRGB value.  (This is a side effect of using this function!)
-       */
-#     ifdef PNG_READ_sRGB_SUPPORTED
-         png_ptr->flags |= PNG_FLAG_ASSUME_sRGB;
-#     endif
-      if (is_screen)
-         output_gamma = PNG_GAMMA_sRGB;
-      else
-         output_gamma = PNG_GAMMA_sRGB_INVERSE;
-   }
-
-   else if (output_gamma == PNG_GAMMA_MAC_18 ||
-      output_gamma == PNG_FP_1 / PNG_GAMMA_MAC_18)
-   {
-      if (is_screen)
-         output_gamma = PNG_GAMMA_MAC_OLD;
-      else
-         output_gamma = PNG_GAMMA_MAC_INVERSE;
-   }
-
-   return output_gamma;
-}
-
-#  ifdef PNG_FLOATING_POINT_SUPPORTED
-static png_fixed_point
-convert_gamma_value(png_structp png_ptr, double output_gamma)
-{
-   /* The following silently ignores cases where fixed point (times 100,000)
-    * gamma values are passed to the floating point API.  This is safe and it
-    * means the fixed point constants work just fine with the floating point
-    * API.  The alternative would just lead to undetected errors and spurious
-    * bug reports.  Negative values fail inside the _fixed API unless they
-    * correspond to the flag values.
-    */
-   if (output_gamma > 0 && output_gamma < 128)
-      output_gamma *= PNG_FP_1;
-
-   /* This preserves -1 and -2 exactly: */
-   output_gamma = floor(output_gamma + .5);
-
-   if (output_gamma > PNG_FP_MAX || output_gamma < PNG_FP_MIN)
-      png_fixed_error(png_ptr, "gamma value");
-
-   return (png_fixed_point)output_gamma;
-}
-#  endif
-#endif /* READ_ALPHA_MODE || READ_GAMMA */
-
-#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
-void PNGFAPI
-png_set_alpha_mode_fixed(png_structp png_ptr, int mode,
-   png_fixed_point output_gamma)
-{
-   int compose = 0;
-   png_fixed_point file_gamma;
-
-   png_debug(1, "in png_set_alpha_mode");
-
-   if (png_ptr == NULL)
-      return;
-
-   output_gamma = translate_gamma_flags(png_ptr, output_gamma, 1/*screen*/);
-
-   /* Validate the value to ensure it is in a reasonable range. The value
-    * is expected to be 1 or greater, but this range test allows for some
-    * viewing correction values.  The intent is to weed out users of this API
-    * who use the inverse of the gamma value accidentally!  Since some of these
-    * values are reasonable this may have to be changed.
-    */
-   if (output_gamma < 70000 || output_gamma > 300000)
-      png_error(png_ptr, "output gamma out of expected range");
-
-   /* The default file gamma is the inverse of the output gamma; the output
-    * gamma may be changed below so get the file value first:
-    */
-   file_gamma = png_reciprocal(output_gamma);
-
-   /* There are really 8 possibilities here, composed of any combination
-    * of:
-    *
-    *    premultiply the color channels
-    *    do not encode non-opaque pixels
-    *    encode the alpha as well as the color channels
-    *
-    * The differences disappear if the input/output ('screen') gamma is 1.0,
-    * because then the encoding is a no-op and there is only the choice of
-    * premultiplying the color channels or not.
-    *
-    * png_set_alpha_mode and png_set_background interact because both use
-    * png_compose to do the work.  Calling both is only useful when
-    * png_set_alpha_mode is used to set the default mode - PNG_ALPHA_PNG - along
-    * with a default gamma value.  Otherwise PNG_COMPOSE must not be set.
-    */
-   switch (mode)
-   {
-      case PNG_ALPHA_PNG:        /* default: png standard */
-         /* No compose, but it may be set by png_set_background! */
-         png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
-         png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
-         break;
-
-      case PNG_ALPHA_ASSOCIATED: /* color channels premultiplied */
-         compose = 1;
-         png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
-         png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
-         /* The output is linear: */
-         output_gamma = PNG_FP_1;
-         break;
-
-      case PNG_ALPHA_OPTIMIZED:  /* associated, non-opaque pixels linear */
-         compose = 1;
-         png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
-         png_ptr->flags |= PNG_FLAG_OPTIMIZE_ALPHA;
-         /* output_gamma records the encoding of opaque pixels! */
-         break;
-
-      case PNG_ALPHA_BROKEN:     /* associated, non-linear, alpha encoded */
-         compose = 1;
-         png_ptr->transformations |= PNG_ENCODE_ALPHA;
-         png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
-         break;
-
-      default:
-         png_error(png_ptr, "invalid alpha mode");
-   }
-
-   /* Only set the default gamma if the file gamma has not been set (this has
-    * the side effect that the gamma in a second call to png_set_alpha_mode will
-    * be ignored.)
-    */
-   if (png_ptr->gamma == 0)
-      png_ptr->gamma = file_gamma;
-
-   /* But always set the output gamma: */
-   png_ptr->screen_gamma = output_gamma;
-
-   /* Finally, if pre-multiplying, set the background fields to achieve the
-    * desired result.
-    */
-   if (compose)
-   {
-      /* And obtain alpha pre-multiplication by composing on black: */
-      png_memset(&png_ptr->background, 0, sizeof png_ptr->background);
-      png_ptr->background_gamma = png_ptr->gamma; /* just in case */
-      png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_FILE;
-      png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND;
-
-      if (png_ptr->transformations & PNG_COMPOSE)
-         png_error(png_ptr,
-            "conflicting calls to set alpha mode and background");
-
-      png_ptr->transformations |= PNG_COMPOSE;
-   }
-
-   /* New API, make sure apps call the correct initializers: */
-   png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED;
-}
-
-#  ifdef PNG_FLOATING_POINT_SUPPORTED
-void PNGAPI
-png_set_alpha_mode(png_structp png_ptr, int mode, double output_gamma)
-{
-   png_set_alpha_mode_fixed(png_ptr, mode, convert_gamma_value(png_ptr,
-      output_gamma));
-}
-#  endif
-#endif
-
-#ifdef PNG_READ_QUANTIZE_SUPPORTED
-/* Dither file to 8-bit.  Supply a palette, the current number
- * of elements in the palette, the maximum number of elements
- * allowed, and a histogram if possible.  If the current number
- * of colors is greater then the maximum number, the palette will be
- * modified to fit in the maximum number.  "full_quantize" indicates
- * whether we need a quantizing cube set up for RGB images, or if we
- * simply are reducing the number of colors in a paletted image.
- */
-
-typedef struct png_dsort_struct
-{
-   struct png_dsort_struct FAR * next;
-   png_byte left;
-   png_byte right;
-} png_dsort;
-typedef png_dsort FAR *       png_dsortp;
-typedef png_dsort FAR * FAR * png_dsortpp;
-
-void PNGAPI
-png_set_quantize(png_structp png_ptr, png_colorp palette,
-    int num_palette, int maximum_colors, png_const_uint_16p histogram,
-    int full_quantize)
-{
-   png_debug(1, "in png_set_quantize");
-
-   if (png_ptr == NULL)
-      return;
-
-   png_ptr->transformations |= PNG_QUANTIZE;
-
-   if (!full_quantize)
-   {
-      int i;
-
-      png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr,
-          (png_uint_32)(num_palette * png_sizeof(png_byte)));
-      for (i = 0; i < num_palette; i++)
-         png_ptr->quantize_index[i] = (png_byte)i;
-   }
-
-   if (num_palette > maximum_colors)
-   {
-      if (histogram != NULL)
-      {
-         /* This is easy enough, just throw out the least used colors.
-          * Perhaps not the best solution, but good enough.
-          */
-
-         int i;
-
-         /* Initialize an array to sort colors */
-         png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr,
-             (png_uint_32)(num_palette * png_sizeof(png_byte)));
-
-         /* Initialize the quantize_sort array */
-         for (i = 0; i < num_palette; i++)
-            png_ptr->quantize_sort[i] = (png_byte)i;
-
-         /* Find the least used palette entries by starting a
-          * bubble sort, and running it until we have sorted
-          * out enough colors.  Note that we don't care about
-          * sorting all the colors, just finding which are
-          * least used.
-          */
-
-         for (i = num_palette - 1; i >= maximum_colors; i--)
-         {
-            int done; /* To stop early if the list is pre-sorted */
-            int j;
-
-            done = 1;
-            for (j = 0; j < i; j++)
-            {
-               if (histogram[png_ptr->quantize_sort[j]]
-                   < histogram[png_ptr->quantize_sort[j + 1]])
-               {
-                  png_byte t;
-
-                  t = png_ptr->quantize_sort[j];
-                  png_ptr->quantize_sort[j] = png_ptr->quantize_sort[j + 1];
-                  png_ptr->quantize_sort[j + 1] = t;
-                  done = 0;
-               }
-            }
-
-            if (done)
-               break;
-         }
-
-         /* Swap the palette around, and set up a table, if necessary */
-         if (full_quantize)
-         {
-            int j = num_palette;
-
-            /* Put all the useful colors within the max, but don't
-             * move the others.
-             */
-            for (i = 0; i < maximum_colors; i++)
-            {
-               if ((int)png_ptr->quantize_sort[i] >= maximum_colors)
-               {
-                  do
-                     j--;
-                  while ((int)png_ptr->quantize_sort[j] >= maximum_colors);
-
-                  palette[i] = palette[j];
-               }
-            }
-         }
-         else
-         {
-            int j = num_palette;
-
-            /* Move all the used colors inside the max limit, and
-             * develop a translation table.
-             */
-            for (i = 0; i < maximum_colors; i++)
-            {
-               /* Only move the colors we need to */
-               if ((int)png_ptr->quantize_sort[i] >= maximum_colors)
-               {
-                  png_color tmp_color;
-
-                  do
-                     j--;
-                  while ((int)png_ptr->quantize_sort[j] >= maximum_colors);
-
-                  tmp_color = palette[j];
-                  palette[j] = palette[i];
-                  palette[i] = tmp_color;
-                  /* Indicate where the color went */
-                  png_ptr->quantize_index[j] = (png_byte)i;
-                  png_ptr->quantize_index[i] = (png_byte)j;
-               }
-            }
-
-            /* Find closest color for those colors we are not using */
-            for (i = 0; i < num_palette; i++)
-            {
-               if ((int)png_ptr->quantize_index[i] >= maximum_colors)
-               {
-                  int min_d, k, min_k, d_index;
-
-                  /* Find the closest color to one we threw out */
-                  d_index = png_ptr->quantize_index[i];
-                  min_d = PNG_COLOR_DIST(palette[d_index], palette[0]);
-                  for (k = 1, min_k = 0; k < maximum_colors; k++)
-                  {
-                     int d;
-
-                     d = PNG_COLOR_DIST(palette[d_index], palette[k]);
-
-                     if (d < min_d)
-                     {
-                        min_d = d;
-                        min_k = k;
-                     }
-                  }
-                  /* Point to closest color */
-                  png_ptr->quantize_index[i] = (png_byte)min_k;
-               }
-            }
-         }
-         png_free(png_ptr, png_ptr->quantize_sort);
-         png_ptr->quantize_sort = NULL;
-      }
-      else
-      {
-         /* This is much harder to do simply (and quickly).  Perhaps
-          * we need to go through a median cut routine, but those
-          * don't always behave themselves with only a few colors
-          * as input.  So we will just find the closest two colors,
-          * and throw out one of them (chosen somewhat randomly).
-          * [We don't understand this at all, so if someone wants to
-          *  work on improving it, be our guest - AED, GRP]
-          */
-         int i;
-         int max_d;
-         int num_new_palette;
-         png_dsortp t;
-         png_dsortpp hash;
-
-         t = NULL;
-
-         /* Initialize palette index arrays */
-         png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,
-             (png_uint_32)(num_palette * png_sizeof(png_byte)));
-         png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr,
-             (png_uint_32)(num_palette * png_sizeof(png_byte)));
-
-         /* Initialize the sort array */
-         for (i = 0; i < num_palette; i++)
-         {
-            png_ptr->index_to_palette[i] = (png_byte)i;
-            png_ptr->palette_to_index[i] = (png_byte)i;
-         }
-
-         hash = (png_dsortpp)png_calloc(png_ptr, (png_uint_32)(769 *
-             png_sizeof(png_dsortp)));
-
-         num_new_palette = num_palette;
-
-         /* Initial wild guess at how far apart the farthest pixel
-          * pair we will be eliminating will be.  Larger
-          * numbers mean more areas will be allocated, Smaller
-          * numbers run the risk of not saving enough data, and
-          * having to do this all over again.
-          *
-          * I have not done extensive checking on this number.
-          */
-         max_d = 96;
-
-         while (num_new_palette > maximum_colors)
-         {
-            for (i = 0; i < num_new_palette - 1; i++)
-            {
-               int j;
-
-               for (j = i + 1; j < num_new_palette; j++)
-               {
-                  int d;
-
-                  d = PNG_COLOR_DIST(palette[i], palette[j]);
-
-                  if (d <= max_d)
-                  {
-
-                     t = (png_dsortp)png_malloc_warn(png_ptr,
-                         (png_uint_32)(png_sizeof(png_dsort)));
-
-                     if (t == NULL)
-                         break;
-
-                     t->next = hash[d];
-                     t->left = (png_byte)i;
-                     t->right = (png_byte)j;
-                     hash[d] = t;
-                  }
-               }
-               if (t == NULL)
-                  break;
-            }
-
-            if (t != NULL)
-            for (i = 0; i <= max_d; i++)
-            {
-               if (hash[i] != NULL)
-               {
-                  png_dsortp p;
-
-                  for (p = hash[i]; p; p = p->next)
-                  {
-                     if ((int)png_ptr->index_to_palette[p->left]
-                         < num_new_palette &&
-                         (int)png_ptr->index_to_palette[p->right]
-                         < num_new_palette)
-                     {
-                        int j, next_j;
-
-                        if (num_new_palette & 0x01)
-                        {
-                           j = p->left;
-                           next_j = p->right;
-                        }
-                        else
-                        {
-                           j = p->right;
-                           next_j = p->left;
-                        }
-
-                        num_new_palette--;
-                        palette[png_ptr->index_to_palette[j]]
-                            = palette[num_new_palette];
-                        if (!full_quantize)
-                        {
-                           int k;
-
-                           for (k = 0; k < num_palette; k++)
-                           {
-                              if (png_ptr->quantize_index[k] ==
-                                  png_ptr->index_to_palette[j])
-                                 png_ptr->quantize_index[k] =
-                                     png_ptr->index_to_palette[next_j];
-
-                              if ((int)png_ptr->quantize_index[k] ==
-                                  num_new_palette)
-                                 png_ptr->quantize_index[k] =
-                                     png_ptr->index_to_palette[j];
-                           }
-                        }
-
-                        png_ptr->index_to_palette[png_ptr->palette_to_index
-                            [num_new_palette]] = png_ptr->index_to_palette[j];
-
-                        png_ptr->palette_to_index[png_ptr->index_to_palette[j]]
-                            = png_ptr->palette_to_index[num_new_palette];
-
-                        png_ptr->index_to_palette[j] =
-                            (png_byte)num_new_palette;
-
-                        png_ptr->palette_to_index[num_new_palette] =
-                            (png_byte)j;
-                     }
-                     if (num_new_palette <= maximum_colors)
-                        break;
-                  }
-                  if (num_new_palette <= maximum_colors)
-                     break;
-               }
-            }
-
-            for (i = 0; i < 769; i++)
-            {
-               if (hash[i] != NULL)
-               {
-                  png_dsortp p = hash[i];
-                  while (p)
-                  {
-                     t = p->next;
-                     png_free(png_ptr, p);
-                     p = t;
-                  }
-               }
-               hash[i] = 0;
-            }
-            max_d += 96;
-         }
-         png_free(png_ptr, hash);
-         png_free(png_ptr, png_ptr->palette_to_index);
-         png_free(png_ptr, png_ptr->index_to_palette);
-         png_ptr->palette_to_index = NULL;
-         png_ptr->index_to_palette = NULL;
-      }
-      num_palette = maximum_colors;
-   }
-   if (png_ptr->palette == NULL)
-   {
-      png_ptr->palette = palette;
-   }
-   png_ptr->num_palette = (png_uint_16)num_palette;
-
-   if (full_quantize)
-   {
-      int i;
-      png_bytep distance;
-      int total_bits = PNG_QUANTIZE_RED_BITS + PNG_QUANTIZE_GREEN_BITS +
-          PNG_QUANTIZE_BLUE_BITS;
-      int num_red = (1 << PNG_QUANTIZE_RED_BITS);
-      int num_green = (1 << PNG_QUANTIZE_GREEN_BITS);
-      int num_blue = (1 << PNG_QUANTIZE_BLUE_BITS);
-      png_size_t num_entries = ((png_size_t)1 << total_bits);
-
-      png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr,
-          (png_uint_32)(num_entries * png_sizeof(png_byte)));
-
-      distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries *
-          png_sizeof(png_byte)));
-
-      png_memset(distance, 0xff, num_entries * png_sizeof(png_byte));
-
-      for (i = 0; i < num_palette; i++)
-      {
-         int ir, ig, ib;
-         int r = (palette[i].red >> (8 - PNG_QUANTIZE_RED_BITS));
-         int g = (palette[i].green >> (8 - PNG_QUANTIZE_GREEN_BITS));
-         int b = (palette[i].blue >> (8 - PNG_QUANTIZE_BLUE_BITS));
-
-         for (ir = 0; ir < num_red; ir++)
-         {
-            /* int dr = abs(ir - r); */
-            int dr = ((ir > r) ? ir - r : r - ir);
-            int index_r = (ir << (PNG_QUANTIZE_BLUE_BITS +
-                PNG_QUANTIZE_GREEN_BITS));
-
-            for (ig = 0; ig < num_green; ig++)
-            {
-               /* int dg = abs(ig - g); */
-               int dg = ((ig > g) ? ig - g : g - ig);
-               int dt = dr + dg;
-               int dm = ((dr > dg) ? dr : dg);
-               int index_g = index_r | (ig << PNG_QUANTIZE_BLUE_BITS);
-
-               for (ib = 0; ib < num_blue; ib++)
-               {
-                  int d_index = index_g | ib;
-                  /* int db = abs(ib - b); */
-                  int db = ((ib > b) ? ib - b : b - ib);
-                  int dmax = ((dm > db) ? dm : db);
-                  int d = dmax + dt + db;
-
-                  if (d < (int)distance[d_index])
-                  {
-                     distance[d_index] = (png_byte)d;
-                     png_ptr->palette_lookup[d_index] = (png_byte)i;
-                  }
-               }
-            }
-         }
-      }
-
-      png_free(png_ptr, distance);
-   }
-}
-#endif /* PNG_READ_QUANTIZE_SUPPORTED */
-
-#ifdef PNG_READ_GAMMA_SUPPORTED
-void PNGFAPI
-png_set_gamma_fixed(png_structp png_ptr, png_fixed_point scrn_gamma,
-   png_fixed_point file_gamma)
-{
-   png_debug(1, "in png_set_gamma_fixed");
-
-   if (png_ptr == NULL)
-      return;
-
-   /* New in libpng-1.5.4 - reserve particular negative values as flags. */
-   scrn_gamma = translate_gamma_flags(png_ptr, scrn_gamma, 1/*screen*/);
-   file_gamma = translate_gamma_flags(png_ptr, file_gamma, 0/*file*/);
-
-#if PNG_LIBPNG_VER >= 10600
-   /* Checking the gamma values for being >0 was added in 1.5.4 along with the
-    * premultiplied alpha support; this actually hides an undocumented feature
-    * of the previous implementation which allowed gamma processing to be
-    * disabled in background handling.  There is no evidence (so far) that this
-    * was being used; however, png_set_background itself accepted and must still
-    * accept '0' for the gamma value it takes, because it isn't always used.
-    *
-    * Since this is an API change (albeit a very minor one that removes an
-    * undocumented API feature) it will not be made until libpng-1.6.0.
-    */
-   if (file_gamma <= 0)
-      png_error(png_ptr, "invalid file gamma in png_set_gamma");
-
-   if (scrn_gamma <= 0)
-      png_error(png_ptr, "invalid screen gamma in png_set_gamma");
-#endif
-
-   /* Set the gamma values unconditionally - this overrides the value in the PNG
-    * file if a gAMA chunk was present.  png_set_alpha_mode provides a
-    * different, easier, way to default the file gamma.
-    */
-   png_ptr->gamma = file_gamma;
-   png_ptr->screen_gamma = scrn_gamma;
-}
-
-#  ifdef PNG_FLOATING_POINT_SUPPORTED
-void PNGAPI
-png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma)
-{
-   png_set_gamma_fixed(png_ptr, convert_gamma_value(png_ptr, scrn_gamma),
-      convert_gamma_value(png_ptr, file_gamma));
-}
-#  endif /* FLOATING_POINT_SUPPORTED */
-#endif /* READ_GAMMA */
-
-#ifdef PNG_READ_EXPAND_SUPPORTED
-/* Expand paletted images to RGB, expand grayscale images of
- * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
- * to alpha channels.
- */
-void PNGAPI
-png_set_expand(png_structp png_ptr)
-{
-   png_debug(1, "in png_set_expand");
-
-   if (png_ptr == NULL)
-      return;
-
-   png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
-   png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
-}
-
-/* GRR 19990627:  the following three functions currently are identical
- *  to png_set_expand().  However, it is entirely reasonable that someone
- *  might wish to expand an indexed image to RGB but *not* expand a single,
- *  fully transparent palette entry to a full alpha channel--perhaps instead
- *  convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace
- *  the transparent color with a particular RGB value, or drop tRNS entirely.
- *  IOW, a future version of the library may make the transformations flag
- *  a bit more fine-grained, with separate bits for each of these three
- *  functions.
- *
- *  More to the point, these functions make it obvious what libpng will be
- *  doing, whereas "expand" can (and does) mean any number of things.
- *
- *  GRP 20060307: In libpng-1.2.9, png_set_gray_1_2_4_to_8() was modified
- *  to expand only the sample depth but not to expand the tRNS to alpha
- *  and its name was changed to png_set_expand_gray_1_2_4_to_8().
- */
-
-/* Expand paletted images to RGB. */
-void PNGAPI
-png_set_palette_to_rgb(png_structp png_ptr)
-{
-   png_debug(1, "in png_set_palette_to_rgb");
-
-   if (png_ptr == NULL)
-      return;
-
-   png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
-   png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
-}
-
-/* Expand grayscale images of less than 8-bit depth to 8 bits. */
-void PNGAPI
-png_set_expand_gray_1_2_4_to_8(png_structp png_ptr)
-{
-   png_debug(1, "in png_set_expand_gray_1_2_4_to_8");
-
-   if (png_ptr == NULL)
-      return;
-
-   png_ptr->transformations |= PNG_EXPAND;
-   png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
-}
-
-
-
-/* Expand tRNS chunks to alpha channels. */
-void PNGAPI
-png_set_tRNS_to_alpha(png_structp png_ptr)
-{
-   png_debug(1, "in png_set_tRNS_to_alpha");
-
-   png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
-   png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
-}
-#endif /* defined(PNG_READ_EXPAND_SUPPORTED) */
-
-#ifdef PNG_READ_EXPAND_16_SUPPORTED
-/* Expand to 16-bit channels, expand the tRNS chunk too (because otherwise
- * it may not work correctly.)
- */
-void PNGAPI
-png_set_expand_16(png_structp png_ptr)
-{
-   png_debug(1, "in png_set_expand_16");
-
-   if (png_ptr == NULL)
-      return;
-
-   png_ptr->transformations |= (PNG_EXPAND_16 | PNG_EXPAND | PNG_EXPAND_tRNS);
-   png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
-
-   /* New API, make sure apps call the correct initializers: */
-   png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED;
-}
-#endif
-
-#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
-void PNGAPI
-png_set_gray_to_rgb(png_structp png_ptr)
-{
-   png_debug(1, "in png_set_gray_to_rgb");
-
-   if (png_ptr != NULL)
-   {
-      /* Because rgb must be 8 bits or more: */
-      png_set_expand_gray_1_2_4_to_8(png_ptr);
-      png_ptr->transformations |= PNG_GRAY_TO_RGB;
-      png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
-   }
-}
-#endif
-
-#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
-void PNGFAPI
-png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action,
-    png_fixed_point red, png_fixed_point green)
-{
-   png_debug(1, "in png_set_rgb_to_gray");
-
-   if (png_ptr == NULL)
-      return;
-
-   switch(error_action)
-   {
-      case PNG_ERROR_ACTION_NONE:
-         png_ptr->transformations |= PNG_RGB_TO_GRAY;
-         break;
-
-      case PNG_ERROR_ACTION_WARN:
-         png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN;
-         break;
-
-      case PNG_ERROR_ACTION_ERROR:
-         png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR;
-         break;
-
-      default:
-         png_error(png_ptr, "invalid error action to rgb_to_gray");
-         break;
-   }
-   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
-#ifdef PNG_READ_EXPAND_SUPPORTED
-      png_ptr->transformations |= PNG_EXPAND;
-#else
-   {
-      png_warning(png_ptr,
-        "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED");
-
-      png_ptr->transformations &= ~PNG_RGB_TO_GRAY;
-   }
-#endif
-   {
-      if (red >= 0 && green >= 0 && red + green <= PNG_FP_1)
-      {
-         png_uint_16 red_int, green_int;
-
-         /* NOTE: this calculation does not round, but this behavior is retained
-          * for consistency, the inaccuracy is very small.  The code here always
-          * overwrites the coefficients, regardless of whether they have been
-          * defaulted or set already.
-          */
-         red_int = (png_uint_16)(((png_uint_32)red*32768)/100000);
-         green_int = (png_uint_16)(((png_uint_32)green*32768)/100000);
-
-         png_ptr->rgb_to_gray_red_coeff   = red_int;
-         png_ptr->rgb_to_gray_green_coeff = green_int;
-         png_ptr->rgb_to_gray_coefficients_set = 1;
-      }
-
-      else
-      {
-         if (red >= 0 && green >= 0)
-            png_warning(png_ptr,
-               "ignoring out of range rgb_to_gray coefficients");
-
-         /* Use the defaults, from the cHRM chunk if set, else the historical
-          * values which are close to the sRGB/HDTV/ITU-Rec 709 values.  See
-          * png_do_rgb_to_gray for more discussion of the values.  In this case
-          * the coefficients are not marked as 'set' and are not overwritten if
-          * something has already provided a default.
-          */
-         if (png_ptr->rgb_to_gray_red_coeff == 0 &&
-            png_ptr->rgb_to_gray_green_coeff == 0)
-         {
-            png_ptr->rgb_to_gray_red_coeff   = 6968;
-            png_ptr->rgb_to_gray_green_coeff = 23434;
-            /* png_ptr->rgb_to_gray_blue_coeff  = 2366; */
-         }
-      }
-   }
-}
-
-#ifdef PNG_FLOATING_POINT_SUPPORTED
-/* Convert a RGB image to a grayscale of the same width.  This allows us,
- * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
- */
-
-void PNGAPI
-png_set_rgb_to_gray(png_structp png_ptr, int error_action, double red,
-   double green)
-{
-   if (png_ptr == NULL)
-      return;
-
-   png_set_rgb_to_gray_fixed(png_ptr, error_action,
-      png_fixed(png_ptr, red, "rgb to gray red coefficient"),
-      png_fixed(png_ptr, green, "rgb to gray green coefficient"));
-}
-#endif /* FLOATING POINT */
-
-#endif
-
-#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
-    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
-void PNGAPI
-png_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr
-    read_user_transform_fn)
-{
-   png_debug(1, "in png_set_read_user_transform_fn");
-
-   if (png_ptr == NULL)
-      return;
-
-#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
-   png_ptr->transformations |= PNG_USER_TRANSFORM;
-   png_ptr->read_user_transform_fn = read_user_transform_fn;
-#endif
-}
-#endif
-
-#ifdef PNG_READ_TRANSFORMS_SUPPORTED
-#ifdef PNG_READ_GAMMA_SUPPORTED
-/* In the case of gamma transformations only do transformations on images where
- * the [file] gamma and screen_gamma are not close reciprocals, otherwise it
- * slows things down slightly, and also needlessly introduces small errors.
- */
-static int /* PRIVATE */
-png_gamma_threshold(png_fixed_point screen_gamma, png_fixed_point file_gamma)
-{
-   /* PNG_GAMMA_THRESHOLD is the threshold for performing gamma
-    * correction as a difference of the overall transform from 1.0
-    *
-    * We want to compare the threshold with s*f - 1, if we get
-    * overflow here it is because of wacky gamma values so we
-    * turn on processing anyway.
-    */
-   png_fixed_point gtest;
-   return !png_muldiv(&gtest, screen_gamma, file_gamma, PNG_FP_1) ||
-       png_gamma_significant(gtest);
-}
-#endif
-
-/* Initialize everything needed for the read.  This includes modifying
- * the palette.
- */
-
-/*For the moment 'png_init_palette_transformations' and
- * 'png_init_rgb_transformations' only do some flag canceling optimizations.
- * The intent is that these two routines should have palette or rgb operations
- * extracted from 'png_init_read_transformations'.
- */
-static void /* PRIVATE */
-png_init_palette_transformations(png_structp png_ptr)
-{
-   /* Called to handle the (input) palette case.  In png_do_read_transformations
-    * the first step is to expand the palette if requested, so this code must
-    * take care to only make changes that are invariant with respect to the
-    * palette expansion, or only do them if there is no expansion.
-    *
-    * STRIP_ALPHA has already been handled in the caller (by setting num_trans
-    * to 0.)
-    */
-   int input_has_alpha = 0;
-   int input_has_transparency = 0;
-
-   if (png_ptr->num_trans > 0)
-   {
-      int i;
-
-      /* Ignore if all the entries are opaque (unlikely!) */
-      for (i=0; i<png_ptr->num_trans; ++i)
-         if (png_ptr->trans_alpha[i] == 255)
-            continue;
-         else if (png_ptr->trans_alpha[i] == 0)
-            input_has_transparency = 1;
-         else
-            input_has_alpha = 1;
-   }
-
-   /* If no alpha we can optimize. */
-   if (!input_has_alpha)
-   {
-      /* Any alpha means background and associative alpha processing is
-       * required, however if the alpha is 0 or 1 throughout OPTIIMIZE_ALPHA
-       * and ENCODE_ALPHA are irrelevant.
-       */
-      png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
-      png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
-
-      if (!input_has_transparency)
-         png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND);
-   }
-
-#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
-   /* png_set_background handling - deals with the complexity of whether the
-    * background color is in the file format or the screen format in the case
-    * where an 'expand' will happen.
-    */
-
-   /* The following code cannot be entered in the alpha pre-multiplication case
-    * because PNG_BACKGROUND_EXPAND is cancelled below.
-    */
-   if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
-       (png_ptr->transformations & PNG_EXPAND))
-   {
-      {
-         png_ptr->background.red   =
-             png_ptr->palette[png_ptr->background.index].red;
-         png_ptr->background.green =
-             png_ptr->palette[png_ptr->background.index].green;
-         png_ptr->background.blue  =
-             png_ptr->palette[png_ptr->background.index].blue;
-
-#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
-        if (png_ptr->transformations & PNG_INVERT_ALPHA)
-        {
-           if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
-           {
-              /* Invert the alpha channel (in tRNS) unless the pixels are
-               * going to be expanded, in which case leave it for later
-               */
-              int i, istop = png_ptr->num_trans;
-
-              for (i=0; i<istop; i++)
-                 png_ptr->trans_alpha[i] = (png_byte)(255 -
-                    png_ptr->trans_alpha[i]);
-           }
-        }
-#endif /* PNG_READ_INVERT_ALPHA_SUPPORTED */
-      }
-   } /* background expand and (therefore) no alpha association. */
-#endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */
-}
-
-static void /* PRIVATE */
-png_init_rgb_transformations(png_structp png_ptr)
-{
-   /* Added to libpng-1.5.4: check the color type to determine whether there
-    * is any alpha or transparency in the image and simply cancel the
-    * background and alpha mode stuff if there isn't.
-    */
-   int input_has_alpha = (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0;
-   int input_has_transparency = png_ptr->num_trans > 0;
-
-   /* If no alpha we can optimize. */
-   if (!input_has_alpha)
-   {
-      /* Any alpha means background and associative alpha processing is
-       * required, however if the alpha is 0 or 1 throughout OPTIIMIZE_ALPHA
-       * and ENCODE_ALPHA are irrelevant.
-       */
-#     ifdef PNG_READ_ALPHA_MODE_SUPPORTED
-         png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
-         png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
-#     endif
-
-      if (!input_has_transparency)
-         png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND);
-   }
-
-#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
-   /* png_set_background handling - deals with the complexity of whether the
-    * background color is in the file format or the screen format in the case
-    * where an 'expand' will happen.
-    */
-
-   /* The following code cannot be entered in the alpha pre-multiplication case
-    * because PNG_BACKGROUND_EXPAND is cancelled below.
-    */
-   if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
-       (png_ptr->transformations & PNG_EXPAND) &&
-       !(png_ptr->color_type & PNG_COLOR_MASK_COLOR))
-       /* i.e., GRAY or GRAY_ALPHA */
-   {
-      {
-         /* Expand background and tRNS chunks */
-         int gray = png_ptr->background.gray;
-         int trans_gray = png_ptr->trans_color.gray;
-
-         switch (png_ptr->bit_depth)
-         {
-            case 1:
-               gray *= 0xff;
-               trans_gray *= 0xff;
-               break;
-
-            case 2:
-               gray *= 0x55;
-               trans_gray *= 0x55;
-               break;
-
-            case 4:
-               gray *= 0x11;
-               trans_gray *= 0x11;
-               break;
-
-            default:
-
-            case 8:
-               /* Already 8 bits, fall through */
-
-            case 16:
-               /* Already a full 16 bits */
-               break;
-         }
-
-         png_ptr->background.red = png_ptr->background.green =
-            png_ptr->background.blue = (png_uint_16)gray;
-
-         if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
-         {
-            png_ptr->trans_color.red = png_ptr->trans_color.green =
-               png_ptr->trans_color.blue = (png_uint_16)trans_gray;
-         }
-      }
-   } /* background expand and (therefore) no alpha association. */
-#endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */
-}
-
-void /* PRIVATE */
-png_init_read_transformations(png_structp png_ptr)
-{
-   png_debug(1, "in png_init_read_transformations");
-
-   /* This internal function is called from png_read_start_row in pngrutil.c
-    * and it is called before the 'rowbytes' calculation is done, so the code
-    * in here can change or update the transformations flags.
-    *
-    * First do updates that do not depend on the details of the PNG image data
-    * being processed.
-    */
-
-#ifdef PNG_READ_GAMMA_SUPPORTED
-   /* Prior to 1.5.4 these tests were performed from png_set_gamma, 1.5.4 adds
-    * png_set_alpha_mode and this is another source for a default file gamma so
-    * the test needs to be performed later - here.  In addition prior to 1.5.4
-    * the tests were repeated for the PALETTE color type here - this is no
-    * longer necessary (and doesn't seem to have been necessary before.)
-    */
-   {
-      /* The following temporary indicates if overall gamma correction is
-       * required.
-       */
-      int gamma_correction = 0;
-
-      if (png_ptr->gamma != 0) /* has been set */
-      {
-         if (png_ptr->screen_gamma != 0) /* screen set too */
-            gamma_correction = png_gamma_threshold(png_ptr->gamma,
-               png_ptr->screen_gamma);
-
-         else
-            /* Assume the output matches the input; a long time default behavior
-             * of libpng, although the standard has nothing to say about this.
-             */
-            png_ptr->screen_gamma = png_reciprocal(png_ptr->gamma);
-      }
-
-      else if (png_ptr->screen_gamma != 0)
-         /* The converse - assume the file matches the screen, note that this
-          * perhaps undesireable default can (from 1.5.4) be changed by calling
-          * png_set_alpha_mode (even if the alpha handling mode isn't required
-          * or isn't changed from the default.)
-          */
-         png_ptr->gamma = png_reciprocal(png_ptr->screen_gamma);
-
-      else /* neither are set */
-         /* Just in case the following prevents any processing - file and screen
-          * are both assumed to be linear and there is no way to introduce a
-          * third gamma value other than png_set_background with 'UNIQUE', and,
-          * prior to 1.5.4
-          */
-         png_ptr->screen_gamma = png_ptr->gamma = PNG_FP_1;
-
-      /* Now turn the gamma transformation on or off as appropriate.  Notice
-       * that PNG_GAMMA just refers to the file->screen correction.  Alpha
-       * composition may independently cause gamma correction because it needs
-       * linear data (e.g. if the file has a gAMA chunk but the screen gamma
-       * hasn't been specified.)  In any case this flag may get turned off in
-       * the code immediately below if the transform can be handled outside the
-       * row loop.
-       */
-      if (gamma_correction)
-         png_ptr->transformations |= PNG_GAMMA;
-
-      else
-         png_ptr->transformations &= ~PNG_GAMMA;
-   }
-#endif
-
-   /* Certain transformations have the effect of preventing other
-    * transformations that happen afterward in png_do_read_transformations,
-    * resolve the interdependencies here.  From the code of
-    * png_do_read_transformations the order is:
-    *
-    *  1) PNG_EXPAND (including PNG_EXPAND_tRNS)
-    *  2) PNG_STRIP_ALPHA (if no compose)
-    *  3) PNG_RGB_TO_GRAY
-    *  4) PNG_GRAY_TO_RGB iff !PNG_BACKGROUND_IS_GRAY
-    *  5) PNG_COMPOSE
-    *  6) PNG_GAMMA
-    *  7) PNG_STRIP_ALPHA (if compose)
-    *  8) PNG_ENCODE_ALPHA
-    *  9) PNG_SCALE_16_TO_8
-    * 10) PNG_16_TO_8
-    * 11) PNG_QUANTIZE (converts to palette)
-    * 12) PNG_EXPAND_16
-    * 13) PNG_GRAY_TO_RGB iff PNG_BACKGROUND_IS_GRAY
-    * 14) PNG_INVERT_MONO
-    * 15) PNG_SHIFT
-    * 16) PNG_PACK
-    * 17) PNG_BGR
-    * 18) PNG_PACKSWAP
-    * 19) PNG_FILLER (includes PNG_ADD_ALPHA)
-    * 20) PNG_INVERT_ALPHA
-    * 21) PNG_SWAP_ALPHA
-    * 22) PNG_SWAP_BYTES
-    * 23) PNG_USER_TRANSFORM [must be last]
-    */
-#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
-   if ((png_ptr->transformations & PNG_STRIP_ALPHA) &&
-      !(png_ptr->transformations & PNG_COMPOSE))
-   {
-      /* Stripping the alpha channel happens immediately after the 'expand'
-       * transformations, before all other transformation, so it cancels out
-       * the alpha handling.  It has the side effect negating the effect of
-       * PNG_EXPAND_tRNS too:
-       */
-      png_ptr->transformations &= ~(PNG_BACKGROUND_EXPAND | PNG_ENCODE_ALPHA |
-         PNG_EXPAND_tRNS);
-      png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
-
-      /* Kill the tRNS chunk itself too.  Prior to 1.5.4 this did not happen
-       * so transparency information would remain just so long as it wasn't
-       * expanded.  This produces unexpected API changes if the set of things
-       * that do PNG_EXPAND_tRNS changes (perfectly possible given the
-       * documentation - which says ask for what you want, accept what you
-       * get.)  This makes the behavior consistent from 1.5.4:
-       */
-      png_ptr->num_trans = 0;
-   }
-#endif /* STRIP_ALPHA supported, no COMPOSE */
-
-#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
-   /* If the screen gamma is about 1.0 then the OPTIMIZE_ALPHA and ENCODE_ALPHA
-    * settings will have no effect.
-    */
-   if (!png_gamma_significant(png_ptr->screen_gamma))
-   {
-      png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
-      png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
-   }
-#endif
-
-#if defined(PNG_READ_EXPAND_SUPPORTED) && \
-   defined(PNG_READ_BACKGROUND_SUPPORTED) && \
-   defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
-   /* Detect gray background and attempt to enable optimization for
-    * gray --> RGB case.
-    *
-    * Note:  if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or
-    * RGB_ALPHA (in which case need_expand is superfluous anyway), the
-    * background color might actually be gray yet not be flagged as such.
-    * This is not a problem for the current code, which uses
-    * PNG_BACKGROUND_IS_GRAY only to decide when to do the
-    * png_do_gray_to_rgb() transformation.
-    *
-    * TODO: this code needs to be revised to avoid the complexity and
-    * interdependencies.  The color type of the background should be recorded in
-    * png_set_background, along with the bit depth, then the code has a record
-    * of exactly what color space the background is currently in.
-    */
-   if (png_ptr->transformations & PNG_BACKGROUND_EXPAND)
-   {
-      /* PNG_BACKGROUND_EXPAND: the background is in the file color space, so if
-       * the file was grayscale the background value is gray.
-       */
-      if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR))
-         png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
-   }
-
-   else if (png_ptr->transformations & PNG_COMPOSE)
-   {
-      /* PNG_COMPOSE: png_set_background was called with need_expand false,
-       * so the color is in the color space of the output or png_set_alpha_mode
-       * was called and the color is black.  Ignore RGB_TO_GRAY because that
-       * happens before GRAY_TO_RGB.
-       */
-      if (png_ptr->transformations & PNG_GRAY_TO_RGB)
-      {
-         if (png_ptr->background.red == png_ptr->background.green &&
-             png_ptr->background.red == png_ptr->background.blue)
-         {
-            png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
-            png_ptr->background.gray = png_ptr->background.red;
-         }
-      }
-   }
-#endif /* PNG_READ_GRAY_TO_RGB_SUPPORTED (etc) */
-
-   /* For indexed PNG data (PNG_COLOR_TYPE_PALETTE) many of the transformations
-    * can be performed directly on the palette, and some (such as rgb to gray)
-    * can be optimized inside the palette.  This is particularly true of the
-    * composite (background and alpha) stuff, which can be pretty much all done
-    * in the palette even if the result is expanded to RGB or gray afterward.
-    *
-    * NOTE: this is Not Yet Implemented, the code behaves as in 1.5.1 and
-    * earlier and the palette stuff is actually handled on the first row.  This
-    * leads to the reported bug that the palette returned by png_get_PLTE is not
-    * updated.
-    */
-   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
-      png_init_palette_transformations(png_ptr);
-
-   else
-      png_init_rgb_transformations(png_ptr);
-
-#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
-   defined(PNG_READ_EXPAND_16_SUPPORTED)
-   if ((png_ptr->transformations & PNG_EXPAND_16) &&
-      (png_ptr->transformations & PNG_COMPOSE) &&
-      !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
-      png_ptr->bit_depth != 16)
-   {
-      /* TODO: fix this.  Because the expand_16 operation is after the compose
-       * handling the background color must be 8, not 16, bits deep, but the
-       * application will supply a 16-bit value so reduce it here.
-       *
-       * The PNG_BACKGROUND_EXPAND code above does not expand to 16 bits at
-       * present, so that case is ok (until do_expand_16 is moved.)
-       *
-       * NOTE: this discards the low 16 bits of the user supplied background
-       * color, but until expand_16 works properly there is no choice!
-       */
-#     define CHOP(x) (x)=((png_uint_16)(((png_uint_32)(x)*255+32895) >> 16))
-      CHOP(png_ptr->background.red);
-      CHOP(png_ptr->background.green);
-      CHOP(png_ptr->background.blue);
-      CHOP(png_ptr->background.gray);
-#     undef CHOP
-   }
-#endif /* PNG_READ_BACKGROUND_SUPPORTED && PNG_READ_EXPAND_16_SUPPORTED */
-
-#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
-   (defined(PNG_READ_SCALE_16_TO_8_SUPPORTED) || \
-   defined(PNG_READ_STRIP_16_TO_8_SUPPORTED))
-   if ((png_ptr->transformations & (PNG_16_TO_8|PNG_SCALE_16_TO_8)) &&
-      (png_ptr->transformations & PNG_COMPOSE) &&
-      !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
-      png_ptr->bit_depth == 16)
-   {
-      /* On the other hand, if a 16-bit file is to be reduced to 8-bits per
-       * component this will also happen after PNG_COMPOSE and so the background
-       * color must be pre-expanded here.
-       *
-       * TODO: fix this too.
-       */
-      png_ptr->background.red = (png_uint_16)(png_ptr->background.red * 257);
-      png_ptr->background.green =
-         (png_uint_16)(png_ptr->background.green * 257);
-      png_ptr->background.blue = (png_uint_16)(png_ptr->background.blue * 257);
-      png_ptr->background.gray = (png_uint_16)(png_ptr->background.gray * 257);
-   }
-#endif
-
-   /* NOTE: below 'PNG_READ_ALPHA_MODE_SUPPORTED' is presumed to also enable the
-    * background support (see the comments in scripts/pnglibconf.dfa), this
-    * allows pre-multiplication of the alpha channel to be implemented as
-    * compositing on black.  This is probably sub-optimal and has been done in
-    * 1.5.4 betas simply to enable external critique and testing (i.e. to
-    * implement the new API quickly, without lots of internal changes.)
-    */
-
-#ifdef PNG_READ_GAMMA_SUPPORTED
-#  ifdef PNG_READ_BACKGROUND_SUPPORTED
-      /* Includes ALPHA_MODE */
-      png_ptr->background_1 = png_ptr->background;
-#  endif
-
-   /* This needs to change - in the palette image case a whole set of tables are
-    * built when it would be quicker to just calculate the correct value for
-    * each palette entry directly.  Also, the test is too tricky - why check
-    * PNG_RGB_TO_GRAY if PNG_GAMMA is not set?  The answer seems to be that
-    * PNG_GAMMA is cancelled even if the gamma is known?  The test excludes the
-    * PNG_COMPOSE case, so apparently if there is no *overall* gamma correction
-    * the gamma tables will not be built even if composition is required on a
-    * gamma encoded value.
-    *
-    * In 1.5.4 this is addressed below by an additional check on the individual
-    * file gamma - if it is not 1.0 both RGB_TO_GRAY and COMPOSE need the
-    * tables.
-    */
-   if ((png_ptr->transformations & PNG_GAMMA)
-      || ((png_ptr->transformations & PNG_RGB_TO_GRAY)
-         && (png_gamma_significant(png_ptr->gamma) ||
-            png_gamma_significant(png_ptr->screen_gamma)))
-      || ((png_ptr->transformations & PNG_COMPOSE)
-         && (png_gamma_significant(png_ptr->gamma)
-            || png_gamma_significant(png_ptr->screen_gamma)
-#  ifdef PNG_READ_BACKGROUND_SUPPORTED
-            || (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_UNIQUE
-               && png_gamma_significant(png_ptr->background_gamma))
-#  endif
-      )) || ((png_ptr->transformations & PNG_ENCODE_ALPHA)
-         && png_gamma_significant(png_ptr->screen_gamma))
-      )
-   {
-      png_build_gamma_table(png_ptr, png_ptr->bit_depth);
-
-#ifdef PNG_READ_BACKGROUND_SUPPORTED
-      if (png_ptr->transformations & PNG_COMPOSE)
-      {
-         /* Issue a warning about this combination: because RGB_TO_GRAY is
-          * optimized to do the gamma transform if present yet do_background has
-          * to do the same thing if both options are set a
-          * double-gamma-correction happens.  This is true in all versions of
-          * libpng to date.
-          */
-         if (png_ptr->transformations & PNG_RGB_TO_GRAY)
-            png_warning(png_ptr,
-               "libpng does not support gamma+background+rgb_to_gray");
-
-         if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
-         {
-            /* We don't get to here unless there is a tRNS chunk with non-opaque
-             * entries - see the checking code at the start of this function.
-             */
-            png_color back, back_1;
-            png_colorp palette = png_ptr->palette;
-            int num_palette = png_ptr->num_palette;
-            int i;
-            if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
-            {
-
-               back.red = png_ptr->gamma_table[png_ptr->background.red];
-               back.green = png_ptr->gamma_table[png_ptr->background.green];
-               back.blue = png_ptr->gamma_table[png_ptr->background.blue];
-
-               back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
-               back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
-               back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
-            }
-            else
-            {
-               png_fixed_point g, gs;
-
-               switch (png_ptr->background_gamma_type)
-               {
-                  case PNG_BACKGROUND_GAMMA_SCREEN:
-                     g = (png_ptr->screen_gamma);
-                     gs = PNG_FP_1;
-                     break;
-
-                  case PNG_BACKGROUND_GAMMA_FILE:
-                     g = png_reciprocal(png_ptr->gamma);
-                     gs = png_reciprocal2(png_ptr->gamma,
-                        png_ptr->screen_gamma);
-                     break;
-
-                  case PNG_BACKGROUND_GAMMA_UNIQUE:
-                     g = png_reciprocal(png_ptr->background_gamma);
-                     gs = png_reciprocal2(png_ptr->background_gamma,
-                        png_ptr->screen_gamma);
-                     break;
-                  default:
-                     g = PNG_FP_1;    /* back_1 */
-                     gs = PNG_FP_1;   /* back */
-                     break;
-               }
-
-               if (png_gamma_significant(gs))
-               {
-                  back.red = png_gamma_8bit_correct(png_ptr->background.red,
-                      gs);
-                  back.green = png_gamma_8bit_correct(png_ptr->background.green,
-                      gs);
-                  back.blue = png_gamma_8bit_correct(png_ptr->background.blue,
-                      gs);
-               }
-
-               else
-               {
-                  back.red   = (png_byte)png_ptr->background.red;
-                  back.green = (png_byte)png_ptr->background.green;
-                  back.blue  = (png_byte)png_ptr->background.blue;
-               }
-
-               if (png_gamma_significant(g))
-               {
-                  back_1.red = png_gamma_8bit_correct(png_ptr->background.red,
-                     g);
-                  back_1.green = png_gamma_8bit_correct(
-                     png_ptr->background.green, g);
-                  back_1.blue = png_gamma_8bit_correct(png_ptr->background.blue,
-                     g);
-               }
-
-               else
-               {
-                  back_1.red   = (png_byte)png_ptr->background.red;
-                  back_1.green = (png_byte)png_ptr->background.green;
-                  back_1.blue  = (png_byte)png_ptr->background.blue;
-               }
-            }
-
-            for (i = 0; i < num_palette; i++)
-            {
-               if (i < (int)png_ptr->num_trans &&
-                   png_ptr->trans_alpha[i] != 0xff)
-               {
-                  if (png_ptr->trans_alpha[i] == 0)
-                  {
-                     palette[i] = back;
-                  }
-                  else /* if (png_ptr->trans_alpha[i] != 0xff) */
-                  {
-                     png_byte v, w;
-
-                     v = png_ptr->gamma_to_1[palette[i].red];
-                     png_composite(w, v, png_ptr->trans_alpha[i], back_1.red);
-                     palette[i].red = png_ptr->gamma_from_1[w];
-
-                     v = png_ptr->gamma_to_1[palette[i].green];
-                     png_composite(w, v, png_ptr->trans_alpha[i], back_1.green);
-                     palette[i].green = png_ptr->gamma_from_1[w];
-
-                     v = png_ptr->gamma_to_1[palette[i].blue];
-                     png_composite(w, v, png_ptr->trans_alpha[i], back_1.blue);
-                     palette[i].blue = png_ptr->gamma_from_1[w];
-                  }
-               }
-               else
-               {
-                  palette[i].red = png_ptr->gamma_table[palette[i].red];
-                  palette[i].green = png_ptr->gamma_table[palette[i].green];
-                  palette[i].blue = png_ptr->gamma_table[palette[i].blue];
-               }
-            }
-
-            /* Prevent the transformations being done again.
-             *
-             * NOTE: this is highly dubious; it removes the transformations in
-             * place.  This seems inconsistent with the general treatment of the
-             * transformations elsewhere.
-             */
-            png_ptr->transformations &= ~(PNG_COMPOSE | PNG_GAMMA);
-         } /* color_type == PNG_COLOR_TYPE_PALETTE */
-
-         /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */
-         else /* color_type != PNG_COLOR_TYPE_PALETTE */
-         {
-            int gs_sig, g_sig;
-            png_fixed_point g = PNG_FP_1;  /* Correction to linear */
-            png_fixed_point gs = PNG_FP_1; /* Correction to screen */
-
-            switch (png_ptr->background_gamma_type)
-            {
-               case PNG_BACKGROUND_GAMMA_SCREEN:
-                  g = png_ptr->screen_gamma;
-                  /* gs = PNG_FP_1; */
-                  break;
-
-               case PNG_BACKGROUND_GAMMA_FILE:
-                  g = png_reciprocal(png_ptr->gamma);
-                  gs = png_reciprocal2(png_ptr->gamma, png_ptr->screen_gamma);
-                  break;
-
-               case PNG_BACKGROUND_GAMMA_UNIQUE:
-                  g = png_reciprocal(png_ptr->background_gamma);
-                  gs = png_reciprocal2(png_ptr->background_gamma,
-                      png_ptr->screen_gamma);
-                  break;
-
-               default:
-                  png_error(png_ptr, "invalid background gamma type");
-            }
-
-            g_sig = png_gamma_significant(g);
-            gs_sig = png_gamma_significant(gs);
-
-            if (g_sig)
-               png_ptr->background_1.gray = png_gamma_correct(png_ptr,
-                   png_ptr->background.gray, g);
-
-            if (gs_sig)
-               png_ptr->background.gray = png_gamma_correct(png_ptr,
-                   png_ptr->background.gray, gs);
-
-            if ((png_ptr->background.red != png_ptr->background.green) ||
-                (png_ptr->background.red != png_ptr->background.blue) ||
-                (png_ptr->background.red != png_ptr->background.gray))
-            {
-               /* RGB or RGBA with color background */
-               if (g_sig)
-               {
-                  png_ptr->background_1.red = png_gamma_correct(png_ptr,
-                      png_ptr->background.red, g);
-
-                  png_ptr->background_1.green = png_gamma_correct(png_ptr,
-                      png_ptr->background.green, g);
-
-                  png_ptr->background_1.blue = png_gamma_correct(png_ptr,
-                      png_ptr->background.blue, g);
-               }
-
-               if (gs_sig)
-               {
-                  png_ptr->background.red = png_gamma_correct(png_ptr,
-                      png_ptr->background.red, gs);
-
-                  png_ptr->background.green = png_gamma_correct(png_ptr,
-                      png_ptr->background.green, gs);
-
-                  png_ptr->background.blue = png_gamma_correct(png_ptr,
-                      png_ptr->background.blue, gs);
-               }
-            }
-
-            else
-            {
-               /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */
-               png_ptr->background_1.red = png_ptr->background_1.green
-                   = png_ptr->background_1.blue = png_ptr->background_1.gray;
-
-               png_ptr->background.red = png_ptr->background.green
-                   = png_ptr->background.blue = png_ptr->background.gray;
-            }
-
-            /* The background is now in screen gamma: */
-            png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_SCREEN;
-         } /* color_type != PNG_COLOR_TYPE_PALETTE */
-      }/* png_ptr->transformations & PNG_BACKGROUND */
-
-      else
-      /* Transformation does not include PNG_BACKGROUND */
-#endif /* PNG_READ_BACKGROUND_SUPPORTED */
-      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE
-#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
-         /* RGB_TO_GRAY needs to have non-gamma-corrected values! */
-         && ((png_ptr->transformations & PNG_EXPAND) == 0 ||
-         (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0)
-#endif
-         )
-      {
-         png_colorp palette = png_ptr->palette;
-         int num_palette = png_ptr->num_palette;
-         int i;
-
-         /* NOTE: there are other transformations that should probably be in
-          * here too.
-          */
-         for (i = 0; i < num_palette; i++)
-         {
-            palette[i].red = png_ptr->gamma_table[palette[i].red];
-            palette[i].green = png_ptr->gamma_table[palette[i].green];
-            palette[i].blue = png_ptr->gamma_table[palette[i].blue];
-         }
-
-         /* Done the gamma correction. */
-         png_ptr->transformations &= ~PNG_GAMMA;
-      } /* color_type == PALETTE && !PNG_BACKGROUND transformation */
-   }
-#ifdef PNG_READ_BACKGROUND_SUPPORTED
-   else
-#endif
-#endif /* PNG_READ_GAMMA_SUPPORTED */
-
-#ifdef PNG_READ_BACKGROUND_SUPPORTED
-   /* No GAMMA transformation (see the hanging else 4 lines above) */
-   if ((png_ptr->transformations & PNG_COMPOSE) &&
-       (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
-   {
-      int i;
-      int istop = (int)png_ptr->num_trans;
-      png_color back;
-      png_colorp palette = png_ptr->palette;
-
-      back.red   = (png_byte)png_ptr->background.red;
-      back.green = (png_byte)png_ptr->background.green;
-      back.blue  = (png_byte)png_ptr->background.blue;
-
-      for (i = 0; i < istop; i++)
-      {
-         if (png_ptr->trans_alpha[i] == 0)
-         {
-            palette[i] = back;
-         }
-
-         else if (png_ptr->trans_alpha[i] != 0xff)
-         {
-            /* The png_composite() macro is defined in png.h */
-            png_composite(palette[i].red, palette[i].red,
-                png_ptr->trans_alpha[i], back.red);
-
-            png_composite(palette[i].green, palette[i].green,
-                png_ptr->trans_alpha[i], back.green);
-
-            png_composite(palette[i].blue, palette[i].blue,
-                png_ptr->trans_alpha[i], back.blue);
-         }
-      }
-
-      png_ptr->transformations &= ~PNG_COMPOSE;
-   }
-#endif /* PNG_READ_BACKGROUND_SUPPORTED */
-
-#ifdef PNG_READ_SHIFT_SUPPORTED
-   if ((png_ptr->transformations & PNG_SHIFT) &&
-      !(png_ptr->transformations & PNG_EXPAND) &&
-       (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
-   {
-      int i;
-      int istop = png_ptr->num_palette;
-      int shift = 8 - png_ptr->sig_bit.red;
-
-      png_ptr->transformations &= ~PNG_SHIFT;
-
-      /* significant bits can be in the range 1 to 7 for a meaninful result, if
-       * the number of significant bits is 0 then no shift is done (this is an
-       * error condition which is silently ignored.)
-       */
-      if (shift > 0 && shift < 8) for (i=0; i<istop; ++i)
-      {
-         int component = png_ptr->palette[i].red;
-
-         component >>= shift;
-         png_ptr->palette[i].red = (png_byte)component;
-      }
-
-      shift = 8 - png_ptr->sig_bit.green;
-      if (shift > 0 && shift < 8) for (i=0; i<istop; ++i)
-      {
-         int component = png_ptr->palette[i].green;
-
-         component >>= shift;
-         png_ptr->palette[i].green = (png_byte)component;
-      }
-
-      shift = 8 - png_ptr->sig_bit.blue;
-      if (shift > 0 && shift < 8) for (i=0; i<istop; ++i)
-      {
-         int component = png_ptr->palette[i].blue;
-
-         component >>= shift;
-         png_ptr->palette[i].blue = (png_byte)component;
-      }
-   }
-#endif  /* PNG_READ_SHIFT_SUPPORTED */
-}
-
-/* Modify the info structure to reflect the transformations.  The
- * info should be updated so a PNG file could be written with it,
- * assuming the transformations result in valid PNG data.
- */
-void /* PRIVATE */
-png_read_transform_info(png_structp png_ptr, png_infop info_ptr)
-{
-   png_debug(1, "in png_read_transform_info");
-
-#ifdef PNG_READ_EXPAND_SUPPORTED
-   if (png_ptr->transformations & PNG_EXPAND)
-   {
-      if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
-      {
-         /* This check must match what actually happens in
-          * png_do_expand_palette; if it ever checks the tRNS chunk to see if
-          * it is all opaque we must do the same (at present it does not.)
-          */
-         if (png_ptr->num_trans > 0)
-            info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
-
-         else
-            info_ptr->color_type = PNG_COLOR_TYPE_RGB;
-
-         info_ptr->bit_depth = 8;
-         info_ptr->num_trans = 0;
-      }
-      else
-      {
-         if (png_ptr->num_trans)
-         {
-            if (png_ptr->transformations & PNG_EXPAND_tRNS)
-               info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
-         }
-         if (info_ptr->bit_depth < 8)
-            info_ptr->bit_depth = 8;
-
-         info_ptr->num_trans = 0;
-      }
-   }
-#endif
-
-#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
-   defined(PNG_READ_ALPHA_MODE_SUPPORTED)
-   /* The following is almost certainly wrong unless the background value is in
-    * the screen space!
-    */
-   if (png_ptr->transformations & PNG_COMPOSE)
-      info_ptr->background = png_ptr->background;
-#endif
-
-#ifdef PNG_READ_GAMMA_SUPPORTED
-   /* The following used to be conditional on PNG_GAMMA (prior to 1.5.4),
-    * however it seems that the code in png_init_read_transformations, which has
-    * been called before this from png_read_update_info->png_read_start_row
-    * sometimes does the gamma transform and cancels the flag.
-    */
-   info_ptr->gamma = png_ptr->gamma;
-#endif
-
-   if (info_ptr->bit_depth == 16)
-   {
-#  ifdef PNG_READ_16BIT_SUPPORTED
-#     ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
-         if (png_ptr->transformations & PNG_SCALE_16_TO_8)
-            info_ptr->bit_depth = 8;
-#     endif
-
-#     ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
-         if (png_ptr->transformations & PNG_16_TO_8)
-            info_ptr->bit_depth = 8;
-#     endif
-
-#  else
-      /* No 16 bit support: force chopping 16-bit input down to 8, in this case
-       * the app program can chose if both APIs are available by setting the
-       * correct scaling to use.
-       */
-#     ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
-         /* For compatibility with previous versions use the strip method by
-          * default.  This code works because if PNG_SCALE_16_TO_8 is already
-          * set the code below will do that in preference to the chop.
-          */
-         png_ptr->transformations |= PNG_16_TO_8;
-         info_ptr->bit_depth = 8;
-#     else
-
-#        ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
-            png_ptr->transformations |= PNG_SCALE_16_TO_8;
-            info_ptr->bit_depth = 8;
-#        else
-
-            CONFIGURATION ERROR: you must enable at least one 16 to 8 method
-#        endif
-#    endif
-#endif /* !READ_16BIT_SUPPORTED */
-   }
-
-#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
-   if (png_ptr->transformations & PNG_GRAY_TO_RGB)
-      info_ptr->color_type = (png_byte)(info_ptr->color_type |
-         PNG_COLOR_MASK_COLOR);
-#endif
-
-#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
-   if (png_ptr->transformations & PNG_RGB_TO_GRAY)
-      info_ptr->color_type = (png_byte)(info_ptr->color_type &
-         ~PNG_COLOR_MASK_COLOR);
-#endif
-
-#ifdef PNG_READ_QUANTIZE_SUPPORTED
-   if (png_ptr->transformations & PNG_QUANTIZE)
-   {
-      if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
-          (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) &&
-          png_ptr->palette_lookup && info_ptr->bit_depth == 8)
-      {
-         info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
-      }
-   }
-#endif
-
-#ifdef PNG_READ_EXPAND_16_SUPPORTED
-   if (png_ptr->transformations & PNG_EXPAND_16 && info_ptr->bit_depth == 8 &&
-      info_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
-   {
-      info_ptr->bit_depth = 16;
-   }
-#endif
-
-#ifdef PNG_READ_PACK_SUPPORTED
-   if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8))
-      info_ptr->bit_depth = 8;
-#endif
-
-   if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
-      info_ptr->channels = 1;
-
-   else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
-      info_ptr->channels = 3;
-
-   else
-      info_ptr->channels = 1;
-
-#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
-   if (png_ptr->transformations & PNG_STRIP_ALPHA)
-   {
-      info_ptr->color_type = (png_byte)(info_ptr->color_type &
-         ~PNG_COLOR_MASK_ALPHA);
-      info_ptr->num_trans = 0;
-   }
-#endif
-
-   if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
-      info_ptr->channels++;
-
-#ifdef PNG_READ_FILLER_SUPPORTED
-   /* STRIP_ALPHA and FILLER allowed:  MASK_ALPHA bit stripped above */
-   if ((png_ptr->transformations & PNG_FILLER) &&
-       ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
-       (info_ptr->color_type == PNG_COLOR_TYPE_GRAY)))
-   {
-      info_ptr->channels++;
-      /* If adding a true alpha channel not just filler */
-      if (png_ptr->transformations & PNG_ADD_ALPHA)
-         info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
-   }
-#endif
-
-#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \
-defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
-   if (png_ptr->transformations & PNG_USER_TRANSFORM)
-   {
-      if (info_ptr->bit_depth < png_ptr->user_transform_depth)
-         info_ptr->bit_depth = png_ptr->user_transform_depth;
-
-      if (info_ptr->channels < png_ptr->user_transform_channels)
-         info_ptr->channels = png_ptr->user_transform_channels;
-   }
-#endif
-
-   info_ptr->pixel_depth = (png_byte)(info_ptr->channels *
-       info_ptr->bit_depth);
-
-   info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, info_ptr->width);
-
-   /* Adding in 1.5.4: cache the above value in png_struct so that we can later
-    * check in png_rowbytes that the user buffer won't get overwritten.  Note
-    * that the field is not always set - if png_read_update_info isn't called
-    * the application has to either not do any transforms or get the calculation
-    * right itself.
-    */
-   png_ptr->info_rowbytes = info_ptr->rowbytes;
-
-#ifndef PNG_READ_EXPAND_SUPPORTED
-   if (png_ptr)
-      return;
-#endif
-}
-
-/* Transform the row.  The order of transformations is significant,
- * and is very touchy.  If you add a transformation, take care to
- * decide how it fits in with the other transformations here.
- */
-void /* PRIVATE */
-png_do_read_transformations(png_structp png_ptr, png_row_infop row_info)
-{
-   png_debug(1, "in png_do_read_transformations");
-
-   if (png_ptr->row_buf == NULL)
-   {
-      /* Prior to 1.5.4 this output row/pass where the NULL pointer is, but this
-       * error is incredibly rare and incredibly easy to debug without this
-       * information.
-       */
-      png_error(png_ptr, "NULL row buffer");
-   }
-
-   /* The following is debugging; prior to 1.5.4 the code was never compiled in;
-    * in 1.5.4 PNG_FLAG_DETECT_UNINITIALIZED was added and the macro
-    * PNG_WARN_UNINITIALIZED_ROW removed.  In 1.5 the new flag is set only for
-    * selected new APIs to ensure that there is no API change.
-    */
-   if ((png_ptr->flags & PNG_FLAG_DETECT_UNINITIALIZED) != 0 &&
-      !(png_ptr->flags & PNG_FLAG_ROW_INIT))
-   {
-      /* Application has failed to call either png_read_start_image() or
-       * png_read_update_info() after setting transforms that expand pixels.
-       * This check added to libpng-1.2.19 (but not enabled until 1.5.4).
-       */
-      png_error(png_ptr, "Uninitialized row");
-   }
-
-#ifdef PNG_READ_EXPAND_SUPPORTED
-   if (png_ptr->transformations & PNG_EXPAND)
-   {
-      if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)
-      {
-         png_do_expand_palette(row_info, png_ptr->row_buf + 1,
-             png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans);
-      }
-
-      else
-      {
-         if (png_ptr->num_trans &&
-             (png_ptr->transformations & PNG_EXPAND_tRNS))
-            png_do_expand(row_info, png_ptr->row_buf + 1,
-                &(png_ptr->trans_color));
-
-         else
-            png_do_expand(row_info, png_ptr->row_buf + 1,
-                NULL);
-      }
-   }
-#endif
-
-#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
-   if ((png_ptr->transformations & PNG_STRIP_ALPHA) &&
-      !(png_ptr->transformations & PNG_COMPOSE) &&
-      (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
-      row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
-      png_do_strip_channel(row_info, png_ptr->row_buf + 1,
-         0 /* at_start == false, because SWAP_ALPHA happens later */);
-#endif
-
-#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
-   if (png_ptr->transformations & PNG_RGB_TO_GRAY)
-   {
-      int rgb_error =
-          png_do_rgb_to_gray(png_ptr, row_info,
-              png_ptr->row_buf + 1);
-
-      if (rgb_error)
-      {
-         png_ptr->rgb_to_gray_status=1;
-         if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
-             PNG_RGB_TO_GRAY_WARN)
-            png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel");
-
-         if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
-             PNG_RGB_TO_GRAY_ERR)
-            png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel");
-      }
-   }
-#endif
-
-/* From Andreas Dilger e-mail to png-implement, 26 March 1998:
- *
- *   In most cases, the "simple transparency" should be done prior to doing
- *   gray-to-RGB, or you will have to test 3x as many bytes to check if a
- *   pixel is transparent.  You would also need to make sure that the
- *   transparency information is upgraded to RGB.
- *
- *   To summarize, the current flow is:
- *   - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
- *                                   with background "in place" if transparent,
- *                                   convert to RGB if necessary
- *   - Gray + alpha -> composite with gray background and remove alpha bytes,
- *                                   convert to RGB if necessary
- *
- *   To support RGB backgrounds for gray images we need:
- *   - Gray + simple transparency -> convert to RGB + simple transparency,
- *                                   compare 3 or 6 bytes and composite with
- *                                   background "in place" if transparent
- *                                   (3x compare/pixel compared to doing
- *                                   composite with gray bkgrnd)
- *   - Gray + alpha -> convert to RGB + alpha, composite with background and
- *                                   remove alpha bytes (3x float
- *                                   operations/pixel compared with composite
- *                                   on gray background)
- *
- *  Greg's change will do this.  The reason it wasn't done before is for
- *  performance, as this increases the per-pixel operations.  If we would check
- *  in advance if the background was gray or RGB, and position the gray-to-RGB
- *  transform appropriately, then it would save a lot of work/time.
- */
-
-#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
-   /* If gray -> RGB, do so now only if background is non-gray; else do later
-    * for performance reasons
-    */
-   if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
-       !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
-      png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1);
-#endif
-
-#if (defined PNG_READ_BACKGROUND_SUPPORTED) ||\
-   (defined PNG_READ_ALPHA_MODE_SUPPORTED)
-   if (png_ptr->transformations & PNG_COMPOSE)
-      png_do_compose(row_info, png_ptr->row_buf + 1, png_ptr);
-#endif
-
-#ifdef PNG_READ_GAMMA_SUPPORTED
-   if ((png_ptr->transformations & PNG_GAMMA) &&
-#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
-      /* Because RGB_TO_GRAY does the gamma transform. */
-      !(png_ptr->transformations & PNG_RGB_TO_GRAY) &&
-#endif
-#if (defined PNG_READ_BACKGROUND_SUPPORTED) ||\
-   (defined PNG_READ_ALPHA_MODE_SUPPORTED)
-      /* Because PNG_COMPOSE does the gamma transform if there is something to
-       * do (if there is an alpha channel or transparency.)
-       */
-       !((png_ptr->transformations & PNG_COMPOSE) &&
-       ((png_ptr->num_trans != 0) ||
-       (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) &&
-#endif
-      /* Because png_init_read_transformations transforms the palette, unless
-       * RGB_TO_GRAY will do the transform.
-       */
-       (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))
-      png_do_gamma(row_info, png_ptr->row_buf + 1, png_ptr);
-#endif
-
-#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
-   if ((png_ptr->transformations & PNG_STRIP_ALPHA) &&
-      (png_ptr->transformations & PNG_COMPOSE) &&
-      (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
-      row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
-      png_do_strip_channel(row_info, png_ptr->row_buf + 1,
-         0 /* at_start == false, because SWAP_ALPHA happens later */);
-#endif
-
-#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
-   if ((png_ptr->transformations & PNG_ENCODE_ALPHA) &&
-      (row_info->color_type & PNG_COLOR_MASK_ALPHA))
-      png_do_encode_alpha(row_info, png_ptr->row_buf + 1, png_ptr);
-#endif
-
-#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
-   if (png_ptr->transformations & PNG_SCALE_16_TO_8)
-      png_do_scale_16_to_8(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
-   /* There is no harm in doing both of these because only one has any effect,
-    * by putting the 'scale' option first if the app asks for scale (either by
-    * calling the API or in a TRANSFORM flag) this is what happens.
-    */
-   if (png_ptr->transformations & PNG_16_TO_8)
-      png_do_chop(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_READ_QUANTIZE_SUPPORTED
-   if (png_ptr->transformations & PNG_QUANTIZE)
-   {
-      png_do_quantize(row_info, png_ptr->row_buf + 1,
-          png_ptr->palette_lookup, png_ptr->quantize_index);
-
-      if (row_info->rowbytes == 0)
-         png_error(png_ptr, "png_do_quantize returned rowbytes=0");
-   }
-#endif /* PNG_READ_QUANTIZE_SUPPORTED */
-
-#ifdef PNG_READ_EXPAND_16_SUPPORTED
-   /* Do the expansion now, after all the arithmetic has been done.  Notice
-    * that previous transformations can handle the PNG_EXPAND_16 flag if this
-    * is efficient (particularly true in the case of gamma correction, where
-    * better accuracy results faster!)
-    */
-   if (png_ptr->transformations & PNG_EXPAND_16)
-      png_do_expand_16(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
-   /* NOTE: moved here in 1.5.4 (from much later in this list.) */
-   if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
-       (png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
-      png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_READ_INVERT_SUPPORTED
-   if (png_ptr->transformations & PNG_INVERT_MONO)
-      png_do_invert(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_READ_SHIFT_SUPPORTED
-   if (png_ptr->transformations & PNG_SHIFT)
-      png_do_unshift(row_info, png_ptr->row_buf + 1,
-          &(png_ptr->shift));
-#endif
-
-#ifdef PNG_READ_PACK_SUPPORTED
-   if (png_ptr->transformations & PNG_PACK)
-      png_do_unpack(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
-   /* Added at libpng-1.5.10 */
-   if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
-       png_ptr->num_palette_max >= 0)
-      png_do_check_palette_indexes(png_ptr, row_info);
-#endif
-
-#ifdef PNG_READ_BGR_SUPPORTED
-   if (png_ptr->transformations & PNG_BGR)
-      png_do_bgr(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_READ_PACKSWAP_SUPPORTED
-   if (png_ptr->transformations & PNG_PACKSWAP)
-      png_do_packswap(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_READ_FILLER_SUPPORTED
-   if (png_ptr->transformations & PNG_FILLER)
-      png_do_read_filler(row_info, png_ptr->row_buf + 1,
-          (png_uint_32)png_ptr->filler, png_ptr->flags);
-#endif
-
-#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
-   if (png_ptr->transformations & PNG_INVERT_ALPHA)
-      png_do_read_invert_alpha(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
-   if (png_ptr->transformations & PNG_SWAP_ALPHA)
-      png_do_read_swap_alpha(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_READ_16BIT_SUPPORTED
-#ifdef PNG_READ_SWAP_SUPPORTED
-   if (png_ptr->transformations & PNG_SWAP_BYTES)
-      png_do_swap(row_info, png_ptr->row_buf + 1);
-#endif
-#endif
-
-#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
-   if (png_ptr->transformations & PNG_USER_TRANSFORM)
-    {
-      if (png_ptr->read_user_transform_fn != NULL)
-         (*(png_ptr->read_user_transform_fn)) /* User read transform function */
-             (png_ptr,     /* png_ptr */
-             row_info,     /* row_info: */
-                /*  png_uint_32 width;       width of row */
-                /*  png_size_t rowbytes;     number of bytes in row */
-                /*  png_byte color_type;     color type of pixels */
-                /*  png_byte bit_depth;      bit depth of samples */
-                /*  png_byte channels;       number of channels (1-4) */
-                /*  png_byte pixel_depth;    bits per pixel (depth*channels) */
-             png_ptr->row_buf + 1);    /* start of pixel data for row */
-#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
-      if (png_ptr->user_transform_depth)
-         row_info->bit_depth = png_ptr->user_transform_depth;
-
-      if (png_ptr->user_transform_channels)
-         row_info->channels = png_ptr->user_transform_channels;
-#endif
-      row_info->pixel_depth = (png_byte)(row_info->bit_depth *
-          row_info->channels);
-
-      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_info->width);
-   }
-#endif
-}
-
-#ifdef PNG_READ_PACK_SUPPORTED
-/* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
- * without changing the actual values.  Thus, if you had a row with
- * a bit depth of 1, you would end up with bytes that only contained
- * the numbers 0 or 1.  If you would rather they contain 0 and 255, use
- * png_do_shift() after this.
- */
-void /* PRIVATE */
-png_do_unpack(png_row_infop row_info, png_bytep row)
-{
-   png_debug(1, "in png_do_unpack");
-
-   if (row_info->bit_depth < 8)
-   {
-      png_uint_32 i;
-      png_uint_32 row_width=row_info->width;
-
-      switch (row_info->bit_depth)
-      {
-         case 1:
-         {
-            png_bytep sp = row + (png_size_t)((row_width - 1) >> 3);
-            png_bytep dp = row + (png_size_t)row_width - 1;
-            png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07);
-            for (i = 0; i < row_width; i++)
-            {
-               *dp = (png_byte)((*sp >> shift) & 0x01);
-
-               if (shift == 7)
-               {
-                  shift = 0;
-                  sp--;
-               }
-
-               else
-                  shift++;
-
-               dp--;
-            }
-            break;
-         }
-
-         case 2:
-         {
-
-            png_bytep sp = row + (png_size_t)((row_width - 1) >> 2);
-            png_bytep dp = row + (png_size_t)row_width - 1;
-            png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
-            for (i = 0; i < row_width; i++)
-            {
-               *dp = (png_byte)((*sp >> shift) & 0x03);
-
-               if (shift == 6)
-               {
-                  shift = 0;
-                  sp--;
-               }
-
-               else
-                  shift += 2;
-
-               dp--;
-            }
-            break;
-         }
-
-         case 4:
-         {
-            png_bytep sp = row + (png_size_t)((row_width - 1) >> 1);
-            png_bytep dp = row + (png_size_t)row_width - 1;
-            png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
-            for (i = 0; i < row_width; i++)
-            {
-               *dp = (png_byte)((*sp >> shift) & 0x0f);
-
-               if (shift == 4)
-               {
-                  shift = 0;
-                  sp--;
-               }
-
-               else
-                  shift = 4;
-
-               dp--;
-            }
-            break;
-         }
-
-         default:
-            break;
-      }
-      row_info->bit_depth = 8;
-      row_info->pixel_depth = (png_byte)(8 * row_info->channels);
-      row_info->rowbytes = row_width * row_info->channels;
-   }
-}
-#endif
-
-#ifdef PNG_READ_SHIFT_SUPPORTED
-/* Reverse the effects of png_do_shift.  This routine merely shifts the
- * pixels back to their significant bits values.  Thus, if you have
- * a row of bit depth 8, but only 5 are significant, this will shift
- * the values back to 0 through 31.
- */
-void /* PRIVATE */
-png_do_unshift(png_row_infop row_info, png_bytep row,
-    png_const_color_8p sig_bits)
-{
-   int color_type;
-
-   png_debug(1, "in png_do_unshift");
-
-   /* The palette case has already been handled in the _init routine. */
-   color_type = row_info->color_type;
-
-   if (color_type != PNG_COLOR_TYPE_PALETTE)
-   {
-      int shift[4];
-      int channels = 0;
-      int bit_depth = row_info->bit_depth;
-
-      if (color_type & PNG_COLOR_MASK_COLOR)
-      {
-         shift[channels++] = bit_depth - sig_bits->red;
-         shift[channels++] = bit_depth - sig_bits->green;
-         shift[channels++] = bit_depth - sig_bits->blue;
-      }
-
-      else
-      {
-         shift[channels++] = bit_depth - sig_bits->gray;
-      }
-
-      if (color_type & PNG_COLOR_MASK_ALPHA)
-      {
-         shift[channels++] = bit_depth - sig_bits->alpha;
-      }
-
-      {
-         int c, have_shift;
-
-         for (c = have_shift = 0; c < channels; ++c)
-         {
-            /* A shift of more than the bit depth is an error condition but it
-             * gets ignored here.
-             */
-            if (shift[c] <= 0 || shift[c] >= bit_depth)
-               shift[c] = 0;
-
-            else
-               have_shift = 1;
-         }
-
-         if (!have_shift)
-            return;
-      }
-
-      switch (bit_depth)
-      {
-         default:
-         /* Must be 1bpp gray: should not be here! */
-            /* NOTREACHED */
-            break;
-
-         case 2:
-         /* Must be 2bpp gray */
-         /* assert(channels == 1 && shift[0] == 1) */
-         {
-            png_bytep bp = row;
-            png_bytep bp_end = bp + row_info->rowbytes;
-
-            while (bp < bp_end)
-            {
-               int b = (*bp >> 1) & 0x55;
-               *bp++ = (png_byte)b;
-            }
-            break;
-         }
-
-         case 4:
-         /* Must be 4bpp gray */
-         /* assert(channels == 1) */
-         {
-            png_bytep bp = row;
-            png_bytep bp_end = bp + row_info->rowbytes;
-            int gray_shift = shift[0];
-            int mask =  0xf >> gray_shift;
-
-            mask |= mask << 4;
-
-            while (bp < bp_end)
-            {
-               int b = (*bp >> gray_shift) & mask;
-               *bp++ = (png_byte)b;
-            }
-            break;
-         }
-
-         case 8:
-         /* Single byte components, G, GA, RGB, RGBA */
-         {
-            png_bytep bp = row;
-            png_bytep bp_end = bp + row_info->rowbytes;
-            int channel = 0;
-
-            while (bp < bp_end)
-            {
-               int b = *bp >> shift[channel];
-               if (++channel >= channels)
-                  channel = 0;
-               *bp++ = (png_byte)b;
-            }
-            break;
-         }
-
-#ifdef PNG_READ_16BIT_SUPPORTED
-         case 16:
-         /* Double byte components, G, GA, RGB, RGBA */
-         {
-            png_bytep bp = row;
-            png_bytep bp_end = bp + row_info->rowbytes;
-            int channel = 0;
-
-            while (bp < bp_end)
-            {
-               int value = (bp[0] << 8) + bp[1];
-
-               value >>= shift[channel];
-               if (++channel >= channels)
-                  channel = 0;
-               *bp++ = (png_byte)(value >> 8);
-               *bp++ = (png_byte)(value & 0xff);
-            }
-            break;
-         }
-#endif
-      }
-   }
-}
-#endif
-
-#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
-/* Scale rows of bit depth 16 down to 8 accurately */
-void /* PRIVATE */
-png_do_scale_16_to_8(png_row_infop row_info, png_bytep row)
-{
-   png_debug(1, "in png_do_scale_16_to_8");
-
-   if (row_info->bit_depth == 16)
-   {
-      png_bytep sp = row; /* source */
-      png_bytep dp = row; /* destination */
-      png_bytep ep = sp + row_info->rowbytes; /* end+1 */
-
-      while (sp < ep)
-      {
-         /* The input is an array of 16 bit components, these must be scaled to
-          * 8 bits each.  For a 16 bit value V the required value (from the PNG
-          * specification) is:
-          *
-          *    (V * 255) / 65535
-          *
-          * This reduces to round(V / 257), or floor((V + 128.5)/257)
-          *
-          * Represent V as the two byte value vhi.vlo.  Make a guess that the
-          * result is the top byte of V, vhi, then the correction to this value
-          * is:
-          *
-          *    error = floor(((V-vhi.vhi) + 128.5) / 257)
-          *          = floor(((vlo-vhi) + 128.5) / 257)
-          *
-          * This can be approximated using integer arithmetic (and a signed
-          * shift):
-          *
-          *    error = (vlo-vhi+128) >> 8;
-          *
-          * The approximate differs from the exact answer only when (vlo-vhi) is
-          * 128; it then gives a correction of +1 when the exact correction is
-          * 0.  This gives 128 errors.  The exact answer (correct for all 16 bit
-          * input values) is:
-          *
-          *    error = (vlo-vhi+128)*65535 >> 24;
-          *
-          * An alternative arithmetic calculation which also gives no errors is:
-          *
-          *    (V * 255 + 32895) >> 16
-          */
-
-         png_int_32 tmp = *sp++; /* must be signed! */
-         tmp += (((int)*sp++ - tmp + 128) * 65535) >> 24;
-         *dp++ = (png_byte)tmp;
-      }
-
-      row_info->bit_depth = 8;
-      row_info->pixel_depth = (png_byte)(8 * row_info->channels);
-      row_info->rowbytes = row_info->width * row_info->channels;
-   }
-}
-#endif
-
-#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
-void /* PRIVATE */
-/* Simply discard the low byte.  This was the default behavior prior
- * to libpng-1.5.4.
- */
-png_do_chop(png_row_infop row_info, png_bytep row)
-{
-   png_debug(1, "in png_do_chop");
-
-   if (row_info->bit_depth == 16)
-   {
-      png_bytep sp = row; /* source */
-      png_bytep dp = row; /* destination */
-      png_bytep ep = sp + row_info->rowbytes; /* end+1 */
-
-      while (sp < ep)
-      {
-         *dp++ = *sp;
-         sp += 2; /* skip low byte */
-      }
-
-      row_info->bit_depth = 8;
-      row_info->pixel_depth = (png_byte)(8 * row_info->channels);
-      row_info->rowbytes = row_info->width * row_info->channels;
-   }
-}
-#endif
-
-#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
-void /* PRIVATE */
-png_do_read_swap_alpha(png_row_infop row_info, png_bytep row)
-{
-   png_debug(1, "in png_do_read_swap_alpha");
-
-   {
-      png_uint_32 row_width = row_info->width;
-      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
-      {
-         /* This converts from RGBA to ARGB */
-         if (row_info->bit_depth == 8)
-         {
-            png_bytep sp = row + row_info->rowbytes;
-            png_bytep dp = sp;
-            png_byte save;
-            png_uint_32 i;
-
-            for (i = 0; i < row_width; i++)
-            {
-               save = *(--sp);
-               *(--dp) = *(--sp);
-               *(--dp) = *(--sp);
-               *(--dp) = *(--sp);
-               *(--dp) = save;
-            }
-         }
-
-#ifdef PNG_READ_16BIT_SUPPORTED
-         /* This converts from RRGGBBAA to AARRGGBB */
-         else
-         {
-            png_bytep sp = row + row_info->rowbytes;
-            png_bytep dp = sp;
-            png_byte save[2];
-            png_uint_32 i;
-
-            for (i = 0; i < row_width; i++)
-            {
-               save[0] = *(--sp);
-               save[1] = *(--sp);
-               *(--dp) = *(--sp);
-               *(--dp) = *(--sp);
-               *(--dp) = *(--sp);
-               *(--dp) = *(--sp);
-               *(--dp) = *(--sp);
-               *(--dp) = *(--sp);
-               *(--dp) = save[0];
-               *(--dp) = save[1];
-            }
-         }
-#endif
-      }
-
-      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
-      {
-         /* This converts from GA to AG */
-         if (row_info->bit_depth == 8)
-         {
-            png_bytep sp = row + row_info->rowbytes;
-            png_bytep dp = sp;
-            png_byte save;
-            png_uint_32 i;
-
-            for (i = 0; i < row_width; i++)
-            {
-               save = *(--sp);
-               *(--dp) = *(--sp);
-               *(--dp) = save;
-            }
-         }
-
-#ifdef PNG_READ_16BIT_SUPPORTED
-         /* This converts from GGAA to AAGG */
-         else
-         {
-            png_bytep sp = row + row_info->rowbytes;
-            png_bytep dp = sp;
-            png_byte save[2];
-            png_uint_32 i;
-
-            for (i = 0; i < row_width; i++)
-            {
-               save[0] = *(--sp);
-               save[1] = *(--sp);
-               *(--dp) = *(--sp);
-               *(--dp) = *(--sp);
-               *(--dp) = save[0];
-               *(--dp) = save[1];
-            }
-         }
-#endif
-      }
-   }
-}
-#endif
-
-#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
-void /* PRIVATE */
-png_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
-{
-   png_uint_32 row_width;
-   png_debug(1, "in png_do_read_invert_alpha");
-
-   row_width = row_info->width;
-   if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
-   {
-      if (row_info->bit_depth == 8)
-      {
-         /* This inverts the alpha channel in RGBA */
-         png_bytep sp = row + row_info->rowbytes;
-         png_bytep dp = sp;
-         png_uint_32 i;
-
-         for (i = 0; i < row_width; i++)
-         {
-            *(--dp) = (png_byte)(255 - *(--sp));
-
-/*          This does nothing:
-            *(--dp) = *(--sp);
-            *(--dp) = *(--sp);
-            *(--dp) = *(--sp);
-            We can replace it with:
-*/
-            sp-=3;
-            dp=sp;
-         }
-      }
-
-#ifdef PNG_READ_16BIT_SUPPORTED
-      /* This inverts the alpha channel in RRGGBBAA */
-      else
-      {
-         png_bytep sp = row + row_info->rowbytes;
-         png_bytep dp = sp;
-         png_uint_32 i;
-
-         for (i = 0; i < row_width; i++)
-         {
-            *(--dp) = (png_byte)(255 - *(--sp));
-            *(--dp) = (png_byte)(255 - *(--sp));
-
-/*          This does nothing:
-            *(--dp) = *(--sp);
-            *(--dp) = *(--sp);
-            *(--dp) = *(--sp);
-            *(--dp) = *(--sp);
-            *(--dp) = *(--sp);
-            *(--dp) = *(--sp);
-            We can replace it with:
-*/
-            sp-=6;
-            dp=sp;
-         }
-      }
-#endif
-   }
-   else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
-   {
-      if (row_info->bit_depth == 8)
-      {
-         /* This inverts the alpha channel in GA */
-         png_bytep sp = row + row_info->rowbytes;
-         png_bytep dp = sp;
-         png_uint_32 i;
-
-         for (i = 0; i < row_width; i++)
-         {
-            *(--dp) = (png_byte)(255 - *(--sp));
-            *(--dp) = *(--sp);
-         }
-      }
-
-#ifdef PNG_READ_16BIT_SUPPORTED
-      else
-      {
-         /* This inverts the alpha channel in GGAA */
-         png_bytep sp  = row + row_info->rowbytes;
-         png_bytep dp = sp;
-         png_uint_32 i;
-
-         for (i = 0; i < row_width; i++)
-         {
-            *(--dp) = (png_byte)(255 - *(--sp));
-            *(--dp) = (png_byte)(255 - *(--sp));
-/*
-            *(--dp) = *(--sp);
-            *(--dp) = *(--sp);
-*/
-            sp-=2;
-            dp=sp;
-         }
-      }
-#endif
-   }
-}
-#endif
-
-#ifdef PNG_READ_FILLER_SUPPORTED
-/* Add filler channel if we have RGB color */
-void /* PRIVATE */
-png_do_read_filler(png_row_infop row_info, png_bytep row,
-    png_uint_32 filler, png_uint_32 flags)
-{
-   png_uint_32 i;
-   png_uint_32 row_width = row_info->width;
-
-#ifdef PNG_READ_16BIT_SUPPORTED
-   png_byte hi_filler = (png_byte)((filler>>8) & 0xff);
-#endif
-   png_byte lo_filler = (png_byte)(filler & 0xff);
-
-   png_debug(1, "in png_do_read_filler");
-
-   if (
-       row_info->color_type == PNG_COLOR_TYPE_GRAY)
-   {
-      if (row_info->bit_depth == 8)
-      {
-         if (flags & PNG_FLAG_FILLER_AFTER)
-         {
-            /* This changes the data from G to GX */
-            png_bytep sp = row + (png_size_t)row_width;
-            png_bytep dp =  sp + (png_size_t)row_width;
-            for (i = 1; i < row_width; i++)
-            {
-               *(--dp) = lo_filler;
-               *(--dp) = *(--sp);
-            }
-            *(--dp) = lo_filler;
-            row_info->channels = 2;
-            row_info->pixel_depth = 16;
-            row_info->rowbytes = row_width * 2;
-         }
-
-         else
-         {
-            /* This changes the data from G to XG */
-            png_bytep sp = row + (png_size_t)row_width;
-            png_bytep dp = sp  + (png_size_t)row_width;
-            for (i = 0; i < row_width; i++)
-            {
-               *(--dp) = *(--sp);
-               *(--dp) = lo_filler;
-            }
-            row_info->channels = 2;
-            row_info->pixel_depth = 16;
-            row_info->rowbytes = row_width * 2;
-         }
-      }
-
-#ifdef PNG_READ_16BIT_SUPPORTED
-      else if (row_info->bit_depth == 16)
-      {
-         if (flags & PNG_FLAG_FILLER_AFTER)
-         {
-            /* This changes the data from GG to GGXX */
-            png_bytep sp = row + (png_size_t)row_width * 2;
-            png_bytep dp = sp  + (png_size_t)row_width * 2;
-            for (i = 1; i < row_width; i++)
-            {
-               *(--dp) = hi_filler;
-               *(--dp) = lo_filler;
-               *(--dp) = *(--sp);
-               *(--dp) = *(--sp);
-            }
-            *(--dp) = hi_filler;
-            *(--dp) = lo_filler;
-            row_info->channels = 2;
-            row_info->pixel_depth = 32;
-            row_info->rowbytes = row_width * 4;
-         }
-
-         else
-         {
-            /* This changes the data from GG to XXGG */
-            png_bytep sp = row + (png_size_t)row_width * 2;
-            png_bytep dp = sp  + (png_size_t)row_width * 2;
-            for (i = 0; i < row_width; i++)
-            {
-               *(--dp) = *(--sp);
-               *(--dp) = *(--sp);
-               *(--dp) = hi_filler;
-               *(--dp) = lo_filler;
-            }
-            row_info->channels = 2;
-            row_info->pixel_depth = 32;
-            row_info->rowbytes = row_width * 4;
-         }
-      }
-#endif
-   } /* COLOR_TYPE == GRAY */
-   else if (row_info->color_type == PNG_COLOR_TYPE_RGB)
-   {
-      if (row_info->bit_depth == 8)
-      {
-         if (flags & PNG_FLAG_FILLER_AFTER)
-         {
-            /* This changes the data from RGB to RGBX */
-            png_bytep sp = row + (png_size_t)row_width * 3;
-            png_bytep dp = sp  + (png_size_t)row_width;
-            for (i = 1; i < row_width; i++)
-            {
-               *(--dp) = lo_filler;
-               *(--dp) = *(--sp);
-               *(--dp) = *(--sp);
-               *(--dp) = *(--sp);
-            }
-            *(--dp) = lo_filler;
-            row_info->channels = 4;
-            row_info->pixel_depth = 32;
-            row_info->rowbytes = row_width * 4;
-         }
-
-         else
-         {
-            /* This changes the data from RGB to XRGB */
-            png_bytep sp = row + (png_size_t)row_width * 3;
-            png_bytep dp = sp + (png_size_t)row_width;
-            for (i = 0; i < row_width; i++)
-            {
-               *(--dp) = *(--sp);
-               *(--dp) = *(--sp);
-               *(--dp) = *(--sp);
-               *(--dp) = lo_filler;
-            }
-            row_info->channels = 4;
-            row_info->pixel_depth = 32;
-            row_info->rowbytes = row_width * 4;
-         }
-      }
-
-#ifdef PNG_READ_16BIT_SUPPORTED
-      else if (row_info->bit_depth == 16)
-      {
-         if (flags & PNG_FLAG_FILLER_AFTER)
-         {
-            /* This changes the data from RRGGBB to RRGGBBXX */
-            png_bytep sp = row + (png_size_t)row_width * 6;
-            png_bytep dp = sp  + (png_size_t)row_width * 2;
-            for (i = 1; i < row_width; i++)
-            {
-               *(--dp) = hi_filler;
-               *(--dp) = lo_filler;
-               *(--dp) = *(--sp);
-               *(--dp) = *(--sp);
-               *(--dp) = *(--sp);
-               *(--dp) = *(--sp);
-               *(--dp) = *(--sp);
-               *(--dp) = *(--sp);
-            }
-            *(--dp) = hi_filler;
-            *(--dp) = lo_filler;
-            row_info->channels = 4;
-            row_info->pixel_depth = 64;
-            row_info->rowbytes = row_width * 8;
-         }
-
-         else
-         {
-            /* This changes the data from RRGGBB to XXRRGGBB */
-            png_bytep sp = row + (png_size_t)row_width * 6;
-            png_bytep dp = sp  + (png_size_t)row_width * 2;
-            for (i = 0; i < row_width; i++)
-            {
-               *(--dp) = *(--sp);
-               *(--dp) = *(--sp);
-               *(--dp) = *(--sp);
-               *(--dp) = *(--sp);
-               *(--dp) = *(--sp);
-               *(--dp) = *(--sp);
-               *(--dp) = hi_filler;
-               *(--dp) = lo_filler;
-            }
-
-            row_info->channels = 4;
-            row_info->pixel_depth = 64;
-            row_info->rowbytes = row_width * 8;
-         }
-      }
-#endif
-   } /* COLOR_TYPE == RGB */
-}
-#endif
-
-#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
-/* Expand grayscale files to RGB, with or without alpha */
-void /* PRIVATE */
-png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
-{
-   png_uint_32 i;
-   png_uint_32 row_width = row_info->width;
-
-   png_debug(1, "in png_do_gray_to_rgb");
-
-   if (row_info->bit_depth >= 8 &&
-       !(row_info->color_type & PNG_COLOR_MASK_COLOR))
-   {
-      if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
-      {
-         if (row_info->bit_depth == 8)
-         {
-            /* This changes G to RGB */
-            png_bytep sp = row + (png_size_t)row_width - 1;
-            png_bytep dp = sp  + (png_size_t)row_width * 2;
-            for (i = 0; i < row_width; i++)
-            {
-               *(dp--) = *sp;
-               *(dp--) = *sp;
-               *(dp--) = *(sp--);
-            }
-         }
-
-         else
-         {
-            /* This changes GG to RRGGBB */
-            png_bytep sp = row + (png_size_t)row_width * 2 - 1;
-            png_bytep dp = sp  + (png_size_t)row_width * 4;
-            for (i = 0; i < row_width; i++)
-            {
-               *(dp--) = *sp;
-               *(dp--) = *(sp - 1);
-               *(dp--) = *sp;
-               *(dp--) = *(sp - 1);
-               *(dp--) = *(sp--);
-               *(dp--) = *(sp--);
-            }
-         }
-      }
-
-      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
-      {
-         if (row_info->bit_depth == 8)
-         {
-            /* This changes GA to RGBA */
-            png_bytep sp = row + (png_size_t)row_width * 2 - 1;
-            png_bytep dp = sp  + (png_size_t)row_width * 2;
-            for (i = 0; i < row_width; i++)
-            {
-               *(dp--) = *(sp--);
-               *(dp--) = *sp;
-               *(dp--) = *sp;
-               *(dp--) = *(sp--);
-            }
-         }
-
-         else
-         {
-            /* This changes GGAA to RRGGBBAA */
-            png_bytep sp = row + (png_size_t)row_width * 4 - 1;
-            png_bytep dp = sp  + (png_size_t)row_width * 4;
-            for (i = 0; i < row_width; i++)
-            {
-               *(dp--) = *(sp--);
-               *(dp--) = *(sp--);
-               *(dp--) = *sp;
-               *(dp--) = *(sp - 1);
-               *(dp--) = *sp;
-               *(dp--) = *(sp - 1);
-               *(dp--) = *(sp--);
-               *(dp--) = *(sp--);
-            }
-         }
-      }
-      row_info->channels = (png_byte)(row_info->channels + 2);
-      row_info->color_type |= PNG_COLOR_MASK_COLOR;
-      row_info->pixel_depth = (png_byte)(row_info->channels *
-          row_info->bit_depth);
-      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
-   }
-}
-#endif
-
-#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
-/* Reduce RGB files to grayscale, with or without alpha
- * using the equation given in Poynton's ColorFAQ of 1998-01-04 at
- * <http://www.inforamp.net/~poynton/>  (THIS LINK IS DEAD June 2008 but
- * versions dated 1998 through November 2002 have been archived at
- * http://web.archive.org/web/20000816232553/http://www.inforamp.net/
- * ~poynton/notes/colour_and_gamma/ColorFAQ.txt )
- * Charles Poynton poynton at poynton.com
- *
- *     Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
- *
- *  which can be expressed with integers as
- *
- *     Y = (6969 * R + 23434 * G + 2365 * B)/32768
- *
- * Poynton's current link (as of January 2003 through July 2011):
- * <http://www.poynton.com/notes/colour_and_gamma/>
- * has changed the numbers slightly:
- *
- *     Y = 0.2126*R + 0.7152*G + 0.0722*B
- *
- *  which can be expressed with integers as
- *
- *     Y = (6966 * R + 23436 * G + 2366 * B)/32768
- *
- *  Historically, however, libpng uses numbers derived from the ITU-R Rec 709
- *  end point chromaticities and the D65 white point.  Depending on the
- *  precision used for the D65 white point this produces a variety of different
- *  numbers, however if the four decimal place value used in ITU-R Rec 709 is
- *  used (0.3127,0.3290) the Y calculation would be:
- *
- *     Y = (6968 * R + 23435 * G + 2366 * B)/32768
- *
- *  While this is correct the rounding results in an overflow for white, because
- *  the sum of the rounded coefficients is 32769, not 32768.  Consequently
- *  libpng uses, instead, the closest non-overflowing approximation:
- *
- *     Y = (6968 * R + 23434 * G + 2366 * B)/32768
- *
- *  Starting with libpng-1.5.5, if the image being converted has a cHRM chunk
- *  (including an sRGB chunk) then the chromaticities are used to calculate the
- *  coefficients.  See the chunk handling in pngrutil.c for more information.
- *
- *  In all cases the calculation is to be done in a linear colorspace.  If no
- *  gamma information is available to correct the encoding of the original RGB
- *  values this results in an implicit assumption that the original PNG RGB
- *  values were linear.
- *
- *  Other integer coefficents can be used via png_set_rgb_to_gray().  Because
- *  the API takes just red and green coefficients the blue coefficient is
- *  calculated to make the sum 32768.  This will result in different rounding
- *  to that used above.
- */
-int /* PRIVATE */
-png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
-
-{
-   int rgb_error = 0;
-
-   png_debug(1, "in png_do_rgb_to_gray");
-
-   if (!(row_info->color_type & PNG_COLOR_MASK_PALETTE) &&
-       (row_info->color_type & PNG_COLOR_MASK_COLOR))
-   {
-      PNG_CONST png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;
-      PNG_CONST png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff;
-      PNG_CONST png_uint_32 bc = 32768 - rc - gc;
-      PNG_CONST png_uint_32 row_width = row_info->width;
-      PNG_CONST int have_alpha =
-         (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0;
-
-      if (row_info->bit_depth == 8)
-      {
-#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
-         /* Notice that gamma to/from 1 are not necessarily inverses (if
-          * there is an overall gamma correction).  Prior to 1.5.5 this code
-          * checked the linearized values for equality; this doesn't match
-          * the documentation, the original values must be checked.
-          */
-         if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
-         {
-            png_bytep sp = row;
-            png_bytep dp = row;
-            png_uint_32 i;
-
-            for (i = 0; i < row_width; i++)
-            {
-               png_byte red   = *(sp++);
-               png_byte green = *(sp++);
-               png_byte blue  = *(sp++);
-
-               if (red != green || red != blue)
-               {
-                  red = png_ptr->gamma_to_1[red];
-                  green = png_ptr->gamma_to_1[green];
-                  blue = png_ptr->gamma_to_1[blue];
-
-                  rgb_error |= 1;
-                  *(dp++) = png_ptr->gamma_from_1[
-                      (rc*red + gc*green + bc*blue + 16384)>>15];
-               }
-
-               else
-               {
-                  /* If there is no overall correction the table will not be
-                   * set.
-                   */
-                  if (png_ptr->gamma_table != NULL)
-                     red = png_ptr->gamma_table[red];
-
-                  *(dp++) = red;
-               }
-
-               if (have_alpha)
-                  *(dp++) = *(sp++);
-            }
-         }
-         else
-#endif
-         {
-            png_bytep sp = row;
-            png_bytep dp = row;
-            png_uint_32 i;
-
-            for (i = 0; i < row_width; i++)
-            {
-               png_byte red   = *(sp++);
-               png_byte green = *(sp++);
-               png_byte blue  = *(sp++);
-
-               if (red != green || red != blue)
-               {
-                  rgb_error |= 1;
-                  /* NOTE: this is the historical approach which simply
-                   * truncates the results.
-                   */
-                  *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15);
-               }
-
-               else
-                  *(dp++) = red;
-
-               if (have_alpha)
-                  *(dp++) = *(sp++);
-            }
-         }
-      }
-
-      else /* RGB bit_depth == 16 */
-      {
-#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
-         if (png_ptr->gamma_16_to_1 != NULL && png_ptr->gamma_16_from_1 != NULL)
-         {
-            png_bytep sp = row;
-            png_bytep dp = row;
-            png_uint_32 i;
-
-            for (i = 0; i < row_width; i++)
-            {
-               png_uint_16 red, green, blue, w;
-
-               red   = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;
-               green = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;
-               blue  = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;
-
-               if (red == green && red == blue)
-               {
-                  if (png_ptr->gamma_16_table != NULL)
-                     w = png_ptr->gamma_16_table[(red&0xff)
-                         >> png_ptr->gamma_shift][red>>8];
-
-                  else
-                     w = red;
-               }
-
-               else
-               {
-                  png_uint_16 red_1   = png_ptr->gamma_16_to_1[(red&0xff)
-                      >> png_ptr->gamma_shift][red>>8];
-                  png_uint_16 green_1 =
-                      png_ptr->gamma_16_to_1[(green&0xff) >>
-                      png_ptr->gamma_shift][green>>8];
-                  png_uint_16 blue_1  = png_ptr->gamma_16_to_1[(blue&0xff)
-                      >> png_ptr->gamma_shift][blue>>8];
-                  png_uint_16 gray16  = (png_uint_16)((rc*red_1 + gc*green_1
-                      + bc*blue_1 + 16384)>>15);
-                  w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
-                      png_ptr->gamma_shift][gray16 >> 8];
-                  rgb_error |= 1;
-               }
-
-               *(dp++) = (png_byte)((w>>8) & 0xff);
-               *(dp++) = (png_byte)(w & 0xff);
-
-               if (have_alpha)
-               {
-                  *(dp++) = *(sp++);
-                  *(dp++) = *(sp++);
-               }
-            }
-         }
-         else
-#endif
-         {
-            png_bytep sp = row;
-            png_bytep dp = row;
-            png_uint_32 i;
-
-            for (i = 0; i < row_width; i++)
-            {
-               png_uint_16 red, green, blue, gray16;
-
-               red   = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;
-               green = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;
-               blue  = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;
-
-               if (red != green || red != blue)
-                  rgb_error |= 1;
-
-               /* From 1.5.5 in the 16 bit case do the accurate conversion even
-                * in the 'fast' case - this is because this is where the code
-                * ends up when handling linear 16 bit data.
-                */
-               gray16  = (png_uint_16)((rc*red + gc*green + bc*blue + 16384) >>
-                  15);
-               *(dp++) = (png_byte)((gray16>>8) & 0xff);
-               *(dp++) = (png_byte)(gray16 & 0xff);
-
-               if (have_alpha)
-               {
-                  *(dp++) = *(sp++);
-                  *(dp++) = *(sp++);
-               }
-            }
-         }
-      }
-
-      row_info->channels = (png_byte)(row_info->channels - 2);
-      row_info->color_type = (png_byte)(row_info->color_type &
-          ~PNG_COLOR_MASK_COLOR);
-      row_info->pixel_depth = (png_byte)(row_info->channels *
-          row_info->bit_depth);
-      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
-   }
-   return rgb_error;
-}
-#endif
-#endif /* PNG_READ_TRANSFORMS_SUPPORTED */
-
-#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED
-/* Build a grayscale palette.  Palette is assumed to be 1 << bit_depth
- * large of png_color.  This lets grayscale images be treated as
- * paletted.  Most useful for gamma correction and simplification
- * of code.  This API is not used internally.
- */
-void PNGAPI
-png_build_grayscale_palette(int bit_depth, png_colorp palette)
-{
-   int num_palette;
-   int color_inc;
-   int i;
-   int v;
-
-   png_debug(1, "in png_do_build_grayscale_palette");
-
-   if (palette == NULL)
-      return;
-
-   switch (bit_depth)
-   {
-      case 1:
-         num_palette = 2;
-         color_inc = 0xff;
-         break;
-
-      case 2:
-         num_palette = 4;
-         color_inc = 0x55;
-         break;
-
-      case 4:
-         num_palette = 16;
-         color_inc = 0x11;
-         break;
-
-      case 8:
-         num_palette = 256;
-         color_inc = 1;
-         break;
-
-      default:
-         num_palette = 0;
-         color_inc = 0;
-         break;
-   }
-
-   for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
-   {
-      palette[i].red = (png_byte)v;
-      palette[i].green = (png_byte)v;
-      palette[i].blue = (png_byte)v;
-   }
-}
-#endif
-
-
-#ifdef PNG_READ_TRANSFORMS_SUPPORTED
-#if (defined PNG_READ_BACKGROUND_SUPPORTED) ||\
-   (defined PNG_READ_ALPHA_MODE_SUPPORTED)
-/* Replace any alpha or transparency with the supplied background color.
- * "background" is already in the screen gamma, while "background_1" is
- * at a gamma of 1.0.  Paletted files have already been taken care of.
- */
-void /* PRIVATE */
-png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr)
-{
-#ifdef PNG_READ_GAMMA_SUPPORTED
-   png_const_bytep gamma_table = png_ptr->gamma_table;
-   png_const_bytep gamma_from_1 = png_ptr->gamma_from_1;
-   png_const_bytep gamma_to_1 = png_ptr->gamma_to_1;
-   png_const_uint_16pp gamma_16 = png_ptr->gamma_16_table;
-   png_const_uint_16pp gamma_16_from_1 = png_ptr->gamma_16_from_1;
-   png_const_uint_16pp gamma_16_to_1 = png_ptr->gamma_16_to_1;
-   int gamma_shift = png_ptr->gamma_shift;
-#endif
-
-   png_bytep sp;
-   png_uint_32 i;
-   png_uint_32 row_width = row_info->width;
-   int optimize = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0;
-   int shift;
-
-   png_debug(1, "in png_do_compose");
-
-   {
-      switch (row_info->color_type)
-      {
-         case PNG_COLOR_TYPE_GRAY:
-         {
-            switch (row_info->bit_depth)
-            {
-               case 1:
-               {
-                  sp = row;
-                  shift = 7;
-                  for (i = 0; i < row_width; i++)
-                  {
-                     if ((png_uint_16)((*sp >> shift) & 0x01)
-                        == png_ptr->trans_color.gray)
-                     {
-                        *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
-                        *sp |= (png_byte)(png_ptr->background.gray << shift);
-                     }
-
-                     if (!shift)
-                     {
-                        shift = 7;
-                        sp++;
-                     }
-
-                     else
-                        shift--;
-                  }
-                  break;
-               }
-
-               case 2:
-               {
-#ifdef PNG_READ_GAMMA_SUPPORTED
-                  if (gamma_table != NULL)
-                  {
-                     sp = row;
-                     shift = 6;
-                     for (i = 0; i < row_width; i++)
-                     {
-                        if ((png_uint_16)((*sp >> shift) & 0x03)
-                            == png_ptr->trans_color.gray)
-                        {
-                           *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
-                           *sp |= (png_byte)(png_ptr->background.gray << shift);
-                        }
-
-                        else
-                        {
-                           png_byte p = (png_byte)((*sp >> shift) & 0x03);
-                           png_byte g = (png_byte)((gamma_table [p | (p << 2) |
-                               (p << 4) | (p << 6)] >> 6) & 0x03);
-                           *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
-                           *sp |= (png_byte)(g << shift);
-                        }
-
-                        if (!shift)
-                        {
-                           shift = 6;
-                           sp++;
-                        }
-
-                        else
-                           shift -= 2;
-                     }
-                  }
-
-                  else
-#endif
-                  {
-                     sp = row;
-                     shift = 6;
-                     for (i = 0; i < row_width; i++)
-                     {
-                        if ((png_uint_16)((*sp >> shift) & 0x03)
-                            == png_ptr->trans_color.gray)
-                        {
-                           *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
-                           *sp |= (png_byte)(png_ptr->background.gray << shift);
-                        }
-
-                        if (!shift)
-                        {
-                           shift = 6;
-                           sp++;
-                        }
-
-                        else
-                           shift -= 2;
-                     }
-                  }
-                  break;
-               }
-
-               case 4:
-               {
-#ifdef PNG_READ_GAMMA_SUPPORTED
-                  if (gamma_table != NULL)
-                  {
-                     sp = row;
-                     shift = 4;
-                     for (i = 0; i < row_width; i++)
-                     {
-                        if ((png_uint_16)((*sp >> shift) & 0x0f)
-                            == png_ptr->trans_color.gray)
-                        {
-                           *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
-                           *sp |= (png_byte)(png_ptr->background.gray << shift);
-                        }
-
-                        else
-                        {
-                           png_byte p = (png_byte)((*sp >> shift) & 0x0f);
-                           png_byte g = (png_byte)((gamma_table[p |
-                               (p << 4)] >> 4) & 0x0f);
-                           *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
-                           *sp |= (png_byte)(g << shift);
-                        }
-
-                        if (!shift)
-                        {
-                           shift = 4;
-                           sp++;
-                        }
-
-                        else
-                           shift -= 4;
-                     }
-                  }
-
-                  else
-#endif
-                  {
-                     sp = row;
-                     shift = 4;
-                     for (i = 0; i < row_width; i++)
-                     {
-                        if ((png_uint_16)((*sp >> shift) & 0x0f)
-                            == png_ptr->trans_color.gray)
-                        {
-                           *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
-                           *sp |= (png_byte)(png_ptr->background.gray << shift);
-                        }
-
-                        if (!shift)
-                        {
-                           shift = 4;
-                           sp++;
-                        }
-
-                        else
-                           shift -= 4;
-                     }
-                  }
-                  break;
-               }
-
-               case 8:
-               {
-#ifdef PNG_READ_GAMMA_SUPPORTED
-                  if (gamma_table != NULL)
-                  {
-                     sp = row;
-                     for (i = 0; i < row_width; i++, sp++)
-                     {
-                        if (*sp == png_ptr->trans_color.gray)
-                           *sp = (png_byte)png_ptr->background.gray;
-
-                        else
-                           *sp = gamma_table[*sp];
-                     }
-                  }
-                  else
-#endif
-                  {
-                     sp = row;
-                     for (i = 0; i < row_width; i++, sp++)
-                     {
-                        if (*sp == png_ptr->trans_color.gray)
-                           *sp = (png_byte)png_ptr->background.gray;
-                     }
-                  }
-                  break;
-               }
-
-               case 16:
-               {
-#ifdef PNG_READ_GAMMA_SUPPORTED
-                  if (gamma_16 != NULL)
-                  {
-                     sp = row;
-                     for (i = 0; i < row_width; i++, sp += 2)
-                     {
-                        png_uint_16 v;
-
-                        v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
-
-                        if (v == png_ptr->trans_color.gray)
-                        {
-                           /* Background is already in screen gamma */
-                           *sp = (png_byte)((png_ptr->background.gray >> 8)
-                                & 0xff);
-                           *(sp + 1) = (png_byte)(png_ptr->background.gray
-                                & 0xff);
-                        }
-
-                        else
-                        {
-                           v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
-                           *sp = (png_byte)((v >> 8) & 0xff);
-                           *(sp + 1) = (png_byte)(v & 0xff);
-                        }
-                     }
-                  }
-                  else
-#endif
-                  {
-                     sp = row;
-                     for (i = 0; i < row_width; i++, sp += 2)
-                     {
-                        png_uint_16 v;
-
-                        v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
-
-                        if (v == png_ptr->trans_color.gray)
-                        {
-                           *sp = (png_byte)((png_ptr->background.gray >> 8)
-                                & 0xff);
-                           *(sp + 1) = (png_byte)(png_ptr->background.gray
-                                & 0xff);
-                        }
-                     }
-                  }
-                  break;
-               }
-
-               default:
-                  break;
-            }
-            break;
-         }
-
-         case PNG_COLOR_TYPE_RGB:
-         {
-            if (row_info->bit_depth == 8)
-            {
-#ifdef PNG_READ_GAMMA_SUPPORTED
-               if (gamma_table != NULL)
-               {
-                  sp = row;
-                  for (i = 0; i < row_width; i++, sp += 3)
-                  {
-                     if (*sp == png_ptr->trans_color.red &&
-                         *(sp + 1) == png_ptr->trans_color.green &&
-                         *(sp + 2) == png_ptr->trans_color.blue)
-                     {
-                        *sp = (png_byte)png_ptr->background.red;
-                        *(sp + 1) = (png_byte)png_ptr->background.green;
-                        *(sp + 2) = (png_byte)png_ptr->background.blue;
-                     }
-
-                     else
-                     {
-                        *sp = gamma_table[*sp];
-                        *(sp + 1) = gamma_table[*(sp + 1)];
-                        *(sp + 2) = gamma_table[*(sp + 2)];
-                     }
-                  }
-               }
-               else
-#endif
-               {
-                  sp = row;
-                  for (i = 0; i < row_width; i++, sp += 3)
-                  {
-                     if (*sp == png_ptr->trans_color.red &&
-                         *(sp + 1) == png_ptr->trans_color.green &&
-                         *(sp + 2) == png_ptr->trans_color.blue)
-                     {
-                        *sp = (png_byte)png_ptr->background.red;
-                        *(sp + 1) = (png_byte)png_ptr->background.green;
-                        *(sp + 2) = (png_byte)png_ptr->background.blue;
-                     }
-                  }
-               }
-            }
-            else /* if (row_info->bit_depth == 16) */
-            {
-#ifdef PNG_READ_GAMMA_SUPPORTED
-               if (gamma_16 != NULL)
-               {
-                  sp = row;
-                  for (i = 0; i < row_width; i++, sp += 6)
-                  {
-                     png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
-
-                     png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
-                         + *(sp + 3));
-
-                     png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
-                         + *(sp + 5));
-
-                     if (r == png_ptr->trans_color.red &&
-                         g == png_ptr->trans_color.green &&
-                         b == png_ptr->trans_color.blue)
-                     {
-                        /* Background is already in screen gamma */
-                        *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
-                        *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
-                        *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
-                                & 0xff);
-                        *(sp + 3) = (png_byte)(png_ptr->background.green
-                                & 0xff);
-                        *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
-                                & 0xff);
-                        *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
-                     }
-
-                     else
-                     {
-                        png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
-                        *sp = (png_byte)((v >> 8) & 0xff);
-                        *(sp + 1) = (png_byte)(v & 0xff);
-
-                        v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
-                        *(sp + 2) = (png_byte)((v >> 8) & 0xff);
-                        *(sp + 3) = (png_byte)(v & 0xff);
-
-                        v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
-                        *(sp + 4) = (png_byte)((v >> 8) & 0xff);
-                        *(sp + 5) = (png_byte)(v & 0xff);
-                     }
-                  }
-               }
-
-               else
-#endif
-               {
-                  sp = row;
-                  for (i = 0; i < row_width; i++, sp += 6)
-                  {
-                     png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
-
-                     png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
-                         + *(sp + 3));
-
-                     png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
-                         + *(sp + 5));
-
-                     if (r == png_ptr->trans_color.red &&
-                         g == png_ptr->trans_color.green &&
-                         b == png_ptr->trans_color.blue)
-                     {
-                        *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
-                        *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
-                        *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
-                                & 0xff);
-                        *(sp + 3) = (png_byte)(png_ptr->background.green
-                                & 0xff);
-                        *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
-                                & 0xff);
-                        *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
-                     }
-                  }
-               }
-            }
-            break;
-         }
-
-         case PNG_COLOR_TYPE_GRAY_ALPHA:
-         {
-            if (row_info->bit_depth == 8)
-            {
-#ifdef PNG_READ_GAMMA_SUPPORTED
-               if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
-                   gamma_table != NULL)
-               {
-                  sp = row;
-                  for (i = 0; i < row_width; i++, sp += 2)
-                  {
-                     png_uint_16 a = *(sp + 1);
-
-                     if (a == 0xff)
-                        *sp = gamma_table[*sp];
-
-                     else if (a == 0)
-                     {
-                        /* Background is already in screen gamma */
-                        *sp = (png_byte)png_ptr->background.gray;
-                     }
-
-                     else
-                     {
-                        png_byte v, w;
-
-                        v = gamma_to_1[*sp];
-                        png_composite(w, v, a, png_ptr->background_1.gray);
-                        if (!optimize)
-                           w = gamma_from_1[w];
-                        *sp = w;
-                     }
-                  }
-               }
-               else
-#endif
-               {
-                  sp = row;
-                  for (i = 0; i < row_width; i++, sp += 2)
-                  {
-                     png_byte a = *(sp + 1);
-
-                     if (a == 0)
-                        *sp = (png_byte)png_ptr->background.gray;
-
-                     else if (a < 0xff)
-                        png_composite(*sp, *sp, a, png_ptr->background_1.gray);
-                  }
-               }
-            }
-            else /* if (png_ptr->bit_depth == 16) */
-            {
-#ifdef PNG_READ_GAMMA_SUPPORTED
-               if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
-                   gamma_16_to_1 != NULL)
-               {
-                  sp = row;
-                  for (i = 0; i < row_width; i++, sp += 4)
-                  {
-                     png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8)
-                         + *(sp + 3));
-
-                     if (a == (png_uint_16)0xffff)
-                     {
-                        png_uint_16 v;
-
-                        v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
-                        *sp = (png_byte)((v >> 8) & 0xff);
-                        *(sp + 1) = (png_byte)(v & 0xff);
-                     }
-
-                     else if (a == 0)
-                     {
-                        /* Background is already in screen gamma */
-                        *sp = (png_byte)((png_ptr->background.gray >> 8)
-                                & 0xff);
-                        *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff);
-                     }
-
-                     else
-                     {
-                        png_uint_16 g, v, w;
-
-                        g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
-                        png_composite_16(v, g, a, png_ptr->background_1.gray);
-                        if (optimize)
-                           w = v;
-                        else
-                           w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8];
-                        *sp = (png_byte)((w >> 8) & 0xff);
-                        *(sp + 1) = (png_byte)(w & 0xff);
-                     }
-                  }
-               }
-               else
-#endif
-               {
-                  sp = row;
-                  for (i = 0; i < row_width; i++, sp += 4)
-                  {
-                     png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8)
-                         + *(sp + 3));
-
-                     if (a == 0)
-                     {
-                        *sp = (png_byte)((png_ptr->background.gray >> 8)
-                                & 0xff);
-                        *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff);
-                     }
-
-                     else if (a < 0xffff)
-                     {
-                        png_uint_16 g, v;
-
-                        g = (png_uint_16)(((*sp) << 8) + *(sp + 1));
-                        png_composite_16(v, g, a, png_ptr->background_1.gray);
-                        *sp = (png_byte)((v >> 8) & 0xff);
-                        *(sp + 1) = (png_byte)(v & 0xff);
-                     }
-                  }
-               }
-            }
-            break;
-         }
-
-         case PNG_COLOR_TYPE_RGB_ALPHA:
-         {
-            if (row_info->bit_depth == 8)
-            {
-#ifdef PNG_READ_GAMMA_SUPPORTED
-               if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
-                   gamma_table != NULL)
-               {
-                  sp = row;
-                  for (i = 0; i < row_width; i++, sp += 4)
-                  {
-                     png_byte a = *(sp + 3);
-
-                     if (a == 0xff)
-                     {
-                        *sp = gamma_table[*sp];
-                        *(sp + 1) = gamma_table[*(sp + 1)];
-                        *(sp + 2) = gamma_table[*(sp + 2)];
-                     }
-
-                     else if (a == 0)
-                     {
-                        /* Background is already in screen gamma */
-                        *sp = (png_byte)png_ptr->background.red;
-                        *(sp + 1) = (png_byte)png_ptr->background.green;
-                        *(sp + 2) = (png_byte)png_ptr->background.blue;
-                     }
-
-                     else
-                     {
-                        png_byte v, w;
-
-                        v = gamma_to_1[*sp];
-                        png_composite(w, v, a, png_ptr->background_1.red);
-                        if (!optimize) w = gamma_from_1[w];
-                        *sp = w;
-
-                        v = gamma_to_1[*(sp + 1)];
-                        png_composite(w, v, a, png_ptr->background_1.green);
-                        if (!optimize) w = gamma_from_1[w];
-                        *(sp + 1) = w;
-
-                        v = gamma_to_1[*(sp + 2)];
-                        png_composite(w, v, a, png_ptr->background_1.blue);
-                        if (!optimize) w = gamma_from_1[w];
-                        *(sp + 2) = w;
-                     }
-                  }
-               }
-               else
-#endif
-               {
-                  sp = row;
-                  for (i = 0; i < row_width; i++, sp += 4)
-                  {
-                     png_byte a = *(sp + 3);
-
-                     if (a == 0)
-                     {
-                        *sp = (png_byte)png_ptr->background.red;
-                        *(sp + 1) = (png_byte)png_ptr->background.green;
-                        *(sp + 2) = (png_byte)png_ptr->background.blue;
-                     }
-
-                     else if (a < 0xff)
-                     {
-                        png_composite(*sp, *sp, a, png_ptr->background.red);
-
-                        png_composite(*(sp + 1), *(sp + 1), a,
-                            png_ptr->background.green);
-
-                        png_composite(*(sp + 2), *(sp + 2), a,
-                            png_ptr->background.blue);
-                     }
-                  }
-               }
-            }
-            else /* if (row_info->bit_depth == 16) */
-            {
-#ifdef PNG_READ_GAMMA_SUPPORTED
-               if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
-                   gamma_16_to_1 != NULL)
-               {
-                  sp = row;
-                  for (i = 0; i < row_width; i++, sp += 8)
-                  {
-                     png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
-                         << 8) + (png_uint_16)(*(sp + 7)));
-
-                     if (a == (png_uint_16)0xffff)
-                     {
-                        png_uint_16 v;
-
-                        v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
-                        *sp = (png_byte)((v >> 8) & 0xff);
-                        *(sp + 1) = (png_byte)(v & 0xff);
-
-                        v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
-                        *(sp + 2) = (png_byte)((v >> 8) & 0xff);
-                        *(sp + 3) = (png_byte)(v & 0xff);
-
-                        v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
-                        *(sp + 4) = (png_byte)((v >> 8) & 0xff);
-                        *(sp + 5) = (png_byte)(v & 0xff);
-                     }
-
-                     else if (a == 0)
-                     {
-                        /* Background is already in screen gamma */
-                        *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
-                        *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
-                        *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
-                                & 0xff);
-                        *(sp + 3) = (png_byte)(png_ptr->background.green
-                                & 0xff);
-                        *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
-                                & 0xff);
-                        *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
-                     }
-
-                     else
-                     {
-                        png_uint_16 v, w;
-
-                        v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
-                        png_composite_16(w, v, a, png_ptr->background_1.red);
-                        if (!optimize)
-                           w = gamma_16_from_1[((w&0xff) >> gamma_shift)]
-                               [w >> 8];
-                        *sp = (png_byte)((w >> 8) & 0xff);
-                        *(sp + 1) = (png_byte)(w & 0xff);
-
-                        v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)];
-                        png_composite_16(w, v, a, png_ptr->background_1.green);
-                        if (!optimize)
-                           w = gamma_16_from_1[((w&0xff) >> gamma_shift)]
-                               [w >> 8];
-
-                        *(sp + 2) = (png_byte)((w >> 8) & 0xff);
-                        *(sp + 3) = (png_byte)(w & 0xff);
-
-                        v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)];
-                        png_composite_16(w, v, a, png_ptr->background_1.blue);
-                        if (!optimize)
-                           w = gamma_16_from_1[((w&0xff) >> gamma_shift)]
-                               [w >> 8];
-
-                        *(sp + 4) = (png_byte)((w >> 8) & 0xff);
-                        *(sp + 5) = (png_byte)(w & 0xff);
-                     }
-                  }
-               }
-
-               else
-#endif
-               {
-                  sp = row;
-                  for (i = 0; i < row_width; i++, sp += 8)
-                  {
-                     png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
-                         << 8) + (png_uint_16)(*(sp + 7)));
-
-                     if (a == 0)
-                     {
-                        *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
-                        *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
-                        *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
-                                & 0xff);
-                        *(sp + 3) = (png_byte)(png_ptr->background.green
-                                & 0xff);
-                        *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
-                                & 0xff);
-                        *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
-                     }
-
-                     else if (a < 0xffff)
-                     {
-                        png_uint_16 v;
-
-                        png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
-                        png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
-                            + *(sp + 3));
-                        png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
-                            + *(sp + 5));
-
-                        png_composite_16(v, r, a, png_ptr->background.red);
-                        *sp = (png_byte)((v >> 8) & 0xff);
-                        *(sp + 1) = (png_byte)(v & 0xff);
-
-                        png_composite_16(v, g, a, png_ptr->background.green);
-                        *(sp + 2) = (png_byte)((v >> 8) & 0xff);
-                        *(sp + 3) = (png_byte)(v & 0xff);
-
-                        png_composite_16(v, b, a, png_ptr->background.blue);
-                        *(sp + 4) = (png_byte)((v >> 8) & 0xff);
-                        *(sp + 5) = (png_byte)(v & 0xff);
-                     }
-                  }
-               }
-            }
-            break;
-         }
-
-         default:
-            break;
-      }
-   }
-}
-#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_READ_ALPHA_MODE_SUPPORTED */
-
-#ifdef PNG_READ_GAMMA_SUPPORTED
-/* Gamma correct the image, avoiding the alpha channel.  Make sure
- * you do this after you deal with the transparency issue on grayscale
- * or RGB images. If your bit depth is 8, use gamma_table, if it
- * is 16, use gamma_16_table and gamma_shift.  Build these with
- * build_gamma_table().
- */
-void /* PRIVATE */
-png_do_gamma(png_row_infop row_info, png_bytep row, png_structp png_ptr)
-{
-   png_const_bytep gamma_table = png_ptr->gamma_table;
-   png_const_uint_16pp gamma_16_table = png_ptr->gamma_16_table;
-   int gamma_shift = png_ptr->gamma_shift;
-
-   png_bytep sp;
-   png_uint_32 i;
-   png_uint_32 row_width=row_info->width;
-
-   png_debug(1, "in png_do_gamma");
-
-   if (((row_info->bit_depth <= 8 && gamma_table != NULL) ||
-       (row_info->bit_depth == 16 && gamma_16_table != NULL)))
-   {
-      switch (row_info->color_type)
-      {
-         case PNG_COLOR_TYPE_RGB:
-         {
-            if (row_info->bit_depth == 8)
-            {
-               sp = row;
-               for (i = 0; i < row_width; i++)
-               {
-                  *sp = gamma_table[*sp];
-                  sp++;
-                  *sp = gamma_table[*sp];
-                  sp++;
-                  *sp = gamma_table[*sp];
-                  sp++;
-               }
-            }
-
-            else /* if (row_info->bit_depth == 16) */
-            {
-               sp = row;
-               for (i = 0; i < row_width; i++)
-               {
-                  png_uint_16 v;
-
-                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
-                  *sp = (png_byte)((v >> 8) & 0xff);
-                  *(sp + 1) = (png_byte)(v & 0xff);
-                  sp += 2;
-
-                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
-                  *sp = (png_byte)((v >> 8) & 0xff);
-                  *(sp + 1) = (png_byte)(v & 0xff);
-                  sp += 2;
-
-                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
-                  *sp = (png_byte)((v >> 8) & 0xff);
-                  *(sp + 1) = (png_byte)(v & 0xff);
-                  sp += 2;
-               }
-            }
-            break;
-         }
-
-         case PNG_COLOR_TYPE_RGB_ALPHA:
-         {
-            if (row_info->bit_depth == 8)
-            {
-               sp = row;
-               for (i = 0; i < row_width; i++)
-               {
-                  *sp = gamma_table[*sp];
-                  sp++;
-
-                  *sp = gamma_table[*sp];
-                  sp++;
-
-                  *sp = gamma_table[*sp];
-                  sp++;
-
-                  sp++;
-               }
-            }
-
-            else /* if (row_info->bit_depth == 16) */
-            {
-               sp = row;
-               for (i = 0; i < row_width; i++)
-               {
-                  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
-                  *sp = (png_byte)((v >> 8) & 0xff);
-                  *(sp + 1) = (png_byte)(v & 0xff);
-                  sp += 2;
-
-                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
-                  *sp = (png_byte)((v >> 8) & 0xff);
-                  *(sp + 1) = (png_byte)(v & 0xff);
-                  sp += 2;
-
-                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
-                  *sp = (png_byte)((v >> 8) & 0xff);
-                  *(sp + 1) = (png_byte)(v & 0xff);
-                  sp += 4;
-               }
-            }
-            break;
-         }
-
-         case PNG_COLOR_TYPE_GRAY_ALPHA:
-         {
-            if (row_info->bit_depth == 8)
-            {
-               sp = row;
-               for (i = 0; i < row_width; i++)
-               {
-                  *sp = gamma_table[*sp];
-                  sp += 2;
-               }
-            }
-
-            else /* if (row_info->bit_depth == 16) */
-            {
-               sp = row;
-               for (i = 0; i < row_width; i++)
-               {
-                  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
-                  *sp = (png_byte)((v >> 8) & 0xff);
-                  *(sp + 1) = (png_byte)(v & 0xff);
-                  sp += 4;
-               }
-            }
-            break;
-         }
-
-         case PNG_COLOR_TYPE_GRAY:
-         {
-            if (row_info->bit_depth == 2)
-            {
-               sp = row;
-               for (i = 0; i < row_width; i += 4)
-               {
-                  int a = *sp & 0xc0;
-                  int b = *sp & 0x30;
-                  int c = *sp & 0x0c;
-                  int d = *sp & 0x03;
-
-                  *sp = (png_byte)(
-                      ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)])   ) & 0xc0)|
-                      ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)|
-                      ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)|
-                      ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) ));
-                  sp++;
-               }
-            }
-
-            if (row_info->bit_depth == 4)
-            {
-               sp = row;
-               for (i = 0; i < row_width; i += 2)
-               {
-                  int msb = *sp & 0xf0;
-                  int lsb = *sp & 0x0f;
-
-                  *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0)
-                      | (((int)gamma_table[(lsb << 4) | lsb]) >> 4));
-                  sp++;
-               }
-            }
-
-            else if (row_info->bit_depth == 8)
-            {
-               sp = row;
-               for (i = 0; i < row_width; i++)
-               {
-                  *sp = gamma_table[*sp];
-                  sp++;
-               }
-            }
-
-            else if (row_info->bit_depth == 16)
-            {
-               sp = row;
-               for (i = 0; i < row_width; i++)
-               {
-                  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
-                  *sp = (png_byte)((v >> 8) & 0xff);
-                  *(sp + 1) = (png_byte)(v & 0xff);
-                  sp += 2;
-               }
-            }
-            break;
-         }
-
-         default:
-            break;
-      }
-   }
-}
-#endif
-
-#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
-/* Encode the alpha channel to the output gamma (the input channel is always
- * linear.)  Called only with color types that have an alpha channel.  Needs the
- * from_1 tables.
- */
-void /* PRIVATE */
-png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structp png_ptr)
-{
-   png_uint_32 row_width = row_info->width;
-
-   png_debug(1, "in png_do_encode_alpha");
-
-   if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
-   {
-      if (row_info->bit_depth == 8)
-      {
-         PNG_CONST png_bytep table = png_ptr->gamma_from_1;
-
-         if (table != NULL)
-         {
-            PNG_CONST int step =
-               (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 4 : 2;
-
-            /* The alpha channel is the last component: */
-            row += step - 1;
-
-            for (; row_width > 0; --row_width, row += step)
-               *row = table[*row];
-
-            return;
-         }
-      }
-
-      else if (row_info->bit_depth == 16)
-      {
-         PNG_CONST png_uint_16pp table = png_ptr->gamma_16_from_1;
-         PNG_CONST int gamma_shift = png_ptr->gamma_shift;
-
-         if (table != NULL)
-         {
-            PNG_CONST int step =
-               (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 8 : 4;
-
-            /* The alpha channel is the last component: */
-            row += step - 2;
-
-            for (; row_width > 0; --row_width, row += step)
-            {
-               png_uint_16 v;
-
-               v = table[*(row + 1) >> gamma_shift][*row];
-               *row = (png_byte)((v >> 8) & 0xff);
-               *(row + 1) = (png_byte)(v & 0xff);
-            }
-
-            return;
-         }
-      }
-   }
-
-   /* Only get to here if called with a weird row_info; no harm has been done,
-    * so just issue a warning.
-    */
-   png_warning(png_ptr, "png_do_encode_alpha: unexpected call");
-}
-#endif
-
-#ifdef PNG_READ_EXPAND_SUPPORTED
-/* Expands a palette row to an RGB or RGBA row depending
- * upon whether you supply trans and num_trans.
- */
-void /* PRIVATE */
-png_do_expand_palette(png_row_infop row_info, png_bytep row,
-   png_const_colorp palette, png_const_bytep trans_alpha, int num_trans)
-{
-   int shift, value;
-   png_bytep sp, dp;
-   png_uint_32 i;
-   png_uint_32 row_width=row_info->width;
-
-   png_debug(1, "in png_do_expand_palette");
-
-   if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)
-   {
-      if (row_info->bit_depth < 8)
-      {
-         switch (row_info->bit_depth)
-         {
-            case 1:
-            {
-               sp = row + (png_size_t)((row_width - 1) >> 3);
-               dp = row + (png_size_t)row_width - 1;
-               shift = 7 - (int)((row_width + 7) & 0x07);
-               for (i = 0; i < row_width; i++)
-               {
-                  if ((*sp >> shift) & 0x01)
-                     *dp = 1;
-
-                  else
-                     *dp = 0;
-
-                  if (shift == 7)
-                  {
-                     shift = 0;
-                     sp--;
-                  }
-
-                  else
-                     shift++;
-
-                  dp--;
-               }
-               break;
-            }
-
-            case 2:
-            {
-               sp = row + (png_size_t)((row_width - 1) >> 2);
-               dp = row + (png_size_t)row_width - 1;
-               shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
-               for (i = 0; i < row_width; i++)
-               {
-                  value = (*sp >> shift) & 0x03;
-                  *dp = (png_byte)value;
-                  if (shift == 6)
-                  {
-                     shift = 0;
-                     sp--;
-                  }
-
-                  else
-                     shift += 2;
-
-                  dp--;
-               }
-               break;
-            }
-
-            case 4:
-            {
-               sp = row + (png_size_t)((row_width - 1) >> 1);
-               dp = row + (png_size_t)row_width - 1;
-               shift = (int)((row_width & 0x01) << 2);
-               for (i = 0; i < row_width; i++)
-               {
-                  value = (*sp >> shift) & 0x0f;
-                  *dp = (png_byte)value;
-                  if (shift == 4)
-                  {
-                     shift = 0;
-                     sp--;
-                  }
-
-                  else
-                     shift += 4;
-
-                  dp--;
-               }
-               break;
-            }
-
-            default:
-               break;
-         }
-         row_info->bit_depth = 8;
-         row_info->pixel_depth = 8;
-         row_info->rowbytes = row_width;
-      }
-
-      if (row_info->bit_depth == 8)
-      {
-         {
-            if (num_trans > 0)
-            {
-               sp = row + (png_size_t)row_width - 1;
-               dp = row + (png_size_t)(row_width << 2) - 1;
-
-               for (i = 0; i < row_width; i++)
-               {
-                  if ((int)(*sp) >= num_trans)
-                     *dp-- = 0xff;
-
-                  else
-                     *dp-- = trans_alpha[*sp];
-
-                  *dp-- = palette[*sp].blue;
-                  *dp-- = palette[*sp].green;
-                  *dp-- = palette[*sp].red;
-                  sp--;
-               }
-               row_info->bit_depth = 8;
-               row_info->pixel_depth = 32;
-               row_info->rowbytes = row_width * 4;
-               row_info->color_type = 6;
-               row_info->channels = 4;
-            }
-
-            else
-            {
-               sp = row + (png_size_t)row_width - 1;
-               dp = row + (png_size_t)(row_width * 3) - 1;
-
-               for (i = 0; i < row_width; i++)
-               {
-                  *dp-- = palette[*sp].blue;
-                  *dp-- = palette[*sp].green;
-                  *dp-- = palette[*sp].red;
-                  sp--;
-               }
-
-               row_info->bit_depth = 8;
-               row_info->pixel_depth = 24;
-               row_info->rowbytes = row_width * 3;
-               row_info->color_type = 2;
-               row_info->channels = 3;
-            }
-         }
-      }
-   }
-}
-
-/* If the bit depth < 8, it is expanded to 8.  Also, if the already
- * expanded transparency value is supplied, an alpha channel is built.
- */
-void /* PRIVATE */
-png_do_expand(png_row_infop row_info, png_bytep row,
-    png_const_color_16p trans_color)
-{
-   int shift, value;
-   png_bytep sp, dp;
-   png_uint_32 i;
-   png_uint_32 row_width=row_info->width;
-
-   png_debug(1, "in png_do_expand");
-
-   {
-      if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
-      {
-         png_uint_16 gray = (png_uint_16)(trans_color ? trans_color->gray : 0);
-
-         if (row_info->bit_depth < 8)
-         {
-            switch (row_info->bit_depth)
-            {
-               case 1:
-               {
-                  gray = (png_uint_16)((gray & 0x01) * 0xff);
-                  sp = row + (png_size_t)((row_width - 1) >> 3);
-                  dp = row + (png_size_t)row_width - 1;
-                  shift = 7 - (int)((row_width + 7) & 0x07);
-                  for (i = 0; i < row_width; i++)
-                  {
-                     if ((*sp >> shift) & 0x01)
-                        *dp = 0xff;
-
-                     else
-                        *dp = 0;
-
-                     if (shift == 7)
-                     {
-                        shift = 0;
-                        sp--;
-                     }
-
-                     else
-                        shift++;
-
-                     dp--;
-                  }
-                  break;
-               }
-
-               case 2:
-               {
-                  gray = (png_uint_16)((gray & 0x03) * 0x55);
-                  sp = row + (png_size_t)((row_width - 1) >> 2);
-                  dp = row + (png_size_t)row_width - 1;
-                  shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
-                  for (i = 0; i < row_width; i++)
-                  {
-                     value = (*sp >> shift) & 0x03;
-                     *dp = (png_byte)(value | (value << 2) | (value << 4) |
-                        (value << 6));
-                     if (shift == 6)
-                     {
-                        shift = 0;
-                        sp--;
-                     }
-
-                     else
-                        shift += 2;
-
-                     dp--;
-                  }
-                  break;
-               }
-
-               case 4:
-               {
-                  gray = (png_uint_16)((gray & 0x0f) * 0x11);
-                  sp = row + (png_size_t)((row_width - 1) >> 1);
-                  dp = row + (png_size_t)row_width - 1;
-                  shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
-                  for (i = 0; i < row_width; i++)
-                  {
-                     value = (*sp >> shift) & 0x0f;
-                     *dp = (png_byte)(value | (value << 4));
-                     if (shift == 4)
-                     {
-                        shift = 0;
-                        sp--;
-                     }
-
-                     else
-                        shift = 4;
-
-                     dp--;
-                  }
-                  break;
-               }
-
-               default:
-                  break;
-            }
-
-            row_info->bit_depth = 8;
-            row_info->pixel_depth = 8;
-            row_info->rowbytes = row_width;
-         }
-
-         if (trans_color != NULL)
-         {
-            if (row_info->bit_depth == 8)
-            {
-               gray = gray & 0xff;
-               sp = row + (png_size_t)row_width - 1;
-               dp = row + (png_size_t)(row_width << 1) - 1;
-
-               for (i = 0; i < row_width; i++)
-               {
-                  if (*sp == gray)
-                     *dp-- = 0;
-
-                  else
-                     *dp-- = 0xff;
-
-                  *dp-- = *sp--;
-               }
-            }
-
-            else if (row_info->bit_depth == 16)
-            {
-               png_byte gray_high = (png_byte)((gray >> 8) & 0xff);
-               png_byte gray_low = (png_byte)(gray & 0xff);
-               sp = row + row_info->rowbytes - 1;
-               dp = row + (row_info->rowbytes << 1) - 1;
-               for (i = 0; i < row_width; i++)
-               {
-                  if (*(sp - 1) == gray_high && *(sp) == gray_low)
-                  {
-                     *dp-- = 0;
-                     *dp-- = 0;
-                  }
-
-                  else
-                  {
-                     *dp-- = 0xff;
-                     *dp-- = 0xff;
-                  }
-
-                  *dp-- = *sp--;
-                  *dp-- = *sp--;
-               }
-            }
-
-            row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
-            row_info->channels = 2;
-            row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
-            row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
-               row_width);
-         }
-      }
-      else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_color)
-      {
-         if (row_info->bit_depth == 8)
-         {
-            png_byte red = (png_byte)(trans_color->red & 0xff);
-            png_byte green = (png_byte)(trans_color->green & 0xff);
-            png_byte blue = (png_byte)(trans_color->blue & 0xff);
-            sp = row + (png_size_t)row_info->rowbytes - 1;
-            dp = row + (png_size_t)(row_width << 2) - 1;
-            for (i = 0; i < row_width; i++)
-            {
-               if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue)
-                  *dp-- = 0;
-
-               else
-                  *dp-- = 0xff;
-
-               *dp-- = *sp--;
-               *dp-- = *sp--;
-               *dp-- = *sp--;
-            }
-         }
-         else if (row_info->bit_depth == 16)
-         {
-            png_byte red_high = (png_byte)((trans_color->red >> 8) & 0xff);
-            png_byte green_high = (png_byte)((trans_color->green >> 8) & 0xff);
-            png_byte blue_high = (png_byte)((trans_color->blue >> 8) & 0xff);
-            png_byte red_low = (png_byte)(trans_color->red & 0xff);
-            png_byte green_low = (png_byte)(trans_color->green & 0xff);
-            png_byte blue_low = (png_byte)(trans_color->blue & 0xff);
-            sp = row + row_info->rowbytes - 1;
-            dp = row + (png_size_t)(row_width << 3) - 1;
-            for (i = 0; i < row_width; i++)
-            {
-               if (*(sp - 5) == red_high &&
-                   *(sp - 4) == red_low &&
-                   *(sp - 3) == green_high &&
-                   *(sp - 2) == green_low &&
-                   *(sp - 1) == blue_high &&
-                   *(sp    ) == blue_low)
-               {
-                  *dp-- = 0;
-                  *dp-- = 0;
-               }
-
-               else
-               {
-                  *dp-- = 0xff;
-                  *dp-- = 0xff;
-               }
-
-               *dp-- = *sp--;
-               *dp-- = *sp--;
-               *dp-- = *sp--;
-               *dp-- = *sp--;
-               *dp-- = *sp--;
-               *dp-- = *sp--;
-            }
-         }
-         row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
-         row_info->channels = 4;
-         row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
-         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
-      }
-   }
-}
-#endif
-
-#ifdef PNG_READ_EXPAND_16_SUPPORTED
-/* If the bit depth is 8 and the color type is not a palette type expand the
- * whole row to 16 bits.  Has no effect otherwise.
- */
-void /* PRIVATE */
-png_do_expand_16(png_row_infop row_info, png_bytep row)
-{
-   if (row_info->bit_depth == 8 &&
-      row_info->color_type != PNG_COLOR_TYPE_PALETTE)
-   {
-      /* The row have a sequence of bytes containing [0..255] and we need
-       * to turn it into another row containing [0..65535], to do this we
-       * calculate:
-       *
-       *  (input / 255) * 65535
-       *
-       *  Which happens to be exactly input * 257 and this can be achieved
-       *  simply by byte replication in place (copying backwards).
-       */
-      png_byte *sp = row + row_info->rowbytes; /* source, last byte + 1 */
-      png_byte *dp = sp + row_info->rowbytes;  /* destination, end + 1 */
-      while (dp > sp)
-         dp[-2] = dp[-1] = *--sp, dp -= 2;
-
-      row_info->rowbytes *= 2;
-      row_info->bit_depth = 16;
-      row_info->pixel_depth = (png_byte)(row_info->channels * 16);
-   }
-}
-#endif
-
-#ifdef PNG_READ_QUANTIZE_SUPPORTED
-void /* PRIVATE */
-png_do_quantize(png_row_infop row_info, png_bytep row,
-    png_const_bytep palette_lookup, png_const_bytep quantize_lookup)
-{
-   png_bytep sp, dp;
-   png_uint_32 i;
-   png_uint_32 row_width=row_info->width;
-
-   png_debug(1, "in png_do_quantize");
-
-   if (row_info->bit_depth == 8)
-   {
-      if (row_info->color_type == PNG_COLOR_TYPE_RGB && palette_lookup)
-      {
-         int r, g, b, p;
-         sp = row;
-         dp = row;
-         for (i = 0; i < row_width; i++)
-         {
-            r = *sp++;
-            g = *sp++;
-            b = *sp++;
-
-            /* This looks real messy, but the compiler will reduce
-             * it down to a reasonable formula.  For example, with
-             * 5 bits per color, we get:
-             * p = (((r >> 3) & 0x1f) << 10) |
-             *    (((g >> 3) & 0x1f) << 5) |
-             *    ((b >> 3) & 0x1f);
-             */
-            p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) &
-                ((1 << PNG_QUANTIZE_RED_BITS) - 1)) <<
-                (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) |
-                (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) &
-                ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) <<
-                (PNG_QUANTIZE_BLUE_BITS)) |
-                ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) &
-                ((1 << PNG_QUANTIZE_BLUE_BITS) - 1));
-
-            *dp++ = palette_lookup[p];
-         }
-
-         row_info->color_type = PNG_COLOR_TYPE_PALETTE;
-         row_info->channels = 1;
-         row_info->pixel_depth = row_info->bit_depth;
-         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
-      }
-
-      else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
-         palette_lookup != NULL)
-      {
-         int r, g, b, p;
-         sp = row;
-         dp = row;
-         for (i = 0; i < row_width; i++)
-         {
-            r = *sp++;
-            g = *sp++;
-            b = *sp++;
-            sp++;
-
-            p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) &
-                ((1 << PNG_QUANTIZE_RED_BITS) - 1)) <<
-                (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) |
-                (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) &
-                ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) <<
-                (PNG_QUANTIZE_BLUE_BITS)) |
-                ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) &
-                ((1 << PNG_QUANTIZE_BLUE_BITS) - 1));
-
-            *dp++ = palette_lookup[p];
-         }
-
-         row_info->color_type = PNG_COLOR_TYPE_PALETTE;
-         row_info->channels = 1;
-         row_info->pixel_depth = row_info->bit_depth;
-         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
-      }
-
-      else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
-         quantize_lookup)
-      {
-         sp = row;
-
-         for (i = 0; i < row_width; i++, sp++)
-         {
-            *sp = quantize_lookup[*sp];
-         }
-      }
-   }
-}
-#endif /* PNG_READ_QUANTIZE_SUPPORTED */
-#endif /* PNG_READ_TRANSFORMS_SUPPORTED */
-
-#ifdef PNG_MNG_FEATURES_SUPPORTED
-/* Undoes intrapixel differencing  */
-void /* PRIVATE */
-png_do_read_intrapixel(png_row_infop row_info, png_bytep row)
-{
-   png_debug(1, "in png_do_read_intrapixel");
-
-   if (
-       (row_info->color_type & PNG_COLOR_MASK_COLOR))
-   {
-      int bytes_per_pixel;
-      png_uint_32 row_width = row_info->width;
-
-      if (row_info->bit_depth == 8)
-      {
-         png_bytep rp;
-         png_uint_32 i;
-
-         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
-            bytes_per_pixel = 3;
-
-         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
-            bytes_per_pixel = 4;
-
-         else
-            return;
-
-         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
-         {
-            *(rp) = (png_byte)((256 + *rp + *(rp + 1)) & 0xff);
-            *(rp+2) = (png_byte)((256 + *(rp + 2) + *(rp + 1)) & 0xff);
-         }
-      }
-      else if (row_info->bit_depth == 16)
-      {
-         png_bytep rp;
-         png_uint_32 i;
-
-         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
-            bytes_per_pixel = 6;
-
-         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
-            bytes_per_pixel = 8;
-
-         else
-            return;
-
-         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
-         {
-            png_uint_32 s0   = (*(rp    ) << 8) | *(rp + 1);
-            png_uint_32 s1   = (*(rp + 2) << 8) | *(rp + 3);
-            png_uint_32 s2   = (*(rp + 4) << 8) | *(rp + 5);
-            png_uint_32 red  = (s0 + s1 + 65536) & 0xffff;
-            png_uint_32 blue = (s2 + s1 + 65536) & 0xffff;
-            *(rp    ) = (png_byte)((red >> 8) & 0xff);
-            *(rp + 1) = (png_byte)(red & 0xff);
-            *(rp + 4) = (png_byte)((blue >> 8) & 0xff);
-            *(rp + 5) = (png_byte)(blue & 0xff);
-         }
-      }
-   }
-}
-#endif /* PNG_MNG_FEATURES_SUPPORTED */
-#endif /* PNG_READ_SUPPORTED */
+
+/* pngrtran.c - transforms the data in a row for PNG readers
+ *
+ * Last changed in libpng 1.6.15 [November 20, 2014]
+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * This file contains functions optionally called by an application
+ * in order to tell libpng how to handle data when reading a PNG.
+ * Transformations that are used in both reading and writing are
+ * in pngtrans.c.
+ */
+
+#include "pngpriv.h"
+
+#ifdef PNG_READ_SUPPORTED
+
+/* Set the action on getting a CRC error for an ancillary or critical chunk. */
+void PNGAPI
+png_set_crc_action(png_structrp png_ptr, int crit_action, int ancil_action)
+{
+   png_debug(1, "in png_set_crc_action");
+
+   if (png_ptr == NULL)
+      return;
+
+   /* Tell libpng how we react to CRC errors in critical chunks */
+   switch (crit_action)
+   {
+      case PNG_CRC_NO_CHANGE:                        /* Leave setting as is */
+         break;
+
+      case PNG_CRC_WARN_USE:                               /* Warn/use data */
+         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
+         png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE;
+         break;
+
+      case PNG_CRC_QUIET_USE:                             /* Quiet/use data */
+         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
+         png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE |
+                           PNG_FLAG_CRC_CRITICAL_IGNORE;
+         break;
+
+      case PNG_CRC_WARN_DISCARD:    /* Not a valid action for critical data */
+         png_warning(png_ptr,
+            "Can't discard critical data on CRC error");
+      case PNG_CRC_ERROR_QUIT:                                /* Error/quit */
+
+      case PNG_CRC_DEFAULT:
+      default:
+         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
+         break;
+   }
+
+   /* Tell libpng how we react to CRC errors in ancillary chunks */
+   switch (ancil_action)
+   {
+      case PNG_CRC_NO_CHANGE:                       /* Leave setting as is */
+         break;
+
+      case PNG_CRC_WARN_USE:                              /* Warn/use data */
+         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
+         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE;
+         break;
+
+      case PNG_CRC_QUIET_USE:                            /* Quiet/use data */
+         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
+         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE |
+                           PNG_FLAG_CRC_ANCILLARY_NOWARN;
+         break;
+
+      case PNG_CRC_ERROR_QUIT:                               /* Error/quit */
+         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
+         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN;
+         break;
+
+      case PNG_CRC_WARN_DISCARD:                      /* Warn/discard data */
+
+      case PNG_CRC_DEFAULT:
+      default:
+         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
+         break;
+   }
+}
+
+#ifdef PNG_READ_TRANSFORMS_SUPPORTED
+/* Is it OK to set a transformation now?  Only if png_start_read_image or
+ * png_read_update_info have not been called.  It is not necessary for the IHDR
+ * to have been read in all cases; the need_IHDR parameter allows for this
+ * check too.
+ */
+static int
+png_rtran_ok(png_structrp png_ptr, int need_IHDR)
+{
+   if (png_ptr != NULL)
+   {
+      if ((png_ptr->flags & PNG_FLAG_ROW_INIT) != 0)
+         png_app_error(png_ptr,
+            "invalid after png_start_read_image or png_read_update_info");
+
+      else if (need_IHDR && (png_ptr->mode & PNG_HAVE_IHDR) == 0)
+         png_app_error(png_ptr, "invalid before the PNG header has been read");
+
+      else
+      {
+         /* Turn on failure to initialize correctly for all transforms. */
+         png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED;
+
+         return 1; /* Ok */
+      }
+   }
+
+   return 0; /* no png_error possible! */
+}
+#endif
+
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+/* Handle alpha and tRNS via a background color */
+void PNGFAPI
+png_set_background_fixed(png_structrp png_ptr,
+    png_const_color_16p background_color, int background_gamma_code,
+    int need_expand, png_fixed_point background_gamma)
+{
+   png_debug(1, "in png_set_background_fixed");
+
+   if (png_rtran_ok(png_ptr, 0) == 0 || background_color == NULL)
+      return;
+
+   if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN)
+   {
+      png_warning(png_ptr, "Application must supply a known background gamma");
+      return;
+   }
+
+   png_ptr->transformations |= PNG_COMPOSE | PNG_STRIP_ALPHA;
+   png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
+   png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
+
+   png_ptr->background = *background_color;
+   png_ptr->background_gamma = background_gamma;
+   png_ptr->background_gamma_type = (png_byte)(background_gamma_code);
+   if (need_expand != 0)
+      png_ptr->transformations |= PNG_BACKGROUND_EXPAND;
+   else
+      png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND;
+}
+
+#  ifdef PNG_FLOATING_POINT_SUPPORTED
+void PNGAPI
+png_set_background(png_structrp png_ptr,
+    png_const_color_16p background_color, int background_gamma_code,
+    int need_expand, double background_gamma)
+{
+   png_set_background_fixed(png_ptr, background_color, background_gamma_code,
+      need_expand, png_fixed(png_ptr, background_gamma, "png_set_background"));
+}
+#  endif  /* FLOATING_POINT */
+#endif /* READ_BACKGROUND */
+
+/* Scale 16-bit depth files to 8-bit depth.  If both of these are set then the
+ * one that pngrtran does first (scale) happens.  This is necessary to allow the
+ * TRANSFORM and API behavior to be somewhat consistent, and it's simpler.
+ */
+#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
+void PNGAPI
+png_set_scale_16(png_structrp png_ptr)
+{
+   png_debug(1, "in png_set_scale_16");
+
+   if (png_rtran_ok(png_ptr, 0) == 0)
+      return;
+
+   png_ptr->transformations |= PNG_SCALE_16_TO_8;
+}
+#endif
+
+#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
+/* Chop 16-bit depth files to 8-bit depth */
+void PNGAPI
+png_set_strip_16(png_structrp png_ptr)
+{
+   png_debug(1, "in png_set_strip_16");
+
+   if (png_rtran_ok(png_ptr, 0) == 0)
+      return;
+
+   png_ptr->transformations |= PNG_16_TO_8;
+}
+#endif
+
+#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
+void PNGAPI
+png_set_strip_alpha(png_structrp png_ptr)
+{
+   png_debug(1, "in png_set_strip_alpha");
+
+   if (png_rtran_ok(png_ptr, 0) == 0)
+      return;
+
+   png_ptr->transformations |= PNG_STRIP_ALPHA;
+}
+#endif
+
+#if defined(PNG_READ_ALPHA_MODE_SUPPORTED) || defined(PNG_READ_GAMMA_SUPPORTED)
+static png_fixed_point
+translate_gamma_flags(png_structrp png_ptr, png_fixed_point output_gamma,
+   int is_screen)
+{
+   /* Check for flag values.  The main reason for having the old Mac value as a
+    * flag is that it is pretty near impossible to work out what the correct
+    * value is from Apple documentation - a working Mac system is needed to
+    * discover the value!
+    */
+   if (output_gamma == PNG_DEFAULT_sRGB ||
+      output_gamma == PNG_FP_1 / PNG_DEFAULT_sRGB)
+   {
+      /* If there is no sRGB support this just sets the gamma to the standard
+       * sRGB value.  (This is a side effect of using this function!)
+       */
+#     ifdef PNG_READ_sRGB_SUPPORTED
+         png_ptr->flags |= PNG_FLAG_ASSUME_sRGB;
+#     else
+         PNG_UNUSED(png_ptr)
+#     endif
+      if (is_screen != 0)
+         output_gamma = PNG_GAMMA_sRGB;
+      else
+         output_gamma = PNG_GAMMA_sRGB_INVERSE;
+   }
+
+   else if (output_gamma == PNG_GAMMA_MAC_18 ||
+      output_gamma == PNG_FP_1 / PNG_GAMMA_MAC_18)
+   {
+      if (is_screen != 0)
+         output_gamma = PNG_GAMMA_MAC_OLD;
+      else
+         output_gamma = PNG_GAMMA_MAC_INVERSE;
+   }
+
+   return output_gamma;
+}
+
+#  ifdef PNG_FLOATING_POINT_SUPPORTED
+static png_fixed_point
+convert_gamma_value(png_structrp png_ptr, double output_gamma)
+{
+   /* The following silently ignores cases where fixed point (times 100,000)
+    * gamma values are passed to the floating point API.  This is safe and it
+    * means the fixed point constants work just fine with the floating point
+    * API.  The alternative would just lead to undetected errors and spurious
+    * bug reports.  Negative values fail inside the _fixed API unless they
+    * correspond to the flag values.
+    */
+   if (output_gamma > 0 && output_gamma < 128)
+      output_gamma *= PNG_FP_1;
+
+   /* This preserves -1 and -2 exactly: */
+   output_gamma = floor(output_gamma + .5);
+
+   if (output_gamma > PNG_FP_MAX || output_gamma < PNG_FP_MIN)
+      png_fixed_error(png_ptr, "gamma value");
+
+   return (png_fixed_point)output_gamma;
+}
+#  endif
+#endif /* READ_ALPHA_MODE || READ_GAMMA */
+
+#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
+void PNGFAPI
+png_set_alpha_mode_fixed(png_structrp png_ptr, int mode,
+   png_fixed_point output_gamma)
+{
+   int compose = 0;
+   png_fixed_point file_gamma;
+
+   png_debug(1, "in png_set_alpha_mode");
+
+   if (png_rtran_ok(png_ptr, 0) == 0)
+      return;
+
+   output_gamma = translate_gamma_flags(png_ptr, output_gamma, 1/*screen*/);
+
+   /* Validate the value to ensure it is in a reasonable range. The value
+    * is expected to be 1 or greater, but this range test allows for some
+    * viewing correction values.  The intent is to weed out users of this API
+    * who use the inverse of the gamma value accidentally!  Since some of these
+    * values are reasonable this may have to be changed.
+    */
+   if (output_gamma < 70000 || output_gamma > 300000)
+      png_error(png_ptr, "output gamma out of expected range");
+
+   /* The default file gamma is the inverse of the output gamma; the output
+    * gamma may be changed below so get the file value first:
+    */
+   file_gamma = png_reciprocal(output_gamma);
+
+   /* There are really 8 possibilities here, composed of any combination
+    * of:
+    *
+    *    premultiply the color channels
+    *    do not encode non-opaque pixels
+    *    encode the alpha as well as the color channels
+    *
+    * The differences disappear if the input/output ('screen') gamma is 1.0,
+    * because then the encoding is a no-op and there is only the choice of
+    * premultiplying the color channels or not.
+    *
+    * png_set_alpha_mode and png_set_background interact because both use
+    * png_compose to do the work.  Calling both is only useful when
+    * png_set_alpha_mode is used to set the default mode - PNG_ALPHA_PNG - along
+    * with a default gamma value.  Otherwise PNG_COMPOSE must not be set.
+    */
+   switch (mode)
+   {
+      case PNG_ALPHA_PNG:        /* default: png standard */
+         /* No compose, but it may be set by png_set_background! */
+         png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
+         png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
+         break;
+
+      case PNG_ALPHA_ASSOCIATED: /* color channels premultiplied */
+         compose = 1;
+         png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
+         png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
+         /* The output is linear: */
+         output_gamma = PNG_FP_1;
+         break;
+
+      case PNG_ALPHA_OPTIMIZED:  /* associated, non-opaque pixels linear */
+         compose = 1;
+         png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
+         png_ptr->flags |= PNG_FLAG_OPTIMIZE_ALPHA;
+         /* output_gamma records the encoding of opaque pixels! */
+         break;
+
+      case PNG_ALPHA_BROKEN:     /* associated, non-linear, alpha encoded */
+         compose = 1;
+         png_ptr->transformations |= PNG_ENCODE_ALPHA;
+         png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
+         break;
+
+      default:
+         png_error(png_ptr, "invalid alpha mode");
+   }
+
+   /* Only set the default gamma if the file gamma has not been set (this has
+    * the side effect that the gamma in a second call to png_set_alpha_mode will
+    * be ignored.)
+    */
+   if (png_ptr->colorspace.gamma == 0)
+   {
+      png_ptr->colorspace.gamma = file_gamma;
+      png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;
+   }
+
+   /* But always set the output gamma: */
+   png_ptr->screen_gamma = output_gamma;
+
+   /* Finally, if pre-multiplying, set the background fields to achieve the
+    * desired result.
+    */
+   if (compose != 0)
+   {
+      /* And obtain alpha pre-multiplication by composing on black: */
+      memset(&png_ptr->background, 0, (sizeof png_ptr->background));
+      png_ptr->background_gamma = png_ptr->colorspace.gamma; /* just in case */
+      png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_FILE;
+      png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND;
+
+      if ((png_ptr->transformations & PNG_COMPOSE) != 0)
+         png_error(png_ptr,
+            "conflicting calls to set alpha mode and background");
+
+      png_ptr->transformations |= PNG_COMPOSE;
+   }
+}
+
+#  ifdef PNG_FLOATING_POINT_SUPPORTED
+void PNGAPI
+png_set_alpha_mode(png_structrp png_ptr, int mode, double output_gamma)
+{
+   png_set_alpha_mode_fixed(png_ptr, mode, convert_gamma_value(png_ptr,
+      output_gamma));
+}
+#  endif
+#endif
+
+#ifdef PNG_READ_QUANTIZE_SUPPORTED
+/* Dither file to 8-bit.  Supply a palette, the current number
+ * of elements in the palette, the maximum number of elements
+ * allowed, and a histogram if possible.  If the current number
+ * of colors is greater then the maximum number, the palette will be
+ * modified to fit in the maximum number.  "full_quantize" indicates
+ * whether we need a quantizing cube set up for RGB images, or if we
+ * simply are reducing the number of colors in a paletted image.
+ */
+
+typedef struct png_dsort_struct
+{
+   struct png_dsort_struct * next;
+   png_byte left;
+   png_byte right;
+} png_dsort;
+typedef png_dsort *   png_dsortp;
+typedef png_dsort * * png_dsortpp;
+
+void PNGAPI
+png_set_quantize(png_structrp png_ptr, png_colorp palette,
+    int num_palette, int maximum_colors, png_const_uint_16p histogram,
+    int full_quantize)
+{
+   png_debug(1, "in png_set_quantize");
+
+   if (png_rtran_ok(png_ptr, 0) == 0)
+      return;
+
+   png_ptr->transformations |= PNG_QUANTIZE;
+
+   if (full_quantize == 0)
+   {
+      int i;
+
+      png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr,
+          (png_uint_32)(num_palette * (sizeof (png_byte))));
+      for (i = 0; i < num_palette; i++)
+         png_ptr->quantize_index[i] = (png_byte)i;
+   }
+
+   if (num_palette > maximum_colors)
+   {
+      if (histogram != NULL)
+      {
+         /* This is easy enough, just throw out the least used colors.
+          * Perhaps not the best solution, but good enough.
+          */
+
+         int i;
+
+         /* Initialize an array to sort colors */
+         png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr,
+             (png_uint_32)(num_palette * (sizeof (png_byte))));
+
+         /* Initialize the quantize_sort array */
+         for (i = 0; i < num_palette; i++)
+            png_ptr->quantize_sort[i] = (png_byte)i;
+
+         /* Find the least used palette entries by starting a
+          * bubble sort, and running it until we have sorted
+          * out enough colors.  Note that we don't care about
+          * sorting all the colors, just finding which are
+          * least used.
+          */
+
+         for (i = num_palette - 1; i >= maximum_colors; i--)
+         {
+            int done; /* To stop early if the list is pre-sorted */
+            int j;
+
+            done = 1;
+            for (j = 0; j < i; j++)
+            {
+               if (histogram[png_ptr->quantize_sort[j]]
+                   < histogram[png_ptr->quantize_sort[j + 1]])
+               {
+                  png_byte t;
+
+                  t = png_ptr->quantize_sort[j];
+                  png_ptr->quantize_sort[j] = png_ptr->quantize_sort[j + 1];
+                  png_ptr->quantize_sort[j + 1] = t;
+                  done = 0;
+               }
+            }
+
+            if (done != 0)
+               break;
+         }
+
+         /* Swap the palette around, and set up a table, if necessary */
+         if (full_quantize != 0)
+         {
+            int j = num_palette;
+
+            /* Put all the useful colors within the max, but don't
+             * move the others.
+             */
+            for (i = 0; i < maximum_colors; i++)
+            {
+               if ((int)png_ptr->quantize_sort[i] >= maximum_colors)
+               {
+                  do
+                     j--;
+                  while ((int)png_ptr->quantize_sort[j] >= maximum_colors);
+
+                  palette[i] = palette[j];
+               }
+            }
+         }
+         else
+         {
+            int j = num_palette;
+
+            /* Move all the used colors inside the max limit, and
+             * develop a translation table.
+             */
+            for (i = 0; i < maximum_colors; i++)
+            {
+               /* Only move the colors we need to */
+               if ((int)png_ptr->quantize_sort[i] >= maximum_colors)
+               {
+                  png_color tmp_color;
+
+                  do
+                     j--;
+                  while ((int)png_ptr->quantize_sort[j] >= maximum_colors);
+
+                  tmp_color = palette[j];
+                  palette[j] = palette[i];
+                  palette[i] = tmp_color;
+                  /* Indicate where the color went */
+                  png_ptr->quantize_index[j] = (png_byte)i;
+                  png_ptr->quantize_index[i] = (png_byte)j;
+               }
+            }
+
+            /* Find closest color for those colors we are not using */
+            for (i = 0; i < num_palette; i++)
+            {
+               if ((int)png_ptr->quantize_index[i] >= maximum_colors)
+               {
+                  int min_d, k, min_k, d_index;
+
+                  /* Find the closest color to one we threw out */
+                  d_index = png_ptr->quantize_index[i];
+                  min_d = PNG_COLOR_DIST(palette[d_index], palette[0]);
+                  for (k = 1, min_k = 0; k < maximum_colors; k++)
+                  {
+                     int d;
+
+                     d = PNG_COLOR_DIST(palette[d_index], palette[k]);
+
+                     if (d < min_d)
+                     {
+                        min_d = d;
+                        min_k = k;
+                     }
+                  }
+                  /* Point to closest color */
+                  png_ptr->quantize_index[i] = (png_byte)min_k;
+               }
+            }
+         }
+         png_free(png_ptr, png_ptr->quantize_sort);
+         png_ptr->quantize_sort = NULL;
+      }
+      else
+      {
+         /* This is much harder to do simply (and quickly).  Perhaps
+          * we need to go through a median cut routine, but those
+          * don't always behave themselves with only a few colors
+          * as input.  So we will just find the closest two colors,
+          * and throw out one of them (chosen somewhat randomly).
+          * [We don't understand this at all, so if someone wants to
+          *  work on improving it, be our guest - AED, GRP]
+          */
+         int i;
+         int max_d;
+         int num_new_palette;
+         png_dsortp t;
+         png_dsortpp hash;
+
+         t = NULL;
+
+         /* Initialize palette index arrays */
+         png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,
+             (png_uint_32)(num_palette * (sizeof (png_byte))));
+         png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr,
+             (png_uint_32)(num_palette * (sizeof (png_byte))));
+
+         /* Initialize the sort array */
+         for (i = 0; i < num_palette; i++)
+         {
+            png_ptr->index_to_palette[i] = (png_byte)i;
+            png_ptr->palette_to_index[i] = (png_byte)i;
+         }
+
+         hash = (png_dsortpp)png_calloc(png_ptr, (png_uint_32)(769 *
+             (sizeof (png_dsortp))));
+
+         num_new_palette = num_palette;
+
+         /* Initial wild guess at how far apart the farthest pixel
+          * pair we will be eliminating will be.  Larger
+          * numbers mean more areas will be allocated, Smaller
+          * numbers run the risk of not saving enough data, and
+          * having to do this all over again.
+          *
+          * I have not done extensive checking on this number.
+          */
+         max_d = 96;
+
+         while (num_new_palette > maximum_colors)
+         {
+            for (i = 0; i < num_new_palette - 1; i++)
+            {
+               int j;
+
+               for (j = i + 1; j < num_new_palette; j++)
+               {
+                  int d;
+
+                  d = PNG_COLOR_DIST(palette[i], palette[j]);
+
+                  if (d <= max_d)
+                  {
+
+                     t = (png_dsortp)png_malloc_warn(png_ptr,
+                         (png_uint_32)(sizeof (png_dsort)));
+
+                     if (t == NULL)
+                         break;
+
+                     t->next = hash[d];
+                     t->left = (png_byte)i;
+                     t->right = (png_byte)j;
+                     hash[d] = t;
+                  }
+               }
+               if (t == NULL)
+                  break;
+            }
+
+            if (t != NULL)
+            for (i = 0; i <= max_d; i++)
+            {
+               if (hash[i] != NULL)
+               {
+                  png_dsortp p;
+
+                  for (p = hash[i]; p; p = p->next)
+                  {
+                     if ((int)png_ptr->index_to_palette[p->left]
+                         < num_new_palette &&
+                         (int)png_ptr->index_to_palette[p->right]
+                         < num_new_palette)
+                     {
+                        int j, next_j;
+
+                        if (num_new_palette & 0x01)
+                        {
+                           j = p->left;
+                           next_j = p->right;
+                        }
+                        else
+                        {
+                           j = p->right;
+                           next_j = p->left;
+                        }
+
+                        num_new_palette--;
+                        palette[png_ptr->index_to_palette[j]]
+                            = palette[num_new_palette];
+                        if (full_quantize == 0)
+                        {
+                           int k;
+
+                           for (k = 0; k < num_palette; k++)
+                           {
+                              if (png_ptr->quantize_index[k] ==
+                                  png_ptr->index_to_palette[j])
+                                 png_ptr->quantize_index[k] =
+                                     png_ptr->index_to_palette[next_j];
+
+                              if ((int)png_ptr->quantize_index[k] ==
+                                  num_new_palette)
+                                 png_ptr->quantize_index[k] =
+                                     png_ptr->index_to_palette[j];
+                           }
+                        }
+
+                        png_ptr->index_to_palette[png_ptr->palette_to_index
+                            [num_new_palette]] = png_ptr->index_to_palette[j];
+
+                        png_ptr->palette_to_index[png_ptr->index_to_palette[j]]
+                            = png_ptr->palette_to_index[num_new_palette];
+
+                        png_ptr->index_to_palette[j] =
+                            (png_byte)num_new_palette;
+
+                        png_ptr->palette_to_index[num_new_palette] =
+                            (png_byte)j;
+                     }
+                     if (num_new_palette <= maximum_colors)
+                        break;
+                  }
+                  if (num_new_palette <= maximum_colors)
+                     break;
+               }
+            }
+
+            for (i = 0; i < 769; i++)
+            {
+               if (hash[i] != NULL)
+               {
+                  png_dsortp p = hash[i];
+                  while (p)
+                  {
+                     t = p->next;
+                     png_free(png_ptr, p);
+                     p = t;
+                  }
+               }
+               hash[i] = 0;
+            }
+            max_d += 96;
+         }
+         png_free(png_ptr, hash);
+         png_free(png_ptr, png_ptr->palette_to_index);
+         png_free(png_ptr, png_ptr->index_to_palette);
+         png_ptr->palette_to_index = NULL;
+         png_ptr->index_to_palette = NULL;
+      }
+      num_palette = maximum_colors;
+   }
+   if (png_ptr->palette == NULL)
+   {
+      png_ptr->palette = palette;
+   }
+   png_ptr->num_palette = (png_uint_16)num_palette;
+
+   if (full_quantize != 0)
+   {
+      int i;
+      png_bytep distance;
+      int total_bits = PNG_QUANTIZE_RED_BITS + PNG_QUANTIZE_GREEN_BITS +
+          PNG_QUANTIZE_BLUE_BITS;
+      int num_red = (1 << PNG_QUANTIZE_RED_BITS);
+      int num_green = (1 << PNG_QUANTIZE_GREEN_BITS);
+      int num_blue = (1 << PNG_QUANTIZE_BLUE_BITS);
+      png_size_t num_entries = ((png_size_t)1 << total_bits);
+
+      png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr,
+          (png_uint_32)(num_entries * (sizeof (png_byte))));
+
+      distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries *
+          (sizeof (png_byte))));
+
+      memset(distance, 0xff, num_entries * (sizeof (png_byte)));
+
+      for (i = 0; i < num_palette; i++)
+      {
+         int ir, ig, ib;
+         int r = (palette[i].red >> (8 - PNG_QUANTIZE_RED_BITS));
+         int g = (palette[i].green >> (8 - PNG_QUANTIZE_GREEN_BITS));
+         int b = (palette[i].blue >> (8 - PNG_QUANTIZE_BLUE_BITS));
+
+         for (ir = 0; ir < num_red; ir++)
+         {
+            /* int dr = abs(ir - r); */
+            int dr = ((ir > r) ? ir - r : r - ir);
+            int index_r = (ir << (PNG_QUANTIZE_BLUE_BITS +
+                PNG_QUANTIZE_GREEN_BITS));
+
+            for (ig = 0; ig < num_green; ig++)
+            {
+               /* int dg = abs(ig - g); */
+               int dg = ((ig > g) ? ig - g : g - ig);
+               int dt = dr + dg;
+               int dm = ((dr > dg) ? dr : dg);
+               int index_g = index_r | (ig << PNG_QUANTIZE_BLUE_BITS);
+
+               for (ib = 0; ib < num_blue; ib++)
+               {
+                  int d_index = index_g | ib;
+                  /* int db = abs(ib - b); */
+                  int db = ((ib > b) ? ib - b : b - ib);
+                  int dmax = ((dm > db) ? dm : db);
+                  int d = dmax + dt + db;
+
+                  if (d < (int)distance[d_index])
+                  {
+                     distance[d_index] = (png_byte)d;
+                     png_ptr->palette_lookup[d_index] = (png_byte)i;
+                  }
+               }
+            }
+         }
+      }
+
+      png_free(png_ptr, distance);
+   }
+}
+#endif /* READ_QUANTIZE */
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+void PNGFAPI
+png_set_gamma_fixed(png_structrp png_ptr, png_fixed_point scrn_gamma,
+   png_fixed_point file_gamma)
+{
+   png_debug(1, "in png_set_gamma_fixed");
+
+   if (png_rtran_ok(png_ptr, 0) == 0)
+      return;
+
+   /* New in libpng-1.5.4 - reserve particular negative values as flags. */
+   scrn_gamma = translate_gamma_flags(png_ptr, scrn_gamma, 1/*screen*/);
+   file_gamma = translate_gamma_flags(png_ptr, file_gamma, 0/*file*/);
+
+   /* Checking the gamma values for being >0 was added in 1.5.4 along with the
+    * premultiplied alpha support; this actually hides an undocumented feature
+    * of the previous implementation which allowed gamma processing to be
+    * disabled in background handling.  There is no evidence (so far) that this
+    * was being used; however, png_set_background itself accepted and must still
+    * accept '0' for the gamma value it takes, because it isn't always used.
+    *
+    * Since this is an API change (albeit a very minor one that removes an
+    * undocumented API feature) the following checks were only enabled in
+    * libpng-1.6.0.
+    */
+   if (file_gamma <= 0)
+      png_error(png_ptr, "invalid file gamma in png_set_gamma");
+
+   if (scrn_gamma <= 0)
+      png_error(png_ptr, "invalid screen gamma in png_set_gamma");
+
+   /* Set the gamma values unconditionally - this overrides the value in the PNG
+    * file if a gAMA chunk was present.  png_set_alpha_mode provides a
+    * different, easier, way to default the file gamma.
+    */
+   png_ptr->colorspace.gamma = file_gamma;
+   png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;
+   png_ptr->screen_gamma = scrn_gamma;
+}
+
+#  ifdef PNG_FLOATING_POINT_SUPPORTED
+void PNGAPI
+png_set_gamma(png_structrp png_ptr, double scrn_gamma, double file_gamma)
+{
+   png_set_gamma_fixed(png_ptr, convert_gamma_value(png_ptr, scrn_gamma),
+      convert_gamma_value(png_ptr, file_gamma));
+}
+#  endif /* FLOATING_POINT */
+#endif /* READ_GAMMA */
+
+#ifdef PNG_READ_EXPAND_SUPPORTED
+/* Expand paletted images to RGB, expand grayscale images of
+ * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
+ * to alpha channels.
+ */
+void PNGAPI
+png_set_expand(png_structrp png_ptr)
+{
+   png_debug(1, "in png_set_expand");
+
+   if (png_rtran_ok(png_ptr, 0) == 0)
+      return;
+
+   png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
+}
+
+/* GRR 19990627:  the following three functions currently are identical
+ *  to png_set_expand().  However, it is entirely reasonable that someone
+ *  might wish to expand an indexed image to RGB but *not* expand a single,
+ *  fully transparent palette entry to a full alpha channel--perhaps instead
+ *  convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace
+ *  the transparent color with a particular RGB value, or drop tRNS entirely.
+ *  IOW, a future version of the library may make the transformations flag
+ *  a bit more fine-grained, with separate bits for each of these three
+ *  functions.
+ *
+ *  More to the point, these functions make it obvious what libpng will be
+ *  doing, whereas "expand" can (and does) mean any number of things.
+ *
+ *  GRP 20060307: In libpng-1.2.9, png_set_gray_1_2_4_to_8() was modified
+ *  to expand only the sample depth but not to expand the tRNS to alpha
+ *  and its name was changed to png_set_expand_gray_1_2_4_to_8().
+ */
+
+/* Expand paletted images to RGB. */
+void PNGAPI
+png_set_palette_to_rgb(png_structrp png_ptr)
+{
+   png_debug(1, "in png_set_palette_to_rgb");
+
+   if (png_rtran_ok(png_ptr, 0) == 0)
+      return;
+
+   png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
+}
+
+/* Expand grayscale images of less than 8-bit depth to 8 bits. */
+void PNGAPI
+png_set_expand_gray_1_2_4_to_8(png_structrp png_ptr)
+{
+   png_debug(1, "in png_set_expand_gray_1_2_4_to_8");
+
+   if (png_rtran_ok(png_ptr, 0) == 0)
+      return;
+
+   png_ptr->transformations |= PNG_EXPAND;
+}
+
+/* Expand tRNS chunks to alpha channels. */
+void PNGAPI
+png_set_tRNS_to_alpha(png_structrp png_ptr)
+{
+   png_debug(1, "in png_set_tRNS_to_alpha");
+
+   if (png_rtran_ok(png_ptr, 0) == 0)
+      return;
+
+   png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
+}
+#endif /* READ_EXPAND */
+
+#ifdef PNG_READ_EXPAND_16_SUPPORTED
+/* Expand to 16-bit channels, expand the tRNS chunk too (because otherwise
+ * it may not work correctly.)
+ */
+void PNGAPI
+png_set_expand_16(png_structrp png_ptr)
+{
+   png_debug(1, "in png_set_expand_16");
+
+   if (png_rtran_ok(png_ptr, 0) == 0)
+      return;
+
+   png_ptr->transformations |= (PNG_EXPAND_16 | PNG_EXPAND | PNG_EXPAND_tRNS);
+}
+#endif
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+void PNGAPI
+png_set_gray_to_rgb(png_structrp png_ptr)
+{
+   png_debug(1, "in png_set_gray_to_rgb");
+
+   if (png_rtran_ok(png_ptr, 0) == 0)
+      return;
+
+   /* Because rgb must be 8 bits or more: */
+   png_set_expand_gray_1_2_4_to_8(png_ptr);
+   png_ptr->transformations |= PNG_GRAY_TO_RGB;
+}
+#endif
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+void PNGFAPI
+png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action,
+    png_fixed_point red, png_fixed_point green)
+{
+   png_debug(1, "in png_set_rgb_to_gray");
+
+   /* Need the IHDR here because of the check on color_type below. */
+   /* TODO: fix this */
+   if (png_rtran_ok(png_ptr, 1) == 0)
+      return;
+
+   switch (error_action)
+   {
+      case PNG_ERROR_ACTION_NONE:
+         png_ptr->transformations |= PNG_RGB_TO_GRAY;
+         break;
+
+      case PNG_ERROR_ACTION_WARN:
+         png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN;
+         break;
+
+      case PNG_ERROR_ACTION_ERROR:
+         png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR;
+         break;
+
+      default:
+         png_error(png_ptr, "invalid error action to rgb_to_gray");
+         break;
+   }
+
+   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+#ifdef PNG_READ_EXPAND_SUPPORTED
+      png_ptr->transformations |= PNG_EXPAND;
+#else
+   {
+      /* Make this an error in 1.6 because otherwise the application may assume
+       * that it just worked and get a memory overwrite.
+       */
+      png_error(png_ptr,
+        "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED");
+
+      /* png_ptr->transformations &= ~PNG_RGB_TO_GRAY; */
+   }
+#endif
+   {
+      if (red >= 0 && green >= 0 && red + green <= PNG_FP_1)
+      {
+         png_uint_16 red_int, green_int;
+
+         /* NOTE: this calculation does not round, but this behavior is retained
+          * for consistency; the inaccuracy is very small.  The code here always
+          * overwrites the coefficients, regardless of whether they have been
+          * defaulted or set already.
+          */
+         red_int = (png_uint_16)(((png_uint_32)red*32768)/100000);
+         green_int = (png_uint_16)(((png_uint_32)green*32768)/100000);
+
+         png_ptr->rgb_to_gray_red_coeff   = red_int;
+         png_ptr->rgb_to_gray_green_coeff = green_int;
+         png_ptr->rgb_to_gray_coefficients_set = 1;
+      }
+
+      else
+      {
+         if (red >= 0 && green >= 0)
+            png_app_warning(png_ptr,
+               "ignoring out of range rgb_to_gray coefficients");
+
+         /* Use the defaults, from the cHRM chunk if set, else the historical
+          * values which are close to the sRGB/HDTV/ITU-Rec 709 values.  See
+          * png_do_rgb_to_gray for more discussion of the values.  In this case
+          * the coefficients are not marked as 'set' and are not overwritten if
+          * something has already provided a default.
+          */
+         if (png_ptr->rgb_to_gray_red_coeff == 0 &&
+            png_ptr->rgb_to_gray_green_coeff == 0)
+         {
+            png_ptr->rgb_to_gray_red_coeff   = 6968;
+            png_ptr->rgb_to_gray_green_coeff = 23434;
+            /* png_ptr->rgb_to_gray_blue_coeff  = 2366; */
+         }
+      }
+   }
+}
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+/* Convert a RGB image to a grayscale of the same width.  This allows us,
+ * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
+ */
+
+void PNGAPI
+png_set_rgb_to_gray(png_structrp png_ptr, int error_action, double red,
+   double green)
+{
+   png_set_rgb_to_gray_fixed(png_ptr, error_action,
+      png_fixed(png_ptr, red, "rgb to gray red coefficient"),
+      png_fixed(png_ptr, green, "rgb to gray green coefficient"));
+}
+#endif /* FLOATING POINT */
+
+#endif /* RGB_TO_GRAY */
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+void PNGAPI
+png_set_read_user_transform_fn(png_structrp png_ptr, png_user_transform_ptr
+    read_user_transform_fn)
+{
+   png_debug(1, "in png_set_read_user_transform_fn");
+
+#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
+   png_ptr->transformations |= PNG_USER_TRANSFORM;
+   png_ptr->read_user_transform_fn = read_user_transform_fn;
+#endif
+}
+#endif
+
+#ifdef PNG_READ_TRANSFORMS_SUPPORTED
+#ifdef PNG_READ_GAMMA_SUPPORTED
+/* In the case of gamma transformations only do transformations on images where
+ * the [file] gamma and screen_gamma are not close reciprocals, otherwise it
+ * slows things down slightly, and also needlessly introduces small errors.
+ */
+static int /* PRIVATE */
+png_gamma_threshold(png_fixed_point screen_gamma, png_fixed_point file_gamma)
+{
+   /* PNG_GAMMA_THRESHOLD is the threshold for performing gamma
+    * correction as a difference of the overall transform from 1.0
+    *
+    * We want to compare the threshold with s*f - 1, if we get
+    * overflow here it is because of wacky gamma values so we
+    * turn on processing anyway.
+    */
+   png_fixed_point gtest;
+   return !png_muldiv(&gtest, screen_gamma, file_gamma, PNG_FP_1) ||
+       png_gamma_significant(gtest);
+}
+#endif
+
+/* Initialize everything needed for the read.  This includes modifying
+ * the palette.
+ */
+
+/* For the moment 'png_init_palette_transformations' and
+ * 'png_init_rgb_transformations' only do some flag canceling optimizations.
+ * The intent is that these two routines should have palette or rgb operations
+ * extracted from 'png_init_read_transformations'.
+ */
+static void /* PRIVATE */
+png_init_palette_transformations(png_structrp png_ptr)
+{
+   /* Called to handle the (input) palette case.  In png_do_read_transformations
+    * the first step is to expand the palette if requested, so this code must
+    * take care to only make changes that are invariant with respect to the
+    * palette expansion, or only do them if there is no expansion.
+    *
+    * STRIP_ALPHA has already been handled in the caller (by setting num_trans
+    * to 0.)
+    */
+   int input_has_alpha = 0;
+   int input_has_transparency = 0;
+
+   if (png_ptr->num_trans > 0)
+   {
+      int i;
+
+      /* Ignore if all the entries are opaque (unlikely!) */
+      for (i=0; i<png_ptr->num_trans; ++i)
+      {
+         if (png_ptr->trans_alpha[i] == 255)
+            continue;
+         else if (png_ptr->trans_alpha[i] == 0)
+            input_has_transparency = 1;
+         else
+         {
+            input_has_transparency = 1;
+            input_has_alpha = 1;
+            break;
+         }
+      }
+   }
+
+   /* If no alpha we can optimize. */
+   if (input_has_alpha == 0)
+   {
+      /* Any alpha means background and associative alpha processing is
+       * required, however if the alpha is 0 or 1 throughout OPTIMIZE_ALPHA
+       * and ENCODE_ALPHA are irrelevant.
+       */
+      png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
+      png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
+
+      if (input_has_transparency == 0)
+         png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND);
+   }
+
+#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
+   /* png_set_background handling - deals with the complexity of whether the
+    * background color is in the file format or the screen format in the case
+    * where an 'expand' will happen.
+    */
+
+   /* The following code cannot be entered in the alpha pre-multiplication case
+    * because PNG_BACKGROUND_EXPAND is cancelled below.
+    */
+   if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0 &&
+       (png_ptr->transformations & PNG_EXPAND) != 0)
+   {
+      {
+         png_ptr->background.red   =
+             png_ptr->palette[png_ptr->background.index].red;
+         png_ptr->background.green =
+             png_ptr->palette[png_ptr->background.index].green;
+         png_ptr->background.blue  =
+             png_ptr->palette[png_ptr->background.index].blue;
+
+#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
+        if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0)
+        {
+           if ((png_ptr->transformations & PNG_EXPAND_tRNS) == 0)
+           {
+              /* Invert the alpha channel (in tRNS) unless the pixels are
+               * going to be expanded, in which case leave it for later
+               */
+              int i, istop = png_ptr->num_trans;
+
+              for (i=0; i<istop; i++)
+                 png_ptr->trans_alpha[i] = (png_byte)(255 -
+                    png_ptr->trans_alpha[i]);
+           }
+        }
+#endif /* READ_INVERT_ALPHA */
+      }
+   } /* background expand and (therefore) no alpha association. */
+#endif /* READ_EXPAND && READ_BACKGROUND */
+}
+
+static void /* PRIVATE */
+png_init_rgb_transformations(png_structrp png_ptr)
+{
+   /* Added to libpng-1.5.4: check the color type to determine whether there
+    * is any alpha or transparency in the image and simply cancel the
+    * background and alpha mode stuff if there isn't.
+    */
+   int input_has_alpha = (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0;
+   int input_has_transparency = png_ptr->num_trans > 0;
+
+   /* If no alpha we can optimize. */
+   if (input_has_alpha == 0)
+   {
+      /* Any alpha means background and associative alpha processing is
+       * required, however if the alpha is 0 or 1 throughout OPTIMIZE_ALPHA
+       * and ENCODE_ALPHA are irrelevant.
+       */
+#     ifdef PNG_READ_ALPHA_MODE_SUPPORTED
+         png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
+         png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
+#     endif
+
+      if (input_has_transparency == 0)
+         png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND);
+   }
+
+#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
+   /* png_set_background handling - deals with the complexity of whether the
+    * background color is in the file format or the screen format in the case
+    * where an 'expand' will happen.
+    */
+
+   /* The following code cannot be entered in the alpha pre-multiplication case
+    * because PNG_BACKGROUND_EXPAND is cancelled below.
+    */
+   if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0 &&
+       (png_ptr->transformations & PNG_EXPAND) != 0 &&
+       (png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0)
+       /* i.e., GRAY or GRAY_ALPHA */
+   {
+      {
+         /* Expand background and tRNS chunks */
+         int gray = png_ptr->background.gray;
+         int trans_gray = png_ptr->trans_color.gray;
+
+         switch (png_ptr->bit_depth)
+         {
+            case 1:
+               gray *= 0xff;
+               trans_gray *= 0xff;
+               break;
+
+            case 2:
+               gray *= 0x55;
+               trans_gray *= 0x55;
+               break;
+
+            case 4:
+               gray *= 0x11;
+               trans_gray *= 0x11;
+               break;
+
+            default:
+
+            case 8:
+               /* FALL THROUGH (Already 8 bits) */
+
+            case 16:
+               /* Already a full 16 bits */
+               break;
+         }
+
+         png_ptr->background.red = png_ptr->background.green =
+            png_ptr->background.blue = (png_uint_16)gray;
+
+         if ((png_ptr->transformations & PNG_EXPAND_tRNS) == 0)
+         {
+            png_ptr->trans_color.red = png_ptr->trans_color.green =
+               png_ptr->trans_color.blue = (png_uint_16)trans_gray;
+         }
+      }
+   } /* background expand and (therefore) no alpha association. */
+#endif /* READ_EXPAND && READ_BACKGROUND */
+}
+
+void /* PRIVATE */
+png_init_read_transformations(png_structrp png_ptr)
+{
+   png_debug(1, "in png_init_read_transformations");
+
+   /* This internal function is called from png_read_start_row in pngrutil.c
+    * and it is called before the 'rowbytes' calculation is done, so the code
+    * in here can change or update the transformations flags.
+    *
+    * First do updates that do not depend on the details of the PNG image data
+    * being processed.
+    */
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+   /* Prior to 1.5.4 these tests were performed from png_set_gamma, 1.5.4 adds
+    * png_set_alpha_mode and this is another source for a default file gamma so
+    * the test needs to be performed later - here.  In addition prior to 1.5.4
+    * the tests were repeated for the PALETTE color type here - this is no
+    * longer necessary (and doesn't seem to have been necessary before.)
+    */
+   {
+      /* The following temporary indicates if overall gamma correction is
+       * required.
+       */
+      int gamma_correction = 0;
+
+      if (png_ptr->colorspace.gamma != 0) /* has been set */
+      {
+         if (png_ptr->screen_gamma != 0) /* screen set too */
+            gamma_correction = png_gamma_threshold(png_ptr->colorspace.gamma,
+               png_ptr->screen_gamma);
+
+         else
+            /* Assume the output matches the input; a long time default behavior
+             * of libpng, although the standard has nothing to say about this.
+             */
+            png_ptr->screen_gamma = png_reciprocal(png_ptr->colorspace.gamma);
+      }
+
+      else if (png_ptr->screen_gamma != 0)
+         /* The converse - assume the file matches the screen, note that this
+          * perhaps undesireable default can (from 1.5.4) be changed by calling
+          * png_set_alpha_mode (even if the alpha handling mode isn't required
+          * or isn't changed from the default.)
+          */
+         png_ptr->colorspace.gamma = png_reciprocal(png_ptr->screen_gamma);
+
+      else /* neither are set */
+         /* Just in case the following prevents any processing - file and screen
+          * are both assumed to be linear and there is no way to introduce a
+          * third gamma value other than png_set_background with 'UNIQUE', and,
+          * prior to 1.5.4
+          */
+         png_ptr->screen_gamma = png_ptr->colorspace.gamma = PNG_FP_1;
+
+      /* We have a gamma value now. */
+      png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;
+
+      /* Now turn the gamma transformation on or off as appropriate.  Notice
+       * that PNG_GAMMA just refers to the file->screen correction.  Alpha
+       * composition may independently cause gamma correction because it needs
+       * linear data (e.g. if the file has a gAMA chunk but the screen gamma
+       * hasn't been specified.)  In any case this flag may get turned off in
+       * the code immediately below if the transform can be handled outside the
+       * row loop.
+       */
+      if (gamma_correction != 0)
+         png_ptr->transformations |= PNG_GAMMA;
+
+      else
+         png_ptr->transformations &= ~PNG_GAMMA;
+   }
+#endif
+
+   /* Certain transformations have the effect of preventing other
+    * transformations that happen afterward in png_do_read_transformations;
+    * resolve the interdependencies here.  From the code of
+    * png_do_read_transformations the order is:
+    *
+    *  1) PNG_EXPAND (including PNG_EXPAND_tRNS)
+    *  2) PNG_STRIP_ALPHA (if no compose)
+    *  3) PNG_RGB_TO_GRAY
+    *  4) PNG_GRAY_TO_RGB iff !PNG_BACKGROUND_IS_GRAY
+    *  5) PNG_COMPOSE
+    *  6) PNG_GAMMA
+    *  7) PNG_STRIP_ALPHA (if compose)
+    *  8) PNG_ENCODE_ALPHA
+    *  9) PNG_SCALE_16_TO_8
+    * 10) PNG_16_TO_8
+    * 11) PNG_QUANTIZE (converts to palette)
+    * 12) PNG_EXPAND_16
+    * 13) PNG_GRAY_TO_RGB iff PNG_BACKGROUND_IS_GRAY
+    * 14) PNG_INVERT_MONO
+    * 15) PNG_INVERT_ALPHA
+    * 16) PNG_SHIFT
+    * 17) PNG_PACK
+    * 18) PNG_BGR
+    * 19) PNG_PACKSWAP
+    * 20) PNG_FILLER (includes PNG_ADD_ALPHA)
+    * 21) PNG_SWAP_ALPHA
+    * 22) PNG_SWAP_BYTES
+    * 23) PNG_USER_TRANSFORM [must be last]
+    */
+#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
+   if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 &&
+       (png_ptr->transformations & PNG_COMPOSE) == 0)
+   {
+      /* Stripping the alpha channel happens immediately after the 'expand'
+       * transformations, before all other transformation, so it cancels out
+       * the alpha handling.  It has the side effect negating the effect of
+       * PNG_EXPAND_tRNS too:
+       */
+      png_ptr->transformations &= ~(PNG_BACKGROUND_EXPAND | PNG_ENCODE_ALPHA |
+         PNG_EXPAND_tRNS);
+      png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
+
+      /* Kill the tRNS chunk itself too.  Prior to 1.5.4 this did not happen
+       * so transparency information would remain just so long as it wasn't
+       * expanded.  This produces unexpected API changes if the set of things
+       * that do PNG_EXPAND_tRNS changes (perfectly possible given the
+       * documentation - which says ask for what you want, accept what you
+       * get.)  This makes the behavior consistent from 1.5.4:
+       */
+      png_ptr->num_trans = 0;
+   }
+#endif /* STRIP_ALPHA supported, no COMPOSE */
+
+#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
+   /* If the screen gamma is about 1.0 then the OPTIMIZE_ALPHA and ENCODE_ALPHA
+    * settings will have no effect.
+    */
+   if (png_gamma_significant(png_ptr->screen_gamma) == 0)
+   {
+      png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
+      png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
+   }
+#endif
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+   /* Make sure the coefficients for the rgb to gray conversion are set
+    * appropriately.
+    */
+   if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)
+      png_colorspace_set_rgb_coefficients(png_ptr);
+#endif
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
+   /* Detect gray background and attempt to enable optimization for
+    * gray --> RGB case.
+    *
+    * Note:  if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or
+    * RGB_ALPHA (in which case need_expand is superfluous anyway), the
+    * background color might actually be gray yet not be flagged as such.
+    * This is not a problem for the current code, which uses
+    * PNG_BACKGROUND_IS_GRAY only to decide when to do the
+    * png_do_gray_to_rgb() transformation.
+    *
+    * TODO: this code needs to be revised to avoid the complexity and
+    * interdependencies.  The color type of the background should be recorded in
+    * png_set_background, along with the bit depth, then the code has a record
+    * of exactly what color space the background is currently in.
+    */
+   if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0)
+   {
+      /* PNG_BACKGROUND_EXPAND: the background is in the file color space, so if
+       * the file was grayscale the background value is gray.
+       */
+      if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0)
+         png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
+   }
+
+   else if ((png_ptr->transformations & PNG_COMPOSE) != 0)
+   {
+      /* PNG_COMPOSE: png_set_background was called with need_expand false,
+       * so the color is in the color space of the output or png_set_alpha_mode
+       * was called and the color is black.  Ignore RGB_TO_GRAY because that
+       * happens before GRAY_TO_RGB.
+       */
+      if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0)
+      {
+         if (png_ptr->background.red == png_ptr->background.green &&
+             png_ptr->background.red == png_ptr->background.blue)
+         {
+            png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
+            png_ptr->background.gray = png_ptr->background.red;
+         }
+      }
+   }
+#endif /* READ_EXPAND && READ_BACKGROUND */
+#endif /* READ_GRAY_TO_RGB */
+
+   /* For indexed PNG data (PNG_COLOR_TYPE_PALETTE) many of the transformations
+    * can be performed directly on the palette, and some (such as rgb to gray)
+    * can be optimized inside the palette.  This is particularly true of the
+    * composite (background and alpha) stuff, which can be pretty much all done
+    * in the palette even if the result is expanded to RGB or gray afterward.
+    *
+    * NOTE: this is Not Yet Implemented, the code behaves as in 1.5.1 and
+    * earlier and the palette stuff is actually handled on the first row.  This
+    * leads to the reported bug that the palette returned by png_get_PLTE is not
+    * updated.
+    */
+   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      png_init_palette_transformations(png_ptr);
+
+   else
+      png_init_rgb_transformations(png_ptr);
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
+   defined(PNG_READ_EXPAND_16_SUPPORTED)
+   if ((png_ptr->transformations & PNG_EXPAND_16) != 0 &&
+       (png_ptr->transformations & PNG_COMPOSE) != 0 &&
+       (png_ptr->transformations & PNG_BACKGROUND_EXPAND) == 0 &&
+       png_ptr->bit_depth != 16)
+   {
+      /* TODO: fix this.  Because the expand_16 operation is after the compose
+       * handling the background color must be 8, not 16, bits deep, but the
+       * application will supply a 16-bit value so reduce it here.
+       *
+       * The PNG_BACKGROUND_EXPAND code above does not expand to 16 bits at
+       * present, so that case is ok (until do_expand_16 is moved.)
+       *
+       * NOTE: this discards the low 16 bits of the user supplied background
+       * color, but until expand_16 works properly there is no choice!
+       */
+#     define CHOP(x) (x)=((png_uint_16)PNG_DIV257(x))
+      CHOP(png_ptr->background.red);
+      CHOP(png_ptr->background.green);
+      CHOP(png_ptr->background.blue);
+      CHOP(png_ptr->background.gray);
+#     undef CHOP
+   }
+#endif /* READ_BACKGROUND && READ_EXPAND_16 */
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
+   (defined(PNG_READ_SCALE_16_TO_8_SUPPORTED) || \
+   defined(PNG_READ_STRIP_16_TO_8_SUPPORTED))
+   if ((png_ptr->transformations & (PNG_16_TO_8|PNG_SCALE_16_TO_8)) != 0 &&
+       (png_ptr->transformations & PNG_COMPOSE) != 0 &&
+       (png_ptr->transformations & PNG_BACKGROUND_EXPAND) == 0 &&
+       png_ptr->bit_depth == 16)
+   {
+      /* On the other hand, if a 16-bit file is to be reduced to 8-bits per
+       * component this will also happen after PNG_COMPOSE and so the background
+       * color must be pre-expanded here.
+       *
+       * TODO: fix this too.
+       */
+      png_ptr->background.red = (png_uint_16)(png_ptr->background.red * 257);
+      png_ptr->background.green =
+         (png_uint_16)(png_ptr->background.green * 257);
+      png_ptr->background.blue = (png_uint_16)(png_ptr->background.blue * 257);
+      png_ptr->background.gray = (png_uint_16)(png_ptr->background.gray * 257);
+   }
+#endif
+
+   /* NOTE: below 'PNG_READ_ALPHA_MODE_SUPPORTED' is presumed to also enable the
+    * background support (see the comments in scripts/pnglibconf.dfa), this
+    * allows pre-multiplication of the alpha channel to be implemented as
+    * compositing on black.  This is probably sub-optimal and has been done in
+    * 1.5.4 betas simply to enable external critique and testing (i.e. to
+    * implement the new API quickly, without lots of internal changes.)
+    */
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+#  ifdef PNG_READ_BACKGROUND_SUPPORTED
+      /* Includes ALPHA_MODE */
+      png_ptr->background_1 = png_ptr->background;
+#  endif
+
+   /* This needs to change - in the palette image case a whole set of tables are
+    * built when it would be quicker to just calculate the correct value for
+    * each palette entry directly.  Also, the test is too tricky - why check
+    * PNG_RGB_TO_GRAY if PNG_GAMMA is not set?  The answer seems to be that
+    * PNG_GAMMA is cancelled even if the gamma is known?  The test excludes the
+    * PNG_COMPOSE case, so apparently if there is no *overall* gamma correction
+    * the gamma tables will not be built even if composition is required on a
+    * gamma encoded value.
+    *
+    * In 1.5.4 this is addressed below by an additional check on the individual
+    * file gamma - if it is not 1.0 both RGB_TO_GRAY and COMPOSE need the
+    * tables.
+    */
+   if ((png_ptr->transformations & PNG_GAMMA) != 0 ||
+       ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0 &&
+        (png_gamma_significant(png_ptr->colorspace.gamma) != 0 ||
+         png_gamma_significant(png_ptr->screen_gamma) != 0)) ||
+        ((png_ptr->transformations & PNG_COMPOSE) != 0 &&
+         (png_gamma_significant(png_ptr->colorspace.gamma) != 0 ||
+          png_gamma_significant(png_ptr->screen_gamma) != 0
+#  ifdef PNG_READ_BACKGROUND_SUPPORTED
+         || (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_UNIQUE &&
+           png_gamma_significant(png_ptr->background_gamma) != 0)
+#  endif
+        )) || ((png_ptr->transformations & PNG_ENCODE_ALPHA) != 0 &&
+       png_gamma_significant(png_ptr->screen_gamma) != 0))
+   {
+      png_build_gamma_table(png_ptr, png_ptr->bit_depth);
+
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+      if ((png_ptr->transformations & PNG_COMPOSE) != 0)
+      {
+         /* Issue a warning about this combination: because RGB_TO_GRAY is
+          * optimized to do the gamma transform if present yet do_background has
+          * to do the same thing if both options are set a
+          * double-gamma-correction happens.  This is true in all versions of
+          * libpng to date.
+          */
+         if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)
+            png_warning(png_ptr,
+               "libpng does not support gamma+background+rgb_to_gray");
+
+         if ((png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) != 0)
+         {
+            /* We don't get to here unless there is a tRNS chunk with non-opaque
+             * entries - see the checking code at the start of this function.
+             */
+            png_color back, back_1;
+            png_colorp palette = png_ptr->palette;
+            int num_palette = png_ptr->num_palette;
+            int i;
+            if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
+            {
+
+               back.red = png_ptr->gamma_table[png_ptr->background.red];
+               back.green = png_ptr->gamma_table[png_ptr->background.green];
+               back.blue = png_ptr->gamma_table[png_ptr->background.blue];
+
+               back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
+               back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
+               back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
+            }
+            else
+            {
+               png_fixed_point g, gs;
+
+               switch (png_ptr->background_gamma_type)
+               {
+                  case PNG_BACKGROUND_GAMMA_SCREEN:
+                     g = (png_ptr->screen_gamma);
+                     gs = PNG_FP_1;
+                     break;
+
+                  case PNG_BACKGROUND_GAMMA_FILE:
+                     g = png_reciprocal(png_ptr->colorspace.gamma);
+                     gs = png_reciprocal2(png_ptr->colorspace.gamma,
+                        png_ptr->screen_gamma);
+                     break;
+
+                  case PNG_BACKGROUND_GAMMA_UNIQUE:
+                     g = png_reciprocal(png_ptr->background_gamma);
+                     gs = png_reciprocal2(png_ptr->background_gamma,
+                        png_ptr->screen_gamma);
+                     break;
+                  default:
+                     g = PNG_FP_1;    /* back_1 */
+                     gs = PNG_FP_1;   /* back */
+                     break;
+               }
+
+               if (png_gamma_significant(gs) != 0)
+               {
+                  back.red = png_gamma_8bit_correct(png_ptr->background.red,
+                      gs);
+                  back.green = png_gamma_8bit_correct(png_ptr->background.green,
+                      gs);
+                  back.blue = png_gamma_8bit_correct(png_ptr->background.blue,
+                      gs);
+               }
+
+               else
+               {
+                  back.red   = (png_byte)png_ptr->background.red;
+                  back.green = (png_byte)png_ptr->background.green;
+                  back.blue  = (png_byte)png_ptr->background.blue;
+               }
+
+               if (png_gamma_significant(g) != 0)
+               {
+                  back_1.red = png_gamma_8bit_correct(png_ptr->background.red,
+                     g);
+                  back_1.green = png_gamma_8bit_correct(
+                     png_ptr->background.green, g);
+                  back_1.blue = png_gamma_8bit_correct(png_ptr->background.blue,
+                     g);
+               }
+
+               else
+               {
+                  back_1.red   = (png_byte)png_ptr->background.red;
+                  back_1.green = (png_byte)png_ptr->background.green;
+                  back_1.blue  = (png_byte)png_ptr->background.blue;
+               }
+            }
+
+            for (i = 0; i < num_palette; i++)
+            {
+               if (i < (int)png_ptr->num_trans &&
+                   png_ptr->trans_alpha[i] != 0xff)
+               {
+                  if (png_ptr->trans_alpha[i] == 0)
+                  {
+                     palette[i] = back;
+                  }
+                  else /* if (png_ptr->trans_alpha[i] != 0xff) */
+                  {
+                     png_byte v, w;
+
+                     v = png_ptr->gamma_to_1[palette[i].red];
+                     png_composite(w, v, png_ptr->trans_alpha[i], back_1.red);
+                     palette[i].red = png_ptr->gamma_from_1[w];
+
+                     v = png_ptr->gamma_to_1[palette[i].green];
+                     png_composite(w, v, png_ptr->trans_alpha[i], back_1.green);
+                     palette[i].green = png_ptr->gamma_from_1[w];
+
+                     v = png_ptr->gamma_to_1[palette[i].blue];
+                     png_composite(w, v, png_ptr->trans_alpha[i], back_1.blue);
+                     palette[i].blue = png_ptr->gamma_from_1[w];
+                  }
+               }
+               else
+               {
+                  palette[i].red = png_ptr->gamma_table[palette[i].red];
+                  palette[i].green = png_ptr->gamma_table[palette[i].green];
+                  palette[i].blue = png_ptr->gamma_table[palette[i].blue];
+               }
+            }
+
+            /* Prevent the transformations being done again.
+             *
+             * NOTE: this is highly dubious; it removes the transformations in
+             * place.  This seems inconsistent with the general treatment of the
+             * transformations elsewhere.
+             */
+            png_ptr->transformations &= ~(PNG_COMPOSE | PNG_GAMMA);
+         } /* color_type == PNG_COLOR_TYPE_PALETTE */
+
+         /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */
+         else /* color_type != PNG_COLOR_TYPE_PALETTE */
+         {
+            int gs_sig, g_sig;
+            png_fixed_point g = PNG_FP_1;  /* Correction to linear */
+            png_fixed_point gs = PNG_FP_1; /* Correction to screen */
+
+            switch (png_ptr->background_gamma_type)
+            {
+               case PNG_BACKGROUND_GAMMA_SCREEN:
+                  g = png_ptr->screen_gamma;
+                  /* gs = PNG_FP_1; */
+                  break;
+
+               case PNG_BACKGROUND_GAMMA_FILE:
+                  g = png_reciprocal(png_ptr->colorspace.gamma);
+                  gs = png_reciprocal2(png_ptr->colorspace.gamma,
+                     png_ptr->screen_gamma);
+                  break;
+
+               case PNG_BACKGROUND_GAMMA_UNIQUE:
+                  g = png_reciprocal(png_ptr->background_gamma);
+                  gs = png_reciprocal2(png_ptr->background_gamma,
+                      png_ptr->screen_gamma);
+                  break;
+
+               default:
+                  png_error(png_ptr, "invalid background gamma type");
+            }
+
+            g_sig = png_gamma_significant(g);
+            gs_sig = png_gamma_significant(gs);
+
+            if (g_sig != 0)
+               png_ptr->background_1.gray = png_gamma_correct(png_ptr,
+                   png_ptr->background.gray, g);
+
+            if (gs_sig != 0)
+               png_ptr->background.gray = png_gamma_correct(png_ptr,
+                   png_ptr->background.gray, gs);
+
+            if ((png_ptr->background.red != png_ptr->background.green) ||
+                (png_ptr->background.red != png_ptr->background.blue) ||
+                (png_ptr->background.red != png_ptr->background.gray))
+            {
+               /* RGB or RGBA with color background */
+               if (g_sig != 0)
+               {
+                  png_ptr->background_1.red = png_gamma_correct(png_ptr,
+                      png_ptr->background.red, g);
+
+                  png_ptr->background_1.green = png_gamma_correct(png_ptr,
+                      png_ptr->background.green, g);
+
+                  png_ptr->background_1.blue = png_gamma_correct(png_ptr,
+                      png_ptr->background.blue, g);
+               }
+
+               if (gs_sig != 0)
+               {
+                  png_ptr->background.red = png_gamma_correct(png_ptr,
+                      png_ptr->background.red, gs);
+
+                  png_ptr->background.green = png_gamma_correct(png_ptr,
+                      png_ptr->background.green, gs);
+
+                  png_ptr->background.blue = png_gamma_correct(png_ptr,
+                      png_ptr->background.blue, gs);
+               }
+            }
+
+            else
+            {
+               /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */
+               png_ptr->background_1.red = png_ptr->background_1.green
+                   = png_ptr->background_1.blue = png_ptr->background_1.gray;
+
+               png_ptr->background.red = png_ptr->background.green
+                   = png_ptr->background.blue = png_ptr->background.gray;
+            }
+
+            /* The background is now in screen gamma: */
+            png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_SCREEN;
+         } /* color_type != PNG_COLOR_TYPE_PALETTE */
+      }/* png_ptr->transformations & PNG_BACKGROUND */
+
+      else
+      /* Transformation does not include PNG_BACKGROUND */
+#endif /* READ_BACKGROUND */
+      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+         /* RGB_TO_GRAY needs to have non-gamma-corrected values! */
+         && ((png_ptr->transformations & PNG_EXPAND) == 0 ||
+         (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0)
+#endif
+         )
+      {
+         png_colorp palette = png_ptr->palette;
+         int num_palette = png_ptr->num_palette;
+         int i;
+
+         /* NOTE: there are other transformations that should probably be in
+          * here too.
+          */
+         for (i = 0; i < num_palette; i++)
+         {
+            palette[i].red = png_ptr->gamma_table[palette[i].red];
+            palette[i].green = png_ptr->gamma_table[palette[i].green];
+            palette[i].blue = png_ptr->gamma_table[palette[i].blue];
+         }
+
+         /* Done the gamma correction. */
+         png_ptr->transformations &= ~PNG_GAMMA;
+      } /* color_type == PALETTE && !PNG_BACKGROUND transformation */
+   }
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+   else
+#endif
+#endif /* READ_GAMMA */
+
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+   /* No GAMMA transformation (see the hanging else 4 lines above) */
+   if ((png_ptr->transformations & PNG_COMPOSE) != 0 &&
+       (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
+   {
+      int i;
+      int istop = (int)png_ptr->num_trans;
+      png_color back;
+      png_colorp palette = png_ptr->palette;
+
+      back.red   = (png_byte)png_ptr->background.red;
+      back.green = (png_byte)png_ptr->background.green;
+      back.blue  = (png_byte)png_ptr->background.blue;
+
+      for (i = 0; i < istop; i++)
+      {
+         if (png_ptr->trans_alpha[i] == 0)
+         {
+            palette[i] = back;
+         }
+
+         else if (png_ptr->trans_alpha[i] != 0xff)
+         {
+            /* The png_composite() macro is defined in png.h */
+            png_composite(palette[i].red, palette[i].red,
+                png_ptr->trans_alpha[i], back.red);
+
+            png_composite(palette[i].green, palette[i].green,
+                png_ptr->trans_alpha[i], back.green);
+
+            png_composite(palette[i].blue, palette[i].blue,
+                png_ptr->trans_alpha[i], back.blue);
+         }
+      }
+
+      png_ptr->transformations &= ~PNG_COMPOSE;
+   }
+#endif /* READ_BACKGROUND */
+
+#ifdef PNG_READ_SHIFT_SUPPORTED
+   if ((png_ptr->transformations & PNG_SHIFT) != 0 &&
+       (png_ptr->transformations & PNG_EXPAND) == 0 &&
+       (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
+   {
+      int i;
+      int istop = png_ptr->num_palette;
+      int shift = 8 - png_ptr->sig_bit.red;
+
+      png_ptr->transformations &= ~PNG_SHIFT;
+
+      /* significant bits can be in the range 1 to 7 for a meaninful result, if
+       * the number of significant bits is 0 then no shift is done (this is an
+       * error condition which is silently ignored.)
+       */
+      if (shift > 0 && shift < 8)
+         for (i=0; i<istop; ++i)
+         {
+            int component = png_ptr->palette[i].red;
+
+            component >>= shift;
+            png_ptr->palette[i].red = (png_byte)component;
+         }
+
+      shift = 8 - png_ptr->sig_bit.green;
+      if (shift > 0 && shift < 8)
+         for (i=0; i<istop; ++i)
+         {
+            int component = png_ptr->palette[i].green;
+
+            component >>= shift;
+            png_ptr->palette[i].green = (png_byte)component;
+         }
+
+      shift = 8 - png_ptr->sig_bit.blue;
+      if (shift > 0 && shift < 8)
+         for (i=0; i<istop; ++i)
+         {
+            int component = png_ptr->palette[i].blue;
+
+            component >>= shift;
+            png_ptr->palette[i].blue = (png_byte)component;
+         }
+   }
+#endif  /* READ_SHIFT */
+}
+
+/* Modify the info structure to reflect the transformations.  The
+ * info should be updated so a PNG file could be written with it,
+ * assuming the transformations result in valid PNG data.
+ */
+void /* PRIVATE */
+png_read_transform_info(png_structrp png_ptr, png_inforp info_ptr)
+{
+   png_debug(1, "in png_read_transform_info");
+
+#ifdef PNG_READ_EXPAND_SUPPORTED
+   if ((png_ptr->transformations & PNG_EXPAND) != 0)
+   {
+      if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      {
+         /* This check must match what actually happens in
+          * png_do_expand_palette; if it ever checks the tRNS chunk to see if
+          * it is all opaque we must do the same (at present it does not.)
+          */
+         if (png_ptr->num_trans > 0)
+            info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
+
+         else
+            info_ptr->color_type = PNG_COLOR_TYPE_RGB;
+
+         info_ptr->bit_depth = 8;
+         info_ptr->num_trans = 0;
+
+         if (png_ptr->palette == NULL)
+            png_error (png_ptr, "Palette is NULL in indexed image");
+      }
+      else
+      {
+         if (png_ptr->num_trans != 0)
+         {
+            if ((png_ptr->transformations & PNG_EXPAND_tRNS) != 0)
+               info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
+         }
+         if (info_ptr->bit_depth < 8)
+            info_ptr->bit_depth = 8;
+
+         info_ptr->num_trans = 0;
+      }
+   }
+#endif
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
+   defined(PNG_READ_ALPHA_MODE_SUPPORTED)
+   /* The following is almost certainly wrong unless the background value is in
+    * the screen space!
+    */
+   if ((png_ptr->transformations & PNG_COMPOSE) != 0)
+      info_ptr->background = png_ptr->background;
+#endif
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+   /* The following used to be conditional on PNG_GAMMA (prior to 1.5.4),
+    * however it seems that the code in png_init_read_transformations, which has
+    * been called before this from png_read_update_info->png_read_start_row
+    * sometimes does the gamma transform and cancels the flag.
+    *
+    * TODO: this looks wrong; the info_ptr should end up with a gamma equal to
+    * the screen_gamma value.  The following probably results in weirdness if
+    * the info_ptr is used by the app after the rows have been read.
+    */
+   info_ptr->colorspace.gamma = png_ptr->colorspace.gamma;
+#endif
+
+   if (info_ptr->bit_depth == 16)
+   {
+#  ifdef PNG_READ_16BIT_SUPPORTED
+#     ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
+         if ((png_ptr->transformations & PNG_SCALE_16_TO_8) != 0)
+            info_ptr->bit_depth = 8;
+#     endif
+
+#     ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
+         if ((png_ptr->transformations & PNG_16_TO_8) != 0)
+            info_ptr->bit_depth = 8;
+#     endif
+
+#  else
+      /* No 16 bit support: force chopping 16-bit input down to 8, in this case
+       * the app program can chose if both APIs are available by setting the
+       * correct scaling to use.
+       */
+#     ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
+         /* For compatibility with previous versions use the strip method by
+          * default.  This code works because if PNG_SCALE_16_TO_8 is already
+          * set the code below will do that in preference to the chop.
+          */
+         png_ptr->transformations |= PNG_16_TO_8;
+         info_ptr->bit_depth = 8;
+#     else
+
+#        ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
+            png_ptr->transformations |= PNG_SCALE_16_TO_8;
+            info_ptr->bit_depth = 8;
+#        else
+
+            CONFIGURATION ERROR: you must enable at least one 16 to 8 method
+#        endif
+#    endif
+#endif /* !READ_16BIT */
+   }
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+   if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0)
+      info_ptr->color_type = (png_byte)(info_ptr->color_type |
+         PNG_COLOR_MASK_COLOR);
+#endif
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+   if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)
+      info_ptr->color_type = (png_byte)(info_ptr->color_type &
+         ~PNG_COLOR_MASK_COLOR);
+#endif
+
+#ifdef PNG_READ_QUANTIZE_SUPPORTED
+   if ((png_ptr->transformations & PNG_QUANTIZE) != 0)
+   {
+      if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
+          (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) &&
+          png_ptr->palette_lookup != 0 && info_ptr->bit_depth == 8)
+      {
+         info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
+      }
+   }
+#endif
+
+#ifdef PNG_READ_EXPAND_16_SUPPORTED
+   if ((png_ptr->transformations & PNG_EXPAND_16) != 0 &&
+       info_ptr->bit_depth == 8 &&
+       info_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
+   {
+      info_ptr->bit_depth = 16;
+   }
+#endif
+
+#ifdef PNG_READ_PACK_SUPPORTED
+   if ((png_ptr->transformations & PNG_PACK) != 0 &&
+       (info_ptr->bit_depth < 8))
+      info_ptr->bit_depth = 8;
+#endif
+
+   if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      info_ptr->channels = 1;
+
+   else if ((info_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
+      info_ptr->channels = 3;
+
+   else
+      info_ptr->channels = 1;
+
+#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
+   if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0)
+   {
+      info_ptr->color_type = (png_byte)(info_ptr->color_type &
+         ~PNG_COLOR_MASK_ALPHA);
+      info_ptr->num_trans = 0;
+   }
+#endif
+
+   if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)
+      info_ptr->channels++;
+
+#ifdef PNG_READ_FILLER_SUPPORTED
+   /* STRIP_ALPHA and FILLER allowed:  MASK_ALPHA bit stripped above */
+   if ((png_ptr->transformations & PNG_FILLER) != 0 &&
+       (info_ptr->color_type == PNG_COLOR_TYPE_RGB ||
+       info_ptr->color_type == PNG_COLOR_TYPE_GRAY))
+   {
+      info_ptr->channels++;
+      /* If adding a true alpha channel not just filler */
+      if ((png_ptr->transformations & PNG_ADD_ALPHA) != 0)
+         info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
+   }
+#endif
+
+#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \
+defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
+   if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0)
+   {
+      if (info_ptr->bit_depth < png_ptr->user_transform_depth)
+         info_ptr->bit_depth = png_ptr->user_transform_depth;
+
+      if (info_ptr->channels < png_ptr->user_transform_channels)
+         info_ptr->channels = png_ptr->user_transform_channels;
+   }
+#endif
+
+   info_ptr->pixel_depth = (png_byte)(info_ptr->channels *
+       info_ptr->bit_depth);
+
+   info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, info_ptr->width);
+
+   /* Adding in 1.5.4: cache the above value in png_struct so that we can later
+    * check in png_rowbytes that the user buffer won't get overwritten.  Note
+    * that the field is not always set - if png_read_update_info isn't called
+    * the application has to either not do any transforms or get the calculation
+    * right itself.
+    */
+   png_ptr->info_rowbytes = info_ptr->rowbytes;
+
+#ifndef PNG_READ_EXPAND_SUPPORTED
+   if (png_ptr != NULL)
+      return;
+#endif
+}
+
+#ifdef PNG_READ_PACK_SUPPORTED
+/* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
+ * without changing the actual values.  Thus, if you had a row with
+ * a bit depth of 1, you would end up with bytes that only contained
+ * the numbers 0 or 1.  If you would rather they contain 0 and 255, use
+ * png_do_shift() after this.
+ */
+static void
+png_do_unpack(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_unpack");
+
+   if (row_info->bit_depth < 8)
+   {
+      png_uint_32 i;
+      png_uint_32 row_width=row_info->width;
+
+      switch (row_info->bit_depth)
+      {
+         case 1:
+         {
+            png_bytep sp = row + (png_size_t)((row_width - 1) >> 3);
+            png_bytep dp = row + (png_size_t)row_width - 1;
+            png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07);
+            for (i = 0; i < row_width; i++)
+            {
+               *dp = (png_byte)((*sp >> shift) & 0x01);
+
+               if (shift == 7)
+               {
+                  shift = 0;
+                  sp--;
+               }
+
+               else
+                  shift++;
+
+               dp--;
+            }
+            break;
+         }
+
+         case 2:
+         {
+
+            png_bytep sp = row + (png_size_t)((row_width - 1) >> 2);
+            png_bytep dp = row + (png_size_t)row_width - 1;
+            png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
+            for (i = 0; i < row_width; i++)
+            {
+               *dp = (png_byte)((*sp >> shift) & 0x03);
+
+               if (shift == 6)
+               {
+                  shift = 0;
+                  sp--;
+               }
+
+               else
+                  shift += 2;
+
+               dp--;
+            }
+            break;
+         }
+
+         case 4:
+         {
+            png_bytep sp = row + (png_size_t)((row_width - 1) >> 1);
+            png_bytep dp = row + (png_size_t)row_width - 1;
+            png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
+            for (i = 0; i < row_width; i++)
+            {
+               *dp = (png_byte)((*sp >> shift) & 0x0f);
+
+               if (shift == 4)
+               {
+                  shift = 0;
+                  sp--;
+               }
+
+               else
+                  shift = 4;
+
+               dp--;
+            }
+            break;
+         }
+
+         default:
+            break;
+      }
+      row_info->bit_depth = 8;
+      row_info->pixel_depth = (png_byte)(8 * row_info->channels);
+      row_info->rowbytes = row_width * row_info->channels;
+   }
+}
+#endif
+
+#ifdef PNG_READ_SHIFT_SUPPORTED
+/* Reverse the effects of png_do_shift.  This routine merely shifts the
+ * pixels back to their significant bits values.  Thus, if you have
+ * a row of bit depth 8, but only 5 are significant, this will shift
+ * the values back to 0 through 31.
+ */
+static void
+png_do_unshift(png_row_infop row_info, png_bytep row,
+    png_const_color_8p sig_bits)
+{
+   int color_type;
+
+   png_debug(1, "in png_do_unshift");
+
+   /* The palette case has already been handled in the _init routine. */
+   color_type = row_info->color_type;
+
+   if (color_type != PNG_COLOR_TYPE_PALETTE)
+   {
+      int shift[4];
+      int channels = 0;
+      int bit_depth = row_info->bit_depth;
+
+      if ((color_type & PNG_COLOR_MASK_COLOR) != 0)
+      {
+         shift[channels++] = bit_depth - sig_bits->red;
+         shift[channels++] = bit_depth - sig_bits->green;
+         shift[channels++] = bit_depth - sig_bits->blue;
+      }
+
+      else
+      {
+         shift[channels++] = bit_depth - sig_bits->gray;
+      }
+
+      if ((color_type & PNG_COLOR_MASK_ALPHA) != 0)
+      {
+         shift[channels++] = bit_depth - sig_bits->alpha;
+      }
+
+      {
+         int c, have_shift;
+
+         for (c = have_shift = 0; c < channels; ++c)
+         {
+            /* A shift of more than the bit depth is an error condition but it
+             * gets ignored here.
+             */
+            if (shift[c] <= 0 || shift[c] >= bit_depth)
+               shift[c] = 0;
+
+            else
+               have_shift = 1;
+         }
+
+         if (have_shift == 0)
+            return;
+      }
+
+      switch (bit_depth)
+      {
+         default:
+         /* Must be 1bpp gray: should not be here! */
+            /* NOTREACHED */
+            break;
+
+         case 2:
+         /* Must be 2bpp gray */
+         /* assert(channels == 1 && shift[0] == 1) */
+         {
+            png_bytep bp = row;
+            png_bytep bp_end = bp + row_info->rowbytes;
+
+            while (bp < bp_end)
+            {
+               int b = (*bp >> 1) & 0x55;
+               *bp++ = (png_byte)b;
+            }
+            break;
+         }
+
+         case 4:
+         /* Must be 4bpp gray */
+         /* assert(channels == 1) */
+         {
+            png_bytep bp = row;
+            png_bytep bp_end = bp + row_info->rowbytes;
+            int gray_shift = shift[0];
+            int mask =  0xf >> gray_shift;
+
+            mask |= mask << 4;
+
+            while (bp < bp_end)
+            {
+               int b = (*bp >> gray_shift) & mask;
+               *bp++ = (png_byte)b;
+            }
+            break;
+         }
+
+         case 8:
+         /* Single byte components, G, GA, RGB, RGBA */
+         {
+            png_bytep bp = row;
+            png_bytep bp_end = bp + row_info->rowbytes;
+            int channel = 0;
+
+            while (bp < bp_end)
+            {
+               int b = *bp >> shift[channel];
+               if (++channel >= channels)
+                  channel = 0;
+               *bp++ = (png_byte)b;
+            }
+            break;
+         }
+
+#ifdef PNG_READ_16BIT_SUPPORTED
+         case 16:
+         /* Double byte components, G, GA, RGB, RGBA */
+         {
+            png_bytep bp = row;
+            png_bytep bp_end = bp + row_info->rowbytes;
+            int channel = 0;
+
+            while (bp < bp_end)
+            {
+               int value = (bp[0] << 8) + bp[1];
+
+               value >>= shift[channel];
+               if (++channel >= channels)
+                  channel = 0;
+               *bp++ = (png_byte)(value >> 8);
+               *bp++ = (png_byte)(value & 0xff);
+            }
+            break;
+         }
+#endif
+      }
+   }
+}
+#endif
+
+#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
+/* Scale rows of bit depth 16 down to 8 accurately */
+static void
+png_do_scale_16_to_8(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_scale_16_to_8");
+
+   if (row_info->bit_depth == 16)
+   {
+      png_bytep sp = row; /* source */
+      png_bytep dp = row; /* destination */
+      png_bytep ep = sp + row_info->rowbytes; /* end+1 */
+
+      while (sp < ep)
+      {
+         /* The input is an array of 16 bit components, these must be scaled to
+          * 8 bits each.  For a 16 bit value V the required value (from the PNG
+          * specification) is:
+          *
+          *    (V * 255) / 65535
+          *
+          * This reduces to round(V / 257), or floor((V + 128.5)/257)
+          *
+          * Represent V as the two byte value vhi.vlo.  Make a guess that the
+          * result is the top byte of V, vhi, then the correction to this value
+          * is:
+          *
+          *    error = floor(((V-vhi.vhi) + 128.5) / 257)
+          *          = floor(((vlo-vhi) + 128.5) / 257)
+          *
+          * This can be approximated using integer arithmetic (and a signed
+          * shift):
+          *
+          *    error = (vlo-vhi+128) >> 8;
+          *
+          * The approximate differs from the exact answer only when (vlo-vhi) is
+          * 128; it then gives a correction of +1 when the exact correction is
+          * 0.  This gives 128 errors.  The exact answer (correct for all 16 bit
+          * input values) is:
+          *
+          *    error = (vlo-vhi+128)*65535 >> 24;
+          *
+          * An alternative arithmetic calculation which also gives no errors is:
+          *
+          *    (V * 255 + 32895) >> 16
+          */
+
+         png_int_32 tmp = *sp++; /* must be signed! */
+         tmp += (((int)*sp++ - tmp + 128) * 65535) >> 24;
+         *dp++ = (png_byte)tmp;
+      }
+
+      row_info->bit_depth = 8;
+      row_info->pixel_depth = (png_byte)(8 * row_info->channels);
+      row_info->rowbytes = row_info->width * row_info->channels;
+   }
+}
+#endif
+
+#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
+static void
+/* Simply discard the low byte.  This was the default behavior prior
+ * to libpng-1.5.4.
+ */
+png_do_chop(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_chop");
+
+   if (row_info->bit_depth == 16)
+   {
+      png_bytep sp = row; /* source */
+      png_bytep dp = row; /* destination */
+      png_bytep ep = sp + row_info->rowbytes; /* end+1 */
+
+      while (sp < ep)
+      {
+         *dp++ = *sp;
+         sp += 2; /* skip low byte */
+      }
+
+      row_info->bit_depth = 8;
+      row_info->pixel_depth = (png_byte)(8 * row_info->channels);
+      row_info->rowbytes = row_info->width * row_info->channels;
+   }
+}
+#endif
+
+#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
+static void
+png_do_read_swap_alpha(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_read_swap_alpha");
+
+   {
+      png_uint_32 row_width = row_info->width;
+      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+      {
+         /* This converts from RGBA to ARGB */
+         if (row_info->bit_depth == 8)
+         {
+            png_bytep sp = row + row_info->rowbytes;
+            png_bytep dp = sp;
+            png_byte save;
+            png_uint_32 i;
+
+            for (i = 0; i < row_width; i++)
+            {
+               save = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = save;
+            }
+         }
+
+#ifdef PNG_READ_16BIT_SUPPORTED
+         /* This converts from RRGGBBAA to AARRGGBB */
+         else
+         {
+            png_bytep sp = row + row_info->rowbytes;
+            png_bytep dp = sp;
+            png_byte save[2];
+            png_uint_32 i;
+
+            for (i = 0; i < row_width; i++)
+            {
+               save[0] = *(--sp);
+               save[1] = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = save[0];
+               *(--dp) = save[1];
+            }
+         }
+#endif
+      }
+
+      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+      {
+         /* This converts from GA to AG */
+         if (row_info->bit_depth == 8)
+         {
+            png_bytep sp = row + row_info->rowbytes;
+            png_bytep dp = sp;
+            png_byte save;
+            png_uint_32 i;
+
+            for (i = 0; i < row_width; i++)
+            {
+               save = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = save;
+            }
+         }
+
+#ifdef PNG_READ_16BIT_SUPPORTED
+         /* This converts from GGAA to AAGG */
+         else
+         {
+            png_bytep sp = row + row_info->rowbytes;
+            png_bytep dp = sp;
+            png_byte save[2];
+            png_uint_32 i;
+
+            for (i = 0; i < row_width; i++)
+            {
+               save[0] = *(--sp);
+               save[1] = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = save[0];
+               *(--dp) = save[1];
+            }
+         }
+#endif
+      }
+   }
+}
+#endif
+
+#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
+static void
+png_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
+{
+   png_uint_32 row_width;
+   png_debug(1, "in png_do_read_invert_alpha");
+
+   row_width = row_info->width;
+   if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+   {
+      if (row_info->bit_depth == 8)
+      {
+         /* This inverts the alpha channel in RGBA */
+         png_bytep sp = row + row_info->rowbytes;
+         png_bytep dp = sp;
+         png_uint_32 i;
+
+         for (i = 0; i < row_width; i++)
+         {
+            *(--dp) = (png_byte)(255 - *(--sp));
+
+/*          This does nothing:
+            *(--dp) = *(--sp);
+            *(--dp) = *(--sp);
+            *(--dp) = *(--sp);
+            We can replace it with:
+*/
+            sp-=3;
+            dp=sp;
+         }
+      }
+
+#ifdef PNG_READ_16BIT_SUPPORTED
+      /* This inverts the alpha channel in RRGGBBAA */
+      else
+      {
+         png_bytep sp = row + row_info->rowbytes;
+         png_bytep dp = sp;
+         png_uint_32 i;
+
+         for (i = 0; i < row_width; i++)
+         {
+            *(--dp) = (png_byte)(255 - *(--sp));
+            *(--dp) = (png_byte)(255 - *(--sp));
+
+/*          This does nothing:
+            *(--dp) = *(--sp);
+            *(--dp) = *(--sp);
+            *(--dp) = *(--sp);
+            *(--dp) = *(--sp);
+            *(--dp) = *(--sp);
+            *(--dp) = *(--sp);
+            We can replace it with:
+*/
+            sp-=6;
+            dp=sp;
+         }
+      }
+#endif
+   }
+   else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+   {
+      if (row_info->bit_depth == 8)
+      {
+         /* This inverts the alpha channel in GA */
+         png_bytep sp = row + row_info->rowbytes;
+         png_bytep dp = sp;
+         png_uint_32 i;
+
+         for (i = 0; i < row_width; i++)
+         {
+            *(--dp) = (png_byte)(255 - *(--sp));
+            *(--dp) = *(--sp);
+         }
+      }
+
+#ifdef PNG_READ_16BIT_SUPPORTED
+      else
+      {
+         /* This inverts the alpha channel in GGAA */
+         png_bytep sp  = row + row_info->rowbytes;
+         png_bytep dp = sp;
+         png_uint_32 i;
+
+         for (i = 0; i < row_width; i++)
+         {
+            *(--dp) = (png_byte)(255 - *(--sp));
+            *(--dp) = (png_byte)(255 - *(--sp));
+/*
+            *(--dp) = *(--sp);
+            *(--dp) = *(--sp);
+*/
+            sp-=2;
+            dp=sp;
+         }
+      }
+#endif
+   }
+}
+#endif
+
+#ifdef PNG_READ_FILLER_SUPPORTED
+/* Add filler channel if we have RGB color */
+static void
+png_do_read_filler(png_row_infop row_info, png_bytep row,
+    png_uint_32 filler, png_uint_32 flags)
+{
+   png_uint_32 i;
+   png_uint_32 row_width = row_info->width;
+
+#ifdef PNG_READ_16BIT_SUPPORTED
+   png_byte hi_filler = (png_byte)((filler>>8) & 0xff);
+#endif
+   png_byte lo_filler = (png_byte)(filler & 0xff);
+
+   png_debug(1, "in png_do_read_filler");
+
+   if (
+       row_info->color_type == PNG_COLOR_TYPE_GRAY)
+   {
+      if (row_info->bit_depth == 8)
+      {
+         if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
+         {
+            /* This changes the data from G to GX */
+            png_bytep sp = row + (png_size_t)row_width;
+            png_bytep dp =  sp + (png_size_t)row_width;
+            for (i = 1; i < row_width; i++)
+            {
+               *(--dp) = lo_filler;
+               *(--dp) = *(--sp);
+            }
+            *(--dp) = lo_filler;
+            row_info->channels = 2;
+            row_info->pixel_depth = 16;
+            row_info->rowbytes = row_width * 2;
+         }
+
+         else
+         {
+            /* This changes the data from G to XG */
+            png_bytep sp = row + (png_size_t)row_width;
+            png_bytep dp = sp  + (png_size_t)row_width;
+            for (i = 0; i < row_width; i++)
+            {
+               *(--dp) = *(--sp);
+               *(--dp) = lo_filler;
+            }
+            row_info->channels = 2;
+            row_info->pixel_depth = 16;
+            row_info->rowbytes = row_width * 2;
+         }
+      }
+
+#ifdef PNG_READ_16BIT_SUPPORTED
+      else if (row_info->bit_depth == 16)
+      {
+         if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
+         {
+            /* This changes the data from GG to GGXX */
+            png_bytep sp = row + (png_size_t)row_width * 2;
+            png_bytep dp = sp  + (png_size_t)row_width * 2;
+            for (i = 1; i < row_width; i++)
+            {
+               *(--dp) = hi_filler;
+               *(--dp) = lo_filler;
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+            }
+            *(--dp) = hi_filler;
+            *(--dp) = lo_filler;
+            row_info->channels = 2;
+            row_info->pixel_depth = 32;
+            row_info->rowbytes = row_width * 4;
+         }
+
+         else
+         {
+            /* This changes the data from GG to XXGG */
+            png_bytep sp = row + (png_size_t)row_width * 2;
+            png_bytep dp = sp  + (png_size_t)row_width * 2;
+            for (i = 0; i < row_width; i++)
+            {
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = hi_filler;
+               *(--dp) = lo_filler;
+            }
+            row_info->channels = 2;
+            row_info->pixel_depth = 32;
+            row_info->rowbytes = row_width * 4;
+         }
+      }
+#endif
+   } /* COLOR_TYPE == GRAY */
+   else if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+   {
+      if (row_info->bit_depth == 8)
+      {
+         if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
+         {
+            /* This changes the data from RGB to RGBX */
+            png_bytep sp = row + (png_size_t)row_width * 3;
+            png_bytep dp = sp  + (png_size_t)row_width;
+            for (i = 1; i < row_width; i++)
+            {
+               *(--dp) = lo_filler;
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+            }
+            *(--dp) = lo_filler;
+            row_info->channels = 4;
+            row_info->pixel_depth = 32;
+            row_info->rowbytes = row_width * 4;
+         }
+
+         else
+         {
+            /* This changes the data from RGB to XRGB */
+            png_bytep sp = row + (png_size_t)row_width * 3;
+            png_bytep dp = sp + (png_size_t)row_width;
+            for (i = 0; i < row_width; i++)
+            {
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = lo_filler;
+            }
+            row_info->channels = 4;
+            row_info->pixel_depth = 32;
+            row_info->rowbytes = row_width * 4;
+         }
+      }
+
+#ifdef PNG_READ_16BIT_SUPPORTED
+      else if (row_info->bit_depth == 16)
+      {
+         if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
+         {
+            /* This changes the data from RRGGBB to RRGGBBXX */
+            png_bytep sp = row + (png_size_t)row_width * 6;
+            png_bytep dp = sp  + (png_size_t)row_width * 2;
+            for (i = 1; i < row_width; i++)
+            {
+               *(--dp) = hi_filler;
+               *(--dp) = lo_filler;
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+            }
+            *(--dp) = hi_filler;
+            *(--dp) = lo_filler;
+            row_info->channels = 4;
+            row_info->pixel_depth = 64;
+            row_info->rowbytes = row_width * 8;
+         }
+
+         else
+         {
+            /* This changes the data from RRGGBB to XXRRGGBB */
+            png_bytep sp = row + (png_size_t)row_width * 6;
+            png_bytep dp = sp  + (png_size_t)row_width * 2;
+            for (i = 0; i < row_width; i++)
+            {
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = hi_filler;
+               *(--dp) = lo_filler;
+            }
+
+            row_info->channels = 4;
+            row_info->pixel_depth = 64;
+            row_info->rowbytes = row_width * 8;
+         }
+      }
+#endif
+   } /* COLOR_TYPE == RGB */
+}
+#endif
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+/* Expand grayscale files to RGB, with or without alpha */
+static void
+png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
+{
+   png_uint_32 i;
+   png_uint_32 row_width = row_info->width;
+
+   png_debug(1, "in png_do_gray_to_rgb");
+
+   if (row_info->bit_depth >= 8 &&
+       (row_info->color_type & PNG_COLOR_MASK_COLOR) == 0)
+   {
+      if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
+      {
+         if (row_info->bit_depth == 8)
+         {
+            /* This changes G to RGB */
+            png_bytep sp = row + (png_size_t)row_width - 1;
+            png_bytep dp = sp  + (png_size_t)row_width * 2;
+            for (i = 0; i < row_width; i++)
+            {
+               *(dp--) = *sp;
+               *(dp--) = *sp;
+               *(dp--) = *(sp--);
+            }
+         }
+
+         else
+         {
+            /* This changes GG to RRGGBB */
+            png_bytep sp = row + (png_size_t)row_width * 2 - 1;
+            png_bytep dp = sp  + (png_size_t)row_width * 4;
+            for (i = 0; i < row_width; i++)
+            {
+               *(dp--) = *sp;
+               *(dp--) = *(sp - 1);
+               *(dp--) = *sp;
+               *(dp--) = *(sp - 1);
+               *(dp--) = *(sp--);
+               *(dp--) = *(sp--);
+            }
+         }
+      }
+
+      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+      {
+         if (row_info->bit_depth == 8)
+         {
+            /* This changes GA to RGBA */
+            png_bytep sp = row + (png_size_t)row_width * 2 - 1;
+            png_bytep dp = sp  + (png_size_t)row_width * 2;
+            for (i = 0; i < row_width; i++)
+            {
+               *(dp--) = *(sp--);
+               *(dp--) = *sp;
+               *(dp--) = *sp;
+               *(dp--) = *(sp--);
+            }
+         }
+
+         else
+         {
+            /* This changes GGAA to RRGGBBAA */
+            png_bytep sp = row + (png_size_t)row_width * 4 - 1;
+            png_bytep dp = sp  + (png_size_t)row_width * 4;
+            for (i = 0; i < row_width; i++)
+            {
+               *(dp--) = *(sp--);
+               *(dp--) = *(sp--);
+               *(dp--) = *sp;
+               *(dp--) = *(sp - 1);
+               *(dp--) = *sp;
+               *(dp--) = *(sp - 1);
+               *(dp--) = *(sp--);
+               *(dp--) = *(sp--);
+            }
+         }
+      }
+      row_info->channels = (png_byte)(row_info->channels + 2);
+      row_info->color_type |= PNG_COLOR_MASK_COLOR;
+      row_info->pixel_depth = (png_byte)(row_info->channels *
+          row_info->bit_depth);
+      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
+   }
+}
+#endif
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+/* Reduce RGB files to grayscale, with or without alpha
+ * using the equation given in Poynton's ColorFAQ of 1998-01-04 at
+ * <http://www.inforamp.net/~poynton/>  (THIS LINK IS DEAD June 2008 but
+ * versions dated 1998 through November 2002 have been archived at
+ * http://web.archive.org/web/20000816232553/http://www.inforamp.net/
+ * ~poynton/notes/colour_and_gamma/ColorFAQ.txt )
+ * Charles Poynton poynton at poynton.com
+ *
+ *     Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
+ *
+ *  which can be expressed with integers as
+ *
+ *     Y = (6969 * R + 23434 * G + 2365 * B)/32768
+ *
+ * Poynton's current link (as of January 2003 through July 2011):
+ * <http://www.poynton.com/notes/colour_and_gamma/>
+ * has changed the numbers slightly:
+ *
+ *     Y = 0.2126*R + 0.7152*G + 0.0722*B
+ *
+ *  which can be expressed with integers as
+ *
+ *     Y = (6966 * R + 23436 * G + 2366 * B)/32768
+ *
+ *  Historically, however, libpng uses numbers derived from the ITU-R Rec 709
+ *  end point chromaticities and the D65 white point.  Depending on the
+ *  precision used for the D65 white point this produces a variety of different
+ *  numbers, however if the four decimal place value used in ITU-R Rec 709 is
+ *  used (0.3127,0.3290) the Y calculation would be:
+ *
+ *     Y = (6968 * R + 23435 * G + 2366 * B)/32768
+ *
+ *  While this is correct the rounding results in an overflow for white, because
+ *  the sum of the rounded coefficients is 32769, not 32768.  Consequently
+ *  libpng uses, instead, the closest non-overflowing approximation:
+ *
+ *     Y = (6968 * R + 23434 * G + 2366 * B)/32768
+ *
+ *  Starting with libpng-1.5.5, if the image being converted has a cHRM chunk
+ *  (including an sRGB chunk) then the chromaticities are used to calculate the
+ *  coefficients.  See the chunk handling in pngrutil.c for more information.
+ *
+ *  In all cases the calculation is to be done in a linear colorspace.  If no
+ *  gamma information is available to correct the encoding of the original RGB
+ *  values this results in an implicit assumption that the original PNG RGB
+ *  values were linear.
+ *
+ *  Other integer coefficents can be used via png_set_rgb_to_gray().  Because
+ *  the API takes just red and green coefficients the blue coefficient is
+ *  calculated to make the sum 32768.  This will result in different rounding
+ *  to that used above.
+ */
+static int
+png_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row)
+
+{
+   int rgb_error = 0;
+
+   png_debug(1, "in png_do_rgb_to_gray");
+
+   if ((row_info->color_type & PNG_COLOR_MASK_PALETTE) == 0 &&
+       (row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
+   {
+      PNG_CONST png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;
+      PNG_CONST png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff;
+      PNG_CONST png_uint_32 bc = 32768 - rc - gc;
+      PNG_CONST png_uint_32 row_width = row_info->width;
+      PNG_CONST int have_alpha =
+         (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0;
+
+      if (row_info->bit_depth == 8)
+      {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+         /* Notice that gamma to/from 1 are not necessarily inverses (if
+          * there is an overall gamma correction).  Prior to 1.5.5 this code
+          * checked the linearized values for equality; this doesn't match
+          * the documentation, the original values must be checked.
+          */
+         if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
+         {
+            png_bytep sp = row;
+            png_bytep dp = row;
+            png_uint_32 i;
+
+            for (i = 0; i < row_width; i++)
+            {
+               png_byte red   = *(sp++);
+               png_byte green = *(sp++);
+               png_byte blue  = *(sp++);
+
+               if (red != green || red != blue)
+               {
+                  red = png_ptr->gamma_to_1[red];
+                  green = png_ptr->gamma_to_1[green];
+                  blue = png_ptr->gamma_to_1[blue];
+
+                  rgb_error |= 1;
+                  *(dp++) = png_ptr->gamma_from_1[
+                      (rc*red + gc*green + bc*blue + 16384)>>15];
+               }
+
+               else
+               {
+                  /* If there is no overall correction the table will not be
+                   * set.
+                   */
+                  if (png_ptr->gamma_table != NULL)
+                     red = png_ptr->gamma_table[red];
+
+                  *(dp++) = red;
+               }
+
+               if (have_alpha != 0)
+                  *(dp++) = *(sp++);
+            }
+         }
+         else
+#endif
+         {
+            png_bytep sp = row;
+            png_bytep dp = row;
+            png_uint_32 i;
+
+            for (i = 0; i < row_width; i++)
+            {
+               png_byte red   = *(sp++);
+               png_byte green = *(sp++);
+               png_byte blue  = *(sp++);
+
+               if (red != green || red != blue)
+               {
+                  rgb_error |= 1;
+                  /* NOTE: this is the historical approach which simply
+                   * truncates the results.
+                   */
+                  *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15);
+               }
+
+               else
+                  *(dp++) = red;
+
+               if (have_alpha != 0)
+                  *(dp++) = *(sp++);
+            }
+         }
+      }
+
+      else /* RGB bit_depth == 16 */
+      {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+         if (png_ptr->gamma_16_to_1 != NULL && png_ptr->gamma_16_from_1 != NULL)
+         {
+            png_bytep sp = row;
+            png_bytep dp = row;
+            png_uint_32 i;
+
+            for (i = 0; i < row_width; i++)
+            {
+               png_uint_16 red, green, blue, w;
+
+               red   = (png_uint_16)(((*(sp)) << 8) | *(sp + 1)); sp += 2;
+               green = (png_uint_16)(((*(sp)) << 8) | *(sp + 1)); sp += 2;
+               blue  = (png_uint_16)(((*(sp)) << 8) | *(sp + 1)); sp += 2;
+
+               if (red == green && red == blue)
+               {
+                  if (png_ptr->gamma_16_table != NULL)
+                     w = png_ptr->gamma_16_table[(red & 0xff)
+                         >> png_ptr->gamma_shift][red >> 8];
+
+                  else
+                     w = red;
+               }
+
+               else
+               {
+                  png_uint_16 red_1   = png_ptr->gamma_16_to_1[(red&0xff)
+                      >> png_ptr->gamma_shift][red>>8];
+                  png_uint_16 green_1 =
+                      png_ptr->gamma_16_to_1[(green&0xff) >>
+                      png_ptr->gamma_shift][green>>8];
+                  png_uint_16 blue_1  = png_ptr->gamma_16_to_1[(blue&0xff)
+                      >> png_ptr->gamma_shift][blue>>8];
+                  png_uint_16 gray16  = (png_uint_16)((rc*red_1 + gc*green_1
+                      + bc*blue_1 + 16384)>>15);
+                  w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
+                      png_ptr->gamma_shift][gray16 >> 8];
+                  rgb_error |= 1;
+               }
+
+               *(dp++) = (png_byte)((w>>8) & 0xff);
+               *(dp++) = (png_byte)(w & 0xff);
+
+               if (have_alpha != 0)
+               {
+                  *(dp++) = *(sp++);
+                  *(dp++) = *(sp++);
+               }
+            }
+         }
+         else
+#endif
+         {
+            png_bytep sp = row;
+            png_bytep dp = row;
+            png_uint_32 i;
+
+            for (i = 0; i < row_width; i++)
+            {
+               png_uint_16 red, green, blue, gray16;
+
+               red   = (png_uint_16)(((*(sp)) << 8) | *(sp + 1)); sp += 2;
+               green = (png_uint_16)(((*(sp)) << 8) | *(sp + 1)); sp += 2;
+               blue  = (png_uint_16)(((*(sp)) << 8) | *(sp + 1)); sp += 2;
+
+               if (red != green || red != blue)
+                  rgb_error |= 1;
+
+               /* From 1.5.5 in the 16 bit case do the accurate conversion even
+                * in the 'fast' case - this is because this is where the code
+                * ends up when handling linear 16 bit data.
+                */
+               gray16  = (png_uint_16)((rc*red + gc*green + bc*blue + 16384) >>
+                  15);
+               *(dp++) = (png_byte)((gray16 >> 8) & 0xff);
+               *(dp++) = (png_byte)(gray16 & 0xff);
+
+               if (have_alpha != 0)
+               {
+                  *(dp++) = *(sp++);
+                  *(dp++) = *(sp++);
+               }
+            }
+         }
+      }
+
+      row_info->channels = (png_byte)(row_info->channels - 2);
+      row_info->color_type = (png_byte)(row_info->color_type &
+          ~PNG_COLOR_MASK_COLOR);
+      row_info->pixel_depth = (png_byte)(row_info->channels *
+          row_info->bit_depth);
+      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
+   }
+   return rgb_error;
+}
+#endif
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
+   defined(PNG_READ_ALPHA_MODE_SUPPORTED)
+/* Replace any alpha or transparency with the supplied background color.
+ * "background" is already in the screen gamma, while "background_1" is
+ * at a gamma of 1.0.  Paletted files have already been taken care of.
+ */
+static void
+png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
+{
+#ifdef PNG_READ_GAMMA_SUPPORTED
+   png_const_bytep gamma_table = png_ptr->gamma_table;
+   png_const_bytep gamma_from_1 = png_ptr->gamma_from_1;
+   png_const_bytep gamma_to_1 = png_ptr->gamma_to_1;
+   png_const_uint_16pp gamma_16 = png_ptr->gamma_16_table;
+   png_const_uint_16pp gamma_16_from_1 = png_ptr->gamma_16_from_1;
+   png_const_uint_16pp gamma_16_to_1 = png_ptr->gamma_16_to_1;
+   int gamma_shift = png_ptr->gamma_shift;
+   int optimize = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0;
+#endif
+
+   png_bytep sp;
+   png_uint_32 i;
+   png_uint_32 row_width = row_info->width;
+   int shift;
+
+   png_debug(1, "in png_do_compose");
+
+   {
+      switch (row_info->color_type)
+      {
+         case PNG_COLOR_TYPE_GRAY:
+         {
+            switch (row_info->bit_depth)
+            {
+               case 1:
+               {
+                  sp = row;
+                  shift = 7;
+                  for (i = 0; i < row_width; i++)
+                  {
+                     if ((png_uint_16)((*sp >> shift) & 0x01)
+                        == png_ptr->trans_color.gray)
+                     {
+                        unsigned int tmp = *sp & (0x7f7f >> (7 - shift));
+                        tmp |= png_ptr->background.gray << shift;
+                        *sp = (png_byte)(tmp & 0xff);
+                     }
+
+                     if (shift == 0)
+                     {
+                        shift = 7;
+                        sp++;
+                     }
+
+                     else
+                        shift--;
+                  }
+                  break;
+               }
+
+               case 2:
+               {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+                  if (gamma_table != NULL)
+                  {
+                     sp = row;
+                     shift = 6;
+                     for (i = 0; i < row_width; i++)
+                     {
+                        if ((png_uint_16)((*sp >> shift) & 0x03)
+                            == png_ptr->trans_color.gray)
+                        {
+                           unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
+                           tmp |= png_ptr->background.gray << shift;
+                           *sp = (png_byte)(tmp & 0xff);
+                        }
+
+                        else
+                        {
+                           unsigned int p = (*sp >> shift) & 0x03;
+                           unsigned int g = (gamma_table [p | (p << 2) |
+                               (p << 4) | (p << 6)] >> 6) & 0x03;
+                           unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
+                           tmp |= g << shift;
+                           *sp = (png_byte)(tmp & 0xff);
+                        }
+
+                        if (shift == 0)
+                        {
+                           shift = 6;
+                           sp++;
+                        }
+
+                        else
+                           shift -= 2;
+                     }
+                  }
+
+                  else
+#endif
+                  {
+                     sp = row;
+                     shift = 6;
+                     for (i = 0; i < row_width; i++)
+                     {
+                        if ((png_uint_16)((*sp >> shift) & 0x03)
+                            == png_ptr->trans_color.gray)
+                        {
+                           unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
+                           tmp |= png_ptr->background.gray << shift;
+                           *sp = (png_byte)(tmp & 0xff);
+                        }
+
+                        if (shift == 0)
+                        {
+                           shift = 6;
+                           sp++;
+                        }
+
+                        else
+                           shift -= 2;
+                     }
+                  }
+                  break;
+               }
+
+               case 4:
+               {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+                  if (gamma_table != NULL)
+                  {
+                     sp = row;
+                     shift = 4;
+                     for (i = 0; i < row_width; i++)
+                     {
+                        if ((png_uint_16)((*sp >> shift) & 0x0f)
+                            == png_ptr->trans_color.gray)
+                        {
+                           unsigned int tmp = *sp & (0xf0f >> (4 - shift));
+                           tmp |= png_ptr->background.gray << shift;
+                           *sp = (png_byte)(tmp & 0xff);
+                        }
+
+                        else
+                        {
+                           unsigned int p = (*sp >> shift) & 0x0f;
+                           unsigned int g = (gamma_table[p | (p << 4)] >> 4) &
+                              0x0f;
+                           unsigned int tmp = *sp & (0xf0f >> (4 - shift));
+                           tmp |= g << shift;
+                           *sp = (png_byte)(tmp & 0xff);
+                        }
+
+                        if (shift == 0)
+                        {
+                           shift = 4;
+                           sp++;
+                        }
+
+                        else
+                           shift -= 4;
+                     }
+                  }
+
+                  else
+#endif
+                  {
+                     sp = row;
+                     shift = 4;
+                     for (i = 0; i < row_width; i++)
+                     {
+                        if ((png_uint_16)((*sp >> shift) & 0x0f)
+                            == png_ptr->trans_color.gray)
+                        {
+                           unsigned int tmp = *sp & (0xf0f >> (4 - shift));
+                           tmp |= png_ptr->background.gray << shift;
+                           *sp = (png_byte)(tmp & 0xff);
+                        }
+
+                        if (shift == 0)
+                        {
+                           shift = 4;
+                           sp++;
+                        }
+
+                        else
+                           shift -= 4;
+                     }
+                  }
+                  break;
+               }
+
+               case 8:
+               {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+                  if (gamma_table != NULL)
+                  {
+                     sp = row;
+                     for (i = 0; i < row_width; i++, sp++)
+                     {
+                        if (*sp == png_ptr->trans_color.gray)
+                           *sp = (png_byte)png_ptr->background.gray;
+
+                        else
+                           *sp = gamma_table[*sp];
+                     }
+                  }
+                  else
+#endif
+                  {
+                     sp = row;
+                     for (i = 0; i < row_width; i++, sp++)
+                     {
+                        if (*sp == png_ptr->trans_color.gray)
+                           *sp = (png_byte)png_ptr->background.gray;
+                     }
+                  }
+                  break;
+               }
+
+               case 16:
+               {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+                  if (gamma_16 != NULL)
+                  {
+                     sp = row;
+                     for (i = 0; i < row_width; i++, sp += 2)
+                     {
+                        png_uint_16 v;
+
+                        v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+
+                        if (v == png_ptr->trans_color.gray)
+                        {
+                           /* Background is already in screen gamma */
+                           *sp = (png_byte)((png_ptr->background.gray >> 8)
+                                & 0xff);
+                           *(sp + 1) = (png_byte)(png_ptr->background.gray
+                                & 0xff);
+                        }
+
+                        else
+                        {
+                           v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+                           *sp = (png_byte)((v >> 8) & 0xff);
+                           *(sp + 1) = (png_byte)(v & 0xff);
+                        }
+                     }
+                  }
+                  else
+#endif
+                  {
+                     sp = row;
+                     for (i = 0; i < row_width; i++, sp += 2)
+                     {
+                        png_uint_16 v;
+
+                        v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+
+                        if (v == png_ptr->trans_color.gray)
+                        {
+                           *sp = (png_byte)((png_ptr->background.gray >> 8)
+                                & 0xff);
+                           *(sp + 1) = (png_byte)(png_ptr->background.gray
+                                & 0xff);
+                        }
+                     }
+                  }
+                  break;
+               }
+
+               default:
+                  break;
+            }
+            break;
+         }
+
+         case PNG_COLOR_TYPE_RGB:
+         {
+            if (row_info->bit_depth == 8)
+            {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+               if (gamma_table != NULL)
+               {
+                  sp = row;
+                  for (i = 0; i < row_width; i++, sp += 3)
+                  {
+                     if (*sp == png_ptr->trans_color.red &&
+                         *(sp + 1) == png_ptr->trans_color.green &&
+                         *(sp + 2) == png_ptr->trans_color.blue)
+                     {
+                        *sp = (png_byte)png_ptr->background.red;
+                        *(sp + 1) = (png_byte)png_ptr->background.green;
+                        *(sp + 2) = (png_byte)png_ptr->background.blue;
+                     }
+
+                     else
+                     {
+                        *sp = gamma_table[*sp];
+                        *(sp + 1) = gamma_table[*(sp + 1)];
+                        *(sp + 2) = gamma_table[*(sp + 2)];
+                     }
+                  }
+               }
+               else
+#endif
+               {
+                  sp = row;
+                  for (i = 0; i < row_width; i++, sp += 3)
+                  {
+                     if (*sp == png_ptr->trans_color.red &&
+                         *(sp + 1) == png_ptr->trans_color.green &&
+                         *(sp + 2) == png_ptr->trans_color.blue)
+                     {
+                        *sp = (png_byte)png_ptr->background.red;
+                        *(sp + 1) = (png_byte)png_ptr->background.green;
+                        *(sp + 2) = (png_byte)png_ptr->background.blue;
+                     }
+                  }
+               }
+            }
+            else /* if (row_info->bit_depth == 16) */
+            {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+               if (gamma_16 != NULL)
+               {
+                  sp = row;
+                  for (i = 0; i < row_width; i++, sp += 6)
+                  {
+                     png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+
+                     png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
+                         + *(sp + 3));
+
+                     png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
+                         + *(sp + 5));
+
+                     if (r == png_ptr->trans_color.red &&
+                         g == png_ptr->trans_color.green &&
+                         b == png_ptr->trans_color.blue)
+                     {
+                        /* Background is already in screen gamma */
+                        *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
+                        *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
+                        *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
+                                & 0xff);
+                        *(sp + 3) = (png_byte)(png_ptr->background.green
+                                & 0xff);
+                        *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
+                                & 0xff);
+                        *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
+                     }
+
+                     else
+                     {
+                        png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+                        *sp = (png_byte)((v >> 8) & 0xff);
+                        *(sp + 1) = (png_byte)(v & 0xff);
+
+                        v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
+                        *(sp + 2) = (png_byte)((v >> 8) & 0xff);
+                        *(sp + 3) = (png_byte)(v & 0xff);
+
+                        v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
+                        *(sp + 4) = (png_byte)((v >> 8) & 0xff);
+                        *(sp + 5) = (png_byte)(v & 0xff);
+                     }
+                  }
+               }
+
+               else
+#endif
+               {
+                  sp = row;
+                  for (i = 0; i < row_width; i++, sp += 6)
+                  {
+                     png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+
+                     png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
+                         + *(sp + 3));
+
+                     png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
+                         + *(sp + 5));
+
+                     if (r == png_ptr->trans_color.red &&
+                         g == png_ptr->trans_color.green &&
+                         b == png_ptr->trans_color.blue)
+                     {
+                        *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
+                        *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
+                        *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
+                                & 0xff);
+                        *(sp + 3) = (png_byte)(png_ptr->background.green
+                                & 0xff);
+                        *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
+                                & 0xff);
+                        *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
+                     }
+                  }
+               }
+            }
+            break;
+         }
+
+         case PNG_COLOR_TYPE_GRAY_ALPHA:
+         {
+            if (row_info->bit_depth == 8)
+            {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+               if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
+                   gamma_table != NULL)
+               {
+                  sp = row;
+                  for (i = 0; i < row_width; i++, sp += 2)
+                  {
+                     png_uint_16 a = *(sp + 1);
+
+                     if (a == 0xff)
+                        *sp = gamma_table[*sp];
+
+                     else if (a == 0)
+                     {
+                        /* Background is already in screen gamma */
+                        *sp = (png_byte)png_ptr->background.gray;
+                     }
+
+                     else
+                     {
+                        png_byte v, w;
+
+                        v = gamma_to_1[*sp];
+                        png_composite(w, v, a, png_ptr->background_1.gray);
+                        if (optimize == 0)
+                           w = gamma_from_1[w];
+                        *sp = w;
+                     }
+                  }
+               }
+               else
+#endif
+               {
+                  sp = row;
+                  for (i = 0; i < row_width; i++, sp += 2)
+                  {
+                     png_byte a = *(sp + 1);
+
+                     if (a == 0)
+                        *sp = (png_byte)png_ptr->background.gray;
+
+                     else if (a < 0xff)
+                        png_composite(*sp, *sp, a, png_ptr->background.gray);
+                  }
+               }
+            }
+            else /* if (png_ptr->bit_depth == 16) */
+            {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+               if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
+                   gamma_16_to_1 != NULL)
+               {
+                  sp = row;
+                  for (i = 0; i < row_width; i++, sp += 4)
+                  {
+                     png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8)
+                         + *(sp + 3));
+
+                     if (a == (png_uint_16)0xffff)
+                     {
+                        png_uint_16 v;
+
+                        v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+                        *sp = (png_byte)((v >> 8) & 0xff);
+                        *(sp + 1) = (png_byte)(v & 0xff);
+                     }
+
+                     else if (a == 0)
+                     {
+                        /* Background is already in screen gamma */
+                        *sp = (png_byte)((png_ptr->background.gray >> 8)
+                                & 0xff);
+                        *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff);
+                     }
+
+                     else
+                     {
+                        png_uint_16 g, v, w;
+
+                        g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
+                        png_composite_16(v, g, a, png_ptr->background_1.gray);
+                        if (optimize != 0)
+                           w = v;
+                        else
+                           w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8];
+                        *sp = (png_byte)((w >> 8) & 0xff);
+                        *(sp + 1) = (png_byte)(w & 0xff);
+                     }
+                  }
+               }
+               else
+#endif
+               {
+                  sp = row;
+                  for (i = 0; i < row_width; i++, sp += 4)
+                  {
+                     png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8)
+                         + *(sp + 3));
+
+                     if (a == 0)
+                     {
+                        *sp = (png_byte)((png_ptr->background.gray >> 8)
+                                & 0xff);
+                        *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff);
+                     }
+
+                     else if (a < 0xffff)
+                     {
+                        png_uint_16 g, v;
+
+                        g = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+                        png_composite_16(v, g, a, png_ptr->background.gray);
+                        *sp = (png_byte)((v >> 8) & 0xff);
+                        *(sp + 1) = (png_byte)(v & 0xff);
+                     }
+                  }
+               }
+            }
+            break;
+         }
+
+         case PNG_COLOR_TYPE_RGB_ALPHA:
+         {
+            if (row_info->bit_depth == 8)
+            {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+               if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
+                   gamma_table != NULL)
+               {
+                  sp = row;
+                  for (i = 0; i < row_width; i++, sp += 4)
+                  {
+                     png_byte a = *(sp + 3);
+
+                     if (a == 0xff)
+                     {
+                        *sp = gamma_table[*sp];
+                        *(sp + 1) = gamma_table[*(sp + 1)];
+                        *(sp + 2) = gamma_table[*(sp + 2)];
+                     }
+
+                     else if (a == 0)
+                     {
+                        /* Background is already in screen gamma */
+                        *sp = (png_byte)png_ptr->background.red;
+                        *(sp + 1) = (png_byte)png_ptr->background.green;
+                        *(sp + 2) = (png_byte)png_ptr->background.blue;
+                     }
+
+                     else
+                     {
+                        png_byte v, w;
+
+                        v = gamma_to_1[*sp];
+                        png_composite(w, v, a, png_ptr->background_1.red);
+                        if (optimize == 0) w = gamma_from_1[w];
+                        *sp = w;
+
+                        v = gamma_to_1[*(sp + 1)];
+                        png_composite(w, v, a, png_ptr->background_1.green);
+                        if (optimize == 0) w = gamma_from_1[w];
+                        *(sp + 1) = w;
+
+                        v = gamma_to_1[*(sp + 2)];
+                        png_composite(w, v, a, png_ptr->background_1.blue);
+                        if (optimize == 0) w = gamma_from_1[w];
+                        *(sp + 2) = w;
+                     }
+                  }
+               }
+               else
+#endif
+               {
+                  sp = row;
+                  for (i = 0; i < row_width; i++, sp += 4)
+                  {
+                     png_byte a = *(sp + 3);
+
+                     if (a == 0)
+                     {
+                        *sp = (png_byte)png_ptr->background.red;
+                        *(sp + 1) = (png_byte)png_ptr->background.green;
+                        *(sp + 2) = (png_byte)png_ptr->background.blue;
+                     }
+
+                     else if (a < 0xff)
+                     {
+                        png_composite(*sp, *sp, a, png_ptr->background.red);
+
+                        png_composite(*(sp + 1), *(sp + 1), a,
+                            png_ptr->background.green);
+
+                        png_composite(*(sp + 2), *(sp + 2), a,
+                            png_ptr->background.blue);
+                     }
+                  }
+               }
+            }
+            else /* if (row_info->bit_depth == 16) */
+            {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+               if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
+                   gamma_16_to_1 != NULL)
+               {
+                  sp = row;
+                  for (i = 0; i < row_width; i++, sp += 8)
+                  {
+                     png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
+                         << 8) + (png_uint_16)(*(sp + 7)));
+
+                     if (a == (png_uint_16)0xffff)
+                     {
+                        png_uint_16 v;
+
+                        v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+                        *sp = (png_byte)((v >> 8) & 0xff);
+                        *(sp + 1) = (png_byte)(v & 0xff);
+
+                        v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
+                        *(sp + 2) = (png_byte)((v >> 8) & 0xff);
+                        *(sp + 3) = (png_byte)(v & 0xff);
+
+                        v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
+                        *(sp + 4) = (png_byte)((v >> 8) & 0xff);
+                        *(sp + 5) = (png_byte)(v & 0xff);
+                     }
+
+                     else if (a == 0)
+                     {
+                        /* Background is already in screen gamma */
+                        *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
+                        *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
+                        *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
+                                & 0xff);
+                        *(sp + 3) = (png_byte)(png_ptr->background.green
+                                & 0xff);
+                        *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
+                                & 0xff);
+                        *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
+                     }
+
+                     else
+                     {
+                        png_uint_16 v, w;
+
+                        v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
+                        png_composite_16(w, v, a, png_ptr->background_1.red);
+                        if (optimize == 0)
+                           w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >>
+                                8];
+                        *sp = (png_byte)((w >> 8) & 0xff);
+                        *(sp + 1) = (png_byte)(w & 0xff);
+
+                        v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)];
+                        png_composite_16(w, v, a, png_ptr->background_1.green);
+                        if (optimize == 0)
+                           w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >>
+                                8];
+
+                        *(sp + 2) = (png_byte)((w >> 8) & 0xff);
+                        *(sp + 3) = (png_byte)(w & 0xff);
+
+                        v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)];
+                        png_composite_16(w, v, a, png_ptr->background_1.blue);
+                        if (optimize == 0)
+                           w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >>
+                                8];
+
+                        *(sp + 4) = (png_byte)((w >> 8) & 0xff);
+                        *(sp + 5) = (png_byte)(w & 0xff);
+                     }
+                  }
+               }
+
+               else
+#endif
+               {
+                  sp = row;
+                  for (i = 0; i < row_width; i++, sp += 8)
+                  {
+                     png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
+                         << 8) + (png_uint_16)(*(sp + 7)));
+
+                     if (a == 0)
+                     {
+                        *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
+                        *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
+                        *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
+                                & 0xff);
+                        *(sp + 3) = (png_byte)(png_ptr->background.green
+                                & 0xff);
+                        *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
+                                & 0xff);
+                        *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
+                     }
+
+                     else if (a < 0xffff)
+                     {
+                        png_uint_16 v;
+
+                        png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+                        png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
+                            + *(sp + 3));
+                        png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
+                            + *(sp + 5));
+
+                        png_composite_16(v, r, a, png_ptr->background.red);
+                        *sp = (png_byte)((v >> 8) & 0xff);
+                        *(sp + 1) = (png_byte)(v & 0xff);
+
+                        png_composite_16(v, g, a, png_ptr->background.green);
+                        *(sp + 2) = (png_byte)((v >> 8) & 0xff);
+                        *(sp + 3) = (png_byte)(v & 0xff);
+
+                        png_composite_16(v, b, a, png_ptr->background.blue);
+                        *(sp + 4) = (png_byte)((v >> 8) & 0xff);
+                        *(sp + 5) = (png_byte)(v & 0xff);
+                     }
+                  }
+               }
+            }
+            break;
+         }
+
+         default:
+            break;
+      }
+   }
+}
+#endif /* READ_BACKGROUND || READ_ALPHA_MODE */
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+/* Gamma correct the image, avoiding the alpha channel.  Make sure
+ * you do this after you deal with the transparency issue on grayscale
+ * or RGB images. If your bit depth is 8, use gamma_table, if it
+ * is 16, use gamma_16_table and gamma_shift.  Build these with
+ * build_gamma_table().
+ */
+static void
+png_do_gamma(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
+{
+   png_const_bytep gamma_table = png_ptr->gamma_table;
+   png_const_uint_16pp gamma_16_table = png_ptr->gamma_16_table;
+   int gamma_shift = png_ptr->gamma_shift;
+
+   png_bytep sp;
+   png_uint_32 i;
+   png_uint_32 row_width=row_info->width;
+
+   png_debug(1, "in png_do_gamma");
+
+   if (((row_info->bit_depth <= 8 && gamma_table != NULL) ||
+       (row_info->bit_depth == 16 && gamma_16_table != NULL)))
+   {
+      switch (row_info->color_type)
+      {
+         case PNG_COLOR_TYPE_RGB:
+         {
+            if (row_info->bit_depth == 8)
+            {
+               sp = row;
+               for (i = 0; i < row_width; i++)
+               {
+                  *sp = gamma_table[*sp];
+                  sp++;
+                  *sp = gamma_table[*sp];
+                  sp++;
+                  *sp = gamma_table[*sp];
+                  sp++;
+               }
+            }
+
+            else /* if (row_info->bit_depth == 16) */
+            {
+               sp = row;
+               for (i = 0; i < row_width; i++)
+               {
+                  png_uint_16 v;
+
+                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+                  *sp = (png_byte)((v >> 8) & 0xff);
+                  *(sp + 1) = (png_byte)(v & 0xff);
+                  sp += 2;
+
+                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+                  *sp = (png_byte)((v >> 8) & 0xff);
+                  *(sp + 1) = (png_byte)(v & 0xff);
+                  sp += 2;
+
+                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+                  *sp = (png_byte)((v >> 8) & 0xff);
+                  *(sp + 1) = (png_byte)(v & 0xff);
+                  sp += 2;
+               }
+            }
+            break;
+         }
+
+         case PNG_COLOR_TYPE_RGB_ALPHA:
+         {
+            if (row_info->bit_depth == 8)
+            {
+               sp = row;
+               for (i = 0; i < row_width; i++)
+               {
+                  *sp = gamma_table[*sp];
+                  sp++;
+
+                  *sp = gamma_table[*sp];
+                  sp++;
+
+                  *sp = gamma_table[*sp];
+                  sp++;
+
+                  sp++;
+               }
+            }
+
+            else /* if (row_info->bit_depth == 16) */
+            {
+               sp = row;
+               for (i = 0; i < row_width; i++)
+               {
+                  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+                  *sp = (png_byte)((v >> 8) & 0xff);
+                  *(sp + 1) = (png_byte)(v & 0xff);
+                  sp += 2;
+
+                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+                  *sp = (png_byte)((v >> 8) & 0xff);
+                  *(sp + 1) = (png_byte)(v & 0xff);
+                  sp += 2;
+
+                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+                  *sp = (png_byte)((v >> 8) & 0xff);
+                  *(sp + 1) = (png_byte)(v & 0xff);
+                  sp += 4;
+               }
+            }
+            break;
+         }
+
+         case PNG_COLOR_TYPE_GRAY_ALPHA:
+         {
+            if (row_info->bit_depth == 8)
+            {
+               sp = row;
+               for (i = 0; i < row_width; i++)
+               {
+                  *sp = gamma_table[*sp];
+                  sp += 2;
+               }
+            }
+
+            else /* if (row_info->bit_depth == 16) */
+            {
+               sp = row;
+               for (i = 0; i < row_width; i++)
+               {
+                  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+                  *sp = (png_byte)((v >> 8) & 0xff);
+                  *(sp + 1) = (png_byte)(v & 0xff);
+                  sp += 4;
+               }
+            }
+            break;
+         }
+
+         case PNG_COLOR_TYPE_GRAY:
+         {
+            if (row_info->bit_depth == 2)
+            {
+               sp = row;
+               for (i = 0; i < row_width; i += 4)
+               {
+                  int a = *sp & 0xc0;
+                  int b = *sp & 0x30;
+                  int c = *sp & 0x0c;
+                  int d = *sp & 0x03;
+
+                  *sp = (png_byte)(
+                      ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)])   ) & 0xc0)|
+                      ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)|
+                      ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)|
+                      ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) ));
+                  sp++;
+               }
+            }
+
+            if (row_info->bit_depth == 4)
+            {
+               sp = row;
+               for (i = 0; i < row_width; i += 2)
+               {
+                  int msb = *sp & 0xf0;
+                  int lsb = *sp & 0x0f;
+
+                  *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0)
+                      | (((int)gamma_table[(lsb << 4) | lsb]) >> 4));
+                  sp++;
+               }
+            }
+
+            else if (row_info->bit_depth == 8)
+            {
+               sp = row;
+               for (i = 0; i < row_width; i++)
+               {
+                  *sp = gamma_table[*sp];
+                  sp++;
+               }
+            }
+
+            else if (row_info->bit_depth == 16)
+            {
+               sp = row;
+               for (i = 0; i < row_width; i++)
+               {
+                  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+                  *sp = (png_byte)((v >> 8) & 0xff);
+                  *(sp + 1) = (png_byte)(v & 0xff);
+                  sp += 2;
+               }
+            }
+            break;
+         }
+
+         default:
+            break;
+      }
+   }
+}
+#endif
+
+#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
+/* Encode the alpha channel to the output gamma (the input channel is always
+ * linear.)  Called only with color types that have an alpha channel.  Needs the
+ * from_1 tables.
+ */
+static void
+png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
+{
+   png_uint_32 row_width = row_info->width;
+
+   png_debug(1, "in png_do_encode_alpha");
+
+   if ((row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0)
+   {
+      if (row_info->bit_depth == 8)
+      {
+         PNG_CONST png_bytep table = png_ptr->gamma_from_1;
+
+         if (table != NULL)
+         {
+            PNG_CONST int step =
+               (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 4 : 2;
+
+            /* The alpha channel is the last component: */
+            row += step - 1;
+
+            for (; row_width > 0; --row_width, row += step)
+               *row = table[*row];
+
+            return;
+         }
+      }
+
+      else if (row_info->bit_depth == 16)
+      {
+         PNG_CONST png_uint_16pp table = png_ptr->gamma_16_from_1;
+         PNG_CONST int gamma_shift = png_ptr->gamma_shift;
+
+         if (table != NULL)
+         {
+            PNG_CONST int step =
+               (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 8 : 4;
+
+            /* The alpha channel is the last component: */
+            row += step - 2;
+
+            for (; row_width > 0; --row_width, row += step)
+            {
+               png_uint_16 v;
+
+               v = table[*(row + 1) >> gamma_shift][*row];
+               *row = (png_byte)((v >> 8) & 0xff);
+               *(row + 1) = (png_byte)(v & 0xff);
+            }
+
+            return;
+         }
+      }
+   }
+
+   /* Only get to here if called with a weird row_info; no harm has been done,
+    * so just issue a warning.
+    */
+   png_warning(png_ptr, "png_do_encode_alpha: unexpected call");
+}
+#endif
+
+#ifdef PNG_READ_EXPAND_SUPPORTED
+/* Expands a palette row to an RGB or RGBA row depending
+ * upon whether you supply trans and num_trans.
+ */
+static void
+png_do_expand_palette(png_row_infop row_info, png_bytep row,
+   png_const_colorp palette, png_const_bytep trans_alpha, int num_trans)
+{
+   int shift, value;
+   png_bytep sp, dp;
+   png_uint_32 i;
+   png_uint_32 row_width=row_info->width;
+
+   png_debug(1, "in png_do_expand_palette");
+
+   if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)
+   {
+      if (row_info->bit_depth < 8)
+      {
+         switch (row_info->bit_depth)
+         {
+            case 1:
+            {
+               sp = row + (png_size_t)((row_width - 1) >> 3);
+               dp = row + (png_size_t)row_width - 1;
+               shift = 7 - (int)((row_width + 7) & 0x07);
+               for (i = 0; i < row_width; i++)
+               {
+                  if ((*sp >> shift) & 0x01)
+                     *dp = 1;
+
+                  else
+                     *dp = 0;
+
+                  if (shift == 7)
+                  {
+                     shift = 0;
+                     sp--;
+                  }
+
+                  else
+                     shift++;
+
+                  dp--;
+               }
+               break;
+            }
+
+            case 2:
+            {
+               sp = row + (png_size_t)((row_width - 1) >> 2);
+               dp = row + (png_size_t)row_width - 1;
+               shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
+               for (i = 0; i < row_width; i++)
+               {
+                  value = (*sp >> shift) & 0x03;
+                  *dp = (png_byte)value;
+                  if (shift == 6)
+                  {
+                     shift = 0;
+                     sp--;
+                  }
+
+                  else
+                     shift += 2;
+
+                  dp--;
+               }
+               break;
+            }
+
+            case 4:
+            {
+               sp = row + (png_size_t)((row_width - 1) >> 1);
+               dp = row + (png_size_t)row_width - 1;
+               shift = (int)((row_width & 0x01) << 2);
+               for (i = 0; i < row_width; i++)
+               {
+                  value = (*sp >> shift) & 0x0f;
+                  *dp = (png_byte)value;
+                  if (shift == 4)
+                  {
+                     shift = 0;
+                     sp--;
+                  }
+
+                  else
+                     shift += 4;
+
+                  dp--;
+               }
+               break;
+            }
+
+            default:
+               break;
+         }
+         row_info->bit_depth = 8;
+         row_info->pixel_depth = 8;
+         row_info->rowbytes = row_width;
+      }
+
+      if (row_info->bit_depth == 8)
+      {
+         {
+            if (num_trans > 0)
+            {
+               sp = row + (png_size_t)row_width - 1;
+               dp = row + (png_size_t)(row_width << 2) - 1;
+
+               for (i = 0; i < row_width; i++)
+               {
+                  if ((int)(*sp) >= num_trans)
+                     *dp-- = 0xff;
+
+                  else
+                     *dp-- = trans_alpha[*sp];
+
+                  *dp-- = palette[*sp].blue;
+                  *dp-- = palette[*sp].green;
+                  *dp-- = palette[*sp].red;
+                  sp--;
+               }
+               row_info->bit_depth = 8;
+               row_info->pixel_depth = 32;
+               row_info->rowbytes = row_width * 4;
+               row_info->color_type = 6;
+               row_info->channels = 4;
+            }
+
+            else
+            {
+               sp = row + (png_size_t)row_width - 1;
+               dp = row + (png_size_t)(row_width * 3) - 1;
+
+               for (i = 0; i < row_width; i++)
+               {
+                  *dp-- = palette[*sp].blue;
+                  *dp-- = palette[*sp].green;
+                  *dp-- = palette[*sp].red;
+                  sp--;
+               }
+
+               row_info->bit_depth = 8;
+               row_info->pixel_depth = 24;
+               row_info->rowbytes = row_width * 3;
+               row_info->color_type = 2;
+               row_info->channels = 3;
+            }
+         }
+      }
+   }
+}
+
+/* If the bit depth < 8, it is expanded to 8.  Also, if the already
+ * expanded transparency value is supplied, an alpha channel is built.
+ */
+static void
+png_do_expand(png_row_infop row_info, png_bytep row,
+    png_const_color_16p trans_color)
+{
+   int shift, value;
+   png_bytep sp, dp;
+   png_uint_32 i;
+   png_uint_32 row_width=row_info->width;
+
+   png_debug(1, "in png_do_expand");
+
+   {
+      if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
+      {
+         unsigned int gray = trans_color != NULL ? trans_color->gray : 0;
+
+         if (row_info->bit_depth < 8)
+         {
+            switch (row_info->bit_depth)
+            {
+               case 1:
+               {
+                  gray = (gray & 0x01) * 0xff;
+                  sp = row + (png_size_t)((row_width - 1) >> 3);
+                  dp = row + (png_size_t)row_width - 1;
+                  shift = 7 - (int)((row_width + 7) & 0x07);
+                  for (i = 0; i < row_width; i++)
+                  {
+                     if ((*sp >> shift) & 0x01)
+                        *dp = 0xff;
+
+                     else
+                        *dp = 0;
+
+                     if (shift == 7)
+                     {
+                        shift = 0;
+                        sp--;
+                     }
+
+                     else
+                        shift++;
+
+                     dp--;
+                  }
+                  break;
+               }
+
+               case 2:
+               {
+                  gray = (gray & 0x03) * 0x55;
+                  sp = row + (png_size_t)((row_width - 1) >> 2);
+                  dp = row + (png_size_t)row_width - 1;
+                  shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
+                  for (i = 0; i < row_width; i++)
+                  {
+                     value = (*sp >> shift) & 0x03;
+                     *dp = (png_byte)(value | (value << 2) | (value << 4) |
+                        (value << 6));
+                     if (shift == 6)
+                     {
+                        shift = 0;
+                        sp--;
+                     }
+
+                     else
+                        shift += 2;
+
+                     dp--;
+                  }
+                  break;
+               }
+
+               case 4:
+               {
+                  gray = (gray & 0x0f) * 0x11;
+                  sp = row + (png_size_t)((row_width - 1) >> 1);
+                  dp = row + (png_size_t)row_width - 1;
+                  shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
+                  for (i = 0; i < row_width; i++)
+                  {
+                     value = (*sp >> shift) & 0x0f;
+                     *dp = (png_byte)(value | (value << 4));
+                     if (shift == 4)
+                     {
+                        shift = 0;
+                        sp--;
+                     }
+
+                     else
+                        shift = 4;
+
+                     dp--;
+                  }
+                  break;
+               }
+
+               default:
+                  break;
+            }
+
+            row_info->bit_depth = 8;
+            row_info->pixel_depth = 8;
+            row_info->rowbytes = row_width;
+         }
+
+         if (trans_color != NULL)
+         {
+            if (row_info->bit_depth == 8)
+            {
+               gray = gray & 0xff;
+               sp = row + (png_size_t)row_width - 1;
+               dp = row + (png_size_t)(row_width << 1) - 1;
+
+               for (i = 0; i < row_width; i++)
+               {
+                  if (*sp == gray)
+                     *dp-- = 0;
+
+                  else
+                     *dp-- = 0xff;
+
+                  *dp-- = *sp--;
+               }
+            }
+
+            else if (row_info->bit_depth == 16)
+            {
+               unsigned int gray_high = (gray >> 8) & 0xff;
+               unsigned int gray_low = gray & 0xff;
+               sp = row + row_info->rowbytes - 1;
+               dp = row + (row_info->rowbytes << 1) - 1;
+               for (i = 0; i < row_width; i++)
+               {
+                  if (*(sp - 1) == gray_high && *(sp) == gray_low)
+                  {
+                     *dp-- = 0;
+                     *dp-- = 0;
+                  }
+
+                  else
+                  {
+                     *dp-- = 0xff;
+                     *dp-- = 0xff;
+                  }
+
+                  *dp-- = *sp--;
+                  *dp-- = *sp--;
+               }
+            }
+
+            row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
+            row_info->channels = 2;
+            row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
+            row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
+               row_width);
+         }
+      }
+      else if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
+          trans_color != NULL)
+      {
+         if (row_info->bit_depth == 8)
+         {
+            png_byte red = (png_byte)(trans_color->red & 0xff);
+            png_byte green = (png_byte)(trans_color->green & 0xff);
+            png_byte blue = (png_byte)(trans_color->blue & 0xff);
+            sp = row + (png_size_t)row_info->rowbytes - 1;
+            dp = row + (png_size_t)(row_width << 2) - 1;
+            for (i = 0; i < row_width; i++)
+            {
+               if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue)
+                  *dp-- = 0;
+
+               else
+                  *dp-- = 0xff;
+
+               *dp-- = *sp--;
+               *dp-- = *sp--;
+               *dp-- = *sp--;
+            }
+         }
+         else if (row_info->bit_depth == 16)
+         {
+            png_byte red_high = (png_byte)((trans_color->red >> 8) & 0xff);
+            png_byte green_high = (png_byte)((trans_color->green >> 8) & 0xff);
+            png_byte blue_high = (png_byte)((trans_color->blue >> 8) & 0xff);
+            png_byte red_low = (png_byte)(trans_color->red & 0xff);
+            png_byte green_low = (png_byte)(trans_color->green & 0xff);
+            png_byte blue_low = (png_byte)(trans_color->blue & 0xff);
+            sp = row + row_info->rowbytes - 1;
+            dp = row + (png_size_t)(row_width << 3) - 1;
+            for (i = 0; i < row_width; i++)
+            {
+               if (*(sp - 5) == red_high &&
+                   *(sp - 4) == red_low &&
+                   *(sp - 3) == green_high &&
+                   *(sp - 2) == green_low &&
+                   *(sp - 1) == blue_high &&
+                   *(sp    ) == blue_low)
+               {
+                  *dp-- = 0;
+                  *dp-- = 0;
+               }
+
+               else
+               {
+                  *dp-- = 0xff;
+                  *dp-- = 0xff;
+               }
+
+               *dp-- = *sp--;
+               *dp-- = *sp--;
+               *dp-- = *sp--;
+               *dp-- = *sp--;
+               *dp-- = *sp--;
+               *dp-- = *sp--;
+            }
+         }
+         row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
+         row_info->channels = 4;
+         row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
+         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
+      }
+   }
+}
+#endif
+
+#ifdef PNG_READ_EXPAND_16_SUPPORTED
+/* If the bit depth is 8 and the color type is not a palette type expand the
+ * whole row to 16 bits.  Has no effect otherwise.
+ */
+static void
+png_do_expand_16(png_row_infop row_info, png_bytep row)
+{
+   if (row_info->bit_depth == 8 &&
+      row_info->color_type != PNG_COLOR_TYPE_PALETTE)
+   {
+      /* The row have a sequence of bytes containing [0..255] and we need
+       * to turn it into another row containing [0..65535], to do this we
+       * calculate:
+       *
+       *  (input / 255) * 65535
+       *
+       *  Which happens to be exactly input * 257 and this can be achieved
+       *  simply by byte replication in place (copying backwards).
+       */
+      png_byte *sp = row + row_info->rowbytes; /* source, last byte + 1 */
+      png_byte *dp = sp + row_info->rowbytes;  /* destination, end + 1 */
+      while (dp > sp)
+         dp[-2] = dp[-1] = *--sp, dp -= 2;
+
+      row_info->rowbytes *= 2;
+      row_info->bit_depth = 16;
+      row_info->pixel_depth = (png_byte)(row_info->channels * 16);
+   }
+}
+#endif
+
+#ifdef PNG_READ_QUANTIZE_SUPPORTED
+static void
+png_do_quantize(png_row_infop row_info, png_bytep row,
+    png_const_bytep palette_lookup, png_const_bytep quantize_lookup)
+{
+   png_bytep sp, dp;
+   png_uint_32 i;
+   png_uint_32 row_width=row_info->width;
+
+   png_debug(1, "in png_do_quantize");
+
+   if (row_info->bit_depth == 8)
+   {
+      if (row_info->color_type == PNG_COLOR_TYPE_RGB && palette_lookup)
+      {
+         int r, g, b, p;
+         sp = row;
+         dp = row;
+         for (i = 0; i < row_width; i++)
+         {
+            r = *sp++;
+            g = *sp++;
+            b = *sp++;
+
+            /* This looks real messy, but the compiler will reduce
+             * it down to a reasonable formula.  For example, with
+             * 5 bits per color, we get:
+             * p = (((r >> 3) & 0x1f) << 10) |
+             *    (((g >> 3) & 0x1f) << 5) |
+             *    ((b >> 3) & 0x1f);
+             */
+            p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) &
+                ((1 << PNG_QUANTIZE_RED_BITS) - 1)) <<
+                (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) |
+                (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) &
+                ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) <<
+                (PNG_QUANTIZE_BLUE_BITS)) |
+                ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) &
+                ((1 << PNG_QUANTIZE_BLUE_BITS) - 1));
+
+            *dp++ = palette_lookup[p];
+         }
+
+         row_info->color_type = PNG_COLOR_TYPE_PALETTE;
+         row_info->channels = 1;
+         row_info->pixel_depth = row_info->bit_depth;
+         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
+      }
+
+      else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
+         palette_lookup != NULL)
+      {
+         int r, g, b, p;
+         sp = row;
+         dp = row;
+         for (i = 0; i < row_width; i++)
+         {
+            r = *sp++;
+            g = *sp++;
+            b = *sp++;
+            sp++;
+
+            p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) &
+                ((1 << PNG_QUANTIZE_RED_BITS) - 1)) <<
+                (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) |
+                (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) &
+                ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) <<
+                (PNG_QUANTIZE_BLUE_BITS)) |
+                ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) &
+                ((1 << PNG_QUANTIZE_BLUE_BITS) - 1));
+
+            *dp++ = palette_lookup[p];
+         }
+
+         row_info->color_type = PNG_COLOR_TYPE_PALETTE;
+         row_info->channels = 1;
+         row_info->pixel_depth = row_info->bit_depth;
+         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
+      }
+
+      else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
+         quantize_lookup)
+      {
+         sp = row;
+
+         for (i = 0; i < row_width; i++, sp++)
+         {
+            *sp = quantize_lookup[*sp];
+         }
+      }
+   }
+}
+#endif /* READ_QUANTIZE */
+
+/* Transform the row.  The order of transformations is significant,
+ * and is very touchy.  If you add a transformation, take care to
+ * decide how it fits in with the other transformations here.
+ */
+void /* PRIVATE */
+png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info)
+{
+   png_debug(1, "in png_do_read_transformations");
+
+   if (png_ptr->row_buf == NULL)
+   {
+      /* Prior to 1.5.4 this output row/pass where the NULL pointer is, but this
+       * error is incredibly rare and incredibly easy to debug without this
+       * information.
+       */
+      png_error(png_ptr, "NULL row buffer");
+   }
+
+   /* The following is debugging; prior to 1.5.4 the code was never compiled in;
+    * in 1.5.4 PNG_FLAG_DETECT_UNINITIALIZED was added and the macro
+    * PNG_WARN_UNINITIALIZED_ROW removed.  In 1.6 the new flag is set only for
+    * all transformations, however in practice the ROW_INIT always gets done on
+    * demand, if necessary.
+    */
+   if ((png_ptr->flags & PNG_FLAG_DETECT_UNINITIALIZED) != 0 &&
+       (png_ptr->flags & PNG_FLAG_ROW_INIT) == 0)
+   {
+      /* Application has failed to call either png_read_start_image() or
+       * png_read_update_info() after setting transforms that expand pixels.
+       * This check added to libpng-1.2.19 (but not enabled until 1.5.4).
+       */
+      png_error(png_ptr, "Uninitialized row");
+   }
+
+#ifdef PNG_READ_EXPAND_SUPPORTED
+   if ((png_ptr->transformations & PNG_EXPAND) != 0)
+   {
+      if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)
+      {
+         png_do_expand_palette(row_info, png_ptr->row_buf + 1,
+             png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans);
+      }
+
+      else
+      {
+         if (png_ptr->num_trans != 0 &&
+             (png_ptr->transformations & PNG_EXPAND_tRNS) != 0)
+            png_do_expand(row_info, png_ptr->row_buf + 1,
+                &(png_ptr->trans_color));
+
+         else
+            png_do_expand(row_info, png_ptr->row_buf + 1,
+                NULL);
+      }
+   }
+#endif
+
+#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
+   if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 &&
+       (png_ptr->transformations & PNG_COMPOSE) == 0 &&
+       (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
+       row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
+      png_do_strip_channel(row_info, png_ptr->row_buf + 1,
+         0 /* at_start == false, because SWAP_ALPHA happens later */);
+#endif
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+   if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)
+   {
+      int rgb_error =
+          png_do_rgb_to_gray(png_ptr, row_info,
+              png_ptr->row_buf + 1);
+
+      if (rgb_error != 0)
+      {
+         png_ptr->rgb_to_gray_status=1;
+         if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
+             PNG_RGB_TO_GRAY_WARN)
+            png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel");
+
+         if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
+             PNG_RGB_TO_GRAY_ERR)
+            png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel");
+      }
+   }
+#endif
+
+/* From Andreas Dilger e-mail to png-implement, 26 March 1998:
+ *
+ *   In most cases, the "simple transparency" should be done prior to doing
+ *   gray-to-RGB, or you will have to test 3x as many bytes to check if a
+ *   pixel is transparent.  You would also need to make sure that the
+ *   transparency information is upgraded to RGB.
+ *
+ *   To summarize, the current flow is:
+ *   - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
+ *                                   with background "in place" if transparent,
+ *                                   convert to RGB if necessary
+ *   - Gray + alpha -> composite with gray background and remove alpha bytes,
+ *                                   convert to RGB if necessary
+ *
+ *   To support RGB backgrounds for gray images we need:
+ *   - Gray + simple transparency -> convert to RGB + simple transparency,
+ *                                   compare 3 or 6 bytes and composite with
+ *                                   background "in place" if transparent
+ *                                   (3x compare/pixel compared to doing
+ *                                   composite with gray bkgrnd)
+ *   - Gray + alpha -> convert to RGB + alpha, composite with background and
+ *                                   remove alpha bytes (3x float
+ *                                   operations/pixel compared with composite
+ *                                   on gray background)
+ *
+ *  Greg's change will do this.  The reason it wasn't done before is for
+ *  performance, as this increases the per-pixel operations.  If we would check
+ *  in advance if the background was gray or RGB, and position the gray-to-RGB
+ *  transform appropriately, then it would save a lot of work/time.
+ */
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+   /* If gray -> RGB, do so now only if background is non-gray; else do later
+    * for performance reasons
+    */
+   if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0 &&
+       (png_ptr->mode & PNG_BACKGROUND_IS_GRAY) == 0)
+      png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
+   defined(PNG_READ_ALPHA_MODE_SUPPORTED)
+   if ((png_ptr->transformations & PNG_COMPOSE) != 0)
+      png_do_compose(row_info, png_ptr->row_buf + 1, png_ptr);
+#endif
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+   if ((png_ptr->transformations & PNG_GAMMA) != 0 &&
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+      /* Because RGB_TO_GRAY does the gamma transform. */
+      (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0 &&
+#endif
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
+   defined(PNG_READ_ALPHA_MODE_SUPPORTED)
+      /* Because PNG_COMPOSE does the gamma transform if there is something to
+       * do (if there is an alpha channel or transparency.)
+       */
+       !((png_ptr->transformations & PNG_COMPOSE) &&
+       ((png_ptr->num_trans != 0) ||
+       (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)) &&
+#endif
+      /* Because png_init_read_transformations transforms the palette, unless
+       * RGB_TO_GRAY will do the transform.
+       */
+       (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))
+      png_do_gamma(row_info, png_ptr->row_buf + 1, png_ptr);
+#endif
+
+#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
+   if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 &&
+       (png_ptr->transformations & PNG_COMPOSE) != 0 &&
+       (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
+       row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
+      png_do_strip_channel(row_info, png_ptr->row_buf + 1,
+          0 /* at_start == false, because SWAP_ALPHA happens later */);
+#endif
+
+#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
+   if ((png_ptr->transformations & PNG_ENCODE_ALPHA) != 0 &&
+       (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0)
+      png_do_encode_alpha(row_info, png_ptr->row_buf + 1, png_ptr);
+#endif
+
+#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
+   if ((png_ptr->transformations & PNG_SCALE_16_TO_8) != 0)
+      png_do_scale_16_to_8(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
+   /* There is no harm in doing both of these because only one has any effect,
+    * by putting the 'scale' option first if the app asks for scale (either by
+    * calling the API or in a TRANSFORM flag) this is what happens.
+    */
+   if ((png_ptr->transformations & PNG_16_TO_8) != 0)
+      png_do_chop(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_QUANTIZE_SUPPORTED
+   if ((png_ptr->transformations & PNG_QUANTIZE) != 0)
+   {
+      png_do_quantize(row_info, png_ptr->row_buf + 1,
+          png_ptr->palette_lookup, png_ptr->quantize_index);
+
+      if (row_info->rowbytes == 0)
+         png_error(png_ptr, "png_do_quantize returned rowbytes=0");
+   }
+#endif /* READ_QUANTIZE */
+
+#ifdef PNG_READ_EXPAND_16_SUPPORTED
+   /* Do the expansion now, after all the arithmetic has been done.  Notice
+    * that previous transformations can handle the PNG_EXPAND_16 flag if this
+    * is efficient (particularly true in the case of gamma correction, where
+    * better accuracy results faster!)
+    */
+   if ((png_ptr->transformations & PNG_EXPAND_16) != 0)
+      png_do_expand_16(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+   /* NOTE: moved here in 1.5.4 (from much later in this list.) */
+   if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0 &&
+       (png_ptr->mode & PNG_BACKGROUND_IS_GRAY) != 0)
+      png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_INVERT_SUPPORTED
+   if ((png_ptr->transformations & PNG_INVERT_MONO) != 0)
+      png_do_invert(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
+   if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0)
+      png_do_read_invert_alpha(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_SHIFT_SUPPORTED
+   if ((png_ptr->transformations & PNG_SHIFT) != 0)
+      png_do_unshift(row_info, png_ptr->row_buf + 1,
+          &(png_ptr->shift));
+#endif
+
+#ifdef PNG_READ_PACK_SUPPORTED
+   if ((png_ptr->transformations & PNG_PACK) != 0)
+      png_do_unpack(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
+   /* Added at libpng-1.5.10 */
+   if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
+       png_ptr->num_palette_max >= 0)
+      png_do_check_palette_indexes(png_ptr, row_info);
+#endif
+
+#ifdef PNG_READ_BGR_SUPPORTED
+   if ((png_ptr->transformations & PNG_BGR) != 0)
+      png_do_bgr(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
+   if ((png_ptr->transformations & PNG_PACKSWAP) != 0)
+      png_do_packswap(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_FILLER_SUPPORTED
+   if ((png_ptr->transformations & PNG_FILLER) != 0)
+      png_do_read_filler(row_info, png_ptr->row_buf + 1,
+          (png_uint_32)png_ptr->filler, png_ptr->flags);
+#endif
+
+#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
+   if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0)
+      png_do_read_swap_alpha(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_16BIT_SUPPORTED
+#ifdef PNG_READ_SWAP_SUPPORTED
+   if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0)
+      png_do_swap(row_info, png_ptr->row_buf + 1);
+#endif
+#endif
+
+#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
+   if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0)
+   {
+      if (png_ptr->read_user_transform_fn != NULL)
+         (*(png_ptr->read_user_transform_fn)) /* User read transform function */
+             (png_ptr,     /* png_ptr */
+             row_info,     /* row_info: */
+                /*  png_uint_32 width;       width of row */
+                /*  png_size_t rowbytes;     number of bytes in row */
+                /*  png_byte color_type;     color type of pixels */
+                /*  png_byte bit_depth;      bit depth of samples */
+                /*  png_byte channels;       number of channels (1-4) */
+                /*  png_byte pixel_depth;    bits per pixel (depth*channels) */
+             png_ptr->row_buf + 1);    /* start of pixel data for row */
+#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
+      if (png_ptr->user_transform_depth != 0)
+         row_info->bit_depth = png_ptr->user_transform_depth;
+
+      if (png_ptr->user_transform_channels != 0)
+         row_info->channels = png_ptr->user_transform_channels;
+#endif
+      row_info->pixel_depth = (png_byte)(row_info->bit_depth *
+          row_info->channels);
+
+      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_info->width);
+   }
+#endif
+}
+
+#endif /* READ_TRANSFORMS */
+#endif /* READ */
diff --git a/Source/LibPNG/pngrutil.c b/Source/LibPNG/pngrutil.c
index b9c3905..4c26be4 100644
--- a/Source/LibPNG/pngrutil.c
+++ b/Source/LibPNG/pngrutil.c
@@ -1,4159 +1,4474 @@
-
-/* pngrutil.c - utilities to read a PNG file
- *
- * Last changed in libpng 1.5.10 [March 8, 2012]
- * Copyright (c) 1998-2012 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- *
- * This file contains routines that are only called from within
- * libpng itself during the course of reading an image.
- */
-
-#include "pngpriv.h"
-
-#ifdef PNG_READ_SUPPORTED
-
-#define png_strtod(p,a,b) strtod(a,b)
-
-png_uint_32 PNGAPI
-png_get_uint_31(png_structp png_ptr, png_const_bytep buf)
-{
-   png_uint_32 uval = png_get_uint_32(buf);
-
-   if (uval > PNG_UINT_31_MAX)
-      png_error(png_ptr, "PNG unsigned integer out of range");
-
-   return (uval);
-}
-
-#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_READ_cHRM_SUPPORTED)
-/* The following is a variation on the above for use with the fixed
- * point values used for gAMA and cHRM.  Instead of png_error it
- * issues a warning and returns (-1) - an invalid value because both
- * gAMA and cHRM use *unsigned* integers for fixed point values.
- */
-#define PNG_FIXED_ERROR (-1)
-
-static png_fixed_point /* PRIVATE */
-png_get_fixed_point(png_structp png_ptr, png_const_bytep buf)
-{
-   png_uint_32 uval = png_get_uint_32(buf);
-
-   if (uval <= PNG_UINT_31_MAX)
-      return (png_fixed_point)uval; /* known to be in range */
-
-   /* The caller can turn off the warning by passing NULL. */
-   if (png_ptr != NULL)
-      png_warning(png_ptr, "PNG fixed point integer out of range");
-
-   return PNG_FIXED_ERROR;
-}
-#endif
-
-#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED
-/* NOTE: the read macros will obscure these definitions, so that if
- * PNG_USE_READ_MACROS is set the library will not use them internally,
- * but the APIs will still be available externally.
- *
- * The parentheses around "PNGAPI function_name" in the following three
- * functions are necessary because they allow the macros to co-exist with
- * these (unused but exported) functions.
- */
-
-/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
-png_uint_32 (PNGAPI
-png_get_uint_32)(png_const_bytep buf)
-{
-   png_uint_32 uval =
-       ((png_uint_32)(*(buf    )) << 24) +
-       ((png_uint_32)(*(buf + 1)) << 16) +
-       ((png_uint_32)(*(buf + 2)) <<  8) +
-       ((png_uint_32)(*(buf + 3))      ) ;
-
-   return uval;
-}
-
-/* Grab a signed 32-bit integer from a buffer in big-endian format.  The
- * data is stored in the PNG file in two's complement format and there
- * is no guarantee that a 'png_int_32' is exactly 32 bits, therefore
- * the following code does a two's complement to native conversion.
- */
-png_int_32 (PNGAPI
-png_get_int_32)(png_const_bytep buf)
-{
-   png_uint_32 uval = png_get_uint_32(buf);
-   if ((uval & 0x80000000) == 0) /* non-negative */
-      return uval;
-
-   uval = (uval ^ 0xffffffff) + 1;  /* 2's complement: -x = ~x+1 */
-   return -(png_int_32)uval;
-}
-
-/* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
-png_uint_16 (PNGAPI
-png_get_uint_16)(png_const_bytep buf)
-{
-   /* ANSI-C requires an int value to accomodate at least 16 bits so this
-    * works and allows the compiler not to worry about possible narrowing
-    * on 32 bit systems.  (Pre-ANSI systems did not make integers smaller
-    * than 16 bits either.)
-    */
-   unsigned int val =
-       ((unsigned int)(*buf) << 8) +
-       ((unsigned int)(*(buf + 1)));
-
-   return (png_uint_16)val;
-}
-
-#endif /* PNG_READ_INT_FUNCTIONS_SUPPORTED */
-
-/* Read and check the PNG file signature */
-void /* PRIVATE */
-png_read_sig(png_structp png_ptr, png_infop info_ptr)
-{
-   png_size_t num_checked, num_to_check;
-
-   /* Exit if the user application does not expect a signature. */
-   if (png_ptr->sig_bytes >= 8)
-      return;
-
-   num_checked = png_ptr->sig_bytes;
-   num_to_check = 8 - num_checked;
-
-#ifdef PNG_IO_STATE_SUPPORTED
-   png_ptr->io_state = PNG_IO_READING | PNG_IO_SIGNATURE;
-#endif
-
-   /* The signature must be serialized in a single I/O call. */
-   png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check);
-   png_ptr->sig_bytes = 8;
-
-   if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
-   {
-      if (num_checked < 4 &&
-          png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
-         png_error(png_ptr, "Not a PNG file");
-      else
-         png_error(png_ptr, "PNG file corrupted by ASCII conversion");
-   }
-   if (num_checked < 3)
-      png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
-}
-
-/* Read the chunk header (length + type name).
- * Put the type name into png_ptr->chunk_name, and return the length.
- */
-png_uint_32 /* PRIVATE */
-png_read_chunk_header(png_structp png_ptr)
-{
-   png_byte buf[8];
-   png_uint_32 length;
-
-#ifdef PNG_IO_STATE_SUPPORTED
-   png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_HDR;
-#endif
-
-   /* Read the length and the chunk name.
-    * This must be performed in a single I/O call.
-    */
-   png_read_data(png_ptr, buf, 8);
-   length = png_get_uint_31(png_ptr, buf);
-
-   /* Put the chunk name into png_ptr->chunk_name. */
-   png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(buf+4);
-
-   png_debug2(0, "Reading %lx chunk, length = %lu",
-       (unsigned long)png_ptr->chunk_name, (unsigned long)length);
-
-   /* Reset the crc and run it over the chunk name. */
-   png_reset_crc(png_ptr);
-   png_calculate_crc(png_ptr, buf + 4, 4);
-
-   /* Check to see if chunk name is valid. */
-   png_check_chunk_name(png_ptr, png_ptr->chunk_name);
-
-#ifdef PNG_IO_STATE_SUPPORTED
-   png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_DATA;
-#endif
-
-   return length;
-}
-
-/* Read data, and (optionally) run it through the CRC. */
-void /* PRIVATE */
-png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
-{
-   if (png_ptr == NULL)
-      return;
-
-   png_read_data(png_ptr, buf, length);
-   png_calculate_crc(png_ptr, buf, length);
-}
-
-/* Optionally skip data and then check the CRC.  Depending on whether we
- * are reading a ancillary or critical chunk, and how the program has set
- * things up, we may calculate the CRC on the data and print a message.
- * Returns '1' if there was a CRC error, '0' otherwise.
- */
-int /* PRIVATE */
-png_crc_finish(png_structp png_ptr, png_uint_32 skip)
-{
-   png_size_t i;
-   png_size_t istop = png_ptr->zbuf_size;
-
-   for (i = (png_size_t)skip; i > istop; i -= istop)
-   {
-      png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
-   }
-
-   if (i)
-   {
-      png_crc_read(png_ptr, png_ptr->zbuf, i);
-   }
-
-   if (png_crc_error(png_ptr))
-   {
-      if (PNG_CHUNK_ANCILLIARY(png_ptr->chunk_name) ?
-          !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) :
-          (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE))
-      {
-         png_chunk_warning(png_ptr, "CRC error");
-      }
-
-      else
-      {
-         png_chunk_benign_error(png_ptr, "CRC error");
-         return (0);
-      }
-
-      return (1);
-   }
-
-   return (0);
-}
-
-/* Compare the CRC stored in the PNG file with that calculated by libpng from
- * the data it has read thus far.
- */
-int /* PRIVATE */
-png_crc_error(png_structp png_ptr)
-{
-   png_byte crc_bytes[4];
-   png_uint_32 crc;
-   int need_crc = 1;
-
-   if (PNG_CHUNK_ANCILLIARY(png_ptr->chunk_name))
-   {
-      if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
-          (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
-         need_crc = 0;
-   }
-
-   else /* critical */
-   {
-      if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
-         need_crc = 0;
-   }
-
-#ifdef PNG_IO_STATE_SUPPORTED
-   png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_CRC;
-#endif
-
-   /* The chunk CRC must be serialized in a single I/O call. */
-   png_read_data(png_ptr, crc_bytes, 4);
-
-   if (need_crc)
-   {
-      crc = png_get_uint_32(crc_bytes);
-      return ((int)(crc != png_ptr->crc));
-   }
-
-   else
-      return (0);
-}
-
-#ifdef PNG_READ_COMPRESSED_TEXT_SUPPORTED
-static png_size_t
-png_inflate(png_structp png_ptr, png_bytep data, png_size_t size,
-    png_bytep output, png_size_t output_size)
-{
-   png_size_t count = 0;
-
-   /* zlib can't necessarily handle more than 65535 bytes at once (i.e. it can't
-    * even necessarily handle 65536 bytes) because the type uInt is "16 bits or
-    * more".  Consequently it is necessary to chunk the input to zlib.  This
-    * code uses ZLIB_IO_MAX, from pngpriv.h, as the maximum (the maximum value
-    * that can be stored in a uInt.)  It is possible to set ZLIB_IO_MAX to a
-    * lower value in pngpriv.h and this may sometimes have a performance
-    * advantage, because it forces access of the input data to be separated from
-    * at least some of the use by some period of time.
-    */
-   png_ptr->zstream.next_in = data;
-   /* avail_in is set below from 'size' */
-   png_ptr->zstream.avail_in = 0;
-
-   while (1)
-   {
-      int ret, avail;
-
-      /* The setting of 'avail_in' used to be outside the loop; by setting it
-       * inside it is possible to chunk the input to zlib and simply rely on
-       * zlib to advance the 'next_in' pointer.  This allows arbitrary amounts o
-       * data to be passed through zlib at the unavoidable cost of requiring a
-       * window save (memcpy of up to 32768 output bytes) every ZLIB_IO_MAX
-       * input bytes.
-       */
-      if (png_ptr->zstream.avail_in == 0 && size > 0)
-      {
-         if (size <= ZLIB_IO_MAX)
-         {
-            /* The value is less than ZLIB_IO_MAX so the cast is safe: */
-            png_ptr->zstream.avail_in = (uInt)size;
-            size = 0;
-         }
-
-         else
-         {
-            png_ptr->zstream.avail_in = ZLIB_IO_MAX;
-            size -= ZLIB_IO_MAX;
-         }
-      }
-
-      /* Reset the output buffer each time round - we empty it
-       * after every inflate call.
-       */
-      png_ptr->zstream.next_out = png_ptr->zbuf;
-      png_ptr->zstream.avail_out = png_ptr->zbuf_size;
-
-      ret = inflate(&png_ptr->zstream, Z_NO_FLUSH);
-      avail = png_ptr->zbuf_size - png_ptr->zstream.avail_out;
-
-      /* First copy/count any new output - but only if we didn't
-       * get an error code.
-       */
-      if ((ret == Z_OK || ret == Z_STREAM_END) && avail > 0)
-      {
-         png_size_t space = avail; /* > 0, see above */
-
-         if (output != 0 && output_size > count)
-         {
-            png_size_t copy = output_size - count;
-
-            if (space < copy)
-               copy = space;
-
-            png_memcpy(output + count, png_ptr->zbuf, copy);
-         }
-         count += space;
-      }
-
-      if (ret == Z_OK)
-         continue;
-
-      /* Termination conditions - always reset the zstream, it
-       * must be left in inflateInit state.
-       */
-      png_ptr->zstream.avail_in = 0;
-      inflateReset(&png_ptr->zstream);
-
-      if (ret == Z_STREAM_END)
-         return count; /* NOTE: may be zero. */
-
-      /* Now handle the error codes - the API always returns 0
-       * and the error message is dumped into the uncompressed
-       * buffer if available.
-       */
-#     ifdef PNG_WARNINGS_SUPPORTED
-      {
-         png_const_charp msg;
-
-         if (png_ptr->zstream.msg != 0)
-            msg = png_ptr->zstream.msg;
-
-         else switch (ret)
-         {
-            case Z_BUF_ERROR:
-               msg = "Buffer error in compressed datastream";
-               break;
-
-            case Z_DATA_ERROR:
-               msg = "Data error in compressed datastream";
-               break;
-
-            default:
-               msg = "Incomplete compressed datastream";
-               break;
-         }
-
-         png_chunk_warning(png_ptr, msg);
-      }
-#     endif
-
-      /* 0 means an error - notice that this code simply ignores
-       * zero length compressed chunks as a result.
-       */
-      return 0;
-   }
-}
-
-/*
- * Decompress trailing data in a chunk.  The assumption is that chunkdata
- * points at an allocated area holding the contents of a chunk with a
- * trailing compressed part.  What we get back is an allocated area
- * holding the original prefix part and an uncompressed version of the
- * trailing part (the malloc area passed in is freed).
- */
-void /* PRIVATE */
-png_decompress_chunk(png_structp png_ptr, int comp_type,
-    png_size_t chunklength,
-    png_size_t prefix_size, png_size_t *newlength)
-{
-   /* The caller should guarantee this */
-   if (prefix_size > chunklength)
-   {
-      /* The recovery is to delete the chunk. */
-      png_warning(png_ptr, "invalid chunklength");
-      prefix_size = 0; /* To delete everything */
-   }
-
-   else if (comp_type == PNG_COMPRESSION_TYPE_BASE)
-   {
-      png_size_t expanded_size = png_inflate(png_ptr,
-          (png_bytep)(png_ptr->chunkdata + prefix_size),
-          chunklength - prefix_size,
-          0,            /* output */
-          0);           /* output size */
-
-      /* Now check the limits on this chunk - if the limit fails the
-       * compressed data will be removed, the prefix will remain.
-       */
-      if (prefix_size >= (~(png_size_t)0) - 1 ||
-         expanded_size >= (~(png_size_t)0) - 1 - prefix_size
-#ifdef PNG_USER_LIMITS_SUPPORTED
-         || (png_ptr->user_chunk_malloc_max &&
-          (prefix_size + expanded_size >= png_ptr->user_chunk_malloc_max - 1))
-#else
-         || ((PNG_USER_CHUNK_MALLOC_MAX > 0) &&
-          prefix_size + expanded_size >= PNG_USER_CHUNK_MALLOC_MAX - 1)
-#endif
-         )
-         png_warning(png_ptr, "Exceeded size limit while expanding chunk");
-
-      /* If the size is zero either there was an error and a message
-       * has already been output (warning) or the size really is zero
-       * and we have nothing to do - the code will exit through the
-       * error case below.
-       */
-      else if (expanded_size > 0)
-      {
-         /* Success (maybe) - really uncompress the chunk. */
-         png_size_t new_size = 0;
-         png_charp text = (png_charp)png_malloc_warn(png_ptr,
-             prefix_size + expanded_size + 1);
-
-         if (text != NULL)
-         {
-            png_memcpy(text, png_ptr->chunkdata, prefix_size);
-            new_size = png_inflate(png_ptr,
-                (png_bytep)(png_ptr->chunkdata + prefix_size),
-                chunklength - prefix_size,
-                (png_bytep)(text + prefix_size), expanded_size);
-            text[prefix_size + expanded_size] = 0; /* just in case */
-
-            if (new_size == expanded_size)
-            {
-               png_free(png_ptr, png_ptr->chunkdata);
-               png_ptr->chunkdata = text;
-               *newlength = prefix_size + expanded_size;
-               return; /* The success return! */
-            }
-
-            png_warning(png_ptr, "png_inflate logic error");
-            png_free(png_ptr, text);
-         }
-
-         else
-            png_warning(png_ptr, "Not enough memory to decompress chunk");
-      }
-   }
-
-   else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
-   {
-      PNG_WARNING_PARAMETERS(p)
-      png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_d, comp_type);
-      png_formatted_warning(png_ptr, p, "Unknown compression type @1");
-
-      /* The recovery is to simply drop the data. */
-   }
-
-   /* Generic error return - leave the prefix, delete the compressed
-    * data, reallocate the chunkdata to remove the potentially large
-    * amount of compressed data.
-    */
-   {
-      png_charp text = (png_charp)png_malloc_warn(png_ptr, prefix_size + 1);
-
-      if (text != NULL)
-      {
-         if (prefix_size > 0)
-            png_memcpy(text, png_ptr->chunkdata, prefix_size);
-
-         png_free(png_ptr, png_ptr->chunkdata);
-         png_ptr->chunkdata = text;
-
-         /* This is an extra zero in the 'uncompressed' part. */
-         *(png_ptr->chunkdata + prefix_size) = 0x00;
-      }
-      /* Ignore a malloc error here - it is safe. */
-   }
-
-   *newlength = prefix_size;
-}
-#endif /* PNG_READ_COMPRESSED_TEXT_SUPPORTED */
-
-/* Read and check the IDHR chunk */
-void /* PRIVATE */
-png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
-   png_byte buf[13];
-   png_uint_32 width, height;
-   int bit_depth, color_type, compression_type, filter_type;
-   int interlace_type;
-
-   png_debug(1, "in png_handle_IHDR");
-
-   if (png_ptr->mode & PNG_HAVE_IHDR)
-      png_error(png_ptr, "Out of place IHDR");
-
-   /* Check the length */
-   if (length != 13)
-      png_error(png_ptr, "Invalid IHDR chunk");
-
-   png_ptr->mode |= PNG_HAVE_IHDR;
-
-   png_crc_read(png_ptr, buf, 13);
-   png_crc_finish(png_ptr, 0);
-
-   width = png_get_uint_31(png_ptr, buf);
-   height = png_get_uint_31(png_ptr, buf + 4);
-   bit_depth = buf[8];
-   color_type = buf[9];
-   compression_type = buf[10];
-   filter_type = buf[11];
-   interlace_type = buf[12];
-
-   /* Set internal variables */
-   png_ptr->width = width;
-   png_ptr->height = height;
-   png_ptr->bit_depth = (png_byte)bit_depth;
-   png_ptr->interlaced = (png_byte)interlace_type;
-   png_ptr->color_type = (png_byte)color_type;
-#ifdef PNG_MNG_FEATURES_SUPPORTED
-   png_ptr->filter_type = (png_byte)filter_type;
-#endif
-   png_ptr->compression_type = (png_byte)compression_type;
-
-   /* Find number of channels */
-   switch (png_ptr->color_type)
-   {
-      default: /* invalid, png_set_IHDR calls png_error */
-      case PNG_COLOR_TYPE_GRAY:
-      case PNG_COLOR_TYPE_PALETTE:
-         png_ptr->channels = 1;
-         break;
-
-      case PNG_COLOR_TYPE_RGB:
-         png_ptr->channels = 3;
-         break;
-
-      case PNG_COLOR_TYPE_GRAY_ALPHA:
-         png_ptr->channels = 2;
-         break;
-
-      case PNG_COLOR_TYPE_RGB_ALPHA:
-         png_ptr->channels = 4;
-         break;
-   }
-
-   /* Set up other useful info */
-   png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
-   png_ptr->channels);
-   png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width);
-   png_debug1(3, "bit_depth = %d", png_ptr->bit_depth);
-   png_debug1(3, "channels = %d", png_ptr->channels);
-   png_debug1(3, "rowbytes = %lu", (unsigned long)png_ptr->rowbytes);
-   png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
-       color_type, interlace_type, compression_type, filter_type);
-}
-
-/* Read and check the palette */
-void /* PRIVATE */
-png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
-   png_color palette[PNG_MAX_PALETTE_LENGTH];
-   int num, i;
-#ifdef PNG_POINTER_INDEXING_SUPPORTED
-   png_colorp pal_ptr;
-#endif
-
-   png_debug(1, "in png_handle_PLTE");
-
-   if (!(png_ptr->mode & PNG_HAVE_IHDR))
-      png_error(png_ptr, "Missing IHDR before PLTE");
-
-   else if (png_ptr->mode & PNG_HAVE_IDAT)
-   {
-      png_warning(png_ptr, "Invalid PLTE after IDAT");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-   else if (png_ptr->mode & PNG_HAVE_PLTE)
-      png_error(png_ptr, "Duplicate PLTE chunk");
-
-   png_ptr->mode |= PNG_HAVE_PLTE;
-
-   if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
-   {
-      png_warning(png_ptr,
-          "Ignoring PLTE chunk in grayscale PNG");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-#ifndef PNG_READ_OPT_PLTE_SUPPORTED
-   if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
-   {
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-#endif
-
-   if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
-   {
-      if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
-      {
-         png_warning(png_ptr, "Invalid palette chunk");
-         png_crc_finish(png_ptr, length);
-         return;
-      }
-
-      else
-      {
-         png_error(png_ptr, "Invalid palette chunk");
-      }
-   }
-
-   num = (int)length / 3;
-
-#ifdef PNG_POINTER_INDEXING_SUPPORTED
-   for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
-   {
-      png_byte buf[3];
-
-      png_crc_read(png_ptr, buf, 3);
-      pal_ptr->red = buf[0];
-      pal_ptr->green = buf[1];
-      pal_ptr->blue = buf[2];
-   }
-#else
-   for (i = 0; i < num; i++)
-   {
-      png_byte buf[3];
-
-      png_crc_read(png_ptr, buf, 3);
-      /* Don't depend upon png_color being any order */
-      palette[i].red = buf[0];
-      palette[i].green = buf[1];
-      palette[i].blue = buf[2];
-   }
-#endif
-
-   /* If we actually need the PLTE chunk (ie for a paletted image), we do
-    * whatever the normal CRC configuration tells us.  However, if we
-    * have an RGB image, the PLTE can be considered ancillary, so
-    * we will act as though it is.
-    */
-#ifndef PNG_READ_OPT_PLTE_SUPPORTED
-   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
-#endif
-   {
-      png_crc_finish(png_ptr, 0);
-   }
-
-#ifndef PNG_READ_OPT_PLTE_SUPPORTED
-   else if (png_crc_error(png_ptr))  /* Only if we have a CRC error */
-   {
-      /* If we don't want to use the data from an ancillary chunk,
-       * we have two options: an error abort, or a warning and we
-       * ignore the data in this chunk (which should be OK, since
-       * it's considered ancillary for a RGB or RGBA image).
-       */
-      if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
-      {
-         if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
-         {
-            png_chunk_benign_error(png_ptr, "CRC error");
-         }
-
-         else
-         {
-            png_chunk_warning(png_ptr, "CRC error");
-            return;
-         }
-      }
-
-      /* Otherwise, we (optionally) emit a warning and use the chunk. */
-      else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
-      {
-         png_chunk_warning(png_ptr, "CRC error");
-      }
-   }
-#endif
-
-   png_set_PLTE(png_ptr, info_ptr, palette, num);
-
-#ifdef PNG_READ_tRNS_SUPPORTED
-   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
-   {
-      if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
-      {
-         if (png_ptr->num_trans > (png_uint_16)num)
-         {
-            png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
-            png_ptr->num_trans = (png_uint_16)num;
-         }
-
-         if (info_ptr->num_trans > (png_uint_16)num)
-         {
-            png_warning(png_ptr, "Truncating incorrect info tRNS chunk length");
-            info_ptr->num_trans = (png_uint_16)num;
-         }
-      }
-   }
-#endif
-
-}
-
-void /* PRIVATE */
-png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
-   png_debug(1, "in png_handle_IEND");
-
-   if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
-   {
-      png_error(png_ptr, "No image in file");
-   }
-
-   png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
-
-   if (length != 0)
-   {
-      png_warning(png_ptr, "Incorrect IEND chunk length");
-   }
-
-   png_crc_finish(png_ptr, length);
-
-   PNG_UNUSED(info_ptr) /* Quiet compiler warnings about unused info_ptr */
-}
-
-#ifdef PNG_READ_gAMA_SUPPORTED
-void /* PRIVATE */
-png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
-   png_fixed_point igamma;
-   png_byte buf[4];
-
-   png_debug(1, "in png_handle_gAMA");
-
-   if (!(png_ptr->mode & PNG_HAVE_IHDR))
-      png_error(png_ptr, "Missing IHDR before gAMA");
-
-   else if (png_ptr->mode & PNG_HAVE_IDAT)
-   {
-      png_warning(png_ptr, "Invalid gAMA after IDAT");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-   else if (png_ptr->mode & PNG_HAVE_PLTE)
-      /* Should be an error, but we can cope with it */
-      png_warning(png_ptr, "Out of place gAMA chunk");
-
-   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
-#ifdef PNG_READ_sRGB_SUPPORTED
-       && !(info_ptr->valid & PNG_INFO_sRGB)
-#endif
-       )
-   {
-      png_warning(png_ptr, "Duplicate gAMA chunk");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-   if (length != 4)
-   {
-      png_warning(png_ptr, "Incorrect gAMA chunk length");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-   png_crc_read(png_ptr, buf, 4);
-
-   if (png_crc_finish(png_ptr, 0))
-      return;
-
-   igamma = png_get_fixed_point(NULL, buf);
-
-   /* Check for zero gamma or an error. */
-   if (igamma <= 0)
-   {
-      png_warning(png_ptr,
-          "Ignoring gAMA chunk with out of range gamma");
-
-      return;
-   }
-
-#  ifdef PNG_READ_sRGB_SUPPORTED
-   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
-   {
-      if (PNG_OUT_OF_RANGE(igamma, 45500, 500))
-      {
-         PNG_WARNING_PARAMETERS(p)
-         png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed, igamma);
-         png_formatted_warning(png_ptr, p,
-             "Ignoring incorrect gAMA value @1 when sRGB is also present");
-         return;
-      }
-   }
-#  endif /* PNG_READ_sRGB_SUPPORTED */
-
-#  ifdef PNG_READ_GAMMA_SUPPORTED
-   /* Gamma correction on read is supported. */
-   png_ptr->gamma = igamma;
-#  endif
-   /* And set the 'info' structure members. */
-   png_set_gAMA_fixed(png_ptr, info_ptr, igamma);
-}
-#endif
-
-#ifdef PNG_READ_sBIT_SUPPORTED
-void /* PRIVATE */
-png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
-   png_size_t truelen;
-   png_byte buf[4];
-
-   png_debug(1, "in png_handle_sBIT");
-
-   buf[0] = buf[1] = buf[2] = buf[3] = 0;
-
-   if (!(png_ptr->mode & PNG_HAVE_IHDR))
-      png_error(png_ptr, "Missing IHDR before sBIT");
-
-   else if (png_ptr->mode & PNG_HAVE_IDAT)
-   {
-      png_warning(png_ptr, "Invalid sBIT after IDAT");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-   else if (png_ptr->mode & PNG_HAVE_PLTE)
-   {
-      /* Should be an error, but we can cope with it */
-      png_warning(png_ptr, "Out of place sBIT chunk");
-   }
-
-   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT))
-   {
-      png_warning(png_ptr, "Duplicate sBIT chunk");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
-      truelen = 3;
-
-   else
-      truelen = (png_size_t)png_ptr->channels;
-
-   if (length != truelen || length > 4)
-   {
-      png_warning(png_ptr, "Incorrect sBIT chunk length");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-   png_crc_read(png_ptr, buf, truelen);
-
-   if (png_crc_finish(png_ptr, 0))
-      return;
-
-   if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
-   {
-      png_ptr->sig_bit.red = buf[0];
-      png_ptr->sig_bit.green = buf[1];
-      png_ptr->sig_bit.blue = buf[2];
-      png_ptr->sig_bit.alpha = buf[3];
-   }
-
-   else
-   {
-      png_ptr->sig_bit.gray = buf[0];
-      png_ptr->sig_bit.red = buf[0];
-      png_ptr->sig_bit.green = buf[0];
-      png_ptr->sig_bit.blue = buf[0];
-      png_ptr->sig_bit.alpha = buf[1];
-   }
-
-   png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
-}
-#endif
-
-#ifdef PNG_READ_cHRM_SUPPORTED
-void /* PRIVATE */
-png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
-   png_byte buf[32];
-   png_fixed_point x_white, y_white, x_red, y_red, x_green, y_green, x_blue,
-      y_blue;
-
-   png_debug(1, "in png_handle_cHRM");
-
-   if (!(png_ptr->mode & PNG_HAVE_IHDR))
-      png_error(png_ptr, "Missing IHDR before cHRM");
-
-   else if (png_ptr->mode & PNG_HAVE_IDAT)
-   {
-      png_warning(png_ptr, "Invalid cHRM after IDAT");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-   else if (png_ptr->mode & PNG_HAVE_PLTE)
-      /* Should be an error, but we can cope with it */
-      png_warning(png_ptr, "Out of place cHRM chunk");
-
-   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)
-#  ifdef PNG_READ_sRGB_SUPPORTED
-       && !(info_ptr->valid & PNG_INFO_sRGB)
-#  endif
-      )
-   {
-      png_warning(png_ptr, "Duplicate cHRM chunk");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-   if (length != 32)
-   {
-      png_warning(png_ptr, "Incorrect cHRM chunk length");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-   png_crc_read(png_ptr, buf, 32);
-
-   if (png_crc_finish(png_ptr, 0))
-      return;
-
-   x_white = png_get_fixed_point(NULL, buf);
-   y_white = png_get_fixed_point(NULL, buf + 4);
-   x_red   = png_get_fixed_point(NULL, buf + 8);
-   y_red   = png_get_fixed_point(NULL, buf + 12);
-   x_green = png_get_fixed_point(NULL, buf + 16);
-   y_green = png_get_fixed_point(NULL, buf + 20);
-   x_blue  = png_get_fixed_point(NULL, buf + 24);
-   y_blue  = png_get_fixed_point(NULL, buf + 28);
-
-   if (x_white == PNG_FIXED_ERROR ||
-       y_white == PNG_FIXED_ERROR ||
-       x_red   == PNG_FIXED_ERROR ||
-       y_red   == PNG_FIXED_ERROR ||
-       x_green == PNG_FIXED_ERROR ||
-       y_green == PNG_FIXED_ERROR ||
-       x_blue  == PNG_FIXED_ERROR ||
-       y_blue  == PNG_FIXED_ERROR)
-   {
-      png_warning(png_ptr, "Ignoring cHRM chunk with negative chromaticities");
-      return;
-   }
-
-#ifdef PNG_READ_sRGB_SUPPORTED
-   if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB))
-   {
-      if (PNG_OUT_OF_RANGE(x_white, 31270,  1000) ||
-          PNG_OUT_OF_RANGE(y_white, 32900,  1000) ||
-          PNG_OUT_OF_RANGE(x_red,   64000,  1000) ||
-          PNG_OUT_OF_RANGE(y_red,   33000,  1000) ||
-          PNG_OUT_OF_RANGE(x_green, 30000,  1000) ||
-          PNG_OUT_OF_RANGE(y_green, 60000,  1000) ||
-          PNG_OUT_OF_RANGE(x_blue,  15000,  1000) ||
-          PNG_OUT_OF_RANGE(y_blue,   6000,  1000))
-      {
-         PNG_WARNING_PARAMETERS(p)
-
-         png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed, x_white);
-         png_warning_parameter_signed(p, 2, PNG_NUMBER_FORMAT_fixed, y_white);
-         png_warning_parameter_signed(p, 3, PNG_NUMBER_FORMAT_fixed, x_red);
-         png_warning_parameter_signed(p, 4, PNG_NUMBER_FORMAT_fixed, y_red);
-         png_warning_parameter_signed(p, 5, PNG_NUMBER_FORMAT_fixed, x_green);
-         png_warning_parameter_signed(p, 6, PNG_NUMBER_FORMAT_fixed, y_green);
-         png_warning_parameter_signed(p, 7, PNG_NUMBER_FORMAT_fixed, x_blue);
-         png_warning_parameter_signed(p, 8, PNG_NUMBER_FORMAT_fixed, y_blue);
-
-         png_formatted_warning(png_ptr, p,
-             "Ignoring incorrect cHRM white(@1, at 2) r(@3, at 4)g(@5, at 6)b(@7, at 8) "
-             "when sRGB is also present");
-      }
-      return;
-   }
-#endif /* PNG_READ_sRGB_SUPPORTED */
-
-#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
-   /* Store the _white values as default coefficients for the rgb to gray
-    * operation if it is supported.  Check if the transform is already set to
-    * avoid destroying the transform values.
-    */
-   if (!png_ptr->rgb_to_gray_coefficients_set)
-   {
-      /* png_set_background has not been called and we haven't seen an sRGB
-       * chunk yet.  Find the XYZ of the three end points.
-       */
-      png_XYZ XYZ;
-      png_xy xy;
-
-      xy.redx = x_red;
-      xy.redy = y_red;
-      xy.greenx = x_green;
-      xy.greeny = y_green;
-      xy.bluex = x_blue;
-      xy.bluey = y_blue;
-      xy.whitex = x_white;
-      xy.whitey = y_white;
-
-      if (png_XYZ_from_xy_checked(png_ptr, &XYZ, xy))
-      {
-         /* The success case, because XYZ_from_xy normalises to a reference
-          * white Y of 1.0 we just need to scale the numbers.  This should
-          * always work just fine. It is an internal error if this overflows.
-          */
-         {
-            png_fixed_point r, g, b;
-            if (png_muldiv(&r, XYZ.redY, 32768, PNG_FP_1) &&
-               r >= 0 && r <= 32768 &&
-               png_muldiv(&g, XYZ.greenY, 32768, PNG_FP_1) &&
-               g >= 0 && g <= 32768 &&
-               png_muldiv(&b, XYZ.blueY, 32768, PNG_FP_1) &&
-               b >= 0 && b <= 32768 &&
-               r+g+b <= 32769)
-            {
-               /* We allow 0 coefficients here.  r+g+b may be 32769 if two or
-                * all of the coefficients were rounded up.  Handle this by
-                * reducing the *largest* coefficient by 1; this matches the
-                * approach used for the default coefficients in pngrtran.c
-                */
-               int add = 0;
-
-               if (r+g+b > 32768)
-                  add = -1;
-               else if (r+g+b < 32768)
-                  add = 1;
-
-               if (add != 0)
-               {
-                  if (g >= r && g >= b)
-                     g += add;
-                  else if (r >= g && r >= b)
-                     r += add;
-                  else
-                     b += add;
-               }
-
-               /* Check for an internal error. */
-               if (r+g+b != 32768)
-                  png_error(png_ptr,
-                     "internal error handling cHRM coefficients");
-
-               png_ptr->rgb_to_gray_red_coeff   = (png_uint_16)r;
-               png_ptr->rgb_to_gray_green_coeff = (png_uint_16)g;
-            }
-
-            /* This is a png_error at present even though it could be ignored -
-             * it should never happen, but it is important that if it does, the
-             * bug is fixed.
-             */
-            else
-               png_error(png_ptr, "internal error handling cHRM->XYZ");
-         }
-      }
-   }
-#endif
-
-   png_set_cHRM_fixed(png_ptr, info_ptr, x_white, y_white, x_red, y_red,
-      x_green, y_green, x_blue, y_blue);
-}
-#endif
-
-#ifdef PNG_READ_sRGB_SUPPORTED
-void /* PRIVATE */
-png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
-   int intent;
-   png_byte buf[1];
-
-   png_debug(1, "in png_handle_sRGB");
-
-   if (!(png_ptr->mode & PNG_HAVE_IHDR))
-      png_error(png_ptr, "Missing IHDR before sRGB");
-
-   else if (png_ptr->mode & PNG_HAVE_IDAT)
-   {
-      png_warning(png_ptr, "Invalid sRGB after IDAT");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-   else if (png_ptr->mode & PNG_HAVE_PLTE)
-      /* Should be an error, but we can cope with it */
-      png_warning(png_ptr, "Out of place sRGB chunk");
-
-   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
-   {
-      png_warning(png_ptr, "Duplicate sRGB chunk");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-   if (length != 1)
-   {
-      png_warning(png_ptr, "Incorrect sRGB chunk length");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-   png_crc_read(png_ptr, buf, 1);
-
-   if (png_crc_finish(png_ptr, 0))
-      return;
-
-   intent = buf[0];
-
-   /* Check for bad intent */
-   if (intent >= PNG_sRGB_INTENT_LAST)
-   {
-      png_warning(png_ptr, "Unknown sRGB intent");
-      return;
-   }
-
-#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
-   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA))
-   {
-      if (PNG_OUT_OF_RANGE(info_ptr->gamma, 45500, 500))
-      {
-         PNG_WARNING_PARAMETERS(p)
-
-         png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed,
-            info_ptr->gamma);
-
-         png_formatted_warning(png_ptr, p,
-             "Ignoring incorrect gAMA value @1 when sRGB is also present");
-      }
-   }
-#endif /* PNG_READ_gAMA_SUPPORTED */
-
-#ifdef PNG_READ_cHRM_SUPPORTED
-   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
-      if (PNG_OUT_OF_RANGE(info_ptr->x_white, 31270,  1000) ||
-          PNG_OUT_OF_RANGE(info_ptr->y_white, 32900,  1000) ||
-          PNG_OUT_OF_RANGE(info_ptr->x_red,   64000,  1000) ||
-          PNG_OUT_OF_RANGE(info_ptr->y_red,   33000,  1000) ||
-          PNG_OUT_OF_RANGE(info_ptr->x_green, 30000,  1000) ||
-          PNG_OUT_OF_RANGE(info_ptr->y_green, 60000,  1000) ||
-          PNG_OUT_OF_RANGE(info_ptr->x_blue,  15000,  1000) ||
-          PNG_OUT_OF_RANGE(info_ptr->y_blue,   6000,  1000))
-      {
-         png_warning(png_ptr,
-             "Ignoring incorrect cHRM value when sRGB is also present");
-      }
-#endif /* PNG_READ_cHRM_SUPPORTED */
-
-   /* This is recorded for use when handling the cHRM chunk above.  An sRGB
-    * chunk unconditionally overwrites the coefficients for grayscale conversion
-    * too.
-    */
-   png_ptr->is_sRGB = 1;
-
-#  ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
-      /* Don't overwrite user supplied values: */
-      if (!png_ptr->rgb_to_gray_coefficients_set)
-      {
-         /* These numbers come from the sRGB specification (or, since one has to
-          * pay much money to get a copy, the wikipedia sRGB page) the
-          * chromaticity values quoted have been inverted to get the reverse
-          * transformation from RGB to XYZ and the 'Y' coefficients scaled by
-          * 32768 (then rounded).
-          *
-          * sRGB and ITU Rec-709 both truncate the values for the D65 white
-          * point to four digits and, even though it actually stores five
-          * digits, the PNG spec gives the truncated value.
-          *
-          * This means that when the chromaticities are converted back to XYZ
-          * end points we end up with (6968,23435,2366), which, as described in
-          * pngrtran.c, would overflow.  If the five digit precision and up is
-          * used we get, instead:
-          *
-          *    6968*R + 23435*G + 2365*B
-          *
-          * (Notice that this rounds the blue coefficient down, rather than the
-          * choice used in pngrtran.c which is to round the green one down.)
-          */
-         png_ptr->rgb_to_gray_red_coeff   =  6968; /* 0.212639005871510 */
-         png_ptr->rgb_to_gray_green_coeff = 23434; /* 0.715168678767756 */
-         /* png_ptr->rgb_to_gray_blue_coeff  =  2366; 0.072192315360734	*/
-
-         /* The following keeps the cHRM chunk from destroying the
-          * coefficients again in the event that it follows the sRGB chunk.
-          */
-         png_ptr->rgb_to_gray_coefficients_set = 1;
-      }
-#  endif
-
-   png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
-}
-#endif /* PNG_READ_sRGB_SUPPORTED */
-
-#ifdef PNG_READ_iCCP_SUPPORTED
-void /* PRIVATE */
-png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-/* Note: this does not properly handle chunks that are > 64K under DOS */
-{
-   png_byte compression_type;
-   png_bytep pC;
-   png_charp profile;
-   png_uint_32 skip = 0;
-   png_uint_32 profile_size;
-   png_alloc_size_t profile_length;
-   png_size_t slength, prefix_length, data_length;
-
-   png_debug(1, "in png_handle_iCCP");
-
-   if (!(png_ptr->mode & PNG_HAVE_IHDR))
-      png_error(png_ptr, "Missing IHDR before iCCP");
-
-   else if (png_ptr->mode & PNG_HAVE_IDAT)
-   {
-      png_warning(png_ptr, "Invalid iCCP after IDAT");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-   else if (png_ptr->mode & PNG_HAVE_PLTE)
-      /* Should be an error, but we can cope with it */
-      png_warning(png_ptr, "Out of place iCCP chunk");
-
-   if ((png_ptr->mode & PNG_HAVE_iCCP) || (info_ptr != NULL &&
-      (info_ptr->valid & (PNG_INFO_iCCP|PNG_INFO_sRGB))))
-   {
-      png_warning(png_ptr, "Duplicate iCCP chunk");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-   png_ptr->mode |= PNG_HAVE_iCCP;
-
-#ifdef PNG_MAX_MALLOC_64K
-   if (length > (png_uint_32)65535L)
-   {
-      png_warning(png_ptr, "iCCP chunk too large to fit in memory");
-      skip = length - (png_uint_32)65535L;
-      length = (png_uint_32)65535L;
-   }
-#endif
-
-   png_free(png_ptr, png_ptr->chunkdata);
-   png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
-   slength = length;
-   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
-
-   if (png_crc_finish(png_ptr, skip))
-   {
-      png_free(png_ptr, png_ptr->chunkdata);
-      png_ptr->chunkdata = NULL;
-      return;
-   }
-
-   png_ptr->chunkdata[slength] = 0x00;
-
-   for (profile = png_ptr->chunkdata; *profile; profile++)
-      /* Empty loop to find end of name */ ;
-
-   ++profile;
-
-   /* There should be at least one zero (the compression type byte)
-    * following the separator, and we should be on it
-    */
-   if (profile >= png_ptr->chunkdata + slength - 1)
-   {
-      png_free(png_ptr, png_ptr->chunkdata);
-      png_ptr->chunkdata = NULL;
-      png_warning(png_ptr, "Malformed iCCP chunk");
-      return;
-   }
-
-   /* Compression_type should always be zero */
-   compression_type = *profile++;
-
-   if (compression_type)
-   {
-      png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk");
-      compression_type = 0x00;  /* Reset it to zero (libpng-1.0.6 through 1.0.8
-                                 wrote nonzero) */
-   }
-
-   prefix_length = profile - png_ptr->chunkdata;
-   png_decompress_chunk(png_ptr, compression_type,
-       slength, prefix_length, &data_length);
-
-   profile_length = data_length - prefix_length;
-
-   if (prefix_length > data_length || profile_length < 4)
-   {
-      png_free(png_ptr, png_ptr->chunkdata);
-      png_ptr->chunkdata = NULL;
-      png_warning(png_ptr, "Profile size field missing from iCCP chunk");
-      return;
-   }
-
-   /* Check the profile_size recorded in the first 32 bits of the ICC profile */
-   pC = (png_bytep)(png_ptr->chunkdata + prefix_length);
-   profile_size = ((*(pC    )) << 24) |
-                  ((*(pC + 1)) << 16) |
-                  ((*(pC + 2)) <<  8) |
-                  ((*(pC + 3))      );
-
-   /* NOTE: the following guarantees that 'profile_length' fits into 32 bits,
-    * because profile_size is a 32 bit value.
-    */
-   if (profile_size < profile_length)
-      profile_length = profile_size;
-
-   /* And the following guarantees that profile_size == profile_length. */
-   if (profile_size > profile_length)
-   {
-      PNG_WARNING_PARAMETERS(p)
-
-      png_free(png_ptr, png_ptr->chunkdata);
-      png_ptr->chunkdata = NULL;
-
-      png_warning_parameter_unsigned(p, 1, PNG_NUMBER_FORMAT_u, profile_size);
-      png_warning_parameter_unsigned(p, 2, PNG_NUMBER_FORMAT_u, profile_length);
-      png_formatted_warning(png_ptr, p,
-         "Ignoring iCCP chunk with declared size = @1 and actual length = @2");
-      return;
-   }
-
-   png_set_iCCP(png_ptr, info_ptr, png_ptr->chunkdata,
-       compression_type, (png_bytep)png_ptr->chunkdata + prefix_length,
-       profile_size);
-   png_free(png_ptr, png_ptr->chunkdata);
-   png_ptr->chunkdata = NULL;
-}
-#endif /* PNG_READ_iCCP_SUPPORTED */
-
-#ifdef PNG_READ_sPLT_SUPPORTED
-void /* PRIVATE */
-png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-/* Note: this does not properly handle chunks that are > 64K under DOS */
-{
-   png_bytep entry_start;
-   png_sPLT_t new_palette;
-   png_sPLT_entryp pp;
-   png_uint_32 data_length;
-   int entry_size, i;
-   png_uint_32 skip = 0;
-   png_size_t slength;
-   png_uint_32 dl;
-   png_size_t max_dl;
-
-   png_debug(1, "in png_handle_sPLT");
-
-#ifdef PNG_USER_LIMITS_SUPPORTED
-
-   if (png_ptr->user_chunk_cache_max != 0)
-   {
-      if (png_ptr->user_chunk_cache_max == 1)
-      {
-         png_crc_finish(png_ptr, length);
-         return;
-      }
-
-      if (--png_ptr->user_chunk_cache_max == 1)
-      {
-         png_warning(png_ptr, "No space in chunk cache for sPLT");
-         png_crc_finish(png_ptr, length);
-         return;
-      }
-   }
-#endif
-
-   if (!(png_ptr->mode & PNG_HAVE_IHDR))
-      png_error(png_ptr, "Missing IHDR before sPLT");
-
-   else if (png_ptr->mode & PNG_HAVE_IDAT)
-   {
-      png_warning(png_ptr, "Invalid sPLT after IDAT");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-#ifdef PNG_MAX_MALLOC_64K
-   if (length > (png_uint_32)65535L)
-   {
-      png_warning(png_ptr, "sPLT chunk too large to fit in memory");
-      skip = length - (png_uint_32)65535L;
-      length = (png_uint_32)65535L;
-   }
-#endif
-
-   png_free(png_ptr, png_ptr->chunkdata);
-   png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
-
-   /* WARNING: this may break if size_t is less than 32 bits; it is assumed
-    * that the PNG_MAX_MALLOC_64K test is enabled in this case, but this is a
-    * potential breakage point if the types in pngconf.h aren't exactly right.
-    */
-   slength = length;
-   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
-
-   if (png_crc_finish(png_ptr, skip))
-   {
-      png_free(png_ptr, png_ptr->chunkdata);
-      png_ptr->chunkdata = NULL;
-      return;
-   }
-
-   png_ptr->chunkdata[slength] = 0x00;
-
-   for (entry_start = (png_bytep)png_ptr->chunkdata; *entry_start;
-       entry_start++)
-      /* Empty loop to find end of name */ ;
-
-   ++entry_start;
-
-   /* A sample depth should follow the separator, and we should be on it  */
-   if (entry_start > (png_bytep)png_ptr->chunkdata + slength - 2)
-   {
-      png_free(png_ptr, png_ptr->chunkdata);
-      png_ptr->chunkdata = NULL;
-      png_warning(png_ptr, "malformed sPLT chunk");
-      return;
-   }
-
-   new_palette.depth = *entry_start++;
-   entry_size = (new_palette.depth == 8 ? 6 : 10);
-   /* This must fit in a png_uint_32 because it is derived from the original
-    * chunk data length (and use 'length', not 'slength' here for clarity -
-    * they are guaranteed to be the same, see the tests above.)
-    */
-   data_length = length - (png_uint_32)(entry_start -
-      (png_bytep)png_ptr->chunkdata);
-
-   /* Integrity-check the data length */
-   if (data_length % entry_size)
-   {
-      png_free(png_ptr, png_ptr->chunkdata);
-      png_ptr->chunkdata = NULL;
-      png_warning(png_ptr, "sPLT chunk has bad length");
-      return;
-   }
-
-   dl = (png_int_32)(data_length / entry_size);
-   max_dl = PNG_SIZE_MAX / png_sizeof(png_sPLT_entry);
-
-   if (dl > max_dl)
-   {
-       png_warning(png_ptr, "sPLT chunk too long");
-       return;
-   }
-
-   new_palette.nentries = (png_int_32)(data_length / entry_size);
-
-   new_palette.entries = (png_sPLT_entryp)png_malloc_warn(
-       png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry));
-
-   if (new_palette.entries == NULL)
-   {
-       png_warning(png_ptr, "sPLT chunk requires too much memory");
-       return;
-   }
-
-#ifdef PNG_POINTER_INDEXING_SUPPORTED
-   for (i = 0; i < new_palette.nentries; i++)
-   {
-      pp = new_palette.entries + i;
-
-      if (new_palette.depth == 8)
-      {
-         pp->red = *entry_start++;
-         pp->green = *entry_start++;
-         pp->blue = *entry_start++;
-         pp->alpha = *entry_start++;
-      }
-
-      else
-      {
-         pp->red   = png_get_uint_16(entry_start); entry_start += 2;
-         pp->green = png_get_uint_16(entry_start); entry_start += 2;
-         pp->blue  = png_get_uint_16(entry_start); entry_start += 2;
-         pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
-      }
-
-      pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
-   }
-#else
-   pp = new_palette.entries;
-
-   for (i = 0; i < new_palette.nentries; i++)
-   {
-
-      if (new_palette.depth == 8)
-      {
-         pp[i].red   = *entry_start++;
-         pp[i].green = *entry_start++;
-         pp[i].blue  = *entry_start++;
-         pp[i].alpha = *entry_start++;
-      }
-
-      else
-      {
-         pp[i].red   = png_get_uint_16(entry_start); entry_start += 2;
-         pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
-         pp[i].blue  = png_get_uint_16(entry_start); entry_start += 2;
-         pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
-      }
-
-      pp[i].frequency = png_get_uint_16(entry_start); entry_start += 2;
-   }
-#endif
-
-   /* Discard all chunk data except the name and stash that */
-   new_palette.name = png_ptr->chunkdata;
-
-   png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
-
-   png_free(png_ptr, png_ptr->chunkdata);
-   png_ptr->chunkdata = NULL;
-   png_free(png_ptr, new_palette.entries);
-}
-#endif /* PNG_READ_sPLT_SUPPORTED */
-
-#ifdef PNG_READ_tRNS_SUPPORTED
-void /* PRIVATE */
-png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
-   png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
-
-   png_debug(1, "in png_handle_tRNS");
-
-   if (!(png_ptr->mode & PNG_HAVE_IHDR))
-      png_error(png_ptr, "Missing IHDR before tRNS");
-
-   else if (png_ptr->mode & PNG_HAVE_IDAT)
-   {
-      png_warning(png_ptr, "Invalid tRNS after IDAT");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
-   {
-      png_warning(png_ptr, "Duplicate tRNS chunk");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-   if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
-   {
-      png_byte buf[2];
-
-      if (length != 2)
-      {
-         png_warning(png_ptr, "Incorrect tRNS chunk length");
-         png_crc_finish(png_ptr, length);
-         return;
-      }
-
-      png_crc_read(png_ptr, buf, 2);
-      png_ptr->num_trans = 1;
-      png_ptr->trans_color.gray = png_get_uint_16(buf);
-   }
-
-   else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
-   {
-      png_byte buf[6];
-
-      if (length != 6)
-      {
-         png_warning(png_ptr, "Incorrect tRNS chunk length");
-         png_crc_finish(png_ptr, length);
-         return;
-      }
-
-      png_crc_read(png_ptr, buf, (png_size_t)length);
-      png_ptr->num_trans = 1;
-      png_ptr->trans_color.red = png_get_uint_16(buf);
-      png_ptr->trans_color.green = png_get_uint_16(buf + 2);
-      png_ptr->trans_color.blue = png_get_uint_16(buf + 4);
-   }
-
-   else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
-   {
-      if (!(png_ptr->mode & PNG_HAVE_PLTE))
-      {
-         /* Should be an error, but we can cope with it. */
-         png_warning(png_ptr, "Missing PLTE before tRNS");
-      }
-
-      if (length > (png_uint_32)png_ptr->num_palette ||
-          length > PNG_MAX_PALETTE_LENGTH)
-      {
-         png_warning(png_ptr, "Incorrect tRNS chunk length");
-         png_crc_finish(png_ptr, length);
-         return;
-      }
-
-      if (length == 0)
-      {
-         png_warning(png_ptr, "Zero length tRNS chunk");
-         png_crc_finish(png_ptr, length);
-         return;
-      }
-
-      png_crc_read(png_ptr, readbuf, (png_size_t)length);
-      png_ptr->num_trans = (png_uint_16)length;
-   }
-
-   else
-   {
-      png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-   if (png_crc_finish(png_ptr, 0))
-   {
-      png_ptr->num_trans = 0;
-      return;
-   }
-
-   png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
-       &(png_ptr->trans_color));
-}
-#endif
-
-#ifdef PNG_READ_bKGD_SUPPORTED
-void /* PRIVATE */
-png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
-   png_size_t truelen;
-   png_byte buf[6];
-   png_color_16 background;
-
-   png_debug(1, "in png_handle_bKGD");
-
-   if (!(png_ptr->mode & PNG_HAVE_IHDR))
-      png_error(png_ptr, "Missing IHDR before bKGD");
-
-   else if (png_ptr->mode & PNG_HAVE_IDAT)
-   {
-      png_warning(png_ptr, "Invalid bKGD after IDAT");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-   else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
-       !(png_ptr->mode & PNG_HAVE_PLTE))
-   {
-      png_warning(png_ptr, "Missing PLTE before bKGD");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD))
-   {
-      png_warning(png_ptr, "Duplicate bKGD chunk");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
-      truelen = 1;
-
-   else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
-      truelen = 6;
-
-   else
-      truelen = 2;
-
-   if (length != truelen)
-   {
-      png_warning(png_ptr, "Incorrect bKGD chunk length");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-   png_crc_read(png_ptr, buf, truelen);
-
-   if (png_crc_finish(png_ptr, 0))
-      return;
-
-   /* We convert the index value into RGB components so that we can allow
-    * arbitrary RGB values for background when we have transparency, and
-    * so it is easy to determine the RGB values of the background color
-    * from the info_ptr struct.
-    */
-   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
-   {
-      background.index = buf[0];
-
-      if (info_ptr && info_ptr->num_palette)
-      {
-         if (buf[0] >= info_ptr->num_palette)
-         {
-            png_warning(png_ptr, "Incorrect bKGD chunk index value");
-            return;
-         }
-
-         background.red = (png_uint_16)png_ptr->palette[buf[0]].red;
-         background.green = (png_uint_16)png_ptr->palette[buf[0]].green;
-         background.blue = (png_uint_16)png_ptr->palette[buf[0]].blue;
-      }
-
-      else
-         background.red = background.green = background.blue = 0;
-
-      background.gray = 0;
-   }
-
-   else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
-   {
-      background.index = 0;
-      background.red =
-      background.green =
-      background.blue =
-      background.gray = png_get_uint_16(buf);
-   }
-
-   else
-   {
-      background.index = 0;
-      background.red = png_get_uint_16(buf);
-      background.green = png_get_uint_16(buf + 2);
-      background.blue = png_get_uint_16(buf + 4);
-      background.gray = 0;
-   }
-
-   png_set_bKGD(png_ptr, info_ptr, &background);
-}
-#endif
-
-#ifdef PNG_READ_hIST_SUPPORTED
-void /* PRIVATE */
-png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
-   unsigned int num, i;
-   png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];
-
-   png_debug(1, "in png_handle_hIST");
-
-   if (!(png_ptr->mode & PNG_HAVE_IHDR))
-      png_error(png_ptr, "Missing IHDR before hIST");
-
-   else if (png_ptr->mode & PNG_HAVE_IDAT)
-   {
-      png_warning(png_ptr, "Invalid hIST after IDAT");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-   else if (!(png_ptr->mode & PNG_HAVE_PLTE))
-   {
-      png_warning(png_ptr, "Missing PLTE before hIST");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST))
-   {
-      png_warning(png_ptr, "Duplicate hIST chunk");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-   if (length > 2*PNG_MAX_PALETTE_LENGTH ||
-       length != (unsigned int) (2*png_ptr->num_palette))
-   {
-      png_warning(png_ptr, "Incorrect hIST chunk length");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-   num = length / 2 ;
-
-   for (i = 0; i < num; i++)
-   {
-      png_byte buf[2];
-
-      png_crc_read(png_ptr, buf, 2);
-      readbuf[i] = png_get_uint_16(buf);
-   }
-
-   if (png_crc_finish(png_ptr, 0))
-      return;
-
-   png_set_hIST(png_ptr, info_ptr, readbuf);
-}
-#endif
-
-#ifdef PNG_READ_pHYs_SUPPORTED
-void /* PRIVATE */
-png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
-   png_byte buf[9];
-   png_uint_32 res_x, res_y;
-   int unit_type;
-
-   png_debug(1, "in png_handle_pHYs");
-
-   if (!(png_ptr->mode & PNG_HAVE_IHDR))
-      png_error(png_ptr, "Missing IHDR before pHYs");
-
-   else if (png_ptr->mode & PNG_HAVE_IDAT)
-   {
-      png_warning(png_ptr, "Invalid pHYs after IDAT");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
-   {
-      png_warning(png_ptr, "Duplicate pHYs chunk");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-   if (length != 9)
-   {
-      png_warning(png_ptr, "Incorrect pHYs chunk length");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-   png_crc_read(png_ptr, buf, 9);
-
-   if (png_crc_finish(png_ptr, 0))
-      return;
-
-   res_x = png_get_uint_32(buf);
-   res_y = png_get_uint_32(buf + 4);
-   unit_type = buf[8];
-   png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
-}
-#endif
-
-#ifdef PNG_READ_oFFs_SUPPORTED
-void /* PRIVATE */
-png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
-   png_byte buf[9];
-   png_int_32 offset_x, offset_y;
-   int unit_type;
-
-   png_debug(1, "in png_handle_oFFs");
-
-   if (!(png_ptr->mode & PNG_HAVE_IHDR))
-      png_error(png_ptr, "Missing IHDR before oFFs");
-
-   else if (png_ptr->mode & PNG_HAVE_IDAT)
-   {
-      png_warning(png_ptr, "Invalid oFFs after IDAT");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
-   {
-      png_warning(png_ptr, "Duplicate oFFs chunk");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-   if (length != 9)
-   {
-      png_warning(png_ptr, "Incorrect oFFs chunk length");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-   png_crc_read(png_ptr, buf, 9);
-
-   if (png_crc_finish(png_ptr, 0))
-      return;
-
-   offset_x = png_get_int_32(buf);
-   offset_y = png_get_int_32(buf + 4);
-   unit_type = buf[8];
-   png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
-}
-#endif
-
-#ifdef PNG_READ_pCAL_SUPPORTED
-/* Read the pCAL chunk (described in the PNG Extensions document) */
-void /* PRIVATE */
-png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
-   png_int_32 X0, X1;
-   png_byte type, nparams;
-   png_charp buf, units, endptr;
-   png_charpp params;
-   png_size_t slength;
-   int i;
-
-   png_debug(1, "in png_handle_pCAL");
-
-   if (!(png_ptr->mode & PNG_HAVE_IHDR))
-      png_error(png_ptr, "Missing IHDR before pCAL");
-
-   else if (png_ptr->mode & PNG_HAVE_IDAT)
-   {
-      png_warning(png_ptr, "Invalid pCAL after IDAT");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL))
-   {
-      png_warning(png_ptr, "Duplicate pCAL chunk");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-   png_debug1(2, "Allocating and reading pCAL chunk data (%u bytes)",
-       length + 1);
-   png_free(png_ptr, png_ptr->chunkdata);
-   png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
-
-   if (png_ptr->chunkdata == NULL)
-   {
-      png_warning(png_ptr, "No memory for pCAL purpose");
-      return;
-   }
-
-   slength = length;
-   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
-
-   if (png_crc_finish(png_ptr, 0))
-   {
-      png_free(png_ptr, png_ptr->chunkdata);
-      png_ptr->chunkdata = NULL;
-      return;
-   }
-
-   png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */
-
-   png_debug(3, "Finding end of pCAL purpose string");
-   for (buf = png_ptr->chunkdata; *buf; buf++)
-      /* Empty loop */ ;
-
-   endptr = png_ptr->chunkdata + slength;
-
-   /* We need to have at least 12 bytes after the purpose string
-    * in order to get the parameter information.
-    */
-   if (endptr <= buf + 12)
-   {
-      png_warning(png_ptr, "Invalid pCAL data");
-      png_free(png_ptr, png_ptr->chunkdata);
-      png_ptr->chunkdata = NULL;
-      return;
-   }
-
-   png_debug(3, "Reading pCAL X0, X1, type, nparams, and units");
-   X0 = png_get_int_32((png_bytep)buf+1);
-   X1 = png_get_int_32((png_bytep)buf+5);
-   type = buf[9];
-   nparams = buf[10];
-   units = buf + 11;
-
-   png_debug(3, "Checking pCAL equation type and number of parameters");
-   /* Check that we have the right number of parameters for known
-    * equation types.
-    */
-   if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
-       (type == PNG_EQUATION_BASE_E && nparams != 3) ||
-       (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
-       (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
-   {
-      png_warning(png_ptr, "Invalid pCAL parameters for equation type");
-      png_free(png_ptr, png_ptr->chunkdata);
-      png_ptr->chunkdata = NULL;
-      return;
-   }
-
-   else if (type >= PNG_EQUATION_LAST)
-   {
-      png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
-   }
-
-   for (buf = units; *buf; buf++)
-      /* Empty loop to move past the units string. */ ;
-
-   png_debug(3, "Allocating pCAL parameters array");
-
-   params = (png_charpp)png_malloc_warn(png_ptr,
-       (png_size_t)(nparams * png_sizeof(png_charp)));
-
-   if (params == NULL)
-   {
-      png_free(png_ptr, png_ptr->chunkdata);
-      png_ptr->chunkdata = NULL;
-      png_warning(png_ptr, "No memory for pCAL params");
-      return;
-   }
-
-   /* Get pointers to the start of each parameter string. */
-   for (i = 0; i < (int)nparams; i++)
-   {
-      buf++; /* Skip the null string terminator from previous parameter. */
-
-      png_debug1(3, "Reading pCAL parameter %d", i);
-
-      for (params[i] = buf; buf <= endptr && *buf != 0x00; buf++)
-         /* Empty loop to move past each parameter string */ ;
-
-      /* Make sure we haven't run out of data yet */
-      if (buf > endptr)
-      {
-         png_warning(png_ptr, "Invalid pCAL data");
-         png_free(png_ptr, png_ptr->chunkdata);
-         png_ptr->chunkdata = NULL;
-         png_free(png_ptr, params);
-         return;
-      }
-   }
-
-   png_set_pCAL(png_ptr, info_ptr, png_ptr->chunkdata, X0, X1, type, nparams,
-      units, params);
-
-   png_free(png_ptr, png_ptr->chunkdata);
-   png_ptr->chunkdata = NULL;
-   png_free(png_ptr, params);
-}
-#endif
-
-#ifdef PNG_READ_sCAL_SUPPORTED
-/* Read the sCAL chunk */
-void /* PRIVATE */
-png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
-   png_size_t slength, i;
-   int state;
-
-   png_debug(1, "in png_handle_sCAL");
-
-   if (!(png_ptr->mode & PNG_HAVE_IHDR))
-      png_error(png_ptr, "Missing IHDR before sCAL");
-
-   else if (png_ptr->mode & PNG_HAVE_IDAT)
-   {
-      png_warning(png_ptr, "Invalid sCAL after IDAT");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL))
-   {
-      png_warning(png_ptr, "Duplicate sCAL chunk");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-   /* Need unit type, width, \0, height: minimum 4 bytes */
-   else if (length < 4)
-   {
-      png_warning(png_ptr, "sCAL chunk too short");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-   png_debug1(2, "Allocating and reading sCAL chunk data (%u bytes)",
-      length + 1);
-
-   png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
-
-   if (png_ptr->chunkdata == NULL)
-   {
-      png_warning(png_ptr, "Out of memory while processing sCAL chunk");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-   slength = length;
-   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
-   png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */
-
-   if (png_crc_finish(png_ptr, 0))
-   {
-      png_free(png_ptr, png_ptr->chunkdata);
-      png_ptr->chunkdata = NULL;
-      return;
-   }
-
-   /* Validate the unit. */
-   if (png_ptr->chunkdata[0] != 1 && png_ptr->chunkdata[0] != 2)
-   {
-      png_warning(png_ptr, "Invalid sCAL ignored: invalid unit");
-      png_free(png_ptr, png_ptr->chunkdata);
-      png_ptr->chunkdata = NULL;
-      return;
-   }
-
-   /* Validate the ASCII numbers, need two ASCII numbers separated by
-    * a '\0' and they need to fit exactly in the chunk data.
-    */
-   i = 1;
-   state = 0;
-
-   if (!png_check_fp_number(png_ptr->chunkdata, slength, &state, &i) ||
-       i >= slength || png_ptr->chunkdata[i++] != 0)
-      png_warning(png_ptr, "Invalid sCAL chunk ignored: bad width format");
-
-   else if (!PNG_FP_IS_POSITIVE(state))
-      png_warning(png_ptr, "Invalid sCAL chunk ignored: non-positive width");
-
-   else
-   {
-      png_size_t heighti = i;
-
-      state = 0;
-      if (!png_check_fp_number(png_ptr->chunkdata, slength, &state, &i) ||
-          i != slength)
-         png_warning(png_ptr, "Invalid sCAL chunk ignored: bad height format");
-
-      else if (!PNG_FP_IS_POSITIVE(state))
-         png_warning(png_ptr,
-            "Invalid sCAL chunk ignored: non-positive height");
-
-      else
-         /* This is the (only) success case. */
-         png_set_sCAL_s(png_ptr, info_ptr, png_ptr->chunkdata[0],
-            png_ptr->chunkdata+1, png_ptr->chunkdata+heighti);
-   }
-
-   /* Clean up - just free the temporarily allocated buffer. */
-   png_free(png_ptr, png_ptr->chunkdata);
-   png_ptr->chunkdata = NULL;
-}
-#endif
-
-#ifdef PNG_READ_tIME_SUPPORTED
-void /* PRIVATE */
-png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
-   png_byte buf[7];
-   png_time mod_time;
-
-   png_debug(1, "in png_handle_tIME");
-
-   if (!(png_ptr->mode & PNG_HAVE_IHDR))
-      png_error(png_ptr, "Out of place tIME chunk");
-
-   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME))
-   {
-      png_warning(png_ptr, "Duplicate tIME chunk");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-   if (png_ptr->mode & PNG_HAVE_IDAT)
-      png_ptr->mode |= PNG_AFTER_IDAT;
-
-   if (length != 7)
-   {
-      png_warning(png_ptr, "Incorrect tIME chunk length");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-   png_crc_read(png_ptr, buf, 7);
-
-   if (png_crc_finish(png_ptr, 0))
-      return;
-
-   mod_time.second = buf[6];
-   mod_time.minute = buf[5];
-   mod_time.hour = buf[4];
-   mod_time.day = buf[3];
-   mod_time.month = buf[2];
-   mod_time.year = png_get_uint_16(buf);
-
-   png_set_tIME(png_ptr, info_ptr, &mod_time);
-}
-#endif
-
-#ifdef PNG_READ_tEXt_SUPPORTED
-/* Note: this does not properly handle chunks that are > 64K under DOS */
-void /* PRIVATE */
-png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
-   png_textp text_ptr;
-   png_charp key;
-   png_charp text;
-   png_uint_32 skip = 0;
-   png_size_t slength;
-   int ret;
-
-   png_debug(1, "in png_handle_tEXt");
-
-#ifdef PNG_USER_LIMITS_SUPPORTED
-   if (png_ptr->user_chunk_cache_max != 0)
-   {
-      if (png_ptr->user_chunk_cache_max == 1)
-      {
-         png_crc_finish(png_ptr, length);
-         return;
-      }
-
-      if (--png_ptr->user_chunk_cache_max == 1)
-      {
-         png_warning(png_ptr, "No space in chunk cache for tEXt");
-         png_crc_finish(png_ptr, length);
-         return;
-      }
-   }
-#endif
-
-   if (!(png_ptr->mode & PNG_HAVE_IHDR))
-      png_error(png_ptr, "Missing IHDR before tEXt");
-
-   if (png_ptr->mode & PNG_HAVE_IDAT)
-      png_ptr->mode |= PNG_AFTER_IDAT;
-
-#ifdef PNG_MAX_MALLOC_64K
-   if (length > (png_uint_32)65535L)
-   {
-      png_warning(png_ptr, "tEXt chunk too large to fit in memory");
-      skip = length - (png_uint_32)65535L;
-      length = (png_uint_32)65535L;
-   }
-#endif
-
-   png_free(png_ptr, png_ptr->chunkdata);
-
-   png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
-
-   if (png_ptr->chunkdata == NULL)
-   {
-     png_warning(png_ptr, "No memory to process text chunk");
-     return;
-   }
-
-   slength = length;
-   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
-
-   if (png_crc_finish(png_ptr, skip))
-   {
-      png_free(png_ptr, png_ptr->chunkdata);
-      png_ptr->chunkdata = NULL;
-      return;
-   }
-
-   key = png_ptr->chunkdata;
-
-   key[slength] = 0x00;
-
-   for (text = key; *text; text++)
-      /* Empty loop to find end of key */ ;
-
-   if (text != key + slength)
-      text++;
-
-   text_ptr = (png_textp)png_malloc_warn(png_ptr,
-       png_sizeof(png_text));
-
-   if (text_ptr == NULL)
-   {
-      png_warning(png_ptr, "Not enough memory to process text chunk");
-      png_free(png_ptr, png_ptr->chunkdata);
-      png_ptr->chunkdata = NULL;
-      return;
-   }
-
-   text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
-   text_ptr->key = key;
-   text_ptr->lang = NULL;
-   text_ptr->lang_key = NULL;
-   text_ptr->itxt_length = 0;
-   text_ptr->text = text;
-   text_ptr->text_length = png_strlen(text);
-
-   ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
-
-   png_free(png_ptr, png_ptr->chunkdata);
-   png_ptr->chunkdata = NULL;
-   png_free(png_ptr, text_ptr);
-
-   if (ret)
-      png_warning(png_ptr, "Insufficient memory to process text chunk");
-}
-#endif
-
-#ifdef PNG_READ_zTXt_SUPPORTED
-/* Note: this does not correctly handle chunks that are > 64K under DOS */
-void /* PRIVATE */
-png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
-   png_textp text_ptr;
-   png_charp text;
-   int comp_type;
-   int ret;
-   png_size_t slength, prefix_len, data_len;
-
-   png_debug(1, "in png_handle_zTXt");
-
-#ifdef PNG_USER_LIMITS_SUPPORTED
-   if (png_ptr->user_chunk_cache_max != 0)
-   {
-      if (png_ptr->user_chunk_cache_max == 1)
-      {
-         png_crc_finish(png_ptr, length);
-         return;
-      }
-
-      if (--png_ptr->user_chunk_cache_max == 1)
-      {
-         png_warning(png_ptr, "No space in chunk cache for zTXt");
-         png_crc_finish(png_ptr, length);
-         return;
-      }
-   }
-#endif
-
-   if (!(png_ptr->mode & PNG_HAVE_IHDR))
-      png_error(png_ptr, "Missing IHDR before zTXt");
-
-   if (png_ptr->mode & PNG_HAVE_IDAT)
-      png_ptr->mode |= PNG_AFTER_IDAT;
-
-#ifdef PNG_MAX_MALLOC_64K
-   /* We will no doubt have problems with chunks even half this size, but
-    * there is no hard and fast rule to tell us where to stop.
-    */
-   if (length > (png_uint_32)65535L)
-   {
-      png_warning(png_ptr, "zTXt chunk too large to fit in memory");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-#endif
-
-   png_free(png_ptr, png_ptr->chunkdata);
-   png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
-
-   if (png_ptr->chunkdata == NULL)
-   {
-      png_warning(png_ptr, "Out of memory processing zTXt chunk");
-      return;
-   }
-
-   slength = length;
-   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
-
-   if (png_crc_finish(png_ptr, 0))
-   {
-      png_free(png_ptr, png_ptr->chunkdata);
-      png_ptr->chunkdata = NULL;
-      return;
-   }
-
-   png_ptr->chunkdata[slength] = 0x00;
-
-   for (text = png_ptr->chunkdata; *text; text++)
-      /* Empty loop */ ;
-
-   /* zTXt must have some text after the chunkdataword */
-   if (text >= png_ptr->chunkdata + slength - 2)
-   {
-      png_warning(png_ptr, "Truncated zTXt chunk");
-      png_free(png_ptr, png_ptr->chunkdata);
-      png_ptr->chunkdata = NULL;
-      return;
-   }
-
-   else
-   {
-       comp_type = *(++text);
-
-       if (comp_type != PNG_TEXT_COMPRESSION_zTXt)
-       {
-          png_warning(png_ptr, "Unknown compression type in zTXt chunk");
-          comp_type = PNG_TEXT_COMPRESSION_zTXt;
-       }
-
-       text++;        /* Skip the compression_method byte */
-   }
-
-   prefix_len = text - png_ptr->chunkdata;
-
-   png_decompress_chunk(png_ptr, comp_type,
-       (png_size_t)length, prefix_len, &data_len);
-
-   text_ptr = (png_textp)png_malloc_warn(png_ptr,
-       png_sizeof(png_text));
-
-   if (text_ptr == NULL)
-   {
-      png_warning(png_ptr, "Not enough memory to process zTXt chunk");
-      png_free(png_ptr, png_ptr->chunkdata);
-      png_ptr->chunkdata = NULL;
-      return;
-   }
-
-   text_ptr->compression = comp_type;
-   text_ptr->key = png_ptr->chunkdata;
-   text_ptr->lang = NULL;
-   text_ptr->lang_key = NULL;
-   text_ptr->itxt_length = 0;
-   text_ptr->text = png_ptr->chunkdata + prefix_len;
-   text_ptr->text_length = data_len;
-
-   ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
-
-   png_free(png_ptr, text_ptr);
-   png_free(png_ptr, png_ptr->chunkdata);
-   png_ptr->chunkdata = NULL;
-
-   if (ret)
-      png_error(png_ptr, "Insufficient memory to store zTXt chunk");
-}
-#endif
-
-#ifdef PNG_READ_iTXt_SUPPORTED
-/* Note: this does not correctly handle chunks that are > 64K under DOS */
-void /* PRIVATE */
-png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
-   png_textp text_ptr;
-   png_charp key, lang, text, lang_key;
-   int comp_flag;
-   int comp_type = 0;
-   int ret;
-   png_size_t slength, prefix_len, data_len;
-
-   png_debug(1, "in png_handle_iTXt");
-
-#ifdef PNG_USER_LIMITS_SUPPORTED
-   if (png_ptr->user_chunk_cache_max != 0)
-   {
-      if (png_ptr->user_chunk_cache_max == 1)
-      {
-         png_crc_finish(png_ptr, length);
-         return;
-      }
-
-      if (--png_ptr->user_chunk_cache_max == 1)
-      {
-         png_warning(png_ptr, "No space in chunk cache for iTXt");
-         png_crc_finish(png_ptr, length);
-         return;
-      }
-   }
-#endif
-
-   if (!(png_ptr->mode & PNG_HAVE_IHDR))
-      png_error(png_ptr, "Missing IHDR before iTXt");
-
-   if (png_ptr->mode & PNG_HAVE_IDAT)
-      png_ptr->mode |= PNG_AFTER_IDAT;
-
-#ifdef PNG_MAX_MALLOC_64K
-   /* We will no doubt have problems with chunks even half this size, but
-    * there is no hard and fast rule to tell us where to stop.
-    */
-   if (length > (png_uint_32)65535L)
-   {
-      png_warning(png_ptr, "iTXt chunk too large to fit in memory");
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-#endif
-
-   png_free(png_ptr, png_ptr->chunkdata);
-   png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
-
-   if (png_ptr->chunkdata == NULL)
-   {
-      png_warning(png_ptr, "No memory to process iTXt chunk");
-      return;
-   }
-
-   slength = length;
-   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
-
-   if (png_crc_finish(png_ptr, 0))
-   {
-      png_free(png_ptr, png_ptr->chunkdata);
-      png_ptr->chunkdata = NULL;
-      return;
-   }
-
-   png_ptr->chunkdata[slength] = 0x00;
-
-   for (lang = png_ptr->chunkdata; *lang; lang++)
-      /* Empty loop */ ;
-
-   lang++;        /* Skip NUL separator */
-
-   /* iTXt must have a language tag (possibly empty), two compression bytes,
-    * translated keyword (possibly empty), and possibly some text after the
-    * keyword
-    */
-
-   if (lang >= png_ptr->chunkdata + slength - 3)
-   {
-      png_warning(png_ptr, "Truncated iTXt chunk");
-      png_free(png_ptr, png_ptr->chunkdata);
-      png_ptr->chunkdata = NULL;
-      return;
-   }
-
-   else
-   {
-      comp_flag = *lang++;
-      comp_type = *lang++;
-   }
-
-   if (comp_type || (comp_flag && comp_flag != PNG_TEXT_COMPRESSION_zTXt))
-   {
-      png_warning(png_ptr, "Unknown iTXt compression type or method");
-      png_free(png_ptr, png_ptr->chunkdata);
-      png_ptr->chunkdata = NULL;
-      return;
-   }
-
-   for (lang_key = lang; *lang_key; lang_key++)
-      /* Empty loop */ ;
-
-   lang_key++;        /* Skip NUL separator */
-
-   if (lang_key >= png_ptr->chunkdata + slength)
-   {
-      png_warning(png_ptr, "Truncated iTXt chunk");
-      png_free(png_ptr, png_ptr->chunkdata);
-      png_ptr->chunkdata = NULL;
-      return;
-   }
-
-   for (text = lang_key; *text; text++)
-      /* Empty loop */ ;
-
-   text++;        /* Skip NUL separator */
-
-   if (text >= png_ptr->chunkdata + slength)
-   {
-      png_warning(png_ptr, "Malformed iTXt chunk");
-      png_free(png_ptr, png_ptr->chunkdata);
-      png_ptr->chunkdata = NULL;
-      return;
-   }
-
-   prefix_len = text - png_ptr->chunkdata;
-
-   key=png_ptr->chunkdata;
-
-   if (comp_flag)
-      png_decompress_chunk(png_ptr, comp_type,
-          (size_t)length, prefix_len, &data_len);
-
-   else
-      data_len = png_strlen(png_ptr->chunkdata + prefix_len);
-
-   text_ptr = (png_textp)png_malloc_warn(png_ptr,
-       png_sizeof(png_text));
-
-   if (text_ptr == NULL)
-   {
-      png_warning(png_ptr, "Not enough memory to process iTXt chunk");
-      png_free(png_ptr, png_ptr->chunkdata);
-      png_ptr->chunkdata = NULL;
-      return;
-   }
-
-   text_ptr->compression = (int)comp_flag + 1;
-   text_ptr->lang_key = png_ptr->chunkdata + (lang_key - key);
-   text_ptr->lang = png_ptr->chunkdata + (lang - key);
-   text_ptr->itxt_length = data_len;
-   text_ptr->text_length = 0;
-   text_ptr->key = png_ptr->chunkdata;
-   text_ptr->text = png_ptr->chunkdata + prefix_len;
-
-   ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
-
-   png_free(png_ptr, text_ptr);
-   png_free(png_ptr, png_ptr->chunkdata);
-   png_ptr->chunkdata = NULL;
-
-   if (ret)
-      png_error(png_ptr, "Insufficient memory to store iTXt chunk");
-}
-#endif
-
-/* This function is called when we haven't found a handler for a
- * chunk.  If there isn't a problem with the chunk itself (ie bad
- * chunk name, CRC, or a critical chunk), the chunk is silently ignored
- * -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
- * case it will be saved away to be written out later.
- */
-void /* PRIVATE */
-png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
-   png_uint_32 skip = 0;
-
-   png_debug(1, "in png_handle_unknown");
-
-#ifdef PNG_USER_LIMITS_SUPPORTED
-   if (png_ptr->user_chunk_cache_max != 0)
-   {
-      if (png_ptr->user_chunk_cache_max == 1)
-      {
-         png_crc_finish(png_ptr, length);
-         return;
-      }
-
-      if (--png_ptr->user_chunk_cache_max == 1)
-      {
-         png_warning(png_ptr, "No space in chunk cache for unknown chunk");
-         png_crc_finish(png_ptr, length);
-         return;
-      }
-   }
-#endif
-
-   if (png_ptr->mode & PNG_HAVE_IDAT)
-   {
-      if (png_ptr->chunk_name != png_IDAT)
-         png_ptr->mode |= PNG_AFTER_IDAT;
-   }
-
-   if (PNG_CHUNK_CRITICAL(png_ptr->chunk_name))
-   {
-#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
-      if (png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name) !=
-          PNG_HANDLE_CHUNK_ALWAYS
-#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
-          && png_ptr->read_user_chunk_fn == NULL
-#endif
-          )
-#endif
-         png_chunk_error(png_ptr, "unknown critical chunk");
-   }
-
-#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
-   if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
-#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
-       || (png_ptr->read_user_chunk_fn != NULL)
-#endif
-       )
-   {
-#ifdef PNG_MAX_MALLOC_64K
-      if (length > 65535)
-      {
-         png_warning(png_ptr, "unknown chunk too large to fit in memory");
-         skip = length - 65535;
-         length = 65535;
-      }
-#endif
-
-      /* TODO: this code is very close to the unknown handling in pngpread.c,
-       * maybe it can be put into a common utility routine?
-       * png_struct::unknown_chunk is just used as a temporary variable, along
-       * with the data into which the chunk is read.  These can be eliminated.
-       */
-      PNG_CSTRING_FROM_CHUNK(png_ptr->unknown_chunk.name, png_ptr->chunk_name);
-      png_ptr->unknown_chunk.size = (png_size_t)length;
-
-      if (length == 0)
-         png_ptr->unknown_chunk.data = NULL;
-
-      else
-      {
-         png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length);
-         png_crc_read(png_ptr, png_ptr->unknown_chunk.data, length);
-      }
-
-#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
-      if (png_ptr->read_user_chunk_fn != NULL)
-      {
-         /* Callback to user unknown chunk handler */
-         int ret;
-
-         ret = (*(png_ptr->read_user_chunk_fn))
-             (png_ptr, &png_ptr->unknown_chunk);
-
-         if (ret < 0)
-            png_chunk_error(png_ptr, "error in user chunk");
-
-         if (ret == 0)
-         {
-            if (PNG_CHUNK_CRITICAL(png_ptr->chunk_name))
-            {
-#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
-               if (png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name) !=
-                   PNG_HANDLE_CHUNK_ALWAYS)
-#endif
-                  png_chunk_error(png_ptr, "unknown critical chunk");
-            }
-
-            png_set_unknown_chunks(png_ptr, info_ptr,
-                &png_ptr->unknown_chunk, 1);
-         }
-      }
-
-      else
-#endif
-         png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
-
-      png_free(png_ptr, png_ptr->unknown_chunk.data);
-      png_ptr->unknown_chunk.data = NULL;
-   }
-
-   else
-#endif
-      skip = length;
-
-   png_crc_finish(png_ptr, skip);
-
-#ifndef PNG_READ_USER_CHUNKS_SUPPORTED
-   PNG_UNUSED(info_ptr) /* Quiet compiler warnings about unused info_ptr */
-#endif
-}
-
-/* This function is called to verify that a chunk name is valid.
- * This function can't have the "critical chunk check" incorporated
- * into it, since in the future we will need to be able to call user
- * functions to handle unknown critical chunks after we check that
- * the chunk name itself is valid.
- */
-
-/* Bit hacking: the test for an invalid byte in the 4 byte chunk name is:
- *
- * ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
- */
-
-void /* PRIVATE */
-png_check_chunk_name(png_structp png_ptr, png_uint_32 chunk_name)
-{
-   int i;
-
-   png_debug(1, "in png_check_chunk_name");
-
-   for (i=1; i<=4; ++i)
-   {
-      int c = chunk_name & 0xff;
-
-      if (c < 65 || c > 122 || (c > 90 && c < 97))
-         png_chunk_error(png_ptr, "invalid chunk type");
-
-      chunk_name >>= 8;
-   }
-}
-
-/* Combines the row recently read in with the existing pixels in the row.  This
- * routine takes care of alpha and transparency if requested.  This routine also
- * handles the two methods of progressive display of interlaced images,
- * depending on the 'display' value; if 'display' is true then the whole row
- * (dp) is filled from the start by replicating the available pixels.  If
- * 'display' is false only those pixels present in the pass are filled in.
- */
-void /* PRIVATE */
-png_combine_row(png_structp png_ptr, png_bytep dp, int display)
-{
-   unsigned int pixel_depth = png_ptr->transformed_pixel_depth;
-   png_const_bytep sp = png_ptr->row_buf + 1;
-   png_uint_32 row_width = png_ptr->width;
-   unsigned int pass = png_ptr->pass;
-   png_bytep end_ptr = 0;
-   png_byte end_byte = 0;
-   unsigned int end_mask;
-
-   png_debug(1, "in png_combine_row");
-
-   /* Added in 1.5.6: it should not be possible to enter this routine until at
-    * least one row has been read from the PNG data and transformed.
-    */
-   if (pixel_depth == 0)
-      png_error(png_ptr, "internal row logic error");
-
-   /* Added in 1.5.4: the pixel depth should match the information returned by
-    * any call to png_read_update_info at this point.  Do not continue if we got
-    * this wrong.
-    */
-   if (png_ptr->info_rowbytes != 0 && png_ptr->info_rowbytes !=
-          PNG_ROWBYTES(pixel_depth, row_width))
-      png_error(png_ptr, "internal row size calculation error");
-
-   /* Don't expect this to ever happen: */
-   if (row_width == 0)
-      png_error(png_ptr, "internal row width error");
-
-   /* Preserve the last byte in cases where only part of it will be overwritten,
-    * the multiply below may overflow, we don't care because ANSI-C guarantees
-    * we get the low bits.
-    */
-   end_mask = (pixel_depth * row_width) & 7;
-   if (end_mask != 0)
-   {
-      /* end_ptr == NULL is a flag to say do nothing */
-      end_ptr = dp + PNG_ROWBYTES(pixel_depth, row_width) - 1;
-      end_byte = *end_ptr;
-#     ifdef PNG_READ_PACKSWAP_SUPPORTED
-         if (png_ptr->transformations & PNG_PACKSWAP) /* little-endian byte */
-            end_mask = 0xff << end_mask;
-
-         else /* big-endian byte */
-#     endif
-         end_mask = 0xff >> end_mask;
-      /* end_mask is now the bits to *keep* from the destination row */
-   }
-
-   /* For non-interlaced images this reduces to a png_memcpy(). A png_memcpy()
-    * will also happen if interlacing isn't supported or if the application
-    * does not call png_set_interlace_handling().  In the latter cases the
-    * caller just gets a sequence of the unexpanded rows from each interlace
-    * pass.
-    */
-#ifdef PNG_READ_INTERLACING_SUPPORTED
-   if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE) &&
-      pass < 6 && (display == 0 ||
-      /* The following copies everything for 'display' on passes 0, 2 and 4. */
-      (display == 1 && (pass & 1) != 0)))
-   {
-      /* Narrow images may have no bits in a pass; the caller should handle
-       * this, but this test is cheap:
-       */
-      if (row_width <= PNG_PASS_START_COL(pass))
-         return;
-
-      if (pixel_depth < 8)
-      {
-         /* For pixel depths up to 4 bpp the 8-pixel mask can be expanded to fit
-          * into 32 bits, then a single loop over the bytes using the four byte
-          * values in the 32-bit mask can be used.  For the 'display' option the
-          * expanded mask may also not require any masking within a byte.  To
-          * make this work the PACKSWAP option must be taken into account - it
-          * simply requires the pixels to be reversed in each byte.
-          *
-          * The 'regular' case requires a mask for each of the first 6 passes,
-          * the 'display' case does a copy for the even passes in the range
-          * 0..6.  This has already been handled in the test above.
-          *
-          * The masks are arranged as four bytes with the first byte to use in
-          * the lowest bits (little-endian) regardless of the order (PACKSWAP or
-          * not) of the pixels in each byte.
-          *
-          * NOTE: the whole of this logic depends on the caller of this function
-          * only calling it on rows appropriate to the pass.  This function only
-          * understands the 'x' logic; the 'y' logic is handled by the caller.
-          *
-          * The following defines allow generation of compile time constant bit
-          * masks for each pixel depth and each possibility of swapped or not
-          * swapped bytes.  Pass 'p' is in the range 0..6; 'x', a pixel index,
-          * is in the range 0..7; and the result is 1 if the pixel is to be
-          * copied in the pass, 0 if not.  'S' is for the sparkle method, 'B'
-          * for the block method.
-          *
-          * With some compilers a compile time expression of the general form:
-          *
-          *    (shift >= 32) ? (a >> (shift-32)) : (b >> shift)
-          *
-          * Produces warnings with values of 'shift' in the range 33 to 63
-          * because the right hand side of the ?: expression is evaluated by
-          * the compiler even though it isn't used.  Microsoft Visual C (various
-          * versions) and the Intel C compiler are known to do this.  To avoid
-          * this the following macros are used in 1.5.6.  This is a temporary
-          * solution to avoid destabilizing the code during the release process.
-          */
-#        if PNG_USE_COMPILE_TIME_MASKS
-#           define PNG_LSR(x,s) ((x)>>((s) & 0x1f))
-#           define PNG_LSL(x,s) ((x)<<((s) & 0x1f))
-#        else
-#           define PNG_LSR(x,s) ((x)>>(s))
-#           define PNG_LSL(x,s) ((x)<<(s))
-#        endif
-#        define S_COPY(p,x) (((p)<4 ? PNG_LSR(0x80088822,(3-(p))*8+(7-(x))) :\
-           PNG_LSR(0xaa55ff00,(7-(p))*8+(7-(x)))) & 1)
-#        define B_COPY(p,x) (((p)<4 ? PNG_LSR(0xff0fff33,(3-(p))*8+(7-(x))) :\
-           PNG_LSR(0xff55ff00,(7-(p))*8+(7-(x)))) & 1)
-
-         /* Return a mask for pass 'p' pixel 'x' at depth 'd'.  The mask is
-          * little endian - the first pixel is at bit 0 - however the extra
-          * parameter 's' can be set to cause the mask position to be swapped
-          * within each byte, to match the PNG format.  This is done by XOR of
-          * the shift with 7, 6 or 4 for bit depths 1, 2 and 4.
-          */
-#        define PIXEL_MASK(p,x,d,s) \
-            (PNG_LSL(((PNG_LSL(1U,(d)))-1),(((x)*(d))^((s)?8-(d):0))))
-
-         /* Hence generate the appropriate 'block' or 'sparkle' pixel copy mask.
-          */
-#        define S_MASKx(p,x,d,s) (S_COPY(p,x)?PIXEL_MASK(p,x,d,s):0)
-#        define B_MASKx(p,x,d,s) (B_COPY(p,x)?PIXEL_MASK(p,x,d,s):0)
-
-         /* Combine 8 of these to get the full mask.  For the 1-bpp and 2-bpp
-          * cases the result needs replicating, for the 4-bpp case the above
-          * generates a full 32 bits.
-          */
-#        define MASK_EXPAND(m,d) ((m)*((d)==1?0x01010101:((d)==2?0x00010001:1)))
-
-#        define S_MASK(p,d,s) MASK_EXPAND(S_MASKx(p,0,d,s) + S_MASKx(p,1,d,s) +\
-            S_MASKx(p,2,d,s) + S_MASKx(p,3,d,s) + S_MASKx(p,4,d,s) +\
-            S_MASKx(p,5,d,s) + S_MASKx(p,6,d,s) + S_MASKx(p,7,d,s), d)
-
-#        define B_MASK(p,d,s) MASK_EXPAND(B_MASKx(p,0,d,s) + B_MASKx(p,1,d,s) +\
-            B_MASKx(p,2,d,s) + B_MASKx(p,3,d,s) + B_MASKx(p,4,d,s) +\
-            B_MASKx(p,5,d,s) + B_MASKx(p,6,d,s) + B_MASKx(p,7,d,s), d)
-
-#if PNG_USE_COMPILE_TIME_MASKS
-         /* Utility macros to construct all the masks for a depth/swap
-          * combination.  The 's' parameter says whether the format is PNG
-          * (big endian bytes) or not.  Only the three odd-numbered passes are
-          * required for the display/block algorithm.
-          */
-#        define S_MASKS(d,s) { S_MASK(0,d,s), S_MASK(1,d,s), S_MASK(2,d,s),\
-            S_MASK(3,d,s), S_MASK(4,d,s), S_MASK(5,d,s) }
-
-#        define B_MASKS(d,s) { B_MASK(1,d,s), S_MASK(3,d,s), S_MASK(5,d,s) }
-
-#        define DEPTH_INDEX(d) ((d)==1?0:((d)==2?1:2))
-
-         /* Hence the pre-compiled masks indexed by PACKSWAP (or not), depth and
-          * then pass:
-          */
-         static PNG_CONST png_uint_32 row_mask[2/*PACKSWAP*/][3/*depth*/][6] =
-         {
-            /* Little-endian byte masks for PACKSWAP */
-            { S_MASKS(1,0), S_MASKS(2,0), S_MASKS(4,0) },
-            /* Normal (big-endian byte) masks - PNG format */
-            { S_MASKS(1,1), S_MASKS(2,1), S_MASKS(4,1) }
-         };
-
-         /* display_mask has only three entries for the odd passes, so index by
-          * pass>>1.
-          */
-         static PNG_CONST png_uint_32 display_mask[2][3][3] =
-         {
-            /* Little-endian byte masks for PACKSWAP */
-            { B_MASKS(1,0), B_MASKS(2,0), B_MASKS(4,0) },
-            /* Normal (big-endian byte) masks - PNG format */
-            { B_MASKS(1,1), B_MASKS(2,1), B_MASKS(4,1) }
-         };
-
-#        define MASK(pass,depth,display,png)\
-            ((display)?display_mask[png][DEPTH_INDEX(depth)][pass>>1]:\
-               row_mask[png][DEPTH_INDEX(depth)][pass])
-
-#else /* !PNG_USE_COMPILE_TIME_MASKS */
-         /* This is the runtime alternative: it seems unlikely that this will
-          * ever be either smaller or faster than the compile time approach.
-          */
-#        define MASK(pass,depth,display,png)\
-            ((display)?B_MASK(pass,depth,png):S_MASK(pass,depth,png))
-#endif /* !PNG_USE_COMPILE_TIME_MASKS */
-
-         /* Use the appropriate mask to copy the required bits.  In some cases
-          * the byte mask will be 0 or 0xff, optimize these cases.  row_width is
-          * the number of pixels, but the code copies bytes, so it is necessary
-          * to special case the end.
-          */
-         png_uint_32 pixels_per_byte = 8 / pixel_depth;
-         png_uint_32 mask;
-
-#        ifdef PNG_READ_PACKSWAP_SUPPORTED
-            if (png_ptr->transformations & PNG_PACKSWAP)
-               mask = MASK(pass, pixel_depth, display, 0);
-
-            else
-#        endif
-            mask = MASK(pass, pixel_depth, display, 1);
-
-         for (;;)
-         {
-            png_uint_32 m;
-
-            /* It doesn't matter in the following if png_uint_32 has more than
-             * 32 bits because the high bits always match those in m<<24; it is,
-             * however, essential to use OR here, not +, because of this.
-             */
-            m = mask;
-            mask = (m >> 8) | (m << 24); /* rotate right to good compilers */
-            m &= 0xff;
-
-            if (m != 0) /* something to copy */
-            {
-               if (m != 0xff)
-                  *dp = (png_byte)((*dp & ~m) | (*sp & m));
-               else
-                  *dp = *sp;
-            }
-
-            /* NOTE: this may overwrite the last byte with garbage if the image
-             * is not an exact number of bytes wide; libpng has always done
-             * this.
-             */
-            if (row_width <= pixels_per_byte)
-               break; /* May need to restore part of the last byte */
-
-            row_width -= pixels_per_byte;
-            ++dp;
-            ++sp;
-         }
-      }
-
-      else /* pixel_depth >= 8 */
-      {
-         unsigned int bytes_to_copy, bytes_to_jump;
-
-         /* Validate the depth - it must be a multiple of 8 */
-         if (pixel_depth & 7)
-            png_error(png_ptr, "invalid user transform pixel depth");
-
-         pixel_depth >>= 3; /* now in bytes */
-         row_width *= pixel_depth;
-
-         /* Regardless of pass number the Adam 7 interlace always results in a
-          * fixed number of pixels to copy then to skip.  There may be a
-          * different number of pixels to skip at the start though.
-          */
-         {
-            unsigned int offset = PNG_PASS_START_COL(pass) * pixel_depth;
-
-            row_width -= offset;
-            dp += offset;
-            sp += offset;
-         }
-
-         /* Work out the bytes to copy. */
-         if (display)
-         {
-            /* When doing the 'block' algorithm the pixel in the pass gets
-             * replicated to adjacent pixels.  This is why the even (0,2,4,6)
-             * passes are skipped above - the entire expanded row is copied.
-             */
-            bytes_to_copy = (1<<((6-pass)>>1)) * pixel_depth;
-
-            /* But don't allow this number to exceed the actual row width. */
-            if (bytes_to_copy > row_width)
-               bytes_to_copy = row_width;
-         }
-
-         else /* normal row; Adam7 only ever gives us one pixel to copy. */
-            bytes_to_copy = pixel_depth;
-
-         /* In Adam7 there is a constant offset between where the pixels go. */
-         bytes_to_jump = PNG_PASS_COL_OFFSET(pass) * pixel_depth;
-
-         /* And simply copy these bytes.  Some optimization is possible here,
-          * depending on the value of 'bytes_to_copy'.  Special case the low
-          * byte counts, which we know to be frequent.
-          *
-          * Notice that these cases all 'return' rather than 'break' - this
-          * avoids an unnecessary test on whether to restore the last byte
-          * below.
-          */
-         switch (bytes_to_copy)
-         {
-            case 1:
-               for (;;)
-               {
-                  *dp = *sp;
-
-                  if (row_width <= bytes_to_jump)
-                     return;
-
-                  dp += bytes_to_jump;
-                  sp += bytes_to_jump;
-                  row_width -= bytes_to_jump;
-               }
-
-            case 2:
-               /* There is a possibility of a partial copy at the end here; this
-                * slows the code down somewhat.
-                */
-               do
-               {
-                  dp[0] = sp[0], dp[1] = sp[1];
-
-                  if (row_width <= bytes_to_jump)
-                     return;
-
-                  sp += bytes_to_jump;
-                  dp += bytes_to_jump;
-                  row_width -= bytes_to_jump;
-               }
-               while (row_width > 1);
-
-               /* And there can only be one byte left at this point: */
-               *dp = *sp;
-               return;
-
-            case 3:
-               /* This can only be the RGB case, so each copy is exactly one
-                * pixel and it is not necessary to check for a partial copy.
-                */
-               for(;;)
-               {
-                  dp[0] = sp[0], dp[1] = sp[1], dp[2] = sp[2];
-
-                  if (row_width <= bytes_to_jump)
-                     return;
-
-                  sp += bytes_to_jump;
-                  dp += bytes_to_jump;
-                  row_width -= bytes_to_jump;
-               }
-
-            default:
-#if PNG_ALIGN_TYPE != PNG_ALIGN_NONE
-               /* Check for double byte alignment and, if possible, use a
-                * 16-bit copy.  Don't attempt this for narrow images - ones that
-                * are less than an interlace panel wide.  Don't attempt it for
-                * wide bytes_to_copy either - use the png_memcpy there.
-                */
-               if (bytes_to_copy < 16 /*else use png_memcpy*/ &&
-                  png_isaligned(dp, png_uint_16) &&
-                  png_isaligned(sp, png_uint_16) &&
-                  bytes_to_copy % sizeof (png_uint_16) == 0 &&
-                  bytes_to_jump % sizeof (png_uint_16) == 0)
-               {
-                  /* Everything is aligned for png_uint_16 copies, but try for
-                   * png_uint_32 first.
-                   */
-                  if (png_isaligned(dp, png_uint_32) &&
-                     png_isaligned(sp, png_uint_32) &&
-                     bytes_to_copy % sizeof (png_uint_32) == 0 &&
-                     bytes_to_jump % sizeof (png_uint_32) == 0)
-                  {
-                     png_uint_32p dp32 = (png_uint_32p)dp;
-                     png_const_uint_32p sp32 = (png_const_uint_32p)sp;
-                     unsigned int skip = (bytes_to_jump-bytes_to_copy) /
-                        sizeof (png_uint_32);
-
-                     do
-                     {
-                        size_t c = bytes_to_copy;
-                        do
-                        {
-                           *dp32++ = *sp32++;
-                           c -= sizeof (png_uint_32);
-                        }
-                        while (c > 0);
-
-                        if (row_width <= bytes_to_jump)
-                           return;
-
-                        dp32 += skip;
-                        sp32 += skip;
-                        row_width -= bytes_to_jump;
-                     }
-                     while (bytes_to_copy <= row_width);
-
-                     /* Get to here when the row_width truncates the final copy.
-                      * There will be 1-3 bytes left to copy, so don't try the
-                      * 16-bit loop below.
-                      */
-                     dp = (png_bytep)dp32;
-                     sp = (png_const_bytep)sp32;
-                     do
-                        *dp++ = *sp++;
-                     while (--row_width > 0);
-                     return;
-                  }
-
-                  /* Else do it in 16-bit quantities, but only if the size is
-                   * not too large.
-                   */
-                  else
-                  {
-                     png_uint_16p dp16 = (png_uint_16p)dp;
-                     png_const_uint_16p sp16 = (png_const_uint_16p)sp;
-                     unsigned int skip = (bytes_to_jump-bytes_to_copy) /
-                        sizeof (png_uint_16);
-
-                     do
-                     {
-                        size_t c = bytes_to_copy;
-                        do
-                        {
-                           *dp16++ = *sp16++;
-                           c -= sizeof (png_uint_16);
-                        }
-                        while (c > 0);
-
-                        if (row_width <= bytes_to_jump)
-                           return;
-
-                        dp16 += skip;
-                        sp16 += skip;
-                        row_width -= bytes_to_jump;
-                     }
-                     while (bytes_to_copy <= row_width);
-
-                     /* End of row - 1 byte left, bytes_to_copy > row_width: */
-                     dp = (png_bytep)dp16;
-                     sp = (png_const_bytep)sp16;
-                     do
-                        *dp++ = *sp++;
-                     while (--row_width > 0);
-                     return;
-                  }
-               }
-#endif /* PNG_ALIGN_ code */
-
-               /* The true default - use a png_memcpy: */
-               for (;;)
-               {
-                  png_memcpy(dp, sp, bytes_to_copy);
-
-                  if (row_width <= bytes_to_jump)
-                     return;
-
-                  sp += bytes_to_jump;
-                  dp += bytes_to_jump;
-                  row_width -= bytes_to_jump;
-                  if (bytes_to_copy > row_width)
-                     bytes_to_copy = row_width;
-               }
-         }
-
-         /* NOT REACHED*/
-      } /* pixel_depth >= 8 */
-
-      /* Here if pixel_depth < 8 to check 'end_ptr' below. */
-   }
-   else
-#endif
-
-   /* If here then the switch above wasn't used so just png_memcpy the whole row
-    * from the temporary row buffer (notice that this overwrites the end of the
-    * destination row if it is a partial byte.)
-    */
-   png_memcpy(dp, sp, PNG_ROWBYTES(pixel_depth, row_width));
-
-   /* Restore the overwritten bits from the last byte if necessary. */
-   if (end_ptr != NULL)
-      *end_ptr = (png_byte)((end_byte & end_mask) | (*end_ptr & ~end_mask));
-}
-
-#ifdef PNG_READ_INTERLACING_SUPPORTED
-void /* PRIVATE */
-png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
-   png_uint_32 transformations /* Because these may affect the byte layout */)
-{
-   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
-   /* Offset to next interlace block */
-   static PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
-
-   png_debug(1, "in png_do_read_interlace");
-   if (row != NULL && row_info != NULL)
-   {
-      png_uint_32 final_width;
-
-      final_width = row_info->width * png_pass_inc[pass];
-
-      switch (row_info->pixel_depth)
-      {
-         case 1:
-         {
-            png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
-            png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
-            int sshift, dshift;
-            int s_start, s_end, s_inc;
-            int jstop = png_pass_inc[pass];
-            png_byte v;
-            png_uint_32 i;
-            int j;
-
-#ifdef PNG_READ_PACKSWAP_SUPPORTED
-            if (transformations & PNG_PACKSWAP)
-            {
-                sshift = (int)((row_info->width + 7) & 0x07);
-                dshift = (int)((final_width + 7) & 0x07);
-                s_start = 7;
-                s_end = 0;
-                s_inc = -1;
-            }
-
-            else
-#endif
-            {
-                sshift = 7 - (int)((row_info->width + 7) & 0x07);
-                dshift = 7 - (int)((final_width + 7) & 0x07);
-                s_start = 0;
-                s_end = 7;
-                s_inc = 1;
-            }
-
-            for (i = 0; i < row_info->width; i++)
-            {
-               v = (png_byte)((*sp >> sshift) & 0x01);
-               for (j = 0; j < jstop; j++)
-               {
-                  *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
-                  *dp |= (png_byte)(v << dshift);
-
-                  if (dshift == s_end)
-                  {
-                     dshift = s_start;
-                     dp--;
-                  }
-
-                  else
-                     dshift += s_inc;
-               }
-
-               if (sshift == s_end)
-               {
-                  sshift = s_start;
-                  sp--;
-               }
-
-               else
-                  sshift += s_inc;
-            }
-            break;
-         }
-
-         case 2:
-         {
-            png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
-            png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
-            int sshift, dshift;
-            int s_start, s_end, s_inc;
-            int jstop = png_pass_inc[pass];
-            png_uint_32 i;
-
-#ifdef PNG_READ_PACKSWAP_SUPPORTED
-            if (transformations & PNG_PACKSWAP)
-            {
-               sshift = (int)(((row_info->width + 3) & 0x03) << 1);
-               dshift = (int)(((final_width + 3) & 0x03) << 1);
-               s_start = 6;
-               s_end = 0;
-               s_inc = -2;
-            }
-
-            else
-#endif
-            {
-               sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
-               dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
-               s_start = 0;
-               s_end = 6;
-               s_inc = 2;
-            }
-
-            for (i = 0; i < row_info->width; i++)
-            {
-               png_byte v;
-               int j;
-
-               v = (png_byte)((*sp >> sshift) & 0x03);
-               for (j = 0; j < jstop; j++)
-               {
-                  *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
-                  *dp |= (png_byte)(v << dshift);
-
-                  if (dshift == s_end)
-                  {
-                     dshift = s_start;
-                     dp--;
-                  }
-
-                  else
-                     dshift += s_inc;
-               }
-
-               if (sshift == s_end)
-               {
-                  sshift = s_start;
-                  sp--;
-               }
-
-               else
-                  sshift += s_inc;
-            }
-            break;
-         }
-
-         case 4:
-         {
-            png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
-            png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
-            int sshift, dshift;
-            int s_start, s_end, s_inc;
-            png_uint_32 i;
-            int jstop = png_pass_inc[pass];
-
-#ifdef PNG_READ_PACKSWAP_SUPPORTED
-            if (transformations & PNG_PACKSWAP)
-            {
-               sshift = (int)(((row_info->width + 1) & 0x01) << 2);
-               dshift = (int)(((final_width + 1) & 0x01) << 2);
-               s_start = 4;
-               s_end = 0;
-               s_inc = -4;
-            }
-
-            else
-#endif
-            {
-               sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
-               dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
-               s_start = 0;
-               s_end = 4;
-               s_inc = 4;
-            }
-
-            for (i = 0; i < row_info->width; i++)
-            {
-               png_byte v = (png_byte)((*sp >> sshift) & 0x0f);
-               int j;
-
-               for (j = 0; j < jstop; j++)
-               {
-                  *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
-                  *dp |= (png_byte)(v << dshift);
-
-                  if (dshift == s_end)
-                  {
-                     dshift = s_start;
-                     dp--;
-                  }
-
-                  else
-                     dshift += s_inc;
-               }
-
-               if (sshift == s_end)
-               {
-                  sshift = s_start;
-                  sp--;
-               }
-
-               else
-                  sshift += s_inc;
-            }
-            break;
-         }
-
-         default:
-         {
-            png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
-
-            png_bytep sp = row + (png_size_t)(row_info->width - 1)
-                * pixel_bytes;
-
-            png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
-
-            int jstop = png_pass_inc[pass];
-            png_uint_32 i;
-
-            for (i = 0; i < row_info->width; i++)
-            {
-               png_byte v[8];
-               int j;
-
-               png_memcpy(v, sp, pixel_bytes);
-
-               for (j = 0; j < jstop; j++)
-               {
-                  png_memcpy(dp, v, pixel_bytes);
-                  dp -= pixel_bytes;
-               }
-
-               sp -= pixel_bytes;
-            }
-            break;
-         }
-      }
-
-      row_info->width = final_width;
-      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width);
-   }
-#ifndef PNG_READ_PACKSWAP_SUPPORTED
-   PNG_UNUSED(transformations)  /* Silence compiler warning */
-#endif
-}
-#endif /* PNG_READ_INTERLACING_SUPPORTED */
-
-static void
-png_read_filter_row_sub(png_row_infop row_info, png_bytep row,
-   png_const_bytep prev_row)
-{
-   png_size_t i;
-   png_size_t istop = row_info->rowbytes;
-   unsigned int bpp = (row_info->pixel_depth + 7) >> 3;
-   png_bytep rp = row + bpp;
-
-   PNG_UNUSED(prev_row)
-
-   for (i = bpp; i < istop; i++)
-   {
-      *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff);
-      rp++;
-   }
-}
-
-static void
-png_read_filter_row_up(png_row_infop row_info, png_bytep row,
-   png_const_bytep prev_row)
-{
-   png_size_t i;
-   png_size_t istop = row_info->rowbytes;
-   png_bytep rp = row;
-   png_const_bytep pp = prev_row;
-
-   for (i = 0; i < istop; i++)
-   {
-      *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
-      rp++;
-   }
-}
-
-static void
-png_read_filter_row_avg(png_row_infop row_info, png_bytep row,
-   png_const_bytep prev_row)
-{
-   png_size_t i;
-   png_bytep rp = row;
-   png_const_bytep pp = prev_row;
-   unsigned int bpp = (row_info->pixel_depth + 7) >> 3;
-   png_size_t istop = row_info->rowbytes - bpp;
-
-   for (i = 0; i < bpp; i++)
-   {
-      *rp = (png_byte)(((int)(*rp) +
-         ((int)(*pp++) / 2 )) & 0xff);
-
-      rp++;
-   }
-
-   for (i = 0; i < istop; i++)
-   {
-      *rp = (png_byte)(((int)(*rp) +
-         (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff);
-
-      rp++;
-   }
-}
-
-static void
-png_read_filter_row_paeth_1byte_pixel(png_row_infop row_info, png_bytep row,
-   png_const_bytep prev_row)
-{
-   png_bytep rp_end = row + row_info->rowbytes;
-   int a, c;
-
-   /* First pixel/byte */
-   c = *prev_row++;
-   a = *row + c;
-   *row++ = (png_byte)a;
-
-   /* Remainder */
-   while (row < rp_end)
-   {
-      int b, pa, pb, pc, p;
-
-      a &= 0xff; /* From previous iteration or start */
-      b = *prev_row++;
-
-      p = b - c;
-      pc = a - c;
-
-#     ifdef PNG_USE_ABS
-         pa = abs(p);
-         pb = abs(pc);
-         pc = abs(p + pc);
-#     else
-         pa = p < 0 ? -p : p;
-         pb = pc < 0 ? -pc : pc;
-         pc = (p + pc) < 0 ? -(p + pc) : p + pc;
-#     endif
-
-      /* Find the best predictor, the least of pa, pb, pc favoring the earlier
-       * ones in the case of a tie.
-       */
-      if (pb < pa) pa = pb, a = b;
-      if (pc < pa) a = c;
-
-      /* Calculate the current pixel in a, and move the previous row pixel to c
-       * for the next time round the loop
-       */
-      c = b;
-      a += *row;
-      *row++ = (png_byte)a;
-   }
-}
-
-static void
-png_read_filter_row_paeth_multibyte_pixel(png_row_infop row_info, png_bytep row,
-   png_const_bytep prev_row)
-{
-   int bpp = (row_info->pixel_depth + 7) >> 3;
-   png_bytep rp_end = row + bpp;
-
-   /* Process the first pixel in the row completely (this is the same as 'up'
-    * because there is only one candidate predictor for the first row).
-    */
-   while (row < rp_end)
-   {
-      int a = *row + *prev_row++;
-      *row++ = (png_byte)a;
-   }
-
-   /* Remainder */
-   rp_end += row_info->rowbytes - bpp;
-
-   while (row < rp_end)
-   {
-      int a, b, c, pa, pb, pc, p;
-
-      c = *(prev_row - bpp);
-      a = *(row - bpp);
-      b = *prev_row++;
-
-      p = b - c;
-      pc = a - c;
-
-#     ifdef PNG_USE_ABS
-         pa = abs(p);
-         pb = abs(pc);
-         pc = abs(p + pc);
-#     else
-         pa = p < 0 ? -p : p;
-         pb = pc < 0 ? -pc : pc;
-         pc = (p + pc) < 0 ? -(p + pc) : p + pc;
-#     endif
-
-      if (pb < pa) pa = pb, a = b;
-      if (pc < pa) a = c;
-
-      c = b;
-      a += *row;
-      *row++ = (png_byte)a;
-   }
-}
-
-#ifdef PNG_ARM_NEON
-
-#ifdef __linux__
-#include <stdio.h>
-#include <elf.h>
-#include <asm/hwcap.h>
-
-static int png_have_hwcap(unsigned cap)
-{
-   FILE *f = fopen("/proc/self/auxv", "r");
-   Elf32_auxv_t aux;
-   int have_cap = 0;
-
-   if (!f)
-      return 0;
-
-   while (fread(&aux, sizeof(aux), 1, f) > 0)
-   {
-      if (aux.a_type == AT_HWCAP &&
-          aux.a_un.a_val & cap)
-      {
-         have_cap = 1;
-         break;
-      }
-   }
-
-   fclose(f);
-
-   return have_cap;
-}
-#endif /* __linux__ */
-
-static void
-png_init_filter_functions_neon(png_structp pp, unsigned int bpp)
-{
-#ifdef __linux__
-   if (!png_have_hwcap(HWCAP_NEON))
-      return;
-#endif
-
-   pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up_neon;
-
-   if (bpp == 3)
-   {
-      pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_neon;
-      pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_neon;
-      pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
-         png_read_filter_row_paeth3_neon;
-   }
-
-   else if (bpp == 4)
-   {
-      pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_neon;
-      pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_neon;
-      pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
-          png_read_filter_row_paeth4_neon;
-   }
-}
-#endif /* PNG_ARM_NEON */
-
-static void
-png_init_filter_functions(png_structp pp)
-{
-   unsigned int bpp = (pp->pixel_depth + 7) >> 3;
-
-   pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub;
-   pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up;
-   pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg;
-   if (bpp == 1)
-      pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
-         png_read_filter_row_paeth_1byte_pixel;
-   else
-      pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
-         png_read_filter_row_paeth_multibyte_pixel;
-
-#ifdef PNG_ARM_NEON
-   png_init_filter_functions_neon(pp, bpp);
-#endif
-}
-
-void /* PRIVATE */
-png_read_filter_row(png_structp pp, png_row_infop row_info, png_bytep row,
-   png_const_bytep prev_row, int filter)
-{
-   if (pp->read_filter[0] == NULL)
-      png_init_filter_functions(pp);
-   if (filter > PNG_FILTER_VALUE_NONE && filter < PNG_FILTER_VALUE_LAST)
-      pp->read_filter[filter-1](row_info, row, prev_row);
-}
-
-#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
-void /* PRIVATE */
-png_read_finish_row(png_structp png_ptr)
-{
-#ifdef PNG_READ_INTERLACING_SUPPORTED
-   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
-
-   /* Start of interlace block */
-   static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
-
-   /* Offset to next interlace block */
-   static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
-
-   /* Start of interlace block in the y direction */
-   static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
-
-   /* Offset to next interlace block in the y direction */
-   static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
-#endif /* PNG_READ_INTERLACING_SUPPORTED */
-
-   png_debug(1, "in png_read_finish_row");
-   png_ptr->row_number++;
-   if (png_ptr->row_number < png_ptr->num_rows)
-      return;
-
-#ifdef PNG_READ_INTERLACING_SUPPORTED
-   if (png_ptr->interlaced)
-   {
-      png_ptr->row_number = 0;
-
-      /* TO DO: don't do this if prev_row isn't needed (requires
-       * read-ahead of the next row's filter byte.
-       */
-      png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
-
-      do
-      {
-         png_ptr->pass++;
-
-         if (png_ptr->pass >= 7)
-            break;
-
-         png_ptr->iwidth = (png_ptr->width +
-            png_pass_inc[png_ptr->pass] - 1 -
-            png_pass_start[png_ptr->pass]) /
-            png_pass_inc[png_ptr->pass];
-
-         if (!(png_ptr->transformations & PNG_INTERLACE))
-         {
-            png_ptr->num_rows = (png_ptr->height +
-                png_pass_yinc[png_ptr->pass] - 1 -
-                png_pass_ystart[png_ptr->pass]) /
-                png_pass_yinc[png_ptr->pass];
-         }
-
-         else  /* if (png_ptr->transformations & PNG_INTERLACE) */
-            break; /* libpng deinterlacing sees every row */
-
-      } while (png_ptr->num_rows == 0 || png_ptr->iwidth == 0);
-
-      if (png_ptr->pass < 7)
-         return;
-   }
-#endif /* PNG_READ_INTERLACING_SUPPORTED */
-
-   if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
-   {
-      char extra;
-      int ret;
-
-      png_ptr->zstream.next_out = (Byte *)&extra;
-      png_ptr->zstream.avail_out = (uInt)1;
-
-      for (;;)
-      {
-         if (!(png_ptr->zstream.avail_in))
-         {
-            while (!png_ptr->idat_size)
-            {
-               png_crc_finish(png_ptr, 0);
-               png_ptr->idat_size = png_read_chunk_header(png_ptr);
-               if (png_ptr->chunk_name != png_IDAT)
-                  png_error(png_ptr, "Not enough image data");
-            }
-
-            png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
-            png_ptr->zstream.next_in = png_ptr->zbuf;
-
-            if (png_ptr->zbuf_size > png_ptr->idat_size)
-               png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
-
-            png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in);
-            png_ptr->idat_size -= png_ptr->zstream.avail_in;
-         }
-
-         ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
-
-         if (ret == Z_STREAM_END)
-         {
-            if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in ||
-                png_ptr->idat_size)
-               png_warning(png_ptr, "Extra compressed data");
-
-            png_ptr->mode |= PNG_AFTER_IDAT;
-            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
-            break;
-         }
-
-         if (ret != Z_OK)
-            png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
-                "Decompression Error");
-
-         if (!(png_ptr->zstream.avail_out))
-         {
-            png_warning(png_ptr, "Extra compressed data");
-            png_ptr->mode |= PNG_AFTER_IDAT;
-            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
-            break;
-         }
-
-      }
-      png_ptr->zstream.avail_out = 0;
-   }
-
-   if (png_ptr->idat_size || png_ptr->zstream.avail_in)
-      png_warning(png_ptr, "Extra compression data");
-
-   inflateReset(&png_ptr->zstream);
-
-   png_ptr->mode |= PNG_AFTER_IDAT;
-}
-#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
-
-void /* PRIVATE */
-png_read_start_row(png_structp png_ptr)
-{
-#ifdef PNG_READ_INTERLACING_SUPPORTED
-   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
-
-   /* Start of interlace block */
-   static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
-
-   /* Offset to next interlace block */
-   static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
-
-   /* Start of interlace block in the y direction */
-   static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
-
-   /* Offset to next interlace block in the y direction */
-   static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
-#endif
-
-   int max_pixel_depth;
-   png_size_t row_bytes;
-
-   png_debug(1, "in png_read_start_row");
-   png_ptr->zstream.avail_in = 0;
-#ifdef PNG_READ_TRANSFORMS_SUPPORTED
-   png_init_read_transformations(png_ptr);
-#endif
-#ifdef PNG_READ_INTERLACING_SUPPORTED
-   if (png_ptr->interlaced)
-   {
-      if (!(png_ptr->transformations & PNG_INTERLACE))
-         png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
-             png_pass_ystart[0]) / png_pass_yinc[0];
-
-      else
-         png_ptr->num_rows = png_ptr->height;
-
-      png_ptr->iwidth = (png_ptr->width +
-          png_pass_inc[png_ptr->pass] - 1 -
-          png_pass_start[png_ptr->pass]) /
-          png_pass_inc[png_ptr->pass];
-   }
-
-   else
-#endif /* PNG_READ_INTERLACING_SUPPORTED */
-   {
-      png_ptr->num_rows = png_ptr->height;
-      png_ptr->iwidth = png_ptr->width;
-   }
-
-   max_pixel_depth = png_ptr->pixel_depth;
-
-   /* WARNING: * png_read_transform_info (pngrtran.c) performs a simpliar set of
-    * calculations to calculate the final pixel depth, then
-    * png_do_read_transforms actually does the transforms.  This means that the
-    * code which effectively calculates this value is actually repeated in three
-    * separate places.  They must all match.  Innocent changes to the order of
-    * transformations can and will break libpng in a way that causes memory
-    * overwrites.
-    *
-    * TODO: fix this.
-    */
-#ifdef PNG_READ_PACK_SUPPORTED
-   if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
-      max_pixel_depth = 8;
-#endif
-
-#ifdef PNG_READ_EXPAND_SUPPORTED
-   if (png_ptr->transformations & PNG_EXPAND)
-   {
-      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
-      {
-         if (png_ptr->num_trans)
-            max_pixel_depth = 32;
-
-         else
-            max_pixel_depth = 24;
-      }
-
-      else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
-      {
-         if (max_pixel_depth < 8)
-            max_pixel_depth = 8;
-
-         if (png_ptr->num_trans)
-            max_pixel_depth *= 2;
-      }
-
-      else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
-      {
-         if (png_ptr->num_trans)
-         {
-            max_pixel_depth *= 4;
-            max_pixel_depth /= 3;
-         }
-      }
-   }
-#endif
-
-#ifdef PNG_READ_EXPAND_16_SUPPORTED
-   if (png_ptr->transformations & PNG_EXPAND_16)
-   {
-#     ifdef PNG_READ_EXPAND_SUPPORTED
-         /* In fact it is an error if it isn't supported, but checking is
-          * the safe way.
-          */
-         if (png_ptr->transformations & PNG_EXPAND)
-         {
-            if (png_ptr->bit_depth < 16)
-               max_pixel_depth *= 2;
-         }
-         else
-#     endif
-         png_ptr->transformations &= ~PNG_EXPAND_16;
-   }
-#endif
-
-#ifdef PNG_READ_FILLER_SUPPORTED
-   if (png_ptr->transformations & (PNG_FILLER))
-   {
-      if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
-      {
-         if (max_pixel_depth <= 8)
-            max_pixel_depth = 16;
-
-         else
-            max_pixel_depth = 32;
-      }
-
-      else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB ||
-         png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
-      {
-         if (max_pixel_depth <= 32)
-            max_pixel_depth = 32;
-
-         else
-            max_pixel_depth = 64;
-      }
-   }
-#endif
-
-#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
-   if (png_ptr->transformations & PNG_GRAY_TO_RGB)
-   {
-      if (
-#ifdef PNG_READ_EXPAND_SUPPORTED
-          (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
-#endif
-#ifdef PNG_READ_FILLER_SUPPORTED
-          (png_ptr->transformations & (PNG_FILLER)) ||
-#endif
-          png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
-      {
-         if (max_pixel_depth <= 16)
-            max_pixel_depth = 32;
-
-         else
-            max_pixel_depth = 64;
-      }
-
-      else
-      {
-         if (max_pixel_depth <= 8)
-         {
-            if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
-               max_pixel_depth = 32;
-
-            else
-               max_pixel_depth = 24;
-         }
-
-         else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
-            max_pixel_depth = 64;
-
-         else
-            max_pixel_depth = 48;
-      }
-   }
-#endif
-
-#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
-defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
-   if (png_ptr->transformations & PNG_USER_TRANSFORM)
-   {
-      int user_pixel_depth = png_ptr->user_transform_depth *
-         png_ptr->user_transform_channels;
-
-      if (user_pixel_depth > max_pixel_depth)
-         max_pixel_depth = user_pixel_depth;
-   }
-#endif
-
-   /* This value is stored in png_struct and double checked in the row read
-    * code.
-    */
-   png_ptr->maximum_pixel_depth = (png_byte)max_pixel_depth;
-   png_ptr->transformed_pixel_depth = 0; /* calculated on demand */
-
-   /* Align the width on the next larger 8 pixels.  Mainly used
-    * for interlacing
-    */
-   row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
-   /* Calculate the maximum bytes needed, adding a byte and a pixel
-    * for safety's sake
-    */
-   row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) +
-       1 + ((max_pixel_depth + 7) >> 3);
-
-#ifdef PNG_MAX_MALLOC_64K
-   if (row_bytes > (png_uint_32)65536L)
-      png_error(png_ptr, "This image requires a row greater than 64KB");
-#endif
-
-   if (row_bytes + 48 > png_ptr->old_big_row_buf_size)
-   {
-     png_free(png_ptr, png_ptr->big_row_buf);
-     png_free(png_ptr, png_ptr->big_prev_row);
-
-     if (png_ptr->interlaced)
-        png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr,
-            row_bytes + 48);
-
-     else
-        png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes + 48);
-
-     png_ptr->big_prev_row = (png_bytep)png_malloc(png_ptr, row_bytes + 48);
-
-#ifdef PNG_ALIGNED_MEMORY_SUPPORTED
-     /* Use 16-byte aligned memory for row_buf with at least 16 bytes
-      * of padding before and after row_buf; treat prev_row similarly.
-      * NOTE: the alignment is to the start of the pixels, one beyond the start
-      * of the buffer, because of the filter byte.  Prior to libpng 1.5.6 this
-      * was incorrect; the filter byte was aligned, which had the exact
-      * opposite effect of that intended.
-      */
-     {
-        png_bytep temp = png_ptr->big_row_buf + 32;
-        int extra = (int)((temp - (png_bytep)0) & 0x0f);
-        png_ptr->row_buf = temp - extra - 1/*filter byte*/;
-
-        temp = png_ptr->big_prev_row + 32;
-        extra = (int)((temp - (png_bytep)0) & 0x0f);
-        png_ptr->prev_row = temp - extra - 1/*filter byte*/;
-     }
-
-#else
-     /* Use 31 bytes of padding before and 17 bytes after row_buf. */
-     png_ptr->row_buf = png_ptr->big_row_buf + 31;
-     png_ptr->prev_row = png_ptr->big_prev_row + 31;
-#endif
-     png_ptr->old_big_row_buf_size = row_bytes + 48;
-   }
-
-#ifdef PNG_MAX_MALLOC_64K
-   if (png_ptr->rowbytes > 65535)
-      png_error(png_ptr, "This image requires a row greater than 64KB");
-
-#endif
-   if (png_ptr->rowbytes > (PNG_SIZE_MAX - 1))
-      png_error(png_ptr, "Row has too many bytes to allocate in memory");
-
-   png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
-
-   png_debug1(3, "width = %u,", png_ptr->width);
-   png_debug1(3, "height = %u,", png_ptr->height);
-   png_debug1(3, "iwidth = %u,", png_ptr->iwidth);
-   png_debug1(3, "num_rows = %u,", png_ptr->num_rows);
-   png_debug1(3, "rowbytes = %lu,", (unsigned long)png_ptr->rowbytes);
-   png_debug1(3, "irowbytes = %lu",
-       (unsigned long)PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1);
-
-   png_ptr->flags |= PNG_FLAG_ROW_INIT;
-}
-#endif /* PNG_READ_SUPPORTED */
+
+/* pngrutil.c - utilities to read a PNG file
+ *
+ * Last changed in libpng 1.6.15 [November 20, 2014]
+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * This file contains routines that are only called from within
+ * libpng itself during the course of reading an image.
+ */
+
+#include "pngpriv.h"
+
+#ifdef PNG_READ_SUPPORTED
+
+png_uint_32 PNGAPI
+png_get_uint_31(png_const_structrp png_ptr, png_const_bytep buf)
+{
+   png_uint_32 uval = png_get_uint_32(buf);
+
+   if (uval > PNG_UINT_31_MAX)
+      png_error(png_ptr, "PNG unsigned integer out of range");
+
+   return (uval);
+}
+
+#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_READ_cHRM_SUPPORTED)
+/* The following is a variation on the above for use with the fixed
+ * point values used for gAMA and cHRM.  Instead of png_error it
+ * issues a warning and returns (-1) - an invalid value because both
+ * gAMA and cHRM use *unsigned* integers for fixed point values.
+ */
+#define PNG_FIXED_ERROR (-1)
+
+static png_fixed_point /* PRIVATE */
+png_get_fixed_point(png_structrp png_ptr, png_const_bytep buf)
+{
+   png_uint_32 uval = png_get_uint_32(buf);
+
+   if (uval <= PNG_UINT_31_MAX)
+      return (png_fixed_point)uval; /* known to be in range */
+
+   /* The caller can turn off the warning by passing NULL. */
+   if (png_ptr != NULL)
+      png_warning(png_ptr, "PNG fixed point integer out of range");
+
+   return PNG_FIXED_ERROR;
+}
+#endif
+
+#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED
+/* NOTE: the read macros will obscure these definitions, so that if
+ * PNG_USE_READ_MACROS is set the library will not use them internally,
+ * but the APIs will still be available externally.
+ *
+ * The parentheses around "PNGAPI function_name" in the following three
+ * functions are necessary because they allow the macros to co-exist with
+ * these (unused but exported) functions.
+ */
+
+/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
+png_uint_32 (PNGAPI
+png_get_uint_32)(png_const_bytep buf)
+{
+   png_uint_32 uval =
+       ((png_uint_32)(*(buf    )) << 24) +
+       ((png_uint_32)(*(buf + 1)) << 16) +
+       ((png_uint_32)(*(buf + 2)) <<  8) +
+       ((png_uint_32)(*(buf + 3))      ) ;
+
+   return uval;
+}
+
+/* Grab a signed 32-bit integer from a buffer in big-endian format.  The
+ * data is stored in the PNG file in two's complement format and there
+ * is no guarantee that a 'png_int_32' is exactly 32 bits, therefore
+ * the following code does a two's complement to native conversion.
+ */
+png_int_32 (PNGAPI
+png_get_int_32)(png_const_bytep buf)
+{
+   png_uint_32 uval = png_get_uint_32(buf);
+   if ((uval & 0x80000000) == 0) /* non-negative */
+      return uval;
+
+   uval = (uval ^ 0xffffffff) + 1;  /* 2's complement: -x = ~x+1 */
+   return -(png_int_32)uval;
+}
+
+/* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
+png_uint_16 (PNGAPI
+png_get_uint_16)(png_const_bytep buf)
+{
+   /* ANSI-C requires an int value to accomodate at least 16 bits so this
+    * works and allows the compiler not to worry about possible narrowing
+    * on 32 bit systems.  (Pre-ANSI systems did not make integers smaller
+    * than 16 bits either.)
+    */
+   unsigned int val =
+       ((unsigned int)(*buf) << 8) +
+       ((unsigned int)(*(buf + 1)));
+
+   return (png_uint_16)val;
+}
+
+#endif /* READ_INT_FUNCTIONS */
+
+/* Read and check the PNG file signature */
+void /* PRIVATE */
+png_read_sig(png_structrp png_ptr, png_inforp info_ptr)
+{
+   png_size_t num_checked, num_to_check;
+
+   /* Exit if the user application does not expect a signature. */
+   if (png_ptr->sig_bytes >= 8)
+      return;
+
+   num_checked = png_ptr->sig_bytes;
+   num_to_check = 8 - num_checked;
+
+#ifdef PNG_IO_STATE_SUPPORTED
+   png_ptr->io_state = PNG_IO_READING | PNG_IO_SIGNATURE;
+#endif
+
+   /* The signature must be serialized in a single I/O call. */
+   png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check);
+   png_ptr->sig_bytes = 8;
+
+   if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check) != 0)
+   {
+      if (num_checked < 4 &&
+          png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
+         png_error(png_ptr, "Not a PNG file");
+      else
+         png_error(png_ptr, "PNG file corrupted by ASCII conversion");
+   }
+   if (num_checked < 3)
+      png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
+}
+
+/* Read the chunk header (length + type name).
+ * Put the type name into png_ptr->chunk_name, and return the length.
+ */
+png_uint_32 /* PRIVATE */
+png_read_chunk_header(png_structrp png_ptr)
+{
+   png_byte buf[8];
+   png_uint_32 length;
+
+#ifdef PNG_IO_STATE_SUPPORTED
+   png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_HDR;
+#endif
+
+   /* Read the length and the chunk name.
+    * This must be performed in a single I/O call.
+    */
+   png_read_data(png_ptr, buf, 8);
+   length = png_get_uint_31(png_ptr, buf);
+
+   /* Put the chunk name into png_ptr->chunk_name. */
+   png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(buf+4);
+
+   png_debug2(0, "Reading %lx chunk, length = %lu",
+       (unsigned long)png_ptr->chunk_name, (unsigned long)length);
+
+   /* Reset the crc and run it over the chunk name. */
+   png_reset_crc(png_ptr);
+   png_calculate_crc(png_ptr, buf + 4, 4);
+
+   /* Check to see if chunk name is valid. */
+   png_check_chunk_name(png_ptr, png_ptr->chunk_name);
+
+#ifdef PNG_IO_STATE_SUPPORTED
+   png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_DATA;
+#endif
+
+   return length;
+}
+
+/* Read data, and (optionally) run it through the CRC. */
+void /* PRIVATE */
+png_crc_read(png_structrp png_ptr, png_bytep buf, png_uint_32 length)
+{
+   if (png_ptr == NULL)
+      return;
+
+   png_read_data(png_ptr, buf, length);
+   png_calculate_crc(png_ptr, buf, length);
+}
+
+/* Optionally skip data and then check the CRC.  Depending on whether we
+ * are reading an ancillary or critical chunk, and how the program has set
+ * things up, we may calculate the CRC on the data and print a message.
+ * Returns '1' if there was a CRC error, '0' otherwise.
+ */
+int /* PRIVATE */
+png_crc_finish(png_structrp png_ptr, png_uint_32 skip)
+{
+   /* The size of the local buffer for inflate is a good guess as to a
+    * reasonable size to use for buffering reads from the application.
+    */
+   while (skip > 0)
+   {
+      png_uint_32 len;
+      png_byte tmpbuf[PNG_INFLATE_BUF_SIZE];
+
+      len = (sizeof tmpbuf);
+      if (len > skip)
+         len = skip;
+      skip -= len;
+
+      png_crc_read(png_ptr, tmpbuf, len);
+   }
+
+   if (png_crc_error(png_ptr) != 0)
+   {
+      if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0 ?
+          (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) == 0 :
+          (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE) != 0)
+      {
+         png_chunk_warning(png_ptr, "CRC error");
+      }
+
+      else
+         png_chunk_error(png_ptr, "CRC error");
+
+      return (1);
+   }
+
+   return (0);
+}
+
+/* Compare the CRC stored in the PNG file with that calculated by libpng from
+ * the data it has read thus far.
+ */
+int /* PRIVATE */
+png_crc_error(png_structrp png_ptr)
+{
+   png_byte crc_bytes[4];
+   png_uint_32 crc;
+   int need_crc = 1;
+
+   if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0)
+   {
+      if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
+          (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
+         need_crc = 0;
+   }
+
+   else /* critical */
+   {
+      if ((png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) != 0)
+         need_crc = 0;
+   }
+
+#ifdef PNG_IO_STATE_SUPPORTED
+   png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_CRC;
+#endif
+
+   /* The chunk CRC must be serialized in a single I/O call. */
+   png_read_data(png_ptr, crc_bytes, 4);
+
+   if (need_crc != 0)
+   {
+      crc = png_get_uint_32(crc_bytes);
+      return ((int)(crc != png_ptr->crc));
+   }
+
+   else
+      return (0);
+}
+
+#if defined(PNG_READ_iCCP_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) ||\
+    defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_READ_sCAL_SUPPORTED) ||\
+    defined(PNG_READ_sPLT_SUPPORTED) || defined(PNG_READ_tEXt_SUPPORTED) ||\
+    defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_SEQUENTIAL_READ_SUPPORTED)
+/* Manage the read buffer; this simply reallocates the buffer if it is not small
+ * enough (or if it is not allocated).  The routine returns a pointer to the
+ * buffer; if an error occurs and 'warn' is set the routine returns NULL, else
+ * it will call png_error (via png_malloc) on failure.  (warn == 2 means
+ * 'silent').
+ */
+static png_bytep
+png_read_buffer(png_structrp png_ptr, png_alloc_size_t new_size, int warn)
+{
+   png_bytep buffer = png_ptr->read_buffer;
+
+   if (buffer != NULL && new_size > png_ptr->read_buffer_size)
+   {
+      png_ptr->read_buffer = NULL;
+      png_ptr->read_buffer = NULL;
+      png_ptr->read_buffer_size = 0;
+      png_free(png_ptr, buffer);
+      buffer = NULL;
+   }
+
+   if (buffer == NULL)
+   {
+      buffer = png_voidcast(png_bytep, png_malloc_base(png_ptr, new_size));
+
+      if (buffer != NULL)
+      {
+         png_ptr->read_buffer = buffer;
+         png_ptr->read_buffer_size = new_size;
+      }
+
+      else if (warn < 2) /* else silent */
+      {
+         if (warn != 0)
+             png_chunk_warning(png_ptr, "insufficient memory to read chunk");
+
+         else
+             png_chunk_error(png_ptr, "insufficient memory to read chunk");
+      }
+   }
+
+   return buffer;
+}
+#endif /* READ_iCCP|iTXt|pCAL|sCAL|sPLT|tEXt|zTXt|SEQUENTIAL_READ */
+
+/* png_inflate_claim: claim the zstream for some nefarious purpose that involves
+ * decompression.  Returns Z_OK on success, else a zlib error code.  It checks
+ * the owner but, in final release builds, just issues a warning if some other
+ * chunk apparently owns the stream.  Prior to release it does a png_error.
+ */
+static int
+png_inflate_claim(png_structrp png_ptr, png_uint_32 owner)
+{
+   if (png_ptr->zowner != 0)
+   {
+      char msg[64];
+
+      PNG_STRING_FROM_CHUNK(msg, png_ptr->zowner);
+      /* So the message that results is "<chunk> using zstream"; this is an
+       * internal error, but is very useful for debugging.  i18n requirements
+       * are minimal.
+       */
+      (void)png_safecat(msg, (sizeof msg), 4, " using zstream");
+#if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC
+      png_chunk_warning(png_ptr, msg);
+      png_ptr->zowner = 0;
+#else
+      png_chunk_error(png_ptr, msg);
+#endif
+   }
+
+   /* Implementation note: unlike 'png_deflate_claim' this internal function
+    * does not take the size of the data as an argument.  Some efficiency could
+    * be gained by using this when it is known *if* the zlib stream itself does
+    * not record the number; however, this is an illusion: the original writer
+    * of the PNG may have selected a lower window size, and we really must
+    * follow that because, for systems with with limited capabilities, we
+    * would otherwise reject the application's attempts to use a smaller window
+    * size (zlib doesn't have an interface to say "this or lower"!).
+    *
+    * inflateReset2 was added to zlib 1.2.4; before this the window could not be
+    * reset, therefore it is necessary to always allocate the maximum window
+    * size with earlier zlibs just in case later compressed chunks need it.
+    */
+   {
+      int ret; /* zlib return code */
+#if PNG_ZLIB_VERNUM >= 0x1240
+
+# if defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_MAXIMUM_INFLATE_WINDOW)
+      int window_bits;
+
+      if (((png_ptr->options >> PNG_MAXIMUM_INFLATE_WINDOW) & 3) ==
+          PNG_OPTION_ON)
+         window_bits = 15;
+
+      else
+         window_bits = 0;
+# else
+#   define window_bits 0
+# endif
+#endif
+
+      /* Set this for safety, just in case the previous owner left pointers to
+       * memory allocations.
+       */
+      png_ptr->zstream.next_in = NULL;
+      png_ptr->zstream.avail_in = 0;
+      png_ptr->zstream.next_out = NULL;
+      png_ptr->zstream.avail_out = 0;
+
+      if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0)
+      {
+#if PNG_ZLIB_VERNUM < 0x1240
+         ret = inflateReset(&png_ptr->zstream);
+#else
+         ret = inflateReset2(&png_ptr->zstream, window_bits);
+#endif
+      }
+
+      else
+      {
+#if PNG_ZLIB_VERNUM < 0x1240
+         ret = inflateInit(&png_ptr->zstream);
+#else
+         ret = inflateInit2(&png_ptr->zstream, window_bits);
+#endif
+
+         if (ret == Z_OK)
+            png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED;
+      }
+
+      if (ret == Z_OK)
+         png_ptr->zowner = owner;
+
+      else
+         png_zstream_error(png_ptr, ret);
+
+      return ret;
+   }
+
+#ifdef window_bits
+# undef window_bits
+#endif
+}
+
+#ifdef PNG_READ_COMPRESSED_TEXT_SUPPORTED
+/* png_inflate now returns zlib error codes including Z_OK and Z_STREAM_END to
+ * allow the caller to do multiple calls if required.  If the 'finish' flag is
+ * set Z_FINISH will be passed to the final inflate() call and Z_STREAM_END must
+ * be returned or there has been a problem, otherwise Z_SYNC_FLUSH is used and
+ * Z_OK or Z_STREAM_END will be returned on success.
+ *
+ * The input and output sizes are updated to the actual amounts of data consumed
+ * or written, not the amount available (as in a z_stream).  The data pointers
+ * are not changed, so the next input is (data+input_size) and the next
+ * available output is (output+output_size).
+ */
+static int
+png_inflate(png_structrp png_ptr, png_uint_32 owner, int finish,
+    /* INPUT: */ png_const_bytep input, png_uint_32p input_size_ptr,
+    /* OUTPUT: */ png_bytep output, png_alloc_size_t *output_size_ptr)
+{
+   if (png_ptr->zowner == owner) /* Else not claimed */
+   {
+      int ret;
+      png_alloc_size_t avail_out = *output_size_ptr;
+      png_uint_32 avail_in = *input_size_ptr;
+
+      /* zlib can't necessarily handle more than 65535 bytes at once (i.e. it
+       * can't even necessarily handle 65536 bytes) because the type uInt is
+       * "16 bits or more".  Consequently it is necessary to chunk the input to
+       * zlib.  This code uses ZLIB_IO_MAX, from pngpriv.h, as the maximum (the
+       * maximum value that can be stored in a uInt.)  It is possible to set
+       * ZLIB_IO_MAX to a lower value in pngpriv.h and this may sometimes have
+       * a performance advantage, because it reduces the amount of data accessed
+       * at each step and that may give the OS more time to page it in.
+       */
+      png_ptr->zstream.next_in = PNGZ_INPUT_CAST(input);
+      /* avail_in and avail_out are set below from 'size' */
+      png_ptr->zstream.avail_in = 0;
+      png_ptr->zstream.avail_out = 0;
+
+      /* Read directly into the output if it is available (this is set to
+       * a local buffer below if output is NULL).
+       */
+      if (output != NULL)
+         png_ptr->zstream.next_out = output;
+
+      do
+      {
+         uInt avail;
+         Byte local_buffer[PNG_INFLATE_BUF_SIZE];
+
+         /* zlib INPUT BUFFER */
+         /* The setting of 'avail_in' used to be outside the loop; by setting it
+          * inside it is possible to chunk the input to zlib and simply rely on
+          * zlib to advance the 'next_in' pointer.  This allows arbitrary
+          * amounts of data to be passed through zlib at the unavoidable cost of
+          * requiring a window save (memcpy of up to 32768 output bytes)
+          * every ZLIB_IO_MAX input bytes.
+          */
+         avail_in += png_ptr->zstream.avail_in; /* not consumed last time */
+
+         avail = ZLIB_IO_MAX;
+
+         if (avail_in < avail)
+            avail = (uInt)avail_in; /* safe: < than ZLIB_IO_MAX */
+
+         avail_in -= avail;
+         png_ptr->zstream.avail_in = avail;
+
+         /* zlib OUTPUT BUFFER */
+         avail_out += png_ptr->zstream.avail_out; /* not written last time */
+
+         avail = ZLIB_IO_MAX; /* maximum zlib can process */
+
+         if (output == NULL)
+         {
+            /* Reset the output buffer each time round if output is NULL and
+             * make available the full buffer, up to 'remaining_space'
+             */
+            png_ptr->zstream.next_out = local_buffer;
+            if ((sizeof local_buffer) < avail)
+               avail = (sizeof local_buffer);
+         }
+
+         if (avail_out < avail)
+            avail = (uInt)avail_out; /* safe: < ZLIB_IO_MAX */
+
+         png_ptr->zstream.avail_out = avail;
+         avail_out -= avail;
+
+         /* zlib inflate call */
+         /* In fact 'avail_out' may be 0 at this point, that happens at the end
+          * of the read when the final LZ end code was not passed at the end of
+          * the previous chunk of input data.  Tell zlib if we have reached the
+          * end of the output buffer.
+          */
+         ret = inflate(&png_ptr->zstream, avail_out > 0 ? Z_NO_FLUSH :
+             (finish ? Z_FINISH : Z_SYNC_FLUSH));
+      } while (ret == Z_OK);
+
+      /* For safety kill the local buffer pointer now */
+      if (output == NULL)
+         png_ptr->zstream.next_out = NULL;
+
+      /* Claw back the 'size' and 'remaining_space' byte counts. */
+      avail_in += png_ptr->zstream.avail_in;
+      avail_out += png_ptr->zstream.avail_out;
+
+      /* Update the input and output sizes; the updated values are the amount
+       * consumed or written, effectively the inverse of what zlib uses.
+       */
+      if (avail_out > 0)
+         *output_size_ptr -= avail_out;
+
+      if (avail_in > 0)
+         *input_size_ptr -= avail_in;
+
+      /* Ensure png_ptr->zstream.msg is set (even in the success case!) */
+      png_zstream_error(png_ptr, ret);
+      return ret;
+   }
+
+   else
+   {
+      /* This is a bad internal error.  The recovery assigns to the zstream msg
+       * pointer, which is not owned by the caller, but this is safe; it's only
+       * used on errors!
+       */
+      png_ptr->zstream.msg = PNGZ_MSG_CAST("zstream unclaimed");
+      return Z_STREAM_ERROR;
+   }
+}
+
+/*
+ * Decompress trailing data in a chunk.  The assumption is that read_buffer
+ * points at an allocated area holding the contents of a chunk with a
+ * trailing compressed part.  What we get back is an allocated area
+ * holding the original prefix part and an uncompressed version of the
+ * trailing part (the malloc area passed in is freed).
+ */
+static int
+png_decompress_chunk(png_structrp png_ptr,
+   png_uint_32 chunklength, png_uint_32 prefix_size,
+   png_alloc_size_t *newlength /* must be initialized to the maximum! */,
+   int terminate /*add a '\0' to the end of the uncompressed data*/)
+{
+   /* TODO: implement different limits for different types of chunk.
+    *
+    * The caller supplies *newlength set to the maximum length of the
+    * uncompressed data, but this routine allocates space for the prefix and
+    * maybe a '\0' terminator too.  We have to assume that 'prefix_size' is
+    * limited only by the maximum chunk size.
+    */
+   png_alloc_size_t limit = PNG_SIZE_MAX;
+
+# ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED
+   if (png_ptr->user_chunk_malloc_max > 0 &&
+       png_ptr->user_chunk_malloc_max < limit)
+      limit = png_ptr->user_chunk_malloc_max;
+# elif PNG_USER_CHUNK_MALLOC_MAX > 0
+   if (PNG_USER_CHUNK_MALLOC_MAX < limit)
+      limit = PNG_USER_CHUNK_MALLOC_MAX;
+# endif
+
+   if (limit >= prefix_size + (terminate != 0))
+   {
+      int ret;
+
+      limit -= prefix_size + (terminate != 0);
+
+      if (limit < *newlength)
+         *newlength = limit;
+
+      /* Now try to claim the stream. */
+      ret = png_inflate_claim(png_ptr, png_ptr->chunk_name);
+
+      if (ret == Z_OK)
+      {
+         png_uint_32 lzsize = chunklength - prefix_size;
+
+         ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/,
+            /* input: */ png_ptr->read_buffer + prefix_size, &lzsize,
+            /* output: */ NULL, newlength);
+
+         if (ret == Z_STREAM_END)
+         {
+            /* Use 'inflateReset' here, not 'inflateReset2' because this
+             * preserves the previously decided window size (otherwise it would
+             * be necessary to store the previous window size.)  In practice
+             * this doesn't matter anyway, because png_inflate will call inflate
+             * with Z_FINISH in almost all cases, so the window will not be
+             * maintained.
+             */
+            if (inflateReset(&png_ptr->zstream) == Z_OK)
+            {
+               /* Because of the limit checks above we know that the new,
+                * expanded, size will fit in a size_t (let alone an
+                * png_alloc_size_t).  Use png_malloc_base here to avoid an
+                * extra OOM message.
+                */
+               png_alloc_size_t new_size = *newlength;
+               png_alloc_size_t buffer_size = prefix_size + new_size +
+                  (terminate != 0);
+               png_bytep text = png_voidcast(png_bytep, png_malloc_base(png_ptr,
+                  buffer_size));
+
+               if (text != NULL)
+               {
+                  ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/,
+                     png_ptr->read_buffer + prefix_size, &lzsize,
+                     text + prefix_size, newlength);
+
+                  if (ret == Z_STREAM_END)
+                  {
+                     if (new_size == *newlength)
+                     {
+                        if (terminate != 0)
+                           text[prefix_size + *newlength] = 0;
+
+                        if (prefix_size > 0)
+                           memcpy(text, png_ptr->read_buffer, prefix_size);
+
+                        {
+                           png_bytep old_ptr = png_ptr->read_buffer;
+
+                           png_ptr->read_buffer = text;
+                           png_ptr->read_buffer_size = buffer_size;
+                           text = old_ptr; /* freed below */
+                        }
+                     }
+
+                     else
+                     {
+                        /* The size changed on the second read, there can be no
+                         * guarantee that anything is correct at this point.
+                         * The 'msg' pointer has been set to "unexpected end of
+                         * LZ stream", which is fine, but return an error code
+                         * that the caller won't accept.
+                         */
+                        ret = PNG_UNEXPECTED_ZLIB_RETURN;
+                     }
+                  }
+
+                  else if (ret == Z_OK)
+                     ret = PNG_UNEXPECTED_ZLIB_RETURN; /* for safety */
+
+                  /* Free the text pointer (this is the old read_buffer on
+                   * success)
+                   */
+                  png_free(png_ptr, text);
+                  text = NULL;
+
+                  /* This really is very benign, but it's still an error because
+                   * the extra space may otherwise be used as a Trojan Horse.
+                   */
+                  if (ret == Z_STREAM_END &&
+                     chunklength - prefix_size != lzsize)
+                     png_chunk_benign_error(png_ptr, "extra compressed data");
+               }
+
+               else
+               {
+                  /* Out of memory allocating the buffer */
+                  ret = Z_MEM_ERROR;
+                  png_zstream_error(png_ptr, Z_MEM_ERROR);
+               }
+            }
+
+            else
+            {
+               /* inflateReset failed, store the error message */
+               png_zstream_error(png_ptr, ret);
+
+               if (ret == Z_STREAM_END)
+                  ret = PNG_UNEXPECTED_ZLIB_RETURN;
+            }
+         }
+
+         else if (ret == Z_OK)
+            ret = PNG_UNEXPECTED_ZLIB_RETURN;
+
+         /* Release the claimed stream */
+         png_ptr->zowner = 0;
+      }
+
+      else /* the claim failed */ if (ret == Z_STREAM_END) /* impossible! */
+         ret = PNG_UNEXPECTED_ZLIB_RETURN;
+
+      return ret;
+   }
+
+   else
+   {
+      /* Application/configuration limits exceeded */
+      png_zstream_error(png_ptr, Z_MEM_ERROR);
+      return Z_MEM_ERROR;
+   }
+}
+#endif /* READ_COMPRESSED_TEXT */
+
+#ifdef PNG_READ_iCCP_SUPPORTED
+/* Perform a partial read and decompress, producing 'avail_out' bytes and
+ * reading from the current chunk as required.
+ */
+static int
+png_inflate_read(png_structrp png_ptr, png_bytep read_buffer, uInt read_size,
+   png_uint_32p chunk_bytes, png_bytep next_out, png_alloc_size_t *out_size,
+   int finish)
+{
+   if (png_ptr->zowner == png_ptr->chunk_name)
+   {
+      int ret;
+
+      /* next_in and avail_in must have been initialized by the caller. */
+      png_ptr->zstream.next_out = next_out;
+      png_ptr->zstream.avail_out = 0; /* set in the loop */
+
+      do
+      {
+         if (png_ptr->zstream.avail_in == 0)
+         {
+            if (read_size > *chunk_bytes)
+               read_size = (uInt)*chunk_bytes;
+            *chunk_bytes -= read_size;
+
+            if (read_size > 0)
+               png_crc_read(png_ptr, read_buffer, read_size);
+
+            png_ptr->zstream.next_in = read_buffer;
+            png_ptr->zstream.avail_in = read_size;
+         }
+
+         if (png_ptr->zstream.avail_out == 0)
+         {
+            uInt avail = ZLIB_IO_MAX;
+            if (avail > *out_size)
+               avail = (uInt)*out_size;
+            *out_size -= avail;
+
+            png_ptr->zstream.avail_out = avail;
+         }
+
+         /* Use Z_SYNC_FLUSH when there is no more chunk data to ensure that all
+          * the available output is produced; this allows reading of truncated
+          * streams.
+          */
+         ret = inflate(&png_ptr->zstream,
+            *chunk_bytes > 0 ? Z_NO_FLUSH : (finish ? Z_FINISH : Z_SYNC_FLUSH));
+      }
+      while (ret == Z_OK && (*out_size > 0 || png_ptr->zstream.avail_out > 0));
+
+      *out_size += png_ptr->zstream.avail_out;
+      png_ptr->zstream.avail_out = 0; /* Should not be required, but is safe */
+
+      /* Ensure the error message pointer is always set: */
+      png_zstream_error(png_ptr, ret);
+      return ret;
+   }
+
+   else
+   {
+      png_ptr->zstream.msg = PNGZ_MSG_CAST("zstream unclaimed");
+      return Z_STREAM_ERROR;
+   }
+}
+#endif
+
+/* Read and check the IDHR chunk */
+
+void /* PRIVATE */
+png_handle_IHDR(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+   png_byte buf[13];
+   png_uint_32 width, height;
+   int bit_depth, color_type, compression_type, filter_type;
+   int interlace_type;
+
+   png_debug(1, "in png_handle_IHDR");
+
+   if ((png_ptr->mode & PNG_HAVE_IHDR) != 0)
+      png_chunk_error(png_ptr, "out of place");
+
+   /* Check the length */
+   if (length != 13)
+      png_chunk_error(png_ptr, "invalid");
+
+   png_ptr->mode |= PNG_HAVE_IHDR;
+
+   png_crc_read(png_ptr, buf, 13);
+   png_crc_finish(png_ptr, 0);
+
+   width = png_get_uint_31(png_ptr, buf);
+   height = png_get_uint_31(png_ptr, buf + 4);
+   bit_depth = buf[8];
+   color_type = buf[9];
+   compression_type = buf[10];
+   filter_type = buf[11];
+   interlace_type = buf[12];
+
+   /* Set internal variables */
+   png_ptr->width = width;
+   png_ptr->height = height;
+   png_ptr->bit_depth = (png_byte)bit_depth;
+   png_ptr->interlaced = (png_byte)interlace_type;
+   png_ptr->color_type = (png_byte)color_type;
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+   png_ptr->filter_type = (png_byte)filter_type;
+#endif
+   png_ptr->compression_type = (png_byte)compression_type;
+
+   /* Find number of channels */
+   switch (png_ptr->color_type)
+   {
+      default: /* invalid, png_set_IHDR calls png_error */
+      case PNG_COLOR_TYPE_GRAY:
+      case PNG_COLOR_TYPE_PALETTE:
+         png_ptr->channels = 1;
+         break;
+
+      case PNG_COLOR_TYPE_RGB:
+         png_ptr->channels = 3;
+         break;
+
+      case PNG_COLOR_TYPE_GRAY_ALPHA:
+         png_ptr->channels = 2;
+         break;
+
+      case PNG_COLOR_TYPE_RGB_ALPHA:
+         png_ptr->channels = 4;
+         break;
+   }
+
+   /* Set up other useful info */
+   png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth * png_ptr->channels);
+   png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width);
+   png_debug1(3, "bit_depth = %d", png_ptr->bit_depth);
+   png_debug1(3, "channels = %d", png_ptr->channels);
+   png_debug1(3, "rowbytes = %lu", (unsigned long)png_ptr->rowbytes);
+   png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
+       color_type, interlace_type, compression_type, filter_type);
+}
+
+/* Read and check the palette */
+void /* PRIVATE */
+png_handle_PLTE(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+   png_color palette[PNG_MAX_PALETTE_LENGTH];
+   int num, i;
+#ifdef PNG_POINTER_INDEXING_SUPPORTED
+   png_colorp pal_ptr;
+#endif
+
+   png_debug(1, "in png_handle_PLTE");
+
+   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+      png_chunk_error(png_ptr, "missing IHDR");
+
+   /* Moved to before the 'after IDAT' check below because otherwise duplicate
+    * PLTE chunks are potentially ignored (the spec says there shall not be more
+    * than one PLTE, the error is not treated as benign, so this check trumps
+    * the requirement that PLTE appears before IDAT.)
+    */
+   else if ((png_ptr->mode & PNG_HAVE_PLTE) != 0)
+      png_chunk_error(png_ptr, "duplicate");
+
+   else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
+   {
+      /* This is benign because the non-benign error happened before, when an
+       * IDAT was encountered in a color-mapped image with no PLTE.
+       */
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "out of place");
+      return;
+   }
+
+   png_ptr->mode |= PNG_HAVE_PLTE;
+
+   if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "ignored in grayscale PNG");
+      return;
+   }
+
+#ifndef PNG_READ_OPT_PLTE_SUPPORTED
+   if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
+   {
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+#endif
+
+   if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
+   {
+      png_crc_finish(png_ptr, length);
+
+      if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
+         png_chunk_benign_error(png_ptr, "invalid");
+
+      else
+         png_chunk_error(png_ptr, "invalid");
+
+      return;
+   }
+
+   /* The cast is safe because 'length' is less than 3*PNG_MAX_PALETTE_LENGTH */
+   num = (int)length / 3;
+
+#ifdef PNG_POINTER_INDEXING_SUPPORTED
+   for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
+   {
+      png_byte buf[3];
+
+      png_crc_read(png_ptr, buf, 3);
+      pal_ptr->red = buf[0];
+      pal_ptr->green = buf[1];
+      pal_ptr->blue = buf[2];
+   }
+#else
+   for (i = 0; i < num; i++)
+   {
+      png_byte buf[3];
+
+      png_crc_read(png_ptr, buf, 3);
+      /* Don't depend upon png_color being any order */
+      palette[i].red = buf[0];
+      palette[i].green = buf[1];
+      palette[i].blue = buf[2];
+   }
+#endif
+
+   /* If we actually need the PLTE chunk (ie for a paletted image), we do
+    * whatever the normal CRC configuration tells us.  However, if we
+    * have an RGB image, the PLTE can be considered ancillary, so
+    * we will act as though it is.
+    */
+#ifndef PNG_READ_OPT_PLTE_SUPPORTED
+   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+#endif
+   {
+      png_crc_finish(png_ptr, 0);
+   }
+
+#ifndef PNG_READ_OPT_PLTE_SUPPORTED
+   else if (png_crc_error(png_ptr) != 0)  /* Only if we have a CRC error */
+   {
+      /* If we don't want to use the data from an ancillary chunk,
+       * we have two options: an error abort, or a warning and we
+       * ignore the data in this chunk (which should be OK, since
+       * it's considered ancillary for a RGB or RGBA image).
+       *
+       * IMPLEMENTATION NOTE: this is only here because png_crc_finish uses the
+       * chunk type to determine whether to check the ancillary or the critical
+       * flags.
+       */
+      if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE) == 0)
+      {
+         if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) != 0)
+            return;
+
+         else
+            png_chunk_error(png_ptr, "CRC error");
+      }
+
+      /* Otherwise, we (optionally) emit a warning and use the chunk. */
+      else if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) == 0)
+         png_chunk_warning(png_ptr, "CRC error");
+   }
+#endif
+
+   /* TODO: png_set_PLTE has the side effect of setting png_ptr->palette to its
+    * own copy of the palette.  This has the side effect that when png_start_row
+    * is called (this happens after any call to png_read_update_info) the
+    * info_ptr palette gets changed.  This is extremely unexpected and
+    * confusing.
+    *
+    * Fix this by not sharing the palette in this way.
+    */
+   png_set_PLTE(png_ptr, info_ptr, palette, num);
+
+   /* The three chunks, bKGD, hIST and tRNS *must* appear after PLTE and before
+    * IDAT.  Prior to 1.6.0 this was not checked; instead the code merely
+    * checked the apparent validity of a tRNS chunk inserted before PLTE on a
+    * palette PNG.  1.6.0 attempts to rigorously follow the standard and
+    * therefore does a benign error if the erroneous condition is detected *and*
+    * cancels the tRNS if the benign error returns.  The alternative is to
+    * amend the standard since it would be rather hypocritical of the standards
+    * maintainers to ignore it.
+    */
+#ifdef PNG_READ_tRNS_SUPPORTED
+   if (png_ptr->num_trans > 0 ||
+       (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS) != 0))
+   {
+      /* Cancel this because otherwise it would be used if the transforms
+       * require it.  Don't cancel the 'valid' flag because this would prevent
+       * detection of duplicate chunks.
+       */
+      png_ptr->num_trans = 0;
+
+      if (info_ptr != NULL)
+         info_ptr->num_trans = 0;
+
+      png_chunk_benign_error(png_ptr, "tRNS must be after");
+   }
+#endif
+
+#ifdef PNG_READ_hIST_SUPPORTED
+   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST) != 0)
+      png_chunk_benign_error(png_ptr, "hIST must be after");
+#endif
+
+#ifdef PNG_READ_bKGD_SUPPORTED
+   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD) != 0)
+      png_chunk_benign_error(png_ptr, "bKGD must be after");
+#endif
+}
+
+void /* PRIVATE */
+png_handle_IEND(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+   png_debug(1, "in png_handle_IEND");
+
+   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0 ||
+       (png_ptr->mode & PNG_HAVE_IDAT) == 0)
+      png_chunk_error(png_ptr, "out of place");
+
+   png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
+
+   png_crc_finish(png_ptr, length);
+
+   if (length != 0)
+      png_chunk_benign_error(png_ptr, "invalid");
+
+   PNG_UNUSED(info_ptr)
+}
+
+#ifdef PNG_READ_gAMA_SUPPORTED
+void /* PRIVATE */
+png_handle_gAMA(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+   png_fixed_point igamma;
+   png_byte buf[4];
+
+   png_debug(1, "in png_handle_gAMA");
+
+   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+      png_chunk_error(png_ptr, "missing IHDR");
+
+   else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "out of place");
+      return;
+   }
+
+   if (length != 4)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "invalid");
+      return;
+   }
+
+   png_crc_read(png_ptr, buf, 4);
+
+   if (png_crc_finish(png_ptr, 0) != 0)
+      return;
+
+   igamma = png_get_fixed_point(NULL, buf);
+
+   png_colorspace_set_gamma(png_ptr, &png_ptr->colorspace, igamma);
+   png_colorspace_sync(png_ptr, info_ptr);
+}
+#endif
+
+#ifdef PNG_READ_sBIT_SUPPORTED
+void /* PRIVATE */
+png_handle_sBIT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+   unsigned int truelen, i;
+   png_byte sample_depth;
+   png_byte buf[4];
+
+   png_debug(1, "in png_handle_sBIT");
+
+   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+      png_chunk_error(png_ptr, "missing IHDR");
+
+   else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "out of place");
+      return;
+   }
+
+   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT) != 0)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "duplicate");
+      return;
+   }
+
+   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+   {
+      truelen = 3;
+      sample_depth = 8;
+   }
+
+   else
+   {
+      truelen = png_ptr->channels;
+      sample_depth = png_ptr->bit_depth;
+   }
+
+   if (length != truelen || length > 4)
+   {
+      png_chunk_benign_error(png_ptr, "invalid");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   buf[0] = buf[1] = buf[2] = buf[3] = sample_depth;
+   png_crc_read(png_ptr, buf, truelen);
+
+   if (png_crc_finish(png_ptr, 0) != 0)
+      return;
+
+   for (i=0; i<truelen; ++i)
+      if (buf[i] == 0 || buf[i] > sample_depth)
+      {
+         png_chunk_benign_error(png_ptr, "invalid");
+         return;
+      }
+
+   if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
+   {
+      png_ptr->sig_bit.red = buf[0];
+      png_ptr->sig_bit.green = buf[1];
+      png_ptr->sig_bit.blue = buf[2];
+      png_ptr->sig_bit.alpha = buf[3];
+   }
+
+   else
+   {
+      png_ptr->sig_bit.gray = buf[0];
+      png_ptr->sig_bit.red = buf[0];
+      png_ptr->sig_bit.green = buf[0];
+      png_ptr->sig_bit.blue = buf[0];
+      png_ptr->sig_bit.alpha = buf[1];
+   }
+
+   png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
+}
+#endif
+
+#ifdef PNG_READ_cHRM_SUPPORTED
+void /* PRIVATE */
+png_handle_cHRM(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+   png_byte buf[32];
+   png_xy xy;
+
+   png_debug(1, "in png_handle_cHRM");
+
+   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+      png_chunk_error(png_ptr, "missing IHDR");
+
+   else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "out of place");
+      return;
+   }
+
+   if (length != 32)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "invalid");
+      return;
+   }
+
+   png_crc_read(png_ptr, buf, 32);
+
+   if (png_crc_finish(png_ptr, 0) != 0)
+      return;
+
+   xy.whitex = png_get_fixed_point(NULL, buf);
+   xy.whitey = png_get_fixed_point(NULL, buf + 4);
+   xy.redx   = png_get_fixed_point(NULL, buf + 8);
+   xy.redy   = png_get_fixed_point(NULL, buf + 12);
+   xy.greenx = png_get_fixed_point(NULL, buf + 16);
+   xy.greeny = png_get_fixed_point(NULL, buf + 20);
+   xy.bluex  = png_get_fixed_point(NULL, buf + 24);
+   xy.bluey  = png_get_fixed_point(NULL, buf + 28);
+
+   if (xy.whitex == PNG_FIXED_ERROR ||
+       xy.whitey == PNG_FIXED_ERROR ||
+       xy.redx   == PNG_FIXED_ERROR ||
+       xy.redy   == PNG_FIXED_ERROR ||
+       xy.greenx == PNG_FIXED_ERROR ||
+       xy.greeny == PNG_FIXED_ERROR ||
+       xy.bluex  == PNG_FIXED_ERROR ||
+       xy.bluey  == PNG_FIXED_ERROR)
+   {
+      png_chunk_benign_error(png_ptr, "invalid values");
+      return;
+   }
+
+   /* If a colorspace error has already been output skip this chunk */
+   if ((png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0)
+      return;
+
+   if ((png_ptr->colorspace.flags & PNG_COLORSPACE_FROM_cHRM) != 0)
+   {
+      png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID;
+      png_colorspace_sync(png_ptr, info_ptr);
+      png_chunk_benign_error(png_ptr, "duplicate");
+      return;
+   }
+
+   png_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM;
+   (void)png_colorspace_set_chromaticities(png_ptr, &png_ptr->colorspace, &xy,
+      1/*prefer cHRM values*/);
+   png_colorspace_sync(png_ptr, info_ptr);
+}
+#endif
+
+#ifdef PNG_READ_sRGB_SUPPORTED
+void /* PRIVATE */
+png_handle_sRGB(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+   png_byte intent;
+
+   png_debug(1, "in png_handle_sRGB");
+
+   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+      png_chunk_error(png_ptr, "missing IHDR");
+
+   else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "out of place");
+      return;
+   }
+
+   if (length != 1)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "invalid");
+      return;
+   }
+
+   png_crc_read(png_ptr, &intent, 1);
+
+   if (png_crc_finish(png_ptr, 0) != 0)
+      return;
+
+   /* If a colorspace error has already been output skip this chunk */
+   if ((png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0)
+      return;
+
+   /* Only one sRGB or iCCP chunk is allowed, use the HAVE_INTENT flag to detect
+    * this.
+    */
+   if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_INTENT) != 0)
+   {
+      png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID;
+      png_colorspace_sync(png_ptr, info_ptr);
+      png_chunk_benign_error(png_ptr, "too many profiles");
+      return;
+   }
+
+   (void)png_colorspace_set_sRGB(png_ptr, &png_ptr->colorspace, intent);
+   png_colorspace_sync(png_ptr, info_ptr);
+}
+#endif /* READ_sRGB */
+
+#ifdef PNG_READ_iCCP_SUPPORTED
+void /* PRIVATE */
+png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+/* Note: this does not properly handle profiles that are > 64K under DOS */
+{
+   png_const_charp errmsg = NULL; /* error message output, or no error */
+   int finished = 0; /* crc checked */
+
+   png_debug(1, "in png_handle_iCCP");
+
+   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+      png_chunk_error(png_ptr, "missing IHDR");
+
+   else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "out of place");
+      return;
+   }
+
+   /* Consistent with all the above colorspace handling an obviously *invalid*
+    * chunk is just ignored, so does not invalidate the color space.  An
+    * alternative is to set the 'invalid' flags at the start of this routine
+    * and only clear them in they were not set before and all the tests pass.
+    * The minimum 'deflate' stream is assumed to be just the 2 byte header and
+    * 4 byte checksum.  The keyword must be at least one character and there is
+    * a terminator (0) byte and the compression method.
+    */
+   if (length < 9)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "too short");
+      return;
+   }
+
+   /* If a colorspace error has already been output skip this chunk */
+   if ((png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0)
+   {
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   /* Only one sRGB or iCCP chunk is allowed, use the HAVE_INTENT flag to detect
+    * this.
+    */
+   if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_INTENT) == 0)
+   {
+      uInt read_length, keyword_length;
+      char keyword[81];
+
+      /* Find the keyword; the keyword plus separator and compression method
+       * bytes can be at most 81 characters long.
+       */
+      read_length = 81; /* maximum */
+      if (read_length > length)
+         read_length = (uInt)length;
+
+      png_crc_read(png_ptr, (png_bytep)keyword, read_length);
+      length -= read_length;
+
+      keyword_length = 0;
+      while (keyword_length < 80 && keyword_length < read_length &&
+         keyword[keyword_length] != 0)
+         ++keyword_length;
+
+      /* TODO: make the keyword checking common */
+      if (keyword_length >= 1 && keyword_length <= 79)
+      {
+         /* We only understand '0' compression - deflate - so if we get a
+          * different value we can't safely decode the chunk.
+          */
+         if (keyword_length+1 < read_length &&
+            keyword[keyword_length+1] == PNG_COMPRESSION_TYPE_BASE)
+         {
+            read_length -= keyword_length+2;
+
+            if (png_inflate_claim(png_ptr, png_iCCP) == Z_OK)
+            {
+               Byte profile_header[132];
+               Byte local_buffer[PNG_INFLATE_BUF_SIZE];
+               png_alloc_size_t size = (sizeof profile_header);
+
+               png_ptr->zstream.next_in = (Bytef*)keyword + (keyword_length+2);
+               png_ptr->zstream.avail_in = read_length;
+               (void)png_inflate_read(png_ptr, local_buffer,
+                  (sizeof local_buffer), &length, profile_header, &size,
+                  0/*finish: don't, because the output is too small*/);
+
+               if (size == 0)
+               {
+                  /* We have the ICC profile header; do the basic header checks.
+                   */
+                  const png_uint_32 profile_length =
+                     png_get_uint_32(profile_header);
+
+                  if (png_icc_check_length(png_ptr, &png_ptr->colorspace,
+                     keyword, profile_length) != 0)
+                  {
+                     /* The length is apparently ok, so we can check the 132
+                      * byte header.
+                      */
+                     if (png_icc_check_header(png_ptr, &png_ptr->colorspace,
+                        keyword, profile_length, profile_header,
+                        png_ptr->color_type) != 0)
+                     {
+                        /* Now read the tag table; a variable size buffer is
+                         * needed at this point, allocate one for the whole
+                         * profile.  The header check has already validated
+                         * that none of these stuff will overflow.
+                         */
+                        const png_uint_32 tag_count = png_get_uint_32(
+                           profile_header+128);
+                        png_bytep profile = png_read_buffer(png_ptr,
+                           profile_length, 2/*silent*/);
+
+                        if (profile != NULL)
+                        {
+                           memcpy(profile, profile_header,
+                              (sizeof profile_header));
+
+                           size = 12 * tag_count;
+
+                           (void)png_inflate_read(png_ptr, local_buffer,
+                              (sizeof local_buffer), &length,
+                              profile + (sizeof profile_header), &size, 0);
+
+                           /* Still expect a buffer error because we expect
+                            * there to be some tag data!
+                            */
+                           if (size == 0)
+                           {
+                              if (png_icc_check_tag_table(png_ptr,
+                                 &png_ptr->colorspace, keyword, profile_length,
+                                 profile) != 0)
+                              {
+                                 /* The profile has been validated for basic
+                                  * security issues, so read the whole thing in.
+                                  */
+                                 size = profile_length - (sizeof profile_header)
+                                    - 12 * tag_count;
+
+                                 (void)png_inflate_read(png_ptr, local_buffer,
+                                    (sizeof local_buffer), &length,
+                                    profile + (sizeof profile_header) +
+                                    12 * tag_count, &size, 1/*finish*/);
+
+                                 if (length > 0 && !(png_ptr->flags &
+                                       PNG_FLAG_BENIGN_ERRORS_WARN))
+                                    errmsg = "extra compressed data";
+
+                                 /* But otherwise allow extra data: */
+                                 else if (size == 0)
+                                 {
+                                    if (length > 0)
+                                    {
+                                       /* This can be handled completely, so
+                                        * keep going.
+                                        */
+                                       png_chunk_warning(png_ptr,
+                                          "extra compressed data");
+                                    }
+
+                                    png_crc_finish(png_ptr, length);
+                                    finished = 1;
+
+#                                   ifdef PNG_sRGB_SUPPORTED
+                                       /* Check for a match against sRGB */
+                                       png_icc_set_sRGB(png_ptr,
+                                          &png_ptr->colorspace, profile,
+                                          png_ptr->zstream.adler);
+#                                   endif
+
+                                    /* Steal the profile for info_ptr. */
+                                    if (info_ptr != NULL)
+                                    {
+                                       png_free_data(png_ptr, info_ptr,
+                                          PNG_FREE_ICCP, 0);
+
+                                       info_ptr->iccp_name = png_voidcast(char*,
+                                          png_malloc_base(png_ptr,
+                                          keyword_length+1));
+                                       if (info_ptr->iccp_name != NULL)
+                                       {
+                                          memcpy(info_ptr->iccp_name, keyword,
+                                             keyword_length+1);
+                                          info_ptr->iccp_proflen =
+                                             profile_length;
+                                          info_ptr->iccp_profile = profile;
+                                          png_ptr->read_buffer = NULL; /*steal*/
+                                          info_ptr->free_me |= PNG_FREE_ICCP;
+                                          info_ptr->valid |= PNG_INFO_iCCP;
+                                       }
+
+                                       else
+                                       {
+                                          png_ptr->colorspace.flags |=
+                                             PNG_COLORSPACE_INVALID;
+                                          errmsg = "out of memory";
+                                       }
+                                    }
+
+                                    /* else the profile remains in the read
+                                     * buffer which gets reused for subsequent
+                                     * chunks.
+                                     */
+
+                                    if (info_ptr != NULL)
+                                       png_colorspace_sync(png_ptr, info_ptr);
+
+                                    if (errmsg == NULL)
+                                    {
+                                       png_ptr->zowner = 0;
+                                       return;
+                                    }
+                                 }
+
+                                 else if (size > 0)
+                                    errmsg = "truncated";
+
+                                 else
+                                    errmsg = png_ptr->zstream.msg;
+                              }
+
+                              /* else png_icc_check_tag_table output an error */
+                           }
+
+                           else /* profile truncated */
+                              errmsg = png_ptr->zstream.msg;
+                        }
+
+                        else
+                           errmsg = "out of memory";
+                     }
+
+                     /* else png_icc_check_header output an error */
+                  }
+
+                  /* else png_icc_check_length output an error */
+               }
+
+               else /* profile truncated */
+                  errmsg = png_ptr->zstream.msg;
+
+               /* Release the stream */
+               png_ptr->zowner = 0;
+            }
+
+            else /* png_inflate_claim failed */
+               errmsg = png_ptr->zstream.msg;
+         }
+
+         else
+            errmsg = "bad compression method"; /* or missing */
+      }
+
+      else
+         errmsg = "bad keyword";
+   }
+
+   else
+      errmsg = "too many profiles";
+
+   /* Failure: the reason is in 'errmsg' */
+   if (finished == 0)
+      png_crc_finish(png_ptr, length);
+
+   png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID;
+   png_colorspace_sync(png_ptr, info_ptr);
+   if (errmsg != NULL) /* else already output */
+      png_chunk_benign_error(png_ptr, errmsg);
+}
+#endif /* READ_iCCP */
+
+#ifdef PNG_READ_sPLT_SUPPORTED
+void /* PRIVATE */
+png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+/* Note: this does not properly handle chunks that are > 64K under DOS */
+{
+   png_bytep entry_start, buffer;
+   png_sPLT_t new_palette;
+   png_sPLT_entryp pp;
+   png_uint_32 data_length;
+   int entry_size, i;
+   png_uint_32 skip = 0;
+   png_uint_32 dl;
+   png_size_t max_dl;
+
+   png_debug(1, "in png_handle_sPLT");
+
+#ifdef PNG_USER_LIMITS_SUPPORTED
+   if (png_ptr->user_chunk_cache_max != 0)
+   {
+      if (png_ptr->user_chunk_cache_max == 1)
+      {
+         png_crc_finish(png_ptr, length);
+         return;
+      }
+
+      if (--png_ptr->user_chunk_cache_max == 1)
+      {
+         png_warning(png_ptr, "No space in chunk cache for sPLT");
+         png_crc_finish(png_ptr, length);
+         return;
+      }
+   }
+#endif
+
+   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+      png_chunk_error(png_ptr, "missing IHDR");
+
+   else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "out of place");
+      return;
+   }
+
+#ifdef PNG_MAX_MALLOC_64K
+   if (length > 65535U)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "too large to fit in memory");
+      return;
+   }
+#endif
+
+   buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/);
+   if (buffer == NULL)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "out of memory");
+      return;
+   }
+
+
+   /* WARNING: this may break if size_t is less than 32 bits; it is assumed
+    * that the PNG_MAX_MALLOC_64K test is enabled in this case, but this is a
+    * potential breakage point if the types in pngconf.h aren't exactly right.
+    */
+   png_crc_read(png_ptr, buffer, length);
+
+   if (png_crc_finish(png_ptr, skip) != 0)
+      return;
+
+   buffer[length] = 0;
+
+   for (entry_start = buffer; *entry_start; entry_start++)
+      /* Empty loop to find end of name */ ;
+
+   ++entry_start;
+
+   /* A sample depth should follow the separator, and we should be on it  */
+   if (entry_start > buffer + length - 2)
+   {
+      png_warning(png_ptr, "malformed sPLT chunk");
+      return;
+   }
+
+   new_palette.depth = *entry_start++;
+   entry_size = (new_palette.depth == 8 ? 6 : 10);
+   /* This must fit in a png_uint_32 because it is derived from the original
+    * chunk data length.
+    */
+   data_length = length - (png_uint_32)(entry_start - buffer);
+
+   /* Integrity-check the data length */
+   if ((data_length % entry_size) != 0)
+   {
+      png_warning(png_ptr, "sPLT chunk has bad length");
+      return;
+   }
+
+   dl = (png_int_32)(data_length / entry_size);
+   max_dl = PNG_SIZE_MAX / (sizeof (png_sPLT_entry));
+
+   if (dl > max_dl)
+   {
+       png_warning(png_ptr, "sPLT chunk too long");
+       return;
+   }
+
+   new_palette.nentries = (png_int_32)(data_length / entry_size);
+
+   new_palette.entries = (png_sPLT_entryp)png_malloc_warn(
+       png_ptr, new_palette.nentries * (sizeof (png_sPLT_entry)));
+
+   if (new_palette.entries == NULL)
+   {
+       png_warning(png_ptr, "sPLT chunk requires too much memory");
+       return;
+   }
+
+#ifdef PNG_POINTER_INDEXING_SUPPORTED
+   for (i = 0; i < new_palette.nentries; i++)
+   {
+      pp = new_palette.entries + i;
+
+      if (new_palette.depth == 8)
+      {
+         pp->red = *entry_start++;
+         pp->green = *entry_start++;
+         pp->blue = *entry_start++;
+         pp->alpha = *entry_start++;
+      }
+
+      else
+      {
+         pp->red   = png_get_uint_16(entry_start); entry_start += 2;
+         pp->green = png_get_uint_16(entry_start); entry_start += 2;
+         pp->blue  = png_get_uint_16(entry_start); entry_start += 2;
+         pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
+      }
+
+      pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
+   }
+#else
+   pp = new_palette.entries;
+
+   for (i = 0; i < new_palette.nentries; i++)
+   {
+
+      if (new_palette.depth == 8)
+      {
+         pp[i].red   = *entry_start++;
+         pp[i].green = *entry_start++;
+         pp[i].blue  = *entry_start++;
+         pp[i].alpha = *entry_start++;
+      }
+
+      else
+      {
+         pp[i].red   = png_get_uint_16(entry_start); entry_start += 2;
+         pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
+         pp[i].blue  = png_get_uint_16(entry_start); entry_start += 2;
+         pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
+      }
+
+      pp[i].frequency = png_get_uint_16(entry_start); entry_start += 2;
+   }
+#endif
+
+   /* Discard all chunk data except the name and stash that */
+   new_palette.name = (png_charp)buffer;
+
+   png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
+
+   png_free(png_ptr, new_palette.entries);
+}
+#endif /* READ_sPLT */
+
+#ifdef PNG_READ_tRNS_SUPPORTED
+void /* PRIVATE */
+png_handle_tRNS(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+   png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
+
+   png_debug(1, "in png_handle_tRNS");
+
+   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+      png_chunk_error(png_ptr, "missing IHDR");
+
+   else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "out of place");
+      return;
+   }
+
+   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS) != 0)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "duplicate");
+      return;
+   }
+
+   if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
+   {
+      png_byte buf[2];
+
+      if (length != 2)
+      {
+         png_crc_finish(png_ptr, length);
+         png_chunk_benign_error(png_ptr, "invalid");
+         return;
+      }
+
+      png_crc_read(png_ptr, buf, 2);
+      png_ptr->num_trans = 1;
+      png_ptr->trans_color.gray = png_get_uint_16(buf);
+   }
+
+   else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
+   {
+      png_byte buf[6];
+
+      if (length != 6)
+      {
+         png_crc_finish(png_ptr, length);
+         png_chunk_benign_error(png_ptr, "invalid");
+         return;
+      }
+
+      png_crc_read(png_ptr, buf, length);
+      png_ptr->num_trans = 1;
+      png_ptr->trans_color.red = png_get_uint_16(buf);
+      png_ptr->trans_color.green = png_get_uint_16(buf + 2);
+      png_ptr->trans_color.blue = png_get_uint_16(buf + 4);
+   }
+
+   else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+   {
+      if ((png_ptr->mode & PNG_HAVE_PLTE) == 0)
+      {
+         /* TODO: is this actually an error in the ISO spec? */
+         png_crc_finish(png_ptr, length);
+         png_chunk_benign_error(png_ptr, "out of place");
+         return;
+      }
+
+      if (length > png_ptr->num_palette || length > PNG_MAX_PALETTE_LENGTH ||
+         length == 0)
+      {
+         png_crc_finish(png_ptr, length);
+         png_chunk_benign_error(png_ptr, "invalid");
+         return;
+      }
+
+      png_crc_read(png_ptr, readbuf, length);
+      png_ptr->num_trans = (png_uint_16)length;
+   }
+
+   else
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "invalid with alpha channel");
+      return;
+   }
+
+   if (png_crc_finish(png_ptr, 0) != 0)
+   {
+      png_ptr->num_trans = 0;
+      return;
+   }
+
+   /* TODO: this is a horrible side effect in the palette case because the
+    * png_struct ends up with a pointer to the tRNS buffer owned by the
+    * png_info.  Fix this.
+    */
+   png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
+       &(png_ptr->trans_color));
+}
+#endif
+
+#ifdef PNG_READ_bKGD_SUPPORTED
+void /* PRIVATE */
+png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+   unsigned int truelen;
+   png_byte buf[6];
+   png_color_16 background;
+
+   png_debug(1, "in png_handle_bKGD");
+
+   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+      png_chunk_error(png_ptr, "missing IHDR");
+
+   else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0 ||
+       (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+       (png_ptr->mode & PNG_HAVE_PLTE) == 0))
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "out of place");
+      return;
+   }
+
+   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD) != 0)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "duplicate");
+      return;
+   }
+
+   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      truelen = 1;
+
+   else if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
+      truelen = 6;
+
+   else
+      truelen = 2;
+
+   if (length != truelen)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "invalid");
+      return;
+   }
+
+   png_crc_read(png_ptr, buf, truelen);
+
+   if (png_crc_finish(png_ptr, 0) != 0)
+      return;
+
+   /* We convert the index value into RGB components so that we can allow
+    * arbitrary RGB values for background when we have transparency, and
+    * so it is easy to determine the RGB values of the background color
+    * from the info_ptr struct.
+    */
+   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+   {
+      background.index = buf[0];
+
+      if (info_ptr != NULL && info_ptr->num_palette != 0)
+      {
+         if (buf[0] >= info_ptr->num_palette)
+         {
+            png_chunk_benign_error(png_ptr, "invalid index");
+            return;
+         }
+
+         background.red = (png_uint_16)png_ptr->palette[buf[0]].red;
+         background.green = (png_uint_16)png_ptr->palette[buf[0]].green;
+         background.blue = (png_uint_16)png_ptr->palette[buf[0]].blue;
+      }
+
+      else
+         background.red = background.green = background.blue = 0;
+
+      background.gray = 0;
+   }
+
+   else if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) /* GRAY */
+   {
+      background.index = 0;
+      background.red =
+      background.green =
+      background.blue =
+      background.gray = png_get_uint_16(buf);
+   }
+
+   else
+   {
+      background.index = 0;
+      background.red = png_get_uint_16(buf);
+      background.green = png_get_uint_16(buf + 2);
+      background.blue = png_get_uint_16(buf + 4);
+      background.gray = 0;
+   }
+
+   png_set_bKGD(png_ptr, info_ptr, &background);
+}
+#endif
+
+#ifdef PNG_READ_hIST_SUPPORTED
+void /* PRIVATE */
+png_handle_hIST(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+   unsigned int num, i;
+   png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];
+
+   png_debug(1, "in png_handle_hIST");
+
+   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+      png_chunk_error(png_ptr, "missing IHDR");
+
+   else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0 ||
+       (png_ptr->mode & PNG_HAVE_PLTE) == 0)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "out of place");
+      return;
+   }
+
+   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST) != 0)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "duplicate");
+      return;
+   }
+
+   num = length / 2 ;
+
+   if (num != png_ptr->num_palette || num > PNG_MAX_PALETTE_LENGTH)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "invalid");
+      return;
+   }
+
+   for (i = 0; i < num; i++)
+   {
+      png_byte buf[2];
+
+      png_crc_read(png_ptr, buf, 2);
+      readbuf[i] = png_get_uint_16(buf);
+   }
+
+   if (png_crc_finish(png_ptr, 0) != 0)
+      return;
+
+   png_set_hIST(png_ptr, info_ptr, readbuf);
+}
+#endif
+
+#ifdef PNG_READ_pHYs_SUPPORTED
+void /* PRIVATE */
+png_handle_pHYs(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+   png_byte buf[9];
+   png_uint_32 res_x, res_y;
+   int unit_type;
+
+   png_debug(1, "in png_handle_pHYs");
+
+   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+      png_chunk_error(png_ptr, "missing IHDR");
+
+   else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "out of place");
+      return;
+   }
+
+   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs) != 0)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "duplicate");
+      return;
+   }
+
+   if (length != 9)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "invalid");
+      return;
+   }
+
+   png_crc_read(png_ptr, buf, 9);
+
+   if (png_crc_finish(png_ptr, 0) != 0)
+      return;
+
+   res_x = png_get_uint_32(buf);
+   res_y = png_get_uint_32(buf + 4);
+   unit_type = buf[8];
+   png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
+}
+#endif
+
+#ifdef PNG_READ_oFFs_SUPPORTED
+void /* PRIVATE */
+png_handle_oFFs(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+   png_byte buf[9];
+   png_int_32 offset_x, offset_y;
+   int unit_type;
+
+   png_debug(1, "in png_handle_oFFs");
+
+   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+      png_chunk_error(png_ptr, "missing IHDR");
+
+   else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "out of place");
+      return;
+   }
+
+   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs) != 0)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "duplicate");
+      return;
+   }
+
+   if (length != 9)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "invalid");
+      return;
+   }
+
+   png_crc_read(png_ptr, buf, 9);
+
+   if (png_crc_finish(png_ptr, 0) != 0)
+      return;
+
+   offset_x = png_get_int_32(buf);
+   offset_y = png_get_int_32(buf + 4);
+   unit_type = buf[8];
+   png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
+}
+#endif
+
+#ifdef PNG_READ_pCAL_SUPPORTED
+/* Read the pCAL chunk (described in the PNG Extensions document) */
+void /* PRIVATE */
+png_handle_pCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+   png_int_32 X0, X1;
+   png_byte type, nparams;
+   png_bytep buffer, buf, units, endptr;
+   png_charpp params;
+   int i;
+
+   png_debug(1, "in png_handle_pCAL");
+
+   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+      png_chunk_error(png_ptr, "missing IHDR");
+
+   else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "out of place");
+      return;
+   }
+
+   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL) != 0)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "duplicate");
+      return;
+   }
+
+   png_debug1(2, "Allocating and reading pCAL chunk data (%u bytes)",
+       length + 1);
+
+   buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/);
+
+   if (buffer == NULL)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "out of memory");
+      return;
+   }
+
+   png_crc_read(png_ptr, buffer, length);
+
+   if (png_crc_finish(png_ptr, 0) != 0)
+      return;
+
+   buffer[length] = 0; /* Null terminate the last string */
+
+   png_debug(3, "Finding end of pCAL purpose string");
+   for (buf = buffer; *buf; buf++)
+      /* Empty loop */ ;
+
+   endptr = buffer + length;
+
+   /* We need to have at least 12 bytes after the purpose string
+    * in order to get the parameter information.
+    */
+   if (endptr <= buf + 12)
+   {
+      png_chunk_benign_error(png_ptr, "invalid");
+      return;
+   }
+
+   png_debug(3, "Reading pCAL X0, X1, type, nparams, and units");
+   X0 = png_get_int_32((png_bytep)buf+1);
+   X1 = png_get_int_32((png_bytep)buf+5);
+   type = buf[9];
+   nparams = buf[10];
+   units = buf + 11;
+
+   png_debug(3, "Checking pCAL equation type and number of parameters");
+   /* Check that we have the right number of parameters for known
+    * equation types.
+    */
+   if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
+       (type == PNG_EQUATION_BASE_E && nparams != 3) ||
+       (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
+       (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
+   {
+      png_chunk_benign_error(png_ptr, "invalid parameter count");
+      return;
+   }
+
+   else if (type >= PNG_EQUATION_LAST)
+   {
+      png_chunk_benign_error(png_ptr, "unrecognized equation type");
+   }
+
+   for (buf = units; *buf; buf++)
+      /* Empty loop to move past the units string. */ ;
+
+   png_debug(3, "Allocating pCAL parameters array");
+
+   params = png_voidcast(png_charpp, png_malloc_warn(png_ptr,
+       nparams * (sizeof (png_charp))));
+
+   if (params == NULL)
+   {
+      png_chunk_benign_error(png_ptr, "out of memory");
+      return;
+   }
+
+   /* Get pointers to the start of each parameter string. */
+   for (i = 0; i < nparams; i++)
+   {
+      buf++; /* Skip the null string terminator from previous parameter. */
+
+      png_debug1(3, "Reading pCAL parameter %d", i);
+
+      for (params[i] = (png_charp)buf; buf <= endptr && *buf != 0; buf++)
+         /* Empty loop to move past each parameter string */ ;
+
+      /* Make sure we haven't run out of data yet */
+      if (buf > endptr)
+      {
+         png_free(png_ptr, params);
+         png_chunk_benign_error(png_ptr, "invalid data");
+         return;
+      }
+   }
+
+   png_set_pCAL(png_ptr, info_ptr, (png_charp)buffer, X0, X1, type, nparams,
+      (png_charp)units, params);
+
+   png_free(png_ptr, params);
+}
+#endif
+
+#ifdef PNG_READ_sCAL_SUPPORTED
+/* Read the sCAL chunk */
+void /* PRIVATE */
+png_handle_sCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+   png_bytep buffer;
+   png_size_t i;
+   int state;
+
+   png_debug(1, "in png_handle_sCAL");
+
+   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+      png_chunk_error(png_ptr, "missing IHDR");
+
+   else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "out of place");
+      return;
+   }
+
+   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL) != 0)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "duplicate");
+      return;
+   }
+
+   /* Need unit type, width, \0, height: minimum 4 bytes */
+   else if (length < 4)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "invalid");
+      return;
+   }
+
+   png_debug1(2, "Allocating and reading sCAL chunk data (%u bytes)",
+      length + 1);
+
+   buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/);
+
+   if (buffer == NULL)
+   {
+      png_chunk_benign_error(png_ptr, "out of memory");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   png_crc_read(png_ptr, buffer, length);
+   buffer[length] = 0; /* Null terminate the last string */
+
+   if (png_crc_finish(png_ptr, 0) != 0)
+      return;
+
+   /* Validate the unit. */
+   if (buffer[0] != 1 && buffer[0] != 2)
+   {
+      png_chunk_benign_error(png_ptr, "invalid unit");
+      return;
+   }
+
+   /* Validate the ASCII numbers, need two ASCII numbers separated by
+    * a '\0' and they need to fit exactly in the chunk data.
+    */
+   i = 1;
+   state = 0;
+
+   if (png_check_fp_number((png_const_charp)buffer, length, &state, &i) == 0 ||
+       i >= length || buffer[i++] != 0)
+      png_chunk_benign_error(png_ptr, "bad width format");
+
+   else if (PNG_FP_IS_POSITIVE(state) == 0)
+      png_chunk_benign_error(png_ptr, "non-positive width");
+
+   else
+   {
+      png_size_t heighti = i;
+
+      state = 0;
+      if (png_check_fp_number((png_const_charp)buffer, length,
+          &state, &i) == 0 || i != length)
+         png_chunk_benign_error(png_ptr, "bad height format");
+
+      else if (PNG_FP_IS_POSITIVE(state) == 0)
+         png_chunk_benign_error(png_ptr, "non-positive height");
+
+      else
+         /* This is the (only) success case. */
+         png_set_sCAL_s(png_ptr, info_ptr, buffer[0],
+            (png_charp)buffer+1, (png_charp)buffer+heighti);
+   }
+}
+#endif
+
+#ifdef PNG_READ_tIME_SUPPORTED
+void /* PRIVATE */
+png_handle_tIME(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+   png_byte buf[7];
+   png_time mod_time;
+
+   png_debug(1, "in png_handle_tIME");
+
+   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+      png_chunk_error(png_ptr, "missing IHDR");
+
+   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME) != 0)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "duplicate");
+      return;
+   }
+
+   if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
+      png_ptr->mode |= PNG_AFTER_IDAT;
+
+   if (length != 7)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "invalid");
+      return;
+   }
+
+   png_crc_read(png_ptr, buf, 7);
+
+   if (png_crc_finish(png_ptr, 0) != 0)
+      return;
+
+   mod_time.second = buf[6];
+   mod_time.minute = buf[5];
+   mod_time.hour = buf[4];
+   mod_time.day = buf[3];
+   mod_time.month = buf[2];
+   mod_time.year = png_get_uint_16(buf);
+
+   png_set_tIME(png_ptr, info_ptr, &mod_time);
+}
+#endif
+
+#ifdef PNG_READ_tEXt_SUPPORTED
+/* Note: this does not properly handle chunks that are > 64K under DOS */
+void /* PRIVATE */
+png_handle_tEXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+   png_text  text_info;
+   png_bytep buffer;
+   png_charp key;
+   png_charp text;
+   png_uint_32 skip = 0;
+
+   png_debug(1, "in png_handle_tEXt");
+
+#ifdef PNG_USER_LIMITS_SUPPORTED
+   if (png_ptr->user_chunk_cache_max != 0)
+   {
+      if (png_ptr->user_chunk_cache_max == 1)
+      {
+         png_crc_finish(png_ptr, length);
+         return;
+      }
+
+      if (--png_ptr->user_chunk_cache_max == 1)
+      {
+         png_crc_finish(png_ptr, length);
+         png_chunk_benign_error(png_ptr, "no space in chunk cache");
+         return;
+      }
+   }
+#endif
+
+   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+      png_chunk_error(png_ptr, "missing IHDR");
+
+   if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
+      png_ptr->mode |= PNG_AFTER_IDAT;
+
+#ifdef PNG_MAX_MALLOC_64K
+   if (length > 65535U)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "too large to fit in memory");
+      return;
+   }
+#endif
+
+   buffer = png_read_buffer(png_ptr, length+1, 1/*warn*/);
+
+   if (buffer == NULL)
+   {
+     png_chunk_benign_error(png_ptr, "out of memory");
+     return;
+   }
+
+   png_crc_read(png_ptr, buffer, length);
+
+   if (png_crc_finish(png_ptr, skip) != 0)
+      return;
+
+   key = (png_charp)buffer;
+   key[length] = 0;
+
+   for (text = key; *text; text++)
+      /* Empty loop to find end of key */ ;
+
+   if (text != key + length)
+      text++;
+
+   text_info.compression = PNG_TEXT_COMPRESSION_NONE;
+   text_info.key = key;
+   text_info.lang = NULL;
+   text_info.lang_key = NULL;
+   text_info.itxt_length = 0;
+   text_info.text = text;
+   text_info.text_length = strlen(text);
+
+   if (png_set_text_2(png_ptr, info_ptr, &text_info, 1) != 0)
+      png_warning(png_ptr, "Insufficient memory to process text chunk");
+}
+#endif
+
+#ifdef PNG_READ_zTXt_SUPPORTED
+/* Note: this does not correctly handle chunks that are > 64K under DOS */
+void /* PRIVATE */
+png_handle_zTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+   png_const_charp errmsg = NULL;
+   png_bytep       buffer;
+   png_uint_32     keyword_length;
+
+   png_debug(1, "in png_handle_zTXt");
+
+#ifdef PNG_USER_LIMITS_SUPPORTED
+   if (png_ptr->user_chunk_cache_max != 0)
+   {
+      if (png_ptr->user_chunk_cache_max == 1)
+      {
+         png_crc_finish(png_ptr, length);
+         return;
+      }
+
+      if (--png_ptr->user_chunk_cache_max == 1)
+      {
+         png_crc_finish(png_ptr, length);
+         png_chunk_benign_error(png_ptr, "no space in chunk cache");
+         return;
+      }
+   }
+#endif
+
+   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+      png_chunk_error(png_ptr, "missing IHDR");
+
+   if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
+      png_ptr->mode |= PNG_AFTER_IDAT;
+
+   buffer = png_read_buffer(png_ptr, length, 2/*silent*/);
+
+   if (buffer == NULL)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "out of memory");
+      return;
+   }
+
+   png_crc_read(png_ptr, buffer, length);
+
+   if (png_crc_finish(png_ptr, 0) != 0)
+      return;
+
+   /* TODO: also check that the keyword contents match the spec! */
+   for (keyword_length = 0;
+      keyword_length < length && buffer[keyword_length] != 0;
+      ++keyword_length)
+      /* Empty loop to find end of name */ ;
+
+   if (keyword_length > 79 || keyword_length < 1)
+      errmsg = "bad keyword";
+
+   /* zTXt must have some LZ data after the keyword, although it may expand to
+    * zero bytes; we need a '\0' at the end of the keyword, the compression type
+    * then the LZ data:
+    */
+   else if (keyword_length + 3 > length)
+      errmsg = "truncated";
+
+   else if (buffer[keyword_length+1] != PNG_COMPRESSION_TYPE_BASE)
+      errmsg = "unknown compression type";
+
+   else
+   {
+      png_alloc_size_t uncompressed_length = PNG_SIZE_MAX;
+
+      /* TODO: at present png_decompress_chunk imposes a single application
+       * level memory limit, this should be split to different values for iCCP
+       * and text chunks.
+       */
+      if (png_decompress_chunk(png_ptr, length, keyword_length+2,
+         &uncompressed_length, 1/*terminate*/) == Z_STREAM_END)
+      {
+         png_text text;
+
+         /* It worked; png_ptr->read_buffer now looks like a tEXt chunk except
+          * for the extra compression type byte and the fact that it isn't
+          * necessarily '\0' terminated.
+          */
+         buffer = png_ptr->read_buffer;
+         buffer[uncompressed_length+(keyword_length+2)] = 0;
+
+         text.compression = PNG_TEXT_COMPRESSION_zTXt;
+         text.key = (png_charp)buffer;
+         text.text = (png_charp)(buffer + keyword_length+2);
+         text.text_length = uncompressed_length;
+         text.itxt_length = 0;
+         text.lang = NULL;
+         text.lang_key = NULL;
+
+         if (png_set_text_2(png_ptr, info_ptr, &text, 1) != 0)
+            errmsg = "insufficient memory";
+      }
+
+      else
+         errmsg = png_ptr->zstream.msg;
+   }
+
+   if (errmsg != NULL)
+      png_chunk_benign_error(png_ptr, errmsg);
+}
+#endif
+
+#ifdef PNG_READ_iTXt_SUPPORTED
+/* Note: this does not correctly handle chunks that are > 64K under DOS */
+void /* PRIVATE */
+png_handle_iTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+   png_const_charp errmsg = NULL;
+   png_bytep buffer;
+   png_uint_32 prefix_length;
+
+   png_debug(1, "in png_handle_iTXt");
+
+#ifdef PNG_USER_LIMITS_SUPPORTED
+   if (png_ptr->user_chunk_cache_max != 0)
+   {
+      if (png_ptr->user_chunk_cache_max == 1)
+      {
+         png_crc_finish(png_ptr, length);
+         return;
+      }
+
+      if (--png_ptr->user_chunk_cache_max == 1)
+      {
+         png_crc_finish(png_ptr, length);
+         png_chunk_benign_error(png_ptr, "no space in chunk cache");
+         return;
+      }
+   }
+#endif
+
+   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+      png_chunk_error(png_ptr, "missing IHDR");
+
+   if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
+      png_ptr->mode |= PNG_AFTER_IDAT;
+
+   buffer = png_read_buffer(png_ptr, length+1, 1/*warn*/);
+
+   if (buffer == NULL)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "out of memory");
+      return;
+   }
+
+   png_crc_read(png_ptr, buffer, length);
+
+   if (png_crc_finish(png_ptr, 0) != 0)
+      return;
+
+   /* First the keyword. */
+   for (prefix_length=0;
+      prefix_length < length && buffer[prefix_length] != 0;
+      ++prefix_length)
+      /* Empty loop */ ;
+
+   /* Perform a basic check on the keyword length here. */
+   if (prefix_length > 79 || prefix_length < 1)
+      errmsg = "bad keyword";
+
+   /* Expect keyword, compression flag, compression type, language, translated
+    * keyword (both may be empty but are 0 terminated) then the text, which may
+    * be empty.
+    */
+   else if (prefix_length + 5 > length)
+      errmsg = "truncated";
+
+   else if (buffer[prefix_length+1] == 0 ||
+      (buffer[prefix_length+1] == 1 &&
+      buffer[prefix_length+2] == PNG_COMPRESSION_TYPE_BASE))
+   {
+      int compressed = buffer[prefix_length+1] != 0;
+      png_uint_32 language_offset, translated_keyword_offset;
+      png_alloc_size_t uncompressed_length = 0;
+
+      /* Now the language tag */
+      prefix_length += 3;
+      language_offset = prefix_length;
+
+      for (; prefix_length < length && buffer[prefix_length] != 0;
+         ++prefix_length)
+         /* Empty loop */ ;
+
+      /* WARNING: the length may be invalid here, this is checked below. */
+      translated_keyword_offset = ++prefix_length;
+
+      for (; prefix_length < length && buffer[prefix_length] != 0;
+         ++prefix_length)
+         /* Empty loop */ ;
+
+      /* prefix_length should now be at the trailing '\0' of the translated
+       * keyword, but it may already be over the end.  None of this arithmetic
+       * can overflow because chunks are at most 2^31 bytes long, but on 16-bit
+       * systems the available allocation may overflow.
+       */
+      ++prefix_length;
+
+      if (compressed == 0 && prefix_length <= length)
+         uncompressed_length = length - prefix_length;
+
+      else if (compressed != 0 && prefix_length < length)
+      {
+         uncompressed_length = PNG_SIZE_MAX;
+
+         /* TODO: at present png_decompress_chunk imposes a single application
+          * level memory limit, this should be split to different values for
+          * iCCP and text chunks.
+          */
+         if (png_decompress_chunk(png_ptr, length, prefix_length,
+            &uncompressed_length, 1/*terminate*/) == Z_STREAM_END)
+            buffer = png_ptr->read_buffer;
+
+         else
+            errmsg = png_ptr->zstream.msg;
+      }
+
+      else
+         errmsg = "truncated";
+
+      if (errmsg == NULL)
+      {
+         png_text text;
+
+         buffer[uncompressed_length+prefix_length] = 0;
+
+         if (compressed == 0)
+            text.compression = PNG_ITXT_COMPRESSION_NONE;
+
+         else
+            text.compression = PNG_ITXT_COMPRESSION_zTXt;
+
+         text.key = (png_charp)buffer;
+         text.lang = (png_charp)buffer + language_offset;
+         text.lang_key = (png_charp)buffer + translated_keyword_offset;
+         text.text = (png_charp)buffer + prefix_length;
+         text.text_length = 0;
+         text.itxt_length = uncompressed_length;
+
+         if (png_set_text_2(png_ptr, info_ptr, &text, 1) != 0)
+            errmsg = "insufficient memory";
+      }
+   }
+
+   else
+      errmsg = "bad compression info";
+
+   if (errmsg != NULL)
+      png_chunk_benign_error(png_ptr, errmsg);
+}
+#endif
+
+#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
+/* Utility function for png_handle_unknown; set up png_ptr::unknown_chunk */
+static int
+png_cache_unknown_chunk(png_structrp png_ptr, png_uint_32 length)
+{
+   png_alloc_size_t limit = PNG_SIZE_MAX;
+
+   if (png_ptr->unknown_chunk.data != NULL)
+   {
+      png_free(png_ptr, png_ptr->unknown_chunk.data);
+      png_ptr->unknown_chunk.data = NULL;
+   }
+
+#  ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED
+      if (png_ptr->user_chunk_malloc_max > 0 &&
+          png_ptr->user_chunk_malloc_max < limit)
+         limit = png_ptr->user_chunk_malloc_max;
+
+#  elif PNG_USER_CHUNK_MALLOC_MAX > 0
+      if (PNG_USER_CHUNK_MALLOC_MAX < limit)
+         limit = PNG_USER_CHUNK_MALLOC_MAX;
+#  endif
+
+   if (length <= limit)
+   {
+      PNG_CSTRING_FROM_CHUNK(png_ptr->unknown_chunk.name, png_ptr->chunk_name);
+      /* The following is safe because of the PNG_SIZE_MAX init above */
+      png_ptr->unknown_chunk.size = (png_size_t)length/*SAFE*/;
+      /* 'mode' is a flag array, only the bottom four bits matter here */
+      png_ptr->unknown_chunk.location = (png_byte)png_ptr->mode/*SAFE*/;
+
+      if (length == 0)
+         png_ptr->unknown_chunk.data = NULL;
+
+      else
+      {
+         /* Do a 'warn' here - it is handled below. */
+         png_ptr->unknown_chunk.data = png_voidcast(png_bytep,
+            png_malloc_warn(png_ptr, length));
+      }
+   }
+
+   if (png_ptr->unknown_chunk.data == NULL && length > 0)
+   {
+      /* This is benign because we clean up correctly */
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "unknown chunk exceeds memory limits");
+      return 0;
+   }
+
+   else
+   {
+      if (length > 0)
+         png_crc_read(png_ptr, png_ptr->unknown_chunk.data, length);
+      png_crc_finish(png_ptr, 0);
+      return 1;
+   }
+}
+#endif /* READ_UNKNOWN_CHUNKS */
+
+/* Handle an unknown, or known but disabled, chunk */
+void /* PRIVATE */
+png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr,
+   png_uint_32 length, int keep)
+{
+   int handled = 0; /* the chunk was handled */
+
+   png_debug(1, "in png_handle_unknown");
+
+#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
+   /* NOTE: this code is based on the code in libpng-1.4.12 except for fixing
+    * the bug which meant that setting a non-default behavior for a specific
+    * chunk would be ignored (the default was always used unless a user
+    * callback was installed).
+    *
+    * 'keep' is the value from the png_chunk_unknown_handling, the setting for
+    * this specific chunk_name, if PNG_HANDLE_AS_UNKNOWN_SUPPORTED, if not it
+    * will always be PNG_HANDLE_CHUNK_AS_DEFAULT and it needs to be set here.
+    * This is just an optimization to avoid multiple calls to the lookup
+    * function.
+    */
+#  ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+#     ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
+         keep = png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name);
+#     endif
+#  endif
+
+   /* One of the following methods will read the chunk or skip it (at least one
+    * of these is always defined because this is the only way to switch on
+    * PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
+    */
+#  ifdef PNG_READ_USER_CHUNKS_SUPPORTED
+      /* The user callback takes precedence over the chunk keep value, but the
+       * keep value is still required to validate a save of a critical chunk.
+       */
+      if (png_ptr->read_user_chunk_fn != NULL)
+      {
+         if (png_cache_unknown_chunk(png_ptr, length) != 0)
+         {
+            /* Callback to user unknown chunk handler */
+            int ret = (*(png_ptr->read_user_chunk_fn))(png_ptr,
+               &png_ptr->unknown_chunk);
+
+            /* ret is:
+             * negative: An error occured, png_chunk_error will be called.
+             *     zero: The chunk was not handled, the chunk will be discarded
+             *           unless png_set_keep_unknown_chunks has been used to set
+             *           a 'keep' behavior for this particular chunk, in which
+             *           case that will be used.  A critical chunk will cause an
+             *           error at this point unless it is to be saved.
+             * positive: The chunk was handled, libpng will ignore/discard it.
+             */
+            if (ret < 0)
+               png_chunk_error(png_ptr, "error in user chunk");
+
+            else if (ret == 0)
+            {
+               /* If the keep value is 'default' or 'never' override it, but
+                * still error out on critical chunks unless the keep value is
+                * 'always'  While this is weird it is the behavior in 1.4.12.
+                * A possible improvement would be to obey the value set for the
+                * chunk, but this would be an API change that would probably
+                * damage some applications.
+                *
+                * The png_app_warning below catches the case that matters, where
+                * the application has not set specific save or ignore for this
+                * chunk or global save or ignore.
+                */
+               if (keep < PNG_HANDLE_CHUNK_IF_SAFE)
+               {
+#                 ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
+                     if (png_ptr->unknown_default < PNG_HANDLE_CHUNK_IF_SAFE)
+                     {
+                        png_chunk_warning(png_ptr, "Saving unknown chunk:");
+                        png_app_warning(png_ptr,
+                           "forcing save of an unhandled chunk;"
+                           " please call png_set_keep_unknown_chunks");
+                           /* with keep = PNG_HANDLE_CHUNK_IF_SAFE */
+                     }
+#                 endif
+                  keep = PNG_HANDLE_CHUNK_IF_SAFE;
+               }
+            }
+
+            else /* chunk was handled */
+            {
+               handled = 1;
+               /* Critical chunks can be safely discarded at this point. */
+               keep = PNG_HANDLE_CHUNK_NEVER;
+            }
+         }
+
+         else
+            keep = PNG_HANDLE_CHUNK_NEVER; /* insufficient memory */
+      }
+
+      else
+         /* Use the SAVE_UNKNOWN_CHUNKS code or skip the chunk */
+#  endif /* READ_USER_CHUNKS */
+
+#  ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED
+      {
+         /* keep is currently just the per-chunk setting, if there was no
+          * setting change it to the global default now (not that this may
+          * still be AS_DEFAULT) then obtain the cache of the chunk if required,
+          * if not simply skip the chunk.
+          */
+         if (keep == PNG_HANDLE_CHUNK_AS_DEFAULT)
+            keep = png_ptr->unknown_default;
+
+         if (keep == PNG_HANDLE_CHUNK_ALWAYS ||
+            (keep == PNG_HANDLE_CHUNK_IF_SAFE &&
+             PNG_CHUNK_ANCILLARY(png_ptr->chunk_name)))
+         {
+            if (png_cache_unknown_chunk(png_ptr, length) == 0)
+               keep = PNG_HANDLE_CHUNK_NEVER;
+         }
+
+         else
+            png_crc_finish(png_ptr, length);
+      }
+#  else
+#     ifndef PNG_READ_USER_CHUNKS_SUPPORTED
+#        error no method to support READ_UNKNOWN_CHUNKS
+#     endif
+
+      {
+         /* If here there is no read callback pointer set and no support is
+          * compiled in to just save the unknown chunks, so simply skip this
+          * chunk.  If 'keep' is something other than AS_DEFAULT or NEVER then
+          * the app has erroneously asked for unknown chunk saving when there
+          * is no support.
+          */
+         if (keep > PNG_HANDLE_CHUNK_NEVER)
+            png_app_error(png_ptr, "no unknown chunk support available");
+
+         png_crc_finish(png_ptr, length);
+      }
+#  endif
+
+#  ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
+      /* Now store the chunk in the chunk list if appropriate, and if the limits
+       * permit it.
+       */
+      if (keep == PNG_HANDLE_CHUNK_ALWAYS ||
+         (keep == PNG_HANDLE_CHUNK_IF_SAFE &&
+          PNG_CHUNK_ANCILLARY(png_ptr->chunk_name)))
+      {
+#     ifdef PNG_USER_LIMITS_SUPPORTED
+         switch (png_ptr->user_chunk_cache_max)
+         {
+            case 2:
+               png_ptr->user_chunk_cache_max = 1;
+               png_chunk_benign_error(png_ptr, "no space in chunk cache");
+               /* FALL THROUGH */
+            case 1:
+               /* NOTE: prior to 1.6.0 this case resulted in an unknown critical
+                * chunk being skipped, now there will be a hard error below.
+                */
+               break;
+
+            default: /* not at limit */
+               --(png_ptr->user_chunk_cache_max);
+               /* FALL THROUGH */
+            case 0: /* no limit */
+#     endif /* USER_LIMITS */
+               /* Here when the limit isn't reached or when limits are compiled
+                * out; store the chunk.
+                */
+               png_set_unknown_chunks(png_ptr, info_ptr,
+                  &png_ptr->unknown_chunk, 1);
+               handled = 1;
+#     ifdef PNG_USER_LIMITS_SUPPORTED
+               break;
+         }
+#     endif
+      }
+#  else /* no store support: the chunk must be handled by the user callback */
+      PNG_UNUSED(info_ptr)
+#  endif
+
+   /* Regardless of the error handling below the cached data (if any) can be
+    * freed now.  Notice that the data is not freed if there is a png_error, but
+    * it will be freed by destroy_read_struct.
+    */
+   if (png_ptr->unknown_chunk.data != NULL)
+      png_free(png_ptr, png_ptr->unknown_chunk.data);
+   png_ptr->unknown_chunk.data = NULL;
+
+#else /* !PNG_READ_UNKNOWN_CHUNKS_SUPPORTED */
+   /* There is no support to read an unknown chunk, so just skip it. */
+   png_crc_finish(png_ptr, length);
+   PNG_UNUSED(info_ptr)
+   PNG_UNUSED(keep)
+#endif /* !READ_UNKNOWN_CHUNKS */
+
+   /* Check for unhandled critical chunks */
+   if (handled == 0 && PNG_CHUNK_CRITICAL(png_ptr->chunk_name))
+      png_chunk_error(png_ptr, "unhandled critical chunk");
+}
+
+/* This function is called to verify that a chunk name is valid.
+ * This function can't have the "critical chunk check" incorporated
+ * into it, since in the future we will need to be able to call user
+ * functions to handle unknown critical chunks after we check that
+ * the chunk name itself is valid.
+ */
+
+/* Bit hacking: the test for an invalid byte in the 4 byte chunk name is:
+ *
+ * ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
+ */
+
+void /* PRIVATE */
+png_check_chunk_name(png_structrp png_ptr, png_uint_32 chunk_name)
+{
+   int i;
+
+   png_debug(1, "in png_check_chunk_name");
+
+   for (i=1; i<=4; ++i)
+   {
+      int c = chunk_name & 0xff;
+
+      if (c < 65 || c > 122 || (c > 90 && c < 97))
+         png_chunk_error(png_ptr, "invalid chunk type");
+
+      chunk_name >>= 8;
+   }
+}
+
+/* Combines the row recently read in with the existing pixels in the row.  This
+ * routine takes care of alpha and transparency if requested.  This routine also
+ * handles the two methods of progressive display of interlaced images,
+ * depending on the 'display' value; if 'display' is true then the whole row
+ * (dp) is filled from the start by replicating the available pixels.  If
+ * 'display' is false only those pixels present in the pass are filled in.
+ */
+void /* PRIVATE */
+png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display)
+{
+   unsigned int pixel_depth = png_ptr->transformed_pixel_depth;
+   png_const_bytep sp = png_ptr->row_buf + 1;
+   png_alloc_size_t row_width = png_ptr->width;
+   unsigned int pass = png_ptr->pass;
+   png_bytep end_ptr = 0;
+   png_byte end_byte = 0;
+   unsigned int end_mask;
+
+   png_debug(1, "in png_combine_row");
+
+   /* Added in 1.5.6: it should not be possible to enter this routine until at
+    * least one row has been read from the PNG data and transformed.
+    */
+   if (pixel_depth == 0)
+      png_error(png_ptr, "internal row logic error");
+
+   /* Added in 1.5.4: the pixel depth should match the information returned by
+    * any call to png_read_update_info at this point.  Do not continue if we got
+    * this wrong.
+    */
+   if (png_ptr->info_rowbytes != 0 && png_ptr->info_rowbytes !=
+          PNG_ROWBYTES(pixel_depth, row_width))
+      png_error(png_ptr, "internal row size calculation error");
+
+   /* Don't expect this to ever happen: */
+   if (row_width == 0)
+      png_error(png_ptr, "internal row width error");
+
+   /* Preserve the last byte in cases where only part of it will be overwritten,
+    * the multiply below may overflow, we don't care because ANSI-C guarantees
+    * we get the low bits.
+    */
+   end_mask = (pixel_depth * row_width) & 7;
+   if (end_mask != 0)
+   {
+      /* end_ptr == NULL is a flag to say do nothing */
+      end_ptr = dp + PNG_ROWBYTES(pixel_depth, row_width) - 1;
+      end_byte = *end_ptr;
+#     ifdef PNG_READ_PACKSWAP_SUPPORTED
+         if ((png_ptr->transformations & PNG_PACKSWAP) != 0)
+            /* little-endian byte */
+            end_mask = 0xff << end_mask;
+
+         else /* big-endian byte */
+#     endif
+         end_mask = 0xff >> end_mask;
+      /* end_mask is now the bits to *keep* from the destination row */
+   }
+
+   /* For non-interlaced images this reduces to a memcpy(). A memcpy()
+    * will also happen if interlacing isn't supported or if the application
+    * does not call png_set_interlace_handling().  In the latter cases the
+    * caller just gets a sequence of the unexpanded rows from each interlace
+    * pass.
+    */
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+   if (png_ptr->interlaced != 0 &&
+       (png_ptr->transformations & PNG_INTERLACE) != 0 &&
+       pass < 6 && (display == 0 ||
+       /* The following copies everything for 'display' on passes 0, 2 and 4. */
+       (display == 1 && (pass & 1) != 0)))
+   {
+      /* Narrow images may have no bits in a pass; the caller should handle
+       * this, but this test is cheap:
+       */
+      if (row_width <= PNG_PASS_START_COL(pass))
+         return;
+
+      if (pixel_depth < 8)
+      {
+         /* For pixel depths up to 4 bpp the 8-pixel mask can be expanded to fit
+          * into 32 bits, then a single loop over the bytes using the four byte
+          * values in the 32-bit mask can be used.  For the 'display' option the
+          * expanded mask may also not require any masking within a byte.  To
+          * make this work the PACKSWAP option must be taken into account - it
+          * simply requires the pixels to be reversed in each byte.
+          *
+          * The 'regular' case requires a mask for each of the first 6 passes,
+          * the 'display' case does a copy for the even passes in the range
+          * 0..6.  This has already been handled in the test above.
+          *
+          * The masks are arranged as four bytes with the first byte to use in
+          * the lowest bits (little-endian) regardless of the order (PACKSWAP or
+          * not) of the pixels in each byte.
+          *
+          * NOTE: the whole of this logic depends on the caller of this function
+          * only calling it on rows appropriate to the pass.  This function only
+          * understands the 'x' logic; the 'y' logic is handled by the caller.
+          *
+          * The following defines allow generation of compile time constant bit
+          * masks for each pixel depth and each possibility of swapped or not
+          * swapped bytes.  Pass 'p' is in the range 0..6; 'x', a pixel index,
+          * is in the range 0..7; and the result is 1 if the pixel is to be
+          * copied in the pass, 0 if not.  'S' is for the sparkle method, 'B'
+          * for the block method.
+          *
+          * With some compilers a compile time expression of the general form:
+          *
+          *    (shift >= 32) ? (a >> (shift-32)) : (b >> shift)
+          *
+          * Produces warnings with values of 'shift' in the range 33 to 63
+          * because the right hand side of the ?: expression is evaluated by
+          * the compiler even though it isn't used.  Microsoft Visual C (various
+          * versions) and the Intel C compiler are known to do this.  To avoid
+          * this the following macros are used in 1.5.6.  This is a temporary
+          * solution to avoid destabilizing the code during the release process.
+          */
+#        if PNG_USE_COMPILE_TIME_MASKS
+#           define PNG_LSR(x,s) ((x)>>((s) & 0x1f))
+#           define PNG_LSL(x,s) ((x)<<((s) & 0x1f))
+#        else
+#           define PNG_LSR(x,s) ((x)>>(s))
+#           define PNG_LSL(x,s) ((x)<<(s))
+#        endif
+#        define S_COPY(p,x) (((p)<4 ? PNG_LSR(0x80088822,(3-(p))*8+(7-(x))) :\
+           PNG_LSR(0xaa55ff00,(7-(p))*8+(7-(x)))) & 1)
+#        define B_COPY(p,x) (((p)<4 ? PNG_LSR(0xff0fff33,(3-(p))*8+(7-(x))) :\
+           PNG_LSR(0xff55ff00,(7-(p))*8+(7-(x)))) & 1)
+
+         /* Return a mask for pass 'p' pixel 'x' at depth 'd'.  The mask is
+          * little endian - the first pixel is at bit 0 - however the extra
+          * parameter 's' can be set to cause the mask position to be swapped
+          * within each byte, to match the PNG format.  This is done by XOR of
+          * the shift with 7, 6 or 4 for bit depths 1, 2 and 4.
+          */
+#        define PIXEL_MASK(p,x,d,s) \
+            (PNG_LSL(((PNG_LSL(1U,(d)))-1),(((x)*(d))^((s)?8-(d):0))))
+
+         /* Hence generate the appropriate 'block' or 'sparkle' pixel copy mask.
+          */
+#        define S_MASKx(p,x,d,s) (S_COPY(p,x)?PIXEL_MASK(p,x,d,s):0)
+#        define B_MASKx(p,x,d,s) (B_COPY(p,x)?PIXEL_MASK(p,x,d,s):0)
+
+         /* Combine 8 of these to get the full mask.  For the 1-bpp and 2-bpp
+          * cases the result needs replicating, for the 4-bpp case the above
+          * generates a full 32 bits.
+          */
+#        define MASK_EXPAND(m,d) ((m)*((d)==1?0x01010101:((d)==2?0x00010001:1)))
+
+#        define S_MASK(p,d,s) MASK_EXPAND(S_MASKx(p,0,d,s) + S_MASKx(p,1,d,s) +\
+            S_MASKx(p,2,d,s) + S_MASKx(p,3,d,s) + S_MASKx(p,4,d,s) +\
+            S_MASKx(p,5,d,s) + S_MASKx(p,6,d,s) + S_MASKx(p,7,d,s), d)
+
+#        define B_MASK(p,d,s) MASK_EXPAND(B_MASKx(p,0,d,s) + B_MASKx(p,1,d,s) +\
+            B_MASKx(p,2,d,s) + B_MASKx(p,3,d,s) + B_MASKx(p,4,d,s) +\
+            B_MASKx(p,5,d,s) + B_MASKx(p,6,d,s) + B_MASKx(p,7,d,s), d)
+
+#if PNG_USE_COMPILE_TIME_MASKS
+         /* Utility macros to construct all the masks for a depth/swap
+          * combination.  The 's' parameter says whether the format is PNG
+          * (big endian bytes) or not.  Only the three odd-numbered passes are
+          * required for the display/block algorithm.
+          */
+#        define S_MASKS(d,s) { S_MASK(0,d,s), S_MASK(1,d,s), S_MASK(2,d,s),\
+            S_MASK(3,d,s), S_MASK(4,d,s), S_MASK(5,d,s) }
+
+#        define B_MASKS(d,s) { B_MASK(1,d,s), B_MASK(3,d,s), B_MASK(5,d,s) }
+
+#        define DEPTH_INDEX(d) ((d)==1?0:((d)==2?1:2))
+
+         /* Hence the pre-compiled masks indexed by PACKSWAP (or not), depth and
+          * then pass:
+          */
+         static PNG_CONST png_uint_32 row_mask[2/*PACKSWAP*/][3/*depth*/][6] =
+         {
+            /* Little-endian byte masks for PACKSWAP */
+            { S_MASKS(1,0), S_MASKS(2,0), S_MASKS(4,0) },
+            /* Normal (big-endian byte) masks - PNG format */
+            { S_MASKS(1,1), S_MASKS(2,1), S_MASKS(4,1) }
+         };
+
+         /* display_mask has only three entries for the odd passes, so index by
+          * pass>>1.
+          */
+         static PNG_CONST png_uint_32 display_mask[2][3][3] =
+         {
+            /* Little-endian byte masks for PACKSWAP */
+            { B_MASKS(1,0), B_MASKS(2,0), B_MASKS(4,0) },
+            /* Normal (big-endian byte) masks - PNG format */
+            { B_MASKS(1,1), B_MASKS(2,1), B_MASKS(4,1) }
+         };
+
+#        define MASK(pass,depth,display,png)\
+            ((display)?display_mask[png][DEPTH_INDEX(depth)][pass>>1]:\
+               row_mask[png][DEPTH_INDEX(depth)][pass])
+
+#else /* !PNG_USE_COMPILE_TIME_MASKS */
+         /* This is the runtime alternative: it seems unlikely that this will
+          * ever be either smaller or faster than the compile time approach.
+          */
+#        define MASK(pass,depth,display,png)\
+            ((display)?B_MASK(pass,depth,png):S_MASK(pass,depth,png))
+#endif /* !USE_COMPILE_TIME_MASKS */
+
+         /* Use the appropriate mask to copy the required bits.  In some cases
+          * the byte mask will be 0 or 0xff; optimize these cases.  row_width is
+          * the number of pixels, but the code copies bytes, so it is necessary
+          * to special case the end.
+          */
+         png_uint_32 pixels_per_byte = 8 / pixel_depth;
+         png_uint_32 mask;
+
+#        ifdef PNG_READ_PACKSWAP_SUPPORTED
+            if ((png_ptr->transformations & PNG_PACKSWAP) != 0)
+               mask = MASK(pass, pixel_depth, display, 0);
+
+            else
+#        endif
+            mask = MASK(pass, pixel_depth, display, 1);
+
+         for (;;)
+         {
+            png_uint_32 m;
+
+            /* It doesn't matter in the following if png_uint_32 has more than
+             * 32 bits because the high bits always match those in m<<24; it is,
+             * however, essential to use OR here, not +, because of this.
+             */
+            m = mask;
+            mask = (m >> 8) | (m << 24); /* rotate right to good compilers */
+            m &= 0xff;
+
+            if (m != 0) /* something to copy */
+            {
+               if (m != 0xff)
+                  *dp = (png_byte)((*dp & ~m) | (*sp & m));
+               else
+                  *dp = *sp;
+            }
+
+            /* NOTE: this may overwrite the last byte with garbage if the image
+             * is not an exact number of bytes wide; libpng has always done
+             * this.
+             */
+            if (row_width <= pixels_per_byte)
+               break; /* May need to restore part of the last byte */
+
+            row_width -= pixels_per_byte;
+            ++dp;
+            ++sp;
+         }
+      }
+
+      else /* pixel_depth >= 8 */
+      {
+         unsigned int bytes_to_copy, bytes_to_jump;
+
+         /* Validate the depth - it must be a multiple of 8 */
+         if (pixel_depth & 7)
+            png_error(png_ptr, "invalid user transform pixel depth");
+
+         pixel_depth >>= 3; /* now in bytes */
+         row_width *= pixel_depth;
+
+         /* Regardless of pass number the Adam 7 interlace always results in a
+          * fixed number of pixels to copy then to skip.  There may be a
+          * different number of pixels to skip at the start though.
+          */
+         {
+            unsigned int offset = PNG_PASS_START_COL(pass) * pixel_depth;
+
+            row_width -= offset;
+            dp += offset;
+            sp += offset;
+         }
+
+         /* Work out the bytes to copy. */
+         if (display != 0)
+         {
+            /* When doing the 'block' algorithm the pixel in the pass gets
+             * replicated to adjacent pixels.  This is why the even (0,2,4,6)
+             * passes are skipped above - the entire expanded row is copied.
+             */
+            bytes_to_copy = (1<<((6-pass)>>1)) * pixel_depth;
+
+            /* But don't allow this number to exceed the actual row width. */
+            if (bytes_to_copy > row_width)
+               bytes_to_copy = (unsigned int)/*SAFE*/row_width;
+         }
+
+         else /* normal row; Adam7 only ever gives us one pixel to copy. */
+            bytes_to_copy = pixel_depth;
+
+         /* In Adam7 there is a constant offset between where the pixels go. */
+         bytes_to_jump = PNG_PASS_COL_OFFSET(pass) * pixel_depth;
+
+         /* And simply copy these bytes.  Some optimization is possible here,
+          * depending on the value of 'bytes_to_copy'.  Special case the low
+          * byte counts, which we know to be frequent.
+          *
+          * Notice that these cases all 'return' rather than 'break' - this
+          * avoids an unnecessary test on whether to restore the last byte
+          * below.
+          */
+         switch (bytes_to_copy)
+         {
+            case 1:
+               for (;;)
+               {
+                  *dp = *sp;
+
+                  if (row_width <= bytes_to_jump)
+                     return;
+
+                  dp += bytes_to_jump;
+                  sp += bytes_to_jump;
+                  row_width -= bytes_to_jump;
+               }
+
+            case 2:
+               /* There is a possibility of a partial copy at the end here; this
+                * slows the code down somewhat.
+                */
+               do
+               {
+                  dp[0] = sp[0], dp[1] = sp[1];
+
+                  if (row_width <= bytes_to_jump)
+                     return;
+
+                  sp += bytes_to_jump;
+                  dp += bytes_to_jump;
+                  row_width -= bytes_to_jump;
+               }
+               while (row_width > 1);
+
+               /* And there can only be one byte left at this point: */
+               *dp = *sp;
+               return;
+
+            case 3:
+               /* This can only be the RGB case, so each copy is exactly one
+                * pixel and it is not necessary to check for a partial copy.
+                */
+               for (;;)
+               {
+                  dp[0] = sp[0], dp[1] = sp[1], dp[2] = sp[2];
+
+                  if (row_width <= bytes_to_jump)
+                     return;
+
+                  sp += bytes_to_jump;
+                  dp += bytes_to_jump;
+                  row_width -= bytes_to_jump;
+               }
+
+            default:
+#if PNG_ALIGN_TYPE != PNG_ALIGN_NONE
+               /* Check for double byte alignment and, if possible, use a
+                * 16-bit copy.  Don't attempt this for narrow images - ones that
+                * are less than an interlace panel wide.  Don't attempt it for
+                * wide bytes_to_copy either - use the memcpy there.
+                */
+               if (bytes_to_copy < 16 /*else use memcpy*/ &&
+                   png_isaligned(dp, png_uint_16) &&
+                   png_isaligned(sp, png_uint_16) &&
+                   bytes_to_copy % (sizeof (png_uint_16)) == 0 &&
+                   bytes_to_jump % (sizeof (png_uint_16)) == 0)
+               {
+                  /* Everything is aligned for png_uint_16 copies, but try for
+                   * png_uint_32 first.
+                   */
+                  if (png_isaligned(dp, png_uint_32) != 0 &&
+                      png_isaligned(sp, png_uint_32) != 0 &&
+                      bytes_to_copy % (sizeof (png_uint_32)) == 0 &&
+                      bytes_to_jump % (sizeof (png_uint_32)) == 0)
+                  {
+                     png_uint_32p dp32 = png_aligncast(png_uint_32p,dp);
+                     png_const_uint_32p sp32 = png_aligncastconst(
+                         png_const_uint_32p, sp);
+                     size_t skip = (bytes_to_jump-bytes_to_copy) /
+                         (sizeof (png_uint_32));
+
+                     do
+                     {
+                        size_t c = bytes_to_copy;
+                        do
+                        {
+                           *dp32++ = *sp32++;
+                           c -= (sizeof (png_uint_32));
+                        }
+                        while (c > 0);
+
+                        if (row_width <= bytes_to_jump)
+                           return;
+
+                        dp32 += skip;
+                        sp32 += skip;
+                        row_width -= bytes_to_jump;
+                     }
+                     while (bytes_to_copy <= row_width);
+
+                     /* Get to here when the row_width truncates the final copy.
+                      * There will be 1-3 bytes left to copy, so don't try the
+                      * 16-bit loop below.
+                      */
+                     dp = (png_bytep)dp32;
+                     sp = (png_const_bytep)sp32;
+                     do
+                        *dp++ = *sp++;
+                     while (--row_width > 0);
+                     return;
+                  }
+
+                  /* Else do it in 16-bit quantities, but only if the size is
+                   * not too large.
+                   */
+                  else
+                  {
+                     png_uint_16p dp16 = png_aligncast(png_uint_16p, dp);
+                     png_const_uint_16p sp16 = png_aligncastconst(
+                        png_const_uint_16p, sp);
+                     size_t skip = (bytes_to_jump-bytes_to_copy) /
+                        (sizeof (png_uint_16));
+
+                     do
+                     {
+                        size_t c = bytes_to_copy;
+                        do
+                        {
+                           *dp16++ = *sp16++;
+                           c -= (sizeof (png_uint_16));
+                        }
+                        while (c > 0);
+
+                        if (row_width <= bytes_to_jump)
+                           return;
+
+                        dp16 += skip;
+                        sp16 += skip;
+                        row_width -= bytes_to_jump;
+                     }
+                     while (bytes_to_copy <= row_width);
+
+                     /* End of row - 1 byte left, bytes_to_copy > row_width: */
+                     dp = (png_bytep)dp16;
+                     sp = (png_const_bytep)sp16;
+                     do
+                        *dp++ = *sp++;
+                     while (--row_width > 0);
+                     return;
+                  }
+               }
+#endif /* ALIGN_TYPE code */
+
+               /* The true default - use a memcpy: */
+               for (;;)
+               {
+                  memcpy(dp, sp, bytes_to_copy);
+
+                  if (row_width <= bytes_to_jump)
+                     return;
+
+                  sp += bytes_to_jump;
+                  dp += bytes_to_jump;
+                  row_width -= bytes_to_jump;
+                  if (bytes_to_copy > row_width)
+                     bytes_to_copy = (unsigned int)/*SAFE*/row_width;
+               }
+         }
+
+         /* NOT REACHED*/
+      } /* pixel_depth >= 8 */
+
+      /* Here if pixel_depth < 8 to check 'end_ptr' below. */
+   }
+   else
+#endif /* READ_INTERLACING */
+
+   /* If here then the switch above wasn't used so just memcpy the whole row
+    * from the temporary row buffer (notice that this overwrites the end of the
+    * destination row if it is a partial byte.)
+    */
+   memcpy(dp, sp, PNG_ROWBYTES(pixel_depth, row_width));
+
+   /* Restore the overwritten bits from the last byte if necessary. */
+   if (end_ptr != NULL)
+      *end_ptr = (png_byte)((end_byte & end_mask) | (*end_ptr & ~end_mask));
+}
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+void /* PRIVATE */
+png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
+   png_uint_32 transformations /* Because these may affect the byte layout */)
+{
+   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+   /* Offset to next interlace block */
+   static PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+   png_debug(1, "in png_do_read_interlace");
+   if (row != NULL && row_info != NULL)
+   {
+      png_uint_32 final_width;
+
+      final_width = row_info->width * png_pass_inc[pass];
+
+      switch (row_info->pixel_depth)
+      {
+         case 1:
+         {
+            png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
+            png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
+            int sshift, dshift;
+            int s_start, s_end, s_inc;
+            int jstop = png_pass_inc[pass];
+            png_byte v;
+            png_uint_32 i;
+            int j;
+
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
+            if ((transformations & PNG_PACKSWAP) != 0)
+            {
+                sshift = (int)((row_info->width + 7) & 0x07);
+                dshift = (int)((final_width + 7) & 0x07);
+                s_start = 7;
+                s_end = 0;
+                s_inc = -1;
+            }
+
+            else
+#endif
+            {
+                sshift = 7 - (int)((row_info->width + 7) & 0x07);
+                dshift = 7 - (int)((final_width + 7) & 0x07);
+                s_start = 0;
+                s_end = 7;
+                s_inc = 1;
+            }
+
+            for (i = 0; i < row_info->width; i++)
+            {
+               v = (png_byte)((*sp >> sshift) & 0x01);
+               for (j = 0; j < jstop; j++)
+               {
+                  unsigned int tmp = *dp & (0x7f7f >> (7 - dshift));
+                  tmp |= v << dshift;
+                  *dp = (png_byte)(tmp & 0xff);
+
+                  if (dshift == s_end)
+                  {
+                     dshift = s_start;
+                     dp--;
+                  }
+
+                  else
+                     dshift += s_inc;
+               }
+
+               if (sshift == s_end)
+               {
+                  sshift = s_start;
+                  sp--;
+               }
+
+               else
+                  sshift += s_inc;
+            }
+            break;
+         }
+
+         case 2:
+         {
+            png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
+            png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
+            int sshift, dshift;
+            int s_start, s_end, s_inc;
+            int jstop = png_pass_inc[pass];
+            png_uint_32 i;
+
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
+            if ((transformations & PNG_PACKSWAP) != 0)
+            {
+               sshift = (int)(((row_info->width + 3) & 0x03) << 1);
+               dshift = (int)(((final_width + 3) & 0x03) << 1);
+               s_start = 6;
+               s_end = 0;
+               s_inc = -2;
+            }
+
+            else
+#endif
+            {
+               sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
+               dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
+               s_start = 0;
+               s_end = 6;
+               s_inc = 2;
+            }
+
+            for (i = 0; i < row_info->width; i++)
+            {
+               png_byte v;
+               int j;
+
+               v = (png_byte)((*sp >> sshift) & 0x03);
+               for (j = 0; j < jstop; j++)
+               {
+                  unsigned int tmp = *dp & (0x3f3f >> (6 - dshift));
+                  tmp |= v << dshift;
+                  *dp = (png_byte)(tmp & 0xff);
+
+                  if (dshift == s_end)
+                  {
+                     dshift = s_start;
+                     dp--;
+                  }
+
+                  else
+                     dshift += s_inc;
+               }
+
+               if (sshift == s_end)
+               {
+                  sshift = s_start;
+                  sp--;
+               }
+
+               else
+                  sshift += s_inc;
+            }
+            break;
+         }
+
+         case 4:
+         {
+            png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
+            png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
+            int sshift, dshift;
+            int s_start, s_end, s_inc;
+            png_uint_32 i;
+            int jstop = png_pass_inc[pass];
+
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
+            if ((transformations & PNG_PACKSWAP) != 0)
+            {
+               sshift = (int)(((row_info->width + 1) & 0x01) << 2);
+               dshift = (int)(((final_width + 1) & 0x01) << 2);
+               s_start = 4;
+               s_end = 0;
+               s_inc = -4;
+            }
+
+            else
+#endif
+            {
+               sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
+               dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
+               s_start = 0;
+               s_end = 4;
+               s_inc = 4;
+            }
+
+            for (i = 0; i < row_info->width; i++)
+            {
+               png_byte v = (png_byte)((*sp >> sshift) & 0x0f);
+               int j;
+
+               for (j = 0; j < jstop; j++)
+               {
+                  unsigned int tmp = *dp & (0xf0f >> (4 - dshift));
+                  tmp |= v << dshift;
+                  *dp = (png_byte)(tmp & 0xff);
+
+                  if (dshift == s_end)
+                  {
+                     dshift = s_start;
+                     dp--;
+                  }
+
+                  else
+                     dshift += s_inc;
+               }
+
+               if (sshift == s_end)
+               {
+                  sshift = s_start;
+                  sp--;
+               }
+
+               else
+                  sshift += s_inc;
+            }
+            break;
+         }
+
+         default:
+         {
+            png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
+
+            png_bytep sp = row + (png_size_t)(row_info->width - 1)
+                * pixel_bytes;
+
+            png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
+
+            int jstop = png_pass_inc[pass];
+            png_uint_32 i;
+
+            for (i = 0; i < row_info->width; i++)
+            {
+               png_byte v[8]; /* SAFE; pixel_depth does not exceed 64 */
+               int j;
+
+               memcpy(v, sp, pixel_bytes);
+
+               for (j = 0; j < jstop; j++)
+               {
+                  memcpy(dp, v, pixel_bytes);
+                  dp -= pixel_bytes;
+               }
+
+               sp -= pixel_bytes;
+            }
+            break;
+         }
+      }
+
+      row_info->width = final_width;
+      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width);
+   }
+#ifndef PNG_READ_PACKSWAP_SUPPORTED
+   PNG_UNUSED(transformations)  /* Silence compiler warning */
+#endif
+}
+#endif /* READ_INTERLACING */
+
+static void
+png_read_filter_row_sub(png_row_infop row_info, png_bytep row,
+   png_const_bytep prev_row)
+{
+   png_size_t i;
+   png_size_t istop = row_info->rowbytes;
+   unsigned int bpp = (row_info->pixel_depth + 7) >> 3;
+   png_bytep rp = row + bpp;
+
+   PNG_UNUSED(prev_row)
+
+   for (i = bpp; i < istop; i++)
+   {
+      *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff);
+      rp++;
+   }
+}
+
+static void
+png_read_filter_row_up(png_row_infop row_info, png_bytep row,
+   png_const_bytep prev_row)
+{
+   png_size_t i;
+   png_size_t istop = row_info->rowbytes;
+   png_bytep rp = row;
+   png_const_bytep pp = prev_row;
+
+   for (i = 0; i < istop; i++)
+   {
+      *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
+      rp++;
+   }
+}
+
+static void
+png_read_filter_row_avg(png_row_infop row_info, png_bytep row,
+   png_const_bytep prev_row)
+{
+   png_size_t i;
+   png_bytep rp = row;
+   png_const_bytep pp = prev_row;
+   unsigned int bpp = (row_info->pixel_depth + 7) >> 3;
+   png_size_t istop = row_info->rowbytes - bpp;
+
+   for (i = 0; i < bpp; i++)
+   {
+      *rp = (png_byte)(((int)(*rp) +
+         ((int)(*pp++) / 2 )) & 0xff);
+
+      rp++;
+   }
+
+   for (i = 0; i < istop; i++)
+   {
+      *rp = (png_byte)(((int)(*rp) +
+         (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff);
+
+      rp++;
+   }
+}
+
+static void
+png_read_filter_row_paeth_1byte_pixel(png_row_infop row_info, png_bytep row,
+   png_const_bytep prev_row)
+{
+   png_bytep rp_end = row + row_info->rowbytes;
+   int a, c;
+
+   /* First pixel/byte */
+   c = *prev_row++;
+   a = *row + c;
+   *row++ = (png_byte)a;
+
+   /* Remainder */
+   while (row < rp_end)
+   {
+      int b, pa, pb, pc, p;
+
+      a &= 0xff; /* From previous iteration or start */
+      b = *prev_row++;
+
+      p = b - c;
+      pc = a - c;
+
+#     ifdef PNG_USE_ABS
+         pa = abs(p);
+         pb = abs(pc);
+         pc = abs(p + pc);
+#     else
+         pa = p < 0 ? -p : p;
+         pb = pc < 0 ? -pc : pc;
+         pc = (p + pc) < 0 ? -(p + pc) : p + pc;
+#     endif
+
+      /* Find the best predictor, the least of pa, pb, pc favoring the earlier
+       * ones in the case of a tie.
+       */
+      if (pb < pa) pa = pb, a = b;
+      if (pc < pa) a = c;
+
+      /* Calculate the current pixel in a, and move the previous row pixel to c
+       * for the next time round the loop
+       */
+      c = b;
+      a += *row;
+      *row++ = (png_byte)a;
+   }
+}
+
+static void
+png_read_filter_row_paeth_multibyte_pixel(png_row_infop row_info, png_bytep row,
+   png_const_bytep prev_row)
+{
+   int bpp = (row_info->pixel_depth + 7) >> 3;
+   png_bytep rp_end = row + bpp;
+
+   /* Process the first pixel in the row completely (this is the same as 'up'
+    * because there is only one candidate predictor for the first row).
+    */
+   while (row < rp_end)
+   {
+      int a = *row + *prev_row++;
+      *row++ = (png_byte)a;
+   }
+
+   /* Remainder */
+   rp_end += row_info->rowbytes - bpp;
+
+   while (row < rp_end)
+   {
+      int a, b, c, pa, pb, pc, p;
+
+      c = *(prev_row - bpp);
+      a = *(row - bpp);
+      b = *prev_row++;
+
+      p = b - c;
+      pc = a - c;
+
+#     ifdef PNG_USE_ABS
+         pa = abs(p);
+         pb = abs(pc);
+         pc = abs(p + pc);
+#     else
+         pa = p < 0 ? -p : p;
+         pb = pc < 0 ? -pc : pc;
+         pc = (p + pc) < 0 ? -(p + pc) : p + pc;
+#     endif
+
+      if (pb < pa) pa = pb, a = b;
+      if (pc < pa) a = c;
+
+      a += *row;
+      *row++ = (png_byte)a;
+   }
+}
+
+static void
+png_init_filter_functions(png_structrp pp)
+   /* This function is called once for every PNG image (except for PNG images
+    * that only use PNG_FILTER_VALUE_NONE for all rows) to set the
+    * implementations required to reverse the filtering of PNG rows.  Reversing
+    * the filter is the first transformation performed on the row data.  It is
+    * performed in place, therefore an implementation can be selected based on
+    * the image pixel format.  If the implementation depends on image width then
+    * take care to ensure that it works correctly if the image is interlaced -
+    * interlacing causes the actual row width to vary.
+    */
+{
+   unsigned int bpp = (pp->pixel_depth + 7) >> 3;
+
+   pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub;
+   pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up;
+   pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg;
+   if (bpp == 1)
+      pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
+         png_read_filter_row_paeth_1byte_pixel;
+   else
+      pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
+         png_read_filter_row_paeth_multibyte_pixel;
+
+#ifdef PNG_FILTER_OPTIMIZATIONS
+   /* To use this define PNG_FILTER_OPTIMIZATIONS as the name of a function to
+    * call to install hardware optimizations for the above functions; simply
+    * replace whatever elements of the pp->read_filter[] array with a hardware
+    * specific (or, for that matter, generic) optimization.
+    *
+    * To see an example of this examine what configure.ac does when
+    * --enable-arm-neon is specified on the command line.
+    */
+   PNG_FILTER_OPTIMIZATIONS(pp, bpp);
+#endif
+}
+
+void /* PRIVATE */
+png_read_filter_row(png_structrp pp, png_row_infop row_info, png_bytep row,
+   png_const_bytep prev_row, int filter)
+{
+   /* OPTIMIZATION: DO NOT MODIFY THIS FUNCTION, instead #define
+    * PNG_FILTER_OPTIMIZATIONS to a function that overrides the generic
+    * implementations.  See png_init_filter_functions above.
+    */
+   if (filter > PNG_FILTER_VALUE_NONE && filter < PNG_FILTER_VALUE_LAST)
+   {
+      if (pp->read_filter[0] == NULL)
+         png_init_filter_functions(pp);
+
+      pp->read_filter[filter-1](row_info, row, prev_row);
+   }
+}
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+void /* PRIVATE */
+png_read_IDAT_data(png_structrp png_ptr, png_bytep output,
+   png_alloc_size_t avail_out)
+{
+   /* Loop reading IDATs and decompressing the result into output[avail_out] */
+   png_ptr->zstream.next_out = output;
+   png_ptr->zstream.avail_out = 0; /* safety: set below */
+
+   if (output == NULL)
+      avail_out = 0;
+
+   do
+   {
+      int ret;
+      png_byte tmpbuf[PNG_INFLATE_BUF_SIZE];
+
+      if (png_ptr->zstream.avail_in == 0)
+      {
+         uInt avail_in;
+         png_bytep buffer;
+
+         while (png_ptr->idat_size == 0)
+         {
+            png_crc_finish(png_ptr, 0);
+
+            png_ptr->idat_size = png_read_chunk_header(png_ptr);
+            /* This is an error even in the 'check' case because the code just
+             * consumed a non-IDAT header.
+             */
+            if (png_ptr->chunk_name != png_IDAT)
+               png_error(png_ptr, "Not enough image data");
+         }
+
+         avail_in = png_ptr->IDAT_read_size;
+
+         if (avail_in > png_ptr->idat_size)
+            avail_in = (uInt)png_ptr->idat_size;
+
+         /* A PNG with a gradually increasing IDAT size will defeat this attempt
+          * to minimize memory usage by causing lots of re-allocs, but
+          * realistically doing IDAT_read_size re-allocs is not likely to be a
+          * big problem.
+          */
+         buffer = png_read_buffer(png_ptr, avail_in, 0/*error*/);
+
+         png_crc_read(png_ptr, buffer, avail_in);
+         png_ptr->idat_size -= avail_in;
+
+         png_ptr->zstream.next_in = buffer;
+         png_ptr->zstream.avail_in = avail_in;
+      }
+
+      /* And set up the output side. */
+      if (output != NULL) /* standard read */
+      {
+         uInt out = ZLIB_IO_MAX;
+
+         if (out > avail_out)
+            out = (uInt)avail_out;
+
+         avail_out -= out;
+         png_ptr->zstream.avail_out = out;
+      }
+
+      else /* after last row, checking for end */
+      {
+         png_ptr->zstream.next_out = tmpbuf;
+         png_ptr->zstream.avail_out = (sizeof tmpbuf);
+      }
+
+      /* Use NO_FLUSH; this gives zlib the maximum opportunity to optimize the
+       * process.  If the LZ stream is truncated the sequential reader will
+       * terminally damage the stream, above, by reading the chunk header of the
+       * following chunk (it then exits with png_error).
+       *
+       * TODO: deal more elegantly with truncated IDAT lists.
+       */
+      ret = inflate(&png_ptr->zstream, Z_NO_FLUSH);
+
+      /* Take the unconsumed output back. */
+      if (output != NULL)
+         avail_out += png_ptr->zstream.avail_out;
+
+      else /* avail_out counts the extra bytes */
+         avail_out += (sizeof tmpbuf) - png_ptr->zstream.avail_out;
+
+      png_ptr->zstream.avail_out = 0;
+
+      if (ret == Z_STREAM_END)
+      {
+         /* Do this for safety; we won't read any more into this row. */
+         png_ptr->zstream.next_out = NULL;
+
+         png_ptr->mode |= PNG_AFTER_IDAT;
+         png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
+
+         if (png_ptr->zstream.avail_in > 0 || png_ptr->idat_size > 0)
+            png_chunk_benign_error(png_ptr, "Extra compressed data");
+         break;
+      }
+
+      if (ret != Z_OK)
+      {
+         png_zstream_error(png_ptr, ret);
+
+         if (output != NULL)
+            png_chunk_error(png_ptr, png_ptr->zstream.msg);
+
+         else /* checking */
+         {
+            png_chunk_benign_error(png_ptr, png_ptr->zstream.msg);
+            return;
+         }
+      }
+   } while (avail_out > 0);
+
+   if (avail_out > 0)
+   {
+      /* The stream ended before the image; this is the same as too few IDATs so
+       * should be handled the same way.
+       */
+      if (output != NULL)
+         png_error(png_ptr, "Not enough image data");
+
+      else /* the deflate stream contained extra data */
+         png_chunk_benign_error(png_ptr, "Too much image data");
+   }
+}
+
+void /* PRIVATE */
+png_read_finish_IDAT(png_structrp png_ptr)
+{
+   /* We don't need any more data and the stream should have ended, however the
+    * LZ end code may actually not have been processed.  In this case we must
+    * read it otherwise stray unread IDAT data or, more likely, an IDAT chunk
+    * may still remain to be consumed.
+    */
+   if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0)
+   {
+      /* The NULL causes png_read_IDAT_data to swallow any remaining bytes in
+       * the compressed stream, but the stream may be damaged too, so even after
+       * this call we may need to terminate the zstream ownership.
+       */
+      png_read_IDAT_data(png_ptr, NULL, 0);
+      png_ptr->zstream.next_out = NULL; /* safety */
+
+      /* Now clear everything out for safety; the following may not have been
+       * done.
+       */
+      if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0)
+      {
+         png_ptr->mode |= PNG_AFTER_IDAT;
+         png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
+      }
+   }
+
+   /* If the zstream has not been released do it now *and* terminate the reading
+    * of the final IDAT chunk.
+    */
+   if (png_ptr->zowner == png_IDAT)
+   {
+      /* Always do this; the pointers otherwise point into the read buffer. */
+      png_ptr->zstream.next_in = NULL;
+      png_ptr->zstream.avail_in = 0;
+
+      /* Now we no longer own the zstream. */
+      png_ptr->zowner = 0;
+
+      /* The slightly weird semantics of the sequential IDAT reading is that we
+       * are always in or at the end of an IDAT chunk, so we always need to do a
+       * crc_finish here.  If idat_size is non-zero we also need to read the
+       * spurious bytes at the end of the chunk now.
+       */
+      (void)png_crc_finish(png_ptr, png_ptr->idat_size);
+   }
+}
+
+void /* PRIVATE */
+png_read_finish_row(png_structrp png_ptr)
+{
+   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+   /* Start of interlace block */
+   static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+   /* Offset to next interlace block */
+   static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+   /* Start of interlace block in the y direction */
+   static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+
+   /* Offset to next interlace block in the y direction */
+   static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+
+   png_debug(1, "in png_read_finish_row");
+   png_ptr->row_number++;
+   if (png_ptr->row_number < png_ptr->num_rows)
+      return;
+
+   if (png_ptr->interlaced != 0)
+   {
+      png_ptr->row_number = 0;
+
+      /* TO DO: don't do this if prev_row isn't needed (requires
+       * read-ahead of the next row's filter byte.
+       */
+      memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
+
+      do
+      {
+         png_ptr->pass++;
+
+         if (png_ptr->pass >= 7)
+            break;
+
+         png_ptr->iwidth = (png_ptr->width +
+            png_pass_inc[png_ptr->pass] - 1 -
+            png_pass_start[png_ptr->pass]) /
+            png_pass_inc[png_ptr->pass];
+
+         if ((png_ptr->transformations & PNG_INTERLACE) == 0)
+         {
+            png_ptr->num_rows = (png_ptr->height +
+                png_pass_yinc[png_ptr->pass] - 1 -
+                png_pass_ystart[png_ptr->pass]) /
+                png_pass_yinc[png_ptr->pass];
+         }
+
+         else  /* if (png_ptr->transformations & PNG_INTERLACE) */
+            break; /* libpng deinterlacing sees every row */
+
+      } while (png_ptr->num_rows == 0 || png_ptr->iwidth == 0);
+
+      if (png_ptr->pass < 7)
+         return;
+   }
+
+   /* Here after at the end of the last row of the last pass. */
+   png_read_finish_IDAT(png_ptr);
+}
+#endif /* SEQUENTIAL_READ */
+
+void /* PRIVATE */
+png_read_start_row(png_structrp png_ptr)
+{
+   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+   /* Start of interlace block */
+   static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+   /* Offset to next interlace block */
+   static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+   /* Start of interlace block in the y direction */
+   static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+
+   /* Offset to next interlace block in the y direction */
+   static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+
+   int max_pixel_depth;
+   png_size_t row_bytes;
+
+   png_debug(1, "in png_read_start_row");
+
+#ifdef PNG_READ_TRANSFORMS_SUPPORTED
+   png_init_read_transformations(png_ptr);
+#endif
+   if (png_ptr->interlaced != 0)
+   {
+      if ((png_ptr->transformations & PNG_INTERLACE) == 0)
+         png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
+             png_pass_ystart[0]) / png_pass_yinc[0];
+
+      else
+         png_ptr->num_rows = png_ptr->height;
+
+      png_ptr->iwidth = (png_ptr->width +
+          png_pass_inc[png_ptr->pass] - 1 -
+          png_pass_start[png_ptr->pass]) /
+          png_pass_inc[png_ptr->pass];
+   }
+
+   else
+   {
+      png_ptr->num_rows = png_ptr->height;
+      png_ptr->iwidth = png_ptr->width;
+   }
+
+   max_pixel_depth = png_ptr->pixel_depth;
+
+   /* WARNING: * png_read_transform_info (pngrtran.c) performs a simpler set of
+    * calculations to calculate the final pixel depth, then
+    * png_do_read_transforms actually does the transforms.  This means that the
+    * code which effectively calculates this value is actually repeated in three
+    * separate places.  They must all match.  Innocent changes to the order of
+    * transformations can and will break libpng in a way that causes memory
+    * overwrites.
+    *
+    * TODO: fix this.
+    */
+#ifdef PNG_READ_PACK_SUPPORTED
+   if ((png_ptr->transformations & PNG_PACK) != 0 && png_ptr->bit_depth < 8)
+      max_pixel_depth = 8;
+#endif
+
+#ifdef PNG_READ_EXPAND_SUPPORTED
+   if ((png_ptr->transformations & PNG_EXPAND) != 0)
+   {
+      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      {
+         if (png_ptr->num_trans != 0)
+            max_pixel_depth = 32;
+
+         else
+            max_pixel_depth = 24;
+      }
+
+      else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
+      {
+         if (max_pixel_depth < 8)
+            max_pixel_depth = 8;
+
+         if (png_ptr->num_trans != 0)
+            max_pixel_depth *= 2;
+      }
+
+      else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
+      {
+         if (png_ptr->num_trans != 0)
+         {
+            max_pixel_depth *= 4;
+            max_pixel_depth /= 3;
+         }
+      }
+   }
+#endif
+
+#ifdef PNG_READ_EXPAND_16_SUPPORTED
+   if ((png_ptr->transformations & PNG_EXPAND_16) != 0)
+   {
+#     ifdef PNG_READ_EXPAND_SUPPORTED
+         /* In fact it is an error if it isn't supported, but checking is
+          * the safe way.
+          */
+         if ((png_ptr->transformations & PNG_EXPAND) != 0)
+         {
+            if (png_ptr->bit_depth < 16)
+               max_pixel_depth *= 2;
+         }
+         else
+#     endif
+         png_ptr->transformations &= ~PNG_EXPAND_16;
+   }
+#endif
+
+#ifdef PNG_READ_FILLER_SUPPORTED
+   if ((png_ptr->transformations & (PNG_FILLER)) != 0)
+   {
+      if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
+      {
+         if (max_pixel_depth <= 8)
+            max_pixel_depth = 16;
+
+         else
+            max_pixel_depth = 32;
+      }
+
+      else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB ||
+         png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      {
+         if (max_pixel_depth <= 32)
+            max_pixel_depth = 32;
+
+         else
+            max_pixel_depth = 64;
+      }
+   }
+#endif
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+   if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0)
+   {
+      if (
+#ifdef PNG_READ_EXPAND_SUPPORTED
+          (png_ptr->num_trans != 0 &&
+          (png_ptr->transformations & PNG_EXPAND) != 0) ||
+#endif
+#ifdef PNG_READ_FILLER_SUPPORTED
+          (png_ptr->transformations & (PNG_FILLER)) != 0 ||
+#endif
+          png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+      {
+         if (max_pixel_depth <= 16)
+            max_pixel_depth = 32;
+
+         else
+            max_pixel_depth = 64;
+      }
+
+      else
+      {
+         if (max_pixel_depth <= 8)
+         {
+            if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+               max_pixel_depth = 32;
+
+            else
+               max_pixel_depth = 24;
+         }
+
+         else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+            max_pixel_depth = 64;
+
+         else
+            max_pixel_depth = 48;
+      }
+   }
+#endif
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
+defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
+   if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0)
+   {
+      int user_pixel_depth = png_ptr->user_transform_depth *
+         png_ptr->user_transform_channels;
+
+      if (user_pixel_depth > max_pixel_depth)
+         max_pixel_depth = user_pixel_depth;
+   }
+#endif
+
+   /* This value is stored in png_struct and double checked in the row read
+    * code.
+    */
+   png_ptr->maximum_pixel_depth = (png_byte)max_pixel_depth;
+   png_ptr->transformed_pixel_depth = 0; /* calculated on demand */
+
+   /* Align the width on the next larger 8 pixels.  Mainly used
+    * for interlacing
+    */
+   row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
+   /* Calculate the maximum bytes needed, adding a byte and a pixel
+    * for safety's sake
+    */
+   row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) +
+       1 + ((max_pixel_depth + 7) >> 3);
+
+#ifdef PNG_MAX_MALLOC_64K
+   if (row_bytes > (png_uint_32)65536L)
+      png_error(png_ptr, "This image requires a row greater than 64KB");
+#endif
+
+   if (row_bytes + 48 > png_ptr->old_big_row_buf_size)
+   {
+     png_free(png_ptr, png_ptr->big_row_buf);
+     png_free(png_ptr, png_ptr->big_prev_row);
+
+     if (png_ptr->interlaced != 0)
+        png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr,
+            row_bytes + 48);
+
+     else
+        png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes + 48);
+
+     png_ptr->big_prev_row = (png_bytep)png_malloc(png_ptr, row_bytes + 48);
+
+#ifdef PNG_ALIGNED_MEMORY_SUPPORTED
+     /* Use 16-byte aligned memory for row_buf with at least 16 bytes
+      * of padding before and after row_buf; treat prev_row similarly.
+      * NOTE: the alignment is to the start of the pixels, one beyond the start
+      * of the buffer, because of the filter byte.  Prior to libpng 1.5.6 this
+      * was incorrect; the filter byte was aligned, which had the exact
+      * opposite effect of that intended.
+      */
+     {
+        png_bytep temp = png_ptr->big_row_buf + 32;
+        int extra = (int)((temp - (png_bytep)0) & 0x0f);
+        png_ptr->row_buf = temp - extra - 1/*filter byte*/;
+
+        temp = png_ptr->big_prev_row + 32;
+        extra = (int)((temp - (png_bytep)0) & 0x0f);
+        png_ptr->prev_row = temp - extra - 1/*filter byte*/;
+     }
+
+#else
+     /* Use 31 bytes of padding before and 17 bytes after row_buf. */
+     png_ptr->row_buf = png_ptr->big_row_buf + 31;
+     png_ptr->prev_row = png_ptr->big_prev_row + 31;
+#endif
+     png_ptr->old_big_row_buf_size = row_bytes + 48;
+   }
+
+#ifdef PNG_MAX_MALLOC_64K
+   if (png_ptr->rowbytes > 65535)
+      png_error(png_ptr, "This image requires a row greater than 64KB");
+
+#endif
+   if (png_ptr->rowbytes > (PNG_SIZE_MAX - 1))
+      png_error(png_ptr, "Row has too many bytes to allocate in memory");
+
+   memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
+
+   png_debug1(3, "width = %u,", png_ptr->width);
+   png_debug1(3, "height = %u,", png_ptr->height);
+   png_debug1(3, "iwidth = %u,", png_ptr->iwidth);
+   png_debug1(3, "num_rows = %u,", png_ptr->num_rows);
+   png_debug1(3, "rowbytes = %lu,", (unsigned long)png_ptr->rowbytes);
+   png_debug1(3, "irowbytes = %lu",
+       (unsigned long)PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1);
+
+   /* The sequential reader needs a buffer for IDAT, but the progressive reader
+    * does not, so free the read buffer now regardless; the sequential reader
+    * reallocates it on demand.
+    */
+   if (png_ptr->read_buffer != 0)
+   {
+      png_bytep buffer = png_ptr->read_buffer;
+
+      png_ptr->read_buffer_size = 0;
+      png_ptr->read_buffer = NULL;
+      png_free(png_ptr, buffer);
+   }
+
+   /* Finally claim the zstream for the inflate of the IDAT data, use the bits
+    * value from the stream (note that this will result in a fatal error if the
+    * IDAT stream has a bogus deflate header window_bits value, but this should
+    * not be happening any longer!)
+    */
+   if (png_inflate_claim(png_ptr, png_IDAT) != Z_OK)
+      png_error(png_ptr, png_ptr->zstream.msg);
+
+   png_ptr->flags |= PNG_FLAG_ROW_INIT;
+}
+#endif /* READ */
diff --git a/Source/LibPNG/pngset.c b/Source/LibPNG/pngset.c
index fc99f5f..2f1f550 100644
--- a/Source/LibPNG/pngset.c
+++ b/Source/LibPNG/pngset.c
@@ -1,1311 +1,1611 @@
-
-/* pngset.c - storage of image information into info struct
- *
- * Last changed in libpng 1.5.11 [June 14, 2012]
- * Copyright (c) 1998-2012 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- *
- * The functions here are used during reads to store data from the file
- * into the info struct, and during writes to store application data
- * into the info struct for writing into the file.  This abstracts the
- * info struct and allows us to change the structure in the future.
- */
-
-#include "pngpriv.h"
-
-#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
-
-#ifdef PNG_bKGD_SUPPORTED
-void PNGAPI
-png_set_bKGD(png_structp png_ptr, png_infop info_ptr,
-    png_const_color_16p background)
-{
-   png_debug1(1, "in %s storage function", "bKGD");
-
-   if (png_ptr == NULL || info_ptr == NULL)
-      return;
-
-   png_memcpy(&(info_ptr->background), background, png_sizeof(png_color_16));
-   info_ptr->valid |= PNG_INFO_bKGD;
-}
-#endif
-
-#ifdef PNG_cHRM_SUPPORTED
-void PNGFAPI
-png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr,
-    png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x,
-    png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y,
-    png_fixed_point blue_x, png_fixed_point blue_y)
-{
-   png_debug1(1, "in %s storage function", "cHRM fixed");
-
-   if (png_ptr == NULL || info_ptr == NULL)
-      return;
-
-#  ifdef PNG_CHECK_cHRM_SUPPORTED
-   if (png_check_cHRM_fixed(png_ptr,
-       white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y))
-#  endif
-   {
-      info_ptr->x_white = white_x;
-      info_ptr->y_white = white_y;
-      info_ptr->x_red   = red_x;
-      info_ptr->y_red   = red_y;
-      info_ptr->x_green = green_x;
-      info_ptr->y_green = green_y;
-      info_ptr->x_blue  = blue_x;
-      info_ptr->y_blue  = blue_y;
-      info_ptr->valid |= PNG_INFO_cHRM;
-   }
-}
-
-void PNGFAPI
-png_set_cHRM_XYZ_fixed(png_structp png_ptr, png_infop info_ptr,
-    png_fixed_point int_red_X, png_fixed_point int_red_Y,
-    png_fixed_point int_red_Z, png_fixed_point int_green_X,
-    png_fixed_point int_green_Y, png_fixed_point int_green_Z,
-    png_fixed_point int_blue_X, png_fixed_point int_blue_Y,
-    png_fixed_point int_blue_Z)
-{
-   png_XYZ XYZ;
-   png_xy xy;
-
-   png_debug1(1, "in %s storage function", "cHRM XYZ fixed");
-
-   if (png_ptr == NULL || info_ptr == NULL)
-      return;
-
-   XYZ.redX = int_red_X;
-   XYZ.redY = int_red_Y;
-   XYZ.redZ = int_red_Z;
-   XYZ.greenX = int_green_X;
-   XYZ.greenY = int_green_Y;
-   XYZ.greenZ = int_green_Z;
-   XYZ.blueX = int_blue_X;
-   XYZ.blueY = int_blue_Y;
-   XYZ.blueZ = int_blue_Z;
-
-   if (png_xy_from_XYZ(&xy, XYZ))
-      png_error(png_ptr, "XYZ values out of representable range");
-
-   png_set_cHRM_fixed(png_ptr, info_ptr, xy.whitex, xy.whitey, xy.redx, xy.redy,
-      xy.greenx, xy.greeny, xy.bluex, xy.bluey);
-}
-
-#  ifdef PNG_FLOATING_POINT_SUPPORTED
-void PNGAPI
-png_set_cHRM(png_structp png_ptr, png_infop info_ptr,
-    double white_x, double white_y, double red_x, double red_y,
-    double green_x, double green_y, double blue_x, double blue_y)
-{
-   png_set_cHRM_fixed(png_ptr, info_ptr,
-      png_fixed(png_ptr, white_x, "cHRM White X"),
-      png_fixed(png_ptr, white_y, "cHRM White Y"),
-      png_fixed(png_ptr, red_x, "cHRM Red X"),
-      png_fixed(png_ptr, red_y, "cHRM Red Y"),
-      png_fixed(png_ptr, green_x, "cHRM Green X"),
-      png_fixed(png_ptr, green_y, "cHRM Green Y"),
-      png_fixed(png_ptr, blue_x, "cHRM Blue X"),
-      png_fixed(png_ptr, blue_y, "cHRM Blue Y"));
-}
-
-void PNGAPI
-png_set_cHRM_XYZ(png_structp png_ptr, png_infop info_ptr, double red_X,
-    double red_Y, double red_Z, double green_X, double green_Y, double green_Z,
-    double blue_X, double blue_Y, double blue_Z)
-{
-   png_set_cHRM_XYZ_fixed(png_ptr, info_ptr,
-      png_fixed(png_ptr, red_X, "cHRM Red X"),
-      png_fixed(png_ptr, red_Y, "cHRM Red Y"),
-      png_fixed(png_ptr, red_Z, "cHRM Red Z"),
-      png_fixed(png_ptr, green_X, "cHRM Red X"),
-      png_fixed(png_ptr, green_Y, "cHRM Red Y"),
-      png_fixed(png_ptr, green_Z, "cHRM Red Z"),
-      png_fixed(png_ptr, blue_X, "cHRM Red X"),
-      png_fixed(png_ptr, blue_Y, "cHRM Red Y"),
-      png_fixed(png_ptr, blue_Z, "cHRM Red Z"));
-}
-#  endif /* PNG_FLOATING_POINT_SUPPORTED */
-
-#endif /* PNG_cHRM_SUPPORTED */
-
-#ifdef PNG_gAMA_SUPPORTED
-void PNGFAPI
-png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point
-    file_gamma)
-{
-   png_debug1(1, "in %s storage function", "gAMA");
-
-   if (png_ptr == NULL || info_ptr == NULL)
-      return;
-
-   /* Changed in libpng-1.5.4 to limit the values to ensure overflow can't
-    * occur.  Since the fixed point representation is assymetrical it is
-    * possible for 1/gamma to overflow the limit of 21474 and this means the
-    * gamma value must be at least 5/100000 and hence at most 20000.0.  For
-    * safety the limits here are a little narrower.  The values are 0.00016 to
-    * 6250.0, which are truly ridiculous gamma values (and will produce
-    * displays that are all black or all white.)
-    */
-   if (file_gamma < 16 || file_gamma > 625000000)
-      png_warning(png_ptr, "Out of range gamma value ignored");
-
-   else
-   {
-      info_ptr->gamma = file_gamma;
-      info_ptr->valid |= PNG_INFO_gAMA;
-   }
-}
-
-#  ifdef PNG_FLOATING_POINT_SUPPORTED
-void PNGAPI
-png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma)
-{
-   png_set_gAMA_fixed(png_ptr, info_ptr, png_fixed(png_ptr, file_gamma,
-       "png_set_gAMA"));
-}
-#  endif
-#endif
-
-#ifdef PNG_hIST_SUPPORTED
-void PNGAPI
-png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_const_uint_16p hist)
-{
-   int i;
-
-   png_debug1(1, "in %s storage function", "hIST");
-
-   if (png_ptr == NULL || info_ptr == NULL)
-      return;
-
-   if (info_ptr->num_palette == 0 || info_ptr->num_palette
-       > PNG_MAX_PALETTE_LENGTH)
-   {
-      png_warning(png_ptr,
-          "Invalid palette size, hIST allocation skipped");
-
-      return;
-   }
-
-   png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0);
-
-   /* Changed from info->num_palette to PNG_MAX_PALETTE_LENGTH in
-    * version 1.2.1
-    */
-   png_ptr->hist = (png_uint_16p)png_malloc_warn(png_ptr,
-       PNG_MAX_PALETTE_LENGTH * png_sizeof(png_uint_16));
-
-   if (png_ptr->hist == NULL)
-   {
-      png_warning(png_ptr, "Insufficient memory for hIST chunk data");
-      return;
-   }
-
-   for (i = 0; i < info_ptr->num_palette; i++)
-      png_ptr->hist[i] = hist[i];
-
-   info_ptr->hist = png_ptr->hist;
-   info_ptr->valid |= PNG_INFO_hIST;
-   info_ptr->free_me |= PNG_FREE_HIST;
-}
-#endif
-
-void PNGAPI
-png_set_IHDR(png_structp png_ptr, png_infop info_ptr,
-    png_uint_32 width, png_uint_32 height, int bit_depth,
-    int color_type, int interlace_type, int compression_type,
-    int filter_type)
-{
-   png_debug1(1, "in %s storage function", "IHDR");
-
-   if (png_ptr == NULL || info_ptr == NULL)
-      return;
-
-   info_ptr->width = width;
-   info_ptr->height = height;
-   info_ptr->bit_depth = (png_byte)bit_depth;
-   info_ptr->color_type = (png_byte)color_type;
-   info_ptr->compression_type = (png_byte)compression_type;
-   info_ptr->filter_type = (png_byte)filter_type;
-   info_ptr->interlace_type = (png_byte)interlace_type;
-
-   png_check_IHDR (png_ptr, info_ptr->width, info_ptr->height,
-       info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type,
-       info_ptr->compression_type, info_ptr->filter_type);
-
-   if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
-      info_ptr->channels = 1;
-
-   else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
-      info_ptr->channels = 3;
-
-   else
-      info_ptr->channels = 1;
-
-   if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
-      info_ptr->channels++;
-
-   info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth);
-
-   /* Check for potential overflow */
-   if (width >
-       (PNG_UINT_32_MAX >> 3)      /* 8-byte RRGGBBAA pixels */
-       - 48       /* bigrowbuf hack */
-       - 1        /* filter byte */
-       - 7*8      /* rounding of width to multiple of 8 pixels */
-       - 8)       /* extra max_pixel_depth pad */
-      info_ptr->rowbytes = 0;
-   else
-      info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width);
-}
-
-#ifdef PNG_oFFs_SUPPORTED
-void PNGAPI
-png_set_oFFs(png_structp png_ptr, png_infop info_ptr,
-    png_int_32 offset_x, png_int_32 offset_y, int unit_type)
-{
-   png_debug1(1, "in %s storage function", "oFFs");
-
-   if (png_ptr == NULL || info_ptr == NULL)
-      return;
-
-   info_ptr->x_offset = offset_x;
-   info_ptr->y_offset = offset_y;
-   info_ptr->offset_unit_type = (png_byte)unit_type;
-   info_ptr->valid |= PNG_INFO_oFFs;
-}
-#endif
-
-#ifdef PNG_pCAL_SUPPORTED
-void PNGAPI
-png_set_pCAL(png_structp png_ptr, png_infop info_ptr,
-    png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type,
-    int nparams, png_const_charp units, png_charpp params)
-{
-   png_size_t length;
-   int i;
-
-   png_debug1(1, "in %s storage function", "pCAL");
-
-   if (png_ptr == NULL || info_ptr == NULL)
-      return;
-
-   length = png_strlen(purpose) + 1;
-   png_debug1(3, "allocating purpose for info (%lu bytes)",
-       (unsigned long)length);
-
-   /* TODO: validate format of calibration name and unit name */
-
-   /* Check that the type matches the specification. */
-   if (type < 0 || type > 3)
-      png_error(png_ptr, "Invalid pCAL equation type");
-
-   /* Validate params[nparams] */
-   for (i=0; i<nparams; ++i)
-      if (!png_check_fp_string(params[i], png_strlen(params[i])))
-         png_error(png_ptr, "Invalid format for pCAL parameter");
-
-   info_ptr->pcal_purpose = (png_charp)png_malloc_warn(png_ptr, length);
-
-   if (info_ptr->pcal_purpose == NULL)
-   {
-      png_warning(png_ptr, "Insufficient memory for pCAL purpose");
-      return;
-   }
-
-   png_memcpy(info_ptr->pcal_purpose, purpose, length);
-
-   png_debug(3, "storing X0, X1, type, and nparams in info");
-   info_ptr->pcal_X0 = X0;
-   info_ptr->pcal_X1 = X1;
-   info_ptr->pcal_type = (png_byte)type;
-   info_ptr->pcal_nparams = (png_byte)nparams;
-
-   length = png_strlen(units) + 1;
-   png_debug1(3, "allocating units for info (%lu bytes)",
-     (unsigned long)length);
-
-   info_ptr->pcal_units = (png_charp)png_malloc_warn(png_ptr, length);
-
-   if (info_ptr->pcal_units == NULL)
-   {
-      png_warning(png_ptr, "Insufficient memory for pCAL units");
-      return;
-   }
-
-   png_memcpy(info_ptr->pcal_units, units, length);
-
-   info_ptr->pcal_params = (png_charpp)png_malloc_warn(png_ptr,
-       (png_size_t)((nparams + 1) * png_sizeof(png_charp)));
-
-   if (info_ptr->pcal_params == NULL)
-   {
-      png_warning(png_ptr, "Insufficient memory for pCAL params");
-      return;
-   }
-
-   png_memset(info_ptr->pcal_params, 0, (nparams + 1) * png_sizeof(png_charp));
-
-   for (i = 0; i < nparams; i++)
-   {
-      length = png_strlen(params[i]) + 1;
-      png_debug2(3, "allocating parameter %d for info (%lu bytes)", i,
-          (unsigned long)length);
-
-      info_ptr->pcal_params[i] = (png_charp)png_malloc_warn(png_ptr, length);
-
-      if (info_ptr->pcal_params[i] == NULL)
-      {
-         png_warning(png_ptr, "Insufficient memory for pCAL parameter");
-         return;
-      }
-
-      png_memcpy(info_ptr->pcal_params[i], params[i], length);
-   }
-
-   info_ptr->valid |= PNG_INFO_pCAL;
-   info_ptr->free_me |= PNG_FREE_PCAL;
-}
-#endif
-
-#ifdef PNG_sCAL_SUPPORTED
-void PNGAPI
-png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr,
-    int unit, png_const_charp swidth, png_const_charp sheight)
-{
-   png_size_t lengthw = 0, lengthh = 0;
-
-   png_debug1(1, "in %s storage function", "sCAL");
-
-   if (png_ptr == NULL || info_ptr == NULL)
-      return;
-
-   /* Double check the unit (should never get here with an invalid
-    * unit unless this is an API call.)
-    */
-   if (unit != 1 && unit != 2)
-      png_error(png_ptr, "Invalid sCAL unit");
-
-   if (swidth == NULL || (lengthw = png_strlen(swidth)) == 0 ||
-       swidth[0] == 45 /* '-' */ || !png_check_fp_string(swidth, lengthw))
-      png_error(png_ptr, "Invalid sCAL width");
-
-   if (sheight == NULL || (lengthh = png_strlen(sheight)) == 0 ||
-       sheight[0] == 45 /* '-' */ || !png_check_fp_string(sheight, lengthh))
-      png_error(png_ptr, "Invalid sCAL height");
-
-   info_ptr->scal_unit = (png_byte)unit;
-
-   ++lengthw;
-
-   png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthw);
-
-   info_ptr->scal_s_width = (png_charp)png_malloc_warn(png_ptr, lengthw);
-
-   if (info_ptr->scal_s_width == NULL)
-   {
-      png_warning(png_ptr, "Memory allocation failed while processing sCAL");
-      return;
-   }
-
-   png_memcpy(info_ptr->scal_s_width, swidth, lengthw);
-
-   ++lengthh;
-
-   png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthh);
-
-   info_ptr->scal_s_height = (png_charp)png_malloc_warn(png_ptr, lengthh);
-
-   if (info_ptr->scal_s_height == NULL)
-   {
-      png_free (png_ptr, info_ptr->scal_s_width);
-      info_ptr->scal_s_width = NULL;
-
-      png_warning(png_ptr, "Memory allocation failed while processing sCAL");
-      return;
-   }
-
-   png_memcpy(info_ptr->scal_s_height, sheight, lengthh);
-
-   info_ptr->valid |= PNG_INFO_sCAL;
-   info_ptr->free_me |= PNG_FREE_SCAL;
-}
-
-#  ifdef PNG_FLOATING_POINT_SUPPORTED
-void PNGAPI
-png_set_sCAL(png_structp png_ptr, png_infop info_ptr, int unit, double width,
-    double height)
-{
-   png_debug1(1, "in %s storage function", "sCAL");
-
-   /* Check the arguments. */
-   if (width <= 0)
-      png_warning(png_ptr, "Invalid sCAL width ignored");
-
-   else if (height <= 0)
-      png_warning(png_ptr, "Invalid sCAL height ignored");
-
-   else
-   {
-      /* Convert 'width' and 'height' to ASCII. */
-      char swidth[PNG_sCAL_MAX_DIGITS+1];
-      char sheight[PNG_sCAL_MAX_DIGITS+1];
-
-      png_ascii_from_fp(png_ptr, swidth, sizeof swidth, width,
-         PNG_sCAL_PRECISION);
-      png_ascii_from_fp(png_ptr, sheight, sizeof sheight, height,
-         PNG_sCAL_PRECISION);
-
-      png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight);
-   }
-}
-#  endif
-
-#  ifdef PNG_FIXED_POINT_SUPPORTED
-void PNGAPI
-png_set_sCAL_fixed(png_structp png_ptr, png_infop info_ptr, int unit,
-    png_fixed_point width, png_fixed_point height)
-{
-   png_debug1(1, "in %s storage function", "sCAL");
-
-   /* Check the arguments. */
-   if (width <= 0)
-      png_warning(png_ptr, "Invalid sCAL width ignored");
-
-   else if (height <= 0)
-      png_warning(png_ptr, "Invalid sCAL height ignored");
-
-   else
-   {
-      /* Convert 'width' and 'height' to ASCII. */
-      char swidth[PNG_sCAL_MAX_DIGITS+1];
-      char sheight[PNG_sCAL_MAX_DIGITS+1];
-
-      png_ascii_from_fixed(png_ptr, swidth, sizeof swidth, width);
-      png_ascii_from_fixed(png_ptr, sheight, sizeof sheight, height);
-
-      png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight);
-   }
-}
-#  endif
-#endif
-
-#ifdef PNG_pHYs_SUPPORTED
-void PNGAPI
-png_set_pHYs(png_structp png_ptr, png_infop info_ptr,
-    png_uint_32 res_x, png_uint_32 res_y, int unit_type)
-{
-   png_debug1(1, "in %s storage function", "pHYs");
-
-   if (png_ptr == NULL || info_ptr == NULL)
-      return;
-
-   info_ptr->x_pixels_per_unit = res_x;
-   info_ptr->y_pixels_per_unit = res_y;
-   info_ptr->phys_unit_type = (png_byte)unit_type;
-   info_ptr->valid |= PNG_INFO_pHYs;
-}
-#endif
-
-void PNGAPI
-png_set_PLTE(png_structp png_ptr, png_infop info_ptr,
-    png_const_colorp palette, int num_palette)
-{
-
-   png_debug1(1, "in %s storage function", "PLTE");
-
-   if (png_ptr == NULL || info_ptr == NULL)
-      return;
-
-   if (num_palette < 0 || num_palette > PNG_MAX_PALETTE_LENGTH)
-   {
-      if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
-         png_error(png_ptr, "Invalid palette length");
-
-      else
-      {
-         png_warning(png_ptr, "Invalid palette length");
-         return;
-      }
-   }
-
-   /* It may not actually be necessary to set png_ptr->palette here;
-    * we do it for backward compatibility with the way the png_handle_tRNS
-    * function used to do the allocation.
-    */
-   png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0);
-
-   /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead
-    * of num_palette entries, in case of an invalid PNG file that has
-    * too-large sample values.
-    */
-   png_ptr->palette = (png_colorp)png_calloc(png_ptr,
-       PNG_MAX_PALETTE_LENGTH * png_sizeof(png_color));
-
-   png_memcpy(png_ptr->palette, palette, num_palette * png_sizeof(png_color));
-   info_ptr->palette = png_ptr->palette;
-   info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette;
-
-   info_ptr->free_me |= PNG_FREE_PLTE;
-
-   info_ptr->valid |= PNG_INFO_PLTE;
-}
-
-#ifdef PNG_sBIT_SUPPORTED
-void PNGAPI
-png_set_sBIT(png_structp png_ptr, png_infop info_ptr,
-    png_const_color_8p sig_bit)
-{
-   png_debug1(1, "in %s storage function", "sBIT");
-
-   if (png_ptr == NULL || info_ptr == NULL)
-      return;
-
-   png_memcpy(&(info_ptr->sig_bit), sig_bit, png_sizeof(png_color_8));
-   info_ptr->valid |= PNG_INFO_sBIT;
-}
-#endif
-
-#ifdef PNG_sRGB_SUPPORTED
-void PNGAPI
-png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int srgb_intent)
-{
-   png_debug1(1, "in %s storage function", "sRGB");
-
-   if (png_ptr == NULL || info_ptr == NULL)
-      return;
-
-   info_ptr->srgb_intent = (png_byte)srgb_intent;
-   info_ptr->valid |= PNG_INFO_sRGB;
-}
-
-void PNGAPI
-png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr,
-    int srgb_intent)
-{
-   png_debug1(1, "in %s storage function", "sRGB_gAMA_and_cHRM");
-
-   if (png_ptr == NULL || info_ptr == NULL)
-      return;
-
-   png_set_sRGB(png_ptr, info_ptr, srgb_intent);
-
-#  ifdef PNG_gAMA_SUPPORTED
-   png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_sRGB_INVERSE);
-#  endif
-
-#  ifdef PNG_cHRM_SUPPORTED
-   png_set_cHRM_fixed(png_ptr, info_ptr,
-      /* color      x       y */
-      /* white */ 31270, 32900,
-      /* red   */ 64000, 33000,
-      /* green */ 30000, 60000,
-      /* blue  */ 15000,  6000
-   );
-#  endif /* cHRM */
-}
-#endif /* sRGB */
-
-
-#ifdef PNG_iCCP_SUPPORTED
-void PNGAPI
-png_set_iCCP(png_structp png_ptr, png_infop info_ptr,
-    png_const_charp name, int compression_type,
-    png_const_bytep profile, png_uint_32 proflen)
-{
-   png_charp new_iccp_name;
-   png_bytep new_iccp_profile;
-   png_size_t length;
-
-   png_debug1(1, "in %s storage function", "iCCP");
-
-   if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL)
-      return;
-
-   length = png_strlen(name)+1;
-   new_iccp_name = (png_charp)png_malloc_warn(png_ptr, length);
-
-   if (new_iccp_name == NULL)
-   {
-        png_warning(png_ptr, "Insufficient memory to process iCCP chunk");
-      return;
-   }
-
-   png_memcpy(new_iccp_name, name, length);
-   new_iccp_profile = (png_bytep)png_malloc_warn(png_ptr, proflen);
-
-   if (new_iccp_profile == NULL)
-   {
-      png_free (png_ptr, new_iccp_name);
-      png_warning(png_ptr,
-          "Insufficient memory to process iCCP profile");
-      return;
-   }
-
-   png_memcpy(new_iccp_profile, profile, (png_size_t)proflen);
-
-   png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0);
-
-   info_ptr->iccp_proflen = proflen;
-   info_ptr->iccp_name = new_iccp_name;
-   info_ptr->iccp_profile = new_iccp_profile;
-   /* Compression is always zero but is here so the API and info structure
-    * does not have to change if we introduce multiple compression types
-    */
-   info_ptr->iccp_compression = (png_byte)compression_type;
-   info_ptr->free_me |= PNG_FREE_ICCP;
-   info_ptr->valid |= PNG_INFO_iCCP;
-}
-#endif
-
-#ifdef PNG_TEXT_SUPPORTED
-void PNGAPI
-png_set_text(png_structp png_ptr, png_infop info_ptr, png_const_textp text_ptr,
-    int num_text)
-{
-   int ret;
-   ret = png_set_text_2(png_ptr, info_ptr, text_ptr, num_text);
-
-   if (ret)
-      png_error(png_ptr, "Insufficient memory to store text");
-}
-
-int /* PRIVATE */
-png_set_text_2(png_structp png_ptr, png_infop info_ptr,
-    png_const_textp text_ptr, int num_text)
-{
-   int i;
-
-   png_debug1(1, "in %lx storage function", png_ptr == NULL ? "unexpected" :
-      (unsigned long)png_ptr->chunk_name);
-
-   if (png_ptr == NULL || info_ptr == NULL || num_text == 0)
-      return(0);
-
-   /* Make sure we have enough space in the "text" array in info_struct
-    * to hold all of the incoming text_ptr objects.
-    */
-   if (info_ptr->num_text + num_text > info_ptr->max_text)
-   {
-      int old_max_text = info_ptr->max_text;
-      int old_num_text = info_ptr->num_text;
-
-      if (info_ptr->text != NULL)
-      {
-         png_textp old_text;
-
-         info_ptr->max_text = info_ptr->num_text + num_text + 8;
-         old_text = info_ptr->text;
-
-         info_ptr->text = (png_textp)png_malloc_warn(png_ptr,
-            (png_size_t)(info_ptr->max_text * png_sizeof(png_text)));
-
-         if (info_ptr->text == NULL)
-         {
-            /* Restore to previous condition */
-            info_ptr->max_text = old_max_text;
-            info_ptr->text = old_text;
-            return(1);
-         }
-
-         png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max_text *
-             png_sizeof(png_text)));
-         png_free(png_ptr, old_text);
-      }
-
-      else
-      {
-         info_ptr->max_text = num_text + 8;
-         info_ptr->num_text = 0;
-         info_ptr->text = (png_textp)png_malloc_warn(png_ptr,
-             (png_size_t)(info_ptr->max_text * png_sizeof(png_text)));
-         if (info_ptr->text == NULL)
-         {
-            /* Restore to previous condition */
-            info_ptr->num_text = old_num_text;
-            info_ptr->max_text = old_max_text;
-            return(1);
-         }
-         info_ptr->free_me |= PNG_FREE_TEXT;
-      }
-
-      png_debug1(3, "allocated %d entries for info_ptr->text",
-          info_ptr->max_text);
-   }
-   for (i = 0; i < num_text; i++)
-   {
-      png_size_t text_length, key_len;
-      png_size_t lang_len, lang_key_len;
-      png_textp textp = &(info_ptr->text[info_ptr->num_text]);
-
-      if (text_ptr[i].key == NULL)
-          continue;
-
-      if (text_ptr[i].compression < PNG_TEXT_COMPRESSION_NONE ||
-          text_ptr[i].compression >= PNG_TEXT_COMPRESSION_LAST)
-      {
-         png_warning(png_ptr, "text compression mode is out of range");
-         continue;
-      }
-
-      key_len = png_strlen(text_ptr[i].key);
-
-      if (text_ptr[i].compression <= 0)
-      {
-         lang_len = 0;
-         lang_key_len = 0;
-      }
-
-      else
-#  ifdef PNG_iTXt_SUPPORTED
-      {
-         /* Set iTXt data */
-
-         if (text_ptr[i].lang != NULL)
-            lang_len = png_strlen(text_ptr[i].lang);
-
-         else
-            lang_len = 0;
-
-         if (text_ptr[i].lang_key != NULL)
-            lang_key_len = png_strlen(text_ptr[i].lang_key);
-
-         else
-            lang_key_len = 0;
-      }
-#  else /* PNG_iTXt_SUPPORTED */
-      {
-         png_warning(png_ptr, "iTXt chunk not supported");
-         continue;
-      }
-#  endif
-
-      if (text_ptr[i].text == NULL || text_ptr[i].text[0] == '\0')
-      {
-         text_length = 0;
-#  ifdef PNG_iTXt_SUPPORTED
-         if (text_ptr[i].compression > 0)
-            textp->compression = PNG_ITXT_COMPRESSION_NONE;
-
-         else
-#  endif
-            textp->compression = PNG_TEXT_COMPRESSION_NONE;
-      }
-
-      else
-      {
-         text_length = png_strlen(text_ptr[i].text);
-         textp->compression = text_ptr[i].compression;
-      }
-
-      textp->key = (png_charp)png_malloc_warn(png_ptr,
-          (png_size_t)
-          (key_len + text_length + lang_len + lang_key_len + 4));
-
-      if (textp->key == NULL)
-         return(1);
-
-      png_debug2(2, "Allocated %lu bytes at %p in png_set_text",
-          (unsigned long)(png_uint_32)
-          (key_len + lang_len + lang_key_len + text_length + 4),
-          textp->key);
-
-      png_memcpy(textp->key, text_ptr[i].key,(png_size_t)(key_len));
-      *(textp->key + key_len) = '\0';
-
-      if (text_ptr[i].compression > 0)
-      {
-         textp->lang = textp->key + key_len + 1;
-         png_memcpy(textp->lang, text_ptr[i].lang, lang_len);
-         *(textp->lang + lang_len) = '\0';
-         textp->lang_key = textp->lang + lang_len + 1;
-         png_memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len);
-         *(textp->lang_key + lang_key_len) = '\0';
-         textp->text = textp->lang_key + lang_key_len + 1;
-      }
-
-      else
-      {
-         textp->lang=NULL;
-         textp->lang_key=NULL;
-         textp->text = textp->key + key_len + 1;
-      }
-
-      if (text_length)
-         png_memcpy(textp->text, text_ptr[i].text,
-             (png_size_t)(text_length));
-
-      *(textp->text + text_length) = '\0';
-
-#  ifdef PNG_iTXt_SUPPORTED
-      if (textp->compression > 0)
-      {
-         textp->text_length = 0;
-         textp->itxt_length = text_length;
-      }
-
-      else
-#  endif
-      {
-         textp->text_length = text_length;
-         textp->itxt_length = 0;
-      }
-
-      info_ptr->num_text++;
-      png_debug1(3, "transferred text chunk %d", info_ptr->num_text);
-   }
-   return(0);
-}
-#endif
-
-#ifdef PNG_tIME_SUPPORTED
-void PNGAPI
-png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_const_timep mod_time)
-{
-   png_debug1(1, "in %s storage function", "tIME");
-
-   if (png_ptr == NULL || info_ptr == NULL ||
-       (png_ptr->mode & PNG_WROTE_tIME))
-      return;
-
-   if (mod_time->month == 0   || mod_time->month > 12  ||
-       mod_time->day   == 0   || mod_time->day   > 31  ||
-       mod_time->hour  > 23   || mod_time->minute > 59 ||
-       mod_time->second > 60)
-   {
-      png_warning(png_ptr, "Ignoring invalid time value");
-      return;
-   }
-
-   png_memcpy(&(info_ptr->mod_time), mod_time, png_sizeof(png_time));
-   info_ptr->valid |= PNG_INFO_tIME;
-}
-#endif
-
-#ifdef PNG_tRNS_SUPPORTED
-void PNGAPI
-png_set_tRNS(png_structp png_ptr, png_infop info_ptr,
-    png_const_bytep trans_alpha, int num_trans, png_const_color_16p trans_color)
-{
-   png_debug1(1, "in %s storage function", "tRNS");
-
-   if (png_ptr == NULL || info_ptr == NULL)
-      return;
-
-   if (trans_alpha != NULL)
-   {
-       /* It may not actually be necessary to set png_ptr->trans_alpha here;
-        * we do it for backward compatibility with the way the png_handle_tRNS
-        * function used to do the allocation.
-        */
-
-       png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0);
-
-       /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */
-       png_ptr->trans_alpha = info_ptr->trans_alpha =
-           (png_bytep)png_malloc(png_ptr, (png_size_t)PNG_MAX_PALETTE_LENGTH);
-
-       if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH)
-          png_memcpy(info_ptr->trans_alpha, trans_alpha, (png_size_t)num_trans);
-   }
-
-   if (trans_color != NULL)
-   {
-      int sample_max = (1 << info_ptr->bit_depth);
-
-      if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY &&
-          (int)trans_color->gray > sample_max) ||
-          (info_ptr->color_type == PNG_COLOR_TYPE_RGB &&
-          ((int)trans_color->red > sample_max ||
-          (int)trans_color->green > sample_max ||
-          (int)trans_color->blue > sample_max)))
-         png_warning(png_ptr,
-            "tRNS chunk has out-of-range samples for bit_depth");
-
-      png_memcpy(&(info_ptr->trans_color), trans_color,
-         png_sizeof(png_color_16));
-
-      if (num_trans == 0)
-         num_trans = 1;
-   }
-
-   info_ptr->num_trans = (png_uint_16)num_trans;
-
-   if (num_trans != 0)
-   {
-      info_ptr->valid |= PNG_INFO_tRNS;
-      info_ptr->free_me |= PNG_FREE_TRNS;
-   }
-}
-#endif
-
-#ifdef PNG_sPLT_SUPPORTED
-void PNGAPI
-png_set_sPLT(png_structp png_ptr,
-    png_infop info_ptr, png_const_sPLT_tp entries, int nentries)
-/*
- *  entries        - array of png_sPLT_t structures
- *                   to be added to the list of palettes
- *                   in the info structure.
- *
- *  nentries       - number of palette structures to be
- *                   added.
- */
-{
-   png_sPLT_tp np;
-   int i;
-
-   if (png_ptr == NULL || info_ptr == NULL)
-      return;
-
-   np = (png_sPLT_tp)png_malloc_warn(png_ptr,
-       (info_ptr->splt_palettes_num + nentries) *
-       (png_size_t)png_sizeof(png_sPLT_t));
-
-   if (np == NULL)
-   {
-      png_warning(png_ptr, "No memory for sPLT palettes");
-      return;
-   }
-
-   png_memcpy(np, info_ptr->splt_palettes,
-       info_ptr->splt_palettes_num * png_sizeof(png_sPLT_t));
-
-   png_free(png_ptr, info_ptr->splt_palettes);
-   info_ptr->splt_palettes=NULL;
-
-   for (i = 0; i < nentries; i++)
-   {
-      png_sPLT_tp to = np + info_ptr->splt_palettes_num + i;
-      png_const_sPLT_tp from = entries + i;
-      png_size_t length;
-
-      length = png_strlen(from->name) + 1;
-      to->name = (png_charp)png_malloc_warn(png_ptr, length);
-
-      if (to->name == NULL)
-      {
-         png_warning(png_ptr,
-             "Out of memory while processing sPLT chunk");
-         continue;
-      }
-
-      png_memcpy(to->name, from->name, length);
-      to->entries = (png_sPLT_entryp)png_malloc_warn(png_ptr,
-          from->nentries * png_sizeof(png_sPLT_entry));
-
-      if (to->entries == NULL)
-      {
-         png_warning(png_ptr,
-             "Out of memory while processing sPLT chunk");
-         png_free(png_ptr, to->name);
-         to->name = NULL;
-         continue;
-      }
-
-      png_memcpy(to->entries, from->entries,
-          from->nentries * png_sizeof(png_sPLT_entry));
-
-      to->nentries = from->nentries;
-      to->depth = from->depth;
-   }
-
-   info_ptr->splt_palettes = np;
-   info_ptr->splt_palettes_num += nentries;
-   info_ptr->valid |= PNG_INFO_sPLT;
-   info_ptr->free_me |= PNG_FREE_SPLT;
-}
-#endif /* PNG_sPLT_SUPPORTED */
-
-#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
-void PNGAPI
-png_set_unknown_chunks(png_structp png_ptr,
-   png_infop info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns)
-{
-   png_unknown_chunkp np;
-   int i;
-
-   if (png_ptr == NULL || info_ptr == NULL || num_unknowns == 0)
-      return;
-
-   np = (png_unknown_chunkp)png_malloc_warn(png_ptr,
-       (png_size_t)(info_ptr->unknown_chunks_num + num_unknowns) *
-       png_sizeof(png_unknown_chunk));
-
-   if (np == NULL)
-   {
-      png_warning(png_ptr,
-          "Out of memory while processing unknown chunk");
-      return;
-   }
-
-   png_memcpy(np, info_ptr->unknown_chunks,
-       (png_size_t)info_ptr->unknown_chunks_num *
-       png_sizeof(png_unknown_chunk));
-
-   png_free(png_ptr, info_ptr->unknown_chunks);
-   info_ptr->unknown_chunks = NULL;
-
-   for (i = 0; i < num_unknowns; i++)
-   {
-      png_unknown_chunkp to = np + info_ptr->unknown_chunks_num + i;
-      png_const_unknown_chunkp from = unknowns + i;
-
-      png_memcpy(to->name, from->name, png_sizeof(from->name));
-      to->name[png_sizeof(to->name)-1] = '\0';
-      to->size = from->size;
-
-      /* Note our location in the read or write sequence */
-      to->location = (png_byte)(png_ptr->mode & 0xff);
-
-      if (from->size == 0)
-         to->data=NULL;
-
-      else
-      {
-         to->data = (png_bytep)png_malloc_warn(png_ptr,
-             (png_size_t)from->size);
-
-         if (to->data == NULL)
-         {
-            png_warning(png_ptr,
-                "Out of memory while processing unknown chunk");
-            to->size = 0;
-         }
-
-         else
-            png_memcpy(to->data, from->data, from->size);
-      }
-   }
-
-   info_ptr->unknown_chunks = np;
-   info_ptr->unknown_chunks_num += num_unknowns;
-   info_ptr->free_me |= PNG_FREE_UNKN;
-}
-
-void PNGAPI
-png_set_unknown_chunk_location(png_structp png_ptr, png_infop info_ptr,
-    int chunk, int location)
-{
-   if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 && chunk <
-       info_ptr->unknown_chunks_num)
-      info_ptr->unknown_chunks[chunk].location = (png_byte)location;
-}
-#endif
-
-
-#ifdef PNG_MNG_FEATURES_SUPPORTED
-png_uint_32 PNGAPI
-png_permit_mng_features (png_structp png_ptr, png_uint_32 mng_features)
-{
-   png_debug(1, "in png_permit_mng_features");
-
-   if (png_ptr == NULL)
-      return (png_uint_32)0;
-
-   png_ptr->mng_features_permitted =
-       (png_byte)(mng_features & PNG_ALL_MNG_FEATURES);
-
-   return (png_uint_32)png_ptr->mng_features_permitted;
-}
-#endif
-
-#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
-void PNGAPI
-png_set_keep_unknown_chunks(png_structp png_ptr, int keep, png_const_bytep
-    chunk_list, int num_chunks)
-{
-   png_bytep new_list, p;
-   int i, old_num_chunks;
-   if (png_ptr == NULL)
-      return;
-
-   if (num_chunks == 0)
-   {
-      if (keep == PNG_HANDLE_CHUNK_ALWAYS || keep == PNG_HANDLE_CHUNK_IF_SAFE)
-         png_ptr->flags |= PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
-
-      else
-         png_ptr->flags &= ~PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
-
-      if (keep == PNG_HANDLE_CHUNK_ALWAYS)
-         png_ptr->flags |= PNG_FLAG_KEEP_UNSAFE_CHUNKS;
-
-      else
-         png_ptr->flags &= ~PNG_FLAG_KEEP_UNSAFE_CHUNKS;
-
-      return;
-   }
-
-   if (chunk_list == NULL)
-      return;
-
-   old_num_chunks = png_ptr->num_chunk_list;
-   new_list=(png_bytep)png_malloc(png_ptr,
-       (png_size_t)(5*(num_chunks + old_num_chunks)));
-
-   if (png_ptr->chunk_list != NULL)
-   {
-      png_memcpy(new_list, png_ptr->chunk_list,
-          (png_size_t)(5*old_num_chunks));
-      png_free(png_ptr, png_ptr->chunk_list);
-      png_ptr->chunk_list=NULL;
-   }
-
-   png_memcpy(new_list + 5*old_num_chunks, chunk_list,
-       (png_size_t)(5*num_chunks));
-
-   for (p = new_list + 5*old_num_chunks + 4, i = 0; i<num_chunks; i++, p += 5)
-      *p=(png_byte)keep;
-
-   png_ptr->num_chunk_list = old_num_chunks + num_chunks;
-   png_ptr->chunk_list = new_list;
-   png_ptr->free_me |= PNG_FREE_LIST;
-}
-#endif
-
-#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
-void PNGAPI
-png_set_read_user_chunk_fn(png_structp png_ptr, png_voidp user_chunk_ptr,
-    png_user_chunk_ptr read_user_chunk_fn)
-{
-   png_debug(1, "in png_set_read_user_chunk_fn");
-
-   if (png_ptr == NULL)
-      return;
-
-   png_ptr->read_user_chunk_fn = read_user_chunk_fn;
-   png_ptr->user_chunk_ptr = user_chunk_ptr;
-}
-#endif
-
-#ifdef PNG_INFO_IMAGE_SUPPORTED
-void PNGAPI
-png_set_rows(png_structp png_ptr, png_infop info_ptr, png_bytepp row_pointers)
-{
-   png_debug1(1, "in %s storage function", "rows");
-
-   if (png_ptr == NULL || info_ptr == NULL)
-      return;
-
-   if (info_ptr->row_pointers && (info_ptr->row_pointers != row_pointers))
-      png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
-
-   info_ptr->row_pointers = row_pointers;
-
-   if (row_pointers)
-      info_ptr->valid |= PNG_INFO_IDAT;
-}
-#endif
-
-void PNGAPI
-png_set_compression_buffer_size(png_structp png_ptr, png_size_t size)
-{
-    if (png_ptr == NULL)
-       return;
-
-    png_free(png_ptr, png_ptr->zbuf);
-
-    if (size > ZLIB_IO_MAX)
-    {
-       png_warning(png_ptr, "Attempt to set buffer size beyond max ignored");
-       png_ptr->zbuf_size = ZLIB_IO_MAX;
-       size = ZLIB_IO_MAX; /* must fit */
-    }
-
-    else
-       png_ptr->zbuf_size = (uInt)size;
-
-    png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, size);
-
-    /* The following ensures a relatively safe failure if this gets called while
-     * the buffer is actually in use.
-     */
-    png_ptr->zstream.next_out = png_ptr->zbuf;
-    png_ptr->zstream.avail_out = 0;
-    png_ptr->zstream.avail_in = 0;
-}
-
-void PNGAPI
-png_set_invalid(png_structp png_ptr, png_infop info_ptr, int mask)
-{
-   if (png_ptr && info_ptr)
-      info_ptr->valid &= ~mask;
-}
-
-
-
-#ifdef PNG_SET_USER_LIMITS_SUPPORTED
-/* This function was added to libpng 1.2.6 */
-void PNGAPI
-png_set_user_limits (png_structp png_ptr, png_uint_32 user_width_max,
-    png_uint_32 user_height_max)
-{
-   /* Images with dimensions larger than these limits will be
-    * rejected by png_set_IHDR().  To accept any PNG datastream
-    * regardless of dimensions, set both limits to 0x7ffffffL.
-    */
-   if (png_ptr == NULL)
-      return;
-
-   png_ptr->user_width_max = user_width_max;
-   png_ptr->user_height_max = user_height_max;
-}
-
-/* This function was added to libpng 1.4.0 */
-void PNGAPI
-png_set_chunk_cache_max (png_structp png_ptr,
-   png_uint_32 user_chunk_cache_max)
-{
-    if (png_ptr)
-       png_ptr->user_chunk_cache_max = user_chunk_cache_max;
-}
-
-/* This function was added to libpng 1.4.1 */
-void PNGAPI
-png_set_chunk_malloc_max (png_structp png_ptr,
-    png_alloc_size_t user_chunk_malloc_max)
-{
-   if (png_ptr)
-      png_ptr->user_chunk_malloc_max = user_chunk_malloc_max;
-}
-#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */
-
-
-#ifdef PNG_BENIGN_ERRORS_SUPPORTED
-void PNGAPI
-png_set_benign_errors(png_structp png_ptr, int allowed)
-{
-   png_debug(1, "in png_set_benign_errors");
-
-   if (allowed)
-      png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN;
-
-   else
-      png_ptr->flags &= ~PNG_FLAG_BENIGN_ERRORS_WARN;
-}
-#endif /* PNG_BENIGN_ERRORS_SUPPORTED */
-
-#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
-/* Whether to report invalid palette index; added at libng-1.5.10
- *   allowed  - one of 0: disable; 1: enable
- */
-void PNGAPI
-png_set_check_for_invalid_index(png_structp png_ptr, int allowed)
-{
-   png_debug(1, "in png_set_check_for_invalid_index");
-
-   if (allowed)
-      png_ptr->num_palette_max = 0;
-
-   else
-      png_ptr->num_palette_max = -1;
-}
-#endif
-
-#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
+
+/* pngset.c - storage of image information into info struct
+ *
+ * Last changed in libpng 1.6.15 [November 20, 2014]
+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * The functions here are used during reads to store data from the file
+ * into the info struct, and during writes to store application data
+ * into the info struct for writing into the file.  This abstracts the
+ * info struct and allows us to change the structure in the future.
+ */
+
+#include "pngpriv.h"
+
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+
+#ifdef PNG_bKGD_SUPPORTED
+void PNGAPI
+png_set_bKGD(png_const_structrp png_ptr, png_inforp info_ptr,
+    png_const_color_16p background)
+{
+   png_debug1(1, "in %s storage function", "bKGD");
+
+   if (png_ptr == NULL || info_ptr == NULL || background == NULL)
+      return;
+
+   info_ptr->background = *background;
+   info_ptr->valid |= PNG_INFO_bKGD;
+}
+#endif
+
+#ifdef PNG_cHRM_SUPPORTED
+void PNGFAPI
+png_set_cHRM_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
+    png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x,
+    png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y,
+    png_fixed_point blue_x, png_fixed_point blue_y)
+{
+   png_xy xy;
+
+   png_debug1(1, "in %s storage function", "cHRM fixed");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   xy.redx = red_x;
+   xy.redy = red_y;
+   xy.greenx = green_x;
+   xy.greeny = green_y;
+   xy.bluex = blue_x;
+   xy.bluey = blue_y;
+   xy.whitex = white_x;
+   xy.whitey = white_y;
+
+   if (png_colorspace_set_chromaticities(png_ptr, &info_ptr->colorspace, &xy,
+       2/* override with app values*/) != 0)
+      info_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM;
+
+   png_colorspace_sync_info(png_ptr, info_ptr);
+}
+
+void PNGFAPI
+png_set_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
+    png_fixed_point int_red_X, png_fixed_point int_red_Y,
+    png_fixed_point int_red_Z, png_fixed_point int_green_X,
+    png_fixed_point int_green_Y, png_fixed_point int_green_Z,
+    png_fixed_point int_blue_X, png_fixed_point int_blue_Y,
+    png_fixed_point int_blue_Z)
+{
+   png_XYZ XYZ;
+
+   png_debug1(1, "in %s storage function", "cHRM XYZ fixed");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   XYZ.red_X = int_red_X;
+   XYZ.red_Y = int_red_Y;
+   XYZ.red_Z = int_red_Z;
+   XYZ.green_X = int_green_X;
+   XYZ.green_Y = int_green_Y;
+   XYZ.green_Z = int_green_Z;
+   XYZ.blue_X = int_blue_X;
+   XYZ.blue_Y = int_blue_Y;
+   XYZ.blue_Z = int_blue_Z;
+
+   if (png_colorspace_set_endpoints(png_ptr, &info_ptr->colorspace,
+       &XYZ, 2) != 0)
+      info_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM;
+
+   png_colorspace_sync_info(png_ptr, info_ptr);
+}
+
+#  ifdef PNG_FLOATING_POINT_SUPPORTED
+void PNGAPI
+png_set_cHRM(png_const_structrp png_ptr, png_inforp info_ptr,
+    double white_x, double white_y, double red_x, double red_y,
+    double green_x, double green_y, double blue_x, double blue_y)
+{
+   png_set_cHRM_fixed(png_ptr, info_ptr,
+      png_fixed(png_ptr, white_x, "cHRM White X"),
+      png_fixed(png_ptr, white_y, "cHRM White Y"),
+      png_fixed(png_ptr, red_x, "cHRM Red X"),
+      png_fixed(png_ptr, red_y, "cHRM Red Y"),
+      png_fixed(png_ptr, green_x, "cHRM Green X"),
+      png_fixed(png_ptr, green_y, "cHRM Green Y"),
+      png_fixed(png_ptr, blue_x, "cHRM Blue X"),
+      png_fixed(png_ptr, blue_y, "cHRM Blue Y"));
+}
+
+void PNGAPI
+png_set_cHRM_XYZ(png_const_structrp png_ptr, png_inforp info_ptr, double red_X,
+    double red_Y, double red_Z, double green_X, double green_Y, double green_Z,
+    double blue_X, double blue_Y, double blue_Z)
+{
+   png_set_cHRM_XYZ_fixed(png_ptr, info_ptr,
+      png_fixed(png_ptr, red_X, "cHRM Red X"),
+      png_fixed(png_ptr, red_Y, "cHRM Red Y"),
+      png_fixed(png_ptr, red_Z, "cHRM Red Z"),
+      png_fixed(png_ptr, green_X, "cHRM Red X"),
+      png_fixed(png_ptr, green_Y, "cHRM Red Y"),
+      png_fixed(png_ptr, green_Z, "cHRM Red Z"),
+      png_fixed(png_ptr, blue_X, "cHRM Red X"),
+      png_fixed(png_ptr, blue_Y, "cHRM Red Y"),
+      png_fixed(png_ptr, blue_Z, "cHRM Red Z"));
+}
+#  endif /* FLOATING_POINT */
+
+#endif /* cHRM */
+
+#ifdef PNG_gAMA_SUPPORTED
+void PNGFAPI
+png_set_gAMA_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
+    png_fixed_point file_gamma)
+{
+   png_debug1(1, "in %s storage function", "gAMA");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   png_colorspace_set_gamma(png_ptr, &info_ptr->colorspace, file_gamma);
+   png_colorspace_sync_info(png_ptr, info_ptr);
+}
+
+#  ifdef PNG_FLOATING_POINT_SUPPORTED
+void PNGAPI
+png_set_gAMA(png_const_structrp png_ptr, png_inforp info_ptr, double file_gamma)
+{
+   png_set_gAMA_fixed(png_ptr, info_ptr, png_fixed(png_ptr, file_gamma,
+       "png_set_gAMA"));
+}
+#  endif
+#endif
+
+#ifdef PNG_hIST_SUPPORTED
+void PNGAPI
+png_set_hIST(png_const_structrp png_ptr, png_inforp info_ptr,
+    png_const_uint_16p hist)
+{
+   int i;
+
+   png_debug1(1, "in %s storage function", "hIST");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   if (info_ptr->num_palette == 0 || info_ptr->num_palette
+       > PNG_MAX_PALETTE_LENGTH)
+   {
+      png_warning(png_ptr,
+          "Invalid palette size, hIST allocation skipped");
+
+      return;
+   }
+
+   png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0);
+
+   /* Changed from info->num_palette to PNG_MAX_PALETTE_LENGTH in
+    * version 1.2.1
+    */
+   info_ptr->hist = png_voidcast(png_uint_16p, png_malloc_warn(png_ptr,
+       PNG_MAX_PALETTE_LENGTH * (sizeof (png_uint_16))));
+
+   if (info_ptr->hist == NULL)
+   {
+      png_warning(png_ptr, "Insufficient memory for hIST chunk data");
+      return;
+   }
+
+   info_ptr->free_me |= PNG_FREE_HIST;
+
+   for (i = 0; i < info_ptr->num_palette; i++)
+      info_ptr->hist[i] = hist[i];
+
+   info_ptr->valid |= PNG_INFO_hIST;
+}
+#endif
+
+void PNGAPI
+png_set_IHDR(png_const_structrp png_ptr, png_inforp info_ptr,
+    png_uint_32 width, png_uint_32 height, int bit_depth,
+    int color_type, int interlace_type, int compression_type,
+    int filter_type)
+{
+   png_debug1(1, "in %s storage function", "IHDR");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   info_ptr->width = width;
+   info_ptr->height = height;
+   info_ptr->bit_depth = (png_byte)bit_depth;
+   info_ptr->color_type = (png_byte)color_type;
+   info_ptr->compression_type = (png_byte)compression_type;
+   info_ptr->filter_type = (png_byte)filter_type;
+   info_ptr->interlace_type = (png_byte)interlace_type;
+
+   png_check_IHDR (png_ptr, info_ptr->width, info_ptr->height,
+       info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type,
+       info_ptr->compression_type, info_ptr->filter_type);
+
+   if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      info_ptr->channels = 1;
+
+   else if ((info_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
+      info_ptr->channels = 3;
+
+   else
+      info_ptr->channels = 1;
+
+   if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)
+      info_ptr->channels++;
+
+   info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth);
+
+   info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width);
+}
+
+#ifdef PNG_oFFs_SUPPORTED
+void PNGAPI
+png_set_oFFs(png_const_structrp png_ptr, png_inforp info_ptr,
+    png_int_32 offset_x, png_int_32 offset_y, int unit_type)
+{
+   png_debug1(1, "in %s storage function", "oFFs");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   info_ptr->x_offset = offset_x;
+   info_ptr->y_offset = offset_y;
+   info_ptr->offset_unit_type = (png_byte)unit_type;
+   info_ptr->valid |= PNG_INFO_oFFs;
+}
+#endif
+
+#ifdef PNG_pCAL_SUPPORTED
+void PNGAPI
+png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
+    png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type,
+    int nparams, png_const_charp units, png_charpp params)
+{
+   png_size_t length;
+   int i;
+
+   png_debug1(1, "in %s storage function", "pCAL");
+
+   if (png_ptr == NULL || info_ptr == NULL || purpose == NULL || units == NULL
+      || (nparams > 0 && params == NULL))
+      return;
+
+   length = strlen(purpose) + 1;
+   png_debug1(3, "allocating purpose for info (%lu bytes)",
+       (unsigned long)length);
+
+   /* TODO: validate format of calibration name and unit name */
+
+   /* Check that the type matches the specification. */
+   if (type < 0 || type > 3)
+      png_error(png_ptr, "Invalid pCAL equation type");
+
+   if (nparams < 0 || nparams > 255)
+      png_error(png_ptr, "Invalid pCAL parameter count");
+
+   /* Validate params[nparams] */
+   for (i=0; i<nparams; ++i)
+   {
+      if (params[i] == NULL ||
+          !png_check_fp_string(params[i], strlen(params[i])))
+         png_error(png_ptr, "Invalid format for pCAL parameter");
+   }
+
+   info_ptr->pcal_purpose = png_voidcast(png_charp,
+       png_malloc_warn(png_ptr, length));
+
+   if (info_ptr->pcal_purpose == NULL)
+   {
+      png_warning(png_ptr, "Insufficient memory for pCAL purpose");
+      return;
+   }
+
+   memcpy(info_ptr->pcal_purpose, purpose, length);
+
+   png_debug(3, "storing X0, X1, type, and nparams in info");
+   info_ptr->pcal_X0 = X0;
+   info_ptr->pcal_X1 = X1;
+   info_ptr->pcal_type = (png_byte)type;
+   info_ptr->pcal_nparams = (png_byte)nparams;
+
+   length = strlen(units) + 1;
+   png_debug1(3, "allocating units for info (%lu bytes)",
+     (unsigned long)length);
+
+   info_ptr->pcal_units = png_voidcast(png_charp,
+      png_malloc_warn(png_ptr, length));
+
+   if (info_ptr->pcal_units == NULL)
+   {
+      png_warning(png_ptr, "Insufficient memory for pCAL units");
+      return;
+   }
+
+   memcpy(info_ptr->pcal_units, units, length);
+
+   info_ptr->pcal_params = png_voidcast(png_charpp, png_malloc_warn(png_ptr,
+       (png_size_t)((nparams + 1) * (sizeof (png_charp)))));
+
+   if (info_ptr->pcal_params == NULL)
+   {
+      png_warning(png_ptr, "Insufficient memory for pCAL params");
+      return;
+   }
+
+   memset(info_ptr->pcal_params, 0, (nparams + 1) * (sizeof (png_charp)));
+
+   for (i = 0; i < nparams; i++)
+   {
+      length = strlen(params[i]) + 1;
+      png_debug2(3, "allocating parameter %d for info (%lu bytes)", i,
+          (unsigned long)length);
+
+      info_ptr->pcal_params[i] = (png_charp)png_malloc_warn(png_ptr, length);
+
+      if (info_ptr->pcal_params[i] == NULL)
+      {
+         png_warning(png_ptr, "Insufficient memory for pCAL parameter");
+         return;
+      }
+
+      memcpy(info_ptr->pcal_params[i], params[i], length);
+   }
+
+   info_ptr->valid |= PNG_INFO_pCAL;
+   info_ptr->free_me |= PNG_FREE_PCAL;
+}
+#endif
+
+#ifdef PNG_sCAL_SUPPORTED
+void PNGAPI
+png_set_sCAL_s(png_const_structrp png_ptr, png_inforp info_ptr,
+    int unit, png_const_charp swidth, png_const_charp sheight)
+{
+   png_size_t lengthw = 0, lengthh = 0;
+
+   png_debug1(1, "in %s storage function", "sCAL");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   /* Double check the unit (should never get here with an invalid
+    * unit unless this is an API call.)
+    */
+   if (unit != 1 && unit != 2)
+      png_error(png_ptr, "Invalid sCAL unit");
+
+   if (swidth == NULL || (lengthw = strlen(swidth)) == 0 ||
+       swidth[0] == 45 /* '-' */ || !png_check_fp_string(swidth, lengthw))
+      png_error(png_ptr, "Invalid sCAL width");
+
+   if (sheight == NULL || (lengthh = strlen(sheight)) == 0 ||
+       sheight[0] == 45 /* '-' */ || !png_check_fp_string(sheight, lengthh))
+      png_error(png_ptr, "Invalid sCAL height");
+
+   info_ptr->scal_unit = (png_byte)unit;
+
+   ++lengthw;
+
+   png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthw);
+
+   info_ptr->scal_s_width = png_voidcast(png_charp,
+      png_malloc_warn(png_ptr, lengthw));
+
+   if (info_ptr->scal_s_width == NULL)
+   {
+      png_warning(png_ptr, "Memory allocation failed while processing sCAL");
+      return;
+   }
+
+   memcpy(info_ptr->scal_s_width, swidth, lengthw);
+
+   ++lengthh;
+
+   png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthh);
+
+   info_ptr->scal_s_height = png_voidcast(png_charp,
+      png_malloc_warn(png_ptr, lengthh));
+
+   if (info_ptr->scal_s_height == NULL)
+   {
+      png_free (png_ptr, info_ptr->scal_s_width);
+      info_ptr->scal_s_width = NULL;
+
+      png_warning(png_ptr, "Memory allocation failed while processing sCAL");
+      return;
+   }
+
+   memcpy(info_ptr->scal_s_height, sheight, lengthh);
+
+   info_ptr->valid |= PNG_INFO_sCAL;
+   info_ptr->free_me |= PNG_FREE_SCAL;
+}
+
+#  ifdef PNG_FLOATING_POINT_SUPPORTED
+void PNGAPI
+png_set_sCAL(png_const_structrp png_ptr, png_inforp info_ptr, int unit,
+    double width, double height)
+{
+   png_debug1(1, "in %s storage function", "sCAL");
+
+   /* Check the arguments. */
+   if (width <= 0)
+      png_warning(png_ptr, "Invalid sCAL width ignored");
+
+   else if (height <= 0)
+      png_warning(png_ptr, "Invalid sCAL height ignored");
+
+   else
+   {
+      /* Convert 'width' and 'height' to ASCII. */
+      char swidth[PNG_sCAL_MAX_DIGITS+1];
+      char sheight[PNG_sCAL_MAX_DIGITS+1];
+
+      png_ascii_from_fp(png_ptr, swidth, (sizeof swidth), width,
+         PNG_sCAL_PRECISION);
+      png_ascii_from_fp(png_ptr, sheight, (sizeof sheight), height,
+         PNG_sCAL_PRECISION);
+
+      png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight);
+   }
+}
+#  endif
+
+#  ifdef PNG_FIXED_POINT_SUPPORTED
+void PNGAPI
+png_set_sCAL_fixed(png_const_structrp png_ptr, png_inforp info_ptr, int unit,
+    png_fixed_point width, png_fixed_point height)
+{
+   png_debug1(1, "in %s storage function", "sCAL");
+
+   /* Check the arguments. */
+   if (width <= 0)
+      png_warning(png_ptr, "Invalid sCAL width ignored");
+
+   else if (height <= 0)
+      png_warning(png_ptr, "Invalid sCAL height ignored");
+
+   else
+   {
+      /* Convert 'width' and 'height' to ASCII. */
+      char swidth[PNG_sCAL_MAX_DIGITS+1];
+      char sheight[PNG_sCAL_MAX_DIGITS+1];
+
+      png_ascii_from_fixed(png_ptr, swidth, (sizeof swidth), width);
+      png_ascii_from_fixed(png_ptr, sheight, (sizeof sheight), height);
+
+      png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight);
+   }
+}
+#  endif
+#endif
+
+#ifdef PNG_pHYs_SUPPORTED
+void PNGAPI
+png_set_pHYs(png_const_structrp png_ptr, png_inforp info_ptr,
+    png_uint_32 res_x, png_uint_32 res_y, int unit_type)
+{
+   png_debug1(1, "in %s storage function", "pHYs");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   info_ptr->x_pixels_per_unit = res_x;
+   info_ptr->y_pixels_per_unit = res_y;
+   info_ptr->phys_unit_type = (png_byte)unit_type;
+   info_ptr->valid |= PNG_INFO_pHYs;
+}
+#endif
+
+void PNGAPI
+png_set_PLTE(png_structrp png_ptr, png_inforp info_ptr,
+    png_const_colorp palette, int num_palette)
+{
+
+   png_debug1(1, "in %s storage function", "PLTE");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   if (num_palette < 0 || num_palette > PNG_MAX_PALETTE_LENGTH)
+   {
+      if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+         png_error(png_ptr, "Invalid palette length");
+
+      else
+      {
+         png_warning(png_ptr, "Invalid palette length");
+         return;
+      }
+   }
+
+   if ((num_palette > 0 && palette == NULL) ||
+      (num_palette == 0
+#        ifdef PNG_MNG_FEATURES_SUPPORTED
+            && (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0
+#        endif
+      ))
+   {
+      png_error(png_ptr, "Invalid palette");
+      return;
+   }
+
+   /* It may not actually be necessary to set png_ptr->palette here;
+    * we do it for backward compatibility with the way the png_handle_tRNS
+    * function used to do the allocation.
+    *
+    * 1.6.0: the above statement appears to be incorrect; something has to set
+    * the palette inside png_struct on read.
+    */
+   png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0);
+
+   /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead
+    * of num_palette entries, in case of an invalid PNG file that has
+    * too-large sample values.
+    */
+   png_ptr->palette = png_voidcast(png_colorp, png_calloc(png_ptr,
+       PNG_MAX_PALETTE_LENGTH * (sizeof (png_color))));
+
+   if (num_palette > 0)
+      memcpy(png_ptr->palette, palette, num_palette * (sizeof (png_color)));
+   info_ptr->palette = png_ptr->palette;
+   info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette;
+
+   info_ptr->free_me |= PNG_FREE_PLTE;
+
+   info_ptr->valid |= PNG_INFO_PLTE;
+}
+
+#ifdef PNG_sBIT_SUPPORTED
+void PNGAPI
+png_set_sBIT(png_const_structrp png_ptr, png_inforp info_ptr,
+    png_const_color_8p sig_bit)
+{
+   png_debug1(1, "in %s storage function", "sBIT");
+
+   if (png_ptr == NULL || info_ptr == NULL || sig_bit == NULL)
+      return;
+
+   info_ptr->sig_bit = *sig_bit;
+   info_ptr->valid |= PNG_INFO_sBIT;
+}
+#endif
+
+#ifdef PNG_sRGB_SUPPORTED
+void PNGAPI
+png_set_sRGB(png_const_structrp png_ptr, png_inforp info_ptr, int srgb_intent)
+{
+   png_debug1(1, "in %s storage function", "sRGB");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   (void)png_colorspace_set_sRGB(png_ptr, &info_ptr->colorspace, srgb_intent);
+   png_colorspace_sync_info(png_ptr, info_ptr);
+}
+
+void PNGAPI
+png_set_sRGB_gAMA_and_cHRM(png_const_structrp png_ptr, png_inforp info_ptr,
+    int srgb_intent)
+{
+   png_debug1(1, "in %s storage function", "sRGB_gAMA_and_cHRM");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   if (png_colorspace_set_sRGB(png_ptr, &info_ptr->colorspace,
+       srgb_intent) != 0)
+   {
+      /* This causes the gAMA and cHRM to be written too */
+      info_ptr->colorspace.flags |=
+         PNG_COLORSPACE_FROM_gAMA|PNG_COLORSPACE_FROM_cHRM;
+   }
+
+   png_colorspace_sync_info(png_ptr, info_ptr);
+}
+#endif /* sRGB */
+
+
+#ifdef PNG_iCCP_SUPPORTED
+void PNGAPI
+png_set_iCCP(png_const_structrp png_ptr, png_inforp info_ptr,
+    png_const_charp name, int compression_type,
+    png_const_bytep profile, png_uint_32 proflen)
+{
+   png_charp new_iccp_name;
+   png_bytep new_iccp_profile;
+   png_size_t length;
+
+   png_debug1(1, "in %s storage function", "iCCP");
+
+   if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL)
+      return;
+
+   if (compression_type != PNG_COMPRESSION_TYPE_BASE)
+      png_app_error(png_ptr, "Invalid iCCP compression method");
+
+   /* Set the colorspace first because this validates the profile; do not
+    * override previously set app cHRM or gAMA here (because likely as not the
+    * application knows better than libpng what the correct values are.)  Pass
+    * the info_ptr color_type field to png_colorspace_set_ICC because in the
+    * write case it has not yet been stored in png_ptr.
+    */
+   {
+      int result = png_colorspace_set_ICC(png_ptr, &info_ptr->colorspace, name,
+         proflen, profile, info_ptr->color_type);
+
+      png_colorspace_sync_info(png_ptr, info_ptr);
+
+      /* Don't do any of the copying if the profile was bad, or inconsistent. */
+      if (result == 0)
+         return;
+
+      /* But do write the gAMA and cHRM chunks from the profile. */
+      info_ptr->colorspace.flags |=
+         PNG_COLORSPACE_FROM_gAMA|PNG_COLORSPACE_FROM_cHRM;
+   }
+
+   length = strlen(name)+1;
+   new_iccp_name = png_voidcast(png_charp, png_malloc_warn(png_ptr, length));
+
+   if (new_iccp_name == NULL)
+   {
+      png_benign_error(png_ptr, "Insufficient memory to process iCCP chunk");
+      return;
+   }
+
+   memcpy(new_iccp_name, name, length);
+   new_iccp_profile = png_voidcast(png_bytep,
+      png_malloc_warn(png_ptr, proflen));
+
+   if (new_iccp_profile == NULL)
+   {
+      png_free(png_ptr, new_iccp_name);
+      new_iccp_name = NULL;
+      png_benign_error(png_ptr,
+          "Insufficient memory to process iCCP profile");
+      return;
+   }
+
+   memcpy(new_iccp_profile, profile, proflen);
+
+   png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0);
+
+   info_ptr->iccp_proflen = proflen;
+   info_ptr->iccp_name = new_iccp_name;
+   info_ptr->iccp_profile = new_iccp_profile;
+   info_ptr->free_me |= PNG_FREE_ICCP;
+   info_ptr->valid |= PNG_INFO_iCCP;
+}
+#endif
+
+#ifdef PNG_TEXT_SUPPORTED
+void PNGAPI
+png_set_text(png_const_structrp png_ptr, png_inforp info_ptr,
+    png_const_textp text_ptr, int num_text)
+{
+   int ret;
+   ret = png_set_text_2(png_ptr, info_ptr, text_ptr, num_text);
+
+   if (ret != 0)
+      png_error(png_ptr, "Insufficient memory to store text");
+}
+
+int /* PRIVATE */
+png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr,
+    png_const_textp text_ptr, int num_text)
+{
+   int i;
+
+   png_debug1(1, "in %lx storage function", png_ptr == NULL ? "unexpected" :
+      (unsigned long)png_ptr->chunk_name);
+
+   if (png_ptr == NULL || info_ptr == NULL || num_text <= 0 || text_ptr == NULL)
+      return(0);
+
+   /* Make sure we have enough space in the "text" array in info_struct
+    * to hold all of the incoming text_ptr objects.  This compare can't overflow
+    * because max_text >= num_text (anyway, subtract of two positive integers
+    * can't overflow in any case.)
+    */
+   if (num_text > info_ptr->max_text - info_ptr->num_text)
+   {
+      int old_num_text = info_ptr->num_text;
+      int max_text;
+      png_textp new_text = NULL;
+
+      /* Calculate an appropriate max_text, checking for overflow. */
+      max_text = old_num_text;
+      if (num_text <= INT_MAX - max_text)
+      {
+         max_text += num_text;
+
+         /* Round up to a multiple of 8 */
+         if (max_text < INT_MAX-8)
+            max_text = (max_text + 8) & ~0x7;
+
+         else
+            max_text = INT_MAX;
+
+         /* Now allocate a new array and copy the old members in; this does all
+          * the overflow checks.
+          */
+         new_text = png_voidcast(png_textp,png_realloc_array(png_ptr,
+            info_ptr->text, old_num_text, max_text-old_num_text,
+            sizeof *new_text));
+      }
+
+      if (new_text == NULL)
+      {
+         png_chunk_report(png_ptr, "too many text chunks",
+            PNG_CHUNK_WRITE_ERROR);
+         return 1;
+      }
+
+      png_free(png_ptr, info_ptr->text);
+
+      info_ptr->text = new_text;
+      info_ptr->free_me |= PNG_FREE_TEXT;
+      info_ptr->max_text = max_text;
+      /* num_text is adjusted below as the entries are copied in */
+
+      png_debug1(3, "allocated %d entries for info_ptr->text", max_text);
+   }
+
+   for (i = 0; i < num_text; i++)
+   {
+      size_t text_length, key_len;
+      size_t lang_len, lang_key_len;
+      png_textp textp = &(info_ptr->text[info_ptr->num_text]);
+
+      if (text_ptr[i].key == NULL)
+          continue;
+
+      if (text_ptr[i].compression < PNG_TEXT_COMPRESSION_NONE ||
+          text_ptr[i].compression >= PNG_TEXT_COMPRESSION_LAST)
+      {
+         png_chunk_report(png_ptr, "text compression mode is out of range",
+            PNG_CHUNK_WRITE_ERROR);
+         continue;
+      }
+
+      key_len = strlen(text_ptr[i].key);
+
+      if (text_ptr[i].compression <= 0)
+      {
+         lang_len = 0;
+         lang_key_len = 0;
+      }
+
+      else
+#  ifdef PNG_iTXt_SUPPORTED
+      {
+         /* Set iTXt data */
+
+         if (text_ptr[i].lang != NULL)
+            lang_len = strlen(text_ptr[i].lang);
+
+         else
+            lang_len = 0;
+
+         if (text_ptr[i].lang_key != NULL)
+            lang_key_len = strlen(text_ptr[i].lang_key);
+
+         else
+            lang_key_len = 0;
+      }
+#  else /* PNG_iTXt_SUPPORTED */
+      {
+         png_chunk_report(png_ptr, "iTXt chunk not supported",
+            PNG_CHUNK_WRITE_ERROR);
+         continue;
+      }
+#  endif
+
+      if (text_ptr[i].text == NULL || text_ptr[i].text[0] == '\0')
+      {
+         text_length = 0;
+#  ifdef PNG_iTXt_SUPPORTED
+         if (text_ptr[i].compression > 0)
+            textp->compression = PNG_ITXT_COMPRESSION_NONE;
+
+         else
+#  endif
+            textp->compression = PNG_TEXT_COMPRESSION_NONE;
+      }
+
+      else
+      {
+         text_length = strlen(text_ptr[i].text);
+         textp->compression = text_ptr[i].compression;
+      }
+
+      textp->key = png_voidcast(png_charp,png_malloc_base(png_ptr,
+          key_len + text_length + lang_len + lang_key_len + 4));
+
+      if (textp->key == NULL)
+      {
+         png_chunk_report(png_ptr, "text chunk: out of memory",
+               PNG_CHUNK_WRITE_ERROR);
+         return 1;
+      }
+
+      png_debug2(2, "Allocated %lu bytes at %p in png_set_text",
+          (unsigned long)(png_uint_32)
+          (key_len + lang_len + lang_key_len + text_length + 4),
+          textp->key);
+
+      memcpy(textp->key, text_ptr[i].key, key_len);
+      *(textp->key + key_len) = '\0';
+
+      if (text_ptr[i].compression > 0)
+      {
+         textp->lang = textp->key + key_len + 1;
+         memcpy(textp->lang, text_ptr[i].lang, lang_len);
+         *(textp->lang + lang_len) = '\0';
+         textp->lang_key = textp->lang + lang_len + 1;
+         memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len);
+         *(textp->lang_key + lang_key_len) = '\0';
+         textp->text = textp->lang_key + lang_key_len + 1;
+      }
+
+      else
+      {
+         textp->lang=NULL;
+         textp->lang_key=NULL;
+         textp->text = textp->key + key_len + 1;
+      }
+
+      if (text_length != 0)
+         memcpy(textp->text, text_ptr[i].text, text_length);
+
+      *(textp->text + text_length) = '\0';
+
+#  ifdef PNG_iTXt_SUPPORTED
+      if (textp->compression > 0)
+      {
+         textp->text_length = 0;
+         textp->itxt_length = text_length;
+      }
+
+      else
+#  endif
+      {
+         textp->text_length = text_length;
+         textp->itxt_length = 0;
+      }
+
+      info_ptr->num_text++;
+      png_debug1(3, "transferred text chunk %d", info_ptr->num_text);
+   }
+
+   return(0);
+}
+#endif
+
+#ifdef PNG_tIME_SUPPORTED
+void PNGAPI
+png_set_tIME(png_const_structrp png_ptr, png_inforp info_ptr,
+    png_const_timep mod_time)
+{
+   png_debug1(1, "in %s storage function", "tIME");
+
+   if (png_ptr == NULL || info_ptr == NULL || mod_time == NULL ||
+       (png_ptr->mode & PNG_WROTE_tIME) != 0)
+      return;
+
+   if (mod_time->month == 0   || mod_time->month > 12  ||
+       mod_time->day   == 0   || mod_time->day   > 31  ||
+       mod_time->hour  > 23   || mod_time->minute > 59 ||
+       mod_time->second > 60)
+   {
+      png_warning(png_ptr, "Ignoring invalid time value");
+      return;
+   }
+
+   info_ptr->mod_time = *mod_time;
+   info_ptr->valid |= PNG_INFO_tIME;
+}
+#endif
+
+#ifdef PNG_tRNS_SUPPORTED
+void PNGAPI
+png_set_tRNS(png_structrp png_ptr, png_inforp info_ptr,
+    png_const_bytep trans_alpha, int num_trans, png_const_color_16p trans_color)
+{
+   png_debug1(1, "in %s storage function", "tRNS");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   if (trans_alpha != NULL)
+   {
+       /* It may not actually be necessary to set png_ptr->trans_alpha here;
+        * we do it for backward compatibility with the way the png_handle_tRNS
+        * function used to do the allocation.
+        *
+        * 1.6.0: The above statement is incorrect; png_handle_tRNS effectively
+        * relies on png_set_tRNS storing the information in png_struct
+        * (otherwise it won't be there for the code in pngrtran.c).
+        */
+
+       png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0);
+
+       /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */
+       png_ptr->trans_alpha = info_ptr->trans_alpha = png_voidcast(png_bytep,
+         png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH));
+
+       if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH)
+          memcpy(info_ptr->trans_alpha, trans_alpha, (png_size_t)num_trans);
+   }
+
+   if (trans_color != NULL)
+   {
+      int sample_max = (1 << info_ptr->bit_depth);
+
+      if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY &&
+          trans_color->gray > sample_max) ||
+          (info_ptr->color_type == PNG_COLOR_TYPE_RGB &&
+          (trans_color->red > sample_max ||
+          trans_color->green > sample_max ||
+          trans_color->blue > sample_max)))
+         png_warning(png_ptr,
+            "tRNS chunk has out-of-range samples for bit_depth");
+
+      info_ptr->trans_color = *trans_color;
+
+      if (num_trans == 0)
+         num_trans = 1;
+   }
+
+   info_ptr->num_trans = (png_uint_16)num_trans;
+
+   if (num_trans != 0)
+   {
+      info_ptr->valid |= PNG_INFO_tRNS;
+      info_ptr->free_me |= PNG_FREE_TRNS;
+   }
+}
+#endif
+
+#ifdef PNG_sPLT_SUPPORTED
+void PNGAPI
+png_set_sPLT(png_const_structrp png_ptr,
+    png_inforp info_ptr, png_const_sPLT_tp entries, int nentries)
+/*
+ *  entries        - array of png_sPLT_t structures
+ *                   to be added to the list of palettes
+ *                   in the info structure.
+ *
+ *  nentries       - number of palette structures to be
+ *                   added.
+ */
+{
+   png_sPLT_tp np;
+
+   if (png_ptr == NULL || info_ptr == NULL || nentries <= 0 || entries == NULL)
+      return;
+
+   /* Use the internal realloc function, which checks for all the possible
+    * overflows.  Notice that the parameters are (int) and (size_t)
+    */
+   np = png_voidcast(png_sPLT_tp,png_realloc_array(png_ptr,
+      info_ptr->splt_palettes, info_ptr->splt_palettes_num, nentries,
+      sizeof *np));
+
+   if (np == NULL)
+   {
+      /* Out of memory or too many chunks */
+      png_chunk_report(png_ptr, "too many sPLT chunks", PNG_CHUNK_WRITE_ERROR);
+      return;
+   }
+
+   png_free(png_ptr, info_ptr->splt_palettes);
+   info_ptr->splt_palettes = np;
+   info_ptr->free_me |= PNG_FREE_SPLT;
+
+   np += info_ptr->splt_palettes_num;
+
+   do
+   {
+      png_size_t length;
+
+      /* Skip invalid input entries */
+      if (entries->name == NULL || entries->entries == NULL)
+      {
+         /* png_handle_sPLT doesn't do this, so this is an app error */
+         png_app_error(png_ptr, "png_set_sPLT: invalid sPLT");
+         /* Just skip the invalid entry */
+         continue;
+      }
+
+      np->depth = entries->depth;
+
+      /* In the event of out-of-memory just return - there's no point keeping
+       * on trying to add sPLT chunks.
+       */
+      length = strlen(entries->name) + 1;
+      np->name = png_voidcast(png_charp, png_malloc_base(png_ptr, length));
+
+      if (np->name == NULL)
+         break;
+
+      memcpy(np->name, entries->name, length);
+
+      /* IMPORTANT: we have memory now that won't get freed if something else
+       * goes wrong; this code must free it.  png_malloc_array produces no
+       * warnings; use a png_chunk_report (below) if there is an error.
+       */
+      np->entries = png_voidcast(png_sPLT_entryp, png_malloc_array(png_ptr,
+          entries->nentries, sizeof (png_sPLT_entry)));
+
+      if (np->entries == NULL)
+      {
+         png_free(png_ptr, np->name);
+         np->name = NULL;
+         break;
+      }
+
+      np->nentries = entries->nentries;
+      /* This multiply can't overflow because png_malloc_array has already
+       * checked it when doing the allocation.
+       */
+      memcpy(np->entries, entries->entries,
+         entries->nentries * sizeof (png_sPLT_entry));
+
+      /* Note that 'continue' skips the advance of the out pointer and out
+       * count, so an invalid entry is not added.
+       */
+      info_ptr->valid |= PNG_INFO_sPLT;
+      ++(info_ptr->splt_palettes_num);
+      ++np;
+   }
+   while (++entries, --nentries);
+
+   if (nentries > 0)
+      png_chunk_report(png_ptr, "sPLT out of memory", PNG_CHUNK_WRITE_ERROR);
+}
+#endif /* sPLT */
+
+#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
+static png_byte
+check_location(png_const_structrp png_ptr, int location)
+{
+   location &= (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT);
+
+   /* New in 1.6.0; copy the location and check it.  This is an API
+    * change; previously the app had to use the
+    * png_set_unknown_chunk_location API below for each chunk.
+    */
+   if (location == 0 && (png_ptr->mode & PNG_IS_READ_STRUCT) == 0)
+   {
+      /* Write struct, so unknown chunks come from the app */
+      png_app_warning(png_ptr,
+         "png_set_unknown_chunks now expects a valid location");
+      /* Use the old behavior */
+      location = (png_byte)(png_ptr->mode &
+         (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT));
+   }
+
+   /* This need not be an internal error - if the app calls
+    * png_set_unknown_chunks on a read pointer it must get the location right.
+    */
+   if (location == 0)
+      png_error(png_ptr, "invalid location in png_set_unknown_chunks");
+
+   /* Now reduce the location to the top-most set bit by removing each least
+    * significant bit in turn.
+    */
+   while (location != (location & -location))
+      location &= ~(location & -location);
+
+   /* The cast is safe because 'location' is a bit mask and only the low four
+    * bits are significant.
+    */
+   return (png_byte)location;
+}
+
+void PNGAPI
+png_set_unknown_chunks(png_const_structrp png_ptr,
+   png_inforp info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns)
+{
+   png_unknown_chunkp np;
+
+   if (png_ptr == NULL || info_ptr == NULL || num_unknowns <= 0 ||
+      unknowns == NULL)
+      return;
+
+   /* Check for the failure cases where support has been disabled at compile
+    * time.  This code is hardly ever compiled - it's here because
+    * STORE_UNKNOWN_CHUNKS is set by both read and write code (compiling in this
+    * code) but may be meaningless if the read or write handling of unknown
+    * chunks is not compiled in.
+    */
+#  if !defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) && \
+      defined(PNG_READ_SUPPORTED)
+      if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
+      {
+         png_app_error(png_ptr, "no unknown chunk support on read");
+         return;
+      }
+#  endif
+#  if !defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) && \
+      defined(PNG_WRITE_SUPPORTED)
+      if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0)
+      {
+         png_app_error(png_ptr, "no unknown chunk support on write");
+         return;
+      }
+#  endif
+
+   /* Prior to 1.6.0 this code used png_malloc_warn; however, this meant that
+    * unknown critical chunks could be lost with just a warning resulting in
+    * undefined behavior.  Now png_chunk_report is used to provide behavior
+    * appropriate to read or write.
+    */
+   np = png_voidcast(png_unknown_chunkp, png_realloc_array(png_ptr,
+         info_ptr->unknown_chunks, info_ptr->unknown_chunks_num, num_unknowns,
+         sizeof *np));
+
+   if (np == NULL)
+   {
+      png_chunk_report(png_ptr, "too many unknown chunks",
+         PNG_CHUNK_WRITE_ERROR);
+      return;
+   }
+
+   png_free(png_ptr, info_ptr->unknown_chunks);
+   info_ptr->unknown_chunks = np; /* safe because it is initialized */
+   info_ptr->free_me |= PNG_FREE_UNKN;
+
+   np += info_ptr->unknown_chunks_num;
+
+   /* Increment unknown_chunks_num each time round the loop to protect the
+    * just-allocated chunk data.
+    */
+   for (; num_unknowns > 0; --num_unknowns, ++unknowns)
+   {
+      memcpy(np->name, unknowns->name, (sizeof np->name));
+      np->name[(sizeof np->name)-1] = '\0';
+      np->location = check_location(png_ptr, unknowns->location);
+
+      if (unknowns->size == 0)
+      {
+         np->data = NULL;
+         np->size = 0;
+      }
+
+      else
+      {
+         np->data = png_voidcast(png_bytep,
+            png_malloc_base(png_ptr, unknowns->size));
+
+         if (np->data == NULL)
+         {
+            png_chunk_report(png_ptr, "unknown chunk: out of memory",
+               PNG_CHUNK_WRITE_ERROR);
+            /* But just skip storing the unknown chunk */
+            continue;
+         }
+
+         memcpy(np->data, unknowns->data, unknowns->size);
+         np->size = unknowns->size;
+      }
+
+      /* These increments are skipped on out-of-memory for the data - the
+       * unknown chunk entry gets overwritten if the png_chunk_report returns.
+       * This is correct in the read case (the chunk is just dropped.)
+       */
+      ++np;
+      ++(info_ptr->unknown_chunks_num);
+   }
+}
+
+void PNGAPI
+png_set_unknown_chunk_location(png_const_structrp png_ptr, png_inforp info_ptr,
+    int chunk, int location)
+{
+   /* This API is pretty pointless in 1.6.0 because the location can be set
+    * before the call to png_set_unknown_chunks.
+    *
+    * TODO: add a png_app_warning in 1.7
+    */
+   if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 &&
+      chunk < info_ptr->unknown_chunks_num)
+   {
+      if ((location & (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT)) == 0)
+      {
+         png_app_error(png_ptr, "invalid unknown chunk location");
+         /* Fake out the pre 1.6.0 behavior: */
+         if ((location & PNG_HAVE_IDAT) != 0) /* undocumented! */
+            location = PNG_AFTER_IDAT;
+
+         else
+            location = PNG_HAVE_IHDR; /* also undocumented */
+      }
+
+      info_ptr->unknown_chunks[chunk].location =
+         check_location(png_ptr, location);
+   }
+}
+#endif
+
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+png_uint_32 PNGAPI
+png_permit_mng_features (png_structrp png_ptr, png_uint_32 mng_features)
+{
+   png_debug(1, "in png_permit_mng_features");
+
+   if (png_ptr == NULL)
+      return 0;
+
+   png_ptr->mng_features_permitted = mng_features & PNG_ALL_MNG_FEATURES;
+
+   return png_ptr->mng_features_permitted;
+}
+#endif
+
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+static unsigned int
+add_one_chunk(png_bytep list, unsigned int count, png_const_bytep add, int keep)
+{
+   unsigned int i;
+
+   /* Utility function: update the 'keep' state of a chunk if it is already in
+    * the list, otherwise add it to the list.
+    */
+   for (i=0; i<count; ++i, list += 5)
+   {
+      if (memcmp(list, add, 4) == 0)
+      {
+         list[4] = (png_byte)keep;
+         return count;
+      }
+   }
+
+   if (keep != PNG_HANDLE_CHUNK_AS_DEFAULT)
+   {
+      ++count;
+      memcpy(list, add, 4);
+      list[4] = (png_byte)keep;
+   }
+
+   return count;
+}
+
+void PNGAPI
+png_set_keep_unknown_chunks(png_structrp png_ptr, int keep,
+    png_const_bytep chunk_list, int num_chunks_in)
+{
+   png_bytep new_list;
+   unsigned int num_chunks, old_num_chunks;
+
+   if (png_ptr == NULL)
+      return;
+
+   if (keep < 0 || keep >= PNG_HANDLE_CHUNK_LAST)
+   {
+      png_app_error(png_ptr, "png_set_keep_unknown_chunks: invalid keep");
+      return;
+   }
+
+   if (num_chunks_in <= 0)
+   {
+      png_ptr->unknown_default = keep;
+
+      /* '0' means just set the flags, so stop here */
+      if (num_chunks_in == 0)
+        return;
+   }
+
+   if (num_chunks_in < 0)
+   {
+      /* Ignore all unknown chunks and all chunks recognized by
+       * libpng except for IHDR, PLTE, tRNS, IDAT, and IEND
+       */
+      static PNG_CONST png_byte chunks_to_ignore[] = {
+         98,  75,  71,  68, '\0',  /* bKGD */
+         99,  72,  82,  77, '\0',  /* cHRM */
+        103,  65,  77,  65, '\0',  /* gAMA */
+        104,  73,  83,  84, '\0',  /* hIST */
+        105,  67,  67,  80, '\0',  /* iCCP */
+        105,  84,  88, 116, '\0',  /* iTXt */
+        111,  70,  70, 115, '\0',  /* oFFs */
+        112,  67,  65,  76, '\0',  /* pCAL */
+        112,  72,  89, 115, '\0',  /* pHYs */
+        115,  66,  73,  84, '\0',  /* sBIT */
+        115,  67,  65,  76, '\0',  /* sCAL */
+        115,  80,  76,  84, '\0',  /* sPLT */
+        115,  84,  69,  82, '\0',  /* sTER */
+        115,  82,  71,  66, '\0',  /* sRGB */
+        116,  69,  88, 116, '\0',  /* tEXt */
+        116,  73,  77,  69, '\0',  /* tIME */
+        122,  84,  88, 116, '\0'   /* zTXt */
+      };
+
+      chunk_list = chunks_to_ignore;
+      num_chunks = (unsigned int)/*SAFE*/(sizeof chunks_to_ignore)/5U;
+   }
+
+   else /* num_chunks_in > 0 */
+   {
+      if (chunk_list == NULL)
+      {
+         /* Prior to 1.6.0 this was silently ignored, now it is an app_error
+          * which can be switched off.
+          */
+         png_app_error(png_ptr, "png_set_keep_unknown_chunks: no chunk list");
+         return;
+      }
+
+      num_chunks = num_chunks_in;
+   }
+
+   old_num_chunks = png_ptr->num_chunk_list;
+   if (png_ptr->chunk_list == NULL)
+      old_num_chunks = 0;
+
+   /* Since num_chunks is always restricted to UINT_MAX/5 this can't overflow.
+    */
+   if (num_chunks + old_num_chunks > UINT_MAX/5)
+   {
+      png_app_error(png_ptr, "png_set_keep_unknown_chunks: too many chunks");
+      return;
+   }
+
+   /* If these chunks are being reset to the default then no more memory is
+    * required because add_one_chunk above doesn't extend the list if the 'keep'
+    * parameter is the default.
+    */
+   if (keep != 0)
+   {
+      new_list = png_voidcast(png_bytep, png_malloc(png_ptr,
+          5 * (num_chunks + old_num_chunks)));
+
+      if (old_num_chunks > 0)
+         memcpy(new_list, png_ptr->chunk_list, 5*old_num_chunks);
+   }
+
+   else if (old_num_chunks > 0)
+      new_list = png_ptr->chunk_list;
+
+   else
+      new_list = NULL;
+
+   /* Add the new chunks together with each one's handling code.  If the chunk
+    * already exists the code is updated, otherwise the chunk is added to the
+    * end.  (In libpng 1.6.0 order no longer matters because this code enforces
+    * the earlier convention that the last setting is the one that is used.)
+    */
+   if (new_list != NULL)
+   {
+      png_const_bytep inlist;
+      png_bytep outlist;
+      unsigned int i;
+
+      for (i=0; i<num_chunks; ++i)
+      {
+         old_num_chunks = add_one_chunk(new_list, old_num_chunks,
+            chunk_list+5*i, keep);
+      }
+
+      /* Now remove any spurious 'default' entries. */
+      num_chunks = 0;
+      for (i=0, inlist=outlist=new_list; i<old_num_chunks; ++i, inlist += 5)
+      {
+         if (inlist[4])
+         {
+            if (outlist != inlist)
+               memcpy(outlist, inlist, 5);
+            outlist += 5;
+            ++num_chunks;
+         }
+      }
+
+      /* This means the application has removed all the specialized handling. */
+      if (num_chunks == 0)
+      {
+         if (png_ptr->chunk_list != new_list)
+            png_free(png_ptr, new_list);
+
+         new_list = NULL;
+      }
+   }
+
+   else
+      num_chunks = 0;
+
+   png_ptr->num_chunk_list = num_chunks;
+
+   if (png_ptr->chunk_list != new_list)
+   {
+      if (png_ptr->chunk_list != NULL)
+         png_free(png_ptr, png_ptr->chunk_list);
+
+      png_ptr->chunk_list = new_list;
+   }
+}
+#endif
+
+#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
+void PNGAPI
+png_set_read_user_chunk_fn(png_structrp png_ptr, png_voidp user_chunk_ptr,
+    png_user_chunk_ptr read_user_chunk_fn)
+{
+   png_debug(1, "in png_set_read_user_chunk_fn");
+
+   if (png_ptr == NULL)
+      return;
+
+   png_ptr->read_user_chunk_fn = read_user_chunk_fn;
+   png_ptr->user_chunk_ptr = user_chunk_ptr;
+}
+#endif
+
+#ifdef PNG_INFO_IMAGE_SUPPORTED
+void PNGAPI
+png_set_rows(png_const_structrp png_ptr, png_inforp info_ptr,
+    png_bytepp row_pointers)
+{
+   png_debug1(1, "in %s storage function", "rows");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   if (info_ptr->row_pointers != NULL &&
+       (info_ptr->row_pointers != row_pointers))
+      png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
+
+   info_ptr->row_pointers = row_pointers;
+
+   if (row_pointers != NULL)
+      info_ptr->valid |= PNG_INFO_IDAT;
+}
+#endif
+
+void PNGAPI
+png_set_compression_buffer_size(png_structrp png_ptr, png_size_t size)
+{
+    if (png_ptr == NULL)
+       return;
+
+    if (size == 0 || size > PNG_UINT_31_MAX)
+       png_error(png_ptr, "invalid compression buffer size");
+
+#  ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+      if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
+      {
+         png_ptr->IDAT_read_size = (png_uint_32)size; /* checked above */
+         return;
+      }
+#  endif
+
+#  ifdef PNG_WRITE_SUPPORTED
+      if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0)
+      {
+         if (png_ptr->zowner != 0)
+         {
+            png_warning(png_ptr,
+              "Compression buffer size cannot be changed because it is in use");
+            return;
+         }
+
+         if (size > ZLIB_IO_MAX)
+         {
+            png_warning(png_ptr,
+               "Compression buffer size limited to system maximum");
+            size = ZLIB_IO_MAX; /* must fit */
+         }
+
+         else if (size < 6)
+         {
+            /* Deflate will potentially go into an infinite loop on a SYNC_FLUSH
+             * if this is permitted.
+             */
+            png_warning(png_ptr,
+               "Compression buffer size cannot be reduced below 6");
+            return;
+         }
+
+         if (png_ptr->zbuffer_size != size)
+         {
+            png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list);
+            png_ptr->zbuffer_size = (uInt)size;
+         }
+      }
+#  endif
+}
+
+void PNGAPI
+png_set_invalid(png_const_structrp png_ptr, png_inforp info_ptr, int mask)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+      info_ptr->valid &= ~mask;
+}
+
+
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+/* This function was added to libpng 1.2.6 */
+void PNGAPI
+png_set_user_limits (png_structrp png_ptr, png_uint_32 user_width_max,
+    png_uint_32 user_height_max)
+{
+   /* Images with dimensions larger than these limits will be
+    * rejected by png_set_IHDR().  To accept any PNG datastream
+    * regardless of dimensions, set both limits to 0x7ffffffL.
+    */
+   if (png_ptr == NULL)
+      return;
+
+   png_ptr->user_width_max = user_width_max;
+   png_ptr->user_height_max = user_height_max;
+}
+
+/* This function was added to libpng 1.4.0 */
+void PNGAPI
+png_set_chunk_cache_max (png_structrp png_ptr, png_uint_32 user_chunk_cache_max)
+{
+    if (png_ptr != NULL)
+       png_ptr->user_chunk_cache_max = user_chunk_cache_max;
+}
+
+/* This function was added to libpng 1.4.1 */
+void PNGAPI
+png_set_chunk_malloc_max (png_structrp png_ptr,
+    png_alloc_size_t user_chunk_malloc_max)
+{
+   if (png_ptr != NULL)
+      png_ptr->user_chunk_malloc_max = user_chunk_malloc_max;
+}
+#endif /* ?SET_USER_LIMITS */
+
+
+#ifdef PNG_BENIGN_ERRORS_SUPPORTED
+void PNGAPI
+png_set_benign_errors(png_structrp png_ptr, int allowed)
+{
+   png_debug(1, "in png_set_benign_errors");
+
+   /* If allowed is 1, png_benign_error() is treated as a warning.
+    *
+    * If allowed is 0, png_benign_error() is treated as an error (which
+    * is the default behavior if png_set_benign_errors() is not called).
+    */
+
+   if (allowed != 0)
+      png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN |
+         PNG_FLAG_APP_WARNINGS_WARN | PNG_FLAG_APP_ERRORS_WARN;
+
+   else
+      png_ptr->flags &= ~(PNG_FLAG_BENIGN_ERRORS_WARN |
+         PNG_FLAG_APP_WARNINGS_WARN | PNG_FLAG_APP_ERRORS_WARN);
+}
+#endif /* BENIGN_ERRORS */
+
+#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
+   /* Whether to report invalid palette index; added at libng-1.5.10.
+    * It is possible for an indexed (color-type==3) PNG file to contain
+    * pixels with invalid (out-of-range) indexes if the PLTE chunk has
+    * fewer entries than the image's bit-depth would allow. We recover
+    * from this gracefully by filling any incomplete palette with zeros
+    * (opaque black).  By default, when this occurs libpng will issue
+    * a benign error.  This API can be used to override that behavior.
+    */
+void PNGAPI
+png_set_check_for_invalid_index(png_structrp png_ptr, int allowed)
+{
+   png_debug(1, "in png_set_check_for_invalid_index");
+
+   if (allowed > 0)
+      png_ptr->num_palette_max = 0;
+
+   else
+      png_ptr->num_palette_max = -1;
+}
+#endif
+#endif /* READ || WRITE */
diff --git a/Source/LibPNG/pngstruct.h b/Source/LibPNG/pngstruct.h
index 73d7114..c1dd026 100644
--- a/Source/LibPNG/pngstruct.h
+++ b/Source/LibPNG/pngstruct.h
@@ -1,358 +1,489 @@
-
-/* pngstruct.h - header file for PNG reference library
- *
- * Copyright (c) 1998-2012 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- *
- * Last changed in libpng 1.5.9 [February 18, 2012]
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- */
-
-/* The structure that holds the information to read and write PNG files.
- * The only people who need to care about what is inside of this are the
- * people who will be modifying the library for their own special needs.
- * It should NOT be accessed directly by an application.
- */
-
-#ifndef PNGSTRUCT_H
-#define PNGSTRUCT_H
-/* zlib.h defines the structure z_stream, an instance of which is included
- * in this structure and is required for decompressing the LZ compressed
- * data in PNG files.
- */
-#include "zlib.h"
-
-struct png_struct_def
-{
-#ifdef PNG_SETJMP_SUPPORTED
-   jmp_buf longjmp_buffer;    /* used in png_error */
-   png_longjmp_ptr longjmp_fn;/* setjmp non-local goto function. */
-#endif
-   png_error_ptr error_fn;    /* function for printing errors and aborting */
-#ifdef PNG_WARNINGS_SUPPORTED
-   png_error_ptr warning_fn;  /* function for printing warnings */
-#endif
-   png_voidp error_ptr;       /* user supplied struct for error functions */
-   png_rw_ptr write_data_fn;  /* function for writing output data */
-   png_rw_ptr read_data_fn;   /* function for reading input data */
-   png_voidp io_ptr;          /* ptr to application struct for I/O functions */
-
-#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
-   png_user_transform_ptr read_user_transform_fn; /* user read transform */
-#endif
-
-#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
-   png_user_transform_ptr write_user_transform_fn; /* user write transform */
-#endif
-
-/* These were added in libpng-1.0.2 */
-#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
-#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
-    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
-   png_voidp user_transform_ptr; /* user supplied struct for user transform */
-   png_byte user_transform_depth;    /* bit depth of user transformed pixels */
-   png_byte user_transform_channels; /* channels in user transformed pixels */
-#endif
-#endif
-
-   png_uint_32 mode;          /* tells us where we are in the PNG file */
-   png_uint_32 flags;         /* flags indicating various things to libpng */
-   png_uint_32 transformations; /* which transformations to perform */
-
-   z_stream zstream;          /* pointer to decompression structure (below) */
-   png_bytep zbuf;            /* buffer for zlib */
-   uInt zbuf_size;            /* size of zbuf (typically 65536) */
-#ifdef PNG_WRITE_SUPPORTED
-
-/* Added in 1.5.4: state to keep track of whether the zstream has been
- * initialized and if so whether it is for IDAT or some other chunk.
- */
-#define PNG_ZLIB_UNINITIALIZED 0
-#define PNG_ZLIB_FOR_IDAT      1
-#define PNG_ZLIB_FOR_TEXT      2 /* anything other than IDAT */
-#define PNG_ZLIB_USE_MASK      3 /* bottom two bits */
-#define PNG_ZLIB_IN_USE        4 /* a flag value */
-
-   png_uint_32 zlib_state;       /* State of zlib initialization */
-/* End of material added at libpng 1.5.4 */
-
-   int zlib_level;            /* holds zlib compression level */
-   int zlib_method;           /* holds zlib compression method */
-   int zlib_window_bits;      /* holds zlib compression window bits */
-   int zlib_mem_level;        /* holds zlib compression memory level */
-   int zlib_strategy;         /* holds zlib compression strategy */
-#endif
-/* Added at libpng 1.5.4 */
-#if defined(PNG_WRITE_COMPRESSED_TEXT_SUPPORTED) || \
-    defined(PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED)
-   int zlib_text_level;            /* holds zlib compression level */
-   int zlib_text_method;           /* holds zlib compression method */
-   int zlib_text_window_bits;      /* holds zlib compression window bits */
-   int zlib_text_mem_level;        /* holds zlib compression memory level */
-   int zlib_text_strategy;         /* holds zlib compression strategy */
-#endif
-/* End of material added at libpng 1.5.4 */
-
-   png_uint_32 width;         /* width of image in pixels */
-   png_uint_32 height;        /* height of image in pixels */
-   png_uint_32 num_rows;      /* number of rows in current pass */
-   png_uint_32 usr_width;     /* width of row at start of write */
-   png_size_t rowbytes;       /* size of row in bytes */
-   png_uint_32 iwidth;        /* width of current interlaced row in pixels */
-   png_uint_32 row_number;    /* current row in interlace pass */
-   png_uint_32 chunk_name;    /* PNG_CHUNK() id of current chunk */
-   png_bytep prev_row;        /* buffer to save previous (unfiltered) row.
-                               * This is a pointer into big_prev_row
-                               */
-   png_bytep row_buf;         /* buffer to save current (unfiltered) row.
-                               * This is a pointer into big_row_buf
-                               */
-   png_bytep sub_row;         /* buffer to save "sub" row when filtering */
-   png_bytep up_row;          /* buffer to save "up" row when filtering */
-   png_bytep avg_row;         /* buffer to save "avg" row when filtering */
-   png_bytep paeth_row;       /* buffer to save "Paeth" row when filtering */
-   png_size_t info_rowbytes;  /* Added in 1.5.4: cache of updated row bytes */
-
-   png_uint_32 idat_size;     /* current IDAT size for read */
-   png_uint_32 crc;           /* current chunk CRC value */
-   png_colorp palette;        /* palette from the input file */
-   png_uint_16 num_palette;   /* number of color entries in palette */
-
-/* Added at libpng-1.5.10 */
-#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
-   int num_palette_max;       /* maximum palette index found in IDAT */
-#endif
-
-   png_uint_16 num_trans;     /* number of transparency values */
-   png_byte compression;      /* file compression type (always 0) */
-   png_byte filter;           /* file filter type (always 0) */
-   png_byte interlaced;       /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
-   png_byte pass;             /* current interlace pass (0 - 6) */
-   png_byte do_filter;        /* row filter flags (see PNG_FILTER_ below ) */
-   png_byte color_type;       /* color type of file */
-   png_byte bit_depth;        /* bit depth of file */
-   png_byte usr_bit_depth;    /* bit depth of users row: write only */
-   png_byte pixel_depth;      /* number of bits per pixel */
-   png_byte channels;         /* number of channels in file */
-   png_byte usr_channels;     /* channels at start of write: write only */
-   png_byte sig_bytes;        /* magic bytes read/written from start of file */
-   png_byte maximum_pixel_depth;
-                              /* pixel depth used for the row buffers */
-   png_byte transformed_pixel_depth;
-                              /* pixel depth after read/write transforms */
-   png_byte io_chunk_string[5];
-                              /* string name of chunk */
-
-#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
-   png_uint_16 filler;           /* filler bytes for pixel expansion */
-#endif
-
-#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
-   defined(PNG_READ_ALPHA_MODE_SUPPORTED)
-   png_byte background_gamma_type;
-   png_fixed_point background_gamma;
-   png_color_16 background;   /* background color in screen gamma space */
-#ifdef PNG_READ_GAMMA_SUPPORTED
-   png_color_16 background_1; /* background normalized to gamma 1.0 */
-#endif
-#endif /* PNG_bKGD_SUPPORTED */
-
-#ifdef PNG_WRITE_FLUSH_SUPPORTED
-   png_flush_ptr output_flush_fn; /* Function for flushing output */
-   png_uint_32 flush_dist;    /* how many rows apart to flush, 0 - no flush */
-   png_uint_32 flush_rows;    /* number of rows written since last flush */
-#endif
-
-#ifdef PNG_READ_GAMMA_SUPPORTED
-   int gamma_shift;      /* number of "insignificant" bits in 16-bit gamma */
-   png_fixed_point gamma;        /* file gamma value */
-   png_fixed_point screen_gamma; /* screen gamma value (display_exponent) */
-
-   png_bytep gamma_table;     /* gamma table for 8-bit depth files */
-   png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */
-#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
-   defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
-   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
-   png_bytep gamma_from_1;    /* converts from 1.0 to screen */
-   png_bytep gamma_to_1;      /* converts from file to 1.0 */
-   png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */
-   png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */
-#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
-#endif
-
-#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_sBIT_SUPPORTED)
-   png_color_8 sig_bit;       /* significant bits in each available channel */
-#endif
-
-#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
-   png_color_8 shift;         /* shift for significant bit tranformation */
-#endif
-
-#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \
- || defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
-   png_bytep trans_alpha;           /* alpha values for paletted files */
-   png_color_16 trans_color;  /* transparent color for non-paletted files */
-#endif
-
-   png_read_status_ptr read_row_fn;   /* called after each row is decoded */
-   png_write_status_ptr write_row_fn; /* called after each row is encoded */
-#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
-   png_progressive_info_ptr info_fn; /* called after header data fully read */
-   png_progressive_row_ptr row_fn;   /* called after a prog. row is decoded */
-   png_progressive_end_ptr end_fn;   /* called after image is complete */
-   png_bytep save_buffer_ptr;        /* current location in save_buffer */
-   png_bytep save_buffer;            /* buffer for previously read data */
-   png_bytep current_buffer_ptr;     /* current location in current_buffer */
-   png_bytep current_buffer;         /* buffer for recently used data */
-   png_uint_32 push_length;          /* size of current input chunk */
-   png_uint_32 skip_length;          /* bytes to skip in input data */
-   png_size_t save_buffer_size;      /* amount of data now in save_buffer */
-   png_size_t save_buffer_max;       /* total size of save_buffer */
-   png_size_t buffer_size;           /* total amount of available input data */
-   png_size_t current_buffer_size;   /* amount of data now in current_buffer */
-   int process_mode;                 /* what push library is currently doing */
-   int cur_palette;                  /* current push library palette index */
-
-#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
-
-#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
-/* For the Borland special 64K segment handler */
-   png_bytepp offset_table_ptr;
-   png_bytep offset_table;
-   png_uint_16 offset_table_number;
-   png_uint_16 offset_table_count;
-   png_uint_16 offset_table_count_free;
-#endif
-
-#ifdef PNG_READ_QUANTIZE_SUPPORTED
-   png_bytep palette_lookup; /* lookup table for quantizing */
-   png_bytep quantize_index; /* index translation for palette files */
-#endif
-
-#if defined(PNG_READ_QUANTIZE_SUPPORTED) || defined(PNG_hIST_SUPPORTED)
-   png_uint_16p hist;                /* histogram */
-#endif
-
-#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
-   png_byte heuristic_method;        /* heuristic for row filter selection */
-   png_byte num_prev_filters;        /* number of weights for previous rows */
-   png_bytep prev_filters;           /* filter type(s) of previous row(s) */
-   png_uint_16p filter_weights;      /* weight(s) for previous line(s) */
-   png_uint_16p inv_filter_weights;  /* 1/weight(s) for previous line(s) */
-   png_uint_16p filter_costs;        /* relative filter calculation cost */
-   png_uint_16p inv_filter_costs;    /* 1/relative filter calculation cost */
-#endif
-
-#ifdef PNG_TIME_RFC1123_SUPPORTED
-   /* This is going to be unused in libpng16 and removed from libpng17 */
-   char time_buffer[29]; /* String to hold RFC 1123 time text */
-#endif
-
-/* New members added in libpng-1.0.6 */
-
-   png_uint_32 free_me;    /* flags items libpng is responsible for freeing */
-
-#ifdef PNG_USER_CHUNKS_SUPPORTED
-   png_voidp user_chunk_ptr;
-   png_user_chunk_ptr read_user_chunk_fn; /* user read chunk handler */
-#endif
-
-#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
-   int num_chunk_list;
-   png_bytep chunk_list;
-#endif
-
-#ifdef PNG_READ_sRGB_SUPPORTED
-   /* Added in 1.5.5 to record an sRGB chunk in the png. */
-   png_byte is_sRGB;
-#endif
-
-/* New members added in libpng-1.0.3 */
-#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
-   png_byte rgb_to_gray_status;
-   /* Added in libpng 1.5.5 to record setting of coefficients: */
-   png_byte rgb_to_gray_coefficients_set;
-   /* These were changed from png_byte in libpng-1.0.6 */
-   png_uint_16 rgb_to_gray_red_coeff;
-   png_uint_16 rgb_to_gray_green_coeff;
-   /* deleted in 1.5.5: rgb_to_gray_blue_coeff; */
-#endif
-
-/* New member added in libpng-1.0.4 (renamed in 1.0.9) */
-#if defined(PNG_MNG_FEATURES_SUPPORTED)
-/* Changed from png_byte to png_uint_32 at version 1.2.0 */
-   png_uint_32 mng_features_permitted;
-#endif
-
-/* New member added in libpng-1.0.9, ifdef'ed out in 1.0.12, enabled in 1.2.0 */
-#ifdef PNG_MNG_FEATURES_SUPPORTED
-   png_byte filter_type;
-#endif
-
-/* New members added in libpng-1.2.0 */
-
-/* New members added in libpng-1.0.2 but first enabled by default in 1.2.0 */
-#ifdef PNG_USER_MEM_SUPPORTED
-   png_voidp mem_ptr;             /* user supplied struct for mem functions */
-   png_malloc_ptr malloc_fn;      /* function for allocating memory */
-   png_free_ptr free_fn;          /* function for freeing memory */
-#endif
-
-/* New member added in libpng-1.0.13 and 1.2.0 */
-   png_bytep big_row_buf;         /* buffer to save current (unfiltered) row */
-
-#ifdef PNG_READ_QUANTIZE_SUPPORTED
-/* The following three members were added at version 1.0.14 and 1.2.4 */
-   png_bytep quantize_sort;          /* working sort array */
-   png_bytep index_to_palette;       /* where the original index currently is
-                                        in the palette */
-   png_bytep palette_to_index;       /* which original index points to this
-                                         palette color */
-#endif
-
-/* New members added in libpng-1.0.16 and 1.2.6 */
-   png_byte compression_type;
-
-#ifdef PNG_USER_LIMITS_SUPPORTED
-   png_uint_32 user_width_max;
-   png_uint_32 user_height_max;
-
-   /* Added in libpng-1.4.0: Total number of sPLT, text, and unknown
-    * chunks that can be stored (0 means unlimited).
-    */
-   png_uint_32 user_chunk_cache_max;
-
-   /* Total memory that a zTXt, sPLT, iTXt, iCCP, or unknown chunk
-    * can occupy when decompressed.  0 means unlimited.
-    */
-   png_alloc_size_t user_chunk_malloc_max;
-#endif
-
-/* New member added in libpng-1.0.25 and 1.2.17 */
-#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
-   /* Storage for unknown chunk that the library doesn't recognize. */
-   png_unknown_chunk unknown_chunk;
-#endif
-
-/* New member added in libpng-1.2.26 */
-  png_size_t old_big_row_buf_size;
-
-/* New member added in libpng-1.2.30 */
-  png_charp chunkdata;  /* buffer for reading chunk data */
-
-#ifdef PNG_IO_STATE_SUPPORTED
-/* New member added in libpng-1.4.0 */
-   png_uint_32 io_state;
-#endif
-
-/* New member added in libpng-1.5.6 */
-   png_bytep big_prev_row;
-
-   void (*read_filter[PNG_FILTER_VALUE_LAST-1])(png_row_infop row_info,
-      png_bytep row, png_const_bytep prev_row);
-};
-#endif /* PNGSTRUCT_H */
+
+/* pngstruct.h - header file for PNG reference library
+ *
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * Last changed in libpng 1.6.1 [March 28, 2013]
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+/* The structure that holds the information to read and write PNG files.
+ * The only people who need to care about what is inside of this are the
+ * people who will be modifying the library for their own special needs.
+ * It should NOT be accessed directly by an application.
+ */
+
+#ifndef PNGSTRUCT_H
+#define PNGSTRUCT_H
+/* zlib.h defines the structure z_stream, an instance of which is included
+ * in this structure and is required for decompressing the LZ compressed
+ * data in PNG files.
+ */
+#ifndef ZLIB_CONST
+   /* We must ensure that zlib uses 'const' in declarations. */
+#  define ZLIB_CONST
+#endif
+#include "zlib.h"
+#ifdef const
+   /* zlib.h sometimes #defines const to nothing, undo this. */
+#  undef const
+#endif
+
+/* zlib.h has mediocre z_const use before 1.2.6, this stuff is for compatibility
+ * with older builds.
+ */
+#if ZLIB_VERNUM < 0x1260
+#  define PNGZ_MSG_CAST(s) png_constcast(char*,s)
+#  define PNGZ_INPUT_CAST(b) png_constcast(png_bytep,b)
+#else
+#  define PNGZ_MSG_CAST(s) (s)
+#  define PNGZ_INPUT_CAST(b) (b)
+#endif
+
+/* zlib.h declares a magic type 'uInt' that limits the amount of data that zlib
+ * can handle at once.  This type need be no larger than 16 bits (so maximum of
+ * 65535), this define allows us to discover how big it is, but limited by the
+ * maximuum for png_size_t.  The value can be overriden in a library build
+ * (pngusr.h, or set it in CPPFLAGS) and it works to set it to a considerably
+ * lower value (e.g. 255 works).  A lower value may help memory usage (slightly)
+ * and may even improve performance on some systems (and degrade it on others.)
+ */
+#ifndef ZLIB_IO_MAX
+#  define ZLIB_IO_MAX ((uInt)-1)
+#endif
+
+#ifdef PNG_WRITE_SUPPORTED
+/* The type of a compression buffer list used by the write code. */
+typedef struct png_compression_buffer
+{
+   struct png_compression_buffer *next;
+   png_byte                       output[1]; /* actually zbuf_size */
+} png_compression_buffer, *png_compression_bufferp;
+
+#define PNG_COMPRESSION_BUFFER_SIZE(pp)\
+   (offsetof(png_compression_buffer, output) + (pp)->zbuffer_size)
+#endif
+
+/* Colorspace support; structures used in png_struct, png_info and in internal
+ * functions to hold and communicate information about the color space.
+ *
+ * PNG_COLORSPACE_SUPPORTED is only required if the application will perform
+ * colorspace corrections, otherwise all the colorspace information can be
+ * skipped and the size of libpng can be reduced (significantly) by compiling
+ * out the colorspace support.
+ */
+#ifdef PNG_COLORSPACE_SUPPORTED
+/* The chromaticities of the red, green and blue colorants and the chromaticity
+ * of the corresponding white point (i.e. of rgb(1.0,1.0,1.0)).
+ */
+typedef struct png_xy
+{
+   png_fixed_point redx, redy;
+   png_fixed_point greenx, greeny;
+   png_fixed_point bluex, bluey;
+   png_fixed_point whitex, whitey;
+} png_xy;
+
+/* The same data as above but encoded as CIE XYZ values.  When this data comes
+ * from chromaticities the sum of the Y values is assumed to be 1.0
+ */
+typedef struct png_XYZ
+{
+   png_fixed_point red_X, red_Y, red_Z;
+   png_fixed_point green_X, green_Y, green_Z;
+   png_fixed_point blue_X, blue_Y, blue_Z;
+} png_XYZ;
+#endif /* COLORSPACE */
+
+#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED)
+/* A colorspace is all the above plus, potentially, profile information,
+ * however at present libpng does not use the profile internally so it is only
+ * stored in the png_info struct (if iCCP is supported.)  The rendering intent
+ * is retained here and is checked.
+ *
+ * The file gamma encoding information is also stored here and gamma correction
+ * is done by libpng, whereas color correction must currently be done by the
+ * application.
+ */
+typedef struct png_colorspace
+{
+#ifdef PNG_GAMMA_SUPPORTED
+   png_fixed_point gamma;        /* File gamma */
+#endif
+
+#ifdef PNG_COLORSPACE_SUPPORTED
+   png_xy      end_points_xy;    /* End points as chromaticities */
+   png_XYZ     end_points_XYZ;   /* End points as CIE XYZ colorant values */
+   png_uint_16 rendering_intent; /* Rendering intent of a profile */
+#endif
+
+   /* Flags are always defined to simplify the code. */
+   png_uint_16 flags;            /* As defined below */
+} png_colorspace, * PNG_RESTRICT png_colorspacerp;
+
+typedef const png_colorspace * PNG_RESTRICT png_const_colorspacerp;
+
+/* General flags for the 'flags' field */
+#define PNG_COLORSPACE_HAVE_GAMMA           0x0001
+#define PNG_COLORSPACE_HAVE_ENDPOINTS       0x0002
+#define PNG_COLORSPACE_HAVE_INTENT          0x0004
+#define PNG_COLORSPACE_FROM_gAMA            0x0008
+#define PNG_COLORSPACE_FROM_cHRM            0x0010
+#define PNG_COLORSPACE_FROM_sRGB            0x0020
+#define PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB 0x0040
+#define PNG_COLORSPACE_MATCHES_sRGB         0x0080 /* exact match on profile */
+#define PNG_COLORSPACE_INVALID              0x8000
+#define PNG_COLORSPACE_CANCEL(flags)        (0xffff ^ (flags))
+#endif /* COLORSPACE || GAMMA */
+
+struct png_struct_def
+{
+#ifdef PNG_SETJMP_SUPPORTED
+   jmp_buf jmp_buf_local;     /* New name in 1.6.0 for jmp_buf in png_struct */
+   png_longjmp_ptr longjmp_fn;/* setjmp non-local goto function. */
+   jmp_buf *jmp_buf_ptr;      /* passed to longjmp_fn */
+   size_t jmp_buf_size;       /* size of the above, if allocated */
+#endif
+   png_error_ptr error_fn;    /* function for printing errors and aborting */
+#ifdef PNG_WARNINGS_SUPPORTED
+   png_error_ptr warning_fn;  /* function for printing warnings */
+#endif
+   png_voidp error_ptr;       /* user supplied struct for error functions */
+   png_rw_ptr write_data_fn;  /* function for writing output data */
+   png_rw_ptr read_data_fn;   /* function for reading input data */
+   png_voidp io_ptr;          /* ptr to application struct for I/O functions */
+
+#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
+   png_user_transform_ptr read_user_transform_fn; /* user read transform */
+#endif
+
+#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
+   png_user_transform_ptr write_user_transform_fn; /* user write transform */
+#endif
+
+/* These were added in libpng-1.0.2 */
+#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+   png_voidp user_transform_ptr; /* user supplied struct for user transform */
+   png_byte user_transform_depth;    /* bit depth of user transformed pixels */
+   png_byte user_transform_channels; /* channels in user transformed pixels */
+#endif
+#endif
+
+   png_uint_32 mode;          /* tells us where we are in the PNG file */
+   png_uint_32 flags;         /* flags indicating various things to libpng */
+   png_uint_32 transformations; /* which transformations to perform */
+
+   png_uint_32 zowner;        /* ID (chunk type) of zstream owner, 0 if none */
+   z_stream    zstream;       /* decompression structure */
+
+#ifdef PNG_WRITE_SUPPORTED
+   png_compression_bufferp zbuffer_list; /* Created on demand during write */
+   uInt                    zbuffer_size; /* size of the actual buffer */
+
+   int zlib_level;            /* holds zlib compression level */
+   int zlib_method;           /* holds zlib compression method */
+   int zlib_window_bits;      /* holds zlib compression window bits */
+   int zlib_mem_level;        /* holds zlib compression memory level */
+   int zlib_strategy;         /* holds zlib compression strategy */
+#endif
+/* Added at libpng 1.5.4 */
+#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
+   int zlib_text_level;            /* holds zlib compression level */
+   int zlib_text_method;           /* holds zlib compression method */
+   int zlib_text_window_bits;      /* holds zlib compression window bits */
+   int zlib_text_mem_level;        /* holds zlib compression memory level */
+   int zlib_text_strategy;         /* holds zlib compression strategy */
+#endif
+/* End of material added at libpng 1.5.4 */
+/* Added at libpng 1.6.0 */
+#ifdef PNG_WRITE_SUPPORTED
+   int zlib_set_level;        /* Actual values set into the zstream on write */
+   int zlib_set_method;
+   int zlib_set_window_bits;
+   int zlib_set_mem_level;
+   int zlib_set_strategy;
+#endif
+
+   png_uint_32 width;         /* width of image in pixels */
+   png_uint_32 height;        /* height of image in pixels */
+   png_uint_32 num_rows;      /* number of rows in current pass */
+   png_uint_32 usr_width;     /* width of row at start of write */
+   png_size_t rowbytes;       /* size of row in bytes */
+   png_uint_32 iwidth;        /* width of current interlaced row in pixels */
+   png_uint_32 row_number;    /* current row in interlace pass */
+   png_uint_32 chunk_name;    /* PNG_CHUNK() id of current chunk */
+   png_bytep prev_row;        /* buffer to save previous (unfiltered) row.
+                               * This is a pointer into big_prev_row
+                               */
+   png_bytep row_buf;         /* buffer to save current (unfiltered) row.
+                               * This is a pointer into big_row_buf
+                               */
+#ifdef PNG_WRITE_SUPPORTED
+   png_bytep sub_row;         /* buffer to save "sub" row when filtering */
+   png_bytep up_row;          /* buffer to save "up" row when filtering */
+   png_bytep avg_row;         /* buffer to save "avg" row when filtering */
+   png_bytep paeth_row;       /* buffer to save "Paeth" row when filtering */
+#endif
+   png_size_t info_rowbytes;  /* Added in 1.5.4: cache of updated row bytes */
+
+   png_uint_32 idat_size;     /* current IDAT size for read */
+   png_uint_32 crc;           /* current chunk CRC value */
+   png_colorp palette;        /* palette from the input file */
+   png_uint_16 num_palette;   /* number of color entries in palette */
+
+/* Added at libpng-1.5.10 */
+#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
+   int num_palette_max;       /* maximum palette index found in IDAT */
+#endif
+
+   png_uint_16 num_trans;     /* number of transparency values */
+   png_byte compression;      /* file compression type (always 0) */
+   png_byte filter;           /* file filter type (always 0) */
+   png_byte interlaced;       /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
+   png_byte pass;             /* current interlace pass (0 - 6) */
+   png_byte do_filter;        /* row filter flags (see PNG_FILTER_ below ) */
+   png_byte color_type;       /* color type of file */
+   png_byte bit_depth;        /* bit depth of file */
+   png_byte usr_bit_depth;    /* bit depth of users row: write only */
+   png_byte pixel_depth;      /* number of bits per pixel */
+   png_byte channels;         /* number of channels in file */
+#ifdef PNG_WRITE_SUPPORTED
+   png_byte usr_channels;     /* channels at start of write: write only */
+#endif
+   png_byte sig_bytes;        /* magic bytes read/written from start of file */
+   png_byte maximum_pixel_depth;
+                              /* pixel depth used for the row buffers */
+   png_byte transformed_pixel_depth;
+                              /* pixel depth after read/write transforms */
+#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
+   png_uint_16 filler;           /* filler bytes for pixel expansion */
+#endif
+
+#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
+   defined(PNG_READ_ALPHA_MODE_SUPPORTED)
+   png_byte background_gamma_type;
+   png_fixed_point background_gamma;
+   png_color_16 background;   /* background color in screen gamma space */
+#ifdef PNG_READ_GAMMA_SUPPORTED
+   png_color_16 background_1; /* background normalized to gamma 1.0 */
+#endif
+#endif /* bKGD */
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+   png_flush_ptr output_flush_fn; /* Function for flushing output */
+   png_uint_32 flush_dist;    /* how many rows apart to flush, 0 - no flush */
+   png_uint_32 flush_rows;    /* number of rows written since last flush */
+#endif
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+   int gamma_shift;      /* number of "insignificant" bits in 16-bit gamma */
+   png_fixed_point screen_gamma; /* screen gamma value (display_exponent) */
+
+   png_bytep gamma_table;     /* gamma table for 8-bit depth files */
+   png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
+   defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
+   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+   png_bytep gamma_from_1;    /* converts from 1.0 to screen */
+   png_bytep gamma_to_1;      /* converts from file to 1.0 */
+   png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */
+   png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */
+#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_sBIT_SUPPORTED)
+   png_color_8 sig_bit;       /* significant bits in each available channel */
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
+   png_color_8 shift;         /* shift for significant bit tranformation */
+#endif
+
+#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \
+ || defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+   png_bytep trans_alpha;           /* alpha values for paletted files */
+   png_color_16 trans_color;  /* transparent color for non-paletted files */
+#endif
+
+   png_read_status_ptr read_row_fn;   /* called after each row is decoded */
+   png_write_status_ptr write_row_fn; /* called after each row is encoded */
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+   png_progressive_info_ptr info_fn; /* called after header data fully read */
+   png_progressive_row_ptr row_fn;   /* called after a prog. row is decoded */
+   png_progressive_end_ptr end_fn;   /* called after image is complete */
+   png_bytep save_buffer_ptr;        /* current location in save_buffer */
+   png_bytep save_buffer;            /* buffer for previously read data */
+   png_bytep current_buffer_ptr;     /* current location in current_buffer */
+   png_bytep current_buffer;         /* buffer for recently used data */
+   png_uint_32 push_length;          /* size of current input chunk */
+   png_uint_32 skip_length;          /* bytes to skip in input data */
+   png_size_t save_buffer_size;      /* amount of data now in save_buffer */
+   png_size_t save_buffer_max;       /* total size of save_buffer */
+   png_size_t buffer_size;           /* total amount of available input data */
+   png_size_t current_buffer_size;   /* amount of data now in current_buffer */
+   int process_mode;                 /* what push library is currently doing */
+   int cur_palette;                  /* current push library palette index */
+
+#endif /* PROGRESSIVE_READ */
+
+#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
+/* For the Borland special 64K segment handler */
+   png_bytepp offset_table_ptr;
+   png_bytep offset_table;
+   png_uint_16 offset_table_number;
+   png_uint_16 offset_table_count;
+   png_uint_16 offset_table_count_free;
+#endif
+
+#ifdef PNG_READ_QUANTIZE_SUPPORTED
+   png_bytep palette_lookup; /* lookup table for quantizing */
+   png_bytep quantize_index; /* index translation for palette files */
+#endif
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+   png_byte heuristic_method;        /* heuristic for row filter selection */
+   png_byte num_prev_filters;        /* number of weights for previous rows */
+   png_bytep prev_filters;           /* filter type(s) of previous row(s) */
+   png_uint_16p filter_weights;      /* weight(s) for previous line(s) */
+   png_uint_16p inv_filter_weights;  /* 1/weight(s) for previous line(s) */
+   png_uint_16p filter_costs;        /* relative filter calculation cost */
+   png_uint_16p inv_filter_costs;    /* 1/relative filter calculation cost */
+#endif
+
+   /* Options */
+#ifdef PNG_SET_OPTION_SUPPORTED
+   png_byte options;           /* On/off state (up to 4 options) */
+#endif
+
+#if PNG_LIBPNG_VER < 10700
+/* To do: remove this from libpng-1.7 */
+#ifdef PNG_TIME_RFC1123_SUPPORTED
+   char time_buffer[29]; /* String to hold RFC 1123 time text */
+#endif
+#endif
+
+/* New members added in libpng-1.0.6 */
+
+   png_uint_32 free_me;    /* flags items libpng is responsible for freeing */
+
+#ifdef PNG_USER_CHUNKS_SUPPORTED
+   png_voidp user_chunk_ptr;
+#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
+   png_user_chunk_ptr read_user_chunk_fn; /* user read chunk handler */
+#endif
+#endif
+
+#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
+   int          unknown_default; /* As PNG_HANDLE_* */
+   unsigned int num_chunk_list;  /* Number of entries in the list */
+   png_bytep    chunk_list;      /* List of png_byte[5]; the textual chunk name
+                                  * followed by a PNG_HANDLE_* byte */
+#endif
+
+/* New members added in libpng-1.0.3 */
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+   png_byte rgb_to_gray_status;
+   /* Added in libpng 1.5.5 to record setting of coefficients: */
+   png_byte rgb_to_gray_coefficients_set;
+   /* These were changed from png_byte in libpng-1.0.6 */
+   png_uint_16 rgb_to_gray_red_coeff;
+   png_uint_16 rgb_to_gray_green_coeff;
+   /* deleted in 1.5.5: rgb_to_gray_blue_coeff; */
+#endif
+
+/* New member added in libpng-1.0.4 (renamed in 1.0.9) */
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+/* Changed from png_byte to png_uint_32 at version 1.2.0 */
+   png_uint_32 mng_features_permitted;
+#endif
+
+/* New member added in libpng-1.0.9, ifdef'ed out in 1.0.12, enabled in 1.2.0 */
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+   png_byte filter_type;
+#endif
+
+/* New members added in libpng-1.2.0 */
+
+/* New members added in libpng-1.0.2 but first enabled by default in 1.2.0 */
+#ifdef PNG_USER_MEM_SUPPORTED
+   png_voidp mem_ptr;             /* user supplied struct for mem functions */
+   png_malloc_ptr malloc_fn;      /* function for allocating memory */
+   png_free_ptr free_fn;          /* function for freeing memory */
+#endif
+
+/* New member added in libpng-1.0.13 and 1.2.0 */
+   png_bytep big_row_buf;         /* buffer to save current (unfiltered) row */
+
+#ifdef PNG_READ_QUANTIZE_SUPPORTED
+/* The following three members were added at version 1.0.14 and 1.2.4 */
+   png_bytep quantize_sort;          /* working sort array */
+   png_bytep index_to_palette;       /* where the original index currently is
+                                        in the palette */
+   png_bytep palette_to_index;       /* which original index points to this
+                                         palette color */
+#endif
+
+/* New members added in libpng-1.0.16 and 1.2.6 */
+   png_byte compression_type;
+
+#ifdef PNG_USER_LIMITS_SUPPORTED
+   png_uint_32 user_width_max;
+   png_uint_32 user_height_max;
+
+   /* Added in libpng-1.4.0: Total number of sPLT, text, and unknown
+    * chunks that can be stored (0 means unlimited).
+    */
+   png_uint_32 user_chunk_cache_max;
+
+   /* Total memory that a zTXt, sPLT, iTXt, iCCP, or unknown chunk
+    * can occupy when decompressed.  0 means unlimited.
+    */
+   png_alloc_size_t user_chunk_malloc_max;
+#endif
+
+/* New member added in libpng-1.0.25 and 1.2.17 */
+#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
+   /* Temporary storage for unknown chunk that the library doesn't recognize,
+    * used while reading the chunk.
+    */
+   png_unknown_chunk unknown_chunk;
+#endif
+
+/* New member added in libpng-1.2.26 */
+  png_size_t old_big_row_buf_size;
+
+#ifdef PNG_READ_SUPPORTED
+/* New member added in libpng-1.2.30 */
+  png_bytep        read_buffer;      /* buffer for reading chunk data */
+  png_alloc_size_t read_buffer_size; /* current size of the buffer */
+#endif
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+  uInt             IDAT_read_size;   /* limit on read buffer size for IDAT */
+#endif
+
+#ifdef PNG_IO_STATE_SUPPORTED
+/* New member added in libpng-1.4.0 */
+   png_uint_32 io_state;
+#endif
+
+/* New member added in libpng-1.5.6 */
+   png_bytep big_prev_row;
+
+/* New member added in libpng-1.5.7 */
+   void (*read_filter[PNG_FILTER_VALUE_LAST-1])(png_row_infop row_info,
+      png_bytep row, png_const_bytep prev_row);
+
+#ifdef PNG_READ_SUPPORTED
+#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED)
+   png_colorspace   colorspace;
+#endif
+#endif
+};
+#endif /* PNGSTRUCT_H */
diff --git a/Source/LibPNG/pngtest.c b/Source/LibPNG/pngtest.c
index 5594333..dbf51a8 100644
--- a/Source/LibPNG/pngtest.c
+++ b/Source/LibPNG/pngtest.c
@@ -1,8 +1,8 @@
 
 /* pngtest.c - a simple test program to test libpng
  *
- * Last changed in libpng 1.5.6 [November 3, 2011]
- * Copyright (c) 1998-2011 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.15 [November 20, 2014]
+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -33,16 +33,50 @@
 
 #define _POSIX_SOURCE 1
 
-#include "zlib.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* Defined so I can write to a file on gui/windowing platforms */
+/*  #define STDERR stderr  */
+#define STDERR stdout   /* For DOS */
+
 #include "png.h"
+
+/* Known chunks that exist in pngtest.png must be supported or pngtest will fail
+ * simply as a result of re-ordering them.  This may be fixed in 1.7
+ *
+ * pngtest allocates a single row buffer for each row and overwrites it,
+ * therefore if the write side doesn't support the writing of interlaced images
+ * nothing can be done for an interlaced image (and the code below will fail
+ * horribly trying to write extra data after writing garbage).
+ */
+#if defined PNG_READ_SUPPORTED && /* else nothing can be done */\
+   defined PNG_READ_bKGD_SUPPORTED &&\
+   defined PNG_READ_cHRM_SUPPORTED &&\
+   defined PNG_READ_gAMA_SUPPORTED &&\
+   defined PNG_READ_oFFs_SUPPORTED &&\
+   defined PNG_READ_pCAL_SUPPORTED &&\
+   defined PNG_READ_pHYs_SUPPORTED &&\
+   defined PNG_READ_sBIT_SUPPORTED &&\
+   defined PNG_READ_sCAL_SUPPORTED &&\
+   defined PNG_READ_sRGB_SUPPORTED &&\
+   defined PNG_READ_tEXt_SUPPORTED &&\
+   defined PNG_READ_tIME_SUPPORTED &&\
+   defined PNG_READ_zTXt_SUPPORTED &&\
+   defined PNG_WRITE_INTERLACING_SUPPORTED
+
+#ifdef PNG_ZLIB_HEADER
+#  include PNG_ZLIB_HEADER /* defined by pnglibconf.h from 1.7 */
+#else
+#  include "zlib.h"
+#endif
+
 /* Copied from pngpriv.h but only used in error messages below. */
 #ifndef PNG_ZBUF_SIZE
 #  define PNG_ZBUF_SIZE 8192
 #endif
-#  include <stdio.h>
-#  include <stdlib.h>
-#  include <string.h>
-#  define FCLOSE(file) fclose(file)
+#define FCLOSE(file) fclose(file)
 
 #ifndef PNG_STDIO_SUPPORTED
 typedef FILE                * png_FILE_p;
@@ -67,17 +101,6 @@ typedef FILE                * png_FILE_p;
 #  define SINGLE_ROWBUF_ALLOC  /* Makes buffer overruns easier to nail */
 #endif
 
-/* The code uses memcmp and memcpy on large objects (typically row pointers) so
- * it is necessary to do soemthing special on certain architectures, note that
- * the actual support for this was effectively removed in 1.4, so only the
- * memory remains in this program:
- */
-#define CVT_PTR(ptr)         (ptr)
-#define CVT_PTR_NOCHECK(ptr) (ptr)
-#define png_memcmp  memcmp
-#define png_memcpy  memcpy
-#define png_memset  memset
-
 /* Turn on CPU timing
 #define PNGTEST_TIMING
 */
@@ -99,30 +122,33 @@ static char tIME_string[PNG_tIME_STRING_LENGTH] = "tIME chunk is not present";
 
 static int verbose = 0;
 static int strict = 0;
-
-int test_one_file PNGARG((PNG_CONST char *inname, PNG_CONST char *outname));
-
-#ifdef __TURBOC__
-#include <mem.h>
-#endif
-
-/* Defined so I can write to a file on gui/windowing platforms */
-/*  #define STDERR stderr  */
-#define STDERR stdout   /* For DOS */
+static int relaxed = 0;
+static int unsupported_chunks = 0; /* chunk unsupported by libpng in input */
+static int error_count = 0; /* count calls to png_error */
+static int warning_count = 0; /* count calls to png_warning */
 
 /* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */
 #ifndef png_jmpbuf
 #  define png_jmpbuf(png_ptr) png_ptr->jmpbuf
 #endif
 
+/* Defines for unknown chunk handling if required. */
+#ifndef PNG_HANDLE_CHUNK_ALWAYS
+#  define PNG_HANDLE_CHUNK_ALWAYS       3
+#endif
+#ifndef PNG_HANDLE_CHUNK_IF_SAFE
+#  define PNG_HANDLE_CHUNK_IF_SAFE      2
+#endif
+
+/* Utility to save typing/errors, the argument must be a name */
+#define MEMZERO(var) ((void)memset(&var, 0, sizeof var))
+
 /* Example of using row callbacks to make a simple progress meter */
 static int status_pass = 1;
 static int status_dots_requested = 0;
 static int status_dots = 1;
 
-void PNGCBAPI
-read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass);
-void PNGCBAPI
+static void PNGCBAPI
 read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
 {
    if (png_ptr == NULL || row_number > PNG_UINT_31_MAX)
@@ -146,9 +172,8 @@ read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
    fprintf(stdout, "r");
 }
 
-void PNGCBAPI
-write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass);
-void PNGCBAPI
+#ifdef PNG_WRITE_SUPPORTED
+static void PNGCBAPI
 write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
 {
    if (png_ptr == NULL || row_number > PNG_UINT_31_MAX || pass > 7)
@@ -156,6 +181,7 @@ write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
 
    fprintf(stdout, "w");
 }
+#endif
 
 
 #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
@@ -164,9 +190,7 @@ write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
  * 5 in case illegal filter values are present.)
  */
 static png_uint_32 filters_used[256];
-void PNGCBAPI
-count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data);
-void PNGCBAPI
+static void PNGCBAPI
 count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data)
 {
    if (png_ptr != NULL && row_info != NULL)
@@ -181,9 +205,7 @@ count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data)
 
 static png_uint_32 zero_samples;
 
-void PNGCBAPI
-count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data);
-void PNGCBAPI
+static void PNGCBAPI
 count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data)
 {
    png_bytep dp = data;
@@ -261,7 +283,8 @@ count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data)
        png_uint_32 n, nstop;
        int channel;
        int color_channels = row_info->channels;
-       if (row_info->color_type > 3)color_channels--;
+       if (row_info->color_type > 3)
+          color_channels--;
 
        for (n = 0, nstop=row_info->width; n<nstop; n++)
        {
@@ -288,9 +311,7 @@ count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data)
        }
     }
 }
-#endif /* PNG_WRITE_USER_TRANSFORM_SUPPORTED */
-
-static int wrote_question = 0;
+#endif /* WRITE_USER_TRANSFORM */
 
 #ifndef PNG_STDIO_SUPPORTED
 /* START of code to validate stdio-free compilation */
@@ -339,12 +360,11 @@ pngtest_check_io_state(png_structp png_ptr, png_size_t data_length,
    default:
       err = 1;  /* uninitialized */
    }
-   if (err)
+   if (err != 0)
       png_error(png_ptr, "Bad I/O state or buffer size");
 }
 #endif
 
-#ifndef USE_FAR_KEYWORD
 static void PNGCBAPI
 pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
 {
@@ -369,59 +389,6 @@ pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
    pngtest_check_io_state(png_ptr, length, PNG_IO_READING);
 #endif
 }
-#else
-/* This is the model-independent version. Since the standard I/O library
-   can't handle far buffers in the medium and small models, we have to copy
-   the data.
-*/
-
-#define NEAR_BUF_SIZE 1024
-#define MIN(a,b) (a <= b ? a : b)
-
-static void PNGCBAPI
-pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
-{
-   png_size_t check;
-   png_byte *n_data;
-   png_FILE_p io_ptr;
-
-   /* Check if data really is near. If so, use usual code. */
-   n_data = (png_byte *)CVT_PTR_NOCHECK(data);
-   io_ptr = (png_FILE_p)CVT_PTR(png_get_io_ptr(png_ptr));
-   if ((png_bytep)n_data == data)
-   {
-      check = fread(n_data, 1, length, io_ptr);
-   }
-   else
-   {
-      png_byte buf[NEAR_BUF_SIZE];
-      png_size_t read, remaining, err;
-      check = 0;
-      remaining = length;
-
-      do
-      {
-         read = MIN(NEAR_BUF_SIZE, remaining);
-         err = fread(buf, 1, 1, io_ptr);
-         png_memcpy(data, buf, read); /* Copy far buffer to near buffer */
-         if (err != read)
-            break;
-         else
-            check += err;
-         data += read;
-         remaining -= read;
-      }
-      while (remaining != 0);
-   }
-
-   if (check != length)
-      png_error(png_ptr, "Read Error");
-
-#ifdef PNG_IO_STATE_SUPPORTED
-   pngtest_check_io_state(png_ptr, length, PNG_IO_READING);
-#endif
-}
-#endif /* USE_FAR_KEYWORD */
 
 #ifdef PNG_WRITE_FLUSH_SUPPORTED
 static void PNGCBAPI
@@ -437,7 +404,6 @@ pngtest_flush(png_structp png_ptr)
  * write_data function and use it at run time with png_set_write_fn(), rather
  * than changing the library.
  */
-#ifndef USE_FAR_KEYWORD
 static void PNGCBAPI
 pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
 {
@@ -454,81 +420,31 @@ pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
    pngtest_check_io_state(png_ptr, length, PNG_IO_WRITING);
 #endif
 }
-#else
-/* This is the model-independent version. Since the standard I/O library
-   can't handle far buffers in the medium and small models, we have to copy
-   the data.
-*/
-
-#define NEAR_BUF_SIZE 1024
-#define MIN(a,b) (a <= b ? a : b)
-
-static void PNGCBAPI
-pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
-{
-   png_size_t check;
-   png_byte *near_data;  /* Needs to be "png_byte *" instead of "png_bytep" */
-   png_FILE_p io_ptr;
-
-   /* Check if data really is near. If so, use usual code. */
-   near_data = (png_byte *)CVT_PTR_NOCHECK(data);
-   io_ptr = (png_FILE_p)CVT_PTR(png_get_io_ptr(png_ptr));
-
-   if ((png_bytep)near_data == data)
-   {
-      check = fwrite(near_data, 1, length, io_ptr);
-   }
-
-   else
-   {
-      png_byte buf[NEAR_BUF_SIZE];
-      png_size_t written, remaining, err;
-      check = 0;
-      remaining = length;
-
-      do
-      {
-         written = MIN(NEAR_BUF_SIZE, remaining);
-         png_memcpy(buf, data, written); /* Copy far buffer to near buffer */
-         err = fwrite(buf, 1, written, io_ptr);
-         if (err != written)
-            break;
-         else
-            check += err;
-         data += written;
-         remaining -= written;
-      }
-      while (remaining != 0);
-   }
-
-   if (check != length)
-   {
-      png_error(png_ptr, "Write Error");
-   }
-
-#ifdef PNG_IO_STATE_SUPPORTED
-   pngtest_check_io_state(png_ptr, length, PNG_IO_WRITING);
-#endif
-}
-#endif /* USE_FAR_KEYWORD */
+#endif /* !STDIO */
 
 /* This function is called when there is a warning, but the library thinks
  * it can continue anyway.  Replacement functions don't have to do anything
  * here if you don't want to.  In the default configuration, png_ptr is
  * not used, but it is passed in case it may be useful.
  */
+typedef struct
+{
+   PNG_CONST char *file_name;
+}  pngtest_error_parameters;
+
 static void PNGCBAPI
 pngtest_warning(png_structp png_ptr, png_const_charp message)
 {
    PNG_CONST char *name = "UNKNOWN (ERROR!)";
-   char *test;
-   test = png_get_error_ptr(png_ptr);
+   pngtest_error_parameters *test =
+      (pngtest_error_parameters*)png_get_error_ptr(png_ptr);
 
-   if (test == NULL)
-     fprintf(STDERR, "%s: libpng warning: %s\n", name, message);
+   ++warning_count;
 
-   else
-     fprintf(STDERR, "%s: libpng warning: %s\n", test, message);
+   if (test != NULL && test->file_name != NULL)
+      name = test->file_name;
+
+   fprintf(STDERR, "%s: libpng warning: %s\n", name, message);
 }
 
 /* This is the default error handling function.  Note that replacements for
@@ -539,12 +455,14 @@ pngtest_warning(png_structp png_ptr, png_const_charp message)
 static void PNGCBAPI
 pngtest_error(png_structp png_ptr, png_const_charp message)
 {
+   ++error_count;
+
    pngtest_warning(png_ptr, message);
    /* We can return because png_error calls the default handler, which is
     * actually OK in this case.
     */
 }
-#endif /* !PNG_STDIO_SUPPORTED */
+
 /* END of code to validate stdio-free compilation */
 
 /* START of code to validate memory allocation and deallocation */
@@ -563,9 +481,9 @@ typedef struct memory_information
 {
    png_alloc_size_t          size;
    png_voidp                 pointer;
-   struct memory_information FAR *next;
+   struct memory_information *next;
 } memory_information;
-typedef memory_information FAR *memory_infop;
+typedef memory_information *memory_infop;
 
 static memory_infop pinformation = NULL;
 static int current_allocation = 0;
@@ -595,7 +513,7 @@ PNGCBAPI png_debug_malloc(png_structp png_ptr, png_alloc_size_t size)
       memory_infop pinfo;
       png_set_mem_fn(png_ptr, NULL, NULL, NULL);
       pinfo = (memory_infop)png_malloc(png_ptr,
-         png_sizeof(*pinfo));
+         (sizeof *pinfo));
       pinfo->size = size;
       current_allocation += size;
       total_allocation += size;
@@ -621,9 +539,9 @@ PNGCBAPI png_debug_malloc(png_structp png_ptr, png_alloc_size_t size)
       pinfo->next = pinformation;
       pinformation = pinfo;
       /* Make sure the caller isn't assuming zeroed memory. */
-      png_memset(pinfo->pointer, 0xdd, pinfo->size);
+      memset(pinfo->pointer, 0xdd, pinfo->size);
 
-      if (verbose)
+      if (verbose != 0)
          printf("png_malloc %lu bytes at %p\n", (unsigned long)size,
             pinfo->pointer);
 
@@ -648,7 +566,7 @@ png_debug_free(png_structp png_ptr, png_voidp ptr)
 
    /* Unlink the element from the list. */
    {
-      memory_infop FAR *ppinfo = &pinformation;
+      memory_infop *ppinfo = &pinformation;
 
       for (;;)
       {
@@ -662,15 +580,16 @@ png_debug_free(png_structp png_ptr, png_voidp ptr)
                fprintf(STDERR, "Duplicate free of memory\n");
             /* We must free the list element too, but first kill
                the memory that is to be freed. */
-            png_memset(ptr, 0x55, pinfo->size);
-            png_free_default(png_ptr, pinfo);
+            memset(ptr, 0x55, pinfo->size);
+            if (pinfo != NULL)
+               free(pinfo);
             pinfo = NULL;
             break;
          }
 
          if (pinfo->next == NULL)
          {
-            fprintf(STDERR, "Pointer %x not found\n", (unsigned int)ptr);
+            fprintf(STDERR, "Pointer %p not found\n", ptr);
             break;
          }
 
@@ -679,35 +598,84 @@ png_debug_free(png_structp png_ptr, png_voidp ptr)
    }
 
    /* Finally free the data. */
-   if (verbose)
+   if (verbose != 0)
       printf("Freeing %p\n", ptr);
 
-   png_free_default(png_ptr, ptr);
+   if (ptr != NULL)
+      free(ptr);
    ptr = NULL;
 }
-#endif /* PNG_USER_MEM_SUPPORTED && PNG_DEBUG */
+#endif /* USER_MEM && DEBUG */
 /* END of code to test memory allocation/deallocation */
 
 
+#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
 /* Demonstration of user chunk support of the sTER and vpAg chunks */
-#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
 
 /* (sTER is a public chunk not yet known by libpng.  vpAg is a private
 chunk used in ImageMagick to store "virtual page" size).  */
 
-static png_uint_32 user_chunk_data[4];
+static struct user_chunk_data
+{
+   png_const_infop info_ptr;
+   png_uint_32     vpAg_width, vpAg_height;
+   png_byte        vpAg_units;
+   png_byte        sTER_mode;
+   int             location[2];
+}
+user_chunk_data;
 
-    /* 0: sTER mode + 1
-     * 1: vpAg width
-     * 2: vpAg height
-     * 3: vpAg units
-     */
+/* Used for location and order; zero means nothing. */
+#define have_sTER   0x01
+#define have_vpAg   0x02
+#define before_PLTE 0x10
+#define before_IDAT 0x20
+#define after_IDAT  0x40
 
-static int PNGCBAPI read_user_chunk_callback(png_struct *png_ptr,
-   png_unknown_chunkp chunk)
+static void
+init_callback_info(png_const_infop info_ptr)
 {
-   png_uint_32
-     *my_user_chunk_data;
+   MEMZERO(user_chunk_data);
+   user_chunk_data.info_ptr = info_ptr;
+}
+
+static int
+set_location(png_structp png_ptr, struct user_chunk_data *data, int what)
+{
+   int location;
+
+   if ((data->location[0] & what) != 0 || (data->location[1] & what) != 0)
+      return 0; /* already have one of these */
+
+   /* Find where we are (the code below zeroes info_ptr to indicate that the
+    * chunks before the first IDAT have been read.)
+    */
+   if (data->info_ptr == NULL) /* after IDAT */
+      location = what | after_IDAT;
+
+   else if (png_get_valid(png_ptr, data->info_ptr, PNG_INFO_PLTE) != 0)
+      location = what | before_IDAT;
+
+   else
+      location = what | before_PLTE;
+
+   if (data->location[0] == 0)
+      data->location[0] = location;
+
+   else
+      data->location[1] = location;
+
+   return 1; /* handled */
+}
+
+static int PNGCBAPI
+read_user_chunk_callback(png_struct *png_ptr, png_unknown_chunkp chunk)
+{
+   struct user_chunk_data *my_user_chunk_data =
+      (struct user_chunk_data*)png_get_user_chunk_ptr(png_ptr);
+
+   if (my_user_chunk_data == NULL)
+      png_error(png_ptr, "lost user chunk pointer");
 
    /* Return one of the following:
     *    return (-n);  chunk had an error
@@ -732,9 +700,14 @@ static int PNGCBAPI read_user_chunk_callback(png_struct *png_ptr,
          if (chunk->data[0] != 0 && chunk->data[0] != 1)
             return (-1);  /* Invalid mode */
 
-         my_user_chunk_data=(png_uint_32 *) png_get_user_chunk_ptr(png_ptr);
-         my_user_chunk_data[0]=chunk->data[0]+1;
-         return (1);
+         if (set_location(png_ptr, my_user_chunk_data, have_sTER) != 0)
+         {
+            my_user_chunk_data->sTER_mode=chunk->data[0];
+            return (1);
+         }
+
+         else
+            return (0); /* duplicate sTER - give it to libpng */
       }
 
    if (chunk->name[0] != 118 || chunk->name[1] != 112 ||    /* v  p */
@@ -746,30 +719,126 @@ static int PNGCBAPI read_user_chunk_callback(png_struct *png_ptr,
    if (chunk->size != 9)
       return (-1); /* Error return */
 
-   my_user_chunk_data=(png_uint_32 *) png_get_user_chunk_ptr(png_ptr);
+   if (set_location(png_ptr, my_user_chunk_data, have_vpAg) == 0)
+      return (0);  /* duplicate vpAg */
 
-   my_user_chunk_data[1]=png_get_uint_31(png_ptr, chunk->data);
-   my_user_chunk_data[2]=png_get_uint_31(png_ptr, chunk->data + 4);
-   my_user_chunk_data[3]=(png_uint_32)chunk->data[8];
+   my_user_chunk_data->vpAg_width = png_get_uint_31(png_ptr, chunk->data);
+   my_user_chunk_data->vpAg_height = png_get_uint_31(png_ptr, chunk->data + 4);
+   my_user_chunk_data->vpAg_units = chunk->data[8];
 
    return (1);
+}
 
+#ifdef PNG_WRITE_SUPPORTED
+static void
+write_sTER_chunk(png_structp write_ptr)
+{
+   png_byte sTER[5] = {115,  84,  69,  82, '\0'};
+
+   if (verbose != 0)
+      fprintf(STDERR, "\n stereo mode = %d\n", user_chunk_data.sTER_mode);
+
+   png_write_chunk(write_ptr, sTER, &user_chunk_data.sTER_mode, 1);
 }
+
+static void
+write_vpAg_chunk(png_structp write_ptr)
+{
+   png_byte vpAg[5] = {118, 112,  65, 103, '\0'};
+
+   png_byte vpag_chunk_data[9];
+
+   if (verbose != 0)
+      fprintf(STDERR, " vpAg = %lu x %lu, units = %d\n",
+        (unsigned long)user_chunk_data.vpAg_width,
+        (unsigned long)user_chunk_data.vpAg_height,
+        user_chunk_data.vpAg_units);
+
+   png_save_uint_32(vpag_chunk_data, user_chunk_data.vpAg_width);
+   png_save_uint_32(vpag_chunk_data + 4, user_chunk_data.vpAg_height);
+   vpag_chunk_data[8] = user_chunk_data.vpAg_units;
+   png_write_chunk(write_ptr, vpAg, vpag_chunk_data, 9);
+}
+
+static void
+write_chunks(png_structp write_ptr, int location)
+{
+   int i;
+
+   /* Notice that this preserves the original chunk order, however chunks
+    * intercepted by the callback will be written *after* chunks passed to
+    * libpng.  This will actually reverse a pair of sTER chunks or a pair of
+    * vpAg chunks, resulting in an error later.  This is not worth worrying
+    * about - the chunks should not be duplicated!
+    */
+   for (i=0; i<2; ++i)
+   {
+      if (user_chunk_data.location[i] == (location | have_sTER))
+         write_sTER_chunk(write_ptr);
+
+      else if (user_chunk_data.location[i] == (location | have_vpAg))
+         write_vpAg_chunk(write_ptr);
+   }
+}
+#endif /* WRITE */
+#else /* !READ_USER_CHUNKS */
+#  define write_chunks(pp,loc) ((void)0)
 #endif
 /* END of code to demonstrate user chunk support */
 
+/* START of code to check that libpng has the required text support; this only
+ * checks for the write support because if read support is missing the chunk
+ * will simply not be reported back to pngtest.
+ */
+#ifdef PNG_TEXT_SUPPORTED
+static void
+pngtest_check_text_support(png_const_structp png_ptr, png_textp text_ptr,
+   int num_text)
+{
+   while (num_text > 0)
+   {
+      switch (text_ptr[--num_text].compression)
+      {
+         case PNG_TEXT_COMPRESSION_NONE:
+            break;
+
+         case PNG_TEXT_COMPRESSION_zTXt:
+#           ifndef PNG_WRITE_zTXt_SUPPORTED
+               ++unsupported_chunks;
+#           endif
+            break;
+
+         case PNG_ITXT_COMPRESSION_NONE:
+         case PNG_ITXT_COMPRESSION_zTXt:
+#           ifndef PNG_WRITE_iTXt_SUPPORTED
+               ++unsupported_chunks;
+#           endif
+            break;
+
+         default:
+            /* This is an error */
+            png_error(png_ptr, "invalid text chunk compression field");
+            break;
+      }
+   }
+}
+#endif
+/* END of code to check that libpng has the required text support */
+
 /* Test one file */
-int
+static int
 test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
 {
    static png_FILE_p fpin;
    static png_FILE_p fpout;  /* "static" prevents setjmp corruption */
+   pngtest_error_parameters error_parameters;
    png_structp read_ptr;
    png_infop read_info_ptr, end_info_ptr;
 #ifdef PNG_WRITE_SUPPORTED
    png_structp write_ptr;
    png_infop write_info_ptr;
    png_infop write_end_info_ptr;
+   int interlace_preserved = 1;
 #else
    png_structp write_ptr = NULL;
    png_infop write_info_ptr = NULL;
@@ -778,17 +847,11 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
    png_bytep row_buf;
    png_uint_32 y;
    png_uint_32 width, height;
-   int num_pass, pass;
+   int num_pass = 1, pass;
    int bit_depth, color_type;
-#ifdef PNG_SETJMP_SUPPORTED
-#ifdef USE_FAR_KEYWORD
-   jmp_buf tmp_jmpbuf;
-#endif
-#endif
-
-   char inbuf[256], outbuf[256];
 
    row_buf = NULL;
+   error_parameters.file_name = inname;
 
    if ((fpin = fopen(inname, "rb")) == NULL)
    {
@@ -812,20 +875,9 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
    read_ptr =
       png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
 #endif
-#ifndef PNG_STDIO_SUPPORTED
-   png_set_error_fn(read_ptr, (png_voidp)inname, pngtest_error,
-       pngtest_warning);
-#endif
+   png_set_error_fn(read_ptr, &error_parameters, pngtest_error,
+      pngtest_warning);
 
-#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
-   user_chunk_data[0] = 0;
-   user_chunk_data[1] = 0;
-   user_chunk_data[2] = 0;
-   user_chunk_data[3] = 0;
-   png_set_read_user_chunk_fn(read_ptr, user_chunk_data,
-     read_user_chunk_callback);
-
-#endif
 #ifdef PNG_WRITE_SUPPORTED
 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
    write_ptr =
@@ -835,10 +887,8 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
    write_ptr =
       png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
 #endif
-#ifndef PNG_STDIO_SUPPORTED
-   png_set_error_fn(write_ptr, (png_voidp)inname, pngtest_error,
-       pngtest_warning);
-#endif
+   png_set_error_fn(write_ptr, &error_parameters, pngtest_error,
+      pngtest_warning);
 #endif
    pngtest_debug("Allocating read_info, write_info and end_info structures");
    read_info_ptr = png_create_info_struct(read_ptr);
@@ -848,13 +898,15 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
    write_end_info_ptr = png_create_info_struct(write_ptr);
 #endif
 
+#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
+   init_callback_info(read_info_ptr);
+   png_set_read_user_chunk_fn(read_ptr, &user_chunk_data,
+     read_user_chunk_callback);
+#endif
+
 #ifdef PNG_SETJMP_SUPPORTED
    pngtest_debug("Setting jmpbuf for read struct");
-#ifdef USE_FAR_KEYWORD
-   if (setjmp(tmp_jmpbuf))
-#else
    if (setjmp(png_jmpbuf(read_ptr)))
-#endif
    {
       fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname);
       png_free(read_ptr, row_buf);
@@ -868,18 +920,11 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
       FCLOSE(fpout);
       return (1);
    }
-#ifdef USE_FAR_KEYWORD
-   png_memcpy(png_jmpbuf(read_ptr), tmp_jmpbuf, png_sizeof(jmp_buf));
-#endif
 
 #ifdef PNG_WRITE_SUPPORTED
    pngtest_debug("Setting jmpbuf for write struct");
-#ifdef USE_FAR_KEYWORD
 
-   if (setjmp(tmp_jmpbuf))
-#else
    if (setjmp(png_jmpbuf(write_ptr)))
-#endif
    {
       fprintf(STDERR, "%s -> %s: libpng write error\n", inname, outname);
       png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
@@ -891,13 +936,35 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
       FCLOSE(fpout);
       return (1);
    }
-
-#ifdef USE_FAR_KEYWORD
-   png_memcpy(png_jmpbuf(write_ptr), tmp_jmpbuf, png_sizeof(jmp_buf));
 #endif
 #endif
+
+   if (strict != 0)
+   {
+      /* Treat png_benign_error() as errors on read */
+      png_set_benign_errors(read_ptr, 0);
+
+#ifdef PNG_WRITE_SUPPORTED
+      /* Treat them as errors on write */
+      png_set_benign_errors(write_ptr, 0);
 #endif
 
+      /* if strict is not set, then app warnings and errors are treated as
+       * warnings in release builds, but not in unstable builds; this can be
+       * changed with '--relaxed'.
+       */
+   }
+
+   else if (relaxed != 0)
+   {
+      /* Allow application (pngtest) errors and warnings to pass */
+      png_set_benign_errors(read_ptr, 1);
+
+#ifdef PNG_WRITE_SUPPORTED
+      png_set_benign_errors(write_ptr, 1);
+#endif
+   }
+
    pngtest_debug("Initializing input and output streams");
 #ifdef PNG_STDIO_SUPPORTED
    png_init_io(read_ptr, fpin);
@@ -916,14 +983,6 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
 #  endif
 #endif
 
-#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
-   /* Normally one would use Z_DEFAULT_STRATEGY for text compression.
-    * This is here just to make pngtest replicate the results from libpng
-    * versions prior to 1.5.4, and to test this new API.
-    */
-   png_set_text_compression_strategy(write_ptr, Z_FILTERED);
-#endif
-
    if (status_dots_requested == 1)
    {
 #ifdef PNG_WRITE_SUPPORTED
@@ -955,36 +1014,65 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
    png_set_write_user_transform_fn(write_ptr, count_zero_samples);
 #endif
 
-#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
-#  ifndef PNG_HANDLE_CHUNK_ALWAYS
-#    define PNG_HANDLE_CHUNK_ALWAYS       3
-#  endif
+#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
+   /* Preserve all the unknown chunks, if possible.  If this is disabled then,
+    * even if the png_{get,set}_unknown_chunks stuff is enabled, we can't use
+    * libpng to *save* the unknown chunks on read (because we can't switch the
+    * save option on!)
+    *
+    * Notice that if SET_UNKNOWN_CHUNKS is *not* supported read will discard all
+    * unknown chunks and write will write them all.
+    */
+#ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED
    png_set_keep_unknown_chunks(read_ptr, PNG_HANDLE_CHUNK_ALWAYS,
       NULL, 0);
 #endif
 #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
-#  ifndef PNG_HANDLE_CHUNK_IF_SAFE
-#    define PNG_HANDLE_CHUNK_IF_SAFE      2
-#  endif
-   png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_IF_SAFE,
+   png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_ALWAYS,
       NULL, 0);
 #endif
+#endif
 
    pngtest_debug("Reading info struct");
    png_read_info(read_ptr, read_info_ptr);
 
+#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
+   /* This is a bit of a hack; there is no obvious way in the callback function
+    * to determine that the chunks before the first IDAT have been read, so
+    * remove the info_ptr (which is only used to determine position relative to
+    * PLTE) here to indicate that we are after the IDAT.
+    */
+   user_chunk_data.info_ptr = NULL;
+#endif
+
    pngtest_debug("Transferring info struct");
    {
       int interlace_type, compression_type, filter_type;
 
       if (png_get_IHDR(read_ptr, read_info_ptr, &width, &height, &bit_depth,
-          &color_type, &interlace_type, &compression_type, &filter_type))
+          &color_type, &interlace_type, &compression_type, &filter_type) != 0)
       {
          png_set_IHDR(write_ptr, write_info_ptr, width, height, bit_depth,
-#ifdef PNG_WRITE_INTERLACING_SUPPORTED
             color_type, interlace_type, compression_type, filter_type);
-#else
-            color_type, PNG_INTERLACE_NONE, compression_type, filter_type);
+#ifndef PNG_READ_INTERLACING_SUPPORTED
+         /* num_pass will not be set below, set it here if the image is
+          * interlaced: what happens is that write interlacing is *not* turned
+          * on an the partial interlaced rows are written directly.
+          */
+         switch (interlace_type)
+         {
+            case PNG_INTERLACE_NONE:
+               num_pass = 1;
+               break;
+
+            case PNG_INTERLACE_ADAM7:
+               num_pass = 7;
+                break;
+
+            default:
+                png_error(read_ptr, "invalid interlace type");
+                /*NOT REACHED*/
+         }
 #endif
       }
    }
@@ -995,7 +1083,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
          blue_y;
 
       if (png_get_cHRM_fixed(read_ptr, read_info_ptr, &white_x, &white_y,
-         &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y))
+         &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y) != 0)
       {
          png_set_cHRM_fixed(write_ptr, write_info_ptr, white_x, white_y, red_x,
             red_y, green_x, green_y, blue_x, blue_y);
@@ -1006,7 +1094,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
    {
       png_fixed_point gamma;
 
-      if (png_get_gAMA_fixed(read_ptr, read_info_ptr, &gamma))
+      if (png_get_gAMA_fixed(read_ptr, read_info_ptr, &gamma) != 0)
          png_set_gAMA_fixed(write_ptr, write_info_ptr, gamma);
    }
 #endif
@@ -1018,7 +1106,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
          blue_y;
 
       if (png_get_cHRM(read_ptr, read_info_ptr, &white_x, &white_y, &red_x,
-         &red_y, &green_x, &green_y, &blue_x, &blue_y))
+         &red_y, &green_x, &green_y, &blue_x, &blue_y) != 0)
       {
          png_set_cHRM(write_ptr, write_info_ptr, white_x, white_y, red_x,
             red_y, green_x, green_y, blue_x, blue_y);
@@ -1029,7 +1117,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
    {
       double gamma;
 
-      if (png_get_gAMA(read_ptr, read_info_ptr, &gamma))
+      if (png_get_gAMA(read_ptr, read_info_ptr, &gamma) != 0)
          png_set_gAMA(write_ptr, write_info_ptr, gamma);
    }
 #endif
@@ -1043,7 +1131,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
       int compression_type;
 
       if (png_get_iCCP(read_ptr, read_info_ptr, &name, &compression_type,
-                      &profile, &proflen))
+                      &profile, &proflen) != 0)
       {
          png_set_iCCP(write_ptr, write_info_ptr, name, compression_type,
                       profile, proflen);
@@ -1054,7 +1142,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
    {
       int intent;
 
-      if (png_get_sRGB(read_ptr, read_info_ptr, &intent))
+      if (png_get_sRGB(read_ptr, read_info_ptr, &intent) != 0)
          png_set_sRGB(write_ptr, write_info_ptr, intent);
    }
 #endif
@@ -1062,14 +1150,14 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
       png_colorp palette;
       int num_palette;
 
-      if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette))
+      if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette) != 0)
          png_set_PLTE(write_ptr, write_info_ptr, palette, num_palette);
    }
 #ifdef PNG_bKGD_SUPPORTED
    {
       png_color_16p background;
 
-      if (png_get_bKGD(read_ptr, read_info_ptr, &background))
+      if (png_get_bKGD(read_ptr, read_info_ptr, &background) != 0)
       {
          png_set_bKGD(write_ptr, write_info_ptr, background);
       }
@@ -1079,7 +1167,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
    {
       png_uint_16p hist;
 
-      if (png_get_hIST(read_ptr, read_info_ptr, &hist))
+      if (png_get_hIST(read_ptr, read_info_ptr, &hist) != 0)
          png_set_hIST(write_ptr, write_info_ptr, hist);
    }
 #endif
@@ -1089,7 +1177,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
       int unit_type;
 
       if (png_get_oFFs(read_ptr, read_info_ptr, &offset_x, &offset_y,
-          &unit_type))
+          &unit_type) != 0)
       {
          png_set_oFFs(write_ptr, write_info_ptr, offset_x, offset_y, unit_type);
       }
@@ -1103,7 +1191,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
       int type, nparams;
 
       if (png_get_pCAL(read_ptr, read_info_ptr, &purpose, &X0, &X1, &type,
-         &nparams, &units, &params))
+         &nparams, &units, &params) != 0)
       {
          png_set_pCAL(write_ptr, write_info_ptr, purpose, X0, X1, type,
             nparams, units, params);
@@ -1115,7 +1203,8 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
       png_uint_32 res_x, res_y;
       int unit_type;
 
-      if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y, &unit_type))
+      if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y,
+          &unit_type) != 0)
          png_set_pHYs(write_ptr, write_info_ptr, res_x, res_y, unit_type);
    }
 #endif
@@ -1123,18 +1212,19 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
    {
       png_color_8p sig_bit;
 
-      if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit))
+      if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit) != 0)
          png_set_sBIT(write_ptr, write_info_ptr, sig_bit);
    }
 #endif
 #ifdef PNG_sCAL_SUPPORTED
-#ifdef PNG_FLOATING_POINT_SUPPORTED
+#if defined(PNG_FLOATING_POINT_SUPPORTED) && \
+   defined(PNG_FLOATING_ARITHMETIC_SUPPORTED)
    {
       int unit;
       double scal_width, scal_height;
 
       if (png_get_sCAL(read_ptr, read_info_ptr, &unit, &scal_width,
-         &scal_height))
+         &scal_height) != 0)
       {
          png_set_sCAL(write_ptr, write_info_ptr, unit, scal_width, scal_height);
       }
@@ -1146,7 +1236,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
       png_charp scal_width, scal_height;
 
       if (png_get_sCAL_s(read_ptr, read_info_ptr, &unit, &scal_width,
-          &scal_height))
+          &scal_height) != 0)
       {
          png_set_sCAL_s(write_ptr, write_info_ptr, unit, scal_width,
              scal_height);
@@ -1164,8 +1254,19 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
       {
          pngtest_debug1("Handling %d iTXt/tEXt/zTXt chunks", num_text);
 
-         if (verbose)
-            printf("\n Text compression=%d\n", text_ptr->compression);
+         pngtest_check_text_support(read_ptr, text_ptr, num_text);
+
+         if (verbose != 0)
+         {
+            int i;
+
+            printf("\n");
+            for (i=0; i<num_text; i++)
+            {
+               printf("   Text compression[%d]=%d\n",
+                     i, text_ptr[i].compression);
+            }
+         }
 
          png_set_text(write_ptr, write_info_ptr, text_ptr, num_text);
       }
@@ -1175,21 +1276,21 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
    {
       png_timep mod_time;
 
-      if (png_get_tIME(read_ptr, read_info_ptr, &mod_time))
+      if (png_get_tIME(read_ptr, read_info_ptr, &mod_time) != 0)
       {
          png_set_tIME(write_ptr, write_info_ptr, mod_time);
 #ifdef PNG_TIME_RFC1123_SUPPORTED
-         /* We have to use png_memcpy instead of "=" because the string
-          * pointed to by png_convert_to_rfc1123() gets free'ed before
-          * we use it.
-          */
-         png_memcpy(tIME_string,
-                    png_convert_to_rfc1123(read_ptr, mod_time),
-                    png_sizeof(tIME_string));
+         if (png_convert_to_rfc1123_buffer(tIME_string, mod_time) != 0)
+            tIME_string[(sizeof tIME_string) - 1] = '\0';
+
+         else
+         {
+            strncpy(tIME_string, "*** invalid time ***", (sizeof tIME_string));
+            tIME_string[(sizeof tIME_string) - 1] = '\0';
+         }
 
-         tIME_string[png_sizeof(tIME_string) - 1] = '\0';
          tIME_chunk_present++;
-#endif /* PNG_TIME_RFC1123_SUPPORTED */
+#endif /* TIME_RFC1123 */
       }
    }
 #endif
@@ -1200,7 +1301,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
       png_color_16p trans_color;
 
       if (png_get_tRNS(read_ptr, read_info_ptr, &trans_alpha, &num_trans,
-         &trans_color))
+         &trans_color) != 0)
       {
          int sample_max = (1 << bit_depth);
          /* libpng doesn't reject a tRNS chunk with out-of-range samples */
@@ -1221,18 +1322,22 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
       int num_unknowns = png_get_unknown_chunks(read_ptr, read_info_ptr,
          &unknowns);
 
-      if (num_unknowns)
+      if (num_unknowns != 0)
       {
-         int i;
          png_set_unknown_chunks(write_ptr, write_info_ptr, unknowns,
            num_unknowns);
+#if PNG_LIBPNG_VER < 10600
          /* Copy the locations from the read_info_ptr.  The automatically
-          * generated locations in write_info_ptr are wrong because we
-          * haven't written anything yet.
+          * generated locations in write_end_info_ptr are wrong prior to 1.6.0
+          * because they are reset from the write pointer (removed in 1.6.0).
           */
-         for (i = 0; i < num_unknowns; i++)
-           png_set_unknown_chunk_location(write_ptr, write_info_ptr, i,
-             unknowns[i].location);
+         {
+            int i;
+            for (i = 0; i < num_unknowns; i++)
+              png_set_unknown_chunk_location(write_ptr, write_info_ptr, i,
+                unknowns[i].location);
+         }
+#endif
       }
    }
 #endif
@@ -1240,47 +1345,16 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
 #ifdef PNG_WRITE_SUPPORTED
    pngtest_debug("Writing info struct");
 
-/* If we wanted, we could write info in two steps:
- * png_write_info_before_PLTE(write_ptr, write_info_ptr);
- */
-   png_write_info(write_ptr, write_info_ptr);
-
-#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
-   if (user_chunk_data[0] != 0)
-   {
-      png_byte png_sTER[5] = {115,  84,  69,  82, '\0'};
-
-      unsigned char
-        ster_chunk_data[1];
-
-      if (verbose)
-         fprintf(STDERR, "\n stereo mode = %lu\n",
-           (unsigned long)(user_chunk_data[0] - 1));
-
-      ster_chunk_data[0]=(unsigned char)(user_chunk_data[0] - 1);
-      png_write_chunk(write_ptr, png_sTER, ster_chunk_data, 1);
-   }
-
-   if (user_chunk_data[1] != 0 || user_chunk_data[2] != 0)
-   {
-      png_byte png_vpAg[5] = {118, 112,  65, 103, '\0'};
-
-      unsigned char
-        vpag_chunk_data[9];
+   /* Write the info in two steps so that if we write the 'unknown' chunks here
+    * they go to the correct place.
+    */
+   png_write_info_before_PLTE(write_ptr, write_info_ptr);
 
-      if (verbose)
-         fprintf(STDERR, " vpAg = %lu x %lu, units = %lu\n",
-           (unsigned long)user_chunk_data[1],
-           (unsigned long)user_chunk_data[2],
-           (unsigned long)user_chunk_data[3]);
+   write_chunks(write_ptr, before_PLTE); /* before PLTE */
 
-      png_save_uint_32(vpag_chunk_data, user_chunk_data[1]);
-      png_save_uint_32(vpag_chunk_data + 4, user_chunk_data[2]);
-      vpag_chunk_data[8] = (unsigned char)(user_chunk_data[3] & 0xff);
-      png_write_chunk(write_ptr, png_vpAg, vpag_chunk_data, 9);
-   }
+   png_write_info(write_ptr, write_info_ptr);
 
-#endif
+   write_chunks(write_ptr, before_IDAT); /* after PLTE */
 #endif
 
 #ifdef SINGLE_ROWBUF_ALLOC
@@ -1292,14 +1366,10 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
 #endif /* SINGLE_ROWBUF_ALLOC */
    pngtest_debug("Writing row data");
 
-#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
-  defined(PNG_WRITE_INTERLACING_SUPPORTED)
+#ifdef PNG_READ_INTERLACING_SUPPORTED
    num_pass = png_set_interlace_handling(read_ptr);
-#  ifdef PNG_WRITE_SUPPORTED
-   png_set_interlace_handling(write_ptr);
-#  endif
-#else
-   num_pass = 1;
+   if (png_set_interlace_handling(write_ptr) != num_pass)
+      png_error(write_ptr, "png_set_interlace_handling: inconsistent num_pass");
 #endif
 
 #ifdef PNGTEST_TIMING
@@ -1314,11 +1384,12 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
       {
 #ifndef SINGLE_ROWBUF_ALLOC
          pngtest_debug2("Allocating row buffer (pass %d, y = %u)...", pass, y);
+
          row_buf = (png_bytep)png_malloc(read_ptr,
             png_get_rowbytes(read_ptr, read_info_ptr));
 
-         pngtest_debug2("\t0x%08lx (%u bytes)", (unsigned long)row_buf,
-            png_get_rowbytes(read_ptr, read_info_ptr));
+         pngtest_debug2("\t0x%08lx (%lu bytes)", (unsigned long)row_buf,
+            (unsigned long)png_get_rowbytes(read_ptr, read_info_ptr));
 
 #endif /* !SINGLE_ROWBUF_ALLOC */
          png_read_rows(read_ptr, (png_bytepp)&row_buf, NULL, 1);
@@ -1335,7 +1406,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
          t_encode += (t_stop - t_start);
          t_start = t_stop;
 #endif
-#endif /* PNG_WRITE_SUPPORTED */
+#endif /* WRITE */
 
 #ifndef SINGLE_ROWBUF_ALLOC
          pngtest_debug2("Freeing row buffer (pass %d, y = %u)", pass, y);
@@ -1345,11 +1416,13 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
       }
    }
 
-#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
-   png_free_data(read_ptr, read_info_ptr, PNG_FREE_UNKN, -1);
-#endif
-#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
-   png_free_data(write_ptr, write_info_ptr, PNG_FREE_UNKN, -1);
+#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
+#  ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
+      png_free_data(read_ptr, read_info_ptr, PNG_FREE_UNKN, -1);
+#  endif
+#  ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+      png_free_data(write_ptr, write_info_ptr, PNG_FREE_UNKN, -1);
+#  endif
 #endif
 
    pngtest_debug("Reading and writing end_info data");
@@ -1363,6 +1436,21 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
       if (png_get_text(read_ptr, end_info_ptr, &text_ptr, &num_text) > 0)
       {
          pngtest_debug1("Handling %d iTXt/tEXt/zTXt chunks", num_text);
+
+         pngtest_check_text_support(read_ptr, text_ptr, num_text);
+
+         if (verbose != 0)
+         {
+            int i;
+
+            printf("\n");
+            for (i=0; i<num_text; i++)
+            {
+               printf("   Text compression[%d]=%d\n",
+                     i, text_ptr[i].compression);
+            }
+         }
+
          png_set_text(write_ptr, write_end_info_ptr, text_ptr, num_text);
       }
    }
@@ -1371,20 +1459,21 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
    {
       png_timep mod_time;
 
-      if (png_get_tIME(read_ptr, end_info_ptr, &mod_time))
+      if (png_get_tIME(read_ptr, end_info_ptr, &mod_time) != 0)
       {
          png_set_tIME(write_ptr, write_end_info_ptr, mod_time);
 #ifdef PNG_TIME_RFC1123_SUPPORTED
-         /* We have to use png_memcpy instead of "=" because the string
-            pointed to by png_convert_to_rfc1123() gets free'ed before
-            we use it */
-         png_memcpy(tIME_string,
-                    png_convert_to_rfc1123(read_ptr, mod_time),
-                    png_sizeof(tIME_string));
-
-         tIME_string[png_sizeof(tIME_string) - 1] = '\0';
+         if (png_convert_to_rfc1123_buffer(tIME_string, mod_time) != 0)
+            tIME_string[(sizeof tIME_string) - 1] = '\0';
+
+         else
+         {
+            strncpy(tIME_string, "*** invalid time ***", sizeof tIME_string);
+            tIME_string[(sizeof tIME_string)-1] = '\0';
+         }
+
          tIME_chunk_present++;
-#endif /* PNG_TIME_RFC1123_SUPPORTED */
+#endif /* TIME_RFC1123 */
       }
    }
 #endif
@@ -1394,27 +1483,48 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
       int num_unknowns = png_get_unknown_chunks(read_ptr, end_info_ptr,
          &unknowns);
 
-      if (num_unknowns)
+      if (num_unknowns != 0)
       {
-         int i;
          png_set_unknown_chunks(write_ptr, write_end_info_ptr, unknowns,
            num_unknowns);
+#if PNG_LIBPNG_VER < 10600
          /* Copy the locations from the read_info_ptr.  The automatically
-          * generated locations in write_end_info_ptr are wrong because we
-          * haven't written the end_info yet.
+          * generated locations in write_end_info_ptr are wrong prior to 1.6.0
+          * because they are reset from the write pointer (removed in 1.6.0).
           */
-         for (i = 0; i < num_unknowns; i++)
-           png_set_unknown_chunk_location(write_ptr, write_end_info_ptr, i,
-             unknowns[i].location);
+         {
+            int i;
+            for (i = 0; i < num_unknowns; i++)
+              png_set_unknown_chunk_location(write_ptr, write_end_info_ptr, i,
+                unknowns[i].location);
+         }
+#endif
       }
    }
 #endif
+
 #ifdef PNG_WRITE_SUPPORTED
+#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
+   /* Normally one would use Z_DEFAULT_STRATEGY for text compression.
+    * This is here just to make pngtest replicate the results from libpng
+    * versions prior to 1.5.4, and to test this new API.
+    */
+   png_set_text_compression_strategy(write_ptr, Z_FILTERED);
+#endif
+
+   /* When the unknown vpAg/sTER chunks are written by pngtest the only way to
+    * do it is to write them *before* calling png_write_end.  When unknown
+    * chunks are written by libpng, however, they are written just before IEND.
+    * There seems to be no way round this, however vpAg/sTER are not expected
+    * after IDAT.
+    */
+   write_chunks(write_ptr, after_IDAT);
+
    png_write_end(write_ptr, write_end_info_ptr);
 #endif
 
 #ifdef PNG_EASY_ACCESS_SUPPORTED
-   if (verbose)
+   if (verbose != 0)
    {
       png_uint_32 iwidth, iheight;
       iwidth = png_get_image_width(write_ptr, write_info_ptr);
@@ -1443,6 +1553,40 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
    FCLOSE(fpin);
    FCLOSE(fpout);
 
+   /* Summarize any warnings or errors and in 'strict' mode fail the test.
+    * Unsupported chunks can result in warnings, in that case ignore the strict
+    * setting, otherwise fail the test on warnings as well as errors.
+    */
+   if (error_count > 0)
+   {
+      /* We don't really expect to get here because of the setjmp handling
+       * above, but this is safe.
+       */
+      fprintf(STDERR, "\n  %s: %d libpng errors found (%d warnings)",
+         inname, error_count, warning_count);
+
+      if (strict != 0)
+         return (1);
+   }
+
+#  ifdef PNG_WRITE_SUPPORTED
+      /* If there we no write support nothing was written! */
+      else if (unsupported_chunks > 0)
+      {
+         fprintf(STDERR, "\n  %s: unsupported chunks (%d)%s",
+            inname, unsupported_chunks, strict ? ": IGNORED --strict!" : "");
+      }
+#  endif
+
+   else if (warning_count > 0)
+   {
+      fprintf(STDERR, "\n  %s: %d libpng warnings found",
+         inname, warning_count);
+
+      if (strict != 0)
+         return (1);
+   }
+
    pngtest_debug("Opening files for comparison");
    if ((fpin = fopen(inname, "rb")) == NULL)
    {
@@ -1457,71 +1601,84 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
       return (1);
    }
 
-   for (;;)
+#ifdef PNG_WRITE_SUPPORTED /* else nothing was written */
+   if (interlace_preserved != 0) /* else the files will be changed */
    {
-      png_size_t num_in, num_out;
-
-         num_in = fread(inbuf, 1, 1, fpin);
-         num_out = fread(outbuf, 1, 1, fpout);
-
-      if (num_in != num_out)
+      for (;;)
       {
-         fprintf(STDERR, "\nFiles %s and %s are of a different size\n",
-                 inname, outname);
+         static int wrote_question = 0;
+         png_size_t num_in, num_out;
+         char inbuf[256], outbuf[256];
+
+         num_in = fread(inbuf, 1, sizeof inbuf, fpin);
+         num_out = fread(outbuf, 1, sizeof outbuf, fpout);
 
-         if (wrote_question == 0)
+         if (num_in != num_out)
          {
-            fprintf(STDERR,
-         "   Was %s written with the same maximum IDAT chunk size (%d bytes),",
-              inname, PNG_ZBUF_SIZE);
-            fprintf(STDERR,
-              "\n   filtering heuristic (libpng default), compression");
-            fprintf(STDERR,
-              " level (zlib default),\n   and zlib version (%s)?\n\n",
-              ZLIB_VERSION);
-            wrote_question = 1;
-         }
+            fprintf(STDERR, "\nFiles %s and %s are of a different size\n",
+                    inname, outname);
 
-         FCLOSE(fpin);
-         FCLOSE(fpout);
+            if (wrote_question == 0 && unsupported_chunks == 0)
+            {
+               fprintf(STDERR,
+         "   Was %s written with the same maximum IDAT chunk size (%d bytes),",
+                 inname, PNG_ZBUF_SIZE);
+               fprintf(STDERR,
+                 "\n   filtering heuristic (libpng default), compression");
+               fprintf(STDERR,
+                 " level (zlib default),\n   and zlib version (%s)?\n\n",
+                 ZLIB_VERSION);
+               wrote_question = 1;
+            }
 
-         if (strict != 0)
-           return (1);
+            FCLOSE(fpin);
+            FCLOSE(fpout);
 
-         else
-           return (0);
-      }
+            if (strict != 0 && unsupported_chunks == 0)
+              return (1);
 
-      if (!num_in)
-         break;
+            else
+              return (0);
+         }
 
-      if (png_memcmp(inbuf, outbuf, num_in))
-      {
-         fprintf(STDERR, "\nFiles %s and %s are different\n", inname, outname);
+         if (num_in == 0)
+            break;
 
-         if (wrote_question == 0)
+         if (memcmp(inbuf, outbuf, num_in))
          {
-            fprintf(STDERR,
+            fprintf(STDERR, "\nFiles %s and %s are different\n", inname,
+               outname);
+
+            if (wrote_question == 0 && unsupported_chunks == 0)
+            {
+               fprintf(STDERR,
          "   Was %s written with the same maximum IDAT chunk size (%d bytes),",
-                 inname, PNG_ZBUF_SIZE);
-            fprintf(STDERR,
-              "\n   filtering heuristic (libpng default), compression");
-            fprintf(STDERR,
-              " level (zlib default),\n   and zlib version (%s)?\n\n",
-              ZLIB_VERSION);
-            wrote_question = 1;
-         }
+                    inname, PNG_ZBUF_SIZE);
+               fprintf(STDERR,
+                 "\n   filtering heuristic (libpng default), compression");
+               fprintf(STDERR,
+                 " level (zlib default),\n   and zlib version (%s)?\n\n",
+                 ZLIB_VERSION);
+               wrote_question = 1;
+            }
 
-         FCLOSE(fpin);
-         FCLOSE(fpout);
+            FCLOSE(fpin);
+            FCLOSE(fpout);
 
-         if (strict != 0)
-           return (1);
+            /* NOTE: the unsupported_chunks escape is permitted here because
+             * unsupported text chunk compression will result in the compression
+             * mode being changed (to NONE) yet, in the test case, the result
+             * can be exactly the same size!
+             */
+            if (strict != 0 && unsupported_chunks == 0)
+              return (1);
 
-         else
-           return (0);
+            else
+              return (0);
+         }
       }
    }
+#endif /* WRITE */
 
    FCLOSE(fpin);
    FCLOSE(fpout);
@@ -1607,6 +1764,16 @@ main(int argc, char *argv[])
          verbose = 1;
          inname = argv[2];
          strict++;
+         relaxed = 0;
+      }
+
+      else if (strcmp(argv[1], "--relaxed") == 0)
+      {
+         status_dots_requested = 0;
+         verbose = 1;
+         inname = argv[2];
+         strict = 0;
+         relaxed++;
       }
 
       else
@@ -1616,10 +1783,11 @@ main(int argc, char *argv[])
       }
    }
 
-   if (!multiple && argc == 3 + verbose)
+   if (multiple == 0 && argc == 3 + verbose)
      outname = argv[2 + verbose];
 
-   if ((!multiple && argc > 3 + verbose) || (multiple && argc < 2))
+   if ((multiple == 0 && argc > 3 + verbose) ||
+       (multiple != 0 && argc < 2))
    {
      fprintf(STDERR,
        "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n",
@@ -1631,7 +1799,7 @@ main(int argc, char *argv[])
      exit(1);
    }
 
-   if (multiple)
+   if (multiple != 0)
    {
       int i;
 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
@@ -1641,6 +1809,9 @@ main(int argc, char *argv[])
       {
          int kerror;
          fprintf(STDERR, "\n Testing %s:", argv[i]);
+#if PNG_DEBUG > 0
+         fprintf(STDERR, "\n");
+#endif
          kerror = test_one_file(argv[i], outname);
          if (kerror == 0)
          {
@@ -1655,7 +1826,7 @@ main(int argc, char *argv[])
 #endif
 #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
             for (k = 0; k<256; k++)
-               if (filters_used[k])
+               if (filters_used[k] != 0)
                   fprintf(STDERR, " Filter %d was used %lu times\n",
                      k, (unsigned long)filters_used[k]);
 #endif
@@ -1664,7 +1835,7 @@ main(int argc, char *argv[])
             fprintf(STDERR, " tIME = %s\n", tIME_string);
 
          tIME_chunk_present = 0;
-#endif /* PNG_TIME_RFC1123_SUPPORTED */
+#endif /* TIME_RFC1123 */
          }
 
          else
@@ -1686,9 +1857,9 @@ main(int argc, char *argv[])
 
             while (pinfo != NULL)
             {
-               fprintf(STDERR, " %lu bytes at %x\n",
+               fprintf(STDERR, " %lu bytes at %p\n",
                  (unsigned long)pinfo->size,
-                 (unsigned int)pinfo->pointer);
+                 pinfo->pointer);
                pinfo = pinfo->next;
             }
          }
@@ -1722,7 +1893,12 @@ main(int argc, char *argv[])
             status_dots_requested = 0;
 
          if (i == 0 || verbose == 1 || ierror != 0)
+         {
             fprintf(STDERR, "\n Testing %s:", inname);
+#if PNG_DEBUG > 0
+            fprintf(STDERR, "\n");
+#endif
+         }
 
          kerror = test_one_file(inname, outname);
 
@@ -1741,21 +1917,26 @@ main(int argc, char *argv[])
 #endif
 #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
                 for (k = 0; k<256; k++)
-                   if (filters_used[k])
+                   if (filters_used[k] != 0)
                       fprintf(STDERR, " Filter %d was used %lu times\n",
                          k, (unsigned long)filters_used[k]);
 #endif
 #ifdef PNG_TIME_RFC1123_SUPPORTED
              if (tIME_chunk_present != 0)
                 fprintf(STDERR, " tIME = %s\n", tIME_string);
-#endif /* PNG_TIME_RFC1123_SUPPORTED */
+#endif /* TIME_RFC1123 */
             }
          }
 
          else
          {
             if (verbose == 0 && i != 2)
+            {
                fprintf(STDERR, "\n Testing %s:", inname);
+#if PNG_DEBUG > 0
+               fprintf(STDERR, "\n");
+#endif
+            }
 
             fprintf(STDERR, " FAIL\n");
             ierror += kerror;
@@ -1774,8 +1955,8 @@ main(int argc, char *argv[])
 
              while (pinfo != NULL)
              {
-                fprintf(STDERR, " %lu bytes at %x\n",
-                   (unsigned long)pinfo->size, (unsigned int)pinfo->pointer);
+                fprintf(STDERR, " %lu bytes at %p\n",
+                   (unsigned long)pinfo->size, pinfo->pointer);
                 pinfo = pinfo->next;
              }
           }
@@ -1815,6 +1996,16 @@ main(int argc, char *argv[])
 
    return (int)(ierror != 0);
 }
+#else
+int
+main(void)
+{
+   fprintf(STDERR,
+      " test ignored because libpng was not built with read support\n");
+   /* And skip this test */
+   return PNG_LIBPNG_VER < 10600 ? 0 : 77;
+}
+#endif
 
 /* Generate a compiler error if there is an old png.h in the search path. */
-typedef png_libpng_version_1_5_13 Your_png_h_is_not_version_1_5_13;
+typedef png_libpng_version_1_6_16 Your_png_h_is_not_version_1_6_16;
diff --git a/Source/LibPNG/pngtrans.c b/Source/LibPNG/pngtrans.c
index d562eb0..56856b4 100644
--- a/Source/LibPNG/pngtrans.c
+++ b/Source/LibPNG/pngtrans.c
@@ -1,781 +1,849 @@
-
-/* pngtrans.c - transforms the data in a row (used by both readers and writers)
- *
- * Last changed in libpng 1.5.11 [June 14, 2012]
- * Copyright (c) 1998-2012 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- */
-
-#include "pngpriv.h"
-
-#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
-
-#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
-/* Turn on BGR-to-RGB mapping */
-void PNGAPI
-png_set_bgr(png_structp png_ptr)
-{
-   png_debug(1, "in png_set_bgr");
-
-   if (png_ptr == NULL)
-      return;
-
-   png_ptr->transformations |= PNG_BGR;
-}
-#endif
-
-#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
-/* Turn on 16 bit byte swapping */
-void PNGAPI
-png_set_swap(png_structp png_ptr)
-{
-   png_debug(1, "in png_set_swap");
-
-   if (png_ptr == NULL)
-      return;
-
-   if (png_ptr->bit_depth == 16)
-      png_ptr->transformations |= PNG_SWAP_BYTES;
-}
-#endif
-
-#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
-/* Turn on pixel packing */
-void PNGAPI
-png_set_packing(png_structp png_ptr)
-{
-   png_debug(1, "in png_set_packing");
-
-   if (png_ptr == NULL)
-      return;
-
-   if (png_ptr->bit_depth < 8)
-   {
-      png_ptr->transformations |= PNG_PACK;
-      png_ptr->usr_bit_depth = 8;
-   }
-}
-#endif
-
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
-/* Turn on packed pixel swapping */
-void PNGAPI
-png_set_packswap(png_structp png_ptr)
-{
-   png_debug(1, "in png_set_packswap");
-
-   if (png_ptr == NULL)
-      return;
-
-   if (png_ptr->bit_depth < 8)
-      png_ptr->transformations |= PNG_PACKSWAP;
-}
-#endif
-
-#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
-void PNGAPI
-png_set_shift(png_structp png_ptr, png_const_color_8p true_bits)
-{
-   png_debug(1, "in png_set_shift");
-
-   if (png_ptr == NULL)
-      return;
-
-   png_ptr->transformations |= PNG_SHIFT;
-   png_ptr->shift = *true_bits;
-}
-#endif
-
-#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
-    defined(PNG_WRITE_INTERLACING_SUPPORTED)
-int PNGAPI
-png_set_interlace_handling(png_structp png_ptr)
-{
-   png_debug(1, "in png_set_interlace handling");
-
-   if (png_ptr && png_ptr->interlaced)
-   {
-      png_ptr->transformations |= PNG_INTERLACE;
-      return (7);
-   }
-
-   return (1);
-}
-#endif
-
-#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
-/* Add a filler byte on read, or remove a filler or alpha byte on write.
- * The filler type has changed in v0.95 to allow future 2-byte fillers
- * for 48-bit input data, as well as to avoid problems with some compilers
- * that don't like bytes as parameters.
- */
-void PNGAPI
-png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc)
-{
-   png_debug(1, "in png_set_filler");
-
-   if (png_ptr == NULL)
-      return;
-
-   png_ptr->transformations |= PNG_FILLER;
-   png_ptr->filler = (png_uint_16)filler;
-
-   if (filler_loc == PNG_FILLER_AFTER)
-      png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
-
-   else
-      png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
-
-   /* This should probably go in the "do_read_filler" routine.
-    * I attempted to do that in libpng-1.0.1a but that caused problems
-    * so I restored it in libpng-1.0.2a
-   */
-
-   if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
-   {
-      png_ptr->usr_channels = 4;
-   }
-
-   /* Also I added this in libpng-1.0.2a (what happens when we expand
-    * a less-than-8-bit grayscale to GA?) */
-
-   if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY && png_ptr->bit_depth >= 8)
-   {
-      png_ptr->usr_channels = 2;
-   }
-}
-
-/* Added to libpng-1.2.7 */
-void PNGAPI
-png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc)
-{
-   png_debug(1, "in png_set_add_alpha");
-
-   if (png_ptr == NULL)
-      return;
-
-   png_set_filler(png_ptr, filler, filler_loc);
-   png_ptr->transformations |= PNG_ADD_ALPHA;
-}
-
-#endif
-
-#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
-    defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
-void PNGAPI
-png_set_swap_alpha(png_structp png_ptr)
-{
-   png_debug(1, "in png_set_swap_alpha");
-
-   if (png_ptr == NULL)
-      return;
-
-   png_ptr->transformations |= PNG_SWAP_ALPHA;
-}
-#endif
-
-#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
-    defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
-void PNGAPI
-png_set_invert_alpha(png_structp png_ptr)
-{
-   png_debug(1, "in png_set_invert_alpha");
-
-   if (png_ptr == NULL)
-      return;
-
-   png_ptr->transformations |= PNG_INVERT_ALPHA;
-}
-#endif
-
-#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
-void PNGAPI
-png_set_invert_mono(png_structp png_ptr)
-{
-   png_debug(1, "in png_set_invert_mono");
-
-   if (png_ptr == NULL)
-      return;
-
-   png_ptr->transformations |= PNG_INVERT_MONO;
-}
-
-/* Invert monochrome grayscale data */
-void /* PRIVATE */
-png_do_invert(png_row_infop row_info, png_bytep row)
-{
-   png_debug(1, "in png_do_invert");
-
-  /* This test removed from libpng version 1.0.13 and 1.2.0:
-   *   if (row_info->bit_depth == 1 &&
-   */
-   if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
-   {
-      png_bytep rp = row;
-      png_size_t i;
-      png_size_t istop = row_info->rowbytes;
-
-      for (i = 0; i < istop; i++)
-      {
-         *rp = (png_byte)(~(*rp));
-         rp++;
-      }
-   }
-
-   else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
-      row_info->bit_depth == 8)
-   {
-      png_bytep rp = row;
-      png_size_t i;
-      png_size_t istop = row_info->rowbytes;
-
-      for (i = 0; i < istop; i += 2)
-      {
-         *rp = (png_byte)(~(*rp));
-         rp += 2;
-      }
-   }
-
-#ifdef PNG_16BIT_SUPPORTED
-   else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
-      row_info->bit_depth == 16)
-   {
-      png_bytep rp = row;
-      png_size_t i;
-      png_size_t istop = row_info->rowbytes;
-
-      for (i = 0; i < istop; i += 4)
-      {
-         *rp = (png_byte)(~(*rp));
-         *(rp + 1) = (png_byte)(~(*(rp + 1)));
-         rp += 4;
-      }
-   }
-#endif
-}
-#endif
-
-#ifdef PNG_16BIT_SUPPORTED
-#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
-/* Swaps byte order on 16 bit depth images */
-void /* PRIVATE */
-png_do_swap(png_row_infop row_info, png_bytep row)
-{
-   png_debug(1, "in png_do_swap");
-
-   if (row_info->bit_depth == 16)
-   {
-      png_bytep rp = row;
-      png_uint_32 i;
-      png_uint_32 istop= row_info->width * row_info->channels;
-
-      for (i = 0; i < istop; i++, rp += 2)
-      {
-         png_byte t = *rp;
-         *rp = *(rp + 1);
-         *(rp + 1) = t;
-      }
-   }
-}
-#endif
-#endif
-
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
-static PNG_CONST png_byte onebppswaptable[256] = {
-   0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
-   0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
-   0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
-   0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
-   0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
-   0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
-   0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
-   0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
-   0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
-   0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
-   0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
-   0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
-   0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
-   0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
-   0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
-   0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
-   0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
-   0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
-   0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
-   0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
-   0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
-   0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
-   0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
-   0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
-   0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
-   0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
-   0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
-   0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
-   0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
-   0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
-   0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
-   0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
-};
-
-static PNG_CONST png_byte twobppswaptable[256] = {
-   0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
-   0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
-   0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
-   0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
-   0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
-   0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
-   0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
-   0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
-   0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
-   0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
-   0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
-   0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
-   0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
-   0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
-   0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
-   0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
-   0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
-   0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
-   0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
-   0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
-   0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
-   0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
-   0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
-   0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
-   0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
-   0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
-   0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
-   0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
-   0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
-   0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
-   0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
-   0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
-};
-
-static PNG_CONST png_byte fourbppswaptable[256] = {
-   0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
-   0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
-   0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
-   0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
-   0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
-   0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
-   0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
-   0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
-   0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
-   0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
-   0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
-   0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
-   0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
-   0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
-   0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
-   0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
-   0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
-   0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
-   0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
-   0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
-   0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
-   0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
-   0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
-   0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
-   0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
-   0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
-   0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
-   0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
-   0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
-   0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
-   0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
-   0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
-};
-
-/* Swaps pixel packing order within bytes */
-void /* PRIVATE */
-png_do_packswap(png_row_infop row_info, png_bytep row)
-{
-   png_debug(1, "in png_do_packswap");
-
-   if (row_info->bit_depth < 8)
-   {
-      png_bytep rp;
-      png_const_bytep end, table;
-
-      end = row + row_info->rowbytes;
-
-      if (row_info->bit_depth == 1)
-         table = onebppswaptable;
-
-      else if (row_info->bit_depth == 2)
-         table = twobppswaptable;
-
-      else if (row_info->bit_depth == 4)
-         table = fourbppswaptable;
-
-      else
-         return;
-
-      for (rp = row; rp < end; rp++)
-         *rp = table[*rp];
-   }
-}
-#endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */
-
-#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
-    defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
-/* Remove a channel - this used to be 'png_do_strip_filler' but it used a
- * somewhat weird combination of flags to determine what to do.  All the calls
- * to png_do_strip_filler are changed in 1.5.2 to call this instead with the
- * correct arguments.
- *
- * The routine isn't general - the channel must be the channel at the start or
- * end (not in the middle) of each pixel.
- */
-void /* PRIVATE */
-png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
-{
-   png_bytep sp = row; /* source pointer */
-   png_bytep dp = row; /* destination pointer */
-   png_bytep ep = row + row_info->rowbytes; /* One beyond end of row */
-
-   /* At the start sp will point to the first byte to copy and dp to where
-    * it is copied to.  ep always points just beyond the end of the row, so
-    * the loop simply copies (channels-1) channels until sp reaches ep.
-    *
-    * at_start:        0 -- convert AG, XG, ARGB, XRGB, AAGG, XXGG, etc.
-    *            nonzero -- convert GA, GX, RGBA, RGBX, GGAA, RRGGBBXX, etc.
-    */
-
-   /* GA, GX, XG cases */
-   if (row_info->channels == 2)
-   {
-      if (row_info->bit_depth == 8)
-      {
-         if (at_start) /* Skip initial filler */
-            ++sp;
-         else          /* Skip initial channel and, for sp, the filler */
-            sp += 2, ++dp;
-
-         /* For a 1 pixel wide image there is nothing to do */
-         while (sp < ep)
-            *dp++ = *sp, sp += 2;
-
-         row_info->pixel_depth = 8;
-      }
-
-      else if (row_info->bit_depth == 16)
-      {
-         if (at_start) /* Skip initial filler */
-            sp += 2;
-         else          /* Skip initial channel and, for sp, the filler */
-            sp += 4, dp += 2;
-
-         while (sp < ep)
-            *dp++ = *sp++, *dp++ = *sp, sp += 3;
-
-         row_info->pixel_depth = 16;
-      }
-
-      else
-         return; /* bad bit depth */
-
-      row_info->channels = 1;
-
-      /* Finally fix the color type if it records an alpha channel */
-      if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
-         row_info->color_type = PNG_COLOR_TYPE_GRAY;
-   }
-
-   /* RGBA, RGBX, XRGB cases */
-   else if (row_info->channels == 4)
-   {
-      if (row_info->bit_depth == 8)
-      {
-         if (at_start) /* Skip initial filler */
-            ++sp;
-         else          /* Skip initial channels and, for sp, the filler */
-            sp += 4, dp += 3;
-
-         /* Note that the loop adds 3 to dp and 4 to sp each time. */
-         while (sp < ep)
-            *dp++ = *sp++, *dp++ = *sp++, *dp++ = *sp, sp += 2;
-
-         row_info->pixel_depth = 24;
-      }
-
-      else if (row_info->bit_depth == 16)
-      {
-         if (at_start) /* Skip initial filler */
-            sp += 2;
-         else          /* Skip initial channels and, for sp, the filler */
-            sp += 8, dp += 6;
-
-         while (sp < ep)
-         {
-            /* Copy 6 bytes, skip 2 */
-            *dp++ = *sp++, *dp++ = *sp++;
-            *dp++ = *sp++, *dp++ = *sp++;
-            *dp++ = *sp++, *dp++ = *sp, sp += 3;
-         }
-
-         row_info->pixel_depth = 48;
-      }
-
-      else
-         return; /* bad bit depth */
-
-      row_info->channels = 3;
-
-      /* Finally fix the color type if it records an alpha channel */
-      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
-         row_info->color_type = PNG_COLOR_TYPE_RGB;
-   }
-
-   else
-      return; /* The filler channel has gone already */
-
-   /* Fix the rowbytes value. */
-   row_info->rowbytes = dp-row;
-}
-#endif
-
-#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
-/* Swaps red and blue bytes within a pixel */
-void /* PRIVATE */
-png_do_bgr(png_row_infop row_info, png_bytep row)
-{
-   png_debug(1, "in png_do_bgr");
-
-   if ((row_info->color_type & PNG_COLOR_MASK_COLOR))
-   {
-      png_uint_32 row_width = row_info->width;
-      if (row_info->bit_depth == 8)
-      {
-         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
-         {
-            png_bytep rp;
-            png_uint_32 i;
-
-            for (i = 0, rp = row; i < row_width; i++, rp += 3)
-            {
-               png_byte save = *rp;
-               *rp = *(rp + 2);
-               *(rp + 2) = save;
-            }
-         }
-
-         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
-         {
-            png_bytep rp;
-            png_uint_32 i;
-
-            for (i = 0, rp = row; i < row_width; i++, rp += 4)
-            {
-               png_byte save = *rp;
-               *rp = *(rp + 2);
-               *(rp + 2) = save;
-            }
-         }
-      }
-
-#ifdef PNG_16BIT_SUPPORTED
-      else if (row_info->bit_depth == 16)
-      {
-         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
-         {
-            png_bytep rp;
-            png_uint_32 i;
-
-            for (i = 0, rp = row; i < row_width; i++, rp += 6)
-            {
-               png_byte save = *rp;
-               *rp = *(rp + 4);
-               *(rp + 4) = save;
-               save = *(rp + 1);
-               *(rp + 1) = *(rp + 5);
-               *(rp + 5) = save;
-            }
-         }
-
-         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
-         {
-            png_bytep rp;
-            png_uint_32 i;
-
-            for (i = 0, rp = row; i < row_width; i++, rp += 8)
-            {
-               png_byte save = *rp;
-               *rp = *(rp + 4);
-               *(rp + 4) = save;
-               save = *(rp + 1);
-               *(rp + 1) = *(rp + 5);
-               *(rp + 5) = save;
-            }
-         }
-      }
-#endif
-   }
-}
-#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */
-
-#if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \
-    defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED)
-/* Added at libpng-1.5.10 */
-void /* PRIVATE */
-png_do_check_palette_indexes(png_structp png_ptr, png_row_infop row_info)
-{
-   if (png_ptr->num_palette < (1 << row_info->bit_depth) &&
-      png_ptr->num_palette > 0) /* num_palette can be 0 in MNG files */
-   {
-      /* Calculations moved outside switch in an attempt to stop different
-       * compiler warnings.  'padding' is in *bits* within the last byte, it is
-       * an 'int' because pixel_depth becomes an 'int' in the expression below,
-       * and this calculation is used because it avoids warnings that other
-       * forms produced on either GCC or MSVC.
-       */
-      int padding = (-row_info->pixel_depth * row_info->width) & 7;
-      png_bytep rp = png_ptr->row_buf + row_info->rowbytes;
-
-      switch (row_info->bit_depth)
-      {
-         case 1:
-         {
-            /* in this case, all bytes must be 0 so we don't need
-             * to unpack the pixels except for the rightmost one.
-             */
-            for (; rp > png_ptr->row_buf; rp--)
-            {
-              if (*rp >> padding != 0)
-                 png_ptr->num_palette_max = 1;
-              padding = 0;
-            }
-
-            break;
-         }
-
-         case 2:
-         {
-            for (; rp > png_ptr->row_buf; rp--)
-            {
-              int i = ((*rp >> padding) & 0x03);
-
-              if (i > png_ptr->num_palette_max)
-                 png_ptr->num_palette_max = i;
-
-              i = (((*rp >> padding) >> 2) & 0x03);
-
-              if (i > png_ptr->num_palette_max)
-                 png_ptr->num_palette_max = i;
-
-              i = (((*rp >> padding) >> 4) & 0x03);
-
-              if (i > png_ptr->num_palette_max)
-                 png_ptr->num_palette_max = i;
-
-              i = (((*rp >> padding) >> 6) & 0x03);
-
-              if (i > png_ptr->num_palette_max)
-                 png_ptr->num_palette_max = i;
-
-              padding = 0;
-            }
-
-            break;
-         }
-
-         case 4:
-         {
-            for (; rp > png_ptr->row_buf; rp--)
-            {
-              int i = ((*rp >> padding) & 0x0f);
-
-              if (i > png_ptr->num_palette_max)
-                 png_ptr->num_palette_max = i;
-
-              i = (((*rp >> padding) >> 4) & 0x0f);
-
-              if (i > png_ptr->num_palette_max)
-                 png_ptr->num_palette_max = i;
-
-              padding = 0;
-            }
-
-            break;
-         }
-
-         case 8:
-         {
-            for (; rp > png_ptr->row_buf; rp--)
-            {
-               if (*rp > png_ptr->num_palette_max)
-                  png_ptr->num_palette_max = (int) *rp;
-            }
-
-            break;
-         }
-
-         default:
-            break;
-      }
-   }
-}
-#endif /* PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED */
-
-#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
-    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
-#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
-void PNGAPI
-png_set_user_transform_info(png_structp png_ptr, png_voidp
-   user_transform_ptr, int user_transform_depth, int user_transform_channels)
-{
-   png_debug(1, "in png_set_user_transform_info");
-
-   if (png_ptr == NULL)
-      return;
-   png_ptr->user_transform_ptr = user_transform_ptr;
-   png_ptr->user_transform_depth = (png_byte)user_transform_depth;
-   png_ptr->user_transform_channels = (png_byte)user_transform_channels;
-}
-#endif
-
-/* This function returns a pointer to the user_transform_ptr associated with
- * the user transform functions.  The application should free any memory
- * associated with this pointer before png_write_destroy and png_read_destroy
- * are called.
- */
-#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
-png_voidp PNGAPI
-png_get_user_transform_ptr(png_const_structp png_ptr)
-{
-   if (png_ptr == NULL)
-      return (NULL);
-
-   return ((png_voidp)png_ptr->user_transform_ptr);
-}
-#endif
-
-#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED
-png_uint_32 PNGAPI
-png_get_current_row_number(png_const_structp png_ptr)
-{
-   /* See the comments in png.h - this is the sub-image row when reading and
-    * interlaced image.
-    */
-   if (png_ptr != NULL)
-      return png_ptr->row_number;
-
-   return PNG_UINT_32_MAX; /* help the app not to fail silently */
-}
-
-png_byte PNGAPI
-png_get_current_pass_number(png_const_structp png_ptr)
-{
-   if (png_ptr != NULL)
-      return png_ptr->pass;
-   return 8; /* invalid */
-}
-#endif /* PNG_USER_TRANSFORM_INFO_SUPPORTED */
-#endif /* PNG_READ_USER_TRANSFORM_SUPPORTED ||
-          PNG_WRITE_USER_TRANSFORM_SUPPORTED */
-#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
+
+/* pngtrans.c - transforms the data in a row (used by both readers and writers)
+ *
+ * Last changed in libpng 1.6.15 [November 20, 2014]
+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+#include "pngpriv.h"
+
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+
+#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
+/* Turn on BGR-to-RGB mapping */
+void PNGAPI
+png_set_bgr(png_structrp png_ptr)
+{
+   png_debug(1, "in png_set_bgr");
+
+   if (png_ptr == NULL)
+      return;
+
+   png_ptr->transformations |= PNG_BGR;
+}
+#endif
+
+#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
+/* Turn on 16 bit byte swapping */
+void PNGAPI
+png_set_swap(png_structrp png_ptr)
+{
+   png_debug(1, "in png_set_swap");
+
+   if (png_ptr == NULL)
+      return;
+
+   if (png_ptr->bit_depth == 16)
+      png_ptr->transformations |= PNG_SWAP_BYTES;
+}
+#endif
+
+#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
+/* Turn on pixel packing */
+void PNGAPI
+png_set_packing(png_structrp png_ptr)
+{
+   png_debug(1, "in png_set_packing");
+
+   if (png_ptr == NULL)
+      return;
+
+   if (png_ptr->bit_depth < 8)
+   {
+      png_ptr->transformations |= PNG_PACK;
+#     ifdef PNG_WRITE_SUPPORTED
+         png_ptr->usr_bit_depth = 8;
+#     endif
+   }
+}
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+/* Turn on packed pixel swapping */
+void PNGAPI
+png_set_packswap(png_structrp png_ptr)
+{
+   png_debug(1, "in png_set_packswap");
+
+   if (png_ptr == NULL)
+      return;
+
+   if (png_ptr->bit_depth < 8)
+      png_ptr->transformations |= PNG_PACKSWAP;
+}
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
+void PNGAPI
+png_set_shift(png_structrp png_ptr, png_const_color_8p true_bits)
+{
+   png_debug(1, "in png_set_shift");
+
+   if (png_ptr == NULL)
+      return;
+
+   png_ptr->transformations |= PNG_SHIFT;
+   png_ptr->shift = *true_bits;
+}
+#endif
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
+    defined(PNG_WRITE_INTERLACING_SUPPORTED)
+int PNGAPI
+png_set_interlace_handling(png_structrp png_ptr)
+{
+   png_debug(1, "in png_set_interlace handling");
+
+   if (png_ptr != 0 && png_ptr->interlaced != 0)
+   {
+      png_ptr->transformations |= PNG_INTERLACE;
+      return (7);
+   }
+
+   return (1);
+}
+#endif
+
+#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
+/* Add a filler byte on read, or remove a filler or alpha byte on write.
+ * The filler type has changed in v0.95 to allow future 2-byte fillers
+ * for 48-bit input data, as well as to avoid problems with some compilers
+ * that don't like bytes as parameters.
+ */
+void PNGAPI
+png_set_filler(png_structrp png_ptr, png_uint_32 filler, int filler_loc)
+{
+   png_debug(1, "in png_set_filler");
+
+   if (png_ptr == NULL)
+      return;
+
+   /* In libpng 1.6 it is possible to determine whether this is a read or write
+    * operation and therefore to do more checking here for a valid call.
+    */
+   if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
+   {
+#     ifdef PNG_READ_FILLER_SUPPORTED
+         /* On read png_set_filler is always valid, regardless of the base PNG
+          * format, because other transformations can give a format where the
+          * filler code can execute (basically an 8 or 16-bit component RGB or G
+          * format.)
+          *
+          * NOTE: usr_channels is not used by the read code!  (This has led to
+          * confusion in the past.)  The filler is only used in the read code.
+          */
+         png_ptr->filler = (png_uint_16)filler;
+#     else
+         png_app_error(png_ptr, "png_set_filler not supported on read");
+         PNG_UNUSED(filler) /* not used in the write case */
+         return;
+#     endif
+   }
+
+   else /* write */
+   {
+#     ifdef PNG_WRITE_FILLER_SUPPORTED
+         /* On write the usr_channels parameter must be set correctly at the
+          * start to record the number of channels in the app-supplied data.
+          */
+         switch (png_ptr->color_type)
+         {
+            case PNG_COLOR_TYPE_RGB:
+               png_ptr->usr_channels = 4;
+               break;
+
+            case PNG_COLOR_TYPE_GRAY:
+               if (png_ptr->bit_depth >= 8)
+               {
+                  png_ptr->usr_channels = 2;
+                  break;
+               }
+
+               else
+               {
+                  /* There simply isn't any code in libpng to strip out bits
+                   * from bytes when the components are less than a byte in
+                   * size!
+                   */
+                  png_app_error(png_ptr,
+                     "png_set_filler is invalid for low bit depth gray output");
+                  return;
+               }
+
+            default:
+               png_app_error(png_ptr,
+                  "png_set_filler: inappropriate color type");
+               return;
+         }
+#     else
+         png_app_error(png_ptr, "png_set_filler not supported on write");
+         return;
+#     endif
+   }
+
+   /* Here on success - libpng supports the operation, set the transformation
+    * and the flag to say where the filler channel is.
+    */
+   png_ptr->transformations |= PNG_FILLER;
+
+   if (filler_loc == PNG_FILLER_AFTER)
+      png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
+
+   else
+      png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
+}
+
+/* Added to libpng-1.2.7 */
+void PNGAPI
+png_set_add_alpha(png_structrp png_ptr, png_uint_32 filler, int filler_loc)
+{
+   png_debug(1, "in png_set_add_alpha");
+
+   if (png_ptr == NULL)
+      return;
+
+   png_set_filler(png_ptr, filler, filler_loc);
+   /* The above may fail to do anything. */
+   if ((png_ptr->transformations & PNG_FILLER) != 0)
+      png_ptr->transformations |= PNG_ADD_ALPHA;
+}
+
+#endif
+
+#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
+    defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
+void PNGAPI
+png_set_swap_alpha(png_structrp png_ptr)
+{
+   png_debug(1, "in png_set_swap_alpha");
+
+   if (png_ptr == NULL)
+      return;
+
+   png_ptr->transformations |= PNG_SWAP_ALPHA;
+}
+#endif
+
+#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
+    defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
+void PNGAPI
+png_set_invert_alpha(png_structrp png_ptr)
+{
+   png_debug(1, "in png_set_invert_alpha");
+
+   if (png_ptr == NULL)
+      return;
+
+   png_ptr->transformations |= PNG_INVERT_ALPHA;
+}
+#endif
+
+#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
+void PNGAPI
+png_set_invert_mono(png_structrp png_ptr)
+{
+   png_debug(1, "in png_set_invert_mono");
+
+   if (png_ptr == NULL)
+      return;
+
+   png_ptr->transformations |= PNG_INVERT_MONO;
+}
+
+/* Invert monochrome grayscale data */
+void /* PRIVATE */
+png_do_invert(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_invert");
+
+  /* This test removed from libpng version 1.0.13 and 1.2.0:
+   *   if (row_info->bit_depth == 1 &&
+   */
+   if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
+   {
+      png_bytep rp = row;
+      png_size_t i;
+      png_size_t istop = row_info->rowbytes;
+
+      for (i = 0; i < istop; i++)
+      {
+         *rp = (png_byte)(~(*rp));
+         rp++;
+      }
+   }
+
+   else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
+      row_info->bit_depth == 8)
+   {
+      png_bytep rp = row;
+      png_size_t i;
+      png_size_t istop = row_info->rowbytes;
+
+      for (i = 0; i < istop; i += 2)
+      {
+         *rp = (png_byte)(~(*rp));
+         rp += 2;
+      }
+   }
+
+#ifdef PNG_16BIT_SUPPORTED
+   else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
+      row_info->bit_depth == 16)
+   {
+      png_bytep rp = row;
+      png_size_t i;
+      png_size_t istop = row_info->rowbytes;
+
+      for (i = 0; i < istop; i += 4)
+      {
+         *rp = (png_byte)(~(*rp));
+         *(rp + 1) = (png_byte)(~(*(rp + 1)));
+         rp += 4;
+      }
+   }
+#endif
+}
+#endif
+
+#ifdef PNG_16BIT_SUPPORTED
+#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
+/* Swaps byte order on 16 bit depth images */
+void /* PRIVATE */
+png_do_swap(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_swap");
+
+   if (row_info->bit_depth == 16)
+   {
+      png_bytep rp = row;
+      png_uint_32 i;
+      png_uint_32 istop= row_info->width * row_info->channels;
+
+      for (i = 0; i < istop; i++, rp += 2)
+      {
+#ifdef PNG_BUILTIN_BSWAP16_SUPPORTED
+         /* Feature added to libpng-1.6.11 for testing purposes, not
+          * enabled by default.
+          */
+         *(png_uint_16*)rp = __builtin_bswap16(*(png_uint_16*)rp);
+#else
+         png_byte t = *rp;
+         *rp = *(rp + 1);
+         *(rp + 1) = t;
+#endif
+      }
+   }
+}
+#endif
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+static PNG_CONST png_byte onebppswaptable[256] = {
+   0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
+   0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
+   0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
+   0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
+   0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
+   0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
+   0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
+   0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
+   0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
+   0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
+   0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
+   0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
+   0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
+   0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
+   0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
+   0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
+   0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
+   0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
+   0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
+   0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
+   0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
+   0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
+   0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
+   0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
+   0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
+   0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
+   0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
+   0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
+   0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
+   0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
+   0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
+   0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
+};
+
+static PNG_CONST png_byte twobppswaptable[256] = {
+   0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
+   0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
+   0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
+   0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
+   0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
+   0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
+   0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
+   0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
+   0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
+   0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
+   0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
+   0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
+   0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
+   0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
+   0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
+   0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
+   0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
+   0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
+   0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
+   0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
+   0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
+   0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
+   0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
+   0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
+   0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
+   0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
+   0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
+   0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
+   0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
+   0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
+   0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
+   0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
+};
+
+static PNG_CONST png_byte fourbppswaptable[256] = {
+   0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
+   0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
+   0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
+   0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
+   0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
+   0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
+   0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
+   0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
+   0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
+   0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
+   0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
+   0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
+   0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
+   0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
+   0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
+   0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
+   0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
+   0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
+   0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
+   0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
+   0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
+   0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
+   0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
+   0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
+   0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
+   0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
+   0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
+   0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
+   0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
+   0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
+   0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
+   0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
+};
+
+/* Swaps pixel packing order within bytes */
+void /* PRIVATE */
+png_do_packswap(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_packswap");
+
+   if (row_info->bit_depth < 8)
+   {
+      png_bytep rp;
+      png_const_bytep end, table;
+
+      end = row + row_info->rowbytes;
+
+      if (row_info->bit_depth == 1)
+         table = onebppswaptable;
+
+      else if (row_info->bit_depth == 2)
+         table = twobppswaptable;
+
+      else if (row_info->bit_depth == 4)
+         table = fourbppswaptable;
+
+      else
+         return;
+
+      for (rp = row; rp < end; rp++)
+         *rp = table[*rp];
+   }
+}
+#endif /* PACKSWAP || WRITE_PACKSWAP */
+
+#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
+    defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
+/* Remove a channel - this used to be 'png_do_strip_filler' but it used a
+ * somewhat weird combination of flags to determine what to do.  All the calls
+ * to png_do_strip_filler are changed in 1.5.2 to call this instead with the
+ * correct arguments.
+ *
+ * The routine isn't general - the channel must be the channel at the start or
+ * end (not in the middle) of each pixel.
+ */
+void /* PRIVATE */
+png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
+{
+   png_bytep sp = row; /* source pointer */
+   png_bytep dp = row; /* destination pointer */
+   png_bytep ep = row + row_info->rowbytes; /* One beyond end of row */
+
+   /* At the start sp will point to the first byte to copy and dp to where
+    * it is copied to.  ep always points just beyond the end of the row, so
+    * the loop simply copies (channels-1) channels until sp reaches ep.
+    *
+    * at_start:        0 -- convert AG, XG, ARGB, XRGB, AAGG, XXGG, etc.
+    *            nonzero -- convert GA, GX, RGBA, RGBX, GGAA, RRGGBBXX, etc.
+    */
+
+   /* GA, GX, XG cases */
+   if (row_info->channels == 2)
+   {
+      if (row_info->bit_depth == 8)
+      {
+         if (at_start != 0) /* Skip initial filler */
+            ++sp;
+         else          /* Skip initial channel and, for sp, the filler */
+            sp += 2, ++dp;
+
+         /* For a 1 pixel wide image there is nothing to do */
+         while (sp < ep)
+            *dp++ = *sp, sp += 2;
+
+         row_info->pixel_depth = 8;
+      }
+
+      else if (row_info->bit_depth == 16)
+      {
+         if (at_start != 0) /* Skip initial filler */
+            sp += 2;
+         else          /* Skip initial channel and, for sp, the filler */
+            sp += 4, dp += 2;
+
+         while (sp < ep)
+            *dp++ = *sp++, *dp++ = *sp, sp += 3;
+
+         row_info->pixel_depth = 16;
+      }
+
+      else
+         return; /* bad bit depth */
+
+      row_info->channels = 1;
+
+      /* Finally fix the color type if it records an alpha channel */
+      if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+         row_info->color_type = PNG_COLOR_TYPE_GRAY;
+   }
+
+   /* RGBA, RGBX, XRGB cases */
+   else if (row_info->channels == 4)
+   {
+      if (row_info->bit_depth == 8)
+      {
+         if (at_start != 0) /* Skip initial filler */
+            ++sp;
+         else          /* Skip initial channels and, for sp, the filler */
+            sp += 4, dp += 3;
+
+         /* Note that the loop adds 3 to dp and 4 to sp each time. */
+         while (sp < ep)
+            *dp++ = *sp++, *dp++ = *sp++, *dp++ = *sp, sp += 2;
+
+         row_info->pixel_depth = 24;
+      }
+
+      else if (row_info->bit_depth == 16)
+      {
+         if (at_start != 0) /* Skip initial filler */
+            sp += 2;
+         else          /* Skip initial channels and, for sp, the filler */
+            sp += 8, dp += 6;
+
+         while (sp < ep)
+         {
+            /* Copy 6 bytes, skip 2 */
+            *dp++ = *sp++, *dp++ = *sp++;
+            *dp++ = *sp++, *dp++ = *sp++;
+            *dp++ = *sp++, *dp++ = *sp, sp += 3;
+         }
+
+         row_info->pixel_depth = 48;
+      }
+
+      else
+         return; /* bad bit depth */
+
+      row_info->channels = 3;
+
+      /* Finally fix the color type if it records an alpha channel */
+      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+         row_info->color_type = PNG_COLOR_TYPE_RGB;
+   }
+
+   else
+      return; /* The filler channel has gone already */
+
+   /* Fix the rowbytes value. */
+   row_info->rowbytes = dp-row;
+}
+#endif
+
+#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
+/* Swaps red and blue bytes within a pixel */
+void /* PRIVATE */
+png_do_bgr(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_bgr");
+
+   if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
+   {
+      png_uint_32 row_width = row_info->width;
+      if (row_info->bit_depth == 8)
+      {
+         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+         {
+            png_bytep rp;
+            png_uint_32 i;
+
+            for (i = 0, rp = row; i < row_width; i++, rp += 3)
+            {
+               png_byte save = *rp;
+               *rp = *(rp + 2);
+               *(rp + 2) = save;
+            }
+         }
+
+         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+         {
+            png_bytep rp;
+            png_uint_32 i;
+
+            for (i = 0, rp = row; i < row_width; i++, rp += 4)
+            {
+               png_byte save = *rp;
+               *rp = *(rp + 2);
+               *(rp + 2) = save;
+            }
+         }
+      }
+
+#ifdef PNG_16BIT_SUPPORTED
+      else if (row_info->bit_depth == 16)
+      {
+         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+         {
+            png_bytep rp;
+            png_uint_32 i;
+
+            for (i = 0, rp = row; i < row_width; i++, rp += 6)
+            {
+               png_byte save = *rp;
+               *rp = *(rp + 4);
+               *(rp + 4) = save;
+               save = *(rp + 1);
+               *(rp + 1) = *(rp + 5);
+               *(rp + 5) = save;
+            }
+         }
+
+         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+         {
+            png_bytep rp;
+            png_uint_32 i;
+
+            for (i = 0, rp = row; i < row_width; i++, rp += 8)
+            {
+               png_byte save = *rp;
+               *rp = *(rp + 4);
+               *(rp + 4) = save;
+               save = *(rp + 1);
+               *(rp + 1) = *(rp + 5);
+               *(rp + 5) = save;
+            }
+         }
+      }
+#endif
+   }
+}
+#endif /* READ_BGR || WRITE_BGR */
+
+#if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \
+    defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED)
+/* Added at libpng-1.5.10 */
+void /* PRIVATE */
+png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info)
+{
+   if (png_ptr->num_palette < (1 << row_info->bit_depth) &&
+      png_ptr->num_palette > 0) /* num_palette can be 0 in MNG files */
+   {
+      /* Calculations moved outside switch in an attempt to stop different
+       * compiler warnings.  'padding' is in *bits* within the last byte, it is
+       * an 'int' because pixel_depth becomes an 'int' in the expression below,
+       * and this calculation is used because it avoids warnings that other
+       * forms produced on either GCC or MSVC.
+       */
+      int padding = (-row_info->pixel_depth * row_info->width) & 7;
+      png_bytep rp = png_ptr->row_buf + row_info->rowbytes;
+
+      switch (row_info->bit_depth)
+      {
+         case 1:
+         {
+            /* in this case, all bytes must be 0 so we don't need
+             * to unpack the pixels except for the rightmost one.
+             */
+            for (; rp > png_ptr->row_buf; rp--)
+            {
+              if (*rp >> padding != 0)
+                 png_ptr->num_palette_max = 1;
+              padding = 0;
+            }
+
+            break;
+         }
+
+         case 2:
+         {
+            for (; rp > png_ptr->row_buf; rp--)
+            {
+              int i = ((*rp >> padding) & 0x03);
+
+              if (i > png_ptr->num_palette_max)
+                 png_ptr->num_palette_max = i;
+
+              i = (((*rp >> padding) >> 2) & 0x03);
+
+              if (i > png_ptr->num_palette_max)
+                 png_ptr->num_palette_max = i;
+
+              i = (((*rp >> padding) >> 4) & 0x03);
+
+              if (i > png_ptr->num_palette_max)
+                 png_ptr->num_palette_max = i;
+
+              i = (((*rp >> padding) >> 6) & 0x03);
+
+              if (i > png_ptr->num_palette_max)
+                 png_ptr->num_palette_max = i;
+
+              padding = 0;
+            }
+
+            break;
+         }
+
+         case 4:
+         {
+            for (; rp > png_ptr->row_buf; rp--)
+            {
+              int i = ((*rp >> padding) & 0x0f);
+
+              if (i > png_ptr->num_palette_max)
+                 png_ptr->num_palette_max = i;
+
+              i = (((*rp >> padding) >> 4) & 0x0f);
+
+              if (i > png_ptr->num_palette_max)
+                 png_ptr->num_palette_max = i;
+
+              padding = 0;
+            }
+
+            break;
+         }
+
+         case 8:
+         {
+            for (; rp > png_ptr->row_buf; rp--)
+            {
+               if (*rp > png_ptr->num_palette_max)
+                  png_ptr->num_palette_max = (int) *rp;
+            }
+
+            break;
+         }
+
+         default:
+            break;
+      }
+   }
+}
+#endif /* CHECK_FOR_INVALID_INDEX */
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
+void PNGAPI
+png_set_user_transform_info(png_structrp png_ptr, png_voidp
+   user_transform_ptr, int user_transform_depth, int user_transform_channels)
+{
+   png_debug(1, "in png_set_user_transform_info");
+
+   if (png_ptr == NULL)
+      return;
+
+#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
+   if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
+      (png_ptr->flags & PNG_FLAG_ROW_INIT) != 0)
+   {
+      png_app_error(png_ptr,
+            "info change after png_start_read_image or png_read_update_info");
+      return;
+   }
+#endif
+
+   png_ptr->user_transform_ptr = user_transform_ptr;
+   png_ptr->user_transform_depth = (png_byte)user_transform_depth;
+   png_ptr->user_transform_channels = (png_byte)user_transform_channels;
+}
+#endif
+
+/* This function returns a pointer to the user_transform_ptr associated with
+ * the user transform functions.  The application should free any memory
+ * associated with this pointer before png_write_destroy and png_read_destroy
+ * are called.
+ */
+#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
+png_voidp PNGAPI
+png_get_user_transform_ptr(png_const_structrp png_ptr)
+{
+   if (png_ptr == NULL)
+      return (NULL);
+
+   return png_ptr->user_transform_ptr;
+}
+#endif
+
+#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED
+png_uint_32 PNGAPI
+png_get_current_row_number(png_const_structrp png_ptr)
+{
+   /* See the comments in png.h - this is the sub-image row when reading an
+    * interlaced image.
+    */
+   if (png_ptr != NULL)
+      return png_ptr->row_number;
+
+   return PNG_UINT_32_MAX; /* help the app not to fail silently */
+}
+
+png_byte PNGAPI
+png_get_current_pass_number(png_const_structrp png_ptr)
+{
+   if (png_ptr != NULL)
+      return png_ptr->pass;
+   return 8; /* invalid */
+}
+#endif /* USER_TRANSFORM_INFO */
+#endif /* READ_USER_TRANSFORM || WRITE_USER_TRANSFORM */
+#endif /* READ || WRITE */
diff --git a/Source/LibPNG/pngwio.c b/Source/LibPNG/pngwio.c
index 8eacf9f..0a40948 100644
--- a/Source/LibPNG/pngwio.c
+++ b/Source/LibPNG/pngwio.c
@@ -1,254 +1,168 @@
-
-/* pngwio.c - functions for data output
- *
- * Last changed in libpng 1.5.0 [January 6, 2011]
- * Copyright (c) 1998-2011 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- *
- * This file provides a location for all output.  Users who need
- * special handling are expected to write functions that have the same
- * arguments as these and perform similar functions, but that possibly
- * use different output methods.  Note that you shouldn't change these
- * functions, but rather write replacement functions and then change
- * them at run time with png_set_write_fn(...).
- */
-
-#include "pngpriv.h"
-
-#ifdef PNG_WRITE_SUPPORTED
-
-/* Write the data to whatever output you are using.  The default routine
- * writes to a file pointer.  Note that this routine sometimes gets called
- * with very small lengths, so you should implement some kind of simple
- * buffering if you are using unbuffered writes.  This should never be asked
- * to write more than 64K on a 16 bit machine.
- */
-
-void /* PRIVATE */
-png_write_data(png_structp png_ptr, png_const_bytep data, png_size_t length)
-{
-   /* NOTE: write_data_fn must not change the buffer! */
-   if (png_ptr->write_data_fn != NULL )
-      (*(png_ptr->write_data_fn))(png_ptr, (png_bytep)data, length);
-
-   else
-      png_error(png_ptr, "Call to NULL write function");
-}
-
-#ifdef PNG_STDIO_SUPPORTED
-/* This is the function that does the actual writing of data.  If you are
- * not writing to a standard C stream, you should create a replacement
- * write_data function and use it at run time with png_set_write_fn(), rather
- * than changing the library.
- */
-#ifndef USE_FAR_KEYWORD
-void PNGCBAPI
-png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
-{
-   png_size_t check;
-
-   if (png_ptr == NULL)
-      return;
-
-   check = fwrite(data, 1, length, (png_FILE_p)(png_ptr->io_ptr));
-
-   if (check != length)
-      png_error(png_ptr, "Write Error");
-}
-#else
-/* This is the model-independent version. Since the standard I/O library
- * can't handle far buffers in the medium and small models, we have to copy
- * the data.
- */
-
-#define NEAR_BUF_SIZE 1024
-#define MIN(a,b) (a <= b ? a : b)
-
-void PNGCBAPI
-png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
-{
-   png_uint_32 check;
-   png_byte *near_data;  /* Needs to be "png_byte *" instead of "png_bytep" */
-   png_FILE_p io_ptr;
-
-   if (png_ptr == NULL)
-      return;
-
-   /* Check if data really is near. If so, use usual code. */
-   near_data = (png_byte *)CVT_PTR_NOCHECK(data);
-   io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
-
-   if ((png_bytep)near_data == data)
-   {
-      check = fwrite(near_data, 1, length, io_ptr);
-   }
-
-   else
-   {
-      png_byte buf[NEAR_BUF_SIZE];
-      png_size_t written, remaining, err;
-      check = 0;
-      remaining = length;
-
-      do
-      {
-         written = MIN(NEAR_BUF_SIZE, remaining);
-         png_memcpy(buf, data, written); /* Copy far buffer to near buffer */
-         err = fwrite(buf, 1, written, io_ptr);
-
-         if (err != written)
-            break;
-
-         else
-            check += err;
-
-         data += written;
-         remaining -= written;
-      }
-      while (remaining != 0);
-   }
-
-   if (check != length)
-      png_error(png_ptr, "Write Error");
-}
-
-#endif
-#endif
-
-/* This function is called to output any data pending writing (normally
- * to disk).  After png_flush is called, there should be no data pending
- * writing in any buffers.
- */
-#ifdef PNG_WRITE_FLUSH_SUPPORTED
-void /* PRIVATE */
-png_flush(png_structp png_ptr)
-{
-   if (png_ptr->output_flush_fn != NULL)
-      (*(png_ptr->output_flush_fn))(png_ptr);
-}
-
-#  ifdef PNG_STDIO_SUPPORTED
-void PNGCBAPI
-png_default_flush(png_structp png_ptr)
-{
-   png_FILE_p io_ptr;
-
-   if (png_ptr == NULL)
-      return;
-
-   io_ptr = (png_FILE_p)CVT_PTR((png_ptr->io_ptr));
-   fflush(io_ptr);
-}
-#  endif
-#endif
-
-/* This function allows the application to supply new output functions for
- * libpng if standard C streams aren't being used.
- *
- * This function takes as its arguments:
- * png_ptr       - pointer to a png output data structure
- * io_ptr        - pointer to user supplied structure containing info about
- *                 the output functions.  May be NULL.
- * write_data_fn - pointer to a new output function that takes as its
- *                 arguments a pointer to a png_struct, a pointer to
- *                 data to be written, and a 32-bit unsigned int that is
- *                 the number of bytes to be written.  The new write
- *                 function should call png_error(png_ptr, "Error msg")
- *                 to exit and output any fatal error messages.  May be
- *                 NULL, in which case libpng's default function will
- *                 be used.
- * flush_data_fn - pointer to a new flush function that takes as its
- *                 arguments a pointer to a png_struct.  After a call to
- *                 the flush function, there should be no data in any buffers
- *                 or pending transmission.  If the output method doesn't do
- *                 any buffering of output, a function prototype must still be
- *                 supplied although it doesn't have to do anything.  If
- *                 PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile
- *                 time, output_flush_fn will be ignored, although it must be
- *                 supplied for compatibility.  May be NULL, in which case
- *                 libpng's default function will be used, if
- *                 PNG_WRITE_FLUSH_SUPPORTED is defined.  This is not
- *                 a good idea if io_ptr does not point to a standard
- *                 *FILE structure.
- */
-void PNGAPI
-png_set_write_fn(png_structp png_ptr, png_voidp io_ptr,
-    png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)
-{
-   if (png_ptr == NULL)
-      return;
-
-   png_ptr->io_ptr = io_ptr;
-
-#ifdef PNG_STDIO_SUPPORTED
-   if (write_data_fn != NULL)
-      png_ptr->write_data_fn = write_data_fn;
-
-   else
-      png_ptr->write_data_fn = png_default_write_data;
-#else
-   png_ptr->write_data_fn = write_data_fn;
-#endif
-
-#ifdef PNG_WRITE_FLUSH_SUPPORTED
-#  ifdef PNG_STDIO_SUPPORTED
-
-   if (output_flush_fn != NULL)
-      png_ptr->output_flush_fn = output_flush_fn;
-
-   else
-      png_ptr->output_flush_fn = png_default_flush;
-
-#  else
-   png_ptr->output_flush_fn = output_flush_fn;
-#  endif
-#endif /* PNG_WRITE_FLUSH_SUPPORTED */
-
-   /* It is an error to read while writing a png file */
-   if (png_ptr->read_data_fn != NULL)
-   {
-      png_ptr->read_data_fn = NULL;
-
-      png_warning(png_ptr,
-          "Can't set both read_data_fn and write_data_fn in the"
-          " same structure");
-   }
-}
-
-#ifdef USE_FAR_KEYWORD
-#  ifdef _MSC_VER
-void *png_far_to_near(png_structp png_ptr, png_voidp ptr, int check)
-{
-   void *near_ptr;
-   void FAR *far_ptr;
-   FP_OFF(near_ptr) = FP_OFF(ptr);
-   far_ptr = (void FAR *)near_ptr;
-
-   if (check != 0)
-      if (FP_SEG(ptr) != FP_SEG(far_ptr))
-         png_error(png_ptr, "segment lost in conversion");
-
-   return(near_ptr);
-}
-#  else
-void *png_far_to_near(png_structp png_ptr, png_voidp ptr, int check)
-{
-   void *near_ptr;
-   void FAR *far_ptr;
-   near_ptr = (void FAR *)ptr;
-   far_ptr = (void FAR *)near_ptr;
-
-   if (check != 0)
-      if (far_ptr != ptr)
-         png_error(png_ptr, "segment lost in conversion");
-
-   return(near_ptr);
-}
-#  endif
-#endif
-#endif /* PNG_WRITE_SUPPORTED */
+
+/* pngwio.c - functions for data output
+ *
+ * Last changed in libpng 1.6.15 [November 20, 2014]
+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * This file provides a location for all output.  Users who need
+ * special handling are expected to write functions that have the same
+ * arguments as these and perform similar functions, but that possibly
+ * use different output methods.  Note that you shouldn't change these
+ * functions, but rather write replacement functions and then change
+ * them at run time with png_set_write_fn(...).
+ */
+
+#include "pngpriv.h"
+
+#ifdef PNG_WRITE_SUPPORTED
+
+/* Write the data to whatever output you are using.  The default routine
+ * writes to a file pointer.  Note that this routine sometimes gets called
+ * with very small lengths, so you should implement some kind of simple
+ * buffering if you are using unbuffered writes.  This should never be asked
+ * to write more than 64K on a 16 bit machine.
+ */
+
+void /* PRIVATE */
+png_write_data(png_structrp png_ptr, png_const_bytep data, png_size_t length)
+{
+   /* NOTE: write_data_fn must not change the buffer! */
+   if (png_ptr->write_data_fn != NULL )
+      (*(png_ptr->write_data_fn))(png_ptr, png_constcast(png_bytep,data),
+         length);
+
+   else
+      png_error(png_ptr, "Call to NULL write function");
+}
+
+#ifdef PNG_STDIO_SUPPORTED
+/* This is the function that does the actual writing of data.  If you are
+ * not writing to a standard C stream, you should create a replacement
+ * write_data function and use it at run time with png_set_write_fn(), rather
+ * than changing the library.
+ */
+void PNGCBAPI
+png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+   png_size_t check;
+
+   if (png_ptr == NULL)
+      return;
+
+   check = fwrite(data, 1, length, (png_FILE_p)(png_ptr->io_ptr));
+
+   if (check != length)
+      png_error(png_ptr, "Write Error");
+}
+#endif
+
+/* This function is called to output any data pending writing (normally
+ * to disk).  After png_flush is called, there should be no data pending
+ * writing in any buffers.
+ */
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+void /* PRIVATE */
+png_flush(png_structrp png_ptr)
+{
+   if (png_ptr->output_flush_fn != NULL)
+      (*(png_ptr->output_flush_fn))(png_ptr);
+}
+
+#  ifdef PNG_STDIO_SUPPORTED
+void PNGCBAPI
+png_default_flush(png_structp png_ptr)
+{
+   png_FILE_p io_ptr;
+
+   if (png_ptr == NULL)
+      return;
+
+   io_ptr = png_voidcast(png_FILE_p, (png_ptr->io_ptr));
+   fflush(io_ptr);
+}
+#  endif
+#endif
+
+/* This function allows the application to supply new output functions for
+ * libpng if standard C streams aren't being used.
+ *
+ * This function takes as its arguments:
+ * png_ptr       - pointer to a png output data structure
+ * io_ptr        - pointer to user supplied structure containing info about
+ *                 the output functions.  May be NULL.
+ * write_data_fn - pointer to a new output function that takes as its
+ *                 arguments a pointer to a png_struct, a pointer to
+ *                 data to be written, and a 32-bit unsigned int that is
+ *                 the number of bytes to be written.  The new write
+ *                 function should call png_error(png_ptr, "Error msg")
+ *                 to exit and output any fatal error messages.  May be
+ *                 NULL, in which case libpng's default function will
+ *                 be used.
+ * flush_data_fn - pointer to a new flush function that takes as its
+ *                 arguments a pointer to a png_struct.  After a call to
+ *                 the flush function, there should be no data in any buffers
+ *                 or pending transmission.  If the output method doesn't do
+ *                 any buffering of output, a function prototype must still be
+ *                 supplied although it doesn't have to do anything.  If
+ *                 PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile
+ *                 time, output_flush_fn will be ignored, although it must be
+ *                 supplied for compatibility.  May be NULL, in which case
+ *                 libpng's default function will be used, if
+ *                 PNG_WRITE_FLUSH_SUPPORTED is defined.  This is not
+ *                 a good idea if io_ptr does not point to a standard
+ *                 *FILE structure.
+ */
+void PNGAPI
+png_set_write_fn(png_structrp png_ptr, png_voidp io_ptr,
+    png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)
+{
+   if (png_ptr == NULL)
+      return;
+
+   png_ptr->io_ptr = io_ptr;
+
+#ifdef PNG_STDIO_SUPPORTED
+   if (write_data_fn != NULL)
+      png_ptr->write_data_fn = write_data_fn;
+
+   else
+      png_ptr->write_data_fn = png_default_write_data;
+#else
+   png_ptr->write_data_fn = write_data_fn;
+#endif
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+#  ifdef PNG_STDIO_SUPPORTED
+
+   if (output_flush_fn != NULL)
+      png_ptr->output_flush_fn = output_flush_fn;
+
+   else
+      png_ptr->output_flush_fn = png_default_flush;
+
+#  else
+   png_ptr->output_flush_fn = output_flush_fn;
+#  endif
+#else
+   PNG_UNUSED(output_flush_fn)
+#endif /* WRITE_FLUSH */
+
+#ifdef PNG_READ_SUPPORTED
+   /* It is an error to read while writing a png file */
+   if (png_ptr->read_data_fn != NULL)
+   {
+      png_ptr->read_data_fn = NULL;
+
+      png_warning(png_ptr,
+          "Can't set both read_data_fn and write_data_fn in the"
+          " same structure");
+   }
+#endif
+}
+#endif /* WRITE */
diff --git a/Source/LibPNG/pngwrite.c b/Source/LibPNG/pngwrite.c
index c188439..9454887 100644
--- a/Source/LibPNG/pngwrite.c
+++ b/Source/LibPNG/pngwrite.c
@@ -1,1668 +1,2455 @@
-
-/* pngwrite.c - general routines to write a PNG file
- *
- * Last changed in libpng 1.5.11 [June 14, 2012]
- * Copyright (c) 1998-2012 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- */
-
-#include "pngpriv.h"
-
-#ifdef PNG_WRITE_SUPPORTED
-
-/* Writes all the PNG information.  This is the suggested way to use the
- * library.  If you have a new chunk to add, make a function to write it,
- * and put it in the correct location here.  If you want the chunk written
- * after the image data, put it in png_write_end().  I strongly encourage
- * you to supply a PNG_INFO_ flag, and check info_ptr->valid before writing
- * the chunk, as that will keep the code from breaking if you want to just
- * write a plain PNG file.  If you have long comments, I suggest writing
- * them in png_write_end(), and compressing them.
- */
-void PNGAPI
-png_write_info_before_PLTE(png_structp png_ptr, png_infop info_ptr)
-{
-   png_debug(1, "in png_write_info_before_PLTE");
-
-   if (png_ptr == NULL || info_ptr == NULL)
-      return;
-
-   if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE))
-   {
-   /* Write PNG signature */
-   png_write_sig(png_ptr);
-
-#ifdef PNG_MNG_FEATURES_SUPPORTED
-   if ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) && \
-       (png_ptr->mng_features_permitted))
-   {
-      png_warning(png_ptr, "MNG features are not allowed in a PNG datastream");
-      png_ptr->mng_features_permitted = 0;
-   }
-#endif
-
-   /* Write IHDR information. */
-   png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height,
-       info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type,
-       info_ptr->filter_type,
-#ifdef PNG_WRITE_INTERLACING_SUPPORTED
-       info_ptr->interlace_type);
-#else
-       0);
-#endif
-   /* The rest of these check to see if the valid field has the appropriate
-    * flag set, and if it does, writes the chunk.
-    */
-#ifdef PNG_WRITE_gAMA_SUPPORTED
-   if (info_ptr->valid & PNG_INFO_gAMA)
-      png_write_gAMA_fixed(png_ptr, info_ptr->gamma);
-#endif
-#ifdef PNG_WRITE_sRGB_SUPPORTED
-   if (info_ptr->valid & PNG_INFO_sRGB)
-      png_write_sRGB(png_ptr, (int)info_ptr->srgb_intent);
-#endif
-
-#ifdef PNG_WRITE_iCCP_SUPPORTED
-   if (info_ptr->valid & PNG_INFO_iCCP)
-      png_write_iCCP(png_ptr, info_ptr->iccp_name, PNG_COMPRESSION_TYPE_BASE,
-          (png_charp)info_ptr->iccp_profile, (int)info_ptr->iccp_proflen);
-#endif
-#ifdef PNG_WRITE_sBIT_SUPPORTED
-   if (info_ptr->valid & PNG_INFO_sBIT)
-      png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type);
-#endif
-#ifdef PNG_WRITE_cHRM_SUPPORTED
-   if (info_ptr->valid & PNG_INFO_cHRM)
-      png_write_cHRM_fixed(png_ptr,
-          info_ptr->x_white, info_ptr->y_white,
-          info_ptr->x_red, info_ptr->y_red,
-          info_ptr->x_green, info_ptr->y_green,
-          info_ptr->x_blue, info_ptr->y_blue);
-#endif
-
-#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
-   if (info_ptr->unknown_chunks_num)
-   {
-      png_unknown_chunk *up;
-
-      png_debug(5, "writing extra chunks");
-
-      for (up = info_ptr->unknown_chunks;
-           up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
-           up++)
-      {
-         int keep = png_handle_as_unknown(png_ptr, up->name);
-
-         if (keep != PNG_HANDLE_CHUNK_NEVER &&
-             up->location &&
-             !(up->location & PNG_HAVE_PLTE) &&
-             !(up->location & PNG_HAVE_IDAT) &&
-             !(up->location & PNG_AFTER_IDAT) &&
-             ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS ||
-             (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS)))
-         {
-            if (up->size == 0)
-               png_warning(png_ptr, "Writing zero-length unknown chunk");
-
-            png_write_chunk(png_ptr, up->name, up->data, up->size);
-         }
-      }
-   }
-#endif
-      png_ptr->mode |= PNG_WROTE_INFO_BEFORE_PLTE;
-   }
-}
-
-void PNGAPI
-png_write_info(png_structp png_ptr, png_infop info_ptr)
-{
-#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
-   int i;
-#endif
-
-   png_debug(1, "in png_write_info");
-
-   if (png_ptr == NULL || info_ptr == NULL)
-      return;
-
-   png_write_info_before_PLTE(png_ptr, info_ptr);
-
-   if (info_ptr->valid & PNG_INFO_PLTE)
-      png_write_PLTE(png_ptr, info_ptr->palette,
-          (png_uint_32)info_ptr->num_palette);
-
-   else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
-      png_error(png_ptr, "Valid palette required for paletted images");
-
-#ifdef PNG_WRITE_tRNS_SUPPORTED
-   if (info_ptr->valid & PNG_INFO_tRNS)
-   {
-#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
-      /* Invert the alpha channel (in tRNS) */
-      if ((png_ptr->transformations & PNG_INVERT_ALPHA) &&
-          info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
-      {
-         int j;
-         for (j = 0; j<(int)info_ptr->num_trans; j++)
-            info_ptr->trans_alpha[j] =
-               (png_byte)(255 - info_ptr->trans_alpha[j]);
-      }
-#endif
-      png_write_tRNS(png_ptr, info_ptr->trans_alpha, &(info_ptr->trans_color),
-          info_ptr->num_trans, info_ptr->color_type);
-   }
-#endif
-#ifdef PNG_WRITE_bKGD_SUPPORTED
-   if (info_ptr->valid & PNG_INFO_bKGD)
-      png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type);
-#endif
-
-#ifdef PNG_WRITE_hIST_SUPPORTED
-   if (info_ptr->valid & PNG_INFO_hIST)
-      png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette);
-#endif
-
-#ifdef PNG_WRITE_oFFs_SUPPORTED
-   if (info_ptr->valid & PNG_INFO_oFFs)
-      png_write_oFFs(png_ptr, info_ptr->x_offset, info_ptr->y_offset,
-          info_ptr->offset_unit_type);
-#endif
-
-#ifdef PNG_WRITE_pCAL_SUPPORTED
-   if (info_ptr->valid & PNG_INFO_pCAL)
-      png_write_pCAL(png_ptr, info_ptr->pcal_purpose, info_ptr->pcal_X0,
-          info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams,
-          info_ptr->pcal_units, info_ptr->pcal_params);
-#endif
-
-#ifdef PNG_WRITE_sCAL_SUPPORTED
-   if (info_ptr->valid & PNG_INFO_sCAL)
-      png_write_sCAL_s(png_ptr, (int)info_ptr->scal_unit,
-          info_ptr->scal_s_width, info_ptr->scal_s_height);
-#endif /* sCAL */
-
-#ifdef PNG_WRITE_pHYs_SUPPORTED
-   if (info_ptr->valid & PNG_INFO_pHYs)
-      png_write_pHYs(png_ptr, info_ptr->x_pixels_per_unit,
-          info_ptr->y_pixels_per_unit, info_ptr->phys_unit_type);
-#endif /* pHYs */
-
-#ifdef PNG_WRITE_tIME_SUPPORTED
-   if (info_ptr->valid & PNG_INFO_tIME)
-   {
-      png_write_tIME(png_ptr, &(info_ptr->mod_time));
-      png_ptr->mode |= PNG_WROTE_tIME;
-   }
-#endif /* tIME */
-
-#ifdef PNG_WRITE_sPLT_SUPPORTED
-   if (info_ptr->valid & PNG_INFO_sPLT)
-      for (i = 0; i < (int)info_ptr->splt_palettes_num; i++)
-         png_write_sPLT(png_ptr, info_ptr->splt_palettes + i);
-#endif /* sPLT */
-
-#ifdef PNG_WRITE_TEXT_SUPPORTED
-   /* Check to see if we need to write text chunks */
-   for (i = 0; i < info_ptr->num_text; i++)
-   {
-      png_debug2(2, "Writing header text chunk %d, type %d", i,
-          info_ptr->text[i].compression);
-      /* An internationalized chunk? */
-      if (info_ptr->text[i].compression > 0)
-      {
-#ifdef PNG_WRITE_iTXt_SUPPORTED
-         /* Write international chunk */
-         png_write_iTXt(png_ptr,
-             info_ptr->text[i].compression,
-             info_ptr->text[i].key,
-             info_ptr->text[i].lang,
-             info_ptr->text[i].lang_key,
-             info_ptr->text[i].text);
-#else
-          png_warning(png_ptr, "Unable to write international text");
-#endif
-          /* Mark this chunk as written */
-          info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
-      }
-
-      /* If we want a compressed text chunk */
-      else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_zTXt)
-      {
-#ifdef PNG_WRITE_zTXt_SUPPORTED
-         /* Write compressed chunk */
-         png_write_zTXt(png_ptr, info_ptr->text[i].key,
-             info_ptr->text[i].text, 0,
-             info_ptr->text[i].compression);
-#else
-         png_warning(png_ptr, "Unable to write compressed text");
-#endif
-         /* Mark this chunk as written */
-         info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
-      }
-
-      else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
-      {
-#ifdef PNG_WRITE_tEXt_SUPPORTED
-         /* Write uncompressed chunk */
-         png_write_tEXt(png_ptr, info_ptr->text[i].key,
-             info_ptr->text[i].text,
-             0);
-         /* Mark this chunk as written */
-         info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
-#else
-         /* Can't get here */
-         png_warning(png_ptr, "Unable to write uncompressed text");
-#endif
-      }
-   }
-#endif /* tEXt */
-
-#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
-   if (info_ptr->unknown_chunks_num)
-   {
-      png_unknown_chunk *up;
-
-      png_debug(5, "writing extra chunks");
-
-      for (up = info_ptr->unknown_chunks;
-           up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
-           up++)
-      {
-         int keep = png_handle_as_unknown(png_ptr, up->name);
-         if (keep != PNG_HANDLE_CHUNK_NEVER &&
-             up->location &&
-             (up->location & PNG_HAVE_PLTE) &&
-             !(up->location & PNG_HAVE_IDAT) &&
-             !(up->location & PNG_AFTER_IDAT) &&
-             ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS ||
-             (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS)))
-         {
-            png_write_chunk(png_ptr, up->name, up->data, up->size);
-         }
-      }
-   }
-#endif
-}
-
-/* Writes the end of the PNG file.  If you don't want to write comments or
- * time information, you can pass NULL for info.  If you already wrote these
- * in png_write_info(), do not write them again here.  If you have long
- * comments, I suggest writing them here, and compressing them.
- */
-void PNGAPI
-png_write_end(png_structp png_ptr, png_infop info_ptr)
-{
-   png_debug(1, "in png_write_end");
-
-   if (png_ptr == NULL)
-      return;
-
-   if (!(png_ptr->mode & PNG_HAVE_IDAT))
-      png_error(png_ptr, "No IDATs written into file");
-
-#ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
-   if (png_ptr->num_palette_max > png_ptr->num_palette)
-      png_benign_error(png_ptr, "Wrote palette index exceeding num_palette");
-#endif
-
-   /* See if user wants us to write information chunks */
-   if (info_ptr != NULL)
-   {
-#ifdef PNG_WRITE_TEXT_SUPPORTED
-      int i; /* local index variable */
-#endif
-#ifdef PNG_WRITE_tIME_SUPPORTED
-      /* Check to see if user has supplied a time chunk */
-      if ((info_ptr->valid & PNG_INFO_tIME) &&
-          !(png_ptr->mode & PNG_WROTE_tIME))
-         png_write_tIME(png_ptr, &(info_ptr->mod_time));
-
-#endif
-#ifdef PNG_WRITE_TEXT_SUPPORTED
-      /* Loop through comment chunks */
-      for (i = 0; i < info_ptr->num_text; i++)
-      {
-         png_debug2(2, "Writing trailer text chunk %d, type %d", i,
-            info_ptr->text[i].compression);
-         /* An internationalized chunk? */
-         if (info_ptr->text[i].compression > 0)
-         {
-#ifdef PNG_WRITE_iTXt_SUPPORTED
-            /* Write international chunk */
-            png_write_iTXt(png_ptr,
-                info_ptr->text[i].compression,
-                info_ptr->text[i].key,
-                info_ptr->text[i].lang,
-                info_ptr->text[i].lang_key,
-                info_ptr->text[i].text);
-#else
-            png_warning(png_ptr, "Unable to write international text");
-#endif
-            /* Mark this chunk as written */
-            info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
-         }
-
-         else if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt)
-         {
-#ifdef PNG_WRITE_zTXt_SUPPORTED
-            /* Write compressed chunk */
-            png_write_zTXt(png_ptr, info_ptr->text[i].key,
-                info_ptr->text[i].text, 0,
-                info_ptr->text[i].compression);
-#else
-            png_warning(png_ptr, "Unable to write compressed text");
-#endif
-            /* Mark this chunk as written */
-            info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
-         }
-
-         else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
-         {
-#ifdef PNG_WRITE_tEXt_SUPPORTED
-            /* Write uncompressed chunk */
-            png_write_tEXt(png_ptr, info_ptr->text[i].key,
-                info_ptr->text[i].text, 0);
-#else
-            png_warning(png_ptr, "Unable to write uncompressed text");
-#endif
-
-            /* Mark this chunk as written */
-            info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
-         }
-      }
-#endif
-#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
-   if (info_ptr->unknown_chunks_num)
-   {
-      png_unknown_chunk *up;
-
-      png_debug(5, "writing extra chunks");
-
-      for (up = info_ptr->unknown_chunks;
-           up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
-           up++)
-      {
-         int keep = png_handle_as_unknown(png_ptr, up->name);
-         if (keep != PNG_HANDLE_CHUNK_NEVER &&
-             up->location &&
-             (up->location & PNG_AFTER_IDAT) &&
-             ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS ||
-             (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS)))
-         {
-            png_write_chunk(png_ptr, up->name, up->data, up->size);
-         }
-      }
-   }
-#endif
-   }
-
-   png_ptr->mode |= PNG_AFTER_IDAT;
-
-   /* Write end of PNG file */
-   png_write_IEND(png_ptr);
-   /* This flush, added in libpng-1.0.8, removed from libpng-1.0.9beta03,
-    * and restored again in libpng-1.2.30, may cause some applications that
-    * do not set png_ptr->output_flush_fn to crash.  If your application
-    * experiences a problem, please try building libpng with
-    * PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED defined, and report the event to
-    * png-mng-implement at lists.sf.net .
-    */
-#ifdef PNG_WRITE_FLUSH_SUPPORTED
-#  ifdef PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED
-   png_flush(png_ptr);
-#  endif
-#endif
-}
-
-#ifdef PNG_CONVERT_tIME_SUPPORTED
-/* "tm" structure is not supported on WindowsCE */
-void PNGAPI
-png_convert_from_struct_tm(png_timep ptime, PNG_CONST struct tm FAR * ttime)
-{
-   png_debug(1, "in png_convert_from_struct_tm");
-
-   ptime->year = (png_uint_16)(1900 + ttime->tm_year);
-   ptime->month = (png_byte)(ttime->tm_mon + 1);
-   ptime->day = (png_byte)ttime->tm_mday;
-   ptime->hour = (png_byte)ttime->tm_hour;
-   ptime->minute = (png_byte)ttime->tm_min;
-   ptime->second = (png_byte)ttime->tm_sec;
-}
-
-void PNGAPI
-png_convert_from_time_t(png_timep ptime, time_t ttime)
-{
-   struct tm *tbuf;
-
-   png_debug(1, "in png_convert_from_time_t");
-
-   tbuf = gmtime(&ttime);
-   png_convert_from_struct_tm(ptime, tbuf);
-}
-#endif
-
-/* Initialize png_ptr structure, and allocate any memory needed */
-PNG_FUNCTION(png_structp,PNGAPI
-png_create_write_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
-    png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED)
-{
-#ifdef PNG_USER_MEM_SUPPORTED
-   return (png_create_write_struct_2(user_png_ver, error_ptr, error_fn,
-       warn_fn, NULL, NULL, NULL));
-}
-
-/* Alternate initialize png_ptr structure, and allocate any memory needed */
-static void png_reset_filter_heuristics(png_structp png_ptr); /* forward decl */
-
-PNG_FUNCTION(png_structp,PNGAPI
-png_create_write_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr,
-    png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
-    png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED)
-{
-#endif /* PNG_USER_MEM_SUPPORTED */
-   volatile int png_cleanup_needed = 0;
-#ifdef PNG_SETJMP_SUPPORTED
-   volatile
-#endif
-   png_structp png_ptr;
-#ifdef PNG_SETJMP_SUPPORTED
-#ifdef USE_FAR_KEYWORD
-   jmp_buf tmp_jmpbuf;
-#endif
-#endif
-
-   png_debug(1, "in png_create_write_struct");
-
-#ifdef PNG_USER_MEM_SUPPORTED
-   png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG,
-       (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr);
-#else
-   png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
-#endif /* PNG_USER_MEM_SUPPORTED */
-   if (png_ptr == NULL)
-      return (NULL);
-
-   /* Added at libpng-1.2.6 */
-#ifdef PNG_SET_USER_LIMITS_SUPPORTED
-   png_ptr->user_width_max = PNG_USER_WIDTH_MAX;
-   png_ptr->user_height_max = PNG_USER_HEIGHT_MAX;
-#endif
-
-#ifdef PNG_SETJMP_SUPPORTED
-/* Applications that neglect to set up their own setjmp() and then
- * encounter a png_error() will longjmp here.  Since the jmpbuf is
- * then meaningless we abort instead of returning.
- */
-#ifdef USE_FAR_KEYWORD
-   if (setjmp(tmp_jmpbuf))
-#else
-   if (setjmp(png_jmpbuf(png_ptr))) /* sets longjmp to match setjmp */
-#endif
-#ifdef USE_FAR_KEYWORD
-   png_memcpy(png_jmpbuf(png_ptr), tmp_jmpbuf, png_sizeof(jmp_buf));
-#endif
-      PNG_ABORT();
-#endif
-
-#ifdef PNG_USER_MEM_SUPPORTED
-   png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
-#endif /* PNG_USER_MEM_SUPPORTED */
-   png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);
-
-   if (!png_user_version_check(png_ptr, user_png_ver))
-      png_cleanup_needed = 1;
-
-   /* Initialize zbuf - compression buffer */
-   png_ptr->zbuf_size = PNG_ZBUF_SIZE;
-
-   if (!png_cleanup_needed)
-   {
-      png_ptr->zbuf = (png_bytep)png_malloc_warn(png_ptr,
-          png_ptr->zbuf_size);
-      if (png_ptr->zbuf == NULL)
-         png_cleanup_needed = 1;
-   }
-
-   if (png_cleanup_needed)
-   {
-       /* Clean up PNG structure and deallocate any memory. */
-       png_free(png_ptr, png_ptr->zbuf);
-       png_ptr->zbuf = NULL;
-#ifdef PNG_USER_MEM_SUPPORTED
-       png_destroy_struct_2((png_voidp)png_ptr,
-           (png_free_ptr)free_fn, (png_voidp)mem_ptr);
-#else
-       png_destroy_struct((png_voidp)png_ptr);
-#endif
-       return (NULL);
-   }
-
-   png_set_write_fn(png_ptr, NULL, NULL, NULL);
-
-#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
-   png_reset_filter_heuristics(png_ptr);
-#endif
-
-   return (png_ptr);
-}
-
-
-/* Write a few rows of image data.  If the image is interlaced,
- * either you will have to write the 7 sub images, or, if you
- * have called png_set_interlace_handling(), you will have to
- * "write" the image seven times.
- */
-void PNGAPI
-png_write_rows(png_structp png_ptr, png_bytepp row,
-    png_uint_32 num_rows)
-{
-   png_uint_32 i; /* row counter */
-   png_bytepp rp; /* row pointer */
-
-   png_debug(1, "in png_write_rows");
-
-   if (png_ptr == NULL)
-      return;
-
-   /* Loop through the rows */
-   for (i = 0, rp = row; i < num_rows; i++, rp++)
-   {
-      png_write_row(png_ptr, *rp);
-   }
-}
-
-/* Write the image.  You only need to call this function once, even
- * if you are writing an interlaced image.
- */
-void PNGAPI
-png_write_image(png_structp png_ptr, png_bytepp image)
-{
-   png_uint_32 i; /* row index */
-   int pass, num_pass; /* pass variables */
-   png_bytepp rp; /* points to current row */
-
-   if (png_ptr == NULL)
-      return;
-
-   png_debug(1, "in png_write_image");
-
-#ifdef PNG_WRITE_INTERLACING_SUPPORTED
-   /* Initialize interlace handling.  If image is not interlaced,
-    * this will set pass to 1
-    */
-   num_pass = png_set_interlace_handling(png_ptr);
-#else
-   num_pass = 1;
-#endif
-   /* Loop through passes */
-   for (pass = 0; pass < num_pass; pass++)
-   {
-      /* Loop through image */
-      for (i = 0, rp = image; i < png_ptr->height; i++, rp++)
-      {
-         png_write_row(png_ptr, *rp);
-      }
-   }
-}
-
-/* Called by user to write a row of image data */
-void PNGAPI
-png_write_row(png_structp png_ptr, png_const_bytep row)
-{
-   /* 1.5.6: moved from png_struct to be a local structure: */
-   png_row_info row_info;
-
-   if (png_ptr == NULL)
-      return;
-
-   png_debug2(1, "in png_write_row (row %u, pass %d)",
-      png_ptr->row_number, png_ptr->pass);
-
-   /* Initialize transformations and other stuff if first time */
-   if (png_ptr->row_number == 0 && png_ptr->pass == 0)
-   {
-      /* Make sure we wrote the header info */
-      if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE))
-         png_error(png_ptr,
-             "png_write_info was never called before png_write_row");
-
-      /* Check for transforms that have been set but were defined out */
-#if !defined(PNG_WRITE_INVERT_SUPPORTED) && defined(PNG_READ_INVERT_SUPPORTED)
-      if (png_ptr->transformations & PNG_INVERT_MONO)
-         png_warning(png_ptr, "PNG_WRITE_INVERT_SUPPORTED is not defined");
-#endif
-
-#if !defined(PNG_WRITE_FILLER_SUPPORTED) && defined(PNG_READ_FILLER_SUPPORTED)
-      if (png_ptr->transformations & PNG_FILLER)
-         png_warning(png_ptr, "PNG_WRITE_FILLER_SUPPORTED is not defined");
-#endif
-#if !defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \
-    defined(PNG_READ_PACKSWAP_SUPPORTED)
-      if (png_ptr->transformations & PNG_PACKSWAP)
-         png_warning(png_ptr,
-             "PNG_WRITE_PACKSWAP_SUPPORTED is not defined");
-#endif
-
-#if !defined(PNG_WRITE_PACK_SUPPORTED) && defined(PNG_READ_PACK_SUPPORTED)
-      if (png_ptr->transformations & PNG_PACK)
-         png_warning(png_ptr, "PNG_WRITE_PACK_SUPPORTED is not defined");
-#endif
-
-#if !defined(PNG_WRITE_SHIFT_SUPPORTED) && defined(PNG_READ_SHIFT_SUPPORTED)
-      if (png_ptr->transformations & PNG_SHIFT)
-         png_warning(png_ptr, "PNG_WRITE_SHIFT_SUPPORTED is not defined");
-#endif
-
-#if !defined(PNG_WRITE_BGR_SUPPORTED) && defined(PNG_READ_BGR_SUPPORTED)
-      if (png_ptr->transformations & PNG_BGR)
-         png_warning(png_ptr, "PNG_WRITE_BGR_SUPPORTED is not defined");
-#endif
-
-#if !defined(PNG_WRITE_SWAP_SUPPORTED) && defined(PNG_READ_SWAP_SUPPORTED)
-      if (png_ptr->transformations & PNG_SWAP_BYTES)
-         png_warning(png_ptr, "PNG_WRITE_SWAP_SUPPORTED is not defined");
-#endif
-
-      png_write_start_row(png_ptr);
-   }
-
-#ifdef PNG_WRITE_INTERLACING_SUPPORTED
-   /* If interlaced and not interested in row, return */
-   if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
-   {
-      switch (png_ptr->pass)
-      {
-         case 0:
-            if (png_ptr->row_number & 0x07)
-            {
-               png_write_finish_row(png_ptr);
-               return;
-            }
-            break;
-
-         case 1:
-            if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
-            {
-               png_write_finish_row(png_ptr);
-               return;
-            }
-            break;
-
-         case 2:
-            if ((png_ptr->row_number & 0x07) != 4)
-            {
-               png_write_finish_row(png_ptr);
-               return;
-            }
-            break;
-
-         case 3:
-            if ((png_ptr->row_number & 0x03) || png_ptr->width < 3)
-            {
-               png_write_finish_row(png_ptr);
-               return;
-            }
-            break;
-
-         case 4:
-            if ((png_ptr->row_number & 0x03) != 2)
-            {
-               png_write_finish_row(png_ptr);
-               return;
-            }
-            break;
-
-         case 5:
-            if ((png_ptr->row_number & 0x01) || png_ptr->width < 2)
-            {
-               png_write_finish_row(png_ptr);
-               return;
-            }
-            break;
-
-         case 6:
-            if (!(png_ptr->row_number & 0x01))
-            {
-               png_write_finish_row(png_ptr);
-               return;
-            }
-            break;
-
-         default: /* error: ignore it */
-            break;
-      }
-   }
-#endif
-
-   /* Set up row info for transformations */
-   row_info.color_type = png_ptr->color_type;
-   row_info.width = png_ptr->usr_width;
-   row_info.channels = png_ptr->usr_channels;
-   row_info.bit_depth = png_ptr->usr_bit_depth;
-   row_info.pixel_depth = (png_byte)(row_info.bit_depth * row_info.channels);
-   row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width);
-
-   png_debug1(3, "row_info->color_type = %d", row_info.color_type);
-   png_debug1(3, "row_info->width = %u", row_info.width);
-   png_debug1(3, "row_info->channels = %d", row_info.channels);
-   png_debug1(3, "row_info->bit_depth = %d", row_info.bit_depth);
-   png_debug1(3, "row_info->pixel_depth = %d", row_info.pixel_depth);
-   png_debug1(3, "row_info->rowbytes = %lu", (unsigned long)row_info.rowbytes);
-
-   /* Copy user's row into buffer, leaving room for filter byte. */
-   png_memcpy(png_ptr->row_buf + 1, row, row_info.rowbytes);
-
-#ifdef PNG_WRITE_INTERLACING_SUPPORTED
-   /* Handle interlacing */
-   if (png_ptr->interlaced && png_ptr->pass < 6 &&
-       (png_ptr->transformations & PNG_INTERLACE))
-   {
-      png_do_write_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass);
-      /* This should always get caught above, but still ... */
-      if (!(row_info.width))
-      {
-         png_write_finish_row(png_ptr);
-         return;
-      }
-   }
-#endif
-
-#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
-   /* Handle other transformations */
-   if (png_ptr->transformations)
-      png_do_write_transformations(png_ptr, &row_info);
-#endif
-
-   /* At this point the row_info pixel depth must match the 'transformed' depth,
-    * which is also the output depth.
-    */
-   if (row_info.pixel_depth != png_ptr->pixel_depth ||
-      row_info.pixel_depth != png_ptr->transformed_pixel_depth)
-      png_error(png_ptr, "internal write transform logic error");
-
-#ifdef PNG_MNG_FEATURES_SUPPORTED
-   /* Write filter_method 64 (intrapixel differencing) only if
-    * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
-    * 2. Libpng did not write a PNG signature (this filter_method is only
-    *    used in PNG datastreams that are embedded in MNG datastreams) and
-    * 3. The application called png_permit_mng_features with a mask that
-    *    included PNG_FLAG_MNG_FILTER_64 and
-    * 4. The filter_method is 64 and
-    * 5. The color_type is RGB or RGBA
-    */
-   if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
-       (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
-   {
-      /* Intrapixel differencing */
-      png_do_write_intrapixel(&row_info, png_ptr->row_buf + 1);
-   }
-#endif
-
-/* Added at libpng-1.5.10 */
-#ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
-   /* Check for out-of-range palette index */
-   if (row_info.color_type == PNG_COLOR_TYPE_PALETTE &&
-       png_ptr->num_palette_max >= 0)
-      png_do_check_palette_indexes(png_ptr, &row_info);
-#endif
-
-   /* Find a filter if necessary, filter the row and write it out. */
-   png_write_find_filter(png_ptr, &row_info);
-
-   if (png_ptr->write_row_fn != NULL)
-      (*(png_ptr->write_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
-}
-
-#ifdef PNG_WRITE_FLUSH_SUPPORTED
-/* Set the automatic flush interval or 0 to turn flushing off */
-void PNGAPI
-png_set_flush(png_structp png_ptr, int nrows)
-{
-   png_debug(1, "in png_set_flush");
-
-   if (png_ptr == NULL)
-      return;
-
-   png_ptr->flush_dist = (nrows < 0 ? 0 : nrows);
-}
-
-/* Flush the current output buffers now */
-void PNGAPI
-png_write_flush(png_structp png_ptr)
-{
-   int wrote_IDAT;
-
-   png_debug(1, "in png_write_flush");
-
-   if (png_ptr == NULL)
-      return;
-
-   /* We have already written out all of the data */
-   if (png_ptr->row_number >= png_ptr->num_rows)
-      return;
-
-   do
-   {
-      int ret;
-
-      /* Compress the data */
-      ret = deflate(&png_ptr->zstream, Z_SYNC_FLUSH);
-      wrote_IDAT = 0;
-
-      /* Check for compression errors */
-      if (ret != Z_OK)
-      {
-         if (png_ptr->zstream.msg != NULL)
-            png_error(png_ptr, png_ptr->zstream.msg);
-
-         else
-            png_error(png_ptr, "zlib error");
-      }
-
-      if (!(png_ptr->zstream.avail_out))
-      {
-         /* Write the IDAT and reset the zlib output buffer */
-         png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
-         wrote_IDAT = 1;
-      }
-   } while (wrote_IDAT == 1);
-
-   /* If there is any data left to be output, write it into a new IDAT */
-   if (png_ptr->zbuf_size != png_ptr->zstream.avail_out)
-   {
-      /* Write the IDAT and reset the zlib output buffer */
-      png_write_IDAT(png_ptr, png_ptr->zbuf,
-          png_ptr->zbuf_size - png_ptr->zstream.avail_out);
-   }
-   png_ptr->flush_rows = 0;
-   png_flush(png_ptr);
-}
-#endif /* PNG_WRITE_FLUSH_SUPPORTED */
-
-/* Free all memory used by the write */
-void PNGAPI
-png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr)
-{
-   png_structp png_ptr = NULL;
-   png_infop info_ptr = NULL;
-#ifdef PNG_USER_MEM_SUPPORTED
-   png_free_ptr free_fn = NULL;
-   png_voidp mem_ptr = NULL;
-#endif
-
-   png_debug(1, "in png_destroy_write_struct");
-
-   if (png_ptr_ptr != NULL)
-      png_ptr = *png_ptr_ptr;
-
-#ifdef PNG_USER_MEM_SUPPORTED
-   if (png_ptr != NULL)
-   {
-      free_fn = png_ptr->free_fn;
-      mem_ptr = png_ptr->mem_ptr;
-   }
-#endif
-
-   if (info_ptr_ptr != NULL)
-      info_ptr = *info_ptr_ptr;
-
-   if (info_ptr != NULL)
-   {
-      if (png_ptr != NULL)
-      {
-         png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
-
-#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
-         if (png_ptr->num_chunk_list)
-         {
-            png_free(png_ptr, png_ptr->chunk_list);
-            png_ptr->num_chunk_list = 0;
-         }
-#endif
-      }
-
-#ifdef PNG_USER_MEM_SUPPORTED
-      png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn,
-          (png_voidp)mem_ptr);
-#else
-      png_destroy_struct((png_voidp)info_ptr);
-#endif
-      *info_ptr_ptr = NULL;
-   }
-
-   if (png_ptr != NULL)
-   {
-      png_write_destroy(png_ptr);
-#ifdef PNG_USER_MEM_SUPPORTED
-      png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn,
-          (png_voidp)mem_ptr);
-#else
-      png_destroy_struct((png_voidp)png_ptr);
-#endif
-      *png_ptr_ptr = NULL;
-   }
-}
-
-
-/* Free any memory used in png_ptr struct (old method) */
-void /* PRIVATE */
-png_write_destroy(png_structp png_ptr)
-{
-#ifdef PNG_SETJMP_SUPPORTED
-   jmp_buf tmp_jmp; /* Save jump buffer */
-#endif
-   png_error_ptr error_fn;
-#ifdef PNG_WARNINGS_SUPPORTED
-   png_error_ptr warning_fn;
-#endif
-   png_voidp error_ptr;
-#ifdef PNG_USER_MEM_SUPPORTED
-   png_free_ptr free_fn;
-#endif
-
-   png_debug(1, "in png_write_destroy");
-
-   /* Free any memory zlib uses */
-   if (png_ptr->zlib_state != PNG_ZLIB_UNINITIALIZED)
-      deflateEnd(&png_ptr->zstream);
-
-   /* Free our memory.  png_free checks NULL for us. */
-   png_free(png_ptr, png_ptr->zbuf);
-   png_free(png_ptr, png_ptr->row_buf);
-#ifdef PNG_WRITE_FILTER_SUPPORTED
-   png_free(png_ptr, png_ptr->prev_row);
-   png_free(png_ptr, png_ptr->sub_row);
-   png_free(png_ptr, png_ptr->up_row);
-   png_free(png_ptr, png_ptr->avg_row);
-   png_free(png_ptr, png_ptr->paeth_row);
-#endif
-
-#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
-   /* Use this to save a little code space, it doesn't free the filter_costs */
-   png_reset_filter_heuristics(png_ptr);
-   png_free(png_ptr, png_ptr->filter_costs);
-   png_free(png_ptr, png_ptr->inv_filter_costs);
-#endif
-
-#ifdef PNG_SETJMP_SUPPORTED
-   /* Reset structure */
-   png_memcpy(tmp_jmp, png_ptr->longjmp_buffer, png_sizeof(jmp_buf));
-#endif
-
-   error_fn = png_ptr->error_fn;
-#ifdef PNG_WARNINGS_SUPPORTED
-   warning_fn = png_ptr->warning_fn;
-#endif
-   error_ptr = png_ptr->error_ptr;
-#ifdef PNG_USER_MEM_SUPPORTED
-   free_fn = png_ptr->free_fn;
-#endif
-
-   png_memset(png_ptr, 0, png_sizeof(png_struct));
-
-   png_ptr->error_fn = error_fn;
-#ifdef PNG_WARNINGS_SUPPORTED
-   png_ptr->warning_fn = warning_fn;
-#endif
-   png_ptr->error_ptr = error_ptr;
-#ifdef PNG_USER_MEM_SUPPORTED
-   png_ptr->free_fn = free_fn;
-#endif
-
-#ifdef PNG_SETJMP_SUPPORTED
-   png_memcpy(png_ptr->longjmp_buffer, tmp_jmp, png_sizeof(jmp_buf));
-#endif
-}
-
-/* Allow the application to select one or more row filters to use. */
-void PNGAPI
-png_set_filter(png_structp png_ptr, int method, int filters)
-{
-   png_debug(1, "in png_set_filter");
-
-   if (png_ptr == NULL)
-      return;
-
-#ifdef PNG_MNG_FEATURES_SUPPORTED
-   if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
-       (method == PNG_INTRAPIXEL_DIFFERENCING))
-      method = PNG_FILTER_TYPE_BASE;
-
-#endif
-   if (method == PNG_FILTER_TYPE_BASE)
-   {
-      switch (filters & (PNG_ALL_FILTERS | 0x07))
-      {
-#ifdef PNG_WRITE_FILTER_SUPPORTED
-         case 5:
-         case 6:
-         case 7: png_warning(png_ptr, "Unknown row filter for method 0");
-#endif /* PNG_WRITE_FILTER_SUPPORTED */
-         case PNG_FILTER_VALUE_NONE:
-            png_ptr->do_filter = PNG_FILTER_NONE; break;
-
-#ifdef PNG_WRITE_FILTER_SUPPORTED
-         case PNG_FILTER_VALUE_SUB:
-            png_ptr->do_filter = PNG_FILTER_SUB; break;
-
-         case PNG_FILTER_VALUE_UP:
-            png_ptr->do_filter = PNG_FILTER_UP; break;
-
-         case PNG_FILTER_VALUE_AVG:
-            png_ptr->do_filter = PNG_FILTER_AVG; break;
-
-         case PNG_FILTER_VALUE_PAETH:
-            png_ptr->do_filter = PNG_FILTER_PAETH; break;
-
-         default:
-            png_ptr->do_filter = (png_byte)filters; break;
-#else
-         default:
-            png_warning(png_ptr, "Unknown row filter for method 0");
-#endif /* PNG_WRITE_FILTER_SUPPORTED */
-      }
-
-      /* If we have allocated the row_buf, this means we have already started
-       * with the image and we should have allocated all of the filter buffers
-       * that have been selected.  If prev_row isn't already allocated, then
-       * it is too late to start using the filters that need it, since we
-       * will be missing the data in the previous row.  If an application
-       * wants to start and stop using particular filters during compression,
-       * it should start out with all of the filters, and then add and
-       * remove them after the start of compression.
-       */
-      if (png_ptr->row_buf != NULL)
-      {
-#ifdef PNG_WRITE_FILTER_SUPPORTED
-         if ((png_ptr->do_filter & PNG_FILTER_SUB) && png_ptr->sub_row == NULL)
-         {
-            png_ptr->sub_row = (png_bytep)png_malloc(png_ptr,
-                (png_ptr->rowbytes + 1));
-            png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
-         }
-
-         if ((png_ptr->do_filter & PNG_FILTER_UP) && png_ptr->up_row == NULL)
-         {
-            if (png_ptr->prev_row == NULL)
-            {
-               png_warning(png_ptr, "Can't add Up filter after starting");
-               png_ptr->do_filter = (png_byte)(png_ptr->do_filter &
-                   ~PNG_FILTER_UP);
-            }
-
-            else
-            {
-               png_ptr->up_row = (png_bytep)png_malloc(png_ptr,
-                   (png_ptr->rowbytes + 1));
-               png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
-            }
-         }
-
-         if ((png_ptr->do_filter & PNG_FILTER_AVG) && png_ptr->avg_row == NULL)
-         {
-            if (png_ptr->prev_row == NULL)
-            {
-               png_warning(png_ptr, "Can't add Average filter after starting");
-               png_ptr->do_filter = (png_byte)(png_ptr->do_filter &
-                   ~PNG_FILTER_AVG);
-            }
-
-            else
-            {
-               png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
-                   (png_ptr->rowbytes + 1));
-               png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
-            }
-         }
-
-         if ((png_ptr->do_filter & PNG_FILTER_PAETH) &&
-             png_ptr->paeth_row == NULL)
-         {
-            if (png_ptr->prev_row == NULL)
-            {
-               png_warning(png_ptr, "Can't add Paeth filter after starting");
-               png_ptr->do_filter &= (png_byte)(~PNG_FILTER_PAETH);
-            }
-
-            else
-            {
-               png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr,
-                   (png_ptr->rowbytes + 1));
-               png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
-            }
-         }
-
-         if (png_ptr->do_filter == PNG_NO_FILTERS)
-#endif /* PNG_WRITE_FILTER_SUPPORTED */
-            png_ptr->do_filter = PNG_FILTER_NONE;
-      }
-   }
-   else
-      png_error(png_ptr, "Unknown custom filter method");
-}
-
-/* This allows us to influence the way in which libpng chooses the "best"
- * filter for the current scanline.  While the "minimum-sum-of-absolute-
- * differences metric is relatively fast and effective, there is some
- * question as to whether it can be improved upon by trying to keep the
- * filtered data going to zlib more consistent, hopefully resulting in
- * better compression.
- */
-#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED      /* GRR 970116 */
-/* Convenience reset API. */
-static void
-png_reset_filter_heuristics(png_structp png_ptr)
-{
-   /* Clear out any old values in the 'weights' - this must be done because if
-    * the app calls set_filter_heuristics multiple times with different
-    * 'num_weights' values we would otherwise potentially have wrong sized
-    * arrays.
-    */
-   png_ptr->num_prev_filters = 0;
-   png_ptr->heuristic_method = PNG_FILTER_HEURISTIC_UNWEIGHTED;
-   if (png_ptr->prev_filters != NULL)
-   {
-      png_bytep old = png_ptr->prev_filters;
-      png_ptr->prev_filters = NULL;
-      png_free(png_ptr, old);
-   }
-   if (png_ptr->filter_weights != NULL)
-   {
-      png_uint_16p old = png_ptr->filter_weights;
-      png_ptr->filter_weights = NULL;
-      png_free(png_ptr, old);
-   }
-
-   if (png_ptr->inv_filter_weights != NULL)
-   {
-      png_uint_16p old = png_ptr->inv_filter_weights;
-      png_ptr->inv_filter_weights = NULL;
-      png_free(png_ptr, old);
-   }
-
-   /* Leave the filter_costs - this array is fixed size. */
-}
-
-static int
-png_init_filter_heuristics(png_structp png_ptr, int heuristic_method,
-   int num_weights)
-{
-   if (png_ptr == NULL)
-      return 0;
-
-   /* Clear out the arrays */
-   png_reset_filter_heuristics(png_ptr);
-
-   /* Check arguments; the 'reset' function makes the correct settings for the
-    * unweighted case, but we must handle the weight case by initializing the
-    * arrays for the caller.
-    */
-   if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
-   {
-      int i;
-
-      if (num_weights > 0)
-      {
-         png_ptr->prev_filters = (png_bytep)png_malloc(png_ptr,
-             (png_uint_32)(png_sizeof(png_byte) * num_weights));
-
-         /* To make sure that the weighting starts out fairly */
-         for (i = 0; i < num_weights; i++)
-         {
-            png_ptr->prev_filters[i] = 255;
-         }
-
-         png_ptr->filter_weights = (png_uint_16p)png_malloc(png_ptr,
-             (png_uint_32)(png_sizeof(png_uint_16) * num_weights));
-
-         png_ptr->inv_filter_weights = (png_uint_16p)png_malloc(png_ptr,
-             (png_uint_32)(png_sizeof(png_uint_16) * num_weights));
-
-         for (i = 0; i < num_weights; i++)
-         {
-            png_ptr->inv_filter_weights[i] =
-            png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
-         }
-
-         /* Safe to set this now */
-         png_ptr->num_prev_filters = (png_byte)num_weights;
-      }
-
-      /* If, in the future, there are other filter methods, this would
-       * need to be based on png_ptr->filter.
-       */
-      if (png_ptr->filter_costs == NULL)
-      {
-         png_ptr->filter_costs = (png_uint_16p)png_malloc(png_ptr,
-             (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST));
-
-         png_ptr->inv_filter_costs = (png_uint_16p)png_malloc(png_ptr,
-             (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST));
-      }
-
-      for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
-      {
-         png_ptr->inv_filter_costs[i] =
-         png_ptr->filter_costs[i] = PNG_COST_FACTOR;
-      }
-
-      /* All the arrays are inited, safe to set this: */
-      png_ptr->heuristic_method = PNG_FILTER_HEURISTIC_WEIGHTED;
-
-      /* Return the 'ok' code. */
-      return 1;
-   }
-   else if (heuristic_method == PNG_FILTER_HEURISTIC_DEFAULT ||
-      heuristic_method == PNG_FILTER_HEURISTIC_UNWEIGHTED)
-   {
-      return 1;
-   }
-   else
-   {
-      png_warning(png_ptr, "Unknown filter heuristic method");
-      return 0;
-   }
-}
-
-/* Provide floating and fixed point APIs */
-#ifdef PNG_FLOATING_POINT_SUPPORTED
-void PNGAPI
-png_set_filter_heuristics(png_structp png_ptr, int heuristic_method,
-    int num_weights, png_const_doublep filter_weights,
-    png_const_doublep filter_costs)
-{
-   png_debug(1, "in png_set_filter_heuristics");
-
-   /* The internal API allocates all the arrays and ensures that the elements of
-    * those arrays are set to the default value.
-    */
-   if (!png_init_filter_heuristics(png_ptr, heuristic_method, num_weights))
-      return;
-
-   /* If using the weighted method copy in the weights. */
-   if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
-   {
-      int i;
-      for (i = 0; i < num_weights; i++)
-      {
-         if (filter_weights[i] <= 0.0)
-         {
-            png_ptr->inv_filter_weights[i] =
-            png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
-         }
-
-         else
-         {
-            png_ptr->inv_filter_weights[i] =
-                (png_uint_16)(PNG_WEIGHT_FACTOR*filter_weights[i]+.5);
-
-            png_ptr->filter_weights[i] =
-                (png_uint_16)(PNG_WEIGHT_FACTOR/filter_weights[i]+.5);
-         }
-      }
-
-      /* Here is where we set the relative costs of the different filters.  We
-       * should take the desired compression level into account when setting
-       * the costs, so that Paeth, for instance, has a high relative cost at low
-       * compression levels, while it has a lower relative cost at higher
-       * compression settings.  The filter types are in order of increasing
-       * relative cost, so it would be possible to do this with an algorithm.
-       */
-      for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) if (filter_costs[i] >= 1.0)
-      {
-         png_ptr->inv_filter_costs[i] =
-             (png_uint_16)(PNG_COST_FACTOR / filter_costs[i] + .5);
-
-         png_ptr->filter_costs[i] =
-             (png_uint_16)(PNG_COST_FACTOR * filter_costs[i] + .5);
-      }
-   }
-}
-#endif /* FLOATING_POINT */
-
-#ifdef PNG_FIXED_POINT_SUPPORTED
-void PNGAPI
-png_set_filter_heuristics_fixed(png_structp png_ptr, int heuristic_method,
-    int num_weights, png_const_fixed_point_p filter_weights,
-    png_const_fixed_point_p filter_costs)
-{
-   png_debug(1, "in png_set_filter_heuristics_fixed");
-
-   /* The internal API allocates all the arrays and ensures that the elements of
-    * those arrays are set to the default value.
-    */
-   if (!png_init_filter_heuristics(png_ptr, heuristic_method, num_weights))
-      return;
-
-   /* If using the weighted method copy in the weights. */
-   if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
-   {
-      int i;
-      for (i = 0; i < num_weights; i++)
-      {
-         if (filter_weights[i] <= 0)
-         {
-            png_ptr->inv_filter_weights[i] =
-            png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
-         }
-
-         else
-         {
-            png_ptr->inv_filter_weights[i] = (png_uint_16)
-               ((PNG_WEIGHT_FACTOR*filter_weights[i]+PNG_FP_HALF)/PNG_FP_1);
-
-            png_ptr->filter_weights[i] = (png_uint_16)((PNG_WEIGHT_FACTOR*
-               PNG_FP_1+(filter_weights[i]/2))/filter_weights[i]);
-         }
-      }
-
-      /* Here is where we set the relative costs of the different filters.  We
-       * should take the desired compression level into account when setting
-       * the costs, so that Paeth, for instance, has a high relative cost at low
-       * compression levels, while it has a lower relative cost at higher
-       * compression settings.  The filter types are in order of increasing
-       * relative cost, so it would be possible to do this with an algorithm.
-       */
-      for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
-         if (filter_costs[i] >= PNG_FP_1)
-      {
-         png_uint_32 tmp;
-
-         /* Use a 32 bit unsigned temporary here because otherwise the
-          * intermediate value will be a 32 bit *signed* integer (ANSI rules)
-          * and this will get the wrong answer on division.
-          */
-         tmp = PNG_COST_FACTOR*PNG_FP_1 + (filter_costs[i]/2);
-         tmp /= filter_costs[i];
-
-         png_ptr->inv_filter_costs[i] = (png_uint_16)tmp;
-
-         tmp = PNG_COST_FACTOR * filter_costs[i] + PNG_FP_HALF;
-         tmp /= PNG_FP_1;
-
-         png_ptr->filter_costs[i] = (png_uint_16)tmp;
-      }
-   }
-}
-#endif /* FIXED_POINT */
-#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */
-
-void PNGAPI
-png_set_compression_level(png_structp png_ptr, int level)
-{
-   png_debug(1, "in png_set_compression_level");
-
-   if (png_ptr == NULL)
-      return;
-
-   png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_LEVEL;
-   png_ptr->zlib_level = level;
-}
-
-void PNGAPI
-png_set_compression_mem_level(png_structp png_ptr, int mem_level)
-{
-   png_debug(1, "in png_set_compression_mem_level");
-
-   if (png_ptr == NULL)
-      return;
-
-   png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL;
-   png_ptr->zlib_mem_level = mem_level;
-}
-
-void PNGAPI
-png_set_compression_strategy(png_structp png_ptr, int strategy)
-{
-   png_debug(1, "in png_set_compression_strategy");
-
-   if (png_ptr == NULL)
-      return;
-
-   png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_STRATEGY;
-   png_ptr->zlib_strategy = strategy;
-}
-
-/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a
- * smaller value of window_bits if it can do so safely.
- */
-void PNGAPI
-png_set_compression_window_bits(png_structp png_ptr, int window_bits)
-{
-   if (png_ptr == NULL)
-      return;
-
-   if (window_bits > 15)
-      png_warning(png_ptr, "Only compression windows <= 32k supported by PNG");
-
-   else if (window_bits < 8)
-      png_warning(png_ptr, "Only compression windows >= 256 supported by PNG");
-
-#ifndef WBITS_8_OK
-   /* Avoid libpng bug with 256-byte windows */
-   if (window_bits == 8)
-      {
-        png_warning(png_ptr, "Compression window is being reset to 512");
-        window_bits = 9;
-      }
-
-#endif
-   png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS;
-   png_ptr->zlib_window_bits = window_bits;
-}
-
-void PNGAPI
-png_set_compression_method(png_structp png_ptr, int method)
-{
-   png_debug(1, "in png_set_compression_method");
-
-   if (png_ptr == NULL)
-      return;
-
-   if (method != 8)
-      png_warning(png_ptr, "Only compression method 8 is supported by PNG");
-
-   png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_METHOD;
-   png_ptr->zlib_method = method;
-}
-
-/* The following were added to libpng-1.5.4 */
-#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
-void PNGAPI
-png_set_text_compression_level(png_structp png_ptr, int level)
-{
-   png_debug(1, "in png_set_text_compression_level");
-
-   if (png_ptr == NULL)
-      return;
-
-   png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_LEVEL;
-   png_ptr->zlib_text_level = level;
-}
-
-void PNGAPI
-png_set_text_compression_mem_level(png_structp png_ptr, int mem_level)
-{
-   png_debug(1, "in png_set_text_compression_mem_level");
-
-   if (png_ptr == NULL)
-      return;
-
-   png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_MEM_LEVEL;
-   png_ptr->zlib_text_mem_level = mem_level;
-}
-
-void PNGAPI
-png_set_text_compression_strategy(png_structp png_ptr, int strategy)
-{
-   png_debug(1, "in png_set_text_compression_strategy");
-
-   if (png_ptr == NULL)
-      return;
-
-   png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_STRATEGY;
-   png_ptr->zlib_text_strategy = strategy;
-}
-
-/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a
- * smaller value of window_bits if it can do so safely.
- */
-void PNGAPI
-png_set_text_compression_window_bits(png_structp png_ptr, int window_bits)
-{
-   if (png_ptr == NULL)
-      return;
-
-   if (window_bits > 15)
-      png_warning(png_ptr, "Only compression windows <= 32k supported by PNG");
-
-   else if (window_bits < 8)
-      png_warning(png_ptr, "Only compression windows >= 256 supported by PNG");
-
-#ifndef WBITS_8_OK
-   /* Avoid libpng bug with 256-byte windows */
-   if (window_bits == 8)
-      {
-        png_warning(png_ptr, "Text compression window is being reset to 512");
-        window_bits = 9;
-      }
-
-#endif
-   png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_WINDOW_BITS;
-   png_ptr->zlib_text_window_bits = window_bits;
-}
-
-void PNGAPI
-png_set_text_compression_method(png_structp png_ptr, int method)
-{
-   png_debug(1, "in png_set_text_compression_method");
-
-   if (png_ptr == NULL)
-      return;
-
-   if (method != 8)
-      png_warning(png_ptr, "Only compression method 8 is supported by PNG");
-
-   png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_METHOD;
-   png_ptr->zlib_text_method = method;
-}
-#endif /* PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED */
-/* end of API added to libpng-1.5.4 */
-
-void PNGAPI
-png_set_write_status_fn(png_structp png_ptr, png_write_status_ptr write_row_fn)
-{
-   if (png_ptr == NULL)
-      return;
-
-   png_ptr->write_row_fn = write_row_fn;
-}
-
-#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
-void PNGAPI
-png_set_write_user_transform_fn(png_structp png_ptr, png_user_transform_ptr
-    write_user_transform_fn)
-{
-   png_debug(1, "in png_set_write_user_transform_fn");
-
-   if (png_ptr == NULL)
-      return;
-
-   png_ptr->transformations |= PNG_USER_TRANSFORM;
-   png_ptr->write_user_transform_fn = write_user_transform_fn;
-}
-#endif
-
-
-#ifdef PNG_INFO_IMAGE_SUPPORTED
-void PNGAPI
-png_write_png(png_structp png_ptr, png_infop info_ptr,
-    int transforms, voidp params)
-{
-   if (png_ptr == NULL || info_ptr == NULL)
-      return;
-
-   /* Write the file header information. */
-   png_write_info(png_ptr, info_ptr);
-
-   /* ------ these transformations don't touch the info structure ------- */
-
-#ifdef PNG_WRITE_INVERT_SUPPORTED
-   /* Invert monochrome pixels */
-   if (transforms & PNG_TRANSFORM_INVERT_MONO)
-      png_set_invert_mono(png_ptr);
-#endif
-
-#ifdef PNG_WRITE_SHIFT_SUPPORTED
-   /* Shift the pixels up to a legal bit depth and fill in
-    * as appropriate to correctly scale the image.
-    */
-   if ((transforms & PNG_TRANSFORM_SHIFT)
-       && (info_ptr->valid & PNG_INFO_sBIT))
-      png_set_shift(png_ptr, &info_ptr->sig_bit);
-#endif
-
-#ifdef PNG_WRITE_PACK_SUPPORTED
-   /* Pack pixels into bytes */
-   if (transforms & PNG_TRANSFORM_PACKING)
-       png_set_packing(png_ptr);
-#endif
-
-#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
-   /* Swap location of alpha bytes from ARGB to RGBA */
-   if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
-      png_set_swap_alpha(png_ptr);
-#endif
-
-#ifdef PNG_WRITE_FILLER_SUPPORTED
-   /* Pack XRGB/RGBX/ARGB/RGBA into RGB (4 channels -> 3 channels) */
-   if (transforms & PNG_TRANSFORM_STRIP_FILLER_AFTER)
-      png_set_filler(png_ptr, 0, PNG_FILLER_AFTER);
-
-   else if (transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE)
-      png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
-#endif
-
-#ifdef PNG_WRITE_BGR_SUPPORTED
-   /* Flip BGR pixels to RGB */
-   if (transforms & PNG_TRANSFORM_BGR)
-      png_set_bgr(png_ptr);
-#endif
-
-#ifdef PNG_WRITE_SWAP_SUPPORTED
-   /* Swap bytes of 16-bit files to most significant byte first */
-   if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
-      png_set_swap(png_ptr);
-#endif
-
-#ifdef PNG_WRITE_PACKSWAP_SUPPORTED
-   /* Swap bits of 1, 2, 4 bit packed pixel formats */
-   if (transforms & PNG_TRANSFORM_PACKSWAP)
-      png_set_packswap(png_ptr);
-#endif
-
-#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
-   /* Invert the alpha channel from opacity to transparency */
-   if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
-      png_set_invert_alpha(png_ptr);
-#endif
-
-   /* ----------------------- end of transformations ------------------- */
-
-   /* Write the bits */
-   if (info_ptr->valid & PNG_INFO_IDAT)
-       png_write_image(png_ptr, info_ptr->row_pointers);
-
-   /* It is REQUIRED to call this to finish writing the rest of the file */
-   png_write_end(png_ptr, info_ptr);
-
-   PNG_UNUSED(transforms)   /* Quiet compiler warnings */
-   PNG_UNUSED(params)
-}
-#endif
-#endif /* PNG_WRITE_SUPPORTED */
+
+/* pngwrite.c - general routines to write a PNG file
+ *
+ * Last changed in libpng 1.6.15 [November 20, 2014]
+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+#include "pngpriv.h"
+#if defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) && defined(PNG_STDIO_SUPPORTED)
+#  include <errno.h>
+#endif
+
+#ifdef PNG_WRITE_SUPPORTED
+
+#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+/* Write out all the unknown chunks for the current given location */
+static void
+write_unknown_chunks(png_structrp png_ptr, png_const_inforp info_ptr,
+   unsigned int where)
+{
+   if (info_ptr->unknown_chunks_num != 0)
+   {
+      png_const_unknown_chunkp up;
+
+      png_debug(5, "writing extra chunks");
+
+      for (up = info_ptr->unknown_chunks;
+           up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
+           ++up)
+         if ((up->location & where) != 0)
+      {
+         /* If per-chunk unknown chunk handling is enabled use it, otherwise
+          * just write the chunks the application has set.
+          */
+#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
+         int keep = png_handle_as_unknown(png_ptr, up->name);
+
+         /* NOTE: this code is radically different from the read side in the
+          * matter of handling an ancillary unknown chunk.  In the read side
+          * the default behavior is to discard it, in the code below the default
+          * behavior is to write it.  Critical chunks are, however, only
+          * written if explicitly listed or if the default is set to write all
+          * unknown chunks.
+          *
+          * The default handling is also slightly weird - it is not possible to
+          * stop the writing of all unsafe-to-copy chunks!
+          *
+          * TODO: REVIEW: this would seem to be a bug.
+          */
+         if (keep != PNG_HANDLE_CHUNK_NEVER &&
+             ((up->name[3] & 0x20) /* safe-to-copy overrides everything */ ||
+              keep == PNG_HANDLE_CHUNK_ALWAYS ||
+              (keep == PNG_HANDLE_CHUNK_AS_DEFAULT &&
+               png_ptr->unknown_default == PNG_HANDLE_CHUNK_ALWAYS)))
+#endif
+         {
+            /* TODO: review, what is wrong with a zero length unknown chunk? */
+            if (up->size == 0)
+               png_warning(png_ptr, "Writing zero-length unknown chunk");
+
+            png_write_chunk(png_ptr, up->name, up->data, up->size);
+         }
+      }
+   }
+}
+#endif /* WRITE_UNKNOWN_CHUNKS */
+
+/* Writes all the PNG information.  This is the suggested way to use the
+ * library.  If you have a new chunk to add, make a function to write it,
+ * and put it in the correct location here.  If you want the chunk written
+ * after the image data, put it in png_write_end().  I strongly encourage
+ * you to supply a PNG_INFO_ flag, and check info_ptr->valid before writing
+ * the chunk, as that will keep the code from breaking if you want to just
+ * write a plain PNG file.  If you have long comments, I suggest writing
+ * them in png_write_end(), and compressing them.
+ */
+void PNGAPI
+png_write_info_before_PLTE(png_structrp png_ptr, png_const_inforp info_ptr)
+{
+   png_debug(1, "in png_write_info_before_PLTE");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   if ((png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE) == 0)
+   {
+   /* Write PNG signature */
+   png_write_sig(png_ptr);
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+   if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0 && \
+       png_ptr->mng_features_permitted != 0)
+   {
+      png_warning(png_ptr, "MNG features are not allowed in a PNG datastream");
+      png_ptr->mng_features_permitted = 0;
+   }
+#endif
+
+   /* Write IHDR information. */
+   png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height,
+       info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type,
+       info_ptr->filter_type,
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+       info_ptr->interlace_type
+#else
+       0
+#endif
+      );
+
+   /* The rest of these check to see if the valid field has the appropriate
+    * flag set, and if it does, writes the chunk.
+    *
+    * 1.6.0: COLORSPACE support controls the writing of these chunks too, and
+    * the chunks will be written if the WRITE routine is there and information
+    * is available in the COLORSPACE.  (See png_colorspace_sync_info in png.c
+    * for where the valid flags get set.)
+    *
+    * Under certain circumstances the colorspace can be invalidated without
+    * syncing the info_struct 'valid' flags; this happens if libpng detects and
+    * error and calls png_error while the color space is being set, yet the
+    * application continues writing the PNG.  So check the 'invalid' flag here
+    * too.
+    */
+#ifdef PNG_GAMMA_SUPPORTED
+#  ifdef PNG_WRITE_gAMA_SUPPORTED
+      if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 &&
+          (info_ptr->colorspace.flags & PNG_COLORSPACE_FROM_gAMA) != 0 &&
+          (info_ptr->valid & PNG_INFO_gAMA) != 0)
+         png_write_gAMA_fixed(png_ptr, info_ptr->colorspace.gamma);
+#  endif
+#endif
+
+#ifdef PNG_COLORSPACE_SUPPORTED
+   /* Write only one of sRGB or an ICC profile.  If a profile was supplied
+    * and it matches one of the known sRGB ones issue a warning.
+    */
+#  ifdef PNG_WRITE_iCCP_SUPPORTED
+      if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 &&
+          (info_ptr->valid & PNG_INFO_iCCP) != 0)
+      {
+#        ifdef PNG_WRITE_sRGB_SUPPORTED
+            if ((info_ptr->valid & PNG_INFO_sRGB) != 0)
+               png_app_warning(png_ptr,
+                  "profile matches sRGB but writing iCCP instead");
+#        endif
+
+         png_write_iCCP(png_ptr, info_ptr->iccp_name,
+            info_ptr->iccp_profile);
+      }
+#     ifdef PNG_WRITE_sRGB_SUPPORTED
+         else
+#     endif
+#  endif
+
+#  ifdef PNG_WRITE_sRGB_SUPPORTED
+      if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 &&
+          (info_ptr->valid & PNG_INFO_sRGB) != 0)
+         png_write_sRGB(png_ptr, info_ptr->colorspace.rendering_intent);
+#  endif /* WRITE_sRGB */
+#endif /* COLORSPACE */
+
+#ifdef PNG_WRITE_sBIT_SUPPORTED
+   if ((info_ptr->valid & PNG_INFO_sBIT) != 0)
+      png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type);
+#endif
+
+#ifdef PNG_COLORSPACE_SUPPORTED
+#  ifdef PNG_WRITE_cHRM_SUPPORTED
+      if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 &&
+         (info_ptr->colorspace.flags & PNG_COLORSPACE_FROM_cHRM) != 0 &&
+         (info_ptr->valid & PNG_INFO_cHRM) != 0)
+         png_write_cHRM_fixed(png_ptr, &info_ptr->colorspace.end_points_xy);
+#  endif
+#endif
+
+#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+      write_unknown_chunks(png_ptr, info_ptr, PNG_HAVE_IHDR);
+#endif
+
+      png_ptr->mode |= PNG_WROTE_INFO_BEFORE_PLTE;
+   }
+}
+
+void PNGAPI
+png_write_info(png_structrp png_ptr, png_const_inforp info_ptr)
+{
+#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
+   int i;
+#endif
+
+   png_debug(1, "in png_write_info");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   png_write_info_before_PLTE(png_ptr, info_ptr);
+
+   if ((info_ptr->valid & PNG_INFO_PLTE) != 0)
+      png_write_PLTE(png_ptr, info_ptr->palette,
+          (png_uint_32)info_ptr->num_palette);
+
+   else if ((info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) !=0)
+      png_error(png_ptr, "Valid palette required for paletted images");
+
+#ifdef PNG_WRITE_tRNS_SUPPORTED
+   if ((info_ptr->valid & PNG_INFO_tRNS) !=0)
+   {
+#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
+      /* Invert the alpha channel (in tRNS) */
+      if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0 &&
+          info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      {
+         int j;
+         for (j = 0; j<(int)info_ptr->num_trans; j++)
+            info_ptr->trans_alpha[j] =
+               (png_byte)(255 - info_ptr->trans_alpha[j]);
+      }
+#endif
+      png_write_tRNS(png_ptr, info_ptr->trans_alpha, &(info_ptr->trans_color),
+          info_ptr->num_trans, info_ptr->color_type);
+   }
+#endif
+#ifdef PNG_WRITE_bKGD_SUPPORTED
+   if ((info_ptr->valid & PNG_INFO_bKGD) != 0)
+      png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type);
+#endif
+
+#ifdef PNG_WRITE_hIST_SUPPORTED
+   if ((info_ptr->valid & PNG_INFO_hIST) != 0)
+      png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette);
+#endif
+
+#ifdef PNG_WRITE_oFFs_SUPPORTED
+   if ((info_ptr->valid & PNG_INFO_oFFs) != 0)
+      png_write_oFFs(png_ptr, info_ptr->x_offset, info_ptr->y_offset,
+          info_ptr->offset_unit_type);
+#endif
+
+#ifdef PNG_WRITE_pCAL_SUPPORTED
+   if ((info_ptr->valid & PNG_INFO_pCAL) != 0)
+      png_write_pCAL(png_ptr, info_ptr->pcal_purpose, info_ptr->pcal_X0,
+          info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams,
+          info_ptr->pcal_units, info_ptr->pcal_params);
+#endif
+
+#ifdef PNG_WRITE_sCAL_SUPPORTED
+   if ((info_ptr->valid & PNG_INFO_sCAL) != 0)
+      png_write_sCAL_s(png_ptr, (int)info_ptr->scal_unit,
+          info_ptr->scal_s_width, info_ptr->scal_s_height);
+#endif /* sCAL */
+
+#ifdef PNG_WRITE_pHYs_SUPPORTED
+   if ((info_ptr->valid & PNG_INFO_pHYs) != 0)
+      png_write_pHYs(png_ptr, info_ptr->x_pixels_per_unit,
+          info_ptr->y_pixels_per_unit, info_ptr->phys_unit_type);
+#endif /* pHYs */
+
+#ifdef PNG_WRITE_tIME_SUPPORTED
+   if ((info_ptr->valid & PNG_INFO_tIME) != 0)
+   {
+      png_write_tIME(png_ptr, &(info_ptr->mod_time));
+      png_ptr->mode |= PNG_WROTE_tIME;
+   }
+#endif /* tIME */
+
+#ifdef PNG_WRITE_sPLT_SUPPORTED
+   if ((info_ptr->valid & PNG_INFO_sPLT) != 0)
+      for (i = 0; i < (int)info_ptr->splt_palettes_num; i++)
+         png_write_sPLT(png_ptr, info_ptr->splt_palettes + i);
+#endif /* sPLT */
+
+#ifdef PNG_WRITE_TEXT_SUPPORTED
+   /* Check to see if we need to write text chunks */
+   for (i = 0; i < info_ptr->num_text; i++)
+   {
+      png_debug2(2, "Writing header text chunk %d, type %d", i,
+          info_ptr->text[i].compression);
+      /* An internationalized chunk? */
+      if (info_ptr->text[i].compression > 0)
+      {
+#ifdef PNG_WRITE_iTXt_SUPPORTED
+         /* Write international chunk */
+         png_write_iTXt(png_ptr,
+             info_ptr->text[i].compression,
+             info_ptr->text[i].key,
+             info_ptr->text[i].lang,
+             info_ptr->text[i].lang_key,
+             info_ptr->text[i].text);
+         /* Mark this chunk as written */
+         if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
+            info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
+         else
+            info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
+#else
+         png_warning(png_ptr, "Unable to write international text");
+#endif
+      }
+
+      /* If we want a compressed text chunk */
+      else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_zTXt)
+      {
+#ifdef PNG_WRITE_zTXt_SUPPORTED
+         /* Write compressed chunk */
+         png_write_zTXt(png_ptr, info_ptr->text[i].key,
+             info_ptr->text[i].text, info_ptr->text[i].compression);
+         /* Mark this chunk as written */
+         info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
+#else
+         png_warning(png_ptr, "Unable to write compressed text");
+#endif
+      }
+
+      else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
+      {
+#ifdef PNG_WRITE_tEXt_SUPPORTED
+         /* Write uncompressed chunk */
+         png_write_tEXt(png_ptr, info_ptr->text[i].key,
+             info_ptr->text[i].text,
+             0);
+         /* Mark this chunk as written */
+         info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
+#else
+         /* Can't get here */
+         png_warning(png_ptr, "Unable to write uncompressed text");
+#endif
+      }
+   }
+#endif /* tEXt */
+
+#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+   write_unknown_chunks(png_ptr, info_ptr, PNG_HAVE_PLTE);
+#endif
+}
+
+/* Writes the end of the PNG file.  If you don't want to write comments or
+ * time information, you can pass NULL for info.  If you already wrote these
+ * in png_write_info(), do not write them again here.  If you have long
+ * comments, I suggest writing them here, and compressing them.
+ */
+void PNGAPI
+png_write_end(png_structrp png_ptr, png_inforp info_ptr)
+{
+   png_debug(1, "in png_write_end");
+
+   if (png_ptr == NULL)
+      return;
+
+   if ((png_ptr->mode & PNG_HAVE_IDAT) == 0)
+      png_error(png_ptr, "No IDATs written into file");
+
+#ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
+   if (png_ptr->num_palette_max > png_ptr->num_palette)
+      png_benign_error(png_ptr, "Wrote palette index exceeding num_palette");
+#endif
+
+   /* See if user wants us to write information chunks */
+   if (info_ptr != NULL)
+   {
+#ifdef PNG_WRITE_TEXT_SUPPORTED
+      int i; /* local index variable */
+#endif
+#ifdef PNG_WRITE_tIME_SUPPORTED
+      /* Check to see if user has supplied a time chunk */
+      if ((info_ptr->valid & PNG_INFO_tIME) != 0 &&
+          (png_ptr->mode & PNG_WROTE_tIME) == 0)
+         png_write_tIME(png_ptr, &(info_ptr->mod_time));
+
+#endif
+#ifdef PNG_WRITE_TEXT_SUPPORTED
+      /* Loop through comment chunks */
+      for (i = 0; i < info_ptr->num_text; i++)
+      {
+         png_debug2(2, "Writing trailer text chunk %d, type %d", i,
+            info_ptr->text[i].compression);
+         /* An internationalized chunk? */
+         if (info_ptr->text[i].compression > 0)
+         {
+#ifdef PNG_WRITE_iTXt_SUPPORTED
+            /* Write international chunk */
+            png_write_iTXt(png_ptr,
+                info_ptr->text[i].compression,
+                info_ptr->text[i].key,
+                info_ptr->text[i].lang,
+                info_ptr->text[i].lang_key,
+                info_ptr->text[i].text);
+            /* Mark this chunk as written */
+            if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
+               info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
+            else
+               info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
+#else
+            png_warning(png_ptr, "Unable to write international text");
+#endif
+         }
+
+         else if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt)
+         {
+#ifdef PNG_WRITE_zTXt_SUPPORTED
+            /* Write compressed chunk */
+            png_write_zTXt(png_ptr, info_ptr->text[i].key,
+                info_ptr->text[i].text, info_ptr->text[i].compression);
+            /* Mark this chunk as written */
+            info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
+#else
+            png_warning(png_ptr, "Unable to write compressed text");
+#endif
+         }
+
+         else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
+         {
+#ifdef PNG_WRITE_tEXt_SUPPORTED
+            /* Write uncompressed chunk */
+            png_write_tEXt(png_ptr, info_ptr->text[i].key,
+                info_ptr->text[i].text, 0);
+            /* Mark this chunk as written */
+            info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
+#else
+            png_warning(png_ptr, "Unable to write uncompressed text");
+#endif
+         }
+      }
+#endif
+#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+      write_unknown_chunks(png_ptr, info_ptr, PNG_AFTER_IDAT);
+#endif
+   }
+
+   png_ptr->mode |= PNG_AFTER_IDAT;
+
+   /* Write end of PNG file */
+   png_write_IEND(png_ptr);
+
+   /* This flush, added in libpng-1.0.8, removed from libpng-1.0.9beta03,
+    * and restored again in libpng-1.2.30, may cause some applications that
+    * do not set png_ptr->output_flush_fn to crash.  If your application
+    * experiences a problem, please try building libpng with
+    * PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED defined, and report the event to
+    * png-mng-implement at lists.sf.net .
+    */
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+#  ifdef PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED
+   png_flush(png_ptr);
+#  endif
+#endif
+}
+
+#ifdef PNG_CONVERT_tIME_SUPPORTED
+void PNGAPI
+png_convert_from_struct_tm(png_timep ptime, PNG_CONST struct tm * ttime)
+{
+   png_debug(1, "in png_convert_from_struct_tm");
+
+   ptime->year = (png_uint_16)(1900 + ttime->tm_year);
+   ptime->month = (png_byte)(ttime->tm_mon + 1);
+   ptime->day = (png_byte)ttime->tm_mday;
+   ptime->hour = (png_byte)ttime->tm_hour;
+   ptime->minute = (png_byte)ttime->tm_min;
+   ptime->second = (png_byte)ttime->tm_sec;
+}
+
+void PNGAPI
+png_convert_from_time_t(png_timep ptime, time_t ttime)
+{
+   struct tm *tbuf;
+
+   png_debug(1, "in png_convert_from_time_t");
+
+   tbuf = gmtime(&ttime);
+   png_convert_from_struct_tm(ptime, tbuf);
+}
+#endif
+
+/* Initialize png_ptr structure, and allocate any memory needed */
+PNG_FUNCTION(png_structp,PNGAPI
+png_create_write_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
+    png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED)
+{
+#ifndef PNG_USER_MEM_SUPPORTED
+   png_structrp png_ptr = png_create_png_struct(user_png_ver, error_ptr,
+       error_fn, warn_fn, NULL, NULL, NULL);
+#else
+   return png_create_write_struct_2(user_png_ver, error_ptr, error_fn,
+       warn_fn, NULL, NULL, NULL);
+}
+
+/* Alternate initialize png_ptr structure, and allocate any memory needed */
+PNG_FUNCTION(png_structp,PNGAPI
+png_create_write_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr,
+    png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
+    png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED)
+{
+   png_structrp png_ptr = png_create_png_struct(user_png_ver, error_ptr,
+       error_fn, warn_fn, mem_ptr, malloc_fn, free_fn);
+#endif /* USER_MEM */
+   if (png_ptr != NULL)
+   {
+      /* Set the zlib control values to defaults; they can be overridden by the
+       * application after the struct has been created.
+       */
+      png_ptr->zbuffer_size = PNG_ZBUF_SIZE;
+
+      /* The 'zlib_strategy' setting is irrelevant because png_default_claim in
+       * pngwutil.c defaults it according to whether or not filters will be
+       * used, and ignores this setting.
+       */
+      png_ptr->zlib_strategy = PNG_Z_DEFAULT_STRATEGY;
+      png_ptr->zlib_level = PNG_Z_DEFAULT_COMPRESSION;
+      png_ptr->zlib_mem_level = 8;
+      png_ptr->zlib_window_bits = 15;
+      png_ptr->zlib_method = 8;
+
+#ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED
+      png_ptr->zlib_text_strategy = PNG_TEXT_Z_DEFAULT_STRATEGY;
+      png_ptr->zlib_text_level = PNG_TEXT_Z_DEFAULT_COMPRESSION;
+      png_ptr->zlib_text_mem_level = 8;
+      png_ptr->zlib_text_window_bits = 15;
+      png_ptr->zlib_text_method = 8;
+#endif /* WRITE_COMPRESSED_TEXT */
+
+      /* This is a highly dubious configuration option; by default it is off,
+       * but it may be appropriate for private builds that are testing
+       * extensions not conformant to the current specification, or of
+       * applications that must not fail to write at all costs!
+       */
+#ifdef PNG_BENIGN_WRITE_ERRORS_SUPPORTED
+      /* In stable builds only warn if an application error can be completely
+       * handled.
+       */
+      png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN;
+#endif
+
+      /* App warnings are warnings in release (or release candidate) builds but
+       * are errors during development.
+       */
+#if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC
+      png_ptr->flags |= PNG_FLAG_APP_WARNINGS_WARN;
+#endif
+
+      /* TODO: delay this, it can be done in png_init_io() (if the app doesn't
+       * do it itself) avoiding setting the default function if it is not
+       * required.
+       */
+      png_set_write_fn(png_ptr, NULL, NULL, NULL);
+   }
+
+   return png_ptr;
+}
+
+
+/* Write a few rows of image data.  If the image is interlaced,
+ * either you will have to write the 7 sub images, or, if you
+ * have called png_set_interlace_handling(), you will have to
+ * "write" the image seven times.
+ */
+void PNGAPI
+png_write_rows(png_structrp png_ptr, png_bytepp row,
+    png_uint_32 num_rows)
+{
+   png_uint_32 i; /* row counter */
+   png_bytepp rp; /* row pointer */
+
+   png_debug(1, "in png_write_rows");
+
+   if (png_ptr == NULL)
+      return;
+
+   /* Loop through the rows */
+   for (i = 0, rp = row; i < num_rows; i++, rp++)
+   {
+      png_write_row(png_ptr, *rp);
+   }
+}
+
+/* Write the image.  You only need to call this function once, even
+ * if you are writing an interlaced image.
+ */
+void PNGAPI
+png_write_image(png_structrp png_ptr, png_bytepp image)
+{
+   png_uint_32 i; /* row index */
+   int pass, num_pass; /* pass variables */
+   png_bytepp rp; /* points to current row */
+
+   if (png_ptr == NULL)
+      return;
+
+   png_debug(1, "in png_write_image");
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+   /* Initialize interlace handling.  If image is not interlaced,
+    * this will set pass to 1
+    */
+   num_pass = png_set_interlace_handling(png_ptr);
+#else
+   num_pass = 1;
+#endif
+   /* Loop through passes */
+   for (pass = 0; pass < num_pass; pass++)
+   {
+      /* Loop through image */
+      for (i = 0, rp = image; i < png_ptr->height; i++, rp++)
+      {
+         png_write_row(png_ptr, *rp);
+      }
+   }
+}
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+/* Performs intrapixel differencing  */
+static void
+png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_write_intrapixel");
+
+   if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
+   {
+      int bytes_per_pixel;
+      png_uint_32 row_width = row_info->width;
+      if (row_info->bit_depth == 8)
+      {
+         png_bytep rp;
+         png_uint_32 i;
+
+         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+            bytes_per_pixel = 3;
+
+         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+            bytes_per_pixel = 4;
+
+         else
+            return;
+
+         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+         {
+            *(rp)     = (png_byte)((*rp       - *(rp + 1)) & 0xff);
+            *(rp + 2) = (png_byte)((*(rp + 2) - *(rp + 1)) & 0xff);
+         }
+      }
+
+#ifdef PNG_WRITE_16BIT_SUPPORTED
+      else if (row_info->bit_depth == 16)
+      {
+         png_bytep rp;
+         png_uint_32 i;
+
+         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+            bytes_per_pixel = 6;
+
+         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+            bytes_per_pixel = 8;
+
+         else
+            return;
+
+         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+         {
+            png_uint_32 s0   = (*(rp    ) << 8) | *(rp + 1);
+            png_uint_32 s1   = (*(rp + 2) << 8) | *(rp + 3);
+            png_uint_32 s2   = (*(rp + 4) << 8) | *(rp + 5);
+            png_uint_32 red  = (png_uint_32)((s0 - s1) & 0xffffL);
+            png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL);
+            *(rp    ) = (png_byte)((red >> 8) & 0xff);
+            *(rp + 1) = (png_byte)(red & 0xff);
+            *(rp + 4) = (png_byte)((blue >> 8) & 0xff);
+            *(rp + 5) = (png_byte)(blue & 0xff);
+         }
+      }
+#endif /* WRITE_16BIT */
+   }
+}
+#endif /* MNG_FEATURES */
+
+/* Called by user to write a row of image data */
+void PNGAPI
+png_write_row(png_structrp png_ptr, png_const_bytep row)
+{
+   /* 1.5.6: moved from png_struct to be a local structure: */
+   png_row_info row_info;
+
+   if (png_ptr == NULL)
+      return;
+
+   png_debug2(1, "in png_write_row (row %u, pass %d)",
+      png_ptr->row_number, png_ptr->pass);
+
+   /* Initialize transformations and other stuff if first time */
+   if (png_ptr->row_number == 0 && png_ptr->pass == 0)
+   {
+      /* Make sure we wrote the header info */
+      if ((png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE) == 0)
+         png_error(png_ptr,
+             "png_write_info was never called before png_write_row");
+
+      /* Check for transforms that have been set but were defined out */
+#if !defined(PNG_WRITE_INVERT_SUPPORTED) && defined(PNG_READ_INVERT_SUPPORTED)
+      if ((png_ptr->transformations & PNG_INVERT_MONO) != 0)
+         png_warning(png_ptr, "PNG_WRITE_INVERT_SUPPORTED is not defined");
+#endif
+
+#if !defined(PNG_WRITE_FILLER_SUPPORTED) && defined(PNG_READ_FILLER_SUPPORTED)
+      if ((png_ptr->transformations & PNG_FILLER) != 0)
+         png_warning(png_ptr, "PNG_WRITE_FILLER_SUPPORTED is not defined");
+#endif
+#if !defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \
+    defined(PNG_READ_PACKSWAP_SUPPORTED)
+      if ((png_ptr->transformations & PNG_PACKSWAP) != 0)
+         png_warning(png_ptr,
+             "PNG_WRITE_PACKSWAP_SUPPORTED is not defined");
+#endif
+
+#if !defined(PNG_WRITE_PACK_SUPPORTED) && defined(PNG_READ_PACK_SUPPORTED)
+      if ((png_ptr->transformations & PNG_PACK) != 0)
+         png_warning(png_ptr, "PNG_WRITE_PACK_SUPPORTED is not defined");
+#endif
+
+#if !defined(PNG_WRITE_SHIFT_SUPPORTED) && defined(PNG_READ_SHIFT_SUPPORTED)
+      if ((png_ptr->transformations & PNG_SHIFT) != 0)
+         png_warning(png_ptr, "PNG_WRITE_SHIFT_SUPPORTED is not defined");
+#endif
+
+#if !defined(PNG_WRITE_BGR_SUPPORTED) && defined(PNG_READ_BGR_SUPPORTED)
+      if ((png_ptr->transformations & PNG_BGR) != 0)
+         png_warning(png_ptr, "PNG_WRITE_BGR_SUPPORTED is not defined");
+#endif
+
+#if !defined(PNG_WRITE_SWAP_SUPPORTED) && defined(PNG_READ_SWAP_SUPPORTED)
+      if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0)
+         png_warning(png_ptr, "PNG_WRITE_SWAP_SUPPORTED is not defined");
+#endif
+
+      png_write_start_row(png_ptr);
+   }
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+   /* If interlaced and not interested in row, return */
+   if (png_ptr->interlaced != 0 &&
+       (png_ptr->transformations & PNG_INTERLACE) != 0)
+   {
+      switch (png_ptr->pass)
+      {
+         case 0:
+            if ((png_ptr->row_number & 0x07) != 0)
+            {
+               png_write_finish_row(png_ptr);
+               return;
+            }
+            break;
+
+         case 1:
+            if ((png_ptr->row_number & 0x07) != 0 || png_ptr->width < 5)
+            {
+               png_write_finish_row(png_ptr);
+               return;
+            }
+            break;
+
+         case 2:
+            if ((png_ptr->row_number & 0x07) != 4)
+            {
+               png_write_finish_row(png_ptr);
+               return;
+            }
+            break;
+
+         case 3:
+            if ((png_ptr->row_number & 0x03) != 0 || png_ptr->width < 3)
+            {
+               png_write_finish_row(png_ptr);
+               return;
+            }
+            break;
+
+         case 4:
+            if ((png_ptr->row_number & 0x03) != 2)
+            {
+               png_write_finish_row(png_ptr);
+               return;
+            }
+            break;
+
+         case 5:
+            if ((png_ptr->row_number & 0x01) != 0 || png_ptr->width < 2)
+            {
+               png_write_finish_row(png_ptr);
+               return;
+            }
+            break;
+
+         case 6:
+            if ((png_ptr->row_number & 0x01) == 0)
+            {
+               png_write_finish_row(png_ptr);
+               return;
+            }
+            break;
+
+         default: /* error: ignore it */
+            break;
+      }
+   }
+#endif
+
+   /* Set up row info for transformations */
+   row_info.color_type = png_ptr->color_type;
+   row_info.width = png_ptr->usr_width;
+   row_info.channels = png_ptr->usr_channels;
+   row_info.bit_depth = png_ptr->usr_bit_depth;
+   row_info.pixel_depth = (png_byte)(row_info.bit_depth * row_info.channels);
+   row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width);
+
+   png_debug1(3, "row_info->color_type = %d", row_info.color_type);
+   png_debug1(3, "row_info->width = %u", row_info.width);
+   png_debug1(3, "row_info->channels = %d", row_info.channels);
+   png_debug1(3, "row_info->bit_depth = %d", row_info.bit_depth);
+   png_debug1(3, "row_info->pixel_depth = %d", row_info.pixel_depth);
+   png_debug1(3, "row_info->rowbytes = %lu", (unsigned long)row_info.rowbytes);
+
+   /* Copy user's row into buffer, leaving room for filter byte. */
+   memcpy(png_ptr->row_buf + 1, row, row_info.rowbytes);
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+   /* Handle interlacing */
+   if (png_ptr->interlaced && png_ptr->pass < 6 &&
+       (png_ptr->transformations & PNG_INTERLACE) != 0)
+   {
+      png_do_write_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass);
+      /* This should always get caught above, but still ... */
+      if (row_info.width == 0)
+      {
+         png_write_finish_row(png_ptr);
+         return;
+      }
+   }
+#endif
+
+#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
+   /* Handle other transformations */
+   if (png_ptr->transformations != 0)
+      png_do_write_transformations(png_ptr, &row_info);
+#endif
+
+   /* At this point the row_info pixel depth must match the 'transformed' depth,
+    * which is also the output depth.
+    */
+   if (row_info.pixel_depth != png_ptr->pixel_depth ||
+      row_info.pixel_depth != png_ptr->transformed_pixel_depth)
+      png_error(png_ptr, "internal write transform logic error");
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+   /* Write filter_method 64 (intrapixel differencing) only if
+    * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
+    * 2. Libpng did not write a PNG signature (this filter_method is only
+    *    used in PNG datastreams that are embedded in MNG datastreams) and
+    * 3. The application called png_permit_mng_features with a mask that
+    *    included PNG_FLAG_MNG_FILTER_64 and
+    * 4. The filter_method is 64 and
+    * 5. The color_type is RGB or RGBA
+    */
+   if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 &&
+       (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
+   {
+      /* Intrapixel differencing */
+      png_do_write_intrapixel(&row_info, png_ptr->row_buf + 1);
+   }
+#endif
+
+/* Added at libpng-1.5.10 */
+#ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
+   /* Check for out-of-range palette index */
+   if (row_info.color_type == PNG_COLOR_TYPE_PALETTE &&
+       png_ptr->num_palette_max >= 0)
+      png_do_check_palette_indexes(png_ptr, &row_info);
+#endif
+
+   /* Find a filter if necessary, filter the row and write it out. */
+   png_write_find_filter(png_ptr, &row_info);
+
+   if (png_ptr->write_row_fn != NULL)
+      (*(png_ptr->write_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
+}
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+/* Set the automatic flush interval or 0 to turn flushing off */
+void PNGAPI
+png_set_flush(png_structrp png_ptr, int nrows)
+{
+   png_debug(1, "in png_set_flush");
+
+   if (png_ptr == NULL)
+      return;
+
+   png_ptr->flush_dist = (nrows < 0 ? 0 : nrows);
+}
+
+/* Flush the current output buffers now */
+void PNGAPI
+png_write_flush(png_structrp png_ptr)
+{
+   png_debug(1, "in png_write_flush");
+
+   if (png_ptr == NULL)
+      return;
+
+   /* We have already written out all of the data */
+   if (png_ptr->row_number >= png_ptr->num_rows)
+      return;
+
+   png_compress_IDAT(png_ptr, NULL, 0, Z_SYNC_FLUSH);
+   png_ptr->flush_rows = 0;
+   png_flush(png_ptr);
+}
+#endif /* WRITE_FLUSH */
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+static void png_reset_filter_heuristics(png_structrp png_ptr);/* forward decl */
+#endif
+
+/* Free any memory used in png_ptr struct without freeing the struct itself. */
+static void
+png_write_destroy(png_structrp png_ptr)
+{
+   png_debug(1, "in png_write_destroy");
+
+   /* Free any memory zlib uses */
+   if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0)
+      deflateEnd(&png_ptr->zstream);
+
+   /* Free our memory.  png_free checks NULL for us. */
+   png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list);
+   png_free(png_ptr, png_ptr->row_buf);
+   png_ptr->row_buf = NULL;
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+   png_free(png_ptr, png_ptr->prev_row);
+   png_free(png_ptr, png_ptr->sub_row);
+   png_free(png_ptr, png_ptr->up_row);
+   png_free(png_ptr, png_ptr->avg_row);
+   png_free(png_ptr, png_ptr->paeth_row);
+   png_ptr->prev_row = NULL;
+   png_ptr->sub_row = NULL;
+   png_ptr->up_row = NULL;
+   png_ptr->avg_row = NULL;
+   png_ptr->paeth_row = NULL;
+#endif
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+   /* Use this to save a little code space, it doesn't free the filter_costs */
+   png_reset_filter_heuristics(png_ptr);
+   png_free(png_ptr, png_ptr->filter_costs);
+   png_free(png_ptr, png_ptr->inv_filter_costs);
+   png_ptr->filter_costs = NULL;
+   png_ptr->inv_filter_costs = NULL;
+#endif
+
+#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
+   png_free(png_ptr, png_ptr->chunk_list);
+   png_ptr->chunk_list = NULL;
+#endif
+
+   /* The error handling and memory handling information is left intact at this
+    * point: the jmp_buf may still have to be freed.  See png_destroy_png_struct
+    * for how this happens.
+    */
+}
+
+/* Free all memory used by the write.
+ * In libpng 1.6.0 this API changed quietly to no longer accept a NULL value for
+ * *png_ptr_ptr.  Prior to 1.6.0 it would accept such a value and it would free
+ * the passed in info_structs but it would quietly fail to free any of the data
+ * inside them.  In 1.6.0 it quietly does nothing (it has to be quiet because it
+ * has no png_ptr.)
+ */
+void PNGAPI
+png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr)
+{
+   png_debug(1, "in png_destroy_write_struct");
+
+   if (png_ptr_ptr != NULL)
+   {
+      png_structrp png_ptr = *png_ptr_ptr;
+
+      if (png_ptr != NULL) /* added in libpng 1.6.0 */
+      {
+         png_destroy_info_struct(png_ptr, info_ptr_ptr);
+
+         *png_ptr_ptr = NULL;
+         png_write_destroy(png_ptr);
+         png_destroy_png_struct(png_ptr);
+      }
+   }
+}
+
+/* Allow the application to select one or more row filters to use. */
+void PNGAPI
+png_set_filter(png_structrp png_ptr, int method, int filters)
+{
+   png_debug(1, "in png_set_filter");
+
+   if (png_ptr == NULL)
+      return;
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+   if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 &&
+       (method == PNG_INTRAPIXEL_DIFFERENCING))
+      method = PNG_FILTER_TYPE_BASE;
+
+#endif
+   if (method == PNG_FILTER_TYPE_BASE)
+   {
+      switch (filters & (PNG_ALL_FILTERS | 0x07))
+      {
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+         case 5:
+         case 6:
+         case 7: png_app_error(png_ptr, "Unknown row filter for method 0");
+            /* FALL THROUGH */
+#endif /* WRITE_FILTER */
+         case PNG_FILTER_VALUE_NONE:
+            png_ptr->do_filter = PNG_FILTER_NONE; break;
+
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+         case PNG_FILTER_VALUE_SUB:
+            png_ptr->do_filter = PNG_FILTER_SUB; break;
+
+         case PNG_FILTER_VALUE_UP:
+            png_ptr->do_filter = PNG_FILTER_UP; break;
+
+         case PNG_FILTER_VALUE_AVG:
+            png_ptr->do_filter = PNG_FILTER_AVG; break;
+
+         case PNG_FILTER_VALUE_PAETH:
+            png_ptr->do_filter = PNG_FILTER_PAETH; break;
+
+         default:
+            png_ptr->do_filter = (png_byte)filters; break;
+#else
+         default:
+            png_app_error(png_ptr, "Unknown row filter for method 0");
+#endif /* WRITE_FILTER */
+      }
+
+      /* If we have allocated the row_buf, this means we have already started
+       * with the image and we should have allocated all of the filter buffers
+       * that have been selected.  If prev_row isn't already allocated, then
+       * it is too late to start using the filters that need it, since we
+       * will be missing the data in the previous row.  If an application
+       * wants to start and stop using particular filters during compression,
+       * it should start out with all of the filters, and then add and
+       * remove them after the start of compression.
+       */
+      if (png_ptr->row_buf != NULL)
+      {
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+         if ((png_ptr->do_filter & PNG_FILTER_SUB) != 0 &&
+             png_ptr->sub_row == NULL)
+         {
+            png_ptr->sub_row = (png_bytep)png_malloc(png_ptr,
+                (png_ptr->rowbytes + 1));
+            png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
+         }
+
+         if ((png_ptr->do_filter & PNG_FILTER_UP) != 0 &&
+              png_ptr->up_row == NULL)
+         {
+            if (png_ptr->prev_row == NULL)
+            {
+               png_warning(png_ptr, "Can't add Up filter after starting");
+               png_ptr->do_filter = (png_byte)(png_ptr->do_filter &
+                   ~PNG_FILTER_UP);
+            }
+
+            else
+            {
+               png_ptr->up_row = (png_bytep)png_malloc(png_ptr,
+                   (png_ptr->rowbytes + 1));
+               png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
+            }
+         }
+
+         if ((png_ptr->do_filter & PNG_FILTER_AVG) != 0 &&
+              png_ptr->avg_row == NULL)
+         {
+            if (png_ptr->prev_row == NULL)
+            {
+               png_warning(png_ptr, "Can't add Average filter after starting");
+               png_ptr->do_filter = (png_byte)(png_ptr->do_filter &
+                   ~PNG_FILTER_AVG);
+            }
+
+            else
+            {
+               png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
+                   (png_ptr->rowbytes + 1));
+               png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
+            }
+         }
+
+         if ((png_ptr->do_filter & PNG_FILTER_PAETH) != 0 &&
+             png_ptr->paeth_row == NULL)
+         {
+            if (png_ptr->prev_row == NULL)
+            {
+               png_warning(png_ptr, "Can't add Paeth filter after starting");
+               png_ptr->do_filter &= (png_byte)(~PNG_FILTER_PAETH);
+            }
+
+            else
+            {
+               png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr,
+                   (png_ptr->rowbytes + 1));
+               png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
+            }
+         }
+
+         if (png_ptr->do_filter == PNG_NO_FILTERS)
+#endif /* WRITE_FILTER */
+            png_ptr->do_filter = PNG_FILTER_NONE;
+      }
+   }
+   else
+      png_error(png_ptr, "Unknown custom filter method");
+}
+
+/* This allows us to influence the way in which libpng chooses the "best"
+ * filter for the current scanline.  While the "minimum-sum-of-absolute-
+ * differences metric is relatively fast and effective, there is some
+ * question as to whether it can be improved upon by trying to keep the
+ * filtered data going to zlib more consistent, hopefully resulting in
+ * better compression.
+ */
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED      /* GRR 970116 */
+/* Convenience reset API. */
+static void
+png_reset_filter_heuristics(png_structrp png_ptr)
+{
+   /* Clear out any old values in the 'weights' - this must be done because if
+    * the app calls set_filter_heuristics multiple times with different
+    * 'num_weights' values we would otherwise potentially have wrong sized
+    * arrays.
+    */
+   png_ptr->num_prev_filters = 0;
+   png_ptr->heuristic_method = PNG_FILTER_HEURISTIC_UNWEIGHTED;
+   if (png_ptr->prev_filters != NULL)
+   {
+      png_bytep old = png_ptr->prev_filters;
+      png_ptr->prev_filters = NULL;
+      png_free(png_ptr, old);
+   }
+   if (png_ptr->filter_weights != NULL)
+   {
+      png_uint_16p old = png_ptr->filter_weights;
+      png_ptr->filter_weights = NULL;
+      png_free(png_ptr, old);
+   }
+
+   if (png_ptr->inv_filter_weights != NULL)
+   {
+      png_uint_16p old = png_ptr->inv_filter_weights;
+      png_ptr->inv_filter_weights = NULL;
+      png_free(png_ptr, old);
+   }
+
+   /* Leave the filter_costs - this array is fixed size. */
+}
+
+static int
+png_init_filter_heuristics(png_structrp png_ptr, int heuristic_method,
+   int num_weights)
+{
+   if (png_ptr == NULL)
+      return 0;
+
+   /* Clear out the arrays */
+   png_reset_filter_heuristics(png_ptr);
+
+   /* Check arguments; the 'reset' function makes the correct settings for the
+    * unweighted case, but we must handle the weight case by initializing the
+    * arrays for the caller.
+    */
+   if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+   {
+      int i;
+
+      if (num_weights > 0)
+      {
+         png_ptr->prev_filters = (png_bytep)png_malloc(png_ptr,
+             (png_uint_32)((sizeof (png_byte)) * num_weights));
+
+         /* To make sure that the weighting starts out fairly */
+         for (i = 0; i < num_weights; i++)
+         {
+            png_ptr->prev_filters[i] = 255;
+         }
+
+         png_ptr->filter_weights = (png_uint_16p)png_malloc(png_ptr,
+             (png_uint_32)((sizeof (png_uint_16)) * num_weights));
+
+         png_ptr->inv_filter_weights = (png_uint_16p)png_malloc(png_ptr,
+             (png_uint_32)((sizeof (png_uint_16)) * num_weights));
+
+         for (i = 0; i < num_weights; i++)
+         {
+            png_ptr->inv_filter_weights[i] =
+            png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
+         }
+
+         /* Safe to set this now */
+         png_ptr->num_prev_filters = (png_byte)num_weights;
+      }
+
+      /* If, in the future, there are other filter methods, this would
+       * need to be based on png_ptr->filter.
+       */
+      if (png_ptr->filter_costs == NULL)
+      {
+         png_ptr->filter_costs = (png_uint_16p)png_malloc(png_ptr,
+             (png_uint_32)((sizeof (png_uint_16)) * PNG_FILTER_VALUE_LAST));
+
+         png_ptr->inv_filter_costs = (png_uint_16p)png_malloc(png_ptr,
+             (png_uint_32)((sizeof (png_uint_16)) * PNG_FILTER_VALUE_LAST));
+      }
+
+      for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
+      {
+         png_ptr->inv_filter_costs[i] =
+         png_ptr->filter_costs[i] = PNG_COST_FACTOR;
+      }
+
+      /* All the arrays are inited, safe to set this: */
+      png_ptr->heuristic_method = PNG_FILTER_HEURISTIC_WEIGHTED;
+
+      /* Return the 'ok' code. */
+      return 1;
+   }
+   else if (heuristic_method == PNG_FILTER_HEURISTIC_DEFAULT ||
+      heuristic_method == PNG_FILTER_HEURISTIC_UNWEIGHTED)
+   {
+      return 1;
+   }
+   else
+   {
+      png_warning(png_ptr, "Unknown filter heuristic method");
+      return 0;
+   }
+}
+
+/* Provide floating and fixed point APIs */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+void PNGAPI
+png_set_filter_heuristics(png_structrp png_ptr, int heuristic_method,
+    int num_weights, png_const_doublep filter_weights,
+    png_const_doublep filter_costs)
+{
+   png_debug(1, "in png_set_filter_heuristics");
+
+   /* The internal API allocates all the arrays and ensures that the elements of
+    * those arrays are set to the default value.
+    */
+   if (png_init_filter_heuristics(png_ptr, heuristic_method, num_weights) == 0)
+      return;
+
+   /* If using the weighted method copy in the weights. */
+   if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+   {
+      int i;
+      for (i = 0; i < num_weights; i++)
+      {
+         if (filter_weights[i] <= 0.0)
+         {
+            png_ptr->inv_filter_weights[i] =
+            png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
+         }
+
+         else
+         {
+            png_ptr->inv_filter_weights[i] =
+                (png_uint_16)(PNG_WEIGHT_FACTOR*filter_weights[i]+.5);
+
+            png_ptr->filter_weights[i] =
+                (png_uint_16)(PNG_WEIGHT_FACTOR/filter_weights[i]+.5);
+         }
+      }
+
+      /* Here is where we set the relative costs of the different filters.  We
+       * should take the desired compression level into account when setting
+       * the costs, so that Paeth, for instance, has a high relative cost at low
+       * compression levels, while it has a lower relative cost at higher
+       * compression settings.  The filter types are in order of increasing
+       * relative cost, so it would be possible to do this with an algorithm.
+       */
+      for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) if (filter_costs[i] >= 1.0)
+      {
+         png_ptr->inv_filter_costs[i] =
+             (png_uint_16)(PNG_COST_FACTOR / filter_costs[i] + .5);
+
+         png_ptr->filter_costs[i] =
+             (png_uint_16)(PNG_COST_FACTOR * filter_costs[i] + .5);
+      }
+   }
+}
+#endif /* FLOATING_POINT */
+
+#ifdef PNG_FIXED_POINT_SUPPORTED
+void PNGAPI
+png_set_filter_heuristics_fixed(png_structrp png_ptr, int heuristic_method,
+    int num_weights, png_const_fixed_point_p filter_weights,
+    png_const_fixed_point_p filter_costs)
+{
+   png_debug(1, "in png_set_filter_heuristics_fixed");
+
+   /* The internal API allocates all the arrays and ensures that the elements of
+    * those arrays are set to the default value.
+    */
+   if (png_init_filter_heuristics(png_ptr, heuristic_method, num_weights) == 0)
+      return;
+
+   /* If using the weighted method copy in the weights. */
+   if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+   {
+      int i;
+      for (i = 0; i < num_weights; i++)
+      {
+         if (filter_weights[i] <= 0)
+         {
+            png_ptr->inv_filter_weights[i] =
+            png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
+         }
+
+         else
+         {
+            png_ptr->inv_filter_weights[i] = (png_uint_16)
+               ((PNG_WEIGHT_FACTOR*filter_weights[i]+PNG_FP_HALF)/PNG_FP_1);
+
+            png_ptr->filter_weights[i] = (png_uint_16)((PNG_WEIGHT_FACTOR*
+               PNG_FP_1+(filter_weights[i]/2))/filter_weights[i]);
+         }
+      }
+
+      /* Here is where we set the relative costs of the different filters.  We
+       * should take the desired compression level into account when setting
+       * the costs, so that Paeth, for instance, has a high relative cost at low
+       * compression levels, while it has a lower relative cost at higher
+       * compression settings.  The filter types are in order of increasing
+       * relative cost, so it would be possible to do this with an algorithm.
+       */
+      for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
+         if (filter_costs[i] >= PNG_FP_1)
+      {
+         png_uint_32 tmp;
+
+         /* Use a 32 bit unsigned temporary here because otherwise the
+          * intermediate value will be a 32 bit *signed* integer (ANSI rules)
+          * and this will get the wrong answer on division.
+          */
+         tmp = PNG_COST_FACTOR*PNG_FP_1 + (filter_costs[i]/2);
+         tmp /= filter_costs[i];
+
+         png_ptr->inv_filter_costs[i] = (png_uint_16)tmp;
+
+         tmp = PNG_COST_FACTOR * filter_costs[i] + PNG_FP_HALF;
+         tmp /= PNG_FP_1;
+
+         png_ptr->filter_costs[i] = (png_uint_16)tmp;
+      }
+   }
+}
+#endif /* FIXED_POINT */
+#endif /* WRITE_WEIGHTED_FILTER */
+
+void PNGAPI
+png_set_compression_level(png_structrp png_ptr, int level)
+{
+   png_debug(1, "in png_set_compression_level");
+
+   if (png_ptr == NULL)
+      return;
+
+   png_ptr->zlib_level = level;
+}
+
+void PNGAPI
+png_set_compression_mem_level(png_structrp png_ptr, int mem_level)
+{
+   png_debug(1, "in png_set_compression_mem_level");
+
+   if (png_ptr == NULL)
+      return;
+
+   png_ptr->zlib_mem_level = mem_level;
+}
+
+void PNGAPI
+png_set_compression_strategy(png_structrp png_ptr, int strategy)
+{
+   png_debug(1, "in png_set_compression_strategy");
+
+   if (png_ptr == NULL)
+      return;
+
+   /* The flag setting here prevents the libpng dynamic selection of strategy.
+    */
+   png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_STRATEGY;
+   png_ptr->zlib_strategy = strategy;
+}
+
+/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a
+ * smaller value of window_bits if it can do so safely.
+ */
+void PNGAPI
+png_set_compression_window_bits(png_structrp png_ptr, int window_bits)
+{
+   if (png_ptr == NULL)
+      return;
+
+   /* Prior to 1.6.0 this would warn but then set the window_bits value, this
+    * meant that negative window bits values could be selected which would cause
+    * libpng to write a non-standard PNG file with raw deflate or gzip
+    * compressed IDAT or ancillary chunks.  Such files can be read and there is
+    * no warning on read, so this seems like a very bad idea.
+    */
+   if (window_bits > 15)
+   {
+      png_warning(png_ptr, "Only compression windows <= 32k supported by PNG");
+      window_bits = 15;
+   }
+
+   else if (window_bits < 8)
+   {
+      png_warning(png_ptr, "Only compression windows >= 256 supported by PNG");
+      window_bits = 8;
+   }
+
+   png_ptr->zlib_window_bits = window_bits;
+}
+
+void PNGAPI
+png_set_compression_method(png_structrp png_ptr, int method)
+{
+   png_debug(1, "in png_set_compression_method");
+
+   if (png_ptr == NULL)
+      return;
+
+   /* This would produce an invalid PNG file if it worked, but it doesn't and
+    * deflate will fault it, so it is harmless to just warn here.
+    */
+   if (method != 8)
+      png_warning(png_ptr, "Only compression method 8 is supported by PNG");
+
+   png_ptr->zlib_method = method;
+}
+
+/* The following were added to libpng-1.5.4 */
+#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
+void PNGAPI
+png_set_text_compression_level(png_structrp png_ptr, int level)
+{
+   png_debug(1, "in png_set_text_compression_level");
+
+   if (png_ptr == NULL)
+      return;
+
+   png_ptr->zlib_text_level = level;
+}
+
+void PNGAPI
+png_set_text_compression_mem_level(png_structrp png_ptr, int mem_level)
+{
+   png_debug(1, "in png_set_text_compression_mem_level");
+
+   if (png_ptr == NULL)
+      return;
+
+   png_ptr->zlib_text_mem_level = mem_level;
+}
+
+void PNGAPI
+png_set_text_compression_strategy(png_structrp png_ptr, int strategy)
+{
+   png_debug(1, "in png_set_text_compression_strategy");
+
+   if (png_ptr == NULL)
+      return;
+
+   png_ptr->zlib_text_strategy = strategy;
+}
+
+/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a
+ * smaller value of window_bits if it can do so safely.
+ */
+void PNGAPI
+png_set_text_compression_window_bits(png_structrp png_ptr, int window_bits)
+{
+   if (png_ptr == NULL)
+      return;
+
+   if (window_bits > 15)
+   {
+      png_warning(png_ptr, "Only compression windows <= 32k supported by PNG");
+      window_bits = 15;
+   }
+
+   else if (window_bits < 8)
+   {
+      png_warning(png_ptr, "Only compression windows >= 256 supported by PNG");
+      window_bits = 8;
+   }
+
+   png_ptr->zlib_text_window_bits = window_bits;
+}
+
+void PNGAPI
+png_set_text_compression_method(png_structrp png_ptr, int method)
+{
+   png_debug(1, "in png_set_text_compression_method");
+
+   if (png_ptr == NULL)
+      return;
+
+   if (method != 8)
+      png_warning(png_ptr, "Only compression method 8 is supported by PNG");
+
+   png_ptr->zlib_text_method = method;
+}
+#endif /* WRITE_CUSTOMIZE_ZTXT_COMPRESSION */
+/* end of API added to libpng-1.5.4 */
+
+void PNGAPI
+png_set_write_status_fn(png_structrp png_ptr, png_write_status_ptr write_row_fn)
+{
+   if (png_ptr == NULL)
+      return;
+
+   png_ptr->write_row_fn = write_row_fn;
+}
+
+#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
+void PNGAPI
+png_set_write_user_transform_fn(png_structrp png_ptr, png_user_transform_ptr
+    write_user_transform_fn)
+{
+   png_debug(1, "in png_set_write_user_transform_fn");
+
+   if (png_ptr == NULL)
+      return;
+
+   png_ptr->transformations |= PNG_USER_TRANSFORM;
+   png_ptr->write_user_transform_fn = write_user_transform_fn;
+}
+#endif
+
+
+#ifdef PNG_INFO_IMAGE_SUPPORTED
+void PNGAPI
+png_write_png(png_structrp png_ptr, png_inforp info_ptr,
+    int transforms, voidp params)
+{
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   if ((info_ptr->valid & PNG_INFO_IDAT) == 0)
+   {
+      png_app_error(png_ptr, "no rows for png_write_image to write");
+      return;
+   }
+
+   /* Write the file header information. */
+   png_write_info(png_ptr, info_ptr);
+
+   /* ------ these transformations don't touch the info structure ------- */
+
+   /* Invert monochrome pixels */
+   if ((transforms & PNG_TRANSFORM_INVERT_MONO) != 0)
+#ifdef PNG_WRITE_INVERT_SUPPORTED
+      png_set_invert_mono(png_ptr);
+#else
+      png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_MONO not supported");
+#endif
+
+   /* Shift the pixels up to a legal bit depth and fill in
+    * as appropriate to correctly scale the image.
+    */
+   if ((transforms & PNG_TRANSFORM_SHIFT) != 0)
+#ifdef PNG_WRITE_SHIFT_SUPPORTED
+      if ((info_ptr->valid & PNG_INFO_sBIT) != 0)
+         png_set_shift(png_ptr, &info_ptr->sig_bit);
+#else
+      png_app_error(png_ptr, "PNG_TRANSFORM_SHIFT not supported");
+#endif
+
+   /* Pack pixels into bytes */
+   if ((transforms & PNG_TRANSFORM_PACKING) != 0)
+#ifdef PNG_WRITE_PACK_SUPPORTED
+      png_set_packing(png_ptr);
+#else
+      png_app_error(png_ptr, "PNG_TRANSFORM_PACKING not supported");
+#endif
+
+   /* Swap location of alpha bytes from ARGB to RGBA */
+   if ((transforms & PNG_TRANSFORM_SWAP_ALPHA) != 0)
+#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
+      png_set_swap_alpha(png_ptr);
+#else
+      png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ALPHA not supported");
+#endif
+
+   /* Remove a filler (X) from XRGB/RGBX/AG/GA into to convert it into
+    * RGB, note that the code expects the input color type to be G or RGB; no
+    * alpha channel.
+    */
+   if ((transforms & (PNG_TRANSFORM_STRIP_FILLER_AFTER|
+      PNG_TRANSFORM_STRIP_FILLER_BEFORE)) != 0)
+   {
+#ifdef PNG_WRITE_FILLER_SUPPORTED
+      if ((transforms & PNG_TRANSFORM_STRIP_FILLER_AFTER) != 0)
+      {
+         if ((transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE) != 0)
+            png_app_error(png_ptr,
+               "PNG_TRANSFORM_STRIP_FILLER: BEFORE+AFTER not supported");
+
+         /* Continue if ignored - this is the pre-1.6.10 behavior */
+         png_set_filler(png_ptr, 0, PNG_FILLER_AFTER);
+      }
+
+      else if ((transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE) != 0)
+         png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
+#else
+      png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_FILLER not supported");
+#endif
+   }
+
+   /* Flip BGR pixels to RGB */
+   if ((transforms & PNG_TRANSFORM_BGR) != 0)
+#ifdef PNG_WRITE_BGR_SUPPORTED
+      png_set_bgr(png_ptr);
+#else
+      png_app_error(png_ptr, "PNG_TRANSFORM_BGR not supported");
+#endif
+
+   /* Swap bytes of 16-bit files to most significant byte first */
+   if ((transforms & PNG_TRANSFORM_SWAP_ENDIAN) != 0)
+#ifdef PNG_WRITE_SWAP_SUPPORTED
+      png_set_swap(png_ptr);
+#else
+      png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ENDIAN not supported");
+#endif
+
+   /* Swap bits of 1, 2, 4 bit packed pixel formats */
+   if ((transforms & PNG_TRANSFORM_PACKSWAP) != 0)
+#ifdef PNG_WRITE_PACKSWAP_SUPPORTED
+      png_set_packswap(png_ptr);
+#else
+      png_app_error(png_ptr, "PNG_TRANSFORM_PACKSWAP not supported");
+#endif
+
+   /* Invert the alpha channel from opacity to transparency */
+   if ((transforms & PNG_TRANSFORM_INVERT_ALPHA) != 0)
+#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
+      png_set_invert_alpha(png_ptr);
+#else
+      png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_ALPHA not supported");
+#endif
+
+   /* ----------------------- end of transformations ------------------- */
+
+   /* Write the bits */
+   png_write_image(png_ptr, info_ptr->row_pointers);
+
+   /* It is REQUIRED to call this to finish writing the rest of the file */
+   png_write_end(png_ptr, info_ptr);
+
+   PNG_UNUSED(params)
+}
+#endif
+
+
+#ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED
+#ifdef PNG_STDIO_SUPPORTED /* currently required for png_image_write_* */
+/* Initialize the write structure - general purpose utility. */
+static int
+png_image_write_init(png_imagep image)
+{
+   png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, image,
+          png_safe_error, png_safe_warning);
+
+   if (png_ptr != NULL)
+   {
+      png_infop info_ptr = png_create_info_struct(png_ptr);
+
+      if (info_ptr != NULL)
+      {
+         png_controlp control = png_voidcast(png_controlp,
+            png_malloc_warn(png_ptr, (sizeof *control)));
+
+         if (control != NULL)
+         {
+            memset(control, 0, (sizeof *control));
+
+            control->png_ptr = png_ptr;
+            control->info_ptr = info_ptr;
+            control->for_write = 1;
+
+            image->opaque = control;
+            return 1;
+         }
+
+         /* Error clean up */
+         png_destroy_info_struct(png_ptr, &info_ptr);
+      }
+
+      png_destroy_write_struct(&png_ptr, NULL);
+   }
+
+   return png_image_error(image, "png_image_write_: out of memory");
+}
+
+/* Arguments to png_image_write_main: */
+typedef struct
+{
+   /* Arguments: */
+   png_imagep      image;
+   png_const_voidp buffer;
+   png_int_32      row_stride;
+   png_const_voidp colormap;
+   int             convert_to_8bit;
+   /* Local variables: */
+   png_const_voidp first_row;
+   ptrdiff_t       row_bytes;
+   png_voidp       local_row;
+} png_image_write_control;
+
+/* Write png_uint_16 input to a 16-bit PNG; the png_ptr has already been set to
+ * do any necessary byte swapping.  The component order is defined by the
+ * png_image format value.
+ */
+static int
+png_write_image_16bit(png_voidp argument)
+{
+   png_image_write_control *display = png_voidcast(png_image_write_control*,
+      argument);
+   png_imagep image = display->image;
+   png_structrp png_ptr = image->opaque->png_ptr;
+
+   png_const_uint_16p input_row = png_voidcast(png_const_uint_16p,
+      display->first_row);
+   png_uint_16p output_row = png_voidcast(png_uint_16p, display->local_row);
+   png_uint_16p row_end;
+   const int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1;
+   int aindex = 0;
+   png_uint_32 y = image->height;
+
+   if ((image->format & PNG_FORMAT_FLAG_ALPHA) != 0)
+   {
+#     ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
+         if ((image->format & PNG_FORMAT_FLAG_AFIRST) != 0)
+         {
+            aindex = -1;
+            ++input_row; /* To point to the first component */
+            ++output_row;
+         }
+
+         else
+#     endif
+         aindex = channels;
+   }
+
+   else
+      png_error(png_ptr, "png_write_image: internal call error");
+
+   /* Work out the output row end and count over this, note that the increment
+    * above to 'row' means that row_end can actually be beyond the end of the
+    * row; this is correct.
+    */
+   row_end = output_row + image->width * (channels+1);
+
+   while (y-- > 0)
+   {
+      png_const_uint_16p in_ptr = input_row;
+      png_uint_16p out_ptr = output_row;
+
+      while (out_ptr < row_end)
+      {
+         const png_uint_16 alpha = in_ptr[aindex];
+         png_uint_32 reciprocal = 0;
+         int c;
+
+         out_ptr[aindex] = alpha;
+
+         /* Calculate a reciprocal.  The correct calculation is simply
+          * component/alpha*65535 << 15. (I.e. 15 bits of precision); this
+          * allows correct rounding by adding .5 before the shift.  'reciprocal'
+          * is only initialized when required.
+          */
+         if (alpha > 0 && alpha < 65535)
+            reciprocal = ((0xffff<<15)+(alpha>>1))/alpha;
+
+         c = channels;
+         do /* always at least one channel */
+         {
+            png_uint_16 component = *in_ptr++;
+
+            /* The following gives 65535 for an alpha of 0, which is fine,
+             * otherwise if 0/0 is represented as some other value there is more
+             * likely to be a discontinuity which will probably damage
+             * compression when moving from a fully transparent area to a
+             * nearly transparent one.  (The assumption here is that opaque
+             * areas tend not to be 0 intensity.)
+             */
+            if (component >= alpha)
+               component = 65535;
+
+            /* component<alpha, so component/alpha is less than one and
+             * component*reciprocal is less than 2^31.
+             */
+            else if (component > 0 && alpha < 65535)
+            {
+               png_uint_32 calc = component * reciprocal;
+               calc += 16384; /* round to nearest */
+               component = (png_uint_16)(calc >> 15);
+            }
+
+            *out_ptr++ = component;
+         }
+         while (--c > 0);
+
+         /* Skip to next component (skip the intervening alpha channel) */
+         ++in_ptr;
+         ++out_ptr;
+      }
+
+      png_write_row(png_ptr, png_voidcast(png_const_bytep, display->local_row));
+      input_row += display->row_bytes/(sizeof (png_uint_16));
+   }
+
+   return 1;
+}
+
+/* Given 16-bit input (1 to 4 channels) write 8-bit output.  If an alpha channel
+ * is present it must be removed from the components, the components are then
+ * written in sRGB encoding.  No components are added or removed.
+ *
+ * Calculate an alpha reciprocal to reverse pre-multiplication.  As above the
+ * calculation can be done to 15 bits of accuracy; however, the output needs to
+ * be scaled in the range 0..255*65535, so include that scaling here.
+ */
+#define UNP_RECIPROCAL(alpha) ((((0xffff*0xff)<<7)+(alpha>>1))/alpha)
+
+static png_byte
+png_unpremultiply(png_uint_32 component, png_uint_32 alpha,
+   png_uint_32 reciprocal/*from the above macro*/)
+{
+   /* The following gives 1.0 for an alpha of 0, which is fine, otherwise if 0/0
+    * is represented as some other value there is more likely to be a
+    * discontinuity which will probably damage compression when moving from a
+    * fully transparent area to a nearly transparent one.  (The assumption here
+    * is that opaque areas tend not to be 0 intensity.)
+    *
+    * There is a rounding problem here; if alpha is less than 128 it will end up
+    * as 0 when scaled to 8 bits.  To avoid introducing spurious colors into the
+    * output change for this too.
+    */
+   if (component >= alpha || alpha < 128)
+      return 255;
+
+   /* component<alpha, so component/alpha is less than one and
+    * component*reciprocal is less than 2^31.
+    */
+   else if (component > 0)
+   {
+      /* The test is that alpha/257 (rounded) is less than 255, the first value
+       * that becomes 255 is 65407.
+       * NOTE: this must agree with the PNG_DIV257 macro (which must, therefore,
+       * be exact!)  [Could also test reciprocal != 0]
+       */
+      if (alpha < 65407)
+      {
+         component *= reciprocal;
+         component += 64; /* round to nearest */
+         component >>= 7;
+      }
+
+      else
+         component *= 255;
+
+      /* Convert the component to sRGB. */
+      return (png_byte)PNG_sRGB_FROM_LINEAR(component);
+   }
+
+   else
+      return 0;
+}
+
+static int
+png_write_image_8bit(png_voidp argument)
+{
+   png_image_write_control *display = png_voidcast(png_image_write_control*,
+      argument);
+   png_imagep image = display->image;
+   png_structrp png_ptr = image->opaque->png_ptr;
+
+   png_const_uint_16p input_row = png_voidcast(png_const_uint_16p,
+      display->first_row);
+   png_bytep output_row = png_voidcast(png_bytep, display->local_row);
+   png_uint_32 y = image->height;
+   const int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1;
+
+   if ((image->format & PNG_FORMAT_FLAG_ALPHA) != 0)
+   {
+      png_bytep row_end;
+      int aindex;
+
+#     ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
+         if ((image->format & PNG_FORMAT_FLAG_AFIRST) != 0)
+         {
+            aindex = -1;
+            ++input_row; /* To point to the first component */
+            ++output_row;
+         }
+
+         else
+#     endif
+         aindex = channels;
+
+      /* Use row_end in place of a loop counter: */
+      row_end = output_row + image->width * (channels+1);
+
+      while (y-- > 0)
+      {
+         png_const_uint_16p in_ptr = input_row;
+         png_bytep out_ptr = output_row;
+
+         while (out_ptr < row_end)
+         {
+            png_uint_16 alpha = in_ptr[aindex];
+            png_byte alphabyte = (png_byte)PNG_DIV257(alpha);
+            png_uint_32 reciprocal = 0;
+            int c;
+
+            /* Scale and write the alpha channel. */
+            out_ptr[aindex] = alphabyte;
+
+            if (alphabyte > 0 && alphabyte < 255)
+               reciprocal = UNP_RECIPROCAL(alpha);
+
+            c = channels;
+            do /* always at least one channel */
+               *out_ptr++ = png_unpremultiply(*in_ptr++, alpha, reciprocal);
+            while (--c > 0);
+
+            /* Skip to next component (skip the intervening alpha channel) */
+            ++in_ptr;
+            ++out_ptr;
+         } /* while out_ptr < row_end */
+
+         png_write_row(png_ptr, png_voidcast(png_const_bytep,
+            display->local_row));
+         input_row += display->row_bytes/(sizeof (png_uint_16));
+      } /* while y */
+   }
+
+   else
+   {
+      /* No alpha channel, so the row_end really is the end of the row and it
+       * is sufficient to loop over the components one by one.
+       */
+      png_bytep row_end = output_row + image->width * channels;
+
+      while (y-- > 0)
+      {
+         png_const_uint_16p in_ptr = input_row;
+         png_bytep out_ptr = output_row;
+
+         while (out_ptr < row_end)
+         {
+            png_uint_32 component = *in_ptr++;
+
+            component *= 255;
+            *out_ptr++ = (png_byte)PNG_sRGB_FROM_LINEAR(component);
+         }
+
+         png_write_row(png_ptr, output_row);
+         input_row += display->row_bytes/(sizeof (png_uint_16));
+      }
+   }
+
+   return 1;
+}
+
+static void
+png_image_set_PLTE(png_image_write_control *display)
+{
+   const png_imagep image = display->image;
+   const void *cmap = display->colormap;
+   const int entries = image->colormap_entries > 256 ? 256 :
+      (int)image->colormap_entries;
+
+   /* NOTE: the caller must check for cmap != NULL and entries != 0 */
+   const png_uint_32 format = image->format;
+   const int channels = PNG_IMAGE_SAMPLE_CHANNELS(format);
+
+#  if defined(PNG_FORMAT_BGR_SUPPORTED) &&\
+      defined(PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED)
+      const int afirst = (format & PNG_FORMAT_FLAG_AFIRST) != 0 &&
+         (format & PNG_FORMAT_FLAG_ALPHA) != 0;
+#  else
+#     define afirst 0
+#  endif
+
+#  ifdef PNG_FORMAT_BGR_SUPPORTED
+      const int bgr = (format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0;
+#  else
+#     define bgr 0
+#  endif
+
+   int i, num_trans;
+   png_color palette[256];
+   png_byte tRNS[256];
+
+   memset(tRNS, 255, (sizeof tRNS));
+   memset(palette, 0, (sizeof palette));
+
+   for (i=num_trans=0; i<entries; ++i)
+   {
+      /* This gets automatically converted to sRGB with reversal of the
+       * pre-multiplication if the color-map has an alpha channel.
+       */
+      if ((format & PNG_FORMAT_FLAG_LINEAR) != 0)
+      {
+         png_const_uint_16p entry = png_voidcast(png_const_uint_16p, cmap);
+
+         entry += i * channels;
+
+         if ((channels & 1) != 0) /* no alpha */
+         {
+            if (channels >= 3) /* RGB */
+            {
+               palette[i].blue = (png_byte)PNG_sRGB_FROM_LINEAR(255 *
+                  entry[(2 ^ bgr)]);
+               palette[i].green = (png_byte)PNG_sRGB_FROM_LINEAR(255 *
+                  entry[1]);
+               palette[i].red = (png_byte)PNG_sRGB_FROM_LINEAR(255 *
+                  entry[bgr]);
+            }
+
+            else /* Gray */
+               palette[i].blue = palette[i].red = palette[i].green =
+                  (png_byte)PNG_sRGB_FROM_LINEAR(255 * *entry);
+         }
+
+         else /* alpha */
+         {
+            png_uint_16 alpha = entry[afirst ? 0 : channels-1];
+            png_byte alphabyte = (png_byte)PNG_DIV257(alpha);
+            png_uint_32 reciprocal = 0;
+
+            /* Calculate a reciprocal, as in the png_write_image_8bit code above
+             * this is designed to produce a value scaled to 255*65535 when
+             * divided by 128 (i.e. asr 7).
+             */
+            if (alphabyte > 0 && alphabyte < 255)
+               reciprocal = (((0xffff*0xff)<<7)+(alpha>>1))/alpha;
+
+            tRNS[i] = alphabyte;
+            if (alphabyte < 255)
+               num_trans = i+1;
+
+            if (channels >= 3) /* RGB */
+            {
+               palette[i].blue = png_unpremultiply(entry[afirst + (2 ^ bgr)],
+                  alpha, reciprocal);
+               palette[i].green = png_unpremultiply(entry[afirst + 1], alpha,
+                  reciprocal);
+               palette[i].red = png_unpremultiply(entry[afirst + bgr], alpha,
+                  reciprocal);
+            }
+
+            else /* gray */
+               palette[i].blue = palette[i].red = palette[i].green =
+                  png_unpremultiply(entry[afirst], alpha, reciprocal);
+         }
+      }
+
+      else /* Color-map has sRGB values */
+      {
+         png_const_bytep entry = png_voidcast(png_const_bytep, cmap);
+
+         entry += i * channels;
+
+         switch (channels)
+         {
+            case 4:
+               tRNS[i] = entry[afirst ? 0 : 3];
+               if (tRNS[i] < 255)
+                  num_trans = i+1;
+               /* FALL THROUGH */
+            case 3:
+               palette[i].blue = entry[afirst + (2 ^ bgr)];
+               palette[i].green = entry[afirst + 1];
+               palette[i].red = entry[afirst + bgr];
+               break;
+
+            case 2:
+               tRNS[i] = entry[1 ^ afirst];
+               if (tRNS[i] < 255)
+                  num_trans = i+1;
+               /* FALL THROUGH */
+            case 1:
+               palette[i].blue = palette[i].red = palette[i].green =
+                  entry[afirst];
+               break;
+
+            default:
+               break;
+         }
+      }
+   }
+
+#  ifdef afirst
+#     undef afirst
+#  endif
+#  ifdef bgr
+#     undef bgr
+#  endif
+
+   png_set_PLTE(image->opaque->png_ptr, image->opaque->info_ptr, palette,
+      entries);
+
+   if (num_trans > 0)
+      png_set_tRNS(image->opaque->png_ptr, image->opaque->info_ptr, tRNS,
+         num_trans, NULL);
+
+   image->colormap_entries = entries;
+}
+
+static int
+png_image_write_main(png_voidp argument)
+{
+   png_image_write_control *display = png_voidcast(png_image_write_control*,
+      argument);
+   png_imagep image = display->image;
+   png_structrp png_ptr = image->opaque->png_ptr;
+   png_inforp info_ptr = image->opaque->info_ptr;
+   png_uint_32 format = image->format;
+
+   /* The following four ints are actually booleans */
+   int colormap = (format & PNG_FORMAT_FLAG_COLORMAP);
+   int linear = !colormap && (format & PNG_FORMAT_FLAG_LINEAR); /* input */
+   int alpha = !colormap && (format & PNG_FORMAT_FLAG_ALPHA);
+   int write_16bit = linear && !colormap && (display->convert_to_8bit == 0);
+
+#  ifdef PNG_BENIGN_ERRORS_SUPPORTED
+      /* Make sure we error out on any bad situation */
+      png_set_benign_errors(png_ptr, 0/*error*/);
+#  endif
+
+   /* Default the 'row_stride' parameter if required. */
+   if (display->row_stride == 0)
+      display->row_stride = PNG_IMAGE_ROW_STRIDE(*image);
+
+   /* Set the required transforms then write the rows in the correct order. */
+   if ((format & PNG_FORMAT_FLAG_COLORMAP) != 0)
+   {
+      if (display->colormap != NULL && image->colormap_entries > 0)
+      {
+         png_uint_32 entries = image->colormap_entries;
+
+         png_set_IHDR(png_ptr, info_ptr, image->width, image->height,
+            entries > 16 ? 8 : (entries > 4 ? 4 : (entries > 2 ? 2 : 1)),
+            PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE,
+            PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+
+         png_image_set_PLTE(display);
+      }
+
+      else
+         png_error(image->opaque->png_ptr,
+            "no color-map for color-mapped image");
+   }
+
+   else
+      png_set_IHDR(png_ptr, info_ptr, image->width, image->height,
+         write_16bit ? 16 : 8,
+         ((format & PNG_FORMAT_FLAG_COLOR) ? PNG_COLOR_MASK_COLOR : 0) +
+         ((format & PNG_FORMAT_FLAG_ALPHA) ? PNG_COLOR_MASK_ALPHA : 0),
+         PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+
+   /* Counter-intuitively the data transformations must be called *after*
+    * png_write_info, not before as in the read code, but the 'set' functions
+    * must still be called before.  Just set the color space information, never
+    * write an interlaced image.
+    */
+
+   if (write_16bit != 0)
+   {
+      /* The gamma here is 1.0 (linear) and the cHRM chunk matches sRGB. */
+      png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_LINEAR);
+
+      if ((image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB) == 0)
+         png_set_cHRM_fixed(png_ptr, info_ptr,
+            /* color      x       y */
+            /* white */ 31270, 32900,
+            /* red   */ 64000, 33000,
+            /* green */ 30000, 60000,
+            /* blue  */ 15000,  6000
+         );
+   }
+
+   else if ((image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB) == 0)
+      png_set_sRGB(png_ptr, info_ptr, PNG_sRGB_INTENT_PERCEPTUAL);
+
+   /* Else writing an 8-bit file and the *colors* aren't sRGB, but the 8-bit
+    * space must still be gamma encoded.
+    */
+   else
+      png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_sRGB_INVERSE);
+
+   /* Write the file header. */
+   png_write_info(png_ptr, info_ptr);
+
+   /* Now set up the data transformations (*after* the header is written),
+    * remove the handled transformations from the 'format' flags for checking.
+    *
+    * First check for a little endian system if writing 16 bit files.
+    */
+   if (write_16bit != 0)
+   {
+      PNG_CONST png_uint_16 le = 0x0001;
+
+      if ((*(png_const_bytep) & le) != 0)
+         png_set_swap(png_ptr);
+   }
+
+#  ifdef PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED
+      if ((format & PNG_FORMAT_FLAG_BGR) != 0)
+      {
+         if (colormap == 0 && (format & PNG_FORMAT_FLAG_COLOR) != 0)
+            png_set_bgr(png_ptr);
+         format &= ~PNG_FORMAT_FLAG_BGR;
+      }
+#  endif
+
+#  ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
+      if ((format & PNG_FORMAT_FLAG_AFIRST) != 0)
+      {
+         if (colormap == 0 && (format & PNG_FORMAT_FLAG_ALPHA) != 0)
+            png_set_swap_alpha(png_ptr);
+         format &= ~PNG_FORMAT_FLAG_AFIRST;
+      }
+#  endif
+
+   /* If there are 16 or fewer color-map entries we wrote a lower bit depth
+    * above, but the application data is still byte packed.
+    */
+   if (colormap != 0 && image->colormap_entries <= 16)
+      png_set_packing(png_ptr);
+
+   /* That should have handled all (both) the transforms. */
+   if ((format & ~(png_uint_32)(PNG_FORMAT_FLAG_COLOR | PNG_FORMAT_FLAG_LINEAR |
+         PNG_FORMAT_FLAG_ALPHA | PNG_FORMAT_FLAG_COLORMAP)) != 0)
+      png_error(png_ptr, "png_write_image: unsupported transformation");
+
+   {
+      png_const_bytep row = png_voidcast(png_const_bytep, display->buffer);
+      ptrdiff_t row_bytes = display->row_stride;
+
+      if (linear != 0)
+         row_bytes *= (sizeof (png_uint_16));
+
+      if (row_bytes < 0)
+         row += (image->height-1) * (-row_bytes);
+
+      display->first_row = row;
+      display->row_bytes = row_bytes;
+   }
+
+   /* Apply 'fast' options if the flag is set. */
+   if ((image->flags & PNG_IMAGE_FLAG_FAST) != 0)
+   {
+      png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, PNG_NO_FILTERS);
+      /* NOTE: determined by experiment using pngstest, this reflects some
+       * balance between the time to write the image once and the time to read
+       * it about 50 times.  The speed-up in pngstest was about 10-20% of the
+       * total (user) time on a heavily loaded system.
+       */
+      png_set_compression_level(png_ptr, 3);
+   }
+
+   /* Check for the cases that currently require a pre-transform on the row
+    * before it is written.  This only applies when the input is 16-bit and
+    * either there is an alpha channel or it is converted to 8-bit.
+    */
+   if ((linear != 0 && alpha != 0 ) ||
+       (colormap == 0 && display->convert_to_8bit != 0))
+   {
+      png_bytep row = png_voidcast(png_bytep, png_malloc(png_ptr,
+         png_get_rowbytes(png_ptr, info_ptr)));
+      int result;
+
+      display->local_row = row;
+      if (write_16bit != 0)
+         result = png_safe_execute(image, png_write_image_16bit, display);
+      else
+         result = png_safe_execute(image, png_write_image_8bit, display);
+      display->local_row = NULL;
+
+      png_free(png_ptr, row);
+
+      /* Skip the 'write_end' on error: */
+      if (result == 0)
+         return 0;
+   }
+
+   /* Otherwise this is the case where the input is in a format currently
+    * supported by the rest of the libpng write code; call it directly.
+    */
+   else
+   {
+      png_const_bytep row = png_voidcast(png_const_bytep, display->first_row);
+      ptrdiff_t row_bytes = display->row_bytes;
+      png_uint_32 y = image->height;
+
+      while (y-- > 0)
+      {
+         png_write_row(png_ptr, row);
+         row += row_bytes;
+      }
+   }
+
+   png_write_end(png_ptr, info_ptr);
+   return 1;
+}
+
+int PNGAPI
+png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8bit,
+   const void *buffer, png_int_32 row_stride, const void *colormap)
+{
+   /* Write the image to the given (FILE*). */
+   if (image != NULL && image->version == PNG_IMAGE_VERSION)
+   {
+      if (file != NULL)
+      {
+         if (png_image_write_init(image) != 0)
+         {
+            png_image_write_control display;
+            int result;
+
+            /* This is slightly evil, but png_init_io doesn't do anything other
+             * than this and we haven't changed the standard IO functions so
+             * this saves a 'safe' function.
+             */
+            image->opaque->png_ptr->io_ptr = file;
+
+            memset(&display, 0, (sizeof display));
+            display.image = image;
+            display.buffer = buffer;
+            display.row_stride = row_stride;
+            display.colormap = colormap;
+            display.convert_to_8bit = convert_to_8bit;
+
+            result = png_safe_execute(image, png_image_write_main, &display);
+            png_image_free(image);
+            return result;
+         }
+
+         else
+            return 0;
+      }
+
+      else
+         return png_image_error(image,
+            "png_image_write_to_stdio: invalid argument");
+   }
+
+   else if (image != NULL)
+      return png_image_error(image,
+         "png_image_write_to_stdio: incorrect PNG_IMAGE_VERSION");
+
+   else
+      return 0;
+}
+
+int PNGAPI
+png_image_write_to_file(png_imagep image, const char *file_name,
+   int convert_to_8bit, const void *buffer, png_int_32 row_stride,
+   const void *colormap)
+{
+   /* Write the image to the named file. */
+   if (image != NULL && image->version == PNG_IMAGE_VERSION)
+   {
+      if (file_name != NULL)
+      {
+         FILE *fp = fopen(file_name, "wb");
+
+         if (fp != NULL)
+         {
+            if (png_image_write_to_stdio(image, fp, convert_to_8bit, buffer,
+               row_stride, colormap) != 0)
+            {
+               int error; /* from fflush/fclose */
+
+               /* Make sure the file is flushed correctly. */
+               if (fflush(fp) == 0 && ferror(fp) == 0)
+               {
+                  if (fclose(fp) == 0)
+                     return 1;
+
+                  error = errno; /* from fclose */
+               }
+
+               else
+               {
+                  error = errno; /* from fflush or ferror */
+                  (void)fclose(fp);
+               }
+
+               (void)remove(file_name);
+               /* The image has already been cleaned up; this is just used to
+                * set the error (because the original write succeeded).
+                */
+               return png_image_error(image, strerror(error));
+            }
+
+            else
+            {
+               /* Clean up: just the opened file. */
+               (void)fclose(fp);
+               (void)remove(file_name);
+               return 0;
+            }
+         }
+
+         else
+            return png_image_error(image, strerror(errno));
+      }
+
+      else
+         return png_image_error(image,
+            "png_image_write_to_file: invalid argument");
+   }
+
+   else if (image != NULL)
+      return png_image_error(image,
+         "png_image_write_to_file: incorrect PNG_IMAGE_VERSION");
+
+   else
+      return 0;
+}
+#endif /* STDIO */
+#endif /* SIMPLIFIED_WRITE */
+#endif /* WRITE */
diff --git a/Source/LibPNG/pngwtran.c b/Source/LibPNG/pngwtran.c
index e962b68..09562a7 100644
--- a/Source/LibPNG/pngwtran.c
+++ b/Source/LibPNG/pngwtran.c
@@ -1,645 +1,574 @@
-
-/* pngwtran.c - transforms the data in a row for PNG writers
- *
- * Last changed in libpng 1.5.13 [September 27, 2012]
- * Copyright (c) 1998-2012 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- */
-
-#include "pngpriv.h"
-
-#ifdef PNG_WRITE_SUPPORTED
-
-#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
-/* Transform the data according to the user's wishes.  The order of
- * transformations is significant.
- */
-void /* PRIVATE */
-png_do_write_transformations(png_structp png_ptr, png_row_infop row_info)
-{
-   png_debug(1, "in png_do_write_transformations");
-
-   if (png_ptr == NULL)
-      return;
-
-#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
-   if (png_ptr->transformations & PNG_USER_TRANSFORM)
-      if (png_ptr->write_user_transform_fn != NULL)
-         (*(png_ptr->write_user_transform_fn)) /* User write transform
-                                                 function */
-             (png_ptr,  /* png_ptr */
-             row_info,  /* row_info: */
-                /*  png_uint_32 width;       width of row */
-                /*  png_size_t rowbytes;     number of bytes in row */
-                /*  png_byte color_type;     color type of pixels */
-                /*  png_byte bit_depth;      bit depth of samples */
-                /*  png_byte channels;       number of channels (1-4) */
-                /*  png_byte pixel_depth;    bits per pixel (depth*channels) */
-             png_ptr->row_buf + 1);      /* start of pixel data for row */
-#endif
-
-#ifdef PNG_WRITE_FILLER_SUPPORTED
-   if (png_ptr->transformations & PNG_FILLER)
-   {
-      if (png_ptr->color_type & (PNG_COLOR_MASK_ALPHA|PNG_COLOR_MASK_PALETTE))
-      {
-         /* GA, RGBA or palette; in any of these cases libpng will not do the
-          * the correct thing (whatever that might be).
-          */
-         png_warning(png_ptr, "incorrect png_set_filler call ignored");
-         png_ptr->transformations &= ~PNG_FILLER;
-      }
-
-      else
-         png_do_strip_channel(row_info, png_ptr->row_buf + 1,
-            !(png_ptr->flags & PNG_FLAG_FILLER_AFTER));
-   }
-#endif
-
-#ifdef PNG_WRITE_PACKSWAP_SUPPORTED
-   if (png_ptr->transformations & PNG_PACKSWAP)
-      png_do_packswap(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_WRITE_PACK_SUPPORTED
-   if (png_ptr->transformations & PNG_PACK)
-      png_do_pack(row_info, png_ptr->row_buf + 1,
-          (png_uint_32)png_ptr->bit_depth);
-#endif
-
-#ifdef PNG_WRITE_SWAP_SUPPORTED
-   if (png_ptr->transformations & PNG_SWAP_BYTES)
-      png_do_swap(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_WRITE_SHIFT_SUPPORTED
-   if (png_ptr->transformations & PNG_SHIFT)
-      png_do_shift(row_info, png_ptr->row_buf + 1,
-          &(png_ptr->shift));
-#endif
-
-#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
-   if (png_ptr->transformations & PNG_SWAP_ALPHA)
-      png_do_write_swap_alpha(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
-   if (png_ptr->transformations & PNG_INVERT_ALPHA)
-      png_do_write_invert_alpha(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_WRITE_BGR_SUPPORTED
-   if (png_ptr->transformations & PNG_BGR)
-      png_do_bgr(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_WRITE_INVERT_SUPPORTED
-   if (png_ptr->transformations & PNG_INVERT_MONO)
-      png_do_invert(row_info, png_ptr->row_buf + 1);
-#endif
-}
-
-#ifdef PNG_WRITE_PACK_SUPPORTED
-/* Pack pixels into bytes.  Pass the true bit depth in bit_depth.  The
- * row_info bit depth should be 8 (one pixel per byte).  The channels
- * should be 1 (this only happens on grayscale and paletted images).
- */
-void /* PRIVATE */
-png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
-{
-   png_debug(1, "in png_do_pack");
-
-   if (row_info->bit_depth == 8 &&
-      row_info->channels == 1)
-   {
-      switch ((int)bit_depth)
-      {
-         case 1:
-         {
-            png_bytep sp, dp;
-            int mask, v;
-            png_uint_32 i;
-            png_uint_32 row_width = row_info->width;
-
-            sp = row;
-            dp = row;
-            mask = 0x80;
-            v = 0;
-
-            for (i = 0; i < row_width; i++)
-            {
-               if (*sp != 0)
-                  v |= mask;
-
-               sp++;
-
-               if (mask > 1)
-                  mask >>= 1;
-
-               else
-               {
-                  mask = 0x80;
-                  *dp = (png_byte)v;
-                  dp++;
-                  v = 0;
-               }
-            }
-
-            if (mask != 0x80)
-               *dp = (png_byte)v;
-
-            break;
-         }
-
-         case 2:
-         {
-            png_bytep sp, dp;
-            int shift, v;
-            png_uint_32 i;
-            png_uint_32 row_width = row_info->width;
-
-            sp = row;
-            dp = row;
-            shift = 6;
-            v = 0;
-
-            for (i = 0; i < row_width; i++)
-            {
-               png_byte value;
-
-               value = (png_byte)(*sp & 0x03);
-               v |= (value << shift);
-
-               if (shift == 0)
-               {
-                  shift = 6;
-                  *dp = (png_byte)v;
-                  dp++;
-                  v = 0;
-               }
-
-               else
-                  shift -= 2;
-
-               sp++;
-            }
-
-            if (shift != 6)
-               *dp = (png_byte)v;
-
-            break;
-         }
-
-         case 4:
-         {
-            png_bytep sp, dp;
-            int shift, v;
-            png_uint_32 i;
-            png_uint_32 row_width = row_info->width;
-
-            sp = row;
-            dp = row;
-            shift = 4;
-            v = 0;
-
-            for (i = 0; i < row_width; i++)
-            {
-               png_byte value;
-
-               value = (png_byte)(*sp & 0x0f);
-               v |= (value << shift);
-
-               if (shift == 0)
-               {
-                  shift = 4;
-                  *dp = (png_byte)v;
-                  dp++;
-                  v = 0;
-               }
-
-               else
-                  shift -= 4;
-
-               sp++;
-            }
-
-            if (shift != 4)
-               *dp = (png_byte)v;
-
-            break;
-         }
-
-         default:
-            break;
-      }
-
-      row_info->bit_depth = (png_byte)bit_depth;
-      row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels);
-      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
-          row_info->width);
-   }
-}
-#endif
-
-#ifdef PNG_WRITE_SHIFT_SUPPORTED
-/* Shift pixel values to take advantage of whole range.  Pass the
- * true number of bits in bit_depth.  The row should be packed
- * according to row_info->bit_depth.  Thus, if you had a row of
- * bit depth 4, but the pixels only had values from 0 to 7, you
- * would pass 3 as bit_depth, and this routine would translate the
- * data to 0 to 15.
- */
-void /* PRIVATE */
-png_do_shift(png_row_infop row_info, png_bytep row,
-    png_const_color_8p bit_depth)
-{
-   png_debug(1, "in png_do_shift");
-
-   if (row_info->color_type != PNG_COLOR_TYPE_PALETTE)
-   {
-      int shift_start[4], shift_dec[4];
-      int channels = 0;
-
-      if (row_info->color_type & PNG_COLOR_MASK_COLOR)
-      {
-         shift_start[channels] = row_info->bit_depth - bit_depth->red;
-         shift_dec[channels] = bit_depth->red;
-         channels++;
-
-         shift_start[channels] = row_info->bit_depth - bit_depth->green;
-         shift_dec[channels] = bit_depth->green;
-         channels++;
-
-         shift_start[channels] = row_info->bit_depth - bit_depth->blue;
-         shift_dec[channels] = bit_depth->blue;
-         channels++;
-      }
-
-      else
-      {
-         shift_start[channels] = row_info->bit_depth - bit_depth->gray;
-         shift_dec[channels] = bit_depth->gray;
-         channels++;
-      }
-
-      if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
-      {
-         shift_start[channels] = row_info->bit_depth - bit_depth->alpha;
-         shift_dec[channels] = bit_depth->alpha;
-         channels++;
-      }
-
-      /* With low row depths, could only be grayscale, so one channel */
-      if (row_info->bit_depth < 8)
-      {
-         png_bytep bp = row;
-         png_size_t i;
-         png_byte mask;
-         png_size_t row_bytes = row_info->rowbytes;
-
-         if (bit_depth->gray == 1 && row_info->bit_depth == 2)
-            mask = 0x55;
-
-         else if (row_info->bit_depth == 4 && bit_depth->gray == 3)
-            mask = 0x11;
-
-         else
-            mask = 0xff;
-
-         for (i = 0; i < row_bytes; i++, bp++)
-         {
-            png_uint_16 v;
-            int j;
-
-            v = *bp;
-            *bp = 0;
-
-            for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0])
-            {
-               if (j > 0)
-                  *bp |= (png_byte)((v << j) & 0xff);
-
-               else
-                  *bp |= (png_byte)((v >> (-j)) & mask);
-            }
-         }
-      }
-
-      else if (row_info->bit_depth == 8)
-      {
-         png_bytep bp = row;
-         png_uint_32 i;
-         png_uint_32 istop = channels * row_info->width;
-
-         for (i = 0; i < istop; i++, bp++)
-         {
-
-            png_uint_16 v;
-            int j;
-            int c = (int)(i%channels);
-
-            v = *bp;
-            *bp = 0;
-
-            for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
-            {
-               if (j > 0)
-                  *bp |= (png_byte)((v << j) & 0xff);
-
-               else
-                  *bp |= (png_byte)((v >> (-j)) & 0xff);
-            }
-         }
-      }
-
-      else
-      {
-         png_bytep bp;
-         png_uint_32 i;
-         png_uint_32 istop = channels * row_info->width;
-
-         for (bp = row, i = 0; i < istop; i++)
-         {
-            int c = (int)(i%channels);
-            png_uint_16 value, v;
-            int j;
-
-            v = (png_uint_16)(((png_uint_16)(*bp) << 8) + *(bp + 1));
-            value = 0;
-
-            for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
-            {
-               if (j > 0)
-                  value |= (png_uint_16)((v << j) & (png_uint_16)0xffff);
-
-               else
-                  value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff);
-            }
-            *bp++ = (png_byte)(value >> 8);
-            *bp++ = (png_byte)(value & 0xff);
-         }
-      }
-   }
-}
-#endif
-
-#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
-void /* PRIVATE */
-png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
-{
-   png_debug(1, "in png_do_write_swap_alpha");
-
-   {
-      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
-      {
-         if (row_info->bit_depth == 8)
-         {
-            /* This converts from ARGB to RGBA */
-            png_bytep sp, dp;
-            png_uint_32 i;
-            png_uint_32 row_width = row_info->width;
-
-            for (i = 0, sp = dp = row; i < row_width; i++)
-            {
-               png_byte save = *(sp++);
-               *(dp++) = *(sp++);
-               *(dp++) = *(sp++);
-               *(dp++) = *(sp++);
-               *(dp++) = save;
-            }
-         }
-
-#ifdef PNG_WRITE_16BIT_SUPPORTED
-         else
-         {
-            /* This converts from AARRGGBB to RRGGBBAA */
-            png_bytep sp, dp;
-            png_uint_32 i;
-            png_uint_32 row_width = row_info->width;
-
-            for (i = 0, sp = dp = row; i < row_width; i++)
-            {
-               png_byte save[2];
-               save[0] = *(sp++);
-               save[1] = *(sp++);
-               *(dp++) = *(sp++);
-               *(dp++) = *(sp++);
-               *(dp++) = *(sp++);
-               *(dp++) = *(sp++);
-               *(dp++) = *(sp++);
-               *(dp++) = *(sp++);
-               *(dp++) = save[0];
-               *(dp++) = save[1];
-            }
-         }
-#endif /* PNG_WRITE_16BIT_SUPPORTED */
-      }
-
-      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
-      {
-         if (row_info->bit_depth == 8)
-         {
-            /* This converts from AG to GA */
-            png_bytep sp, dp;
-            png_uint_32 i;
-            png_uint_32 row_width = row_info->width;
-
-            for (i = 0, sp = dp = row; i < row_width; i++)
-            {
-               png_byte save = *(sp++);
-               *(dp++) = *(sp++);
-               *(dp++) = save;
-            }
-         }
-
-#ifdef PNG_WRITE_16BIT_SUPPORTED
-         else
-         {
-            /* This converts from AAGG to GGAA */
-            png_bytep sp, dp;
-            png_uint_32 i;
-            png_uint_32 row_width = row_info->width;
-
-            for (i = 0, sp = dp = row; i < row_width; i++)
-            {
-               png_byte save[2];
-               save[0] = *(sp++);
-               save[1] = *(sp++);
-               *(dp++) = *(sp++);
-               *(dp++) = *(sp++);
-               *(dp++) = save[0];
-               *(dp++) = save[1];
-            }
-         }
-#endif /* PNG_WRITE_16BIT_SUPPORTED */
-      }
-   }
-}
-#endif
-
-#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
-void /* PRIVATE */
-png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
-{
-   png_debug(1, "in png_do_write_invert_alpha");
-
-   {
-      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
-      {
-         if (row_info->bit_depth == 8)
-         {
-            /* This inverts the alpha channel in RGBA */
-            png_bytep sp, dp;
-            png_uint_32 i;
-            png_uint_32 row_width = row_info->width;
-
-            for (i = 0, sp = dp = row; i < row_width; i++)
-            {
-               /* Does nothing
-               *(dp++) = *(sp++);
-               *(dp++) = *(sp++);
-               *(dp++) = *(sp++);
-               */
-               sp+=3; dp = sp;
-               *(dp++) = (png_byte)(255 - *(sp++));
-            }
-         }
-
-#ifdef PNG_WRITE_16BIT_SUPPORTED
-         else
-         {
-            /* This inverts the alpha channel in RRGGBBAA */
-            png_bytep sp, dp;
-            png_uint_32 i;
-            png_uint_32 row_width = row_info->width;
-
-            for (i = 0, sp = dp = row; i < row_width; i++)
-            {
-               /* Does nothing
-               *(dp++) = *(sp++);
-               *(dp++) = *(sp++);
-               *(dp++) = *(sp++);
-               *(dp++) = *(sp++);
-               *(dp++) = *(sp++);
-               *(dp++) = *(sp++);
-               */
-               sp+=6; dp = sp;
-               *(dp++) = (png_byte)(255 - *(sp++));
-               *(dp++) = (png_byte)(255 - *(sp++));
-            }
-         }
-#endif /* PNG_WRITE_16BIT_SUPPORTED */
-      }
-
-      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
-      {
-         if (row_info->bit_depth == 8)
-         {
-            /* This inverts the alpha channel in GA */
-            png_bytep sp, dp;
-            png_uint_32 i;
-            png_uint_32 row_width = row_info->width;
-
-            for (i = 0, sp = dp = row; i < row_width; i++)
-            {
-               *(dp++) = *(sp++);
-               *(dp++) = (png_byte)(255 - *(sp++));
-            }
-         }
-
-#ifdef PNG_WRITE_16BIT_SUPPORTED
-         else
-         {
-            /* This inverts the alpha channel in GGAA */
-            png_bytep sp, dp;
-            png_uint_32 i;
-            png_uint_32 row_width = row_info->width;
-
-            for (i = 0, sp = dp = row; i < row_width; i++)
-            {
-               /* Does nothing
-               *(dp++) = *(sp++);
-               *(dp++) = *(sp++);
-               */
-               sp+=2; dp = sp;
-               *(dp++) = (png_byte)(255 - *(sp++));
-               *(dp++) = (png_byte)(255 - *(sp++));
-            }
-         }
-#endif /* PNG_WRITE_16BIT_SUPPORTED */
-      }
-   }
-}
-#endif
-#endif /* PNG_WRITE_TRANSFORMS_SUPPORTED */
-
-#ifdef PNG_MNG_FEATURES_SUPPORTED
-/* Undoes intrapixel differencing  */
-void /* PRIVATE */
-png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
-{
-   png_debug(1, "in png_do_write_intrapixel");
-
-   if ((row_info->color_type & PNG_COLOR_MASK_COLOR))
-   {
-      int bytes_per_pixel;
-      png_uint_32 row_width = row_info->width;
-      if (row_info->bit_depth == 8)
-      {
-         png_bytep rp;
-         png_uint_32 i;
-
-         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
-            bytes_per_pixel = 3;
-
-         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
-            bytes_per_pixel = 4;
-
-         else
-            return;
-
-         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
-         {
-            *(rp)     = (png_byte)((*rp       - *(rp + 1)) & 0xff);
-            *(rp + 2) = (png_byte)((*(rp + 2) - *(rp + 1)) & 0xff);
-         }
-      }
-
-#ifdef PNG_WRITE_16BIT_SUPPORTED
-      else if (row_info->bit_depth == 16)
-      {
-         png_bytep rp;
-         png_uint_32 i;
-
-         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
-            bytes_per_pixel = 6;
-
-         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
-            bytes_per_pixel = 8;
-
-         else
-            return;
-
-         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
-         {
-            png_uint_32 s0   = (*(rp    ) << 8) | *(rp + 1);
-            png_uint_32 s1   = (*(rp + 2) << 8) | *(rp + 3);
-            png_uint_32 s2   = (*(rp + 4) << 8) | *(rp + 5);
-            png_uint_32 red  = (png_uint_32)((s0 - s1) & 0xffffL);
-            png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL);
-            *(rp    ) = (png_byte)((red >> 8) & 0xff);
-            *(rp + 1) = (png_byte)(red & 0xff);
-            *(rp + 4) = (png_byte)((blue >> 8) & 0xff);
-            *(rp + 5) = (png_byte)(blue & 0xff);
-         }
-      }
-#endif /* PNG_WRITE_16BIT_SUPPORTED */
-   }
-}
-#endif /* PNG_MNG_FEATURES_SUPPORTED */
-#endif /* PNG_WRITE_SUPPORTED */
+
+/* pngwtran.c - transforms the data in a row for PNG writers
+ *
+ * Last changed in libpng 1.6.15 [November 20, 2014]
+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+#include "pngpriv.h"
+
+#ifdef PNG_WRITE_SUPPORTED
+#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
+
+#ifdef PNG_WRITE_PACK_SUPPORTED
+/* Pack pixels into bytes.  Pass the true bit depth in bit_depth.  The
+ * row_info bit depth should be 8 (one pixel per byte).  The channels
+ * should be 1 (this only happens on grayscale and paletted images).
+ */
+static void
+png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
+{
+   png_debug(1, "in png_do_pack");
+
+   if (row_info->bit_depth == 8 &&
+      row_info->channels == 1)
+   {
+      switch ((int)bit_depth)
+      {
+         case 1:
+         {
+            png_bytep sp, dp;
+            int mask, v;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+
+            sp = row;
+            dp = row;
+            mask = 0x80;
+            v = 0;
+
+            for (i = 0; i < row_width; i++)
+            {
+               if (*sp != 0)
+                  v |= mask;
+
+               sp++;
+
+               if (mask > 1)
+                  mask >>= 1;
+
+               else
+               {
+                  mask = 0x80;
+                  *dp = (png_byte)v;
+                  dp++;
+                  v = 0;
+               }
+            }
+
+            if (mask != 0x80)
+               *dp = (png_byte)v;
+
+            break;
+         }
+
+         case 2:
+         {
+            png_bytep sp, dp;
+            int shift, v;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+
+            sp = row;
+            dp = row;
+            shift = 6;
+            v = 0;
+
+            for (i = 0; i < row_width; i++)
+            {
+               png_byte value;
+
+               value = (png_byte)(*sp & 0x03);
+               v |= (value << shift);
+
+               if (shift == 0)
+               {
+                  shift = 6;
+                  *dp = (png_byte)v;
+                  dp++;
+                  v = 0;
+               }
+
+               else
+                  shift -= 2;
+
+               sp++;
+            }
+
+            if (shift != 6)
+               *dp = (png_byte)v;
+
+            break;
+         }
+
+         case 4:
+         {
+            png_bytep sp, dp;
+            int shift, v;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+
+            sp = row;
+            dp = row;
+            shift = 4;
+            v = 0;
+
+            for (i = 0; i < row_width; i++)
+            {
+               png_byte value;
+
+               value = (png_byte)(*sp & 0x0f);
+               v |= (value << shift);
+
+               if (shift == 0)
+               {
+                  shift = 4;
+                  *dp = (png_byte)v;
+                  dp++;
+                  v = 0;
+               }
+
+               else
+                  shift -= 4;
+
+               sp++;
+            }
+
+            if (shift != 4)
+               *dp = (png_byte)v;
+
+            break;
+         }
+
+         default:
+            break;
+      }
+
+      row_info->bit_depth = (png_byte)bit_depth;
+      row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels);
+      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
+          row_info->width);
+   }
+}
+#endif
+
+#ifdef PNG_WRITE_SHIFT_SUPPORTED
+/* Shift pixel values to take advantage of whole range.  Pass the
+ * true number of bits in bit_depth.  The row should be packed
+ * according to row_info->bit_depth.  Thus, if you had a row of
+ * bit depth 4, but the pixels only had values from 0 to 7, you
+ * would pass 3 as bit_depth, and this routine would translate the
+ * data to 0 to 15.
+ */
+static void
+png_do_shift(png_row_infop row_info, png_bytep row,
+    png_const_color_8p bit_depth)
+{
+   png_debug(1, "in png_do_shift");
+
+   if (row_info->color_type != PNG_COLOR_TYPE_PALETTE)
+   {
+      int shift_start[4], shift_dec[4];
+      int channels = 0;
+
+      if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
+      {
+         shift_start[channels] = row_info->bit_depth - bit_depth->red;
+         shift_dec[channels] = bit_depth->red;
+         channels++;
+
+         shift_start[channels] = row_info->bit_depth - bit_depth->green;
+         shift_dec[channels] = bit_depth->green;
+         channels++;
+
+         shift_start[channels] = row_info->bit_depth - bit_depth->blue;
+         shift_dec[channels] = bit_depth->blue;
+         channels++;
+      }
+
+      else
+      {
+         shift_start[channels] = row_info->bit_depth - bit_depth->gray;
+         shift_dec[channels] = bit_depth->gray;
+         channels++;
+      }
+
+      if ((row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0)
+      {
+         shift_start[channels] = row_info->bit_depth - bit_depth->alpha;
+         shift_dec[channels] = bit_depth->alpha;
+         channels++;
+      }
+
+      /* With low row depths, could only be grayscale, so one channel */
+      if (row_info->bit_depth < 8)
+      {
+         png_bytep bp = row;
+         png_size_t i;
+         unsigned int mask;
+         png_size_t row_bytes = row_info->rowbytes;
+
+         if (bit_depth->gray == 1 && row_info->bit_depth == 2)
+            mask = 0x55;
+
+         else if (row_info->bit_depth == 4 && bit_depth->gray == 3)
+            mask = 0x11;
+
+         else
+            mask = 0xff;
+
+         for (i = 0; i < row_bytes; i++, bp++)
+         {
+            int j;
+            unsigned int v, out;
+
+            v = *bp;
+            out = 0;
+
+            for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0])
+            {
+               if (j > 0)
+                  out |= v << j;
+
+               else
+                  out |= (v >> (-j)) & mask;
+            }
+
+            *bp = (png_byte)(out & 0xff);
+         }
+      }
+
+      else if (row_info->bit_depth == 8)
+      {
+         png_bytep bp = row;
+         png_uint_32 i;
+         png_uint_32 istop = channels * row_info->width;
+
+         for (i = 0; i < istop; i++, bp++)
+         {
+
+            const unsigned int c = i%channels;
+            int j;
+            unsigned int v, out;
+
+            v = *bp;
+            out = 0;
+
+            for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
+            {
+               if (j > 0)
+                  out |= v << j;
+
+               else
+                  out |= v >> (-j);
+            }
+
+            *bp = (png_byte)(out & 0xff);
+         }
+      }
+
+      else
+      {
+         png_bytep bp;
+         png_uint_32 i;
+         png_uint_32 istop = channels * row_info->width;
+
+         for (bp = row, i = 0; i < istop; i++)
+         {
+            const unsigned int c = i%channels;
+            int j;
+            unsigned int value, v;
+
+            v = png_get_uint_16(bp);
+            value = 0;
+
+            for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
+            {
+               if (j > 0)
+                  value |= v << j;
+
+               else
+                  value |= v >> (-j);
+            }
+            *bp++ = (png_byte)((value >> 8) & 0xff);
+            *bp++ = (png_byte)(value & 0xff);
+         }
+      }
+   }
+}
+#endif
+
+#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
+static void
+png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_write_swap_alpha");
+
+   {
+      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+      {
+         if (row_info->bit_depth == 8)
+         {
+            /* This converts from ARGB to RGBA */
+            png_bytep sp, dp;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+
+            for (i = 0, sp = dp = row; i < row_width; i++)
+            {
+               png_byte save = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = save;
+            }
+         }
+
+#ifdef PNG_WRITE_16BIT_SUPPORTED
+         else
+         {
+            /* This converts from AARRGGBB to RRGGBBAA */
+            png_bytep sp, dp;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+
+            for (i = 0, sp = dp = row; i < row_width; i++)
+            {
+               png_byte save[2];
+               save[0] = *(sp++);
+               save[1] = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = save[0];
+               *(dp++) = save[1];
+            }
+         }
+#endif /* WRITE_16BIT */
+      }
+
+      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+      {
+         if (row_info->bit_depth == 8)
+         {
+            /* This converts from AG to GA */
+            png_bytep sp, dp;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+
+            for (i = 0, sp = dp = row; i < row_width; i++)
+            {
+               png_byte save = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = save;
+            }
+         }
+
+#ifdef PNG_WRITE_16BIT_SUPPORTED
+         else
+         {
+            /* This converts from AAGG to GGAA */
+            png_bytep sp, dp;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+
+            for (i = 0, sp = dp = row; i < row_width; i++)
+            {
+               png_byte save[2];
+               save[0] = *(sp++);
+               save[1] = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = save[0];
+               *(dp++) = save[1];
+            }
+         }
+#endif /* WRITE_16BIT */
+      }
+   }
+}
+#endif
+
+#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
+static void
+png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_write_invert_alpha");
+
+   {
+      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+      {
+         if (row_info->bit_depth == 8)
+         {
+            /* This inverts the alpha channel in RGBA */
+            png_bytep sp, dp;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+
+            for (i = 0, sp = dp = row; i < row_width; i++)
+            {
+               /* Does nothing
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               */
+               sp+=3; dp = sp;
+               *(dp++) = (png_byte)(255 - *(sp++));
+            }
+         }
+
+#ifdef PNG_WRITE_16BIT_SUPPORTED
+         else
+         {
+            /* This inverts the alpha channel in RRGGBBAA */
+            png_bytep sp, dp;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+
+            for (i = 0, sp = dp = row; i < row_width; i++)
+            {
+               /* Does nothing
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               */
+               sp+=6; dp = sp;
+               *(dp++) = (png_byte)(255 - *(sp++));
+               *(dp++) = (png_byte)(255 - *(sp++));
+            }
+         }
+#endif /* WRITE_16BIT */
+      }
+
+      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+      {
+         if (row_info->bit_depth == 8)
+         {
+            /* This inverts the alpha channel in GA */
+            png_bytep sp, dp;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+
+            for (i = 0, sp = dp = row; i < row_width; i++)
+            {
+               *(dp++) = *(sp++);
+               *(dp++) = (png_byte)(255 - *(sp++));
+            }
+         }
+
+#ifdef PNG_WRITE_16BIT_SUPPORTED
+         else
+         {
+            /* This inverts the alpha channel in GGAA */
+            png_bytep sp, dp;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+
+            for (i = 0, sp = dp = row; i < row_width; i++)
+            {
+               /* Does nothing
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               */
+               sp+=2; dp = sp;
+               *(dp++) = (png_byte)(255 - *(sp++));
+               *(dp++) = (png_byte)(255 - *(sp++));
+            }
+         }
+#endif /* WRITE_16BIT */
+      }
+   }
+}
+#endif
+
+/* Transform the data according to the user's wishes.  The order of
+ * transformations is significant.
+ */
+void /* PRIVATE */
+png_do_write_transformations(png_structrp png_ptr, png_row_infop row_info)
+{
+   png_debug(1, "in png_do_write_transformations");
+
+   if (png_ptr == NULL)
+      return;
+
+#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
+   if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0)
+      if (png_ptr->write_user_transform_fn != NULL)
+         (*(png_ptr->write_user_transform_fn)) /* User write transform
+                                                 function */
+             (png_ptr,  /* png_ptr */
+             row_info,  /* row_info: */
+                /*  png_uint_32 width;       width of row */
+                /*  png_size_t rowbytes;     number of bytes in row */
+                /*  png_byte color_type;     color type of pixels */
+                /*  png_byte bit_depth;      bit depth of samples */
+                /*  png_byte channels;       number of channels (1-4) */
+                /*  png_byte pixel_depth;    bits per pixel (depth*channels) */
+             png_ptr->row_buf + 1);      /* start of pixel data for row */
+#endif
+
+#ifdef PNG_WRITE_FILLER_SUPPORTED
+   if ((png_ptr->transformations & PNG_FILLER) != 0)
+      png_do_strip_channel(row_info, png_ptr->row_buf + 1,
+         !(png_ptr->flags & PNG_FLAG_FILLER_AFTER));
+#endif
+
+#ifdef PNG_WRITE_PACKSWAP_SUPPORTED
+   if ((png_ptr->transformations & PNG_PACKSWAP) != 0)
+      png_do_packswap(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_WRITE_PACK_SUPPORTED
+   if ((png_ptr->transformations & PNG_PACK) != 0)
+      png_do_pack(row_info, png_ptr->row_buf + 1,
+          (png_uint_32)png_ptr->bit_depth);
+#endif
+
+#ifdef PNG_WRITE_SWAP_SUPPORTED
+#  ifdef PNG_16BIT_SUPPORTED
+   if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0)
+      png_do_swap(row_info, png_ptr->row_buf + 1);
+#  endif
+#endif
+
+#ifdef PNG_WRITE_SHIFT_SUPPORTED
+   if ((png_ptr->transformations & PNG_SHIFT) != 0)
+      png_do_shift(row_info, png_ptr->row_buf + 1,
+          &(png_ptr->shift));
+#endif
+
+#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
+   if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0)
+      png_do_write_swap_alpha(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
+   if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0)
+      png_do_write_invert_alpha(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_WRITE_BGR_SUPPORTED
+   if ((png_ptr->transformations & PNG_BGR) != 0)
+      png_do_bgr(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_WRITE_INVERT_SUPPORTED
+   if ((png_ptr->transformations & PNG_INVERT_MONO) != 0)
+      png_do_invert(row_info, png_ptr->row_buf + 1);
+#endif
+}
+#endif /* WRITE_TRANSFORMS */
+#endif /* WRITE */
diff --git a/Source/LibPNG/pngwutil.c b/Source/LibPNG/pngwutil.c
index 3cef5b2..10c1edf 100644
--- a/Source/LibPNG/pngwutil.c
+++ b/Source/LibPNG/pngwutil.c
@@ -1,3180 +1,3029 @@
-
-/* pngwutil.c - utilities to write a PNG file
- *
- * Last changed in libpng 1.5.10 [March 8, 2012]
- * Copyright (c) 1998-2012 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- */
-
-#include "pngpriv.h"
-
-#ifdef PNG_WRITE_SUPPORTED
-
-#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED
-/* Place a 32-bit number into a buffer in PNG byte order.  We work
- * with unsigned numbers for convenience, although one supported
- * ancillary chunk uses signed (two's complement) numbers.
- */
-void PNGAPI
-png_save_uint_32(png_bytep buf, png_uint_32 i)
-{
-   buf[0] = (png_byte)((i >> 24) & 0xff);
-   buf[1] = (png_byte)((i >> 16) & 0xff);
-   buf[2] = (png_byte)((i >> 8) & 0xff);
-   buf[3] = (png_byte)(i & 0xff);
-}
-
-#ifdef PNG_SAVE_INT_32_SUPPORTED
-/* The png_save_int_32 function assumes integers are stored in two's
- * complement format.  If this isn't the case, then this routine needs to
- * be modified to write data in two's complement format.  Note that,
- * the following works correctly even if png_int_32 has more than 32 bits
- * (compare the more complex code required on read for sign extention.)
- */
-void PNGAPI
-png_save_int_32(png_bytep buf, png_int_32 i)
-{
-   buf[0] = (png_byte)((i >> 24) & 0xff);
-   buf[1] = (png_byte)((i >> 16) & 0xff);
-   buf[2] = (png_byte)((i >> 8) & 0xff);
-   buf[3] = (png_byte)(i & 0xff);
-}
-#endif
-
-/* Place a 16-bit number into a buffer in PNG byte order.
- * The parameter is declared unsigned int, not png_uint_16,
- * just to avoid potential problems on pre-ANSI C compilers.
- */
-void PNGAPI
-png_save_uint_16(png_bytep buf, unsigned int i)
-{
-   buf[0] = (png_byte)((i >> 8) & 0xff);
-   buf[1] = (png_byte)(i & 0xff);
-}
-#endif
-
-/* Simple function to write the signature.  If we have already written
- * the magic bytes of the signature, or more likely, the PNG stream is
- * being embedded into another stream and doesn't need its own signature,
- * we should call png_set_sig_bytes() to tell libpng how many of the
- * bytes have already been written.
- */
-void PNGAPI
-png_write_sig(png_structp png_ptr)
-{
-   png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
-
-#ifdef PNG_IO_STATE_SUPPORTED
-   /* Inform the I/O callback that the signature is being written */
-   png_ptr->io_state = PNG_IO_WRITING | PNG_IO_SIGNATURE;
-#endif
-
-   /* Write the rest of the 8 byte signature */
-   png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes],
-      (png_size_t)(8 - png_ptr->sig_bytes));
-
-   if (png_ptr->sig_bytes < 3)
-      png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
-}
-
-/* Write the start of a PNG chunk.  The type is the chunk type.
- * The total_length is the sum of the lengths of all the data you will be
- * passing in png_write_chunk_data().
- */
-static void
-png_write_chunk_header(png_structp png_ptr, png_uint_32 chunk_name,
-    png_uint_32 length)
-{
-   png_byte buf[8];
-
-#if defined(PNG_DEBUG) && (PNG_DEBUG > 0)
-   PNG_CSTRING_FROM_CHUNK(buf, chunk_name);
-   png_debug2(0, "Writing %s chunk, length = %lu", buf, (unsigned long)length);
-#endif
-
-   if (png_ptr == NULL)
-      return;
-
-#ifdef PNG_IO_STATE_SUPPORTED
-   /* Inform the I/O callback that the chunk header is being written.
-    * PNG_IO_CHUNK_HDR requires a single I/O call.
-    */
-   png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_HDR;
-#endif
-
-   /* Write the length and the chunk name */
-   png_save_uint_32(buf, length);
-   png_save_uint_32(buf + 4, chunk_name);
-   png_write_data(png_ptr, buf, 8);
-
-   /* Put the chunk name into png_ptr->chunk_name */
-   png_ptr->chunk_name = chunk_name;
-
-   /* Reset the crc and run it over the chunk name */
-   png_reset_crc(png_ptr);
-
-   png_calculate_crc(png_ptr, buf + 4, 4);
-
-#ifdef PNG_IO_STATE_SUPPORTED
-   /* Inform the I/O callback that chunk data will (possibly) be written.
-    * PNG_IO_CHUNK_DATA does NOT require a specific number of I/O calls.
-    */
-   png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_DATA;
-#endif
-}
-
-void PNGAPI
-png_write_chunk_start(png_structp png_ptr, png_const_bytep chunk_string,
-    png_uint_32 length)
-{
-   png_write_chunk_header(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), length);
-}
-
-/* Write the data of a PNG chunk started with png_write_chunk_header().
- * Note that multiple calls to this function are allowed, and that the
- * sum of the lengths from these calls *must* add up to the total_length
- * given to png_write_chunk_header().
- */
-void PNGAPI
-png_write_chunk_data(png_structp png_ptr, png_const_bytep data,
-    png_size_t length)
-{
-   /* Write the data, and run the CRC over it */
-   if (png_ptr == NULL)
-      return;
-
-   if (data != NULL && length > 0)
-   {
-      png_write_data(png_ptr, data, length);
-
-      /* Update the CRC after writing the data,
-       * in case that the user I/O routine alters it.
-       */
-      png_calculate_crc(png_ptr, data, length);
-   }
-}
-
-/* Finish a chunk started with png_write_chunk_header(). */
-void PNGAPI
-png_write_chunk_end(png_structp png_ptr)
-{
-   png_byte buf[4];
-
-   if (png_ptr == NULL) return;
-
-#ifdef PNG_IO_STATE_SUPPORTED
-   /* Inform the I/O callback that the chunk CRC is being written.
-    * PNG_IO_CHUNK_CRC requires a single I/O function call.
-    */
-   png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_CRC;
-#endif
-
-   /* Write the crc in a single operation */
-   png_save_uint_32(buf, png_ptr->crc);
-
-   png_write_data(png_ptr, buf, (png_size_t)4);
-}
-
-/* Write a PNG chunk all at once.  The type is an array of ASCII characters
- * representing the chunk name.  The array must be at least 4 bytes in
- * length, and does not need to be null terminated.  To be safe, pass the
- * pre-defined chunk names here, and if you need a new one, define it
- * where the others are defined.  The length is the length of the data.
- * All the data must be present.  If that is not possible, use the
- * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end()
- * functions instead.
- */
-static void
-png_write_complete_chunk(png_structp png_ptr, png_uint_32 chunk_name,
-   png_const_bytep data, png_size_t length)
-{
-   if (png_ptr == NULL)
-      return;
-
-   /* On 64 bit architectures 'length' may not fit in a png_uint_32. */
-   if (length > PNG_UINT_32_MAX)
-      png_error(png_ptr, "length exceeds PNG maxima");
-
-   png_write_chunk_header(png_ptr, chunk_name, (png_uint_32)length);
-   png_write_chunk_data(png_ptr, data, length);
-   png_write_chunk_end(png_ptr);
-}
-
-/* This is the API that calls the internal function above. */
-void PNGAPI
-png_write_chunk(png_structp png_ptr, png_const_bytep chunk_string,
-   png_const_bytep data, png_size_t length)
-{
-   png_write_complete_chunk(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), data,
-      length);
-}
-
-/* Initialize the compressor for the appropriate type of compression. */
-static void
-png_zlib_claim(png_structp png_ptr, png_uint_32 state)
-{
-   if (!(png_ptr->zlib_state & PNG_ZLIB_IN_USE))
-   {
-      /* If already initialized for 'state' do not re-init. */
-      if (png_ptr->zlib_state != state)
-      {
-         int ret = Z_OK;
-         png_const_charp who = "-";
-
-         /* If actually initialized for another state do a deflateEnd. */
-         if (png_ptr->zlib_state != PNG_ZLIB_UNINITIALIZED)
-         {
-            ret = deflateEnd(&png_ptr->zstream);
-            who = "end";
-            png_ptr->zlib_state = PNG_ZLIB_UNINITIALIZED;
-         }
-
-         /* zlib itself detects an incomplete state on deflateEnd */
-         if (ret == Z_OK) switch (state)
-         {
-#           ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED
-               case PNG_ZLIB_FOR_TEXT:
-                  ret = deflateInit2(&png_ptr->zstream,
-                     png_ptr->zlib_text_level, png_ptr->zlib_text_method,
-                     png_ptr->zlib_text_window_bits,
-                     png_ptr->zlib_text_mem_level, png_ptr->zlib_text_strategy);
-                  who = "text";
-                  break;
-#           endif
-
-            case PNG_ZLIB_FOR_IDAT:
-               ret = deflateInit2(&png_ptr->zstream, png_ptr->zlib_level,
-                   png_ptr->zlib_method, png_ptr->zlib_window_bits,
-                   png_ptr->zlib_mem_level, png_ptr->zlib_strategy);
-               who = "IDAT";
-               break;
-
-            default:
-               png_error(png_ptr, "invalid zlib state");
-         }
-
-         if (ret == Z_OK)
-            png_ptr->zlib_state = state;
-
-         else /* an error in deflateEnd or deflateInit2 */
-         {
-            size_t pos = 0;
-            char msg[64];
-
-            pos = png_safecat(msg, sizeof msg, pos,
-               "zlib failed to initialize compressor (");
-            pos = png_safecat(msg, sizeof msg, pos, who);
-
-            switch (ret)
-            {
-               case Z_VERSION_ERROR:
-                  pos = png_safecat(msg, sizeof msg, pos, ") version error");
-                  break;
-
-               case Z_STREAM_ERROR:
-                  pos = png_safecat(msg, sizeof msg, pos, ") stream error");
-                  break;
-
-               case Z_MEM_ERROR:
-                  pos = png_safecat(msg, sizeof msg, pos, ") memory error");
-                  break;
-
-               default:
-                  pos = png_safecat(msg, sizeof msg, pos, ") unknown error");
-                  break;
-            }
-
-            png_error(png_ptr, msg);
-         }
-      }
-
-      /* Here on success, claim the zstream: */
-      png_ptr->zlib_state |= PNG_ZLIB_IN_USE;
-   }
-
-   else
-      png_error(png_ptr, "zstream already in use (internal error)");
-}
-
-/* The opposite: release the stream.  It is also reset, this API will warn on
- * error but will not fail.
- */
-static void
-png_zlib_release(png_structp png_ptr)
-{
-   if (png_ptr->zlib_state & PNG_ZLIB_IN_USE)
-   {
-      int ret = deflateReset(&png_ptr->zstream);
-
-      png_ptr->zlib_state &= ~PNG_ZLIB_IN_USE;
-
-      if (ret != Z_OK)
-      {
-         png_const_charp err;
-         PNG_WARNING_PARAMETERS(p)
-
-         switch (ret)
-         {
-            case Z_VERSION_ERROR:
-               err = "version";
-               break;
-
-            case Z_STREAM_ERROR:
-               err = "stream";
-               break;
-
-            case Z_MEM_ERROR:
-               err = "memory";
-               break;
-
-            default:
-               err = "unknown";
-               break;
-         }
-
-         png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_d, ret);
-         png_warning_parameter(p, 2, err);
-
-         if (png_ptr->zstream.msg)
-            err = png_ptr->zstream.msg;
-         else
-            err = "[no zlib message]";
-
-         png_warning_parameter(p, 3, err);
-
-         png_formatted_warning(png_ptr, p,
-            "zlib failed to reset compressor: @1(@2): @3");
-      }
-   }
-
-   else
-      png_warning(png_ptr, "zstream not in use (internal error)");
-}
-
-#ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED
-/* This pair of functions encapsulates the operation of (a) compressing a
- * text string, and (b) issuing it later as a series of chunk data writes.
- * The compression_state structure is shared context for these functions
- * set up by the caller in order to make the whole mess thread-safe.
- */
-
-typedef struct
-{
-   png_const_bytep input;   /* The uncompressed input data */
-   png_size_t input_len;    /* Its length */
-   int num_output_ptr;      /* Number of output pointers used */
-   int max_output_ptr;      /* Size of output_ptr */
-   png_bytep *output_ptr;   /* Array of pointers to output */
-} compression_state;
-
-/* Compress given text into storage in the png_ptr structure */
-static int /* PRIVATE */
-png_text_compress(png_structp png_ptr,
-    png_const_charp text, png_size_t text_len, int compression,
-    compression_state *comp)
-{
-   int ret;
-
-   comp->num_output_ptr = 0;
-   comp->max_output_ptr = 0;
-   comp->output_ptr = NULL;
-   comp->input = NULL;
-   comp->input_len = text_len;
-
-   /* We may just want to pass the text right through */
-   if (compression == PNG_TEXT_COMPRESSION_NONE)
-   {
-      comp->input = (png_const_bytep)text;
-      return((int)text_len);
-   }
-
-   if (compression >= PNG_TEXT_COMPRESSION_LAST)
-   {
-      PNG_WARNING_PARAMETERS(p)
-
-      png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_d,
-         compression);
-      png_formatted_warning(png_ptr, p, "Unknown compression type @1");
-   }
-
-   /* We can't write the chunk until we find out how much data we have,
-    * which means we need to run the compressor first and save the
-    * output.  This shouldn't be a problem, as the vast majority of
-    * comments should be reasonable, but we will set up an array of
-    * malloc'd pointers to be sure.
-    *
-    * If we knew the application was well behaved, we could simplify this
-    * greatly by assuming we can always malloc an output buffer large
-    * enough to hold the compressed text ((1001 * text_len / 1000) + 12)
-    * and malloc this directly.  The only time this would be a bad idea is
-    * if we can't malloc more than 64K and we have 64K of random input
-    * data, or if the input string is incredibly large (although this
-    * wouldn't cause a failure, just a slowdown due to swapping).
-    */
-   png_zlib_claim(png_ptr, PNG_ZLIB_FOR_TEXT);
-
-   /* Set up the compression buffers */
-   /* TODO: the following cast hides a potential overflow problem. */
-   png_ptr->zstream.avail_in = (uInt)text_len;
-
-   /* NOTE: assume zlib doesn't overwrite the input */
-   png_ptr->zstream.next_in = (Bytef *)text;
-   png_ptr->zstream.avail_out = png_ptr->zbuf_size;
-   png_ptr->zstream.next_out = png_ptr->zbuf;
-
-   /* This is the same compression loop as in png_write_row() */
-   do
-   {
-      /* Compress the data */
-      ret = deflate(&png_ptr->zstream, Z_NO_FLUSH);
-
-      if (ret != Z_OK)
-      {
-         /* Error */
-         if (png_ptr->zstream.msg != NULL)
-            png_error(png_ptr, png_ptr->zstream.msg);
-
-         else
-            png_error(png_ptr, "zlib error");
-      }
-
-      /* Check to see if we need more room */
-      if (!(png_ptr->zstream.avail_out))
-      {
-         /* Make sure the output array has room */
-         if (comp->num_output_ptr >= comp->max_output_ptr)
-         {
-            int old_max;
-
-            old_max = comp->max_output_ptr;
-            comp->max_output_ptr = comp->num_output_ptr + 4;
-            if (comp->output_ptr != NULL)
-            {
-               png_bytepp old_ptr;
-
-               old_ptr = comp->output_ptr;
-
-               comp->output_ptr = (png_bytepp)png_malloc(png_ptr,
-                   (png_alloc_size_t)
-                   (comp->max_output_ptr * png_sizeof(png_charpp)));
-
-               png_memcpy(comp->output_ptr, old_ptr, old_max
-                   * png_sizeof(png_charp));
-
-               png_free(png_ptr, old_ptr);
-            }
-            else
-               comp->output_ptr = (png_bytepp)png_malloc(png_ptr,
-                   (png_alloc_size_t)
-                   (comp->max_output_ptr * png_sizeof(png_charp)));
-         }
-
-         /* Save the data */
-         comp->output_ptr[comp->num_output_ptr] =
-             (png_bytep)png_malloc(png_ptr,
-             (png_alloc_size_t)png_ptr->zbuf_size);
-
-         png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf,
-             png_ptr->zbuf_size);
-
-         comp->num_output_ptr++;
-
-         /* and reset the buffer */
-         png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
-         png_ptr->zstream.next_out = png_ptr->zbuf;
-      }
-   /* Continue until we don't have any more to compress */
-   } while (png_ptr->zstream.avail_in);
-
-   /* Finish the compression */
-   do
-   {
-      /* Tell zlib we are finished */
-      ret = deflate(&png_ptr->zstream, Z_FINISH);
-
-      if (ret == Z_OK)
-      {
-         /* Check to see if we need more room */
-         if (!(png_ptr->zstream.avail_out))
-         {
-            /* Check to make sure our output array has room */
-            if (comp->num_output_ptr >= comp->max_output_ptr)
-            {
-               int old_max;
-
-               old_max = comp->max_output_ptr;
-               comp->max_output_ptr = comp->num_output_ptr + 4;
-               if (comp->output_ptr != NULL)
-               {
-                  png_bytepp old_ptr;
-
-                  old_ptr = comp->output_ptr;
-
-                  /* This could be optimized to realloc() */
-                  comp->output_ptr = (png_bytepp)png_malloc(png_ptr,
-                      (png_alloc_size_t)(comp->max_output_ptr *
-                      png_sizeof(png_charp)));
-
-                  png_memcpy(comp->output_ptr, old_ptr,
-                      old_max * png_sizeof(png_charp));
-
-                  png_free(png_ptr, old_ptr);
-               }
-
-               else
-                  comp->output_ptr = (png_bytepp)png_malloc(png_ptr,
-                      (png_alloc_size_t)(comp->max_output_ptr *
-                      png_sizeof(png_charp)));
-            }
-
-            /* Save the data */
-            comp->output_ptr[comp->num_output_ptr] =
-                (png_bytep)png_malloc(png_ptr,
-                (png_alloc_size_t)png_ptr->zbuf_size);
-
-            png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf,
-                png_ptr->zbuf_size);
-
-            comp->num_output_ptr++;
-
-            /* and reset the buffer pointers */
-            png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
-            png_ptr->zstream.next_out = png_ptr->zbuf;
-         }
-      }
-      else if (ret != Z_STREAM_END)
-      {
-         /* We got an error */
-         if (png_ptr->zstream.msg != NULL)
-            png_error(png_ptr, png_ptr->zstream.msg);
-
-         else
-            png_error(png_ptr, "zlib error");
-      }
-   } while (ret != Z_STREAM_END);
-
-   /* Text length is number of buffers plus last buffer */
-   text_len = png_ptr->zbuf_size * comp->num_output_ptr;
-
-   if (png_ptr->zstream.avail_out < png_ptr->zbuf_size)
-      text_len += png_ptr->zbuf_size - (png_size_t)png_ptr->zstream.avail_out;
-
-   return((int)text_len);
-}
-
-/* Ship the compressed text out via chunk writes */
-static void /* PRIVATE */
-png_write_compressed_data_out(png_structp png_ptr, compression_state *comp,
-   png_size_t data_len)
-{
-   int i;
-
-   /* Handle the no-compression case */
-   if (comp->input)
-   {
-      png_write_chunk_data(png_ptr, comp->input, data_len);
-
-      return;
-   }
-
-#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
-   /* The zbuf_size test is because the code below doesn't work if zbuf_size is
-    * '1'; simply skip it to avoid memory overwrite.
-    */
-   if (data_len >= 2 && comp->input_len < 16384 && png_ptr->zbuf_size > 1)
-   {
-      unsigned int z_cmf;  /* zlib compression method and flags */
-
-      /* Optimize the CMF field in the zlib stream.  This hack of the zlib
-       * stream is compliant to the stream specification.
-       */
-
-      if (comp->num_output_ptr)
-        z_cmf = comp->output_ptr[0][0];
-      else
-        z_cmf = png_ptr->zbuf[0];
-
-      if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70)
-      {
-         unsigned int z_cinfo;
-         unsigned int half_z_window_size;
-         png_size_t uncompressed_text_size = comp->input_len;
-
-         z_cinfo = z_cmf >> 4;
-         half_z_window_size = 1 << (z_cinfo + 7);
-
-         while (uncompressed_text_size <= half_z_window_size &&
-             half_z_window_size >= 256)
-         {
-            z_cinfo--;
-            half_z_window_size >>= 1;
-         }
-
-         z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4);
-
-         if (comp->num_output_ptr)
-         {
-
-           if (comp->output_ptr[0][0] != z_cmf)
-           {
-              int tmp;
-
-              comp->output_ptr[0][0] = (png_byte)z_cmf;
-              tmp = comp->output_ptr[0][1] & 0xe0;
-              tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f;
-              comp->output_ptr[0][1] = (png_byte)tmp;
-           }
-         }
-         else
-         {
-            int tmp;
-
-            png_ptr->zbuf[0] = (png_byte)z_cmf;
-            tmp = png_ptr->zbuf[1] & 0xe0;
-            tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f;
-            png_ptr->zbuf[1] = (png_byte)tmp;
-         }
-      }
-
-      else
-         png_error(png_ptr,
-             "Invalid zlib compression method or flags in non-IDAT chunk");
-   }
-#endif /* PNG_WRITE_OPTIMIZE_CMF_SUPPORTED */
-
-   /* Write saved output buffers, if any */
-   for (i = 0; i < comp->num_output_ptr; i++)
-   {
-      png_write_chunk_data(png_ptr, comp->output_ptr[i],
-          (png_size_t)png_ptr->zbuf_size);
-
-      png_free(png_ptr, comp->output_ptr[i]);
-   }
-
-   if (comp->max_output_ptr != 0)
-      png_free(png_ptr, comp->output_ptr);
-
-   /* Write anything left in zbuf */
-   if (png_ptr->zstream.avail_out < (png_uint_32)png_ptr->zbuf_size)
-      png_write_chunk_data(png_ptr, png_ptr->zbuf,
-          (png_size_t)(png_ptr->zbuf_size - png_ptr->zstream.avail_out));
-
-   /* Reset zlib for another zTXt/iTXt or image data */
-   png_zlib_release(png_ptr);
-}
-#endif /* PNG_WRITE_COMPRESSED_TEXT_SUPPORTED */
-
-/* Write the IHDR chunk, and update the png_struct with the necessary
- * information.  Note that the rest of this code depends upon this
- * information being correct.
- */
-void /* PRIVATE */
-png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height,
-    int bit_depth, int color_type, int compression_type, int filter_type,
-    int interlace_type)
-{
-   png_byte buf[13]; /* Buffer to store the IHDR info */
-
-   png_debug(1, "in png_write_IHDR");
-
-   /* Check that we have valid input data from the application info */
-   switch (color_type)
-   {
-      case PNG_COLOR_TYPE_GRAY:
-         switch (bit_depth)
-         {
-            case 1:
-            case 2:
-            case 4:
-            case 8:
-#ifdef PNG_WRITE_16BIT_SUPPORTED
-            case 16:
-#endif
-               png_ptr->channels = 1; break;
-
-            default:
-               png_error(png_ptr,
-                   "Invalid bit depth for grayscale image");
-         }
-         break;
-
-      case PNG_COLOR_TYPE_RGB:
-#ifdef PNG_WRITE_16BIT_SUPPORTED
-         if (bit_depth != 8 && bit_depth != 16)
-#else
-         if (bit_depth != 8)
-#endif
-            png_error(png_ptr, "Invalid bit depth for RGB image");
-
-         png_ptr->channels = 3;
-         break;
-
-      case PNG_COLOR_TYPE_PALETTE:
-         switch (bit_depth)
-         {
-            case 1:
-            case 2:
-            case 4:
-            case 8:
-               png_ptr->channels = 1;
-               break;
-
-            default:
-               png_error(png_ptr, "Invalid bit depth for paletted image");
-         }
-         break;
-
-      case PNG_COLOR_TYPE_GRAY_ALPHA:
-         if (bit_depth != 8 && bit_depth != 16)
-            png_error(png_ptr, "Invalid bit depth for grayscale+alpha image");
-
-         png_ptr->channels = 2;
-         break;
-
-      case PNG_COLOR_TYPE_RGB_ALPHA:
-#ifdef PNG_WRITE_16BIT_SUPPORTED
-         if (bit_depth != 8 && bit_depth != 16)
-#else
-         if (bit_depth != 8)
-#endif
-            png_error(png_ptr, "Invalid bit depth for RGBA image");
-
-         png_ptr->channels = 4;
-         break;
-
-      default:
-         png_error(png_ptr, "Invalid image color type specified");
-   }
-
-   if (compression_type != PNG_COMPRESSION_TYPE_BASE)
-   {
-      png_warning(png_ptr, "Invalid compression type specified");
-      compression_type = PNG_COMPRESSION_TYPE_BASE;
-   }
-
-   /* Write filter_method 64 (intrapixel differencing) only if
-    * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
-    * 2. Libpng did not write a PNG signature (this filter_method is only
-    *    used in PNG datastreams that are embedded in MNG datastreams) and
-    * 3. The application called png_permit_mng_features with a mask that
-    *    included PNG_FLAG_MNG_FILTER_64 and
-    * 4. The filter_method is 64 and
-    * 5. The color_type is RGB or RGBA
-    */
-   if (
-#ifdef PNG_MNG_FEATURES_SUPPORTED
-       !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
-       ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) &&
-       (color_type == PNG_COLOR_TYPE_RGB ||
-        color_type == PNG_COLOR_TYPE_RGB_ALPHA) &&
-       (filter_type == PNG_INTRAPIXEL_DIFFERENCING)) &&
-#endif
-       filter_type != PNG_FILTER_TYPE_BASE)
-   {
-      png_warning(png_ptr, "Invalid filter type specified");
-      filter_type = PNG_FILTER_TYPE_BASE;
-   }
-
-#ifdef PNG_WRITE_INTERLACING_SUPPORTED
-   if (interlace_type != PNG_INTERLACE_NONE &&
-       interlace_type != PNG_INTERLACE_ADAM7)
-   {
-      png_warning(png_ptr, "Invalid interlace type specified");
-      interlace_type = PNG_INTERLACE_ADAM7;
-   }
-#else
-   interlace_type=PNG_INTERLACE_NONE;
-#endif
-
-   /* Save the relevent information */
-   png_ptr->bit_depth = (png_byte)bit_depth;
-   png_ptr->color_type = (png_byte)color_type;
-   png_ptr->interlaced = (png_byte)interlace_type;
-#ifdef PNG_MNG_FEATURES_SUPPORTED
-   png_ptr->filter_type = (png_byte)filter_type;
-#endif
-   png_ptr->compression_type = (png_byte)compression_type;
-   png_ptr->width = width;
-   png_ptr->height = height;
-
-   png_ptr->pixel_depth = (png_byte)(bit_depth * png_ptr->channels);
-   png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width);
-   /* Set the usr info, so any transformations can modify it */
-   png_ptr->usr_width = png_ptr->width;
-   png_ptr->usr_bit_depth = png_ptr->bit_depth;
-   png_ptr->usr_channels = png_ptr->channels;
-
-   /* Pack the header information into the buffer */
-   png_save_uint_32(buf, width);
-   png_save_uint_32(buf + 4, height);
-   buf[8] = (png_byte)bit_depth;
-   buf[9] = (png_byte)color_type;
-   buf[10] = (png_byte)compression_type;
-   buf[11] = (png_byte)filter_type;
-   buf[12] = (png_byte)interlace_type;
-
-   /* Write the chunk */
-   png_write_complete_chunk(png_ptr, png_IHDR, buf, (png_size_t)13);
-
-   /* Initialize zlib with PNG info */
-   png_ptr->zstream.zalloc = png_zalloc;
-   png_ptr->zstream.zfree = png_zfree;
-   png_ptr->zstream.opaque = (voidpf)png_ptr;
-
-   if (!(png_ptr->do_filter))
-   {
-      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE ||
-          png_ptr->bit_depth < 8)
-         png_ptr->do_filter = PNG_FILTER_NONE;
-
-      else
-         png_ptr->do_filter = PNG_ALL_FILTERS;
-   }
-
-   if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY))
-   {
-      if (png_ptr->do_filter != PNG_FILTER_NONE)
-         png_ptr->zlib_strategy = Z_FILTERED;
-
-      else
-         png_ptr->zlib_strategy = Z_DEFAULT_STRATEGY;
-   }
-
-   if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_LEVEL))
-      png_ptr->zlib_level = Z_DEFAULT_COMPRESSION;
-
-   if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL))
-      png_ptr->zlib_mem_level = 8;
-
-   if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS))
-      png_ptr->zlib_window_bits = 15;
-
-   if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_METHOD))
-      png_ptr->zlib_method = 8;
-
-#ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED
-#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
-   if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_STRATEGY))
-      png_ptr->zlib_text_strategy = Z_DEFAULT_STRATEGY;
-
-   if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_LEVEL))
-      png_ptr->zlib_text_level = png_ptr->zlib_level;
-
-   if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_MEM_LEVEL))
-      png_ptr->zlib_text_mem_level = png_ptr->zlib_mem_level;
-
-   if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_WINDOW_BITS))
-      png_ptr->zlib_text_window_bits = png_ptr->zlib_window_bits;
-
-   if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_METHOD))
-      png_ptr->zlib_text_method = png_ptr->zlib_method;
-#else
-   png_ptr->zlib_text_strategy = Z_DEFAULT_STRATEGY;
-   png_ptr->zlib_text_level = png_ptr->zlib_level;
-   png_ptr->zlib_text_mem_level = png_ptr->zlib_mem_level;
-   png_ptr->zlib_text_window_bits = png_ptr->zlib_window_bits;
-   png_ptr->zlib_text_method = png_ptr->zlib_method;
-#endif /* PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED */
-#endif /* PNG_WRITE_COMPRESSED_TEXT_SUPPORTED */
-
-   /* Record that the compressor has not yet been initialized. */
-   png_ptr->zlib_state = PNG_ZLIB_UNINITIALIZED;
-
-   png_ptr->mode = PNG_HAVE_IHDR; /* not READY_FOR_ZTXT */
-}
-
-/* Write the palette.  We are careful not to trust png_color to be in the
- * correct order for PNG, so people can redefine it to any convenient
- * structure.
- */
-void /* PRIVATE */
-png_write_PLTE(png_structp png_ptr, png_const_colorp palette,
-    png_uint_32 num_pal)
-{
-   png_uint_32 i;
-   png_const_colorp pal_ptr;
-   png_byte buf[3];
-
-   png_debug(1, "in png_write_PLTE");
-
-   if ((
-#ifdef PNG_MNG_FEATURES_SUPPORTED
-       !(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) &&
-#endif
-       num_pal == 0) || num_pal > 256)
-   {
-      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
-      {
-         png_error(png_ptr, "Invalid number of colors in palette");
-      }
-
-      else
-      {
-         png_warning(png_ptr, "Invalid number of colors in palette");
-         return;
-      }
-   }
-
-   if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
-   {
-      png_warning(png_ptr,
-          "Ignoring request to write a PLTE chunk in grayscale PNG");
-
-      return;
-   }
-
-   png_ptr->num_palette = (png_uint_16)num_pal;
-   png_debug1(3, "num_palette = %d", png_ptr->num_palette);
-
-   png_write_chunk_header(png_ptr, png_PLTE, (png_uint_32)(num_pal * 3));
-#ifdef PNG_POINTER_INDEXING_SUPPORTED
-
-   for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++)
-   {
-      buf[0] = pal_ptr->red;
-      buf[1] = pal_ptr->green;
-      buf[2] = pal_ptr->blue;
-      png_write_chunk_data(png_ptr, buf, (png_size_t)3);
-   }
-
-#else
-   /* This is a little slower but some buggy compilers need to do this
-    * instead
-    */
-   pal_ptr=palette;
-
-   for (i = 0; i < num_pal; i++)
-   {
-      buf[0] = pal_ptr[i].red;
-      buf[1] = pal_ptr[i].green;
-      buf[2] = pal_ptr[i].blue;
-      png_write_chunk_data(png_ptr, buf, (png_size_t)3);
-   }
-
-#endif
-   png_write_chunk_end(png_ptr);
-   png_ptr->mode |= PNG_HAVE_PLTE;
-}
-
-/* Write an IDAT chunk */
-void /* PRIVATE */
-png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length)
-{
-   png_debug(1, "in png_write_IDAT");
-
-#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
-   if (!(png_ptr->mode & PNG_HAVE_IDAT) &&
-       png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE)
-   {
-      /* Optimize the CMF field in the zlib stream.  This hack of the zlib
-       * stream is compliant to the stream specification.
-       */
-      unsigned int z_cmf = data[0];  /* zlib compression method and flags */
-
-      if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70)
-      {
-         /* Avoid memory underflows and multiplication overflows.
-          *
-          * The conditions below are practically always satisfied;
-          * however, they still must be checked.
-          */
-         if (length >= 2 &&
-             png_ptr->height < 16384 && png_ptr->width < 16384)
-         {
-            /* Compute the maximum possible length of the datastream */
-
-            /* Number of pixels, plus for each row a filter byte
-             * and possibly a padding byte, so increase the maximum
-             * size to account for these.
-             */
-            unsigned int z_cinfo;
-            unsigned int half_z_window_size;
-            png_uint_32 uncompressed_idat_size = png_ptr->height *
-                ((png_ptr->width *
-                png_ptr->channels * png_ptr->bit_depth + 15) >> 3);
-
-            /* If it's interlaced, each block of 8 rows is sent as up to
-             * 14 rows, i.e., 6 additional rows, each with a filter byte
-             * and possibly a padding byte
-             */
-            if (png_ptr->interlaced)
-               uncompressed_idat_size += ((png_ptr->height + 7)/8) *
-                   (png_ptr->bit_depth < 8 ? 12 : 6);
-
-            z_cinfo = z_cmf >> 4;
-            half_z_window_size = 1 << (z_cinfo + 7);
-
-            while (uncompressed_idat_size <= half_z_window_size &&
-                half_z_window_size >= 256)
-            {
-               z_cinfo--;
-               half_z_window_size >>= 1;
-            }
-
-            z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4);
-
-            if (data[0] != z_cmf)
-            {
-               int tmp;
-               data[0] = (png_byte)z_cmf;
-               tmp = data[1] & 0xe0;
-               tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f;
-               data[1] = (png_byte)tmp;
-            }
-         }
-      }
-
-      else
-         png_error(png_ptr,
-             "Invalid zlib compression method or flags in IDAT");
-   }
-#endif /* PNG_WRITE_OPTIMIZE_CMF_SUPPORTED */
-
-   png_write_complete_chunk(png_ptr, png_IDAT, data, length);
-   png_ptr->mode |= PNG_HAVE_IDAT;
-
-   /* Prior to 1.5.4 this code was replicated in every caller (except at the
-    * end, where it isn't technically necessary).  Since this function has
-    * flushed the data we can safely reset the zlib output buffer here.
-    */
-   png_ptr->zstream.next_out = png_ptr->zbuf;
-   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
-}
-
-/* Write an IEND chunk */
-void /* PRIVATE */
-png_write_IEND(png_structp png_ptr)
-{
-   png_debug(1, "in png_write_IEND");
-
-   png_write_complete_chunk(png_ptr, png_IEND, NULL, (png_size_t)0);
-   png_ptr->mode |= PNG_HAVE_IEND;
-}
-
-#ifdef PNG_WRITE_gAMA_SUPPORTED
-/* Write a gAMA chunk */
-void /* PRIVATE */
-png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma)
-{
-   png_byte buf[4];
-
-   png_debug(1, "in png_write_gAMA");
-
-   /* file_gamma is saved in 1/100,000ths */
-   png_save_uint_32(buf, (png_uint_32)file_gamma);
-   png_write_complete_chunk(png_ptr, png_gAMA, buf, (png_size_t)4);
-}
-#endif
-
-#ifdef PNG_WRITE_sRGB_SUPPORTED
-/* Write a sRGB chunk */
-void /* PRIVATE */
-png_write_sRGB(png_structp png_ptr, int srgb_intent)
-{
-   png_byte buf[1];
-
-   png_debug(1, "in png_write_sRGB");
-
-   if (srgb_intent >= PNG_sRGB_INTENT_LAST)
-      png_warning(png_ptr,
-          "Invalid sRGB rendering intent specified");
-
-   buf[0]=(png_byte)srgb_intent;
-   png_write_complete_chunk(png_ptr, png_sRGB, buf, (png_size_t)1);
-}
-#endif
-
-#ifdef PNG_WRITE_iCCP_SUPPORTED
-/* Write an iCCP chunk */
-void /* PRIVATE */
-png_write_iCCP(png_structp png_ptr, png_const_charp name, int compression_type,
-    png_const_charp profile, int profile_len)
-{
-   png_size_t name_len;
-   png_charp new_name;
-   compression_state comp;
-   int embedded_profile_len = 0;
-
-   png_debug(1, "in png_write_iCCP");
-
-   comp.num_output_ptr = 0;
-   comp.max_output_ptr = 0;
-   comp.output_ptr = NULL;
-   comp.input = NULL;
-   comp.input_len = 0;
-
-   if ((name_len = png_check_keyword(png_ptr, name, &new_name)) == 0)
-      return;
-
-   if (compression_type != PNG_COMPRESSION_TYPE_BASE)
-      png_warning(png_ptr, "Unknown compression type in iCCP chunk");
-
-   if (profile == NULL)
-      profile_len = 0;
-
-   if (profile_len > 3)
-      embedded_profile_len =
-          ((*( (png_const_bytep)profile    ))<<24) |
-          ((*( (png_const_bytep)profile + 1))<<16) |
-          ((*( (png_const_bytep)profile + 2))<< 8) |
-          ((*( (png_const_bytep)profile + 3))    );
-
-   if (embedded_profile_len < 0)
-   {
-      png_warning(png_ptr,
-          "Embedded profile length in iCCP chunk is negative");
-
-      png_free(png_ptr, new_name);
-      return;
-   }
-
-   if (profile_len < embedded_profile_len)
-   {
-      png_warning(png_ptr,
-          "Embedded profile length too large in iCCP chunk");
-
-      png_free(png_ptr, new_name);
-      return;
-   }
-
-   if (profile_len > embedded_profile_len)
-   {
-      png_warning(png_ptr,
-          "Truncating profile to actual length in iCCP chunk");
-
-      profile_len = embedded_profile_len;
-   }
-
-   if (profile_len)
-      profile_len = png_text_compress(png_ptr, profile,
-          (png_size_t)profile_len, PNG_COMPRESSION_TYPE_BASE, &comp);
-
-   /* Make sure we include the NULL after the name and the compression type */
-   png_write_chunk_header(png_ptr, png_iCCP,
-       (png_uint_32)(name_len + profile_len + 2));
-
-   new_name[name_len + 1] = 0x00;
-
-   png_write_chunk_data(png_ptr, (png_bytep)new_name,
-       (png_size_t)(name_len + 2));
-
-   if (profile_len)
-   {
-      png_write_compressed_data_out(png_ptr, &comp, profile_len);
-   }
-
-   png_write_chunk_end(png_ptr);
-   png_free(png_ptr, new_name);
-}
-#endif
-
-#ifdef PNG_WRITE_sPLT_SUPPORTED
-/* Write a sPLT chunk */
-void /* PRIVATE */
-png_write_sPLT(png_structp png_ptr, png_const_sPLT_tp spalette)
-{
-   png_size_t name_len;
-   png_charp new_name;
-   png_byte entrybuf[10];
-   png_size_t entry_size = (spalette->depth == 8 ? 6 : 10);
-   png_size_t palette_size = entry_size * spalette->nentries;
-   png_sPLT_entryp ep;
-#ifndef PNG_POINTER_INDEXING_SUPPORTED
-   int i;
-#endif
-
-   png_debug(1, "in png_write_sPLT");
-
-   if ((name_len = png_check_keyword(png_ptr,spalette->name, &new_name))==0)
-      return;
-
-   /* Make sure we include the NULL after the name */
-   png_write_chunk_header(png_ptr, png_sPLT,
-       (png_uint_32)(name_len + 2 + palette_size));
-
-   png_write_chunk_data(png_ptr, (png_bytep)new_name,
-       (png_size_t)(name_len + 1));
-
-   png_write_chunk_data(png_ptr, &spalette->depth, (png_size_t)1);
-
-   /* Loop through each palette entry, writing appropriately */
-#ifdef PNG_POINTER_INDEXING_SUPPORTED
-   for (ep = spalette->entries; ep<spalette->entries + spalette->nentries; ep++)
-   {
-      if (spalette->depth == 8)
-      {
-         entrybuf[0] = (png_byte)ep->red;
-         entrybuf[1] = (png_byte)ep->green;
-         entrybuf[2] = (png_byte)ep->blue;
-         entrybuf[3] = (png_byte)ep->alpha;
-         png_save_uint_16(entrybuf + 4, ep->frequency);
-      }
-
-      else
-      {
-         png_save_uint_16(entrybuf + 0, ep->red);
-         png_save_uint_16(entrybuf + 2, ep->green);
-         png_save_uint_16(entrybuf + 4, ep->blue);
-         png_save_uint_16(entrybuf + 6, ep->alpha);
-         png_save_uint_16(entrybuf + 8, ep->frequency);
-      }
-
-      png_write_chunk_data(png_ptr, entrybuf, (png_size_t)entry_size);
-   }
-#else
-   ep=spalette->entries;
-   for (i = 0; i>spalette->nentries; i++)
-   {
-      if (spalette->depth == 8)
-      {
-         entrybuf[0] = (png_byte)ep[i].red;
-         entrybuf[1] = (png_byte)ep[i].green;
-         entrybuf[2] = (png_byte)ep[i].blue;
-         entrybuf[3] = (png_byte)ep[i].alpha;
-         png_save_uint_16(entrybuf + 4, ep[i].frequency);
-      }
-
-      else
-      {
-         png_save_uint_16(entrybuf + 0, ep[i].red);
-         png_save_uint_16(entrybuf + 2, ep[i].green);
-         png_save_uint_16(entrybuf + 4, ep[i].blue);
-         png_save_uint_16(entrybuf + 6, ep[i].alpha);
-         png_save_uint_16(entrybuf + 8, ep[i].frequency);
-      }
-
-      png_write_chunk_data(png_ptr, entrybuf, (png_size_t)entry_size);
-   }
-#endif
-
-   png_write_chunk_end(png_ptr);
-   png_free(png_ptr, new_name);
-}
-#endif
-
-#ifdef PNG_WRITE_sBIT_SUPPORTED
-/* Write the sBIT chunk */
-void /* PRIVATE */
-png_write_sBIT(png_structp png_ptr, png_const_color_8p sbit, int color_type)
-{
-   png_byte buf[4];
-   png_size_t size;
-
-   png_debug(1, "in png_write_sBIT");
-
-   /* Make sure we don't depend upon the order of PNG_COLOR_8 */
-   if (color_type & PNG_COLOR_MASK_COLOR)
-   {
-      png_byte maxbits;
-
-      maxbits = (png_byte)(color_type==PNG_COLOR_TYPE_PALETTE ? 8 :
-          png_ptr->usr_bit_depth);
-
-      if (sbit->red == 0 || sbit->red > maxbits ||
-          sbit->green == 0 || sbit->green > maxbits ||
-          sbit->blue == 0 || sbit->blue > maxbits)
-      {
-         png_warning(png_ptr, "Invalid sBIT depth specified");
-         return;
-      }
-
-      buf[0] = sbit->red;
-      buf[1] = sbit->green;
-      buf[2] = sbit->blue;
-      size = 3;
-   }
-
-   else
-   {
-      if (sbit->gray == 0 || sbit->gray > png_ptr->usr_bit_depth)
-      {
-         png_warning(png_ptr, "Invalid sBIT depth specified");
-         return;
-      }
-
-      buf[0] = sbit->gray;
-      size = 1;
-   }
-
-   if (color_type & PNG_COLOR_MASK_ALPHA)
-   {
-      if (sbit->alpha == 0 || sbit->alpha > png_ptr->usr_bit_depth)
-      {
-         png_warning(png_ptr, "Invalid sBIT depth specified");
-         return;
-      }
-
-      buf[size++] = sbit->alpha;
-   }
-
-   png_write_complete_chunk(png_ptr, png_sBIT, buf, size);
-}
-#endif
-
-#ifdef PNG_WRITE_cHRM_SUPPORTED
-/* Write the cHRM chunk */
-void /* PRIVATE */
-png_write_cHRM_fixed(png_structp png_ptr, png_fixed_point white_x,
-    png_fixed_point white_y, png_fixed_point red_x, png_fixed_point red_y,
-    png_fixed_point green_x, png_fixed_point green_y, png_fixed_point blue_x,
-    png_fixed_point blue_y)
-{
-   png_byte buf[32];
-
-   png_debug(1, "in png_write_cHRM");
-
-   /* Each value is saved in 1/100,000ths */
-#ifdef PNG_CHECK_cHRM_SUPPORTED
-   if (png_check_cHRM_fixed(png_ptr, white_x, white_y, red_x, red_y,
-       green_x, green_y, blue_x, blue_y))
-#endif
-   {
-      png_save_uint_32(buf, (png_uint_32)white_x);
-      png_save_uint_32(buf + 4, (png_uint_32)white_y);
-
-      png_save_uint_32(buf + 8, (png_uint_32)red_x);
-      png_save_uint_32(buf + 12, (png_uint_32)red_y);
-
-      png_save_uint_32(buf + 16, (png_uint_32)green_x);
-      png_save_uint_32(buf + 20, (png_uint_32)green_y);
-
-      png_save_uint_32(buf + 24, (png_uint_32)blue_x);
-      png_save_uint_32(buf + 28, (png_uint_32)blue_y);
-
-      png_write_complete_chunk(png_ptr, png_cHRM, buf, (png_size_t)32);
-   }
-}
-#endif
-
-#ifdef PNG_WRITE_tRNS_SUPPORTED
-/* Write the tRNS chunk */
-void /* PRIVATE */
-png_write_tRNS(png_structp png_ptr, png_const_bytep trans_alpha,
-    png_const_color_16p tran, int num_trans, int color_type)
-{
-   png_byte buf[6];
-
-   png_debug(1, "in png_write_tRNS");
-
-   if (color_type == PNG_COLOR_TYPE_PALETTE)
-   {
-      if (num_trans <= 0 || num_trans > (int)png_ptr->num_palette)
-      {
-         png_warning(png_ptr, "Invalid number of transparent colors specified");
-         return;
-      }
-
-      /* Write the chunk out as it is */
-      png_write_complete_chunk(png_ptr, png_tRNS, trans_alpha,
-         (png_size_t)num_trans);
-   }
-
-   else if (color_type == PNG_COLOR_TYPE_GRAY)
-   {
-      /* One 16 bit value */
-      if (tran->gray >= (1 << png_ptr->bit_depth))
-      {
-         png_warning(png_ptr,
-             "Ignoring attempt to write tRNS chunk out-of-range for bit_depth");
-
-         return;
-      }
-
-      png_save_uint_16(buf, tran->gray);
-      png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)2);
-   }
-
-   else if (color_type == PNG_COLOR_TYPE_RGB)
-   {
-      /* Three 16 bit values */
-      png_save_uint_16(buf, tran->red);
-      png_save_uint_16(buf + 2, tran->green);
-      png_save_uint_16(buf + 4, tran->blue);
-#ifdef PNG_WRITE_16BIT_SUPPORTED
-      if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]))
-#else
-      if (buf[0] | buf[2] | buf[4])
-#endif
-      {
-         png_warning(png_ptr,
-           "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8");
-         return;
-      }
-
-      png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)6);
-   }
-
-   else
-   {
-      png_warning(png_ptr, "Can't write tRNS with an alpha channel");
-   }
-}
-#endif
-
-#ifdef PNG_WRITE_bKGD_SUPPORTED
-/* Write the background chunk */
-void /* PRIVATE */
-png_write_bKGD(png_structp png_ptr, png_const_color_16p back, int color_type)
-{
-   png_byte buf[6];
-
-   png_debug(1, "in png_write_bKGD");
-
-   if (color_type == PNG_COLOR_TYPE_PALETTE)
-   {
-      if (
-#ifdef PNG_MNG_FEATURES_SUPPORTED
-          (png_ptr->num_palette ||
-          (!(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE))) &&
-#endif
-         back->index >= png_ptr->num_palette)
-      {
-         png_warning(png_ptr, "Invalid background palette index");
-         return;
-      }
-
-      buf[0] = back->index;
-      png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)1);
-   }
-
-   else if (color_type & PNG_COLOR_MASK_COLOR)
-   {
-      png_save_uint_16(buf, back->red);
-      png_save_uint_16(buf + 2, back->green);
-      png_save_uint_16(buf + 4, back->blue);
-#ifdef PNG_WRITE_16BIT_SUPPORTED
-      if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]))
-#else
-      if (buf[0] | buf[2] | buf[4])
-#endif
-      {
-         png_warning(png_ptr,
-             "Ignoring attempt to write 16-bit bKGD chunk when bit_depth is 8");
-
-         return;
-      }
-
-      png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)6);
-   }
-
-   else
-   {
-      if (back->gray >= (1 << png_ptr->bit_depth))
-      {
-         png_warning(png_ptr,
-             "Ignoring attempt to write bKGD chunk out-of-range for bit_depth");
-
-         return;
-      }
-
-      png_save_uint_16(buf, back->gray);
-      png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)2);
-   }
-}
-#endif
-
-#ifdef PNG_WRITE_hIST_SUPPORTED
-/* Write the histogram */
-void /* PRIVATE */
-png_write_hIST(png_structp png_ptr, png_const_uint_16p hist, int num_hist)
-{
-   int i;
-   png_byte buf[3];
-
-   png_debug(1, "in png_write_hIST");
-
-   if (num_hist > (int)png_ptr->num_palette)
-   {
-      png_debug2(3, "num_hist = %d, num_palette = %d", num_hist,
-          png_ptr->num_palette);
-
-      png_warning(png_ptr, "Invalid number of histogram entries specified");
-      return;
-   }
-
-   png_write_chunk_header(png_ptr, png_hIST, (png_uint_32)(num_hist * 2));
-
-   for (i = 0; i < num_hist; i++)
-   {
-      png_save_uint_16(buf, hist[i]);
-      png_write_chunk_data(png_ptr, buf, (png_size_t)2);
-   }
-
-   png_write_chunk_end(png_ptr);
-}
-#endif
-
-#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \
-    defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
-/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification,
- * and if invalid, correct the keyword rather than discarding the entire
- * chunk.  The PNG 1.0 specification requires keywords 1-79 characters in
- * length, forbids leading or trailing whitespace, multiple internal spaces,
- * and the non-break space (0x80) from ISO 8859-1.  Returns keyword length.
- *
- * The new_key is allocated to hold the corrected keyword and must be freed
- * by the calling routine.  This avoids problems with trying to write to
- * static keywords without having to have duplicate copies of the strings.
- */
-png_size_t /* PRIVATE */
-png_check_keyword(png_structp png_ptr, png_const_charp key, png_charpp new_key)
-{
-   png_size_t key_len;
-   png_const_charp ikp;
-   png_charp kp, dp;
-   int kflag;
-   int kwarn=0;
-
-   png_debug(1, "in png_check_keyword");
-
-   *new_key = NULL;
-
-   if (key == NULL || (key_len = png_strlen(key)) == 0)
-   {
-      png_warning(png_ptr, "zero length keyword");
-      return ((png_size_t)0);
-   }
-
-   png_debug1(2, "Keyword to be checked is '%s'", key);
-
-   *new_key = (png_charp)png_malloc_warn(png_ptr, (png_uint_32)(key_len + 2));
-
-   if (*new_key == NULL)
-   {
-      png_warning(png_ptr, "Out of memory while procesing keyword");
-      return ((png_size_t)0);
-   }
-
-   /* Replace non-printing characters with a blank and print a warning */
-   for (ikp = key, dp = *new_key; *ikp != '\0'; ikp++, dp++)
-   {
-      if ((png_byte)*ikp < 0x20 ||
-         ((png_byte)*ikp > 0x7E && (png_byte)*ikp < 0xA1))
-      {
-         PNG_WARNING_PARAMETERS(p)
-
-         png_warning_parameter_unsigned(p, 1, PNG_NUMBER_FORMAT_02x,
-            (png_byte)*ikp);
-         png_formatted_warning(png_ptr, p, "invalid keyword character 0x at 1");
-         *dp = ' ';
-      }
-
-      else
-      {
-         *dp = *ikp;
-      }
-   }
-   *dp = '\0';
-
-   /* Remove any trailing white space. */
-   kp = *new_key + key_len - 1;
-   if (*kp == ' ')
-   {
-      png_warning(png_ptr, "trailing spaces removed from keyword");
-
-      while (*kp == ' ')
-      {
-         *(kp--) = '\0';
-         key_len--;
-      }
-   }
-
-   /* Remove any leading white space. */
-   kp = *new_key;
-   if (*kp == ' ')
-   {
-      png_warning(png_ptr, "leading spaces removed from keyword");
-
-      while (*kp == ' ')
-      {
-         kp++;
-         key_len--;
-      }
-   }
-
-   png_debug1(2, "Checking for multiple internal spaces in '%s'", kp);
-
-   /* Remove multiple internal spaces. */
-   for (kflag = 0, dp = *new_key; *kp != '\0'; kp++)
-   {
-      if (*kp == ' ' && kflag == 0)
-      {
-         *(dp++) = *kp;
-         kflag = 1;
-      }
-
-      else if (*kp == ' ')
-      {
-         key_len--;
-         kwarn = 1;
-      }
-
-      else
-      {
-         *(dp++) = *kp;
-         kflag = 0;
-      }
-   }
-   *dp = '\0';
-   if (kwarn)
-      png_warning(png_ptr, "extra interior spaces removed from keyword");
-
-   if (key_len == 0)
-   {
-      png_free(png_ptr, *new_key);
-      png_warning(png_ptr, "Zero length keyword");
-   }
-
-   if (key_len > 79)
-   {
-      png_warning(png_ptr, "keyword length must be 1 - 79 characters");
-      (*new_key)[79] = '\0';
-      key_len = 79;
-   }
-
-   return (key_len);
-}
-#endif
-
-#ifdef PNG_WRITE_tEXt_SUPPORTED
-/* Write a tEXt chunk */
-void /* PRIVATE */
-png_write_tEXt(png_structp png_ptr, png_const_charp key, png_const_charp text,
-    png_size_t text_len)
-{
-   png_size_t key_len;
-   png_charp new_key;
-
-   png_debug(1, "in png_write_tEXt");
-
-   if ((key_len = png_check_keyword(png_ptr, key, &new_key))==0)
-      return;
-
-   if (text == NULL || *text == '\0')
-      text_len = 0;
-
-   else
-      text_len = png_strlen(text);
-
-   /* Make sure we include the 0 after the key */
-   png_write_chunk_header(png_ptr, png_tEXt,
-       (png_uint_32)(key_len + text_len + 1));
-   /*
-    * We leave it to the application to meet PNG-1.0 requirements on the
-    * contents of the text.  PNG-1.0 through PNG-1.2 discourage the use of
-    * any non-Latin-1 characters except for NEWLINE.  ISO PNG will forbid them.
-    * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
-    */
-   png_write_chunk_data(png_ptr, (png_bytep)new_key,
-       (png_size_t)(key_len + 1));
-
-   if (text_len)
-      png_write_chunk_data(png_ptr, (png_const_bytep)text,
-          (png_size_t)text_len);
-
-   png_write_chunk_end(png_ptr);
-   png_free(png_ptr, new_key);
-}
-#endif
-
-#ifdef PNG_WRITE_zTXt_SUPPORTED
-/* Write a compressed text chunk */
-void /* PRIVATE */
-png_write_zTXt(png_structp png_ptr, png_const_charp key, png_const_charp text,
-    png_size_t text_len, int compression)
-{
-   png_size_t key_len;
-   png_byte buf;
-   png_charp new_key;
-   compression_state comp;
-
-   png_debug(1, "in png_write_zTXt");
-
-   comp.num_output_ptr = 0;
-   comp.max_output_ptr = 0;
-   comp.output_ptr = NULL;
-   comp.input = NULL;
-   comp.input_len = 0;
-
-   if ((key_len = png_check_keyword(png_ptr, key, &new_key)) == 0)
-   {
-      png_free(png_ptr, new_key);
-      return;
-   }
-
-   if (text == NULL || *text == '\0' || compression==PNG_TEXT_COMPRESSION_NONE)
-   {
-      png_write_tEXt(png_ptr, new_key, text, (png_size_t)0);
-      png_free(png_ptr, new_key);
-      return;
-   }
-
-   text_len = png_strlen(text);
-
-   /* Compute the compressed data; do it now for the length */
-   text_len = png_text_compress(png_ptr, text, text_len, compression,
-       &comp);
-
-   /* Write start of chunk */
-   png_write_chunk_header(png_ptr, png_zTXt,
-       (png_uint_32)(key_len+text_len + 2));
-
-   /* Write key */
-   png_write_chunk_data(png_ptr, (png_bytep)new_key,
-       (png_size_t)(key_len + 1));
-
-   png_free(png_ptr, new_key);
-
-   buf = (png_byte)compression;
-
-   /* Write compression */
-   png_write_chunk_data(png_ptr, &buf, (png_size_t)1);
-
-   /* Write the compressed data */
-   png_write_compressed_data_out(png_ptr, &comp, text_len);
-
-   /* Close the chunk */
-   png_write_chunk_end(png_ptr);
-}
-#endif
-
-#ifdef PNG_WRITE_iTXt_SUPPORTED
-/* Write an iTXt chunk */
-void /* PRIVATE */
-png_write_iTXt(png_structp png_ptr, int compression, png_const_charp key,
-    png_const_charp lang, png_const_charp lang_key, png_const_charp text)
-{
-   png_size_t lang_len, key_len, lang_key_len, text_len;
-   png_charp new_lang;
-   png_charp new_key = NULL;
-   png_byte cbuf[2];
-   compression_state comp;
-
-   png_debug(1, "in png_write_iTXt");
-
-   comp.num_output_ptr = 0;
-   comp.max_output_ptr = 0;
-   comp.output_ptr = NULL;
-   comp.input = NULL;
-
-   if ((key_len = png_check_keyword(png_ptr, key, &new_key)) == 0)
-      return;
-
-   if ((lang_len = png_check_keyword(png_ptr, lang, &new_lang)) == 0)
-   {
-      png_warning(png_ptr, "Empty language field in iTXt chunk");
-      new_lang = NULL;
-      lang_len = 0;
-   }
-
-   if (lang_key == NULL)
-      lang_key_len = 0;
-
-   else
-      lang_key_len = png_strlen(lang_key);
-
-   if (text == NULL)
-      text_len = 0;
-
-   else
-      text_len = png_strlen(text);
-
-   /* Compute the compressed data; do it now for the length */
-   text_len = png_text_compress(png_ptr, text, text_len, compression - 2,
-       &comp);
-
-
-   /* Make sure we include the compression flag, the compression byte,
-    * and the NULs after the key, lang, and lang_key parts
-    */
-
-   png_write_chunk_header(png_ptr, png_iTXt, (png_uint_32)(
-        5 /* comp byte, comp flag, terminators for key, lang and lang_key */
-        + key_len
-        + lang_len
-        + lang_key_len
-        + text_len));
-
-   /* We leave it to the application to meet PNG-1.0 requirements on the
-    * contents of the text.  PNG-1.0 through PNG-1.2 discourage the use of
-    * any non-Latin-1 characters except for NEWLINE.  ISO PNG will forbid them.
-    * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
-    */
-   png_write_chunk_data(png_ptr, (png_bytep)new_key, (png_size_t)(key_len + 1));
-
-   /* Set the compression flag */
-   if (compression == PNG_ITXT_COMPRESSION_NONE ||
-       compression == PNG_TEXT_COMPRESSION_NONE)
-      cbuf[0] = 0;
-
-   else /* compression == PNG_ITXT_COMPRESSION_zTXt */
-      cbuf[0] = 1;
-
-   /* Set the compression method */
-   cbuf[1] = 0;
-
-   png_write_chunk_data(png_ptr, cbuf, (png_size_t)2);
-
-   cbuf[0] = 0;
-   png_write_chunk_data(png_ptr, (new_lang ? (png_const_bytep)new_lang : cbuf),
-       (png_size_t)(lang_len + 1));
-
-   png_write_chunk_data(png_ptr, (lang_key ? (png_const_bytep)lang_key : cbuf),
-       (png_size_t)(lang_key_len + 1));
-
-   png_write_compressed_data_out(png_ptr, &comp, text_len);
-
-   png_write_chunk_end(png_ptr);
-
-   png_free(png_ptr, new_key);
-   png_free(png_ptr, new_lang);
-}
-#endif
-
-#ifdef PNG_WRITE_oFFs_SUPPORTED
-/* Write the oFFs chunk */
-void /* PRIVATE */
-png_write_oFFs(png_structp png_ptr, png_int_32 x_offset, png_int_32 y_offset,
-    int unit_type)
-{
-   png_byte buf[9];
-
-   png_debug(1, "in png_write_oFFs");
-
-   if (unit_type >= PNG_OFFSET_LAST)
-      png_warning(png_ptr, "Unrecognized unit type for oFFs chunk");
-
-   png_save_int_32(buf, x_offset);
-   png_save_int_32(buf + 4, y_offset);
-   buf[8] = (png_byte)unit_type;
-
-   png_write_complete_chunk(png_ptr, png_oFFs, buf, (png_size_t)9);
-}
-#endif
-#ifdef PNG_WRITE_pCAL_SUPPORTED
-/* Write the pCAL chunk (described in the PNG extensions document) */
-void /* PRIVATE */
-png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0,
-    png_int_32 X1, int type, int nparams, png_const_charp units,
-    png_charpp params)
-{
-   png_size_t purpose_len, units_len, total_len;
-   png_size_tp params_len;
-   png_byte buf[10];
-   png_charp new_purpose;
-   int i;
-
-   png_debug1(1, "in png_write_pCAL (%d parameters)", nparams);
-
-   if (type >= PNG_EQUATION_LAST)
-      png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
-
-   purpose_len = png_check_keyword(png_ptr, purpose, &new_purpose) + 1;
-   png_debug1(3, "pCAL purpose length = %d", (int)purpose_len);
-   units_len = png_strlen(units) + (nparams == 0 ? 0 : 1);
-   png_debug1(3, "pCAL units length = %d", (int)units_len);
-   total_len = purpose_len + units_len + 10;
-
-   params_len = (png_size_tp)png_malloc(png_ptr,
-       (png_alloc_size_t)(nparams * png_sizeof(png_size_t)));
-
-   /* Find the length of each parameter, making sure we don't count the
-    * null terminator for the last parameter.
-    */
-   for (i = 0; i < nparams; i++)
-   {
-      params_len[i] = png_strlen(params[i]) + (i == nparams - 1 ? 0 : 1);
-      png_debug2(3, "pCAL parameter %d length = %lu", i,
-          (unsigned long)params_len[i]);
-      total_len += params_len[i];
-   }
-
-   png_debug1(3, "pCAL total length = %d", (int)total_len);
-   png_write_chunk_header(png_ptr, png_pCAL, (png_uint_32)total_len);
-   png_write_chunk_data(png_ptr, (png_const_bytep)new_purpose, purpose_len);
-   png_save_int_32(buf, X0);
-   png_save_int_32(buf + 4, X1);
-   buf[8] = (png_byte)type;
-   buf[9] = (png_byte)nparams;
-   png_write_chunk_data(png_ptr, buf, (png_size_t)10);
-   png_write_chunk_data(png_ptr, (png_const_bytep)units, (png_size_t)units_len);
-
-   png_free(png_ptr, new_purpose);
-
-   for (i = 0; i < nparams; i++)
-   {
-      png_write_chunk_data(png_ptr, (png_const_bytep)params[i], params_len[i]);
-   }
-
-   png_free(png_ptr, params_len);
-   png_write_chunk_end(png_ptr);
-}
-#endif
-
-#ifdef PNG_WRITE_sCAL_SUPPORTED
-/* Write the sCAL chunk */
-void /* PRIVATE */
-png_write_sCAL_s(png_structp png_ptr, int unit, png_const_charp width,
-    png_const_charp height)
-{
-   png_byte buf[64];
-   png_size_t wlen, hlen, total_len;
-
-   png_debug(1, "in png_write_sCAL_s");
-
-   wlen = png_strlen(width);
-   hlen = png_strlen(height);
-   total_len = wlen + hlen + 2;
-
-   if (total_len > 64)
-   {
-      png_warning(png_ptr, "Can't write sCAL (buffer too small)");
-      return;
-   }
-
-   buf[0] = (png_byte)unit;
-   png_memcpy(buf + 1, width, wlen + 1);      /* Append the '\0' here */
-   png_memcpy(buf + wlen + 2, height, hlen);  /* Do NOT append the '\0' here */
-
-   png_debug1(3, "sCAL total length = %u", (unsigned int)total_len);
-   png_write_complete_chunk(png_ptr, png_sCAL, buf, total_len);
-}
-#endif
-
-#ifdef PNG_WRITE_pHYs_SUPPORTED
-/* Write the pHYs chunk */
-void /* PRIVATE */
-png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit,
-    png_uint_32 y_pixels_per_unit,
-    int unit_type)
-{
-   png_byte buf[9];
-
-   png_debug(1, "in png_write_pHYs");
-
-   if (unit_type >= PNG_RESOLUTION_LAST)
-      png_warning(png_ptr, "Unrecognized unit type for pHYs chunk");
-
-   png_save_uint_32(buf, x_pixels_per_unit);
-   png_save_uint_32(buf + 4, y_pixels_per_unit);
-   buf[8] = (png_byte)unit_type;
-
-   png_write_complete_chunk(png_ptr, png_pHYs, buf, (png_size_t)9);
-}
-#endif
-
-#ifdef PNG_WRITE_tIME_SUPPORTED
-/* Write the tIME chunk.  Use either png_convert_from_struct_tm()
- * or png_convert_from_time_t(), or fill in the structure yourself.
- */
-void /* PRIVATE */
-png_write_tIME(png_structp png_ptr, png_const_timep mod_time)
-{
-   png_byte buf[7];
-
-   png_debug(1, "in png_write_tIME");
-
-   if (mod_time->month  > 12 || mod_time->month  < 1 ||
-       mod_time->day    > 31 || mod_time->day    < 1 ||
-       mod_time->hour   > 23 || mod_time->second > 60)
-   {
-      png_warning(png_ptr, "Invalid time specified for tIME chunk");
-      return;
-   }
-
-   png_save_uint_16(buf, mod_time->year);
-   buf[2] = mod_time->month;
-   buf[3] = mod_time->day;
-   buf[4] = mod_time->hour;
-   buf[5] = mod_time->minute;
-   buf[6] = mod_time->second;
-
-   png_write_complete_chunk(png_ptr, png_tIME, buf, (png_size_t)7);
-}
-#endif
-
-/* Initializes the row writing capability of libpng */
-void /* PRIVATE */
-png_write_start_row(png_structp png_ptr)
-{
-#ifdef PNG_WRITE_INTERLACING_SUPPORTED
-   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
-
-   /* Start of interlace block */
-   static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
-
-   /* Offset to next interlace block */
-   static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
-
-   /* Start of interlace block in the y direction */
-   static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
-
-   /* Offset to next interlace block in the y direction */
-   static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
-#endif
-
-   png_alloc_size_t buf_size;
-   int usr_pixel_depth;
-
-   png_debug(1, "in png_write_start_row");
-
-   usr_pixel_depth = png_ptr->usr_channels * png_ptr->usr_bit_depth;
-   buf_size = PNG_ROWBYTES(usr_pixel_depth, png_ptr->width) + 1;
-
-   /* 1.5.6: added to allow checking in the row write code. */
-   png_ptr->transformed_pixel_depth = png_ptr->pixel_depth;
-   png_ptr->maximum_pixel_depth = (png_byte)usr_pixel_depth;
-
-   /* Set up row buffer */
-   png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, buf_size);
-
-   png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE;
-
-#ifdef PNG_WRITE_FILTER_SUPPORTED
-   /* Set up filtering buffer, if using this filter */
-   if (png_ptr->do_filter & PNG_FILTER_SUB)
-   {
-      png_ptr->sub_row = (png_bytep)png_malloc(png_ptr, png_ptr->rowbytes + 1);
-
-      png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
-   }
-
-   /* We only need to keep the previous row if we are using one of these. */
-   if (png_ptr->do_filter & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH))
-   {
-      /* Set up previous row buffer */
-      png_ptr->prev_row = (png_bytep)png_calloc(png_ptr, buf_size);
-
-      if (png_ptr->do_filter & PNG_FILTER_UP)
-      {
-         png_ptr->up_row = (png_bytep)png_malloc(png_ptr,
-            png_ptr->rowbytes + 1);
-
-         png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
-      }
-
-      if (png_ptr->do_filter & PNG_FILTER_AVG)
-      {
-         png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
-             png_ptr->rowbytes + 1);
-
-         png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
-      }
-
-      if (png_ptr->do_filter & PNG_FILTER_PAETH)
-      {
-         png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr,
-             png_ptr->rowbytes + 1);
-
-         png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
-      }
-   }
-#endif /* PNG_WRITE_FILTER_SUPPORTED */
-
-#ifdef PNG_WRITE_INTERLACING_SUPPORTED
-   /* If interlaced, we need to set up width and height of pass */
-   if (png_ptr->interlaced)
-   {
-      if (!(png_ptr->transformations & PNG_INTERLACE))
-      {
-         png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
-             png_pass_ystart[0]) / png_pass_yinc[0];
-
-         png_ptr->usr_width = (png_ptr->width + png_pass_inc[0] - 1 -
-             png_pass_start[0]) / png_pass_inc[0];
-      }
-
-      else
-      {
-         png_ptr->num_rows = png_ptr->height;
-         png_ptr->usr_width = png_ptr->width;
-      }
-   }
-
-   else
-#endif
-   {
-      png_ptr->num_rows = png_ptr->height;
-      png_ptr->usr_width = png_ptr->width;
-   }
-
-   png_zlib_claim(png_ptr, PNG_ZLIB_FOR_IDAT);
-   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
-   png_ptr->zstream.next_out = png_ptr->zbuf;
-}
-
-/* Internal use only.  Called when finished processing a row of data. */
-void /* PRIVATE */
-png_write_finish_row(png_structp png_ptr)
-{
-#ifdef PNG_WRITE_INTERLACING_SUPPORTED
-   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
-
-   /* Start of interlace block */
-   static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
-
-   /* Offset to next interlace block */
-   static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
-
-   /* Start of interlace block in the y direction */
-   static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
-
-   /* Offset to next interlace block in the y direction */
-   static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
-#endif
-
-   int ret;
-
-   png_debug(1, "in png_write_finish_row");
-
-   /* Next row */
-   png_ptr->row_number++;
-
-   /* See if we are done */
-   if (png_ptr->row_number < png_ptr->num_rows)
-      return;
-
-#ifdef PNG_WRITE_INTERLACING_SUPPORTED
-   /* If interlaced, go to next pass */
-   if (png_ptr->interlaced)
-   {
-      png_ptr->row_number = 0;
-      if (png_ptr->transformations & PNG_INTERLACE)
-      {
-         png_ptr->pass++;
-      }
-
-      else
-      {
-         /* Loop until we find a non-zero width or height pass */
-         do
-         {
-            png_ptr->pass++;
-
-            if (png_ptr->pass >= 7)
-               break;
-
-            png_ptr->usr_width = (png_ptr->width +
-                png_pass_inc[png_ptr->pass] - 1 -
-                png_pass_start[png_ptr->pass]) /
-                png_pass_inc[png_ptr->pass];
-
-            png_ptr->num_rows = (png_ptr->height +
-                png_pass_yinc[png_ptr->pass] - 1 -
-                png_pass_ystart[png_ptr->pass]) /
-                png_pass_yinc[png_ptr->pass];
-
-            if (png_ptr->transformations & PNG_INTERLACE)
-               break;
-
-         } while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0);
-
-      }
-
-      /* Reset the row above the image for the next pass */
-      if (png_ptr->pass < 7)
-      {
-         if (png_ptr->prev_row != NULL)
-            png_memset(png_ptr->prev_row, 0,
-                (png_size_t)(PNG_ROWBYTES(png_ptr->usr_channels*
-                png_ptr->usr_bit_depth, png_ptr->width)) + 1);
-
-         return;
-      }
-   }
-#endif
-
-   /* If we get here, we've just written the last row, so we need
-      to flush the compressor */
-   do
-   {
-      /* Tell the compressor we are done */
-      ret = deflate(&png_ptr->zstream, Z_FINISH);
-
-      /* Check for an error */
-      if (ret == Z_OK)
-      {
-         /* Check to see if we need more room */
-         if (!(png_ptr->zstream.avail_out))
-         {
-            png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
-            png_ptr->zstream.next_out = png_ptr->zbuf;
-            png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
-         }
-      }
-
-      else if (ret != Z_STREAM_END)
-      {
-         if (png_ptr->zstream.msg != NULL)
-            png_error(png_ptr, png_ptr->zstream.msg);
-
-         else
-            png_error(png_ptr, "zlib error");
-      }
-   } while (ret != Z_STREAM_END);
-
-   /* Write any extra space */
-   if (png_ptr->zstream.avail_out < png_ptr->zbuf_size)
-   {
-      png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size -
-          png_ptr->zstream.avail_out);
-   }
-
-   png_zlib_release(png_ptr);
-   png_ptr->zstream.data_type = Z_BINARY;
-}
-
-#ifdef PNG_WRITE_INTERLACING_SUPPORTED
-/* Pick out the correct pixels for the interlace pass.
- * The basic idea here is to go through the row with a source
- * pointer and a destination pointer (sp and dp), and copy the
- * correct pixels for the pass.  As the row gets compacted,
- * sp will always be >= dp, so we should never overwrite anything.
- * See the default: case for the easiest code to understand.
- */
-void /* PRIVATE */
-png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
-{
-   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
-
-   /* Start of interlace block */
-   static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
-
-   /* Offset to next interlace block */
-   static PNG_CONST png_byte  png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
-
-   png_debug(1, "in png_do_write_interlace");
-
-   /* We don't have to do anything on the last pass (6) */
-   if (pass < 6)
-   {
-      /* Each pixel depth is handled separately */
-      switch (row_info->pixel_depth)
-      {
-         case 1:
-         {
-            png_bytep sp;
-            png_bytep dp;
-            int shift;
-            int d;
-            int value;
-            png_uint_32 i;
-            png_uint_32 row_width = row_info->width;
-
-            dp = row;
-            d = 0;
-            shift = 7;
-
-            for (i = png_pass_start[pass]; i < row_width;
-               i += png_pass_inc[pass])
-            {
-               sp = row + (png_size_t)(i >> 3);
-               value = (int)(*sp >> (7 - (int)(i & 0x07))) & 0x01;
-               d |= (value << shift);
-
-               if (shift == 0)
-               {
-                  shift = 7;
-                  *dp++ = (png_byte)d;
-                  d = 0;
-               }
-
-               else
-                  shift--;
-
-            }
-            if (shift != 7)
-               *dp = (png_byte)d;
-
-            break;
-         }
-
-         case 2:
-         {
-            png_bytep sp;
-            png_bytep dp;
-            int shift;
-            int d;
-            int value;
-            png_uint_32 i;
-            png_uint_32 row_width = row_info->width;
-
-            dp = row;
-            shift = 6;
-            d = 0;
-
-            for (i = png_pass_start[pass]; i < row_width;
-               i += png_pass_inc[pass])
-            {
-               sp = row + (png_size_t)(i >> 2);
-               value = (*sp >> ((3 - (int)(i & 0x03)) << 1)) & 0x03;
-               d |= (value << shift);
-
-               if (shift == 0)
-               {
-                  shift = 6;
-                  *dp++ = (png_byte)d;
-                  d = 0;
-               }
-
-               else
-                  shift -= 2;
-            }
-            if (shift != 6)
-               *dp = (png_byte)d;
-
-            break;
-         }
-
-         case 4:
-         {
-            png_bytep sp;
-            png_bytep dp;
-            int shift;
-            int d;
-            int value;
-            png_uint_32 i;
-            png_uint_32 row_width = row_info->width;
-
-            dp = row;
-            shift = 4;
-            d = 0;
-            for (i = png_pass_start[pass]; i < row_width;
-                i += png_pass_inc[pass])
-            {
-               sp = row + (png_size_t)(i >> 1);
-               value = (*sp >> ((1 - (int)(i & 0x01)) << 2)) & 0x0f;
-               d |= (value << shift);
-
-               if (shift == 0)
-               {
-                  shift = 4;
-                  *dp++ = (png_byte)d;
-                  d = 0;
-               }
-
-               else
-                  shift -= 4;
-            }
-            if (shift != 4)
-               *dp = (png_byte)d;
-
-            break;
-         }
-
-         default:
-         {
-            png_bytep sp;
-            png_bytep dp;
-            png_uint_32 i;
-            png_uint_32 row_width = row_info->width;
-            png_size_t pixel_bytes;
-
-            /* Start at the beginning */
-            dp = row;
-
-            /* Find out how many bytes each pixel takes up */
-            pixel_bytes = (row_info->pixel_depth >> 3);
-
-            /* Loop through the row, only looking at the pixels that matter */
-            for (i = png_pass_start[pass]; i < row_width;
-               i += png_pass_inc[pass])
-            {
-               /* Find out where the original pixel is */
-               sp = row + (png_size_t)i * pixel_bytes;
-
-               /* Move the pixel */
-               if (dp != sp)
-                  png_memcpy(dp, sp, pixel_bytes);
-
-               /* Next pixel */
-               dp += pixel_bytes;
-            }
-            break;
-         }
-      }
-      /* Set new row width */
-      row_info->width = (row_info->width +
-          png_pass_inc[pass] - 1 -
-          png_pass_start[pass]) /
-          png_pass_inc[pass];
-
-      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
-          row_info->width);
-   }
-}
-#endif
-
-/* This filters the row, chooses which filter to use, if it has not already
- * been specified by the application, and then writes the row out with the
- * chosen filter.
- */
-static void png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row,
-   png_size_t row_bytes);
-
-#define PNG_MAXSUM (((png_uint_32)(-1)) >> 1)
-#define PNG_HISHIFT 10
-#define PNG_LOMASK ((png_uint_32)0xffffL)
-#define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT))
-void /* PRIVATE */
-png_write_find_filter(png_structp png_ptr, png_row_infop row_info)
-{
-   png_bytep best_row;
-#ifdef PNG_WRITE_FILTER_SUPPORTED
-   png_bytep prev_row, row_buf;
-   png_uint_32 mins, bpp;
-   png_byte filter_to_do = png_ptr->do_filter;
-   png_size_t row_bytes = row_info->rowbytes;
-#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
-   int num_p_filters = png_ptr->num_prev_filters;
-#endif
-
-   png_debug(1, "in png_write_find_filter");
-
-#ifndef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
-  if (png_ptr->row_number == 0 && filter_to_do == PNG_ALL_FILTERS)
-  {
-     /* These will never be selected so we need not test them. */
-     filter_to_do &= ~(PNG_FILTER_UP | PNG_FILTER_PAETH);
-  }
-#endif
-
-   /* Find out how many bytes offset each pixel is */
-   bpp = (row_info->pixel_depth + 7) >> 3;
-
-   prev_row = png_ptr->prev_row;
-#endif
-   best_row = png_ptr->row_buf;
-#ifdef PNG_WRITE_FILTER_SUPPORTED
-   row_buf = best_row;
-   mins = PNG_MAXSUM;
-
-   /* The prediction method we use is to find which method provides the
-    * smallest value when summing the absolute values of the distances
-    * from zero, using anything >= 128 as negative numbers.  This is known
-    * as the "minimum sum of absolute differences" heuristic.  Other
-    * heuristics are the "weighted minimum sum of absolute differences"
-    * (experimental and can in theory improve compression), and the "zlib
-    * predictive" method (not implemented yet), which does test compressions
-    * of lines using different filter methods, and then chooses the
-    * (series of) filter(s) that give minimum compressed data size (VERY
-    * computationally expensive).
-    *
-    * GRR 980525:  consider also
-    *
-    *   (1) minimum sum of absolute differences from running average (i.e.,
-    *       keep running sum of non-absolute differences & count of bytes)
-    *       [track dispersion, too?  restart average if dispersion too large?]
-    *
-    *  (1b) minimum sum of absolute differences from sliding average, probably
-    *       with window size <= deflate window (usually 32K)
-    *
-    *   (2) minimum sum of squared differences from zero or running average
-    *       (i.e., ~ root-mean-square approach)
-    */
-
-
-   /* We don't need to test the 'no filter' case if this is the only filter
-    * that has been chosen, as it doesn't actually do anything to the data.
-    */
-   if ((filter_to_do & PNG_FILTER_NONE) && filter_to_do != PNG_FILTER_NONE)
-   {
-      png_bytep rp;
-      png_uint_32 sum = 0;
-      png_size_t i;
-      int v;
-
-      for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++)
-      {
-         v = *rp;
-         sum += (v < 128) ? v : 256 - v;
-      }
-
-#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
-      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
-      {
-         png_uint_32 sumhi, sumlo;
-         int j;
-         sumlo = sum & PNG_LOMASK;
-         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; /* Gives us some footroom */
-
-         /* Reduce the sum if we match any of the previous rows */
-         for (j = 0; j < num_p_filters; j++)
-         {
-            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE)
-            {
-               sumlo = (sumlo * png_ptr->filter_weights[j]) >>
-                   PNG_WEIGHT_SHIFT;
-
-               sumhi = (sumhi * png_ptr->filter_weights[j]) >>
-                   PNG_WEIGHT_SHIFT;
-            }
-         }
-
-         /* Factor in the cost of this filter (this is here for completeness,
-          * but it makes no sense to have a "cost" for the NONE filter, as
-          * it has the minimum possible computational cost - none).
-          */
-         sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >>
-             PNG_COST_SHIFT;
-
-         sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >>
-             PNG_COST_SHIFT;
-
-         if (sumhi > PNG_HIMASK)
-            sum = PNG_MAXSUM;
-
-         else
-            sum = (sumhi << PNG_HISHIFT) + sumlo;
-      }
-#endif
-      mins = sum;
-   }
-
-   /* Sub filter */
-   if (filter_to_do == PNG_FILTER_SUB)
-   /* It's the only filter so no testing is needed */
-   {
-      png_bytep rp, lp, dp;
-      png_size_t i;
-
-      for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
-           i++, rp++, dp++)
-      {
-         *dp = *rp;
-      }
-
-      for (lp = row_buf + 1; i < row_bytes;
-         i++, rp++, lp++, dp++)
-      {
-         *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
-      }
-
-      best_row = png_ptr->sub_row;
-   }
-
-   else if (filter_to_do & PNG_FILTER_SUB)
-   {
-      png_bytep rp, dp, lp;
-      png_uint_32 sum = 0, lmins = mins;
-      png_size_t i;
-      int v;
-
-#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
-      /* We temporarily increase the "minimum sum" by the factor we
-       * would reduce the sum of this filter, so that we can do the
-       * early exit comparison without scaling the sum each time.
-       */
-      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
-      {
-         int j;
-         png_uint_32 lmhi, lmlo;
-         lmlo = lmins & PNG_LOMASK;
-         lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
-
-         for (j = 0; j < num_p_filters; j++)
-         {
-            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB)
-            {
-               lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
-                   PNG_WEIGHT_SHIFT;
-
-               lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
-                   PNG_WEIGHT_SHIFT;
-            }
-         }
-
-         lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
-             PNG_COST_SHIFT;
-
-         lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
-             PNG_COST_SHIFT;
-
-         if (lmhi > PNG_HIMASK)
-            lmins = PNG_MAXSUM;
-
-         else
-            lmins = (lmhi << PNG_HISHIFT) + lmlo;
-      }
-#endif
-
-      for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
-           i++, rp++, dp++)
-      {
-         v = *dp = *rp;
-
-         sum += (v < 128) ? v : 256 - v;
-      }
-
-      for (lp = row_buf + 1; i < row_bytes;
-         i++, rp++, lp++, dp++)
-      {
-         v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
-
-         sum += (v < 128) ? v : 256 - v;
-
-         if (sum > lmins)  /* We are already worse, don't continue. */
-            break;
-      }
-
-#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
-      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
-      {
-         int j;
-         png_uint_32 sumhi, sumlo;
-         sumlo = sum & PNG_LOMASK;
-         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
-
-         for (j = 0; j < num_p_filters; j++)
-         {
-            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB)
-            {
-               sumlo = (sumlo * png_ptr->inv_filter_weights[j]) >>
-                   PNG_WEIGHT_SHIFT;
-
-               sumhi = (sumhi * png_ptr->inv_filter_weights[j]) >>
-                   PNG_WEIGHT_SHIFT;
-            }
-         }
-
-         sumlo = (sumlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
-             PNG_COST_SHIFT;
-
-         sumhi = (sumhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
-             PNG_COST_SHIFT;
-
-         if (sumhi > PNG_HIMASK)
-            sum = PNG_MAXSUM;
-
-         else
-            sum = (sumhi << PNG_HISHIFT) + sumlo;
-      }
-#endif
-
-      if (sum < mins)
-      {
-         mins = sum;
-         best_row = png_ptr->sub_row;
-      }
-   }
-
-   /* Up filter */
-   if (filter_to_do == PNG_FILTER_UP)
-   {
-      png_bytep rp, dp, pp;
-      png_size_t i;
-
-      for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
-          pp = prev_row + 1; i < row_bytes;
-          i++, rp++, pp++, dp++)
-      {
-         *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
-      }
-
-      best_row = png_ptr->up_row;
-   }
-
-   else if (filter_to_do & PNG_FILTER_UP)
-   {
-      png_bytep rp, dp, pp;
-      png_uint_32 sum = 0, lmins = mins;
-      png_size_t i;
-      int v;
-
-
-#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
-      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
-      {
-         int j;
-         png_uint_32 lmhi, lmlo;
-         lmlo = lmins & PNG_LOMASK;
-         lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
-
-         for (j = 0; j < num_p_filters; j++)
-         {
-            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP)
-            {
-               lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
-                   PNG_WEIGHT_SHIFT;
-
-               lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
-                   PNG_WEIGHT_SHIFT;
-            }
-         }
-
-         lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >>
-             PNG_COST_SHIFT;
-
-         lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >>
-             PNG_COST_SHIFT;
-
-         if (lmhi > PNG_HIMASK)
-            lmins = PNG_MAXSUM;
-
-         else
-            lmins = (lmhi << PNG_HISHIFT) + lmlo;
-      }
-#endif
-
-      for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
-          pp = prev_row + 1; i < row_bytes; i++)
-      {
-         v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
-
-         sum += (v < 128) ? v : 256 - v;
-
-         if (sum > lmins)  /* We are already worse, don't continue. */
-            break;
-      }
-
-#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
-      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
-      {
-         int j;
-         png_uint_32 sumhi, sumlo;
-         sumlo = sum & PNG_LOMASK;
-         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
-
-         for (j = 0; j < num_p_filters; j++)
-         {
-            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP)
-            {
-               sumlo = (sumlo * png_ptr->filter_weights[j]) >>
-                   PNG_WEIGHT_SHIFT;
-
-               sumhi = (sumhi * png_ptr->filter_weights[j]) >>
-                   PNG_WEIGHT_SHIFT;
-            }
-         }
-
-         sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >>
-             PNG_COST_SHIFT;
-
-         sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >>
-             PNG_COST_SHIFT;
-
-         if (sumhi > PNG_HIMASK)
-            sum = PNG_MAXSUM;
-
-         else
-            sum = (sumhi << PNG_HISHIFT) + sumlo;
-      }
-#endif
-
-      if (sum < mins)
-      {
-         mins = sum;
-         best_row = png_ptr->up_row;
-      }
-   }
-
-   /* Avg filter */
-   if (filter_to_do == PNG_FILTER_AVG)
-   {
-      png_bytep rp, dp, pp, lp;
-      png_uint_32 i;
-
-      for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
-           pp = prev_row + 1; i < bpp; i++)
-      {
-         *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
-      }
-
-      for (lp = row_buf + 1; i < row_bytes; i++)
-      {
-         *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2))
-                 & 0xff);
-      }
-      best_row = png_ptr->avg_row;
-   }
-
-   else if (filter_to_do & PNG_FILTER_AVG)
-   {
-      png_bytep rp, dp, pp, lp;
-      png_uint_32 sum = 0, lmins = mins;
-      png_size_t i;
-      int v;
-
-#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
-      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
-      {
-         int j;
-         png_uint_32 lmhi, lmlo;
-         lmlo = lmins & PNG_LOMASK;
-         lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
-
-         for (j = 0; j < num_p_filters; j++)
-         {
-            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_AVG)
-            {
-               lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
-                   PNG_WEIGHT_SHIFT;
-
-               lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
-                   PNG_WEIGHT_SHIFT;
-            }
-         }
-
-         lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >>
-             PNG_COST_SHIFT;
-
-         lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >>
-             PNG_COST_SHIFT;
-
-         if (lmhi > PNG_HIMASK)
-            lmins = PNG_MAXSUM;
-
-         else
-            lmins = (lmhi << PNG_HISHIFT) + lmlo;
-      }
-#endif
-
-      for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
-           pp = prev_row + 1; i < bpp; i++)
-      {
-         v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
-
-         sum += (v < 128) ? v : 256 - v;
-      }
-
-      for (lp = row_buf + 1; i < row_bytes; i++)
-      {
-         v = *dp++ =
-             (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) & 0xff);
-
-         sum += (v < 128) ? v : 256 - v;
-
-         if (sum > lmins)  /* We are already worse, don't continue. */
-            break;
-      }
-
-#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
-      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
-      {
-         int j;
-         png_uint_32 sumhi, sumlo;
-         sumlo = sum & PNG_LOMASK;
-         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
-
-         for (j = 0; j < num_p_filters; j++)
-         {
-            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE)
-            {
-               sumlo = (sumlo * png_ptr->filter_weights[j]) >>
-                   PNG_WEIGHT_SHIFT;
-
-               sumhi = (sumhi * png_ptr->filter_weights[j]) >>
-                   PNG_WEIGHT_SHIFT;
-            }
-         }
-
-         sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >>
-             PNG_COST_SHIFT;
-
-         sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >>
-             PNG_COST_SHIFT;
-
-         if (sumhi > PNG_HIMASK)
-            sum = PNG_MAXSUM;
-
-         else
-            sum = (sumhi << PNG_HISHIFT) + sumlo;
-      }
-#endif
-
-      if (sum < mins)
-      {
-         mins = sum;
-         best_row = png_ptr->avg_row;
-      }
-   }
-
-   /* Paeth filter */
-   if (filter_to_do == PNG_FILTER_PAETH)
-   {
-      png_bytep rp, dp, pp, cp, lp;
-      png_size_t i;
-
-      for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
-          pp = prev_row + 1; i < bpp; i++)
-      {
-         *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
-      }
-
-      for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++)
-      {
-         int a, b, c, pa, pb, pc, p;
-
-         b = *pp++;
-         c = *cp++;
-         a = *lp++;
-
-         p = b - c;
-         pc = a - c;
-
-#ifdef PNG_USE_ABS
-         pa = abs(p);
-         pb = abs(pc);
-         pc = abs(p + pc);
-#else
-         pa = p < 0 ? -p : p;
-         pb = pc < 0 ? -pc : pc;
-         pc = (p + pc) < 0 ? -(p + pc) : p + pc;
-#endif
-
-         p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
-
-         *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
-      }
-      best_row = png_ptr->paeth_row;
-   }
-
-   else if (filter_to_do & PNG_FILTER_PAETH)
-   {
-      png_bytep rp, dp, pp, cp, lp;
-      png_uint_32 sum = 0, lmins = mins;
-      png_size_t i;
-      int v;
-
-#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
-      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
-      {
-         int j;
-         png_uint_32 lmhi, lmlo;
-         lmlo = lmins & PNG_LOMASK;
-         lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
-
-         for (j = 0; j < num_p_filters; j++)
-         {
-            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH)
-            {
-               lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
-                   PNG_WEIGHT_SHIFT;
-
-               lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
-                   PNG_WEIGHT_SHIFT;
-            }
-         }
-
-         lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >>
-             PNG_COST_SHIFT;
-
-         lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >>
-             PNG_COST_SHIFT;
-
-         if (lmhi > PNG_HIMASK)
-            lmins = PNG_MAXSUM;
-
-         else
-            lmins = (lmhi << PNG_HISHIFT) + lmlo;
-      }
-#endif
-
-      for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
-          pp = prev_row + 1; i < bpp; i++)
-      {
-         v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
-
-         sum += (v < 128) ? v : 256 - v;
-      }
-
-      for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++)
-      {
-         int a, b, c, pa, pb, pc, p;
-
-         b = *pp++;
-         c = *cp++;
-         a = *lp++;
-
-#ifndef PNG_SLOW_PAETH
-         p = b - c;
-         pc = a - c;
-#ifdef PNG_USE_ABS
-         pa = abs(p);
-         pb = abs(pc);
-         pc = abs(p + pc);
-#else
-         pa = p < 0 ? -p : p;
-         pb = pc < 0 ? -pc : pc;
-         pc = (p + pc) < 0 ? -(p + pc) : p + pc;
-#endif
-         p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
-#else /* PNG_SLOW_PAETH */
-         p = a + b - c;
-         pa = abs(p - a);
-         pb = abs(p - b);
-         pc = abs(p - c);
-
-         if (pa <= pb && pa <= pc)
-            p = a;
-
-         else if (pb <= pc)
-            p = b;
-
-         else
-            p = c;
-#endif /* PNG_SLOW_PAETH */
-
-         v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
-
-         sum += (v < 128) ? v : 256 - v;
-
-         if (sum > lmins)  /* We are already worse, don't continue. */
-            break;
-      }
-
-#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
-      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
-      {
-         int j;
-         png_uint_32 sumhi, sumlo;
-         sumlo = sum & PNG_LOMASK;
-         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
-
-         for (j = 0; j < num_p_filters; j++)
-         {
-            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH)
-            {
-               sumlo = (sumlo * png_ptr->filter_weights[j]) >>
-                   PNG_WEIGHT_SHIFT;
-
-               sumhi = (sumhi * png_ptr->filter_weights[j]) >>
-                   PNG_WEIGHT_SHIFT;
-            }
-         }
-
-         sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >>
-             PNG_COST_SHIFT;
-
-         sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >>
-             PNG_COST_SHIFT;
-
-         if (sumhi > PNG_HIMASK)
-            sum = PNG_MAXSUM;
-
-         else
-            sum = (sumhi << PNG_HISHIFT) + sumlo;
-      }
-#endif
-
-      if (sum < mins)
-      {
-         best_row = png_ptr->paeth_row;
-      }
-   }
-#endif /* PNG_WRITE_FILTER_SUPPORTED */
-
-   /* Do the actual writing of the filtered row data from the chosen filter. */
-   png_write_filtered_row(png_ptr, best_row, row_info->rowbytes+1);
-
-#ifdef PNG_WRITE_FILTER_SUPPORTED
-#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
-   /* Save the type of filter we picked this time for future calculations */
-   if (png_ptr->num_prev_filters > 0)
-   {
-      int j;
-
-      for (j = 1; j < num_p_filters; j++)
-      {
-         png_ptr->prev_filters[j] = png_ptr->prev_filters[j - 1];
-      }
-
-      png_ptr->prev_filters[j] = best_row[0];
-   }
-#endif
-#endif /* PNG_WRITE_FILTER_SUPPORTED */
-}
-
-
-/* Do the actual writing of a previously filtered row. */
-static void
-png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row,
-   png_size_t avail/*includes filter byte*/)
-{
-   png_debug(1, "in png_write_filtered_row");
-
-   png_debug1(2, "filter = %d", filtered_row[0]);
-   /* Set up the zlib input buffer */
-
-   png_ptr->zstream.next_in = filtered_row;
-   png_ptr->zstream.avail_in = 0;
-   /* Repeat until we have compressed all the data */
-   do
-   {
-      int ret; /* Return of zlib */
-
-      /* Record the number of bytes available - zlib supports at least 65535
-       * bytes at one step, depending on the size of the zlib type 'uInt', the
-       * maximum size zlib can write at once is ZLIB_IO_MAX (from pngpriv.h).
-       * Use this because on 16 bit systems 'rowbytes' can be up to 65536 (i.e.
-       * one more than 16 bits) and, in this case 'rowbytes+1' can overflow a
-       * uInt.  ZLIB_IO_MAX can be safely reduced to cause zlib to be called
-       * with smaller chunks of data.
-       */
-      if (png_ptr->zstream.avail_in == 0)
-      {
-         if (avail > ZLIB_IO_MAX)
-         {
-            png_ptr->zstream.avail_in  = ZLIB_IO_MAX;
-            avail -= ZLIB_IO_MAX;
-         }
-
-         else
-         {
-            /* So this will fit in the available uInt space: */
-            png_ptr->zstream.avail_in = (uInt)avail;
-            avail = 0;
-         }
-      }
-
-      /* Compress the data */
-      ret = deflate(&png_ptr->zstream, Z_NO_FLUSH);
-
-      /* Check for compression errors */
-      if (ret != Z_OK)
-      {
-         if (png_ptr->zstream.msg != NULL)
-            png_error(png_ptr, png_ptr->zstream.msg);
-
-         else
-            png_error(png_ptr, "zlib error");
-      }
-
-      /* See if it is time to write another IDAT */
-      if (!(png_ptr->zstream.avail_out))
-      {
-         /* Write the IDAT and reset the zlib output buffer */
-         png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
-      }
-   /* Repeat until all data has been compressed */
-   } while (avail > 0 || png_ptr->zstream.avail_in > 0);
-
-   /* Swap the current and previous rows */
-   if (png_ptr->prev_row != NULL)
-   {
-      png_bytep tptr;
-
-      tptr = png_ptr->prev_row;
-      png_ptr->prev_row = png_ptr->row_buf;
-      png_ptr->row_buf = tptr;
-   }
-
-   /* Finish row - updates counters and flushes zlib if last row */
-   png_write_finish_row(png_ptr);
-
-#ifdef PNG_WRITE_FLUSH_SUPPORTED
-   png_ptr->flush_rows++;
-
-   if (png_ptr->flush_dist > 0 &&
-       png_ptr->flush_rows >= png_ptr->flush_dist)
-   {
-      png_write_flush(png_ptr);
-   }
-#endif
-}
-#endif /* PNG_WRITE_SUPPORTED */
+
+/* pngwutil.c - utilities to write a PNG file
+ *
+ * Last changed in libpng 1.6.15 [November 20, 2014]
+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+#include "pngpriv.h"
+
+#ifdef PNG_WRITE_SUPPORTED
+
+#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED
+/* Place a 32-bit number into a buffer in PNG byte order.  We work
+ * with unsigned numbers for convenience, although one supported
+ * ancillary chunk uses signed (two's complement) numbers.
+ */
+void PNGAPI
+png_save_uint_32(png_bytep buf, png_uint_32 i)
+{
+   buf[0] = (png_byte)((i >> 24) & 0xff);
+   buf[1] = (png_byte)((i >> 16) & 0xff);
+   buf[2] = (png_byte)((i >> 8) & 0xff);
+   buf[3] = (png_byte)(i & 0xff);
+}
+
+/* Place a 16-bit number into a buffer in PNG byte order.
+ * The parameter is declared unsigned int, not png_uint_16,
+ * just to avoid potential problems on pre-ANSI C compilers.
+ */
+void PNGAPI
+png_save_uint_16(png_bytep buf, unsigned int i)
+{
+   buf[0] = (png_byte)((i >> 8) & 0xff);
+   buf[1] = (png_byte)(i & 0xff);
+}
+#endif
+
+/* Simple function to write the signature.  If we have already written
+ * the magic bytes of the signature, or more likely, the PNG stream is
+ * being embedded into another stream and doesn't need its own signature,
+ * we should call png_set_sig_bytes() to tell libpng how many of the
+ * bytes have already been written.
+ */
+void PNGAPI
+png_write_sig(png_structrp png_ptr)
+{
+   png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
+
+#ifdef PNG_IO_STATE_SUPPORTED
+   /* Inform the I/O callback that the signature is being written */
+   png_ptr->io_state = PNG_IO_WRITING | PNG_IO_SIGNATURE;
+#endif
+
+   /* Write the rest of the 8 byte signature */
+   png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes],
+      (png_size_t)(8 - png_ptr->sig_bytes));
+
+   if (png_ptr->sig_bytes < 3)
+      png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
+}
+
+/* Write the start of a PNG chunk.  The type is the chunk type.
+ * The total_length is the sum of the lengths of all the data you will be
+ * passing in png_write_chunk_data().
+ */
+static void
+png_write_chunk_header(png_structrp png_ptr, png_uint_32 chunk_name,
+    png_uint_32 length)
+{
+   png_byte buf[8];
+
+#if defined(PNG_DEBUG) && (PNG_DEBUG > 0)
+   PNG_CSTRING_FROM_CHUNK(buf, chunk_name);
+   png_debug2(0, "Writing %s chunk, length = %lu", buf, (unsigned long)length);
+#endif
+
+   if (png_ptr == NULL)
+      return;
+
+#ifdef PNG_IO_STATE_SUPPORTED
+   /* Inform the I/O callback that the chunk header is being written.
+    * PNG_IO_CHUNK_HDR requires a single I/O call.
+    */
+   png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_HDR;
+#endif
+
+   /* Write the length and the chunk name */
+   png_save_uint_32(buf, length);
+   png_save_uint_32(buf + 4, chunk_name);
+   png_write_data(png_ptr, buf, 8);
+
+   /* Put the chunk name into png_ptr->chunk_name */
+   png_ptr->chunk_name = chunk_name;
+
+   /* Reset the crc and run it over the chunk name */
+   png_reset_crc(png_ptr);
+
+   png_calculate_crc(png_ptr, buf + 4, 4);
+
+#ifdef PNG_IO_STATE_SUPPORTED
+   /* Inform the I/O callback that chunk data will (possibly) be written.
+    * PNG_IO_CHUNK_DATA does NOT require a specific number of I/O calls.
+    */
+   png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_DATA;
+#endif
+}
+
+void PNGAPI
+png_write_chunk_start(png_structrp png_ptr, png_const_bytep chunk_string,
+    png_uint_32 length)
+{
+   png_write_chunk_header(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), length);
+}
+
+/* Write the data of a PNG chunk started with png_write_chunk_header().
+ * Note that multiple calls to this function are allowed, and that the
+ * sum of the lengths from these calls *must* add up to the total_length
+ * given to png_write_chunk_header().
+ */
+void PNGAPI
+png_write_chunk_data(png_structrp png_ptr, png_const_bytep data,
+    png_size_t length)
+{
+   /* Write the data, and run the CRC over it */
+   if (png_ptr == NULL)
+      return;
+
+   if (data != NULL && length > 0)
+   {
+      png_write_data(png_ptr, data, length);
+
+      /* Update the CRC after writing the data,
+       * in case the user I/O routine alters it.
+       */
+      png_calculate_crc(png_ptr, data, length);
+   }
+}
+
+/* Finish a chunk started with png_write_chunk_header(). */
+void PNGAPI
+png_write_chunk_end(png_structrp png_ptr)
+{
+   png_byte buf[4];
+
+   if (png_ptr == NULL) return;
+
+#ifdef PNG_IO_STATE_SUPPORTED
+   /* Inform the I/O callback that the chunk CRC is being written.
+    * PNG_IO_CHUNK_CRC requires a single I/O function call.
+    */
+   png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_CRC;
+#endif
+
+   /* Write the crc in a single operation */
+   png_save_uint_32(buf, png_ptr->crc);
+
+   png_write_data(png_ptr, buf, (png_size_t)4);
+}
+
+/* Write a PNG chunk all at once.  The type is an array of ASCII characters
+ * representing the chunk name.  The array must be at least 4 bytes in
+ * length, and does not need to be null terminated.  To be safe, pass the
+ * pre-defined chunk names here, and if you need a new one, define it
+ * where the others are defined.  The length is the length of the data.
+ * All the data must be present.  If that is not possible, use the
+ * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end()
+ * functions instead.
+ */
+static void
+png_write_complete_chunk(png_structrp png_ptr, png_uint_32 chunk_name,
+   png_const_bytep data, png_size_t length)
+{
+   if (png_ptr == NULL)
+      return;
+
+   /* On 64 bit architectures 'length' may not fit in a png_uint_32. */
+   if (length > PNG_UINT_31_MAX)
+      png_error(png_ptr, "length exceeds PNG maximum");
+
+   png_write_chunk_header(png_ptr, chunk_name, (png_uint_32)length);
+   png_write_chunk_data(png_ptr, data, length);
+   png_write_chunk_end(png_ptr);
+}
+
+/* This is the API that calls the internal function above. */
+void PNGAPI
+png_write_chunk(png_structrp png_ptr, png_const_bytep chunk_string,
+   png_const_bytep data, png_size_t length)
+{
+   png_write_complete_chunk(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), data,
+      length);
+}
+
+/* This is used below to find the size of an image to pass to png_deflate_claim,
+ * so it only needs to be accurate if the size is less than 16384 bytes (the
+ * point at which a lower LZ window size can be used.)
+ */
+static png_alloc_size_t
+png_image_size(png_structrp png_ptr)
+{
+   /* Only return sizes up to the maximum of a png_uint_32; do this by limiting
+    * the width and height used to 15 bits.
+    */
+   png_uint_32 h = png_ptr->height;
+
+   if (png_ptr->rowbytes < 32768 && h < 32768)
+   {
+      if (png_ptr->interlaced != 0)
+      {
+         /* Interlacing makes the image larger because of the replication of
+          * both the filter byte and the padding to a byte boundary.
+          */
+         png_uint_32 w = png_ptr->width;
+         unsigned int pd = png_ptr->pixel_depth;
+         png_alloc_size_t cb_base;
+         int pass;
+
+         for (cb_base=0, pass=0; pass<=6; ++pass)
+         {
+            png_uint_32 pw = PNG_PASS_COLS(w, pass);
+
+            if (pw > 0)
+               cb_base += (PNG_ROWBYTES(pd, pw)+1) * PNG_PASS_ROWS(h, pass);
+         }
+
+         return cb_base;
+      }
+
+      else
+         return (png_ptr->rowbytes+1) * h;
+   }
+
+   else
+      return 0xffffffffU;
+}
+
+#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
+   /* This is the code to hack the first two bytes of the deflate stream (the
+    * deflate header) to correct the windowBits value to match the actual data
+    * size.  Note that the second argument is the *uncompressed* size but the
+    * first argument is the *compressed* data (and it must be deflate
+    * compressed.)
+    */
+static void
+optimize_cmf(png_bytep data, png_alloc_size_t data_size)
+{
+   /* Optimize the CMF field in the zlib stream.  The resultant zlib stream is
+    * still compliant to the stream specification.
+    */
+   if (data_size <= 16384) /* else windowBits must be 15 */
+   {
+      unsigned int z_cmf = data[0];  /* zlib compression method and flags */
+
+      if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70)
+      {
+         unsigned int z_cinfo;
+         unsigned int half_z_window_size;
+
+         z_cinfo = z_cmf >> 4;
+         half_z_window_size = 1U << (z_cinfo + 7);
+
+         if (data_size <= half_z_window_size) /* else no change */
+         {
+            unsigned int tmp;
+
+            do
+            {
+               half_z_window_size >>= 1;
+               --z_cinfo;
+            }
+            while (z_cinfo > 0 && data_size <= half_z_window_size);
+
+            z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4);
+
+            data[0] = (png_byte)z_cmf;
+            tmp = data[1] & 0xe0;
+            tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f;
+            data[1] = (png_byte)tmp;
+         }
+      }
+   }
+}
+#endif /* WRITE_OPTIMIZE_CMF */
+
+/* Initialize the compressor for the appropriate type of compression. */
+static int
+png_deflate_claim(png_structrp png_ptr, png_uint_32 owner,
+   png_alloc_size_t data_size)
+{
+   if (png_ptr->zowner != 0)
+   {
+#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_ERROR_TEXT_SUPPORTED)
+      char msg[64];
+
+      PNG_STRING_FROM_CHUNK(msg, owner);
+      msg[4] = ':';
+      msg[5] = ' ';
+      PNG_STRING_FROM_CHUNK(msg+6, png_ptr->zowner);
+      /* So the message that results is "<chunk> using zstream"; this is an
+       * internal error, but is very useful for debugging.  i18n requirements
+       * are minimal.
+       */
+      (void)png_safecat(msg, (sizeof msg), 10, " using zstream");
+#endif
+#if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC
+         png_warning(png_ptr, msg);
+
+         /* Attempt sane error recovery */
+         if (png_ptr->zowner == png_IDAT) /* don't steal from IDAT */
+         {
+            png_ptr->zstream.msg = PNGZ_MSG_CAST("in use by IDAT");
+            return Z_STREAM_ERROR;
+         }
+
+         png_ptr->zowner = 0;
+#else
+         png_error(png_ptr, msg);
+#endif
+   }
+
+   {
+      int level = png_ptr->zlib_level;
+      int method = png_ptr->zlib_method;
+      int windowBits = png_ptr->zlib_window_bits;
+      int memLevel = png_ptr->zlib_mem_level;
+      int strategy; /* set below */
+      int ret; /* zlib return code */
+
+      if (owner == png_IDAT)
+      {
+         if ((png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY) != 0)
+            strategy = png_ptr->zlib_strategy;
+
+         else if (png_ptr->do_filter != PNG_FILTER_NONE)
+            strategy = PNG_Z_DEFAULT_STRATEGY;
+
+         else
+            strategy = PNG_Z_DEFAULT_NOFILTER_STRATEGY;
+      }
+
+      else
+      {
+#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
+            level = png_ptr->zlib_text_level;
+            method = png_ptr->zlib_text_method;
+            windowBits = png_ptr->zlib_text_window_bits;
+            memLevel = png_ptr->zlib_text_mem_level;
+            strategy = png_ptr->zlib_text_strategy;
+#else
+            /* If customization is not supported the values all come from the
+             * IDAT values except for the strategy, which is fixed to the
+             * default.  (This is the pre-1.6.0 behavior too, although it was
+             * implemented in a very different way.)
+             */
+            strategy = Z_DEFAULT_STRATEGY;
+#endif
+      }
+
+      /* Adjust 'windowBits' down if larger than 'data_size'; to stop this
+       * happening just pass 32768 as the data_size parameter.  Notice that zlib
+       * requires an extra 262 bytes in the window in addition to the data to be
+       * able to see the whole of the data, so if data_size+262 takes us to the
+       * next windowBits size we need to fix up the value later.  (Because even
+       * though deflate needs the extra window, inflate does not!)
+       */
+      if (data_size <= 16384)
+      {
+         /* IMPLEMENTATION NOTE: this 'half_window_size' stuff is only here to
+          * work round a Microsoft Visual C misbehavior which, contrary to C-90,
+          * widens the result of the following shift to 64-bits if (and,
+          * apparently, only if) it is used in a test.
+          */
+         unsigned int half_window_size = 1U << (windowBits-1);
+
+         while (data_size + 262 <= half_window_size)
+         {
+            half_window_size >>= 1;
+            --windowBits;
+         }
+      }
+
+      /* Check against the previous initialized values, if any. */
+      if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0 &&
+         (png_ptr->zlib_set_level != level ||
+         png_ptr->zlib_set_method != method ||
+         png_ptr->zlib_set_window_bits != windowBits ||
+         png_ptr->zlib_set_mem_level != memLevel ||
+         png_ptr->zlib_set_strategy != strategy))
+      {
+         if (deflateEnd(&png_ptr->zstream) != Z_OK)
+            png_warning(png_ptr, "deflateEnd failed (ignored)");
+
+         png_ptr->flags &= ~PNG_FLAG_ZSTREAM_INITIALIZED;
+      }
+
+      /* For safety clear out the input and output pointers (currently zlib
+       * doesn't use them on Init, but it might in the future).
+       */
+      png_ptr->zstream.next_in = NULL;
+      png_ptr->zstream.avail_in = 0;
+      png_ptr->zstream.next_out = NULL;
+      png_ptr->zstream.avail_out = 0;
+
+      /* Now initialize if required, setting the new parameters, otherwise just
+       * to a simple reset to the previous parameters.
+       */
+      if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0)
+         ret = deflateReset(&png_ptr->zstream);
+
+      else
+      {
+         ret = deflateInit2(&png_ptr->zstream, level, method, windowBits,
+            memLevel, strategy);
+
+         if (ret == Z_OK)
+            png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED;
+      }
+
+      /* The return code is from either deflateReset or deflateInit2; they have
+       * pretty much the same set of error codes.
+       */
+      if (ret == Z_OK)
+         png_ptr->zowner = owner;
+
+      else
+         png_zstream_error(png_ptr, ret);
+
+      return ret;
+   }
+}
+
+/* Clean up (or trim) a linked list of compression buffers. */
+void /* PRIVATE */
+png_free_buffer_list(png_structrp png_ptr, png_compression_bufferp *listp)
+{
+   png_compression_bufferp list = *listp;
+
+   if (list != NULL)
+   {
+      *listp = NULL;
+
+      do
+      {
+         png_compression_bufferp next = list->next;
+
+         png_free(png_ptr, list);
+         list = next;
+      }
+      while (list != NULL);
+   }
+}
+
+#ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED
+/* This pair of functions encapsulates the operation of (a) compressing a
+ * text string, and (b) issuing it later as a series of chunk data writes.
+ * The compression_state structure is shared context for these functions
+ * set up by the caller to allow access to the relevant local variables.
+ *
+ * compression_buffer (new in 1.6.0) is just a linked list of zbuffer_size
+ * temporary buffers.  From 1.6.0 it is retained in png_struct so that it will
+ * be correctly freed in the event of a write error (previous implementations
+ * just leaked memory.)
+ */
+typedef struct
+{
+   png_const_bytep      input;        /* The uncompressed input data */
+   png_alloc_size_t     input_len;    /* Its length */
+   png_uint_32          output_len;   /* Final compressed length */
+   png_byte             output[1024]; /* First block of output */
+} compression_state;
+
+static void
+png_text_compress_init(compression_state *comp, png_const_bytep input,
+   png_alloc_size_t input_len)
+{
+   comp->input = input;
+   comp->input_len = input_len;
+   comp->output_len = 0;
+}
+
+/* Compress the data in the compression state input */
+static int
+png_text_compress(png_structrp png_ptr, png_uint_32 chunk_name,
+   compression_state *comp, png_uint_32 prefix_len)
+{
+   int ret;
+
+   /* To find the length of the output it is necessary to first compress the
+    * input. The result is buffered rather than using the two-pass algorithm
+    * that is used on the inflate side; deflate is assumed to be slower and a
+    * PNG writer is assumed to have more memory available than a PNG reader.
+    *
+    * IMPLEMENTATION NOTE: the zlib API deflateBound() can be used to find an
+    * upper limit on the output size, but it is always bigger than the input
+    * size so it is likely to be more efficient to use this linked-list
+    * approach.
+    */
+   ret = png_deflate_claim(png_ptr, chunk_name, comp->input_len);
+
+   if (ret != Z_OK)
+      return ret;
+
+   /* Set up the compression buffers, we need a loop here to avoid overflowing a
+    * uInt.  Use ZLIB_IO_MAX to limit the input.  The output is always limited
+    * by the output buffer size, so there is no need to check that.  Since this
+    * is ANSI-C we know that an 'int', hence a uInt, is always at least 16 bits
+    * in size.
+    */
+   {
+      png_compression_bufferp *end = &png_ptr->zbuffer_list;
+      png_alloc_size_t input_len = comp->input_len; /* may be zero! */
+      png_uint_32 output_len;
+
+      /* zlib updates these for us: */
+      png_ptr->zstream.next_in = PNGZ_INPUT_CAST(comp->input);
+      png_ptr->zstream.avail_in = 0; /* Set below */
+      png_ptr->zstream.next_out = comp->output;
+      png_ptr->zstream.avail_out = (sizeof comp->output);
+
+      output_len = png_ptr->zstream.avail_out;
+
+      do
+      {
+         uInt avail_in = ZLIB_IO_MAX;
+
+         if (avail_in > input_len)
+            avail_in = (uInt)input_len;
+
+         input_len -= avail_in;
+
+         png_ptr->zstream.avail_in = avail_in;
+
+         if (png_ptr->zstream.avail_out == 0)
+         {
+            png_compression_buffer *next;
+
+            /* Chunk data is limited to 2^31 bytes in length, so the prefix
+             * length must be counted here.
+             */
+            if (output_len + prefix_len > PNG_UINT_31_MAX)
+            {
+               ret = Z_MEM_ERROR;
+               break;
+            }
+
+            /* Need a new (malloc'ed) buffer, but there may be one present
+             * already.
+             */
+            next = *end;
+            if (next == NULL)
+            {
+               next = png_voidcast(png_compression_bufferp, png_malloc_base
+                  (png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr)));
+
+               if (next == NULL)
+               {
+                  ret = Z_MEM_ERROR;
+                  break;
+               }
+
+               /* Link in this buffer (so that it will be freed later) */
+               next->next = NULL;
+               *end = next;
+            }
+
+            png_ptr->zstream.next_out = next->output;
+            png_ptr->zstream.avail_out = png_ptr->zbuffer_size;
+            output_len += png_ptr->zstream.avail_out;
+
+            /* Move 'end' to the next buffer pointer. */
+            end = &next->next;
+         }
+
+         /* Compress the data */
+         ret = deflate(&png_ptr->zstream,
+            input_len > 0 ? Z_NO_FLUSH : Z_FINISH);
+
+         /* Claw back input data that was not consumed (because avail_in is
+          * reset above every time round the loop).
+          */
+         input_len += png_ptr->zstream.avail_in;
+         png_ptr->zstream.avail_in = 0; /* safety */
+      }
+      while (ret == Z_OK);
+
+      /* There may be some space left in the last output buffer. This needs to
+       * be subtracted from output_len.
+       */
+      output_len -= png_ptr->zstream.avail_out;
+      png_ptr->zstream.avail_out = 0; /* safety */
+      comp->output_len = output_len;
+
+      /* Now double check the output length, put in a custom message if it is
+       * too long.  Otherwise ensure the z_stream::msg pointer is set to
+       * something.
+       */
+      if (output_len + prefix_len >= PNG_UINT_31_MAX)
+      {
+         png_ptr->zstream.msg = PNGZ_MSG_CAST("compressed data too long");
+         ret = Z_MEM_ERROR;
+      }
+
+      else
+         png_zstream_error(png_ptr, ret);
+
+      /* Reset zlib for another zTXt/iTXt or image data */
+      png_ptr->zowner = 0;
+
+      /* The only success case is Z_STREAM_END, input_len must be 0; if not this
+       * is an internal error.
+       */
+      if (ret == Z_STREAM_END && input_len == 0)
+      {
+#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
+         /* Fix up the deflate header, if required */
+         optimize_cmf(comp->output, comp->input_len);
+#endif
+         /* But Z_OK is returned, not Z_STREAM_END; this allows the claim
+          * function above to return Z_STREAM_END on an error (though it never
+          * does in the current versions of zlib.)
+          */
+         return Z_OK;
+      }
+
+      else
+         return ret;
+   }
+}
+
+/* Ship the compressed text out via chunk writes */
+static void
+png_write_compressed_data_out(png_structrp png_ptr, compression_state *comp)
+{
+   png_uint_32 output_len = comp->output_len;
+   png_const_bytep output = comp->output;
+   png_uint_32 avail = (sizeof comp->output);
+   png_compression_buffer *next = png_ptr->zbuffer_list;
+
+   for (;;)
+   {
+      if (avail > output_len)
+         avail = output_len;
+
+      png_write_chunk_data(png_ptr, output, avail);
+
+      output_len -= avail;
+
+      if (output_len == 0 || next == NULL)
+         break;
+
+      avail = png_ptr->zbuffer_size;
+      output = next->output;
+      next = next->next;
+   }
+
+   /* This is an internal error; 'next' must have been NULL! */
+   if (output_len > 0)
+      png_error(png_ptr, "error writing ancillary chunked compressed data");
+}
+#endif /* WRITE_COMPRESSED_TEXT */
+
+#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \
+    defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
+/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification,
+ * and if invalid, correct the keyword rather than discarding the entire
+ * chunk.  The PNG 1.0 specification requires keywords 1-79 characters in
+ * length, forbids leading or trailing whitespace, multiple internal spaces,
+ * and the non-break space (0x80) from ISO 8859-1.  Returns keyword length.
+ *
+ * The 'new_key' buffer must be 80 characters in size (for the keyword plus a
+ * trailing '\0').  If this routine returns 0 then there was no keyword, or a
+ * valid one could not be generated, and the caller must png_error.
+ */
+static png_uint_32
+png_check_keyword(png_structrp png_ptr, png_const_charp key, png_bytep new_key)
+{
+   png_const_charp orig_key = key;
+   png_uint_32 key_len = 0;
+   int bad_character = 0;
+   int space = 1;
+
+   png_debug(1, "in png_check_keyword");
+
+   if (key == NULL)
+   {
+      *new_key = 0;
+      return 0;
+   }
+
+   while (*key && key_len < 79)
+   {
+      png_byte ch = (png_byte)(0xff & *key++);
+
+      if ((ch > 32 && ch <= 126) || (ch >= 161 /*&& ch <= 255*/))
+         *new_key++ = ch, ++key_len, space = 0;
+
+      else if (space == 0)
+      {
+         /* A space or an invalid character when one wasn't seen immediately
+          * before; output just a space.
+          */
+         *new_key++ = 32, ++key_len, space = 1;
+
+         /* If the character was not a space then it is invalid. */
+         if (ch != 32)
+            bad_character = ch;
+      }
+
+      else if (bad_character == 0)
+         bad_character = ch; /* just skip it, record the first error */
+   }
+
+   if (key_len > 0 && space != 0) /* trailing space */
+   {
+      --key_len, --new_key;
+      if (bad_character == 0)
+         bad_character = 32;
+   }
+
+   /* Terminate the keyword */
+   *new_key = 0;
+
+   if (key_len == 0)
+      return 0;
+
+#ifdef PNG_WARNINGS_SUPPORTED
+   /* Try to only output one warning per keyword: */
+   if (*key != 0) /* keyword too long */
+      png_warning(png_ptr, "keyword truncated");
+
+   else if (bad_character != 0)
+   {
+      PNG_WARNING_PARAMETERS(p)
+
+      png_warning_parameter(p, 1, orig_key);
+      png_warning_parameter_signed(p, 2, PNG_NUMBER_FORMAT_02x, bad_character);
+
+      png_formatted_warning(png_ptr, p, "keyword \"@1\": bad character '0x at 2'");
+   }
+#endif /* WARNINGS */
+
+   return key_len;
+}
+#endif /* WRITE_TEXT || WRITE_pCAL || WRITE_iCCP || WRITE_sPLT */
+
+/* Write the IHDR chunk, and update the png_struct with the necessary
+ * information.  Note that the rest of this code depends upon this
+ * information being correct.
+ */
+void /* PRIVATE */
+png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height,
+    int bit_depth, int color_type, int compression_type, int filter_type,
+    int interlace_type)
+{
+   png_byte buf[13]; /* Buffer to store the IHDR info */
+
+   png_debug(1, "in png_write_IHDR");
+
+   /* Check that we have valid input data from the application info */
+   switch (color_type)
+   {
+      case PNG_COLOR_TYPE_GRAY:
+         switch (bit_depth)
+         {
+            case 1:
+            case 2:
+            case 4:
+            case 8:
+#ifdef PNG_WRITE_16BIT_SUPPORTED
+            case 16:
+#endif
+               png_ptr->channels = 1; break;
+
+            default:
+               png_error(png_ptr,
+                   "Invalid bit depth for grayscale image");
+         }
+         break;
+
+      case PNG_COLOR_TYPE_RGB:
+#ifdef PNG_WRITE_16BIT_SUPPORTED
+         if (bit_depth != 8 && bit_depth != 16)
+#else
+         if (bit_depth != 8)
+#endif
+            png_error(png_ptr, "Invalid bit depth for RGB image");
+
+         png_ptr->channels = 3;
+         break;
+
+      case PNG_COLOR_TYPE_PALETTE:
+         switch (bit_depth)
+         {
+            case 1:
+            case 2:
+            case 4:
+            case 8:
+               png_ptr->channels = 1;
+               break;
+
+            default:
+               png_error(png_ptr, "Invalid bit depth for paletted image");
+         }
+         break;
+
+      case PNG_COLOR_TYPE_GRAY_ALPHA:
+         if (bit_depth != 8 && bit_depth != 16)
+            png_error(png_ptr, "Invalid bit depth for grayscale+alpha image");
+
+         png_ptr->channels = 2;
+         break;
+
+      case PNG_COLOR_TYPE_RGB_ALPHA:
+#ifdef PNG_WRITE_16BIT_SUPPORTED
+         if (bit_depth != 8 && bit_depth != 16)
+#else
+         if (bit_depth != 8)
+#endif
+            png_error(png_ptr, "Invalid bit depth for RGBA image");
+
+         png_ptr->channels = 4;
+         break;
+
+      default:
+         png_error(png_ptr, "Invalid image color type specified");
+   }
+
+   if (compression_type != PNG_COMPRESSION_TYPE_BASE)
+   {
+      png_warning(png_ptr, "Invalid compression type specified");
+      compression_type = PNG_COMPRESSION_TYPE_BASE;
+   }
+
+   /* Write filter_method 64 (intrapixel differencing) only if
+    * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
+    * 2. Libpng did not write a PNG signature (this filter_method is only
+    *    used in PNG datastreams that are embedded in MNG datastreams) and
+    * 3. The application called png_permit_mng_features with a mask that
+    *    included PNG_FLAG_MNG_FILTER_64 and
+    * 4. The filter_method is 64 and
+    * 5. The color_type is RGB or RGBA
+    */
+   if (
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+       !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 &&
+       ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) &&
+       (color_type == PNG_COLOR_TYPE_RGB ||
+        color_type == PNG_COLOR_TYPE_RGB_ALPHA) &&
+       (filter_type == PNG_INTRAPIXEL_DIFFERENCING)) &&
+#endif
+       filter_type != PNG_FILTER_TYPE_BASE)
+   {
+      png_warning(png_ptr, "Invalid filter type specified");
+      filter_type = PNG_FILTER_TYPE_BASE;
+   }
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+   if (interlace_type != PNG_INTERLACE_NONE &&
+       interlace_type != PNG_INTERLACE_ADAM7)
+   {
+      png_warning(png_ptr, "Invalid interlace type specified");
+      interlace_type = PNG_INTERLACE_ADAM7;
+   }
+#else
+   interlace_type=PNG_INTERLACE_NONE;
+#endif
+
+   /* Save the relevent information */
+   png_ptr->bit_depth = (png_byte)bit_depth;
+   png_ptr->color_type = (png_byte)color_type;
+   png_ptr->interlaced = (png_byte)interlace_type;
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+   png_ptr->filter_type = (png_byte)filter_type;
+#endif
+   png_ptr->compression_type = (png_byte)compression_type;
+   png_ptr->width = width;
+   png_ptr->height = height;
+
+   png_ptr->pixel_depth = (png_byte)(bit_depth * png_ptr->channels);
+   png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width);
+   /* Set the usr info, so any transformations can modify it */
+   png_ptr->usr_width = png_ptr->width;
+   png_ptr->usr_bit_depth = png_ptr->bit_depth;
+   png_ptr->usr_channels = png_ptr->channels;
+
+   /* Pack the header information into the buffer */
+   png_save_uint_32(buf, width);
+   png_save_uint_32(buf + 4, height);
+   buf[8] = (png_byte)bit_depth;
+   buf[9] = (png_byte)color_type;
+   buf[10] = (png_byte)compression_type;
+   buf[11] = (png_byte)filter_type;
+   buf[12] = (png_byte)interlace_type;
+
+   /* Write the chunk */
+   png_write_complete_chunk(png_ptr, png_IHDR, buf, (png_size_t)13);
+
+   if ((png_ptr->do_filter) == PNG_NO_FILTERS)
+   {
+      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE ||
+          png_ptr->bit_depth < 8)
+         png_ptr->do_filter = PNG_FILTER_NONE;
+
+      else
+         png_ptr->do_filter = PNG_ALL_FILTERS;
+   }
+
+   png_ptr->mode = PNG_HAVE_IHDR; /* not READY_FOR_ZTXT */
+}
+
+/* Write the palette.  We are careful not to trust png_color to be in the
+ * correct order for PNG, so people can redefine it to any convenient
+ * structure.
+ */
+void /* PRIVATE */
+png_write_PLTE(png_structrp png_ptr, png_const_colorp palette,
+    png_uint_32 num_pal)
+{
+   png_uint_32 i;
+   png_const_colorp pal_ptr;
+   png_byte buf[3];
+
+   png_debug(1, "in png_write_PLTE");
+
+   if ((
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+       (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0 &&
+#endif
+       num_pal == 0) || num_pal > 256)
+   {
+      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      {
+         png_error(png_ptr, "Invalid number of colors in palette");
+      }
+
+      else
+      {
+         png_warning(png_ptr, "Invalid number of colors in palette");
+         return;
+      }
+   }
+
+   if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0)
+   {
+      png_warning(png_ptr,
+          "Ignoring request to write a PLTE chunk in grayscale PNG");
+
+      return;
+   }
+
+   png_ptr->num_palette = (png_uint_16)num_pal;
+   png_debug1(3, "num_palette = %d", png_ptr->num_palette);
+
+   png_write_chunk_header(png_ptr, png_PLTE, (png_uint_32)(num_pal * 3));
+#ifdef PNG_POINTER_INDEXING_SUPPORTED
+
+   for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++)
+   {
+      buf[0] = pal_ptr->red;
+      buf[1] = pal_ptr->green;
+      buf[2] = pal_ptr->blue;
+      png_write_chunk_data(png_ptr, buf, (png_size_t)3);
+   }
+
+#else
+   /* This is a little slower but some buggy compilers need to do this
+    * instead
+    */
+   pal_ptr=palette;
+
+   for (i = 0; i < num_pal; i++)
+   {
+      buf[0] = pal_ptr[i].red;
+      buf[1] = pal_ptr[i].green;
+      buf[2] = pal_ptr[i].blue;
+      png_write_chunk_data(png_ptr, buf, (png_size_t)3);
+   }
+
+#endif
+   png_write_chunk_end(png_ptr);
+   png_ptr->mode |= PNG_HAVE_PLTE;
+}
+
+/* This is similar to png_text_compress, above, except that it does not require
+ * all of the data at once and, instead of buffering the compressed result,
+ * writes it as IDAT chunks.  Unlike png_text_compress it *can* png_error out
+ * because it calls the write interface.  As a result it does its own error
+ * reporting and does not return an error code.  In the event of error it will
+ * just call png_error.  The input data length may exceed 32-bits.  The 'flush'
+ * parameter is exactly the same as that to deflate, with the following
+ * meanings:
+ *
+ * Z_NO_FLUSH: normal incremental output of compressed data
+ * Z_SYNC_FLUSH: do a SYNC_FLUSH, used by png_write_flush
+ * Z_FINISH: this is the end of the input, do a Z_FINISH and clean up
+ *
+ * The routine manages the acquire and release of the png_ptr->zstream by
+ * checking and (at the end) clearing png_ptr->zowner; it does some sanity
+ * checks on the 'mode' flags while doing this.
+ */
+void /* PRIVATE */
+png_compress_IDAT(png_structrp png_ptr, png_const_bytep input,
+   png_alloc_size_t input_len, int flush)
+{
+   if (png_ptr->zowner != png_IDAT)
+   {
+      /* First time.   Ensure we have a temporary buffer for compression and
+       * trim the buffer list if it has more than one entry to free memory.
+       * If 'WRITE_COMPRESSED_TEXT' is not set the list will never have been
+       * created at this point, but the check here is quick and safe.
+       */
+      if (png_ptr->zbuffer_list == NULL)
+      {
+         png_ptr->zbuffer_list = png_voidcast(png_compression_bufferp,
+            png_malloc(png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr)));
+         png_ptr->zbuffer_list->next = NULL;
+      }
+
+      else
+         png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list->next);
+
+      /* It is a terminal error if we can't claim the zstream. */
+      if (png_deflate_claim(png_ptr, png_IDAT, png_image_size(png_ptr)) != Z_OK)
+         png_error(png_ptr, png_ptr->zstream.msg);
+
+      /* The output state is maintained in png_ptr->zstream, so it must be
+       * initialized here after the claim.
+       */
+      png_ptr->zstream.next_out = png_ptr->zbuffer_list->output;
+      png_ptr->zstream.avail_out = png_ptr->zbuffer_size;
+   }
+
+   /* Now loop reading and writing until all the input is consumed or an error
+    * terminates the operation.  The _out values are maintained across calls to
+    * this function, but the input must be reset each time.
+    */
+   png_ptr->zstream.next_in = PNGZ_INPUT_CAST(input);
+   png_ptr->zstream.avail_in = 0; /* set below */
+   for (;;)
+   {
+      int ret;
+
+      /* INPUT: from the row data */
+      uInt avail = ZLIB_IO_MAX;
+
+      if (avail > input_len)
+         avail = (uInt)input_len; /* safe because of the check */
+
+      png_ptr->zstream.avail_in = avail;
+      input_len -= avail;
+
+      ret = deflate(&png_ptr->zstream, input_len > 0 ? Z_NO_FLUSH : flush);
+
+      /* Include as-yet unconsumed input */
+      input_len += png_ptr->zstream.avail_in;
+      png_ptr->zstream.avail_in = 0;
+
+      /* OUTPUT: write complete IDAT chunks when avail_out drops to zero. Note
+       * that these two zstream fields are preserved across the calls, therefore
+       * there is no need to set these up on entry to the loop.
+       */
+      if (png_ptr->zstream.avail_out == 0)
+      {
+         png_bytep data = png_ptr->zbuffer_list->output;
+         uInt size = png_ptr->zbuffer_size;
+
+         /* Write an IDAT containing the data then reset the buffer.  The
+          * first IDAT may need deflate header optimization.
+          */
+#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
+            if ((png_ptr->mode & PNG_HAVE_IDAT) == 0 &&
+                png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE)
+               optimize_cmf(data, png_image_size(png_ptr));
+#endif
+
+         png_write_complete_chunk(png_ptr, png_IDAT, data, size);
+         png_ptr->mode |= PNG_HAVE_IDAT;
+
+         png_ptr->zstream.next_out = data;
+         png_ptr->zstream.avail_out = size;
+
+         /* For SYNC_FLUSH or FINISH it is essential to keep calling zlib with
+          * the same flush parameter until it has finished output, for NO_FLUSH
+          * it doesn't matter.
+          */
+         if (ret == Z_OK && flush != Z_NO_FLUSH)
+            continue;
+      }
+
+      /* The order of these checks doesn't matter much; it just affects which
+       * possible error might be detected if multiple things go wrong at once.
+       */
+      if (ret == Z_OK) /* most likely return code! */
+      {
+         /* If all the input has been consumed then just return.  If Z_FINISH
+          * was used as the flush parameter something has gone wrong if we get
+          * here.
+          */
+         if (input_len == 0)
+         {
+            if (flush == Z_FINISH)
+               png_error(png_ptr, "Z_OK on Z_FINISH with output space");
+
+            return;
+         }
+      }
+
+      else if (ret == Z_STREAM_END && flush == Z_FINISH)
+      {
+         /* This is the end of the IDAT data; any pending output must be
+          * flushed.  For small PNG files we may still be at the beginning.
+          */
+         png_bytep data = png_ptr->zbuffer_list->output;
+         uInt size = png_ptr->zbuffer_size - png_ptr->zstream.avail_out;
+
+#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
+         if ((png_ptr->mode & PNG_HAVE_IDAT) == 0 &&
+             png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE)
+            optimize_cmf(data, png_image_size(png_ptr));
+#endif
+
+         png_write_complete_chunk(png_ptr, png_IDAT, data, size);
+         png_ptr->zstream.avail_out = 0;
+         png_ptr->zstream.next_out = NULL;
+         png_ptr->mode |= PNG_HAVE_IDAT | PNG_AFTER_IDAT;
+
+         png_ptr->zowner = 0; /* Release the stream */
+         return;
+      }
+
+      else
+      {
+         /* This is an error condition. */
+         png_zstream_error(png_ptr, ret);
+         png_error(png_ptr, png_ptr->zstream.msg);
+      }
+   }
+}
+
+/* Write an IEND chunk */
+void /* PRIVATE */
+png_write_IEND(png_structrp png_ptr)
+{
+   png_debug(1, "in png_write_IEND");
+
+   png_write_complete_chunk(png_ptr, png_IEND, NULL, (png_size_t)0);
+   png_ptr->mode |= PNG_HAVE_IEND;
+}
+
+#ifdef PNG_WRITE_gAMA_SUPPORTED
+/* Write a gAMA chunk */
+void /* PRIVATE */
+png_write_gAMA_fixed(png_structrp png_ptr, png_fixed_point file_gamma)
+{
+   png_byte buf[4];
+
+   png_debug(1, "in png_write_gAMA");
+
+   /* file_gamma is saved in 1/100,000ths */
+   png_save_uint_32(buf, (png_uint_32)file_gamma);
+   png_write_complete_chunk(png_ptr, png_gAMA, buf, (png_size_t)4);
+}
+#endif
+
+#ifdef PNG_WRITE_sRGB_SUPPORTED
+/* Write a sRGB chunk */
+void /* PRIVATE */
+png_write_sRGB(png_structrp png_ptr, int srgb_intent)
+{
+   png_byte buf[1];
+
+   png_debug(1, "in png_write_sRGB");
+
+   if (srgb_intent >= PNG_sRGB_INTENT_LAST)
+      png_warning(png_ptr,
+          "Invalid sRGB rendering intent specified");
+
+   buf[0]=(png_byte)srgb_intent;
+   png_write_complete_chunk(png_ptr, png_sRGB, buf, (png_size_t)1);
+}
+#endif
+
+#ifdef PNG_WRITE_iCCP_SUPPORTED
+/* Write an iCCP chunk */
+void /* PRIVATE */
+png_write_iCCP(png_structrp png_ptr, png_const_charp name,
+    png_const_bytep profile)
+{
+   png_uint_32 name_len;
+   png_uint_32 profile_len;
+   png_byte new_name[81]; /* 1 byte for the compression byte */
+   compression_state comp;
+   png_uint_32 temp;
+
+   png_debug(1, "in png_write_iCCP");
+
+   /* These are all internal problems: the profile should have been checked
+    * before when it was stored.
+    */
+   if (profile == NULL)
+      png_error(png_ptr, "No profile for iCCP chunk"); /* internal error */
+
+   profile_len = png_get_uint_32(profile);
+
+   if (profile_len < 132)
+      png_error(png_ptr, "ICC profile too short");
+
+   temp = (png_uint_32) (*(profile+8));
+   if (temp > 3 && (profile_len & 0x03))
+      png_error(png_ptr, "ICC profile length invalid (not a multiple of 4)");
+
+   {
+      png_uint_32 embedded_profile_len = png_get_uint_32(profile);
+
+      if (profile_len != embedded_profile_len)
+         png_error(png_ptr, "Profile length does not match profile");
+   }
+
+   name_len = png_check_keyword(png_ptr, name, new_name);
+
+   if (name_len == 0)
+      png_error(png_ptr, "iCCP: invalid keyword");
+
+   new_name[++name_len] = PNG_COMPRESSION_TYPE_BASE;
+
+   /* Make sure we include the NULL after the name and the compression type */
+   ++name_len;
+
+   png_text_compress_init(&comp, profile, profile_len);
+
+   /* Allow for keyword terminator and compression byte */
+   if (png_text_compress(png_ptr, png_iCCP, &comp, name_len) != Z_OK)
+      png_error(png_ptr, png_ptr->zstream.msg);
+
+   png_write_chunk_header(png_ptr, png_iCCP, name_len + comp.output_len);
+
+   png_write_chunk_data(png_ptr, new_name, name_len);
+
+   png_write_compressed_data_out(png_ptr, &comp);
+
+   png_write_chunk_end(png_ptr);
+}
+#endif
+
+#ifdef PNG_WRITE_sPLT_SUPPORTED
+/* Write a sPLT chunk */
+void /* PRIVATE */
+png_write_sPLT(png_structrp png_ptr, png_const_sPLT_tp spalette)
+{
+   png_uint_32 name_len;
+   png_byte new_name[80];
+   png_byte entrybuf[10];
+   png_size_t entry_size = (spalette->depth == 8 ? 6 : 10);
+   png_size_t palette_size = entry_size * spalette->nentries;
+   png_sPLT_entryp ep;
+#ifndef PNG_POINTER_INDEXING_SUPPORTED
+   int i;
+#endif
+
+   png_debug(1, "in png_write_sPLT");
+
+   name_len = png_check_keyword(png_ptr, spalette->name, new_name);
+
+   if (name_len == 0)
+      png_error(png_ptr, "sPLT: invalid keyword");
+
+   /* Make sure we include the NULL after the name */
+   png_write_chunk_header(png_ptr, png_sPLT,
+       (png_uint_32)(name_len + 2 + palette_size));
+
+   png_write_chunk_data(png_ptr, (png_bytep)new_name,
+       (png_size_t)(name_len + 1));
+
+   png_write_chunk_data(png_ptr, &spalette->depth, (png_size_t)1);
+
+   /* Loop through each palette entry, writing appropriately */
+#ifdef PNG_POINTER_INDEXING_SUPPORTED
+   for (ep = spalette->entries; ep<spalette->entries + spalette->nentries; ep++)
+   {
+      if (spalette->depth == 8)
+      {
+         entrybuf[0] = (png_byte)ep->red;
+         entrybuf[1] = (png_byte)ep->green;
+         entrybuf[2] = (png_byte)ep->blue;
+         entrybuf[3] = (png_byte)ep->alpha;
+         png_save_uint_16(entrybuf + 4, ep->frequency);
+      }
+
+      else
+      {
+         png_save_uint_16(entrybuf + 0, ep->red);
+         png_save_uint_16(entrybuf + 2, ep->green);
+         png_save_uint_16(entrybuf + 4, ep->blue);
+         png_save_uint_16(entrybuf + 6, ep->alpha);
+         png_save_uint_16(entrybuf + 8, ep->frequency);
+      }
+
+      png_write_chunk_data(png_ptr, entrybuf, entry_size);
+   }
+#else
+   ep=spalette->entries;
+   for (i = 0; i>spalette->nentries; i++)
+   {
+      if (spalette->depth == 8)
+      {
+         entrybuf[0] = (png_byte)ep[i].red;
+         entrybuf[1] = (png_byte)ep[i].green;
+         entrybuf[2] = (png_byte)ep[i].blue;
+         entrybuf[3] = (png_byte)ep[i].alpha;
+         png_save_uint_16(entrybuf + 4, ep[i].frequency);
+      }
+
+      else
+      {
+         png_save_uint_16(entrybuf + 0, ep[i].red);
+         png_save_uint_16(entrybuf + 2, ep[i].green);
+         png_save_uint_16(entrybuf + 4, ep[i].blue);
+         png_save_uint_16(entrybuf + 6, ep[i].alpha);
+         png_save_uint_16(entrybuf + 8, ep[i].frequency);
+      }
+
+      png_write_chunk_data(png_ptr, entrybuf, entry_size);
+   }
+#endif
+
+   png_write_chunk_end(png_ptr);
+}
+#endif
+
+#ifdef PNG_WRITE_sBIT_SUPPORTED
+/* Write the sBIT chunk */
+void /* PRIVATE */
+png_write_sBIT(png_structrp png_ptr, png_const_color_8p sbit, int color_type)
+{
+   png_byte buf[4];
+   png_size_t size;
+
+   png_debug(1, "in png_write_sBIT");
+
+   /* Make sure we don't depend upon the order of PNG_COLOR_8 */
+   if ((color_type & PNG_COLOR_MASK_COLOR) != 0)
+   {
+      png_byte maxbits;
+
+      maxbits = (png_byte)(color_type==PNG_COLOR_TYPE_PALETTE ? 8 :
+          png_ptr->usr_bit_depth);
+
+      if (sbit->red == 0 || sbit->red > maxbits ||
+          sbit->green == 0 || sbit->green > maxbits ||
+          sbit->blue == 0 || sbit->blue > maxbits)
+      {
+         png_warning(png_ptr, "Invalid sBIT depth specified");
+         return;
+      }
+
+      buf[0] = sbit->red;
+      buf[1] = sbit->green;
+      buf[2] = sbit->blue;
+      size = 3;
+   }
+
+   else
+   {
+      if (sbit->gray == 0 || sbit->gray > png_ptr->usr_bit_depth)
+      {
+         png_warning(png_ptr, "Invalid sBIT depth specified");
+         return;
+      }
+
+      buf[0] = sbit->gray;
+      size = 1;
+   }
+
+   if ((color_type & PNG_COLOR_MASK_ALPHA) != 0)
+   {
+      if (sbit->alpha == 0 || sbit->alpha > png_ptr->usr_bit_depth)
+      {
+         png_warning(png_ptr, "Invalid sBIT depth specified");
+         return;
+      }
+
+      buf[size++] = sbit->alpha;
+   }
+
+   png_write_complete_chunk(png_ptr, png_sBIT, buf, size);
+}
+#endif
+
+#ifdef PNG_WRITE_cHRM_SUPPORTED
+/* Write the cHRM chunk */
+void /* PRIVATE */
+png_write_cHRM_fixed(png_structrp png_ptr, const png_xy *xy)
+{
+   png_byte buf[32];
+
+   png_debug(1, "in png_write_cHRM");
+
+   /* Each value is saved in 1/100,000ths */
+   png_save_int_32(buf,      xy->whitex);
+   png_save_int_32(buf +  4, xy->whitey);
+
+   png_save_int_32(buf +  8, xy->redx);
+   png_save_int_32(buf + 12, xy->redy);
+
+   png_save_int_32(buf + 16, xy->greenx);
+   png_save_int_32(buf + 20, xy->greeny);
+
+   png_save_int_32(buf + 24, xy->bluex);
+   png_save_int_32(buf + 28, xy->bluey);
+
+   png_write_complete_chunk(png_ptr, png_cHRM, buf, 32);
+}
+#endif
+
+#ifdef PNG_WRITE_tRNS_SUPPORTED
+/* Write the tRNS chunk */
+void /* PRIVATE */
+png_write_tRNS(png_structrp png_ptr, png_const_bytep trans_alpha,
+    png_const_color_16p tran, int num_trans, int color_type)
+{
+   png_byte buf[6];
+
+   png_debug(1, "in png_write_tRNS");
+
+   if (color_type == PNG_COLOR_TYPE_PALETTE)
+   {
+      if (num_trans <= 0 || num_trans > (int)png_ptr->num_palette)
+      {
+         png_app_warning(png_ptr,
+             "Invalid number of transparent colors specified");
+         return;
+      }
+
+      /* Write the chunk out as it is */
+      png_write_complete_chunk(png_ptr, png_tRNS, trans_alpha,
+         (png_size_t)num_trans);
+   }
+
+   else if (color_type == PNG_COLOR_TYPE_GRAY)
+   {
+      /* One 16 bit value */
+      if (tran->gray >= (1 << png_ptr->bit_depth))
+      {
+         png_app_warning(png_ptr,
+             "Ignoring attempt to write tRNS chunk out-of-range for bit_depth");
+
+         return;
+      }
+
+      png_save_uint_16(buf, tran->gray);
+      png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)2);
+   }
+
+   else if (color_type == PNG_COLOR_TYPE_RGB)
+   {
+      /* Three 16 bit values */
+      png_save_uint_16(buf, tran->red);
+      png_save_uint_16(buf + 2, tran->green);
+      png_save_uint_16(buf + 4, tran->blue);
+#ifdef PNG_WRITE_16BIT_SUPPORTED
+      if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]) != 0)
+#else
+      if ((buf[0] | buf[2] | buf[4]) != 0)
+#endif
+      {
+         png_app_warning(png_ptr,
+           "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8");
+         return;
+      }
+
+      png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)6);
+   }
+
+   else
+   {
+      png_app_warning(png_ptr, "Can't write tRNS with an alpha channel");
+   }
+}
+#endif
+
+#ifdef PNG_WRITE_bKGD_SUPPORTED
+/* Write the background chunk */
+void /* PRIVATE */
+png_write_bKGD(png_structrp png_ptr, png_const_color_16p back, int color_type)
+{
+   png_byte buf[6];
+
+   png_debug(1, "in png_write_bKGD");
+
+   if (color_type == PNG_COLOR_TYPE_PALETTE)
+   {
+      if (
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+          (png_ptr->num_palette != 0 ||
+          (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0) &&
+#endif
+         back->index >= png_ptr->num_palette)
+      {
+         png_warning(png_ptr, "Invalid background palette index");
+         return;
+      }
+
+      buf[0] = back->index;
+      png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)1);
+   }
+
+   else if ((color_type & PNG_COLOR_MASK_COLOR) != 0)
+   {
+      png_save_uint_16(buf, back->red);
+      png_save_uint_16(buf + 2, back->green);
+      png_save_uint_16(buf + 4, back->blue);
+#ifdef PNG_WRITE_16BIT_SUPPORTED
+      if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]) != 0)
+#else
+      if ((buf[0] | buf[2] | buf[4]) != 0)
+#endif
+      {
+         png_warning(png_ptr,
+             "Ignoring attempt to write 16-bit bKGD chunk when bit_depth is 8");
+
+         return;
+      }
+
+      png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)6);
+   }
+
+   else
+   {
+      if (back->gray >= (1 << png_ptr->bit_depth))
+      {
+         png_warning(png_ptr,
+             "Ignoring attempt to write bKGD chunk out-of-range for bit_depth");
+
+         return;
+      }
+
+      png_save_uint_16(buf, back->gray);
+      png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)2);
+   }
+}
+#endif
+
+#ifdef PNG_WRITE_hIST_SUPPORTED
+/* Write the histogram */
+void /* PRIVATE */
+png_write_hIST(png_structrp png_ptr, png_const_uint_16p hist, int num_hist)
+{
+   int i;
+   png_byte buf[3];
+
+   png_debug(1, "in png_write_hIST");
+
+   if (num_hist > (int)png_ptr->num_palette)
+   {
+      png_debug2(3, "num_hist = %d, num_palette = %d", num_hist,
+          png_ptr->num_palette);
+
+      png_warning(png_ptr, "Invalid number of histogram entries specified");
+      return;
+   }
+
+   png_write_chunk_header(png_ptr, png_hIST, (png_uint_32)(num_hist * 2));
+
+   for (i = 0; i < num_hist; i++)
+   {
+      png_save_uint_16(buf, hist[i]);
+      png_write_chunk_data(png_ptr, buf, (png_size_t)2);
+   }
+
+   png_write_chunk_end(png_ptr);
+}
+#endif
+
+#ifdef PNG_WRITE_tEXt_SUPPORTED
+/* Write a tEXt chunk */
+void /* PRIVATE */
+png_write_tEXt(png_structrp png_ptr, png_const_charp key, png_const_charp text,
+    png_size_t text_len)
+{
+   png_uint_32 key_len;
+   png_byte new_key[80];
+
+   png_debug(1, "in png_write_tEXt");
+
+   key_len = png_check_keyword(png_ptr, key, new_key);
+
+   if (key_len == 0)
+      png_error(png_ptr, "tEXt: invalid keyword");
+
+   if (text == NULL || *text == '\0')
+      text_len = 0;
+
+   else
+      text_len = strlen(text);
+
+   if (text_len > PNG_UINT_31_MAX - (key_len+1))
+      png_error(png_ptr, "tEXt: text too long");
+
+   /* Make sure we include the 0 after the key */
+   png_write_chunk_header(png_ptr, png_tEXt,
+       (png_uint_32)/*checked above*/(key_len + text_len + 1));
+   /*
+    * We leave it to the application to meet PNG-1.0 requirements on the
+    * contents of the text.  PNG-1.0 through PNG-1.2 discourage the use of
+    * any non-Latin-1 characters except for NEWLINE.  ISO PNG will forbid them.
+    * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
+    */
+   png_write_chunk_data(png_ptr, new_key, key_len + 1);
+
+   if (text_len != 0)
+      png_write_chunk_data(png_ptr, (png_const_bytep)text, text_len);
+
+   png_write_chunk_end(png_ptr);
+}
+#endif
+
+#ifdef PNG_WRITE_zTXt_SUPPORTED
+/* Write a compressed text chunk */
+void /* PRIVATE */
+png_write_zTXt(png_structrp png_ptr, png_const_charp key, png_const_charp text,
+    int compression)
+{
+   png_uint_32 key_len;
+   png_byte new_key[81];
+   compression_state comp;
+
+   png_debug(1, "in png_write_zTXt");
+
+   if (compression == PNG_TEXT_COMPRESSION_NONE)
+   {
+      png_write_tEXt(png_ptr, key, text, 0);
+      return;
+   }
+
+   if (compression != PNG_TEXT_COMPRESSION_zTXt)
+      png_error(png_ptr, "zTXt: invalid compression type");
+
+   key_len = png_check_keyword(png_ptr, key, new_key);
+
+   if (key_len == 0)
+      png_error(png_ptr, "zTXt: invalid keyword");
+
+   /* Add the compression method and 1 for the keyword separator. */
+   new_key[++key_len] = PNG_COMPRESSION_TYPE_BASE;
+   ++key_len;
+
+   /* Compute the compressed data; do it now for the length */
+   png_text_compress_init(&comp, (png_const_bytep)text,
+      text == NULL ? 0 : strlen(text));
+
+   if (png_text_compress(png_ptr, png_zTXt, &comp, key_len) != Z_OK)
+      png_error(png_ptr, png_ptr->zstream.msg);
+
+   /* Write start of chunk */
+   png_write_chunk_header(png_ptr, png_zTXt, key_len + comp.output_len);
+
+   /* Write key */
+   png_write_chunk_data(png_ptr, new_key, key_len);
+
+   /* Write the compressed data */
+   png_write_compressed_data_out(png_ptr, &comp);
+
+   /* Close the chunk */
+   png_write_chunk_end(png_ptr);
+}
+#endif
+
+#ifdef PNG_WRITE_iTXt_SUPPORTED
+/* Write an iTXt chunk */
+void /* PRIVATE */
+png_write_iTXt(png_structrp png_ptr, int compression, png_const_charp key,
+    png_const_charp lang, png_const_charp lang_key, png_const_charp text)
+{
+   png_uint_32 key_len, prefix_len;
+   png_size_t lang_len, lang_key_len;
+   png_byte new_key[82];
+   compression_state comp;
+
+   png_debug(1, "in png_write_iTXt");
+
+   key_len = png_check_keyword(png_ptr, key, new_key);
+
+   if (key_len == 0)
+      png_error(png_ptr, "iTXt: invalid keyword");
+
+   /* Set the compression flag */
+   switch (compression)
+   {
+      case PNG_ITXT_COMPRESSION_NONE:
+      case PNG_TEXT_COMPRESSION_NONE:
+         compression = new_key[++key_len] = 0; /* no compression */
+         break;
+
+      case PNG_TEXT_COMPRESSION_zTXt:
+      case PNG_ITXT_COMPRESSION_zTXt:
+         compression = new_key[++key_len] = 1; /* compressed */
+         break;
+
+      default:
+         png_error(png_ptr, "iTXt: invalid compression");
+   }
+
+   new_key[++key_len] = PNG_COMPRESSION_TYPE_BASE;
+   ++key_len; /* for the keywod separator */
+
+   /* We leave it to the application to meet PNG-1.0 requirements on the
+    * contents of the text.  PNG-1.0 through PNG-1.2 discourage the use of
+    * any non-Latin-1 characters except for NEWLINE.  ISO PNG, however,
+    * specifies that the text is UTF-8 and this really doesn't require any
+    * checking.
+    *
+    * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
+    *
+    * TODO: validate the language tag correctly (see the spec.)
+    */
+   if (lang == NULL) lang = ""; /* empty language is valid */
+   lang_len = strlen(lang)+1;
+   if (lang_key == NULL) lang_key = ""; /* may be empty */
+   lang_key_len = strlen(lang_key)+1;
+   if (text == NULL) text = ""; /* may be empty */
+
+   prefix_len = key_len;
+   if (lang_len > PNG_UINT_31_MAX-prefix_len)
+      prefix_len = PNG_UINT_31_MAX;
+   else
+      prefix_len = (png_uint_32)(prefix_len + lang_len);
+
+   if (lang_key_len > PNG_UINT_31_MAX-prefix_len)
+      prefix_len = PNG_UINT_31_MAX;
+   else
+      prefix_len = (png_uint_32)(prefix_len + lang_key_len);
+
+   png_text_compress_init(&comp, (png_const_bytep)text, strlen(text));
+
+   if (compression != 0)
+   {
+      if (png_text_compress(png_ptr, png_iTXt, &comp, prefix_len) != Z_OK)
+         png_error(png_ptr, png_ptr->zstream.msg);
+   }
+
+   else
+   {
+      if (comp.input_len > PNG_UINT_31_MAX-prefix_len)
+         png_error(png_ptr, "iTXt: uncompressed text too long");
+
+      /* So the string will fit in a chunk: */
+      comp.output_len = (png_uint_32)/*SAFE*/comp.input_len;
+   }
+
+   png_write_chunk_header(png_ptr, png_iTXt, comp.output_len + prefix_len);
+
+   png_write_chunk_data(png_ptr, new_key, key_len);
+
+   png_write_chunk_data(png_ptr, (png_const_bytep)lang, lang_len);
+
+   png_write_chunk_data(png_ptr, (png_const_bytep)lang_key, lang_key_len);
+
+   if (compression != 0)
+      png_write_compressed_data_out(png_ptr, &comp);
+
+   else
+      png_write_chunk_data(png_ptr, (png_const_bytep)text, comp.input_len);
+
+   png_write_chunk_end(png_ptr);
+}
+#endif
+
+#ifdef PNG_WRITE_oFFs_SUPPORTED
+/* Write the oFFs chunk */
+void /* PRIVATE */
+png_write_oFFs(png_structrp png_ptr, png_int_32 x_offset, png_int_32 y_offset,
+    int unit_type)
+{
+   png_byte buf[9];
+
+   png_debug(1, "in png_write_oFFs");
+
+   if (unit_type >= PNG_OFFSET_LAST)
+      png_warning(png_ptr, "Unrecognized unit type for oFFs chunk");
+
+   png_save_int_32(buf, x_offset);
+   png_save_int_32(buf + 4, y_offset);
+   buf[8] = (png_byte)unit_type;
+
+   png_write_complete_chunk(png_ptr, png_oFFs, buf, (png_size_t)9);
+}
+#endif
+#ifdef PNG_WRITE_pCAL_SUPPORTED
+/* Write the pCAL chunk (described in the PNG extensions document) */
+void /* PRIVATE */
+png_write_pCAL(png_structrp png_ptr, png_charp purpose, png_int_32 X0,
+    png_int_32 X1, int type, int nparams, png_const_charp units,
+    png_charpp params)
+{
+   png_uint_32 purpose_len;
+   png_size_t units_len, total_len;
+   png_size_tp params_len;
+   png_byte buf[10];
+   png_byte new_purpose[80];
+   int i;
+
+   png_debug1(1, "in png_write_pCAL (%d parameters)", nparams);
+
+   if (type >= PNG_EQUATION_LAST)
+      png_error(png_ptr, "Unrecognized equation type for pCAL chunk");
+
+   purpose_len = png_check_keyword(png_ptr, purpose, new_purpose);
+
+   if (purpose_len == 0)
+      png_error(png_ptr, "pCAL: invalid keyword");
+
+   ++purpose_len; /* terminator */
+
+   png_debug1(3, "pCAL purpose length = %d", (int)purpose_len);
+   units_len = strlen(units) + (nparams == 0 ? 0 : 1);
+   png_debug1(3, "pCAL units length = %d", (int)units_len);
+   total_len = purpose_len + units_len + 10;
+
+   params_len = (png_size_tp)png_malloc(png_ptr,
+       (png_alloc_size_t)(nparams * (sizeof (png_size_t))));
+
+   /* Find the length of each parameter, making sure we don't count the
+    * null terminator for the last parameter.
+    */
+   for (i = 0; i < nparams; i++)
+   {
+      params_len[i] = strlen(params[i]) + (i == nparams - 1 ? 0 : 1);
+      png_debug2(3, "pCAL parameter %d length = %lu", i,
+          (unsigned long)params_len[i]);
+      total_len += params_len[i];
+   }
+
+   png_debug1(3, "pCAL total length = %d", (int)total_len);
+   png_write_chunk_header(png_ptr, png_pCAL, (png_uint_32)total_len);
+   png_write_chunk_data(png_ptr, new_purpose, purpose_len);
+   png_save_int_32(buf, X0);
+   png_save_int_32(buf + 4, X1);
+   buf[8] = (png_byte)type;
+   buf[9] = (png_byte)nparams;
+   png_write_chunk_data(png_ptr, buf, (png_size_t)10);
+   png_write_chunk_data(png_ptr, (png_const_bytep)units, (png_size_t)units_len);
+
+   for (i = 0; i < nparams; i++)
+   {
+      png_write_chunk_data(png_ptr, (png_const_bytep)params[i], params_len[i]);
+   }
+
+   png_free(png_ptr, params_len);
+   png_write_chunk_end(png_ptr);
+}
+#endif
+
+#ifdef PNG_WRITE_sCAL_SUPPORTED
+/* Write the sCAL chunk */
+void /* PRIVATE */
+png_write_sCAL_s(png_structrp png_ptr, int unit, png_const_charp width,
+    png_const_charp height)
+{
+   png_byte buf[64];
+   png_size_t wlen, hlen, total_len;
+
+   png_debug(1, "in png_write_sCAL_s");
+
+   wlen = strlen(width);
+   hlen = strlen(height);
+   total_len = wlen + hlen + 2;
+
+   if (total_len > 64)
+   {
+      png_warning(png_ptr, "Can't write sCAL (buffer too small)");
+      return;
+   }
+
+   buf[0] = (png_byte)unit;
+   memcpy(buf + 1, width, wlen + 1);      /* Append the '\0' here */
+   memcpy(buf + wlen + 2, height, hlen);  /* Do NOT append the '\0' here */
+
+   png_debug1(3, "sCAL total length = %u", (unsigned int)total_len);
+   png_write_complete_chunk(png_ptr, png_sCAL, buf, total_len);
+}
+#endif
+
+#ifdef PNG_WRITE_pHYs_SUPPORTED
+/* Write the pHYs chunk */
+void /* PRIVATE */
+png_write_pHYs(png_structrp png_ptr, png_uint_32 x_pixels_per_unit,
+    png_uint_32 y_pixels_per_unit,
+    int unit_type)
+{
+   png_byte buf[9];
+
+   png_debug(1, "in png_write_pHYs");
+
+   if (unit_type >= PNG_RESOLUTION_LAST)
+      png_warning(png_ptr, "Unrecognized unit type for pHYs chunk");
+
+   png_save_uint_32(buf, x_pixels_per_unit);
+   png_save_uint_32(buf + 4, y_pixels_per_unit);
+   buf[8] = (png_byte)unit_type;
+
+   png_write_complete_chunk(png_ptr, png_pHYs, buf, (png_size_t)9);
+}
+#endif
+
+#ifdef PNG_WRITE_tIME_SUPPORTED
+/* Write the tIME chunk.  Use either png_convert_from_struct_tm()
+ * or png_convert_from_time_t(), or fill in the structure yourself.
+ */
+void /* PRIVATE */
+png_write_tIME(png_structrp png_ptr, png_const_timep mod_time)
+{
+   png_byte buf[7];
+
+   png_debug(1, "in png_write_tIME");
+
+   if (mod_time->month  > 12 || mod_time->month  < 1 ||
+       mod_time->day    > 31 || mod_time->day    < 1 ||
+       mod_time->hour   > 23 || mod_time->second > 60)
+   {
+      png_warning(png_ptr, "Invalid time specified for tIME chunk");
+      return;
+   }
+
+   png_save_uint_16(buf, mod_time->year);
+   buf[2] = mod_time->month;
+   buf[3] = mod_time->day;
+   buf[4] = mod_time->hour;
+   buf[5] = mod_time->minute;
+   buf[6] = mod_time->second;
+
+   png_write_complete_chunk(png_ptr, png_tIME, buf, (png_size_t)7);
+}
+#endif
+
+/* Initializes the row writing capability of libpng */
+void /* PRIVATE */
+png_write_start_row(png_structrp png_ptr)
+{
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+   /* Start of interlace block */
+   static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+   /* Offset to next interlace block */
+   static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+   /* Start of interlace block in the y direction */
+   static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+
+   /* Offset to next interlace block in the y direction */
+   static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif
+
+   png_alloc_size_t buf_size;
+   int usr_pixel_depth;
+
+   png_debug(1, "in png_write_start_row");
+
+   usr_pixel_depth = png_ptr->usr_channels * png_ptr->usr_bit_depth;
+   buf_size = PNG_ROWBYTES(usr_pixel_depth, png_ptr->width) + 1;
+
+   /* 1.5.6: added to allow checking in the row write code. */
+   png_ptr->transformed_pixel_depth = png_ptr->pixel_depth;
+   png_ptr->maximum_pixel_depth = (png_byte)usr_pixel_depth;
+
+   /* Set up row buffer */
+   png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, buf_size);
+
+   png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE;
+
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+   /* Set up filtering buffer, if using this filter */
+   if (png_ptr->do_filter & PNG_FILTER_SUB)
+   {
+      png_ptr->sub_row = (png_bytep)png_malloc(png_ptr, png_ptr->rowbytes + 1);
+
+      png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
+   }
+
+   /* We only need to keep the previous row if we are using one of these. */
+   if ((png_ptr->do_filter &
+      (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH)) != 0)
+   {
+      /* Set up previous row buffer */
+      png_ptr->prev_row = (png_bytep)png_calloc(png_ptr, buf_size);
+
+      if ((png_ptr->do_filter & PNG_FILTER_UP) != 0)
+      {
+         png_ptr->up_row = (png_bytep)png_malloc(png_ptr,
+            png_ptr->rowbytes + 1);
+
+         png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
+      }
+
+      if ((png_ptr->do_filter & PNG_FILTER_AVG) != 0)
+      {
+         png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
+             png_ptr->rowbytes + 1);
+
+         png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
+      }
+
+      if ((png_ptr->do_filter & PNG_FILTER_PAETH) != 0)
+      {
+         png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr,
+             png_ptr->rowbytes + 1);
+
+         png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
+      }
+   }
+#endif /* WRITE_FILTER */
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+   /* If interlaced, we need to set up width and height of pass */
+   if (png_ptr->interlaced != 0)
+   {
+      if ((png_ptr->transformations & PNG_INTERLACE) == 0)
+      {
+         png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
+             png_pass_ystart[0]) / png_pass_yinc[0];
+
+         png_ptr->usr_width = (png_ptr->width + png_pass_inc[0] - 1 -
+             png_pass_start[0]) / png_pass_inc[0];
+      }
+
+      else
+      {
+         png_ptr->num_rows = png_ptr->height;
+         png_ptr->usr_width = png_ptr->width;
+      }
+   }
+
+   else
+#endif
+   {
+      png_ptr->num_rows = png_ptr->height;
+      png_ptr->usr_width = png_ptr->width;
+   }
+}
+
+/* Internal use only.  Called when finished processing a row of data. */
+void /* PRIVATE */
+png_write_finish_row(png_structrp png_ptr)
+{
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+   /* Start of interlace block */
+   static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+   /* Offset to next interlace block */
+   static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+   /* Start of interlace block in the y direction */
+   static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+
+   /* Offset to next interlace block in the y direction */
+   static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif
+
+   png_debug(1, "in png_write_finish_row");
+
+   /* Next row */
+   png_ptr->row_number++;
+
+   /* See if we are done */
+   if (png_ptr->row_number < png_ptr->num_rows)
+      return;
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+   /* If interlaced, go to next pass */
+   if (png_ptr->interlaced != 0)
+   {
+      png_ptr->row_number = 0;
+      if ((png_ptr->transformations & PNG_INTERLACE) != 0)
+      {
+         png_ptr->pass++;
+      }
+
+      else
+      {
+         /* Loop until we find a non-zero width or height pass */
+         do
+         {
+            png_ptr->pass++;
+
+            if (png_ptr->pass >= 7)
+               break;
+
+            png_ptr->usr_width = (png_ptr->width +
+                png_pass_inc[png_ptr->pass] - 1 -
+                png_pass_start[png_ptr->pass]) /
+                png_pass_inc[png_ptr->pass];
+
+            png_ptr->num_rows = (png_ptr->height +
+                png_pass_yinc[png_ptr->pass] - 1 -
+                png_pass_ystart[png_ptr->pass]) /
+                png_pass_yinc[png_ptr->pass];
+
+            if ((png_ptr->transformations & PNG_INTERLACE) != 0)
+               break;
+
+         } while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0);
+
+      }
+
+      /* Reset the row above the image for the next pass */
+      if (png_ptr->pass < 7)
+      {
+         if (png_ptr->prev_row != NULL)
+            memset(png_ptr->prev_row, 0,
+                (png_size_t)(PNG_ROWBYTES(png_ptr->usr_channels*
+                png_ptr->usr_bit_depth, png_ptr->width)) + 1);
+
+         return;
+      }
+   }
+#endif
+
+   /* If we get here, we've just written the last row, so we need
+      to flush the compressor */
+   png_compress_IDAT(png_ptr, NULL, 0, Z_FINISH);
+}
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+/* Pick out the correct pixels for the interlace pass.
+ * The basic idea here is to go through the row with a source
+ * pointer and a destination pointer (sp and dp), and copy the
+ * correct pixels for the pass.  As the row gets compacted,
+ * sp will always be >= dp, so we should never overwrite anything.
+ * See the default: case for the easiest code to understand.
+ */
+void /* PRIVATE */
+png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
+{
+   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+   /* Start of interlace block */
+   static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+   /* Offset to next interlace block */
+   static PNG_CONST png_byte  png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+   png_debug(1, "in png_do_write_interlace");
+
+   /* We don't have to do anything on the last pass (6) */
+   if (pass < 6)
+   {
+      /* Each pixel depth is handled separately */
+      switch (row_info->pixel_depth)
+      {
+         case 1:
+         {
+            png_bytep sp;
+            png_bytep dp;
+            int shift;
+            int d;
+            int value;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+
+            dp = row;
+            d = 0;
+            shift = 7;
+
+            for (i = png_pass_start[pass]; i < row_width;
+               i += png_pass_inc[pass])
+            {
+               sp = row + (png_size_t)(i >> 3);
+               value = (int)(*sp >> (7 - (int)(i & 0x07))) & 0x01;
+               d |= (value << shift);
+
+               if (shift == 0)
+               {
+                  shift = 7;
+                  *dp++ = (png_byte)d;
+                  d = 0;
+               }
+
+               else
+                  shift--;
+
+            }
+            if (shift != 7)
+               *dp = (png_byte)d;
+
+            break;
+         }
+
+         case 2:
+         {
+            png_bytep sp;
+            png_bytep dp;
+            int shift;
+            int d;
+            int value;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+
+            dp = row;
+            shift = 6;
+            d = 0;
+
+            for (i = png_pass_start[pass]; i < row_width;
+               i += png_pass_inc[pass])
+            {
+               sp = row + (png_size_t)(i >> 2);
+               value = (*sp >> ((3 - (int)(i & 0x03)) << 1)) & 0x03;
+               d |= (value << shift);
+
+               if (shift == 0)
+               {
+                  shift = 6;
+                  *dp++ = (png_byte)d;
+                  d = 0;
+               }
+
+               else
+                  shift -= 2;
+            }
+            if (shift != 6)
+               *dp = (png_byte)d;
+
+            break;
+         }
+
+         case 4:
+         {
+            png_bytep sp;
+            png_bytep dp;
+            int shift;
+            int d;
+            int value;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+
+            dp = row;
+            shift = 4;
+            d = 0;
+            for (i = png_pass_start[pass]; i < row_width;
+                i += png_pass_inc[pass])
+            {
+               sp = row + (png_size_t)(i >> 1);
+               value = (*sp >> ((1 - (int)(i & 0x01)) << 2)) & 0x0f;
+               d |= (value << shift);
+
+               if (shift == 0)
+               {
+                  shift = 4;
+                  *dp++ = (png_byte)d;
+                  d = 0;
+               }
+
+               else
+                  shift -= 4;
+            }
+            if (shift != 4)
+               *dp = (png_byte)d;
+
+            break;
+         }
+
+         default:
+         {
+            png_bytep sp;
+            png_bytep dp;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+            png_size_t pixel_bytes;
+
+            /* Start at the beginning */
+            dp = row;
+
+            /* Find out how many bytes each pixel takes up */
+            pixel_bytes = (row_info->pixel_depth >> 3);
+
+            /* Loop through the row, only looking at the pixels that matter */
+            for (i = png_pass_start[pass]; i < row_width;
+               i += png_pass_inc[pass])
+            {
+               /* Find out where the original pixel is */
+               sp = row + (png_size_t)i * pixel_bytes;
+
+               /* Move the pixel */
+               if (dp != sp)
+                  memcpy(dp, sp, pixel_bytes);
+
+               /* Next pixel */
+               dp += pixel_bytes;
+            }
+            break;
+         }
+      }
+      /* Set new row width */
+      row_info->width = (row_info->width +
+          png_pass_inc[pass] - 1 -
+          png_pass_start[pass]) /
+          png_pass_inc[pass];
+
+      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
+          row_info->width);
+   }
+}
+#endif
+
+/* This filters the row, chooses which filter to use, if it has not already
+ * been specified by the application, and then writes the row out with the
+ * chosen filter.
+ */
+static void
+png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row,
+   png_size_t row_bytes);
+
+#define PNG_MAXSUM (((png_uint_32)(-1)) >> 1)
+#define PNG_HISHIFT 10
+#define PNG_LOMASK ((png_uint_32)0xffffL)
+#define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT))
+void /* PRIVATE */
+png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
+{
+   png_bytep best_row;
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+   png_bytep prev_row, row_buf;
+   png_uint_32 mins, bpp;
+   png_byte filter_to_do = png_ptr->do_filter;
+   png_size_t row_bytes = row_info->rowbytes;
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+   int num_p_filters = png_ptr->num_prev_filters;
+#endif
+
+   png_debug(1, "in png_write_find_filter");
+
+#ifndef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+  if (png_ptr->row_number == 0 && filter_to_do == PNG_ALL_FILTERS)
+  {
+     /* These will never be selected so we need not test them. */
+     filter_to_do &= ~(PNG_FILTER_UP | PNG_FILTER_PAETH);
+  }
+#endif
+
+   /* Find out how many bytes offset each pixel is */
+   bpp = (row_info->pixel_depth + 7) >> 3;
+
+   prev_row = png_ptr->prev_row;
+#endif
+   best_row = png_ptr->row_buf;
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+   row_buf = best_row;
+   mins = PNG_MAXSUM;
+
+   /* The prediction method we use is to find which method provides the
+    * smallest value when summing the absolute values of the distances
+    * from zero, using anything >= 128 as negative numbers.  This is known
+    * as the "minimum sum of absolute differences" heuristic.  Other
+    * heuristics are the "weighted minimum sum of absolute differences"
+    * (experimental and can in theory improve compression), and the "zlib
+    * predictive" method (not implemented yet), which does test compressions
+    * of lines using different filter methods, and then chooses the
+    * (series of) filter(s) that give minimum compressed data size (VERY
+    * computationally expensive).
+    *
+    * GRR 980525:  consider also
+    *
+    *   (1) minimum sum of absolute differences from running average (i.e.,
+    *       keep running sum of non-absolute differences & count of bytes)
+    *       [track dispersion, too?  restart average if dispersion too large?]
+    *
+    *  (1b) minimum sum of absolute differences from sliding average, probably
+    *       with window size <= deflate window (usually 32K)
+    *
+    *   (2) minimum sum of squared differences from zero or running average
+    *       (i.e., ~ root-mean-square approach)
+    */
+
+
+   /* We don't need to test the 'no filter' case if this is the only filter
+    * that has been chosen, as it doesn't actually do anything to the data.
+    */
+   if ((filter_to_do & PNG_FILTER_NONE) != 0 && filter_to_do != PNG_FILTER_NONE)
+   {
+      png_bytep rp;
+      png_uint_32 sum = 0;
+      png_size_t i;
+      int v;
+
+      for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++)
+      {
+         v = *rp;
+         sum += (v < 128) ? v : 256 - v;
+      }
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+      {
+         png_uint_32 sumhi, sumlo;
+         int j;
+         sumlo = sum & PNG_LOMASK;
+         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; /* Gives us some footroom */
+
+         /* Reduce the sum if we match any of the previous rows */
+         for (j = 0; j < num_p_filters; j++)
+         {
+            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE)
+            {
+               sumlo = (sumlo * png_ptr->filter_weights[j]) >>
+                   PNG_WEIGHT_SHIFT;
+
+               sumhi = (sumhi * png_ptr->filter_weights[j]) >>
+                   PNG_WEIGHT_SHIFT;
+            }
+         }
+
+         /* Factor in the cost of this filter (this is here for completeness,
+          * but it makes no sense to have a "cost" for the NONE filter, as
+          * it has the minimum possible computational cost - none).
+          */
+         sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >>
+             PNG_COST_SHIFT;
+
+         sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >>
+             PNG_COST_SHIFT;
+
+         if (sumhi > PNG_HIMASK)
+            sum = PNG_MAXSUM;
+
+         else
+            sum = (sumhi << PNG_HISHIFT) + sumlo;
+      }
+#endif
+      mins = sum;
+   }
+
+   /* Sub filter */
+   if (filter_to_do == PNG_FILTER_SUB)
+   /* It's the only filter so no testing is needed */
+   {
+      png_bytep rp, lp, dp;
+      png_size_t i;
+
+      for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
+           i++, rp++, dp++)
+      {
+         *dp = *rp;
+      }
+
+      for (lp = row_buf + 1; i < row_bytes;
+         i++, rp++, lp++, dp++)
+      {
+         *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
+      }
+
+      best_row = png_ptr->sub_row;
+   }
+
+   else if ((filter_to_do & PNG_FILTER_SUB) != 0)
+   {
+      png_bytep rp, dp, lp;
+      png_uint_32 sum = 0, lmins = mins;
+      png_size_t i;
+      int v;
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+      /* We temporarily increase the "minimum sum" by the factor we
+       * would reduce the sum of this filter, so that we can do the
+       * early exit comparison without scaling the sum each time.
+       */
+      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+      {
+         int j;
+         png_uint_32 lmhi, lmlo;
+         lmlo = lmins & PNG_LOMASK;
+         lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
+
+         for (j = 0; j < num_p_filters; j++)
+         {
+            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB)
+            {
+               lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
+                   PNG_WEIGHT_SHIFT;
+
+               lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
+                   PNG_WEIGHT_SHIFT;
+            }
+         }
+
+         lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
+             PNG_COST_SHIFT;
+
+         lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
+             PNG_COST_SHIFT;
+
+         if (lmhi > PNG_HIMASK)
+            lmins = PNG_MAXSUM;
+
+         else
+            lmins = (lmhi << PNG_HISHIFT) + lmlo;
+      }
+#endif
+
+      for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
+           i++, rp++, dp++)
+      {
+         v = *dp = *rp;
+
+         sum += (v < 128) ? v : 256 - v;
+      }
+
+      for (lp = row_buf + 1; i < row_bytes;
+         i++, rp++, lp++, dp++)
+      {
+         v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
+
+         sum += (v < 128) ? v : 256 - v;
+
+         if (sum > lmins)  /* We are already worse, don't continue. */
+            break;
+      }
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+      {
+         int j;
+         png_uint_32 sumhi, sumlo;
+         sumlo = sum & PNG_LOMASK;
+         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
+
+         for (j = 0; j < num_p_filters; j++)
+         {
+            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB)
+            {
+               sumlo = (sumlo * png_ptr->inv_filter_weights[j]) >>
+                   PNG_WEIGHT_SHIFT;
+
+               sumhi = (sumhi * png_ptr->inv_filter_weights[j]) >>
+                   PNG_WEIGHT_SHIFT;
+            }
+         }
+
+         sumlo = (sumlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
+             PNG_COST_SHIFT;
+
+         sumhi = (sumhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
+             PNG_COST_SHIFT;
+
+         if (sumhi > PNG_HIMASK)
+            sum = PNG_MAXSUM;
+
+         else
+            sum = (sumhi << PNG_HISHIFT) + sumlo;
+      }
+#endif
+
+      if (sum < mins)
+      {
+         mins = sum;
+         best_row = png_ptr->sub_row;
+      }
+   }
+
+   /* Up filter */
+   if (filter_to_do == PNG_FILTER_UP)
+   {
+      png_bytep rp, dp, pp;
+      png_size_t i;
+
+      for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
+          pp = prev_row + 1; i < row_bytes;
+          i++, rp++, pp++, dp++)
+      {
+         *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
+      }
+
+      best_row = png_ptr->up_row;
+   }
+
+   else if ((filter_to_do & PNG_FILTER_UP) != 0)
+   {
+      png_bytep rp, dp, pp;
+      png_uint_32 sum = 0, lmins = mins;
+      png_size_t i;
+      int v;
+
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+      {
+         int j;
+         png_uint_32 lmhi, lmlo;
+         lmlo = lmins & PNG_LOMASK;
+         lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
+
+         for (j = 0; j < num_p_filters; j++)
+         {
+            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP)
+            {
+               lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
+                   PNG_WEIGHT_SHIFT;
+
+               lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
+                   PNG_WEIGHT_SHIFT;
+            }
+         }
+
+         lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >>
+             PNG_COST_SHIFT;
+
+         lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >>
+             PNG_COST_SHIFT;
+
+         if (lmhi > PNG_HIMASK)
+            lmins = PNG_MAXSUM;
+
+         else
+            lmins = (lmhi << PNG_HISHIFT) + lmlo;
+      }
+#endif
+
+      for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
+          pp = prev_row + 1; i < row_bytes; i++)
+      {
+         v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
+
+         sum += (v < 128) ? v : 256 - v;
+
+         if (sum > lmins)  /* We are already worse, don't continue. */
+            break;
+      }
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+      {
+         int j;
+         png_uint_32 sumhi, sumlo;
+         sumlo = sum & PNG_LOMASK;
+         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
+
+         for (j = 0; j < num_p_filters; j++)
+         {
+            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP)
+            {
+               sumlo = (sumlo * png_ptr->filter_weights[j]) >>
+                   PNG_WEIGHT_SHIFT;
+
+               sumhi = (sumhi * png_ptr->filter_weights[j]) >>
+                   PNG_WEIGHT_SHIFT;
+            }
+         }
+
+         sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >>
+             PNG_COST_SHIFT;
+
+         sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >>
+             PNG_COST_SHIFT;
+
+         if (sumhi > PNG_HIMASK)
+            sum = PNG_MAXSUM;
+
+         else
+            sum = (sumhi << PNG_HISHIFT) + sumlo;
+      }
+#endif
+
+      if (sum < mins)
+      {
+         mins = sum;
+         best_row = png_ptr->up_row;
+      }
+   }
+
+   /* Avg filter */
+   if (filter_to_do == PNG_FILTER_AVG)
+   {
+      png_bytep rp, dp, pp, lp;
+      png_uint_32 i;
+
+      for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
+           pp = prev_row + 1; i < bpp; i++)
+      {
+         *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
+      }
+
+      for (lp = row_buf + 1; i < row_bytes; i++)
+      {
+         *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2))
+                 & 0xff);
+      }
+      best_row = png_ptr->avg_row;
+   }
+
+   else if ((filter_to_do & PNG_FILTER_AVG) != 0)
+   {
+      png_bytep rp, dp, pp, lp;
+      png_uint_32 sum = 0, lmins = mins;
+      png_size_t i;
+      int v;
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+      {
+         int j;
+         png_uint_32 lmhi, lmlo;
+         lmlo = lmins & PNG_LOMASK;
+         lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
+
+         for (j = 0; j < num_p_filters; j++)
+         {
+            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_AVG)
+            {
+               lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
+                   PNG_WEIGHT_SHIFT;
+
+               lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
+                   PNG_WEIGHT_SHIFT;
+            }
+         }
+
+         lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >>
+             PNG_COST_SHIFT;
+
+         lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >>
+             PNG_COST_SHIFT;
+
+         if (lmhi > PNG_HIMASK)
+            lmins = PNG_MAXSUM;
+
+         else
+            lmins = (lmhi << PNG_HISHIFT) + lmlo;
+      }
+#endif
+
+      for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
+           pp = prev_row + 1; i < bpp; i++)
+      {
+         v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
+
+         sum += (v < 128) ? v : 256 - v;
+      }
+
+      for (lp = row_buf + 1; i < row_bytes; i++)
+      {
+         v = *dp++ =
+             (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) & 0xff);
+
+         sum += (v < 128) ? v : 256 - v;
+
+         if (sum > lmins)  /* We are already worse, don't continue. */
+            break;
+      }
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+      {
+         int j;
+         png_uint_32 sumhi, sumlo;
+         sumlo = sum & PNG_LOMASK;
+         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
+
+         for (j = 0; j < num_p_filters; j++)
+         {
+            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE)
+            {
+               sumlo = (sumlo * png_ptr->filter_weights[j]) >>
+                   PNG_WEIGHT_SHIFT;
+
+               sumhi = (sumhi * png_ptr->filter_weights[j]) >>
+                   PNG_WEIGHT_SHIFT;
+            }
+         }
+
+         sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >>
+             PNG_COST_SHIFT;
+
+         sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >>
+             PNG_COST_SHIFT;
+
+         if (sumhi > PNG_HIMASK)
+            sum = PNG_MAXSUM;
+
+         else
+            sum = (sumhi << PNG_HISHIFT) + sumlo;
+      }
+#endif
+
+      if (sum < mins)
+      {
+         mins = sum;
+         best_row = png_ptr->avg_row;
+      }
+   }
+
+   /* Paeth filter */
+   if ((filter_to_do == PNG_FILTER_PAETH) != 0)
+   {
+      png_bytep rp, dp, pp, cp, lp;
+      png_size_t i;
+
+      for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
+          pp = prev_row + 1; i < bpp; i++)
+      {
+         *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
+      }
+
+      for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++)
+      {
+         int a, b, c, pa, pb, pc, p;
+
+         b = *pp++;
+         c = *cp++;
+         a = *lp++;
+
+         p = b - c;
+         pc = a - c;
+
+#ifdef PNG_USE_ABS
+         pa = abs(p);
+         pb = abs(pc);
+         pc = abs(p + pc);
+#else
+         pa = p < 0 ? -p : p;
+         pb = pc < 0 ? -pc : pc;
+         pc = (p + pc) < 0 ? -(p + pc) : p + pc;
+#endif
+
+         p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
+
+         *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
+      }
+      best_row = png_ptr->paeth_row;
+   }
+
+   else if ((filter_to_do & PNG_FILTER_PAETH) != 0)
+   {
+      png_bytep rp, dp, pp, cp, lp;
+      png_uint_32 sum = 0, lmins = mins;
+      png_size_t i;
+      int v;
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+      {
+         int j;
+         png_uint_32 lmhi, lmlo;
+         lmlo = lmins & PNG_LOMASK;
+         lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
+
+         for (j = 0; j < num_p_filters; j++)
+         {
+            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH)
+            {
+               lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
+                   PNG_WEIGHT_SHIFT;
+
+               lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
+                   PNG_WEIGHT_SHIFT;
+            }
+         }
+
+         lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >>
+             PNG_COST_SHIFT;
+
+         lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >>
+             PNG_COST_SHIFT;
+
+         if (lmhi > PNG_HIMASK)
+            lmins = PNG_MAXSUM;
+
+         else
+            lmins = (lmhi << PNG_HISHIFT) + lmlo;
+      }
+#endif
+
+      for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
+          pp = prev_row + 1; i < bpp; i++)
+      {
+         v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
+
+         sum += (v < 128) ? v : 256 - v;
+      }
+
+      for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++)
+      {
+         int a, b, c, pa, pb, pc, p;
+
+         b = *pp++;
+         c = *cp++;
+         a = *lp++;
+
+#ifndef PNG_SLOW_PAETH
+         p = b - c;
+         pc = a - c;
+#ifdef PNG_USE_ABS
+         pa = abs(p);
+         pb = abs(pc);
+         pc = abs(p + pc);
+#else
+         pa = p < 0 ? -p : p;
+         pb = pc < 0 ? -pc : pc;
+         pc = (p + pc) < 0 ? -(p + pc) : p + pc;
+#endif
+         p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
+#else /* SLOW_PAETH */
+         p = a + b - c;
+         pa = abs(p - a);
+         pb = abs(p - b);
+         pc = abs(p - c);
+
+         if (pa <= pb && pa <= pc)
+            p = a;
+
+         else if (pb <= pc)
+            p = b;
+
+         else
+            p = c;
+#endif /* SLOW_PAETH */
+
+         v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
+
+         sum += (v < 128) ? v : 256 - v;
+
+         if (sum > lmins)  /* We are already worse, don't continue. */
+            break;
+      }
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+      {
+         int j;
+         png_uint_32 sumhi, sumlo;
+         sumlo = sum & PNG_LOMASK;
+         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
+
+         for (j = 0; j < num_p_filters; j++)
+         {
+            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH)
+            {
+               sumlo = (sumlo * png_ptr->filter_weights[j]) >>
+                   PNG_WEIGHT_SHIFT;
+
+               sumhi = (sumhi * png_ptr->filter_weights[j]) >>
+                   PNG_WEIGHT_SHIFT;
+            }
+         }
+
+         sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >>
+             PNG_COST_SHIFT;
+
+         sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >>
+             PNG_COST_SHIFT;
+
+         if (sumhi > PNG_HIMASK)
+            sum = PNG_MAXSUM;
+
+         else
+            sum = (sumhi << PNG_HISHIFT) + sumlo;
+      }
+#endif
+
+      if (sum < mins)
+      {
+         best_row = png_ptr->paeth_row;
+      }
+   }
+#endif /* WRITE_FILTER */
+
+   /* Do the actual writing of the filtered row data from the chosen filter. */
+   png_write_filtered_row(png_ptr, best_row, row_info->rowbytes+1);
+
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+   /* Save the type of filter we picked this time for future calculations */
+   if (png_ptr->num_prev_filters > 0)
+   {
+      int j;
+
+      for (j = 1; j < num_p_filters; j++)
+      {
+         png_ptr->prev_filters[j] = png_ptr->prev_filters[j - 1];
+      }
+
+      png_ptr->prev_filters[j] = best_row[0];
+   }
+#endif
+#endif /* WRITE_FILTER */
+}
+
+
+/* Do the actual writing of a previously filtered row. */
+static void
+png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row,
+   png_size_t full_row_length/*includes filter byte*/)
+{
+   png_debug(1, "in png_write_filtered_row");
+
+   png_debug1(2, "filter = %d", filtered_row[0]);
+
+   png_compress_IDAT(png_ptr, filtered_row, full_row_length, Z_NO_FLUSH);
+
+   /* Swap the current and previous rows */
+   if (png_ptr->prev_row != NULL)
+   {
+      png_bytep tptr;
+
+      tptr = png_ptr->prev_row;
+      png_ptr->prev_row = png_ptr->row_buf;
+      png_ptr->row_buf = tptr;
+   }
+
+   /* Finish row - updates counters and flushes zlib if last row */
+   png_write_finish_row(png_ptr);
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+   png_ptr->flush_rows++;
+
+   if (png_ptr->flush_dist > 0 &&
+       png_ptr->flush_rows >= png_ptr->flush_dist)
+   {
+      png_write_flush(png_ptr);
+   }
+#endif /* WRITE_FLUSH */
+}
+#endif /* WRITE */
diff --git a/Source/LibRawLite/COPYRIGHT b/Source/LibRawLite/COPYRIGHT
index e4ec2ff..f4d1f0e 100644
--- a/Source/LibRawLite/COPYRIGHT
+++ b/Source/LibRawLite/COPYRIGHT
@@ -1,6 +1,6 @@
  ** LibRaw: Raw images processing library **
 
-Copyright (C) 2008-2010 LibRaw LLC (http://www.libraw.org, info at libraw.org)
+Copyright (C) 2008-2013 LibRaw LLC (http://www.libraw.org, info at libraw.org)
  
 LibRaw is free software; you can redistribute it and/or modify
 it under the terms of the one of three licenses as you choose:
@@ -16,8 +16,11 @@ it under the terms of the one of three licenses as you choose:
 
 
 LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder,
-dcraw.c is copyright 1997-2010 by Dave Coffin, dcoffin a cybercom o net.
+dcraw.c is copyright 1997-2012 by Dave Coffin, dcoffin a cybercom o net.
 
 LibRaw uses DCB demosaic and FBDD denoise licensed under BSD-like 3-clause license
 DCB and FBDD are Copyright (C) 2010,  Jacek Gozdz (cuniek at kft.umcs.lublin.pl)
 
+LibRaw uses X3F library to unpack Foveon Files, licensed BSD-style license
+Copyright (c) 2010, Roland Karlsson (roland at proxel.se)
+All rights reserved.
diff --git a/Source/LibRawLite/Changelog.txt b/Source/LibRawLite/Changelog.txt
index 76dd7a2..925ebcf 100644
--- a/Source/LibRawLite/Changelog.txt
+++ b/Source/LibRawLite/Changelog.txt
@@ -1,15 +1,332 @@
-2012-06-27 Alex Tutubalin <lexa at lexa.ru>
-        * Imported dcraw 9.15 (1.449):
-          - New cameras supported: Canon 5D Mark III, G1 X, 1D X and Powershot SX200;
-            Nikon D4,D800/D800E and D3200; Fuji X-S1 and HS30EXR; Casio EX-Z8;
-            Olympus E-M5; Panasonic GF5; Sony NEX-F3, SLT-A37 and SLT-A57;
-            Samsung NX20 and NX210;
-          - Support for updated Samsung NX200 firmware.
-        * Makefile.msvc: additional compiler flags
-        * LibRaw 0.14.7-Release
-
-2012-04-11 Alex Tutubalin <lexa at lexa.ru>
-        * Fixed thumbnail processing (esp. for Adobe Lightroom DNGs)
+2015-03-02  Alex Tutubalin <lexa at lexa.ru>
+
+ * LibRaw 0.17 Alpha 1.
+
+ * More metadata parsing/extraction:
+    - XMP packet extracted (if exists)
+    - DNG Color information parsed
+    - GPS data (partially) parsed
+    - EXIF/Makernotes parsed for used optics (for both RAW files and DNG converted by Adobe convertor).
+
+ * Exif/Makernotes parser callback (called for each processed tag)
+
+ * Sony ARW2.3 decoder:
+   - params.sony_arw2_hack removed, decoded data are always in 0...17k range (note the difference with dcraw!)
+   - Additional processing options for Sony lossy compression techincal analysis.
+
+ * Dcraw 9.24 imported (but some changes not approved because Libraw do it better).
+
+ * Many improvements in data decoding/processing:
+    - Correct decoding of black level values from metadata for many formats, LibRaw do not rely on hardcoded black levels.
+
+ * 196 camera models added to supported camera list.
+   Some of them are new (released since LibRaw 0.16 come out), some was supported before, but missed from the list.
+   Added cameras are:
+
+  Alcatel 5035D
+  BlackMagic Pocket Cinema Camera, Production Camera 4k
+  Canon PowerShot A550, A3300 IS, G1 X Mark II, G7 X, SD950, SX60 HS, EOS 7D Mark II, EOS 20Da, EOS 60Da, EOS 1200D, EOS-1D C
+  Casio EX-FC300S, EX-FC400S, EX-Z1080, EX-ZR700, EX-ZR710, EX-ZR750, EX-ZR800, EX-ZR850, EX-ZR1000, EX-ZR1100, ZR1200, ZR1300, EX-ZR1500, EX-100, EX-10
+  Digital Bolex D16,D16M
+  DJI 4384x3288,
+  Epson R-D1s, R-D1x
+  FujiFilm E505,S1,S205EXR,HS10,HS11,HS22EXR,HS33EXR,HS35EXR,F505EXR,F605EXR,F775EXR,F900EXR,X100T,X30,X-T1,X-T1 Graphite Silver
+  Hasselblad H5D-60, H5D-50,H5D-50c,H5D-40,H4D-60,H4D-50,H4D-40,H4D-31,H3DII-22,H3DII-31,H3DII-39,H3DII-50,H3D-22,H3D-31,H3D-39,H2D-22,H2D-39,CF-22,CF-31,CF-39,Stellar II,HV
+  HTC UltraPixel
+  Imacon Ixpress 96, 96C, 384, 384C (single shot only),132C,  528C (single shot only)
+  ISG 2020x1520
+  Ikonoskop A-Cam dII Panchromatic, A-Cam dII
+  Kinefinity KineMINI, KineRAW Mini, KineRAW S35
+  Kodak DCS460D, S-1
+  Leaf Credo 50
+  Lenovo a820
+  Leica Digital-Modul-R, D-Lux (Typ 109), M (Typ 240), Monochrom (Typ 240), M-E, M-P, R8, S, T (Typ 701), X (Typ 113), X2, X-E (Typ 102), V-Lux (Typ 114),
+  Matrix 4608x3288
+  Nikon D4s, D600, D610, D750, D800, D800E, D810, D3300, D5500, Df, 1 J4, 1 S2, 1 V3, Coolpix P340, Coolscan NEF
+  Nokia 1200x1600
+  Olympus E-450, E-600, E-PL6, E-PL7, E-M1, E-M10, E-M5 Mark II, SP565UZ, STYLUS1s
+  Panasonic DMC-CM1, DMC-FZ7, DMC-FZ70, DMC-FZ1000, DMC-GF7, DMC-GH4, AG-GH4, DMC-GM1s, DMC-GM5, DMC-LX100, DMC-TZ60/61/SZ40, DMC-TZ70
+  Pentax GR, K110D, K-01,  K-S1, Q, QS-1, 645Z
+  PhaseOne IQ250, IQ260, IQ260 Achromatic, IQ280, Achromatic+, P 20+, P 21, P 25+, P 30+, P 40+
+  Ricoh GXR MOUNT A12, GXR MOUNT A16 24-85mm F3.5-5.5, GXR, S10 24-72mm F2.5-4.4 VC, GXR, GR A12 50mm F2.5 MACRO, GXR, GR LENS A12 28mm F2.5, GXR, GXR P10
+  Samsung GX-1L, NX1, NX5, NX1000, NX1100, NX30, NX300, NX300M, NX3000, NX mini, Galaxy S3, Galaxy Nexus
+  Sigma dp1 Quattro, dp2 Quattro
+  Sinar eMotion 22, eMotion 54, eSpirit 65, eMotion 75, eVolution 75, Sinarback 54
+  Sony A7 II, A7S, ILCA-77M2 (A77-II), ILCE-3000, ILCE-5000, ILCE-5100, ILCE-6000, ILCE-QX1, DSC-RX100III, DSLR-A560, NEX-VG20, NEX-VG30, NEX-VG900, IMX135-mipi 13mp, IMX135-QCOM, IMX072-mipi
+
+
+2014-02-01  Alex Tutubalin <lexa at lexa.ru>
+   * Updated Oly E-M10 & Panasonic TZ60/61 color data
+   * Updated foveon SD9-14 white level
+   * Support for 1x1 BlackLevelRepeatDim
+   * test message #3
+   
+2014-01-31  Alex Tutubalin <lexa at lexa.ru>
+   * imported dcraw 1.461: fixed error in BlackLevelDim handling
+   * Accurate work with pattern black-level (cblack[6+])
+   * Support for Olympus E-M10 and Fujifilm X-T1
+   * Adjusted possbile maximum value for Sigma SD9 small raws
+   
+2014-01-27 Alex Tutubalin <lexa at lexa.ru>
+   * dcraw 1.460:  Nikon D3300, Panasonic DMC-TZ61, Sony  ILCE-5000
+2014-01-25 Alex Tutubalin <lexa at lexa.ru>
+   * PhaseOne IQ250 support (both compressed and uncompressed)
+2014-01-21 Alex Tutubalin <lexa at lexa.ru>
+   * imgdata.params.sony_arw2_hack removed.
+     It always on for ARW2-files.
+   * New imgdata.params.sony_arw2_options processing flags
+     Values:
+       LIBRAW_SONYARW2_NONE - normal processing
+       LIBRAW_SONYARW2_BASEONLY - BASE pixels outputeed, delta pixels set to 0
+       LIBRAW_SONYARW2_DELTAONLY - Delta pixels written to raw data, base pixels zeroed
+       LIBRAW_SONYARW2_DELTAZEROBASE - Only deltas written without base offset
+
+2014-01-20 Alex Tutubalin <lexa at lexa.ru>
+  * Imported dcraw 9.20:
+    - Support for DNG BlackLevelRepeatDim tags
+    - imgdata.color.cblack[] holds variable BlackLevel for DNG files (up to ~4k values)
+    - imgdata.params.use_camera_matrix is now ON by default. Set it to 3 if you want
+      to force use of DNG embedded matrix.
+    - Tone curve for Canon RMF format supported
+    - Color data for Canon C500
+  * Additional camera support:
+     Alcatel 5035D
+     DJI 4384x3288
+     Fujifilm F900EXR 
+     Kodak 12MP
+     Matrix 4608x3288
+     Nokia 1200x1600
+     Olympus E-PL6
+     Panasonic DMC-FZ7
+
+2014-01-17 Alex Tutubalin <lexa at lexa.ru>
+  * Camera support:
+     Added: Fujifilm XE2, XQ1
+     Color data updated: Nikon D4 1 AW1/J3, Fuji X-M2
+     Fixes: Nikon D610 visible image area, Canon A3300 bayer 
+     pattern
+  * RawSpeed support: enabled processing for cameras,
+    unknown to RawSpeed
+  * Fixed error in LibRaw::unpack_thumb()
+  * little improve performance in my_strcasestr
+  * Fix compiler errors for VS2012/OpenMP
+  * Fixed typo which prevents to use Demosaic Pack GPL2
+  * LibRaw 0.16.0-Release
+
+2013-11-15 Alex Tutubalin <lexa at lexa.ru>
+  * New cameras supported
+     Leica C, X VARIO
+     Nikon D5300, D610, Df, 1 AW1
+     Nokia Lumia 1020, 1520
+     Olympus STYLUS1
+     Pentax K-3
+     Sony RX10, A3000 (ILCE-3000), 
+  * Color data updated:
+     Canon S120
+     Nikon P7800, 1 J3
+     Olympus E-M1
+  * Corrected image visible area sizes
+    Canon G16
+    Sigma pre-Merrill cameras: small and medium-sized RAWs
+
+  * Better EXIF parsing:
+     - ISO values for new Nikon cameras (D4, D800)
+     - black level extraction for Nikon D5300
+     - correct Olympus color data conversion
+
+  * Better Visual Studio compatibility (esp. old versions)
+  * Cmake build: added ws2_32 library for MinGW builds
+  * LibRaw 0.16.0-Beta1
+
+2013-10-22 Alex Tutubalin <lexa at lexa.ru>
+  * Support for new cameras:
+    Sony A7, A7R
+    Panasonic GM1
+
+  * Sony RX1R and RX100M2 color data updated.
+
+  * Sony cameras model name is set by SonyModelID EXIF tag
+  
+  * Sony ARW2: black level and color matrix extracted from EXIF data
+
+  * Samsung: black level and color matrix extracted from EXIF; 
+    Camera multipliers are now extracted correctly even if black is not 0
+
+  * Better source compatibility with Mac OS X compilation
+
+  * Better source compatibility with Win32 compilation
+
+  * DNG without Compression tag assumed uncompressed
+
+  * Better X3F-tools based Foveon support:
+    - new Foveon metadata parser based on X3F-tools. So, if LibRaw compiled
+      without demosaic-pack-GPL2, then no dcraw Foveon code used.
+    - Support for Medium resolution RAWs from DPx Merrill and SD1 cameras.
+      RAW data extracted as is (4800x1600 pixels), aspect ratio is set to
+      0.5, so these RAWs are processed to full-size 4800x3200 RGB.
+    - Support for Foveon thumbnail extraction. Only JPEG and bitmap
+      thumbnails extracted, but 'foveon' (RAW) thumbnails are really not used
+      in production cameras.
+    - New imgdata.params.force_foveon_x3f flag
+      Forces use of x3f-tools based code for Foveon processing if LibRaw
+      compiled with demosaic-pack-GPL2 (and does nothing if LibRaw compiled
+      without this pack).
+      New flag -disadcf added to dcraw_emu sample to use this flag.
+    - LibRaw do not calls exit() on broken Foveon files.
+
+  * API/ABI changed, so all code using LibRaw should be recompiled.
+
+  * LibRaw 0.16.0-Alpha3
+    
+
+2013-10-16 Alex Tutubalin <lexa at lexa.ru>
+  * Support for new cameras:
+    Canon S120 (preliminary color data), G16
+    Fujifilm X-A1 (preliminary color data)
+    Hasselblad Lunar, Stellar
+    Nikon P7800 (preliminary color data)
+    Pentax K50, K500, Q7
+    Samsung Galaxy NX (EK-GN120)
+    Sony NEX-5T
+
+  * Updated color data for:
+    Samsung NX300
+    Sony RX1R
+    Sigma SD1, SD1 Merrill, DPxx (only if non-GPL2 foveon decoder used)
+
+  * Image dimensions table for Foveon cameras (only if
+    non-GPL2 foveon decoder used)
+
+  * Fixed memory leak in x3f-tools code (new Foveon decoder)
+  * Fixed DHT-demosaic incompatibility with MS VisualStudio in OpenMP directives
+  * Additional image size checks.
+  * LibRaw 0.16-Alpha2
+
+2013-09-22 Alex Tutubalin <lexa at lexa.ru>
+  * Support for new cameras:
+     Baumer TXG14
+     Blackmagic Cinema
+     Canon EOS 70D, C500
+     Fujifilm X-M1
+     Nikon D5200
+     Olympus E-P5,E-M1
+     OmniVision OV5647 (Raspberry Pi)
+     Panasonic LF1, GX7, GF6
+     Richon GR
+     Samsung NX300, NX1100, NX2000
+     Sony RX100II, RX1R, NEX-3N
+
+  * Support for Foveon sensor based on X3F code by Roland Karlsson
+    BSD-like license, so included in main LibRaw code.
+    No 'foveon intepolation', so no way to get good colors from
+    old Sigma cameras (SD9, SD14, Polaroid x530). For modern Foveon cameras
+    one may try to create ICC profile (not supplied).
+
+    TODO: thumbnail extraction, fast cancelation    
+
+    Old foveon_*_load_raw (from dcraw) code is used if compiled with 
+    LIBRAW_DEMOSAIC_PACK_GPL2
+
+  * API Changes:
+
+    + New parameters in imgdata.params:
+      - imgdata.params.no_interpolation - disables interpolation step in 
+        LibRaw::dcraw_process() call.
+      - imgdata.params.no_auto_scale - disables call to scale_colors() in
+        LibRaw::dcraw_process() call.
+      - imgdata.params.sraw_ycc - disables Canon sRAW YCbCr to RGB conversion
+        in LibRaw::unpack() call (use for RAW analyzers 
+
+    + New Fuji X-Trans handling:
+      - imgdata.iparams.filters value is now 9 for Fuji X-Trans (instead of 2)
+      - imgdata.iparams.xtrans[6][6] matrix contains row/col to color mapping
+        for Fuji X-Trans sensor.
+
+    + LibRaw::setCancelFlag() - use for fast decoder termination
+
+    + LibRaw_abstract_datastream::make_byte_buffer() call is not needed more.
+
+    + New demosaic code: DHT Demosaic by Anton Petrusevich
+      Set params.user_qual=11 to use.
+
+    + New demosaic code: Modified AHD Demosaic by Anton Petrusevich
+      Set params.user_qual=12 to use.
+
+    + New C-API call libraw_COLOR(libraw_data_t *t, int row,int col)
+      (so LibRaw::COLOR(row,col) exposed to C-API users)
+
+  * Removed faster lossless jpeg decoder ported from RawSpeed library
+    some years ago. Build LibRaw with RawSpeed to get fast decoding.
+
+  * Fixed decoding error for some Canon sRAW files.
+
+  * Disabled RawSpeed's bad pixel processing if RawSpeed used.
+
+  * EOS M and EOS 70D added to unique Canon ID table
+
+  * Canon EOS model name normalized by unique ID table
+
+  * Backported 0.15.4 input data checks
+
+  * Support for CMake builds
+
+  * Updated RawSpeed supported camera list
+
+  * Internals changed, so all code using LibRaw should be recompiled.
+
+  * LibRaw 0.16.0-Alpha1
+
+2013-05-23 Alex Tutubalin <lexa at lexa.ru>
+
+ LibRaw 0.15-Release
+ 
+ New camera/format support:
+  * Adobe DNG:	fast Load DNG (LightRoom 4.x), support for 
+		lossy-compressed DNG (LR 4.x, requires libjpeg 6+)
+  * Canon:	G1 X, SX220 HS, EOS 5D Mark III, EOS 650D, EOS 1D-X, 
+		100D (Rebel SL1), 700D (Rebel T5i), 6D, EOS M, G15, S110, SX50
+  * Casio:	EX-ZR100,EX-Z8
+  * Fujifilm:	X-S1, HS30EXR, X1-Pro,X-E1, X20, X100S, SL1000, HS50EXR,
+  		F800EXR, XF1
+  * Leica:	D-LUX6 and V-LUX4
+  * Nikon:	D4, D3200, D800, D800E, 1 J2, 1 V2, D600, 1 J3, 1 S1, Coolpix A,
+		Coolpix P330, Coolpix P7700, D7100
+  * Olympus:	E-M5, XZ-2, XZ-10, E-PL5, E-PM2
+  * Panasonic:	G5, G6, DMC-GF5, FZ200, GH3, LX7
+  * Pentax:	MX-1, K-5 II, K-5 IIs, K-30, Q10
+  * Samsung:	EX2F, NX20, NX210, support for the new firmware for NX100
+  * Sigma:	SD15, SD1, SD1 Merill, DP1, DP1S, DP1X, DP2, DP2S, DP2X 
+		(only with Demosaic-pack-GPL2)
+  * Sony:	SLT-A58, RX-1, SLT-A99, NEX-5R, NEX-6, NEX-F3, SLT-A37, SLT-A57
+  * Multishot files:	Imacon Ixpress 39Mpix
+
+API changes:
+  1. dcraw_process() can now be called several times with different parameters 
+     without re-opening and unpacking the file for second and consecutive 
+     calls to dcraw_process
+
+  2. deleted (nobody uses those)
+   - LibRaw::dcraw_document_mode_processing  (and respective C-API)
+   - imgdata.color.color_flags data field
+
+  3. LibRaw::unpack() now decodes data into different buffers, the buffer
+     depends on the raw data type
+     - imgdata.rawdata.raw_image - 1 color component per pixel, 
+       for b/w and Bayer type sensors
+     - imgdata.rawdata.color3_image - 3 color components per pixel, 
+       sRAW/mRAW files, RawSpeed decoding
+     - imgdata.rawdata.color4_image - 4 components per pixel, the 4th 
+       component can be void
+
+   4. Support for compiling with RawSpeed library, http://rawstudio.org/blog/?p=800
+      details are in README.RawSpeed
+
+   5. Suppression of banding
+
+   6. New API calls
+     - recycle_datastream(), 
+     - open_file(wchar_t*) (Win32)
+
 
 2012-04-05 Alex Tutubalin <lexa at lexa.ru>
         * Casio EX-Z500 support
diff --git a/Source/LibRawLite/DEVELOPER-NOTES b/Source/LibRawLite/DEVELOPER-NOTES
new file mode 100644
index 0000000..498e646
--- /dev/null
+++ b/Source/LibRawLite/DEVELOPER-NOTES
@@ -0,0 +1,43 @@
+
+=== Notes for LibRaw contributor ===
+
+0. Repository
+   LibRaw public repository is located on GitHub
+   URL: 
+    http://github.com/LibRaw/LibRaw - main page
+    git://github.com/LibRaw/LibRaw.git - git URL
+
+If you wish to participate in LibRaw development please use GitHub fork.
+
+1. Some files in internal/ folder are generated from dcraw/dcraw.c file
+   by simple preprocessor internal/preprocess.pl (you need perl to run it)
+
+   dcraw/dcraw.c is a *patched* dcraw (and foveon processng code is removed
+   due to copyright).
+
+   'Official' dcraw.c changes are tracked by LibRaw team and merged to 
+   head revision at regular basis.
+
+   So, if you want to change code in internal/*.cpp files you need to change
+   dcraw/dcraw.c (and run make)
+
+2. For developer's work use Makefile from GitHub 
+   It contains rules to re-generate
+   internal/*cpp from dcraw/dcraw.c
+
+3. LibRaw distribution files are prepared by ./mkdist.sh script
+   This script
+     - regenerates internal/*cpp without #line directives
+     - generates ./configure script from autotools stuff
+     - removes developer Makefile
+     - fetches 'Official' dcraw.c from Dave Coffin's site
+     - removes .PSD files from doc/
+     - removes itself
+
+3. Please do not use ./configure script in development enviroment.
+   This script generates Makefile from ./Makefile.in for use in production.
+   The generated Makefile does not contain section to build internal/*
+   from dcraw/dcraw.c
+
+Feel free to contact us (info at libraw.org or Contact form on www.libraw.org) if
+you have any questions or suggestions.
diff --git a/Source/LibRawLite/LibRawLite.2003.vcproj b/Source/LibRawLite/LibRawLite.2003.vcproj
deleted file mode 100644
index 4531a31..0000000
--- a/Source/LibRawLite/LibRawLite.2003.vcproj
+++ /dev/null
@@ -1,196 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="7.10"
-	Name="LibRaw"
-	ProjectGUID="{1B0A722E-A6A5-4DF2-9A7F-DE24E20E6937}"
-	Keyword="Win32Proj">
-	<Platforms>
-		<Platform
-			Name="Win32"/>
-	</Platforms>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			OutputDirectory=".\Debug"
-			IntermediateDirectory=".\Debug"
-			ConfigurationType="4"
-			CharacterSet="2">
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="0"
-				AdditionalIncludeDirectories="./"
-				PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;LIBRAW_NODLL"
-				StringPooling="TRUE"
-				MinimalRebuild="FALSE"
-				BasicRuntimeChecks="3"
-				RuntimeLibrary="1"
-				UsePrecompiledHeader="2"
-				PrecompiledHeaderFile=".\Debug/LibRawLite.pch"
-				ExpandAttributedSource="FALSE"
-				AssemblerListingLocation=".\Debug/"
-				ObjectFile=".\Debug/"
-				ProgramDataBaseFileName=".\Debug/"
-				WarningLevel="3"
-				Detect64BitPortabilityProblems="FALSE"
-				DebugInformationFormat="4"
-				CompileAs="0"/>
-			<Tool
-				Name="VCCustomBuildTool"/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile=".\Debug\LibRawLite.lib"/>
-			<Tool
-				Name="VCMIDLTool"/>
-			<Tool
-				Name="VCPostBuildEventTool"/>
-			<Tool
-				Name="VCPreBuildEventTool"/>
-			<Tool
-				Name="VCPreLinkEventTool"/>
-			<Tool
-				Name="VCResourceCompilerTool"/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"/>
-			<Tool
-				Name="VCManagedWrapperGeneratorTool"/>
-			<Tool
-				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			OutputDirectory=".\Release"
-			IntermediateDirectory=".\Release"
-			ConfigurationType="4"
-			CharacterSet="2">
-			<Tool
-				Name="VCCLCompilerTool"
-				GlobalOptimizations="TRUE"
-				InlineFunctionExpansion="2"
-				EnableIntrinsicFunctions="TRUE"
-				FavorSizeOrSpeed="1"
-				OmitFramePointers="TRUE"
-				OptimizeForProcessor="3"
-				AdditionalIncludeDirectories="./"
-				PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;LIBRAW_NODLL"
-				RuntimeLibrary="0"
-				UsePrecompiledHeader="2"
-				PrecompiledHeaderFile=".\Release/LibRawLite.pch"
-				AssemblerListingLocation=".\Release/"
-				ObjectFile=".\Release/"
-				ProgramDataBaseFileName=".\Release/"
-				WarningLevel="0"
-				Detect64BitPortabilityProblems="FALSE"
-				DebugInformationFormat="0"
-				CompileAs="0"/>
-			<Tool
-				Name="VCCustomBuildTool"/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile=".\Release\LibRawLite.lib"/>
-			<Tool
-				Name="VCMIDLTool"/>
-			<Tool
-				Name="VCPostBuildEventTool"/>
-			<Tool
-				Name="VCPreBuildEventTool"/>
-			<Tool
-				Name="VCPreLinkEventTool"/>
-			<Tool
-				Name="VCResourceCompilerTool"/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"/>
-			<Tool
-				Name="VCManagedWrapperGeneratorTool"/>
-			<Tool
-				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Source Files"
-			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
-			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
-			<Filter
-				Name="internal"
-				Filter="">
-				<File
-					RelativePath=".\internal\dcraw_common.cpp">
-				</File>
-				<File
-					RelativePath=".\internal\dcraw_fileio.cpp">
-				</File>
-				<File
-					RelativePath=".\internal\demosaic_packs.cpp">
-				</File>
-			</Filter>
-			<Filter
-				Name="libraw"
-				Filter="">
-				<File
-					RelativePath=".\src\libraw_c_api.cpp">
-				</File>
-				<File
-					RelativePath=".\src\libraw_cxx.cpp">
-				</File>
-				<File
-					RelativePath=".\src\libraw_datastream.cpp">
-				</File>
-			</Filter>
-		</Filter>
-		<Filter
-			Name="Header Files"
-			Filter="h;hpp;hxx;hm;inl;inc;xsd"
-			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
-			<Filter
-				Name="internal"
-				Filter="">
-				<File
-					RelativePath=".\internal\defines.h">
-				</File>
-				<File
-					RelativePath=".\internal\libraw_bytebuffer.h">
-				</File>
-				<File
-					RelativePath=".\internal\libraw_internal_funcs.h">
-				</File>
-				<File
-					RelativePath=".\internal\var_defines.h">
-				</File>
-			</Filter>
-			<Filter
-				Name="libraw"
-				Filter="">
-				<File
-					RelativePath=".\libraw\libraw.h">
-				</File>
-				<File
-					RelativePath=".\libraw\libraw_alloc.h">
-				</File>
-				<File
-					RelativePath=".\libraw\libraw_const.h">
-				</File>
-				<File
-					RelativePath=".\libraw\libraw_datastream.h">
-				</File>
-				<File
-					RelativePath=".\libraw\libraw_internal.h">
-				</File>
-				<File
-					RelativePath=".\libraw\libraw_types.h">
-				</File>
-				<File
-					RelativePath=".\libraw\libraw_version.h">
-				</File>
-			</Filter>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
diff --git a/Source/LibRawLite/LibRawLite.2005.vcproj b/Source/LibRawLite/LibRawLite.2005.vcproj
index b1ae48c..b472ef7 100644
--- a/Source/LibRawLite/LibRawLite.2005.vcproj
+++ b/Source/LibRawLite/LibRawLite.2005.vcproj
@@ -347,10 +347,6 @@
 					>
 				</File>
 				<File
-					RelativePath=".\internal\libraw_bytebuffer.h"
-					>
-				</File>
-				<File
 					RelativePath=".\internal\libraw_internal_funcs.h"
 					>
 				</File>
diff --git a/Source/LibRawLite/LibRawLite.2008.vcproj b/Source/LibRawLite/LibRawLite.2008.vcproj
index 1fda792..7fa3f21 100644
--- a/Source/LibRawLite/LibRawLite.2008.vcproj
+++ b/Source/LibRawLite/LibRawLite.2008.vcproj
@@ -87,7 +87,7 @@
 		</Configuration>
 		<Configuration
 			Name="Debug|x64"
-			OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"
 			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
 			ConfigurationType="4"
 			CharacterSet="1"
@@ -227,7 +227,7 @@
 		</Configuration>
 		<Configuration
 			Name="Release|x64"
-			OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"
 			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
 			ConfigurationType="4"
 			CharacterSet="1"
@@ -352,10 +352,6 @@
 					>
 				</File>
 				<File
-					RelativePath=".\internal\libraw_bytebuffer.h"
-					>
-				</File>
-				<File
 					RelativePath=".\internal\libraw_internal_funcs.h"
 					>
 				</File>
diff --git a/Source/LibRawLite/LibRawLite.2013.vcxproj b/Source/LibRawLite/LibRawLite.2013.vcxproj
new file mode 100644
index 0000000..47f548d
--- /dev/null
+++ b/Source/LibRawLite/LibRawLite.2013.vcxproj
@@ -0,0 +1,203 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectName>LibRaw</ProjectName>
+    <ProjectGuid>{07F662C1-1323-42AB-B6AF-FBFD34A7437A}</ProjectGuid>
+    <RootNamespace>LibRawLite</RootNamespace>
+    <Keyword>Win32Proj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>12.0.21005.1</_ProjectFileVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>./;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;LIBRAW_NODLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+      <CompileAs>Default</CompileAs>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+    </ClCompile>
+    <Lib />
+    <PostBuildEvent>
+      <Command />
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>./;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;LIBRAW_NODLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <OpenMPSupport>true</OpenMPSupport>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <CompileAs>Default</CompileAs>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+    </ClCompile>
+    <Lib />
+    <PostBuildEvent>
+      <Command />
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <Optimization>Full</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <OmitFramePointers>true</OmitFramePointers>
+      <WholeProgramOptimization>false</WholeProgramOptimization>
+      <AdditionalIncludeDirectories>./;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;LIBRAW_NODLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <OpenMPSupport>false</OpenMPSupport>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>None</DebugInformationFormat>
+      <CompileAs>Default</CompileAs>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+    </ClCompile>
+    <Lib />
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <OmitFramePointers>true</OmitFramePointers>
+      <WholeProgramOptimization>false</WholeProgramOptimization>
+      <AdditionalIncludeDirectories>./;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;LIBRAW_NODLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <OpenMPSupport>true</OpenMPSupport>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>None</DebugInformationFormat>
+      <CompileAs>Default</CompileAs>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+      <Optimization>Full</Optimization>
+    </ClCompile>
+    <Lib />
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="internal\dcraw_common.cpp" />
+    <ClCompile Include="internal\dcraw_fileio.cpp" />
+    <ClCompile Include="internal\demosaic_packs.cpp" />
+    <ClCompile Include="src\libraw_c_api.cpp" />
+    <ClCompile Include="src\libraw_cxx.cpp" />
+    <ClCompile Include="src\libraw_datastream.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="internal\defines.h" />
+    <ClInclude Include="internal\libraw_internal_funcs.h" />
+    <ClInclude Include="internal\var_defines.h" />
+    <ClInclude Include="libraw\libraw.h" />
+    <ClInclude Include="libraw\libraw_alloc.h" />
+    <ClInclude Include="libraw\libraw_const.h" />
+    <ClInclude Include="libraw\libraw_datastream.h" />
+    <ClInclude Include="libraw\libraw_internal.h" />
+    <ClInclude Include="libraw\libraw_types.h" />
+    <ClInclude Include="libraw\libraw_version.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\LibJPEG\LibJPEG.2013.vcxproj">
+      <Project>{5e1d4e5f-e10c-4ba3-b663-f33014fd21d9}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/Source/LibRawLite/LibRawLite.2013.vcxproj.filters b/Source/LibRawLite/LibRawLite.2013.vcxproj.filters
new file mode 100644
index 0000000..7e504bb
--- /dev/null
+++ b/Source/LibRawLite/LibRawLite.2013.vcxproj.filters
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="Source Files\internal">
+      <UniqueIdentifier>{ebdefd5d-9d25-4edd-9e77-3329a0979f71}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\libraw">
+      <UniqueIdentifier>{031eceac-8076-49d1-b0e5-6ed5a3952299}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+    </Filter>
+    <Filter Include="Header Files\internal">
+      <UniqueIdentifier>{82a5a3af-1351-4b3d-9ee4-de10fd734468}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\libraw">
+      <UniqueIdentifier>{0d5a6978-bac3-4f2d-80df-a148b577ec20}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Resource Files">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="internal\dcraw_common.cpp">
+      <Filter>Source Files\internal</Filter>
+    </ClCompile>
+    <ClCompile Include="internal\dcraw_fileio.cpp">
+      <Filter>Source Files\internal</Filter>
+    </ClCompile>
+    <ClCompile Include="internal\demosaic_packs.cpp">
+      <Filter>Source Files\internal</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libraw_c_api.cpp">
+      <Filter>Source Files\libraw</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libraw_cxx.cpp">
+      <Filter>Source Files\libraw</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libraw_datastream.cpp">
+      <Filter>Source Files\libraw</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="internal\defines.h">
+      <Filter>Header Files\internal</Filter>
+    </ClInclude>
+    <ClInclude Include="internal\libraw_internal_funcs.h">
+      <Filter>Header Files\internal</Filter>
+    </ClInclude>
+    <ClInclude Include="internal\var_defines.h">
+      <Filter>Header Files\internal</Filter>
+    </ClInclude>
+    <ClInclude Include="libraw\libraw.h">
+      <Filter>Header Files\libraw</Filter>
+    </ClInclude>
+    <ClInclude Include="libraw\libraw_alloc.h">
+      <Filter>Header Files\libraw</Filter>
+    </ClInclude>
+    <ClInclude Include="libraw\libraw_const.h">
+      <Filter>Header Files\libraw</Filter>
+    </ClInclude>
+    <ClInclude Include="libraw\libraw_datastream.h">
+      <Filter>Header Files\libraw</Filter>
+    </ClInclude>
+    <ClInclude Include="libraw\libraw_internal.h">
+      <Filter>Header Files\libraw</Filter>
+    </ClInclude>
+    <ClInclude Include="libraw\libraw_types.h">
+      <Filter>Header Files\libraw</Filter>
+    </ClInclude>
+    <ClInclude Include="libraw\libraw_version.h">
+      <Filter>Header Files\libraw</Filter>
+    </ClInclude>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/Source/LibRawLite/dcraw/dcraw.1.html b/Source/LibRawLite/dcraw/dcraw.1.html
new file mode 100644
index 0000000..78ce9d5
--- /dev/null
+++ b/Source/LibRawLite/dcraw/dcraw.1.html
@@ -0,0 +1,440 @@
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<HTML><HEAD><TITLE>Manpage of dcraw</TITLE>
+</HEAD><BODY>
+<H1>dcraw</H1>
+Section: User Commands  (1)<BR>Updated: February 2, 2012<BR><A HREF="#index">Index</A>
+<A HREF="../index.html">Return to Main Contents</A><HR>
+
+
+<A NAME="lbAB"> </A>
+<H2>NAME</H2>
+
+dcraw - command-line decoder for raw digital photos
+<A NAME="lbAC"> </A>
+<H2>SYNOPSIS</H2>
+
+<B>dcraw</B>
+
+[<I>OPTION</I>]... [<I>FILE</I>]...
+<A NAME="lbAD"> </A>
+<H2>DESCRIPTION</H2>
+
+<B>dcraw</B>
+
+decodes raw photos, displays metadata, and extracts thumbnails.
+<A NAME="lbAE"> </A>
+<H2>GENERAL OPTIONS</H2>
+
+<DL COMPACT>
+<DT><B>-v</B>
+
+<DD>
+Print verbose messages, not just warnings and errors.
+<DT><B>-c</B>
+
+<DD>
+Write decoded images or thumbnails to standard output.
+<DT><B>-e</B>
+
+<DD>
+Extract the camera-generated thumbnail, not the raw image.
+You'll get either a JPEG or a PPM file, depending on the camera.
+<DT><B>-z</B>
+
+<DD>
+Change the access and modification times of an AVI, JPEG, TIFF or raw
+file to when the photo was taken, assuming that the camera clock
+was set to Universal Time.
+<DT><B>-i</B>
+
+<DD>
+Identify files but don't decode them.
+Exit status is 0 if
+<B>dcraw</B>
+
+can decode the last file, 1 if it can't.
+<B>-i -v</B>
+
+shows metadata.
+<DT><B></B>
+
+<DD>
+<B>dcraw</B>
+
+cannot decode JPEG files!!
+</DL>
+<A NAME="lbAF"> </A>
+<H2>REPAIR OPTIONS</H2>
+
+<DL COMPACT>
+<DT><B>-I</B>
+
+<DD>
+Read the raw pixels from standard input in CPU byte order with
+no header.  Use
+<B>dcraw -E -4</B>
+
+to get the raw pixel values.
+<DT><B>-P deadpixels.txt</B>
+
+<DD>
+Read the dead pixel list from this file instead of ".badpixels".
+See
+<B>FILES</B>
+
+for a description of the format.
+<DT><B>-K darkframe.pgm</B>
+
+<DD>
+Subtract a dark frame from the raw data.  To generate a
+dark frame, shoot a raw photo with no light and do
+<B>dcraw -D -4 -j -t 0</B>.
+
+<DT><B>-k darkness</B>
+
+<DD>
+When shadows appear foggy, you need to raise the darkness level.
+To measure this, apply
+<B>pamsumm -mean</B>
+
+to the dark frame generated above.
+<DT><B>-S saturation</B>
+
+<DD>
+When highlights appear pink, you need to lower the saturation level.
+To measure this, take a picture of something shiny and do
+<B>dcraw -D -4 -j -c</B>
+
+photo.raw
+<B>| pamsumm -max</B>
+
+<DT><B></B>
+
+<DD>
+The default darkness and saturation are usually correct.
+<DT><B>-n noise_threshold</B>
+
+<DD>
+Use wavelets to erase noise while preserving real detail.
+The best threshold should be somewhere between 100 and 1000.
+<DT><B>-C red_mag blue_mag</B>
+
+<DD>
+Enlarge the raw red and blue layers by the given factors,
+typically 0.999 to 1.001, to correct chromatic aberration.
+<DT><B>-H 0</B>
+
+<DD>
+Clip all highlights to solid white (default).
+<DT><B>-H 1</B>
+
+<DD>
+Leave highlights unclipped in various shades of pink.
+<DT><B>-H 2</B>
+
+<DD>
+Blend clipped and unclipped values together for a gradual fade
+to white.
+<DT><B>-H 3+</B>
+
+<DD>
+Reconstruct highlights.  Low numbers favor whites; high numbers
+favor colors.  Try
+<B>-H 5</B>
+
+as a compromise.  If that's not good enough, do
+<B>-H 9</B>,
+
+cut out the non-white highlights, and paste them into an image
+generated with
+<B>-H 3</B>.
+
+</DL>
+<A NAME="lbAG"> </A>
+<H2>COLOR OPTIONS</H2>
+
+By default,
+<B>dcraw</B>
+
+uses a fixed white balance based on a color chart illuminated
+with a standard D65 lamp.
+<DL COMPACT>
+<DT><B>-w</B>
+
+<DD>
+Use the white balance specified by the camera.
+If this is not found, print a warning and use another method.
+<DT><B>-a</B>
+
+<DD>
+Calculate the white balance by averaging the entire image.
+<DT><B>-A left top width height</B>
+
+<DD>
+Calculate the white balance by averaging a rectangular area.
+First do
+<B>dcraw -j -t 0</B>
+
+and select an area of neutral grey color.
+<DT><B>-r mul0 mul1 mul2 mul3</B>
+
+<DD>
+Specify your own raw white balance.
+These multipliers can be cut and pasted from the output of
+<B>dcraw -v</B>.
+
+<DT><B>+M</B> or <B>-M</B>
+
+<DD>
+Use (or don't use) any color matrix from the camera metadata.
+The default is
+<B>+M</B>
+
+if
+<B>-w</B>
+
+is set,
+<B>-M</B>
+
+otherwise.
+This option only affects Olympus, Leaf, and Phase One cameras.
+<DT><B>-o [0-5]</B>
+
+<DD>
+Select the output colorspace when the
+<B>-p</B>
+
+option is not used:
+<P>
+<B>	0</B>
+
+  Raw color (unique to each camera)
+<BR>
+
+<B>	1</B>
+
+  sRGB D65 (default)
+<BR>
+
+<B>	2</B>
+
+  Adobe RGB (1998) D65
+<BR>
+
+<B>	3</B>
+
+  Wide Gamut RGB D65
+<BR>
+
+<B>	4</B>
+
+  Kodak ProPhoto RGB D65
+<BR>
+
+<B>	5</B>
+
+  XYZ
+<DT><B>-p camera.icm</B> [ <B>-o output.icm</B> ]
+
+<DD>
+Use ICC profiles to define the camera's raw colorspace and the
+desired output colorspace (sRGB by default).
+<DT><B>-p embed</B>
+
+<DD>
+Use the ICC profile embedded in the raw photo.
+</DL>
+<A NAME="lbAH"> </A>
+<H2>INTERPOLATION OPTIONS</H2>
+
+<DL COMPACT>
+<DT><B>-d</B>
+
+<DD>
+Show the raw data as a grayscale image with no interpolation.
+Good for photographing black-and-white documents.
+<DT><B>-D</B>
+
+<DD>
+Same as
+<B>-d</B>,
+
+but with the original unscaled pixel values.
+<DT><B>-E</B>
+
+<DD>
+Same as
+<B>-D</B>,
+
+but masked pixels are not cropped.
+<DT><B>-h</B>
+
+<DD>
+Output a half-size color image.  Twice as fast as
+<B>-q 0</B>.
+
+<DT><B>-q 0</B>
+
+<DD>
+Use high-speed, low-quality bilinear interpolation.
+<DT><B>-q 1</B>
+
+<DD>
+Use Variable Number of Gradients (VNG) interpolation.
+<DT><B>-q 2</B>
+
+<DD>
+Use Patterned Pixel Grouping (PPG) interpolation.
+<DT><B>-q 3</B>
+
+<DD>
+Use Adaptive Homogeneity-Directed (AHD) interpolation.
+<DT><B>-f</B>
+
+<DD>
+Interpolate RGB as four colors.  Use this if the output shows
+false 2x2 meshes with VNG or mazes with AHD.
+<DT><B>-m number_of_passes</B>
+
+<DD>
+After interpolation, clean up color artifacts by repeatedly
+applying a 3x3 median filter to the R-G and B-G channels.
+</DL>
+<A NAME="lbAI"> </A>
+<H2>OUTPUT OPTIONS</H2>
+
+By default,
+<B>dcraw</B>
+
+writes PGM/PPM/PAM with 8-bit samples, a BT.709 gamma curve,
+a histogram-based white level, and no metadata.
+<DL COMPACT>
+<DT><B>-W</B>
+
+<DD>
+Use a fixed white level, ignoring the image histogram.
+<DT><B>-b brightness</B>
+
+<DD>
+Divide the white level by this number, 1.0 by default.
+<DT><B>-g power toe_slope</B>
+
+<DD>
+Set the gamma curve, by default BT.709
+(<B>-g 2.222 4.5</B>).
+
+If you prefer sRGB gamma, use
+<B>-g 2.4 12.92</B>.
+
+For a simple power curve, set the toe slope to zero.
+<DT><B>-6</B>
+
+<DD>
+Write sixteen bits per sample instead of eight.
+<DT><B>-4</B>
+
+<DD>
+Linear 16-bit, same as
+<B>-6 -W -g 1 1</B>.
+
+<DT><B>-T</B>
+
+<DD>
+Write TIFF with metadata instead of PGM/PPM/PAM.
+<DT><B>-t [0-7,90,180,270]</B>
+
+<DD>
+Flip the output image.  By default,
+<B>dcraw</B>
+
+applies the flip specified by the camera.
+<B>-t 0</B>
+
+disables all flipping.
+<DT><B>-j</B>
+
+<DD>
+For Fuji Super CCD cameras, show the image tilted 45 degrees.
+For cameras with non-square pixels, do not stretch the image to
+its correct aspect ratio.  In any case, this option guarantees
+that each output pixel corresponds to one raw pixel.
+<DT><B>-s [0..N-1]</B> or <B>-s all</B>
+
+<DD>
+If a file contains N raw images, choose one or "all" to decode.
+For example, Fuji Super CCD SR cameras generate a second image
+underexposed four stops to show detail in the highlights.
+</DL>
+<A NAME="lbAJ"> </A>
+<H2>FILES</H2>
+
+<DL COMPACT>
+<DT>:./.badpixels, ../.badpixels, ../../.badpixels, ...<DD>
+List of your camera's dead pixels, so that
+<B>dcraw</B>
+
+can interpolate around them.  Each line specifies the column,
+row, and UNIX time of death for one pixel.  For example:
+<P>
+<PRE>
+ 962   91 1028350000  # died between August 1 and 4, 2002
+1285 1067 0           # don't know when this pixel died
+</PRE>
+
+<P>
+These coordinates are before any cropping or rotation, so use
+<B>dcraw -j -t 0</B>
+
+to locate dead pixels.
+</DL>
+<A NAME="lbAK"> </A>
+<H2>SEE ALSO</H2>
+
+<B><A HREF="../man5/pgm.5.html">pgm</A></B>(5),
+
+<B><A HREF="../man5/ppm.5.html">ppm</A></B>(5),
+
+<B><A HREF="../man5/pam.5.html">pam</A></B>(5),
+
+<B><A HREF="../man1/pamsumm.1.html">pamsumm</A></B>(1),
+
+<B><A HREF="../man1/pnmgamma.1.html">pnmgamma</A></B>(1),
+
+<B><A HREF="../man1/pnmtotiff.1.html">pnmtotiff</A></B>(1),
+
+<B><A HREF="../man1/pnmtopng.1.html">pnmtopng</A></B>(1),
+
+<B><A HREF="../man1/gphoto2.1.html">gphoto2</A></B>(1),
+
+<B><A HREF="../man1/cjpeg.1.html">cjpeg</A></B>(1),
+
+<B><A HREF="../man1/djpeg.1.html">djpeg</A></B>(1)
+
+<A NAME="lbAL"> </A>
+<H2>AUTHOR</H2>
+
+Written by David Coffin, dcoffin a cybercom o net
+<P>
+
+<HR>
+<A NAME="index"> </A><H2>Index</H2>
+<DL>
+<DT><A HREF="#lbAB">NAME</A><DD>
+<DT><A HREF="#lbAC">SYNOPSIS</A><DD>
+<DT><A HREF="#lbAD">DESCRIPTION</A><DD>
+<DT><A HREF="#lbAE">GENERAL OPTIONS</A><DD>
+<DT><A HREF="#lbAF">REPAIR OPTIONS</A><DD>
+<DT><A HREF="#lbAG">COLOR OPTIONS</A><DD>
+<DT><A HREF="#lbAH">INTERPOLATION OPTIONS</A><DD>
+<DT><A HREF="#lbAI">OUTPUT OPTIONS</A><DD>
+<DT><A HREF="#lbAJ">FILES</A><DD>
+<DT><A HREF="#lbAK">SEE ALSO</A><DD>
+<DT><A HREF="#lbAL">AUTHOR</A><DD>
+</DL>
+<HR>
+This document was created by
+<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>,
+using the manual pages.<BR>
+Time: 18:30:09 GMT, February 25, 2015
+</BODY>
+</HTML>
diff --git a/Source/LibRawLite/dcraw/dcraw.c b/Source/LibRawLite/dcraw/dcraw.c
index 7f4e8f4..f90b4b6 100644
--- a/Source/LibRawLite/dcraw/dcraw.c
+++ b/Source/LibRawLite/dcraw/dcraw.c
@@ -1,6 +1,7 @@
+#ifndef IGNOREALL
 /*
    dcraw.c -- Dave Coffin's raw photo decoder
-   Copyright 1997-2012 by Dave Coffin, dcoffin a cybercom o net
+   Copyright 1997-2015 by Dave Coffin, dcoffin a cybercom o net
 
    This is a command-line ANSI C program to convert raw photos from
    any digital camera on any computer running any operating system.
@@ -19,11 +20,28 @@
    *If you have not modified dcraw.c in any way, a link to my
    homepage qualifies as "full source code".
 
-   $Revision: 1.31 $
-   $Date: 2012/07/15 12:44:06 $
+
+   $Revision: 1.44 $
+   $Date: 2015/03/08 19:19:51 $
+
+make -f Makefile.devel
+git commit -a -m "v.102"
+git push
+
  */
+/*@out DEFINES
+#ifndef USE_JPEG
+#define NO_JPEG
+#endif
+#ifndef USE_JASPER
+#define NO_JASPER
+#endif
+ at end DEFINES */
 
-#define DCRAW_VERSION "9.15"
+#define NO_LCMS
+#define DCRAW_VERBOSE
+//@out DEFINES
+#define DCRAW_VERSION "9.24"
 
 #ifndef _GNU_SOURCE
 #define _GNU_SOURCE
@@ -41,27 +59,7 @@
 #include <string.h>
 #include <time.h>
 #include <sys/types.h>
-
-#ifdef NODEPS
-#define NO_JASPER
-#define NO_JPEG
-#define NO_LCMS
-#endif
-#ifndef NO_JASPER
-#include <jasper/jasper.h>	/* Decode RED camera movies */
-#endif
-#ifndef NO_JPEG
-#include <jpeglib.h>		/* Decode compressed Kodak DC120 photos */
-#endif				/* and Adobe Lossy DNGs */
-#ifndef NO_LCMS
-#include <lcms.h>		/* Support color profiles */
-#endif
-#ifdef LOCALEDIR
-#include <libintl.h>
-#define _(String) gettext(String)
-#else
-#define _(String) (String)
-#endif
+//@end DEFINES
 
 #if defined(DJGPP) || defined(__MINGW32__)
 #define fseeko fseek
@@ -69,6 +67,7 @@
 #else
 #define fgetc getc_unlocked
 #endif
+//@out DEFINES
 #ifdef __CYGWIN__
 #include <io.h>
 #endif
@@ -79,8 +78,10 @@
 #define snprintf _snprintf
 #define strcasecmp stricmp
 #define strncasecmp strnicmp
+//@end DEFINES
 typedef __int64 INT64;
 typedef unsigned __int64 UINT64;
+//@out DEFINES
 #else
 #include <unistd.h>
 #include <utime.h>
@@ -89,6 +90,31 @@ typedef long long INT64;
 typedef unsigned long long UINT64;
 #endif
 
+#ifdef NODEPS
+#define NO_JASPER
+#define NO_JPEG
+#define NO_LCMS
+#endif
+#ifndef NO_JASPER
+#include <jasper/jasper.h>	/* Decode Red camera movies */
+#endif
+#ifndef NO_JPEG
+#include <jpeglib.h>		/* Decode compressed Kodak DC120 photos */
+#endif				/* and Adobe Lossy DNGs */
+#ifndef NO_LCMS
+#ifdef USE_LCMS
+#include <lcms.h>		/* Support color profiles */
+#else
+#include <lcms2.h>		/* Support color profiles */
+#endif
+#endif
+#ifdef LOCALEDIR
+#include <libintl.h>
+#define _(String) gettext(String)
+#else
+#define _(String) (String)
+#endif
+
 #ifdef LJPEG_DECODE
 #error Please compile dcraw.c by itself.
 #error Do not link it with ljpeg_decode.
@@ -97,6 +123,7 @@ typedef unsigned long long UINT64;
 #ifndef LONG_BIT
 #define LONG_BIT (8 * sizeof (long))
 #endif
+//@end DEFINES
 
 #if !defined(uchar)
 #define uchar unsigned char
@@ -113,28 +140,29 @@ typedef unsigned long long UINT64;
 FILE *ifp, *ofp;
 short order;
 const char *ifname;
-char *meta_data;
-char cdesc[5], desc[512], make[64], model[64], model2[64], artist[64];
+char *meta_data, xtrans[6][6], xtrans_abs[6][6];
+char cdesc[5], desc[512], make[64], model[64], model2[64], artist[64],software[64];
 float flash_used, canon_ev, iso_speed, shutter, aperture, focal_len;
 time_t timestamp;
-unsigned shot_order, kodak_cbpp, filters, exif_cfa, unique_id;
-off_t    strip_offset, data_offset;
-off_t    thumb_offset, meta_offset, profile_offset;
+off_t strip_offset, data_offset;
+off_t thumb_offset, meta_offset, profile_offset;
+unsigned shot_order, kodak_cbpp, exif_cfa, unique_id;
 unsigned thumb_length, meta_length, profile_length;
 unsigned thumb_misc, *oprof, fuji_layout, shot_select=0, multi_out=0;
 unsigned tiff_nifds, tiff_samples, tiff_bps, tiff_compress;
-unsigned black, cblack[4], maximum, mix_green, raw_color, zero_is_bad;
+unsigned black, maximum, mix_green, raw_color, zero_is_bad;
 unsigned zero_after_ff, is_raw, dng_version, is_foveon, data_error;
 unsigned tile_width, tile_length, gpsdata[32], load_flags;
+unsigned flip, tiff_flip, filters, colors;
 ushort raw_height, raw_width, height, width, top_margin, left_margin;
 ushort shrink, iheight, iwidth, fuji_width, thumb_width, thumb_height;
-ushort *raw_image, (*image)[4];
+ushort *raw_image, (*image)[4], cblack[4102];
 ushort white[8][8], curve[0x10000], cr2_slice[3], sraw_mul[4];
-int mask[8][4], flip, tiff_flip, colors;
 double pixel_aspect, aber[4]={1,1,1,1}, gamm[6]={ 0.45,4.5,0,0,0,0 };
 float bright=1, user_mul[4]={0,0,0,0}, threshold=0;
+int mask[8][4];
 int half_size=0, four_color_rgb=0, document_mode=0, highlight=0;
-int verbose=0, use_auto_wb=0, use_camera_wb=0, use_camera_matrix=-1;
+int verbose=0, use_auto_wb=0, use_camera_wb=0, use_camera_matrix=1;
 int output_color=1, output_bps=8, output_tiff=0, med_passes=0;
 int no_auto_bright=0;
 unsigned greybox[4] = { 0, 0, UINT_MAX, UINT_MAX };
@@ -155,17 +183,19 @@ struct decode {
 } first_decode[2048], *second_decode, *free_decode;
 
 struct tiff_ifd {
-  int width, height, bps, comp, phint, offset, flip, samples, bytes;
-  int tile_width, tile_length;
+  int t_width, t_height, bps, comp, phint, offset, t_flip, samples, bytes;
+  int t_tile_width, t_tile_length;
 } tiff_ifd[10];
 
 struct ph1 {
-  int format, key_off, black, black_off, split_col, tag_21a;
+  int format, key_off, tag_21a;
+  int t_black, split_col, black_col, split_row, black_row;
   float tag_210;
 } ph1;
 
 #define CLASS
 
+//@out DEFINES
 #define FORC(cnt) for (c=0; c < cnt; c++)
 #define FORC3 FORC(3)
 #define FORC4 FORC(4)
@@ -180,6 +210,8 @@ struct ph1 {
 #define CLIP(x) LIM(x,0,65535)
 #define SWAP(a,b) { a=a+b; b=a-b; a=a-b; }
 
+#define my_swap(type, i, j) {type t = i; i = j; j = t;}
+
 /*
    In order to inline this calculation, I make the risky
    assumption that all filter patterns can be described
@@ -221,16 +253,31 @@ struct ph1 {
 
 #define RAW(row,col) \
 	raw_image[(row)*raw_width+(col)]
+//@end DEFINES
 
 #define FC(row,col) \
 	(filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)
 
+//@out DEFINES
 #define BAYER(row,col) \
 	image[((row) >> shrink)*iwidth + ((col) >> shrink)][FC(row,col)]
 
 #define BAYER2(row,col) \
 	image[((row) >> shrink)*iwidth + ((col) >> shrink)][fcol(row,col)]
+//@end DEFINES
 
+/* @out COMMON
+#include <math.h>
+#define CLASS LibRaw::
+#include "libraw/libraw_types.h"
+#define LIBRAW_LIBRARY_BUILD
+#define LIBRAW_IO_REDEFINED
+#include "libraw/libraw.h"
+#include "internal/defines.h"
+#include "internal/var_defines.h"
+ at end COMMON */
+
+//@out COMMON
 int CLASS fcol (int row, int col)
 {
   static const char filter[16][16] =
@@ -250,16 +297,9 @@ int CLASS fcol (int row, int col)
     { 0,2,0,3,1,0,0,1,1,3,3,2,3,2,2,1 },
     { 2,1,3,2,3,1,2,1,0,3,0,2,0,2,0,2 },
     { 0,3,1,0,0,2,0,3,2,1,3,1,1,3,1,3 } };
-  static const char filter2[6][6] =
-  { { 1,1,0,1,1,2 },
-    { 1,1,2,1,1,0 },
-    { 2,0,1,0,2,1 },
-    { 1,1,2,1,1,0 },
-    { 1,1,0,1,1,2 },
-    { 0,2,1,2,0,1 } };
 
   if (filters == 1) return filter[(row+top_margin)&15][(col+left_margin)&15];
-  if (filters == 2) return filter2[(row+6) % 6][(col+6) % 6];
+  if (filters == 9) return xtrans[(row+6) % 6][(col+6) % 6];
   return FC(row,col);
 }
 
@@ -274,7 +314,18 @@ char *my_memmem (char *haystack, size_t haystacklen,
   return 0;
 }
 #define memmem my_memmem
+char *my_strcasestr (char *haystack, const char *needle)
+{
+  char *c;
+  for (c = haystack; *c; c++)
+    if (!strncasecmp(c, needle, strlen(needle)))
+      return c;
+  return 0;
+}
+#define strcasestr my_strcasestr
 #endif
+//@end COMMON
+
 
 void CLASS merror (void *ptr, const char *where)
 {
@@ -295,6 +346,7 @@ void CLASS derror()
   data_error++;
 }
 
+//@out COMMON
 ushort CLASS sget2 (uchar *s)
 {
   if (order == 0x4949)		/* "II" means little-endian */
@@ -303,6 +355,46 @@ ushort CLASS sget2 (uchar *s)
     return s[0] << 8 | s[1];
 }
 
+// DNG was written by:
+#define CameraDNG	1
+#define AdobeDNG	2
+
+#ifdef LIBRAW_LIBRARY_BUILD
+
+
+static ushort saneSonyCameraInfo(uchar a, uchar b, uchar c, uchar d, uchar e, uchar f){
+	if ((a >> 4) > 9) return 0;
+	else if ((a & 0x0f) > 9) return 0;
+	else if ((b >> 4) > 9) return 0;
+	else if ((b & 0x0f) > 9) return 0;
+	else if ((c >> 4) > 9) return 0;
+	else if ((c & 0x0f) > 9) return 0;
+	else if ((d >> 4) > 9) return 0;
+	else if ((d & 0x0f) > 9) return 0;
+	else if ((e >> 4) > 9) return 0;
+	else if ((e & 0x0f) > 9) return 0;
+	else if ((f >> 4) > 9) return 0;
+	else if ((f & 0x0f) > 9) return 0;
+return 1;
+}
+
+static ushort bcd2dec(uchar data){
+	if ((data >> 4) > 9) return 0;
+	else if ((data & 0x0f) > 9) return 0;
+	else return (data >> 4) * 10 + (data & 0x0f);
+}
+
+static uchar SonySubstitution[257] = "\x00\x01\x32\xb1\x0a\x0e\x87\x28\x02\xcc\xca\xad\x1b\xdc\x08\xed\x64\x86\xf0\x4f\x8c\x6c\xb8\xcb\x69\xc4\x2c\x03\x97\xb6\x93\x7c\x14\xf3\xe2\x3e\x30\x8e\xd7\x60\x1c\xa1\xab\x37\xec\x75\xbe\x23\x15\x6a\x59\x3f\xd0\xb9\x96\xb5\x50\x27\x88\xe3\x81\x94\xe0\xc0\x04\x5c\xc6\xe8\x5f\x4b\x70\x38\x9f\x82\x80\x51\x2b\xc5\x45\x49\x9b\x21\x52\x53\x54\x85\x0b\x5d\x61\xda\x7b\x55\x26\x24\x07\x6e\x36\x5b\x47\xb7\xd9\x4a\xa2\xdf\xbf\x12\x25\xbc\x1e\x7f\x56\xea\x10\x [...]
+
+ushort CLASS sget2Rev(uchar *s)	// specific to some Canon Makernotes fields, where they have endian in reverse
+{
+	if (order == 0x4d4d)		/* "II" means little-endian, and we reverse to "MM" - big endian */
+		return s[0] | s[1] << 8;
+	else						/* "MM" means big-endian... */
+		return s[0] << 8 | s[1];
+}
+#endif
+
 ushort CLASS get2()
 {
   uchar str[2] = { 0xff,0xff };
@@ -340,18 +432,22 @@ float CLASS int_to_float (int i)
 
 double CLASS getreal (int type)
 {
-  union { char c[8]; double d; } u;
+  union { char c[8]; double d; } u,v;
   int i, rev;
 
   switch (type) {
     case 3: return (unsigned short) get2();
     case 4: return (unsigned int) get4();
-    case 5:  u.d = (unsigned int) get4();
-      return u.d / (unsigned int) get4();
+    case 5:
+      u.d = (unsigned int) get4();
+      v.d = (unsigned int)get4();
+      return u.d / (v.d ? v.d : 1);
     case 8: return (signed short) get2();
     case 9: return (signed int) get4();
-    case 10: u.d = (signed int) get4();
-      return u.d / (signed int) get4();
+    case 10:
+      u.d = (signed int) get4();
+      v.d = (signed int)get4();
+      return u.d / (v.d?v.d:1);
     case 11: return int_to_float (get4());
     case 12:
       rev = 7 * ((order == 0x4949) == (ntohs(0x1234) == 0x1234));
@@ -366,7 +462,62 @@ void CLASS read_shorts (ushort *pixel, int count)
 {
   if (fread (pixel, 2, count, ifp) < count) derror();
   if ((order == 0x4949) == (ntohs(0x1234) == 0x1234))
-    swab (pixel, pixel, count*2);
+    swab ((char*)pixel, (char*)pixel, count*2);
+}
+
+void CLASS cubic_spline (const int *x_, const int *y_, const int len)
+{
+  float **A, *b, *c, *d, *x, *y;
+  int i, j;
+
+  A = (float **) calloc (((2*len + 4)*sizeof **A + sizeof *A), 2*len);
+  if (!A) return;
+  A[0] = (float *) (A + 2*len);
+  for (i = 1; i < 2*len; i++)
+    A[i] = A[0] + 2*len*i;
+  y = len + (x = i + (d = i + (c = i + (b = A[0] + i*i))));
+  for (i = 0; i < len; i++) {
+    x[i] = x_[i] / 65535.0;
+    y[i] = y_[i] / 65535.0;
+  }
+  for (i = len-1; i > 0; i--) {
+    b[i] = (y[i] - y[i-1]) / (x[i] - x[i-1]);
+    d[i-1] = x[i] - x[i-1];
+  }
+  for (i = 1; i < len-1; i++) {
+    A[i][i] = 2 * (d[i-1] + d[i]);
+    if (i > 1) {
+      A[i][i-1] = d[i-1];
+      A[i-1][i] = d[i-1];
+    }
+    A[i][len-1] = 6 * (b[i+1] - b[i]);
+  }
+  for(i = 1; i < len-2; i++) {
+    float v = A[i+1][i] / A[i][i];
+    for(j = 1; j <= len-1; j++)
+      A[i+1][j] -= v * A[i][j];
+  }
+  for(i = len-2; i > 0; i--) {
+    float acc = 0;
+    for(j = i; j <= len-2; j++)
+      acc += A[i][j]*c[j];
+    c[i] = (A[i][len-1] - acc) / A[i][i];
+  }
+  for (i = 0; i < 0x10000; i++) {
+    float x_out = (float)(i / 65535.0);
+    float y_out = 0;
+    for (j = 0; j < len-1; j++) {
+      if (x[j] <= x_out && x_out <= x[j+1]) {
+	float v = x_out - x[j];
+	y_out = y[j] +
+	  ((y[j+1] - y[j]) / d[j] - (2 * d[j] * c[j] + c[j+1] * d[j])/6) * v
+	   + (c[j] * 0.5) * v*v + ((c[j+1] - c[j]) / (6 * d[j])) * v*v*v;
+      }
+    }
+    curve[i] = y_out < 0.0 ? 0 : (y_out >= 1.0 ? 65535 :
+		(ushort)(y_out * 65535.0 + 0.5));
+  }
+  free (A);
 }
 
 void CLASS canon_600_fixed_wb (int temp)
@@ -492,6 +643,9 @@ void CLASS canon_600_load_raw()
   int irow, row;
 
   for (irow=row=0; irow < height; irow++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     if (fread (data, 1, 1120, ifp) < 1120) derror();
     pix = raw_image + row*raw_width;
     for (dp=data; dp < data+1120;  dp+=10, pix+=8) {
@@ -515,11 +669,16 @@ void CLASS canon_600_correct()
   { { 1141,1145 }, { 1128,1109 }, { 1178,1149 }, { 1128,1109 } };
 
   for (row=0; row < height; row++)
+    {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     for (col=0; col < width; col++) {
       if ((val = BAYER(row,col) - black) < 0) val = 0;
       val = val * mul[row & 3][col & 1] >> 9;
       BAYER(row,col) = val;
     }
+    }
   canon_600_fixed_wb(1311);
   canon_600_auto_wb();
   canon_600_coeff();
@@ -538,17 +697,20 @@ int CLASS canon_s2is()
   return 0;
 }
 
-/*
-   getbits(-1) initializes the buffer
-   getbits(n) where 0 <= n <= 25 returns an n-bit integer
- */
 unsigned CLASS getbithuff (int nbits, ushort *huff)
 {
+#ifdef LIBRAW_NOTHREADS
   static unsigned bitbuf=0;
   static int vbits=0, reset=0;
+#else
+#define bitbuf tls->getbits.bitbuf
+#define vbits  tls->getbits.vbits
+#define reset  tls->getbits.reset
+#endif
   unsigned c;
 
-  if (nbits == -1)
+  if (nbits > 25) return 0;
+  if (nbits < 0)
     return bitbuf = vbits = reset = 0;
   if (nbits == 0 || vbits < 0) return 0;
   while (!reset && vbits < nbits && (c = fgetc(ifp)) != EOF &&
@@ -564,6 +726,11 @@ unsigned CLASS getbithuff (int nbits, ushort *huff)
     vbits -= nbits;
   if (vbits < 0) derror();
   return c;
+#ifndef LIBRAW_NOTHREADS
+#undef bitbuf
+#undef vbits
+#undef reset
+#endif
 }
 
 #define getbits(n) getbithuff(n,0)
@@ -714,7 +881,13 @@ void CLASS canon_load_raw()
   fseek (ifp, 540 + lowbits*raw_height*raw_width/4, SEEK_SET);
   zero_after_ff = 1;
   getbits(-1);
+#ifdef LIBRAW_LIBRARY_BUILD
+  try {
+#endif
   for (row=0; row < raw_height; row+=8) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     pixel = raw_image + row*raw_width;
     nblocks = MIN (8, raw_height-row) * raw_width >> 6;
     for (block=0; block < nblocks; block++) {
@@ -754,8 +927,15 @@ void CLASS canon_load_raw()
       fseek (ifp, save, SEEK_SET);
     }
   }
+#ifdef LIBRAW_LIBRARY_BUILD
+  } catch (...) {
+    FORC(2) free (huff[c]);
+    throw;
+  }
+#endif
   FORC(2) free (huff[c]);
 }
+//@end COMMON
 
 /*
    Not a full implementation of Lossless JPEG, just
@@ -766,6 +946,8 @@ struct jhead {
   ushort *huff[6], *free[4], *row;
 };
 
+//@out COMMON
+
 int CLASS ljpeg_start (struct jhead *jh, int info_only)
 {
   int c, tag, len;
@@ -780,32 +962,49 @@ int CLASS ljpeg_start (struct jhead *jh, int info_only)
     fread (data, 2, 2, ifp);
     tag =  data[0] << 8 | data[1];
     len = (data[2] << 8 | data[3]) - 2;
+
+// printf ("\n*** ljpeg_start pos= %llx tag= %x, len= %d", ftell(ifp)-4, tag, len);
+
     if (tag <= 0xff00) return 0;
     fread (data, 1, len, ifp);
     switch (tag) {
-      case 0xffc3:
+      case 0xffc3:        // start of frame; lossless, Huffman
 	jh->sraw = ((data[7] >> 4) * (data[7] & 15) - 1) & 3;
-      case 0xffc0:
+//	printf ("\n*** %x: startraw= %d", tag, jh->sraw);
+      case 0xffc0:        // start of frame; baseline jpeg
 	jh->bits = data[0];
 	jh->high = data[1] << 8 | data[2];
 	jh->wide = data[3] << 8 | data[4];
 	jh->clrs = data[5] + jh->sraw;
+
+if (!strcmp(model, "EOS 5DS"))
+{
+  jh->wide = data[1] << 8 | data[2];
+	jh->high = data[3] << 8 | data[4];
+}
+//	printf ("\n*** %x: bits= %d; high= %d; wide= %d; clrs= %d",
+//	  tag, jh->bits, jh->high, jh->wide, jh->clrs);
+
 	if (len == 9 && !dng_version) getc(ifp);
 	break;
-      case 0xffc4:
+      case 0xffc4:          // define Huffman tables
 	if (info_only) break;
 	for (dp = data; dp < data+len && (c = *dp++) < 4; )
 	  jh->free[c] = jh->huff[c] = make_decoder_ref (&dp);
 	break;
-      case 0xffda:
+      case 0xffda:          // start of scan
 	jh->psv = data[1+data[0]*2];
 	jh->bits -= data[3+data[0]*2] & 15;
 	break;
-      case 0xffdd:
+      case 0xffdd:          // define restart interval
 	jh->restart = data[0] << 8 | data[1];
     }
   } while (tag != 0xffda);
+
+// printf ("\n");
+
   if (info_only) return 1;
+  if (jh->clrs > 6 || !jh->huff[0]) return 0;
   FORC(5) if (!jh->huff[c+1]) jh->huff[c+1] = jh->huff[c];
   if (jh->sraw) {
     FORC(4)        jh->huff[2+c] = jh->huff[1];
@@ -826,6 +1025,13 @@ void CLASS ljpeg_end (struct jhead *jh)
 int CLASS ljpeg_diff (ushort *huff)
 {
   int len, diff;
+  if(!huff)
+#ifdef LIBRAW_LIBRARY_BUILD
+    throw LIBRAW_EXCEPTION_IO_CORRUPT;
+#else
+    longjmp (failure, 2);
+#endif
+
 
   len = gethuff(huff);
   if (len == 16 && (!dng_version || dng_version >= 0x1010000))
@@ -881,10 +1087,25 @@ void CLASS lossless_jpeg_load_raw()
   struct jhead jh;
   ushort *rp;
 
+// printf ("\n*** lossless_jpeg_load_raw\n");
+
   if (!ljpeg_start (&jh, 0)) return;
+
+  if(jh.wide<1 || jh.high<1 || jh.clrs<1 || jh.bits <1)
+#ifdef LIBRAW_LIBRARY_BUILD
+    throw LIBRAW_EXCEPTION_IO_CORRUPT;
+#else
+    longjmp (failure, 2);
+#endif
   jwide = jh.wide * jh.clrs;
 
+#ifdef LIBRAW_LIBRARY_BUILD
+  try {
+#endif
   for (jrow=0; jrow < jh.high; jrow++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     rp = ljpeg_row (jrow, &jh);
     if (load_flags & 1)
       row = jrow & 1 ? height-1-jrow/2 : jrow/2;
@@ -901,11 +1122,23 @@ void CLASS lossless_jpeg_load_raw()
       }
       if (raw_width == 3984 && (col -= 2) < 0)
 	col += (row--,raw_width);
-      if (row >= 0) RAW(row,col) = val;
+      if(row>raw_height)
+#ifdef LIBRAW_LIBRARY_BUILD
+        throw LIBRAW_EXCEPTION_IO_CORRUPT;
+#else
+        longjmp (failure, 3);
+#endif
+      if ((unsigned) row < raw_height) RAW(row,col) = val;
       if (++col >= raw_width)
 	col = (row++,0);
     }
   }
+#ifdef LIBRAW_LIBRARY_BUILD
+  } catch (...) {
+    ljpeg_end (&jh);
+    throw;
+  }
+#endif
   ljpeg_end (&jh);
 }
 
@@ -917,26 +1150,73 @@ void CLASS canon_sraw_load_raw()
   int v[3]={0,0,0}, ver, hue;
   char *cp;
 
-  if (!ljpeg_start (&jh, 0)) return;
+  if (!ljpeg_start (&jh, 0) || jh.clrs < 4) return;
   jwide = (jh.wide >>= 1) * jh.clrs;
 
+#ifdef LIBRAW_LIBRARY_BUILD
+  try {
+#endif
   for (ecol=slice=0; slice <= cr2_slice[0]; slice++) {
     scol = ecol;
     ecol += cr2_slice[1] * 2 / jh.clrs;
     if (!cr2_slice[0] || ecol > raw_width-1) ecol = raw_width & -2;
     for (row=0; row < height; row += (jh.clrs >> 1) - 1) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
       ip = (short (*)[4]) image + row*width;
       for (col=scol; col < ecol; col+=2, jcol+=jh.clrs) {
 	if ((jcol %= jwide) == 0)
 	  rp = (short *) ljpeg_row (jrow++, &jh);
 	if (col >= width) continue;
-	FORC (jh.clrs-2)
-	  ip[col + (c >> 1)*width + (c & 1)][0] = rp[jcol+c];
-	ip[col][1] = rp[jcol+jh.clrs-2] - 16384;
-	ip[col][2] = rp[jcol+jh.clrs-1] - 16384;
+#ifdef LIBRAW_LIBRARY_BUILD
+        if(imgdata.params.sraw_ycc>=2)
+          {
+            FORC (jh.clrs-2)
+              {
+                ip[col + (c >> 1)*width + (c & 1)][0] = rp[jcol+c];
+                ip[col + (c >> 1)*width + (c & 1)][1] = ip[col + (c >> 1)*width + (c & 1)][2] = 8192;
+              }
+            ip[col][1] = rp[jcol+jh.clrs-2] - 8192;
+            ip[col][2] = rp[jcol+jh.clrs-1] - 8192;
+          }
+        else if(imgdata.params.sraw_ycc)
+          {
+            FORC (jh.clrs-2)
+                ip[col + (c >> 1)*width + (c & 1)][0] = rp[jcol+c];
+            ip[col][1] = rp[jcol+jh.clrs-2] - 8192;
+            ip[col][2] = rp[jcol+jh.clrs-1] - 8192;
+          }
+        else
+#endif
+          {
+            FORC (jh.clrs-2)
+              ip[col + (c >> 1)*width + (c & 1)][0] = rp[jcol+c];
+            ip[col][1] = rp[jcol+jh.clrs-2] - 16384;
+            ip[col][2] = rp[jcol+jh.clrs-1] - 16384;
+          }
       }
     }
   }
+#ifdef LIBRAW_LIBRARY_BUILD
+  } catch (...) {
+      ljpeg_end (&jh);
+      throw ;
+  }
+#endif
+
+#ifdef LIBRAW_LIBRARY_BUILD
+  if(imgdata.params.sraw_ycc>=2)
+    {
+      ljpeg_end (&jh);
+      maximum = 0x3fff;
+      return;
+    }
+#endif
+
+#ifdef LIBRAW_LIBRARY_BUILD
+  try {
+#endif
   for (cp=model2; *cp && !isdigit(*cp); cp++);
   sscanf (cp, "%d.%d.%d", v, v+1, v+2);
   ver = (v[0]*1000 + v[1])*1000 + v[2];
@@ -946,6 +1226,9 @@ void CLASS canon_sraw_load_raw()
   ip = (short (*)[4]) image;
   rp = ip[0];
   for (row=0; row < height; row++, ip+=width) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     if (row & (jh.sraw >> 1))
       for (col=0; col < width; col+=2)
 	for (c=1; c < 3; c++)
@@ -958,23 +1241,37 @@ void CLASS canon_sraw_load_raw()
 	     ip[col][c] =  ip[col-1][c];
 	else ip[col][c] = (ip[col-1][c] + ip[col+1][c] + 1) >> 1;
   }
-  for ( ; rp < ip[0]; rp+=4) {
-    if (unique_id < 0x80000218) {
-      rp[0] -= 512;
-      goto next;
-    } else if (unique_id == 0x80000285) {
-next: pix[0] = rp[0] + rp[2];
-      pix[2] = rp[0] + rp[1];
-      pix[1] = rp[0] + ((-778*rp[1] - (rp[2] << 11)) >> 12);
-    } else {
-      rp[1] = (rp[1] << 2) + hue;
-      rp[2] = (rp[2] << 2) + hue;
-      pix[0] = rp[0] + ((   50*rp[1] + 22929*rp[2]) >> 14);
-      pix[1] = rp[0] + ((-5640*rp[1] - 11751*rp[2]) >> 14);
-      pix[2] = rp[0] + ((29040*rp[1] -   101*rp[2]) >> 14);
+#ifdef LIBRAW_LIBRARY_BUILD
+  if(!imgdata.params.sraw_ycc)
+#endif
+    for ( ; rp < ip[0]; rp+=4) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
+      if (unique_id == 0x80000218 ||
+          unique_id == 0x80000250 ||
+          unique_id == 0x80000261 ||
+          unique_id == 0x80000281 ||
+          unique_id == 0x80000287) {
+        rp[1] = (rp[1] << 2) + hue;
+        rp[2] = (rp[2] << 2) + hue;
+        pix[0] = rp[0] + ((   50*rp[1] + 22929*rp[2]) >> 14);
+        pix[1] = rp[0] + ((-5640*rp[1] - 11751*rp[2]) >> 14);
+        pix[2] = rp[0] + ((29040*rp[1] -   101*rp[2]) >> 14);
+      } else {
+        if (unique_id < 0x80000218) rp[0] -= 512;
+        pix[0] = rp[0] + rp[2];
+        pix[2] = rp[0] + rp[1];
+        pix[1] = rp[0] + ((-778*rp[1] - (rp[2] << 11)) >> 12);
+      }
+      FORC3 rp[c] = CLIP(pix[c] * sraw_mul[c] >> 10);
     }
-    FORC3 rp[c] = CLIP(pix[c] * sraw_mul[c] >> 10);
+#ifdef LIBRAW_LIBRARY_BUILD
+  } catch (...) {
+      ljpeg_end (&jh);
+      throw ;
   }
+#endif
   ljpeg_end (&jh);
   maximum = 0x3fff;
 }
@@ -1004,6 +1301,9 @@ void CLASS lossless_dng_load_raw()
   ushort *rp;
 
   while (trow < raw_height) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     save = ftell(ifp);
     if (tile_length < INT_MAX)
       fseek (ifp, get4(), SEEK_SET);
@@ -1011,7 +1311,13 @@ void CLASS lossless_dng_load_raw()
     jwide = jh.wide;
     if (filters) jwide *= jh.clrs;
     jwide /= is_raw;
+#ifdef LIBRAW_LIBRARY_BUILD
+  try {
+#endif
     for (row=col=jrow=0; jrow < jh.high; jrow++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
       rp = ljpeg_row (jrow, &jh);
       for (jcol=0; jcol < jwide; jcol++) {
 	adobe_copy_pixel (trow+row, tcol+col, &rp);
@@ -1019,9 +1325,16 @@ void CLASS lossless_dng_load_raw()
 	  row += 1 + (col = 0);
       }
     }
+#ifdef LIBRAW_LIBRARY_BUILD
+  } catch (...) {
+      ljpeg_end (&jh);
+      throw ;
+  }
+#endif
     fseek (ifp, save+4, SEEK_SET);
     if ((tcol += tile_width) >= raw_width)
       trow += tile_length + (tcol = 0);
+
     ljpeg_end (&jh);
   }
 }
@@ -1031,9 +1344,15 @@ void CLASS packed_dng_load_raw()
   ushort *pixel, *rp;
   int row, col;
 
-  pixel = (ushort *) calloc (raw_width * tiff_samples, sizeof *pixel);
+  pixel = (ushort *) calloc (raw_width, tiff_samples*sizeof *pixel);
   merror (pixel, "packed_dng_load_raw()");
+#ifdef LIBRAW_LIBRARY_BUILD
+  try {
+#endif
   for (row=0; row < raw_height; row++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     if (tiff_bps == 16)
       read_shorts (pixel, raw_width * tiff_samples);
     else {
@@ -1044,6 +1363,12 @@ void CLASS packed_dng_load_raw()
     for (rp=pixel, col=0; col < raw_width; col++)
       adobe_copy_pixel (row, col, &rp);
   }
+#ifdef LIBRAW_LIBRARY_BUILD
+  } catch (...) {
+    free (pixel);
+    throw ;
+  }
+#endif
   free (pixel);
 }
 
@@ -1065,6 +1390,10 @@ void CLASS pentax_load_raw()
   fseek (ifp, data_offset, SEEK_SET);
   getbits(-1);
   for (row=0; row < raw_height; row++)
+  {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     for (col=0; col < raw_width; col++) {
       diff = ljpeg_diff (huff);
       if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
@@ -1072,7 +1401,45 @@ void CLASS pentax_load_raw()
       RAW(row,col) = hpred[col & 1];
       if (hpred[col & 1] >> tiff_bps) derror();
     }
+  }
+}
+
+#ifdef LIBRAW_LIBRARY_BUILD
+
+void CLASS nikon_coolscan_load_raw()
+{
+  int bufsize = width*3*tiff_bps/8;
+  if(tiff_bps <= 8)
+    gamma_curve(1.0/imgdata.params.coolscan_nef_gamma,0.,1,255);
+  else
+    gamma_curve(1.0/imgdata.params.coolscan_nef_gamma,0.,1,65535);
+  fseek (ifp, data_offset, SEEK_SET);
+  unsigned char *buf = (unsigned char*)malloc(bufsize);
+  unsigned short *ubuf = (unsigned short *)buf;
+  for(int row = 0; row < raw_height; row++)
+    {
+      int red = fread (buf, 1, bufsize, ifp);
+      unsigned short (*ip)[4] = (unsigned short (*)[4]) image + row*width;
+      if(tiff_bps <= 8)
+        for(int col=0; col<width;col++)
+          {
+            ip[col][0] = curve[buf[col*3]];
+            ip[col][1] = curve[buf[col*3+1]];
+            ip[col][2] = curve[buf[col*3+2]];
+            ip[col][3]=0;
+          }
+      else
+        for(int col=0; col<width;col++)
+          {
+            ip[col][0] = curve[ubuf[col*3]];
+            ip[col][1] = curve[ubuf[col*3+1]];
+            ip[col][2] = curve[ubuf[col*3+2]];
+            ip[col][3]=0;
+          }
+    }
+  free(buf);
 }
+#endif
 
 void CLASS nikon_load_raw()
 {
@@ -1117,7 +1484,13 @@ void CLASS nikon_load_raw()
   huff = make_decoder (nikon_tree[tree]);
   fseek (ifp, data_offset, SEEK_SET);
   getbits(-1);
+#ifdef LIBRAW_LIBRARY_BUILD
+  try {
+#endif
   for (min=row=0; row < height; row++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     if (split && row == split) {
       free (huff);
       huff = make_decoder (nikon_tree[tree+1]);
@@ -1136,24 +1509,38 @@ void CLASS nikon_load_raw()
       RAW(row,col) = curve[LIM((short)hpred[col & 1],0,0x3fff)];
     }
   }
+#ifdef LIBRAW_LIBRARY_BUILD
+  } catch (...) {
+    free (huff);
+    throw;
+  }
+#endif
   free (huff);
 }
 
-/*
-   Figure out if a NEF file is compressed.  These fancy heuristics
-   are only needed for the D100, thanks to a bug in some cameras
-   that tags all images as "compressed".
- */
-int CLASS nikon_is_compressed()
+void CLASS nikon_yuv_load_raw()
 {
-  uchar test[256];
-  int i;
+  int row, col, yuv[4], rgb[3], b, c;
+  UINT64 bitbuf=0;
 
-  fseek (ifp, data_offset, SEEK_SET);
-  fread (test, 1, 256, ifp);
-  for (i=15; i < 256; i+=16)
-    if (test[i]) return 1;
-  return 0;
+  for (row=0; row < raw_height; row++)
+  {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
+
+    for (col=0; col < raw_width; col++) {
+      if (!(b = col & 1)) {
+	bitbuf = 0;
+	FORC(6) bitbuf |= (UINT64) fgetc(ifp) << c*8;
+	FORC(4) yuv[c] = (bitbuf >> c*12 & 0xfff) - (c >> 1 << 11);
+      }
+      rgb[0] = yuv[b] + 1.370705*yuv[3];
+      rgb[1] = yuv[b] - 0.337633*yuv[2] - 0.698001*yuv[3];
+      rgb[2] = yuv[b] + 1.732446*yuv[2];
+      FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,0xfff)] / cam_mul[c];
+    }
+  }
 }
 
 /*
@@ -1198,20 +1585,20 @@ void CLASS nikon_3700()
   uchar dp[24];
   static const struct {
     int bits;
-    char make[12], model[15];
+    char t_make[12], t_model[15];
   } table[] = {
-    { 0x00, "PENTAX",  "Optio 33WR" },
-    { 0x03, "NIKON",   "E3200" },
-    { 0x32, "NIKON",   "E3700" },
-    { 0x33, "OLYMPUS", "C740UZ" } };
+    { 0x00, "Pentax",  "Optio 33WR" },
+    { 0x03, "Nikon",   "E3200" },
+    { 0x32, "Nikon",   "E3700" },
+    { 0x33, "Olympus", "C740UZ" } };
 
   fseek (ifp, 3072, SEEK_SET);
   fread (dp, 1, 24, ifp);
   bits = (dp[8] & 3) << 4 | (dp[20] & 3);
   for (i=0; i < sizeof table / sizeof *table; i++)
     if (bits == table[i].bits) {
-      strcpy (make,  table[i].make );
-      strcpy (model, table[i].model);
+      strcpy (make,  table[i].t_make );
+      strcpy (model, table[i].t_model);
     }
 }
 
@@ -1229,9 +1616,11 @@ int CLASS minolta_z2()
     if (tail[i]) nz++;
   return nz > 20;
 }
+//@end COMMON
 
 void CLASS jpeg_thumb();
 
+//@out COMMON
 void CLASS ppm_thumb()
 {
   char *thumb;
@@ -1249,7 +1638,7 @@ void CLASS ppm16_thumb()
   int i;
   char *thumb;
   thumb_length = thumb_width*thumb_height*3;
-  thumb = (char *) calloc (thumb_length,2);
+  thumb = (char *) calloc (thumb_length, 2);
   merror (thumb, "ppm16_thumb()");
   read_shorts ((ushort *) thumb, thumb_length);
   for (i=0; i < thumb_length; i++)
@@ -1301,6 +1690,9 @@ void CLASS rollei_load_raw()
 
   isix = raw_width * raw_height * 5 / 8;
   while (fread (pixel, 1, 10, ifp) == 10) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     for (i=0; i < 10; i+=2) {
       todo[i]   = iten++;
       todo[i+1] = pixel[i] << 8 | pixel[i+1];
@@ -1324,14 +1716,19 @@ int CLASS raw (unsigned row, unsigned col)
 void CLASS phase_one_flat_field (int is_float, int nc)
 {
   ushort head[8];
-  unsigned wide, y, x, c, rend, cend, row, col;
+  unsigned wide, high, y, x, c, rend, cend, row, col;
   float *mrow, num, mult[4];
 
   read_shorts (head, 8);
-  wide = head[2] / head[4];
+  if (head[2] * head[3] * head[4] * head[5] == 0) return;
+  wide = head[2] / head[4] + (head[2] % head[4] != 0);
+  high = head[3] / head[5] + (head[3] % head[5] != 0);
   mrow = (float *) calloc (nc*wide, sizeof *mrow);
   merror (mrow, "phase_one_flat_field()");
-  for (y=0; y < head[3] / head[5]; y++) {
+  for (y=0; y < high; y++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     for (x=0; x < wide; x++)
       for (c=0; c < nc; c+=2) {
 	num = is_float ? getreal(11) : get2()/32768.0;
@@ -1340,14 +1737,18 @@ void CLASS phase_one_flat_field (int is_float, int nc)
       }
     if (y==0) continue;
     rend = head[1] + y*head[5];
-    for (row = rend-head[5]; row < raw_height && row < rend; row++) {
+    for (row = rend-head[5];
+	 row < raw_height && row < rend &&
+	 row < head[1]+head[3]-head[5]; row++) {
       for (x=1; x < wide; x++) {
 	for (c=0; c < nc; c+=2) {
 	  mult[c] = mrow[c*wide+x-1];
 	  mult[c+1] = (mrow[c*wide+x] - mult[c]) / head[4];
 	}
 	cend = head[0] + x*head[4];
-	for (col = cend-head[4]; col < raw_width && col < cend; col++) {
+	for (col = cend-head[4];
+	     col < raw_width &&
+	     col < cend && col < head[0]+head[2]-head[4]; col++) {
 	  c = nc > 2 ? FC(row-top_margin,col-left_margin) : 0;
 	  if (!(c & 1)) {
 	    c = RAW(row,col) * mult[c];
@@ -1365,7 +1766,7 @@ void CLASS phase_one_flat_field (int is_float, int nc)
   free (mrow);
 }
 
-void CLASS phase_one_correct()
+int CLASS phase_one_correct()
 {
   unsigned entries, tag, data, save, col, row, type;
   int len, i, j, k, cip, val[4], dev[4], sum, max;
@@ -1375,15 +1776,25 @@ void CLASS phase_one_correct()
       {-2,-2}, {-2,2}, {2,-2}, {2,2} };
   float poly[8], num, cfrac, frac, mult[2], *yval[2];
   ushort *xval[2];
+  int qmult_applied = 0, qlin_applied = 0;
 
-  if (half_size || !meta_length) return;
+  if (half_size || !meta_length) return 0;
+#ifdef DCRAW_VERBOSE
   if (verbose) fprintf (stderr,_("Phase One correction...\n"));
+#endif
   fseek (ifp, meta_offset, SEEK_SET);
   order = get2();
   fseek (ifp, 6, SEEK_CUR);
   fseek (ifp, meta_offset+get4(), SEEK_SET);
   entries = get4();  get4();
+
+#ifdef LIBRAW_LIBRARY_BUILD
+  try {
+#endif
   while (entries--) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     tag  = get4();
     len  = get4();
     data = get4();
@@ -1406,15 +1817,20 @@ void CLASS phase_one_correct()
 	curve[i] = LIM(num+i,0,65535);
       } apply:					/* apply to whole image */
       for (row=0; row < raw_height; row++)
+      {
+#ifdef LIBRAW_LIBRARY_BUILD
+        checkCancel();
+#endif
 	for (col = (tag & 1)*ph1.split_col; col < raw_width; col++)
 	  RAW(row,col) = curve[RAW(row,col)];
+      }
     } else if (tag == 0x400) {			/* Sensor defects */
       while ((len -= 8) >= 0) {
 	col  = get2();
 	row  = get2();
 	type = get2(); get2();
 	if (col >= raw_width) continue;
-	if (type == 131)			/* Bad column */
+	if (type == 131 || type == 137)		/* Bad column */
 	  for (row=0; row < raw_height; row++)
 	    if (FC(row-top_margin,col-left_margin) == 1) {
 	      for (sum=i=0; i < 4; i++)
@@ -1451,6 +1867,99 @@ void CLASS phase_one_correct()
 	mindiff = diff;
 	off_412 = ftell(ifp) - 38;
       }
+    } else if (tag == 0x41f && !qlin_applied) { /* Quadrant linearization */
+      ushort lc[2][2][16], ref[16];
+      int qr, qc;
+      for (qr = 0; qr < 2; qr++)
+	for (qc = 0; qc < 2; qc++)
+	  for (i = 0; i < 16; i++)
+	    lc[qr][qc][i] = (ushort)get4();
+      for (i = 0; i < 16; i++) {
+	int v = 0;
+	for (qr = 0; qr < 2; qr++)
+	  for (qc = 0; qc < 2; qc++)
+	    v += lc[qr][qc][i];
+	ref[i] = (v + 2) >> 2;
+      }
+      for (qr = 0; qr < 2; qr++) {
+	for (qc = 0; qc < 2; qc++) {
+	  int cx[19], cf[19];
+	  for (i = 0; i < 16; i++) {
+	    cx[1+i] = lc[qr][qc][i];
+	    cf[1+i] = ref[i];
+	  }
+	  cx[0] = cf[0] = 0;
+	  cx[17] = cf[17] = ((unsigned int)ref[15] * 65535) / lc[qr][qc][15];
+          cf[18] = cx[18] = 65535;
+	  cubic_spline(cx, cf, 19);
+
+	  for (row = (qr ? ph1.split_row : 0);
+	       row < (qr ? raw_height : ph1.split_row); row++)
+          {
+#ifdef LIBRAW_LIBRARY_BUILD
+            checkCancel();
+#endif
+	    for (col = (qc ? ph1.split_col : 0);
+		 col < (qc ? raw_width : ph1.split_col); col++)
+	      RAW(row,col) = curve[RAW(row,col)];
+          }
+	}
+      }
+      qlin_applied = 1;
+    } else if (tag == 0x41e && !qmult_applied) { /* Quadrant multipliers */
+      float qmult[2][2] = { { 1, 1 }, { 1, 1 } };
+      get4(); get4(); get4(); get4();
+      qmult[0][0] = 1.0 + getreal(11);
+      get4(); get4(); get4(); get4(); get4();
+      qmult[0][1] = 1.0 + getreal(11);
+      get4(); get4(); get4();
+      qmult[1][0] = 1.0 + getreal(11);
+      get4(); get4(); get4();
+      qmult[1][1] = 1.0 + getreal(11);
+      for (row=0; row < raw_height; row++)
+      {
+#ifdef LIBRAW_LIBRARY_BUILD
+        checkCancel();
+#endif
+	for (col=0; col < raw_width; col++) {
+	  i = qmult[row >= ph1.split_row][col >= ph1.split_col] * RAW(row,col);
+	  RAW(row,col) = LIM(i,0,65535);
+	}
+      }
+      qmult_applied = 1;
+    } else if (tag == 0x431 && !qmult_applied) { /* Quadrant combined */
+      ushort lc[2][2][7], ref[7];
+      int qr, qc;
+      for (i = 0; i < 7; i++)
+	ref[i] = (ushort)get4();
+      for (qr = 0; qr < 2; qr++)
+	for (qc = 0; qc < 2; qc++)
+	  for (i = 0; i < 7; i++)
+	    lc[qr][qc][i] = (ushort)get4();
+      for (qr = 0; qr < 2; qr++) {
+	for (qc = 0; qc < 2; qc++) {
+	  int cx[9], cf[9];
+	  for (i = 0; i < 7; i++) {
+	    cx[1+i] = ref[i];
+	    cf[1+i] = ((unsigned int)ref[i] * lc[qr][qc][i]) / 10000;
+	  }
+	  cx[0] = cf[0] = 0;
+	  cx[8] = cf[8] = 65535;
+	  cubic_spline(cx, cf, 9);
+	  for (row = (qr ? ph1.split_row : 0);
+	       row < (qr ? raw_height : ph1.split_row); row++)
+          {
+#ifdef LIBRAW_LIBRARY_BUILD
+            checkCancel();
+#endif
+	    for (col = (qc ? ph1.split_col : 0);
+		 col < (qc ? raw_width : ph1.split_col); col++)
+	      RAW(row,col) = curve[RAW(row,col)];
+          }
+        }
+      }
+      qmult_applied = 1;
+      qlin_applied = 1;
     }
     fseek (ifp, save, SEEK_SET);
   }
@@ -1470,6 +1979,10 @@ void CLASS phase_one_correct()
       for (j=0; j < head[i+1]*head[i+3]; j++)
 	xval[i][j] = get2();
     for (row=0; row < raw_height; row++)
+    {
+#ifdef LIBRAW_LIBRARY_BUILD
+      checkCancel();
+#endif
       for (col=0; col < raw_width; col++) {
 	cfrac = (float) col * head[3] / raw_width;
 	cfrac -= cip = cfrac;
@@ -1484,34 +1997,66 @@ void CLASS phase_one_correct()
 	i = ((mult[0] * (1-cfrac) + mult[1] * cfrac) * row + num) * 2;
 	RAW(row,col) = LIM(i,0,65535);
       }
+    }
     free (yval[0]);
   }
+#ifdef LIBRAW_LIBRARY_BUILD
+  }
+  catch (...)
+  {
+	  return LIBRAW_CANCELLED_BY_CALLBACK;
+  }
+#endif
 }
 
 void CLASS phase_one_load_raw()
 {
   int a, b, i;
-  ushort akey, bkey, mask;
+  ushort akey, bkey, t_mask;
 
   fseek (ifp, ph1.key_off, SEEK_SET);
   akey = get2();
   bkey = get2();
-  mask = ph1.format == 1 ? 0x5555:0x1354;
+  t_mask = ph1.format == 1 ? 0x5555:0x1354;
+#ifdef LIBRAW_LIBRARY_BUILD
+  if (ph1.black_col || ph1.black_row )
+    {
+      imgdata.rawdata.ph1_cblack = (short(*)[2])calloc(raw_height*2,sizeof(ushort));
+      merror(imgdata.rawdata.ph1_cblack,"phase_one_load_raw()");
+      imgdata.rawdata.ph1_rblack = (short(*)[2])calloc(raw_width*2,sizeof(ushort));
+      merror(imgdata.rawdata.ph1_rblack,"phase_one_load_raw()");
+      if (ph1.black_col)
+        {
+          fseek (ifp, ph1.black_col, SEEK_SET);
+          read_shorts ((ushort *)imgdata.rawdata.ph1_cblack[0], raw_height*2);
+        }
+      if (ph1.black_row)
+        {
+          fseek (ifp, ph1.black_row, SEEK_SET);
+          read_shorts ((ushort *) imgdata.rawdata.ph1_rblack[0], raw_width*2);
+        }
+      }
+#endif
   fseek (ifp, data_offset, SEEK_SET);
   read_shorts (raw_image, raw_width*raw_height);
   if (ph1.format)
     for (i=0; i < raw_width*raw_height; i+=2) {
       a = raw_image[i+0] ^ akey;
       b = raw_image[i+1] ^ bkey;
-      raw_image[i+0] = (a & mask) | (b & ~mask);
-      raw_image[i+1] = (b & mask) | (a & ~mask);
+      raw_image[i+0] = (a & t_mask) | (b & ~t_mask);
+      raw_image[i+1] = (b & t_mask) | (a & ~t_mask);
     }
 }
 
 unsigned CLASS ph1_bithuff (int nbits, ushort *huff)
 {
+#ifndef LIBRAW_NOTHREADS
+#define bitbuf tls->ph1_bits.bitbuf
+#define vbits  tls->ph1_bits.vbits
+#else
   static UINT64 bitbuf=0;
   static int vbits=0;
+#endif
   unsigned c;
 
   if (nbits == -1)
@@ -1528,6 +2073,10 @@ unsigned CLASS ph1_bithuff (int nbits, ushort *huff)
   }
   vbits -= nbits;
   return c;
+#ifndef LIBRAW_NOTHREADS
+#undef bitbuf
+#undef vbits
+#endif
 }
 #define ph1_bits(n) ph1_bithuff(n,0)
 #define ph1_huff(h) ph1_bithuff(*h,h+1)
@@ -1537,21 +2086,49 @@ void CLASS phase_one_load_raw_c()
   static const int length[] = { 8,7,6,9,11,10,5,12,14,13 };
   int *offset, len[2], pred[2], row, col, i, j;
   ushort *pixel;
-  short (*black)[2];
+  short (*c_black)[2], (*r_black)[2];
+#ifdef LIBRAW_LIBRARY_BUILD
+  if(ph1.format == 6)
+    throw LIBRAW_EXCEPTION_IO_CORRUPT;
+#endif
 
-  pixel = (ushort *) calloc (raw_width + raw_height*4, 2);
+  pixel = (ushort *) calloc (raw_width*3 + raw_height*4, 2);
   merror (pixel, "phase_one_load_raw_c()");
   offset = (int *) (pixel + raw_width);
   fseek (ifp, strip_offset, SEEK_SET);
   for (row=0; row < raw_height; row++)
     offset[row] = get4();
-  black = (short (*)[2]) offset + raw_height;
-  fseek (ifp, ph1.black_off, SEEK_SET);
-  if (ph1.black_off)
-    read_shorts ((ushort *) black[0], raw_height*2);
+  c_black = (short (*)[2]) (offset + raw_height);
+  fseek (ifp, ph1.black_col, SEEK_SET);
+  if (ph1.black_col)
+      read_shorts ((ushort *) c_black[0], raw_height*2);
+  r_black = c_black + raw_height;
+  fseek (ifp, ph1.black_row, SEEK_SET);
+  if (ph1.black_row)
+      read_shorts ((ushort *) r_black[0], raw_width*2);
+
+#ifdef LIBRAW_LIBRARY_BUILD
+  // Copy data to internal copy (ever if not read)
+  if (ph1.black_col || ph1.black_row )
+    {
+      imgdata.rawdata.ph1_cblack = (short(*)[2])calloc(raw_height*2,sizeof(ushort));
+      merror(imgdata.rawdata.ph1_cblack,"phase_one_load_raw_c()");
+      memmove(imgdata.rawdata.ph1_cblack,(ushort*)c_black[0],raw_height*2*sizeof(ushort));
+      imgdata.rawdata.ph1_rblack = (short(*)[2])calloc(raw_width*2,sizeof(ushort));
+      merror(imgdata.rawdata.ph1_rblack,"phase_one_load_raw_c()");
+      memmove(imgdata.rawdata.ph1_rblack,(ushort*)r_black[0],raw_width*2*sizeof(ushort));
+    }
+#endif
+
   for (i=0; i < 256; i++)
     curve[i] = i*i / 3.969 + 0.5;
+#ifdef LIBRAW_LIBRARY_BUILD
+  try {
+#endif
   for (row=0; row < raw_height; row++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     fseek (ifp, data_offset + offset[row], SEEK_SET);
     ph1_bits(-1);
     pred[0] = pred[1] = 0;
@@ -1572,41 +2149,96 @@ void CLASS phase_one_load_raw_c()
 	pixel[col] = curve[pixel[col]];
     }
     for (col=0; col < raw_width; col++) {
-      i = (pixel[col] << 2) - ph1.black + black[row][col >= ph1.split_col];
-	if (i > 0) RAW(row,col) = i;
+#ifndef LIBRAW_LIBRARY_BUILD
+      i = (pixel[col] << 2) - ph1.t_black
+	+ c_black[row][col >= ph1.split_col]
+	+ r_black[col][row >= ph1.split_row];
+      if (i > 0) RAW(row,col) = i;
+#else
+      RAW(row,col) = pixel[col] << 2;
+#endif
     }
   }
+#ifdef LIBRAW_LIBRARY_BUILD
+  } catch(...) {
+    free (pixel);
+    throw;
+  }
+#endif
   free (pixel);
-  maximum = 0xfffc - ph1.black;
+  maximum = 0xfffc - ph1.t_black;
 }
 
 void CLASS hasselblad_load_raw()
 {
   struct jhead jh;
-  int row, col, pred[2], len[2], diff, c;
+  int shot, row, col, *back[5], len[2], diff[12], pred, sh, f, s, c;
+  unsigned upix, urow, ucol;
+  ushort *ip;
 
   if (!ljpeg_start (&jh, 0)) return;
   order = 0x4949;
   ph1_bits(-1);
+#ifdef LIBRAW_LIBRARY_BUILD
+  try {
+#endif
+  back[4] = (int *) calloc (raw_width, 3*sizeof **back);
+  merror (back[4], "hasselblad_load_raw()");
+  FORC3 back[c] = back[4] + c*raw_width;
+  cblack[6] >>= sh = tiff_samples > 1;
+  shot = LIM(shot_select, 1, tiff_samples) - 1;
   for (row=0; row < raw_height; row++) {
-    pred[0] = pred[1] = 0x8000 + load_flags;
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
+    FORC4 back[(c+3) & 3] = back[c];
     for (col=0; col < raw_width; col+=2) {
-      FORC(2) len[c] = ph1_huff(jh.huff[0]);
-      FORC(2) {
-	diff = ph1_bits(len[c]);
-	if ((diff & (1 << (len[c]-1))) == 0)
-	  diff -= (1 << len[c]) - 1;
-	if (diff == 65535) diff = -32768;
-	pred[c] += diff;
-	if (row >= 0 && (unsigned)(col+c) < width)
-	  RAW(row,col+c) = pred[c];
+      for (s=0; s < tiff_samples*2; s+=2) {
+	FORC(2) len[c] = ph1_huff(jh.huff[0]);
+	FORC(2) {
+	  diff[s+c] = ph1_bits(len[c]);
+	  if ((diff[s+c] & (1 << (len[c]-1))) == 0)
+	    diff[s+c] -= (1 << len[c]) - 1;
+	  if (diff[s+c] == 65535) diff[s+c] = -32768;
+	}
+      }
+      for (s=col; s < col+2; s++) {
+	pred = 0x8000 + load_flags;
+	if (col) pred = back[2][s-2];
+	if (col && row > 1) switch (jh.psv) {
+	  case 11: pred += back[0][s]/2 - back[0][s-2]/2;  break;
+	}
+	f = (row & 1)*3 ^ ((col+s) & 1);
+	FORC (tiff_samples) {
+	  pred += diff[(s & 1)*tiff_samples+c];
+	  upix = pred >> sh & 0xffff;
+	  if (raw_image && c == shot)
+	    RAW(row,s) = upix;
+	  if (image) {
+	    urow = row-top_margin  + (c & 1);
+	    ucol = col-left_margin - ((c >> 1) & 1);
+	    ip = &image[urow*width+ucol][f];
+	    if (urow < height && ucol < width)
+	      *ip = c < 4 ? upix : (*ip + upix) >> 1;
+	  }
+	}
+	back[2][s] = pred;
       }
     }
   }
+#ifdef LIBRAW_LIBRARY_BUILD
+  } catch (...){
+    free (back[4]);
+    ljpeg_end (&jh);
+    throw;
+  }
+#endif
+  free (back[4]);
   ljpeg_end (&jh);
-  maximum = 0xffff;
+  if (image) mix_green = 1;
 }
 
+
 void CLASS leaf_hdr_load_raw()
 {
   ushort *pixel=0;
@@ -1616,8 +2248,14 @@ void CLASS leaf_hdr_load_raw()
     pixel = (ushort *) calloc (raw_width, sizeof *pixel);
     merror (pixel, "leaf_hdr_load_raw()");
   }
+#ifdef LIBRAW_LIBRARY_BUILD
+  try {
+#endif
   FORC(tiff_samples)
     for (r=0; r < raw_height; r++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
       if (r % tile_length == 0) {
 	fseek (ifp, data_offset + 4*tile++, SEEK_SET);
 	fseek (ifp, get4(), SEEK_SET);
@@ -1629,6 +2267,12 @@ void CLASS leaf_hdr_load_raw()
 	for (col=0; col < width; col++)
 	  image[row*width+col][c] = pixel[col+left_margin];
     }
+#ifdef LIBRAW_LIBRARY_BUILD
+  } catch (...) {
+    if(!filters) free(pixel);
+    throw;
+  }
+#endif
   if (!filters) {
     maximum = 0xffff;
     raw_color = 1;
@@ -1643,34 +2287,39 @@ void CLASS unpacked_load_raw()
   while (1 << ++bits < maximum);
   read_shorts (raw_image, raw_width*raw_height);
   for (row=0; row < raw_height; row++)
+  {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     for (col=0; col < raw_width; col++)
       if ((RAW(row,col) >>= load_flags) >> bits
 	&& (unsigned) (row-top_margin) < height
 	&& (unsigned) (col-left_margin) < width) derror();
+  }
 }
 
+
 void CLASS sinar_4shot_load_raw()
 {
   ushort *pixel;
   unsigned shot, row, col, r, c;
 
-  if ((shot = shot_select) || half_size) {
-    if (shot) shot--;
-    if (shot > 3) shot = 3;
+  if (raw_image) {
+    shot = LIM (shot_select, 1, 4) - 1;
     fseek (ifp, data_offset + shot*4, SEEK_SET);
     fseek (ifp, get4(), SEEK_SET);
     unpacked_load_raw();
     return;
   }
-  free (raw_image);
-  raw_image = 0;
-  free (image);
-  image = (ushort (*)[4])
-	calloc ((iheight=height)*(iwidth=width), sizeof *image);
-  merror (image, "sinar_4shot_load_raw()");
   pixel = (ushort *) calloc (raw_width, sizeof *pixel);
   merror (pixel, "sinar_4shot_load_raw()");
+#ifdef LIBRAW_LIBRARY_BUILD
+  try {
+#endif
   for (shot=0; shot < 4; shot++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     fseek (ifp, data_offset + shot*4, SEEK_SET);
     fseek (ifp, get4(), SEEK_SET);
     for (row=0; row < raw_height; row++) {
@@ -1678,36 +2327,69 @@ void CLASS sinar_4shot_load_raw()
       if ((r = row-top_margin - (shot >> 1 & 1)) >= height) continue;
       for (col=0; col < raw_width; col++) {
 	if ((c = col-left_margin - (shot & 1)) >= width) continue;
-	image[r*width+c][FC(row,col)] = pixel[col];
+	image[r*width+c][(row & 1)*3 ^ (~col & 1)] = pixel[col];
       }
     }
   }
+#ifdef LIBRAW_LIBRARY_BUILD
+  } catch (...) {
+    free(pixel);
+    throw;
+  }
+#endif
   free (pixel);
-  shrink = filters = 0;
+  mix_green = 1;
 }
 
 void CLASS imacon_full_load_raw()
 {
   int row, col;
 
+  if (!image) return;
+
+#ifdef LIBRAW_LIBRARY_BUILD
+  unsigned short *buf = (unsigned short *)malloc(width*3*sizeof(unsigned short));
+  merror(buf,"imacon_full_load_raw");
+#endif
+
   for (row=0; row < height; row++)
+  {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+    read_shorts(buf,width*3);
+    unsigned short (*rowp)[4] = &image[row*width];
+    for (col=0; col < width; col++)
+      {
+        rowp[col][0]=buf[col*3];
+        rowp[col][1]=buf[col*3+1];
+        rowp[col][2]=buf[col*3+2];
+        rowp[col][3]=0;
+      }
+#else
     for (col=0; col < width; col++)
       read_shorts (image[row*width+col], 3);
+#endif
+  }
+#ifdef LIBRAW_LIBRARY_BUILD
+  free(buf);
+#endif
 }
 
 void CLASS packed_load_raw()
 {
-  int vbits=0, bwide, pwide, rbits, bite, half, irow, row, col, val, i;
+  int vbits=0, bwide, rbits, bite, half, irow, row, col, val, i;
   UINT64 bitbuf=0;
 
-  if (raw_width * 8 >= width * tiff_bps)	/* Is raw_width in bytes? */
-       pwide = (bwide = raw_width) * 8 / tiff_bps;
-  else bwide = (pwide = raw_width) * tiff_bps / 8;
-  rbits = bwide * 8 - pwide * tiff_bps;
+  bwide = raw_width * tiff_bps / 8;
+  bwide += bwide & load_flags >> 7;
+  rbits = bwide * 8 - raw_width * tiff_bps;
   if (load_flags & 1) bwide = bwide * 16 / 15;
   bite = 8 + (load_flags & 24);
   half = (raw_height+1) >> 1;
   for (irow=0; irow < raw_height; irow++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     row = irow;
     if (load_flags & 2 &&
 	(row = irow % half * 2 + irow / half) == 1 &&
@@ -1719,16 +2401,16 @@ void CLASS packed_load_raw()
 	fseek (ifp, ftell(ifp) >> 3 << 2, SEEK_SET);
       }
     }
-    for (col=0; col < pwide; col++) {
+    for (col=0; col < raw_width; col++) {
       for (vbits -= tiff_bps; vbits < 0; vbits += bite) {
 	bitbuf <<= bite;
 	for (i=0; i < bite; i+=8)
 	  bitbuf |= (unsigned) (fgetc(ifp) << i);
       }
       val = bitbuf << (64-tiff_bps-vbits) >> (64-tiff_bps);
-      RAW(row,col ^ (load_flags >> 6)) = val;
-      if (load_flags & 1 && (col % 10) == 9 &&
-	fgetc(ifp) && col < width+left_margin) derror();
+      RAW(row,col ^ (load_flags >> 6 & 1)) = val;
+      if (load_flags & 1 && (col % 10) == 9 && fgetc(ifp) &&
+	row < height+top_margin && col < width+left_margin) derror();
     }
     vbits -= rbits;
   }
@@ -1738,25 +2420,133 @@ void CLASS nokia_load_raw()
 {
   uchar  *data,  *dp;
   int rev, dwide, row, col, c;
+  double sum[]={0,0};
 
   rev = 3 * (order == 0x4949);
-  dwide = raw_width * 5 / 4;
+  dwide = (raw_width * 5 + 1) / 4;
   data = (uchar *) malloc (dwide*2);
   merror (data, "nokia_load_raw()");
+#ifdef LIBRAW_LIBRARY_BUILD
+  try {
+#endif
   for (row=0; row < raw_height; row++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     if (fread (data+dwide, 1, dwide, ifp) < dwide) derror();
     FORC(dwide) data[c] = data[dwide+(c ^ rev)];
     for (dp=data, col=0; col < raw_width; dp+=5, col+=4)
       FORC4 RAW(row,col+c) = (dp[c] << 2) | (dp[4] >> (c << 1) & 3);
   }
+#ifdef LIBRAW_LIBRARY_BUILD
+  } catch (...){
+    free (data);
+    throw;
+  }
+#endif
   free (data);
   maximum = 0x3ff;
+  if (strcmp(make,"OmniVision")) return;
+  row = raw_height/2;
+  FORC(width-1) {
+    sum[ c & 1] += SQR(RAW(row,c)-RAW(row+1,c+1));
+    sum[~c & 1] += SQR(RAW(row+1,c)-RAW(row,c+1));
+  }
+  if (sum[1] > sum[0]) filters = 0x4b4b4b4b;
+}
+
+void CLASS android_tight_load_raw()
+{
+  uchar *data, *dp;
+  int bwide, row, col, c;
+
+  bwide = -(-5*raw_width >> 5) << 3;
+  data = (uchar *) malloc (bwide);
+  merror (data, "android_tight_load_raw()");
+  for (row=0; row < raw_height; row++) {
+    if (fread (data, 1, bwide, ifp) < bwide) derror();
+    for (dp=data, col=0; col < raw_width; dp+=5, col+=4)
+      FORC4 RAW(row,col+c) = (dp[c] << 2) | (dp[4] >> (c << 1) & 3);
+}
+  free (data);
+}
+
+void CLASS android_loose_load_raw()
+{
+  uchar *data, *dp;
+  int bwide, row, col, c;
+  UINT64 bitbuf=0;
+
+  bwide = (raw_width+5)/6 << 3;
+  data = (uchar *) malloc (bwide);
+  merror (data, "android_loose_load_raw()");
+  for (row=0; row < raw_height; row++) {
+    if (fread (data, 1, bwide, ifp) < bwide) derror();
+    for (dp=data, col=0; col < raw_width; dp+=8, col+=6) {
+      FORC(8) bitbuf = (bitbuf << 8) | dp[c^7];
+      FORC(6) RAW(row,col+c) = (bitbuf >> c*10) & 0x3ff;
+    }
+  }
+  free (data);
+}
+
+void CLASS canon_rmf_load_raw()
+{
+  int row, col, bits, orow, ocol, c;
+
+#ifdef LIBRAW_LIBRARY_BUILD
+  int *words = (int*)malloc(sizeof(int)*(raw_width/3+1));
+  merror(words,"canon_rmf_load_raw");
+#endif
+  for (row=0; row < raw_height; row++)
+  {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+    fread(words,sizeof(int),raw_width/3,ifp);
+    for (col=0; col < raw_width-2; col+=3)
+      {
+        bits = words[col/3];
+        FORC3 {
+          orow = row;
+          if ((ocol = col+c-4) < 0)
+            {
+              ocol += raw_width;
+              if ((orow -= 2) < 0)
+                orow += raw_height;
+            }
+          RAW(orow,ocol) = curve[bits >> (10*c+2) & 0x3ff];
+        }
+      }
+#else
+    for (col=0; col < raw_width-2; col+=3) {
+      bits = get4();
+      FORC3 {
+	orow = row;
+	if ((ocol = col+c-4) < 0) {
+	  ocol += raw_width;
+	  if ((orow -= 2) < 0)
+	    orow += raw_height;
+	}
+	RAW(orow,ocol) = curve[bits >> (10*c+2) & 0x3ff];
+      }
+    }
+#endif
+  }
+#ifdef LIBRAW_LIBRARY_BUILD
+  free(words);
+#endif
+  maximum = curve[0x3ff];
 }
 
 unsigned CLASS pana_bits (int nbits)
 {
+#ifndef LIBRAW_NOTHREADS
+#define buf tls->pana_bits.buf
+#define vbits tls->pana_bits.vbits
+#else
   static uchar buf[0x4000];
   static int vbits;
+#endif
   int byte;
 
   if (!nbits) return vbits=0;
@@ -1766,7 +2556,11 @@ unsigned CLASS pana_bits (int nbits)
   }
   vbits = (vbits - nbits) & 0x1ffff;
   byte = vbits >> 3 ^ 0x3ff0;
-  return (buf[byte] | buf[byte+1] << 8) >> (vbits & 7) & ~(-1 << nbits);
+  return (buf[byte] | buf[byte+1] << 8) >> (vbits & 7) & ~((~0u) << nbits);
+#ifndef LIBRAW_NOTHREADS
+#undef buf
+#undef vbits
+#endif
 }
 
 void CLASS panasonic_load_raw()
@@ -1775,6 +2569,10 @@ void CLASS panasonic_load_raw()
 
   pana_bits(0);
   for (row=0; row < height; row++)
+  {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     for (col=0; col < raw_width; col++) {
       if ((i = col % 14) == 0)
 	pred[0] = pred[1] = nonz[0] = nonz[1] = 0;
@@ -1782,14 +2580,14 @@ void CLASS panasonic_load_raw()
       if (nonz[i & 1]) {
 	if ((j = pana_bits(8))) {
 	  if ((pred[i & 1] -= 0x80 << sh) < 0 || sh == 4)
-	       pred[i & 1] &= ~(-1 << sh);
+            pred[i & 1] &= ~((~0u) << sh);
 	  pred[i & 1] += j << sh;
 	}
       } else if ((nonz[i & 1] = pana_bits(8)) || i > 11)
 	pred[i & 1] = nonz[i & 1] << 4 | pana_bits(4);
-      if (col < width)
-	if ((RAW(row,col) = pred[col & 1]) > 4098) derror();
+      if ((RAW(row,col) = pred[col & 1]) > 4098 && col < width) derror();
     }
+  }
 }
 
 void CLASS olympus_load_raw()
@@ -1804,6 +2602,9 @@ void CLASS olympus_load_raw()
   fseek (ifp, 7, SEEK_CUR);
   getbits(-1);
   for (row=0; row < height; row++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     memset (acarry, 0, sizeof acarry);
     for (col=0; col < raw_width; col++) {
       carry = acarry[col & 1];
@@ -1842,6 +2643,9 @@ void CLASS minolta_rd175_load_raw()
   unsigned irow, box, row, col;
 
   for (irow=0; irow < 1481; irow++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     if (fread (pixel, 1, 768, ifp) < 768) derror();
     box = irow / 82;
     row = irow % 82 * 12 + ((box < 12) ? box | 1 : (box-12)*2);
@@ -1872,7 +2676,7 @@ void CLASS quicktake_100_load_raw()
   static const short rstep[6][4] =
   { {  -3,-1,1,3  }, {  -5,-1,1,5  }, {  -8,-2,2,8  },
     { -13,-3,3,13 }, { -19,-4,4,19 }, { -28,-6,6,28 } };
-  static const short curve[256] =
+  static const short t_curve[256] =
   { 0,1,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,
     28,29,30,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,53,
     54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,74,75,76,77,78,
@@ -1891,6 +2695,9 @@ void CLASS quicktake_100_load_raw()
   getbits(-1);
   memset (pixel, 0x80, sizeof pixel);
   for (row=2; row < height+2; row++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     for (col=2+(row & 1); col < width+2; col+=2) {
       val = ((pixel[row-1][col-1] + 2*pixel[row-1][col+1] +
 		pixel[row][col-2]) >> 2) + gstep[getbits(4)];
@@ -1904,6 +2711,10 @@ void CLASS quicktake_100_load_raw()
   }
   for (rb=0; rb < 2; rb++)
     for (row=2+rb; row < height+2; row+=2)
+    {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
       for (col=3-(row & 1); col < width+2; col+=2) {
 	if (row < 4 || col < 4) sharp = 2;
 	else {
@@ -1919,15 +2730,26 @@ void CLASS quicktake_100_load_raw()
 	if (row < 4) pixel[row-2][col+2] = val;
 	if (col < 4) pixel[row+2][col-2] = val;
       }
+    }
   for (row=2; row < height+2; row++)
+  {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     for (col=3-(row & 1); col < width+2; col+=2) {
       val = ((pixel[row][col-1] + (pixel[row][col] << 2) +
 	      pixel[row][col+1]) >> 1) - 0x100;
       pixel[row][col] = LIM(val,0,255);
     }
+  }
   for (row=0; row < height; row++)
+  {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     for (col=0; col < width; col++)
-      RAW(row,col) = curve[pixel[row+2][col+2]];
+      RAW(row,col) = t_curve[pixel[row+2][col+2]];
+  }
   maximum = 0x3ff;
 }
 
@@ -1938,6 +2760,12 @@ void CLASS quicktake_100_load_raw()
 #define PREDICTOR (c ? (buf[c][y-1][x] + buf[c][y][x+1]) / 2 \
 : (buf[c][y-1][x+1] + 2*buf[c][y-1][x] + buf[c][y][x+1]) / 4)
 
+#ifdef __GNUC__
+# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+# pragma GCC optimize("no-aggressive-loop-optimizations")
+# endif
+#endif
+
 void CLASS kodak_radc_load_raw()
 {
   static const char src[] = {
@@ -1979,11 +2807,14 @@ void CLASS kodak_radc_load_raw()
   for (i=0; i < sizeof(buf)/sizeof(short); i++)
     buf[0][0][i] = 2048;
   for (row=0; row < height; row+=4) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     FORC3 mul[c] = getbits(6);
     FORC3 {
       val = ((0x1000000/last[c] + 0x7ff) >> 12) * mul[c];
       s = val > 65564 ? 10:12;
-      x = ~(-1 << (s-1));
+      x = ~((~0u) << (s-1));
       val <<= 12-s;
       for (i=0; i < sizeof(buf[0])/sizeof(short); i++)
 	buf[c][0][i] = (buf[c][0][i] * val + x) >> s;
@@ -2043,6 +2874,8 @@ void CLASS kodak_jpeg_load_raw() {}
 void CLASS lossy_dng_load_raw() {}
 #else
 
+
+#ifndef LIBRAW_LIBRARY_BUILD
 METHODDEF(boolean)
 fill_input_buffer (j_decompress_ptr cinfo)
 {
@@ -2055,7 +2888,6 @@ fill_input_buffer (j_decompress_ptr cinfo)
   cinfo->src->bytes_in_buffer = nbytes;
   return TRUE;
 }
-
 void CLASS kodak_jpeg_load_raw()
 {
   struct jpeg_decompress_struct cinfo;
@@ -2078,7 +2910,7 @@ void CLASS kodak_jpeg_load_raw()
     longjmp (failure, 3);
   }
   buf = (*cinfo.mem->alloc_sarray)
-		((j_common_ptr) &cinfo, JPOOL_IMAGE, width*3, 1);
+    ((j_common_ptr) &cinfo, JPOOL_IMAGE, width*3, 1);
 
   while (cinfo.output_scanline < cinfo.output_height) {
     row = cinfo.output_scanline * 2;
@@ -2095,6 +2927,91 @@ void CLASS kodak_jpeg_load_raw()
   jpeg_destroy_decompress (&cinfo);
   maximum = 0xff << 1;
 }
+#else
+
+struct jpegErrorManager {
+  struct jpeg_error_mgr pub;
+};
+
+static void jpegErrorExit (j_common_ptr cinfo)
+{
+  jpegErrorManager* myerr = (jpegErrorManager*) cinfo->err;
+  throw LIBRAW_EXCEPTION_DECODE_JPEG;
+}
+
+
+// LibRaw's Kodak_jpeg_load_raw
+void CLASS kodak_jpeg_load_raw()
+{
+  if(data_size < 1)
+    throw LIBRAW_EXCEPTION_DECODE_JPEG;
+
+  int row, col;
+  jpegErrorManager jerr;
+  struct jpeg_decompress_struct cinfo;
+
+  cinfo.err = jpeg_std_error(&jerr.pub);
+  jerr.pub.error_exit = jpegErrorExit;
+
+  unsigned char *jpg_buf = (unsigned char *)malloc(data_size);
+  merror(jpg_buf,"kodak_jpeg_load_raw");
+  unsigned char *pixel_buf = (unsigned char*) malloc(width*3);
+  jpeg_create_decompress (&cinfo);
+  merror(pixel_buf,"kodak_jpeg_load_raw");
+
+  fread(jpg_buf,data_size,1,ifp);
+  swab ((char*)jpg_buf, (char*)jpg_buf, data_size);
+  try
+    {
+      jpeg_mem_src(&cinfo, jpg_buf, data_size);
+      int rc = jpeg_read_header(&cinfo, TRUE);
+      if(rc!=1)
+        throw LIBRAW_EXCEPTION_DECODE_JPEG;
+
+      jpeg_start_decompress (&cinfo);
+      if ((cinfo.output_width      != width  ) ||
+          (cinfo.output_height*2   != height ) ||
+          (cinfo.output_components != 3      ))
+        {
+          throw LIBRAW_EXCEPTION_DECODE_JPEG;
+        }
+
+      unsigned char *buf[1];
+      buf[0] = pixel_buf;
+
+      while (cinfo.output_scanline < cinfo.output_height)
+        {
+          checkCancel();
+          row = cinfo.output_scanline * 2;
+          jpeg_read_scanlines (&cinfo, buf, 1);
+          unsigned char (*pixel)[3] = (unsigned char (*)[3]) buf[0];
+          for (col=0; col < width; col+=2) {
+            RAW(row+0,col+0) = pixel[col+0][1] << 1;
+            RAW(row+1,col+1) = pixel[col+1][1] << 1;
+            RAW(row+0,col+1) = pixel[col][0] + pixel[col+1][0];
+            RAW(row+1,col+0) = pixel[col][2] + pixel[col+1][2];
+          }
+        }
+    }
+  catch (...)
+        {
+          jpeg_finish_decompress (&cinfo);
+          jpeg_destroy_decompress (&cinfo);
+          free(jpg_buf);
+          free(pixel_buf);
+          throw;
+        }
+  jpeg_finish_decompress (&cinfo);
+  jpeg_destroy_decompress (&cinfo);
+  free(jpg_buf);
+  free(pixel_buf);
+  maximum = 0xff << 1;
+}
+#endif
+
+#ifndef LIBRAW_LIBRARY_BUILD
+void CLASS gamma_curve (double pwr, double ts, int mode, int imax);
+#endif
 
 void CLASS lossy_dng_load_raw()
 {
@@ -2104,48 +3021,73 @@ void CLASS lossy_dng_load_raw()
   JSAMPLE (*pixel)[3];
   unsigned sorder=order, ntags, opcode, deg, i, j, c;
   unsigned save=data_offset-4, trow=0, tcol=0, row, col;
-  ushort curve[3][256];
+  ushort cur[3][256];
   double coeff[9], tot;
 
-  fseek (ifp, meta_offset, SEEK_SET);
-  order = 0x4d4d;
-  ntags = get4();
-  while (ntags--) {
-    opcode = get4(); get4(); get4();
-    if (opcode != 8)
-    { fseek (ifp, get4(), SEEK_CUR); continue; }
-    fseek (ifp, 20, SEEK_CUR);
-    if ((c = get4()) > 2) break;
-    fseek (ifp, 12, SEEK_CUR);
-    if ((deg = get4()) > 8) break;
-    for (i=0; i <= deg && i < 9; i++)
-      coeff[i] = getreal(12);
-    for (i=0; i < 256; i++) {
-      for (tot=j=0; j <= deg; j++)
-	tot += coeff[j] * pow(i/255.0, j);
-      curve[c][i] = tot*0xffff;
+  if (meta_offset) {
+    fseek (ifp, meta_offset, SEEK_SET);
+    order = 0x4d4d;
+    ntags = get4();
+    while (ntags--) {
+      opcode = get4(); get4(); get4();
+      if (opcode != 8)
+      { fseek (ifp, get4(), SEEK_CUR); continue; }
+      fseek (ifp, 20, SEEK_CUR);
+      if ((c = get4()) > 2) break;
+      fseek (ifp, 12, SEEK_CUR);
+      if ((deg = get4()) > 8) break;
+      for (i=0; i <= deg && i < 9; i++)
+	coeff[i] = getreal(12);
+      for (i=0; i < 256; i++) {
+	for (tot=j=0; j <= deg; j++)
+	  tot += coeff[j] * pow(i/255.0, (int)j);
+	cur[c][i] = tot*0xffff;
+      }
     }
+    order = sorder;
+  } else {
+    gamma_curve (1/2.4, 12.92, 1, 255);
+    FORC3 memcpy (cur[c], curve, sizeof cur[0]);
   }
-  order = sorder;
   cinfo.err = jpeg_std_error (&jerr);
   jpeg_create_decompress (&cinfo);
   while (trow < raw_height) {
     fseek (ifp, save+=4, SEEK_SET);
     if (tile_length < INT_MAX)
       fseek (ifp, get4(), SEEK_SET);
+#ifdef LIBRAW_LIBRARY_BUILD
+    if(libraw_internal_data.internal_data.input->jpeg_src(&cinfo) == -1)
+      {
+        jpeg_destroy_decompress(&cinfo);
+        throw LIBRAW_EXCEPTION_DECODE_JPEG;
+      }
+#else
     jpeg_stdio_src (&cinfo, ifp);
+#endif
     jpeg_read_header (&cinfo, TRUE);
     jpeg_start_decompress (&cinfo);
     buf = (*cinfo.mem->alloc_sarray)
 	((j_common_ptr) &cinfo, JPOOL_IMAGE, cinfo.output_width*3, 1);
+#ifdef LIBRAW_LIBRARY_BUILD
+  try {
+#endif
     while (cinfo.output_scanline < cinfo.output_height &&
 	(row = trow + cinfo.output_scanline) < height) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
       jpeg_read_scanlines (&cinfo, buf, 1);
       pixel = (JSAMPLE (*)[3]) buf[0];
       for (col=0; col < cinfo.output_width && tcol+col < width; col++) {
-	FORC3 image[row*width+tcol+col][c] = curve[c][pixel[col][c]];
+	FORC3 image[row*width+tcol+col][c] = cur[c][pixel[col][c]];
       }
     }
+#ifdef LIBRAW_LIBRARY_BUILD
+  } catch(...) {
+    jpeg_destroy_decompress (&cinfo);
+    throw;
+  }
+#endif
     jpeg_abort_decompress (&cinfo);
     if ((tcol += tile_width) >= raw_width)
       trow += tile_length + (tcol = 0);
@@ -2163,6 +3105,9 @@ void CLASS kodak_dc120_load_raw()
   int row, shift, col;
 
   for (row=0; row < height; row++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     if (fread (pixel, 1, 848, ifp) < 848) derror();
     shift = row * mul[row & 3] + add[row & 3];
     for (col=0; col < width; col++)
@@ -2178,35 +3123,96 @@ void CLASS eight_bit_load_raw()
 
   pixel = (uchar *) calloc (raw_width, sizeof *pixel);
   merror (pixel, "eight_bit_load_raw()");
+#ifdef LIBRAW_LIBRARY_BUILD
+  try {
+#endif
   for (row=0; row < raw_height; row++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     if (fread (pixel, 1, raw_width, ifp) < raw_width) derror();
     for (col=0; col < raw_width; col++)
       RAW(row,col) = curve[pixel[col]];
   }
+#ifdef LIBRAW_LIBRARY_BUILD
+  } catch(...) {
+    free (pixel);
+    throw;
+  }
+#endif
+  free (pixel);
+  maximum = curve[0xff];
+}
+
+void CLASS kodak_c330_load_raw()
+{
+  uchar *pixel;
+  int row, col, y, cb, cr, rgb[3], c;
+
+  pixel = (uchar *) calloc (raw_width, 2*sizeof *pixel);
+  merror (pixel, "kodak_c330_load_raw()");
+#ifdef LIBRAW_LIBRARY_BUILD
+  try {
+#endif
+  for (row=0; row < height; row++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
+    if (fread (pixel, raw_width, 2, ifp) < 2) derror();
+    if (load_flags && (row & 31) == 31)
+      fseek (ifp, raw_width*32, SEEK_CUR);
+    for (col=0; col < width; col++) {
+      y  = pixel[col*2];
+      cb = pixel[(col*2 & -4) | 1] - 128;
+      cr = pixel[(col*2 & -4) | 3] - 128;
+      rgb[1] = y - ((cb + cr + 2) >> 2);
+      rgb[2] = rgb[1] + cb;
+      rgb[0] = rgb[1] + cr;
+      FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,255)];
+    }
+  }
+#ifdef LIBRAW_LIBRARY_BUILD
+  } catch(...) {
+    free (pixel);
+    throw;
+  }
+#endif
   free (pixel);
   maximum = curve[0xff];
 }
 
-void CLASS kodak_yrgb_load_raw()
+void CLASS kodak_c603_load_raw()
 {
   uchar *pixel;
   int row, col, y, cb, cr, rgb[3], c;
 
   pixel = (uchar *) calloc (raw_width, 3*sizeof *pixel);
-  merror (pixel, "kodak_yrgb_load_raw()");
+  merror (pixel, "kodak_c603_load_raw()");
+#ifdef LIBRAW_LIBRARY_BUILD
+  try {
+#endif
   for (row=0; row < height; row++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     if (~row & 1)
       if (fread (pixel, raw_width, 3, ifp) < 3) derror();
-    for (col=0; col < raw_width; col++) {
+    for (col=0; col < width; col++) {
       y  = pixel[width*2*(row & 1) + col];
       cb = pixel[width + (col & -2)]   - 128;
       cr = pixel[width + (col & -2)+1] - 128;
-      rgb[1] = y-((cb + cr + 2) >> 2);
+      rgb[1] = y - ((cb + cr + 2) >> 2);
       rgb[2] = rgb[1] + cb;
       rgb[0] = rgb[1] + cr;
       FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,255)];
     }
   }
+#ifdef LIBRAW_LIBRARY_BUILD
+  } catch(...) {
+    free (pixel);
+    throw;
+  }
+#endif
   free (pixel);
   maximum = curve[0xff];
 }
@@ -2227,7 +3233,13 @@ void CLASS kodak_262_load_raw()
   strip = (int *) (pixel + raw_width*32);
   order = 0x4d4d;
   FORC(ns) strip[c] = get4();
+#ifdef LIBRAW_LIBRARY_BUILD
+  try {
+#endif
   for (row=0; row < raw_height; row++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     if ((row & 31) == 0) {
       fseek (ifp, strip[row >> 5], SEEK_SET);
       getbits(-1);
@@ -2248,6 +3260,12 @@ void CLASS kodak_262_load_raw()
       RAW(row,col) = val;
     }
   }
+#ifdef LIBRAW_LIBRARY_BUILD
+  } catch(...) {
+    free (pixel);
+    throw;
+  }
+#endif
   free (pixel);
   FORC(2) free (huff[c]);
 }
@@ -2304,6 +3322,10 @@ void CLASS kodak_65000_load_raw()
   int row, col, len, pred[2], ret, i;
 
   for (row=0; row < height; row++)
+  {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     for (col=0; col < width; col+=256) {
       pred[0] = pred[1] = 0;
       len = MIN (256, width-col);
@@ -2312,6 +3334,7 @@ void CLASS kodak_65000_load_raw()
 	if ((RAW(row,col+i) =	curve[ret ? buf[i] :
 		(pred[i & 1] += buf[i])]) >> 12) derror();
     }
+  }
 }
 
 void CLASS kodak_ycbcr_load_raw()
@@ -2320,7 +3343,13 @@ void CLASS kodak_ycbcr_load_raw()
   int row, col, len, c, i, j, k, y[2][2], cb, cr, rgb[3];
   ushort *ip;
 
+  if (!image) return;
+  unsigned int bits = (load_flags && load_flags > 9 && load_flags < 17)?load_flags:10;
   for (row=0; row < height; row+=2)
+  {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     for (col=0; col < width; col+=128) {
       len = MIN (128, width-col);
       kodak_65000_decode (buf, len*3);
@@ -2333,30 +3362,41 @@ void CLASS kodak_ycbcr_load_raw()
 	rgb[0] = rgb[1] + cr;
 	for (j=0; j < 2; j++)
 	  for (k=0; k < 2; k++) {
-	    if ((y[j][k] = y[j][k^1] + *bp++) >> 10) derror();
+	    if ((y[j][k] = y[j][k^1] + *bp++) >> bits) derror();
 	    ip = image[(row+j)*width + col+i+k];
 	    FORC3 ip[c] = curve[LIM(y[j][k]+rgb[c], 0, 0xfff)];
 	  }
       }
     }
+  }
 }
 
 void CLASS kodak_rgb_load_raw()
 {
   short buf[768], *bp;
-  int row, col, len, c, i, rgb[3];
+  int row, col, len, c, i, rgb[3],ret;
   ushort *ip=image[0];
 
-  if (raw_image) free (raw_image);
-  raw_image = 0;
   for (row=0; row < height; row++)
+  {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     for (col=0; col < width; col+=256) {
       len = MIN (256, width-col);
-      kodak_65000_decode (buf, len*3);
+      ret = kodak_65000_decode (buf, len*3);
       memset (rgb, 0, sizeof rgb);
       for (bp=buf, i=0; i < len; i++, ip+=4)
-	FORC3 if ((ip[c] = rgb[c] += *bp++) >> 12) derror();
+#ifdef LIBRAW_LIBRARY_BUILD
+        if(load_flags == 12)
+          {
+            FORC3 ip[c] = ret ? (*bp++) : (rgb[c] += *bp++);
+          }
+        else
+#endif
+          FORC3 if ((ip[c] = ret ? (*bp++) : (rgb[c] += *bp++)) >> 12) derror();
     }
+  }
 }
 
 void CLASS kodak_thumb_load_raw()
@@ -2371,8 +3411,12 @@ void CLASS kodak_thumb_load_raw()
 
 void CLASS sony_decrypt (unsigned *data, int len, int start, int key)
 {
+#ifndef LIBRAW_NOTHREADS
+#define pad tls->sony_decrypt.pad
+#define p   tls->sony_decrypt.p
+#else
   static unsigned pad[128], p;
-
+#endif
   if (start) {
     for (p=0; p < 4; p++)
       pad[p] = key = key * 48828125 + 1;
@@ -2383,7 +3427,14 @@ void CLASS sony_decrypt (unsigned *data, int len, int start, int key)
       pad[p] = htonl(pad[p]);
   }
   while (len--)
-    *data++ ^= pad[p++ & 127] = pad[(p+1) & 127] ^ pad[(p+65) & 127];
+    {
+      *data++ ^= pad[p & 127] = pad[(p+1) & 127] ^ pad[(p+65) & 127];
+      p++;
+    }
+#ifndef LIBRAW_NOTHREADS
+#undef pad
+#undef p
+#endif
 }
 
 void CLASS sony_load_raw()
@@ -2403,6 +3454,9 @@ void CLASS sony_load_raw()
     key = key << 8 | head[i];
   fseek (ifp, data_offset, SEEK_SET);
   for (row=0; row < raw_height; row++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     pixel = raw_image + row*raw_width;
     if (fread (pixel, 2, raw_width, ifp) < raw_width) derror();
     sony_decrypt ((unsigned int *) pixel, raw_width/2, !row, key);
@@ -2414,25 +3468,27 @@ void CLASS sony_load_raw()
 
 void CLASS sony_arw_load_raw()
 {
-  ushort huff[32768];
+  ushort huff[32770];
   static const ushort tab[18] =
   { 0xf11,0xf10,0xe0f,0xd0e,0xc0d,0xb0c,0xa0b,0x90a,0x809,
     0x708,0x607,0x506,0x405,0x304,0x303,0x300,0x202,0x201 };
-  int i, c, n, col, row, len, diff, sum=0;
+  int i, c, n, col, row, sum=0;
 
+  huff[0] = 15;
   for (n=i=0; i < 18; i++)
-    FORC(32768 >> (tab[i] >> 8)) huff[n++] = tab[i];
+    FORC(32768 >> (tab[i] >> 8)) huff[++n] = tab[i];
   getbits(-1);
   for (col = raw_width; col--; )
+  {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     for (row=0; row < raw_height+1; row+=2) {
       if (row == raw_height) row = 1;
-      len = getbithuff(15,huff);
-      diff = getbits(len);
-      if ((diff & (1 << (len-1))) == 0)
-	diff -= (1 << len) - 1;
-      if ((sum += diff) >> 12) derror();
+      if ((sum += ljpeg_diff(huff)) >> 12) derror();
       if (row < height) RAW(row,col) = sum;
     }
+  }
 }
 
 void CLASS sony_arw2_load_raw()
@@ -2441,9 +3497,15 @@ void CLASS sony_arw2_load_raw()
   ushort pix[16];
   int row, col, val, max, min, imax, imin, sh, bit, i;
 
-  data = (uchar *) malloc (raw_width);
+  data = (uchar *) malloc (raw_width+1);
   merror (data, "sony_arw2_load_raw()");
+#ifdef LIBRAW_LIBRARY_BUILD
+  try {
+#endif
   for (row=0; row < height; row++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     fread (data, 1, raw_width, ifp);
     for (dp=data, col=0; col < raw_width-30; dp+=16) {
       max = 0x7ff & (val = sget4(dp));
@@ -2451,6 +3513,52 @@ void CLASS sony_arw2_load_raw()
       imax = 0x0f & val >> 22;
       imin = 0x0f & val >> 26;
       for (sh=0; sh < 4 && 0x80 << sh <= max-min; sh++);
+#ifdef LIBRAW_LIBRARY_BUILD
+      /* flag checks if outside of loop */
+      if(imgdata.params.sony_arw2_options == LIBRAW_SONYARW2_NONE
+         || imgdata.params.sony_arw2_options == LIBRAW_SONYARW2_DELTATOVALUE
+         )
+        {
+          for (bit=30, i=0; i < 16; i++)
+            if      (i == imax) pix[i] = max;
+            else if (i == imin) pix[i] = min;
+            else {
+              pix[i] = ((sget2(dp+(bit >> 3)) >> (bit & 7) & 0x7f) << sh) + min;
+              if (pix[i] > 0x7ff) pix[i] = 0x7ff;
+              bit += 7;
+            }
+        }
+      else if(imgdata.params.sony_arw2_options == LIBRAW_SONYARW2_BASEONLY)
+        {
+          for (bit=30, i=0; i < 16; i++)
+            if      (i == imax) pix[i] = max;
+            else if (i == imin) pix[i] = min;
+            else pix[i]=0;
+        }
+      else if(imgdata.params.sony_arw2_options == LIBRAW_SONYARW2_DELTAONLY)
+        {
+          for (bit=30, i=0; i < 16; i++)
+            if      (i == imax) pix[i] = 0;
+            else if (i == imin) pix[i] = 0;
+            else {
+              pix[i] = ((sget2(dp+(bit >> 3)) >> (bit & 7) & 0x7f) << sh) + min;
+              if (pix[i] > 0x7ff) pix[i] = 0x7ff;
+              bit += 7;
+            }
+        }
+      else if(imgdata.params.sony_arw2_options == LIBRAW_SONYARW2_DELTAZEROBASE)
+        {
+          for (bit=30, i=0; i < 16; i++)
+            if      (i == imax) pix[i] = 0;
+            else if (i == imin) pix[i] = 0;
+            else {
+              pix[i] = ((sget2(dp+(bit >> 3)) >> (bit & 7) & 0x7f) << sh);
+              if (pix[i] > 0x7ff) pix[i] = 0x7ff;
+              bit += 7;
+            }
+        }
+#else
+      /* unaltered dcraw processing */
       for (bit=30, i=0; i < 16; i++)
 	if      (i == imax) pix[i] = max;
 	else if (i == imin) pix[i] = min;
@@ -2459,14 +3567,155 @@ void CLASS sony_arw2_load_raw()
 	  if (pix[i] > 0x7ff) pix[i] = 0x7ff;
 	  bit += 7;
 	}
+#endif
+
+#ifdef LIBRAW_LIBRARY_BUILD
+      if(imgdata.params.sony_arw2_options == LIBRAW_SONYARW2_DELTATOVALUE)
+        {
+          for (i=0; i < 16; i++, col+=2)
+            {
+              unsigned slope = pix[i] < 1001? 2 : curve[pix[i]<<1]-curve[(pix[i]<<1)-2];
+              unsigned step = 1 << sh;
+              RAW(row,col)=curve[pix[i]<<1]>black+imgdata.params.sony_arw2_posterization_thr?
+                LIM(((slope*step*1000)/(curve[pix[i]<<1]-black)),0,10000):0;
+            }
+        }
+      else
+        {
+          for (i=0; i < 16; i++, col+=2)
+            RAW(row,col) = curve[pix[i] << 1];
+        }
+#else
       for (i=0; i < 16; i++, col+=2)
-	if (col < width) RAW(row,col) = curve[pix[i] << 1] >> 2;
+	RAW(row,col) = curve[pix[i] << 1] >> 2;
+#endif
       col -= col & 1 ? 1:31;
     }
   }
+#ifdef LIBRAW_LIBRARY_BUILD
+  } catch(...) {
+    free (data);
+    throw;
+  }
+  if(imgdata.params.sony_arw2_options == LIBRAW_SONYARW2_DELTATOVALUE)
+    maximum=10000;
+#endif
   free (data);
 }
 
+void CLASS samsung_load_raw()
+{
+  int row, col, c, i, dir, op[4], len[4];
+
+  order = 0x4949;
+  for (row=0; row < raw_height; row++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
+    fseek (ifp, strip_offset+row*4, SEEK_SET);
+    fseek (ifp, data_offset+get4(), SEEK_SET);
+    ph1_bits(-1);
+    FORC4 len[c] = row < 2 ? 7:4;
+    for (col=0; col < raw_width; col+=16) {
+      dir = ph1_bits(1);
+      FORC4 op[c] = ph1_bits(2);
+      FORC4 switch (op[c]) {
+	case 3: len[c] = ph1_bits(4);	break;
+	case 2: len[c]--;		break;
+	case 1: len[c]++;
+      }
+      for (c=0; c < 16; c+=2) {
+	i = len[((c & 1) << 1) | (c >> 3)];
+        RAW(row,col+c) = ((signed) ph1_bits(i) << (32-i) >> (32-i)) +
+	  (dir ? RAW(row+(~c | -2),col+c) : col ? RAW(row,col+(c | -2)) : 128);
+	if (c == 14) c = -1;
+      }
+    }
+  }
+  for (row=0; row < raw_height-1; row+=2)
+    for (col=0; col < raw_width-1; col+=2)
+      SWAP (RAW(row,col+1), RAW(row+1,col));
+}
+
+void CLASS samsung2_load_raw()
+{
+  static const ushort tab[14] =
+  { 0x304,0x307,0x206,0x205,0x403,0x600,0x709,
+    0x80a,0x90b,0xa0c,0xa0d,0x501,0x408,0x402 };
+  ushort huff[1026], vpred[2][2] = {{0,0},{0,0}}, hpred[2];
+  int i, c, n, row, col, diff;
+
+  huff[0] = 10;
+  for (n=i=0; i < 14; i++)
+    FORC(1024 >> (tab[i] >> 8)) huff[++n] = tab[i];
+  getbits(-1);
+  for (row=0; row < raw_height; row++)
+  {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
+    for (col=0; col < raw_width; col++) {
+      diff = ljpeg_diff (huff);
+      if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
+      else	   hpred[col & 1] += diff;
+      RAW(row,col) = hpred[col & 1];
+      if (hpred[col & 1] >> tiff_bps) derror();
+    }
+  }
+}
+
+void CLASS samsung3_load_raw()
+{
+  int opt, init, mag, pmode, row, tab, col, pred, diff, i, c;
+  ushort lent[3][2], len[4], *prow[2];
+
+  order = 0x4949;
+  fseek (ifp, 9, SEEK_CUR);
+  opt = fgetc(ifp);
+  init = (get2(),get2());
+  for (row=0; row < raw_height; row++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
+    fseek (ifp, (data_offset-ftell(ifp)) & 15, SEEK_CUR);
+    ph1_bits(-1);
+    mag = 0; pmode = 7;
+    FORC(6) lent[0][c] = row < 2 ? 7:4;
+    prow[ row & 1] = &RAW(row-1,1-((row & 1) << 1));	// green
+    prow[~row & 1] = &RAW(row-2,0);			// red and blue
+    for (tab=0; tab+15 < raw_width; tab+=16) {
+      if (~opt & 4 && !(tab & 63)) {
+	i = ph1_bits(2);
+	mag = i < 3 ? mag-'2'+"204"[i] : ph1_bits(12);
+      }
+      if (opt & 2)
+	pmode = 7 - 4*ph1_bits(1);
+      else if (!ph1_bits(1))
+	pmode = ph1_bits(3);
+      if (opt & 1 || !ph1_bits(1)) {
+	FORC4 len[c] = ph1_bits(2);
+	FORC4 {
+	  i = ((row & 1) << 1 | (c & 1)) % 3;
+	  len[c] = len[c] < 3 ? lent[i][0]-'1'+"120"[len[c]] : ph1_bits(4);
+	  lent[i][0] = lent[i][1];
+	  lent[i][1] = len[c];
+	}
+      }
+      FORC(16) {
+	col = tab + (((c & 7) << 1)^(c >> 3)^(row & 1));
+	pred = (pmode == 7 || row < 2)
+	     ? (tab ? RAW(row,tab-2+(col & 1)) : init)
+	     : (prow[col & 1][col-'4'+"0224468"[pmode]] +
+		prow[col & 1][col-'4'+"0244668"[pmode]] + 1) >> 1;
+	diff = ph1_bits (i = len[c >> 2]);
+	if (diff >> (i-1)) diff -= 1 << i;
+	diff = diff * (mag*2+1) + mag;
+	RAW(row,col) = pred + diff;
+      }
+    }
+  }
+}
+
 #define HOLE(row) ((holes >> (((row) - raw_height) & 7)) & 1)
 
 /* Kudos to Rich Taylor for figuring out SMaL's compression algorithm. */
@@ -2492,7 +3741,7 @@ void CLASS smal_decode_segment (unsigned seg[2][2], int holes)
 	if ((data >> nbits & 0xff) == 0xff) break;
       if (nbits > 0)
 	  data = ((data & ((1 << (nbits-1)) - 1)) << 1) |
-	((data + (((data & (1 << (nbits-1)))) << 1)) & (-1 << nbits));
+            ((data + (((data & (1 << (nbits-1)))) << 1)) & ((~0u) << nbits));
       if (nbits >= 0) {
 	data += getbits(1);
 	carry = nbits - 8;
@@ -2613,15 +3862,36 @@ void CLASS redcine_load_raw()
   ushort *img, *pix;
 
   jas_init();
+#ifndef LIBRAW_LIBRARY_BUILD
   in = jas_stream_fopen (ifname, "rb");
+#else
+  in = (jas_stream_t*)ifp->make_jas_stream();
+  if(!in)
+          throw LIBRAW_EXCEPTION_DECODE_JPEG2000;
+#endif
   jas_stream_seek (in, data_offset+20, SEEK_SET);
   jimg = jas_image_decode (in, -1, 0);
+#ifndef LIBRAW_LIBRARY_BUILD
   if (!jimg) longjmp (failure, 3);
+#else
+  if(!jimg)
+    {
+      jas_stream_close (in);
+      throw LIBRAW_EXCEPTION_DECODE_JPEG2000;
+    }
+#endif
   jmat = jas_matrix_create (height/2, width/2);
   merror (jmat, "redcine_load_raw()");
-  img = (ushort *) calloc ((height+2)*(width+2), 2);
+  img = (ushort *) calloc ((height+2), (width+2)*2);
   merror (img, "redcine_load_raw()");
+#ifdef LIBRAW_LIBRARY_BUILD
+  bool fastexitflag = false;
+  try {
+#endif
   FORC4 {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     jas_image_readcmpt (jimg, c, 0, 0, width/2, height/2, jmat);
     data = jas_matrix_getref (jmat, 0, 0);
     for (row = c >> 1; row < height; row+=2)
@@ -2637,6 +3907,9 @@ void CLASS redcine_load_raw()
     img[(row+1)*(width+2)-1] = img[(row+1)*(width+2)-3];
   }
   for (row=1; row <= height; row++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     pix = img + row*(width+2) + (col = 1 + (FC(row,1) & 1));
     for (   ; col <= width; col+=2, pix+=2) {
       c = (((pix[0] - 0x800) << 3) +
@@ -2645,14 +3918,29 @@ void CLASS redcine_load_raw()
     }
   }
   for (row=0; row < height; row++)
+  {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     for (col=0; col < width; col++)
       RAW(row,col) = curve[img[(row+1)*(width+2)+col+1]];
+  }
+#ifdef LIBRAW_LIBRARY_BUILD
+  } catch (...) {
+    fastexitflag=true;
+  }
+#endif
   free (img);
   jas_matrix_destroy (jmat);
   jas_image_destroy (jimg);
   jas_stream_close (in);
+#ifdef LIBRAW_LIBRARY_BUILD
+  if(fastexitflag)
+    throw LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK;
+#endif
 #endif
 }
+//@end COMMON
 
 /* RESTRICTED code starts here */
 
@@ -2738,6 +4026,9 @@ void CLASS foveon_sd_load_raw()
   if (!load_flags) foveon_decoder (1024, 0);
 
   for (row=0; row < height; row++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     memset (pred, 0, sizeof pred);
     if (!bit && !load_flags && atoi(model+2) < 14) get4();
     for (col=bit=0; col < width; col++) {
@@ -2777,7 +4068,7 @@ void CLASS foveon_huff (ushort *huff)
 void CLASS foveon_dp_load_raw()
 {
   unsigned c, roff[4], row, col, diff;
-  ushort huff[258], vpred, hpred;
+  ushort huff[512], vpred[2][2], hpred[2];
 
   fseek (ifp, 8, SEEK_CUR);
   foveon_huff (huff);
@@ -2786,18 +4077,22 @@ void CLASS foveon_dp_load_raw()
   FORC3 {
     fseek (ifp, data_offset+roff[c], SEEK_SET);
     getbits(-1);
-    vpred = 1024;
+    vpred[0][0] = vpred[0][1] = vpred[1][0] = vpred[1][1] = 512;
     for (row=0; row < height; row++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
       for (col=0; col < width; col++) {
-	diff = ljpeg_diff(huff);
-	if (col) hpred += diff;
-	else hpred = vpred += diff;
-	image[row*width+col][c] = hpred;
+       diff = ljpeg_diff(huff);
+       if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
+       else hpred[col & 1] += diff;
+       image[row*width+col][c] = hpred[col & 1];
       }
     }
   }
 }
 
+
 void CLASS foveon_load_camf()
 {
   unsigned type, wide, high, i, j, row, col, diff;
@@ -2830,11 +4125,14 @@ void CLASS foveon_load_camf()
 	  meta_data[j++] = hpred[0] >> 4;
 	  meta_data[j++] = hpred[0] << 4 | hpred[1] >> 8;
 	  meta_data[j++] = hpred[1];
-        }
+	}
       }
     }
-  } else
+  }
+#ifdef DCRAW_VERBOSE
+   else
     fprintf (stderr,_("%s has unknown CAMF type %d.\n"), ifname, type);
+#endif
 }
 
 const char * CLASS foveon_camf_param (const char *block, const char *param)
@@ -2889,7 +4187,9 @@ void * CLASS foveon_camf_matrix (unsigned dim[3], const char *name)
 	mat[i] = sget4(dp + i*2) & 0xffff;
     return mat;
   }
+#ifdef DCRAW_VERBOSE
   fprintf (stderr,_("%s: \"%s\" matrix not found!\n"), ifname, name);
+#endif
   return 0;
 }
 
@@ -2976,8 +4276,10 @@ void CLASS foveon_interpolate()
   char str[128];
   const char* cp;
 
+#ifdef DCRAW_VERBOSE
   if (verbose)
     fprintf (stderr,_("Foveon interpolation...\n"));
+#endif
 
   foveon_load_camf();
   foveon_fixed (dscr, 4, "DarkShieldColRange");
@@ -2990,7 +4292,7 @@ void CLASS foveon_interpolate()
 	foveon_camf_param ("IncludeBlocks", "ColorDQ") ?
 		"ColorDQ" : "ColorDQCamRGB");
   if (foveon_camf_param ("IncludeBlocks", "ColumnFilter"))
-  		 foveon_fixed (&cfilt, 1, "ColumnFilter");
+		 foveon_fixed (&cfilt, 1, "ColumnFilter");
 
   memset (ddft, 0, sizeof ddft);
   if (!foveon_camf_param ("IncludeBlocks", "DarkDrift")
@@ -3004,7 +4306,10 @@ void CLASS foveon_interpolate()
     }
 
   if (!(cp = foveon_camf_param ("WhiteBalanceIlluminants", model2)))
-  { fprintf (stderr,_("%s: Invalid white balance \"%s\"\n"), ifname, model2);
+  {
+#ifdef DCRAW_VERBOSE
+    fprintf (stderr,_("%s: Invalid white balance \"%s\"\n"), ifname, model2);
+#endif
     return; }
   foveon_fixed (cam_xyz, 9, cp);
   foveon_fixed (correct, 9,
@@ -3057,7 +4362,7 @@ void CLASS foveon_interpolate()
       ddft[0][0][i] = ddft[1][0][i] +
 	row / (height-1.0) * (ddft[2][0][i] - ddft[1][0][i]);
     FORC3 black[row][c] =
- 	( foveon_avg (image[row*width]+c, dscr[0], cfilt) +
+	( foveon_avg (image[row*width]+c, dscr[0], cfilt) +
 	  foveon_avg (image[row*width]+c, dscr[1], cfilt) * 3
 	  - ddft[0][c][0] ) / 4 - ddft[0][c][1];
   }
@@ -3282,7 +4587,7 @@ void CLASS foveon_interpolate()
   }
 
   /* Smooth the image bottom-to-top and save at 1/4 scale */
-  shrink = (short (*)[3]) calloc ((width/4) * (height/4), sizeof *shrink);
+  shrink = (short (*)[3]) calloc ((height/4), (width/4)*sizeof *shrink);
   merror (shrink, "foveon_interpolate()");
   for (row = height/4; row--; )
     for (col=0; col < width/4; col++) {
@@ -3358,11 +4663,20 @@ void CLASS foveon_interpolate()
 
 /* RESTRICTED code ends here */
 
+//@out COMMON
 void CLASS crop_masked_pixels()
 {
   int row, col;
-  unsigned r, c, m, mblack[8], zero, val;
+  unsigned
+#ifndef LIBRAW_LIBRARY_BUILD
+    r, raw_pitch = raw_width*2,
+    c, m, mblack[8], zero, val;
+#else
+    c, m, zero, val;
+#define mblack imgdata.color.black_stat
+#endif
 
+#ifndef LIBRAW_LIBRARY_BUILD
   if (load_raw == &CLASS phase_one_load_raw ||
       load_raw == &CLASS phase_one_load_raw_c)
     phase_one_correct();
@@ -3385,18 +4699,16 @@ void CLASS crop_masked_pixels()
       for (col=0; col < width; col++)
 	BAYER2(row,col) = RAW(row+top_margin,col+left_margin);
   }
-  if (mask[0][3]) goto mask_set;
+#endif
+  if (mask[0][3] > 0) goto mask_set;
   if (load_raw == &CLASS canon_load_raw ||
       load_raw == &CLASS lossless_jpeg_load_raw) {
-    mask[0][1] = mask[1][1] = 2;
-    mask[0][3] = -2;
-    goto sides;
-  }
-  if (load_raw == &CLASS sony_load_raw) {
-    mask[0][3] = 9;
+    mask[0][1] = mask[1][1] += 2;
+    mask[0][3] -= 2;
     goto sides;
   }
   if (load_raw == &CLASS canon_600_load_raw ||
+      load_raw == &CLASS sony_load_raw ||
      (load_raw == &CLASS eight_bit_load_raw && strncmp(model,"DC2",3)) ||
       load_raw == &CLASS kodak_262_load_raw ||
      (load_raw == &CLASS packed_load_raw && (load_flags & 32))) {
@@ -3414,25 +4726,36 @@ sides:
 mask_set:
   memset (mblack, 0, sizeof mblack);
   for (zero=m=0; m < 8; m++)
-    for (row=mask[m][0]; row < mask[m][2]; row++)
-      for (col=mask[m][1]; col < mask[m][3]; col++) {
+    for (row=MAX(mask[m][0],0); row < MIN(mask[m][2],raw_height); row++)
+      for (col=MAX(mask[m][1],0); col < MIN(mask[m][3],raw_width); col++) {
 	c = FC(row-top_margin,col-left_margin);
-	mblack[c] += val = RAW(row,col);
+	mblack[c] += val = raw_image[(row)*raw_pitch/2+(col)];
 	mblack[4+c]++;
 	zero += !val;
       }
   if (load_raw == &CLASS canon_600_load_raw && width < raw_width) {
     black = (mblack[0]+mblack[1]+mblack[2]+mblack[3]) /
 	    (mblack[4]+mblack[5]+mblack[6]+mblack[7]) - 4;
+#ifndef LIBRAW_LIBRARY_BUILD
     canon_600_correct();
-  } else if (zero < mblack[4] && mblack[5] && mblack[6] && mblack[7])
+#endif
+  } else if (zero < mblack[4] && mblack[5] && mblack[6] && mblack[7]) {
     FORC4 cblack[c] = mblack[c] / mblack[4+c];
+    cblack[4] = cblack[5] = cblack[6] = 0;
+  }
 }
+#ifdef LIBRAW_LIBRARY_BUILD
+#undef mblack
+#endif
 
 void CLASS remove_zeroes()
 {
   unsigned row, col, tot, n, r, c;
 
+#ifdef LIBRAW_LIBRARY_BUILD
+  RUN_CALLBACK(LIBRAW_PROGRESS_REMOVE_ZEROES,0,2);
+#endif
+
   for (row=0; row < height; row++)
     for (col=0; col < width; col++)
       if (BAYER(row,col) == 0) {
@@ -3444,21 +4767,49 @@ void CLASS remove_zeroes()
 	      tot += (n++,BAYER(r,c));
 	if (n) BAYER(row,col) = tot/n;
       }
+#ifdef LIBRAW_LIBRARY_BUILD
+  RUN_CALLBACK(LIBRAW_PROGRESS_REMOVE_ZEROES,1,2);
+#endif
 }
+//@end COMMON
+
+/* @out FILEIO
+#include <math.h>
+#define CLASS LibRaw::
+#include "libraw/libraw_types.h"
+#define LIBRAW_LIBRARY_BUILD
+#include "libraw/libraw.h"
+#include "internal/defines.h"
+#include "internal/var_defines.h"
+ at end FILEIO */
+
 
+// @out FILEIO
 /*
    Seach from the current directory up to the root looking for
    a ".badpixels" file, and fix those pixels now.
  */
 void CLASS bad_pixels (const char *cfname)
 {
-  FILE *fp=0;
+  FILE *fp=NULL;
+#ifndef LIBRAW_LIBRARY_BUILD
   char *fname, *cp, line[128];
   int len, time, row, col, r, c, rad, tot, n, fixed=0;
+#else
+  char *cp, line[128];
+  int time, row, col, r, c, rad, tot, n;
+#ifdef DCRAW_VERBOSE
+  int fixed = 0;
+#endif
+#endif
 
   if (!filters) return;
+#ifdef LIBRAW_LIBRARY_BUILD
+  RUN_CALLBACK(LIBRAW_PROGRESS_BAD_PIXELS,0,2);
+#endif
   if (cfname)
     fp = fopen (cfname, "r");
+// @end FILEIO
   else {
     for (len=32 ; ; len *= 2) {
       fname = (char *) malloc (len);
@@ -3483,7 +4834,14 @@ void CLASS bad_pixels (const char *cfname)
     }
     free (fname);
   }
-  if (!fp) return;
+// @out FILEIO
+  if (!fp)
+      {
+#ifdef LIBRAW_LIBRARY_BUILD
+          imgdata.process_warnings |= LIBRAW_WARN_NO_BADPIXELMAP;
+#endif
+          return;
+      }
   while (fgets (line, 128, fp)) {
     cp = strchr (line, '#');
     if (cp) *cp = 0;
@@ -3499,14 +4857,21 @@ void CLASS bad_pixels (const char *cfname)
 	    n++;
 	  }
     BAYER2(row,col) = tot/n;
+#ifdef DCRAW_VERBOSE
     if (verbose) {
       if (!fixed++)
 	fprintf (stderr,_("Fixed dead pixels at:"));
       fprintf (stderr, " %d,%d", col, row);
     }
+#endif
   }
+#ifdef DCRAW_VERBOSE
   if (fixed) fputc ('\n', stderr);
+#endif
   fclose (fp);
+#ifdef LIBRAW_LIBRARY_BUILD
+  RUN_CALLBACK(LIBRAW_PROGRESS_BAD_PIXELS,1,2);
+#endif
 }
 
 void CLASS subtract (const char *fname)
@@ -3514,9 +4879,18 @@ void CLASS subtract (const char *fname)
   FILE *fp;
   int dim[3]={0,0,0}, comment=0, number=0, error=0, nd=0, c, row, col;
   ushort *pixel;
+#ifdef LIBRAW_LIBRARY_BUILD
+  RUN_CALLBACK(LIBRAW_PROGRESS_DARK_FRAME,0,2);
+#endif
 
   if (!(fp = fopen (fname, "rb"))) {
-    perror (fname);  return;
+#ifdef DCRAW_VERBOSE
+    perror (fname);
+#endif
+#ifdef LIBRAW_LIBRARY_BUILD
+    imgdata.process_warnings |= LIBRAW_WARN_BAD_DARKFRAME_FILE;
+#endif
+    return;
   }
   if (fgetc(fp) != 'P' || fgetc(fp) != '5') error = 1;
   while (!error && nd < 3 && (c = fgetc(fp)) != EOF) {
@@ -3532,10 +4906,17 @@ void CLASS subtract (const char *fname)
     }
   }
   if (error || nd < 3) {
+#ifdef DCRAW_VERBOSE
     fprintf (stderr,_("%s is not a valid PGM file!\n"), fname);
+#endif
     fclose (fp);  return;
   } else if (dim[0] != width || dim[1] != height || dim[2] != 65535) {
-    fprintf (stderr,_("%s has the wrong dimensions!\n"), fname);
+#ifdef DCRAW_VERBOSE
+      fprintf (stderr,_("%s has the wrong dimensions!\n"), fname);
+#endif
+#ifdef LIBRAW_LIBRARY_BUILD
+      imgdata.process_warnings |= LIBRAW_WARN_BAD_DARKFRAME_DIM;
+#endif
     fclose (fp);  return;
   }
   pixel = (ushort *) calloc (width, sizeof *pixel);
@@ -3549,7 +4930,47 @@ void CLASS subtract (const char *fname)
   fclose (fp);
   memset (cblack, 0, sizeof cblack);
   black = 0;
+#ifdef LIBRAW_LIBRARY_BUILD
+  RUN_CALLBACK(LIBRAW_PROGRESS_DARK_FRAME,1,2);
+#endif
 }
+//@end FILEIO
+
+//@out COMMON
+
+static const uchar xlat[2][256] = {
+  { 0xc1,0xbf,0x6d,0x0d,0x59,0xc5,0x13,0x9d,0x83,0x61,0x6b,0x4f,0xc7,0x7f,0x3d,0x3d,
+    0x53,0x59,0xe3,0xc7,0xe9,0x2f,0x95,0xa7,0x95,0x1f,0xdf,0x7f,0x2b,0x29,0xc7,0x0d,
+    0xdf,0x07,0xef,0x71,0x89,0x3d,0x13,0x3d,0x3b,0x13,0xfb,0x0d,0x89,0xc1,0x65,0x1f,
+    0xb3,0x0d,0x6b,0x29,0xe3,0xfb,0xef,0xa3,0x6b,0x47,0x7f,0x95,0x35,0xa7,0x47,0x4f,
+    0xc7,0xf1,0x59,0x95,0x35,0x11,0x29,0x61,0xf1,0x3d,0xb3,0x2b,0x0d,0x43,0x89,0xc1,
+    0x9d,0x9d,0x89,0x65,0xf1,0xe9,0xdf,0xbf,0x3d,0x7f,0x53,0x97,0xe5,0xe9,0x95,0x17,
+    0x1d,0x3d,0x8b,0xfb,0xc7,0xe3,0x67,0xa7,0x07,0xf1,0x71,0xa7,0x53,0xb5,0x29,0x89,
+    0xe5,0x2b,0xa7,0x17,0x29,0xe9,0x4f,0xc5,0x65,0x6d,0x6b,0xef,0x0d,0x89,0x49,0x2f,
+    0xb3,0x43,0x53,0x65,0x1d,0x49,0xa3,0x13,0x89,0x59,0xef,0x6b,0xef,0x65,0x1d,0x0b,
+    0x59,0x13,0xe3,0x4f,0x9d,0xb3,0x29,0x43,0x2b,0x07,0x1d,0x95,0x59,0x59,0x47,0xfb,
+    0xe5,0xe9,0x61,0x47,0x2f,0x35,0x7f,0x17,0x7f,0xef,0x7f,0x95,0x95,0x71,0xd3,0xa3,
+    0x0b,0x71,0xa3,0xad,0x0b,0x3b,0xb5,0xfb,0xa3,0xbf,0x4f,0x83,0x1d,0xad,0xe9,0x2f,
+    0x71,0x65,0xa3,0xe5,0x07,0x35,0x3d,0x0d,0xb5,0xe9,0xe5,0x47,0x3b,0x9d,0xef,0x35,
+    0xa3,0xbf,0xb3,0xdf,0x53,0xd3,0x97,0x53,0x49,0x71,0x07,0x35,0x61,0x71,0x2f,0x43,
+    0x2f,0x11,0xdf,0x17,0x97,0xfb,0x95,0x3b,0x7f,0x6b,0xd3,0x25,0xbf,0xad,0xc7,0xc5,
+    0xc5,0xb5,0x8b,0xef,0x2f,0xd3,0x07,0x6b,0x25,0x49,0x95,0x25,0x49,0x6d,0x71,0xc7 },
+  { 0xa7,0xbc,0xc9,0xad,0x91,0xdf,0x85,0xe5,0xd4,0x78,0xd5,0x17,0x46,0x7c,0x29,0x4c,
+    0x4d,0x03,0xe9,0x25,0x68,0x11,0x86,0xb3,0xbd,0xf7,0x6f,0x61,0x22,0xa2,0x26,0x34,
+    0x2a,0xbe,0x1e,0x46,0x14,0x68,0x9d,0x44,0x18,0xc2,0x40,0xf4,0x7e,0x5f,0x1b,0xad,
+    0x0b,0x94,0xb6,0x67,0xb4,0x0b,0xe1,0xea,0x95,0x9c,0x66,0xdc,0xe7,0x5d,0x6c,0x05,
+    0xda,0xd5,0xdf,0x7a,0xef,0xf6,0xdb,0x1f,0x82,0x4c,0xc0,0x68,0x47,0xa1,0xbd,0xee,
+    0x39,0x50,0x56,0x4a,0xdd,0xdf,0xa5,0xf8,0xc6,0xda,0xca,0x90,0xca,0x01,0x42,0x9d,
+    0x8b,0x0c,0x73,0x43,0x75,0x05,0x94,0xde,0x24,0xb3,0x80,0x34,0xe5,0x2c,0xdc,0x9b,
+    0x3f,0xca,0x33,0x45,0xd0,0xdb,0x5f,0xf5,0x52,0xc3,0x21,0xda,0xe2,0x22,0x72,0x6b,
+    0x3e,0xd0,0x5b,0xa8,0x87,0x8c,0x06,0x5d,0x0f,0xdd,0x09,0x19,0x93,0xd0,0xb9,0xfc,
+    0x8b,0x0f,0x84,0x60,0x33,0x1c,0x9b,0x45,0xf1,0xf0,0xa3,0x94,0x3a,0x12,0x77,0x33,
+    0x4d,0x44,0x78,0x28,0x3c,0x9e,0xfd,0x65,0x57,0x16,0x94,0x6b,0xfb,0x59,0xd0,0xc8,
+    0x22,0x36,0xdb,0xd2,0x63,0x98,0x43,0xa1,0x04,0x87,0x86,0xf7,0xa6,0x26,0xbb,0xd6,
+    0x59,0x4d,0xbf,0x6a,0x2e,0xaa,0x2b,0xef,0xe6,0x78,0xb6,0x4e,0xe0,0x2f,0xdc,0x7c,
+    0xbe,0x57,0x19,0x32,0x7e,0x2a,0xd0,0xb8,0xba,0x29,0x00,0x3c,0x52,0x7d,0xa8,0x49,
+    0x3b,0x2d,0xeb,0x25,0x49,0xfa,0xa3,0xaa,0x39,0xa7,0xc5,0xa7,0x50,0x11,0x36,0xfb,
+    0xc6,0x67,0x4a,0xf5,0xa5,0x12,0x65,0x7e,0xb0,0xdf,0xaf,0x4e,0xb3,0x61,0x7f,0x2f } };
 
 void CLASS gamma_curve (double pwr, double ts, int mode, int imax)
 {
@@ -3615,7 +5036,7 @@ void CLASS pseudoinverse (double (*in)[3], double (*out)[3], int size)
 	out[i][j] += work[j][k+3] * in[i][k];
 }
 
-void CLASS cam_xyz_coeff (double cam_xyz[4][3])
+void CLASS cam_xyz_coeff (float _rgb_cam[3][4], double cam_xyz[4][3])
 {
   double cam_rgb[4][3], inverse[4][3], num;
   int i, j, k;
@@ -3628,14 +5049,23 @@ void CLASS cam_xyz_coeff (double cam_xyz[4][3])
   for (i=0; i < colors; i++) {		/* Normalize cam_rgb so that */
     for (num=j=0; j < 3; j++)		/* cam_rgb * (1,1,1) is (1,1,1,1) */
       num += cam_rgb[i][j];
-    for (j=0; j < 3; j++)
-      cam_rgb[i][j] /= num;
-    pre_mul[i] = 1 / num;
+    if(num > 0.00001)
+      {
+        for (j=0; j < 3; j++)
+          cam_rgb[i][j] /= num;
+        pre_mul[i] = 1 / num;
+      }
+    else
+      {
+        for (j=0; j < 3; j++)
+          cam_rgb[i][j] = 0.0;
+        pre_mul[i] = 1.0;
+      }
   }
   pseudoinverse (cam_rgb, inverse, colors);
-  for (raw_color = i=0; i < 3; i++)
+  for (i=0; i < 3; i++)
     for (j=0; j < colors; j++)
-      rgb_cam[i][j] = inverse[j][i];
+      _rgb_cam[i][j] = inverse[j][i];
 }
 
 #ifdef COLORCHECK
@@ -3672,8 +5102,8 @@ void CLASS colorcheck()
     { 0.310, 0.316, 9.0 },		// Neutral 3.5
     { 0.310, 0.316, 3.1 } };		// Black
   double gmb_cam[NSQ][4], gmb_xyz[NSQ][3];
-  double inverse[NSQ][3], cam_xyz[4][3], num;
-  int c, i, j, k, sq, row, col, count[4];
+  double inverse[NSQ][3], cam_xyz[4][3], balance[4], num;
+  int c, i, j, k, sq, row, col, pass, count[4];
 
   memset (gmb_cam, 0, sizeof gmb_cam);
   for (sq=0; sq < NSQ; sq++) {
@@ -3682,7 +5112,8 @@ void CLASS colorcheck()
       for (col=cut[sq][2]; col < cut[sq][2]+cut[sq][0]; col++) {
 	c = FC(row,col);
 	if (c >= colors) c -= 2;
-	gmb_cam[sq][c] += BAYER(row,col);
+	gmb_cam[sq][c] += BAYER2(row,col);
+	BAYER2(row,col) = black + (BAYER2(row,col)-black)/2;
 	count[c]++;
       }
     FORCC gmb_cam[sq][c] = gmb_cam[sq][c]/count[c] - black;
@@ -3692,11 +5123,16 @@ void CLASS colorcheck()
 		(1 - gmb_xyY[sq][0] - gmb_xyY[sq][1]) / gmb_xyY[sq][1];
   }
   pseudoinverse (gmb_xyz, inverse, NSQ);
-  for (i=0; i < colors; i++)
-    for (j=0; j < 3; j++)
-      for (cam_xyz[i][j] = k=0; k < NSQ; k++)
-	cam_xyz[i][j] += gmb_cam[k][i] * inverse[k][j];
-  cam_xyz_coeff (cam_xyz);
+  for (pass=0; pass < 2; pass++) {
+    for (raw_color = i=0; i < colors; i++)
+      for (j=0; j < 3; j++)
+	for (cam_xyz[i][j] = k=0; k < NSQ; k++)
+	  cam_xyz[i][j] += gmb_cam[k][i] * inverse[k][j];
+    cam_xyz_coeff (rgb_cam, cam_xyz);
+    FORCC balance[c] = pre_mul[c] * gmb_cam[20][c];
+    for (sq=0; sq < NSQ; sq++)
+      FORCC gmb_cam[sq][c] *= balance[c];
+  }
   if (verbose) {
     printf ("    { \"%s %s\", %d,\n\t{", make, model, black);
     num = 10000 / (cam_xyz[1][0] + cam_xyz[1][1] + cam_xyz[1][2]);
@@ -3719,6 +5155,7 @@ void CLASS hat_transform (float *temp, float *base, int st, int size, int sc)
     temp[i] = 2*base[st*i] + base[st*(i-sc)] + base[st*(2*size-2-(i+sc))];
 }
 
+#if !defined(LIBRAW_USE_OPENMP)
 void CLASS wavelet_denoise()
 {
   float *fimg=0, *temp, thold, mul[2], avg, diff;
@@ -3727,7 +5164,9 @@ void CLASS wavelet_denoise()
   static const float noise[] =
   { 0.8002,0.2735,0.1202,0.0585,0.0291,0.0152,0.0080,0.0044 };
 
+#ifdef DCRAW_VERBOSE
   if (verbose) fprintf (stderr,_("Wavelet denoising...\n"));
+#endif
 
   while (maximum << scale < 0x10000) scale++;
   maximum <<= --scale;
@@ -3740,7 +5179,7 @@ void CLASS wavelet_denoise()
   if ((nc = colors) == 3 && filters) nc++;
   FORC(nc) {			/* denoise R,G1,B,G3 individually */
     for (i=0; i < size; i++)
-      fimg[i] = 256 * sqrt(image[i][c] << scale);
+      fimg[i] = 256 * sqrt((double)(image[i][c] << scale));
     for (hpass=lev=0; lev < 5; lev++) {
       lpass = size*((lev & 1)+1);
       for (row=0; row < iheight; row++) {
@@ -3786,7 +5225,113 @@ void CLASS wavelet_denoise()
 		window[2][col-1] + window[2][col+1] - blk[~row & 1]*4 )
 	      * mul[row & 1] + (window[1][col] + blk[row & 1]) * 0.5;
 	avg = avg < 0 ? 0 : sqrt(avg);
-	diff = sqrt(BAYER(row,col)) - avg;
+	diff = sqrt((double)BAYER(row,col)) - avg;
+	if      (diff < -thold) diff += thold;
+	else if (diff >  thold) diff -= thold;
+	else diff = 0;
+	BAYER(row,col) = CLIP(SQR(avg+diff) + 0.5);
+      }
+    }
+  }
+  free (fimg);
+}
+#else /* LIBRAW_USE_OPENMP */
+void CLASS wavelet_denoise()
+{
+  float *fimg=0, *temp, thold, mul[2], avg, diff;
+   int scale=1, size, lev, hpass, lpass, row, col, nc, c, i, wlast, blk[2];
+  ushort *window[4];
+  static const float noise[] =
+  { 0.8002,0.2735,0.1202,0.0585,0.0291,0.0152,0.0080,0.0044 };
+
+#ifdef DCRAW_VERBOSE
+  if (verbose) fprintf (stderr,_("Wavelet denoising...\n"));
+#endif
+
+  while (maximum << scale < 0x10000) scale++;
+  maximum <<= --scale;
+  black <<= scale;
+  FORC4 cblack[c] <<= scale;
+  if ((size = iheight*iwidth) < 0x15550000)
+    fimg = (float *) malloc ((size*3 + iheight + iwidth) * sizeof *fimg);
+  merror (fimg, "wavelet_denoise()");
+  temp = fimg + size*3;
+  if ((nc = colors) == 3 && filters) nc++;
+#ifdef LIBRAW_LIBRARY_BUILD
+#pragma omp parallel default(shared) private(i,col,row,thold,lev,lpass,hpass,temp,c) firstprivate(scale,size)
+#endif
+  {
+      temp = (float*)malloc( (iheight + iwidth) * sizeof *fimg);
+    FORC(nc) {			/* denoise R,G1,B,G3 individually */
+#ifdef LIBRAW_LIBRARY_BUILD
+#pragma omp for
+#endif
+      for (i=0; i < size; i++)
+        fimg[i] = 256 * sqrt((double)(image[i][c] << scale));
+      for (hpass=lev=0; lev < 5; lev++) {
+	lpass = size*((lev & 1)+1);
+#ifdef LIBRAW_LIBRARY_BUILD
+#pragma omp for
+#endif
+	for (row=0; row < iheight; row++) {
+	  hat_transform (temp, fimg+hpass+row*iwidth, 1, iwidth, 1 << lev);
+	  for (col=0; col < iwidth; col++)
+	    fimg[lpass + row*iwidth + col] = temp[col] * 0.25;
+	}
+#ifdef LIBRAW_LIBRARY_BUILD
+#pragma omp for
+#endif
+	for (col=0; col < iwidth; col++) {
+	  hat_transform (temp, fimg+lpass+col, iwidth, iheight, 1 << lev);
+	  for (row=0; row < iheight; row++)
+	    fimg[lpass + row*iwidth + col] = temp[row] * 0.25;
+	}
+	thold = threshold * noise[lev];
+#ifdef LIBRAW_LIBRARY_BUILD
+#pragma omp for
+#endif
+	for (i=0; i < size; i++) {
+	  fimg[hpass+i] -= fimg[lpass+i];
+	  if	(fimg[hpass+i] < -thold) fimg[hpass+i] += thold;
+	  else if (fimg[hpass+i] >  thold) fimg[hpass+i] -= thold;
+	  else	 fimg[hpass+i] = 0;
+	  if (hpass) fimg[i] += fimg[hpass+i];
+	}
+	hpass = lpass;
+      }
+#ifdef LIBRAW_LIBRARY_BUILD
+#pragma omp for
+#endif
+      for (i=0; i < size; i++)
+	image[i][c] = CLIP(SQR(fimg[i]+fimg[lpass+i])/0x10000);
+    }
+    free(temp);
+  } /* end omp parallel */
+/* the following loops are hard to parallize, no idea yes,
+ * problem is wlast which is carrying dependency
+ * second part should be easyer, but did not yet get it right.
+ */
+  if (filters && colors == 3) {  /* pull G1 and G3 closer together */
+   for (row=0; row < 2; row++){
+      mul[row] = 0.125 * pre_mul[FC(row+1,0) | 1] / pre_mul[FC(row,0) | 1];
+      blk[row] = cblack[FC(row,0) | 1];
+   }
+    for (i=0; i < 4; i++)
+      window[i] = (ushort *) fimg + width*i;
+    for (wlast=-1, row=1; row < height-1; row++) {
+      while (wlast < row+1) {
+	for (wlast++, i=0; i < 4; i++)
+	  window[(i+3) & 3] = window[i];
+	for (col = FC(wlast,1) & 1; col < width; col+=2)
+	  window[2][col] = BAYER(wlast,col);
+      }
+      thold = threshold/512;
+      for (col = (FC(row,0) & 1)+1; col < width-1; col+=2) {
+	avg = ( window[0][col-1] + window[0][col+1] +
+		window[2][col-1] + window[2][col+1] - blk[~row & 1]*4 )
+	      * mul[row & 1] + (window[1][col] + blk[row & 1]) * 0.5;
+	avg = avg < 0 ? 0 : sqrt(avg);
+	diff = sqrt((double)BAYER(row,col)) - avg;
 	if      (diff < -thold) diff += thold;
 	else if (diff >  thold) diff -= thold;
 	else diff = 0;
@@ -3797,6 +5342,54 @@ void CLASS wavelet_denoise()
   free (fimg);
 }
 
+#endif
+
+// green equilibration
+void CLASS green_matching()
+{
+  int i,j;
+  double m1,m2,c1,c2;
+  int o1_1,o1_2,o1_3,o1_4;
+  int o2_1,o2_2,o2_3,o2_4;
+  ushort (*img)[4];
+  const int margin = 3;
+  int oj = 2, oi = 2;
+  float f;
+  const float thr = 0.01f;
+  if(half_size || shrink) return;
+  if(FC(oj, oi) != 3) oj++;
+  if(FC(oj, oi) != 3) oi++;
+  if(FC(oj, oi) != 3) oj--;
+
+  img = (ushort (*)[4]) calloc (height*width, sizeof *image);
+  merror (img, "green_matching()");
+  memcpy(img,image,height*width*sizeof *image);
+
+  for(j=oj;j<height-margin;j+=2)
+    for(i=oi;i<width-margin;i+=2){
+      o1_1=img[(j-1)*width+i-1][1];
+      o1_2=img[(j-1)*width+i+1][1];
+      o1_3=img[(j+1)*width+i-1][1];
+      o1_4=img[(j+1)*width+i+1][1];
+      o2_1=img[(j-2)*width+i][3];
+      o2_2=img[(j+2)*width+i][3];
+      o2_3=img[j*width+i-2][3];
+      o2_4=img[j*width+i+2][3];
+
+      m1=(o1_1+o1_2+o1_3+o1_4)/4.0;
+      m2=(o2_1+o2_2+o2_3+o2_4)/4.0;
+
+      c1=(abs(o1_1-o1_2)+abs(o1_1-o1_3)+abs(o1_1-o1_4)+abs(o1_2-o1_3)+abs(o1_3-o1_4)+abs(o1_2-o1_4))/6.0;
+      c2=(abs(o2_1-o2_2)+abs(o2_1-o2_3)+abs(o2_1-o2_4)+abs(o2_2-o2_3)+abs(o2_3-o2_4)+abs(o2_2-o2_4))/6.0;
+      if((img[j*width+i][3]<maximum*0.95)&&(c1<maximum*thr)&&(c2<maximum*thr))
+      {
+        f = image[j*width+i][3]*m1/m2;
+        image[j*width+i][3]=f>0xffff?0xffff:f;
+      }
+    }
+  free(img);
+}
+
 void CLASS scale_colors()
 {
   unsigned bottom, right, size, row, col, ur, uc, i, x, y, c, sum[8];
@@ -3805,6 +5398,10 @@ void CLASS scale_colors()
   float scale_mul[4], fr, fc;
   ushort *img=0, *pix;
 
+#ifdef LIBRAW_LIBRARY_BUILD
+  RUN_CALLBACK(LIBRAW_PROGRESS_SCALE_COLORS,0,2);
+#endif
+
   if (user_mul[0])
     memcpy (pre_mul, user_mul, sizeof pre_mul);
   if (use_auto_wb || (use_camera_wb && cam_mul[0] == -1)) {
@@ -3842,13 +5439,39 @@ skip_block: ;
 	  sum[c] += val;
 	sum[c+4]++;
       }
+#ifdef LIBRAW_LIBRARY_BUILD
+    if(load_raw == &LibRaw::nikon_load_sraw)
+      {
+        // Nikon sRAW: camera WB already applied:
+        pre_mul[0]=pre_mul[1]=pre_mul[2]=pre_mul[3]=1.0;
+      }
+    else
+#endif
     if (sum[0] && sum[1] && sum[2] && sum[3])
       FORC4 pre_mul[c] = (float) sum[c+4] / sum[c];
     else if (cam_mul[0] && cam_mul[2])
       memcpy (pre_mul, cam_mul, sizeof pre_mul);
     else
-      fprintf (stderr,_("%s: Cannot use camera white balance.\n"), ifname);
+      {
+#ifdef LIBRAW_LIBRARY_BUILD
+            imgdata.process_warnings |= LIBRAW_WARN_BAD_CAMERA_WB;
+#endif
+#ifdef DCRAW_VERBOSE
+            fprintf (stderr,_("%s: Cannot use camera white balance.\n"), ifname);
+#endif
+      }
   }
+#ifdef LIBRAW_LIBRARY_BUILD
+  // Nikon sRAW, daylight
+  if (load_raw == &LibRaw::nikon_load_sraw
+      && !use_camera_wb && !use_auto_wb
+      && cam_mul[0] > 0.001f && cam_mul[1] > 0.001f && cam_mul[2] > 0.001f )
+    {
+      for(c=0;c<3;c++)
+        pre_mul[c]/=cam_mul[c];
+  }
+#endif
+  if (pre_mul[1] == 0) pre_mul[1] = 1;
   if (pre_mul[3] == 0) pre_mul[3] = colors < 4 ? pre_mul[1] : 1;
   dark = black;
   sat = maximum;
@@ -3862,23 +5485,38 @@ skip_block: ;
   }
   if (!highlight) dmax = dmin;
   FORC4 scale_mul[c] = (pre_mul[c] /= dmax) * 65535.0 / maximum;
+#ifdef DCRAW_VERBOSE
   if (verbose) {
     fprintf (stderr,
       _("Scaling with darkness %d, saturation %d, and\nmultipliers"), dark, sat);
     FORC4 fprintf (stderr, " %f", pre_mul[c]);
     fputc ('\n', stderr);
   }
+#endif
+  if (filters > 1000 && (cblack[4]+1)/2 == 1 && (cblack[5]+1)/2 == 1) {
+    FORC4 cblack[FC(c/2,c%2)] +=
+	cblack[6 + c/2 % cblack[4] * cblack[5] + c%2 % cblack[5]];
+    cblack[4] = cblack[5] = 0;
+  }
   size = iheight*iwidth;
+#ifdef LIBRAW_LIBRARY_BUILD
+  scale_colors_loop(scale_mul);
+#else
   for (i=0; i < size*4; i++) {
-    val = image[0][i];
-    if (!val) continue;
+    if (!(val = image[0][i])) continue;
+    if (cblack[4] && cblack[5])
+      val -= cblack[6 + i/4 / iwidth % cblack[4] * cblack[5] +
+			i/4 % iwidth % cblack[5]];
     val -= cblack[i & 3];
     val *= scale_mul[i & 3];
     image[0][i] = CLIP(val);
   }
+#endif
   if ((aber[0] != 1 || aber[2] != 1) && colors == 3) {
+#ifdef DCRAW_VERBOSE
     if (verbose)
       fprintf (stderr,_("Correcting chromatic aberration...\n"));
+#endif
     for (c=0; c < 4; c+=2) {
       if (aber[c] == 1) continue;
       img = (ushort *) malloc (size * sizeof *img);
@@ -3902,19 +5540,36 @@ skip_block: ;
       free(img);
     }
   }
+#ifdef LIBRAW_LIBRARY_BUILD
+  RUN_CALLBACK(LIBRAW_PROGRESS_SCALE_COLORS,1,2);
+#endif
 }
 
 void CLASS pre_interpolate()
 {
   ushort (*img)[4];
   int row, col, c;
-
+#ifdef LIBRAW_LIBRARY_BUILD
+  RUN_CALLBACK(LIBRAW_PROGRESS_PRE_INTERPOLATE,0,2);
+#endif
   if (shrink) {
     if (half_size) {
       height = iheight;
       width  = iwidth;
+      if (filters == 9) {
+	for (row=0; row < 3; row++)
+	  for (col=1; col < 4; col++)
+	    if (!(image[row*width+col][0] | image[row*width+col][2]))
+	      goto break2;  break2:
+	for ( ; row < height; row+=3)
+	  for (col=(col-1)%3+1; col < width-1; col+=3) {
+	    img = image + row*width+col;
+	    for (c=0; c < 3; c+=2)
+	      img[0][c] = (img[-1][c] + img[1][c]) >> 1;
+	  }
+      }
     } else {
-      img = (ushort (*)[4]) calloc (height*width, sizeof *img);
+      img = (ushort (*)[4]) calloc (height, width*sizeof *img);
       merror (img, "pre_interpolate()");
       for (row=0; row < height; row++)
 	for (col=0; col < width; col++) {
@@ -3927,8 +5582,8 @@ void CLASS pre_interpolate()
     }
   }
   if (filters > 1000 && colors == 3) {
-    if (four_color_rgb && colors++)
-      mix_green = !half_size;
+    mix_green = four_color_rgb ^ half_size;
+    if (four_color_rgb | half_size) colors++;
     else {
       for (row = FC(1,0) >> 1; row < height; row+=2)
 	for (col = FC(row,1) & 1; col < width; col+=2)
@@ -3937,6 +5592,9 @@ void CLASS pre_interpolate()
     }
   }
   if (half_size) filters = 0;
+#ifdef LIBRAW_LIBRARY_BUILD
+  RUN_CALLBACK(LIBRAW_PROGRESS_PRE_INTERPOLATE,1,2);
+#endif
 }
 
 void CLASS border_interpolate (int border)
@@ -3961,14 +5619,41 @@ void CLASS border_interpolate (int border)
     }
 }
 
+void CLASS lin_interpolate_loop(int code[16][16][32],int size)
+{
+  int row;
+  for (row=1; row < height-1; row++)
+    {
+      int col,*ip;
+      ushort *pix;
+      for (col=1; col < width-1; col++) {
+        int i;
+        int sum[4];
+        pix = image[row*width+col];
+        ip = code[row % size][col % size];
+        memset (sum, 0, sizeof sum);
+        for (i=*ip++; i--; ip+=3)
+          sum[ip[2]] += pix[ip[0]] << ip[1];
+        for (i=colors; --i; ip+=2)
+          pix[ip[0]] = sum[ip[0]] * ip[1] >> 8;
+      }
+    }
+}
+
 void CLASS lin_interpolate()
 {
   int code[16][16][32], size=16, *ip, sum[4];
-  int f, c, i, x, y, row, col, shift, color;
-  ushort *pix;
+  int f, c, x, y, row, col, shift, color;
 
+
+#ifdef DCRAW_VERBOSE
   if (verbose) fprintf (stderr,_("Bilinear interpolation...\n"));
-  if (filters == 2) size = 6;
+#endif
+#ifdef LIBRAW_LIBRARY_BUILD
+  RUN_CALLBACK(LIBRAW_PROGRESS_INTERPOLATE,0,3);
+#endif
+
+  if (filters == 9) size = 6;
   border_interpolate(1);
   for (row=0; row < size; row++)
     for (col=0; col < size; col++) {
@@ -3989,19 +5674,16 @@ void CLASS lin_interpolate()
       FORCC
 	if (c != f) {
 	  *ip++ = c;
-	  *ip++ = 256 / sum[c];
+	  *ip++ = sum[c]>0?256 / sum[c]:0;
 	}
     }
-  for (row=1; row < height-1; row++)
-    for (col=1; col < width-1; col++) {
-      pix = image[row*width+col];
-      ip = code[row % size][col % size];
-      memset (sum, 0, sizeof sum);
-      for (i=*ip++; i--; ip+=3)
-	sum[ip[2]] += pix[ip[0]] << ip[1];
-      for (i=colors; --i; ip+=2)
-	pix[ip[0]] = sum[ip[0]] * ip[1] >> 8;
-    }
+#ifdef LIBRAW_LIBRARY_BUILD
+  RUN_CALLBACK(LIBRAW_PROGRESS_INTERPOLATE,1,3);
+#endif
+  lin_interpolate_loop(code,size);
+#ifdef LIBRAW_LIBRARY_BUILD
+  RUN_CALLBACK(LIBRAW_PROGRESS_INTERPOLATE,2,3);
+#endif
 }
 
 /*
@@ -4046,10 +5728,12 @@ void CLASS vng_interpolate()
   int g, diff, thold, num, c;
 
   lin_interpolate();
+#ifdef DCRAW_VERBOSE
   if (verbose) fprintf (stderr,_("VNG interpolation...\n"));
+#endif
 
   if (filters == 1) prow = pcol = 16;
-  if (filters == 2) prow = pcol =  6;
+  if (filters == 9) prow = pcol =  6;
   ip = (int *) calloc (prow*pcol, 1280);
   merror (ip, "vng_interpolate()");
   for (row=0; row < prow; row++)		/* Precalculate for VNG */
@@ -4087,6 +5771,9 @@ void CLASS vng_interpolate()
   for (row=0; row < 3; row++)
     brow[row] = brow[4] + row*width;
   for (row=2; row < height-2; row++) {		/* Do VNG interpolation */
+#ifdef LIBRAW_LIBRARY_BUILD
+      if(!((row-2)%256))RUN_CALLBACK(LIBRAW_PROGRESS_INTERPOLATE,(row-2)/256+1,((height-3)/256)+1);
+#endif
     for (col=2; col < width-2; col++) {
       pix = image[row*width+col];
       ip = code[row % prow][col % pcol];
@@ -4151,9 +5838,17 @@ void CLASS ppg_interpolate()
   ushort (*pix)[4];
 
   border_interpolate(3);
+#ifdef DCRAW_VERBOSE
   if (verbose) fprintf (stderr,_("PPG interpolation...\n"));
+#endif
 
 /*  Fill in the green layer with gradients and pattern recognition: */
+#ifdef LIBRAW_LIBRARY_BUILD
+  RUN_CALLBACK(LIBRAW_PROGRESS_INTERPOLATE,0,3);
+#ifdef LIBRAW_USE_OPENMP
+#pragma omp parallel for default(shared) private(guess, diff, row, col, d, c, i, pix) schedule(static)
+#endif
+#endif
   for (row=3; row < height-3; row++)
     for (col=3+(FC(row,3) & 1), c=FC(row,col); col < width-3; col+=2) {
       pix = image + row*width+col;
@@ -4170,6 +5865,12 @@ void CLASS ppg_interpolate()
       pix[0][1] = ULIM(guess[i] >> 2, pix[d][1], pix[-d][1]);
     }
 /*  Calculate red and blue for each green pixel:		*/
+#ifdef LIBRAW_LIBRARY_BUILD
+  RUN_CALLBACK(LIBRAW_PROGRESS_INTERPOLATE,1,3);
+#ifdef LIBRAW_USE_OPENMP
+#pragma omp parallel for default(shared) private(guess, diff, row, col, d, c, i, pix) schedule(static)
+#endif
+#endif
   for (row=1; row < height-1; row++)
     for (col=1+(FC(row,2) & 1), c=FC(row,col+1); col < width-1; col+=2) {
       pix = image + row*width+col;
@@ -4178,6 +5879,12 @@ void CLASS ppg_interpolate()
 			- pix[-d][1] - pix[d][1]) >> 1);
     }
 /*  Calculate blue for red pixels and vice versa:		*/
+#ifdef LIBRAW_LIBRARY_BUILD
+  RUN_CALLBACK(LIBRAW_PROGRESS_INTERPOLATE,2,3);
+#ifdef LIBRAW_USE_OPENMP
+#pragma omp parallel for default(shared) private(guess, diff, row, col, d, c, i, pix) schedule(static)
+#endif
+#endif
   for (row=1; row < height-1; row++)
     for (col=1+(FC(row,1) & 1), c=2-FC(row,col); col < width-1; col+=2) {
       pix = image + row*width+col;
@@ -4195,91 +5902,590 @@ void CLASS ppg_interpolate()
     }
 }
 
+void CLASS cielab (ushort rgb[3], short lab[3])
+{
+  int c, i, j, k;
+  float r, xyz[3];
+#ifdef LIBRAW_NOTHREADS
+  static float cbrt[0x10000], xyz_cam[3][4];
+#else
+#define cbrt tls->ahd_data.cbrt
+#define xyz_cam tls->ahd_data.xyz_cam
+#endif
+
+  if (!rgb) {
+#ifndef LIBRAW_NOTHREADS
+    if(cbrt[0] < -1.0f)
+#endif
+    for (i=0; i < 0x10000; i++) {
+      r = i / 65535.0;
+      cbrt[i] = r > 0.008856 ? pow(r,1.f/3.0f) : 7.787f*r + 16.f/116.0f;
+    }
+    for (i=0; i < 3; i++)
+      for (j=0; j < colors; j++)
+	for (xyz_cam[i][j] = k=0; k < 3; k++)
+	  xyz_cam[i][j] += xyz_rgb[i][k] * rgb_cam[k][j] / d65_white[i];
+    return;
+  }
+  xyz[0] = xyz[1] = xyz[2] = 0.5;
+  FORCC {
+    xyz[0] += xyz_cam[0][c] * rgb[c];
+    xyz[1] += xyz_cam[1][c] * rgb[c];
+    xyz[2] += xyz_cam[2][c] * rgb[c];
+  }
+  xyz[0] = cbrt[CLIP((int) xyz[0])];
+  xyz[1] = cbrt[CLIP((int) xyz[1])];
+  xyz[2] = cbrt[CLIP((int) xyz[2])];
+  lab[0] = 64 * (116 * xyz[1] - 16);
+  lab[1] = 64 * 500 * (xyz[0] - xyz[1]);
+  lab[2] = 64 * 200 * (xyz[1] - xyz[2]);
+#ifndef LIBRAW_NOTHREADS
+#undef cbrt
+#undef xyz_cam
+#endif
+}
+
+#define TS 512		/* Tile Size */
+#define fcol(row,col) xtrans[(row+6) % 6][(col+6) % 6]
+
 /*
-   Adaptive Homogeneity-Directed interpolation is based on
-   the work of Keigo Hirakawa, Thomas Parks, and Paul Lee.
+   Frank Markesteijn's algorithm for Fuji X-Trans sensors
  */
-#define TS 256		/* Tile Size */
-
-void CLASS ahd_interpolate()
-{
-  int i, j, k, top, left, row, col, tr, tc, c, d, val, hm[2];
-  ushort (*pix)[4], (*rix)[3];
-  static const int dir[4] = { -1, 1, -TS, TS };
-  unsigned ldiff[2][4], abdiff[2][4], leps, abeps;
-  float r, cbrt[0x10000], xyz[3], xyz_cam[3][4];
-  ushort (*rgb)[TS][TS][3];
-   short (*lab)[TS][TS][3], (*lix)[3];
+void CLASS xtrans_interpolate (int passes)
+{
+  int c, d, f, g, h, i, v, ng, row, col, top, left, mrow, mcol;
+  int val, ndir, pass, hm[8], avg[4], color[3][8];
+  static const short orth[12] = { 1,0,0,1,-1,0,0,-1,1,0,0,1 },
+	patt[2][16] = { { 0,1,0,-1,2,0,-1,0,1,1,1,-1,0,0,0,0 },
+			{ 0,1,0,-2,1,0,-2,0,1,1,-2,-2,1,-1,-1,1 } },
+	dir[4] = { 1,TS,TS+1,TS-1 };
+  short allhex[3][3][2][8], *hex;
+  ushort min, max, sgrow, sgcol;
+  ushort (*rgb)[TS][TS][3], (*rix)[3], (*pix)[4];
+   short (*lab)    [TS][3], (*lix)[3];
+   float (*drv)[TS][TS], diff[6], tr;
    char (*homo)[TS][TS], *buffer;
 
-  if (verbose) fprintf (stderr,_("AHD interpolation...\n"));
-
-  for (i=0; i < 0x10000; i++) {
-    r = i / 65535.0;
-    cbrt[i] = r > 0.008856 ? pow(r,1/3.0) : 7.787*r + 16/116.0;
-  }
-  for (i=0; i < 3; i++)
-    for (j=0; j < colors; j++)
-      for (xyz_cam[i][j] = k=0; k < 3; k++)
-	xyz_cam[i][j] += xyz_rgb[i][k] * rgb_cam[k][j] / d65_white[i];
+#ifdef DCRAW_VERBOSE
+  if (verbose)
+    fprintf (stderr,_("%d-pass X-Trans interpolation...\n"), passes);
+#endif
 
-  border_interpolate(5);
-  buffer = (char *) malloc (26*TS*TS);		/* 1664 kB */
-  merror (buffer, "ahd_interpolate()");
+  cielab (0,0);
+  ndir = 4 << (passes > 1);
+  buffer = (char *) malloc (TS*TS*(ndir*11+6));
+  merror (buffer, "xtrans_interpolate()");
   rgb  = (ushort(*)[TS][TS][3]) buffer;
-  lab  = (short (*)[TS][TS][3])(buffer + 12*TS*TS);
-  homo = (char  (*)[TS][TS])   (buffer + 24*TS*TS);
+  lab  = (short (*)    [TS][3])(buffer + TS*TS*(ndir*6));
+  drv  = (float (*)[TS][TS])   (buffer + TS*TS*(ndir*6+6));
+  homo = (char  (*)[TS][TS])   (buffer + TS*TS*(ndir*10+6));
 
-  for (top=2; top < height-5; top += TS-6)
-    for (left=2; left < width-5; left += TS-6) {
-
-/*  Interpolate green horizontally and vertically:		*/
-      for (row = top; row < top+TS && row < height-2; row++) {
-	col = left + (FC(row,left) & 1);
-	for (c = FC(row,col); col < left+TS && col < width-2; col+=2) {
-	  pix = image + row*width+col;
-	  val = ((pix[-1][1] + pix[0][c] + pix[1][1]) * 2
-		- pix[-2][c] - pix[2][c]) >> 2;
-	  rgb[0][row-top][col-left][1] = ULIM(val,pix[-1][1],pix[1][1]);
-	  val = ((pix[-width][1] + pix[0][c] + pix[width][1]) * 2
-		- pix[-2*width][c] - pix[2*width][c]) >> 2;
-	  rgb[1][row-top][col-left][1] = ULIM(val,pix[-width][1],pix[width][1]);
+/* Map a green hexagon around each non-green pixel and vice versa:	*/
+  for (row=0; row < 3; row++)
+    for (col=0; col < 3; col++)
+      for (ng=d=0; d < 10; d+=2) {
+	g = fcol(row,col) == 1;
+	if (fcol(row+orth[d],col+orth[d+2]) == 1) ng=0; else ng++;
+	if (ng == 4) { sgrow = row; sgcol = col; }
+	if (ng == g+1) FORC(8) {
+	  v = orth[d  ]*patt[g][c*2] + orth[d+1]*patt[g][c*2+1];
+	  h = orth[d+2]*patt[g][c*2] + orth[d+3]*patt[g][c*2+1];
+	  allhex[row][col][0][c^(g*2 & d)] = h + v*width;
+	  allhex[row][col][1][c^(g*2 & d)] = h + v*TS;
 	}
       }
-/*  Interpolate red and blue, and convert to CIELab:		*/
-      for (d=0; d < 2; d++)
-	for (row=top+1; row < top+TS-1 && row < height-3; row++)
-	  for (col=left+1; col < left+TS-1 && col < width-3; col++) {
-	    pix = image + row*width+col;
-	    rix = &rgb[d][row-top][col-left];
-	    lix = &lab[d][row-top][col-left];
-	    if ((c = 2 - FC(row,col)) == 1) {
-	      c = FC(row+1,col);
-	      val = pix[0][1] + (( pix[-1][2-c] + pix[1][2-c]
-				 - rix[-1][1] - rix[1][1] ) >> 1);
-	      rix[0][2-c] = CLIP(val);
-	      val = pix[0][1] + (( pix[-width][c] + pix[width][c]
-				 - rix[-TS][1] - rix[TS][1] ) >> 1);
-	    } else
-	      val = rix[0][1] + (( pix[-width-1][c] + pix[-width+1][c]
-				 + pix[+width-1][c] + pix[+width+1][c]
-				 - rix[-TS-1][1] - rix[-TS+1][1]
-				 - rix[+TS-1][1] - rix[+TS+1][1] + 1) >> 2);
-	    rix[0][c] = CLIP(val);
-	    c = FC(row,col);
-	    rix[0][c] = pix[0][c];
-	    xyz[0] = xyz[1] = xyz[2] = 0.5;
-	    FORCC {
-	      xyz[0] += xyz_cam[0][c] * rix[0][c];
-	      xyz[1] += xyz_cam[1][c] * rix[0][c];
-	      xyz[2] += xyz_cam[2][c] * rix[0][c];
+
+/* Set green1 and green3 to the minimum and maximum allowed values:	*/
+  for (row=2; row < height-2; row++)
+    for (min=~(max=0), col=2; col < width-2; col++) {
+      if (fcol(row,col) == 1 && (min=~(max=0))) continue;
+      pix = image + row*width + col;
+      hex = allhex[row % 3][col % 3][0];
+      if (!max) FORC(6) {
+	val = pix[hex[c]][1];
+	if (min > val) min = val;
+	if (max < val) max = val;
+      }
+      pix[0][1] = min;
+      pix[0][3] = max;
+      switch ((row-sgrow) % 3) {
+	case 1: if (row < height-3) { row++; col--; } break;
+	case 2: if ((min=~(max=0)) && (col+=2) < width-3 && row > 2) row--;
+      }
+    }
+
+  for (top=3; top < height-19; top += TS-16)
+    for (left=3; left < width-19; left += TS-16) {
+      mrow = MIN (top+TS, height-3);
+      mcol = MIN (left+TS, width-3);
+      for (row=top; row < mrow; row++)
+	for (col=left; col < mcol; col++)
+	  memcpy (rgb[0][row-top][col-left], image[row*width+col], 6);
+      FORC3 memcpy (rgb[c+1], rgb[0], sizeof *rgb);
+
+/* Interpolate green horizontally, vertically, and along both diagonals: */
+      for (row=top; row < mrow; row++)
+	for (col=left; col < mcol; col++) {
+	  if ((f = fcol(row,col)) == 1) continue;
+	  pix = image + row*width + col;
+	  hex = allhex[row % 3][col % 3][0];
+	  color[1][0] = 174 * (pix[  hex[1]][1] + pix[  hex[0]][1]) -
+			 46 * (pix[2*hex[1]][1] + pix[2*hex[0]][1]);
+	  color[1][1] = 223 *  pix[  hex[3]][1] + pix[  hex[2]][1] * 33 +
+			 92 * (pix[      0 ][f] - pix[ -hex[2]][f]);
+	  FORC(2) color[1][2+c] =
+		164 * pix[hex[4+c]][1] + 92 * pix[-2*hex[4+c]][1] + 33 *
+		(2*pix[0][f] - pix[3*hex[4+c]][f] - pix[-3*hex[4+c]][f]);
+	  FORC4 rgb[c^!((row-sgrow) % 3)][row-top][col-left][1] =
+		LIM(color[1][c] >> 8,pix[0][1],pix[0][3]);
+	}
+
+      for (pass=0; pass < passes; pass++) {
+	if (pass == 1)
+	  memcpy (rgb+=4, buffer, 4*sizeof *rgb);
+
+/* Recalculate green from interpolated values of closer pixels:	*/
+	if (pass) {
+	  for (row=top+2; row < mrow-2; row++)
+	    for (col=left+2; col < mcol-2; col++) {
+	      if ((f = fcol(row,col)) == 1) continue;
+	      pix = image + row*width + col;
+	      hex = allhex[row % 3][col % 3][1];
+	      for (d=3; d < 6; d++) {
+		rix = &rgb[(d-2)^!((row-sgrow) % 3)][row-top][col-left];
+		val = rix[-2*hex[d]][1] + 2*rix[hex[d]][1]
+		    - rix[-2*hex[d]][f] - 2*rix[hex[d]][f] + 3*rix[0][f];
+		rix[0][1] = LIM(val/3,pix[0][1],pix[0][3]);
+	      }
 	    }
-	    xyz[0] = cbrt[CLIP((int) xyz[0])];
-	    xyz[1] = cbrt[CLIP((int) xyz[1])];
-	    xyz[2] = cbrt[CLIP((int) xyz[2])];
-	    lix[0][0] = 64 * (116 * xyz[1] - 16);
-	    lix[0][1] = 64 * 500 * (xyz[0] - xyz[1]);
-	    lix[0][2] = 64 * 200 * (xyz[1] - xyz[2]);
+	}
+
+/* Interpolate red and blue values for solitary green pixels:	*/
+	for (row=(top-sgrow+4)/3*3+sgrow; row < mrow-2; row+=3)
+	  for (col=(left-sgcol+4)/3*3+sgcol; col < mcol-2; col+=3) {
+	    rix = &rgb[0][row-top][col-left];
+	    h = fcol(row,col+1);
+	    memset (diff, 0, sizeof diff);
+	    for (i=1, d=0; d < 6; d++, i^=TS^1, h^=2) {
+	      for (c=0; c < 2; c++, h^=2) {
+		g = 2*rix[0][1] - rix[i<<c][1] - rix[-i<<c][1];
+		color[h][d] = g + rix[i<<c][h] + rix[-i<<c][h];
+		if (d > 1)
+		  diff[d] += SQR (rix[i<<c][1] - rix[-i<<c][1]
+				- rix[i<<c][h] + rix[-i<<c][h]) + SQR(g);
+	      }
+	      if (d > 1 && (d & 1))
+		if (diff[d-1] < diff[d])
+		  FORC(2) color[c*2][d] = color[c*2][d-1];
+	      if (d < 2 || (d & 1)) {
+		FORC(2) rix[0][c*2] = CLIP(color[c*2][d]/2);
+		rix += TS*TS;
+	      }
+	    }
+	  }
+
+/* Interpolate red for blue pixels and vice versa:		*/
+	for (row=top+3; row < mrow-3; row++)
+	  for (col=left+3; col < mcol-3; col++) {
+	    if ((f = 2-fcol(row,col)) == 1) continue;
+	    rix = &rgb[0][row-top][col-left];
+	    c = (row-sgrow) % 3 ? TS:1;
+	    h = 3 * (c ^ TS ^ 1);
+	    for (d=0; d < 4; d++, rix += TS*TS) {
+	      i = d > 1 || ((d ^ c) & 1) ||
+		 ((ABS(rix[0][1]-rix[c][1])+ABS(rix[0][1]-rix[-c][1])) <
+		2*(ABS(rix[0][1]-rix[h][1])+ABS(rix[0][1]-rix[-h][1]))) ? c:h;
+	      rix[0][f] = CLIP((rix[i][f] + rix[-i][f] +
+		  2*rix[0][1] - rix[i][1] - rix[-i][1])/2);
+	    }
+	  }
+
+/* Fill in red and blue for 2x2 blocks of green:		*/
+	for (row=top+2; row < mrow-2; row++) if ((row-sgrow) % 3)
+	  for (col=left+2; col < mcol-2; col++) if ((col-sgcol) % 3) {
+	    rix = &rgb[0][row-top][col-left];
+	    hex = allhex[row % 3][col % 3][1];
+	    for (d=0; d < ndir; d+=2, rix += TS*TS)
+	      if (hex[d] + hex[d+1]) {
+		g = 3*rix[0][1] - 2*rix[hex[d]][1] - rix[hex[d+1]][1];
+		for (c=0; c < 4; c+=2) rix[0][c] =
+			CLIP((g + 2*rix[hex[d]][c] + rix[hex[d+1]][c])/3);
+	      } else {
+		g = 2*rix[0][1] - rix[hex[d]][1] - rix[hex[d+1]][1];
+		for (c=0; c < 4; c+=2) rix[0][c] =
+			CLIP((g + rix[hex[d]][c] + rix[hex[d+1]][c])/2);
+	      }
+	  }
+      }
+      rgb = (ushort(*)[TS][TS][3]) buffer;
+      mrow -= top;
+      mcol -= left;
+
+/* Convert to CIELab and differentiate in all directions:	*/
+      for (d=0; d < ndir; d++) {
+	for (row=2; row < mrow-2; row++)
+	  for (col=2; col < mcol-2; col++)
+	    cielab (rgb[d][row][col], lab[row][col]);
+	for (f=dir[d & 3],row=3; row < mrow-3; row++)
+	  for (col=3; col < mcol-3; col++) {
+	    lix = &lab[row][col];
+	    g = 2*lix[0][0] - lix[f][0] - lix[-f][0];
+	    drv[d][row][col] = SQR(g)
+	      + SQR((2*lix[0][1] - lix[f][1] - lix[-f][1] + g*500/232))
+	      + SQR((2*lix[0][2] - lix[f][2] - lix[-f][2] - g*500/580));
+	  }
+      }
+
+/* Build homogeneity maps from the derivatives:			*/
+      memset(homo, 0, ndir*TS*TS);
+      for (row=4; row < mrow-4; row++)
+	for (col=4; col < mcol-4; col++) {
+	  for (tr=FLT_MAX, d=0; d < ndir; d++)
+	    if (tr > drv[d][row][col])
+		tr = drv[d][row][col];
+	  tr *= 8;
+	  for (d=0; d < ndir; d++)
+	    for (v=-1; v <= 1; v++)
+	      for (h=-1; h <= 1; h++)
+		if (drv[d][row+v][col+h] <= tr)
+		  homo[d][row][col]++;
+	}
+
+/* Average the most homogenous pixels for the final result:	*/
+      if (height-top < TS+4) mrow = height-top+2;
+      if (width-left < TS+4) mcol = width-left+2;
+      for (row = MIN(top,8); row < mrow-8; row++)
+	for (col = MIN(left,8); col < mcol-8; col++) {
+	  for (d=0; d < ndir; d++)
+	    for (hm[d]=0, v=-2; v <= 2; v++)
+	      for (h=-2; h <= 2; h++)
+		hm[d] += homo[d][row+v][col+h];
+	  for (d=0; d < ndir-4; d++)
+	    if (hm[d] < hm[d+4]) hm[d  ] = 0; else
+	    if (hm[d] > hm[d+4]) hm[d+4] = 0;
+	  for (max=hm[0],d=1; d < ndir; d++)
+	    if (max < hm[d]) max = hm[d];
+	  max -= max >> 3;
+	  memset (avg, 0, sizeof avg);
+	  for (d=0; d < ndir; d++)
+	    if (hm[d] >= max) {
+	      FORC3 avg[c] += rgb[d][row][col][c];
+	      avg[3]++;
+	    }
+	  FORC3 image[(row+top)*width+col+left][c] = avg[c]/avg[3];
+	}
+    }
+  free(buffer);
+  border_interpolate(8);
+}
+#undef fcol
+
+/*
+   Adaptive Homogeneity-Directed interpolation is based on
+   the work of Keigo Hirakawa, Thomas Parks, and Paul Lee.
+ */
+#ifdef LIBRAW_LIBRARY_BUILD
+
+void CLASS ahd_interpolate_green_h_and_v(int top, int left, ushort (*out_rgb)[TS][TS][3])
+{
+  int row, col;
+  int c, val;
+  ushort (*pix)[4];
+  const int rowlimit = MIN(top+TS, height-2);
+  const int collimit = MIN(left+TS, width-2);
+
+  for (row = top; row < rowlimit; row++) {
+    col = left + (FC(row,left) & 1);
+    for (c = FC(row,col); col < collimit; col+=2) {
+      pix = image + row*width+col;
+      val = ((pix[-1][1] + pix[0][c] + pix[1][1]) * 2
+            - pix[-2][c] - pix[2][c]) >> 2;
+      out_rgb[0][row-top][col-left][1] = ULIM(val,pix[-1][1],pix[1][1]);
+      val = ((pix[-width][1] + pix[0][c] + pix[width][1]) * 2
+            - pix[-2*width][c] - pix[2*width][c]) >> 2;
+      out_rgb[1][row-top][col-left][1] = ULIM(val,pix[-width][1],pix[width][1]);
+    }
+  }
+}
+void CLASS ahd_interpolate_r_and_b_in_rgb_and_convert_to_cielab(int top, int left, ushort (*inout_rgb)[TS][3], short (*out_lab)[TS][3])
+{
+  unsigned row, col;
+  int c, val;
+  ushort (*pix)[4];
+  ushort (*rix)[3];
+  short (*lix)[3];
+  float xyz[3];
+  const unsigned num_pix_per_row = 4*width;
+  const unsigned rowlimit = MIN(top+TS-1, height-3);
+  const unsigned collimit = MIN(left+TS-1, width-3);
+  ushort *pix_above;
+  ushort *pix_below;
+  int t1, t2;
+
+  for (row = top+1; row < rowlimit; row++) {
+    pix = image + row*width + left;
+    rix = &inout_rgb[row-top][0];
+    lix = &out_lab[row-top][0];
+
+    for (col = left+1; col < collimit; col++) {
+      pix++;
+      pix_above = &pix[0][0] - num_pix_per_row;
+      pix_below = &pix[0][0] + num_pix_per_row;
+      rix++;
+      lix++;
+
+      c = 2 - FC(row, col);
+
+      if (c == 1) {
+        c = FC(row+1,col);
+	t1 = 2-c;
+        val = pix[0][1] + (( pix[-1][t1] + pix[1][t1]
+              - rix[-1][1] - rix[1][1] ) >> 1);
+        rix[0][t1] = CLIP(val);
+        val = pix[0][1] + (( pix_above[c] + pix_below[c]
+              - rix[-TS][1] - rix[TS][1] ) >> 1);
+      } else {
+	t1 = -4+c; /* -4+c: pixel of color c to the left */
+	t2 = 4+c; /* 4+c: pixel of color c to the right */
+        val = rix[0][1] + (( pix_above[t1] + pix_above[t2]
+              + pix_below[t1] + pix_below[t2]
+              - rix[-TS-1][1] - rix[-TS+1][1]
+              - rix[+TS-1][1] - rix[+TS+1][1] + 1) >> 2);
+      }
+      rix[0][c] = CLIP(val);
+      c = FC(row,col);
+      rix[0][c] = pix[0][c];
+      cielab(rix[0],lix[0]);
+    }
+  }
+}
+void CLASS ahd_interpolate_r_and_b_and_convert_to_cielab(int top, int left, ushort (*inout_rgb)[TS][TS][3], short (*out_lab)[TS][TS][3])
+{
+  int direction;
+  for (direction = 0; direction < 2; direction++) {
+    ahd_interpolate_r_and_b_in_rgb_and_convert_to_cielab(top, left, inout_rgb[direction], out_lab[direction]);
+  }
+}
+
+void CLASS ahd_interpolate_build_homogeneity_map(int top, int left, short (*lab)[TS][TS][3], char (*out_homogeneity_map)[TS][2])
+{
+  int row, col;
+  int tr, tc;
+  int direction;
+  int i;
+  short (*lix)[3];
+  short (*lixs[2])[3];
+  short *adjacent_lix;
+  unsigned ldiff[2][4], abdiff[2][4], leps, abeps;
+  static const int dir[4] = { -1, 1, -TS, TS };
+  const int rowlimit = MIN(top+TS-2, height-4);
+  const int collimit = MIN(left+TS-2, width-4);
+  int homogeneity;
+  char (*homogeneity_map_p)[2];
+
+  memset (out_homogeneity_map, 0, 2*TS*TS);
+
+  for (row=top+2; row < rowlimit; row++) {
+    tr = row-top;
+    homogeneity_map_p = &out_homogeneity_map[tr][1];
+    for (direction=0; direction < 2; direction++) {
+      lixs[direction] = &lab[direction][tr][1];
+    }
+
+    for (col=left+2; col < collimit; col++) {
+      tc = col-left;
+      homogeneity_map_p++;
+
+      for (direction=0; direction < 2; direction++) {
+        lix = ++lixs[direction];
+        for (i=0; i < 4; i++) {
+	  adjacent_lix = lix[dir[i]];
+          ldiff[direction][i] = ABS(lix[0][0]-adjacent_lix[0]);
+          abdiff[direction][i] = SQR(lix[0][1]-adjacent_lix[1])
+            + SQR(lix[0][2]-adjacent_lix[2]);
+        }
+      }
+      leps = MIN(MAX(ldiff[0][0],ldiff[0][1]),
+          MAX(ldiff[1][2],ldiff[1][3]));
+      abeps = MIN(MAX(abdiff[0][0],abdiff[0][1]),
+          MAX(abdiff[1][2],abdiff[1][3]));
+      for (direction=0; direction < 2; direction++) {
+	homogeneity = 0;
+        for (i=0; i < 4; i++) {
+          if (ldiff[direction][i] <= leps && abdiff[direction][i] <= abeps) {
+	    homogeneity++;
+	  }
+	}
+	homogeneity_map_p[0][direction] = homogeneity;
+      }
+    }
+  }
+}
+void CLASS ahd_interpolate_combine_homogeneous_pixels(int top, int left, ushort (*rgb)[TS][TS][3], char (*homogeneity_map)[TS][2])
+{
+  int row, col;
+  int tr, tc;
+  int i, j;
+  int direction;
+  int hm[2];
+  int c;
+  const int rowlimit = MIN(top+TS-3, height-5);
+  const int collimit = MIN(left+TS-3, width-5);
+
+  ushort (*pix)[4];
+  ushort (*rix[2])[3];
+
+  for (row=top+3; row < rowlimit; row++) {
+    tr = row-top;
+    pix = &image[row*width+left+2];
+    for (direction = 0; direction < 2; direction++) {
+      rix[direction] = &rgb[direction][tr][2];
+    }
+
+    for (col=left+3; col < collimit; col++) {
+      tc = col-left;
+      pix++;
+      for (direction = 0; direction < 2; direction++) {
+        rix[direction]++;
+      }
+
+      for (direction=0; direction < 2; direction++) {
+        hm[direction] = 0;
+        for (i=tr-1; i <= tr+1; i++) {
+          for (j=tc-1; j <= tc+1; j++) {
+            hm[direction] += homogeneity_map[i][j][direction];
+          }
+        }
+      }
+      if (hm[0] != hm[1]) {
+        memcpy(pix[0], rix[hm[1] > hm[0]][0], 3 * sizeof(ushort));
+      } else {
+        FORC3 {
+          pix[0][c] = (rix[0][0][c] + rix[1][0][c]) >> 1;
+        }
+      }
+    }
+  }
+}
+void CLASS ahd_interpolate()
+{
+  int i, j, k, top, left;
+  float xyz_cam[3][4],r;
+  char *buffer;
+  ushort (*rgb)[TS][TS][3];
+  short (*lab)[TS][TS][3];
+  char (*homo)[TS][2];
+  int terminate_flag = 0;
+
+
+  cielab(0,0);
+  border_interpolate(5);
+
+#ifdef LIBRAW_LIBRARY_BUILD
+#ifdef LIBRAW_USE_OPENMP
+#pragma omp parallel private(buffer,rgb,lab,homo,top,left,i,j,k) shared(xyz_cam,terminate_flag)
+#endif
+#endif
+  {
+    buffer = (char *) malloc (26*TS*TS);		/* 1664 kB */
+    merror (buffer, "ahd_interpolate()");
+    rgb  = (ushort(*)[TS][TS][3]) buffer;
+    lab  = (short (*)[TS][TS][3])(buffer + 12*TS*TS);
+    homo = (char  (*)[TS][2])    (buffer + 24*TS*TS);
+
+#ifdef LIBRAW_LIBRARY_BUILD
+#ifdef LIBRAW_USE_OPENMP
+#pragma omp for schedule(dynamic)
+#endif
+#endif
+    for (top=2; top < height-5; top += TS-6){
+#ifdef LIBRAW_LIBRARY_BUILD
+#ifdef LIBRAW_USE_OPENMP
+        if(0== omp_get_thread_num())
+#endif
+           if(callbacks.progress_cb) {
+               int rr = (*callbacks.progress_cb)(callbacks.progresscb_data,LIBRAW_PROGRESS_INTERPOLATE,top-2,height-7);
+               if(rr)
+                   terminate_flag = 1;
+           }
+#endif
+        for (left=2; !terminate_flag && (left < width-5); left += TS-6) {
+            ahd_interpolate_green_h_and_v(top, left, rgb);
+            ahd_interpolate_r_and_b_and_convert_to_cielab(top, left, rgb, lab);
+            ahd_interpolate_build_homogeneity_map(top, left, lab, homo);
+            ahd_interpolate_combine_homogeneous_pixels(top, left, rgb, homo);
+      }
+    }
+    free (buffer);
+  }
+#ifdef LIBRAW_LIBRARY_BUILD
+  if(terminate_flag)
+      throw LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK;
+#endif
+}
+
+#else
+void CLASS ahd_interpolate()
+{
+  int i, j, top, left, row, col, tr, tc, c, d, val, hm[2];
+  static const int dir[4] = { -1, 1, -TS, TS };
+  unsigned ldiff[2][4], abdiff[2][4], leps, abeps;
+  ushort (*rgb)[TS][TS][3], (*rix)[3], (*pix)[4];
+   short (*lab)[TS][TS][3], (*lix)[3];
+   char (*homo)[TS][TS], *buffer;
+
+#ifdef DCRAW_VERBOSE
+  if (verbose) fprintf (stderr,_("AHD interpolation...\n"));
+#endif
+
+  cielab (0,0);
+  border_interpolate(5);
+  buffer = (char *) malloc (26*TS*TS);
+  merror (buffer, "ahd_interpolate()");
+  rgb  = (ushort(*)[TS][TS][3]) buffer;
+  lab  = (short (*)[TS][TS][3])(buffer + 12*TS*TS);
+  homo = (char  (*)[TS][TS])   (buffer + 24*TS*TS);
+
+  for (top=2; top < height-5; top += TS-6)
+    for (left=2; left < width-5; left += TS-6) {
+
+/*  Interpolate green horizontally and vertically:		*/
+      for (row=top; row < top+TS && row < height-2; row++) {
+	col = left + (FC(row,left) & 1);
+	for (c = FC(row,col); col < left+TS && col < width-2; col+=2) {
+	  pix = image + row*width+col;
+	  val = ((pix[-1][1] + pix[0][c] + pix[1][1]) * 2
+		- pix[-2][c] - pix[2][c]) >> 2;
+	  rgb[0][row-top][col-left][1] = ULIM(val,pix[-1][1],pix[1][1]);
+	  val = ((pix[-width][1] + pix[0][c] + pix[width][1]) * 2
+		- pix[-2*width][c] - pix[2*width][c]) >> 2;
+	  rgb[1][row-top][col-left][1] = ULIM(val,pix[-width][1],pix[width][1]);
+	}
+      }
+
+/*  Interpolate red and blue, and convert to CIELab:		*/
+      for (d=0; d < 2; d++)
+	for (row=top+1; row < top+TS-1 && row < height-3; row++)
+	  for (col=left+1; col < left+TS-1 && col < width-3; col++) {
+	    pix = image + row*width+col;
+	    rix = &rgb[d][row-top][col-left];
+	    lix = &lab[d][row-top][col-left];
+	    if ((c = 2 - FC(row,col)) == 1) {
+	      c = FC(row+1,col);
+	      val = pix[0][1] + (( pix[-1][2-c] + pix[1][2-c]
+				 - rix[-1][1] - rix[1][1] ) >> 1);
+	      rix[0][2-c] = CLIP(val);
+	      val = pix[0][1] + (( pix[-width][c] + pix[width][c]
+				 - rix[-TS][1] - rix[TS][1] ) >> 1);
+	    } else
+	      val = rix[0][1] + (( pix[-width-1][c] + pix[-width+1][c]
+				 + pix[+width-1][c] + pix[+width+1][c]
+				 - rix[-TS-1][1] - rix[-TS+1][1]
+				 - rix[+TS-1][1] - rix[+TS+1][1] + 1) >> 2);
+	    rix[0][c] = CLIP(val);
+	    c = FC(row,col);
+	    rix[0][c] = pix[0][c];
+	    cielab (rix[0],lix[0]);
 	  }
 /*  Build homogeneity maps from the CIELab images:		*/
       memset (homo, 0, 2*TS*TS);
@@ -4324,6 +6530,7 @@ void CLASS ahd_interpolate()
     }
   free (buffer);
 }
+#endif
 #undef TS
 
 void CLASS median_filter()
@@ -4335,8 +6542,13 @@ void CLASS median_filter()
     0,3, 5,8, 4,7, 3,6, 1,4, 2,5, 4,7, 4,2, 6,4, 4,2 };
 
   for (pass=1; pass <= med_passes; pass++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+      RUN_CALLBACK(LIBRAW_PROGRESS_MEDIAN_FILTER,pass-1,med_passes);
+#endif
+#ifdef DCRAW_VERBOSE
     if (verbose)
       fprintf (stderr,_("Median filter pass %d...\n"), pass);
+#endif
     for (c=0; c < 3; c+=2) {
       for (pix = image; pix < image+width*height; pix++)
 	pix[0][3] = pix[0][c];
@@ -4366,7 +6578,12 @@ void CLASS blend_highlights()
   float cam[2][4], lab[2][4], sum[2], chratio;
 
   if ((unsigned) (colors-3) > 1) return;
+#ifdef DCRAW_VERBOSE
   if (verbose) fprintf (stderr,_("Blending highlights...\n"));
+#endif
+#ifdef LIBRAW_LIBRARY_BUILD
+  RUN_CALLBACK(LIBRAW_PROGRESS_HIGHLIGHTS,0,2);
+#endif
   FORCC if (clip > (i = 65535*pre_mul[c])) clip = i;
   for (row=0; row < height; row++)
     for (col=0; col < width; col++) {
@@ -4389,6 +6606,9 @@ void CLASS blend_highlights()
 	cam[0][c] += itrans[colors-3][c][j] * lab[0][j];
       FORCC image[row*width+col][c] = cam[0][c] / colors;
     }
+#ifdef LIBRAW_LIBRARY_BUILD
+  RUN_CALLBACK(LIBRAW_PROGRESS_HIGHLIGHTS,1,2);
+#endif
 }
 
 #define SCALE (4 >> shrink)
@@ -4401,17 +6621,22 @@ void CLASS recover_highlights()
   static const signed char dir[8][2] =
     { {-1,-1}, {-1,0}, {-1,1}, {0,1}, {1,1}, {1,0}, {1,-1}, {0,-1} };
 
+#ifdef DCRAW_VERBOSE
   if (verbose) fprintf (stderr,_("Rebuilding highlights...\n"));
+#endif
 
-  grow = pow (2, 4-highlight);
+  grow = pow (2.0, 4-highlight);
   FORCC hsat[c] = 32000 * pre_mul[c];
   for (kc=0, c=1; c < colors; c++)
     if (pre_mul[kc] < pre_mul[c]) kc = c;
   high = height / SCALE;
   wide =  width / SCALE;
-  map = (float *) calloc (high*wide, sizeof *map);
+  map = (float *) calloc (high, wide*sizeof *map);
   merror (map, "recover_highlights()");
   FORCC if (c != kc) {
+#ifdef LIBRAW_LIBRARY_BUILD
+      RUN_CALLBACK(LIBRAW_PROGRESS_HIGHLIGHTS,c-1,colors-1);
+#endif
     memset (map, 0, high*wide*sizeof *map);
     for (mrow=0; mrow < high; mrow++)
       for (mcol=0; mcol < wide; mcol++) {
@@ -4476,7 +6701,7 @@ void CLASS tiff_get (unsigned base,
   *type = get2();
   *len  = get4();
   *save = ftell(ifp) + 4;
-  if (*len * ("11124811248488"[*type < 14 ? *type:0]-'0') > 4)
+  if (*len * ("11124811248484"[*type < 14 ? *type:0]-'0') > 4)
     fseek (ifp, get4()+base, SEEK_SET);
 }
 
@@ -4492,49 +6717,1734 @@ void CLASS parse_thumb_note (int base, unsigned toff, unsigned tlen)
     fseek (ifp, save, SEEK_SET);
   }
 }
+//@end COMMON
 
 int CLASS parse_tiff_ifd (int base);
 
+//@out COMMON
+
+static float powf_lim(float a, float b, float limup)
+{
+  return (b>limup || b < -limup)?0.f:powf(a,b);
+}
+static float powf64(float a, float b)
+{
+  return powf_lim(a,b,64.f);
+}
+
+
+#ifdef LIBRAW_LIBRARY_BUILD
+
+static float my_roundf(float x) {
+  float t;
+  if (x >= 0.0) {
+    t = ceilf(x);
+    if (t - x > 0.5) t -= 1.0;
+    return t;
+  } else {
+    t = ceilf(-x);
+    if (t + x > 0.5) t -= 1.0;
+    return -t;
+  }
+}
+
+static float _CanonConvert2EV(short in)
+        {
+	float frac1;
+	short val = in, sign = 1, frac;
+	if (val < 0) { val = -val; sign = -1; }
+	frac = (val & 0x1f);
+	val -= frac;
+	if (frac == 0x0c) frac1 = 32.0f / 3.0f;
+	else if (frac == 0x14) frac1 = 64.0f / 3.0f;
+	else frac1 = (float)frac;
+	return (float)sign * ((float)val + frac1) / 32.0f;
+    }
+
+static float _CanonConvertAperture(short in)
+{
+  if (in == (short)0xffe0) return 0.0f;
+  else return powf64(2.0f, _CanonConvert2EV(in) / 2.0f);
+}
+
+void CLASS setCanonBodyFeatures (unsigned id)
+      {
+      imgdata.lens.makernotes.CamID = id;
+	if (
+            (id == 0x80000001) ||	// 1D
+            (id == 0x80000174) ||	// 1D2
+            (id == 0x80000232) ||	// 1D2N
+            (id == 0x80000169) ||	// 1D3
+            (id == 0x80000281)		// 1D4
+            )
+          {
+            imgdata.lens.makernotes.CameraFormat = LIBRAW_FORMAT_APSH;
+            imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Canon_EF;
+          }
+        else
+          if (
+              (id == 0x80000167) ||	// 1Ds
+              (id == 0x80000188) ||	// 1Ds2
+              (id == 0x80000215) ||	// 1Ds3
+              (id == 0x80000213) ||	// 5D
+              (id == 0x80000218) ||	// 5D2
+              (id == 0x80000285) ||	// 5D3
+              (id == 0x80000302) ||	// 6D
+              (id == 0x80000269) ||	// 1DX
+              (id == 0x80000324) ||	// 1DC
+              (id == 0x80000382) ||	// 5DS
+              (id == 0x80000401)		// 5DS R
+              )
+            {
+              imgdata.lens.makernotes.CameraFormat = LIBRAW_FORMAT_FF;
+              imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Canon_EF;
+            }
+          else
+            if (
+                (id == 0x80000331) ||	// M
+                (id == 0x80000355)		// M2
+                )
+              {
+                imgdata.lens.makernotes.CameraFormat = LIBRAW_FORMAT_APSC;
+                imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Canon_EF_M;
+              }
+            else
+              if (
+                  (id == 0x01140000) ||	// D30
+                  (id == 0x01668000) ||	// D60
+                  (id > 0x80000000)
+                  )
+                {
+                  imgdata.lens.makernotes.CameraFormat = LIBRAW_FORMAT_APSC;
+                  imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Canon_EF;
+                  imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Unknown;
+                }
+              else
+                {
+                  imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_FixedLens;
+                  imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_FixedLens;
+                }
+
+	return;
+      }
+
+void CLASS processCanonCameraInfo (unsigned id, uchar *CameraInfo)
+{
+  ushort iCanonLensID = 0, iCanonMaxFocal = 0, iCanonMinFocal = 0, iCanonLens = 0, iCanonCurFocal = 0, iCanonFocalType = 0;
+  CameraInfo[0] = 0;
+  CameraInfo[1] = 0;
+  switch (id) {
+  case 0x80000001: // 1D
+  case 0x80000167: // 1DS
+    iCanonCurFocal = 10;
+    iCanonLensID = 13;
+    iCanonMinFocal = 14;
+    iCanonMaxFocal = 16;
+    if (!imgdata.lens.makernotes.CurFocal)
+      imgdata.lens.makernotes.CurFocal = sget2(CameraInfo + iCanonCurFocal);
+    if (!imgdata.lens.makernotes.MinFocal)
+      imgdata.lens.makernotes.MinFocal  = sget2(CameraInfo + iCanonMinFocal);
+    if (!imgdata.lens.makernotes.MaxFocal)
+      imgdata.lens.makernotes.MaxFocal = sget2(CameraInfo + iCanonMaxFocal);
+    break;
+  case 0x80000174: // 1DMkII
+  case 0x80000188: // 1DsMkII
+    iCanonCurFocal = 9;
+    iCanonLensID = 12;
+    iCanonMinFocal = 17;
+    iCanonMaxFocal = 19;
+    iCanonFocalType = 45;
+    break;
+  case 0x80000232: // 1DMkII N
+    iCanonCurFocal = 9;
+    iCanonLensID = 12;
+    iCanonMinFocal = 17;
+    iCanonMaxFocal = 19;
+    break;
+  case 0x80000169: // 1DMkIII
+  case 0x80000215: // 1DsMkIII
+    iCanonCurFocal = 29;
+    iCanonLensID = 273;
+    iCanonMinFocal = 275;
+    iCanonMaxFocal = 277;
+    break;
+  case 0x80000281: // 1DMkIV
+    iCanonCurFocal = 30;
+    iCanonLensID = 335;
+    iCanonMinFocal = 337;
+    iCanonMaxFocal = 339;
+    break;
+  case 0x80000269: // 1D X
+    iCanonCurFocal = 35;
+    iCanonLensID = 423;
+    iCanonMinFocal = 425;
+    iCanonMaxFocal = 427;
+    break;
+  case 0x80000213: // 5D
+    iCanonCurFocal = 40;
+    if (!sget2Rev(CameraInfo + 12)) iCanonLensID = 151;
+    else iCanonLensID = 12;
+    iCanonMinFocal = 147;
+    iCanonMaxFocal = 149;
+    break;
+  case 0x80000218: // 5DMkII
+    iCanonCurFocal = 30;
+    iCanonLensID = 230;
+    iCanonMinFocal = 232;
+    iCanonMaxFocal = 234;
+    break;
+  case 0x80000285: // 5DMkIII
+    iCanonCurFocal = 35;
+    iCanonLensID = 339;
+    iCanonMinFocal = 341;
+    iCanonMaxFocal = 343;
+    break;
+  case 0x80000302: // 6D
+    iCanonCurFocal = 35;
+    iCanonLensID = 353;
+    iCanonMinFocal = 355;
+    iCanonMaxFocal = 357;
+    break;
+  case 0x80000250: // 7D
+    iCanonCurFocal = 30;
+    iCanonLensID = 274;
+    iCanonMinFocal = 276;
+    iCanonMaxFocal = 278;
+    break;
+  case 0x80000190: // 40D
+    iCanonCurFocal = 29;
+    iCanonLensID = 214;
+    iCanonMinFocal = 216;
+    iCanonMaxFocal = 218;
+    iCanonLens = 2347;
+    break;
+  case 0x80000261: // 50D
+    iCanonCurFocal = 30;
+    iCanonLensID = 234;
+    iCanonMinFocal = 236;
+    iCanonMaxFocal = 238;
+    break;
+  case 0x80000287: // 60D
+    iCanonCurFocal = 30;
+    iCanonLensID = 232;
+    iCanonMinFocal = 234;
+    iCanonMaxFocal = 236;
+    break;
+  case 0x80000325: // 70D
+    iCanonCurFocal = 35;
+    iCanonLensID = 358;
+    iCanonMinFocal = 360;
+    iCanonMaxFocal = 362;
+    break;
+  case 0x80000176: // 450D
+    iCanonCurFocal = 29;
+    iCanonLensID = 222;
+    iCanonLens = 2355;
+    break;
+  case 0x80000252: // 500D
+    iCanonCurFocal = 30;
+    iCanonLensID = 246;
+    iCanonMinFocal = 248;
+    iCanonMaxFocal = 250;
+    break;
+  case 0x80000270: // 550D
+    iCanonCurFocal = 30;
+    iCanonLensID = 255;
+    iCanonMinFocal = 257;
+    iCanonMaxFocal = 259;
+    break;
+  case 0x80000286: // 600D
+  case 0x80000288: // 1100D
+    iCanonCurFocal = 30;
+    iCanonLensID = 234;
+    iCanonMinFocal = 236;
+    iCanonMaxFocal = 238;
+    break;
+  case 0x80000301: // 650D
+  case 0x80000326: // 700D
+    iCanonCurFocal = 35;
+    iCanonLensID = 295;
+    iCanonMinFocal = 297;
+    iCanonMaxFocal = 299;
+    break;
+  case 0x80000254: // 1000D
+    iCanonCurFocal = 29;
+    iCanonLensID = 226;
+    iCanonMinFocal = 228;
+    iCanonMaxFocal = 230;
+    iCanonLens = 2359;
+    break;
+  }
+  if (iCanonFocalType)
+    {
+      imgdata.lens.makernotes.FocalType = CameraInfo[iCanonFocalType];
+      if (!imgdata.lens.makernotes.FocalType)	// zero means 'fixed' here, replacing with standard '1'
+        imgdata.lens.makernotes.FocalType = 1;
+    }
+  if (!imgdata.lens.makernotes.CurFocal)
+    imgdata.lens.makernotes.CurFocal = sget2Rev(CameraInfo + iCanonCurFocal);
+  if (!imgdata.lens.makernotes.LensID)
+    imgdata.lens.makernotes.LensID = sget2Rev(CameraInfo + iCanonLensID);
+  if (!imgdata.lens.makernotes.MinFocal)
+    imgdata.lens.makernotes.MinFocal = sget2Rev(CameraInfo + iCanonMinFocal);
+  if (!imgdata.lens.makernotes.MaxFocal)
+    imgdata.lens.makernotes.MaxFocal = sget2Rev(CameraInfo + iCanonMaxFocal);
+  if (!imgdata.lens.makernotes.Lens[0] && iCanonLens) {
+    if (CameraInfo[iCanonLens] < 65)								// non-Canon lens
+      memcpy(imgdata.lens.makernotes.Lens, CameraInfo + iCanonLens, 64);
+    else if (!strncmp((char *)CameraInfo + iCanonLens, "EF-S", 4)) {
+      memcpy(imgdata.lens.makernotes.Lens, "EF-S ", 5);
+      memcpy(imgdata.lens.makernotes.LensFeatures_pre, "EF-E", 4);
+      imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Canon_EF_S;
+      memcpy(imgdata.lens.makernotes.Lens + 5, CameraInfo + iCanonLens + 4, 60);
+    }
+    else if (!strncmp((char *)CameraInfo + iCanonLens, "TS-E", 4)) {
+      memcpy(imgdata.lens.makernotes.Lens, "TS-E ", 5);
+      memcpy(imgdata.lens.makernotes.LensFeatures_pre, "TS-E", 4);
+      imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Canon_EF;
+      memcpy(imgdata.lens.makernotes.Lens + 5, CameraInfo + iCanonLens + 4, 60);
+    }
+    else if (!strncmp((char *)CameraInfo + iCanonLens, "MP-E", 4)) {
+      memcpy(imgdata.lens.makernotes.Lens, "MP-E ", 5);
+      memcpy(imgdata.lens.makernotes.LensFeatures_pre, "MP-E", 4);
+      imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Canon_EF;
+      memcpy(imgdata.lens.makernotes.Lens + 5, CameraInfo + iCanonLens + 4, 60);
+    }
+    else if (!strncmp((char *)CameraInfo + iCanonLens, "EF-M", 4)) {
+      memcpy(imgdata.lens.makernotes.Lens, "EF-M ", 5);
+      memcpy(imgdata.lens.makernotes.LensFeatures_pre, "EF-M", 4);
+      imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Canon_EF_M;
+      memcpy(imgdata.lens.makernotes.Lens + 5, CameraInfo + iCanonLens + 4, 60);
+    }
+    else {
+      memcpy(imgdata.lens.makernotes.Lens, CameraInfo + iCanonLens, 2);
+      memcpy(imgdata.lens.makernotes.LensFeatures_pre, "EF", 2);
+      imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Canon_EF;
+      imgdata.lens.makernotes.Lens[2] = 32;
+      memcpy(imgdata.lens.makernotes.Lens + 3, CameraInfo + iCanonLens + 2, 62);
+    }
+  }
+  free(CameraInfo);
+  return;
+}
+
+void CLASS processNikonLensData (uchar *LensData, unsigned len)
+{
+  ushort i;
+  if (len < 20) {
+    switch (len) {
+    case 9:
+      i = 2;
+      break;
+    case 15:
+      i = 7;
+      break;
+    case 16:
+      i = 8;
+      break;
+    }
+    imgdata.lens.nikon.NikonLensIDNumber = LensData[i];
+    imgdata.lens.nikon.NikonLensFStops = LensData[i + 1];
+    imgdata.lens.makernotes.LensFStops = (float)imgdata.lens.nikon.NikonLensFStops /12.0f;
+    imgdata.lens.makernotes.MinFocal = 5.0f * powf64(2.0f, (float)LensData[i + 2] / 24.0f);
+    imgdata.lens.makernotes.MaxFocal = 5.0f * powf64(2.0f, (float)LensData[i + 3] / 24.0f);
+    imgdata.lens.makernotes.MaxAp4MinFocal = powf64(2.0f, (float)LensData[i + 4] / 24.0f);
+    imgdata.lens.makernotes.MaxAp4MaxFocal = powf64(2.0f, (float)LensData[i + 5] / 24.0f);
+    imgdata.lens.nikon.NikonMCUVersion = LensData[i + 6];
+    if (i != 2)
+      {
+        imgdata.lens.makernotes.CurFocal = 5.0f * powf64(2.0f, (float)LensData[i - 1] / 24.0f);
+        imgdata.lens.nikon.NikonEffectiveMaxAp = powf64(2.0f, (float)LensData[i + 7] / 24.0f);
+      }
+    imgdata.lens.makernotes.LensID =
+      (unsigned long long) LensData[i] << 56 |
+      (unsigned long long) LensData[i + 1] << 48 |
+      (unsigned long long) LensData[i + 2] << 40 |
+      (unsigned long long) LensData[i + 3] << 32 |
+      (unsigned long long) LensData[i + 4] << 24 |
+      (unsigned long long) LensData[i + 5] << 16 |
+      (unsigned long long) LensData[i + 6] << 8 |
+      (unsigned long long) imgdata.lens.nikon.NikonLensType;
+
+  }
+  else if ((len == 459) || (len == 590))
+    {
+      memcpy(imgdata.lens.makernotes.Lens, LensData + 390, 64);
+    }
+  else if (len == 509)
+    {
+      memcpy(imgdata.lens.makernotes.Lens, LensData + 391, 64);
+    }
+  else if (len == 879)
+    {
+      memcpy(imgdata.lens.makernotes.Lens, LensData + 680, 64);
+    }
+  free (LensData);
+  return;
+}
+
+void CLASS setOlympusBodyFeatures (unsigned long id)
+{
+  imgdata.lens.makernotes.CamID = id;
+  if ((id == 0x4434303430) ||
+      (id == 0x4434303431) ||
+      ((id >= 0x5330303030) && (id <= 0x5330303939)))
+    {
+      imgdata.lens.makernotes.CameraFormat = LIBRAW_FORMAT_FT;
+      imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_FT;
+    }
+  else
+    {
+      imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_FixedLens;
+      imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_FixedLens;
+    }
+
+  if ((id == 0x4434303430) ||
+      (id == 0x4434303431) ||
+      ((id >= 0x5330303033) && (id <= 0x5330303138)) ||
+      (id == 0x5330303233) ||
+      (id == 0x5330303239) ||
+      (id == 0x5330303330) ||
+      (id == 0x5330303333))
+    {
+      imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_FT;
+    }
+  else if (imgdata.lens.makernotes.CameraMount != LIBRAW_MOUNT_FixedLens)
+    {
+      imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_mFT;
+    }
+  return;
+}
+
+void CLASS setPentaxBodyFeatures (unsigned id)
+{
+  imgdata.lens.makernotes.CamID = id;
+
+  switch (id) {
+  case 0x12994:
+  case 0x12aa2:
+  case 0x12b1a:
+  case 0x12b60:
+  case 0x12b7e:
+  case 0x12b80:
+  case 0x12b9c:
+  case 0x12b9d:
+  case 0x12ba2:
+  case 0x12c1e:
+  case 0x12c20:
+  case 0x12cd2:
+  case 0x12cd4:
+  case 0x12cfa:
+  case 0x12d72:
+  case 0x12d73:
+  case 0x12db8:
+  case 0x12dfe:
+  case 0x12e6c:
+  case 0x12e76:
+  case 0x12ef8:
+  case 0x12f52:
+  case 0x12f70:
+  case 0x12f71:
+  case 0x12fb6:
+  case 0x12fc0:
+  case 0x12fca:
+  case 0x1301a:
+    imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Pentax_K;
+    imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Pentax_K;
+    imgdata.lens.makernotes.CameraFormat = LIBRAW_FORMAT_APSC;
+    break;
+  case 0x12e08:
+  case 0x13010:
+    imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Pentax_645;
+    imgdata.lens.makernotes.LensFormat = LIBRAW_FORMAT_MF;
+    imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Pentax_645;
+    imgdata.lens.makernotes.CameraFormat = LIBRAW_FORMAT_MF;
+    break;
+  case 0x12ee4:
+  case 0x12f66:
+  case 0x12f7a:
+  case 0x1302e:
+    imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Pentax_Q;
+    imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Pentax_Q;
+    break;
+  default:
+    imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_FixedLens;
+    imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_FixedLens;
+  }
+  return;
+}
+
+void CLASS setPhaseOneFeatures (unsigned id) {
+
+  ushort i;
+  static const struct {
+    ushort id;
+    char t_model[32];
+  } p1_unique[] = {
+    // Phase One section:
+    {1, "Hasselblad V"},
+    {10, "PhaseOne/Mamiya"},
+    {12, "Contax 645"},
+    {16, "Hasselblad V"},
+    {17, "Hasselblad V"},
+    {18, "Contax 645"},
+    {19, "PhaseOne/Mamiya"},
+    {20, "Hasselblad V"},
+    {21, "Contax 645"},
+    {22, "PhaseOne/Mamiya"},
+    {23, "Hasselblad V"},
+    {24, "Hasselblad H"},
+    {25, "PhaseOne/Mamiya"},
+    {32, "Contax 645"},
+    {34, "Hasselblad V"},
+    {35, "Hasselblad V"},
+    {36, "Hasselblad H"},
+    {37, "Contax 645"},
+    {38, "PhaseOne/Mamiya"},
+    {39, "Hasselblad V"},
+    {40, "Hasselblad H"},
+    {41, "Contax 645"},
+    {42, "PhaseOne/Mamiya"},
+    {44, "Hasselblad V"},
+    {45, "Hasselblad H"},
+    {46, "Contax 645"},
+    {47, "PhaseOne/Mamiya"},
+    {48, "Hasselblad V"},
+    {49, "Hasselblad H"},
+    {50, "Contax 645"},
+    {51, "PhaseOne/Mamiya"},
+    {52, "Hasselblad V"},
+    {53, "Hasselblad H"},
+    {54, "Contax 645"},
+    {55, "PhaseOne/Mamiya"},
+    {67, "Hasselblad V"},
+    {68, "Hasselblad H"},
+    {69, "Contax 645"},
+    {70, "PhaseOne/Mamiya"},
+    {71, "Hasselblad V"},
+    {72, "Hasselblad H"},
+    {73, "Contax 645"},
+    {74, "PhaseOne/Mamiya"},
+    {76, "Hasselblad V"},
+    {77, "Hasselblad H"},
+    {78, "Contax 645"},
+    {79, "PhaseOne/Mamiya"},
+    {80, "Hasselblad V"},
+    {81, "Hasselblad H"},
+    {82, "Contax 645"},
+    {83, "PhaseOne/Mamiya"},
+    {84, "Hasselblad V"},
+    {85, "Hasselblad H"},
+    {86, "Contax 645"},
+    {87, "PhaseOne/Mamiya"},
+    {99, "Hasselblad V"},
+    {100, "Hasselblad H"},
+    {101, "Contax 645"},
+    {102, "PhaseOne/Mamiya"},
+    {103, "Hasselblad V"},
+    {104, "Hasselblad H"},
+    {105, "PhaseOne/Mamiya"},
+    {106, "Contax 645"},
+    {112, "Hasselblad V"},
+    {113, "Hasselblad H"},
+    {114, "Contax 645"},
+    {115, "PhaseOne/Mamiya"},
+    {131, "Hasselblad V"},
+    {132, "Hasselblad H"},
+    {133, "Contax 645"},
+    {134, "PhaseOne/Mamiya"},
+    {135, "Hasselblad V"},
+    {136, "Hasselblad H"},
+    {137, "Contax 645"},
+    {138, "PhaseOne/Mamiya"},
+    {140, "Hasselblad V"},
+    {141, "Hasselblad H"},
+    {142, "Contax 645"},
+    {143, "PhaseOne/Mamiya"},
+    {148, "Hasselblad V"},
+    {149, "Hasselblad H"},
+    {150, "Contax 645"},
+    {151, "PhaseOne/Mamiya"},
+    {160, "A-250"},
+    {161, "A-260"},
+    {162, "A-280"},
+    {167, "Hasselblad V"},
+    {168, "Hasselblad H"},
+    {169, "Contax 645"},
+    {170, "PhaseOne/Mamiya"},
+    {172, "Hasselblad V"},
+    {173, "Hasselblad H"},
+    {174, "Contax 645"},
+    {175, "PhaseOne/Mamiya"},
+    {176, "Hasselblad V"},
+    {177, "Hasselblad H"},
+    {178, "Contax 645"},
+    {179, "PhaseOne/Mamiya"},
+    {180, "Hasselblad V"},
+    {181, "Hasselblad H"},
+    {182, "Contax 645"},
+    {183, "PhaseOne/Mamiya"},
+    {208, "Hasselblad V"},
+    {211, "PhaseOne/Mamiya"},
+    {448, "Phase One 645AF"},
+    {457, "Phase One 645DF"},
+    {471, "Phase One 645DF+"},
+    {704, "Phase One iXA"},
+    {705, "Phase One iXA - R"},
+    {706, "Phase One iXU 150"},
+    {707, "Phase One iXU 150 - NIR"},
+    {708, "Phase One iXU 180"},
+    {721, "Phase One iXR"},
+    // Leaf section:
+    {333,"Mamiya"},
+    {329,"Universal"},
+    {330,"Hasselblad H1/H2"},
+    {332,"Contax"},
+    {336,"AFi"},
+    {327,"Mamiya"},
+    {324,"Universal"},
+    {325,"Hasselblad H1/H2"},
+    {326,"Contax"},
+    {335,"AFi"},
+    {340,"Mamiya"},
+    {337,"Universal"},
+    {338,"Hasselblad H1/H2"},
+    {339,"Contax"},
+    {323,"Mamiya"},
+    {320,"Universal"},
+    {322,"Hasselblad H1/H2"},
+    {321,"Contax"},
+    {334,"AFi"},
+    {369,"Universal"},
+    {370,"Mamiya"},
+    {371,"Hasselblad H1/H2"},
+    {372,"Contax"},
+    {373,"Afi"},
+  };
+  imgdata.lens.makernotes.CamID = id;
+  if (id && !imgdata.lens.makernotes.body[0]) {
+    for (i=0; i < sizeof p1_unique / sizeof *p1_unique; i++)
+      if (id == p1_unique[i].id) {
+        strcpy(imgdata.lens.makernotes.body,p1_unique[i].t_model);
+      }
+  }
+  return;
+}
+
+void CLASS setSonyBodyFeatures (unsigned id) {
+
+  imgdata.lens.makernotes.CamID = id;
+  if (	// FF cameras
+      (id == 257) ||		// a900
+      (id == 269) ||		// a850
+      (id == 340) ||		// ILCE-7M2
+      (id == 318) ||		// ILCE-7S
+      (id == 311) ||		// ILCE-7R
+      (id == 306) ||		// ILCE-7
+      (id == 298) ||		// DSC-RX1
+      (id == 299) ||		// NEX-VG900
+      (id == 310) ||		// DSC-RX1R
+      (id == 294)				// SLT-99, Hasselblad HV
+      )
+    {
+      imgdata.lens.makernotes.CameraFormat = LIBRAW_FORMAT_FF;
+    }
+  else
+    {
+      if ((id != 002) &&  // DSC-R1
+          (id != 297) &&  // DSC-RX100
+          (id != 308) &&  // DSC-RX100M2
+          (id != 309) &&  // DSC-RX10
+          (id != 317))    // DSC-RX100M3
+      imgdata.lens.makernotes.CameraFormat = LIBRAW_FORMAT_APSC;
+    }
+
+  if (	// E-mount cameras
+      // ILCE:
+      (id == 302) ||
+      (id == 306) ||
+      (id == 311) ||
+      (id == 312) ||
+      (id == 313) ||
+      (id == 318) ||
+      (id == 339) ||
+      (id == 340) ||
+      (id == 346)	||
+      // NEX:
+      (id == 278) ||
+      (id == 279) ||
+      (id == 284) ||
+      (id == 288) ||
+      (id == 289) ||
+      (id == 290) ||
+      (id == 293) ||
+      (id == 295) ||
+      (id == 296) ||
+      (id == 299) ||
+      (id == 300) ||
+      (id == 305) ||
+      (id == 307)
+      )
+    {
+      imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Sony_E;
+    }
+
+  else if (	// A-mount cameras
+           // DSLR:
+           (id == 256) ||
+           (id == 257) ||
+           (id == 258) ||
+           (id == 259) ||
+           (id == 260) ||
+           (id == 261) ||
+           (id == 262) ||
+           (id == 263) ||
+           (id == 264) ||
+           (id == 265) ||
+           (id == 266) ||
+           (id == 269) ||
+           (id == 270) ||
+           (id == 273) ||
+           (id == 274) ||
+           (id == 275) ||
+           (id == 282) ||
+           (id == 283)	||
+           // SLT:
+           (id == 280) ||
+           (id == 281) ||
+           (id == 285) ||
+           (id == 286) ||
+           (id == 287) ||
+           (id == 291) ||
+           (id == 292) ||
+           (id == 294) ||
+           (id == 303)	||
+           // ILCA:
+           (id == 319)
+           )
+    {
+      imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Minolta_A;
+    }
+
+  else if (	// DSC
+           (id == 002) ||  // DSC-R1
+           (id == 297) ||  // DSC-RX100
+           (id == 298) ||  // DSC-RX1
+           (id == 308) ||  // DSC-RX100M2
+           (id == 309) ||  // DSC-RX10
+           (id == 310) ||  // DSC-RX1R
+           (id == 317)     // DSC-RX100M3
+           )
+    {
+      imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_FixedLens;
+      imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_FixedLens;
+    }
+  return;
+}
+
+void CLASS parseSonyLensType2 (uchar a, uchar b) {
+  ushort lid2;
+  lid2 = (((ushort)a)<<8) | ((ushort)b);
+  if (!lid2) return;
+  if (lid2 < 0x100)
+    {
+      imgdata.lens.makernotes.AdapterID = lid2;
+      switch (lid2) {
+      case 1:
+      case 2:
+      case 3:
+      case 6:
+        imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Minolta_A;
+        break;
+      case 44:
+      case 78:
+      case 239:
+        imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Canon_EF;
+        break;
+      }
+    }
+  else
+    imgdata.lens.makernotes.LensID = lid2;
+  return;
+}
+
+void CLASS parseSonyLensFeatures (uchar a, uchar b) {
+
+  ushort features;
+  features = (((ushort)a)<<8) | ((ushort)b);
+
+  if ((imgdata.lens.makernotes.LensMount == LIBRAW_MOUNT_Canon_EF) || !features)
+    return;
+
+  imgdata.lens.makernotes.LensFormat = LIBRAW_FORMAT_FF;
+  imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Minolta_A;
+  imgdata.lens.makernotes.LensFeatures_pre[0] = 0;
+  imgdata.lens.makernotes.LensFeatures_suf[0] = 0;
+
+  if ((features & 0x0200) && (features & 0x0100)) {
+    strcpy(imgdata.lens.makernotes.LensFeatures_pre, "E");
+    imgdata.lens.makernotes.LensFormat = LIBRAW_FORMAT_APSC;
+    imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Sony_E;
+  } else if (features & 0x0200) {
+    strcpy(imgdata.lens.makernotes.LensFeatures_pre, "FE");
+    imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Sony_E;
+  } else if (features & 0x0100) {
+    strcpy(imgdata.lens.makernotes.LensFeatures_pre, "DT");
+    imgdata.lens.makernotes.LensFormat = LIBRAW_FORMAT_APSC;
+  }
+
+  if (features & 0x4000)
+    strncat(imgdata.lens.makernotes.LensFeatures_pre, " PZ", sizeof(imgdata.lens.makernotes.LensFeatures_pre));
+
+  if (features & 0x0008)
+    strncat(imgdata.lens.makernotes.LensFeatures_suf, " G", sizeof(imgdata.lens.makernotes.LensFeatures_suf));
+  else if (features & 0x0004)
+    strncat(imgdata.lens.makernotes.LensFeatures_suf, " ZA", sizeof(imgdata.lens.makernotes.LensFeatures_suf));
+
+  if ((features & 0x0020) && (features & 0x0040))
+    strncat(imgdata.lens.makernotes.LensFeatures_suf, " Macro", sizeof(imgdata.lens.makernotes.LensFeatures_suf));
+  else if (features & 0x0020)
+    strncat(imgdata.lens.makernotes.LensFeatures_suf, " STF", sizeof(imgdata.lens.makernotes.LensFeatures_suf));
+  else if (features & 0x0040)
+    strncat(imgdata.lens.makernotes.LensFeatures_suf, " Reflex", sizeof(imgdata.lens.makernotes.LensFeatures_suf));
+  else if (features & 0x0080)
+    strncat(imgdata.lens.makernotes.LensFeatures_suf, " Fisheye", sizeof(imgdata.lens.makernotes.LensFeatures_suf));
+
+  if (features & 0x0001)
+    strncat(imgdata.lens.makernotes.LensFeatures_suf, " SSM", sizeof(imgdata.lens.makernotes.LensFeatures_suf));
+  else if (features & 0x0002)
+    strncat(imgdata.lens.makernotes.LensFeatures_suf, " SAM", sizeof(imgdata.lens.makernotes.LensFeatures_suf));
+
+  if (features & 0x8000)
+    strncat(imgdata.lens.makernotes.LensFeatures_suf, " OSS", sizeof(imgdata.lens.makernotes.LensFeatures_suf));
+
+  if (features & 0x2000)
+    strncat(imgdata.lens.makernotes.LensFeatures_suf, " LE", sizeof(imgdata.lens.makernotes.LensFeatures_suf));
+
+  if (features & 0x0800)
+    strncat(imgdata.lens.makernotes.LensFeatures_suf, " II", sizeof(imgdata.lens.makernotes.LensFeatures_suf));
+
+  if (imgdata.lens.makernotes.LensFeatures_suf[0] == ' ')
+    memmove(imgdata.lens.makernotes.LensFeatures_suf, imgdata.lens.makernotes.LensFeatures_suf+1, strlen(imgdata.lens.makernotes.LensFeatures_suf));
+
+  return;
+}
+
+void CLASS process_Sony_0x940c (uchar * buf)
+{
+  ushort lid2;
+  if (imgdata.lens.makernotes.LensMount != LIBRAW_MOUNT_Canon_EF)
+    {
+      switch (SonySubstitution[buf[0x0008]]) {
+      case 1:
+      case 5:
+        imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Minolta_A;
+        break;
+      case 4:
+        imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Sony_E;
+        break;
+      }
+    }
+  lid2 = (((ushort)SonySubstitution[buf[0x000a]])<<8) |
+    ((ushort)SonySubstitution[buf[0x0009]]);
+  if ((lid2 > 0) && (lid2 < 32784))
+    parseSonyLensType2 (SonySubstitution[buf[0x000a]],	// LensType2 - Sony lens ids
+                        SonySubstitution[buf[0x0009]]);
+  return;
+}
+
+
+void CLASS process_Sony_0x9050 (uchar * buf, unsigned id)
+{
+  ushort lid;
+
+  if ((imgdata.lens.makernotes.CameraMount != LIBRAW_MOUNT_Sony_E) &&
+      (imgdata.lens.makernotes.CameraMount != LIBRAW_MOUNT_FixedLens))
+    {
+      if (buf[0])
+        imgdata.lens.makernotes.MaxAp =
+          my_roundf(powf64(2.0f, ((float)SonySubstitution[buf[0]] / 8.0 - 1.06f) / 2.0f)*10.0f) / 10.0f;
+
+      if (buf[1])
+        imgdata.lens.makernotes.MinAp =
+          my_roundf(powf64(2.0f, ((float)SonySubstitution[buf[1]] / 8.0 - 1.06f) / 2.0f)*10.0f) / 10.0f;
+    }
+
+  if (imgdata.lens.makernotes.CameraMount != LIBRAW_MOUNT_FixedLens)
+    {
+      if (buf[0x3d] | buf[0x3c])
+        {
+          lid = SonySubstitution[buf[0x3d]] << 8 |
+            SonySubstitution[buf[0x3c]];
+          imgdata.lens.makernotes.CurAp =
+            powf64(2.0f, ((float)lid/256.0f - 16.0f) / 2.0f);
+        }
+      if (buf[0x105] && (imgdata.lens.makernotes.LensMount != LIBRAW_MOUNT_Canon_EF))
+        imgdata.lens.makernotes.LensMount =
+          SonySubstitution[buf[0x105]];
+      if (buf[0x106])
+        imgdata.lens.makernotes.LensFormat =
+          SonySubstitution[buf[0x106]];
+    }
+
+  if (imgdata.lens.makernotes.CameraMount == LIBRAW_MOUNT_Sony_E)
+    {
+      parseSonyLensType2 (SonySubstitution[buf[0x0108]],		// LensType2 - Sony lens ids
+                          SonySubstitution[buf[0x0107]]);
+    }
+
+  if ((imgdata.lens.makernotes.LensID == -1) &&
+      (imgdata.lens.makernotes.CameraMount == LIBRAW_MOUNT_Minolta_A) &&
+      (buf[0x010a] | buf[0x0109]))
+    {
+      imgdata.lens.makernotes.LensID =		 // LensType - Minolta/Sony lens ids
+        SonySubstitution[buf[0x010a]] << 8 |
+        SonySubstitution[buf[0x0109]];
+      if ((imgdata.lens.makernotes.LensID > 61184) &&
+          (imgdata.lens.makernotes.LensID < 65535))
+        {
+          imgdata.lens.makernotes.LensID -= 61184;
+          imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Canon_EF;
+        }
+    }
+
+  if ((id >= 286) && (id <= 293))
+    // "SLT-A65", "SLT-A77", "NEX-7", "NEX-VG20E",
+    // "SLT-A37", "SLT-A57", "NEX-F3", "Lunar"
+    parseSonyLensFeatures (SonySubstitution[buf[0x115]],
+                           SonySubstitution[buf[0x116]]);
+  else if (imgdata.lens.makernotes.CameraMount != LIBRAW_MOUNT_FixedLens)
+    parseSonyLensFeatures (SonySubstitution[buf[0x116]],
+                           SonySubstitution[buf[0x117]]);
+  return;
+}
+
+void CLASS parse_makernote_0xc634(int base, int uptag, unsigned dng_writer)
+{
+  unsigned offset = 0, entries, tag, type, len, save, c;
+  unsigned i;
+
+  uchar NikonKey, ci, cj, ck;
+  unsigned serial = 0;
+  unsigned NikonLensDataVersion = 0;
+  unsigned lenNikonLensData = 0;
+
+  uchar *CanonCameraInfo;
+  unsigned lenCanonCameraInfo = 0;
+
+  uchar *table_buf;
+  uchar *table_buf_0x9050;
+  ushort table_buf_0x9050_present = 0;
+  uchar *table_buf_0x940c;
+  ushort table_buf_0x940c_present = 0;
+
+  short morder, sorder = order;
+  char buf[10];
+
+  fread(buf, 1, 10, ifp);
+  if (!strcmp(buf, "Nikon")) {
+    base = ftell(ifp);
+    order = get2();
+    if (get2() != 42) goto quit;
+    offset = get4();
+    fseek(ifp, offset - 8, SEEK_CUR);
+  }
+  else if (!strcmp(buf, "OLYMPUS") ||
+           !strcmp(buf, "PENTAX ") ||
+           (!strncmp(make, "SAMSUNG", 7) && (dng_writer == CameraDNG))) {
+    base = ftell(ifp) - 10;
+    fseek(ifp, -2, SEEK_CUR);
+    order = get2();
+    if (buf[0] == 'O') get2();
+  }
+  else if (!strncmp(buf, "SONY", 4) ||
+           !strcmp(buf, "Panasonic")) {
+    goto nf;
+  }
+  else if (!strncmp(buf, "FUJIFILM", 8)) {
+    base = ftell(ifp) - 10;
+  nf: order = 0x4949;
+    fseek(ifp, 2, SEEK_CUR);
+  }
+  else if (!strcmp(buf, "OLYMP") ||
+           !strcmp(buf, "LEICA") ||
+           !strcmp(buf, "Ricoh") ||
+           !strcmp(buf, "EPSON"))
+    fseek(ifp, -2, SEEK_CUR);
+  else if (!strcmp(buf, "AOC") ||
+           !strcmp(buf, "QVC"))
+    fseek(ifp, -4, SEEK_CUR);
+  else {
+    fseek(ifp, -10, SEEK_CUR);
+    if ((!strncmp(make, "SAMSUNG", 7) &&
+				(dng_writer == AdobeDNG)))
+      base = ftell(ifp);
+  }
+
+  entries = get2();
+
+// if (dng_writer == AdobeDNG)
+//   printf("\n*** parse_makernote_0xc634: AdobeDNG");
+// else if (dng_writer == CameraDNG)
+//   printf("\n*** parse_makernote_0xc634: CameraDNG");
+
+//   printf ("\n\tbuf  =%s=\n\tmake  =%s=\n\tmodel =%s=\n\tbase: 0x%x\n\tentries: %d\n",
+//   		buf, make, model, base, entries);
+
+  if (entries > 1000) return;
+  morder = order;
+  while (entries--) {
+    order = morder;
+    tiff_get(base, &tag, &type, &len, &save);
+    tag |= uptag << 16;
+
+// 	printf ("\n\tbase: 0x%x tag: 0x%04x type: 0x%x len: 0x%x pos: 0x%llx",
+// 			base, tag, type, len, ftell(ifp));
+
+    if (!strcmp(make, "Canon"))
+      {
+        if (tag == 0x0001)				// camera settings
+          {
+            fseek(ifp, 44, SEEK_CUR);
+            imgdata.lens.makernotes.LensID = get2();
+            imgdata.lens.makernotes.MaxFocal = get2();
+            imgdata.lens.makernotes.MinFocal = get2();
+            imgdata.lens.makernotes.CanonFocalUnits = get2();
+            if (imgdata.lens.makernotes.CanonFocalUnits != 1)
+              {
+                imgdata.lens.makernotes.MaxFocal /= (float)imgdata.lens.makernotes.CanonFocalUnits;
+                imgdata.lens.makernotes.MinFocal /= (float)imgdata.lens.makernotes.CanonFocalUnits;
+              }
+            imgdata.lens.makernotes.MaxAp = _CanonConvertAperture(get2());
+            imgdata.lens.makernotes.MinAp = _CanonConvertAperture(get2());
+          }
+
+        else if (tag == 0x0002)			// focal length
+          {
+            imgdata.lens.makernotes.FocalType = get2();
+            imgdata.lens.makernotes.CurFocal = get2();
+            if ((imgdata.lens.makernotes.CanonFocalUnits != 1) &&
+                imgdata.lens.makernotes.CanonFocalUnits)
+              {
+                imgdata.lens.makernotes.CurFocal /= (float)imgdata.lens.makernotes.CanonFocalUnits;
+              }
+          }
+
+        else if (tag == 0x0004)			// shot info
+          {
+            fseek(ifp, 42, SEEK_CUR);
+            imgdata.lens.makernotes.CurAp = _CanonConvertAperture(get2());
+          }
+
+        else if (tag == 0x000d)			// camera info
+          {
+            CanonCameraInfo = (uchar*)malloc(len);
+            fread(CanonCameraInfo, len, 1, ifp);
+            lenCanonCameraInfo = len;
+          }
+
+        else if (tag == 0x10)	// Canon ModelID
+          {
+            unique_id = get4();
+            setCanonBodyFeatures(unique_id);
+            if (lenCanonCameraInfo) processCanonCameraInfo(unique_id, CanonCameraInfo);
+          }
+
+        else if (tag == 0x0095 &&		// lens model tag
+                 !imgdata.lens.makernotes.Lens[0])
+          {
+            fread(imgdata.lens.makernotes.Lens, 2, 1, ifp);
+            imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Canon_EF;
+            if (imgdata.lens.makernotes.Lens[0] < 65)					// non-Canon lens
+              fread(imgdata.lens.makernotes.Lens + 2, 62, 1, ifp);
+            else
+              {
+                char efs[2];
+                imgdata.lens.makernotes.LensFeatures_pre[0] = imgdata.lens.makernotes.Lens[0];
+                imgdata.lens.makernotes.LensFeatures_pre[1] = imgdata.lens.makernotes.Lens[1];
+                fread(efs, 2, 1, ifp);
+                if (efs[0] == 45 && (efs[1] == 83 || efs[1] == 69 || efs[1] == 77))
+                  {	// "EF-S, TS-E, MP-E, EF-M" lenses
+                    imgdata.lens.makernotes.Lens[2] = imgdata.lens.makernotes.LensFeatures_pre[2] = efs[0];
+                    imgdata.lens.makernotes.Lens[3] = imgdata.lens.makernotes.LensFeatures_pre[3] = efs[1];
+                    imgdata.lens.makernotes.Lens[4] = 32;
+                    if (efs[1] == 83)
+                      {
+                        imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Canon_EF_S;
+                        imgdata.lens.makernotes.LensFormat = LIBRAW_FORMAT_APSC;
+                      }
+                    else if (efs[1] == 77)
+                      {
+                        imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Canon_EF_M;
+                      }
+                  }
+                else
+                  {																// "EF" lenses
+                    imgdata.lens.makernotes.Lens[2] = 32;
+                    imgdata.lens.makernotes.Lens[3] = efs[0];
+                    imgdata.lens.makernotes.Lens[4] = efs[1];
+                  }
+                fread(imgdata.lens.makernotes.Lens + 5, 58, 1, ifp);
+              }
+          }
+      }
+
+    else if (!strncmp(make, "FUJI", 4))
+      switch (tag) {
+      case 0x1404: imgdata.lens.makernotes.MinFocal = getreal(type); break;
+      case 0x1405: imgdata.lens.makernotes.MaxFocal = getreal(type); break;
+      case 0x1406: imgdata.lens.makernotes.MaxAp4MinFocal = getreal(type); break;
+      case 0x1407: imgdata.lens.makernotes.MaxAp4MaxFocal = getreal(type); break;
+      }
+
+    else if (!strncasecmp(make, "LEICA", 5))
+      {
+        if ((tag == 0x0303) && (type != 4))
+          {
+            fread(imgdata.lens.makernotes.Lens, len, 1, ifp);
+          }
+
+        if ((tag == 0x3405) ||
+            (tag == 0x0310) ||
+            (tag == 0x34003405))
+          {
+            imgdata.lens.makernotes.LensID = get4();
+            imgdata.lens.makernotes.LensID =
+              ((imgdata.lens.makernotes.LensID>>2)<<8) |
+              (imgdata.lens.makernotes.LensID & 0x3);
+            if (imgdata.lens.makernotes.LensID != -1)
+              {
+                if ((model[0] == 'M') ||
+                    !strncasecmp (model, "LEICA M", 7))
+                  {
+                    imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Leica_M;
+                    if (imgdata.lens.makernotes.LensID)
+                      imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Leica_M;
+                  }
+                else if ((model[0] == 'S') ||
+                         !strncasecmp (model, "LEICA S", 7))
+                  {
+                    imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Leica_S;
+                    if (imgdata.lens.makernotes.Lens[0])
+                      imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Leica_S;
+                  }
+              }
+          }
+
+        else if (
+                 ((tag == 0x0313) || (tag == 0x34003406)) &&
+                 (fabs(imgdata.lens.makernotes.CurAp) < 0.17f) &&
+                 ((type == 10) || (type == 5))
+                )
+          {
+            imgdata.lens.makernotes.CurAp = getreal(type);
+            if (imgdata.lens.makernotes.CurAp > 126.3)
+              imgdata.lens.makernotes.CurAp = 0.0f;
+          }
+
+        else if (tag == 0x3400)
+          {
+            parse_makernote (base, 0x3400);
+          }
+      }
+
+    else if (!strncmp(make, "NIKON", 5))
+      {
+        if (tag == 0x1d)							// serial number
+          while ((c = fgetc(ifp)) && c != EOF)
+            serial = serial * 10 + (isdigit(c) ? c - '0' : c % 10);
+
+        else if (tag == 0x0082)				// lens attachment
+          {
+            fread(imgdata.lens.makernotes.Attachment, len, 1, ifp);
+          }
+        else if (tag == 0x0083)				// lens type
+          {
+            imgdata.lens.nikon.NikonLensType = fgetc(ifp);
+            if (!(imgdata.lens.nikon.NikonLensType & 0x01))
+              {
+                imgdata.lens.makernotes.LensFeatures_pre[0] = 'A';
+                imgdata.lens.makernotes.LensFeatures_pre[1] = 'F';
+              }
+            if (imgdata.lens.nikon.NikonLensType & 0x02)
+              {
+                if (imgdata.lens.nikon.NikonLensType & 0x04)
+                  imgdata.lens.makernotes.LensFeatures_suf[0] = 'G';
+                else
+                  imgdata.lens.makernotes.LensFeatures_suf[0] = 'D';
+                imgdata.lens.makernotes.LensFeatures_suf[1] = ' ';
+              }
+            if (imgdata.lens.nikon.NikonLensType & 0x08)
+              {
+                imgdata.lens.makernotes.LensFeatures_suf[2] = 'V';
+                imgdata.lens.makernotes.LensFeatures_suf[3] = 'R';
+              }
+            if (imgdata.lens.nikon.NikonLensType & 0x10)
+              {
+                imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Nikon_CX;
+              }
+
+            if (imgdata.lens.nikon.NikonLensType & 0x20)
+              {
+                strcpy(imgdata.lens.makernotes.Adapter, "FT-1");
+              }
+            imgdata.lens.nikon.NikonLensType = imgdata.lens.nikon.NikonLensType & 0xdf;
+          }
+        else if (tag == 0x0084)				// lens
+          {
+            imgdata.lens.makernotes.MinFocal = getreal(type);
+            imgdata.lens.makernotes.MaxFocal = getreal(type);
+            imgdata.lens.makernotes.MaxAp4MinFocal = getreal(type);
+            imgdata.lens.makernotes.MaxAp4MaxFocal = getreal(type);
+          }
+        else if (tag == 0x008b)				// lens f-stops
+          {
+            uchar a, b, c;
+            a = fgetc(ifp);
+            b = fgetc(ifp);
+            c = fgetc(ifp);
+            if (c)
+              {
+                imgdata.lens.nikon.NikonLensFStops = a*b*(12/c);
+                imgdata.lens.makernotes.LensFStops =
+                  (float)imgdata.lens.nikon.NikonLensFStops /12.0f;
+              }
+          }
+        else if (tag == 0x0098)				// contains lens data
+          {
+            for (i = 0; i < 4; i++)
+              {
+                NikonLensDataVersion = NikonLensDataVersion * 10 + fgetc(ifp) - '0';
+              }
+            switch (NikonLensDataVersion)
+              {
+              case 100: lenNikonLensData = 9; imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Nikon_F; break;
+              case 101:
+              case 201:	// encrypted, starting from v.201
+              case 202:
+              case 203: lenNikonLensData = 15; imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Nikon_F; break;
+              case 204: lenNikonLensData = 16; imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Nikon_F; break;
+              case 400: lenNikonLensData = 459; break;
+              case 401: lenNikonLensData = 590; break;
+              case 402: lenNikonLensData = 509; break;
+              case 403: lenNikonLensData = 879; break;
+              }
+            table_buf = (uchar*)malloc(lenNikonLensData);
+            fread(table_buf, lenNikonLensData, 1, ifp);
+            if ((NikonLensDataVersion < 201) && lenNikonLensData)
+            {
+              processNikonLensData(table_buf, lenNikonLensData);
+              lenNikonLensData = 0;
+            }
+          }
+
+        else if (tag == 0xa7)					// shutter count
+          {
+            NikonKey = fgetc(ifp) ^ fgetc(ifp) ^ fgetc(ifp) ^ fgetc(ifp);
+            if ((NikonLensDataVersion > 200) && lenNikonLensData)
+              {
+                ci = xlat[0][serial & 0xff];
+                cj = xlat[1][NikonKey];
+                ck = 0x60;
+                for (i = 0; i < lenNikonLensData; i++)
+                  table_buf[i] ^= (cj += ci * ck++);
+                processNikonLensData(table_buf, lenNikonLensData);
+                lenNikonLensData = 0;
+              }
+          }
+
+        else if (tag == 37 && (!iso_speed || iso_speed == 65535))
+          {
+            unsigned char cc;
+            fread(&cc, 1, 1, ifp);
+            iso_speed = (int)(100.0 * powf64(2.0, (double)(cc) / 12.0 - 5.0));
+            break;
+          }
+      }
+
+    else if (!strncmp(make, "OLYMPUS", 7))
+      {
+        if (tag == 0x2010)
+          {
+            fseek(ifp, save - 4, SEEK_SET);
+            fseek(ifp, base + get4(), SEEK_SET);
+            parse_makernote_0xc634(base, 0x2010, dng_writer);
+          }
+
+        switch (tag) {
+        case 0x0207:
+        case 0x20100100:
+          {
+            uchar sOlyID[7];
+            long unsigned OlyID;
+            fread (sOlyID, len, 1, ifp);
+            OlyID = sOlyID[0];
+            i = 1;
+            while (sOlyID[i])
+              {
+                OlyID = OlyID << 8 | sOlyID[i];
+                i++;
+              }
+            setOlympusBodyFeatures(OlyID);
+          }
+          break;
+        case 0x1002:
+          imgdata.lens.makernotes.CurAp = powf64(2.0f, getreal(type)/2);
+          break;
+        case 0x20100201:
+          imgdata.lens.makernotes.LensID =
+            (unsigned long long)fgetc(ifp)<<16 |
+            (unsigned long long)(fgetc(ifp), fgetc(ifp))<<8 |
+            (unsigned long long)fgetc(ifp);
+          imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_FT;
+          imgdata.lens.makernotes.LensFormat = LIBRAW_FORMAT_FT;
+          if (((imgdata.lens.makernotes.LensID < 0x20000) ||
+               (imgdata.lens.makernotes.LensID > 0x4ffff)) &&
+              (imgdata.lens.makernotes.LensID & 0x10))
+            {
+              imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_mFT;
+            }
+          break;
+        case 0x20100203:
+          fread(imgdata.lens.makernotes.Lens, len, 1, ifp);
+          break;
+        case 0x20100205:
+          imgdata.lens.makernotes.MaxAp4MinFocal = powf64(sqrt(2.0f), get2() / 256.0f);
+          break;
+        case 0x20100206:
+          imgdata.lens.makernotes.MaxAp4MaxFocal = powf64(sqrt(2.0f), get2() / 256.0f);
+          break;
+        case 0x20100207:
+          imgdata.lens.makernotes.MinFocal = (float)get2();
+          break;
+        case 0x20100208:
+          imgdata.lens.makernotes.MaxFocal = (float)get2();
+          if (imgdata.lens.makernotes.MaxFocal > 1000.0f)
+            imgdata.lens.makernotes.MaxFocal = imgdata.lens.makernotes.MinFocal;
+          break;
+        case 0x2010020a:
+          imgdata.lens.makernotes.MaxAp4CurFocal = powf64(sqrt(2.0f), get2() / 256.0f);
+          break;
+        case 0x20100301:
+          imgdata.lens.makernotes.TeleconverterID = fgetc(ifp) << 8;
+          fgetc(ifp);
+          imgdata.lens.makernotes.TeleconverterID =
+            imgdata.lens.makernotes.TeleconverterID | fgetc(ifp);
+          break;
+        case 0x20100303:
+          fread(imgdata.lens.makernotes.Teleconverter, len, 1, ifp);
+          break;
+        case 0x20100403:
+          fread(imgdata.lens.makernotes.Attachment, len, 1, ifp);
+          break;
+        }
+      }
+
+    else if (!strncmp(make, "PENTAX", 6) ||
+             !strncmp(model, "PENTAX", 6) ||
+             (!strncmp(make, "SAMSUNG", 7) && (dng_writer == CameraDNG)))
+      {
+        if (tag == 0x0005)
+          {
+            unique_id = get4();
+            setPentaxBodyFeatures(unique_id);
+            if (
+                (dng_writer == CameraDNG) &&
+                (
+                 (unique_id == 0x12f66) ||		// Q10
+                 (unique_id == 0x12f7a) ||		// Q7
+                 (unique_id == 0x12ee4)			  // Q
+                 )
+                )
+              base += 10;
+          }
+        else if (tag == 0x0013)
+          {
+            imgdata.lens.makernotes.CurAp = (float)get2()/10.0f;
+          }
+        else if (tag == 0x001d)
+          {
+            imgdata.lens.makernotes.CurFocal = (float)get4()/100.0f;
+          }
+        else if (tag == 0x003f)
+          {
+            imgdata.lens.makernotes.LensID = fgetc(ifp) << 8 | fgetc(ifp);
+          }
+        else if (tag == 0x0207)
+          {
+            ushort iLensData = 0;
+            table_buf = (uchar*)malloc(len);
+            fread(table_buf, len, 1, ifp);
+            if ((imgdata.lens.makernotes.CamID < 0x12b9c) ||
+                ((imgdata.lens.makernotes.CamID == 0x12b9c) ||	// K100D
+                 (imgdata.lens.makernotes.CamID == 0x12b9d) ||	// K110D
+                 (imgdata.lens.makernotes.CamID == 0x12ba2)	&&	// K100D Super
+                 (!table_buf[20] || (table_buf[20] == 0xff))))
+              {
+                iLensData = 3;
+                if (imgdata.lens.makernotes.LensID == -1)
+                  imgdata.lens.makernotes.LensID =
+                    (((unsigned)table_buf[0]) << 8) + table_buf[1];
+              }
+            else switch (len)
+              {
+              case 90:							// LensInfo3
+                iLensData = 13;
+                if (imgdata.lens.makernotes.LensID == -1)
+                  imgdata.lens.makernotes.LensID =
+                    ((unsigned)((table_buf[1] & 0x0f) + table_buf[3]) <<8) + table_buf[4];
+                break;
+              case 91:							// LensInfo4
+                iLensData = 12;
+                if (imgdata.lens.makernotes.LensID == -1)
+                  imgdata.lens.makernotes.LensID =
+                    ((unsigned)((table_buf[1] & 0x0f) + table_buf[3]) <<8) + table_buf[4];
+                break;
+              case 80:							// LensInfo5
+              case 128:
+                iLensData = 15;
+                if (imgdata.lens.makernotes.LensID == -1)
+                  imgdata.lens.makernotes.LensID =
+                    ((unsigned)((table_buf[1] & 0x0f) + table_buf[4]) <<8) + table_buf[5];
+                break;
+              default:
+                if (imgdata.lens.makernotes.CamID >= 0x12b9c)		// LensInfo2
+                  {
+                    iLensData = 4;
+                    if (imgdata.lens.makernotes.LensID == -1)
+                      imgdata.lens.makernotes.LensID =
+                        ((unsigned)((table_buf[0] & 0x0f) + table_buf[2]) <<8) + table_buf[3];
+                  }
+              }
+            if (iLensData)
+              {
+                if (table_buf[iLensData+9] &&
+                    (fabs(imgdata.lens.makernotes.CurFocal) < 0.1f))
+                  imgdata.lens.makernotes.CurFocal =
+                    10*(table_buf[iLensData+9]>>2) * powf64(4, (table_buf[iLensData+9] & 0x03)-2);
+                if (table_buf[iLensData+10] & 0xf0)
+                  imgdata.lens.makernotes.MaxAp4CurFocal =
+                    powf64(2.0f, (float)((table_buf[iLensData+10] & 0xf0) >>4)/4.0f);
+                if (table_buf[iLensData+10] & 0x0f)
+                  imgdata.lens.makernotes.MinAp4CurFocal =
+                    powf64(2.0f, (float)((table_buf[iLensData+10] & 0x0f) + 10)/4.0f);
+                if (
+                    (imgdata.lens.makernotes.CamID != 0x12e6c) &&	// K-r
+                    (imgdata.lens.makernotes.CamID != 0x12e76) &&	// K-5
+                    (imgdata.lens.makernotes.CamID != 0x12f70)		// K-5 II
+                    //        	  		(imgdata.lens.makernotes.CamID != 0x12f71)		// K-5 II s
+                    )
+                  {
+                    switch (table_buf[iLensData] & 0x06)
+                      {
+                      case 0: imgdata.lens.makernotes.MinAp4MinFocal = 22.0f; break;
+                      case 2: imgdata.lens.makernotes.MinAp4MinFocal = 32.0f; break;
+                      case 4: imgdata.lens.makernotes.MinAp4MinFocal = 45.0f; break;
+                      case 6: imgdata.lens.makernotes.MinAp4MinFocal = 16.0f; break;
+                      }
+                    if (table_buf[iLensData] & 0x70)
+                      imgdata.lens.makernotes.LensFStops =
+                        ((float)(((table_buf[iLensData] & 0x70) >> 4) ^ 0x07)) / 2.0f + 5.0f;
+                    if ((table_buf[iLensData+14] > 1) &&
+                        (fabs(imgdata.lens.makernotes.MaxAp4CurFocal) < 0.7f))
+                      imgdata.lens.makernotes.MaxAp4CurFocal =
+                        powf64(2.0f, (float)((table_buf[iLensData+14] & 0x7f) -1)/32.0f);
+                  }
+                else if ((imgdata.lens.makernotes.CamID != 0x12e76) &&	// K-5
+                         (table_buf[iLensData+15] > 1) &&
+                         (fabs(imgdata.lens.makernotes.MaxAp4CurFocal) < 0.7f))
+                  {
+                    imgdata.lens.makernotes.MaxAp4CurFocal =
+                      powf64(2.0f, (float)((table_buf[iLensData+15] & 0x7f) -1)/32.0f);
+                  }
+              }
+            free(table_buf);
+          }
+        else if (tag == 0x0239)		// Q-series lens info (LensInfoQ)
+          {
+            char LensInfo [20];
+            fseek (ifp, 2, SEEK_CUR);
+            fread(imgdata.lens.makernotes.Lens, 30, 1, ifp);
+            strcat(imgdata.lens.makernotes.Lens, " ");
+            fread(LensInfo, 20, 1, ifp);
+            strcat(imgdata.lens.makernotes.Lens, LensInfo);
+          }
+      }
+
+    else if (!strncmp(make, "SAMSUNG", 7) &&
+             (dng_writer == AdobeDNG))
+      {
+        if (tag == 0x0002)
+          {
+            if(get4() == 0x2000)
+              {
+                imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Samsung_NX;
+              }
+            else if (!strncmp(model, "NX mini", 7))
+              {
+                imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Samsung_NX_M;
+              }
+            else
+              {
+                imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_FixedLens;
+                imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_FixedLens;
+              }
+          }
+        else if (tag == 0x0003)
+          {
+            imgdata.lens.makernotes.CamID = unique_id = get4();
+          }
+        else if (tag == 0xa003)
+          {
+            imgdata.lens.makernotes.LensID = get2();
+            if (imgdata.lens.makernotes.LensID)
+              imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Samsung_NX;
+          }
+        else if (tag == 0xa019)
+          {
+            imgdata.lens.makernotes.CurAp = getreal(type);
+          }
+        else if (tag == 0xa01a)
+          {
+            imgdata.lens.makernotes.FocalLengthIn35mmFormat = get4() / 10.0f;
+            if (imgdata.lens.makernotes.FocalLengthIn35mmFormat < 10.0f)
+              imgdata.lens.makernotes.FocalLengthIn35mmFormat *= 10.0f;
+          }
+      }
+
+    else if (!strncasecmp(make, "SONY", 4) ||
+             !strncasecmp(make, "Konica", 6) ||
+             !strncasecmp(make, "Minolta", 7) ||
+             (!strncasecmp(make, "Hasselblad", 10) &&
+              (!strncasecmp(model, "Stellar", 7) ||
+               !strncasecmp(model, "Lunar", 5) ||
+               !strncasecmp(model, "HV",2))))
+      {
+        ushort lid;
+
+        if (tag == 0xb001)			// Sony ModelID
+          {
+            unique_id = get2();
+            setSonyBodyFeatures(unique_id);
+            if (table_buf_0x9050_present)
+              {
+                process_Sony_0x9050(table_buf_0x9050, unique_id);
+                free (table_buf_0x9050);
+                table_buf_0x9050_present = 0;
+              }
+            if (table_buf_0x940c_present)
+              {
+                if (imgdata.lens.makernotes.CameraMount == LIBRAW_MOUNT_Sony_E)
+                  {
+                    process_Sony_0x940c(table_buf_0x940c);
+                  }
+                free (table_buf_0x940c);
+                table_buf_0x940c_present = 0;
+              }
+          }
+        else if ((tag == 0x0010) &&					// CameraInfo
+                 strncasecmp(model, "DSLR-A100", 9) &&
+                 strncasecmp(model, "NEX-5C", 6) &&
+                 !strncasecmp(make, "SONY", 4) &&
+                 ((len == 368) ||			// a700
+                  (len == 5478) ||		// a850, a900
+                  (len == 5506) ||		// a200, a300, a350
+                  (len == 6118) ||		// a230, a290, a330, a380, a390
+
+                  // a450, a500, a550, a560, a580
+                  // a33, a35, a55
+                  // NEX3, NEX5, NEX5C, NEXC3, VG10E
+                  (len == 15360))
+                 )
+          {
+            table_buf = (uchar*)malloc(len);
+            fread(table_buf, len, 1, ifp);
+            if (memcmp(table_buf, "\xff\xff\xff\xff\xff\xff\xff\xff", 8) &&
+                memcmp(table_buf, "\x00\x00\x00\x00\x00\x00\x00\x00", 8))
+              {
+                switch (len) {
+                case 368:
+                case 5478:
+                  // a700, a850, a900: CameraInfo
+                  if (saneSonyCameraInfo(table_buf[0], table_buf[3], table_buf[2], table_buf[5], table_buf[4], table_buf[7]))
+                    {
+                      if (table_buf[0] | table_buf[3])
+                        imgdata.lens.makernotes.MinFocal =
+                          bcd2dec(table_buf[0]) * 100 + bcd2dec(table_buf[3]);
+                      if (table_buf[2] | table_buf[5])
+                        imgdata.lens.makernotes.MaxFocal =
+                          bcd2dec(table_buf[2]) * 100 + bcd2dec(table_buf[5]);
+                      if (table_buf[4])
+                        imgdata.lens.makernotes.MaxAp4MinFocal = bcd2dec(table_buf[4]) / 10.0f;
+                      if (table_buf[4])
+                        imgdata.lens.makernotes.MaxAp4MaxFocal = bcd2dec(table_buf[7]) / 10.0f;
+                      parseSonyLensFeatures(table_buf[1], table_buf[6]);
+                    }
+                  break;
+                default:
+                  // CameraInfo2 & 3
+                  if (saneSonyCameraInfo(table_buf[1], table_buf[2], table_buf[3], table_buf[4], table_buf[5], table_buf[6]))
+                    {
+                      if (table_buf[1] | table_buf[2])
+                        imgdata.lens.makernotes.MinFocal =
+                          bcd2dec(table_buf[1]) * 100 + bcd2dec(table_buf[2]);
+                      if (table_buf[3] | table_buf[4])
+                        imgdata.lens.makernotes.MaxFocal =
+                          bcd2dec(table_buf[3]) * 100 + bcd2dec(table_buf[4]);
+                      if (table_buf[5])
+                        imgdata.lens.makernotes.MaxAp4MinFocal = bcd2dec(table_buf[5]) / 10.0f;
+                      if (table_buf[6])
+                        imgdata.lens.makernotes.MaxAp4MaxFocal = bcd2dec(table_buf[6]) / 10.0f;
+                      parseSonyLensFeatures(table_buf[0], table_buf[7]);
+                    }
+                }
+              }
+            free(table_buf);
+          }
+
+        else if (tag == 0x0105)					// Teleconverter
+          {
+            imgdata.lens.makernotes.TeleconverterID = get2();
+          }
+
+        else if (tag == 0x0114)					// CameraSettings
+          {
+            table_buf = (uchar*)malloc(len);
+            fread(table_buf, len, 1, ifp);
+            switch (len) {
+            case 280:
+            case 364:
+            case 332:
+              // CameraSettings and CameraSettings2 are big endian
+              if (table_buf[2] | table_buf[3])
+                {
+                  lid = (((ushort)table_buf[2])<<8) |
+                    ((ushort)table_buf[3]);
+                  imgdata.lens.makernotes.CurAp =
+                    powf64(2.0f, ((float)lid/8.0f-1.0f)/2.0f);
+                }
+              break;
+            case 1536:
+            case 2048:
+              // CameraSettings3 are little endian
+              parseSonyLensType2(table_buf[1016], table_buf[1015]);
+              if (imgdata.lens.makernotes.LensMount != LIBRAW_MOUNT_Canon_EF)
+                {
+                  switch (table_buf[153]) {
+                  case 16: imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Minolta_A; break;
+                  case 17: imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Sony_E; break;
+                  }
+                }
+              break;
+            }
+            free(table_buf);
+          }
+
+        else if (tag == 0x9050)		// little endian
+          {
+            table_buf_0x9050 = (uchar*)malloc(len);
+            table_buf_0x9050_present = 1;
+            fread(table_buf_0x9050, len, 1, ifp);
+
+            if (imgdata.lens.makernotes.CamID)
+              {
+                process_Sony_0x9050(table_buf_0x9050, imgdata.lens.makernotes.CamID);
+                free (table_buf_0x9050);
+                table_buf_0x9050_present = 0;
+              }
+          }
+
+        else if (tag == 0x940c)
+          {
+            table_buf_0x940c = (uchar*)malloc(len);
+            table_buf_0x940c_present = 1;
+            fread(table_buf_0x940c, len, 1, ifp);
+            if ((imgdata.lens.makernotes.CamID) &&
+                (imgdata.lens.makernotes.CameraMount == LIBRAW_MOUNT_Sony_E))
+              {
+                process_Sony_0x940c(table_buf_0x940c);
+                free(table_buf_0x940c);
+                table_buf_0x940c_present = 0;
+              }
+          }
+
+        else if (((tag == 0xb027) || (tag == 0x010c)) && (imgdata.lens.makernotes.LensID == -1))
+          {
+            imgdata.lens.makernotes.LensID = get4();
+            if ((imgdata.lens.makernotes.LensID > 61184) &&
+                (imgdata.lens.makernotes.LensID < 65535))
+              {
+                imgdata.lens.makernotes.LensID -= 61184;
+                imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Canon_EF;
+              }
+            if (tag == 0x010c) imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Minolta_A;
+          }
+
+        else if (tag == 0xb02a)					// Sony LensSpec
+          {
+            table_buf = (uchar*)malloc(len);
+            fread(table_buf, len, 1, ifp);
+            if (saneSonyCameraInfo(table_buf[1], table_buf[2], table_buf[3], table_buf[4], table_buf[5], table_buf[6]))
+              {
+                if (table_buf[1] | table_buf[2])
+                  imgdata.lens.makernotes.MinFocal =
+                    bcd2dec(table_buf[1]) * 100 + bcd2dec(table_buf[2]);
+                if (table_buf[3] | table_buf[4])
+                  imgdata.lens.makernotes.MaxFocal =
+                    bcd2dec(table_buf[3]) * 100 + bcd2dec(table_buf[4]);
+                if (table_buf[5])
+                  imgdata.lens.makernotes.MaxAp4MinFocal = bcd2dec(table_buf[5]) / 10.0f;
+                if (table_buf[6])
+                  imgdata.lens.makernotes.MaxAp4MaxFocal = bcd2dec(table_buf[6]) / 10.0f;
+                parseSonyLensFeatures(table_buf[0], table_buf[7]);
+              }
+            free(table_buf);
+          }
+      }
+  next:
+    fseek (ifp, save, SEEK_SET);
+  }
+ quit:
+  order = sorder;
+}
+
+#else
+void CLASS parse_makernote_0xc634(int base, int uptag, unsigned dng_writer)
+{
+  /*placeholder */
+}
+#endif
+
+
 void CLASS parse_makernote (int base, int uptag)
 {
-  static const uchar xlat[2][256] = {
-  { 0xc1,0xbf,0x6d,0x0d,0x59,0xc5,0x13,0x9d,0x83,0x61,0x6b,0x4f,0xc7,0x7f,0x3d,0x3d,
-    0x53,0x59,0xe3,0xc7,0xe9,0x2f,0x95,0xa7,0x95,0x1f,0xdf,0x7f,0x2b,0x29,0xc7,0x0d,
-    0xdf,0x07,0xef,0x71,0x89,0x3d,0x13,0x3d,0x3b,0x13,0xfb,0x0d,0x89,0xc1,0x65,0x1f,
-    0xb3,0x0d,0x6b,0x29,0xe3,0xfb,0xef,0xa3,0x6b,0x47,0x7f,0x95,0x35,0xa7,0x47,0x4f,
-    0xc7,0xf1,0x59,0x95,0x35,0x11,0x29,0x61,0xf1,0x3d,0xb3,0x2b,0x0d,0x43,0x89,0xc1,
-    0x9d,0x9d,0x89,0x65,0xf1,0xe9,0xdf,0xbf,0x3d,0x7f,0x53,0x97,0xe5,0xe9,0x95,0x17,
-    0x1d,0x3d,0x8b,0xfb,0xc7,0xe3,0x67,0xa7,0x07,0xf1,0x71,0xa7,0x53,0xb5,0x29,0x89,
-    0xe5,0x2b,0xa7,0x17,0x29,0xe9,0x4f,0xc5,0x65,0x6d,0x6b,0xef,0x0d,0x89,0x49,0x2f,
-    0xb3,0x43,0x53,0x65,0x1d,0x49,0xa3,0x13,0x89,0x59,0xef,0x6b,0xef,0x65,0x1d,0x0b,
-    0x59,0x13,0xe3,0x4f,0x9d,0xb3,0x29,0x43,0x2b,0x07,0x1d,0x95,0x59,0x59,0x47,0xfb,
-    0xe5,0xe9,0x61,0x47,0x2f,0x35,0x7f,0x17,0x7f,0xef,0x7f,0x95,0x95,0x71,0xd3,0xa3,
-    0x0b,0x71,0xa3,0xad,0x0b,0x3b,0xb5,0xfb,0xa3,0xbf,0x4f,0x83,0x1d,0xad,0xe9,0x2f,
-    0x71,0x65,0xa3,0xe5,0x07,0x35,0x3d,0x0d,0xb5,0xe9,0xe5,0x47,0x3b,0x9d,0xef,0x35,
-    0xa3,0xbf,0xb3,0xdf,0x53,0xd3,0x97,0x53,0x49,0x71,0x07,0x35,0x61,0x71,0x2f,0x43,
-    0x2f,0x11,0xdf,0x17,0x97,0xfb,0x95,0x3b,0x7f,0x6b,0xd3,0x25,0xbf,0xad,0xc7,0xc5,
-    0xc5,0xb5,0x8b,0xef,0x2f,0xd3,0x07,0x6b,0x25,0x49,0x95,0x25,0x49,0x6d,0x71,0xc7 },
-  { 0xa7,0xbc,0xc9,0xad,0x91,0xdf,0x85,0xe5,0xd4,0x78,0xd5,0x17,0x46,0x7c,0x29,0x4c,
-    0x4d,0x03,0xe9,0x25,0x68,0x11,0x86,0xb3,0xbd,0xf7,0x6f,0x61,0x22,0xa2,0x26,0x34,
-    0x2a,0xbe,0x1e,0x46,0x14,0x68,0x9d,0x44,0x18,0xc2,0x40,0xf4,0x7e,0x5f,0x1b,0xad,
-    0x0b,0x94,0xb6,0x67,0xb4,0x0b,0xe1,0xea,0x95,0x9c,0x66,0xdc,0xe7,0x5d,0x6c,0x05,
-    0xda,0xd5,0xdf,0x7a,0xef,0xf6,0xdb,0x1f,0x82,0x4c,0xc0,0x68,0x47,0xa1,0xbd,0xee,
-    0x39,0x50,0x56,0x4a,0xdd,0xdf,0xa5,0xf8,0xc6,0xda,0xca,0x90,0xca,0x01,0x42,0x9d,
-    0x8b,0x0c,0x73,0x43,0x75,0x05,0x94,0xde,0x24,0xb3,0x80,0x34,0xe5,0x2c,0xdc,0x9b,
-    0x3f,0xca,0x33,0x45,0xd0,0xdb,0x5f,0xf5,0x52,0xc3,0x21,0xda,0xe2,0x22,0x72,0x6b,
-    0x3e,0xd0,0x5b,0xa8,0x87,0x8c,0x06,0x5d,0x0f,0xdd,0x09,0x19,0x93,0xd0,0xb9,0xfc,
-    0x8b,0x0f,0x84,0x60,0x33,0x1c,0x9b,0x45,0xf1,0xf0,0xa3,0x94,0x3a,0x12,0x77,0x33,
-    0x4d,0x44,0x78,0x28,0x3c,0x9e,0xfd,0x65,0x57,0x16,0x94,0x6b,0xfb,0x59,0xd0,0xc8,
-    0x22,0x36,0xdb,0xd2,0x63,0x98,0x43,0xa1,0x04,0x87,0x86,0xf7,0xa6,0x26,0xbb,0xd6,
-    0x59,0x4d,0xbf,0x6a,0x2e,0xaa,0x2b,0xef,0xe6,0x78,0xb6,0x4e,0xe0,0x2f,0xdc,0x7c,
-    0xbe,0x57,0x19,0x32,0x7e,0x2a,0xd0,0xb8,0xba,0x29,0x00,0x3c,0x52,0x7d,0xa8,0x49,
-    0x3b,0x2d,0xeb,0x25,0x49,0xfa,0xa3,0xaa,0x39,0xa7,0xc5,0xa7,0x50,0x11,0x36,0xfb,
-    0xc6,0x67,0x4a,0xf5,0xa5,0x12,0x65,0x7e,0xb0,0xdf,0xaf,0x4e,0xb3,0x61,0x7f,0x2f } };
   unsigned offset=0, entries, tag, type, len, save, c;
   unsigned ver97=0, serial=0, i, wbi=0, wb[4]={0,0,0,0};
   uchar buf97[324], ci, cj, ck;
   short morder, sorder=order;
   char buf[10];
+  unsigned SamsungKey[11];
+  static const double rgb_adobe[3][3] =		// inv(sRGB2XYZ_D65) * AdobeRGB2XYZ_D65
+    {{ 1.398283396477404,     -0.398283116703571, 4.427165001263944E-08},
+     {-1.233904514232401E-07,  0.999999995196570, 3.126724276714121e-08},
+     { 4.561487232726535E-08, -0.042938290466635, 1.042938250416105    }};
+
+  float adobe_cam [3][3];
+  uchar NikonKey;
+
+#ifdef LIBRAW_LIBRARY_BUILD
+  unsigned NikonLensDataVersion = 0;
+  unsigned lenNikonLensData = 0;
+
+  uchar *CanonCameraInfo;
+  unsigned lenCanonCameraInfo = 0;
+
+  uchar *table_buf;
+  uchar *table_buf_0x9050;
+  ushort table_buf_0x9050_present = 0;
+  uchar *table_buf_0x940c;
+  ushort table_buf_0x940c_present = 0;
+#endif
 /*
    The MakerNote might have its own TIFF header (possibly with
    its own byte-order!), or it might just be a table.
@@ -4563,46 +8473,815 @@ void CLASS parse_makernote (int base, int uptag)
     if (get2() != 42) goto quit;
     offset = get4();
     fseek (ifp, offset-8, SEEK_CUR);
-  } else if (!strcmp (buf,"OLYMPUS")) {
+  } else if (!strcmp (buf,"OLYMPUS") ||
+             !strcmp (buf,"PENTAX ")) {
     base = ftell(ifp)-10;
     fseek (ifp, -2, SEEK_CUR);
-    order = get2();  get2();
+    order = get2();
+    if (buf[0] == 'O') get2();
   } else if (!strncmp (buf,"SONY",4) ||
-	     !strcmp  (buf,"Panasonic")) {
+						 !strcmp  (buf,"Panasonic")) {
     goto nf;
   } else if (!strncmp (buf,"FUJIFILM",8)) {
     base = ftell(ifp)-10;
-nf: order = 0x4949;
+	nf: order = 0x4949;
     fseek (ifp,  2, SEEK_CUR);
   } else if (!strcmp (buf,"OLYMP") ||
-	     !strcmp (buf,"LEICA") ||
-	     !strcmp (buf,"Ricoh") ||
-	     !strcmp (buf,"EPSON"))
+						 !strcmp (buf,"LEICA") ||
+						 !strcmp (buf,"Ricoh") ||
+						 !strcmp (buf,"EPSON"))
     fseek (ifp, -2, SEEK_CUR);
   else if (!strcmp (buf,"AOC") ||
-	   !strcmp (buf,"QVC"))
+					 !strcmp (buf,"QVC"))
     fseek (ifp, -4, SEEK_CUR);
   else {
     fseek (ifp, -10, SEEK_CUR);
     if (!strncmp(make,"SAMSUNG",7))
       base = ftell(ifp);
   }
+
+  // adjust pos & base for Leica M8/M9/M Mono tags and dir in tag 0x3400
+  if (!strncasecmp(make, "LEICA", 5))
+    {
+      if (!strncmp(model, "M8", 2) ||
+          !strncasecmp(model, "Leica M8", 8) ||
+          !strncasecmp(model, "LEICA X", 7))
+        {
+          base = ftell(ifp)-8;
+        }
+      else if (!strncasecmp(model, "LEICA M (Typ 240)", 17))
+        {
+          base = 0;
+        }
+      else if (!strncmp(model, "M9", 2) ||
+               !strncasecmp(model, "Leica M9", 8) ||
+               !strncasecmp(model, "M Monochrom", 11) ||
+               !strncasecmp(model, "Leica M Monochrom", 11))
+        {
+          if (!uptag)
+            {
+              base = ftell(ifp) - 10;
+              fseek (ifp, 8, SEEK_CUR);
+            }
+          else if (uptag == 0x3400)
+            {
+              fseek (ifp, 10, SEEK_CUR);
+              base += 10;
+            }
+        }
+      else if (!strncasecmp(model, "LEICA T", 7))
+      	{
+      	  base = ftell(ifp)-8;
+#ifdef LIBRAW_LIBRARY_BUILD
+      	  imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Leica_T;
+#endif
+      	}
+    }
+
   entries = get2();
+
+//  printf("\n*** parse_makernote\n\tmake  =%s=\n\tmodel =%s= \n\tentries: %d\n\tpos: 0x%llx\n",
+//    make, model, entries, ftell(ifp));
+
   if (entries > 1000) return;
   morder = order;
   while (entries--) {
     order = morder;
     tiff_get (base, &tag, &type, &len, &save);
     tag |= uptag << 16;
+
+// 	printf ("\n\tbase: 0x%x tag: 0x%04x type: 0x%x len: 0x%x pos: 0x%llx",
+// 		base, tag, type, len, ftell(ifp));
+
+#ifdef LIBRAW_LIBRARY_BUILD
+
+    if (!strcmp(make, "Canon"))
+      {
+        if (tag == 0x0001)				// camera settings
+          {
+            fseek(ifp, 44, SEEK_CUR);
+            imgdata.lens.makernotes.LensID = get2();
+            imgdata.lens.makernotes.MaxFocal = get2();
+            imgdata.lens.makernotes.MinFocal = get2();
+            imgdata.lens.makernotes.CanonFocalUnits = get2();
+            if (imgdata.lens.makernotes.CanonFocalUnits != 1)
+              {
+                imgdata.lens.makernotes.MaxFocal /= (float)imgdata.lens.makernotes.CanonFocalUnits;
+                imgdata.lens.makernotes.MinFocal /= (float)imgdata.lens.makernotes.CanonFocalUnits;
+              }
+            imgdata.lens.makernotes.MaxAp = _CanonConvertAperture(get2());
+            imgdata.lens.makernotes.MinAp = _CanonConvertAperture(get2());
+          }
+
+        else if (tag == 0x0002)			// focal length
+          {
+            imgdata.lens.makernotes.FocalType = get2();
+            imgdata.lens.makernotes.CurFocal = get2();
+            if ((imgdata.lens.makernotes.CanonFocalUnits != 1) &&
+                imgdata.lens.makernotes.CanonFocalUnits)
+              {
+                imgdata.lens.makernotes.CurFocal /= (float)imgdata.lens.makernotes.CanonFocalUnits;
+              }
+          }
+
+        else if (tag == 0x0004)			// shot info
+          {
+            fseek(ifp, 42, SEEK_CUR);
+            imgdata.lens.makernotes.CurAp = _CanonConvertAperture(get2());
+          }
+
+        else if (tag == 0x000d)			// camera info
+          {
+            CanonCameraInfo = (uchar*)malloc(len);
+            fread(CanonCameraInfo, len, 1, ifp);
+            lenCanonCameraInfo = len;
+          }
+
+        else if (tag == 0x0095 &&		// lens model tag
+                 !imgdata.lens.makernotes.Lens[0])
+          {
+            fread(imgdata.lens.makernotes.Lens, 2, 1, ifp);
+            imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Canon_EF;
+            if (imgdata.lens.makernotes.Lens[0] < 65)					// non-Canon lens
+              fread(imgdata.lens.makernotes.Lens + 2, 62, 1, ifp);
+            else
+              {
+                char efs[2];
+                imgdata.lens.makernotes.LensFeatures_pre[0] = imgdata.lens.makernotes.Lens[0];
+                imgdata.lens.makernotes.LensFeatures_pre[1] = imgdata.lens.makernotes.Lens[1];
+                fread(efs, 2, 1, ifp);
+                if (efs[0] == 45 && (efs[1] == 83 || efs[1] == 69 || efs[1] == 77))
+                  {	// "EF-S, TS-E, MP-E, EF-M" lenses
+                    imgdata.lens.makernotes.Lens[2] = imgdata.lens.makernotes.LensFeatures_pre[2] = efs[0];
+                    imgdata.lens.makernotes.Lens[3] = imgdata.lens.makernotes.LensFeatures_pre[3] = efs[1];
+                    imgdata.lens.makernotes.Lens[4] = 32;
+                    if (efs[1] == 83)
+                      {
+                        imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Canon_EF_S;
+                        imgdata.lens.makernotes.LensFormat = LIBRAW_FORMAT_APSC;
+                      }
+                    else if (efs[1] == 77)
+                      {
+                        imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Canon_EF_M;
+                      }
+                  }
+                else
+                  {																// "EF" lenses
+                    imgdata.lens.makernotes.Lens[2] = 32;
+                    imgdata.lens.makernotes.Lens[3] = efs[0];
+                    imgdata.lens.makernotes.Lens[4] = efs[1];
+                  }
+                fread(imgdata.lens.makernotes.Lens + 5, 58, 1, ifp);
+              }
+          }
+      }
+
+    else if (!strncmp(make, "FUJI", 4))
+      switch (tag) {
+      case 0x1404: imgdata.lens.makernotes.MinFocal = getreal(type); break;
+      case 0x1405: imgdata.lens.makernotes.MaxFocal = getreal(type); break;
+      case 0x1406: imgdata.lens.makernotes.MaxAp4MinFocal = getreal(type); break;
+      case 0x1407: imgdata.lens.makernotes.MaxAp4MaxFocal = getreal(type); break;
+      }
+
+    else if (!strncasecmp(make, "LEICA", 5))
+      {
+        if ((tag == 0x0303) && (type != 4))
+          {
+            fread(imgdata.lens.makernotes.Lens, len, 1, ifp);
+          }
+
+        if ((tag == 0x3405) ||
+            (tag == 0x0310) ||
+            (tag == 0x34003405))
+          {
+            imgdata.lens.makernotes.LensID = get4();
+            imgdata.lens.makernotes.LensID =
+              ((imgdata.lens.makernotes.LensID>>2)<<8) |
+              (imgdata.lens.makernotes.LensID & 0x3);
+            if (imgdata.lens.makernotes.LensID != -1)
+              {
+                if ((model[0] == 'M') ||
+                    !strncasecmp (model, "LEICA M", 7))
+                  {
+                    imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Leica_M;
+                    if (imgdata.lens.makernotes.LensID)
+                    imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Leica_M;
+                  }
+                else if ((model[0] == 'S') ||
+                         !strncasecmp (model, "LEICA S", 7))
+                  {
+                    imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Leica_S;
+                    if (imgdata.lens.makernotes.Lens[0])
+                    imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Leica_S;
+                  }
+              }
+          }
+
+        else if (
+                 ((tag == 0x0313) || (tag == 0x34003406)) &&
+                 (fabs(imgdata.lens.makernotes.CurAp) < 0.17f) &&
+                 ((type == 10) || (type == 5))
+                 )
+          {
+            imgdata.lens.makernotes.CurAp = getreal(type);
+            if (imgdata.lens.makernotes.CurAp > 126.3)
+              imgdata.lens.makernotes.CurAp = 0.0f;
+          }
+
+        else if (tag == 0x3400)
+          {
+            parse_makernote (base, 0x3400);
+          }
+      }
+
+    else if (!strncmp(make, "NIKON",5))
+      {
+        if (tag == 0x0082)						// lens attachment
+          {
+            fread(imgdata.lens.makernotes.Attachment, len, 1, ifp);
+          }
+        else if (tag == 0x0083)				// lens type
+          {
+            imgdata.lens.nikon.NikonLensType = fgetc(ifp);
+            if (!(imgdata.lens.nikon.NikonLensType & 0x01))
+              {
+                imgdata.lens.makernotes.LensFeatures_pre[0] = 'A';
+                imgdata.lens.makernotes.LensFeatures_pre[1] = 'F';
+              }
+            if (imgdata.lens.nikon.NikonLensType & 0x02)
+              {
+                if (imgdata.lens.nikon.NikonLensType & 0x04)
+                  imgdata.lens.makernotes.LensFeatures_suf[0] = 'G';
+                else
+                  imgdata.lens.makernotes.LensFeatures_suf[0] = 'D';
+                imgdata.lens.makernotes.LensFeatures_suf[1] = ' ';
+              }
+            if (imgdata.lens.nikon.NikonLensType & 0x08)
+              {
+                imgdata.lens.makernotes.LensFeatures_suf[2] = 'V';
+                imgdata.lens.makernotes.LensFeatures_suf[3] = 'R';
+              }
+            if (imgdata.lens.nikon.NikonLensType & 0x10)
+              {
+                imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Nikon_CX;
+              }
+            if (imgdata.lens.nikon.NikonLensType & 0x20)
+              {
+                strcpy(imgdata.lens.makernotes.Adapter, "FT-1");
+              }
+            imgdata.lens.nikon.NikonLensType = imgdata.lens.nikon.NikonLensType & 0xdf;
+          }
+        else if (tag == 0x0084)				// lens
+          {
+            imgdata.lens.makernotes.MinFocal = getreal(type);
+            imgdata.lens.makernotes.MaxFocal = getreal(type);
+            imgdata.lens.makernotes.MaxAp4MinFocal = getreal(type);
+            imgdata.lens.makernotes.MaxAp4MaxFocal = getreal(type);
+          }
+        else if (tag == 0x008b)				// lens f-stops
+          {
+            uchar a, b, c;
+            a = fgetc(ifp);
+            b = fgetc(ifp);
+            c = fgetc(ifp);
+            if (c)
+              {
+                imgdata.lens.nikon.NikonLensFStops = a*b*(12/c);
+                imgdata.lens.makernotes.LensFStops =
+                  (float)imgdata.lens.nikon.NikonLensFStops /12.0f;
+              }
+          }
+        else if (tag == 0x0098)				// contains lens data
+          {
+            for (i = 0; i < 4; i++)
+              {
+                NikonLensDataVersion = NikonLensDataVersion * 10 + fgetc(ifp) - '0';
+              }
+            switch (NikonLensDataVersion)
+              {
+              case 100: lenNikonLensData = 9; imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Nikon_F; break;
+              case 101:
+              case 201:	// encrypted, starting from v.201
+              case 202:
+              case 203: lenNikonLensData = 15; imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Nikon_F; break;
+              case 204: lenNikonLensData = 16; imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Nikon_F; break;
+              case 400: lenNikonLensData = 459; break;
+              case 401: lenNikonLensData = 590; break;
+              case 402: lenNikonLensData = 509; break;
+              case 403: lenNikonLensData = 879; break;
+              }
+            table_buf = (uchar*)malloc(lenNikonLensData);
+            fread(table_buf, lenNikonLensData, 1, ifp);
+            if ((NikonLensDataVersion < 201) && lenNikonLensData)
+            {
+              processNikonLensData(table_buf, lenNikonLensData);
+              lenNikonLensData = 0;
+            }
+          }
+      }
+
+    else if (!strncmp(make, "OLYMPUS", 7))
+      {
+        switch (tag) {
+        case 0x0207:
+        case 0x20100100:
+          {
+            uchar sOlyID[7];
+            long unsigned OlyID;
+            fread (sOlyID, len, 1, ifp);
+            OlyID = sOlyID[0];
+            i = 1;
+            while (sOlyID[i])
+              {
+                OlyID = OlyID << 8 | sOlyID[i];
+                i++;
+              }
+            setOlympusBodyFeatures(OlyID);
+          }
+          break;
+        case 0x1002:
+          imgdata.lens.makernotes.CurAp = powf64(2.0f, getreal(type)/2);
+          break;
+        case 0x20100201:
+          imgdata.lens.makernotes.LensID =
+            (unsigned long long)fgetc(ifp)<<16 |
+            (unsigned long long)(fgetc(ifp), fgetc(ifp))<<8 |
+            (unsigned long long)fgetc(ifp);
+          imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_FT;
+          imgdata.lens.makernotes.LensFormat = LIBRAW_FORMAT_FT;
+          if (((imgdata.lens.makernotes.LensID < 0x20000) ||
+               (imgdata.lens.makernotes.LensID > 0x4ffff)) &&
+              (imgdata.lens.makernotes.LensID & 0x10))
+            {
+              imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_mFT;
+            }
+          break;
+        case 0x20100203:
+          fread(imgdata.lens.makernotes.Lens, len, 1, ifp);
+          break;
+        case 0x20100205:
+          imgdata.lens.makernotes.MaxAp4MinFocal = powf64(sqrt(2.0f), get2() / 256.0f);
+          break;
+        case 0x20100206:
+          imgdata.lens.makernotes.MaxAp4MaxFocal = powf64(sqrt(2.0f), get2() / 256.0f);
+          break;
+        case 0x20100207:
+          imgdata.lens.makernotes.MinFocal = (float)get2();
+          break;
+        case 0x20100208:
+          imgdata.lens.makernotes.MaxFocal = (float)get2();
+          if (imgdata.lens.makernotes.MaxFocal > 1000.0f)
+            imgdata.lens.makernotes.MaxFocal = imgdata.lens.makernotes.MinFocal;
+          break;
+        case 0x2010020a:
+          imgdata.lens.makernotes.MaxAp4CurFocal = powf64(sqrt(2.0f), get2() / 256.0f);
+          break;
+        case 0x20100301:
+          imgdata.lens.makernotes.TeleconverterID = fgetc(ifp) << 8;
+          fgetc(ifp);
+          imgdata.lens.makernotes.TeleconverterID =
+            imgdata.lens.makernotes.TeleconverterID | fgetc(ifp);
+          break;
+        case 0x20100303:
+          fread(imgdata.lens.makernotes.Teleconverter, len, 1, ifp);
+          break;
+        case 0x20100403:
+          fread(imgdata.lens.makernotes.Attachment, len, 1, ifp);
+          break;
+        }
+      }
+
+    else if (!strncmp(make, "PENTAX", 6) &&
+             !strncmp(model, "GR", 2))
+      {
+        if ((tag == 0x1001) && (type == 3))
+          {
+            imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_FixedLens;
+            imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_FixedLens;
+            imgdata.lens.makernotes.CameraFormat = LIBRAW_FORMAT_APSC;
+            imgdata.lens.makernotes.LensID = -1;
+            imgdata.lens.makernotes.FocalType = 1;
+          }
+        else if ((tag == 0x1017) && (get2() == 2))
+          {
+            strcpy(imgdata.lens.makernotes.Attachment, "Wide-Angle Adapter");
+          }
+        else if (tag == 0x1500)
+          {
+            imgdata.lens.makernotes.CurFocal = getreal(type);
+          }
+      }
+
+    else if (!strncmp(make, "RICOH", 5) &&
+             strncmp(model, "PENTAX", 6))
+      {
+        if ((tag == 0x1017) && (get2() == 2))
+          {
+            strcpy(imgdata.lens.makernotes.Attachment, "Wide-Angle Adapter");
+          }
+
+        else if (tag == 0x1500)
+          {
+            imgdata.lens.makernotes.CurFocal = getreal(type);
+          }
+
+        else if (tag == 0x2001)
+          {
+            short ntags, cur_tag;
+            fseek(ifp, 20, SEEK_CUR);
+            ntags = get2();
+            cur_tag = get2();
+            while (cur_tag != 0x002c)
+              {
+                fseek(ifp, 10, SEEK_CUR);
+                cur_tag = get2();
+              }
+            fseek(ifp, 6, SEEK_CUR);
+            fseek(ifp, get4()+34, SEEK_SET);
+            imgdata.lens.makernotes.LensID = getc(ifp) - '0';
+            switch(imgdata.lens.makernotes.LensID)
+              {
+            	case 1:
+            	case 2:
+            	case 3:
+            	case 5:
+            	case 6:
+            		imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_FixedLens;
+                        imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_RicohModule;
+                break;
+              case 8:
+                imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Leica_M;
+                imgdata.lens.makernotes.CameraFormat = LIBRAW_FORMAT_APSC;
+                imgdata.lens.makernotes.LensID = -1;
+                break;
+              default:
+              	imgdata.lens.makernotes.LensID = -1;
+              }
+          }
+      }
+
+    else if (!strncmp(make, "PENTAX", 6) ||
+             !strncmp(model, "PENTAX", 6) ||
+             (!strncmp(make, "SAMSUNG", 7) && dng_version) &&
+             strncmp(model, "GR", 2))
+      {
+        if (tag == 0x0005)
+          {
+            unique_id = get4();
+            setPentaxBodyFeatures(unique_id);
+          }
+        else if (tag == 0x0013)
+          {
+            imgdata.lens.makernotes.CurAp = (float)get2()/10.0f;
+          }
+        else if (tag == 0x001d)
+          {
+            imgdata.lens.makernotes.CurFocal = (float)get4()/100.0f;
+          }
+        else if (tag == 0x003f)
+          {
+            imgdata.lens.makernotes.LensID = fgetc(ifp) << 8 | fgetc(ifp);
+          }
+        else if (tag == 0x0207)
+          {
+            ushort iLensData = 0;
+            table_buf = (uchar*)malloc(len);
+            fread(table_buf, len, 1, ifp);
+            if ((imgdata.lens.makernotes.CamID < 0x12b9c) ||
+                ((imgdata.lens.makernotes.CamID == 0x12b9c) ||	// K100D
+                 (imgdata.lens.makernotes.CamID == 0x12b9d) ||	// K110D
+                 (imgdata.lens.makernotes.CamID == 0x12ba2)	&&	// K100D Super
+                 (!table_buf[20] || (table_buf[20] == 0xff))))
+              {
+                iLensData = 3;
+                if (imgdata.lens.makernotes.LensID == -1)
+                  imgdata.lens.makernotes.LensID =
+                    (((unsigned)table_buf[0]) << 8) + table_buf[1];
+              }
+            else switch (len)
+              {
+              case 90:							// LensInfo3
+                iLensData = 13;
+                if (imgdata.lens.makernotes.LensID == -1)
+                  imgdata.lens.makernotes.LensID =
+                    ((unsigned)((table_buf[1] & 0x0f) + table_buf[3]) <<8) + table_buf[4];
+                break;
+              case 91:							// LensInfo4
+                iLensData = 12;
+                if (imgdata.lens.makernotes.LensID == -1)
+                  imgdata.lens.makernotes.LensID =
+                    ((unsigned)((table_buf[1] & 0x0f) + table_buf[3]) <<8) + table_buf[4];
+                break;
+              case 80:							// LensInfo5
+              case 128:
+                iLensData = 15;
+                if (imgdata.lens.makernotes.LensID == -1)
+                  imgdata.lens.makernotes.LensID =
+                    ((unsigned)((table_buf[1] & 0x0f) + table_buf[4]) <<8) + table_buf[5];
+                break;
+              default:
+                if (imgdata.lens.makernotes.CamID >= 0x12b9c)		// LensInfo2
+                  {
+                    iLensData = 4;
+                    if (imgdata.lens.makernotes.LensID == -1)
+                      imgdata.lens.makernotes.LensID =
+                        ((unsigned)((table_buf[0] & 0x0f) + table_buf[2]) <<8) + table_buf[3];
+                  }
+              }
+            if (iLensData)
+              {
+                if (table_buf[iLensData+9] && (fabs(imgdata.lens.makernotes.CurFocal) < 0.1f))
+                  imgdata.lens.makernotes.CurFocal =
+                    10*(table_buf[iLensData+9]>>2) * powf64(4, (table_buf[iLensData+9] & 0x03)-2);
+                if (table_buf[iLensData+10] & 0xf0)
+                  imgdata.lens.makernotes.MaxAp4CurFocal =
+                    powf64(2.0f, (float)((table_buf[iLensData+10] & 0xf0) >>4)/4.0f);
+                if (table_buf[iLensData+10] & 0x0f)
+                  imgdata.lens.makernotes.MinAp4CurFocal =
+                    powf64(2.0f, (float)((table_buf[iLensData+10] & 0x0f) + 10)/4.0f);
+                if (
+                    (imgdata.lens.makernotes.CamID != 0x12e6c) &&	// K-r
+                    (imgdata.lens.makernotes.CamID != 0x12e76) &&	// K-5
+                    (imgdata.lens.makernotes.CamID != 0x12f70)		// K-5 II
+                    //        	  		(imgdata.lens.makernotes.CamID != 0x12f71)		// K-5 II s
+                    )
+                  {
+                    switch (table_buf[iLensData] & 0x06)
+                      {
+                      case 0: imgdata.lens.makernotes.MinAp4MinFocal = 22.0f; break;
+                      case 2: imgdata.lens.makernotes.MinAp4MinFocal = 32.0f; break;
+                      case 4: imgdata.lens.makernotes.MinAp4MinFocal = 45.0f; break;
+                      case 6: imgdata.lens.makernotes.MinAp4MinFocal = 16.0f; break;
+                      }
+                    if (table_buf[iLensData] & 0x70)
+                      imgdata.lens.makernotes.LensFStops =
+                        ((float)(((table_buf[iLensData] & 0x70) >> 4) ^ 0x07)) / 2.0f + 5.0f;
+                    if ((table_buf[iLensData+14] > 1) &&
+                        (fabs(imgdata.lens.makernotes.MaxAp4CurFocal) < 0.7f))
+                      imgdata.lens.makernotes.MaxAp4CurFocal =
+                        powf64(2.0f, (float)((table_buf[iLensData+14] & 0x7f) -1)/32.0f);
+                  }
+                else if ((imgdata.lens.makernotes.CamID != 0x12e76) &&	// K-5
+                         (table_buf[iLensData+15] > 1) &&
+                         (fabs(imgdata.lens.makernotes.MaxAp4CurFocal) < 0.7f))
+                  {
+                    imgdata.lens.makernotes.MaxAp4CurFocal =
+                      powf64(2.0f, (float)((table_buf[iLensData+15] & 0x7f) -1)/32.0f);
+                  }
+              }
+            free(table_buf);
+          }
+        else if (tag == 0x0239)		// Q-series lens info (LensInfoQ)
+          {
+            char LensInfo [20];
+            fseek (ifp, 2, SEEK_CUR);
+            fread(imgdata.lens.makernotes.Lens, 30, 1, ifp);
+            strcat(imgdata.lens.makernotes.Lens, " ");
+            fread(LensInfo, 20, 1, ifp);
+            strcat(imgdata.lens.makernotes.Lens, LensInfo);
+          }
+      }
+
+    else if (!strncmp(make, "SAMSUNG", 7))
+      {
+        if (tag == 0x0002)
+          {
+            if(get4() == 0x2000)
+              {
+                imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Samsung_NX;
+              }
+            else if (!strncmp(model, "NX mini", 7))
+              {
+                imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Samsung_NX_M;
+              }
+            else
+              {
+                imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_FixedLens;
+                imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_FixedLens;
+              }
+          }
+        else if (tag == 0x0003)
+          {
+            unique_id = imgdata.lens.makernotes.CamID = get4();
+          }
+        else if (tag == 0xa003)
+          {
+            imgdata.lens.makernotes.LensID = get2();
+            if (imgdata.lens.makernotes.LensID)
+              imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Samsung_NX;
+          }
+        else if (tag == 0xa019)
+          {
+            imgdata.lens.makernotes.CurAp = getreal(type);
+          }
+        else if (tag == 0xa01a)
+          {
+            imgdata.lens.makernotes.FocalLengthIn35mmFormat = get4() / 10.0f;
+            if (imgdata.lens.makernotes.FocalLengthIn35mmFormat < 10.0f)
+              imgdata.lens.makernotes.FocalLengthIn35mmFormat *= 10.0f;
+          }
+      }
+
+    else if (!strncasecmp(make, "SONY", 4) ||
+             !strncasecmp(make, "Konica", 6) ||
+             !strncasecmp(make, "Minolta", 7) ||
+             (!strncasecmp(make, "Hasselblad", 10) &&
+              (!strncasecmp(model, "Stellar", 7) ||
+               !strncasecmp(model, "Lunar", 5) ||
+               !strncasecmp(model, "HV",2))))
+      {
+        ushort lid;
+
+        if (tag == 0xb001)			// Sony ModelID
+        {
+          unique_id = get2();
+          setSonyBodyFeatures(unique_id);
+          if (table_buf_0x9050_present)
+            {
+              process_Sony_0x9050(table_buf_0x9050, unique_id);
+              free (table_buf_0x9050);
+              table_buf_0x9050_present = 0;
+            }
+          if (table_buf_0x940c_present)
+            {
+              if (imgdata.lens.makernotes.CameraMount == LIBRAW_MOUNT_Sony_E)
+                {
+                  process_Sony_0x940c(table_buf_0x940c);
+                }
+              free (table_buf_0x940c);
+              table_buf_0x940c_present = 0;
+            }
+        }
+
+        else if ((tag == 0x0010) &&					// CameraInfo
+                 strncasecmp(model, "DSLR-A100", 9) &&
+                 strncasecmp(model, "NEX-5C", 6) &&
+                 !strncasecmp(make, "SONY", 4) &&
+                 ((len == 368) ||			// a700
+                  (len == 5478) ||		// a850, a900
+                  (len == 5506) ||		// a200, a300, a350
+                  (len == 6118) ||		// a230, a290, a330, a380, a390
+
+                  // a450, a500, a550, a560, a580
+                  // a33, a35, a55
+                  // NEX3, NEX5, NEX5C, NEXC3, VG10E
+                  (len == 15360))
+                 )
+          {
+            table_buf = (uchar*)malloc(len);
+            fread(table_buf, len, 1, ifp);
+            if (memcmp(table_buf, "\xff\xff\xff\xff\xff\xff\xff\xff", 8) &&
+                memcmp(table_buf, "\x00\x00\x00\x00\x00\x00\x00\x00", 8))
+              {
+                switch (len)
+                  {
+                  case 368:
+                  case 5478:
+                    // a700, a850, a900: CameraInfo
+                    if (table_buf[0] | table_buf[3])
+                      imgdata.lens.makernotes.MinFocal =
+                        bcd2dec(table_buf[0]) * 100 + bcd2dec(table_buf[3]);
+                    if (table_buf[2] | table_buf[5])
+                      imgdata.lens.makernotes.MaxFocal =
+                        bcd2dec(table_buf[2]) * 100 + bcd2dec(table_buf[5]);
+                    if (table_buf[4])
+                      imgdata.lens.makernotes.MaxAp4MinFocal = bcd2dec(table_buf[4]) / 10.0f;
+                    if (table_buf[4])
+                      imgdata.lens.makernotes.MaxAp4MaxFocal = bcd2dec(table_buf[7]) / 10.0f;
+                    parseSonyLensFeatures(table_buf[1], table_buf[6]);
+                    break;
+                  default:
+                    // CameraInfo2 & 3
+                    if (table_buf[1] | table_buf[2])
+                      imgdata.lens.makernotes.MinFocal =
+                        bcd2dec(table_buf[1]) * 100 + bcd2dec(table_buf[2]);
+                    if (table_buf[3] | table_buf[4])
+                      imgdata.lens.makernotes.MaxFocal =
+                        bcd2dec(table_buf[3]) * 100 + bcd2dec(table_buf[4]);
+                    if (table_buf[5])
+                      imgdata.lens.makernotes.MaxAp4MinFocal = bcd2dec(table_buf[5]) / 10.0f;
+                    if (table_buf[6])
+                      imgdata.lens.makernotes.MaxAp4MaxFocal = bcd2dec(table_buf[6]) / 10.0f;
+                    parseSonyLensFeatures(table_buf[0], table_buf[7]);
+                }
+              }
+            free(table_buf);
+          }
+
+        else if (tag == 0x0105)					// Teleconverter
+          {
+            imgdata.lens.makernotes.TeleconverterID = get2();
+          }
+
+        else if (tag == 0x0114)					// CameraSettings
+          {
+            table_buf = (uchar*)malloc(len);
+            fread(table_buf, len, 1, ifp);
+            switch (len) {
+            case 280:
+            case 364:
+            case 332:
+              // CameraSettings and CameraSettings2 are big endian
+              if (table_buf[2] | table_buf[3])
+                {
+                  lid = (((ushort)table_buf[2])<<8) |
+                    ((ushort)table_buf[3]);
+                  imgdata.lens.makernotes.CurAp =
+                    powf64(2.0f, ((float)lid/8.0f-1.0f)/2.0f);
+                }
+              break;
+            case 1536:
+            case 2048:
+              // CameraSettings3 are little endian
+              parseSonyLensType2(table_buf[1016], table_buf[1015]);
+              if (imgdata.lens.makernotes.LensMount != LIBRAW_MOUNT_Canon_EF)
+                {
+                  switch (table_buf[153]) {
+                  case 16: imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Minolta_A; break;
+                  case 17: imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Sony_E; break;
+                  }
+                }
+              break;
+            }
+            free(table_buf);
+          }
+
+        else if (tag == 0x9050)		// little endian
+          {
+            table_buf_0x9050 = (uchar*)malloc(len);
+            table_buf_0x9050_present = 1;
+            fread(table_buf_0x9050, len, 1, ifp);
+
+            if (imgdata.lens.makernotes.CamID)
+              {
+                process_Sony_0x9050(table_buf_0x9050, imgdata.lens.makernotes.CamID);
+                free (table_buf_0x9050);
+                table_buf_0x9050_present = 0;
+              }
+          }
+
+        else if (tag == 0x940c)
+          {
+            table_buf_0x940c = (uchar*)malloc(len);
+            table_buf_0x940c_present = 1;
+            fread(table_buf_0x940c, len, 1, ifp);
+            if ((imgdata.lens.makernotes.CamID) &&
+                (imgdata.lens.makernotes.CameraMount == LIBRAW_MOUNT_Sony_E))
+              {
+                process_Sony_0x940c(table_buf_0x940c);
+                free(table_buf_0x940c);
+                table_buf_0x940c_present = 0;
+              }
+          }
+
+        else if (((tag == 0xb027) || (tag == 0x010c)) && (imgdata.lens.makernotes.LensID == -1))
+          {
+            imgdata.lens.makernotes.LensID = get4();
+            if ((imgdata.lens.makernotes.LensID > 61184) &&
+                (imgdata.lens.makernotes.LensID < 65535))
+              {
+                imgdata.lens.makernotes.LensID -= 61184;
+                imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Canon_EF;
+              }
+            if (tag == 0x010c) imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Minolta_A;
+          }
+
+        else if (tag == 0xb02a)					// Sony LensSpec
+          {
+            table_buf = (uchar*)malloc(len);
+            fread(table_buf, len, 1, ifp);
+            if (table_buf[1] | table_buf[2])
+              imgdata.lens.makernotes.MinFocal =
+                bcd2dec(table_buf[1]) * 100 + bcd2dec(table_buf[2]);
+            if (table_buf[3] | table_buf[4])
+              imgdata.lens.makernotes.MaxFocal =
+                bcd2dec(table_buf[3]) * 100 + bcd2dec(table_buf[4]);
+            if (table_buf[5])
+              imgdata.lens.makernotes.MaxAp4MinFocal = bcd2dec(table_buf[5]) / 10.0f;
+            if (table_buf[6])
+              imgdata.lens.makernotes.MaxAp4MaxFocal = bcd2dec(table_buf[6]) / 10.0f;
+            parseSonyLensFeatures(table_buf[0], table_buf[7]);
+            free(table_buf);
+          }
+      }
+#endif
+
     if (tag == 2 && strstr(make,"NIKON") && !iso_speed)
       iso_speed = (get2(),get2());
+    if (tag == 37 && strstr(make,"NIKON") && (!iso_speed || iso_speed == 65535))
+      {
+        unsigned char cc;
+        fread(&cc,1,1,ifp);
+        iso_speed = int(100.0 * powf64(2.0f,float(cc)/12.0-5.0));
+      }
     if (tag == 4 && len > 26 && len < 35) {
-      if ((i=(get4(),get2())) != 0x7fff && !iso_speed)
-	iso_speed = 50 * pow (2, i/32.0 - 4);
+      if ((i=(get4(),get2())) != 0x7fff && (!iso_speed || iso_speed == 65535))
+	iso_speed = 50 * powf64(2.0, i/32.0 - 4);
       if ((i=(get2(),get2())) != 0x7fff && !aperture)
-	aperture = pow (2, i/64.0);
+	aperture = powf64(2.0, i/64.0);
       if ((i=get2()) != 0xffff && !shutter)
-	shutter = pow (2, (short) i/-32.0);
+	shutter = powf64(2.0, (short) i/-32.0);
       wbi = (get2(),get2());
       shot_order = (get2(),get2());
     }
@@ -4620,10 +9299,8 @@ nf: order = 0x4949;
       shot_order = get4();
     if (tag == 9 && !strcmp(make,"Canon"))
       fread (artist, 64, 1, ifp);
-    if (tag == 0xc && len == 4) {
-      cam_mul[0] = getreal(type);
-      cam_mul[2] = getreal(type);
-    }
+    if (tag == 0xc && len == 4)
+      FORC3 cam_mul[(c << 1 | c >> 1) & 3] = getreal(type);
     if (tag == 0xd && type == 7 && get2() == 0xaaaa) {
       for (c=i=2; (ushort) c != 0xbbbb && i < len; i++)
 	c = c << 8 | fgetc(ifp);
@@ -4631,8 +9308,110 @@ nf: order = 0x4949;
 	if (get4() == 257 && (i=len) && (c = (get4(),fgetc(ifp))) < 3)
 	  flip = "065"[c]-'0';
     }
+
     if (tag == 0x10 && type == 4)
-      unique_id = get4();
+      {
+        unique_id = get4();
+
+#ifdef LIBRAW_LIBRARY_BUILD
+        setCanonBodyFeatures(unique_id);
+        if (lenCanonCameraInfo) processCanonCameraInfo(unique_id, CanonCameraInfo);
+#endif
+      }
+
+#ifdef LIBRAW_LIBRARY_BUILD
+    if(tag == 0x20400805 && len == 2 && !strncasecmp(make,"Olympus",7))
+      {
+        imgdata.color.OlympusSensorCalibration[0]=getreal(type);
+        imgdata.color.OlympusSensorCalibration[1]=getreal(type);
+      }
+    if (tag == 0x4001 && len > 500 && !strcasecmp(make,"Canon"))
+      {
+        long int save1 = ftell(ifp);
+        switch (len)
+          {
+          case 582:
+            imgdata.color.canon_makernotes.CanonColorDataVer = 1;	// 20D / 350D
+            break;
+          case 653:
+            imgdata.color.canon_makernotes.CanonColorDataVer = 2;	// 1Dmk2 / 1DsMK2
+            break;
+          case 796:
+            imgdata.color.canon_makernotes.CanonColorDataVer = 3;	// 1DmkIIN / 5D / 30D / 400D
+
+            // 1DmkIII / 1DSmkIII / 1DmkIV / 5DmkII
+            // 7D / 40D / 50D / 60D / 450D / 500D
+            // 550D / 1000D / 1100D
+          case 674: case 692: case 702: case 1227: case 1250:
+          case 1251: case 1337: case 1338: case 1346:
+            imgdata.color.canon_makernotes.CanonColorDataVer = 4;
+            imgdata.color.canon_makernotes.CanonColorDataSubVer = get2();
+            {
+              fseek (ifp, save1+(0x0e7<<1), SEEK_SET); // offset 231 short
+              int bls=0;
+              FORC4 bls+=get2();
+              imgdata.color.canon_makernotes.AverageBlackLevel = bls/4;
+            }
+            if ((imgdata.color.canon_makernotes.CanonColorDataSubVer == 4)
+                || (imgdata.color.canon_makernotes.CanonColorDataSubVer == 5))
+              {
+                fseek (ifp, save1+(0x2b9<<1), SEEK_SET);		// offset 697 shorts
+                imgdata.color.canon_makernotes.SpecularWhiteLevel = get2();
+              }
+            else if ((imgdata.color.canon_makernotes.CanonColorDataSubVer == 6) ||
+                     (imgdata.color.canon_makernotes.CanonColorDataSubVer == 7))
+              {
+                fseek (ifp, save1+(0x2d0<<1), SEEK_SET);		// offset 720 shorts
+                imgdata.color.canon_makernotes.SpecularWhiteLevel = get2();
+              }
+            else if (imgdata.color.canon_makernotes.CanonColorDataSubVer == 9)
+              {
+                fseek (ifp, save1+(0x2d4<<1), SEEK_SET);		// offset 724 shorts
+                imgdata.color.canon_makernotes.SpecularWhiteLevel = get2();
+              }
+            break;
+
+          case 5120:
+            imgdata.color.canon_makernotes.CanonColorDataVer = 5;	// PowerSot G10
+            break;
+
+          case 1273: case 1275:
+            imgdata.color.canon_makernotes.CanonColorDataVer = 6;	// 600D / 1200D
+            imgdata.color.canon_makernotes.CanonColorDataSubVer = get2();
+            {
+              fseek (ifp, save1+(0x0fb<<1), SEEK_SET);			// offset 251 short
+              int bls=0;
+              FORC4 bls+=get2();
+              imgdata.color.canon_makernotes.AverageBlackLevel = bls/4;
+            }
+            fseek (ifp, save1+(0x1e4<<1), SEEK_SET);			// offset 484 shorts
+            imgdata.color.canon_makernotes.SpecularWhiteLevel = get2();
+            break;
+
+            // 1DX / 5DmkIII / 6D / 100D / 650D / 700D / M / 7DmkII / 750D / 760D
+          case 1312: case 1313: case 1316: case 1506:
+            imgdata.color.canon_makernotes.CanonColorDataVer = 7;
+            imgdata.color.canon_makernotes.CanonColorDataSubVer = get2();
+            {
+              fseek (ifp, save1+(0x114<<1), SEEK_SET);			// offset 276 shorts
+              int bls=0;
+              FORC4 bls+=get2();
+              imgdata.color.canon_makernotes.AverageBlackLevel = bls/4;
+            }
+            if (imgdata.color.canon_makernotes.CanonColorDataSubVer == 10)
+              {
+                fseek (ifp, save1+(0x1fd<<1), SEEK_SET);		// offset 509 shorts
+                imgdata.color.canon_makernotes.SpecularWhiteLevel = get2();
+              } else if (imgdata.color.canon_makernotes.CanonColorDataSubVer == 11)
+              {
+                fseek (ifp, save1+(0x2dd<<1), SEEK_SET);		// offset 733 shorts
+                imgdata.color.canon_makernotes.SpecularWhiteLevel = get2();
+              }
+            break;
+          }
+        fseek (ifp, save1, SEEK_SET);
+      }
+#endif
     if (tag == 0x11 && is_raw && !strncmp(make,"NIKON",5)) {
       fseek (ifp, get4()+base, SEEK_SET);
       parse_tiff_ifd (base);
@@ -4659,6 +9438,16 @@ nf: order = 0x4949;
     if (tag == 0x1d)
       while ((c = fgetc(ifp)) && c != EOF)
 	serial = serial*10 + (isdigit(c) ? c - '0' : c % 10);
+    if (tag == 0x29 && type == 1) {  // Canon PowerShot G9
+      c = wbi < 18 ? "012347800000005896"[wbi]-'0' : 0;
+      fseek (ifp, 8 + c*32, SEEK_CUR);
+      FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get4();
+    }
+#ifndef LIBRAW_LIBRARY_BUILD
+	// works for some files, but not all
+    if (tag == 0x3d && type == 3 && len == 4)
+      FORC4 cblack[c ^ c >> 1] = get2() >> (14-tiff_ifd[2].bps);
+#endif
     if (tag == 0x81 && type == 4) {
       data_offset = get4();
       fseek (ifp, data_offset + 41, SEEK_SET);
@@ -4666,11 +9455,6 @@ nf: order = 0x4949;
       raw_width  = get2();
       filters = 0x61616161;
     }
-    if (tag == 0x29 && type == 1) {
-      c = wbi < 18 ? "012347800000005896"[wbi]-'0' : 0;
-      fseek (ifp, 8 + c*32, SEEK_CUR);
-      FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get4();
-    }
     if ((tag == 0x81  && type == 7) ||
 	(tag == 0x100 && type == 7) ||
 	(tag == 0x280 && type == 1)) {
@@ -4712,16 +9496,37 @@ nf: order = 0x4949;
       fseek (ifp, wbi*48, SEEK_CUR);
       FORC3 cam_mul[c] = get2();
     }
-    if (tag == 0xa7 && (unsigned) (ver97-200) < 17) {
-      ci = xlat[0][serial & 0xff];
-      cj = xlat[1][fgetc(ifp)^fgetc(ifp)^fgetc(ifp)^fgetc(ifp)];
-      ck = 0x60;
-      for (i=0; i < 324; i++)
-	buf97[i] ^= (cj += ci * ck++);
-      i = "66666>666;6A;:;55"[ver97-200] - '0';
-      FORC4 cam_mul[c ^ (c >> 1) ^ (i & 1)] =
-	sget2 (buf97 + (i & -2) + c*2);
+
+    if (tag == 0xa7) {	// shutter count
+      NikonKey = fgetc(ifp)^fgetc(ifp)^fgetc(ifp)^fgetc(ifp);
+      if ( (unsigned) (ver97-200) < 17) {
+        ci = xlat[0][serial & 0xff];
+        cj = xlat[1][NikonKey];
+        ck = 0x60;
+        for (i=0; i < 324; i++)
+          buf97[i] ^= (cj += ci * ck++);
+        i = "66666>666;6A;:;55"[ver97-200] - '0';
+        FORC4 cam_mul[c ^ (c >> 1) ^ (i & 1)] =
+          sget2 (buf97 + (i & -2) + c*2);
+      }
+#ifdef LIBRAW_LIBRARY_BUILD
+      if ((NikonLensDataVersion > 200) && lenNikonLensData)
+      {
+        ci = xlat[0][serial & 0xff];
+        cj = xlat[1][NikonKey];
+        ck = 0x60;
+        for (i = 0; i < lenNikonLensData; i++)
+          table_buf[i] ^= (cj += ci * ck++);
+        processNikonLensData(table_buf, lenNikonLensData);
+        lenNikonLensData = 0;
+    	}
+#endif
     }
+
+    if(tag == 0xb001 && type == 3)	// Sony ModelID
+      {
+        unique_id = get2();
+      }
     if (tag == 0x200 && len == 3)
       shot_order = (get4(),get4());
     if (tag == 0x200 && len == 4)
@@ -4732,6 +9537,17 @@ nf: order = 0x4949;
       meta_offset = ftell(ifp);
     if (tag == 0x401 && type == 4 && len == 4)
       FORC4 cblack[c ^ c >> 1] = get4();
+#ifdef LIBRAW_LIBRARY_BUILD
+    // not corrected for file bitcount, to be patched in open_datastream
+    if (tag == 0x03d && strstr(make,"NIKON") && len == 4)
+      {
+        FORC4 cblack[c ^ c >> 1] = get2();
+        i = cblack[3];
+        FORC3 if(i>cblack[c]) i = cblack[c];
+        FORC4 cblack[c]-=i;
+        black += i;
+      }
+#endif
     if (tag == 0xe01) {		/* Nikon Capture Note */
       order = 0x4949;
       fseek (ifp, 22, SEEK_CUR);
@@ -4757,8 +9573,21 @@ nf: order = 0x4949;
       goto get2_256;
     }
     if ((tag == 0x1011 && len == 9) || tag == 0x20400200)
-      for (i=0; i < 3; i++)
-	FORC3 cmatrix[i][c] = ((short) get2()) / 256.0;
+      {
+        if(!strncasecmp(make,"Olympus", 7))
+          {
+            int j,k;
+            for (i=0; i < 3; i++)
+              FORC3 adobe_cam[i][c] = ((short) get2()) / 256.0;
+            for (i=0; i < 3; i++)
+              for (j=0; j < 3; j++)
+                for (cmatrix[i][j] = k=0; k < 3; k++)
+                  cmatrix[i][j] += rgb_adobe[i][k] * adobe_cam[k][j];
+          }
+        else
+          for (i=0; i < 3; i++)
+            FORC3 cmatrix[i][c] = ((short) get2()) / 256.0;
+      }
     if ((tag == 0x1012 || tag == 0x20400600) && len == 4)
       FORC4 cblack[c ^ c >> 1] = get2();
     if (tag == 0x1017 || tag == 0x20400100)
@@ -4771,14 +9600,20 @@ get2_256:
       cam_mul[0] = get2() / 256.0;
       cam_mul[2] = get2() / 256.0;
     }
-    if ((tag | 0x70) == 0x2070 && type == 4)
+    if ((tag | 0x70) == 0x2070 && (type == 4 || type == 13))
       fseek (ifp, get4()+base, SEEK_SET);
-    if (tag == 0x2010 && type != 7)
-      load_raw = &CLASS olympus_load_raw;
     if (tag == 0x2020)
       parse_thumb_note (base, 257, 258);
     if (tag == 0x2040)
       parse_makernote (base, 0x2040);
+#ifdef LIBRAW_LIBRARY_BUILD
+	// IB start
+	if (tag == 0x2010)
+	  {
+		parse_makernote(base, 0x2010);
+	  }
+	// IB end
+#endif
     if (tag == 0xb028) {
       fseek (ifp, get4()+base, SEEK_SET);
       parse_thumb_note (base, 136, 137);
@@ -4788,14 +9623,32 @@ get2_256:
       fseek (ifp, i, SEEK_CUR);
 get2_rggb:
       FORC4 cam_mul[c ^ (c >> 1)] = get2();
-      i = len == 1312 ? 112:22;
+      i = len >> 3 == 164 || len == 1506 ? 112:22;
       fseek (ifp, i, SEEK_CUR);
       FORC4 sraw_mul[c ^ (c >> 1)] = get2();
     }
-    if (tag == 0xa021)
-      FORC4 cam_mul[c ^ (c >> 1)] = get4();
-    if (tag == 0xa028)
-      FORC4 cam_mul[c ^ (c >> 1)] -= get4();
+    if(!strcasecmp(make,"Samsung"))
+      {
+        if (tag == 0xa020) // get the full Samsung encryption key
+            for (i=0; i<11; i++) SamsungKey[i] = get4();
+        if (tag == 0xa021) // get and decode Samsung cam_mul array
+            FORC4 cam_mul[c ^ (c >> 1)] = get4() - SamsungKey[c];
+        if (tag == 0xa030 && len == 9)	// get and decode Samsung color matrix
+            for (i=0; i < 3; i++)
+              FORC3 cmatrix[i][c] = (short)((get4() + SamsungKey[i*3+c]))/256.0;
+        if (tag == 0xa028)
+          FORC4 cblack[c ^ (c >> 1)] = get4() - SamsungKey[c];
+      }
+    else
+      {
+        // Somebody else use 0xa021 and 0xa028?
+        if (tag == 0xa021)
+          FORC4 cam_mul[c ^ (c >> 1)] = get4();
+        if (tag == 0xa028)
+          FORC4 cam_mul[c ^ (c >> 1)] -= get4();
+      }
+    if (tag == 0x4021 && get4() && get4())
+      FORC4 cam_mul[c] = 1024;
 next:
     fseek (ifp, save, SEEK_SET);
   }
@@ -4832,23 +9685,74 @@ void CLASS get_timestamp (int reversed)
 void CLASS parse_exif (int base)
 {
   unsigned kodak, entries, tag, type, len, save, c;
-  double expo;
+  double expo,ape;
 
   kodak = !strncmp(make,"EASTMAN",7) && tiff_nifds < 3;
   entries = get2();
+  if(!strcmp(make,"Hasselblad") && (tiff_nifds > 3) && (entries > 512)) return;
+
+//  printf("\n*** in parse_exif, make: =%s= model: =%s=", make, model);
+
   while (entries--) {
     tiff_get (base, &tag, &type, &len, &save);
+
+		//    printf("\n\ttag: %x", tag);
+
+#ifdef LIBRAW_LIBRARY_BUILD
+    if(callbacks.exif_cb)
+      {
+        int savepos = ftell(ifp);
+        callbacks.exif_cb(callbacks.exifparser_data,tag,type,len,order,ifp);
+        fseek(ifp,savepos,SEEK_SET);
+      }
+#endif
     switch (tag) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    case 0xa405:		// FocalLengthIn35mmFormat
+      imgdata.lens.FocalLengthIn35mmFormat = get2();
+      break;
+    case 0xa432:		// LensInfo, 42034dec, Lens Specification per EXIF standard
+      imgdata.lens.MinFocal = getreal(type);
+      imgdata.lens.MaxFocal = getreal(type);
+      imgdata.lens.MaxAp4MinFocal = getreal(type);
+      imgdata.lens.MaxAp4MaxFocal = getreal(type);
+      break;
+    case 0xc630:		// DNG LensInfo, Lens Specification per EXIF standard
+      imgdata.lens.dng.MinFocal = getreal(type);
+      imgdata.lens.dng.MaxFocal = getreal(type);
+      imgdata.lens.dng.MaxAp4MinFocal = getreal(type);
+      imgdata.lens.dng.MaxAp4MaxFocal = getreal(type);
+      break;
+    case 0xa433:		// LensMake
+      fread(imgdata.lens.LensMake, MIN(len,sizeof(imgdata.lens.LensMake)), 1, ifp);
+      break;
+    case 0xa434:		// LensModel
+      fread(imgdata.lens.Lens, MIN(len, sizeof(imgdata.lens.LensMake)), 1, ifp);
+      if (!strncmp(imgdata.lens.Lens, "----", 4))
+        imgdata.lens.Lens[0] = 0;
+      break;
+    case 0x9205:
+      imgdata.lens.EXIF_MaxAp = powf64(2.0f, (getreal(type) / 2.0f));
+      break;
+#endif
       case 33434:  shutter = getreal(type);		break;
       case 33437:  aperture = getreal(type);		break;
       case 34855:  iso_speed = get2();			break;
+      case 34866:
+        if (iso_speed == 0xffff && (!strcasecmp(make, "SONY") || !strcasecmp(make, "CANON")))
+          iso_speed = getreal(type);
+        break;
       case 36867:
       case 36868:  get_timestamp(0);			break;
-      case 37377:  if ((expo = -getreal(type)) < 128)
-		     shutter = pow (2, expo);		break;
-      case 37378:  aperture = pow (2, getreal(type)/2);	break;
+      case 37377:  if ((expo = -getreal(type)) < 128 && shutter == 0.)
+          shutter = powf64(2.0, expo);		break;
+      case 37378:
+        if (fabs(ape = getreal(type))<256.0)
+          aperture = powf64(2.0, ape/2);
+        break;
+      case 37385:  flash_used = getreal(type);          break;
       case 37386:  focal_len = getreal(type);		break;
-      case 37500:  parse_makernote (base, 0);		break;
+      case 37500:  parse_makernote (base, 0);		break;	// tag 0x927c
       case 40962:  if (kodak) raw_width  = get4();	break;
       case 40963:  if (kodak) raw_height = get4();	break;
       case 41730:
@@ -4860,6 +9764,43 @@ void CLASS parse_exif (int base)
   }
 }
 
+#ifdef LIBRAW_LIBRARY_BUILD
+
+void CLASS parse_gps_libraw(int base)
+{
+  unsigned entries, tag, type, len, save, c;
+
+  entries = get2();
+  if (entries > 0)
+    imgdata.other.parsed_gps.gpsparsed = 1;
+  while (entries--) {
+    tiff_get(base, &tag, &type, &len, &save);
+    switch (tag) {
+    case 1:  imgdata.other.parsed_gps.latref = getc(ifp); break;
+    case 3:  imgdata.other.parsed_gps.longref = getc(ifp); break;
+    case 5:  imgdata.other.parsed_gps.altref = getc(ifp); break;
+    case 2:
+      if (len == 3)
+        FORC(3) imgdata.other.parsed_gps.latitude[c] = getreal(type);
+      break;
+    case 4:
+      if (len == 3)
+        FORC(3) imgdata.other.parsed_gps.longtitude[c] = getreal(type);
+      break;
+    case 7:
+      if (len == 3)
+        FORC(3) imgdata.other.parsed_gps.gpstimestamp[c] = getreal(type);
+      break;
+    case 6:
+      imgdata.other.parsed_gps.altitude = getreal(type);
+      break;
+    case 9: imgdata.other.parsed_gps.gpsstatus = getc(ifp); break;
+    }
+    fseek(ifp, save, SEEK_SET);
+  }
+}
+#endif
+
 void CLASS parse_gps (int base)
 {
   unsigned entries, tag, type, len, save, c;
@@ -4893,6 +9834,9 @@ void CLASS romm_coeff (float romm_cam[3][3])
     for (j=0; j < 3; j++)
       for (cmatrix[i][j] = k=0; k < 3; k++)
 	cmatrix[i][j] += rgb_romm[i][k] * romm_cam[k][j];
+#ifdef LIBRAW_LIBRARY_BUILD
+   imgdata.color.digitalBack_color=1;
+#endif
 }
 
 void CLASS parse_mos (int offset)
@@ -4903,7 +9847,8 @@ void CLASS parse_mos (int offset)
   { "","DCB2","Volare","Cantare","CMost","Valeo 6","Valeo 11","Valeo 22",
     "Valeo 11p","Valeo 17","","Aptus 17","Aptus 22","Aptus 75","Aptus 65",
     "Aptus 54S","Aptus 65S","Aptus 75S","AFi 5","AFi 6","AFi 7",
-    "","","","","","","","","","","","","","","","","","AFi-II 12" };
+    "Aptus-II 7","","","Aptus-II 6","","","Aptus-II 10","Aptus-II 5",
+    "","","","","Aptus-II 10R","Aptus-II 8","","Aptus-II 12","","AFi-II 12" };
   float romm_cam[3][3];
 
   fseek (ifp, offset, SEEK_SET);
@@ -4913,6 +9858,14 @@ void CLASS parse_mos (int offset)
     fread (data, 1, 40, ifp);
     skip = get4();
     from = ftell(ifp);
+
+// IB start
+#ifdef LIBRAW_LIBRARY_BUILD
+    if (!strcmp(data,"CameraObj_camera_type")) {
+			fread(imgdata.lens.makernotes.body, skip, 1, ifp);
+	}
+#endif
+// IB end
     if (!strcmp(data,"JPEG_preview_data")) {
       thumb_offset = from;
       thumb_length = skip;
@@ -4966,13 +9919,58 @@ void CLASS parse_mos (int offset)
 void CLASS linear_table (unsigned len)
 {
   int i;
-  if (len > 0x1000) len = 0x1000;
+  if (len > 0x10000) len = 0x10000;
   read_shorts (curve, len);
-  for (i=len; i < 0x1000; i++)
+  for (i=len; i < 0x10000; i++)
     curve[i] = curve[i-1];
-  maximum = curve[0xfff];
+  maximum = curve[len<0x1000?0xfff:len-1];
 }
 
+#ifdef LIBRAW_LIBRARY_BUILD
+/* Thanks to Alexey Danilchenko for wb as-shot parsing code */
+void CLASS parse_kodak_ifd (int base)
+{
+  unsigned entries, tag, type, len, save;
+  int i, c, wbi=-2;
+  float mul[3]={1,1,1}, num;
+  static const int wbtag[] = { 64037,64040,64039,64041,-1,-1,64042 };
+
+  entries = get2();
+  if (entries > 1024) return;
+  while (entries--) {
+    tiff_get (base, &tag, &type, &len, &save);
+#ifdef LIBRAW_LIBRARY_BUILD
+    if(callbacks.exif_cb)
+      {
+        int savepos = ftell(ifp);
+        callbacks.exif_cb(callbacks.exifparser_data,tag | 0x20000,type,len,order,ifp);
+        fseek(ifp,savepos,SEEK_SET);
+      }
+#endif
+    if (tag == 1020) wbi = getint(type);
+    if (tag == 1021 && len == 72) {		/* WB set in software */
+      fseek (ifp, 40, SEEK_CUR);
+      FORC3 cam_mul[c] = 2048.0 / get2();
+      wbi = -2;
+    }
+    if (tag == 2120 + wbi ||
+        (wbi<0 && tag == 2125))  /* use Auto WB if illuminant index is not set */
+      {
+        FORC3 mul[c] = (num=getreal(type))==0 ? 1 : num;
+        FORC3 cam_mul[c] = mul[1] / mul[c]; /* normalise against green */
+      }
+    if (tag == 2317) linear_table (len);
+    if (tag == 0x903) iso_speed = getreal(type);
+    //if (tag == 6020) iso_speed = getint(type);
+    if (tag == 64013) wbi = fgetc(ifp);
+    if ((unsigned) wbi < 7 && tag == wbtag[wbi])
+      FORC3 cam_mul[c] = get4();
+    if (tag == 64019) width = getint(type);
+    if (tag == 64020) height = (getint(type)+1) & -2;
+    fseek (ifp, save, SEEK_SET);
+  }
+}
+#else
 void CLASS parse_kodak_ifd (int base)
 {
   unsigned entries, tag, type, len, save;
@@ -4991,6 +9989,8 @@ void CLASS parse_kodak_ifd (int base)
       wbi = -2;
     }
     if (tag == 2118) wbtemp = getint(type);
+    if (tag == 2120 + wbi && wbi >= 0)
+      FORC3 cam_mul[c] = 2048.0 / getreal(type);
     if (tag == 2130 + wbi)
       FORC3 mul[c] = getreal(type);
     if (tag == 2140 + wbi && wbi >= 0)
@@ -5009,23 +10009,28 @@ void CLASS parse_kodak_ifd (int base)
     fseek (ifp, save, SEEK_SET);
   }
 }
+#endif
+//@end COMMON
 
 void CLASS parse_minolta (int base);
 int CLASS parse_tiff (int base);
 
+//@out COMMON
 int CLASS parse_tiff_ifd (int base)
 {
   unsigned entries, tag, type, len, plen=16, save;
   int ifd, use_cm=0, cfa, i, j, c, ima_len=0;
-  int blrr=1, blrc=1, dblack[] = { 0,0,0,0 };
-  char software[64], *cbuf, *cp;
+  char *cbuf, *cp;
   uchar cfa_pat[16], cfa_pc[] = { 0,1,2,3 }, tab[256];
   double cc[4][4], cm[4][3], cam_xyz[4][3], num;
   double ab[]={ 1,1,1,1 }, asn[] = { 0,0,0,0 }, xyz[] = { 1,1,1 };
   unsigned sony_curve[] = { 0,0,0,0,0,4095 };
   unsigned *buf, sony_offset=0, sony_length=0, sony_key=0;
   struct jhead jh;
+  int pana_raw = 0;
+#ifndef LIBRAW_LIBRARY_BUILD
   FILE *sfp;
+#endif
 
   if (tiff_nifds >= sizeof tiff_ifd / sizeof tiff_ifd[0])
     return 1;
@@ -5037,11 +10042,35 @@ int CLASS parse_tiff_ifd (int base)
   if (entries > 512) return 1;
   while (entries--) {
     tiff_get (base, &tag, &type, &len, &save);
+
+//    printf ("\n*** parse_tiff_ifd tag: 0x%04x", tag);
+
+#ifdef LIBRAW_LIBRARY_BUILD
+    if(callbacks.exif_cb)
+      {
+        int savepos = ftell(ifp);
+        callbacks.exif_cb(callbacks.exifparser_data,tag|(pana_raw?0x30000:0),type,len,order,ifp);
+        fseek(ifp,savepos,SEEK_SET);
+      }
+#endif
     switch (tag) {
+      case 1:   if(len==4) pana_raw = get4(); break;
       case 5:   width  = get2();  break;
       case 6:   height = get2();  break;
       case 7:   width += get2();  break;
-      case 9:  filters = get2();  break;
+      case 9:   if ((i = get2())) filters = i;
+#ifdef LIBRAW_LIBRARY_BUILD
+        if(pana_raw && len == 1 && type ==3)
+          pana_black[3]+=i;
+#endif
+        break;
+      case 8:
+      case 10:
+#ifdef LIBRAW_LIBRARY_BUILD
+        if(pana_raw && len == 1 && type ==3)
+          pana_black[3]+=get2();
+#endif
+        break;
       case 17: case 18:
 	if (type == 3 && len == 1)
 	  cam_mul[(tag-17)*2] = get2() / 256.0;
@@ -5049,8 +10078,21 @@ int CLASS parse_tiff_ifd (int base)
       case 23:
 	if (type == 3) iso_speed = get2();
 	break;
+      case 28: case 29: case 30:
+#ifdef LIBRAW_LIBRARY_BUILD
+        if(pana_raw && len == 1 && type ==3)
+          {
+            pana_black[tag-28] = get2();
+          }
+        else
+#endif
+          {
+            cblack[tag-28] = get2();
+            cblack[3] = cblack[1];
+          }
+	break;
       case 36: case 37: case 38:
-	cam_mul[tag-0x24] = get2();
+	cam_mul[tag-36] = get2();
 	break;
       case 39:
 	if (len < 50 || cam_mul[0]) break;
@@ -5063,13 +10105,14 @@ int CLASS parse_tiff_ifd (int base)
 	thumb_length = len;
 	break;
       case 61440:			/* Fuji HS10 table */
+	fseek (ifp, get4()+base, SEEK_SET);
 	parse_tiff_ifd (base);
 	break;
       case 2: case 256: case 61441:	/* ImageWidth */
-	tiff_ifd[ifd].width = getint(type);
+	tiff_ifd[ifd].t_width = getint(type);
 	break;
       case 3: case 257: case 61442:	/* ImageHeight */
-	tiff_ifd[ifd].height = getint(type);
+	tiff_ifd[ifd].t_height = getint(type);
 	break;
       case 258:				/* BitsPerSample */
       case 61443:
@@ -5078,8 +10121,9 @@ int CLASS parse_tiff_ifd (int base)
 	break;
       case 61446:
 	raw_height = 0;
+	if (tiff_ifd[ifd].bps > 12) break;
 	load_raw = &CLASS packed_load_raw;
-	load_flags = get4() && (filters=0x16161616) ? 24:80;
+	load_flags = get4() ? 24:80;
 	break;
       case 259:				/* Compression */
 	tiff_ifd[ifd].comp = getint(type);
@@ -5108,12 +10152,12 @@ int CLASS parse_tiff_ifd (int base)
 	  fseek (ifp, tiff_ifd[ifd].offset, SEEK_SET);
 	  if (ljpeg_start (&jh, 1)) {
 	    tiff_ifd[ifd].comp    = 6;
-	    tiff_ifd[ifd].width   = jh.wide;
-	    tiff_ifd[ifd].height  = jh.high;
+	    tiff_ifd[ifd].t_width   = jh.wide;
+	    tiff_ifd[ifd].t_height  = jh.high;
 	    tiff_ifd[ifd].bps     = jh.bits;
 	    tiff_ifd[ifd].samples = jh.clrs;
 	    if (!(jh.sraw || (jh.clrs & 1)))
-	      tiff_ifd[ifd].width *= jh.clrs;
+	      tiff_ifd[ifd].t_width *= jh.clrs;
 	    i = order;
 	    parse_tiff (tiff_ifd[ifd].offset + 12);
 	    order = i;
@@ -5121,7 +10165,7 @@ int CLASS parse_tiff_ifd (int base)
 	}
 	break;
       case 274:				/* Orientation */
-	tiff_ifd[ifd].flip = "50132467"[get2() & 7]-'0';
+	tiff_ifd[ifd].t_flip = "50132467"[get2() & 7]-'0';
 	break;
       case 277:				/* SamplesPerPixel */
 	tiff_ifd[ifd].samples = getint(type) & 7;
@@ -5140,7 +10184,6 @@ int CLASS parse_tiff_ifd (int base)
 	    !strncmp(software,"dcraw",5) ||
 	    !strncmp(software,"UFRaw",5) ||
 	    !strncmp(software,"Bibble",6) ||
-	    !strncmp(software,"Nikon Scan",10) ||
 	    !strcmp (software,"Digital Photo Professional"))
 	  is_raw = 0;
 	break;
@@ -5151,24 +10194,45 @@ int CLASS parse_tiff_ifd (int base)
 	fread (artist, 64, 1, ifp);
 	break;
       case 322:				/* TileWidth */
-	tiff_ifd[ifd].tile_width = getint(type);
+	tiff_ifd[ifd].t_tile_width = getint(type);
 	break;
       case 323:				/* TileLength */
-	tiff_ifd[ifd].tile_length = getint(type);
+	tiff_ifd[ifd].t_tile_length = getint(type);
 	break;
       case 324:				/* TileOffsets */
 	tiff_ifd[ifd].offset = len > 1 ? ftell(ifp) : get4();
+	if (len == 1)
+	  tiff_ifd[ifd].t_tile_width = tiff_ifd[ifd].t_tile_length = 0;
 	if (len == 4) {
 	  load_raw = &CLASS sinar_4shot_load_raw;
 	  is_raw = 5;
 	}
 	break;
+#ifdef LIBRAW_LIBRARY_BUILD
+      case 325:				/* TileByteCount */
+          tiff_ifd[ifd].tile_maxbytes = 0;
+          for(int jj=0;jj<len;jj++)
+              {
+                  int s = get4();
+                  if(s > tiff_ifd[ifd].tile_maxbytes) tiff_ifd[ifd].tile_maxbytes=s;
+              }
+	break;
+#endif
       case 330:				/* SubIFDs */
-	if (!strcmp(model,"DSLR-A100") && tiff_ifd[ifd].width == 3872) {
+	if (!strcmp(model,"DSLR-A100") && tiff_ifd[ifd].t_width == 3872) {
 	  load_raw = &CLASS sony_arw_load_raw;
 	  data_offset = get4()+base;
 	  ifd++;  break;
 	}
+#ifdef LIBRAW_LIBRARY_BUILD
+	if (!strcmp(make,"Hasselblad") && libraw_internal_data.unpacker_data.hasselblad_parser_flag) {
+          fseek (ifp, ftell(ifp)+4, SEEK_SET);
+          fseek (ifp, get4()+base, SEEK_SET);
+          parse_tiff_ifd (base);
+          break;
+	}
+#endif
+        if(len > 1000) len=1000; /* 1000 SubIFDs is enough */
 	while (len--) {
 	  i = ftell(ifp);
 	  fseek (ifp, get4()+base, SEEK_SET);
@@ -5180,6 +10244,16 @@ int CLASS parse_tiff_ifd (int base)
 	strcpy (make, "Sarnoff");
 	maximum = 0xfff;
 	break;
+#ifdef LIBRAW_LIBRARY_BUILD
+      case 700:
+        if((type == 1 || type == 2 || type == 6 || type == 7) && len > 1 && len < 5100000)
+          {
+            xmpdata = (char*)malloc(xmplen = len+1);
+            fread(xmpdata,len,1,ifp);
+            xmpdata[len]=0;
+          }
+        break;
+#endif
       case 28688:
 	FORC4 sony_curve[c+1] = get2() >> 2 & 0xfff;
 	for (i=0; i < 5; i++)
@@ -5201,20 +10275,55 @@ int CLASS parse_tiff_ifd (int base)
 	i = (cam_mul[1] == 1024 && cam_mul[2] == 1024) << 1;
 	SWAP (cam_mul[i],cam_mul[i+1])
 	break;
+    case 30720: // Sony matrix, Sony_SR2SubIFD_0x7800
+      for (i=0; i < 3; i++)
+        FORC3 cmatrix[i][c] = ((short) get2()) / 1024.0;
+#ifdef DCRAW_VERBOSE
+	if (verbose) fprintf (stderr, _(" Sony matrix:\n%f %f %f\n%f %f %f\n%f %f %f\n"), cmatrix[0][0],  cmatrix[0][1], cmatrix[0][2], cmatrix[1][0], cmatrix[1][1], cmatrix[1][2], cmatrix[2][0], cmatrix[2][1], cmatrix[2][2]);
+#endif
+	break;
+    case 29456: // Sony black level, Sony_SR2SubIFD_0x7310, no more needs to be divided by 4
+      FORC4 cblack[c ^ c >> 1] = get2();
+      i = cblack[3];
+      FORC3 if(i>cblack[c]) i = cblack[c];
+      FORC4 cblack[c]-=i;
+      black = i;
+#ifdef DCRAW_VERBOSE
+      if (verbose) fprintf (stderr, _("...Sony black: %u cblack: %u %u %u %u\n"),black, cblack[0],cblack[1],cblack[2], cblack[3]);
+#endif
+      break;
       case 33405:			/* Model2 */
 	fgets (model2, 64, ifp);
 	break;
+      case 33421:			/* CFARepeatPatternDim */
+	if (get2() == 6 && get2() == 6)
+	  filters = 9;
+	break;
       case 33422:			/* CFAPattern */
-      case 64777:			/* Kodak P-series */
-	if ((plen=len) > 16) plen = 16;
-	fread (cfa_pat, 1, plen, ifp);
-	for (colors=cfa=i=0; i < plen; i++) {
-	  colors += !(cfa & (1 << cfa_pat[i]));
-	  cfa |= 1 << cfa_pat[i];
+	if (filters == 9) {
+	  FORC(36) xtrans[0][c] = fgetc(ifp) & 3;
+	  break;
 	}
-	if (cfa == 070) memcpy (cfa_pc,"\003\004\005",3);	/* CMY */
-	if (cfa == 072) memcpy (cfa_pc,"\005\003\004\001",4);	/* GMCY */
-	goto guess_cfa_pc;
+      case 64777:			/* Kodak P-series */
+        if(len == 36)
+          {
+            filters = 9;
+            colors = 3;
+            FORC(36) xtrans[0][c] = fgetc(ifp) & 3;
+          }
+        else
+          {
+            if ((plen=len) > 16) plen = 16;
+            fread (cfa_pat, 1, plen, ifp);
+            for (colors=cfa=i=0; i < plen && colors < 4; i++) {
+              colors += !(cfa & (1 << cfa_pat[i]));
+              cfa |= 1 << cfa_pat[i];
+            }
+            if (cfa == 070) memcpy (cfa_pc,"\003\004\005",3);	/* CMY */
+            if (cfa == 072) memcpy (cfa_pc,"\005\003\004\001",4);	/* GMCY */
+            goto guess_cfa_pc;
+          }
+        break;
       case 33424:
       case 65024:
 	fseek (ifp, get4()+base, SEEK_SET);
@@ -5226,6 +10335,36 @@ int CLASS parse_tiff_ifd (int base)
       case 33437:			/* FNumber */
 	aperture = getreal(type);
 	break;
+#ifdef LIBRAW_LIBRARY_BUILD
+// IB start
+    case 0xa405:		// FocalLengthIn35mmFormat
+      imgdata.lens.FocalLengthIn35mmFormat = get2();
+      break;
+    case 0xa432:		// LensInfo, 42034dec, Lens Specification per EXIF standard
+      imgdata.lens.MinFocal = getreal(type);
+      imgdata.lens.MaxFocal = getreal(type);
+      imgdata.lens.MaxAp4MinFocal = getreal(type);
+      imgdata.lens.MaxAp4MaxFocal = getreal(type);
+      break;
+    case 0xc630:		// DNG LensInfo, Lens Specification per EXIF standard
+      imgdata.lens.MinFocal = getreal(type);
+      imgdata.lens.MaxFocal = getreal(type);
+      imgdata.lens.MaxAp4MinFocal = getreal(type);
+      imgdata.lens.MaxAp4MaxFocal = getreal(type);
+      break;
+    case 0xa433:		// LensMake
+      fread(imgdata.lens.LensMake, MIN(len, sizeof(imgdata.lens.LensMake)), 1, ifp);
+      break;
+    case 0xa434:		// LensModel
+      fread(imgdata.lens.Lens, MIN(len, sizeof(imgdata.lens.Lens)), 1, ifp);
+      if (!strncmp(imgdata.lens.Lens, "----", 4))
+        imgdata.lens.Lens[0] = 0;
+      break;
+    case 0x9205:
+				imgdata.lens.EXIF_MaxAp = powf64(2.0f, (getreal(type) / 2.0f));
+      break;
+// IB end
+#endif
       case 34306:			/* Leaf white balance */
 	FORC4 cam_mul[c ^ 1] = 4096.0 / get2();
 	break;
@@ -5251,8 +10390,15 @@ int CLASS parse_tiff_ifd (int base)
 	parse_exif (base);
 	break;
       case 34853:			/* GPSInfo tag */
-	fseek (ifp, get4()+base, SEEK_SET);
-	parse_gps (base);
+        {
+          unsigned pos;
+          fseek(ifp, pos = (get4() + base), SEEK_SET);
+          parse_gps(base);
+#ifdef LIBRAW_LIBRARY_BUILD
+          fseek(ifp, pos, SEEK_SET);
+          parse_gps_libraw(base);
+#endif
+        }
 	break;
       case 34675:			/* InterColorProfile */
       case 50831:			/* AsShotICCProfile */
@@ -5274,6 +10420,14 @@ int CLASS parse_tiff_ifd (int base)
 	  FORC3 rgb_cam[i][c] = getreal(type);
 	}
 	break;
+      case 40976:
+	strip_offset = get4();
+	switch (tiff_ifd[ifd].comp) {
+	  case 32770: load_raw = &CLASS samsung_load_raw;   break;
+	  case 32772: load_raw = &CLASS samsung2_load_raw;  break;
+	  case 32773: load_raw = &CLASS samsung3_load_raw;  break;
+	}
+	break;
       case 46275:			/* Imacon tags */
 	strcpy (make, "Imacon");
 	data_offset = ftell(ifp);
@@ -5290,7 +10444,12 @@ int CLASS parse_tiff_ifd (int base)
 	width = raw_width - left_margin - (get4() & 7);
 	top_margin = get4() & 7;
 	height = raw_height - top_margin - (get4() & 7);
-	if (raw_width == 7262) {
+	if (raw_width == 7262 && ima_len == 234317952 ) {
+	  height = 5412;
+	  width  = 7216;
+	  left_margin = 7;
+          filters=0;
+	} else 	if (raw_width == 7262) {
 	  height = 5444;
 	  width  = 7244;
 	  left_margin = 7;
@@ -5326,6 +10485,9 @@ int CLASS parse_tiff_ifd (int base)
 	if (!make[0]) strcpy (make, "Hasselblad");
 	break;
       case 50459:			/* Hasselblad tag */
+#ifdef LIBRAW_LIBRARY_BUILD
+        libraw_internal_data.unpacker_data.hasselblad_parser_flag=1;
+#endif
 	i = order;
 	j = ftell(ifp);
 	c = tiff_nifds;
@@ -5342,14 +10504,16 @@ int CLASS parse_tiff_ifd (int base)
 	is_raw = 1;
 	break;
       case 50710:			/* CFAPlaneColor */
+	if (filters == 9) break;
 	if (len > 4) len = 4;
 	colors = len;
 	fread (cfa_pc, 1, colors, ifp);
 guess_cfa_pc:
-	FORCC tab[cfa_pc[c]] = c;
-	cdesc[c] = 0;
-	for (i=16; i--; )
-	  filters = filters << 2 | tab[cfa_pat[i % plen]];
+        FORCC tab[cfa_pc[c]] = c;
+        cdesc[c] = 0;
+        for (i=16; i--; )
+          filters = filters << 2 | tab[cfa_pat[i % plen]];
+        filters -= !filters;
 	break;
       case 50711:			/* CFALayout */
 	if (get2() == 2) {
@@ -5362,27 +10526,28 @@ guess_cfa_pc:
 	linear_table (len);
 	break;
       case 50713:			/* BlackLevelRepeatDim */
-	blrr = get2();
-	blrc = get2();
+	cblack[4] = get2();
+	cblack[5] = get2();
+	if (cblack[4] * cblack[5] > (sizeof(cblack) / sizeof (cblack[0]) - 6))
+	    cblack[4] = cblack[5] = 1;
 	break;
       case 61450:
-	blrr = blrc = 2;
+	cblack[4] = cblack[5] = MIN(sqrt((double)len),64);
       case 50714:			/* BlackLevel */
-	black = getreal(type);
-	if (!filters || !~filters) break;
-	dblack[0] = black;
-	dblack[1] = (blrc == 2) ? getreal(type):dblack[0];
-	dblack[2] = (blrr == 2) ? getreal(type):dblack[0];
-	dblack[3] = (blrc == 2 && blrr == 2) ? getreal(type):dblack[1];
-	if (colors == 3)
-	  filters |= ((filters >> 2 & 0x22222222) |
-		      (filters << 2 & 0x88888888)) & filters << 1;
-	FORC4 cblack[filters >> (c << 1) & 3] = dblack[c];
-	black = 0;
+        if((cblack[4] * cblack[5] < 2) && len == 1)
+          {
+            black = getreal(type);
+          }
+        else if(cblack[4] * cblack[5] <= len)
+          {
+            FORC (cblack[4] * cblack[5])
+              cblack[6+c] = getreal(type);
+            black = 0;
+          }
 	break;
       case 50715:			/* BlackLevelDeltaH */
       case 50716:			/* BlackLevelDeltaV */
-	for (num=i=0; i < len; i++)
+	for (num=i=0; i < len && i < 65536; i++)
 	  num += getreal(type);
 	black += num/len + 0.5;
 	break;
@@ -5392,17 +10557,44 @@ guess_cfa_pc:
       case 50718:			/* DefaultScale */
 	pixel_aspect  = getreal(type);
 	pixel_aspect /= getreal(type);
+	if(pixel_aspect > 0.995 && pixel_aspect < 1.005)
+          pixel_aspect = 1.0;
 	break;
+#ifdef LIBRAW_LIBRARY_BUILD
+      case 50778:
+        imgdata.color.dng_color[0].illuminant = get2();
+        break;
+      case 50779:
+        imgdata.color.dng_color[1].illuminant = get2();
+        break;
+#endif
       case 50721:			/* ColorMatrix1 */
       case 50722:			/* ColorMatrix2 */
+#ifdef LIBRAW_LIBRARY_BUILD
+        i = tag == 50721?0:1;
+#endif
 	FORCC for (j=0; j < 3; j++)
+          {
+#ifdef LIBRAW_LIBRARY_BUILD
+          imgdata.color.dng_color[i].colormatrix[c][j]=
+#endif
 	  cm[c][j] = getreal(type);
+          }
 	use_cm = 1;
 	break;
       case 50723:			/* CameraCalibration1 */
       case 50724:			/* CameraCalibration2 */
+#ifdef LIBRAW_LIBRARY_BUILD
+        j = tag == 50723?0:1;
+#endif
 	for (i=0; i < colors; i++)
-	  FORCC cc[i][c] = getreal(type);
+	  FORCC
+            {
+#ifdef LIBRAW_LIBRARY_BUILD
+              imgdata.color.dng_color[j].calibration[i][c]=
+#endif
+              cc[i][c] = getreal(type);
+            }
 	break;
       case 50727:			/* AnalogBalance */
 	FORCC ab[c] = getreal(type);
@@ -5416,7 +10608,55 @@ guess_cfa_pc:
 	xyz[2] = 1 - xyz[0] - xyz[1];
 	FORC3 xyz[c] /= d65_white[c];
 	break;
-      case 50740:			/* DNGPrivateData */
+#ifdef LIBRAW_LIBRARY_BUILD
+      case 50730:			/* DNG: Baseline Exposure */
+        baseline_exposure = getreal(type);
+        break;
+#endif
+		  // IB start
+			case 50740:			/* tag 0xc634 : DNG Adobe, DNG Pentax, Sony SR2, DNG Private */
+      {
+        char mbuf[64];
+        unsigned short makernote_found = 0;
+        unsigned curr_pos, start_pos = ftell(ifp);
+        unsigned MakN_order, m_sorder = order;
+        unsigned MakN_length;
+        unsigned pos_in_original_raw;
+        fread(mbuf, 1, 6, ifp);
+
+        if (!strcmp(mbuf, "Adobe")) {
+          order = 0x4d4d;				// Adobe header is always in "MM" / big endian
+          curr_pos = start_pos + 6;
+          while (curr_pos + 8 - start_pos <= len)
+            {
+              fread(mbuf, 1, 4, ifp);
+              curr_pos += 8;
+              if (!strncmp(mbuf, "MakN", 4)) {
+                makernote_found = 1;
+                MakN_length = get4();
+                MakN_order = get2();
+                pos_in_original_raw = get4();
+                order = MakN_order;
+                parse_makernote_0xc634(curr_pos + 6 - pos_in_original_raw, 0, AdobeDNG);
+                break;
+              }
+            }
+        }
+        else {
+          fread(mbuf + 6, 1, 2, ifp);
+          if (!strcmp(mbuf, "PENTAX ") ||
+              !strcmp(mbuf, "SAMSUNG"))
+            {
+              makernote_found = 1;
+              fseek(ifp, start_pos, SEEK_SET);
+              parse_makernote_0xc634(base, 0, CameraDNG);
+            }
+        }
+
+        if (!makernote_found) fseek(ifp, start_pos, SEEK_SET);
+        order = m_sorder;
+      }
+      // IB end
 	if (dng_version) break;
 	parse_minolta (j = get4()+base);
 	fseek (ifp, j, SEEK_SET);
@@ -5456,6 +10696,7 @@ guess_cfa_pc:
     fseek (ifp, sony_offset, SEEK_SET);
     fread (buf, sony_length, 1, ifp);
     sony_decrypt (buf, sony_length/4, 1, sony_key);
+#ifndef LIBRAW_LIBRARY_BUILD
     sfp = ifp;
     if ((ifp = tmpfile())) {
       fwrite (buf, sony_length, 1, ifp);
@@ -5464,6 +10705,13 @@ guess_cfa_pc:
       fclose (ifp);
     }
     ifp = sfp;
+#else
+    if( !ifp->tempbuffer_open(buf,sony_length))
+        {
+            parse_tiff_ifd(-sony_offset);
+            ifp->tempbuffer_close();
+        }
+#endif
     free (buf);
   }
   for (i=0; i < colors; i++)
@@ -5472,7 +10720,7 @@ guess_cfa_pc:
     FORCC for (i=0; i < 3; i++)
       for (cam_xyz[c][i]=j=0; j < colors; j++)
 	cam_xyz[c][i] += cc[c][j] * cm[j][i] * xyz[i];
-    cam_xyz_coeff (cam_xyz);
+    cam_xyz_coeff (cmatrix, cam_xyz);
   }
   if (asn[0]) {
     cam_mul[3] = 0;
@@ -5507,9 +10755,12 @@ void CLASS apply_tiff()
   if (thumb_offset) {
     fseek (ifp, thumb_offset, SEEK_SET);
     if (ljpeg_start (&jh, 1)) {
-      thumb_misc   = jh.bits;
-      thumb_width  = jh.wide;
-      thumb_height = jh.high;
+      if((unsigned)jh.bits<17 && (unsigned)jh.wide < 0x10000 && (unsigned)jh.high < 0x10000)
+        {
+          thumb_misc   = jh.bits;
+          thumb_width  = jh.wide;
+          thumb_height = jh.high;
+        }
     }
   }
   for (i=0; i < tiff_nifds; i++) {
@@ -5517,24 +10768,28 @@ void CLASS apply_tiff()
 	max_samp = tiff_ifd[i].samples;
     if (max_samp > 3) max_samp = 3;
     if ((tiff_ifd[i].comp != 6 || tiff_ifd[i].samples != 3) &&
-	(tiff_ifd[i].width | tiff_ifd[i].height) < 0x10000 &&
-	tiff_ifd[i].width*tiff_ifd[i].height > raw_width*raw_height) {
-      raw_width     = tiff_ifd[i].width;
-      raw_height    = tiff_ifd[i].height;
+        unsigned(tiff_ifd[i].t_width | tiff_ifd[i].t_height) < 0x10000 &&
+        (unsigned)tiff_ifd[i].bps < 33 && (unsigned)tiff_ifd[i].samples < 13 &&
+	tiff_ifd[i].t_width*tiff_ifd[i].t_height > raw_width*raw_height) {
+      raw_width     = tiff_ifd[i].t_width;
+      raw_height    = tiff_ifd[i].t_height;
       tiff_bps      = tiff_ifd[i].bps;
       tiff_compress = tiff_ifd[i].comp;
       data_offset   = tiff_ifd[i].offset;
-      tiff_flip     = tiff_ifd[i].flip;
+      tiff_flip     = tiff_ifd[i].t_flip;
       tiff_samples  = tiff_ifd[i].samples;
-      tile_width    = tiff_ifd[i].tile_width;
-      tile_length   = tiff_ifd[i].tile_length;
+      tile_width    = tiff_ifd[i].t_tile_width;
+      tile_length   = tiff_ifd[i].t_tile_length;
+#ifdef LIBRAW_LIBRARY_BUILD
+      data_size     = tile_length < INT_MAX && tile_length>0 ? tiff_ifd[i].tile_maxbytes: tiff_ifd[i].bytes;
+#endif
       raw = i;
     }
   }
   if (!tile_width ) tile_width  = INT_MAX;
   if (!tile_length) tile_length = INT_MAX;
   for (i=tiff_nifds; i--; )
-    if (tiff_ifd[i].flip) tiff_flip = tiff_ifd[i].flip;
+    if (tiff_ifd[i].t_flip) tiff_flip = tiff_ifd[i].t_flip;
   if (raw >= 0 && !load_raw)
     switch (tiff_compress) {
       case 32767:
@@ -5552,6 +10807,18 @@ void CLASS apply_tiff()
       case 32770:
       case 32773: goto slr;
       case 0:  case 1:
+#ifdef LIBRAW_LIBRARY_BUILD
+        if(!strcasecmp(make,"Nikon") && !strncmp(software,"Nikon Scan",10))
+          {
+            load_raw = &CLASS nikon_coolscan_load_raw;
+            raw_color = 1;
+            filters = 0;
+            break;
+          }
+#endif
+	if (!strncmp(make,"OLYMPUS",7) &&
+		tiff_ifd[raw].bytes*2 == raw_width*raw_height*3)
+	  load_flags = 24;
 	if (tiff_ifd[raw].bytes*5 == raw_width*raw_height*8) {
 	  load_flags = 81;
 	  tiff_bps = 12;
@@ -5562,7 +10829,10 @@ void CLASS apply_tiff()
 		     load_flags = 6;
 		   load_raw = &CLASS packed_load_raw;		break;
 	  case 14: load_flags = 0;
-	  case 16: load_raw = &CLASS unpacked_load_raw;		break;
+	  case 16: load_raw = &CLASS unpacked_load_raw;
+		   if (!strncmp(make,"OLYMPUS",7) &&
+			tiff_ifd[raw].bytes*7 > raw_width*raw_height)
+		     load_raw = &CLASS olympus_load_raw;
 	}
 	break;
       case 6:  case 7:  case 99:
@@ -5570,9 +10840,31 @@ void CLASS apply_tiff()
       case 262:
 	load_raw = &CLASS kodak_262_load_raw;			break;
       case 34713:
-	load_raw = &CLASS nikon_load_raw;			break;
-      case 34892:
-	load_raw = &CLASS lossy_dng_load_raw;		break;
+	if ((raw_width+9)/10*16*raw_height == tiff_ifd[raw].bytes) {
+	  load_raw = &CLASS packed_load_raw;
+	  load_flags = 1;
+	} else if (raw_width*raw_height*3 == tiff_ifd[raw].bytes*2) {
+	  load_raw = &CLASS packed_load_raw;
+	  if (model[0] == 'N') load_flags = 80;
+	} else if (raw_width*raw_height*3 == tiff_ifd[raw].bytes) {
+	  load_raw = &CLASS nikon_yuv_load_raw;
+	  gamma_curve (1/2.4, 12.92, 1, 4095);
+	  memset (cblack, 0, sizeof cblack);
+	  filters = 0;
+	} else if (raw_width*raw_height*2 == tiff_ifd[raw].bytes) {
+	  load_raw = &CLASS unpacked_load_raw;
+	  load_flags = 4;
+	  order = 0x4d4d;
+	} else
+#ifdef LIBRAW_LIBRARY_BUILD
+          if(raw_width*raw_height*3 == tiff_ifd[raw].bytes*2)
+            {
+              load_raw = &CLASS packed_load_raw;
+              load_flags=80;
+            }
+          else
+#endif
+            load_raw = &CLASS nikon_load_raw;			break;
       case 65535:
 	load_raw = &CLASS pentax_load_raw;			break;
       case 65000:
@@ -5581,22 +10873,25 @@ void CLASS apply_tiff()
 	  case 6: load_raw = &CLASS kodak_ycbcr_load_raw; filters = 0;  break;
 	  case 32803: load_raw = &CLASS kodak_65000_load_raw;
 	}
-      case 32867: break;
+      case 32867: case 34892: break;
       default: is_raw = 0;
     }
   if (!dng_version)
-    if ( (tiff_samples == 3 && tiff_ifd[raw].bytes &&
-	  tiff_bps != 14 && tiff_bps != 2048 && tiff_compress != 32770)
-      || (tiff_bps == 8 && !strstr(make,"KODAK") && !strstr(make,"Kodak") &&
+    if ( ((tiff_samples == 3 && tiff_ifd[raw].bytes && tiff_bps != 14 &&
+	  (tiff_compress & -16) != 32768)
+      || (tiff_bps == 8 && !strcasestr(make,"Kodak") &&
 	  !strstr(model2,"DEBUG RAW")))
+         && strncmp(software,"Nikon Scan",10))
       is_raw = 0;
   for (i=0; i < tiff_nifds; i++)
     if (i != raw && tiff_ifd[i].samples == max_samp &&
-	tiff_ifd[i].width * tiff_ifd[i].height / SQR(tiff_ifd[i].bps+1) >
-	      thumb_width *       thumb_height / SQR(thumb_misc+1)
+        tiff_ifd[i].bps>0 && tiff_ifd[i].bps < 33 &&
+        unsigned(tiff_ifd[i].t_width | tiff_ifd[i].t_height) < 0x10000 &&
+	tiff_ifd[i].t_width * tiff_ifd[i].t_height / (SQR(tiff_ifd[i].bps)+1) >
+	      thumb_width *       thumb_height / (SQR(thumb_misc)+1)
 	&& tiff_ifd[i].comp != 34892) {
-      thumb_width  = tiff_ifd[i].width;
-      thumb_height = tiff_ifd[i].height;
+      thumb_width  = tiff_ifd[i].t_width;
+      thumb_height = tiff_ifd[i].t_height;
       thumb_offset = tiff_ifd[i].offset;
       thumb_length = tiff_ifd[i].bytes;
       thumb_misc   = tiff_ifd[i].bps;
@@ -5667,12 +10962,41 @@ void CLASS parse_external_jpeg()
 {
   const char *file, *ext;
   char *jname, *jfile, *jext;
+#ifndef LIBRAW_LIBRARY_BUILD
   FILE *save=ifp;
+#else
+#if defined(_WIN32) && !defined(__MINGW32__) && defined(_MSC_VER) && (_MSC_VER > 1310)
+  if(ifp->wfname())
+  {
+	  std::wstring rawfile(ifp->wfname());
+	  rawfile.replace(rawfile.length()-3,3,L"JPG");
+	  if(!ifp->subfile_open(rawfile.c_str()))
+	  {
+		  parse_tiff (12);
+		  thumb_offset = 0;
+		  is_raw = 1;
+		  ifp->subfile_close();
+	  }
+	  else
+		  imgdata.process_warnings |= LIBRAW_WARN_NO_METADATA ;
+	 return;
+  }
+#endif
+  if(!ifp->fname())
+      {
+          imgdata.process_warnings |= LIBRAW_WARN_NO_METADATA ;
+          return;
+      }
+#endif
 
   ext  = strrchr (ifname, '.');
   file = strrchr (ifname, '/');
   if (!file) file = strrchr (ifname, '\\');
+#ifndef LIBRAW_LIBRARY_BUILD
   if (!file) file = ifname-1;
+#else
+  if (!file) file = (char*)ifname-1;
+#endif
   file++;
   if (!ext || strlen(ext) != 4 || ext-file != 8) return;
   jname = (char *) malloc (strlen(ifname) + 1);
@@ -5694,20 +11018,46 @@ void CLASS parse_external_jpeg()
       }
       *jext = '0';
     }
+#ifndef LIBRAW_LIBRARY_BUILD
   if (strcmp (jname, ifname)) {
     if ((ifp = fopen (jname, "rb"))) {
+#ifdef DCRAW_VERBOSE
       if (verbose)
 	fprintf (stderr,_("Reading metadata from %s ...\n"), jname);
+#endif
       parse_tiff (12);
       thumb_offset = 0;
       is_raw = 1;
       fclose (ifp);
     }
   }
+#else
+  if (strcmp (jname, ifname))
+      {
+          if(!ifp->subfile_open(jname))
+              {
+                  parse_tiff (12);
+                  thumb_offset = 0;
+                  is_raw = 1;
+                  ifp->subfile_close();
+              }
+          else
+              imgdata.process_warnings |= LIBRAW_WARN_NO_METADATA ;
+      }
+#endif
   if (!timestamp)
-    fprintf (stderr,_("Failed to read metadata from %s\n"), jname);
+      {
+#ifdef LIBRAW_LIBRARY_BUILD
+          imgdata.process_warnings |= LIBRAW_WARN_NO_METADATA ;
+#endif
+#ifdef DCRAW_VERBOSE
+          fprintf (stderr,_("Failed to read metadata from %s\n"), jname);
+#endif
+      }
   free (jname);
+#ifndef LIBRAW_LIBRARY_BUILD
   ifp = save;
+#endif
 }
 
 /*
@@ -5738,7 +11088,8 @@ void CLASS ciff_block_1030()
 /*
    Parse a CIFF file, better known as Canon CRW format.
  */
-void CLASS parse_ciff (int offset, int length)
+
+void CLASS parse_ciff (int offset, int length, int depth)
 {
   int tboff, nrecs, c, type, len, save, wbi=-1;
   ushort key[] = { 0x410, 0x45f3 };
@@ -5747,15 +11098,18 @@ void CLASS parse_ciff (int offset, int length)
   tboff = get4() + offset;
   fseek (ifp, tboff, SEEK_SET);
   nrecs = get2();
-  if (nrecs > 100) return;
+  if ((nrecs | depth) > 127) return;
   while (nrecs--) {
     type = get2();
     len  = get4();
+
+//    printf ("\n*** type: 0x%04x len: 0x%04x", type, len);
+
     save = ftell(ifp) + 4;
     fseek (ifp, offset+get4(), SEEK_SET);
-    if ((((type >> 8) + 8) | 8) == 0x38)
-      parse_ciff (ftell(ifp), len);	/* Parse a sub-table */
-
+    if ((((type >> 8) + 8) | 8) == 0x38) {
+      parse_ciff (ftell(ifp), len, depth+1); /* Parse a sub-table */
+    }
     if (type == 0x0810)
       fread (artist, 64, 1, ifp);
     if (type == 0x080a) {
@@ -5764,7 +11118,9 @@ void CLASS parse_ciff (int offset, int length)
       fread (model, 64, 1, ifp);
     }
     if (type == 0x1810) {
-      fseek (ifp, 12, SEEK_CUR);
+      width = get4();
+      height = get4();
+      pixel_aspect = int_to_float(get4());
       flip = get4();
     }
     if (type == 0x1835)			/* Get the decoder table */
@@ -5774,13 +11130,22 @@ void CLASS parse_ciff (int offset, int length)
       thumb_length = len;
     }
     if (type == 0x1818) {
-      shutter = pow (2, -int_to_float((get4(),get4())));
-      aperture = pow (2, int_to_float(get4())/2);
+      shutter = powf64(2.0f, -int_to_float((get4(),get4())));
+      aperture = powf64(2.0f, int_to_float(get4())/2);
+#ifdef LIBRAW_LIBRARY_BUILD
+			imgdata.lens.makernotes.CurAp = aperture;
+#endif
     }
     if (type == 0x102a) {
-      iso_speed = pow (2, (get4(),get2())/32.0 - 4) * 50;
-      aperture  = pow (2, (get2(),(short)get2())/64.0);
-      shutter   = pow (2,-((short)get2())/32.0);
+			//      iso_speed = pow (2.0, (get4(),get2())/32.0 - 4) * 50;
+      iso_speed = powf64(2.0f, ((get2(),get2()) + get2())/32.0f - 5.0f) * 100.0f;
+#ifdef LIBRAW_LIBRARY_BUILD
+      aperture  = _CanonConvertAperture((get2(),get2()));
+      imgdata.lens.makernotes.CurAp = aperture;
+#else
+      aperture  = powf64(2.0, (get2(),(short)get2())/64.0);
+#endif
+      shutter   = powf64(2.0,-((short)get2())/32.0);
       wbi = (get2(),get2());
       if (wbi > 17) wbi = 0;
       fseek (ifp, 32, SEEK_CUR);
@@ -5795,6 +11160,22 @@ void CLASS parse_ciff (int offset, int length)
 	FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get2();
       }
     }
+#ifdef LIBRAW_LIBRARY_BUILD
+    if (type == 0x102d) {
+        fseek(ifp, 44, SEEK_CUR);
+        imgdata.lens.makernotes.LensID = get2();
+        imgdata.lens.makernotes.MaxFocal = get2();
+        imgdata.lens.makernotes.MinFocal = get2();
+        imgdata.lens.makernotes.CanonFocalUnits = get2();
+        if (imgdata.lens.makernotes.CanonFocalUnits != 1)
+          {
+            imgdata.lens.makernotes.MaxFocal /= (float)imgdata.lens.makernotes.CanonFocalUnits;
+            imgdata.lens.makernotes.MinFocal /= (float)imgdata.lens.makernotes.CanonFocalUnits;
+          }
+        imgdata.lens.makernotes.MaxAp = _CanonConvertAperture(get2());
+        imgdata.lens.makernotes.MinAp = _CanonConvertAperture(get2());
+    }
+#endif
     if (type == 0x0032) {
       if (len == 768) {			/* EOS D30 */
 	fseek (ifp, 72, SEEK_CUR);
@@ -5824,14 +11205,33 @@ void CLASS parse_ciff (int offset, int length)
       raw_width = (get2(),get2());
       raw_height = get2();
     }
+    if (type == 0x501c) {
+      iso_speed = len & 0xffff;
+    }
     if (type == 0x5029) {
+#ifdef LIBRAW_LIBRARY_BUILD
+      imgdata.lens.makernotes.CurFocal  = len >> 16;
+      imgdata.lens.makernotes.FocalType = len & 0xffff;
+      if (imgdata.lens.makernotes.FocalType == 2) {
+        imgdata.lens.makernotes.CanonFocalUnits = 32;
+        imgdata.lens.makernotes.CurFocal /= (float)imgdata.lens.makernotes.CanonFocalUnits;
+      }
+      focal_len = imgdata.lens.makernotes.CurFocal;
+#else
       focal_len = len >> 16;
       if ((len & 0xffff) == 2) focal_len /= 32;
+#endif
     }
     if (type == 0x5813) flash_used = int_to_float(len);
     if (type == 0x5814) canon_ev   = int_to_float(len);
     if (type == 0x5817) shot_order = len;
-    if (type == 0x5834) unique_id  = len;
+    if (type == 0x5834)
+		{
+			unique_id  = len;
+#ifdef LIBRAW_LIBRARY_BUILD
+			setCanonBodyFeatures(unique_id);
+#endif
+		}
     if (type == 0x580e) timestamp  = len;
     if (type == 0x180e) timestamp  = get4();
 #ifdef LOCALTIME
@@ -5918,6 +11318,11 @@ void CLASS parse_phase_one (int base)
   float romm_cam[3][3];
   char *cp;
 
+#ifdef LIBRAW_LIBRARY_BUILD
+	char body_id[3];
+	body_id[0] = 0;
+#endif
+
   memset (&ph1, 0, sizeof ph1);
   fseek (ifp, base, SEEK_SET);
   order = get4() & 0xffff;
@@ -5933,6 +11338,64 @@ void CLASS parse_phase_one (int base)
     save = ftell(ifp);
     fseek (ifp, base+data, SEEK_SET);
     switch (tag) {
+
+#ifdef LIBRAW_LIBRARY_BUILD
+    case 0x0102:
+      fread(body_id, 1, 3, ifp);
+      if ((body_id[0] == 0x4c) && (body_id[1] == 0x49)) {
+        body_id[1] = body_id[2];
+      }
+      unique_id = (((body_id[0] & 0x3f) << 5) | (body_id[1] & 0x3f)) - 0x41;
+      setPhaseOneFeatures(unique_id);
+      break;
+    case 0x0401:
+      if (type == 4) imgdata.lens.makernotes.CurAp =  powf64(2.0f, (int_to_float(data)/2.0f));
+      else imgdata.lens.makernotes.CurAp = powf64(2.0f, (getreal(type)/2.0f));
+      break;
+    case 0x0403:
+      if (type == 4) imgdata.lens.makernotes.CurFocal =  int_to_float(data);
+      else imgdata.lens.makernotes.CurFocal = getreal(type);
+      break;
+    case 0x0410:
+      fread(imgdata.lens.makernotes.body, 1, len, ifp);
+      break;
+    case 0x0412:
+      fread(imgdata.lens.makernotes.Lens, 1, len, ifp);
+      break;
+    case 0x0414:
+      if (type == 4) {
+      	imgdata.lens.makernotes.MaxAp4CurFocal = powf64(2.0f, (int_to_float(data)/2.0f));
+      } else {
+        imgdata.lens.makernotes.MaxAp4CurFocal = powf64(2.0f, (getreal(type) / 2.0f));
+      }
+      break;
+    case 0x0415:
+      if (type == 4) {
+      	imgdata.lens.makernotes.MinAp4CurFocal = powf64(2.0f, (int_to_float(data)/2.0f));
+      } else {
+        imgdata.lens.makernotes.MinAp4CurFocal = powf64(2.0f, (getreal(type) / 2.0f));
+      }
+      break;
+    case 0x0416:
+      if (type == 4) {
+        imgdata.lens.makernotes.MinFocal =  int_to_float(data);
+      } else {
+        imgdata.lens.makernotes.MinFocal = getreal(type);
+      }
+      if (imgdata.lens.makernotes.MinFocal > 1000.0f)
+        {
+          imgdata.lens.makernotes.MinFocal = 0.0f;
+        }
+      break;
+    case 0x0417:
+      if (type == 4) {
+        imgdata.lens.makernotes.MaxFocal =  int_to_float(data);
+      } else {
+        imgdata.lens.makernotes.MaxFocal = getreal(type);
+      }
+      break;
+#endif
+
       case 0x100:  flip = "0653"[data & 3]-'0';  break;
       case 0x106:
 	for (i=0; i < 9; i++)
@@ -5956,9 +11419,11 @@ void CLASS parse_phase_one (int base)
       case 0x210:  ph1.tag_210   = int_to_float(data);	break;
       case 0x21a:  ph1.tag_21a   = data;		break;
       case 0x21c:  strip_offset  = data+base;		break;
-      case 0x21d:  ph1.black     = data;		break;
+      case 0x21d:  ph1.t_black     = data;		break;
       case 0x222:  ph1.split_col = data;		break;
-      case 0x223:  ph1.black_off = data+base;		break;
+      case 0x223:  ph1.black_col = data+base;		break;
+      case 0x224:  ph1.split_row = data;		break;
+      case 0x225:  ph1.black_row = data+base;		break;
       case 0x301:
 	model[63] = 0;
 	fread (model, 1, 63, ifp);
@@ -5966,6 +11431,33 @@ void CLASS parse_phase_one (int base)
     }
     fseek (ifp, save, SEEK_SET);
   }
+
+#ifdef LIBRAW_LIBRARY_BUILD
+  if (!imgdata.lens.makernotes.body[0] && !body_id[0]) {
+    fseek (ifp, meta_offset, SEEK_SET);
+    order = get2();
+    fseek (ifp, 6, SEEK_CUR);
+    fseek (ifp, meta_offset+get4(), SEEK_SET);
+    entries = get4();  get4();
+    while (entries--) {
+      tag  = get4();
+      len  = get4();
+      data = get4();
+      save = ftell(ifp);
+      fseek (ifp, meta_offset+data, SEEK_SET);
+      if (tag == 0x0407) {
+        fread(body_id, 1, 3, ifp);
+        if ((body_id[0] == 0x4c) && (body_id[1] == 0x49)) {
+          body_id[1] = body_id[2];
+        }
+        unique_id = (((body_id[0] & 0x3f) << 5) | (body_id[1] & 0x3f)) - 0x41;
+        setPhaseOneFeatures(unique_id);
+      }
+      fseek (ifp, save, SEEK_SET);
+    }
+  }
+#endif
+
   load_raw = ph1.format < 3 ?
 	&CLASS phase_one_load_raw : &CLASS phase_one_load_raw_c;
   maximum = 0xffff;
@@ -5999,12 +11491,16 @@ void CLASS parse_fuji (int offset)
     } else if (tag == 0x130) {
       fuji_layout = fgetc(ifp) >> 7;
       fuji_width = !(fgetc(ifp) & 8);
+    } else if (tag == 0x131) {
+      filters = 9;
+      FORC(36) xtrans_abs[0][35-c] = fgetc(ifp) & 3;
     } else if (tag == 0x2ff0) {
       FORC4 cam_mul[c ^ 1] = get2();
     } else if (tag == 0xc000) {
       c = order;
       order = 0x4949;
-      width  = get4();
+      if ((tag = get4()) > 10000) tag = get4();
+      width = tag;
       height = get4();
       order = c;
     }
@@ -6033,7 +11529,13 @@ int CLASS parse_jpeg (int offset)
     order = get2();
     hlen  = get4();
     if (get4() == 0x48454150)		/* "HEAP" */
-      parse_ciff (save+hlen, len-hlen);
+		{
+#ifdef LIBRAW_LIBRARY_BUILD
+			imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_FixedLens;
+			imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_FixedLens;
+#endif
+      parse_ciff (save+hlen, len-hlen, 0);
+		}
     if (parse_tiff (save+6)) apply_tiff();
     fseek (ifp, save+len, SEEK_SET);
   }
@@ -6053,8 +11555,9 @@ void CLASS parse_riff()
   size = get4();
   end = ftell(ifp) + size;
   if (!memcmp(tag,"RIFF",4) || !memcmp(tag,"LIST",4)) {
+    int maxloop = 1000;
     get4();
-    while (ftell(ifp)+7 < end)
+    while (ftell(ifp)+7 < end && !feof(ifp) && maxloop--)
       parse_riff();
   } else if (!memcmp(tag,"nctg",4)) {
     while (ftell(ifp)+7 < end) {
@@ -6080,6 +11583,26 @@ void CLASS parse_riff()
     fseek (ifp, size, SEEK_CUR);
 }
 
+void CLASS parse_qt (int end)
+{
+  unsigned save, size;
+  char tag[4];
+
+  order = 0x4d4d;
+  while (ftell(ifp)+7 < end) {
+    save = ftell(ifp);
+    if ((size = get4()) < 8) return;
+    fread (tag, 4, 1, ifp);
+    if (!memcmp(tag,"moov",4) ||
+	!memcmp(tag,"udta",4) ||
+	!memcmp(tag,"CNTH",4))
+      parse_qt (save+size);
+    if (!memcmp(tag,"CNDA",4))
+      parse_jpeg (ftell(ifp));
+    fseek (ifp, save+size, SEEK_SET);
+  }
+}
+
 void CLASS parse_smal (int offset, int fsize)
 {
   int ver;
@@ -6138,7 +11661,7 @@ void CLASS parse_cine()
   }
   cam_mul[0] = getreal(11);
   cam_mul[2] = getreal(11);
-  maximum = ~(-1 << get4());
+  maximum = ~((~0u) << get4());
   fseek (ifp, 668, SEEK_CUR);
   shutter = get4()/1000000000.0;
   fseek (ifp, off_image, SEEK_SET);
@@ -6160,7 +11683,9 @@ void CLASS parse_redcine()
   fseek (ifp, 0, SEEK_END);
   fseek (ifp, -(i = ftello(ifp) & 511), SEEK_CUR);
   if (get4() != i || get4() != 0x52454f42) {
+#ifdef DCRAW_VERBOSE
     fprintf (stderr,_("%s: Tail is missing, parsing from head...\n"), ifname);
+#endif
     fseek (ifp, 0, SEEK_SET);
     while ((len = get4()) != EOF) {
       if (get4() == 0x52454456)
@@ -6176,6 +11701,7 @@ void CLASS parse_redcine()
     data_offset = get4();
   }
 }
+//@end COMMON
 
 char * CLASS foveon_gets (int offset, char *str, int len)
 {
@@ -6191,7 +11717,6 @@ void CLASS parse_foveon()
 {
   int entries, img=0, off, len, tag, save, i, wide, high, pent, poff[256][2];
   char name[64], value[64];
-
   order = 0x4949;			/* Little-endian */
   fseek (ifp, 36, SEEK_SET);
   flip = get4();
@@ -6223,6 +11748,7 @@ void CLASS parse_foveon()
 	  raw_width  = wide;
 	  raw_height = high;
 	  data_offset = off+28;
+	  is_foveon = 1;
 	}
 	fseek (ifp, off+28, SEEK_SET);
 	if (fgetc(ifp) == 0xff && fgetc(ifp) == 0xd8
@@ -6268,6 +11794,41 @@ void CLASS parse_foveon()
 	    aperture = atof(value);
 	  if (!strcmp (name, "FLENGTH"))
 	    focal_len = atof(value);
+#ifdef LIBRAW_LIBRARY_BUILD
+	  if (!strcmp (name, "FLEQ35MM"))
+				imgdata.lens.makernotes.FocalLengthIn35mmFormat = atof(value);
+		if (!strcmp (name, "LENSARANGE"))
+			{
+				char *sp;
+				imgdata.lens.makernotes.MaxAp4CurFocal = imgdata.lens.makernotes.MinAp4CurFocal = atof(value);
+				sp = strrchr (value, ' ');
+				if (sp)
+					{
+						imgdata.lens.makernotes.MinAp4CurFocal = atof(sp);
+						if (imgdata.lens.makernotes.MaxAp4CurFocal > imgdata.lens.makernotes.MinAp4CurFocal)
+							my_swap (float, imgdata.lens.makernotes.MaxAp4CurFocal, imgdata.lens.makernotes.MinAp4CurFocal);
+					}
+			}
+			if (!strcmp (name, "LENSFRANGE"))
+			{
+				char *sp;
+				imgdata.lens.makernotes.MinFocal = imgdata.lens.makernotes.MaxFocal = atof(value);
+				sp = strrchr (value, ' ');
+				if (sp)
+					{
+						imgdata.lens.makernotes.MaxFocal = atof(sp);
+						if ((imgdata.lens.makernotes.MaxFocal + 0.17f) < imgdata.lens.makernotes.MinFocal)
+							my_swap (float, imgdata.lens.makernotes.MaxFocal, imgdata.lens.makernotes.MinFocal);
+					}
+			}
+			if (!strcmp (name, "LENSMODEL"))
+			{
+				imgdata.lens.makernotes.LensID = atoi(value);
+				if (imgdata.lens.makernotes.LensID)
+				 imgdata.lens.makernotes.LensMount = Sigma_X3F;
+			}
+		}
+#endif
 	}
 #ifdef LOCALTIME
 	timestamp = mktime (gmtime (&timestamp));
@@ -6275,19 +11836,24 @@ void CLASS parse_foveon()
     }
     fseek (ifp, save, SEEK_SET);
   }
-  is_foveon = 1;
 }
 
+//@out COMMON
+
 /*
    All matrices are from Adobe DNG Converter unless otherwise noted.
  */
-void CLASS adobe_coeff (const char *make, const char *model)
+void CLASS adobe_coeff (const char *t_make, const char *t_model
+#ifdef LIBRAW_LIBRARY_BUILD
+	,int internal_only
+#endif
+)
 {
   static const struct {
     const char *prefix;
-    short black, maximum, trans[12];
+    int t_black, t_maximum, trans[12];
   } table[] = {
-    { "AGFAPHOTO DC-833m", 0, 0,	/* DJC */
+    { "AgfaPhoto DC-833m", 0, 0,	/* DJC */
 	{ 11438,-3762,-1115,-2409,9914,2497,-1227,2295,5300 } },
     { "Apple QuickTake", 0, 0,		/* DJC */
 	{ 21392,-5653,-3353,2406,8010,-415,7166,1427,2078 } },
@@ -6305,6 +11871,10 @@ void CLASS adobe_coeff (const char *make, const char *model)
 	{ 4716,603,-830,-7798,15474,2480,-1496,1937,6651 } },
     { "Canon EOS 5D", 0, 0xe6c,
 	{ 6347,-479,-972,-8297,15954,2480,-1968,2131,7649 } },
+    { "Canon EOS 6D", 0, 0x3c82,
+	{ 8621,-2197,-787,-3150,11358,912,-1161,2400,4836 } },
+    { "Canon EOS 7D Mark II", 0, 0x3510,
+	{ 7268,-1082,-969,-4186,11839,2663,-825,2029,5839 } },
     { "Canon EOS 7D", 0, 0x3510,
 	{ 6844,-996,-856,-3876,11761,2396,-593,1772,6198 } },
     { "Canon EOS 10D", 0, 0xfa0,
@@ -6321,6 +11891,10 @@ void CLASS adobe_coeff (const char *make, const char *model)
 	{ 4920,616,-593,-6493,13964,2784,-1774,3178,7005 } },
     { "Canon EOS 60D", 0, 0x2ff7,
 	{ 6719,-994,-925,-4408,12426,2211,-887,2129,6051 } },
+    { "Canon EOS 70D", 0, 0x3bc7,
+	{ 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 } },
+    { "Canon EOS 100D", 0, 0x350f,
+	{ 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
     { "Canon EOS 300D", 0, 0xfa0,
 	{ 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } },
     { "Canon EOS 350D", 0, 0xfff,
@@ -6335,10 +11909,18 @@ void CLASS adobe_coeff (const char *make, const char *model)
 	{ 6941,-1164,-857,-3825,11597,2534,-416,1540,6039 } },
     { "Canon EOS 600D", 0, 0x3510,
 	{ 6461,-907,-882,-4300,12184,2378,-819,1944,5931 } },
+    { "Canon EOS 650D", 0, 0x354d,
+	{ 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
+    { "Canon EOS 700D", 0, 0x3c00,
+	{ 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
     { "Canon EOS 1000D", 0, 0xe43,
 	{ 6771,-1139,-977,-7818,15123,2928,-1244,1437,7533 } },
     { "Canon EOS 1100D", 0, 0x3510,
 	{ 6444,-904,-893,-4563,12308,2535,-903,2016,6728 } },
+    { "Canon EOS 1200D", 0, 0x37c2,
+	{ 6461,-907,-882,-4300,12184,2378,-819,1944,5931 } },
+    { "Canon EOS M", 0, 0,
+	{ 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
     { "Canon EOS-1Ds Mark III", 0, 0x3bb0,
 	{ 5859,-211,-930,-8255,16017,2353,-1732,1887,7448 } },
     { "Canon EOS-1Ds Mark II", 0, 0xe80,
@@ -6353,12 +11935,14 @@ void CLASS adobe_coeff (const char *make, const char *model)
 	{ 6264,-582,-724,-8312,15948,2504,-1744,1919,8664 } },
     { "Canon EOS-1DS", 0, 0xe20,
 	{ 4374,3631,-1743,-7520,15212,2472,-2892,3632,8161 } },
-    { "Canon EOS-1D X", 0, 0,
+    { "Canon EOS-1D C", 0, 0x3c4e,
+	{ 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } },
+    { "Canon EOS-1D X", 0, 0x3c4e,
 	{ 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } },
     { "Canon EOS-1D", 0, 0xe20,
 	{ 6806,-179,-1020,-8097,16415,1687,-3267,4236,7690 } },
-    { "Canon EOS", 0, 0,
-	{ 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } },
+    { "Canon EOS C500", 853, 0,		/* DJC */
+	{ 17851,-10604,922,-7425,16662,763,-3660,3636,22278 } },
     { "Canon PowerShot A530", 0, 0,
 	{ 0 } },	/* don't want the A5 matrix */
     { "Canon PowerShot A50", 0, 0,
@@ -6371,6 +11955,12 @@ void CLASS adobe_coeff (const char *make, const char *model)
 	{ 12177,-4817,-1069,-1612,9864,2049,-98,850,4471 } },
     { "Canon PowerShot G12", 0, 0,
 	{ 13244,-5501,-1248,-1508,9858,1935,-270,1083,4366 } },
+    { "Canon PowerShot G15", 0, 0,
+	{ 7474,-2301,-567,-4056,11456,2975,-222,716,4181 } },
+    { "Canon PowerShot G16", 0, 0,
+        { 14130,-8071,127,2199,6528,1551,3402,-1721,4960 } },
+    { "Canon PowerShot G1 X Mark II", 0, 0,
+	{ 7378,-1255,-1043,-4088,12251,2048,-876,1946,5805 } },
     { "Canon PowerShot G1 X", 0, 0,
 	{ 7378,-1255,-1043,-4088,12251,2048,-876,1946,5805 } },
     { "Canon PowerShot G1", 0, 0,
@@ -6383,6 +11973,8 @@ void CLASS adobe_coeff (const char *make, const char *model)
 	{ 9757,-2872,-933,-5972,13861,2301,-1622,2328,7212 } },
     { "Canon PowerShot G6", 0, 0,
 	{ 9877,-3775,-871,-7613,14807,3072,-1448,1305,7485 } },
+    { "Canon PowerShot G7 X", 0, 0,
+	{ 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } },
     { "Canon PowerShot G9", 0, 0,
 	{ 7368,-2141,-598,-5621,13254,2625,-1418,1696,5743 } },
     { "Canon PowerShot Pro1", 0, 0,
@@ -6407,8 +11999,20 @@ void CLASS adobe_coeff (const char *make, const char *model)
 	{ 12374,-5016,-1049,-1677,9902,2078,-83,852,4683 } },
     { "Canon PowerShot S95", 0, 0,
 	{ 13440,-5896,-1279,-1236,9598,1931,-180,1001,4651 } },
+    { "Canon PowerShot S120", 0, 0, /* LibRaw */
+      { 10800,-4782,-628,-2057,10783,1176,-802,2091,4739 } },
+    { "Canon PowerShot S110", 0, 0,
+	{ 8039,-2643,-654,-3783,11230,2930,-206,690,4194 } },
     { "Canon PowerShot S100", 0, 0,
 	{ 7968,-2565,-636,-2873,10697,2513,180,667,4211 } },
+    { "Canon PowerShot SX1 IS", 0, 0,
+	{ 6578,-259,-502,-5974,13030,3309,-308,1058,4970 } },
+    { "Canon PowerShot SX50 HS", 0, 0,
+	{ 12432,-4753,-1247,-2110,10691,1629,-412,1623,4926 } },
+    { "Canon PowerShot SX60 HS", 0, 0,
+	{ 13161,-5451,-1344,-1989,10654,1531,-47,1271,4955 } },
+    { "Canon PowerShot A3300", 0, 0,	/* DJC */
+	{ 10826,-3654,-1023,-3215,11310,1906,0,999,4960 } },
     { "Canon PowerShot A470", 0, 0,	/* DJC */
 	{ 12513,-4407,-1242,-2680,10276,2405,-878,2215,4734 } },
     { "Canon PowerShot A610", 0, 0,	/* DJC */
@@ -6425,17 +12029,15 @@ void CLASS adobe_coeff (const char *make, const char *model)
 	{ 14573,-5482,-1546,-1266,9799,1468,-1040,1912,3810 } },
     { "Canon PowerShot S3 IS", 0, 0,	/* DJC */
 	{ 14062,-5199,-1446,-4712,12470,2243,-1286,2028,4836 } },
-    { "Canon PowerShot SX1 IS", 0, 0,
-	{ 6578,-259,-502,-5974,13030,3309,-308,1058,4970 } },
     { "Canon PowerShot SX110 IS", 0, 0,	/* DJC */
 	{ 14134,-5576,-1527,-1991,10719,1273,-1158,1929,3581 } },
     { "Canon PowerShot SX220", 0, 0,	/* DJC */
 	{ 13898,-5076,-1447,-1405,10109,1297,-244,1860,3687 } },
-    { "CASIO EX-S20", 0, 0,		/* DJC */
+    { "Casio EX-S20", 0, 0,		/* DJC */
 	{ 11634,-3924,-1128,-4968,12954,2015,-1588,2648,7206 } },
-    { "CASIO EX-Z750", 0, 0,		/* DJC */
+    { "Casio EX-Z750", 0, 0,		/* DJC */
 	{ 10819,-3873,-1099,-4903,13730,1175,-1755,3751,4632 } },
-    { "CASIO EX-Z10", 128, 0xfff,	/* DJC */
+    { "Casio EX-Z10", 128, 0xfff,	/* DJC */
 	{ 9790,-3338,-603,-2321,10222,2099,-344,1273,4799 } },
     { "CINE 650", 0, 0,
 	{ 3390,480,-500,-800,3610,340,-550,2336,1192 } },
@@ -6445,99 +12047,155 @@ void CLASS adobe_coeff (const char *make, const char *model)
 	{ 20183,-4295,-423,-3940,15330,3985,-280,4870,9800 } },
     { "Contax N Digital", 0, 0xf1e,
 	{ 7777,1285,-1053,-9280,16543,2916,-3677,5679,7060 } },
-    { "EPSON R-D1", 0, 0,
+    { "Epson R-D1", 0, 0,
 	{ 6827,-1878,-732,-8429,16012,2564,-704,592,7145 } },
-    { "FUJIFILM E550", 0, 0,
+    { "Fujifilm E550", 0, 0,
 	{ 11044,-3888,-1120,-7248,15168,2208,-1531,2277,8069 } },
-    { "FUJIFILM E900", 0, 0,
+    { "Fujifilm E900", 0, 0,
 	{ 9183,-2526,-1078,-7461,15071,2574,-2022,2440,8639 } },
-    { "FUJIFILM F5", 0, 0,
+    { "Fujifilm F5", 0, 0,
 	{ 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
-    { "FUJIFILM F6", 0, 0,
+    { "Fujifilm F6", 0, 0,
 	{ 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
-    { "FUJIFILM F77", 0, 0,
+    { "Fujifilm F77", 0, 0xfe9,
 	{ 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
-    { "FUJIFILM F7", 0, 0,
+    { "Fujifilm F7", 0, 0,
 	{ 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } },
-    { "FUJIFILM F8", 0, 0,
-	{ 11044,-3888,-1120,-7248,15168,2208,-1531,2277,8069 } },
-    { "FUJIFILM S100FS", 514, 0,
+    { "Fujifilm F8", 0, 0,
+	{ 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
+    { "Fujifilm S100FS", 514, 0,
 	{ 11521,-4355,-1065,-6524,13767,3058,-1466,1984,6045 } },
-    { "FUJIFILM S200EXR", 512, 0x3fff,
-	{ 11401,-4498,-1312,-5088,12751,2613,-838,1568,5941 } },
-    { "FUJIFILM S20Pro", 0, 0,
+    { "Fujifilm S1", 0, 0,
+	{ 12297,-4882,-1202,-2106,10691,1623,-88,1312,4790 } },
+    { "Fujifilm S20Pro", 0, 0,
 	{ 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } },
-    { "FUJIFILM S2Pro", 128, 0,
+    { "Fujifilm S20", 512, 0x3fff,
+	{ 11401,-4498,-1312,-5088,12751,2613,-838,1568,5941 } },
+    { "Fujifilm S2Pro", 128, 0,
 	{ 12492,-4690,-1402,-7033,15423,1647,-1507,2111,7697 } },
-    { "FUJIFILM S3Pro", 0, 0,
+    { "Fujifilm S3Pro", 0, 0,
 	{ 11807,-4612,-1294,-8927,16968,1988,-2120,2741,8006 } },
-    { "FUJIFILM S5Pro", 0, 0,
+    { "Fujifilm S5Pro", 0, 0,
 	{ 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } },
-    { "FUJIFILM S5000", 0, 0,
+    { "Fujifilm S5000", 0, 0,
 	{ 8754,-2732,-1019,-7204,15069,2276,-1702,2334,6982 } },
-    { "FUJIFILM S5100", 0, 0,
+    { "Fujifilm S5100", 0, 0,
 	{ 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } },
-    { "FUJIFILM S5500", 0, 0,
+    { "Fujifilm S5500", 0, 0,
 	{ 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } },
-    { "FUJIFILM S5200", 0, 0,
+    { "Fujifilm S5200", 0, 0,
 	{ 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } },
-    { "FUJIFILM S5600", 0, 0,
+    { "Fujifilm S5600", 0, 0,
 	{ 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } },
-    { "FUJIFILM S6", 0, 0,
+    { "Fujifilm S6", 0, 0,
 	{ 12628,-4887,-1401,-6861,14996,1962,-2198,2782,7091 } },
-    { "FUJIFILM S7000", 0, 0,
+    { "Fujifilm S7000", 0, 0,
 	{ 10190,-3506,-1312,-7153,15051,2238,-2003,2399,7505 } },
-    { "FUJIFILM S9000", 0, 0,
+    { "Fujifilm S9000", 0, 0,
 	{ 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } },
-    { "FUJIFILM S9500", 0, 0,
+    { "Fujifilm S9500", 0, 0,
 	{ 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } },
-    { "FUJIFILM S9100", 0, 0,
+    { "Fujifilm S9100", 0, 0,
 	{ 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } },
-    { "FUJIFILM S9600", 0, 0,
+    { "Fujifilm S9600", 0, 0,
 	{ 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } },
-    { "FUJIFILM IS-1", 0, 0,
+    { "Fujifilm SL1000", 0, 0,
+	{ 11705,-4262,-1107,-2282,10791,1709,-555,1713,4945 } },
+    { "Fujifilm IS-1", 0, 0,
 	{ 21461,-10807,-1441,-2332,10599,1999,289,875,7703 } },
-    { "FUJIFILM IS Pro", 0, 0,
+    { "Fujifilm IS Pro", 0, 0,
 	{ 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } },
-    { "FUJIFILM HS10 HS11", 0, 0xf68,
+    { "Fujifilm HS10 HS11", 0, 0xf68,
 	{ 12440,-3954,-1183,-1123,9674,1708,-83,1614,4086 } },
-    { "FUJIFILM HS20EXR", 0, 0,
+    { "Fujifilm HS2", 0, 0,
 	{ 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
-    { "FUJIFILM HS3", 0, 0,
+    { "Fujifilm HS3", 0, 0,
 	{ 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
-    { "FUJIFILM X100", 0, 0,
+    { "Fujifilm HS50EXR", 0, 0,
+	{ 12085,-4727,-953,-3257,11489,2002,-511,2046,4592 } },
+    { "Fujifilm F900EXR", 0, 0,
+	{ 12085,-4727,-953,-3257,11489,2002,-511,2046,4592 } },
+    { "Fujifilm X100S", 0, 0,
+	{ 10592,-4262,-1008,-3514,11355,2465,-870,2025,6386 } },
+    { "Fujifilm X100T", 0, 0,
+	{ 10592,-4262,-1008,-3514,11355,2465,-870,2025,6386 } },
+    { "Fujifilm X100", 0, 0,
 	{ 12161,-4457,-1069,-5034,12874,2400,-795,1724,6904 } },
-    { "FUJIFILM X10", 0, 0,
+    { "Fujifilm X10", 0, 0,
 	{ 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } },
-    { "FUJIFILM X-Pro1", 0, 0,
+    { "Fujifilm X20", 0, 0,
+	{ 11768,-4971,-1133,-4904,12927,2183,-480,1723,4605 } },
+    { "Fujifilm X30", 0, 0,
+	{ 12328,-5256,-1144,-4469,12927,1675,-87,1291,4351 } },
+    { "Fujifilm X-Pro1", 0, 0,
 	{ 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } },
-    { "FUJIFILM X-S1", 0, 0,
+    { "Fujifilm X-A1", 0, 0,
+        { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } },
+    { "Fujifilm X-E1", 0, 0,
+	{ 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } },
+    { "Fujifilm X-E2", 0, 0,
+      { 12066,-5927,-367,-1969,9878,1503,-721,2034,5453 } },
+    { "Fujifilm XF1", 0, 0,
+	{ 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } },
+    { "Fujifilm X-M1", 0, 0,
+      { 13193,-6685,-425,-2229,10458,1534,-878,1763,5217 } },
+    { "Fujifilm X-S1", 0, 0,
 	{ 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } },
+    { "Fujifilm X-T1", 0, 0, /* LibRaw */
+      { 12066,-5927,-367,-1969,9878,1503,-721,2034,5453 } },
+    { "Fujifilm XQ1", 0, 0,
+      { 14305,-7365,-687,-3117,12383,432,-287,1660,4361 } },
+    { "Hasselblad Lunar", -512, 0,
+	{ 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } },
+    { "Hasselblad Stellar", -800, 0,
+	{ 8651,-2754,-1057,-3464,12207,1373,-568,1398,4434 } },
+    { "Hasselblad CFV", 0, 0, /* Adobe */
+	{ 8519, -3260, -280, -5081, 13459, 1738, -1449, 2960, 7809, } },
+    { "Hasselblad H-16MP", 0, 0, /* LibRaw */
+	{ 17765,-5322,-1734,-6168,13354,2135,-264,2524,7440 } },
+    { "Hasselblad H-22MP", 0, 0, /* LibRaw */
+	{ 17765,-5322,-1734,-6168,13354,2135,-264,2524,7440 } },
+    {"Hasselblad H-31MP",0, 0, /* LibRaw */
+	{ 14480,-5448,-1686,-3534,13123,2260,384,2952,7232 } },
+    {"Hasselblad H-39MP",0, 0, /* Adobe */
+	{3857,452, -46, -6008, 14477, 1596, -2627, 4481, 5718}},
+    { "Hasselblad H3D-50", 0, 0, /* Adobe  */
+	{3857,452, -46, -6008, 14477, 1596, -2627, 4481, 5718}},
+    {"Hasselblad H4D-40",0, 0, /* LibRaw */
+	{ 6325,-860,-957,-6559,15945,266,167,770,5936 } },
+    {"Hasselblad H4D-50",0, 0, /* LibRaw */
+	{ 15283,-6272,-465,-2030,16031,478,-2379,390,7965 } },
+    {"Hasselblad H4D-60",0, 0, /* Adobe */
+        {9662, -684, -279, -4903, 12293, 2950, -344, 1669, 6024}},
+    {"Hasselblad H5D-50c",0, 0, /* Adobe */
+	{4932, -835, 141, -4878, 11868, 3437, -1138, 1961, 7067}},
+    {"Hasselblad H5D-50",0, 0, /* Adobe */
+	{5656, -659, -346, -3923, 12306, 1791, -1602, 3509, 5442}},
     { "Imacon Ixpress", 0, 0,		/* DJC */
 	{ 7025,-1415,-704,-5188,13765,1424,-1248,2742,6038 } },
-    { "KODAK NC2000", 0, 0,
+    { "Kodak NC2000", 0, 0,
 	{ 13891,-6055,-803,-465,9919,642,2121,82,1291 } },
-    { "Kodak DCS315C", 8, 0,
+    { "Kodak DCS315C", -8, 0,
 	{ 17523,-4827,-2510,756,8546,-137,6113,1649,2250 } },
-    { "Kodak DCS330C", 8, 0,
+    { "Kodak DCS330C", -8, 0,
 	{ 20620,-7572,-2801,-103,10073,-396,3551,-233,2220 } },
-    { "KODAK DCS420", 0, 0,
+    { "Kodak DCS420", 0, 0,
 	{ 10868,-1852,-644,-1537,11083,484,2343,628,2216 } },
-    { "KODAK DCS460", 0, 0,
+    { "Kodak DCS460", 0, 0,
 	{ 10592,-2206,-967,-1944,11685,230,2206,670,1273 } },
-    { "KODAK EOSDCS1", 0, 0,
+    { "Kodak EOSDCS1", 0, 0,
 	{ 10592,-2206,-967,-1944,11685,230,2206,670,1273 } },
-    { "KODAK EOSDCS3B", 0, 0,
+    { "Kodak EOSDCS3B", 0, 0,
 	{ 9898,-2700,-940,-2478,12219,206,1985,634,1031 } },
-    { "Kodak DCS520C", 180, 0,
+    { "Kodak DCS520C", -178, 0,
 	{ 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } },
-    { "Kodak DCS560C", 188, 0,
+    { "Kodak DCS560C", -177, 0,
 	{ 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } },
-    { "Kodak DCS620C", 180, 0,
+    { "Kodak DCS620C", -177, 0,
 	{ 23617,-10175,-3149,-2054,11749,-272,2586,-489,3453 } },
-    { "Kodak DCS620X", 185, 0,
+    { "Kodak DCS620X", -176, 0,
 	{ 13095,-6231,154,12221,-21,-2137,895,4602,2258 } },
-    { "Kodak DCS660C", 214, 0,
+    { "Kodak DCS660C", -173, 0,
 	{ 18244,-6351,-2739,-791,11193,-521,3711,-129,2802 } },
     { "Kodak DCS720X", 0, 0,
 	{ 11775,-5884,950,9556,1846,-1286,-1019,6221,2728 } },
@@ -6553,19 +12211,19 @@ void CLASS adobe_coeff (const char *make, const char *model)
 	{ 16414,-6060,-1470,-3555,13037,473,2545,122,4948 } },
     { "Kodak ProBack", 0, 0,
 	{ 21179,-8316,-2918,-915,11019,-165,3477,-180,4210 } },
-    { "KODAK P712", 0, 0,
+    { "Kodak P712", 0, 0,
 	{ 9658,-3314,-823,-5163,12695,2768,-1342,1843,6044 } },
-    { "KODAK P850", 0, 0xf7c,
+    { "Kodak P850", 0, 0xf7c,
 	{ 10511,-3836,-1102,-6946,14587,2558,-1481,1792,6246 } },
-    { "KODAK P880", 0, 0xfff,
+    { "Kodak P880", 0, 0xfff,
 	{ 12805,-4662,-1376,-7480,15267,2360,-1626,2194,7904 } },
-    { "KODAK EasyShare Z980", 0, 0,
+    { "Kodak EasyShare Z980", 0, 0,
 	{ 11313,-3559,-1101,-3893,11891,2257,-1214,2398,4908 } },
-    { "KODAK EasyShare Z981", 0, 0,
+    { "Kodak EasyShare Z981", 0, 0,
 	{ 12729,-4717,-1188,-1367,9187,2582,274,860,4411 } },
-    { "KODAK EasyShare Z990", 0, 0xfed,
+    { "Kodak EasyShare Z990", 0, 0xfed,
 	{ 11749,-4048,-1309,-1867,10572,1489,-138,1449,4522 } },
-    { "KODAK EASYSHARE Z1015", 0, 0xef1,
+    { "Kodak EASYSHARE Z1015", 0, 0xef1,
 	{ 11265,-4286,-992,-4694,12343,2647,-1090,1523,5447 } },
     { "Leaf CMost", 0, 0,
 	{ 3952,2189,449,-6701,14585,2275,-4536,7349,6536 } },
@@ -6577,6 +12235,14 @@ void CLASS adobe_coeff (const char *make, const char *model)
 	{ 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } },
     { "Leaf Aptus 75", 0, 0,
 	{ 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } },
+    { "Leaf Credo 40", 0, 0,
+	{ 8035, 435, -962, -6001, 13872, 2320, -1159, 3065, 5434 } },
+    { "Leaf Credo 50", 0, 0,
+	{ 3984, 0, 0, 0, 10000, 0, 0, 0, 7666 } },
+    { "Leaf Credo 60", 0, 0,
+	{ 8035, 435, -962, -6001, 13872,2320,-1159,3065,5434} },
+    { "Leaf Credo 80", 0, 0,
+	{ 6294, 686, -712, -5435, 13417, 2211, -1006, 2435, 5042} },
     { "Leaf", 0, 0,
 	{ 8236,1746,-1314,-8251,15953,2428,-3673,5786,5771 } },
     { "Mamiya ZD", 0, 0,
@@ -6591,294 +12257,430 @@ void CLASS adobe_coeff (const char *make, const char *model)
 	{ 9144,-2777,-998,-6676,14556,2281,-2470,3019,7744 } },
     { "Minolta DiMAGE A1", 0, 0xf8b,
 	{ 9274,-2547,-1167,-8220,16323,1943,-2273,2720,8340 } },
-    { "MINOLTA DiMAGE A200", 0, 0,
+    { "Minolta DiMAGE A200", 0, 0,
 	{ 8560,-2487,-986,-8112,15535,2771,-1209,1324,7743 } },
     { "Minolta DiMAGE A2", 0, 0xf8f,
 	{ 9097,-2726,-1053,-8073,15506,2762,-966,981,7763 } },
     { "Minolta DiMAGE Z2", 0, 0,	/* DJC */
 	{ 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } },
-    { "MINOLTA DYNAX 5", 0, 0xffb,
+    { "Minolta DYNAX 5", 0, 0xffb,
 	{ 10284,-3283,-1086,-7957,15762,2316,-829,882,6644 } },
-    { "MINOLTA DYNAX 7", 0, 0xffb,
+    { "Minolta DYNAX 7", 0, 0xffb,
 	{ 10239,-3104,-1099,-8037,15727,2451,-927,925,6871 } },
-    { "MOTOROLA PIXL", 0, 0,		/* DJC */
+    { "Motorola PIXL", 0, 0,		/* DJC */
 	{ 8898,-989,-1033,-3292,11619,1674,-661,3178,5216 } },
-    { "NIKON D100", 0, 0,
+    { "Nikon D100", 0, 0,
 	{ 5902,-933,-782,-8983,16719,2354,-1402,1455,6464 } },
-    { "NIKON D1H", 0, 0,
+    { "Nikon D1H", 0, 0,
 	{ 7577,-2166,-926,-7454,15592,1934,-2377,2808,8606 } },
-    { "NIKON D1X", 0, 0,
+    { "Nikon D1X", 0, 0,
 	{ 7702,-2245,-975,-9114,17242,1875,-2679,3055,8521 } },
-    { "NIKON D1", 0, 0, /* multiplied by 2.218750, 1.0, 1.148438 */
+    { "Nikon D1", 0, 0, /* multiplied by 2.218750, 1.0, 1.148438 */
 	{ 16772,-4726,-2141,-7611,15713,1972,-2846,3494,9521 } },
-    { "NIKON D200", 0, 0xfbc,
+    { "Nikon D200", 0, 0xfbc,
 	{ 8367,-2248,-763,-8758,16447,2422,-1527,1550,8053 } },
-    { "NIKON D2H", 0, 0,
+    { "Nikon D2H", 0, 0,
 	{ 5710,-901,-615,-8594,16617,2024,-2975,4120,6830 } },
-    { "NIKON D2X", 0, 0,
+    { "Nikon D2X", 0, 0,
 	{ 10231,-2769,-1255,-8301,15900,2552,-797,680,7148 } },
-    { "NIKON D3000", 0, 0,
+    { "Nikon D3000", 0, 0,
 	{ 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } },
-    { "NIKON D3100", 0, 0,
+    { "Nikon D3100", 0, 0,
 	{ 7911,-2167,-813,-5327,13150,2408,-1288,2483,7968 } },
-    { "NIKON D3200", 0, 0,
+    { "Nikon D3200", 0, 0xfb9,
 	{ 7013,-1408,-635,-5268,12902,2640,-1470,2801,7379 } },
-    { "NIKON D300", 0, 0,
+    { "Nikon D3300", 0, 0,
+	{ 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 } },
+    { "Nikon D300", 0, 0,
 	{ 9030,-1992,-715,-8465,16302,2255,-2689,3217,8069 } },
-    { "NIKON D3X", 0, 0,
+    { "Nikon D3X", 0, 0,
 	{ 7171,-1986,-648,-8085,15555,2718,-2170,2512,7457 } },
-    { "NIKON D3S", 0, 0,
+    { "Nikon D3S", 0, 0,
 	{ 8828,-2406,-694,-4874,12603,2541,-660,1509,7587 } },
-    { "NIKON D3", 0, 0,
+    { "Nikon D3", 0, 0,
 	{ 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } },
-    { "NIKON D40X", 0, 0,
+    { "Nikon D40X", 0, 0,
 	{ 8819,-2543,-911,-9025,16928,2151,-1329,1213,8449 } },
-    { "NIKON D40", 0, 0,
+    { "Nikon D40", 0, 0,
 	{ 6992,-1668,-806,-8138,15748,2543,-874,850,7897 } },
-    { "NIKON D4", 0, 0,
+    { "Nikon D4S", 0, 0,
+	{ 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } },
+    { "Nikon D4", 0, 0,
 	{ 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } },
-    { "NIKON D5000", 0, 0xf00,
+    { "Nikon Df", 0, 0,
+	{ 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } },
+    { "Nikon D5000", 0, 0xf00,
 	{ 7309,-1403,-519,-8474,16008,2622,-2433,2826,8064 } },
-    { "NIKON D5100", 0, 0x3de6,
+    { "Nikon D5100", 0, 0x3de6,
 	{ 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } },
-    { "NIKON D50", 0, 0,
+    { "Nikon D5200", 0, 0,
+	{ 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } },
+    { "Nikon D5300", 0, 0,
+	{ 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 } },
+    { "Nikon D5500", 0, 0,		/* DJC */
+	{ 5765,-2176,184,-3736,9072,4664,-1028,2213,9259 } },
+    { "Nikon D50", 0, 0,
 	{ 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } },
-    { "NIKON D60", 0, 0,
+    { "Nikon D600", 0, 0x3e07,
+	{ 8178,-2245,-609,-4857,12394,2776,-1207,2086,7298 } },
+    {"Nikon D610",0, 0,
+        { 10426,-4005,-444,-3565,11764,1403,-1206,2266,6549 } },
+    { "Nikon D60", 0, 0,
 	{ 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } },
-    { "NIKON D7000", 0, 0,
+    { "Nikon D7000", 0, 0,
 	{ 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } },
-    { "NIKON D700", 0, 0,
+    { "Nikon D7100", 0, 0,
+	{ 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } },
+    { "Nikon D750", 0, 0,
+	{ 9020,-2890,-715,-4535,12436,2348,-934,1919,7086 } },
+    { "Nikon D700", 0, 0,
 	{ 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } },
-    { "NIKON D70", 0, 0,
+    { "Nikon D70", 0, 0,
 	{ 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } },
-    { "NIKON D800", 0, 0,
+    { "Nikon D810", 0, 0,
+	{ 9369,-3195,-791,-4488,12430,2301,-893,1796,6872 } },
+    { "Nikon D800", 0, 0,
 	{ 7866,-2108,-555,-4869,12483,2681,-1176,2069,7501 } },
-    { "NIKON D80", 0, 0,
+    { "Nikon D80", 0, 0,
 	{ 8629,-2410,-883,-9055,16940,2171,-1490,1363,8520 } },
-    { "NIKON D90", 0, 0xf00,
+    { "Nikon D90", 0, 0xf00,
 	{ 7309,-1403,-519,-8474,16008,2622,-2434,2826,8064 } },
-    { "NIKON E950", 0, 0x3dd,		/* DJC */
+    { "Nikon E700", 0, 0x3dd,		/* DJC */
+	{ -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } },
+    { "Nikon E800", 0, 0x3dd,		/* DJC */
 	{ -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } },
-    { "NIKON E995", 0, 0,	/* copied from E5000 */
+    { "Nikon E950", 0, 0x3dd,		/* DJC */
+	{ -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } },
+    { "Nikon E995", 0, 0,	/* copied from E5000 */
 	{ -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
-    { "NIKON E2100", 0, 0,	/* copied from Z2, new white balance */
+    { "Nikon E2100", 0, 0,	/* copied from Z2, new white balance */
 	{ 13142,-4152,-1596,-4655,12374,2282,-1769,2696,6711} },
-    { "NIKON E2500", 0, 0,
+    { "Nikon E2500", 0, 0,
 	{ -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
-    { "NIKON E3200", 0, 0,		/* DJC */
+    { "Nikon E3200", 0, 0,		/* DJC */
 	{ 9846,-2085,-1019,-3278,11109,2170,-774,2134,5745 } },
-    { "NIKON E4300", 0, 0,	/* copied from Minolta DiMAGE Z2 */
+    { "Nikon E4300", 0, 0,	/* copied from Minolta DiMAGE Z2 */
 	{ 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } },
-    { "NIKON E4500", 0, 0,
+    { "Nikon E4500", 0, 0,
 	{ -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
-    { "NIKON E5000", 0, 0,
+    { "Nikon E5000", 0, 0,
 	{ -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
-    { "NIKON E5400", 0, 0,
+    { "Nikon E5400", 0, 0,
 	{ 9349,-2987,-1001,-7919,15766,2266,-2098,2680,6839 } },
-    { "NIKON E5700", 0, 0,
+    { "Nikon E5700", 0, 0,
 	{ -5368,11478,2368,5537,-113,3148,-4969,10021,5782,778,9028,211 } },
-    { "NIKON E8400", 0, 0,
+    { "Nikon E8400", 0, 0,
 	{ 7842,-2320,-992,-8154,15718,2599,-1098,1342,7560 } },
-    { "NIKON E8700", 0, 0,
+    { "Nikon E8700", 0, 0,
 	{ 8489,-2583,-1036,-8051,15583,2643,-1307,1407,7354 } },
-    { "NIKON E8800", 0, 0,
+    { "Nikon E8800", 0, 0,
 	{ 7971,-2314,-913,-8451,15762,2894,-1442,1520,7610 } },
-    { "NIKON COOLPIX P6000", 0, 0,
+    { "Nikon COOLPIX A", 0, 0,
+	{ 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } },
+    { "Nikon COOLPIX P330", -200, 0,
+	{ 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } },
+    { "Nikon COOLPIX P340", -200, 0,
+        { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } },
+    { "Nikon COOLPIX P6000", 0, 0,
 	{ 9698,-3367,-914,-4706,12584,2368,-837,968,5801 } },
-    { "NIKON COOLPIX P7000", 0, 0,
+    { "Nikon COOLPIX P7000", 0, 0,
 	{ 11432,-3679,-1111,-3169,11239,2202,-791,1380,4455 } },
-    { "NIKON COOLPIX P7100", 0, 0,
+    { "Nikon COOLPIX P7100", 0, 0,
 	{ 11053,-4269,-1024,-1976,10182,2088,-526,1263,4469 } },
-    { "NIKON 1 ", 0, 0,
+    { "Nikon COOLPIX P7700", -3200, 0,
+	{ 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } },
+    { "Nikon COOLPIX P7800", -3200, 0, /* LibRaw */
+      { 13443,-6418,-673,-1309,10025,1131,-462,1827,4782 } },
+    { "Nikon 1 V3", -200, 0,
+	{ 5958,-1559,-571,-4021,11453,2939,-634,1548,5087 } },
+    { "Nikon 1 J4", 0, 0,
+	{ 5958,-1559,-571,-4021,11453,2939,-634,1548,5087 } },
+    { "Nikon 1 S2", 200, 0,
+	{ 6612,-1342,-618,-3338,11055,2623,-174,1792,5075 } },
+    { "Nikon 1 V2", 0, 0,
+	{ 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } },
+    { "Nikon 1 J3", 0, 0,
+      { 8144,-2671,-473,-1740,9834,1601,-58,1971,4296 } },
+    { "Nikon 1 AW1", 0, 0,
+	{ 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } },
+    { "Nikon 1 ", 0, 0,		/* J1, J2, S1, V1 */
 	{ 8994,-2667,-865,-4594,12324,2552,-699,1786,6260 } },
-    { "OLYMPUS C5050", 0, 0,
+    { "Olympus C5050", 0, 0,
 	{ 10508,-3124,-1273,-6079,14294,1901,-1653,2306,6237 } },
-    { "OLYMPUS C5060", 0, 0,
+    { "Olympus C5060", 0, 0,
 	{ 10445,-3362,-1307,-7662,15690,2058,-1135,1176,7602 } },
-    { "OLYMPUS C7070", 0, 0,
+    { "Olympus C7070", 0, 0,
 	{ 10252,-3531,-1095,-7114,14850,2436,-1451,1723,6365 } },
-    { "OLYMPUS C70", 0, 0,
+    { "Olympus C70", 0, 0,
 	{ 10793,-3791,-1146,-7498,15177,2488,-1390,1577,7321 } },
-    { "OLYMPUS C80", 0, 0,
+    { "Olympus C80", 0, 0,
 	{ 8606,-2509,-1014,-8238,15714,2703,-942,979,7760 } },
-    { "OLYMPUS E-10", 0, 0xffc,
+    { "Olympus E-10", 0, 0xffc,
 	{ 12745,-4500,-1416,-6062,14542,1580,-1934,2256,6603 } },
-    { "OLYMPUS E-1", 0, 0,
+    { "Olympus E-1", 0, 0,
 	{ 11846,-4767,-945,-7027,15878,1089,-2699,4122,8311 } },
-    { "OLYMPUS E-20", 0, 0xffc,
+    { "Olympus E-20", 0, 0xffc,
 	{ 13173,-4732,-1499,-5807,14036,1895,-2045,2452,7142 } },
-    { "OLYMPUS E-300", 0, 0,
+    { "Olympus E-300", 0, 0,
 	{ 7828,-1761,-348,-5788,14071,1830,-2853,4518,6557 } },
-    { "OLYMPUS E-330", 0, 0,
+    { "Olympus E-330", 0, 0,
 	{ 8961,-2473,-1084,-7979,15990,2067,-2319,3035,8249 } },
-    { "OLYMPUS E-30", 0, 0xfbc,
+    { "Olympus E-30", 0, 0xfbc,
 	{ 8144,-1861,-1111,-7763,15894,1929,-1865,2542,7607 } },
-    { "OLYMPUS E-3", 0, 0xf99,
+    { "Olympus E-3", 0, 0xf99,
 	{ 9487,-2875,-1115,-7533,15606,2010,-1618,2100,7389 } },
-    { "OLYMPUS E-400", 0, 0,
+    { "Olympus E-400", 0, 0,
 	{ 6169,-1483,-21,-7107,14761,2536,-2904,3580,8568 } },
-    { "OLYMPUS E-410", 0, 0xf6a,
+    { "Olympus E-410", 0, 0xf6a,
 	{ 8856,-2582,-1026,-7761,15766,2082,-2009,2575,7469 } },
-    { "OLYMPUS E-420", 0, 0xfd7,
+    { "Olympus E-420", 0, 0xfd7,
 	{ 8746,-2425,-1095,-7594,15612,2073,-1780,2309,7416 } },
-    { "OLYMPUS E-450", 0, 0xfd2,
+    { "Olympus E-450", 0, 0xfd2,
 	{ 8745,-2425,-1095,-7594,15613,2073,-1780,2309,7416 } },
-    { "OLYMPUS E-500", 0, 0,
+    { "Olympus E-500", 0, 0,
 	{ 8136,-1968,-299,-5481,13742,1871,-2556,4205,6630 } },
-    { "OLYMPUS E-510", 0, 0xf6a,
+    { "Olympus E-510", 0, 0xf6a,
 	{ 8785,-2529,-1033,-7639,15624,2112,-1783,2300,7817 } },
-    { "OLYMPUS E-520", 0, 0xfd2,
+    { "Olympus E-520", 0, 0xfd2,
 	{ 8344,-2322,-1020,-7596,15635,2048,-1748,2269,7287 } },
-    { "OLYMPUS E-5", 0, 0,
+    { "Olympus E-5", 0, 0xeec,
 	{ 11200,-3783,-1325,-4576,12593,2206,-695,1742,7504 } },
-    { "OLYMPUS E-600", 0, 0xfaf,
+    { "Olympus E-600", 0, 0xfaf,
 	{ 8453,-2198,-1092,-7609,15681,2008,-1725,2337,7824 } },
-    { "OLYMPUS E-620", 0, 0xfaf,
+    { "Olympus E-620", 0, 0xfaf,
 	{ 8453,-2198,-1092,-7609,15681,2008,-1725,2337,7824 } },
-    { "OLYMPUS E-P1", 0, 0xffd,
+    { "Olympus E-P1", 0, 0xffd,
 	{ 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } },
-    { "OLYMPUS E-P2", 0, 0xffd,
+    { "Olympus E-P2", 0, 0xffd,
 	{ 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } },
-    { "OLYMPUS E-P3", 0, 0,
+    { "Olympus E-P3", 0, 0,
 	{ 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } },
-    { "OLYMPUS E-PL1s", 0, 0,
+    { "Olympus E-P5", 0, 0,
+	{ 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
+    { "Olympus E-PL1s", 0, 0,
 	{ 11409,-3872,-1393,-4572,12757,2003,-709,1810,7415 } },
-    { "OLYMPUS E-PL1", 0, 0,
+    { "Olympus E-PL1", 0, 0,
 	{ 11408,-4289,-1215,-4286,12385,2118,-387,1467,7787 } },
-    { "OLYMPUS E-PL2", 0, 0,
+    { "Olympus E-PL2", 0, 0xcf3,
 	{ 15030,-5552,-1806,-3987,12387,1767,-592,1670,7023 } },
-    { "OLYMPUS E-PL3", 0, 0,
+    { "Olympus E-PL3", 0, 0,
 	{ 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } },
-    { "OLYMPUS E-PM1", 0, 0,
+    { "Olympus E-PL5", 0, 0xfcb,
+	{ 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
+    { "Olympus E-PL6", 0, 0,
+	{ 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
+    { "Olympus E-PL7", 0, 0,
+	{ 9197,-3190,-659,-2606,10830,2039,-458,1250,5458 } },
+    { "Olympus E-PM1", 0, 0,
 	{ 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } },
-    { "OLYMPUS E-M5", 0, 0,
+    { "Olympus E-PM2", 0, 0,
+	{ 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
+    { "Olympus E-M10", 0, 0,
 	{ 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
-    { "OLYMPUS SP350", 0, 0,
+    { "Olympus E-M1", 0, 0,
+	{ 7687,-1984,-606,-4327,11928,2721,-1381,2339,6452 } },
+    { "Olympus E-M5MarkII", 0, 0,	/* DJC */
+	{ 6617,-2589,139,-2917,8499,4419,-884,1913,6829 } },
+    { "Olympus E-M5", 0, 0xfe1,
+	{ 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
+    { "Olympus SP350", 0, 0,
 	{ 12078,-4836,-1069,-6671,14306,2578,-786,939,7418 } },
-    { "OLYMPUS SP3", 0, 0,
+    { "Olympus SP3", 0, 0,
 	{ 11766,-4445,-1067,-6901,14421,2707,-1029,1217,7572 } },
-    { "OLYMPUS SP500UZ", 0, 0xfff,
+    { "Olympus SP500UZ", 0, 0xfff,
 	{ 9493,-3415,-666,-5211,12334,3260,-1548,2262,6482 } },
-    { "OLYMPUS SP510UZ", 0, 0xffe,
+    { "Olympus SP510UZ", 0, 0xffe,
 	{ 10593,-3607,-1010,-5881,13127,3084,-1200,1805,6721 } },
-    { "OLYMPUS SP550UZ", 0, 0xffe,
+    { "Olympus SP550UZ", 0, 0xffe,
 	{ 11597,-4006,-1049,-5432,12799,2957,-1029,1750,6516 } },
-    { "OLYMPUS SP560UZ", 0, 0xff9,
+    { "Olympus SP560UZ", 0, 0xff9,
 	{ 10915,-3677,-982,-5587,12986,2911,-1168,1968,6223 } },
-    { "OLYMPUS SP570UZ", 0, 0,
+    { "Olympus SP570UZ", 0, 0,
 	{ 11522,-4044,-1146,-4736,12172,2904,-988,1829,6039 } },
-    { "OLYMPUS XZ-1", 0, 0,
+    {"Olympus STYLUS1",0, 0,
+        { 11976,-5518,-545,-1419,10472,846,-475,1766,4524 } },
+    { "Olympus XZ-10", 0, 0,
+	{ 9777,-3483,-925,-2886,11297,1800,-602,1663,5134 } },
+    { "Olympus XZ-1", 0, 0,
 	{ 10901,-4095,-1074,-1141,9208,2293,-62,1417,5158 } },
-    { "PENTAX *ist DL2", 0, 0,
+    { "Olympus XZ-2", 0, 0,
+	{ 9777,-3483,-925,-2886,11297,1800,-602,1663,5134 } },
+    { "OmniVision", 0, 0,		/* DJC */
+	{ 12782,-4059,-379,-478,9066,1413,1340,1513,5176 } },
+    { "Pentax *ist DL2", 0, 0,
 	{ 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
-    { "PENTAX *ist DL", 0, 0,
+    { "Pentax *ist DL", 0, 0,
 	{ 10829,-2838,-1115,-8339,15817,2696,-837,680,11939 } },
-    { "PENTAX *ist DS2", 0, 0,
+    { "Pentax *ist DS2", 0, 0,
 	{ 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
-    { "PENTAX *ist DS", 0, 0,
+    { "Pentax *ist DS", 0, 0,
 	{ 10371,-2333,-1206,-8688,16231,2602,-1230,1116,11282 } },
-    { "PENTAX *ist D", 0, 0,
+    { "Pentax *ist D", 0, 0,
 	{ 9651,-2059,-1189,-8881,16512,2487,-1460,1345,10687 } },
-    { "PENTAX K10D", 0, 0,
+    { "Pentax K10D", 0, 0,
 	{ 9566,-2863,-803,-7170,15172,2112,-818,803,9705 } },
-    { "PENTAX K1", 0, 0,
+    { "Pentax K1", 0, 0,
 	{ 11095,-3157,-1324,-8377,15834,2720,-1108,947,11688 } },
-    { "PENTAX K20D", 0, 0,
+    { "Pentax K20D", 0, 0,
 	{ 9427,-2714,-868,-7493,16092,1373,-2199,3264,7180 } },
-    { "PENTAX K200D", 0, 0,
+    { "Pentax K200D", 0, 0,
 	{ 9186,-2678,-907,-8693,16517,2260,-1129,1094,8524 } },
-    { "PENTAX K2000", 0, 0,
+    { "Pentax K2000", 0, 0,
 	{ 11057,-3604,-1155,-5152,13046,2329,-282,375,8104 } },
-    { "PENTAX K-m", 0, 0,
+    { "Pentax K-m", 0, 0,
 	{ 11057,-3604,-1155,-5152,13046,2329,-282,375,8104 } },
-    { "PENTAX K-x", 0, 0,
+    { "Pentax K-x", 0, 0,
 	{ 8843,-2837,-625,-5025,12644,2668,-411,1234,7410 } },
-    { "PENTAX K-r", 0, 0,
+   { "Pentax K-r", 0, 0,
 	{ 9895,-3077,-850,-5304,13035,2521,-883,1768,6936 } },
-    { "PENTAX K-5", 0, 0,
+    { "Pentax K-3", 0, 0,
+	{ 7415,-2052,-721,-5186,12788,2682,-1446,2157,6773 } },
+    { "Pentax K-5 II", 0, 0,
+	{ 8170,-2725,-639,-4440,12017,2744,-771,1465,6599 } },
+    { "Pentax K-5", 0, 0,
 	{ 8713,-2833,-743,-4342,11900,2772,-722,1543,6247 } },
-    { "PENTAX K-7", 0, 0,
+    { "Pentax K-7", 0, 0,
 	{ 9142,-2947,-678,-8648,16967,1663,-2224,2898,8615 } },
-    { "PENTAX 645D", 0, 0x3e00,
+    { "Pentax K-S1", 0, 0,
+	{ 8512,-3211,-787,-4167,11966,2487,-638,1288,6054 } },
+    { "Pentax MX-1", 0, 0,
+	{ 8804,-2523,-1238,-2423,11627,860,-682,1774,4753 } },
+    { "Pentax Q10", 0, 0,
+	{ 12995,-5593,-1107,-1879,10139,2027,-64,1233,4919 } },
+    { "Pentax 645D", 0, 0x3e00,
 	{ 10646,-3593,-1158,-3329,11699,1831,-667,2874,6287 } },
+    { "Panasonic DMC-CM1", -15, 0,
+        { 8770, -3194,-820,-2871,11281,1803,-513,1552,4434} },
     { "Panasonic DMC-FZ8", 0, 0xf7f,
 	{ 8986,-2755,-802,-6341,13575,3077,-1476,2144,6379 } },
     { "Panasonic DMC-FZ18", 0, 0,
 	{ 9932,-3060,-935,-5809,13331,2753,-1267,2155,5575 } },
-    { "Panasonic DMC-FZ28", 15, 0xf96,
+    { "Panasonic DMC-FZ28", -15, 0xf96,
 	{ 10109,-3488,-993,-5412,12812,2916,-1305,2140,5543 } },
     { "Panasonic DMC-FZ30", 0, 0xf94,
 	{ 10976,-4029,-1141,-7918,15491,2600,-1670,2071,8246 } },
-    { "Panasonic DMC-FZ3", 143, 0,
+    { "Panasonic DMC-FZ3", -15, 0,
 	{ 9938,-2780,-890,-4604,12393,2480,-1117,2304,4620 } },
-    { "Panasonic DMC-FZ4", 143, 0,
+    { "Panasonic DMC-FZ4", -15, 0,
 	{ 13639,-5535,-1371,-1698,9633,2430,316,1152,4108 } },
     { "Panasonic DMC-FZ50", 0, 0,
 	{ 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } },
-    { "LEICA V-LUX1", 0, 0,
+    { "Panasonic DMC-FZ7", -15, 0,
+	{ 11532,-4324,-1066,-2375,10847,1749,-564,1699,4351 } },
+    { "Leica V-LUX1", 0, 0,
 	{ 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } },
-    { "Panasonic DMC-L10", 15, 0xf96,
+    { "Panasonic DMC-L10", -15, 0xf96,
 	{ 8025,-1942,-1050,-7920,15904,2100,-2456,3005,7039 } },
     { "Panasonic DMC-L1", 0, 0xf7f,
 	{ 8054,-1885,-1025,-8349,16367,2040,-2805,3542,7629 } },
-    { "LEICA DIGILUX 3", 0, 0xf7f,
+    { "Leica DIGILUX 3", 0, 0xf7f,
 	{ 8054,-1885,-1025,-8349,16367,2040,-2805,3542,7629 } },
     { "Panasonic DMC-LC1", 0, 0,
 	{ 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } },
-    { "LEICA DIGILUX 2", 0, 0,
+    { "Leica DIGILUX 2", 0, 0,
 	{ 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } },
+    { "Panasonic DMC-LX100", -15, 0,
+	{ 8844,-3538,-768,-3709,11762,2200,-698,1792,5220 } },
+    { "Leica D-LUX (Typ 109)", -15, 0,
+	{ 8844,-3538,-768,-3709,11762,2200,-698,1792,5220 } },
+    { "Panasonic DMC-LF1", -15, 0,
+	{ 9379,-3267,-816,-3227,11560,1881,-926,1928,5340 } },
+    { "Leica C (Typ 112)", -15, 0,
+	{ 9379,-3267,-816,-3227,11560,1881,-926,1928,5340 } },
     { "Panasonic DMC-LX1", 0, 0xf7f,
 	{ 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } },
-    { "LEICA D-LUX2", 0, 0xf7f,
+    { "Leica D-Lux (Typ 109)", 0, 0xf7f, /* LibRaw */
+	{ 10031,-4555,-456,-3024,11520,1091,-1342,2611,4752 } },
+    { "Leica D-LUX2", 0, 0xf7f,
 	{ 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } },
     { "Panasonic DMC-LX2", 0, 0,
 	{ 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } },
-    { "LEICA D-LUX3", 0, 0,
+    { "Leica D-LUX3", 0, 0,
 	{ 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } },
-    { "Panasonic DMC-LX3", 15, 0,
+    { "Panasonic DMC-LX3", -15, 0,
 	{ 8128,-2668,-655,-6134,13307,3161,-1782,2568,6083 } },
-    { "LEICA D-LUX 4", 15, 0,
+    { "Leica D-LUX 4", -15, 0,
 	{ 8128,-2668,-655,-6134,13307,3161,-1782,2568,6083 } },
-    { "Panasonic DMC-LX5", 143, 0,
+    { "Panasonic DMC-LX5", -15, 0,
 	{ 10909,-4295,-948,-1333,9306,2399,22,1738,4582 } },
-    { "LEICA D-LUX 5", 143, 0,
+    { "Leica D-LUX 5", -15, 0,
 	{ 10909,-4295,-948,-1333,9306,2399,22,1738,4582 } },
-    { "Panasonic DMC-FZ100", 143, 0xfff,
+    { "Panasonic DMC-LX7", -15, 0,
+	{ 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } },
+    { "Leica D-LUX 6", -15, 0,
+	{ 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } },
+    { "Panasonic DMC-FZ1000", -15, 0,
+	{ 7830,-2696,-763,-3325,11667,1866,-641,1712,4824 } },
+    { "Leica V-LUX (Typ 114)", 15, 0,
+	{ 7830,-2696,-763,-3325,11667,1866,-641,1712,4824 } },
+    { "Panasonic DMC-FZ100", -15, 0xfff,
 	{ 16197,-6146,-1761,-2393,10765,1869,366,2238,5248 } },
-    { "LEICA V-LUX 2", 143, 0xfff,
+    { "Leica V-LUX 2", -15, 0xfff,
 	{ 16197,-6146,-1761,-2393,10765,1869,366,2238,5248 } },
-    { "Panasonic DMC-FZ150", 143, 0xfff,
+    { "Panasonic DMC-FZ150", -15, 0xfff,
 	{ 11904,-4541,-1189,-2355,10899,1662,-296,1586,4289 } },
-    { "LEICA V-LUX 3", 143, 0xfff,
+    { "Leica V-LUX 3", -15, 0xfff,
 	{ 11904,-4541,-1189,-2355,10899,1662,-296,1586,4289 } },
-    { "Panasonic DMC-FX150", 15, 0xfff,
+    { "Panasonic DMC-FZ200", -15, 0xfff,
+	{ 8112,-2563,-740,-3730,11784,2197,-941,2075,4933 } },
+    { "Leica V-LUX 4", -15, 0xfff,
+	{ 8112,-2563,-740,-3730,11784,2197,-941,2075,4933 } },
+    { "Panasonic DMC-FX150", -15, 0xfff,
 	{ 9082,-2907,-925,-6119,13377,3058,-1797,2641,5609 } },
     { "Panasonic DMC-G10", 0, 0,
 	{ 10113,-3400,-1114,-4765,12683,2317,-377,1437,6710 } },
-    { "Panasonic DMC-G1", 15, 0xf94,
+    { "Panasonic DMC-G1", -15, 0xf94,
 	{ 8199,-2065,-1056,-8124,16156,2033,-2458,3022,7220 } },
-    { "Panasonic DMC-G2", 15, 0xf3c,
+    { "Panasonic DMC-G2", -15, 0xf3c,
 	{ 10113,-3400,-1114,-4765,12683,2317,-377,1437,6710 } },
-    { "Panasonic DMC-G3", 143, 0xfff,
+    { "Panasonic DMC-G3", -15, 0xfff,
 	{ 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } },
-    { "Panasonic DMC-GF1", 15, 0xf92,
+    { "Panasonic DMC-G5", -15, 0xfff,
+	{ 7798,-2562,-740,-3879,11584,2613,-1055,2248,5434 } },
+    { "Panasonic DMC-G6", -15, 0xfff,
+	{ 8294,-2891,-651,-3869,11590,2595,-1183,2267,5352 } },
+    { "Panasonic DMC-GF1", -15, 0xf92,
 	{ 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } },
-    { "Panasonic DMC-GF2", 143, 0xfff,
+    { "Panasonic DMC-GF2", -15, 0xfff,
 	{ 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } },
-    { "Panasonic DMC-GF3", 143, 0xfff,
+    { "Panasonic DMC-GF3", -15, 0xfff,
 	{ 9051,-2468,-1204,-5212,13276,2121,-1197,2510,6890 } },
-    { "Panasonic DMC-GF5", 143, 0xfff,
+    { "Panasonic DMC-GF5", -15, 0xfff,
 	{ 8228,-2945,-660,-3938,11792,2430,-1094,2278,5793 } },
-    { "Panasonic DMC-GH1", 15, 0xf92,
+    { "Panasonic DMC-GF6", -15, 0,
+	{ 8130,-2801,-946,-3520,11289,2552,-1314,2511,5791 } },
+    { "Panasonic DMC-GF7", -15, 0,	/* DJC */
+	{ 6086,-2691,-18,-4207,9767,4441,-1486,2640,7441 } },
+    { "Panasonic DMC-GH1", -15, 0xf92,
 	{ 6299,-1466,-532,-6535,13852,2969,-2331,3112,5984 } },
-    { "Panasonic DMC-GH2", 15, 0xf95,
+    { "Panasonic DMC-GH2", -15, 0xf95,
 	{ 7780,-2410,-806,-3913,11724,2484,-1018,2390,5298 } },
-    { "Panasonic DMC-GX1", 143, 0,
+    { "Panasonic DMC-GH3", -15, 0,
+	{ 6559,-1752,-491,-3672,11407,2586,-962,1875,5130 } },
+    { "Panasonic DMC-GH4", -15, 0,
+	{ 7122,-2108,-512,-3155,11201,2231,-541,1423,5045 } },
+    { "Panasonic DMC-GM1", -15, 0,
+	{ 6770,-1895,-744,-5232,13145,2303,-1664,2691,5703 } },
+    { "Panasonic DMC-GM5", -15, 0,
+	{ 8238,-3244,-679,-3921,11814,2384,-836,2022,5852 } },
+    { "Panasonic DMC-GX1", -15, 0,
 	{ 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } },
+    {"Panasonic DMC-GX7", -15,0, /* LibRaw */
+        {7541,-2355,-591,-3163,10598,1894,-933,2109,5006}},
+    {"Panasonic DMC-TZ6",-15, 0,
+        { 15964,-8332,-389,1756,7198,383,862,784,1995 } },
+    {"Panasonic DMC-ZS4",-15, 0,
+        { 15964,-8332,-389,1756,7198,383,862,784,1995 } },
+    { "Panasonic DMC-TZ7",-15, 0,
+	{ 7901,-2472,-600,-3298,10720,2210,-864,2205,5064 } },
+    { "Panasonic DMC-ZS5",-15, 0,	/* same ID as Panasonic DMC-TZ70 */
+	{ 7901,-2472,-600,-3298,10720,2210,-864,2205,5064 } },
     { "Phase One H 20", 0, 0,		/* DJC */
 	{ 1313,1855,-109,-6715,15908,808,-327,1840,6020 } },
     { "Phase One H 25", 0, 0,
 	{ 2905,732,-237,-8134,16626,1476,-3038,4253,7517 } },
+    {"Phase One IQ250",0, 0,
+        { 4396,-153,-249,-5267,12249,2657,-1397,2323,6014 } },
     { "Phase One P 2", 0, 0,
 	{ 2905,732,-237,-8134,16626,1476,-3038,4253,7517 } },
     { "Phase One P 30", 0, 0,
@@ -6889,98 +12691,207 @@ void CLASS adobe_coeff (const char *make, const char *model)
 	{ 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } },
     { "Phase One P65", 0, 0,
 	{ 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } },
-    { "RED ONE", 704, 0xffff,		/* DJC */
+    { "Red One", 704, 0xffff,		/* DJC */
 	{ 21014,-7891,-2613,-3056,12201,856,-2203,5125,8042 } },
-    { "SAMSUNG EX1", 0, 0x3e00,
+    { "Samsung EK-GN120", 0, 0, /* Adobe; Galaxy NX */
+        { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } },
+    { "Samsung EX1", 0, 0x3e00,
 	{ 8898,-2498,-994,-3144,11328,2066,-760,1381,4576 } },
-    { "SAMSUNG NX2", 0, 0xfff,	/* NX20, NX200, NX210 */
+    { "Samsung EX2F", 0, 0x7ff,
+	{ 10648,-3897,-1055,-2022,10573,1668,-492,1611,4742 } },
+    { "Samsung NX mini", 0, 0,
+	{ 5222,-1196,-550,-6540,14649,2009,-1666,2819,5657 } },
+    { "Samsung NX3000", 0, 0,
+	{ 8060,-2933,-761,-4504,12890,1762,-630,1489,5227 } },
+    { "Samsung NX30", 0, 0,	/* NX30, NX300, NX300M */
+	{ 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } },
+    { "Samsung NX2000", 0, 0,
+	{ 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } },
+    { "Samsung NX2", 0, 0xfff,	/* NX20, NX200, NX210 */
+	{ 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } },
+    { "Samsung NX1000", 0, 0,
 	{ 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } },
-    { "SAMSUNG NX", 0, 0,	/* NX5, NX10, NX11, NX100 */
+    { "Samsung NX1100", 0, 0,
+	{ 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } },
+    { "Samsung NX11", 0, 0,
+	{ 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } },
+    { "Samsung NX10", 0, 0,	/* also NX100 */
 	{ 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } },
-    { "SAMSUNG WB2000", 0, 0xfff,
+    { "Samsung NX5", 0, 0,
+	{ 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } },
+    { "Samsung NX1", -128, 0,
+	{ 10686,-4042,-1052,-3595,13238,276,-464,1259,5931 } },
+    { "Samsung WB2000", 0, 0xfff,
 	{ 12093,-3557,-1155,-1000,9534,1733,-22,1787,4576 } },
-    { "SAMSUNG GX-1", 0, 0,
+    { "Samsung GX-1", 0, 0,
 	{ 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
-    { "SAMSUNG S85", 0, 0xffff,		/* DJC */
+    { "Samsung GX20", 0, 0,	/* copied from Pentax K20D */
+	{ 9427,-2714,-868,-7493,16092,1373,-2199,3264,7180 } },
+    { "Samsung S85", 0, 0,		/* DJC */
 	{ 11885,-3968,-1473,-4214,12299,1916,-835,1655,5549 } },
+     // Foveon: LibRaw color data
+    {"Sigma dp1 Quattro",2047, 0,
+      { 13801,-3390,-1016,5535,3802,877,1848,4245,3730 } },
+    {"Sigma dp2 Quattro",2047, 0,
+      { 13801,-3390,-1016,5535,3802,877,1848,4245,3730 } },
+    { "Sigma SD9", 15, 4095,			/* LibRaw */
+      { 14082,-2201,-1056,-5243,14788,167,-121,196,8881 } },
+    { "Sigma SD10", 15, 16383,			/* LibRaw */
+      { 14082,-2201,-1056,-5243,14788,167,-121,196,8881 } },
+    { "Sigma SD14", 15, 16383,			/* LibRaw */
+      { 14082,-2201,-1056,-5243,14788,167,-121,196,8881 } },
+    { "Sigma SD15", 15, 4095,			/* LibRaw */
+      { 14082,-2201,-1056,-5243,14788,167,-121,196,8881 } },
+    // Merills + SD1
+    { "Sigma SD1", 31, 4095,			/* LibRaw */
+      { 5133,-1895,-353,4978,744,144,3837,3069,2777 } },
+    { "Sigma DP1 Merrill", 31, 4095,			/* LibRaw */
+      { 5133,-1895,-353,4978,744,144,3837,3069,2777 } },
+    { "Sigma DP2 Merrill", 31, 4095,			/* LibRaw */
+      { 5133,-1895,-353,4978,744,144,3837,3069,2777 } },
+    { "Sigma DP3 Merrill", 31, 4095,			/* LibRaw */
+      { 5133,-1895,-353,4978,744,144,3837,3069,2777 } },
+    // Sigma DP (non-Merill Versions)
+    { "Sigma DP", 0, 4095,			/* LibRaw */
+      //  { 7401,-1169,-567,2059,3769,1510,664,3367,5328 } },
+      { 13100,-3638,-847,6855,2369,580,2723,3218,3251 } },
     { "Sinar", 0, 0,			/* DJC */
 	{ 16442,-2956,-2422,-2877,12128,750,-1136,6066,4559 } },
-    { "SONY DSC-F828", 491, 0,
+    { "Sony DSC-F828", 0, 0,
 	{ 7924,-1910,-777,-8226,15459,2998,-1517,2199,6818,-7242,11401,3481 } },
-    { "SONY DSC-R1", 512, 0,
+    { "Sony DSC-R1", -512, 0,
 	{ 8512,-2641,-694,-8042,15670,2526,-1821,2117,7414 } },
-    { "SONY DSC-V3", 0, 0,
+    { "Sony DSC-V3", 0, 0,
 	{ 7511,-2571,-692,-7894,15088,3060,-948,1111,8128 } },
-    { "SONY DSLR-A100", 0, 0xfeb,
+    { "Sony DSC-RX100M", -800, 0,	/* M2 and M3 */
+	{ 6596,-2079,-562,-4782,13016,1933,-970,1581,5181 } },
+    { "Sony DSC-RX100", -800, 0,
+	{ 8651,-2754,-1057,-3464,12207,1373,-568,1398,4434 } },
+    {"Sony DSC-RX10",0, 0,
+        { 8562,-3595,-385,-2715,11089,1128,-1023,2081,4400 } },
+    { "Sony DSC-RX1R", -512, 0,
+        { 8195,-2800,-422,-4261,12273,1709,-1505,2400,5624 } },
+    { "Sony DSC-RX1", -512, 0,
+	{ 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } },
+    { "Sony DSLR-A100", 0, 0xfeb,
 	{ 9437,-2811,-774,-8405,16215,2290,-710,596,7181 } },
-    { "SONY DSLR-A290", 0, 0,
+    { "Sony DSLR-A290", 0, 0,
 	{ 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } },
-    { "SONY DSLR-A2", 0, 0,
+    { "Sony DSLR-A2", 0, 0,
 	{ 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } },
-    { "SONY DSLR-A300", 0, 0,
+    { "Sony DSLR-A300", 0, 0,
 	{ 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } },
-    { "SONY DSLR-A330", 0, 0,
+    { "Sony DSLR-A330", 0, 0,
 	{ 9847,-3091,-929,-8485,16346,2225,-714,595,7103 } },
-    { "SONY DSLR-A350", 0, 0xffc,
+    { "Sony DSLR-A350", 0, 0xffc,
 	{ 6038,-1484,-578,-9146,16746,2513,-875,746,7217 } },
-    { "SONY DSLR-A380", 0, 0,
+    { "Sony DSLR-A380", 0, 0,
 	{ 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } },
-    { "SONY DSLR-A390", 0, 0,
+    { "Sony DSLR-A390", 0, 0,
 	{ 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } },
-    { "SONY DSLR-A450", 128, 0xfeb,
+    { "Sony DSLR-A450", -512, 0xfeb,
 	{ 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } },
-    { "SONY DSLR-A580", 128, 0xfeb,
+    { "Sony DSLR-A580", -512, 0xfeb,
 	{ 5932,-1492,-411,-4813,12285,2856,-741,1524,6739 } },
-    { "SONY DSLR-A5", 128, 0xfeb,
+    { "Sony DSLR-A500", -512, 0xfeb,
+	{ 6046,-1127,-278,-5574,13076,2786,-691,1419,7625 } },
+    { "Sony DSLR-A5", -512, 0xfeb,
 	{ 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } },
-    { "SONY DSLR-A700", 126, 0,
+    { "Sony DSLR-A700", -512, 0,
 	{ 5775,-805,-359,-8574,16295,2391,-1943,2341,7249 } },
-    { "SONY DSLR-A850", 128, 0,
+    { "Sony DSLR-A850", -512, 0,
 	{ 5413,-1162,-365,-5665,13098,2866,-608,1179,8440 } },
-    { "SONY DSLR-A900", 128, 0,
+    { "Sony DSLR-A900", -512, 0,
 	{ 5209,-1072,-397,-8845,16120,2919,-1618,1803,8654 } },
-    { "SONY NEX-5N", 128, 0,
+    { "Sony ILCA-77M2", -512, 0,
+	{ 5991,-1732,-443,-4100,11989,2381,-704,1467,5992 } },
+    { "Sony ILCE-7M2", -512, 0,
+	{ 5271,-712,-347,-6153,13653,2763,-1601,2366,7242 } },
+    { "Sony ILCE-7S", -512, 0,
+	{ 5838,-1430,-246,-3497,11477,2297,-748,1885,5778 } },
+    { "Sony ILCE-7R", -512, 0,
+	{ 4913,-541,-202,-6130,13513,2906,-1564,2151,7183 } },
+    { "Sony ILCE-7", -512, 0,
+	{ 5271,-712,-347,-6153,13653,2763,-1601,2366,7242 } },
+    { "Sony ILCE", -512, 0,	/* 3000, 5000, 5100, 6000, and QX1 */
 	{ 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
-    { "SONY NEX-3", 138, 0,		/* DJC */
-	{ 6907,-1256,-645,-4940,12621,2320,-1710,2581,6230 } },
-    { "SONY NEX-5", 116, 0,		/* DJC */
-	{ 6807,-1350,-342,-4216,11649,2567,-1089,2001,6420 } },
-    { "SONY NEX-3", 128, 0,		/* Adobe */
+    { "Sony NEX-5N", -512, 0,
+	{ 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
+    { "Sony NEX-5R", -512, 0,
+	{ 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
+    { "Sony NEX-5T", -512, 0,
+	{ 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
+    { "Sony NEX-3N", -512, 0,
+	{ 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
+    { "Sony NEX-3", -512, 0,		/* Adobe */
 	{ 6549,-1550,-436,-4880,12435,2753,-854,1868,6976 } },
-    { "SONY NEX-5", 128, 0,		/* Adobe */
+    { "Sony NEX-5", -512, 0,		/* Adobe */
 	{ 6549,-1550,-436,-4880,12435,2753,-854,1868,6976 } },
-    { "SONY NEX-7", 128, 0,
+    { "Sony NEX-6", -512, 0,
+	{ 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
+    { "Sony NEX-7", -512, 0,
 	{ 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } },
-    { "SONY NEX", 128, 0,	/* NEX-C3, NEX-F3 */
+    { "Sony NEX", -512, 0,	/* NEX-C3, NEX-F3 */
 	{ 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
-    { "SONY SLT-A33", 128, 0,
+    { "Sony SLT-A33", -512, 0,
 	{ 6069,-1221,-366,-5221,12779,2734,-1024,2066,6834 } },
-    { "SONY SLT-A35", 128, 0,
+    { "Sony SLT-A35", -512, 0,
 	{ 5986,-1618,-415,-4557,11820,3120,-681,1404,6971 } },
-    { "SONY SLT-A37", 128, 0,
+    { "Sony SLT-A37", -512, 0,
 	{ 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
-    { "SONY SLT-A55", 128, 0,
+    { "Sony SLT-A55", -512, 0,
 	{ 5932,-1492,-411,-4813,12285,2856,-741,1524,6739 } },
-    { "SONY SLT-A57", 128, 0,
-        { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
-    { "SONY SLT-A65", 128, 0,
+    { "Sony SLT-A57", -512, 0,
+	{ 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
+    { "Sony SLT-A58", -512, 0,
+	{ 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
+    { "Sony SLT-A65", -512, 0,
+	{ 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } },
+    { "Sony SLT-A77", -512, 0,
 	{ 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } },
-    { "SONY SLT-A77", 128, 0,
-	{ 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } }
+    { "Sony SLT-A99", -512, 0,
+	{ 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } },
   };
   double cam_xyz[4][3];
   char name[130];
   int i, j;
 
-  sprintf (name, "%s %s", make, model);
+  int bl4=(cblack[0]+cblack[1]+cblack[2]+cblack[3])/4,bl64=0;
+  if(cblack[4]*cblack[5]>0)
+  {
+	  for (unsigned c = 0; c < 4096 && c < cblack[4]*cblack[5]; c++)
+		  bl64+=cblack[c+6];
+	  bl64 /= cblack[4]*cblack[5];
+  }
+  int rblack  = black+bl4+bl64;
+
+  sprintf (name, "%s %s", t_make, t_model);
   for (i=0; i < sizeof table / sizeof *table; i++)
-    if (!strncmp (name, table[i].prefix, strlen(table[i].prefix))) {
-      if (table[i].black)   black   = (ushort) table[i].black;
-      if (table[i].maximum) maximum = (ushort) table[i].maximum;
+    if (!strncasecmp(name, table[i].prefix, strlen(table[i].prefix))) {
+      if (table[i].t_black>0)
+        {
+          black   = (ushort) table[i].t_black;
+          memset(cblack,0,sizeof(cblack));
+        }
+      else if(table[i].t_black <0 && rblack == 0 )
+        {
+          black   = (ushort) (-table[i].t_black);
+          memset(cblack,0,sizeof(cblack));
+        }
+      if (table[i].t_maximum) maximum = (ushort) table[i].t_maximum;
       if (table[i].trans[0]) {
-	for (j=0; j < 12; j++)
-	  cam_xyz[0][j] = table[i].trans[j] / 10000.0;
-	cam_xyz_coeff (cam_xyz);
+	for (raw_color = j=0; j < 12; j++)
+#ifdef LIBRAW_LIBRARY_BUILD
+		if(internal_only)
+			imgdata.color.cam_xyz[0][j] = table[i].trans[j] / 10000.0;
+		else
+                  imgdata.color.cam_xyz[0][j] =
+#endif
+                    cam_xyz[0][j] = table[i].trans[j] / 10000.0;
+#ifdef LIBRAW_LIBRARY_BUILD
+	if(!internal_only)
+#endif
+          cam_xyz_coeff (rgb_cam, cam_xyz);
       }
       break;
     }
@@ -7050,16 +12961,14 @@ float CLASS find_green (int bps, int bite, int off0, int off1)
   return 100 * log(sum[0]/sum[1]);
 }
 
+
 /*
    Identify which camera created this file, and set global variables
    accordingly.
  */
 void CLASS identify()
 {
-  char head[32], *cp;
-  int hlen, flen, fsize, zero_fsize=1, i, c, is_canon;
-  struct jhead jh;
-  short pana[][6] = {
+  static const short pana[][6] = {
     { 3130, 1743,  4,  0, -6,  0 },
     { 3130, 2055,  4,  0, -6,  0 },
     { 3130, 2319,  4,  0, -6,  0 },
@@ -7082,104 +12991,260 @@ void CLASS identify()
     { 4290, 2391,  3,  0, -8, -1 },
     { 4330, 2439, 17, 15,-44,-19 },
     { 4508, 2962,  0,  0, -3, -4 },
-    { 4508, 3330,  0,  0, -3, -6 } };
+    { 4508, 3330,  0,  0, -3, -6 },
+  };
+  static const ushort canon[][11] = {
+    { 1944, 1416,   0,  0, 48,  0 },
+    { 2144, 1560,   4,  8, 52,  2, 0, 0, 0, 25 },
+    { 2224, 1456,  48,  6,  0,  2 },
+    { 2376, 1728,  12,  6, 52,  2 },
+    { 2672, 1968,  12,  6, 44,  2 },
+    { 3152, 2068,  64, 12,  0,  0, 16 },
+    { 3160, 2344,  44, 12,  4,  4 },
+    { 3344, 2484,   4,  6, 52,  6 },
+    { 3516, 2328,  42, 14,  0,  0 },
+    { 3596, 2360,  74, 12,  0,  0 },
+    { 3744, 2784,  52, 12,  8, 12 },
+    { 3944, 2622,  30, 18,  6,  2 },
+    { 3948, 2622,  42, 18,  0,  2 },
+    { 3984, 2622,  76, 20,  0,  2, 14 },
+    { 4104, 3048,  48, 12, 24, 12 },
+    { 4116, 2178,   4,  2,  0,  0 },
+    { 4152, 2772, 192, 12,  0,  0 },
+    { 4160, 3124, 104, 11,  8, 65 },
+    { 4176, 3062,  96, 17,  8,  0, 0, 16, 0, 7, 0x49 },
+    { 4192, 3062,  96, 17, 24,  0, 0, 16, 0, 0, 0x49 },
+    { 4312, 2876,  22, 18,  0,  2 },
+    { 4352, 2874,  62, 18,  0,  0 },
+    { 4476, 2954,  90, 34,  0,  0 },
+    { 4480, 3348,  12, 10, 36, 12, 0, 0, 0, 18, 0x49 },
+    { 4480, 3366,  80, 50,  0,  0 },
+    { 4496, 3366,  80, 50, 12,  0 },
+    { 4768, 3516,  96, 16,  0,  0, 0, 16 },
+    { 4832, 3204,  62, 26,  0,  0 },
+    { 4832, 3228,  62, 51,  0,  0 },
+    { 5108, 3349,  98, 13,  0,  0 },
+    { 5120, 3318, 142, 45, 62,  0 },
+    { 5280, 3528,  72, 52,  0,  0 },
+    { 5344, 3516, 142, 51,  0,  0 },
+    { 5344, 3584, 126,100,  0,  2 },
+    { 5360, 3516, 158, 51,  0,  0 },
+    { 5568, 3708,  72, 38,  0,  0 },
+    { 5632, 3710,  96, 17,  0,  0, 0, 16, 0, 0, 0x49 },
+    { 5712, 3774,  62, 20, 10,  2 },
+    { 5792, 3804, 158, 51,  0,  0 },
+    { 5920, 3950, 122, 80,  2,  0 },
+  };
+  static const struct {
+    ushort id;
+    char t_model[20];
+  } unique[] = {
+    { 0x001, "EOS-1D" },
+    { 0x167, "EOS-1DS" },
+    { 0x168, "EOS 10D" },
+    { 0x169, "EOS-1D Mark III" },
+    { 0x170, "EOS 300D" },
+    { 0x174, "EOS-1D Mark II" },
+    { 0x175, "EOS 20D" },
+    { 0x176, "EOS 450D" },
+    { 0x188, "EOS-1Ds Mark II" },
+    { 0x189, "EOS 350D" },
+    { 0x190, "EOS 40D" },
+    { 0x213, "EOS 5D" },
+    { 0x215, "EOS-1Ds Mark III" },
+    { 0x218, "EOS 5D Mark II" },
+    { 0x232, "EOS-1D Mark II N" },
+    { 0x234, "EOS 30D" },
+    { 0x236, "EOS 400D" },
+    { 0x250, "EOS 7D" },
+    { 0x252, "EOS 500D" },
+    { 0x254, "EOS 1000D" },
+    { 0x261, "EOS 50D" },
+    { 0x269, "EOS-1D X" },
+    { 0x270, "EOS 550D" },
+    { 0x281, "EOS-1D Mark IV" },
+    { 0x285, "EOS 5D Mark III" },
+    { 0x286, "EOS 600D" },
+    { 0x287, "EOS 60D" },
+    { 0x288, "EOS 1100D" },
+    { 0x289, "EOS 7D Mark II" },
+    { 0x301, "EOS 650D" },
+    { 0x302, "EOS 6D" },
+    { 0x324, "EOS-1D C" },
+    { 0x325, "EOS 70D" },
+    { 0x326, "EOS 700D" },
+    { 0x327, "EOS 1200D" },
+    { 0x331, "EOS M" },
+    { 0x335, "EOS M2" },
+    { 0x346, "EOS 100D" },
+    { 0x347, "EOS 760D" },
+    { 0x382, "EOS 5DS" },
+    { 0x393, "EOS 750D" },
+    { 0x401, "EOS 5DS R" },
+  }, sonique[] = {
+    { 0x002, "DSC-R1" },     { 0x100, "DSLR-A100" },
+    { 0x101, "DSLR-A900" },  { 0x102, "DSLR-A700" },
+    { 0x103, "DSLR-A200" },  { 0x104, "DSLR-A350" },
+    { 0x105, "DSLR-A300" },
+    {262,"DSLR-A900"},
+    {263,"DSLR-A380"},
+    { 0x108, "DSLR-A330" },
+    { 0x109, "DSLR-A230" },  { 0x10a, "DSLR-A290" },
+    { 0x10d, "DSLR-A850" },
+    {270,"DSLR-A850"},
+    { 0x111, "DSLR-A550" },
+    { 0x112, "DSLR-A500" },  { 0x113, "DSLR-A450" },
+    { 0x116, "NEX-5" },      { 0x117, "NEX-3" },
+    { 0x118, "SLT-A33" },    { 0x119, "SLT-A55V" },
+    { 0x11a, "DSLR-A560" },  { 0x11b, "DSLR-A580" },
+    { 0x11c, "NEX-C3" },     { 0x11d, "SLT-A35" },
+    { 0x11e, "SLT-A65V" },   { 0x11f, "SLT-A77V" },
+    { 0x120, "NEX-5N" },     { 0x121, "NEX-7" },
+    {290,"NEX-VG20E"},
+    { 0x123, "SLT-A37" },    { 0x124, "SLT-A57" },
+    { 0x125, "NEX-F3" },     { 0x126, "SLT-A99V" },
+    { 0x127, "NEX-6" },      { 0x128, "NEX-5R" },
+    { 0x129, "DSC-RX100" },  { 0x12a, "DSC-RX1" },
+    {299,"NEX-VG900"},
+    {300,"NEX-VG30E"},
+    { 0x12e, "ILCE-3000" },  { 0x12f, "SLT-A58" },
+    { 0x131, "NEX-3N" },     { 0x132, "ILCE-7" },
+    { 0x133, "NEX-5T" },     { 0x134, "DSC-RX100M2" },
+    { 0x135, "DSC-RX10" },   { 0x136, "DSC-RX1R" },
+    { 0x137, "ILCE-7R" },    { 0x138, "ILCE-6000" },
+    { 0x139, "ILCE-5000" },  { 0x13d, "DSC-RX100M3" },
+    { 0x13e, "ILCE-7S" },    { 0x13f, "ILCA-77M2" },
+    { 0x153, "ILCE-5100" },  { 0x154, "ILCE-7M2" },
+    { 0x15a, "ILCE-QX1" },
+  };
+
   static const struct {
-    int fsize;
-    char make[12], model[19], withjpeg;
+    unsigned fsize;
+    ushort rw, rh;
+    uchar lm, tm, rm, bm, lf, cf, max, flags;
+    char t_make[10], t_model[20];
+    ushort offset;
   } table[] = {
-    {    62464, "Kodak",    "DC20"            ,0 },
-    {   124928, "Kodak",    "DC20"            ,0 },
-    {  1652736, "Kodak",    "DCS200"          ,0 },
-    {  4159302, "Kodak",    "C330"            ,0 },
-    {  4162462, "Kodak",    "C330"            ,0 },
-    {   460800, "Kodak",    "C603v"           ,0 },
-    {   614400, "Kodak",    "C603v"           ,0 },
-    {  6163328, "Kodak",    "C603"            ,0 },
-    {  6166488, "Kodak",    "C603"            ,0 },
-    {  9116448, "Kodak",    "C603y"           ,0 },
-    {   311696, "ST Micro", "STV680 VGA"      ,0 },  /* SPYz */
-    {   787456, "Creative", "PC-CAM 600"      ,0 },
-    {  1138688, "Minolta",  "RD175"           ,0 },
-    {  3840000, "Foculus",  "531C"            ,0 },
-    {   307200, "Generic",  "640x480"         ,0 },
-    {   786432, "AVT",      "F-080C"          ,0 },
-    {  1447680, "AVT",      "F-145C"          ,0 },
-    {  1920000, "AVT",      "F-201C"          ,0 },
-    {  5067304, "AVT",      "F-510C"          ,0 },
-    {  5067316, "AVT",      "F-510C"          ,0 },
-    { 10134608, "AVT",      "F-510C"          ,0 },
-    { 10134620, "AVT",      "F-510C"          ,0 },
-    { 16157136, "AVT",      "F-810C"          ,0 },
-    {  1409024, "Sony",     "XCD-SX910CR"     ,0 },
-    {  2818048, "Sony",     "XCD-SX910CR"     ,0 },
-    {  3884928, "Micron",   "2010"            ,0 },
-    {  6624000, "Pixelink", "A782"            ,0 },
-    { 13248000, "Pixelink", "A782"            ,0 },
-    {  6291456, "RoverShot","3320AF"          ,0 },
-    {  6553440, "Canon",    "PowerShot A460"  ,0 },
-    {  6653280, "Canon",    "PowerShot A530"  ,0 },
-    {  6573120, "Canon",    "PowerShot A610"  ,0 },
-    {  9219600, "Canon",    "PowerShot A620"  ,0 },
-    {  9243240, "Canon",    "PowerShot A470"  ,0 },
-    { 10341600, "Canon",    "PowerShot A720 IS",0 },
-    { 10383120, "Canon",    "PowerShot A630"  ,0 },
-    { 12945240, "Canon",    "PowerShot A640"  ,0 },
-    { 15636240, "Canon",    "PowerShot A650"  ,0 },
-    {  5298000, "Canon",    "PowerShot SD300" ,0 },
-    {  7710960, "Canon",    "PowerShot S3 IS" ,0 },
-    { 15467760, "Canon",    "PowerShot SX110 IS",0 },
-    { 15534576, "Canon",    "PowerShot SX120 IS",0 },
-    { 18653760, "Canon",    "PowerShot SX20 IS",0 },
-    { 19131120, "Canon",    "PowerShot SX220 HS",0 },
-    { 21936096, "Canon",    "PowerShot SX30 IS",0 },
-    {  5939200, "OLYMPUS",  "C770UZ"          ,0 },
-    {  1581060, "NIKON",    "E900"            ,1 },  /* or E900s,E910 */
-    {  2465792, "NIKON",    "E950"            ,1 },  /* or E800,E700 */
-    {  2940928, "NIKON",    "E2100"           ,1 },  /* or E2500 */
-    {  4771840, "NIKON",    "E990"            ,1 },  /* or E995, Oly C3030Z */
-    {  4775936, "NIKON",    "E3700"           ,1 },  /* or Optio 33WR */
-    {  5869568, "NIKON",    "E4300"           ,1 },  /* or DiMAGE Z2 */
-    {  5865472, "NIKON",    "E4500"           ,1 },
-    {  7438336, "NIKON",    "E5000"           ,1 },  /* or E5700 */
-    {  8998912, "NIKON",    "COOLPIX S6"      ,1 },
-    {  1976352, "CASIO",    "QV-2000UX"       ,1 },
-    {  3217760, "CASIO",    "QV-3*00EX"       ,1 },
-    {  6218368, "CASIO",    "QV-5700"         ,1 },
-    {  6054400, "CASIO",    "QV-R41"          ,1 },
-    {  7530816, "CASIO",    "QV-R51"          ,1 },
-    {  7684000, "CASIO",    "QV-4000"         ,1 },
-    {  2937856, "CASIO",    "EX-S20"          ,1 },
-    {  4948608, "CASIO",    "EX-S100"         ,1 },
-    {  7542528, "CASIO",    "EX-Z50"          ,1 },
-    {  7562048, "CASIO",    "EX-Z500"         ,1 },
-    {  7753344, "CASIO",    "EX-Z55"          ,1 },
-    {  7816704, "CASIO",    "EX-Z60"          ,1 },
-    { 10843712, "CASIO",    "EX-Z75"          ,1 },
-    { 10834368, "CASIO",    "EX-Z750"         ,1 },
-    { 12310144, "CASIO",    "EX-Z850"         ,1 },
-    { 12489984, "CASIO",    "EX-Z8"           ,1 },
-    { 15499264, "CASIO",    "EX-Z1050"        ,1 },
-    {  7426656, "CASIO",    "EX-P505"         ,1 },
-    {  9313536, "CASIO",    "EX-P600"         ,1 },
-    { 10979200, "CASIO",    "EX-P700"         ,1 },
-    {  3178560, "PENTAX",   "Optio S"         ,1 },
-    {  4841984, "PENTAX",   "Optio S"         ,1 },
-    {  6114240, "PENTAX",   "Optio S4"        ,1 },  /* or S4i, CASIO EX-Z4 */
-    { 10702848, "PENTAX",   "Optio 750Z"      ,1 },
-    { 15980544, "AGFAPHOTO","DC-833m"         ,1 },
-    { 16098048, "SAMSUNG",  "S85"             ,1 },
-    { 16215552, "SAMSUNG",  "S85"             ,1 },
-    { 20487168, "SAMSUNG",  "WB550"           ,1 },
-    { 24000000, "SAMSUNG",  "WB550"           ,1 },
-    { 12582980, "Sinar",    ""                ,0 },
-    { 33292868, "Sinar",    ""                ,0 },
-    { 44390468, "Sinar",    ""                ,0 } };
+    {   786432,1024, 768, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-080C" },
+    {  1447680,1392,1040, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-145C" },
+    {  1920000,1600,1200, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-201C" },
+    {  5067304,2588,1958, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-510C" },
+    {  5067316,2588,1958, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-510C",12 },
+    { 10134608,2588,1958, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-510C" },
+    { 10134620,2588,1958, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-510C",12 },
+    { 16157136,3272,2469, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-810C" },
+    { 15980544,3264,2448, 0, 0, 0, 0, 8,0x61,0,1,"AgfaPhoto","DC-833m" },
+    {  9631728,2532,1902, 0, 0, 0, 0,96,0x61,0,0,"Alcatel","5035D" },
+
+//   Android Raw dumps id start
+//   File Size in bytes Horizontal Res Vertical Flag then bayer order eg 0x16 bbgr 0x94 rggb
+    { 16424960,4208,3120, 0, 0, 0, 0, 1,0x16,0,0,"Sony","IMX135-mipi 13mp" },
+    { 17522688,4212,3120, 0, 0, 0, 0, 0,0x16,0,0,"Sony","IMX135-QCOM" },
+    { 10223360,2608,1960, 0, 0, 0, 0, 1,0x94,0,0,"Sony","IMX072-mipi" },
+    { 5107712,2688,1520, 0, 0, 0, 0, 1,0x61,0,0,"HTC","UltraPixel" },
+    { 1540857,2688,1520, 0, 0, 0, 0, 1,0x61,0,0,"Samsung","S3" },
+    { 10223363,2688,1520, 0, 0, 0, 0, 1,0x61,0,0,"Samsung","GalaxyNexus" },
+    //   Android Raw dumps id end
+
+    {  2868726,1384,1036, 0, 0, 0, 0,64,0x49,0,8,"Baumer","TXG14",1078 },
+    {  5298000,2400,1766,12,12,44, 2,40,0x94,0,2,"Canon","PowerShot SD300" },
+    {  6553440,2664,1968, 4, 4,44, 4,40,0x94,0,2,"Canon","PowerShot A460" },
+    {  6573120,2672,1968,12, 8,44, 0,40,0x94,0,2,"Canon","PowerShot A610" },
+    {  6653280,2672,1992,10, 6,42, 2,40,0x94,0,2,"Canon","PowerShot A530" },
+    {  7710960,2888,2136,44, 8, 4, 0,40,0x94,0,2,"Canon","PowerShot S3 IS" },
+    {  9219600,3152,2340,36,12, 4, 0,40,0x94,0,2,"Canon","PowerShot A620" },
+    {  9243240,3152,2346,12, 7,44,13,40,0x49,0,2,"Canon","PowerShot A470" },
+    { 10341600,3336,2480, 6, 5,32, 3,40,0x94,0,2,"Canon","PowerShot A720 IS" },
+    { 10383120,3344,2484,12, 6,44, 6,40,0x94,0,2,"Canon","PowerShot A630" },
+    { 12945240,3736,2772,12, 6,52, 6,40,0x94,0,2,"Canon","PowerShot A640" },
+    { 15636240,4104,3048,48,12,24,12,40,0x94,0,2,"Canon","PowerShot A650" },
+    { 15467760,3720,2772, 6,12,30, 0,40,0x94,0,2,"Canon","PowerShot SX110 IS" },
+    { 15534576,3728,2778,12, 9,44, 9,40,0x94,0,2,"Canon","PowerShot SX120 IS" },
+    { 18653760,4080,3048,24,12,24,12,40,0x94,0,2,"Canon","PowerShot SX20 IS" },
+    { 19131120,4168,3060,92,16, 4, 1,40,0x94,0,2,"Canon","PowerShot SX220 HS" },
+    { 21936096,4464,3276,25,10,73,12,40,0x16,0,2,"Canon","PowerShot SX30 IS" },
+    { 24724224,4704,3504, 8,16,56, 8,40,0x49,0,2,"Canon","PowerShot A3300 IS" },
+    {  1976352,1632,1211, 0, 2, 0, 1, 0,0x94,0,1,"Casio","QV-2000UX" },
+    {  3217760,2080,1547, 0, 0,10, 1, 0,0x94,0,1,"Casio","QV-3*00EX" },
+    {  6218368,2585,1924, 0, 0, 9, 0, 0,0x94,0,1,"Casio","QV-5700" },
+    {  7816704,2867,2181, 0, 0,34,36, 0,0x16,0,1,"Casio","EX-Z60" },
+    {  2937856,1621,1208, 0, 0, 1, 0, 0,0x94,7,13,"Casio","EX-S20" },
+    {  4948608,2090,1578, 0, 0,32,34, 0,0x94,7,1,"Casio","EX-S100" },
+    {  6054400,2346,1720, 2, 0,32, 0, 0,0x94,7,1,"Casio","QV-R41" },
+    {  7426656,2568,1928, 0, 0, 0, 0, 0,0x94,0,1,"Casio","EX-P505" },
+    {  7530816,2602,1929, 0, 0,22, 0, 0,0x94,7,1,"Casio","QV-R51" },
+    {  7542528,2602,1932, 0, 0,32, 0, 0,0x94,7,1,"Casio","EX-Z50" },
+    {  7562048,2602,1937, 0, 0,25, 0, 0,0x16,7,1,"Casio","EX-Z500" },
+    {  7753344,2602,1986, 0, 0,32,26, 0,0x94,7,1,"Casio","EX-Z55" },
+    {  9313536,2858,2172, 0, 0,14,30, 0,0x94,7,1,"Casio","EX-P600" },
+    { 10834368,3114,2319, 0, 0,27, 0, 0,0x94,0,1,"Casio","EX-Z750" },
+    { 10843712,3114,2321, 0, 0,25, 0, 0,0x94,0,1,"Casio","EX-Z75" },
+    { 10979200,3114,2350, 0, 0,32,32, 0,0x94,7,1,"Casio","EX-P700" },
+    { 12310144,3285,2498, 0, 0, 6,30, 0,0x94,0,1,"Casio","EX-Z850" },
+    { 12489984,3328,2502, 0, 0,47,35, 0,0x94,0,1,"Casio","EX-Z8" },
+    { 15499264,3754,2752, 0, 0,82, 0, 0,0x94,0,1,"Casio","EX-Z1050" },
+    { 18702336,4096,3044, 0, 0,24, 0,80,0x94,7,1,"Casio","EX-ZR100" },
+    {  7684000,2260,1700, 0, 0, 0, 0,13,0x94,0,1,"Casio","QV-4000" },
+    {   787456,1024, 769, 0, 1, 0, 0, 0,0x49,0,0,"Creative","PC-CAM 600" },
+    { 28829184,4384,3288, 0, 0, 0, 0,36,0x61,0,0,"DJI" },
+    { 15151104,4608,3288, 0, 0, 0, 0, 0,0x94,0,0,"Matrix" },
+    {  3840000,1600,1200, 0, 0, 0, 0,65,0x49,0,0,"Foculus","531C" },
+    {   307200, 640, 480, 0, 0, 0, 0, 0,0x94,0,0,"Generic" },
+    {    62464, 256, 244, 1, 1, 6, 1, 0,0x8d,0,0,"Kodak","DC20" },
+    {   124928, 512, 244, 1, 1,10, 1, 0,0x8d,0,0,"Kodak","DC20" },
+    {  1652736,1536,1076, 0,52, 0, 0, 0,0x61,0,0,"Kodak","DCS200" },
+    {  4159302,2338,1779, 1,33, 1, 2, 0,0x94,0,0,"Kodak","C330" },
+    {  4162462,2338,1779, 1,33, 1, 2, 0,0x94,0,0,"Kodak","C330",3160 },
+    {  2247168,1232, 912, 0, 0,16, 0, 0,0x00,0,0,"Kodak","C330" },
+    {  3370752,1232, 912, 0, 0,16, 0, 0,0x00,0,0,"Kodak","C330" },
+    {  6163328,2864,2152, 0, 0, 0, 0, 0,0x94,0,0,"Kodak","C603" },
+    {  6166488,2864,2152, 0, 0, 0, 0, 0,0x94,0,0,"Kodak","C603",3160 },
+    {   460800, 640, 480, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","C603" },
+    {  9116448,2848,2134, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","C603" },
+    { 12241200,4040,3030, 2, 0, 0,13, 0,0x49,0,0,"Kodak","12MP" },
+    { 12272756,4040,3030, 2, 0, 0,13, 0,0x49,0,0,"Kodak","12MP",31556 },
+    { 18000000,4000,3000, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","12MP" },
+    {   614400, 640, 480, 0, 3, 0, 0,64,0x94,0,0,"Kodak","KAI-0340" },
+    { 15360000,3200,2400, 0, 0, 0, 0,96,0x16,0,0,"Lenovo","A820" },
+    {  3884928,1608,1207, 0, 0, 0, 0,96,0x16,0,0,"Micron","2010",3212 },
+    {  1138688,1534, 986, 0, 0, 0, 0, 0,0x61,0,0,"Minolta","RD175",513 },
+    {  1581060,1305, 969, 0, 0,18, 6, 6,0x1e,4,1,"Nikon","E900" },
+    {  2465792,1638,1204, 0, 0,22, 1, 6,0x4b,5,1,"Nikon","E950" },
+    {  2940928,1616,1213, 0, 0, 0, 7,30,0x94,0,1,"Nikon","E2100" },
+    {  4771840,2064,1541, 0, 0, 0, 1, 6,0xe1,0,1,"Nikon","E990" },
+    {  4775936,2064,1542, 0, 0, 0, 0,30,0x94,0,1,"Nikon","E3700" },
+    {  5865472,2288,1709, 0, 0, 0, 1, 6,0xb4,0,1,"Nikon","E4500" },
+    {  5869568,2288,1710, 0, 0, 0, 0, 6,0x16,0,1,"Nikon","E4300" },
+    {  7438336,2576,1925, 0, 0, 0, 1, 6,0xb4,0,1,"Nikon","E5000" },
+    {  8998912,2832,2118, 0, 0, 0, 0,30,0x94,7,1,"Nikon","COOLPIX S6" },
+    {  5939200,2304,1718, 0, 0, 0, 0,30,0x16,0,0,"Olympus","C770UZ" },
+    {  3178560,2064,1540, 0, 0, 0, 0, 0,0x94,0,1,"Pentax","Optio S" },
+    {  4841984,2090,1544, 0, 0,22, 0, 0,0x94,7,1,"Pentax","Optio S" },
+    {  6114240,2346,1737, 0, 0,22, 0, 0,0x94,7,1,"Pentax","Optio S4" },
+    { 10702848,3072,2322, 0, 0, 0,21,30,0x94,0,1,"Pentax","Optio 750Z" },
+    { 13248000,2208,3000, 0, 0, 0, 0,13,0x61,0,0,"Pixelink","A782" },
+    {  6291456,2048,1536, 0, 0, 0, 0,96,0x61,0,0,"RoverShot","3320AF" },
+    {   311696, 644, 484, 0, 0, 0, 0, 0,0x16,0,8,"ST Micro","STV680 VGA" },
+    { 16098048,3288,2448, 0, 0,24, 0, 9,0x94,0,1,"Samsung","S85" },
+    { 16215552,3312,2448, 0, 0,48, 0, 9,0x94,0,1,"Samsung","S85" },
+    { 20487168,3648,2808, 0, 0, 0, 0,13,0x94,5,1,"Samsung","WB550" },
+    { 24000000,4000,3000, 0, 0, 0, 0,13,0x94,5,1,"Samsung","WB550" },
+    { 12582980,3072,2048, 0, 0, 0, 0,33,0x61,0,0,"Sinar","",68 },
+    { 33292868,4080,4080, 0, 0, 0, 0,33,0x61,0,0,"Sinar","",68 },
+    { 44390468,4080,5440, 0, 0, 0, 0,33,0x61,0,0,"Sinar","",68 },
+    {  1409024,1376,1024, 0, 0, 1, 0, 0,0x49,0,0,"Sony","XCD-SX910CR" },
+    {  2818048,1376,1024, 0, 0, 1, 0,97,0x49,0,0,"Sony","XCD-SX910CR" },
+  };
   static const char *corp[] =
-    { "Canon", "NIKON", "EPSON", "KODAK", "Kodak", "OLYMPUS", "PENTAX",
-      "MINOLTA", "Minolta", "Konica", "CASIO", "Sinar", "Phase One",
-      "SAMSUNG", "Mamiya", "MOTOROLA", "LEICA" };
+    { "AgfaPhoto", "Canon", "Casio", "Epson", "Fujifilm",
+      "Mamiya", "Minolta", "Motorola", "Kodak", "Konica", "Leica",
+      "Nikon", "Nokia", "Olympus", "Pentax", "Phase One", "Ricoh",
+      "Samsung", "Sigma", "Sinar", "Sony" };
+  char head[32], *cp;
+  int hlen, flen, fsize, zero_fsize=1, i, c;
+  struct jhead jh;
 
-  tiff_flip = flip = filters = -1;	/* 0 is valid, so -1 is unknown */
+  tiff_flip = flip = filters = UINT_MAX;	/* unknown */
   raw_height = raw_width = fuji_width = fuji_layout = cr2_slice[0] = 0;
   maximum = height = width = top_margin = left_margin = 0;
   cdesc[0] = desc[0] = artist[0] = make[0] = model[0] = model2[0] = 0;
@@ -7193,12 +13258,14 @@ void CLASS identify()
   thumb_offset = thumb_length = thumb_width = thumb_height = 0;
   load_raw = thumb_load_raw = 0;
   write_thumb = &CLASS jpeg_thumb;
-  data_offset = meta_length = tiff_bps = tiff_compress = 0;
+  data_offset = meta_offset = meta_length = tiff_bps = tiff_compress = 0;
   kodak_cbpp = zero_after_ff = dng_version = load_flags = 0;
   timestamp = shot_order = tiff_samples = black = is_foveon = 0;
   mix_green = profile_length = data_error = zero_is_bad = 0;
   pixel_aspect = is_raw = raw_color = 1;
   tile_width = tile_length = 0;
+
+
   for (i=0; i < 4; i++) {
     cam_mul[i] = i == 1;
     pre_mul[i] = i < 3;
@@ -7214,14 +13281,19 @@ void CLASS identify()
   fread (head, 1, 32, ifp);
   fseek (ifp, 0, SEEK_END);
   flen = fsize = ftell(ifp);
-  if ((cp = (char *) memmem (head, 32, "MMMM", 4)) ||
-      (cp = (char *) memmem (head, 32, "IIII", 4))) {
+  if ((cp = (char *) memmem (head, 32, (char*)"MMMM", 4)) ||
+      (cp = (char *) memmem (head, 32, (char*)"IIII", 4))) {
     parse_phase_one (cp-head);
     if (cp-head && parse_tiff(0)) apply_tiff();
   } else if (order == 0x4949 || order == 0x4d4d) {
     if (!memcmp (head+6,"HEAPCCDR",8)) {
       data_offset = hlen;
-      parse_ciff (hlen, flen - hlen);
+#ifdef LIBRAW_LIBRARY_BUILD
+      imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_FixedLens;
+      imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_FixedLens;
+#endif
+      parse_ciff (hlen, flen-hlen, 0);
+      load_raw = &CLASS canon_load_raw;
     } else if (parse_tiff(0)) apply_tiff();
   } else if (!memcmp (head,"\xff\xd8\xff\xe1",4) &&
 	     !memcmp (head+6,"Exif",4)) {
@@ -7236,8 +13308,37 @@ void CLASS identify()
     strcpy (model,"N Digital");
     fseek (ifp, 33, SEEK_SET);
     get_timestamp(1);
-    fseek (ifp, 60, SEEK_SET);
+    fseek (ifp, 52, SEEK_SET);
+    switch (get4()) {
+      case  7: iso_speed = 25;  break;
+      case  8: iso_speed = 32;  break;
+      case  9: iso_speed = 40;  break;
+      case 10: iso_speed = 50;  break;
+      case 11: iso_speed = 64;  break;
+      case 12: iso_speed = 80;  break;
+      case 13: iso_speed = 100; break;
+      case 14: iso_speed = 125; break;
+      case 15: iso_speed = 160; break;
+      case 16: iso_speed = 200; break;
+      case 17: iso_speed = 250; break;
+      case 18: iso_speed = 320; break;
+      case 19: iso_speed = 400; break;
+    }
+    shutter = powf64(2.0f, (((float)get4())/8.0f)) / 16000.0f;
     FORC4 cam_mul[c ^ (c >> 1)] = get4();
+    fseek (ifp, 88, SEEK_SET);
+    aperture = powf64(2.0f, ((float)get4())/16.0f);
+    fseek (ifp, 112, SEEK_SET);
+    focal_len = get4();
+#ifdef LIBRAW_LIBRARY_BUILD
+    fseek (ifp, 104, SEEK_SET);
+    imgdata.lens.makernotes.MaxAp4CurFocal = powf64(2.0f, ((float)get4())/16.0f);
+    fseek (ifp, 124, SEEK_SET);
+    fread(imgdata.lens.makernotes.Lens, 32, 1, ifp);
+    imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Contax_N;
+    if (imgdata.lens.makernotes.Lens[0])
+      imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Contax_N;
+#endif
   } else if (!strcmp (head, "PXN")) {
     strcpy (make, "Logitech");
     strcpy (model,"Fotoman Pixtura");
@@ -7269,6 +13370,10 @@ void CLASS identify()
   } else if (!memcmp (head,"RIFF",4)) {
     fseek (ifp, 0, SEEK_SET);
     parse_riff();
+  } else if (!memcmp (head+4,"ftypqt   ",9)) {
+    fseek (ifp, 0, SEEK_SET);
+    parse_qt (fsize);
+    is_raw = 0;
   } else if (!memcmp (head,"\0\001\0\001\0@",6)) {
     fseek (ifp, 6, SEEK_SET);
     fread (make, 1, 8, ifp);
@@ -7282,15 +13387,18 @@ void CLASS identify()
     filters = 0x61616161;
   } else if (!memcmp (head,"NOKIARAW",8)) {
     strcpy (make, "NOKIA");
-    strcpy (model, "X2");
     order = 0x4949;
     fseek (ifp, 300, SEEK_SET);
     data_offset = get4();
     i = get4();
     width = get2();
     height = get2();
-    data_offset += i - width * 5 / 4 * height;
-    load_raw = &CLASS nokia_load_raw;
+    switch (tiff_bps = i*8 / (width * height)) {
+      case  8: load_raw = &CLASS eight_bit_load_raw;  break;
+      case 10: load_raw = &CLASS nokia_load_raw;
+    }
+    raw_height = height + (top_margin = i / (width * tiff_bps/8) - height);
+    mask[0][3] = 1;
     filters = 0x61616161;
   } else if (!memcmp (head,"ARRI",4)) {
     order = 0x4949;
@@ -7304,9 +13412,20 @@ void CLASS identify()
     load_raw = &CLASS packed_load_raw;
     load_flags = 88;
     filters = 0x61616161;
+  } else if (!memcmp (head,"XPDS",4)) {
+    order = 0x4949;
+    fseek (ifp, 0x800, SEEK_SET);
+    fread (make, 1, 41, ifp);
+    raw_height = get2();
+    raw_width  = get2();
+    fseek (ifp, 56, SEEK_CUR);
+    fread (model, 1, 30, ifp);
+    data_offset = 0x10000;
+    load_raw = &CLASS canon_rmf_load_raw;
+    gamma_curve (0, 12.25, 1, 1023);
   } else if (!memcmp (head+4,"RED1",4)) {
-    strcpy (make, "RED");
-    strcpy (model,"ONE");
+    strcpy (make, "Red");
+    strcpy (model,"One");
     parse_redcine();
     load_raw = &CLASS redcine_load_raw;
     gamma_curve (1/2.4, 12.92, 1, 4095);
@@ -7318,29 +13437,97 @@ void CLASS identify()
   else if (!memcmp (head,"\0MRM",4))
     parse_minolta(0);
   else if (!memcmp (head,"FOVb",4))
-    parse_foveon();
+    {
+#ifdef LIBRAW_LIBRARY_BUILD
+#ifdef  LIBRAW_DEMOSAIC_PACK_GPL2
+      if(!imgdata.params.force_foveon_x3f)
+        parse_foveon();
+      else
+#endif
+        parse_x3f();
+#else
+#ifdef  LIBRAW_DEMOSAIC_PACK_GPL2
+      parse_foveon();
+#endif
+#endif
+    }
   else if (!memcmp (head,"CI",2))
     parse_cine();
   else
     for (zero_fsize=i=0; i < sizeof table / sizeof *table; i++)
       if (fsize == table[i].fsize) {
-	strcpy (make,  table[i].make );
-	strcpy (model, table[i].model);
-	if (table[i].withjpeg)
+	strcpy (make,  table[i].t_make );
+#ifdef LIBRAW_LIBRARY_BUILD
+        if (!strcmp(make, "Canon"))
+          {
+            imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_FixedLens;
+            imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_FixedLens;
+          }
+#endif
+	strcpy (model, table[i].t_model);
+	flip = table[i].flags >> 2;
+	zero_is_bad = table[i].flags & 2;
+	if (table[i].flags & 1)
 	  parse_external_jpeg();
+	data_offset = table[i].offset;
+	raw_width   = table[i].rw;
+	raw_height  = table[i].rh;
+	left_margin = table[i].lm;
+	 top_margin = table[i].tm;
+	width  = raw_width - left_margin - table[i].rm;
+	height = raw_height - top_margin - table[i].bm;
+	filters = 0x1010101 * table[i].cf;
+	colors = 4 - !((filters & filters >> 1) & 0x5555);
+	load_flags = table[i].lf;
+	switch (tiff_bps = (fsize-data_offset)*8 / (raw_width*raw_height)) {
+	  case 6:
+	    load_raw = &CLASS minolta_rd175_load_raw;  break;
+	  case 8:
+	    load_raw = &CLASS eight_bit_load_raw;  break;
+	  case 10:
+           if ((fsize-data_offset)/raw_height*3 >= raw_width*4) {
+             load_raw = &CLASS android_loose_load_raw;  break;
+           } else if (load_flags & 1) {
+             load_raw = &CLASS android_tight_load_raw;  break;
+           }
+	  case 12:
+	    load_flags |= 128;
+	    load_raw = &CLASS packed_load_raw;     break;
+	  case 16:
+	    order = 0x4949 | 0x404 * (load_flags & 1);
+	    tiff_bps -= load_flags >> 4;
+	    tiff_bps -= load_flags = load_flags >> 1 & 7;
+	    load_raw = &CLASS unpacked_load_raw;
+	}
+	maximum = (1 << tiff_bps) - (1 << table[i].max);
       }
   if (zero_fsize) fsize = 0;
   if (make[0] == 0) parse_smal (0, flen);
-  if (make[0] == 0) parse_jpeg (is_raw = 0);
+  if (make[0] == 0) {
+    parse_jpeg(0);
+    fseek(ifp,0,SEEK_END);
+    int sz = ftell(ifp);
+    if (!(strncmp(model,"ov",2) && strncmp(model,"RP_OV",5)) && sz>=6404096 &&
+        !fseek (ifp, -6404096, SEEK_END) &&
+	fread (head, 1, 32, ifp) && !strcmp(head,"BRCMn")) {
+      strcpy (make, "OmniVision");
+      data_offset = ftell(ifp) + 0x8000-32;
+      width = raw_width;
+      raw_width = 2611;
+      load_raw = &CLASS nokia_load_raw;
+      filters = 0x16161616;
+    } else is_raw = 0;
+  }
 
   for (i=0; i < sizeof corp / sizeof *corp; i++)
-    if (strstr (make, corp[i]))		/* Simplify company names */
-	strcpy (make, corp[i]);
-  if (!strncmp (make,"KODAK",5) &&
-	((cp = strstr(model," DIGITAL CAMERA")) ||
-	 (cp = strstr(model," Digital Camera")) ||
+    if (strcasestr (make, corp[i]))	/* Simplify company names */
+	    strcpy (make, corp[i]);
+  if ((!strcmp(make,"Kodak") || !strcmp(make,"Leica")) &&
+	((cp = strcasestr(model," DIGITAL CAMERA")) ||
 	 (cp = strstr(model,"FILE VERSION"))))
      *cp = 0;
+  if (!strncasecmp(model,"PENTAX",6))
+    strcpy (make, "Pentax");
   cp = make + strlen(make);		/* Remove trailing spaces */
   while (*--cp == ' ') *cp = 0;
   cp = model + strlen(model);
@@ -7363,10 +13550,12 @@ void CLASS identify()
     { height  = 3124;   width  = 4688; filters = 0x16161616; }
   if (width == 4352 && (!strcmp(model,"K-r") || !strcmp(model,"K-x")))
     {			width  = 4309; filters = 0x16161616; }
-  if (width >= 4960 && !strcmp(model,"K-5"))
+  if (width >= 4960 && !strncmp(model,"K-5",3))
     { left_margin = 10; width  = 4950; filters = 0x16161616; }
   if (width == 4736 && !strcmp(model,"K-7"))
     { height  = 3122;   width  = 4684; filters = 0x16161616; top_margin = 2; }
+  if (width == 6080 && !strcmp(model,"K-3"))
+    { left_margin = 4;  width  = 6040; }
   if (width == 7424 && !strcmp(model,"645D"))
     { height  = 5502;   width  = 7328; filters = 0x61616161; top_margin = 29;
       left_margin = 48; }
@@ -7376,45 +13565,109 @@ void CLASS identify()
     if (filters == UINT_MAX) filters = 0;
     if (filters) is_raw = tiff_samples;
     else	 colors = tiff_samples;
-    if (tiff_compress == 1)
-      load_raw = &CLASS packed_dng_load_raw;
-    if (tiff_compress == 7)
-      load_raw = &CLASS lossless_dng_load_raw;
+    switch (tiff_compress) {
+    case 0:  /* Compression not set, assuming uncompressed */
+      case 1:     load_raw = &CLASS   packed_dng_load_raw;  break;
+      case 7:     load_raw = &CLASS lossless_dng_load_raw;  break;
+      case 34892: load_raw = &CLASS    lossy_dng_load_raw;  break;
+      default:    load_raw = 0;
+    }
+    if (!strcmp(make, "Canon") && unique_id)
+      {
+        for (i = 0; i < sizeof unique / sizeof *unique; i++)
+          if (unique_id == 0x80000000 + unique[i].id)
+            {
+              strcpy(model, unique[i].t_model);
+              break;
+            }
+      }
+    if (!strcasecmp(make, "Sony") && unique_id)
+      {
+        for (i = 0; i < sizeof sonique / sizeof *sonique; i++)
+          if (unique_id == sonique[i].id)
+            {
+              strcpy(model, sonique[i].t_model);
+              break;
+            }
+      }
     goto dng_skip;
   }
-  if ((is_canon = !strcmp(make,"Canon")))
-    load_raw = memcmp (head+6,"HEAPCCDR",8) ?
-	&CLASS lossless_jpeg_load_raw : &CLASS canon_load_raw;
-  if (!strcmp(make,"NIKON")) {
+  if (!strcmp(make,"Canon") && !fsize && tiff_bps != 15) {
+    if (!load_raw)
+      load_raw = &CLASS lossless_jpeg_load_raw;
+    for (i=0; i < sizeof canon / sizeof *canon; i++)
+      if (raw_width == canon[i][0] && raw_height == canon[i][1]) {
+	width  = raw_width - (left_margin = canon[i][2]);
+	height = raw_height - (top_margin = canon[i][3]);
+	width  -= canon[i][4];
+	height -= canon[i][5];
+	mask[0][1] =  canon[i][6];
+	mask[0][3] = -canon[i][7];
+	mask[1][1] =  canon[i][8];
+	mask[1][3] = -canon[i][9];
+	if (canon[i][10]) filters = canon[i][10] * 0x01010101;
+      }
+    if ((unique_id | 0x20000) == 0x2720000) {
+      left_margin = 8;
+      top_margin = 16;
+    }
+  }
+  if (!strcmp(make,"Canon") && unique_id)
+    {
+      for (i=0; i < sizeof unique / sizeof *unique; i++)
+        if (unique_id == 0x80000000 + unique[i].id)
+          {
+            adobe_coeff ("Canon", unique[i].t_model);
+            strcpy(model,unique[i].t_model);
+          }
+    }
+
+  if (!strcasecmp(make,"Sony") && unique_id)
+    {
+      for (i=0; i < sizeof sonique / sizeof *sonique; i++)
+        if (unique_id == sonique[i].id)
+          {
+            adobe_coeff ("Sony", sonique[i].t_model);
+            strcpy(model,sonique[i].t_model);
+          }
+    }
+
+  if (!strcmp(make,"Nikon")) {
     if (!load_raw)
       load_raw = &CLASS packed_load_raw;
     if (model[0] == 'E')
       load_flags |= !data_offset << 2 | 2;
   }
-  if (!strcmp(make,"CASIO")) {
-    load_raw = &CLASS packed_load_raw;
-    maximum = 0xf7f;
-  }
 
 /* Set parameters based on camera name (for non-DNG files). */
 
+  if (!strcmp(model,"KAI-0340")
+	&& find_green (16, 16, 3840, 5120) < 25) {
+    height = 480;
+    top_margin = filters = 0;
+    strcpy (model,"C603");
+  }
   if (is_foveon) {
     if (height*2 < width) pixel_aspect = 0.5;
     if (height   > width) pixel_aspect = 2;
     filters = 0;
-    simple_coeff(0);
-  } else if (is_canon && tiff_bps == 15) {
+#ifdef LIBRAW_DEMOSAIC_PACK_GPL2
+    if(!imgdata.params.force_foveon_x3f)
+      simple_coeff(0);
+#endif
+  } else if (!strcmp(make,"Canon") && tiff_bps == 15) {
     switch (width) {
       case 3344: width -= 66;
       case 3872: width -= 6;
     }
+    if (height > width) SWAP(height,width);
     filters = 0;
+    tiff_samples = colors = 3;
     load_raw = &CLASS canon_sraw_load_raw;
   } else if (!strcmp(model,"PowerShot 600")) {
     height = 613;
     width  = 854;
     raw_width = 896;
-    pixel_aspect = 607/628.0;
     colors = 4;
     filters = 0xe1e4e1e4;
     load_raw = &CLASS canon_600_load_raw;
@@ -7423,345 +13676,58 @@ void CLASS identify()
     height = 773;
     width  = 960;
     raw_width = 992;
-    pixel_aspect = 256/235.0;
-    colors = 4;
-    filters = 0x1e4e1e4e;
-    goto canon_a5;
-  } else if (!strcmp(model,"PowerShot A50")) {
-    height =  968;
-    width  = 1290;
-    raw_width = 1320;
-    colors = 4;
-    filters = 0x1b4e4b1e;
-    goto canon_a5;
-  } else if (!strcmp(model,"PowerShot Pro70")) {
-    height = 1024;
-    width  = 1552;
-    colors = 4;
-    filters = 0x1e4b4e1b;
-    goto canon_a5;
-  } else if (!strcmp(model,"PowerShot SD300")) {
-    height = 1752;
-    width  = 2344;
-    raw_height = 1766;
-    raw_width  = 2400;
-    top_margin  = 12;
-    left_margin = 12;
-    goto canon_a5;
-  } else if (!strcmp(model,"PowerShot A460")) {
-    height = 1960;
-    width  = 2616;
-    raw_height = 1968;
-    raw_width  = 2664;
-    top_margin  = 4;
-    left_margin = 4;
-    goto canon_a5;
-  } else if (!strcmp(model,"PowerShot A530")) {
-    height = 1984;
-    width  = 2620;
-    raw_height = 1992;
-    raw_width  = 2672;
-    top_margin  = 6;
-    left_margin = 10;
-    goto canon_a5;
-  } else if (!strcmp(model,"PowerShot A610")) {
-    if (canon_s2is()) strcpy (model+10, "S2 IS");
-    height = 1960;
-    width  = 2616;
-    raw_height = 1968;
-    raw_width  = 2672;
-    top_margin  = 8;
-    left_margin = 12;
-    goto canon_a5;
-  } else if (!strcmp(model,"PowerShot A620")) {
-    height = 2328;
-    width  = 3112;
-    raw_height = 2340;
-    raw_width  = 3152;
-    top_margin  = 12;
-    left_margin = 36;
-    goto canon_a5;
-  } else if (!strcmp(model,"PowerShot A470")) {
-    height = 2328;
-    width  = 3096;
-    raw_height = 2346;
-    raw_width  = 3152;
-    top_margin  = 6;
-    left_margin = 12;
-    goto canon_a5;
-  } else if (!strcmp(model,"PowerShot A720 IS")) {
-    height = 2472;
-    width  = 3298;
-    raw_height = 2480;
-    raw_width  = 3336;
-    top_margin  = 5;
-    left_margin = 6;
-    goto canon_a5;
-  } else if (!strcmp(model,"PowerShot A630")) {
-    height = 2472;
-    width  = 3288;
-    raw_height = 2484;
-    raw_width  = 3344;
-    top_margin  = 6;
-    left_margin = 12;
-    goto canon_a5;
-  } else if (!strcmp(model,"PowerShot A640")) {
-    height = 2760;
-    width  = 3672;
-    raw_height = 2772;
-    raw_width  = 3736;
-    top_margin  = 6;
-    left_margin = 12;
-    goto canon_a5;
-  } else if (!strcmp(model,"PowerShot A650")) {
-    height = 3024;
-    width  = 4032;
-    raw_height = 3048;
-    raw_width  = 4104;
-    top_margin  = 12;
-    left_margin = 48;
-    goto canon_a5;
-  } else if (!strcmp(model,"PowerShot S3 IS")) {
-    height = 2128;
-    width  = 2840;
-    raw_height = 2136;
-    raw_width  = 2888;
-    top_margin  = 8;
-    left_margin = 44;
-canon_a5:
-    tiff_bps = 10;
-    load_raw = &CLASS packed_load_raw;
-    load_flags = 40;
-    if (raw_width > 1600) zero_is_bad = 1;
-  } else if (!strcmp(model,"PowerShot SX110 IS")) {
-    height = 2760;
-    width  = 3684;
-    raw_height = 2772;
-    raw_width  = 3720;
-    top_margin  = 12;
-    left_margin = 6;
-    load_raw = &CLASS packed_load_raw;
-    load_flags = 40;
-    zero_is_bad = 1;
-  } else if (!strcmp(model,"PowerShot SX120 IS")) {
-    height = 2742;
-    width  = 3664;
-    raw_height = 2778;
-    raw_width  = 3728;
-    top_margin  = 18;
-    left_margin = 16;
-    filters = 0x49494949;
-    load_raw = &CLASS packed_load_raw;
-    load_flags = 40;
-    zero_is_bad = 1;
-  } else if (!strcmp(model,"PowerShot SX20 IS")) {
-    height = 3024;
-    width  = 4032;
-    raw_height = 3048;
-    raw_width  = 4080;
-    top_margin  = 12;
-    left_margin = 24;
-    load_raw = &CLASS packed_load_raw;
-    load_flags = 40;
-    zero_is_bad = 1;
-  } else if (!strcmp(model,"PowerShot SX220 HS")) {
-    height = 3043;
-    width  = 4072;
-    raw_height = 3060;
-    raw_width  = 4168;
-    mask[0][0] = top_margin = 16;
-    mask[0][2] = top_margin + height;
-    mask[0][3] = left_margin = 92;
-    load_raw = &CLASS packed_load_raw;
-    load_flags = 8;
-    zero_is_bad = 1;
-  } else if (!strcmp(model,"PowerShot SX30 IS")) {
-    height = 3254;
-    width  = 4366;
-    raw_height = 3276;
-    raw_width  = 4464;
-    top_margin  = 10;
-    left_margin = 25;
-    filters = 0x16161616;
+    pixel_aspect = 256/235.0;
+    filters = 0x1e4e1e4e;
+    goto canon_a5;
+  } else if (!strcmp(model,"PowerShot A50")) {
+    height =  968;
+    width  = 1290;
+    raw_width = 1320;
+    filters = 0x1b4e4b1e;
+    goto canon_a5;
+  } else if (!strcmp(model,"PowerShot Pro70")) {
+    height = 1024;
+    width  = 1552;
+    filters = 0x1e4b4e1b;
+canon_a5:
+    colors = 4;
+    tiff_bps = 10;
     load_raw = &CLASS packed_load_raw;
     load_flags = 40;
-    zero_is_bad = 1;
-  } else if (!strcmp(model,"PowerShot Pro90 IS")) {
-    width  = 1896;
+  } else if (!strcmp(model,"PowerShot Pro90 IS") ||
+	     !strcmp(model,"PowerShot G1")) {
     colors = 4;
     filters = 0xb4b4b4b4;
-  } else if (is_canon && raw_width == 2144) {
-    height = 1550;
-    width  = 2088;
-    top_margin  = 8;
-    left_margin = 4;
-    if (!strcmp(model,"PowerShot G1")) {
-      colors = 4;
-      filters = 0xb4b4b4b4;
-    }
-  } else if (is_canon && raw_width == 2224) {
-    height = 1448;
-    width  = 2176;
-    top_margin  = 6;
-    left_margin = 48;
-  } else if (is_canon && raw_width == 2376) {
-    height = 1720;
-    width  = 2312;
-    top_margin  = 6;
-    left_margin = 12;
-  } else if (is_canon && raw_width == 2672) {
-    height = 1960;
-    width  = 2616;
-    top_margin  = 6;
-    left_margin = 12;
-  } else if (is_canon && raw_width == 3152) {
-    height = 2056;
-    width  = 3088;
-    top_margin  = 12;
-    left_margin = 64;
-    if (unique_id == 0x80000170)
-      adobe_coeff ("Canon","EOS 300D");
-  } else if (is_canon && raw_width == 3160) {
-    height = 2328;
-    width  = 3112;
-    top_margin  = 12;
-    left_margin = 44;
-  } else if (is_canon && raw_width == 3344) {
-    height = 2472;
-    width  = 3288;
-    top_margin  = 6;
-    left_margin = 4;
+  } else if (!strcmp(model,"PowerShot A610")) {
+    if (canon_s2is()) strcpy (model+10, "S2 IS");
+  } else if (!strcmp(model,"PowerShot SX220 HS")) {
+    mask[1][3] = -4;
+    top_margin=16;
+    left_margin = 92;
+  } else if (!strcmp(model,"PowerShot S120")) {
+        raw_width = 4192;
+        raw_height = 3062;
+        width = 4022;
+        height = 3016;
+        mask[0][0] = top_margin = 31;
+        mask[0][2] = top_margin + height;
+        left_margin = 120;
+        mask[0][1] = 23;
+        mask[0][3] = 72;
+  } else if (!strcmp(model,"PowerShot G16")) {
+      mask[0][0] = 0;
+      mask[0][2] = 80;
+      mask[0][1] = 0;
+      mask[0][3] = 16;
+      top_margin = 29;
+      left_margin = 120;
+      width = raw_width-left_margin-48;
+      height = raw_height-top_margin-14;
+  } else if (!strcmp(model,"PowerShot SX50 HS")) {
+    top_margin = 17;
   } else if (!strcmp(model,"EOS D2000C")) {
     filters = 0x61616161;
     black = curve[200];
-  } else if (is_canon && raw_width == 3516) {
-    top_margin  = 14;
-    left_margin = 42;
-    if (unique_id == 0x80000189)
-      adobe_coeff ("Canon","EOS 350D");
-    goto canon_cr2;
-  } else if (is_canon && raw_width == 3596) {
-    top_margin  = 12;
-    left_margin = 74;
-    goto canon_cr2;
-  } else if (is_canon && raw_width == 3744) {
-    height = 2760;
-    width  = 3684;
-    top_margin  = 16;
-    left_margin = 8;
-    if (unique_id > 0x2720000) {
-      top_margin  = 12;
-      left_margin = 52;
-    }
-  } else if (is_canon && raw_width == 3944) {
-    height = 2602;
-    width  = 3908;
-    top_margin  = 18;
-    left_margin = 30;
-  } else if (is_canon && raw_width == 3948) {
-    top_margin  = 18;
-    left_margin = 42;
-    height -= 2;
-    if (unique_id == 0x80000236)
-      adobe_coeff ("Canon","EOS 400D");
-    if (unique_id == 0x80000254)
-      adobe_coeff ("Canon","EOS 1000D");
-    goto canon_cr2;
-  } else if (is_canon && raw_width == 3984) {
-    top_margin  = 20;
-    left_margin = 76;
-    height -= 2;
-    goto canon_cr2;
-  } else if (is_canon && raw_width == 4104) {
-    height = 3024;
-    width  = 4032;
-    top_margin  = 12;
-    left_margin = 48;
-  } else if (is_canon && raw_width == 4152) {
-    top_margin  = 12;
-    left_margin = 192;
-    goto canon_cr2;
-  } else if (is_canon && raw_width == 4160) {
-    height = 3048;
-    width  = 4048;
-    top_margin  = 11;
-    left_margin = 104;
-  } else if (is_canon && raw_width == 4312) {
-    top_margin  = 18;
-    left_margin = 22;
-    height -= 2;
-    if (unique_id == 0x80000176)
-      adobe_coeff ("Canon","EOS 450D");
-    goto canon_cr2;
-  } else if (is_canon && raw_width == 4352) {
-    top_margin  = 18;
-    left_margin = 62;
-    if (unique_id == 0x80000288)
-      adobe_coeff ("Canon","EOS 1100D");
-    goto canon_cr2;
-  } else if (is_canon && raw_width == 4476) {
-    top_margin  = 34;
-    left_margin = 90;
-    goto canon_cr2;
-  } else if (is_canon && raw_width == 4480) {
-    height = 3326;
-    width  = 4432;
-    top_margin  = 10;
-    left_margin = 12;
-    filters = 0x49494949;
-  } else if (is_canon && raw_width == 4496) {
-    height = 3316;
-    width  = 4404;
-    top_margin  = 50;
-    left_margin = 80;
-  } else if (is_canon && raw_width == 4832) {
-    top_margin = unique_id == 0x80000261 ? 51:26;
-    left_margin = 62;
-    if (unique_id == 0x80000252)
-      adobe_coeff ("Canon","EOS 500D");
-    goto canon_cr2;
-  } else if (is_canon && raw_width == 5108) {
-    top_margin  = 13;
-    left_margin = 98;
-    goto canon_cr2;
-  } else if (is_canon && raw_width == 5120) {
-    height -= top_margin = 45;
-    left_margin = 142;
-    width = 4916;
-  } else if (is_canon && raw_width == 5344) {
-    top_margin = 51;
-    left_margin = 142;
-    if (unique_id == 0x80000269) {
-      top_margin = 100;
-      left_margin = 126;
-      height -= 2;
-      adobe_coeff ("Canon","EOS-1D X");
-    }
-    if (unique_id == 0x80000270)
-      adobe_coeff ("Canon","EOS 550D");
-    if (unique_id == 0x80000286)
-      adobe_coeff ("Canon","EOS 600D");
-    goto canon_cr2;
-  } else if (is_canon && raw_width == 5360) {
-    top_margin = 51;
-    left_margin = 158;
-    goto canon_cr2;
-  } else if (is_canon && raw_width == 5712) {
-    height = 3752;
-    width  = 5640;
-    top_margin  = 20;
-    left_margin = 62;
-  } else if (is_canon && raw_width == 5792) {
-    top_margin  = 51;
-    left_margin = 158;
-canon_cr2:
-    height -= top_margin;
-    width  -= left_margin;
-  } else if (is_canon && raw_width == 5920) {
-    height = 3870;
-    width  = 5796;
-    top_margin  = 80;
-    left_margin = 122;
   } else if (!strcmp(model,"D1")) {
     cam_mul[0] *= 256/527.0;
     cam_mul[2] *= 256/317.0;
@@ -7786,12 +13752,15 @@ canon_cr2:
 	     !strcmp(model,"D90")) {
     width -= 42;
   } else if (!strcmp(model,"D5100") ||
-	     !strcmp(model,"D7000")) {
+	     !strcmp(model,"D7000") ||
+	     !strcmp(model,"COOLPIX A")) {
     width -= 44;
   } else if (!strcmp(model,"D3200") ||
-	     !strcmp(model,"D800")) {
+	    !strncmp(model,"D6",2)  ||
+	    !strncmp(model,"D800",4)) {
     width -= 46;
-  } else if (!strcmp(model,"D4")) {
+  } else if (!strcmp(model,"D4") ||
+	     !strcmp(model,"Df")) {
     width -= 52;
     left_margin = 2;
   } else if (!strncmp(model,"D40",3) ||
@@ -7799,11 +13768,8 @@ canon_cr2:
 	     !strncmp(model,"D70",3)) {
     width--;
   } else if (!strcmp(model,"D100")) {
-    if (tiff_compress == 34713 && !nikon_is_compressed()) {
-      load_raw = &CLASS packed_load_raw;
-      load_flags |= 1;
+    if (load_flags)
       raw_width = (width += 3) + 3;
-    }
   } else if (!strcmp(model,"D200")) {
     left_margin = 1;
     width -= 4;
@@ -7816,7 +13782,22 @@ canon_cr2:
     else width -= 8;
   } else if (!strncmp(model,"D300",4)) {
     width -= 32;
-  } else if (!strncmp(model,"COOLPIX P",9)) {
+  } else if (!strcmp(make,"Nikon") && raw_width == 4032) {
+    if(!strcmp(model,"COOLPIX P7700"))
+      {
+        adobe_coeff ("Nikon","COOLPIX P7700");
+        maximum = 65504;
+        load_flags = 0;
+      }
+    else if(!strcmp(model,"COOLPIX P7800"))
+      {
+        adobe_coeff ("Nikon","COOLPIX P7800");
+        maximum = 65504;
+        load_flags = 0;
+      }
+    else  if(!strcmp(model,"COOLPIX P340"))
+      load_flags=0;
+  } else if (!strncmp(model,"COOLPIX P",9) && raw_width != 4032) {
     load_flags = 24;
     filters = 0x94949494;
     if (model[9] == '7' && iso_speed >= 400)
@@ -7824,35 +13805,14 @@ canon_cr2:
   } else if (!strncmp(model,"1 ",2)) {
     height -= 2;
   } else if (fsize == 1581060) {
-    height = 963;
-    width = 1287;
-    raw_width = 1632;
-    maximum = 0x3f4;
-    colors = 4;
-    filters = 0x1e1e1e1e;
     simple_coeff(3);
     pre_mul[0] = 1.2085;
     pre_mul[1] = 1.0943;
     pre_mul[3] = 1.1103;
-    goto e900;
-  } else if (fsize == 2465792) {
-    height = 1203;
-    width  = 1616;
-    raw_width = 2048;
-    colors = 4;
-    filters = 0x4b4b4b4b;
-    adobe_coeff ("NIKON","E950");
-e900:
-    tiff_bps = 10;
-    load_raw = &CLASS packed_load_raw;
-    load_flags = 6;
+  } else if (fsize == 3178560) {
+    cam_mul[0] *= 4;
+    cam_mul[2] *= 4;
   } else if (fsize == 4771840) {
-    height = 1540;
-    width  = 2064;
-    colors = 4;
-    filters = 0xe1e1e1e1;
-    load_raw = &CLASS packed_load_raw;
-    load_flags = 6;
     if (!timestamp && nikon_e995())
       strcpy (model, "E995");
     if (strcmp(model,"E995")) {
@@ -7862,23 +13822,16 @@ e900:
       pre_mul[1] = 1.246;
       pre_mul[2] = 1.018;
     }
-  } else if (!strcmp(model,"E2100")) {
-    if (!timestamp && !nikon_e2100()) goto cp_e2500;
-    height = 1206;
-    width  = 1616;
-    load_flags = 30;
-  } else if (!strcmp(model,"E2500")) {
-cp_e2500:
-    strcpy (model, "E2500");
-    height = 1204;
-    width  = 1616;
-    colors = 4;
-    filters = 0x4b4b4b4b;
+  } else if (fsize == 2940928) {
+    if (!timestamp && !nikon_e2100())
+      strcpy (model,"E2500");
+    if (!strcmp(model,"E2500")) {
+      height -= 2;
+      load_flags = 6;
+      colors = 4;
+      filters = 0x4b4b4b4b;
+    }
   } else if (fsize == 4775936) {
-    height = 1542;
-    width  = 2064;
-    load_raw = &CLASS packed_load_raw;
-    load_flags = 30;
     if (!timestamp) nikon_3700();
     if (model[0] == 'E' && atoi(model+1) < 3700)
       filters = 0x49494949;
@@ -7896,32 +13849,21 @@ cp_e2500:
       if (i < 0) filters = 0x61616161;
     }
   } else if (fsize == 5869568) {
-    height = 1710;
-    width  = 2288;
-    filters = 0x16161616;
     if (!timestamp && minolta_z2()) {
       strcpy (make, "Minolta");
       strcpy (model,"DiMAGE Z2");
     }
-    load_raw = &CLASS packed_load_raw;
     load_flags = 6 + 24*(make[0] == 'M');
-  } else if (!strcmp(model,"E4500")) {
-    height = 1708;
-    width  = 2288;
-    colors = 4;
-    filters = 0xb4b4b4b4;
-  } else if (fsize == 7438336) {
-    height = 1924;
-    width  = 2576;
-    colors = 4;
-    filters = 0xb4b4b4b4;
-  } else if (fsize == 8998912) {
-    height = 2118;
-    width  = 2832;
-    maximum = 0xf83;
-    load_raw = &CLASS packed_load_raw;
-    load_flags = 30;
-  } else if (!strcmp(make,"FUJIFILM")) {
+  } else if (fsize == 6291456) {
+    fseek (ifp, 0x300000, SEEK_SET);
+    if ((order = guess_byte_order(0x10000)) == 0x4d4d) {
+      height -= (top_margin = 16);
+      width -= (left_margin = 28);
+      maximum = 0xf5c0;
+      strcpy (make, "ISG");
+      model[0] = 0;
+    }
+  } else if (!strcmp(make,"Fujifilm")) {
     if (!strcmp(model+7,"S2Pro")) {
       strcpy (model,"S2Pro");
       height = 2144;
@@ -7931,23 +13873,24 @@ cp_e2500:
       maximum = (is_raw == 2 && shot_select) ? 0x2f00 : 0x3e00;
     top_margin = (raw_height - height) >> 2 << 1;
     left_margin = (raw_width - width ) >> 2 << 1;
-    if (width == 3328) {
-      width = 3262;
-      left_margin = 34;
-    }
-    if (!strcmp(model,"X10") || !strcmp(model,"X-S1"))
-      filters = 0x16161616;
-    if (!strcmp(model,"X-Pro1")) {
+    if (width == 2848 || width == 3664) filters = 0x16161616;
+    if (width == 4032 || width == 4952) left_margin = 0;
+    if (width == 3328 && (width -= 66)) left_margin = 34;
+    if (width == 4936) left_margin = 4;
+    if (!strcmp(model,"HS50EXR") ||
+	!strcmp(model,"F900EXR")) {
+      width += 2;
       left_margin = 0;
-      filters = 2;
+      filters = 0x16161616;
     }
+    if(!strcmp(model,"S5500"))
+      {
+        height -= (top_margin=6);
+      }
     if (fuji_layout) raw_width *= is_raw;
-  } else if (!strcmp(model,"RD175")) {
-    height = 986;
-    width = 1534;
-    data_offset = 513;
-    filters = 0x61616161;
-    load_raw = &CLASS minolta_rd175_load_raw;
+    if (filters == 9)
+      FORC(36) xtrans[0][c] =
+	xtrans_abs[(c/6+top_margin) % 6][(c+left_margin) % 6];
   } else if (!strcmp(model,"KD-400Z")) {
     height = 1712;
     width  = 2312;
@@ -7955,9 +13898,9 @@ cp_e2500:
     goto konica_400z;
   } else if (!strcmp(model,"KD-510Z")) {
     goto konica_510z;
-  } else if (!strcasecmp(make,"MINOLTA")) {
-    load_raw = &CLASS unpacked_load_raw;
-    maximum = 0xfff;
+  } else if (!strcasecmp(make,"Minolta")) {
+    if (!load_raw && (maximum = 0xfff))
+      load_raw = &CLASS unpacked_load_raw;
     if (!strncmp(model,"DiMAGE A",8)) {
       if (!strcmp(model,"DiMAGE A200"))
 	filters = 0x49494949;
@@ -7994,54 +13937,37 @@ konica_400z:
     data_error = -1;
   } else if (!strcmp(model,"*ist DS")) {
     height -= 2;
-  } else if (!strcmp(model,"Optio S")) {
-    if (fsize == 3178560) {
-      height = 1540;
-      width  = 2064;
-      load_raw = &CLASS eight_bit_load_raw;
-      cam_mul[0] *= 4;
-      cam_mul[2] *= 4;
-    } else {
-      height = 1544;
-      width  = 2068;
-      raw_width = 3136;
-      load_raw = &CLASS packed_load_raw;
-      maximum = 0xf7c;
-    }
-  } else if (fsize == 6114240) {
-    height = 1737;
-    width  = 2324;
-    raw_width = 3520;
-    load_raw = &CLASS packed_load_raw;
-    maximum = 0xf7a;
-  } else if (!strcmp(model,"Optio 750Z")) {
-    height = 2302;
-    width  = 3072;
-    load_raw = &CLASS packed_load_raw;
-    load_flags = 30;
-  } else if (!strcmp(model,"DC-833m")) {
-    height = 2448;
-    width  = 3264;
-    order = 0x4949;
-    filters = 0x61616161;
-    load_raw = &CLASS unpacked_load_raw;
-    maximum = 0xfc00;
-  } else if (!strncmp(model,"S85",3)) {
-    height = 2448;
-    width  = 3264;
-    raw_width = fsize/height/2;
-    order = 0x4d4d;
-    load_raw = &CLASS unpacked_load_raw;
-  } else if (!strncmp(model,"NX1",3)) {
+  } else if (!strcmp(make,"Samsung") && raw_width == 4704) {
     height -= top_margin = 8;
     width -= 2 * (left_margin = 8);
     load_flags = 32;
-  } else if (!strcmp(model,"NX200")) {
+  } else if (!strcmp(make,"Samsung") && !strcmp(model,"NX3000")) {
+    top_margin = 24;
+    left_margin = 64;
+    width = 5472;
+    height = 3648;
+    filters = 0x61616161;
+    colors = 3;
+  } else if (!strcmp(make,"Samsung") && raw_height == 3714) {
+    height -= top_margin = 18;
+    left_margin = raw_width - (width = 5536);
+    if (raw_width != 5600)
+      left_margin = top_margin = 0;
+    filters = 0x61616161;
+    colors = 3;
+  } else if (!strcmp(make,"Samsung") && raw_width == 5632) {
     order = 0x4949;
     height = 3694;
     top_margin = 2;
     width  = 5574 - (left_margin = 32 + tiff_bps);
     if (tiff_bps == 12) load_flags = 80;
+  } else if (!strcmp(make,"Samsung") && raw_width == 5664) {
+    height -= top_margin = 17;
+    left_margin = 96;
+    width = 5544;
+    filters = 0x49494949;
+  } else if (!strcmp(make,"Samsung") && raw_width == 6496) {
+    filters = 0x61616161;
   } else if (!strcmp(model,"EX1")) {
     order = 0x4949;
     height -= 20;
@@ -8060,99 +13986,21 @@ konica_400z:
       width  -= 56;
       top_margin = 8;
     }
-  } else if (fsize == 20487168) {
-    height = 2808;
-    width  = 3648;
-    goto wb550;
-  } else if (fsize == 24000000) {
-    height = 3000;
-    width  = 4000;
-wb550:
+  } else if (strstr(model,"WB550")) {
     strcpy (model, "WB550");
-    order = 0x4d4d;
+  } else if (!strcmp(model,"EX2F")) {
+    height = 3045;
+    width  = 4070;
+    top_margin = 3;
+    order = 0x4949;
+    filters = 0x49494949;
     load_raw = &CLASS unpacked_load_raw;
-    load_flags = 6;
-    maximum = 0x3df;
   } else if (!strcmp(model,"STV680 VGA")) {
-    height = 484;
-    width  = 644;
-    load_raw = &CLASS eight_bit_load_raw;
-    flip = 2;
-    filters = 0x16161616;
     black = 16;
   } else if (!strcmp(model,"N95")) {
     height = raw_height - (top_margin = 2);
-  } else if (!strcmp(model,"531C")) {
-    height = 1200;
-    width  = 1600;
-    load_raw = &CLASS unpacked_load_raw;
-    filters = 0x49494949;
   } else if (!strcmp(model,"640x480")) {
-    height = 480;
-    width  = 640;
-    load_raw = &CLASS eight_bit_load_raw;
     gamma_curve (0.45, 4.5, 1, 255);
-  } else if (!strcmp(model,"F-080C")) {
-    height = 768;
-    width  = 1024;
-    load_raw = &CLASS eight_bit_load_raw;
-  } else if (!strcmp(model,"F-145C")) {
-    height = 1040;
-    width  = 1392;
-    load_raw = &CLASS eight_bit_load_raw;
-  } else if (!strcmp(model,"F-201C")) {
-    height = 1200;
-    width  = 1600;
-    load_raw = &CLASS eight_bit_load_raw;
-  } else if (!strcmp(model,"F-510C")) {
-    height = 1958;
-    width  = 2588;
-    load_raw = fsize < 7500000 ?
-	&CLASS eight_bit_load_raw : &CLASS unpacked_load_raw;
-    data_offset = fsize - width*height*(fsize >> 22);
-    maximum = 0xfff0;
-  } else if (!strcmp(model,"F-810C")) {
-    height = 2469;
-    width  = 3272;
-    load_raw = &CLASS unpacked_load_raw;
-    maximum = 0xfff0;
-  } else if (!strcmp(model,"XCD-SX910CR")) {
-    height = 1024;
-    width  = 1375;
-    raw_width = 1376;
-    filters = 0x49494949;
-    maximum = 0x3ff;
-    load_raw = fsize < 2000000 ?
-	&CLASS eight_bit_load_raw : &CLASS unpacked_load_raw;
-  } else if (!strcmp(model,"2010")) {
-    height = 1207;
-    width  = 1608;
-    order = 0x4949;
-    filters = 0x16161616;
-    data_offset = 3212;
-    maximum = 0x3ff;
-    load_raw = &CLASS unpacked_load_raw;
-  } else if (!strcmp(model,"A782")) {
-    height = 3000;
-    width  = 2208;
-    filters = 0x61616161;
-    load_raw = fsize < 10000000 ?
-	&CLASS eight_bit_load_raw : &CLASS unpacked_load_raw;
-    maximum = 0xffc0;
-  } else if (!strcmp(model,"3320AF")) {
-    height = 1536;
-    raw_width = width = 2048;
-    filters = 0x61616161;
-    load_raw = &CLASS unpacked_load_raw;
-    maximum = 0x3ff;
-    fseek (ifp, 0x300000, SEEK_SET);
-    if ((order = guess_byte_order(0x10000)) == 0x4d4d) {
-      height -= (top_margin = 16);
-      width -= (left_margin = 28);
-      maximum = 0xf5c0;
-      strcpy (make, "ISG");
-      model[0] = 0;
-    }
   } else if (!strcmp(make,"Hasselblad")) {
     if (load_raw == &CLASS lossless_jpeg_load_raw)
       load_raw = &CLASS hasselblad_load_raw;
@@ -8162,34 +14010,84 @@ wb550:
       top_margin  = 4;
       left_margin = 7;
       filters = 0x61616161;
-    } else if (raw_width == 7410) {
-      height = 5502;
-      width  = 7328;
+      if(!strcasecmp(model,"H3D"))
+        {
+          adobe_coeff("Hasselblad","H3DII-39");
+          strcpy(model,"H3DII-39");
+        }
+    } else if (raw_width == 7410 || raw_width == 8282) {
+      height -= 84;
+      width  -= 82;
       top_margin  = 4;
       left_margin = 41;
       filters = 0x61616161;
+      adobe_coeff("Hasselblad","H4D-40");
+      strcpy(model,"H4D-40");
     } else if (raw_width == 9044) {
-      height = 6716;
-      width  = 8964;
-      top_margin  = 8;
-      left_margin = 40;
-      black += load_flags = 256;
-      maximum = 0x8101;
+      if(black > 500)
+        {
+          top_margin = 12;
+          left_margin = 44;
+          width = 8956;
+          height = 6708;
+          memset(cblack,0,sizeof(cblack));
+          adobe_coeff("Hasselblad","H4D-60");
+          strcpy(model,"H4D-60");
+          black = 512;
+        }
+      else
+        {
+          height = 6716;
+          width  = 8964;
+          top_margin  = 8;
+          left_margin = 40;
+          black += load_flags = 256;
+          maximum = 0x8101;
+          strcpy(model,"H3DII-60");
+        }
     } else if (raw_width == 4090) {
       strcpy (model, "V96C");
       height -= (top_margin = 6);
       width -= (left_margin = 3) + 7;
       filters = 0x61616161;
+    } else if (raw_width == 8282 && raw_height == 6240) {
+      if(!strcasecmp(model,"H5D"))
+        {
+          /* H5D 50*/
+          left_margin = 54;
+          top_margin = 16;
+          width = 8176;
+          height = 6132;
+          black = 256;
+          strcpy(model,"H5D-50");
+        }
+      else if(!strcasecmp(model,"H3D"))
+        {
+          black=0;
+          left_margin = 54;
+          top_margin = 16;
+          width = 8176;
+          height = 6132;
+          memset(cblack,0,sizeof(cblack));
+          adobe_coeff("Hasselblad","H3D-50");
+          strcpy(model,"H3D-50");
+        }
+    } else if (raw_width == 8374 && raw_height == 6304) {
+      /* H5D 50c*/
+      left_margin = 52;
+      top_margin = 100;
+      width = 8272;
+      height = 6200;
+      black = 256;
+      strcpy(model,"H5D-50c");
     }
-  } else if (!strcmp(make,"Sinar")) {
-    if (!memcmp(head,"8BPS",4)) {
-      fseek (ifp, 14, SEEK_SET);
-      height = get4();
-      width  = get4();
-      filters = 0x61616161;
-      data_offset = 68;
+    if (tiff_samples > 1) {
+      is_raw = tiff_samples+1;
+      if (!shot_select && !half_size) filters = 0;
     }
+  } else if (!strcmp(make,"Sinar")) {
     if (!load_raw) load_raw = &CLASS unpacked_load_raw;
+    if (is_raw > 1 && !shot_select && !half_size) filters = 0;
     maximum = 0x3fff;
   } else if (!strcmp(make,"Leaf")) {
     maximum = 0x3fff;
@@ -8233,7 +14131,7 @@ wb550:
       width -= 2 * (left_margin = 24);
       filters = 0x16161616;
     }
-  } else if (!strcmp(make,"LEICA") || !strcmp(make,"Panasonic")) {
+  } else if (!strcmp(make,"Leica") || !strcmp(make,"Panasonic")) {
     if ((flen - data_offset) / (raw_width*8/7) == raw_height)
       load_raw = &CLASS panasonic_load_raw;
     if (!load_raw) {
@@ -8257,11 +14155,12 @@ wb550:
     filters = 0x16161616;
     load_raw = &CLASS packed_load_raw;
     load_flags = 30;
-  } else if (!strcmp(make,"OLYMPUS")) {
+  } else if (!strcmp(make,"Olympus")) {
     height += height & 1;
-    filters = exif_cfa;
+    if (exif_cfa) filters = exif_cfa;
     if (width == 4100) width -= 4;
     if (width == 4080) width -= 24;
+    if (width == 9280) { width -= 6; height -= 6; }
     if (load_raw == &CLASS unpacked_load_raw)
       load_flags = 4;
     tiff_bps = 12;
@@ -8272,6 +14171,9 @@ wb550:
 	maximum = 0xfc3;
 	memset (cblack, 0, sizeof cblack);
       }
+    } else if (!strcmp(model,"STYLUS1")) {
+      width -= 14;
+      maximum = 0xfff;
     } else if (!strcmp(model,"E-330")) {
       width -= 30;
       if (load_raw == &CLASS unpacked_load_raw)
@@ -8290,6 +14192,7 @@ wb550:
   } else if (!strcmp(model,"DSC-F828")) {
     width = 3288;
     left_margin = 5;
+    mask[1][3] = -17;
     data_offset = 862144;
     load_raw = &CLASS sony_load_raw;
     filters = 0x9c9c9c9c;
@@ -8298,19 +14201,31 @@ wb550:
   } else if (!strcmp(model,"DSC-V3")) {
     width = 3109;
     left_margin = 59;
+    mask[0][1] = 9;
     data_offset = 787392;
     load_raw = &CLASS sony_load_raw;
-  } else if (!strcmp(make,"SONY") && raw_width == 3984) {
-    adobe_coeff ("SONY","DSC-R1");
+  } else if (!strcmp(make,"Sony") && raw_width == 3984) {
     width = 3925;
     order = 0x4d4d;
-  } else if (!strcmp(make,"SONY") && raw_width == 6048) {
+  } else if (!strcmp(make,"Sony") && raw_width == 4288) {
+    width -= 32;
+  } else if (!strcmp(make,"Sony") && raw_width == 4928) {
+    if (height < 3280) width -= 8;
+  } else if (!strcmp(make,"Sony") && raw_width == 5504) { // ILCE-3000//5000
+    width -= height > 3664 ? 8 : 32;
+  } else if (!strcmp(make,"Sony") && raw_width == 6048) {
     width -= 24;
+    if (strstr(model,"RX1") || strstr(model,"A99"))
+      width -= 6;
+  } else if (!strcmp(make,"Sony") && raw_width == 7392) {
+    width -= 30;
   } else if (!strcmp(model,"DSLR-A100")) {
     if (width == 3880) {
       height--;
       width = ++raw_width;
     } else {
+      height -= 4;
+      width  -= 4;
       order = 0x4d4d;
       load_flags = 2;
     }
@@ -8321,72 +14236,35 @@ wb550:
     height -= top_margin = 4;
     width -= left_margin = 32;
     gamma_curve (0, 7, 1, 255);
-  } else if (!strcmp(model,"C603v")) {
-    height = 480;
-    width  = 640;
-    if (fsize < 614400 || find_green (16, 16, 3840, 5120) < 25) goto c603v;
-    strcpy (model,"KAI-0340");
-    height -= 3;
-    data_offset = 3840;
-    order = 0x4949;
-    load_raw = &CLASS unpacked_load_raw;
-  } else if (!strcmp(model,"C603y")) {
-    height = 2134;
-    width  = 2848;
-c603v:
-    filters = 0;
-    load_raw = &CLASS kodak_yrgb_load_raw;
-    gamma_curve (0, 3.875, 1, 255);
-  } else if (!strcmp(model,"C603")) {
-    raw_height = height = 2152;
-    raw_width  = width  = 2864;
-    goto c603;
-  } else if (!strcmp(model,"C330")) {
-    height = 1744;
-    width  = 2336;
-    raw_height = 1779;
-    raw_width  = 2338;
-    top_margin = 33;
-    left_margin = 1;
-c603:
+  } else if (!strcmp(model,"C603") || !strcmp(model,"C330")
+	|| !strcmp(model,"12MP")) {
     order = 0x4949;
-    if ((data_offset = fsize - raw_height*raw_width)) {
-      fseek (ifp, 168, SEEK_SET);
+    if (filters && data_offset) {
+      fseek (ifp, data_offset < 4096 ? 168 : 5252, SEEK_SET);
       read_shorts (curve, 256);
     } else gamma_curve (0, 3.875, 1, 255);
-    load_raw = &CLASS eight_bit_load_raw;
+    load_raw  =  filters   ? &CLASS eight_bit_load_raw :
+      strcmp(model,"C330") ? &CLASS kodak_c603_load_raw :
+			     &CLASS kodak_c330_load_raw;
+    load_flags = tiff_bps > 16;
+    tiff_bps = 8;
   } else if (!strncasecmp(model,"EasyShare",9)) {
     data_offset = data_offset < 0x15000 ? 0x15000 : 0x17000;
     load_raw = &CLASS packed_load_raw;
-  } else if (!strcasecmp(make,"KODAK")) {
+  } else if (!strcasecmp(make,"Kodak")) {
     if (filters == UINT_MAX) filters = 0x61616161;
-    if (!strncmp(model,"NC2000",6)) {
-      width -= 4;
-      left_margin = 2;
-    } else if (!strcmp(model,"EOSDCS3B")) {
-      width -= 4;
-      left_margin = 2;
-    } else if (!strcmp(model,"EOSDCS1")) {
-      width -= 4;
-      left_margin = 2;
-    } else if (!strcmp(model,"DCS420")) {
-      width -= 4;
-      left_margin = 2;
-    } else if (!strncmp(model,"DCS460 ",7)) {
-      model[6] = 0;
-      width -= 4;
-      left_margin = 2;
-    } else if (!strcmp(model,"DCS460A")) {
+    if (!strncmp(model,"NC2000",6) ||
+	!strncmp(model,"EOSDCS",6) ||
+	!strncmp(model,"DCS4",4)) {
       width -= 4;
       left_margin = 2;
-      colors = 1;
-      filters = 0;
+      if (model[6] == ' ') model[6] = 0;
+      if (!strcmp(model,"DCS460A")) goto bw;
     } else if (!strcmp(model,"DCS660M")) {
       black = 214;
-      colors = 1;
-      filters = 0;
+      goto bw;
     } else if (!strcmp(model,"DCS760M")) {
-      colors = 1;
+bw:   colors = 1;
       filters = 0;
     }
     if (!strcmp(model+4,"20X"))
@@ -8396,7 +14274,11 @@ c603:
       data_offset = 15424;
     }
     if (!strncmp(model,"DC2",3)) {
-      raw_height = height = 242;
+      raw_height = 2 + (height = 242);
+      if (!strncmp(model, "DC290", 5))
+        iso_speed = 100;
+      if (!strncmp(model, "DC280", 5))
+        iso_speed = 70;
       if (flen < 100000) {
 	raw_width = 256; width = 249;
 	pixel_aspect = (4.0*height) / (3.0*width);
@@ -8404,7 +14286,7 @@ c603:
 	raw_width = 512; width = 501;
 	pixel_aspect = (493.0*height) / (373.0*width);
       }
-      data_offset += raw_width + 1;
+      top_margin = left_margin = 1;
       colors = 4;
       filters = 0x8d8d8d8d;
       simple_coeff(1);
@@ -8422,12 +14304,14 @@ c603:
       strcpy (model, "DC50");
       height = 512;
       width  = 768;
+      iso_speed=84;
       data_offset = 19712;
       load_raw = &CLASS kodak_radc_load_raw;
     } else if (strstr(model,"DC120")) {
       strcpy (model, "DC120");
       height = 976;
       width  = 848;
+      iso_speed=160;
       pixel_aspect = height/0.75/width;
       load_raw = tiff_compress == 7 ?
 	&CLASS kodak_jpeg_load_raw : &CLASS kodak_dc120_load_raw;
@@ -8436,11 +14320,8 @@ c603:
       thumb_width  = 192;
       thumb_offset = 6144;
       thumb_misc   = 360;
+      iso_speed=140;
       write_thumb = &CLASS layer_thumb;
-      height = 1024;
-      width  = 1536;
-      data_offset = 79872;
-      load_raw = &CLASS eight_bit_load_raw;
       black = 17;
     }
   } else if (!strcmp(model,"Fotoman Pixtura")) {
@@ -8478,113 +14359,53 @@ c603:
     }
     filters = 0x16161616;
     load_raw = &CLASS rollei_load_raw;
-  } else if (!strcmp(model,"PC-CAM 600")) {
-    height = 768;
-    data_offset = width = 1024;
-    filters = 0x49494949;
-    load_raw = &CLASS eight_bit_load_raw;
-  } else if (!strcmp(model,"QV-2000UX")) {
-    height = 1208;
-    width  = 1632;
-    data_offset = width * 2;
-    load_raw = &CLASS eight_bit_load_raw;
-  } else if (fsize == 3217760) {
-    height = 1546;
-    width  = 2070;
-    raw_width = 2080;
-    load_raw = &CLASS eight_bit_load_raw;
-  } else if (!strcmp(model,"QV-4000")) {
-    height = 1700;
-    width  = 2260;
-    load_raw = &CLASS unpacked_load_raw;
-    maximum = 0xffff;
-  } else if (!strcmp(model,"QV-5700")) {
-    height = 1924;
-    width  = 2576;
-    raw_width = 3232;
-    tiff_bps = 10;
-  } else if (!strcmp(model,"QV-R41")) {
-    height = 1720;
-    width  = 2312;
-    raw_width = 3520;
-    left_margin = 2;
-  } else if (!strcmp(model,"QV-R51")) {
-    height = 1926;
-    width  = 2580;
-    raw_width = 3904;
-  } else if (!strcmp(model,"EX-S20")) {
-    height = 1208;
-    width  = 1620;
-    raw_width = 2432;
-    flip = 3;
-  } else if (!strcmp(model,"EX-S100")) {
-    height = 1544;
-    width  = 2058;
-    raw_width = 3136;
-  } else if (!strcmp(model,"EX-Z50")) {
-    height = 1931;
-    width  = 2570;
-    raw_width = 3904;
-  } else if (!strcmp(model,"EX-Z500")) {
-    height = 1937;
-    width  = 2577;
-    raw_width = 3904;
-    filters = 0x16161616;
-  } else if (!strcmp(model,"EX-Z55")) {
-    height = 1960;
-    width  = 2570;
-    raw_width = 3904;
-  } else if (!strcmp(model,"EX-Z60")) {
-    height = 2145;
-    width  = 2833;
-    raw_width = 3584;
-    filters = 0x16161616;
-    tiff_bps = 10;
-  } else if (!strcmp(model,"EX-Z75")) {
-    height = 2321;
-    width  = 3089;
-    raw_width = 4672;
-    maximum = 0xfff;
-  } else if (!strcmp(model,"EX-Z750")) {
-    height = 2319;
-    width  = 3087;
-    raw_width = 4672;
-    maximum = 0xfff;
-  } else if (!strcmp(model,"EX-Z850")) {
-    height = 2468;
-    width  = 3279;
-    raw_width = 4928;
-    maximum = 0xfff;
-  } else if (!strcmp(model,"EX-Z8")) {
-    height = 2467;
-    width  = 3281;
-    raw_height = 2502;
-    raw_width  = 4992;
-    maximum = 0xfff;
-  } else if (fsize == 15499264) {	/* EX-Z1050 or EX-Z1080 */
-    height = 2752;
-    width  = 3672;
-    raw_width = 5632;
-  } else if (!strcmp(model,"EX-P505")) {
-    height = 1928;
-    width  = 2568;
-    raw_width = 3852;
-    maximum = 0xfff;
-  } else if (fsize == 9313536) {	/* EX-P600 or QV-R61 */
-    height = 2142;
-    width  = 2844;
-    raw_width = 4288;
-  } else if (!strcmp(model,"EX-P700")) {
-    height = 2318;
-    width  = 3082;
-    raw_width = 4672;
   }
+  else if (!strcmp(model,"GRAS-50S5C")) {
+   height = 2048;
+   width = 2440;
+   load_raw = &CLASS unpacked_load_raw;
+   data_offset = 0;
+   filters = 0x49494949;
+   order = 0x4949;
+   maximum = 0xfffC;
+  } else if (!strcmp(model,"BB-500CL")) {
+   height = 2058;
+   width = 2448;
+   load_raw = &CLASS unpacked_load_raw;
+   data_offset = 0;
+   filters = 0x94949494;
+   order = 0x4949;
+   maximum = 0x3fff;
+  } else if (!strcmp(model,"BB-500GE")) {
+   height = 2058;
+   width = 2456;
+   load_raw = &CLASS unpacked_load_raw;
+   data_offset = 0;
+   filters = 0x94949494;
+   order = 0x4949;
+   maximum = 0x3fff;
+  } else if (!strcmp(model,"SVS625CL")) {
+   height = 2050;
+   width = 2448;
+   load_raw = &CLASS unpacked_load_raw;
+   data_offset = 0;
+   filters = 0x94949494;
+   order = 0x4949;
+   maximum = 0x0fff;
+  }
+  /* Early reject for damaged images */
+  if (!load_raw || height < 22 || width < 22 ||
+	tiff_bps > 16 || tiff_samples > 4 || colors > 4 || colors < 1)
+    {
+      is_raw = 0;
+#ifdef LIBRAW_LIBRARY_BUILD
+      RUN_CALLBACK(LIBRAW_PROGRESS_IDENTIFY,1,2);
+#endif
+      return;
+    }
   if (!model[0])
     sprintf (model, "%dx%d", width, height);
   if (filters == UINT_MAX) filters = 0x94949494;
-  if (raw_color) adobe_coeff (make, model);
-  if (load_raw == &CLASS kodak_radc_load_raw)
-    if (raw_color) adobe_coeff ("Apple","Quicktake");
   if (thumb_offset && !thumb_height) {
     fseek (ifp, thumb_offset, SEEK_SET);
     if (ljpeg_start (&jh, 1)) {
@@ -8592,7 +14413,23 @@ c603:
       thumb_height = jh.high;
     }
   }
+
 dng_skip:
+  if ((use_camera_matrix & (use_camera_wb || dng_version))
+	&& cmatrix[0][0] > 0.125) {
+    memcpy (rgb_cam, cmatrix, sizeof cmatrix);
+    raw_color = 0;
+  }
+
+  if (raw_color) adobe_coeff (make, model);
+#ifdef LIBRAW_LIBRARY_BUILD
+  else if(imgdata.color.cam_xyz[0][0]<0.01)
+	  adobe_coeff (make, model,1);
+#endif
+
+  if (load_raw == &CLASS kodak_radc_load_raw)
+    if (raw_color) adobe_coeff ("Apple","Quicktake");
+
   if (fuji_width) {
     fuji_width = width >> !fuji_layout;
     if (~fuji_width & 1) filters = 0x49494949;
@@ -8604,35 +14441,60 @@ dng_skip:
     if (raw_width  < width ) raw_width  = width;
   }
   if (!tiff_bps) tiff_bps = 12;
-  if (!maximum) maximum = (1 << tiff_bps) - 1;
-  if (!load_raw || height < 22) is_raw = 0;
+  if (!maximum)
+    {
+      maximum = (1 << tiff_bps) - 1;
+      if(maximum < 0x10000 && curve[maximum]>0 &&    load_raw == &CLASS sony_arw2_load_raw)
+        maximum = curve[maximum];
+    }
+  if (!load_raw || height < 22 || width < 22 ||
+	tiff_bps > 16 || tiff_samples > 6 || colors > 4)
+    is_raw = 0;
 #ifdef NO_JASPER
   if (load_raw == &CLASS redcine_load_raw) {
+#ifdef DCRAW_VERBOSE
     fprintf (stderr,_("%s: You must link dcraw with %s!!\n"),
 	ifname, "libjasper");
+#endif
     is_raw = 0;
+#ifdef LIBRAW_LIBRARY_BUILD
+    imgdata.process_warnings |= LIBRAW_WARN_NO_JASPER;
+#endif
   }
 #endif
 #ifdef NO_JPEG
   if (load_raw == &CLASS kodak_jpeg_load_raw ||
       load_raw == &CLASS lossy_dng_load_raw) {
+#ifdef DCRAW_VERBOSE
     fprintf (stderr,_("%s: You must link dcraw with %s!!\n"),
 	ifname, "libjpeg");
+#endif
     is_raw = 0;
+#ifdef LIBRAW_LIBRARY_BUILD
+    imgdata.process_warnings |= LIBRAW_WARN_NO_JPEGLIB;
+#endif
   }
 #endif
   if (!cdesc[0])
     strcpy (cdesc, colors == 3 ? "RGBG":"GMCY");
   if (!raw_height) raw_height = height;
   if (!raw_width ) raw_width  = width;
-  if (filters && colors == 3)
+  if (filters > 999 && colors == 3)
     filters |= ((filters >> 2 & 0x22222222) |
 		(filters << 2 & 0x88888888)) & filters << 1;
 notraw:
-  if (flip == -1) flip = tiff_flip;
-  if (flip == -1) flip = 0;
+  if (flip == UINT_MAX) flip = tiff_flip;
+  if (flip == UINT_MAX) flip = 0;
+
+#ifdef LIBRAW_LIBRARY_BUILD
+  RUN_CALLBACK(LIBRAW_PROGRESS_IDENTIFY,1,2);
+#endif
 }
 
+
+//@end COMMON
+
+//@out FILEIO
 #ifndef NO_LCMS
 void CLASS apply_profile (const char *input, const char *output)
 {
@@ -8642,19 +14504,35 @@ void CLASS apply_profile (const char *input, const char *output)
   FILE *fp;
   unsigned size;
 
-  cmsErrorAction (LCMS_ERROR_SHOW);
   if (strcmp (input, "embed"))
     hInProfile = cmsOpenProfileFromFile (input, "r");
   else if (profile_length) {
+#ifndef LIBRAW_LIBRARY_BUILD
     prof = (char *) malloc (profile_length);
     merror (prof, "apply_profile()");
     fseek (ifp, profile_offset, SEEK_SET);
     fread (prof, 1, profile_length, ifp);
     hInProfile = cmsOpenProfileFromMem (prof, profile_length);
     free (prof);
+#else
+    hInProfile = cmsOpenProfileFromMem (imgdata.color.profile, profile_length);
+#endif
   } else
-    fprintf (stderr,_("%s has no embedded profile.\n"), ifname);
-  if (!hInProfile) return;
+    {
+#ifdef LIBRAW_LIBRARY_BUILD
+          imgdata.process_warnings |= LIBRAW_WARN_NO_EMBEDDED_PROFILE;
+#endif
+#ifdef DCRAW_VERBOSE
+          fprintf (stderr,_("%s has no embedded profile.\n"), ifname);
+#endif
+    }
+  if (!hInProfile)
+      {
+#ifdef LIBRAW_LIBRARY_BUILD
+          imgdata.process_warnings |= LIBRAW_WARN_NO_INPUT_PROFILE;
+#endif
+          return;
+      }
   if (!output)
     hOutProfile = cmsCreate_sRGBProfile();
   else if ((fp = fopen (output, "rb"))) {
@@ -8668,11 +14546,25 @@ void CLASS apply_profile (const char *input, const char *output)
       free (oprof);
       oprof = 0;
     }
-  } else
+  }
+#ifdef DCRAW_VERBOSE
+ else
     fprintf (stderr,_("Cannot open file %s!\n"), output);
-  if (!hOutProfile) goto quit;
+#endif
+  if (!hOutProfile)
+      {
+#ifdef LIBRAW_LIBRARY_BUILD
+          imgdata.process_warnings |= LIBRAW_WARN_BAD_OUTPUT_PROFILE;
+#endif
+          goto quit;
+      }
+#ifdef DCRAW_VERBOSE
   if (verbose)
     fprintf (stderr,_("Applying color profile...\n"));
+#endif
+#ifdef LIBRAW_LIBRARY_BUILD
+  RUN_CALLBACK(LIBRAW_PROGRESS_APPLY_PROFILE,0,2);
+#endif
   hTransform = cmsCreateTransform (hInProfile, TYPE_RGBA_16,
 	hOutProfile, TYPE_RGBA_16, INTENT_PERCEPTUAL, 0);
   cmsDoTransform (hTransform, image, image, width*height);
@@ -8681,14 +14573,25 @@ void CLASS apply_profile (const char *input, const char *output)
   cmsCloseProfile (hOutProfile);
 quit:
   cmsCloseProfile (hInProfile);
+#ifdef LIBRAW_LIBRARY_BUILD
+  RUN_CALLBACK(LIBRAW_PROGRESS_APPLY_PROFILE,1,2);
+#endif
 }
 #endif
+//@end FILEIO
 
+//@out COMMON
 void CLASS convert_to_rgb()
 {
-  int row, col, c, i, j, k;
+#ifndef LIBRAW_LIBRARY_BUILD
+  int row, col, c;
+#endif
+  int  i, j, k;
+#ifndef LIBRAW_LIBRARY_BUILD
   ushort *img;
-  float out[3], out_cam[3][4];
+  float out[3];
+#endif
+  float out_cam[3][4];
   double num, inverse[3][3];
   static const double xyzd50_srgb[3][3] =
   { { 0.436083, 0.385083, 0.143055 },
@@ -8729,10 +14632,18 @@ void CLASS convert_to_rgb()
   static const unsigned pwhite[] = { 0xf351, 0x10000, 0x116cc };
   unsigned pcurve[] = { 0x63757276, 0, 1, 0x1000000 };
 
+#ifdef LIBRAW_LIBRARY_BUILD
+  RUN_CALLBACK(LIBRAW_PROGRESS_CONVERT_RGB,0,2);
+#endif
   gamma_curve (gamm[0], gamm[1], 0, 0);
   memcpy (out_cam, rgb_cam, sizeof out_cam);
+#ifndef LIBRAW_LIBRARY_BUILD
   raw_color |= colors == 1 || document_mode ||
 		output_color < 1 || output_color > 5;
+#else
+  raw_color |= colors == 1 ||
+		output_color < 1 || output_color > 5;
+#endif
   if (!raw_color) {
     oprof = (unsigned *) calloc (phead[0], 1);
     merror (oprof, "convert_to_rgb()");
@@ -8766,10 +14677,14 @@ void CLASS convert_to_rgb()
 	for (out_cam[i][j] = k=0; k < 3; k++)
 	  out_cam[i][j] += out_rgb[output_color-1][i][k] * rgb_cam[k][j];
   }
+#ifdef DCRAW_VERBOSE
   if (verbose)
     fprintf (stderr, raw_color ? _("Building histograms...\n") :
 	_("Converting to %s colorspace...\n"), name[output_color-1]);
-
+#endif
+#ifdef LIBRAW_LIBRARY_BUILD
+  convert_to_rgb_loop(out_cam);
+#else
   memset (histogram, 0, sizeof histogram);
   for (img=image[0], row=0; row < height; row++)
     for (col=0; col < width; col++, img+=4) {
@@ -8786,8 +14701,14 @@ void CLASS convert_to_rgb()
 	img[0] = img[fcol(row,col)];
       FORCC histogram[c][img[c] >> 3]++;
     }
+#endif
   if (colors == 4 && output_color) colors = 3;
+#ifndef LIBRAW_LIBRARY_BUILD
   if (document_mode && filters) colors = 1;
+#endif
+#ifdef LIBRAW_LIBRARY_BUILD
+  RUN_CALLBACK(LIBRAW_PROGRESS_CONVERT_RGB,1,2);
+#endif
 }
 
 void CLASS fuji_rotate()
@@ -8799,15 +14720,21 @@ void CLASS fuji_rotate()
   ushort wide, high, (*img)[4], (*pix)[4];
 
   if (!fuji_width) return;
+#ifdef DCRAW_VERBOSE
   if (verbose)
     fprintf (stderr,_("Rotating image 45 degrees...\n"));
+#endif
   fuji_width = (fuji_width - 1 + shrink) >> shrink;
   step = sqrt(0.5);
   wide = fuji_width / step;
   high = (height - fuji_width) / step;
-  img = (ushort (*)[4]) calloc (wide*high, sizeof *img);
+  img = (ushort (*)[4]) calloc (high, wide*sizeof *img);
   merror (img, "fuji_rotate()");
 
+#ifdef LIBRAW_LIBRARY_BUILD
+  RUN_CALLBACK(LIBRAW_PROGRESS_FUJI_ROTATE,0,2);
+#endif
+
   for (row=0; row < high; row++)
     for (col=0; col < wide; col++) {
       ur = r = fuji_width + (row-col)*step;
@@ -8821,11 +14748,15 @@ void CLASS fuji_rotate()
 	  (pix[    0][i]*(1-fc) + pix[      1][i]*fc) * (1-fr) +
 	  (pix[width][i]*(1-fc) + pix[width+1][i]*fc) * fr;
     }
+
   free (image);
   width  = wide;
   height = high;
   image  = img;
   fuji_width = 0;
+#ifdef LIBRAW_LIBRARY_BUILD
+  RUN_CALLBACK(LIBRAW_PROGRESS_FUJI_ROTATE,1,2);
+#endif
 }
 
 void CLASS stretch()
@@ -8835,10 +14766,15 @@ void CLASS stretch()
   double rc, frac;
 
   if (pixel_aspect == 1) return;
+#ifdef LIBRAW_LIBRARY_BUILD
+  RUN_CALLBACK(LIBRAW_PROGRESS_STRETCH,0,2);
+#endif
+#ifdef DCRAW_VERBOSE
   if (verbose) fprintf (stderr,_("Stretching the image...\n"));
+#endif
   if (pixel_aspect < 1) {
     newdim = height / pixel_aspect + 0.5;
-    img = (ushort (*)[4]) calloc (width*newdim, sizeof *img);
+    img = (ushort (*)[4]) calloc (width, newdim*sizeof *img);
     merror (img, "stretch()");
     for (rc=row=0; row < newdim; row++, rc+=pixel_aspect) {
       frac = rc - (c = rc);
@@ -8850,7 +14786,7 @@ void CLASS stretch()
     height = newdim;
   } else {
     newdim = width * pixel_aspect + 0.5;
-    img = (ushort (*)[4]) calloc (height*newdim, sizeof *img);
+    img = (ushort (*)[4]) calloc (height, newdim*sizeof *img);
     merror (img, "stretch()");
     for (rc=col=0; col < newdim; col++, rc+=1/pixel_aspect) {
       frac = rc - (c = rc);
@@ -8863,6 +14799,9 @@ void CLASS stretch()
   }
   free (image);
   image = img;
+#ifdef LIBRAW_LIBRARY_BUILD
+  RUN_CALLBACK(LIBRAW_PROGRESS_STRETCH,1,2);
+#endif
 }
 
 int CLASS flip_index (int row, int col)
@@ -8872,6 +14811,8 @@ int CLASS flip_index (int row, int col)
   if (flip & 1) col = iwidth  - 1 - col;
   return row * iwidth + col;
 }
+//@end COMMON
+
 
 struct tiff_tag {
   ushort tag, type;
@@ -8880,7 +14821,7 @@ struct tiff_tag {
 };
 
 struct tiff_hdr {
-  ushort order, magic;
+  ushort t_order, magic;
   int ifd;
   ushort pad, ntag;
   struct tiff_tag tag[23];
@@ -8892,9 +14833,10 @@ struct tiff_hdr {
   short bps[4];
   int rat[10];
   unsigned gps[26];
-  char desc[512], make[64], model[64], soft[32], date[20], artist[64];
+  char t_desc[512], t_make[64], t_model[64], soft[32], date[20], t_artist[64];
 };
 
+//@out COMMON
 void CLASS tiff_set (ushort *ntag,
 	ushort tag, ushort type, int count, int val)
 {
@@ -8920,7 +14862,7 @@ void CLASS tiff_head (struct tiff_hdr *th, int full)
   struct tm *t;
 
   memset (th, 0, sizeof *th);
-  th->order = htonl(0x4d4d4949) >> 16;
+  th->t_order = htonl(0x4d4d4949) >> 16;
   th->magic = 42;
   th->ifd = 10;
   if (full) {
@@ -8934,9 +14876,9 @@ void CLASS tiff_head (struct tiff_hdr *th, int full)
     tiff_set (&th->ntag, 259, 3, 1, 1);
     tiff_set (&th->ntag, 262, 3, 1, 1 + (colors > 1));
   }
-  tiff_set (&th->ntag, 270, 2, 512, TOFF(th->desc));
-  tiff_set (&th->ntag, 271, 2, 64, TOFF(th->make));
-  tiff_set (&th->ntag, 272, 2, 64, TOFF(th->model));
+  tiff_set (&th->ntag, 270, 2, 512, TOFF(th->t_desc));
+  tiff_set (&th->ntag, 271, 2, 64, TOFF(th->t_make));
+  tiff_set (&th->ntag, 272, 2, 64, TOFF(th->t_model));
   if (full) {
     if (oprof) psize = ntohl(oprof[0]);
     tiff_set (&th->ntag, 273, 4, 1, sizeof *th + psize);
@@ -8951,7 +14893,7 @@ void CLASS tiff_head (struct tiff_hdr *th, int full)
   tiff_set (&th->ntag, 296, 3, 1, 2);
   tiff_set (&th->ntag, 305, 2, 32, TOFF(th->soft));
   tiff_set (&th->ntag, 306, 2, 20, TOFF(th->date));
-  tiff_set (&th->ntag, 315, 2, 64, TOFF(th->artist));
+  tiff_set (&th->ntag, 315, 2, 64, TOFF(th->t_artist));
   tiff_set (&th->ntag, 34665, 4, 1, TOFF(th->nexif));
   if (psize) tiff_set (&th->ntag, 34675, 7, psize, sizeof *th);
   tiff_set (&th->nexif, 33434, 5, 1, TOFF(th->rat[4]));
@@ -8978,19 +14920,47 @@ void CLASS tiff_head (struct tiff_hdr *th, int full)
   th->rat[4] *= shutter;
   th->rat[6] *= aperture;
   th->rat[8] *= focal_len;
-  strncpy (th->desc, desc, 512);
-  strncpy (th->make, make, 64);
-  strncpy (th->model, model, 64);
-  strcpy (th->soft, "dcraw v"DCRAW_VERSION);
+  strncpy (th->t_desc, desc, 512);
+  strncpy (th->t_make, make, 64);
+  strncpy (th->t_model, model, 64);
+  strcpy (th->soft, "dcraw v" DCRAW_VERSION);
   t = localtime (&timestamp);
   sprintf (th->date, "%04d:%02d:%02d %02d:%02d:%02d",
       t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);
-  strncpy (th->artist, artist, 64);
+  strncpy (th->t_artist, artist, 64);
+}
+
+#ifdef LIBRAW_LIBRARY_BUILD
+void CLASS jpeg_thumb_writer (FILE *tfp,char *t_humb,int t_humb_length)
+{
+  ushort exif[5];
+  struct tiff_hdr th;
+  fputc (0xff, tfp);
+  fputc (0xd8, tfp);
+  if (strcmp (t_humb+6, "Exif")) {
+    memcpy (exif, "\xff\xe1  Exif\0\0", 10);
+    exif[1] = htons (8 + sizeof th);
+    fwrite (exif, 1, sizeof exif, tfp);
+    tiff_head (&th, 0);
+    fwrite (&th, 1, sizeof th, tfp);
+  }
+  fwrite (t_humb+2, 1, t_humb_length-2, tfp);
 }
 
 void CLASS jpeg_thumb()
 {
   char *thumb;
+
+  thumb = (char *) malloc (thumb_length);
+  merror (thumb, "jpeg_thumb()");
+  fread (thumb, 1, thumb_length, ifp);
+  jpeg_thumb_writer(ofp,thumb,thumb_length);
+  free (thumb);
+}
+#else
+void CLASS jpeg_thumb()
+{
+  char *thumb;
   ushort exif[5];
   struct tiff_hdr th;
 
@@ -9009,6 +14979,7 @@ void CLASS jpeg_thumb()
   fwrite (thumb+2, 1, thumb_length-2, ofp);
   free (thumb);
 }
+#endif
 
 void CLASS write_ppm_tiff()
 {
@@ -9016,17 +14987,21 @@ void CLASS write_ppm_tiff()
   uchar *ppm;
   ushort *ppm2;
   int c, row, col, soff, rstep, cstep;
-  int perc, val, total, white=0x2000;
+  int perc, val, total, t_white=0x2000;
 
+#ifdef LIBRAW_LIBRARY_BUILD
+  perc = width * height * auto_bright_thr;
+#else
   perc = width * height * 0.01;		/* 99th percentile white level */
+#endif
   if (fuji_width) perc /= 2;
   if (!((highlight & ~2) || no_auto_bright))
-    for (white=c=0; c < colors; c++) {
+    for (t_white=c=0; c < colors; c++) {
       for (val=0x2000, total=0; --val > 32; )
 	if ((total += histogram[c][val]) > perc) break;
-      if (white < val) white = val;
+      if (t_white < val) t_white = val;
     }
-  gamma_curve (gamm[0], gamm[1], 2, (white << 3)/bright);
+  gamma_curve (gamm[0], gamm[1], 2, (t_white << 3)/bright);
   iheight = height;
   iwidth  = width;
   if (flip & 4) SWAP(height,width);
@@ -9054,11 +15029,12 @@ void CLASS write_ppm_tiff()
 	   FORCC ppm [col*colors+c] = curve[image[soff][c]] >> 8;
       else FORCC ppm2[col*colors+c] = curve[image[soff][c]];
     if (output_bps == 16 && !output_tiff && htons(0x55aa) != 0x55aa)
-      swab (ppm2, ppm2, width*colors*2);
+      swab ((char*)ppm2, (char*)ppm2, width*colors*2);
     fwrite (ppm, colors*output_bps/8, width, ofp);
   }
   free (ppm);
 }
+//@end COMMON
 
 int CLASS main (int argc, const char **argv)
 {
@@ -9173,12 +15149,12 @@ int CLASS main (int argc, const char **argv)
       case 'i':  identify_only     = 1;  break;
       case 'c':  write_to_stdout   = 1;  break;
       case 'v':  verbose           = 1;  break;
-      case 'h':  half_size         = 1;		/* "-h" implies "-f" */
+      case 'h':  half_size         = 1;  break;
       case 'f':  four_color_rgb    = 1;  break;
       case 'A':  FORC4 greybox[c]  = atoi(argv[arg++]);
       case 'a':  use_auto_wb       = 1;  break;
       case 'w':  use_camera_wb     = 1;  break;
-      case 'M':  use_camera_matrix = (opm == '+');  break;
+      case 'M':  use_camera_matrix = 3 * (opm == '+');  break;
       case 'I':  read_from_stdin   = 1;  break;
       case 'E':  document_mode++;
       case 'D':  document_mode++;
@@ -9194,8 +15170,6 @@ int CLASS main (int argc, const char **argv)
 	return 1;
     }
   }
-  if (use_camera_matrix < 0)
-      use_camera_matrix = use_camera_wb;
   if (arg == argc) {
     fprintf (stderr,_("No files to process.\n"));
     return 1;
@@ -9262,6 +15236,7 @@ int CLASS main (int argc, const char **argv)
 	height = thumb_height;
 	width  = thumb_width;
 	filters = 0;
+	colors = 3;
       } else {
 	fseek (ifp, thumb_offset, SEEK_SET);
 	write_fun = write_thumb;
@@ -9272,6 +15247,7 @@ int CLASS main (int argc, const char **argv)
       height += height & 1;
       width  += width  & 1;
     }
+
     if (identify_only && verbose && make[0]) {
       printf (_("\nFilename: %s\n"), ifname);
       printf (_("Timestamp: %s"), ctime(&timestamp));
@@ -9302,17 +15278,17 @@ int CLASS main (int argc, const char **argv)
     if (!is_raw) goto next;
     shrink = filters && (half_size || (!identify_only &&
 	(threshold || aber[0] != 1 || aber[2] != 1)));
-    if (document_mode == 3) {
-      top_margin = left_margin = fuji_width = 0;
-      height = raw_height;
-      if  (width <= raw_width * 8 / tiff_bps)
-	   width  = raw_width * 8 / tiff_bps;
-      else width  = raw_width;
-    }
     iheight = (height + shrink) >> shrink;
     iwidth  = (width  + shrink) >> shrink;
     if (identify_only) {
       if (verbose) {
+	if (document_mode == 3) {
+	  top_margin = left_margin = fuji_width = 0;
+	  height = raw_height;
+	  width  = raw_width;
+	}
+	iheight = (height + shrink) >> shrink;
+	iwidth  = (width  + shrink) >> shrink;
 	if (use_fuji_rotate) {
 	  if (fuji_width) {
 	    fuji_width = (fuji_width - 1 + shrink) >> shrink;
@@ -9329,9 +15305,15 @@ int CLASS main (int argc, const char **argv)
 	printf (_("Output size: %4d x %d\n"), iwidth, iheight);
 	printf (_("Raw colors: %d"), colors);
 	if (filters) {
+	  int fhigh = 2, fwide = 2;
+	  if ((filters ^ (filters >>  8)) & 0xff)   fhigh = 4;
+	  if ((filters ^ (filters >> 16)) & 0xffff) fhigh = 8;
+	  if (filters == 1) fhigh = fwide = 16;
+	  if (filters == 9) fhigh = fwide = 6;
 	  printf (_("\nFilter pattern: "));
-	  for (i=0; i < 16; i++)
-	    putchar (cdesc[fcol(i >> 1,i & 1)]);
+	  for (i=0; i < fhigh; i++)
+	    for (c = i && putchar('/') && 0; c < fwide; c++)
+	      putchar (cdesc[fcol(i,c)]);
 	}
 	printf (_("\nDaylight multipliers:"));
 	FORCC printf (" %f", pre_mul[c]);
@@ -9346,19 +15328,16 @@ next:
       fclose(ifp);
       continue;
     }
-    if (use_camera_matrix && cmatrix[0][0] > 0.25) {
-      memcpy (rgb_cam, cmatrix, sizeof cmatrix);
-      raw_color = 0;
-    }
-    image = (ushort (*)[4]) calloc (iheight*iwidth, sizeof *image);
-    merror (image, "main()");
     if (meta_length) {
       meta_data = (char *) malloc (meta_length);
       merror (meta_data, "main()");
     }
     if (filters || colors == 1) {
-      raw_image = (ushort *) calloc ((raw_height+7)*raw_width, 2);
+      raw_image = (ushort *) calloc ((raw_height+7), raw_width*2);
       merror (raw_image, "main()");
+    } else {
+      image = (ushort (*)[4]) calloc (iheight, iwidth*sizeof *image);
+      merror (image, "main()");
     }
     if (verbose)
       fprintf (stderr,_("Loading %s %s image from %s ...\n"),
@@ -9370,7 +15349,16 @@ next:
     if (raw_image && read_from_stdin)
       fread (raw_image, 2, raw_height*raw_width, stdin);
     else (*load_raw)();
+    if (document_mode == 3) {
+      top_margin = left_margin = fuji_width = 0;
+      height = raw_height;
+      width  = raw_width;
+    }
+    iheight = (height + shrink) >> shrink;
+    iwidth  = (width  + shrink) >> shrink;
     if (raw_image) {
+      image = (ushort (*)[4]) calloc (iheight, iwidth*sizeof *image);
+      merror (image, "main()");
       crop_masked_pixels();
       free (raw_image);
     }
@@ -9383,6 +15371,12 @@ next:
     FORC3 if (i > cblack[c]) i = cblack[c];
     FORC4 cblack[c] -= i;
     black += i;
+    i = cblack[6];
+    FORC (cblack[4] * cblack[5])
+      if (i > cblack[6+c]) i = cblack[6+c];
+    FORC (cblack[4] * cblack[5])
+      cblack[6+c] -= i;
+    black += i;
     if (user_black >= 0) black = user_black;
     FORC4 cblack[c] += black;
     if (user_sat > 0) maximum = user_sat;
@@ -9390,7 +15384,7 @@ next:
     colorcheck();
 #endif
     if (is_foveon) {
-      if (document_mode || model[0] == 'D') {
+      if (document_mode || load_raw == &CLASS foveon_dp_load_raw) {
 	for (i=0; i < height*width*4; i++)
 	  if ((short) image[0][i] < 0) image[0][i] = 0;
       } else foveon_interpolate();
@@ -9400,11 +15394,14 @@ next:
     if (filters && !document_mode) {
       if (quality == 0)
 	lin_interpolate();
-      else if (quality == 1 || colors > 3 || filters < 1000)
+      else if (quality == 1 || colors > 3)
 	vng_interpolate();
-      else if (quality == 2)
+      else if (quality == 2 && filters > 1000)
 	ppg_interpolate();
-      else ahd_interpolate();
+      else if (filters == 9)
+	xtrans_interpolate (quality*2-3);
+      else
+	ahd_interpolate();
     }
     if (mix_green)
       for (colors=3, i=0; i < height*width; i++)
@@ -9462,3 +15459,4 @@ cleanup:
   }
   return status;
 }
+#endif
diff --git a/Source/LibRawLite/internal/aahd_demosaic.cpp b/Source/LibRawLite/internal/aahd_demosaic.cpp
new file mode 100644
index 0000000..f4c3afa
--- /dev/null
+++ b/Source/LibRawLite/internal/aahd_demosaic.cpp
@@ -0,0 +1,706 @@
+/* -*- C++ -*-
+ * File: aahd_demosaic.cpp
+ * Copyright 2013 Anton Petrusevich
+ * Created: Wed May  15, 2013
+ *
+ * This code is licensed under one of three licenses as you choose:
+ *
+ * 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
+ *    (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
+ *
+ * 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
+ *    (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
+ *
+ * 3. LibRaw Software License 27032010
+ *    (See file LICENSE.LibRaw.pdf provided in LibRaw distribution archive for details).
+ *
+ */
+
+typedef ushort ushort3[3];
+typedef int int3[3];
+
+#ifndef Pnw
+#define Pnw (-1-nr_width)
+#define Pn    (-nr_width)
+#define Pne (+1-nr_width)
+#define Pe  (+1)
+#define Pse (+1+nr_width)
+#define Ps    (+nr_width)
+#define Psw (-1+nr_width)
+#define Pw  (-1)
+#endif
+
+struct AAHD {
+	int nr_height, nr_width;
+	static const int nr_margin = 4;
+	static const int Thot = 4;
+	static const int Tdead = 4;
+	static const int OverFraction = 8;
+	ushort3 *rgb_ahd[2];
+	int3 *yuv[2];
+	char *ndir, *homo[2];
+	ushort channel_maximum[3], channels_max;
+	ushort channel_minimum[3];
+	static const float yuv_coeff[3][3];
+	static float gammaLUT[0x10000];
+	float yuv_cam[3][3];
+	LibRaw &libraw;
+	enum {
+		HVSH = 1, HOR = 2, VER = 4, HORSH = HOR | HVSH, VERSH = VER | HVSH, HOT = 8
+	};
+
+	static inline float calc_dist(int c1, int c2) throw () {
+		return c1 > c2 ? (float) c1 / c2 : (float) c2 / c1;
+	}
+	int inline Y(ushort3 &rgb) throw () {
+		return yuv_cam[0][0] * rgb[0] + yuv_cam[0][1] * rgb[1] + yuv_cam[0][2] * rgb[2];
+	}
+	int inline U(ushort3 &rgb) throw () {
+		return yuv_cam[1][0] * rgb[0] + yuv_cam[1][1] * rgb[1] + yuv_cam[1][2] * rgb[2];
+	}
+	int inline V(ushort3 &rgb) throw () {
+		return yuv_cam[2][0] * rgb[0] + yuv_cam[2][1] * rgb[1] + yuv_cam[2][2] * rgb[2];
+	}
+	inline int nr_offset(int row, int col) throw () {
+		return (row * nr_width + col);
+	}
+	~AAHD();
+	AAHD(LibRaw &_libraw);
+	void make_ahd_greens();
+	void make_ahd_gline(int i);
+	void make_ahd_rb();
+	void make_ahd_rb_hv(int i);
+	void make_ahd_rb_last(int i);
+	void evaluate_ahd();
+	void combine_image();
+	void hide_hots();
+	void refine_hv_dirs();
+	void refine_hv_dirs(int i, int js);
+	void refine_ihv_dirs(int i);
+	void illustrate_dirs();
+	void illustrate_dline(int i);
+};
+
+const float AAHD::yuv_coeff[3][3] = {
+// YPbPr
+//	{
+//		0.299f,
+//		0.587f,
+//		0.114f },
+//	{
+//		-0.168736,
+//		-0.331264f,
+//		0.5f },
+//	{
+//		0.5f,
+//		-0.418688f,
+//		-0.081312f }
+//
+//	Rec. 2020
+//	Y'= 0,2627R' + 0,6780G' + 0,0593B'
+//	U = (B-Y)/1.8814 =  (-0,2627R' - 0,6780G' + 0.9407B) / 1.8814 = -0.13963R - 0.36037G + 0.5B
+//	V = (R-Y)/1.4647 = (0.7373R - 0,6780G - 0,0593B) / 1.4647 = 0.5R - 0.4629G - 0.04049B
+	{
+		+0.2627f,
+		+0.6780f,
+		+0.0593f },
+	{
+		-0.13963f,
+		-0.36037f,
+		+0.5f },
+	{
+		+0.5034f,
+		-0.4629f,
+		-0.0405f }
+
+};
+
+float AAHD::gammaLUT[0x10000] = {
+	-1.f };
+
+AAHD::AAHD(LibRaw& _libraw) :
+		libraw(_libraw) {
+	nr_height = libraw.imgdata.sizes.iheight + nr_margin * 2;
+	nr_width = libraw.imgdata.sizes.iwidth + nr_margin * 2;
+	rgb_ahd[0] = (ushort3*) calloc(nr_height * nr_width,
+			(sizeof(ushort3) * 2 + sizeof(int3) * 2 + 3));
+	rgb_ahd[1] = rgb_ahd[0] + nr_height * nr_width;
+	yuv[0] = (int3 *) (rgb_ahd[1] + nr_height * nr_width);
+	yuv[1] = yuv[0] + nr_height * nr_width;
+	ndir = (char*) (yuv[1] + nr_height * nr_width);
+	homo[0] = ndir + nr_height * nr_width;
+	homo[1] = homo[0] + nr_height * nr_width;
+	channel_maximum[0] = channel_maximum[1] = channel_maximum[2] = 0;
+	channel_minimum[0] = libraw.imgdata.image[0][0];
+	channel_minimum[1] = libraw.imgdata.image[0][1];
+	channel_minimum[2] = libraw.imgdata.image[0][2];
+	int iwidth = libraw.imgdata.sizes.iwidth;
+	for (int i = 0; i < 3; ++i)
+		for (int j = 0; j < 3; ++j) {
+			yuv_cam[i][j] = 0;
+			for (int k = 0; k < 3; ++k)
+				yuv_cam[i][j] += yuv_coeff[i][k] * libraw.imgdata.color.rgb_cam[k][j];
+		}
+	if (gammaLUT[0] < -0.1f) {
+		float r;
+		for (int i = 0; i < 0x10000; i++) {
+			r = (float) i / 0x10000;
+			gammaLUT[i] = 0x10000 * (r < 0.0181 ? 4.5f * r : 1.0993f * pow(r, 0.45f) - .0993f);
+		}
+	}
+	for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) {
+		int col_cache[48];
+		for (int j = 0; j < 48; ++j) {
+			int c = libraw.COLOR(i, j);
+			if (c == 3)
+				c = 1;
+			col_cache[j] = c;
+		}
+		int moff = nr_offset(i + nr_margin, nr_margin);
+		for (int j = 0; j < iwidth; ++j, ++moff) {
+			int c = col_cache[j % 48];
+			unsigned short d = libraw.imgdata.image[i * iwidth + j][c];
+			if (d != 0) {
+				if (channel_maximum[c] < d)
+					channel_maximum[c] = d;
+				if (channel_minimum[c] > d)
+					channel_minimum[c] = d;
+				rgb_ahd[1][moff][c] = rgb_ahd[0][moff][c] = d;
+			}
+		}
+	}
+	channels_max = MAX(MAX(channel_maximum[0], channel_maximum[1]), channel_maximum[2]);
+}
+
+void AAHD::hide_hots() {
+	int iwidth = libraw.imgdata.sizes.iwidth;
+	for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) {
+		int js = libraw.COLOR(i, 0) & 1;
+		int kc = libraw.COLOR(i, js);
+		/*
+		 * js -- начальная х-координата, которая попадает мимо известного зелёного
+		 * kc -- известный цвет в точке интерполирования
+		 */
+		int moff = nr_offset(i + nr_margin, nr_margin + js);
+		for (int j = js; j < iwidth; j += 2, moff += 2) {
+			ushort3 *rgb = &rgb_ahd[0][moff];
+			int c = rgb[0][kc];
+			if ((c > rgb[2 * Pe][kc] && c > rgb[2 * Pw][kc] && c > rgb[2 * Pn][kc]
+					&& c > rgb[2 * Ps][kc] && c > rgb[Pe][1] && c > rgb[Pw][1] && c > rgb[Pn][1]
+					&& c > rgb[Ps][1])
+					|| (c < rgb[2 * Pe][kc] && c < rgb[2 * Pw][kc] && c < rgb[2 * Pn][kc]
+							&& c < rgb[2 * Ps][kc] && c < rgb[Pe][1] && c < rgb[Pw][1]
+							&& c < rgb[Pn][1] && c < rgb[Ps][1])) {
+				int chot = c >> Thot;
+				int cdead = c << Tdead;
+				int avg = 0;
+				for (int k = -2; k < 3; k += 2)
+					for (int m = -2; m < 3; m += 2)
+						if (m == 0 && k == 0)
+							continue;
+						else
+							avg += rgb[nr_offset(k, m)][kc];
+				avg /= 8;
+				if (chot > avg || cdead < avg) {
+					ndir[moff] |= HOT;
+					int dh = ABS(rgb[2 * Pw][kc] - rgb[2 * Pe][kc]) + ABS(rgb[Pw][1] - rgb[Pe][1])
+							+ ABS(rgb[Pw][1] - rgb[Pe][1] + rgb[2 * Pe][kc] - rgb[2 * Pw][kc]);
+					int dv = ABS(rgb[2 * Pn][kc] - rgb[2 * Ps][kc]) + ABS(rgb[Pn][1] - rgb[Ps][1])
+							+ ABS(rgb[Pn][1] - rgb[Ps][1] + rgb[2 * Ps][kc] - rgb[2 * Pn][kc]);
+					int d;
+					if (dv > dh)
+						d = Pw;
+					else
+						d = Pn;
+					rgb_ahd[1][moff][kc] = rgb[0][kc] = (rgb[+2 * d][kc] + rgb[-2 * d][kc]) / 2;
+				}
+			}
+		}
+		js ^= 1;
+		moff = nr_offset(i + nr_margin, nr_margin + js);
+		for (int j = js; j < iwidth; j += 2, moff += 2) {
+			ushort3 *rgb = &rgb_ahd[0][moff];
+			int c = rgb[0][1];
+			if ((c > rgb[2 * Pe][1] && c > rgb[2 * Pw][1] && c > rgb[2 * Pn][1]
+					&& c > rgb[2 * Ps][1] && c > rgb[Pe][kc] && c > rgb[Pw][kc]
+					&& c > rgb[Pn][kc ^ 2] && c > rgb[Ps][kc ^ 2])
+					|| (c < rgb[2 * Pe][1] && c < rgb[2 * Pw][1] && c < rgb[2 * Pn][1]
+							&& c < rgb[2 * Ps][1] && c < rgb[Pe][kc] && c < rgb[Pw][kc]
+							&& c < rgb[Pn][kc ^ 2] && c < rgb[Ps][kc ^ 2])) {
+				int chot = c >> Thot;
+				int cdead = c << Tdead;
+				int avg = 0;
+				for (int k = -2; k < 3; k += 2)
+					for (int m = -2; m < 3; m += 2)
+						if (k == 0 && m == 0)
+							continue;
+						else
+							avg += rgb[nr_offset(k, m)][1];
+				avg /= 8;
+				if (chot > avg || cdead < avg) {
+					ndir[moff] |= HOT;
+					int dh = ABS(rgb[2 * Pw][1] - rgb[2 * Pe][1]) + ABS(rgb[Pw][kc] - rgb[Pe][kc])
+							+ ABS(rgb[Pw][kc] - rgb[Pe][kc] + rgb[2 * Pe][1] - rgb[2 * Pw][1]);
+					int dv = ABS(rgb[2 * Pn][1] - rgb[2 * Ps][1])
+							+ ABS(rgb[Pn][kc ^ 2] - rgb[Ps][kc ^ 2])
+							+ ABS(
+									rgb[Pn][kc ^ 2] - rgb[Ps][kc ^ 2] + rgb[2 * Ps][1]
+											- rgb[2 * Pn][1]);
+					int d;
+					if (dv > dh)
+						d = Pw;
+					else
+						d = Pn;
+					rgb_ahd[1][moff][1] = rgb[0][1] = (rgb[+2 * d][1] + rgb[-2 * d][1]) / 2;
+				}
+			}
+		}
+	}
+}
+
+const static double xyz_rgb[3][3] = {
+	{
+		0.412453,
+		0.357580,
+		0.180423 },
+	{
+		0.212671,
+		0.715160,
+		0.072169 },
+	{
+		0.019334,
+		0.119193,
+		0.950227 } };
+
+const static float d65_white[3] = {
+	0.950456f,
+	1.0f,
+	1.088754f };
+
+void AAHD::evaluate_ahd() {
+	int hvdir[4] = {
+		Pw,
+		Pe,
+		Pn,
+		Ps };
+	/*
+	 * YUV
+	 *
+	 */
+	for (int d = 0; d < 2; ++d) {
+		for (int i = 0; i < nr_width * nr_height; ++i) {
+			ushort3 rgb;
+			for (int c = 0; c < 3; ++c) {
+				rgb[c] = gammaLUT[rgb_ahd[d][i][c]];
+			}
+			yuv[d][i][0] = Y(rgb);
+			yuv[d][i][1] = U(rgb);
+			yuv[d][i][2] = V(rgb);
+		}
+	}
+	/* */
+	/*
+	 * Lab
+	 *
+	 float r, cbrt[0x10000], xyz[3], xyz_cam[3][4];
+	 for (int i = 0; i < 0x10000; i++) {
+	 r = i / 65535.0;
+	 cbrt[i] = r > 0.008856 ? pow((double) r, (double) (1 / 3.0)) : 7.787 * r + 16 / 116.0;
+	 }
+	 for (int i = 0; i < 3; i++)
+	 for (int j = 0; j < 3; j++) {
+	 xyz_cam[i][j] = 0;
+	 for (int k = 0; k < 3; k++)
+	 xyz_cam[i][j] += xyz_rgb[i][k] * libraw.imgdata.color.rgb_cam[k][j] / d65_white[i];
+	 }
+	 for (int d = 0; d < 2; ++d)
+	 for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) {
+	 int moff = nr_offset(i + nr_margin, nr_margin);
+	 for (int j = 0; j < libraw.imgdata.sizes.iwidth; j++, ++moff) {
+	 xyz[0] = xyz[1] = xyz[2] = 0.5;
+	 for (int c = 0; c < 3; c++) {
+	 xyz[0] += xyz_cam[0][c] * rgb_ahd[d][moff][c];
+	 xyz[1] += xyz_cam[1][c] * rgb_ahd[d][moff][c];
+	 xyz[2] += xyz_cam[2][c] * rgb_ahd[d][moff][c];
+	 }
+	 xyz[0] = cbrt[CLIP((int) xyz[0])];
+	 xyz[1] = cbrt[CLIP((int) xyz[1])];
+	 xyz[2] = cbrt[CLIP((int) xyz[2])];
+	 yuv[d][moff][0] = 64 * (116 * xyz[1] - 16);
+	 yuv[d][moff][1] = 64 * 500 * (xyz[0] - xyz[1]);
+	 yuv[d][moff][2] = 64 * 200 * (xyz[1] - xyz[2]);
+	 }
+	 }
+	 * Lab */
+	for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) {
+		int moff = nr_offset(i + nr_margin, nr_margin);
+		for (int j = 0; j < libraw.imgdata.sizes.iwidth; j++, ++moff) {
+			int3 *ynr;
+			float ydiff[2][4];
+			int uvdiff[2][4];
+			for (int d = 0; d < 2; ++d) {
+				ynr = &yuv[d][moff];
+				for (int k = 0; k < 4; k++) {
+					ydiff[d][k] = ABS(ynr[0][0] - ynr[hvdir[k]][0]);
+					uvdiff[d][k] = SQR(ynr[0][1] - ynr[hvdir[k]][1])
+							+ SQR(ynr[0][2] - ynr[hvdir[k]][2]);
+				}
+			}
+			float yeps = MIN(MAX(ydiff[0][0], ydiff[0][1]), MAX(ydiff[1][2], ydiff[1][3]));
+			int uveps = MIN(MAX(uvdiff[0][0], uvdiff[0][1]), MAX(uvdiff[1][2], uvdiff[1][3]));
+			for (int d = 0; d < 2; d++) {
+				ynr = &yuv[d][moff];
+				for (int k = 0; k < 4; k++)
+					if (ydiff[d][k] <= yeps && uvdiff[d][k] <= uveps) {
+						homo[d][moff + hvdir[k]]++;
+						if (k / 2 == d) {
+							// если в сонаправленном направлении интеполяции следующие точки так же гомогенны, учтём их тоже
+							for (int m = 2; m < 4; ++m) {
+								int hvd = m * hvdir[k];
+								if (ABS(ynr[0][0] - ynr[hvd][0]) < yeps
+										&& SQR(ynr[0][1] - ynr[hvd][1])
+												+ SQR(ynr[0][2] - ynr[hvd][2]) < uveps) {
+									homo[d][moff + hvd]++;
+								} else
+									break;
+							}
+						}
+					}
+			}
+		}
+	}
+	for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) {
+		int moff = nr_offset(i + nr_margin, nr_margin);
+		for (int j = 0; j < libraw.imgdata.sizes.iwidth; j++, ++moff) {
+			char hm[2];
+			for (int d = 0; d < 2; d++) {
+				hm[d] = 0;
+				char *hh = &homo[d][moff];
+				for (int hx = -1; hx < 2; hx++)
+					for (int hy = -1; hy < 2; hy++)
+						hm[d] += hh[nr_offset(hy, hx)];
+			}
+			char d = 0;
+			if (hm[0] != hm[1]) {
+				if (hm[1] > hm[0]) {
+					d = VERSH;
+				} else {
+					d = HORSH;
+				}
+			} else {
+				int3 *ynr = &yuv[1][moff];
+				int gv = SQR(2 * ynr[0][0] - ynr[Pn][0] - ynr[Ps][0]);
+				gv += SQR(2 * ynr[0][1] - ynr[Pn][1] - ynr[Ps][1])
+						+ SQR(2 * ynr[0][2] - ynr[Pn][2] - ynr[Ps][2]);
+				ynr = &yuv[1][moff + Pn];
+				gv += (SQR(2 * ynr[0][0] - ynr[Pn][0] - ynr[Ps][0])
+						+ SQR(2 * ynr[0][1] - ynr[Pn][1] - ynr[Ps][1])
+						+ SQR(2 * ynr[0][2] - ynr[Pn][2] - ynr[Ps][2])) / 2;
+				ynr = &yuv[1][moff + Ps];
+				gv += (SQR(2 * ynr[0][0] - ynr[Pn][0] - ynr[Ps][0])
+						+ SQR(2 * ynr[0][1] - ynr[Pn][1] - ynr[Ps][1])
+						+ SQR(2 * ynr[0][2] - ynr[Pn][2] - ynr[Ps][2])) / 2;
+				ynr = &yuv[0][moff];
+				int gh = SQR(2 * ynr[0][0] - ynr[Pw][0] - ynr[Pe][0]);
+				gh += SQR(2 * ynr[0][1] - ynr[Pw][1] - ynr[Pe][1])
+						+ SQR(2 * ynr[0][2] - ynr[Pw][2] - ynr[Pe][2]);
+				ynr = &yuv[0][moff + Pw];
+				gh += (SQR(2 * ynr[0][0] - ynr[Pw][0] - ynr[Pe][0])
+						+ SQR(2 * ynr[0][1] - ynr[Pw][1] - ynr[Pe][1])
+						+ SQR(2 * ynr[0][2] - ynr[Pw][2] - ynr[Pe][2])) / 2;
+				ynr = &yuv[0][moff + Pe];
+				gh += (SQR(2 * ynr[0][0] - ynr[Pw][0] - ynr[Pe][0])
+						+ SQR(2 * ynr[0][1] - ynr[Pw][1] - ynr[Pe][1])
+						+ SQR(2 * ynr[0][2] - ynr[Pw][2] - ynr[Pe][2])) / 2;
+				if (gv > gh)
+					d = HOR;
+				else
+					d = VER;
+			}
+			ndir[moff] |= d;
+		}
+	}
+}
+
+void AAHD::combine_image() {
+	for (int i = 0, i_out = 0; i < libraw.imgdata.sizes.iheight; ++i) {
+		int moff = nr_offset(i + nr_margin, nr_margin);
+		for (int j = 0; j < libraw.imgdata.sizes.iwidth; j++, ++moff, ++i_out) {
+			if (ndir[moff] & HOT) {
+				int c = libraw.COLOR(i, j);
+				rgb_ahd[1][moff][c] = rgb_ahd[0][moff][c] = libraw.imgdata.image[i_out][c];
+
+			}
+			if (ndir[moff] & VER) {
+				libraw.imgdata.image[i_out][0] = rgb_ahd[1][moff][0];
+				libraw.imgdata.image[i_out][3] = libraw.imgdata.image[i_out][1] =
+						rgb_ahd[1][moff][1];
+				libraw.imgdata.image[i_out][2] = rgb_ahd[1][moff][2];
+			} else {
+				libraw.imgdata.image[i_out][0] = rgb_ahd[0][moff][0];
+				libraw.imgdata.image[i_out][3] = libraw.imgdata.image[i_out][1] =
+						rgb_ahd[0][moff][1];
+				libraw.imgdata.image[i_out][2] = rgb_ahd[0][moff][2];
+			}
+		}
+	}
+}
+
+void AAHD::refine_hv_dirs() {
+	for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) {
+		refine_hv_dirs(i, i & 1);
+	}
+	for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) {
+		refine_hv_dirs(i, (i & 1) ^ 1);
+	}
+	for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) {
+		refine_ihv_dirs(i);
+	}
+}
+
+void AAHD::refine_ihv_dirs(int i) {
+	int iwidth = libraw.imgdata.sizes.iwidth;
+	int moff = nr_offset(i + nr_margin, nr_margin);
+	for (int j = 0; j < iwidth; j++, ++moff) {
+		if (ndir[moff] & HVSH)
+			continue;
+		int nv = (ndir[moff + Pn] & VER) + (ndir[moff + Ps] & VER) + (ndir[moff + Pw] & VER)
+				+ (ndir[moff + Pe] & VER);
+		int nh = (ndir[moff + Pn] & HOR) + (ndir[moff + Ps] & HOR) + (ndir[moff + Pw] & HOR)
+				+ (ndir[moff + Pe] & HOR);
+		nv /= VER;
+		nh /= HOR;
+		if ((ndir[moff] & VER) && nh > 3) {
+			ndir[moff] &= ~VER;
+			ndir[moff] |= HOR;
+		}
+		if ((ndir[moff] & HOR) && nv > 3) {
+			ndir[moff] &= ~HOR;
+			ndir[moff] |= VER;
+		}
+	}
+}
+
+void AAHD::refine_hv_dirs(int i, int js) {
+	int iwidth = libraw.imgdata.sizes.iwidth;
+	int moff = nr_offset(i + nr_margin, nr_margin + js);
+	for (int j = js; j < iwidth; j += 2, moff += 2) {
+		int nv = (ndir[moff + Pn] & VER) + (ndir[moff + Ps] & VER) + (ndir[moff + Pw] & VER)
+				+ (ndir[moff + Pe] & VER);
+		int nh = (ndir[moff + Pn] & HOR) + (ndir[moff + Ps] & HOR) + (ndir[moff + Pw] & HOR)
+				+ (ndir[moff + Pe] & HOR);
+		bool codir =
+				(ndir[moff] & VER) ? ((ndir[moff + Pn] & VER) || (ndir[moff + Ps] & VER)) :
+										((ndir[moff + Pw] & HOR) || (ndir[moff + Pe] & HOR));
+		nv /= VER;
+		nh /= HOR;
+		if ((ndir[moff] & VER) && (nh > 2 && !codir)) {
+			ndir[moff] &= ~VER;
+			ndir[moff] |= HOR;
+		}
+		if ((ndir[moff] & HOR) && (nv > 2 && !codir)) {
+			ndir[moff] &= ~HOR;
+			ndir[moff] |= VER;
+		}
+	}
+}
+
+/*
+ * вычисление недостающих зелёных точек.
+ */
+void AAHD::make_ahd_greens() {
+	for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) {
+		make_ahd_gline(i);
+	}
+}
+
+void AAHD::make_ahd_gline(int i) {
+	int iwidth = libraw.imgdata.sizes.iwidth;
+	int js = libraw.COLOR(i, 0) & 1;
+	int kc = libraw.COLOR(i, js);
+	/*
+	 * js -- начальная х-координата, которая попадает мимо известного зелёного
+	 * kc -- известный цвет в точке интерполирования
+	 */
+	int hvdir[2] = {
+		Pe,
+		Ps };
+	for (int d = 0; d < 2; ++d) {
+		int moff = nr_offset(i + nr_margin, nr_margin + js);
+		for (int j = js; j < iwidth; j += 2, moff += 2) {
+			ushort3 *cnr;
+			cnr = &rgb_ahd[d][moff];
+			int h1 = 2 * cnr[-hvdir[d]][1] - int(cnr[-2 * hvdir[d]][kc] + cnr[0][kc]);
+			int h2 = 2 * cnr[+hvdir[d]][1] - int(cnr[+2 * hvdir[d]][kc] + cnr[0][kc]);
+			int h0 = (h1 + h2) / 4;
+			int eg = cnr[0][kc] + h0;
+			int min = MIN(cnr[-hvdir[d]][1], cnr[+hvdir[d]][1]);
+			int max = MAX(cnr[-hvdir[d]][1], cnr[+hvdir[d]][1]);
+			min -= min / OverFraction;
+			max += max / OverFraction;
+			if (eg < min)
+				eg = min - sqrt(float(min - eg));
+			else if (eg > max)
+				eg = max + sqrt(float(eg - max));
+			if (eg > channel_maximum[1])
+				eg = channel_maximum[1];
+			else if (eg < channel_minimum[1])
+				eg = channel_minimum[1];
+			cnr[0][1] = eg;
+		}
+	}
+}
+
+/*
+ * отладочная функция
+ */
+
+void AAHD::illustrate_dirs() {
+	for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) {
+		illustrate_dline(i);
+	}
+}
+
+void AAHD::illustrate_dline(int i) {
+	int iwidth = libraw.imgdata.sizes.iwidth;
+	for (int j = 0; j < iwidth; j++) {
+		int x = j + nr_margin;
+		int y = i + nr_margin;
+		rgb_ahd[1][nr_offset(y, x)][0] = rgb_ahd[1][nr_offset(y, x)][1] =
+				rgb_ahd[1][nr_offset(y, x)][2] = rgb_ahd[0][nr_offset(y, x)][0] =
+						rgb_ahd[0][nr_offset(y, x)][1] = rgb_ahd[0][nr_offset(y, x)][2] = 0;
+		int l = ndir[nr_offset(y, x)] & HVSH;
+		l /= HVSH;
+		if (ndir[nr_offset(y, x)] & VER)
+			rgb_ahd[1][nr_offset(y, x)][0] = l * channel_maximum[0] / 4 + channel_maximum[0] / 4;
+		else
+			rgb_ahd[0][nr_offset(y, x)][2] = l * channel_maximum[2] / 4 + channel_maximum[2] / 4;
+	}
+
+}
+
+void AAHD::make_ahd_rb_hv(int i) {
+	int iwidth = libraw.imgdata.sizes.iwidth;
+	int js = libraw.COLOR(i, 0) & 1;
+	int kc = libraw.COLOR(i, js);
+	js ^= 1; // начальная координата зелёного
+	int hvdir[2] = {
+		Pe,
+		Ps };
+	// интерполяция вертикальных вертикально и горизонтальных горизонтально
+	for (int j = js; j < iwidth; j += 2) {
+		int x = j + nr_margin;
+		int y = i + nr_margin;
+		int moff = nr_offset(y, x);
+		for (int d = 0; d < 2; ++d) {
+			ushort3 *cnr;
+			cnr = &rgb_ahd[d][moff];
+			int c = kc ^ (d << 1); // цвет соответсвенного направления, для горизонтального c = kc, для вертикального c=kc^2
+			int h1 = cnr[-hvdir[d]][c] - cnr[-hvdir[d]][1];
+			int h2 = cnr[+hvdir[d]][c] - cnr[+hvdir[d]][1];
+			int h0 = (h1 + h2) / 2;
+			int eg = cnr[0][1] + h0;
+//			int min = MIN(cnr[-hvdir[d]][c], cnr[+hvdir[d]][c]);
+//			int max = MAX(cnr[-hvdir[d]][c], cnr[+hvdir[d]][c]);
+//			min -= min / OverFraction;
+//			max += max / OverFraction;
+//			if (eg < min)
+//				eg = min - sqrt(min - eg);
+//			else if (eg > max)
+//				eg = max + sqrt(eg - max);
+			if (eg > channel_maximum[c])
+				eg = channel_maximum[c];
+			else if (eg < channel_minimum[c])
+				eg = channel_minimum[c];
+			cnr[0][c] = eg;
+		}
+	}
+}
+
+void AAHD::make_ahd_rb() {
+	for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) {
+		make_ahd_rb_hv(i);
+	}
+	for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) {
+		make_ahd_rb_last(i);
+	}
+}
+
+void AAHD::make_ahd_rb_last(int i) {
+	int iwidth = libraw.imgdata.sizes.iwidth;
+	int js = libraw.COLOR(i, 0) & 1;
+	int kc = libraw.COLOR(i, js);
+	/*
+	 * js -- начальная х-координата, которая попадает мимо известного зелёного
+	 * kc -- известный цвет в точке интерполирования
+	 */
+	int dirs[2][3] = {
+		{
+			Pnw,
+			Pn,
+			Pne },
+		{
+			Pnw,
+			Pw,
+			Psw } };
+	int moff = nr_offset(i + nr_margin, nr_margin);
+	for (int j = 0; j < iwidth; j++) {
+		for (int d = 0; d < 2; ++d) {
+			ushort3 *cnr;
+			cnr = &rgb_ahd[d][moff + j];
+			int c = kc ^ 2;
+			if ((j & 1) != js) {
+				// точка зелёного, для вертикального направления нужен альтернативный строчному цвет
+				c ^= d << 1;
+			}
+			int bh, bk;
+			int bgd = 0;
+			for (int k = 0; k < 3; ++k)
+				for (int h = 0; h < 3; ++h) {
+					// градиент зелёного плюс градиент {r,b}
+					int gd = ABS(2 * cnr[0][1] - (cnr[+dirs[d][k]][1] + cnr[-dirs[d][h]][1]))
+							+ ABS(cnr[+dirs[d][k]][c] - cnr[-dirs[d][h]][c]) / 4
+							+ ABS(
+									cnr[+dirs[d][k]][c] - cnr[+dirs[d][k]][1] + cnr[-dirs[d][h]][1]
+											- cnr[-dirs[d][h]][c]) / 4;
+					if (bgd == 0 || gd < bgd) {
+						bgd = gd;
+						bh = h;
+						bk = k;
+					}
+				}
+			int h1 = cnr[+dirs[d][bk]][c] - cnr[+dirs[d][bk]][1];
+			int h2 = cnr[-dirs[d][bh]][c] - cnr[-dirs[d][bh]][1];
+			int eg = cnr[0][1] + (h1 + h2) / 2;
+//			int min = MIN(cnr[+dirs[d][bk]][c], cnr[-dirs[d][bh]][c]);
+//			int max = MAX(cnr[+dirs[d][bk]][c], cnr[-dirs[d][bh]][c]);
+//			min -= min / OverFraction;
+//			max += max / OverFraction;
+//			if (eg < min)
+//				eg = min - sqrt(min - eg);
+//			else if (eg > max)
+//				eg = max + sqrt(eg - max);
+			if (eg > channel_maximum[c])
+				eg = channel_maximum[c];
+			else if (eg < channel_minimum[c])
+				eg = channel_minimum[c];
+			cnr[0][c] = eg;
+		}
+	}
+}
+
+AAHD::~AAHD() {
+	free(rgb_ahd[0]);
+}
+
+void LibRaw::aahd_interpolate() {
+	printf("AAHD interpolating\n");
+	AAHD aahd(*this);
+	aahd.hide_hots();
+	aahd.make_ahd_greens();
+	aahd.make_ahd_rb();
+	aahd.evaluate_ahd();
+	aahd.refine_hv_dirs();
+//	aahd.illustrate_dirs();
+	aahd.combine_image();
+}
diff --git a/Source/LibRawLite/internal/dcb_demosaicing.c b/Source/LibRawLite/internal/dcb_demosaicing.c
index ed3631c..70010b7 100644
--- a/Source/LibRawLite/internal/dcb_demosaicing.c
+++ b/Source/LibRawLite/internal/dcb_demosaicing.c
@@ -500,7 +500,7 @@ void CLASS fbdd_correction()
 	for (row=2; row < height-2; row++) {
 	for (col=2, indx=row*width+col; col < width-2; col++, indx++) { 	
 
-		c =  fc(row,col);
+		c =  fcol(row,col);
 
 		image[indx][c] = ULIM(image[indx][c], 
 					MAX(image[indx-1][c], MAX(image[indx+1][c], MAX(image[indx-u][c], image[indx+u][c]))), 
diff --git a/Source/LibRawLite/internal/dcraw_common.cpp b/Source/LibRawLite/internal/dcraw_common.cpp
index 04d77a1..217133a 100644
--- a/Source/LibRawLite/internal/dcraw_common.cpp
+++ b/Source/LibRawLite/internal/dcraw_common.cpp
@@ -1,5 +1,5 @@
 /* 
-  Copyright 2008-2010 LibRaw LLC (info at libraw.org)
+  Copyright 2008-2013 LibRaw LLC (info at libraw.org)
 
 LibRaw is free software; you can redistribute it and/or modify
 it under the terms of the one of three licenses as you choose:
@@ -29,7 +29,30 @@ it under the terms of the one of three licenses as you choose:
 #include "libraw/libraw.h"
 #include "internal/defines.h"
 #include "internal/var_defines.h"
-#include "internal/libraw_bytebuffer.h"
+int CLASS fcol (int row, int col)
+{
+  static const char filter[16][16] =
+  { { 2,1,1,3,2,3,2,0,3,2,3,0,1,2,1,0 },
+    { 0,3,0,2,0,1,3,1,0,1,1,2,0,3,3,2 },
+    { 2,3,3,2,3,1,1,3,3,1,2,1,2,0,0,3 },
+    { 0,1,0,1,0,2,0,2,2,0,3,0,1,3,2,1 },
+    { 3,1,1,2,0,1,0,2,1,3,1,3,0,1,3,0 },
+    { 2,0,0,3,3,2,3,1,2,0,2,0,3,2,2,1 },
+    { 2,3,3,1,2,1,2,1,2,1,1,2,3,0,0,1 },
+    { 1,0,0,2,3,0,0,3,0,3,0,3,2,1,2,3 },
+    { 2,3,3,1,1,2,1,0,3,2,3,0,2,3,1,3 },
+    { 1,0,2,0,3,0,3,2,0,1,1,2,0,1,0,2 },
+    { 0,1,1,3,3,2,2,1,1,3,3,0,2,1,3,2 },
+    { 2,3,2,0,0,1,3,0,2,0,1,2,3,0,1,0 },
+    { 1,3,1,2,3,2,3,2,0,2,0,1,1,0,3,0 },
+    { 0,2,0,3,1,0,0,1,1,3,3,2,3,2,2,1 },
+    { 2,1,3,2,3,1,2,1,0,3,0,2,0,2,0,2 },
+    { 0,3,1,0,0,2,0,3,2,1,3,1,1,3,1,3 } };
+
+  if (filters == 1) return filter[(row+top_margin)&15][(col+left_margin)&15];
+  if (filters == 9) return xtrans[(row+6) % 6][(col+6) % 6];
+  return FC(row,col);
+}
 
 #ifndef __GLIBC__
 char *my_memmem (char *haystack, size_t haystacklen,
@@ -42,9 +65,16 @@ char *my_memmem (char *haystack, size_t haystacklen,
   return 0;
 }
 #define memmem my_memmem
+char *my_strcasestr (char *haystack, const char *needle)
+{
+  char *c;
+  for (c = haystack; *c; c++)
+    if (!strncasecmp(c, needle, strlen(needle)))
+      return c;
+  return 0;
+}
+#define strcasestr my_strcasestr
 #endif
-
-
 ushort CLASS sget2 (uchar *s)
 {
   if (order == 0x4949)		/* "II" means little-endian */
@@ -53,6 +83,46 @@ ushort CLASS sget2 (uchar *s)
     return s[0] << 8 | s[1];
 }
 
+// DNG was written by:
+#define CameraDNG	1
+#define AdobeDNG	2
+
+#ifdef LIBRAW_LIBRARY_BUILD
+
+
+static ushort saneSonyCameraInfo(uchar a, uchar b, uchar c, uchar d, uchar e, uchar f){
+	if ((a >> 4) > 9) return 0;
+	else if ((a & 0x0f) > 9) return 0;
+	else if ((b >> 4) > 9) return 0;
+	else if ((b & 0x0f) > 9) return 0;
+	else if ((c >> 4) > 9) return 0;
+	else if ((c & 0x0f) > 9) return 0;
+	else if ((d >> 4) > 9) return 0;
+	else if ((d & 0x0f) > 9) return 0;
+	else if ((e >> 4) > 9) return 0;
+	else if ((e & 0x0f) > 9) return 0;
+	else if ((f >> 4) > 9) return 0;
+	else if ((f & 0x0f) > 9) return 0;
+return 1;
+}
+
+static ushort bcd2dec(uchar data){
+	if ((data >> 4) > 9) return 0;
+	else if ((data & 0x0f) > 9) return 0;
+	else return (data >> 4) * 10 + (data & 0x0f);
+}
+
+static uchar SonySubstitution[257] = "\x00\x01\x32\xb1\x0a\x0e\x87\x28\x02\xcc\xca\xad\x1b\xdc\x08\xed\x64\x86\xf0\x4f\x8c\x6c\xb8\xcb\x69\xc4\x2c\x03\x97\xb6\x93\x7c\x14\xf3\xe2\x3e\x30\x8e\xd7\x60\x1c\xa1\xab\x37\xec\x75\xbe\x23\x15\x6a\x59\x3f\xd0\xb9\x96\xb5\x50\x27\x88\xe3\x81\x94\xe0\xc0\x04\x5c\xc6\xe8\x5f\x4b\x70\x38\x9f\x82\x80\x51\x2b\xc5\x45\x49\x9b\x21\x52\x53\x54\x85\x0b\x5d\x61\xda\x7b\x55\x26\x24\x07\x6e\x36\x5b\x47\xb7\xd9\x4a\xa2\xdf\xbf\x12\x25\xbc\x1e\x7f\x56\xea\x10\x [...]
+
+ushort CLASS sget2Rev(uchar *s)	// specific to some Canon Makernotes fields, where they have endian in reverse
+{
+	if (order == 0x4d4d)		/* "II" means little-endian, and we reverse to "MM" - big endian */
+		return s[0] | s[1] << 8;
+	else						/* "MM" means big-endian... */
+		return s[0] << 8 | s[1];
+}
+#endif
+
 ushort CLASS get2()
 {
   uchar str[2] = { 0xff,0xff };
@@ -90,18 +160,22 @@ float CLASS int_to_float (int i)
 
 double CLASS getreal (int type)
 {
-  union { char c[8]; double d; } u;
+  union { char c[8]; double d; } u,v;
   int i, rev;
 
   switch (type) {
     case 3: return (unsigned short) get2();
     case 4: return (unsigned int) get4();
-    case 5:  u.d = (unsigned int) get4();
-      return u.d / (unsigned int) get4();
+    case 5:
+      u.d = (unsigned int) get4();
+      v.d = (unsigned int)get4();
+      return u.d / (v.d ? v.d : 1);
     case 8: return (signed short) get2();
     case 9: return (signed int) get4();
-    case 10: u.d = (signed int) get4();
-      return u.d / (signed int) get4();
+    case 10:
+      u.d = (signed int) get4();
+      v.d = (signed int)get4();
+      return u.d / (v.d?v.d:1);
     case 11: return int_to_float (get4());
     case 12:
       rev = 7 * ((order == 0x4949) == (ntohs(0x1234) == 0x1234));
@@ -116,18 +190,63 @@ void CLASS read_shorts (ushort *pixel, int count)
 {
   if (fread (pixel, 2, count, ifp) < count) derror();
   if ((order == 0x4949) == (ntohs(0x1234) == 0x1234))
-      swab ((char*)pixel, (char*)pixel, count*2);
+    swab ((char*)pixel, (char*)pixel, count*2);
 }
 
-#ifdef LIBRAW_LIBRARY_BUILD
-#define RBAYER(x,y) raw_image[(x)*raw_width+(y)]
-#define RRBAYER(x,y) raw_image[((x)+top_margin)*raw_width+(y)+left_margin]
-#define CBAYER(x,y) color_image[((x)+top_margin)*raw_width+(y)+left_margin][FC((x),(y))]
-#else
-#define CBAYER(x,y) BAYER((x),(y))
-#define RBAYER(x,y) BAYER((x),(y))
-#define RRBAYER(x,y) BAYER((x),(y))
-#endif
+void CLASS cubic_spline (const int *x_, const int *y_, const int len)
+{
+  float **A, *b, *c, *d, *x, *y;
+  int i, j;
+
+  A = (float **) calloc (((2*len + 4)*sizeof **A + sizeof *A), 2*len);
+  if (!A) return;
+  A[0] = (float *) (A + 2*len);
+  for (i = 1; i < 2*len; i++)
+    A[i] = A[0] + 2*len*i;
+  y = len + (x = i + (d = i + (c = i + (b = A[0] + i*i))));
+  for (i = 0; i < len; i++) {
+    x[i] = x_[i] / 65535.0;
+    y[i] = y_[i] / 65535.0;
+  }
+  for (i = len-1; i > 0; i--) {
+    b[i] = (y[i] - y[i-1]) / (x[i] - x[i-1]);
+    d[i-1] = x[i] - x[i-1];
+  }
+  for (i = 1; i < len-1; i++) {
+    A[i][i] = 2 * (d[i-1] + d[i]);
+    if (i > 1) {
+      A[i][i-1] = d[i-1];
+      A[i-1][i] = d[i-1];
+    }
+    A[i][len-1] = 6 * (b[i+1] - b[i]);
+  }
+  for(i = 1; i < len-2; i++) {
+    float v = A[i+1][i] / A[i][i];
+    for(j = 1; j <= len-1; j++)
+      A[i+1][j] -= v * A[i][j];
+  }
+  for(i = len-2; i > 0; i--) {
+    float acc = 0;
+    for(j = i; j <= len-2; j++)
+      acc += A[i][j]*c[j];
+    c[i] = (A[i][len-1] - acc) / A[i][i];
+  }
+  for (i = 0; i < 0x10000; i++) {
+    float x_out = (float)(i / 65535.0);
+    float y_out = 0;
+    for (j = 0; j < len-1; j++) {
+      if (x[j] <= x_out && x_out <= x[j+1]) {
+	float v = x_out - x[j];
+	y_out = y[j] +
+	  ((y[j+1] - y[j]) / d[j] - (2 * d[j] * c[j] + c[j+1] * d[j])/6) * v
+	   + (c[j] * 0.5) * v*v + ((c[j+1] - c[j]) / (6 * d[j])) * v*v*v;
+      }
+    }
+    curve[i] = y_out < 0.0 ? 0 : (y_out >= 1.0 ? 65535 :
+		(ushort)(y_out * 65535.0 + 0.5));
+  }
+  free (A);
+}
 
 void CLASS canon_600_fixed_wb (int temp)
 {
@@ -147,9 +266,6 @@ void CLASS canon_600_fixed_wb (int temp)
     frac = (float) (temp - *mul[lo]) / (*mul[hi] - *mul[lo]);
   for (i=1; i < 5; i++)
     pre_mul[i-1] = 1 / (frac * mul[hi][i] + (1-frac) * mul[lo][i]);
-#ifdef LIBRAW_LIBRARY_BUILD
-  color_flags.pre_mul_state = LIBRAW_COLORSTATE_CONST;
-#endif
 }
 
 /* Return values:  0 = white  1 = near white  2 = not white */
@@ -221,9 +337,6 @@ next: ;
     st = count[0]*200 < count[1];
     for (i=0; i < 4; i++)
       pre_mul[i] = 1.0 / (total[st][i] + total[st][i+4]);
-#ifdef LIBRAW_LIBRARY_BUILD
-    color_flags.pre_mul_state = LIBRAW_COLORSTATE_CALCULATED;
-#endif
   }
 }
 
@@ -249,22 +362,21 @@ void CLASS canon_600_coeff()
   if (flash_used) t=5;
   for (raw_color = i=0; i < 3; i++)
     FORCC rgb_cam[i][c] = table[t][i*4 + c] / 1024.0;
-#ifdef LIBRAW_LIBRARY_BUILD
-  color_flags.rgb_cam_state = LIBRAW_COLORSTATE_CALCULATED;
-#endif
 }
 
 void CLASS canon_600_load_raw()
 {
   uchar  data[1120], *dp;
-  ushort pixel[896], *pix;
-  int irow, row, col, val;
-  static const short mul[4][2] =
-  { { 1141,1145 }, { 1128,1109 }, { 1178,1149 }, { 1128,1109 } };
+  ushort *pix;
+  int irow, row;
 
   for (irow=row=0; irow < height; irow++) {
-    if (fread (data, 1, raw_width*5/4, ifp) < raw_width*5/4) derror();
-    for (dp=data, pix=pixel; dp < data+1120; dp+=10, pix+=8) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
+    if (fread (data, 1, 1120, ifp) < 1120) derror();
+    pix = raw_image + row*raw_width;
+    for (dp=data; dp < data+1120;  dp+=10, pix+=8) {
       pix[0] = (dp[0] << 2) + (dp[1] >> 6    );
       pix[1] = (dp[2] << 2) + (dp[1] >> 4 & 3);
       pix[2] = (dp[3] << 2) + (dp[1] >> 2 & 3);
@@ -274,40 +386,27 @@ void CLASS canon_600_load_raw()
       pix[6] = (dp[7] << 2) + (dp[9] >> 4 & 3);
       pix[7] = (dp[8] << 2) + (dp[9] >> 6    );
     }
-#ifndef LIBRAW_LIBRARY_BUILD
-    for (col=0; col < width; col++)
-        {
-            BAYER(row,col) = pixel[col];
-        }
-#else
-    for (col=0; col < raw_width; col++)
-            RBAYER(row,col) = pixel[col];
-#endif
-
-    for (col=width; col < raw_width; col++)
-        {
-            black += pixel[col];
-        }
     if ((row+=2) > height) row = 1;
   }
-  if (raw_width > width)
-    black = black / ((raw_width - width) * height) - 4;
-#ifndef LIBRAW_LIBRARY_BUILD
+}
+
+void CLASS canon_600_correct()
+{
+  int row, col, val;
+  static const short mul[4][2] =
+  { { 1141,1145 }, { 1128,1109 }, { 1178,1149 }, { 1128,1109 } };
+
   for (row=0; row < height; row++)
+    {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     for (col=0; col < width; col++) {
       if ((val = BAYER(row,col) - black) < 0) val = 0;
       val = val * mul[row & 3][col & 1] >> 9;
       BAYER(row,col) = val;
     }
-#else
-  for (row=0; row < height; row++)
-    for (col=0; col < raw_width; col++) {
-      if ((val = RBAYER(row,col) - black) < 0) val = 0;
-      val = val * mul[row & 3][col & 1] >> 9;
-      RBAYER(row,col) = val;
     }
-
-#endif
   canon_600_fixed_wb(1311);
   canon_600_auto_wb();
   canon_600_coeff();
@@ -315,29 +414,6 @@ void CLASS canon_600_load_raw()
   black = 0;
 }
 
-void CLASS remove_zeroes()
-{
-  unsigned row, col, tot, n, r, c;
-
-#ifdef LIBRAW_LIBRARY_BUILD
-  RUN_CALLBACK(LIBRAW_PROGRESS_REMOVE_ZEROES,0,2);
-#endif
-  for (row=0; row < height; row++)
-    for (col=0; col < width; col++)
-      if (BAYER(row,col) == 0) {
-	tot = n = 0;
-	for (r = row-2; r <= row+2; r++)
-	  for (c = col-2; c <= col+2; c++)
-	    if (r < height && c < width &&
-		FC(r,c) == FC(row,col) && BAYER(r,c))
-	      tot += (n++,BAYER(r,c));
-	if (n) BAYER(row,col) = tot/n;
-      }
-#ifdef LIBRAW_LIBRARY_BUILD
-  RUN_CALLBACK(LIBRAW_PROGRESS_REMOVE_ZEROES,1,2);
-#endif
-}
-
 int CLASS canon_s2is()
 {
   unsigned row;
@@ -349,11 +425,6 @@ int CLASS canon_s2is()
   return 0;
 }
 
-/*
-   getbits(-1) initializes the buffer
-   getbits(n) where 0 <= n <= 25 returns an n-bit integer
- */
-
 unsigned CLASS getbithuff (int nbits, ushort *huff)
 {
 #ifdef LIBRAW_NOTHREADS
@@ -366,7 +437,8 @@ unsigned CLASS getbithuff (int nbits, ushort *huff)
 #endif
   unsigned c;
 
-  if (nbits == -1)
+  if (nbits > 25) return 0;
+  if (nbits < 0)
     return bitbuf = vbits = reset = 0;
   if (nbits == 0 || vbits < 0) return 0;
   while (!reset && vbits < nbits && (c = fgetc(ifp)) != EOF &&
@@ -393,7 +465,7 @@ unsigned CLASS getbithuff (int nbits, ushort *huff)
 #define gethuff(h) getbithuff(*h,h+1)
 
 /*
-   Construct a decode tree according to the specification in *source.
+   Construct a decode tree according the specification in *source.
    The first 16 bytes specify how many codes should be 1-bit, 2-bit
    3-bit, etc.  Bytes after that are the leaf values.
 
@@ -450,7 +522,6 @@ void CLASS crw_init_tables (unsigned table, ushort *huff[2])
     { 0,2,2,3,1,1,1,1,2,0,0,0,0,0,0,0,
       0x03,0x02,0x04,0x01,0x05,0x00,0x06,0x07,0x09,0x08,0x0a,0x0b,0xff  },
     { 0,0,6,3,1,1,2,0,0,0,0,0,0,0,0,0,
-
       0x06,0x05,0x07,0x04,0x08,0x03,0x09,0x02,0x00,0x0a,0x01,0x0b,0xff  },
   };
   static const uchar second_tree[3][180] = {
@@ -514,8 +585,7 @@ void CLASS crw_init_tables (unsigned table, ushort *huff[2])
 int CLASS canon_has_lowbits()
 {
   uchar test[0x4000];
-  int ret=1;
-  unsigned i;
+  int ret=1, i;
 
   fseek (ifp, 0, SEEK_SET);
   fread (test, 1, sizeof test, ifp);
@@ -527,22 +597,26 @@ int CLASS canon_has_lowbits()
   return ret;
 }
 
-void CLASS canon_compressed_load_raw()
+void CLASS canon_load_raw()
 {
   ushort *pixel, *prow, *huff[2];
-  int nblocks, lowbits, i, c, row, r, col, save, val;
-  unsigned irow, icol;
+  int nblocks, lowbits, i, c, row, r, save, val;
   int block, diffbuf[64], leaf, len, diff, carry=0, pnum=0, base[2];
 
   crw_init_tables (tiff_compress, huff);
-  pixel = (ushort *) calloc (raw_width*8, sizeof *pixel);
-  merror (pixel, "canon_compressed_load_raw()");
   lowbits = canon_has_lowbits();
   if (!lowbits) maximum = 0x3ff;
   fseek (ifp, 540 + lowbits*raw_height*raw_width/4, SEEK_SET);
   zero_after_ff = 1;
   getbits(-1);
+#ifdef LIBRAW_LIBRARY_BUILD
+  try {
+#endif
   for (row=0; row < raw_height; row+=8) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
+    pixel = raw_image + row*raw_width;
     nblocks = MIN (8, raw_height-row) * raw_width >> 6;
     for (block=0; block < nblocks; block++) {
       memset (diffbuf, 0, sizeof diffbuf);
@@ -580,52 +654,14 @@ void CLASS canon_compressed_load_raw()
       }
       fseek (ifp, save, SEEK_SET);
     }
-
+  }
 #ifdef LIBRAW_LIBRARY_BUILD
-    for (r=0; r < 8; r++) {
-        if(row+r>=raw_height) break; // Not sure that raw_height is always N*8
-        // MOVE entire row into place
-        memmove(&raw_image[(row+r)*raw_width],&pixel[r*raw_width],raw_width*sizeof(pixel[0]));
-
-        irow = row - top_margin + r;
-        if (irow >= height) continue; // if row above image area than irow is VERY positive :)
-
-        // only margins!
-        for (col=0; col < left_margin; col++) 
-            {
-                icol = col - left_margin;
-                c = FC(irow,icol);
-                if (icol >= width && col > 1 && (unsigned) (col-left_margin+2) > width+3)
-                    cblack[c] += (cblack[4+c]++,pixel[r*raw_width+col]);
-            }
-        for (col=width+left_margin; col < raw_width; col++) 
-            {
-                icol = col - left_margin;
-                c = FC(irow,icol);
-                if (icol >= width && col > 1 && (unsigned) (col-left_margin+2) > width+3)
-                    cblack[c] += (cblack[4+c]++,pixel[r*raw_width+col]);
-            }
-
-    }
-#else
-    // dcraw original code
-    for (r=0; r < 8; r++) {
-      irow = row - top_margin + r;
-      if (irow >= height) continue;
-      for (col=0; col < raw_width; col++) {
-	icol = col - left_margin;
-	c = FC(irow,icol);
-	if (icol < width)
-	  BAYER(irow,icol) = pixel[r*raw_width+col];
-	else if (col > 1 && (unsigned) (col-left_margin+2) > width+3)
-	  cblack[c] += (cblack[4+c]++,pixel[r*raw_width+col]);
-      }
-    }
-#endif
+  } catch (...) {
+    FORC(2) free (huff[c]);
+    throw;
   }
-  free (pixel);
+#endif
   FORC(2) free (huff[c]);
-  FORC4 if (cblack[4+c]) cblack[c] /= cblack[4+c];
 }
 
 int CLASS ljpeg_start (struct jhead *jh, int info_only)
@@ -642,32 +678,49 @@ int CLASS ljpeg_start (struct jhead *jh, int info_only)
     fread (data, 2, 2, ifp);
     tag =  data[0] << 8 | data[1];
     len = (data[2] << 8 | data[3]) - 2;
+
+// printf ("\n*** ljpeg_start pos= %llx tag= %x, len= %d", ftell(ifp)-4, tag, len);
+
     if (tag <= 0xff00) return 0;
     fread (data, 1, len, ifp);
     switch (tag) {
-      case 0xffc3:
+      case 0xffc3:        // start of frame; lossless, Huffman
 	jh->sraw = ((data[7] >> 4) * (data[7] & 15) - 1) & 3;
-      case 0xffc0:
+//	printf ("\n*** %x: startraw= %d", tag, jh->sraw);
+      case 0xffc0:        // start of frame; baseline jpeg
 	jh->bits = data[0];
 	jh->high = data[1] << 8 | data[2];
 	jh->wide = data[3] << 8 | data[4];
 	jh->clrs = data[5] + jh->sraw;
+
+if (!strcmp(model, "EOS 5DS"))
+{
+  jh->wide = data[1] << 8 | data[2];
+	jh->high = data[3] << 8 | data[4];
+}
+//	printf ("\n*** %x: bits= %d; high= %d; wide= %d; clrs= %d",
+//	  tag, jh->bits, jh->high, jh->wide, jh->clrs);
+
 	if (len == 9 && !dng_version) getc(ifp);
 	break;
-      case 0xffc4:
+      case 0xffc4:          // define Huffman tables
 	if (info_only) break;
 	for (dp = data; dp < data+len && (c = *dp++) < 4; )
 	  jh->free[c] = jh->huff[c] = make_decoder_ref (&dp);
 	break;
-      case 0xffda:
+      case 0xffda:          // start of scan
 	jh->psv = data[1+data[0]*2];
 	jh->bits -= data[3+data[0]*2] & 15;
 	break;
-      case 0xffdd:
+      case 0xffdd:          // define restart interval
 	jh->restart = data[0] << 8 | data[1];
     }
   } while (tag != 0xffda);
+
+// printf ("\n");
+
   if (info_only) return 1;
+  if (jh->clrs > 6 || !jh->huff[0]) return 0;
   FORC(5) if (!jh->huff[c+1]) jh->huff[c+1] = jh->huff[c];
   if (jh->sraw) {
     FORC(4)        jh->huff[2+c] = jh->huff[1];
@@ -685,51 +738,26 @@ void CLASS ljpeg_end (struct jhead *jh)
   free (jh->row);
 }
 
-// used for kodak-262 decoder
 int CLASS ljpeg_diff (ushort *huff)
 {
   int len, diff;
-
-  len = gethuff(huff);
-  if (len == 16 && (!dng_version || dng_version >= 0x1010000))
-    return -32768;
-  diff = getbits(len);
-  if ((diff & (1 << (len-1))) == 0)
-    diff -= (1 << len) - 1;
-  return diff;
-}
-
+  if(!huff)
 #ifdef LIBRAW_LIBRARY_BUILD
-int CLASS ljpeg_diff_new (LibRaw_bit_buffer& bits, LibRaw_byte_buffer* buf,ushort *huff)
-{
-  int len, diff;
-
-  len = bits._gethuff_lj(buf,*huff,huff+1);
-  if (len == 16 && (!dng_version || dng_version >= 0x1010000))
-    return -32768;
-  diff = bits._getbits_lj(buf,len);
-  if ((diff & (1 << (len-1))) == 0)
-    diff -= (1 << len) - 1;
-  return diff;
-}
+    throw LIBRAW_EXCEPTION_IO_CORRUPT;
+#else
+    longjmp (failure, 2);
+#endif
 
-int CLASS ljpeg_diff_pef (LibRaw_bit_buffer& bits, LibRaw_byte_buffer* buf,ushort *huff)
-{
-  int len, diff;
 
-  len = bits._gethuff(buf,*huff,huff+1,zero_after_ff);
+  len = gethuff(huff);
   if (len == 16 && (!dng_version || dng_version >= 0x1010000))
     return -32768;
-  diff = bits._getbits(buf,len,zero_after_ff);
+  diff = getbits(len);
   if ((diff & (1 << (len-1))) == 0)
     diff -= (1 << len) - 1;
   return diff;
 }
 
-
-#endif
-
-
 ushort * CLASS ljpeg_row (int jrow, struct jhead *jh)
 {
   int col, c, diff, pred, spred=0;
@@ -769,137 +797,36 @@ ushort * CLASS ljpeg_row (int jrow, struct jhead *jh)
   return row[2];
 }
 
-#ifdef LIBRAW_LIBRARY_BUILD
-ushort * CLASS ljpeg_row_new (int jrow, struct jhead *jh, LibRaw_bit_buffer& bits,LibRaw_byte_buffer* bytes)
-{
-  int col, c, diff, pred, spred=0;
-  ushort mark=0, *row[3];
-
-  if (jrow * jh->wide % jh->restart == 0) {
-    FORC(6) jh->vpred[c] = 1 << (jh->bits-1);
-    if (jrow) {
-        bytes->unseek2();
-        do mark = (mark << 8) + (c = bytes->get_byte());
-        while (c != EOF && mark >> 4 != 0xffd);
-    }
-    bits.reset();
-  }
-  FORC3 row[c] = jh->row + jh->wide*jh->clrs*((jrow+c) & 1);
-  for (col=0; col < jh->wide; col++)
-    FORC(jh->clrs) {
-        diff = ljpeg_diff_new (bits,bytes,jh->huff[c]);
-      if (jh->sraw && c <= jh->sraw && (col | c))
-		    pred = spred;
-      else if (col) pred = row[0][-jh->clrs];
-      else	    pred = (jh->vpred[c] += diff) - diff;
-      if (jrow && col) switch (jh->psv) {
-	case 1:	break;
-	case 2: pred = row[1][0];					break;
-	case 3: pred = row[1][-jh->clrs];				break;
-	case 4: pred = pred +   row[1][0] - row[1][-jh->clrs];		break;
-	case 5: pred = pred + ((row[1][0] - row[1][-jh->clrs]) >> 1);	break;
-	case 6: pred = row[1][0] + ((pred - row[1][-jh->clrs]) >> 1);	break;
-	case 7: pred = (pred + row[1][0]) >> 1;				break;
-	default: pred = 0;
-      }
-      if ((**row = pred + diff) >> jh->bits) derror();
-      if (c <= jh->sraw) spred = **row;
-      row[0]++; row[1]++;
-    }
-  return row[2];
-}
-
-#endif
-
 void CLASS lossless_jpeg_load_raw()
 {
-  int jwide, jrow, jcol, val, c, i, row=0, col=0;
-#ifndef LIBRAW_LIBRARY_BUILD
-  int jidx,j;
-#endif
+  int jwide, jrow, jcol, val, jidx, i, j, row=0, col=0;
   struct jhead jh;
-  int min=INT_MAX;
   ushort *rp;
-#ifdef LIBRAW_LIBRARY_BUILD
-  int save_min = 0;
-  unsigned slicesW[16],slicesWcnt=0,slices;
-  unsigned *offset;
-  unsigned t_y=0,t_x=0,t_s=0,slice=0,pixelsInSlice,pixno;
-  if (!strcasecmp(make,"KODAK"))
-      save_min = 1;
-#endif
-
-#ifdef LIBRAW_LIBRARY_BUILD
-  if (cr2_slice[0]>15)
-      throw LIBRAW_EXCEPTION_IO_EOF; // change many slices
-#else
-  if (cr2_slice[0]>15)
-  {
-      fprintf(stderr,"Too many CR2 slices: %d\n",cr2_slice[0]+1);
-      return;
-  }
-#endif
 
+// printf ("\n*** lossless_jpeg_load_raw\n");
 
   if (!ljpeg_start (&jh, 0)) return;
-  jwide = jh.wide * jh.clrs;
 
+  if(jh.wide<1 || jh.high<1 || jh.clrs<1 || jh.bits <1)
 #ifdef LIBRAW_LIBRARY_BUILD
-  if(cr2_slice[0])
-      {
-          for(i=0;i<cr2_slice[0];i++)
-              slicesW[slicesWcnt++] = cr2_slice[1];
-          slicesW[slicesWcnt++] = cr2_slice[2];
-      }
-  else
-      {
-          // not sliced
-          slicesW[slicesWcnt++] = raw_width; // safe fallback
-      }
-       
-  slices = slicesWcnt * jh.high;
-  offset = (unsigned*)calloc(slices+1,sizeof(offset[0]));
-
-  for(slice=0;slice<slices;slice++)
-      {
-          offset[slice] = (t_x + t_y * raw_width)| (t_s<<28);
-          if((offset[slice] & 0x0fffffff) >= raw_width * raw_height)
-              throw LIBRAW_EXCEPTION_IO_BADFILE; 
-          t_y++;
-          if(t_y == jh.high)
-              {
-                  t_y = 0;
-                  t_x += slicesW[t_s++];
-              }
-      }
-  offset[slices] = offset[slices-1];
-  slice = 1; // next slice
-  pixno = offset[0]; 
-  pixelsInSlice = slicesW[0];
+    throw LIBRAW_EXCEPTION_IO_CORRUPT;
+#else
+    longjmp (failure, 2);
 #endif
+  jwide = jh.wide * jh.clrs;
 
 #ifdef LIBRAW_LIBRARY_BUILD
-  LibRaw_byte_buffer *buf=NULL;
-  if(data_size)
-      buf = ifp->make_byte_buffer(data_size);
-  LibRaw_bit_buffer bits;
+  try {
 #endif
   for (jrow=0; jrow < jh.high; jrow++) {
 #ifdef LIBRAW_LIBRARY_BUILD
-      if (buf)
-          rp = ljpeg_row_new (jrow, &jh,bits,buf);
-      else
+    checkCancel();
 #endif
     rp = ljpeg_row (jrow, &jh);
-
     if (load_flags & 1)
       row = jrow & 1 ? height-1-jrow/2 : jrow/2;
     for (jcol=0; jcol < jwide; jcol++) {
-      val = *rp++;
-      if (jh.bits <= 12)
-	val = curve[val & 0xfff];
-#ifndef LIBRAW_LIBRARY_BUILD
-      // slow dcraw way to calculate row/col
+      val = curve[*rp++];
       if (cr2_slice[0]) {
 	jidx = jrow*jwide + jcol;
 	i = jidx / (cr2_slice[1]*jh.high);
@@ -909,82 +836,26 @@ void CLASS lossless_jpeg_load_raw()
 	row = jidx / cr2_slice[1+j];
 	col = jidx % cr2_slice[1+j] + i*cr2_slice[1];
       }
-#else
-      // new fast one, but for data_size defined only (i.e. new CR2 format, not 1D/1Ds)
-      if(buf) 
-          {
-              if(!(load_flags & 1))
-                  row = pixno/raw_width;
-              col = pixno % raw_width;
-              pixno++;
-              if (0 == --pixelsInSlice)
-                  {
-                      unsigned o = offset[slice++];
-                      pixno = o & 0x0fffffff;
-                      pixelsInSlice = slicesW[o>>28];
-                  }
-          }
-#endif
-#ifndef LIBRAW_LIBRARY_BUILD
-
       if (raw_width == 3984 && (col -= 2) < 0)
-              col += (row--,raw_width);
-
-      if ((unsigned) (row-top_margin) < height) {
-	c = FC(row-top_margin,col-left_margin);
-	if ((unsigned) (col-left_margin) < width) {
-	  BAYER(row-top_margin,col-left_margin) = val;
-	  if (min > val) min = val;
-	} else if (col > 1 && (unsigned) (col-left_margin+2) > width+3)
-	  cblack[c] += (cblack[4+c]++,val);
-      }
+	col += (row--,raw_width);
+      if(row>raw_height)
+#ifdef LIBRAW_LIBRARY_BUILD
+        throw LIBRAW_EXCEPTION_IO_CORRUPT;
 #else
-      if (raw_width == 3984)
-          {
-              if ( (col -= 2) < 0)
-                  col += (row--,raw_width);
-              if(row >= 0 && row < raw_height && col >= 0 && col < raw_width)
-                  RBAYER(row,col) = val;
-          }
-      else 
-          RBAYER(row,col) = val;
-
-      if ((unsigned) (row-top_margin) < height) 
-          {
-              // within image height
-              if ((unsigned) (col-left_margin) < width) 
-                  {
-                      // within image area, save min
-                      if(save_min)
-                          if (min > val) min = val;
-                  } 
-              else if (col > 1 && (unsigned) (col-left_margin+2) > width+3) 
-                  {
-                      c = FC(row-top_margin,col-left_margin);
-                      cblack[c] += (cblack[4+c]++,val);
-                  }
-          }
+        longjmp (failure, 3);
 #endif
-
-#ifndef LIBRAW_LIBRARY_BUILD
+      if ((unsigned) row < raw_height) RAW(row,col) = val;
       if (++col >= raw_width)
 	col = (row++,0);
-#else
-      if(!buf) // 1D or 1Ds case
-         if (++col >= raw_width)
-            col = (row++,0);
-#endif
     }
   }
-  ljpeg_end (&jh);
-  FORC4 if (cblack[4+c]) cblack[c] /= cblack[4+c];
-  if (!strcasecmp(make,"KODAK"))
-    black = min;
 #ifdef LIBRAW_LIBRARY_BUILD
-  if(buf)
-      delete buf;
-  free(offset);
+  } catch (...) {
+    ljpeg_end (&jh);
+    throw;
+  }
 #endif
+  ljpeg_end (&jh);
 }
 
 void CLASS canon_sraw_load_raw()
@@ -995,38 +866,73 @@ void CLASS canon_sraw_load_raw()
   int v[3]={0,0,0}, ver, hue;
   char *cp;
 
-  if (!ljpeg_start (&jh, 0)) return;
+  if (!ljpeg_start (&jh, 0) || jh.clrs < 4) return;
   jwide = (jh.wide >>= 1) * jh.clrs;
 
 #ifdef LIBRAW_LIBRARY_BUILD
-  if(!data_size)
-      throw LIBRAW_EXCEPTION_IO_BADFILE;
-  LibRaw_byte_buffer *buf = ifp->make_byte_buffer(data_size);
-  LibRaw_bit_buffer bits;
+  try {
 #endif
-
-
   for (ecol=slice=0; slice <= cr2_slice[0]; slice++) {
     scol = ecol;
     ecol += cr2_slice[1] * 2 / jh.clrs;
     if (!cr2_slice[0] || ecol > raw_width-1) ecol = raw_width & -2;
     for (row=0; row < height; row += (jh.clrs >> 1) - 1) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
       ip = (short (*)[4]) image + row*width;
       for (col=scol; col < ecol; col+=2, jcol+=jh.clrs) {
 	if ((jcol %= jwide) == 0)
-#ifdef LIBRAW_LIBRARY_BUILD
-            rp = (short*) ljpeg_row_new (jrow++, &jh,bits,buf);
-#else
-            rp = (short *) ljpeg_row (jrow++, &jh);
-#endif
+	  rp = (short *) ljpeg_row (jrow++, &jh);
 	if (col >= width) continue;
-	FORC (jh.clrs-2)
-	  ip[col + (c >> 1)*width + (c & 1)][0] = rp[jcol+c];
-	ip[col][1] = rp[jcol+jh.clrs-2] - 16384;
-	ip[col][2] = rp[jcol+jh.clrs-1] - 16384;
-      }
-    }
-  }
+#ifdef LIBRAW_LIBRARY_BUILD
+        if(imgdata.params.sraw_ycc>=2)
+          {
+            FORC (jh.clrs-2)
+              {
+                ip[col + (c >> 1)*width + (c & 1)][0] = rp[jcol+c];
+                ip[col + (c >> 1)*width + (c & 1)][1] = ip[col + (c >> 1)*width + (c & 1)][2] = 8192;
+              }
+            ip[col][1] = rp[jcol+jh.clrs-2] - 8192;
+            ip[col][2] = rp[jcol+jh.clrs-1] - 8192;
+          }
+        else if(imgdata.params.sraw_ycc)
+          {
+            FORC (jh.clrs-2)
+                ip[col + (c >> 1)*width + (c & 1)][0] = rp[jcol+c];
+            ip[col][1] = rp[jcol+jh.clrs-2] - 8192;
+            ip[col][2] = rp[jcol+jh.clrs-1] - 8192;
+          }
+        else
+#endif
+          {
+            FORC (jh.clrs-2)
+              ip[col + (c >> 1)*width + (c & 1)][0] = rp[jcol+c];
+            ip[col][1] = rp[jcol+jh.clrs-2] - 16384;
+            ip[col][2] = rp[jcol+jh.clrs-1] - 16384;
+          }
+      }
+    }
+  }
+#ifdef LIBRAW_LIBRARY_BUILD
+  } catch (...) {
+      ljpeg_end (&jh);
+      throw ;
+  }
+#endif
+
+#ifdef LIBRAW_LIBRARY_BUILD
+  if(imgdata.params.sraw_ycc>=2)
+    {
+      ljpeg_end (&jh);
+      maximum = 0x3fff;
+      return;
+    }
+#endif
+
+#ifdef LIBRAW_LIBRARY_BUILD
+  try {
+#endif
   for (cp=model2; *cp && !isdigit(*cp); cp++);
   sscanf (cp, "%d.%d.%d", v, v+1, v+2);
   ver = (v[0]*1000 + v[1])*1000 + v[2];
@@ -1036,6 +942,9 @@ void CLASS canon_sraw_load_raw()
   ip = (short (*)[4]) image;
   rp = ip[0];
   for (row=0; row < height; row++, ip+=width) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     if (row & (jh.sraw >> 1))
       for (col=0; col < width; col+=2)
 	for (c=1; c < 3; c++)
@@ -1048,91 +957,69 @@ void CLASS canon_sraw_load_raw()
 	     ip[col][c] =  ip[col-1][c];
 	else ip[col][c] = (ip[col-1][c] + ip[col+1][c] + 1) >> 1;
   }
-  for ( ; rp < ip[0]; rp+=4) {
-#if 1
-    if (unique_id < 0x80000218) {
-      rp[0] -= 512;
-      goto next;
-    } else if (unique_id == 0x80000285) {
-next: pix[0] = rp[0] + rp[2];
-      pix[2] = rp[0] + rp[1];
-      pix[1] = rp[0] + ((-778*rp[1] - (rp[2] << 11)) >> 12);
-    } else {
-      rp[1] = (rp[1] << 2) + hue;
-      rp[2] = (rp[2] << 2) + hue;
-      pix[0] = rp[0] + ((   50*rp[1] + 22929*rp[2]) >> 14);
-      pix[1] = rp[0] + ((-5640*rp[1] - 11751*rp[2]) >> 14);
-      pix[2] = rp[0] + ((29040*rp[1] -   101*rp[2]) >> 14);
-    }
-#else
-    if (unique_id < 0x80000218) {
-      pix[0] = rp[0] + rp[2] - 512;
-      pix[2] = rp[0] + rp[1] - 512;
-      pix[1] = rp[0] + ((-778*rp[1] - (rp[2] << 11)) >> 12) - 512;
-    } else {
-      rp[1] = (rp[1] << 2) + hue;
-      rp[2] = (rp[2] << 2) + hue;
-      pix[0] = rp[0] + ((   50*rp[1] + 22929*rp[2]) >> 14);
-      pix[1] = rp[0] + ((-5640*rp[1] - 11751*rp[2]) >> 14);
-      pix[2] = rp[0] + ((29040*rp[1] -   101*rp[2]) >> 14);
-    }
+#ifdef LIBRAW_LIBRARY_BUILD
+  if(!imgdata.params.sraw_ycc)
 #endif
-    FORC3 
-        rp[c] = CLIP(pix[c] * sraw_mul[c] >> 10);
-  }
+    for ( ; rp < ip[0]; rp+=4) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
+      if (unique_id == 0x80000218 ||
+          unique_id == 0x80000250 ||
+          unique_id == 0x80000261 ||
+          unique_id == 0x80000281 ||
+          unique_id == 0x80000287) {
+        rp[1] = (rp[1] << 2) + hue;
+        rp[2] = (rp[2] << 2) + hue;
+        pix[0] = rp[0] + ((   50*rp[1] + 22929*rp[2]) >> 14);
+        pix[1] = rp[0] + ((-5640*rp[1] - 11751*rp[2]) >> 14);
+        pix[2] = rp[0] + ((29040*rp[1] -   101*rp[2]) >> 14);
+      } else {
+        if (unique_id < 0x80000218) rp[0] -= 512;
+        pix[0] = rp[0] + rp[2];
+        pix[2] = rp[0] + rp[1];
+        pix[1] = rp[0] + ((-778*rp[1] - (rp[2] << 11)) >> 12);
+      }
+      FORC3 rp[c] = CLIP(pix[c] * sraw_mul[c] >> 10);
+    }
 #ifdef LIBRAW_LIBRARY_BUILD
-  delete buf;
+  } catch (...) {
+      ljpeg_end (&jh);
+      throw ;
+  }
 #endif
   ljpeg_end (&jh);
   maximum = 0x3fff;
 }
 
-void CLASS adobe_copy_pixel (int row, int col, ushort **rp)
+void CLASS adobe_copy_pixel (unsigned row, unsigned col, ushort **rp)
 {
-  unsigned r, c;
+  int c;
 
-#ifndef LIBRAW_LIBRARY_BUILD
-  r = row -= top_margin;
-  c = col -= left_margin;
   if (is_raw == 2 && shot_select) (*rp)++;
-  if (filters) {
-    if (fuji_width) {
-      r = row + fuji_width - 1 - (col >> 1);
-      c = row + ((col+1) >> 1);
-    }
-    if (r < height && c < width)
-      BAYER(r,c) = **rp < 0x1000 ? curve[**rp] : **rp;
+  if (raw_image) {
+    if (row < raw_height && col < raw_width)
+      RAW(row,col) = curve[**rp];
     *rp += is_raw;
   } else {
-    if (r < height && c < width)
+    if (row < height && col < width)
       FORC(tiff_samples)
-	image[row*width+col][c] = (*rp)[c] < 0x1000 ? curve[(*rp)[c]]:(*rp)[c];
+	image[row*width+col][c] = curve[(*rp)[c]];
     *rp += tiff_samples;
   }
-#else
-  if (is_raw == 2 && shot_select) (*rp)++;
-  if (filters) {
-      if(row < raw_height && col < raw_width)
-          RBAYER(row,col) = **rp < 0x1000 ? curve[**rp] : **rp;
-    *rp += is_raw;
-  } else {
-      if (row < raw_height && col < raw_width)
-          FORC(tiff_samples)
-              color_image[row*raw_width+col][c] = (*rp)[c]<0x1000 ? curve[(*rp)[c]]:(*rp)[c];
-      *rp += tiff_samples;
-  }
-
-#endif
   if (is_raw == 2 && shot_select) (*rp)--;
-
 }
 
-void CLASS adobe_dng_load_raw_lj()
+void CLASS lossless_dng_load_raw()
 {
   unsigned save, trow=0, tcol=0, jwide, jrow, jcol, row, col;
   struct jhead jh;
   ushort *rp;
+
   while (trow < raw_height) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     save = ftell(ifp);
     if (tile_length < INT_MAX)
       fseek (ifp, get4(), SEEK_SET);
@@ -1141,75 +1028,64 @@ void CLASS adobe_dng_load_raw_lj()
     if (filters) jwide *= jh.clrs;
     jwide /= is_raw;
 #ifdef LIBRAW_LIBRARY_BUILD
-    if(!data_size)
-        throw LIBRAW_EXCEPTION_IO_BADFILE;
-    LibRaw_byte_buffer *buf = ifp->make_byte_buffer(data_size);
-    LibRaw_bit_buffer bits;
+  try {
 #endif
     for (row=col=jrow=0; jrow < jh.high; jrow++) {
 #ifdef LIBRAW_LIBRARY_BUILD
-        rp = ljpeg_row_new (jrow, &jh,bits,buf);
-#else
-        rp = ljpeg_row (jrow, &jh);
+    checkCancel();
 #endif
+      rp = ljpeg_row (jrow, &jh);
       for (jcol=0; jcol < jwide; jcol++) {
 	adobe_copy_pixel (trow+row, tcol+col, &rp);
 	if (++col >= tile_width || col >= raw_width)
 	  row += 1 + (col = 0);
       }
     }
+#ifdef LIBRAW_LIBRARY_BUILD
+  } catch (...) {
+      ljpeg_end (&jh);
+      throw ;
+  }
+#endif
     fseek (ifp, save+4, SEEK_SET);
     if ((tcol += tile_width) >= raw_width)
       trow += tile_length + (tcol = 0);
+
     ljpeg_end (&jh);
-#ifdef LIBRAW_LIBRARY_BUILD
-    delete buf;
-#endif
   }
 }
 
-void CLASS adobe_dng_load_raw_nc()
+void CLASS packed_dng_load_raw()
 {
   ushort *pixel, *rp;
   int row, col;
 
-  pixel = (ushort *) calloc (raw_width * tiff_samples, sizeof *pixel);
-  merror (pixel, "adobe_dng_load_raw_nc()");
-
-
+  pixel = (ushort *) calloc (raw_width, tiff_samples*sizeof *pixel);
+  merror (pixel, "packed_dng_load_raw()");
 #ifdef LIBRAW_LIBRARY_BUILD
-  int dsz= raw_height*raw_width * tiff_samples * tiff_bps/8;
-  LibRaw_byte_buffer *buf = NULL;
-  if (tiff_bps != 16)
-      {
-          buf = ifp->make_byte_buffer(dsz);
-      }
-  LibRaw_bit_buffer bits;
+  try {
 #endif
-
   for (row=0; row < raw_height; row++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     if (tiff_bps == 16)
       read_shorts (pixel, raw_width * tiff_samples);
     else {
-#ifdef LIBRAW_LIBRARY_BUILD
-        bits.reset();
-        for (col=0; col < raw_width * tiff_samples; col++)
-            pixel[col] = bits._getbits(buf,tiff_bps,zero_after_ff);
-
-#else
       getbits(-1);
       for (col=0; col < raw_width * tiff_samples; col++)
 	pixel[col] = getbits(tiff_bps);
-#endif
     }
     for (rp=pixel, col=0; col < raw_width; col++)
       adobe_copy_pixel (row, col, &rp);
   }
-  free (pixel);
 #ifdef LIBRAW_LIBRARY_BUILD
-    if(buf)
-        delete buf;
+  } catch (...) {
+    free (pixel);
+    throw ;
+  }
 #endif
+  free (pixel);
 }
 
 void CLASS pentax_load_raw()
@@ -1228,44 +1104,60 @@ void CLASS pentax_load_raw()
       huff[++i] = bit[1][c] << 8 | c;
   huff[0] = 12;
   fseek (ifp, data_offset, SEEK_SET);
-#ifdef LIBRAW_LIBRARY_BUILD
-  if(!data_size)
-      throw LIBRAW_EXCEPTION_IO_BADFILE;
-  LibRaw_byte_buffer *buf = ifp->make_byte_buffer(data_size);
-  LibRaw_bit_buffer bits;
-  bits.reset();
-#else
   getbits(-1);
-#endif
   for (row=0; row < raw_height; row++)
-      {
-          for (col=0; col < raw_width; col++) {
+  {
 #ifdef LIBRAW_LIBRARY_BUILD
-              diff = ljpeg_diff_pef(bits,buf,huff);
-#else
-              diff = ljpeg_diff (huff);
+    checkCancel();
 #endif
-              if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
-              else	   hpred[col & 1] += diff;
+    for (col=0; col < raw_width; col++) {
+      diff = ljpeg_diff (huff);
+      if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
+      else	   hpred[col & 1] += diff;
+      RAW(row,col) = hpred[col & 1];
+      if (hpred[col & 1] >> tiff_bps) derror();
+    }
+  }
+}
 
-              unsigned val = hpred[col & 1];
+#ifdef LIBRAW_LIBRARY_BUILD
 
-#ifndef LIBRAW_LIBRARY_BUILD
-              if ((unsigned) (row-top_margin) < height && 
-                  (unsigned)(col-left_margin) < width)
-                  BAYER(row-top_margin,col-left_margin) = val;
-#else
-              RBAYER(row,col) = val;
-#endif
-              if (val >> tiff_bps) derror();
+void CLASS nikon_coolscan_load_raw()
+{
+  int bufsize = width*3*tiff_bps/8;
+  if(tiff_bps <= 8)
+    gamma_curve(1.0/imgdata.params.coolscan_nef_gamma,0.,1,255);
+  else
+    gamma_curve(1.0/imgdata.params.coolscan_nef_gamma,0.,1,65535);
+  fseek (ifp, data_offset, SEEK_SET);
+  unsigned char *buf = (unsigned char*)malloc(bufsize);
+  unsigned short *ubuf = (unsigned short *)buf;
+  for(int row = 0; row < raw_height; row++)
+    {
+      int red = fread (buf, 1, bufsize, ifp);
+      unsigned short (*ip)[4] = (unsigned short (*)[4]) image + row*width;
+      if(tiff_bps <= 8)
+        for(int col=0; col<width;col++)
+          {
+            ip[col][0] = curve[buf[col*3]];
+            ip[col][1] = curve[buf[col*3+1]];
+            ip[col][2] = curve[buf[col*3+2]];
+            ip[col][3]=0;
           }
-      }
-#ifdef LIBRAW_LIBRARY_BUILD
-  delete buf;
-#endif
+      else
+        for(int col=0; col<width;col++)
+          {
+            ip[col][0] = curve[ubuf[col*3]];
+            ip[col][1] = curve[ubuf[col*3+1]];
+            ip[col][2] = curve[ubuf[col*3+2]];
+            ip[col][3]=0;
+          }
+    }
+  free(buf);
 }
+#endif
 
-void CLASS nikon_compressed_load_raw()
+void CLASS nikon_load_raw()
 {
   static const uchar nikon_tree[][32] = {
     { 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0,	/* 12-bit lossy */
@@ -1300,86 +1192,71 @@ void CLASS nikon_compressed_load_raw()
     for (i=0; i < max; i++)
       curve[i] = ( curve[i-i%step]*(step-i%step) +
 		   curve[i-i%step+step]*(i%step) ) / step;
-#ifdef LIBRAW_LIBRARY_BUILD
-    color_flags.curve_state = LIBRAW_COLORSTATE_LOADED;
-#endif
     fseek (ifp, meta_offset+562, SEEK_SET);
     split = get2();
   } else if (ver0 != 0x46 && csize <= 0x4001)
-      {
     read_shorts (curve, max=csize);
-#ifdef LIBRAW_LIBRARY_BUILD
-    color_flags.curve_state = LIBRAW_COLORSTATE_LOADED;
-#endif
-      }
   while (curve[max-2] == curve[max-1]) max--;
   huff = make_decoder (nikon_tree[tree]);
   fseek (ifp, data_offset, SEEK_SET);
-#ifdef LIBRAW_LIBRARY_BUILD
-  if(!data_size)
-      throw LIBRAW_EXCEPTION_IO_BADFILE;
-  LibRaw_byte_buffer *buf = ifp->make_byte_buffer(data_size);
-  LibRaw_bit_buffer bits;
-  bits.reset();
-#else
   getbits(-1);
+#ifdef LIBRAW_LIBRARY_BUILD
+  try {
 #endif
   for (min=row=0; row < height; row++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     if (split && row == split) {
       free (huff);
       huff = make_decoder (nikon_tree[tree+1]);
       max += (min = 16) << 1;
     }
     for (col=0; col < raw_width; col++) {
-#ifdef LIBRAW_LIBRARY_BUILD
-        i = bits._gethuff(buf,*huff,huff+1,zero_after_ff);
-#else
       i = gethuff(huff);
-#endif
       len = i & 15;
       shl = i >> 4;
-#ifdef LIBRAW_LIBRARY_BUILD
-      diff = ((bits._getbits(buf,len-shl,zero_after_ff) << 1) + 1) << shl >> 1;
-#else
       diff = ((getbits(len-shl) << 1) + 1) << shl >> 1;
-#endif
       if ((diff & (1 << (len-1))) == 0)
 	diff -= (1 << len) - !shl;
       if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
       else	   hpred[col & 1] += diff;
       if ((ushort)(hpred[col & 1] + min) >= max) derror();
-#ifndef LIBRAW_LIBRARY_BUILD
-      if ((unsigned) (col-left_margin) < width)
-	BAYER(row,col-left_margin) =  curve[LIM((short)hpred[col & 1],0,0x3fff)];
-#else
-      ushort xval = hpred[col & 1];
-      xval = curve[LIM((short)xval,0,0x3fff)];
-      RBAYER(row,col) = xval;
-#endif
-
+      RAW(row,col) = curve[LIM((short)hpred[col & 1],0,0x3fff)];
     }
   }
 #ifdef LIBRAW_LIBRARY_BUILD
-  delete buf;
+  } catch (...) {
+    free (huff);
+    throw;
+  }
 #endif
   free (huff);
 }
 
-/*
-   Figure out if a NEF file is compressed.  These fancy heuristics
-   are only needed for the D100, thanks to a bug in some cameras
-   that tags all images as "compressed".
- */
-int CLASS nikon_is_compressed()
+void CLASS nikon_yuv_load_raw()
 {
-  uchar test[256];
-  int i;
+  int row, col, yuv[4], rgb[3], b, c;
+  UINT64 bitbuf=0;
 
-  fseek (ifp, data_offset, SEEK_SET);
-  fread (test, 1, 256, ifp);
-  for (i=15; i < 256; i+=16)
-    if (test[i]) return 1;
-  return 0;
+  for (row=0; row < raw_height; row++)
+  {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
+
+    for (col=0; col < raw_width; col++) {
+      if (!(b = col & 1)) {
+	bitbuf = 0;
+	FORC(6) bitbuf |= (UINT64) fgetc(ifp) << c*8;
+	FORC(4) yuv[c] = (bitbuf >> c*12 & 0xfff) - (c >> 1 << 11);
+      }
+      rgb[0] = yuv[b] + 1.370705*yuv[3];
+      rgb[1] = yuv[b] - 0.337633*yuv[2] - 0.698001*yuv[3];
+      rgb[2] = yuv[b] + 1.732446*yuv[2];
+      FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,0xfff)] / cam_mul[c];
+    }
+  }
 }
 
 /*
@@ -1426,10 +1303,10 @@ void CLASS nikon_3700()
     int bits;
     char t_make[12], t_model[15];
   } table[] = {
-    { 0x00, "PENTAX",  "Optio 33WR" },
-    { 0x03, "NIKON",   "E3200" },
-    { 0x32, "NIKON",   "E3700" },
-    { 0x33, "OLYMPUS", "C740UZ" } };
+    { 0x00, "Pentax",  "Optio 33WR" },
+    { 0x03, "Nikon",   "E3200" },
+    { 0x32, "Nikon",   "E3700" },
+    { 0x33, "Olympus", "C740UZ" } };
 
   fseek (ifp, 3072, SEEK_SET);
   fread (dp, 1, 24, ifp);
@@ -1455,39 +1332,6 @@ int CLASS minolta_z2()
     if (tail[i]) nz++;
   return nz > 20;
 }
-
-/*
-   The Fuji Super CCD is just a Bayer grid rotated 45 degrees.
- */
-void CLASS fuji_load_raw()
-{
-#ifndef LIBRAW_LIBRARY_BUILD
-  ushort *pixel;
-  int wide, row, col, r, c;
-
-  fseek (ifp, (top_margin*raw_width + left_margin) * 2, SEEK_CUR);
-  wide = fuji_width << !fuji_layout;
-  pixel = (ushort *) calloc (wide, sizeof *pixel);
-  merror (pixel, "fuji_load_raw()");
-  for (row=0; row < raw_height; row++) {
-    read_shorts (pixel, wide);
-    fseek (ifp, 2*(raw_width - wide), SEEK_CUR);
-    for (col=0; col < wide; col++) {
-      if (fuji_layout) {
-	r = fuji_width - 1 - col + (row >> 1);
-	c = col + ((row+1) >> 1);
-      } else {
-	r = fuji_width - 1 + row - (col >> 1);
-	c = row + ((col+1) >> 1);
-      }
-      BAYER(r,c) = pixel[col];
-    }
-  }
-  free (pixel);
-#else
-  read_shorts(raw_image,raw_width*raw_height);
-#endif
-}
 void CLASS ppm_thumb()
 {
   char *thumb;
@@ -1500,6 +1344,21 @@ void CLASS ppm_thumb()
   free (thumb);
 }
 
+void CLASS ppm16_thumb()
+{
+  int i;
+  char *thumb;
+  thumb_length = thumb_width*thumb_height*3;
+  thumb = (char *) calloc (thumb_length, 2);
+  merror (thumb, "ppm16_thumb()");
+  read_shorts ((ushort *) thumb, thumb_length);
+  for (i=0; i < thumb_length; i++)
+    thumb[i] = ((ushort *) thumb)[i] >> 8;
+  fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
+  fwrite (thumb, 1, thumb_length, ofp);
+  free (thumb);
+}
+
 void CLASS layer_thumb()
 {
   int i, c;
@@ -1538,10 +1397,13 @@ void CLASS rollei_thumb()
 void CLASS rollei_load_raw()
 {
   uchar pixel[10];
-  unsigned iten=0, isix, i, buffer=0, row, col, todo[16];
+  unsigned iten=0, isix, i, buffer=0, todo[16];
 
   isix = raw_width * raw_height * 5 / 8;
   while (fread (pixel, 1, 10, ifp) == 10) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     for (i=0; i < 10; i+=2) {
       todo[i]   = iten++;
       todo[i+1] = pixel[i] << 8 | pixel[i+1];
@@ -1551,36 +1413,33 @@ void CLASS rollei_load_raw()
       todo[i]   = isix++;
       todo[i+1] = buffer >> (14-i)*5;
     }
-    for (i=0; i < 16; i+=2) {
-#ifndef LIBRAW_LIBRARY_BUILD
-      row = todo[i] / raw_width - top_margin;
-      col = todo[i] % raw_width - left_margin;
-      if (row < height && col < width)
-              BAYER(row,col) = (todo[i+1] & 0x3ff);
-#else
-      RBAYER(todo[i] / raw_width,todo[i] % raw_width) = (todo[i+1] & 0x3ff);
-#endif
-    }
+    for (i=0; i < 16; i+=2)
+      raw_image[todo[i]] = (todo[i+1] & 0x3ff);
   }
   maximum = 0x3ff;
 }
 
-int CLASS bayer (unsigned row, unsigned col)
+int CLASS raw (unsigned row, unsigned col)
 {
-  return (row < height && col < width) ? BAYER(row,col) : 0;
+  return (row < raw_height && col < raw_width) ? RAW(row,col) : 0;
 }
 
 void CLASS phase_one_flat_field (int is_float, int nc)
 {
   ushort head[8];
-  unsigned wide, y, x, c, rend, cend, row, col;
+  unsigned wide, high, y, x, c, rend, cend, row, col;
   float *mrow, num, mult[4];
 
   read_shorts (head, 8);
-  wide = head[2] / head[4];
+  if (head[2] * head[3] * head[4] * head[5] == 0) return;
+  wide = head[2] / head[4] + (head[2] % head[4] != 0);
+  high = head[3] / head[5] + (head[3] % head[5] != 0);
   mrow = (float *) calloc (nc*wide, sizeof *mrow);
   merror (mrow, "phase_one_flat_field()");
-  for (y=0; y < head[3] / head[5]; y++) {
+  for (y=0; y < high; y++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     for (x=0; x < wide; x++)
       for (c=0; c < nc; c+=2) {
 	num = is_float ? getreal(11) : get2()/32768.0;
@@ -1588,19 +1447,23 @@ void CLASS phase_one_flat_field (int is_float, int nc)
 	else mrow[(c+1)*wide+x] = (num - mrow[c*wide+x]) / head[5];
       }
     if (y==0) continue;
-    rend = head[1]-top_margin + y*head[5];
-    for (row = rend-head[5]; row < height && row < rend; row++) {
+    rend = head[1] + y*head[5];
+    for (row = rend-head[5];
+	 row < raw_height && row < rend &&
+	 row < head[1]+head[3]-head[5]; row++) {
       for (x=1; x < wide; x++) {
 	for (c=0; c < nc; c+=2) {
 	  mult[c] = mrow[c*wide+x-1];
 	  mult[c+1] = (mrow[c*wide+x] - mult[c]) / head[4];
 	}
-	cend = head[0]-left_margin + x*head[4];
-	for (col = cend-head[4]; col < width && col < cend; col++) {
-	  c = nc > 2 ? FC(row,col) : 0;
+	cend = head[0] + x*head[4];
+	for (col = cend-head[4];
+	     col < raw_width &&
+	     col < cend && col < head[0]+head[2]-head[4]; col++) {
+	  c = nc > 2 ? FC(row-top_margin,col-left_margin) : 0;
 	  if (!(c & 1)) {
-	    c = BAYER(row,col) * mult[c];
-	    BAYER(row,col) = LIM(c,0,65535);
+	    c = RAW(row,col) * mult[c];
+	    RAW(row,col) = LIM(c,0,65535);
 	  }
 	  for (c=0; c < nc; c+=2)
 	    mult[c] += mult[c+1];
@@ -1614,7 +1477,7 @@ void CLASS phase_one_flat_field (int is_float, int nc)
   free (mrow);
 }
 
-void CLASS phase_one_correct()
+int CLASS phase_one_correct()
 {
   unsigned entries, tag, data, save, col, row, type;
   int len, i, j, k, cip, val[4], dev[4], sum, max;
@@ -1624,8 +1487,9 @@ void CLASS phase_one_correct()
       {-2,-2}, {-2,2}, {2,-2}, {2,2} };
   float poly[8], num, cfrac, frac, mult[2], *yval[2];
   ushort *xval[2];
+  int qmult_applied = 0, qlin_applied = 0;
 
-  if (half_size || !meta_length) return;
+  if (half_size || !meta_length) return 0;
 #ifdef DCRAW_VERBOSE
   if (verbose) fprintf (stderr,_("Phase One correction...\n"));
 #endif
@@ -1634,7 +1498,14 @@ void CLASS phase_one_correct()
   fseek (ifp, 6, SEEK_CUR);
   fseek (ifp, meta_offset+get4(), SEEK_SET);
   entries = get4();  get4();
+
+#ifdef LIBRAW_LIBRARY_BUILD
+  try {
+#endif
   while (entries--) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     tag  = get4();
     len  = get4();
     data = get4();
@@ -1656,37 +1527,42 @@ void CLASS phase_one_correct()
 	  num = num * i + poly[j];
 	curve[i] = LIM(num+i,0,65535);
       } apply:					/* apply to whole image */
-      for (row=0; row < height; row++)
-	for (col = (tag & 1)*ph1.split_col; col < width; col++)
-	  BAYER(row,col) = curve[BAYER(row,col)];
+      for (row=0; row < raw_height; row++)
+      {
+#ifdef LIBRAW_LIBRARY_BUILD
+        checkCancel();
+#endif
+	for (col = (tag & 1)*ph1.split_col; col < raw_width; col++)
+	  RAW(row,col) = curve[RAW(row,col)];
+      }
     } else if (tag == 0x400) {			/* Sensor defects */
       while ((len -= 8) >= 0) {
-	col  = get2() - left_margin;
-	row  = get2() - top_margin;
+	col  = get2();
+	row  = get2();
 	type = get2(); get2();
-	if (col >= width) continue;
-	if (type == 131)			/* Bad column */
-	  for (row=0; row < height; row++)
-	    if (FC(row,col) == 1) {
+	if (col >= raw_width) continue;
+	if (type == 131 || type == 137)		/* Bad column */
+	  for (row=0; row < raw_height; row++)
+	    if (FC(row-top_margin,col-left_margin) == 1) {
 	      for (sum=i=0; i < 4; i++)
-		sum += val[i] = bayer (row+dir[i][0], col+dir[i][1]);
+		sum += val[i] = raw (row+dir[i][0], col+dir[i][1]);
 	      for (max=i=0; i < 4; i++) {
 		dev[i] = abs((val[i] << 2) - sum);
 		if (dev[max] < dev[i]) max = i;
 	      }
-	      BAYER(row,col) = (sum - val[max])/3.0 + 0.5;
+	      RAW(row,col) = (sum - val[max])/3.0 + 0.5;
 	    } else {
 	      for (sum=0, i=8; i < 12; i++)
-		sum += bayer (row+dir[i][0], col+dir[i][1]);
-	      BAYER(row,col) = 0.5 + sum * 0.0732233 +
-		(bayer(row,col-2) + bayer(row,col+2)) * 0.3535534;
+		sum += raw (row+dir[i][0], col+dir[i][1]);
+	      RAW(row,col) = 0.5 + sum * 0.0732233 +
+		(raw(row,col-2) + raw(row,col+2)) * 0.3535534;
 	    }
 	else if (type == 129) {			/* Bad pixel */
-	  if (row >= height) continue;
-	  j = (FC(row,col) != 1) * 4;
+	  if (row >= raw_height) continue;
+	  j = (FC(row-top_margin,col-left_margin) != 1) * 4;
 	  for (sum=0, i=j; i < j+8; i++)
-	    sum += bayer (row+dir[i][0], col+dir[i][1]);
-	  BAYER(row,col) = (sum + 4) >> 3;
+	    sum += raw (row+dir[i][0], col+dir[i][1]);
+	  RAW(row,col) = (sum + 4) >> 3;
 	}
       }
     } else if (tag == 0x401) {			/* All-color flat fields */
@@ -1702,6 +1578,99 @@ void CLASS phase_one_correct()
 	mindiff = diff;
 	off_412 = ftell(ifp) - 38;
       }
+    } else if (tag == 0x41f && !qlin_applied) { /* Quadrant linearization */
+      ushort lc[2][2][16], ref[16];
+      int qr, qc;
+      for (qr = 0; qr < 2; qr++)
+	for (qc = 0; qc < 2; qc++)
+	  for (i = 0; i < 16; i++)
+	    lc[qr][qc][i] = (ushort)get4();
+      for (i = 0; i < 16; i++) {
+	int v = 0;
+	for (qr = 0; qr < 2; qr++)
+	  for (qc = 0; qc < 2; qc++)
+	    v += lc[qr][qc][i];
+	ref[i] = (v + 2) >> 2;
+      }
+      for (qr = 0; qr < 2; qr++) {
+	for (qc = 0; qc < 2; qc++) {
+	  int cx[19], cf[19];
+	  for (i = 0; i < 16; i++) {
+	    cx[1+i] = lc[qr][qc][i];
+	    cf[1+i] = ref[i];
+	  }
+	  cx[0] = cf[0] = 0;
+	  cx[17] = cf[17] = ((unsigned int)ref[15] * 65535) / lc[qr][qc][15];
+          cf[18] = cx[18] = 65535;
+	  cubic_spline(cx, cf, 19);
+
+	  for (row = (qr ? ph1.split_row : 0);
+	       row < (qr ? raw_height : ph1.split_row); row++)
+          {
+#ifdef LIBRAW_LIBRARY_BUILD
+            checkCancel();
+#endif
+	    for (col = (qc ? ph1.split_col : 0);
+		 col < (qc ? raw_width : ph1.split_col); col++)
+	      RAW(row,col) = curve[RAW(row,col)];
+          }
+	}
+      }
+      qlin_applied = 1;
+    } else if (tag == 0x41e && !qmult_applied) { /* Quadrant multipliers */
+      float qmult[2][2] = { { 1, 1 }, { 1, 1 } };
+      get4(); get4(); get4(); get4();
+      qmult[0][0] = 1.0 + getreal(11);
+      get4(); get4(); get4(); get4(); get4();
+      qmult[0][1] = 1.0 + getreal(11);
+      get4(); get4(); get4();
+      qmult[1][0] = 1.0 + getreal(11);
+      get4(); get4(); get4();
+      qmult[1][1] = 1.0 + getreal(11);
+      for (row=0; row < raw_height; row++)
+      {
+#ifdef LIBRAW_LIBRARY_BUILD
+        checkCancel();
+#endif
+	for (col=0; col < raw_width; col++) {
+	  i = qmult[row >= ph1.split_row][col >= ph1.split_col] * RAW(row,col);
+	  RAW(row,col) = LIM(i,0,65535);
+	}
+      }
+      qmult_applied = 1;
+    } else if (tag == 0x431 && !qmult_applied) { /* Quadrant combined */
+      ushort lc[2][2][7], ref[7];
+      int qr, qc;
+      for (i = 0; i < 7; i++)
+	ref[i] = (ushort)get4();
+      for (qr = 0; qr < 2; qr++)
+	for (qc = 0; qc < 2; qc++)
+	  for (i = 0; i < 7; i++)
+	    lc[qr][qc][i] = (ushort)get4();
+      for (qr = 0; qr < 2; qr++) {
+	for (qc = 0; qc < 2; qc++) {
+	  int cx[9], cf[9];
+	  for (i = 0; i < 7; i++) {
+	    cx[1+i] = ref[i];
+	    cf[1+i] = ((unsigned int)ref[i] * lc[qr][qc][i]) / 10000;
+	  }
+	  cx[0] = cf[0] = 0;
+	  cx[8] = cf[8] = 65535;
+	  cubic_spline(cx, cf, 9);
+	  for (row = (qr ? ph1.split_row : 0);
+	       row < (qr ? raw_height : ph1.split_row); row++)
+          {
+#ifdef LIBRAW_LIBRARY_BUILD
+            checkCancel();
+#endif
+	    for (col = (qc ? ph1.split_col : 0);
+		 col < (qc ? raw_width : ph1.split_col); col++)
+	      RAW(row,col) = curve[RAW(row,col)];
+          }
+        }
+      }
+      qmult_applied = 1;
+      qlin_applied = 1;
     }
     fseek (ifp, save, SEEK_SET);
   }
@@ -1720,11 +1689,15 @@ void CLASS phase_one_correct()
     for (i=0; i < 2; i++)
       for (j=0; j < head[i+1]*head[i+3]; j++)
 	xval[i][j] = get2();
-    for (row=0; row < height; row++)
-      for (col=0; col < width; col++) {
+    for (row=0; row < raw_height; row++)
+    {
+#ifdef LIBRAW_LIBRARY_BUILD
+      checkCancel();
+#endif
+      for (col=0; col < raw_width; col++) {
 	cfrac = (float) col * head[3] / raw_width;
 	cfrac -= cip = cfrac;
-	num = BAYER(row,col) * 0.5;
+	num = RAW(row,col) * 0.5;
 	for (i=cip; i < cip+2; i++) {
 	  for (k=j=0; j < head[1]; j++)
 	    if (num < xval[0][k = head[1]*i+j]) break;
@@ -1732,67 +1705,65 @@ void CLASS phase_one_correct()
 		(xval[0][k] - num) / (xval[0][k] - xval[0][k-1]);
 	  mult[i-cip] = yval[0][k-1] * frac + yval[0][k] * (1-frac);
 	}
-	i = ((mult[0] * (1-cfrac) + mult[1] * cfrac)
-		* (row + top_margin) + num) * 2;
-	BAYER(row,col) = LIM(i,0,65535);
+	i = ((mult[0] * (1-cfrac) + mult[1] * cfrac) * row + num) * 2;
+	RAW(row,col) = LIM(i,0,65535);
       }
+    }
     free (yval[0]);
   }
+#ifdef LIBRAW_LIBRARY_BUILD
+  }
+  catch (...)
+  {
+	  return LIBRAW_CANCELLED_BY_CALLBACK;
+  }
+#endif
 }
 
 void CLASS phase_one_load_raw()
 {
-  int row, col, a, b;
-  ushort *pixel, akey, bkey, mask;
+  int a, b, i;
+  ushort akey, bkey, t_mask;
 
   fseek (ifp, ph1.key_off, SEEK_SET);
   akey = get2();
   bkey = get2();
-  mask = ph1.format == 1 ? 0x5555:0x1354;
-#ifndef LIBRAW_LIBRARY_BUILD
-  fseek (ifp, data_offset + top_margin*raw_width*2, SEEK_SET);
-  pixel = (ushort *) calloc (raw_width, sizeof *pixel);
-  merror (pixel, "phase_one_load_raw()");
-  for (row=0; row < height; row++) {
-    read_shorts (pixel, raw_width);
-    if (ph1.format)
-      for (col=0; col < raw_width; col+=2) {
-	a = pixel[col+0] ^ akey;
-	b = pixel[col+1] ^ bkey;
-	pixel[col+0] = (a & mask) | (b & ~mask);
-	pixel[col+1] = (b & mask) | (a & ~mask);
-      }
-    for (col=0; col < width; col++)
-      BAYER(row,col) = pixel[col+left_margin];
-  }
-  free (pixel);
-  phase_one_correct();
-#else
-  fseek (ifp, data_offset, SEEK_SET);
-  pixel = (ushort *) calloc (raw_width, sizeof *pixel);
-  merror (pixel, "phase_one_load_raw()");
-  for (row=0; row < raw_height; row++) {
-    read_shorts (pixel, raw_width);
-    if (ph1.format)
-        for (col=0; col < raw_width; col+=2) {
-            a = pixel[col+0] ^ akey;
-            b = pixel[col+1] ^ bkey;
-            pixel[col+0] = (a & mask) | (b & ~mask);
-            pixel[col+1] = (b & mask) | (a & ~mask);
+  t_mask = ph1.format == 1 ? 0x5555:0x1354;
+#ifdef LIBRAW_LIBRARY_BUILD
+  if (ph1.black_col || ph1.black_row )
+    {
+      imgdata.rawdata.ph1_cblack = (short(*)[2])calloc(raw_height*2,sizeof(ushort));
+      merror(imgdata.rawdata.ph1_cblack,"phase_one_load_raw()");
+      imgdata.rawdata.ph1_rblack = (short(*)[2])calloc(raw_width*2,sizeof(ushort));
+      merror(imgdata.rawdata.ph1_rblack,"phase_one_load_raw()");
+      if (ph1.black_col)
+        {
+          fseek (ifp, ph1.black_col, SEEK_SET);
+          read_shorts ((ushort *)imgdata.rawdata.ph1_cblack[0], raw_height*2);
         }
-    memmove(&raw_image[row*raw_width],pixel,raw_width*sizeof(pixel[0]));
-  }
-  free (pixel);
-  // use correct on postprocessing!
-  imgdata.rawdata.use_ph1_correct=1;
+      if (ph1.black_row)
+        {
+          fseek (ifp, ph1.black_row, SEEK_SET);
+          read_shorts ((ushort *) imgdata.rawdata.ph1_rblack[0], raw_width*2);
+        }
+      }
 #endif
+  fseek (ifp, data_offset, SEEK_SET);
+  read_shorts (raw_image, raw_width*raw_height);
+  if (ph1.format)
+    for (i=0; i < raw_width*raw_height; i+=2) {
+      a = raw_image[i+0] ^ akey;
+      b = raw_image[i+1] ^ bkey;
+      raw_image[i+0] = (a & t_mask) | (b & ~t_mask);
+      raw_image[i+1] = (b & t_mask) | (a & ~t_mask);
+    }
 }
 
 unsigned CLASS ph1_bithuff (int nbits, ushort *huff)
 {
 #ifndef LIBRAW_NOTHREADS
 #define bitbuf tls->ph1_bits.bitbuf
-#define vbits  tls->ph1_bits.vbits    
+#define vbits  tls->ph1_bits.vbits
 #else
   static UINT64 bitbuf=0;
   static int vbits=0;
@@ -1826,31 +1797,49 @@ void CLASS phase_one_load_raw_c()
   static const int length[] = { 8,7,6,9,11,10,5,12,14,13 };
   int *offset, len[2], pred[2], row, col, i, j;
   ushort *pixel;
-  short (*t_black)[2];
+  short (*c_black)[2], (*r_black)[2];
+#ifdef LIBRAW_LIBRARY_BUILD
+  if(ph1.format == 6)
+    throw LIBRAW_EXCEPTION_IO_CORRUPT;
+#endif
 
-  pixel = (ushort *) calloc (raw_width + raw_height*4, 2);
+  pixel = (ushort *) calloc (raw_width*3 + raw_height*4, 2);
   merror (pixel, "phase_one_load_raw_c()");
   offset = (int *) (pixel + raw_width);
   fseek (ifp, strip_offset, SEEK_SET);
   for (row=0; row < raw_height; row++)
     offset[row] = get4();
-  t_black = (short (*)[2]) offset + raw_height;
-  fseek (ifp, ph1.black_off, SEEK_SET);
-  if (ph1.black_off)
-      {
-          read_shorts ((ushort *) t_black[0], raw_height*2);
+  c_black = (short (*)[2]) (offset + raw_height);
+  fseek (ifp, ph1.black_col, SEEK_SET);
+  if (ph1.black_col)
+      read_shorts ((ushort *) c_black[0], raw_height*2);
+  r_black = c_black + raw_height;
+  fseek (ifp, ph1.black_row, SEEK_SET);
+  if (ph1.black_row)
+      read_shorts ((ushort *) r_black[0], raw_width*2);
+
 #ifdef LIBRAW_LIBRARY_BUILD
-          imgdata.rawdata.ph1_black = (short (*)[2])calloc(raw_height*2,sizeof(short));
-          merror (imgdata.rawdata.ph1_black, "phase_one_load_raw_c()");
-          memmove(imgdata.rawdata.ph1_black,(short *) t_black[0],raw_height*2*sizeof(short));
+  // Copy data to internal copy (ever if not read)
+  if (ph1.black_col || ph1.black_row )
+    {
+      imgdata.rawdata.ph1_cblack = (short(*)[2])calloc(raw_height*2,sizeof(ushort));
+      merror(imgdata.rawdata.ph1_cblack,"phase_one_load_raw_c()");
+      memmove(imgdata.rawdata.ph1_cblack,(ushort*)c_black[0],raw_height*2*sizeof(ushort));
+      imgdata.rawdata.ph1_rblack = (short(*)[2])calloc(raw_width*2,sizeof(ushort));
+      merror(imgdata.rawdata.ph1_rblack,"phase_one_load_raw_c()");
+      memmove(imgdata.rawdata.ph1_rblack,(ushort*)r_black[0],raw_width*2*sizeof(ushort));
+    }
 #endif
-      }
+
   for (i=0; i < 256; i++)
     curve[i] = i*i / 3.969 + 0.5;
 #ifdef LIBRAW_LIBRARY_BUILD
-  color_flags.curve_state = LIBRAW_COLORSTATE_CALCULATED;
+  try {
 #endif
   for (row=0; row < raw_height; row++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     fseek (ifp, data_offset + offset[row], SEEK_SET);
     ph1_bits(-1);
     pred[0] = pred[1] = 0;
@@ -1870,192 +1859,248 @@ void CLASS phase_one_load_raw_c()
       if (ph1.format == 5 && pixel[col] < 256)
 	pixel[col] = curve[pixel[col]];
     }
+    for (col=0; col < raw_width; col++) {
 #ifndef LIBRAW_LIBRARY_BUILD
-    if ((unsigned) (row-top_margin) < height)
-      for (col=0; col < width; col++) {
-	i = (pixel[col+left_margin] << 2)
-		- ph1.t_black + t_black[row][col >= ph1.split_col];
-	if (i > 0) BAYER(row-top_margin,col) = i;
-      }
+      i = (pixel[col] << 2) - ph1.t_black
+	+ c_black[row][col >= ph1.split_col]
+	+ r_black[col][row >= ph1.split_row];
+      if (i > 0) RAW(row,col) = i;
 #else
-    for (col=0; col < raw_width; col++) 
-        {
-            i = (pixel[col] << 2);
-            RBAYER(row,col) = i;
-        }
+      RAW(row,col) = pixel[col] << 2;
 #endif
+    }
+  }
+#ifdef LIBRAW_LIBRARY_BUILD
+  } catch(...) {
+    free (pixel);
+    throw;
   }
+#endif
   free (pixel);
-#ifndef LIBRAW_LIBRARY_BUILD
-  phase_one_correct();
   maximum = 0xfffc - ph1.t_black;
-#else
-  maximum = 0xfffc;
-  black = ph1.t_black;
-#endif
 }
 
 void CLASS hasselblad_load_raw()
 {
   struct jhead jh;
-  int row, col, pred[2], len[2], diff, c;
+  int shot, row, col, *back[5], len[2], diff[12], pred, sh, f, s, c;
+  unsigned upix, urow, ucol;
+  ushort *ip;
 
   if (!ljpeg_start (&jh, 0)) return;
   order = 0x4949;
   ph1_bits(-1);
-#ifndef LIBRAW_LIBRARY_BUILD
-  for (row=-top_margin; row < height; row++) {
-    pred[0] = pred[1] = 0x8000 + load_flags;
-    for (col=-left_margin; col < raw_width-left_margin; col+=2) {
-      FORC(2) len[c] = ph1_huff(jh.huff[0]);
-      FORC(2) {
-	diff = ph1_bits(len[c]);
-	if ((diff & (1 << (len[c]-1))) == 0)
-	  diff -= (1 << len[c]) - 1;
-	if (diff == 65535) diff = -32768;
-	pred[c] += diff;
-	if (row >= 0 && (unsigned)(col+c) < width)
-	  BAYER(row,col+c) = pred[c];
-      }
-    }
-  }
-#else
+#ifdef LIBRAW_LIBRARY_BUILD
+  try {
+#endif
+  back[4] = (int *) calloc (raw_width, 3*sizeof **back);
+  merror (back[4], "hasselblad_load_raw()");
+  FORC3 back[c] = back[4] + c*raw_width;
+  cblack[6] >>= sh = tiff_samples > 1;
+  shot = LIM(shot_select, 1, tiff_samples) - 1;
   for (row=0; row < raw_height; row++) {
-    pred[0] = pred[1] = 0x8000 + load_flags;
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
+    FORC4 back[(c+3) & 3] = back[c];
     for (col=0; col < raw_width; col+=2) {
-      FORC(2) len[c] = ph1_huff(jh.huff[0]);
-      FORC(2) {
-	diff = ph1_bits(len[c]);
-	if ((diff & (1 << (len[c]-1))) == 0)
-	  diff -= (1 << len[c]) - 1;
-	if (diff == 65535) diff = -32768;
-	pred[c] += diff;
-        RBAYER(row,col+c) = pred[c];
+      for (s=0; s < tiff_samples*2; s+=2) {
+	FORC(2) len[c] = ph1_huff(jh.huff[0]);
+	FORC(2) {
+	  diff[s+c] = ph1_bits(len[c]);
+	  if ((diff[s+c] & (1 << (len[c]-1))) == 0)
+	    diff[s+c] -= (1 << len[c]) - 1;
+	  if (diff[s+c] == 65535) diff[s+c] = -32768;
+	}
+      }
+      for (s=col; s < col+2; s++) {
+	pred = 0x8000 + load_flags;
+	if (col) pred = back[2][s-2];
+	if (col && row > 1) switch (jh.psv) {
+	  case 11: pred += back[0][s]/2 - back[0][s-2]/2;  break;
+	}
+	f = (row & 1)*3 ^ ((col+s) & 1);
+	FORC (tiff_samples) {
+	  pred += diff[(s & 1)*tiff_samples+c];
+	  upix = pred >> sh & 0xffff;
+	  if (raw_image && c == shot)
+	    RAW(row,s) = upix;
+	  if (image) {
+	    urow = row-top_margin  + (c & 1);
+	    ucol = col-left_margin - ((c >> 1) & 1);
+	    ip = &image[urow*width+ucol][f];
+	    if (urow < height && ucol < width)
+	      *ip = c < 4 ? upix : (*ip + upix) >> 1;
+	  }
+	}
+	back[2][s] = pred;
       }
     }
   }
-
+#ifdef LIBRAW_LIBRARY_BUILD
+  } catch (...){
+    free (back[4]);
+    ljpeg_end (&jh);
+    throw;
+  }
 #endif
+  free (back[4]);
   ljpeg_end (&jh);
-  maximum = 0xffff;
+  if (image) mix_green = 1;
 }
 
+
 void CLASS leaf_hdr_load_raw()
 {
-  ushort *pixel;
+  ushort *pixel=0;
   unsigned tile=0, r, c, row, col;
 
-  pixel = (ushort *) calloc (raw_width, sizeof *pixel);
-  merror (pixel, "leaf_hdr_load_raw()");
+  if (!filters) {
+    pixel = (ushort *) calloc (raw_width, sizeof *pixel);
+    merror (pixel, "leaf_hdr_load_raw()");
+  }
+#ifdef LIBRAW_LIBRARY_BUILD
+  try {
+#endif
   FORC(tiff_samples)
     for (r=0; r < raw_height; r++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
       if (r % tile_length == 0) {
 	fseek (ifp, data_offset + 4*tile++, SEEK_SET);
-	fseek (ifp, get4() + 2*left_margin, SEEK_SET);
+	fseek (ifp, get4(), SEEK_SET);
       }
       if (filters && c != shot_select) continue;
+      if (filters) pixel = raw_image + r*raw_width;
       read_shorts (pixel, raw_width);
-#ifndef LIBRAW_LIBRARY_BUILD
-      if ((row = r - top_margin) >= height) continue;
-      for (col=0; col < width; col++)
-	if (filters)  BAYER(row,col) = pixel[col];
-	else image[row*width+col][c] = pixel[col];
-#else
-      if(filters)
-          memmove(&raw_image[r*raw_width],pixel,raw_width*sizeof(pixel[0]));
-      else
-          for (col=0; col < raw_width; col++)
-              color_image[r*raw_width+col][c] = pixel[col];
-#endif
+      if (!filters && (row = r - top_margin) < height)
+	for (col=0; col < width; col++)
+	  image[row*width+col][c] = pixel[col+left_margin];
     }
-  free (pixel);
+#ifdef LIBRAW_LIBRARY_BUILD
+  } catch (...) {
+    if(!filters) free(pixel);
+    throw;
+  }
+#endif
   if (!filters) {
     maximum = 0xffff;
     raw_color = 1;
+    free (pixel);
+  }
+}
+
+void CLASS unpacked_load_raw()
+{
+  int row, col, bits=0;
+
+  while (1 << ++bits < maximum);
+  read_shorts (raw_image, raw_width*raw_height);
+  for (row=0; row < raw_height; row++)
+  {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
+    for (col=0; col < raw_width; col++)
+      if ((RAW(row,col) >>= load_flags) >> bits
+	&& (unsigned) (row-top_margin) < height
+	&& (unsigned) (col-left_margin) < width) derror();
   }
 }
 
+
 void CLASS sinar_4shot_load_raw()
 {
   ushort *pixel;
   unsigned shot, row, col, r, c;
 
-  if ((shot = shot_select) || half_size) {
-    if (shot) shot--;
-    if (shot > 3) shot = 3;
+  if (raw_image) {
+    shot = LIM (shot_select, 1, 4) - 1;
     fseek (ifp, data_offset + shot*4, SEEK_SET);
     fseek (ifp, get4(), SEEK_SET);
     unpacked_load_raw();
     return;
   }
-  free (image);
-  image = (ushort (*)[4])
-	calloc ((iheight=height)*(iwidth=width), sizeof *image);
-  merror (image, "sinar_4shot_load_raw()");
   pixel = (ushort *) calloc (raw_width, sizeof *pixel);
   merror (pixel, "sinar_4shot_load_raw()");
+#ifdef LIBRAW_LIBRARY_BUILD
+  try {
+#endif
   for (shot=0; shot < 4; shot++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     fseek (ifp, data_offset + shot*4, SEEK_SET);
     fseek (ifp, get4(), SEEK_SET);
-#ifndef LIBRAW_LIBRARY_BUILD
     for (row=0; row < raw_height; row++) {
       read_shorts (pixel, raw_width);
       if ((r = row-top_margin - (shot >> 1 & 1)) >= height) continue;
       for (col=0; col < raw_width; col++) {
 	if ((c = col-left_margin - (shot & 1)) >= width) continue;
-	 image[r*width+c][FC(row,col)] = pixel[col];
-      }
-    }
-#else
-    for (row=0; row < raw_height; row++) {
-      read_shorts (pixel, raw_width);
-      if ((r = row - (shot >> 1 & 1)) >= raw_height) continue;
-      for (col=0; col < raw_width; col++) {
-	if ((c = col- (shot & 1)) >= raw_width) continue;
-         color_image[r*width+c][FC(row,col)] = pixel[col];
+	image[r*width+c][(row & 1)*3 ^ (~col & 1)] = pixel[col];
       }
     }
-#endif
   }
+#ifdef LIBRAW_LIBRARY_BUILD
+  } catch (...) {
+    free(pixel);
+    throw;
+  }
+#endif
   free (pixel);
-  shrink = filters = 0;
+  mix_green = 1;
 }
 
 void CLASS imacon_full_load_raw()
 {
   int row, col;
 
-#ifndef LIBRAW_LIBRARY_BUILD
+  if (!image) return;
+
+#ifdef LIBRAW_LIBRARY_BUILD
+  unsigned short *buf = (unsigned short *)malloc(width*3*sizeof(unsigned short));
+  merror(buf,"imacon_full_load_raw");
+#endif
+
   for (row=0; row < height; row++)
+  {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+    read_shorts(buf,width*3);
+    unsigned short (*rowp)[4] = &image[row*width];
     for (col=0; col < width; col++)
-        {
-            read_shorts (image[row*width+col], 3);
-        }
+      {
+        rowp[col][0]=buf[col*3];
+        rowp[col][1]=buf[col*3+1];
+        rowp[col][2]=buf[col*3+2];
+        rowp[col][3]=0;
+      }
 #else
-  for (row=0; row < height; row++)
     for (col=0; col < width; col++)
-        {
-            read_shorts (color_image[(row+top_margin)*raw_width+col+left_margin], 3);
-        }
+      read_shorts (image[row*width+col], 3);
+#endif
+  }
+#ifdef LIBRAW_LIBRARY_BUILD
+  free(buf);
 #endif
 }
 
 void CLASS packed_load_raw()
 {
-  int vbits=0, bwide, pwide, rbits, bite, half, irow, row, col, val, i;
-  int zero=0;
+  int vbits=0, bwide, rbits, bite, half, irow, row, col, val, i;
   UINT64 bitbuf=0;
 
-  if (raw_width * 8 >= width * tiff_bps)	/* Is raw_width in bytes? */
-       pwide = (bwide = raw_width) * 8 / tiff_bps;
-  else bwide = (pwide = raw_width) * tiff_bps / 8;
-  rbits = bwide * 8 - pwide * tiff_bps;
+  bwide = raw_width * tiff_bps / 8;
+  bwide += bwide & load_flags >> 7;
+  rbits = bwide * 8 - raw_width * tiff_bps;
   if (load_flags & 1) bwide = bwide * 16 / 15;
-  fseek (ifp, top_margin*bwide, SEEK_CUR);
   bite = 8 + (load_flags & 24);
-  half = (height+1) >> 1;
-  for (irow=0; irow < height; irow++) 
-  {
+  half = (raw_height+1) >> 1;
+  for (irow=0; irow < raw_height; irow++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     row = irow;
     if (load_flags & 2 &&
 	(row = irow % half * 2 + irow / half) == 1 &&
@@ -2067,110 +2112,148 @@ void CLASS packed_load_raw()
 	fseek (ifp, ftell(ifp) >> 3 << 2, SEEK_SET);
       }
     }
-    for (col=0; col < pwide; col++) {
+    for (col=0; col < raw_width; col++) {
       for (vbits -= tiff_bps; vbits < 0; vbits += bite) {
 	bitbuf <<= bite;
 	for (i=0; i < bite; i+=8)
 	  bitbuf |= (unsigned) (fgetc(ifp) << i);
       }
       val = bitbuf << (64-tiff_bps-vbits) >> (64-tiff_bps);
-      i = (col ^ (load_flags >> 6)) - left_margin;
-#ifdef LIBRAW_LIBRARY_BUILD
-      RBAYER(row+top_margin,i+left_margin) = val;
-      if (((unsigned)i>=width) && (load_flags & 32) ) {
-	black += val;
-	zero += !val;
-      }
-#else
-      if ((unsigned) i < width)
-	BAYER(row,i+left_margin) = val;
-      else if (load_flags & 32) {
-	black += val;
-	zero += !val;
-      }
-#endif
-      if (load_flags & 1 && (col % 10) == 9 &&
-	fgetc(ifp) && col < width+left_margin) derror();
+      RAW(row,col ^ (load_flags >> 6 & 1)) = val;
+      if (load_flags & 1 && (col % 10) == 9 && fgetc(ifp) &&
+	row < height+top_margin && col < width+left_margin) derror();
     }
     vbits -= rbits;
   }
-  if (load_flags & 32 && pwide > width)
-    black /= (pwide - width) * height;
-  if (zero*4 > (pwide - width) * height)
-    black = 0;
 }
 
-void CLASS unpacked_load_raw()
+void CLASS nokia_load_raw()
 {
-  ushort *pixel;
-  int row, col, bits=0;
+  uchar  *data,  *dp;
+  int rev, dwide, row, col, c;
+  double sum[]={0,0};
 
-  while (1 << ++bits < maximum);
-#ifndef LIBRAW_LIBRARY_BUILD
-  fseek (ifp, (top_margin*raw_width + left_margin) * 2, SEEK_CUR);
-  pixel = (ushort *) calloc (width, sizeof *pixel);
-  merror (pixel, "unpacked_load_raw()");
-  for (row=0; row < height; row++) {
-    read_shorts (pixel, width);
-    fseek (ifp, 2*(raw_width - width), SEEK_CUR);
-    for (col=0; col < width; col++)
-      if ((BAYER2(row,col) = pixel[col] >> load_flags) >> bits) derror();
-  }
-  free (pixel);
-#else
-  // fseek (ifp, (top_margin*raw_width + left_margin) * 2, SEEK_CUR);
-  pixel = (ushort *) calloc (raw_width, sizeof *pixel);
-  merror (pixel, "unpacked_load_raw()");
+  rev = 3 * (order == 0x4949);
+  dwide = (raw_width * 5 + 1) / 4;
+  data = (uchar *) malloc (dwide*2);
+  merror (data, "nokia_load_raw()");
+#ifdef LIBRAW_LIBRARY_BUILD
+  try {
+#endif
   for (row=0; row < raw_height; row++) {
-    read_shorts (pixel, raw_width);
-    for (col=0; col < raw_width; col++)
-        {
-            RBAYER(row,col) = pixel[col]>>load_flags;
-            if( ((unsigned)(row-top_margin) < height)
-                && ((unsigned)(col-left_margin)<width ))
-                if(RBAYER(row,col)>>bits)
-                    derror();
-        }
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
+    if (fread (data+dwide, 1, dwide, ifp) < dwide) derror();
+    FORC(dwide) data[c] = data[dwide+(c ^ rev)];
+    for (dp=data, col=0; col < raw_width; dp+=5, col+=4)
+      FORC4 RAW(row,col+c) = (dp[c] << 2) | (dp[4] >> (c << 1) & 3);
+  }
+#ifdef LIBRAW_LIBRARY_BUILD
+  } catch (...){
+    free (data);
+    throw;
   }
-  free (pixel);
 #endif
+  free (data);
+  maximum = 0x3ff;
+  if (strcmp(make,"OmniVision")) return;
+  row = raw_height/2;
+  FORC(width-1) {
+    sum[ c & 1] += SQR(RAW(row,c)-RAW(row+1,c+1));
+    sum[~c & 1] += SQR(RAW(row+1,c)-RAW(row,c+1));
+  }
+  if (sum[1] > sum[0]) filters = 0x4b4b4b4b;
 }
 
-void CLASS nokia_load_raw()
+void CLASS android_tight_load_raw()
 {
-  uchar  *data,  *dp;
-  ushort *pixel, *pix;
-  int rev, dwide, row, c;
+  uchar *data, *dp;
+  int bwide, row, col, c;
 
-  rev = 3 * (order == 0x4949);
-  dwide = raw_width * 5 / 4;
-  data = (uchar *) malloc (dwide + raw_width*2);
-  merror (data, "nokia_load_raw()");
-  pixel = (ushort *) (data + dwide);
+  bwide = -(-5*raw_width >> 5) << 3;
+  data = (uchar *) malloc (bwide);
+  merror (data, "android_tight_load_raw()");
   for (row=0; row < raw_height; row++) {
-    if (fread (data+dwide, 1, dwide, ifp) < dwide) derror();
-    FORC(dwide) data[c] = data[dwide+(c ^ rev)];
-    for (dp=data, pix=pixel; pix < pixel+raw_width; dp+=5, pix+=4)
-      FORC4 pix[c] = (dp[c] << 2) | (dp[4] >> (c << 1) & 3);
-    if (row < top_margin)
-      FORC(width) black += pixel[c];
-#ifndef LIBRAW_LIBRARY_BUILD
-    else
-      FORC(width) BAYER(row-top_margin,c) = pixel[c];
+    if (fread (data, 1, bwide, ifp) < bwide) derror();
+    for (dp=data, col=0; col < raw_width; dp+=5, col+=4)
+      FORC4 RAW(row,col+c) = (dp[c] << 2) | (dp[4] >> (c << 1) & 3);
+}
+  free (data);
+}
+
+void CLASS android_loose_load_raw()
+{
+  uchar *data, *dp;
+  int bwide, row, col, c;
+  UINT64 bitbuf=0;
+
+  bwide = (raw_width+5)/6 << 3;
+  data = (uchar *) malloc (bwide);
+  merror (data, "android_loose_load_raw()");
+  for (row=0; row < raw_height; row++) {
+    if (fread (data, 1, bwide, ifp) < bwide) derror();
+    for (dp=data, col=0; col < raw_width; dp+=8, col+=6) {
+      FORC(8) bitbuf = (bitbuf << 8) | dp[c^7];
+      FORC(6) RAW(row,col+c) = (bitbuf >> c*10) & 0x3ff;
+    }
+  }
+  free (data);
+}
+
+void CLASS canon_rmf_load_raw()
+{
+  int row, col, bits, orow, ocol, c;
+
+#ifdef LIBRAW_LIBRARY_BUILD
+  int *words = (int*)malloc(sizeof(int)*(raw_width/3+1));
+  merror(words,"canon_rmf_load_raw");
+#endif
+  for (row=0; row < raw_height; row++)
+  {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+    fread(words,sizeof(int),raw_width/3,ifp);
+    for (col=0; col < raw_width-2; col+=3)
+      {
+        bits = words[col/3];
+        FORC3 {
+          orow = row;
+          if ((ocol = col+c-4) < 0)
+            {
+              ocol += raw_width;
+              if ((orow -= 2) < 0)
+                orow += raw_height;
+            }
+          RAW(orow,ocol) = curve[bits >> (10*c+2) & 0x3ff];
+        }
+      }
 #else
-    memmove(&raw_image[row*raw_width],pixel,width*sizeof(pixel[0]));
+    for (col=0; col < raw_width-2; col+=3) {
+      bits = get4();
+      FORC3 {
+	orow = row;
+	if ((ocol = col+c-4) < 0) {
+	  ocol += raw_width;
+	  if ((orow -= 2) < 0)
+	    orow += raw_height;
+	}
+	RAW(orow,ocol) = curve[bits >> (10*c+2) & 0x3ff];
+      }
+    }
 #endif
   }
-  free (data);
-  if (top_margin) black /= top_margin * width;
-  maximum = 0x3ff;
+#ifdef LIBRAW_LIBRARY_BUILD
+  free(words);
+#endif
+  maximum = curve[0x3ff];
 }
 
 unsigned CLASS pana_bits (int nbits)
 {
 #ifndef LIBRAW_NOTHREADS
 #define buf tls->pana_bits.buf
-#define vbits tls->pana_bits.vbits   
+#define vbits tls->pana_bits.vbits
 #else
   static uchar buf[0x4000];
   static int vbits;
@@ -2184,7 +2267,7 @@ unsigned CLASS pana_bits (int nbits)
   }
   vbits = (vbits - nbits) & 0x1ffff;
   byte = vbits >> 3 ^ 0x3ff0;
-  return (buf[byte] | buf[byte+1] << 8) >> (vbits & 7) & ~(-1 << nbits);
+  return (buf[byte] | buf[byte+1] << 8) >> (vbits & 7) & ~((~0u) << nbits);
 #ifndef LIBRAW_NOTHREADS
 #undef buf
 #undef vbits
@@ -2197,6 +2280,10 @@ void CLASS panasonic_load_raw()
 
   pana_bits(0);
   for (row=0; row < height; row++)
+  {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     for (col=0; col < raw_width; col++) {
       if ((i = col % 14) == 0)
 	pred[0] = pred[1] = nonz[0] = nonz[1] = 0;
@@ -2204,23 +2291,16 @@ void CLASS panasonic_load_raw()
       if (nonz[i & 1]) {
 	if ((j = pana_bits(8))) {
 	  if ((pred[i & 1] -= 0x80 << sh) < 0 || sh == 4)
-	       pred[i & 1] &= ~(-1 << sh);
+            pred[i & 1] &= ~((~0u) << sh);
 	  pred[i & 1] += j << sh;
 	}
       } else if ((nonz[i & 1] = pana_bits(8)) || i > 11)
 	pred[i & 1] = nonz[i & 1] << 4 | pana_bits(4);
-#ifndef LIBRAW_LIBRARY_BUILD
-      if (col < width)
-              if ((BAYER(row,col) = pred[col & 1]) > 4098) derror();
-#else
-      RBAYER(row,col) = pred[col & 1];
-      if (col < width)
-          if (RBAYER(row,col) > 4098) derror();
-#endif
+      if ((RAW(row,col) = pred[col & 1]) > 4098 && col < width) derror();
     }
+  }
 }
 
-
 void CLASS olympus_load_raw()
 {
   ushort huff[4096];
@@ -2231,66 +2311,52 @@ void CLASS olympus_load_raw()
   for (i=12; i--; )
     FORC(2048 >> i) huff[++n] = (i+1) << 8 | i;
   fseek (ifp, 7, SEEK_CUR);
-#ifdef LIBRAW_LIBRARY_BUILD
-  if(!data_size)
-      throw LIBRAW_EXCEPTION_IO_BADFILE;
-  LibRaw_byte_buffer *buf = ifp->make_byte_buffer(data_size);
-  LibRaw_bit_buffer bits;
-  bits.reset();
-#else
   getbits(-1);
-#endif
   for (row=0; row < height; row++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     memset (acarry, 0, sizeof acarry);
     for (col=0; col < raw_width; col++) {
       carry = acarry[col & 1];
       i = 2 * (carry[2] < 3);
       for (nbits=2+i; (ushort) carry[0] >> (nbits+i); nbits++);
-#ifdef LIBRAW_LIBRARY_BUILD
-      low = (sign = bits._getbits(buf,3,zero_after_ff)) & 3;
-      sign = sign << 29 >> 31;
-      if ((high = bits._gethuff(buf,12,huff,zero_after_ff)) == 12)
-          high = bits._getbits(buf,16-nbits,zero_after_ff) >> 1;
-      carry[0] = (high << nbits) | bits._getbits(buf,nbits,zero_after_ff);
-#else
       low = (sign = getbits(3)) & 3;
       sign = sign << 29 >> 31;
       if ((high = getbithuff(12,huff)) == 12)
 	high = getbits(16-nbits) >> 1;
       carry[0] = (high << nbits) | getbits(nbits);
-#endif
       diff = (carry[0] ^ sign) + carry[1];
       carry[1] = (diff*3 + carry[1]) >> 5;
       carry[2] = carry[0] > 16 ? 0 : carry[2]+1;
       if (col >= width) continue;
       if (row < 2 && col < 2) pred = 0;
-      else if (row < 2) pred = RBAYER(row,col-2);
-      else if (col < 2) pred = RBAYER(row-2,col);
+      else if (row < 2) pred = RAW(row,col-2);
+      else if (col < 2) pred = RAW(row-2,col);
       else {
-	w  = RBAYER(row,col-2);
-	n  = RBAYER(row-2,col);
-	nw = RBAYER(row-2,col-2);
+	w  = RAW(row,col-2);
+	n  = RAW(row-2,col);
+	nw = RAW(row-2,col-2);
 	if ((w < nw && nw < n) || (n < nw && nw < w)) {
 	  if (ABS(w-nw) > 32 || ABS(n-nw) > 32)
 	    pred = w + n - nw;
 	  else pred = (w + n) >> 1;
 	} else pred = ABS(w-nw) > ABS(n-nw) ? w : n;
       }
-      if ((RBAYER(row,col) = pred + ((diff << 2) | low)) >> 12) derror();
+      if ((RAW(row,col) = pred + ((diff << 2) | low)) >> 12) derror();
     }
   }
-#ifdef LIBRAW_LIBRARY_BUILD
-  delete buf;
-#endif
 }
 
-
 void CLASS minolta_rd175_load_raw()
 {
   uchar pixel[768];
   unsigned irow, box, row, col;
 
   for (irow=0; irow < 1481; irow++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     if (fread (pixel, 1, 768, ifp) < 768) derror();
     box = irow / 82;
     row = irow % 82 * 12 + ((box < 12) ? box | 1 : (box-12)*2);
@@ -2302,13 +2368,13 @@ void CLASS minolta_rd175_load_raw()
     }
     if ((box < 12) && (box & 1)) {
       for (col=0; col < 1533; col++, row ^= 1)
-	if (col != 1) RRBAYER(row,col) = (col+1) & 2 ?
+	if (col != 1) RAW(row,col) = (col+1) & 2 ?
 		   pixel[col/2-1] + pixel[col/2+1] : pixel[col/2] << 1;
-      RRBAYER(row,1)    = pixel[1]   << 1;
-      RRBAYER(row,1533) = pixel[765] << 1;
+      RAW(row,1)    = pixel[1]   << 1;
+      RAW(row,1533) = pixel[765] << 1;
     } else
       for (col=row & 1; col < 1534; col+=2)
-          RRBAYER(row,col) = pixel[col/2] << 1;
+	RAW(row,col) = pixel[col/2] << 1;
   }
   maximum = 0xff << 1;
 }
@@ -2340,6 +2406,9 @@ void CLASS quicktake_100_load_raw()
   getbits(-1);
   memset (pixel, 0x80, sizeof pixel);
   for (row=2; row < height+2; row++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     for (col=2+(row & 1); col < width+2; col+=2) {
       val = ((pixel[row-1][col-1] + 2*pixel[row-1][col+1] +
 		pixel[row][col-2]) >> 2) + gstep[getbits(4)];
@@ -2353,6 +2422,10 @@ void CLASS quicktake_100_load_raw()
   }
   for (rb=0; rb < 2; rb++)
     for (row=2+rb; row < height+2; row+=2)
+    {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
       for (col=3-(row & 1); col < width+2; col+=2) {
 	if (row < 4 || col < 4) sharp = 2;
 	else {
@@ -2368,15 +2441,26 @@ void CLASS quicktake_100_load_raw()
 	if (row < 4) pixel[row-2][col+2] = val;
 	if (col < 4) pixel[row+2][col-2] = val;
       }
+    }
   for (row=2; row < height+2; row++)
+  {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     for (col=3-(row & 1); col < width+2; col+=2) {
       val = ((pixel[row][col-1] + (pixel[row][col] << 2) +
 	      pixel[row][col+1]) >> 1) - 0x100;
       pixel[row][col] = LIM(val,0,255);
     }
+  }
   for (row=0; row < height; row++)
+  {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     for (col=0; col < width; col++)
-            RBAYER(row,col) = t_curve[pixel[row+2][col+2]];
+      RAW(row,col) = t_curve[pixel[row+2][col+2]];
+  }
   maximum = 0x3ff;
 }
 
@@ -2387,6 +2471,12 @@ void CLASS quicktake_100_load_raw()
 #define PREDICTOR (c ? (buf[c][y-1][x] + buf[c][y][x+1]) / 2 \
 : (buf[c][y-1][x+1] + 2*buf[c][y-1][x] + buf[c][y][x+1]) / 4)
 
+#ifdef __GNUC__
+# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+# pragma GCC optimize("no-aggressive-loop-optimizations")
+# endif
+#endif
+
 void CLASS kodak_radc_load_raw()
 {
   static const char src[] = {
@@ -2428,11 +2518,14 @@ void CLASS kodak_radc_load_raw()
   for (i=0; i < sizeof(buf)/sizeof(short); i++)
     buf[0][0][i] = 2048;
   for (row=0; row < height; row+=4) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     FORC3 mul[c] = getbits(6);
     FORC3 {
       val = ((0x1000000/last[c] + 0x7ff) >> 12) * mul[c];
       s = val > 65564 ? 10:12;
-      x = ~(-1 << (s-1));
+      x = ~((~0u) << (s-1));
       val <<= 12-s;
       for (i=0; i < sizeof(buf[0])/sizeof(short); i++)
 	buf[c][0][i] = (buf[c][0][i] * val + x) >> s;
@@ -2463,8 +2556,8 @@ void CLASS kodak_radc_load_raw()
 	  for (x=0; x < width/2; x++) {
 	    val = (buf[c][y+1][x] << 4) / mul[c];
 	    if (val < 0) val = 0;
-	    if (c) CBAYER(row+y*2+c-1,x*2+2-c) = val;
-	    else   CBAYER(row+r*2+y,x*2+y) = val;
+	    if (c) RAW(row+y*2+c-1,x*2+2-c) = val;
+	    else   RAW(row+r*2+y,x*2+y) = val;
 	  }
 	memcpy (buf[c][0]+!c, buf[c][2], sizeof buf[c][0]-2*!c);
       }
@@ -2474,18 +2567,13 @@ void CLASS kodak_radc_load_raw()
 	if ((x+y) & 1) {
 	  r = x ? x-1 : x+1;
 	  s = x+1 < width ? x+1 : x-1;
-	  val = (CBAYER(y,x)-2048)*2 + (CBAYER(y,r)+CBAYER(y,s))/2;
+	  val = (RAW(y,x)-2048)*2 + (RAW(y,r)+RAW(y,s))/2;
 	  if (val < 0) val = 0;
-	  CBAYER(y,x) = val;
+	  RAW(y,x) = val;
 	}
   }
-#ifndef LIBRAW_LIBRARY_BUILD
-  for (i=0; i < iheight*iwidth*4; i++)
-    image[0][i] = curve[image[0][i]];
-#else
-  for (i=0; i < height*width*4; i++)
-    color_image[0][i] = curve[color_image[0][i]];
-#endif
+  for (i=0; i < height*width; i++)
+    raw_image[i] = curve[raw_image[i]];
   maximum = 0x3fff;
 }
 
@@ -2494,16 +2582,15 @@ void CLASS kodak_radc_load_raw()
 
 #ifdef NO_JPEG
 void CLASS kodak_jpeg_load_raw() {}
+void CLASS lossy_dng_load_raw() {}
 #else
 
+
+#ifndef LIBRAW_LIBRARY_BUILD
 METHODDEF(boolean)
 fill_input_buffer (j_decompress_ptr cinfo)
 {
-#ifndef LIBRAW_NOTHREADS
-#define jpeg_buffer tls->jpeg_buffer
-#else
   static uchar jpeg_buffer[4096];
-#endif
   size_t nbytes;
 
   nbytes = fread (jpeg_buffer, 1, 4096, ifp);
@@ -2511,11 +2598,7 @@ fill_input_buffer (j_decompress_ptr cinfo)
   cinfo->src->next_input_byte = jpeg_buffer;
   cinfo->src->bytes_in_buffer = nbytes;
   return TRUE;
-#ifndef LIBRAW_NOTHREADS
-#undef jpeg_buffer
-#endif
 }
-
 void CLASS kodak_jpeg_load_raw()
 {
   struct jpeg_decompress_struct cinfo;
@@ -2533,117 +2616,314 @@ void CLASS kodak_jpeg_load_raw()
   if ((cinfo.output_width      != width  ) ||
       (cinfo.output_height*2   != height ) ||
       (cinfo.output_components != 3      )) {
-#ifdef DCRAW_VERBOSE
     fprintf (stderr,_("%s: incorrect JPEG dimensions\n"), ifname);
-#endif
     jpeg_destroy_decompress (&cinfo);
-#ifdef LIBRAW_LIBRARY_BUILD
-    throw LIBRAW_EXCEPTION_DECODE_JPEG;
-#else
     longjmp (failure, 3);
-#endif
   }
   buf = (*cinfo.mem->alloc_sarray)
-		((j_common_ptr) &cinfo, JPOOL_IMAGE, width*3, 1);
+    ((j_common_ptr) &cinfo, JPOOL_IMAGE, width*3, 1);
 
   while (cinfo.output_scanline < cinfo.output_height) {
     row = cinfo.output_scanline * 2;
     jpeg_read_scanlines (&cinfo, buf, 1);
     pixel = (JSAMPLE (*)[3]) buf[0];
     for (col=0; col < width; col+=2) {
-      RBAYER(row+0,col+0) = pixel[col+0][1] << 1;
-      RBAYER(row+1,col+1) = pixel[col+1][1] << 1;
-      RBAYER(row+0,col+1) = pixel[col][0] + pixel[col+1][0];
-      RBAYER(row+1,col+0) = pixel[col][2] + pixel[col+1][2];
+      RAW(row+0,col+0) = pixel[col+0][1] << 1;
+      RAW(row+1,col+1) = pixel[col+1][1] << 1;
+      RAW(row+0,col+1) = pixel[col][0] + pixel[col+1][0];
+      RAW(row+1,col+0) = pixel[col][2] + pixel[col+1][2];
     }
   }
   jpeg_finish_decompress (&cinfo);
   jpeg_destroy_decompress (&cinfo);
   maximum = 0xff << 1;
 }
-#endif
+#else
 
-void CLASS kodak_dc120_load_raw()
-{
-  static const int mul[4] = { 162, 192, 187,  92 };
-  static const int add[4] = {   0, 636, 424, 212 };
-  uchar pixel[848];
-  int row, shift, col;
+struct jpegErrorManager {
+  struct jpeg_error_mgr pub;
+};
 
-  for (row=0; row < height; row++) {
-    if (fread (pixel, 1, 848, ifp) < 848) derror();
-    shift = row * mul[row & 3] + add[row & 3];
-    for (col=0; col < width; col++)
-      RBAYER(row,col) = (ushort) pixel[(col + shift) % 848];
-  }
-  maximum = 0xff;
+static void jpegErrorExit (j_common_ptr cinfo)
+{
+  jpegErrorManager* myerr = (jpegErrorManager*) cinfo->err;
+  throw LIBRAW_EXCEPTION_DECODE_JPEG;
 }
 
-void CLASS eight_bit_load_raw()
+
+// LibRaw's Kodak_jpeg_load_raw
+void CLASS kodak_jpeg_load_raw()
 {
-  uchar *pixel;
-  unsigned row, col, val, lblack=0;
+  if(data_size < 1)
+    throw LIBRAW_EXCEPTION_DECODE_JPEG;
 
-  pixel = (uchar *) calloc (raw_width, sizeof *pixel);
-  merror (pixel, "eight_bit_load_raw()");
-#ifndef LIBRAW_LIBRARY_BUILD
-  fseek (ifp, top_margin*raw_width, SEEK_CUR);
-  for (row=0; row < height; row++) {
-    if (fread (pixel, 1, raw_width, ifp) < raw_width) derror();
-    for (col=0; col < raw_width; col++) {
-      val = curve[pixel[col]];
-      if ((unsigned) (col-left_margin) < width)
-	BAYER(row,col-left_margin) = val;
-      else lblack += val;
-    }
+  int row, col;
+  jpegErrorManager jerr;
+  struct jpeg_decompress_struct cinfo;
+
+  cinfo.err = jpeg_std_error(&jerr.pub);
+  jerr.pub.error_exit = jpegErrorExit;
+
+  unsigned char *jpg_buf = (unsigned char *)malloc(data_size);
+  merror(jpg_buf,"kodak_jpeg_load_raw");
+  unsigned char *pixel_buf = (unsigned char*) malloc(width*3);
+  jpeg_create_decompress (&cinfo);
+  merror(pixel_buf,"kodak_jpeg_load_raw");
+
+  fread(jpg_buf,data_size,1,ifp);
+  swab ((char*)jpg_buf, (char*)jpg_buf, data_size);
+  try
+    {
+      jpeg_mem_src(&cinfo, jpg_buf, data_size);
+      int rc = jpeg_read_header(&cinfo, TRUE);
+      if(rc!=1)
+        throw LIBRAW_EXCEPTION_DECODE_JPEG;
+
+      jpeg_start_decompress (&cinfo);
+      if ((cinfo.output_width      != width  ) ||
+          (cinfo.output_height*2   != height ) ||
+          (cinfo.output_components != 3      ))
+        {
+          throw LIBRAW_EXCEPTION_DECODE_JPEG;
+        }
+
+      unsigned char *buf[1];
+      buf[0] = pixel_buf;
+
+      while (cinfo.output_scanline < cinfo.output_height)
+        {
+          checkCancel();
+          row = cinfo.output_scanline * 2;
+          jpeg_read_scanlines (&cinfo, buf, 1);
+          unsigned char (*pixel)[3] = (unsigned char (*)[3]) buf[0];
+          for (col=0; col < width; col+=2) {
+            RAW(row+0,col+0) = pixel[col+0][1] << 1;
+            RAW(row+1,col+1) = pixel[col+1][1] << 1;
+            RAW(row+0,col+1) = pixel[col][0] + pixel[col+1][0];
+            RAW(row+1,col+0) = pixel[col][2] + pixel[col+1][2];
+          }
+        }
+    }
+  catch (...)
+        {
+          jpeg_finish_decompress (&cinfo);
+          jpeg_destroy_decompress (&cinfo);
+          free(jpg_buf);
+          free(pixel_buf);
+          throw;
+        }
+  jpeg_finish_decompress (&cinfo);
+  jpeg_destroy_decompress (&cinfo);
+  free(jpg_buf);
+  free(pixel_buf);
+  maximum = 0xff << 1;
+}
+#endif
+
+#ifndef LIBRAW_LIBRARY_BUILD
+void CLASS gamma_curve (double pwr, double ts, int mode, int imax);
+#endif
+
+void CLASS lossy_dng_load_raw()
+{
+  struct jpeg_decompress_struct cinfo;
+  struct jpeg_error_mgr jerr;
+  JSAMPARRAY buf;
+  JSAMPLE (*pixel)[3];
+  unsigned sorder=order, ntags, opcode, deg, i, j, c;
+  unsigned save=data_offset-4, trow=0, tcol=0, row, col;
+  ushort cur[3][256];
+  double coeff[9], tot;
+
+  if (meta_offset) {
+    fseek (ifp, meta_offset, SEEK_SET);
+    order = 0x4d4d;
+    ntags = get4();
+    while (ntags--) {
+      opcode = get4(); get4(); get4();
+      if (opcode != 8)
+      { fseek (ifp, get4(), SEEK_CUR); continue; }
+      fseek (ifp, 20, SEEK_CUR);
+      if ((c = get4()) > 2) break;
+      fseek (ifp, 12, SEEK_CUR);
+      if ((deg = get4()) > 8) break;
+      for (i=0; i <= deg && i < 9; i++)
+	coeff[i] = getreal(12);
+      for (i=0; i < 256; i++) {
+	for (tot=j=0; j <= deg; j++)
+	  tot += coeff[j] * pow(i/255.0, (int)j);
+	cur[c][i] = tot*0xffff;
+      }
+    }
+    order = sorder;
+  } else {
+    gamma_curve (1/2.4, 12.92, 1, 255);
+    FORC3 memcpy (cur[c], curve, sizeof cur[0]);
   }
+  cinfo.err = jpeg_std_error (&jerr);
+  jpeg_create_decompress (&cinfo);
+  while (trow < raw_height) {
+    fseek (ifp, save+=4, SEEK_SET);
+    if (tile_length < INT_MAX)
+      fseek (ifp, get4(), SEEK_SET);
+#ifdef LIBRAW_LIBRARY_BUILD
+    if(libraw_internal_data.internal_data.input->jpeg_src(&cinfo) == -1)
+      {
+        jpeg_destroy_decompress(&cinfo);
+        throw LIBRAW_EXCEPTION_DECODE_JPEG;
+      }
 #else
+    jpeg_stdio_src (&cinfo, ifp);
+#endif
+    jpeg_read_header (&cinfo, TRUE);
+    jpeg_start_decompress (&cinfo);
+    buf = (*cinfo.mem->alloc_sarray)
+	((j_common_ptr) &cinfo, JPOOL_IMAGE, cinfo.output_width*3, 1);
+#ifdef LIBRAW_LIBRARY_BUILD
+  try {
+#endif
+    while (cinfo.output_scanline < cinfo.output_height &&
+	(row = trow + cinfo.output_scanline) < height) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
+      jpeg_read_scanlines (&cinfo, buf, 1);
+      pixel = (JSAMPLE (*)[3]) buf[0];
+      for (col=0; col < cinfo.output_width && tcol+col < width; col++) {
+	FORC3 image[row*width+tcol+col][c] = cur[c][pixel[col][c]];
+      }
+    }
+#ifdef LIBRAW_LIBRARY_BUILD
+  } catch(...) {
+    jpeg_destroy_decompress (&cinfo);
+    throw;
+  }
+#endif
+    jpeg_abort_decompress (&cinfo);
+    if ((tcol += tile_width) >= raw_width)
+      trow += tile_length + (tcol = 0);
+  }
+  jpeg_destroy_decompress (&cinfo);
+  maximum = 0xffff;
+}
+#endif
+
+void CLASS kodak_dc120_load_raw()
+{
+  static const int mul[4] = { 162, 192, 187,  92 };
+  static const int add[4] = {   0, 636, 424, 212 };
+  uchar pixel[848];
+  int row, shift, col;
+
+  for (row=0; row < height; row++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
+    if (fread (pixel, 1, 848, ifp) < 848) derror();
+    shift = row * mul[row & 3] + add[row & 3];
+    for (col=0; col < width; col++)
+      RAW(row,col) = (ushort) pixel[(col + shift) % 848];
+  }
+  maximum = 0xff;
+}
+
+void CLASS eight_bit_load_raw()
+{
+  uchar *pixel;
+  unsigned row, col;
+
+  pixel = (uchar *) calloc (raw_width, sizeof *pixel);
+  merror (pixel, "eight_bit_load_raw()");
+#ifdef LIBRAW_LIBRARY_BUILD
+  try {
+#endif
   for (row=0; row < raw_height; row++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     if (fread (pixel, 1, raw_width, ifp) < raw_width) derror();
-    for (col=0; col < raw_width; col++) {
-            val = curve[pixel[col]];
-        RBAYER(row,col) = val;
-        if((unsigned) (row-top_margin)< height)
-            if ((unsigned) (col-left_margin) >= width)
-                lblack+=val;
-    }
+    for (col=0; col < raw_width; col++)
+      RAW(row,col) = curve[pixel[col]];
+  }
+#ifdef LIBRAW_LIBRARY_BUILD
+  } catch(...) {
+    free (pixel);
+    throw;
   }
 #endif
+  free (pixel);
+  maximum = curve[0xff];
+}
+
+void CLASS kodak_c330_load_raw()
+{
+  uchar *pixel;
+  int row, col, y, cb, cr, rgb[3], c;
 
+  pixel = (uchar *) calloc (raw_width, 2*sizeof *pixel);
+  merror (pixel, "kodak_c330_load_raw()");
+#ifdef LIBRAW_LIBRARY_BUILD
+  try {
+#endif
+  for (row=0; row < height; row++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
+    if (fread (pixel, raw_width, 2, ifp) < 2) derror();
+    if (load_flags && (row & 31) == 31)
+      fseek (ifp, raw_width*32, SEEK_CUR);
+    for (col=0; col < width; col++) {
+      y  = pixel[col*2];
+      cb = pixel[(col*2 & -4) | 1] - 128;
+      cr = pixel[(col*2 & -4) | 3] - 128;
+      rgb[1] = y - ((cb + cr + 2) >> 2);
+      rgb[2] = rgb[1] + cb;
+      rgb[0] = rgb[1] + cr;
+      FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,255)];
+    }
+  }
+#ifdef LIBRAW_LIBRARY_BUILD
+  } catch(...) {
+    free (pixel);
+    throw;
+  }
+#endif
   free (pixel);
-  if (raw_width > width+1)
-    black = lblack / ((raw_width - width) * height);
-  if (!strncmp(model,"DC2",3))
-    black = 0;
   maximum = curve[0xff];
 }
 
-void CLASS kodak_yrgb_load_raw()
+void CLASS kodak_c603_load_raw()
 {
   uchar *pixel;
   int row, col, y, cb, cr, rgb[3], c;
 
   pixel = (uchar *) calloc (raw_width, 3*sizeof *pixel);
-  merror (pixel, "kodak_yrgb_load_raw()");
+  merror (pixel, "kodak_c603_load_raw()");
+#ifdef LIBRAW_LIBRARY_BUILD
+  try {
+#endif
   for (row=0; row < height; row++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     if (~row & 1)
       if (fread (pixel, raw_width, 3, ifp) < 3) derror();
-    for (col=0; col < raw_width; col++) {
+    for (col=0; col < width; col++) {
       y  = pixel[width*2*(row & 1) + col];
       cb = pixel[width + (col & -2)]   - 128;
       cr = pixel[width + (col & -2)+1] - 128;
-      rgb[1] = y-((cb + cr + 2) >> 2);
+      rgb[1] = y - ((cb + cr + 2) >> 2);
       rgb[2] = rgb[1] + cb;
       rgb[0] = rgb[1] + cr;
-      FORC3{
-#ifndef LIBRAW_LIBRARY_BUILD
-          image[row*width+col][c] = curve[LIM(rgb[c],0,255)];
-#else
-          color_image[(row+top_margin)*raw_width+col+left_margin][c] = curve[LIM(rgb[c],0,255)];
-#endif
-      }
+      FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,255)];
     }
   }
+#ifdef LIBRAW_LIBRARY_BUILD
+  } catch(...) {
+    free (pixel);
+    throw;
+  }
+#endif
   free (pixel);
   maximum = curve[0xff];
 }
@@ -2664,7 +2944,13 @@ void CLASS kodak_262_load_raw()
   strip = (int *) (pixel + raw_width*32);
   order = 0x4d4d;
   FORC(ns) strip[c] = get4();
+#ifdef LIBRAW_LIBRARY_BUILD
+  try {
+#endif
   for (row=0; row < raw_height; row++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     if ((row & 31) == 0) {
       fseek (ifp, strip[row >> 5], SEEK_SET);
       getbits(-1);
@@ -2681,24 +2967,18 @@ void CLASS kodak_262_load_raw()
       pred = (pi1 < 0) ? 0 : (pixel[pi1] + pixel[pi2]) >> 1;
       pixel[pi] = val = pred + ljpeg_diff (huff[chess]);
       if (val >> 8) derror();
-
       val = curve[pixel[pi++]];
-
-#ifdef LIBRAW_LIBRARY_BUILD
-      RBAYER(row,col) = val;
-      if ((unsigned) (col-left_margin) >= width)
-          black+=val;
-#else
-      if ((unsigned) (col-left_margin) < width)
-	BAYER(row,col-left_margin) = val;
-      else black += val;
-#endif
+      RAW(row,col) = val;
     }
   }
+#ifdef LIBRAW_LIBRARY_BUILD
+  } catch(...) {
+    free (pixel);
+    throw;
+  }
+#endif
   free (pixel);
   FORC(2) free (huff[c]);
-  if (raw_width > width)
-    black /= (raw_width - width) * height;
 }
 
 int CLASS kodak_65000_decode (short *out, int bsize)
@@ -2753,23 +3033,19 @@ void CLASS kodak_65000_load_raw()
   int row, col, len, pred[2], ret, i;
 
   for (row=0; row < height; row++)
+  {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     for (col=0; col < width; col+=256) {
       pred[0] = pred[1] = 0;
       len = MIN (256, width-col);
       ret = kodak_65000_decode (buf, len);
       for (i=0; i < len; i++)
-#ifndef LIBRAW_LIBRARY_BUILD
-	if ((BAYER(row,col+i) =	curve[ret ? buf[i] :
+	if ((RAW(row,col+i) =	curve[ret ? buf[i] :
 		(pred[i & 1] += buf[i])]) >> 12) derror();
-#else
-      {
-          ushort val = ret ? buf[i] : (pred[i & 1] += buf[i]);
-          val = curve[val];
-          RBAYER(row,col+i) = val;
-          if(curve[val]>>12) derror();
-      }
-#endif
     }
+  }
 }
 
 void CLASS kodak_ycbcr_load_raw()
@@ -2778,7 +3054,13 @@ void CLASS kodak_ycbcr_load_raw()
   int row, col, len, c, i, j, k, y[2][2], cb, cr, rgb[3];
   ushort *ip;
 
+  if (!image) return;
+  unsigned int bits = (load_flags && load_flags > 9 && load_flags < 17)?load_flags:10;
   for (row=0; row < height; row+=2)
+  {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     for (col=0; col < width; col+=128) {
       len = MIN (128, width-col);
       kodak_65000_decode (buf, len*3);
@@ -2791,85 +3073,41 @@ void CLASS kodak_ycbcr_load_raw()
 	rgb[0] = rgb[1] + cr;
 	for (j=0; j < 2; j++)
 	  for (k=0; k < 2; k++) {
-	    if ((y[j][k] = y[j][k^1] + *bp++) >> 10) derror();
-#ifndef LIBRAW_LIBRARY_BUILD
+	    if ((y[j][k] = y[j][k^1] + *bp++) >> bits) derror();
 	    ip = image[(row+j)*width + col+i+k];
 	    FORC3 ip[c] = curve[LIM(y[j][k]+rgb[c], 0, 0xfff)];
-#else
-	    ip = color_image[(row+top_margin+j)*raw_width + col+i+k+left_margin];
-            FORC3 ip[c] = curve[LIM(y[j][k]+rgb[c], 0, 0xfff)];
-#endif
 	  }
       }
     }
+  }
 }
 
 void CLASS kodak_rgb_load_raw()
 {
   short buf[768], *bp;
-  int row, col, len, c, i, rgb[3];
-#ifndef LIBRAW_LIBRARY_BUILD
+  int row, col, len, c, i, rgb[3],ret;
   ushort *ip=image[0];
-#else
-  ushort *ip;
-#endif
 
   for (row=0; row < height; row++)
-    for (col=0; col < width; col+=256) {
-      len = MIN (256, width-col);
-      kodak_65000_decode (buf, len*3);
-      memset (rgb, 0, sizeof rgb);
+  {
 #ifdef LIBRAW_LIBRARY_BUILD
-      ip = &color_image[(row+top_margin)*raw_width+left_margin][0];
+    checkCancel();
 #endif
-      for (bp=buf, i=0; i < len; i++, ip+=4)
-          FORC3{
-              if ((ip[c] = rgb[c] += *bp++) >> 12) derror();
-          }
-    }
-}
-
-void CLASS kodak_ycbcr_load_thumb()
-{
-  short buf[384], *bp;
-  int row, col, len, c, i, j, k, y[2][2], cb, cr, rgb[3];
-  ushort *ip;
-
-  for (row=0; row < height; row+=2)
-    for (col=0; col < width; col+=128) {
-      len = MIN (128, width-col);
-      kodak_65000_decode (buf, len*3);
-      y[0][1] = y[1][1] = cb = cr = 0;
-      for (bp=buf, i=0; i < len; i+=2, bp+=2) {
-	cb += bp[4];
-	cr += bp[5];
-	rgb[1] = -((cb + cr + 2) >> 2);
-	rgb[2] = rgb[1] + cb;
-	rgb[0] = rgb[1] + cr;
-	for (j=0; j < 2; j++)
-	  for (k=0; k < 2; k++) {
-	    if ((y[j][k] = y[j][k^1] + *bp++) >> 10) derror();
-	    ip = image[(row+j)*width + col+i+k];
-	    FORC3 ip[c] = curve[LIM(y[j][k]+rgb[c], 0, 0xfff)];
-	  }
-      }
-    }
-}
-
-void CLASS kodak_rgb_load_thumb()
-{
-  short buf[768], *bp;
-  int row, col, len, c, i, rgb[3];
-  ushort *ip=image[0];
-
-  for (row=0; row < height; row++)
     for (col=0; col < width; col+=256) {
       len = MIN (256, width-col);
-      kodak_65000_decode (buf, len*3);
+      ret = kodak_65000_decode (buf, len*3);
       memset (rgb, 0, sizeof rgb);
       for (bp=buf, i=0; i < len; i++, ip+=4)
-	FORC3 if ((ip[c] = rgb[c] += *bp++) >> 12) derror();
+#ifdef LIBRAW_LIBRARY_BUILD
+        if(load_flags == 12)
+          {
+            FORC3 ip[c] = ret ? (*bp++) : (rgb[c] += *bp++);
+          }
+        else
+#endif
+          FORC3 if ((ip[c] = ret ? (*bp++) : (rgb[c] += *bp++)) >> 12) derror();
     }
+  }
 }
 
 void CLASS kodak_thumb_load_raw()
@@ -2890,7 +3128,6 @@ void CLASS sony_decrypt (unsigned *data, int len, int start, int key)
 #else
   static unsigned pad[128], p;
 #endif
-
   if (start) {
     for (p=0; p < 4; p++)
       pad[p] = key = key * 48828125 + 1;
@@ -2901,7 +3138,10 @@ void CLASS sony_decrypt (unsigned *data, int len, int start, int key)
       pad[p] = htonl(pad[p]);
   }
   while (len--)
-    *data++ ^= pad[p++ & 127] = pad[(p+1) & 127] ^ pad[(p+65) & 127];
+    {
+      *data++ ^= pad[p & 127] = pad[(p+1) & 127] ^ pad[(p+65) & 127];
+      p++;
+    }
 #ifndef LIBRAW_NOTHREADS
 #undef pad
 #undef p
@@ -2924,88 +3164,42 @@ void CLASS sony_load_raw()
   for (i=26; i-- > 22; )
     key = key << 8 | head[i];
   fseek (ifp, data_offset, SEEK_SET);
-  pixel = (ushort *) calloc (raw_width, sizeof *pixel);
-  merror (pixel, "sony_load_raw()");
-  for (row=0; row < height; row++) {
+  for (row=0; row < raw_height; row++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
+    pixel = raw_image + row*raw_width;
     if (fread (pixel, 2, raw_width, ifp) < raw_width) derror();
     sony_decrypt ((unsigned int *) pixel, raw_width/2, !row, key);
-    for (col=9; col < left_margin; col++)
-      black += ntohs(pixel[col]);
-#ifndef LIBRAW_LIBRARY_BUILD
-    for (col=0; col < width; col++)
-      if ((BAYER(row,col) = ntohs(pixel[col+left_margin])) >> 14)
-	derror();
-#else
     for (col=0; col < raw_width; col++)
-        {
-            RBAYER(row,col) = ntohs(pixel[col]);
-            if(col >= left_margin && col < width+left_margin
-               && (RBAYER(row,col)>>14))
-                derror();
-        }
-#endif
-   }
-  free (pixel);
-  if (left_margin > 9)
-    black /= (left_margin-9) * height;
+      if ((pixel[col] = ntohs(pixel[col])) >> 14) derror();
+  }
   maximum = 0x3ff0;
 }
 
 void CLASS sony_arw_load_raw()
 {
-  ushort huff[32768];
+  ushort huff[32770];
   static const ushort tab[18] =
   { 0xf11,0xf10,0xe0f,0xd0e,0xc0d,0xb0c,0xa0b,0x90a,0x809,
     0x708,0x607,0x506,0x405,0x304,0x303,0x300,0x202,0x201 };
-  int i, c, n, col, row, len, diff, sum=0;
+  int i, c, n, col, row, sum=0;
 
+  huff[0] = 15;
   for (n=i=0; i < 18; i++)
-    FORC(32768 >> (tab[i] >> 8)) huff[n++] = tab[i];
-#ifdef LIBRAW_LIBRARY_BUILD
-  LibRaw_byte_buffer *buf=NULL;
-  if(data_size)
-      buf = ifp->make_byte_buffer(data_size);
-  else
-      getbits(-1);
-      
-  LibRaw_bit_buffer bits;
-  bits.reset();
-#else
+    FORC(32768 >> (tab[i] >> 8)) huff[++n] = tab[i];
   getbits(-1);
-#endif
   for (col = raw_width; col--; )
-    for (row=0; row < raw_height+1; row+=2) {
-      if (row == raw_height) row = 1;
+  {
 #ifdef LIBRAW_LIBRARY_BUILD
-      if(data_size)
-          {
-              len = bits._gethuff(buf,15,huff,zero_after_ff);
-              diff = bits._getbits(buf,len,zero_after_ff);
-          }
-      else
-          {
-              len = getbithuff(15,huff);
-              diff = getbits(len);
-          }
-#else
-      len = getbithuff(15,huff);
-      diff = getbits(len);
-#endif
-      if ((diff & (1 << (len-1))) == 0)
-	diff -= (1 << len) - 1;
-      if ((sum += diff) >> 12) derror();
-#ifndef LIBRAW_LIBRARY_BUILD
-      if (row < height)
-          {
-              BAYER(row,col) = sum;
-          }
-#else
-      RBAYER(row,col) = sum;
+    checkCancel();
 #endif
+    for (row=0; row < raw_height+1; row+=2) {
+      if (row == raw_height) row = 1;
+      if ((sum += ljpeg_diff(huff)) >> 12) derror();
+      if (row < height) RAW(row,col) = sum;
     }
-#ifdef LIBRAW_LIBRARY_BUILD
-  if(buf) delete buf;
-#endif
+  }
 }
 
 void CLASS sony_arw2_load_raw()
@@ -3014,9 +3208,15 @@ void CLASS sony_arw2_load_raw()
   ushort pix[16];
   int row, col, val, max, min, imax, imin, sh, bit, i;
 
-  data = (uchar *) malloc (raw_width+4);
+  data = (uchar *) malloc (raw_width+1);
   merror (data, "sony_arw2_load_raw()");
+#ifdef LIBRAW_LIBRARY_BUILD
+  try {
+#endif
   for (row=0; row < height; row++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     fread (data, 1, raw_width, ifp);
     for (dp=data, col=0; col < raw_width-30; dp+=16) {
       max = 0x7ff & (val = sget4(dp));
@@ -3024,26 +3224,209 @@ void CLASS sony_arw2_load_raw()
       imax = 0x0f & val >> 22;
       imin = 0x0f & val >> 26;
       for (sh=0; sh < 4 && 0x80 << sh <= max-min; sh++);
-      for (bit=30, i=0; i < 16; i++)
-	if      (i == imax) pix[i] = max;
-	else if (i == imin) pix[i] = min;
-	else {
+#ifdef LIBRAW_LIBRARY_BUILD
+      /* flag checks if outside of loop */
+      if(imgdata.params.sony_arw2_options == LIBRAW_SONYARW2_NONE
+         || imgdata.params.sony_arw2_options == LIBRAW_SONYARW2_DELTATOVALUE
+         )
+        {
+          for (bit=30, i=0; i < 16; i++)
+            if      (i == imax) pix[i] = max;
+            else if (i == imin) pix[i] = min;
+            else {
+              pix[i] = ((sget2(dp+(bit >> 3)) >> (bit & 7) & 0x7f) << sh) + min;
+              if (pix[i] > 0x7ff) pix[i] = 0x7ff;
+              bit += 7;
+            }
+        }
+      else if(imgdata.params.sony_arw2_options == LIBRAW_SONYARW2_BASEONLY)
+        {
+          for (bit=30, i=0; i < 16; i++)
+            if      (i == imax) pix[i] = max;
+            else if (i == imin) pix[i] = min;
+            else pix[i]=0;
+        }
+      else if(imgdata.params.sony_arw2_options == LIBRAW_SONYARW2_DELTAONLY)
+        {
+          for (bit=30, i=0; i < 16; i++)
+            if      (i == imax) pix[i] = 0;
+            else if (i == imin) pix[i] = 0;
+            else {
+              pix[i] = ((sget2(dp+(bit >> 3)) >> (bit & 7) & 0x7f) << sh) + min;
+              if (pix[i] > 0x7ff) pix[i] = 0x7ff;
+              bit += 7;
+            }
+        }
+      else if(imgdata.params.sony_arw2_options == LIBRAW_SONYARW2_DELTAZEROBASE)
+        {
+          for (bit=30, i=0; i < 16; i++)
+            if      (i == imax) pix[i] = 0;
+            else if (i == imin) pix[i] = 0;
+            else {
+              pix[i] = ((sget2(dp+(bit >> 3)) >> (bit & 7) & 0x7f) << sh);
+              if (pix[i] > 0x7ff) pix[i] = 0x7ff;
+              bit += 7;
+            }
+        }
+#else
+      /* unaltered dcraw processing */
+      for (bit=30, i=0; i < 16; i++)
+	if      (i == imax) pix[i] = max;
+	else if (i == imin) pix[i] = min;
+	else {
 	  pix[i] = ((sget2(dp+(bit >> 3)) >> (bit & 7) & 0x7f) << sh) + min;
 	  if (pix[i] > 0x7ff) pix[i] = 0x7ff;
 	  bit += 7;
 	}
-      for (i=0; i < 16; i++, col+=2)
+#endif
+
 #ifdef LIBRAW_LIBRARY_BUILD
-	RBAYER(row,col) = curve[pix[i] << 1] >> 2;
+      if(imgdata.params.sony_arw2_options == LIBRAW_SONYARW2_DELTATOVALUE)
+        {
+          for (i=0; i < 16; i++, col+=2)
+            {
+              unsigned slope = pix[i] < 1001? 2 : curve[pix[i]<<1]-curve[(pix[i]<<1)-2];
+              unsigned step = 1 << sh;
+              RAW(row,col)=curve[pix[i]<<1]>black+imgdata.params.sony_arw2_posterization_thr?
+                LIM(((slope*step*1000)/(curve[pix[i]<<1]-black)),0,10000):0;
+            }
+        }
+      else
+        {
+          for (i=0; i < 16; i++, col+=2)
+            RAW(row,col) = curve[pix[i] << 1];
+        }
 #else
-	if (col < width) BAYER(row,col) = curve[pix[i] << 1] >> 2;
+      for (i=0; i < 16; i++, col+=2)
+	RAW(row,col) = curve[pix[i] << 1] >> 2;
 #endif
       col -= col & 1 ? 1:31;
     }
   }
+#ifdef LIBRAW_LIBRARY_BUILD
+  } catch(...) {
+    free (data);
+    throw;
+  }
+  if(imgdata.params.sony_arw2_options == LIBRAW_SONYARW2_DELTATOVALUE)
+    maximum=10000;
+#endif
   free (data);
 }
- 
+
+void CLASS samsung_load_raw()
+{
+  int row, col, c, i, dir, op[4], len[4];
+
+  order = 0x4949;
+  for (row=0; row < raw_height; row++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
+    fseek (ifp, strip_offset+row*4, SEEK_SET);
+    fseek (ifp, data_offset+get4(), SEEK_SET);
+    ph1_bits(-1);
+    FORC4 len[c] = row < 2 ? 7:4;
+    for (col=0; col < raw_width; col+=16) {
+      dir = ph1_bits(1);
+      FORC4 op[c] = ph1_bits(2);
+      FORC4 switch (op[c]) {
+	case 3: len[c] = ph1_bits(4);	break;
+	case 2: len[c]--;		break;
+	case 1: len[c]++;
+      }
+      for (c=0; c < 16; c+=2) {
+	i = len[((c & 1) << 1) | (c >> 3)];
+        RAW(row,col+c) = ((signed) ph1_bits(i) << (32-i) >> (32-i)) +
+	  (dir ? RAW(row+(~c | -2),col+c) : col ? RAW(row,col+(c | -2)) : 128);
+	if (c == 14) c = -1;
+      }
+    }
+  }
+  for (row=0; row < raw_height-1; row+=2)
+    for (col=0; col < raw_width-1; col+=2)
+      SWAP (RAW(row,col+1), RAW(row+1,col));
+}
+
+void CLASS samsung2_load_raw()
+{
+  static const ushort tab[14] =
+  { 0x304,0x307,0x206,0x205,0x403,0x600,0x709,
+    0x80a,0x90b,0xa0c,0xa0d,0x501,0x408,0x402 };
+  ushort huff[1026], vpred[2][2] = {{0,0},{0,0}}, hpred[2];
+  int i, c, n, row, col, diff;
+
+  huff[0] = 10;
+  for (n=i=0; i < 14; i++)
+    FORC(1024 >> (tab[i] >> 8)) huff[++n] = tab[i];
+  getbits(-1);
+  for (row=0; row < raw_height; row++)
+  {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
+    for (col=0; col < raw_width; col++) {
+      diff = ljpeg_diff (huff);
+      if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
+      else	   hpred[col & 1] += diff;
+      RAW(row,col) = hpred[col & 1];
+      if (hpred[col & 1] >> tiff_bps) derror();
+    }
+  }
+}
+
+void CLASS samsung3_load_raw()
+{
+  int opt, init, mag, pmode, row, tab, col, pred, diff, i, c;
+  ushort lent[3][2], len[4], *prow[2];
+
+  order = 0x4949;
+  fseek (ifp, 9, SEEK_CUR);
+  opt = fgetc(ifp);
+  init = (get2(),get2());
+  for (row=0; row < raw_height; row++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
+    fseek (ifp, (data_offset-ftell(ifp)) & 15, SEEK_CUR);
+    ph1_bits(-1);
+    mag = 0; pmode = 7;
+    FORC(6) lent[0][c] = row < 2 ? 7:4;
+    prow[ row & 1] = &RAW(row-1,1-((row & 1) << 1));	// green
+    prow[~row & 1] = &RAW(row-2,0);			// red and blue
+    for (tab=0; tab+15 < raw_width; tab+=16) {
+      if (~opt & 4 && !(tab & 63)) {
+	i = ph1_bits(2);
+	mag = i < 3 ? mag-'2'+"204"[i] : ph1_bits(12);
+      }
+      if (opt & 2)
+	pmode = 7 - 4*ph1_bits(1);
+      else if (!ph1_bits(1))
+	pmode = ph1_bits(3);
+      if (opt & 1 || !ph1_bits(1)) {
+	FORC4 len[c] = ph1_bits(2);
+	FORC4 {
+	  i = ((row & 1) << 1 | (c & 1)) % 3;
+	  len[c] = len[c] < 3 ? lent[i][0]-'1'+"120"[len[c]] : ph1_bits(4);
+	  lent[i][0] = lent[i][1];
+	  lent[i][1] = len[c];
+	}
+      }
+      FORC(16) {
+	col = tab + (((c & 7) << 1)^(c >> 3)^(row & 1));
+	pred = (pmode == 7 || row < 2)
+	     ? (tab ? RAW(row,tab-2+(col & 1)) : init)
+	     : (prow[col & 1][col-'4'+"0224468"[pmode]] +
+		prow[col & 1][col-'4'+"0244668"[pmode]] + 1) >> 1;
+	diff = ph1_bits (i = len[c >> 2]);
+	if (diff >> (i-1)) diff -= 1 << i;
+	diff = diff * (mag*2+1) + mag;
+	RAW(row,col) = pred + diff;
+      }
+    }
+  }
+}
+
 #define HOLE(row) ((holes >> (((row) - raw_height) & 7)) & 1)
 
 /* Kudos to Rich Taylor for figuring out SMaL's compression algorithm. */
@@ -3054,10 +3437,9 @@ void CLASS smal_decode_segment (unsigned seg[2][2], int holes)
     { 7, 7, 0, 0, 63, 55, 47, 39, 31, 23, 15, 7, 0 },
     { 3, 3, 0, 0, 63,     47,     31,     15,    0 } };
   int low, high=0xff, carry=0, nbits=8;
-  int s, count, bin, next, i, sym[3];
+  int pix, s, count, bin, next, i, sym[3];
   uchar diff, pred[]={0,0};
   ushort data=0, range=0;
-  unsigned pix, row, col;
 
   fseek (ifp, seg[0][1]+1, SEEK_SET);
   getbits(-1);
@@ -3070,7 +3452,7 @@ void CLASS smal_decode_segment (unsigned seg[2][2], int holes)
 	if ((data >> nbits & 0xff) == 0xff) break;
       if (nbits > 0)
 	  data = ((data & ((1 << (nbits-1)) - 1)) << 1) |
-	((data + (((data & (1 << (nbits-1)))) << 1)) & (-1 << nbits));
+            ((data + (((data & (1 << (nbits-1)))) << 1)) & ((~0u) << nbits));
       if (nbits >= 0) {
 	data += getbits(1);
 	carry = nbits - 8;
@@ -3103,17 +3485,8 @@ void CLASS smal_decode_segment (unsigned seg[2][2], int holes)
       diff = diff ? -diff : 0x80;
     if (ftell(ifp) + 12 >= seg[1][1])
       diff = 0;
-    pred[pix & 1] += diff;
-#ifndef LIBRAW_LIBRARY_BUILD
-    row = pix / raw_width - top_margin;
-    col = pix % raw_width - left_margin;
-    if (row < height && col < width)
-            BAYER(row,col) = pred[pix & 1];
-#else
-    row = pix / raw_width - top_margin;
-    RBAYER(pix / raw_width, pix % raw_width) = pred[pix & 1];
-#endif
-    if (!(pix & 1) && HOLE(row)) pix += 2;
+    raw_image[pix] = pred[pix & 1] += diff;
+    if (!(pix & 1) && HOLE(pix / raw_width)) pix += 2;
   }
   maximum = 0xff;
 }
@@ -3150,21 +3523,21 @@ void CLASS fill_holes (int holes)
   for (row=2; row < height-2; row++) {
     if (!HOLE(row)) continue;
     for (col=1; col < width-1; col+=4) {
-      val[0] = BAYER(row-1,col-1);
-      val[1] = BAYER(row-1,col+1);
-      val[2] = BAYER(row+1,col-1);
-      val[3] = BAYER(row+1,col+1);
-      BAYER(row,col) = median4(val);
+      val[0] = RAW(row-1,col-1);
+      val[1] = RAW(row-1,col+1);
+      val[2] = RAW(row+1,col-1);
+      val[3] = RAW(row+1,col+1);
+      RAW(row,col) = median4(val);
     }
     for (col=2; col < width-2; col+=4)
       if (HOLE(row-2) || HOLE(row+2))
-	BAYER(row,col) = (BAYER(row,col-2) + BAYER(row,col+2)) >> 1;
+	RAW(row,col) = (RAW(row,col-2) + RAW(row,col+2)) >> 1;
       else {
-	val[0] = BAYER(row,col-2);
-	val[1] = BAYER(row,col+2);
-	val[2] = BAYER(row-2,col);
-	val[3] = BAYER(row+2,col);
-	BAYER(row,col) = median4(val);
+	val[0] = RAW(row,col-2);
+	val[1] = RAW(row,col+2);
+	val[2] = RAW(row-2,col);
+	val[3] = RAW(row+2,col);
+	RAW(row,col) = median4(val);
       }
   }
 }
@@ -3213,16 +3586,23 @@ void CLASS redcine_load_raw()
   if (!jimg) longjmp (failure, 3);
 #else
   if(!jimg)
-      {
-          jas_stream_close (in);
-          throw LIBRAW_EXCEPTION_DECODE_JPEG2000;
-      }
+    {
+      jas_stream_close (in);
+      throw LIBRAW_EXCEPTION_DECODE_JPEG2000;
+    }
 #endif
   jmat = jas_matrix_create (height/2, width/2);
   merror (jmat, "redcine_load_raw()");
-  img = (ushort *) calloc ((height+2)*(width+2), 2);
+  img = (ushort *) calloc ((height+2), (width+2)*2);
   merror (img, "redcine_load_raw()");
+#ifdef LIBRAW_LIBRARY_BUILD
+  bool fastexitflag = false;
+  try {
+#endif
   FORC4 {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     jas_image_readcmpt (jimg, c, 0, 0, width/2, height/2, jmat);
     data = jas_matrix_getref (jmat, 0, 0);
     for (row = c >> 1; row < height; row+=2)
@@ -3238,6 +3618,9 @@ void CLASS redcine_load_raw()
     img[(row+1)*(width+2)-1] = img[(row+1)*(width+2)-3];
   }
   for (row=1; row <= height; row++) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     pix = img + row*(width+2) + (col = 1 + (FC(row,1) & 1));
     for (   ; col <= width; col+=2, pix+=2) {
       c = (((pix[0] - 0x800) << 3) +
@@ -3246,15 +3629,169 @@ void CLASS redcine_load_raw()
     }
   }
   for (row=0; row < height; row++)
+  {
+#ifdef LIBRAW_LIBRARY_BUILD
+    checkCancel();
+#endif
     for (col=0; col < width; col++)
-      RBAYER(row,col) = curve[img[(row+1)*(width+2)+col+1]];
+      RAW(row,col) = curve[img[(row+1)*(width+2)+col+1]];
+  }
+#ifdef LIBRAW_LIBRARY_BUILD
+  } catch (...) {
+    fastexitflag=true;
+  }
+#endif
   free (img);
   jas_matrix_destroy (jmat);
   jas_image_destroy (jimg);
   jas_stream_close (in);
+#ifdef LIBRAW_LIBRARY_BUILD
+  if(fastexitflag)
+    throw LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK;
+#endif
+#endif
+}
+void CLASS crop_masked_pixels()
+{
+  int row, col;
+  unsigned
+#ifndef LIBRAW_LIBRARY_BUILD
+    r, raw_pitch = raw_width*2,
+    c, m, mblack[8], zero, val;
+#else
+    c, m, zero, val;
+#define mblack imgdata.color.black_stat
+#endif
+
+#ifndef LIBRAW_LIBRARY_BUILD
+  if (load_raw == &CLASS phase_one_load_raw ||
+      load_raw == &CLASS phase_one_load_raw_c)
+    phase_one_correct();
+  if (fuji_width) {
+    for (row=0; row < raw_height-top_margin*2; row++) {
+      for (col=0; col < fuji_width << !fuji_layout; col++) {
+	if (fuji_layout) {
+	  r = fuji_width - 1 - col + (row >> 1);
+	  c = col + ((row+1) >> 1);
+	} else {
+	  r = fuji_width - 1 + row - (col >> 1);
+	  c = row + ((col+1) >> 1);
+	}
+	if (r < height && c < width)
+	  BAYER(r,c) = RAW(row+top_margin,col+left_margin);
+      }
+    }
+  } else {
+    for (row=0; row < height; row++)
+      for (col=0; col < width; col++)
+	BAYER2(row,col) = RAW(row+top_margin,col+left_margin);
+  }
+#endif
+  if (mask[0][3] > 0) goto mask_set;
+  if (load_raw == &CLASS canon_load_raw ||
+      load_raw == &CLASS lossless_jpeg_load_raw) {
+    mask[0][1] = mask[1][1] += 2;
+    mask[0][3] -= 2;
+    goto sides;
+  }
+  if (load_raw == &CLASS canon_600_load_raw ||
+      load_raw == &CLASS sony_load_raw ||
+     (load_raw == &CLASS eight_bit_load_raw && strncmp(model,"DC2",3)) ||
+      load_raw == &CLASS kodak_262_load_raw ||
+     (load_raw == &CLASS packed_load_raw && (load_flags & 32))) {
+sides:
+    mask[0][0] = mask[1][0] = top_margin;
+    mask[0][2] = mask[1][2] = top_margin+height;
+    mask[0][3] += left_margin;
+    mask[1][1] += left_margin+width;
+    mask[1][3] += raw_width;
+  }
+  if (load_raw == &CLASS nokia_load_raw) {
+    mask[0][2] = top_margin;
+    mask[0][3] = width;
+  }
+mask_set:
+  memset (mblack, 0, sizeof mblack);
+  for (zero=m=0; m < 8; m++)
+    for (row=MAX(mask[m][0],0); row < MIN(mask[m][2],raw_height); row++)
+      for (col=MAX(mask[m][1],0); col < MIN(mask[m][3],raw_width); col++) {
+	c = FC(row-top_margin,col-left_margin);
+	mblack[c] += val = raw_image[(row)*raw_pitch/2+(col)];
+	mblack[4+c]++;
+	zero += !val;
+      }
+  if (load_raw == &CLASS canon_600_load_raw && width < raw_width) {
+    black = (mblack[0]+mblack[1]+mblack[2]+mblack[3]) /
+	    (mblack[4]+mblack[5]+mblack[6]+mblack[7]) - 4;
+#ifndef LIBRAW_LIBRARY_BUILD
+    canon_600_correct();
+#endif
+  } else if (zero < mblack[4] && mblack[5] && mblack[6] && mblack[7]) {
+    FORC4 cblack[c] = mblack[c] / mblack[4+c];
+    cblack[4] = cblack[5] = cblack[6] = 0;
+  }
+}
+#ifdef LIBRAW_LIBRARY_BUILD
+#undef mblack
+#endif
+
+void CLASS remove_zeroes()
+{
+  unsigned row, col, tot, n, r, c;
+
+#ifdef LIBRAW_LIBRARY_BUILD
+  RUN_CALLBACK(LIBRAW_PROGRESS_REMOVE_ZEROES,0,2);
+#endif
+
+  for (row=0; row < height; row++)
+    for (col=0; col < width; col++)
+      if (BAYER(row,col) == 0) {
+	tot = n = 0;
+	for (r = row-2; r <= row+2; r++)
+	  for (c = col-2; c <= col+2; c++)
+	    if (r < height && c < width &&
+		FC(r,c) == FC(row,col) && BAYER(r,c))
+	      tot += (n++,BAYER(r,c));
+	if (n) BAYER(row,col) = tot/n;
+      }
+#ifdef LIBRAW_LIBRARY_BUILD
+  RUN_CALLBACK(LIBRAW_PROGRESS_REMOVE_ZEROES,1,2);
 #endif
 }
 
+static const uchar xlat[2][256] = {
+  { 0xc1,0xbf,0x6d,0x0d,0x59,0xc5,0x13,0x9d,0x83,0x61,0x6b,0x4f,0xc7,0x7f,0x3d,0x3d,
+    0x53,0x59,0xe3,0xc7,0xe9,0x2f,0x95,0xa7,0x95,0x1f,0xdf,0x7f,0x2b,0x29,0xc7,0x0d,
+    0xdf,0x07,0xef,0x71,0x89,0x3d,0x13,0x3d,0x3b,0x13,0xfb,0x0d,0x89,0xc1,0x65,0x1f,
+    0xb3,0x0d,0x6b,0x29,0xe3,0xfb,0xef,0xa3,0x6b,0x47,0x7f,0x95,0x35,0xa7,0x47,0x4f,
+    0xc7,0xf1,0x59,0x95,0x35,0x11,0x29,0x61,0xf1,0x3d,0xb3,0x2b,0x0d,0x43,0x89,0xc1,
+    0x9d,0x9d,0x89,0x65,0xf1,0xe9,0xdf,0xbf,0x3d,0x7f,0x53,0x97,0xe5,0xe9,0x95,0x17,
+    0x1d,0x3d,0x8b,0xfb,0xc7,0xe3,0x67,0xa7,0x07,0xf1,0x71,0xa7,0x53,0xb5,0x29,0x89,
+    0xe5,0x2b,0xa7,0x17,0x29,0xe9,0x4f,0xc5,0x65,0x6d,0x6b,0xef,0x0d,0x89,0x49,0x2f,
+    0xb3,0x43,0x53,0x65,0x1d,0x49,0xa3,0x13,0x89,0x59,0xef,0x6b,0xef,0x65,0x1d,0x0b,
+    0x59,0x13,0xe3,0x4f,0x9d,0xb3,0x29,0x43,0x2b,0x07,0x1d,0x95,0x59,0x59,0x47,0xfb,
+    0xe5,0xe9,0x61,0x47,0x2f,0x35,0x7f,0x17,0x7f,0xef,0x7f,0x95,0x95,0x71,0xd3,0xa3,
+    0x0b,0x71,0xa3,0xad,0x0b,0x3b,0xb5,0xfb,0xa3,0xbf,0x4f,0x83,0x1d,0xad,0xe9,0x2f,
+    0x71,0x65,0xa3,0xe5,0x07,0x35,0x3d,0x0d,0xb5,0xe9,0xe5,0x47,0x3b,0x9d,0xef,0x35,
+    0xa3,0xbf,0xb3,0xdf,0x53,0xd3,0x97,0x53,0x49,0x71,0x07,0x35,0x61,0x71,0x2f,0x43,
+    0x2f,0x11,0xdf,0x17,0x97,0xfb,0x95,0x3b,0x7f,0x6b,0xd3,0x25,0xbf,0xad,0xc7,0xc5,
+    0xc5,0xb5,0x8b,0xef,0x2f,0xd3,0x07,0x6b,0x25,0x49,0x95,0x25,0x49,0x6d,0x71,0xc7 },
+  { 0xa7,0xbc,0xc9,0xad,0x91,0xdf,0x85,0xe5,0xd4,0x78,0xd5,0x17,0x46,0x7c,0x29,0x4c,
+    0x4d,0x03,0xe9,0x25,0x68,0x11,0x86,0xb3,0xbd,0xf7,0x6f,0x61,0x22,0xa2,0x26,0x34,
+    0x2a,0xbe,0x1e,0x46,0x14,0x68,0x9d,0x44,0x18,0xc2,0x40,0xf4,0x7e,0x5f,0x1b,0xad,
+    0x0b,0x94,0xb6,0x67,0xb4,0x0b,0xe1,0xea,0x95,0x9c,0x66,0xdc,0xe7,0x5d,0x6c,0x05,
+    0xda,0xd5,0xdf,0x7a,0xef,0xf6,0xdb,0x1f,0x82,0x4c,0xc0,0x68,0x47,0xa1,0xbd,0xee,
+    0x39,0x50,0x56,0x4a,0xdd,0xdf,0xa5,0xf8,0xc6,0xda,0xca,0x90,0xca,0x01,0x42,0x9d,
+    0x8b,0x0c,0x73,0x43,0x75,0x05,0x94,0xde,0x24,0xb3,0x80,0x34,0xe5,0x2c,0xdc,0x9b,
+    0x3f,0xca,0x33,0x45,0xd0,0xdb,0x5f,0xf5,0x52,0xc3,0x21,0xda,0xe2,0x22,0x72,0x6b,
+    0x3e,0xd0,0x5b,0xa8,0x87,0x8c,0x06,0x5d,0x0f,0xdd,0x09,0x19,0x93,0xd0,0xb9,0xfc,
+    0x8b,0x0f,0x84,0x60,0x33,0x1c,0x9b,0x45,0xf1,0xf0,0xa3,0x94,0x3a,0x12,0x77,0x33,
+    0x4d,0x44,0x78,0x28,0x3c,0x9e,0xfd,0x65,0x57,0x16,0x94,0x6b,0xfb,0x59,0xd0,0xc8,
+    0x22,0x36,0xdb,0xd2,0x63,0x98,0x43,0xa1,0x04,0x87,0x86,0xf7,0xa6,0x26,0xbb,0xd6,
+    0x59,0x4d,0xbf,0x6a,0x2e,0xaa,0x2b,0xef,0xe6,0x78,0xb6,0x4e,0xe0,0x2f,0xdc,0x7c,
+    0xbe,0x57,0x19,0x32,0x7e,0x2a,0xd0,0xb8,0xba,0x29,0x00,0x3c,0x52,0x7d,0xa8,0x49,
+    0x3b,0x2d,0xeb,0x25,0x49,0xfa,0xa3,0xaa,0x39,0xa7,0xc5,0xa7,0x50,0x11,0x36,0xfb,
+    0xc6,0x67,0x4a,0xf5,0xa5,0x12,0x65,0x7e,0xb0,0xdf,0xaf,0x4e,0xb3,0x61,0x7f,0x2f } };
 
 void CLASS gamma_curve (double pwr, double ts, int mode, int imax)
 {
@@ -3320,7 +3857,7 @@ void CLASS pseudoinverse (double (*in)[3], double (*out)[3], int size)
 	out[i][j] += work[j][k+3] * in[i][k];
 }
 
-void CLASS cam_xyz_coeff (double cam_xyz[4][3])
+void CLASS cam_xyz_coeff (float _rgb_cam[3][4], double cam_xyz[4][3])
 {
   double cam_rgb[4][3], inverse[4][3], num;
   int i, j, k;
@@ -3333,18 +3870,23 @@ void CLASS cam_xyz_coeff (double cam_xyz[4][3])
   for (i=0; i < colors; i++) {		/* Normalize cam_rgb so that */
     for (num=j=0; j < 3; j++)		/* cam_rgb * (1,1,1) is (1,1,1,1) */
       num += cam_rgb[i][j];
-    for (j=0; j < 3; j++)
-      cam_rgb[i][j] /= num;
-    pre_mul[i] = 1 / num;
+    if(num > 0.00001)
+      {
+        for (j=0; j < 3; j++)
+          cam_rgb[i][j] /= num;
+        pre_mul[i] = 1 / num;
+      }
+    else
+      {
+        for (j=0; j < 3; j++)
+          cam_rgb[i][j] = 0.0;
+        pre_mul[i] = 1.0;
+      }
   }
   pseudoinverse (cam_rgb, inverse, colors);
-  for (raw_color = i=0; i < 3; i++)
+  for (i=0; i < 3; i++)
     for (j=0; j < colors; j++)
-      rgb_cam[i][j] = inverse[j][i];
-#ifdef LIBRAW_LIBRARY_BUILD
-  color_flags.pre_mul_state = LIBRAW_COLORSTATE_CONST;
-  color_flags.rgb_cam_state = LIBRAW_COLORSTATE_CONST;
-#endif
+      _rgb_cam[i][j] = inverse[j][i];
 }
 
 #ifdef COLORCHECK
@@ -3381,8 +3923,8 @@ void CLASS colorcheck()
     { 0.310, 0.316, 9.0 },		// Neutral 3.5
     { 0.310, 0.316, 3.1 } };		// Black
   double gmb_cam[NSQ][4], gmb_xyz[NSQ][3];
-  double inverse[NSQ][3], cam_xyz[4][3], num;
-  int c, i, j, k, sq, row, col, count[4];
+  double inverse[NSQ][3], cam_xyz[4][3], balance[4], num;
+  int c, i, j, k, sq, row, col, pass, count[4];
 
   memset (gmb_cam, 0, sizeof gmb_cam);
   for (sq=0; sq < NSQ; sq++) {
@@ -3391,7 +3933,8 @@ void CLASS colorcheck()
       for (col=cut[sq][2]; col < cut[sq][2]+cut[sq][0]; col++) {
 	c = FC(row,col);
 	if (c >= colors) c -= 2;
-	gmb_cam[sq][c] += BAYER(row,col);
+	gmb_cam[sq][c] += BAYER2(row,col);
+	BAYER2(row,col) = black + (BAYER2(row,col)-black)/2;
 	count[c]++;
       }
     FORCC gmb_cam[sq][c] = gmb_cam[sq][c]/count[c] - black;
@@ -3401,12 +3944,16 @@ void CLASS colorcheck()
 		(1 - gmb_xyY[sq][0] - gmb_xyY[sq][1]) / gmb_xyY[sq][1];
   }
   pseudoinverse (gmb_xyz, inverse, NSQ);
-  for (i=0; i < colors; i++)
-    for (j=0; j < 3; j++)
-      for (cam_xyz[i][j] = k=0; k < NSQ; k++)
-	cam_xyz[i][j] += gmb_cam[k][i] * inverse[k][j];
-  cam_xyz_coeff (cam_xyz);
-#ifdef DCRAW_VERBOSE
+  for (pass=0; pass < 2; pass++) {
+    for (raw_color = i=0; i < colors; i++)
+      for (j=0; j < 3; j++)
+	for (cam_xyz[i][j] = k=0; k < NSQ; k++)
+	  cam_xyz[i][j] += gmb_cam[k][i] * inverse[k][j];
+    cam_xyz_coeff (rgb_cam, cam_xyz);
+    FORCC balance[c] = pre_mul[c] * gmb_cam[20][c];
+    for (sq=0; sq < NSQ; sq++)
+      FORCC gmb_cam[sq][c] *= balance[c];
+  }
   if (verbose) {
     printf ("    { \"%s %s\", %d,\n\t{", make, model, black);
     num = 10000 / (cam_xyz[1][0] + cam_xyz[1][1] + cam_xyz[1][2]);
@@ -3414,7 +3961,6 @@ void CLASS colorcheck()
       printf ("%c%d", (c | j) ? ',':' ', (int) (cam_xyz[c][j] * num + 0.5));
     puts (" } },");
   }
-#endif
 #undef NSQ
 }
 #endif
@@ -3454,7 +4000,7 @@ void CLASS wavelet_denoise()
   if ((nc = colors) == 3 && filters) nc++;
   FORC(nc) {			/* denoise R,G1,B,G3 individually */
     for (i=0; i < size; i++)
-        fimg[i] = 256 * sqrt((double)(image[i][c] << scale));
+      fimg[i] = 256 * sqrt((double)(image[i][c] << scale));
     for (hpass=lev=0; lev < 5; lev++) {
       lpass = size*((lev & 1)+1);
       for (row=0; row < iheight; row++) {
@@ -3500,7 +4046,7 @@ void CLASS wavelet_denoise()
 		window[2][col-1] + window[2][col+1] - blk[~row & 1]*4 )
 	      * mul[row & 1] + (window[1][col] + blk[row & 1]) * 0.5;
 	avg = avg < 0 ? 0 : sqrt(avg);
-	diff = sqrt((double)(BAYER(row,col))) - avg;
+	diff = sqrt((double)BAYER(row,col)) - avg;
 	if      (diff < -thold) diff += thold;
 	else if (diff >  thold) diff -= thold;
 	else diff = 0;
@@ -3533,7 +4079,7 @@ void CLASS wavelet_denoise()
   temp = fimg + size*3;
   if ((nc = colors) == 3 && filters) nc++;
 #ifdef LIBRAW_LIBRARY_BUILD
-#pragma omp parallel default(shared) private(i,col,row,thold,lev,lpass,hpass,temp,c) firstprivate(scale,size) 
+#pragma omp parallel default(shared) private(i,col,row,thold,lev,lpass,hpass,temp,c) firstprivate(scale,size)
 #endif
   {
       temp = (float*)malloc( (iheight + iwidth) * sizeof *fimg);
@@ -3619,8 +4165,6 @@ void CLASS wavelet_denoise()
 
 #endif
 
-
-
 // green equilibration
 void CLASS green_matching()
 {
@@ -3667,11 +4211,10 @@ void CLASS green_matching()
   free(img);
 }
 
-
 void CLASS scale_colors()
 {
-  unsigned bottom, right, size, row, col, ur, uc, x, y, c, sum[8];
-  int val, dark, sat,i;
+  unsigned bottom, right, size, row, col, ur, uc, i, x, y, c, sum[8];
+  int val, dark, sat;
   double dsum[8], dmin, dmax;
   float scale_mul[4], fr, fc;
   ushort *img=0, *pix;
@@ -3680,7 +4223,6 @@ void CLASS scale_colors()
   RUN_CALLBACK(LIBRAW_PROGRESS_SCALE_COLORS,0,2);
 #endif
 
-  FORC4 cblack[c] += black;
   if (user_mul[0])
     memcpy (pre_mul, user_mul, sizeof pre_mul);
   if (use_auto_wb || (use_camera_wb && cam_mul[0] == -1)) {
@@ -3694,8 +4236,8 @@ void CLASS scale_colors()
 	  for (x=col; x < col+8 && x < right; x++)
 	    FORC4 {
 	      if (filters) {
-		c = FC(y,x);
-		val = BAYER(y,x);
+		c = fcol(y,x);
+		val = BAYER2(y,x);
 	      } else
 		val = image[y*width+x][c];
 	      if (val > maximum-25) goto skip_block;
@@ -3708,9 +4250,6 @@ void CLASS scale_colors()
 skip_block: ;
       }
     FORC4 if (dsum[c]) pre_mul[c] = dsum[c+4] / dsum[c];
-#ifdef LIBRAW_LIBRARY_BUILD
-    color_flags.pre_mul_state = LIBRAW_COLORSTATE_CALCULATED;
-#endif
   }
   if (use_camera_wb && cam_mul[0] != -1) {
     memset (sum, 0, sizeof sum);
@@ -3721,30 +4260,39 @@ skip_block: ;
 	  sum[c] += val;
 	sum[c+4]++;
       }
-    if (sum[0] && sum[1] && sum[2] && sum[3])
-        {
-            FORC4 pre_mul[c] = (float) sum[c+4] / sum[c];
 #ifdef LIBRAW_LIBRARY_BUILD
-            color_flags.pre_mul_state = LIBRAW_COLORSTATE_CALCULATED;
+    if(load_raw == &LibRaw::nikon_load_sraw)
+      {
+        // Nikon sRAW: camera WB already applied:
+        pre_mul[0]=pre_mul[1]=pre_mul[2]=pre_mul[3]=1.0;
+      }
+    else
 #endif
-        }
+    if (sum[0] && sum[1] && sum[2] && sum[3])
+      FORC4 pre_mul[c] = (float) sum[c+4] / sum[c];
     else if (cam_mul[0] && cam_mul[2])
-        {
-            memcpy (pre_mul, cam_mul, sizeof pre_mul);
-#ifdef LIBRAW_LIBRARY_BUILD
-            color_flags.pre_mul_state =color_flags.pre_mul_state;
-#endif
-        }
+      memcpy (pre_mul, cam_mul, sizeof pre_mul);
     else
-        {
+      {
 #ifdef LIBRAW_LIBRARY_BUILD
             imgdata.process_warnings |= LIBRAW_WARN_BAD_CAMERA_WB;
 #endif
 #ifdef DCRAW_VERBOSE
             fprintf (stderr,_("%s: Cannot use camera white balance.\n"), ifname);
 #endif
-        }
+      }
+  }
+#ifdef LIBRAW_LIBRARY_BUILD
+  // Nikon sRAW, daylight
+  if (load_raw == &LibRaw::nikon_load_sraw
+      && !use_camera_wb && !use_auto_wb
+      && cam_mul[0] > 0.001f && cam_mul[1] > 0.001f && cam_mul[2] > 0.001f )
+    {
+      for(c=0;c<3;c++)
+        pre_mul[c]/=cam_mul[c];
   }
+#endif
+  if (pre_mul[1] == 0) pre_mul[1] = 1;
   if (pre_mul[3] == 0) pre_mul[3] = colors < 4 ? pre_mul[1] : 1;
   dark = black;
   sat = maximum;
@@ -3766,18 +4314,25 @@ skip_block: ;
     fputc ('\n', stderr);
   }
 #endif
-
+  if (filters > 1000 && (cblack[4]+1)/2 == 1 && (cblack[5]+1)/2 == 1) {
+    FORC4 cblack[FC(c/2,c%2)] +=
+	cblack[6 + c/2 % cblack[4] * cblack[5] + c%2 % cblack[5]];
+    cblack[4] = cblack[5] = 0;
+  }
   size = iheight*iwidth;
-#if defined(LIBRAW_USE_OPENMP)
-#pragma omp parallel for private(val) default(shared)
-#endif
+#ifdef LIBRAW_LIBRARY_BUILD
+  scale_colors_loop(scale_mul);
+#else
   for (i=0; i < size*4; i++) {
-    val = image[0][i];
-    if (!val) continue;
+    if (!(val = image[0][i])) continue;
+    if (cblack[4] && cblack[5])
+      val -= cblack[6 + i/4 / iwidth % cblack[4] * cblack[5] +
+			i/4 % iwidth % cblack[5]];
     val -= cblack[i & 3];
     val *= scale_mul[i & 3];
     image[0][i] = CLIP(val);
   }
+#endif
   if ((aber[0] != 1 || aber[2] != 1) && colors == 3) {
 #ifdef DCRAW_VERBOSE
     if (verbose)
@@ -3815,7 +4370,6 @@ void CLASS pre_interpolate()
 {
   ushort (*img)[4];
   int row, col, c;
-
 #ifdef LIBRAW_LIBRARY_BUILD
   RUN_CALLBACK(LIBRAW_PROGRESS_PRE_INTERPOLATE,0,2);
 #endif
@@ -3823,12 +4377,24 @@ void CLASS pre_interpolate()
     if (half_size) {
       height = iheight;
       width  = iwidth;
+      if (filters == 9) {
+	for (row=0; row < 3; row++)
+	  for (col=1; col < 4; col++)
+	    if (!(image[row*width+col][0] | image[row*width+col][2]))
+	      goto break2;  break2:
+	for ( ; row < height; row+=3)
+	  for (col=(col-1)%3+1; col < width-1; col+=3) {
+	    img = image + row*width+col;
+	    for (c=0; c < 3; c+=2)
+	      img[0][c] = (img[-1][c] + img[1][c]) >> 1;
+	  }
+      }
     } else {
-      img = (ushort (*)[4]) calloc (height*width, sizeof *img);
+      img = (ushort (*)[4]) calloc (height, width*sizeof *img);
       merror (img, "pre_interpolate()");
       for (row=0; row < height; row++)
 	for (col=0; col < width; col++) {
-	  c = fc(row,col);
+	  c = fcol(row,col);
 	  img[row*width+col][c] = image[(row >> 1)*iwidth+(col >> 1)][c];
 	}
       free (image);
@@ -3836,9 +4402,9 @@ void CLASS pre_interpolate()
       shrink = 0;
     }
   }
-  if (filters && colors == 3) {
-    if (four_color_rgb && colors++)
-      mix_green = !half_size;
+  if (filters > 1000 && colors == 3) {
+    mix_green = four_color_rgb ^ half_size;
+    if (four_color_rgb | half_size) colors++;
     else {
       for (row = FC(1,0) >> 1; row < height; row+=2)
 	for (col = FC(row,1) & 1; col < width; col+=2)
@@ -3864,63 +4430,78 @@ void CLASS border_interpolate (int border)
       for (y=row-1; y != row+2; y++)
 	for (x=col-1; x != col+2; x++)
 	  if (y < height && x < width) {
-	    f = fc(y,x);
+	    f = fcol(y,x);
 	    sum[f] += image[y*width+x][f];
 	    sum[f+4]++;
 	  }
-      f = fc(row,col);
+      f = fcol(row,col);
       FORCC if (c != f && sum[c+4])
 	image[row*width+col][c] = sum[c] / sum[c+4];
     }
 }
 
+void CLASS lin_interpolate_loop(int code[16][16][32],int size)
+{
+  int row;
+  for (row=1; row < height-1; row++)
+    {
+      int col,*ip;
+      ushort *pix;
+      for (col=1; col < width-1; col++) {
+        int i;
+        int sum[4];
+        pix = image[row*width+col];
+        ip = code[row % size][col % size];
+        memset (sum, 0, sizeof sum);
+        for (i=*ip++; i--; ip+=3)
+          sum[ip[2]] += pix[ip[0]] << ip[1];
+        for (i=colors; --i; ip+=2)
+          pix[ip[0]] = sum[ip[0]] * ip[1] >> 8;
+      }
+    }
+}
+
 void CLASS lin_interpolate()
 {
-  int code[16][16][32], *ip, sum[4];
-  int c, i, x, y, row, col, shift, color;
-  ushort *pix;
+  int code[16][16][32], size=16, *ip, sum[4];
+  int f, c, x, y, row, col, shift, color;
+
 
 #ifdef DCRAW_VERBOSE
   if (verbose) fprintf (stderr,_("Bilinear interpolation...\n"));
 #endif
-
 #ifdef LIBRAW_LIBRARY_BUILD
   RUN_CALLBACK(LIBRAW_PROGRESS_INTERPOLATE,0,3);
 #endif
+
+  if (filters == 9) size = 6;
   border_interpolate(1);
-  for (row=0; row < 16; row++)
-    for (col=0; col < 16; col++) {
-      ip = code[row][col];
+  for (row=0; row < size; row++)
+    for (col=0; col < size; col++) {
+      ip = code[row][col]+1;
+      f = fcol(row,col);
       memset (sum, 0, sizeof sum);
       for (y=-1; y <= 1; y++)
 	for (x=-1; x <= 1; x++) {
 	  shift = (y==0) + (x==0);
-	  if (shift == 2) continue;
-	  color = fc(row+y,col+x);
+	  color = fcol(row+y,col+x);
+	  if (color == f) continue;
 	  *ip++ = (width*y + x)*4 + color;
 	  *ip++ = shift;
 	  *ip++ = color;
 	  sum[color] += 1 << shift;
 	}
+      code[row][col][0] = (ip - code[row][col]) / 3;
       FORCC
-	if (c != fc(row,col)) {
+	if (c != f) {
 	  *ip++ = c;
-	  *ip++ = 256 / sum[c];
+	  *ip++ = sum[c]>0?256 / sum[c]:0;
 	}
     }
 #ifdef LIBRAW_LIBRARY_BUILD
   RUN_CALLBACK(LIBRAW_PROGRESS_INTERPOLATE,1,3);
 #endif
-  for (row=1; row < height-1; row++)
-    for (col=1; col < width-1; col++) {
-      pix = image[row*width+col];
-      ip = code[row & 15][col & 15];
-      memset (sum, 0, sizeof sum);
-      for (i=8; i--; ip+=3)
-	sum[ip[2]] += pix[ip[0]] << ip[1];
-      for (i=colors; --i; ip+=2)
-	pix[ip[0]] = sum[ip[0]] * ip[1] >> 8;
-    }
+  lin_interpolate_loop(code,size);
 #ifdef LIBRAW_LIBRARY_BUILD
   RUN_CALLBACK(LIBRAW_PROGRESS_INTERPOLATE,2,3);
 #endif
@@ -3963,28 +4544,30 @@ void CLASS vng_interpolate()
     +1,+0,+2,+1,0,0x10
   }, chood[] = { -1,-1, -1,0, -1,+1, 0,+1, +1,+1, +1,0, +1,-1, 0,-1 };
   ushort (*brow[5])[4], *pix;
-  int prow=7, pcol=1, *ip, *code[16][16], gval[8], gmin, gmax, sum[4];
+  int prow=8, pcol=2, *ip, *code[16][16], gval[8], gmin, gmax, sum[4];
   int row, col, x, y, x1, x2, y1, y2, t, weight, grads, color, diag;
   int g, diff, thold, num, c;
+
   lin_interpolate();
 #ifdef DCRAW_VERBOSE
   if (verbose) fprintf (stderr,_("VNG interpolation...\n"));
 #endif
 
-  if (filters == 1) prow = pcol = 15;
-  ip = (int *) calloc ((prow+1)*(pcol+1), 1280);
+  if (filters == 1) prow = pcol = 16;
+  if (filters == 9) prow = pcol =  6;
+  ip = (int *) calloc (prow*pcol, 1280);
   merror (ip, "vng_interpolate()");
-  for (row=0; row <= prow; row++)		/* Precalculate for VNG */
-    for (col=0; col <= pcol; col++) {
+  for (row=0; row < prow; row++)		/* Precalculate for VNG */
+    for (col=0; col < pcol; col++) {
       code[row][col] = ip;
       for (cp=terms, t=0; t < 64; t++) {
 	y1 = *cp++;  x1 = *cp++;
 	y2 = *cp++;  x2 = *cp++;
 	weight = *cp++;
 	grads = *cp++;
-	color = fc(row+y1,col+x1);
-	if (fc(row+y2,col+x2) != color) continue;
-	diag = (fc(row,col+1) == color && fc(row+1,col) == color) ? 2:1;
+	color = fcol(row+y1,col+x1);
+	if (fcol(row+y2,col+x2) != color) continue;
+	diag = (fcol(row,col+1) == color && fcol(row+1,col) == color) ? 2:1;
 	if (abs(y1-y2) == diag && abs(x1-x2) == diag) continue;
 	*ip++ = (y1*width + x1)*4 + color;
 	*ip++ = (y2*width + x2)*4 + color;
@@ -3997,8 +4580,8 @@ void CLASS vng_interpolate()
       for (cp=chood, g=0; g < 8; g++) {
 	y = *cp++;  x = *cp++;
 	*ip++ = (y*width + x) * 4;
-	color = fc(row,col);
-	if (fc(row+y,col+x) != color && fc(row+y*2,col+x*2) == color)
+	color = fcol(row,col);
+	if (fcol(row+y,col+x) != color && fcol(row+y*2,col+x*2) == color)
 	  *ip++ = (y*width + x) * 8 + color;
 	else
 	  *ip++ = 0;
@@ -4014,7 +4597,7 @@ void CLASS vng_interpolate()
 #endif
     for (col=2; col < width-2; col++) {
       pix = image[row*width+col];
-      ip = code[row & prow][col & pcol];
+      ip = code[row % prow][col % pcol];
       memset (gval, 0, sizeof gval);
       while ((g = ip[0]) != INT_MAX) {		/* Calculate gradients */
 	diff = ABS(pix[g] - pix[ip[1]]) << ip[2];
@@ -4037,7 +4620,7 @@ void CLASS vng_interpolate()
       }
       thold = gmin + (gmax >> 1);
       memset (sum, 0, sizeof sum);
-      color = fc(row,col);
+      color = fcol(row,col);
       for (num=g=0; g < 8; g++,ip+=2) {		/* Average the neighbors */
 	if (gval[g] <= thold) {
 	  FORCC
@@ -4140,29 +4723,290 @@ void CLASS ppg_interpolate()
     }
 }
 
-/*
-   Adaptive Homogeneity-Directed interpolation is based on
-   the work of Keigo Hirakawa, Thomas Parks, and Paul Lee.
- */
-#define TS 256		/* Tile Size */
-static float dcraw_cbrt[0x10000] = {-1.0f};
-
-static inline float calc_64cbrt(float f)
+void CLASS cielab (ushort rgb[3], short lab[3])
 {
-  unsigned u;
-  static float lower = dcraw_cbrt[0];
-  static float upper = dcraw_cbrt[0xffff];
-
-  if (f <= 0) {
-    return lower;
-  }
+  int c, i, j, k;
+  float r, xyz[3];
+#ifdef LIBRAW_NOTHREADS
+  static float cbrt[0x10000], xyz_cam[3][4];
+#else
+#define cbrt tls->ahd_data.cbrt
+#define xyz_cam tls->ahd_data.xyz_cam
+#endif
 
-  u = (unsigned) f;
-  if (u >= 0xffff) {
-    return upper;
+  if (!rgb) {
+#ifndef LIBRAW_NOTHREADS
+    if(cbrt[0] < -1.0f)
+#endif
+    for (i=0; i < 0x10000; i++) {
+      r = i / 65535.0;
+      cbrt[i] = r > 0.008856 ? pow(r,1.f/3.0f) : 7.787f*r + 16.f/116.0f;
+    }
+    for (i=0; i < 3; i++)
+      for (j=0; j < colors; j++)
+	for (xyz_cam[i][j] = k=0; k < 3; k++)
+	  xyz_cam[i][j] += xyz_rgb[i][k] * rgb_cam[k][j] / d65_white[i];
+    return;
   }
-  return dcraw_cbrt[u];
+  xyz[0] = xyz[1] = xyz[2] = 0.5;
+  FORCC {
+    xyz[0] += xyz_cam[0][c] * rgb[c];
+    xyz[1] += xyz_cam[1][c] * rgb[c];
+    xyz[2] += xyz_cam[2][c] * rgb[c];
+  }
+  xyz[0] = cbrt[CLIP((int) xyz[0])];
+  xyz[1] = cbrt[CLIP((int) xyz[1])];
+  xyz[2] = cbrt[CLIP((int) xyz[2])];
+  lab[0] = 64 * (116 * xyz[1] - 16);
+  lab[1] = 64 * 500 * (xyz[0] - xyz[1]);
+  lab[2] = 64 * 200 * (xyz[1] - xyz[2]);
+#ifndef LIBRAW_NOTHREADS
+#undef cbrt
+#undef xyz_cam
+#endif
+}
+
+#define TS 512		/* Tile Size */
+#define fcol(row,col) xtrans[(row+6) % 6][(col+6) % 6]
+
+/*
+   Frank Markesteijn's algorithm for Fuji X-Trans sensors
+ */
+void CLASS xtrans_interpolate (int passes)
+{
+  int c, d, f, g, h, i, v, ng, row, col, top, left, mrow, mcol;
+  int val, ndir, pass, hm[8], avg[4], color[3][8];
+  static const short orth[12] = { 1,0,0,1,-1,0,0,-1,1,0,0,1 },
+	patt[2][16] = { { 0,1,0,-1,2,0,-1,0,1,1,1,-1,0,0,0,0 },
+			{ 0,1,0,-2,1,0,-2,0,1,1,-2,-2,1,-1,-1,1 } },
+	dir[4] = { 1,TS,TS+1,TS-1 };
+  short allhex[3][3][2][8], *hex;
+  ushort min, max, sgrow, sgcol;
+  ushort (*rgb)[TS][TS][3], (*rix)[3], (*pix)[4];
+   short (*lab)    [TS][3], (*lix)[3];
+   float (*drv)[TS][TS], diff[6], tr;
+   char (*homo)[TS][TS], *buffer;
+
+#ifdef DCRAW_VERBOSE
+  if (verbose)
+    fprintf (stderr,_("%d-pass X-Trans interpolation...\n"), passes);
+#endif
+
+  cielab (0,0);
+  ndir = 4 << (passes > 1);
+  buffer = (char *) malloc (TS*TS*(ndir*11+6));
+  merror (buffer, "xtrans_interpolate()");
+  rgb  = (ushort(*)[TS][TS][3]) buffer;
+  lab  = (short (*)    [TS][3])(buffer + TS*TS*(ndir*6));
+  drv  = (float (*)[TS][TS])   (buffer + TS*TS*(ndir*6+6));
+  homo = (char  (*)[TS][TS])   (buffer + TS*TS*(ndir*10+6));
+
+/* Map a green hexagon around each non-green pixel and vice versa:	*/
+  for (row=0; row < 3; row++)
+    for (col=0; col < 3; col++)
+      for (ng=d=0; d < 10; d+=2) {
+	g = fcol(row,col) == 1;
+	if (fcol(row+orth[d],col+orth[d+2]) == 1) ng=0; else ng++;
+	if (ng == 4) { sgrow = row; sgcol = col; }
+	if (ng == g+1) FORC(8) {
+	  v = orth[d  ]*patt[g][c*2] + orth[d+1]*patt[g][c*2+1];
+	  h = orth[d+2]*patt[g][c*2] + orth[d+3]*patt[g][c*2+1];
+	  allhex[row][col][0][c^(g*2 & d)] = h + v*width;
+	  allhex[row][col][1][c^(g*2 & d)] = h + v*TS;
+	}
+      }
+
+/* Set green1 and green3 to the minimum and maximum allowed values:	*/
+  for (row=2; row < height-2; row++)
+    for (min=~(max=0), col=2; col < width-2; col++) {
+      if (fcol(row,col) == 1 && (min=~(max=0))) continue;
+      pix = image + row*width + col;
+      hex = allhex[row % 3][col % 3][0];
+      if (!max) FORC(6) {
+	val = pix[hex[c]][1];
+	if (min > val) min = val;
+	if (max < val) max = val;
+      }
+      pix[0][1] = min;
+      pix[0][3] = max;
+      switch ((row-sgrow) % 3) {
+	case 1: if (row < height-3) { row++; col--; } break;
+	case 2: if ((min=~(max=0)) && (col+=2) < width-3 && row > 2) row--;
+      }
+    }
+
+  for (top=3; top < height-19; top += TS-16)
+    for (left=3; left < width-19; left += TS-16) {
+      mrow = MIN (top+TS, height-3);
+      mcol = MIN (left+TS, width-3);
+      for (row=top; row < mrow; row++)
+	for (col=left; col < mcol; col++)
+	  memcpy (rgb[0][row-top][col-left], image[row*width+col], 6);
+      FORC3 memcpy (rgb[c+1], rgb[0], sizeof *rgb);
+
+/* Interpolate green horizontally, vertically, and along both diagonals: */
+      for (row=top; row < mrow; row++)
+	for (col=left; col < mcol; col++) {
+	  if ((f = fcol(row,col)) == 1) continue;
+	  pix = image + row*width + col;
+	  hex = allhex[row % 3][col % 3][0];
+	  color[1][0] = 174 * (pix[  hex[1]][1] + pix[  hex[0]][1]) -
+			 46 * (pix[2*hex[1]][1] + pix[2*hex[0]][1]);
+	  color[1][1] = 223 *  pix[  hex[3]][1] + pix[  hex[2]][1] * 33 +
+			 92 * (pix[      0 ][f] - pix[ -hex[2]][f]);
+	  FORC(2) color[1][2+c] =
+		164 * pix[hex[4+c]][1] + 92 * pix[-2*hex[4+c]][1] + 33 *
+		(2*pix[0][f] - pix[3*hex[4+c]][f] - pix[-3*hex[4+c]][f]);
+	  FORC4 rgb[c^!((row-sgrow) % 3)][row-top][col-left][1] =
+		LIM(color[1][c] >> 8,pix[0][1],pix[0][3]);
+	}
+
+      for (pass=0; pass < passes; pass++) {
+	if (pass == 1)
+	  memcpy (rgb+=4, buffer, 4*sizeof *rgb);
+
+/* Recalculate green from interpolated values of closer pixels:	*/
+	if (pass) {
+	  for (row=top+2; row < mrow-2; row++)
+	    for (col=left+2; col < mcol-2; col++) {
+	      if ((f = fcol(row,col)) == 1) continue;
+	      pix = image + row*width + col;
+	      hex = allhex[row % 3][col % 3][1];
+	      for (d=3; d < 6; d++) {
+		rix = &rgb[(d-2)^!((row-sgrow) % 3)][row-top][col-left];
+		val = rix[-2*hex[d]][1] + 2*rix[hex[d]][1]
+		    - rix[-2*hex[d]][f] - 2*rix[hex[d]][f] + 3*rix[0][f];
+		rix[0][1] = LIM(val/3,pix[0][1],pix[0][3]);
+	      }
+	    }
+	}
+
+/* Interpolate red and blue values for solitary green pixels:	*/
+	for (row=(top-sgrow+4)/3*3+sgrow; row < mrow-2; row+=3)
+	  for (col=(left-sgcol+4)/3*3+sgcol; col < mcol-2; col+=3) {
+	    rix = &rgb[0][row-top][col-left];
+	    h = fcol(row,col+1);
+	    memset (diff, 0, sizeof diff);
+	    for (i=1, d=0; d < 6; d++, i^=TS^1, h^=2) {
+	      for (c=0; c < 2; c++, h^=2) {
+		g = 2*rix[0][1] - rix[i<<c][1] - rix[-i<<c][1];
+		color[h][d] = g + rix[i<<c][h] + rix[-i<<c][h];
+		if (d > 1)
+		  diff[d] += SQR (rix[i<<c][1] - rix[-i<<c][1]
+				- rix[i<<c][h] + rix[-i<<c][h]) + SQR(g);
+	      }
+	      if (d > 1 && (d & 1))
+		if (diff[d-1] < diff[d])
+		  FORC(2) color[c*2][d] = color[c*2][d-1];
+	      if (d < 2 || (d & 1)) {
+		FORC(2) rix[0][c*2] = CLIP(color[c*2][d]/2);
+		rix += TS*TS;
+	      }
+	    }
+	  }
+
+/* Interpolate red for blue pixels and vice versa:		*/
+	for (row=top+3; row < mrow-3; row++)
+	  for (col=left+3; col < mcol-3; col++) {
+	    if ((f = 2-fcol(row,col)) == 1) continue;
+	    rix = &rgb[0][row-top][col-left];
+	    c = (row-sgrow) % 3 ? TS:1;
+	    h = 3 * (c ^ TS ^ 1);
+	    for (d=0; d < 4; d++, rix += TS*TS) {
+	      i = d > 1 || ((d ^ c) & 1) ||
+		 ((ABS(rix[0][1]-rix[c][1])+ABS(rix[0][1]-rix[-c][1])) <
+		2*(ABS(rix[0][1]-rix[h][1])+ABS(rix[0][1]-rix[-h][1]))) ? c:h;
+	      rix[0][f] = CLIP((rix[i][f] + rix[-i][f] +
+		  2*rix[0][1] - rix[i][1] - rix[-i][1])/2);
+	    }
+	  }
+
+/* Fill in red and blue for 2x2 blocks of green:		*/
+	for (row=top+2; row < mrow-2; row++) if ((row-sgrow) % 3)
+	  for (col=left+2; col < mcol-2; col++) if ((col-sgcol) % 3) {
+	    rix = &rgb[0][row-top][col-left];
+	    hex = allhex[row % 3][col % 3][1];
+	    for (d=0; d < ndir; d+=2, rix += TS*TS)
+	      if (hex[d] + hex[d+1]) {
+		g = 3*rix[0][1] - 2*rix[hex[d]][1] - rix[hex[d+1]][1];
+		for (c=0; c < 4; c+=2) rix[0][c] =
+			CLIP((g + 2*rix[hex[d]][c] + rix[hex[d+1]][c])/3);
+	      } else {
+		g = 2*rix[0][1] - rix[hex[d]][1] - rix[hex[d+1]][1];
+		for (c=0; c < 4; c+=2) rix[0][c] =
+			CLIP((g + rix[hex[d]][c] + rix[hex[d+1]][c])/2);
+	      }
+	  }
+      }
+      rgb = (ushort(*)[TS][TS][3]) buffer;
+      mrow -= top;
+      mcol -= left;
+
+/* Convert to CIELab and differentiate in all directions:	*/
+      for (d=0; d < ndir; d++) {
+	for (row=2; row < mrow-2; row++)
+	  for (col=2; col < mcol-2; col++)
+	    cielab (rgb[d][row][col], lab[row][col]);
+	for (f=dir[d & 3],row=3; row < mrow-3; row++)
+	  for (col=3; col < mcol-3; col++) {
+	    lix = &lab[row][col];
+	    g = 2*lix[0][0] - lix[f][0] - lix[-f][0];
+	    drv[d][row][col] = SQR(g)
+	      + SQR((2*lix[0][1] - lix[f][1] - lix[-f][1] + g*500/232))
+	      + SQR((2*lix[0][2] - lix[f][2] - lix[-f][2] - g*500/580));
+	  }
+      }
+
+/* Build homogeneity maps from the derivatives:			*/
+      memset(homo, 0, ndir*TS*TS);
+      for (row=4; row < mrow-4; row++)
+	for (col=4; col < mcol-4; col++) {
+	  for (tr=FLT_MAX, d=0; d < ndir; d++)
+	    if (tr > drv[d][row][col])
+		tr = drv[d][row][col];
+	  tr *= 8;
+	  for (d=0; d < ndir; d++)
+	    for (v=-1; v <= 1; v++)
+	      for (h=-1; h <= 1; h++)
+		if (drv[d][row+v][col+h] <= tr)
+		  homo[d][row][col]++;
+	}
+
+/* Average the most homogenous pixels for the final result:	*/
+      if (height-top < TS+4) mrow = height-top+2;
+      if (width-left < TS+4) mcol = width-left+2;
+      for (row = MIN(top,8); row < mrow-8; row++)
+	for (col = MIN(left,8); col < mcol-8; col++) {
+	  for (d=0; d < ndir; d++)
+	    for (hm[d]=0, v=-2; v <= 2; v++)
+	      for (h=-2; h <= 2; h++)
+		hm[d] += homo[d][row+v][col+h];
+	  for (d=0; d < ndir-4; d++)
+	    if (hm[d] < hm[d+4]) hm[d  ] = 0; else
+	    if (hm[d] > hm[d+4]) hm[d+4] = 0;
+	  for (max=hm[0],d=1; d < ndir; d++)
+	    if (max < hm[d]) max = hm[d];
+	  max -= max >> 3;
+	  memset (avg, 0, sizeof avg);
+	  for (d=0; d < ndir; d++)
+	    if (hm[d] >= max) {
+	      FORC3 avg[c] += rgb[d][row][col][c];
+	      avg[3]++;
+	    }
+	  FORC3 image[(row+top)*width+col+left][c] = avg[c]/avg[3];
+	}
+    }
+  free(buffer);
+  border_interpolate(8);
 }
+#undef fcol
+
+/*
+   Adaptive Homogeneity-Directed interpolation is based on
+   the work of Keigo Hirakawa, Thomas Parks, and Paul Lee.
+ */
+#ifdef LIBRAW_LIBRARY_BUILD
+
 void CLASS ahd_interpolate_green_h_and_v(int top, int left, ushort (*out_rgb)[TS][TS][3])
 {
   int row, col;
@@ -4184,7 +5028,7 @@ void CLASS ahd_interpolate_green_h_and_v(int top, int left, ushort (*out_rgb)[TS
     }
   }
 }
-void CLASS ahd_interpolate_r_and_b_in_rgb_and_convert_to_cielab(int top, int left, ushort (*inout_rgb)[TS][3], short (*out_lab)[TS][3], const float (&xyz_cam)[3][4])
+void CLASS ahd_interpolate_r_and_b_in_rgb_and_convert_to_cielab(int top, int left, ushort (*inout_rgb)[TS][3], short (*out_lab)[TS][3])
 {
   unsigned row, col;
   int c, val;
@@ -4232,32 +5076,18 @@ void CLASS ahd_interpolate_r_and_b_in_rgb_and_convert_to_cielab(int top, int lef
       rix[0][c] = CLIP(val);
       c = FC(row,col);
       rix[0][c] = pix[0][c];
-      xyz[0] = xyz[1] = xyz[2] = 0.5;
-      FORC3 {
-	/*
-	 * Technically this ought to be FORCC, but the rest of
-	 * ahd_interpolate() assumes 3 colors so let's help the compiler.
-	 */
-        xyz[0] += xyz_cam[0][c] * rix[0][c];
-        xyz[1] += xyz_cam[1][c] * rix[0][c];
-        xyz[2] += xyz_cam[2][c] * rix[0][c];
-      }
-      FORC3 {
-	xyz[c] = calc_64cbrt(xyz[c]);
-      }
-      lix[0][0] = (116 * xyz[1] - 16);
-      lix[0][1] = 500 * (xyz[0] - xyz[1]);
-      lix[0][2] = 200 * (xyz[1] - xyz[2]);
+      cielab(rix[0],lix[0]);
     }
   }
 }
-void CLASS ahd_interpolate_r_and_b_and_convert_to_cielab(int top, int left, ushort (*inout_rgb)[TS][TS][3], short (*out_lab)[TS][TS][3], const float (&xyz_cam)[3][4])
+void CLASS ahd_interpolate_r_and_b_and_convert_to_cielab(int top, int left, ushort (*inout_rgb)[TS][TS][3], short (*out_lab)[TS][TS][3])
 {
   int direction;
   for (direction = 0; direction < 2; direction++) {
-    ahd_interpolate_r_and_b_in_rgb_and_convert_to_cielab(top, left, inout_rgb[direction], out_lab[direction], xyz_cam);
+    ahd_interpolate_r_and_b_in_rgb_and_convert_to_cielab(top, left, inout_rgb[direction], out_lab[direction]);
   }
 }
+
 void CLASS ahd_interpolate_build_homogeneity_map(int top, int left, short (*lab)[TS][TS][3], char (*out_homogeneity_map)[TS][2])
 {
   int row, col;
@@ -4368,26 +5198,8 @@ void CLASS ahd_interpolate()
   char (*homo)[TS][2];
   int terminate_flag = 0;
 
-  if(dcraw_cbrt[0]<-0.1){
-      for (i=0x10000-1; i >=0; i--) {
-          r = i / 65535.0;
-          dcraw_cbrt[i] = 64.0*(r > 0.008856 ? pow((double)r,1/3.0) : 7.787*r + 16/116.0);
-      }
-  }
-
-#ifdef DCRAW_VERBOSE
-  if (verbose) fprintf (stderr,_("AHD interpolation...\n"));
-#endif
-
-  for (i=0; i < 3; i++) {
-    for (j=0; j < colors; j++) {
-      xyz_cam[i][j] = 0;
-      for (k=0; k < 3; k++) {
-        xyz_cam[i][j] += xyz_rgb[i][k] * rgb_cam[k][j] / d65_white[i];
-      }
-    }
-  }
 
+  cielab(0,0);
   border_interpolate(5);
 
 #ifdef LIBRAW_LIBRARY_BUILD
@@ -4412,7 +5224,7 @@ void CLASS ahd_interpolate()
 #ifdef LIBRAW_USE_OPENMP
         if(0== omp_get_thread_num())
 #endif
-           if(callbacks.progress_cb) {                                     
+           if(callbacks.progress_cb) {
                int rr = (*callbacks.progress_cb)(callbacks.progresscb_data,LIBRAW_PROGRESS_INTERPOLATE,top-2,height-7);
                if(rr)
                    terminate_flag = 1;
@@ -4420,21 +5232,126 @@ void CLASS ahd_interpolate()
 #endif
         for (left=2; !terminate_flag && (left < width-5); left += TS-6) {
             ahd_interpolate_green_h_and_v(top, left, rgb);
-            ahd_interpolate_r_and_b_and_convert_to_cielab(top, left, rgb, lab, xyz_cam);
+            ahd_interpolate_r_and_b_and_convert_to_cielab(top, left, rgb, lab);
             ahd_interpolate_build_homogeneity_map(top, left, lab, homo);
             ahd_interpolate_combine_homogeneous_pixels(top, left, rgb, homo);
       }
     }
     free (buffer);
   }
-#ifdef LIBRAW_LIBRARY_BUILD 
+#ifdef LIBRAW_LIBRARY_BUILD
   if(terminate_flag)
       throw LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK;
 #endif
 }
 
+#else
+void CLASS ahd_interpolate()
+{
+  int i, j, top, left, row, col, tr, tc, c, d, val, hm[2];
+  static const int dir[4] = { -1, 1, -TS, TS };
+  unsigned ldiff[2][4], abdiff[2][4], leps, abeps;
+  ushort (*rgb)[TS][TS][3], (*rix)[3], (*pix)[4];
+   short (*lab)[TS][TS][3], (*lix)[3];
+   char (*homo)[TS][TS], *buffer;
+
+#ifdef DCRAW_VERBOSE
+  if (verbose) fprintf (stderr,_("AHD interpolation...\n"));
+#endif
 
+  cielab (0,0);
+  border_interpolate(5);
+  buffer = (char *) malloc (26*TS*TS);
+  merror (buffer, "ahd_interpolate()");
+  rgb  = (ushort(*)[TS][TS][3]) buffer;
+  lab  = (short (*)[TS][TS][3])(buffer + 12*TS*TS);
+  homo = (char  (*)[TS][TS])   (buffer + 24*TS*TS);
+
+  for (top=2; top < height-5; top += TS-6)
+    for (left=2; left < width-5; left += TS-6) {
+
+/*  Interpolate green horizontally and vertically:		*/
+      for (row=top; row < top+TS && row < height-2; row++) {
+	col = left + (FC(row,left) & 1);
+	for (c = FC(row,col); col < left+TS && col < width-2; col+=2) {
+	  pix = image + row*width+col;
+	  val = ((pix[-1][1] + pix[0][c] + pix[1][1]) * 2
+		- pix[-2][c] - pix[2][c]) >> 2;
+	  rgb[0][row-top][col-left][1] = ULIM(val,pix[-1][1],pix[1][1]);
+	  val = ((pix[-width][1] + pix[0][c] + pix[width][1]) * 2
+		- pix[-2*width][c] - pix[2*width][c]) >> 2;
+	  rgb[1][row-top][col-left][1] = ULIM(val,pix[-width][1],pix[width][1]);
+	}
+      }
 
+/*  Interpolate red and blue, and convert to CIELab:		*/
+      for (d=0; d < 2; d++)
+	for (row=top+1; row < top+TS-1 && row < height-3; row++)
+	  for (col=left+1; col < left+TS-1 && col < width-3; col++) {
+	    pix = image + row*width+col;
+	    rix = &rgb[d][row-top][col-left];
+	    lix = &lab[d][row-top][col-left];
+	    if ((c = 2 - FC(row,col)) == 1) {
+	      c = FC(row+1,col);
+	      val = pix[0][1] + (( pix[-1][2-c] + pix[1][2-c]
+				 - rix[-1][1] - rix[1][1] ) >> 1);
+	      rix[0][2-c] = CLIP(val);
+	      val = pix[0][1] + (( pix[-width][c] + pix[width][c]
+				 - rix[-TS][1] - rix[TS][1] ) >> 1);
+	    } else
+	      val = rix[0][1] + (( pix[-width-1][c] + pix[-width+1][c]
+				 + pix[+width-1][c] + pix[+width+1][c]
+				 - rix[-TS-1][1] - rix[-TS+1][1]
+				 - rix[+TS-1][1] - rix[+TS+1][1] + 1) >> 2);
+	    rix[0][c] = CLIP(val);
+	    c = FC(row,col);
+	    rix[0][c] = pix[0][c];
+	    cielab (rix[0],lix[0]);
+	  }
+/*  Build homogeneity maps from the CIELab images:		*/
+      memset (homo, 0, 2*TS*TS);
+      for (row=top+2; row < top+TS-2 && row < height-4; row++) {
+	tr = row-top;
+	for (col=left+2; col < left+TS-2 && col < width-4; col++) {
+	  tc = col-left;
+	  for (d=0; d < 2; d++) {
+	    lix = &lab[d][tr][tc];
+	    for (i=0; i < 4; i++) {
+	       ldiff[d][i] = ABS(lix[0][0]-lix[dir[i]][0]);
+	      abdiff[d][i] = SQR(lix[0][1]-lix[dir[i]][1])
+			   + SQR(lix[0][2]-lix[dir[i]][2]);
+	    }
+	  }
+	  leps = MIN(MAX(ldiff[0][0],ldiff[0][1]),
+		     MAX(ldiff[1][2],ldiff[1][3]));
+	  abeps = MIN(MAX(abdiff[0][0],abdiff[0][1]),
+		      MAX(abdiff[1][2],abdiff[1][3]));
+	  for (d=0; d < 2; d++)
+	    for (i=0; i < 4; i++)
+	      if (ldiff[d][i] <= leps && abdiff[d][i] <= abeps)
+		homo[d][tr][tc]++;
+	}
+      }
+/*  Combine the most homogenous pixels for the final result:	*/
+      for (row=top+3; row < top+TS-3 && row < height-5; row++) {
+	tr = row-top;
+	for (col=left+3; col < left+TS-3 && col < width-5; col++) {
+	  tc = col-left;
+	  for (d=0; d < 2; d++)
+	    for (hm[d]=0, i=tr-1; i <= tr+1; i++)
+	      for (j=tc-1; j <= tc+1; j++)
+		hm[d] += homo[d][i][j];
+	  if (hm[0] != hm[1])
+	    FORC3 image[row*width+col][c] = rgb[hm[1] > hm[0]][tr][tc][c];
+	  else
+	    FORC3 image[row*width+col][c] =
+		(rgb[0][tr][tc][c] + rgb[1][tr][tc][c]) >> 1;
+	}
+      }
+    }
+  free (buffer);
+}
+#endif
 #undef TS
 
 void CLASS median_filter()
@@ -4485,10 +5402,10 @@ void CLASS blend_highlights()
 #ifdef DCRAW_VERBOSE
   if (verbose) fprintf (stderr,_("Blending highlights...\n"));
 #endif
-  FORCC if (clip > (i = 65535*pre_mul[c])) clip = i;
 #ifdef LIBRAW_LIBRARY_BUILD
   RUN_CALLBACK(LIBRAW_PROGRESS_HIGHLIGHTS,0,2);
 #endif
+  FORCC if (clip > (i = 65535*pre_mul[c])) clip = i;
   for (row=0; row < height; row++)
     for (col=0; col < width; col++) {
       FORCC if (image[row*width+col][c] > clip) break;
@@ -4529,13 +5446,13 @@ void CLASS recover_highlights()
   if (verbose) fprintf (stderr,_("Rebuilding highlights...\n"));
 #endif
 
-  grow = pow (2.0, 4.0-highlight);
+  grow = pow (2.0, 4-highlight);
   FORCC hsat[c] = 32000 * pre_mul[c];
   for (kc=0, c=1; c < colors; c++)
     if (pre_mul[kc] < pre_mul[c]) kc = c;
   high = height / SCALE;
   wide =  width / SCALE;
-  map = (float *) calloc (high*wide, sizeof *map);
+  map = (float *) calloc (high, wide*sizeof *map);
   merror (map, "recover_highlights()");
   FORCC if (c != kc) {
 #ifdef LIBRAW_LIBRARY_BUILD
@@ -4605,7 +5522,7 @@ void CLASS tiff_get (unsigned base,
   *type = get2();
   *len  = get4();
   *save = ftell(ifp) + 4;
-  if (*len * ("11124811248488"[*type < 14 ? *type:0]-'0') > 4)
+  if (*len * ("11124811248484"[*type < 14 ? *type:0]-'0') > 4)
     fseek (ifp, get4()+base, SEEK_SET);
 }
 
@@ -4622,117 +5539,2565 @@ void CLASS parse_thumb_note (int base, unsigned toff, unsigned tlen)
   }
 }
 
-void CLASS parse_makernote (int base, int uptag)
+static float powf_lim(float a, float b, float limup)
 {
-  static const uchar xlat[2][256] = {
-  { 0xc1,0xbf,0x6d,0x0d,0x59,0xc5,0x13,0x9d,0x83,0x61,0x6b,0x4f,0xc7,0x7f,0x3d,0x3d,
-    0x53,0x59,0xe3,0xc7,0xe9,0x2f,0x95,0xa7,0x95,0x1f,0xdf,0x7f,0x2b,0x29,0xc7,0x0d,
-    0xdf,0x07,0xef,0x71,0x89,0x3d,0x13,0x3d,0x3b,0x13,0xfb,0x0d,0x89,0xc1,0x65,0x1f,
-    0xb3,0x0d,0x6b,0x29,0xe3,0xfb,0xef,0xa3,0x6b,0x47,0x7f,0x95,0x35,0xa7,0x47,0x4f,
-    0xc7,0xf1,0x59,0x95,0x35,0x11,0x29,0x61,0xf1,0x3d,0xb3,0x2b,0x0d,0x43,0x89,0xc1,
-    0x9d,0x9d,0x89,0x65,0xf1,0xe9,0xdf,0xbf,0x3d,0x7f,0x53,0x97,0xe5,0xe9,0x95,0x17,
-    0x1d,0x3d,0x8b,0xfb,0xc7,0xe3,0x67,0xa7,0x07,0xf1,0x71,0xa7,0x53,0xb5,0x29,0x89,
-    0xe5,0x2b,0xa7,0x17,0x29,0xe9,0x4f,0xc5,0x65,0x6d,0x6b,0xef,0x0d,0x89,0x49,0x2f,
-    0xb3,0x43,0x53,0x65,0x1d,0x49,0xa3,0x13,0x89,0x59,0xef,0x6b,0xef,0x65,0x1d,0x0b,
-    0x59,0x13,0xe3,0x4f,0x9d,0xb3,0x29,0x43,0x2b,0x07,0x1d,0x95,0x59,0x59,0x47,0xfb,
-    0xe5,0xe9,0x61,0x47,0x2f,0x35,0x7f,0x17,0x7f,0xef,0x7f,0x95,0x95,0x71,0xd3,0xa3,
-    0x0b,0x71,0xa3,0xad,0x0b,0x3b,0xb5,0xfb,0xa3,0xbf,0x4f,0x83,0x1d,0xad,0xe9,0x2f,
-    0x71,0x65,0xa3,0xe5,0x07,0x35,0x3d,0x0d,0xb5,0xe9,0xe5,0x47,0x3b,0x9d,0xef,0x35,
-    0xa3,0xbf,0xb3,0xdf,0x53,0xd3,0x97,0x53,0x49,0x71,0x07,0x35,0x61,0x71,0x2f,0x43,
-    0x2f,0x11,0xdf,0x17,0x97,0xfb,0x95,0x3b,0x7f,0x6b,0xd3,0x25,0xbf,0xad,0xc7,0xc5,
-    0xc5,0xb5,0x8b,0xef,0x2f,0xd3,0x07,0x6b,0x25,0x49,0x95,0x25,0x49,0x6d,0x71,0xc7 },
-  { 0xa7,0xbc,0xc9,0xad,0x91,0xdf,0x85,0xe5,0xd4,0x78,0xd5,0x17,0x46,0x7c,0x29,0x4c,
-    0x4d,0x03,0xe9,0x25,0x68,0x11,0x86,0xb3,0xbd,0xf7,0x6f,0x61,0x22,0xa2,0x26,0x34,
-    0x2a,0xbe,0x1e,0x46,0x14,0x68,0x9d,0x44,0x18,0xc2,0x40,0xf4,0x7e,0x5f,0x1b,0xad,
-    0x0b,0x94,0xb6,0x67,0xb4,0x0b,0xe1,0xea,0x95,0x9c,0x66,0xdc,0xe7,0x5d,0x6c,0x05,
-    0xda,0xd5,0xdf,0x7a,0xef,0xf6,0xdb,0x1f,0x82,0x4c,0xc0,0x68,0x47,0xa1,0xbd,0xee,
-    0x39,0x50,0x56,0x4a,0xdd,0xdf,0xa5,0xf8,0xc6,0xda,0xca,0x90,0xca,0x01,0x42,0x9d,
-    0x8b,0x0c,0x73,0x43,0x75,0x05,0x94,0xde,0x24,0xb3,0x80,0x34,0xe5,0x2c,0xdc,0x9b,
-    0x3f,0xca,0x33,0x45,0xd0,0xdb,0x5f,0xf5,0x52,0xc3,0x21,0xda,0xe2,0x22,0x72,0x6b,
-    0x3e,0xd0,0x5b,0xa8,0x87,0x8c,0x06,0x5d,0x0f,0xdd,0x09,0x19,0x93,0xd0,0xb9,0xfc,
-    0x8b,0x0f,0x84,0x60,0x33,0x1c,0x9b,0x45,0xf1,0xf0,0xa3,0x94,0x3a,0x12,0x77,0x33,
-    0x4d,0x44,0x78,0x28,0x3c,0x9e,0xfd,0x65,0x57,0x16,0x94,0x6b,0xfb,0x59,0xd0,0xc8,
-    0x22,0x36,0xdb,0xd2,0x63,0x98,0x43,0xa1,0x04,0x87,0x86,0xf7,0xa6,0x26,0xbb,0xd6,
-    0x59,0x4d,0xbf,0x6a,0x2e,0xaa,0x2b,0xef,0xe6,0x78,0xb6,0x4e,0xe0,0x2f,0xdc,0x7c,
-    0xbe,0x57,0x19,0x32,0x7e,0x2a,0xd0,0xb8,0xba,0x29,0x00,0x3c,0x52,0x7d,0xa8,0x49,
-    0x3b,0x2d,0xeb,0x25,0x49,0xfa,0xa3,0xaa,0x39,0xa7,0xc5,0xa7,0x50,0x11,0x36,0xfb,
-    0xc6,0x67,0x4a,0xf5,0xa5,0x12,0x65,0x7e,0xb0,0xdf,0xaf,0x4e,0xb3,0x61,0x7f,0x2f } };
-  unsigned offset=0, entries, tag, type, len, save, c;
-  unsigned ver97=0, serial=0, i, wbi=0, wb[4]={0,0,0,0};
-  uchar buf97[324], ci, cj, ck;
-  short morder, sorder=order;
-  char buf[10];
-/*
-   The MakerNote might have its own TIFF header (possibly with
-   its own byte-order!), or it might just be a table.
- */
-  if (!strcmp(make,"Nokia")) return;
-  fread (buf, 1, 10, ifp);
-  if (!strncmp (buf,"KDK" ,3) ||	/* these aren't TIFF tables */
-      !strncmp (buf,"VER" ,3) ||
-      !strncmp (buf,"IIII",4) ||
-      !strncmp (buf,"MMMM",4)) return;
-  if (!strncmp (buf,"KC"  ,2) ||	/* Konica KD-400Z, KD-510Z */
-      !strncmp (buf,"MLY" ,3)) {	/* Minolta DiMAGE G series */
-    order = 0x4d4d;
-    while ((i=ftell(ifp)) < data_offset && i < 16384) {
-      wb[0] = wb[2];  wb[2] = wb[1];  wb[1] = wb[3];
-      wb[3] = get2();
-      if (wb[1] == 256 && wb[3] == 256 &&
-	  wb[0] > 256 && wb[0] < 640 && wb[2] > 256 && wb[2] < 640)
-	FORC4 cam_mul[c] = wb[c];
+  return (b>limup || b < -limup)?0.f:powf(a,b);
+}
+static float powf64(float a, float b)
+{
+  return powf_lim(a,b,64.f);
+}
+
+
 #ifdef LIBRAW_LIBRARY_BUILD
-      color_flags.cam_mul_state = LIBRAW_COLORSTATE_LOADED;
+
+static float my_roundf(float x) {
+  float t;
+  if (x >= 0.0) {
+    t = ceilf(x);
+    if (t - x > 0.5) t -= 1.0;
+    return t;
+  } else {
+    t = ceilf(-x);
+    if (t + x > 0.5) t -= 1.0;
+    return -t;
+  }
+}
+
+static float _CanonConvert2EV(short in)
+        {
+	float frac1;
+	short val = in, sign = 1, frac;
+	if (val < 0) { val = -val; sign = -1; }
+	frac = (val & 0x1f);
+	val -= frac;
+	if (frac == 0x0c) frac1 = 32.0f / 3.0f;
+	else if (frac == 0x14) frac1 = 64.0f / 3.0f;
+	else frac1 = (float)frac;
+	return (float)sign * ((float)val + frac1) / 32.0f;
+    }
+
+static float _CanonConvertAperture(short in)
+{
+  if (in == (short)0xffe0) return 0.0f;
+  else return powf64(2.0f, _CanonConvert2EV(in) / 2.0f);
+}
+
+void CLASS setCanonBodyFeatures (unsigned id)
+      {
+      imgdata.lens.makernotes.CamID = id;
+	if (
+            (id == 0x80000001) ||	// 1D
+            (id == 0x80000174) ||	// 1D2
+            (id == 0x80000232) ||	// 1D2N
+            (id == 0x80000169) ||	// 1D3
+            (id == 0x80000281)		// 1D4
+            )
+          {
+            imgdata.lens.makernotes.CameraFormat = LIBRAW_FORMAT_APSH;
+            imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Canon_EF;
+          }
+        else
+          if (
+              (id == 0x80000167) ||	// 1Ds
+              (id == 0x80000188) ||	// 1Ds2
+              (id == 0x80000215) ||	// 1Ds3
+              (id == 0x80000213) ||	// 5D
+              (id == 0x80000218) ||	// 5D2
+              (id == 0x80000285) ||	// 5D3
+              (id == 0x80000302) ||	// 6D
+              (id == 0x80000269) ||	// 1DX
+              (id == 0x80000324) ||	// 1DC
+              (id == 0x80000382) ||	// 5DS
+              (id == 0x80000401)		// 5DS R
+              )
+            {
+              imgdata.lens.makernotes.CameraFormat = LIBRAW_FORMAT_FF;
+              imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Canon_EF;
+            }
+          else
+            if (
+                (id == 0x80000331) ||	// M
+                (id == 0x80000355)		// M2
+                )
+              {
+                imgdata.lens.makernotes.CameraFormat = LIBRAW_FORMAT_APSC;
+                imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Canon_EF_M;
+              }
+            else
+              if (
+                  (id == 0x01140000) ||	// D30
+                  (id == 0x01668000) ||	// D60
+                  (id > 0x80000000)
+                  )
+                {
+                  imgdata.lens.makernotes.CameraFormat = LIBRAW_FORMAT_APSC;
+                  imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Canon_EF;
+                  imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Unknown;
+                }
+              else
+                {
+                  imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_FixedLens;
+                  imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_FixedLens;
+                }
+
+	return;
+      }
+
+void CLASS processCanonCameraInfo (unsigned id, uchar *CameraInfo)
+{
+  ushort iCanonLensID = 0, iCanonMaxFocal = 0, iCanonMinFocal = 0, iCanonLens = 0, iCanonCurFocal = 0, iCanonFocalType = 0;
+  CameraInfo[0] = 0;
+  CameraInfo[1] = 0;
+  switch (id) {
+  case 0x80000001: // 1D
+  case 0x80000167: // 1DS
+    iCanonCurFocal = 10;
+    iCanonLensID = 13;
+    iCanonMinFocal = 14;
+    iCanonMaxFocal = 16;
+    if (!imgdata.lens.makernotes.CurFocal)
+      imgdata.lens.makernotes.CurFocal = sget2(CameraInfo + iCanonCurFocal);
+    if (!imgdata.lens.makernotes.MinFocal)
+      imgdata.lens.makernotes.MinFocal  = sget2(CameraInfo + iCanonMinFocal);
+    if (!imgdata.lens.makernotes.MaxFocal)
+      imgdata.lens.makernotes.MaxFocal = sget2(CameraInfo + iCanonMaxFocal);
+    break;
+  case 0x80000174: // 1DMkII
+  case 0x80000188: // 1DsMkII
+    iCanonCurFocal = 9;
+    iCanonLensID = 12;
+    iCanonMinFocal = 17;
+    iCanonMaxFocal = 19;
+    iCanonFocalType = 45;
+    break;
+  case 0x80000232: // 1DMkII N
+    iCanonCurFocal = 9;
+    iCanonLensID = 12;
+    iCanonMinFocal = 17;
+    iCanonMaxFocal = 19;
+    break;
+  case 0x80000169: // 1DMkIII
+  case 0x80000215: // 1DsMkIII
+    iCanonCurFocal = 29;
+    iCanonLensID = 273;
+    iCanonMinFocal = 275;
+    iCanonMaxFocal = 277;
+    break;
+  case 0x80000281: // 1DMkIV
+    iCanonCurFocal = 30;
+    iCanonLensID = 335;
+    iCanonMinFocal = 337;
+    iCanonMaxFocal = 339;
+    break;
+  case 0x80000269: // 1D X
+    iCanonCurFocal = 35;
+    iCanonLensID = 423;
+    iCanonMinFocal = 425;
+    iCanonMaxFocal = 427;
+    break;
+  case 0x80000213: // 5D
+    iCanonCurFocal = 40;
+    if (!sget2Rev(CameraInfo + 12)) iCanonLensID = 151;
+    else iCanonLensID = 12;
+    iCanonMinFocal = 147;
+    iCanonMaxFocal = 149;
+    break;
+  case 0x80000218: // 5DMkII
+    iCanonCurFocal = 30;
+    iCanonLensID = 230;
+    iCanonMinFocal = 232;
+    iCanonMaxFocal = 234;
+    break;
+  case 0x80000285: // 5DMkIII
+    iCanonCurFocal = 35;
+    iCanonLensID = 339;
+    iCanonMinFocal = 341;
+    iCanonMaxFocal = 343;
+    break;
+  case 0x80000302: // 6D
+    iCanonCurFocal = 35;
+    iCanonLensID = 353;
+    iCanonMinFocal = 355;
+    iCanonMaxFocal = 357;
+    break;
+  case 0x80000250: // 7D
+    iCanonCurFocal = 30;
+    iCanonLensID = 274;
+    iCanonMinFocal = 276;
+    iCanonMaxFocal = 278;
+    break;
+  case 0x80000190: // 40D
+    iCanonCurFocal = 29;
+    iCanonLensID = 214;
+    iCanonMinFocal = 216;
+    iCanonMaxFocal = 218;
+    iCanonLens = 2347;
+    break;
+  case 0x80000261: // 50D
+    iCanonCurFocal = 30;
+    iCanonLensID = 234;
+    iCanonMinFocal = 236;
+    iCanonMaxFocal = 238;
+    break;
+  case 0x80000287: // 60D
+    iCanonCurFocal = 30;
+    iCanonLensID = 232;
+    iCanonMinFocal = 234;
+    iCanonMaxFocal = 236;
+    break;
+  case 0x80000325: // 70D
+    iCanonCurFocal = 35;
+    iCanonLensID = 358;
+    iCanonMinFocal = 360;
+    iCanonMaxFocal = 362;
+    break;
+  case 0x80000176: // 450D
+    iCanonCurFocal = 29;
+    iCanonLensID = 222;
+    iCanonLens = 2355;
+    break;
+  case 0x80000252: // 500D
+    iCanonCurFocal = 30;
+    iCanonLensID = 246;
+    iCanonMinFocal = 248;
+    iCanonMaxFocal = 250;
+    break;
+  case 0x80000270: // 550D
+    iCanonCurFocal = 30;
+    iCanonLensID = 255;
+    iCanonMinFocal = 257;
+    iCanonMaxFocal = 259;
+    break;
+  case 0x80000286: // 600D
+  case 0x80000288: // 1100D
+    iCanonCurFocal = 30;
+    iCanonLensID = 234;
+    iCanonMinFocal = 236;
+    iCanonMaxFocal = 238;
+    break;
+  case 0x80000301: // 650D
+  case 0x80000326: // 700D
+    iCanonCurFocal = 35;
+    iCanonLensID = 295;
+    iCanonMinFocal = 297;
+    iCanonMaxFocal = 299;
+    break;
+  case 0x80000254: // 1000D
+    iCanonCurFocal = 29;
+    iCanonLensID = 226;
+    iCanonMinFocal = 228;
+    iCanonMaxFocal = 230;
+    iCanonLens = 2359;
+    break;
+  }
+  if (iCanonFocalType)
+    {
+      imgdata.lens.makernotes.FocalType = CameraInfo[iCanonFocalType];
+      if (!imgdata.lens.makernotes.FocalType)	// zero means 'fixed' here, replacing with standard '1'
+        imgdata.lens.makernotes.FocalType = 1;
+    }
+  if (!imgdata.lens.makernotes.CurFocal)
+    imgdata.lens.makernotes.CurFocal = sget2Rev(CameraInfo + iCanonCurFocal);
+  if (!imgdata.lens.makernotes.LensID)
+    imgdata.lens.makernotes.LensID = sget2Rev(CameraInfo + iCanonLensID);
+  if (!imgdata.lens.makernotes.MinFocal)
+    imgdata.lens.makernotes.MinFocal = sget2Rev(CameraInfo + iCanonMinFocal);
+  if (!imgdata.lens.makernotes.MaxFocal)
+    imgdata.lens.makernotes.MaxFocal = sget2Rev(CameraInfo + iCanonMaxFocal);
+  if (!imgdata.lens.makernotes.Lens[0] && iCanonLens) {
+    if (CameraInfo[iCanonLens] < 65)								// non-Canon lens
+      memcpy(imgdata.lens.makernotes.Lens, CameraInfo + iCanonLens, 64);
+    else if (!strncmp((char *)CameraInfo + iCanonLens, "EF-S", 4)) {
+      memcpy(imgdata.lens.makernotes.Lens, "EF-S ", 5);
+      memcpy(imgdata.lens.makernotes.LensFeatures_pre, "EF-E", 4);
+      imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Canon_EF_S;
+      memcpy(imgdata.lens.makernotes.Lens + 5, CameraInfo + iCanonLens + 4, 60);
+    }
+    else if (!strncmp((char *)CameraInfo + iCanonLens, "TS-E", 4)) {
+      memcpy(imgdata.lens.makernotes.Lens, "TS-E ", 5);
+      memcpy(imgdata.lens.makernotes.LensFeatures_pre, "TS-E", 4);
+      imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Canon_EF;
+      memcpy(imgdata.lens.makernotes.Lens + 5, CameraInfo + iCanonLens + 4, 60);
+    }
+    else if (!strncmp((char *)CameraInfo + iCanonLens, "MP-E", 4)) {
+      memcpy(imgdata.lens.makernotes.Lens, "MP-E ", 5);
+      memcpy(imgdata.lens.makernotes.LensFeatures_pre, "MP-E", 4);
+      imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Canon_EF;
+      memcpy(imgdata.lens.makernotes.Lens + 5, CameraInfo + iCanonLens + 4, 60);
+    }
+    else if (!strncmp((char *)CameraInfo + iCanonLens, "EF-M", 4)) {
+      memcpy(imgdata.lens.makernotes.Lens, "EF-M ", 5);
+      memcpy(imgdata.lens.makernotes.LensFeatures_pre, "EF-M", 4);
+      imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Canon_EF_M;
+      memcpy(imgdata.lens.makernotes.Lens + 5, CameraInfo + iCanonLens + 4, 60);
+    }
+    else {
+      memcpy(imgdata.lens.makernotes.Lens, CameraInfo + iCanonLens, 2);
+      memcpy(imgdata.lens.makernotes.LensFeatures_pre, "EF", 2);
+      imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Canon_EF;
+      imgdata.lens.makernotes.Lens[2] = 32;
+      memcpy(imgdata.lens.makernotes.Lens + 3, CameraInfo + iCanonLens + 2, 62);
+    }
+  }
+  free(CameraInfo);
+  return;
+}
+
+void CLASS processNikonLensData (uchar *LensData, unsigned len)
+{
+  ushort i;
+  if (len < 20) {
+    switch (len) {
+    case 9:
+      i = 2;
+      break;
+    case 15:
+      i = 7;
+      break;
+    case 16:
+      i = 8;
+      break;
+    }
+    imgdata.lens.nikon.NikonLensIDNumber = LensData[i];
+    imgdata.lens.nikon.NikonLensFStops = LensData[i + 1];
+    imgdata.lens.makernotes.LensFStops = (float)imgdata.lens.nikon.NikonLensFStops /12.0f;
+    imgdata.lens.makernotes.MinFocal = 5.0f * powf64(2.0f, (float)LensData[i + 2] / 24.0f);
+    imgdata.lens.makernotes.MaxFocal = 5.0f * powf64(2.0f, (float)LensData[i + 3] / 24.0f);
+    imgdata.lens.makernotes.MaxAp4MinFocal = powf64(2.0f, (float)LensData[i + 4] / 24.0f);
+    imgdata.lens.makernotes.MaxAp4MaxFocal = powf64(2.0f, (float)LensData[i + 5] / 24.0f);
+    imgdata.lens.nikon.NikonMCUVersion = LensData[i + 6];
+    if (i != 2)
+      {
+        imgdata.lens.makernotes.CurFocal = 5.0f * powf64(2.0f, (float)LensData[i - 1] / 24.0f);
+        imgdata.lens.nikon.NikonEffectiveMaxAp = powf64(2.0f, (float)LensData[i + 7] / 24.0f);
+      }
+    imgdata.lens.makernotes.LensID =
+      (unsigned long long) LensData[i] << 56 |
+      (unsigned long long) LensData[i + 1] << 48 |
+      (unsigned long long) LensData[i + 2] << 40 |
+      (unsigned long long) LensData[i + 3] << 32 |
+      (unsigned long long) LensData[i + 4] << 24 |
+      (unsigned long long) LensData[i + 5] << 16 |
+      (unsigned long long) LensData[i + 6] << 8 |
+      (unsigned long long) imgdata.lens.nikon.NikonLensType;
+
+  }
+  else if ((len == 459) || (len == 590))
+    {
+      memcpy(imgdata.lens.makernotes.Lens, LensData + 390, 64);
+    }
+  else if (len == 509)
+    {
+      memcpy(imgdata.lens.makernotes.Lens, LensData + 391, 64);
+    }
+  else if (len == 879)
+    {
+      memcpy(imgdata.lens.makernotes.Lens, LensData + 680, 64);
+    }
+  free (LensData);
+  return;
+}
+
+void CLASS setOlympusBodyFeatures (unsigned long id)
+{
+  imgdata.lens.makernotes.CamID = id;
+  if ((id == 0x4434303430) ||
+      (id == 0x4434303431) ||
+      ((id >= 0x5330303030) && (id <= 0x5330303939)))
+    {
+      imgdata.lens.makernotes.CameraFormat = LIBRAW_FORMAT_FT;
+      imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_FT;
+    }
+  else
+    {
+      imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_FixedLens;
+      imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_FixedLens;
+    }
+
+  if ((id == 0x4434303430) ||
+      (id == 0x4434303431) ||
+      ((id >= 0x5330303033) && (id <= 0x5330303138)) ||
+      (id == 0x5330303233) ||
+      (id == 0x5330303239) ||
+      (id == 0x5330303330) ||
+      (id == 0x5330303333))
+    {
+      imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_FT;
+    }
+  else if (imgdata.lens.makernotes.CameraMount != LIBRAW_MOUNT_FixedLens)
+    {
+      imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_mFT;
+    }
+  return;
+}
+
+void CLASS setPentaxBodyFeatures (unsigned id)
+{
+  imgdata.lens.makernotes.CamID = id;
+
+  switch (id) {
+  case 0x12994:
+  case 0x12aa2:
+  case 0x12b1a:
+  case 0x12b60:
+  case 0x12b7e:
+  case 0x12b80:
+  case 0x12b9c:
+  case 0x12b9d:
+  case 0x12ba2:
+  case 0x12c1e:
+  case 0x12c20:
+  case 0x12cd2:
+  case 0x12cd4:
+  case 0x12cfa:
+  case 0x12d72:
+  case 0x12d73:
+  case 0x12db8:
+  case 0x12dfe:
+  case 0x12e6c:
+  case 0x12e76:
+  case 0x12ef8:
+  case 0x12f52:
+  case 0x12f70:
+  case 0x12f71:
+  case 0x12fb6:
+  case 0x12fc0:
+  case 0x12fca:
+  case 0x1301a:
+    imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Pentax_K;
+    imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Pentax_K;
+    imgdata.lens.makernotes.CameraFormat = LIBRAW_FORMAT_APSC;
+    break;
+  case 0x12e08:
+  case 0x13010:
+    imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Pentax_645;
+    imgdata.lens.makernotes.LensFormat = LIBRAW_FORMAT_MF;
+    imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Pentax_645;
+    imgdata.lens.makernotes.CameraFormat = LIBRAW_FORMAT_MF;
+    break;
+  case 0x12ee4:
+  case 0x12f66:
+  case 0x12f7a:
+  case 0x1302e:
+    imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Pentax_Q;
+    imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Pentax_Q;
+    break;
+  default:
+    imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_FixedLens;
+    imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_FixedLens;
+  }
+  return;
+}
+
+void CLASS setPhaseOneFeatures (unsigned id) {
+
+  ushort i;
+  static const struct {
+    ushort id;
+    char t_model[32];
+  } p1_unique[] = {
+    // Phase One section:
+    {1, "Hasselblad V"},
+    {10, "PhaseOne/Mamiya"},
+    {12, "Contax 645"},
+    {16, "Hasselblad V"},
+    {17, "Hasselblad V"},
+    {18, "Contax 645"},
+    {19, "PhaseOne/Mamiya"},
+    {20, "Hasselblad V"},
+    {21, "Contax 645"},
+    {22, "PhaseOne/Mamiya"},
+    {23, "Hasselblad V"},
+    {24, "Hasselblad H"},
+    {25, "PhaseOne/Mamiya"},
+    {32, "Contax 645"},
+    {34, "Hasselblad V"},
+    {35, "Hasselblad V"},
+    {36, "Hasselblad H"},
+    {37, "Contax 645"},
+    {38, "PhaseOne/Mamiya"},
+    {39, "Hasselblad V"},
+    {40, "Hasselblad H"},
+    {41, "Contax 645"},
+    {42, "PhaseOne/Mamiya"},
+    {44, "Hasselblad V"},
+    {45, "Hasselblad H"},
+    {46, "Contax 645"},
+    {47, "PhaseOne/Mamiya"},
+    {48, "Hasselblad V"},
+    {49, "Hasselblad H"},
+    {50, "Contax 645"},
+    {51, "PhaseOne/Mamiya"},
+    {52, "Hasselblad V"},
+    {53, "Hasselblad H"},
+    {54, "Contax 645"},
+    {55, "PhaseOne/Mamiya"},
+    {67, "Hasselblad V"},
+    {68, "Hasselblad H"},
+    {69, "Contax 645"},
+    {70, "PhaseOne/Mamiya"},
+    {71, "Hasselblad V"},
+    {72, "Hasselblad H"},
+    {73, "Contax 645"},
+    {74, "PhaseOne/Mamiya"},
+    {76, "Hasselblad V"},
+    {77, "Hasselblad H"},
+    {78, "Contax 645"},
+    {79, "PhaseOne/Mamiya"},
+    {80, "Hasselblad V"},
+    {81, "Hasselblad H"},
+    {82, "Contax 645"},
+    {83, "PhaseOne/Mamiya"},
+    {84, "Hasselblad V"},
+    {85, "Hasselblad H"},
+    {86, "Contax 645"},
+    {87, "PhaseOne/Mamiya"},
+    {99, "Hasselblad V"},
+    {100, "Hasselblad H"},
+    {101, "Contax 645"},
+    {102, "PhaseOne/Mamiya"},
+    {103, "Hasselblad V"},
+    {104, "Hasselblad H"},
+    {105, "PhaseOne/Mamiya"},
+    {106, "Contax 645"},
+    {112, "Hasselblad V"},
+    {113, "Hasselblad H"},
+    {114, "Contax 645"},
+    {115, "PhaseOne/Mamiya"},
+    {131, "Hasselblad V"},
+    {132, "Hasselblad H"},
+    {133, "Contax 645"},
+    {134, "PhaseOne/Mamiya"},
+    {135, "Hasselblad V"},
+    {136, "Hasselblad H"},
+    {137, "Contax 645"},
+    {138, "PhaseOne/Mamiya"},
+    {140, "Hasselblad V"},
+    {141, "Hasselblad H"},
+    {142, "Contax 645"},
+    {143, "PhaseOne/Mamiya"},
+    {148, "Hasselblad V"},
+    {149, "Hasselblad H"},
+    {150, "Contax 645"},
+    {151, "PhaseOne/Mamiya"},
+    {160, "A-250"},
+    {161, "A-260"},
+    {162, "A-280"},
+    {167, "Hasselblad V"},
+    {168, "Hasselblad H"},
+    {169, "Contax 645"},
+    {170, "PhaseOne/Mamiya"},
+    {172, "Hasselblad V"},
+    {173, "Hasselblad H"},
+    {174, "Contax 645"},
+    {175, "PhaseOne/Mamiya"},
+    {176, "Hasselblad V"},
+    {177, "Hasselblad H"},
+    {178, "Contax 645"},
+    {179, "PhaseOne/Mamiya"},
+    {180, "Hasselblad V"},
+    {181, "Hasselblad H"},
+    {182, "Contax 645"},
+    {183, "PhaseOne/Mamiya"},
+    {208, "Hasselblad V"},
+    {211, "PhaseOne/Mamiya"},
+    {448, "Phase One 645AF"},
+    {457, "Phase One 645DF"},
+    {471, "Phase One 645DF+"},
+    {704, "Phase One iXA"},
+    {705, "Phase One iXA - R"},
+    {706, "Phase One iXU 150"},
+    {707, "Phase One iXU 150 - NIR"},
+    {708, "Phase One iXU 180"},
+    {721, "Phase One iXR"},
+    // Leaf section:
+    {333,"Mamiya"},
+    {329,"Universal"},
+    {330,"Hasselblad H1/H2"},
+    {332,"Contax"},
+    {336,"AFi"},
+    {327,"Mamiya"},
+    {324,"Universal"},
+    {325,"Hasselblad H1/H2"},
+    {326,"Contax"},
+    {335,"AFi"},
+    {340,"Mamiya"},
+    {337,"Universal"},
+    {338,"Hasselblad H1/H2"},
+    {339,"Contax"},
+    {323,"Mamiya"},
+    {320,"Universal"},
+    {322,"Hasselblad H1/H2"},
+    {321,"Contax"},
+    {334,"AFi"},
+    {369,"Universal"},
+    {370,"Mamiya"},
+    {371,"Hasselblad H1/H2"},
+    {372,"Contax"},
+    {373,"Afi"},
+  };
+  imgdata.lens.makernotes.CamID = id;
+  if (id && !imgdata.lens.makernotes.body[0]) {
+    for (i=0; i < sizeof p1_unique / sizeof *p1_unique; i++)
+      if (id == p1_unique[i].id) {
+        strcpy(imgdata.lens.makernotes.body,p1_unique[i].t_model);
+      }
+  }
+  return;
+}
+
+void CLASS setSonyBodyFeatures (unsigned id) {
+
+  imgdata.lens.makernotes.CamID = id;
+  if (	// FF cameras
+      (id == 257) ||		// a900
+      (id == 269) ||		// a850
+      (id == 340) ||		// ILCE-7M2
+      (id == 318) ||		// ILCE-7S
+      (id == 311) ||		// ILCE-7R
+      (id == 306) ||		// ILCE-7
+      (id == 298) ||		// DSC-RX1
+      (id == 299) ||		// NEX-VG900
+      (id == 310) ||		// DSC-RX1R
+      (id == 294)				// SLT-99, Hasselblad HV
+      )
+    {
+      imgdata.lens.makernotes.CameraFormat = LIBRAW_FORMAT_FF;
+    }
+  else
+    {
+      if ((id != 002) &&  // DSC-R1
+          (id != 297) &&  // DSC-RX100
+          (id != 308) &&  // DSC-RX100M2
+          (id != 309) &&  // DSC-RX10
+          (id != 317))    // DSC-RX100M3
+      imgdata.lens.makernotes.CameraFormat = LIBRAW_FORMAT_APSC;
+    }
+
+  if (	// E-mount cameras
+      // ILCE:
+      (id == 302) ||
+      (id == 306) ||
+      (id == 311) ||
+      (id == 312) ||
+      (id == 313) ||
+      (id == 318) ||
+      (id == 339) ||
+      (id == 340) ||
+      (id == 346)	||
+      // NEX:
+      (id == 278) ||
+      (id == 279) ||
+      (id == 284) ||
+      (id == 288) ||
+      (id == 289) ||
+      (id == 290) ||
+      (id == 293) ||
+      (id == 295) ||
+      (id == 296) ||
+      (id == 299) ||
+      (id == 300) ||
+      (id == 305) ||
+      (id == 307)
+      )
+    {
+      imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Sony_E;
+    }
+
+  else if (	// A-mount cameras
+           // DSLR:
+           (id == 256) ||
+           (id == 257) ||
+           (id == 258) ||
+           (id == 259) ||
+           (id == 260) ||
+           (id == 261) ||
+           (id == 262) ||
+           (id == 263) ||
+           (id == 264) ||
+           (id == 265) ||
+           (id == 266) ||
+           (id == 269) ||
+           (id == 270) ||
+           (id == 273) ||
+           (id == 274) ||
+           (id == 275) ||
+           (id == 282) ||
+           (id == 283)	||
+           // SLT:
+           (id == 280) ||
+           (id == 281) ||
+           (id == 285) ||
+           (id == 286) ||
+           (id == 287) ||
+           (id == 291) ||
+           (id == 292) ||
+           (id == 294) ||
+           (id == 303)	||
+           // ILCA:
+           (id == 319)
+           )
+    {
+      imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Minolta_A;
+    }
+
+  else if (	// DSC
+           (id == 002) ||  // DSC-R1
+           (id == 297) ||  // DSC-RX100
+           (id == 298) ||  // DSC-RX1
+           (id == 308) ||  // DSC-RX100M2
+           (id == 309) ||  // DSC-RX10
+           (id == 310) ||  // DSC-RX1R
+           (id == 317)     // DSC-RX100M3
+           )
+    {
+      imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_FixedLens;
+      imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_FixedLens;
+    }
+  return;
+}
+
+void CLASS parseSonyLensType2 (uchar a, uchar b) {
+  ushort lid2;
+  lid2 = (((ushort)a)<<8) | ((ushort)b);
+  if (!lid2) return;
+  if (lid2 < 0x100)
+    {
+      imgdata.lens.makernotes.AdapterID = lid2;
+      switch (lid2) {
+      case 1:
+      case 2:
+      case 3:
+      case 6:
+        imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Minolta_A;
+        break;
+      case 44:
+      case 78:
+      case 239:
+        imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Canon_EF;
+        break;
+      }
+    }
+  else
+    imgdata.lens.makernotes.LensID = lid2;
+  return;
+}
+
+void CLASS parseSonyLensFeatures (uchar a, uchar b) {
+
+  ushort features;
+  features = (((ushort)a)<<8) | ((ushort)b);
+
+  if ((imgdata.lens.makernotes.LensMount == LIBRAW_MOUNT_Canon_EF) || !features)
+    return;
+
+  imgdata.lens.makernotes.LensFormat = LIBRAW_FORMAT_FF;
+  imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Minolta_A;
+  imgdata.lens.makernotes.LensFeatures_pre[0] = 0;
+  imgdata.lens.makernotes.LensFeatures_suf[0] = 0;
+
+  if ((features & 0x0200) && (features & 0x0100)) {
+    strcpy(imgdata.lens.makernotes.LensFeatures_pre, "E");
+    imgdata.lens.makernotes.LensFormat = LIBRAW_FORMAT_APSC;
+    imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Sony_E;
+  } else if (features & 0x0200) {
+    strcpy(imgdata.lens.makernotes.LensFeatures_pre, "FE");
+    imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Sony_E;
+  } else if (features & 0x0100) {
+    strcpy(imgdata.lens.makernotes.LensFeatures_pre, "DT");
+    imgdata.lens.makernotes.LensFormat = LIBRAW_FORMAT_APSC;
+  }
+
+  if (features & 0x4000)
+    strncat(imgdata.lens.makernotes.LensFeatures_pre, " PZ", sizeof(imgdata.lens.makernotes.LensFeatures_pre));
+
+  if (features & 0x0008)
+    strncat(imgdata.lens.makernotes.LensFeatures_suf, " G", sizeof(imgdata.lens.makernotes.LensFeatures_suf));
+  else if (features & 0x0004)
+    strncat(imgdata.lens.makernotes.LensFeatures_suf, " ZA", sizeof(imgdata.lens.makernotes.LensFeatures_suf));
+
+  if ((features & 0x0020) && (features & 0x0040))
+    strncat(imgdata.lens.makernotes.LensFeatures_suf, " Macro", sizeof(imgdata.lens.makernotes.LensFeatures_suf));
+  else if (features & 0x0020)
+    strncat(imgdata.lens.makernotes.LensFeatures_suf, " STF", sizeof(imgdata.lens.makernotes.LensFeatures_suf));
+  else if (features & 0x0040)
+    strncat(imgdata.lens.makernotes.LensFeatures_suf, " Reflex", sizeof(imgdata.lens.makernotes.LensFeatures_suf));
+  else if (features & 0x0080)
+    strncat(imgdata.lens.makernotes.LensFeatures_suf, " Fisheye", sizeof(imgdata.lens.makernotes.LensFeatures_suf));
+
+  if (features & 0x0001)
+    strncat(imgdata.lens.makernotes.LensFeatures_suf, " SSM", sizeof(imgdata.lens.makernotes.LensFeatures_suf));
+  else if (features & 0x0002)
+    strncat(imgdata.lens.makernotes.LensFeatures_suf, " SAM", sizeof(imgdata.lens.makernotes.LensFeatures_suf));
+
+  if (features & 0x8000)
+    strncat(imgdata.lens.makernotes.LensFeatures_suf, " OSS", sizeof(imgdata.lens.makernotes.LensFeatures_suf));
+
+  if (features & 0x2000)
+    strncat(imgdata.lens.makernotes.LensFeatures_suf, " LE", sizeof(imgdata.lens.makernotes.LensFeatures_suf));
+
+  if (features & 0x0800)
+    strncat(imgdata.lens.makernotes.LensFeatures_suf, " II", sizeof(imgdata.lens.makernotes.LensFeatures_suf));
+
+  if (imgdata.lens.makernotes.LensFeatures_suf[0] == ' ')
+    memmove(imgdata.lens.makernotes.LensFeatures_suf, imgdata.lens.makernotes.LensFeatures_suf+1, strlen(imgdata.lens.makernotes.LensFeatures_suf));
+
+  return;
+}
+
+void CLASS process_Sony_0x940c (uchar * buf)
+{
+  ushort lid2;
+  if (imgdata.lens.makernotes.LensMount != LIBRAW_MOUNT_Canon_EF)
+    {
+      switch (SonySubstitution[buf[0x0008]]) {
+      case 1:
+      case 5:
+        imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Minolta_A;
+        break;
+      case 4:
+        imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Sony_E;
+        break;
+      }
+    }
+  lid2 = (((ushort)SonySubstitution[buf[0x000a]])<<8) |
+    ((ushort)SonySubstitution[buf[0x0009]]);
+  if ((lid2 > 0) && (lid2 < 32784))
+    parseSonyLensType2 (SonySubstitution[buf[0x000a]],	// LensType2 - Sony lens ids
+                        SonySubstitution[buf[0x0009]]);
+  return;
+}
+
+
+void CLASS process_Sony_0x9050 (uchar * buf, unsigned id)
+{
+  ushort lid;
+
+  if ((imgdata.lens.makernotes.CameraMount != LIBRAW_MOUNT_Sony_E) &&
+      (imgdata.lens.makernotes.CameraMount != LIBRAW_MOUNT_FixedLens))
+    {
+      if (buf[0])
+        imgdata.lens.makernotes.MaxAp =
+          my_roundf(powf64(2.0f, ((float)SonySubstitution[buf[0]] / 8.0 - 1.06f) / 2.0f)*10.0f) / 10.0f;
+
+      if (buf[1])
+        imgdata.lens.makernotes.MinAp =
+          my_roundf(powf64(2.0f, ((float)SonySubstitution[buf[1]] / 8.0 - 1.06f) / 2.0f)*10.0f) / 10.0f;
+    }
+
+  if (imgdata.lens.makernotes.CameraMount != LIBRAW_MOUNT_FixedLens)
+    {
+      if (buf[0x3d] | buf[0x3c])
+        {
+          lid = SonySubstitution[buf[0x3d]] << 8 |
+            SonySubstitution[buf[0x3c]];
+          imgdata.lens.makernotes.CurAp =
+            powf64(2.0f, ((float)lid/256.0f - 16.0f) / 2.0f);
+        }
+      if (buf[0x105] && (imgdata.lens.makernotes.LensMount != LIBRAW_MOUNT_Canon_EF))
+        imgdata.lens.makernotes.LensMount =
+          SonySubstitution[buf[0x105]];
+      if (buf[0x106])
+        imgdata.lens.makernotes.LensFormat =
+          SonySubstitution[buf[0x106]];
+    }
+
+  if (imgdata.lens.makernotes.CameraMount == LIBRAW_MOUNT_Sony_E)
+    {
+      parseSonyLensType2 (SonySubstitution[buf[0x0108]],		// LensType2 - Sony lens ids
+                          SonySubstitution[buf[0x0107]]);
+    }
+
+  if ((imgdata.lens.makernotes.LensID == -1) &&
+      (imgdata.lens.makernotes.CameraMount == LIBRAW_MOUNT_Minolta_A) &&
+      (buf[0x010a] | buf[0x0109]))
+    {
+      imgdata.lens.makernotes.LensID =		 // LensType - Minolta/Sony lens ids
+        SonySubstitution[buf[0x010a]] << 8 |
+        SonySubstitution[buf[0x0109]];
+      if ((imgdata.lens.makernotes.LensID > 61184) &&
+          (imgdata.lens.makernotes.LensID < 65535))
+        {
+          imgdata.lens.makernotes.LensID -= 61184;
+          imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Canon_EF;
+        }
+    }
+
+  if ((id >= 286) && (id <= 293))
+    // "SLT-A65", "SLT-A77", "NEX-7", "NEX-VG20E",
+    // "SLT-A37", "SLT-A57", "NEX-F3", "Lunar"
+    parseSonyLensFeatures (SonySubstitution[buf[0x115]],
+                           SonySubstitution[buf[0x116]]);
+  else if (imgdata.lens.makernotes.CameraMount != LIBRAW_MOUNT_FixedLens)
+    parseSonyLensFeatures (SonySubstitution[buf[0x116]],
+                           SonySubstitution[buf[0x117]]);
+  return;
+}
+
+void CLASS parse_makernote_0xc634(int base, int uptag, unsigned dng_writer)
+{
+  unsigned offset = 0, entries, tag, type, len, save, c;
+  unsigned i;
+
+  uchar NikonKey, ci, cj, ck;
+  unsigned serial = 0;
+  unsigned NikonLensDataVersion = 0;
+  unsigned lenNikonLensData = 0;
+
+  uchar *CanonCameraInfo;
+  unsigned lenCanonCameraInfo = 0;
+
+  uchar *table_buf;
+  uchar *table_buf_0x9050;
+  ushort table_buf_0x9050_present = 0;
+  uchar *table_buf_0x940c;
+  ushort table_buf_0x940c_present = 0;
+
+  short morder, sorder = order;
+  char buf[10];
+
+  fread(buf, 1, 10, ifp);
+  if (!strcmp(buf, "Nikon")) {
+    base = ftell(ifp);
+    order = get2();
+    if (get2() != 42) goto quit;
+    offset = get4();
+    fseek(ifp, offset - 8, SEEK_CUR);
+  }
+  else if (!strcmp(buf, "OLYMPUS") ||
+           !strcmp(buf, "PENTAX ") ||
+           (!strncmp(make, "SAMSUNG", 7) && (dng_writer == CameraDNG))) {
+    base = ftell(ifp) - 10;
+    fseek(ifp, -2, SEEK_CUR);
+    order = get2();
+    if (buf[0] == 'O') get2();
+  }
+  else if (!strncmp(buf, "SONY", 4) ||
+           !strcmp(buf, "Panasonic")) {
+    goto nf;
+  }
+  else if (!strncmp(buf, "FUJIFILM", 8)) {
+    base = ftell(ifp) - 10;
+  nf: order = 0x4949;
+    fseek(ifp, 2, SEEK_CUR);
+  }
+  else if (!strcmp(buf, "OLYMP") ||
+           !strcmp(buf, "LEICA") ||
+           !strcmp(buf, "Ricoh") ||
+           !strcmp(buf, "EPSON"))
+    fseek(ifp, -2, SEEK_CUR);
+  else if (!strcmp(buf, "AOC") ||
+           !strcmp(buf, "QVC"))
+    fseek(ifp, -4, SEEK_CUR);
+  else {
+    fseek(ifp, -10, SEEK_CUR);
+    if ((!strncmp(make, "SAMSUNG", 7) &&
+				(dng_writer == AdobeDNG)))
+      base = ftell(ifp);
+  }
+
+  entries = get2();
+
+// if (dng_writer == AdobeDNG)
+//   printf("\n*** parse_makernote_0xc634: AdobeDNG");
+// else if (dng_writer == CameraDNG)
+//   printf("\n*** parse_makernote_0xc634: CameraDNG");
+
+//   printf ("\n\tbuf  =%s=\n\tmake  =%s=\n\tmodel =%s=\n\tbase: 0x%x\n\tentries: %d\n",
+//   		buf, make, model, base, entries);
+
+  if (entries > 1000) return;
+  morder = order;
+  while (entries--) {
+    order = morder;
+    tiff_get(base, &tag, &type, &len, &save);
+    tag |= uptag << 16;
+
+// 	printf ("\n\tbase: 0x%x tag: 0x%04x type: 0x%x len: 0x%x pos: 0x%llx",
+// 			base, tag, type, len, ftell(ifp));
+
+    if (!strcmp(make, "Canon"))
+      {
+        if (tag == 0x0001)				// camera settings
+          {
+            fseek(ifp, 44, SEEK_CUR);
+            imgdata.lens.makernotes.LensID = get2();
+            imgdata.lens.makernotes.MaxFocal = get2();
+            imgdata.lens.makernotes.MinFocal = get2();
+            imgdata.lens.makernotes.CanonFocalUnits = get2();
+            if (imgdata.lens.makernotes.CanonFocalUnits != 1)
+              {
+                imgdata.lens.makernotes.MaxFocal /= (float)imgdata.lens.makernotes.CanonFocalUnits;
+                imgdata.lens.makernotes.MinFocal /= (float)imgdata.lens.makernotes.CanonFocalUnits;
+              }
+            imgdata.lens.makernotes.MaxAp = _CanonConvertAperture(get2());
+            imgdata.lens.makernotes.MinAp = _CanonConvertAperture(get2());
+          }
+
+        else if (tag == 0x0002)			// focal length
+          {
+            imgdata.lens.makernotes.FocalType = get2();
+            imgdata.lens.makernotes.CurFocal = get2();
+            if ((imgdata.lens.makernotes.CanonFocalUnits != 1) &&
+                imgdata.lens.makernotes.CanonFocalUnits)
+              {
+                imgdata.lens.makernotes.CurFocal /= (float)imgdata.lens.makernotes.CanonFocalUnits;
+              }
+          }
+
+        else if (tag == 0x0004)			// shot info
+          {
+            fseek(ifp, 42, SEEK_CUR);
+            imgdata.lens.makernotes.CurAp = _CanonConvertAperture(get2());
+          }
+
+        else if (tag == 0x000d)			// camera info
+          {
+            CanonCameraInfo = (uchar*)malloc(len);
+            fread(CanonCameraInfo, len, 1, ifp);
+            lenCanonCameraInfo = len;
+          }
+
+        else if (tag == 0x10)	// Canon ModelID
+          {
+            unique_id = get4();
+            setCanonBodyFeatures(unique_id);
+            if (lenCanonCameraInfo) processCanonCameraInfo(unique_id, CanonCameraInfo);
+          }
+
+        else if (tag == 0x0095 &&		// lens model tag
+                 !imgdata.lens.makernotes.Lens[0])
+          {
+            fread(imgdata.lens.makernotes.Lens, 2, 1, ifp);
+            imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Canon_EF;
+            if (imgdata.lens.makernotes.Lens[0] < 65)					// non-Canon lens
+              fread(imgdata.lens.makernotes.Lens + 2, 62, 1, ifp);
+            else
+              {
+                char efs[2];
+                imgdata.lens.makernotes.LensFeatures_pre[0] = imgdata.lens.makernotes.Lens[0];
+                imgdata.lens.makernotes.LensFeatures_pre[1] = imgdata.lens.makernotes.Lens[1];
+                fread(efs, 2, 1, ifp);
+                if (efs[0] == 45 && (efs[1] == 83 || efs[1] == 69 || efs[1] == 77))
+                  {	// "EF-S, TS-E, MP-E, EF-M" lenses
+                    imgdata.lens.makernotes.Lens[2] = imgdata.lens.makernotes.LensFeatures_pre[2] = efs[0];
+                    imgdata.lens.makernotes.Lens[3] = imgdata.lens.makernotes.LensFeatures_pre[3] = efs[1];
+                    imgdata.lens.makernotes.Lens[4] = 32;
+                    if (efs[1] == 83)
+                      {
+                        imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Canon_EF_S;
+                        imgdata.lens.makernotes.LensFormat = LIBRAW_FORMAT_APSC;
+                      }
+                    else if (efs[1] == 77)
+                      {
+                        imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Canon_EF_M;
+                      }
+                  }
+                else
+                  {																// "EF" lenses
+                    imgdata.lens.makernotes.Lens[2] = 32;
+                    imgdata.lens.makernotes.Lens[3] = efs[0];
+                    imgdata.lens.makernotes.Lens[4] = efs[1];
+                  }
+                fread(imgdata.lens.makernotes.Lens + 5, 58, 1, ifp);
+              }
+          }
+      }
+
+    else if (!strncmp(make, "FUJI", 4))
+      switch (tag) {
+      case 0x1404: imgdata.lens.makernotes.MinFocal = getreal(type); break;
+      case 0x1405: imgdata.lens.makernotes.MaxFocal = getreal(type); break;
+      case 0x1406: imgdata.lens.makernotes.MaxAp4MinFocal = getreal(type); break;
+      case 0x1407: imgdata.lens.makernotes.MaxAp4MaxFocal = getreal(type); break;
+      }
+
+    else if (!strncasecmp(make, "LEICA", 5))
+      {
+        if ((tag == 0x0303) && (type != 4))
+          {
+            fread(imgdata.lens.makernotes.Lens, len, 1, ifp);
+          }
+
+        if ((tag == 0x3405) ||
+            (tag == 0x0310) ||
+            (tag == 0x34003405))
+          {
+            imgdata.lens.makernotes.LensID = get4();
+            imgdata.lens.makernotes.LensID =
+              ((imgdata.lens.makernotes.LensID>>2)<<8) |
+              (imgdata.lens.makernotes.LensID & 0x3);
+            if (imgdata.lens.makernotes.LensID != -1)
+              {
+                if ((model[0] == 'M') ||
+                    !strncasecmp (model, "LEICA M", 7))
+                  {
+                    imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Leica_M;
+                    if (imgdata.lens.makernotes.LensID)
+                      imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Leica_M;
+                  }
+                else if ((model[0] == 'S') ||
+                         !strncasecmp (model, "LEICA S", 7))
+                  {
+                    imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Leica_S;
+                    if (imgdata.lens.makernotes.Lens[0])
+                      imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Leica_S;
+                  }
+              }
+          }
+
+        else if (
+                 ((tag == 0x0313) || (tag == 0x34003406)) &&
+                 (fabs(imgdata.lens.makernotes.CurAp) < 0.17f) &&
+                 ((type == 10) || (type == 5))
+                )
+          {
+            imgdata.lens.makernotes.CurAp = getreal(type);
+            if (imgdata.lens.makernotes.CurAp > 126.3)
+              imgdata.lens.makernotes.CurAp = 0.0f;
+          }
+
+        else if (tag == 0x3400)
+          {
+            parse_makernote (base, 0x3400);
+          }
+      }
+
+    else if (!strncmp(make, "NIKON", 5))
+      {
+        if (tag == 0x1d)							// serial number
+          while ((c = fgetc(ifp)) && c != EOF)
+            serial = serial * 10 + (isdigit(c) ? c - '0' : c % 10);
+
+        else if (tag == 0x0082)				// lens attachment
+          {
+            fread(imgdata.lens.makernotes.Attachment, len, 1, ifp);
+          }
+        else if (tag == 0x0083)				// lens type
+          {
+            imgdata.lens.nikon.NikonLensType = fgetc(ifp);
+            if (!(imgdata.lens.nikon.NikonLensType & 0x01))
+              {
+                imgdata.lens.makernotes.LensFeatures_pre[0] = 'A';
+                imgdata.lens.makernotes.LensFeatures_pre[1] = 'F';
+              }
+            if (imgdata.lens.nikon.NikonLensType & 0x02)
+              {
+                if (imgdata.lens.nikon.NikonLensType & 0x04)
+                  imgdata.lens.makernotes.LensFeatures_suf[0] = 'G';
+                else
+                  imgdata.lens.makernotes.LensFeatures_suf[0] = 'D';
+                imgdata.lens.makernotes.LensFeatures_suf[1] = ' ';
+              }
+            if (imgdata.lens.nikon.NikonLensType & 0x08)
+              {
+                imgdata.lens.makernotes.LensFeatures_suf[2] = 'V';
+                imgdata.lens.makernotes.LensFeatures_suf[3] = 'R';
+              }
+            if (imgdata.lens.nikon.NikonLensType & 0x10)
+              {
+                imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Nikon_CX;
+              }
+
+            if (imgdata.lens.nikon.NikonLensType & 0x20)
+              {
+                strcpy(imgdata.lens.makernotes.Adapter, "FT-1");
+              }
+            imgdata.lens.nikon.NikonLensType = imgdata.lens.nikon.NikonLensType & 0xdf;
+          }
+        else if (tag == 0x0084)				// lens
+          {
+            imgdata.lens.makernotes.MinFocal = getreal(type);
+            imgdata.lens.makernotes.MaxFocal = getreal(type);
+            imgdata.lens.makernotes.MaxAp4MinFocal = getreal(type);
+            imgdata.lens.makernotes.MaxAp4MaxFocal = getreal(type);
+          }
+        else if (tag == 0x008b)				// lens f-stops
+          {
+            uchar a, b, c;
+            a = fgetc(ifp);
+            b = fgetc(ifp);
+            c = fgetc(ifp);
+            if (c)
+              {
+                imgdata.lens.nikon.NikonLensFStops = a*b*(12/c);
+                imgdata.lens.makernotes.LensFStops =
+                  (float)imgdata.lens.nikon.NikonLensFStops /12.0f;
+              }
+          }
+        else if (tag == 0x0098)				// contains lens data
+          {
+            for (i = 0; i < 4; i++)
+              {
+                NikonLensDataVersion = NikonLensDataVersion * 10 + fgetc(ifp) - '0';
+              }
+            switch (NikonLensDataVersion)
+              {
+              case 100: lenNikonLensData = 9; imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Nikon_F; break;
+              case 101:
+              case 201:	// encrypted, starting from v.201
+              case 202:
+              case 203: lenNikonLensData = 15; imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Nikon_F; break;
+              case 204: lenNikonLensData = 16; imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Nikon_F; break;
+              case 400: lenNikonLensData = 459; break;
+              case 401: lenNikonLensData = 590; break;
+              case 402: lenNikonLensData = 509; break;
+              case 403: lenNikonLensData = 879; break;
+              }
+            table_buf = (uchar*)malloc(lenNikonLensData);
+            fread(table_buf, lenNikonLensData, 1, ifp);
+            if ((NikonLensDataVersion < 201) && lenNikonLensData)
+            {
+              processNikonLensData(table_buf, lenNikonLensData);
+              lenNikonLensData = 0;
+            }
+          }
+
+        else if (tag == 0xa7)					// shutter count
+          {
+            NikonKey = fgetc(ifp) ^ fgetc(ifp) ^ fgetc(ifp) ^ fgetc(ifp);
+            if ((NikonLensDataVersion > 200) && lenNikonLensData)
+              {
+                ci = xlat[0][serial & 0xff];
+                cj = xlat[1][NikonKey];
+                ck = 0x60;
+                for (i = 0; i < lenNikonLensData; i++)
+                  table_buf[i] ^= (cj += ci * ck++);
+                processNikonLensData(table_buf, lenNikonLensData);
+                lenNikonLensData = 0;
+              }
+          }
+
+        else if (tag == 37 && (!iso_speed || iso_speed == 65535))
+          {
+            unsigned char cc;
+            fread(&cc, 1, 1, ifp);
+            iso_speed = (int)(100.0 * powf64(2.0, (double)(cc) / 12.0 - 5.0));
+            break;
+          }
+      }
+
+    else if (!strncmp(make, "OLYMPUS", 7))
+      {
+        if (tag == 0x2010)
+          {
+            fseek(ifp, save - 4, SEEK_SET);
+            fseek(ifp, base + get4(), SEEK_SET);
+            parse_makernote_0xc634(base, 0x2010, dng_writer);
+          }
+
+        switch (tag) {
+        case 0x0207:
+        case 0x20100100:
+          {
+            uchar sOlyID[7];
+            long unsigned OlyID;
+            fread (sOlyID, len, 1, ifp);
+            OlyID = sOlyID[0];
+            i = 1;
+            while (sOlyID[i])
+              {
+                OlyID = OlyID << 8 | sOlyID[i];
+                i++;
+              }
+            setOlympusBodyFeatures(OlyID);
+          }
+          break;
+        case 0x1002:
+          imgdata.lens.makernotes.CurAp = powf64(2.0f, getreal(type)/2);
+          break;
+        case 0x20100201:
+          imgdata.lens.makernotes.LensID =
+            (unsigned long long)fgetc(ifp)<<16 |
+            (unsigned long long)(fgetc(ifp), fgetc(ifp))<<8 |
+            (unsigned long long)fgetc(ifp);
+          imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_FT;
+          imgdata.lens.makernotes.LensFormat = LIBRAW_FORMAT_FT;
+          if (((imgdata.lens.makernotes.LensID < 0x20000) ||
+               (imgdata.lens.makernotes.LensID > 0x4ffff)) &&
+              (imgdata.lens.makernotes.LensID & 0x10))
+            {
+              imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_mFT;
+            }
+          break;
+        case 0x20100203:
+          fread(imgdata.lens.makernotes.Lens, len, 1, ifp);
+          break;
+        case 0x20100205:
+          imgdata.lens.makernotes.MaxAp4MinFocal = powf64(sqrt(2.0f), get2() / 256.0f);
+          break;
+        case 0x20100206:
+          imgdata.lens.makernotes.MaxAp4MaxFocal = powf64(sqrt(2.0f), get2() / 256.0f);
+          break;
+        case 0x20100207:
+          imgdata.lens.makernotes.MinFocal = (float)get2();
+          break;
+        case 0x20100208:
+          imgdata.lens.makernotes.MaxFocal = (float)get2();
+          if (imgdata.lens.makernotes.MaxFocal > 1000.0f)
+            imgdata.lens.makernotes.MaxFocal = imgdata.lens.makernotes.MinFocal;
+          break;
+        case 0x2010020a:
+          imgdata.lens.makernotes.MaxAp4CurFocal = powf64(sqrt(2.0f), get2() / 256.0f);
+          break;
+        case 0x20100301:
+          imgdata.lens.makernotes.TeleconverterID = fgetc(ifp) << 8;
+          fgetc(ifp);
+          imgdata.lens.makernotes.TeleconverterID =
+            imgdata.lens.makernotes.TeleconverterID | fgetc(ifp);
+          break;
+        case 0x20100303:
+          fread(imgdata.lens.makernotes.Teleconverter, len, 1, ifp);
+          break;
+        case 0x20100403:
+          fread(imgdata.lens.makernotes.Attachment, len, 1, ifp);
+          break;
+        }
+      }
+
+    else if (!strncmp(make, "PENTAX", 6) ||
+             !strncmp(model, "PENTAX", 6) ||
+             (!strncmp(make, "SAMSUNG", 7) && (dng_writer == CameraDNG)))
+      {
+        if (tag == 0x0005)
+          {
+            unique_id = get4();
+            setPentaxBodyFeatures(unique_id);
+            if (
+                (dng_writer == CameraDNG) &&
+                (
+                 (unique_id == 0x12f66) ||		// Q10
+                 (unique_id == 0x12f7a) ||		// Q7
+                 (unique_id == 0x12ee4)			  // Q
+                 )
+                )
+              base += 10;
+          }
+        else if (tag == 0x0013)
+          {
+            imgdata.lens.makernotes.CurAp = (float)get2()/10.0f;
+          }
+        else if (tag == 0x001d)
+          {
+            imgdata.lens.makernotes.CurFocal = (float)get4()/100.0f;
+          }
+        else if (tag == 0x003f)
+          {
+            imgdata.lens.makernotes.LensID = fgetc(ifp) << 8 | fgetc(ifp);
+          }
+        else if (tag == 0x0207)
+          {
+            ushort iLensData = 0;
+            table_buf = (uchar*)malloc(len);
+            fread(table_buf, len, 1, ifp);
+            if ((imgdata.lens.makernotes.CamID < 0x12b9c) ||
+                ((imgdata.lens.makernotes.CamID == 0x12b9c) ||	// K100D
+                 (imgdata.lens.makernotes.CamID == 0x12b9d) ||	// K110D
+                 (imgdata.lens.makernotes.CamID == 0x12ba2)	&&	// K100D Super
+                 (!table_buf[20] || (table_buf[20] == 0xff))))
+              {
+                iLensData = 3;
+                if (imgdata.lens.makernotes.LensID == -1)
+                  imgdata.lens.makernotes.LensID =
+                    (((unsigned)table_buf[0]) << 8) + table_buf[1];
+              }
+            else switch (len)
+              {
+              case 90:							// LensInfo3
+                iLensData = 13;
+                if (imgdata.lens.makernotes.LensID == -1)
+                  imgdata.lens.makernotes.LensID =
+                    ((unsigned)((table_buf[1] & 0x0f) + table_buf[3]) <<8) + table_buf[4];
+                break;
+              case 91:							// LensInfo4
+                iLensData = 12;
+                if (imgdata.lens.makernotes.LensID == -1)
+                  imgdata.lens.makernotes.LensID =
+                    ((unsigned)((table_buf[1] & 0x0f) + table_buf[3]) <<8) + table_buf[4];
+                break;
+              case 80:							// LensInfo5
+              case 128:
+                iLensData = 15;
+                if (imgdata.lens.makernotes.LensID == -1)
+                  imgdata.lens.makernotes.LensID =
+                    ((unsigned)((table_buf[1] & 0x0f) + table_buf[4]) <<8) + table_buf[5];
+                break;
+              default:
+                if (imgdata.lens.makernotes.CamID >= 0x12b9c)		// LensInfo2
+                  {
+                    iLensData = 4;
+                    if (imgdata.lens.makernotes.LensID == -1)
+                      imgdata.lens.makernotes.LensID =
+                        ((unsigned)((table_buf[0] & 0x0f) + table_buf[2]) <<8) + table_buf[3];
+                  }
+              }
+            if (iLensData)
+              {
+                if (table_buf[iLensData+9] &&
+                    (fabs(imgdata.lens.makernotes.CurFocal) < 0.1f))
+                  imgdata.lens.makernotes.CurFocal =
+                    10*(table_buf[iLensData+9]>>2) * powf64(4, (table_buf[iLensData+9] & 0x03)-2);
+                if (table_buf[iLensData+10] & 0xf0)
+                  imgdata.lens.makernotes.MaxAp4CurFocal =
+                    powf64(2.0f, (float)((table_buf[iLensData+10] & 0xf0) >>4)/4.0f);
+                if (table_buf[iLensData+10] & 0x0f)
+                  imgdata.lens.makernotes.MinAp4CurFocal =
+                    powf64(2.0f, (float)((table_buf[iLensData+10] & 0x0f) + 10)/4.0f);
+                if (
+                    (imgdata.lens.makernotes.CamID != 0x12e6c) &&	// K-r
+                    (imgdata.lens.makernotes.CamID != 0x12e76) &&	// K-5
+                    (imgdata.lens.makernotes.CamID != 0x12f70)		// K-5 II
+                    //        	  		(imgdata.lens.makernotes.CamID != 0x12f71)		// K-5 II s
+                    )
+                  {
+                    switch (table_buf[iLensData] & 0x06)
+                      {
+                      case 0: imgdata.lens.makernotes.MinAp4MinFocal = 22.0f; break;
+                      case 2: imgdata.lens.makernotes.MinAp4MinFocal = 32.0f; break;
+                      case 4: imgdata.lens.makernotes.MinAp4MinFocal = 45.0f; break;
+                      case 6: imgdata.lens.makernotes.MinAp4MinFocal = 16.0f; break;
+                      }
+                    if (table_buf[iLensData] & 0x70)
+                      imgdata.lens.makernotes.LensFStops =
+                        ((float)(((table_buf[iLensData] & 0x70) >> 4) ^ 0x07)) / 2.0f + 5.0f;
+                    if ((table_buf[iLensData+14] > 1) &&
+                        (fabs(imgdata.lens.makernotes.MaxAp4CurFocal) < 0.7f))
+                      imgdata.lens.makernotes.MaxAp4CurFocal =
+                        powf64(2.0f, (float)((table_buf[iLensData+14] & 0x7f) -1)/32.0f);
+                  }
+                else if ((imgdata.lens.makernotes.CamID != 0x12e76) &&	// K-5
+                         (table_buf[iLensData+15] > 1) &&
+                         (fabs(imgdata.lens.makernotes.MaxAp4CurFocal) < 0.7f))
+                  {
+                    imgdata.lens.makernotes.MaxAp4CurFocal =
+                      powf64(2.0f, (float)((table_buf[iLensData+15] & 0x7f) -1)/32.0f);
+                  }
+              }
+            free(table_buf);
+          }
+        else if (tag == 0x0239)		// Q-series lens info (LensInfoQ)
+          {
+            char LensInfo [20];
+            fseek (ifp, 2, SEEK_CUR);
+            fread(imgdata.lens.makernotes.Lens, 30, 1, ifp);
+            strcat(imgdata.lens.makernotes.Lens, " ");
+            fread(LensInfo, 20, 1, ifp);
+            strcat(imgdata.lens.makernotes.Lens, LensInfo);
+          }
+      }
+
+    else if (!strncmp(make, "SAMSUNG", 7) &&
+             (dng_writer == AdobeDNG))
+      {
+        if (tag == 0x0002)
+          {
+            if(get4() == 0x2000)
+              {
+                imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Samsung_NX;
+              }
+            else if (!strncmp(model, "NX mini", 7))
+              {
+                imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Samsung_NX_M;
+              }
+            else
+              {
+                imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_FixedLens;
+                imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_FixedLens;
+              }
+          }
+        else if (tag == 0x0003)
+          {
+            imgdata.lens.makernotes.CamID = unique_id = get4();
+          }
+        else if (tag == 0xa003)
+          {
+            imgdata.lens.makernotes.LensID = get2();
+            if (imgdata.lens.makernotes.LensID)
+              imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Samsung_NX;
+          }
+        else if (tag == 0xa019)
+          {
+            imgdata.lens.makernotes.CurAp = getreal(type);
+          }
+        else if (tag == 0xa01a)
+          {
+            imgdata.lens.makernotes.FocalLengthIn35mmFormat = get4() / 10.0f;
+            if (imgdata.lens.makernotes.FocalLengthIn35mmFormat < 10.0f)
+              imgdata.lens.makernotes.FocalLengthIn35mmFormat *= 10.0f;
+          }
+      }
+
+    else if (!strncasecmp(make, "SONY", 4) ||
+             !strncasecmp(make, "Konica", 6) ||
+             !strncasecmp(make, "Minolta", 7) ||
+             (!strncasecmp(make, "Hasselblad", 10) &&
+              (!strncasecmp(model, "Stellar", 7) ||
+               !strncasecmp(model, "Lunar", 5) ||
+               !strncasecmp(model, "HV",2))))
+      {
+        ushort lid;
+
+        if (tag == 0xb001)			// Sony ModelID
+          {
+            unique_id = get2();
+            setSonyBodyFeatures(unique_id);
+            if (table_buf_0x9050_present)
+              {
+                process_Sony_0x9050(table_buf_0x9050, unique_id);
+                free (table_buf_0x9050);
+                table_buf_0x9050_present = 0;
+              }
+            if (table_buf_0x940c_present)
+              {
+                if (imgdata.lens.makernotes.CameraMount == LIBRAW_MOUNT_Sony_E)
+                  {
+                    process_Sony_0x940c(table_buf_0x940c);
+                  }
+                free (table_buf_0x940c);
+                table_buf_0x940c_present = 0;
+              }
+          }
+        else if ((tag == 0x0010) &&					// CameraInfo
+                 strncasecmp(model, "DSLR-A100", 9) &&
+                 strncasecmp(model, "NEX-5C", 6) &&
+                 !strncasecmp(make, "SONY", 4) &&
+                 ((len == 368) ||			// a700
+                  (len == 5478) ||		// a850, a900
+                  (len == 5506) ||		// a200, a300, a350
+                  (len == 6118) ||		// a230, a290, a330, a380, a390
+
+                  // a450, a500, a550, a560, a580
+                  // a33, a35, a55
+                  // NEX3, NEX5, NEX5C, NEXC3, VG10E
+                  (len == 15360))
+                 )
+          {
+            table_buf = (uchar*)malloc(len);
+            fread(table_buf, len, 1, ifp);
+            if (memcmp(table_buf, "\xff\xff\xff\xff\xff\xff\xff\xff", 8) &&
+                memcmp(table_buf, "\x00\x00\x00\x00\x00\x00\x00\x00", 8))
+              {
+                switch (len) {
+                case 368:
+                case 5478:
+                  // a700, a850, a900: CameraInfo
+                  if (saneSonyCameraInfo(table_buf[0], table_buf[3], table_buf[2], table_buf[5], table_buf[4], table_buf[7]))
+                    {
+                      if (table_buf[0] | table_buf[3])
+                        imgdata.lens.makernotes.MinFocal =
+                          bcd2dec(table_buf[0]) * 100 + bcd2dec(table_buf[3]);
+                      if (table_buf[2] | table_buf[5])
+                        imgdata.lens.makernotes.MaxFocal =
+                          bcd2dec(table_buf[2]) * 100 + bcd2dec(table_buf[5]);
+                      if (table_buf[4])
+                        imgdata.lens.makernotes.MaxAp4MinFocal = bcd2dec(table_buf[4]) / 10.0f;
+                      if (table_buf[4])
+                        imgdata.lens.makernotes.MaxAp4MaxFocal = bcd2dec(table_buf[7]) / 10.0f;
+                      parseSonyLensFeatures(table_buf[1], table_buf[6]);
+                    }
+                  break;
+                default:
+                  // CameraInfo2 & 3
+                  if (saneSonyCameraInfo(table_buf[1], table_buf[2], table_buf[3], table_buf[4], table_buf[5], table_buf[6]))
+                    {
+                      if (table_buf[1] | table_buf[2])
+                        imgdata.lens.makernotes.MinFocal =
+                          bcd2dec(table_buf[1]) * 100 + bcd2dec(table_buf[2]);
+                      if (table_buf[3] | table_buf[4])
+                        imgdata.lens.makernotes.MaxFocal =
+                          bcd2dec(table_buf[3]) * 100 + bcd2dec(table_buf[4]);
+                      if (table_buf[5])
+                        imgdata.lens.makernotes.MaxAp4MinFocal = bcd2dec(table_buf[5]) / 10.0f;
+                      if (table_buf[6])
+                        imgdata.lens.makernotes.MaxAp4MaxFocal = bcd2dec(table_buf[6]) / 10.0f;
+                      parseSonyLensFeatures(table_buf[0], table_buf[7]);
+                    }
+                }
+              }
+            free(table_buf);
+          }
+
+        else if (tag == 0x0105)					// Teleconverter
+          {
+            imgdata.lens.makernotes.TeleconverterID = get2();
+          }
+
+        else if (tag == 0x0114)					// CameraSettings
+          {
+            table_buf = (uchar*)malloc(len);
+            fread(table_buf, len, 1, ifp);
+            switch (len) {
+            case 280:
+            case 364:
+            case 332:
+              // CameraSettings and CameraSettings2 are big endian
+              if (table_buf[2] | table_buf[3])
+                {
+                  lid = (((ushort)table_buf[2])<<8) |
+                    ((ushort)table_buf[3]);
+                  imgdata.lens.makernotes.CurAp =
+                    powf64(2.0f, ((float)lid/8.0f-1.0f)/2.0f);
+                }
+              break;
+            case 1536:
+            case 2048:
+              // CameraSettings3 are little endian
+              parseSonyLensType2(table_buf[1016], table_buf[1015]);
+              if (imgdata.lens.makernotes.LensMount != LIBRAW_MOUNT_Canon_EF)
+                {
+                  switch (table_buf[153]) {
+                  case 16: imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Minolta_A; break;
+                  case 17: imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Sony_E; break;
+                  }
+                }
+              break;
+            }
+            free(table_buf);
+          }
+
+        else if (tag == 0x9050)		// little endian
+          {
+            table_buf_0x9050 = (uchar*)malloc(len);
+            table_buf_0x9050_present = 1;
+            fread(table_buf_0x9050, len, 1, ifp);
+
+            if (imgdata.lens.makernotes.CamID)
+              {
+                process_Sony_0x9050(table_buf_0x9050, imgdata.lens.makernotes.CamID);
+                free (table_buf_0x9050);
+                table_buf_0x9050_present = 0;
+              }
+          }
+
+        else if (tag == 0x940c)
+          {
+            table_buf_0x940c = (uchar*)malloc(len);
+            table_buf_0x940c_present = 1;
+            fread(table_buf_0x940c, len, 1, ifp);
+            if ((imgdata.lens.makernotes.CamID) &&
+                (imgdata.lens.makernotes.CameraMount == LIBRAW_MOUNT_Sony_E))
+              {
+                process_Sony_0x940c(table_buf_0x940c);
+                free(table_buf_0x940c);
+                table_buf_0x940c_present = 0;
+              }
+          }
+
+        else if (((tag == 0xb027) || (tag == 0x010c)) && (imgdata.lens.makernotes.LensID == -1))
+          {
+            imgdata.lens.makernotes.LensID = get4();
+            if ((imgdata.lens.makernotes.LensID > 61184) &&
+                (imgdata.lens.makernotes.LensID < 65535))
+              {
+                imgdata.lens.makernotes.LensID -= 61184;
+                imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Canon_EF;
+              }
+            if (tag == 0x010c) imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Minolta_A;
+          }
+
+        else if (tag == 0xb02a)					// Sony LensSpec
+          {
+            table_buf = (uchar*)malloc(len);
+            fread(table_buf, len, 1, ifp);
+            if (saneSonyCameraInfo(table_buf[1], table_buf[2], table_buf[3], table_buf[4], table_buf[5], table_buf[6]))
+              {
+                if (table_buf[1] | table_buf[2])
+                  imgdata.lens.makernotes.MinFocal =
+                    bcd2dec(table_buf[1]) * 100 + bcd2dec(table_buf[2]);
+                if (table_buf[3] | table_buf[4])
+                  imgdata.lens.makernotes.MaxFocal =
+                    bcd2dec(table_buf[3]) * 100 + bcd2dec(table_buf[4]);
+                if (table_buf[5])
+                  imgdata.lens.makernotes.MaxAp4MinFocal = bcd2dec(table_buf[5]) / 10.0f;
+                if (table_buf[6])
+                  imgdata.lens.makernotes.MaxAp4MaxFocal = bcd2dec(table_buf[6]) / 10.0f;
+                parseSonyLensFeatures(table_buf[0], table_buf[7]);
+              }
+            free(table_buf);
+          }
+      }
+  next:
+    fseek (ifp, save, SEEK_SET);
+  }
+ quit:
+  order = sorder;
+}
+
+#else
+void CLASS parse_makernote_0xc634(int base, int uptag, unsigned dng_writer)
+{
+  /*placeholder */
+}
+#endif
+
+
+void CLASS parse_makernote (int base, int uptag)
+{
+  unsigned offset=0, entries, tag, type, len, save, c;
+  unsigned ver97=0, serial=0, i, wbi=0, wb[4]={0,0,0,0};
+  uchar buf97[324], ci, cj, ck;
+  short morder, sorder=order;
+  char buf[10];
+  unsigned SamsungKey[11];
+  static const double rgb_adobe[3][3] =		// inv(sRGB2XYZ_D65) * AdobeRGB2XYZ_D65
+    {{ 1.398283396477404,     -0.398283116703571, 4.427165001263944E-08},
+     {-1.233904514232401E-07,  0.999999995196570, 3.126724276714121e-08},
+     { 4.561487232726535E-08, -0.042938290466635, 1.042938250416105    }};
+
+  float adobe_cam [3][3];
+  uchar NikonKey;
+
+#ifdef LIBRAW_LIBRARY_BUILD
+  unsigned NikonLensDataVersion = 0;
+  unsigned lenNikonLensData = 0;
+
+  uchar *CanonCameraInfo;
+  unsigned lenCanonCameraInfo = 0;
+
+  uchar *table_buf;
+  uchar *table_buf_0x9050;
+  ushort table_buf_0x9050_present = 0;
+  uchar *table_buf_0x940c;
+  ushort table_buf_0x940c_present = 0;
+#endif
+/*
+   The MakerNote might have its own TIFF header (possibly with
+   its own byte-order!), or it might just be a table.
+ */
+  if (!strcmp(make,"Nokia")) return;
+  fread (buf, 1, 10, ifp);
+  if (!strncmp (buf,"KDK" ,3) ||	/* these aren't TIFF tables */
+      !strncmp (buf,"VER" ,3) ||
+      !strncmp (buf,"IIII",4) ||
+      !strncmp (buf,"MMMM",4)) return;
+  if (!strncmp (buf,"KC"  ,2) ||	/* Konica KD-400Z, KD-510Z */
+      !strncmp (buf,"MLY" ,3)) {	/* Minolta DiMAGE G series */
+    order = 0x4d4d;
+    while ((i=ftell(ifp)) < data_offset && i < 16384) {
+      wb[0] = wb[2];  wb[2] = wb[1];  wb[1] = wb[3];
+      wb[3] = get2();
+      if (wb[1] == 256 && wb[3] == 256 &&
+	  wb[0] > 256 && wb[0] < 640 && wb[2] > 256 && wb[2] < 640)
+	FORC4 cam_mul[c] = wb[c];
+    }
+    goto quit;
+  }
+  if (!strcmp (buf,"Nikon")) {
+    base = ftell(ifp);
+    order = get2();
+    if (get2() != 42) goto quit;
+    offset = get4();
+    fseek (ifp, offset-8, SEEK_CUR);
+  } else if (!strcmp (buf,"OLYMPUS") ||
+             !strcmp (buf,"PENTAX ")) {
+    base = ftell(ifp)-10;
+    fseek (ifp, -2, SEEK_CUR);
+    order = get2();
+    if (buf[0] == 'O') get2();
+  } else if (!strncmp (buf,"SONY",4) ||
+						 !strcmp  (buf,"Panasonic")) {
+    goto nf;
+  } else if (!strncmp (buf,"FUJIFILM",8)) {
+    base = ftell(ifp)-10;
+	nf: order = 0x4949;
+    fseek (ifp,  2, SEEK_CUR);
+  } else if (!strcmp (buf,"OLYMP") ||
+						 !strcmp (buf,"LEICA") ||
+						 !strcmp (buf,"Ricoh") ||
+						 !strcmp (buf,"EPSON"))
+    fseek (ifp, -2, SEEK_CUR);
+  else if (!strcmp (buf,"AOC") ||
+					 !strcmp (buf,"QVC"))
+    fseek (ifp, -4, SEEK_CUR);
+  else {
+    fseek (ifp, -10, SEEK_CUR);
+    if (!strncmp(make,"SAMSUNG",7))
+      base = ftell(ifp);
+  }
+
+  // adjust pos & base for Leica M8/M9/M Mono tags and dir in tag 0x3400
+  if (!strncasecmp(make, "LEICA", 5))
+    {
+      if (!strncmp(model, "M8", 2) ||
+          !strncasecmp(model, "Leica M8", 8) ||
+          !strncasecmp(model, "LEICA X", 7))
+        {
+          base = ftell(ifp)-8;
+        }
+      else if (!strncasecmp(model, "LEICA M (Typ 240)", 17))
+        {
+          base = 0;
+        }
+      else if (!strncmp(model, "M9", 2) ||
+               !strncasecmp(model, "Leica M9", 8) ||
+               !strncasecmp(model, "M Monochrom", 11) ||
+               !strncasecmp(model, "Leica M Monochrom", 11))
+        {
+          if (!uptag)
+            {
+              base = ftell(ifp) - 10;
+              fseek (ifp, 8, SEEK_CUR);
+            }
+          else if (uptag == 0x3400)
+            {
+              fseek (ifp, 10, SEEK_CUR);
+              base += 10;
+            }
+        }
+      else if (!strncasecmp(model, "LEICA T", 7))
+      	{
+      	  base = ftell(ifp)-8;
+#ifdef LIBRAW_LIBRARY_BUILD
+      	  imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Leica_T;
+#endif
+      	}
+    }
+
+  entries = get2();
+
+//  printf("\n*** parse_makernote\n\tmake  =%s=\n\tmodel =%s= \n\tentries: %d\n\tpos: 0x%llx\n",
+//    make, model, entries, ftell(ifp));
+
+  if (entries > 1000) return;
+  morder = order;
+  while (entries--) {
+    order = morder;
+    tiff_get (base, &tag, &type, &len, &save);
+    tag |= uptag << 16;
+
+// 	printf ("\n\tbase: 0x%x tag: 0x%04x type: 0x%x len: 0x%x pos: 0x%llx",
+// 		base, tag, type, len, ftell(ifp));
+
+#ifdef LIBRAW_LIBRARY_BUILD
+
+    if (!strcmp(make, "Canon"))
+      {
+        if (tag == 0x0001)				// camera settings
+          {
+            fseek(ifp, 44, SEEK_CUR);
+            imgdata.lens.makernotes.LensID = get2();
+            imgdata.lens.makernotes.MaxFocal = get2();
+            imgdata.lens.makernotes.MinFocal = get2();
+            imgdata.lens.makernotes.CanonFocalUnits = get2();
+            if (imgdata.lens.makernotes.CanonFocalUnits != 1)
+              {
+                imgdata.lens.makernotes.MaxFocal /= (float)imgdata.lens.makernotes.CanonFocalUnits;
+                imgdata.lens.makernotes.MinFocal /= (float)imgdata.lens.makernotes.CanonFocalUnits;
+              }
+            imgdata.lens.makernotes.MaxAp = _CanonConvertAperture(get2());
+            imgdata.lens.makernotes.MinAp = _CanonConvertAperture(get2());
+          }
+
+        else if (tag == 0x0002)			// focal length
+          {
+            imgdata.lens.makernotes.FocalType = get2();
+            imgdata.lens.makernotes.CurFocal = get2();
+            if ((imgdata.lens.makernotes.CanonFocalUnits != 1) &&
+                imgdata.lens.makernotes.CanonFocalUnits)
+              {
+                imgdata.lens.makernotes.CurFocal /= (float)imgdata.lens.makernotes.CanonFocalUnits;
+              }
+          }
+
+        else if (tag == 0x0004)			// shot info
+          {
+            fseek(ifp, 42, SEEK_CUR);
+            imgdata.lens.makernotes.CurAp = _CanonConvertAperture(get2());
+          }
+
+        else if (tag == 0x000d)			// camera info
+          {
+            CanonCameraInfo = (uchar*)malloc(len);
+            fread(CanonCameraInfo, len, 1, ifp);
+            lenCanonCameraInfo = len;
+          }
+
+        else if (tag == 0x0095 &&		// lens model tag
+                 !imgdata.lens.makernotes.Lens[0])
+          {
+            fread(imgdata.lens.makernotes.Lens, 2, 1, ifp);
+            imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Canon_EF;
+            if (imgdata.lens.makernotes.Lens[0] < 65)					// non-Canon lens
+              fread(imgdata.lens.makernotes.Lens + 2, 62, 1, ifp);
+            else
+              {
+                char efs[2];
+                imgdata.lens.makernotes.LensFeatures_pre[0] = imgdata.lens.makernotes.Lens[0];
+                imgdata.lens.makernotes.LensFeatures_pre[1] = imgdata.lens.makernotes.Lens[1];
+                fread(efs, 2, 1, ifp);
+                if (efs[0] == 45 && (efs[1] == 83 || efs[1] == 69 || efs[1] == 77))
+                  {	// "EF-S, TS-E, MP-E, EF-M" lenses
+                    imgdata.lens.makernotes.Lens[2] = imgdata.lens.makernotes.LensFeatures_pre[2] = efs[0];
+                    imgdata.lens.makernotes.Lens[3] = imgdata.lens.makernotes.LensFeatures_pre[3] = efs[1];
+                    imgdata.lens.makernotes.Lens[4] = 32;
+                    if (efs[1] == 83)
+                      {
+                        imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Canon_EF_S;
+                        imgdata.lens.makernotes.LensFormat = LIBRAW_FORMAT_APSC;
+                      }
+                    else if (efs[1] == 77)
+                      {
+                        imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Canon_EF_M;
+                      }
+                  }
+                else
+                  {																// "EF" lenses
+                    imgdata.lens.makernotes.Lens[2] = 32;
+                    imgdata.lens.makernotes.Lens[3] = efs[0];
+                    imgdata.lens.makernotes.Lens[4] = efs[1];
+                  }
+                fread(imgdata.lens.makernotes.Lens + 5, 58, 1, ifp);
+              }
+          }
+      }
+
+    else if (!strncmp(make, "FUJI", 4))
+      switch (tag) {
+      case 0x1404: imgdata.lens.makernotes.MinFocal = getreal(type); break;
+      case 0x1405: imgdata.lens.makernotes.MaxFocal = getreal(type); break;
+      case 0x1406: imgdata.lens.makernotes.MaxAp4MinFocal = getreal(type); break;
+      case 0x1407: imgdata.lens.makernotes.MaxAp4MaxFocal = getreal(type); break;
+      }
+
+    else if (!strncasecmp(make, "LEICA", 5))
+      {
+        if ((tag == 0x0303) && (type != 4))
+          {
+            fread(imgdata.lens.makernotes.Lens, len, 1, ifp);
+          }
+
+        if ((tag == 0x3405) ||
+            (tag == 0x0310) ||
+            (tag == 0x34003405))
+          {
+            imgdata.lens.makernotes.LensID = get4();
+            imgdata.lens.makernotes.LensID =
+              ((imgdata.lens.makernotes.LensID>>2)<<8) |
+              (imgdata.lens.makernotes.LensID & 0x3);
+            if (imgdata.lens.makernotes.LensID != -1)
+              {
+                if ((model[0] == 'M') ||
+                    !strncasecmp (model, "LEICA M", 7))
+                  {
+                    imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Leica_M;
+                    if (imgdata.lens.makernotes.LensID)
+                    imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Leica_M;
+                  }
+                else if ((model[0] == 'S') ||
+                         !strncasecmp (model, "LEICA S", 7))
+                  {
+                    imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Leica_S;
+                    if (imgdata.lens.makernotes.Lens[0])
+                    imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Leica_S;
+                  }
+              }
+          }
+
+        else if (
+                 ((tag == 0x0313) || (tag == 0x34003406)) &&
+                 (fabs(imgdata.lens.makernotes.CurAp) < 0.17f) &&
+                 ((type == 10) || (type == 5))
+                 )
+          {
+            imgdata.lens.makernotes.CurAp = getreal(type);
+            if (imgdata.lens.makernotes.CurAp > 126.3)
+              imgdata.lens.makernotes.CurAp = 0.0f;
+          }
+
+        else if (tag == 0x3400)
+          {
+            parse_makernote (base, 0x3400);
+          }
+      }
+
+    else if (!strncmp(make, "NIKON",5))
+      {
+        if (tag == 0x0082)						// lens attachment
+          {
+            fread(imgdata.lens.makernotes.Attachment, len, 1, ifp);
+          }
+        else if (tag == 0x0083)				// lens type
+          {
+            imgdata.lens.nikon.NikonLensType = fgetc(ifp);
+            if (!(imgdata.lens.nikon.NikonLensType & 0x01))
+              {
+                imgdata.lens.makernotes.LensFeatures_pre[0] = 'A';
+                imgdata.lens.makernotes.LensFeatures_pre[1] = 'F';
+              }
+            if (imgdata.lens.nikon.NikonLensType & 0x02)
+              {
+                if (imgdata.lens.nikon.NikonLensType & 0x04)
+                  imgdata.lens.makernotes.LensFeatures_suf[0] = 'G';
+                else
+                  imgdata.lens.makernotes.LensFeatures_suf[0] = 'D';
+                imgdata.lens.makernotes.LensFeatures_suf[1] = ' ';
+              }
+            if (imgdata.lens.nikon.NikonLensType & 0x08)
+              {
+                imgdata.lens.makernotes.LensFeatures_suf[2] = 'V';
+                imgdata.lens.makernotes.LensFeatures_suf[3] = 'R';
+              }
+            if (imgdata.lens.nikon.NikonLensType & 0x10)
+              {
+                imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Nikon_CX;
+              }
+            if (imgdata.lens.nikon.NikonLensType & 0x20)
+              {
+                strcpy(imgdata.lens.makernotes.Adapter, "FT-1");
+              }
+            imgdata.lens.nikon.NikonLensType = imgdata.lens.nikon.NikonLensType & 0xdf;
+          }
+        else if (tag == 0x0084)				// lens
+          {
+            imgdata.lens.makernotes.MinFocal = getreal(type);
+            imgdata.lens.makernotes.MaxFocal = getreal(type);
+            imgdata.lens.makernotes.MaxAp4MinFocal = getreal(type);
+            imgdata.lens.makernotes.MaxAp4MaxFocal = getreal(type);
+          }
+        else if (tag == 0x008b)				// lens f-stops
+          {
+            uchar a, b, c;
+            a = fgetc(ifp);
+            b = fgetc(ifp);
+            c = fgetc(ifp);
+            if (c)
+              {
+                imgdata.lens.nikon.NikonLensFStops = a*b*(12/c);
+                imgdata.lens.makernotes.LensFStops =
+                  (float)imgdata.lens.nikon.NikonLensFStops /12.0f;
+              }
+          }
+        else if (tag == 0x0098)				// contains lens data
+          {
+            for (i = 0; i < 4; i++)
+              {
+                NikonLensDataVersion = NikonLensDataVersion * 10 + fgetc(ifp) - '0';
+              }
+            switch (NikonLensDataVersion)
+              {
+              case 100: lenNikonLensData = 9; imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Nikon_F; break;
+              case 101:
+              case 201:	// encrypted, starting from v.201
+              case 202:
+              case 203: lenNikonLensData = 15; imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Nikon_F; break;
+              case 204: lenNikonLensData = 16; imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Nikon_F; break;
+              case 400: lenNikonLensData = 459; break;
+              case 401: lenNikonLensData = 590; break;
+              case 402: lenNikonLensData = 509; break;
+              case 403: lenNikonLensData = 879; break;
+              }
+            table_buf = (uchar*)malloc(lenNikonLensData);
+            fread(table_buf, lenNikonLensData, 1, ifp);
+            if ((NikonLensDataVersion < 201) && lenNikonLensData)
+            {
+              processNikonLensData(table_buf, lenNikonLensData);
+              lenNikonLensData = 0;
+            }
+          }
+      }
+
+    else if (!strncmp(make, "OLYMPUS", 7))
+      {
+        switch (tag) {
+        case 0x0207:
+        case 0x20100100:
+          {
+            uchar sOlyID[7];
+            long unsigned OlyID;
+            fread (sOlyID, len, 1, ifp);
+            OlyID = sOlyID[0];
+            i = 1;
+            while (sOlyID[i])
+              {
+                OlyID = OlyID << 8 | sOlyID[i];
+                i++;
+              }
+            setOlympusBodyFeatures(OlyID);
+          }
+          break;
+        case 0x1002:
+          imgdata.lens.makernotes.CurAp = powf64(2.0f, getreal(type)/2);
+          break;
+        case 0x20100201:
+          imgdata.lens.makernotes.LensID =
+            (unsigned long long)fgetc(ifp)<<16 |
+            (unsigned long long)(fgetc(ifp), fgetc(ifp))<<8 |
+            (unsigned long long)fgetc(ifp);
+          imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_FT;
+          imgdata.lens.makernotes.LensFormat = LIBRAW_FORMAT_FT;
+          if (((imgdata.lens.makernotes.LensID < 0x20000) ||
+               (imgdata.lens.makernotes.LensID > 0x4ffff)) &&
+              (imgdata.lens.makernotes.LensID & 0x10))
+            {
+              imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_mFT;
+            }
+          break;
+        case 0x20100203:
+          fread(imgdata.lens.makernotes.Lens, len, 1, ifp);
+          break;
+        case 0x20100205:
+          imgdata.lens.makernotes.MaxAp4MinFocal = powf64(sqrt(2.0f), get2() / 256.0f);
+          break;
+        case 0x20100206:
+          imgdata.lens.makernotes.MaxAp4MaxFocal = powf64(sqrt(2.0f), get2() / 256.0f);
+          break;
+        case 0x20100207:
+          imgdata.lens.makernotes.MinFocal = (float)get2();
+          break;
+        case 0x20100208:
+          imgdata.lens.makernotes.MaxFocal = (float)get2();
+          if (imgdata.lens.makernotes.MaxFocal > 1000.0f)
+            imgdata.lens.makernotes.MaxFocal = imgdata.lens.makernotes.MinFocal;
+          break;
+        case 0x2010020a:
+          imgdata.lens.makernotes.MaxAp4CurFocal = powf64(sqrt(2.0f), get2() / 256.0f);
+          break;
+        case 0x20100301:
+          imgdata.lens.makernotes.TeleconverterID = fgetc(ifp) << 8;
+          fgetc(ifp);
+          imgdata.lens.makernotes.TeleconverterID =
+            imgdata.lens.makernotes.TeleconverterID | fgetc(ifp);
+          break;
+        case 0x20100303:
+          fread(imgdata.lens.makernotes.Teleconverter, len, 1, ifp);
+          break;
+        case 0x20100403:
+          fread(imgdata.lens.makernotes.Attachment, len, 1, ifp);
+          break;
+        }
+      }
+
+    else if (!strncmp(make, "PENTAX", 6) &&
+             !strncmp(model, "GR", 2))
+      {
+        if ((tag == 0x1001) && (type == 3))
+          {
+            imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_FixedLens;
+            imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_FixedLens;
+            imgdata.lens.makernotes.CameraFormat = LIBRAW_FORMAT_APSC;
+            imgdata.lens.makernotes.LensID = -1;
+            imgdata.lens.makernotes.FocalType = 1;
+          }
+        else if ((tag == 0x1017) && (get2() == 2))
+          {
+            strcpy(imgdata.lens.makernotes.Attachment, "Wide-Angle Adapter");
+          }
+        else if (tag == 0x1500)
+          {
+            imgdata.lens.makernotes.CurFocal = getreal(type);
+          }
+      }
+
+    else if (!strncmp(make, "RICOH", 5) &&
+             strncmp(model, "PENTAX", 6))
+      {
+        if ((tag == 0x1017) && (get2() == 2))
+          {
+            strcpy(imgdata.lens.makernotes.Attachment, "Wide-Angle Adapter");
+          }
+
+        else if (tag == 0x1500)
+          {
+            imgdata.lens.makernotes.CurFocal = getreal(type);
+          }
+
+        else if (tag == 0x2001)
+          {
+            short ntags, cur_tag;
+            fseek(ifp, 20, SEEK_CUR);
+            ntags = get2();
+            cur_tag = get2();
+            while (cur_tag != 0x002c)
+              {
+                fseek(ifp, 10, SEEK_CUR);
+                cur_tag = get2();
+              }
+            fseek(ifp, 6, SEEK_CUR);
+            fseek(ifp, get4()+34, SEEK_SET);
+            imgdata.lens.makernotes.LensID = getc(ifp) - '0';
+            switch(imgdata.lens.makernotes.LensID)
+              {
+            	case 1:
+            	case 2:
+            	case 3:
+            	case 5:
+            	case 6:
+            		imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_FixedLens;
+                        imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_RicohModule;
+                break;
+              case 8:
+                imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Leica_M;
+                imgdata.lens.makernotes.CameraFormat = LIBRAW_FORMAT_APSC;
+                imgdata.lens.makernotes.LensID = -1;
+                break;
+              default:
+              	imgdata.lens.makernotes.LensID = -1;
+              }
+          }
+      }
+
+    else if (!strncmp(make, "PENTAX", 6) ||
+             !strncmp(model, "PENTAX", 6) ||
+             (!strncmp(make, "SAMSUNG", 7) && dng_version) &&
+             strncmp(model, "GR", 2))
+      {
+        if (tag == 0x0005)
+          {
+            unique_id = get4();
+            setPentaxBodyFeatures(unique_id);
+          }
+        else if (tag == 0x0013)
+          {
+            imgdata.lens.makernotes.CurAp = (float)get2()/10.0f;
+          }
+        else if (tag == 0x001d)
+          {
+            imgdata.lens.makernotes.CurFocal = (float)get4()/100.0f;
+          }
+        else if (tag == 0x003f)
+          {
+            imgdata.lens.makernotes.LensID = fgetc(ifp) << 8 | fgetc(ifp);
+          }
+        else if (tag == 0x0207)
+          {
+            ushort iLensData = 0;
+            table_buf = (uchar*)malloc(len);
+            fread(table_buf, len, 1, ifp);
+            if ((imgdata.lens.makernotes.CamID < 0x12b9c) ||
+                ((imgdata.lens.makernotes.CamID == 0x12b9c) ||	// K100D
+                 (imgdata.lens.makernotes.CamID == 0x12b9d) ||	// K110D
+                 (imgdata.lens.makernotes.CamID == 0x12ba2)	&&	// K100D Super
+                 (!table_buf[20] || (table_buf[20] == 0xff))))
+              {
+                iLensData = 3;
+                if (imgdata.lens.makernotes.LensID == -1)
+                  imgdata.lens.makernotes.LensID =
+                    (((unsigned)table_buf[0]) << 8) + table_buf[1];
+              }
+            else switch (len)
+              {
+              case 90:							// LensInfo3
+                iLensData = 13;
+                if (imgdata.lens.makernotes.LensID == -1)
+                  imgdata.lens.makernotes.LensID =
+                    ((unsigned)((table_buf[1] & 0x0f) + table_buf[3]) <<8) + table_buf[4];
+                break;
+              case 91:							// LensInfo4
+                iLensData = 12;
+                if (imgdata.lens.makernotes.LensID == -1)
+                  imgdata.lens.makernotes.LensID =
+                    ((unsigned)((table_buf[1] & 0x0f) + table_buf[3]) <<8) + table_buf[4];
+                break;
+              case 80:							// LensInfo5
+              case 128:
+                iLensData = 15;
+                if (imgdata.lens.makernotes.LensID == -1)
+                  imgdata.lens.makernotes.LensID =
+                    ((unsigned)((table_buf[1] & 0x0f) + table_buf[4]) <<8) + table_buf[5];
+                break;
+              default:
+                if (imgdata.lens.makernotes.CamID >= 0x12b9c)		// LensInfo2
+                  {
+                    iLensData = 4;
+                    if (imgdata.lens.makernotes.LensID == -1)
+                      imgdata.lens.makernotes.LensID =
+                        ((unsigned)((table_buf[0] & 0x0f) + table_buf[2]) <<8) + table_buf[3];
+                  }
+              }
+            if (iLensData)
+              {
+                if (table_buf[iLensData+9] && (fabs(imgdata.lens.makernotes.CurFocal) < 0.1f))
+                  imgdata.lens.makernotes.CurFocal =
+                    10*(table_buf[iLensData+9]>>2) * powf64(4, (table_buf[iLensData+9] & 0x03)-2);
+                if (table_buf[iLensData+10] & 0xf0)
+                  imgdata.lens.makernotes.MaxAp4CurFocal =
+                    powf64(2.0f, (float)((table_buf[iLensData+10] & 0xf0) >>4)/4.0f);
+                if (table_buf[iLensData+10] & 0x0f)
+                  imgdata.lens.makernotes.MinAp4CurFocal =
+                    powf64(2.0f, (float)((table_buf[iLensData+10] & 0x0f) + 10)/4.0f);
+                if (
+                    (imgdata.lens.makernotes.CamID != 0x12e6c) &&	// K-r
+                    (imgdata.lens.makernotes.CamID != 0x12e76) &&	// K-5
+                    (imgdata.lens.makernotes.CamID != 0x12f70)		// K-5 II
+                    //        	  		(imgdata.lens.makernotes.CamID != 0x12f71)		// K-5 II s
+                    )
+                  {
+                    switch (table_buf[iLensData] & 0x06)
+                      {
+                      case 0: imgdata.lens.makernotes.MinAp4MinFocal = 22.0f; break;
+                      case 2: imgdata.lens.makernotes.MinAp4MinFocal = 32.0f; break;
+                      case 4: imgdata.lens.makernotes.MinAp4MinFocal = 45.0f; break;
+                      case 6: imgdata.lens.makernotes.MinAp4MinFocal = 16.0f; break;
+                      }
+                    if (table_buf[iLensData] & 0x70)
+                      imgdata.lens.makernotes.LensFStops =
+                        ((float)(((table_buf[iLensData] & 0x70) >> 4) ^ 0x07)) / 2.0f + 5.0f;
+                    if ((table_buf[iLensData+14] > 1) &&
+                        (fabs(imgdata.lens.makernotes.MaxAp4CurFocal) < 0.7f))
+                      imgdata.lens.makernotes.MaxAp4CurFocal =
+                        powf64(2.0f, (float)((table_buf[iLensData+14] & 0x7f) -1)/32.0f);
+                  }
+                else if ((imgdata.lens.makernotes.CamID != 0x12e76) &&	// K-5
+                         (table_buf[iLensData+15] > 1) &&
+                         (fabs(imgdata.lens.makernotes.MaxAp4CurFocal) < 0.7f))
+                  {
+                    imgdata.lens.makernotes.MaxAp4CurFocal =
+                      powf64(2.0f, (float)((table_buf[iLensData+15] & 0x7f) -1)/32.0f);
+                  }
+              }
+            free(table_buf);
+          }
+        else if (tag == 0x0239)		// Q-series lens info (LensInfoQ)
+          {
+            char LensInfo [20];
+            fseek (ifp, 2, SEEK_CUR);
+            fread(imgdata.lens.makernotes.Lens, 30, 1, ifp);
+            strcat(imgdata.lens.makernotes.Lens, " ");
+            fread(LensInfo, 20, 1, ifp);
+            strcat(imgdata.lens.makernotes.Lens, LensInfo);
+          }
+      }
+
+    else if (!strncmp(make, "SAMSUNG", 7))
+      {
+        if (tag == 0x0002)
+          {
+            if(get4() == 0x2000)
+              {
+                imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Samsung_NX;
+              }
+            else if (!strncmp(model, "NX mini", 7))
+              {
+                imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Samsung_NX_M;
+              }
+            else
+              {
+                imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_FixedLens;
+                imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_FixedLens;
+              }
+          }
+        else if (tag == 0x0003)
+          {
+            unique_id = imgdata.lens.makernotes.CamID = get4();
+          }
+        else if (tag == 0xa003)
+          {
+            imgdata.lens.makernotes.LensID = get2();
+            if (imgdata.lens.makernotes.LensID)
+              imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Samsung_NX;
+          }
+        else if (tag == 0xa019)
+          {
+            imgdata.lens.makernotes.CurAp = getreal(type);
+          }
+        else if (tag == 0xa01a)
+          {
+            imgdata.lens.makernotes.FocalLengthIn35mmFormat = get4() / 10.0f;
+            if (imgdata.lens.makernotes.FocalLengthIn35mmFormat < 10.0f)
+              imgdata.lens.makernotes.FocalLengthIn35mmFormat *= 10.0f;
+          }
+      }
+
+    else if (!strncasecmp(make, "SONY", 4) ||
+             !strncasecmp(make, "Konica", 6) ||
+             !strncasecmp(make, "Minolta", 7) ||
+             (!strncasecmp(make, "Hasselblad", 10) &&
+              (!strncasecmp(model, "Stellar", 7) ||
+               !strncasecmp(model, "Lunar", 5) ||
+               !strncasecmp(model, "HV",2))))
+      {
+        ushort lid;
+
+        if (tag == 0xb001)			// Sony ModelID
+        {
+          unique_id = get2();
+          setSonyBodyFeatures(unique_id);
+          if (table_buf_0x9050_present)
+            {
+              process_Sony_0x9050(table_buf_0x9050, unique_id);
+              free (table_buf_0x9050);
+              table_buf_0x9050_present = 0;
+            }
+          if (table_buf_0x940c_present)
+            {
+              if (imgdata.lens.makernotes.CameraMount == LIBRAW_MOUNT_Sony_E)
+                {
+                  process_Sony_0x940c(table_buf_0x940c);
+                }
+              free (table_buf_0x940c);
+              table_buf_0x940c_present = 0;
+            }
+        }
+
+        else if ((tag == 0x0010) &&					// CameraInfo
+                 strncasecmp(model, "DSLR-A100", 9) &&
+                 strncasecmp(model, "NEX-5C", 6) &&
+                 !strncasecmp(make, "SONY", 4) &&
+                 ((len == 368) ||			// a700
+                  (len == 5478) ||		// a850, a900
+                  (len == 5506) ||		// a200, a300, a350
+                  (len == 6118) ||		// a230, a290, a330, a380, a390
+
+                  // a450, a500, a550, a560, a580
+                  // a33, a35, a55
+                  // NEX3, NEX5, NEX5C, NEXC3, VG10E
+                  (len == 15360))
+                 )
+          {
+            table_buf = (uchar*)malloc(len);
+            fread(table_buf, len, 1, ifp);
+            if (memcmp(table_buf, "\xff\xff\xff\xff\xff\xff\xff\xff", 8) &&
+                memcmp(table_buf, "\x00\x00\x00\x00\x00\x00\x00\x00", 8))
+              {
+                switch (len)
+                  {
+                  case 368:
+                  case 5478:
+                    // a700, a850, a900: CameraInfo
+                    if (table_buf[0] | table_buf[3])
+                      imgdata.lens.makernotes.MinFocal =
+                        bcd2dec(table_buf[0]) * 100 + bcd2dec(table_buf[3]);
+                    if (table_buf[2] | table_buf[5])
+                      imgdata.lens.makernotes.MaxFocal =
+                        bcd2dec(table_buf[2]) * 100 + bcd2dec(table_buf[5]);
+                    if (table_buf[4])
+                      imgdata.lens.makernotes.MaxAp4MinFocal = bcd2dec(table_buf[4]) / 10.0f;
+                    if (table_buf[4])
+                      imgdata.lens.makernotes.MaxAp4MaxFocal = bcd2dec(table_buf[7]) / 10.0f;
+                    parseSonyLensFeatures(table_buf[1], table_buf[6]);
+                    break;
+                  default:
+                    // CameraInfo2 & 3
+                    if (table_buf[1] | table_buf[2])
+                      imgdata.lens.makernotes.MinFocal =
+                        bcd2dec(table_buf[1]) * 100 + bcd2dec(table_buf[2]);
+                    if (table_buf[3] | table_buf[4])
+                      imgdata.lens.makernotes.MaxFocal =
+                        bcd2dec(table_buf[3]) * 100 + bcd2dec(table_buf[4]);
+                    if (table_buf[5])
+                      imgdata.lens.makernotes.MaxAp4MinFocal = bcd2dec(table_buf[5]) / 10.0f;
+                    if (table_buf[6])
+                      imgdata.lens.makernotes.MaxAp4MaxFocal = bcd2dec(table_buf[6]) / 10.0f;
+                    parseSonyLensFeatures(table_buf[0], table_buf[7]);
+                }
+              }
+            free(table_buf);
+          }
+
+        else if (tag == 0x0105)					// Teleconverter
+          {
+            imgdata.lens.makernotes.TeleconverterID = get2();
+          }
+
+        else if (tag == 0x0114)					// CameraSettings
+          {
+            table_buf = (uchar*)malloc(len);
+            fread(table_buf, len, 1, ifp);
+            switch (len) {
+            case 280:
+            case 364:
+            case 332:
+              // CameraSettings and CameraSettings2 are big endian
+              if (table_buf[2] | table_buf[3])
+                {
+                  lid = (((ushort)table_buf[2])<<8) |
+                    ((ushort)table_buf[3]);
+                  imgdata.lens.makernotes.CurAp =
+                    powf64(2.0f, ((float)lid/8.0f-1.0f)/2.0f);
+                }
+              break;
+            case 1536:
+            case 2048:
+              // CameraSettings3 are little endian
+              parseSonyLensType2(table_buf[1016], table_buf[1015]);
+              if (imgdata.lens.makernotes.LensMount != LIBRAW_MOUNT_Canon_EF)
+                {
+                  switch (table_buf[153]) {
+                  case 16: imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Minolta_A; break;
+                  case 17: imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Sony_E; break;
+                  }
+                }
+              break;
+            }
+            free(table_buf);
+          }
+
+        else if (tag == 0x9050)		// little endian
+          {
+            table_buf_0x9050 = (uchar*)malloc(len);
+            table_buf_0x9050_present = 1;
+            fread(table_buf_0x9050, len, 1, ifp);
+
+            if (imgdata.lens.makernotes.CamID)
+              {
+                process_Sony_0x9050(table_buf_0x9050, imgdata.lens.makernotes.CamID);
+                free (table_buf_0x9050);
+                table_buf_0x9050_present = 0;
+              }
+          }
+
+        else if (tag == 0x940c)
+          {
+            table_buf_0x940c = (uchar*)malloc(len);
+            table_buf_0x940c_present = 1;
+            fread(table_buf_0x940c, len, 1, ifp);
+            if ((imgdata.lens.makernotes.CamID) &&
+                (imgdata.lens.makernotes.CameraMount == LIBRAW_MOUNT_Sony_E))
+              {
+                process_Sony_0x940c(table_buf_0x940c);
+                free(table_buf_0x940c);
+                table_buf_0x940c_present = 0;
+              }
+          }
+
+        else if (((tag == 0xb027) || (tag == 0x010c)) && (imgdata.lens.makernotes.LensID == -1))
+          {
+            imgdata.lens.makernotes.LensID = get4();
+            if ((imgdata.lens.makernotes.LensID > 61184) &&
+                (imgdata.lens.makernotes.LensID < 65535))
+              {
+                imgdata.lens.makernotes.LensID -= 61184;
+                imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Canon_EF;
+              }
+            if (tag == 0x010c) imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Minolta_A;
+          }
+
+        else if (tag == 0xb02a)					// Sony LensSpec
+          {
+            table_buf = (uchar*)malloc(len);
+            fread(table_buf, len, 1, ifp);
+            if (table_buf[1] | table_buf[2])
+              imgdata.lens.makernotes.MinFocal =
+                bcd2dec(table_buf[1]) * 100 + bcd2dec(table_buf[2]);
+            if (table_buf[3] | table_buf[4])
+              imgdata.lens.makernotes.MaxFocal =
+                bcd2dec(table_buf[3]) * 100 + bcd2dec(table_buf[4]);
+            if (table_buf[5])
+              imgdata.lens.makernotes.MaxAp4MinFocal = bcd2dec(table_buf[5]) / 10.0f;
+            if (table_buf[6])
+              imgdata.lens.makernotes.MaxAp4MaxFocal = bcd2dec(table_buf[6]) / 10.0f;
+            parseSonyLensFeatures(table_buf[0], table_buf[7]);
+            free(table_buf);
+          }
+      }
 #endif
-    }
-    goto quit;
-  }
-  if (!strcmp (buf,"Nikon")) {
-    base = ftell(ifp);
-    order = get2();
-    if (get2() != 42) goto quit;
-    offset = get4();
-    fseek (ifp, offset-8, SEEK_CUR);
-  } else if (!strcmp (buf,"OLYMPUS")) {
-    base = ftell(ifp)-10;
-    fseek (ifp, -2, SEEK_CUR);
-    order = get2();  get2();
-  } else if (!strncmp (buf,"SONY",4) ||
-	     !strcmp  (buf,"Panasonic")) {
-    goto nf;
-  } else if (!strncmp (buf,"FUJIFILM",8)) {
-    base = ftell(ifp)-10;
-nf: order = 0x4949;
-    fseek (ifp,  2, SEEK_CUR);
-  } else if (!strcmp (buf,"OLYMP") ||
-	     !strcmp (buf,"LEICA") ||
-	     !strcmp (buf,"Ricoh") ||
-	     !strcmp (buf,"EPSON"))
-    fseek (ifp, -2, SEEK_CUR);
-  else if (!strcmp (buf,"AOC") ||
-	   !strcmp (buf,"QVC"))
-    fseek (ifp, -4, SEEK_CUR);
-  else {
-    fseek (ifp, -10, SEEK_CUR);
-    if (!strncmp(make,"SAMSUNG",7))
-      base = ftell(ifp);
-  }
-  entries = get2();
-  if (entries > 1000) return;
-  morder = order;
-  while (entries--) {
-    order = morder;
-    tiff_get (base, &tag, &type, &len, &save);
-    tag |= uptag << 16;
+
     if (tag == 2 && strstr(make,"NIKON") && !iso_speed)
       iso_speed = (get2(),get2());
+    if (tag == 37 && strstr(make,"NIKON") && (!iso_speed || iso_speed == 65535))
+      {
+        unsigned char cc;
+        fread(&cc,1,1,ifp);
+        iso_speed = int(100.0 * powf64(2.0f,float(cc)/12.0-5.0));
+      }
     if (tag == 4 && len > 26 && len < 35) {
-      if ((i=(get4(),get2())) != 0x7fff && !iso_speed)
-	iso_speed = 50 * pow (2.0, i/32.0 - 4);
+      if ((i=(get4(),get2())) != 0x7fff && (!iso_speed || iso_speed == 65535))
+	iso_speed = 50 * powf64(2.0, i/32.0 - 4);
       if ((i=(get2(),get2())) != 0x7fff && !aperture)
-	aperture = pow (2.0, i/64.0);
+	aperture = powf64(2.0, i/64.0);
       if ((i=get2()) != 0xffff && !shutter)
-	shutter = pow (2.0, (short) i/-32.0);
+	shutter = powf64(2.0, (short) i/-32.0);
       wbi = (get2(),get2());
       shot_order = (get2(),get2());
     }
@@ -4750,22 +8115,119 @@ nf: order = 0x4949;
       shot_order = get4();
     if (tag == 9 && !strcmp(make,"Canon"))
       fread (artist, 64, 1, ifp);
-    if (tag == 0xc && len == 4) {
-      cam_mul[0] = getreal(type);
-      cam_mul[2] = getreal(type);
-#ifdef LIBRAW_LIBRARY_BUILD
-      color_flags.cam_mul_state = LIBRAW_COLORSTATE_LOADED;
-#endif
-    }
+    if (tag == 0xc && len == 4)
+      FORC3 cam_mul[(c << 1 | c >> 1) & 3] = getreal(type);
     if (tag == 0xd && type == 7 && get2() == 0xaaaa) {
       for (c=i=2; (ushort) c != 0xbbbb && i < len; i++)
-        c = c << 8 | fgetc(ifp);
+	c = c << 8 | fgetc(ifp);
       while ((i+=4) < len-5)
-        if (get4() == 257 && (i=len) && (c = (get4(),fgetc(ifp))) < 3)
-          flip = "065"[c]-'0';
-     }
+	if (get4() == 257 && (i=len) && (c = (get4(),fgetc(ifp))) < 3)
+	  flip = "065"[c]-'0';
+    }
+
     if (tag == 0x10 && type == 4)
-      unique_id = get4();
+      {
+        unique_id = get4();
+
+#ifdef LIBRAW_LIBRARY_BUILD
+        setCanonBodyFeatures(unique_id);
+        if (lenCanonCameraInfo) processCanonCameraInfo(unique_id, CanonCameraInfo);
+#endif
+      }
+
+#ifdef LIBRAW_LIBRARY_BUILD
+    if(tag == 0x20400805 && len == 2 && !strncasecmp(make,"Olympus",7))
+      {
+        imgdata.color.OlympusSensorCalibration[0]=getreal(type);
+        imgdata.color.OlympusSensorCalibration[1]=getreal(type);
+      }
+    if (tag == 0x4001 && len > 500 && !strcasecmp(make,"Canon"))
+      {
+        long int save1 = ftell(ifp);
+        switch (len)
+          {
+          case 582:
+            imgdata.color.canon_makernotes.CanonColorDataVer = 1;	// 20D / 350D
+            break;
+          case 653:
+            imgdata.color.canon_makernotes.CanonColorDataVer = 2;	// 1Dmk2 / 1DsMK2
+            break;
+          case 796:
+            imgdata.color.canon_makernotes.CanonColorDataVer = 3;	// 1DmkIIN / 5D / 30D / 400D
+
+            // 1DmkIII / 1DSmkIII / 1DmkIV / 5DmkII
+            // 7D / 40D / 50D / 60D / 450D / 500D
+            // 550D / 1000D / 1100D
+          case 674: case 692: case 702: case 1227: case 1250:
+          case 1251: case 1337: case 1338: case 1346:
+            imgdata.color.canon_makernotes.CanonColorDataVer = 4;
+            imgdata.color.canon_makernotes.CanonColorDataSubVer = get2();
+            {
+              fseek (ifp, save1+(0x0e7<<1), SEEK_SET); // offset 231 short
+              int bls=0;
+              FORC4 bls+=get2();
+              imgdata.color.canon_makernotes.AverageBlackLevel = bls/4;
+            }
+            if ((imgdata.color.canon_makernotes.CanonColorDataSubVer == 4)
+                || (imgdata.color.canon_makernotes.CanonColorDataSubVer == 5))
+              {
+                fseek (ifp, save1+(0x2b9<<1), SEEK_SET);		// offset 697 shorts
+                imgdata.color.canon_makernotes.SpecularWhiteLevel = get2();
+              }
+            else if ((imgdata.color.canon_makernotes.CanonColorDataSubVer == 6) ||
+                     (imgdata.color.canon_makernotes.CanonColorDataSubVer == 7))
+              {
+                fseek (ifp, save1+(0x2d0<<1), SEEK_SET);		// offset 720 shorts
+                imgdata.color.canon_makernotes.SpecularWhiteLevel = get2();
+              }
+            else if (imgdata.color.canon_makernotes.CanonColorDataSubVer == 9)
+              {
+                fseek (ifp, save1+(0x2d4<<1), SEEK_SET);		// offset 724 shorts
+                imgdata.color.canon_makernotes.SpecularWhiteLevel = get2();
+              }
+            break;
+
+          case 5120:
+            imgdata.color.canon_makernotes.CanonColorDataVer = 5;	// PowerSot G10
+            break;
+
+          case 1273: case 1275:
+            imgdata.color.canon_makernotes.CanonColorDataVer = 6;	// 600D / 1200D
+            imgdata.color.canon_makernotes.CanonColorDataSubVer = get2();
+            {
+              fseek (ifp, save1+(0x0fb<<1), SEEK_SET);			// offset 251 short
+              int bls=0;
+              FORC4 bls+=get2();
+              imgdata.color.canon_makernotes.AverageBlackLevel = bls/4;
+            }
+            fseek (ifp, save1+(0x1e4<<1), SEEK_SET);			// offset 484 shorts
+            imgdata.color.canon_makernotes.SpecularWhiteLevel = get2();
+            break;
+
+            // 1DX / 5DmkIII / 6D / 100D / 650D / 700D / M / 7DmkII / 750D / 760D
+          case 1312: case 1313: case 1316: case 1506:
+            imgdata.color.canon_makernotes.CanonColorDataVer = 7;
+            imgdata.color.canon_makernotes.CanonColorDataSubVer = get2();
+            {
+              fseek (ifp, save1+(0x114<<1), SEEK_SET);			// offset 276 shorts
+              int bls=0;
+              FORC4 bls+=get2();
+              imgdata.color.canon_makernotes.AverageBlackLevel = bls/4;
+            }
+            if (imgdata.color.canon_makernotes.CanonColorDataSubVer == 10)
+              {
+                fseek (ifp, save1+(0x1fd<<1), SEEK_SET);		// offset 509 shorts
+                imgdata.color.canon_makernotes.SpecularWhiteLevel = get2();
+              } else if (imgdata.color.canon_makernotes.CanonColorDataSubVer == 11)
+              {
+                fseek (ifp, save1+(0x2dd<<1), SEEK_SET);		// offset 733 shorts
+                imgdata.color.canon_makernotes.SpecularWhiteLevel = get2();
+              }
+            break;
+          }
+        fseek (ifp, save1, SEEK_SET);
+      }
+#endif
     if (tag == 0x11 && is_raw && !strncmp(make,"NIKON",5)) {
       fseek (ifp, get4()+base, SEEK_SET);
       parse_tiff_ifd (base);
@@ -4792,6 +8254,16 @@ nf: order = 0x4949;
     if (tag == 0x1d)
       while ((c = fgetc(ifp)) && c != EOF)
 	serial = serial*10 + (isdigit(c) ? c - '0' : c % 10);
+    if (tag == 0x29 && type == 1) {  // Canon PowerShot G9
+      c = wbi < 18 ? "012347800000005896"[wbi]-'0' : 0;
+      fseek (ifp, 8 + c*32, SEEK_CUR);
+      FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get4();
+    }
+#ifndef LIBRAW_LIBRARY_BUILD
+	// works for some files, but not all
+    if (tag == 0x3d && type == 3 && len == 4)
+      FORC4 cblack[c ^ c >> 1] = get2() >> (14-tiff_ifd[2].bps);
+#endif
     if (tag == 0x81 && type == 4) {
       data_offset = get4();
       fseek (ifp, data_offset + 41, SEEK_SET);
@@ -4799,14 +8271,6 @@ nf: order = 0x4949;
       raw_width  = get2();
       filters = 0x61616161;
     }
-    if (tag == 0x29 && type == 1) {
-      c = wbi < 18 ? "012347800000005896"[wbi]-'0' : 0;
-      fseek (ifp, 8 + c*32, SEEK_CUR);
-      FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get4();
-#ifdef LIBRAW_LIBRARY_BUILD
-      color_flags.cam_mul_state = LIBRAW_COLORSTATE_LOADED;
-#endif
-    }
     if ((tag == 0x81  && type == 7) ||
 	(tag == 0x100 && type == 7) ||
 	(tag == 0x280 && type == 1)) {
@@ -4826,9 +8290,6 @@ nf: order = 0x4949;
 	case 100:
 	  fseek (ifp, 68, SEEK_CUR);
 	  FORC4 cam_mul[(c >> 1) | ((c & 1) << 1)] = get2();
-#ifdef LIBRAW_LIBRARY_BUILD
-          color_flags.cam_mul_state = LIBRAW_COLORSTATE_LOADED;
-#endif
 	  break;
 	case 102:
 	  fseek (ifp, 6, SEEK_CUR);
@@ -4836,9 +8297,6 @@ nf: order = 0x4949;
 	case 103:
 	  fseek (ifp, 16, SEEK_CUR);
 	  FORC4 cam_mul[c] = get2();
-#ifdef LIBRAW_LIBRARY_BUILD
-          color_flags.cam_mul_state = LIBRAW_COLORSTATE_LOADED;
-#endif
       }
       if (ver97 >= 200) {
 	if (ver97 != 205) fseek (ifp, 280, SEEK_CUR);
@@ -4853,23 +8311,38 @@ nf: order = 0x4949;
     if (tag == 0xa4 && type == 3) {
       fseek (ifp, wbi*48, SEEK_CUR);
       FORC3 cam_mul[c] = get2();
-#ifdef LIBRAW_LIBRARY_BUILD
-      color_flags.cam_mul_state = LIBRAW_COLORSTATE_LOADED;
-#endif
     }
-    if (tag == 0xa7 && (unsigned) (ver97-200) < 17) {
-      ci = xlat[0][serial & 0xff];
-      cj = xlat[1][fgetc(ifp)^fgetc(ifp)^fgetc(ifp)^fgetc(ifp)];
-      ck = 0x60;
-      for (i=0; i < 324; i++)
-	buf97[i] ^= (cj += ci * ck++);
-      i = "66666>666;6A;:;55"[ver97-200] - '0';
-      FORC4 cam_mul[c ^ (c >> 1) ^ (i & 1)] =
-	sget2 (buf97 + (i & -2) + c*2);
+
+    if (tag == 0xa7) {	// shutter count
+      NikonKey = fgetc(ifp)^fgetc(ifp)^fgetc(ifp)^fgetc(ifp);
+      if ( (unsigned) (ver97-200) < 17) {
+        ci = xlat[0][serial & 0xff];
+        cj = xlat[1][NikonKey];
+        ck = 0x60;
+        for (i=0; i < 324; i++)
+          buf97[i] ^= (cj += ci * ck++);
+        i = "66666>666;6A;:;55"[ver97-200] - '0';
+        FORC4 cam_mul[c ^ (c >> 1) ^ (i & 1)] =
+          sget2 (buf97 + (i & -2) + c*2);
+      }
 #ifdef LIBRAW_LIBRARY_BUILD
-      color_flags.cam_mul_state = LIBRAW_COLORSTATE_LOADED;
+      if ((NikonLensDataVersion > 200) && lenNikonLensData)
+      {
+        ci = xlat[0][serial & 0xff];
+        cj = xlat[1][NikonKey];
+        ck = 0x60;
+        for (i = 0; i < lenNikonLensData; i++)
+          table_buf[i] ^= (cj += ci * ck++);
+        processNikonLensData(table_buf, lenNikonLensData);
+        lenNikonLensData = 0;
+    	}
 #endif
     }
+
+    if(tag == 0xb001 && type == 3)	// Sony ModelID
+      {
+        unique_id = get2();
+      }
     if (tag == 0x200 && len == 3)
       shot_order = (get4(),get4());
     if (tag == 0x200 && len == 4)
@@ -4880,6 +8353,17 @@ nf: order = 0x4949;
       meta_offset = ftell(ifp);
     if (tag == 0x401 && type == 4 && len == 4)
       FORC4 cblack[c ^ c >> 1] = get4();
+#ifdef LIBRAW_LIBRARY_BUILD
+    // not corrected for file bitcount, to be patched in open_datastream
+    if (tag == 0x03d && strstr(make,"NIKON") && len == 4)
+      {
+        FORC4 cblack[c ^ c >> 1] = get2();
+        i = cblack[3];
+        FORC3 if(i>cblack[c]) i = cblack[c];
+        FORC4 cblack[c]-=i;
+        black += i;
+      }
+#endif
     if (tag == 0xe01) {		/* Nikon Capture Note */
       order = 0x4949;
       fseek (ifp, 22, SEEK_CUR);
@@ -4895,9 +8379,6 @@ nf: order = 0x4949;
       fseek (ifp, 48, SEEK_CUR);
       cam_mul[0] = get2() * 508 * 1.078 / 0x10000;
       cam_mul[2] = get2() * 382 * 1.173 / 0x10000;
-#ifdef LIBRAW_LIBRARY_BUILD
-      color_flags.cam_mul_state = LIBRAW_COLORSTATE_LOADED;
-#endif
     }
     if (tag == 0xf00 && type == 7) {
       if (len == 614)
@@ -4908,46 +8389,47 @@ nf: order = 0x4949;
       goto get2_256;
     }
     if ((tag == 0x1011 && len == 9) || tag == 0x20400200)
-        {
-      for (i=0; i < 3; i++)
-	FORC3 cmatrix[i][c] = ((short) get2()) / 256.0;
-#ifdef LIBRAW_LIBRARY_BUILD
-      color_flags.cmatrix_state = LIBRAW_COLORSTATE_LOADED;
-#endif
-        }
+      {
+        if(!strncasecmp(make,"Olympus", 7))
+          {
+            int j,k;
+            for (i=0; i < 3; i++)
+              FORC3 adobe_cam[i][c] = ((short) get2()) / 256.0;
+            for (i=0; i < 3; i++)
+              for (j=0; j < 3; j++)
+                for (cmatrix[i][j] = k=0; k < 3; k++)
+                  cmatrix[i][j] += rgb_adobe[i][k] * adobe_cam[k][j];
+          }
+        else
+          for (i=0; i < 3; i++)
+            FORC3 cmatrix[i][c] = ((short) get2()) / 256.0;
+      }
     if ((tag == 0x1012 || tag == 0x20400600) && len == 4)
       FORC4 cblack[c ^ c >> 1] = get2();
     if (tag == 0x1017 || tag == 0x20400100)
-        {
       cam_mul[0] = get2() / 256.0;
-#ifdef LIBRAW_LIBRARY_BUILD
-      color_flags.cam_mul_state = LIBRAW_COLORSTATE_LOADED;
-#endif
-        }
     if (tag == 0x1018 || tag == 0x20400100)
-        {
       cam_mul[2] = get2() / 256.0;
-#ifdef LIBRAW_LIBRARY_BUILD
-      color_flags.cam_mul_state = LIBRAW_COLORSTATE_LOADED;
-#endif
-        }
     if (tag == 0x2011 && len == 2) {
 get2_256:
       order = 0x4d4d;
       cam_mul[0] = get2() / 256.0;
       cam_mul[2] = get2() / 256.0;
-#ifdef LIBRAW_LIBRARY_BUILD
-      color_flags.cam_mul_state = LIBRAW_COLORSTATE_LOADED;
-#endif
     }
-    if ((tag | 0x70) == 0x2070 && type == 4)
+    if ((tag | 0x70) == 0x2070 && (type == 4 || type == 13))
       fseek (ifp, get4()+base, SEEK_SET);
-    if (tag == 0x2010 && type != 7)
-      load_raw = &CLASS olympus_load_raw;
     if (tag == 0x2020)
       parse_thumb_note (base, 257, 258);
     if (tag == 0x2040)
       parse_makernote (base, 0x2040);
+#ifdef LIBRAW_LIBRARY_BUILD
+	// IB start
+	if (tag == 0x2010)
+	  {
+		parse_makernote(base, 0x2010);
+	  }
+	// IB end
+#endif
     if (tag == 0xb028) {
       fseek (ifp, get4()+base, SEEK_SET);
       parse_thumb_note (base, 136, 137);
@@ -4957,21 +8439,32 @@ get2_256:
       fseek (ifp, i, SEEK_CUR);
 get2_rggb:
       FORC4 cam_mul[c ^ (c >> 1)] = get2();
-#ifdef LIBRAW_LIBRARY_BUILD
-      color_flags.cam_mul_state = LIBRAW_COLORSTATE_LOADED;
-#endif
-#if 1
-      i = len == 1312 ? 112:22;
+      i = len >> 3 == 164 || len == 1506 ? 112:22;
       fseek (ifp, i, SEEK_CUR);
-#else
-      fseek (ifp, 22, SEEK_CUR);
-#endif
       FORC4 sraw_mul[c ^ (c >> 1)] = get2();
     }
-    if (tag == 0xa021)
-      FORC4 cam_mul[c ^ (c >> 1)] = get4();
-    if (tag == 0xa028)
-      FORC4 cam_mul[c ^ (c >> 1)] -= get4();
+    if(!strcasecmp(make,"Samsung"))
+      {
+        if (tag == 0xa020) // get the full Samsung encryption key
+            for (i=0; i<11; i++) SamsungKey[i] = get4();
+        if (tag == 0xa021) // get and decode Samsung cam_mul array
+            FORC4 cam_mul[c ^ (c >> 1)] = get4() - SamsungKey[c];
+        if (tag == 0xa030 && len == 9)	// get and decode Samsung color matrix
+            for (i=0; i < 3; i++)
+              FORC3 cmatrix[i][c] = (short)((get4() + SamsungKey[i*3+c]))/256.0;
+        if (tag == 0xa028)
+          FORC4 cblack[c ^ (c >> 1)] = get4() - SamsungKey[c];
+      }
+    else
+      {
+        // Somebody else use 0xa021 and 0xa028?
+        if (tag == 0xa021)
+          FORC4 cam_mul[c ^ (c >> 1)] = get4();
+        if (tag == 0xa028)
+          FORC4 cam_mul[c ^ (c >> 1)] -= get4();
+      }
+    if (tag == 0x4021 && get4() && get4())
+      FORC4 cam_mul[c] = 1024;
 next:
     fseek (ifp, save, SEEK_SET);
   }
@@ -5008,23 +8501,74 @@ void CLASS get_timestamp (int reversed)
 void CLASS parse_exif (int base)
 {
   unsigned kodak, entries, tag, type, len, save, c;
-  double expo;
+  double expo,ape;
 
   kodak = !strncmp(make,"EASTMAN",7) && tiff_nifds < 3;
   entries = get2();
+  if(!strcmp(make,"Hasselblad") && (tiff_nifds > 3) && (entries > 512)) return;
+
+//  printf("\n*** in parse_exif, make: =%s= model: =%s=", make, model);
+
   while (entries--) {
     tiff_get (base, &tag, &type, &len, &save);
+
+		//    printf("\n\ttag: %x", tag);
+
+#ifdef LIBRAW_LIBRARY_BUILD
+    if(callbacks.exif_cb)
+      {
+        int savepos = ftell(ifp);
+        callbacks.exif_cb(callbacks.exifparser_data,tag,type,len,order,ifp);
+        fseek(ifp,savepos,SEEK_SET);
+      }
+#endif
     switch (tag) {
+#ifdef LIBRAW_LIBRARY_BUILD
+    case 0xa405:		// FocalLengthIn35mmFormat
+      imgdata.lens.FocalLengthIn35mmFormat = get2();
+      break;
+    case 0xa432:		// LensInfo, 42034dec, Lens Specification per EXIF standard
+      imgdata.lens.MinFocal = getreal(type);
+      imgdata.lens.MaxFocal = getreal(type);
+      imgdata.lens.MaxAp4MinFocal = getreal(type);
+      imgdata.lens.MaxAp4MaxFocal = getreal(type);
+      break;
+    case 0xc630:		// DNG LensInfo, Lens Specification per EXIF standard
+      imgdata.lens.dng.MinFocal = getreal(type);
+      imgdata.lens.dng.MaxFocal = getreal(type);
+      imgdata.lens.dng.MaxAp4MinFocal = getreal(type);
+      imgdata.lens.dng.MaxAp4MaxFocal = getreal(type);
+      break;
+    case 0xa433:		// LensMake
+      fread(imgdata.lens.LensMake, MIN(len,sizeof(imgdata.lens.LensMake)), 1, ifp);
+      break;
+    case 0xa434:		// LensModel
+      fread(imgdata.lens.Lens, MIN(len, sizeof(imgdata.lens.LensMake)), 1, ifp);
+      if (!strncmp(imgdata.lens.Lens, "----", 4))
+        imgdata.lens.Lens[0] = 0;
+      break;
+    case 0x9205:
+      imgdata.lens.EXIF_MaxAp = powf64(2.0f, (getreal(type) / 2.0f));
+      break;
+#endif
       case 33434:  shutter = getreal(type);		break;
       case 33437:  aperture = getreal(type);		break;
       case 34855:  iso_speed = get2();			break;
+      case 34866:
+        if (iso_speed == 0xffff && (!strcasecmp(make, "SONY") || !strcasecmp(make, "CANON")))
+          iso_speed = getreal(type);
+        break;
       case 36867:
       case 36868:  get_timestamp(0);			break;
-      case 37377:  if ((expo = -getreal(type)) < 128)
-		     shutter = pow (2.0, expo);		break;
-      case 37378:  aperture = pow (2.0, getreal(type)/2);	break;
+      case 37377:  if ((expo = -getreal(type)) < 128 && shutter == 0.)
+          shutter = powf64(2.0, expo);		break;
+      case 37378:
+        if (fabs(ape = getreal(type))<256.0)
+          aperture = powf64(2.0, ape/2);
+        break;
+      case 37385:  flash_used = getreal(type);          break;
       case 37386:  focal_len = getreal(type);		break;
-      case 37500:  parse_makernote (base, 0);		break;
+      case 37500:  parse_makernote (base, 0);		break;	// tag 0x927c
       case 40962:  if (kodak) raw_width  = get4();	break;
       case 40963:  if (kodak) raw_height = get4();	break;
       case 41730:
@@ -5036,6 +8580,43 @@ void CLASS parse_exif (int base)
   }
 }
 
+#ifdef LIBRAW_LIBRARY_BUILD
+
+void CLASS parse_gps_libraw(int base)
+{
+  unsigned entries, tag, type, len, save, c;
+
+  entries = get2();
+  if (entries > 0)
+    imgdata.other.parsed_gps.gpsparsed = 1;
+  while (entries--) {
+    tiff_get(base, &tag, &type, &len, &save);
+    switch (tag) {
+    case 1:  imgdata.other.parsed_gps.latref = getc(ifp); break;
+    case 3:  imgdata.other.parsed_gps.longref = getc(ifp); break;
+    case 5:  imgdata.other.parsed_gps.altref = getc(ifp); break;
+    case 2:
+      if (len == 3)
+        FORC(3) imgdata.other.parsed_gps.latitude[c] = getreal(type);
+      break;
+    case 4:
+      if (len == 3)
+        FORC(3) imgdata.other.parsed_gps.longtitude[c] = getreal(type);
+      break;
+    case 7:
+      if (len == 3)
+        FORC(3) imgdata.other.parsed_gps.gpstimestamp[c] = getreal(type);
+      break;
+    case 6:
+      imgdata.other.parsed_gps.altitude = getreal(type);
+      break;
+    case 9: imgdata.other.parsed_gps.gpsstatus = getc(ifp); break;
+    }
+    fseek(ifp, save, SEEK_SET);
+  }
+}
+#endif
+
 void CLASS parse_gps (int base)
 {
   unsigned entries, tag, type, len, save, c;
@@ -5070,7 +8651,7 @@ void CLASS romm_coeff (float romm_cam[3][3])
       for (cmatrix[i][j] = k=0; k < 3; k++)
 	cmatrix[i][j] += rgb_romm[i][k] * romm_cam[k][j];
 #ifdef LIBRAW_LIBRARY_BUILD
-  color_flags.cmatrix_state = LIBRAW_COLORSTATE_CALCULATED;
+   imgdata.color.digitalBack_color=1;
 #endif
 }
 
@@ -5082,9 +8663,8 @@ void CLASS parse_mos (int offset)
   { "","DCB2","Volare","Cantare","CMost","Valeo 6","Valeo 11","Valeo 22",
     "Valeo 11p","Valeo 17","","Aptus 17","Aptus 22","Aptus 75","Aptus 65",
     "Aptus 54S","Aptus 65S","Aptus 75S","AFi 5","AFi 6","AFi 7",
-    "AFi-II 7","","","AFi-II 6","","","AFi-II 10","AFi-II 5"
-    "","","","","","AFi-II 10R","AFi-II 8","","AFi-II 12"};
-
+    "Aptus-II 7","","","Aptus-II 6","","","Aptus-II 10","Aptus-II 5",
+    "","","","","Aptus-II 10R","Aptus-II 8","","Aptus-II 12","","AFi-II 12" };
   float romm_cam[3][3];
 
   fseek (ifp, offset, SEEK_SET);
@@ -5094,6 +8674,14 @@ void CLASS parse_mos (int offset)
     fread (data, 1, 40, ifp);
     skip = get4();
     from = ftell(ifp);
+
+// IB start
+#ifdef LIBRAW_LIBRARY_BUILD
+    if (!strcmp(data,"CameraObj_camera_type")) {
+			fread(imgdata.lens.makernotes.body, skip, 1, ifp);
+	}
+#endif
+// IB end
     if (!strcmp(data,"JPEG_preview_data")) {
       thumb_offset = from;
       thumb_length = skip;
@@ -5133,9 +8721,6 @@ void CLASS parse_mos (int offset)
     if (!strcmp(data,"NeutObj_neutrals") && !cam_mul[0]) {
       FORC4 fscanf (ifp, "%d", neut+c);
       FORC3 cam_mul[c] = (float) neut[0] / neut[c+1];
-#ifdef LIBRAW_LIBRARY_BUILD
-      color_flags.cam_mul_state = LIBRAW_COLORSTATE_LOADED;
-#endif
     }
     if (!strcmp(data,"Rows_data"))
       load_flags = get4();
@@ -5150,16 +8735,58 @@ void CLASS parse_mos (int offset)
 void CLASS linear_table (unsigned len)
 {
   int i;
-  if (len > 0x1000) len = 0x1000;
+  if (len > 0x10000) len = 0x10000;
   read_shorts (curve, len);
-#ifdef LIBRAW_LIBRARY_BUILD
-  color_flags.curve_state = LIBRAW_COLORSTATE_LOADED;
-#endif
-  for (i=len; i < 0x1000; i++)
+  for (i=len; i < 0x10000; i++)
     curve[i] = curve[i-1];
-  maximum = curve[0xfff];
+  maximum = curve[len<0x1000?0xfff:len-1];
 }
 
+#ifdef LIBRAW_LIBRARY_BUILD
+/* Thanks to Alexey Danilchenko for wb as-shot parsing code */
+void CLASS parse_kodak_ifd (int base)
+{
+  unsigned entries, tag, type, len, save;
+  int i, c, wbi=-2;
+  float mul[3]={1,1,1}, num;
+  static const int wbtag[] = { 64037,64040,64039,64041,-1,-1,64042 };
+
+  entries = get2();
+  if (entries > 1024) return;
+  while (entries--) {
+    tiff_get (base, &tag, &type, &len, &save);
+#ifdef LIBRAW_LIBRARY_BUILD
+    if(callbacks.exif_cb)
+      {
+        int savepos = ftell(ifp);
+        callbacks.exif_cb(callbacks.exifparser_data,tag | 0x20000,type,len,order,ifp);
+        fseek(ifp,savepos,SEEK_SET);
+      }
+#endif
+    if (tag == 1020) wbi = getint(type);
+    if (tag == 1021 && len == 72) {		/* WB set in software */
+      fseek (ifp, 40, SEEK_CUR);
+      FORC3 cam_mul[c] = 2048.0 / get2();
+      wbi = -2;
+    }
+    if (tag == 2120 + wbi ||
+        (wbi<0 && tag == 2125))  /* use Auto WB if illuminant index is not set */
+      {
+        FORC3 mul[c] = (num=getreal(type))==0 ? 1 : num;
+        FORC3 cam_mul[c] = mul[1] / mul[c]; /* normalise against green */
+      }
+    if (tag == 2317) linear_table (len);
+    if (tag == 0x903) iso_speed = getreal(type);
+    //if (tag == 6020) iso_speed = getint(type);
+    if (tag == 64013) wbi = fgetc(ifp);
+    if ((unsigned) wbi < 7 && tag == wbtag[wbi])
+      FORC3 cam_mul[c] = get4();
+    if (tag == 64019) width = getint(type);
+    if (tag == 64020) height = (getint(type)+1) & -2;
+    fseek (ifp, save, SEEK_SET);
+  }
+}
+#else
 void CLASS parse_kodak_ifd (int base)
 {
   unsigned entries, tag, type, len, save;
@@ -5175,25 +8802,19 @@ void CLASS parse_kodak_ifd (int base)
     if (tag == 1021 && len == 72) {		/* WB set in software */
       fseek (ifp, 40, SEEK_CUR);
       FORC3 cam_mul[c] = 2048.0 / get2();
-#ifdef LIBRAW_LIBRARY_BUILD
-      color_flags.cam_mul_state = LIBRAW_COLORSTATE_LOADED;
-#endif
       wbi = -2;
     }
     if (tag == 2118) wbtemp = getint(type);
+    if (tag == 2120 + wbi && wbi >= 0)
+      FORC3 cam_mul[c] = 2048.0 / getreal(type);
     if (tag == 2130 + wbi)
       FORC3 mul[c] = getreal(type);
     if (tag == 2140 + wbi && wbi >= 0)
-        {
       FORC3 {
 	for (num=i=0; i < 4; i++)
 	  num += getreal(type) * pow (wbtemp/100.0, i);
 	cam_mul[c] = 2048 / (num * mul[c]);
       }
-#ifdef LIBRAW_LIBRARY_BUILD
-      color_flags.cam_mul_state = LIBRAW_COLORSTATE_LOADED;
-#endif
-        }
     if (tag == 2317) linear_table (len);
     if (tag == 6020) iso_speed = getint(type);
     if (tag == 64013) wbi = fgetc(ifp);
@@ -5204,19 +8825,19 @@ void CLASS parse_kodak_ifd (int base)
     fseek (ifp, save, SEEK_SET);
   }
 }
-
+#endif
 int CLASS parse_tiff_ifd (int base)
 {
   unsigned entries, tag, type, len, plen=16, save;
   int ifd, use_cm=0, cfa, i, j, c, ima_len=0;
-  int blrr=1, blrc=1, dblack[] = { 0,0,0,0 };
-  char software[64], *cbuf, *cp;
+  char *cbuf, *cp;
   uchar cfa_pat[16], cfa_pc[] = { 0,1,2,3 }, tab[256];
   double cc[4][4], cm[4][3], cam_xyz[4][3], num;
   double ab[]={ 1,1,1,1 }, asn[] = { 0,0,0,0 }, xyz[] = { 1,1,1 };
   unsigned sony_curve[] = { 0,0,0,0,0,4095 };
   unsigned *buf, sony_offset=0, sony_length=0, sony_key=0;
   struct jhead jh;
+  int pana_raw = 0;
 #ifndef LIBRAW_LIBRARY_BUILD
   FILE *sfp;
 #endif
@@ -5231,33 +8852,62 @@ int CLASS parse_tiff_ifd (int base)
   if (entries > 512) return 1;
   while (entries--) {
     tiff_get (base, &tag, &type, &len, &save);
+
+//    printf ("\n*** parse_tiff_ifd tag: 0x%04x", tag);
+
+#ifdef LIBRAW_LIBRARY_BUILD
+    if(callbacks.exif_cb)
+      {
+        int savepos = ftell(ifp);
+        callbacks.exif_cb(callbacks.exifparser_data,tag|(pana_raw?0x30000:0),type,len,order,ifp);
+        fseek(ifp,savepos,SEEK_SET);
+      }
+#endif
     switch (tag) {
+      case 1:   if(len==4) pana_raw = get4(); break;
       case 5:   width  = get2();  break;
       case 6:   height = get2();  break;
       case 7:   width += get2();  break;
-      case 9:  filters = get2();  break;
+      case 9:   if ((i = get2())) filters = i;
+#ifdef LIBRAW_LIBRARY_BUILD
+        if(pana_raw && len == 1 && type ==3)
+          pana_black[3]+=i;
+#endif
+        break;
+      case 8:
+      case 10:
+#ifdef LIBRAW_LIBRARY_BUILD
+        if(pana_raw && len == 1 && type ==3)
+          pana_black[3]+=get2();
+#endif
+        break;
       case 17: case 18:
 	if (type == 3 && len == 1)
-            {
 	  cam_mul[(tag-17)*2] = get2() / 256.0;
-#ifdef LIBRAW_LIBRARY_BUILD
-          color_flags.cam_mul_state = LIBRAW_COLORSTATE_LOADED;
-#endif
-            }
 	break;
       case 23:
 	if (type == 3) iso_speed = get2();
 	break;
+      case 28: case 29: case 30:
+#ifdef LIBRAW_LIBRARY_BUILD
+        if(pana_raw && len == 1 && type ==3)
+          {
+            pana_black[tag-28] = get2();
+          }
+        else
+#endif
+          {
+            cblack[tag-28] = get2();
+            cblack[3] = cblack[1];
+          }
+	break;
       case 36: case 37: case 38:
-	cam_mul[tag-0x24] = get2();
+	cam_mul[tag-36] = get2();
 	break;
       case 39:
 	if (len < 50 || cam_mul[0]) break;
 	fseek (ifp, 12, SEEK_CUR);
 	FORC3 cam_mul[c] = get2();
-#ifdef LIBRAW_LIBRARY_BUILD
-        color_flags.cam_mul_state = LIBRAW_COLORSTATE_LOADED;
-#endif
 	break;
       case 46:
 	if (type != 7 || fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) break;
@@ -5265,6 +8915,7 @@ int CLASS parse_tiff_ifd (int base)
 	thumb_length = len;
 	break;
       case 61440:			/* Fuji HS10 table */
+	fseek (ifp, get4()+base, SEEK_SET);
 	parse_tiff_ifd (base);
 	break;
       case 2: case 256: case 61441:	/* ImageWidth */
@@ -5280,8 +8931,9 @@ int CLASS parse_tiff_ifd (int base)
 	break;
       case 61446:
 	raw_height = 0;
+	if (tiff_ifd[ifd].bps > 12) break;
 	load_raw = &CLASS packed_load_raw;
-	load_flags = get4() && (filters=0x16161616) ? 24:80;
+	load_flags = get4() ? 24:80;
 	break;
       case 259:				/* Compression */
 	tiff_ifd[ifd].comp = getint(type);
@@ -5342,7 +8994,6 @@ int CLASS parse_tiff_ifd (int base)
 	    !strncmp(software,"dcraw",5) ||
 	    !strncmp(software,"UFRaw",5) ||
 	    !strncmp(software,"Bibble",6) ||
-	    !strncmp(software,"Nikon Scan",10) ||
 	    !strcmp (software,"Digital Photo Professional"))
 	  is_raw = 0;
 	break;
@@ -5353,13 +9004,15 @@ int CLASS parse_tiff_ifd (int base)
 	fread (artist, 64, 1, ifp);
 	break;
       case 322:				/* TileWidth */
-        tile_width = getint(type);
+	tiff_ifd[ifd].t_tile_width = getint(type);
 	break;
       case 323:				/* TileLength */
-        tile_length = getint(type);
+	tiff_ifd[ifd].t_tile_length = getint(type);
 	break;
       case 324:				/* TileOffsets */
 	tiff_ifd[ifd].offset = len > 1 ? ftell(ifp) : get4();
+	if (len == 1)
+	  tiff_ifd[ifd].t_tile_width = tiff_ifd[ifd].t_tile_length = 0;
 	if (len == 4) {
 	  load_raw = &CLASS sinar_4shot_load_raw;
 	  is_raw = 5;
@@ -5381,6 +9034,15 @@ int CLASS parse_tiff_ifd (int base)
 	  data_offset = get4()+base;
 	  ifd++;  break;
 	}
+#ifdef LIBRAW_LIBRARY_BUILD
+	if (!strcmp(make,"Hasselblad") && libraw_internal_data.unpacker_data.hasselblad_parser_flag) {
+          fseek (ifp, ftell(ifp)+4, SEEK_SET);
+          fseek (ifp, get4()+base, SEEK_SET);
+          parse_tiff_ifd (base);
+          break;
+	}
+#endif
+        if(len > 1000) len=1000; /* 1000 SubIFDs is enough */
 	while (len--) {
 	  i = ftell(ifp);
 	  fseek (ifp, get4()+base, SEEK_SET);
@@ -5392,14 +9054,21 @@ int CLASS parse_tiff_ifd (int base)
 	strcpy (make, "Sarnoff");
 	maximum = 0xfff;
 	break;
+#ifdef LIBRAW_LIBRARY_BUILD
+      case 700:
+        if((type == 1 || type == 2 || type == 6 || type == 7) && len > 1 && len < 5100000)
+          {
+            xmpdata = (char*)malloc(xmplen = len+1);
+            fread(xmpdata,len,1,ifp);
+            xmpdata[len]=0;
+          }
+        break;
+#endif
       case 28688:
 	FORC4 sony_curve[c+1] = get2() >> 2 & 0xfff;
 	for (i=0; i < 5; i++)
 	  for (j = sony_curve[i]+1; j <= sony_curve[i+1]; j++)
 	    curve[j] = curve[j-1] + (1 << i);
-#ifdef LIBRAW_LIBRARY_BUILD
-        color_flags.curve_state = LIBRAW_COLORSTATE_LOADED;
-#endif
 	break;
       case 29184: sony_offset = get4();  break;
       case 29185: sony_length = get4();  break;
@@ -5410,32 +9079,61 @@ int CLASS parse_tiff_ifd (int base)
 	break;
       case 29443:
 	FORC4 cam_mul[c ^ (c < 2)] = get2();
-#ifdef LIBRAW_LIBRARY_BUILD
-        color_flags.cam_mul_state = LIBRAW_COLORSTATE_LOADED;
-#endif
 	break;
       case 29459:
-       FORC4 cam_mul[c] = get2();
-       i = (cam_mul[1] == 1024 && cam_mul[2] == 1024) << 1;
-       SWAP (cam_mul[i],cam_mul[i+1])
-#ifdef LIBRAW_LIBRARY_BUILD
-        color_flags.cam_mul_state = LIBRAW_COLORSTATE_LOADED;
+	FORC4 cam_mul[c] = get2();
+	i = (cam_mul[1] == 1024 && cam_mul[2] == 1024) << 1;
+	SWAP (cam_mul[i],cam_mul[i+1])
+	break;
+    case 30720: // Sony matrix, Sony_SR2SubIFD_0x7800
+      for (i=0; i < 3; i++)
+        FORC3 cmatrix[i][c] = ((short) get2()) / 1024.0;
+#ifdef DCRAW_VERBOSE
+	if (verbose) fprintf (stderr, _(" Sony matrix:\n%f %f %f\n%f %f %f\n%f %f %f\n"), cmatrix[0][0],  cmatrix[0][1], cmatrix[0][2], cmatrix[1][0], cmatrix[1][1], cmatrix[1][2], cmatrix[2][0], cmatrix[2][1], cmatrix[2][2]);
 #endif
 	break;
+    case 29456: // Sony black level, Sony_SR2SubIFD_0x7310, no more needs to be divided by 4
+      FORC4 cblack[c ^ c >> 1] = get2();
+      i = cblack[3];
+      FORC3 if(i>cblack[c]) i = cblack[c];
+      FORC4 cblack[c]-=i;
+      black = i;
+#ifdef DCRAW_VERBOSE
+      if (verbose) fprintf (stderr, _("...Sony black: %u cblack: %u %u %u %u\n"),black, cblack[0],cblack[1],cblack[2], cblack[3]);
+#endif
+      break;
       case 33405:			/* Model2 */
 	fgets (model2, 64, ifp);
 	break;
+      case 33421:			/* CFARepeatPatternDim */
+	if (get2() == 6 && get2() == 6)
+	  filters = 9;
+	break;
       case 33422:			/* CFAPattern */
-      case 64777:			/* Kodak P-series */
-	if ((plen=len) > 16) plen = 16;
-	fread (cfa_pat, 1, plen, ifp);
-	for (colors=cfa=i=0; i < plen; i++) {
-	  colors += !(cfa & (1 << cfa_pat[i]));
-	  cfa |= 1 << cfa_pat[i];
+	if (filters == 9) {
+	  FORC(36) xtrans[0][c] = fgetc(ifp) & 3;
+	  break;
 	}
-	if (cfa == 070) memcpy (cfa_pc,"\003\004\005",3);	/* CMY */
-	if (cfa == 072) memcpy (cfa_pc,"\005\003\004\001",4);	/* GMCY */
-	goto guess_cfa_pc;
+      case 64777:			/* Kodak P-series */
+        if(len == 36)
+          {
+            filters = 9;
+            colors = 3;
+            FORC(36) xtrans[0][c] = fgetc(ifp) & 3;
+          }
+        else
+          {
+            if ((plen=len) > 16) plen = 16;
+            fread (cfa_pat, 1, plen, ifp);
+            for (colors=cfa=i=0; i < plen && colors < 4; i++) {
+              colors += !(cfa & (1 << cfa_pat[i]));
+              cfa |= 1 << cfa_pat[i];
+            }
+            if (cfa == 070) memcpy (cfa_pc,"\003\004\005",3);	/* CMY */
+            if (cfa == 072) memcpy (cfa_pc,"\005\003\004\001",4);	/* GMCY */
+            goto guess_cfa_pc;
+          }
+        break;
       case 33424:
       case 65024:
 	fseek (ifp, get4()+base, SEEK_SET);
@@ -5447,11 +9145,38 @@ int CLASS parse_tiff_ifd (int base)
       case 33437:			/* FNumber */
 	aperture = getreal(type);
 	break;
-      case 34306:			/* Leaf white balance */
-	FORC4 cam_mul[c ^ 1] = 4096.0 / get2();
 #ifdef LIBRAW_LIBRARY_BUILD
-        color_flags.cam_mul_state = LIBRAW_COLORSTATE_LOADED;
+// IB start
+    case 0xa405:		// FocalLengthIn35mmFormat
+      imgdata.lens.FocalLengthIn35mmFormat = get2();
+      break;
+    case 0xa432:		// LensInfo, 42034dec, Lens Specification per EXIF standard
+      imgdata.lens.MinFocal = getreal(type);
+      imgdata.lens.MaxFocal = getreal(type);
+      imgdata.lens.MaxAp4MinFocal = getreal(type);
+      imgdata.lens.MaxAp4MaxFocal = getreal(type);
+      break;
+    case 0xc630:		// DNG LensInfo, Lens Specification per EXIF standard
+      imgdata.lens.MinFocal = getreal(type);
+      imgdata.lens.MaxFocal = getreal(type);
+      imgdata.lens.MaxAp4MinFocal = getreal(type);
+      imgdata.lens.MaxAp4MaxFocal = getreal(type);
+      break;
+    case 0xa433:		// LensMake
+      fread(imgdata.lens.LensMake, MIN(len, sizeof(imgdata.lens.LensMake)), 1, ifp);
+      break;
+    case 0xa434:		// LensModel
+      fread(imgdata.lens.Lens, MIN(len, sizeof(imgdata.lens.Lens)), 1, ifp);
+      if (!strncmp(imgdata.lens.Lens, "----", 4))
+        imgdata.lens.Lens[0] = 0;
+      break;
+    case 0x9205:
+				imgdata.lens.EXIF_MaxAp = powf64(2.0f, (getreal(type) / 2.0f));
+      break;
+// IB end
 #endif
+      case 34306:			/* Leaf white balance */
+	FORC4 cam_mul[c ^ 1] = 4096.0 / get2();
 	break;
       case 34307:			/* Leaf CatchLight color matrix */
 	fread (software, 1, 7, ifp);
@@ -5463,9 +9188,6 @@ int CLASS parse_tiff_ifd (int base)
 	  num = 0;
 	  FORC4 num += rgb_cam[i][c];
 	  FORC4 rgb_cam[i][c] /= num;
-#ifdef LIBRAW_LIBRARY_BUILD
-          color_flags.rgb_cam_state = LIBRAW_COLORSTATE_LOADED;
-#endif
 	}
 	break;
       case 34310:			/* Leaf metadata */
@@ -5478,8 +9200,15 @@ int CLASS parse_tiff_ifd (int base)
 	parse_exif (base);
 	break;
       case 34853:			/* GPSInfo tag */
-	fseek (ifp, get4()+base, SEEK_SET);
-	parse_gps (base);
+        {
+          unsigned pos;
+          fseek(ifp, pos = (get4() + base), SEEK_SET);
+          parse_gps(base);
+#ifdef LIBRAW_LIBRARY_BUILD
+          fseek(ifp, pos, SEEK_SET);
+          parse_gps_libraw(base);
+#endif
+        }
 	break;
       case 34675:			/* InterColorProfile */
       case 50831:			/* AsShotICCProfile */
@@ -5500,9 +9229,14 @@ int CLASS parse_tiff_ifd (int base)
 	  getreal(type);
 	  FORC3 rgb_cam[i][c] = getreal(type);
 	}
-#ifdef LIBRAW_LIBRARY_BUILD
-        color_flags.rgb_cam_state = LIBRAW_COLORSTATE_LOADED;
-#endif
+	break;
+      case 40976:
+	strip_offset = get4();
+	switch (tiff_ifd[ifd].comp) {
+	  case 32770: load_raw = &CLASS samsung_load_raw;   break;
+	  case 32772: load_raw = &CLASS samsung2_load_raw;  break;
+	  case 32773: load_raw = &CLASS samsung3_load_raw;  break;
+	}
 	break;
       case 46275:			/* Imacon tags */
 	strcpy (make, "Imacon");
@@ -5511,37 +9245,34 @@ int CLASS parse_tiff_ifd (int base)
 	break;
       case 46279:
 	if (!ima_len) break;
-        fseek (ifp, 38, SEEK_CUR);
+	fseek (ifp, 38, SEEK_CUR);
       case 46274:
-        fseek (ifp, 40, SEEK_CUR);
+	fseek (ifp, 40, SEEK_CUR);
 	raw_width  = get4();
 	raw_height = get4();
 	left_margin = get4() & 7;
 	width = raw_width - left_margin - (get4() & 7);
 	top_margin = get4() & 7;
 	height = raw_height - top_margin - (get4() & 7);
-	if (raw_width == 7262) {
+	if (raw_width == 7262 && ima_len == 234317952 ) {
+	  height = 5412;
+	  width  = 7216;
+	  left_margin = 7;
+          filters=0;
+	} else 	if (raw_width == 7262) {
 	  height = 5444;
 	  width  = 7244;
 	  left_margin = 7;
 	}
 	fseek (ifp, 52, SEEK_CUR);
 	FORC3 cam_mul[c] = getreal(11);
-#ifdef LIBRAW_LIBRARY_BUILD
-        color_flags.cam_mul_state = LIBRAW_COLORSTATE_LOADED;
-#endif
 	fseek (ifp, 114, SEEK_CUR);
 	flip = (get2() >> 7) * 90;
 	if (width * height * 6 == ima_len) {
-#if 1
-         if (flip % 180 == 90) SWAP(width,height);
-         filters = flip = 0;
-#else
-          if (flip % 180 == 90) SWAP(width,height);
-          raw_width = width;
-          raw_height = height;
-          left_margin = top_margin = filters = flip = 0;
-#endif
+	  if (flip % 180 == 90) SWAP(width,height);
+	  raw_width = width;
+	  raw_height = height;
+	  left_margin = top_margin = filters = flip = 0;
 	}
 	sprintf (model, "Ixpress %d-Mp", height*width/1000000);
 	load_raw = &CLASS imacon_full_load_raw;
@@ -5557,18 +9288,16 @@ int CLASS parse_tiff_ifd (int base)
 	fread (cbuf, 1, len, ifp);
 	for (cp = cbuf-1; cp && cp < cbuf+len; cp = strchr(cp,'\n'))
 	  if (!strncmp (++cp,"Neutral ",8))
-              {
 	    sscanf (cp+8, "%f %f %f", cam_mul, cam_mul+1, cam_mul+2);
-#ifdef LIBRAW_LIBRARY_BUILD
-            color_flags.cam_mul_state = LIBRAW_COLORSTATE_LOADED;
-#endif
-              }
 	free (cbuf);
 	break;
       case 50458:
 	if (!make[0]) strcpy (make, "Hasselblad");
 	break;
       case 50459:			/* Hasselblad tag */
+#ifdef LIBRAW_LIBRARY_BUILD
+        libraw_internal_data.unpacker_data.hasselblad_parser_flag=1;
+#endif
 	i = order;
 	j = ftell(ifp);
 	c = tiff_nifds;
@@ -5585,14 +9314,16 @@ int CLASS parse_tiff_ifd (int base)
 	is_raw = 1;
 	break;
       case 50710:			/* CFAPlaneColor */
+	if (filters == 9) break;
 	if (len > 4) len = 4;
 	colors = len;
 	fread (cfa_pc, 1, colors, ifp);
 guess_cfa_pc:
-	FORCC tab[cfa_pc[c]] = c;
-	cdesc[c] = 0;
-	for (i=16; i--; )
-	  filters = filters << 2 | tab[cfa_pat[i % plen]];
+        FORCC tab[cfa_pc[c]] = c;
+        cdesc[c] = 0;
+        for (i=16; i--; )
+          filters = filters << 2 | tab[cfa_pat[i % plen]];
+        filters -= !filters;
 	break;
       case 50711:			/* CFALayout */
 	if (get2() == 2) {
@@ -5605,27 +9336,28 @@ guess_cfa_pc:
 	linear_table (len);
 	break;
       case 50713:			/* BlackLevelRepeatDim */
-	blrr = get2();
-	blrc = get2();
+	cblack[4] = get2();
+	cblack[5] = get2();
+	if (cblack[4] * cblack[5] > (sizeof(cblack) / sizeof (cblack[0]) - 6))
+	    cblack[4] = cblack[5] = 1;
 	break;
       case 61450:
-	blrr = blrc = 2;
+	cblack[4] = cblack[5] = MIN(sqrt((double)len),64);
       case 50714:			/* BlackLevel */
-	black = getreal(type);
-	if (!filters || !~filters) break;
-	dblack[0] = black;
-	dblack[1] = (blrc == 2) ? getreal(type):dblack[0];
-	dblack[2] = (blrr == 2) ? getreal(type):dblack[0];
-	dblack[3] = (blrc == 2 && blrr == 2) ? getreal(type):dblack[1];
-	if (colors == 3)
-	  filters |= ((filters >> 2 & 0x22222222) |
-		      (filters << 2 & 0x88888888)) & filters << 1;
-	FORC4 cblack[filters >> (c << 1) & 3] = dblack[c];
-	black = 0;
+        if((cblack[4] * cblack[5] < 2) && len == 1)
+          {
+            black = getreal(type);
+          }
+        else if(cblack[4] * cblack[5] <= len)
+          {
+            FORC (cblack[4] * cblack[5])
+              cblack[6+c] = getreal(type);
+            black = 0;
+          }
 	break;
       case 50715:			/* BlackLevelDeltaH */
       case 50716:			/* BlackLevelDeltaV */
-	for (num=i=0; i < len; i++)
+	for (num=i=0; i < len && i < 65536; i++)
 	  num += getreal(type);
 	black += num/len + 0.5;
 	break;
@@ -5635,17 +9367,44 @@ guess_cfa_pc:
       case 50718:			/* DefaultScale */
 	pixel_aspect  = getreal(type);
 	pixel_aspect /= getreal(type);
+	if(pixel_aspect > 0.995 && pixel_aspect < 1.005)
+          pixel_aspect = 1.0;
 	break;
+#ifdef LIBRAW_LIBRARY_BUILD
+      case 50778:
+        imgdata.color.dng_color[0].illuminant = get2();
+        break;
+      case 50779:
+        imgdata.color.dng_color[1].illuminant = get2();
+        break;
+#endif
       case 50721:			/* ColorMatrix1 */
       case 50722:			/* ColorMatrix2 */
+#ifdef LIBRAW_LIBRARY_BUILD
+        i = tag == 50721?0:1;
+#endif
 	FORCC for (j=0; j < 3; j++)
+          {
+#ifdef LIBRAW_LIBRARY_BUILD
+          imgdata.color.dng_color[i].colormatrix[c][j]=
+#endif
 	  cm[c][j] = getreal(type);
+          }
 	use_cm = 1;
 	break;
       case 50723:			/* CameraCalibration1 */
       case 50724:			/* CameraCalibration2 */
+#ifdef LIBRAW_LIBRARY_BUILD
+        j = tag == 50723?0:1;
+#endif
 	for (i=0; i < colors; i++)
-	  FORCC cc[i][c] = getreal(type);
+	  FORCC
+            {
+#ifdef LIBRAW_LIBRARY_BUILD
+              imgdata.color.dng_color[j].calibration[i][c]=
+#endif
+              cc[i][c] = getreal(type);
+            }
 	break;
       case 50727:			/* AnalogBalance */
 	FORCC ab[c] = getreal(type);
@@ -5659,7 +9418,55 @@ guess_cfa_pc:
 	xyz[2] = 1 - xyz[0] - xyz[1];
 	FORC3 xyz[c] /= d65_white[c];
 	break;
-      case 50740:			/* DNGPrivateData */
+#ifdef LIBRAW_LIBRARY_BUILD
+      case 50730:			/* DNG: Baseline Exposure */
+        baseline_exposure = getreal(type);
+        break;
+#endif
+		  // IB start
+			case 50740:			/* tag 0xc634 : DNG Adobe, DNG Pentax, Sony SR2, DNG Private */
+      {
+        char mbuf[64];
+        unsigned short makernote_found = 0;
+        unsigned curr_pos, start_pos = ftell(ifp);
+        unsigned MakN_order, m_sorder = order;
+        unsigned MakN_length;
+        unsigned pos_in_original_raw;
+        fread(mbuf, 1, 6, ifp);
+
+        if (!strcmp(mbuf, "Adobe")) {
+          order = 0x4d4d;				// Adobe header is always in "MM" / big endian
+          curr_pos = start_pos + 6;
+          while (curr_pos + 8 - start_pos <= len)
+            {
+              fread(mbuf, 1, 4, ifp);
+              curr_pos += 8;
+              if (!strncmp(mbuf, "MakN", 4)) {
+                makernote_found = 1;
+                MakN_length = get4();
+                MakN_order = get2();
+                pos_in_original_raw = get4();
+                order = MakN_order;
+                parse_makernote_0xc634(curr_pos + 6 - pos_in_original_raw, 0, AdobeDNG);
+                break;
+              }
+            }
+        }
+        else {
+          fread(mbuf + 6, 1, 2, ifp);
+          if (!strcmp(mbuf, "PENTAX ") ||
+              !strcmp(mbuf, "SAMSUNG"))
+            {
+              makernote_found = 1;
+              fseek(ifp, start_pos, SEEK_SET);
+              parse_makernote_0xc634(base, 0, CameraDNG);
+            }
+        }
+
+        if (!makernote_found) fseek(ifp, start_pos, SEEK_SET);
+        order = m_sorder;
+      }
+      // IB end
 	if (dng_version) break;
 	parse_minolta (j = get4()+base);
 	fseek (ifp, j, SEEK_SET);
@@ -5674,11 +9481,14 @@ guess_cfa_pc:
 	height = getint(type) - top_margin;
 	width = getint(type) - left_margin;
 	break;
-#if 0
-      case 51009:                       /* OpcodeList2 */
-        meta_offset = ftell(ifp);
-        break;
-#endif
+      case 50830:			/* MaskedAreas */
+        for (i=0; i < len && i < 32; i++)
+	  mask[0][i] = getint(type);
+	black = 0;
+	break;
+      case 51009:			/* OpcodeList2 */
+	meta_offset = ftell(ifp);
+	break;
       case 64772:			/* Kodak P-series */
 	if (len < 13) break;
 	fseek (ifp, 16, SEEK_CUR);
@@ -5720,23 +9530,14 @@ guess_cfa_pc:
     FORCC for (i=0; i < 3; i++)
       for (cam_xyz[c][i]=j=0; j < colors; j++)
 	cam_xyz[c][i] += cc[c][j] * cm[j][i] * xyz[i];
-    cam_xyz_coeff (cam_xyz);
+    cam_xyz_coeff (cmatrix, cam_xyz);
   }
   if (asn[0]) {
     cam_mul[3] = 0;
     FORCC cam_mul[c] = 1 / asn[c];
-#ifdef LIBRAW_LIBRARY_BUILD
-    color_flags.cam_mul_state = LIBRAW_COLORSTATE_LOADED;
-#endif
   }
   if (!use_cm)
-      {
     FORCC pre_mul[c] /= cc[c][c];
-#ifdef LIBRAW_LIBRARY_BUILD
-    color_flags.pre_mul_state = LIBRAW_COLORSTATE_LOADED;
-#endif
-      }
-
   return 0;
 }
 
@@ -5757,26 +9558,28 @@ int CLASS parse_tiff (int base)
 
 void CLASS apply_tiff()
 {
-  int max_samp=0, raw=-1, thm=-1, i,max_bps=0;
+  int max_samp=0, raw=-1, thm=-1, i;
   struct jhead jh;
 
   thumb_misc = 16;
   if (thumb_offset) {
     fseek (ifp, thumb_offset, SEEK_SET);
     if (ljpeg_start (&jh, 1)) {
-      thumb_misc   = jh.bits;
-      thumb_width  = jh.wide;
-      thumb_height = jh.high;
+      if((unsigned)jh.bits<17 && (unsigned)jh.wide < 0x10000 && (unsigned)jh.high < 0x10000)
+        {
+          thumb_misc   = jh.bits;
+          thumb_width  = jh.wide;
+          thumb_height = jh.high;
+        }
     }
   }
   for (i=0; i < tiff_nifds; i++) {
     if (max_samp < tiff_ifd[i].samples)
 	max_samp = tiff_ifd[i].samples;
     if (max_samp > 3) max_samp = 3;
-    if (max_bps < tiff_ifd[i].bps)
-        max_bps = tiff_ifd[i].bps;
     if ((tiff_ifd[i].comp != 6 || tiff_ifd[i].samples != 3) &&
-	(tiff_ifd[i].t_width | tiff_ifd[i].t_height) < 0x10000 &&
+        unsigned(tiff_ifd[i].t_width | tiff_ifd[i].t_height) < 0x10000 &&
+        (unsigned)tiff_ifd[i].bps < 33 && (unsigned)tiff_ifd[i].samples < 13 &&
 	tiff_ifd[i].t_width*tiff_ifd[i].t_height > raw_width*raw_height) {
       raw_width     = tiff_ifd[i].t_width;
       raw_height    = tiff_ifd[i].t_height;
@@ -5785,107 +9588,93 @@ void CLASS apply_tiff()
       data_offset   = tiff_ifd[i].offset;
       tiff_flip     = tiff_ifd[i].t_flip;
       tiff_samples  = tiff_ifd[i].samples;
+      tile_width    = tiff_ifd[i].t_tile_width;
+      tile_length   = tiff_ifd[i].t_tile_length;
 #ifdef LIBRAW_LIBRARY_BUILD
-      data_size     = tile_length < INT_MAX ? tiff_ifd[i].tile_maxbytes: tiff_ifd[i].bytes;
+      data_size     = tile_length < INT_MAX && tile_length>0 ? tiff_ifd[i].tile_maxbytes: tiff_ifd[i].bytes;
 #endif
       raw = i;
     }
   }
-#if 0
   if (!tile_width ) tile_width  = INT_MAX;
   if (!tile_length) tile_length = INT_MAX;
-#endif
   for (i=tiff_nifds; i--; )
     if (tiff_ifd[i].t_flip) tiff_flip = tiff_ifd[i].t_flip;
   if (raw >= 0 && !load_raw)
     switch (tiff_compress) {
-#if 1
       case 32767:
-        if (tiff_ifd[raw].bytes == raw_width*raw_height) {
-          tiff_bps = 12;
-          load_raw = &CLASS sony_arw2_load_raw;                 break;
-        }
-        if (tiff_ifd[raw].bytes*8 != raw_width*raw_height*tiff_bps) {
-          raw_height += 8;
-          load_raw = &CLASS sony_arw_load_raw;                  break;
-        }
-        load_flags = 79;
+	if (tiff_ifd[raw].bytes == raw_width*raw_height) {
+	  tiff_bps = 12;
+	  load_raw = &CLASS sony_arw2_load_raw;			break;
+	}
+	if (tiff_ifd[raw].bytes*8 != raw_width*raw_height*tiff_bps) {
+	  raw_height += 8;
+	  load_raw = &CLASS sony_arw_load_raw;			break;
+	}
+	load_flags = 79;
       case 32769:
-        load_flags++;
+	load_flags++;
       case 32770:
       case 32773: goto slr;
       case 0:  case 1:
-        if (tiff_ifd[raw].bytes*5 == raw_width*raw_height*8) {
-          load_flags = 81;
-          tiff_bps = 12;
-        } slr:
-        switch (tiff_bps) {
-          case  8: load_raw = &CLASS eight_bit_load_raw;        break;
-          case 12: if (tiff_ifd[raw].phint == 2)
-                     load_flags = 6;
-                   load_raw = &CLASS packed_load_raw;           break;
-          case 14: load_flags = 0;
-          case 16: load_raw = &CLASS unpacked_load_raw;         break;
-        }
-        break;
-      case 6:  case 7:  case 99:
-	load_raw = &CLASS lossless_jpeg_load_raw;		break;
-      case 262:
-        load_raw = &CLASS kodak_262_load_raw;                   break;
-      case 34713:
-        load_raw = &CLASS nikon_compressed_load_raw;            break;
-/*
-      case 34892:
-        load_raw = &CLASS lossy_dng_load_raw;           break;
-*/
-      case 65535:
-        load_raw = &CLASS pentax_load_raw;                      break;
-      case 65000:
-        switch (tiff_ifd[raw].phint) {
-          case 2: load_raw = &CLASS kodak_rgb_load_raw;   filters = 0;  break;
-          case 6: load_raw = &CLASS kodak_ycbcr_load_raw; filters = 0;  break;
-          case 32803: load_raw = &CLASS kodak_65000_load_raw;
-        }
-      case 32867: break;
-      default: is_raw = 0;
-#else
-      case 0:  case 1:
+#ifdef LIBRAW_LIBRARY_BUILD
+        if(!strcasecmp(make,"Nikon") && !strncmp(software,"Nikon Scan",10))
+          {
+            load_raw = &CLASS nikon_coolscan_load_raw;
+            raw_color = 1;
+            filters = 0;
+            break;
+          }
+#endif
+	if (!strncmp(make,"OLYMPUS",7) &&
+		tiff_ifd[raw].bytes*2 == raw_width*raw_height*3)
+	  load_flags = 24;
+	if (tiff_ifd[raw].bytes*5 == raw_width*raw_height*8) {
+	  load_flags = 81;
+	  tiff_bps = 12;
+	} slr:
 	switch (tiff_bps) {
 	  case  8: load_raw = &CLASS eight_bit_load_raw;	break;
-	  case 12: load_raw = &CLASS packed_load_raw;
-		   if (tiff_ifd[raw].phint == 2)
+	  case 12: if (tiff_ifd[raw].phint == 2)
 		     load_flags = 6;
-		   if (strncmp(make,"PENTAX",6)) break;
-	  case 14:
-	  case 16: load_raw = &CLASS unpacked_load_raw;		break;
-	}
-	if (tiff_ifd[raw].bytes*5 == raw_width*raw_height*8) {
-	  tiff_bps = 12;
-	  load_raw = &CLASS packed_load_raw;
-	  load_flags = 81;
+		   load_raw = &CLASS packed_load_raw;		break;
+	  case 14: load_flags = 0;
+	  case 16: load_raw = &CLASS unpacked_load_raw;
+		   if (!strncmp(make,"OLYMPUS",7) &&
+			tiff_ifd[raw].bytes*7 > raw_width*raw_height)
+		     load_raw = &CLASS olympus_load_raw;
 	}
 	break;
       case 6:  case 7:  case 99:
 	load_raw = &CLASS lossless_jpeg_load_raw;		break;
       case 262:
 	load_raw = &CLASS kodak_262_load_raw;			break;
-      case 32767:
-	if (tiff_ifd[raw].bytes == raw_width*raw_height) {
-	  tiff_bps = 12;
-	  load_raw = &CLASS sony_arw2_load_raw;			break;
-	}
-	if (tiff_ifd[raw].bytes*8 != raw_width*raw_height*tiff_bps) {
-	  raw_height += 8;
-	  load_raw = &CLASS sony_arw_load_raw;			break;
-	}
-	load_flags = 79;
-      case 32769:
-	load_flags++;
-      case 32770:
-      case 32773:
-	load_raw = &CLASS packed_load_raw;			break;
       case 34713:
-	load_raw = &CLASS nikon_compressed_load_raw;		break;
+	if ((raw_width+9)/10*16*raw_height == tiff_ifd[raw].bytes) {
+	  load_raw = &CLASS packed_load_raw;
+	  load_flags = 1;
+	} else if (raw_width*raw_height*3 == tiff_ifd[raw].bytes*2) {
+	  load_raw = &CLASS packed_load_raw;
+	  if (model[0] == 'N') load_flags = 80;
+	} else if (raw_width*raw_height*3 == tiff_ifd[raw].bytes) {
+	  load_raw = &CLASS nikon_yuv_load_raw;
+	  gamma_curve (1/2.4, 12.92, 1, 4095);
+	  memset (cblack, 0, sizeof cblack);
+	  filters = 0;
+	} else if (raw_width*raw_height*2 == tiff_ifd[raw].bytes) {
+	  load_raw = &CLASS unpacked_load_raw;
+	  load_flags = 4;
+	  order = 0x4d4d;
+	} else
+#ifdef LIBRAW_LIBRARY_BUILD
+          if(raw_width*raw_height*3 == tiff_ifd[raw].bytes*2)
+            {
+              load_raw = &CLASS packed_load_raw;
+              load_flags=80;
+            }
+          else
+#endif
+            load_raw = &CLASS nikon_load_raw;			break;
       case 65535:
 	load_raw = &CLASS pentax_load_raw;			break;
       case 65000:
@@ -5894,23 +9683,23 @@ void CLASS apply_tiff()
 	  case 6: load_raw = &CLASS kodak_ycbcr_load_raw; filters = 0;  break;
 	  case 32803: load_raw = &CLASS kodak_65000_load_raw;
 	}
-      case 32867: break;
+      case 32867: case 34892: break;
       default: is_raw = 0;
-#endif
     }
   if (!dng_version)
-    if ( (tiff_samples == 3 && tiff_ifd[raw].bytes &&
-	  tiff_bps != 14 && tiff_bps != 2048 && tiff_compress != 32770)
-      || (tiff_bps == 8 && !strstr(make,"KODAK") && !strstr(make,"Kodak") &&
+    if ( ((tiff_samples == 3 && tiff_ifd[raw].bytes && tiff_bps != 14 &&
+	  (tiff_compress & -16) != 32768)
+      || (tiff_bps == 8 && !strcasestr(make,"Kodak") &&
 	  !strstr(model2,"DEBUG RAW")))
-      is_raw = 0;
-  if(dng_version && max_bps > 16)
+         && strncmp(software,"Nikon Scan",10))
       is_raw = 0;
   for (i=0; i < tiff_nifds; i++)
-    if (i != raw && tiff_ifd[i].samples == max_samp && tiff_ifd[i].offset && tiff_ifd[i].bytes &&
-	tiff_ifd[i].t_width * tiff_ifd[i].t_height / SQR(tiff_ifd[i].bps+1) >
-	      thumb_width *       thumb_height / SQR(thumb_misc+1)
-         && tiff_ifd[i].comp != 34892) {
+    if (i != raw && tiff_ifd[i].samples == max_samp &&
+        tiff_ifd[i].bps>0 && tiff_ifd[i].bps < 33 &&
+        unsigned(tiff_ifd[i].t_width | tiff_ifd[i].t_height) < 0x10000 &&
+	tiff_ifd[i].t_width * tiff_ifd[i].t_height / (SQR(tiff_ifd[i].bps)+1) >
+	      thumb_width *       thumb_height / (SQR(thumb_misc)+1)
+	&& tiff_ifd[i].comp != 34892) {
       thumb_width  = tiff_ifd[i].t_width;
       thumb_height = tiff_ifd[i].t_height;
       thumb_offset = tiff_ifd[i].offset;
@@ -5925,16 +9714,16 @@ void CLASS apply_tiff()
 	write_thumb = &CLASS layer_thumb;
 	break;
       case 1:
-        if (tiff_ifd[thm].bps <= 8)
-          write_thumb = &CLASS ppm_thumb;
-        else if (!strcmp(make,"Imacon"))
-            write_thumb = NULL; /* &CLASS ppm16_thumb; */
-        else
-          thumb_load_raw = &CLASS kodak_thumb_load_raw;
+	if (tiff_ifd[thm].bps <= 8)
+	  write_thumb = &CLASS ppm_thumb;
+	else if (!strcmp(make,"Imacon"))
+	  write_thumb = &CLASS ppm16_thumb;
+	else
+	  thumb_load_raw = &CLASS kodak_thumb_load_raw;
 	break;
       case 65000:
 	thumb_load_raw = tiff_ifd[thm].phint == 6 ?
-		&CLASS kodak_ycbcr_load_thumb : &CLASS kodak_rgb_load_thumb;
+		&CLASS kodak_ycbcr_load_raw : &CLASS kodak_rgb_load_raw;
     }
   }
 }
@@ -5962,9 +9751,6 @@ void CLASS parse_minolta (int base)
 	get4();
 	i = strcmp(model,"DiMAGE A200") ? 0:3;
 	FORC4 cam_mul[c ^ (c >> 1) ^ i] = get2();
-#ifdef LIBRAW_LIBRARY_BUILD
-        color_flags.cam_mul_state = LIBRAW_COLORSTATE_LOADED;
-#endif
 	break;
       case 0x545457:				/* TTW */
 	parse_tiff (ftell(ifp));
@@ -5989,6 +9775,23 @@ void CLASS parse_external_jpeg()
 #ifndef LIBRAW_LIBRARY_BUILD
   FILE *save=ifp;
 #else
+#if defined(_WIN32) && !defined(__MINGW32__) && defined(_MSC_VER) && (_MSC_VER > 1310)
+  if(ifp->wfname())
+  {
+	  std::wstring rawfile(ifp->wfname());
+	  rawfile.replace(rawfile.length()-3,3,L"JPG");
+	  if(!ifp->subfile_open(rawfile.c_str()))
+	  {
+		  parse_tiff (12);
+		  thumb_offset = 0;
+		  is_raw = 1;
+		  ifp->subfile_close();
+	  }
+	  else
+		  imgdata.process_warnings |= LIBRAW_WARN_NO_METADATA ;
+	 return;
+  }
+#endif
   if(!ifp->fname())
       {
           imgdata.process_warnings |= LIBRAW_WARN_NO_METADATA ;
@@ -6039,7 +9842,7 @@ void CLASS parse_external_jpeg()
     }
   }
 #else
-  if (strcmp (jname, ifname)) 
+  if (strcmp (jname, ifname))
       {
           if(!ifp->subfile_open(jname))
               {
@@ -6095,7 +9898,8 @@ void CLASS ciff_block_1030()
 /*
    Parse a CIFF file, better known as Canon CRW format.
  */
-void CLASS parse_ciff (int offset, int length)
+
+void CLASS parse_ciff (int offset, int length, int depth)
 {
   int tboff, nrecs, c, type, len, save, wbi=-1;
   ushort key[] = { 0x410, 0x45f3 };
@@ -6104,24 +9908,29 @@ void CLASS parse_ciff (int offset, int length)
   tboff = get4() + offset;
   fseek (ifp, tboff, SEEK_SET);
   nrecs = get2();
-  if (nrecs > 100) return;
+  if ((nrecs | depth) > 127) return;
   while (nrecs--) {
     type = get2();
     len  = get4();
+
+//    printf ("\n*** type: 0x%04x len: 0x%04x", type, len);
+
     save = ftell(ifp) + 4;
     fseek (ifp, offset+get4(), SEEK_SET);
-    if ((((type >> 8) + 8) | 8) == 0x38)
-      parse_ciff (ftell(ifp), len);	/* Parse a sub-table */
-
+    if ((((type >> 8) + 8) | 8) == 0x38) {
+      parse_ciff (ftell(ifp), len, depth+1); /* Parse a sub-table */
+    }
     if (type == 0x0810)
       fread (artist, 64, 1, ifp);
     if (type == 0x080a) {
       fread (make, 64, 1, ifp);
-      fseek (ifp, ((INT64)strlen(make)) - 63, SEEK_CUR);
+      fseek (ifp, strlen(make) - 63, SEEK_CUR);
       fread (model, 64, 1, ifp);
     }
     if (type == 0x1810) {
-      fseek (ifp, 12, SEEK_CUR);
+      width = get4();
+      height = get4();
+      pixel_aspect = int_to_float(get4());
       flip = get4();
     }
     if (type == 0x1835)			/* Get the decoder table */
@@ -6131,13 +9940,22 @@ void CLASS parse_ciff (int offset, int length)
       thumb_length = len;
     }
     if (type == 0x1818) {
-      shutter = pow (2.0f, -int_to_float((get4(),get4())));
-      aperture = pow (2.0f, int_to_float(get4())/2);
+      shutter = powf64(2.0f, -int_to_float((get4(),get4())));
+      aperture = powf64(2.0f, int_to_float(get4())/2);
+#ifdef LIBRAW_LIBRARY_BUILD
+			imgdata.lens.makernotes.CurAp = aperture;
+#endif
     }
     if (type == 0x102a) {
-      iso_speed = pow (2.0, (get4(),get2())/32.0 - 4) * 50;
-      aperture  = pow (2.0, (get2(),(short)get2())/64.0);
-      shutter   = pow (2.0,-((short)get2())/32.0);
+			//      iso_speed = pow (2.0, (get4(),get2())/32.0 - 4) * 50;
+      iso_speed = powf64(2.0f, ((get2(),get2()) + get2())/32.0f - 5.0f) * 100.0f;
+#ifdef LIBRAW_LIBRARY_BUILD
+      aperture  = _CanonConvertAperture((get2(),get2()));
+      imgdata.lens.makernotes.CurAp = aperture;
+#else
+      aperture  = powf64(2.0, (get2(),(short)get2())/64.0);
+#endif
+      shutter   = powf64(2.0,-((short)get2())/32.0);
       wbi = (get2(),get2());
       if (wbi > 17) wbi = 0;
       fseek (ifp, 32, SEEK_CUR);
@@ -6147,24 +9965,31 @@ void CLASS parse_ciff (int offset, int length)
       if (get2() > 512) {		/* Pro90, G1 */
 	fseek (ifp, 118, SEEK_CUR);
 	FORC4 cam_mul[c ^ 2] = get2();
-#ifdef LIBRAW_LIBRARY_BUILD
-        color_flags.cam_mul_state = LIBRAW_COLORSTATE_LOADED;
-#endif
       } else {				/* G2, S30, S40 */
 	fseek (ifp, 98, SEEK_CUR);
 	FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get2();
-#ifdef LIBRAW_LIBRARY_BUILD
-        color_flags.cam_mul_state = LIBRAW_COLORSTATE_LOADED;
-#endif
       }
     }
+#ifdef LIBRAW_LIBRARY_BUILD
+    if (type == 0x102d) {
+        fseek(ifp, 44, SEEK_CUR);
+        imgdata.lens.makernotes.LensID = get2();
+        imgdata.lens.makernotes.MaxFocal = get2();
+        imgdata.lens.makernotes.MinFocal = get2();
+        imgdata.lens.makernotes.CanonFocalUnits = get2();
+        if (imgdata.lens.makernotes.CanonFocalUnits != 1)
+          {
+            imgdata.lens.makernotes.MaxFocal /= (float)imgdata.lens.makernotes.CanonFocalUnits;
+            imgdata.lens.makernotes.MinFocal /= (float)imgdata.lens.makernotes.CanonFocalUnits;
+          }
+        imgdata.lens.makernotes.MaxAp = _CanonConvertAperture(get2());
+        imgdata.lens.makernotes.MinAp = _CanonConvertAperture(get2());
+    }
+#endif
     if (type == 0x0032) {
       if (len == 768) {			/* EOS D30 */
 	fseek (ifp, 72, SEEK_CUR);
 	FORC4 cam_mul[c ^ (c >> 1)] = 1024.0 / get2();
-#ifdef LIBRAW_LIBRARY_BUILD
-        color_flags.cam_mul_state = LIBRAW_COLORSTATE_LOADED;
-#endif
 	if (!wbi) cam_mul[0] = -1;	/* use my auto white balance */
       } else if (!cam_mul[0]) {
 	if (get2() == key[0])		/* Pro1, G6, S60, S70 */
@@ -6176,9 +10001,6 @@ void CLASS parse_ciff (int offset, int length)
 	}
 	fseek (ifp, 78 + c*8, SEEK_CUR);
 	FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get2() ^ key[c & 1];
-#ifdef LIBRAW_LIBRARY_BUILD
-        color_flags.cam_mul_state = LIBRAW_COLORSTATE_LOADED;
-#endif
 	if (!wbi) cam_mul[0] = -1;
       }
     }
@@ -6186,9 +10008,6 @@ void CLASS parse_ciff (int offset, int length)
       if (len > 66) wbi = "0134567028"[wbi]-'0';
       fseek (ifp, 2 + wbi*8, SEEK_CUR);
       FORC4 cam_mul[c ^ (c >> 1)] = get2();
-#ifdef LIBRAW_LIBRARY_BUILD
-      color_flags.cam_mul_state = LIBRAW_COLORSTATE_LOADED;
-#endif
     }
     if (type == 0x1030 && (0x18040 >> wbi & 1))
       ciff_block_1030();		/* all that don't have 0x10a9 */
@@ -6196,14 +10015,33 @@ void CLASS parse_ciff (int offset, int length)
       raw_width = (get2(),get2());
       raw_height = get2();
     }
+    if (type == 0x501c) {
+      iso_speed = len & 0xffff;
+    }
     if (type == 0x5029) {
+#ifdef LIBRAW_LIBRARY_BUILD
+      imgdata.lens.makernotes.CurFocal  = len >> 16;
+      imgdata.lens.makernotes.FocalType = len & 0xffff;
+      if (imgdata.lens.makernotes.FocalType == 2) {
+        imgdata.lens.makernotes.CanonFocalUnits = 32;
+        imgdata.lens.makernotes.CurFocal /= (float)imgdata.lens.makernotes.CanonFocalUnits;
+      }
+      focal_len = imgdata.lens.makernotes.CurFocal;
+#else
       focal_len = len >> 16;
       if ((len & 0xffff) == 2) focal_len /= 32;
+#endif
     }
     if (type == 0x5813) flash_used = int_to_float(len);
     if (type == 0x5814) canon_ev   = int_to_float(len);
     if (type == 0x5817) shot_order = len;
-    if (type == 0x5834) unique_id  = len;
+    if (type == 0x5834)
+		{
+			unique_id  = len;
+#ifdef LIBRAW_LIBRARY_BUILD
+			setCanonBodyFeatures(unique_id);
+#endif
+		}
     if (type == 0x580e) timestamp  = len;
     if (type == 0x180e) timestamp  = get4();
 #ifdef LOCALTIME
@@ -6290,6 +10128,11 @@ void CLASS parse_phase_one (int base)
   float romm_cam[3][3];
   char *cp;
 
+#ifdef LIBRAW_LIBRARY_BUILD
+	char body_id[3];
+	body_id[0] = 0;
+#endif
+
   memset (&ph1, 0, sizeof ph1);
   fseek (ifp, base, SEEK_SET);
   order = get4() & 0xffff;
@@ -6305,6 +10148,64 @@ void CLASS parse_phase_one (int base)
     save = ftell(ifp);
     fseek (ifp, base+data, SEEK_SET);
     switch (tag) {
+
+#ifdef LIBRAW_LIBRARY_BUILD
+    case 0x0102:
+      fread(body_id, 1, 3, ifp);
+      if ((body_id[0] == 0x4c) && (body_id[1] == 0x49)) {
+        body_id[1] = body_id[2];
+      }
+      unique_id = (((body_id[0] & 0x3f) << 5) | (body_id[1] & 0x3f)) - 0x41;
+      setPhaseOneFeatures(unique_id);
+      break;
+    case 0x0401:
+      if (type == 4) imgdata.lens.makernotes.CurAp =  powf64(2.0f, (int_to_float(data)/2.0f));
+      else imgdata.lens.makernotes.CurAp = powf64(2.0f, (getreal(type)/2.0f));
+      break;
+    case 0x0403:
+      if (type == 4) imgdata.lens.makernotes.CurFocal =  int_to_float(data);
+      else imgdata.lens.makernotes.CurFocal = getreal(type);
+      break;
+    case 0x0410:
+      fread(imgdata.lens.makernotes.body, 1, len, ifp);
+      break;
+    case 0x0412:
+      fread(imgdata.lens.makernotes.Lens, 1, len, ifp);
+      break;
+    case 0x0414:
+      if (type == 4) {
+      	imgdata.lens.makernotes.MaxAp4CurFocal = powf64(2.0f, (int_to_float(data)/2.0f));
+      } else {
+        imgdata.lens.makernotes.MaxAp4CurFocal = powf64(2.0f, (getreal(type) / 2.0f));
+      }
+      break;
+    case 0x0415:
+      if (type == 4) {
+      	imgdata.lens.makernotes.MinAp4CurFocal = powf64(2.0f, (int_to_float(data)/2.0f));
+      } else {
+        imgdata.lens.makernotes.MinAp4CurFocal = powf64(2.0f, (getreal(type) / 2.0f));
+      }
+      break;
+    case 0x0416:
+      if (type == 4) {
+        imgdata.lens.makernotes.MinFocal =  int_to_float(data);
+      } else {
+        imgdata.lens.makernotes.MinFocal = getreal(type);
+      }
+      if (imgdata.lens.makernotes.MinFocal > 1000.0f)
+        {
+          imgdata.lens.makernotes.MinFocal = 0.0f;
+        }
+      break;
+    case 0x0417:
+      if (type == 4) {
+        imgdata.lens.makernotes.MaxFocal =  int_to_float(data);
+      } else {
+        imgdata.lens.makernotes.MaxFocal = getreal(type);
+      }
+      break;
+#endif
+
       case 0x100:  flip = "0653"[data & 3]-'0';  break;
       case 0x106:
 	for (i=0; i < 9; i++)
@@ -6313,9 +10214,6 @@ void CLASS parse_phase_one (int base)
 	break;
       case 0x107:
 	FORC3 cam_mul[c] = getreal(11);
-#ifdef LIBRAW_LIBRARY_BUILD
-        color_flags.cam_mul_state = LIBRAW_COLORSTATE_LOADED;
-#endif
 	break;
       case 0x108:  raw_width     = data;	break;
       case 0x109:  raw_height    = data;	break;
@@ -6332,8 +10230,10 @@ void CLASS parse_phase_one (int base)
       case 0x21a:  ph1.tag_21a   = data;		break;
       case 0x21c:  strip_offset  = data+base;		break;
       case 0x21d:  ph1.t_black     = data;		break;
-      case 0x222:  ph1.split_col = data - left_margin;	break;
-      case 0x223:  ph1.black_off = data+base;		break;
+      case 0x222:  ph1.split_col = data;		break;
+      case 0x223:  ph1.black_col = data+base;		break;
+      case 0x224:  ph1.split_row = data;		break;
+      case 0x225:  ph1.black_row = data+base;		break;
       case 0x301:
 	model[63] = 0;
 	fread (model, 1, 63, ifp);
@@ -6341,6 +10241,33 @@ void CLASS parse_phase_one (int base)
     }
     fseek (ifp, save, SEEK_SET);
   }
+
+#ifdef LIBRAW_LIBRARY_BUILD
+  if (!imgdata.lens.makernotes.body[0] && !body_id[0]) {
+    fseek (ifp, meta_offset, SEEK_SET);
+    order = get2();
+    fseek (ifp, 6, SEEK_CUR);
+    fseek (ifp, meta_offset+get4(), SEEK_SET);
+    entries = get4();  get4();
+    while (entries--) {
+      tag  = get4();
+      len  = get4();
+      data = get4();
+      save = ftell(ifp);
+      fseek (ifp, meta_offset+data, SEEK_SET);
+      if (tag == 0x0407) {
+        fread(body_id, 1, 3, ifp);
+        if ((body_id[0] == 0x4c) && (body_id[1] == 0x49)) {
+          body_id[1] = body_id[2];
+        }
+        unique_id = (((body_id[0] & 0x3f) << 5) | (body_id[1] & 0x3f)) - 0x41;
+        setPhaseOneFeatures(unique_id);
+      }
+      fseek (ifp, save, SEEK_SET);
+    }
+  }
+#endif
+
   load_raw = ph1.format < 3 ?
 	&CLASS phase_one_load_raw : &CLASS phase_one_load_raw_c;
   maximum = 0xffff;
@@ -6373,17 +10300,17 @@ void CLASS parse_fuji (int offset)
       if ((width = get2()) == 4284) width += 3;
     } else if (tag == 0x130) {
       fuji_layout = fgetc(ifp) >> 7;
-      load_raw = fgetc(ifp) & 8 ?
-	&CLASS unpacked_load_raw : &CLASS fuji_load_raw;
+      fuji_width = !(fgetc(ifp) & 8);
+    } else if (tag == 0x131) {
+      filters = 9;
+      FORC(36) xtrans_abs[0][35-c] = fgetc(ifp) & 3;
     } else if (tag == 0x2ff0) {
       FORC4 cam_mul[c ^ 1] = get2();
-#ifdef LIBRAW_LIBRARY_BUILD
-      color_flags.cam_mul_state = LIBRAW_COLORSTATE_LOADED;
-#endif
     } else if (tag == 0xc000) {
       c = order;
       order = 0x4949;
-      width  = get4();
+      if ((tag = get4()) > 10000) tag = get4();
+      width = tag;
       height = get4();
       order = c;
     }
@@ -6412,7 +10339,13 @@ int CLASS parse_jpeg (int offset)
     order = get2();
     hlen  = get4();
     if (get4() == 0x48454150)		/* "HEAP" */
-      parse_ciff (save+hlen, len-hlen);
+		{
+#ifdef LIBRAW_LIBRARY_BUILD
+			imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_FixedLens;
+			imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_FixedLens;
+#endif
+      parse_ciff (save+hlen, len-hlen, 0);
+		}
     if (parse_tiff (save+6)) apply_tiff();
     fseek (ifp, save+len, SEEK_SET);
   }
@@ -6432,13 +10365,10 @@ void CLASS parse_riff()
   size = get4();
   end = ftell(ifp) + size;
   if (!memcmp(tag,"RIFF",4) || !memcmp(tag,"LIST",4)) {
-      int cnt=0;
+    int maxloop = 1000;
     get4();
-    while (ftell(ifp)+7 < end)
-        {
-            parse_riff();
-            if(cnt++>10000) break; // no more than 10k times
-        }
+    while (ftell(ifp)+7 < end && !feof(ifp) && maxloop--)
+      parse_riff();
   } else if (!memcmp(tag,"nctg",4)) {
     while (ftell(ifp)+7 < end) {
       i = get2();
@@ -6463,6 +10393,26 @@ void CLASS parse_riff()
     fseek (ifp, size, SEEK_CUR);
 }
 
+void CLASS parse_qt (int end)
+{
+  unsigned save, size;
+  char tag[4];
+
+  order = 0x4d4d;
+  while (ftell(ifp)+7 < end) {
+    save = ftell(ifp);
+    if ((size = get4()) < 8) return;
+    fread (tag, 4, 1, ifp);
+    if (!memcmp(tag,"moov",4) ||
+	!memcmp(tag,"udta",4) ||
+	!memcmp(tag,"CNTH",4))
+      parse_qt (save+size);
+    if (!memcmp(tag,"CNDA",4))
+      parse_jpeg (ftell(ifp));
+    fseek (ifp, save+size, SEEK_SET);
+  }
+}
+
 void CLASS parse_smal (int offset, int fsize)
 {
   int ver;
@@ -6521,10 +10471,7 @@ void CLASS parse_cine()
   }
   cam_mul[0] = getreal(11);
   cam_mul[2] = getreal(11);
-#ifdef LIBRAW_LIBRARY_BUILD
-  color_flags.cam_mul_state = LIBRAW_COLORSTATE_LOADED;
-#endif
-  maximum = ~(-1 << get4());
+  maximum = ~((~0u) << get4());
   fseek (ifp, 668, SEEK_CUR);
   shutter = get4()/1000000000.0;
   fseek (ifp, off_image, SEEK_SET);
@@ -6564,13 +10511,21 @@ void CLASS parse_redcine()
     data_offset = get4();
   }
 }
-void CLASS adobe_coeff (const char *p_make, const char *p_model)
+
+/*
+   All matrices are from Adobe DNG Converter unless otherwise noted.
+ */
+void CLASS adobe_coeff (const char *t_make, const char *t_model
+#ifdef LIBRAW_LIBRARY_BUILD
+	,int internal_only
+#endif
+)
 {
   static const struct {
     const char *prefix;
-    short t_black, t_maximum, trans[12];
+    int t_black, t_maximum, trans[12];
   } table[] = {
-    { "AGFAPHOTO DC-833m", 0, 0,	/* DJC */
+    { "AgfaPhoto DC-833m", 0, 0,	/* DJC */
 	{ 11438,-3762,-1115,-2409,9914,2497,-1227,2295,5300 } },
     { "Apple QuickTake", 0, 0,		/* DJC */
 	{ 21392,-5653,-3353,2406,8010,-415,7166,1427,2078 } },
@@ -6583,11 +10538,15 @@ void CLASS adobe_coeff (const char *p_make, const char *p_model)
     { "Canon EOS D60", 0, 0xfa0,
 	{ 6188,-1341,-890,-7168,14489,2937,-2640,3228,8483 } },
     { "Canon EOS 5D Mark III", 0, 0x3c80,
-        { 6722,-635,-963,-4287,12460,2028,-908,2162,5668 } },
+	{ 6722,-635,-963,-4287,12460,2028,-908,2162,5668 } },
     { "Canon EOS 5D Mark II", 0, 0x3cf0,
 	{ 4716,603,-830,-7798,15474,2480,-1496,1937,6651 } },
     { "Canon EOS 5D", 0, 0xe6c,
 	{ 6347,-479,-972,-8297,15954,2480,-1968,2131,7649 } },
+    { "Canon EOS 6D", 0, 0x3c82,
+	{ 8621,-2197,-787,-3150,11358,912,-1161,2400,4836 } },
+    { "Canon EOS 7D Mark II", 0, 0x3510,
+	{ 7268,-1082,-969,-4186,11839,2663,-825,2029,5839 } },
     { "Canon EOS 7D", 0, 0x3510,
 	{ 6844,-996,-856,-3876,11761,2396,-593,1772,6198 } },
     { "Canon EOS 10D", 0, 0xfa0,
@@ -6604,6 +10563,10 @@ void CLASS adobe_coeff (const char *p_make, const char *p_model)
 	{ 4920,616,-593,-6493,13964,2784,-1774,3178,7005 } },
     { "Canon EOS 60D", 0, 0x2ff7,
 	{ 6719,-994,-925,-4408,12426,2211,-887,2129,6051 } },
+    { "Canon EOS 70D", 0, 0x3bc7,
+	{ 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 } },
+    { "Canon EOS 100D", 0, 0x350f,
+	{ 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
     { "Canon EOS 300D", 0, 0xfa0,
 	{ 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } },
     { "Canon EOS 350D", 0, 0xfff,
@@ -6618,10 +10581,18 @@ void CLASS adobe_coeff (const char *p_make, const char *p_model)
 	{ 6941,-1164,-857,-3825,11597,2534,-416,1540,6039 } },
     { "Canon EOS 600D", 0, 0x3510,
 	{ 6461,-907,-882,-4300,12184,2378,-819,1944,5931 } },
+    { "Canon EOS 650D", 0, 0x354d,
+	{ 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
+    { "Canon EOS 700D", 0, 0x3c00,
+	{ 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
     { "Canon EOS 1000D", 0, 0xe43,
 	{ 6771,-1139,-977,-7818,15123,2928,-1244,1437,7533 } },
     { "Canon EOS 1100D", 0, 0x3510,
 	{ 6444,-904,-893,-4563,12308,2535,-903,2016,6728 } },
+    { "Canon EOS 1200D", 0, 0x37c2,
+	{ 6461,-907,-882,-4300,12184,2378,-819,1944,5931 } },
+    { "Canon EOS M", 0, 0,
+	{ 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
     { "Canon EOS-1Ds Mark III", 0, 0x3bb0,
 	{ 5859,-211,-930,-8255,16017,2353,-1732,1887,7448 } },
     { "Canon EOS-1Ds Mark II", 0, 0xe80,
@@ -6636,12 +10607,14 @@ void CLASS adobe_coeff (const char *p_make, const char *p_model)
 	{ 6264,-582,-724,-8312,15948,2504,-1744,1919,8664 } },
     { "Canon EOS-1DS", 0, 0xe20,
 	{ 4374,3631,-1743,-7520,15212,2472,-2892,3632,8161 } },
-    { "Canon EOS-1D X", 0, 0,
-        { 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } },
-     { "Canon EOS-1D", 0, 0xe20,
+    { "Canon EOS-1D C", 0, 0x3c4e,
+	{ 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } },
+    { "Canon EOS-1D X", 0, 0x3c4e,
+	{ 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } },
+    { "Canon EOS-1D", 0, 0xe20,
 	{ 6806,-179,-1020,-8097,16415,1687,-3267,4236,7690 } },
-    { "Canon EOS", 0, 0,
-	{ 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } },
+    { "Canon EOS C500", 853, 0,		/* DJC */
+	{ 17851,-10604,922,-7425,16662,763,-3660,3636,22278 } },
     { "Canon PowerShot A530", 0, 0,
 	{ 0 } },	/* don't want the A5 matrix */
     { "Canon PowerShot A50", 0, 0,
@@ -6654,8 +10627,14 @@ void CLASS adobe_coeff (const char *p_make, const char *p_model)
 	{ 12177,-4817,-1069,-1612,9864,2049,-98,850,4471 } },
     { "Canon PowerShot G12", 0, 0,
 	{ 13244,-5501,-1248,-1508,9858,1935,-270,1083,4366 } },
+    { "Canon PowerShot G15", 0, 0,
+	{ 7474,-2301,-567,-4056,11456,2975,-222,716,4181 } },
+    { "Canon PowerShot G16", 0, 0,
+        { 14130,-8071,127,2199,6528,1551,3402,-1721,4960 } },
+    { "Canon PowerShot G1 X Mark II", 0, 0,
+	{ 7378,-1255,-1043,-4088,12251,2048,-876,1946,5805 } },
     { "Canon PowerShot G1 X", 0, 0,
-        { 7378,-1255,-1043,-4088,12251,2048,-876,1946,5805 } },
+	{ 7378,-1255,-1043,-4088,12251,2048,-876,1946,5805 } },
     { "Canon PowerShot G1", 0, 0,
 	{ -4778,9467,2172,4743,-1141,4344,-5146,9908,6077,-1566,11051,557 } },
     { "Canon PowerShot G2", 0, 0,
@@ -6666,6 +10645,8 @@ void CLASS adobe_coeff (const char *p_make, const char *p_model)
 	{ 9757,-2872,-933,-5972,13861,2301,-1622,2328,7212 } },
     { "Canon PowerShot G6", 0, 0,
 	{ 9877,-3775,-871,-7613,14807,3072,-1448,1305,7485 } },
+    { "Canon PowerShot G7 X", 0, 0,
+	{ 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } },
     { "Canon PowerShot G9", 0, 0,
 	{ 7368,-2141,-598,-5621,13254,2625,-1418,1696,5743 } },
     { "Canon PowerShot Pro1", 0, 0,
@@ -6690,8 +10671,20 @@ void CLASS adobe_coeff (const char *p_make, const char *p_model)
 	{ 12374,-5016,-1049,-1677,9902,2078,-83,852,4683 } },
     { "Canon PowerShot S95", 0, 0,
 	{ 13440,-5896,-1279,-1236,9598,1931,-180,1001,4651 } },
+    { "Canon PowerShot S120", 0, 0, /* LibRaw */
+      { 10800,-4782,-628,-2057,10783,1176,-802,2091,4739 } },
+    { "Canon PowerShot S110", 0, 0,
+	{ 8039,-2643,-654,-3783,11230,2930,-206,690,4194 } },
     { "Canon PowerShot S100", 0, 0,
 	{ 7968,-2565,-636,-2873,10697,2513,180,667,4211 } },
+    { "Canon PowerShot SX1 IS", 0, 0,
+	{ 6578,-259,-502,-5974,13030,3309,-308,1058,4970 } },
+    { "Canon PowerShot SX50 HS", 0, 0,
+	{ 12432,-4753,-1247,-2110,10691,1629,-412,1623,4926 } },
+    { "Canon PowerShot SX60 HS", 0, 0,
+	{ 13161,-5451,-1344,-1989,10654,1531,-47,1271,4955 } },
+    { "Canon PowerShot A3300", 0, 0,	/* DJC */
+	{ 10826,-3654,-1023,-3215,11310,1906,0,999,4960 } },
     { "Canon PowerShot A470", 0, 0,	/* DJC */
 	{ 12513,-4407,-1242,-2680,10276,2405,-878,2215,4734 } },
     { "Canon PowerShot A610", 0, 0,	/* DJC */
@@ -6706,19 +10699,17 @@ void CLASS adobe_coeff (const char *p_make, const char *p_model)
 	{ 9427,-3036,-959,-2581,10671,1911,-1039,1982,4430 } },
     { "Canon PowerShot A720", 0, 0,	/* DJC */
 	{ 14573,-5482,-1546,-1266,9799,1468,-1040,1912,3810 } },
-    { "Canon PowerShot S2 IS", 0, 0,    /* jlb */
-      { 14062,-5199,-1446,-4712,12470,2243,-1286,2028,4836 } },   /* jlb - copied from Powershot S3 IS */
     { "Canon PowerShot S3 IS", 0, 0,	/* DJC */
 	{ 14062,-5199,-1446,-4712,12470,2243,-1286,2028,4836 } },
-    { "Canon PowerShot SX1 IS", 0, 0,
-	{ 6578,-259,-502,-5974,13030,3309,-308,1058,4970 } },
     { "Canon PowerShot SX110 IS", 0, 0,	/* DJC */
 	{ 14134,-5576,-1527,-1991,10719,1273,-1158,1929,3581 } },
-    { "CASIO EX-S20", 0, 0,		/* DJC */
+    { "Canon PowerShot SX220", 0, 0,	/* DJC */
+	{ 13898,-5076,-1447,-1405,10109,1297,-244,1860,3687 } },
+    { "Casio EX-S20", 0, 0,		/* DJC */
 	{ 11634,-3924,-1128,-4968,12954,2015,-1588,2648,7206 } },
-    { "CASIO EX-Z750", 0, 0,		/* DJC */
+    { "Casio EX-Z750", 0, 0,		/* DJC */
 	{ 10819,-3873,-1099,-4903,13730,1175,-1755,3751,4632 } },
-    { "CASIO EX-Z10", 128, 0xfff,	/* DJC */
+    { "Casio EX-Z10", 128, 0xfff,	/* DJC */
 	{ 9790,-3338,-603,-2321,10222,2099,-344,1273,4799 } },
     { "CINE 650", 0, 0,
 	{ 3390,480,-500,-800,3610,340,-550,2336,1192 } },
@@ -6728,99 +10719,155 @@ void CLASS adobe_coeff (const char *p_make, const char *p_model)
 	{ 20183,-4295,-423,-3940,15330,3985,-280,4870,9800 } },
     { "Contax N Digital", 0, 0xf1e,
 	{ 7777,1285,-1053,-9280,16543,2916,-3677,5679,7060 } },
-    { "EPSON R-D1", 0, 0,
+    { "Epson R-D1", 0, 0,
 	{ 6827,-1878,-732,-8429,16012,2564,-704,592,7145 } },
-    { "FUJIFILM E550", 0, 0,
-        { 11044,-3888,-1120,-7248,15168,2208,-1531,2277,8069 } },
-    { "FUJIFILM E900", 0, 0,
-        { 9183,-2526,-1078,-7461,15071,2574,-2022,2440,8639 } },
-    { "FUJIFILM F5", 0, 0,
-        { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
-    { "FUJIFILM F6", 0, 0,
-        { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
-    { "FUJIFILM F77", 0, 0,
-        { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
-    { "FUJIFILM F7", 0, 0,
-        { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } },
-    { "FUJIFILM F8", 0, 0,
-        { 11044,-3888,-1120,-7248,15168,2208,-1531,2277,8069 } },
-    { "FUJIFILM S100FS", 514, 0,
-        { 11521,-4355,-1065,-6524,13767,3058,-1466,1984,6045 } },
-    { "FUJIFILM S200EXR", 512, 0x3fff,
-        { 11401,-4498,-1312,-5088,12751,2613,-838,1568,5941 } },
-    { "FUJIFILM S20Pro", 0, 0,
-        { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } },
-    { "FUJIFILM S2Pro", 128, 0,
-        { 12492,-4690,-1402,-7033,15423,1647,-1507,2111,7697 } },
-    { "FUJIFILM S3Pro", 0, 0,
-        { 11807,-4612,-1294,-8927,16968,1988,-2120,2741,8006 } },
-    { "FUJIFILM S5Pro", 0, 0,
-        { 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } },
-    { "FUJIFILM S5000", 0, 0,
-        { 8754,-2732,-1019,-7204,15069,2276,-1702,2334,6982 } },
-    { "FUJIFILM S5100", 0, 0,
-        { 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } },
-    { "FUJIFILM S5500", 0, 0,
-        { 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } },
-    { "FUJIFILM S5200", 0, 0,
-        { 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } },
-    { "FUJIFILM S5600", 0, 0,
-        { 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } },
-    { "FUJIFILM S6", 0, 0,
-        { 12628,-4887,-1401,-6861,14996,1962,-2198,2782,7091 } },
-    { "FUJIFILM S7000", 0, 0,
-        { 10190,-3506,-1312,-7153,15051,2238,-2003,2399,7505 } },
-    { "FUJIFILM S9000", 0, 0,
-        { 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } },
-    { "FUJIFILM S9500", 0, 0,
-        { 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } },
-    { "FUJIFILM S9100", 0, 0,
-        { 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } },
-    { "FUJIFILM S9600", 0, 0,
-        { 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } },
-    { "FUJIFILM IS-1", 0, 0,
-        { 21461,-10807,-1441,-2332,10599,1999,289,875,7703 } },
-    { "FUJIFILM IS Pro", 0, 0,
-        { 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } },
-    { "FUJIFILM HS10 HS11", 0, 0xf68,
-        { 12440,-3954,-1183,-1123,9674,1708,-83,1614,4086 } },
-    { "FUJIFILM HS20EXR", 0, 0,
-        { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
-    { "FUJIFILM HS3", 0, 0,
-        { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
-    { "FUJIFILM X100", 0, 0,
-        { 12161,-4457,-1069,-5034,12874,2400,-795,1724,6904 } },
-    { "FUJIFILM X10", 0, 0,
-        { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } },
-    { "FUJIFILM X-Pro1", 0, 0,
+    { "Fujifilm E550", 0, 0,
+	{ 11044,-3888,-1120,-7248,15168,2208,-1531,2277,8069 } },
+    { "Fujifilm E900", 0, 0,
+	{ 9183,-2526,-1078,-7461,15071,2574,-2022,2440,8639 } },
+    { "Fujifilm F5", 0, 0,
+	{ 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
+    { "Fujifilm F6", 0, 0,
+	{ 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
+    { "Fujifilm F77", 0, 0xfe9,
+	{ 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
+    { "Fujifilm F7", 0, 0,
+	{ 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } },
+    { "Fujifilm F8", 0, 0,
+	{ 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
+    { "Fujifilm S100FS", 514, 0,
+	{ 11521,-4355,-1065,-6524,13767,3058,-1466,1984,6045 } },
+    { "Fujifilm S1", 0, 0,
+	{ 12297,-4882,-1202,-2106,10691,1623,-88,1312,4790 } },
+    { "Fujifilm S20Pro", 0, 0,
+	{ 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } },
+    { "Fujifilm S20", 512, 0x3fff,
+	{ 11401,-4498,-1312,-5088,12751,2613,-838,1568,5941 } },
+    { "Fujifilm S2Pro", 128, 0,
+	{ 12492,-4690,-1402,-7033,15423,1647,-1507,2111,7697 } },
+    { "Fujifilm S3Pro", 0, 0,
+	{ 11807,-4612,-1294,-8927,16968,1988,-2120,2741,8006 } },
+    { "Fujifilm S5Pro", 0, 0,
+	{ 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } },
+    { "Fujifilm S5000", 0, 0,
+	{ 8754,-2732,-1019,-7204,15069,2276,-1702,2334,6982 } },
+    { "Fujifilm S5100", 0, 0,
+	{ 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } },
+    { "Fujifilm S5500", 0, 0,
+	{ 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } },
+    { "Fujifilm S5200", 0, 0,
+	{ 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } },
+    { "Fujifilm S5600", 0, 0,
+	{ 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } },
+    { "Fujifilm S6", 0, 0,
+	{ 12628,-4887,-1401,-6861,14996,1962,-2198,2782,7091 } },
+    { "Fujifilm S7000", 0, 0,
+	{ 10190,-3506,-1312,-7153,15051,2238,-2003,2399,7505 } },
+    { "Fujifilm S9000", 0, 0,
+	{ 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } },
+    { "Fujifilm S9500", 0, 0,
+	{ 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } },
+    { "Fujifilm S9100", 0, 0,
+	{ 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } },
+    { "Fujifilm S9600", 0, 0,
+	{ 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } },
+    { "Fujifilm SL1000", 0, 0,
+	{ 11705,-4262,-1107,-2282,10791,1709,-555,1713,4945 } },
+    { "Fujifilm IS-1", 0, 0,
+	{ 21461,-10807,-1441,-2332,10599,1999,289,875,7703 } },
+    { "Fujifilm IS Pro", 0, 0,
+	{ 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } },
+    { "Fujifilm HS10 HS11", 0, 0xf68,
+	{ 12440,-3954,-1183,-1123,9674,1708,-83,1614,4086 } },
+    { "Fujifilm HS2", 0, 0,
+	{ 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
+    { "Fujifilm HS3", 0, 0,
+	{ 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
+    { "Fujifilm HS50EXR", 0, 0,
+	{ 12085,-4727,-953,-3257,11489,2002,-511,2046,4592 } },
+    { "Fujifilm F900EXR", 0, 0,
+	{ 12085,-4727,-953,-3257,11489,2002,-511,2046,4592 } },
+    { "Fujifilm X100S", 0, 0,
+	{ 10592,-4262,-1008,-3514,11355,2465,-870,2025,6386 } },
+    { "Fujifilm X100T", 0, 0,
+	{ 10592,-4262,-1008,-3514,11355,2465,-870,2025,6386 } },
+    { "Fujifilm X100", 0, 0,
+	{ 12161,-4457,-1069,-5034,12874,2400,-795,1724,6904 } },
+    { "Fujifilm X10", 0, 0,
+	{ 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } },
+    { "Fujifilm X20", 0, 0,
+	{ 11768,-4971,-1133,-4904,12927,2183,-480,1723,4605 } },
+    { "Fujifilm X30", 0, 0,
+	{ 12328,-5256,-1144,-4469,12927,1675,-87,1291,4351 } },
+    { "Fujifilm X-Pro1", 0, 0,
+	{ 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } },
+    { "Fujifilm X-A1", 0, 0,
         { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } },
-    { "FUJIFILM X-S1", 0, 0,
-        { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } },
+    { "Fujifilm X-E1", 0, 0,
+	{ 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } },
+    { "Fujifilm X-E2", 0, 0,
+      { 12066,-5927,-367,-1969,9878,1503,-721,2034,5453 } },
+    { "Fujifilm XF1", 0, 0,
+	{ 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } },
+    { "Fujifilm X-M1", 0, 0,
+      { 13193,-6685,-425,-2229,10458,1534,-878,1763,5217 } },
+    { "Fujifilm X-S1", 0, 0,
+	{ 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } },
+    { "Fujifilm X-T1", 0, 0, /* LibRaw */
+      { 12066,-5927,-367,-1969,9878,1503,-721,2034,5453 } },
+    { "Fujifilm XQ1", 0, 0,
+      { 14305,-7365,-687,-3117,12383,432,-287,1660,4361 } },
+    { "Hasselblad Lunar", -512, 0,
+	{ 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } },
+    { "Hasselblad Stellar", -800, 0,
+	{ 8651,-2754,-1057,-3464,12207,1373,-568,1398,4434 } },
+    { "Hasselblad CFV", 0, 0, /* Adobe */
+	{ 8519, -3260, -280, -5081, 13459, 1738, -1449, 2960, 7809, } },
+    { "Hasselblad H-16MP", 0, 0, /* LibRaw */
+	{ 17765,-5322,-1734,-6168,13354,2135,-264,2524,7440 } },
+    { "Hasselblad H-22MP", 0, 0, /* LibRaw */
+	{ 17765,-5322,-1734,-6168,13354,2135,-264,2524,7440 } },
+    {"Hasselblad H-31MP",0, 0, /* LibRaw */
+	{ 14480,-5448,-1686,-3534,13123,2260,384,2952,7232 } },
+    {"Hasselblad H-39MP",0, 0, /* Adobe */
+	{3857,452, -46, -6008, 14477, 1596, -2627, 4481, 5718}},
+    { "Hasselblad H3D-50", 0, 0, /* Adobe  */
+	{3857,452, -46, -6008, 14477, 1596, -2627, 4481, 5718}},
+    {"Hasselblad H4D-40",0, 0, /* LibRaw */
+	{ 6325,-860,-957,-6559,15945,266,167,770,5936 } },
+    {"Hasselblad H4D-50",0, 0, /* LibRaw */
+	{ 15283,-6272,-465,-2030,16031,478,-2379,390,7965 } },
+    {"Hasselblad H4D-60",0, 0, /* Adobe */
+        {9662, -684, -279, -4903, 12293, 2950, -344, 1669, 6024}},
+    {"Hasselblad H5D-50c",0, 0, /* Adobe */
+	{4932, -835, 141, -4878, 11868, 3437, -1138, 1961, 7067}},
+    {"Hasselblad H5D-50",0, 0, /* Adobe */
+	{5656, -659, -346, -3923, 12306, 1791, -1602, 3509, 5442}},
     { "Imacon Ixpress", 0, 0,		/* DJC */
 	{ 7025,-1415,-704,-5188,13765,1424,-1248,2742,6038 } },
-    { "KODAK NC2000", 0, 0,
+    { "Kodak NC2000", 0, 0,
 	{ 13891,-6055,-803,-465,9919,642,2121,82,1291 } },
-    { "Kodak DCS315C", 8, 0,
+    { "Kodak DCS315C", -8, 0,
 	{ 17523,-4827,-2510,756,8546,-137,6113,1649,2250 } },
-    { "Kodak DCS330C", 8, 0,
+    { "Kodak DCS330C", -8, 0,
 	{ 20620,-7572,-2801,-103,10073,-396,3551,-233,2220 } },
-    { "KODAK DCS420", 0, 0,
+    { "Kodak DCS420", 0, 0,
 	{ 10868,-1852,-644,-1537,11083,484,2343,628,2216 } },
-    { "KODAK DCS460", 0, 0,
+    { "Kodak DCS460", 0, 0,
 	{ 10592,-2206,-967,-1944,11685,230,2206,670,1273 } },
-    { "KODAK EOSDCS1", 0, 0,
+    { "Kodak EOSDCS1", 0, 0,
 	{ 10592,-2206,-967,-1944,11685,230,2206,670,1273 } },
-    { "KODAK EOSDCS3B", 0, 0,
+    { "Kodak EOSDCS3B", 0, 0,
 	{ 9898,-2700,-940,-2478,12219,206,1985,634,1031 } },
-    { "Kodak DCS520C", 180, 0,
+    { "Kodak DCS520C", -178, 0,
 	{ 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } },
-    { "Kodak DCS560C", 188, 0,
+    { "Kodak DCS560C", -177, 0,
 	{ 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } },
-    { "Kodak DCS620C", 180, 0,
+    { "Kodak DCS620C", -177, 0,
 	{ 23617,-10175,-3149,-2054,11749,-272,2586,-489,3453 } },
-    { "Kodak DCS620X", 185, 0,
+    { "Kodak DCS620X", -176, 0,
 	{ 13095,-6231,154,12221,-21,-2137,895,4602,2258 } },
-    { "Kodak DCS660C", 214, 0,
+    { "Kodak DCS660C", -173, 0,
 	{ 18244,-6351,-2739,-791,11193,-521,3711,-129,2802 } },
     { "Kodak DCS720X", 0, 0,
 	{ 11775,-5884,950,9556,1846,-1286,-1019,6221,2728 } },
@@ -6836,19 +10883,19 @@ void CLASS adobe_coeff (const char *p_make, const char *p_model)
 	{ 16414,-6060,-1470,-3555,13037,473,2545,122,4948 } },
     { "Kodak ProBack", 0, 0,
 	{ 21179,-8316,-2918,-915,11019,-165,3477,-180,4210 } },
-    { "KODAK P712", 0, 0,
+    { "Kodak P712", 0, 0,
 	{ 9658,-3314,-823,-5163,12695,2768,-1342,1843,6044 } },
-    { "KODAK P850", 0, 0xf7c,
+    { "Kodak P850", 0, 0xf7c,
 	{ 10511,-3836,-1102,-6946,14587,2558,-1481,1792,6246 } },
-    { "KODAK P880", 0, 0xfff,
+    { "Kodak P880", 0, 0xfff,
 	{ 12805,-4662,-1376,-7480,15267,2360,-1626,2194,7904 } },
-    { "KODAK EasyShare Z980", 0, 0,
+    { "Kodak EasyShare Z980", 0, 0,
 	{ 11313,-3559,-1101,-3893,11891,2257,-1214,2398,4908 } },
-    { "KODAK EasyShare Z981", 0, 0,
+    { "Kodak EasyShare Z981", 0, 0,
 	{ 12729,-4717,-1188,-1367,9187,2582,274,860,4411 } },
-    { "KODAK EasyShare Z990", 0, 0xfed,
+    { "Kodak EasyShare Z990", 0, 0xfed,
 	{ 11749,-4048,-1309,-1867,10572,1489,-138,1449,4522 } },
-    { "KODAK EASYSHARE Z1015", 0, 0xef1,
+    { "Kodak EASYSHARE Z1015", 0, 0xef1,
 	{ 11265,-4286,-992,-4694,12343,2647,-1090,1523,5447 } },
     { "Leaf CMost", 0, 0,
 	{ 3952,2189,449,-6701,14585,2275,-4536,7349,6536 } },
@@ -6860,22 +10907,14 @@ void CLASS adobe_coeff (const char *p_make, const char *p_model)
 	{ 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } },
     { "Leaf Aptus 75", 0, 0,
 	{ 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } },
-    { "Leaf Aptus 22", 0, 0,
-      { 8236, 1746, -1314, -8251, 15953, 2428, -3673, 5786, 5770, } },
-    { "Leaf Aptus-II 5", 0, 0,                                                    // Mamiya 645 AFD
-      { 8236, 1746, -1314, -8251, 15953, 2428, -3673, 5786, 5770, } },
-    { "Leaf Aptus-II 6", 0, 0,
-      { 7914, 1414, -1190, -8777, 16582, 2280, -2811, 4605, 5562, } },
-    { "Leaf Aptus-II 7", 0, 0,
-      { 7914, 1414, -1190, -8777, 16582, 2280, -2811, 4605, 5562, } },
-    { "Leaf Aptus-II 8", 0, 0,                                                    // Hasselblad 500 Series
-      { 8236, 1746, -1314, -8251, 15953, 2428, -3673, 5786, 5770, } },
-    { "Leaf Aptus-II 10", 0, 0,
-      { 8236, 1746, -1314, -8251, 15953, 2428, -3673, 5786, 5770, } },
-    { "Leaf Aptus-II 10R", 0, 0,
-      { 8236, 1746, -1314, -8251, 15953, 2428, -3673, 5786, 5770, } },
-    { "Leaf Aptus-II 12", 0, 0,
-      { 8236, 1746, -1314, -8251, 15953, 2428, -3673, 5786, 5770, } },
+    { "Leaf Credo 40", 0, 0,
+	{ 8035, 435, -962, -6001, 13872, 2320, -1159, 3065, 5434 } },
+    { "Leaf Credo 50", 0, 0,
+	{ 3984, 0, 0, 0, 10000, 0, 0, 0, 7666 } },
+    { "Leaf Credo 60", 0, 0,
+	{ 8035, 435, -962, -6001, 13872,2320,-1159,3065,5434} },
+    { "Leaf Credo 80", 0, 0,
+	{ 6294, 686, -712, -5435, 13417, 2211, -1006, 2435, 5042} },
     { "Leaf", 0, 0,
 	{ 8236,1746,-1314,-8251,15953,2428,-3673,5786,5771 } },
     { "Mamiya ZD", 0, 0,
@@ -6890,294 +10929,430 @@ void CLASS adobe_coeff (const char *p_make, const char *p_model)
 	{ 9144,-2777,-998,-6676,14556,2281,-2470,3019,7744 } },
     { "Minolta DiMAGE A1", 0, 0xf8b,
 	{ 9274,-2547,-1167,-8220,16323,1943,-2273,2720,8340 } },
-    { "MINOLTA DiMAGE A200", 0, 0,
+    { "Minolta DiMAGE A200", 0, 0,
 	{ 8560,-2487,-986,-8112,15535,2771,-1209,1324,7743 } },
     { "Minolta DiMAGE A2", 0, 0xf8f,
 	{ 9097,-2726,-1053,-8073,15506,2762,-966,981,7763 } },
     { "Minolta DiMAGE Z2", 0, 0,	/* DJC */
 	{ 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } },
-    { "MINOLTA DYNAX 5", 0, 0xffb,
+    { "Minolta DYNAX 5", 0, 0xffb,
 	{ 10284,-3283,-1086,-7957,15762,2316,-829,882,6644 } },
-    { "MINOLTA DYNAX 7", 0, 0xffb,
+    { "Minolta DYNAX 7", 0, 0xffb,
 	{ 10239,-3104,-1099,-8037,15727,2451,-927,925,6871 } },
-    { "MOTOROLA PIXL", 0, 0,		/* DJC */
+    { "Motorola PIXL", 0, 0,		/* DJC */
 	{ 8898,-989,-1033,-3292,11619,1674,-661,3178,5216 } },
-    { "NIKON D100", 0, 0,
+    { "Nikon D100", 0, 0,
 	{ 5902,-933,-782,-8983,16719,2354,-1402,1455,6464 } },
-    { "NIKON D1H", 0, 0,
+    { "Nikon D1H", 0, 0,
 	{ 7577,-2166,-926,-7454,15592,1934,-2377,2808,8606 } },
-    { "NIKON D1X", 0, 0,
+    { "Nikon D1X", 0, 0,
 	{ 7702,-2245,-975,-9114,17242,1875,-2679,3055,8521 } },
-    { "NIKON D1", 0, 0, /* multiplied by 2.218750, 1.0, 1.148438 */
+    { "Nikon D1", 0, 0, /* multiplied by 2.218750, 1.0, 1.148438 */
 	{ 16772,-4726,-2141,-7611,15713,1972,-2846,3494,9521 } },
-    { "NIKON D200", 0, 0xfbc,
+    { "Nikon D200", 0, 0xfbc,
 	{ 8367,-2248,-763,-8758,16447,2422,-1527,1550,8053 } },
-    { "NIKON D2H", 0, 0,
+    { "Nikon D2H", 0, 0,
 	{ 5710,-901,-615,-8594,16617,2024,-2975,4120,6830 } },
-    { "NIKON D2X", 0, 0,
+    { "Nikon D2X", 0, 0,
 	{ 10231,-2769,-1255,-8301,15900,2552,-797,680,7148 } },
-    { "NIKON D3000", 0, 0,
+    { "Nikon D3000", 0, 0,
 	{ 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } },
-    { "NIKON D3100", 0, 0,
+    { "Nikon D3100", 0, 0,
 	{ 7911,-2167,-813,-5327,13150,2408,-1288,2483,7968 } },
-    { "NIKON D3200", 0, 0,
-        { 7013,-1408,-635,-5268,12902,2640,-1470,2801,7379 } },
-     { "NIKON D300", 0, 0,
+    { "Nikon D3200", 0, 0xfb9,
+	{ 7013,-1408,-635,-5268,12902,2640,-1470,2801,7379 } },
+    { "Nikon D3300", 0, 0,
+	{ 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 } },
+    { "Nikon D300", 0, 0,
 	{ 9030,-1992,-715,-8465,16302,2255,-2689,3217,8069 } },
-    { "NIKON D3X", 0, 0,
+    { "Nikon D3X", 0, 0,
 	{ 7171,-1986,-648,-8085,15555,2718,-2170,2512,7457 } },
-    { "NIKON D3S", 0, 0,
+    { "Nikon D3S", 0, 0,
 	{ 8828,-2406,-694,-4874,12603,2541,-660,1509,7587 } },
-    { "NIKON D3", 0, 0,
+    { "Nikon D3", 0, 0,
 	{ 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } },
-    { "NIKON D40X", 0, 0,
+    { "Nikon D40X", 0, 0,
 	{ 8819,-2543,-911,-9025,16928,2151,-1329,1213,8449 } },
-    { "NIKON D40", 0, 0,
+    { "Nikon D40", 0, 0,
 	{ 6992,-1668,-806,-8138,15748,2543,-874,850,7897 } },
-    { "NIKON D4", 0, 0,
-        { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } },
-    { "NIKON D5000", 0, 0xf00,
+    { "Nikon D4S", 0, 0,
+	{ 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } },
+    { "Nikon D4", 0, 0,
+	{ 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } },
+    { "Nikon Df", 0, 0,
+	{ 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } },
+    { "Nikon D5000", 0, 0xf00,
 	{ 7309,-1403,-519,-8474,16008,2622,-2433,2826,8064 } },
-    { "NIKON D5100", 0, 0x3de6,
+    { "Nikon D5100", 0, 0x3de6,
 	{ 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } },
-    { "NIKON D50", 0, 0,
+    { "Nikon D5200", 0, 0,
+	{ 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } },
+    { "Nikon D5300", 0, 0,
+	{ 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 } },
+    { "Nikon D5500", 0, 0,		/* DJC */
+	{ 5765,-2176,184,-3736,9072,4664,-1028,2213,9259 } },
+    { "Nikon D50", 0, 0,
 	{ 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } },
-    { "NIKON D60", 0, 0,
+    { "Nikon D600", 0, 0x3e07,
+	{ 8178,-2245,-609,-4857,12394,2776,-1207,2086,7298 } },
+    {"Nikon D610",0, 0,
+        { 10426,-4005,-444,-3565,11764,1403,-1206,2266,6549 } },
+    { "Nikon D60", 0, 0,
 	{ 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } },
-    { "NIKON D7000", 0, 0,
+    { "Nikon D7000", 0, 0,
 	{ 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } },
-    { "NIKON D700", 0, 0,
+    { "Nikon D7100", 0, 0,
+	{ 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } },
+    { "Nikon D750", 0, 0,
+	{ 9020,-2890,-715,-4535,12436,2348,-934,1919,7086 } },
+    { "Nikon D700", 0, 0,
 	{ 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } },
-    { "NIKON D70", 0, 0,
+    { "Nikon D70", 0, 0,
 	{ 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } },
-    { "NIKON D800", 0, 0,
-        { 7866,-2108,-555,-4869,12483,2681,-1176,2069,7501 } },
-    { "NIKON D80", 0, 0,
+    { "Nikon D810", 0, 0,
+	{ 9369,-3195,-791,-4488,12430,2301,-893,1796,6872 } },
+    { "Nikon D800", 0, 0,
+	{ 7866,-2108,-555,-4869,12483,2681,-1176,2069,7501 } },
+    { "Nikon D80", 0, 0,
 	{ 8629,-2410,-883,-9055,16940,2171,-1490,1363,8520 } },
-    { "NIKON D90", 0, 0xf00,
+    { "Nikon D90", 0, 0xf00,
 	{ 7309,-1403,-519,-8474,16008,2622,-2434,2826,8064 } },
-    { "NIKON E950", 0, 0x3dd,		/* DJC */
+    { "Nikon E700", 0, 0x3dd,		/* DJC */
+	{ -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } },
+    { "Nikon E800", 0, 0x3dd,		/* DJC */
 	{ -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } },
-    { "NIKON E995", 0, 0,	/* copied from E5000 */
+    { "Nikon E950", 0, 0x3dd,		/* DJC */
+	{ -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } },
+    { "Nikon E995", 0, 0,	/* copied from E5000 */
 	{ -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
-    { "NIKON E2100", 0, 0,	/* copied from Z2, new white balance */
+    { "Nikon E2100", 0, 0,	/* copied from Z2, new white balance */
 	{ 13142,-4152,-1596,-4655,12374,2282,-1769,2696,6711} },
-    { "NIKON E2500", 0, 0,
+    { "Nikon E2500", 0, 0,
 	{ -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
-    { "NIKON E3200", 0, 0,		/* DJC */
+    { "Nikon E3200", 0, 0,		/* DJC */
 	{ 9846,-2085,-1019,-3278,11109,2170,-774,2134,5745 } },
-    { "NIKON E4300", 0, 0,	/* copied from Minolta DiMAGE Z2 */
+    { "Nikon E4300", 0, 0,	/* copied from Minolta DiMAGE Z2 */
 	{ 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } },
-    { "NIKON E4500", 0, 0,
+    { "Nikon E4500", 0, 0,
 	{ -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
-    { "NIKON E5000", 0, 0,
+    { "Nikon E5000", 0, 0,
 	{ -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
-    { "NIKON E5400", 0, 0,
+    { "Nikon E5400", 0, 0,
 	{ 9349,-2987,-1001,-7919,15766,2266,-2098,2680,6839 } },
-    { "NIKON E5700", 0, 0,
+    { "Nikon E5700", 0, 0,
 	{ -5368,11478,2368,5537,-113,3148,-4969,10021,5782,778,9028,211 } },
-    { "NIKON E8400", 0, 0,
+    { "Nikon E8400", 0, 0,
 	{ 7842,-2320,-992,-8154,15718,2599,-1098,1342,7560 } },
-    { "NIKON E8700", 0, 0,
+    { "Nikon E8700", 0, 0,
 	{ 8489,-2583,-1036,-8051,15583,2643,-1307,1407,7354 } },
-    { "NIKON E8800", 0, 0,
+    { "Nikon E8800", 0, 0,
 	{ 7971,-2314,-913,-8451,15762,2894,-1442,1520,7610 } },
-    { "NIKON COOLPIX P6000", 0, 0,
+    { "Nikon COOLPIX A", 0, 0,
+	{ 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } },
+    { "Nikon COOLPIX P330", -200, 0,
+	{ 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } },
+    { "Nikon COOLPIX P340", -200, 0,
+        { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } },
+    { "Nikon COOLPIX P6000", 0, 0,
 	{ 9698,-3367,-914,-4706,12584,2368,-837,968,5801 } },
-    { "NIKON COOLPIX P7000", 0, 0,
+    { "Nikon COOLPIX P7000", 0, 0,
 	{ 11432,-3679,-1111,-3169,11239,2202,-791,1380,4455 } },
-    { "NIKON COOLPIX P7100", 0, 0,
+    { "Nikon COOLPIX P7100", 0, 0,
 	{ 11053,-4269,-1024,-1976,10182,2088,-526,1263,4469 } },
-    { "NIKON 1 ", 0, 0,
+    { "Nikon COOLPIX P7700", -3200, 0,
+	{ 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } },
+    { "Nikon COOLPIX P7800", -3200, 0, /* LibRaw */
+      { 13443,-6418,-673,-1309,10025,1131,-462,1827,4782 } },
+    { "Nikon 1 V3", -200, 0,
+	{ 5958,-1559,-571,-4021,11453,2939,-634,1548,5087 } },
+    { "Nikon 1 J4", 0, 0,
+	{ 5958,-1559,-571,-4021,11453,2939,-634,1548,5087 } },
+    { "Nikon 1 S2", 200, 0,
+	{ 6612,-1342,-618,-3338,11055,2623,-174,1792,5075 } },
+    { "Nikon 1 V2", 0, 0,
+	{ 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } },
+    { "Nikon 1 J3", 0, 0,
+      { 8144,-2671,-473,-1740,9834,1601,-58,1971,4296 } },
+    { "Nikon 1 AW1", 0, 0,
+	{ 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } },
+    { "Nikon 1 ", 0, 0,		/* J1, J2, S1, V1 */
 	{ 8994,-2667,-865,-4594,12324,2552,-699,1786,6260 } },
-    { "OLYMPUS C5050", 0, 0,
+    { "Olympus C5050", 0, 0,
 	{ 10508,-3124,-1273,-6079,14294,1901,-1653,2306,6237 } },
-    { "OLYMPUS C5060", 0, 0,
+    { "Olympus C5060", 0, 0,
 	{ 10445,-3362,-1307,-7662,15690,2058,-1135,1176,7602 } },
-    { "OLYMPUS C7070", 0, 0,
+    { "Olympus C7070", 0, 0,
 	{ 10252,-3531,-1095,-7114,14850,2436,-1451,1723,6365 } },
-    { "OLYMPUS C70", 0, 0,
+    { "Olympus C70", 0, 0,
 	{ 10793,-3791,-1146,-7498,15177,2488,-1390,1577,7321 } },
-    { "OLYMPUS C80", 0, 0,
+    { "Olympus C80", 0, 0,
 	{ 8606,-2509,-1014,-8238,15714,2703,-942,979,7760 } },
-    { "OLYMPUS E-10", 0, 0xffc,
+    { "Olympus E-10", 0, 0xffc,
 	{ 12745,-4500,-1416,-6062,14542,1580,-1934,2256,6603 } },
-    { "OLYMPUS E-1", 0, 0,
+    { "Olympus E-1", 0, 0,
 	{ 11846,-4767,-945,-7027,15878,1089,-2699,4122,8311 } },
-    { "OLYMPUS E-20", 0, 0xffc,
+    { "Olympus E-20", 0, 0xffc,
 	{ 13173,-4732,-1499,-5807,14036,1895,-2045,2452,7142 } },
-    { "OLYMPUS E-300", 0, 0,
+    { "Olympus E-300", 0, 0,
 	{ 7828,-1761,-348,-5788,14071,1830,-2853,4518,6557 } },
-    { "OLYMPUS E-330", 0, 0,
+    { "Olympus E-330", 0, 0,
 	{ 8961,-2473,-1084,-7979,15990,2067,-2319,3035,8249 } },
-    { "OLYMPUS E-30", 0, 0xfbc,
+    { "Olympus E-30", 0, 0xfbc,
 	{ 8144,-1861,-1111,-7763,15894,1929,-1865,2542,7607 } },
-    { "OLYMPUS E-3", 0, 0xf99,
+    { "Olympus E-3", 0, 0xf99,
 	{ 9487,-2875,-1115,-7533,15606,2010,-1618,2100,7389 } },
-    { "OLYMPUS E-400", 0, 0,
+    { "Olympus E-400", 0, 0,
 	{ 6169,-1483,-21,-7107,14761,2536,-2904,3580,8568 } },
-    { "OLYMPUS E-410", 0, 0xf6a,
+    { "Olympus E-410", 0, 0xf6a,
 	{ 8856,-2582,-1026,-7761,15766,2082,-2009,2575,7469 } },
-    { "OLYMPUS E-420", 0, 0xfd7,
+    { "Olympus E-420", 0, 0xfd7,
 	{ 8746,-2425,-1095,-7594,15612,2073,-1780,2309,7416 } },
-    { "OLYMPUS E-450", 0, 0xfd2,
+    { "Olympus E-450", 0, 0xfd2,
 	{ 8745,-2425,-1095,-7594,15613,2073,-1780,2309,7416 } },
-    { "OLYMPUS E-500", 0, 0,
+    { "Olympus E-500", 0, 0,
 	{ 8136,-1968,-299,-5481,13742,1871,-2556,4205,6630 } },
-    { "OLYMPUS E-510", 0, 0xf6a,
+    { "Olympus E-510", 0, 0xf6a,
 	{ 8785,-2529,-1033,-7639,15624,2112,-1783,2300,7817 } },
-    { "OLYMPUS E-520", 0, 0xfd2,
+    { "Olympus E-520", 0, 0xfd2,
 	{ 8344,-2322,-1020,-7596,15635,2048,-1748,2269,7287 } },
-    { "OLYMPUS E-5", 0, 0,
+    { "Olympus E-5", 0, 0xeec,
 	{ 11200,-3783,-1325,-4576,12593,2206,-695,1742,7504 } },
-    { "OLYMPUS E-600", 0, 0xfaf,
+    { "Olympus E-600", 0, 0xfaf,
 	{ 8453,-2198,-1092,-7609,15681,2008,-1725,2337,7824 } },
-    { "OLYMPUS E-620", 0, 0xfaf,
+    { "Olympus E-620", 0, 0xfaf,
 	{ 8453,-2198,-1092,-7609,15681,2008,-1725,2337,7824 } },
-    { "OLYMPUS E-P1", 0, 0xffd,
+    { "Olympus E-P1", 0, 0xffd,
 	{ 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } },
-    { "OLYMPUS E-P2", 0, 0xffd,
+    { "Olympus E-P2", 0, 0xffd,
 	{ 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } },
-    { "OLYMPUS E-P3", 0, 0,
+    { "Olympus E-P3", 0, 0,
 	{ 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } },
-    { "OLYMPUS E-PL1s", 0, 0,
+    { "Olympus E-P5", 0, 0,
+	{ 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
+    { "Olympus E-PL1s", 0, 0,
 	{ 11409,-3872,-1393,-4572,12757,2003,-709,1810,7415 } },
-    { "OLYMPUS E-PL1", 0, 0,
+    { "Olympus E-PL1", 0, 0,
 	{ 11408,-4289,-1215,-4286,12385,2118,-387,1467,7787 } },
-    { "OLYMPUS E-PL2", 0, 0,
+    { "Olympus E-PL2", 0, 0xcf3,
 	{ 15030,-5552,-1806,-3987,12387,1767,-592,1670,7023 } },
-    { "OLYMPUS E-PL3", 0, 0,
+    { "Olympus E-PL3", 0, 0,
 	{ 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } },
-    { "OLYMPUS E-PM1", 0, 0,
+    { "Olympus E-PL5", 0, 0xfcb,
+	{ 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
+    { "Olympus E-PL6", 0, 0,
+	{ 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
+    { "Olympus E-PL7", 0, 0,
+	{ 9197,-3190,-659,-2606,10830,2039,-458,1250,5458 } },
+    { "Olympus E-PM1", 0, 0,
 	{ 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } },
-    { "OLYMPUS E-M5", 0, 0,
-        { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
-    { "OLYMPUS SP350", 0, 0,
+    { "Olympus E-PM2", 0, 0,
+	{ 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
+    { "Olympus E-M10", 0, 0,
+	{ 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
+    { "Olympus E-M1", 0, 0,
+	{ 7687,-1984,-606,-4327,11928,2721,-1381,2339,6452 } },
+    { "Olympus E-M5MarkII", 0, 0,	/* DJC */
+	{ 6617,-2589,139,-2917,8499,4419,-884,1913,6829 } },
+    { "Olympus E-M5", 0, 0xfe1,
+	{ 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
+    { "Olympus SP350", 0, 0,
 	{ 12078,-4836,-1069,-6671,14306,2578,-786,939,7418 } },
-    { "OLYMPUS SP3", 0, 0,
+    { "Olympus SP3", 0, 0,
 	{ 11766,-4445,-1067,-6901,14421,2707,-1029,1217,7572 } },
-    { "OLYMPUS SP500UZ", 0, 0xfff,
+    { "Olympus SP500UZ", 0, 0xfff,
 	{ 9493,-3415,-666,-5211,12334,3260,-1548,2262,6482 } },
-    { "OLYMPUS SP510UZ", 0, 0xffe,
+    { "Olympus SP510UZ", 0, 0xffe,
 	{ 10593,-3607,-1010,-5881,13127,3084,-1200,1805,6721 } },
-    { "OLYMPUS SP550UZ", 0, 0xffe,
+    { "Olympus SP550UZ", 0, 0xffe,
 	{ 11597,-4006,-1049,-5432,12799,2957,-1029,1750,6516 } },
-    { "OLYMPUS SP560UZ", 0, 0xff9,
+    { "Olympus SP560UZ", 0, 0xff9,
 	{ 10915,-3677,-982,-5587,12986,2911,-1168,1968,6223 } },
-    { "OLYMPUS SP570UZ", 0, 0,
+    { "Olympus SP570UZ", 0, 0,
 	{ 11522,-4044,-1146,-4736,12172,2904,-988,1829,6039 } },
-    { "OLYMPUS XZ-1", 0, 0,
+    {"Olympus STYLUS1",0, 0,
+        { 11976,-5518,-545,-1419,10472,846,-475,1766,4524 } },
+    { "Olympus XZ-10", 0, 0,
+	{ 9777,-3483,-925,-2886,11297,1800,-602,1663,5134 } },
+    { "Olympus XZ-1", 0, 0,
 	{ 10901,-4095,-1074,-1141,9208,2293,-62,1417,5158 } },
-    { "PENTAX *ist DL2", 0, 0,
+    { "Olympus XZ-2", 0, 0,
+	{ 9777,-3483,-925,-2886,11297,1800,-602,1663,5134 } },
+    { "OmniVision", 0, 0,		/* DJC */
+	{ 12782,-4059,-379,-478,9066,1413,1340,1513,5176 } },
+    { "Pentax *ist DL2", 0, 0,
 	{ 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
-    { "PENTAX *ist DL", 0, 0,
+    { "Pentax *ist DL", 0, 0,
 	{ 10829,-2838,-1115,-8339,15817,2696,-837,680,11939 } },
-    { "PENTAX *ist DS2", 0, 0,
+    { "Pentax *ist DS2", 0, 0,
 	{ 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
-    { "PENTAX *ist DS", 0, 0,
+    { "Pentax *ist DS", 0, 0,
 	{ 10371,-2333,-1206,-8688,16231,2602,-1230,1116,11282 } },
-    { "PENTAX *ist D", 0, 0,
+    { "Pentax *ist D", 0, 0,
 	{ 9651,-2059,-1189,-8881,16512,2487,-1460,1345,10687 } },
-    { "PENTAX K10D", 0, 0,
+    { "Pentax K10D", 0, 0,
 	{ 9566,-2863,-803,-7170,15172,2112,-818,803,9705 } },
-    { "PENTAX K1", 0, 0,
+    { "Pentax K1", 0, 0,
 	{ 11095,-3157,-1324,-8377,15834,2720,-1108,947,11688 } },
-    { "PENTAX K20D", 0, 0,
+    { "Pentax K20D", 0, 0,
 	{ 9427,-2714,-868,-7493,16092,1373,-2199,3264,7180 } },
-    { "PENTAX K200D", 0, 0,
+    { "Pentax K200D", 0, 0,
 	{ 9186,-2678,-907,-8693,16517,2260,-1129,1094,8524 } },
-    { "PENTAX K2000", 0, 0,
+    { "Pentax K2000", 0, 0,
 	{ 11057,-3604,-1155,-5152,13046,2329,-282,375,8104 } },
-    { "PENTAX K-m", 0, 0,
+    { "Pentax K-m", 0, 0,
 	{ 11057,-3604,-1155,-5152,13046,2329,-282,375,8104 } },
-    { "PENTAX K-x", 0, 0,
+    { "Pentax K-x", 0, 0,
 	{ 8843,-2837,-625,-5025,12644,2668,-411,1234,7410 } },
-    { "PENTAX K-r", 0, 0,
+   { "Pentax K-r", 0, 0,
 	{ 9895,-3077,-850,-5304,13035,2521,-883,1768,6936 } },
-    { "PENTAX K-5", 0, 0,
+    { "Pentax K-3", 0, 0,
+	{ 7415,-2052,-721,-5186,12788,2682,-1446,2157,6773 } },
+    { "Pentax K-5 II", 0, 0,
+	{ 8170,-2725,-639,-4440,12017,2744,-771,1465,6599 } },
+    { "Pentax K-5", 0, 0,
 	{ 8713,-2833,-743,-4342,11900,2772,-722,1543,6247 } },
-    { "PENTAX K-7", 0, 0,
+    { "Pentax K-7", 0, 0,
 	{ 9142,-2947,-678,-8648,16967,1663,-2224,2898,8615 } },
-    { "PENTAX 645D", 0, 0x3e00,
+    { "Pentax K-S1", 0, 0,
+	{ 8512,-3211,-787,-4167,11966,2487,-638,1288,6054 } },
+    { "Pentax MX-1", 0, 0,
+	{ 8804,-2523,-1238,-2423,11627,860,-682,1774,4753 } },
+    { "Pentax Q10", 0, 0,
+	{ 12995,-5593,-1107,-1879,10139,2027,-64,1233,4919 } },
+    { "Pentax 645D", 0, 0x3e00,
 	{ 10646,-3593,-1158,-3329,11699,1831,-667,2874,6287 } },
+    { "Panasonic DMC-CM1", -15, 0,
+        { 8770, -3194,-820,-2871,11281,1803,-513,1552,4434} },
     { "Panasonic DMC-FZ8", 0, 0xf7f,
 	{ 8986,-2755,-802,-6341,13575,3077,-1476,2144,6379 } },
     { "Panasonic DMC-FZ18", 0, 0,
 	{ 9932,-3060,-935,-5809,13331,2753,-1267,2155,5575 } },
-    { "Panasonic DMC-FZ28", 15, 0xf96,
+    { "Panasonic DMC-FZ28", -15, 0xf96,
 	{ 10109,-3488,-993,-5412,12812,2916,-1305,2140,5543 } },
     { "Panasonic DMC-FZ30", 0, 0xf94,
 	{ 10976,-4029,-1141,-7918,15491,2600,-1670,2071,8246 } },
-    { "Panasonic DMC-FZ3", 143, 0,
+    { "Panasonic DMC-FZ3", -15, 0,
 	{ 9938,-2780,-890,-4604,12393,2480,-1117,2304,4620 } },
-    { "Panasonic DMC-FZ4", 143, 0,
+    { "Panasonic DMC-FZ4", -15, 0,
 	{ 13639,-5535,-1371,-1698,9633,2430,316,1152,4108 } },
     { "Panasonic DMC-FZ50", 0, 0,
 	{ 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } },
-    { "LEICA V-LUX1", 0, 0,
+    { "Panasonic DMC-FZ7", -15, 0,
+	{ 11532,-4324,-1066,-2375,10847,1749,-564,1699,4351 } },
+    { "Leica V-LUX1", 0, 0,
 	{ 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } },
-    { "Panasonic DMC-L10", 15, 0xf96,
+    { "Panasonic DMC-L10", -15, 0xf96,
 	{ 8025,-1942,-1050,-7920,15904,2100,-2456,3005,7039 } },
     { "Panasonic DMC-L1", 0, 0xf7f,
 	{ 8054,-1885,-1025,-8349,16367,2040,-2805,3542,7629 } },
-    { "LEICA DIGILUX 3", 0, 0xf7f,
+    { "Leica DIGILUX 3", 0, 0xf7f,
 	{ 8054,-1885,-1025,-8349,16367,2040,-2805,3542,7629 } },
     { "Panasonic DMC-LC1", 0, 0,
 	{ 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } },
-    { "LEICA DIGILUX 2", 0, 0,
+    { "Leica DIGILUX 2", 0, 0,
 	{ 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } },
+    { "Panasonic DMC-LX100", -15, 0,
+	{ 8844,-3538,-768,-3709,11762,2200,-698,1792,5220 } },
+    { "Leica D-LUX (Typ 109)", -15, 0,
+	{ 8844,-3538,-768,-3709,11762,2200,-698,1792,5220 } },
+    { "Panasonic DMC-LF1", -15, 0,
+	{ 9379,-3267,-816,-3227,11560,1881,-926,1928,5340 } },
+    { "Leica C (Typ 112)", -15, 0,
+	{ 9379,-3267,-816,-3227,11560,1881,-926,1928,5340 } },
     { "Panasonic DMC-LX1", 0, 0xf7f,
 	{ 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } },
-    { "LEICA D-LUX2", 0, 0xf7f,
+    { "Leica D-Lux (Typ 109)", 0, 0xf7f, /* LibRaw */
+	{ 10031,-4555,-456,-3024,11520,1091,-1342,2611,4752 } },
+    { "Leica D-LUX2", 0, 0xf7f,
 	{ 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } },
     { "Panasonic DMC-LX2", 0, 0,
 	{ 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } },
-    { "LEICA D-LUX3", 0, 0,
+    { "Leica D-LUX3", 0, 0,
 	{ 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } },
-    { "Panasonic DMC-LX3", 15, 0,
+    { "Panasonic DMC-LX3", -15, 0,
 	{ 8128,-2668,-655,-6134,13307,3161,-1782,2568,6083 } },
-    { "LEICA D-LUX 4", 15, 0,
+    { "Leica D-LUX 4", -15, 0,
 	{ 8128,-2668,-655,-6134,13307,3161,-1782,2568,6083 } },
-    { "Panasonic DMC-LX5", 143, 0,
+    { "Panasonic DMC-LX5", -15, 0,
 	{ 10909,-4295,-948,-1333,9306,2399,22,1738,4582 } },
-    { "LEICA D-LUX 5", 143, 0,
+    { "Leica D-LUX 5", -15, 0,
 	{ 10909,-4295,-948,-1333,9306,2399,22,1738,4582 } },
-    { "Panasonic DMC-FZ100", 143, 0xfff,
+    { "Panasonic DMC-LX7", -15, 0,
+	{ 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } },
+    { "Leica D-LUX 6", -15, 0,
+	{ 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } },
+    { "Panasonic DMC-FZ1000", -15, 0,
+	{ 7830,-2696,-763,-3325,11667,1866,-641,1712,4824 } },
+    { "Leica V-LUX (Typ 114)", 15, 0,
+	{ 7830,-2696,-763,-3325,11667,1866,-641,1712,4824 } },
+    { "Panasonic DMC-FZ100", -15, 0xfff,
 	{ 16197,-6146,-1761,-2393,10765,1869,366,2238,5248 } },
-    { "LEICA V-LUX 2", 143, 0xfff,
+    { "Leica V-LUX 2", -15, 0xfff,
 	{ 16197,-6146,-1761,-2393,10765,1869,366,2238,5248 } },
-    { "Panasonic DMC-FZ150", 143, 0xfff,
+    { "Panasonic DMC-FZ150", -15, 0xfff,
 	{ 11904,-4541,-1189,-2355,10899,1662,-296,1586,4289 } },
-    { "LEICA V-LUX 3", 143, 0xfff,
+    { "Leica V-LUX 3", -15, 0xfff,
 	{ 11904,-4541,-1189,-2355,10899,1662,-296,1586,4289 } },
-    { "Panasonic DMC-FX150", 15, 0xfff,
+    { "Panasonic DMC-FZ200", -15, 0xfff,
+	{ 8112,-2563,-740,-3730,11784,2197,-941,2075,4933 } },
+    { "Leica V-LUX 4", -15, 0xfff,
+	{ 8112,-2563,-740,-3730,11784,2197,-941,2075,4933 } },
+    { "Panasonic DMC-FX150", -15, 0xfff,
 	{ 9082,-2907,-925,-6119,13377,3058,-1797,2641,5609 } },
     { "Panasonic DMC-G10", 0, 0,
 	{ 10113,-3400,-1114,-4765,12683,2317,-377,1437,6710 } },
-    { "Panasonic DMC-G1", 15, 0xf94,
+    { "Panasonic DMC-G1", -15, 0xf94,
 	{ 8199,-2065,-1056,-8124,16156,2033,-2458,3022,7220 } },
-    { "Panasonic DMC-G2", 15, 0xf3c,
+    { "Panasonic DMC-G2", -15, 0xf3c,
 	{ 10113,-3400,-1114,-4765,12683,2317,-377,1437,6710 } },
-    { "Panasonic DMC-G3", 143, 0xfff,
+    { "Panasonic DMC-G3", -15, 0xfff,
 	{ 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } },
-    { "Panasonic DMC-GF1", 15, 0xf92,
+    { "Panasonic DMC-G5", -15, 0xfff,
+	{ 7798,-2562,-740,-3879,11584,2613,-1055,2248,5434 } },
+    { "Panasonic DMC-G6", -15, 0xfff,
+	{ 8294,-2891,-651,-3869,11590,2595,-1183,2267,5352 } },
+    { "Panasonic DMC-GF1", -15, 0xf92,
 	{ 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } },
-    { "Panasonic DMC-GF2", 143, 0xfff,
+    { "Panasonic DMC-GF2", -15, 0xfff,
 	{ 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } },
-    { "Panasonic DMC-GF3", 143, 0xfff,
+    { "Panasonic DMC-GF3", -15, 0xfff,
 	{ 9051,-2468,-1204,-5212,13276,2121,-1197,2510,6890 } },
-   { "Panasonic DMC-GF5", 143, 0xfff,
-        { 8228,-2945,-660,-3938,11792,2430,-1094,2278,5793 } },
-     { "Panasonic DMC-GH1", 15, 0xf92,
+    { "Panasonic DMC-GF5", -15, 0xfff,
+	{ 8228,-2945,-660,-3938,11792,2430,-1094,2278,5793 } },
+    { "Panasonic DMC-GF6", -15, 0,
+	{ 8130,-2801,-946,-3520,11289,2552,-1314,2511,5791 } },
+    { "Panasonic DMC-GF7", -15, 0,	/* DJC */
+	{ 6086,-2691,-18,-4207,9767,4441,-1486,2640,7441 } },
+    { "Panasonic DMC-GH1", -15, 0xf92,
 	{ 6299,-1466,-532,-6535,13852,2969,-2331,3112,5984 } },
-    { "Panasonic DMC-GH2", 15, 0xf95,
+    { "Panasonic DMC-GH2", -15, 0xf95,
 	{ 7780,-2410,-806,-3913,11724,2484,-1018,2390,5298 } },
-    { "Panasonic DMC-GX1", 143, 0,
+    { "Panasonic DMC-GH3", -15, 0,
+	{ 6559,-1752,-491,-3672,11407,2586,-962,1875,5130 } },
+    { "Panasonic DMC-GH4", -15, 0,
+	{ 7122,-2108,-512,-3155,11201,2231,-541,1423,5045 } },
+    { "Panasonic DMC-GM1", -15, 0,
+	{ 6770,-1895,-744,-5232,13145,2303,-1664,2691,5703 } },
+    { "Panasonic DMC-GM5", -15, 0,
+	{ 8238,-3244,-679,-3921,11814,2384,-836,2022,5852 } },
+    { "Panasonic DMC-GX1", -15, 0,
 	{ 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } },
+    {"Panasonic DMC-GX7", -15,0, /* LibRaw */
+        {7541,-2355,-591,-3163,10598,1894,-933,2109,5006}},
+    {"Panasonic DMC-TZ6",-15, 0,
+        { 15964,-8332,-389,1756,7198,383,862,784,1995 } },
+    {"Panasonic DMC-ZS4",-15, 0,
+        { 15964,-8332,-389,1756,7198,383,862,784,1995 } },
+    { "Panasonic DMC-TZ7",-15, 0,
+	{ 7901,-2472,-600,-3298,10720,2210,-864,2205,5064 } },
+    { "Panasonic DMC-ZS5",-15, 0,	/* same ID as Panasonic DMC-TZ70 */
+	{ 7901,-2472,-600,-3298,10720,2210,-864,2205,5064 } },
     { "Phase One H 20", 0, 0,		/* DJC */
 	{ 1313,1855,-109,-6715,15908,808,-327,1840,6020 } },
     { "Phase One H 25", 0, 0,
 	{ 2905,732,-237,-8134,16626,1476,-3038,4253,7517 } },
+    {"Phase One IQ250",0, 0,
+        { 4396,-153,-249,-5267,12249,2657,-1397,2323,6014 } },
     { "Phase One P 2", 0, 0,
 	{ 2905,732,-237,-8134,16626,1476,-3038,4253,7517 } },
     { "Phase One P 30", 0, 0,
@@ -7188,101 +11363,207 @@ void CLASS adobe_coeff (const char *p_make, const char *p_model)
 	{ 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } },
     { "Phase One P65", 0, 0,
 	{ 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } },
-    { "RED ONE", 704, 0xffff,		/* DJC */
+    { "Red One", 704, 0xffff,		/* DJC */
 	{ 21014,-7891,-2613,-3056,12201,856,-2203,5125,8042 } },
-    { "SAMSUNG EX1", 0, 0x3e00,
+    { "Samsung EK-GN120", 0, 0, /* Adobe; Galaxy NX */
+        { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } },
+    { "Samsung EX1", 0, 0x3e00,
 	{ 8898,-2498,-994,-3144,11328,2066,-760,1381,4576 } },
-    { "SAMSUNG NX2", 0, 0xfff,  /* NX20, NX200, NX210 */
-        { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } },
-    { "SAMSUNG NX", 0, 0,	/* NX5, NX10, NX11, NX100 */
+    { "Samsung EX2F", 0, 0x7ff,
+	{ 10648,-3897,-1055,-2022,10573,1668,-492,1611,4742 } },
+    { "Samsung NX mini", 0, 0,
+	{ 5222,-1196,-550,-6540,14649,2009,-1666,2819,5657 } },
+    { "Samsung NX3000", 0, 0,
+	{ 8060,-2933,-761,-4504,12890,1762,-630,1489,5227 } },
+    { "Samsung NX30", 0, 0,	/* NX30, NX300, NX300M */
+	{ 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } },
+    { "Samsung NX2000", 0, 0,
+	{ 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } },
+    { "Samsung NX2", 0, 0xfff,	/* NX20, NX200, NX210 */
+	{ 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } },
+    { "Samsung NX1000", 0, 0,
+	{ 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } },
+    { "Samsung NX1100", 0, 0,
+	{ 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } },
+    { "Samsung NX11", 0, 0,
 	{ 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } },
-    { "SAMSUNG WB2000", 0, 0xfff,
+    { "Samsung NX10", 0, 0,	/* also NX100 */
+	{ 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } },
+    { "Samsung NX5", 0, 0,
+	{ 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } },
+    { "Samsung NX1", -128, 0,
+	{ 10686,-4042,-1052,-3595,13238,276,-464,1259,5931 } },
+    { "Samsung WB2000", 0, 0xfff,
 	{ 12093,-3557,-1155,-1000,9534,1733,-22,1787,4576 } },
-    { "SAMSUNG GX-1", 0, 0,
+    { "Samsung GX-1", 0, 0,
 	{ 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
-    { "SAMSUNG S85", 0, 0xffff,		/* DJC */
+    { "Samsung GX20", 0, 0,	/* copied from Pentax K20D */
+	{ 9427,-2714,-868,-7493,16092,1373,-2199,3264,7180 } },
+    { "Samsung S85", 0, 0,		/* DJC */
 	{ 11885,-3968,-1473,-4214,12299,1916,-835,1655,5549 } },
+     // Foveon: LibRaw color data
+    {"Sigma dp1 Quattro",2047, 0,
+      { 13801,-3390,-1016,5535,3802,877,1848,4245,3730 } },
+    {"Sigma dp2 Quattro",2047, 0,
+      { 13801,-3390,-1016,5535,3802,877,1848,4245,3730 } },
+    { "Sigma SD9", 15, 4095,			/* LibRaw */
+      { 14082,-2201,-1056,-5243,14788,167,-121,196,8881 } },
+    { "Sigma SD10", 15, 16383,			/* LibRaw */
+      { 14082,-2201,-1056,-5243,14788,167,-121,196,8881 } },
+    { "Sigma SD14", 15, 16383,			/* LibRaw */
+      { 14082,-2201,-1056,-5243,14788,167,-121,196,8881 } },
+    { "Sigma SD15", 15, 4095,			/* LibRaw */
+      { 14082,-2201,-1056,-5243,14788,167,-121,196,8881 } },
+    // Merills + SD1
+    { "Sigma SD1", 31, 4095,			/* LibRaw */
+      { 5133,-1895,-353,4978,744,144,3837,3069,2777 } },
+    { "Sigma DP1 Merrill", 31, 4095,			/* LibRaw */
+      { 5133,-1895,-353,4978,744,144,3837,3069,2777 } },
+    { "Sigma DP2 Merrill", 31, 4095,			/* LibRaw */
+      { 5133,-1895,-353,4978,744,144,3837,3069,2777 } },
+    { "Sigma DP3 Merrill", 31, 4095,			/* LibRaw */
+      { 5133,-1895,-353,4978,744,144,3837,3069,2777 } },
+    // Sigma DP (non-Merill Versions)
+    { "Sigma DP", 0, 4095,			/* LibRaw */
+      //  { 7401,-1169,-567,2059,3769,1510,664,3367,5328 } },
+      { 13100,-3638,-847,6855,2369,580,2723,3218,3251 } },
     { "Sinar", 0, 0,			/* DJC */
 	{ 16442,-2956,-2422,-2877,12128,750,-1136,6066,4559 } },
-    { "SONY DSC-F828", 491, 0,
+    { "Sony DSC-F828", 0, 0,
 	{ 7924,-1910,-777,-8226,15459,2998,-1517,2199,6818,-7242,11401,3481 } },
-    { "SONY DSC-R1", 512, 0,
+    { "Sony DSC-R1", -512, 0,
 	{ 8512,-2641,-694,-8042,15670,2526,-1821,2117,7414 } },
-    { "SONY DSC-V3", 0, 0,
+    { "Sony DSC-V3", 0, 0,
 	{ 7511,-2571,-692,-7894,15088,3060,-948,1111,8128 } },
-    { "SONY DSLR-A100", 0, 0xfeb,
+    { "Sony DSC-RX100M", -800, 0,	/* M2 and M3 */
+	{ 6596,-2079,-562,-4782,13016,1933,-970,1581,5181 } },
+    { "Sony DSC-RX100", -800, 0,
+	{ 8651,-2754,-1057,-3464,12207,1373,-568,1398,4434 } },
+    {"Sony DSC-RX10",0, 0,
+        { 8562,-3595,-385,-2715,11089,1128,-1023,2081,4400 } },
+    { "Sony DSC-RX1R", -512, 0,
+        { 8195,-2800,-422,-4261,12273,1709,-1505,2400,5624 } },
+    { "Sony DSC-RX1", -512, 0,
+	{ 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } },
+    { "Sony DSLR-A100", 0, 0xfeb,
 	{ 9437,-2811,-774,-8405,16215,2290,-710,596,7181 } },
-    { "SONY DSLR-A290", 0, 0,
+    { "Sony DSLR-A290", 0, 0,
 	{ 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } },
-    { "SONY DSLR-A2", 0, 0,
+    { "Sony DSLR-A2", 0, 0,
 	{ 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } },
-    { "SONY DSLR-A300", 0, 0,
+    { "Sony DSLR-A300", 0, 0,
 	{ 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } },
-    { "SONY DSLR-A330", 0, 0,
+    { "Sony DSLR-A330", 0, 0,
 	{ 9847,-3091,-929,-8485,16346,2225,-714,595,7103 } },
-    { "SONY DSLR-A350", 0, 0xffc,
+    { "Sony DSLR-A350", 0, 0xffc,
 	{ 6038,-1484,-578,-9146,16746,2513,-875,746,7217 } },
-    { "SONY DSLR-A380", 0, 0,
+    { "Sony DSLR-A380", 0, 0,
 	{ 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } },
-    { "SONY DSLR-A390", 0, 0,
+    { "Sony DSLR-A390", 0, 0,
 	{ 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } },
-    { "SONY DSLR-A450", 128, 0xfeb,
+    { "Sony DSLR-A450", -512, 0xfeb,
 	{ 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } },
-    { "SONY DSLR-A580", 128, 0xfeb,
+    { "Sony DSLR-A580", -512, 0xfeb,
 	{ 5932,-1492,-411,-4813,12285,2856,-741,1524,6739 } },
-    { "SONY DSLR-A5", 128, 0xfeb,
+    { "Sony DSLR-A500", -512, 0xfeb,
+	{ 6046,-1127,-278,-5574,13076,2786,-691,1419,7625 } },
+    { "Sony DSLR-A5", -512, 0xfeb,
 	{ 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } },
-    { "SONY DSLR-A700", 126, 0,
+    { "Sony DSLR-A700", -512, 0,
 	{ 5775,-805,-359,-8574,16295,2391,-1943,2341,7249 } },
-    { "SONY DSLR-A850", 128, 0,
+    { "Sony DSLR-A850", -512, 0,
 	{ 5413,-1162,-365,-5665,13098,2866,-608,1179,8440 } },
-    { "SONY DSLR-A900", 128, 0,
+    { "Sony DSLR-A900", -512, 0,
 	{ 5209,-1072,-397,-8845,16120,2919,-1618,1803,8654 } },
-    { "SONY NEX-5N", 128, 0,
+    { "Sony ILCA-77M2", -512, 0,
+	{ 5991,-1732,-443,-4100,11989,2381,-704,1467,5992 } },
+    { "Sony ILCE-7M2", -512, 0,
+	{ 5271,-712,-347,-6153,13653,2763,-1601,2366,7242 } },
+    { "Sony ILCE-7S", -512, 0,
+	{ 5838,-1430,-246,-3497,11477,2297,-748,1885,5778 } },
+    { "Sony ILCE-7R", -512, 0,
+	{ 4913,-541,-202,-6130,13513,2906,-1564,2151,7183 } },
+    { "Sony ILCE-7", -512, 0,
+	{ 5271,-712,-347,-6153,13653,2763,-1601,2366,7242 } },
+    { "Sony ILCE", -512, 0,	/* 3000, 5000, 5100, 6000, and QX1 */
+	{ 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
+    { "Sony NEX-5N", -512, 0,
 	{ 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
-    { "SONY NEX-3", 138, 0,		/* DJC */
-	{ 6907,-1256,-645,-4940,12621,2320,-1710,2581,6230 } },
-    { "SONY NEX-5", 116, 0,		/* DJC */
-	{ 6807,-1350,-342,-4216,11649,2567,-1089,2001,6420 } },
-    { "SONY NEX-3", 128, 0,		/* Adobe */
+    { "Sony NEX-5R", -512, 0,
+	{ 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
+    { "Sony NEX-5T", -512, 0,
+	{ 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
+    { "Sony NEX-3N", -512, 0,
+	{ 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
+    { "Sony NEX-3", -512, 0,		/* Adobe */
 	{ 6549,-1550,-436,-4880,12435,2753,-854,1868,6976 } },
-    { "SONY NEX-5", 128, 0,		/* Adobe */
+    { "Sony NEX-5", -512, 0,		/* Adobe */
 	{ 6549,-1550,-436,-4880,12435,2753,-854,1868,6976 } },
-    { "SONY NEX-7", 128, 0,
+    { "Sony NEX-6", -512, 0,
+	{ 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
+    { "Sony NEX-7", -512, 0,
 	{ 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } },
-    { "SONY NEX", 128, 0,       /* NEX-C3, NEX-F3 */
-        { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
-     { "SONY SLT-A33", 128, 0,
+    { "Sony NEX", -512, 0,	/* NEX-C3, NEX-F3 */
+	{ 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
+    { "Sony SLT-A33", -512, 0,
 	{ 6069,-1221,-366,-5221,12779,2734,-1024,2066,6834 } },
-    { "SONY SLT-A35", 128, 0,
+    { "Sony SLT-A35", -512, 0,
 	{ 5986,-1618,-415,-4557,11820,3120,-681,1404,6971 } },
-    { "SONY SLT-A37", 128, 0,
-        { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
-    { "SONY SLT-A55", 128, 0,
+    { "Sony SLT-A37", -512, 0,
+	{ 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
+    { "Sony SLT-A55", -512, 0,
 	{ 5932,-1492,-411,-4813,12285,2856,-741,1524,6739 } },
-    { "SONY SLT-A57", 128, 0,
-        { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
-    { "SONY SLT-A65", 128, 0,
+    { "Sony SLT-A57", -512, 0,
+	{ 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
+    { "Sony SLT-A58", -512, 0,
+	{ 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
+    { "Sony SLT-A65", -512, 0,
 	{ 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } },
-    { "SONY SLT-A77", 128, 0,
-	{ 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } }
+    { "Sony SLT-A77", -512, 0,
+	{ 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } },
+    { "Sony SLT-A99", -512, 0,
+	{ 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } },
   };
   double cam_xyz[4][3];
   char name[130];
   int i, j;
 
-  sprintf (name, "%s %s", p_make, p_model);
+  int bl4=(cblack[0]+cblack[1]+cblack[2]+cblack[3])/4,bl64=0;
+  if(cblack[4]*cblack[5]>0)
+  {
+	  for (unsigned c = 0; c < 4096 && c < cblack[4]*cblack[5]; c++)
+		  bl64+=cblack[c+6];
+	  bl64 /= cblack[4]*cblack[5];
+  }
+  int rblack  = black+bl4+bl64;
+
+  sprintf (name, "%s %s", t_make, t_model);
   for (i=0; i < sizeof table / sizeof *table; i++)
-    if (!strncmp (name, table[i].prefix, strlen(table[i].prefix))) {
-      if (table[i].t_black)   black   = (ushort) table[i].t_black;
+    if (!strncasecmp(name, table[i].prefix, strlen(table[i].prefix))) {
+      if (table[i].t_black>0)
+        {
+          black   = (ushort) table[i].t_black;
+          memset(cblack,0,sizeof(cblack));
+        }
+      else if(table[i].t_black <0 && rblack == 0 )
+        {
+          black   = (ushort) (-table[i].t_black);
+          memset(cblack,0,sizeof(cblack));
+        }
       if (table[i].t_maximum) maximum = (ushort) table[i].t_maximum;
       if (table[i].trans[0]) {
-        for (j=0; j < 12; j++)
+	for (raw_color = j=0; j < 12; j++)
 #ifdef LIBRAW_LIBRARY_BUILD
-          imgdata.color.cam_xyz[0][j] = 
+		if(internal_only)
+			imgdata.color.cam_xyz[0][j] = table[i].trans[j] / 10000.0;
+		else
+                  imgdata.color.cam_xyz[0][j] =
 #endif
-	  cam_xyz[0][j] = table[i].trans[j] / 10000.0;
-      cam_xyz_coeff (cam_xyz);
+                    cam_xyz[0][j] = table[i].trans[j] / 10000.0;
+#ifdef LIBRAW_LIBRARY_BUILD
+	if(!internal_only)
+#endif
+          cam_xyz_coeff (rgb_cam, cam_xyz);
       }
       break;
     }
@@ -7306,9 +11587,6 @@ void CLASS simple_coeff (int index)
 
   for (raw_color = i=0; i < 3; i++)
     FORCC rgb_cam[i][c] = table[index][i*colors+c];
-#ifdef LIBRAW_LIBRARY_BUILD
-  color_flags.rgb_cam_state = LIBRAW_COLORSTATE_CALCULATED;
-#endif
 }
 
 short CLASS guess_byte_order (int words)
@@ -7330,7 +11608,6 @@ short CLASS guess_byte_order (int words)
   return sum[0] < sum[1] ? 0x4d4d : 0x4949;
 }
 
-
 float CLASS find_green (int bps, int bite, int off0, int off1)
 {
   UINT64 bitbuf=0;
@@ -7356,16 +11633,14 @@ float CLASS find_green (int bps, int bite, int off0, int off1)
   return 100 * log(sum[0]/sum[1]);
 }
 
+
 /*
    Identify which camera created this file, and set global variables
    accordingly.
  */
 void CLASS identify()
 {
-  char head[32], *cp;
-  int hlen, flen, fsize, zero_fsize=1, i, c, is_canon;
-  struct jhead jh;
-  short pana[][6] = {
+  static const short pana[][6] = {
     { 3130, 1743,  4,  0, -6,  0 },
     { 3130, 2055,  4,  0, -6,  0 },
     { 3130, 2319,  4,  0, -6,  0 },
@@ -7388,112 +11663,260 @@ void CLASS identify()
     { 4290, 2391,  3,  0, -8, -1 },
     { 4330, 2439, 17, 15,-44,-19 },
     { 4508, 2962,  0,  0, -3, -4 },
-    { 4508, 3330,  0,  0, -3, -6 } };
+    { 4508, 3330,  0,  0, -3, -6 },
+  };
+  static const ushort canon[][11] = {
+    { 1944, 1416,   0,  0, 48,  0 },
+    { 2144, 1560,   4,  8, 52,  2, 0, 0, 0, 25 },
+    { 2224, 1456,  48,  6,  0,  2 },
+    { 2376, 1728,  12,  6, 52,  2 },
+    { 2672, 1968,  12,  6, 44,  2 },
+    { 3152, 2068,  64, 12,  0,  0, 16 },
+    { 3160, 2344,  44, 12,  4,  4 },
+    { 3344, 2484,   4,  6, 52,  6 },
+    { 3516, 2328,  42, 14,  0,  0 },
+    { 3596, 2360,  74, 12,  0,  0 },
+    { 3744, 2784,  52, 12,  8, 12 },
+    { 3944, 2622,  30, 18,  6,  2 },
+    { 3948, 2622,  42, 18,  0,  2 },
+    { 3984, 2622,  76, 20,  0,  2, 14 },
+    { 4104, 3048,  48, 12, 24, 12 },
+    { 4116, 2178,   4,  2,  0,  0 },
+    { 4152, 2772, 192, 12,  0,  0 },
+    { 4160, 3124, 104, 11,  8, 65 },
+    { 4176, 3062,  96, 17,  8,  0, 0, 16, 0, 7, 0x49 },
+    { 4192, 3062,  96, 17, 24,  0, 0, 16, 0, 0, 0x49 },
+    { 4312, 2876,  22, 18,  0,  2 },
+    { 4352, 2874,  62, 18,  0,  0 },
+    { 4476, 2954,  90, 34,  0,  0 },
+    { 4480, 3348,  12, 10, 36, 12, 0, 0, 0, 18, 0x49 },
+    { 4480, 3366,  80, 50,  0,  0 },
+    { 4496, 3366,  80, 50, 12,  0 },
+    { 4768, 3516,  96, 16,  0,  0, 0, 16 },
+    { 4832, 3204,  62, 26,  0,  0 },
+    { 4832, 3228,  62, 51,  0,  0 },
+    { 5108, 3349,  98, 13,  0,  0 },
+    { 5120, 3318, 142, 45, 62,  0 },
+    { 5280, 3528,  72, 52,  0,  0 },
+    { 5344, 3516, 142, 51,  0,  0 },
+    { 5344, 3584, 126,100,  0,  2 },
+    { 5360, 3516, 158, 51,  0,  0 },
+    { 5568, 3708,  72, 38,  0,  0 },
+    { 5632, 3710,  96, 17,  0,  0, 0, 16, 0, 0, 0x49 },
+    { 5712, 3774,  62, 20, 10,  2 },
+    { 5792, 3804, 158, 51,  0,  0 },
+    { 5920, 3950, 122, 80,  2,  0 },
+  };
+  static const struct {
+    ushort id;
+    char t_model[20];
+  } unique[] = {
+    { 0x001, "EOS-1D" },
+    { 0x167, "EOS-1DS" },
+    { 0x168, "EOS 10D" },
+    { 0x169, "EOS-1D Mark III" },
+    { 0x170, "EOS 300D" },
+    { 0x174, "EOS-1D Mark II" },
+    { 0x175, "EOS 20D" },
+    { 0x176, "EOS 450D" },
+    { 0x188, "EOS-1Ds Mark II" },
+    { 0x189, "EOS 350D" },
+    { 0x190, "EOS 40D" },
+    { 0x213, "EOS 5D" },
+    { 0x215, "EOS-1Ds Mark III" },
+    { 0x218, "EOS 5D Mark II" },
+    { 0x232, "EOS-1D Mark II N" },
+    { 0x234, "EOS 30D" },
+    { 0x236, "EOS 400D" },
+    { 0x250, "EOS 7D" },
+    { 0x252, "EOS 500D" },
+    { 0x254, "EOS 1000D" },
+    { 0x261, "EOS 50D" },
+    { 0x269, "EOS-1D X" },
+    { 0x270, "EOS 550D" },
+    { 0x281, "EOS-1D Mark IV" },
+    { 0x285, "EOS 5D Mark III" },
+    { 0x286, "EOS 600D" },
+    { 0x287, "EOS 60D" },
+    { 0x288, "EOS 1100D" },
+    { 0x289, "EOS 7D Mark II" },
+    { 0x301, "EOS 650D" },
+    { 0x302, "EOS 6D" },
+    { 0x324, "EOS-1D C" },
+    { 0x325, "EOS 70D" },
+    { 0x326, "EOS 700D" },
+    { 0x327, "EOS 1200D" },
+    { 0x331, "EOS M" },
+    { 0x335, "EOS M2" },
+    { 0x346, "EOS 100D" },
+    { 0x347, "EOS 760D" },
+    { 0x382, "EOS 5DS" },
+    { 0x393, "EOS 750D" },
+    { 0x401, "EOS 5DS R" },
+  }, sonique[] = {
+    { 0x002, "DSC-R1" },     { 0x100, "DSLR-A100" },
+    { 0x101, "DSLR-A900" },  { 0x102, "DSLR-A700" },
+    { 0x103, "DSLR-A200" },  { 0x104, "DSLR-A350" },
+    { 0x105, "DSLR-A300" },
+    {262,"DSLR-A900"},
+    {263,"DSLR-A380"},
+    { 0x108, "DSLR-A330" },
+    { 0x109, "DSLR-A230" },  { 0x10a, "DSLR-A290" },
+    { 0x10d, "DSLR-A850" },
+    {270,"DSLR-A850"},
+    { 0x111, "DSLR-A550" },
+    { 0x112, "DSLR-A500" },  { 0x113, "DSLR-A450" },
+    { 0x116, "NEX-5" },      { 0x117, "NEX-3" },
+    { 0x118, "SLT-A33" },    { 0x119, "SLT-A55V" },
+    { 0x11a, "DSLR-A560" },  { 0x11b, "DSLR-A580" },
+    { 0x11c, "NEX-C3" },     { 0x11d, "SLT-A35" },
+    { 0x11e, "SLT-A65V" },   { 0x11f, "SLT-A77V" },
+    { 0x120, "NEX-5N" },     { 0x121, "NEX-7" },
+    {290,"NEX-VG20E"},
+    { 0x123, "SLT-A37" },    { 0x124, "SLT-A57" },
+    { 0x125, "NEX-F3" },     { 0x126, "SLT-A99V" },
+    { 0x127, "NEX-6" },      { 0x128, "NEX-5R" },
+    { 0x129, "DSC-RX100" },  { 0x12a, "DSC-RX1" },
+    {299,"NEX-VG900"},
+    {300,"NEX-VG30E"},
+    { 0x12e, "ILCE-3000" },  { 0x12f, "SLT-A58" },
+    { 0x131, "NEX-3N" },     { 0x132, "ILCE-7" },
+    { 0x133, "NEX-5T" },     { 0x134, "DSC-RX100M2" },
+    { 0x135, "DSC-RX10" },   { 0x136, "DSC-RX1R" },
+    { 0x137, "ILCE-7R" },    { 0x138, "ILCE-6000" },
+    { 0x139, "ILCE-5000" },  { 0x13d, "DSC-RX100M3" },
+    { 0x13e, "ILCE-7S" },    { 0x13f, "ILCA-77M2" },
+    { 0x153, "ILCE-5100" },  { 0x154, "ILCE-7M2" },
+    { 0x15a, "ILCE-QX1" },
+  };
+
   static const struct {
-    int fsize;
-    char t_make[12], t_model[19], withjpeg;
+    unsigned fsize;
+    ushort rw, rh;
+    uchar lm, tm, rm, bm, lf, cf, max, flags;
+    char t_make[10], t_model[20];
+    ushort offset;
   } table[] = {
-    {    62464, "Kodak",    "DC20"            ,0 },
-    {   124928, "Kodak",    "DC20"            ,0 },
-    {  1652736, "Kodak",    "DCS200"          ,0 },
-    {  4159302, "Kodak",    "C330"            ,0 },
-    {  4162462, "Kodak",    "C330"            ,0 },
-    {   460800, "Kodak",    "C603v"           ,0 },
-    {   614400, "Kodak",    "C603v"           ,0 },
-    {  6163328, "Kodak",    "C603"            ,0 },
-    {  6166488, "Kodak",    "C603"            ,0 },
-    {  9116448, "Kodak",    "C603y"           ,0 },
-    {   311696, "ST Micro", "STV680 VGA"      ,0 },  /* SPYz */
-    {   787456, "Creative", "PC-CAM 600"      ,0 },
-    {  1138688, "Minolta",  "RD175"           ,0 },
-    {  3840000, "Foculus",  "531C"            ,0 },
-    {   307200, "Generic",  "640x480"         ,0 },
-    {   786432, "AVT",      "F-080C"          ,0 },
-    {  1447680, "AVT",      "F-145C"          ,0 },
-    {  1920000, "AVT",      "F-201C"          ,0 },
-    {  5067304, "AVT",      "F-510C"          ,0 },
-    {  5067316, "AVT",      "F-510C"          ,0 },
-    { 10134608, "AVT",      "F-510C"          ,0 },
-    { 10134620, "AVT",      "F-510C"          ,0 },
-    { 16157136, "AVT",      "F-810C"          ,0 },
-    {  1409024, "Sony",     "XCD-SX910CR"     ,0 },
-    {  2818048, "Sony",     "XCD-SX910CR"     ,0 },
-    {  3884928, "Micron",   "2010"            ,0 },
-    {  6624000, "Pixelink", "A782"            ,0 },
-    { 13248000, "Pixelink", "A782"            ,0 },
-    {  6291456, "RoverShot","3320AF"          ,0 },
-    {  6553440, "Canon",    "PowerShot A460"  ,0 },
-    {  6653280, "Canon",    "PowerShot A530"  ,0 },
-    {  6573120, "Canon",    "PowerShot A610"  ,0 },
-    {  9219600, "Canon",    "PowerShot A620"  ,0 },
-    {  9243240, "Canon",    "PowerShot A470"  ,0 },
-    { 10341600, "Canon",    "PowerShot A720 IS",0 },
-    { 10383120, "Canon",    "PowerShot A630"  ,0 },
-    { 12945240, "Canon",    "PowerShot A640"  ,0 },
-    { 15636240, "Canon",    "PowerShot A650"  ,0 },
-    {  5298000, "Canon",    "PowerShot SD300" ,0 },
-    {  7710960, "Canon",    "PowerShot S3 IS" ,0 },
-    { 15467760, "Canon",    "PowerShot SX110 IS",0 },
-    { 15534576, "Canon",    "PowerShot SX120 IS",0 },
-    { 18653760, "Canon",    "PowerShot SX20 IS",0 },
-    { 19131120, "Canon",    "PowerShot SX220 HS",0 },
-    { 21936096, "Canon",    "PowerShot SX30 IS",0 },
-    {  5939200, "OLYMPUS",  "C770UZ"          ,0 },
-    {  1581060, "NIKON",    "E900"            ,1 },  /* or E900s,E910 */
-    {  2465792, "NIKON",    "E950"            ,1 },  /* or E800,E700 */
-    {  2940928, "NIKON",    "E2100"           ,1 },  /* or E2500 */
-    {  4771840, "NIKON",    "E990"            ,1 },  /* or E995, Oly C3030Z */
-    {  4775936, "NIKON",    "E3700"           ,1 },  /* or Optio 33WR */
-    {  5869568, "NIKON",    "E4300"           ,1 },  /* or DiMAGE Z2 */
-    {  5865472, "NIKON",    "E4500"           ,1 },
-    {  7438336, "NIKON",    "E5000"           ,1 },  /* or E5700 */
-    {  8998912, "NIKON",    "COOLPIX S6"      ,1 },
-    {  1976352, "CASIO",    "QV-2000UX"       ,1 },
-    {  3217760, "CASIO",    "QV-3*00EX"       ,1 },
-    {  6218368, "CASIO",    "QV-5700"         ,1 },
-    {  6054400, "CASIO",    "QV-R41"          ,1 },
-    {  7530816, "CASIO",    "QV-R51"          ,1 },
-    {  7684000, "CASIO",    "QV-4000"         ,1 },
-    {  2937856, "CASIO",    "EX-S20"          ,1 },
-    {  4948608, "CASIO",    "EX-S100"         ,1 },
-    {  7542528, "CASIO",    "EX-Z50"          ,1 },
-    {  7562048, "CASIO",    "EX-Z500"         ,1 },
-    {  7753344, "CASIO",    "EX-Z55"          ,1 },
-    {  7816704, "CASIO",    "EX-Z60"          ,1 },
-    { 10843712, "CASIO",    "EX-Z75"          ,1 },
-    { 10834368, "CASIO",    "EX-Z750"         ,1 },
-    { 12310144, "CASIO",    "EX-Z850"         ,1 },
-    { 12489984, "CASIO",    "EX-Z8"           ,1 },
-    { 15499264, "CASIO",    "EX-Z1050"        ,1 },
-    {  7426656, "CASIO",    "EX-P505"         ,1 },
-    {  9313536, "CASIO",    "EX-P600"         ,1 },
-    { 10979200, "CASIO",    "EX-P700"         ,1 },
-    {  3178560, "PENTAX",   "Optio S"         ,1 },
-    {  4841984, "PENTAX",   "Optio S"         ,1 },
-    {  6114240, "PENTAX",   "Optio S4"        ,1 },  /* or S4i, CASIO EX-Z4 */
-    { 10702848, "PENTAX",   "Optio 750Z"      ,1 },
-    { 15980544, "AGFAPHOTO","DC-833m"         ,1 },
-    { 16098048, "SAMSUNG",  "S85"             ,1 },
-    { 16215552, "SAMSUNG",  "S85"             ,1 },
-    { 20487168, "SAMSUNG",  "WB550"           ,1 },
-    { 24000000, "SAMSUNG",  "WB550"           ,1 },
-    { 9994240, "ptGrey", "GRAS-50S5C" ,0 }, // KC: SUPPORT GRASSHOPPER
-    { 10075968, "JaiPulnix","BB-500CL" ,0 }, // KC: SUPPORT BB-500CL
-    { 10108896, "JaiPulnix","BB-500GE" ,0 }, // KC: SUPPORT BB-500GE
-    { 10036800, "SVS", "SVS625CL" ,0 }, // KC: SUPPORT SVS625 cameralink
-    { 12582980, "Sinar",    ""                ,0 },
-    { 33292868, "Sinar",    ""                ,0 },
-    { 44390468, "Sinar",    ""                ,0 } };
+    {   786432,1024, 768, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-080C" },
+    {  1447680,1392,1040, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-145C" },
+    {  1920000,1600,1200, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-201C" },
+    {  5067304,2588,1958, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-510C" },
+    {  5067316,2588,1958, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-510C",12 },
+    { 10134608,2588,1958, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-510C" },
+    { 10134620,2588,1958, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-510C",12 },
+    { 16157136,3272,2469, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-810C" },
+    { 15980544,3264,2448, 0, 0, 0, 0, 8,0x61,0,1,"AgfaPhoto","DC-833m" },
+    {  9631728,2532,1902, 0, 0, 0, 0,96,0x61,0,0,"Alcatel","5035D" },
+
+//   Android Raw dumps id start
+//   File Size in bytes Horizontal Res Vertical Flag then bayer order eg 0x16 bbgr 0x94 rggb
+    { 16424960,4208,3120, 0, 0, 0, 0, 1,0x16,0,0,"Sony","IMX135-mipi 13mp" },
+    { 17522688,4212,3120, 0, 0, 0, 0, 0,0x16,0,0,"Sony","IMX135-QCOM" },
+    { 10223360,2608,1960, 0, 0, 0, 0, 1,0x94,0,0,"Sony","IMX072-mipi" },
+    { 5107712,2688,1520, 0, 0, 0, 0, 1,0x61,0,0,"HTC","UltraPixel" },
+    { 1540857,2688,1520, 0, 0, 0, 0, 1,0x61,0,0,"Samsung","S3" },
+    { 10223363,2688,1520, 0, 0, 0, 0, 1,0x61,0,0,"Samsung","GalaxyNexus" },
+    //   Android Raw dumps id end
+
+    {  2868726,1384,1036, 0, 0, 0, 0,64,0x49,0,8,"Baumer","TXG14",1078 },
+    {  5298000,2400,1766,12,12,44, 2,40,0x94,0,2,"Canon","PowerShot SD300" },
+    {  6553440,2664,1968, 4, 4,44, 4,40,0x94,0,2,"Canon","PowerShot A460" },
+    {  6573120,2672,1968,12, 8,44, 0,40,0x94,0,2,"Canon","PowerShot A610" },
+    {  6653280,2672,1992,10, 6,42, 2,40,0x94,0,2,"Canon","PowerShot A530" },
+    {  7710960,2888,2136,44, 8, 4, 0,40,0x94,0,2,"Canon","PowerShot S3 IS" },
+    {  9219600,3152,2340,36,12, 4, 0,40,0x94,0,2,"Canon","PowerShot A620" },
+    {  9243240,3152,2346,12, 7,44,13,40,0x49,0,2,"Canon","PowerShot A470" },
+    { 10341600,3336,2480, 6, 5,32, 3,40,0x94,0,2,"Canon","PowerShot A720 IS" },
+    { 10383120,3344,2484,12, 6,44, 6,40,0x94,0,2,"Canon","PowerShot A630" },
+    { 12945240,3736,2772,12, 6,52, 6,40,0x94,0,2,"Canon","PowerShot A640" },
+    { 15636240,4104,3048,48,12,24,12,40,0x94,0,2,"Canon","PowerShot A650" },
+    { 15467760,3720,2772, 6,12,30, 0,40,0x94,0,2,"Canon","PowerShot SX110 IS" },
+    { 15534576,3728,2778,12, 9,44, 9,40,0x94,0,2,"Canon","PowerShot SX120 IS" },
+    { 18653760,4080,3048,24,12,24,12,40,0x94,0,2,"Canon","PowerShot SX20 IS" },
+    { 19131120,4168,3060,92,16, 4, 1,40,0x94,0,2,"Canon","PowerShot SX220 HS" },
+    { 21936096,4464,3276,25,10,73,12,40,0x16,0,2,"Canon","PowerShot SX30 IS" },
+    { 24724224,4704,3504, 8,16,56, 8,40,0x49,0,2,"Canon","PowerShot A3300 IS" },
+    {  1976352,1632,1211, 0, 2, 0, 1, 0,0x94,0,1,"Casio","QV-2000UX" },
+    {  3217760,2080,1547, 0, 0,10, 1, 0,0x94,0,1,"Casio","QV-3*00EX" },
+    {  6218368,2585,1924, 0, 0, 9, 0, 0,0x94,0,1,"Casio","QV-5700" },
+    {  7816704,2867,2181, 0, 0,34,36, 0,0x16,0,1,"Casio","EX-Z60" },
+    {  2937856,1621,1208, 0, 0, 1, 0, 0,0x94,7,13,"Casio","EX-S20" },
+    {  4948608,2090,1578, 0, 0,32,34, 0,0x94,7,1,"Casio","EX-S100" },
+    {  6054400,2346,1720, 2, 0,32, 0, 0,0x94,7,1,"Casio","QV-R41" },
+    {  7426656,2568,1928, 0, 0, 0, 0, 0,0x94,0,1,"Casio","EX-P505" },
+    {  7530816,2602,1929, 0, 0,22, 0, 0,0x94,7,1,"Casio","QV-R51" },
+    {  7542528,2602,1932, 0, 0,32, 0, 0,0x94,7,1,"Casio","EX-Z50" },
+    {  7562048,2602,1937, 0, 0,25, 0, 0,0x16,7,1,"Casio","EX-Z500" },
+    {  7753344,2602,1986, 0, 0,32,26, 0,0x94,7,1,"Casio","EX-Z55" },
+    {  9313536,2858,2172, 0, 0,14,30, 0,0x94,7,1,"Casio","EX-P600" },
+    { 10834368,3114,2319, 0, 0,27, 0, 0,0x94,0,1,"Casio","EX-Z750" },
+    { 10843712,3114,2321, 0, 0,25, 0, 0,0x94,0,1,"Casio","EX-Z75" },
+    { 10979200,3114,2350, 0, 0,32,32, 0,0x94,7,1,"Casio","EX-P700" },
+    { 12310144,3285,2498, 0, 0, 6,30, 0,0x94,0,1,"Casio","EX-Z850" },
+    { 12489984,3328,2502, 0, 0,47,35, 0,0x94,0,1,"Casio","EX-Z8" },
+    { 15499264,3754,2752, 0, 0,82, 0, 0,0x94,0,1,"Casio","EX-Z1050" },
+    { 18702336,4096,3044, 0, 0,24, 0,80,0x94,7,1,"Casio","EX-ZR100" },
+    {  7684000,2260,1700, 0, 0, 0, 0,13,0x94,0,1,"Casio","QV-4000" },
+    {   787456,1024, 769, 0, 1, 0, 0, 0,0x49,0,0,"Creative","PC-CAM 600" },
+    { 28829184,4384,3288, 0, 0, 0, 0,36,0x61,0,0,"DJI" },
+    { 15151104,4608,3288, 0, 0, 0, 0, 0,0x94,0,0,"Matrix" },
+    {  3840000,1600,1200, 0, 0, 0, 0,65,0x49,0,0,"Foculus","531C" },
+    {   307200, 640, 480, 0, 0, 0, 0, 0,0x94,0,0,"Generic" },
+    {    62464, 256, 244, 1, 1, 6, 1, 0,0x8d,0,0,"Kodak","DC20" },
+    {   124928, 512, 244, 1, 1,10, 1, 0,0x8d,0,0,"Kodak","DC20" },
+    {  1652736,1536,1076, 0,52, 0, 0, 0,0x61,0,0,"Kodak","DCS200" },
+    {  4159302,2338,1779, 1,33, 1, 2, 0,0x94,0,0,"Kodak","C330" },
+    {  4162462,2338,1779, 1,33, 1, 2, 0,0x94,0,0,"Kodak","C330",3160 },
+    {  2247168,1232, 912, 0, 0,16, 0, 0,0x00,0,0,"Kodak","C330" },
+    {  3370752,1232, 912, 0, 0,16, 0, 0,0x00,0,0,"Kodak","C330" },
+    {  6163328,2864,2152, 0, 0, 0, 0, 0,0x94,0,0,"Kodak","C603" },
+    {  6166488,2864,2152, 0, 0, 0, 0, 0,0x94,0,0,"Kodak","C603",3160 },
+    {   460800, 640, 480, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","C603" },
+    {  9116448,2848,2134, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","C603" },
+    { 12241200,4040,3030, 2, 0, 0,13, 0,0x49,0,0,"Kodak","12MP" },
+    { 12272756,4040,3030, 2, 0, 0,13, 0,0x49,0,0,"Kodak","12MP",31556 },
+    { 18000000,4000,3000, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","12MP" },
+    {   614400, 640, 480, 0, 3, 0, 0,64,0x94,0,0,"Kodak","KAI-0340" },
+    { 15360000,3200,2400, 0, 0, 0, 0,96,0x16,0,0,"Lenovo","A820" },
+    {  3884928,1608,1207, 0, 0, 0, 0,96,0x16,0,0,"Micron","2010",3212 },
+    {  1138688,1534, 986, 0, 0, 0, 0, 0,0x61,0,0,"Minolta","RD175",513 },
+    {  1581060,1305, 969, 0, 0,18, 6, 6,0x1e,4,1,"Nikon","E900" },
+    {  2465792,1638,1204, 0, 0,22, 1, 6,0x4b,5,1,"Nikon","E950" },
+    {  2940928,1616,1213, 0, 0, 0, 7,30,0x94,0,1,"Nikon","E2100" },
+    {  4771840,2064,1541, 0, 0, 0, 1, 6,0xe1,0,1,"Nikon","E990" },
+    {  4775936,2064,1542, 0, 0, 0, 0,30,0x94,0,1,"Nikon","E3700" },
+    {  5865472,2288,1709, 0, 0, 0, 1, 6,0xb4,0,1,"Nikon","E4500" },
+    {  5869568,2288,1710, 0, 0, 0, 0, 6,0x16,0,1,"Nikon","E4300" },
+    {  7438336,2576,1925, 0, 0, 0, 1, 6,0xb4,0,1,"Nikon","E5000" },
+    {  8998912,2832,2118, 0, 0, 0, 0,30,0x94,7,1,"Nikon","COOLPIX S6" },
+    {  5939200,2304,1718, 0, 0, 0, 0,30,0x16,0,0,"Olympus","C770UZ" },
+    {  3178560,2064,1540, 0, 0, 0, 0, 0,0x94,0,1,"Pentax","Optio S" },
+    {  4841984,2090,1544, 0, 0,22, 0, 0,0x94,7,1,"Pentax","Optio S" },
+    {  6114240,2346,1737, 0, 0,22, 0, 0,0x94,7,1,"Pentax","Optio S4" },
+    { 10702848,3072,2322, 0, 0, 0,21,30,0x94,0,1,"Pentax","Optio 750Z" },
+    { 13248000,2208,3000, 0, 0, 0, 0,13,0x61,0,0,"Pixelink","A782" },
+    {  6291456,2048,1536, 0, 0, 0, 0,96,0x61,0,0,"RoverShot","3320AF" },
+    {   311696, 644, 484, 0, 0, 0, 0, 0,0x16,0,8,"ST Micro","STV680 VGA" },
+    { 16098048,3288,2448, 0, 0,24, 0, 9,0x94,0,1,"Samsung","S85" },
+    { 16215552,3312,2448, 0, 0,48, 0, 9,0x94,0,1,"Samsung","S85" },
+    { 20487168,3648,2808, 0, 0, 0, 0,13,0x94,5,1,"Samsung","WB550" },
+    { 24000000,4000,3000, 0, 0, 0, 0,13,0x94,5,1,"Samsung","WB550" },
+    { 12582980,3072,2048, 0, 0, 0, 0,33,0x61,0,0,"Sinar","",68 },
+    { 33292868,4080,4080, 0, 0, 0, 0,33,0x61,0,0,"Sinar","",68 },
+    { 44390468,4080,5440, 0, 0, 0, 0,33,0x61,0,0,"Sinar","",68 },
+    {  1409024,1376,1024, 0, 0, 1, 0, 0,0x49,0,0,"Sony","XCD-SX910CR" },
+    {  2818048,1376,1024, 0, 0, 1, 0,97,0x49,0,0,"Sony","XCD-SX910CR" },
+  };
   static const char *corp[] =
-    { "Canon", "NIKON", "EPSON", "KODAK", "Kodak", "OLYMPUS", "PENTAX",
-      "MINOLTA", "Minolta", "Konica", "CASIO", "Sinar", "Phase One",
-      "SAMSUNG", "Mamiya", "MOTOROLA", "LEICA" };
-
-#ifdef LIBRAW_LIBRARY_BUILD
-  RUN_CALLBACK(LIBRAW_PROGRESS_IDENTIFY,0,2);
-#endif
+    { "AgfaPhoto", "Canon", "Casio", "Epson", "Fujifilm",
+      "Mamiya", "Minolta", "Motorola", "Kodak", "Konica", "Leica",
+      "Nikon", "Nokia", "Olympus", "Pentax", "Phase One", "Ricoh",
+      "Samsung", "Sigma", "Sinar", "Sony" };
+  char head[32], *cp;
+  int hlen, flen, fsize, zero_fsize=1, i, c;
+  struct jhead jh;
 
-  tiff_flip = flip = filters = -1;	/* 0 is valid, so -1 is unknown */
+  tiff_flip = flip = filters = UINT_MAX;	/* unknown */
   raw_height = raw_width = fuji_width = fuji_layout = cr2_slice[0] = 0;
   maximum = height = width = top_margin = left_margin = 0;
   cdesc[0] = desc[0] = artist[0] = make[0] = model[0] = model2[0] = 0;
@@ -7503,32 +11926,26 @@ void CLASS identify()
   memset (gpsdata, 0, sizeof gpsdata);
   memset (cblack, 0, sizeof cblack);
   memset (white, 0, sizeof white);
+  memset (mask, 0, sizeof mask);
   thumb_offset = thumb_length = thumb_width = thumb_height = 0;
   load_raw = thumb_load_raw = 0;
   write_thumb = &CLASS jpeg_thumb;
-  data_offset = meta_length = tiff_bps = tiff_compress = 0;
+  data_offset = meta_offset = meta_length = tiff_bps = tiff_compress = 0;
   kodak_cbpp = zero_after_ff = dng_version = load_flags = 0;
-  timestamp = shot_order = tiff_samples = black =  is_foveon = 0;
+  timestamp = shot_order = tiff_samples = black = is_foveon = 0;
   mix_green = profile_length = data_error = zero_is_bad = 0;
   pixel_aspect = is_raw = raw_color = 1;
-  tile_width = tile_length = INT_MAX;
+  tile_width = tile_length = 0;
+
+
   for (i=0; i < 4; i++) {
     cam_mul[i] = i == 1;
     pre_mul[i] = i < 3;
     FORC3 cmatrix[c][i] = 0;
     FORC3 rgb_cam[c][i] = c == i;
   }
-#ifdef LIBRAW_LIBRARY_BUILD
-  color_flags.cmatrix_state = LIBRAW_COLORSTATE_INIT;
-  color_flags.rgb_cam_state = LIBRAW_COLORSTATE_INIT;
-  color_flags.pre_mul_state = LIBRAW_COLORSTATE_INIT;
-  color_flags.cam_mul_state = LIBRAW_COLORSTATE_INIT;
-#endif
   colors = 3;
-  for (i=0; i < 0x4000; i++) curve[i] = i;
-#ifdef LIBRAW_LIBRARY_BUILD
-  color_flags.curve_state = LIBRAW_COLORSTATE_INIT;
-#endif
+  for (i=0; i < 0x10000; i++) curve[i] = i;
 
   order = get2();
   hlen = get4();
@@ -7543,7 +11960,12 @@ void CLASS identify()
   } else if (order == 0x4949 || order == 0x4d4d) {
     if (!memcmp (head+6,"HEAPCCDR",8)) {
       data_offset = hlen;
-      parse_ciff (hlen, flen - hlen);
+#ifdef LIBRAW_LIBRARY_BUILD
+      imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_FixedLens;
+      imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_FixedLens;
+#endif
+      parse_ciff (hlen, flen-hlen, 0);
+      load_raw = &CLASS canon_load_raw;
     } else if (parse_tiff(0)) apply_tiff();
   } else if (!memcmp (head,"\xff\xd8\xff\xe1",4) &&
 	     !memcmp (head+6,"Exif",4)) {
@@ -7558,10 +11980,36 @@ void CLASS identify()
     strcpy (model,"N Digital");
     fseek (ifp, 33, SEEK_SET);
     get_timestamp(1);
-    fseek (ifp, 60, SEEK_SET);
+    fseek (ifp, 52, SEEK_SET);
+    switch (get4()) {
+      case  7: iso_speed = 25;  break;
+      case  8: iso_speed = 32;  break;
+      case  9: iso_speed = 40;  break;
+      case 10: iso_speed = 50;  break;
+      case 11: iso_speed = 64;  break;
+      case 12: iso_speed = 80;  break;
+      case 13: iso_speed = 100; break;
+      case 14: iso_speed = 125; break;
+      case 15: iso_speed = 160; break;
+      case 16: iso_speed = 200; break;
+      case 17: iso_speed = 250; break;
+      case 18: iso_speed = 320; break;
+      case 19: iso_speed = 400; break;
+    }
+    shutter = powf64(2.0f, (((float)get4())/8.0f)) / 16000.0f;
     FORC4 cam_mul[c ^ (c >> 1)] = get4();
-#ifdef LIBRAW_LIBRARY_BUILD
-    color_flags.cam_mul_state = LIBRAW_COLORSTATE_LOADED;
+    fseek (ifp, 88, SEEK_SET);
+    aperture = powf64(2.0f, ((float)get4())/16.0f);
+    fseek (ifp, 112, SEEK_SET);
+    focal_len = get4();
+#ifdef LIBRAW_LIBRARY_BUILD
+    fseek (ifp, 104, SEEK_SET);
+    imgdata.lens.makernotes.MaxAp4CurFocal = powf64(2.0f, ((float)get4())/16.0f);
+    fseek (ifp, 124, SEEK_SET);
+    fread(imgdata.lens.makernotes.Lens, 32, 1, ifp);
+    imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Contax_N;
+    if (imgdata.lens.makernotes.Lens[0])
+      imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Contax_N;
 #endif
   } else if (!strcmp (head, "PXN")) {
     strcpy (make, "Logitech");
@@ -7586,7 +12034,7 @@ void CLASS identify()
       if (is_raw == 2 && shot_select)
 	parse_fuji (i);
     }
-//    load_raw = &CLASS unpacked_load_raw;
+    load_raw = &CLASS unpacked_load_raw;
     fseek (ifp, 100+28*(shot_select > 0), SEEK_SET);
     parse_tiff (data_offset = get4());
     parse_tiff (thumb_offset+12);
@@ -7594,6 +12042,10 @@ void CLASS identify()
   } else if (!memcmp (head,"RIFF",4)) {
     fseek (ifp, 0, SEEK_SET);
     parse_riff();
+  } else if (!memcmp (head+4,"ftypqt   ",9)) {
+    fseek (ifp, 0, SEEK_SET);
+    parse_qt (fsize);
+    is_raw = 0;
   } else if (!memcmp (head,"\0\001\0\001\0@",6)) {
     fseek (ifp, 6, SEEK_SET);
     fread (make, 1, 8, ifp);
@@ -7607,15 +12059,18 @@ void CLASS identify()
     filters = 0x61616161;
   } else if (!memcmp (head,"NOKIARAW",8)) {
     strcpy (make, "NOKIA");
-    strcpy (model, "X2");
     order = 0x4949;
     fseek (ifp, 300, SEEK_SET);
     data_offset = get4();
     i = get4();
     width = get2();
     height = get2();
-    data_offset += i - width * 5 / 4 * height;
-    load_raw = &CLASS nokia_load_raw;
+    switch (tiff_bps = i*8 / (width * height)) {
+      case  8: load_raw = &CLASS eight_bit_load_raw;  break;
+      case 10: load_raw = &CLASS nokia_load_raw;
+    }
+    raw_height = height + (top_margin = i / (width * tiff_bps/8) - height);
+    mask[0][3] = 1;
     filters = 0x61616161;
   } else if (!memcmp (head,"ARRI",4)) {
     order = 0x4949;
@@ -7629,9 +12084,20 @@ void CLASS identify()
     load_raw = &CLASS packed_load_raw;
     load_flags = 88;
     filters = 0x61616161;
+  } else if (!memcmp (head,"XPDS",4)) {
+    order = 0x4949;
+    fseek (ifp, 0x800, SEEK_SET);
+    fread (make, 1, 41, ifp);
+    raw_height = get2();
+    raw_width  = get2();
+    fseek (ifp, 56, SEEK_CUR);
+    fread (model, 1, 30, ifp);
+    data_offset = 0x10000;
+    load_raw = &CLASS canon_rmf_load_raw;
+    gamma_curve (0, 12.25, 1, 1023);
   } else if (!memcmp (head+4,"RED1",4)) {
-    strcpy (make, "RED");
-    strcpy (model,"ONE");
+    strcpy (make, "Red");
+    strcpy (model,"One");
     parse_redcine();
     load_raw = &CLASS redcine_load_raw;
     gamma_curve (1/2.4, 12.92, 1, 4095);
@@ -7643,36 +12109,97 @@ void CLASS identify()
   else if (!memcmp (head,"\0MRM",4))
     parse_minolta(0);
   else if (!memcmp (head,"FOVb",4))
-      {
-          parse_foveon();
-          if(!strcasecmp(make,"SIGMA") && !strncasecmp(model,"SIGMA DP",8))
-              {
-                  make[0] = model[0] = 0;
-                  is_foveon = 0;
-              }
-      }
+    {
+#ifdef LIBRAW_LIBRARY_BUILD
+#ifdef  LIBRAW_DEMOSAIC_PACK_GPL2
+      if(!imgdata.params.force_foveon_x3f)
+        parse_foveon();
+      else
+#endif
+        parse_x3f();
+#else
+#ifdef  LIBRAW_DEMOSAIC_PACK_GPL2
+      parse_foveon();
+#endif
+#endif
+    }
   else if (!memcmp (head,"CI",2))
     parse_cine();
   else
     for (zero_fsize=i=0; i < sizeof table / sizeof *table; i++)
       if (fsize == table[i].fsize) {
 	strcpy (make,  table[i].t_make );
+#ifdef LIBRAW_LIBRARY_BUILD
+        if (!strcmp(make, "Canon"))
+          {
+            imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_FixedLens;
+            imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_FixedLens;
+          }
+#endif
 	strcpy (model, table[i].t_model);
-	if (table[i].withjpeg)
+	flip = table[i].flags >> 2;
+	zero_is_bad = table[i].flags & 2;
+	if (table[i].flags & 1)
 	  parse_external_jpeg();
+	data_offset = table[i].offset;
+	raw_width   = table[i].rw;
+	raw_height  = table[i].rh;
+	left_margin = table[i].lm;
+	 top_margin = table[i].tm;
+	width  = raw_width - left_margin - table[i].rm;
+	height = raw_height - top_margin - table[i].bm;
+	filters = 0x1010101 * table[i].cf;
+	colors = 4 - !((filters & filters >> 1) & 0x5555);
+	load_flags = table[i].lf;
+	switch (tiff_bps = (fsize-data_offset)*8 / (raw_width*raw_height)) {
+	  case 6:
+	    load_raw = &CLASS minolta_rd175_load_raw;  break;
+	  case 8:
+	    load_raw = &CLASS eight_bit_load_raw;  break;
+	  case 10:
+           if ((fsize-data_offset)/raw_height*3 >= raw_width*4) {
+             load_raw = &CLASS android_loose_load_raw;  break;
+           } else if (load_flags & 1) {
+             load_raw = &CLASS android_tight_load_raw;  break;
+           }
+	  case 12:
+	    load_flags |= 128;
+	    load_raw = &CLASS packed_load_raw;     break;
+	  case 16:
+	    order = 0x4949 | 0x404 * (load_flags & 1);
+	    tiff_bps -= load_flags >> 4;
+	    tiff_bps -= load_flags = load_flags >> 1 & 7;
+	    load_raw = &CLASS unpacked_load_raw;
+	}
+	maximum = (1 << tiff_bps) - (1 << table[i].max);
       }
   if (zero_fsize) fsize = 0;
   if (make[0] == 0) parse_smal (0, flen);
-  if (make[0] == 0) parse_jpeg (is_raw = 0);
+  if (make[0] == 0) {
+    parse_jpeg(0);
+    fseek(ifp,0,SEEK_END);
+    int sz = ftell(ifp);
+    if (!(strncmp(model,"ov",2) && strncmp(model,"RP_OV",5)) && sz>=6404096 &&
+        !fseek (ifp, -6404096, SEEK_END) &&
+	fread (head, 1, 32, ifp) && !strcmp(head,"BRCMn")) {
+      strcpy (make, "OmniVision");
+      data_offset = ftell(ifp) + 0x8000-32;
+      width = raw_width;
+      raw_width = 2611;
+      load_raw = &CLASS nokia_load_raw;
+      filters = 0x16161616;
+    } else is_raw = 0;
+  }
 
   for (i=0; i < sizeof corp / sizeof *corp; i++)
-    if (strstr (make, corp[i]))		/* Simplify company names */
-	strcpy (make, corp[i]);
-  if (!strncmp (make,"KODAK",5) &&
-	((cp = strstr(model," DIGITAL CAMERA")) ||
-	 (cp = strstr(model," Digital Camera")) ||
+    if (strcasestr (make, corp[i]))	/* Simplify company names */
+	    strcpy (make, corp[i]);
+  if ((!strcmp(make,"Kodak") || !strcmp(make,"Leica")) &&
+	((cp = strcasestr(model," DIGITAL CAMERA")) ||
 	 (cp = strstr(model,"FILE VERSION"))))
      *cp = 0;
+  if (!strncasecmp(model,"PENTAX",6))
+    strcpy (make, "Pentax");
   cp = make + strlen(make);		/* Remove trailing spaces */
   while (*--cp == ' ') *cp = 0;
   cp = model + strlen(model);
@@ -7689,22 +12216,18 @@ void CLASS identify()
 
   if (!height) height = raw_height;
   if (!width)  width  = raw_width;
-  if (fuji_width) {
-    fuji_width = (raw_width+1)/2;
-    width = height + fuji_width;
-    height = width - 1;
-    pixel_aspect = 1;
-  }
   if (height == 2624 && width == 3936)	/* Pentax K10D and Samsung GX10 */
     { height  = 2616;   width  = 3896; }
   if (height == 3136 && width == 4864)  /* Pentax K20D and Samsung GX20 */
     { height  = 3124;   width  = 4688; filters = 0x16161616; }
   if (width == 4352 && (!strcmp(model,"K-r") || !strcmp(model,"K-x")))
     {			width  = 4309; filters = 0x16161616; }
-  if (width >= 4960 && !strcmp(model,"K-5"))
+  if (width >= 4960 && !strncmp(model,"K-5",3))
     { left_margin = 10; width  = 4950; filters = 0x16161616; }
   if (width == 4736 && !strcmp(model,"K-7"))
     { height  = 3122;   width  = 4684; filters = 0x16161616; top_margin = 2; }
+  if (width == 6080 && !strcmp(model,"K-3"))
+    { left_margin = 4;  width  = 6040; }
   if (width == 7424 && !strcmp(model,"645D"))
     { height  = 5502;   width  = 7328; filters = 0x61616161; top_margin = 29;
       left_margin = 48; }
@@ -7714,45 +12237,109 @@ void CLASS identify()
     if (filters == UINT_MAX) filters = 0;
     if (filters) is_raw = tiff_samples;
     else	 colors = tiff_samples;
-    if (tiff_compress == 1)
-      load_raw = &CLASS adobe_dng_load_raw_nc;
-    if (tiff_compress == 7)
-      load_raw = &CLASS adobe_dng_load_raw_lj;
+    switch (tiff_compress) {
+    case 0:  /* Compression not set, assuming uncompressed */
+      case 1:     load_raw = &CLASS   packed_dng_load_raw;  break;
+      case 7:     load_raw = &CLASS lossless_dng_load_raw;  break;
+      case 34892: load_raw = &CLASS    lossy_dng_load_raw;  break;
+      default:    load_raw = 0;
+    }
+    if (!strcmp(make, "Canon") && unique_id)
+      {
+        for (i = 0; i < sizeof unique / sizeof *unique; i++)
+          if (unique_id == 0x80000000 + unique[i].id)
+            {
+              strcpy(model, unique[i].t_model);
+              break;
+            }
+      }
+    if (!strcasecmp(make, "Sony") && unique_id)
+      {
+        for (i = 0; i < sizeof sonique / sizeof *sonique; i++)
+          if (unique_id == sonique[i].id)
+            {
+              strcpy(model, sonique[i].t_model);
+              break;
+            }
+      }
     goto dng_skip;
   }
-  if ((is_canon = !strcmp(make,"Canon")))
-    load_raw = memcmp (head+6,"HEAPCCDR",8) ?
-	&CLASS lossless_jpeg_load_raw : &CLASS canon_compressed_load_raw;
-  if (!strcmp(make,"NIKON")) {
+  if (!strcmp(make,"Canon") && !fsize && tiff_bps != 15) {
+    if (!load_raw)
+      load_raw = &CLASS lossless_jpeg_load_raw;
+    for (i=0; i < sizeof canon / sizeof *canon; i++)
+      if (raw_width == canon[i][0] && raw_height == canon[i][1]) {
+	width  = raw_width - (left_margin = canon[i][2]);
+	height = raw_height - (top_margin = canon[i][3]);
+	width  -= canon[i][4];
+	height -= canon[i][5];
+	mask[0][1] =  canon[i][6];
+	mask[0][3] = -canon[i][7];
+	mask[1][1] =  canon[i][8];
+	mask[1][3] = -canon[i][9];
+	if (canon[i][10]) filters = canon[i][10] * 0x01010101;
+      }
+    if ((unique_id | 0x20000) == 0x2720000) {
+      left_margin = 8;
+      top_margin = 16;
+    }
+  }
+  if (!strcmp(make,"Canon") && unique_id)
+    {
+      for (i=0; i < sizeof unique / sizeof *unique; i++)
+        if (unique_id == 0x80000000 + unique[i].id)
+          {
+            adobe_coeff ("Canon", unique[i].t_model);
+            strcpy(model,unique[i].t_model);
+          }
+    }
+
+  if (!strcasecmp(make,"Sony") && unique_id)
+    {
+      for (i=0; i < sizeof sonique / sizeof *sonique; i++)
+        if (unique_id == sonique[i].id)
+          {
+            adobe_coeff ("Sony", sonique[i].t_model);
+            strcpy(model,sonique[i].t_model);
+          }
+    }
+
+  if (!strcmp(make,"Nikon")) {
     if (!load_raw)
       load_raw = &CLASS packed_load_raw;
     if (model[0] == 'E')
       load_flags |= !data_offset << 2 | 2;
   }
-  if (!strcmp(make,"CASIO")) {
-    load_raw = &CLASS packed_load_raw;
-    maximum = 0xf7f;
-  }
 
 /* Set parameters based on camera name (for non-DNG files). */
- if (is_foveon) {
+
+  if (!strcmp(model,"KAI-0340")
+	&& find_green (16, 16, 3840, 5120) < 25) {
+    height = 480;
+    top_margin = filters = 0;
+    strcpy (model,"C603");
+  }
+  if (is_foveon) {
     if (height*2 < width) pixel_aspect = 0.5;
     if (height   > width) pixel_aspect = 2;
     filters = 0;
-    load_raw = &CLASS foveon_load_raw;
-    simple_coeff(0);
-  } else if (is_canon && tiff_bps == 15) {
+#ifdef LIBRAW_DEMOSAIC_PACK_GPL2
+    if(!imgdata.params.force_foveon_x3f)
+      simple_coeff(0);
+#endif
+  } else if (!strcmp(make,"Canon") && tiff_bps == 15) {
     switch (width) {
       case 3344: width -= 66;
       case 3872: width -= 6;
     }
+    if (height > width) SWAP(height,width);
     filters = 0;
+    tiff_samples = colors = 3;
     load_raw = &CLASS canon_sraw_load_raw;
   } else if (!strcmp(model,"PowerShot 600")) {
     height = 613;
     width  = 854;
     raw_width = 896;
-    pixel_aspect = 607/628.0;
     colors = 4;
     filters = 0xe1e4e1e4;
     load_raw = &CLASS canon_600_load_raw;
@@ -7762,346 +12349,57 @@ void CLASS identify()
     width  = 960;
     raw_width = 992;
     pixel_aspect = 256/235.0;
-    colors = 4;
     filters = 0x1e4e1e4e;
     goto canon_a5;
   } else if (!strcmp(model,"PowerShot A50")) {
     height =  968;
     width  = 1290;
     raw_width = 1320;
-    colors = 4;
     filters = 0x1b4e4b1e;
     goto canon_a5;
   } else if (!strcmp(model,"PowerShot Pro70")) {
     height = 1024;
     width  = 1552;
-    colors = 4;
     filters = 0x1e4b4e1b;
-    goto canon_a5;
-  } else if (!strcmp(model,"PowerShot SD300")) {
-    height = 1752;
-    width  = 2344;
-    raw_height = 1766;
-    raw_width  = 2400;
-    top_margin  = 12;
-    left_margin = 12;
-    goto canon_a5;
-  } else if (!strcmp(model,"PowerShot A460")) {
-    height = 1960;
-    width  = 2616;
-    raw_height = 1968;
-    raw_width  = 2664;
-    top_margin  = 4;
-    left_margin = 4;
-    goto canon_a5;
-  } else if (!strcmp(model,"PowerShot A530")) {
-    height = 1984;
-    width  = 2620;
-    raw_height = 1992;
-    raw_width  = 2672;
-    top_margin  = 6;
-    left_margin = 10;
-    goto canon_a5;
-  } else if (!strcmp(model,"PowerShot A610")) {
-    if (canon_s2is()) strcpy (model+10, "S2 IS");
-    height = 1960;
-    width  = 2616;
-    raw_height = 1968;
-    raw_width  = 2672;
-    top_margin  = 8;
-    left_margin = 12;
-    goto canon_a5;
-  } else if (!strcmp(model,"PowerShot A620")) {
-    height = 2328;
-    width  = 3112;
-    raw_height = 2340;
-    raw_width  = 3152;
-    top_margin  = 12;
-    left_margin = 36;
-    goto canon_a5;
-  } else if (!strcmp(model,"PowerShot A470")) {
-    height = 2328;
-    width  = 3096;
-    raw_height = 2346;
-    raw_width  = 3152;
-    top_margin  = 6;
-    left_margin = 12;
-    goto canon_a5;
-  } else if (!strcmp(model,"PowerShot A720 IS")) {
-    height = 2472;
-    width  = 3298;
-    raw_height = 2480;
-    raw_width  = 3336;
-    top_margin  = 5;
-    left_margin = 6;
-    goto canon_a5;
-  } else if (!strcmp(model,"PowerShot A630")) {
-    height = 2472;
-    width  = 3288;
-    raw_height = 2484;
-    raw_width  = 3344;
-    top_margin  = 6;
-    left_margin = 12;
-    goto canon_a5;
-  } else if (!strcmp(model,"PowerShot A640")) {
-    height = 2760;
-    width  = 3672;
-    raw_height = 2772;
-    raw_width  = 3736;
-    top_margin  = 6;
-    left_margin = 12;
-    goto canon_a5;
-  } else if (!strcmp(model,"PowerShot A650")) {
-    height = 3024;
-    width  = 4032;
-    raw_height = 3048;
-    raw_width  = 4104;
-    top_margin  = 12;
-    left_margin = 48;
-    goto canon_a5;
-  } else if (!strcmp(model,"PowerShot S3 IS")) {
-    height = 2128;
-    width  = 2840;
-    raw_height = 2136;
-    raw_width  = 2888;
-    top_margin  = 8;
-    left_margin = 44;
 canon_a5:
+    colors = 4;
     tiff_bps = 10;
     load_raw = &CLASS packed_load_raw;
     load_flags = 40;
-    if (raw_width > 1600) zero_is_bad = 1;
-  } else if (!strcmp(model,"PowerShot SX110 IS")) {
-    height = 2760;
-    width  = 3684;
-    raw_height = 2772;
-    raw_width  = 3720;
-    top_margin  = 12;
-    left_margin = 6;
-    load_raw = &CLASS packed_load_raw;
-    load_flags = 40;
-    zero_is_bad = 1;
-  } else if (!strcmp(model,"PowerShot SX120 IS")) {
-    height = 2742;
-    width  = 3664;
-    raw_height = 2778;
-    raw_width  = 3728;
-    top_margin  = 18;
-    left_margin = 16;
-    filters = 0x49494949;
-    load_raw = &CLASS packed_load_raw;
-    load_flags = 40;
-    zero_is_bad = 1;
-  } else if (!strcmp(model,"PowerShot SX20 IS")) {
-    height = 3024;
-    width  = 4032;
-    raw_height = 3048;
-    raw_width  = 4080;
-    top_margin  = 12;
-    left_margin = 24;
-    load_raw = &CLASS packed_load_raw;
-    load_flags = 40;
-    zero_is_bad = 1;
-  } else if (!strcmp(model,"PowerShot SX220 HS")) {
-    height = 3043;
-    width  = 4072;
-    raw_height = 3060;
-    raw_width  = 4168;
-/*
-    mask[0][0] = top_margin = 16;
-    mask[0][2] = top_margin + height;
-    mask[0][3] = left_margin = 92;
-*/
-    load_raw = &CLASS packed_load_raw;
-    load_flags = 8;
-    zero_is_bad = 1;
-  } else if (!strcmp(model,"PowerShot SX30 IS")) {
-    height = 3254;
-    width  = 4366;
-    raw_height = 3276;
-    raw_width  = 4464;
-    top_margin  = 10;
-    left_margin = 25;
-    filters = 0x16161616;
-    load_raw = &CLASS packed_load_raw;
-    load_flags = 40;
-    zero_is_bad = 1;
-  } else if (!strcmp(model,"PowerShot Pro90 IS")) {
-    width  = 1896;
+  } else if (!strcmp(model,"PowerShot Pro90 IS") ||
+	     !strcmp(model,"PowerShot G1")) {
     colors = 4;
     filters = 0xb4b4b4b4;
-  } else if (is_canon && raw_width == 2144) {
-    height = 1550;
-    width  = 2088;
-    top_margin  = 8;
-    left_margin = 4;
-    if (!strcmp(model,"PowerShot G1")) {
-      colors = 4;
-      filters = 0xb4b4b4b4;
-    }
-  } else if (is_canon && raw_width == 2224) {
-    height = 1448;
-    width  = 2176;
-    top_margin  = 6;
-    left_margin = 48;
-  } else if (is_canon && raw_width == 2376) {
-    height = 1720;
-    width  = 2312;
-    top_margin  = 6;
-    left_margin = 12;
-  } else if (is_canon && raw_width == 2672) {
-    height = 1960;
-    width  = 2616;
-    top_margin  = 6;
-    left_margin = 12;
-  } else if (is_canon && raw_width == 3152) {
-    height = 2056;
-    width  = 3088;
-    top_margin  = 12;
-    left_margin = 64;
-    if (unique_id == 0x80000170)
-      adobe_coeff ("Canon","EOS 300D");
-  } else if (is_canon && raw_width == 3160) {
-    height = 2328;
-    width  = 3112;
-    top_margin  = 12;
-    left_margin = 44;
-  } else if (is_canon && raw_width == 3344) {
-    height = 2472;
-    width  = 3288;
-    top_margin  = 6;
-    left_margin = 4;
+  } else if (!strcmp(model,"PowerShot A610")) {
+    if (canon_s2is()) strcpy (model+10, "S2 IS");
+  } else if (!strcmp(model,"PowerShot SX220 HS")) {
+    mask[1][3] = -4;
+    top_margin=16;
+    left_margin = 92;
+  } else if (!strcmp(model,"PowerShot S120")) {
+        raw_width = 4192;
+        raw_height = 3062;
+        width = 4022;
+        height = 3016;
+        mask[0][0] = top_margin = 31;
+        mask[0][2] = top_margin + height;
+        left_margin = 120;
+        mask[0][1] = 23;
+        mask[0][3] = 72;
+  } else if (!strcmp(model,"PowerShot G16")) {
+      mask[0][0] = 0;
+      mask[0][2] = 80;
+      mask[0][1] = 0;
+      mask[0][3] = 16;
+      top_margin = 29;
+      left_margin = 120;
+      width = raw_width-left_margin-48;
+      height = raw_height-top_margin-14;
+  } else if (!strcmp(model,"PowerShot SX50 HS")) {
+    top_margin = 17;
   } else if (!strcmp(model,"EOS D2000C")) {
     filters = 0x61616161;
     black = curve[200];
-  } else if (is_canon && raw_width == 3516) {
-    top_margin  = 14;
-    left_margin = 42;
-    if (unique_id == 0x80000189)
-      adobe_coeff ("Canon","EOS 350D");
-    goto canon_cr2;
-  } else if (is_canon && raw_width == 3596) {
-    top_margin  = 12;
-    left_margin = 74;
-    goto canon_cr2;
-  } else if (is_canon && raw_width == 3744) {
-    height = 2760;
-    width  = 3684;
-    top_margin  = 16;
-    left_margin = 8;
-    if (unique_id > 0x2720000) {
-      top_margin  = 12;
-      left_margin = 52;
-    }
-  } else if (is_canon && raw_width == 3944) {
-    height = 2602;
-    width  = 3908;
-    top_margin  = 18;
-    left_margin = 30;
-  } else if (is_canon && raw_width == 3948) {
-    top_margin  = 18;
-    left_margin = 42;
-    height -= 2;
-    if (unique_id == 0x80000236)
-      adobe_coeff ("Canon","EOS 400D");
-    if (unique_id == 0x80000254)
-      adobe_coeff ("Canon","EOS 1000D");
-    goto canon_cr2;
-  } else if (is_canon && raw_width == 3984) {
-    top_margin  = 20;
-    left_margin = 76;
-    height -= 2;
-    goto canon_cr2;
-  } else if (is_canon && raw_width == 4104) {
-    height = 3024;
-    width  = 4032;
-    top_margin  = 12;
-    left_margin = 48;
-  } else if (is_canon && raw_width == 4152) {
-    top_margin  = 12;
-    left_margin = 192;
-    goto canon_cr2;
-  } else if (is_canon && raw_width == 4160) {
-    height = 3048;
-    width  = 4048;
-    top_margin  = 11;
-    left_margin = 104;
-  } else if (is_canon && raw_width == 4312) {
-    top_margin  = 18;
-    left_margin = 22;
-    height -= 2;
-    if (unique_id == 0x80000176)
-      adobe_coeff ("Canon","EOS 450D");
-    goto canon_cr2;
-  } else if (is_canon && raw_width == 4352) {
-    top_margin  = 18;
-    left_margin = 62;
-    if (unique_id == 0x80000288)
-      adobe_coeff ("Canon","EOS 1100D");
-    goto canon_cr2;
-  } else if (is_canon && raw_width == 4476) {
-    top_margin  = 34;
-    left_margin = 90;
-    goto canon_cr2;
-  } else if (is_canon && raw_width == 4480) {
-    height = 3326;
-    width  = 4432;
-    top_margin  = 10;
-    left_margin = 12;
-    filters = 0x49494949;
-  } else if (is_canon && raw_width == 4496) {
-    height = 3316;
-    width  = 4404;
-    top_margin  = 50;
-    left_margin = 80;
-  } else if (is_canon && raw_width == 4832) {
-    top_margin = unique_id == 0x80000261 ? 51:26;
-    left_margin = 62;
-    if (unique_id == 0x80000252)
-      adobe_coeff ("Canon","EOS 500D");
-    goto canon_cr2;
-  } else if (is_canon && raw_width == 5108) {
-    top_margin  = 13;
-    left_margin = 98;
-    goto canon_cr2;
-  } else if (is_canon && raw_width == 5120) {
-    height -= top_margin = 45;
-    left_margin = 142;
-    width = 4916;
-  } else if (is_canon && raw_width == 5344) {
-    top_margin = 51;
-    left_margin = 142;
-    if (unique_id == 0x80000269) {
-      top_margin = 100;
-      left_margin = 126;
-      height -= 2;
-      adobe_coeff ("Canon","EOS-1D X");
-    }
-    if (unique_id == 0x80000270)
-      adobe_coeff ("Canon","EOS 550D");
-    if (unique_id == 0x80000286)
-      adobe_coeff ("Canon","EOS 600D");
-    goto canon_cr2;
-  } else if (is_canon && raw_width == 5360) {
-    top_margin = 51;
-    left_margin = 158;
-    goto canon_cr2;
-  } else if (is_canon && raw_width == 5712) {
-    height = 3752;
-    width  = 5640;
-    top_margin  = 20;
-    left_margin = 62;
-  } else if (is_canon && raw_width == 5792) {
-    top_margin  = 51;
-    left_margin = 158;
-canon_cr2:
-    height -= top_margin;
-    width  -= left_margin;
-  } else if (is_canon && raw_width == 5920) {
-    height = 3870;
-    width  = 5796;
-    top_margin  = 80;
-    left_margin = 122;
   } else if (!strcmp(model,"D1")) {
     cam_mul[0] *= 256/527.0;
     cam_mul[2] *= 256/317.0;
@@ -8119,31 +12417,31 @@ canon_cr2:
 	     !strcmp(model,"D700")) {
     width -= 4;
     left_margin = 2;
- } else if (!strcmp(model,"D3100")) {
+  } else if (!strcmp(model,"D3100")) {
     width -= 28;
     left_margin = 6;
   } else if (!strcmp(model,"D5000") ||
-             !strcmp(model,"D90")) {
+	     !strcmp(model,"D90")) {
     width -= 42;
   } else if (!strcmp(model,"D5100") ||
-	     !strcmp(model,"D7000")) {
+	     !strcmp(model,"D7000") ||
+	     !strcmp(model,"COOLPIX A")) {
     width -= 44;
   } else if (!strcmp(model,"D3200") ||
-             !strcmp(model,"D800")) {
+	    !strncmp(model,"D6",2)  ||
+	    !strncmp(model,"D800",4)) {
     width -= 46;
-  } else if (!strcmp(model,"D4")) {
+  } else if (!strcmp(model,"D4") ||
+	     !strcmp(model,"Df")) {
     width -= 52;
     left_margin = 2;
-   } else if (!strncmp(model,"D40",3) ||
+  } else if (!strncmp(model,"D40",3) ||
 	     !strncmp(model,"D50",3) ||
 	     !strncmp(model,"D70",3)) {
     width--;
   } else if (!strcmp(model,"D100")) {
-    if (tiff_compress == 34713 && !nikon_is_compressed()) {
-      load_raw = &CLASS packed_load_raw;
-      load_flags |= 1;
+    if (load_flags)
       raw_width = (width += 3) + 3;
-    }
   } else if (!strcmp(model,"D200")) {
     left_margin = 1;
     width -= 4;
@@ -8156,7 +12454,22 @@ canon_cr2:
     else width -= 8;
   } else if (!strncmp(model,"D300",4)) {
     width -= 32;
-  } else if (!strncmp(model,"COOLPIX P",9)) {
+  } else if (!strcmp(make,"Nikon") && raw_width == 4032) {
+    if(!strcmp(model,"COOLPIX P7700"))
+      {
+        adobe_coeff ("Nikon","COOLPIX P7700");
+        maximum = 65504;
+        load_flags = 0;
+      }
+    else if(!strcmp(model,"COOLPIX P7800"))
+      {
+        adobe_coeff ("Nikon","COOLPIX P7800");
+        maximum = 65504;
+        load_flags = 0;
+      }
+    else  if(!strcmp(model,"COOLPIX P340"))
+      load_flags=0;
+  } else if (!strncmp(model,"COOLPIX P",9) && raw_width != 4032) {
     load_flags = 24;
     filters = 0x94949494;
     if (model[9] == '7' && iso_speed >= 400)
@@ -8164,38 +12477,14 @@ canon_cr2:
   } else if (!strncmp(model,"1 ",2)) {
     height -= 2;
   } else if (fsize == 1581060) {
-    height = 963;
-    width = 1287;
-    raw_width = 1632;
-    maximum = 0x3f4;
-    colors = 4;
-    filters = 0x1e1e1e1e;
     simple_coeff(3);
     pre_mul[0] = 1.2085;
     pre_mul[1] = 1.0943;
     pre_mul[3] = 1.1103;
-#ifdef LIBRAW_LIBRARY_BUILD
-    color_flags.pre_mul_state = LIBRAW_COLORSTATE_CONST;
-#endif
-    goto e900;
-  } else if (fsize == 2465792) {
-    height = 1203;
-    width  = 1616;
-    raw_width = 2048;
-    colors = 4;
-    filters = 0x4b4b4b4b;
-    adobe_coeff ("NIKON","E950");
-e900:
-    tiff_bps = 10;
-    load_raw = &CLASS packed_load_raw;
-    load_flags = 6;
+  } else if (fsize == 3178560) {
+    cam_mul[0] *= 4;
+    cam_mul[2] *= 4;
   } else if (fsize == 4771840) {
-    height = 1540;
-    width  = 2064;
-    colors = 4;
-    filters = 0xe1e1e1e1;
-    load_raw = &CLASS packed_load_raw;
-    load_flags = 6;
     if (!timestamp && nikon_e995())
       strcpy (model, "E995");
     if (strcmp(model,"E995")) {
@@ -8204,27 +12493,17 @@ e900:
       pre_mul[0] = 1.196;
       pre_mul[1] = 1.246;
       pre_mul[2] = 1.018;
-#ifdef LIBRAW_LIBRARY_BUILD
-      color_flags.pre_mul_state = LIBRAW_COLORSTATE_CONST;
-#endif
     }
-  } else if (!strcmp(model,"E2100")) {
-    if (!timestamp && !nikon_e2100()) goto cp_e2500;
-    height = 1206;
-    width  = 1616;
-    load_flags = 30;
-  } else if (!strcmp(model,"E2500")) {
-cp_e2500:
-    strcpy (model, "E2500");
-    height = 1204;
-    width  = 1616;
-    colors = 4;
-    filters = 0x4b4b4b4b;
+  } else if (fsize == 2940928) {
+    if (!timestamp && !nikon_e2100())
+      strcpy (model,"E2500");
+    if (!strcmp(model,"E2500")) {
+      height -= 2;
+      load_flags = 6;
+      colors = 4;
+      filters = 0x4b4b4b4b;
+    }
   } else if (fsize == 4775936) {
-    height = 1542;
-    width  = 2064;
-    load_raw = &CLASS packed_load_raw;
-    load_flags = 30;
     if (!timestamp) nikon_3700();
     if (model[0] == 'E' && atoi(model+1) < 3700)
       filters = 0x49494949;
@@ -8242,32 +12521,21 @@ cp_e2500:
       if (i < 0) filters = 0x61616161;
     }
   } else if (fsize == 5869568) {
-    height = 1710;
-    width  = 2288;
-    filters = 0x16161616;
     if (!timestamp && minolta_z2()) {
       strcpy (make, "Minolta");
       strcpy (model,"DiMAGE Z2");
     }
-    load_raw = &CLASS packed_load_raw;
     load_flags = 6 + 24*(make[0] == 'M');
-  } else if (!strcmp(model,"E4500")) {
-    height = 1708;
-    width  = 2288;
-    colors = 4;
-    filters = 0xb4b4b4b4;
-  } else if (fsize == 7438336) {
-    height = 1924;
-    width  = 2576;
-    colors = 4;
-    filters = 0xb4b4b4b4;
-  } else if (fsize == 8998912) {
-    height = 2118;
-    width  = 2832;
-    maximum = 0xf83;
-    load_raw = &CLASS packed_load_raw;
-    load_flags = 30;
-  } else if (!strcmp(make,"FUJIFILM")) {
+  } else if (fsize == 6291456) {
+    fseek (ifp, 0x300000, SEEK_SET);
+    if ((order = guess_byte_order(0x10000)) == 0x4d4d) {
+      height -= (top_margin = 16);
+      width -= (left_margin = 28);
+      maximum = 0xf5c0;
+      strcpy (make, "ISG");
+      model[0] = 0;
+    }
+  } else if (!strcmp(make,"Fujifilm")) {
     if (!strcmp(model+7,"S2Pro")) {
       strcpy (model,"S2Pro");
       height = 2144;
@@ -8277,31 +12545,24 @@ cp_e2500:
       maximum = (is_raw == 2 && shot_select) ? 0x2f00 : 0x3e00;
     top_margin = (raw_height - height) >> 2 << 1;
     left_margin = (raw_width - width ) >> 2 << 1;
-    if (width == 3328) {
-      width = 3262;
-      left_margin = 34;
-    }
-    if (!strcmp(model,"X10") || !strcmp(model,"X-S1"))
-      filters = 0x16161616;
-    if (fuji_layout) raw_width *= is_raw;
-    if (load_raw == &CLASS fuji_load_raw) {
-      fuji_width = width >> !fuji_layout;
-      width = (height >> fuji_layout) + fuji_width;
-      raw_height = height;
-      height = width - 1;
-      if (~fuji_width & 1) filters = 0x49494949;
-    }
-    if (!strcmp(model,"X-Pro1")) {
+    if (width == 2848 || width == 3664) filters = 0x16161616;
+    if (width == 4032 || width == 4952) left_margin = 0;
+    if (width == 3328 && (width -= 66)) left_margin = 34;
+    if (width == 4936) left_margin = 4;
+    if (!strcmp(model,"HS50EXR") ||
+	!strcmp(model,"F900EXR")) {
+      width += 2;
       left_margin = 0;
-      filters = 2;
-      is_raw = 0; /* Not supported! */
+      filters = 0x16161616;
     }
-  } else if (!strcmp(model,"RD175")) {
-    height = 986;
-    width = 1534;
-    data_offset = 513;
-    filters = 0x61616161;
-    load_raw = &CLASS minolta_rd175_load_raw;
+    if(!strcmp(model,"S5500"))
+      {
+        height -= (top_margin=6);
+      }
+    if (fuji_layout) raw_width *= is_raw;
+    if (filters == 9)
+      FORC(36) xtrans[0][c] =
+	xtrans_abs[(c/6+top_margin) % 6][(c+left_margin) % 6];
   } else if (!strcmp(model,"KD-400Z")) {
     height = 1712;
     width  = 2312;
@@ -8309,9 +12570,9 @@ cp_e2500:
     goto konica_400z;
   } else if (!strcmp(model,"KD-510Z")) {
     goto konica_510z;
-  } else if (!strcasecmp(make,"MINOLTA")) {
-    load_raw = &CLASS unpacked_load_raw;
-    maximum = 0xfff;
+  } else if (!strcasecmp(make,"Minolta")) {
+    if (!load_raw && (maximum = 0xfff))
+      load_raw = &CLASS unpacked_load_raw;
     if (!strncmp(model,"DiMAGE A",8)) {
       if (!strcmp(model,"DiMAGE A200"))
 	filters = 0x49494949;
@@ -8348,54 +12609,37 @@ konica_400z:
     data_error = -1;
   } else if (!strcmp(model,"*ist DS")) {
     height -= 2;
-  } else if (!strcmp(model,"Optio S")) {
-    if (fsize == 3178560) {
-      height = 1540;
-      width  = 2064;
-      load_raw = &CLASS eight_bit_load_raw;
-      cam_mul[0] *= 4;
-      cam_mul[2] *= 4;
-    } else {
-      height = 1544;
-      width  = 2068;
-      raw_width = 3136;
-      load_raw = &CLASS packed_load_raw;
-      maximum = 0xf7c;
-    }
-  } else if (fsize == 6114240) {
-    height = 1737;
-    width  = 2324;
-    raw_width = 3520;
-    load_raw = &CLASS packed_load_raw;
-    maximum = 0xf7a;
-  } else if (!strcmp(model,"Optio 750Z")) {
-    height = 2302;
-    width  = 3072;
-    load_raw = &CLASS packed_load_raw;
-    load_flags = 30;
-  } else if (!strcmp(model,"DC-833m")) {
-    height = 2448;
-    width  = 3264;
-    order = 0x4949;
-    filters = 0x61616161;
-    load_raw = &CLASS unpacked_load_raw;
-    maximum = 0xfc00;
-  } else if (!strncmp(model,"S85",3)) {
-    height = 2448;
-    width  = 3264;
-    raw_width = fsize/height/2;
-    order = 0x4d4d;
-    load_raw = &CLASS unpacked_load_raw;
-  } else if (!strncmp(model,"NX1",3)) {
+  } else if (!strcmp(make,"Samsung") && raw_width == 4704) {
     height -= top_margin = 8;
     width -= 2 * (left_margin = 8);
     load_flags = 32;
-  } else if (!strcmp(model,"NX200")) {
+  } else if (!strcmp(make,"Samsung") && !strcmp(model,"NX3000")) {
+    top_margin = 24;
+    left_margin = 64;
+    width = 5472;
+    height = 3648;
+    filters = 0x61616161;
+    colors = 3;
+  } else if (!strcmp(make,"Samsung") && raw_height == 3714) {
+    height -= top_margin = 18;
+    left_margin = raw_width - (width = 5536);
+    if (raw_width != 5600)
+      left_margin = top_margin = 0;
+    filters = 0x61616161;
+    colors = 3;
+  } else if (!strcmp(make,"Samsung") && raw_width == 5632) {
     order = 0x4949;
     height = 3694;
     top_margin = 2;
     width  = 5574 - (left_margin = 32 + tiff_bps);
     if (tiff_bps == 12) load_flags = 80;
+  } else if (!strcmp(make,"Samsung") && raw_width == 5664) {
+    height -= top_margin = 17;
+    left_margin = 96;
+    width = 5544;
+    filters = 0x49494949;
+  } else if (!strcmp(make,"Samsung") && raw_width == 6496) {
+    filters = 0x61616161;
   } else if (!strcmp(model,"EX1")) {
     order = 0x4949;
     height -= 20;
@@ -8414,99 +12658,21 @@ konica_400z:
       width  -= 56;
       top_margin = 8;
     }
-  } else if (fsize == 20487168) {
-    height = 2808;
-    width  = 3648;
-    goto wb550;
-  } else if (fsize == 24000000) {
-    height = 3000;
-    width  = 4000;
-wb550:
+  } else if (strstr(model,"WB550")) {
     strcpy (model, "WB550");
-    order = 0x4d4d;
+  } else if (!strcmp(model,"EX2F")) {
+    height = 3045;
+    width  = 4070;
+    top_margin = 3;
+    order = 0x4949;
+    filters = 0x49494949;
     load_raw = &CLASS unpacked_load_raw;
-    load_flags = 6;
-    maximum = 0x3df;
   } else if (!strcmp(model,"STV680 VGA")) {
-    height = 484;
-    width  = 644;
-    load_raw = &CLASS eight_bit_load_raw;
-    flip = 2;
-    filters = 0x16161616;
     black = 16;
   } else if (!strcmp(model,"N95")) {
     height = raw_height - (top_margin = 2);
-  } else if (!strcmp(model,"531C")) {
-    height = 1200;
-    width  = 1600;
-    load_raw = &CLASS unpacked_load_raw;
-    filters = 0x49494949;
   } else if (!strcmp(model,"640x480")) {
-    height = 480;
-    width  = 640;
-    load_raw = &CLASS eight_bit_load_raw;
     gamma_curve (0.45, 4.5, 1, 255);
-  } else if (!strcmp(model,"F-080C")) {
-    height = 768;
-    width  = 1024;
-    load_raw = &CLASS eight_bit_load_raw;
-  } else if (!strcmp(model,"F-145C")) {
-    height = 1040;
-    width  = 1392;
-    load_raw = &CLASS eight_bit_load_raw;
-  } else if (!strcmp(model,"F-201C")) {
-    height = 1200;
-    width  = 1600;
-    load_raw = &CLASS eight_bit_load_raw;
-  } else if (!strcmp(model,"F-510C")) {
-    height = 1958;
-    width  = 2588;
-    load_raw = fsize < 7500000 ?
-	&CLASS eight_bit_load_raw : &CLASS unpacked_load_raw;
-    data_offset = fsize - width*height*(fsize >> 22);
-    maximum = 0xfff0;
-  } else if (!strcmp(model,"F-810C")) {
-    height = 2469;
-    width  = 3272;
-    load_raw = &CLASS unpacked_load_raw;
-    maximum = 0xfff0;
-  } else if (!strcmp(model,"XCD-SX910CR")) {
-    height = 1024;
-    width  = 1375;
-    raw_width = 1376;
-    filters = 0x49494949;
-    maximum = 0x3ff;
-    load_raw = fsize < 2000000 ?
-	&CLASS eight_bit_load_raw : &CLASS unpacked_load_raw;
-  } else if (!strcmp(model,"2010")) {
-    height = 1207;
-    width  = 1608;
-    order = 0x4949;
-    filters = 0x16161616;
-    data_offset = 3212;
-    maximum = 0x3ff;
-    load_raw = &CLASS unpacked_load_raw;
-  } else if (!strcmp(model,"A782")) {
-    height = 3000;
-    width  = 2208;
-    filters = 0x61616161;
-    load_raw = fsize < 10000000 ?
-	&CLASS eight_bit_load_raw : &CLASS unpacked_load_raw;
-    maximum = 0xffc0;
-  } else if (!strcmp(model,"3320AF")) {
-    height = 1536;
-    raw_width = width = 2048;
-    filters = 0x61616161;
-    load_raw = &CLASS unpacked_load_raw;
-    maximum = 0x3ff;
-    fseek (ifp, 0x300000, SEEK_SET);
-    if ((order = guess_byte_order(0x10000)) == 0x4d4d) {
-      height -= (top_margin = 16);
-      width -= (left_margin = 28);
-      maximum = 0xf5c0;
-      strcpy (make, "ISG");
-      model[0] = 0;
-    }
   } else if (!strcmp(make,"Hasselblad")) {
     if (load_raw == &CLASS lossless_jpeg_load_raw)
       load_raw = &CLASS hasselblad_load_raw;
@@ -8516,34 +12682,84 @@ wb550:
       top_margin  = 4;
       left_margin = 7;
       filters = 0x61616161;
-    } else if (raw_width == 7410) {
-      height = 5502;
-      width  = 7328;
+      if(!strcasecmp(model,"H3D"))
+        {
+          adobe_coeff("Hasselblad","H3DII-39");
+          strcpy(model,"H3DII-39");
+        }
+    } else if (raw_width == 7410 || raw_width == 8282) {
+      height -= 84;
+      width  -= 82;
       top_margin  = 4;
       left_margin = 41;
       filters = 0x61616161;
+      adobe_coeff("Hasselblad","H4D-40");
+      strcpy(model,"H4D-40");
     } else if (raw_width == 9044) {
-      height = 6716;
-      width  = 8964;
-      top_margin  = 8;
-      left_margin = 40;
-      black += load_flags = 256;
-      maximum = 0x8101;
+      if(black > 500)
+        {
+          top_margin = 12;
+          left_margin = 44;
+          width = 8956;
+          height = 6708;
+          memset(cblack,0,sizeof(cblack));
+          adobe_coeff("Hasselblad","H4D-60");
+          strcpy(model,"H4D-60");
+          black = 512;
+        }
+      else
+        {
+          height = 6716;
+          width  = 8964;
+          top_margin  = 8;
+          left_margin = 40;
+          black += load_flags = 256;
+          maximum = 0x8101;
+          strcpy(model,"H3DII-60");
+        }
     } else if (raw_width == 4090) {
       strcpy (model, "V96C");
       height -= (top_margin = 6);
       width -= (left_margin = 3) + 7;
       filters = 0x61616161;
+    } else if (raw_width == 8282 && raw_height == 6240) {
+      if(!strcasecmp(model,"H5D"))
+        {
+          /* H5D 50*/
+          left_margin = 54;
+          top_margin = 16;
+          width = 8176;
+          height = 6132;
+          black = 256;
+          strcpy(model,"H5D-50");
+        }
+      else if(!strcasecmp(model,"H3D"))
+        {
+          black=0;
+          left_margin = 54;
+          top_margin = 16;
+          width = 8176;
+          height = 6132;
+          memset(cblack,0,sizeof(cblack));
+          adobe_coeff("Hasselblad","H3D-50");
+          strcpy(model,"H3D-50");
+        }
+    } else if (raw_width == 8374 && raw_height == 6304) {
+      /* H5D 50c*/
+      left_margin = 52;
+      top_margin = 100;
+      width = 8272;
+      height = 6200;
+      black = 256;
+      strcpy(model,"H5D-50c");
     }
-  } else if (!strcmp(make,"Sinar")) {
-    if (!memcmp(head,"8BPS",4)) {
-      fseek (ifp, 14, SEEK_SET);
-      height = get4();
-      width  = get4();
-      filters = 0x61616161;
-      data_offset = 68;
+    if (tiff_samples > 1) {
+      is_raw = tiff_samples+1;
+      if (!shot_select && !half_size) filters = 0;
     }
+  } else if (!strcmp(make,"Sinar")) {
     if (!load_raw) load_raw = &CLASS unpacked_load_raw;
+    if (is_raw > 1 && !shot_select && !half_size) filters = 0;
     maximum = 0x3fff;
   } else if (!strcmp(make,"Leaf")) {
     maximum = 0x3fff;
@@ -8587,8 +12803,7 @@ wb550:
       width -= 2 * (left_margin = 24);
       filters = 0x16161616;
     }
-  } else if (!strcmp(make,"LEICA") || !strcmp(make,"Panasonic")) {
-     if(raw_width < 1) { is_raw = 0; goto notraw; }
+  } else if (!strcmp(make,"Leica") || !strcmp(make,"Panasonic")) {
     if ((flen - data_offset) / (raw_width*8/7) == raw_height)
       load_raw = &CLASS panasonic_load_raw;
     if (!load_raw) {
@@ -8612,11 +12827,12 @@ wb550:
     filters = 0x16161616;
     load_raw = &CLASS packed_load_raw;
     load_flags = 30;
-  } else if (!strcmp(make,"OLYMPUS")) {
+  } else if (!strcmp(make,"Olympus")) {
     height += height & 1;
-    filters = exif_cfa;
+    if (exif_cfa) filters = exif_cfa;
     if (width == 4100) width -= 4;
     if (width == 4080) width -= 24;
+    if (width == 9280) { width -= 6; height -= 6; }
     if (load_raw == &CLASS unpacked_load_raw)
       load_flags = 4;
     tiff_bps = 12;
@@ -8627,6 +12843,9 @@ wb550:
 	maximum = 0xfc3;
 	memset (cblack, 0, sizeof cblack);
       }
+    } else if (!strcmp(model,"STYLUS1")) {
+      width -= 14;
+      maximum = 0xfff;
     } else if (!strcmp(model,"E-330")) {
       width -= 30;
       if (load_raw == &CLASS unpacked_load_raw)
@@ -8636,83 +12855,7 @@ wb550:
       thumb_height = 480;
       thumb_width  = 640;
     }
-  }
-  else
-      identify2(fsize,flen,head); /* Avoid MS VS 2008 bug */
-
-
-  if (!model[0])
-    sprintf (model, "%dx%d", width, height);
-  if (filters == UINT_MAX) filters = 0x94949494;
-  if (raw_color) adobe_coeff (make, model);
-  if (load_raw == &CLASS kodak_radc_load_raw)
-    if (raw_color) adobe_coeff ("Apple","Quicktake");
-  if (thumb_offset && !thumb_height) {
-    fseek (ifp, thumb_offset, SEEK_SET);
-    if (ljpeg_start (&jh, 1)) {
-      thumb_width  = jh.wide;
-      thumb_height = jh.high;
-    }
-  }
-dng_skip:
-  if (fuji_width) {
-/*
-    fuji_width = width >> !fuji_layout;
-    if (~fuji_width & 1) filters = 0x49494949;
-    width = (height >> fuji_layout) + fuji_width;
-    height = width - 1;
-    pixel_aspect = 1;
-*/
-  } else {
-    if (raw_height < height) raw_height = height;
-    if (raw_width  < width ) raw_width  = width;
-  }
-  if (!tiff_bps) tiff_bps = 12;
-  if (!maximum) maximum = (1 << tiff_bps) - 1;
-  if (!load_raw || height < 22) is_raw = 0;
-#ifdef NO_JASPER
-  if (load_raw == &CLASS redcine_load_raw) {
-#ifdef DCRAW_VERBOSE
-    fprintf (stderr,_("%s: You must link dcraw with %s!!\n"),
-	ifname, "libjasper");
-#endif
-    is_raw = 0;
-#ifdef LIBRAW_LIBRARY_BUILD
-    imgdata.process_warnings |= LIBRAW_WARN_NO_JASPER;
-#endif
-  }
-#endif
-#ifdef NO_JPEG
-  if (load_raw == &CLASS kodak_jpeg_load_raw) {
-#ifdef DCRAW_VERBOSE
-    fprintf (stderr,_("%s: You must link dcraw with %s!!\n"),
-	ifname, "libjpeg");
-#endif
-    is_raw = 0;
-#ifdef LIBRAW_LIBRARY_BUILD
-    imgdata.process_warnings |= LIBRAW_WARN_NO_JPEGLIB;
-#endif
-  }
-#endif
-  if (!cdesc[0])
-    strcpy (cdesc, colors == 3 ? "RGBG":"GMCY");
-  if (!raw_height) raw_height = height;
-  if (!raw_width ) raw_width  = width;
-  if (filters && colors == 3)
-    filters |= ((filters >> 2 & 0x22222222) |
-		(filters << 2 & 0x88888888)) & filters << 1;
-notraw:
-  if (flip == -1) flip = tiff_flip;
-  if (flip == -1) flip = 0;
-
-#ifdef LIBRAW_LIBRARY_BUILD
-  RUN_CALLBACK(LIBRAW_PROGRESS_IDENTIFY,1,2);
-#endif
-}
-
-void CLASS identify2(unsigned fsize, unsigned flen, char *head)
-{
- if (!strcmp(model,"N Digital")) {
+  } else if (!strcmp(model,"N Digital")) {
     height = 2047;
     width  = 3072;
     filters = 0x61616161;
@@ -8721,6 +12864,7 @@ void CLASS identify2(unsigned fsize, unsigned flen, char *head)
   } else if (!strcmp(model,"DSC-F828")) {
     width = 3288;
     left_margin = 5;
+    mask[1][3] = -17;
     data_offset = 862144;
     load_raw = &CLASS sony_load_raw;
     filters = 0x9c9c9c9c;
@@ -8729,100 +12873,70 @@ void CLASS identify2(unsigned fsize, unsigned flen, char *head)
   } else if (!strcmp(model,"DSC-V3")) {
     width = 3109;
     left_margin = 59;
+    mask[0][1] = 9;
     data_offset = 787392;
     load_raw = &CLASS sony_load_raw;
-  } else if (!strcmp(make,"SONY") && raw_width == 3984) {
-    adobe_coeff ("SONY","DSC-R1");
+  } else if (!strcmp(make,"Sony") && raw_width == 3984) {
     width = 3925;
     order = 0x4d4d;
-  } else if (!strcmp(make,"SONY") && raw_width == 6048) {
+  } else if (!strcmp(make,"Sony") && raw_width == 4288) {
+    width -= 32;
+  } else if (!strcmp(make,"Sony") && raw_width == 4928) {
+    if (height < 3280) width -= 8;
+  } else if (!strcmp(make,"Sony") && raw_width == 5504) { // ILCE-3000//5000
+    width -= height > 3664 ? 8 : 32;
+  } else if (!strcmp(make,"Sony") && raw_width == 6048) {
     width -= 24;
+    if (strstr(model,"RX1") || strstr(model,"A99"))
+      width -= 6;
+  } else if (!strcmp(make,"Sony") && raw_width == 7392) {
+    width -= 30;
   } else if (!strcmp(model,"DSLR-A100")) {
     if (width == 3880) {
       height--;
       width = ++raw_width;
     } else {
+      height -= 4;
+      width  -= 4;
       order = 0x4d4d;
       load_flags = 2;
     }
     filters = 0x61616161;
   } else if (!strcmp(model,"DSLR-A350")) {
     height -= 4;
-  }
- else if (!strcmp(model,"PIXL")) {
+  } else if (!strcmp(model,"PIXL")) {
     height -= top_margin = 4;
     width -= left_margin = 32;
     gamma_curve (0, 7, 1, 255);
-  } else if (!strcmp(model,"C603v")) {
-    height = 480;
-    width  = 640;
-    if (fsize < 614400 || find_green (16, 16, 3840, 5120) < 25) goto c603v;
-    strcpy (model,"KAI-0340");
-    height -= 3;
-    data_offset = 3840;
+  } else if (!strcmp(model,"C603") || !strcmp(model,"C330")
+	|| !strcmp(model,"12MP")) {
     order = 0x4949;
-    load_raw = &CLASS unpacked_load_raw;
-  } else if (!strcmp(model,"C603y")) {
-    height = 2134;
-    width  = 2848;
-c603v:
-    filters = 0;
-    load_raw = &CLASS kodak_yrgb_load_raw;
-    gamma_curve (0, 3.875, 1, 255);
-  } else if (!strcmp(model,"C603")) {
-    raw_height = height = 2152;
-    raw_width  = width  = 2864;
-    goto c603;
-  } else if (!strcmp(model,"C330")) {
-    height = 1744;
-    width  = 2336;
-    raw_height = 1779;
-    raw_width  = 2338;
-    top_margin = 33;
-    left_margin = 1;
-c603:
-    order = 0x4949;
-    if ((data_offset = fsize - raw_height*raw_width)) {
-      fseek (ifp, 168, SEEK_SET);
+    if (filters && data_offset) {
+      fseek (ifp, data_offset < 4096 ? 168 : 5252, SEEK_SET);
       read_shorts (curve, 256);
-#ifdef LIBRAW_LIBRARY_BUILD
-      color_flags.curve_state = LIBRAW_COLORSTATE_LOADED;
-#endif
     } else gamma_curve (0, 3.875, 1, 255);
-    load_raw = &CLASS eight_bit_load_raw;
-  }
- else if (!strncasecmp(model,"EasyShare",9)) {
+    load_raw  =  filters   ? &CLASS eight_bit_load_raw :
+      strcmp(model,"C330") ? &CLASS kodak_c603_load_raw :
+			     &CLASS kodak_c330_load_raw;
+    load_flags = tiff_bps > 16;
+    tiff_bps = 8;
+  } else if (!strncasecmp(model,"EasyShare",9)) {
     data_offset = data_offset < 0x15000 ? 0x15000 : 0x17000;
     load_raw = &CLASS packed_load_raw;
-  } else if (!strcasecmp(make,"KODAK")) {
+  } else if (!strcasecmp(make,"Kodak")) {
     if (filters == UINT_MAX) filters = 0x61616161;
-    if (!strncmp(model,"NC2000",6)) {
-      width -= 4;
-      left_margin = 2;
-    } else if (!strcmp(model,"EOSDCS3B")) {
-      width -= 4;
-      left_margin = 2;
-    } else if (!strcmp(model,"EOSDCS1")) {
-      width -= 4;
-      left_margin = 2;
-    } else if (!strcmp(model,"DCS420")) {
-      width -= 4;
-      left_margin = 2;
-    } else if (!strncmp(model,"DCS460 ",7)) {
-      model[6] = 0;
-      width -= 4;
-      left_margin = 2;
-    } else if (!strcmp(model,"DCS460A")) {
+    if (!strncmp(model,"NC2000",6) ||
+	!strncmp(model,"EOSDCS",6) ||
+	!strncmp(model,"DCS4",4)) {
       width -= 4;
       left_margin = 2;
-      colors = 1;
-      filters = 0;
+      if (model[6] == ' ') model[6] = 0;
+      if (!strcmp(model,"DCS460A")) goto bw;
     } else if (!strcmp(model,"DCS660M")) {
       black = 214;
-      colors = 1;
-      filters = 0;
+      goto bw;
     } else if (!strcmp(model,"DCS760M")) {
-      colors = 1;
+bw:   colors = 1;
       filters = 0;
     }
     if (!strcmp(model+4,"20X"))
@@ -8832,7 +12946,11 @@ c603:
       data_offset = 15424;
     }
     if (!strncmp(model,"DC2",3)) {
-      raw_height = height = 242;
+      raw_height = 2 + (height = 242);
+      if (!strncmp(model, "DC290", 5))
+        iso_speed = 100;
+      if (!strncmp(model, "DC280", 5))
+        iso_speed = 70;
       if (flen < 100000) {
 	raw_width = 256; width = 249;
 	pixel_aspect = (4.0*height) / (3.0*width);
@@ -8840,16 +12958,13 @@ c603:
 	raw_width = 512; width = 501;
 	pixel_aspect = (493.0*height) / (373.0*width);
       }
-      data_offset += raw_width + 1;
+      top_margin = left_margin = 1;
       colors = 4;
       filters = 0x8d8d8d8d;
       simple_coeff(1);
       pre_mul[1] = 1.179;
       pre_mul[2] = 1.209;
       pre_mul[3] = 1.036;
-#ifdef LIBRAW_LIBRARY_BUILD
-      color_flags.pre_mul_state = LIBRAW_COLORSTATE_CONST;
-#endif
       load_raw = &CLASS eight_bit_load_raw;
     } else if (!strcmp(model,"40")) {
       strcpy (model, "DC40");
@@ -8861,12 +12976,14 @@ c603:
       strcpy (model, "DC50");
       height = 512;
       width  = 768;
+      iso_speed=84;
       data_offset = 19712;
       load_raw = &CLASS kodak_radc_load_raw;
     } else if (strstr(model,"DC120")) {
       strcpy (model, "DC120");
       height = 976;
       width  = 848;
+      iso_speed=160;
       pixel_aspect = height/0.75/width;
       load_raw = tiff_compress == 7 ?
 	&CLASS kodak_jpeg_load_raw : &CLASS kodak_dc120_load_raw;
@@ -8875,14 +12992,11 @@ c603:
       thumb_width  = 192;
       thumb_offset = 6144;
       thumb_misc   = 360;
+      iso_speed=140;
       write_thumb = &CLASS layer_thumb;
-      height = 1024;
-      width  = 1536;
-      data_offset = 79872;
-      load_raw = &CLASS eight_bit_load_raw;
       black = 17;
     }
-} else if (!strcmp(model,"Fotoman Pixtura")) {
+  } else if (!strcmp(model,"Fotoman Pixtura")) {
     height = 512;
     width  = 768;
     data_offset = 3632;
@@ -8917,106 +13031,6 @@ c603:
     }
     filters = 0x16161616;
     load_raw = &CLASS rollei_load_raw;
-  } else if (!strcmp(model,"PC-CAM 600")) {
-    height = 768;
-    data_offset = width = 1024;
-    filters = 0x49494949;
-    load_raw = &CLASS eight_bit_load_raw;
-  }
-else if (!strcmp(model,"QV-2000UX")) {
-    height = 1208;
-    width  = 1632;
-    data_offset = width * 2;
-    load_raw = &CLASS eight_bit_load_raw;
-  } else if (fsize == 3217760) {
-    height = 1546;
-    width  = 2070;
-    raw_width = 2080;
-    load_raw = &CLASS eight_bit_load_raw;
-  } else if (!strcmp(model,"QV-4000")) {
-    height = 1700;
-    width  = 2260;
-    load_raw = &CLASS unpacked_load_raw;
-    maximum = 0xffff;
-  } else if (!strcmp(model,"QV-5700")) {
-    height = 1924;
-    width  = 2576;
-    raw_width = 3232;
-    tiff_bps = 10;
-  } else if (!strcmp(model,"QV-R41")) {
-    height = 1720;
-    width  = 2312;
-    raw_width = 3520;
-    left_margin = 2;
-  } else if (!strcmp(model,"QV-R51")) {
-    height = 1926;
-    width  = 2580;
-    raw_width = 3904;
-  } else if (!strcmp(model,"EX-S20")) {
-    height = 1208;
-    width  = 1620;
-    raw_width = 2432;
-    flip = 3;
-  } else if (!strcmp(model,"EX-S100")) {
-    height = 1544;
-    width  = 2058;
-    raw_width = 3136;
-  } else if (!strcmp(model,"EX-Z50")) {
-    height = 1931;
-    width  = 2570;
-    raw_width = 3904;
-  } else if (!strcmp(model,"EX-Z500")) {
-    height = 1937;
-    width  = 2577;
-    raw_width = 3904;
-    filters = 0x16161616;
-  } else if (!strcmp(model,"EX-Z55")) {
-    height = 1960;
-    width  = 2570;
-    raw_width = 3904;
-  } else if (!strcmp(model,"EX-Z60")) {
-    height = 2145;
-    width  = 2833;
-    raw_width = 3584;
-    filters = 0x16161616;
-    tiff_bps = 10;
-  } else if (!strcmp(model,"EX-Z75")) {
-    height = 2321;
-    width  = 3089;
-    raw_width = 4672;
-  } else if (!strcmp(model,"EX-Z750")) {
-    height = 2319;
-    width  = 3087;
-    raw_width = 4672;
-    maximum = 0xfff;
-  } else if (!strcmp(model,"EX-Z850")) {
-    height = 2468;
-    width  = 3279;
-    raw_width = 4928;
-    maximum = 0xfff;
-  } else if (!strcmp(model,"EX-Z8")) {
-    height = 2467;
-    width  = 3281;
-    raw_height = 2502;
-    raw_width  = 4992;
-    maximum = 0xfff;
-  } else if (fsize == 15499264) {       /* EX-Z1050 or EX-Z1080 */
-    height = 2752;
-    width  = 3672;
-    raw_width = 5632;
-  } else if (!strcmp(model,"EX-P505")) {
-    height = 1928;
-    width  = 2568;
-    raw_width = 3852;
-    maximum = 0xfff;
-  } else if (fsize == 9313536) {	/* EX-P600 or QV-R61 */
-    height = 2142;
-    width  = 2844;
-    raw_width = 4288;
-  } else if (!strcmp(model,"EX-P700")) {
-    height = 2318;
-    width  = 3082;
-    raw_width = 4672;
   }
   else if (!strcmp(model,"GRAS-50S5C")) {
    height = 2048;
@@ -9051,13 +13065,116 @@ else if (!strcmp(model,"QV-2000UX")) {
    order = 0x4949;
    maximum = 0x0fff;
   }
+  /* Early reject for damaged images */
+  if (!load_raw || height < 22 || width < 22 ||
+	tiff_bps > 16 || tiff_samples > 4 || colors > 4 || colors < 1)
+    {
+      is_raw = 0;
+#ifdef LIBRAW_LIBRARY_BUILD
+      RUN_CALLBACK(LIBRAW_PROGRESS_IDENTIFY,1,2);
+#endif
+      return;
+    }
+  if (!model[0])
+    sprintf (model, "%dx%d", width, height);
+  if (filters == UINT_MAX) filters = 0x94949494;
+  if (thumb_offset && !thumb_height) {
+    fseek (ifp, thumb_offset, SEEK_SET);
+    if (ljpeg_start (&jh, 1)) {
+      thumb_width  = jh.wide;
+      thumb_height = jh.high;
+    }
+  }
+
+dng_skip:
+  if ((use_camera_matrix & (use_camera_wb || dng_version))
+	&& cmatrix[0][0] > 0.125) {
+    memcpy (rgb_cam, cmatrix, sizeof cmatrix);
+    raw_color = 0;
+  }
+
+  if (raw_color) adobe_coeff (make, model);
+#ifdef LIBRAW_LIBRARY_BUILD
+  else if(imgdata.color.cam_xyz[0][0]<0.01)
+	  adobe_coeff (make, model,1);
+#endif
+
+  if (load_raw == &CLASS kodak_radc_load_raw)
+    if (raw_color) adobe_coeff ("Apple","Quicktake");
+
+  if (fuji_width) {
+    fuji_width = width >> !fuji_layout;
+    if (~fuji_width & 1) filters = 0x49494949;
+    width = (height >> fuji_layout) + fuji_width;
+    height = width - 1;
+    pixel_aspect = 1;
+  } else {
+    if (raw_height < height) raw_height = height;
+    if (raw_width  < width ) raw_width  = width;
+  }
+  if (!tiff_bps) tiff_bps = 12;
+  if (!maximum)
+    {
+      maximum = (1 << tiff_bps) - 1;
+      if(maximum < 0x10000 && curve[maximum]>0 &&    load_raw == &CLASS sony_arw2_load_raw)
+        maximum = curve[maximum];
+    }
+  if (!load_raw || height < 22 || width < 22 ||
+	tiff_bps > 16 || tiff_samples > 6 || colors > 4)
+    is_raw = 0;
+#ifdef NO_JASPER
+  if (load_raw == &CLASS redcine_load_raw) {
+#ifdef DCRAW_VERBOSE
+    fprintf (stderr,_("%s: You must link dcraw with %s!!\n"),
+	ifname, "libjasper");
+#endif
+    is_raw = 0;
+#ifdef LIBRAW_LIBRARY_BUILD
+    imgdata.process_warnings |= LIBRAW_WARN_NO_JASPER;
+#endif
+  }
+#endif
+#ifdef NO_JPEG
+  if (load_raw == &CLASS kodak_jpeg_load_raw ||
+      load_raw == &CLASS lossy_dng_load_raw) {
+#ifdef DCRAW_VERBOSE
+    fprintf (stderr,_("%s: You must link dcraw with %s!!\n"),
+	ifname, "libjpeg");
+#endif
+    is_raw = 0;
+#ifdef LIBRAW_LIBRARY_BUILD
+    imgdata.process_warnings |= LIBRAW_WARN_NO_JPEGLIB;
+#endif
+  }
+#endif
+  if (!cdesc[0])
+    strcpy (cdesc, colors == 3 ? "RGBG":"GMCY");
+  if (!raw_height) raw_height = height;
+  if (!raw_width ) raw_width  = width;
+  if (filters > 999 && colors == 3)
+    filters |= ((filters >> 2 & 0x22222222) |
+		(filters << 2 & 0x88888888)) & filters << 1;
+notraw:
+  if (flip == UINT_MAX) flip = tiff_flip;
+  if (flip == UINT_MAX) flip = 0;
+
+#ifdef LIBRAW_LIBRARY_BUILD
+  RUN_CALLBACK(LIBRAW_PROGRESS_IDENTIFY,1,2);
+#endif
 }
 
+
 void CLASS convert_to_rgb()
 {
-  int row, col, c, i, j, k;
+#ifndef LIBRAW_LIBRARY_BUILD
+  int row, col, c;
+#endif
+  int  i, j, k;
+#ifndef LIBRAW_LIBRARY_BUILD
   ushort *img;
-  float out[3], out_cam[3][4];
+  float out[3];
+#endif
+  float out_cam[3][4];
   double num, inverse[3][3];
   static const double xyzd50_srgb[3][3] =
   { { 0.436083, 0.385083, 0.143055 },
@@ -9103,8 +13220,13 @@ void CLASS convert_to_rgb()
 #endif
   gamma_curve (gamm[0], gamm[1], 0, 0);
   memcpy (out_cam, rgb_cam, sizeof out_cam);
+#ifndef LIBRAW_LIBRARY_BUILD
   raw_color |= colors == 1 || document_mode ||
 		output_color < 1 || output_color > 5;
+#else
+  raw_color |= colors == 1 ||
+		output_color < 1 || output_color > 5;
+#endif
   if (!raw_color) {
     oprof = (unsigned *) calloc (phead[0], 1);
     merror (oprof, "convert_to_rgb()");
@@ -9142,13 +13264,11 @@ void CLASS convert_to_rgb()
   if (verbose)
     fprintf (stderr, raw_color ? _("Building histograms...\n") :
 	_("Converting to %s colorspace...\n"), name[output_color-1]);
-
 #endif
 #ifdef LIBRAW_LIBRARY_BUILD
-  memset(histogram,0,sizeof(int)*LIBRAW_HISTOGRAM_SIZE*4);
+  convert_to_rgb_loop(out_cam);
 #else
   memset (histogram, 0, sizeof histogram);
-#endif
   for (img=image[0], row=0; row < height; row++)
     for (col=0; col < width; col++, img+=4) {
       if (!raw_color) {
@@ -9161,11 +13281,14 @@ void CLASS convert_to_rgb()
 	FORC3 img[c] = CLIP((int) out[c]);
       }
       else if (document_mode)
-	img[0] = img[FC(row,col)];
+	img[0] = img[fcol(row,col)];
       FORCC histogram[c][img[c] >> 3]++;
     }
+#endif
   if (colors == 4 && output_color) colors = 3;
+#ifndef LIBRAW_LIBRARY_BUILD
   if (document_mode && filters) colors = 1;
+#endif
 #ifdef LIBRAW_LIBRARY_BUILD
   RUN_CALLBACK(LIBRAW_PROGRESS_CONVERT_RGB,1,2);
 #endif
@@ -9188,7 +13311,7 @@ void CLASS fuji_rotate()
   step = sqrt(0.5);
   wide = fuji_width / step;
   high = (height - fuji_width) / step;
-  img = (ushort (*)[4]) calloc (wide*high, sizeof *img);
+  img = (ushort (*)[4]) calloc (high, wide*sizeof *img);
   merror (img, "fuji_rotate()");
 
 #ifdef LIBRAW_LIBRARY_BUILD
@@ -9208,6 +13331,7 @@ void CLASS fuji_rotate()
 	  (pix[    0][i]*(1-fc) + pix[      1][i]*fc) * (1-fr) +
 	  (pix[width][i]*(1-fc) + pix[width+1][i]*fc) * fr;
     }
+
   free (image);
   width  = wide;
   height = high;
@@ -9233,7 +13357,7 @@ void CLASS stretch()
 #endif
   if (pixel_aspect < 1) {
     newdim = height / pixel_aspect + 0.5;
-    img = (ushort (*)[4]) calloc (width*newdim, sizeof *img);
+    img = (ushort (*)[4]) calloc (width, newdim*sizeof *img);
     merror (img, "stretch()");
     for (rc=row=0; row < newdim; row++, rc+=pixel_aspect) {
       frac = rc - (c = rc);
@@ -9245,7 +13369,7 @@ void CLASS stretch()
     height = newdim;
   } else {
     newdim = width * pixel_aspect + 0.5;
-    img = (ushort (*)[4]) calloc (height*newdim, sizeof *img);
+    img = (ushort (*)[4]) calloc (height, newdim*sizeof *img);
     merror (img, "stretch()");
     for (rc=col=0; col < newdim; col++, rc+=1/pixel_aspect) {
       frac = rc - (c = rc);
@@ -9270,7 +13394,6 @@ int CLASS flip_index (int row, int col)
   if (flip & 1) col = iwidth  - 1 - col;
   return row * iwidth + col;
 }
-
 void CLASS tiff_set (ushort *ntag,
 	ushort tag, ushort type, int count, int val)
 {
@@ -9357,13 +13480,14 @@ void CLASS tiff_head (struct tiff_hdr *th, int full)
   strncpy (th->t_desc, desc, 512);
   strncpy (th->t_make, make, 64);
   strncpy (th->t_model, model, 64);
-  strcpy (th->soft, "dcraw v"DCRAW_VERSION);
+  strcpy (th->soft, "dcraw v" DCRAW_VERSION);
   t = localtime (&timestamp);
   sprintf (th->date, "%04d:%02d:%02d %02d:%02d:%02d",
       t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);
   strncpy (th->t_artist, artist, 64);
 }
 
+#ifdef LIBRAW_LIBRARY_BUILD
 void CLASS jpeg_thumb_writer (FILE *tfp,char *t_humb,int t_humb_length)
 {
   ushort exif[5];
@@ -9380,7 +13504,6 @@ void CLASS jpeg_thumb_writer (FILE *tfp,char *t_humb,int t_humb_length)
   fwrite (t_humb+2, 1, t_humb_length-2, tfp);
 }
 
-
 void CLASS jpeg_thumb()
 {
   char *thumb;
@@ -9391,6 +13514,29 @@ void CLASS jpeg_thumb()
   jpeg_thumb_writer(ofp,thumb,thumb_length);
   free (thumb);
 }
+#else
+void CLASS jpeg_thumb()
+{
+  char *thumb;
+  ushort exif[5];
+  struct tiff_hdr th;
+
+  thumb = (char *) malloc (thumb_length);
+  merror (thumb, "jpeg_thumb()");
+  fread (thumb, 1, thumb_length, ifp);
+  fputc (0xff, ofp);
+  fputc (0xd8, ofp);
+  if (strcmp (thumb+6, "Exif")) {
+    memcpy (exif, "\xff\xe1  Exif\0\0", 10);
+    exif[1] = htons (8 + sizeof th);
+    fwrite (exif, 1, sizeof exif, ofp);
+    tiff_head (&th, 0);
+    fwrite (&th, 1, sizeof th, ofp);
+  }
+  fwrite (thumb+2, 1, thumb_length-2, ofp);
+  free (thumb);
+}
+#endif
 
 void CLASS write_ppm_tiff()
 {
@@ -9400,7 +13546,11 @@ void CLASS write_ppm_tiff()
   int c, row, col, soff, rstep, cstep;
   int perc, val, total, t_white=0x2000;
 
+#ifdef LIBRAW_LIBRARY_BUILD
+  perc = width * height * auto_bright_thr;
+#else
   perc = width * height * 0.01;		/* 99th percentile white level */
+#endif
   if (fuji_width) perc /= 2;
   if (!((highlight & ~2) || no_auto_bright))
     for (t_white=c=0; c < colors; c++) {
@@ -9427,7 +13577,6 @@ void CLASS write_ppm_tiff()
   else
     fprintf (ofp, "P%d\n%d %d\n%d\n",
 	colors/2+5, width, height, (1 << output_bps)-1);
-
   soff  = flip_index (0, 0);
   cstep = flip_index (0, 1) - soff;
   rstep = flip_index (1, 0) - flip_index (0, width);
@@ -9437,9 +13586,8 @@ void CLASS write_ppm_tiff()
 	   FORCC ppm [col*colors+c] = curve[image[soff][c]] >> 8;
       else FORCC ppm2[col*colors+c] = curve[image[soff][c]];
     if (output_bps == 16 && !output_tiff && htons(0x55aa) != 0x55aa)
-        swab ((char*)ppm2, (char*)ppm2, width*colors*2);
+      swab ((char*)ppm2, (char*)ppm2, width*colors*2);
     fwrite (ppm, colors*output_bps/8, width, ofp);
   }
   free (ppm);
 }
-
diff --git a/Source/LibRawLite/internal/dcraw_fileio.cpp b/Source/LibRawLite/internal/dcraw_fileio.cpp
index ec796ce..b3a9066 100644
--- a/Source/LibRawLite/internal/dcraw_fileio.cpp
+++ b/Source/LibRawLite/internal/dcraw_fileio.cpp
@@ -1,5 +1,5 @@
 /* 
-  Copyright 2008-2010 LibRaw LLC (info at libraw.org)
+  Copyright 2008-2013 LibRaw LLC (info at libraw.org)
 
 LibRaw is free software; you can redistribute it and/or modify
 it under the terms of the one of three licenses as you choose:
@@ -21,6 +21,7 @@ it under the terms of the one of three licenses as you choose:
    for more information
 */
 
+#line 4777 "dcraw/dcraw.c"
 #include <math.h>
 #define CLASS LibRaw::
 #include "libraw/libraw_types.h"
@@ -28,14 +29,14 @@ it under the terms of the one of three licenses as you choose:
 #include "libraw/libraw.h"
 #include "internal/defines.h"
 #include "internal/var_defines.h"
-
+#line 4788 "dcraw/dcraw.c"
 /*
    Seach from the current directory up to the root looking for
    a ".badpixels" file, and fix those pixels now.
  */
 void CLASS bad_pixels (const char *cfname)
 {
-  FILE *fp=0;
+  FILE *fp=NULL;
 #ifndef LIBRAW_LIBRARY_BUILD
   char *fname, *cp, line[128];
   int len, time, row, col, r, c, rad, tot, n, fixed=0;
@@ -53,7 +54,8 @@ void CLASS bad_pixels (const char *cfname)
 #endif
   if (cfname)
     fp = fopen (cfname, "r");
-  if (!fp) 
+#line 4838 "dcraw/dcraw.c"
+  if (!fp)
       {
 #ifdef LIBRAW_LIBRARY_BUILD
           imgdata.process_warnings |= LIBRAW_WARN_NO_BADPIXELMAP;
@@ -70,7 +72,7 @@ void CLASS bad_pixels (const char *cfname)
       for (r = row-rad; r <= row+rad; r++)
 	for (c = col-rad; c <= col+rad; c++)
 	  if ((unsigned) r < height && (unsigned) c < width &&
-		(r != row || c != col) && fc(r,c) == fc(row,col)) {
+		(r != row || c != col) && fcol(r,c) == fcol(row,col)) {
 	    tot += BAYER2(r,c);
 	    n++;
 	  }
@@ -103,7 +105,7 @@ void CLASS subtract (const char *fname)
 
   if (!(fp = fopen (fname, "rb"))) {
 #ifdef DCRAW_VERBOSE
-    perror (fname); 
+    perror (fname);
 #endif
 #ifdef LIBRAW_LIBRARY_BUILD
     imgdata.process_warnings |= LIBRAW_WARN_BAD_DARKFRAME_FILE;
@@ -124,7 +126,9 @@ void CLASS subtract (const char *fname)
     }
   }
   if (error || nd < 3) {
+#ifdef DCRAW_VERBOSE
     fprintf (stderr,_("%s is not a valid PGM file!\n"), fname);
+#endif
     fclose (fp);  return;
   } else if (dim[0] != width || dim[1] != height || dim[2] != 65535) {
 #ifdef DCRAW_VERBOSE
@@ -150,7 +154,7 @@ void CLASS subtract (const char *fname)
   RUN_CALLBACK(LIBRAW_PROGRESS_DARK_FRAME,1,2);
 #endif
 }
-
+#line 14498 "dcraw/dcraw.c"
 #ifndef NO_LCMS
 void CLASS apply_profile (const char *input, const char *output)
 {
@@ -160,9 +164,6 @@ void CLASS apply_profile (const char *input, const char *output)
   FILE *fp;
   unsigned size;
 
-#ifndef USE_LCMS2
-  cmsErrorAction (LCMS_ERROR_SHOW);
-#endif
   if (strcmp (input, "embed"))
     hInProfile = cmsOpenProfileFromFile (input, "r");
   else if (profile_length) {
@@ -177,14 +178,14 @@ void CLASS apply_profile (const char *input, const char *output)
     hInProfile = cmsOpenProfileFromMem (imgdata.color.profile, profile_length);
 #endif
   } else
-      {
+    {
 #ifdef LIBRAW_LIBRARY_BUILD
           imgdata.process_warnings |= LIBRAW_WARN_NO_EMBEDDED_PROFILE;
 #endif
 #ifdef DCRAW_VERBOSE
           fprintf (stderr,_("%s has no embedded profile.\n"), ifname);
 #endif
-      }
+    }
   if (!hInProfile)
       {
 #ifdef LIBRAW_LIBRARY_BUILD
@@ -205,11 +206,10 @@ void CLASS apply_profile (const char *input, const char *output)
       free (oprof);
       oprof = 0;
     }
+  }
 #ifdef DCRAW_VERBOSE
-  } else
+ else
     fprintf (stderr,_("Cannot open file %s!\n"), output);
-#else
-}
 #endif
   if (!hOutProfile)
       {
diff --git a/Source/LibRawLite/internal/defines.h b/Source/LibRawLite/internal/defines.h
index 2fb5bb8..ae389c1 100644
--- a/Source/LibRawLite/internal/defines.h
+++ b/Source/LibRawLite/internal/defines.h
@@ -1,5 +1,5 @@
 /* 
-  Copyright 2008-2010 LibRaw LLC (info at libraw.org)
+  Copyright 2008-2013 LibRaw LLC (info at libraw.org)
 
 LibRaw is free software; you can redistribute it and/or modify
 it under the terms of the one of three licenses as you choose:
@@ -21,11 +21,15 @@ it under the terms of the one of three licenses as you choose:
    for more information
 */
 
+#line 33 "dcraw/dcraw.c"
+#ifndef USE_JPEG
 #define NO_JPEG
+#endif
 #ifndef USE_JASPER
 #define NO_JASPER
 #endif
-#define DCRAW_VERSION "9.12"
+#line 44 "dcraw/dcraw.c"
+#define DCRAW_VERSION "9.24"
 
 #ifndef _GNU_SOURCE
 #define _GNU_SOURCE
@@ -43,26 +47,44 @@ it under the terms of the one of three licenses as you choose:
 #include <string.h>
 #include <time.h>
 #include <sys/types.h>
+#line 71 "dcraw/dcraw.c"
+#ifdef __CYGWIN__
+#include <io.h>
+#endif
+#ifdef WIN32
+#include <sys/utime.h>
+#include <winsock2.h>
+#pragma comment(lib, "ws2_32.lib")
+#define snprintf _snprintf
+#define strcasecmp stricmp
+#define strncasecmp strnicmp
+#line 85 "dcraw/dcraw.c"
+#else
+#include <unistd.h>
+#include <utime.h>
+#include <netinet/in.h>
+#include <stdint.h>
+typedef int64_t INT64;
+typedef uint64_t UINT64;
+#endif
 
-/*
-   NO_JPEG disables decoding of compressed Kodak DC120 files.
-   NO_LCMS disables the "-p" option.
- */
 #ifdef NODEPS
 #define NO_JASPER
 #define NO_JPEG
 #define NO_LCMS
 #endif
 #ifndef NO_JASPER
-#undef PACKAGE_BUGREPORT
-#undef PACKAGE_NAME
-#undef PACKAGE_STRING
-#undef PACKAGE_TARNAME
-#undef PACKAGE_VERSION
-#include <jasper/jasper.h>	/* Decode RED camera movies */
+#include <jasper/jasper.h>	/* Decode Red camera movies */
 #endif
 #ifndef NO_JPEG
 #include <jpeglib.h>		/* Decode compressed Kodak DC120 photos */
+#endif				/* and Adobe Lossy DNGs */
+#ifndef NO_LCMS
+#ifdef USE_LCMS
+#include <lcms.h>		/* Support color profiles */
+#else
+#include <lcms2.h>		/* Support color profiles */
+#endif
 #endif
 #ifdef LOCALEDIR
 #include <libintl.h>
@@ -70,21 +92,6 @@ it under the terms of the one of three licenses as you choose:
 #else
 #define _(String) (String)
 #endif
-#ifdef __CYGWIN__
-#include <io.h>
-#endif
-#ifdef WIN32
-#include <sys/utime.h>
-#include <winsock2.h>
-#pragma comment(lib, "ws2_32.lib")
-#define snprintf _snprintf
-#define strcasecmp _stricmp
-#define strncasecmp strnicmp
-#else
-#include <unistd.h>
-#include <utime.h>
-#include <netinet/in.h>
-#endif
 
 #ifdef LJPEG_DECODE
 #error Please compile dcraw.c by itself.
@@ -94,6 +101,7 @@ it under the terms of the one of three licenses as you choose:
 #ifndef LONG_BIT
 #define LONG_BIT (8 * sizeof (long))
 #endif
+#line 199 "dcraw/dcraw.c"
 #define FORC(cnt) for (c=0; c < cnt; c++)
 #define FORC3 FORC(3)
 #define FORC4 FORC(4)
@@ -108,6 +116,8 @@ it under the terms of the one of three licenses as you choose:
 #define CLIP(x) LIM(x,0,65535)
 #define SWAP(a,b) { a=a+b; b=a-b; a=a-b; }
 
+#define my_swap(type, i, j) {type t = i; i = j; j = t;}
+
 /*
    In order to inline this calculation, I make the risky
    assumption that all filter patterns can be described
@@ -147,7 +157,11 @@ it under the terms of the one of three licenses as you choose:
 	3 G R G R G R	3 B G B G B G	3 R G R G R G	3 G B G B G B
  */
 
+#define RAW(row,col) \
+	raw_image[(row)*raw_width+(col)]
+#line 262 "dcraw/dcraw.c"
 #define BAYER(row,col) \
 	image[((row) >> shrink)*iwidth + ((col) >> shrink)][FC(row,col)]
+
 #define BAYER2(row,col) \
-	image[((row) >> shrink)*iwidth + ((col) >> shrink)][fc(row,col)]
+	image[((row) >> shrink)*iwidth + ((col) >> shrink)][fcol(row,col)]
diff --git a/Source/LibRawLite/internal/demosaic_packs.cpp b/Source/LibRawLite/internal/demosaic_packs.cpp
index 874fc10..3350064 100644
--- a/Source/LibRawLite/internal/demosaic_packs.cpp
+++ b/Source/LibRawLite/internal/demosaic_packs.cpp
@@ -1,5 +1,5 @@
 /* 
-  Copyright 2008-2010 LibRaw LLC (info at libraw.org)
+  Copyright 2008-2013 LibRaw LLC (info at libraw.org)
 
 LibRaw is free software; you can redistribute it and/or modify
 it under the terms of the one of three licenses as you choose:
@@ -34,6 +34,13 @@ it under the terms of the one of three licenses as you choose:
 #define SRC_USES_BLACK
 #define SRC_USES_CURVE
 
+/* WF filtering is allowed to triple libraw license */
+#include "./wf_filtering.cpp"
+/* DHT and AAHD are LGPL licensed, so include them */
+#include "./dht_demosaic.cpp"
+#include "./aahd_demosaic.cpp"
+
+
 #include "internal/var_defines.h"
 
 
@@ -66,6 +73,7 @@ void CLASS refinement() {}
 /* DCB is BSD licensed, so include it */
 #include "./dcb_demosaicing.c"
 
+
 #ifdef LIBRAW_DEMOSAIC_PACK_GPL3
 /*AMaZE*/
 #include <amaze_demosaic_RT.cc>
@@ -88,10 +96,4 @@ void CLASS cfa_impulse_gauss(float lclean, float cclean){}
 #endif
 #ifdef LIBRAW_DEMOSAIC_PACK_GPL2
 #include <dcraw_foveon.c>
-#else
-void CLASS foveon_interpolate(){}
-void CLASS foveon_load_raw(){}
-void CLASS parse_foveon(){}
-void CLASS foveon_thumb_loader(){}
-void CLASS foveon_thumb(){}
 #endif
diff --git a/Source/LibRawLite/internal/dht_demosaic.cpp b/Source/LibRawLite/internal/dht_demosaic.cpp
new file mode 100644
index 0000000..030e0ba
--- /dev/null
+++ b/Source/LibRawLite/internal/dht_demosaic.cpp
@@ -0,0 +1,873 @@
+/* -*- C++ -*-
+ * File: dht_demosaic.cpp
+ * Copyright 2013 Anton Petrusevich
+ * Created: Tue Apr  9, 2013
+ *
+ * This code is licensed under one of three licenses as you choose:
+ *
+ * 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
+ *    (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
+ *
+ * 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
+ *    (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
+ *
+ * 3. LibRaw Software License 27032010
+ *    (See file LICENSE.LibRaw.pdf provided in LibRaw distribution archive for details).
+ *
+ */
+
+/*
+ * функция вычисляет яркостную дистанцию.
+ * если две яркости отличаются в два раза, например 10 и 20, то они имеют такой же вес
+ * при принятии решения об интерполировании, как и 100 и 200 -- фотографическая яркость между ними 1 стоп.
+ * дистанция всегда >=1
+ */
+static inline float calc_dist(float c1, float c2) {
+	return c1 > c2 ? c1 / c2 : c2 / c1;
+}
+
+struct DHT {
+	int nr_height, nr_width;
+	static const int nr_topmargin = 4, nr_leftmargin = 4;
+	float (*nraw)[3];
+	ushort channel_maximum[3];
+	float channel_minimum[3];
+	LibRaw &libraw;
+	enum {
+		HVSH = 1,
+		HOR = 2,
+		VER = 4,
+		HORSH = HOR | HVSH,
+		VERSH = VER | HVSH,
+		DIASH = 8,
+		LURD = 16,
+		RULD = 32,
+		LURDSH = LURD | DIASH,
+		RULDSH = RULD | DIASH,
+		HOT = 64
+	};
+	static inline float Thot(void) throw () {
+		return 64.0f;
+	}
+	static inline float Tg(void) throw () {
+		return 256.0f;
+	}
+	static inline float T(void) throw () {
+		return 1.4f;
+	}
+	char *ndir;
+	inline int nr_offset(int row, int col) throw () {
+		return (row * nr_width + col);
+	}
+	int get_hv_grb(int x, int y, int kc) {
+		float hv1 = 2 * nraw[nr_offset(y - 1, x)][1]
+				/ (nraw[nr_offset(y - 2, x)][kc] + nraw[nr_offset(y, x)][kc]);
+		float hv2 = 2 * nraw[nr_offset(y + 1, x)][1]
+				/ (nraw[nr_offset(y + 2, x)][kc] + nraw[nr_offset(y, x)][kc]);
+		float kv = calc_dist(hv1, hv2)
+				* calc_dist(nraw[nr_offset(y, x)][kc] * nraw[nr_offset(y, x)][kc],
+						(nraw[nr_offset(y - 2, x)][kc] * nraw[nr_offset(y + 2, x)][kc]));
+		kv *= kv;
+		kv *= kv;
+		kv *= kv;
+		float dv = kv
+				* calc_dist(nraw[nr_offset(y - 3, x)][1] * nraw[nr_offset(y + 3, x)][1],
+						nraw[nr_offset(y - 1, x)][1] * nraw[nr_offset(y + 1, x)][1]);
+		float hh1 = 2 * nraw[nr_offset(y, x - 1)][1]
+				/ (nraw[nr_offset(y, x - 2)][kc] + nraw[nr_offset(y, x)][kc]);
+		float hh2 = 2 * nraw[nr_offset(y, x + 1)][1]
+				/ (nraw[nr_offset(y, x + 2)][kc] + nraw[nr_offset(y, x)][kc]);
+		float kh = calc_dist(hh1, hh2)
+				* calc_dist(nraw[nr_offset(y, x)][kc] * nraw[nr_offset(y, x)][kc],
+						(nraw[nr_offset(y, x - 2)][kc] * nraw[nr_offset(y, x + 2)][kc]));
+		kh *= kh;
+		kh *= kh;
+		kh *= kh;
+		float dh = kh
+				* calc_dist(nraw[nr_offset(y, x - 3)][1] * nraw[nr_offset(y, x + 3)][1],
+						nraw[nr_offset(y, x - 1)][1] * nraw[nr_offset(y, x + 1)][1]);
+		float e = calc_dist(dh, dv);
+		char d = dh < dv ? (e > Tg() ? HORSH : HOR) : (e > Tg() ? VERSH : VER);
+		return d;
+	}
+	int get_hv_rbg(int x, int y, int hc) {
+		float hv1 = 2 * nraw[nr_offset(y - 1, x)][hc ^ 2]
+				/ (nraw[nr_offset(y - 2, x)][1] + nraw[nr_offset(y, x)][1]);
+		float hv2 = 2 * nraw[nr_offset(y + 1, x)][hc ^ 2]
+				/ (nraw[nr_offset(y + 2, x)][1] + nraw[nr_offset(y, x)][1]);
+		float kv = calc_dist(hv1, hv2)
+				* calc_dist(nraw[nr_offset(y, x)][1] * nraw[nr_offset(y, x)][1],
+						(nraw[nr_offset(y - 2, x)][1] * nraw[nr_offset(y + 2, x)][1]));
+		kv *= kv;
+		kv *= kv;
+		kv *= kv;
+		float dv = kv
+				* calc_dist(nraw[nr_offset(y - 3, x)][hc ^ 2] * nraw[nr_offset(y + 3, x)][hc ^ 2],
+						nraw[nr_offset(y - 1, x)][hc ^ 2] * nraw[nr_offset(y + 1, x)][hc ^ 2]);
+		float hh1 = 2 * nraw[nr_offset(y, x - 1)][hc]
+				/ (nraw[nr_offset(y, x - 2)][1] + nraw[nr_offset(y, x)][1]);
+		float hh2 = 2 * nraw[nr_offset(y, x + 1)][hc]
+				/ (nraw[nr_offset(y, x + 2)][1] + nraw[nr_offset(y, x)][1]);
+		float kh = calc_dist(hh1, hh2)
+				* calc_dist(nraw[nr_offset(y, x)][1] * nraw[nr_offset(y, x)][1],
+						(nraw[nr_offset(y, x - 2)][1] * nraw[nr_offset(y, x + 2)][1]));
+		kh *= kh;
+		kh *= kh;
+		kh *= kh;
+		float dh = kh
+				* calc_dist(nraw[nr_offset(y, x - 3)][hc] * nraw[nr_offset(y, x + 3)][hc],
+						nraw[nr_offset(y, x - 1)][hc] * nraw[nr_offset(y, x + 1)][hc]);
+		float e = calc_dist(dh, dv);
+		char d = dh < dv ? (e > Tg() ? HORSH : HOR) : (e > Tg() ? VERSH : VER);
+		return d;
+	}
+	int get_diag_grb(int x, int y, int kc) {
+		float hlu = nraw[nr_offset(y - 1, x - 1)][1] / nraw[nr_offset(y - 1, x - 1)][kc];
+		float hrd = nraw[nr_offset(y + 1, x + 1)][1] / nraw[nr_offset(y + 1, x + 1)][kc];
+		float hru = nraw[nr_offset(y - 1, x + 1)][1] / nraw[nr_offset(y - 1, x + 1)][kc];
+		float hld = nraw[nr_offset(y + 1, x - 1)][1] / nraw[nr_offset(y + 1, x - 1)][kc];
+		float dlurd = calc_dist(hlu, hrd)
+				* calc_dist(nraw[nr_offset(y - 1, x - 1)][1] * nraw[nr_offset(y + 1, x + 1)][1],
+						nraw[nr_offset(y, x)][1] * nraw[nr_offset(y, x)][1]);
+		float druld = calc_dist(hlu, hrd)
+				* calc_dist(nraw[nr_offset(y - 1, x + 1)][1] * nraw[nr_offset(y + 1, x - 1)][1],
+						nraw[nr_offset(y, x)][1] * nraw[nr_offset(y, x)][1]);
+		float e = calc_dist(dlurd, druld);
+		char d = druld < dlurd ? (e > T() ? RULDSH : RULD) : (e > T() ? LURDSH : LURD);
+		return d;
+	}
+	int get_diag_rbg(int x, int y, int hc) {
+		float dlurd = calc_dist(nraw[nr_offset(y - 1, x - 1)][1] * nraw[nr_offset(y + 1, x + 1)][1],
+				nraw[nr_offset(y, x)][1] * nraw[nr_offset(y, x)][1]);
+		float druld = calc_dist(nraw[nr_offset(y - 1, x + 1)][1] * nraw[nr_offset(y + 1, x - 1)][1],
+				nraw[nr_offset(y, x)][1] * nraw[nr_offset(y, x)][1]);
+		float e = calc_dist(dlurd, druld);
+		char d = druld < dlurd ? (e > T() ? RULDSH : RULD) : (e > T() ? LURDSH : LURD);
+		return d;
+	}
+	static inline float scale_over(float ec, float base) {
+		float s = base * .4;
+		float o = ec - base;
+		return base + sqrt(s * (o + s)) - s;
+	}
+	static inline float scale_under(float ec, float base) {
+		float s = base * .6;
+		float o = base - ec;
+		return base - sqrt(s * (o + s)) + s;
+	}
+	~DHT();
+	DHT(LibRaw &_libraw);
+	void copy_to_image();
+	void make_greens();
+	void make_diag_dirs();
+	void make_hv_dirs();
+	void refine_hv_dirs(int i, int js);
+	void refine_diag_dirs(int i, int js);
+	void refine_ihv_dirs(int i);
+	void refine_idiag_dirs(int i);
+	void illustrate_dirs();
+	void illustrate_dline(int i);
+	void make_hv_dline(int i);
+	void make_diag_dline(int i);
+	void make_gline(int i);
+	void make_rbdiag(int i);
+	void make_rbhv(int i);
+	void make_rb();
+	void hide_hots();
+	void restore_hots();
+};
+
+typedef float float3[3];
+
+/*
+ * информация о цветах копируется во float в общем то с одной целью -- чтобы вместо 0 можно было писать 0.5,
+ * что больше подходит для вычисления яркостной разницы.
+ * причина: в целых числах разница в 1 стоп составляет ряд 8,4,2,1,0 -- последнее число должно быть 0.5,
+ * которое непредствамио в целых числах.
+ * так же это изменение позволяет не думать о специальных случаях деления на ноль.
+ *
+ * альтернативное решение: умножить все данные на 2 и в младший бит внести 1. правда,
+ * всё равно придётся следить, чтобы при интерпретации зелёного цвета не получился 0 при округлении,
+ * иначе проблема при интерпретации синих и красных.
+ *
+ */
+DHT::DHT(LibRaw& _libraw) :
+		libraw(_libraw) {
+	nr_height = libraw.imgdata.sizes.iheight + nr_topmargin * 2;
+	nr_width = libraw.imgdata.sizes.iwidth + nr_leftmargin * 2;
+	nraw = (float3*) malloc(nr_height * nr_width * sizeof(float3));
+	int iwidth = libraw.imgdata.sizes.iwidth;
+	ndir = (char*) calloc(nr_height * nr_width, 1);
+	channel_maximum[0] = channel_maximum[1] = channel_maximum[2] = 0;
+	channel_minimum[0] = libraw.imgdata.image[0][0];
+	channel_minimum[1] = libraw.imgdata.image[0][1];
+	channel_minimum[2] = libraw.imgdata.image[0][2];
+	for (int i = 0; i < nr_height * nr_width; ++i)
+		nraw[i][0] = nraw[i][1] = nraw[i][2] = 0.5;
+	for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) {
+		int col_cache[48];
+		for (int j = 0; j < 48; ++j) {
+			int l = libraw.COLOR(i, j);
+			if (l == 3)
+				l = 1;
+			col_cache[j] = l;
+		}
+		for (int j = 0; j < iwidth; ++j) {
+			int l = col_cache[j % 48];
+			unsigned short c = libraw.imgdata.image[i * iwidth + j][l];
+			if (c != 0) {
+				if (channel_maximum[l] < c)
+					channel_maximum[l] = c;
+				if (channel_minimum[l] > c)
+					channel_minimum[l] = c;
+				nraw[nr_offset(i + nr_topmargin, j + nr_leftmargin)][l] = (float) c;
+			}
+		}
+	}
+	channel_minimum[0] += .5;
+	channel_minimum[1] += .5;
+	channel_minimum[2] += .5;
+}
+
+void DHT::hide_hots() {
+	int iwidth = libraw.imgdata.sizes.iwidth;
+#if defined(LIBRAW_USE_OPENMP)
+#pragma omp parallel for schedule(guided) firstprivate(iwidth)
+#endif
+	for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) {
+		int js = libraw.COLOR(i, 0) & 1;
+		int kc = libraw.COLOR(i, js);
+		/*
+		 * js -- начальная х-координата, которая попадает мимо известного зелёного
+		 * kc -- известный цвет в точке интерполирования
+		 */
+		for (int j = js; j < iwidth; j += 2) {
+			int x = j + nr_leftmargin;
+			int y = i + nr_topmargin;
+			float c = nraw[nr_offset(y, x)][kc];
+			if ((c > nraw[nr_offset(y, x + 2)][kc] && c > nraw[nr_offset(y, x - 2)][kc]
+					&& c > nraw[nr_offset(y - 2, x)][kc] && c > nraw[nr_offset(y + 2, x)][kc]
+					&& c > nraw[nr_offset(y, x + 1)][1] && c > nraw[nr_offset(y, x - 1)][1]
+					&& c > nraw[nr_offset(y - 1, x)][1] && c > nraw[nr_offset(y + 1, x)][1])
+					|| (c < nraw[nr_offset(y, x + 2)][kc] && c < nraw[nr_offset(y, x - 2)][kc]
+							&& c < nraw[nr_offset(y - 2, x)][kc]
+							&& c < nraw[nr_offset(y + 2, x)][kc] && c < nraw[nr_offset(y, x + 1)][1]
+							&& c < nraw[nr_offset(y, x - 1)][1] && c < nraw[nr_offset(y - 1, x)][1]
+							&& c < nraw[nr_offset(y + 1, x)][1])) {
+				float avg = 0;
+				for (int k = -2; k < 3; k += 2)
+					for (int m = -2; m < 3; m += 2)
+						if (m == 0 && k == 0)
+							continue;
+						else
+							avg += nraw[nr_offset(y + k, x + m)][kc];
+				avg /= 8;
+//				float dev = 0;
+//				for (int k = -2; k < 3; k += 2)
+//					for (int l = -2; l < 3; l += 2)
+//						if (k == 0 && l == 0)
+//							continue;
+//						else {
+//							float t = nraw[nr_offset(y + k, x + l)][kc] - avg;
+//							dev += t * t;
+//						}
+//				dev /= 8;
+//				dev = sqrt(dev);
+				if (calc_dist(c, avg) > Thot()) {
+					ndir[nr_offset(y, x)] |= HOT;
+					float dv = calc_dist(
+							nraw[nr_offset(y - 2, x)][kc] * nraw[nr_offset(y - 1, x)][1],
+							nraw[nr_offset(y + 2, x)][kc] * nraw[nr_offset(y + 1, x)][1]);
+					float dh = calc_dist(
+							nraw[nr_offset(y, x - 2)][kc] * nraw[nr_offset(y, x - 1)][1],
+							nraw[nr_offset(y, x + 2)][kc] * nraw[nr_offset(y, x + 1)][1]);
+					if (dv > dh)
+						nraw[nr_offset(y, x)][kc] = (nraw[nr_offset(y, x + 2)][kc]
+								+ nraw[nr_offset(y, x - 2)][kc]) / 2;
+					else
+						nraw[nr_offset(y, x)][kc] = (nraw[nr_offset(y - 2, x)][kc]
+								+ nraw[nr_offset(y + 2, x)][kc]) / 2;
+				}
+			}
+		}
+		for (int j = js ^ 1; j < iwidth; j += 2) {
+			int x = j + nr_leftmargin;
+			int y = i + nr_topmargin;
+			float c = nraw[nr_offset(y, x)][1];
+			if ((c > nraw[nr_offset(y, x + 2)][1] && c > nraw[nr_offset(y, x - 2)][1]
+					&& c > nraw[nr_offset(y - 2, x)][1] && c > nraw[nr_offset(y + 2, x)][1]
+					&& c > nraw[nr_offset(y, x + 1)][kc] && c > nraw[nr_offset(y, x - 1)][kc]
+					&& c > nraw[nr_offset(y - 1, x)][kc ^ 2]
+					&& c > nraw[nr_offset(y + 1, x)][kc ^ 2])
+					|| (c < nraw[nr_offset(y, x + 2)][1] && c < nraw[nr_offset(y, x - 2)][1]
+							&& c < nraw[nr_offset(y - 2, x)][1] && c < nraw[nr_offset(y + 2, x)][1]
+							&& c < nraw[nr_offset(y, x + 1)][kc]
+							&& c < nraw[nr_offset(y, x - 1)][kc]
+							&& c < nraw[nr_offset(y - 1, x)][kc ^ 2]
+							&& c < nraw[nr_offset(y + 1, x)][kc ^ 2])) {
+				float avg = 0;
+				for (int k = -2; k < 3; k += 2)
+					for (int m = -2; m < 3; m += 2)
+						if (k == 0 && m == 0)
+							continue;
+						else
+							avg += nraw[nr_offset(y + k, x + m)][1];
+				avg /= 8;
+//				float dev = 0;
+//				for (int k = -2; k < 3; k += 2)
+//					for (int l = -2; l < 3; l += 2)
+//						if (k == 0 && l == 0)
+//							continue;
+//						else {
+//							float t = nraw[nr_offset(y + k, x + l)][1] - avg;
+//							dev += t * t;
+//						}
+//				dev /= 8;
+//				dev = sqrt(dev);
+				if (calc_dist(c, avg) > Thot()) {
+					ndir[nr_offset(y, x)] |= HOT;
+					float dv = calc_dist(
+							nraw[nr_offset(y - 2, x)][1] * nraw[nr_offset(y - 1, x)][kc ^ 2],
+							nraw[nr_offset(y + 2, x)][1] * nraw[nr_offset(y + 1, x)][kc ^ 2]);
+					float dh = calc_dist(
+							nraw[nr_offset(y, x - 2)][1] * nraw[nr_offset(y, x - 1)][kc],
+							nraw[nr_offset(y, x + 2)][1] * nraw[nr_offset(y, x + 1)][kc]);
+					if (dv > dh)
+						nraw[nr_offset(y, x)][1] = (nraw[nr_offset(y, x + 2)][1]
+								+ nraw[nr_offset(y, x - 2)][1]) / 2;
+					else
+						nraw[nr_offset(y, x)][1] = (nraw[nr_offset(y - 2, x)][1]
+								+ nraw[nr_offset(y + 2, x)][1]) / 2;
+				}
+			}
+		}
+	}
+}
+
+void DHT::restore_hots() {
+	int iwidth = libraw.imgdata.sizes.iwidth;
+#if defined(LIBRAW_USE_OPENMP)
+#ifdef WIN32
+#pragma omp parallel for firstprivate(iwidth)
+#else
+#pragma omp parallel for schedule(guided) firstprivate(iwidth) collapse(2)
+#endif
+#endif
+	for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) {
+		for (int j = 0; j < iwidth; ++j) {
+			int x = j + nr_leftmargin;
+			int y = i + nr_topmargin;
+			if (ndir[nr_offset(y, x)] & HOT) {
+				int l = libraw.COLOR(i, j);
+				nraw[nr_offset(i + nr_topmargin, j + nr_leftmargin)][l] = libraw.imgdata.image[i
+						* iwidth + j][l];
+			}
+		}
+	}
+}
+
+void DHT::make_diag_dirs() {
+#if defined(LIBRAW_USE_OPENMP)
+#pragma omp parallel for schedule(guided)
+#endif
+	for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) {
+		make_diag_dline(i);
+	}
+//#if defined(LIBRAW_USE_OPENMP)
+//#pragma omp parallel for schedule(guided)
+//#endif
+//	for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) {
+//		refine_diag_dirs(i, i & 1);
+//	}
+//#if defined(LIBRAW_USE_OPENMP)
+//#pragma omp parallel for schedule(guided)
+//#endif
+//	for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) {
+//		refine_diag_dirs(i, (i & 1) ^ 1);
+//	}
+#if defined(LIBRAW_USE_OPENMP)
+#pragma omp parallel for schedule(guided)
+#endif
+	for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) {
+		refine_idiag_dirs(i);
+	}
+}
+
+void DHT::make_hv_dirs() {
+#if defined(LIBRAW_USE_OPENMP)
+#pragma omp parallel for schedule(guided)
+#endif
+	for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) {
+		make_hv_dline(i);
+	}
+#if defined(LIBRAW_USE_OPENMP)
+#pragma omp parallel for schedule(guided)
+#endif
+	for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) {
+		refine_hv_dirs(i, i & 1);
+	}
+#if defined(LIBRAW_USE_OPENMP)
+#pragma omp parallel for schedule(guided)
+#endif
+	for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) {
+		refine_hv_dirs(i, (i & 1) ^ 1);
+	}
+#if defined(LIBRAW_USE_OPENMP)
+#pragma omp parallel for schedule(guided)
+#endif
+	for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) {
+		refine_ihv_dirs(i);
+	}
+}
+
+void DHT::refine_hv_dirs(int i, int js) {
+	int iwidth = libraw.imgdata.sizes.iwidth;
+	for (int j = js; j < iwidth; j += 2) {
+		int x = j + nr_leftmargin;
+		int y = i + nr_topmargin;
+		if (ndir[nr_offset(y, x)] & HVSH)
+			continue;
+		int nv = (ndir[nr_offset(y - 1, x)] & VER) + (ndir[nr_offset(y + 1, x)] & VER)
+				+ (ndir[nr_offset(y, x - 1)] & VER) + (ndir[nr_offset(y, x + 1)] & VER);
+		int nh = (ndir[nr_offset(y - 1, x)] & HOR) + (ndir[nr_offset(y + 1, x)] & HOR)
+				+ (ndir[nr_offset(y, x - 1)] & HOR) + (ndir[nr_offset(y, x + 1)] & HOR);
+		bool codir =
+				(ndir[nr_offset(y, x)] & VER) ?
+						((ndir[nr_offset(y - 1, x)] & VER) || (ndir[nr_offset(y + 1, x)] & VER)) :
+						((ndir[nr_offset(y, x - 1)] & HOR) || (ndir[nr_offset(y, x + 1)] & HOR));
+		nv /= VER;
+		nh /= HOR;
+		if ((ndir[nr_offset(y, x)] & VER) && (nh > 2 && !codir)) {
+			ndir[nr_offset(y, x)] &= ~VER;
+			ndir[nr_offset(y, x)] |= HOR;
+		}
+		if ((ndir[nr_offset(y, x)] & HOR) && (nv > 2 && !codir)) {
+			ndir[nr_offset(y, x)] &= ~HOR;
+			ndir[nr_offset(y, x)] |= VER;
+		}
+	}
+}
+
+void DHT::refine_ihv_dirs(int i) {
+	int iwidth = libraw.imgdata.sizes.iwidth;
+	for (int j = 0; j < iwidth; j++) {
+		int x = j + nr_leftmargin;
+		int y = i + nr_topmargin;
+		if (ndir[nr_offset(y, x)] & HVSH)
+			continue;
+		int nv = (ndir[nr_offset(y - 1, x)] & VER) + (ndir[nr_offset(y + 1, x)] & VER)
+				+ (ndir[nr_offset(y, x - 1)] & VER) + (ndir[nr_offset(y, x + 1)] & VER);
+		int nh = (ndir[nr_offset(y - 1, x)] & HOR) + (ndir[nr_offset(y + 1, x)] & HOR)
+				+ (ndir[nr_offset(y, x - 1)] & HOR) + (ndir[nr_offset(y, x + 1)] & HOR);
+		nv /= VER;
+		nh /= HOR;
+		if ((ndir[nr_offset(y, x)] & VER) && nh > 3) {
+			ndir[nr_offset(y, x)] &= ~VER;
+			ndir[nr_offset(y, x)] |= HOR;
+		}
+		if ((ndir[nr_offset(y, x)] & HOR) && nv > 3) {
+			ndir[nr_offset(y, x)] &= ~HOR;
+			ndir[nr_offset(y, x)] |= VER;
+		}
+	}
+}
+void DHT::make_hv_dline(int i) {
+	int iwidth = libraw.imgdata.sizes.iwidth;
+	int js = libraw.COLOR(i, 0) & 1;
+	int kc = libraw.COLOR(i, js);
+	/*
+	 * js -- начальная х-координата, которая попадает мимо известного зелёного
+	 * kc -- известный цвет в точке интерполирования
+	 */
+	for (int j = 0; j < iwidth; j++) {
+		int x = j + nr_leftmargin;
+		int y = i + nr_topmargin;
+		char d = 0;
+		if ((j & 1) == js) {
+			d = get_hv_grb(x, y, kc);
+		} else {
+			d = get_hv_rbg(x, y, kc);
+		}
+		ndir[nr_offset(y, x)] |= d;
+	}
+}
+
+void DHT::make_diag_dline(int i) {
+	int iwidth = libraw.imgdata.sizes.iwidth;
+	int js = libraw.COLOR(i, 0) & 1;
+	int kc = libraw.COLOR(i, js);
+	/*
+	 * js -- начальная х-координата, которая попадает мимо известного зелёного
+	 * kc -- известный цвет в точке интерполирования
+	 */
+	for (int j = 0; j < iwidth; j++) {
+		int x = j + nr_leftmargin;
+		int y = i + nr_topmargin;
+		char d = 0;
+		if ((j & 1) == js) {
+			d = get_diag_grb(x, y, kc);
+		} else {
+			d = get_diag_rbg(x, y, kc);
+		}
+		ndir[nr_offset(y, x)] |= d;
+	}
+}
+
+void DHT::refine_diag_dirs(int i, int js) {
+	int iwidth = libraw.imgdata.sizes.iwidth;
+	for (int j = js; j < iwidth; j += 2) {
+		int x = j + nr_leftmargin;
+		int y = i + nr_topmargin;
+		if (ndir[nr_offset(y, x)] & DIASH)
+			continue;
+		int nv = (ndir[nr_offset(y - 1, x)] & LURD) + (ndir[nr_offset(y + 1, x)] & LURD)
+				+ (ndir[nr_offset(y, x - 1)] & LURD) + (ndir[nr_offset(y, x + 1)] & LURD)
+				+ (ndir[nr_offset(y - 1, x - 1)] & LURD) + (ndir[nr_offset(y - 1, x + 1)] & LURD)
+				+ (ndir[nr_offset(y + 1, x - 1)] & LURD) + (ndir[nr_offset(y + 1, x + 1)] & LURD);
+		int nh = (ndir[nr_offset(y - 1, x)] & RULD) + (ndir[nr_offset(y + 1, x)] & RULD)
+				+ (ndir[nr_offset(y, x - 1)] & RULD) + (ndir[nr_offset(y, x + 1)] & RULD)
+				+ (ndir[nr_offset(y - 1, x - 1)] & RULD) + (ndir[nr_offset(y - 1, x + 1)] & RULD)
+				+ (ndir[nr_offset(y + 1, x - 1)] & RULD) + (ndir[nr_offset(y + 1, x + 1)] & RULD);
+		bool codir =
+				(ndir[nr_offset(y, x)] & LURD) ?
+						((ndir[nr_offset(y - 1, x - 1)] & LURD)
+								|| (ndir[nr_offset(y + 1, x + 1)] & LURD)) :
+						((ndir[nr_offset(y - 1, x + 1)] & RULD)
+								|| (ndir[nr_offset(y + 1, x - 1)] & RULD));
+		nv /= LURD;
+		nh /= RULD;
+		if ((ndir[nr_offset(y, x)] & LURD) && (nh > 4 && !codir)) {
+			ndir[nr_offset(y, x)] &= ~LURD;
+			ndir[nr_offset(y, x)] |= RULD;
+		}
+		if ((ndir[nr_offset(y, x)] & RULD) && (nv > 4 && !codir)) {
+			ndir[nr_offset(y, x)] &= ~RULD;
+			ndir[nr_offset(y, x)] |= LURD;
+		}
+	}
+}
+
+void DHT::refine_idiag_dirs(int i) {
+	int iwidth = libraw.imgdata.sizes.iwidth;
+	for (int j = 0; j < iwidth; j++) {
+		int x = j + nr_leftmargin;
+		int y = i + nr_topmargin;
+		if (ndir[nr_offset(y, x)] & DIASH)
+			continue;
+		int nv = (ndir[nr_offset(y - 1, x)] & LURD) + (ndir[nr_offset(y + 1, x)] & LURD)
+				+ (ndir[nr_offset(y, x - 1)] & LURD) + (ndir[nr_offset(y, x + 1)] & LURD)
+				+ (ndir[nr_offset(y - 1, x - 1)] & LURD) + (ndir[nr_offset(y - 1, x + 1)] & LURD)
+				+ (ndir[nr_offset(y + 1, x - 1)] & LURD) + (ndir[nr_offset(y + 1, x + 1)] & LURD);
+		int nh = (ndir[nr_offset(y - 1, x)] & RULD) + (ndir[nr_offset(y + 1, x)] & RULD)
+				+ (ndir[nr_offset(y, x - 1)] & RULD) + (ndir[nr_offset(y, x + 1)] & RULD)
+				+ (ndir[nr_offset(y - 1, x - 1)] & RULD) + (ndir[nr_offset(y - 1, x + 1)] & RULD)
+				+ (ndir[nr_offset(y + 1, x - 1)] & RULD) + (ndir[nr_offset(y + 1, x + 1)] & RULD);
+		bool codir =
+				(ndir[nr_offset(y, x)] & LURD) ?
+						((ndir[nr_offset(y - 1, x - 1)] & LURD)
+								|| (ndir[nr_offset(y + 1, x + 1)] & LURD)) :
+						((ndir[nr_offset(y - 1, x + 1)] & RULD)
+								|| (ndir[nr_offset(y + 1, x - 1)] & RULD));
+		nv /= LURD;
+		nh /= RULD;
+		if ((ndir[nr_offset(y, x)] & LURD) && nh > 7) {
+			ndir[nr_offset(y, x)] &= ~LURD;
+			ndir[nr_offset(y, x)] |= RULD;
+		}
+		if ((ndir[nr_offset(y, x)] & RULD) && nv > 7) {
+			ndir[nr_offset(y, x)] &= ~RULD;
+			ndir[nr_offset(y, x)] |= LURD;
+		}
+	}
+}
+
+/*
+ * вычисление недостающих зелёных точек.
+ */
+void DHT::make_greens() {
+#if defined(LIBRAW_USE_OPENMP)
+#pragma omp parallel for schedule(guided)
+#endif
+	for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) {
+		make_gline(i);
+	}
+}
+
+void DHT::make_gline(int i) {
+	int iwidth = libraw.imgdata.sizes.iwidth;
+	int js = libraw.COLOR(i, 0) & 1;
+	int kc = libraw.COLOR(i, js);
+	/*
+	 * js -- начальная х-координата, которая попадает мимо известного зелёного
+	 * kc -- известный цвет в точке интерполирования
+	 */
+	for (int j = js; j < iwidth; j += 2) {
+		int x = j + nr_leftmargin;
+		int y = i + nr_topmargin;
+		int dx, dy, dx2, dy2;
+		float h1, h2;
+		if (ndir[nr_offset(y, x)] & VER) {
+			dx = dx2 = 0;
+			dy = -1;
+			dy2 = 1;
+			h1 = 2 * nraw[nr_offset(y - 1, x)][1]
+					/ (nraw[nr_offset(y - 2, x)][kc] + nraw[nr_offset(y, x)][kc]);
+			h2 = 2 * nraw[nr_offset(y + 1, x)][1]
+					/ (nraw[nr_offset(y + 2, x)][kc] + nraw[nr_offset(y, x)][kc]);
+		} else {
+			dy = dy2 = 0;
+			dx = 1;
+			dx2 = -1;
+			h1 = 2 * nraw[nr_offset(y, x + 1)][1]
+					/ (nraw[nr_offset(y, x + 2)][kc] + nraw[nr_offset(y, x)][kc]);
+			h2 = 2 * nraw[nr_offset(y, x - 1)][1]
+					/ (nraw[nr_offset(y, x - 2)][kc] + nraw[nr_offset(y, x)][kc]);
+		}
+		float b1 = 1
+				/ calc_dist(nraw[nr_offset(y, x)][kc], nraw[nr_offset(y + dy * 2, x + dx * 2)][kc]);
+		float b2 = 1
+				/ calc_dist(nraw[nr_offset(y, x)][kc],
+						nraw[nr_offset(y + dy2 * 2, x + dx2 * 2)][kc]);
+		b1 *= b1;
+		b2 *= b2;
+		float eg = nraw[nr_offset(y, x)][kc] * (b1 * h1 + b2 * h2) / (b1 + b2);
+		float min, max;
+		min = MIN(nraw[nr_offset(y + dy, x + dx)][1], nraw[nr_offset(y + dy2, x + dx2)][1]);
+		max = MAX(nraw[nr_offset(y + dy, x + dx)][1], nraw[nr_offset(y + dy2, x + dx2)][1]);
+		min /= 1.2;
+		max *= 1.2;
+		if (eg < min)
+			eg = scale_under(eg, min);
+		else if (eg > max)
+			eg = scale_over(eg, max);
+		if (eg > channel_maximum[1])
+			eg = channel_maximum[1];
+		else if (eg < channel_minimum[1])
+			eg = channel_minimum[1];
+		nraw[nr_offset(y, x)][1] = eg;
+	}
+}
+
+/*
+ * отладочная функция
+ */
+
+void DHT::illustrate_dirs() {
+#if defined(LIBRAW_USE_OPENMP)
+#pragma omp parallel for schedule(guided)
+#endif
+	for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) {
+		illustrate_dline(i);
+	}
+}
+
+void DHT::illustrate_dline(int i) {
+	int iwidth = libraw.imgdata.sizes.iwidth;
+	for (int j = 0; j < iwidth; j++) {
+		int x = j + nr_leftmargin;
+		int y = i + nr_topmargin;
+		nraw[nr_offset(y, x)][0] = nraw[nr_offset(y, x)][1] = nraw[nr_offset(y, x)][2] = 0.5;
+		int l = ndir[nr_offset(y, x)] & 8;
+		// l >>= 3; // WTF?
+		l = 1;
+		if (ndir[nr_offset(y, x)] & HOT)
+			nraw[nr_offset(y, x)][0] = l * channel_maximum[0] / 4 + channel_maximum[0] / 4;
+		else
+			nraw[nr_offset(y, x)][2] = l * channel_maximum[2] / 4 + channel_maximum[2] / 4;
+	}
+
+}
+
+/*
+ * интерполяция красных и синих.
+ *
+ * сначала интерполируются недостающие цвета, по диагональным направлениям от которых находятся известные,
+ * затем ситуация сводится к тому как интерполировались зелёные.
+ */
+
+void DHT::make_rbdiag(int i) {
+	int iwidth = libraw.imgdata.sizes.iwidth;
+	int js = libraw.COLOR(i, 0) & 1;
+	int uc = libraw.COLOR(i, js);
+	int cl = uc ^ 2;
+	/*
+	 * js -- начальная х-координата, которая попадает на уже интерполированный зелёный
+	 * al -- известный цвет (кроме зелёного) в точке интерполирования
+	 * cl -- неизвестный цвет
+	 */
+	for (int j = js; j < iwidth; j += 2) {
+		int x = j + nr_leftmargin;
+		int y = i + nr_topmargin;
+		int dx, dy, dx2, dy2;
+		if (ndir[nr_offset(y, x)] & LURD) {
+			dx = -1;
+			dx2 = 1;
+			dy = -1;
+			dy2 = 1;
+		} else {
+			dx = -1;
+			dx2 = 1;
+			dy = 1;
+			dy2 = -1;
+		}
+		float g1 = 1 / calc_dist(nraw[nr_offset(y, x)][1], nraw[nr_offset(y + dy, x + dx)][1]);
+		float g2 = 1 / calc_dist(nraw[nr_offset(y, x)][1], nraw[nr_offset(y + dy2, x + dx2)][1]);
+		g1 *= g1 * g1;
+		g2 *= g2 * g2;
+
+		float eg;
+		eg = nraw[nr_offset(y, x)][1]
+				* (g1 * nraw[nr_offset(y + dy, x + dx)][cl] / nraw[nr_offset(y + dy, x + dx)][1]
+						+ g2 * nraw[nr_offset(y + dy2, x + dx2)][cl]
+								/ nraw[nr_offset(y + dy2, x + dx2)][1]) / (g1 + g2);
+		float min, max;
+		min = MIN(nraw[nr_offset(y + dy, x + dx)][cl], nraw[nr_offset(y + dy2, x + dx2)][cl]);
+		max = MAX(nraw[nr_offset(y + dy, x + dx)][cl], nraw[nr_offset(y + dy2, x + dx2)][cl]);
+		min /= 1.2;
+		max *= 1.2;
+		if (eg < min)
+			eg = scale_under(eg, min);
+		else if (eg > max)
+			eg = scale_over(eg, max);
+		if (eg > channel_maximum[cl])
+			eg = channel_maximum[cl];
+		else if (eg < channel_minimum[cl])
+			eg = channel_minimum[cl];
+		nraw[nr_offset(y, x)][cl] = eg;
+	}
+
+}
+
+/*
+ * интерполяция красных и синих в точках где был известен только зелёный,
+ * направления горизонтальные или вертикальные
+ */
+
+void DHT::make_rbhv(int i) {
+	int iwidth = libraw.imgdata.sizes.iwidth;
+	int js = (libraw.COLOR(i, 0) & 1) ^ 1;
+	for (int j = js; j < iwidth; j += 2) {
+		int x = j + nr_leftmargin;
+		int y = i + nr_topmargin;
+		/*
+		 * поскольку сверху-снизу и справа-слева уже есть все необходимые красные и синие,
+		 * то можно выбрать наилучшее направление исходя из информации по обоим цветам.
+		 */
+		int dx, dy, dx2, dy2;
+		float h1, h2;
+		if (ndir[nr_offset(y, x)] & VER) {
+			dx = dx2 = 0;
+			dy = -1;
+			dy2 = 1;
+		} else {
+			dy = dy2 = 0;
+			dx = 1;
+			dx2 = -1;
+		}
+		float g1 = 1 / calc_dist(nraw[nr_offset(y, x)][1], nraw[nr_offset(y + dy, x + dx)][1]);
+		float g2 = 1 / calc_dist(nraw[nr_offset(y, x)][1], nraw[nr_offset(y + dy2, x + dx2)][1]);
+		g1 *= g1;
+		g2 *= g2;
+		float eg_r, eg_b;
+		eg_r = nraw[nr_offset(y, x)][1]
+				* (g1 * nraw[nr_offset(y + dy, x + dx)][0] / nraw[nr_offset(y + dy, x + dx)][1]
+						+ g2 * nraw[nr_offset(y + dy2, x + dx2)][0]
+								/ nraw[nr_offset(y + dy2, x + dx2)][1]) / (g1 + g2);
+		eg_b = nraw[nr_offset(y, x)][1]
+				* (g1 * nraw[nr_offset(y + dy, x + dx)][2] / nraw[nr_offset(y + dy, x + dx)][1]
+						+ g2 * nraw[nr_offset(y + dy2, x + dx2)][2]
+								/ nraw[nr_offset(y + dy2, x + dx2)][1]) / (g1 + g2);
+		float min_r, max_r;
+		min_r = MIN(nraw[nr_offset(y + dy, x + dx)][0], nraw[nr_offset(y + dy2, x + dx2)][0]);
+		max_r = MAX(nraw[nr_offset(y + dy, x + dx)][0], nraw[nr_offset(y + dy2, x + dx2)][0]);
+		float min_b, max_b;
+		min_b = MIN(nraw[nr_offset(y + dy, x + dx)][2], nraw[nr_offset(y + dy2, x + dx2)][2]);
+		max_b = MAX(nraw[nr_offset(y + dy, x + dx)][2], nraw[nr_offset(y + dy2, x + dx2)][2]);
+		min_r /= 1.2;
+		max_r *= 1.2;
+		min_b /= 1.2;
+		max_b *= 1.2;
+
+		if (eg_r < min_r)
+			eg_r = scale_under(eg_r, min_r);
+		else if (eg_r > max_r)
+			eg_r = scale_over(eg_r, max_r);
+		if (eg_b < min_b)
+			eg_b = scale_under(eg_b, min_b);
+		else if (eg_b > max_b)
+			eg_b = scale_over(eg_b, max_b);
+
+		if (eg_r > channel_maximum[0])
+			eg_r = channel_maximum[0];
+		else if (eg_r < channel_minimum[0])
+			eg_r = channel_minimum[0];
+		if (eg_b > channel_maximum[2])
+			eg_b = channel_maximum[2];
+		else if (eg_b < channel_minimum[2])
+			eg_b = channel_minimum[2];
+		nraw[nr_offset(y, x)][0] = eg_r;
+		nraw[nr_offset(y, x)][2] = eg_b;
+	}
+}
+
+void DHT::make_rb() {
+#if defined(LIBRAW_USE_OPENMP)
+#pragma omp barrier
+#pragma omp parallel for schedule(guided)
+#endif
+	for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) {
+		make_rbdiag(i);
+	}
+#if defined(LIBRAW_USE_OPENMP)
+#pragma omp barrier
+#pragma omp parallel for schedule(guided)
+#endif
+	for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) {
+		make_rbhv(i);
+	}
+
+}
+
+/*
+ * перенос изображения в выходной массив
+ */
+void DHT::copy_to_image() {
+	int iwidth = libraw.imgdata.sizes.iwidth;
+#if defined(LIBRAW_USE_OPENMP)
+#ifdef WIN32
+#pragma omp parallel for
+#else
+#pragma omp parallel for schedule(guided) collapse(2)
+#endif
+#endif
+	for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) {
+		for (int j = 0; j < iwidth; ++j) {
+			libraw.imgdata.image[i * iwidth + j][0] = (unsigned short) (nraw[nr_offset(
+					i + nr_topmargin, j + nr_leftmargin)][0]);
+			libraw.imgdata.image[i * iwidth + j][2] = (unsigned short) (nraw[nr_offset(
+					i + nr_topmargin, j + nr_leftmargin)][2]);
+			libraw.imgdata.image[i * iwidth + j][1] = libraw.imgdata.image[i * iwidth + j][3] =
+					(unsigned short) (nraw[nr_offset(i + nr_topmargin, j + nr_leftmargin)][1]);
+		}
+	}
+}
+
+DHT::~DHT() {
+	free(nraw);
+	free(ndir);
+}
+
+void LibRaw::dht_interpolate() {
+	printf("DHT interpolating\n");
+	DHT dht(*this);
+	dht.hide_hots();
+	dht.make_hv_dirs();
+//	dht.illustrate_dirs();
+	dht.make_greens();
+	dht.make_diag_dirs();
+//	dht.illustrate_dirs();
+	dht.make_rb();
+	dht.restore_hots();
+	dht.copy_to_image();
+
+}
diff --git a/Source/LibRawLite/internal/libraw_bytebuffer.h b/Source/LibRawLite/internal/libraw_bytebuffer.h
deleted file mode 100644
index ba180c3..0000000
--- a/Source/LibRawLite/internal/libraw_bytebuffer.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/* -*- C -*-
- * File: libraw_bytebuffer.h
- *
- * Created: Fri Aug 12 14:41:45 2011
-
-
-LibRaw is free software; you can redistribute it and/or modify
-it under the terms of the one of three licenses as you choose:
-
-1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
-   (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
-
-2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
-   (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
-
-3. LibRaw Software License 27032010
-   (See file LICENSE.LibRaw.pdf provided in LibRaw distribution archive for details).
-
- */
-class LibRaw_byte_buffer
-{
-  public:
-    LibRaw_byte_buffer(unsigned sz=0);
-    void set_buffer(void *bb, unsigned int sz);
-    virtual ~LibRaw_byte_buffer();
-    // fast inlines
-    int get_byte() { if(offt>=size) return EOF; return buf[offt++];}
-    void unseek2() { if(offt>=2) offt-=2;}
-    void *get_buffer() { return buf; }
-    int get_ljpeg_byte() {
-        if(offt>=size) return 0;
-        unsigned char val = buf[offt++];
-        if(val!=0xFF || offt >=size || buf[offt++]==0)
-            return val;
-        offt -=2;
-        return 0;
-    }
-
-  private:
-    unsigned char *buf;
-    unsigned int  size,offt, do_free;
-};
-
-class LibRaw_bit_buffer
-{
-    unsigned bitbuf;
-    int vbits, rst;
-  public:
-    LibRaw_bit_buffer() : bitbuf(0),vbits(0),rst(0) {}
-
-        void reset() {  bitbuf=vbits=rst=0;}
-#ifndef LIBRAW_LIBRARY_BUILD
-        void fill_lj(LibRaw_byte_buffer* buf,int nbits);
-        unsigned _getbits_lj(LibRaw_byte_buffer* buf, int nbits);
-        unsigned _gethuff_lj(LibRaw_byte_buffer* buf, int nbits, unsigned short* huff);
-        void fill(LibRaw_byte_buffer* buf,int nbits,int zer0_ff);
-        unsigned _getbits(LibRaw_byte_buffer* buf, int nbits,int zer0_ff);
-        unsigned _gethuff(LibRaw_byte_buffer* buf, int nbits, unsigned short* huff, int zer0_ff);
-#else
-        void fill_lj(LibRaw_byte_buffer* buf,int nbits)
-        {
-            unsigned c1,c2,c3;
-            if(rst || nbits < vbits) return;
-            int m = vbits >> 3;
-            switch(m)
-                {
-                case 2:	
-                    c1 = buf->get_ljpeg_byte();
-                    bitbuf = (bitbuf <<8) | (c1);
-                    vbits+=8;
-                    break;
-                case 1:
-                    c1 = buf->get_ljpeg_byte();
-                    c2 = buf->get_ljpeg_byte();
-                    bitbuf = (bitbuf <<16) | (c1<<8) | c2;
-                    vbits+=16;		
-                    break;
-                case 0:
-                    c1 = buf->get_ljpeg_byte();
-                    c2 = buf->get_ljpeg_byte();
-                    c3 = buf->get_ljpeg_byte();
-                    bitbuf = (bitbuf <<24) | (c1<<16) | (c2<<8)|c3;
-                    vbits+=24;
-                    break;
-                }
-        }
-
-        unsigned _getbits_lj(LibRaw_byte_buffer* buf, int nbits)
-        {
-            unsigned c;
-            if(nbits==0 || vbits < 0) return 0;
-            fill_lj(buf,nbits);
-            c = bitbuf << (32-vbits) >> (32-nbits);
-            vbits-=nbits;
-            if(vbits<0)throw LIBRAW_EXCEPTION_IO_EOF;
-            return c;
-        }
-        unsigned _gethuff_lj(LibRaw_byte_buffer* buf, int nbits, unsigned short* huff)
-        {
-            unsigned c;
-            if(nbits==0 || vbits < 0) return 0;
-            fill_lj(buf,nbits);
-            c = bitbuf << (32-vbits) >> (32-nbits);
-            vbits -= huff[c] >> 8;
-            c = (uchar) huff[c];
-            if(vbits<0)throw LIBRAW_EXCEPTION_IO_EOF;
-            return c;
-        }
-        void fill(LibRaw_byte_buffer* buf,int nbits,int zer0_ff)
-        {
-            unsigned c;
-            while (!rst && vbits < nbits && (c = buf->get_byte()) != EOF &&
-                   !(rst = zer0_ff && c == 0xff && buf->get_byte())) {
-                bitbuf = (bitbuf << 8) + (uchar) c;
-                vbits += 8;
-            }
-        }
-        unsigned _getbits(LibRaw_byte_buffer* buf, int nbits,int zer0_ff)
-        {
-            unsigned c;
-            if(nbits==0 || vbits < 0) return 0;
-            fill(buf,nbits,zer0_ff);
-            c = bitbuf << (32-vbits) >> (32-nbits);
-            vbits-=nbits;
-            if(vbits<0)throw LIBRAW_EXCEPTION_IO_EOF;
-            return c;
-        }
-        unsigned _gethuff(LibRaw_byte_buffer* buf, int nbits, unsigned short* huff, int zer0_ff)
-        {
-            unsigned c;
-            if(nbits==0 || vbits < 0) return 0;
-            fill(buf,nbits,zer0_ff);
-            c = bitbuf << (32-vbits) >> (32-nbits);
-            vbits -= huff[c] >> 8;
-            c = (uchar) huff[c];
-            if(vbits<0)throw LIBRAW_EXCEPTION_IO_EOF;
-            return c;
-        }
-#endif
-};
diff --git a/Source/LibRawLite/internal/libraw_internal_funcs.h b/Source/LibRawLite/internal/libraw_internal_funcs.h
index e8847af..7219e92 100644
--- a/Source/LibRawLite/internal/libraw_internal_funcs.h
+++ b/Source/LibRawLite/internal/libraw_internal_funcs.h
@@ -1,6 +1,6 @@
 /* -*- C++ -*-
  * File: libraw_internal_funcs.h
- * Copyright 2008-2009 LibRaw LLC (info at libraw.org)
+ * Copyright 2008-2013 LibRaw LLC (info at libraw.org)
  * Created: Sat Mar  14, 2008
 
 LibRaw is free software; you can redistribute it and/or modify
@@ -23,8 +23,28 @@ it under the terms of the one of three licenses as you choose:
 #ifndef LIBRAW_LIBRARY_BUILD
 #error "This file should be used only for libraw library build"
 #else
+    /* WF */
+    void        wf_bayer4_igauss_filter(int radius,void* src_image, int src_imgmode, void* dst_image, int dst_imgmode);
+    void			wf_bayer4_green_blur   (int mode,void* src_image, int src_imgmode, void* dst_image, int dst_imgmode);
+    void        wf_bayer4_block_filter (int* radius_list, void* src_image, int src_imgmode, void* dst_image, int dst_imgmode);
+    double	wf_filter_energy       (int r1_greenmode, int r1, int r2_greenmode, int r2);
+
+
 // inline functions
     ushort      sget2 (uchar *s);
+    ushort      sget2Rev(uchar *s);
+    void	setCanonBodyFeatures (unsigned id);
+    void 	processCanonCameraInfo (unsigned id, uchar *CameraInfo);
+    void	processNikonLensData (uchar *LensData, unsigned len);
+    void	setOlympusBodyFeatures (unsigned long id);
+    void	setPhaseOneFeatures (unsigned id);
+    void	setPentaxBodyFeatures (unsigned id);
+    void	setSonyBodyFeatures (unsigned id);
+    void	parseSonyLensType2 (uchar a, uchar b);
+    void 	parseSonyLensFeatures (uchar a, uchar b);
+    void	process_Sony_0x9050 (uchar * buf, unsigned id);
+    void	process_Sony_0x940c (uchar * buf);
+
     ushort      get2();
     unsigned    sget4 (uchar *s);
     unsigned    getint (int type);
@@ -38,43 +58,44 @@ it under the terms of the one of three licenses as you choose:
     void        canon_600_auto_wb();
     void        canon_600_coeff();
     void        canon_600_load_raw();
+    void        canon_600_correct();
     int         canon_s2is();
-    void        parse_ciff (int offset, int length);
+void        parse_ciff (int offset, int length, int);
     void        ciff_block_1030();
 
+
 // LJPEG decoder
     unsigned    getbithuff (int nbits, ushort *huff);
     ushort*     make_decoder_ref (const uchar **source);
     ushort*     make_decoder (const uchar *source);
     int         ljpeg_start (struct jhead *jh, int info_only);
     void        ljpeg_end(struct jhead *jh);
-    int         ljpeg_diff (ushort *huff); 
-    int         ljpeg_diff_new (LibRaw_bit_buffer& bits, LibRaw_byte_buffer* buf,ushort *huff);
-    int         ljpeg_diff_pef (LibRaw_bit_buffer& bits, LibRaw_byte_buffer* buf,ushort *huff);
+    int         ljpeg_diff (ushort *huff);
     ushort *    ljpeg_row (int jrow, struct jhead *jh);
-    ushort *    ljpeg_row_new (int jrow, struct jhead *jh, LibRaw_bit_buffer& bits,LibRaw_byte_buffer* bytes);
-
     unsigned    ph1_bithuff (int nbits, ushort *huff);
 
 // Canon DSLRs
 void        crw_init_tables (unsigned table, ushort *huff[2]);
     int         canon_has_lowbits();
-    void        canon_compressed_load_raw();
+    void        canon_load_raw();
     void        lossless_jpeg_load_raw();
     void        canon_sraw_load_raw();
 // Adobe DNG
-    void        adobe_copy_pixel (int row, int col, ushort **rp);
-    void        adobe_dng_load_raw_lj();
-    void        adobe_dng_load_raw_nc();
+    void        adobe_copy_pixel (unsigned int row, unsigned int col, ushort **rp);
+    void        lossless_dng_load_raw();
+    void        packed_dng_load_raw();
+    void        lossy_dng_load_raw();
+//void        adobe_dng_load_raw_nc();
 
 // Pentax
     void        pentax_load_raw();
     void        pentax_tree();
 
 // Nikon (and Minolta Z2)
-    void        nikon_compressed_load_raw();
     void        nikon_load_raw();
-    int         nikon_is_compressed();
+    void        nikon_load_sraw();
+    void        nikon_yuv_load_raw();
+    void	nikon_coolscan_load_raw();
     int         nikon_e995();
     int         nikon_e2100();
     void        nikon_3700();
@@ -82,7 +103,7 @@ void        crw_init_tables (unsigned table, ushort *huff[2]);
     void        nikon_e2100_load_raw();
 
 // Fuji
-    void        fuji_load_raw();
+//void        fuji_load_raw();
     void        parse_fuji (int offset);
 
 // RedCine
@@ -94,9 +115,9 @@ void        crw_init_tables (unsigned table, ushort *huff[2]);
     void        parse_rollei();
 
 // MF backs
-    int         bayer (unsigned row, unsigned col);
+//int         bayer (unsigned row, unsigned col);
+    int         raw(unsigned,unsigned);
     void        phase_one_flat_field (int is_float, int nc);
-    void        phase_one_correct();
     void        phase_one_load_raw();
     unsigned    ph1_bits (int nbits);
     void        phase_one_load_raw_c();
@@ -104,6 +125,7 @@ void        crw_init_tables (unsigned table, ushort *huff[2]);
     void        leaf_hdr_load_raw();
     void        sinar_4shot_load_raw();
     void        imacon_full_load_raw();
+    void        hasselblad_full_load_raw();
     void        packed_load_raw();
     float	find_green(int,int,int,int);
     void        unpacked_load_raw();
@@ -112,6 +134,9 @@ void        crw_init_tables (unsigned table, ushort *huff[2]);
 
 // Misc P&S cameras
     void        nokia_load_raw();
+    void        android_loose_load_raw();
+    void        android_tight_load_raw();
+    void        canon_rmf_load_raw();
     unsigned    pana_bits (int nbits);
     void        panasonic_load_raw();
     void        olympus_load_raw();
@@ -139,8 +164,10 @@ void        crw_init_tables (unsigned table, ushort *huff[2]);
     int         kodak_65000_decode (short *out, int bsize);
     void        kodak_65000_load_raw();
     void        kodak_rgb_load_raw();
-    void        kodak_yrgb_load_raw();
     void        kodak_ycbcr_load_raw();
+//    void        kodak_yrgb_load_raw();
+    void        kodak_c330_load_raw();
+    void        kodak_c603_load_raw();
     void        kodak_rgb_load_thumb();
     void        kodak_ycbcr_load_thumb();
 
@@ -149,11 +176,18 @@ void        crw_init_tables (unsigned table, ushort *huff[2]);
     void        sony_load_raw();
     void        sony_arw_load_raw();
     void        sony_arw2_load_raw();
+    void        samsung_load_raw();
+    void        samsung2_load_raw();
+    void        samsung3_load_raw();
     void        parse_minolta (int base);
 
 // Foveon/Sigma
+#ifdef LIBRAW_DEMOSAIC_PACK_GPL2
+    void        foveon_sd_load_raw();
+    void        foveon_dp_load_raw();
+    void        foveon_huff (ushort *huff);
     void        foveon_load_camf();
-    void        foveon_load_raw();
+
     const char* foveon_camf_param (const char *block, const char *param);
     void *      foveon_camf_matrix (unsigned dim[3], const char *name);
     int         foveon_fixed (void *ptr, int size, const char *name);
@@ -164,11 +198,15 @@ void        crw_init_tables (unsigned table, ushort *huff[2]);
     void        foveon_interpolate();
     char *      foveon_gets (int offset, char *str, int len);
     void        parse_foveon();
+#endif
+// We always have x3f code compiled in!
+    void        parse_x3f();
+    void        x3f_load_raw();
+    void        x3f_dpq_interpolate_rg();
+	void        x3f_dpq_interpolate_af(int xstep, int ystep, int scale); // 1x1 af pixels
 
 // CAM/RGB
     void        pseudoinverse (double (*in)[3], double (*out)[3], int size);
-    void        cam_xyz_coeff (double cam_xyz[4][3]);
-    void        adobe_coeff (const char *, const char *);
     void        simple_coeff (int index);
 
 
@@ -176,6 +214,7 @@ void        crw_init_tables (unsigned table, ushort *huff[2]);
     void        tiff_get (unsigned base,unsigned *tag, unsigned *type, unsigned *len, unsigned *save);
     void        parse_thumb_note (int base, unsigned toff, unsigned tlen);
     void        parse_makernote (int base, int uptag);
+		void        parse_makernote_0xc634(int base, int uptag, unsigned dng_writer);
     void        parse_exif (int base);
     void        linear_table (unsigned len);
     void        parse_kodak_ifd (int base);
@@ -183,8 +222,10 @@ void        crw_init_tables (unsigned table, ushort *huff[2]);
     int         parse_tiff (int base);
     void        apply_tiff(void);
     void        parse_gps (int base);
-    void        romm_coeff (float romm_cam[3][3]);
+		void        parse_gps_libraw(int base);
+		void        romm_coeff(float romm_cam[3][3]);
     void        parse_mos (int offset);
+    void        parse_qt (int end);
     void        get_timestamp (int reversed);
 
 // External JPEGs, what cameras uses it ?
@@ -198,10 +239,10 @@ void        crw_init_tables (unsigned table, ushort *huff[2]);
     void        tiff_head (struct tiff_hdr *th, int full);
 
 // splitted AHD code
-#define TS 256
+#define TS 512
     void        ahd_interpolate_green_h_and_v(int top, int left, ushort (*out_rgb)[TS][TS][3]);
-    void ahd_interpolate_r_and_b_in_rgb_and_convert_to_cielab(int top, int left, ushort (*inout_rgb)[TS][3], short (*out_lab)[TS][3], const float (&xyz_cam)[3][4]);
-    void ahd_interpolate_r_and_b_and_convert_to_cielab(int top, int left, ushort (*inout_rgb)[TS][TS][3], short (*out_lab)[TS][TS][3], const float (&xyz_cam)[3][4]);
+    void ahd_interpolate_r_and_b_in_rgb_and_convert_to_cielab(int top, int left, ushort (*inout_rgb)[TS][3], short (*out_lab)[TS][3]);
+    void ahd_interpolate_r_and_b_and_convert_to_cielab(int top, int left, ushort (*inout_rgb)[TS][TS][3], short (*out_lab)[TS][TS][3]);
     void ahd_interpolate_build_homogeneity_map(int top, int left, short (*lab)[TS][TS][3], char (*out_homogeneity_map)[TS][2]);
     void ahd_interpolate_combine_homogeneous_pixels(int top, int left, ushort (*rgb)[TS][TS][3], char (*homogeneity_map)[TS][2]);
 
diff --git a/Source/LibRawLite/internal/libraw_x3f.cpp b/Source/LibRawLite/internal/libraw_x3f.cpp
new file mode 100644
index 0000000..e08ce4b
--- /dev/null
+++ b/Source/LibRawLite/internal/libraw_x3f.cpp
@@ -0,0 +1,1919 @@
+/* Library for accessing X3F Files 
+----------------------------------------------------------------
+BSD-style License
+----------------------------------------------------------------
+
+* Copyright (c) 2010, Roland Karlsson (roland at proxel.se)
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*     * Redistributions of source code must retain the above copyright
+*       notice, this list of conditions and the following disclaimer.
+*     * Redistributions in binary form must reproduce the above copyright
+*       notice, this list of conditions and the following disclaimer in the
+*       documentation and/or other materials provided with the distribution.
+*     * Neither the name of the organization nor the
+*       names of its contributors may be used to endorse or promote products
+*       derived from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY ROLAND KARLSSON ''AS IS'' AND ANY
+* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL ROLAND KARLSSON BE LIABLE FOR ANY
+* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+  /* From X3F_IO.H */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+#include <stdio.h>
+#include "../libraw/libraw_datastream.h"
+
+#define SIZE_UNIQUE_IDENTIFIER 16
+#define SIZE_WHITE_BALANCE 32
+#define NUM_EXT_DATA 32
+
+#define X3F_VERSION(MAJ,MIN) (uint32_t)(((MAJ)<<16) + MIN)
+#define X3F_VERSION_2_0 X3F_VERSION(2,0)
+#define X3F_VERSION_2_1 X3F_VERSION(2,1)
+
+/* Main file identifier */
+#define X3F_FOVb (uint32_t)(0x62564f46)
+/* Directory identifier */
+#define X3F_SECd (uint32_t)(0x64434553)
+/* Property section identifiers */
+#define X3F_PROP (uint32_t)(0x504f5250)
+#define X3F_SECp (uint32_t)(0x70434553)
+/* Image section identifiers */
+#define X3F_IMAG (uint32_t)(0x46414d49)
+#define X3F_IMA2 (uint32_t)(0x32414d49)
+#define X3F_SECi (uint32_t)(0x69434553)
+/* CAMF identifiers */
+#define X3F_CAMF (uint32_t)(0x464d4143)
+#define X3F_SECc (uint32_t)(0x63434553)
+/* CAMF entry identifiers */
+#define X3F_CMbP (uint32_t)(0x50624d43)
+#define X3F_CMbT (uint32_t)(0x54624d43)
+#define X3F_CMbM (uint32_t)(0x4d624d43)
+#define X3F_CMb  (uint32_t)(0x00624d43)
+
+#define X3F_IMAGE_THUMB_PLAIN       (uint32_t)(0x00020003)
+#define X3F_IMAGE_THUMB_HUFFMAN     (uint32_t)(0x0002000b)
+#define X3F_IMAGE_THUMB_JPEG        (uint32_t)(0x00020012)
+
+#define X3F_IMAGE_RAW_HUFFMAN_X530  (uint32_t)(0x00030005)
+#define X3F_IMAGE_RAW_HUFFMAN_10BIT (uint32_t)(0x00030006)
+#define X3F_IMAGE_RAW_TRUE          (uint32_t)(0x0003001e)
+#define X3F_IMAGE_RAW_MERRILL       (uint32_t)(0x0001001e)
+#define X3F_IMAGE_RAW_QUATTRO       (uint32_t)(0x00010023)
+
+#define X3F_IMAGE_HEADER_SIZE 28
+#define X3F_CAMF_HEADER_SIZE 28
+#define X3F_PROPERTY_LIST_HEADER_SIZE 24
+
+typedef uint16_t utf16_t;
+
+typedef int bool_t;
+
+typedef enum x3f_extended_types_e {
+  X3F_EXT_TYPE_NONE=0,
+  X3F_EXT_TYPE_EXPOSURE_ADJUST=1,
+  X3F_EXT_TYPE_CONTRAST_ADJUST=2,
+  X3F_EXT_TYPE_SHADOW_ADJUST=3,
+  X3F_EXT_TYPE_HIGHLIGHT_ADJUST=4,
+  X3F_EXT_TYPE_SATURATION_ADJUST=5,
+  X3F_EXT_TYPE_SHARPNESS_ADJUST=6,
+  X3F_EXT_TYPE_RED_ADJUST=7,
+  X3F_EXT_TYPE_GREEN_ADJUST=8,
+  X3F_EXT_TYPE_BLUE_ADJUST=9,
+  X3F_EXT_TYPE_FILL_LIGHT_ADJUST=10
+} x3f_extended_types_t;
+
+typedef struct x3f_property_s {
+  /* Read from file */
+  uint32_t name_offset;
+  uint32_t value_offset;
+
+  /* Computed */
+  utf16_t *name;		/* 0x00 terminated UTF 16 */
+  utf16_t *value;               /* 0x00 terminated UTF 16 */
+} x3f_property_t;
+
+typedef struct x3f_property_table_s {
+  uint32_t size;
+  x3f_property_t *element;
+} x3f_property_table_t;
+
+typedef struct x3f_property_list_s {
+  /* 2.0 Fields */
+  uint32_t num_properties;
+  uint32_t character_format;
+  uint32_t reserved;
+  uint32_t total_length;
+
+  x3f_property_table_t property_table;
+
+  void *data;
+
+  uint32_t data_size;
+
+} x3f_property_list_t;
+
+typedef struct x3f_table8_s {
+  uint32_t size;
+  uint8_t *element;
+} x3f_table8_t;
+
+typedef struct x3f_table16_s {
+  uint32_t size;
+  uint16_t *element;
+} x3f_table16_t;
+
+typedef struct x3f_table32_s {
+  uint32_t size;
+  uint32_t *element;
+} x3f_table32_t;
+
+#define UNDEFINED_LEAF 0xffffffff
+
+typedef struct x3f_huffnode_s {
+  struct x3f_huffnode_s *branch[2];
+  uint32_t leaf;
+} x3f_huffnode_t;
+
+typedef struct x3f_hufftree_s {
+  uint32_t free_node_index; /* Free node index in huffman tree array */
+  x3f_huffnode_t *nodes;    /* Coding tree */
+} x3f_hufftree_t;
+
+typedef struct x3f_true_huffman_element_s {
+  uint8_t code_size;
+  uint8_t code;
+} x3f_true_huffman_element_t;
+
+typedef struct x3f_true_huffman_s {
+  uint32_t size;
+  x3f_true_huffman_element_t *element;
+} x3f_true_huffman_t;
+
+/* 0=bottom, 1=middle, 2=top */
+#define TRUE_PLANES 3
+
+typedef struct x3f_true_s {
+  uint16_t seed[TRUE_PLANES];	/* Always 512,512,512 */
+  uint16_t unknown;		/* Always 0 */
+  x3f_true_huffman_t table;	/* Huffman table - zero
+				   terminated. size is the number of
+				   leaves plus 1.*/
+
+  x3f_table32_t plane_size;	/* Size of the 3 planes */
+  uint8_t *plane_address[TRUE_PLANES]; /* computed offset to the planes */
+  x3f_hufftree_t tree;		/* Coding tree */
+  x3f_table16_t x3rgb16;        /* 3x16 bit X3-RGB data */
+} x3f_true_t;
+
+typedef struct x3f_quattro_s {
+  struct {
+    uint16_t columns;
+    uint16_t rows;
+  } plane[TRUE_PLANES];
+  uint32_t unknown;
+} x3f_quattro_t;
+
+typedef struct x3f_huffman_s {
+  x3f_table16_t mapping;   /* Value Mapping = X3F lossy compression */
+  x3f_table32_t table;          /* Coding Table */
+  x3f_hufftree_t tree;		/* Coding tree */
+  x3f_table32_t row_offsets;    /* Row offsets */
+  x3f_table8_t rgb8;            /* 3x8 bit RGB data */
+  x3f_table16_t x3rgb16;        /* 3x16 bit X3-RGB data */
+} x3f_huffman_t;
+
+typedef struct x3f_image_data_s {
+  /* 2.0 Fields */
+  /* ------------------------------------------------------------------ */
+  /* Known combinations of type and format are:
+     1-6, 2-3, 2-11, 2-18, 3-6 */
+  uint32_t type;                /* 1 = RAW X3 (SD1)
+                                   2 = thumbnail or maybe just RGB
+                                   3 = RAW X3 */
+  uint32_t format;              /* 3 = 3x8 bit pixmap
+                                   6 = 3x10 bit huffman with map table
+                                   11 = 3x8 bit huffman
+                                   18 = JPEG */
+  uint32_t type_format;         /* type<<16 + format */
+  /* ------------------------------------------------------------------ */
+
+  uint32_t columns;             /* width / row size in pixels */
+  uint32_t rows;                /* height */
+  uint32_t row_stride;          /* row size in bytes */
+
+  /* NULL if not used */
+  x3f_huffman_t *huffman;       /* Huffman help data */
+  x3f_true_t *tru;		/* TRUE help data */
+  x3f_quattro_t *quattro;	/* Quattro help data */
+
+  void *data;                   /* Take from file if NULL. Otherwise,
+                                   this is the actual data bytes in
+                                   the file. */
+  uint32_t data_size;
+
+} x3f_image_data_t;
+
+typedef struct camf_entry_s {
+  uint32_t id;
+  uint32_t version;
+  uint32_t entry_size;
+  uint32_t name_offset;
+  uint32_t value_offset;
+  void *entry;			/* pointer into decoded data */
+
+  /* computed values */
+  uint8_t *name_address;
+  void *value_address;
+} camf_entry_t;
+
+typedef struct camf_entry_table_s {
+  uint32_t size;
+  camf_entry_t *element;
+} camf_entry_table_t;
+
+typedef struct x3f_camf_typeN_s {
+  uint32_t val0;
+  uint32_t val1;
+  uint32_t val2;
+  uint32_t val3;
+} x3f_camf_typeN_t;
+
+typedef struct x3f_camf_type2_s {
+  uint32_t reserved;
+  uint32_t infotype;
+  uint32_t infotype_version;
+  uint32_t crypt_key;
+} x3f_camf_type2_t;
+
+typedef struct x3f_camf_type4_s {
+  uint32_t reserved;
+  uint32_t decode_bias;
+  uint32_t block_size;
+  uint32_t block_count;
+} x3f_camf_type4_t;
+
+typedef struct x3f_camf_s {
+
+  /* Header info */
+  uint32_t type;
+  union {
+    x3f_camf_typeN_t tN;
+    x3f_camf_type2_t t2;
+    x3f_camf_type4_t t4;
+  };
+
+  /* The encrypted raw data */
+  void *data;
+  uint32_t data_size;
+
+  /* Help data for type 4 Huffman compression */
+  x3f_true_huffman_t table;
+  x3f_hufftree_t tree;
+  uint8_t *decoding_start;
+
+  /* The decrypted data */
+  void *decoded_data;
+  uint32_t decoded_data_size;
+
+  /* Pointers into the decrypted data */
+  camf_entry_table_t entry_table;
+} x3f_camf_t;
+
+typedef struct x3f_directory_entry_header_s {
+  uint32_t identifier;        /* Should be ´SECp´, "SECi", ... */
+  uint32_t version;           /* 0x00020001 is version 2.1  */
+  union {
+    x3f_property_list_t property_list;
+    x3f_image_data_t image_data;
+    x3f_camf_t camf;
+  } data_subsection;
+} x3f_directory_entry_header_t;
+
+typedef struct x3f_directory_entry_s {
+  struct {
+    uint32_t offset;
+    uint32_t size;
+  } input, output;
+
+  uint32_t type;
+
+  x3f_directory_entry_header_t header;
+} x3f_directory_entry_t;
+
+typedef struct x3f_directory_section_s {
+  uint32_t identifier;          /* Should be ´SECd´ */
+  uint32_t version;             /* 0x00020001 is version 2.1  */
+
+  /* 2.0 Fields */
+  uint32_t num_directory_entries;
+  x3f_directory_entry_t *directory_entry;
+} x3f_directory_section_t;
+
+typedef struct x3f_header_s {
+  /* 2.0 Fields */
+  uint32_t identifier;          /* Should be ´FOVb´ */
+  uint32_t version;             /* 0x00020001 means 2.1 */
+  uint8_t unique_identifier[SIZE_UNIQUE_IDENTIFIER];
+  uint32_t mark_bits;
+  uint32_t columns;             /* Columns and rows ... */
+  uint32_t rows;                /* ... before rotation */
+  uint32_t rotation;            /* 0, 90, 180, 270 */
+
+  /* Added for 2.1 and 2.2 */
+  uint8_t white_balance[SIZE_WHITE_BALANCE];
+  uint8_t extended_types[NUM_EXT_DATA]; /* x3f_extended_types_t */
+  uint32_t extended_data[NUM_EXT_DATA];
+} x3f_header_t;
+
+typedef struct x3f_info_s {
+  char *error;
+  struct {
+	  LibRaw_abstract_datastream *file;                 /* Use if more data is needed */
+  } input, output;
+} x3f_info_t;
+
+typedef struct x3f_s {
+  x3f_info_t info;
+  x3f_header_t header;
+  x3f_directory_section_t directory_section;
+} x3f_t;
+
+typedef enum x3f_return_e {
+  X3F_OK=0,
+  X3F_ARGUMENT_ERROR=1,
+  X3F_INFILE_ERROR=2,
+  X3F_OUTFILE_ERROR=3,
+  X3F_INTERNAL_ERROR=4
+} x3f_return_t;
+
+x3f_return_t x3f_delete(x3f_t *x3f);
+
+
+/* --------------------------------------------------------------------- */
+/* Hacky external flags                                                 */
+/* --------------------------------------------------------------------- */
+
+/* extern */ int legacy_offset = 0;
+/* extern */ bool_t auto_legacy_offset = 1;
+
+/* --------------------------------------------------------------------- */
+/* Huffman Decode Macros                                                 */
+/* --------------------------------------------------------------------- */
+
+#define HUF_TREE_MAX_LENGTH 27
+#define HUF_TREE_MAX_NODES(_leaves) ((HUF_TREE_MAX_LENGTH+1)*(_leaves))
+#define HUF_TREE_GET_LENGTH(_v) (((_v)>>27)&0x1f)
+#define HUF_TREE_GET_CODE(_v) ((_v)&0x07ffffff)
+
+/* --------------------------------------------------------------------- */
+/* Reading and writing - assuming little endian in the file              */
+/* --------------------------------------------------------------------- */
+
+static int x3f_get1(LibRaw_abstract_datastream *f)
+{
+	/* Little endian file */
+	return f->get_char(); 
+}
+
+static int  x3f_sget2 (uchar *s)
+{
+	return s[0] | s[1] << 8;
+}
+
+static int x3f_get2(LibRaw_abstract_datastream *f)
+{
+	uchar str[2] = { 0xff,0xff };
+	f->read (str, 1, 2);
+	return x3f_sget2(str);
+}
+
+unsigned x3f_sget4 (uchar *s)
+{
+	return s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24;
+}
+
+unsigned x3f_get4(LibRaw_abstract_datastream *f)
+{
+	uchar str[4] = { 0xff,0xff,0xff,0xff };
+	f->read (str, 1, 4);
+	return x3f_sget4(str);
+}
+
+#define FREE(P) do { free(P); (P) = NULL; } while (0)
+
+#define PUT_GET_N(_buffer,_size,_file,_func)			\
+	do								\
+{								\
+	int _left = _size;					\
+	while (_left != 0) {					\
+	int _cur = _file->_func(_buffer,1,_left);		\
+	if (_cur == 0) {					\
+		break; \
+	}							\
+	_left -= _cur;						\
+	}								\
+} while(0)
+
+#define GET1(_v) do {(_v) = x3f_get1(I->input.file);} while (0)
+#define GET2(_v) do {(_v) = x3f_get2(I->input.file);} while (0)
+#define GET4(_v) do {(_v) = x3f_get4(I->input.file);} while (0)
+#define GETN(_v,_s) PUT_GET_N(_v,_s,I->input.file,read)
+
+#define GET_TABLE(_T, _GETX, _NUM,_TYPE)					\
+	do {									\
+	int _i;								\
+	(_T).size = (_NUM);							\
+	(_T).element = (_TYPE *)realloc((_T).element,			\
+	(_NUM)*sizeof((_T).element[0]));	\
+	for (_i = 0; _i < (_T).size; _i++)					\
+	_GETX((_T).element[_i]);						\
+	} while (0)
+
+#define GET_PROPERTY_TABLE(_T, _NUM)					\
+	do {									\
+	int _i;								\
+	(_T).size = (_NUM);							\
+	(_T).element = (x3f_property_t *)realloc((_T).element,			\
+	(_NUM)*sizeof((_T).element[0]));	\
+	for (_i = 0; _i < (_T).size; _i++) {				\
+	GET4((_T).element[_i].name_offset);				\
+	GET4((_T).element[_i].value_offset);				\
+	}									\
+	} while (0)
+
+#define GET_TRUE_HUFF_TABLE(_T)						\
+	do {									\
+	int _i;								\
+	(_T).element = NULL;						\
+	for (_i = 0; ; _i++) {						\
+	(_T).size = _i + 1;						\
+	(_T).element = (x3f_true_huffman_element_t *)realloc((_T).element,			\
+	(_i + 1)*sizeof((_T).element[0]));	\
+	GET1((_T).element[_i].code_size);					\
+	GET1((_T).element[_i].code);					\
+	if ((_T).element[_i].code_size == 0) break;			\
+	}									\
+	} while (0)
+
+
+
+/* --------------------------------------------------------------------- */
+/* Allocating Huffman tree help data                                   */
+/* --------------------------------------------------------------------- */
+
+static void cleanup_huffman_tree(x3f_hufftree_t *HTP)
+{
+  free(HTP->nodes);
+}
+
+static void new_huffman_tree(x3f_hufftree_t *HTP, int bits)
+{
+  int leaves = 1<<bits;
+
+  HTP->free_node_index = 0;
+  HTP->nodes = (x3f_huffnode_t *)
+    calloc(1, HUF_TREE_MAX_NODES(leaves)*sizeof(x3f_huffnode_t));
+}
+
+/* --------------------------------------------------------------------- */
+/* Allocating TRUE engine RAW help data                                  */
+/* --------------------------------------------------------------------- */
+
+static void cleanup_true(x3f_true_t **TRUP)
+{
+  x3f_true_t *TRU = *TRUP;
+
+  if (TRU == NULL) return;
+
+  FREE(TRU->table.element);
+  FREE(TRU->plane_size.element);
+  cleanup_huffman_tree(&TRU->tree);
+  FREE(TRU->x3rgb16.element);
+
+  FREE(TRU);
+
+  *TRUP = NULL;
+}
+
+static x3f_true_t *new_true(x3f_true_t **TRUP)
+{
+  x3f_true_t *TRU = (x3f_true_t *)calloc(1, sizeof(x3f_true_t));
+
+  cleanup_true(TRUP);
+
+  TRU->table.size = 0;
+  TRU->table.element = NULL;
+  TRU->plane_size.size = 0;
+  TRU->plane_size.element = NULL;
+  TRU->tree.nodes = NULL;
+  TRU->x3rgb16.size = 0;
+  TRU->x3rgb16.element = NULL;
+
+  *TRUP = TRU;
+
+  return TRU;
+}
+
+static void cleanup_quattro(x3f_quattro_t **QP)
+{
+  x3f_quattro_t *Q = *QP;
+
+  if (Q == NULL) return;
+
+  FREE(Q);
+
+  *QP = NULL;
+}
+
+static x3f_quattro_t *new_quattro(x3f_quattro_t **QP)
+{
+  x3f_quattro_t *Q = (x3f_quattro_t *)calloc(1, sizeof(x3f_quattro_t));
+  int i;
+
+  cleanup_quattro(QP);
+
+  for (i=0; i<TRUE_PLANES; i++) {
+    Q->plane[i].columns = 0;
+    Q->plane[i].rows = 0;
+  }
+
+  Q->unknown = 0;
+
+  *QP = Q;
+
+  return Q;
+}
+
+/* --------------------------------------------------------------------- */
+/* Allocating Huffman engine help data                                   */
+/* --------------------------------------------------------------------- */
+
+static void cleanup_huffman(x3f_huffman_t **HUFP)
+{
+  x3f_huffman_t *HUF = *HUFP;
+
+  if (HUF == NULL) return;
+
+  FREE(HUF->mapping.element);
+  FREE(HUF->table.element);
+  cleanup_huffman_tree(&HUF->tree);
+  FREE(HUF->row_offsets.element);
+  FREE(HUF->rgb8.element);
+  FREE(HUF->x3rgb16.element);
+  FREE(HUF);
+
+  *HUFP = NULL;
+}
+
+static x3f_huffman_t *new_huffman(x3f_huffman_t **HUFP)
+{
+  x3f_huffman_t *HUF = (x3f_huffman_t *)calloc(1, sizeof(x3f_huffman_t));
+
+  cleanup_huffman(HUFP);
+
+  /* Set all not read data block pointers to NULL */
+  HUF->mapping.size = 0;
+  HUF->mapping.element = NULL;
+  HUF->table.size = 0;
+  HUF->table.element = NULL;
+  HUF->tree.nodes = NULL;
+  HUF->row_offsets.size = 0;
+  HUF->row_offsets.element = NULL;
+  HUF->rgb8.size = 0;
+  HUF->rgb8.element = NULL;
+  HUF->x3rgb16.size = 0;
+  HUF->x3rgb16.element = NULL;
+
+  *HUFP = HUF;
+
+  return HUF;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Creating a new x3f structure from file                                */
+/* --------------------------------------------------------------------- */
+
+/* extern */ x3f_t *x3f_new_from_file(LibRaw_abstract_datastream *infile)
+{
+  x3f_t *x3f = (x3f_t *)calloc(1, sizeof(x3f_t));
+  x3f_info_t *I = NULL;
+  x3f_header_t *H = NULL;
+  x3f_directory_section_t *DS = NULL;
+  int i, d;
+
+  I = &x3f->info;
+  I->error = NULL;
+  I->input.file = infile;
+  I->output.file = NULL;
+
+  if (infile == NULL) {
+    I->error = "No infile";
+    return x3f;
+  }
+
+  /* Read file header */
+  H = &x3f->header;
+  infile->seek(0, SEEK_SET);
+  GET4(H->identifier);
+
+  if (H->identifier != X3F_FOVb) {
+#ifdef DCRAW_VERBOSE
+    fprintf(stderr, "Faulty file type\n");
+#endif
+    x3f_delete(x3f);
+    return NULL;
+  }
+
+  GET4(H->version);
+  GETN(H->unique_identifier, SIZE_UNIQUE_IDENTIFIER);
+  GET4(H->mark_bits);
+  GET4(H->columns);
+  GET4(H->rows);
+  GET4(H->rotation);
+  if (H->version > X3F_VERSION_2_0) {
+    GETN(H->white_balance, SIZE_WHITE_BALANCE);
+    GETN(H->extended_types, NUM_EXT_DATA);
+    for (i=0; i<NUM_EXT_DATA; i++)
+      GET4(H->extended_data[i]);
+  }
+
+  /* Go to the beginning of the directory */
+  infile->seek(-4, SEEK_END);
+  infile->seek(x3f_get4(infile), SEEK_SET);
+
+  /* Read the directory header */
+  DS = &x3f->directory_section;
+  GET4(DS->identifier);
+  GET4(DS->version);
+  GET4(DS->num_directory_entries);
+
+  if (DS->num_directory_entries > 0) {
+    size_t size = DS->num_directory_entries * sizeof(x3f_directory_entry_t);
+    DS->directory_entry = (x3f_directory_entry_t *)calloc(1, size);
+  }
+
+  /* Traverse the directory */
+  for (d=0; d<DS->num_directory_entries; d++) { 
+    x3f_directory_entry_t *DE = &DS->directory_entry[d];
+    x3f_directory_entry_header_t *DEH = &DE->header;
+    uint32_t save_dir_pos;
+
+    /* Read the directory entry info */
+    GET4(DE->input.offset);
+    GET4(DE->input.size);
+
+    DE->output.offset = 0;
+    DE->output.size = 0;
+
+    GET4(DE->type);
+
+    /* Save current pos and go to the entry */
+    save_dir_pos = infile->tell();
+    infile->seek(DE->input.offset, SEEK_SET);
+
+    /* Read the type independent part of the entry header */
+    DEH = &DE->header;
+    GET4(DEH->identifier);
+    GET4(DEH->version);
+
+    /* NOTE - the tests below could be made on DE->type instead */
+
+    if (DEH->identifier == X3F_SECp) {
+      x3f_property_list_t *PL = &DEH->data_subsection.property_list;
+
+      /* Read the property part of the header */
+      GET4(PL->num_properties);
+      GET4(PL->character_format);
+      GET4(PL->reserved);
+      GET4(PL->total_length);
+
+      /* Set all not read data block pointers to NULL */
+      PL->data = NULL;
+      PL->data_size = 0;
+    }
+
+    if (DEH->identifier == X3F_SECi) {
+      x3f_image_data_t *ID = &DEH->data_subsection.image_data;
+
+      /* Read the image part of the header */
+      GET4(ID->type);
+      GET4(ID->format);
+      ID->type_format = (ID->type << 16) + (ID->format);
+      GET4(ID->columns);
+      GET4(ID->rows);
+      GET4(ID->row_stride);
+
+      /* Set all not read data block pointers to NULL */
+      ID->huffman = NULL;
+
+      ID->data = NULL;
+      ID->data_size = 0;
+    }
+
+    if (DEH->identifier == X3F_SECc) {
+      x3f_camf_t *CAMF = &DEH->data_subsection.camf;
+
+      /* Read the CAMF part of the header */
+      GET4(CAMF->type);
+      GET4(CAMF->tN.val0);
+      GET4(CAMF->tN.val1);
+      GET4(CAMF->tN.val2);
+      GET4(CAMF->tN.val3);
+
+      /* Set all not read data block pointers to NULL */
+      CAMF->data = NULL;
+      CAMF->data_size = 0;
+
+      /* Set all not allocated help pointers to NULL */
+      CAMF->table.element = NULL;
+      CAMF->table.size = 0;
+      CAMF->tree.nodes = NULL;
+      CAMF->decoded_data = NULL;
+      CAMF->decoded_data_size = 0;
+      CAMF->entry_table.element = NULL;
+      CAMF->entry_table.size = 0;
+    }
+
+    /* Reset the file pointer back to the directory */
+    infile->seek(save_dir_pos, SEEK_SET);
+  }
+
+  return x3f;
+}
+
+
+
+/* --------------------------------------------------------------------- */
+/* Clean up an x3f structure                                             */
+/* --------------------------------------------------------------------- */
+
+/* extern */ x3f_return_t x3f_delete(x3f_t *x3f)
+{
+  x3f_directory_section_t *DS;
+  int d;
+
+  if (x3f == NULL)
+    return X3F_ARGUMENT_ERROR;
+
+  DS = &x3f->directory_section;
+
+  for (d=0; d<DS->num_directory_entries; d++) { 
+    x3f_directory_entry_t *DE = &DS->directory_entry[d];
+    x3f_directory_entry_header_t *DEH = &DE->header;
+
+    if (DEH->identifier == X3F_SECp) {
+      x3f_property_list_t *PL = &DEH->data_subsection.property_list;
+
+      FREE(PL->property_table.element);
+      FREE(PL->data);
+    }
+
+    if (DEH->identifier == X3F_SECi) {
+      x3f_image_data_t *ID = &DEH->data_subsection.image_data;
+
+      cleanup_huffman(&ID->huffman);
+
+      FREE(ID->data);
+    }
+
+    if (DEH->identifier == X3F_SECc) {
+      x3f_camf_t *CAMF = &DEH->data_subsection.camf;
+
+      FREE(CAMF->data);
+      FREE(CAMF->table.element);
+      cleanup_huffman_tree(&CAMF->tree);
+      FREE(CAMF->decoded_data);
+      FREE(CAMF->entry_table.element);
+    }
+  }
+
+  FREE(DS->directory_entry);
+  FREE(x3f);
+
+  return X3F_OK;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Getting a reference to a directory entry                              */
+/* --------------------------------------------------------------------- */
+
+/* TODO: all those only get the first instance */
+
+static x3f_directory_entry_t *x3f_get(x3f_t *x3f,
+                                      uint32_t type,
+                                      uint32_t image_type)
+{
+  x3f_directory_section_t *DS;
+  int d;
+
+  if (x3f == NULL) return NULL;
+
+  DS = &x3f->directory_section;
+
+  for (d=0; d<DS->num_directory_entries; d++) { 
+    x3f_directory_entry_t *DE = &DS->directory_entry[d];
+    x3f_directory_entry_header_t *DEH = &DE->header;
+    
+    if (DEH->identifier == type) {
+      switch (DEH->identifier) {
+      case X3F_SECi:
+        {
+          x3f_image_data_t *ID = &DEH->data_subsection.image_data;
+
+          if (ID->type_format == image_type)
+            return DE;
+        }
+        break;
+      default:
+        return DE;
+      }
+    }
+  }
+
+  return NULL;
+}
+
+/* extern */ x3f_directory_entry_t *x3f_get_raw(x3f_t *x3f)
+{
+  x3f_directory_entry_t *DE;
+
+  if ((DE = x3f_get(x3f, X3F_SECi, X3F_IMAGE_RAW_HUFFMAN_X530)) != NULL)
+    return DE;
+
+  if ((DE = x3f_get(x3f, X3F_SECi, X3F_IMAGE_RAW_HUFFMAN_10BIT)) != NULL)
+    return DE;
+
+  if ((DE = x3f_get(x3f, X3F_SECi, X3F_IMAGE_RAW_TRUE)) != NULL)
+    return DE;
+
+  if ((DE = x3f_get(x3f, X3F_SECi, X3F_IMAGE_RAW_MERRILL)) != NULL)
+    return DE;
+
+  if ((DE = x3f_get(x3f, X3F_SECi, X3F_IMAGE_RAW_QUATTRO)) != NULL)
+    return DE;
+
+  return NULL;
+}
+
+/* extern */ x3f_directory_entry_t *x3f_get_thumb_plain(x3f_t *x3f)
+{
+  return x3f_get(x3f, X3F_SECi, X3F_IMAGE_THUMB_PLAIN);
+}
+
+/* extern */ x3f_directory_entry_t *x3f_get_thumb_huffman(x3f_t *x3f)
+{
+  return x3f_get(x3f, X3F_SECi, X3F_IMAGE_THUMB_HUFFMAN);
+}
+
+/* extern */ x3f_directory_entry_t *x3f_get_thumb_jpeg(x3f_t *x3f)
+{
+  return x3f_get(x3f, X3F_SECi, X3F_IMAGE_THUMB_JPEG);
+}
+
+/* extern */ x3f_directory_entry_t *x3f_get_camf(x3f_t *x3f)
+{
+  return x3f_get(x3f, X3F_SECc, 0);
+}
+
+/* extern */ x3f_directory_entry_t *x3f_get_prop(x3f_t *x3f)
+{
+  return x3f_get(x3f, X3F_SECp, 0);
+}
+
+/* For some obscure reason, the bit numbering is weird. It is
+   generally some kind of "big endian" style - e.g. the bit 7 is the
+   first in a byte and bit 31 first in a 4 byte int. For patterns in
+   the huffman pattern table, bit 27 is the first bit and bit 26 the
+   next one. */
+
+#define PATTERN_BIT_POS(_len, _bit) ((_len) - (_bit) - 1)
+#define MEMORY_BIT_POS(_bit) PATTERN_BIT_POS(8, _bit)
+
+
+/* --------------------------------------------------------------------- */
+/* Huffman Decode                                                        */
+/* --------------------------------------------------------------------- */
+
+/* Make the huffman tree */
+
+#ifdef DBG_PRNT
+static char *display_code(int length, uint32_t code, char *buffer)
+{
+  int i;
+
+  for (i=0; i<length; i++) {
+    int pos = PATTERN_BIT_POS(length, i);
+    buffer[i] = ((code>>pos)&1) == 0 ? '0' : '1';
+  }
+
+  buffer[i] = 0;
+
+  return buffer;
+}
+#endif
+
+static x3f_huffnode_t *new_node(x3f_hufftree_t *tree)
+{
+  x3f_huffnode_t *t = &tree->nodes[tree->free_node_index];
+
+  t->branch[0] = NULL;
+  t->branch[1] = NULL;
+  t->leaf = UNDEFINED_LEAF;
+
+  tree->free_node_index++;
+
+  return t;
+}
+
+static void add_code_to_tree(x3f_hufftree_t *tree,
+                             int length, uint32_t code, uint32_t value)
+{
+  int i;
+
+  x3f_huffnode_t *t = tree->nodes;
+
+  for (i=0; i<length; i++) {
+    int pos = PATTERN_BIT_POS(length, i);
+    int bit = (code>>pos)&1;
+    x3f_huffnode_t *t_next = t->branch[bit];
+
+    if (t_next == NULL)
+      t_next = t->branch[bit] = new_node(tree);
+
+    t = t_next;
+  }
+
+  t->leaf = value;
+}
+
+static void populate_true_huffman_tree(x3f_hufftree_t *tree,
+				       x3f_true_huffman_t *table)
+{
+  int i;
+
+  new_node(tree);
+
+  for (i=0; i<table->size; i++) {
+    x3f_true_huffman_element_t *element = &table->element[i];
+    uint32_t length = element->code_size;
+    
+    if (length != 0) {
+      /* add_code_to_tree wants the code right adjusted */
+      uint32_t code = ((element->code) >> (8 - length)) & 0xff;
+      uint32_t value = i;
+
+      add_code_to_tree(tree, length, code, value);
+
+#ifdef DBG_PRNT
+      {
+        char buffer[100];
+
+        printf("H %5d : %5x : %5d : %02x %08x (%08x) (%s)\n",
+               i, i, value, length, code, value,
+               display_code(length, code, buffer));
+      }
+#endif
+    }
+  }
+}
+
+static void populate_huffman_tree(x3f_hufftree_t *tree,
+				  x3f_table32_t *table,
+				  x3f_table16_t *mapping)
+{
+  int i;
+
+  new_node(tree);
+
+  for (i=0; i<table->size; i++) {
+    uint32_t element = table->element[i];
+
+    if (element != 0) {
+      uint32_t length = HUF_TREE_GET_LENGTH(element);
+      uint32_t code = HUF_TREE_GET_CODE(element); 
+      uint32_t value;
+
+      /* If we have a valid mapping table - then the value from the
+         mapping table shall be used. Otherwise we use the current
+         index in the table as value. */
+      if (table->size == mapping->size)
+        value = mapping->element[i];
+      else
+        value = i;
+
+      add_code_to_tree(tree, length, code, value);
+
+#ifdef DBG_PRNT
+      {
+        char buffer[100];
+
+        printf("H %5d : %5x : %5d : %02x %08x (%08x) (%s)\n",
+               i, i, value, length, code, element,
+               display_code(length, code, buffer));
+      }
+#endif
+    }
+  }
+}
+
+#ifdef DBG_PRNT
+static void print_huffman_tree(x3f_huffnode_t *t, int length, uint32_t code)
+{
+  char buf1[100];
+  char buf2[100];
+
+  printf("%*s (%s,%s) %s (%s)\n",
+         length, length < 1 ? "-" : (code&1) ? "1" : "0",
+         t->branch[0]==NULL ? "-" : "0",
+         t->branch[1]==NULL ? "-" : "1",
+         t->leaf==UNDEFINED_LEAF ? "-" : (sprintf(buf1, "%x", t->leaf),buf1),
+         display_code(length, code, buf2));
+
+  code = code << 1;
+  if (t->branch[0]) print_huffman_tree(t->branch[0], length+1, code+0);
+  if (t->branch[1]) print_huffman_tree(t->branch[1], length+1, code+1);
+}
+#endif
+
+/* Help machinery for reading bits in a memory */
+
+typedef struct bit_state_s {
+  uint8_t *next_address;
+  uint8_t bit_offset;
+  uint8_t bits[8];
+} bit_state_t;
+
+static void set_bit_state(bit_state_t *BS, uint8_t *address)
+{
+  BS->next_address = address;
+  BS->bit_offset = 8;
+}
+
+static uint8_t get_bit(bit_state_t *BS)
+{
+  if (BS->bit_offset == 8) {
+    uint8_t byte = *BS->next_address;
+    int i;
+
+    for (i=7; i>= 0; i--) {
+      BS->bits[i] = byte&1;
+      byte = byte >> 1;
+    }
+    BS->next_address++;
+    BS->bit_offset = 0;
+  }
+
+  return BS->bits[BS->bit_offset++];
+}
+
+/* Decode use the TRUE algorithm */
+
+static int32_t get_true_diff(bit_state_t *BS, x3f_hufftree_t *HTP)
+{
+  int32_t diff;
+  x3f_huffnode_t *node = &HTP->nodes[0];
+  uint8_t bits;
+
+  while (node->branch[0] != NULL || node->branch[1] != NULL) {
+    uint8_t bit = get_bit(BS);
+    x3f_huffnode_t *new_node = node->branch[bit];
+
+    node = new_node;
+    if (node == NULL) {
+#ifdef DCRAW_VERBOSE
+      fprintf(stderr, "Huffman coding got unexpected bit\n");
+#endif
+      return 0;
+    }
+  }
+
+  bits = node->leaf;
+
+  if (bits == 0)
+    diff = 0;
+  else {
+    uint8_t first_bit = get_bit(BS);
+    int i;
+
+    diff = first_bit;
+
+    for (i=1; i<bits; i++)
+      diff = (diff << 1) + get_bit(BS); 
+    
+    if (first_bit == 0)
+      diff -= (1<<bits) - 1;
+  }
+
+  return diff;
+}
+
+/* This code (that decodes one of the X3F color planes, really is a
+   decoding of a compression algorithm suited for Bayer CFA data. In
+   Bayer CFA the data is divided into 2x2 squares that represents
+   (R,G1,G2,B) data. Those four positions are (in this compression)
+   treated as one data stream each, where you store the differences to
+   previous data in the stream. The reason for this is, of course,
+   that the date is more often than not near to the next data in a
+   stream that represents the same color. */
+
+/* TODO: write more about the compression */
+
+static void true_decode_one_color(x3f_image_data_t *ID, int color)
+{
+  x3f_true_t *TRU = ID->tru;
+  uint32_t seed = TRU->seed[color]; /* TODO : Is this correct ? */
+  int row;
+
+  x3f_hufftree_t *tree = &TRU->tree;
+  bit_state_t BS;
+
+  int32_t row_start_acc[2][2];
+  uint32_t rows = ID->rows;
+  uint32_t cols = ID->columns;
+  uint32_t out_cols = ID->columns;
+
+
+  set_bit_state(&BS, TRU->plane_address[color]);
+
+  row_start_acc[0][0] = seed;
+  row_start_acc[0][1] = seed;
+  row_start_acc[1][0] = seed;
+  row_start_acc[1][1] = seed;
+
+
+  int datastep = 1;
+
+  if (ID->type_format == X3F_IMAGE_RAW_QUATTRO) {
+    if(ID->quattro->plane[color].rows < (rows/2)+16)
+	{ 
+		// Half sized layer
+		datastep = 2;
+	}
+    rows = ID->quattro->plane[color].rows;
+    cols = ID->quattro->plane[color].columns;
+  }
+
+
+  for (row = 0; row < rows; row++) 
+  {
+	    uint16_t *dst = TRU->x3rgb16.element + row * out_cols * 3 * datastep+ color;
+		int col;
+		bool_t odd_row = row&1;
+		int32_t acc[2];
+		for (col = 0; col < cols; col++) 
+		{
+			bool_t odd_col = col&1;
+			int32_t diff = get_true_diff(&BS, tree);
+			int32_t prev = col < 2 ? row_start_acc[odd_row][odd_col] : acc[odd_col];
+			int32_t value = prev + diff;
+		    acc[odd_col] = value;
+			if (col < 2)
+				row_start_acc[odd_row][odd_col] = value;
+		    if (col < out_cols) 
+			{ 
+				/* For quattro the input may be larger   than the output */
+				*dst = value;
+				dst += 3*datastep;
+			}
+		}
+  }
+}
+
+static void true_decode(x3f_info_t *I,
+			x3f_directory_entry_t *DE)
+{
+  x3f_directory_entry_header_t *DEH = &DE->header;
+  x3f_image_data_t *ID = &DEH->data_subsection.image_data;
+  int color;
+
+  for (color = 0; color < 3; color++) {
+    true_decode_one_color(ID, color);
+  }
+}
+
+/* Decode use the huffman tree */
+
+static int32_t get_huffman_diff(bit_state_t *BS, x3f_hufftree_t *HTP)
+{
+  int32_t diff;
+  x3f_huffnode_t *node = &HTP->nodes[0];
+
+  while (node->branch[0] != NULL || node->branch[1] != NULL) {
+    uint8_t bit = get_bit(BS);
+    x3f_huffnode_t *new_node = node->branch[bit];
+
+    node = new_node;
+    if (node == NULL) {
+#ifdef DCRAW_VERBOSE
+      fprintf(stderr, "Huffman coding got unexpected bit\n");
+#endif
+      return 0;
+    }
+  }
+
+  diff = node->leaf;
+
+  return diff;
+}
+
+static void huffman_decode_row(x3f_info_t *I,
+                               x3f_directory_entry_t *DE,
+                               int bits,
+                               int row,
+                               int offset,
+                               int *minimum)
+{
+  x3f_directory_entry_header_t *DEH = &DE->header;
+  x3f_image_data_t *ID = &DEH->data_subsection.image_data;
+  x3f_huffman_t *HUF = ID->huffman;
+
+  int16_t c[3] = {offset,offset,offset};
+  int col;
+  bit_state_t BS;
+  
+  set_bit_state(&BS, ((unsigned char*)ID->data) + HUF->row_offsets.element[row]);
+
+  for (col = 0; col < ID->columns; col++) {
+    int color;
+
+    for (color = 0; color < 3; color++) {
+      uint16_t c_fix;
+
+      c[color] += get_huffman_diff(&BS, &HUF->tree);
+      if (c[color] < 0) {
+        c_fix = 0;
+        if (c[color] < *minimum)
+          *minimum = c[color];
+      } else {
+        c_fix = c[color];
+      }
+
+      switch (ID->type_format) {
+      case X3F_IMAGE_RAW_HUFFMAN_X530:
+      case X3F_IMAGE_RAW_HUFFMAN_10BIT:
+        HUF->x3rgb16.element[3*(row*ID->columns + col) + color] = (uint16_t)c_fix;
+        break;
+      case X3F_IMAGE_THUMB_HUFFMAN:
+        HUF->rgb8.element[3*(row*ID->columns + col) + color] = (uint8_t)c_fix; 
+        break;
+      default:
+#ifdef DCRAW_VERBOSE
+        fprintf(stderr, "Unknown huffman image type\n");
+#endif
+		break;
+      }
+    }
+  }
+}
+
+static void huffman_decode(x3f_info_t *I,
+                           x3f_directory_entry_t *DE,
+                           int bits)
+{
+  x3f_directory_entry_header_t *DEH = &DE->header;
+  x3f_image_data_t *ID = &DEH->data_subsection.image_data;
+
+  int row;
+  int minimum = 0;
+  int offset = legacy_offset;
+
+#ifdef DCRAW_VERBOSE
+  printf("Huffman decode with offset: %d\n", offset);
+#endif
+  for (row = 0; row < ID->rows; row++)
+    huffman_decode_row(I, DE, bits, row, offset, &minimum);
+
+  if (auto_legacy_offset && minimum < 0) {
+    offset = -minimum;
+#ifdef DCRAW_VERBOSE
+    printf("Redo with offset: %d\n", offset);
+#endif
+    for (row = 0; row < ID->rows; row++)
+      huffman_decode_row(I, DE, bits, row, offset, &minimum);
+  }
+}
+
+static int32_t get_simple_diff(x3f_huffman_t *HUF, uint16_t index)
+{
+  if (HUF->mapping.size == 0)
+    return index;
+  else
+    return HUF->mapping.element[index];
+}
+
+static void simple_decode_row(x3f_info_t *I,
+                              x3f_directory_entry_t *DE,
+                              int bits,
+                              int row,
+                              int row_stride)
+{
+  x3f_directory_entry_header_t *DEH = &DE->header;
+  x3f_image_data_t *ID = &DEH->data_subsection.image_data;
+  x3f_huffman_t *HUF = ID->huffman;
+
+  uint32_t *data = (uint32_t *)((unsigned char*)ID->data + row*row_stride); 
+
+  uint16_t c[3] = {0,0,0};
+  int col;
+
+  uint32_t mask = 0;
+
+  switch (bits) {
+  case 8:
+    mask = 0x0ff;
+    break;
+  case 9:
+    mask = 0x1ff;
+    break;
+  case 10:
+    mask = 0x3ff;
+    break;
+  case 11:
+    mask = 0x7ff;
+    break;
+  case 12:
+    mask = 0xfff;
+    break;
+  default:
+#ifdef DCRAW_VERBOSE
+    fprintf(stderr, "Unknown number of bits: %d\n", bits);
+#endif
+    mask = 0;
+    break;
+  }
+
+  for (col = 0; col < ID->columns; col++) {
+    int color;
+    uint32_t val = data[col];
+
+    for (color = 0; color < 3; color++) {
+      uint16_t c_fix;
+      c[color] += get_simple_diff(HUF, (val>>(color*bits))&mask);
+
+      switch (ID->type_format) {
+      case X3F_IMAGE_RAW_HUFFMAN_X530:
+      case X3F_IMAGE_RAW_HUFFMAN_10BIT:
+        c_fix = (int16_t)c[color] > 0 ? c[color] : 0;
+
+        HUF->x3rgb16.element[3*(row*ID->columns + col) + color] = c_fix; 
+        break;
+      case X3F_IMAGE_THUMB_HUFFMAN:
+        c_fix = (int8_t)c[color] > 0 ? c[color] : 0;
+
+        HUF->rgb8.element[3*(row*ID->columns + col) + color] = c_fix; 
+        break;
+      default:
+#ifdef DCRAW_VERBOSE
+        fprintf(stderr, "Unknown huffman image type\n");
+#endif
+		break;
+      }
+    }
+  }
+}
+
+static void simple_decode(x3f_info_t *I,
+                          x3f_directory_entry_t *DE,
+                          int bits,
+                          int row_stride)
+{
+  x3f_directory_entry_header_t *DEH = &DE->header;
+  x3f_image_data_t *ID = &DEH->data_subsection.image_data;
+
+  int row;
+
+  for (row = 0; row < ID->rows; row++)
+    simple_decode_row(I, DE, bits, row, row_stride);
+}
+
+/* --------------------------------------------------------------------- */
+/* Loading the data in a directory entry                                 */
+/* --------------------------------------------------------------------- */
+
+/* First you set the offset to where to start reading the data ... */
+
+static void read_data_set_offset(x3f_info_t *I,
+                                 x3f_directory_entry_t *DE,
+                                 uint32_t header_size)
+{
+  uint32_t i_off = DE->input.offset + header_size;
+
+  I->input.file->seek(i_off, SEEK_SET);
+}
+
+/* ... then you read the data, block for block */
+
+static uint32_t read_data_block(void **data,
+                                x3f_info_t *I,
+                                x3f_directory_entry_t *DE,
+                                uint32_t footer)
+{
+  uint32_t size =
+    DE->input.size + DE->input.offset - I->input.file->tell() - footer;
+
+  *data = (void *)malloc(size);
+
+  GETN(*data, size);
+
+  return size;
+}
+
+static void x3f_load_image_verbatim(x3f_info_t *I, x3f_directory_entry_t *DE)
+{
+  x3f_directory_entry_header_t *DEH = &DE->header;
+  x3f_image_data_t *ID = &DEH->data_subsection.image_data;
+
+#ifdef DCRAW_VERBOSE
+  printf("Load image verbatim\n");
+#endif
+
+  ID->data_size = read_data_block((void**)&ID->data, I, DE, 0);
+}
+
+static void x3f_load_property_list(x3f_info_t *I, x3f_directory_entry_t *DE)
+{
+  x3f_directory_entry_header_t *DEH = &DE->header;
+  x3f_property_list_t *PL = &DEH->data_subsection.property_list;
+
+  int i;
+
+  read_data_set_offset(I, DE, X3F_PROPERTY_LIST_HEADER_SIZE);
+
+  GET_PROPERTY_TABLE(PL->property_table, PL->num_properties);
+
+  PL->data_size = read_data_block(&PL->data, I, DE, 0);
+
+  for (i=0; i<PL->num_properties; i++) {
+    x3f_property_t *P = &PL->property_table.element[i];
+ 
+    P->name = ((utf16_t *)PL->data + P->name_offset);
+    P->value = ((utf16_t *)PL->data + P->value_offset);
+  }
+}
+
+static void x3f_load_true(x3f_info_t *I,
+			  x3f_directory_entry_t *DE)
+{
+  x3f_directory_entry_header_t *DEH = &DE->header;
+  x3f_image_data_t *ID = &DEH->data_subsection.image_data;
+  x3f_true_t *TRU = new_true(&ID->tru);
+  x3f_quattro_t *Q = NULL;
+  int i;
+
+  if (ID->type_format == X3F_IMAGE_RAW_QUATTRO) {
+#ifdef DCRAW_VERBOSE
+    printf("Load Quattro extra info\n");
+#endif
+    Q = new_quattro(&ID->quattro);
+
+    for (i=0; i<TRUE_PLANES; i++) {
+      GET2(Q->plane[i].columns);
+      GET2(Q->plane[i].rows);
+    }
+  }
+#ifdef DCRAW_VERBOSE
+  printf("Load TRUE\n");
+#endif
+
+  /* Read TRUE header data */
+  GET2(TRU->seed[0]);		/* TODO : should it always be 512 ?? */
+  GET2(TRU->seed[1]);		/* TODO : should it always be 512 ?? */
+  GET2(TRU->seed[2]);		/* TODO : should it always be 512 ?? */
+  GET2(TRU->unknown);		/* TODO : should it always be zero ?? */
+  GET_TRUE_HUFF_TABLE(TRU->table);
+
+  if (ID->type_format == X3F_IMAGE_RAW_QUATTRO) {
+#ifdef DCRAW_VERBOSE
+    printf("Load Quattro extra info 2\n");
+#endif
+    GET4(Q->unknown);
+  }
+
+  GET_TABLE(TRU->plane_size, GET4, TRUE_PLANES,uint32_t);
+
+  /* Read image data */
+  ID->data_size = read_data_block(&ID->data, I, DE, 0);
+
+  /* TODO: can it be fewer than 8 bits? Maybe taken from TRU->table? */  
+  new_huffman_tree(&TRU->tree, 8);
+
+  populate_true_huffman_tree(&TRU->tree, &TRU->table);
+
+#ifdef DBG_PRNT
+  print_huffman_tree(TRU->tree.nodes, 0, 0);
+#endif
+
+  TRU->plane_address[0] = (uint8_t*)ID->data;
+  for (i=1; i<TRUE_PLANES; i++)
+    TRU->plane_address[i] = 
+      TRU->plane_address[i-1] +
+      (((TRU->plane_size.element[i-1] + 15) / 16) * 16); 
+
+  TRU->x3rgb16.size = ID->columns * ID->rows * 3;
+  TRU->x3rgb16.element =
+    (uint16_t *)malloc(sizeof(uint16_t)*TRU->x3rgb16.size);
+
+  true_decode(I, DE);
+}
+
+static void x3f_load_huffman_compressed(x3f_info_t *I,
+                                        x3f_directory_entry_t *DE,
+                                        int bits,
+                                        int use_map_table)
+{
+  x3f_directory_entry_header_t *DEH = &DE->header;
+  x3f_image_data_t *ID = &DEH->data_subsection.image_data;
+  x3f_huffman_t *HUF = ID->huffman;
+  int table_size = 1<<bits;
+  int row_offsets_size = ID->rows * sizeof(HUF->row_offsets.element[0]);
+
+#ifdef DCRAW_VERBOSE
+  printf("Load huffman compressed\n");
+#endif
+  GET_TABLE(HUF->table, GET4, table_size,uint32_t);
+
+  ID->data_size = read_data_block(&ID->data, I, DE, row_offsets_size);
+
+  GET_TABLE(HUF->row_offsets, GET4, ID->rows,uint32_t);
+#ifdef DCRAW_VERBOSE
+  printf("Make huffman tree ...\n");
+#endif
+  new_huffman_tree(&HUF->tree, bits);
+  populate_huffman_tree(&HUF->tree, &HUF->table, &HUF->mapping);
+#ifdef DCRAW_VERBOSE
+  printf("... DONE\n");
+#endif
+#ifdef DBG_PRNT
+  print_huffman_tree(HUF->tree.nodes, 0, 0);
+#endif
+
+  huffman_decode(I, DE, bits);
+}
+
+static void x3f_load_huffman_not_compressed(x3f_info_t *I,
+                                            x3f_directory_entry_t *DE,
+                                            int bits,
+                                            int use_map_table,
+                                            int row_stride)
+{
+  x3f_directory_entry_header_t *DEH = &DE->header;
+  x3f_image_data_t *ID = &DEH->data_subsection.image_data;
+#ifdef DCRAW_VERBOSE
+  printf("Load huffman not compressed\n");
+#endif
+  ID->data_size = read_data_block(&ID->data, I, DE, 0);
+
+  simple_decode(I, DE, bits, row_stride);
+}
+
+static void x3f_load_huffman(x3f_info_t *I,
+                             x3f_directory_entry_t *DE,
+                             int bits,
+                             int use_map_table,
+                             int row_stride)
+{
+  x3f_directory_entry_header_t *DEH = &DE->header;
+  x3f_image_data_t *ID = &DEH->data_subsection.image_data;
+  x3f_huffman_t *HUF = new_huffman(&ID->huffman);
+
+  if (use_map_table) {
+    int table_size = 1<<bits;
+
+    GET_TABLE(HUF->mapping, GET2, table_size,uint16_t); 
+  }
+
+  switch (ID->type_format) {
+  case X3F_IMAGE_RAW_HUFFMAN_X530:
+  case X3F_IMAGE_RAW_HUFFMAN_10BIT:
+    HUF->x3rgb16.size = ID->columns * ID->rows * 3;
+    HUF->x3rgb16.element =
+      (uint16_t *)malloc(sizeof(uint16_t)*HUF->x3rgb16.size);
+    break;
+  case X3F_IMAGE_THUMB_HUFFMAN:
+    HUF->rgb8.size = ID->columns * ID->rows * 3;
+    HUF->rgb8.element =
+      (uint8_t *)malloc(sizeof(uint8_t)*HUF->rgb8.size);
+    break;
+  default:
+#ifdef DCRAW_VERBOSE
+    fprintf(stderr, "Unknown huffman image type\n");
+#endif
+	break;
+  }
+
+  if (row_stride == 0)
+    return x3f_load_huffman_compressed(I, DE, bits, use_map_table);
+  else
+    return x3f_load_huffman_not_compressed(I, DE, bits, use_map_table, row_stride);
+}
+
+static void x3f_load_pixmap(x3f_info_t *I, x3f_directory_entry_t *DE)
+{
+  x3f_load_image_verbatim(I, DE);
+}
+
+static void x3f_load_jpeg(x3f_info_t *I, x3f_directory_entry_t *DE)
+{
+  x3f_load_image_verbatim(I, DE);
+}
+
+static void x3f_load_image(x3f_info_t *I, x3f_directory_entry_t *DE)
+{
+  x3f_directory_entry_header_t *DEH = &DE->header;
+  x3f_image_data_t *ID = &DEH->data_subsection.image_data;
+
+  read_data_set_offset(I, DE, X3F_IMAGE_HEADER_SIZE);
+  
+  switch (ID->type_format) {
+  case X3F_IMAGE_RAW_TRUE:
+  case X3F_IMAGE_RAW_MERRILL:
+  case X3F_IMAGE_RAW_QUATTRO:
+    x3f_load_true(I, DE);
+    break;
+  case X3F_IMAGE_RAW_HUFFMAN_X530:
+  case X3F_IMAGE_RAW_HUFFMAN_10BIT:
+    x3f_load_huffman(I, DE, 10, 1, ID->row_stride);
+    break;
+  case X3F_IMAGE_THUMB_PLAIN:
+    x3f_load_pixmap(I, DE);
+    break;
+  case X3F_IMAGE_THUMB_HUFFMAN:
+    x3f_load_huffman(I, DE, 8, 0, ID->row_stride);
+    break;
+  case X3F_IMAGE_THUMB_JPEG:
+    x3f_load_jpeg(I, DE);
+    break;
+  default:
+#ifdef DCRAW_VERBOSE
+    fprintf(stderr, "Unknown image type\n");
+#endif
+	break;
+  }
+}
+
+static void x3f_load_camf_decode_type2(x3f_camf_t *CAMF)
+{
+  uint32_t key = CAMF->t2.crypt_key;
+  int i;
+
+  CAMF->decoded_data_size = CAMF->data_size;
+  CAMF->decoded_data = malloc(CAMF->decoded_data_size);
+
+  for (i=0; i<CAMF->data_size; i++) {
+    uint8_t old, _new;
+    uint32_t tmp;
+
+    old = ((uint8_t *)CAMF->data)[i];
+    key = (key * 1597 + 51749) % 244944;
+    tmp = (uint32_t)(key * ((int64_t)301593171) >> 24);
+    _new = (uint8_t)(old ^ (uint8_t)(((((key << 8) - tmp) >> 1) + tmp) >> 17));
+    ((uint8_t *)CAMF->decoded_data)[i] = _new;
+  }
+}
+
+
+/* NOTE: the unpacking in this code is in big respects identical to
+   true_decode_one_color(). The difference is in the output you
+   build. It might be possible to make some parts shared. NOTE ALSO:
+   This means that the meta data is obfuscated using an image
+   compression algorithm. */
+
+static void camf_decode_type4(x3f_camf_t *CAMF)
+{
+  uint32_t seed = CAMF->t4.decode_bias;
+  int row;
+
+  uint8_t *dst;
+  bool_t odd_dst = 0;
+
+  x3f_hufftree_t *tree = &CAMF->tree;
+  bit_state_t BS;
+
+  int32_t row_start_acc[2][2];
+  uint32_t rows = CAMF->t4.block_count;
+  uint32_t cols = CAMF->t4.block_size;
+
+  CAMF->decoded_data_size = (cols * rows * 3) / 2;
+  CAMF->decoded_data = malloc(CAMF->decoded_data_size);
+
+  dst = (uint8_t *)CAMF->decoded_data;
+
+  set_bit_state(&BS, CAMF->decoding_start);
+
+  row_start_acc[0][0] = seed;
+  row_start_acc[0][1] = seed;
+  row_start_acc[1][0] = seed;
+  row_start_acc[1][1] = seed;
+
+  for (row = 0; row < rows; row++) {
+    int col;
+    bool_t odd_row = row&1;
+    int32_t acc[2];
+
+    for (col = 0; col < cols; col++) {
+      bool_t odd_col = col&1;
+      int32_t diff = get_true_diff(&BS, tree);
+      int32_t prev = col < 2 ?
+	row_start_acc[odd_row][odd_col] :
+	acc[odd_col];
+      int32_t value = prev + diff;
+
+      acc[odd_col] = value;
+      if (col < 2)
+	row_start_acc[odd_row][odd_col] = value;
+
+      switch(odd_dst) {
+      case 0:
+	*dst++  = (uint8_t)((value>>4)&0xff);
+	*dst    = (uint8_t)((value<<4)&0xf0);
+	break;
+      case 1:
+	*dst++ |= (uint8_t)((value>>8)&0x0f);
+	*dst++  = (uint8_t)((value<<0)&0xff);
+	break;
+      }
+
+      odd_dst = !odd_dst;
+
+    } /* end col */
+  } /* end row */
+}
+
+static void x3f_load_camf_decode_type4(x3f_camf_t *CAMF)
+{
+  int i;
+  uint8_t *p;
+  x3f_true_huffman_element_t *element = NULL;
+
+  for (i=0, p = (uint8_t*)CAMF->data; *p != 0; i++) {
+    /* TODO: Is this too expensive ??*/
+    element =
+      (x3f_true_huffman_element_t *)realloc(element, (i+1)*sizeof(*element));
+
+    element[i].code_size = *p++;
+    element[i].code = *p++;
+  }
+
+  CAMF->table.size = i;
+  CAMF->table.element = element;
+
+  /* TODO: where does thes value 32 come from? */
+#define CAMF_T4_DATA_OFFSET 32
+  CAMF->decoding_start = (uint8_t *)CAMF->data + CAMF_T4_DATA_OFFSET;
+
+  /* TODO: can it be fewer than 8 bits? Maybe taken from TRU->table? */  
+  new_huffman_tree(&CAMF->tree, 8);
+
+  populate_true_huffman_tree(&CAMF->tree, &CAMF->table);
+
+#ifdef DBG_PRNT
+  print_huffman_tree(CAMF->tree.nodes, 0, 0);
+#endif
+
+  camf_decode_type4(CAMF);
+}
+
+static void x3f_setup_camf_entries(x3f_camf_t *CAMF)
+{
+  uint8_t *p = (uint8_t *)CAMF->decoded_data;
+  uint8_t *end = p + CAMF->decoded_data_size;
+  camf_entry_t *table = NULL;
+  int i;
+
+  for (i=0; p < end; i++) {
+    uint32_t *p4 = (uint32_t *)p;
+
+    if ((*p4 & 0xffffff) != X3F_CMb) {
+      /* TODO: whats this all about ? Is it OK to just terminate if
+	 you find an invalid entry ? */
+#ifdef DCRAW_VERBOSE
+      fprintf(stderr, "Unknown CAMF entry %x\n", *p4);
+#endif
+      break;
+    }
+
+    /* TODO: lots of realloc - may be inefficient */
+    table = (camf_entry_t *)realloc(table, (i+1)*sizeof(camf_entry_t));
+
+    table[i].id = *p4++;
+    table[i].version = *p4++;
+    table[i].entry_size = *p4++;
+    table[i].name_offset = *p4++;
+    table[i].value_offset = *p4++;
+
+    table[i].entry = p;
+
+    table[i].name_address = p + table[i].name_offset; 
+    table[i].value_address = p + table[i].value_offset; 
+
+    p += table[i].entry_size;
+  }
+
+  CAMF->entry_table.size = i;
+  CAMF->entry_table.element = table;
+}
+
+static void x3f_load_camf(x3f_info_t *I, x3f_directory_entry_t *DE)
+{
+  x3f_directory_entry_header_t *DEH = &DE->header;
+  x3f_camf_t *CAMF = &DEH->data_subsection.camf;
+
+  read_data_set_offset(I, DE, X3F_CAMF_HEADER_SIZE);
+
+  CAMF->data_size = read_data_block(&CAMF->data, I, DE, 0);
+
+  switch (CAMF->type) {
+  case 2:			/* Older SD9-SD14 */
+    x3f_load_camf_decode_type2(CAMF);
+    break;
+  case 4:			/* TRUE DP1-... */
+    x3f_load_camf_decode_type4(CAMF);
+    break;
+  default:
+#ifdef DCRAW_VERBOSE
+    fprintf(stderr, "Unknown CAMF type\n");
+#endif
+	break;
+  }
+
+  if (CAMF->decoded_data != NULL)
+    x3f_setup_camf_entries(CAMF);
+#ifdef DCRAW_VERBOSE
+  else
+    fprintf(stderr, "No decoded CAMF data\n");
+#endif
+}
+
+/* extern */ x3f_return_t x3f_load_data(x3f_t *x3f, x3f_directory_entry_t *DE)
+{
+  x3f_info_t *I = &x3f->info;
+
+  if (DE == NULL)
+    return X3F_ARGUMENT_ERROR;
+
+  switch (DE->header.identifier) {
+  case X3F_SECp:
+    x3f_load_property_list(I, DE);
+    break;
+  case X3F_SECi:
+    x3f_load_image(I, DE);
+    break;
+  case X3F_SECc:
+    x3f_load_camf(I, DE);
+    break;
+  default:
+#ifdef DCRAW_VERBOSE
+    fprintf(stderr, "Unknown directory entry type\n");
+#endif
+    return X3F_INTERNAL_ERROR;
+  }
+
+  return X3F_OK;
+}
+
+/* extern */ x3f_return_t x3f_load_image_block(x3f_t *x3f, x3f_directory_entry_t *DE)
+{
+  x3f_info_t *I = &x3f->info;
+
+  if (DE == NULL)
+    return X3F_ARGUMENT_ERROR;
+
+  switch (DE->header.identifier) {
+  case X3F_SECi:
+    read_data_set_offset(I, DE, X3F_IMAGE_HEADER_SIZE);
+    x3f_load_image_verbatim(I, DE);
+    break;
+  default:
+#ifdef DCRAW_VERBOSE
+    fprintf(stderr, "Unknown image directory entry type\n");
+#endif
+    return X3F_INTERNAL_ERROR;
+  }
+
+  return X3F_OK;
+}
+
+
+
+/* --------------------------------------------------------------------- */
+/* The End                                                               */
+/* --------------------------------------------------------------------- */
diff --git a/Source/LibRawLite/internal/preprocess.pl b/Source/LibRawLite/internal/preprocess.pl
new file mode 100644
index 0000000..3561f43
--- /dev/null
+++ b/Source/LibRawLite/internal/preprocess.pl
@@ -0,0 +1,99 @@
+#!/usr/bin/perl
+ 
+# File: preprocess.pl
+# Copyright 2008-2013 LibRaw LLC (info at libraw.org)
+# Created: Sat Mar  8, 2008
+# LibRaw preprocessor for dcraw source
+#
+
+use strict;
+use Getopt::Std;
+
+my %opts;
+getopts('D:N',\%opts);
+my $tag = $opts{D};
+my $nolines = $opts{N};
+
+die 'use -DTAG option to specify tags, use __ALL__ tag to out all @out sections' unless $tag;
+
+process_file($_) foreach @ARGV;
+
+sub process_file
+  {
+    my $file = shift;
+    return unless $file;
+    open O,$file or die;
+    my $lno = 0;
+    my $out = 0;
+    my $date = scalar localtime;
+print <<EOM;
+/* 
+  Copyright 2008-2013 LibRaw LLC (info\@libraw.org)
+
+LibRaw is free software; you can redistribute it and/or modify
+it under the terms of the one of three licenses as you choose:
+
+1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
+   (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
+
+2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
+   (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
+
+3. LibRaw Software License 27032010
+   (See file LICENSE.LibRaw.pdf provided in LibRaw distribution archive for details).
+
+   This file is generated from Dave Coffin's dcraw.c
+   dcraw.c -- Dave Coffin's raw photo decoder
+   Copyright 1997-2010 by Dave Coffin, dcoffin a cybercom o net
+
+   Look into dcraw homepage (probably http://cybercom.net/~dcoffin/dcraw/)
+   for more information
+*/
+
+EOM
+    while (my $line= <>)
+      {
+        $lno++;
+        if ($line=~m|^\s*/\*\s*\@_emit\s+(.*)\*/\s*$|)
+          {
+            print "$1\n" if $out;
+            next;
+          }
+        if ($line=~/^\s*(\/\/\s*\@out|\/\*\s*\@out)\s+(.*)/)
+          {
+            my @tags = split(/\s+/,$2);
+            $out = 1 if $tag eq '__ALL__';
+            foreach my $t (@tags)
+              {
+                if ($t eq $tag)
+                  {
+                    $out = 1;
+                    print "#line ".($lno+1)." \"$file\"\n" unless $nolines;
+                    last;
+                  }
+              }
+            next;
+          }
+        if ($line=~/^\s*\/\/\s*\@end\s+(.*)/)
+          {
+            my @tags = split(/\s+/,$1);
+            $out = 0 if $tag eq '__ALL__';
+            foreach my $t (@tags)
+              {
+                $out = 0 if $t eq $tag;
+              }
+            next;
+          }
+        if ($line=~/^\s*\@end\s+(.*)\*\/\s*$/)
+          {
+            my @tags = split(/\s+/,$1);
+            $out = 0 if $tag eq '__ALL__';
+            foreach my $t (@tags)
+              {
+                $out = 0 if $t eq $tag;
+              }
+            next;
+          }
+        print $line if $out;
+      }
+  }
diff --git a/Source/LibRawLite/internal/var_defines.h b/Source/LibRawLite/internal/var_defines.h
index 6c91654..641209e 100644
--- a/Source/LibRawLite/internal/var_defines.h
+++ b/Source/LibRawLite/internal/var_defines.h
@@ -1,6 +1,6 @@
 /* -*- C++ -*-
  * File: var_defines.h
- * Copyright 2008-2009 LibRaw LLC (info at libraw.org)
+ * Copyright 2008-2013 LibRaw LLC (info at libraw.org)
  * Created: Sat Mar  8, 2008
  *
  * LibRaw redefinitions of dcraw internal variables
@@ -21,16 +21,21 @@ it under the terms of the one of three licenses as you choose:
 #ifndef VAR_DEFINES_H
 #define VAR_DEFINES_H
 
+
 // imgdata.idata
 #define make            (imgdata.idata.make)
 #define model           (imgdata.idata.model)
+#define software        (imgdata.idata.software)
 #define is_raw          (imgdata.idata.raw_count)
 #define dng_version     (imgdata.idata.dng_version)
 #define is_foveon       (imgdata.idata.is_foveon)
 #define colors          (imgdata.idata.colors)
 #define cdesc           (imgdata.idata.cdesc)
 #define filters         (imgdata.idata.filters)
-
+#define xtrans          (imgdata.idata.xtrans)
+#define xtrans_abs      (imgdata.idata.xtrans_abs)
+#define xmpdata			(imgdata.idata.xmpdata)
+#define xmplen			(imgdata.idata.xmplen)
 //imgdata image
 #define image           (imgdata.image)
 #define raw_image       (imgdata.rawdata.raw_image)
@@ -39,6 +44,7 @@ it under the terms of the one of three licenses as you choose:
 // imgdata.sizes
 #define raw_height      (imgdata.sizes.raw_height)
 #define raw_width       (imgdata.sizes.raw_width)
+#define raw_pitch       (imgdata.sizes.raw_pitch)
 #define height          (imgdata.sizes.height)
 #define width           (imgdata.sizes.width)
 #define top_margin      (imgdata.sizes.top_margin)
@@ -49,6 +55,7 @@ it under the terms of the one of three licenses as you choose:
 #define iwidth          (imgdata.sizes.iwidth)
 #define pixel_aspect    (imgdata.sizes.pixel_aspect)
 #define flip            (imgdata.sizes.flip)
+#define mask            (imgdata.sizes.mask)
 
 //imgdata.color
 #define white           (imgdata.color.white)
@@ -71,6 +78,7 @@ it under the terms of the one of three licenses as you choose:
 #define flash_used      (imgdata.color.flash_used)
 #define canon_ev        (imgdata.color.canon_ev)
 #define model2          (imgdata.color.model2)
+#define baseline_exposure  (imgdata.color.baseline_exposure)
 
 //imgdata.thumbnail
 
@@ -101,7 +109,6 @@ it under the terms of the one of three licenses as you choose:
 #define threshold       (imgdata.params.threshold)
 #define half_size       (imgdata.params.half_size)
 #define four_color_rgb  (imgdata.params.four_color_rgb)
-#define document_mode   (imgdata.params.document_mode)
 #define highlight       (imgdata.params.highlight)
 //#define verbose         (imgdata.params.verbose)
 #define use_auto_wb     (imgdata.params.use_auto_wb)
@@ -113,6 +120,7 @@ it under the terms of the one of three licenses as you choose:
 #define output_tiff     (imgdata.params.output_tiff)
 #define med_passes      (imgdata.params.med_passes)
 #define no_auto_bright  (imgdata.params.no_auto_bright)
+#define auto_bright_thr  (imgdata.params.auto_bright_thr)
 #define use_fuji_rotate (imgdata.params.use_fuji_rotate)
 #define filtering_mode (imgdata.params.filtering_mode)
 
@@ -144,6 +152,7 @@ it under the terms of the one of three licenses as you choose:
 #define ofp             libraw_internal_data.internal_data.output
 #define profile_offset  (libraw_internal_data.internal_data.profile_offset)
 #define thumb_offset    (libraw_internal_data.internal_data.toffset)
+#define pana_black		(libraw_internal_data.internal_data.pana_black)
 
 //libraw_internal_data.internal_output_params
 #define mix_green       (libraw_internal_data.internal_output_params.mix_green)
@@ -193,6 +202,7 @@ it under the terms of the one of three licenses as you choose:
 #define fseeko(stream,o,w)	 stream->seek(o,w)
 #define ftell(stream)		 stream->tell()
 #define ftello(stream)		 stream->tell()
+#define feof(stream)		 stream->eof()
 #ifdef getc
 #undef getc
 #endif
diff --git a/Source/LibRawLite/internal/wf_filtering.cpp b/Source/LibRawLite/internal/wf_filtering.cpp
new file mode 100644
index 0000000..48b091c
--- /dev/null
+++ b/Source/LibRawLite/internal/wf_filtering.cpp
@@ -0,0 +1,1950 @@
+/* 
+   WF debanding code
+   Copyright 2011 by Yan Vladimirovich
+
+   Used in LibRaw with author permission.
+
+LibRaw is free software; you can redistribute it and/or modify
+it under the terms of the one of three licenses as you choose:
+
+1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
+   (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
+
+2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
+   (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
+
+3. LibRaw Software License 27032010
+   (See file LICENSE.LibRaw.pdf provided in LibRaw distribution archive for details).
+
+   This file is generated from Dave Coffin's dcraw.c
+   dcraw.c -- Dave Coffin's raw photo decoder
+   Copyright 1997-2010 by Dave Coffin, dcoffin a cybercom o net
+
+   Look into dcraw homepage (probably http://cybercom.net/~dcoffin/dcraw/)
+   for more information
+*/
+
+
+#define P1 imgdata.idata
+#define S imgdata.sizes
+#define O imgdata.params
+#define C imgdata.color
+#define T imgdata.thumbnail
+#define IO libraw_internal_data.internal_output_params
+#define ID libraw_internal_data.internal_data
+
+
+int LibRaw::wf_remove_banding()
+{
+#define WF_IMGMODE_BAYER4PLANE 4
+#define WF_IMGMODE_BAYER1PLANE 1
+
+#define WF_GREENMODE_IND   0
+#define WF_GREENMODE_GX_XG 1
+#define WF_GREENMODE_XG_GX 2
+
+#define WF_DEBANDING_OK          0
+#define WF_DEBANDING_NOTBAYER2X2 1
+#define WF_DEBANDING_TOOSMALL    2
+
+#define WF_GAUSS_PIRAMID_SIZE 4
+
+#define WF_MAXTRESHOLD 65536
+
+#define WF_BAYERSRC(row, col, c) ((ushort(*)[4])imgdata.image)[((row) >> IO.shrink)*S.iwidth + ((col) >> IO.shrink)][c] 
+#define WF_BAYERGAU(l, row, col) (gauss_pyramid[l])[((row) >> IO.shrink)*S.iwidth + ((col) >> IO.shrink)] 
+#define WF_BAYERDFG(l, row, col) (difwg_pyramid[l])[((row) >> IO.shrink)*S.iwidth + ((col) >> IO.shrink)] 
+	
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+
+#define WF_i_1TO4 for(int i=0; i<4; i++)
+
+	// too small?
+
+	if (S.width<128 || S.height<128)
+		return WF_DEBANDING_TOOSMALL;
+
+	// is 2x2 bayer? 
+
+	int bayer2x2flag=-1;
+
+	for(int row_shift=0; row_shift<=8; row_shift+=2)
+	{
+		for(int col_shift=0; col_shift<=8; col_shift+=2)
+		{
+			if ((FC(0,0)!=FC(row_shift,   col_shift))   ||
+				(FC(1,0)!=FC(row_shift+1, col_shift))   ||
+				(FC(0,1)!=FC(row_shift,   col_shift+1)) ||
+				(FC(1,1)!=FC(row_shift+1, col_shift+1)))
+			{
+				bayer2x2flag=0;
+			}
+		}
+	}
+
+	if (bayer2x2flag==0)
+		return WF_DEBANDING_NOTBAYER2X2;
+
+	int    x_green_flag = -1;
+
+	int    width_d2,    height_d2;
+	int    width_p1_d2, height_p1_d2;
+
+	width_d2  = S.width/2;
+	height_d2 = S.height/2;
+	
+	width_p1_d2  = (S.width+1)/2;
+	height_p1_d2 = (S.height+1)/2;
+
+	ushort  val_max_c[4]={0,0,0,0};
+	ushort  val_max;
+
+	ushort  dummy_pixel=0;
+	ushort *dummy_line;
+
+	dummy_line = (ushort*)calloc(S.width, sizeof(ushort)*4);
+
+	for(int i=0; i<S.width*4; i++)
+		dummy_line[i]=0;
+
+	// Searching max value for increasing bit-depth
+
+	for(int row_d2=0; row_d2<height_p1_d2; row_d2++)
+	{
+		int     row, row_p1;
+		ushort *src[4];
+		ushort *src_first, *src_plast, *src_last;
+		
+		row    = row_d2*2;
+		row_p1 = row+1;
+
+		WF_i_1TO4 src[i] = &WF_BAYERSRC((i<2)?row:row_p1, i&1, FC((i<2)?row:row_p1, i&1));
+
+		if (row_p1==S.height)
+			src[2]=src[3]=dummy_line;
+
+		src_first   = &WF_BAYERSRC(row,   0,               FC(row,   0));
+		src_plast   = &WF_BAYERSRC(row,   width_d2*2-2,    FC(row,   0));
+		src_last    = &WF_BAYERSRC(row,   width_p1_d2*2-2, FC(row,   0));
+
+		do
+		{
+			// Do
+
+			WF_i_1TO4 val_max_c[i]=MAX(val_max_c[i], *src[i]);
+
+			// Next 4 pixel or exit
+
+			if     (src[0]<src_plast)
+			{
+				WF_i_1TO4 src[i]+=8;
+			}
+			else if(src[0]>src_first && src[0]<src_last)
+			{
+				WF_i_1TO4 src[i]=i&1?&dummy_pixel:src[i]+8;
+			}
+			else break;
+
+		}
+		while(1);
+	}
+
+	val_max=MAX(MAX(val_max_c[0], val_max_c[1]), MAX(val_max_c[2], val_max_c[3]));
+	
+	// end of searching max value
+
+	if (val_max==0)
+		return WF_DEBANDING_OK;
+		
+	int data_shift;
+	int data_mult;
+	int val_max_s;
+
+	data_shift = 15;
+	val_max_s  = val_max;
+
+	if (val_max_s >= (1 << 8)) { val_max_s >>= 8; data_shift -=  8; }
+	if (val_max_s >= (1 << 4)) { val_max_s >>= 4; data_shift -=  4; }
+	if (val_max_s >= (1 << 2)) { val_max_s >>= 2; data_shift -=  2; }
+	if (val_max_s >= (1 << 1)) {                  data_shift -=  1; }
+  
+	data_mult = 1<<data_shift;
+	val_max <<= data_shift;
+		
+	// Bit shift
+
+	for(int row_d2=0; row_d2<height_p1_d2; row_d2++)
+	{
+		int     row, row_p1;
+		ushort *src[4];
+		ushort *src_first, *src_plast, *src_last;
+		
+		row    = row_d2*2;
+		row_p1 = row+1;
+
+		WF_i_1TO4 src[i] = &WF_BAYERSRC((i<2)?row:row_p1, i&1, FC((i<2)?row:row_p1, i&1));
+
+		if (row_p1==S.height)
+			src[2]=src[3]=dummy_line;
+
+		src_first   = &WF_BAYERSRC(row,   0,               FC(row,   0));
+		src_plast   = &WF_BAYERSRC(row,   width_d2*2-2,    FC(row,   0));
+		src_last    = &WF_BAYERSRC(row,   width_p1_d2*2-2, FC(row,   0));
+
+		do
+		{
+			// Do
+
+			WF_i_1TO4 (*src[i])<<=data_shift;
+
+			// Next 4 pixel or exit
+
+			if     (src[0]<src_plast)
+			{
+				WF_i_1TO4 src[i]+=8;
+			}
+			else if(src[0]>src_first && src[0]<src_last)
+			{
+				WF_i_1TO4 src[i]=i&1?&dummy_pixel:src[i]+8;
+			}
+			else break;
+
+		}
+		while(1);
+	}
+
+	ushort *gauss_pyramid[WF_GAUSS_PIRAMID_SIZE];
+	ushort *difwg_pyramid[WF_GAUSS_PIRAMID_SIZE];
+
+	for(int i=0; i<WF_GAUSS_PIRAMID_SIZE; i++)
+	{
+		gauss_pyramid[i] = (ushort*)calloc(S.width*S.height, sizeof(ushort));
+		difwg_pyramid[i] = (ushort*)calloc(S.width*S.height, sizeof(ushort));
+	}
+
+	int radius3x3 [4]={3,  3,  3,  0}; // as gau r=24
+	int radius3x14[4]={14, 14, 14, 0}; // as gau r=420
+	int radius3x45[4]={45, 45, 45, 0}; // as gau r=4140
+
+	// Making 4-level gaussian pyramid
+
+	if (x_green_flag)
+	{
+		wf_bayer4_green_blur   (0,          imgdata.image,    WF_IMGMODE_BAYER4PLANE, gauss_pyramid[0], WF_IMGMODE_BAYER1PLANE);
+		wf_bayer4_igauss_filter(1,          gauss_pyramid[0], WF_IMGMODE_BAYER1PLANE, gauss_pyramid[0], WF_IMGMODE_BAYER1PLANE);
+	}
+	else
+	{
+		wf_bayer4_igauss_filter(1,          imgdata.image,    WF_IMGMODE_BAYER4PLANE, gauss_pyramid[0], WF_IMGMODE_BAYER1PLANE);
+	}
+
+	wf_bayer4_block_filter (radius3x3,  gauss_pyramid[0], WF_IMGMODE_BAYER1PLANE, gauss_pyramid[1], WF_IMGMODE_BAYER1PLANE); // as gau r=24
+	wf_bayer4_block_filter (radius3x14, gauss_pyramid[0], WF_IMGMODE_BAYER1PLANE, gauss_pyramid[2], WF_IMGMODE_BAYER1PLANE); // as gau r=420
+	wf_bayer4_block_filter (radius3x45, gauss_pyramid[0], WF_IMGMODE_BAYER1PLANE, gauss_pyramid[3], WF_IMGMODE_BAYER1PLANE); // as gau r=4140 
+
+	
+	// Energy multiplyers for laplasyan pyramid
+
+	float dfg_mult[WF_GAUSS_PIRAMID_SIZE]={1.560976, 8.196011, 180.413773, 3601.427246/3.0};
+
+/*	dif_mult[0]=1.0/wf_filter_energy(0, 0,   0,    1);
+	dif_mult[1]=1.0/wf_filter_energy(0, 1,   0,   24);
+	dif_mult[2]=1.0/wf_filter_energy(0, 24,  0,  420);
+	dif_mult[3]=1.0/wf_filter_energy(0, 420, 0, 4140);*/
+
+	float dfg_mulg[WF_GAUSS_PIRAMID_SIZE]={1.235223, 19.813868, 365.148407, 7208.362793/3.0};
+
+/*	dif_mulg[0]=1.0/wf_filter_energy(0, 0,    1,    1);
+	dif_mulg[1]=1.0/wf_filter_energy(1, 1,    1,   24);
+	dif_mulg[2]=1.0/wf_filter_energy(1, 24,   1,  420);
+	dif_mulg[3]=1.0/wf_filter_energy(1, 420,  1, 4140);*/
+
+	float    dfg_mlcc[WF_GAUSS_PIRAMID_SIZE][4];
+	long int dfg_dmax[WF_GAUSS_PIRAMID_SIZE][4];
+
+	int green_mode;
+
+	if      ( x_green_flag && (imgdata.idata.cdesc[FC(0, 0)] == imgdata.idata.cdesc[FC(1, 1)]) )
+		green_mode = WF_GREENMODE_GX_XG;
+	else if ( x_green_flag && (imgdata.idata.cdesc[FC(0, 1)] == imgdata.idata.cdesc[FC(1, 0)]) )
+		green_mode = WF_GREENMODE_XG_GX;
+	else
+		green_mode = WF_GREENMODE_IND;
+	
+	for(int l=0; l<WF_GAUSS_PIRAMID_SIZE; l++)
+	{
+		switch (green_mode)
+		{
+			case WF_GREENMODE_GX_XG:
+
+				dfg_mlcc[l][0]=dfg_mlcc[l][3]=dfg_mulg[l];
+				dfg_dmax[l][0]=dfg_dmax[l][3]=65535/dfg_mulg[l];
+
+				dfg_mlcc[l][1]=dfg_mlcc[l][2]=dfg_mult[l];
+				dfg_dmax[l][1]=dfg_dmax[l][2]=65535/dfg_mult[l];
+				
+				break;
+
+			case WF_GREENMODE_XG_GX:
+
+				dfg_mlcc[l][1]=dfg_mlcc[l][2]=dfg_mulg[l];
+				dfg_dmax[l][1]=dfg_dmax[l][2]=65535/dfg_mulg[l];
+
+				dfg_mlcc[l][0]=dfg_mlcc[l][3]=dfg_mult[l];
+				dfg_dmax[l][0]=dfg_dmax[l][3]=65535/dfg_mult[l];
+				
+				break;
+			
+			case WF_GREENMODE_IND:
+
+				dfg_mlcc[l][0]=dfg_mlcc[l][1]=dfg_mlcc[l][2]=dfg_mlcc[l][3]=dfg_mult[l];
+				dfg_dmax[l][0]=dfg_dmax[l][1]=dfg_dmax[l][2]=dfg_dmax[l][3]=65535/dfg_mult[l];
+				
+				break;
+		}
+	}
+
+	// laplasyan energy
+
+	for(int row_d2=0; row_d2<height_p1_d2; row_d2++)
+	{
+		int     row, row_p1;
+		ushort *src[4];
+
+		ushort *gau[WF_GAUSS_PIRAMID_SIZE][4];
+		ushort *dfg[WF_GAUSS_PIRAMID_SIZE][4];
+
+		row    = row_d2*2;
+		row_p1 = row+1;
+
+		WF_i_1TO4 src[i] = &WF_BAYERSRC((i<2)?row:row_p1, i&1, FC((i<2)?row:row_p1, i&1));
+
+		if (row_p1==S.height)
+			src[2]=src[3]=dummy_line;
+
+		for(int l=0; l<WF_GAUSS_PIRAMID_SIZE; l++)
+		{
+			WF_i_1TO4 gau[l][i] = &WF_BAYERGAU(l, (i<2)?row:row_p1, i&1);
+
+			WF_i_1TO4 dfg[l][i] = &WF_BAYERDFG(l, (i<2)?row:row_p1, i&1);
+
+			if ((row+1)==S.height)
+				dfg[l][2]=dfg[l][3]=gau[l][2]=gau[l][3]=dummy_line;
+		}
+
+		ushort *src_first, *src_last, *src_last2;
+
+		src_first   = &WF_BAYERSRC(row,   0,               FC(row,   0));
+		src_last    = &WF_BAYERSRC(row,   width_d2*2-2,    FC(row,   0));
+		src_last2   = &WF_BAYERSRC(row,   width_p1_d2*2-2, FC(row,   0));
+
+		do
+		{
+			long int val_gau[4];
+			long int val_dif[4];
+			long int val_src[4];
+
+			WF_i_1TO4 val_src[i]=*src[i];
+
+			for(int l=0; l<WF_GAUSS_PIRAMID_SIZE; l++)
+			{
+				WF_i_1TO4 val_gau[i]=*gau[l][i];
+				WF_i_1TO4 val_dif[i]=val_src[i]-val_gau[i];
+				WF_i_1TO4 val_src[i]=val_gau[i];
+				WF_i_1TO4 val_dif[i]*=val_dif[i];
+
+				WF_i_1TO4
+					if(val_dif[i]<dfg_dmax[l][i])
+					{
+						val_dif[i]*=dfg_mlcc[l][i];
+						*dfg[l][i] =val_dif[i];
+					}
+					else
+					{
+						*dfg[l][i]=65535;
+					}
+			}
+
+			// Next 4 pixel or exit
+
+			if     (src[0]<src_last)
+			{
+				WF_i_1TO4 src[i]+=8;
+
+				for (int l=0; l<WF_GAUSS_PIRAMID_SIZE; l++)
+					WF_i_1TO4 gau[l][i]+=2;
+
+				for (int l=0; l<WF_GAUSS_PIRAMID_SIZE; l++)
+					WF_i_1TO4 dfg[l][i]+=2;
+			}
+			else if(src[0]>src_first && src[0]<src_last2)
+			{
+				WF_i_1TO4 src[i]=i&1?&dummy_pixel:src[i]+8;
+
+				for (int l=0; l<WF_GAUSS_PIRAMID_SIZE; l++)
+					WF_i_1TO4 gau[l][i]=i&1?&dummy_pixel:gau[l][i]+2;
+
+				for (int l=0; l<WF_GAUSS_PIRAMID_SIZE; l++)
+					WF_i_1TO4 dfg[l][i]=i&1?&dummy_pixel:dfg[l][i]+2;
+			}
+			else break;
+		}
+		while(1);
+	}
+	
+	int radius2x32 [3]={32, 32, 0};
+	int radius2x56 [3]={56, 56, 0};
+	int radius2x90 [3]={90, 90, 0};
+	int radius2x104[3]={104, 104, 0};
+
+	if (x_green_flag)
+	{
+		for(int i=0;i<4;i++)
+			wf_bayer4_green_blur   (0,           difwg_pyramid[i], WF_IMGMODE_BAYER1PLANE, difwg_pyramid[i], WF_IMGMODE_BAYER1PLANE);
+	}
+
+	wf_bayer4_block_filter (radius2x32,  difwg_pyramid[0], WF_IMGMODE_BAYER1PLANE, difwg_pyramid[0], WF_IMGMODE_BAYER1PLANE);
+	wf_bayer4_block_filter (radius2x56,  difwg_pyramid[1], WF_IMGMODE_BAYER1PLANE, difwg_pyramid[1], WF_IMGMODE_BAYER1PLANE);
+	wf_bayer4_block_filter (radius2x90,  difwg_pyramid[2], WF_IMGMODE_BAYER1PLANE, difwg_pyramid[2], WF_IMGMODE_BAYER1PLANE);
+	wf_bayer4_block_filter (radius2x104, difwg_pyramid[3], WF_IMGMODE_BAYER1PLANE, difwg_pyramid[3], WF_IMGMODE_BAYER1PLANE);
+
+	float (*banding_col)[4];
+	float (*banding_row)[4];
+	float (*banding_col_count)[4];
+	float (*banding_row_count)[4];
+
+	banding_col       = (float(*)[4])calloc(height_p1_d2, sizeof(float)*4);
+	banding_col_count = (float(*)[4])calloc(height_p1_d2, sizeof(float)*4);
+
+	banding_row       = (float(*)[4])calloc(width_p1_d2, sizeof(float)*4);
+	banding_row_count = (float(*)[4])calloc(width_p1_d2, sizeof(float)*4);
+
+	for(int row_d2=0; row_d2<height_p1_d2; row_d2++)
+		WF_i_1TO4 banding_col[row_d2][i]=banding_col_count[row_d2][i]=0;
+
+	for(int col_d2=0; col_d2<width_p1_d2; col_d2++)
+		WF_i_1TO4 banding_row[col_d2][i]=banding_row_count[col_d2][i]=0;
+
+	long int val_accepted;
+	float    treshold[4];
+
+	WF_i_1TO4 treshold[i]=imgdata.params.wf_deband_treshold[FC(i>>1,i&1)];
+
+	val_accepted = val_max-3*MAX(MAX(treshold[0],treshold[1]),MAX(treshold[2],treshold[3]));
+
+	float (*tr_weight)[4];
+
+	tr_weight=(float(*)[4])calloc(WF_MAXTRESHOLD*4, sizeof(float));
+
+	WF_i_1TO4 treshold[i]*=data_mult;
+
+	for(int v=0; v<WF_MAXTRESHOLD; v++)
+	{
+		for(int i=0; i<4; i++)
+		{
+			if (v<treshold[i]*treshold[i])
+				tr_weight[v][i] = 1.0;
+			else if (v*5<6*treshold[i]*treshold[i])
+				tr_weight[v][i] = 6.0-5.0*float(v)/(treshold[i]*treshold[i]);
+			else
+				tr_weight[v][i] = 0.0;
+		}
+	}
+
+	for(int row_d2=0; row_d2<height_p1_d2; row_d2++)
+	{
+		int     row, row_p1;
+		ushort *src[4];
+
+		ushort *gau[WF_GAUSS_PIRAMID_SIZE][4];
+		ushort *dfg[WF_GAUSS_PIRAMID_SIZE][4];
+
+		row    = row_d2*2;
+		row_p1 = row+1;
+
+		WF_i_1TO4 src[i] = &WF_BAYERSRC((i<2)?row:row_p1, i&1, FC((i<2)?row:row_p1, i&1));
+
+		if (row_p1==S.height)
+			src[2]=src[3]=dummy_line;
+
+		for(int l=0; l<WF_GAUSS_PIRAMID_SIZE; l++)
+		{
+			WF_i_1TO4 gau[l][i] = &WF_BAYERGAU(l, (i<2)?row:row_p1, i&1);
+
+			WF_i_1TO4 dfg[l][i] = &WF_BAYERDFG(l, (i<2)?row:row_p1, i&1);
+
+			if (row_p1==S.height)
+				dfg[l][2]=dfg[l][3]=gau[l][2]=gau[l][3]=dummy_line;
+		}
+
+		ushort *src_first, *src_last, *src_last2;
+
+		src_first   = &WF_BAYERSRC(row,   0,               FC(row,   0));
+		src_last    = &WF_BAYERSRC(row,   width_d2*2-2,    FC(row,   0));
+		src_last2   = &WF_BAYERSRC(row,   width_p1_d2*2-2, FC(row,   0));
+
+		int col_d2 = 0;
+
+		do
+		{
+			float val_src[4];
+
+			float bsum[4]={0,0,0,0};
+			float wsum[4]={0,0,0,0};
+
+			WF_i_1TO4 val_src[i]=*src[i];
+
+			for(int l=0; l<WF_GAUSS_PIRAMID_SIZE; l++)
+			{
+				float val_dif[4];
+				float val_gau[4];
+				float wght[4];
+
+				WF_i_1TO4 val_gau[i] =  *gau[l][i];
+				WF_i_1TO4 val_dif[i] =  val_src[i]-val_gau[i];
+				WF_i_1TO4 val_src[i] =  val_gau[i];
+
+				WF_i_1TO4 wght[i]    =  tr_weight[*dfg[l][i]][i];
+				WF_i_1TO4 wsum[i]    += wght[i];
+				WF_i_1TO4 bsum[i]    += wght[i]*val_dif[i];
+			}
+
+			//WF_i_1TO4 *src[i]=bsum[i];
+
+			WF_i_1TO4 wsum[i]*=wsum[i];
+
+			WF_i_1TO4 banding_col      [row_d2][i] += bsum[i]*wsum[i];
+			WF_i_1TO4 banding_col_count[row_d2][i] += wsum[i];
+
+			WF_i_1TO4 banding_row      [col_d2][i] += bsum[i]*wsum[i];
+			WF_i_1TO4 banding_row_count[col_d2][i] += wsum[i];
+
+			// Next 4 pixel or exit
+
+			if     (src[0]<src_last)
+			{
+				WF_i_1TO4 src[i]+=8;
+
+				for (int l=0; l<WF_GAUSS_PIRAMID_SIZE; l++)
+					WF_i_1TO4 gau[l][i]+=2;
+
+				for (int l=0; l<WF_GAUSS_PIRAMID_SIZE; l++)
+					WF_i_1TO4 dfg[l][i]+=2;
+			}
+			else if(src[0]>src_first && src[0]<src_last2)
+			{
+				WF_i_1TO4 src[i]=i&1?&dummy_pixel:src[i]+8;
+
+				for (int l=0; l<WF_GAUSS_PIRAMID_SIZE; l++)
+					WF_i_1TO4 gau[l][i]=i&1?&dummy_pixel:gau[l][i]+2;
+
+				for (int l=0; l<WF_GAUSS_PIRAMID_SIZE; l++)
+					WF_i_1TO4 dfg[l][i]=i&1?&dummy_pixel:dfg[l][i]+2;
+			}
+			else break;
+
+			col_d2++;
+		}
+		while(1);
+	}
+
+	float bsum[4], bmean[4];
+
+	int (*banding_col_i)[4];
+	int (*banding_row_i)[4];
+
+	banding_col_i = (int(*)[4])calloc(height_p1_d2, sizeof(int)*4);
+	banding_row_i = (int(*)[4])calloc(width_p1_d2,  sizeof(int)*4);
+	
+	// cols
+
+	WF_i_1TO4 bsum[i]=bmean[i]=0;
+
+	for(int row_d2=0; row_d2<height_p1_d2; row_d2++)
+		for(int i=0; i<4; i++)
+		{
+			if (banding_col_count[row_d2][i]>0)
+			{
+				banding_col[row_d2][i]=banding_col[row_d2][i]/banding_col_count[row_d2][i];
+				bsum[i]+=banding_col[row_d2][i];
+			}
+		}
+
+	WF_i_1TO4 bmean[i]=bsum[i]/(i<2?height_d2:height_p1_d2);
+		
+	for(int row_d2=0; row_d2<height_p1_d2; row_d2++)
+		for(int i=0; i<4; i++)
+			banding_col_i[row_d2][i]=int(banding_col[row_d2][i]-bmean[i]);
+
+	// rows
+
+	WF_i_1TO4 bsum[i]=bmean[i]=0;
+
+	for(int col_d2=0; col_d2<width_p1_d2; col_d2++)
+		for(int i=0; i<4; i++)
+		{
+			if (banding_row_count[col_d2][i]>0)
+			{
+				banding_row[col_d2][i]=(banding_row[col_d2][i]/banding_row_count[col_d2][i]);
+				bsum[i]+=banding_row[col_d2][i];
+			}
+		}
+
+	WF_i_1TO4 bmean[i]=bsum[i]/(i<2?width_d2:width_p1_d2);
+
+	for(int col_d2=0; col_d2<width_p1_d2; col_d2++)
+		for(int i=0; i<4; i++)
+			if (banding_row_count[col_d2][i]>0)
+				banding_row_i[col_d2][i]=int(banding_row[col_d2][i]-bmean[i]);
+
+	for(int row_d2=0; row_d2<height_p1_d2; row_d2++)
+	{
+		int     row, row_p1;
+		ushort *src[4];
+		ushort *src_first, *src_plast, *src_last;
+		
+		row    = row_d2*2;
+		row_p1 = row+1;
+
+		WF_i_1TO4 src[i] = &WF_BAYERSRC((i<2)?row:row_p1, i&1, FC((i<2)?row:row_p1, i&1));
+
+		if (row_p1==S.height)
+			src[2]=src[3]=dummy_line;
+
+		src_first   = &WF_BAYERSRC(row,   0,               FC(row,   0));
+		src_plast   = &WF_BAYERSRC(row,   width_d2*2-2,    FC(row,   0));
+		src_last    = &WF_BAYERSRC(row,   width_p1_d2*2-2, FC(row,   0));
+
+		int col_d2=0;
+
+		do
+		{
+			// Do
+
+			int val_new[4];
+
+			WF_i_1TO4 val_new[i]=*src[i];
+			WF_i_1TO4 val_new[i]-=banding_col_i[row_d2][i];
+			WF_i_1TO4 val_new[i]-=banding_row_i[col_d2][i];
+
+			for(int i=0; i<4; i++)
+			{
+				if (*src[i]>=val_accepted)
+				{
+					val_new[i]=*src[i]>>data_shift;
+				}
+				else
+				{
+					if      (val_new[i]>val_max)
+						val_new[i]=val_max;
+					else if (val_new[i]<0)
+						val_new[i]=0;
+
+					val_new[i]>>=data_shift;
+				}
+			}
+
+			WF_i_1TO4 *src[i]=val_new[i];
+
+			// Next 4 pixel or exit
+
+			if     (src[0]<src_plast)
+			{
+				WF_i_1TO4 src[i]+=8;
+			}
+			else if(src[0]>src_first && src[0]<src_last)
+			{
+				WF_i_1TO4 src[i]=i&1?&dummy_pixel:src[i]+8;
+			}
+			else break;
+
+			col_d2++;
+		}
+		while(1);
+	}
+
+	free(banding_col_i);
+	free(banding_row_i);
+
+	free(tr_weight);
+	
+	free(banding_col);
+	free(banding_col_count);
+
+	free(banding_row);
+	free(banding_row_count);
+
+	for(int i=0; i<WF_GAUSS_PIRAMID_SIZE; i++)
+	{
+		free(gauss_pyramid[i]);
+		free(difwg_pyramid[i]);
+	}
+
+	free(dummy_line);
+        return WF_DEBANDING_OK;
+}
+
+double LibRaw::wf_filter_energy(int r1_greenmode, int r1, int r2_greenmode, int r2)
+{
+	/* 
+		This function caclulates energy of laplasyan piramid level.
+		Laplasyan level is difference between two 2D gaussian (exactly, binominal) convolutions with radius r1 and r2
+		Convolution is done on bayer data, 4 channels, and if (greenmode), additive on green channel.
+	
+		Not optimized, because now it's used only for precalculations.
+	*/
+
+
+#define WF_MAXFILTERSIZE 10000
+
+	int rmin, rmax;
+	int rmin_greenmode, rmax_greenmode;
+
+	if (r1>r2)
+	{
+		rmax=r1;
+		rmin=r2;
+		rmax_greenmode=r1_greenmode;
+		rmin_greenmode=r2_greenmode;
+	}
+	else
+	{
+		rmax=r2;
+		rmin=r1;
+		rmax_greenmode=r2_greenmode;
+		rmin_greenmode=r1_greenmode;
+	}
+
+
+	int rmin_x2_p1, rmax_x2_p1;
+	rmin_x2_p1=rmin*2+1;
+	rmax_x2_p1=rmax*2+1;
+
+	double gau_kernel_rmin[WF_MAXFILTERSIZE];
+	double gau_kernel_rmax[WF_MAXFILTERSIZE];
+
+	for(int i=0; i<rmax_x2_p1; i++)
+		gau_kernel_rmin[i]=0;
+
+	gau_kernel_rmin[1]=1.0;
+				
+	for(int i=2; i<=rmin_x2_p1; i++)
+	{
+		for(int j=i; j>0; j--)
+			gau_kernel_rmin[j]=0.5*(gau_kernel_rmin[j]+gau_kernel_rmin[j-1]);
+	}
+
+	for(int i=0; i<=rmax_x2_p1; i++)
+		gau_kernel_rmax[i]=gau_kernel_rmin[i];
+
+	for(int i=rmin_x2_p1+1; i<=rmax_x2_p1; i++)
+	{
+		for(int j=i; j>0; j--)
+			gau_kernel_rmax[j]=0.5*(gau_kernel_rmax[j]+gau_kernel_rmax[j-1]);
+	}
+
+	double wmin_sum, wmax_sum, energy_sum;
+
+	wmin_sum=0;
+	wmax_sum=0;
+	energy_sum=0;
+
+	for(int row=-rmax*2-1; row<=rmax*2+1; row++)
+	{
+		for(int col=-rmax*2-1; col<=rmax*2+1; col++)
+		{
+			double wght_rmax=0;
+			double wght_rmin=0;
+
+#define WF_WMAX(row, col) (((abs(row)<=rmax*2)&&(abs(col)<=rmax*2))?gau_kernel_rmax[abs(row)/2+rmax+1]*gau_kernel_rmax[abs(col)/2+rmax+1]:0)
+#define WF_WMIN(row, col) (((abs(row)<=rmin*2)&&(abs(col)<=rmin*2))?gau_kernel_rmin[abs(row)/2+rmin+1]*gau_kernel_rmin[abs(col)/2+rmin+1]:0)
+
+			if ( ((row&1)==0) && ((col&1)==0))
+			{
+				wght_rmax = WF_WMAX(row, col);
+				wght_rmin = WF_WMIN(row, col);
+			}
+
+			if (rmax_greenmode)
+			{
+				if ( ((row&1)==0) && ((col&1)==0))
+					wght_rmax = 0.5*wght_rmax;
+				else if ( ((row&1)==1) && ((col&1)==1))
+				{
+					wght_rmax = 0.125*(WF_WMAX(row-1, col-1)+WF_WMAX(row-1, col+1)+WF_WMAX(row+1, col-1)+WF_WMAX(row+1, col+1));
+				}
+			}
+
+			if (rmin_greenmode)
+			{
+				if ( ((row&1)==0) && ((col&1)==0))
+					wght_rmin = 0.5*wght_rmin;
+				else if ( ((row&1)==1) && ((col&1)==1))
+				{
+					wght_rmin = 0.125*(WF_WMIN(row-1, col-1)+WF_WMIN(row-1, col+1)+WF_WMIN(row+1, col-1)+WF_WMIN(row+1, col+1));
+				}
+			}
+
+			wmin_sum+=wght_rmin;
+			wmax_sum+=wght_rmax;
+
+			energy_sum+=(wght_rmax-wght_rmin)*(wght_rmax-wght_rmin);
+		}
+		
+	}
+
+	return energy_sum;
+}
+
+void LibRaw::wf_bayer4_green_blur(int mode, void* src_image, int src_imgmode, void* dst_image, int dst_imgmode)
+{
+	/* 
+		This function filters green (or any "diagonal") channel of bayer4 data with "X" kernel,
+
+		1 1
+		 4
+		1 1
+	*/
+
+#define WF_BAYERSRC4(row, col, c) ((ushort(*)[4])src_image)[((row) >> IO.shrink)*S.iwidth + ((col) >> IO.shrink)][c] 
+#define WF_BAYERSRC1(row, col)    ((ushort*)src_image)     [((row) >> IO.shrink)*S.iwidth + ((col) >> IO.shrink)] 
+#define WF_BAYERDST4(row, col, c) ((ushort(*)[4])dst_image)[((row) >> IO.shrink)*S.iwidth + ((col) >> IO.shrink)][c] 
+#define WF_BAYERDST1(row, col)    ((ushort*)dst_image)     [((row) >> IO.shrink)*S.iwidth + ((col) >> IO.shrink)]
+
+	int green_mode;
+
+	if ( imgdata.idata.cdesc[FC(0, 0)] == imgdata.idata.cdesc[FC(1, 1)] )
+		green_mode = WF_GREENMODE_GX_XG;
+	else if ( imgdata.idata.cdesc[FC(0, 1)] == imgdata.idata.cdesc[FC(1, 0)] )
+		green_mode = WF_GREENMODE_XG_GX;
+	else
+		green_mode = WF_GREENMODE_IND;
+
+	int src_h_shift, dst_h_shift, src_h_shift_x2;
+
+	if      (src_imgmode == WF_IMGMODE_BAYER1PLANE)
+		src_h_shift = 2 >> IO.shrink;
+	else if (src_imgmode == WF_IMGMODE_BAYER4PLANE)
+		src_h_shift = 8 >> IO.shrink;
+
+	src_h_shift_x2 = src_h_shift*2;
+
+	if      (dst_imgmode == WF_IMGMODE_BAYER1PLANE)
+		dst_h_shift = 2 >> IO.shrink;
+	else if (dst_imgmode == WF_IMGMODE_BAYER4PLANE)
+		dst_h_shift = 8 >> IO.shrink;
+
+	int row, col;
+
+	long int *line_filtered;
+
+	line_filtered = (long int*) calloc(S.width, sizeof(*line_filtered));
+	
+	ushort *src, *src_c, *src_u1, *src_u2, *src_d1, *src_d2, *dst_c, *src_ca, *dst_ca, *dst_rb; 
+	int start_col, start_col_left, row_up, row_dn;
+
+	if ( green_mode != WF_GREENMODE_IND)
+	{
+		for(row=0; row<S.height; row++)
+		{
+
+			if (row == 0)
+				row_up = 1;
+			else
+				row_up = row-1;
+
+			if (row == S.height-1)
+				row_dn = S.height-2;
+			else
+				row_dn = row+1;
+
+			if ( green_mode == WF_GREENMODE_GX_XG )
+				start_col = row & 1;
+			else
+				start_col = ( row+1 ) & 1;
+
+			if ( start_col == 0 )
+				start_col_left = 1;
+			else
+				start_col_left = 0;
+
+			switch (src_imgmode)
+			{
+				case WF_IMGMODE_BAYER1PLANE:
+
+					src_c  = &WF_BAYERSRC1(row,    start_col);
+					src_u1 = &WF_BAYERSRC1(row_up, start_col_left);
+					src_d1 = &WF_BAYERSRC1(row_dn, start_col_left);
+					src_u2 = &WF_BAYERSRC1(row_up, start_col+1);
+					src_d2 = &WF_BAYERSRC1(row_dn, start_col+1);
+
+					break;
+
+				case WF_IMGMODE_BAYER4PLANE:
+
+					src_c  = &WF_BAYERSRC4(row,    start_col,      FC(row,   start_col));
+					src_u1 = &WF_BAYERSRC4(row_up, start_col_left, FC(row_up, start_col_left));
+					src_d1 = &WF_BAYERSRC4(row_dn, start_col_left, FC(row_dn, start_col_left));
+					src_u2 = &WF_BAYERSRC4(row_up, start_col+1,    FC(row_up, start_col+1));
+					src_d2 = &WF_BAYERSRC4(row_dn, start_col+1,    FC(row_dn, start_col+1));
+
+					break;
+			}
+
+			long int sum_l1, sum_l2;
+
+			sum_l1 = *src_u1 + *src_d1;
+			sum_l2 = *src_u2 + *src_d2;			
+			
+			if (start_col == 0)
+			{
+				// Edges
+
+				line_filtered[start_col] = sum_l1 + sum_l2 + (*src_c)*4;
+
+				src_u2 += src_h_shift;
+				src_d2 += src_h_shift;				
+
+				sum_l2 = *src_u2 + *src_d2;
+
+				src_c += src_h_shift;
+				start_col=2;
+			}
+
+			int width_m_3 = S.width-3;
+
+			// Main
+
+			for (col=start_col; col<width_m_3; col+=2)
+			{
+				line_filtered[col] = sum_l1 + sum_l2 + 4*(*src_c);
+
+				src_u1 += src_h_shift_x2;
+				src_d1 += src_h_shift_x2;
+
+				sum_l1 = *src_u1 + *src_d1;
+
+				src_c += src_h_shift;
+				col+=2;
+
+				line_filtered[col] = sum_l1 + sum_l2 + 4*(*src_c);
+
+				src_u2 += src_h_shift_x2;
+				src_d2 += src_h_shift_x2;
+
+				sum_l2 = *src_u2 + *src_d2; 
+
+				src_c += src_h_shift;
+			}
+			
+			// Right edge
+
+			if      (col == S.width-1)
+			{
+				line_filtered[col] = 2*sum_l1 + 4*(*src_c);
+			}
+			else if (col == S.width-2)
+			{
+				line_filtered[col] = sum_l1 + sum_l2 + 4*(*src_c);
+			}
+			else if (col == S.width-3)
+			{
+				line_filtered[col] = sum_l1 + sum_l2 + 4*(*src_c);
+				
+				src_c += src_h_shift;
+				col+=2;
+
+				line_filtered[col] = 2*sum_l2 + 4*(*src_c);
+			}
+
+			if (row>0)
+			{
+
+				if ( green_mode == WF_GREENMODE_GX_XG )
+					start_col = ( row+1 ) & 1;
+				else
+					start_col = row & 1;
+				
+
+				switch (dst_imgmode)
+				{
+					case WF_IMGMODE_BAYER1PLANE:
+						dst_c  = &WF_BAYERDST1(row-1,    start_col);
+						break;
+
+					case WF_IMGMODE_BAYER4PLANE:
+						dst_c  = &WF_BAYERDST4(row-1,    start_col, FC(row-1, start_col));
+						break;
+				}
+
+				for (col=start_col;  col<S.width; col+=2)
+				{
+					*dst_c=(line_filtered[col])>>3;
+					dst_c+=dst_h_shift;
+				}
+
+				if (src_image != dst_image)
+				{
+					// copy red or blue channel
+
+					if ( green_mode == WF_GREENMODE_GX_XG )
+						start_col = row & 1;
+					else
+						start_col = (row+1) & 1;
+					
+					switch (src_imgmode)
+					{
+						case WF_IMGMODE_BAYER1PLANE:
+							src     = &WF_BAYERSRC1(row-1, start_col);
+							break;
+
+						case WF_IMGMODE_BAYER4PLANE:
+							src     = &WF_BAYERSRC4(row-1, start_col, FC(row-1, start_col));
+							break;
+					}
+
+					switch (dst_imgmode)
+					{
+						case WF_IMGMODE_BAYER1PLANE:
+							dst_rb  = &WF_BAYERDST1(row-1, start_col);
+							break;
+
+						case WF_IMGMODE_BAYER4PLANE:
+							dst_rb  = &WF_BAYERDST4(row-1, start_col, FC(row-1, start_col));
+							break;
+					}
+
+					for (col=start_col;  col<S.width; col+=2)
+					{
+						*dst_rb=*src;
+						src   +=src_h_shift;
+						dst_rb+=dst_h_shift;
+					}
+				}
+			}
+		}
+
+		if ( green_mode == WF_GREENMODE_GX_XG )
+			start_col = ( row+1 ) & 1;
+		else
+			start_col = row & 1;
+				
+
+		switch (dst_imgmode)
+		{
+			case WF_IMGMODE_BAYER1PLANE:
+				dst_c  = &WF_BAYERDST1(row-1,    start_col);
+				break;
+
+			case WF_IMGMODE_BAYER4PLANE:
+				dst_c  = &WF_BAYERDST4(row-1,    start_col, FC(row-1, start_col));
+				break;
+		}
+
+		for (col=start_col;  col<S.width; col+=2)
+		{
+			*dst_c=(line_filtered[col])>>3;
+			dst_c+=dst_h_shift;
+		}
+
+		if (src_image != dst_image)
+		{
+			// copy red or blue channel
+			
+			if ( green_mode == WF_GREENMODE_GX_XG )
+				start_col = row & 1;
+			else
+				start_col = (row+1) & 1;
+				
+			switch (src_imgmode)
+			{
+				case WF_IMGMODE_BAYER1PLANE:
+					src     = &WF_BAYERSRC1(row-1, start_col);
+					break;
+
+				case WF_IMGMODE_BAYER4PLANE:
+					src     = &WF_BAYERSRC4(row-1, start_col, FC(row-1, start_col));
+					break;
+			}
+
+			switch (dst_imgmode)
+			{
+				case WF_IMGMODE_BAYER1PLANE:
+					dst_rb  = &WF_BAYERDST1(row-1, start_col);
+					break;
+				
+				case WF_IMGMODE_BAYER4PLANE:
+					dst_rb  = &WF_BAYERDST4(row-1, start_col, FC(row-1, start_col));
+					break;
+			}
+			
+			for (col=start_col;  col<S.width; col+=2)
+			{
+				*dst_rb=*src;
+				src   +=src_h_shift;
+				dst_rb+=dst_h_shift;
+			}
+		}
+	}
+
+	free(line_filtered);
+}
+
+void LibRaw::wf_bayer4_igauss_filter(int radius, void* src_image, int src_imgmode, void* dst_image, int dst_imgmode)
+{
+	/* 
+	   This function filter source bayer4 data with gauss (binominal), 4 channels independently.
+	*/
+	   
+#define WF_BAYERSRC4(row, col, c) ((ushort(*)[4])src_image)[((row) >> IO.shrink)*S.iwidth + ((col) >> IO.shrink)][c] 
+#define WF_BAYERSRC1(row, col)    ((ushort*)src_image)     [((row) >> IO.shrink)*S.iwidth + ((col) >> IO.shrink)] 
+#define WF_BAYERDST4(row, col, c) ((ushort(*)[4])dst_image)[((row) >> IO.shrink)*S.iwidth + ((col) >> IO.shrink)][c] 
+#define WF_BAYERDST1(row, col)    ((ushort*)dst_image)     [((row) >> IO.shrink)*S.iwidth + ((col) >> IO.shrink)]
+
+	if (radius <= 0 || radius > 8)
+	   return;
+
+	long int (*line_filtered)[4];
+
+	long int gauss_conv_kernel[9][4];
+
+	long int gauss_conv_kernel_c[8][9] = 
+	{
+		{32768, 16384},
+		{24576, 16384, 4096},
+		{20480,	15360, 6144, 1024},
+		{17920, 14336, 7168, 2048, 256},
+		{16128, 13440, 7680, 2880, 640,  64},
+		{14784, 12672, 7920, 3520, 1056, 192, 16},
+		{13728, 12012, 8008, 4004, 1456, 364, 56,  4},
+		{12870, 11440, 8008, 4368, 1820, 560, 120, 16, 1},
+	};
+
+	int line_memory_len = (MAX(S.height, S.width)+1)/2+radius*2+1;
+    line_filtered       = (long int(*)[4]) calloc(line_memory_len, sizeof(long int[4]));
+
+	int src_h_shift, src_v_shift;
+	int dst_h_shift, dst_v_shift;
+
+	if      (src_imgmode == WF_IMGMODE_BAYER1PLANE)
+		src_h_shift = 2 >> IO.shrink;
+	else if (src_imgmode == WF_IMGMODE_BAYER4PLANE)
+		src_h_shift = 8 >> IO.shrink;
+
+	src_v_shift = S.width*src_h_shift;
+
+	if      (dst_imgmode == WF_IMGMODE_BAYER1PLANE)
+		dst_h_shift = 2 >> IO.shrink;
+	else if (dst_imgmode == WF_IMGMODE_BAYER4PLANE)
+		dst_h_shift = 8 >> IO.shrink;
+
+	dst_v_shift = S.width*dst_h_shift;
+
+	int width_d2  = S.width  / 2;
+	int height_d2 = S.height / 2;
+
+	int i, j;
+
+	for (j=0; j<=radius; j++)
+	{
+		for (i=0; i<4; i++)
+		{
+			gauss_conv_kernel[j][i] = gauss_conv_kernel_c[radius-1][j];
+		}
+	}
+
+	int row,  col;
+	int rowf, colf;
+
+	ushort   *src  [4], *dst[4];
+	long int  src_c[4];
+
+	// Horizontal 
+
+	int right_edge[4];
+
+	for (i=0; i<4; i++)
+	{
+		int padding = i<2 && (S.width & 1) ? 1 : 0;
+		right_edge[i]=width_d2 + radius + padding;
+	}
+	
+	for(row=0; row<S.height; row+=2)
+	{
+		int row_p1=MIN(row+1, S.height-1);
+
+		switch (src_imgmode)
+		{
+			case WF_IMGMODE_BAYER1PLANE:
+
+				src[0] = &WF_BAYERSRC1(row,    0);
+				src[1] = &WF_BAYERSRC1(row_p1, 0);
+				src[2] = &WF_BAYERSRC1(row,    1);
+				src[3] = &WF_BAYERSRC1(row_p1, 1);
+				break;
+
+			case WF_IMGMODE_BAYER4PLANE:
+
+				src[0] = &WF_BAYERSRC4(row,    0, FC(0,      0));
+				src[1] = &WF_BAYERSRC4(row_p1, 0, FC(row_p1, 0));
+				src[2] = &WF_BAYERSRC4(row,    1, FC(0,      1));
+				src[3] = &WF_BAYERSRC4(row_p1, 1, FC(row_p1, 1));
+				break;
+		}
+
+		colf = radius;
+
+		for (int j=0; j<line_memory_len; j++)
+		{
+			for(i=0;i<4;i++)
+				line_filtered[j][i]=0;
+		}
+		
+		for(col=0; col<S.width-1; col+=2)
+		{
+
+			int col1, col2;
+
+			col1=col2=colf;
+
+			for (i=0; i<4; i++)
+				src_c[i]=*src[i];
+
+			for (i=0; i<4; i++)
+				line_filtered[colf][i]+=gauss_conv_kernel[0][i]*(src_c[i]);
+
+			for(int j=1; j<=radius; j++)
+			{
+				col1++;
+				col2--;
+			
+				for (i=0; i<4; i++)
+				{
+					long int g;
+
+					g = gauss_conv_kernel[j][i]*src_c[i];
+
+					line_filtered[col1][i]+=g;
+					line_filtered[col2][i]+=g;
+				}
+			}
+
+			colf++;
+
+			for (i=0; i<4; i++)
+				src[i]+=src_h_shift;
+		}
+
+		// width is odd number
+
+		if (col == S.width-1)
+		{
+			int col1, col2;
+
+			col1=col2=colf;
+
+			for (i=0; i<2; i++)
+				src_c[i]=*src[i];
+
+			for (i=0; i<2; i++)
+				line_filtered[colf][i]+=gauss_conv_kernel[0][i]*(src_c[i]);
+
+			for(int j=1; j<=radius; j++)
+			{
+				col1++;
+				col2--;
+			
+				for (i=0; i<2; i++)
+				{
+					long int g;
+
+					g = gauss_conv_kernel[j][i]*src_c[i];
+
+					line_filtered[col1][i]+=g;
+					line_filtered[col2][i]+=g;
+				}
+			}
+
+			colf++;
+
+			for (i=0; i<2; i++)
+				src[i]+=src_h_shift;
+		}
+
+		// Edges mirroring
+
+		for(j=0; j<radius; j++)
+		{
+			for (i=0; i<4; i++)
+			{
+				line_filtered[radius+j         ][i]+=line_filtered[radius-j-1     ][i];
+				line_filtered[right_edge[i]-1-j][i]+=line_filtered[right_edge[i]+j][i];
+			}
+		}
+		
+		switch (dst_imgmode)
+		{
+			case WF_IMGMODE_BAYER1PLANE:
+			
+				dst[0] = &WF_BAYERDST1(row,    0);
+				dst[1] = &WF_BAYERDST1(row_p1, 0);
+				dst[2] = &WF_BAYERDST1(row,    1);
+				dst[3] = &WF_BAYERDST1(row_p1, 1);
+				break;
+
+			case WF_IMGMODE_BAYER4PLANE:
+		
+				dst[0] = &WF_BAYERDST4(row,    0, FC(0,      0));
+				dst[1] = &WF_BAYERDST4(row_p1, 0, FC(row_p1, 0));
+				dst[2] = &WF_BAYERDST4(row,    1, FC(0,      1));
+				dst[3] = &WF_BAYERDST4(row_p1, 1, FC(row_p1, 1));
+				break;
+		}
+
+		colf = radius;
+
+		for(col=0; col<S.width-1; col+=2)
+		{
+			for(i=0; i<4; i++)
+			{
+				*dst[i]=line_filtered[colf][i]>>16;
+				dst[i]+=dst_h_shift;
+			}
+
+			colf++;
+		}
+
+		if (col == S.width-1)
+		{
+			for(i=0; i<2; i++)
+				*dst[i]=line_filtered[colf][i]>>16;
+		}
+	}
+
+
+   	// Vertical
+
+	int lower_edge[4];
+
+	for (i=0; i<4; i++)
+	{
+		int padding = i<2 && (S.height & 1 ) ? 1 : 0;
+		lower_edge[i]=height_d2 + radius + padding;
+	}
+
+
+	for(col=0; col<S.width; col+=2)
+	{
+		int col_p1=MIN(col+1, S.width-1);	
+
+		switch (dst_imgmode)
+		{
+			case WF_IMGMODE_BAYER1PLANE:
+
+				src[0] = &WF_BAYERDST1(0, col);
+				src[1] = &WF_BAYERDST1(0, col_p1);
+				src[2] = &WF_BAYERDST1(1, col);
+				src[3] = &WF_BAYERDST1(1, col_p1);
+				break;
+
+			case WF_IMGMODE_BAYER4PLANE:
+
+				src[0] = &WF_BAYERDST4(0, col,    FC(0,      0));
+				src[1] = &WF_BAYERDST4(0, col_p1, FC(0, col_p1));
+				src[2] = &WF_BAYERDST4(1, col,    FC(1,      0));
+				src[3] = &WF_BAYERDST4(1, col_p1, FC(1, col_p1));
+				break;
+		}
+
+		rowf = radius;
+
+		for (int j=0; j<line_memory_len; j++)
+		{
+			for(i=0;i<4;i++)
+				line_filtered[j][i]=0;
+		}
+		
+		for(row=0; row<S.height-1; row+=2)
+		{
+
+			int row1, row2;
+
+			row1=row2=rowf;
+
+			for (i=0; i<4; i++)
+				src_c[i]=*src[i];
+
+			for (i=0; i<4; i++)
+				line_filtered[rowf][i]+=gauss_conv_kernel[0][i]*(src_c[i]);
+
+			for(int j=1; j<=radius; j++)
+			{
+				row1++;
+				row2--;
+			
+				long int g[4];
+
+				for (i=0; i<4; i++)
+				{
+
+					g[i] = gauss_conv_kernel[j][i]*src_c[i];
+
+					line_filtered[row1][i]+=g[i];
+					line_filtered[row2][i]+=g[i];
+				}
+			}
+
+			rowf++;
+
+			for (i=0; i<4; i++)
+				src[i]+=dst_v_shift;
+		}
+
+		// height is odd number
+
+		if (row == S.height-1)
+		{
+			int row1, row2;
+
+			row1=row2=rowf;
+
+			for (i=0; i<2; i++)
+				src_c[i]=*src[i];
+
+			for (i=0; i<2; i++)
+				line_filtered[rowf][i]+=gauss_conv_kernel[0][i]*(src_c[i]);
+
+			for(int j=1; j<=radius; j++)
+			{
+				row1++;
+				row2--;
+			
+				long int g[4];
+
+				for (i=0; i<2; i++)
+				{
+
+					g[i] = gauss_conv_kernel[j][i]*src_c[i];
+
+					line_filtered[row1][i]+=g[i];
+					line_filtered[row2][i]+=g[i];
+				}
+			}
+
+			rowf++;
+
+			for (i=0; i<2; i++)
+				src[i]+=dst_v_shift;
+		}
+
+		// Edge mirroring
+
+		for(int j=0; j<radius; j++)
+		{
+			for (int i=0; i<4; i++)
+			{
+				line_filtered[radius+j][i]         +=line_filtered[radius-j-1][i];
+				line_filtered[lower_edge[i]-1-j][i]+=line_filtered[lower_edge[i]+j][i];
+			}
+		}
+
+
+		switch (dst_imgmode)
+		{
+			case WF_IMGMODE_BAYER1PLANE:
+			
+				dst[0] = &WF_BAYERDST1(0, col);
+				dst[1] = &WF_BAYERDST1(0, col_p1);
+				dst[2] = &WF_BAYERDST1(1, col);
+				dst[3] = &WF_BAYERDST1(1, col_p1);
+				break;
+
+			case WF_IMGMODE_BAYER4PLANE:
+		
+				dst[0] = &WF_BAYERDST4(0, col,    FC(0, 0));
+				dst[1] = &WF_BAYERDST4(0, col_p1, FC(0, col_p1));
+				dst[2] = &WF_BAYERDST4(1, col,    FC(1, 0));
+				dst[3] = &WF_BAYERDST4(1, col_p1, FC(1, col_p1));
+				break;
+		}
+
+		rowf = radius;
+
+		for(row=0; row<S.height-1; row+=2)
+		{
+			for(i=0; i<4; i++)
+			{
+				*dst[i]=line_filtered[rowf][i]>>16;
+				dst[i]+=dst_v_shift;
+			}
+
+			rowf++;
+		}
+
+		if (row == S.height-1)
+		{
+			for(i=0; i<2; i++)
+				*dst[i]=line_filtered[rowf][i]>>16;
+		}
+   }
+
+   free(line_filtered);
+}
+
+void LibRaw::wf_bayer4_block_filter(int* radius_list, void* src_image, int src_imgmode, void* dst_image, int dst_imgmode)
+{
+#define WF_BLOCKFILTER_MAXF 8
+
+#define WF_BAYERSRC4(row,col,c) ((ushort(*)[4])src_image)[((row) >> IO.shrink)*S.iwidth + ((col) >> IO.shrink)][c] 
+#define WF_BAYERSRC1(row,col)   ((ushort*)src_image)     [((row) >> IO.shrink)*S.iwidth + ((col) >> IO.shrink)] 
+#define WF_BAYERDST4(row,col,c) ((ushort(*)[4])dst_image)[((row) >> IO.shrink)*S.iwidth + ((col) >> IO.shrink)][c] 
+#define WF_BAYERDST1(row,col)   ((ushort*)dst_image)     [((row) >> IO.shrink)*S.iwidth + ((col) >> IO.shrink)] 
+
+	int filter_itrtns_num = 0;
+	
+	int block_radius      [WF_BLOCKFILTER_MAXF]; 
+	int block_radius_x2   [WF_BLOCKFILTER_MAXF];
+	int block_radius_x2_p1[WF_BLOCKFILTER_MAXF];
+
+	int block_radius_max = 0;
+	int block_radius_max_x2;
+	int block_radius_max_x2_p1;
+
+	for(int i=0; (i<WF_BLOCKFILTER_MAXF) && (radius_list[i]!=0); i++)
+	{
+		block_radius      [i]=radius_list[i];
+		block_radius_x2   [i]=block_radius[i]*2;
+		block_radius_x2_p1[i]=block_radius_x2[i]+1;
+
+		if(block_radius_max<block_radius[i])
+			block_radius_max=block_radius[i];
+
+		filter_itrtns_num++;
+	}
+
+	long int divider[WF_BLOCKFILTER_MAXF];
+	long int div_multiplication;
+
+	div_multiplication=block_radius_x2_p1[0];
+
+	for(int i=1; i<filter_itrtns_num; i++)
+	{
+		if (div_multiplication*((long int)block_radius_x2_p1[i])<65535)
+		{
+			div_multiplication*=block_radius_x2_p1[i];
+			divider[i-1]=1;
+		}
+		else
+		{
+			divider[i-1]=block_radius_x2_p1[i];
+		}
+	}
+
+	divider[filter_itrtns_num-1]=div_multiplication;
+
+	block_radius_max_x2    = block_radius_max*2;
+	block_radius_max_x2_p1 = block_radius_max_x2+1;
+	
+	int line_memory_len;
+
+	long int (*source_line)[4];
+	long int (*line_block_filtered)[4];
+ 
+	line_memory_len = (MAX(S.height, S.width)+1)/2+block_radius_max_x2_p1*2;
+
+	line_block_filtered=(long int(*)[4]) calloc(line_memory_len, sizeof(long int[4]));
+	source_line        =(long int(*)[4]) calloc(line_memory_len, sizeof(long int[4]));
+	
+
+   	int   src_h_shift, dst_h_shift, src_v_shift, dst_v_shift;
+ 
+	if      (src_imgmode == WF_IMGMODE_BAYER1PLANE)
+		src_h_shift = 2 >> IO.shrink;
+	else if (src_imgmode == WF_IMGMODE_BAYER4PLANE)
+		src_h_shift = 8 >> IO.shrink;
+
+	src_v_shift = S.width*src_h_shift;
+
+	if      (dst_imgmode == WF_IMGMODE_BAYER1PLANE)
+		dst_h_shift = 2 >> IO.shrink;
+	else if (dst_imgmode == WF_IMGMODE_BAYER4PLANE)
+		dst_h_shift = 8 >> IO.shrink;
+
+	dst_v_shift = S.width*dst_h_shift;
+
+	int width_d2     = S.width  / 2;
+	int height_d2    = S.height / 2;
+
+	int width_p1_d2  = (S.width+1)  / 2;
+	int height_p1_d2 = (S.height+1) / 2;
+
+	ushort   *src[4], *dst[4];
+
+	long int  (*src_plus)[4], (*src_minus)[4];
+	long int  block_sum[4];
+	
+	int row, col;
+
+	int right_edge[4], lower_edge[4];
+
+	for(row=0; row<S.height; row+=2)
+	{
+		int row_p1=MIN(row+1, S.height-1);
+
+		switch (src_imgmode)
+		{
+			case WF_IMGMODE_BAYER1PLANE:
+
+				src[0] = &WF_BAYERSRC1(row,    0);
+				src[1] = &WF_BAYERSRC1(row_p1, 0);
+				src[2] = &WF_BAYERSRC1(row,    1);
+				src[3] = &WF_BAYERSRC1(row_p1, 1);
+				break;
+
+			case WF_IMGMODE_BAYER4PLANE:
+
+				src[0] = &WF_BAYERSRC4(row,    0, FC(0,      0));
+				src[1] = &WF_BAYERSRC4(row_p1, 0, FC(row_p1, 0));
+				src[2] = &WF_BAYERSRC4(row,    1, FC(0,      1));
+				src[3] = &WF_BAYERSRC4(row_p1, 1, FC(row_p1, 1));
+				break;
+		}
+
+		for(col=0; col<width_d2; col++)
+		{
+			for (int i=0; i<4; i++)
+			{
+				source_line[col][i]=*src[i];
+				src[i] += src_h_shift;
+			}
+		}
+
+		if (S.width & 1 == 1)
+		{
+			for (int i=0; i<2; i++)
+			{		   
+				source_line[width_d2][i]=*src[i];
+			}
+
+			for (int i=2; i<4; i++)
+			{		   
+				source_line[width_d2][i]=0;
+			}
+		}
+
+		for(int f=0; f<filter_itrtns_num; f++)
+		{
+			src_minus=src_plus=source_line;
+
+			for (int i=0; i<4; i++)
+				block_sum[i]=0;
+
+			for(col=0; col<block_radius_x2_p1[f]; col++)
+			{
+				for (int i=0; i<4; i++)
+				{
+					block_sum[i]+=(*src_plus)[i];
+					line_block_filtered[col][i]=block_sum[i];
+				}
+
+				src_plus++;
+			}
+
+			for(col=block_radius_x2_p1[f]; col<width_p1_d2; col++)
+			{
+				for (int i=0; i<4; i++)
+				{		   
+					block_sum[i]+=(*src_plus)[i];
+					block_sum[i]-=(*src_minus)[i];
+					line_block_filtered[col][i]=block_sum[i];
+				}
+
+				src_plus++;
+				src_minus++;
+			}
+
+			for(col=width_p1_d2; col<width_p1_d2+block_radius_x2_p1[f]; col++)
+			{
+				for (int i=0; i<4; i++)
+				{
+					block_sum[i]-=(*src_minus)[i];
+					line_block_filtered[col][i]=block_sum[i];
+				}
+
+				src_minus++;
+			}
+
+			// Edge mirroring
+
+			for (int i=0; i<4; i++)
+			{
+				int padding = i<2 && (S.width & 1 == 1) ? 1 : 0;
+				right_edge[i]=width_d2 + block_radius[f] + padding;
+			}
+
+			for(int j=0; j<block_radius[f]; j++)
+			{
+				for (int i=0; i<4; i++)
+				{
+					line_block_filtered[block_radius[f]+j][i]+=line_block_filtered[block_radius[f]-j-1][i];
+					line_block_filtered[right_edge[i]-1-j][i]+=line_block_filtered[right_edge[i]+j][i];
+				}
+			}
+
+			if (divider[f]==1)
+			{
+				for(col=0; col<width_d2; col++)
+				{
+					for (int i=0; i<4; i++)
+						source_line[col][i]=line_block_filtered[col+block_radius[f]][i];
+				}
+
+				if (S.width & 1 == 1)
+				{
+					for (int i=0; i<2; i++)
+						source_line[width_d2][i]=line_block_filtered[width_d2+block_radius[f]][i];
+
+					for (int i=2; i<4; i++)
+						source_line[width_d2][i]=0;
+				}
+			}
+			else
+			{
+				for(col=0; col<width_d2; col++)
+				{
+					for (int i=0; i<4; i++)
+						source_line[col][i]=line_block_filtered[col+block_radius[f]][i]/divider[f];
+				}
+
+				if (S.width & 1 == 1)
+				{
+					for (int i=0; i<2; i++)
+						source_line[width_d2][i]=line_block_filtered[width_d2+block_radius[f]][i]/divider[f];
+
+					for (int i=2; i<4; i++)
+						source_line[width_d2][i]=0;
+				}
+			}
+		}
+
+		switch (dst_imgmode)
+		{
+			case WF_IMGMODE_BAYER1PLANE:
+
+				dst[0] = &WF_BAYERDST1(row,    0);
+				dst[1] = &WF_BAYERDST1(row_p1, 0);
+				dst[2] = &WF_BAYERDST1(row,    1);
+				dst[3] = &WF_BAYERDST1(row_p1, 1);
+				break;
+
+			case WF_IMGMODE_BAYER4PLANE:
+
+				dst[0] = &WF_BAYERDST4(row,    0, FC(0,      0));
+				dst[1] = &WF_BAYERDST4(row_p1, 0, FC(row_p1, 0));
+				dst[2] = &WF_BAYERDST4(row,    1, FC(0,      1));
+				dst[3] = &WF_BAYERDST4(row_p1, 1, FC(row_p1, 1));
+				break;
+		}
+
+		for(col=0; col<width_d2; col++)
+		{
+			for (int i=0; i<4; i++)
+			{		   
+				*dst[i]=source_line[col][i];
+				dst[i]+=dst_h_shift;
+			}
+		}
+
+		if (S.width & 1 == 1)
+		{
+			for (int i=0; i<2; i++)
+				*dst[i]=source_line[col][i];
+		}
+	}
+
+	for(col=0; col<S.width; col+=2)
+	{
+		int col_p1=MIN(col+1, S.width-1);
+
+		switch (dst_imgmode)
+		{
+			case WF_IMGMODE_BAYER1PLANE:
+
+				src[0] = &WF_BAYERDST1(0, col);
+				src[1] = &WF_BAYERDST1(0, col_p1);
+				src[2] = &WF_BAYERDST1(1, col);
+				src[3] = &WF_BAYERDST1(1, col_p1);
+				break;
+
+			case WF_IMGMODE_BAYER4PLANE:
+
+				src[0] = &WF_BAYERDST4(0, col,    FC(0,      0));
+				src[1] = &WF_BAYERDST4(0, col_p1, FC(0, col_p1));
+				src[2] = &WF_BAYERDST4(1, col,    FC(1,      0));
+				src[3] = &WF_BAYERDST4(1, col_p1, FC(1, col_p1));
+				break;
+		}
+
+		for(row=0; row<height_d2; row++)
+		{
+			for (int i=0; i<4; i++)
+			{
+				source_line[row][i]=*src[i];
+				src[i] += dst_v_shift;
+			}
+		}
+		
+		if (S.height & 1 == 1)
+		{
+			for (int i=0; i<2; i++)
+			{		   
+				source_line[height_d2][i]=*src[i];
+			}
+
+			for (int i=2; i<4; i++)
+			{		   
+				source_line[height_d2][i]=0;
+			}
+		}
+
+		for(int f=0; f<filter_itrtns_num; f++)
+		{
+			src_minus=src_plus=source_line;
+
+			for (int i=0; i<4; i++)
+				block_sum[i]=0;
+
+			for(row=0; row<block_radius_x2_p1[f]; row++)
+			{
+				for (int i=0; i<4; i++)
+				{
+					block_sum[i]+=(*src_plus)[i];
+					line_block_filtered[row][i]=block_sum[i];
+				}
+
+				src_plus++;
+			}
+
+			for(row=block_radius_x2_p1[f]; row<height_p1_d2; row++)
+			{
+				for (int i=0; i<4; i++)
+				{		   
+					block_sum[i]+=(*src_plus)[i];
+					block_sum[i]-=(*src_minus)[i];
+					line_block_filtered[row][i]=block_sum[i];
+				}
+
+				src_plus++;
+				src_minus++;
+			}
+
+			for(row=height_p1_d2; row<height_p1_d2+block_radius_x2_p1[f]; row++)
+			{
+				for (int i=0; i<4; i++)
+				{
+					block_sum[i]-=(*src_minus)[i];
+					line_block_filtered[row][i]=block_sum[i];
+				}
+
+				src_minus++;
+			}
+
+			// Edge mirroring
+
+			for (int i=0; i<4; i++)
+			{
+				int padding = (i<2) && (S.height & 1 == 1) ? 1 : 0;
+				lower_edge[i]=height_d2 + block_radius[f] + padding;
+			}
+
+			for(int j=0; j<block_radius[f]; j++)
+			{
+				for (int i=0; i<4; i++)
+				{
+					line_block_filtered[block_radius[f]+j][i]+=line_block_filtered[block_radius[f]-j-1][i];
+					line_block_filtered[lower_edge[i]-1-j][i]+=line_block_filtered[lower_edge[i]+j][i];
+				}
+			}
+
+			if (divider[f]==1)
+			{
+				for(row=0; row<height_d2; row++)
+				{
+					for (int i=0; i<4; i++)
+						source_line[row][i]=line_block_filtered[row+block_radius[f]][i];
+				}
+
+				if (S.height & 1 == 1)
+				{
+					for (int i=0; i<2; i++)
+						source_line[height_d2][i]=line_block_filtered[height_d2+block_radius[f]][i];
+
+					for (int i=2; i<4; i++)
+						source_line[height_d2][i]=0;
+				}
+			}
+			else
+			{
+				for(row=0; row<height_d2; row++)
+				{
+					for (int i=0; i<4; i++)
+						source_line[row][i]=line_block_filtered[row+block_radius[f]][i]/divider[f];
+				}
+
+				if (S.height & 1 == 1)
+				{
+					for (int i=0; i<2; i++)
+						source_line[height_d2][i]=line_block_filtered[height_d2+block_radius[f]][i]/divider[f];
+
+					for (int i=2; i<4; i++)
+						source_line[height_d2][i]=0;
+				}
+			}
+		}
+
+		switch (dst_imgmode)
+		{
+			case WF_IMGMODE_BAYER1PLANE:
+
+				dst[0] = &WF_BAYERDST1(0, col);
+				dst[1] = &WF_BAYERDST1(0, col_p1);
+				dst[2] = &WF_BAYERDST1(1, col);
+				dst[3] = &WF_BAYERDST1(1, col_p1);
+				break;
+
+			case WF_IMGMODE_BAYER4PLANE:
+
+				dst[0] = &WF_BAYERDST4(0, col,    FC(0,      0));
+				dst[1] = &WF_BAYERDST4(0, col_p1, FC(0, col_p1));
+				dst[2] = &WF_BAYERDST4(1, col,    FC(1,      0));
+				dst[3] = &WF_BAYERDST4(1, col_p1, FC(1, col_p1));
+				break;
+		}
+
+		for(row=0; row<height_d2; row++)
+		{
+			for (int i=0; i<4; i++)
+			{		   
+				*dst[i]=source_line[row][i];
+				dst[i]+=dst_v_shift;
+			}
+		}
+
+		if (S.height & 1 == 1)
+		{
+			for (int i=0; i<2; i++)
+				*dst[i]=source_line[height_d2][i];
+		}
+	}
+
+	free(line_block_filtered);
+	free(source_line);
+}
+#undef P1
+#undef S
+#undef O
+#undef C
+#undef T
+#undef IO
+#undef ID
diff --git a/Source/LibRawLite/libraw/libraw.h b/Source/LibRawLite/libraw/libraw.h
index 8091c21..d518d72 100644
--- a/Source/LibRawLite/libraw/libraw.h
+++ b/Source/LibRawLite/libraw/libraw.h
@@ -1,6 +1,6 @@
 /* -*- C++ -*-
  * File: libraw.h
- * Copyright 2008-2010 LibRaw LLC (info at libraw.org)
+ * Copyright 2008-2013 LibRaw LLC (info at libraw.org)
  * Created: Sat Mar  8, 2008 
  *
  * LibRaw C++ interface
@@ -53,9 +53,14 @@ DllDef    const char          *libraw_strprogress(enum LibRaw_progress);
 DllDef    libraw_data_t       *libraw_init(unsigned int flags);
 DllDef    int                 libraw_open_file(libraw_data_t*, const char *);
 DllDef    int                 libraw_open_file_ex(libraw_data_t*, const char *, INT64 max_buff_sz);
+#if defined(_WIN32) && !defined(__MINGW32__) && defined(_MSC_VER) && (_MSC_VER > 1310)
+DllDef    int                 libraw_open_wfile(libraw_data_t*, const wchar_t *);
+DllDef    int                 libraw_open_wfile_ex(libraw_data_t*, const wchar_t *, INT64 max_buff_sz);
+#endif
 DllDef    int                 libraw_open_buffer(libraw_data_t*, void * buffer, size_t size);
 DllDef    int                 libraw_unpack(libraw_data_t*);
 DllDef    int                 libraw_unpack_thumb(libraw_data_t*);
+DllDef    void                libraw_recycle_datastream(libraw_data_t*);
 DllDef    void                libraw_recycle(libraw_data_t*);
 DllDef    void                libraw_close(libraw_data_t*);
 DllDef    void                libraw_subtract_black(libraw_data_t*);
@@ -68,15 +73,17 @@ DllDef    int                 libraw_versionNumber();
 DllDef    const char**        libraw_cameraList();
 DllDef    int                 libraw_cameraCount();
 
+  /* helpers */
 DllDef    void                libraw_set_memerror_handler(libraw_data_t*, memory_callback cb, void *datap);
+DllDef    void                libraw_set_exifparser_handler(libraw_data_t*, exif_parser_callback cb, void *datap);
 DllDef    void                libraw_set_dataerror_handler(libraw_data_t*,data_callback func,void *datap);
 DllDef    void                libraw_set_progress_handler(libraw_data_t*,progress_callback cb,void *datap);
 DllDef    const char *        libraw_unpack_function_name(libraw_data_t* lr);
 DllDef    int                 libraw_get_decoder_info(libraw_data_t* lr,libraw_decoder_info_t* d);
+DllDef    int libraw_COLOR(libraw_data_t*,int row, int col);
 
     /* DCRAW compatibility */
 DllDef    int                 libraw_adjust_sizes_info_only(libraw_data_t*);
-DllDef    int                 libraw_dcraw_document_mode_processing(libraw_data_t*);
 DllDef    int                 libraw_dcraw_ppm_tiff_writer(libraw_data_t* lr,const char *filename);
 DllDef    int                 libraw_dcraw_thumb_writer(libraw_data_t* lr,const char *fname);
 DllDef    int                 libraw_dcraw_process(libraw_data_t* lr);
@@ -97,21 +104,28 @@ class DllDef LibRaw
     int verbose;
 
     LibRaw(unsigned int flags = LIBRAW_OPTIONS_NONE);
-    
     libraw_output_params_t*     output_params_ptr() { return &imgdata.params;}
     int                         open_file(const char *fname, INT64 max_buffered_sz=LIBRAW_USE_STREAMS_DATASTREAM_MAXSIZE);
+#if defined(_WIN32) && !defined(__MINGW32__) && defined(_MSC_VER) && (_MSC_VER > 1310)
+	int                         open_file(const wchar_t *fname, INT64 max_buffered_sz=LIBRAW_USE_STREAMS_DATASTREAM_MAXSIZE);
+#endif
     int                         open_buffer(void *buffer, size_t size);
-    int                         open_datastream(LibRaw_abstract_datastream *);
+    virtual int                 open_datastream(LibRaw_abstract_datastream *);
+	int							error_count(){return libraw_internal_data.unpacker_data.data_error;}
+	void							recycle_datastream();
     int                         unpack(void);
     int                         unpack_thumb(void);
 
     int                         adjust_sizes_info_only(void);
-    void                        subtract_black();
+    LibRaw_colormatrix_type	camera_color_type();
+    int                         subtract_black();
+    int                         subtract_black_internal();
     int                         raw2image();
-    int                         raw2image_ex();
+    int                         raw2image_ex(int do_subtract_black);
     void                        raw2image_start();
     void                        free_image();
     int                         adjust_maximum();
+    void		      	set_exifparser_handler( exif_parser_callback cb,void *data) {callbacks.exifparser_data = data; callbacks.exif_cb = cb; }
     void                        set_memerror_handler( memory_callback cb,void *data) {callbacks.memcb_data = data; callbacks.mem_cb = cb; }
     void                        set_dataerror_handler(data_callback func, void *data) { callbacks.datacb_data = data; callbacks.data_cb = func;}
     void                        set_progress_handler(progress_callback pcb, void *data) { callbacks.progresscb_data = data; callbacks.progress_cb = pcb;}
@@ -124,13 +138,18 @@ class DllDef LibRaw
     static const char*          strprogress(enum LibRaw_progress);
     static const char*          strerror(int p);
     /* dcraw emulation */
-    int                         dcraw_document_mode_processing();
     int                         dcraw_ppm_tiff_writer(const char *filename);
     int                         dcraw_thumb_writer(const char *fname);
     int                         dcraw_process(void);
+    /* information calls */
+    int is_fuji_rotated(){return libraw_internal_data.internal_output_params.fuji_width;}
+    int is_sraw();
+	int sraw_midpoint();
+	int is_nikon_sraw();
+	int is_coolscan_nef();
     /* memory writers */
-    libraw_processed_image_t*   dcraw_make_mem_image(int *errcode=NULL);  
-    libraw_processed_image_t*   dcraw_make_mem_thumb(int *errcode=NULL);
+    virtual libraw_processed_image_t*   dcraw_make_mem_image(int *errcode=NULL);  
+    virtual libraw_processed_image_t*   dcraw_make_mem_thumb(int *errcode=NULL);
     static void                 dcraw_clear_mem(libraw_processed_image_t*);
     
     /* Additional calls for make_mem_image */
@@ -139,18 +158,45 @@ class DllDef LibRaw
 
     /* free all internal data structures */
     void         recycle(); 
-    ~LibRaw(void) { recycle(); delete tls; }
+    virtual ~LibRaw(void); 
 
     int COLOR(int row, int col) { return libraw_internal_data.internal_output_params.fuji_width? FCF(row,col):FC(row,col);}
  
     int FC(int row,int col) { return (imgdata.idata.filters >> (((row << 1 & 14) | (col & 1)) << 1) & 3);}
-    int         fc (int row, int col);
+    int         fcol (int row, int col);
     
     const char *unpack_function_name();
-    int get_decoder_info(libraw_decoder_info_t* d_info);
+    virtual int get_decoder_info(libraw_decoder_info_t* d_info);
     libraw_internal_data_t * get_internal_data_pointer(){ return &libraw_internal_data; }
 
-  private:
+    /* Debanding filter */
+    int  wf_remove_banding();
+
+  /* Phase one correction/subtractBL calls */
+	/* Returns libraw error code */
+  
+  int phase_one_subtract_black(ushort *src, ushort *dest);
+  int phase_one_correct();
+
+  int  set_rawspeed_camerafile(char *filename);
+  void setCancelFlag();
+  void clearCancelFlag();
+  virtual void adobe_coeff (const char *, const char *, int internal_only=0);
+
+
+protected:
+    void checkCancel();
+	void        cam_xyz_coeff(float _rgb_cam[3][4], double cam_xyz[4][3]);
+    void phase_one_allocate_tempbuffer();
+    void phase_one_free_tempbuffer();
+    virtual int  is_phaseone_compressed();
+    /* Hotspots */
+    virtual void copy_fuji_uncropped(unsigned short cblack[4], unsigned short *dmaxp);
+    virtual void copy_bayer(unsigned short cblack[4], unsigned short *dmaxp);
+    virtual void fuji_rotate();
+    virtual void convert_to_rgb_loop(float out_cam[3][4]);
+    virtual void lin_interpolate_loop(int code[16][16][32],int size);
+    virtual void scale_colors_loop(float scale_mul[4]);
 
     int FCF(int row,int col) { 
         int rr,cc;
@@ -164,6 +210,7 @@ class DllDef LibRaw
         return FC(rr,cc);
     }
 
+    void adjust_bl();
     void*        malloc(size_t t);
     void*        calloc(size_t n,size_t t);
     void*        realloc(void *p, size_t s);
@@ -179,6 +226,7 @@ class DllDef LibRaw
     libraw_callbacks_t callbacks;
 
     LibRaw_constants rgb_constants;
+
     void        (LibRaw:: *write_thumb)();
     void        (LibRaw:: *write_fun)();
     void        (LibRaw:: *load_raw)();
@@ -186,14 +234,17 @@ class DllDef LibRaw
 
     void        kodak_thumb_loader();
     void        write_thumb_ppm_tiff(FILE *); 
+    void        x3f_thumb_loader();
+#ifdef LIBRAW_DEMOSAIC_PACK_GPL2
     void        foveon_thumb_loader (void);
+#endif
     
     int         own_filtering_supported(){ return 0;}
     void        identify();
-    void        identify2(unsigned, unsigned, char*);
     void        write_ppm_tiff ();
     void        convert_to_rgb();
     void        remove_zeroes();
+    void        crop_masked_pixels();
 #ifndef NO_LCMS
     void	apply_profile(const char*,const char*);
 #endif
@@ -202,7 +253,11 @@ class DllDef LibRaw
     void        lin_interpolate();
     void        vng_interpolate();
     void        ppg_interpolate();
+    void        cielab(ushort rgb[3], short lab[3]);
+    void        xtrans_interpolate(int);
     void        ahd_interpolate();
+    void        dht_interpolate();
+    void        aahd_interpolate();
 
     /* from demosaic pack */
     void        ahd_interpolate_mod();
@@ -231,23 +286,37 @@ class DllDef LibRaw
     void        recover_highlights();
     void        green_matching();
 
-    void        fuji_rotate();
     void        stretch();
 
+#ifdef LIBRAW_DEMOSAIC_PACK_GPL2
     void        foveon_thumb ();
+#endif
     void        jpeg_thumb_writer (FILE *tfp,char *thumb,int thumb_length);
     void        jpeg_thumb ();
     void        ppm_thumb ();
+    void        ppm16_thumb();
     void        layer_thumb ();
     void        rollei_thumb ();
     void        kodak_thumb_load_raw();
 
+#ifdef LIBRAW_DEMOSAIC_PACK_GPL2
     void        foveon_decoder (unsigned size, unsigned code);
+#endif
     unsigned    get4();
 
     int         flip_index (int row, int col);
     void        gamma_curve (double pwr, double ts, int mode, int imax);
+    void        cubic_spline (const int *x_, const int *y_, const int len);
+
+  /* RawSpeed data */
+  void		*_rawspeed_camerameta;
+  void          *_rawspeed_decoder;
+  void		fix_after_rawspeed(int bl);
+  /* Fast cancel flag */
+  long          _exitflag;
 
+  /* X3F data */
+  void          *_x3f_data;
 
 #ifdef LIBRAW_LIBRARY_BUILD 
 #include "internal/libraw_internal_funcs.h"
diff --git a/Source/LibRawLite/libraw/libraw_alloc.h b/Source/LibRawLite/libraw/libraw_alloc.h
index ec6d4e6..6d85d25 100644
--- a/Source/LibRawLite/libraw/libraw_alloc.h
+++ b/Source/LibRawLite/libraw/libraw_alloc.h
@@ -1,6 +1,6 @@
 /* -*- C++ -*-
  * File: libraw_alloc.h
- * Copyright 2008-2010 LibRaw LLC (info at libraw.org)
+ * Copyright 2008-2013 LibRaw LLC (info at libraw.org)
  * Created: Sat Mar  22, 2008 
  *
  * LibRaw C++ interface
@@ -27,7 +27,7 @@ it under the terms of the one of three licenses as you choose:
 
 #ifdef __cplusplus
 
-#define MSIZE 32
+#define LIBRAW_MSIZE 32
 
 class DllDef libraw_memmgr
 {
@@ -63,7 +63,7 @@ class DllDef libraw_memmgr
     }
     void cleanup(void)
     {
-        for(int i = 0; i< MSIZE; i++)
+        for(int i = 0; i< LIBRAW_MSIZE; i++)
             if(mems[i])
                 {
                     free(mems[i]);
@@ -72,12 +72,12 @@ class DllDef libraw_memmgr
     }
 
   private:
-    void *mems[MSIZE];
+    void *mems[LIBRAW_MSIZE];
     int calloc_cnt;
     void mem_ptr(void *ptr)
     {
         if(ptr)
-            for(int i=0;i < MSIZE; i++)
+            for(int i=0;i < LIBRAW_MSIZE; i++)
                 if(!mems[i])
                     {
                         mems[i] = ptr;
@@ -87,7 +87,7 @@ class DllDef libraw_memmgr
     void forget_ptr(void *ptr)
     {
         if(ptr)
-            for(int i=0;i < MSIZE; i++)
+            for(int i=0;i < LIBRAW_MSIZE; i++)
                 if(mems[i] == ptr)
                     mems[i] = NULL;
     }
diff --git a/Source/LibRawLite/libraw/libraw_const.h b/Source/LibRawLite/libraw/libraw_const.h
index 0fe03cf..7327556 100644
--- a/Source/LibRawLite/libraw/libraw_const.h
+++ b/Source/LibRawLite/libraw/libraw_const.h
@@ -1,8 +1,7 @@
 /* -*- C++ -*-
  * File: libraw_const.h
- * Copyright 2008-2010 LibRaw LLC (info at libraw.org)
+ * Copyright 2008-2013 LibRaw LLC (info at libraw.org)
  * Created: Sat Mar  8 , 2008
- *
  * LibRaw error codes
 LibRaw is free software; you can redistribute it and/or modify
 it under the terms of the one of three licenses as you choose:
@@ -24,16 +23,82 @@ it under the terms of the one of three licenses as you choose:
 #define LIBRAW_DEFAULT_ADJUST_MAXIMUM_THRESHOLD 0.75
 #define LIBRAW_DEFAULT_AUTO_BRIGHTNESS_THRESHOLD 0.01
 
+enum LibRaw_colormatrix_type
+{
+ LIBRAW_CMATRIX_NONE=0,
+ LIBRAW_CMATRIX_DNG=1,
+ LIBRAW_CMATRIX_DIGBACK=2,
+ LIBRAW_CMATRIX_OTHER=4
+};
+
+enum LibRaw_camera_mounts
+  {
+    LIBRAW_MOUNT_Unknown=0,
+    LIBRAW_MOUNT_Minolta_A=1,
+    LIBRAW_MOUNT_Sony_E=2,
+    LIBRAW_MOUNT_Canon_EF=3,
+    LIBRAW_MOUNT_Canon_EF_S=4,
+    LIBRAW_MOUNT_Canon_EF_M=5,
+    LIBRAW_MOUNT_Nikon_F=6,
+    LIBRAW_MOUNT_Nikon_CX=7,	// used in Nikon 1 series
+    LIBRAW_MOUNT_FT=8,	// original 4/3
+    LIBRAW_MOUNT_mFT=9,	// micro 4/3
+    LIBRAW_MOUNT_Pentax_K=10,
+    LIBRAW_MOUNT_Pentax_Q=11,
+    LIBRAW_MOUNT_Pentax_645=12,
+    LIBRAW_MOUNT_Fuji_X=13,
+    LIBRAW_MOUNT_Leica_M=14,
+    LIBRAW_MOUNT_Leica_R=15,
+    LIBRAW_MOUNT_Leica_S=16,
+    LIBRAW_MOUNT_Samsung_NX=17,
+    LIBRAW_MOUNT_RicohModule=18,
+    LIBRAW_MOUNT_Samsung_NX_M=19,
+    LIBRAW_MOUNT_Leica_T=20,
+    LIBRAW_MOUNT_Contax_N=21,
+    LIBRAW_MOUNT_Sigma_X3F=22,
+    LIBRAW_MOUNT_FixedLens=99
+  };
+
+enum LibRaw_camera_formats
+  {
+
+    LIBRAW_FORMAT_APSC=1,
+    LIBRAW_FORMAT_FF=2,
+    LIBRAW_FORMAT_MF=3,
+    LIBRAW_FORMAT_APSH=4,
+    LIBRAW_FORMAT_FT=8	
+  };
+
+
+enum LibRaw_sonyarw2_options
+{
+  LIBRAW_SONYARW2_NONE=0,
+  LIBRAW_SONYARW2_BASEONLY=1,  
+  LIBRAW_SONYARW2_DELTAONLY=2,  
+  LIBRAW_SONYARW2_DELTAZEROBASE=3,
+  LIBRAW_SONYARW2_DELTATOVALUE=4
+};
+enum LibRaw_dp2q_options
+{
+	LIBRAW_DP2QOPT_NONE=0,
+	LIBRAW_DP2Q_INTERPOLATERG=1,
+	LIBRAW_DP2Q_INTERPOLATEAF=2
+};
+
 enum LibRaw_decoder_flags
 {
-    LIBRAW_DECODER_LEGACY = 1,      
-    LIBRAW_DECODER_FLATFIELD = 1<<1,
-    LIBRAW_DECODER_4COMPONENT = 1<<2,
+  //    LIBRAW_DECODER_LEGACY = 1,      
+  //  LIBRAW_DECODER_FLATFIELD = 1<<1,
     LIBRAW_DECODER_USEBAYER2 = 1<<3,
     LIBRAW_DECODER_HASCURVE = 1<<4,
+    LIBRAW_DECODER_SONYARW2 = 1<<5,
+    LIBRAW_DECODER_TRYRAWSPEED = 1<<6,
+    LIBRAW_DECODER_OWNALLOC = 1<<7,
+    LIBRAW_DECODER_FIXEDMAXC = 1<<8,
     LIBRAW_DECODER_NOTSET = 1<<15
 };
 
+#define LIBRAW_XTRANS 9
 
 enum LibRaw_constructor_flags
 {
@@ -56,7 +121,11 @@ enum LibRaw_warnings
     LIBRAW_WARN_NO_BADPIXELMAP=1<<8,
     LIBRAW_WARN_BAD_DARKFRAME_FILE=1<<9,
     LIBRAW_WARN_BAD_DARKFRAME_DIM=1<<10,
-    LIBRAW_WARN_NO_JASPER = 1<<11
+    LIBRAW_WARN_NO_JASPER = 1<<11,
+    LIBRAW_WARN_RAWSPEED_PROBLEM = 1<<12,
+    LIBRAW_WARN_RAWSPEED_UNSUPPORTED = 1<<13,
+    LIBRAW_WARN_RAWSPEED_PROCESSED = 1<<14,
+    LIBRAW_WARN_FALLBACK_TO_AHD = 1<<15
 };
 
 enum LibRaw_exceptions
@@ -73,7 +142,7 @@ enum LibRaw_exceptions
     LIBRAW_EXCEPTION_DECODE_JPEG2000=9
 };
 
-
+#if 0
 enum LibRaw_colorstate
 {
     LIBRAW_COLORSTATE_UNKNOWN   =0,
@@ -85,6 +154,7 @@ enum LibRaw_colorstate
     LIBRAW_COLORSTATE_RESERVED2 =6,
     LIBRAW_COLORSTATE_RESERVED3 =7
 };
+#endif
 
 enum LibRaw_progress
 {
@@ -93,23 +163,23 @@ enum LibRaw_progress
     LIBRAW_PROGRESS_IDENTIFY            = 1<<1,
     LIBRAW_PROGRESS_SIZE_ADJUST         = 1<<2,
     LIBRAW_PROGRESS_LOAD_RAW            = 1<<3,
-    LIBRAW_PROGRESS_REMOVE_ZEROES       = 1<<4,
-    LIBRAW_PROGRESS_BAD_PIXELS          = 1<<5,
-    LIBRAW_PROGRESS_DARK_FRAME          = 1<<6,
-    LIBRAW_PROGRESS_FOVEON_INTERPOLATE  = 1<<7,
-    LIBRAW_PROGRESS_SCALE_COLORS        = 1<<8,
-    LIBRAW_PROGRESS_PRE_INTERPOLATE     = 1<<9,
-    LIBRAW_PROGRESS_INTERPOLATE         = 1<<10,
-    LIBRAW_PROGRESS_MIX_GREEN           = 1<<11,
-    LIBRAW_PROGRESS_MEDIAN_FILTER       = 1<<12,
-    LIBRAW_PROGRESS_HIGHLIGHTS          = 1<<13,
-    LIBRAW_PROGRESS_FUJI_ROTATE         = 1<<14,
-    LIBRAW_PROGRESS_FLIP                = 1<<15,
-    LIBRAW_PROGRESS_APPLY_PROFILE       = 1<<16,
-    LIBRAW_PROGRESS_CONVERT_RGB         = 1<<17,
-    LIBRAW_PROGRESS_STRETCH             = 1<<18,
+	LIBRAW_PROGRESS_RAW2_IMAGE			= 1<<4,
+    LIBRAW_PROGRESS_REMOVE_ZEROES       = 1<<5,
+    LIBRAW_PROGRESS_BAD_PIXELS          = 1<<6,
+    LIBRAW_PROGRESS_DARK_FRAME          = 1<<7,
+    LIBRAW_PROGRESS_FOVEON_INTERPOLATE  = 1<<8,
+    LIBRAW_PROGRESS_SCALE_COLORS        = 1<<9,
+    LIBRAW_PROGRESS_PRE_INTERPOLATE     = 1<<10,
+    LIBRAW_PROGRESS_INTERPOLATE         = 1<<11,
+    LIBRAW_PROGRESS_MIX_GREEN           = 1<<12,
+    LIBRAW_PROGRESS_MEDIAN_FILTER       = 1<<13,
+    LIBRAW_PROGRESS_HIGHLIGHTS          = 1<<14,
+    LIBRAW_PROGRESS_FUJI_ROTATE         = 1<<15,
+    LIBRAW_PROGRESS_FLIP                = 1<<16,
+    LIBRAW_PROGRESS_APPLY_PROFILE       = 1<<17,
+    LIBRAW_PROGRESS_CONVERT_RGB         = 1<<18,
+    LIBRAW_PROGRESS_STRETCH             = 1<<19,
 /* reserved */
-    LIBRAW_PROGRESS_STAGE19             = 1<<19,
     LIBRAW_PROGRESS_STAGE20             = 1<<20,
     LIBRAW_PROGRESS_STAGE21             = 1<<21,
     LIBRAW_PROGRESS_STAGE22             = 1<<22,
@@ -135,6 +205,7 @@ enum LibRaw_errors
     LIBRAW_OUT_OF_ORDER_CALL=-4,
     LIBRAW_NO_THUMBNAIL=-5,
     LIBRAW_UNSUPPORTED_THUMBNAIL=-6,
+    LIBRAW_INPUT_CLOSED=-7,
     LIBRAW_UNSUFFICIENT_MEMORY=-100007,
     LIBRAW_DATA_ERROR=-100008,
     LIBRAW_IO_ERROR=-100009,
diff --git a/Source/LibRawLite/libraw/libraw_datastream.h b/Source/LibRawLite/libraw/libraw_datastream.h
index 5096047..a298e84 100644
--- a/Source/LibRawLite/libraw/libraw_datastream.h
+++ b/Source/LibRawLite/libraw/libraw_datastream.h
@@ -1,6 +1,6 @@
 /* -*- C -*-
  * File: libraw_datastream.h
- * Copyright 2008-2010 LibRaw LLC (info at libraw.org)
+ * Copyright 2008-2013 LibRaw LLC (info at libraw.org)
  * Created: Sun Jan 18 13:07:35 2009
  *
  * LibRaw Data stream interface
@@ -49,7 +49,6 @@ it under the terms of the one of three licenses as you choose:
 #define IOERROR() do { throw LIBRAW_EXCEPTION_IO_EOF; } while(0)
 
 class LibRaw_buffer_datastream;
-class LibRaw_byte_buffer;
 class LibRaw_bit_buffer;
 
 class DllDef LibRaw_abstract_datastream
@@ -61,16 +60,21 @@ class DllDef LibRaw_abstract_datastream
     virtual int         read(void *,size_t, size_t ) = 0;
     virtual int         seek(INT64 , int ) = 0;
     virtual INT64       tell() = 0;
+    virtual INT64 	size() = 0;
     virtual int         get_char() = 0;
     virtual char*       gets(char *, int) = 0;
     virtual int         scanf_one(const char *, void *) = 0;
     virtual int         eof() = 0;
     virtual void *      make_jas_stream() = 0;
+    virtual int         jpeg_src(void *) { return -1; }
     /* Make buffer from current offset */
-    virtual LibRaw_byte_buffer *make_byte_buffer(unsigned int sz);
 
     /* subfile parsing not implemented in base class */
     virtual const char* fname(){ return NULL;};
+#if defined(_WIN32) && !defined(__MINGW32__) && defined(_MSC_VER) && (_MSC_VER > 1310)
+	virtual const wchar_t* wfname(){ return NULL;};
+	virtual int         subfile_open(const wchar_t*) { return -1;}
+#endif
     virtual int         subfile_open(const char*) { return -1;}
     virtual void        subfile_close() { }
 
@@ -91,17 +95,26 @@ class DllDef  LibRaw_file_datastream: public LibRaw_abstract_datastream
   protected:
     std::auto_ptr<std::streambuf> f; /* will close() automatically through dtor */
     std::auto_ptr<std::streambuf> saved_f; /* when *f is a subfile, *saved_f is the master file */
-    const char *filename;
-
+    std::string filename;
+    INT64 _fsize;
+#ifdef WIN32
+    std::wstring wfilename;
+#endif
+    FILE *jas_file;
   public:
-    virtual             ~LibRaw_file_datastream(){}
-                        LibRaw_file_datastream(const char *fname);
+    virtual     ~LibRaw_file_datastream();
+                LibRaw_file_datastream(const char *fname);
+#if defined(_WIN32) && !defined(__MINGW32__) && defined(_MSC_VER) && (_MSC_VER > 1310)
+                LibRaw_file_datastream(const wchar_t *fname);
+#endif
     virtual void        *make_jas_stream();
+    virtual int         jpeg_src(void *jpegdata);
     virtual int         valid();
     virtual int         read(void * ptr,size_t size, size_t nmemb);
     virtual int         eof();
     virtual int         seek(INT64 o, int whence);
     virtual INT64       tell();
+    virtual INT64	size() { return _fsize;}
     virtual int         get_char()
         { 
             if(substream) return substream->get_char();
@@ -110,10 +123,15 @@ class DllDef  LibRaw_file_datastream: public LibRaw_abstract_datastream
     virtual char*       gets(char *str, int sz); 
     virtual int         scanf_one(const char *fmt, void*val); 
     virtual const char* fname();
+#if defined(_WIN32) && !defined(__MINGW32__) && defined(_MSC_VER) && (_MSC_VER > 1310)
+    virtual const wchar_t* wfname();
+    virtual int         subfile_open(const wchar_t *fn);
+#endif
     virtual int         subfile_open(const char *fn);
     virtual void        subfile_close();
 };
 
+
 class DllDef  LibRaw_buffer_datastream : public LibRaw_abstract_datastream
 {
   public:
@@ -121,11 +139,12 @@ class DllDef  LibRaw_buffer_datastream : public LibRaw_abstract_datastream
     virtual             ~LibRaw_buffer_datastream();
     virtual int         valid();
     virtual void        *make_jas_stream();
-    virtual LibRaw_byte_buffer *make_byte_buffer(unsigned int sz);
+    virtual int         jpeg_src(void *jpegdata);
     virtual int         read(void * ptr,size_t sz, size_t nmemb);
     virtual int         eof();
     virtual int         seek(INT64 o, int whence);
     virtual INT64       tell();
+    virtual INT64	size() { return streamsize;}
     virtual char*       gets(char *s, int sz);
     virtual int         scanf_one(const char *fmt, void* val);
     virtual int         get_char()
@@ -145,17 +164,26 @@ class DllDef LibRaw_bigfile_datastream : public LibRaw_abstract_datastream
 {
   public:
                         LibRaw_bigfile_datastream(const char *fname);
+#if defined(_WIN32) && !defined(__MINGW32__) && defined(_MSC_VER) && (_MSC_VER > 1310)
+			LibRaw_bigfile_datastream(const wchar_t *fname);
+#endif
     virtual             ~LibRaw_bigfile_datastream();
     virtual int         valid();
-    virtual void *make_jas_stream();
+    virtual int         jpeg_src(void *jpegdata);
+    virtual void        *make_jas_stream();
 
     virtual int         read(void * ptr,size_t size, size_t nmemb); 
     virtual int         eof();
     virtual int         seek(INT64 o, int whence);
     virtual INT64       tell();
+    virtual INT64	size() { return _fsize;}
     virtual char*       gets(char *str, int sz);
     virtual int         scanf_one(const char *fmt, void*val);
     virtual const char *fname();
+#if defined(_WIN32) && !defined(__MINGW32__) && defined(_MSC_VER) && (_MSC_VER > 1310)
+    virtual const wchar_t* wfname();
+    virtual int         subfile_open(const wchar_t *fn);
+#endif
     virtual int         subfile_open(const char *fn);
     virtual void        subfile_close();
     virtual int         get_char()
@@ -167,9 +195,13 @@ class DllDef LibRaw_bigfile_datastream : public LibRaw_abstract_datastream
 #endif
     }
 
-  private:
+protected:
     FILE *f,*sav;
-    const char *filename;
+    std::string filename;
+    INT64 _fsize;
+#ifdef WIN32
+    std::wstring wfilename;
+#endif
 };
 
 #ifdef WIN32
@@ -182,6 +214,7 @@ public:
     LibRaw_windows_datastream(HANDLE hFile);
     /* dtor: unmap and close the mapping handle */
     virtual ~LibRaw_windows_datastream();
+    virtual INT64 size() { return cbView_;}
 
 protected:
     void Open(HANDLE hFile);
diff --git a/Source/LibRawLite/libraw/libraw_internal.h b/Source/LibRawLite/libraw/libraw_internal.h
index 286286f..5490a1c 100644
--- a/Source/LibRawLite/libraw/libraw_internal.h
+++ b/Source/LibRawLite/libraw/libraw_internal.h
@@ -1,6 +1,6 @@
 /* -*- C++ -*-
  * File: libraw_internal.h
- * Copyright 2008-2010 LibRaw LLC (info at libraw.org)
+ * Copyright 2008-2013 LibRaw LLC (info at libraw.org)
  * Created: Sat Mar  8 , 2008
  *
  * LibRaw internal data structures (not visible outside)
@@ -51,7 +51,7 @@ public:
          unsigned bitbuf;
          int vbits, reset;
     }getbits;
-    struct 
+    struct
     {
          UINT64 bitbuf;
          int vbits;
@@ -61,18 +61,22 @@ public:
     {
          unsigned pad[128], p;
     }sony_decrypt;
-    uchar jpeg_buffer[4096];
     struct
     {
         uchar buf[0x4000];
         int vbits, padding;
     }pana_bits;
-
-    void init() 
-        { 
+    uchar jpeg_buffer[4096];
+    struct
+    {
+      float cbrt[0x10000], xyz_cam[3][4];
+    }ahd_data;
+    void init()
+        {
             getbits.bitbuf = 0; getbits.vbits = getbits.reset = 0;
             ph1_bits.bitbuf = 0; ph1_bits.vbits = 0;
             pana_bits.vbits = 0;
+            ahd_data.cbrt[0]=-2.0f;
         }
 };
 
@@ -97,6 +101,7 @@ typedef struct
     char        *meta_data;
     INT64       profile_offset;
     INT64       toffset;
+	unsigned    pana_black[4];
 
 } internal_data_t;
 
@@ -118,7 +123,7 @@ typedef struct
 
 typedef struct
 {
-    short       order; 
+    short       order;
     ushort      sraw_mul[4],cr2_slice[3];
     unsigned    kodak_cbpp;
     INT64       strip_offset, data_offset;
@@ -133,6 +138,7 @@ typedef struct
     unsigned    zero_after_ff;
     unsigned    tile_width, tile_length,load_flags;
     unsigned    data_error;
+	int			hasselblad_parser_flag;
 }unpacker_data_t;
 
 
@@ -140,22 +146,23 @@ typedef struct
 typedef struct
 {
     internal_data_t internal_data;
-    libraw_internal_output_params_t internal_output_params;    
+    libraw_internal_output_params_t internal_output_params;
     output_data_t output_data;
     identify_data_t identify_data;
     unpacker_data_t unpacker_data;
 } libraw_internal_data_t;
 
 
-struct decode 
+struct decode
 {
     struct decode *branch[2];
     int leaf;
 };
 
-struct tiff_ifd_t 
+struct tiff_ifd_t
 {
     int t_width, t_height, bps, comp, phint, offset, t_flip, samples, bytes,tile_maxbytes;
+    int t_tile_width, t_tile_length;
 };
 
 
diff --git a/Source/LibRawLite/libraw/libraw_types.h b/Source/LibRawLite/libraw/libraw_types.h
index b2b484c..de2f695 100644
--- a/Source/LibRawLite/libraw/libraw_types.h
+++ b/Source/LibRawLite/libraw/libraw_types.h
@@ -1,6 +1,6 @@
 /* -*- C++ -*-
  * File: libraw_types.h
- * Copyright 2008-2010 LibRaw LLC (info at libraw.org)
+ * Copyright 2008-2013 LibRaw LLC (info at libraw.org)
  * Created: Sat Mar  8 , 2008
  *
  * LibRaw C data structures
@@ -29,10 +29,10 @@ it under the terms of the one of three licenses as you choose:
 #endif
 #include <stdio.h>
 
-#if defined (_OPENMP) 
+#if defined (_OPENMP)
 
-#if defined(WIN32) 
-# if defined (_MSC_VER) && (_MSC_VER >= 1600 || (_MSC_VER == 1500 && _MSC_FULL_VER >= 150030729) ) 
+#if defined(WIN32)
+# if defined (_MSC_VER) && (_MSC_VER >= 1600 || (_MSC_VER == 1500 && _MSC_FULL_VER >= 150030729) )
 /* VS2010+ : OpenMP works OK, VS2008: have tested by cgilles */
 #   define LIBRAW_USE_OPENMP
 #elif defined (__INTEL_COMPILER) && (__INTEL_COMPILER >=910)
@@ -44,7 +44,7 @@ it under the terms of the one of three licenses as you choose:
 /* Not Win32 */
 # elif (defined(__APPLE__) || defined(__MACOSX__)) && defined(_REENTRANT)
 #   undef LIBRAW_USE_OPENMP
-# else 
+# else
 #   define LIBRAW_USE_OPENMP
 # endif
 #endif
@@ -69,16 +69,14 @@ extern "C" {
 #include "libraw_const.h"
 #include "libraw_version.h"
 
-#ifndef _MSC_VER
-// define portable types for 32-bit / 64-bit OS
-#include <inttypes.h>
+#ifdef WIN32
+typedef __int64 INT64;
+typedef unsigned __int64 UINT64;
+#else
+#include <stdint.h>
 typedef int64_t INT64;
 typedef uint64_t UINT64;
-#else
-// MS is not C99 ISO compliant
-typedef signed __int64 INT64;
-typedef unsigned __int64 UINT64;
-#endif // _MSC_VER
+#endif
 
 typedef unsigned char uchar;
 typedef unsigned short ushort;
@@ -110,11 +108,11 @@ typedef struct
     unsigned    zero_is_bad;
     ushort      shrink;
     ushort      fuji_width;
-    ushort      fwidth,fheight;
 } libraw_internal_output_params_t;
 
 
 typedef void (* memory_callback)(void * data, const char *file, const char *where);
+typedef void (*exif_parser_callback) (void *context, int tag, int type, int len,unsigned int ord, void *ifp);
 
 DllDef void default_memory_callback(void *data,const char *file, const char *where);
 
@@ -134,111 +132,140 @@ typedef struct
 
     progress_callback progress_cb;
     void *progresscb_data;
+
+	exif_parser_callback exif_cb;
+	void *exifparser_data;
 } libraw_callbacks_t;
 
 
 typedef struct
 {
-    enum LibRaw_image_formats type; 
+    enum LibRaw_image_formats type;
     ushort      height,
                 width,
                 colors,
                 bits;
-    unsigned int  data_size; 
-    unsigned char data[1]; 
+    unsigned int  data_size;
+    unsigned char data[1];
 }libraw_processed_image_t;
 
 
 typedef struct
 {
-    char        make[64];
-    char        model[64];
-
-    unsigned    raw_count;
-    unsigned    dng_version;
-    unsigned    is_foveon;
-    int         colors;
-
-    unsigned    filters; 
-    char        cdesc[5];
+  char        make[64];
+  char        model[64];
+  char		  	software[64];
+  unsigned    raw_count;
+  unsigned    dng_version;
+  unsigned    is_foveon;
+  int         colors;
+  unsigned    filters;
+  char        xtrans[6][6];
+  char        xtrans_abs[6][6];
+  char        cdesc[5];
+  unsigned    xmplen;
+  char	      *xmpdata;
 
 }libraw_iparams_t;
 
 typedef struct
 {
-    ushort      raw_height, 
-                raw_width, 
-                height, 
-                width, 
-                top_margin, 
+    ushort      raw_height,
+                raw_width,
+                height,
+                width,
+                top_margin,
                 left_margin;
     ushort      iheight,
                 iwidth;
+    unsigned    raw_pitch;
     double      pixel_aspect;
     int         flip;
+    int         mask[8][4];
 
 } libraw_image_sizes_t;
 
 struct ph1_t
 {
-    int format, key_off, t_black, black_off, split_col, tag_21a;
-    float tag_210;
+  int format, key_off, tag_21a;
+  int t_black, split_col, black_col, split_row, black_row;
+  float tag_210;
 };
 
+typedef struct
+{
+  unsigned short illuminant;
+  float calibration[4][4];
+  float colormatrix[4][3];
+} libraw_dng_color_t;
 
 typedef struct
 {
-    unsigned curve_state        : 3;
-    unsigned rgb_cam_state      : 3;
-    unsigned cmatrix_state      : 3;
-    unsigned pre_mul_state      : 3;
-    unsigned cam_mul_state      : 3;
-    unsigned filler             : 17;
-} color_data_state_t;
+	int CanonColorDataVer;
+	int CanonColorDataSubVer;
+	int SpecularWhiteLevel;
+	int AverageBlackLevel;
+} canon_makernotes_t;
 
 typedef struct
 {
-    color_data_state_t   color_flags;
-    ushort      white[8][8];  
-    float       cam_mul[4]; 
-    float       pre_mul[4]; 
-    float       cmatrix[3][4]; 
-    float       rgb_cam[3][4]; 
-    float       cam_xyz[4][3]; 
-    ushort      curve[0x10000]; 
-    unsigned    black;
-    unsigned    cblack[8];
-    unsigned    maximum;
-    unsigned    channel_maximum[4];
-    struct ph1_t       phase_one_data;
-    float       flash_used; 
-    float       canon_ev; 
-    char        model2[64];
-    void        *profile;
-    unsigned    profile_length;
-    short  (*ph1_black)[2];
+  ushort      curve[0x10000];
+  unsigned    cblack[4102];
+  unsigned    black;
+  unsigned    data_maximum;
+  unsigned    maximum;
+  ushort      white[8][8];
+  float       cam_mul[4];
+  float       pre_mul[4];
+  float       cmatrix[3][4];
+  float       rgb_cam[3][4];
+  float       cam_xyz[4][3];
+  struct ph1_t       phase_one_data;
+  float       flash_used;
+  float       canon_ev;
+  char        model2[64];
+  void        *profile;
+  unsigned    profile_length;
+  unsigned    black_stat[8];
+  libraw_dng_color_t  dng_color[2];
+  canon_makernotes_t canon_makernotes;
+  float	      baseline_exposure;
+  int		  OlympusSensorCalibration[2];
+  int		digitalBack_color;
 }libraw_colordata_t;
 
 typedef struct
 {
     enum LibRaw_thumbnail_formats tformat;
-    ushort      twidth, 
+    ushort      twidth,
                 theight;
     unsigned    tlength;
     int         tcolors;
-    
+
     char       *thumb;
 }libraw_thumbnail_t;
 
 typedef struct
 {
-    float       iso_speed; 
+	float latitude[3]; // Deg,min,sec
+	float longtitude[3]; // Deg,min,sec
+	float gpstimestamp[3]; // Deg,min,sec
+	float altitude;
+	char  altref, latref, longref, gpsstatus;
+	char  gpsparsed;
+
+} libraw_gps_info_t;
+
+typedef struct
+{
+    float       iso_speed;
     float       shutter;
     float       aperture;
     float       focal_len;
-    time_t      timestamp; 
+    time_t      timestamp;
     unsigned    shot_order;
     unsigned    gpsdata[32];
+	libraw_gps_info_t parsed_gps;
     char        desc[512],
                 artist[64];
 } libraw_imgother_t;
@@ -255,7 +282,6 @@ typedef struct
     float       threshold;      /*  -n */
     int         half_size;      /* -h */
     int         four_color_rgb; /* -f */
-    int         document_mode;  /* -d/-D */
     int         highlight;      /* -H */
     int         use_auto_wb;    /* -a */
     int         use_camera_wb;  /* -w */
@@ -270,22 +296,15 @@ typedef struct
     int         user_flip;      /* -t */
     int         user_qual;      /* -q */
     int         user_black;     /* -k */
+    int		user_cblack[4];
     int         user_sat;       /* -S */
 
     int         med_passes;     /* -m */
-    float       auto_bright_thr; 
+    float       auto_bright_thr;
     float       adjust_maximum_thr;
     int         no_auto_bright; /* -W */
     int         use_fuji_rotate;/* -j */
     int         green_matching;
-#if 0
-    /* AFD noise suppression parameters, disabled for now */
-    int         afd_noise_att;
-    int         afd_noise_thres;
-    int         afd_luminance_passes;
-    int         afd_chrominance_method;
-    int         afd_luminance_only; 
-#endif
     /* DCB parameters */
     int         dcb_iterations;
     int         dcb_enhance_fl;
@@ -307,41 +326,112 @@ typedef struct
     int exp_correc;
     float exp_shift;
     float exp_preser;
+   /* WF debanding */
+    int   wf_debanding;
+    float wf_deband_treshold[4];
+	/* Raw speed */
+    int use_rawspeed;
+  /* Disable Auto-scale */
+    int no_auto_scale;
+  /* Disable intepolation */
+    int no_interpolation;
+  /* Disable sRAW YCC to RGB conversion */
+  int sraw_ycc;
+  /* Force use x3f data decoding either if demosaic pack GPL2 enabled */
+  int force_foveon_x3f;
+  int x3f_flags;
+  /* Sony ARW2 digging mode */
+  int sony_arw2_options;
+  int sony_arw2_posterization_thr;
+  /* Nikon Coolscan */
+  float coolscan_nef_gamma;
 }libraw_output_params_t;
 
 typedef struct
 {
     /* really allocated bitmap */
-    void        *raw_alloc;
-    /* alias to single_channel variant */
-    ushort                      *raw_image;
-    /* alias to 4-channel variant */
-    ushort                      (*color_image)[4] ;
-    
-    /* Phase One black level data; */
-    short  (*ph1_black)[2];
-    int         use_ph1_correct;
-    /* save color and sizes here, too.... */
-    libraw_iparams_t  iparams;
-    libraw_image_sizes_t sizes;
-    libraw_internal_output_params_t ioparams;
-    libraw_colordata_t color;
+  void          *raw_alloc;
+  /* alias to single_channel variant */
+  ushort        *raw_image;
+  /* alias to 4-channel variant */
+  ushort        (*color4_image)[4] ;
+  /* alias to 3-color variand decoded by RawSpeed */
+  ushort        (*color3_image)[3];
+
+  /* Phase One black level data; */
+  short  (*ph1_cblack)[2];
+  short  (*ph1_rblack)[2];
+  /* save color and sizes here, too.... */
+  libraw_iparams_t  iparams;
+  libraw_image_sizes_t sizes;
+  libraw_internal_output_params_t ioparams;
+  libraw_colordata_t color;
 } libraw_rawdata_t;
 
+typedef struct
+{
+	unsigned long long LensID;
+	char	Lens[128];
+	ushort	LensFormat;		// to characterize the image circle the lens covers
+	ushort	LensMount;		// 'male', lens itself
+	unsigned long CamID;
+	ushort	CameraFormat;	// some of the sensor formats
+	ushort	CameraMount;	// 'female', body throat
+	char	body[64];
+	short	FocalType;		// -1/0 is unknown; 1 is fixed focal; 2 is zoom
+	char	LensFeatures_pre[16], LensFeatures_suf[16];
+	float	MinFocal, MaxFocal;
+	float	MaxAp4MinFocal, MaxAp4MaxFocal, MinAp4MinFocal, MinAp4MaxFocal;
+	float	MaxAp, MinAp;
+	float	CurFocal, CurAp;
+	float	MaxAp4CurFocal, MinAp4CurFocal;
+	float	LensFStops;
+	unsigned long long TeleconverterID;
+	char	Teleconverter[128];
+	unsigned long long AdapterID;
+	char	Adapter[128];
+	unsigned long long AttachmentID;
+	char	Attachment[128];
+	short CanonFocalUnits;
+	float	FocalLengthIn35mmFormat;
+} libraw_makernotes_lens_t;
+
+typedef struct
+{
+	float NikonEffectiveMaxAp;
+	uchar NikonLensIDNumber, NikonLensFStops, NikonMCUVersion, NikonLensType;
+} libraw_nikonlens_t;
+
+typedef struct
+{
+	float MinFocal, MaxFocal, MaxAp4MinFocal, MaxAp4MaxFocal;
+} libraw_dnglens_t;
+
+typedef struct
+{
+	float MinFocal, MaxFocal, MaxAp4MinFocal, MaxAp4MaxFocal, EXIF_MaxAp;
+	char LensMake[128], Lens[128];
+	ushort FocalLengthIn35mmFormat;
+	libraw_nikonlens_t nikon;
+	libraw_dnglens_t dng;
+	libraw_makernotes_lens_t makernotes;
+} libraw_lensinfo_t;
+
 
 typedef struct
 {
-    unsigned int                progress_flags;
-    unsigned int                process_warnings;
-    libraw_iparams_t            idata;
-    libraw_image_sizes_t        sizes;
-    libraw_colordata_t          color;
-    libraw_imgother_t           other;
-    libraw_thumbnail_t          thumbnail;
-    libraw_rawdata_t            rawdata;
-    ushort                      (*image)[4] ;
-    libraw_output_params_t     params;
-    void                *parent_class;      
+  ushort                      (*image)[4] ;
+  libraw_image_sizes_t        sizes;
+  libraw_iparams_t            idata;
+  libraw_lensinfo_t			  lens;
+  libraw_output_params_t		params;
+  unsigned int                progress_flags;
+  unsigned int                process_warnings;
+  libraw_colordata_t          color;
+  libraw_imgother_t           other;
+  libraw_thumbnail_t          thumbnail;
+  libraw_rawdata_t            rawdata;
+  void                *parent_class;
 } libraw_data_t;
 
 
diff --git a/Source/LibRawLite/libraw/libraw_version.h b/Source/LibRawLite/libraw/libraw_version.h
index e78a13b..2cc4ad1 100644
--- a/Source/LibRawLite/libraw/libraw_version.h
+++ b/Source/LibRawLite/libraw/libraw_version.h
@@ -1,6 +1,6 @@
 /* -*- C++ -*-
  * File: libraw_version.h
- * Copyright 2008-2010 LibRaw LLC (info at libraw.org)
+ * Copyright 2008-2013 LibRaw LLC (info at libraw.org)
  * Created: Mon Sept  8, 2008 
  *
  * LibRaw C++ interface
@@ -24,11 +24,11 @@ it under the terms of the one of three licenses as you choose:
 #define __VERSION_H
 
 #define LIBRAW_MAJOR_VERSION  0
-#define LIBRAW_MINOR_VERSION  14
-#define LIBRAW_PATCH_VERSION  7
-#define LIBRAW_VERSION_TAIL   Release
+#define LIBRAW_MINOR_VERSION  17
+#define LIBRAW_PATCH_VERSION  0
+#define LIBRAW_VERSION_TAIL   Alpha1
 
-#define LIBRAW_SHLIB_CURRENT  	5
+#define LIBRAW_SHLIB_CURRENT  	11
 #define LIBRAW_SHLIB_REVISION 	0
 #define LIBRAW_SHLIB_AGE     	0
 
diff --git a/Source/LibRawLite/src/libraw_c_api.cpp b/Source/LibRawLite/src/libraw_c_api.cpp
index aeb921d..4b443e8 100644
--- a/Source/LibRawLite/src/libraw_c_api.cpp
+++ b/Source/LibRawLite/src/libraw_c_api.cpp
@@ -1,6 +1,6 @@
 /* -*- C++ -*-
  * File: libraw_c_api.cpp
- * Copyright 2008-2010 LibRaw LLC (info at libraw.org)
+ * Copyright 2008-2013 LibRaw LLC (info at libraw.org)
  * Created: Sat Mar  8 , 2008
  *
  * LibRaw C interface 
@@ -68,12 +68,28 @@ extern "C"
         LibRaw *ip = (LibRaw*) lr->parent_class;
         return ip->open_file(file);
     }
+
     int libraw_open_file_ex(libraw_data_t* lr, const char *file,INT64 sz)
     {
         if(!lr) return EINVAL;
         LibRaw *ip = (LibRaw*) lr->parent_class;
         return ip->open_file(file,sz);
     }
+#if defined(_WIN32) && !defined(__MINGW32__) && defined(_MSC_VER) && (_MSC_VER > 1310)
+    int libraw_open_wfile(libraw_data_t* lr, const wchar_t *file)
+    {
+        if(!lr) return EINVAL;
+        LibRaw *ip = (LibRaw*) lr->parent_class;
+        return ip->open_file(file);
+    }
+
+    int libraw_open_wfile_ex(libraw_data_t* lr, const wchar_t *file,INT64 sz)
+    {
+        if(!lr) return EINVAL;
+        LibRaw *ip = (LibRaw*) lr->parent_class;
+        return ip->open_file(file,sz);
+    }
+#endif
     int libraw_open_buffer(libraw_data_t* lr, void *buffer, size_t size)
     {
         if(!lr) return EINVAL;
@@ -92,6 +108,12 @@ extern "C"
         LibRaw *ip = (LibRaw*) lr->parent_class;
         return ip->unpack_thumb();
     }
+	void libraw_recycle_datastream(libraw_data_t* lr)
+	{
+		if(!lr) return;
+		LibRaw *ip = (LibRaw*) lr->parent_class;
+		ip->recycle_datastream();
+	}
     void libraw_recycle(libraw_data_t* lr)
     {
         if(!lr) return;
@@ -105,6 +127,14 @@ extern "C"
         delete ip;
     }
 
+	void  libraw_set_exifparser_handler(libraw_data_t* lr, exif_parser_callback cb,void *data)
+	{
+		if(!lr) return;
+		LibRaw *ip = (LibRaw*) lr->parent_class;
+		ip->set_exifparser_handler(cb,data);
+
+	}
+
     void  libraw_set_memerror_handler(libraw_data_t* lr, memory_callback cb,void *data)
     {
         if(!lr) return;
@@ -134,13 +164,6 @@ extern "C"
         LibRaw *ip = (LibRaw*) lr->parent_class;
         return ip->adjust_sizes_info_only();
     }
-    int  libraw_dcraw_document_mode_processing(libraw_data_t* lr)
-    {
-        if(!lr) return EINVAL;
-        LibRaw *ip = (LibRaw*) lr->parent_class;
-        return ip->dcraw_document_mode_processing();
-
-    }
     int  libraw_dcraw_ppm_tiff_writer(libraw_data_t* lr,const char *filename)
     {
         if(!lr) return EINVAL;
@@ -196,6 +219,12 @@ extern "C"
         LibRaw *ip = (LibRaw*) lr->parent_class;
         return ip->get_decoder_info(d);
     }
+    int libraw_COLOR(libraw_data_t *lr, int row, int col)
+    {
+        if(!lr) return EINVAL;
+        LibRaw *ip = (LibRaw*) lr->parent_class;
+        return ip->COLOR(row,col);
+    }
 #ifdef __cplusplus
 }
 #endif
diff --git a/Source/LibRawLite/src/libraw_cxx.cpp b/Source/LibRawLite/src/libraw_cxx.cpp
index 89d5f04..7f5637b 100644
--- a/Source/LibRawLite/src/libraw_cxx.cpp
+++ b/Source/LibRawLite/src/libraw_cxx.cpp
@@ -1,6 +1,6 @@
 /* -*- C++ -*-
  * File: libraw_cxx.cpp
- * Copyright 2008-2010 LibRaw LLC (info at libraw.org)
+ * Copyright 2008-2013 LibRaw LLC (info at libraw.org)
  * Created: Sat Mar  8 , 2008
  *
  * LibRaw C++ interface (implementation)
@@ -35,66 +35,100 @@ it under the terms of the one of three licenses as you choose:
 #include "libraw/libraw.h"
 #include "internal/defines.h"
 
+
+#if defined(_WIN32)
+#if defined _MSC_VER
+typedef   signed __int8   int8_t;
+typedef unsigned __int8   uint8_t;
+typedef   signed __int16  int16_t;
+typedef unsigned __int16  uint16_t;
+typedef   signed __int32  int32_t;
+typedef unsigned __int32  uint32_t;
+typedef   signed __int64  int64_t;
+typedef unsigned __int64  uint64_t;
+#else
+#include <stdint.h>
+#endif // _WIN32
+#include <sys/types.h>
+#else
+#include <inttypes.h>
+#endif
+
+
+#ifdef USE_RAWSPEED
+#include "../RawSpeed/rawspeed_xmldata.cpp"
+#include <RawSpeed/StdAfx.h>
+#include <RawSpeed/FileMap.h>
+#include <RawSpeed/RawParser.h>
+#include <RawSpeed/RawDecoder.h>
+#include <RawSpeed/CameraMetaData.h>
+#include <RawSpeed/ColorFilterArray.h>
+#endif
+
+
 #ifdef __cplusplus
-extern "C" 
+extern "C"
 {
 #endif
-    void default_memory_callback(void *,const char *file,const char *where)
-    {
-        fprintf (stderr,"%s: Out of memory in %s\n", file?file:"unknown file", where);
-    }
-
-    void default_data_callback(void*,const char *file, const int offset)
-    {
-        if(offset < 0)
-            fprintf (stderr,"%s: Unexpected end of file\n", file?file:"unknown file");
-        else
-            fprintf (stderr,"%s: data corrupted at %d\n",file?file:"unknown file",offset); 
-    }
-    const char *libraw_strerror(int e)
-    {
-        enum LibRaw_errors errorcode = (LibRaw_errors)e;
-        switch(errorcode)
-            {
-            case        LIBRAW_SUCCESS:
-                return "No error";
-            case        LIBRAW_UNSPECIFIED_ERROR:
-                return "Unspecified error";
-            case        LIBRAW_FILE_UNSUPPORTED:
-                return "Unsupported file format or not RAW file";
-            case        LIBRAW_REQUEST_FOR_NONEXISTENT_IMAGE:
-                return "Request for nonexisting image number";
-            case        LIBRAW_OUT_OF_ORDER_CALL:
-                return "Out of order call of libraw function";
-            case    LIBRAW_NO_THUMBNAIL:
-                return "No thumbnail in file";
-            case    LIBRAW_UNSUPPORTED_THUMBNAIL:
-                return "Unsupported thumbnail format";
-            case    LIBRAW_UNSUFFICIENT_MEMORY:
-                return "Unsufficient memory";
-            case    LIBRAW_DATA_ERROR:
-                return "Corrupted data or unexpected EOF";
-            case    LIBRAW_IO_ERROR:
-                return "Input/output error";
-            case LIBRAW_CANCELLED_BY_CALLBACK:
-                return "Cancelled by user callback";
-            case LIBRAW_BAD_CROP:
-                return "Bad crop box";
-            default:
-                return "Unknown error code";
-        }
-    }
+  void default_memory_callback(void *,const char *file,const char *where)
+  {
+    fprintf (stderr,"%s: Out of memory in %s\n", file?file:"unknown file", where);
+  }
+
+  void default_data_callback(void*,const char *file, const int offset)
+  {
+    if(offset < 0)
+      fprintf (stderr,"%s: Unexpected end of file\n", file?file:"unknown file");
+    else
+      fprintf (stderr,"%s: data corrupted at %d\n",file?file:"unknown file",offset);
+  }
+  const char *libraw_strerror(int e)
+  {
+    enum LibRaw_errors errorcode = (LibRaw_errors)e;
+    switch(errorcode)
+      {
+      case        LIBRAW_SUCCESS:
+        return "No error";
+      case        LIBRAW_UNSPECIFIED_ERROR:
+        return "Unspecified error";
+      case        LIBRAW_FILE_UNSUPPORTED:
+        return "Unsupported file format or not RAW file";
+      case        LIBRAW_REQUEST_FOR_NONEXISTENT_IMAGE:
+        return "Request for nonexisting image number";
+      case        LIBRAW_OUT_OF_ORDER_CALL:
+        return "Out of order call of libraw function";
+      case    LIBRAW_NO_THUMBNAIL:
+        return "No thumbnail in file";
+      case    LIBRAW_UNSUPPORTED_THUMBNAIL:
+        return "Unsupported thumbnail format";
+      case LIBRAW_INPUT_CLOSED:
+        return "No input stream, or input stream closed";
+      case    LIBRAW_UNSUFFICIENT_MEMORY:
+        return "Unsufficient memory";
+      case    LIBRAW_DATA_ERROR:
+        return "Corrupted data or unexpected EOF";
+      case    LIBRAW_IO_ERROR:
+        return "Input/output error";
+      case LIBRAW_CANCELLED_BY_CALLBACK:
+        return "Cancelled by user callback";
+      case LIBRAW_BAD_CROP:
+        return "Bad crop box";
+      default:
+        return "Unknown error code";
+      }
+  }
 
 #ifdef __cplusplus
 }
 #endif
 
+#define Sigma_X3F   22
 
-const double LibRaw_constants::xyz_rgb[3][3] = 
+const double LibRaw_constants::xyz_rgb[3][3] =
 {
     { 0.412453, 0.357580, 0.180423 },
     { 0.212671, 0.715160, 0.072169 },
-    { 0.019334, 0.119193, 0.950227 } 
+    { 0.019334, 0.119193, 0.950227 }
 };
 
 const float LibRaw_constants::d65_white[3] =  { 0.950456f, 1.0f, 1.088754f };
@@ -108,58 +142,66 @@ const float LibRaw_constants::d65_white[3] =  { 0.950456f, 1.0f, 1.088754f };
 #define ID libraw_internal_data.internal_data
 
 #define EXCEPTION_HANDLER(e) do{                        \
-        /* fprintf(stderr,"Exception %d caught\n",e);*/ \
-        switch(e)                                       \
-            {                                           \
-            case LIBRAW_EXCEPTION_ALLOC:                \
-                recycle();                              \
-                return LIBRAW_UNSUFFICIENT_MEMORY;      \
-            case LIBRAW_EXCEPTION_DECODE_RAW:           \
-            case LIBRAW_EXCEPTION_DECODE_JPEG:          \
-                recycle();                              \
-                return LIBRAW_DATA_ERROR;               \
-            case LIBRAW_EXCEPTION_DECODE_JPEG2000:      \
-                recycle();                              \
-                return LIBRAW_DATA_ERROR;               \
-            case LIBRAW_EXCEPTION_IO_EOF:               \
-            case LIBRAW_EXCEPTION_IO_CORRUPT:           \
-                recycle();                              \
-                return LIBRAW_IO_ERROR;                 \
-            case LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK:\
-                recycle();                              \
-                return LIBRAW_CANCELLED_BY_CALLBACK;    \
-            case LIBRAW_EXCEPTION_BAD_CROP:             \
-                recycle();                              \
-                return LIBRAW_BAD_CROP;                 \
-            default:                                    \
-                return LIBRAW_UNSPECIFIED_ERROR;        \
-            } \
-    }while(0)
+    /* fprintf(stderr,"Exception %d caught\n",e);*/     \
+    switch(e)                                           \
+      {                                                 \
+      case LIBRAW_EXCEPTION_ALLOC:                      \
+        recycle();                                      \
+        return LIBRAW_UNSUFFICIENT_MEMORY;              \
+      case LIBRAW_EXCEPTION_DECODE_RAW:                 \
+      case LIBRAW_EXCEPTION_DECODE_JPEG:                \
+        recycle();                                      \
+        return LIBRAW_DATA_ERROR;                       \
+      case LIBRAW_EXCEPTION_DECODE_JPEG2000:            \
+        recycle();                                      \
+        return LIBRAW_DATA_ERROR;                       \
+      case LIBRAW_EXCEPTION_IO_EOF:                     \
+      case LIBRAW_EXCEPTION_IO_CORRUPT:                 \
+        recycle();                                      \
+        return LIBRAW_IO_ERROR;                                 \
+      case LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK:              \
+        recycle();                                              \
+        return LIBRAW_CANCELLED_BY_CALLBACK;                    \
+      case LIBRAW_EXCEPTION_BAD_CROP:                           \
+        recycle();                                              \
+        return LIBRAW_BAD_CROP;                                 \
+      default:                                                  \
+        return LIBRAW_UNSPECIFIED_ERROR;                        \
+      }                                                         \
+  }while(0)
 
 const char* LibRaw::version() { return LIBRAW_VERSION_STR;}
 int LibRaw::versionNumber() { return LIBRAW_VERSION; }
 const char* LibRaw::strerror(int p) { return libraw_strerror(p);}
 
+LibRaw_colormatrix_type LibRaw::camera_color_type()
+{
+  if(C.cmatrix[0][0] <= 0.125) return LIBRAW_CMATRIX_NONE;
+  if(P1.dng_version) return LIBRAW_CMATRIX_DNG;
+  if(C.digitalBack_color) return LIBRAW_CMATRIX_DIGBACK;
+  return LIBRAW_CMATRIX_OTHER;
+
+}
 
 void LibRaw::derror()
 {
-    if (!libraw_internal_data.unpacker_data.data_error && libraw_internal_data.internal_data.input) 
+  if (!libraw_internal_data.unpacker_data.data_error && libraw_internal_data.internal_data.input)
+    {
+      if (libraw_internal_data.internal_data.input->eof())
         {
-            if (libraw_internal_data.internal_data.input->eof())
-                {
-                    if(callbacks.data_cb)(*callbacks.data_cb)(callbacks.datacb_data,
-                                                              libraw_internal_data.internal_data.input->fname(),-1);
-                    throw LIBRAW_EXCEPTION_IO_EOF;
-                }
-            else
-                {
-                    if(callbacks.data_cb)(*callbacks.data_cb)(callbacks.datacb_data,
-                                                              libraw_internal_data.internal_data.input->fname(),
-                                                              libraw_internal_data.internal_data.input->tell());
-                    throw LIBRAW_EXCEPTION_IO_CORRUPT;
-                }
+          if(callbacks.data_cb)(*callbacks.data_cb)(callbacks.datacb_data,
+                                                    libraw_internal_data.internal_data.input->fname(),-1);
+          throw LIBRAW_EXCEPTION_IO_EOF;
         }
-    libraw_internal_data.unpacker_data.data_error++;
+      else
+        {
+          if(callbacks.data_cb)(*callbacks.data_cb)(callbacks.datacb_data,
+                                                    libraw_internal_data.internal_data.input->fname(),
+                                                    libraw_internal_data.internal_data.input->tell());
+          //throw LIBRAW_EXCEPTION_IO_CORRUPT;
+        }
+    }
+  libraw_internal_data.unpacker_data.data_error++;
 }
 
 void LibRaw::dcraw_clear_mem(libraw_processed_image_t* p)
@@ -167,58 +209,234 @@ void LibRaw::dcraw_clear_mem(libraw_processed_image_t* p)
     if(p) ::free(p);
 }
 
+int LibRaw::is_sraw() { return load_raw == &LibRaw::canon_sraw_load_raw || load_raw == &LibRaw::nikon_load_sraw ; }
+int LibRaw::is_coolscan_nef() { return load_raw == &LibRaw::nikon_coolscan_load_raw;}
+
+int LibRaw::is_nikon_sraw(){
+  return load_raw == &LibRaw::nikon_load_sraw;
+}
+int LibRaw::sraw_midpoint() {
+  if (load_raw == &LibRaw::canon_sraw_load_raw) return 8192;
+  else if (load_raw == &LibRaw::nikon_load_sraw) return 2048;
+  else return 0;
+}
+
+
+#ifdef USE_RAWSPEED
+using namespace RawSpeed;
+class CameraMetaDataLR : public CameraMetaData
+{
+public:
+  CameraMetaDataLR() : CameraMetaData() {}
+  CameraMetaDataLR(char *filename) : CameraMetaData(filename){}
+  CameraMetaDataLR(char *data, int sz);
+};
+
+CameraMetaDataLR::CameraMetaDataLR(char *data, int sz) : CameraMetaData() {
+  ctxt = xmlNewParserCtxt();
+  if (ctxt == NULL) {
+    ThrowCME("CameraMetaData:Could not initialize context.");
+  }
+
+  xmlResetLastError();
+  doc = xmlCtxtReadMemory(ctxt, data,sz, "", NULL, XML_PARSE_DTDVALID);
+
+  if (doc == NULL) {
+    ThrowCME("CameraMetaData: XML Document could not be parsed successfully. Error was: %s", ctxt->lastError.message);
+  }
+
+  if (ctxt->valid == 0) {
+    if (ctxt->lastError.code == 0x5e) {
+      // printf("CameraMetaData: Unable to locate DTD, attempting to ignore.");
+    } else {
+      ThrowCME("CameraMetaData: XML file does not validate. DTD Error was: %s", ctxt->lastError.message);
+    }
+  }
+
+  xmlNodePtr cur;
+  cur = xmlDocGetRootElement(doc);
+  if (xmlStrcmp(cur->name, (const xmlChar *) "Cameras")) {
+    ThrowCME("CameraMetaData: XML document of the wrong type, root node is not cameras.");
+    return;
+  }
+
+  cur = cur->xmlChildrenNode;
+  while (cur != NULL) {
+    if ((!xmlStrcmp(cur->name, (const xmlChar *)"Camera"))) {
+      Camera *camera = new Camera(doc, cur);
+      addCamera(camera);
+
+      // Create cameras for aliases.
+      for (unsigned int i = 0; i < camera->aliases.size(); i++) {
+        addCamera(new Camera(camera, i));
+      }
+    }
+    cur = cur->next;
+  }
+  if (doc)
+    xmlFreeDoc(doc);
+  doc = 0;
+  if (ctxt)
+    xmlFreeParserCtxt(ctxt);
+  ctxt = 0;
+}
+
+#define RAWSPEED_DATA_COUNT (sizeof(_rawspeed_data_xml)/sizeof(_rawspeed_data_xml[0]))
+static CameraMetaDataLR* make_camera_metadata()
+{
+  int len = 0,i;
+  for(i=0;i<RAWSPEED_DATA_COUNT;i++)
+    if(_rawspeed_data_xml[i])
+      {
+        len+=strlen(_rawspeed_data_xml[i]);
+      }
+  char *rawspeed_xml = (char*)calloc(len+1,sizeof(_rawspeed_data_xml[0][0]));
+  if(!rawspeed_xml) return NULL;
+  int offt = 0;
+  for(i=0;i<RAWSPEED_DATA_COUNT;i++)
+    if(_rawspeed_data_xml[i])
+      {
+        int ll = strlen(_rawspeed_data_xml[i]);
+        if(offt+ll>len) break;
+        memmove(rawspeed_xml+offt,_rawspeed_data_xml[i],ll);
+        offt+=ll;
+      }
+  rawspeed_xml[offt]=0;
+  CameraMetaDataLR *ret=NULL;
+  try {
+    ret = new CameraMetaDataLR(rawspeed_xml,offt);
+  } catch (...) {
+    // Mask all exceptions
+  }
+  free(rawspeed_xml);
+  return ret;
+}
+
+#endif
+
 #define ZERO(a) memset(&a,0,sizeof(a))
 
+static void cleargps(libraw_gps_info_t*q)
+{
+	for (int i = 0; i < 3; i++)
+		q->latitude[i] = q->longtitude[i] = q->gpstimestamp[i] = 0.f;
+	q->altitude = 0.f;
+	q->altref = q->latref = q->longref = q->gpsstatus = q->gpsparsed = 0;
+}
 
 LibRaw:: LibRaw(unsigned int flags)
 {
-    double aber[4] = {1,1,1,1};
-    double gamm[6] = { 0.45,4.5,0,0,0,0 };
-    unsigned greybox[4] =  { 0, 0, UINT_MAX, UINT_MAX };
-    unsigned cropbox[4] =  { 0, 0, UINT_MAX, UINT_MAX };
+  double aber[4] = {1,1,1,1};
+  double gamm[6] = { 0.45,4.5,0,0,0,0 };
+  unsigned greybox[4] =  { 0, 0, UINT_MAX, UINT_MAX };
+  unsigned cropbox[4] =  { 0, 0, UINT_MAX, UINT_MAX };
 #ifdef DCRAW_VERBOSE
-    verbose = 1;
+  verbose = 1;
 #else
-    verbose = 0;
+  verbose = 0;
+#endif
+  ZERO(imgdata);
+  imgdata.lens.makernotes.CanonFocalUnits = 1;
+  imgdata.lens.makernotes.LensID = 0xffffffffffffffffULL;
+
+  cleargps(&imgdata.other.parsed_gps);
+  ZERO(libraw_internal_data);
+  ZERO(callbacks);
+
+  _rawspeed_camerameta = _rawspeed_decoder = NULL;
+  _x3f_data = NULL;
+
+#ifdef USE_RAWSPEED
+  CameraMetaDataLR *camerameta = make_camera_metadata(); // May be NULL in case of exception in make_camera_metadata()
+  _rawspeed_camerameta = static_cast<void*>(camerameta);
+#endif
+  callbacks.mem_cb = (flags & LIBRAW_OPIONS_NO_MEMERR_CALLBACK) ? NULL:  &default_memory_callback;
+  callbacks.data_cb = (flags & LIBRAW_OPIONS_NO_DATAERR_CALLBACK)? NULL : &default_data_callback;
+  callbacks.exif_cb = NULL; // no default callback
+  memmove(&imgdata.params.aber,&aber,sizeof(aber));
+  memmove(&imgdata.params.gamm,&gamm,sizeof(gamm));
+  memmove(&imgdata.params.greybox,&greybox,sizeof(greybox));
+  memmove(&imgdata.params.cropbox,&cropbox,sizeof(cropbox));
+
+  imgdata.params.bright=1;
+  imgdata.params.use_camera_matrix=1;
+  imgdata.params.user_flip=-1;
+  imgdata.params.user_black=-1;
+  imgdata.params.user_cblack[0]=imgdata.params.user_cblack[1]=imgdata.params.user_cblack[2]=imgdata.params.user_cblack[3]=-1000001;
+  imgdata.params.user_sat=-1;
+  imgdata.params.user_qual=-1;
+  imgdata.params.output_color=1;
+  imgdata.params.output_bps=8;
+  imgdata.params.use_fuji_rotate=1;
+  imgdata.params.exp_shift = 1.0;
+  imgdata.params.auto_bright_thr = LIBRAW_DEFAULT_AUTO_BRIGHTNESS_THRESHOLD;
+  imgdata.params.adjust_maximum_thr= LIBRAW_DEFAULT_ADJUST_MAXIMUM_THRESHOLD;
+  imgdata.params.use_rawspeed = 1;
+  imgdata.params.no_auto_scale = 0;
+  imgdata.params.no_interpolation = 0;
+  imgdata.params.sraw_ycc = 0;
+  imgdata.params.force_foveon_x3f = 0;
+  imgdata.params.x3f_flags = LIBRAW_DP2Q_INTERPOLATERG|LIBRAW_DP2Q_INTERPOLATEAF;
+  imgdata.params.sony_arw2_options = 0;
+  imgdata.params.sony_arw2_posterization_thr = 0;
+  imgdata.params.green_matching = 0;
+  imgdata.params.coolscan_nef_gamma = 1.0f;
+  imgdata.parent_class = this;
+  imgdata.progress_flags = 0;
+  imgdata.color.baseline_exposure = -999.f;
+  _exitflag = 0;
+  tls = new LibRaw_TLS;
+  tls->init();
+}
+
+int LibRaw::set_rawspeed_camerafile(char *filename)
+{
+#ifdef USE_RAWSPEED
+  try
+    {
+      CameraMetaDataLR *camerameta = new CameraMetaDataLR(filename);
+      if(_rawspeed_camerameta)
+        {
+          CameraMetaDataLR *d = static_cast<CameraMetaDataLR*>(_rawspeed_camerameta);
+          delete d;
+        }
+      _rawspeed_camerameta = static_cast<void*>(camerameta);
+    }
+  catch (...)
+    {
+      //just return error code
+      return -1;
+    }
 #endif
-    ZERO(imgdata);
-    ZERO(libraw_internal_data);
-    ZERO(callbacks);
-    callbacks.mem_cb = (flags & LIBRAW_OPIONS_NO_MEMERR_CALLBACK) ? NULL:  &default_memory_callback;
-    callbacks.data_cb = (flags & LIBRAW_OPIONS_NO_DATAERR_CALLBACK)? NULL : &default_data_callback;
-    memmove(&imgdata.params.aber,&aber,sizeof(aber));
-    memmove(&imgdata.params.gamm,&gamm,sizeof(gamm));
-    memmove(&imgdata.params.greybox,&greybox,sizeof(greybox));
-    memmove(&imgdata.params.cropbox,&cropbox,sizeof(cropbox));
-    
-    imgdata.params.bright=1;
-    imgdata.params.use_camera_matrix=-1;
-    imgdata.params.user_flip=-1;
-    imgdata.params.user_black=-1;
-    imgdata.params.user_sat=-1;
-    imgdata.params.user_qual=-1;
-    imgdata.params.output_color=1;
-    imgdata.params.output_bps=8;
-    imgdata.params.use_fuji_rotate=1;
-    imgdata.params.exp_shift = 1.0;
-    imgdata.params.auto_bright_thr = LIBRAW_DEFAULT_AUTO_BRIGHTNESS_THRESHOLD;
-    imgdata.params.adjust_maximum_thr= LIBRAW_DEFAULT_ADJUST_MAXIMUM_THRESHOLD;
-    imgdata.params.green_matching = 0;
-    imgdata.parent_class = this;
-    imgdata.progress_flags = 0;
-    tls = new LibRaw_TLS;
-    tls->init();
+  return 0;
 }
 
+LibRaw::~LibRaw()
+{
+  recycle();
+  delete tls;
+#ifdef USE_RAWSPEED
+  if(_rawspeed_camerameta)
+    {
+      CameraMetaDataLR *cmeta = static_cast<CameraMetaDataLR*>(_rawspeed_camerameta);
+      delete cmeta;
+      _rawspeed_camerameta = NULL;
+    }
+#endif
+}
 
 void* LibRaw:: malloc(size_t t)
 {
     void *p = memmgr.malloc(t);
+	if(!p)
+		throw LIBRAW_EXCEPTION_ALLOC;
     return p;
 }
 void* LibRaw:: realloc(void *q,size_t t)
 {
     void *p = memmgr.realloc(q,t);
+	if(!p)
+		throw LIBRAW_EXCEPTION_ALLOC;
     return p;
 }
 
@@ -226,6 +444,8 @@ void* LibRaw:: realloc(void *q,size_t t)
 void* LibRaw::       calloc(size_t n,size_t t)
 {
     void *p = memmgr.calloc(n,t);
+	if(!p)
+		throw LIBRAW_EXCEPTION_ALLOC;
     return p;
 }
 void  LibRaw::      free(void *p)
@@ -233,305 +453,343 @@ void  LibRaw::      free(void *p)
     memmgr.free(p);
 }
 
+void LibRaw:: recycle_datastream()
+{
+  if(libraw_internal_data.internal_data.input && libraw_internal_data.internal_data.input_internal)
+    {
+      delete libraw_internal_data.internal_data.input;
+      libraw_internal_data.internal_data.input = NULL;
+    }
+  libraw_internal_data.internal_data.input_internal = 0;
+}
 
-int LibRaw:: fc (int row, int col)
-{
-    static const char filter[16][16] =
-        { { 2,1,1,3,2,3,2,0,3,2,3,0,1,2,1,0 },
-          { 0,3,0,2,0,1,3,1,0,1,1,2,0,3,3,2 },
-          { 2,3,3,2,3,1,1,3,3,1,2,1,2,0,0,3 },
-          { 0,1,0,1,0,2,0,2,2,0,3,0,1,3,2,1 },
-          { 3,1,1,2,0,1,0,2,1,3,1,3,0,1,3,0 },
-          { 2,0,0,3,3,2,3,1,2,0,2,0,3,2,2,1 },
-          { 2,3,3,1,2,1,2,1,2,1,1,2,3,0,0,1 },
-          { 1,0,0,2,3,0,0,3,0,3,0,3,2,1,2,3 },
-          { 2,3,3,1,1,2,1,0,3,2,3,0,2,3,1,3 },
-          { 1,0,2,0,3,0,3,2,0,1,1,2,0,1,0,2 },
-          { 0,1,1,3,3,2,2,1,1,3,3,0,2,1,3,2 },
-          { 2,3,2,0,0,1,3,0,2,0,1,2,3,0,1,0 },
-          { 1,3,1,2,3,2,3,2,0,2,0,1,1,0,3,0 },
-          { 0,2,0,3,1,0,0,1,1,3,3,2,3,2,2,1 },
-          { 2,1,3,2,3,1,2,1,0,3,0,2,0,2,0,2 },
-          { 0,3,1,0,0,2,0,3,2,1,3,1,1,3,1,3 } };
-    
-    if (imgdata.idata.filters != 1) return FC(row,col);
-    return filter[(row+imgdata.sizes.top_margin) & 15][(col+imgdata.sizes.left_margin) & 15];
-}
-
-void LibRaw:: recycle() 
-{
-    if(libraw_internal_data.internal_data.input && libraw_internal_data.internal_data.input_internal) 
-        { 
-            delete libraw_internal_data.internal_data.input; 
-            libraw_internal_data.internal_data.input = NULL;
-        }
-    libraw_internal_data.internal_data.input_internal = 0;
+void x3f_clear(void*);
+
+
+void LibRaw:: recycle()
+{
+  recycle_datastream();
 #define FREE(a) do { if(a) { free(a); a = NULL;} }while(0)
-            
-    FREE(imgdata.image); 
-    FREE(imgdata.thumbnail.thumb);
-    FREE(libraw_internal_data.internal_data.meta_data);
-    FREE(libraw_internal_data.output_data.histogram);
-    FREE(libraw_internal_data.output_data.oprof);
-    FREE(imgdata.color.profile);
-    FREE(imgdata.rawdata.ph1_black);
-    FREE(imgdata.rawdata.raw_alloc); 
+
+  FREE(imgdata.image);
+  FREE(imgdata.thumbnail.thumb);
+  FREE(libraw_internal_data.internal_data.meta_data);
+  FREE(libraw_internal_data.output_data.histogram);
+  FREE(libraw_internal_data.output_data.oprof);
+  FREE(imgdata.color.profile);
+  FREE(imgdata.rawdata.ph1_cblack);
+  FREE(imgdata.rawdata.ph1_rblack);
+  FREE(imgdata.rawdata.raw_alloc);
+  FREE(imgdata.idata.xmpdata);
 #undef FREE
-    ZERO(imgdata.rawdata);
-    ZERO(imgdata.sizes);
-    ZERO(imgdata.color);
-    ZERO(libraw_internal_data);
-    memmgr.cleanup();
-    imgdata.thumbnail.tformat = LIBRAW_THUMBNAIL_UNKNOWN;
-    imgdata.progress_flags = 0;
-    
-    tls->init();
+  ZERO(imgdata.rawdata);
+  ZERO(imgdata.sizes);
+  ZERO(imgdata.color);
+  cleargps(&imgdata.other.parsed_gps);
+  imgdata.color.baseline_exposure = -999.f;
+  ZERO(libraw_internal_data);
+  ZERO(imgdata.lens);
+  imgdata.lens.makernotes.CanonFocalUnits = 1;
+  imgdata.lens.makernotes.LensID = 0xffffffffffffffffULL;
+
+  _exitflag = 0;
+#ifdef USE_RAWSPEED
+  if(_rawspeed_decoder)
+    {
+      RawDecoder *d = static_cast<RawDecoder*>(_rawspeed_decoder);
+      delete d;
+    }
+  _rawspeed_decoder = 0;
+#endif
+  if(_x3f_data)
+    {
+      x3f_clear(_x3f_data);
+      _x3f_data = 0;
+    }
+
+  memmgr.cleanup();
+  imgdata.thumbnail.tformat = LIBRAW_THUMBNAIL_UNKNOWN;
+  imgdata.progress_flags = 0;
+
+  tls->init();
 }
 
 const char * LibRaw::unpack_function_name()
 {
-    libraw_decoder_info_t decoder_info;
-    get_decoder_info(&decoder_info);
-    return decoder_info.decoder_name;
+  libraw_decoder_info_t decoder_info;
+  get_decoder_info(&decoder_info);
+  return decoder_info.decoder_name;
 }
 
 int LibRaw::get_decoder_info(libraw_decoder_info_t* d_info)
 {
-    if(!d_info)   return LIBRAW_UNSPECIFIED_ERROR;
-    if(!load_raw) return LIBRAW_OUT_OF_ORDER_CALL;
-    
-    d_info->decoder_flags = LIBRAW_DECODER_NOTSET;
+  if(!d_info)   return LIBRAW_UNSPECIFIED_ERROR;
+  if(!load_raw) return LIBRAW_OUT_OF_ORDER_CALL;
+
+  d_info->decoder_flags = 0;
+  int rawdata = (imgdata.idata.filters || P1.colors == 1);
+  // dcraw.c names order
+  if (load_raw == &LibRaw::android_tight_load_raw)
+  {
+	  d_info->decoder_name = "android_tight_load_raw()";
+  }
+  else if (load_raw == &LibRaw::android_loose_load_raw)
+  {
+	  d_info->decoder_name = "android_loose_load_raw()";
+  }
+  else if (load_raw == &LibRaw::canon_600_load_raw)
+    {
+      d_info->decoder_name = "canon_600_load_raw()";
+    }
+  else if (load_raw == &LibRaw::canon_load_raw)
+    {
+      d_info->decoder_name = "canon_load_raw()";
+    }
+  else if (load_raw == &LibRaw::lossless_jpeg_load_raw)
+    {
+      // Check rbayer
+      d_info->decoder_name = "lossless_jpeg_load_raw()";
+      d_info->decoder_flags = LIBRAW_DECODER_HASCURVE | LIBRAW_DECODER_TRYRAWSPEED;
+    }
+  else if (load_raw == &LibRaw::canon_sraw_load_raw)
+    {
+      d_info->decoder_name = "canon_sraw_load_raw()";
+      d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED;
+    }
+  else if (load_raw == &LibRaw::lossless_dng_load_raw)
+    {
+      // Check rbayer
+      d_info->decoder_name = "lossless_dng_load_raw()";
+      d_info->decoder_flags = LIBRAW_DECODER_HASCURVE | LIBRAW_DECODER_TRYRAWSPEED;
+    }
+  else if (load_raw == &LibRaw::packed_dng_load_raw)
+    {
+      // Check rbayer
+      d_info->decoder_name = "packed_dng_load_raw()";
+      d_info->decoder_flags = LIBRAW_DECODER_HASCURVE | LIBRAW_DECODER_TRYRAWSPEED;
+    }
+  else if (load_raw == &LibRaw::pentax_load_raw )
+    {
+      d_info->decoder_name = "pentax_load_raw()";
+      d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED;
+    }
+  else if (load_raw == &LibRaw::nikon_load_raw)
+    {
+      // Check rbayer
+      d_info->decoder_name = "nikon_load_raw()";
+      d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED;
+    }
+  else if (load_raw == &LibRaw::nikon_coolscan_load_raw )
+  {
+	  d_info->decoder_name = "nikon_coolscan_load_raw()";
+	  d_info->decoder_flags = LIBRAW_DECODER_FIXEDMAXC;
+  }
+  else if (load_raw == &LibRaw::nikon_load_sraw )
+    {
+      d_info->decoder_name = "nikon_load_sraw()";
+      d_info->decoder_flags = LIBRAW_DECODER_HASCURVE | LIBRAW_DECODER_FIXEDMAXC;
+    }
+  else if (load_raw == &LibRaw::nikon_yuv_load_raw )
+    {
+      d_info->decoder_name = "nikon_load_sraw()";
+      d_info->decoder_flags = LIBRAW_DECODER_HASCURVE;
+    }
+  else if (load_raw == &LibRaw::rollei_load_raw )
+    {
+      // UNTESTED
+      d_info->decoder_name = "rollei_load_raw()";
+    }
+  else if (load_raw == &LibRaw::phase_one_load_raw )
+    {
+      d_info->decoder_name = "phase_one_load_raw()";
+    }
+  else if (load_raw == &LibRaw::phase_one_load_raw_c )
+    {
+      d_info->decoder_name = "phase_one_load_raw_c()";
+    }
+  else if (load_raw == &LibRaw::hasselblad_load_raw )
+    {
+      d_info->decoder_name = "hasselblad_load_raw()";
+    }
+  else if (load_raw == &LibRaw::leaf_hdr_load_raw )
+    {
+      d_info->decoder_name = "leaf_hdr_load_raw()";
+    }
+  else if (load_raw == &LibRaw::unpacked_load_raw )
+    {
+      d_info->decoder_name = "unpacked_load_raw()";
+    }
+  else if (load_raw == &LibRaw::sinar_4shot_load_raw )
+    {
+      // UNTESTED
+      d_info->decoder_name = "sinar_4shot_load_raw()";
+    }
+  else if (load_raw == &LibRaw::imacon_full_load_raw )
+    {
+      d_info->decoder_name = "imacon_full_load_raw()";
+    }
+  else if (load_raw == &LibRaw::hasselblad_full_load_raw )
+    {
+      d_info->decoder_name = "hasselblad_full_load_raw()";
+    }
+  else if (load_raw == &LibRaw::packed_load_raw )
+    {
+      d_info->decoder_name = "packed_load_raw()";
+      d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED;
+    }
+  else if (load_raw == &LibRaw::nokia_load_raw )
+    {
+      // UNTESTED
+      d_info->decoder_name = "nokia_load_raw()";
+    }
+  else if (load_raw == &LibRaw::canon_rmf_load_raw )
+    {
+      // UNTESTED
+      d_info->decoder_name = "canon_rmf_load_raw()";
+    }
+  else if (load_raw == &LibRaw::panasonic_load_raw )
+    {
+      d_info->decoder_name = "panasonic_load_raw()";
+      d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED;
+    }
+  else if (load_raw == &LibRaw::olympus_load_raw )
+    {
+      d_info->decoder_name = "olympus_load_raw()";
+      d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED;
+    }
+  else if (load_raw == &LibRaw::minolta_rd175_load_raw )
+    {
+      // UNTESTED
+      d_info->decoder_name = "minolta_rd175_load_raw()";
+    }
+  else if (load_raw == &LibRaw::quicktake_100_load_raw )
+    {
+      // UNTESTED
+      d_info->decoder_name = "quicktake_100_load_raw()";
+    }
+  else if (load_raw == &LibRaw::kodak_radc_load_raw )
+    {
+      d_info->decoder_name = "kodak_radc_load_raw()";
+    }
+  else if (load_raw == &LibRaw::kodak_jpeg_load_raw )
+    {
+      // UNTESTED + RBAYER
+      d_info->decoder_name = "kodak_jpeg_load_raw()";
+    }
+  else if (load_raw == &LibRaw::lossy_dng_load_raw)
+    {
+      // Check rbayer
+      d_info->decoder_name = "lossy_dng_load_raw()";
+      d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED | LIBRAW_DECODER_HASCURVE;
+    }
+  else if (load_raw == &LibRaw::kodak_dc120_load_raw )
+    {
+      d_info->decoder_name = "kodak_dc120_load_raw()";
+    }
+  else if (load_raw == &LibRaw::eight_bit_load_raw )
+    {
+      d_info->decoder_name = "eight_bit_load_raw()";
+      d_info->decoder_flags = LIBRAW_DECODER_HASCURVE;
+    }
+  else if (load_raw == &LibRaw::kodak_c330_load_raw )
+    {
+      d_info->decoder_name = "kodak_yrgb_load_raw()";
+      d_info->decoder_flags = LIBRAW_DECODER_HASCURVE;
+    }
+  else if (load_raw == &LibRaw::kodak_c603_load_raw )
+    {
+      d_info->decoder_name = "kodak_yrgb_load_raw()";
+      d_info->decoder_flags = LIBRAW_DECODER_HASCURVE;
+    }
+  else if (load_raw == &LibRaw::kodak_262_load_raw )
+    {
+      d_info->decoder_name = "kodak_262_load_raw()"; // UNTESTED!
+      d_info->decoder_flags = LIBRAW_DECODER_HASCURVE;
+    }
+  else if (load_raw == &LibRaw::kodak_65000_load_raw )
+    {
+      d_info->decoder_name = "kodak_65000_load_raw()";
+      d_info->decoder_flags = LIBRAW_DECODER_HASCURVE;
+    }
+  else if (load_raw == &LibRaw::kodak_ycbcr_load_raw )
+    {
+      // UNTESTED
+      d_info->decoder_name = "kodak_ycbcr_load_raw()";
+      d_info->decoder_flags = LIBRAW_DECODER_HASCURVE;
+    }
+  else if (load_raw == &LibRaw::kodak_rgb_load_raw )
+    {
+      // UNTESTED
+      d_info->decoder_name = "kodak_rgb_load_raw()";
+    }
+  else if (load_raw == &LibRaw::sony_load_raw )
+    {
+      d_info->decoder_name = "sony_load_raw()";
+    }
+  else if (load_raw == &LibRaw::sony_arw_load_raw )
+    {
+      d_info->decoder_name = "sony_arw_load_raw()";
+      d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED;
 
-    // sorted names order
-    if (load_raw == &LibRaw::adobe_dng_load_raw_lj) 
-        {
-            // Check rbayer
-            d_info->decoder_name = "adobe_dng_load_raw_lj()"; 
-            d_info->decoder_flags = imgdata.idata.filters ? LIBRAW_DECODER_FLATFIELD : LIBRAW_DECODER_4COMPONENT ;
-            d_info->decoder_flags |= LIBRAW_DECODER_HASCURVE;
-        }
-    else if (load_raw == &LibRaw::adobe_dng_load_raw_nc)
-        {
-            // Check rbayer
-            d_info->decoder_name = "adobe_dng_load_raw_nc()"; 
-            d_info->decoder_flags = imgdata.idata.filters ? LIBRAW_DECODER_FLATFIELD : LIBRAW_DECODER_4COMPONENT;
-            d_info->decoder_flags |= LIBRAW_DECODER_HASCURVE;
-        }
-    else if (load_raw == &LibRaw::canon_600_load_raw) 
-        {
-            d_info->decoder_name = "canon_600_load_raw()";   
-            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD; // WB set within decoder, no need to load raw
-        }
-    else if (load_raw == &LibRaw::canon_compressed_load_raw)
-        {
-            d_info->decoder_name = "canon_compressed_load_raw()"; 
-            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
-        }
-    else if (load_raw == &LibRaw::canon_sraw_load_raw) 
-        {
-            d_info->decoder_name = "canon_sraw_load_raw()";
-            d_info->decoder_flags = LIBRAW_DECODER_LEGACY; 
-        }
-    else if (load_raw == &LibRaw::eight_bit_load_raw )
-        {
-            d_info->decoder_name = "eight_bit_load_raw()";
-            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
-            d_info->decoder_flags |= LIBRAW_DECODER_HASCURVE;
-        }
-    else if (load_raw == &LibRaw::foveon_load_raw )
-        {
-            d_info->decoder_name = "foveon_load_raw()";
-            d_info->decoder_flags = LIBRAW_DECODER_LEGACY; 
-        }
-    else if (load_raw == &LibRaw::fuji_load_raw ) 
-        { 
-            d_info->decoder_name = "fuji_load_raw()"; 
-            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
-        }
-    else if (load_raw == &LibRaw::hasselblad_load_raw )
-        {
-            d_info->decoder_name = "hasselblad_load_raw()"; 
-            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
-        }
-    else if (load_raw == &LibRaw::imacon_full_load_raw )
-        {
-            d_info->decoder_name = "imacon_full_load_raw()"; 
-            d_info->decoder_flags = LIBRAW_DECODER_4COMPONENT; 
-        }
-    else if (load_raw == &LibRaw::kodak_262_load_raw )
-        {
-            d_info->decoder_name = "kodak_262_load_raw()"; // UNTESTED!
-            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
-            d_info->decoder_flags |= LIBRAW_DECODER_HASCURVE;
-        }
-    else if (load_raw == &LibRaw::kodak_65000_load_raw )
-        {
-            d_info->decoder_name = "kodak_65000_load_raw()";
-            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
-            d_info->decoder_flags |= LIBRAW_DECODER_HASCURVE;
-        }
-    else if (load_raw == &LibRaw::kodak_dc120_load_raw )
-        {
-            d_info->decoder_name = "kodak_dc120_load_raw()"; 
-            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
-        }
-    else if (load_raw == &LibRaw::kodak_jpeg_load_raw )
-        {
-            // UNTESTED + RBAYER
-            d_info->decoder_name = "kodak_jpeg_load_raw()"; 
-            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
-        }
-    else if (load_raw == &LibRaw::kodak_radc_load_raw )
-        {
-            d_info->decoder_name = "kodak_radc_load_raw()"; 
-            d_info->decoder_flags = LIBRAW_DECODER_4COMPONENT;
-        }
-    else if (load_raw == &LibRaw::kodak_rgb_load_raw ) 
-        {
-            // UNTESTED
-            d_info->decoder_name = "kodak_rgb_load_raw()"; 
-            d_info->decoder_flags = LIBRAW_DECODER_4COMPONENT;
-        }
-    else if (load_raw == &LibRaw::kodak_yrgb_load_raw )    
-        {
-            d_info->decoder_name = "kodak_yrgb_load_raw()"; 
-            d_info->decoder_flags = LIBRAW_DECODER_4COMPONENT;
-            d_info->decoder_flags |= LIBRAW_DECODER_HASCURVE;
-        }
-    else if (load_raw == &LibRaw::kodak_ycbcr_load_raw )
-        {
-            // UNTESTED
-            d_info->decoder_name = "kodak_ycbcr_load_raw()"; 
-            d_info->decoder_flags = LIBRAW_DECODER_4COMPONENT;
-            d_info->decoder_flags |= LIBRAW_DECODER_HASCURVE;
-        }
-    else if (load_raw == &LibRaw::leaf_hdr_load_raw )
-        {
-            d_info->decoder_name = "leaf_hdr_load_raw()"; 
-            d_info->decoder_flags = imgdata.idata.filters ? LIBRAW_DECODER_FLATFIELD : LIBRAW_DECODER_4COMPONENT;
-        }
-    else if (load_raw == &LibRaw::lossless_jpeg_load_raw)
-        {
-            // Check rbayer
-            d_info->decoder_name = "lossless_jpeg_load_raw()"; 
-            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD | LIBRAW_DECODER_HASCURVE;
-        }
-    else if (load_raw == &LibRaw::minolta_rd175_load_raw ) 
-        {  
-            // UNTESTED
-            d_info->decoder_name = "minolta_rd175_load_raw()"; 
-            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
-        }
-    else if (load_raw == &LibRaw::nikon_compressed_load_raw)
-        {
-            // Check rbayer
-            d_info->decoder_name = "nikon_compressed_load_raw()";
-            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
-        }
-    else if (load_raw == &LibRaw::nokia_load_raw )
-        {
-            // UNTESTED
-            d_info->decoder_name = "nokia_load_raw()";
-            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
-        }
-    else if (load_raw == &LibRaw::olympus_load_raw )
-        {
-            d_info->decoder_name = "olympus_load_raw()"; 
-            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
-        }
-    else if (load_raw == &LibRaw::packed_load_raw )
-        {
-            d_info->decoder_name = "packed_load_raw()";
-            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
-        }
-    else if (load_raw == &LibRaw::panasonic_load_raw )
-        {
-            d_info->decoder_name = "panasonic_load_raw()";
-            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
-        }
-    else if (load_raw == &LibRaw::pentax_load_raw )
-        {
-            d_info->decoder_name = "pentax_load_raw()"; 
-            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
-        }
-    else if (load_raw == &LibRaw::phase_one_load_raw )
-        {
-            d_info->decoder_name = "phase_one_load_raw()"; 
-            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
-        }
-    else if (load_raw == &LibRaw::phase_one_load_raw_c )
-        {
-            d_info->decoder_name = "phase_one_load_raw_c()"; 
-            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
-        }
-    else if (load_raw == &LibRaw::quicktake_100_load_raw )
-        {
-            // UNTESTED
-            d_info->decoder_name = "quicktake_100_load_raw()";
-            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
-        }
-    else if (load_raw == &LibRaw::rollei_load_raw )
-        {
-            // UNTESTED
-            d_info->decoder_name = "rollei_load_raw()"; 
-            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
-        }
-    else if (load_raw == &LibRaw::sinar_4shot_load_raw )
-        {
-            // UNTESTED
-            d_info->decoder_name = "sinar_4shot_load_raw()";
-            d_info->decoder_flags = LIBRAW_DECODER_4COMPONENT;
-        }
-    else if (load_raw == &LibRaw::smal_v6_load_raw )
-        {
-            // UNTESTED
-            d_info->decoder_name = "smal_v6_load_raw()";
-            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
-        }
-    else if (load_raw == &LibRaw::smal_v9_load_raw )
-        {
-            // UNTESTED
-            d_info->decoder_name = "smal_v9_load_raw()";
-            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
-        }
-    else if (load_raw == &LibRaw::sony_load_raw )
-        {
-            d_info->decoder_name = "sony_load_raw()"; 
-            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
-        }
-    else if (load_raw == &LibRaw::sony_arw_load_raw )
-        {
-            d_info->decoder_name = "sony_arw_load_raw()";
-            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
-        }
-    else if (load_raw == &LibRaw::sony_arw2_load_raw )
-        {
-            d_info->decoder_name = "sony_arw2_load_raw()";
-            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
-            d_info->decoder_flags |= LIBRAW_DECODER_HASCURVE;
-        }
-    else if (load_raw == &LibRaw::unpacked_load_raw )
-        {
-            d_info->decoder_name = "unpacked_load_raw()"; 
-            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD | LIBRAW_DECODER_USEBAYER2;
-        }
-    else  if (load_raw == &LibRaw::redcine_load_raw)
-        {
-            d_info->decoder_name = "redcine_load_raw()";
-            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD; 
-            d_info->decoder_flags |= LIBRAW_DECODER_HASCURVE;
-        }
-    else
-        {
-            d_info->decoder_name = "Unknown unpack function";
-            d_info->decoder_flags = LIBRAW_DECODER_NOTSET;
-        }
-    return LIBRAW_SUCCESS;
+    }
+  else if (load_raw == &LibRaw::sony_arw2_load_raw )
+    {
+      d_info->decoder_name = "sony_arw2_load_raw()";
+      d_info->decoder_flags = LIBRAW_DECODER_HASCURVE | LIBRAW_DECODER_TRYRAWSPEED | LIBRAW_DECODER_SONYARW2;
+    }
+  else if (load_raw == &LibRaw::samsung_load_raw )
+    {
+      d_info->decoder_name = "samsung_load_raw()";
+      d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED;
+    }
+  else if (load_raw == &LibRaw::samsung2_load_raw )
+    {
+      d_info->decoder_name = "samsung2_load_raw()";
+    }
+  else if (load_raw == &LibRaw::samsung3_load_raw )
+    {
+      d_info->decoder_name = "samsung3_load_raw()";
+    }
+  else if (load_raw == &LibRaw::smal_v6_load_raw )
+    {
+      // UNTESTED
+      d_info->decoder_name = "smal_v6_load_raw()";
+    }
+  else if (load_raw == &LibRaw::smal_v9_load_raw )
+    {
+      // UNTESTED
+      d_info->decoder_name = "smal_v9_load_raw()";
+    }
+  else  if (load_raw == &LibRaw::redcine_load_raw)
+    {
+      d_info->decoder_name = "redcine_load_raw()";
+      d_info->decoder_flags = LIBRAW_DECODER_HASCURVE;
+    }
+  else if (load_raw == &LibRaw::x3f_load_raw )
+    {
+      d_info->decoder_name = "x3f_load_raw()";
+      d_info->decoder_flags = LIBRAW_DECODER_OWNALLOC;
+    }
+#ifdef LIBRAW_DEMOSAIC_PACK_GPL2
+  else if (load_raw == &LibRaw::foveon_sd_load_raw )
+    {
+      d_info->decoder_name = "foveon_sd_load_raw()";
+    }
+  else if (load_raw == &LibRaw::foveon_dp_load_raw )
+    {
+      d_info->decoder_name = "foveon_dp_load_raw()";
+    }
+#endif
+  else
+    {
+      d_info->decoder_name = "Unknown unpack function";
+      d_info->decoder_flags = LIBRAW_DECODER_NOTSET;
+    }
+  return LIBRAW_SUCCESS;
 }
 
 int LibRaw::adjust_maximum()
 {
-    int i;
     ushort real_max;
     float  auto_threshold;
 
@@ -541,17 +799,13 @@ int LibRaw::adjust_maximum()
         auto_threshold = LIBRAW_DEFAULT_ADJUST_MAXIMUM_THRESHOLD;
     else
         auto_threshold = O.adjust_maximum_thr;
-        
-    
-    real_max = C.channel_maximum[0];
-    for(i = 1; i< 4; i++)
-        if(real_max < C.channel_maximum[i])
-            real_max = C.channel_maximum[i];
 
+
+    real_max = C.data_maximum;
     if (real_max > 0 && real_max < C.maximum && real_max > C.maximum* auto_threshold)
-        {
-            C.maximum = real_max;
-        }
+      {
+        C.maximum = real_max;
+      }
     return LIBRAW_SUCCESS;
 }
 
@@ -572,876 +826,1430 @@ void LibRaw:: merror (void *ptr, const char *where)
 int LibRaw::open_file(const char *fname, INT64 max_buf_size)
 {
 #ifndef WIN32
-    struct stat st;
-    if(stat(fname,&st))
-        return LIBRAW_IO_ERROR;
-    int big = (st.st_size > max_buf_size)?1:0;
+  struct stat st;
+  if(stat(fname,&st))
+    return LIBRAW_IO_ERROR;
+  int big = (st.st_size > max_buf_size)?1:0;
 #else
-	struct _stati64 st;
-    if(_stati64(fname,&st))	
-        return LIBRAW_IO_ERROR;
-    int big = (st.st_size > max_buf_size)?1:0;
+  struct _stati64 st;
+  if(_stati64(fname,&st))
+    return LIBRAW_IO_ERROR;
+  int big = (st.st_size > max_buf_size)?1:0;
 #endif
 
-    LibRaw_abstract_datastream *stream;
-    try {
-        if(big)
-         stream = new LibRaw_bigfile_datastream(fname);
-        else
-         stream = new LibRaw_file_datastream(fname);
+  LibRaw_abstract_datastream *stream;
+  try {
+    if(big)
+      stream = new LibRaw_bigfile_datastream(fname);
+    else
+      stream = new LibRaw_file_datastream(fname);
+  }
+
+  catch (std::bad_alloc)
+    {
+      recycle();
+      return LIBRAW_UNSUFFICIENT_MEMORY;
     }
+  if(!stream->valid())
+    {
+      delete stream;
+      return LIBRAW_IO_ERROR;
+    }
+  ID.input_internal = 0; // preserve from deletion on error
+  int ret = open_datastream(stream);
+  if (ret == LIBRAW_SUCCESS)
+    {
+      ID.input_internal =1 ; // flag to delete datastream on recycle
+    }
+  else
+    {
+      delete stream;
+      ID.input_internal = 0;
+    }
+  return ret;
+}
 
-    catch (std::bad_alloc)
-        {
-            recycle();
-            return LIBRAW_UNSUFFICIENT_MEMORY;
-        }
-    if(!stream->valid())
-        {
-            delete stream;
-            return LIBRAW_IO_ERROR;
-        }
-    ID.input_internal = 0; // preserve from deletion on error
-    int ret = open_datastream(stream);
-    if (ret == LIBRAW_SUCCESS)
-        {
-            ID.input_internal =1 ; // flag to delete datastream on recycle
-        }
+#if defined(_WIN32) && !defined(__MINGW32__) && defined(_MSC_VER) && (_MSC_VER > 1310)
+int LibRaw::open_file(const wchar_t *fname, INT64 max_buf_size)
+{
+  struct _stati64 st;
+  if(_wstati64(fname,&st))
+    return LIBRAW_IO_ERROR;
+  int big = (st.st_size > max_buf_size)?1:0;
+
+  LibRaw_abstract_datastream *stream;
+  try {
+    if(big)
+      stream = new LibRaw_bigfile_datastream(fname);
     else
-        {
-            delete stream;
-            ID.input_internal = 0;
-        }
-    return ret;
+      stream = new LibRaw_file_datastream(fname);
+  }
+
+  catch (std::bad_alloc)
+    {
+      recycle();
+      return LIBRAW_UNSUFFICIENT_MEMORY;
+    }
+  if(!stream->valid())
+    {
+      delete stream;
+      return LIBRAW_IO_ERROR;
+    }
+  ID.input_internal = 0; // preserve from deletion on error
+  int ret = open_datastream(stream);
+  if (ret == LIBRAW_SUCCESS)
+    {
+      ID.input_internal =1 ; // flag to delete datastream on recycle
+    }
+  else
+    {
+      delete stream;
+      ID.input_internal = 0;
+    }
+  return ret;
 }
+#endif
 
 int LibRaw::open_buffer(void *buffer, size_t size)
 {
-    // this stream will close on recycle()
-    if(!buffer  || buffer==(void*)-1)
-        return LIBRAW_IO_ERROR;
-
-    LibRaw_buffer_datastream *stream;
-    try {
-        stream = new LibRaw_buffer_datastream(buffer,size);
+  // this stream will close on recycle()
+  if(!buffer  || buffer==(void*)-1)
+    return LIBRAW_IO_ERROR;
+
+  LibRaw_buffer_datastream *stream;
+  try {
+    stream = new LibRaw_buffer_datastream(buffer,size);
+  }
+  catch (std::bad_alloc)
+    {
+      recycle();
+      return LIBRAW_UNSUFFICIENT_MEMORY;
     }
-    catch (std::bad_alloc)
-        {
-            recycle();
-            return LIBRAW_UNSUFFICIENT_MEMORY;
-        }
-    if(!stream->valid())
-        {
-            delete stream;
-            return LIBRAW_IO_ERROR;
-        }
-    ID.input_internal = 0; // preserve from deletion on error
-    int ret = open_datastream(stream);
-    if (ret == LIBRAW_SUCCESS)
-        {
-            ID.input_internal =1 ; // flag to delete datastream on recycle
-        }
-    else
-        {
-            delete stream;
-            ID.input_internal = 0;
-        }
-    return ret;
+  if(!stream->valid())
+    {
+      delete stream;
+      return LIBRAW_IO_ERROR;
+    }
+  ID.input_internal = 0; // preserve from deletion on error
+  int ret = open_datastream(stream);
+  if (ret == LIBRAW_SUCCESS)
+    {
+      ID.input_internal =1 ; // flag to delete datastream on recycle
+    }
+  else
+    {
+      delete stream;
+      ID.input_internal = 0;
+    }
+  return ret;
 }
 
+void LibRaw::hasselblad_full_load_raw()
+{
+  int row, col;
+
+  for (row=0; row < S.height; row++)
+    for (col=0; col < S.width; col++)
+      {
+        read_shorts (&imgdata.image[row*S.width+col][2], 1); // B
+        read_shorts (&imgdata.image[row*S.width+col][1], 1); // G
+        read_shorts (&imgdata.image[row*S.width+col][0], 1); // R
+      }
+}
 
-int LibRaw::open_datastream(LibRaw_abstract_datastream *stream)
+struct foveon_data_t
+{
+    const char *make;
+    const char *model;
+    const int raw_width,raw_height;
+    const int  white;
+    const int  left_margin,top_margin;
+    const int  width,height;
+} foveon_data [] =
 {
+  {"Sigma","SD9",2304,1531,12000,20,8,2266,1510},
+  {"Sigma","SD9",1152,763,12000,10,2,1132,755},
+  {"Sigma","SD10",2304,1531,12000,20,8,2266,1510},
+  {"Sigma","SD10",1152,763,12000,10,2,1132,755},
+  {"Sigma","SD14",2688,1792,14000,18,12,2651,1767},
+  {"Sigma","SD14",2688,896,14000,18,6,2651,883}, // 2/3
+  {"Sigma","SD14",1344,896,14000,9,6,1326,883}, // 1/2
+  {"Sigma","SD15",2688,1792,2900,18,12,2651,1767},
+  {"Sigma","SD15",2688,896,2900,18,6,2651,883}, // 2/3 ?
+  {"Sigma","SD15",1344,896,2900,9,6,1326,883}, // 1/2 ?
+  {"Sigma","DP1",2688,1792,2100,18,12,2651,1767},
+  {"Sigma","DP1",2688,896,2100,18,6,2651,883}, // 2/3 ?
+  {"Sigma","DP1",1344,896,2100,9,6,1326,883}, // 1/2 ?
+  {"Sigma","DP1S",2688,1792,2200,18,12,2651,1767},
+  {"Sigma","DP1S",2688,896,2200,18,6,2651,883}, // 2/3
+  {"Sigma","DP1S",1344,896,2200,9,6,1326,883}, // 1/2
+  {"Sigma","DP1X",2688,1792,3560,18,12,2651,1767},
+  {"Sigma","DP1X",2688,896,3560,18,6,2651,883}, // 2/3
+  {"Sigma","DP1X",1344,896,3560,9,6,1326,883}, // 1/2
+  {"Sigma","DP2",2688,1792,2326,13,16,2651,1767},
+  {"Sigma","DP2",2688,896,2326,13,8,2651,883}, // 2/3 ??
+  {"Sigma","DP2",1344,896,2326,7,8,1325,883}, // 1/2 ??
+  {"Sigma","DP2S",2688,1792,2300,18,12,2651,1767},
+  {"Sigma","DP2S",2688,896,2300,18,6,2651,883}, // 2/3
+  {"Sigma","DP2S",1344,896,2300,9,6,1326,883}, // 1/2
+  {"Sigma","DP2X",2688,1792,2300,18,12,2651,1767},
+  {"Sigma","DP2X",2688,896,2300,18,6,2651,883}, // 2/3
+  {"Sigma","DP2X",1344,896,2300,9,6,1325,883}, // 1/2
+  {"Sigma","SD1",4928,3264,3900,12,52,4807,3205}, // Full size
+  {"Sigma","SD1",4928,1632,3900,12,26,4807,1603}, // 2/3 size
+  {"Sigma","SD1",2464,1632,3900,6,26,2403,1603}, // 1/2 size
+  {"Sigma","SD1 Merrill",4928,3264,3900,12,52,4807,3205}, // Full size
+  {"Sigma","SD1 Merrill",4928,1632,3900,12,26,4807,1603}, // 2/3 size
+  {"Sigma","SD1 Merrill",2464,1632,3900,6,26,2403,1603}, // 1/2 size
+  {"Sigma","DP1 Merrill",4928,3264,3900,12,0,4807,3205},
+  {"Sigma","DP1 Merrill",2464,1632,3900,12,0,2403,1603}, // 1/2 size
+  {"Sigma","DP1 Merrill",4928,1632,3900,12,0,4807,1603}, // 2/3 size
+  {"Sigma","DP2 Merrill",4928,3264,3900,12,0,4807,3205},
+  {"Sigma","DP2 Merrill",2464,1632,3900,12,0,2403,1603}, // 1/2 size
+  {"Sigma","DP2 Merrill",4928,1632,3900,12,0,4807,1603}, // 2/3 size
+  {"Sigma","DP3 Merrill",4928,3264,3900,12,0,4807,3205},
+  {"Sigma","DP3 Merrill",2464,1632,3900,12,0,2403,1603}, // 1/2 size
+  {"Sigma","DP3 Merrill",4928,1632,3900,12,0,4807,1603}, // 2/3 size
+  {"Polaroid","x530",1440,1088,2700,10,13,1419,1059},
+  // dp2 Q
+  {"Sigma","dp2 Quattro",5888,3672,16383,204,24,5446,3624}, // full size
+  {"Sigma","dp2 Quattro",2944,1836,16383,102,12,2723,1812}, // half size
+  {"Sigma","dp1 Quattro",5888,3672,16383,204,24,5446,3624}, // full size
+  {"Sigma","dp1 Quattro",2944,1836,16383,102,12,2723,1812}, // half size
+};
+const int foveon_count = sizeof(foveon_data)/sizeof(foveon_data[0]);
 
-    if(!stream)
-        return ENOENT;
-    if(!stream->valid())
-        return LIBRAW_IO_ERROR;
-    recycle();
 
-    try {
-        ID.input = stream;
-        SET_PROC_FLAG(LIBRAW_PROGRESS_OPEN);
+int LibRaw::open_datastream(LibRaw_abstract_datastream *stream)
+{
 
-        if (O.use_camera_matrix < 0)
-            O.use_camera_matrix = O.use_camera_wb;
+  if(!stream)
+    return ENOENT;
+  if(!stream->valid())
+    return LIBRAW_IO_ERROR;
+  recycle();
 
-        identify();
+  try {
+    ID.input = stream;
+    SET_PROC_FLAG(LIBRAW_PROGRESS_OPEN);
 
-        if(IO.fuji_width)
-            {
-                IO.fwidth = S.width;
-                IO.fheight = S.height;
-                S.iwidth = S.width = IO.fuji_width << (int)(!libraw_internal_data.unpacker_data.fuji_layout);
-                S.iheight = S.height = S.raw_height;
-                S.raw_height += 2*S.top_margin;
-            }
+    identify();
 
-        if(C.profile_length)
+	if (!imgdata.idata.dng_version && !strcmp(imgdata.idata.make, "Leaf") && !strcmp(imgdata.idata.model, "Credo 50"))
+	{
+		imgdata.color.pre_mul[0] = 1.f / 0.3984f;
+		imgdata.color.pre_mul[2] = 1.f / 0.7666f;
+		imgdata.color.pre_mul[1] = imgdata.color.pre_mul[3] = 1.0;
+	}
+
+	// S3Pro DNG patch
+	if(imgdata.idata.dng_version && !strcmp(imgdata.idata.make,"Fujifilm") && !strcmp(imgdata.idata.model,"S3Pro") && imgdata.sizes.raw_width == 4288 )
+	{
+		imgdata.sizes.left_margin++;
+		imgdata.sizes.width--;
+	}
+	if(imgdata.idata.dng_version && !strcmp(imgdata.idata.make,"Fujifilm") && !strcmp(imgdata.idata.model,"S5Pro") && imgdata.sizes.raw_width == 4288 )
+	{
+		imgdata.sizes.left_margin++;
+		imgdata.sizes.width--;
+	}
+	if(!imgdata.idata.dng_version && !strcmp(imgdata.idata.make,"Fujifilm") && !strcmp(imgdata.idata.model,"S20Pro"))
+	{
+		if(imgdata.idata.raw_count>1)
+			imgdata.idata.raw_count = 1;
+	}
+	if(load_raw == &LibRaw::packed_load_raw && !strcasecmp(imgdata.idata.make,"Nikon")
+		 && !libraw_internal_data.unpacker_data.load_flags
+		 && (!strcasecmp(imgdata.idata.model,"D810") || !strcasecmp(imgdata.idata.model,"D4S"))
+		 && libraw_internal_data.unpacker_data.data_size*2 == imgdata.sizes.raw_height*imgdata.sizes.raw_width*3)
+	{
+		libraw_internal_data.unpacker_data.load_flags = 80;
+	}
+	// Adjust BL for Sony A900/A850
+    if(load_raw == &LibRaw::packed_load_raw && !strcasecmp(imgdata.idata.make,"Sony")) // 12 bit sony, but metadata may be for 14-bit range
+      {
+        if(C.maximum>4095)
+          C.maximum = 4095;
+        if(C.black > 256 || C.cblack[0] > 256)
+          {
+            C.black /=4;
+            for(int c=0; c< 4; c++)
+              C.cblack[c]/=4;
+            for(int c=0; c< C.cblack[4]*C.cblack[5];c++)
+              C.cblack[6+c]/=4;
+          }
+      }
+    if(  load_raw == &LibRaw::nikon_yuv_load_raw  ) // Is it Nikon sRAW?
+      {
+           load_raw= &LibRaw::nikon_load_sraw;
+           C.black =0;
+		   memset(C.cblack,0,sizeof(C.cblack));
+           imgdata.idata.filters = 0;
+           libraw_internal_data.unpacker_data.tiff_samples=3;
+           imgdata.idata.colors = 3;
+           double beta_1 = -5.79342238397656E-02;
+           double beta_2 = 3.28163551282665;
+           double beta_3 = -8.43136004842678;
+           double beta_4 = 1.03533181861023E+01;
+           for(int i=0; i<=3072;i++)
+           {
+               double x = (double)i/3072.;
+               double y = (1.-exp(-beta_1*x-beta_2*x*x-beta_3*x*x*x-beta_4*x*x*x*x));
+               if(y<0.)y=0.;
+               imgdata.color.curve[i] = (y*16383.);
+           }
+           for(int i=0;i<3;i++)
+             for(int j=0;j<4;j++)
+               imgdata.color.rgb_cam[i][j]=float(i==j);
+      }
+    // Adjust BL for Nikon 12bit
+    if((
+        load_raw == &LibRaw::nikon_load_raw
+        || load_raw == &LibRaw::packed_load_raw)
+       && !strcasecmp(imgdata.idata.make,"Nikon")
+       && strncmp(imgdata.idata.model,"COOLPIX",7)
+	   && strncmp(imgdata.idata.model,"1 ",2)
+       && libraw_internal_data.unpacker_data.tiff_bps == 12)
+      {
+        C.maximum = 4095;
+        C.black /=4;
+        for(int c=0; c< 4; c++)
+          C.cblack[c]/=4;
+        for(int c=0; c< C.cblack[4]*C.cblack[5];c++)
+          C.cblack[6+c]/=4;
+      }
+
+	// Adjust BL for Panasonic
+    if(load_raw == &LibRaw::panasonic_load_raw && (!strcasecmp(imgdata.idata.make,"Panasonic") || !strcasecmp(imgdata.idata.make,"Leica"))
+       &&  ID.pana_black[0] && ID.pana_black[1] && ID.pana_black[2])
+      {
+        C.black=0;
+        C.cblack[0] = ID.pana_black[0]+ID.pana_black[3];
+        C.cblack[1] = C.cblack[3] = ID.pana_black[1]+ID.pana_black[3];
+        C.cblack[2] = ID.pana_black[2]+ID.pana_black[3];
+        int i = C.cblack[3];
+        for(int c=0; c<3; c++) if(i>C.cblack[c]) i = C.cblack[c];
+        for(int c=0; c< 4; c++) C.cblack[c]-=i;
+        C.black = i;
+      }
+
+    // Adjust sizes for X3F processing
+    if(load_raw == &LibRaw::x3f_load_raw)
+    {
+        for(int i=0; i< foveon_count;i++)
+            if(!strcasecmp(imgdata.idata.make,foveon_data[i].make) && !strcasecmp(imgdata.idata.model,foveon_data[i].model)
+                && imgdata.sizes.raw_width == foveon_data[i].raw_width
+                && imgdata.sizes.raw_height == foveon_data[i].raw_height
+                )
             {
-                if(C.profile) free(C.profile);
-                C.profile = malloc(C.profile_length);
-                merror(C.profile,"LibRaw::open_file()");
-                ID.input->seek(ID.profile_offset,SEEK_SET);
-                ID.input->read(C.profile,C.profile_length,1);
+                imgdata.sizes.top_margin = foveon_data[i].top_margin;
+                imgdata.sizes.left_margin = foveon_data[i].left_margin;
+                imgdata.sizes.width = imgdata.sizes.iwidth = foveon_data[i].width;
+                imgdata.sizes.height = imgdata.sizes.iheight = foveon_data[i].height;
+                C.maximum = foveon_data[i].white;
+                break;
             }
-        
-        SET_PROC_FLAG(LIBRAW_PROGRESS_IDENTIFY);
-    }
-    catch ( LibRaw_exceptions err) {
-        EXCEPTION_HANDLER(err);
     }
-    catch (std::exception ee) {
-        EXCEPTION_HANDLER(LIBRAW_EXCEPTION_IO_CORRUPT);
+#if 0
+    size_t bytes = ID.input->size()-libraw_internal_data.unpacker_data.data_offset;
+    float bpp = float(bytes)/float(S.raw_width)/float(S.raw_height);
+    float bpp2 = float(bytes)/float(S.width)/float(S.height);
+    printf("RawSize: %dx%d data offset: %d data size:%d bpp: %g bpp2: %g\n",S.raw_width,S.raw_height,libraw_internal_data.unpacker_data.data_offset,bytes,bpp,bpp2);
+    if(!strcasecmp(imgdata.idata.make,"Hasselblad") && bpp == 6.0f)
+      {
+        load_raw = &LibRaw::hasselblad_full_load_raw;
+        S.width = S.raw_width;
+        S.height = S.raw_height;
+        P1.filters = 0;
+        P1.colors=3;
+        P1.raw_count=1;
+        C.maximum=0xffff;
+        printf("3 channel hassy found\n");
+      }
+#endif
+    if(C.profile_length)
+      {
+        if(C.profile) free(C.profile);
+        C.profile = malloc(C.profile_length);
+        merror(C.profile,"LibRaw::open_file()");
+        ID.input->seek(ID.profile_offset,SEEK_SET);
+        ID.input->read(C.profile,C.profile_length,1);
+      }
+
+    SET_PROC_FLAG(LIBRAW_PROGRESS_IDENTIFY);
+  }
+  catch ( LibRaw_exceptions err) {
+    EXCEPTION_HANDLER(err);
+  }
+  catch (std::exception ee) {
+    EXCEPTION_HANDLER(LIBRAW_EXCEPTION_IO_CORRUPT);
+  }
+
+  if(P1.raw_count < 1)
+    return LIBRAW_FILE_UNSUPPORTED;
+
+
+  write_fun = &LibRaw::write_ppm_tiff;
+
+  if (load_raw == &LibRaw::kodak_ycbcr_load_raw)
+    {
+      S.height += S.height & 1;
+      S.width  += S.width  & 1;
     }
 
-    if(P1.raw_count < 1) 
-        return LIBRAW_FILE_UNSUPPORTED;
+  IO.shrink = P1.filters && (O.half_size ||
+                             ((O.threshold || O.aber[0] != 1 || O.aber[2] != 1) ));
 
-    
-    write_fun = &LibRaw::write_ppm_tiff;
-    
-    if (load_raw == &LibRaw::kodak_ycbcr_load_raw) 
-        {
-            S.height += S.height & 1;
-            S.width  += S.width  & 1;
-        }
+  S.iheight = (S.height + IO.shrink) >> IO.shrink;
+  S.iwidth  = (S.width  + IO.shrink) >> IO.shrink;
 
-    IO.shrink = P1.filters && (O.half_size ||
-	((O.threshold || O.aber[0] != 1 || O.aber[2] != 1) ));
+  // Save color,sizes and internal data into raw_image fields
+  memmove(&imgdata.rawdata.color,&imgdata.color,sizeof(imgdata.color));
+  memmove(&imgdata.rawdata.sizes,&imgdata.sizes,sizeof(imgdata.sizes));
+  memmove(&imgdata.rawdata.iparams,&imgdata.idata,sizeof(imgdata.idata));
+  memmove(&imgdata.rawdata.ioparams,&libraw_internal_data.internal_output_params,sizeof(libraw_internal_data.internal_output_params));
 
-    S.iheight = (S.height + IO.shrink) >> IO.shrink;
-    S.iwidth  = (S.width  + IO.shrink) >> IO.shrink;
-
-    // Save color,sizes and internal data into raw_image fields
-    memmove(&imgdata.rawdata.color,&imgdata.color,sizeof(imgdata.color));
-    memmove(&imgdata.rawdata.sizes,&imgdata.sizes,sizeof(imgdata.sizes));
-    memmove(&imgdata.rawdata.iparams,&imgdata.idata,sizeof(imgdata.idata));
-    memmove(&imgdata.rawdata.ioparams,&libraw_internal_data.internal_output_params,sizeof(libraw_internal_data.internal_output_params));
-    
-    SET_PROC_FLAG(LIBRAW_PROGRESS_SIZE_ADJUST);
+  SET_PROC_FLAG(LIBRAW_PROGRESS_SIZE_ADJUST);
 
 
-    return LIBRAW_SUCCESS;
+  return LIBRAW_SUCCESS;
 }
 
-int LibRaw::unpack(void)
+#ifdef USE_RAWSPEED
+void LibRaw::fix_after_rawspeed(int bl)
 {
-    CHECK_ORDER_HIGH(LIBRAW_PROGRESS_LOAD_RAW);
-    CHECK_ORDER_LOW(LIBRAW_PROGRESS_IDENTIFY);
-    try {
-
-        RUN_CALLBACK(LIBRAW_PROGRESS_LOAD_RAW,0,2);
-        if (O.shot_select >= P1.raw_count)
-            return LIBRAW_REQUEST_FOR_NONEXISTENT_IMAGE;
-        
-        if(!load_raw)
-            return LIBRAW_UNSPECIFIED_ERROR;
-        
-        if (O.use_camera_matrix && C.cmatrix[0][0] > 0.25) 
-            {
-                memcpy (C.rgb_cam, C.cmatrix, sizeof (C.cmatrix));
-                IO.raw_color = 0;
-            }
-        // already allocated ?
-        if(imgdata.image)
-            {
-                free(imgdata.image);
-                imgdata.image = 0;
-            }
-
-        if (libraw_internal_data.unpacker_data.meta_length) 
-            {
-                libraw_internal_data.internal_data.meta_data = 
-                    (char *) malloc (libraw_internal_data.unpacker_data.meta_length);
-                merror (libraw_internal_data.internal_data.meta_data, "LibRaw::unpack()");
-            }
-        ID.input->seek(libraw_internal_data.unpacker_data.data_offset, SEEK_SET);
-        int save_document_mode = O.document_mode;
-        O.document_mode = 0;
+  if (load_raw == &LibRaw::lossy_dng_load_raw)
+    C.maximum = 0xffff;
+  else if (load_raw == &LibRaw::sony_load_raw)
+    C.maximum = 0x3ff0;
+}
+#else
+void LibRaw::fix_after_rawspeed(int)
+{
+}
+#endif
 
-        libraw_decoder_info_t decoder_info;
-        get_decoder_info(&decoder_info);
+void LibRaw::clearCancelFlag()
+{
+#ifdef WIN32
+	InterlockedExchange(&_exitflag, 0);
+#else
+	__sync_fetch_and_and(&_exitflag, 0);
+#endif
+#ifdef RAWSPEED_FASTEXIT
+	if (_rawspeed_decoder)
+	{
+		RawDecoder *d = static_cast<RawDecoder*>(_rawspeed_decoder);
+		d->resumeProcessing();
+	}
+#endif
 
-        int save_iwidth = S.iwidth, save_iheight = S.iheight, save_shrink = IO.shrink;
+}
 
-        int rwidth = S.raw_width, rheight = S.raw_height;
-        if( !IO.fuji_width)
-            {
-                // adjust non-Fuji allocation
-                if(rwidth < S.width + S.left_margin)
-                    rwidth = S.width + S.left_margin;
-                if(rheight < S.height + S.top_margin)
-                    rheight = S.height + S.top_margin;
-            }
-        
-        if(decoder_info.decoder_flags &  LIBRAW_DECODER_FLATFIELD)
-            {
-                imgdata.rawdata.raw_alloc = malloc(rwidth*rheight*sizeof(imgdata.rawdata.raw_image[0]));
-                imgdata.rawdata.raw_image = (ushort*) imgdata.rawdata.raw_alloc;
-            }
-        else if (decoder_info.decoder_flags &  LIBRAW_DECODER_4COMPONENT)
-            {
-                S.iwidth = S.width;
-                S.iheight= S.height;
-                IO.shrink = 0;
-                imgdata.rawdata.raw_alloc = calloc(rwidth*rheight,sizeof(*imgdata.rawdata.color_image));
-                imgdata.rawdata.color_image = (ushort(*)[4]) imgdata.rawdata.raw_alloc;
-            }
-        else if (decoder_info.decoder_flags & LIBRAW_DECODER_LEGACY)
-            {
-                // sRAW and Foveon only, so extra buffer size is just 1/4
-                // Legacy converters does not supports half mode!
-                S.iwidth = S.width;
-                S.iheight= S.height;
-                IO.shrink = 0;
-                // allocate image as temporary buffer, size 
-                imgdata.rawdata.raw_alloc = calloc(S.iwidth*S.iheight,sizeof(*imgdata.image));
-                imgdata.image = (ushort (*)[4]) imgdata.rawdata.raw_alloc;
-            }
+void LibRaw::setCancelFlag()
+{
+#ifdef WIN32
+  InterlockedExchange(&_exitflag,1);
+#else
+  __sync_fetch_and_add(&_exitflag,1);
+#endif
+#ifdef RAWSPEED_FASTEXIT
+  if(_rawspeed_decoder)
+    {
+      RawDecoder *d = static_cast<RawDecoder*>(_rawspeed_decoder);
+      d->cancelProcessing();
+    }
+#endif
+}
 
+void LibRaw::checkCancel()
+{
+#ifdef WIN32
+  if(InterlockedExchange(&_exitflag,0))
+    throw LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK;
+#else
+  if( __sync_fetch_and_and(&_exitflag,0))
+    throw LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK;
+#endif
+}
 
-        (this->*load_raw)();
+int LibRaw::unpack(void)
+{
+  CHECK_ORDER_HIGH(LIBRAW_PROGRESS_LOAD_RAW);
+  CHECK_ORDER_LOW(LIBRAW_PROGRESS_IDENTIFY);
+  try {
 
+    if(!libraw_internal_data.internal_data.input)
+      return LIBRAW_INPUT_CLOSED;
 
-        // recover saved
-        if( decoder_info.decoder_flags & LIBRAW_DECODER_LEGACY)
-            {
-                imgdata.image = 0; 
-                imgdata.rawdata.color_image = (ushort (*)[4]) imgdata.rawdata.raw_alloc;
-            }
+    RUN_CALLBACK(LIBRAW_PROGRESS_LOAD_RAW,0,2);
+    if (O.shot_select >= P1.raw_count)
+      return LIBRAW_REQUEST_FOR_NONEXISTENT_IMAGE;
 
-        // calculate channel maximum
-        {
-            for(int c=0;c<4;c++) C.channel_maximum[c] = 0;
-            if(decoder_info.decoder_flags & LIBRAW_DECODER_LEGACY)
-                {
-                    for(int rc = 0; rc < S.iwidth*S.iheight; rc++)
-                        {
-                            if(C.channel_maximum[0]<imgdata.rawdata.color_image[rc][0]) 
-                                C.channel_maximum[0]=imgdata.rawdata.color_image[rc][0];
-                            if(C.channel_maximum[1]<imgdata.rawdata.color_image[rc][1]) 
-                                C.channel_maximum[1]=imgdata.rawdata.color_image[rc][1];
-                            if(C.channel_maximum[2]<imgdata.rawdata.color_image[rc][2]) 
-                                C.channel_maximum[2]=imgdata.rawdata.color_image[rc][2];
-                            if(C.channel_maximum[3]<imgdata.rawdata.color_image[rc][3]) 
-                                C.channel_maximum[3]=imgdata.rawdata.color_image[rc][3];
-                        }
-                }
-            else if(decoder_info.decoder_flags &  LIBRAW_DECODER_4COMPONENT)
-                {
-                    for(int row = S.top_margin; row < S.height+S.top_margin; row++)
-                        for(int col = S.left_margin; col < S.width+S.left_margin; col++)
-                        {
-                            int rc = row*S.raw_width+col;
-                            if(C.channel_maximum[0]<imgdata.rawdata.color_image[rc][0]) 
-                                C.channel_maximum[0]=imgdata.rawdata.color_image[rc][0];
-                            if(C.channel_maximum[1]<imgdata.rawdata.color_image[rc][1]) 
-                                C.channel_maximum[1]=imgdata.rawdata.color_image[rc][1];
-                            if(C.channel_maximum[2]<imgdata.rawdata.color_image[rc][2]) 
-                                C.channel_maximum[2]=imgdata.rawdata.color_image[rc][2];
-                            if(C.channel_maximum[3]<imgdata.rawdata.color_image[rc][3]) 
-                                C.channel_maximum[3]=imgdata.rawdata.color_image[rc][4];
-                        }
-                }
-            else if (decoder_info.decoder_flags &  LIBRAW_DECODER_FLATFIELD)
-                {
-                        for(int row = 0; row < S.height; row++)
-                            {
-                                int colors[4];
-                                for (int xx=0;xx<4;xx++)
-                                    colors[xx] = COLOR(row,xx);
-                                for(int col = 0; col < S.width; col++)
-                                    {
-                                        int cc = colors[col&3];
-                                        if(C.channel_maximum[cc] 
-                                           < imgdata.rawdata.raw_image[(row+S.top_margin)*S.raw_width
-                                                                       +(col+S.left_margin)])
-                                            C.channel_maximum[cc] = 
-                                                imgdata.rawdata.raw_image[(row+S.top_margin)*S.raw_width
-                                                                          +(col+S.left_margin)];
-                                    }
-                            }
-                }
-        }
-        // recover image sizes
-        S.iwidth = save_iwidth;
-        S.iheight = save_iheight;
-        IO.shrink = save_shrink;
-
-        // phase-one black
-        if(imgdata.rawdata.ph1_black)
-            C.ph1_black = imgdata.rawdata.ph1_black;
-        O.document_mode = save_document_mode;
-
-        // adjust black to possible maximum
-        unsigned int i = C.cblack[3];
-        unsigned int c;
-        for(c=0;c<3;c++)
-            if (i > C.cblack[c]) i = C.cblack[c];
-        for (c=0;c<4;c++)
-            C.cblack[c] -= i;
-        C.black += i;
+    if(!load_raw)
+      return LIBRAW_UNSPECIFIED_ERROR;
 
+    // already allocated ?
+    if(imgdata.image)
+      {
+        free(imgdata.image);
+        imgdata.image = 0;
+      }
+    if(imgdata.rawdata.raw_alloc)
+      {
+        free(imgdata.rawdata.raw_alloc);
+        imgdata.rawdata.raw_alloc = 0;
+      }
+    if (libraw_internal_data.unpacker_data.meta_length)
+      {
+        libraw_internal_data.internal_data.meta_data =
+          (char *) malloc (libraw_internal_data.unpacker_data.meta_length);
+        merror (libraw_internal_data.internal_data.meta_data, "LibRaw::unpack()");
+      }
 
-        // Save color,sizes and internal data into raw_image fields
-        memmove(&imgdata.rawdata.color,&imgdata.color,sizeof(imgdata.color));
-        memmove(&imgdata.rawdata.sizes,&imgdata.sizes,sizeof(imgdata.sizes));
-        memmove(&imgdata.rawdata.iparams,&imgdata.idata,sizeof(imgdata.idata));
-        memmove(&imgdata.rawdata.ioparams,&libraw_internal_data.internal_output_params,sizeof(libraw_internal_data.internal_output_params));
+    libraw_decoder_info_t decoder_info;
+    get_decoder_info(&decoder_info);
 
-        SET_PROC_FLAG(LIBRAW_PROGRESS_LOAD_RAW);
-        RUN_CALLBACK(LIBRAW_PROGRESS_LOAD_RAW,1,2);
-        
-        return 0;
-    }
-    catch ( LibRaw_exceptions err) {
-        EXCEPTION_HANDLER(err);
-    }
-    catch (std::exception ee) {
-        EXCEPTION_HANDLER(LIBRAW_EXCEPTION_IO_CORRUPT);
-    }
-}
+    int save_iwidth = S.iwidth, save_iheight = S.iheight, save_shrink = IO.shrink;
+
+    int rwidth = S.raw_width, rheight = S.raw_height;
+    if( !IO.fuji_width)
+      {
+        // adjust non-Fuji allocation
+        if(rwidth < S.width + S.left_margin)
+          rwidth = S.width + S.left_margin;
+        if(rheight < S.height + S.top_margin)
+          rheight = S.height + S.top_margin;
+      }
+
+    imgdata.rawdata.raw_image = 0;
+    imgdata.rawdata.color4_image = 0;
+    imgdata.rawdata.color3_image = 0;
+#ifdef USE_RAWSPEED
+	int rawspeed_enabled = 1;
+	if(imgdata.idata.dng_version && libraw_internal_data.unpacker_data.tiff_samples == 2)
+		rawspeed_enabled = 0;
+	// Disable rawspeed for double-sized Oly files
+	if(!strncasecmp(imgdata.idata.make,"Olympus",7) && !strncasecmp(imgdata.idata.model,"E-M5MarkII",10) && imgdata.sizes.raw_width == 9280)
+		rawspeed_enabled = 0;
+
+    // RawSpeed Supported,
+    if(O.use_rawspeed  && rawspeed_enabled
+       && !(is_sraw() && O.sraw_ycc)
+       && (decoder_info.decoder_flags & LIBRAW_DECODER_TRYRAWSPEED) && _rawspeed_camerameta)
+      {
+        INT64 spos = ID.input->tell();
+        void *_rawspeed_buffer = 0;
+        try
+          {
+            //                printf("Using rawspeed\n");
+            ID.input->seek(0,SEEK_SET);
+            INT64 _rawspeed_buffer_sz = ID.input->size()+32;
+            _rawspeed_buffer = malloc(_rawspeed_buffer_sz);
+            if(!_rawspeed_buffer) throw LIBRAW_EXCEPTION_ALLOC;
+            ID.input->read(_rawspeed_buffer,_rawspeed_buffer_sz,1);
+            FileMap map((uchar8*)_rawspeed_buffer,_rawspeed_buffer_sz);
+            RawParser t(&map);
+            RawDecoder *d = 0;
+            CameraMetaDataLR *meta = static_cast<CameraMetaDataLR*>(_rawspeed_camerameta);
+            d = t.getDecoder();
+            if(!d) throw "Unable to find decoder";
+            try {
+              d->checkSupport(meta);
+            }
+            catch (const RawDecoderException& e)
+              {
+                imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED_UNSUPPORTED;
+                throw e;
+              }
+            d->interpolateBadPixels = FALSE;
+            d->applyStage1DngOpcodes = FALSE;
+            _rawspeed_decoder = static_cast<void*>(d);
+            d->decodeRaw();
+            d->decodeMetaData(meta);
+            RawImage r = d->mRaw;
+            if( r->errors.size()>0)
+              {
+                delete d;
+                _rawspeed_decoder = 0;
+                throw 1;
+              }
+            if (r->isCFA)
+			{
+              imgdata.rawdata.raw_image = (ushort*) r->getDataUncropped(0,0);
+            }
+			else if(r->getCpp()==4)
+			{
+              imgdata.rawdata.color4_image = (ushort(*)[4]) r->getDataUncropped(0,0);
+			  if(r->whitePoint > 0 && r->whitePoint < 65536)
+					C.maximum = r->whitePoint;
+            } else if(r->getCpp() == 3)
+              {
+                imgdata.rawdata.color3_image = (ushort(*)[3]) r->getDataUncropped(0,0);
+				if(r->whitePoint > 0 && r->whitePoint < 65536)
+					C.maximum = r->whitePoint;
+              }
+            else
+              {
+                delete d;
+                _rawspeed_decoder = 0;
+              }
+            if(_rawspeed_decoder)
+              {
+                // set sizes
+                iPoint2D rsdim = r->getUncroppedDim();
+                S.raw_pitch = r->pitch;
+                S.raw_width = rsdim.x;
+                S.raw_height = rsdim.y;
+                //C.maximum = r->whitePoint;
+                fix_after_rawspeed(r->blackLevel);
+              }
+            free(_rawspeed_buffer);
+            _rawspeed_buffer = 0;
+            imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED_PROCESSED;
+          }
+		catch (const RawDecoderException& RDE)
+		{
+			imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED_PROBLEM;
+			if (_rawspeed_buffer)
+			{
+				free(_rawspeed_buffer);
+				_rawspeed_buffer = 0;
+			}
+			const char *p = RDE.what();
+			if (!strncmp(RDE.what(), "Decoder canceled", strlen("Decoder canceled")))
+				throw LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK;
+		}
+        catch (...)
+          {
+            // We may get here due to cancellation flag
+            imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED_PROBLEM;
+            if(_rawspeed_buffer)
+              {
+                free(_rawspeed_buffer);
+                _rawspeed_buffer = 0;
+              }
+          }
+        ID.input->seek(spos,SEEK_SET);
+      }
+#endif
+    if(!imgdata.rawdata.raw_image && !imgdata.rawdata.color4_image && !imgdata.rawdata.color3_image) //RawSpeed failed!
+      {
+        // Not allocated on RawSpeed call, try call LibRaw
+        if(decoder_info.decoder_flags &  LIBRAW_DECODER_OWNALLOC)
+          {
+            // x3f foveon decoder
+            // Do nothing! Decoder will allocate data internally
+          }
+        else if(imgdata.idata.filters || P1.colors == 1) // Bayer image or single color -> decode to raw_image
+          {
+            imgdata.rawdata.raw_alloc = malloc(rwidth*(rheight+8)*sizeof(imgdata.rawdata.raw_image[0]));
+            imgdata.rawdata.raw_image = (ushort*) imgdata.rawdata.raw_alloc;
+            if(!S.raw_pitch)
+                S.raw_pitch = S.raw_width*2; // Bayer case, not set before
+          }
+        else // NO LEGACY FLAG if (decoder_info.decoder_flags & LIBRAW_DECODER_LEGACY)
+          {
+            // sRAW and old Foveon decoders only, so extra buffer size is just 1/4
+            S.iwidth = S.width;
+            S.iheight= S.height;
+            IO.shrink = 0;
+            S.raw_pitch = S.width*8;
+            // allocate image as temporary buffer, size
+            imgdata.rawdata.raw_alloc = 0;
+            imgdata.image = (ushort (*)[4]) calloc(S.iwidth*S.iheight,sizeof(*imgdata.image));
+          }
+        ID.input->seek(libraw_internal_data.unpacker_data.data_offset, SEEK_SET);
 
-void LibRaw::free_image(void)
-{
-    if(imgdata.image)
-        {
-            free(imgdata.image);
+        unsigned m_save = C.maximum;
+        if(load_raw == &LibRaw::unpacked_load_raw && !strcasecmp(imgdata.idata.make,"Nikon"))
+          C.maximum=65535;
+        (this->*load_raw)();
+        if(load_raw == &LibRaw::unpacked_load_raw && !strcasecmp(imgdata.idata.make,"Nikon"))
+          C.maximum = m_save;
+        if(decoder_info.decoder_flags &  LIBRAW_DECODER_OWNALLOC)
+          {
+            // x3f foveon decoder only: do nothing
+
+          }
+        else if (!(imgdata.idata.filters || P1.colors == 1))
+          {
+            // successfully decoded legacy image, attach image to raw_alloc
+            imgdata.rawdata.raw_alloc = imgdata.image;
             imgdata.image = 0;
-            imgdata.progress_flags 
-                = LIBRAW_PROGRESS_START|LIBRAW_PROGRESS_OPEN
-                |LIBRAW_PROGRESS_IDENTIFY|LIBRAW_PROGRESS_SIZE_ADJUST|LIBRAW_PROGRESS_LOAD_RAW;
-        }
-}
-
-
-void LibRaw::raw2image_start()
-{
-        // restore color,sizes and internal data into raw_image fields
-        memmove(&imgdata.color,&imgdata.rawdata.color,sizeof(imgdata.color));
-        memmove(&imgdata.sizes,&imgdata.rawdata.sizes,sizeof(imgdata.sizes));
-        memmove(&imgdata.idata,&imgdata.rawdata.iparams,sizeof(imgdata.idata));
-        memmove(&libraw_internal_data.internal_output_params,&imgdata.rawdata.ioparams,sizeof(libraw_internal_data.internal_output_params));
+            // Restore saved values. Note: Foveon have masked frame
+            // Other 4-color legacy data: no borders
+            S.raw_width = S.width;
+            S.left_margin = 0;
+            S.raw_height = S.height;
+            S.top_margin = 0;
+          }
+      }
+
+    if(imgdata.rawdata.raw_image)
+      crop_masked_pixels(); // calculate black levels
+
+    // recover saved
+    if( !(imgdata.idata.filters || P1.colors == 1) && !imgdata.rawdata.color4_image)
+      {
+        imgdata.image = 0;
+        imgdata.rawdata.color4_image = (ushort (*)[4]) imgdata.rawdata.raw_alloc;
+      }
+
+    // recover image sizes
+    S.iwidth = save_iwidth;
+    S.iheight = save_iheight;
+    IO.shrink = save_shrink;
+
+    // adjust black to possible maximum
+    unsigned int i = C.cblack[3];
+    unsigned int c;
+    for(c=0;c<3;c++)
+      if (i > C.cblack[c]) i = C.cblack[c];
+    for (c=0;c<4;c++)
+      C.cblack[c] -= i;
+    C.black += i;
 
-        if (O.user_flip >= 0)
-            S.flip = O.user_flip;
-        
-        switch ((S.flip+3600) % 360) 
-            {
-            case 270:  S.flip = 5;  break;
-            case 180:  S.flip = 3;  break;
-            case  90:  S.flip = 6;  break;
-            }
+    // Save color,sizes and internal data into raw_image fields
+    memmove(&imgdata.rawdata.color,&imgdata.color,sizeof(imgdata.color));
+    memmove(&imgdata.rawdata.sizes,&imgdata.sizes,sizeof(imgdata.sizes));
+    memmove(&imgdata.rawdata.iparams,&imgdata.idata,sizeof(imgdata.idata));
+    memmove(&imgdata.rawdata.ioparams,&libraw_internal_data.internal_output_params,sizeof(libraw_internal_data.internal_output_params));
 
-        // adjust for half mode!
-        IO.shrink = P1.filters && (O.half_size ||
-                                   ((O.threshold || O.aber[0] != 1 || O.aber[2] != 1) ));
-        
-        S.iheight = (S.height + IO.shrink) >> IO.shrink;
-        S.iwidth  = (S.width  + IO.shrink) >> IO.shrink;
+    SET_PROC_FLAG(LIBRAW_PROGRESS_LOAD_RAW);
+    RUN_CALLBACK(LIBRAW_PROGRESS_LOAD_RAW,1,2);
 
-        if (O.user_black >= 0) 
-            C.black = O.user_black;
+    return 0;
+  }
+  catch ( LibRaw_exceptions err) {
+    EXCEPTION_HANDLER(err);
+  }
+  catch (std::exception ee) {
+    EXCEPTION_HANDLER(LIBRAW_EXCEPTION_IO_CORRUPT);
+  }
 }
 
-// Same as raw2image, but
-// 1) Do raw2image and rotate_fuji_raw in one pass
-// 2) Do raw2image and cropping in one pass
-#ifndef MIN
-#define MIN(a,b) ((a) < (b) ? (a) : (b))
-#endif
-int LibRaw::raw2image_ex(void)
+void LibRaw::nikon_load_sraw()
 {
-    CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);
-
-    raw2image_start();
-
-    // process cropping
-    int do_crop = 0;
-    unsigned save_filters = imgdata.idata.filters;
-    unsigned save_width = S.width;
-    if (~O.cropbox[2] && ~O.cropbox[3])
+  // We're already seeked to data!
+  unsigned char *rd = (unsigned char *)malloc(3*(imgdata.sizes.raw_width+2));
+  if(!rd) throw LIBRAW_EXCEPTION_ALLOC;
+  try {
+    int row,col;
+    for(row = 0; row < imgdata.sizes.raw_height; row++)
+      {
+        checkCancel();
+        libraw_internal_data.internal_data.input->read(rd,3,imgdata.sizes.raw_width);
+        for(col = 0; col < imgdata.sizes.raw_width-1;col+=2)
+          {
+            int bi = col*3;
+            ushort bits1 = (rd[bi+1] &0xf)<<8| rd[bi]; // 3,0,1
+            ushort bits2 = rd[bi+2] << 4 | ((rd[bi+1]>>4)& 0xf); //452
+            ushort bits3 =  ((rd[bi+4] & 0xf)<<8) | rd[bi+3]; // 967
+            ushort bits4 = rd[bi+5] << 4 | ((rd[bi+4]>>4)& 0xf); // ab8
+            imgdata.image[row*imgdata.sizes.raw_width+col][0]=bits1;
+            imgdata.image[row*imgdata.sizes.raw_width+col][1]=bits3;
+            imgdata.image[row*imgdata.sizes.raw_width+col][2]=bits4;
+            imgdata.image[row*imgdata.sizes.raw_width+col+1][0]=bits2;
+            imgdata.image[row*imgdata.sizes.raw_width+col+1][1]=2048;
+            imgdata.image[row*imgdata.sizes.raw_width+col+1][2]=2048;
+          }
+      }
+  }catch (...) {
+    free(rd);
+    throw ;
+  }
+  free(rd);
+  C.maximum = 0xfff; // 12 bit?
+  if(imgdata.params.sraw_ycc>=2)
+    {
+      return; // no CbCr interpolation
+    }
+  // Interpolate CC channels
+  int row,col;
+  for(row = 0; row < imgdata.sizes.raw_height; row++)
+    {
+      checkCancel(); // will throw out
+      for(col = 0; col < imgdata.sizes.raw_width;col+=2)
         {
-            int crop[4],c,filt;
-            for(int c=0;c<4;c++) 
-                {
-                    crop[c] = O.cropbox[c];
-                    if(crop[c]<0)
-                        crop[c]=0;
-                }
-            if(IO.fwidth) 
-                {
-                    crop[0] = (crop[0]/4)*4;
-                    crop[1] = (crop[1]/4)*4;
-                }
-            do_crop = 1;
-            crop[2] = MIN (crop[2], (signed) S.width-crop[0]);
-            crop[3] = MIN (crop[3], (signed) S.height-crop[1]);
-            if (crop[2] <= 0 || crop[3] <= 0)
-                throw LIBRAW_EXCEPTION_BAD_CROP;
-            
-            // adjust sizes!
-            S.left_margin+=crop[0];
-            S.top_margin+=crop[1];
-            S.width=crop[2];
-            S.height=crop[3];
-            
-            S.iheight = (S.height + IO.shrink) >> IO.shrink;
-            S.iwidth  = (S.width  + IO.shrink) >> IO.shrink;
-            if(!IO.fwidth && imgdata.idata.filters)
-                {
-                    for (filt=c=0; c < 16; c++)
-                        filt |= FC((c >> 1)+(crop[1]),
-                                   (c &  1)+(crop[0])) << c*2;
-                    imgdata.idata.filters = filt;
-                }
+          int col2 = col<imgdata.sizes.raw_width-2?col+2:col;
+          imgdata.image[row*imgdata.sizes.raw_width+col+1][1]
+            =(unsigned short)(int(imgdata.image[row*imgdata.sizes.raw_width+col][1]
+                                  +imgdata.image[row*imgdata.sizes.raw_width+col2][1])/2);
+          imgdata.image[row*imgdata.sizes.raw_width+col+1][2]
+            =(unsigned short)(int(imgdata.image[row*imgdata.sizes.raw_width+col][2]
+                                  +imgdata.image[row*imgdata.sizes.raw_width+col2][2])/2);
         }
+    }
+  if(imgdata.params.sraw_ycc>0)
+    return;
 
-    if(IO.fwidth) 
+  for(row = 0; row < imgdata.sizes.raw_height; row++)
+    {
+      checkCancel(); // will throw out
+      for(col = 0; col < imgdata.sizes.raw_width;col++)
         {
-            ushort fiwidth,fiheight;
-            if(do_crop)
-                {
-                    IO.fuji_width = S.width >> !libraw_internal_data.unpacker_data.fuji_layout;
-                    IO.fwidth = (S.height >> libraw_internal_data.unpacker_data.fuji_layout) + IO.fuji_width;
-                    IO.fheight = IO.fwidth - 1;
-                }
+          float Y = float(imgdata.image[row*imgdata.sizes.raw_width+col][0])/2549.f;
+          float Ch2 = float(imgdata.image[row*imgdata.sizes.raw_width+col][1]-1280)/1536.f;
+          float Ch3 = float(imgdata.image[row*imgdata.sizes.raw_width+col][2]-1280)/1536.f;
+          if(Y>1.f) Y = 1.f;
+		  if(Y>0.803f) Ch2 = Ch3 = 0.5f;
+          float r = Y + 1.40200f*(Ch3 - 0.5f);
+		  if(r<0.f) r=0.f;
+		  if(r>1.f) r=1.f;
+          float g = Y - 0.34414f*(Ch2-0.5f) - 0.71414*(Ch3 - 0.5f) ;
+		  if(g>1.f) g = 1.f;
+		  if(g<0.f) g = 0.f;
+          float b = Y + 1.77200*(Ch2-0.5f);
+		  if(b>1.f) b = 1.f;
+		  if(b<0.f) b = 0.f;
+          imgdata.image[row*imgdata.sizes.raw_width+col][0]=imgdata.color.curve[int(r*3072.f)];
+          imgdata.image[row*imgdata.sizes.raw_width+col][1]=imgdata.color.curve[int(g*3072.f)];
+          imgdata.image[row*imgdata.sizes.raw_width+col][2]=imgdata.color.curve[int(b*3072.f)];
+        }
+    }
+  C.maximum=16383;
+}
+
+void LibRaw::free_image(void)
+{
+  if(imgdata.image)
+    {
+      free(imgdata.image);
+      imgdata.image = 0;
+      imgdata.progress_flags
+        = LIBRAW_PROGRESS_START|LIBRAW_PROGRESS_OPEN
+        |LIBRAW_PROGRESS_IDENTIFY|LIBRAW_PROGRESS_SIZE_ADJUST|LIBRAW_PROGRESS_LOAD_RAW;
+    }
+}
 
-            fiheight = (IO.fheight + IO.shrink) >> IO.shrink;
-            fiwidth = (IO.fwidth + IO.shrink) >> IO.shrink;
-            if(imgdata.image)
-                    {
-                        imgdata.image = (ushort (*)[4])realloc(imgdata.image,fiheight*fiwidth*sizeof (*imgdata.image));
-                        memset(imgdata.image,0,fiheight*fiwidth *sizeof (*imgdata.image));
-                    }
-                else
-                    imgdata.image = (ushort (*)[4]) calloc (fiheight*fiwidth, sizeof (*imgdata.image));
-            merror (imgdata.image, "raw2image_ex()");
 
-            int cblk[4],i;
-            for(i=0;i<4;i++)
-                cblk[i] = C.cblack[i]+C.black;
-            ZERO(C.channel_maximum);
+void LibRaw::raw2image_start()
+{
+  // restore color,sizes and internal data into raw_image fields
+  memmove(&imgdata.color,&imgdata.rawdata.color,sizeof(imgdata.color));
+  memmove(&imgdata.sizes,&imgdata.rawdata.sizes,sizeof(imgdata.sizes));
+  memmove(&imgdata.idata,&imgdata.rawdata.iparams,sizeof(imgdata.idata));
+  memmove(&libraw_internal_data.internal_output_params,&imgdata.rawdata.ioparams,sizeof(libraw_internal_data.internal_output_params));
 
-            int row,col;
-            for(row=0;row<S.height;row++)
-                {
-                    for(col=0;col<S.width;col++)
-                        {
-                            int r,c;
-                            if (libraw_internal_data.unpacker_data.fuji_layout) {
-                                r = IO.fuji_width - 1 - col + (row >> 1);
-                                c = col + ((row+1) >> 1);
-                            } else {
-                                r = IO.fuji_width - 1 + row - (col >> 1);
-                                c = row + ((col+1) >> 1);
-                            }
-                            
-                            int val = imgdata.rawdata.raw_image[(row+S.top_margin)*S.raw_width
-                                                            +(col+S.left_margin)];
-                            int cc = FCF(row,col);
-                            if(val > cblk[cc])
-                                val -= cblk[cc];
-                            else
-                                val = 0;
-                            imgdata.image[((r) >> IO.shrink)*fiwidth + ((c) >> IO.shrink)][cc] = val;
-                            if(C.channel_maximum[cc] < val) C.channel_maximum[cc] = val;
-                        }
-                }
-            C.maximum -= C.black;
-            ZERO(C.cblack);
-            C.black = 0;
-
-            // restore fuji sizes!
-            S.height = IO.fheight;
-            S.width = IO.fwidth;
-            S.iheight = (S.height + IO.shrink) >> IO.shrink;
-            S.iwidth  = (S.width  + IO.shrink) >> IO.shrink;
-            S.raw_height -= 2*S.top_margin;
-        }
-    else
-        {
+  if (O.user_flip >= 0)
+    S.flip = O.user_flip;
 
-                if(imgdata.image)
-                    {
-                        imgdata.image = (ushort (*)[4]) realloc (imgdata.image,S.iheight*S.iwidth 
-                                                                 *sizeof (*imgdata.image));
-                        memset(imgdata.image,0,S.iheight*S.iwidth *sizeof (*imgdata.image));
-                    }
-                else
-                    imgdata.image = (ushort (*)[4]) calloc (S.iheight*S.iwidth, sizeof (*imgdata.image));
+  switch ((S.flip+3600) % 360)
+    {
+    case 270:  S.flip = 5;  break;
+    case 180:  S.flip = 3;  break;
+    case  90:  S.flip = 6;  break;
+    }
 
-                merror (imgdata.image, "raw2image_ex()");
-                
-                libraw_decoder_info_t decoder_info;
-                get_decoder_info(&decoder_info);
+  // adjust for half mode!
+  IO.shrink = P1.filters && (O.half_size ||
+                             ((O.threshold || O.aber[0] != 1 || O.aber[2] != 1) ));
 
+  S.iheight = (S.height + IO.shrink) >> IO.shrink;
+  S.iwidth  = (S.width  + IO.shrink) >> IO.shrink;
 
-                if(decoder_info.decoder_flags & LIBRAW_DECODER_FLATFIELD)
-                    {
-                        if(decoder_info.decoder_flags & LIBRAW_DECODER_USEBAYER2)
-#if defined(LIBRAW_USE_OPENMP)
-#pragma omp parallel for default(shared)
-#endif
-                            for(int row = 0; row < S.height; row++)
-                                for(int col = 0; col < S.width; col++)
-                                    imgdata.image[(row >> IO.shrink)*S.iwidth + (col>>IO.shrink)][fc(row,col)]
-                                        = imgdata.rawdata.raw_image[(row+S.top_margin)*S.raw_width
-                                                                    +(col+S.left_margin)];
-                        else
-#if defined(LIBRAW_USE_OPENMP)
-#pragma omp parallel for default(shared)
-#endif
-                            for(int row = 0; row < S.height; row++)
-                                {
-                                    int colors[2];
-                                    for (int xx=0;xx<2;xx++)
-                                        colors[xx] = COLOR(row,xx);
-                                    for(int col = 0; col < S.width; col++)
-                                        {
-                                            int cc = colors[col&1];
-                                            imgdata.image[(row >> IO.shrink)*S.iwidth + (col>>IO.shrink)][cc] =
-                                                imgdata.rawdata.raw_image[(row+S.top_margin)*S.raw_width
-                                                                          +(col+S.left_margin)];
-                                        }
-                                }
-                    }
-                else if (decoder_info.decoder_flags & LIBRAW_DECODER_4COMPONENT)
-                    {
-#define FC0(row,col) (save_filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)
-                        if(IO.shrink)
-#if defined(LIBRAW_USE_OPENMP)
-#pragma omp parallel for default(shared)
-#endif
-                            for(int row = 0; row < S.height; row++)
-                                for(int col = 0; col < S.width; col++)
-                                    imgdata.image[(row >> IO.shrink)*S.iwidth + (col>>IO.shrink)][FC(row,col)] 
-                                        = imgdata.rawdata.color_image[(row+S.top_margin)*S.raw_width
-                                                                      +S.left_margin+col]
-                                        [FC0(row+S.top_margin,col+S.left_margin)];
-#undef FC0
-                        else
-#if defined(LIBRAW_USE_OPENMP)
-#pragma omp parallel for default(shared)
-#endif
-                            for(int row = 0; row < S.height; row++)
-                                memmove(&imgdata.image[row*S.width],
-                                        &imgdata.rawdata.color_image[(row+S.top_margin)*S.raw_width+S.left_margin],
-                                        S.width*sizeof(*imgdata.image));
-                    }
-                else if(decoder_info.decoder_flags & LIBRAW_DECODER_LEGACY)
-                    {
-                        if(do_crop)
-#if defined(LIBRAW_USE_OPENMP)
-#pragma omp parallel for default(shared)
-#endif
-                            for(int row = 0; row < S.height; row++)
-                                memmove(&imgdata.image[row*S.width],
-                                        &imgdata.rawdata.color_image[(row+S.top_margin)*save_width+S.left_margin],
-                                        S.width*sizeof(*imgdata.image));
-                                
-                        else 
-                            memmove(imgdata.image,imgdata.rawdata.color_image,
-                                    S.width*S.height*sizeof(*imgdata.image));
-                    }
+}
 
-                if(imgdata.rawdata.use_ph1_correct) // Phase one unpacked!
-                        phase_one_correct();
-            }
-    return LIBRAW_SUCCESS;
+int LibRaw::is_phaseone_compressed()
+{
+  return (load_raw == &LibRaw::phase_one_load_raw_c || load_raw == &LibRaw::phase_one_load_raw);
 }
 
-#undef MIN
+int LibRaw::raw2image(void)
+{
 
+  CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);
 
+  try {
+    raw2image_start();
 
+    if (is_phaseone_compressed())
+      {
+        phase_one_allocate_tempbuffer();
+        phase_one_subtract_black((ushort*)imgdata.rawdata.raw_alloc,imgdata.rawdata.raw_image);
+        phase_one_correct();
+      }
 
-int LibRaw::raw2image(void)
-{
+    // free and re-allocate image bitmap
+    if(imgdata.image)
+      {
+        imgdata.image = (ushort (*)[4]) realloc (imgdata.image,S.iheight*S.iwidth *sizeof (*imgdata.image));
+        memset(imgdata.image,0,S.iheight*S.iwidth *sizeof (*imgdata.image));
+      }
+    else
+      imgdata.image = (ushort (*)[4]) calloc (S.iheight*S.iwidth, sizeof (*imgdata.image));
 
-    CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);
+    merror (imgdata.image, "raw2image()");
 
-    try {
-        raw2image_start();
+    libraw_decoder_info_t decoder_info;
+    get_decoder_info(&decoder_info);
 
-        // free and re-allocate image bitmap
-        if(imgdata.image)
-            {
-                imgdata.image = (ushort (*)[4]) realloc (imgdata.image,S.iheight*S.iwidth *sizeof (*imgdata.image));
-                memset(imgdata.image,0,S.iheight*S.iwidth *sizeof (*imgdata.image));
+    // Move saved bitmap to imgdata.image
+    if( imgdata.idata.filters || P1.colors == 1)
+      {
+        if (IO.fuji_width) {
+          unsigned r,c;
+          int row,col;
+          for (row=0; row < S.raw_height-S.top_margin*2; row++) {
+            for (col=0; col < IO.fuji_width << !libraw_internal_data.unpacker_data.fuji_layout; col++) {
+              if (libraw_internal_data.unpacker_data.fuji_layout) {
+                r = IO.fuji_width - 1 - col + (row >> 1);
+                c = col + ((row+1) >> 1);
+              } else {
+                r = IO.fuji_width - 1 + row - (col >> 1);
+                c = row + ((col+1) >> 1);
+              }
+              if (r < S.height && c < S.width)
+                imgdata.image[((r)>>IO.shrink)*S.iwidth+((c)>>IO.shrink)][FC(r,c)]
+                  = imgdata.rawdata.raw_image[(row+S.top_margin)*S.raw_pitch/2+(col+S.left_margin)];
             }
+          }
+        }
+        else {
+          int row,col;
+          for (row=0; row < S.height; row++)
+            for (col=0; col < S.width; col++)
+              imgdata.image[((row) >> IO.shrink)*S.iwidth + ((col) >> IO.shrink)][fcol(row,col)]
+                = imgdata.rawdata.raw_image[(row+S.top_margin)*S.raw_pitch/2+(col+S.left_margin)];
+        }
+      }
+    else // if(decoder_info.decoder_flags & LIBRAW_DECODER_LEGACY)
+      {
+        if(imgdata.rawdata.color4_image)
+          {
+            if(S.width*8 == S.raw_pitch)
+              memmove(imgdata.image,imgdata.rawdata.color4_image,S.width*S.height*sizeof(*imgdata.image));
+            else
+              {
+                for(int row = 0; row < S.height; row++)
+                  memmove(&imgdata.image[row*S.width],
+                          &imgdata.rawdata.color4_image[(row+S.top_margin)*S.raw_pitch/8+S.left_margin],
+                          S.width*sizeof(*imgdata.image));
+              }
+          }
+        else if(imgdata.rawdata.color3_image)
+          {
+            unsigned char *c3image = (unsigned char*) imgdata.rawdata.color3_image;
+            for(int row = 0; row < S.height; row++)
+              {
+                ushort (*srcrow)[3] = (ushort (*)[3]) &c3image[(row+S.top_margin)*S.raw_pitch];
+                ushort (*dstrow)[4] = (ushort (*)[4]) &imgdata.image[row*S.width];
+                for(int col=0; col < S.width; col++)
+                  {
+                    for(int c=0; c< 3; c++)
+                      dstrow[col][c] = srcrow[S.left_margin+col][c];
+                    dstrow[col][3]=0;
+                  }
+              }
+          }
         else
-            imgdata.image = (ushort (*)[4]) calloc (S.iheight*S.iwidth, sizeof (*imgdata.image));
+          {
+            // legacy decoder, but no data?
+            throw LIBRAW_EXCEPTION_DECODE_RAW;
+          }
+      }
+
+    // Free PhaseOne separate copy allocated at function start
+    if (is_phaseone_compressed())
+      {
+        phase_one_free_tempbuffer();
+      }
+    // hack - clear later flags!
+
+    if (load_raw == &CLASS canon_600_load_raw && S.width < S.raw_width)
+      {
+        canon_600_correct();
+      }
+
+    imgdata.progress_flags
+      = LIBRAW_PROGRESS_START|LIBRAW_PROGRESS_OPEN | LIBRAW_PROGRESS_RAW2_IMAGE
+      |LIBRAW_PROGRESS_IDENTIFY|LIBRAW_PROGRESS_SIZE_ADJUST|LIBRAW_PROGRESS_LOAD_RAW;
+    return 0;
+  }
+  catch ( LibRaw_exceptions err) {
+    EXCEPTION_HANDLER(err);
+  }
+}
+
+void LibRaw::phase_one_allocate_tempbuffer()
+{
+  // Allocate temp raw_image buffer
+  imgdata.rawdata.raw_image = (ushort*)malloc(S.raw_pitch*S.raw_height);
+  merror (imgdata.rawdata.raw_image, "phase_one_prepare_to_correct()");
+}
+void LibRaw::phase_one_free_tempbuffer()
+{
+	free(imgdata.rawdata.raw_image);
+	imgdata.rawdata.raw_image = (ushort*) imgdata.rawdata.raw_alloc;
+}
 
-        merror (imgdata.image, "raw2image()");
+int LibRaw::phase_one_subtract_black(ushort *src, ushort *dest)
+{
 
-        libraw_decoder_info_t decoder_info;
-        get_decoder_info(&decoder_info);
-        
-        // Move saved bitmap to imgdata.image
-        if(decoder_info.decoder_flags & LIBRAW_DECODER_FLATFIELD)
+  try
+    {
+      if (O.user_black < 0 && O.user_cblack[0] <= -1000000 && O.user_cblack[1] <= -1000000 && O.user_cblack[2] <= -1000000 && O.user_cblack[3] <= -1000000)
+        {
+          if (!imgdata.rawdata.ph1_cblack || !imgdata.rawdata.ph1_rblack)
             {
-                if(decoder_info.decoder_flags & LIBRAW_DECODER_USEBAYER2)
-                    {
-                        for(int row = 0; row < S.height; row++)
-                            for(int col = 0; col < S.width; col++)
-                                imgdata.image[(row >> IO.shrink)*S.iwidth + (col>>IO.shrink)][fc(row,col)]
-                                = imgdata.rawdata.raw_image[(row+S.top_margin)*S.raw_width
-                                                                           +(col+S.left_margin)];
-                    }
-                else
+              register int bl = imgdata.color.phase_one_data.t_black;
+              for (int row = 0; row < S.raw_height; row++)
+                {
+                  checkCancel();
+                  for (int col = 0; col < S.raw_width; col++)
                     {
-                        for(int row = 0; row < S.height; row++)
-                            {
-                                int colors[4];
-                                for (int xx=0;xx<4;xx++)
-                                    colors[xx] = COLOR(row,xx);
-                                for(int col = 0; col < S.width; col++)
-                                    {
-                                        int cc = colors[col&3];
-                                        imgdata.image[(row >> IO.shrink)*S.iwidth + (col>>IO.shrink)][cc] =
-                                            imgdata.rawdata.raw_image[(row+S.top_margin)*S.raw_width+(col
-                                                                                                      +S.left_margin)];
-                                    }
-                            }
+                      int idx = row*S.raw_width + col;
+                      int val = int(src[idx]) - bl;
+                      dest[idx] = val>0 ? val : 0;
                     }
+                }
             }
-        else if (decoder_info.decoder_flags & LIBRAW_DECODER_4COMPONENT)
+          else
             {
-                if(IO.shrink)
+              register int bl = imgdata.color.phase_one_data.t_black;
+              for (int row = 0; row < S.raw_height; row++)
+                {
+                  checkCancel();
+                  for (int col = 0; col < S.raw_width; col++)
                     {
-                        for(int row = 0; row < S.height; row++)
-                            for(int col = 0; col < S.width; col++)
-                                {
-                                    int cc = FC(row,col);
-                                    imgdata.image[(row >> IO.shrink)*S.iwidth + (col>>IO.shrink)][cc] 
-                                        = imgdata.rawdata.color_image[(row+S.top_margin)*S.raw_width
-                                                                      +S.left_margin+col][cc];
-                                }
+                      int idx = row*S.raw_width + col;
+                      int val = int(src[idx]) - bl
+                      + imgdata.rawdata.ph1_cblack[row][col >= imgdata.rawdata.color.phase_one_data.split_col]
+                        + imgdata.rawdata.ph1_rblack[col][row >= imgdata.rawdata.color.phase_one_data.split_row];
+                      dest[idx] = val>0 ? val : 0;
                     }
-                else
-                    for(int row = 0; row < S.height; row++)
-                        memmove(&imgdata.image[row*S.width],
-                                &imgdata.rawdata.color_image[(row+S.top_margin)*S.raw_width+S.left_margin],
-                                S.width*sizeof(*imgdata.image));
+                }
             }
-        else if(decoder_info.decoder_flags & LIBRAW_DECODER_LEGACY)
+        }
+      else // black set by user interaction
+        {
+          // Black level in cblack!
+          for (int row = 0; row < S.raw_height; row++)
             {
-                // legacy is always 4channel and not shrinked!
-                memmove(imgdata.image,imgdata.rawdata.color_image,S.width*S.height*sizeof(*imgdata.image));
+              checkCancel();
+              unsigned short cblk[16];
+              for (int cc = 0; cc < 16; cc++)
+                cblk[cc] = C.cblack[fcol(row, cc)];
+              for (int col = 0; col < S.raw_width; col++)
+                {
+                  int idx = row*S.raw_width + col;
+                  ushort val = src[idx];
+                  ushort bl = cblk[col & 0xf];
+                  dest[idx] = val>bl ? val - bl : 0;
+                }
             }
-
-        if(imgdata.rawdata.use_ph1_correct) // Phase one unpacked!
-            phase_one_correct();
-
-        // hack - clear later flags!
-        imgdata.progress_flags 
-            = LIBRAW_PROGRESS_START|LIBRAW_PROGRESS_OPEN
-            |LIBRAW_PROGRESS_IDENTIFY|LIBRAW_PROGRESS_SIZE_ADJUST|LIBRAW_PROGRESS_LOAD_RAW;
-        return 0;
-    }
-    catch ( LibRaw_exceptions err) {
-        EXCEPTION_HANDLER(err);
+        }
+      return 0;
     }
+  catch (LibRaw_exceptions err) {
+    return LIBRAW_CANCELLED_BY_CALLBACK;
+  }
 }
-    
 
-int LibRaw::dcraw_document_mode_processing(void)
+void LibRaw::copy_fuji_uncropped(unsigned short cblack[4],unsigned short *dmaxp)
 {
-//    CHECK_ORDER_HIGH(LIBRAW_PROGRESS_PRE_INTERPOLATE);
-    CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);
-
-    try {
-
-        int no_crop = 1;
-
-        if (~O.cropbox[2] && ~O.cropbox[3])
-            no_crop=0;
-
-        raw2image_ex(); // raw2image+crop+rotate_fuji_raw
-
-        if (IO.zero_is_bad)
-            {
-                remove_zeroes();
-                SET_PROC_FLAG(LIBRAW_PROGRESS_REMOVE_ZEROES);
-            }
-
-        if(!IO.fuji_width)
-            subtract_black();
-        
-        O.document_mode = 2;
-        
-        if(P1.is_foveon)
+  int row;
+#if defined(LIBRAW_USE_OPENMP)
+#pragma omp parallel for default(shared)
+#endif
+  for (row=0; row < S.raw_height-S.top_margin*2; row++)
+    {
+      int col;
+      unsigned short ldmax = 0;
+      for (col=0; col < IO.fuji_width << !libraw_internal_data.unpacker_data.fuji_layout; col++)
+        {
+          unsigned r,c;
+          if (libraw_internal_data.unpacker_data.fuji_layout) {
+            r = IO.fuji_width - 1 - col + (row >> 1);
+            c = col + ((row+1) >> 1);
+          } else {
+            r = IO.fuji_width - 1 + row - (col >> 1);
+            c = row + ((col+1) >> 1);
+          }
+          if (r < S.height && c < S.width)
             {
-                // filter image data for foveon document mode
-                short *iptr = (short *)imgdata.image;
-                for (int i=0; i < S.height*S.width*4; i++)
-                    {
-                        if ((short) iptr[i] < 0) 
-                            iptr[i] = 0;
-                    }
-                SET_PROC_FLAG(LIBRAW_PROGRESS_FOVEON_INTERPOLATE);
+              unsigned short val = imgdata.rawdata.raw_image[(row+S.top_margin)*S.raw_pitch/2+(col+S.left_margin)];
+              int cc = FC(r,c);
+              if(val>cblack[cc])
+                {
+                  val-=cblack[cc];
+                  if(val>ldmax)ldmax = val;
+                }
+              else
+                val = 0;
+              imgdata.image[((r)>>IO.shrink)*S.iwidth+((c)>>IO.shrink)][cc] = val;
             }
+        }
+#if defined(LIBRAW_USE_OPENMP)
+#pragma omp critical(dataupdate)
+#endif
+      {
+        if(*dmaxp < ldmax)
+          *dmaxp = ldmax;
+      }
+    }
+}
 
-        O.use_fuji_rotate = 0;
+void LibRaw::copy_bayer(unsigned short cblack[4],unsigned short *dmaxp)
+{
+  // Both cropped and uncropped
+  int row;
 
-        if(O.bad_pixels && no_crop) 
-            {
-                bad_pixels(O.bad_pixels);
-                SET_PROC_FLAG(LIBRAW_PROGRESS_BAD_PIXELS);
-            }
-        if (O.dark_frame && no_crop)
+#if defined(LIBRAW_USE_OPENMP)
+#pragma omp parallel for default(shared)
+#endif
+  for (row=0; row < S.height; row++)
+    {
+      int col;
+      unsigned short ldmax = 0;
+      for (col=0; col < S.width; col++)
+        {
+          unsigned short val = imgdata.rawdata.raw_image[(row+S.top_margin)*S.raw_pitch/2+(col+S.left_margin)];
+          int cc = fcol(row,col);
+          if(val>cblack[cc])
             {
-                subtract (O.dark_frame);
-                SET_PROC_FLAG(LIBRAW_PROGRESS_DARK_FRAME);
+              val-=cblack[cc];
+              if(val>ldmax)ldmax = val;
             }
+          else
+            val = 0;
+          imgdata.image[((row) >> IO.shrink)*S.iwidth + ((col) >> IO.shrink)][cc] = val;
+        }
+#if defined(LIBRAW_USE_OPENMP)
+#pragma omp critical(dataupdate)
+#endif
+      {
+        if(*dmaxp < ldmax)
+          *dmaxp = ldmax;
+      }
+    }
+}
 
 
-        adjust_maximum();
-
-        if (O.user_sat > 0) 
-            C.maximum = O.user_sat;
+int LibRaw::raw2image_ex(int do_subtract_black)
+{
 
-        pre_interpolate();
-        SET_PROC_FLAG(LIBRAW_PROGRESS_PRE_INTERPOLATE);
+  CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);
 
-        if (libraw_internal_data.internal_output_params.mix_green)
-            {
-                int i;
-                for (P1.colors=3, i=0; i < S.height*S.width; i++)
-                    imgdata.image[i][1] = (imgdata.image[i][1] + imgdata.image[i][3]) >> 1;
-            }
-        SET_PROC_FLAG(LIBRAW_PROGRESS_MIX_GREEN);
+  try {
+    raw2image_start();
 
-        if (!P1.is_foveon && P1.colors == 3) 
-            median_filter();
-        SET_PROC_FLAG(LIBRAW_PROGRESS_MEDIAN_FILTER);
+    // Compressed P1 files with bl data!
+    if (is_phaseone_compressed())
+      {
+        phase_one_allocate_tempbuffer();
+        phase_one_subtract_black((ushort*)imgdata.rawdata.raw_alloc,imgdata.rawdata.raw_image);
+        phase_one_correct();
+      }
 
-        if (!P1.is_foveon && O.highlight == 2) 
-            blend_highlights();
+    // process cropping
+    int do_crop = 0;
+    unsigned save_width = S.width;
+    if (~O.cropbox[2] && ~O.cropbox[3]
+#ifdef LIBRAW_DEMOSAIC_PACK_GPL2
+        && load_raw != &LibRaw::foveon_sd_load_raw
+#endif
+        ) // Foveon SD to be cropped later
+      {
+        int crop[4],c,filt;
+        for(int c=0;c<4;c++)
+          {
+            crop[c] = O.cropbox[c];
+            if(crop[c]<0)
+              crop[c]=0;
+          }
+
+        if(IO.fuji_width && imgdata.idata.filters >= 1000)
+          {
+            crop[0] = (crop[0]/4)*4;
+            crop[1] = (crop[1]/4)*4;
+            if(!libraw_internal_data.unpacker_data.fuji_layout)
+              {
+                crop[2]*=sqrt(2.0);
+                crop[3]/=sqrt(2.0);
+              }
+            crop[2] = (crop[2]/4+1)*4;
+            crop[3] = (crop[3]/4+1)*4;
+          }
+        else if (imgdata.idata.filters == 1)
+          {
+            crop[0] = (crop[0]/16)*16;
+            crop[1] = (crop[1]/16)*16;
+          }
+        else if(imgdata.idata.filters == LIBRAW_XTRANS)
+          {
+            crop[0] = (crop[0]/6)*6;
+            crop[1] = (crop[1]/6)*6;
+          }
+        do_crop = 1;
+
+        crop[2] = MIN (crop[2], (signed) S.width-crop[0]);
+        crop[3] = MIN (crop[3], (signed) S.height-crop[1]);
+        if (crop[2] <= 0 || crop[3] <= 0)
+          throw LIBRAW_EXCEPTION_BAD_CROP;
+
+        // adjust sizes!
+        S.left_margin+=crop[0];
+        S.top_margin+=crop[1];
+        S.width=crop[2];
+        S.height=crop[3];
 
-        if (!P1.is_foveon && O.highlight > 2) 
-            recover_highlights();
-        SET_PROC_FLAG(LIBRAW_PROGRESS_HIGHLIGHTS);
+        S.iheight = (S.height + IO.shrink) >> IO.shrink;
+        S.iwidth  = (S.width  + IO.shrink) >> IO.shrink;
+        if(!IO.fuji_width && imgdata.idata.filters && imgdata.idata.filters >= 1000)
+          {
+            for (filt=c=0; c < 16; c++)
+              filt |= FC((c >> 1)+(crop[1]),
+                         (c &  1)+(crop[0])) << c*2;
+            imgdata.idata.filters = filt;
+          }
+      }
+
+    int alloc_width = S.iwidth;
+    int alloc_height = S.iheight;
+
+    if(IO.fuji_width && do_crop)
+      {
+        int IO_fw = S.width >> !libraw_internal_data.unpacker_data.fuji_layout;
+        int t_alloc_width = (S.height >> libraw_internal_data.unpacker_data.fuji_layout) + IO_fw;
+        int t_alloc_height = t_alloc_width - 1;
+        alloc_height = (t_alloc_height + IO.shrink) >> IO.shrink;
+        alloc_width = (t_alloc_width + IO.shrink) >> IO.shrink;
+      }
+    int alloc_sz = alloc_width*alloc_height;
 
-        if (O.use_fuji_rotate) 
-            fuji_rotate();
-        SET_PROC_FLAG(LIBRAW_PROGRESS_FUJI_ROTATE);
-#ifndef NO_LCMS
-	if(O.camera_profile)
-            {
-                apply_profile(O.camera_profile,O.output_profile);
-                SET_PROC_FLAG(LIBRAW_PROGRESS_APPLY_PROFILE);
-            }
-#endif
-        if(!libraw_internal_data.output_data.histogram)
-            {
-                libraw_internal_data.output_data.histogram = (int (*)[LIBRAW_HISTOGRAM_SIZE]) malloc(sizeof(*libraw_internal_data.output_data.histogram)*4);
-                merror(libraw_internal_data.output_data.histogram,"LibRaw::dcraw_document_mode_processing()");
-            }
-        convert_to_rgb();
-        SET_PROC_FLAG(LIBRAW_PROGRESS_CONVERT_RGB);
+    if(imgdata.image)
+      {
+        imgdata.image = (ushort (*)[4]) realloc (imgdata.image,alloc_sz *sizeof (*imgdata.image));
+        memset(imgdata.image,0,alloc_sz *sizeof (*imgdata.image));
+      }
+    else
+      imgdata.image = (ushort (*)[4]) calloc (alloc_sz, sizeof (*imgdata.image));
+    merror (imgdata.image, "raw2image_ex()");
 
-        if (O.use_fuji_rotate)
-            stretch();
-        SET_PROC_FLAG(LIBRAW_PROGRESS_STRETCH);
+    libraw_decoder_info_t decoder_info;
+    get_decoder_info(&decoder_info);
 
-        return 0;
-    }
-    catch ( LibRaw_exceptions err) {
-        EXCEPTION_HANDLER(err);
-    }
+    // Adjust black levels
+    unsigned short cblack[4]={0,0,0,0};
+    unsigned short dmax = 0;
+    if(do_subtract_black)
+      {
+        adjust_bl();
+        for(int i=0; i< 4; i++)
+          cblack[i] = (unsigned short)C.cblack[i];
+      }
+
+    // Move saved bitmap to imgdata.image
+    if(imgdata.idata.filters || P1.colors == 1)
+      {
+        if (IO.fuji_width)
+          {
+            if(do_crop)
+              {
+                IO.fuji_width = S.width >> !libraw_internal_data.unpacker_data.fuji_layout;
+                int IO_fwidth = (S.height >> libraw_internal_data.unpacker_data.fuji_layout) + IO.fuji_width;
+                int IO_fheight = IO_fwidth - 1;
+
+                int row,col;
+                for(row=0;row<S.height;row++)
+                  {
+                    for(col=0;col<S.width;col++)
+                      {
+                        int r,c;
+                        if (libraw_internal_data.unpacker_data.fuji_layout) {
+                          r = IO.fuji_width - 1 - col + (row >> 1);
+                          c = col + ((row+1) >> 1);
+                        } else {
+                          r = IO.fuji_width - 1 + row - (col >> 1);
+                          c = row + ((col+1) >> 1);
+                        }
 
+                        unsigned short val = imgdata.rawdata.raw_image[(row+S.top_margin)*S.raw_pitch/2
+                                                            +(col+S.left_margin)];
+                        int cc = FCF(row,col);
+                        if(val > cblack[cc])
+                          {
+                            val-=cblack[cc];
+                            if(dmax < val) dmax = val;
+                          }
+                        else
+                          val = 0;
+                        imgdata.image[((r) >> IO.shrink)*alloc_width + ((c) >> IO.shrink)][cc] = val;
+                      }
+                  }
+                S.height = IO_fheight;
+                S.width = IO_fwidth;
+                S.iheight = (S.height + IO.shrink) >> IO.shrink;
+                S.iwidth  = (S.width  + IO.shrink) >> IO.shrink;
+                S.raw_height -= 2*S.top_margin;
+              }
+            else
+              {
+                copy_fuji_uncropped(cblack,&dmax);
+              }
+          } // end Fuji
+        else
+          {
+            copy_bayer(cblack,&dmax);
+          }
+      }
+    else //if(decoder_info.decoder_flags & LIBRAW_DECODER_LEGACY)
+      {
+        if(imgdata.rawdata.color4_image)
+          {
+            if(S.raw_pitch != S.width*8)
+              {
+                for(int row = 0; row < S.height; row++)
+                  memmove(&imgdata.image[row*S.width],
+                          &imgdata.rawdata.color4_image[(row+S.top_margin)*S.raw_pitch/8+S.left_margin],
+                          S.width*sizeof(*imgdata.image));
+              }
+            else
+              {
+                // legacy is always 4channel and not shrinked!
+                memmove(imgdata.image,imgdata.rawdata.color4_image,S.width*S.height*sizeof(*imgdata.image));
+              }
+          }
+        else if(imgdata.rawdata.color3_image)
+          {
+            unsigned char *c3image = (unsigned char*) imgdata.rawdata.color3_image;
+            for(int row = 0; row < S.height; row++)
+              {
+                ushort (*srcrow)[3] = (ushort (*)[3]) &c3image[(row+S.top_margin)*S.raw_pitch];
+                ushort (*dstrow)[4] = (ushort (*)[4]) &imgdata.image[row*S.width];
+                for(int col=0; col < S.width; col++)
+                  {
+                    for(int c=0; c< 3; c++)
+                      dstrow[col][c] = srcrow[S.left_margin+col][c];
+                    dstrow[col][3]=0;
+                  }
+              }
+          }
+        else
+          {
+            // legacy decoder, but no data?
+            throw LIBRAW_EXCEPTION_DECODE_RAW;
+          }
+      }
+
+    // Free PhaseOne separate copy allocated at function start
+    if (is_phaseone_compressed())
+      {
+		  phase_one_free_tempbuffer();
+      }
+    if (load_raw == &CLASS canon_600_load_raw && S.width < S.raw_width)
+      {
+        canon_600_correct();
+      }
+
+    if(do_subtract_black)
+      {
+        C.data_maximum = (int)dmax;
+        C.maximum -= C.black;
+        //        ZERO(C.cblack);
+        C.cblack[0]=C.cblack[1]=C.cblack[2]=C.cblack[3]=0;
+        C.black = 0;
+      }
+
+    // hack - clear later flags!
+    imgdata.progress_flags
+      = LIBRAW_PROGRESS_START|LIBRAW_PROGRESS_OPEN | LIBRAW_PROGRESS_RAW2_IMAGE
+      |LIBRAW_PROGRESS_IDENTIFY|LIBRAW_PROGRESS_SIZE_ADJUST|LIBRAW_PROGRESS_LOAD_RAW;
+    return 0;
+  }
+  catch ( LibRaw_exceptions err) {
+    EXCEPTION_HANDLER(err);
+  }
 }
 
 #if 1
 
 libraw_processed_image_t * LibRaw::dcraw_make_mem_thumb(int *errcode)
 {
-    if(!T.thumb)
+  if(!T.thumb)
+    {
+      if ( !ID.toffset)
         {
-            if ( !ID.toffset) 
-                {
-                    if(errcode) *errcode= LIBRAW_NO_THUMBNAIL;
-                }
-            else
-                {
-                    if(errcode) *errcode= LIBRAW_OUT_OF_ORDER_CALL;
-                }
-            return NULL;
+          if(errcode) *errcode= LIBRAW_NO_THUMBNAIL;
         }
-
-    if (T.tformat == LIBRAW_THUMBNAIL_BITMAP)
+      else
         {
-            libraw_processed_image_t * ret = 
-                (libraw_processed_image_t *)::malloc(sizeof(libraw_processed_image_t)+T.tlength);
+          if(errcode) *errcode= LIBRAW_OUT_OF_ORDER_CALL;
+        }
+      return NULL;
+    }
 
-            if(!ret)
-                {
-                    if(errcode) *errcode= ENOMEM;
-                    return NULL;
-                }
+  if (T.tformat == LIBRAW_THUMBNAIL_BITMAP)
+    {
+      libraw_processed_image_t * ret =
+        (libraw_processed_image_t *)::malloc(sizeof(libraw_processed_image_t)+T.tlength);
 
-            memset(ret,0,sizeof(libraw_processed_image_t));
-            ret->type   = LIBRAW_IMAGE_BITMAP;
-            ret->height = T.theight;
-            ret->width  = T.twidth;
-            ret->colors = 3; 
-            ret->bits   = 8;
-            ret->data_size = T.tlength;
-            memmove(ret->data,T.thumb,T.tlength);
-            if(errcode) *errcode= 0;
-            return ret;
-        }
-    else if (T.tformat == LIBRAW_THUMBNAIL_JPEG)
+      if(!ret)
         {
-            ushort exif[5];
-            int mk_exif = 0;
-            if(strcmp(T.thumb+6,"Exif")) mk_exif = 1;
-            
-            int dsize = T.tlength + mk_exif * (sizeof(exif)+sizeof(tiff_hdr));
+          if(errcode) *errcode= ENOMEM;
+          return NULL;
+        }
 
-            libraw_processed_image_t * ret = 
-                (libraw_processed_image_t *)::malloc(sizeof(libraw_processed_image_t)+dsize);
+      memset(ret,0,sizeof(libraw_processed_image_t));
+      ret->type   = LIBRAW_IMAGE_BITMAP;
+      ret->height = T.theight;
+      ret->width  = T.twidth;
+      ret->colors = 3;
+      ret->bits   = 8;
+      ret->data_size = T.tlength;
+      memmove(ret->data,T.thumb,T.tlength);
+      if(errcode) *errcode= 0;
+      return ret;
+    }
+  else if (T.tformat == LIBRAW_THUMBNAIL_JPEG)
+    {
+      ushort exif[5];
+      int mk_exif = 0;
+      if(strcmp(T.thumb+6,"Exif")) mk_exif = 1;
 
-            if(!ret)
-                {
-                    if(errcode) *errcode= ENOMEM;
-                    return NULL;
-                }
+      int dsize = T.tlength + mk_exif * (sizeof(exif)+sizeof(tiff_hdr));
 
-            memset(ret,0,sizeof(libraw_processed_image_t));
+      libraw_processed_image_t * ret =
+        (libraw_processed_image_t *)::malloc(sizeof(libraw_processed_image_t)+dsize);
 
-            ret->type = LIBRAW_IMAGE_JPEG;
-            ret->data_size = dsize;
-            
-            ret->data[0] = 0xff;
-            ret->data[1] = 0xd8;
-            if(mk_exif)
-                {
-                    struct tiff_hdr th;
-                    memcpy (exif, "\xff\xe1  Exif\0\0", 10);
-                    exif[1] = htons (8 + sizeof th);
-                    memmove(ret->data+2,exif,sizeof(exif));
-                    tiff_head (&th, 0);
-                    memmove(ret->data+(2+sizeof(exif)),&th,sizeof(th));
-                    memmove(ret->data+(2+sizeof(exif)+sizeof(th)),T.thumb+2,T.tlength-2);
-                }
-            else
-                {
-                    memmove(ret->data+2,T.thumb+2,T.tlength-2);
-                }
-            if(errcode) *errcode= 0;
-            return ret;
-            
-        }
-    else
+      if(!ret)
         {
-            if(errcode) *errcode= LIBRAW_UNSUPPORTED_THUMBNAIL;
-            return NULL;
+          if(errcode) *errcode= ENOMEM;
+          return NULL;
+        }
+
+      memset(ret,0,sizeof(libraw_processed_image_t));
+
+      ret->type = LIBRAW_IMAGE_JPEG;
+      ret->data_size = dsize;
 
+      ret->data[0] = 0xff;
+      ret->data[1] = 0xd8;
+      if(mk_exif)
+        {
+          struct tiff_hdr th;
+          memcpy (exif, "\xff\xe1  Exif\0\0", 10);
+          exif[1] = htons (8 + sizeof th);
+          memmove(ret->data+2,exif,sizeof(exif));
+          tiff_head (&th, 0);
+          memmove(ret->data+(2+sizeof(exif)),&th,sizeof(th));
+          memmove(ret->data+(2+sizeof(exif)+sizeof(th)),T.thumb+2,T.tlength-2);
+        }
+      else
+        {
+          memmove(ret->data+2,T.thumb+2,T.tlength-2);
         }
+      if(errcode) *errcode= 0;
+      return ret;
+
+    }
+  else
+    {
+      if(errcode) *errcode= LIBRAW_UNSUPPORTED_THUMBNAIL;
+      return NULL;
+    }
 }
 
 
@@ -1454,16 +2262,16 @@ libraw_processed_image_t * LibRaw::dcraw_make_mem_thumb(int *errcode)
 void LibRaw::get_mem_image_format(int* width, int* height, int* colors, int* bps) const
 
 {
-    if (S.flip & 4) {
-        *width = S.height;
-        *height = S.width;
-    }
-    else {
-        *width = S.width;
-        *height = S.height;
-    }
-    *colors = P1.colors;
-    *bps = O.output_bps;
+  if (S.flip & 4) {
+    *width = S.height;
+    *height = S.width;
+  }
+  else {
+    *width = S.width;
+    *height = S.height;
+  }
+  *colors = P1.colors;
+  *bps = O.output_bps;
 }
 
 int LibRaw::copy_mem_image(void* scan0, int stride, int bgr)
@@ -1474,18 +2282,18 @@ int LibRaw::copy_mem_image(void* scan0, int stride, int bgr)
         return LIBRAW_OUT_OF_ORDER_CALL;
 
     if(libraw_internal_data.output_data.histogram)
-        {
-            int perc, val, total, t_white=0x2000,c;
-            perc = S.width * S.height * 0.01;        /* 99th percentile white level */
-            if (IO.fuji_width) perc /= 2;
-            if (!((O.highlight & ~2) || O.no_auto_bright))
-                for (t_white=c=0; c < P1.colors; c++) {
-                    for (val=0x2000, total=0; --val > 32; )
-                        if ((total += libraw_internal_data.output_data.histogram[c][val]) > perc) break;
-                    if (t_white < val) t_white = val;
-                }
-             gamma_curve (O.gamm[0], O.gamm[1], 2, (t_white << 3)/O.bright);
-        }
+      {
+        int perc, val, total, t_white=0x2000,c;
+        perc = S.width * S.height * O.auto_bright_thr;
+        if (IO.fuji_width) perc /= 2;
+        if (!((O.highlight & ~2) || O.no_auto_bright))
+          for (t_white=c=0; c < P1.colors; c++) {
+            for (val=0x2000, total=0; --val > 32; )
+              if ((total += libraw_internal_data.output_data.histogram[c][val]) > perc) break;
+            if (t_white < val) t_white = val;
+          }
+        gamma_curve (O.gamm[0], O.gamm[1], 2, (t_white << 3)/O.bright);
+      }
 
     int s_iheight = S.iheight;
     int s_iwidth = S.iwidth;
@@ -1504,35 +2312,35 @@ int LibRaw::copy_mem_image(void* scan0, int stride, int bgr)
     cstep = flip_index (0, 1) - soff;
     rstep = flip_index (1, 0) - flip_index (0, S.width);
 
-    for (row=0; row < S.height; row++, soff += rstep) 
-        {
-            uchar *bufp = ((uchar*)scan0)+row*stride;
-            ppm2 = (ushort*) (ppm = bufp);
-            // keep trivial decisions in the outer loop for speed
-            if (bgr) {
-                if (O.output_bps == 8) {
-                    for (col=0; col < S.width; col++, soff += cstep) 
-                        FORBGR *ppm++ = imgdata.color.curve[imgdata.image[soff][c]]>>8;
-                }
-                else {
-                    for (col=0; col < S.width; col++, soff += cstep) 
-                        FORBGR *ppm2++ = imgdata.color.curve[imgdata.image[soff][c]];
-                }
-            }
-            else {
-                if (O.output_bps == 8) {
-                    for (col=0; col < S.width; col++, soff += cstep) 
-                        FORRGB *ppm++ = imgdata.color.curve[imgdata.image[soff][c]]>>8;
-                }
-                else {
-                    for (col=0; col < S.width; col++, soff += cstep) 
-                        FORRGB *ppm2++ = imgdata.color.curve[imgdata.image[soff][c]];
-                }
-            }
+    for (row=0; row < S.height; row++, soff += rstep)
+      {
+        uchar *bufp = ((uchar*)scan0)+row*stride;
+        ppm2 = (ushort*) (ppm = bufp);
+        // keep trivial decisions in the outer loop for speed
+        if (bgr) {
+          if (O.output_bps == 8) {
+            for (col=0; col < S.width; col++, soff += cstep)
+              FORBGR *ppm++ = imgdata.color.curve[imgdata.image[soff][c]]>>8;
+          }
+          else {
+            for (col=0; col < S.width; col++, soff += cstep)
+              FORBGR *ppm2++ = imgdata.color.curve[imgdata.image[soff][c]];
+          }
+        }
+        else {
+          if (O.output_bps == 8) {
+            for (col=0; col < S.width; col++, soff += cstep)
+              FORRGB *ppm++ = imgdata.color.curve[imgdata.image[soff][c]]>>8;
+          }
+          else {
+            for (col=0; col < S.width; col++, soff += cstep)
+              FORRGB *ppm2++ = imgdata.color.curve[imgdata.image[soff][c]];
+          }
+        }
 
 //            bufp += stride;           // go to the next line
-        }
- 
+      }
+
     S.iheight = s_iheight;
     S.iwidth = s_iwidth;
     S.width = s_width;
@@ -1545,7 +2353,7 @@ int LibRaw::copy_mem_image(void* scan0, int stride, int bgr)
 #undef FORBGR
 #undef FORRGB
 
- 
+
 
 libraw_processed_image_t *LibRaw::dcraw_make_mem_image(int *errcode)
 
@@ -1569,7 +2377,7 @@ libraw_processed_image_t *LibRaw::dcraw_make_mem_image(int *errcode)
     ret->colors = colors;
     ret->bits   = bps;
     ret->data_size = ds;
-    copy_mem_image(ret->data, stride, 0); 
+    copy_mem_image(ret->data, stride, 0);
 
     return ret;
 }
@@ -1582,199 +2390,225 @@ libraw_processed_image_t *LibRaw::dcraw_make_mem_image(int *errcode)
 
 int LibRaw::dcraw_ppm_tiff_writer(const char *filename)
 {
-    CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);
-
-    if(!imgdata.image) 
-        return LIBRAW_OUT_OF_ORDER_CALL;
-
-    if(!filename) 
-        return ENOENT;
-    FILE *f = fopen(filename,"wb");
-
-    if(!f) 
-        return errno;
-
-    try {
-        if(!libraw_internal_data.output_data.histogram)
-            {
-                libraw_internal_data.output_data.histogram = 
-                    (int (*)[LIBRAW_HISTOGRAM_SIZE]) malloc(sizeof(*libraw_internal_data.output_data.histogram)*4);
-                merror(libraw_internal_data.output_data.histogram,"LibRaw::dcraw_ppm_tiff_writer()");
-            }
-        libraw_internal_data.internal_data.output = f;
-        write_ppm_tiff();
-        SET_PROC_FLAG(LIBRAW_PROGRESS_FLIP);
-        libraw_internal_data.internal_data.output = NULL;
-        fclose(f);
-        return 0;
-    }
-    catch ( LibRaw_exceptions err) {
-        fclose(f);
-        EXCEPTION_HANDLER(err);
-    }
+  CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);
+
+  if(!imgdata.image)
+    return LIBRAW_OUT_OF_ORDER_CALL;
+
+  if(!filename)
+    return ENOENT;
+  FILE *f = fopen(filename,"wb");
+
+  if(!f)
+    return errno;
+
+  try {
+    if(!libraw_internal_data.output_data.histogram)
+      {
+        libraw_internal_data.output_data.histogram =
+          (int (*)[LIBRAW_HISTOGRAM_SIZE]) malloc(sizeof(*libraw_internal_data.output_data.histogram)*4);
+        merror(libraw_internal_data.output_data.histogram,"LibRaw::dcraw_ppm_tiff_writer()");
+      }
+    libraw_internal_data.internal_data.output = f;
+    write_ppm_tiff();
+    SET_PROC_FLAG(LIBRAW_PROGRESS_FLIP);
+    libraw_internal_data.internal_data.output = NULL;
+    fclose(f);
+    return 0;
+  }
+  catch ( LibRaw_exceptions err) {
+    fclose(f);
+    EXCEPTION_HANDLER(err);
+  }
 }
 
 void LibRaw::kodak_thumb_loader()
 {
-    // some kodak cameras
-    ushort s_height = S.height, s_width = S.width,s_iwidth = S.iwidth,s_iheight=S.iheight;
-    int s_colors = P1.colors;
-    unsigned s_filters = P1.filters;
-    ushort (*s_image)[4] = imgdata.image;
-
-    
-    S.height = T.theight;
-    S.width  = T.twidth;
-    P1.filters = 0;
-
-    if (thumb_load_raw == &CLASS kodak_ycbcr_load_thumb) 
-        {
-            S.height += S.height & 1;
-            S.width  += S.width  & 1;
-        }
-    
-    imgdata.image = (ushort (*)[4]) calloc (S.iheight*S.iwidth, sizeof (*imgdata.image));
-    merror (imgdata.image, "LibRaw::kodak_thumb_loader()");
+  // some kodak cameras
+  ushort s_height = S.height, s_width = S.width,s_iwidth = S.iwidth,s_iheight=S.iheight;
+  ushort s_flags = libraw_internal_data.unpacker_data.load_flags;
+  libraw_internal_data.unpacker_data.load_flags = 12;
+  int s_colors = P1.colors;
+  unsigned s_filters = P1.filters;
+  ushort (*s_image)[4] = imgdata.image;
 
-    ID.input->seek(ID.toffset, SEEK_SET);
-    // read kodak thumbnail into T.image[]
-    (this->*thumb_load_raw)();
 
-    // copy-n-paste from image pipe
-#define MIN(a,b) ((a) < (b) ? (a) : (b))
-#define MAX(a,b) ((a) > (b) ? (a) : (b))
-#define LIM(x,min,max) MAX(min,MIN(x,max))
-#define CLIP(x) LIM(x,0,65535)
-#define SWAP(a,b) { a ^= b; a ^= (b ^= a); }
+  S.height = T.theight;
+  S.width  = T.twidth;
+  P1.filters = 0;
 
-    // from scale_colors
+  if (thumb_load_raw == &CLASS kodak_ycbcr_load_raw)
     {
-        double   dmax;
-        float scale_mul[4];
-        int c,val;
-        for (dmax=DBL_MAX, c=0; c < 3; c++) 
-                if (dmax > C.pre_mul[c])
-                    dmax = C.pre_mul[c];
-
-        for( c=0; c< 3; c++)
-                scale_mul[c] = (C.pre_mul[c] / dmax) * 65535.0 / C.maximum;
-        scale_mul[3] = scale_mul[1];
-
-        size_t size = S.height * S.width;
-        for (unsigned i=0; i < size*4 ; i++) 
-            {
-                val = imgdata.image[0][i];
-                if(!val) continue;
-                val *= scale_mul[i & 3];
-                imgdata.image[0][i] = CLIP(val);
-            }
+      S.height += S.height & 1;
+      S.width  += S.width  & 1;
     }
 
-    // from convert_to_rgb
-    ushort *img;
-    int row,col;
-    
-    int  (*t_hist)[LIBRAW_HISTOGRAM_SIZE] =  (int (*)[LIBRAW_HISTOGRAM_SIZE]) calloc(sizeof(*t_hist),4);
-    merror (t_hist, "LibRaw::kodak_thumb_loader()");
-    
-    float out[3], 
-        out_cam[3][4] = 
-        {
-            {2.81761312, -1.98369181, 0.166078627, 0}, 
-            {-0.111855984, 1.73688626, -0.625030339, 0}, 
-            {-0.0379119813, -0.891268849, 1.92918086, 0}
-        };
-
-    for (img=imgdata.image[0], row=0; row < S.height; row++)
-        for (col=0; col < S.width; col++, img+=4)
-            {
-                out[0] = out[1] = out[2] = 0;
-                int c;
-                for(c=0;c<3;c++) 
-                    {
-                        out[0] += out_cam[0][c] * img[c];
-                        out[1] += out_cam[1][c] * img[c];
-                        out[2] += out_cam[2][c] * img[c];
-                    }
-                for(c=0; c<3; c++)
-                    img[c] = CLIP((int) out[c]);
-                for(c=0; c<P1.colors;c++)
-                    t_hist[c][img[c] >> 3]++;
-                    
-            }
-
-    // from gamma_lut
-    int  (*save_hist)[LIBRAW_HISTOGRAM_SIZE] = libraw_internal_data.output_data.histogram;
-    libraw_internal_data.output_data.histogram = t_hist;
-
-    // make curve output curve!
-    ushort (*t_curve) = (ushort*) calloc(sizeof(C.curve),1);
-    merror (t_curve, "LibRaw::kodak_thumb_loader()");
-    memmove(t_curve,C.curve,sizeof(C.curve));
-    memset(C.curve,0,sizeof(C.curve));
-        {
-            int perc, val, total, t_white=0x2000,c;
-
-            perc = S.width * S.height * 0.01;		/* 99th percentile white level */
-            if (IO.fuji_width) perc /= 2;
-            if (!((O.highlight & ~2) || O.no_auto_bright))
-                for (t_white=c=0; c < P1.colors; c++) {
-                    for (val=0x2000, total=0; --val > 32; )
-                        if ((total += libraw_internal_data.output_data.histogram[c][val]) > perc) break;
-                    if (t_white < val) t_white = val;
-                }
-            gamma_curve (O.gamm[0], O.gamm[1], 2, (t_white << 3)/O.bright);
-        }
-    
-    libraw_internal_data.output_data.histogram = save_hist;
-    free(t_hist);
-    
-    // from write_ppm_tiff - copy pixels into bitmap
-    
-    S.iheight = S.height;
-    S.iwidth  = S.width;
-    if (S.flip & 4) SWAP(S.height,S.width);
+  imgdata.image = (ushort (*)[4]) calloc (S.iheight*S.iwidth, sizeof (*imgdata.image));
+  merror (imgdata.image, "LibRaw::kodak_thumb_loader()");
 
-    if(T.thumb) free(T.thumb);
-    T.thumb = (char*) calloc (S.width * S.height, P1.colors);
-    merror (T.thumb, "LibRaw::kodak_thumb_loader()");
-    T.tlength = S.width * S.height * P1.colors;
+  ID.input->seek(ID.toffset, SEEK_SET);
+  // read kodak thumbnail into T.image[]
+  try {
+	  (this->*thumb_load_raw)();
+  } catch (...)
+  {
+	  free(imgdata.image);
+	  imgdata.image  = s_image;
 
-    // from write_tiff_ppm
-    {
-        int soff  = flip_index (0, 0);
-        int cstep = flip_index (0, 1) - soff;
-        int rstep = flip_index (1, 0) - flip_index (0, S.width);
-        
-        for (int row=0; row < S.height; row++, soff += rstep) 
-            {
-                char *ppm = T.thumb + row*S.width*P1.colors;
-                for (int col=0; col < S.width; col++, soff += cstep)
-                    for(int c = 0; c < P1.colors; c++)
-                        ppm [col*P1.colors+c] = imgdata.color.curve[imgdata.image[soff][c]]>>8;
-            }
-    }
+	  T.twidth = 0;
+	  S.width = s_width;
 
-    memmove(C.curve,t_curve,sizeof(C.curve));
-    free(t_curve);
+	  S.iwidth = s_iwidth;
+	  S.iheight = s_iheight;
 
-    // restore variables
-    free(imgdata.image);
-    imgdata.image  = s_image;
-    
-    T.twidth = S.width;
-    S.width = s_width;
+	  T.theight = 0;
+	  S.height = s_height;
 
-    S.iwidth = s_iwidth;
-    S.iheight = s_iheight;
+	  T.tcolors = 0;
+	  P1.colors = s_colors;
 
-    T.theight = S.height;
-    S.height = s_height;
+	  P1.filters = s_filters;
+	  T.tlength=0;
+	  libraw_internal_data.unpacker_data.load_flags = s_flags;
+	  return;
+  }
 
-    T.tcolors = P1.colors;
-    P1.colors = s_colors;
+  // copy-n-paste from image pipe
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+#define LIM(x,min,max) MAX(min,MIN(x,max))
+#define CLIP(x) LIM(x,0,65535)
+#define SWAP(a,b) { a ^= b; a ^= (b ^= a); }
 
-    P1.filters = s_filters;
+  // from scale_colors
+  {
+    double   dmax;
+    float scale_mul[4];
+    int c,val;
+    for (dmax=DBL_MAX, c=0; c < 3; c++)
+      if (dmax > C.pre_mul[c])
+        dmax = C.pre_mul[c];
+
+    for( c=0; c< 3; c++)
+      scale_mul[c] = (C.pre_mul[c] / dmax) * 65535.0 / C.maximum;
+    scale_mul[3] = scale_mul[1];
+
+    size_t size = S.height * S.width;
+    for (unsigned i=0; i < size*4 ; i++)
+      {
+        val = imgdata.image[0][i];
+        if(!val) continue;
+        val *= scale_mul[i & 3];
+        imgdata.image[0][i] = CLIP(val);
+      }
+  }
+
+  // from convert_to_rgb
+  ushort *img;
+  int row,col;
+
+  int  (*t_hist)[LIBRAW_HISTOGRAM_SIZE] =  (int (*)[LIBRAW_HISTOGRAM_SIZE]) calloc(sizeof(*t_hist),4);
+  merror (t_hist, "LibRaw::kodak_thumb_loader()");
+
+  float out[3],
+    out_cam[3][4] =
+    {
+      {2.81761312, -1.98369181, 0.166078627, 0},
+      {-0.111855984, 1.73688626, -0.625030339, 0},
+      {-0.0379119813, -0.891268849, 1.92918086, 0}
+    };
+
+  for (img=imgdata.image[0], row=0; row < S.height; row++)
+    for (col=0; col < S.width; col++, img+=4)
+      {
+        out[0] = out[1] = out[2] = 0;
+        int c;
+        for(c=0;c<3;c++)
+          {
+            out[0] += out_cam[0][c] * img[c];
+            out[1] += out_cam[1][c] * img[c];
+            out[2] += out_cam[2][c] * img[c];
+          }
+        for(c=0; c<3; c++)
+          img[c] = CLIP((int) out[c]);
+        for(c=0; c<P1.colors;c++)
+          t_hist[c][img[c] >> 3]++;
+
+      }
+
+  // from gamma_lut
+  int  (*save_hist)[LIBRAW_HISTOGRAM_SIZE] = libraw_internal_data.output_data.histogram;
+  libraw_internal_data.output_data.histogram = t_hist;
+
+  // make curve output curve!
+  ushort (*t_curve) = (ushort*) calloc(sizeof(C.curve),1);
+  merror (t_curve, "LibRaw::kodak_thumb_loader()");
+  memmove(t_curve,C.curve,sizeof(C.curve));
+  memset(C.curve,0,sizeof(C.curve));
+  {
+    int perc, val, total, t_white=0x2000,c;
+
+    perc = S.width * S.height * 0.01;		/* 99th percentile white level */
+    if (IO.fuji_width) perc /= 2;
+    if (!((O.highlight & ~2) || O.no_auto_bright))
+      for (t_white=c=0; c < P1.colors; c++) {
+        for (val=0x2000, total=0; --val > 32; )
+          if ((total += libraw_internal_data.output_data.histogram[c][val]) > perc) break;
+        if (t_white < val) t_white = val;
+      }
+    gamma_curve (O.gamm[0], O.gamm[1], 2, (t_white << 3)/O.bright);
+  }
+
+  libraw_internal_data.output_data.histogram = save_hist;
+  free(t_hist);
+
+  // from write_ppm_tiff - copy pixels into bitmap
+
+  S.iheight = S.height;
+  S.iwidth  = S.width;
+  if (S.flip & 4) SWAP(S.height,S.width);
+
+  if(T.thumb) free(T.thumb);
+  T.thumb = (char*) calloc (S.width * S.height, P1.colors);
+  merror (T.thumb, "LibRaw::kodak_thumb_loader()");
+  T.tlength = S.width * S.height * P1.colors;
+
+  // from write_tiff_ppm
+  {
+    int soff  = flip_index (0, 0);
+    int cstep = flip_index (0, 1) - soff;
+    int rstep = flip_index (1, 0) - flip_index (0, S.width);
+
+    for (int row=0; row < S.height; row++, soff += rstep)
+      {
+        char *ppm = T.thumb + row*S.width*P1.colors;
+        for (int col=0; col < S.width; col++, soff += cstep)
+          for(int c = 0; c < P1.colors; c++)
+            ppm [col*P1.colors+c] = imgdata.color.curve[imgdata.image[soff][c]]>>8;
+      }
+  }
+
+  memmove(C.curve,t_curve,sizeof(C.curve));
+  free(t_curve);
+
+  // restore variables
+  free(imgdata.image);
+  imgdata.image  = s_image;
+
+  T.twidth = S.width;
+  S.width = s_width;
+
+  S.iwidth = s_iwidth;
+  S.iheight = s_iheight;
+
+  T.theight = S.height;
+  S.height = s_height;
+
+  T.tcolors = P1.colors;
+  P1.colors = s_colors;
+
+  P1.filters = s_filters;
+  libraw_internal_data.unpacker_data.load_flags = s_flags;
 }
 #undef MIN
 #undef MAX
@@ -1783,75 +2617,103 @@ void LibRaw::kodak_thumb_loader()
 #undef SWAP
 
 
-
-
-// ������� thumbnail �� �����, ������ thumb_format � ������������ � ��������
+// ������� thumbnail �� �����, ������ thumb_format � ������������ � ��������
 int LibRaw::unpack_thumb(void)
 {
-    CHECK_ORDER_LOW(LIBRAW_PROGRESS_IDENTIFY);
-    CHECK_ORDER_BIT(LIBRAW_PROGRESS_THUMB_LOAD);
-
-    try {
-        if ( !ID.toffset) 
-            {
-                return LIBRAW_NO_THUMBNAIL;
-            } 
-        else if (thumb_load_raw) 
-            {
-                kodak_thumb_loader();
-                T.tformat = LIBRAW_THUMBNAIL_BITMAP;
-                SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
-                return 0;
-            } 
-        else 
-            {
-                ID.input->seek(ID.toffset, SEEK_SET);
-                if ( write_thumb == &LibRaw::jpeg_thumb)
-                    {
-                        if(T.thumb) free(T.thumb);
-                        T.thumb = (char *) malloc (T.tlength);
-                        merror (T.thumb, "jpeg_thumb()");
-                        ID.input->read (T.thumb, 1, T.tlength);
-                        T.tcolors = 3;
-                        T.tformat = LIBRAW_THUMBNAIL_JPEG;
-                        SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
-                        return 0;
-                    }
-                else if (write_thumb == &LibRaw::ppm_thumb)
-                    {
-                        T.tlength = T.twidth * T.theight*3;
-                        if(T.thumb) free(T.thumb);
-
-                        T.thumb = (char *) malloc (T.tlength);
-                        merror (T.thumb, "ppm_thumb()");
-
-                        ID.input->read(T.thumb, 1, T.tlength);
-
-                        T.tformat = LIBRAW_THUMBNAIL_BITMAP;
-                        SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
-                        return 0;
-
-                    }
-                else if (write_thumb == &LibRaw::foveon_thumb)
-                    {
-                        foveon_thumb_loader();
-                        // may return with error, so format is set in
-                        // foveon thumb loader itself
-                        SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
-                        return 0;
-                    }
-                // else if -- all other write_thumb cases!
-                else
-                    {
-                        return LIBRAW_UNSUPPORTED_THUMBNAIL;
-                    }
-            }
-        // last resort
-        return LIBRAW_UNSUPPORTED_THUMBNAIL;
-    }
-    catch ( LibRaw_exceptions err) {
-        EXCEPTION_HANDLER(err);
-    }
+  CHECK_ORDER_LOW(LIBRAW_PROGRESS_IDENTIFY);
+  CHECK_ORDER_BIT(LIBRAW_PROGRESS_THUMB_LOAD);
+
+  try {
+    if(!libraw_internal_data.internal_data.input)
+      return LIBRAW_INPUT_CLOSED;
+
+    if ( !ID.toffset)
+      {
+        return LIBRAW_NO_THUMBNAIL;
+      }
+    else if (thumb_load_raw)
+      {
+        kodak_thumb_loader();
+        T.tformat = LIBRAW_THUMBNAIL_BITMAP;
+        SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
+        return 0;
+      }
+    else
+      {
+        ID.input->seek(ID.toffset, SEEK_SET);
+        if ( write_thumb == &LibRaw::jpeg_thumb)
+          {
+            if(T.thumb) free(T.thumb);
+            T.thumb = (char *) malloc (T.tlength);
+            merror (T.thumb, "jpeg_thumb()");
+            ID.input->read (T.thumb, 1, T.tlength);
+            T.tcolors = 3;
+            T.tformat = LIBRAW_THUMBNAIL_JPEG;
+            SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
+            return 0;
+          }
+        else if (write_thumb == &LibRaw::ppm_thumb)
+          {
+            T.tlength = T.twidth * T.theight*3;
+            if(T.thumb) free(T.thumb);
+
+            T.thumb = (char *) malloc (T.tlength);
+            merror (T.thumb, "ppm_thumb()");
+
+            ID.input->read(T.thumb, 1, T.tlength);
+
+            T.tformat = LIBRAW_THUMBNAIL_BITMAP;
+            SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
+            return 0;
+
+          }
+        else if (write_thumb == &LibRaw::ppm16_thumb)
+          {
+            T.tlength = T.twidth * T.theight*3;
+            ushort *t_thumb = (ushort*)calloc(T.tlength,2);
+            ID.input->read(t_thumb,2,T.tlength);
+            if ((libraw_internal_data.unpacker_data.order == 0x4949) == (ntohs(0x1234) == 0x1234))
+              swab ((char*)t_thumb, (char*)t_thumb, T.tlength*2);
+
+            if(T.thumb) free(T.thumb);
+            T.thumb = (char *) malloc (T.tlength);
+            merror (T.thumb, "ppm_thumb()");
+            for (int i=0; i < T.tlength; i++)
+              T.thumb[i] = t_thumb[i] >> 8;
+            free(t_thumb);
+            T.tformat = LIBRAW_THUMBNAIL_BITMAP;
+            SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
+            return 0;
+
+          }
+        else if (write_thumb == &LibRaw::x3f_thumb_loader)
+          {
+            x3f_thumb_loader();
+            SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
+            return 0;
+          }
+#ifdef LIBRAW_DEMOSAIC_PACK_GPL2
+        else if (write_thumb == &LibRaw::foveon_thumb)
+          {
+            foveon_thumb_loader();
+            // may return with error, so format is set in
+            // foveon thumb loader itself
+            SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
+            return 0;
+          }
+        // else if -- all other write_thumb cases!
+#endif
+        else
+          {
+            return LIBRAW_UNSUPPORTED_THUMBNAIL;
+          }
+      }
+    // last resort
+    return LIBRAW_UNSUPPORTED_THUMBNAIL;
+  }
+  catch ( LibRaw_exceptions err) {
+    EXCEPTION_HANDLER(err);
+  }
 
 }
 
@@ -1859,428 +2721,590 @@ int LibRaw::dcraw_thumb_writer(const char *fname)
 {
 //    CHECK_ORDER_LOW(LIBRAW_PROGRESS_THUMB_LOAD);
 
-    if(!fname) 
-        return ENOENT;
-        
-    FILE *tfp = fopen(fname,"wb");
-    
-    if(!tfp) 
-        return errno;
+  if(!fname)
+    return ENOENT;
 
-    if(!T.thumb)
-	{
-		fclose(tfp);
-        	return LIBRAW_OUT_OF_ORDER_CALL;
-	}
+  FILE *tfp = fopen(fname,"wb");
 
-    try {
-        switch (T.tformat)
-            {
-            case LIBRAW_THUMBNAIL_JPEG:
-                jpeg_thumb_writer (tfp,T.thumb,T.tlength);
-                break;
-            case LIBRAW_THUMBNAIL_BITMAP:
-                fprintf (tfp, "P6\n%d %d\n255\n", T.twidth, T.theight);
-                fwrite (T.thumb, 1, T.tlength, tfp);
-                break;
-            default:
-                fclose(tfp);
-                return LIBRAW_UNSUPPORTED_THUMBNAIL;
-           }
-        fclose(tfp);
-        return 0;
+  if(!tfp)
+    return errno;
+
+  if(!T.thumb)
+    {
+      fclose(tfp);
+      return LIBRAW_OUT_OF_ORDER_CALL;
     }
-    catch ( LibRaw_exceptions err) {
+
+  try {
+    switch (T.tformat)
+      {
+      case LIBRAW_THUMBNAIL_JPEG:
+        jpeg_thumb_writer (tfp,T.thumb,T.tlength);
+        break;
+      case LIBRAW_THUMBNAIL_BITMAP:
+        fprintf (tfp, "P6\n%d %d\n255\n", T.twidth, T.theight);
+        fwrite (T.thumb, 1, T.tlength, tfp);
+        break;
+      default:
         fclose(tfp);
-        EXCEPTION_HANDLER(err);
-    }
+        return LIBRAW_UNSUPPORTED_THUMBNAIL;
+      }
+    fclose(tfp);
+    return 0;
+  }
+  catch ( LibRaw_exceptions err) {
+    fclose(tfp);
+    EXCEPTION_HANDLER(err);
+  }
 }
 
 int LibRaw::adjust_sizes_info_only(void)
 {
-    CHECK_ORDER_LOW(LIBRAW_PROGRESS_IDENTIFY);
+  CHECK_ORDER_LOW(LIBRAW_PROGRESS_IDENTIFY);
 
-    raw2image_start();
-    if (O.use_fuji_rotate)
+  raw2image_start();
+  if (O.use_fuji_rotate)
+    {
+      if (IO.fuji_width)
         {
-            if (IO.fuji_width) 
-                {
-                    // restore saved values
-                    if(IO.fheight)
-                        {
-                            S.height = IO.fheight;
-                            S.width = IO.fwidth;
-                            S.iheight = (S.height + IO.shrink) >> IO.shrink;
-                            S.iwidth  = (S.width  + IO.shrink) >> IO.shrink;
-                            S.raw_height -= 2*S.top_margin;
-                            IO.fheight = IO.fwidth = 0; // prevent repeated calls
-                        }
-                    // dcraw code
-                    IO.fuji_width = (IO.fuji_width - 1 + IO.shrink) >> IO.shrink;
-                    S.iwidth = (ushort)(IO.fuji_width / sqrt(0.5));
-                    S.iheight = (ushort)( (S.iheight - IO.fuji_width) / sqrt(0.5));
-                } 
-            else 
-                {
-                    if (S.pixel_aspect < 1) S.iheight = (ushort)( S.iheight / S.pixel_aspect + 0.5);
-                    if (S.pixel_aspect > 1) S.iwidth  = (ushort) (S.iwidth  * S.pixel_aspect + 0.5);
-                }
+          IO.fuji_width = (IO.fuji_width - 1 + IO.shrink) >> IO.shrink;
+          S.iwidth = (ushort)(IO.fuji_width / sqrt(0.5));
+          S.iheight = (ushort)( (S.iheight - IO.fuji_width) / sqrt(0.5));
         }
-    SET_PROC_FLAG(LIBRAW_PROGRESS_FUJI_ROTATE);
-    if ( S.flip & 4)
+      else
         {
-            unsigned short t = S.iheight;
-            S.iheight=S.iwidth;
-            S.iwidth = t;
-            SET_PROC_FLAG(LIBRAW_PROGRESS_FLIP);
+          if (S.pixel_aspect < 0.995) S.iheight = (ushort)( S.iheight / S.pixel_aspect + 0.5);
+          if (S.pixel_aspect > 1.005) S.iwidth  = (ushort) (S.iwidth  * S.pixel_aspect + 0.5);
         }
+    }
+  SET_PROC_FLAG(LIBRAW_PROGRESS_FUJI_ROTATE);
+  if ( S.flip & 4)
+    {
+      unsigned short t = S.iheight;
+      S.iheight=S.iwidth;
+      S.iwidth = t;
+      SET_PROC_FLAG(LIBRAW_PROGRESS_FLIP);
+    }
+  return 0;
+}
+
+int LibRaw::subtract_black()
+{
+  adjust_bl();
+  return subtract_black_internal();
+}
+
+int LibRaw::subtract_black_internal()
+{
+  CHECK_ORDER_LOW(LIBRAW_PROGRESS_RAW2_IMAGE);
+
+  try {
+    if(!is_phaseone_compressed() && (C.cblack[0] || C.cblack[1] || C.cblack[2] || C.cblack[3] || (C.cblack[4] && C.cblack[5]) ))
+      {
+#define BAYERC(row,col,c) imgdata.image[((row) >> IO.shrink)*S.iwidth + ((col) >> IO.shrink)][c]
+        int cblk[4],i;
+        for(i=0;i<4;i++)
+          cblk[i] = C.cblack[i];
+
+        int size = S.iheight * S.iwidth;
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+#define LIM(x,min,max) MAX(min,MIN(x,max))
+#define CLIP(x) LIM(x,0,65535)
+        int dmax = 0;
+        if(C.cblack[4] && C.cblack[5])
+          {
+            for(i=0; i< size*4; i++)
+              {
+                int val = imgdata.image[0][i];
+                val -= C.cblack[6 + i/4 / S.iwidth % C.cblack[4] * C.cblack[5] +
+			i/4 % S.iwidth % C.cblack[5]];
+                val -= cblk[i & 3];
+                imgdata.image[0][i] = CLIP(val);
+                if(dmax < val) dmax = val;
+              }
+          }
+        else
+          {
+            for(i=0; i< size*4; i++)
+              {
+                int val = imgdata.image[0][i];
+                val -= cblk[i & 3];
+                imgdata.image[0][i] = CLIP(val);
+                if(dmax < val) dmax = val;
+              }
+          }
+        C.data_maximum = dmax & 0xffff;
+#undef MIN
+#undef MAX
+#undef LIM
+#undef CLIP
+        C.maximum -= C.black;
+        ZERO(C.cblack); // Yeah, we used cblack[6+] values too!
+        C.black = 0;
+#undef BAYERC
+      }
+    else
+      {
+        // Nothing to Do, maximum is already calculated, black level is 0, so no change
+        // only calculate channel maximum;
+        int idx;
+        ushort *p = (ushort*)imgdata.image;
+        int dmax = 0;
+        for(idx=0;idx<S.iheight*S.iwidth*4;idx++)
+          if(dmax < p[idx]) dmax = p[idx];
+        C.data_maximum = dmax;
+      }
     return 0;
+  }
+  catch ( LibRaw_exceptions err) {
+    EXCEPTION_HANDLER(err);
+  }
+
 }
 
+#define TBLN 65535
 
-void LibRaw::subtract_black()
+void LibRaw::exp_bef(float shift, float smooth)
 {
+  // params limits
+  if(shift>8) shift = 8;
+  if(shift<0.25) shift = 0.25;
+  if(smooth < 0.0) smooth = 0.0;
+  if(smooth > 1.0) smooth = 1.0;
 
-#define BAYERC(row,col,c) imgdata.image[((row) >> IO.shrink)*S.iwidth + ((col) >> IO.shrink)][c] 
+  unsigned short *lut = (ushort*)malloc((TBLN+1)*sizeof(unsigned short));
 
-    if(C.ph1_black)
+  if(shift <=1.0)
+    {
+      for(int i=0;i<=TBLN;i++)
+        lut[i] = (unsigned short)((float)i*shift);
+    }
+  else
+    {
+      float x1,x2,y1,y2;
+
+      float cstops = log(shift)/log(2.0f);
+      float room = cstops*2;
+      float roomlin = powf(2.0f,room);
+      x2 = (float)TBLN;
+      x1 = (x2+1)/roomlin-1;
+      y1 = x1*shift;
+      y2 = x2*(1+(1-smooth)*(shift-1));
+      float sq3x=powf(x1*x1*x2,1.0f/3.0f);
+      float B = (y2-y1+shift*(3*x1-3.0f*sq3x)) / (x2+2.0f*x1-3.0f*sq3x);
+      float A = (shift - B)*3.0f*powf(x1*x1,1.0f/3.0f);
+      float CC = y2 - A*powf(x2,1.0f/3.0f)-B*x2;
+      for(int i=0;i<=TBLN;i++)
         {
-            // Phase One compressed format
-            int row,col,val,cc;
-            for(row=0;row<S.height;row++)
-                for(col=0;col<S.width;col++)
-                    {
-                        cc=FC(row,col);
-                        val = BAYERC(row,col,cc) 
-                            - C.phase_one_data.t_black 
-                            + C.ph1_black[row+S.top_margin][(col + S.left_margin) 
-                                                                                >=C.phase_one_data.split_col];
-                        if(val<0) val = 0;
-                        BAYERC(row,col,cc) = val;
-                    }
-            C.maximum -= C.black;
-            phase_one_correct();
-            // recalculate channel maximum
-            ZERO(C.channel_maximum);
-            for(row=0;row<S.height;row++)
-                for(col=0;col<S.width;col++)
-                    {
-                        cc=FC(row,col);
-                        val = BAYERC(row,col,cc);
-                        if(C.channel_maximum[cc] > val) C.channel_maximum[cc] = val;
-                    }
-            // clear P1 black level data
-            imgdata.color.phase_one_data.t_black = 0;
-            C.ph1_black = 0;
-            ZERO(C.cblack);
-            C.black = 0;
+          float X = (float)i;
+          float Y = A*powf(X,1.0f/3.0f)+B*X+CC;
+          if(i<x1)
+            lut[i] = (unsigned short)((float)i*shift);
+          else
+            lut[i] = Y<0?0:(Y>TBLN?TBLN:(unsigned short)(Y));
         }
-    else if((C.black || C.cblack[0] || C.cblack[1] || C.cblack[2] || C.cblack[3]))
-        {
-            int cblk[4],i,row,col,val,cc;
-            for(i=0;i<4;i++)
-                cblk[i] = C.cblack[i]+C.black;
-            ZERO(C.channel_maximum);
+    }
+  for(int i=0; i< S.height*S.width; i++)
+    {
+      imgdata.image[i][0] = lut[imgdata.image[i][0]];
+      imgdata.image[i][1] = lut[imgdata.image[i][1]];
+      imgdata.image[i][2] = lut[imgdata.image[i][2]];
+      imgdata.image[i][3] = lut[imgdata.image[i][3]];
+    }
 
-            for(row=0;row<S.height;row++)
-                for(col=0;col<S.width;col++)
-                    {
-                        cc=COLOR(row,col);
-                        val = BAYERC(row,col,cc);
-                        if(val > cblk[cc])
-                            val -= cblk[cc];
-                        else
-                            val = 0;
-                        if(C.channel_maximum[cc] < val) C.channel_maximum[cc] = val;
-                        BAYERC(row,col,cc) = val;
-                    }
-            C.maximum -= C.black;
-            ZERO(C.cblack);
-            C.black = 0;
-        }
-    else
-        {
-            // only calculate channel maximum;
-            int row,col,cc,val;
-            ZERO(C.channel_maximum);
-            for(row=0;row<S.height;row++)
-                for(col=0;col<S.width;col++)
-                    for(cc = 0; cc< 4; cc++)
-                        {
-                            int val = BAYERC(row,col,cc);
-                            if(C.channel_maximum[cc] < val) C.channel_maximum[cc] = val;
-                        }
-            
-        }
+  if(C.data_maximum <=TBLN)
+    C.data_maximum = lut[C.data_maximum];
+  if(C.maximum <= TBLN)
+    C.maximum = lut[C.maximum];
+  // no need to adjust the minumum, black is already subtracted
+  free(lut);
 }
 
-#define TBLN 65535
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+#define LIM(x,min,max) MAX(min,MIN(x,max))
+#define ULIM(x,y,z) ((y) < (z) ? LIM(x,y,z) : LIM(x,z,y))
+#define CLIP(x) LIM(x,0,65535)
 
-void LibRaw::exp_bef(float shift, float smooth)
+void LibRaw::convert_to_rgb_loop(float out_cam[3][4])
+{
+  int row,col,c;
+  float out[3];
+  ushort *img;
+  memset(libraw_internal_data.output_data.histogram,0,sizeof(int)*LIBRAW_HISTOGRAM_SIZE*4);
+  for (img=imgdata.image[0], row=0; row < S.height; row++)
+    for (col=0; col < S.width; col++, img+=4) {
+      if (!libraw_internal_data.internal_output_params.raw_color) {
+        out[0] = out[1] = out[2] = 0;
+        for(c=0; c< imgdata.idata.colors; c++) {
+          out[0] += out_cam[0][c] * img[c];
+          out[1] += out_cam[1][c] * img[c];
+          out[2] += out_cam[2][c] * img[c];
+        }
+        for(c=0;c<3;c++) img[c] = CLIP((int) out[c]);
+      }
+      for(c=0; c< imgdata.idata.colors; c++) libraw_internal_data.output_data.histogram[c][img[c] >> 3]++;
+    }
+
+}
+
+void LibRaw::scale_colors_loop(float scale_mul[4])
 {
-    // params limits
-    if(shift>8) shift = 8;
-    if(shift<0.25) shift = 0.25;
-    if(smooth < 0.0) smooth = 0.0;
-    if(smooth > 1.0) smooth = 1.0;
-    
-    unsigned short *lut = (ushort*)malloc((TBLN+1)*sizeof(unsigned short));
+  unsigned size = S.iheight*S.iwidth;
+
 
-    if(shift <=1.0)
+  if (C.cblack[4] && C.cblack[5])
+    {
+      int val;
+      for (unsigned i=0; i < size*4; i++)
         {
-            for(int i=0;i<=TBLN;i++)
-                lut[i] = (unsigned short)((float)i*shift);
+          if (!(val = imgdata.image[0][i])) continue;
+          val -= C.cblack[6 + i/4 / S.iwidth % C.cblack[4] * C.cblack[5] +
+			i/4 % S.iwidth % C.cblack[5]];
+          val -= C.cblack[i & 3];
+          val *= scale_mul[i & 3];
+          imgdata.image[0][i] = CLIP(val);
         }
-    else
+    }
+  else if(C.cblack[0]||C.cblack[1]||C.cblack[2]||C.cblack[3])
+    {
+      for (unsigned i=0; i < size*4; i++)
         {
-            float x1,x2,y1,y2;
-
-            float cstops = log(shift)/log(2.0f);
-            float room = cstops*2;
-            float roomlin = powf(2.0f,room);
-            x2 = (float)TBLN;
-            x1 = (x2+1)/roomlin-1;
-            y1 = x1*shift;
-            y2 = x2*(1+(1-smooth)*(shift-1));
-            float sq3x=powf(x1*x1*x2,1.0f/3.0f);
-            float B = (y2-y1+shift*(3*x1-3.0f*sq3x)) / (x2+2.0f*x1-3.0f*sq3x);
-            float A = (shift - B)*3.0f*powf(x1*x1,1.0f/3.0f);
-            float CC = y2 - A*powf(x2,1.0f/3.0f)-B*x2;
-            for(int i=0;i<=TBLN;i++)
-                {
-                    float X = (float)i;
-                    float Y = A*powf(X,1.0f/3.0f)+B*X+CC;
-                    if(i<x1)
-                        lut[i] = (unsigned short)((float)i*shift);
-                    else
-                        lut[i] = Y<0?0:(Y>TBLN?TBLN:(unsigned short)(Y));
-                }
+          int val = imgdata.image[0][i];
+          if (!val) continue;
+          val -= C.cblack[i & 3];
+          val *= scale_mul[i & 3];
+          imgdata.image[0][i] = CLIP(val);
         }
-    for(int i=0; i< S.height*S.width; i++)
+    }
+  else // BL is zero
+    {
+      for (unsigned i=0; i < size*4; i++)
         {
-            imgdata.image[i][0] = lut[imgdata.image[i][0]];
-            imgdata.image[i][1] = lut[imgdata.image[i][1]];
-            imgdata.image[i][2] = lut[imgdata.image[i][2]];
-            imgdata.image[i][3] = lut[imgdata.image[i][3]];
+          int val = imgdata.image[0][i];
+          val *= scale_mul[i & 3];
+          imgdata.image[0][i] = CLIP(val);
         }
-    for(int i=0;i<4;i++)
-        C.channel_maximum[i] = lut[C.channel_maximum[i]];
-    C.maximum = lut[C.maximum];
-    // no need to adjust the minumum, black is already subtracted
-    free(lut);
+    }
 }
-int LibRaw::dcraw_process(void)
+
+void LibRaw::adjust_bl()
 {
-    int quality,i;
+  int clear_repeat=0;
+   if (O.user_black >= 0)
+     {
+       C.black = O.user_black;
+       clear_repeat = 1;
+     }
+   for(int i=0; i<4; i++)
+     if(O.user_cblack[i]>-1000000)
+       {
+         C.cblack[i] = O.user_cblack[i];
+         clear_repeat  = 1;
+       }
+
+   if(clear_repeat)
+     C.cblack[4]=C.cblack[5]=0;
+
+ // Add common part to cblack[] early
+   if (imgdata.idata.filters > 1000 && (C.cblack[4]+1)/2 == 1 && (C.cblack[5]+1)/2 == 1)
+   {
+	   for(int c=0; c<4; c++)
+		   C.cblack[c] += C.cblack[6 + c/2 % C.cblack[4] * C.cblack[5] + c%2 % C.cblack[5]];
+	   C.cblack[4]=C.cblack[5]=0;
+   }
+   else if(imgdata.idata.filters <= 1000 && C.cblack[4]==1 && C.cblack[5]==1) // Fuji RAF dng
+   {
+	   for(int c=0; c<4; c++)
+		   C.cblack[c] += C.cblack[6];
+	   C.cblack[4]=C.cblack[5]=0;
+   }
+  // remove common part from C.cblack[]
+  int i = C.cblack[3];
+  int c;
+  for(c=0;c<3;c++) if (i > C.cblack[c]) i = C.cblack[c];
+
+  for(c=0;c<4;c++) C.cblack[c] -= i; // remove common part
+  C.black += i;
+
+  // Now calculate common part for cblack[6+] part and move it to C.black
+
+  if(C.cblack[4] && C.cblack[5])
+    {
+      i = C.cblack[6];
+      for(c=1; c<C.cblack[4]*C.cblack[5]; c++)
+        if(i>C.cblack[6+c]) i = C.cblack[6+c];
+      // Remove i from cblack[6+]
+      int nonz=0;
+      for(c=0; c<C.cblack[4]*C.cblack[5]; c++)
+        {
+          C.cblack[6+c]-=i;
+          if(C.cblack[6+c])nonz++;
+        }
+      C.black +=i;
+      if(!nonz)
+        C.cblack[4] = C.cblack[5] = 0;
+    }
+  for(c=0;c<4;c++) C.cblack[c] += C.black;
+}
 
-    int iterations=-1, dcb_enhance=1, noiserd=0;
-    int eeci_refine_fl=0, es_med_passes_fl=0;
-    float cared=0,cablue=0;
-    float linenoise=0; 
-    float lclean=0,cclean=0;
-    float thresh=0;
-    float preser=0;
-    float expos=1.0;
+int LibRaw::dcraw_process(void)
+{
+  int quality,i;
 
+  int iterations=-1, dcb_enhance=1, noiserd=0;
+  int eeci_refine_fl=0, es_med_passes_fl=0;
+  float cared=0,cablue=0;
+  float linenoise=0;
+  float lclean=0,cclean=0;
+  float thresh=0;
+  float preser=0;
+  float expos=1.0;
 
-    CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);
-//    CHECK_ORDER_HIGH(LIBRAW_PROGRESS_PRE_INTERPOLATE);
 
-    try {
+  CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);
+  //    CHECK_ORDER_HIGH(LIBRAW_PROGRESS_PRE_INTERPOLATE);
 
-        int no_crop = 1;
+  try {
 
-        if (~O.cropbox[2] && ~O.cropbox[3])
-            no_crop=0;
+    int no_crop = 1;
 
-        raw2image_ex(); // raw2image+crop+rotate_fuji_raw + subtract_black for fuji
+    if (~O.cropbox[2] && ~O.cropbox[3])
+      no_crop=0;
 
-        int save_4color = O.four_color_rgb;
+    libraw_decoder_info_t di;
+    get_decoder_info(&di);
 
-        if (IO.zero_is_bad) 
-            {
-                remove_zeroes();
-                SET_PROC_FLAG(LIBRAW_PROGRESS_REMOVE_ZEROES);
-            }
+    bool is_bayer = (imgdata.idata.filters || P1.colors == 1);
+    int subtract_inline = !O.bad_pixels && !O.dark_frame && !O.wf_debanding && is_bayer && !IO.zero_is_bad;
 
-        if(!IO.fuji_width) // PhaseOne only, all other cases handled at raw2image_ex()
-            subtract_black();
+    raw2image_ex(subtract_inline); // allocate imgdata.image and copy data!
 
-        if(O.half_size) 
-            O.four_color_rgb = 1;
+    // Adjust sizes
 
-        if(O.bad_pixels && no_crop) 
-            {
-                bad_pixels(O.bad_pixels);
-                SET_PROC_FLAG(LIBRAW_PROGRESS_BAD_PIXELS);
-            }
+    int save_4color = O.four_color_rgb;
 
-        if (O.dark_frame && no_crop)
-            {
-                subtract (O.dark_frame);
-                SET_PROC_FLAG(LIBRAW_PROGRESS_DARK_FRAME);
-            }
+    if (IO.zero_is_bad)
+      {
+        remove_zeroes();
+        SET_PROC_FLAG(LIBRAW_PROGRESS_REMOVE_ZEROES);
+      }
 
+    if(O.bad_pixels && no_crop)
+      {
+        bad_pixels(O.bad_pixels);
+        SET_PROC_FLAG(LIBRAW_PROGRESS_BAD_PIXELS);
+      }
 
-        quality = 2 + !IO.fuji_width;
+    if (O.dark_frame && no_crop)
+      {
+        subtract (O.dark_frame);
+        SET_PROC_FLAG(LIBRAW_PROGRESS_DARK_FRAME);
+      }
 
-        if (O.user_qual >= 0) quality = O.user_qual;
+    if (O.wf_debanding)
+      {
+        wf_remove_banding();
+      }
 
-        adjust_maximum();
+    quality = 2 + !IO.fuji_width;
 
-        if (O.user_sat > 0) C.maximum = O.user_sat;
+    if (O.user_qual >= 0) quality = O.user_qual;
 
-        if (P1.is_foveon && !O.document_mode) 
-            {
-                foveon_interpolate();
-                SET_PROC_FLAG(LIBRAW_PROGRESS_FOVEON_INTERPOLATE);
-            }
+    if(!subtract_inline || !C.data_maximum)
+      {
+        adjust_bl();
+        subtract_black_internal();
+      }
 
-        if (O.green_matching && !O.half_size)
-            {
-                green_matching();
-            }
+	if(!(di.decoder_flags & LIBRAW_DECODER_FIXEDMAXC))
+		adjust_maximum();
 
-        if (!P1.is_foveon &&  O.document_mode < 2)
-            {
-                scale_colors();
-                SET_PROC_FLAG(LIBRAW_PROGRESS_SCALE_COLORS);
-            }
+    if (O.user_sat > 0) C.maximum = O.user_sat;
 
-        pre_interpolate();
+    if (P1.is_foveon)
+      {
+        if(load_raw == &LibRaw::x3f_load_raw)
+          {
+            // Filter out zeroes
+            for (int i=0; i < S.height*S.width*4; i++)
+              if ((short) imgdata.image[0][i] < 0) imgdata.image[0][i] = 0;
+          }
+#ifdef LIBRAW_DEMOSAIC_PACK_GPL2
+        else if(load_raw == &LibRaw::foveon_dp_load_raw)
+          {
+            for (int i=0; i < S.height*S.width*4; i++)
+              if ((short) imgdata.image[0][i] < 0) imgdata.image[0][i] = 0;
+          }
+        else
+          {
+            foveon_interpolate();
+          }
+#endif
+        SET_PROC_FLAG(LIBRAW_PROGRESS_FOVEON_INTERPOLATE);
+      }
 
-        SET_PROC_FLAG(LIBRAW_PROGRESS_PRE_INTERPOLATE);
+    if (O.green_matching && !O.half_size)
+      {
+        green_matching();
+      }
 
-        if (O.dcb_iterations >= 0) iterations = O.dcb_iterations;
-        if (O.dcb_enhance_fl >=0 ) dcb_enhance = O.dcb_enhance_fl;
-        if (O.fbdd_noiserd >=0 ) noiserd = O.fbdd_noiserd;
-        if (O.eeci_refine >=0 ) eeci_refine_fl = O.eeci_refine;
-        if (O.es_med_passes >0 ) es_med_passes_fl = O.es_med_passes;
+    if (
+#ifdef LIBRAW_DEMOSAIC_PACK_GPL2
+        (!P1.is_foveon || O.force_foveon_x3f) &&
+#endif
+        !O.no_auto_scale)
+      {
+        scale_colors();
+        SET_PROC_FLAG(LIBRAW_PROGRESS_SCALE_COLORS);
+      }
+
+    pre_interpolate();
+
+    SET_PROC_FLAG(LIBRAW_PROGRESS_PRE_INTERPOLATE);
+
+    if (O.dcb_iterations >= 0) iterations = O.dcb_iterations;
+    if (O.dcb_enhance_fl >=0 ) dcb_enhance = O.dcb_enhance_fl;
+    if (O.fbdd_noiserd >=0 ) noiserd = O.fbdd_noiserd;
+    if (O.eeci_refine >=0 ) eeci_refine_fl = O.eeci_refine;
+    if (O.es_med_passes >0 ) es_med_passes_fl = O.es_med_passes;
+
+    // LIBRAW_DEMOSAIC_PACK_GPL3
+
+    if (!O.half_size && O.cfa_green >0) {thresh=O.green_thresh ;green_equilibrate(thresh);}
+    if (O.exp_correc >0) {expos=O.exp_shift ; preser=O.exp_preser; exp_bef(expos,preser);}
+    if (O.ca_correc >0 ) {cablue=O.cablue; cared=O.cared; CA_correct_RT(cablue, cared);}
+    if (O.cfaline >0 ) {linenoise=O.linenoise; cfa_linedn(linenoise);}
+    if (O.cfa_clean >0 ) {lclean=O.lclean; cclean=O.cclean; cfa_impulse_gauss(lclean,cclean);}
+
+    if (P1.filters  && !O.no_interpolation)
+      {
+        if (noiserd>0 && P1.colors==3 && P1.filters) fbdd(noiserd);
+        if (quality == 0)
+          lin_interpolate();
+        else if (quality == 1 || P1.colors > 3)
+          vng_interpolate();
+        else if (quality == 2 && P1.filters > 1000)
+          ppg_interpolate();
+        else if (P1.filters == LIBRAW_XTRANS)
+          {
+            // Fuji X-Trans
+            xtrans_interpolate(quality>2?3:1);
+          }
+        else if (quality == 3)
+          ahd_interpolate(); // really don't need it here due to fallback op
+        else if (quality == 4)
+          dcb(iterations, dcb_enhance);
+        //  LIBRAW_DEMOSAIC_PACK_GPL2
+        else if (quality == 5)
+          ahd_interpolate_mod();
+        else if (quality == 6)
+          afd_interpolate_pl(2,1);
+        else if (quality == 7)
+          vcd_interpolate(0);
+        else if (quality == 8)
+          vcd_interpolate(12);
+        else if (quality == 9)
+          lmmse_interpolate(1);
+
+        // LIBRAW_DEMOSAIC_PACK_GPL3
+        else if (quality == 10)
+          amaze_demosaic_RT();
+        // LGPL2
+        else if (quality == 11)
+          dht_interpolate();
+        else if (quality == 12)
+          aahd_interpolate();
+        // fallback to AHD
+        else
+          {
+            ahd_interpolate();
+            imgdata.process_warnings |= LIBRAW_WARN_FALLBACK_TO_AHD;
+          }
+
+
+        SET_PROC_FLAG(LIBRAW_PROGRESS_INTERPOLATE);
+      }
+    if (IO.mix_green)
+      {
+        for (P1.colors=3, i=0; i < S.height * S.width; i++)
+          imgdata.image[i][1] = (imgdata.image[i][1] + imgdata.image[i][3]) >> 1;
+        SET_PROC_FLAG(LIBRAW_PROGRESS_MIX_GREEN);
+      }
+
+    if(!P1.is_foveon)
+      {
+        if (P1.colors == 3)
+          {
+
+            if (quality == 8)
+              {
+                if (eeci_refine_fl == 1) refinement();
+                if (O.med_passes > 0)    median_filter_new();
+                if (es_med_passes_fl > 0) es_median_filter();
+              }
+            else {
+              median_filter();
+            }
+            SET_PROC_FLAG(LIBRAW_PROGRESS_MEDIAN_FILTER);
+          }
+      }
 
-// LIBRAW_DEMOSAIC_PACK_GPL3
+    if (O.highlight == 2)
+      {
+        blend_highlights();
+        SET_PROC_FLAG(LIBRAW_PROGRESS_HIGHLIGHTS);
+      }
 
-        if (!O.half_size && O.cfa_green >0) {thresh=O.green_thresh ;green_equilibrate(thresh);} 
-        if (O.exp_correc >0) {expos=O.exp_shift ; preser=O.exp_preser; exp_bef(expos,preser);} 
-        if (O.ca_correc >0 ) {cablue=O.cablue; cared=O.cared; CA_correct_RT(cablue, cared);}
-        if (O.cfaline >0 ) {linenoise=O.linenoise; cfa_linedn(linenoise);}
-        if (O.cfa_clean >0 ) {lclean=O.lclean; cclean=O.cclean; cfa_impulse_gauss(lclean,cclean);}
+    if (O.highlight > 2)
+      {
+        recover_highlights();
+        SET_PROC_FLAG(LIBRAW_PROGRESS_HIGHLIGHTS);
+      }
 
-        if (P1.filters && !O.document_mode) 
-            {
-                if (noiserd>0 && P1.colors==3 && P1.filters) fbdd(noiserd);
-
-                if (quality == 0)
-                    lin_interpolate();
-                else if (quality == 1 || P1.colors > 3)
-                    vng_interpolate();
-                else if (quality == 2)
-                    ppg_interpolate();
-
-                else if (quality == 3) 
-                    ahd_interpolate(); // really don't need it here due to fallback op
-
-                else if (quality == 4)
-                    dcb(iterations, dcb_enhance);
-
-//  LIBRAW_DEMOSAIC_PACK_GPL2                
-                else if (quality == 5)
-                    ahd_interpolate_mod();
-                else if (quality == 6)
-                    afd_interpolate_pl(2,1);
-                else if (quality == 7)
-                    vcd_interpolate(0);
-                else if (quality == 8)
-                    vcd_interpolate(12);
-                else if (quality == 9)
-                    lmmse_interpolate(1);
-
-// LIBRAW_DEMOSAIC_PACK_GPL3
-                else if (quality == 10)
-                    amaze_demosaic_RT();
- // fallback to AHD
-                else
-                    ahd_interpolate();
-                
-                SET_PROC_FLAG(LIBRAW_PROGRESS_INTERPOLATE);
-            }
-        if (IO.mix_green)
-            {
-                for (P1.colors=3, i=0; i < S.height * S.width; i++)
-                    imgdata.image[i][1] = (imgdata.image[i][1] + imgdata.image[i][3]) >> 1;
-                SET_PROC_FLAG(LIBRAW_PROGRESS_MIX_GREEN);
-            }
+    if (O.use_fuji_rotate)
+      {
+        fuji_rotate();
+        SET_PROC_FLAG(LIBRAW_PROGRESS_FUJI_ROTATE);
+      }
 
-        if(!P1.is_foveon)
-            {
-                if (P1.colors == 3) 
-                    {
-                        
-                        if (quality == 8) 
-                            {
-                                if (eeci_refine_fl == 1) refinement();
-                                if (O.med_passes > 0)    median_filter_new();
-                                if (es_med_passes_fl > 0) es_median_filter();
-                            } 
-                        else {
-                            median_filter();
-                        }
-                        SET_PROC_FLAG(LIBRAW_PROGRESS_MEDIAN_FILTER);
-                    }
-            }
-        
-        if (O.highlight == 2) 
-            {
-                blend_highlights();
-                SET_PROC_FLAG(LIBRAW_PROGRESS_HIGHLIGHTS);
-            }
-        
-        if (O.highlight > 2) 
-            {
-                recover_highlights();
-                SET_PROC_FLAG(LIBRAW_PROGRESS_HIGHLIGHTS);
-            }
-        
-        if (O.use_fuji_rotate) 
-            {
-                fuji_rotate();
-                SET_PROC_FLAG(LIBRAW_PROGRESS_FUJI_ROTATE);
-            }
-    
-        if(!libraw_internal_data.output_data.histogram)
-            {
-                libraw_internal_data.output_data.histogram = (int (*)[LIBRAW_HISTOGRAM_SIZE]) malloc(sizeof(*libraw_internal_data.output_data.histogram)*4);
-                merror(libraw_internal_data.output_data.histogram,"LibRaw::dcraw_process()");
-            }
+    if(!libraw_internal_data.output_data.histogram)
+      {
+        libraw_internal_data.output_data.histogram = (int (*)[LIBRAW_HISTOGRAM_SIZE]) malloc(sizeof(*libraw_internal_data.output_data.histogram)*4);
+        merror(libraw_internal_data.output_data.histogram,"LibRaw::dcraw_process()");
+      }
 #ifndef NO_LCMS
-	if(O.camera_profile)
-            {
-                apply_profile(O.camera_profile,O.output_profile);
-                SET_PROC_FLAG(LIBRAW_PROGRESS_APPLY_PROFILE);
-            }
+    if(O.camera_profile)
+      {
+        apply_profile(O.camera_profile,O.output_profile);
+        SET_PROC_FLAG(LIBRAW_PROGRESS_APPLY_PROFILE);
+      }
 #endif
 
-        convert_to_rgb();
-        SET_PROC_FLAG(LIBRAW_PROGRESS_CONVERT_RGB);
+    convert_to_rgb();
+    SET_PROC_FLAG(LIBRAW_PROGRESS_CONVERT_RGB);
 
-        if (O.use_fuji_rotate) 
-            {
-                stretch();
-                SET_PROC_FLAG(LIBRAW_PROGRESS_STRETCH);
-            }
-        O.four_color_rgb = save_4color; // also, restore
+    if (O.use_fuji_rotate)
+      {
+        stretch();
+        SET_PROC_FLAG(LIBRAW_PROGRESS_STRETCH);
+      }
+    O.four_color_rgb = save_4color; // also, restore
 
-        return 0;
-    }
-    catch ( LibRaw_exceptions err) {
-        EXCEPTION_HANDLER(err);
-    }
+    return 0;
+  }
+  catch ( LibRaw_exceptions err) {
+    EXCEPTION_HANDLER(err);
+  }
 }
 
 // Supported cameras:
-static const char  *static_camera_list[] = 
+static const char  *static_camera_list[] =
 {
 "Adobe Digital Negative (DNG)",
 "AgfaPhoto DC-833m",
+"Alcatel 5035D",
 "Apple QuickTake 100",
 "Apple QuickTake 150",
 "Apple QuickTake 200",
@@ -2290,6 +3314,10 @@ static const char  *static_camera_list[] =
 "AVT F-201C",
 "AVT F-510C",
 "AVT F-810C",
+"Baumer TXG14",
+"BlackMagic Cinema Camera",
+"BlackMagic Pocket Cinema Camera",
+"BlackMagic Production Camera 4k",
 "Canon PowerShot 600",
 "Canon PowerShot A5",
 "Canon PowerShot A5 Zoom",
@@ -2297,6 +3325,7 @@ static const char  *static_camera_list[] =
 "Canon PowerShot A460 (CHDK hack)",
 "Canon PowerShot A470 (CHDK hack)",
 "Canon PowerShot A530 (CHDK hack)",
+"Canon PowerShot A550 (CHDK hack)",
 "Canon PowerShot A570 (CHDK hack)",
 "Canon PowerShot A590 (CHDK hack)",
 "Canon PowerShot A610 (CHDK hack)",
@@ -2306,24 +3335,30 @@ static const char  *static_camera_list[] =
 "Canon PowerShot A650 (CHDK hack)",
 "Canon PowerShot A710 IS (CHDK hack)",
 "Canon PowerShot A720 IS (CHDK hack)",
+"Canon PowerShot A3300 IS (CHDK hack)",
 "Canon PowerShot Pro70",
 "Canon PowerShot Pro90 IS",
 "Canon PowerShot Pro1",
 "Canon PowerShot G1",
 "Canon PowerShot G1 X",
+"Canon PowerShot G1 X Mark II",
 "Canon PowerShot G2",
 "Canon PowerShot G3",
 "Canon PowerShot G5",
 "Canon PowerShot G6",
 "Canon PowerShot G7 (CHDK hack)",
+"Canon PowerShot G7 X",
 "Canon PowerShot G9",
 "Canon PowerShot G10",
 "Canon PowerShot G11",
 "Canon PowerShot G12",
+"Canon PowerShot G15",
+"Canon PowerShot G16",
 "Canon PowerShot S2 IS (CHDK hack)",
 "Canon PowerShot S3 IS (CHDK hack)",
 "Canon PowerShot S5 IS (CHDK hack)",
 "Canon PowerShot SD300 (CHDK hack)",
+"Canon PowerShot SD950 (CHDK hack)",
 "Canon PowerShot S30",
 "Canon PowerShot S40",
 "Canon PowerShot S45",
@@ -2333,24 +3368,33 @@ static const char  *static_camera_list[] =
 "Canon PowerShot S90",
 "Canon PowerShot S95",
 "Canon PowerShot S100",
+"Canon PowerShot S110",
+"Canon PowerShot S120",
 "Canon PowerShot SX1 IS",
+"Canon PowerShot SX50 HS",
+"Canon PowerShot SX60 HS",
 "Canon PowerShot SX110 IS (CHDK hack)",
 "Canon PowerShot SX120 IS (CHDK hack)",
-"Canon PowerShot SX20 IS (CHDK hack)",
 "Canon PowerShot SX220 HS (CHDK hack)",
+"Canon PowerShot SX20 IS (CHDK hack)",
 "Canon PowerShot SX30 IS (CHDK hack)",
 "Canon EOS D30",
 "Canon EOS D60",
 "Canon EOS 5D",
 "Canon EOS 5D Mark II",
 "Canon EOS 5D Mark III",
+"Canon EOS 6D",
 "Canon EOS 7D",
+"Canon EOS 7D Mark II",
 "Canon EOS 10D",
 "Canon EOS 20D",
+"Canon EOS 20Da",
 "Canon EOS 30D",
 "Canon EOS 40D",
 "Canon EOS 50D",
 "Canon EOS 60D",
+"Canon EOS 60Da",
+"Canon EOS 70D",
 "Canon EOS 300D / Digital Rebel / Kiss Digital",
 "Canon EOS 350D / Digital Rebel XT / Kiss Digital N",
 "Canon EOS 400D / Digital Rebel XTi / Kiss Digital X",
@@ -2358,11 +3402,18 @@ static const char  *static_camera_list[] =
 "Canon EOS 500D / Digital Rebel T1i / Kiss Digital X3",
 "Canon EOS 550D / Digital Rebel T2i / Kiss Digital X4",
 "Canon EOS 600D / Digital Rebel T3i / Kiss Digital X5",
+"Canon EOS 650D / Digital Rebel T4i / Kiss Digital X6i",
+"Canon EOS 700D / Digital Rebel T5i",
+"Canon EOS 100D / Digital Rebel SL1",
 "Canon EOS 1000D / Digital Rebel XS / Kiss Digital F",
 "Canon EOS 1100D / Digital Rebel T3 / Kiss Digital X50",
+"Canon EOS 1200D",
+"Canon EOS C500",
 "Canon EOS D2000C",
+"Canon EOS M",
 "Canon EOS-1D",
 "Canon EOS-1DS",
+"Canon EOS-1D C",
 "Canon EOS-1D X",
 "Canon EOS-1D Mark II",
 "Canon EOS-1D Mark II N",
@@ -2378,6 +3429,12 @@ static const char  *static_camera_list[] =
 "Casio QV-R41",
 "Casio QV-R51",
 "Casio QV-R61",
+"Casio EX-F1",
+"Casio EX-FC300S",
+"Casio EX-FC400S",
+"Casio EX-FH20",
+"Casio EX-FH25",
+"Casio EX-FH100",
 "Casio EX-S20",
 "Casio EX-S100",
 "Casio EX-Z4",
@@ -2390,61 +3447,137 @@ static const char  *static_camera_list[] =
 "Casio EX-Z8",
 "Casio EX-Z850",
 "Casio EX-Z1050",
+"Casio EX-ZR100",
 "Casio EX-Z1080",
+"Casio EX-ZR700",
+"Casio EX-ZR710",
+"Casio EX-ZR750",
+"Casio EX-ZR800",
+"Casio EX-ZR850",
+"Casio EX-ZR1000",
+"Casio EX-ZR1100",
+"Casio EX-ZR1200",
+"Casio EX-ZR1300",
+"Casio EX-ZR1500",
+"Casio EX-100",
+"Casio EX-10",
 "Casio Exlim Pro 505",
 "Casio Exlim Pro 600",
 "Casio Exlim Pro 700",
 "Contax N Digital",
 "Creative PC-CAM 600",
+"Digital Bolex D16",
+"Digital Bolex D16M",
+"DJI 4384x3288",
 "Epson R-D1",
+"Epson R-D1s",
+"Epson R-D1x",
 "Foculus 531C",
-"Fuji FinePix E550",
-"Fuji FinePix E900",
-"Fuji FinePix F700",
-"Fuji FinePix F710",
-"Fuji FinePix F800",
-"Fuji FinePix F810",
-"Fuji FinePix S2Pro",
-"Fuji FinePix S3Pro",
-"Fuji FinePix S5Pro",
-"Fuji FinePix S20Pro",
-"Fuji FinePix S100FS",
-"Fuji FinePix S5000",
-"Fuji FinePix S5100/S5500",
-"Fuji FinePix S5200/S5600",
-"Fuji FinePix S6000fd",
-"Fuji FinePix S7000",
-"Fuji FinePix S9000/S9500",
-"Fuji FinePix S9100/S9600",
-"Fuji FinePix S200EXR",
-"Fuji FinePix HS10/HS11",
-"Fuji FinePix HS20EXR",
-"Fuji FinePix HS30EXR",
-"Fuji FinePix F550EXR",
-"Fuji FinePix F600EXR",
-"Fuji FinePix X-S1",
-"Fuji FinePix X100",
-"Fuji FinePix X10",
-"Fuji IS-1",
+"FujiFilm E505",
+"FujiFilm E900",
+"FujiFilm F700",
+"FujiFilm F710",
+"FujiFilm F800",
+"FujiFilm F810",
+"FujiFilm S2Pro",
+"FujiFilm S3Pro",
+"FujiFilm S5Pro",
+"FujiFilm S20Pro",
+"FujiFilm S1",
+"FujiFilm S100FS",
+"FujiFilm S5000",
+"FujiFilm S5100/S5500",
+"FujiFilm S5200/S5600",
+"FujiFilm S6000fd",
+"FujiFilm S7000",
+"FujiFilm S9000/S9500",
+"FujiFilm S9100/S9600",
+"FujiFilm S200EXR",
+"FujiFilm S205EXR",
+"FujiFilm SL1000",
+"FujiFilm HS10",
+"FujiFilm HS11",
+"FujiFilm HS20EXR",
+"FujiFilm HS22EXR",
+"FujiFilm HS30EXR",
+"FujiFilm HS33EXR",
+"FujiFilm HS35EXR",
+"FujiFilm HS50EXR",
+"FujiFilm F505EXR",
+"FujiFilm F550EXR",
+"FujiFilm F600EXR",
+"FujiFilm F605EXR",
+"FujiFilm F770EXR",
+"FujiFilm F775EXR",
+"FujiFilm F800EXR",
+"FujiFilm F900EXR",
+"FujiFilm X-Pro1",
+"FujiFilm X-S1",
+"FujiFilm XQ1",
+"FujiFilm X100",
+"FujiFilm X100S",
+"FujiFilm X100T",
+"FujiFilm X10",
+"FujiFilm X20",
+"FujiFilm X30",
+"FujiFilm X-A1",
+"FujiFilm X-E1",
+"FujiFilm X-E2",
+"FujiFilm X-M1",
+"FujiFilm XF1",
+"FujiFilm X-T1",
+"FujiFilm X-T1 Graphite Silver",
+"FujiFilm IS-1",
+"Hasselblad H5D-60",
+"Hasselblad H5D-50",
+"Hasselblad H5D-50c",
+"Hasselblad H5D-40",
+"Hasselblad H4D-60",
+"Hasselblad H4D-50",
+"Hasselblad H4D-40",
+"Hasselblad H4D-31",
+"Hasselblad H3DII-22",
+"Hasselblad H3DII-31",
+"Hasselblad H3DII-39",
+"Hasselblad H3DII-50",
+"Hasselblad H3D-22",
+"Hasselblad H3D-31",
+"Hasselblad H3D-39",
+"Hasselblad H2D-22",
+"Hasselblad H2D-39",
 "Hasselblad CFV",
-"Hasselblad H3D",
-"Hasselblad H4D",
+"Hasselblad CFH",
+"Hasselblad CF-22",
+"Hasselblad CF-31",
+"Hasselblad CF-39",
 "Hasselblad V96C",
-"Imacon Ixpress 16-megapixel",
-"Imacon Ixpress 22-megapixel",
-"Imacon Ixpress 39-megapixel",
+"Hasselblad Lunar",
+"Hasselblad Stellar",
+"Hasselblad Stellar II",
+"Hasselblad HV",
+"HTC UltraPixel",
+"Imacon Ixpress 96, 96C",
+"Imacon Ixpress 384, 384C (single shot only)",
+"Imacon Ixpress 132C",
+"Imacon Ixpress 528C (single shot only)",
 "ISG 2020x1520",
+"Ikonoskop A-Cam dII Panchromatic",
+"Ikonoskop A-Cam dII",
+"Kinefinity KineMINI",
+"Kinefinity KineRAW Mini",
+"Kinefinity KineRAW S35",
 "Kodak DC20",
 "Kodak DC25",
 "Kodak DC40",
 "Kodak DC50",
-"Kodak DC120 (also try kdc2tiff)",
+"Kodak DC120",
 "Kodak DCS200",
 "Kodak DCS315C",
 "Kodak DCS330C",
 "Kodak DCS420",
 "Kodak DCS460",
 "Kodak DCS460A",
+"Kodak DCS460D",
 "Kodak DCS520C",
 "Kodak DCS560C",
 "Kodak DCS620C",
@@ -2469,6 +3602,7 @@ static const char  *static_camera_list[] =
 "Kodak C603",
 "Kodak P850",
 "Kodak P880",
+"Kodak S-1",
 "Kodak Z980",
 "Kodak Z981",
 "Kodak Z990",
@@ -2494,22 +3628,52 @@ static const char  *static_camera_list[] =
 "Leaf Cantare",
 "Leaf CatchLight",
 "Leaf CMost",
+"Leaf Credo 40",
+"Leaf Credo 50",
+"Leaf Credo 60",
+"Leaf Credo 80",
 "Leaf DCB2",
 "Leaf Valeo 6",
 "Leaf Valeo 11",
 "Leaf Valeo 17",
 "Leaf Valeo 22",
 "Leaf Volare",
+"Lenovo a820",
+"Leica C (Typ 112)",
 "Leica Digilux 2",
 "Leica Digilux 3",
+"Leica Digital-Modul-R",
 "Leica D-LUX2",
 "Leica D-LUX3",
 "Leica D-LUX4",
 "Leica D-LUX5",
+"Leica D-LUX6",
+"Leica D-Lux (Typ 109)",
+"Leica M8",
+"Leica M8.2",
+"Leica M9",
+"Leica M (Typ 240)",
+"Leica Monochrom (Typ 240)",
+"Leica M-E",
+"Leica M-P",
+"Leica R8",
+"Leica S",
+"Leica S2",
+//"Leica S3",
+"Leica T (Typ 701)",
+"Leica X1",
+"Leica X (Typ 113)",
+"Leica X2",
+"Leica X-E (Typ 102)",
 "Leica V-LUX1",
 "Leica V-LUX2",
+"Leica V-LUX3",
+"Leica V-LUX4",
+"Leica V-Lux (Typ 114)",
+"Leica X VARIO (Typ 107)",
 "Logitech Fotoman Pixtura",
 "Mamiya ZD",
+"Matrix 4608x3288",
 "Micron 2010",
 "Minolta RD175",
 "Minolta DiMAGE 5",
@@ -2538,6 +3702,7 @@ static const char  *static_camera_list[] =
 "Nikon D3s",
 "Nikon D3X",
 "Nikon D4",
+"Nikon D4s",
 "Nikon D40",
 "Nikon D40X",
 "Nikon D50",
@@ -2550,16 +3715,35 @@ static const char  *static_camera_list[] =
 "Nikon D200",
 "Nikon D300",
 "Nikon D300s",
+"Nikon D600",
+"Nikon D610",
 "Nikon D700",
+"Nikon D750",
+"Nikon D800",
+"Nikon D800E",
+"Nikon D810",
 "Nikon D3000",
 "Nikon D3100",
 "Nikon D3200",
+"Nikon D3300",
 "Nikon D5000",
 "Nikon D5100",
+"Nikon D5200",
+"Nikon D5300",
+"Nikon D5500",
 "Nikon D7000",
-"Nikon D800",
+"Nikon D7100",
+"Nikon Df",
+"Nikon 1 AW1",
 "Nikon 1 J1",
+"Nikon 1 J2",
+"Nikon 1 J3",
+"Nikon 1 J4",
+"Nikon 1 S1",
+"Nikon 1 S2",
 "Nikon 1 V1",
+"Nikon 1 V2",
+"Nikon 1 V3",
 "Nikon E700 (\"DIAG RAW\" hack)",
 "Nikon E800 (\"DIAG RAW\" hack)",
 "Nikon E880 (\"DIAG RAW\" hack)",
@@ -2579,15 +3763,24 @@ static const char  *static_camera_list[] =
 "Nikon E8400",
 "Nikon E8700",
 "Nikon E8800",
+"Nikon Coolpix A",
+"Nikon Coolpix P330",
+"Nikon Coolpix P340",
 "Nikon Coolpix P6000",
 "Nikon Coolpix P7000",
 "Nikon Coolpix P7100",
+"Nikon Coolpix P7700",
+"Nikon Coolpix P7800",
 "Nikon Coolpix S6 (\"DIAG RAW\" hack)",
+"Nikon Coolscan NEF",
 "Nokia N95",
 "Nokia X2",
+"Nokia 1200x1600",
+"Nokia Lumia 1020",
+"Nokia Lumia 1520",
 "Olympus C3030Z",
 "Olympus C5050Z",
-"Olympus C5060WZ",
+"Olympus C5060Z",
 "Olympus C7070WZ",
 "Olympus C70Z,C7000Z",
 "Olympus C740UZ",
@@ -2605,19 +3798,29 @@ static const char  *static_camera_list[] =
 "Olympus E-400",
 "Olympus E-410",
 "Olympus E-420",
+"Olympus E-450",
 "Olympus E-500",
 "Olympus E-510",
 "Olympus E-520",
+"Olympus E-600",
 "Olympus E-620",
 "Olympus E-P1",
 "Olympus E-P2",
 "Olympus E-P3",
+"Olympus E-P5",
 "Olympus E-PL1",
 "Olympus E-PL1s",
 "Olympus E-PL2",
 "Olympus E-PL3",
+"Olympus E-PL5",
+"Olympus E-PL6",
+"Olympus E-PL7",
 "Olympus E-PM1",
+"Olympus E-PM2",
+"Olympus E-M1",
+"Olympus E-M10",
 "Olympus E-M5",
+"Olympus E-M5 Mark II",
 "Olympus SP310",
 "Olympus SP320",
 "Olympus SP350",
@@ -2625,8 +3828,15 @@ static const char  *static_camera_list[] =
 "Olympus SP510UZ",
 "Olympus SP550UZ",
 "Olympus SP560UZ",
+"Olympus SP565UZ",
 "Olympus SP570UZ",
+"Olympus STYLUS1",
+"Olympus STYLUS1s",
 "Olympus XZ-1",
+"Olympus XZ-2",
+"Olympus XZ-10",
+"OmniVision OV5647 (Raspberry Pi)",
+"Panasonic DMC-CM1",
 "Panasonic DMC-FZ8",
 "Panasonic DMC-FZ18",
 "Panasonic DMC-FZ28",
@@ -2634,95 +3844,210 @@ static const char  *static_camera_list[] =
 "Panasonic DMC-FZ35/FZ38",
 "Panasonic DMC-FZ40",
 "Panasonic DMC-FZ50",
+"Panasonic DMC-FZ7",
+"Panasonic DMC-FZ70",
 "Panasonic DMC-FZ100",
 "Panasonic DMC-FZ150",
+"Panasonic DMC-FZ200",
+"Panasonic DMC-FZ1000",
 "Panasonic DMC-FX150",
 "Panasonic DMC-G1",
 "Panasonic DMC-G10",
 "Panasonic DMC-G2",
 "Panasonic DMC-G3",
+"Panasonic DMC-G5",
+"Panasonic DMC-G6",
 "Panasonic DMC-GF1",
 "Panasonic DMC-GF2",
 "Panasonic DMC-GF3",
+//"Panasonic DMC-GF3KK",
 "Panasonic DMC-GF5",
+"Panasonic DMC-GF6",
+"Panasonic DMC-GF7",
 "Panasonic DMC-GH1",
 "Panasonic DMC-GH2",
+"Panasonic DMC-GH3",
+"Panasonic DMC-GH4",
+"Panasonic AG-GH4",
+"Panasonic DMC-GM1",
+"Panasonic DMC-GM1s",
+"Panasonic DMC-GM5",
 "Panasonic DMC-GX1",
+"Panasonic DMC-GX7",
 "Panasonic DMC-L1",
 "Panasonic DMC-L10",
 "Panasonic DMC-LC1",
 "Panasonic DMC-LX1",
+"Panasonic DMC-LF1",
 "Panasonic DMC-LX2",
 "Panasonic DMC-LX3",
 "Panasonic DMC-LX5",
+"Panasonic DMC-LX7",
+"Panasonic DMC-LX100",
+"Panasonic DMC-TZ60/61/SZ40",
+"Panasonic DMC-TZ70",
 "Pentax *ist D",
 "Pentax *ist DL",
 "Pentax *ist DL2",
 "Pentax *ist DS",
 "Pentax *ist DS2",
+"Pentax GR",
 "Pentax K10D",
 "Pentax K20D",
 "Pentax K100D",
 "Pentax K100D Super",
+"Pentax K110D",
 "Pentax K200D",
 "Pentax K2000/K-m",
 "Pentax K-x",
 "Pentax K-r",
+"Pentax K-01",
+"Pentax K-3",
+"Pentax K-30",
 "Pentax K-5",
+"Pentax K-5 II",
+"Pentax K-5 IIs",
+"Pentax K-50",
+"Pentax K-500",
 "Pentax K-7",
+"Pentax K-S1",
+"Pentax MX-1",
+"Pentax Q",
+"Pentax Q7",
+"Pentax Q10",
+"Pentax QS-1",
 "Pentax Optio S",
 "Pentax Optio S4",
 "Pentax Optio 33WR",
 "Pentax Optio 750Z",
 "Pentax 645D",
-"Phase One LightPhase",
-"Phase One H 10",
-"Phase One H 20",
-"Phase One H 25",
-"Phase One P 20",
-"Phase One P 25",
-"Phase One P 30",
-"Phase One P 45",
-"Phase One P 45+",
-"Phase One P 65",
+"Pentax 645Z",
+"PhaseOne IQ140",
+"PhaseOne IQ160",
+"PhaseOne IQ180",
+"PhaseOne IQ250",
+"PhaseOne IQ260",
+"PhaseOne IQ260 Achromatic",
+"PhaseOne IQ280",
+"PhaseOne LightPhase",
+"PhaseOne Achromatic+",
+"PhaseOne H 10",
+"PhaseOne H 20",
+"PhaseOne H 25",
+"PhaseOne P 20",
+"PhaseOne P 20+",
+"PhaseOne P 21",
+"PhaseOne P 25",
+"PhaseOne P 25+",
+"PhaseOne P 30",
+"PhaseOne P 30+",
+"PhaseOne P 40+",
+"PhaseOne P 45",
+"PhaseOne P 45+",
+"PhaseOne P 65",
+"PhaseOne P 65+",
 "Pixelink A782",
-#ifdef LIBRAW_DEMOSAIC_PACK_GPL2
 "Polaroid x530",
-#endif
+"Ricoh GR",
+"Ricoh GR Digital",
+"Ricoh GR Digital II",
+"Ricoh GR Digital III",
+"Ricoh GR Digital IV",
+"Ricoh GX100",
+"Ricoh GX200",
+"Ricoh GXR MOUNT A12",
+"Ricoh GXR MOUNT A16 24-85mm F3.5-5.5",
+"Ricoh GXR, S10 24-72mm F2.5-4.4 VC",
+"Ricoh GXR, GR A12 50mm F2.5 MACRO",
+"Ricoh GXR, GR LENS A12 28mm F2.5",
+"Ricoh GXR, GXR P10",
 #ifndef NO_JASPER
 "Redcode R3D format",
 #endif
 "Rollei d530flex",
 "RoverShot 3320af",
 "Samsung EX1",
+"Samsung EX2F",
+"Samsung GX-1L",
 "Samsung GX-1S",
 "Samsung GX10",
 "Samsung GX20",
+"Samsung Galaxy NX (EK-GN120)",
+"Samsung NX1",
+"Samsung NX5",
 "Samsung NX10",
 "Samsung NX11",
 "Samsung NX100",
+"Samsung NX1000",
+"Samsung NX1100",
 "Samsung NX20",
 "Samsung NX200",
 "Samsung NX210",
+"Samsung NX2000",
+"Samsung NX30",
+"Samsung NX300",
+"Samsung NX300M",
+"Samsung NX3000",
+"Samsung NX mini",
+"Samsung Pro815",
 "Samsung WB550",
 "Samsung WB2000",
 "Samsung S85 (hacked)",
 "Samsung S850 (hacked)",
+"Samsung Galaxy S3",
+"Samsung Galaxy Nexus",
 "Sarnoff 4096x5440",
-#ifdef LIBRAW_DEMOSAIC_PACK_GPL2
+"Seitz 6x17",
+"Seitz Roundshot D3",
+"Seitz Roundshot D2X",
+"Seitz Roundshot D2Xs",
 "Sigma SD9",
 "Sigma SD10",
 "Sigma SD14",
-#endif
+"Sigma SD15",
+"Sigma SD1",
+"Sigma SD1 Merill",
+"Sigma DP1",
+"Sigma DP1 Merill",
+"Sigma DP1S",
+"Sigma DP1X",
+"Sigma DP2",
+"Sigma DP2 Merill",
+"Sigma DP2S",
+"Sigma DP2X",
+"Sigma dp1 Quattro",
+"Sigma dp2 Quattro",
+"Sinar eMotion 22",
+"Sinar eMotion 54",
+"Sinar eSpirit 65",
+"Sinar eMotion 75",
+"Sinar eVolution 75",
 "Sinar 3072x2048",
 "Sinar 4080x4080",
 "Sinar 4080x5440",
 "Sinar STI format",
+"Sinar Sinarback 54",
 "SMaL Ultra-Pocket 3",
 "SMaL Ultra-Pocket 4",
 "SMaL Ultra-Pocket 5",
+"Sony A7",
+"Sony A7 II",
+"Sony A7R",
+"Sony A7S",
+"Sony ILCA-77M2 (A77-II)",
+"Sony ILCE-3000",
+"Sony ILCE-5000",
+"Sony ILCE-5100",
+"Sony ILCE-6000",
+"Sony ILCE-QX1",
 "Sony DSC-F828",
 "Sony DSC-R1",
+"Sony DSC-RX1",
+"Sony DSC-RX1R",
+"Sony DSC-RX10",
+"Sony DSC-RX100",
+"Sony DSC-RX100II",
+"Sony DSC-RX100III",
 "Sony DSC-V3",
 "Sony DSLR-A100",
 "Sony DSLR-A200",
@@ -2736,25 +4061,42 @@ static const char  *static_camera_list[] =
 "Sony DSLR-A450",
 "Sony DSLR-A500",
 "Sony DSLR-A550",
+"Sony DSLR-A560",
 "Sony DSLR-A580",
 "Sony DSLR-A700",
 "Sony DSLR-A850",
 "Sony DSLR-A900",
 "Sony NEX-3",
+"Sony NEX-3N",
 "Sony NEX-5",
 "Sony NEX-5N",
+"Sony NEX-5R",
+"Sony NEX-5T",
+"Sony NEX-6",
 "Sony NEX-7",
 "Sony NEX-C3",
 "Sony NEX-F3",
+"Sony NEX-VG20",
+"Sony NEX-VG30",
+"Sony NEX-VG900",
 "Sony SLT-A33",
 "Sony SLT-A35",
 "Sony SLT-A37",
 "Sony SLT-A55V",
 "Sony SLT-A57",
+"Sony SLT-A58",
 "Sony SLT-A65V",
 "Sony SLT-A77V",
+"Sony SLT-A99V",
 "Sony XCD-SX910CR",
+"Sony IMX135-mipi 13mp",
+"Sony IMX135-QCOM",
+"Sony IMX072-mipi",
 "STV680 VGA",
+"ptGrey GRAS-50S5C",
+"JaiPulnix BB-500CL",
+"JaiPulnix BB-500GE",
+"SVS SVS625CL",
    NULL
 };
 
@@ -2764,51 +4106,428 @@ int LibRaw::cameraCount() { return (sizeof(static_camera_list)/sizeof(static_cam
 
 const char * LibRaw::strprogress(enum LibRaw_progress p)
 {
-    switch(p)
+  switch(p)
+    {
+    case LIBRAW_PROGRESS_START:
+      return "Starting";
+    case LIBRAW_PROGRESS_OPEN :
+      return "Opening file";
+    case LIBRAW_PROGRESS_IDENTIFY :
+      return "Reading metadata";
+    case LIBRAW_PROGRESS_SIZE_ADJUST:
+      return "Adjusting size";
+    case LIBRAW_PROGRESS_LOAD_RAW:
+      return "Reading RAW data";
+    case LIBRAW_PROGRESS_REMOVE_ZEROES:
+      return "Clearing zero values";
+    case LIBRAW_PROGRESS_BAD_PIXELS :
+      return "Removing dead pixels";
+    case LIBRAW_PROGRESS_DARK_FRAME:
+      return "Subtracting dark frame data";
+    case LIBRAW_PROGRESS_FOVEON_INTERPOLATE:
+      return "Interpolating Foveon sensor data";
+    case LIBRAW_PROGRESS_SCALE_COLORS:
+      return "Scaling colors";
+    case LIBRAW_PROGRESS_PRE_INTERPOLATE:
+      return "Pre-interpolating";
+    case LIBRAW_PROGRESS_INTERPOLATE:
+      return "Interpolating";
+    case LIBRAW_PROGRESS_MIX_GREEN :
+      return "Mixing green channels";
+    case LIBRAW_PROGRESS_MEDIAN_FILTER   :
+      return "Median filter";
+    case LIBRAW_PROGRESS_HIGHLIGHTS:
+      return "Highlight recovery";
+    case LIBRAW_PROGRESS_FUJI_ROTATE :
+      return "Rotating Fuji diagonal data";
+    case LIBRAW_PROGRESS_FLIP :
+      return "Flipping image";
+    case LIBRAW_PROGRESS_APPLY_PROFILE:
+      return "ICC conversion";
+    case LIBRAW_PROGRESS_CONVERT_RGB:
+      return "Converting to RGB";
+    case LIBRAW_PROGRESS_STRETCH:
+      return "Stretching image";
+    case LIBRAW_PROGRESS_THUMB_LOAD:
+      return "Loading thumbnail";
+    default:
+      return "Some strange things";
+    }
+}
+
+#undef ID
+
+
+#include "../internal/libraw_x3f.cpp"
+
+void x3f_clear(void *p)
+{
+  x3f_delete((x3f_t*)p);
+}
+
+static char *utf2char(utf16_t *str, char *buffer)
+{
+  char *b = buffer;
+
+  while (*str != 0x00) {
+    char *chr = (char *)str;
+    *b++ = *chr;
+    str++;
+  }
+  *b = 0;
+  return buffer;
+}
+
+static void *lr_memmem(const void *l, size_t l_len, const void *s, size_t s_len)
+{
+	register char *cur, *last;
+	const char *cl = (const char *)l;
+	const char *cs = (const char *)s;
+
+	/* we need something to compare */
+	if (l_len == 0 || s_len == 0)
+		return NULL;
+
+	/* "s" must be smaller or equal to "l" */
+	if (l_len < s_len)
+		return NULL;
+
+	/* special case where s_len == 1 */
+	if (s_len == 1)
+		return (void*)memchr(l, (int)*cs, l_len);
+
+	/* the last position where its possible to find "s" in "l" */
+	last = (char *)cl + l_len - s_len;
+
+	for (cur = (char *)cl; cur <= last; cur++)
+		if (cur[0] == cs[0] && memcmp(cur, cs, s_len) == 0)
+			return cur;
+	return NULL;
+}
+
+void LibRaw::parse_x3f()
+{
+  x3f_t *x3f = x3f_new_from_file(libraw_internal_data.internal_data.input);
+  if(!x3f)
+      return;
+  _x3f_data = x3f;
+
+  x3f_header_t *H = NULL;
+  x3f_directory_section_t *DS = NULL;
+
+  H = &x3f->header;
+  // Parse RAW size from RAW section
+  x3f_directory_entry_t *DE = x3f_get_raw(x3f);
+  if(!DE) return;
+  imgdata.sizes.flip = H->rotation;
+  x3f_directory_entry_header_t *DEH = &DE->header;
+  x3f_image_data_t *ID = &DEH->data_subsection.image_data;
+  imgdata.sizes.raw_width = ID->columns;
+  imgdata.sizes.raw_height = ID->rows;
+  // Parse other params from property section
+  DE = x3f_get_prop(x3f);
+  if((x3f_load_data(x3f,DE) == X3F_OK))
+  {
+	  // Parse property list
+	  DEH = &DE->header;
+	  x3f_property_list_t *PL = &DEH->data_subsection.property_list;
+	  if (PL->property_table.size != 0) {
+		  int i;
+		  x3f_property_t *P = PL->property_table.element;
+		  for (i=0; i<PL->num_properties; i++) {
+			  char name[100], value[100];
+			  utf2char(P[i].name,name);
+			  utf2char(P[i].value,value);
+			  if (!strcmp (name, "ISO"))
+				  imgdata.other.iso_speed = atoi(value);
+			  if (!strcmp (name, "CAMMANUF"))
+				  strcpy (imgdata.idata.make, value);
+			  if (!strcmp (name, "CAMMODEL"))
+				  strcpy (imgdata.idata.model, value);
+			  if (!strcmp (name, "WB_DESC"))
+				  strcpy (imgdata.color.model2, value);
+			  if (!strcmp (name, "TIME"))
+				  imgdata.other.timestamp = atoi(value);
+			  if (!strcmp (name, "SHUTTER"))
+				  imgdata.other.shutter = atof(value);
+			  if (!strcmp (name, "APERTURE"))
+				  imgdata.other.aperture = atof(value);
+			  if (!strcmp (name, "FLENGTH"))
+				  imgdata.other.focal_len = atof(value);
+				if (!strcmp (name, "FLEQ35MM"))
+				  imgdata.lens.makernotes.FocalLengthIn35mmFormat = atof(value);
+				if (!strcmp (name, "LENSARANGE"))
+				{
+				  char *sp;
+				  imgdata.lens.makernotes.MaxAp4CurFocal = imgdata.lens.makernotes.MinAp4CurFocal = atof(value);
+				  sp = strrchr (value, ' ');
+				  if (sp)
+				    {
+				      imgdata.lens.makernotes.MinAp4CurFocal = atof(sp);
+				      if (imgdata.lens.makernotes.MaxAp4CurFocal > imgdata.lens.makernotes.MinAp4CurFocal)
+				        my_swap (float, imgdata.lens.makernotes.MaxAp4CurFocal, imgdata.lens.makernotes.MinAp4CurFocal);
+				    }
+				}
+				if (!strcmp (name, "LENSFRANGE"))
+				{
+					char *sp;
+					imgdata.lens.makernotes.MinFocal = imgdata.lens.makernotes.MaxFocal = atof(value);
+					sp = strrchr (value, ' ');
+					if (sp)
+						{
+							imgdata.lens.makernotes.MaxFocal = atof(sp);
+							if ((imgdata.lens.makernotes.MaxFocal + 0.17f) < imgdata.lens.makernotes.MinFocal)
+								my_swap (float, imgdata.lens.makernotes.MaxFocal, imgdata.lens.makernotes.MinFocal);
+						}
+				}
+				if (!strcmp (name, "LENSMODEL"))
+				{
+					imgdata.lens.makernotes.LensID = atoi(value);
+					if (imgdata.lens.makernotes.LensID)
+					 imgdata.lens.makernotes.LensMount = Sigma_X3F;
+				}
+		  }
+		  imgdata.idata.raw_count=1;
+		  load_raw = &LibRaw::x3f_load_raw;
+		  imgdata.sizes.raw_pitch = imgdata.sizes.raw_width*6;
+		  imgdata.idata.is_foveon = 1;
+		  libraw_internal_data.internal_output_params.raw_color=1; // Force adobe coeff
+		  imgdata.color.maximum=0x3fff; // To be reset by color table
+		  libraw_internal_data.unpacker_data.order = 0x4949;
+	  }
+  }
+  else
+  {
+	  // No property list
+	  if(imgdata.sizes.raw_width == 5888 ||imgdata.sizes.raw_width == 2944 ) // dp2Q
+	  {
+		  imgdata.idata.raw_count=1;
+		  load_raw = &LibRaw::x3f_load_raw;
+		  imgdata.sizes.raw_pitch = imgdata.sizes.raw_width*6;
+		  imgdata.idata.is_foveon = 1;
+		  libraw_internal_data.internal_output_params.raw_color=1; // Force adobe coeff
+		  libraw_internal_data.unpacker_data.order = 0x4949;
+		  strcpy (imgdata.idata.make, "SIGMA");
+#if 1
+		  // Try to find model number in first 2048 bytes;
+		  int pos = libraw_internal_data.internal_data.input->tell();
+		  libraw_internal_data.internal_data.input->seek(0,SEEK_SET);
+		  unsigned char buf[2048];
+		  libraw_internal_data.internal_data.input->read(buf,2048,1);
+		  libraw_internal_data.internal_data.input->seek(pos,SEEK_SET);
+		  unsigned char *fnd=(unsigned char*)lr_memmem(buf,2048,"SIGMA dp",8);
+		  if(fnd)
+		  {
+			  unsigned char *nm = fnd+8;
+			  snprintf(imgdata.idata.model,64,"dp%c Quattro",*nm<='9' && *nm >='0' ? *nm: '2');
+		  }
+		  else
+#endif
+			strcpy (imgdata.idata.model, "dp2 Quattro");
+	  }
+  }
+  // Try to get thumbnail data
+  LibRaw_thumbnail_formats format = LIBRAW_THUMBNAIL_UNKNOWN;
+  if(DE = x3f_get_thumb_jpeg(x3f))
+    {
+      format = LIBRAW_THUMBNAIL_JPEG;
+    }
+  else if(DE = x3f_get_thumb_plain(x3f))
+    {
+      format = LIBRAW_THUMBNAIL_BITMAP;
+    }
+  if(DE)
+    {
+      x3f_directory_entry_header_t *DEH = &DE->header;
+      x3f_image_data_t *ID = &DEH->data_subsection.image_data;
+      imgdata.thumbnail.twidth = ID->columns;
+      imgdata.thumbnail.theight = ID->rows;
+      imgdata.thumbnail.tcolors = 3;
+      imgdata.thumbnail.tformat = format;
+      libraw_internal_data.internal_data.toffset = DE->input.offset;
+      write_thumb = &LibRaw::x3f_thumb_loader;
+    }
+}
+
+void LibRaw::x3f_thumb_loader()
+{
+  x3f_t *x3f = (x3f_t*)_x3f_data;
+  if(!x3f) return; // No data pointer set
+  x3f_directory_entry_t *DE = x3f_get_thumb_jpeg(x3f);
+  if(!DE)
+    DE = x3f_get_thumb_plain(x3f);
+  if(!DE)
+    return;
+  if(X3F_OK != x3f_load_data(x3f, DE))
+    throw LIBRAW_EXCEPTION_IO_CORRUPT;
+  x3f_directory_entry_header_t *DEH = &DE->header;
+  x3f_image_data_t *ID = &DEH->data_subsection.image_data;
+  imgdata.thumbnail.twidth = ID->columns;
+  imgdata.thumbnail.theight = ID->rows;
+  imgdata.thumbnail.tcolors = 3;
+  if(imgdata.thumbnail.tformat == LIBRAW_THUMBNAIL_JPEG)
+    {
+      imgdata.thumbnail.thumb = (char*)malloc(ID->data_size);
+      merror(imgdata.thumbnail.thumb,"LibRaw::x3f_thumb_loader()");
+      memmove(imgdata.thumbnail.thumb,ID->data,ID->data_size);
+      imgdata.thumbnail.tlength = ID->data_size;
+    }
+  else if(imgdata.thumbnail.tformat == LIBRAW_THUMBNAIL_BITMAP)
+    {
+      imgdata.thumbnail.tlength = ID->columns * ID->rows * 3;
+      imgdata.thumbnail.thumb = (char*)malloc(ID->columns * ID->rows * 3);
+      merror(imgdata.thumbnail.thumb,"LibRaw::x3f_thumb_loader()");
+      char *src0 = (char*)ID->data;
+      for(int row = 0; row < ID->rows;row++)
+        {
+          char *dest = &imgdata.thumbnail.thumb[row*ID->columns*3];
+          char *src = &src0[row * ID->row_stride];
+          memmove(dest,src,ID->columns*3);
+        }
+    }
+}
+
+static inline uint32_t _clampbits(int x, uint32_t n) {
+	uint32_t _y_temp;
+	if( (_y_temp=x>>n) )
+		x = ~_y_temp >> (32-n);
+	return x;
+}
+
+void LibRaw::x3f_dpq_interpolate_rg()
+{
+	int w = imgdata.sizes.raw_width/2;
+	int h = imgdata.sizes.raw_height/2;
+	unsigned short *image = (ushort*)imgdata.rawdata.color3_image;
+
+	for (int color = 0; color < 2;  color++)
+	{
+		for (int y = 2; y < (h-2); y++)
+		{
+			uint16_t* row0 = &image[imgdata.sizes.raw_width*3*(y*2)+color]; // dst[1]
+			uint16_t  row0_3 = row0[3];
+			uint16_t* row1 = &image[imgdata.sizes.raw_width*3*(y*2+1)+color]; //dst1[1]
+			uint16_t  row1_3 = row1[3];
+			for (int x = 2; x < (w-2); x++)
+			{
+				row1[0]=row1[3]=row0[3]=row0[0];
+				row0 += 6;
+				row1 += 6;
+			}
+		}
+	}
+}
+
+#define _ABS(a) ((a)<0?-(a):(a))
+
+#undef CLIP
+#define CLIP(value,high) ((value)>(high)?(high):(value))
+
+void LibRaw::x3f_dpq_interpolate_af(int xstep, int ystep, int scale)
+{
+	unsigned short *image = (ushort*)imgdata.rawdata.color3_image;
+	unsigned int rowpitch = imgdata.rawdata.sizes.raw_pitch/2; // in 16-bit words
+		// Interpolate single pixel
+	for(int y = 0;  y < imgdata.rawdata.sizes.height+imgdata.rawdata.sizes.top_margin; y+=ystep)
+	{
+		if(y<imgdata.rawdata.sizes.top_margin) continue;
+		if(y<scale) continue;
+		if(y>imgdata.rawdata.sizes.raw_height-scale) break;
+		uint16_t* row0 = &image[imgdata.sizes.raw_width*3*y]; // Наша строка
+		uint16_t* row_minus = &image[imgdata.sizes.raw_width*3*(y-scale)]; // Строка выше
+		uint16_t* row_plus = &image[imgdata.sizes.raw_width*3*(y+scale)]; // Строка ниже
+		for(int x = 0; x < imgdata.rawdata.sizes.width+imgdata.rawdata.sizes.left_margin; x+= xstep)
+			{
+				if(x<imgdata.rawdata.sizes.left_margin) continue;
+				if(x<scale) continue;
+				if(x>imgdata.rawdata.sizes.raw_width-scale) break;
+				uint16_t* pixel0 = &row0[x*3];
+				uint16_t* pixel_top = &row_minus[x*3];
+				uint16_t* pixel_bottom = &row_plus[x*3];
+				uint16_t* pixel_left = &row0[(x-scale)*3];
+				uint16_t* pixel_right = &row0[(x+scale)*3];
+				uint16_t* pixf = pixel_top;
+				if(_ABS(pixf[2]-pixel0[2])>_ABS(pixel_bottom[2]-pixel0[2]))
+					pixf = pixel_bottom;
+				if(_ABS(pixf[2]-pixel0[2])>_ABS(pixel_left[2]-pixel0[2]))
+					pixf = pixel_left;
+				if(_ABS(pixf[2]-pixel0[2])>_ABS(pixel_right[2]-pixel0[2]))
+					pixf = pixel_right;
+				int blocal = pixel0[2],bnear = pixf[2];
+				if(blocal < imgdata.color.black+16 || bnear < imgdata.color.black+16	)
+				{
+					pixel0[0] = CLIP((pixel0[0] - imgdata.color.black)*4 + imgdata.color.black,16383);
+					pixel0[1] = CLIP((pixel0[1] - imgdata.color.black)*4 + imgdata.color.black,16383);
+				}
+				else
+				{
+					float multip = float(bnear - imgdata.color.black)/float(blocal-imgdata.color.black);
+					pixel0[0] = CLIP(((float(pixf[0]-imgdata.color.black)*multip + imgdata.color.black)+((pixel0[0]-imgdata.color.black)*3.75 + imgdata.color.black))/2,16383);
+					pixel0[1] = CLIP(((float(pixf[1]-imgdata.color.black)*multip + imgdata.color.black)+((pixel0[1]-imgdata.color.black)*3.75 + imgdata.color.black))/2,16383);
+					//pixel0[1] = float(pixf[1]-imgdata.color.black)*multip + imgdata.color.black;
+				}
+			}
+		}
+}
+
+
+void LibRaw::x3f_load_raw()
+{
+  int raise_error=0;
+  x3f_t *x3f = (x3f_t*)_x3f_data;
+  if(!x3f) return; // No data pointer set
+  if(X3F_OK == x3f_load_data(x3f, x3f_get_raw(x3f)))
+    {
+      x3f_directory_entry_t *DE = x3f_get_raw(x3f);
+      x3f_directory_entry_header_t *DEH = &DE->header;
+      x3f_image_data_t *ID = &DEH->data_subsection.image_data;
+      x3f_huffman_t *HUF = ID->huffman;
+      x3f_true_t *TRU = ID->tru;
+      uint16_t *data = NULL;
+      if(ID->rows != S.raw_height || ID->columns != S.raw_width)
+        {
+          raise_error = 1;
+          goto end;
+        }
+      if (HUF != NULL)
+        data = HUF->x3rgb16.element;
+      if (TRU != NULL)
+        data = TRU->x3rgb16.element;
+      if (data == NULL)
         {
-        case LIBRAW_PROGRESS_START:
-            return "Starting";
-        case LIBRAW_PROGRESS_OPEN :
-            return "Opening file";
-        case LIBRAW_PROGRESS_IDENTIFY :
-            return "Reading metadata";
-        case LIBRAW_PROGRESS_SIZE_ADJUST:
-            return "Adjusting size";
-        case LIBRAW_PROGRESS_LOAD_RAW:
-            return "Reading RAW data";
-        case LIBRAW_PROGRESS_REMOVE_ZEROES:
-            return "Clearing zero values";
-        case LIBRAW_PROGRESS_BAD_PIXELS :
-            return "Removing dead pixels";
-        case LIBRAW_PROGRESS_DARK_FRAME:
-            return "Subtracting dark frame data";
-        case LIBRAW_PROGRESS_FOVEON_INTERPOLATE:
-            return "Interpolating Foveon sensor data";
-        case LIBRAW_PROGRESS_SCALE_COLORS:
-            return "Scaling colors";
-        case LIBRAW_PROGRESS_PRE_INTERPOLATE:
-            return "Pre-interpolating";
-        case LIBRAW_PROGRESS_INTERPOLATE:
-            return "Interpolating";
-        case LIBRAW_PROGRESS_MIX_GREEN :
-            return "Mixing green channels";
-        case LIBRAW_PROGRESS_MEDIAN_FILTER   :
-            return "Median filter";
-        case LIBRAW_PROGRESS_HIGHLIGHTS:
-            return "Highlight recovery";
-        case LIBRAW_PROGRESS_FUJI_ROTATE :
-            return "Rotating Fuji diagonal data";
-        case LIBRAW_PROGRESS_FLIP :
-            return "Flipping image";
-        case LIBRAW_PROGRESS_APPLY_PROFILE:
-            return "ICC conversion";
-        case LIBRAW_PROGRESS_CONVERT_RGB:
-            return "Converting to RGB";
-        case LIBRAW_PROGRESS_STRETCH:
-            return "Stretching image";
-        case LIBRAW_PROGRESS_THUMB_LOAD:
-            return "Loading thumbnail";
-        default:
-            return "Some strange things";
+          raise_error = 1;
+          goto end;
         }
+      imgdata.rawdata.color3_image = (ushort (*)[3])data;
+
+	  if(!strcasecmp(imgdata.idata.make,"Sigma")
+		  && (!strcasecmp(imgdata.idata.model,"dp2 Quattro")  || !strcasecmp(imgdata.idata.model,"dp1 Quattro"))
+		  && (imgdata.params.x3f_flags & LIBRAW_DP2Q_INTERPOLATEAF)
+		  )
+	  {
+		  if(imgdata.sizes.raw_width == 5888)
+		  {
+			  x3f_dpq_interpolate_af(32,8,2);
+		  }
+		  if(imgdata.sizes.raw_width == 2944)
+		  {
+			  x3f_dpq_interpolate_af(16,4,1);
+		  }
+	  }
+
+	  if(!strcasecmp(imgdata.idata.make,"Sigma")
+		  && (!strcasecmp(imgdata.idata.model,"dp2 Quattro") || !strcasecmp(imgdata.idata.model,"dp1 Quattro"))
+		  && (imgdata.params.x3f_flags & LIBRAW_DP2Q_INTERPOLATERG)
+		  && (imgdata.sizes.raw_width== 5888)
+		  )
+			x3f_dpq_interpolate_rg();
+
+
+  }
+  else
+    raise_error = 1;
+end:
+  if(raise_error)
+    throw LIBRAW_EXCEPTION_IO_CORRUPT;
 }
+
diff --git a/Source/LibRawLite/src/libraw_datastream.cpp b/Source/LibRawLite/src/libraw_datastream.cpp
index be05e05..54ea691 100644
--- a/Source/LibRawLite/src/libraw_datastream.cpp
+++ b/Source/LibRawLite/src/libraw_datastream.cpp
@@ -1,3 +1,23 @@
+/* -*- C++ -*-
+ * File: libraw_datastream.cpp
+ * Copyright 2008-2013 LibRaw LLC (info at libraw.org)
+ *
+ * LibRaw C++ interface (implementation)
+
+ LibRaw is free software; you can redistribute it and/or modify
+ it under the terms of the one of three licenses as you choose:
+
+1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
+   (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
+
+2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
+   (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
+
+3. LibRaw Software License 27032010
+   (See file LICENSE.LibRaw.pdf provided in LibRaw distribution archive for details).
+
+*/
+
 #ifdef WIN32
 #ifdef __MINGW32__
     #define _WIN32_WINNT 0x0500
@@ -9,39 +29,17 @@
 #include "libraw/libraw_types.h"
 #include "libraw/libraw.h"
 #include "libraw/libraw_datastream.h"
-#include "internal/libraw_bytebuffer.h"
+#include <sys/stat.h>
 #ifdef USE_JASPER
 #include <jasper/jasper.h>	/* Decode RED camera movies */
 #else
 #define NO_JASPER
 #endif
-
-
-LibRaw_byte_buffer::LibRaw_byte_buffer(unsigned sz) 
-{ 
-    buf=0; size=sz; offt=0; do_free=0; 
-    if(size)
-        { 
-            buf = (unsigned char*)malloc(size); do_free=1;
-        }
-}
-
-void LibRaw_byte_buffer::set_buffer(void *bb, unsigned int sz) 
-{ 
-    buf = (unsigned char*)bb; size = sz; offt=0; do_free=0;
-}
-
-LibRaw_byte_buffer::~LibRaw_byte_buffer() 
-{ 
-    if(do_free) free(buf);
-}
-
-LibRaw_byte_buffer *LibRaw_abstract_datastream::make_byte_buffer(unsigned int sz)
-{
-    LibRaw_byte_buffer *ret = new LibRaw_byte_buffer(sz);
-    read(ret->get_buffer(),sz,1);
-    return ret;
-}
+#ifdef USE_JPEG
+#include <jpeglib.h>
+#else
+#define NO_JPEG
+#endif
 
 int LibRaw_abstract_datastream::tempbuffer_open(void  *buf, size_t size)
 {
@@ -59,17 +57,58 @@ void	LibRaw_abstract_datastream::tempbuffer_close()
 
 // == LibRaw_file_datastream ==
 
+LibRaw_file_datastream::~LibRaw_file_datastream()
+{
+  if(jas_file) fclose(jas_file);
+}
+
 LibRaw_file_datastream::LibRaw_file_datastream(const char *fname)
     :filename(fname)
+#ifdef WIN32
+    ,wfilename()
+#endif
+    ,jas_file(NULL),_fsize(0)
 {
-    if (filename) {
-        std::auto_ptr<std::filebuf> buf(new std::filebuf());
-        buf->open(filename, std::ios_base::in | std::ios_base::binary);
-        if (buf->is_open()) {
-            f = buf;
-        }
+  if (filename.size()>0) 
+    {
+#ifndef WIN32
+      struct stat st;
+      if(!stat(filename.c_str(),&st))
+        _fsize = st.st_size;	
+#else
+      struct _stati64 st;
+      if(!_stati64(filename.c_str(),&st))
+        _fsize = st.st_size;
+#endif
+      
+      std::auto_ptr<std::filebuf> buf(new std::filebuf());
+      buf->open(filename.c_str(), std::ios_base::in | std::ios_base::binary);
+      if (buf->is_open()) {
+        f = buf;
+      }
     }
 }
+#if defined(_WIN32) && !defined(__MINGW32__) && defined(_MSC_VER) && (_MSC_VER > 1310)
+LibRaw_file_datastream::LibRaw_file_datastream(const wchar_t *fname) : filename(),wfilename(fname),jas_file(NULL),_fsize(0)
+{
+  if (wfilename.size()>0) 
+    {
+      struct _stati64 st;
+      if(!_wstati64(wfilename.c_str(),&st))
+        _fsize = st.st_size;
+      std::auto_ptr<std::filebuf> buf(new std::filebuf());
+      buf->open(wfilename.c_str(), std::ios_base::in | std::ios_base::binary);
+      if (buf->is_open()) {
+        f = buf;
+      }
+    }
+}
+const wchar_t *LibRaw_file_datastream::wfname()
+{
+  return wfilename.size()>0?wfilename.c_str():NULL;
+}
+#endif
+
  int LibRaw_file_datastream::valid()
 { 
     return f.get() ? 1 : 0; 
@@ -83,9 +122,9 @@ int LibRaw_file_datastream::read(void * ptr,size_t size, size_t nmemb)
     
 /* Visual Studio 2008 marks sgetn as insecure, but VS2010 does not. */
 #if defined(WIN32SECURECALLS) && (_MSC_VER < 1600)
-    LR_STREAM_CHK(); return int(f->_Sgetn_s(static_cast<char*>(ptr), nmemb * size,nmemb * size) / size); 
+    LR_STREAM_CHK(); return int(f->_Sgetn_s(static_cast<char*>(ptr), nmemb * size,nmemb * size) / (size>0?size:1)); 
 #else
-    LR_STREAM_CHK(); return int(f->sgetn(static_cast<char*>(ptr), std::streamsize(nmemb * size)) / size); 
+    LR_STREAM_CHK(); return int(f->sgetn(static_cast<char*>(ptr), std::streamsize(nmemb * size)) / (size>0?size:1)); 
 #endif
 }
 
@@ -107,7 +146,7 @@ int LibRaw_file_datastream::seek(INT64 o, int whence)
         case SEEK_END: dir = std::ios_base::end; break;
         default: dir = std::ios_base::beg;
         }
-    return (int)f->pubseekoff((long)o, dir);
+    return f->pubseekoff((long)o, dir) < 0;
 }
 
 INT64 LibRaw_file_datastream::tell()     
@@ -151,7 +190,7 @@ int LibRaw_file_datastream::scanf_one(const char *fmt, void*val)
 
 const char* LibRaw_file_datastream::fname() 
 { 
-    return filename; 
+  return filename.size()>0?filename.c_str():NULL; 
 }
     
 /* You can't have a "subfile" and a "tempfile" at the same time. */
@@ -173,6 +212,26 @@ int LibRaw_file_datastream::subfile_open(const char *fn)
         return 0;
 }
 
+#if defined(_WIN32) && !defined(__MINGW32__) && defined(_MSC_VER) && (_MSC_VER > 1310)
+int LibRaw_file_datastream::subfile_open(const wchar_t *fn)
+{
+	LR_STREAM_CHK();
+	if (saved_f.get()) return EBUSY;
+	saved_f = f;
+	std::auto_ptr<std::filebuf> buf(new std::filebuf());
+
+	buf->open(fn, std::ios_base::in | std::ios_base::binary);
+	if (!buf->is_open()) {
+		f = saved_f;
+		return ENOENT;
+	} else {
+		f = buf;
+	}
+
+	return 0;
+}
+#endif
+
 
 void LibRaw_file_datastream::subfile_close()
 { 
@@ -187,10 +246,48 @@ void * LibRaw_file_datastream::make_jas_stream()
 #ifdef NO_JASPER
     return NULL;
 #else
-    return jas_stream_fopen(fname(),"rb");
+#if defined(_WIN32) && !defined(__MINGW32__) && defined(_MSC_VER) && (_MSC_VER > 1310)
+	if(wfname())
+	{
+		jas_file = _wfopen(wfname(),L"rb");
+		return jas_stream_fdopen(fileno(jas_file),"rb");
+	}
+	else
+#endif
+	{
+		return jas_stream_fopen(fname(),"rb");
+	}
 #endif
 }
 
+int LibRaw_file_datastream::jpeg_src(void *jpegdata)
+{
+#ifdef NO_JPEG
+  return -1; // not supported
+#else
+  if(jas_file) { fclose(jas_file); jas_file = NULL;}
+#if defined(_WIN32) && !defined(__MINGW32__) && defined(_MSC_VER) && (_MSC_VER > 1310)
+  if(wfname())
+    {
+      jas_file = _wfopen(wfname(),L"rb");
+    }
+  else
+#endif
+    {
+      jas_file = fopen(fname(),"rb");
+    }
+  if(jas_file)
+    {
+      fseek(jas_file,tell(),SEEK_SET);
+      j_decompress_ptr cinfo = (j_decompress_ptr) jpegdata;
+      jpeg_stdio_src(cinfo,jas_file);
+      return 0; // OK
+    }
+  return -1;
+#endif
+}
+
+
 // == LibRaw_buffer_datastream
 LibRaw_buffer_datastream::LibRaw_buffer_datastream(void *buffer, size_t bsize)
 {    
@@ -209,7 +306,7 @@ int LibRaw_buffer_datastream::read(void * ptr,size_t sz, size_t nmemb)
         return 0;
     memmove(ptr,buf+streampos,to_read);
     streampos+=to_read;
-    return int((to_read+sz-1)/sz);
+    return int((to_read+sz-1)/(sz>0?sz:1));
 }
 
 int LibRaw_buffer_datastream::seek(INT64 o, int whence)
@@ -314,15 +411,6 @@ int LibRaw_buffer_datastream::scanf_one(const char *fmt, void* val)
     return scanf_res;
 }
 
-LibRaw_byte_buffer *LibRaw_buffer_datastream::make_byte_buffer(unsigned int sz)
-{
-    LibRaw_byte_buffer *ret = new LibRaw_byte_buffer(0);
-    if(streampos + sz > streamsize)
-        sz = streamsize - streampos;
-    ret->set_buffer(buf+streampos,sz);
-    return ret;
-}
-
 int LibRaw_buffer_datastream::eof()
 { 
     if(substream) return substream->eof();
@@ -339,28 +427,83 @@ void * LibRaw_buffer_datastream::make_jas_stream()
 #ifdef NO_JASPER
     return NULL;
 #else
-    return jas_stream_memopen((char*)buf,streamsize);
+    return jas_stream_memopen((char*)buf+streampos,streamsize-streampos);
 #endif
 }
 
+int LibRaw_buffer_datastream::jpeg_src(void *jpegdata)
+{
+#if defined(NO_JPEG) || !defined (USE_JPEG8)
+  return -1;
+#else
+  j_decompress_ptr cinfo = (j_decompress_ptr) jpegdata;
+  jpeg_mem_src(cinfo,(unsigned char*)buf+streampos,streamsize-streampos);
+  return 0;
+#endif
+}
+
+
+//int LibRaw_buffer_datastream
+
+
 // == LibRaw_bigfile_datastream
-LibRaw_bigfile_datastream::LibRaw_bigfile_datastream(const char *fname)
+LibRaw_bigfile_datastream::LibRaw_bigfile_datastream(const char *fname): filename(fname)
+#ifdef WIN32
+	,wfilename()
+#endif
 { 
-    if(fname)
-        {
-            filename = fname; 
+  if(filename.size()>0)
+    {
+#ifndef WIN32
+      struct stat st;
+      if(!stat(filename.c_str(),&st))
+        _fsize = st.st_size;	
+#else
+      struct _stati64 st;
+      if(!_stati64(filename.c_str(),&st))
+        _fsize = st.st_size;
+#endif
+
 #ifndef WIN32SECURECALLS
-            f = fopen(fname,"rb");
+      f = fopen(fname,"rb");
 #else
-            if(fopen_s(&f,fname,"rb"))
-                f = 0;
+      if(fopen_s(&f,fname,"rb"))
+        f = 0;
 #endif
-        }
+    }
     else 
-        {filename=0;f=0;}
+      {filename=std::string();f=0;}
     sav=0;
 }
 
+#if defined(_WIN32) && !defined(__MINGW32__) && defined(_MSC_VER) && (_MSC_VER > 1310)
+LibRaw_bigfile_datastream::LibRaw_bigfile_datastream(const wchar_t *fname) : filename(),wfilename(fname)
+{ 
+  if(wfilename.size()>0)
+    {
+      struct _stati64 st;
+      if(!_wstati64(wfilename.c_str(),&st))
+        _fsize = st.st_size;
+#ifndef WIN32SECURECALLS
+      f = _wfopen(wfilename.c_str(),L"rb");
+#else
+      if(_wfopen_s(&f,fname,L"rb"))
+        f = 0;
+#endif
+    }
+  else 
+    {
+      wfilename=std::wstring();
+      f=0;
+    }
+  sav=0;
+}
+const wchar_t *LibRaw_bigfile_datastream::wfname()
+{
+  return wfilename.size()>0?wfilename.c_str():NULL;
+}
+#endif
+
 LibRaw_bigfile_datastream::~LibRaw_bigfile_datastream() {if(f)fclose(f); if(sav)fclose(sav);}
 int         LibRaw_bigfile_datastream::valid() { return f?1:0;}
 
@@ -426,7 +569,7 @@ int LibRaw_bigfile_datastream::scanf_one(const char *fmt, void*val)
 
 const char *LibRaw_bigfile_datastream::fname() 
 { 
-    return filename; 
+  return filename.size()>0?filename.c_str():NULL; 
 }
 
 int LibRaw_bigfile_datastream::subfile_open(const char *fn)
@@ -447,6 +590,27 @@ int LibRaw_bigfile_datastream::subfile_open(const char *fn)
     else
         return 0;
 }
+#if defined(_WIN32) && !defined(__MINGW32__) && defined(_MSC_VER) && (_MSC_VER > 1310)
+int LibRaw_bigfile_datastream::subfile_open(const wchar_t *fn)
+{
+	if(sav) return EBUSY;
+	sav = f;
+#ifndef WIN32SECURECALLS
+	f = _wfopen(fn,L"rb");
+#else
+	_wfopen_s(&f,fn,L"rb");
+#endif
+	if(!f)
+	{
+		f = sav;
+		sav = NULL;
+		return ENOENT;
+	}
+	else
+		return 0;
+}
+#endif
+
 
 void LibRaw_bigfile_datastream::subfile_close()
 {
@@ -462,10 +626,23 @@ void *LibRaw_bigfile_datastream::make_jas_stream()
 #ifdef NO_JASPER
     return NULL;
 #else
-    return jas_stream_freopen(fname(),"rb",f);
+    return jas_stream_fdopen(fileno(f),"rb");
 #endif
 }
 
+int LibRaw_bigfile_datastream::jpeg_src(void *jpegdata)
+{
+#ifdef NO_JPEG
+  return -1;
+#else
+  if(!f) return -1;
+  j_decompress_ptr cinfo = (j_decompress_ptr) jpegdata;
+  jpeg_stdio_src(cinfo,f);
+  return 0; // OK
+#endif
+}
+
+
 // == LibRaw_windows_datastream
 #ifdef WIN32
 
diff --git a/Source/LibTIFF/ChangeLog b/Source/LibTIFF/ChangeLog
deleted file mode 100644
index f3dfe26..0000000
--- a/Source/LibTIFF/ChangeLog
+++ /dev/null
@@ -1,4849 +0,0 @@
-2011-04-09  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* libtiff 3.9.5 released.
-
-2011-04-09  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* configure.ac: Should use AC_CANONICAL_HOST since host specifies
-	the run-time target whereas target is used to specify the final
-	output target if the package is a build tool (like a compiler),
-	which libtiff is not.  Resolves libtiff bug 2307 "Use
-	AC_CANONICAL_HOST macro".
-
-2011-04-02  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* tools/fax2ps.c (main): Use tmpfile() rather than mkstemp() since
-	it is much more portable.  Tmpfile is included in ISO/IEC
-	9899:1990 and the WIN32 CRT.
-
-2011-03-21  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tiffiop.h: avoid declaring int64/uint64 on AIX with XLC
-	where they are already available.  (#2301)
-
-	* libtiff/tif_thunder.c: Correct potential buffer overflow with 
-	thunder encoded files with wrong bitspersample set.  The libtiff 
-	development team would like to thank Marin Barbella and TippingPoint's
-	Zero Day Initiative for reporting this vulnerability (ZDI-CAN-1004,
-	CVE-2011-1167).
-	http://bugzilla.maptools.org/show_bug.cgi?id=2300
-
-2011-03-10  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_fax3.h: Fix to last change allowing zero length 
-	runs at the start of a scanline - needed for legal cases.
-
-2011-03-02  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_fax3.h: Protect against a fax VL(n) codeword commanding 
-	a move left.  Without this, a malicious input file can generate an 
-	indefinitely large series of runs without a0 ever reaching the right 
-	margin, thus overrunning our buffer of run lengths.  Per CVE-2011-0192.
-	This is a modified version of a patch proposed by Drew Yao of Apple 
-	Product Security.  It adds an unexpected() report, and disallows the 
-	equality case, since emitting a run without increasing a0 still allows 
-	buffer overrun.
-
-2011-02-25  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_dirwrite.c: Avoid undefined behaviour when casting from
-	float to unsigned integer in TIFFWriteRationalArray() as reported by
-	Kareem Shehata.
-
-2011-01-03  Lee Howard <faxguy at howardsilvan.com>
-
-	* libtiff/tif_jpeg.c: Fix regressions with 2 and 3 band images
-	caused by commit on 2010-12-14.  Submitted by e-mail from 
-	Even Rouault <even.rouault at mines-paris.org>
-
-2010-12-31  Olivier Paquet  <olivier.paquet at gmail.com>
-
-	* libtiff/tif_dirread.c: Allow reading directories where
-	TIFFTAG_SMINSAMPLEVALUE and TIFFTAG_SMAXSAMPLEVALUE values differ for each
-	channel. The min/max of all channels is used as appropriate.
-
-2010-12-14  Lee Howard <faxguy at howardsilvan.com>
-
-	* libtiff/tif_dirread.c: tolerate some cases where
-	FIELD_COLORMAP is missing
-	http://bugzilla.maptools.org/show_bug.cgi?id=2189
-
-2010-12-14  Lee Howard <faxguy at howardsilvan.com>
-
-	* libtiff/tif_strip.c: use TIFFGetFieldDefaulted instead
-	of TIFFGetField when we assume that it will succeed
-	http://bugzilla.maptools.org/show_bug.cgi?id=2215
-
-2010-12-14  Lee Howard <faxguy at howardsilvan.com>
-
-	* tools/gif2tiff.c: fix buffer overrun
-	http://bugzilla.maptools.org/show_bug.cgi?id=2270
-
-2010-12-14  Lee Howard <faxguy at howardsilvan.com>
-
-	* libtiff/tif_jpeg.c: reduce usage of JCS_UNKNOWN in order
-	to improve compatibility with various viewers
-	submitted by e-mail from Dwight Kelly <dkelly at apago.com>
-
-2010-12-13  Lee Howard <faxguy at howardsilvan.com>
-
-	* tools/fax2ps.c: be consistent with page-numbering
-	http://bugzilla.maptools.org/show_bug.cgi?id=2225
-
-2010-12-13  Lee Howard <faxguy at howardsilvan.com>
-
-	* libtiff/tif_dirread.c: fix needless tag ordering warning
-	http://bugzilla.maptools.org/show_bug.cgi?id=2210
-
-2010-12-13  Lee Howard <faxguy at howardsilvan.com>
-
-	* libtiff/tif_color.c: prevent crash in handling bad TIFFs
-	resolves CVE-2010-2595
-	http://bugzilla.maptools.org/show_bug.cgi?id=2208
-
-2010-12-13  Lee Howard <faxguy at howardsilvan.com>
-
-	* tools/tiffcrop.c: new release by Richard Nolde
-	http://bugzilla.maptools.org/show_bug.cgi?id=2004
-
-2010-12-12  Lee Howard <faxguy at howardsilvan.com>
-
-	* tools/tiff2pdf.c: fix colors for images with RGBA 
-	interleaved data
-	http://bugzilla.maptools.org/show_bug.cgi?id=2250
-
-2010-12-11  Lee Howard <faxguy at howardsilvan.com>
-
-	* tools/tiff2pdf.c: remove invalid duplication for Lab 
-	http://bugzilla.maptools.org/show_bug.cgi?id=2162
-
-2010-12-11  Lee Howard <faxguy at howardsilvan.com>
-
-	* libtiff/tif_jpeg.c: fix use of clumplines calculation
-	http://bugzilla.maptools.org/show_bug.cgi?id=2149
-
-2010-12-11  Lee Howard <faxguy at howardsilvan.com>
-
-	* tools/fax2ps.c: replace unsafe tmpfile() with mkstemp()
-	http://bugzilla.maptools.org/show_bug.cgi?id=2118
-
-2010-12-11  Lee Howard <faxguy at howardsilvan.com>
-
-	* tools/tiff2pdf.c: add fill-page option
-	 http://bugzilla.maptools.org/show_bug.cgi?id=2051
-
-2010-12-11  Lee Howard <faxguy at howardsilvan.com>
-
-	* libtiff/tif_dirread.c: modify warnings
-	http://bugzilla.maptools.org/show_bug.cgi?id=2016
-
-2010-12-11  Lee Howard <faxguy at howardsilvan.com>
-
-	* libtiff/tif_ojpeg.c: fix buffer overflow on problem data
-	http://bugzilla.maptools.org/show_bug.cgi?id=1999
-
-2010-12-11  Lee Howard <faxguy at howardsilvan.com>
-
-	* libtiff/tif_ojpeg.c: fix crash when reading a TIFF with a zero
-	or missing byte-count tag
-	* tools/tiffsplit.c: abort when reading a TIFF without a byte-count
-	per http://bugzilla.maptools.org/show_bug.cgi?id=1996
-
-2010-12-08  Lee Howard <faxguy at howardsilvan.com>
-
-	* libtiff/tif_dirread.c: fix crash when reading a badly-constructed
-	TIFF per http://bugzilla.maptools.org/show_bug.cgi?id=1994
-
-2010-12-07  Lee Howard <faxguy at howardsilvan.com>
-
-	* libtiff/tif_jpeg.c, libtiff/tif_strip.c: apply patch for 
-	CVE-2010-3087 per bug
-	http://bugzilla.maptools.org/show_bug.cgi?id=2140
-
-2010-12-06  Lee Howard <faxguy at howardsilvan.com>
-
-	* libtiff/tif_open.c: Fix mode check before opening a file.
-	http://bugzilla.maptools.org/show_bug.cgi?id=1906
-
-2010-09-25  Lee Howard <faxguy at howardsilvan.com>
-
-	* tools/tiff2ps.c: improvements and enhancements from Richard Nolde
-	with additional command line options for Document Title, 
-	Document Creator, and Page Orientation
-
-2010-07-13  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* tools/tiffcrop.c: Patch from Richard Nolde to avoid a
-	potentially unterminated buffer due to using an exceptionally long
-	file name.
-
-2010-07-08  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiff2pdf.c: Fixed ID buffer filling in
-	t2p_write_pdf_trailer(), thanks to Dmitry V. Levin.
-
-2010-07-07  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_dirread.c: Really reset the tag count in CheckDirCount()
-	to expected value as the warning message suggests. As per bug
-	http://bugzilla.maptools.org/show_bug.cgi?id=1963
-
-	* tools/tiffdump.c: Avoid integer overflows computing the buffer size
-	for large directories. As per bug
-	http://bugzilla.maptools.org/show_bug.cgi?id=2218
-
-2010-07-06  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiffset.c: Properly handle TIFFTAG_PAGENUMBER,
-	TIFFTAG_HALFTONEHINTS, TIFFTAG_YCBCRSUBSAMPLING, TIFFTAG_DOTRANGE
-	which should be set by value.
-
-	* libtiff/tif_dirinfo.c: Don't use assertions in _TIFFFieldWithTag()
-	and _TIFFFieldWithName() if the tag is not found in the tag table.
-	This should be normal situation and returned NULL value should be
-	properly handled by the caller.
-
-	* libtiff/{tif_dirwrite.c, tif_print.c}: Properly handle "DotRange"
-	tag as it can be either byte or short size and should be set and read
-	by value, not as an array. As per bug
-	http://bugzilla.maptools.org/show_bug.cgi?id=2116
-
-2010-07-02  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_getimage.c: Avoid wrong math du to the signed/unsigned
-	integer type conversions. As per bug
-	http://bugzilla.maptools.org/show_bug.cgi?id=2207
-
-	* tools/{tiff2bw.c, thumbnail.c, pal2rgb.c}: Fix the count for
-	WhitePoint tag as per bug
-	http://bugzilla.maptools.org/show_bug.cgi?id=2042
-
-	* tools/tiffdump.c: Use PrintData() function instead of
-	PrintByte/Short/Long(). Should fix an issue reported at
-	http://bugzilla.maptools.org/show_bug.cgi?id=2116
-
-	* libtiff/tif_getimage.c: Check the number of samples per pixel when
-	working with YCbCr image in PickContigCase(). As per bug
-	http://bugzilla.maptools.org/show_bug.cgi?id=2216
-
-	* libtiff/tif_dir.c: Set the bogus post-decoding hook when processing
-	TIFFTAG_BITSPERSAMPLE in _TIFFVSetField() for the case of 8 bit when
-	we don't need any post-processing. That helps to reset the hook if we
-	previously set this field to some other value and the hook was
-	initialized accordingly. As per bug
-	http://bugzilla.maptools.org/show_bug.cgi?id=2035
-
-2010-06-30  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiff2pdf.c: Better generation of ID field in
-	t2p_write_pdf_trailer(). Get rid of GCC aliasing warnings.
-
-	* tools/tiff2pdf.c: Fixed computation of the tile buffer size when
-	converting JPEG encoded tiles.
-
-	* tools/tiff2pdf.c: Better handling of string fields, use static
-	string buffers instead of dynamically allocated, use strncpy() instead
-	of strcpy(), control the string lengths.
-
-2010-06-25  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiffcp.c: Initialize buffer arrays with zero to avoid
-	referencing to uninitialized memory in some cases (e.g. when tile size
-	set bigger than the image size).
-
-2010-06-15  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* tools/tiffcrop.c: Patch from Richard Nolde. Reject YCbCr
-	subsampled data since tiffcrop currently doesn't support it.  Fix
-	JPEG support.
-
-2010-06-15  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* libtiff 3.9.4 released.
-
-2010-06-13  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_jpeg.c: avoid re-preparing jpeg tables unnecessarily
-	(gdal #3633, libtiff #2135).
-
-	* libtiff/tif_dirread.c: Fixed bad handling of out of order tags
-	definated late by a codec (#2210)
-
-	* libtiff/tif_dirread.c: Fixed inadequate validation of the 
-	SubjectDistance field (#2212).
-
-	* tiff2pdf.c: Fix assorted bugs in tiff2pdf: missing "return" 
-	in t2p_read_tiff_size() causes t2p->tiff_datasize to be set entirely 
-	wrong for COMPRESSION_JPEG case, resulting in memory stomp if actual 
-	size is larger.  Also, there are a bunch of places that try to 
-	memset() a malloc'd buffer before checking for malloc failure, which 
-	would result in core dump if there actually were a failure. (#2211)
-
-2010-06-11  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* tools/tiff2rgba.c: Applied portion of patch (from Tom Lane)
-	which was left out in order to fully resolve "CVE-2009-2347
-	libtiff: integer overflows in various inter-color space conversion
-	tools". http://bugzilla.maptools.org/show_bug.cgi?id=2079
-
-	* libtiff/tiffiop.h (TIFFSafeMultiply): Need more castings to
-	avoid compiler warnings if parameter types are not sign
-	consistent.
-
-	* tools/tiffcrop.c: Applied patch from Richard Nolde: Corrected
-	European page size dimensions.  Added an option to allow the user
-	to specify a custom page size on the command line.  Fix the case
-	where a page size specified with a fractional part was being
-	coerced to an integer by retyping the variables that define the
-	paper size.
-
-	* libtiff 3.9.3 released.
-
-	* tools/tiffcp.c (tiffcp): Applied Tom Lane's patch to reject
-	YCbCr subsampled data since tiffcp currently doesn't support it.
-	http://bugzilla.maptools.org/show_bug.cgi?id=2097
-
-	* Update libtool to version 2.2.10.
-
-2010-06-10  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* libtiff/tiffiop.h (TIFFSafeMultiply): Work properly if
-	multiplier is zero.
-
-2010-06-09  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* libtiff/tif_dir.h: Restore ReferenceBlackWhite as a non-custom
-	field.  This avoids a multi-thread reentrancy problem as well as
-	fixing output of wrong tag value due to redundant definitions for
-	the same tag in the tiffFieldInfo[] array.  Resolves
-	http://bugzilla.maptools.org/show_bug.cgi?id=2185
-
-	* libtiff/tif_fax3.c (Fax3SetupState): Yesterday's fix for
-	CVE-2010-1411 was not complete.
-
-	* libtiff/tiffiop.h (TIFFSafeMultiply): New macro to safely
-	multiply two integers.  Returns zero if there is an integer
-	overflow.
-
-	* tools/tiffcp.c (main): Fix more TIFF handle leaks.
-
-	* libtiff/tif_read.c (TIFFReadBufferSetup): Skip allocating
-	tif_rawdata if tif_rawdatasize becomes zero.
-
-2010-06-08  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* tools/tiffcrop.c: Removed duplicated macros such as
-	TIFFhowmany().
-
-	* Update libtool to version 2.2.8.
-
-	* libtiff/tif_fax3.c (Fax3SetupState): Avoid under-allocation of
-	buffer due to integer overflow in TIFFroundup() and several other
-	potential overflows.  In conjunction with the fix to TIFFhowmany(),
-	fixes CVE-2010-1411.
-
-	* libtiff/tiffiop.h (TIFFhowmany): Return zero if parameters would
-	result in an integer overflow. This causes TIFFroundup() to also
-	return zero if there would be an integer overflow.
-
-	* libtiff/tif_read.c (TIFFReadBufferSetup): Return an error if
-	tif_rawdatasize becomes zero due to an initial raw size of zero or
-	an overflow reported by TIFFroundup().
-
-	* libtiff/tif_ojpeg.c (OJPEGReadBufferFill): Report an error and
-	avoid a crash if the input file is so broken that the strip
-	offsets are not defined.
-
-	* tools/tiffcp.c (main): tiffcp should not leak memory if an error
-	is reported when reading the input file.
-
-	* libtiff/tif_aux.c (_TIFFCheckRealloc): Produce a fully detailed
-	error message string.
-
-	* Add an emacs formatting mode footer to all source files so that
-	emacs can be effectively used.
-
-2010-06-03  Oliver Chen Feng <scip8183 at gmail.com>
-
-        * libtiff/tools/tiffcp.c: add a new option -x to force merged tiff
-	file PAGENUMBER value in sequence for users who care the page
-	sequence, this will also prevent tiff2pdf from creating pdf file from
-	the merged tiff file with wrong page sequence.
-
-2010-05-07  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_jpeg.c: Ensure that quality is always set in 
-	JPEGPreEncode(), not just when we want to output local tables.  
-	Otherwise the quality used during compression may not be right and
-	might not match the tables in the tables tag.   This bug only occurs
-	when seeking between directories in the midst of writing blocks.
-	http://trac.osgeo.org/gdal/ticket/3539
-	
-2010-05-05  Olivier Paquet  <olivier.paquet at gmail.com>
-
-	* libtiff/tif_print.c: Have TIFFTAG_REFERENCEBLACKWHITE always print 6
-	floats instead of 2*SamplesPerPixel.
-	http://bugzilla.maptools.org/show_bug.cgi?id=2186
-	* man/TIFFGetField.3tiff, man/TIFFSetField.3tiff: Fixed doc to reflect the
-	fact that libtiff considers TIFFTAG_REFERENCEBLACKWHITE to be 6 floats.
-
-2010-04-10  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* tools/ppm2tiff.c (main): While case for parsing comment line
-	requires extra parenthesis to work as expected.  Reported by
-	Thomas Sinclair.
-
-2010-02-22  Lee Howard  <faxguy at howardsilvan.com>
-
-	* libtiff/tif_jpeg.c: Do not generate a JPEGTables tag when creating
-	the JPEG TIFF as is is not required in order to prevent it from 
-	being unused and filled with invalid data.  (Leave it to be 
-	generated by later activity.)
-	http://bugzilla.maptools.org/show_bug.cgi?id=2135
-	* tools/tiff2pdf.c: Write the JPEG SOI headers into the TIFF strip 
-	data rather than skipping them.  This fixes the ability to view in
-	Acrobat Reader, Evince, and Ghostscript.
-	http://bugzilla.maptools.org/show_bug.cgi?id=2135
-	* libtiff/tif_fax3.c: Don't return error on badly-terminated MMR
-	strips.
-	http://bugzilla.maptools.org/show_bug.cgi?id=2029
-
-2010-01-06  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_dir.c: Ensure tile and scanline sizes are reset
-	when moving to new directories. 
-	http://bugzilla.maptools.org/show_bug.cgi?id=1936
-
-2009-12-03  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_jpeg.c: Fix a couple of issues that trigger failures in
-	some cases when using TIFFReadScanline() with JPEG compressed 
-	subsampled ycbcr images.
-	http://bugzilla.maptools.org/show_bug.cgi?id=1936
-
-2009-11-04  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* libtiff 3.9.2 released.
-
-2009-11-03  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* tools/tiffcrop.c: Updated tiffcrop from Richard Nolde.  This
-	version has undergone substantial testing with arbitrary sample
-	bit depths.  Also eliminates GCC compilation warnings.
-
-2009-11-02  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* port/libport.h: Added header file for porting prototypes and
-	extern declarations.
-
-2009-10-31  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* libtiff/tif_dirwrite.c (TIFFWriteAnyArray): Add missing break
-	statement so writing an array of TIFF_DOUBLE works.
-
-2009-10-29  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* libtiff/tif_dirread.c: Eliminate GCC "dereferencing type-punned
-	pointer" warnings.
-
-2009-10-28  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* html/tools.html: Add manual page links, and a summary
-	description of tiffcrop.
-
-2009-10-07  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* configure.ac: x86_64 should use the same fill order as i386.
-
-2009-09-24  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* tools/tiffcrop.c, man/tiffcrop.1: New tiffcrop from Richard
-	Nolde.  Major updates to add significant functionality for reading
-	and writing tile based images with bit depths not a multiple of 8
-	which cannot be handled by tiffcp.
-
-2009-09-03  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* libtiff/tif_ojpeg.c (OJPEGWriteHeaderInfo): IJG JPEG 7 needs
-	do_fancy_upsampling=FALSE in order to read raw data.  Resolves
-	"Bug 2090 - OJPEG crash with libjpeg v7".
-	http://bugzilla.maptools.org/show_bug.cgi?id=2090
-
-2009-08-30  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* contrib/iptcutil/iptcutil.c,
-	libtiff/tif_getimage.c,libtiff/tif_jpeg.c,libtiff/tif_ojpeg.c,tools/tiffcrop.c,tools/tiffgt.c:
-	Applied patch from Oden Eriksson to allow building with GCC using
-	the "-Wformat -Werror=format-security" flags.
-
-2009-08-28  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* libtiff 3.9.1 released.
-
-2009-08-28  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_dirwrite.c: Back out changes from 2007-11-22 that
-	resulted in the final strip not being written in some circumstances.
-	http://bugzilla.maptools.org/show_bug.cgi?id=2088
-
-2009-08-27  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* libtiff/tif_write.c (TIFFAppendToStrip): Remove cast which
-	caused libtiff to output a wrong last strip with byte-count and
-	strip-offset of zero.  This cast was added on the day of the 3.9.0
-	release.
-
-	* libtiff/tif_config.vc.h: tiffiop.h needs the TIFF_INT64_T and
-	TIFF_UINT64_T defines in order to compile.  Copy existing
-	definitions from tiffconf.vc.h.
-
-2009-08-21  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* test/Makefile.am (AUTOMAKE_OPTIONS): Colorized tests was not
-	actually activated since it needed to be enabled in this
-	Makefile.am.  Also activated parallel-tests mode since it offers
-	useful features such as per-test .log files and a summary test
-	report .log file.
-
-2009-08-20  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* libtiff 3.9.0 released.
-
-	* libtiff/tif_print.c (TIFFPrintDirectory): Applied patch for "tag
-	error may cause segfault in tif_print.c."
-	http://bugzilla.maptools.org/show_bug.cgi?id=1896
-
-	* tools/{rgb2ycbcr.c, tiff2rgba.c}: Applied patch for
-	CVE-2009-2347 libtiff: integer overflows in various inter-color
-	space conversion tools.
-	http://bugzilla.maptools.org/show_bug.cgi?id=2079
-
-	* configure.ac: Updated autotools.  Autoconf 2.64, Automake 1.11,
-	libtool 2.2.6.  Enabled support for silent build rules
-	(--enable-silent-rules or 'make V=0') and colorized tests.
-
-2009-06-30  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_luv.c: correct return codes from encoderow to be
-	1 on success instead of zero.
-	http://bugzilla.maptools.org/show_bug.cgi?id=2069
-
-2009-06-22  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_lzw.c: Fix buffer underflow bug. 
-	http://bugzilla.maptools.org/show_bug.cgi?id=2065
-
-2009-06-03  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_write.c: do not override the planar configuration to be
-	contig for one sample files if planar configuration is already set.
-	http://bugzilla.maptools.org/show_bug.cgi?id=2057
-
-2009-02-12  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_luv.c: Fix handling of tiled logluv images. 
-	http://bugzilla.maptools.org/show_bug.cgi?id=2005
-
-2009-01-23  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_predict.c: Add support for 32bit integer horz. predictors.
-	http://bugzilla.maptools.org/show_bug.cgi?id=1911
-
-2009-01-20  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* tools/tiffsplit.c: fix sampleformat to be shortv instead of longv.
-
-2009-01-12  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* tools/tiff2ps.c: Remove spurious message printed to stderr. 
-
-2009-01-11  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* tools/tiff2ps.c: Incorporated significant functionality update
-	from Richard Nolde.  In particular, support for rotating the image
-	by 90, 180, 270, and 'auto' has been added.
-
-	* tools/tiffcrop.c: Incorporated significant functionality update
-	from Richard Nolde.
-
-2009-01-06  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* libtiff/tiffiop.h: Add private type declarations for int64, and
-	uint64 so that bundled utilities (like tiffcrop) can use it when
-	necessary.
-
-2009-01-01  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* configure.ac: Updated to test for 64-bit types.  This version of
-	the library does not require a 64-bit type, but tiffcrop needs it.
-
-2008-12-31  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* Update to use current FSF autotools versions.
-	* libtiff/tiffio.h: GCC will now validate format specifications
-	for TIFFError(), TIFFErrorExt(), TIFFWarning(), and
-	TIFFWarningExt() in order to reveal bugs.  Cleaned up resulting
-	warnings throughout for 32 bit build only.
-
-2008-12-31  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* tools/tiffcrop.c, man/tiffcrop.1: A major update from Richard
-	Nolde.  
-
-2008-12-21  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_jpeg.c: Avoid errors if the application writes a full
-	strip for the last partial strip in a jpeg compressed file.
-	http://bugzilla.maptools.org/show_bug.cgi?id=1981
-
-2008-12-21  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_getimage.c, tiffio.h: More ABI corrections. 
-	Removed SubsamplingHor/Ver from TIFFRGBAImage structure.
-	  http://bugzilla.maptools.org/show_bug.cgi?id=1980
-
-2008-12-18  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_getimage.c,tiffio.h: removed all use of UaToAa and
-	Bitmap16to8 arrays in TIFFRGBAImage structure to restore ABI
-	compatability.  These were just an attempt to speed up processing
-	with precalculated tables.
-	  http://bugzilla.maptools.org/show_bug.cgi?id=1979
-
-	* libtiff/tif_codec.c: Avoid printing c->name if it does not exist.
-
-2008-10-21  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_jbig.c: Support the JBIG-KIT 2.0 (compatibility with
-	the older versions retained).
-
-2008-09-05  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiffsplit.c: Use dynamically allocated array instead of static
-	when constructing output file names.
-
-2008-09-03  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiffsplit.c: Get rid of unsafe strcpy()/strcat() calls when
-	doing the filename/path construction.
-
-	* tools/tiff2pdf.c: More appropriate format string in
-	t2p_write_pdf_string(); avoid signed/unsigned mismatch.
-
-	* libtiff/tif_lzw.c: Properly zero out the codetable. As per bug
-
-	http://bugzilla.maptools.org/show_bug.cgi?id=1929
-
-	* libtiff/tif_lzw.c: Properly zero out the string table. Fixes
-	CVE-2008-2327 security issue.
-
-2008-05-24  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* tif_codec.c: Avoid NULL pointer dereferencing for exotic 
-	compression codec codes.
-
-	* tif_dirread.c: zero tif->tif_dir after freeing the directory
-	in TIFFReadCustomDirectory().  I don't exactly remember why this
-	was important. 
-
-	* tif_dirwrite.c: Fix potential memory leak writing large double
-	tags. 
-
-	* tif_dirread.c: Fix unchecked malloc result.
-
-2008-01-30  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tif_fax3.c: Make find0span() and find1span() non-inline to
-	make MSVC 6.0 compiler happy.
-
-2007-11-26  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* tif_fax3.c: fix leak of FAXCS state (per bug 1603).
-
-2007-11-23  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* configure.com, libtiff/tif_vms.c: Better OpenVMS support. Patches
-	from Alexey Chupahin.
-
-2007-11-22  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* tif_write.c: Rip out the fancy logic in TIFFAppendToStrip() for 
-	establishing if an existing tile can be rewritten to the same location 
-	by comparing the current size to all the other blocks in the same 
-	directory.  This is dangerous in many situations and can easily 
-	corrupt a file.  (observed in esoteric GDAL situation that's hard to
-	document).  This change involves leaving the stripbytecount[] values 
-	unaltered till TIFFAppendToStrip().  Now we only write a block back
-	to the same location it used to be at if the new data is the same
-	size or smaller - otherwise we move it to the end of file.
-
-	* tif_dirwrite.c: Try to avoid writing out a full readbuffer of tile
-	data when writing the directory just because we have BEENWRITING at
-	some point in the past.  This was causing odd junk to be written out
-	in a tile of data when a single tile had an interleaving of reading 
-	and writing with reading last.  (highlighted by gdal 
-	autotest/gcore/tif_write.py test 7. 
-
-	* tif_predict.c: use working buffer in PredictorEncodeTile to avoid
-	modifying callers buffer. 
-	http://trac.osgeo.org/gdal/ticket/1965
-
-	* tif_predict.c/h, tif_lzw.c, tif_zip.c: Improvements so that 
-	predictor based encoding and decoding works in read-write update
-	mode properly. 
-	http://trac.osgeo.org/gdal/ticket/1948
-
-2007-10-05  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* tools/tiff2pdf.c: Fixed setting of alpha value per report on list.
-
-2007-09-13  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* tif_dirinfo.c:  _TIFFMergeFields() now only merges in field
-	definitions that are missing.  Existing definitions are silently
-	ignored.  (Bug #1585)
-
-2007-07-18  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{Makefile.am, Makefile.v}: Do not distribute tiffconf.h, 
-	remove tif_config.h/tiffconf.h during cleaning. As per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1573
-
-2007-07-13  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff 3.9.0beta released.
-
-2007-07-12  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiff2pdf.c: Added missed extern optind as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1567
-
-2007-07-03  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiff2ps.c:  Added support 16-bit images as per bug
-	
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1566
-
-	Patch from William Bader.
-
-	* tools/tiff2pdf.c: Fix for TIFFTAG_JPEGTABLES tag fetching and
-	significant upgrade of the whole utility as per bug
-	
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1560
-
-	Now we don't need tiffiop.h in tiff2pdf anymore and will open output
-	PDF file using TIFFClientOpen() machinery as it is implemented
-	by Leon Bottou.
-
-2007-06-29  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* libtiff/tif_dirinfo.c (_TIFFFindFieldInfo): Don't attempt to
-	bsearch() on a NULL fieldinfo list.
-	(_TIFFFindFieldInfoByName): Don't attempt to
-	lfind() on a NULL fieldinfo list.
-
-2007-05-01  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_dirwrite.c: Fixed problem introduced with a fix for a
-	byte swapping issue
-	
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1363
-
-	As per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1550
-
-2007-04-27  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiff2pdf.c: Check the tmpfile() return status as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=154
-
-2007-04-07  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tif_dir.h, tif_dirread.c, tif_dirinfo.c, tif_jpeg.c,
-	tif_fax3.c, tif_jbig.c, tif_luv.c, tif_ojpeg.c, tif_pixarlog.c,
-	tif_predict.c, tif_zip.c}: Finally fix bug
-	
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1274
-
-	by introducing _TIFFMergeFieldInfo() returning integer error status
-	instead of void in case of problems with field merging (e.g., if the
-	field with such a tag already registered). TIFFMergeFieldInfo() in
-	public API remains void. Use _TIFFMergeFieldInfo() everywhere and
-	check returned value.
-
-2007-04-07  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* contrib/addtiffo/tif_overview.c: Fix problems with odd sized output 
-	blocks in TIFF_DownSample_Subsampled() (bug 1542).
-
-2007-04-06  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_jpeg.c: Changed JPEGInitializeLibJPEG() so that it
-	will convert from decompressor to compressor or compress to decompress
-	if required by the force arguments.  This works around a problem in
-	where the JPEGFixupTestSubsampling() may cause a decompressor to 
-	be setup on a directory when later a compressor is required with the
-	force flag set.  Occurs with the addtiffo program for instance. 
-
-2007-04-06  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_dirwrite.c: Fixed swapping of byte arrays stored
-	in-place in tag offsets as per bug
-	
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1363
-
-	* tools/tiffcrop.c, man/tiffcrop.1: Significant update in
-	functionality from Richard Nolde. As per bug
-	
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1525
-
-2007-03-28  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_fax3.c: "inline static" -> "static inline" for IRIC CC.
-
-2007-03-07  Joris Van Damme  <joris.at.lebbeke at skynet.be>
-	
-	* libtiff/tif_getimage.c: workaround for 'Fractional scanline' error reading
-	OJPEG images with rowsperstrip that is not a multiple of vertical subsampling
-	factor. This bug is mentioned in:
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1390
-	http://www.asmail.be/msg0054766825.html 
-
-2007-03-07  Joris Van Damme  <joris.at.lebbeke at skynet.be>
-	
-	* libtiff/tif_win32.c: made inclusion of windows.h unconditional
-
-	* libtiff/tif_win32.c: replaced preprocessor indication for consiously
-	unused arguments by standard C indication for the same
-
-2007-02-27  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_dirread.c: Use uint32 type instead of tsize_t in byte
-	counters in TIFFFetchData(). Should finally fix the issue
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=890
-
-2007-02-24  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiffset.c: Properly handle tags with TIFF_VARIABLE writecount.
-	As per bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1350
-
-	* libtiff/tif_dirread.c: Added special function to handle
-	SubjectDistance EXIF tag as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1362
-
-	* tools/tiff2pdf.c: Do not assume inches when the resolution units
-	do not specified. As per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1366
-
-	* tools/{tiffcp.c, tiffcrop.c}: Do not change RowsPerStrip value if
-	it was set as infinite. As per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1368
-
-	* tools/tiffcrop.c, man/tiffcrop.1: New tiffcrop utility contributed
-	by Richard Nolde. As per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1383
-
-2007-02-22  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_dir.c: Workaround for incorrect TIFFs with
-	ExtraSamples == 999 produced by Corel Draw. As per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1490
-
-	* libtiff/{tif_dirread.c, tif_read.c}: Type of the byte counters
-	changed from tsize_t to uint32 to be able to work with data arrays
-	larger than 2GB. Fixes bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=890
-	
-	Idea submitted by Matt Hancher.
-
-2007-01-31  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tif2rgba.c: This utility does not work properly on big-endian
-	architectures. It was fixed including the bug
-	
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1149
-
-2007-01-15  Mateusz Loskot <mateusz at loskot.net>
-
-	* Submitted libtiff port for Windows CE platform
-	* libtiff/tif_config.wince.h: Added configuration header for WinCE.
-	* libtiff/tiffconf.wince.h: Ported old configuration header for WinCE.
-	* libtiff/tif_wince.c: Added WinCE-specific implementation of some
-	functons from tif_win32.c.
-	* libtiff/tif_win32.c: Disabled some functions already reimplemented in tif_wince.c.
-	* libtiff/tiffiop.h, port/lfind.c: Added conditional include of some
-	standard header files for Windows CE build.
-	* tools/tiffinfoce.c: Ported tiffinfo utility for Windows CE.
-
-2006-11-19  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_write.c: TIFFAppendToStrip() - clear sorted flag if 
-	we move a strip. 
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1359	
-
-2006-10-13  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_dir.c: More fixes for vulnerabilities, reported
-	in Gentoo bug ():
-	
-	http://bugs.gentoo.org/show_bug.cgi?id=142383
-
-	* libtiff/contrib/dbs/xtiff/xtiff.c: Make xtiff utility compilable.
-	Though it is still far from the state of being working and useful.
-
-2006-10-12  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_fax3.c: Save the state of printdir codec dependent
-	method.
-
-	* libtiff/tif_jpeg.c: Save the state of printdir codec dependent method
-	as per bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1273
-
-	* libtiff/tif_win32.c: Fixed problem with offset value manipulation
-	as per bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1322
-
-	* libtiff/{tif_read.c, tif_jpeg.c, tif_dir.c}: More fixes for
-	vulnerabilities, reported in Gentoo bug ():
-
-	http://bugs.gentoo.org/show_bug.cgi?id=142383
-
-2006-09-28  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tif_fax3.c, tif_next.c, tif_pixarlog.c}: Fixed multiple
-	vulnerabilities, as per	Gentoo bug ():
-
-	http://bugs.gentoo.org/show_bug.cgi?id=142383
-
-2006-09-27  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_lzw.c, libtiff/tif_zip.c: Fixed problems with mixing
-	encoding and decoding on the same read-write TIFF handle.  The LZW
-	code can now maintain encode and decode state at the same time. The
-	ZIP code will switch back and forth as needed.  
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=757
-
-2006-09-20  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff: Rename config.h.vc and tif_config.h.vc to config.vc.h and 
-	tif_config.vc.h for easier identification by folks using an IDE.
-
-2006-07-25  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* tif_msdos.c: Avoid handle leak for failed opens.  c/o Thierry Pierron
-
-2006-07-19  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* tif_dirwrite.c: take care not to flush out buffer of strip/tile
-	data in _TIFFWriteDirectory if TIFF_BEENWRITING not set.  Relates
-	to bug report by Peng Gao with black strip at bottom of images.
-
-2006-07-12  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* tif_dirwrite.c: make sure to use uint32 for wordcount in 
-	TIFFWriteNormanTag if writecount is VARIABLE2 for ASCII fields.
-	It already seems to have been done for other field types.  Needed
-	for "tiffset" on files with geotiff ascii text.
-
-2006-07-04  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* {configure.ac, libtiff/tif_config.h.vc, libtiff/tif_jbig.c}
-	(JBIGDecode): jbg_newlen is not available in older JBIG-KIT and
-	its use does not appear to be required, so use it only when it is
-	available.
-
-2006-06-24  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_dirinfo.c: Added missed EXIF tag ColorSpace (40961).
-
-	* libtiff/tif_dirread.c: Move IFD fetching code in the separate
-	function TIFFFetchDirectory() avoiding code duplication in
-	TIFFReadDirectory() and TIFFReadCustomDirectory().
-
-2006-06-19  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* tools/tiff2pdf.c: Fix handling of -q values.
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=587
-
-2006-06-17  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* tif_readdir.c: Added case in EstimateStripByteCounts() for tiled
-	files.  Modified TIFFReadDirectory() to not invoke 
-	EstimateStripByteCounts() for case where entry 0 and 1 are unequal
-	but one of them is zero. 
-	  http://bugzilla.remotesensing.org/show_bug.cgi?id=1204
-
-2006-06-08  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tif_open.c, tif_dirread.c, tiffiop.h}: Move IFD looping
-	checking code in the separate function TIFFCheckDirOffset().
-
-	* libtiff/tif_aux.c: Added _TIFFCheckRealloc() function.
-
-	* tools/tiffcmp.c: Fixed floating point comparison logic as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1191
-
-	* libtiff/tif_fax3.c: Fixed problems in fax decoder as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1194
-
-	* tools/tiff2pdf.c: Fixed buffer overflow condition in
-	t2p_write_pdf_string() as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1196
-
-2006-06-07  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* {configure, configure.ac, libtiff/tif_jbig.c, tools/tiffcp.c}: Added
-	support for JBIG compression scheme (34661 code) contributed by Lee
-	Howard. As per bug
-	
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=896
-
-	* configure, configure.ac: OJPEG support enabled by default.
-
-	* contrib/ojpeg/: Removed. New OJPEG support does not need this patch.
-
-2006-06-03  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* libtiff/{tif_dirinfo.c, tif_print.c} : Fix crash in
-	TIFFPrintDirectory().  Joris Van Damme authored the fix.
-
-2006-04-21  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiff2pdf.c: Unified line ending characters (always use '\n')
-	as per bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1163
-
-	* README.vms, Makefile.am, configure.com, libtiff/{Makefile.am,
-	tif_config.h-vms, tif_stream.cxx, tif_vms.c, tiffconf.h-vms}:
-	Added support for OpenVMS by Alexey Chupahin, elvis_75 at mail.ru.
-
-2006-04-20  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/{fax2ps.c, fax2tiff.c, ppm2tiff.c, ras2tiff.c, tiff2pdf.c}:
-	Properly set the binary mode for stdin stream as per bug
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1141
-
-	* man/{bmp2tiff.1, fax2ps.1, fax2tiff.1, gif2tiff.1, ras2tiff.1,
-	raw2tiff.1, rgb2ycbcr.1, sgi2tiff.1, tiff2bw.1, tiff2pdf.1, tiff2ps.1,
-	tiff2rgba.1, tiffcmp.1, tiffcp.1, tiffdither.1,	tiffdump.1, tiffgt.1,
-	tiffset.1}: Improvements in page formatting as per bug
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1140
-
-	* html/tools.html, html/man/Makefile.am, tools/tiff2pdf.c: Fixed
-	typos as per bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1139
-
-2006-04-18  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* nmake.opt: use /EHsc for VS2005 compatibility.  Also define
-	_CRT_SECURE_NO_DEPRECATE to avoid noise on VS2005. 
-
-2006-04-12  Joris Van Damme  <joris.at.lebbeke at skynet.be>
-
-	* libtiff/tif_getimage.c: Added support for planarconfig separate
-	non-subsampled YCbCr (i.e. separate YCbCr with subsampling [1,1])
-
-2006-04-11  Joris Van Damme  <joris.at.lebbeke at skynet.be>
-	
-	* libtiff/tif_getimage.c: Revision of all RGB(A) put routines
-	- Conversion of unassociated alpha to associated alpha now done with
-	  more performant LUT, and calculation more correct
-	- Conversion of 16bit data to 8bit data now done with
-	  more performant LUT, and calculation more correct
-	- Bugfix of handling of 16bit RGB with unassociated alpha
-
-2006-04-11  Joris Van Damme  <joris.at.lebbeke at skynet.be>
-	
-	* libtiff/tif_getimage.c: 
-	- When there is no alpha, gtTileSeparate and gtStripSeparate allocated 
-	  buffer for alpha strile and filled it, only to never read it back. 
-	  Removed allocation and fill.
-	- Minor rename of vars in gtTileSeparate and gtStripSeparate 
-	  anticipating planned functionality extension
-
-2006-04-08  Joris Van Damme  <joris.at.lebbeke at skynet.be>
-
-	* libtiff/tif_getimage.c: renamed pickTileContigCase to PickContigCase 
-	and pickTileSeparateCase to PickSeparateCase as both work on strips as 
-	well
-
-	* libtiff/tif_getimage.c: moved img->get selection from 
-	TIFFRGBAImageBegin into PickContigCase and PickSeparateCase to create
-	logical hook for planned functionality extension
-
-2006-04-08  Joris Van Damme  <joris.at.lebbeke at skynet.be>
-
-	* libtiff/tif_ojpeg.c: resolved memory leak that was a consequence
-	of inappropriate use of jpeg_abort instead of jpeg_destroy
-
-2006-04-07  Joris Van Damme  <joris.at.lebbeke at skynet.be>
-
-	* libtiff/tif_getimage.c: replaced usage of TIFFScanlineSize in 
-	gtStripContig with TIFFNewScanlineSize so as to fix buggy behaviour
-	on subsampled images - this ought to get sorted when we feel brave 
-	enough to replace TIFFScanlineSize alltogether
-
-	* libtiff/tif_ojpeg.c: fixed bug in OJPEGReadSkip
-
-2006-04-04  Joris Van Damme  <joris.at.lebbeke at skynet.be>
-
-	* libtiff/tiffio.h: added new type tstrile_t
-
-	* libtiff/tif_dir.h: changed types of td_stripsperimage and td_nstrips 
-	to new tstrile_t, types of td_stripoffset and td_stripbytecount to 
-	toff_t*
-
-	* libtiff/tif_ojpeg.c: totally new implementation
-
-	* libtiff/tif_dirread.c: added several hacks to suit new support of 
-	OJPEG
-
-	* libtiff/tif_getimage.c: removed TIFFTAG_JPEGCOLORMODE handling
-	of OJPEG images in favor of tif_getimage.c native handling of
-	YCbCr and desubsampling
-
-2006-03-29  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_jpeg.c: JPEGVSetField() so that altering the photometric
-	interpretation causes the "upsampled" flag to be recomputed.  Fixes
-	peculiar bug where photometric flag had to be set before jpegcolormode
-	flag.
-
-2006-03-25  Joris Van Damme  <joris.at.lebbeke at skynet.be>
-
-	* libtiff/tif_jpeg.c: strip size related bugfix in encode raw
-
-	* libtiff/tif_strip.c: temporarilly added two new versions of
-	TIFFScanlineSize
-	  - TIFFNewScanlineSize: proposed new version, after all related
-	    issues and side-effects are sorted out
-	  - TIFFOldScanlineSize: old version, from prior to 2006-03-21 change
-	This needs further sorting out.
-
-2006-03-25  Joris Van Damme  <joris.at.lebbeke at skynet.be>
-
-	* contrib/addtiffo/tif_ovrcache.c: bugfix to correctly pass size
-	of last truncated strip data to TIFFWriteEncodedStrip
-
-2006-03-25  Joris Van Damme  <joris.at.lebbeke at skynet.be>
-
-	* libtiff/{tif_jpeg.c, tif_strip.c}: bugfix of tif_jpeg decode raw
-
-2006-03-25  Joris Van Damme  <joris.at.lebbeke at skynet.be>
-
-	* libtiff/tif_getimage.c: bugfix/rewrite of putcontig8bitYCbCr22tile
-
-	* libtiff/tif_getimage.c: added putcontig8bitYCbCr12tile
-
-	* libtiff/tif_read.c: added support for new TIFF_NOREADRAW flag to 
-	prepare	the path for new tif_ojpeg.c
-
-2006-03-23  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff 3.8.2 released.
-
-	* tools/Makefile.am: Use runtime paths linker flags when rpath
-	option enabled.
-
-2006-03-21  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/libtiff.def: Added missed exports as per bug
-	http://bugzilla.remotesensing.org/attachment.cgi?id=337
-
-	* contrib/addtiffo/Makefile.vc, libtiff/Makefile.vc, port/Makefile.vc,
-	tools/Makefile.vc: Makefiles improvements as per bug
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1128
-
-	* nmake.opt libtiff/{tif_config.h.vc, tif_unix.c, tiffio.h},
-	tools/{fax2ps.c, fax2tiff.c, tiff2pdf.c}: Fixed win32 I/O functions
-	usage as per bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1127
-
-	* libtiff/tif_strip.c: Take subsampling in account when calculating
-	TIFFScanlineSize().
-
-	* tools/tiffcp.c: Do not set RowsPerStrip bigger than image length.
-
-2006-03-17  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/fax2tiff.c: Fixed wrong TIFFerror() invocations as per bug
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1125
-
-	* tools/fax2ps.c: Fixed reading the input stream from stdin as per bug
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1124
-
-2006-03-16  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tiffiop.h: Added decalration for
-	_TIFFSetDefaultCompressionState().
-
-	* libtiff/{tif_jpeg.c, tif_fax3.c, tif_zip.c, tif_pixarlog.c,
-	tif_lzw.c, tif_luv.c}: Use _TIFFSetDefaultCompressionState() in all
-	codec cleanup methods. As per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1120
-
-2006-03-15  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_jpeg.c: Do not cleanup codec state in TIFFInitJPEG(). As
-	per bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1119
-
-	* tools/raw2tiff.c: Do not set RowsPerStrip larger than ImageLength.
-	As per bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1110
-
-	* libtiff/tiffiop.h: dblparam_t typedef removed; GLOBALDATA macro
-	removed; move here the STRIP_SIZE_DEFAULT macro definition.
-
-	* libtiff/{tif_dirread.c, tif_strip.c}: Removed STRIP_SIZE_DEFAULT
-	macro definition.
-
-	* libtiff/tif_dir.c: Use double type instead of dblparam_t.
-
-2006-03-14  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_dirread.c: Do not check the PlanarConfig tag presence
-	in TIFFReadDirectory, because it is always set at the start of
-	function and we allow TIFFs without that tag set.
-
-2005-03-13  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff 3.8.1 released.
-
-2006-03-07  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_dirread.c: Fixed error reporting in TIFFFetchAnyArray()
-	function as per bug
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1102
-
-	* libtiff/tif_dirread.c: More wise check for integer overflow
-	condition as per bug
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1102
-
-	* libtiff/{tif_jpeg.c, tif_pixarlog.c, tif_fax3.c, tif_zip.c}:
-	Properly restore setfield/getfield methods in cleanup functions. As
-	per bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1102
-
-2006-03-03  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tif_predict.c, tif_predict.h}: Added new function
-	TIFFPredictorCleanup() to restore parent decode/encode/field methods.
-
-	* libtiff/{tif_lzw.c, tif_pixarlog.c, tif_zip.c}: Use
-	TIFFPredictorCleanup() in codec cleanup methods. As per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1102
-
-	* libtiff/tif_dirread.c: Fixed integer overflow condition in
-	TIFFFetchData() function. As per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1102
-
-2006-03-01  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_ojpeg.c: Set the ReferenceBlackWhite with the
-	TIFFSetField() method, not directly. As per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1043
-
-	* tools/ppm2tiff.c: Added support for PBM files as per bug
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1044
-
-2006-02-27  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_write.c: Small code rearrangement in TIFFWriteScanline()
-	to avoid crash as per bug
-	
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1081.
-
-2006-02-26  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiff2pdf.c: Functions t2p_sample_rgbaa_to_rgb() and
-	t2p_sample_rgba_to_rgb() was used in place of each other, that was
-	resulted in problems with RGBA images with associated alpha.
-	As per bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1097
-
-2006-02-23  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_dirwrite.c: Properly write TIFFTAG_DOTRANGE tag as per
-	bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1088.
-
-	* libtiff/tif_print.c: Properly read TIFFTAG_PAGENUMBER,
-	TIFFTAG_HALFTONEHINTS, TIFFTAG_YCBCRSUBSAMPLING and TIFFTAG_DOTRANGE
-	tags as per bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1088.
-
-	* tools/tiff2ps.c: Properly scale all the pages when converting
-	multipage TIFF with /width/height/center options set. As per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1080
-
-2006-02-15  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiff2pdf.c: Do not create output file until all option checks
-	will be done. As per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1072
-
-	* tools/bmp2tiff.c: Added ability to create multipage TIFFs from the
-	list of input files as per bug:
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1077
-
-2006-02-09  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_tile.c: Fix error reporting in TIFFCheckTile() as per
-	bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1063.
-
-	* tools/tiffgt.c: Avoid crashing in case of image unsupported by
-	TIFFRGBAImage interface.
-
-	* libtiff/tif_color.c: Avoid overflow in case of wrong input as per
-	bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1065.
-
-2006-02-07  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* tools/tiff2pdf.c: Fixed support for non-YCbCr encoded JPEG
-	compressed TIFF files, per submission from Dan Cobra. 
-
-2006-02-07  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tif_dirread.c, tif_packbits.c, tif_win32.c}: Properly
-	cast values to avoid warnings. As per bug
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1033.
-
-	* libtiff/tif_dirinfo.c: Use TIFF_NOTYPE instead of 0 when
-	appropriate. As per bug
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1033.
-
-	* libtiff/tif_aux.c: Fixed type of temporary variable in
-	_TIFFCheckMalloc() as per bug
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1033.
-
-2006-02-06  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_aux.c: Return static array when fetching default
-	YCbCrCoefficients (another problem, reported a the
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1029 entry).
-
-2006-02-03  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_dir.c: Special handling for PageNumber, HalftoneHints,
-	YCbCrSubsampling and DotRange tags as per bugs
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1029
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1034
-
-	* libtiff/tif_dirread.c: Use _TIFFGetExifFieldInfo() instead of
-	_TIFFGetFieldInfo() in TIFFReadEXIFDirectory() call as per bug
-	
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1026.
-
-2006-01-23  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtool related stuff updated from the 2.1a branch.
-
-2006-01-11  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* tools/bmp2tiff,pal2rgb,ppm2tiff,ras2tiff,raw2tiff,sgi2tiff,
-	tiff2bw,tiffcp: Fixed jpeg option processing so -c jpeg:r:50 works
-	properly as per bug:
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1025
-
-2006-01-09  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* configure.ac: Fix with_default_strip_size comparison as reported
-	by Norihiko Murase.
-
-2006-01-08  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* test/Makefile.am (LIBTIFF): Due to linking against libtiff
-	incorrectly, tests were not actually testing the uninstalled
-	libtiff.  Now they are.
-
-2006-01-04  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_dirinfo.c: Change definitions for TIFFTAG_ICCPROFILE,
-	TIFFTAG_PHOTOSHOP, TIFFTAG_RICHTIFFIPTC, TIFFTAG_XMLPACKET: readcount
-	should be uint32 value.
-
-2006-01-02  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* html/man/Makefile.am (htmldoc): Fix htmldoc rule so that it can
-	be used if build directory is not the same as source directory.
-	* man/{TIFFGetField.3tiff, TIFFSetField.3tiff}: Documented
-	TIFFTAG_PHOTOSHOP, TIFFTAG_RICHTIFFIPTC, and TIFFTAG_XMLPACKET,
-	and re-sorted tag names in alphabetical order.
-
-2005-12-29  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff 3.8.0 released.
-
-2005-12-28  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* tools/bmp2tiff.c (main): Fixed warning regarding returning
-	inconsistent types from a condition.
-	* tools/tiffcmp.c (CheckLongTag): Eliminate warning due to printf
-	format.
-	* tools/bmp2tiff.c: Reduce compilation warnings on big-endian CPUs.
-
-2005-12-28  Joris Van Damme  <joris.at.lebbeke at skynet.be>
-
-	* html/{index.html, support.hml, libtiff.html}: Cleaned up HTML
-
-2005-12-27  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tiffio.h: Added VC_EXTRALEAN definition before including
-	windows.h, to reduce the compile time.
-
-2005-12-26  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* libtiff/tif_jpeg.c: Improve compilation under MinGW.
-
-2005-12-26  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tif_dir.c, tif_dir.h, tif_dirread.c, tif_dirinfo.c}: 
-	tiffFieldInfo and exifFieldInfo arrays definitions moved back to
-	tif_dirinfo.c; added _TIFFGetFieldInfo() and _TIFFGetExifFieldInfo()
-	private functions to retrieve FieldInfo arrays.
-
-2005-12-24  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* html/build.html: Added some additional instructions for when
-	building using MSVC under Windows.  Also fixed two HTML syntax
-	errors and used HTML Tidy to tidy up the HTML syntax and
-	formatting.
-
-2005-12-24  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tif_aux.c, tif_dir.c, tif_dir.h, tif_dirwrite.c,
-	tif_print.c, tif_getimage.c}: Make InkSet, NumberOfInks, DotRange and
-	StoNits tags custom.
-
-2005-12-23  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tif_aux.c, tif_dir.c, tif_dir.h, tif_print.c}: Make
-	WhitePoint tag custom.
-
-	* libtiff/{tif_dir.h, tiff.h}: More EXIF tags added.
-
-2005-12-23  Joris Van Damme  <joris.at.lebbeke at skynet.be>
-
-	* libtiff/tiffio.h: fixed typo that potentially resulted in 
-	redefininition of USE_WIN32_FILEIO
-
-	* libtiff/*: Added more 'dual-mode' error handling: Done TIFFWarning 
-	calls in core LibTiff.
-
-2005-12-21  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tif_dir.c, tif_dir.h, tif_print.c}: Make RichTIFFIPTC,
-	Photoshop and ICCProfile tags custom.
-
-2005-12-21  Joris Van Damme  <joris.at.lebbeke at skynet.be>
-
-	* libtiff/*, contrib/*: Added 'dual-mode' error handling, enabling 
-	newer code to get context indicator in error handler and still
-	remain compatible with older code: Done TIFFError calls everywhere 
-	except in tools   
-
-2005-12-20  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiffcp.c: Added many error reporting messages; fixed integer
-	overflow as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=789
-
-2005-12-16  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* contrib/addtiffo/*: Major upgrade by Joris to support subsampled
-	YCbCr images in jpeg compressed TIFF files.
-
-2005-12-14  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiffcp.c: Return non-zero status when reading fails (again).
-
-2005-12-13  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiffcp.c: Return non-zero status when reading fails.
-
-2005-12-12  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tif_dir.h, tiff.h}: Added more EXIF tags.
-
-2005-12-09  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tif_dir.c, tif_dir.h, tif_print.c}: Make XMLPacket tag
-	custom.
-
-	* tools/tiffinfo.c: Print EXIF directory contents if exist.
-
-	* libtiff/tiff.h: Few EXIF tag numbers added.
-
-	* libtiff/{tif_dirinfo.c, tif_dirread.c, tif_dir.h, tif_dir.c,
-	tiffio.h}: Preliminary support to read custom directories. New
-	functions: TIFFReadCustomDirectory() and TIFFReadEXIFDirectory().
-
-2005-12-07  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tif_dirinfo.c, tif_dirread.c, tif_dir.h, tif_dir.c}:
-	More work to implement custom directory read support.
-
-	* libtiff/{tif_aux.c, tif_dirinfo.c, tif_dirread.c, tif_dir.h,
-	tif_dir.c, tif_print.c}: Make YCbCrCoefficients and ReferenceBlackWhite
-	tags custom.
-
-2005-12-05  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_dirread.c: One more workaround for broken
-	StripByteCounts tag. Handle the case when StripByteCounts array filled
-	with completely wrong values.
-
-2005-11-30  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_dirinfo.c: Release file descriptor in case of failure
-	in the TIFFOpenW() function as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1003
-
-	* libtiff/tif_dirinfo.c: Correctly yse bsearch() and lfind()
-	functions as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1008
-
-2005-11-20  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* tif_open.c, tiff.h, tiffdump.c: Incorporate preliminary support
-	for MS MDI format.
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1002
-
-	* .cvsignore: many files added, and a few update according
-	to suggestion of Brad HArds on tiff mailing list. 
-
-2005-11-03  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/libtiff.def, tiffiop.h, tiffio.h: Made TIFFFreeDirectory
-	public.
-
-2005-10-31  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/fax2tiff.c: Properly calculate sizes of temporary arrays
-	as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=943
-
-	* tools/fax2tiff.c: Added option '-r' to set RowsPerStrip parameter
-	as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=944
-
-	* tools/tiffdump.c: Fixed typeshift and typemask arrays initialization
-	problem as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=946
-
-	* tools/bmp2tiff.c: Fixed possible integer overflow error as per bug
-	
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=965
-
-	* libtiff/tif_dirinfo.c: Make XResolution, YResolution and
-	ResolutionUnit tags modifiable during write process. As per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=977
-
-	* tools/tiffsplit.c: Copy fax related fields over splitted parts
-	as per bug
-	
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=983
-
-2005-10-21  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* tif_dirread.c: Don't try and split single strips into "0" strips
-	in ChopUpSingleUncompressedStrip.  This happens in some degenerate
-	cases (like 1x1 files with stripbytecounts==0 (gtsmall.jp2 embed tiff)
-
-2005-10-20  Joris Van Damme  <joris.at.lebbeke at skynet.be>
-
-	* tif_fax3.c: changed 'at scanline ...' style warning/errors
-	with incorrect use of tif_row, to 'at line ... of
-	strip/tile ...' style
-
-2005-10-15  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* tif_write.c: fixed setting of planarconfig as per bug report
-	on the mailing list from Joris.
-
-2005-10-07  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* configure.ac, configure, nmake.opt, libtiff/{tif_config.h,
-	tif_dirread.c}: Make the default strip size configurable via the
-	--with-default-strip-size and STRIP_SIZE_DEFAULT options.
-
-2005-09-30  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* html/support.html: Fixed link to documentation on Greg Ward's
-	LogLuv TIFF format.
-
-2005-09-28  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiffdump.c: Fixed crash when reading malformed tags.
-
-2005-09-20  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiff2pdf.c: Added missed 'break' statement as per bug
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=932
-
-2005-09-12  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff 3.7.4 released.
-
-	* {configure, configure.ac, Makefile.am, autogen.sh}: Applied patch
-	from Patrick Welche (all scripts moved in the 'config' and 'm4'
-	directories).
-
-2005-09-12  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_open.c: reintroduce seek to avoid problem on solaris.
-
-2005-09-05  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_dir.c: When prefreeing tv->value in TIFFSetFieldV
-	also set it to NULL to avoid double free when re-setting custom
-	string fields as per: 
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=922
-
-2005-08-12  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_print.c: avoid signed/unsigned warning.
-
-	* libtiff/tif_dirread.c: removed unused variable.
-
-2005-07-30  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_dir.c: Fixed up support for swapping "double complex"
-	values (128 bits as 2 64 bits doubles).  GDAL gcore tests now
-	pass on bigendian (macosx) system.
-
-2005-07-28  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tif_aux.c, tif_dirread.c, tif_fax3.c, tiffiop.h}: Rename
-	CheckMalloc() function to _TIFFCheckMalloc() and make it available
-	globally as an internal helper routine.
-
-2005-07-27  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_dir.c: More improvements in the "pass by value" part of
-	the custom tags handling code.
-
-2005-07-26  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tif_dirread.c, tif_dirinfo.c}: Do not upcast BYTEs to
-	SHORTs in the TIFFFetchByteArray(). Remove TIFFFetchExtraSamples()
-	function, use TIFFFetchNormalTag() instead as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=831
-
-	Remove TIFFFetchExtraSamples() function, use TIFFFetchNormalTag()
-	instead. 
-
-	* libtiff/tiffconf.h.in: One more attempt to fix the AIX bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=39
-
-2005-07-25  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_print.c: Fixed printing of the BYTE and SBYTE arrays.
-
-	* tools/tiffdump.c: Added support for TIFF_IFD datatype.
-
-2005-07-21  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_write.c: Do not check the PlanarConfiguration field in
-	the TIFFWriteCheck() function in case of single band images (as per
-	TIFF spec).
-
-2005-07-12  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* SConstruct, libtiff/SConstruct: Added the first very preliminary
-	support for SCons software building tool (http://www.scons.org/).
-	This is experimental infrastructure and it will exist along with the
-	autotools mechanics.
-
-2005-07-07  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* port/{getopt.c, strcasecmp.c, strtoul.c}: Update modules from
-	the NetBSD source tree (the old	4-clause BSD license changed to
-	the new 3-clause one).
-
-	* configure.ac, port/lfind.c, libtiff/tiffiop.h: Added lfind()
-	replacement module.
-
-	* port/dummy.c: Make the dummy function static.
-
-2005-07-06  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiffcp.c: Fixed WhitePoint tag copying.
-
-	* libtiff/{tif_dir.c, tif_dir.h, tif_dirinfo.c, tif_print.c}:
-	Make FieldOfViewCotangent, MatrixWorldToScreen, MatrixWorldToCamera,
-	ImageFullWidth, ImageFullLength and PrimaryChromaticities tags custom.
-
-2005-07-04  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff 3.7.3 released.
-
-	* configure, configure.ac: Do not use empty -R option when linking
-	with --enable-rpath.
-
-2005-07-01  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tiffiop.h, tif_open.c}: Added open option 'h' to avoid
-	reading the first IFD when needed. As per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=875
-
-	* libtiff/tif_color.c: Better use of TIFFmin() macro to avoid side
-	effects.
-
-2005-06-23  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiff2pdf.c: Print two characters per loop in the
-	t2p_write_pdf_trailer(). As per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=594
-
-	* tools/tiffgt.c: Use MacOS X OpenGL framework when appropriate. As
-	per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=844
-
-	* acinclude.m4: Updated to latest OpenGL test macros versions.
-
-	* libtiff/tiff.h: Use correct int size on Sparc 64bit/Sun compiler
-	platform. As per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=855
-
-2005-06-14  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_dirinfo.c: Added support for ClipPath, XClipPathUnits
-	and YClipPathUnits tags.
-
-2005-06-07  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* contrib/addtiffo/tif_ovrcache.c: Properly extract tile/strip size;
-	use pixel sized shift in contigous case.
-
-2005-06-06  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* contrib/addtiffo/{tif_overview.c, tif_ovrcache.c, tif_ovrcache.h}:
-	Make overviews working for contiguos images.
-
-2005-06-03  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_open.c: Replace runtime endianess check with the compile
-	time one.
-
-	* libtiff/tif_predict.c: Floating point predictor now works on
-	big-endian hosts.
-
-2005-06-01  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_dir.c: Use _TIFFsetString() function when read custom
-	ASCII values.
-
-	* libtiff/{tif_dirinfo.c, tif_dir.h, tif_dir.c, tif_print.c}: Make
-	DocumentName, Artist, HostComputer, ImageDescription, Make, Model,
-	Copyright, DateTime, PageName, TextureFormat, TextureWrapModes and
-	TargetPrinter tags custom.
-
-	* libtiff/tif_jpeg.c: Cleanup the codec state depending on
-	TIFF_CODERSETUP flag (to fix memry leaks).
-
-	* libtiff/tif_jpeg.c: Initialize JPEGTables array with zero after
-	allocating.
-
-2005-05-26  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* configure.ac, libtiff/Makefile.am: Added workaround for
-	OpenBSD/MirOS soname problem as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=838
-
-	* libtiff/tif_dirwrite.c: Use tdir_count when calling
-	TIFFCvtNativeToIEEEDouble() in the TIFFWriteDoubleArray() function as
-	per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=845
-
-2005-05-25  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/ppm2tiff.c: Fixed format string when read PPM file header with
-	the fscanf() function. As per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=861
-
-	* libtiff/{tif_dirinfo.c, tif_print.c}: TIFFFetchByteArray() returns
-	uint16 array when fetching the BYTE and SBYTE filds, so we should
-	consider result as pointer to uint16 array and not as array of chars.
-	As per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=831
-
-	* libtiff/tif_dir.c: More efficient custom tags retrieval as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=830
-
-	* libtiff/tif_win32.c: Use FILE_SHARE_READ | FILE_SHARE_WRITE share
-	mode in CreateFile() call as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=829
-
-	* libtiff/Makefile.am: Fixed parallel compilation of the libtiff and
-	libtiffxx libraries as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=826
-
-	* contrib/addtiffo/{tif_overview.c, tif_ovrcache.h}: Sinchronized with
-	GDAL.
-
-2005-05-23  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_jpeg.c: Substantial fix for addtiffo problems with
-	JPEG encoded TIFF files.  Pre-allocate lots of space for jpegtables
-	in directory.
-
-2005-05-22  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_dirread.c: Changed the code that computes 
-	stripbytecount[0] if it appears bogus to ignore if stripoffset[0] is
-	zero. This is a common case with GDAL indicating a "null" tile/strip.
-
-2005-05-17  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiffsplit.c: Check for JPEGTables tag presence before copying.
-
-2005-05-06  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_dirread.c: Applied similar change to 
-	TIFFFetchPerSampleLongs and TIFFFetchPerSampleAnys. 
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=843
-
-	* libtiff/tif_jpeg.c: added LIB_JPEG_MK1 support in JPEGDecodeRaw().
-
-2005-05-06  Andrey Kiselev  <dron at ak4719.spb.edu>
-	* tools/tiff2pdfr.c, man/tiff2pdf.1: Calculate the tile width properly;
-	added new option '-b' to use interpolation in output PDF files (Bruno
-	Ledoux).
-
-2005-05-05  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_dirread.c: Ensure that broken files with too many
-	values in PerSampleShorts work ok instead of crashing.
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=843
-
-2005-04-27  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiffdither.c: Copy the PhotometricInterpretation tag from the
-	input file.
-
-2005-04-15  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_predict.c: Added ability to encode floating point
-	predictor, as per TIFF Technical Note 3.
-
-2005-04-14  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tif_predict.h, tif_predict.c}: Added ability to decode
-	floating point predictor, as per TIFF Technical Note 3.
-
-2005-04-13  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tiffio.h, tiffiop.h, tif_dir.c, tif_read.c, tif_swab.c}:
-	Added _TIFFSwab24BitData() and TIFFSwabArrayOfLong() functions used to
-	swap 24-bit floating point values.
-
-	* libtiff/tiff.h: Added predictor constants.
-
-2005-04-08  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tiffiop.h, tif_dir.c}: Use uint32 type for appropriate
-	values in _TIFFVSetField() function. Inspired by the bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=816
-
-	* man/TIFFSetField.3tiff: Fixed definition of the TIFFTAG_INKNAMES tag
-	as per bug
-	
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=816
-
-2005-03-30  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_open.c: Do not read header in case the output file
-	should be truncated (Ron).
-
-	* libtiff/{tif_dirinfo.c, tif_config.h.vc}: Use lfind() instead
-	of bsearch() in _TIFFFindFieldInfoByName() function (Ron).
-
-	* libtiff/{tiff.h, tif_dirinfo.c}: Fixes in EXIF tag ordering (Ron).
-
-2005-03-22  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* configure.ac, libtiff/Makefile.am: Use libtool machinery to pass
-	rpath option.
-
-2005-03-21  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tif_dir.c, tif_print.c}: Handle all data types in custom
-	tags.
-
-2005-03-18  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/dirinfo.c: Added DNG tags.
-
-	* libtiff/{tif_dir.c, tif_print.c}: More improvements in custom tag
-	handling code.
-
-	* libtiff/tiff.h: More comments; added missed DNG tag (LensInfo);
-	added DNG 1.1.0.0 tags.
-
-	* tools/tif2pdf.c: Fixed problem with alpha channel handling as per
-	bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=794
-
-	* man/TIFFGetField.3tiff: Add a note about autoregistered tags.
-
-2005-03-17  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* nmake.opt: Build with Win32 CRT library by default.
-
-	* tools/tiff2ps.c: Fixed typo in page size handling code.
-
-	* libtiff/{tif_dir.c, tif_print.c}: Support for custom tags, passed
-	by value.
-
-	* libtiff/{tiff.h, tif_dirinfo.c, tiffiop.h}: Added EXIF related tags.
-
-2005-03-15  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff 3.7.2 released.
-
-2005-03-09  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiffcmp.c: Added ability to compare the 32-bit integer and
-	floating point data; complain on unsupported bit depths.
-
-2005-03-05  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tif_stream.cxx: Use ios namespace instead of ios_base to support
-	GCC 2.95.
-
-	* libtiff/{tiff.h, tif_fax3.tif, tif_jpeg.c}: Applied correct patch from
-	Lee Howard for HylaFax DCS tag
-	(see http://bugzilla.remotesensing.org/show_bug.cgi?id=771)
-
-2005-03-04  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* configure, configure.ac: Use -rpath option instead of -R as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=732
-
-	* libtiff/{tiff.h, tif_fax3.tif, tif_jpeg.c}: Applied patch from Lee
-	Howard to support a new tag TIFFTAG_FAXDCS (34911) used in HylaFax
-	software. As per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=771
-
-	* nmake.opt, html/build.html: Add more comments, change the config
-	file organization a bit as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=764
-
-	* tools/tiffcmp.c: Use properly sized buffer in short arrays comparison
-	as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=785
-
-2005-03-03  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_dirread.c: More logic to guess missed strip size as per
-	bug http://bugzilla.remotesensing.org/show_bug.cgi?id=705
-
-	* tools/fax2ps.c: Replace insecure mktemp() function with the
-	tmpfile() as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=786
-
-2005-02-04  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tiff.h: Changed the int8 definition to be always signed char
-	as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=727
-
-	* libtiff/tiffio.h: Move TIFFOpenW() function into the extern "C"{}
-	block as per bug
-	
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=763
-
-2005-02-03  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* tools/tiffgt.c: Fix problem on big-endian CPUs so that images
-	display more correctly.  Images display brighter than they should
-	on a Sun workstation.
-
-2005-02-03  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_dirread.c: Estimate strip size in case of wrong or
-	suspicious values in the tags. As per bugs
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=705
-
-	and
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=320
-
-	* tools/tiff2ps.c: Fixed problem with page sizes as per bug
-	
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=742
-
-2005-01-31  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* libtiff/tiff.h (TIFFTAG_TILEWIDTH): Corrected description.
-	(TIFFTAG_TILELENGTH): Corrected description.
-
-2005-01-30  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* configure.ac: Fixes for --with-docdir option as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=759
-
-	* libtiff/tif_open.c: Remove unnesessary TIFFSeekFile() call as per
-	bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=756
-
-	* libtiff/tif_stream.cxx: Fixes for C++ stream interface from
-	Michael Rinne and Edward Lam.
-
-2005-01-15  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* configure.ac: Make the documentation directory location configurable
-	via the --with-docdir option (as suggested by Jeremy C. Reed).
-
-	* libtiff/tif_color.c: Use double as the second argument of pow()
-	function in TIFFCIELabToRGBInit(). As per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=741
-
-	* libtiff/tif_pixarlog.c: Avoid warnings when converting float to
-	integer as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=740
-
-	* libtiff/tif_getimage.c: Always fill the error message buffer in
-	TIFFRGBAImageBegin() as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=739
-	
-2005-01-12  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_jpeg.c: Added ability to read/write the fax specific
-	TIFFTAG_FAXRECVPARAMS, TIFFTAG_FAXSUBADDRESS and TIFFTAG_FAXRECVTIME
-	tags as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=736
-
-	* libtiff/tif_win32.c: Fixed message formatting in functions
-	Win32WarningHandler() and Win32ErrorHandler() as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=735
-
-	* tools/tiff2ps.c: Interpret the -w and -h options independently. As
-	per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=689
-
-2005-01-11  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tiffio.h: Move the color conversion routines in the 'extern
-	"C"' section as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=727
-
-	* libtiff/tiff.h: Restore back the workaround for AIX Visual Age C
-	compiler to avoid double definition of BSD types as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=39	
-
-	* libtiff/Makefile.am: Place the C++ stream API in the separate
-	library called libtiffxx to avoid unneeded dependencies. Probably
-	there will be more C++ API in the future. As per bugs
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=733
-
-	and
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=730
-
-2005-01-05  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiffdump.c: Fixed problem when read broken TIFFs with the
-	wrong tag counts (Dmitry V. Levin, Martin Pitt).
-
-	* configure.ac: Replace --disable-c++ with the --disable-cxx option as
-	per bug http://bugzilla.remotesensing.org/show_bug.cgi?id=730
-
-2004-12-25  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_getimage.c: More fixes for multiple-alpha-channelled
-	RGB-images as per bug
-	
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=713
-
-
-	* tools/tiffset.c: Convert character option to integer value as per
-	bug http://bugzilla.remotesensing.org/show_bug.cgi?id=725
-
-2004-12-20  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff 3.7.1 released.
-
-	* html/tiffset.1.html: Add missed manual page as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=678
-
-	* libtiff/tiff.h: Revert back libtiff data type definitions as per
-	bug http://bugzilla.remotesensing.org/show_bug.cgi?id=687
-
-2004-12-19  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_dirread.c: Do not forget about TIFF_VARIABLE2 when
-	checking for tag count in TIFFReadDirectory() function. As per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=713
-
-	* libtiff/{tif_dirread.c, tif_fax3.c}: More argument checking in
-	CheckMallock() function.
-
-	* libtiff/tif_getimage.c: Support for multiple-alpha-channelled
-	RGB-images as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=718
-
-2004-12-15  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_getimage.c: #define A1 bracketing for clean build on
-	SunPro compiler. 
-
-2004-12-11  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* autogen.sh: aclocal and autoheader should be executed after
-	libtoolize.  Also add '-I .' to aclocal invocation to check
-	current directory for macros.
-
-2004-12-10  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_dirwrite.c: Always write TIFFTAG_SUBIFD using LONG type
-	as per bugs
-	
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=703
-
-	and
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=704
-
-2004-12-04  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* nmake.opt: Link with the user32.lib in windowed mode. As per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=697
-
-	* libtiff/tif_win32.c: Use char* strings instead of TCHAR in windowed
-	mode as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=697
-
-	* libtiff/tif_config.in.vc: Removed unneded definitions for
-	read/open/close/lseek functions to fix the
-	
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=680
-	
-2004-12-03  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tif_dir.c, tif_dirread.c}: Remove TIFFReassignTagToIgnore()
-	call from the TIFFReadDirectory() function. TIFFReassignTagToIgnore
-	must be removed in the future, as it was never used properly. As per
-	bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=692
-
-2004-11-30  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* libtiff/tif_jpeg.c: Added a work-around in order to allow
-	compilation with the heavily modified version of libjpeg delivered
-	with Cygwin.
-
-2004-11-29  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_dir.c: Properly handle tags, which have the uint32
-	counts. As per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=693
-
-	* tools/fax2ps.c: Be able to extract the first page (#0). As per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=690
-
-2004-11-28  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_unix.c: Make UNIX module compilable (and usable)
-	on Windows.
-
-	* nmake.opt: Add missed DLLNAME variable.
-
-2004-11-26  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/makefile.vc: make it easier to rename the libtiff DLL. 
-
-2004-11-24  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* man/libtiff.3tiff: Improvements in the "LIST OF ROUTINES" table as
-	per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=545
-
-	* man/tiffset.1: Added manual page for tiffset tool written by Jay
-	Berkenbilt. As per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=678
-
-2004-11-23  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_error.c: fixed TIFFerror call to be TIFFError.
-
-2004-11-21  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* html/document.html: Updated Adobe web links as per email from Joris.
-
-2004-11-21  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tiffio.hxx, tiffio.h}: C++ stream interface moved to new
-	file tiffio.hxx. We don't have any C++ in tiffio.h, those who want to
-	use C++ streams should #include <tiffio.hxx>.
-
-2004-11-13  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tiff.h: Added Adobe DNG tags.
-
-	* libtiff/tif_win32.c: Typo fixed.
-
-	* libtiff/{tif_stream.cxx, tiffio.h}: C++ stream interface updated to
-	be compliant with the latest standard. Appropriate additions in
-	makefiles now completed.
-
-2004-11-11  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiffset.c, libtiff/tif_dirinfo.c: Properly handle the
-	different tag types. As per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=600
-
-2004-11-10  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_aux.c: Set the appropriate ReferenceBlackWhite array for
-	YCbCr image which lacks that tag (noted by Hans Petter Selasky).
-
-2004-11-09  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_color.c: Division by zero fixed (Hans Petter Selasky).
-
-2004-11-07  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tif_stream.cxx, tiffio.h}: Added C++ stream interface
-	contributed by Edward Lam (see
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=654 for details).
-	Though no changes in any makefiles yet.
-
-2004-11-05  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_open.c: Removed close() in TIFFClientOpen() if file
-	is bad. This is the callers responsibility.
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=651
-
-2004-11-05  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tiffio.h, tif_win32.c, libtiff.def}: Added TIFFOpenW()
-	function to work with the double byte strings (used to represent
-	filenames in some locales). As per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=625
-
-	* libtiff/tif_dirread.c: Fixed problem when fetching BitsPerSample and
-	Compression tags of type LONG from broken TIFFS as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=662
-
-	* libtiff/tif_dirinfo.c: Fixed definition for TIFFTAG_RICHTIFFIPTC,
-	the writecount should have uint32 type. As per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=662
-
-	* libtiff/tif_write.c: Fixed wrong if() statement in
-	TIFFAppendToStrip() function as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=660
-
-2004-11-04  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_dirinfo.c: Change definition for TIFFTAG_EXTRASAMPLES
-	field. The caller should supply a count when setting this field. As
-	per bug
-
-	 http://bugzilla.remotesensing.org/show_bug.cgi?id=648
-	
-	* libtiff/{tif_jpeg.c, tif_ojpeg.c}: TIFFTAG_JPEGTABLES should have
-	uint32 count. Use this type everywhere.
-
-2004-11-03  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_next.c: avoid use of u_long and u_char types.  Bug 653.
-
-2004-11-02  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* tools/tiff2rgba.c: removed extra newlines in usage message.
-
-2004-10-30  Andrey Kiselev  <dron at ak4719.spb.edu>
-	
-	* libtiff/tif_dirwrite.c: Improvements in tag writing code.
-
-	* tools/tiff2ps.c: Fixed wrong variable data type when read Position
-	tags (Tristan Hill).
-
-2004-10-30  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tiffiop.h: added fallback definition of assert() if we
-	don't have assert.h.
-
-2004-10-29  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_fax3.c: Fixed case with the wrong decode routines
-	choosing when the incorrect Group4Options tag set. As per bug
-	
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=323
-
-	* libtiff/tif_dirwrite.c: Fixed problem with passing count variable of
-	wrong type when writing the TIFF_BYTE/TIFF_SBYTE tags in
-	TIFFWriteNormalTag().
-
-2004-10-28  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiff2ps.c: Fixed wrong variable data type when read Resolution
-	tags (Peter Fales).
-
-	* tools/{bmp2tiff.c, raw2tiff.c}: Get rid of stream I/O functions.
-
-2004-10-28  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* tools/tiff2pdf.c: added casts to avoid warnings.
-
-	* libtiff/libtiff.def: Added several more entry points required
-	to link fax2tiff.c against the DLL on windows. 
-
-2004-10-27  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* configure, configure.ac: Added --enable-rpath option to embed linker
-	paths into library binary.
-
-2004-10-26  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiffset.c: Check the malloc return value (Dmitry V. Levin).
-
-	* libtiff/{tif_strip.c, tif_tile.c}: Zero division problem fixed
-	(Vladimir Nadvornik, Dmitry V. Levin).
-
-2004-10-16  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff 3.7.0 released.
-
-2004-10-15  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* libtiff/tif_jpeg.c: There seems to be no need to include stdio.h
-	in this file so its inclusion is removed.  Including stdio.h
-	sometimes incurs an INT32 typedef conflict between MinGW's
-	basetsd.h and libjpeg's jmorecfg.h.
-
-2004-10-15  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* man/bmp2tiff.1: Added manual page for bmp2tiff utility.
-
-2004-10-13  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* tools/tiffcmp.c (leof): Renamed from 'eof' in order to avoid
-	conflict noticed under MinGW.
-	* ltmain.sh: Fix for MinGW compilation.
-
-2004-10-13  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* man/tiffsplit.1: Fixed to indicate using aaa-zzz, not aa-zz.
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=635
-
-2004-10-12  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tif_dirread.c, tif_jpeg.c, tif_luv.c, tif_ojpeg.c,
-	tif_pixarlog.c, tif_write.c}: Handle the zero strip/tile sizes
-	properly (Dmitry V. Levin, Marcus Meissner).
-
-2004-10-11  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_dirinfo.c: Type of the TIFFTAG_SUBIFD field changed
-	to TIFF_IFD.
-
-2004-10-10  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/bmp2tif.c: Check the space allocation results.
-
-2004-10-09  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_dir.c: Initialize td_tilewidth and td_tilelength fields
-	of the TIFFDirectory structure with the 0 instead of -1 to avoid
-	confusing integer overflows in TIFFTileRowSize() for striped images.
-
-	* tools/tiff2pdf.c: Fixed TransferFunction tag handling reported
-	by Ross A. Finlayson.
-
-	* libtiff/tif_dir.c: Fixed custom tags handling as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=629
-
-2004-10-08  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_dirinfo.c: Fix bug with tif_foundfield and reallocation
-	of tif_fieldinfo.  
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=630
-
-2004-10-04  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* contrib/iptcutil/README: Added the missing README which goes
-	along with iptcutil.
-
-2004-10-03  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_compress.c: Improved error reporting in
-	TIFFGetConfiguredCODECs() (Dmitry V. Levin).
-
-2004-10-02  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff 3.7.0beta2 released.
-
-	* libtiff/{tif_aux.c, tif_compress.c, tif_dirinfo.c, tif_dirwrite.c,
-	tif_extension.c, tif_fax3.c, tif_luv.c, tif_packbits.c,
-	tif_pixarlog.c, tif_write.c}: Added checks for failed memory
-	allocations and	integer overflows (Dmitry V. Levin).
-
-	* libtiff/tiff.h: Missed TIFF_BIGTIFF_VERSION constant added.
-
-2004-10-01  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_open.c: added a more informative message if a BigTIFF
-	file is opened.
-
-2004-09-30  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_dirinfo.c: changed type of XMLPacket (tag 700) to 
-	TIFFTAG_BYTE instead of TIFFTAG_UNDEFINED to comply with the info
-	in the Adobe XMP Specification.
-
-2004-09-29  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tif_jpeg.c, tif_pixarlog.c}: Use _TIFFmemset() instead of
-	memset().
-
-	* libtiff/{tif_dirread.c, tif_strip.c, tif_tile.c}: Applied patches
-	from Dmitry V. Levin to fix possible integer overflow problems.
-
-2004-09-28  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_getimage.c: Check for allocated buffers before clearing
-	(Dmitry V. Levin).
-
-2004-09-26  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tif_dir.h, tif_dir.c, tif_dirread.c, tif_write.c}:
-	Optimize checking for the strip bounds. 
-
-	* libtiff/{tif_dirread.c, tif_strip.c}: TIFFScanlineSize() and
-	TIFFRasterScanlineSize() functions report zero in the case of integer
-	overflow now. Properly handle this case in TIFFReadDirectory()
-	(patches from Dmitry V. Levin).
-
-2004-09-25  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tif_dirinfo.c, tif_strip.c, tif_tile.c}: Use TIFFhowmany8()
-	macro where appropriate.
-
-	* tools/tiff2bw.c: Write ImageWidth/Height tags to output file, as
-	noted by Gennady Khokhorin.
-
-	* libtiff/tif_dirread.c: Always check the return values, returned
-	by the _TIFFmalloc() (Dmitry V. Levin).
-
-	* libtiff/tif_dir.c: Fixed possible integer overflow _TIFFset*Array()
-	functions (Dmitry V. Levin).
-
-	* libtiff/{tif_dirread.c, tif_dir.c, tif_write.c}:
-	Potential memory leak fixed in TIFFReadDirectory(), _TIFFVSetField(),
-	TIFFGrowStrips() (found by Dmitry V. Levin).
-
-2004-09-24  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tiffio.h, tif_compress.c}: Added TIFFGetConfiguredCODECs()
-	to get the list of configured codecs.
-
-	* libtiff/{tiffiop.h, tif_dirread.c}: More overflow fixes from
-	Dmitry V. Levin.
-
-2004-09-23  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_dirread.c: Applied patch from Dmitry V. Levin to fix
-	possible integer overflow in CheckMalloc() function.
-
-2004-09-22  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tiffiop.h, tif_strip.c}: Use TIFFhowmany8() macro instead
-	of plain TIFFhowmany() where appropriate.
-
-2004-09-21  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_getimage.c: Initialize arrays after space allocation.
-
-2004-09-19  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff 3.7.0beta released.
-
-	* libtiff/{tif_luv.c, tif_next.c, tif_thunder.c}: Several buffer
-	overruns fixed, as noted by Chris Evans.
-
-2004-09-14  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* commit: Added a script to make it more convenient to commit
-	updates.  The CVS commit message is extracted from this ChangeLog
-	file.
-
-2004-09-14  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* configure.ac, configure, aclocal.m4, libtiff/{mkspans.c, tif_fax3.c,
-	tif_getimage.c, tif_luv.c, tif_lzw.c, tif_ojpeg.c, tif_packbits.c,
-	tif_predict.c, tif_read.c, tif_swab.c, tif_thunder.c, tif_write.c,
-	tif_dir.c, tif_dirread.c, tif_dirwrite.c, tif_jpeg.c, tif_dirinfo.c,
-	tif_vms.c, tif_print.c, tif_strip.c, tif_tile.c, tif_dir.h,
-	tif_config.h.in, tiffiop.h}:
-	Get rid of BSD data types (u_char, u_short, u_int, u_long).
-
-2004-09-13  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* libtiff/tiff.h: Fix column tagging. Reference current Adobe XMP
-	specification. Reference libtiff bug tracking system to submit
-	private tag additions.
-
-2004-09-12  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* tools/tiffgt.c: Include "tif_config.h".
-
-	* configure.ac: Use AM_PROG_CC_C_O since it is now needed to build
-	tiffgt.  This results in the 'compile' script being added to the
-	project.
-
-	* tools/Makefile.am (tiffgt_CFLAGS): Add extra build options
-	required to find OpenGL headers necessary to build tiffgt.  Also
-	ensure that the libtiff that we built is used rather than some other
-	libtiff installed on the system.
-
-2004-09-12  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* configure.ac, acinclude.m4, aclocal.m4: New macros to detect GLUT
-	libraries.
-
-2004-09-11  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
-
-	* configure.ac: Pass library configuration defines via
-	tif_config.h rather than extending CPPFLAGS. Configure a
-	libtiff/tiffconf.h in order to satisfy application requirements
-	(not used by library build). Do not define _POSIX_C_SOURCE=2 since
-	this causes failure to build on systems which properly respect
-	this request.
-
-	* libtiff/tiffconf.h.in: New file to act as the template for the
-	configured tiffconf.h
-
-	* libtiff/files.lst (HDRS): Install the configured tiffconf.h.
-
-2004-09-10  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* html/internals.html: Split off a discussion of adding new tags
-	into addingtags.html.
-
-2004-09-10  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* test/{ascii_tag.c, long_tag.c}: Preliminary test suite added.
-
-	* tools/tiff2pdf.c: Fixed reading TransferFunction tag as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=590
-
-	* libtiff/tif_print.c: Fixes in InkNames and NumberOfInks reporting.
-
-	* libtiff/tif_dirread.c: Don't reject to read tags of the
-	SamplesPerPixel size when the tag count is greater than number of
-	samples as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=576
-
-	* libtiff/tiff.h: Use _TIFF_DATA_TYPEDEFS_ guardian to switch off
-	defining int8/uint8/... etc. types. As per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=607
-
-2004-09-09  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* tools/tiff2ps.c, tools/tiffmedian.c: fiddle with include files
-	to avoid compile warnings about getopt() and a few other things.
-
-2004-09-02  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_dirread.c: Use memcpy() function instead of pointer
-	assigning magic in TIFFFetchFloat().
-
-2004-09-01  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tiffio.h, tif_open.c}: Applied patches from Joris Van Damme
-	to avoid requirement for tiffiop.h inclusion in some applications. See
-	here
-
-	http://www.asmail.be/msg0054799560.html
-	
-	for details.
-
-	* tools/fax2tiff.c: Use the new functions in the code.
-
-2004-08-25  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiff2pdf.c: Initialize arrays properly.
-
-	* tools/tiff2ps.c: Avoid zero division in setupPageState() function;
-	properly initialize array in PSDataBW().
-
-2004-08-24  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiff2pdf.c: More fixes for bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=590
-
-	from Ross Finlayson.
-
-2004-08-23  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiff2ps.c: Fixed problem with uninitialized values.
-
-	* libtiff/tif_dir.c: Initialize tif_foundfield data member in the
-	TIFFDefaultDirectory() (in addition to 2004-08-19 fix).
-
-	* tools/tiff2pdf.c: Fixed a bunch of problems as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=590
-
-2004-08-20  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiff2pdf.c: Applied patch from Ross Finlayson that checks
-	that the input file has compression, photometric interpretation,
-	etcetra, tags or if not than a more descriptive error is returned.
-
-	* libtiff/tif_dirread.c: Fixed problem in TIFFReadDirectory() in the
-	code, responsible for tag data type checking.
-
-2004-08-19  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tiffiop.h, tif_dirinfo.c}: Fixed problem with the static
-	variable as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=593
-
-2004-08-16  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/ras2tiff.c: Fixed issue with missed big-endian checks as per
-	bug http://bugzilla.remotesensing.org/show_bug.cgi?id=586
-
-2004-08-01  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tif_config.h.in, tif_config.h.vc}: config.h.in and
-	config.h.vc files renamed in the tif_config.h.in and tif_config.h.vc.
-
-2004-07-24  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_lzw.c: LZW compression code is merged back from the
-	separate package. All libtiff tools are updated to not advertise an
-	abcence of LZW support.
-
-2004-07-12  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tiffio.h: Revert thandle_t back to void* type.
-
-2004-07-11  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tif_read.c, tif_tile.c, tif_strip.c}: Fixes in error
-	messages, as suggested by Bernd Herd.
-
-2004-07-03  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_dir.c: Call TIFFError() instead of producing warnings
-	when setting custom tags by value. Reported by Eric Fieleke.
-
-2004-06-14  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/bmp2tiff.c: Add missed RawsPerStrip setting.
-
-2004-06-08  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/bmp2tiff.c: Added new utility to convert Windows BMP files
-	into TIFFs.
-
-2004-06-07  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff 3.7.0alpha released.
-
-2004-06-06  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tiff.h, tif_dirwrite.c, tif_fax3.c, tif_packbits.c,}: Get rid
-	of ugly 64-bit hacks, replace them with the clever (autoconf based )
-	ones :-).
-
-	* libtiff/tiffio.h: Define thandle_t as int, not void* (may cause
-	problems in 64-bit environment).
-
-2004-06-05  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiffset.c: tiffset now can set any libtiff supported tags.
-	Tags can be supplied by the mnemonic name or number.
-
-	* libtiff/{tiffio.h, tif_dir.h, tif_dirinfo.c,}: Added two new
-	functions TIFFFindFieldInfoByName() and TIFFFieldWithName().
-
-2004-05-27  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_ojpeg.c: Fixed problem with duplicated SOI and SOF
-	markers as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=581
-
-2004-05-24  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiffsplit.c: Don't forget to copy Photometric
-	Interpretation tag.
-
-2004-05-20  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tif_open.c, tiffio.h}: New function added:
-	TIFFIsBigEndian(). Function returns nonzero if given was file written
-	in big-endian order.
-
-	* tools/tiffsplit.c: Fixed problem with unproperly written multibyte
-	files. Now output files will be written using the same byte order
-	flag as	in the input image. See
-	
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=574
-	
-	for details.
-	
-2004-05-19  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_print.c: added (untested) support for printing
-	SSHORT, SLONG and SRATIONAL fields.
-
-	* tools/tiffcp.c: close output file on normal exit.
-
-2004-05-17  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_fax3.c: Avoid reading CCITT compression options
-	if compression type mismatches. See
-	
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=565
-
-2004-04-30  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_strip.c: Never return 0 from the
-	TIFFNumberOfStrips().
-
-2004-04-29  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_dirread.c: Workaround for broken TIFF writers which
-	store single SampleFormat value for multisampled images. See
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=562
-
-2004-04-25  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* configure.ac, libtiff/{tiff.h, config.h.in}: Added tests for int8,
-	int16 and int32 types to avoid complains on some compilers. Details at
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=39
-
-2004-04-20  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiff2pdf.c: Fixed problem with unaligned access as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=555
-
-2004-04-14  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_write.c: Allow in-place updating of the compressed
-	images (don't work properly with all codecs). For details see GDAL bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=534
-
-2004-04-06  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_jpeg.c: Workaround for wrong sampling factors used
-	in the Intergarph JPEG compressed TIFF images as per bug:
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=532
-
-2004-04-04  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_open.c: close clientdata if TIFFClientOpen() fails
-	via bad2. 
-
-2004-03-26  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiffcp.c: Properly set Photometric Interpretation in case of
-	JPEG compression of grayscale images.
-
-	* tools/tiffcp.c: Don't emit warnings when Orientation tag does not
-	present in the input image.
-
-2004-03-19  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* {many}: The first attempt to switch to autotools.
-
-2004-03-03  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_open.c: Use dummy mmap/munmap functions in
-	TIFFClientOpen() when the appropriate client functions was not
-	supplied by user.
-
-2004-03-02  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* tools/ycbcr.c: fixed main() declaration as per:
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=513
-
-2004-02-26  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiffsplit.c: Copy JPEGTables tag contents for JPEG compressed 
-	images. Reported by Artem Mirolubov.
-
-	* libtiff/tif_dirread.c: Fixed problem with handling TIFF_UNDEFINED 
-	tag type in TIFFFetchNormalTag() as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=508
-
-2004-02-17  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_codec.c: Fixed typo in TIFFInitPackBits name as per:
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=494
-
-2004-02-05  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_fax3.c: Fixed problem with CCITT encoding modes as per
-	bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=483
-
-	But we need more work on fax codec to support update mode.
-
-2004-01-30  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/libtiff.def: Added TIFFCurrentDirOffset, TIFFWriteCheck,
-	TIFFRGBAImageOK, and TIFFNumberOfDirectories as suggested by 
-	Scott Reynolds. 
-
-2004-01-29  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tiff.h: Fixed tag definitions for TIFFTAG_YCLIPPATHUNITS
-	and TIFFTAG_INDEXED as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=475
-
-	* libtiff/{tif_win32.c, tif_unix.c}: Check whether the pointer is
-	NULL before proceeding further as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=474
-
-	Check results, returned by the TIFFFdOpen() before returning and close
-	file if TIFFFdOpen() failed as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=468
-	
-	* libtiff/tif_open.c: More fixes for
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=468
-
-2004-01-28  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{libtiff.def, tif_close.c, tiffio.h, tif_open.c}: Separate
-	TIFFCleanup() from the TIFFClose() in order to fix the bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=468
-
-	* tools/tiffcp.c: Fixed problem with wrong interpretation of the
-	InkNames tag as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=466
-
-	Memory leak fixed.
-
-2004-01-21  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_dirwrite.c: Fixed handling of writable ASCII tags that
-	are field_passcount=TRUE properly.  Arguably anonymous custom tags
-	should be declared as passcount=FALSE, but I don't want to change
-	that without a careful review. 
-
-2004-01-20  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_write.c: Fixed reporting size of the buffer in case of
-	stripped image in TIFFWriteBufferSetup(). As per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=460
-
-2004-01-11  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_dir.c: Incomplete cleanup in TIFFFreeDirectory(),
-	patch from Gerben Koopmans.
-
-	* libtiff/tif_dirread.c: Check field_passcount value before setting
-	the value of undefined type, patch from Gerben Koopmans.
-
-2004-01-02  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiffcp.c: Fixed problem with wrong Photometric setting for
-	non-RGB images.
-
-2003-12-31  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_win32.c: Fixed problem with _TIFFrealloc() when the NULL
-	pointer passed. Patch supplied by Larry Grill.
-
-	* libtiff/{tiff.h, tif_fax3.c}:Fixes for AMD 64 platform as
-	suggested by Jeremy C. Reed.
-
-2003-12-26  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff 3.6.1 released.
-
-2003-12-24  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* config.guess, config.sub: Updated from the recent upstream.
-
-2003-12-22  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tif_color, tif_getimage.c, tiffio.h}, man/TIFFcolor.3t:
-	More cleanups in color conversion interface, added appropriate manual
-	page.
-
-2003-12-19  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tif_extension.c, tif_dirinfo.c, tiff.h}: Warnings fixed as
-	per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=357
-
-	* tools/tiff2ps.c: Added support for alpha channel. Fixes
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=428
-
-	* libtiff/{libtiff.def, tif_color.c, tif_getimage.c, tiffio.h}:
-	Interface for Lab->RGB color conversion is finally cleaned up.
-	Added support for ReferenceBlackWhite tag handling when converted from
-	YCbCr color space. The latter closes
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=120
-
-2003-12-07  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tif_getimage.c, tiffio.h}: Avoid warnings.
-
-	* libtiff/makefile.vc, tools/makefile.vc: Support for IJG JPEG
-	library.
-
-2003-12-06  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tif_getimage.c, tif_aux.c}: Read WhitePoint tag from the
-	file and properly use it for CIE Lab->RGB transform.
-
-2003-12-04  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tif_getimage.c, tif_color.c, tiffio.h}: YCbCr->RGB
-	conversion routines now in the tif_color.c module. New function
-	TIFFYCbCrtoRGB() available in TIFF API.
-
-	* libtiff/tif_dirwrite.c: Handle TIFF_IFD tag type correctly.
-
-2003-12-03  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tif_getimage.c, tif_color.c, tiffio.h}: Improvements in
-	CIE Lab conversion code. Start moving YCbCr stuff to the tif_color.c
-	module.
-
-	* libtiff/{tif_getimage.c, tiffio.h}, man{TIFFReadRGBAImage.3t,
-	TIFFReadRGBAStrip.3t, TIFFReadRGBATile.3t, TIFFRGBAImage.3t}:
-	Finally resolved problems with orientation handling. TIFFRGBAImage
-	interface now properly supports all possible orientations, i.e. images
-	will be flipped both in horizontal and vertical directions if
-	required. 'Known bugs' section now removed from the appropriate manual
-	pages. Closed bug entry:
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=322
-
-2003-12-02  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_dir.c: Fixed order of the parameters in TIFFError()
-	function calls as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=440
-
-2003-11-28 Ross Finlayson  <libtiff at apexinternetsoftware.com>
-
-	* tools/tiff2pdf.c:  Some bugs fixed.
-
-2003-11-27  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_luv.c: Fixed bug in 48-bit to 24-bit conversion routine,
-	reported by Antonio Scuri.
-
-	* man/tiff2pdf.1: Few improvements in page layout.
-
-	* Makefile.in, /man/Makefile.in, /html/man/tiff2pdf.1.html:
-	 Added support fpr tiff2pdf manual page.
-
-2003-11-26 Ross Finlayson  <libtiff at apexinternetsoftware.com>
-
-	* /man/tiff2pdf.1:  File added to repository.
-
-2003-11-26  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* Makefile.in, /tools/{Makefile.in, makefile.vc}:
-	 Added support fpr tiff2pdf utility.
-
-2003-11-25  Ross Finlayson  <libtiff at apexinternetsoftware.com>
-
-	* /tools/tiff2pdf.c:  File added to repository.
-
-2003-11-22  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* /tools/raw2tiff.c: sqrtf() replaced with sqrt().
-
-2003-11-21  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* /tools/raw2tiff.c: #include <getopt.h> removed.
-
-	* tools/{Makefile.in, tiffgt.c}: Unmaintained and platform dependent
-	sgigt utility removed and replaced with the completely rewritten
-	portable tiffgt tool (depend on OpenGL and GLUT). Initial revision,
-	there is a lot of things to improve.
-
-	* libtiff/tif_ojpeg.c: TIFFVGetField() function now can properly
-	extract the fields from the OJPEG files. Patch supplied by Ross
-	Finlayson.
-
-	* libtiff/{tiffio.h, tif_codec.c}, man/{libtiff.3t, TIFFcodec.3t}:
-	Added new function TIFFIsCODECConfigured(), suggested by Ross
-	Finlayson.
-
-2003-11-18  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_dirinfo.c: Implemented binary search in
-	_TIFFMergeFieldInfo(). Patch supplied by Ross Finlayson.
-
-	* libtiff/tif_dir.h: _TIFFFindOrRegisterdInfo declaration replaced
-	with _TIFFFindOrRegisterFieldInfo as reported by Ross Finlayson.
-
-2003-11-17  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* tif_dirread.c: do not mark all anonymously defined tags to be 
-	IGNOREd.  
-
-2003-11-17  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* contrib/pds/{tif_pdsdirread.c, tif_pdsdirwrite.c}: Use
-	TIFFDataWidth() function insted of tiffDataWidth array.
-
-2003-11-16  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tiff.h, tif_dirinfo.c}: Added support for IFD (13)
-	datatype, intruduced in "Adobe PageMaker TIFF Tech. Notes".
-
-2003-11-15  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* Makefile.in: fixed missing backslash for tif_color.c in list.
-
-2003-11-13  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tif_color.c, tif_getimage.c, tiffio.h, Makefile.in}:
-	New color space conversion code: CIE L*a*b* 1976 images now supported
-	by the TIFFRGBAImage interface. All introduced routines go to new
-	module tif_color.c. Eventually all color conversion functions should
-	be moved there.
-
-2003-11-12  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/{ras2tiff.c, rasterfile.h}: Properly determine SUN Rasterfiles
-	with the reverse byte order (it is reported by the magic header
-	field). Problem reported by Andreas Wiesmann.
-
-	* tools/raw2tiff.c, man/raw2tiff.1: Few improvements in correlation
-	calculation function. Guessing mechanics now documented in manual page.
-
-2003-11-11  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/raw2tiff.c: Implemented image size guessing using
-	correlation coefficient calculation between two neighbour lines.
-
-2003-11-09  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_tile.c: remove spurious use of "s" (sample) in the 
-	planarconfig_contig case in TIFFComputeTile().
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=387
-
-2003-11-09  Andrey Kiselev  <dron at ak4719.spb.edu>
-	
-	* libtiff/tiffiop.h: New macros: TIFFmax, TIFFmin and TIFFrint.
-	
-2003-11-07  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tiffio.h, tif_strip.c}, man/{TIFFstrip.3t, libtiff.3t}:
-	Added TIFFRawStripSize() function as suggested by Chris Hanson.
-
-2003-11-03  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tif_lzw.c, tif_fax3.c}: Proper support for update mode as
-	per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=424
-
-2003-10-29  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/libtiff.def: Added TIFFReadRGBAImageOriented.
-
-	* html/build.html: Added note about GNU make requirement.
-
-2003-10-25  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* Makefile.in: Fixes in using MAKEFLAGS as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=418
-
-	* port/install.sh.in: Option -p added to the mkdir command to create
-	all directory tree structure before installing.
-
-2003-10-18  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* /tools/tiff2ps.c: #include <strings.h> replaced with the
-	#include <string.h>.
-
-2003-10-16  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* Makefile.in: Add an absolute path to the test_pics.sh call.
-
-2003-10-12  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tiffcomp.h: #define _BSDTYPES_DEFINED when defining BSD
-	typedefs.
-
-2003-10-09  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* configure, libtiff/{Makefile.in, mkversion.c}:
-	Relative buildings fixed.
-
-	* tools/Makefile.in: Added "-I../libtiff" to the tiffset building
-	rule.
-
-2003-10-07  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* Makefile.in: Added missed v3.6.0.html.
-
-	* libtiff/tiffio.h: Typo fixed: ORIENTATION_BOTTOMLEFT replaced with
-	ORIENTATION_BOTLEFT.
-
-2003-10-04  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* 3.6.0 final release.
-
-2003-10-03  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tif_getimage.c, tiffio.h}, man/TIFFReadRGBAImage.3t: New
-	function TIFFReadRGBAImageOriented() implemented to retrieve raster
-	array with user-specified origin position as suggested by Jason Frank.
-	See
-	
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=322
-
-	for details.
-	
-	* tools/tiff2rgba.c: Switched to use TIFFReadRGBAImageOriented()
-	instead of TIFFReadRGBAImage().
-
-	* tools/tiff2ps.c: Fixed possible endless loop as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=404
-
-2003-09-30  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_dirread.c: Check field counter against number of fields
-	in order to fix
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=366
-
-	* libtiff/tif_fax3.c: Fix wrong line numbering as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=342
-
-2003-09-25  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/{tiffiop.h, tif_dirread.c, tif_dir.c, tif_open.c,
-	tif_close.c}: Store a list of opened IFD to prevent looping as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=383
-
-2003-09-23  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_dirread.c: More fixes for	EstimateStripByteCounts(). See
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=358
-
-2003-08-21  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiffmedian.c: int declaration replaced with the uint32 to
-	support large images as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=382
-
-2003-08-12  Andrey Kiselev  <dron at ak4719.spb.edu>
-
- 	* libtiff/Makefile.in: Fixed problem with building in different
-	directory.
-
-	* tools/tiff2ps.c: Added missing #include <strings.h>.
-
-	* libtiff/tif_dirwrite.c: More fixes for custom tags code
-	from Ashley Dreier.
-
-2003-08-07  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiff2ps.c: Added page size setting when creating PS Level 2.
-	Patch submitted by Balatoni Denes (with corrections from Tom
-	Kacvinsky).
-
-	* tools/tiff2ps.c: Fixed PS comment emitted when FlateDecode is
-	being used. Reported by Tom Kacvinsky.
-
-	* libtiff/tif_dirwrite.c: Fixed problem with custom tags writing,
-	reported by Ashley Dreier.
-
-	* libtiff/tif_print.c: Fixed problem with float tags reading, support
-	for printing RATIONAL and BYTE tags added.
-
-2003-08-05  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_lzw.c: Move LZW codec state block allocation back to
-	TIFFInitLZW(), because its initialization in LZWSetupDecode() cause
-	problems with predictor initialization. Remove O_RDONLY check during
-	state block allocation to be able open LZW compressed files in update
-	mode.
-
-	Problem exist for libtiff version of the tif_lzw.c module. One from
-	lzw-compression-kit hasn't such troubles.
-
-2003-08-04  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_write.c: modified tif_write.c so that the various
-	encoded write functions use tif_postdecode() to apply byte order
-	swapping (swab) to the application passed data buffer if the same
-	would be done when reading.  This allows us to write pixel data with
-	more than 8 bits per sample to existing files of a non-native byte 
-	order.  One side effect of this change is the applications buffer
-	itself is altered in this case by the act of writing. 
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=171
-
-2003-07-25  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_open.c: avoid signed/unsigned casting warning
-	initializing typemask as per patch from J.A. Strother.
-
-	* tools/tiffcp.c: fixed signed/unsigned casting warning.
-
-	* libtiff/tif_print.c: dos2unix conversion.
-
-	* tools/tiffsplit.c: increased the maximum number of pages that
-	can be split.  Patch provided by Andrew J. Montalenti.
-
-2003-07-11  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/raw2tiff.c: Added option `-p' to explicitly select color
-	space of input image data. Closes
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=364
-
-2003-07-08  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* tif_aux.c, tif_codec.c, tif_dir.c, tif_dirread.c, tif_extension.c,
-	tif_fax3.c, tif_getimage.c, tif_luv.c, tif_lzw.c, tif_next.c, 
-	tif_packbits.c, tif_predict.c, tif_print.c, tif_swab.c, tif_thunder.c:
-	avoid casting warning at /W4. 
-
-2003-07-03  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/thumbnail.c: Memory leak fixed as reported by Robert S. Kissel.
-
-2003-06-30  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_pixarlog.c: Unused variables removed.
-
-	* libtiff/{tif_dirread.c, tif_dir.c}: Fixed problem with
-	EstimateStripByteCounts() as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=358
-
-	* libtiff/{tif_dirwrite.c, tif_packbits.c}: Fixed compilation on
-	64-bit architectures as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=357
-
-	* libtiff/tif_dirinfo.c: TIFFDataWidth() returns 0 in case of
-	unknown data type.
-	
-2003-06-19  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_print.c: fixed some serious bugs when printing
-	custom tags ... almost certain to crash. 
-
-	* libtiff/tif_dirread.c: Don't ignore custom fields that are
-	autodefined.  Not sure how this got to be like this.
-
-2003-06-18  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* 3.6.0 Beta2 released.
-
-	* tools/tiffcmp.c, man/tiffcmp.1: Fixed problem with unused data
-	comparing as per bug
-	
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=349
-
-	`-z' option now can be used to set the number of reported different
-	bytes.
-	
-2003-06-09  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiffcp.c, man/tiffcp.1: Added possibility to specify value -1
-	to -r option to get the entire image as one strip. See
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=343
-
-	for details.
-
-2003-06-04  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiffcp.c: Set the correct RowsPerStrip and PageNumber
-	values as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=343
-
-2003-05-27  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_jpeg.c: modified segment_height calculation to always
-	be a full height tile for tiled images.  Also changed error to just
-	be a warning.
-
-2003-05-25  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/fax2tiff.c: Page numbering fixed, as per bug
-	
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=341
-
-2003-05-20  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* contrib/ojpeg/{Makefile.in, jdhuff.h, jinclude.h, ojpeg.c, README},
-	configure, Makefile.in:	Switched back to the old behaviour. Likely
-	better solution should be found for OJPEG support.
-
-2003-05-11  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/mkversion.c: Fixed problem with wrong string size when
-	reading RELEASE-DATE file.
-
-2003-05-07  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiff2ps.c: Fixed bug in Ascii85EncodeBlock() function: array
-	index was out of range.
-
-2003-05-06  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* contrib/ojpeg/{Makefile.in, jdhuff.h, jinclude.h, ojpeg.c, README},
-	configure, Makefile.in:	Improved libtiff compilation with OJPEG
-	support. Now no need for patching IJG JPEG library, hack requred by
-	libtiff will be compiled and used in-place. Implemented with
-	suggestion and help from Bill Allombert, Debian's libjpeg maintainer.
-
-	* libtiff/tif_aux.c: Properly handle TIFFTAG_PREDICTOR in
-	TIFFVGetFieldDefaulted() function.
-
-2003-05-05  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/ppm2tiff.c: PPM header parser improved: now able to skip
-	comments.
-
-	* tools/tiffdither.c: Fixed problem with bit fill order tag setting:
-	was not copied from source image.
-
-	* libtiff/getimage.c: Workaround for some images without correct
-	info about alpha channel as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=331
-
-2003-04-29  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiff2ps.c, man/tiff2ps.1: Add ability to generate PS Level 3.
-	It basically allows one to use the /flateDecode filter for ZIP
-	compressed TIFF images. Patch supplied by Tom Kacvinsky. Fixes
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=328
-
-	* tools/tiff2ps.c: Force deadzone printing when EPS output specified
-	as per bug
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=325
-
-2003-04-17  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_dirread.c: Removed additional check for StripByteCounts
-	due to problems with multidirectory images. Quality of error messages
-	improved.
-
-2003-04-16  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiffcp.c: Fixed problem with colorspace conversion for JPEG
-	encoded images. See bug entries
-	
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=275
-
-	and
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=23
-
-	* libtiff/tif_dirread.c: Additional check for StripByteCounts
-	correctness. Fixes
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=320
-
-2003-03-12  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/{fax2ps.c, fax2tiff.c, gif2tiff.c, pal2rgb.c, ppm2tiff.c,
-	ras2tiff.c, raw2tiff.c, rgb2ycbcr.c, thumbnail.c, tiff2bw.c,
-	tiff2ps.c, tiff2rgba.c, tiffcp.c, tiffdither.c, tiffinfo.c,
-	tiffmedian.c}: Added library version reporting facility to all tools.
-
-2003-03-06  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* port/install.sh.in: Fixed problems with install producing paths
-	like ///usr/local/lib on cygwin.
-
-2003-02-27  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/fax2tiff.c, man/fax2tiff.1: New switch (-X) to set width of
-	raw input page. Patch supplied by Julien Gaulmin. See
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=293
-
-	for details.
-
-2003-02-26  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_dir.c: fixed up the tif_postdecode settings
-	responsible for byte swapping complex image data.
-
-	* libtiff/tif_lzw.c: fixed so that decoder state isn't allocated till
-	LZWSetupDecode().  Needed to read LZW files in "r+" mode.
-
-2003-02-07  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/ppm2tiff.c: Fixed problem with too many arguments.
-
-2003-02-04  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/raw2tiff.c: Memory leak fixed.
-
-2003-02-03  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/fax2tiff.c, man/fax2tiff.1: Applied patch from Julien Gaulmin
-	(thanks, Julien!). More switches for fax2tiff tool for better control
-	of input and output. Details at
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=272
-
-2003-02-03  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_jpeg.c: Modified to defer initialization of jpeg
-	library so that we can check if there is already any tile/strip data
-	before deciding between creating a compressor or a decompressor. 
-
-2003-01-31  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_write.c: TIFFWriteCheck() now fails if the image is
-	a pre-existing compressed image.  That is, image writing to 
-	pre-existing compressed images is not allowed.
-
-	* libtiff/tif_open.c: Removed error if opening a compressed file
-	in update mode. 
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=198
-
-2003-01-31  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* config.guess, config.sub: Updated to recent upstream versions.
-
-2003-01-15  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* cut 3.6.0 Beta release.
-
-2002-12-20  Andrey Kiselev  <dron at ak4719.spb.edu>
-	
-	* tools/fax2ps.c, man/fax2ps.1: Page size was determined
-	in wrong way as per bug
-	
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=239
-
-2002-12-17  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_dirread.c: Allow wrong sized arrays in 
-	TIFFFetchStripThing(). 
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=49
-
-2002-12-02  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_dir.c: fix problem with test on td_customValueCount.
-	Was using realloc even first time.  Fix by Igor Venevtsev.
-
-2002-11-30  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_dir.c: fixed bug with resetting an existing custom
-	field value.
-
-	* libtiff/tif_dir.c: Fixed potential problem with ascii "custom" 
-	tags in TIFFVGetField() ... added missing break.
-
-2002-10-14  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* tools/tiff2ps.c: fixes a problem where "tiff2ps -1e" did not make
-	the scanline buffer long enough when writing rgb triplets.
-	The scanline needs to be 3 X the number of dots or else it will
-	contain	an incomplete triplet and programs that try to separate
-	the eps by redefining the colorimage operator will get messed up.
-	Patch supplied by William Bader.
-
-	* Makefile.in: added tif_extension.c to file list as per 
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=218.
-
-2002-10-11  Andrey Kiselev  <dron at ak4719.spb.edu>
-	
-	* configure, config.site, libtiff/{tif_unix.c, Makefile.in}: Fix for
-	large files (>2GiB) supporting. New option in the config.site:
-	LARGEFILE="yes". Should be enough for I/O of the large files.
-
-2002-10-10  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/html/v3.6.0.html: new release notes.
-
-	* libtiff/index.html: removed faq, cvs snapshot cruft.  Added email
-	link for Andrey.  Pointer to v3.6.0.html.
-
-	* libtiff/Makefile.in: added direct rule for tiffvers.h for release.
-
-2002-10-07  Andrey Kiselev  <dron at ak4719.spb.edu>
-	* tools/tiff2ps.c, man/tiff2ps.1: Applied patch form Sebastian Eken
-	(thanks, Sebastian!). New switches:
-	-b # for a bottom margin of # inches
-	-c   center image
-	-l # for a left margin of # inches
-	-r   rotate the image by 180 degrees
-	New features merged with code for shrinking/overlapping.
-	Previously added -c and -n switches (for overriding PS units) renamed
-	in -x and -y respectively.
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=200
-
-	* html/man/*.html: Updated from actual manual pages.
-
-2002-10-06  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_jpeg.c: fixed problem with boolean defined with wrong
-	size on windows.  Use #define boolean hack.  
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=188
-
-	* libtiff/tiff.h: Don't do special type handling in tiff.h unless
-	USING_VISUALAGE is defined.
-	
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=39
-
-2002-10-03  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tiff.h: added COMPRESSION_JP2000.
-
-2002-10-02  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_dirread.c: Another fix for the fetching SBYTE arrays
-	by the TIFFFetchByteArray() function. Should finally resolve
-	
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=52
-	
-	* configure: Set -DPIXARLOG_SUPPORT option along with -DZIP_SUPPORT
-
-	* html/Makefile.in: New targets added: html and groffhtml for
-	producing HTML representations of the manual pages automatically.
-	html target uses man2html tool, groffhtml uses groff tool.
-	
-2002-09-29  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* configure, libtiff/Makefile.in: Added SCO OpenServer 5.0.6 support
-	from John H. DuBois III.  
-
-2002-09-15  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* Makefile.in, /man/{raw2tiff.1, Makefile.in, libtiff.3}: Added
-	manual page for raw2tiff(1) tool.
-	
-2002-09-12  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* /libtiff/{tiffio.h, tif_dir.h}: TIFFDataWidth() declaration moved to
-	the tiffio.h header file.
-	
-	* Makefile.in, /man/{TIFFDataWidth.3t, Makefile.in, libtiff.3}: Added
-	manual page for TIFFDataWidth() function
-
-2002-09-08  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_dirread.c: Expand v[2] to v[4] in TIFFFetchShortPair()
-	as per http://bugzilla.remotesensing.org/show_bug.cgi?id=196.
-
-	* tools/tiff2ps.c: Don't emit BeginData/EndData DSC comments
-	since we are unable to properly include the amount to skip. 
-	
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=80
-
-2002-09-02  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* /libtiff/tif_dirread.c: Fixed problem with SBYTE type data fetching
-	in TIFFFetchByteArray(). Problem described at
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=52
-
-2002-08-22  Andrey Kiselev  <dron at ak4719.spb.edu>
-	
-	* /libtiff/tif_dirinfo.c: Further additions to free custom fields
-	in _TIFFSetupFieldInfo() function.
-	See http://bugzilla.remotesensing.org/show_bug.cgi?id=169 for details.
-
-	* /libtiff/tif_lzw.c: Additional consistency checking added in
-	LZWDecode() and LZWDecodeCompat().
-	Fixes http://bugzilla.remotesensing.org/show_bug.cgi?id=190
-	and http://bugzilla.remotesensing.org/show_bug.cgi?id=100
-	
-	* /libtiff/tif_lzw.c:
-	Added check for valid code lengths in LZWDecode() and
-	LZWDecodeCompat(). Fixes
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=115
-
-2002-08-16  Andrey Kiselev  <dron at ak4719.spb.edu>
-	
-	* /libtiff/{Makefile.vc, libtiff.def}:
-	Missed declarations added.
-
-2002-08-15  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* tif_getimage.c: Ensure that TIFFRGBAImageBegin() returns the
-	return code from the underlying pick function.
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=177
-
-	* tif_dir.h: changed FIELD_CODEC to 66 from 64 to avoid overlap 
-	with FIELD_CUSTOM as mentioned in bug 169.
-
-	* tif_close.c: added logic to free dynamically created anonymous
-	field definitions to correct a small memory leak.
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=169
-
-2002-08-10  Andrey Kiselev  <dron at ak4719.spb.edu>
-	
-	* /tools/{raw2tiff.c, Makefile.in, Makefile.lcc, Makefile.vc}:
-	New tool: raw2tiff --- raw images to TIFF converter. No manual page yet.
-
-2002-07-31  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_jpeg.c: Fixed problem with setting of nrows in 
-	JPEGDecode() as per bugzilla bug (issue 1):
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=129
-
-	* libtiff/{tif_jpeg.c,tif_strip.c,tif_print.c}: Hacked tif_jpeg.c to
-	fetch TIFFTAG_YCBCRSUBSAMPLING from the jpeg data stream if it isn't
-	present in the tiff tags. 
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=168
-
-	* libtiff/tif_read.c, libtiff/tif_write.c: TIFFReadScanline() and
-	TIFFWriteScanline() now set tif_row explicitly in case the codec has
-	fooled with the value. 
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=129
-
-2002-06-22  Andrey Kiselev  <dron at ak4719.spb.edu>
-	
-	* /tools/tiff2ps.c: Added workaround for some software that may crash
-	when last strip of image contains fewer number of scanlines than
-	specified by the `/Height' variable. See
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=164
-	for explanation.
-
-2002-06-21  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiff2ps, man/tiff2ps.1: New functionality for tiff2ps utility:
-	splitting long images in several pages. See
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=142 for explanation.
-	Patch granted by John Williams <williams at morinda.com>.
-
-2002-06-11  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/contrib/win95: renamed to contrib/win_dib.  Added new 
-	Tiffile.cpp example of converting TIFF files into a DIB on Win32.  
-	This one is described in:
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=143
-
-	* libtiff/tif_ojpeg.c: Major upgrade from Scott.  See details at:
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=156
-
-2002-05-10  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiff2ps: New commandline switches to override resolution
-	units obtained from the input file. Closes
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=131
-
-2002-04-26  Andrey Kiselev  <dron at ak4719.spb.edu>
-	
-	* libtiff/libtiff.def: Added missed declaration.
-	
-2002-04-22  Andrey Kiselev  <dron at ak4719.spb.edu>
-	
-	* tools/fax2tiff.c: Updated to reflect latest changes in libtiff.
-	Closes http://bugzilla.remotesensing.org/show_bug.cgi?id=125
-
-2002-04-20  Andrey Kiselev  <dron at ak4719.spb.edu>
-	
-	* libtiff/tif_open.c: Pointers to custom procedures
-	in TIFFClientOpen() are checked to be not NULL-pointers.
-	
-2002-04-18  Andrey Kiselev  <dron at ak4719.spb.edu>
-	
-	* libtiff/libtiff.def: Added missed declarations.
-
-	* libtiff/tif_pixarlog.c: Updated for using tif_tagmethods structure.
-
-2002-04-16  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_lzw.c: Additional checks for data integrity introduced.
-	Should finally close
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=100
-	
-2002-04-10  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/tiff2ps: Division by zero fixed.
-	Closes http://bugzilla.remotesensing.org/show_bug.cgi?id=88
-
-2002-04-09  Andrey Kiselev  <dron at ak4719.spb.edu>
-	
-	* libtiff/: tif_dirwrite.c, tif_write.c, tiffio.h:
-	TIFFCheckpointDirectory() routine added.
-	Closes http://bugzilla.remotesensing.org/show_bug.cgi?id=124
-
-	* man/: TIFFWriteDirectory.3t,  Makefile.in: Added description
-	for the new function.
-
-2002-04-08  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/: tif_codec.c, tif_compress.c, tiffiop.h: Introduced
-	additional members tif->tif_decodestatus and tif->tif_encodestatus
-	for correct handling of unconfigured codecs (we should not try to read
-	data or to define data size without correct codecs).
-
-	* libtiff/tif_getimage.c: The way of codecs checking in TIFFRGBAImageOK
-	changed. Now it has used tif->tif_decodestatus and
-	tif->tif_encodestatus.
-	Should fix http://bugzilla.remotesensing.org/show_bug.cgi?id=119 (in
-	case of __cvs_8.tif test image).
-
-	* libtiff/: tif_dirinfo.c, tif_dirread.c: Somebody makes a bug in
-	tif_dirread.c when TIFFCreateAnonFieldInfo was introduced.
-	Closes http://bugzilla.remotesensing.org/show_bug.cgi?id=119 in case
-	of _cvs_00000-00.tif, _cvs_00000-01.tif and _cvs_00000-02.tif.
-
-2002-04-04  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/: tif_lzw.c: Assertions in LZWDecode and LZWDecodeCompat
-	replaced by warnings. Now libtiff should read corrupted LZW-compressed
-	files by skipping bad strips.
-	Closes http://bugzilla.remotesensing.org/show_bug.cgi?id=100
-	
-2002-04-03  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_dirwrite.c: Removed some dead code.
-
-	* libtiff/*: Cleanup some warnings.
-
-	* libtiff/tif_dir.c: Fixed bug with count returned by TIFFGetField()
-	for variable length FIELD_CUSTOM values.  Was int * but should be
-	u_short *.
-
-2002-04-01  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* tools/: tifcp.c: Added support for 'Orientation' tag in tiffcp
-	utility (at cpStripToTile routine).
-
-2002-03-27  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* tif_dirread.c: avoid div-by-zero if rowbytes is zero in chop func.
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=111
-
-	* tif_print.c: Fixed so that ASCII FIELD_CUSTOM values with 
-	passcount set FALSE can be printed (such as TIFFTAG_SOFTWARE).
-
-	* libtiff/tif_dir.c,tif_dirinfo.c,tif_dir.h,tif_ojpeg.c: modified so 
-	that TIFFTAG_SOFTWARE uses FIELD_CUSTOM as an example.
-
-2002-03-26  Dwight Kelly  <dbmalloc at remotesensing.org>
-
-	* libtiff/: tiff.h, tif_dir.c, tif_dir.h, tif_dirinfo.c, tif_dirread.c,
-	tif_dirwrite.c: Added get/put code for new tag XMLPACKET as defined
-	in Adobe XMP Technote. Added missing INKSET tag value from TIFF 6.0 spec 
-	INKSET_MULTIINK (=2). Added missing tags from Adobe TIFF technotes: 
-	CLIPPATH, XCLIPPATHUNITS, YCLIPPATHUNITS, OPIIMAGEID, OPIPROXY and
-	INDEXED. Added PHOTOMETRIC tag value from TIFF technote 4 ICCLAB (=9).
-
-2002-03-26  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/: tif_getimage.c: TIFFReadRGBAStrip and TIFFReadRGBATile
-	now also uses TIFFRGBAImageOK before reading. This is additional fix
-	for http://bugzilla.remotesensing.org/show_bug.cgi?id=110
-
-2002-03-25  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/: tif_getimage.c: Additional check for supported
-	codecs added in TIFFRGBAImageOK and TIFFReadRGBAImage now uses
-	TIFFRGBAImageOK before reading.
-	Closes http://bugzilla.remotesensing.org/show_bug.cgi?id=110
-
-2002-03-15  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/: tif_dir.c, tif_dir.h, tif_dirinfo.c, tif_dirread.c,
-	tif_dirwrite.c: Added routine TIFFDataWidth for detrmining
-	TIFFDataType sizes instead of working with tiffDataWidth array
-	directly. Should prevent out-of-borders bugs in case of unknown or
-	broken data types.  EstimateStripByteCounts routine modified, so it
-	won't work when tags with uknown sizes founded.
-	Closes http://bugzilla.remotesensing.org/show_bug.cgi?id=109
-
-2002-03-13  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/tif_getimage.c: Added support for correct handling
-	`Orientation' tag in gtTileContig. Should be added in other gt*
-	functions as well, but I have not images for testing yet. Partially
-	resolves http://bugzilla.remotesensing.org/show_bug.cgi?id=23
-
-2002-03-10  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/: tif_dirinfo.c, tif_dirwrite.c: Added possibility to
-	read broken TIFFs with LONG type used for TIFFTAG_COMPRESSION,
-	TIFFTAG_BITSPERSAMPLE, TIFFTAG_PHOTOMETRIC.  Closes
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=99
-
-2002-03-08  Andrey Kiselev  <dron at ak4719.spb.edu>
-
-	* libtiff/Makefile.in, tools/Makefile.in: Shared library will not
-	be stripped when installing, utility binaries will do.	Closes
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=93
-
-2002-02-28  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* man/TIFFGetField: fixed type of TIFFTAG_COPYRIGHT.
-
-	* man/libtiff.3t: added copyright tag info.
-
-2002-02-11  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/{tiff.h,tif_fax3.c}: Add support for __arch64__.
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=94
-
-	* man/Makefile.in: Patch DESTDIR handling 
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=95
-
-	* configure: OpenBSD changes for Sparc64 and DSO version.
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=96
-
-2002-02-05  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* config.site/configure: added support for OJPEG=yes option to enable
-	OJPEG support from config.site.
-
-2002-01-27  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* html/document.html: fixed links for TIFf 6 docs.
-
-2002-01-18  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* config.guess, config.sub: Updated from ftp.gnu.org/pub/config.
-
-	* libtiff/tif_read.c: Fixed TIFFReadEncodedStrip() to fail if the
-	decodestrip function returns anything not greater than zero as per
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=97
-
-	* configure: Modify CheckForBigEndian so it can work in a cross
-	compiled situation.
-
-2002-01-16  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* tools/tiffdump.c: include TIFFTAG_JPEGTABLES in tag list.
-
-	* tools/tiffset.c: fix bug in error reporting.
-
-	* tools/tiffcp.c: fix several warnings that show up with -Wall.
-
-2002-01-04  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_jpeg.c: fixed computation of segment_width for 
-	tiles files to avoid error about it not matching the 
-	cinfo.d.image_width values ("JPEGPreDecode: Improper JPEG strip/tile 
-	size.") for ITIFF files.  Apparently the problem was incorporated since
-	3.5.5, presumably during the OJPEG/JPEG work recently.
-
-2001-12-15  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* configure, libtiff/Makefile.in: Changes for building on MacOS 10.1.
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=94
-
-	* libtiff/tif_getimage.c: If DEFAULT_EXTRASAMPLE_AS_ALPHA is 1 
-	(defined in tiffconf.h - 1 by default) then the RGBA interface
-	will assume that a fourth extra sample is ASSOCALPHA if the
-	EXTRASAMPLE value isn't set for it.  This changes the behaviour of
-	the library, but makes it work better with RGBA files produced by
-	lots of applications that don't mark the alpha values properly.
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=93
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=65
-
-2001-12-12  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_jpeg.c: allow jpeg data stream sampling values to 
-	override those from tiff directory.  This makes this work with 
-	ImageGear generated files. 
-
-2001-12-07  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* html/Makefile.in: added missing images per bug 92.
-
-	* port/Makefile.in: fixed clean target per bug 92.
-
-2001-11-28  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* Reissue 3.5.7 release.
-
-	* libtiff/mkversion.c: Fix output of TIFF_VERSION to be
-	YYYYMMDD so that it is increasing over time. 
-
-	* Makefile.in: Ensure that tiffvers.h is regenerated in the
-	make release target.
-
-	* Makefile.in: added libtiff/tiffvers.h to the release file list.
-
-2001-11-23  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* added html/v3.5.7.html, updated html/index.html.
-
-	* Makefile.in: added contrib/addtiffo/tif_ovrcache.{c,h}.
-
-2001-11-15  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* configure: fixed test for -lm.
-
-2001-11-02  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* Added PHOTOMETRIC_ITULAB as per bug 90.
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=90
-
-2001-10-10  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tiff.h: I have created COMPRESSION_CCITT_T4, 
-	COMPRESSION_CCITT_T6, TIFFTAG_T4OPTIONS and TIFFTAG_T6OPTIONS aliases 
-	in keeping with TIFF 6.0 standard in tiff.h
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=83
-
-2001-09-26  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_dirwrite.c: added TIFFRewriteDirectory() function.
-	Updated TIFFWriteDirectory man page to include TIFFRewriteDirectory.
-
-2001-09-24  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_lzw.c: Avoid MS VC++ 5.0 optimization bug.
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=78
-
-	* libtiff/tif_lzw.c: added dummy LZWSetupEncode() to report an
-	error about LZW not being available.
-
-	* libtiff/tif_dir.c: propagate failure to initialize compression
-	back from TIFFSetField() as an error status, so applications can 
-	detect failure.
-
-	* libtiff/tif_dir.c: removed the auto replacement of 
-	COMPRESSION_LZW with COMPRESSION_NONE in _TIFFVSetField().
-
-	* Removed Makefile, tools/Makefile, port/install.sh, man/Makefile
-	from CVS as they are all supposed to be auto-generated by configure.
-
-2001-09-22  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_ojpeg.c: new update from Scott. 
-
-2001-09-09  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtif/tif_fax3.c: Removed #ifdef PURIFY logic, and modified to
-	always use the "safe" version, even if there is a very slight
-	cost in performance.
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=54
-
-	* libtiff/Makefile.in: Fixed @DSOSUB_VERSION to be @DSOSUF_VERSION@
-	in two places.
-
-	* libtiff/tif_getimage.c: Fixed problem with reading strips or
-	tiles that don't start on a tile boundary.  Fix contributed by
-	Josep Vallverdu (from HP), and further described in bug 47.
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=47
-
-	* tools/tiff2ps.c: added OJPEG YCbCr to RGB support. 
-
-	* libtiff/tif_ojpeg.c: Applied substantial patch from Scott.
-
-2001-09-06  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_packbits.c: fixed memory overrun error.
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=77
-	
-2001-08-31  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_getimage.c: relax handling of contig case where
-	there are extra samples that are supposed to be ignored.  This
-	should now work for 8bit greyscale or palletted images.  
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=75	
-
-2001-08-28  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_getimage.c: Don't complain for CMYK (separated)
-	images with more than four samples per pixel.  See:
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=73
-
-2001-08-10  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_getimage.c: Use memmove() instead of TIFFmemcpy()
-	in TIFFReadRGBATile() to avoid issues in cases of overlapping
-	buffers.  See Bug 69 in Bugzilla. 
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=69
-	
-	* tools/tiff2rgba.c: fixed getopt() call so that -b works again.
-
-2001-08-09  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tiff.h, libtiff/tif_fax3.c: added check for __LP64__ 
-	when checking for 64 bit architectures as per bugzilla bug 67.
-
-2001-07-27  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* man/Makefile.in: add TIFFClientOpen link as per debian submitted
-	bug 66.
-
-2001-07-20  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_jpeg.c: Define HAVE_BOOLEAN on windows if RPCNDR.H 
-	has been included.
-
-2001-07-19  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_open.c: Seek back to zero after failed read,
-	before writing header.
-
-2001-07-18  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_ojpeg.c: updates from Scott.  Handles colors
-	much better.  Now depends on having patched libjpeg as per
-	patch in contrib/ojpeg/*. 
-
-2001-07-17  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* */Makefile.in: added DESTDIR support. 
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=60
-
-2001-07-16  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* configure, libtiff/Makefile.in: applied OpenBSD patches
-	as per:
-	
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=61
-
-2001-06-28  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_getimage.c: Fixed so that failure is properly
-	reported by gtTileContig, gtStripContig, gtTileSeparate and 
-	gtStripSeparate.
-
-	See http://bugzilla.remotesensing.org/show_bug.cgi?id=51
-
-	* tiffcmp.c: Fixed multi samples per pixel support for ContigCompare.  
-	Updated bug section of tiffcmp.1 to note tiled file issues.
-	
-	See http://bugzilla.remotesensing.org/show_bug.cgi?id=53
-
-2001-06-22  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* configure: Changes for DSO generation on AIX provided by
-	John Marquart <jomarqua at indiana.edu>.
-
-	* configure, libtiff/Makeifle.in: Modified to build DSOs properly
-	on Darwin thanks to Robert Krajewski (rpk at alum.mit.edu) and
-	Keisuke Fujii (fujiik at jlcuxf.kek.jp).
-
-2001-06-13  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* tools/tiff2rgba.c: added -n flag to avoid emitting alpha component.
-
-	* man/tiff2rgba.1: new
-
-2001-05-22  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* Added tiffset and tif_ojpeg to the dist lists in Makefile.in.
-
-2001-05-13  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tools/thumbnail.c: changed default output compression
-	to packbits from LZW since LZW isn't generally available.
-
-2001-05-12  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_ojpeg.c: New.
-	libtiff/tif_jpeg.c, tiffconf.h, tif_getimage.c: changes related
-	to OJPEG support.
-
-	Scott Marovich <marovich at hpl.hp.com> supplied OJPEG support.
-
-2001-05-11  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* tiff.h: removed, it duplicates libtiff/tiff.h.
-
-2001-05-08  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_dirinfo.c: moved pixar and copyright flags to 
-	ensure everything is in order.
-
-	* libtiff/libtiff.def: added TIFFCreateDirectory and 
-	TIFFDefaultStripSize as per:
-
-	  http://bugzilla.remotesensing.org/show_bug.cgi?id=46
-
-2001-05-02  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_dirinfo.c: Modified the TIFF_BYTE definition for
-	TIFFTAG_PHOTOSHOP to use a writecount of TIFF_VARIABLE2 (-3) to
-	force use of uint32 counts instead of short counts. 
-
-	* libtiff/tif_dirwrite.c: Added support for TIFF_VARIABLE2 in the
-	case of writing TIFF_BYTE/TIFF_SBYTE fields.  
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=43
-
-2001-05-01  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_dirinfo.c: removed duplicate TIFFTAG_PHOTOSHOP as per
-	bug report http://bugzilla.remotesensing.org/show_bug.cgi?id=44
-
-2001-04-05  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* tiffio.h: removed C++ style comment.
-
-	* configure: fixed up SCRIPT_SH/SHELL handling.
-
-	* Makefile.in: Fixed SCRIPT_SH/SHELL handling.
-
-	* config.guess: documented more variables as per bug 40.
-
-2001-04-03  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* configure, *Makefile.in: Various changes to improve configuration
-	for HP/UX specifically, and also in general.  They include:
-	 - Try to handle /usr/bin/sh instead of /bin/sh where necessary.
-	 - Upgrade to HP/UX 10.x+ compiler, linker and dso options.
-	 - Fixed mmap() test to avoid MMAP_FIXED ... it isn't available on HP
-	 - Use -${MAKEFLAGS} in sub makes from makefiles.
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=40
-
-2001-04-02  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tiff.h: Applied hac to try and resolve the problem
-	with the inttypes.h include file on AIX.
-
-	See http://bugzilla.remotesensing.org/show_bug.cgi?id=39
-	
-	* VERSION: update to 3.5.7 beta in preparation for release.
-
-	* configure/config.site: modified to check if -lm is needed for
-	MACHDEPLIBS if not supplied by config.site.  Needed for Darwin.
-
-	* config.guess: updated wholesale to an FSF version apparently 
-	from 1998 (as opposed to 1994).  This is mainly inspired by 
-	providing for MacOS X support.
-
-2001-03-29  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* configure, Makefile.in, etc: added support for OPTIMIZER being
-	set from config.site. 
-
-2001-03-28  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* fax2ps.c: Helge (libtiff at oldach.net) submitted fix:
-
-	Here's a fix for fax2ps that corrects behaviour for non-Letter paper
-	sizes. It fixes two problems:
-
-	Without	scaling (-S) the fax is now centered on the page size specified
-	with -H	and/or -W. Before, fax2ps was using an obscure and practially
-	useless algorithm to allocate the image relative to Letter sized paper
-	which sometime sled to useless whitespace on the paper, while at the
-	same time cutting of the faxes printable area at the opposite border.
-
-	Second, scaling now preserves aspect ratio, which makes unusual faxes
-	(in particular short ones) print properly.
-
-	See http://bugzilla.remotesensing.org/show_bug.cgi?id=35
-	
-	* tiff2ps.c/tiff2ps.1: Substantial changes to tiff2ps by
-	Bruce A. Mallett.  See check message for detailed information
-	on all the changes, including a faster encoder, fixes for level
-	2 PostScript, and support for the imagemask operator.
-
-2001-03-27  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tiffio.h: Changed "#if LOGLUV_PUBLIC" to 
-	"#ifdef LOGLUV_PUBLIC" so it will work with VisualAge on AIX.
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=39
-
-2001-03-16  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* tif_dirinfo.c: moved definition of copyright tag in field list.
-	Apparently they have to be in sorted order by tag id.
-
-2001-03-13  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* tif_getimage.c: Added support for 16bit minisblack/miniswhite 
-	images in RGBA interface.
-
-2001-03-02  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* Added TIFFTAG_COPYRIGHT support.
-
-2001-02-19  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* Brent Roman contributed updated tiffcp utility (and tiffcp.1)
-	with support for extracting subimages with the ,n syntax, and also
-	adding the -b bias removal flag. 
-
-2001-02-16  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/libtiff.def: Brent Roman submitted new version adding
-	serveral missing entry points. 
-
-	* libtiff/tif_dirinfo.c: don't declare tiffFieldInfo static on VMS.
-	Some sort of weird VMS thing.  
-
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=31
-
-	* tif_luv.c/tiff.h/tiffio.h: 
-	New version of TIFF LogLuv (SGILOG) modules contributed by Greg Ward 
-	(greg at shutterfly.com).  He writes:
-
-	1) I improved the gamut-mapping function in tif_luv.c for imaginary
-	colors, because some images were being super-saturated on the input 
-	side and this resulted in some strange color shifts in the output.
-
-	2) I added a psuedotag in tiff.h to control random dithering during
-	LogLuv encoding.  This is turned off by default for 32-bit LogLuv and 
-	on for 24-bit LogLuv output.  Dithering improves the average color 
-	accuracy over the image.
-
-	3) I added a #define for LOG_LUV_PUBLIC, which is enabled by default in
-	tiffio.h, to expose internal routines for converting between LogLuv and
-	XYZ coordinates.  This is helpful for writing more efficient,
-	specialized conversion routines, especially for reading LogLuv files.
-
-	Changes applied with minor edits.
-
-2001-01-23  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* tif_fax3.c: keep rw_mode flag internal to fax3 state to remember
-	whether we are encoding or decoding.  This is to ensure graceful 
-	recovery if TIFFClientOpen() discovers an attempt to open a compressed
-	file for "r+" access, and subsequently close it, as it resets the 
-	tif_mode flag to O_RDONLY in this case to avoid writes, confusing the
-	compressor's concept of whether it is in encode or decode mode.
-
-2001-01-08  Mike Welles <mike at bangstate.com> 
-
-	* Makefile.in:  Now cleaning up after itself after creating the .tar.gz and .zip
-	
-2001-01-07  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* html/libtiff.html: Fixed arguments in example for TIFFRGBAImageGet()
-	as per bug report by Patrick Connor. 
-
-2000-12-28  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* Added RELEASE-DATE file to release file list.
-
-	* Fixed libtiff/makefile.vc to make tiffvers.h not version.h.
-
-2000-12-22  Mike Welles <mike at bangstate.com> 
-        * added link to CVS mirror from index.html
-	
-	* updated html/internals.html to note that LZW compression is 
-	  not supported by default. 
-	
-2000-12-22  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* updated html/libtiff.html to not point at Niles' old JPL web site
-	for the man pages, point at www.libtiff.org.
-
-2000-12-21  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/tif_apple.c: Applied "Carbon" support patches supplied by
-	Leonard Rosenthol <leonardr at lazerware.com>.  May interfere
-	with correct building on older systems.  If so, please let me know.
-
-2000-12-19 Mike Welles <mike at bangsate.com>   
-
-	* Took out LZW Encoding from tif_lzw.c 
-
-	* Created HOWTO-RELEASE
-
-	* Created html/v3.5.6.html
-
-	* updated index.html
-	
-2000-12-01  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* Added patches for EOFB support in tif_fax3.c and tif_fax3.h. 
-	Patches supplied by Frank Cringle <fdc at cliwe.ping.de>
-	Example file at: ftp://ftp.remotesensing.org/pub/libtiff/eofb_396.tif
-
-2000-11-24  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* libtiff/Makefile.in: Added an installPrivateHdrs and install-private
-	target so that the private headers required by libgeotiff can be
-	installed with the others.  They are not installed by default.
-
-	* libtiff/Makefile.in: Added @MACHLIBDEPS@ to LINUXdso and GNULDdso
-	targets so libtiff.so will be built with an explicit dependency
-	on libm.so.
-
-	* libtiff/Makefile.in: Use softlinks to link libtiff.so.3 to 
-	libtiff.so.3.5.5.  
-
-	* libtiff/Makefile.in & configure: Remove all references to the ALPHA 
-	file, or ALPHA version logic.  Added stuff about DIST_POINT in 
-	place of DIST_TYPE and the alpha release number stuff.
-
-2000-11-22  Frank Warmerdam  <warmerdam at pobox.com>
-
-	* I have applied a patch from Steffen Moeller <moeller at ebi.ac.uk> to
-	the configure script so that it now accepts the --prefix, and 
-	--exec-prefix directives. 
-
-2000-11-13  Frank Warmerdam  <warmerda at cs46980-c>
-
-	* I have made a variety of modifications in an effort to ensure the 
-	TIFFLIB_VERSION macro is automatically generated from the RELEASE-DATE
-	file which seems to be updated regularly.  
-
-	 o mkversion.c now reads RELEASE-DATE and emits TIFFLIB_VERSION in 
-	   version include file. 
-	 o renamed version.h to tiffvers.h because we now have to install it 
-	   with the public libtiff include files.  
-	 o include tiffvers.h in tiffio.h. 
-	 o updated tif_version.c to use tiffvers.h.
-	 o Updated Makefile.in accordingly.
-
-	* As per http://bugzilla.remotesensing.org/show_bug.cgi?id=25
-	I have updated the win32 detection rules in tiffcomp.h.
-
-2000-10-20  Frank Warmerdam  <warmerda at cs46980-c>
-
-	* tif_getimage.c: Fixed RGBA translation for YCbCr images for which
-	the strip/tile width and height aren't multiples of the sampling size.
-	See http://bugzilla.remotesensing.org/show_bug.cgi?id=20
-	Some patches from Rick LaMont of Dot C Software.
-
-	* Modified tif_packbits.c encoder to avoid compressing more 
-	data than provided if rowsize doesn't factor into provided data
-	(such as occurs for YCbCr).
-
-2000-10-19  Frank Warmerdam  <warmerda at cs46980-c>
-
-	* tools/rgb2ycbcr.c: fixed output strip size to account for vertical 
-	roundup if rows_per_strip not a multiple of vertical sample size.
-
-2000-10-16  Frank Warmerdam  <warmerda at cs46980-c>
-
-	* tif_dir.c: Clear TIFF_ISTILED flag in TIFFDefaultDirectory
-	as per http://bugzilla.remotesensing.org/show_bug.cgi?id=18
-	from vandrove at vc.cvut.cz.
-
-	* Modified tif_packbits.c decoding to avoid overrunning the
-	output buffer, and to issue a warning if data needs to be
-	discarded.  See http://bugzilla.remotesensing.org/show_bug.cgi?id=18
-
-2000-10-12  Frank Warmerdam  <warmerda at cs46980-c>
-
-	* Modified tiff2bw to ensure portions add to 100%, and that
-	white is properly recovered. 
-	
-	See bug http://bugzilla.remotesensing.org/show_bug.cgi?id=15
-	Patch c/o Stanislav Brabec <utx at penguin.cz>
-
-2000-09-30  Frank Warmerdam  <warmerda at cs46980-c>
-
-	* Modified TIFFClientOpen() to emit an error on an attempt to
-	open a comperessed file for update (O_RDWR/r+) access.  This is
-	because the compressor/decompressor code gets very confused when
-	the mode is O_RDWR, assuming this means writing only.  See
-	bug http://bugzilla.remotesensing.org/show_bug.cgi?id=13
-
-2000-09-27  Frank Warmerdam  <warmerda at cs46980-c>
-
-	* Added GNULDdso target an`d switched linux and freebsd to use it. 
-
-2000-09-26  Frank Warmerdam  <warmerda at cs46980-c>
-
-	* Applied patch for 0x0000 sequences in tif_fax3.h's definition
-	of EXPAND1D() as per bug 11 (from Roman). 
-
-2000-09-25  Frank Warmerdam  <warmerda at cs46980-c>
-	* Fixed tiffcomp.h to avoid win32 stuff if unix #defined, to improve
-	cygwin compatibility.
-
-	* Applied patch from Roman Shpount to tif_fax3.c.  This seems to
-	be a proper fix to the buffer sizing problem.  See 
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=11
-
-	* Fixed tif_getimage.c to fix overrun bug with YCbCr images without
-	downsampling.  http://bugzilla.remotesensing.org/show_bug.cgi?id=10
-	Thanks to Nick Lamb <njl98r at ecs.soton.ac.uk> for reporting the
-	bug and proving the patch.
-	
-2000-09-18  Frank Warmerdam  <warmerda at cs46980-c>
-
-	* Fixed tif_jpeg.c so avoid destroying the decompressor before
-	we are done access data thanks to bug report from:
-	Michael Eckstein <eckstein at gepro.cz>.
-
-	* Reverted tif_flush change.
-
-2000-09-14  Frank Warmerdam  <warmerda at cs46980-c>
-
-	* tif_flush.c: Changed so that TIFFFlushData() doesn't return an
-	error when TIFF_BEENWRITING is not set.  This ensures that the
-	directory contents can still be flushed by TIFFFlush().
-
-2000-08-14  Frank Warmerdam  <warmerda at rommel.atlsci.com>
-
-	* tif_open.c: Don't set MMAP for O_RDWR files.
-
-	* tif_open.c: Set STRIPCHOP_DEFAULT for O_RDWR as well as O_RDONLY
-	so that files opened for update can be strip chopped too.
-
-	* tif_read.c: fixed up bug with files missing rowsperstrip and
-	the strips per separation fix done a few weeks ago.
-
-2000-07-17  Frank Warmerdam  <warmerda at cs46980-c>
-
-	* Tentatively added support for SAMPLEFORMAT_COMPLEXIEEEFP, and
-	SAMPLEFORMAT_COMPLEXINT.
-
-2000-07-13  Mike Welles <mike at onshore.com> 
-
-	* index.html, bugs.html: added bugzilla info. 
-	
-2000-07-12  Frank Warmerdam  <warmerda at rommel.atlsci.com>
-
-	* tif_read.c: fix subtle bug with determining the number of
-	rows for strips that are the last strip in a separation but
-	not the last strip of all in TIFFReadEncodedStrip().  
-
-	* Applied 16/32 bit fix to tif_fax3.c.  Fix supplied by
-	Peter Skarpetis <peters at serendipity-software.com.au>
-
-2000-06-15  Frank Warmerdam  <warmerda at rommel.atlsci.com>
-
-	* Modified tiffio.h logic with regard to including windows.h.  It
-	won't include it when building with __CYGWIN__.
-
-2000-05-11  Frank Warmerdam  <warmerda at cs46980-c>
-
-	* README: update to mention www.libtiff.org, don't list Sam's old
-	email address.
-
-	* configure: Fixed DSO test for Linux as per patch from
-	  Jan Van Buggenhout <chipzz at Ace.ULYSSIS.Student.KULeuven.Ac.Be>.
-
-2000-04-21  Frank Warmerdam  <warmerda at rommel.atlsci.com>
-
-	* libtiff/tif_dirread.c: Don't use estimate strip byte count for
-	one tile/strip images with an offset, and byte count of zero. These
-	could be "unpopulated" images. 
-
-2000-04-18  Frank Warmerdam  <warmerda at rommel.atlsci.com>
-
-	* contrib/addtiffo: Added "averaging" resampling option.
-
-	* tools/tiffsplit.c: Copy TIFFTAG_SAMPLEFORMAT.
-
-Tue Apr 18 16:18:08 2000  Frank Warmerdam  <warmerda at esabot.atlsci.com>
-
-	* tools/Makefile.in: Modified to install properly on SGI.
-
-2000-04-12  Mike Welles	     <mike at onshore.com>
-	* configure:  Fixed stupid mistake in libc6 test on Linux
-
-2000-04-04  Mike Welles	     <mike at onshore.com> 
-	* tif_win32.c:  Applied patch to fix overreads and ovverwrites
-	  caught by BoundsChecker.  From Arvan Pritchard 
-	  <arvan.pritchard at infomatix.co.uk>  (untested). 
-	
-	* tif_getimage.c:  Applied patch to silence VC6 warnings.  From 
-	  Arvan Pritchard <arvan.pritchard at informatix.co.uk>
-	
-	* tif_lzw.c:  Applied patch to silence VC6 warnings.  From 
-	  Arvan Pritchard <arvan.pritchard at informatix.co.uk>
-	
-2000-03-28  Frank Warmerdam  <warmerda at cs46980-c>
-
-	* Added contrib/stream (stream io) code submitted by Avi Bleiweiss.
-
-2000-03-28  Frank Warmerdam  <warmerda at cs46980-c>    *** 3.5.5 release ***
-
-	* fax2ps: Fixed mixup of width and height in bounding box statement
-	as per submission by Nalin Dahyabhai <nalin at redhat.com>.
-
-2000-03-27  Mike Welles	     <mike at onshore.com> 
-
-	* fax2ps:  Modified printruns to take uint32 instead of uint16.  
-	Patch courtesy of Bernt Herd <herd at herdsoft.com> 
-	
-2000-03-20  Mike Welles	     <mike at onshore.com> 
-
-	* configure: added test for libc6 for linux targets.  Bug reported by 
-        Stanislav Brabec <utx at k332.feld.cvut.cz>
-
-	* Added 3.5 docs to html/Makefile.in.  
-	Thanks to  Stanislav Brabec <utx at k332.feld.cvut.cz>
-
-	* configure: fixed bugs in sed scripts 
-	(applied sed script s:/@:s;@:;s:/s;;:;: to configure). 
-	fix submitted to Stanislav Brabec <utx at k332.feld.cvut.cz>
-
-	* tools/iptcutil was not in files list, and wasn't being 
-	added to tar archive.  Updated Makefile.in.
-
-2000-03-17  Frank Warmerdam  <warmerda at cs46980-c>
-
-	* tif_fax3.c: Fixed serious bug introduced during the uint16->uint32
-	conversion for the run arrays.  
-
-2000-03-03  Frank Warmerdam  <warmerda at cs46980-c.mtnk1.on.wave.home.com>
-
-	* Set td_sampleformat default to SAMPLEFORMAT_UINT instead of 
-	SAMPLEFORMAT_VOID in TIFFDefaultDirectory() in tif_dir.c.
-
-2000-03-02  Frank Warmerdam  <warmerda at cs46980-c.mtnk1.on.wave.home.com>
-
-	* Added "GetDefaulted" support for TIFFTAG_SAMPLEFORMAT in tif_aux.c.
-
-	* Patched tif_fax3.c so that dsp->runs is allocated a bit bigger
-	to avoid overruns encountered with frle_bug.tif.
-
-Tue Feb 15 22:01:05 2000  Frank Warmerdam  <warmerda at gdal.velocet.ca>
-
-	* Fixed tools/tiffcmp so that stopondiff testing works.
-	  Patch care of Joseph Orost <joe at sanskrit.lz.att.com>.
-
-2000-01-28    <warmerda at CS46980-B>
-
-	* Modified tif_unix.c to support 2-4GB seeks if USE_64BIT_API is
-	  set to 1, and added default (off) setting in tiffconf.h.  This
-	  should eventually be set by the configure script somehow.
-
-	  The original work on all these 2-4GB changes was done by 
-	  Peter Smith (psmith at creo.com).
-
-	* Modified tif_win32.c to support 2-4GB seeks.
-
-	* tentatively changed toff_t to be unsigned instead of signed to
-	  facilitate support for 2-4GB files. 
-
-	* Updated a variety of files to use toff_t.  Fixed some mixups
-	  between toff_t and tsize_t.
-
-Fri Jan 28 10:13:49 2000  Frank Warmerdam  <warmerda at gdal.velocet.ca>
-
-	* Largely reimplemented contrib/addtiffo to avoid temp files, 
-	updating the TIFF file in place.  Fixed a few other bugs to.
-
-	* Set tif_rawdatasize to zero when freeing raw data buffer in
-	TIFFWriteDirectory().
-
-	* Enabled "REWRITE_HACK" in tif_write.c by default.
-
-	* Fix bug in tif_write.c when switching between reading one directory
-	and writing to another. 
-
-	* Made TIFFWriteCheck() public, and added TIFFCreateDirectory()
-
-Wed Jan  5 12:37:48 2000  Frank Warmerdam  <warmerda at gdal.velocet.ca>
-
-	* Added TIFFmemory(3t) functions to libtiff.def.
-
-Tue Jan  4 13:39:00 2000  Frank Warmerdam  <warmerda at gdal.velocet.ca>
-
-	* Added libtiff/libtiff.def to TIFFILES distribution list.
-
-Mon Dec 27 12:13:39 EST 1999  Mike Welles <mike at onshore.com> 
-
-	* Created lzw compression kit, as a new module (libtiff-lzw-compression-kit). 
-
-	* Altered descriptions in tools to reflect "by default" lzw not supported
-
-	* Updated index.html to note lzw compression kit. 
-	
-Tue Dec 21 14:01:51 1999  Frank Warmerdam  <warmerda at gdal.velocet.ca>
-
-	* Added fax3sm_winnt.c to distribution list in Makefile.in. 
-
-Tue Dec 21 11:04:45 EST 1999  Mike Welles <mike at onshore.com> *** 3.5.4 release ***
-	
-	* Aadded Pixar tag support.  Contributed by Phil Beffery <phil at pixar.com> 
-
-	* Made one more change to tif_dir.c for removal of LZW compression. Also added notice 
-	  when LZW compression invoked. 
-
-	* Changed default compression in tools to TIFF_PACKBITS, and changed usage descriptions
-	  in tools to reflect removal of LZW compression
-	  
-Mon Dec 20 18:39:02 EST 1999  Mike Welles  <mike at onshore.com>
-
-        * Fixed bug that caused LZW (non) compression to segfault. Added 
-	  warning about LZW compression removed being removed, and why. 
-
-	* Added nostrip to install in tools/Makefile.in so that debugging 
-	  symbols are kept. 
-	
-Tue Dec  7 12:04:47 EST 1999  Mike Welles  <mike at onshore.com>
-
-	* Added patch from Ivo Penzar <ivo.penzar at infolink-software.com>, 
-	  supporting Adobe ZIP deflate.  Untested. 
-	
-Sat Dec  4 15:47:11 1999  Frank Warmerdam  <warmerda at gdal.velocet.ca>
-
-	* Made Packbits the default compression in tools/tiff2rgba.c instead
-	of LZW.
-
-Tue Nov 30 14:41:43 1999  Frank Warmerdam  <warmerda at gdal.velocet.ca>    *** 3.5.3. release ***
-
-	* Added tif_luv to contrib/djgpp/Makefile.lib.
-
-Tue Nov 30 14:15:32 EST 1999   Mike Welles <mike at onshore.com> 
-
-        * Added zip creation to relase makefile target 
-
-	* Added html for TIFFWriteTile.3t man page. 
-	
-Tue Nov 30 09:20:16 1999  Frank Warmerdam  <warmerda at gdal.velocet.ca>
-
-	* Added some changes to tif_write.c to support rewriting existing
-	fixed sized tiles and strips.  Code mods disabled by default, only
-	enabled if REWRITE_HACK is defined for now.
-
-Mon Nov 29 11:43:42 1999  Frank Warmerdam  <warmerda at gdal.velocet.ca>
-
-	* Added TIFFWriteTile.3t man page.
-
-Sun Nov 28 20:36:18 1999  Frank Warmerdam  <warmerda at gdal.velocet.ca>
-
-	* Added notes on use of makefile.vc in build.html, and fixed 
-	email subscription address.
-
-199-11-28  Mike Welles <mike at onshore.com> 
-
-	*  Fixed apocalypse-inducing y2k bug in contrib/ras/ras2tiff.c 
-
-	*  Did some casts cleaning up to reduce compiler warnings in tif_fax3.c,
-	   from Bruce Carmeron <cameron at petris.com> -- modifications of 
-	   changes made by Frank (sun cc still complained on cast). 
-
-	*  Added tiffconf.h to install target per request from Bill
-	   Radcliffe <billr at corbis.com>: "We need a way for ImageMagick to
- 	   know features have been compiled into the TIFF library in order to
-	   handle things properly".  
-	
-Sat Nov 27 16:49:21 1999  Frank Warmerdam  <warmerda at gdal.velocet.ca>
-
-	* fixed various VC++ warnings as suggested by Gilles Vollant
-	<info at winimage.com>.  
-
-Wed Nov 24 12:08:16 1999  Frank Warmerdam  <warmerda at gdal.velocet.ca>
-
-	* Modified TIFFquery.3t man pages info on TIFFIsByteSwapped() to
-	not imply applications are responsible for image data swapping.
-
-1999-11-22  Mike Welles <mike at onshore.com>
-	*  HTML-ized the man pages, added to html/man
-	
-	*  Removed LZW Compression to comply with Unisys patent extortion. 
-	
-1999-09-29  Mike Welles		<mike at onshore.com> 
-	*  Corrected one remaining 16 -> 32 bit value in tif_fax3.c, 
-	   From Ivo Penzar <ivo.penzar at infolink-software.com. 
-
-	*  Added patch from Ivo Penzar to have TiffAdvanceDirectory handle
-	   memory mapped files. <ivo.penzar at infolink-software.com>
-	
-1999-09-26  Mike Welles 	<mike at onshore.com>  *** 3.5.2 release ***
-	* Corrected alpha versioning.  
-
-	* Removed distinction between  alpha and release targets in Makefile.in. 
-
-	* added release.stamp target, which tags cvs tree, and updates 
-	  "RELEASE-DATE"
-
-	* added releasediff target, which diffs tree with source as of 
-	  date in "RELEASE-DATE"
-	  
-	* Ticked up version to 3.5.2 (alpha 01 -- but I think we'll moving 
-	  away from alpha/non-alpha distinctions). 
-
-	* updated html to reflect release 
-	
-1999-09-23    <warmerda at CS46980-B>
-
-	* Set O_BINARY for tif_unix.c open() ... used on cygwin for instance.
-
-	* Added CYGWIN case in configure.
-
-Fri Sep 17 00:13:51 CEST 1999  Mike Welles <mike at onshore.com> 
-
-	* Applied Francois Dagand's patch to handle fax decompression bug. 
-	  (sizes >= 65536 were failing) 
-	
-Tue Sep 14 21:31:43 1999  Frank Warmerdam  <warmerda at gdal.velocet.ca>
-
-	* Applied "a" mode fix to tif_win32.c/TIFFOpen() as suggested 
-	  by Christopher Lawton <clawton at mathworks.com>
-
-Wed Sep  8 08:19:18 1999  Frank Warmerdam  <warmerda at gdal.velocet.ca>
-
-	* Added IRIX/gcc, and OSF/1 4.x support on behalf of 
-	  Albert Chin-A-Young <china at thewrittenword.com>
-
-	* Added TIFFReassignTagToIgnore() API on behalf of 
-	  Bruce Cameron <cameron at petris.com>.  Man page still pending.
-
-Wed Aug 25 11:39:07 1999  Frank Warmerdam  <warmerda at gdal.velocet.ca>
-
-	* Added test target in Makefile, test_pics.sh script and pics/*.rpt 
-	files to provide for a rudimentary testsuite.
-
-	* Added contrib/tags back from old distribution ... fixed up a bit.
-
-1999-08-16    <warmerda at CS46980-B>
-
-	* Added simple makefile.vc makefiles for building with MS VC++
-	on Windows NT/98/95 in console mode.  Stuff in contrib/win* make give 
-	better solutions for some users.
-
-Mon Aug 16 21:52:11 1999  Frank Warmerdam  <warmerda at gdal.velocet.ca>
-
-	* Added addtiffo (add overviews to a TIFF file) in contrib.  Didn't
-	put it in tools since part of it is in C++.
-
-1999-08-16  Michael L. Welles  <mike at kurtz.fake>
-
-	* Updated html/index.html with anon CVS instructions. 
-
-Mon Aug 16 13:18:41 1999  Frank Warmerdam  <warmerda at gdal.velocet.ca>
-
-	* pre-remove so link before softlink in LINUXdso action in 
-	libtiff/Makefile.in to avoid failure on LINUXdso builds other than
-	the first.
-
-	* Fixed problem with cvtcmap() in tif_getimage.c modifying the
-	colormaps owned by the TIFF handle itself when trying to fixup wrong
-	(eight bit) colormaps.  Corrected by maintaining a private copy of
-	the colormap. 
-
-	* Added TIFFReadRGBATile()/TIFFReadRGBAStrip() support in 
-	tif_getimage.c.
-
-	* CVS Repository placed at remotesensing.org.  ChangeLog added.
diff --git a/Source/LibTIFF/LibTIFF.2003.vcproj b/Source/LibTIFF/LibTIFF.2003.vcproj
deleted file mode 100644
index 576c713..0000000
--- a/Source/LibTIFF/LibTIFF.2003.vcproj
+++ /dev/null
@@ -1,272 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="7.10"
-	Name="LibTIFF"
-	SccProjectName=""$/FreeImage/LibTIFF", MKAAAAAA"
-	SccLocalPath=".">
-	<Platforms>
-		<Platform
-			Name="Win32"/>
-	</Platforms>
-	<Configurations>
-		<Configuration
-			Name="Release|Win32"
-			OutputDirectory=".\Release"
-			IntermediateDirectory=".\Release"
-			ConfigurationType="4"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="FALSE"
-			CharacterSet="2">
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="2"
-				GlobalOptimizations="TRUE"
-				InlineFunctionExpansion="2"
-				EnableIntrinsicFunctions="TRUE"
-				FavorSizeOrSpeed="1"
-				OmitFramePointers="TRUE"
-				OptimizeForProcessor="3"
-				AdditionalIncludeDirectories="..\libtiff\libtiff,..\zlib"
-				PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
-				StringPooling="TRUE"
-				RuntimeLibrary="0"
-				BufferSecurityCheck="FALSE"
-				UsePrecompiledHeader="2"
-				PrecompiledHeaderFile=".\Release/LibTIFF.pch"
-				AssemblerListingLocation=".\Release/"
-				ObjectFile=".\Release/"
-				ProgramDataBaseFileName=".\Release/"
-				WarningLevel="3"
-				SuppressStartupBanner="TRUE"
-				CompileAs="0"/>
-			<Tool
-				Name="VCCustomBuildTool"/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile=".\Release\LibTIFF.lib"
-				SuppressStartupBanner="TRUE"/>
-			<Tool
-				Name="VCMIDLTool"/>
-			<Tool
-				Name="VCPostBuildEventTool"/>
-			<Tool
-				Name="VCPreBuildEventTool"/>
-			<Tool
-				Name="VCPreLinkEventTool"/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="1033"/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"/>
-			<Tool
-				Name="VCManagedWrapperGeneratorTool"/>
-			<Tool
-				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
-		</Configuration>
-		<Configuration
-			Name="Debug|Win32"
-			OutputDirectory=".\Debug"
-			IntermediateDirectory=".\Debug"
-			ConfigurationType="4"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="FALSE"
-			CharacterSet="2">
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="0"
-				AdditionalIncludeDirectories="..\libtiff\libtiff"
-				PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
-				StringPooling="TRUE"
-				BasicRuntimeChecks="3"
-				RuntimeLibrary="1"
-				UsePrecompiledHeader="2"
-				PrecompiledHeaderFile=".\Debug/LibTIFF.pch"
-				AssemblerListingLocation=".\Debug/"
-				ObjectFile=".\Debug/"
-				ProgramDataBaseFileName=".\Debug/"
-				WarningLevel="3"
-				SuppressStartupBanner="TRUE"
-				DebugInformationFormat="4"
-				CompileAs="0"/>
-			<Tool
-				Name="VCCustomBuildTool"/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile=".\Debug\LibTIFF.lib"
-				SuppressStartupBanner="TRUE"/>
-			<Tool
-				Name="VCMIDLTool"/>
-			<Tool
-				Name="VCPostBuildEventTool"/>
-			<Tool
-				Name="VCPreBuildEventTool"/>
-			<Tool
-				Name="VCPreLinkEventTool"/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="_DEBUG"
-				Culture="1033"/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"/>
-			<Tool
-				Name="VCManagedWrapperGeneratorTool"/>
-			<Tool
-				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Source Files"
-			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
-			<File
-				RelativePath="tif_aux.c">
-			</File>
-			<File
-				RelativePath="tif_close.c">
-			</File>
-			<File
-				RelativePath="tif_codec.c">
-			</File>
-			<File
-				RelativePath="tif_color.c">
-			</File>
-			<File
-				RelativePath="tif_compress.c">
-			</File>
-			<File
-				RelativePath="tif_dir.c">
-			</File>
-			<File
-				RelativePath="tif_dirinfo.c">
-			</File>
-			<File
-				RelativePath="tif_dirread.c">
-			</File>
-			<File
-				RelativePath="tif_dirwrite.c">
-			</File>
-			<File
-				RelativePath="tif_dumpmode.c">
-			</File>
-			<File
-				RelativePath="tif_error.c">
-			</File>
-			<File
-				RelativePath="tif_extension.c">
-			</File>
-			<File
-				RelativePath="tif_fax3.c">
-			</File>
-			<File
-				RelativePath="tif_fax3sm.c">
-			</File>
-			<File
-				RelativePath="tif_flush.c">
-			</File>
-			<File
-				RelativePath="tif_getimage.c">
-			</File>
-			<File
-				RelativePath="tif_jpeg.c">
-			</File>
-			<File
-				RelativePath="tif_luv.c">
-			</File>
-			<File
-				RelativePath="tif_lzw.c">
-			</File>
-			<File
-				RelativePath="tif_next.c">
-			</File>
-			<File
-				RelativePath=".\tif_ojpeg.c">
-			</File>
-			<File
-				RelativePath="tif_open.c">
-			</File>
-			<File
-				RelativePath="tif_packbits.c">
-			</File>
-			<File
-				RelativePath="tif_pixarlog.c">
-			</File>
-			<File
-				RelativePath="tif_predict.c">
-			</File>
-			<File
-				RelativePath="tif_print.c">
-			</File>
-			<File
-				RelativePath="tif_read.c">
-			</File>
-			<File
-				RelativePath="tif_strip.c">
-			</File>
-			<File
-				RelativePath="tif_swab.c">
-			</File>
-			<File
-				RelativePath="tif_thunder.c">
-			</File>
-			<File
-				RelativePath="tif_tile.c">
-			</File>
-			<File
-				RelativePath="tif_version.c">
-			</File>
-			<File
-				RelativePath="tif_warning.c">
-			</File>
-			<File
-				RelativePath="tif_write.c">
-			</File>
-			<File
-				RelativePath="tif_zip.c">
-			</File>
-		</Filter>
-		<Filter
-			Name="Header Files"
-			Filter="h;hpp;hxx;hm;inl">
-			<File
-				RelativePath="t4.h">
-			</File>
-			<File
-				RelativePath="tif_config.h">
-			</File>
-			<File
-				RelativePath="tif_dir.h">
-			</File>
-			<File
-				RelativePath="tif_fax3.h">
-			</File>
-			<File
-				RelativePath="tif_predict.h">
-			</File>
-			<File
-				RelativePath="tiff.h">
-			</File>
-			<File
-				RelativePath="tiffio.h">
-			</File>
-			<File
-				RelativePath="tiffiop.h">
-			</File>
-			<File
-				RelativePath="tiffvers.h">
-			</File>
-			<File
-				RelativePath="uvcode.h">
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
diff --git a/Source/LibTIFF/LibTIFF.2005.vcproj b/Source/LibTIFF/LibTIFF.2005.vcproj
deleted file mode 100644
index 7fc5c1c..0000000
--- a/Source/LibTIFF/LibTIFF.2005.vcproj
+++ /dev/null
@@ -1,525 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="8,00"
-	Name="LibTIFF"
-	ProjectGUID="{431E3F3F-7C4D-430A-B8F1-4F165DB64EDC}"
-	RootNamespace="LibTIFF"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-		<Platform
-			Name="x64"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Release|Win32"
-			OutputDirectory=".\Release"
-			IntermediateDirectory=".\Release"
-			ConfigurationType="4"
-			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="2"
-				InlineFunctionExpansion="2"
-				EnableIntrinsicFunctions="true"
-				FavorSizeOrSpeed="1"
-				OmitFramePointers="true"
-				AdditionalIncludeDirectories="..\libtiff\libtiff,..\zlib"
-				PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE"
-				StringPooling="true"
-				RuntimeLibrary="0"
-				BufferSecurityCheck="false"
-				UsePrecompiledHeader="0"
-				PrecompiledHeaderFile=".\Release/LibTIFF.pch"
-				AssemblerListingLocation=".\Release/"
-				ObjectFile=".\Release/"
-				ProgramDataBaseFileName=".\Release/"
-				WarningLevel="3"
-				SuppressStartupBanner="true"
-				CompileAs="0"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="1033"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile=".\Release\LibTIFF.lib"
-				SuppressStartupBanner="true"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|Win32"
-			OutputDirectory=".\Debug"
-			IntermediateDirectory=".\Debug"
-			ConfigurationType="4"
-			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="0"
-				AdditionalIncludeDirectories="..\libtiff\libtiff"
-				PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE"
-				StringPooling="true"
-				BasicRuntimeChecks="3"
-				RuntimeLibrary="1"
-				UsePrecompiledHeader="0"
-				PrecompiledHeaderFile=".\Debug/LibTIFF.pch"
-				AssemblerListingLocation=".\Debug/"
-				ObjectFile=".\Debug/"
-				ProgramDataBaseFileName=".\Debug/"
-				WarningLevel="3"
-				SuppressStartupBanner="true"
-				DebugInformationFormat="4"
-				CompileAs="0"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="_DEBUG"
-				Culture="1033"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile=".\Debug\LibTIFF.lib"
-				SuppressStartupBanner="true"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|x64"
-			OutputDirectory="$(PlatformName)\$(ConfigurationName)"
-			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
-			ConfigurationType="4"
-			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="2"
-				InlineFunctionExpansion="2"
-				EnableIntrinsicFunctions="true"
-				FavorSizeOrSpeed="1"
-				OmitFramePointers="true"
-				AdditionalIncludeDirectories="..\libtiff\libtiff,..\zlib"
-				PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE"
-				StringPooling="true"
-				RuntimeLibrary="0"
-				BufferSecurityCheck="false"
-				UsePrecompiledHeader="0"
-				PrecompiledHeaderFile=".\Release/LibTIFF.pch"
-				AssemblerListingLocation=".\Release/"
-				ObjectFile=".\Release/"
-				ProgramDataBaseFileName=".\Release/"
-				WarningLevel="3"
-				SuppressStartupBanner="true"
-				CompileAs="0"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="1033"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile=".\Release\LibTIFF.lib"
-				SuppressStartupBanner="true"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|x64"
-			OutputDirectory="$(PlatformName)\$(ConfigurationName)"
-			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
-			ConfigurationType="4"
-			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="0"
-				AdditionalIncludeDirectories="..\libtiff\libtiff"
-				PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE"
-				StringPooling="true"
-				BasicRuntimeChecks="3"
-				RuntimeLibrary="1"
-				UsePrecompiledHeader="0"
-				PrecompiledHeaderFile=".\Debug/LibTIFF.pch"
-				AssemblerListingLocation=".\Debug/"
-				ObjectFile=".\Debug/"
-				ProgramDataBaseFileName=".\Debug/"
-				WarningLevel="3"
-				SuppressStartupBanner="true"
-				DebugInformationFormat="3"
-				CompileAs="0"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="_DEBUG"
-				Culture="1033"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile=".\Debug\LibTIFF.lib"
-				SuppressStartupBanner="true"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Source Files"
-			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-			>
-			<File
-				RelativePath="tif_aux.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_close.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_codec.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_color.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_compress.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_dir.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_dirinfo.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_dirread.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_dirwrite.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_dumpmode.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_error.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_extension.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_fax3.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_fax3sm.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_flush.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_getimage.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_jpeg.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_luv.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_lzw.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_next.c"
-				>
-			</File>
-			<File
-				RelativePath=".\tif_ojpeg.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_open.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_packbits.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_pixarlog.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_predict.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_print.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_read.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_strip.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_swab.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_thunder.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_tile.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_version.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_warning.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_write.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_zip.c"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="Header Files"
-			Filter="h;hpp;hxx;hm;inl"
-			>
-			<File
-				RelativePath="t4.h"
-				>
-			</File>
-			<File
-				RelativePath="tif_config.h"
-				>
-			</File>
-			<File
-				RelativePath="tif_dir.h"
-				>
-			</File>
-			<File
-				RelativePath="tif_fax3.h"
-				>
-			</File>
-			<File
-				RelativePath="tif_predict.h"
-				>
-			</File>
-			<File
-				RelativePath="tiff.h"
-				>
-			</File>
-			<File
-				RelativePath="tiffio.h"
-				>
-			</File>
-			<File
-				RelativePath="tiffiop.h"
-				>
-			</File>
-			<File
-				RelativePath="tiffvers.h"
-				>
-			</File>
-			<File
-				RelativePath="uvcode.h"
-				>
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
diff --git a/Source/LibTIFF/LibTIFF.2008.vcproj b/Source/LibTIFF/LibTIFF.2008.vcproj
deleted file mode 100644
index 84f83b3..0000000
--- a/Source/LibTIFF/LibTIFF.2008.vcproj
+++ /dev/null
@@ -1,526 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="9,00"
-	Name="LibTIFF"
-	ProjectGUID="{431E3F3F-7C4D-430A-B8F1-4F165DB64EDC}"
-	RootNamespace="LibTIFF"
-	TargetFrameworkVersion="131072"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-		<Platform
-			Name="x64"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Release|Win32"
-			OutputDirectory=".\Release"
-			IntermediateDirectory=".\Release"
-			ConfigurationType="4"
-			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="2"
-				InlineFunctionExpansion="2"
-				EnableIntrinsicFunctions="true"
-				FavorSizeOrSpeed="1"
-				OmitFramePointers="true"
-				AdditionalIncludeDirectories="..\libtiff\libtiff,..\zlib"
-				PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE"
-				StringPooling="true"
-				RuntimeLibrary="0"
-				BufferSecurityCheck="false"
-				UsePrecompiledHeader="0"
-				PrecompiledHeaderFile=".\Release/LibTIFF.pch"
-				AssemblerListingLocation=".\Release/"
-				ObjectFile=".\Release/"
-				ProgramDataBaseFileName=".\Release/"
-				WarningLevel="3"
-				SuppressStartupBanner="true"
-				CompileAs="0"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="1033"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile=".\Release\LibTIFF.lib"
-				SuppressStartupBanner="true"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|Win32"
-			OutputDirectory=".\Debug"
-			IntermediateDirectory=".\Debug"
-			ConfigurationType="4"
-			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="0"
-				AdditionalIncludeDirectories="..\libtiff\libtiff"
-				PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE"
-				StringPooling="true"
-				BasicRuntimeChecks="3"
-				RuntimeLibrary="1"
-				UsePrecompiledHeader="0"
-				PrecompiledHeaderFile=".\Debug/LibTIFF.pch"
-				AssemblerListingLocation=".\Debug/"
-				ObjectFile=".\Debug/"
-				ProgramDataBaseFileName=".\Debug/"
-				WarningLevel="3"
-				SuppressStartupBanner="true"
-				DebugInformationFormat="4"
-				CompileAs="0"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="_DEBUG"
-				Culture="1033"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile=".\Debug\LibTIFF.lib"
-				SuppressStartupBanner="true"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|x64"
-			OutputDirectory="$(PlatformName)\$(ConfigurationName)"
-			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
-			ConfigurationType="4"
-			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="2"
-				InlineFunctionExpansion="2"
-				EnableIntrinsicFunctions="true"
-				FavorSizeOrSpeed="1"
-				OmitFramePointers="true"
-				AdditionalIncludeDirectories="..\libtiff\libtiff,..\zlib"
-				PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE"
-				StringPooling="true"
-				RuntimeLibrary="0"
-				BufferSecurityCheck="false"
-				UsePrecompiledHeader="0"
-				PrecompiledHeaderFile=".\Release/LibTIFF.pch"
-				AssemblerListingLocation=".\Release/"
-				ObjectFile=".\Release/"
-				ProgramDataBaseFileName=".\Release/"
-				WarningLevel="3"
-				SuppressStartupBanner="true"
-				CompileAs="0"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="1033"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile=".\Release\LibTIFF.lib"
-				SuppressStartupBanner="true"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|x64"
-			OutputDirectory="$(PlatformName)\$(ConfigurationName)"
-			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
-			ConfigurationType="4"
-			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="0"
-				AdditionalIncludeDirectories="..\libtiff\libtiff"
-				PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE"
-				StringPooling="true"
-				BasicRuntimeChecks="3"
-				RuntimeLibrary="1"
-				UsePrecompiledHeader="0"
-				PrecompiledHeaderFile=".\Debug/LibTIFF.pch"
-				AssemblerListingLocation=".\Debug/"
-				ObjectFile=".\Debug/"
-				ProgramDataBaseFileName=".\Debug/"
-				WarningLevel="3"
-				SuppressStartupBanner="true"
-				DebugInformationFormat="3"
-				CompileAs="0"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="_DEBUG"
-				Culture="1033"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile=".\Debug\LibTIFF.lib"
-				SuppressStartupBanner="true"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Source Files"
-			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-			>
-			<File
-				RelativePath="tif_aux.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_close.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_codec.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_color.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_compress.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_dir.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_dirinfo.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_dirread.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_dirwrite.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_dumpmode.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_error.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_extension.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_fax3.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_fax3sm.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_flush.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_getimage.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_jpeg.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_luv.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_lzw.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_next.c"
-				>
-			</File>
-			<File
-				RelativePath=".\tif_ojpeg.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_open.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_packbits.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_pixarlog.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_predict.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_print.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_read.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_strip.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_swab.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_thunder.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_tile.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_version.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_warning.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_write.c"
-				>
-			</File>
-			<File
-				RelativePath="tif_zip.c"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="Header Files"
-			Filter="h;hpp;hxx;hm;inl"
-			>
-			<File
-				RelativePath="t4.h"
-				>
-			</File>
-			<File
-				RelativePath="tif_config.h"
-				>
-			</File>
-			<File
-				RelativePath="tif_dir.h"
-				>
-			</File>
-			<File
-				RelativePath="tif_fax3.h"
-				>
-			</File>
-			<File
-				RelativePath="tif_predict.h"
-				>
-			</File>
-			<File
-				RelativePath="tiff.h"
-				>
-			</File>
-			<File
-				RelativePath="tiffio.h"
-				>
-			</File>
-			<File
-				RelativePath="tiffiop.h"
-				>
-			</File>
-			<File
-				RelativePath="tiffvers.h"
-				>
-			</File>
-			<File
-				RelativePath="uvcode.h"
-				>
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
diff --git a/Source/LibTIFF/Makefile.am b/Source/LibTIFF/Makefile.am
deleted file mode 100644
index 0aaac39..0000000
--- a/Source/LibTIFF/Makefile.am
+++ /dev/null
@@ -1,143 +0,0 @@
-# Tag Image File Format (TIFF) Software
-#
-# Copyright (C) 2004, Andrey Kiselev <dron at ak4719.spb.edu>
-#
-# Permission to use, copy, modify, distribute, and sell this software and 
-# its documentation for any purpose is hereby granted without fee, provided
-# that (i) the above copyright notices and this permission notice appear in
-# all copies of the software and related documentation, and (ii) the names of
-# Sam Leffler and Silicon Graphics may not be used in any advertising or
-# publicity relating to the software without the specific, prior written
-# permission of Sam Leffler and Silicon Graphics.
-# 
-# THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
-# EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
-# WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
-# 
-# IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
-# ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
-# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-# WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
-# LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
-# OF THIS SOFTWARE.
-
-# Process this file with automake to produce Makefile.in.
-
-LIBPORT = $(top_builddir)/port/libport.la
-LIBTIFF = $(top_builddir)/libtiff/libtiff.la
-libtiffincludedir = $(includedir)
-
-EXTRA_DIST = Makefile.vc \
-	     SConstruct \
-	     tif_config.h-vms \
-	     tif_config.vc.h \
-	     tif_config.wince.h \
-	     tiffconf.vc.h \
-	     tiffconf.wince.h \
-	     libtiff.def \
-	     $(EXTRA_SRCS)
-
-libtiffinclude_HEADERS = \
-	tiff.h \
-	tiffio.h \
-	tiffvers.h
-
-if HAVE_CXX
-libtiffinclude_HEADERS += tiffio.hxx
-endif
-
-noinst_HEADERS = \
-	t4.h \
-	tif_dir.h \
-	tif_predict.h \
-	tiffiop.h \
-	uvcode.h
-
-nodist_libtiffinclude_HEADERS = \
-	tiffconf.h
-
-libtiff_la_SOURCES = \
-	tif_aux.c \
-	tif_close.c \
-	tif_codec.c \
-	tif_color.c \
-	tif_compress.c \
-	tif_dir.c \
-	tif_dirinfo.c \
-	tif_dirread.c \
-	tif_dirwrite.c \
-	tif_dumpmode.c \
-	tif_error.c \
-	tif_extension.c \
-	tif_fax3.c \
-	tif_fax3sm.c \
-	tif_flush.c \
-	tif_getimage.c \
-	tif_jbig.c \
-	tif_jpeg.c \
-	tif_luv.c \
-	tif_lzw.c \
-	tif_next.c \
-	tif_ojpeg.c \
-	tif_open.c \
-	tif_packbits.c \
-	tif_pixarlog.c \
-	tif_predict.c \
-	tif_print.c \
-	tif_read.c \
-	tif_strip.c \
-	tif_swab.c \
-	tif_thunder.c \
-	tif_tile.c \
-	tif_unix.c \
-	tif_version.c \
-	tif_warning.c \
-	tif_write.c \
-	tif_zip.c
-
-libtiffxx_la_SOURCES = \
-	tif_stream.cxx
-
-EXTRA_SRCS = \
-	tif_acorn.c \
-	tif_apple.c \
-	tif_atari.c \
-	tif_msdos.c \
-	tif_next.c \
-	tif_win3.c \
-	tif_win32.c
-
-lib_LTLIBRARIES = libtiff.la
-if HAVE_CXX
-lib_LTLIBRARIES += libtiffxx.la
-endif
-
-libtiff_la_LDFLAGS = \
-	-no-undefined \
-	-version-number $(LIBTIFF_VERSION_INFO)
-if HAVE_RPATH
-libtiff_la_LDFLAGS += $(LIBDIR)
-endif
-libtiff_la_LIBADD = $(LIBPORT)
-
-libtiffxx_la_LDFLAGS = \
-	-no-undefined \
-	-version-number $(LIBTIFF_VERSION_INFO)
-if HAVE_RPATH
-libtiffxx_la_LDFLAGS += $(LIBDIR)
-endif
-libtiffxx_la_LIBADD = $(LIBTIFF) $(LIBPORT)
-libtiffxx_la_DEPENDENCIES = libtiff.la
-
-#
-# The finite state machine tables used by the G3/G4 decoders
-# are generated by the mkg3states program.  On systems without
-# make these rules have to be manually carried out.
-#
-noinst_PROGRAMS = mkg3states
-mkg3states_SOURCES = mkg3states.c tif_fax3.h
-mkg3states_LDADD = $(LIBPORT)
-
-faxtable: mkg3states
-	(rm -f tif_fax3sm.c && ./mkg3states -b -c const tif_fax3sm.c)
-
diff --git a/Source/LibTIFF/Makefile.in b/Source/LibTIFF/Makefile.in
deleted file mode 100644
index 10dbddf..0000000
--- a/Source/LibTIFF/Makefile.in
+++ /dev/null
@@ -1,884 +0,0 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
-# Inc.
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
- at SET_MAKE@
-
-# Tag Image File Format (TIFF) Software
-#
-# Copyright (C) 2004, Andrey Kiselev <dron at ak4719.spb.edu>
-#
-# Permission to use, copy, modify, distribute, and sell this software and 
-# its documentation for any purpose is hereby granted without fee, provided
-# that (i) the above copyright notices and this permission notice appear in
-# all copies of the software and related documentation, and (ii) the names of
-# Sam Leffler and Silicon Graphics may not be used in any advertising or
-# publicity relating to the software without the specific, prior written
-# permission of Sam Leffler and Silicon Graphics.
-# 
-# THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
-# EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
-# WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
-# 
-# IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
-# ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
-# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-# WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
-# LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
-# OF THIS SOFTWARE.
-
-# Process this file with automake to produce Makefile.in.
-
-
-
-VPATH = @srcdir@
-pkgdatadir = $(datadir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkglibexecdir = $(libexecdir)/@PACKAGE@
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-build_triplet = @build@
-host_triplet = @host@
- at HAVE_CXX_TRUE@am__append_1 = tiffio.hxx
- at HAVE_CXX_TRUE@am__append_2 = libtiffxx.la
- at HAVE_RPATH_TRUE@am__append_3 = $(LIBDIR)
- at HAVE_RPATH_TRUE@am__append_4 = $(LIBDIR)
-noinst_PROGRAMS = mkg3states$(EXEEXT)
-subdir = libtiff
-DIST_COMMON = $(am__libtiffinclude_HEADERS_DIST) $(noinst_HEADERS) \
-	$(srcdir)/Makefile.am $(srcdir)/Makefile.in \
-	$(srcdir)/tif_config.h.in $(srcdir)/tiffconf.h.in
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \
-	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
-	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
-	$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
-	$(ACLOCAL_M4)
-mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
-CONFIG_HEADER = tif_config.h tiffconf.h
-CONFIG_CLEAN_FILES =
-CONFIG_CLEAN_VPATH_FILES =
-am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
-am__vpath_adj = case $$p in \
-    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
-    *) f=$$p;; \
-  esac;
-am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
-am__install_max = 40
-am__nobase_strip_setup = \
-  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
-am__nobase_strip = \
-  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
-am__nobase_list = $(am__nobase_strip_setup); \
-  for p in $$list; do echo "$$p $$p"; done | \
-  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
-  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
-    if (++n[$$2] == $(am__install_max)) \
-      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
-    END { for (dir in files) print dir, files[dir] }'
-am__base_list = \
-  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
-  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
-am__installdirs = "$(DESTDIR)$(libdir)" \
-	"$(DESTDIR)$(libtiffincludedir)" \
-	"$(DESTDIR)$(libtiffincludedir)"
-LTLIBRARIES = $(lib_LTLIBRARIES)
-libtiff_la_DEPENDENCIES = $(LIBPORT)
-am_libtiff_la_OBJECTS = tif_aux.lo tif_close.lo tif_codec.lo \
-	tif_color.lo tif_compress.lo tif_dir.lo tif_dirinfo.lo \
-	tif_dirread.lo tif_dirwrite.lo tif_dumpmode.lo tif_error.lo \
-	tif_extension.lo tif_fax3.lo tif_fax3sm.lo tif_flush.lo \
-	tif_getimage.lo tif_jbig.lo tif_jpeg.lo tif_luv.lo tif_lzw.lo \
-	tif_next.lo tif_ojpeg.lo tif_open.lo tif_packbits.lo \
-	tif_pixarlog.lo tif_predict.lo tif_print.lo tif_read.lo \
-	tif_strip.lo tif_swab.lo tif_thunder.lo tif_tile.lo \
-	tif_unix.lo tif_version.lo tif_warning.lo tif_write.lo \
-	tif_zip.lo
-libtiff_la_OBJECTS = $(am_libtiff_la_OBJECTS)
-AM_V_lt = $(am__v_lt_$(V))
-am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
-am__v_lt_0 = --silent
-libtiff_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
-	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
-	$(libtiff_la_LDFLAGS) $(LDFLAGS) -o $@
-am_libtiffxx_la_OBJECTS = tif_stream.lo
-libtiffxx_la_OBJECTS = $(am_libtiffxx_la_OBJECTS)
-libtiffxx_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
-	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
-	$(CXXFLAGS) $(libtiffxx_la_LDFLAGS) $(LDFLAGS) -o $@
- at HAVE_CXX_TRUE@am_libtiffxx_la_rpath = -rpath $(libdir)
-PROGRAMS = $(noinst_PROGRAMS)
-am_mkg3states_OBJECTS = mkg3states.$(OBJEXT)
-mkg3states_OBJECTS = $(am_mkg3states_OBJECTS)
-mkg3states_DEPENDENCIES = $(LIBPORT)
-DEFAULT_INCLUDES = -I. at am__isrc@
-depcomp = $(SHELL) $(top_srcdir)/config/depcomp
-am__depfiles_maybe = depfiles
-am__mv = mv -f
-COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
-	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
-	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
-	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
-	$(AM_CFLAGS) $(CFLAGS)
-AM_V_CC = $(am__v_CC_$(V))
-am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
-am__v_CC_0 = @echo "  CC    " $@;
-AM_V_at = $(am__v_at_$(V))
-am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
-am__v_at_0 = @
-CCLD = $(CC)
-LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
-	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
-	$(AM_LDFLAGS) $(LDFLAGS) -o $@
-AM_V_CCLD = $(am__v_CCLD_$(V))
-am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
-am__v_CCLD_0 = @echo "  CCLD  " $@;
-CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
-	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
-LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
-	$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
-	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
-	$(AM_CXXFLAGS) $(CXXFLAGS)
-AM_V_CXX = $(am__v_CXX_$(V))
-am__v_CXX_ = $(am__v_CXX_$(AM_DEFAULT_VERBOSITY))
-am__v_CXX_0 = @echo "  CXX   " $@;
-CXXLD = $(CXX)
-CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
-	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
-	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
-AM_V_CXXLD = $(am__v_CXXLD_$(V))
-am__v_CXXLD_ = $(am__v_CXXLD_$(AM_DEFAULT_VERBOSITY))
-am__v_CXXLD_0 = @echo "  CXXLD " $@;
-AM_V_GEN = $(am__v_GEN_$(V))
-am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
-am__v_GEN_0 = @echo "  GEN   " $@;
-SOURCES = $(libtiff_la_SOURCES) $(libtiffxx_la_SOURCES) \
-	$(mkg3states_SOURCES)
-DIST_SOURCES = $(libtiff_la_SOURCES) $(libtiffxx_la_SOURCES) \
-	$(mkg3states_SOURCES)
-am__libtiffinclude_HEADERS_DIST = tiff.h tiffio.h tiffvers.h \
-	tiffio.hxx
-HEADERS = $(libtiffinclude_HEADERS) $(nodist_libtiffinclude_HEADERS) \
-	$(noinst_HEADERS)
-ETAGS = etags
-CTAGS = ctags
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = @ACLOCAL@
-AMTAR = @AMTAR@
-AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
-AR = @AR@
-AS = @AS@
-AUTOCONF = @AUTOCONF@
-AUTOHEADER = @AUTOHEADER@
-AUTOMAKE = @AUTOMAKE@
-AWK = @AWK@
-CC = @CC@
-CCDEPMODE = @CCDEPMODE@
-CFLAGS = @CFLAGS@
-CPP = @CPP@
-CPPFLAGS = @CPPFLAGS@
-CXX = @CXX@
-CXXCPP = @CXXCPP@
-CXXDEPMODE = @CXXDEPMODE@
-CXXFLAGS = @CXXFLAGS@
-CYGPATH_W = @CYGPATH_W@
-DEFS = @DEFS@
-DEPDIR = @DEPDIR@
-DLLTOOL = @DLLTOOL@
-DSYMUTIL = @DSYMUTIL@
-DUMPBIN = @DUMPBIN@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EGREP = @EGREP@
-EXEEXT = @EXEEXT@
-FGREP = @FGREP@
-GLUT_CFLAGS = @GLUT_CFLAGS@
-GLUT_LIBS = @GLUT_LIBS@
-GLU_CFLAGS = @GLU_CFLAGS@
-GLU_LIBS = @GLU_LIBS@
-GL_CFLAGS = @GL_CFLAGS@
-GL_LIBS = @GL_LIBS@
-GREP = @GREP@
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LD = @LD@
-LDFLAGS = @LDFLAGS@
-LIBDIR = @LIBDIR@
-LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
-LIBTIFF_ALPHA_VERSION = @LIBTIFF_ALPHA_VERSION@
-LIBTIFF_DOCDIR = @LIBTIFF_DOCDIR@
-LIBTIFF_MAJOR_VERSION = @LIBTIFF_MAJOR_VERSION@
-LIBTIFF_MICRO_VERSION = @LIBTIFF_MICRO_VERSION@
-LIBTIFF_MINOR_VERSION = @LIBTIFF_MINOR_VERSION@
-LIBTIFF_RELEASE_DATE = @LIBTIFF_RELEASE_DATE@
-LIBTIFF_VERSION = @LIBTIFF_VERSION@
-LIBTIFF_VERSION_INFO = @LIBTIFF_VERSION_INFO@
-LIBTOOL = @LIBTOOL@
-LIPO = @LIPO@
-LN_S = @LN_S@
-LTLIBOBJS = @LTLIBOBJS@
-MAINT = @MAINT@
-MAKEINFO = @MAKEINFO@
-MANIFEST_TOOL = @MANIFEST_TOOL@
-MKDIR_P = @MKDIR_P@
-NM = @NM@
-NMEDIT = @NMEDIT@
-OBJDUMP = @OBJDUMP@
-OBJEXT = @OBJEXT@
-OTOOL = @OTOOL@
-OTOOL64 = @OTOOL64@
-PACKAGE = @PACKAGE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_URL = @PACKAGE_URL@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-PTHREAD_CC = @PTHREAD_CC@
-PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
-PTHREAD_LIBS = @PTHREAD_LIBS@
-RANLIB = @RANLIB@
-SED = @SED@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-STRIP = @STRIP@
-VERSION = @VERSION@
-XMKMF = @XMKMF@
-X_CFLAGS = @X_CFLAGS@
-X_EXTRA_LIBS = @X_EXTRA_LIBS@
-X_LIBS = @X_LIBS@
-X_PRE_LIBS = @X_PRE_LIBS@
-abs_builddir = @abs_builddir@
-abs_srcdir = @abs_srcdir@
-abs_top_builddir = @abs_top_builddir@
-abs_top_srcdir = @abs_top_srcdir@
-ac_ct_AR = @ac_ct_AR@
-ac_ct_CC = @ac_ct_CC@
-ac_ct_CXX = @ac_ct_CXX@
-ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
-acx_pthread_config = @acx_pthread_config@
-am__include = @am__include@
-am__leading_dot = @am__leading_dot@
-am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
-bindir = @bindir@
-build = @build@
-build_alias = @build_alias@
-build_cpu = @build_cpu@
-build_os = @build_os@
-build_vendor = @build_vendor@
-builddir = @builddir@
-datadir = @datadir@
-datarootdir = @datarootdir@
-docdir = @docdir@
-dvidir = @dvidir@
-exec_prefix = @exec_prefix@
-host = @host@
-host_alias = @host_alias@
-host_cpu = @host_cpu@
-host_os = @host_os@
-host_vendor = @host_vendor@
-htmldir = @htmldir@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-libdir = @libdir@
-libexecdir = @libexecdir@
-localedir = @localedir@
-localstatedir = @localstatedir@
-mandir = @mandir@
-mkdir_p = @mkdir_p@
-oldincludedir = @oldincludedir@
-pdfdir = @pdfdir@
-prefix = @prefix@
-program_transform_name = @program_transform_name@
-psdir = @psdir@
-sbindir = @sbindir@
-sharedstatedir = @sharedstatedir@
-srcdir = @srcdir@
-sysconfdir = @sysconfdir@
-target_alias = @target_alias@
-top_build_prefix = @top_build_prefix@
-top_builddir = @top_builddir@
-top_srcdir = @top_srcdir@
-LIBPORT = $(top_builddir)/port/libport.la
-LIBTIFF = $(top_builddir)/libtiff/libtiff.la
-libtiffincludedir = $(includedir)
-EXTRA_DIST = Makefile.vc \
-	     SConstruct \
-	     tif_config.h-vms \
-	     tif_config.vc.h \
-	     tif_config.wince.h \
-	     tiffconf.vc.h \
-	     tiffconf.wince.h \
-	     libtiff.def \
-	     $(EXTRA_SRCS)
-
-libtiffinclude_HEADERS = tiff.h tiffio.h tiffvers.h $(am__append_1)
-noinst_HEADERS = \
-	t4.h \
-	tif_dir.h \
-	tif_predict.h \
-	tiffiop.h \
-	uvcode.h
-
-nodist_libtiffinclude_HEADERS = \
-	tiffconf.h
-
-libtiff_la_SOURCES = \
-	tif_aux.c \
-	tif_close.c \
-	tif_codec.c \
-	tif_color.c \
-	tif_compress.c \
-	tif_dir.c \
-	tif_dirinfo.c \
-	tif_dirread.c \
-	tif_dirwrite.c \
-	tif_dumpmode.c \
-	tif_error.c \
-	tif_extension.c \
-	tif_fax3.c \
-	tif_fax3sm.c \
-	tif_flush.c \
-	tif_getimage.c \
-	tif_jbig.c \
-	tif_jpeg.c \
-	tif_luv.c \
-	tif_lzw.c \
-	tif_next.c \
-	tif_ojpeg.c \
-	tif_open.c \
-	tif_packbits.c \
-	tif_pixarlog.c \
-	tif_predict.c \
-	tif_print.c \
-	tif_read.c \
-	tif_strip.c \
-	tif_swab.c \
-	tif_thunder.c \
-	tif_tile.c \
-	tif_unix.c \
-	tif_version.c \
-	tif_warning.c \
-	tif_write.c \
-	tif_zip.c
-
-libtiffxx_la_SOURCES = \
-	tif_stream.cxx
-
-EXTRA_SRCS = \
-	tif_acorn.c \
-	tif_apple.c \
-	tif_atari.c \
-	tif_msdos.c \
-	tif_next.c \
-	tif_win3.c \
-	tif_win32.c
-
-lib_LTLIBRARIES = libtiff.la $(am__append_2)
-libtiff_la_LDFLAGS = -no-undefined -version-number \
-	$(LIBTIFF_VERSION_INFO) $(am__append_3)
-libtiff_la_LIBADD = $(LIBPORT)
-libtiffxx_la_LDFLAGS = -no-undefined -version-number \
-	$(LIBTIFF_VERSION_INFO) $(am__append_4)
-libtiffxx_la_LIBADD = $(LIBTIFF) $(LIBPORT)
-libtiffxx_la_DEPENDENCIES = libtiff.la
-mkg3states_SOURCES = mkg3states.c tif_fax3.h
-mkg3states_LDADD = $(LIBPORT)
-all: tif_config.h tiffconf.h
-	$(MAKE) $(AM_MAKEFLAGS) all-am
-
-.SUFFIXES:
-.SUFFIXES: .c .cxx .lo .o .obj
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
-	@for dep in $?; do \
-	  case '$(am__configure_deps)' in \
-	    *$$dep*) \
-	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
-	        && { if test -f $@; then exit 0; else break; fi; }; \
-	      exit 1;; \
-	  esac; \
-	done; \
-	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign libtiff/Makefile'; \
-	$(am__cd) $(top_srcdir) && \
-	  $(AUTOMAKE) --foreign libtiff/Makefile
-.PRECIOUS: Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
-	@case '$?' in \
-	  *config.status*) \
-	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
-	  *) \
-	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
-	esac;
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(am__aclocal_m4_deps):
-
-tif_config.h: stamp-h1
-	@if test ! -f $@; then \
-	  rm -f stamp-h1; \
-	  $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \
-	else :; fi
-
-stamp-h1: $(srcdir)/tif_config.h.in $(top_builddir)/config.status
-	@rm -f stamp-h1
-	cd $(top_builddir) && $(SHELL) ./config.status libtiff/tif_config.h
-$(srcdir)/tif_config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) 
-	($(am__cd) $(top_srcdir) && $(AUTOHEADER))
-	rm -f stamp-h1
-	touch $@
-
-tiffconf.h: stamp-h2
-	@if test ! -f $@; then \
-	  rm -f stamp-h2; \
-	  $(MAKE) $(AM_MAKEFLAGS) stamp-h2; \
-	else :; fi
-
-stamp-h2: $(srcdir)/tiffconf.h.in $(top_builddir)/config.status
-	@rm -f stamp-h2
-	cd $(top_builddir) && $(SHELL) ./config.status libtiff/tiffconf.h
-
-distclean-hdr:
-	-rm -f tif_config.h stamp-h1 tiffconf.h stamp-h2
-install-libLTLIBRARIES: $(lib_LTLIBRARIES)
-	@$(NORMAL_INSTALL)
-	test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
-	@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
-	list2=; for p in $$list; do \
-	  if test -f $$p; then \
-	    list2="$$list2 $$p"; \
-	  else :; fi; \
-	done; \
-	test -z "$$list2" || { \
-	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
-	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
-	}
-
-uninstall-libLTLIBRARIES:
-	@$(NORMAL_UNINSTALL)
-	@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
-	for p in $$list; do \
-	  $(am__strip_dir) \
-	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
-	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
-	done
-
-clean-libLTLIBRARIES:
-	-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
-	@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
-	  dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
-	  test "$$dir" != "$$p" || dir=.; \
-	  echo "rm -f \"$${dir}/so_locations\""; \
-	  rm -f "$${dir}/so_locations"; \
-	done
-libtiff.la: $(libtiff_la_OBJECTS) $(libtiff_la_DEPENDENCIES) 
-	$(AM_V_CCLD)$(libtiff_la_LINK) -rpath $(libdir) $(libtiff_la_OBJECTS) $(libtiff_la_LIBADD) $(LIBS)
-libtiffxx.la: $(libtiffxx_la_OBJECTS) $(libtiffxx_la_DEPENDENCIES) 
-	$(AM_V_CXXLD)$(libtiffxx_la_LINK) $(am_libtiffxx_la_rpath) $(libtiffxx_la_OBJECTS) $(libtiffxx_la_LIBADD) $(LIBS)
-
-clean-noinstPROGRAMS:
-	@list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
-	echo " rm -f" $$list; \
-	rm -f $$list || exit $$?; \
-	test -n "$(EXEEXT)" || exit 0; \
-	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
-	echo " rm -f" $$list; \
-	rm -f $$list
-mkg3states$(EXEEXT): $(mkg3states_OBJECTS) $(mkg3states_DEPENDENCIES) 
-	@rm -f mkg3states$(EXEEXT)
-	$(AM_V_CCLD)$(LINK) $(mkg3states_OBJECTS) $(mkg3states_LDADD) $(LIBS)
-
-mostlyclean-compile:
-	-rm -f *.$(OBJEXT)
-
-distclean-compile:
-	-rm -f *.tab.c
-
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mkg3states.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tif_aux.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tif_close.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tif_codec.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tif_color.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tif_compress.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tif_dir.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tif_dirinfo.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tif_dirread.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tif_dirwrite.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tif_dumpmode.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tif_error.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tif_extension.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tif_fax3.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tif_fax3sm.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tif_flush.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tif_getimage.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tif_jbig.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tif_jpeg.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tif_luv.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tif_lzw.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tif_next.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tif_ojpeg.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tif_open.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tif_packbits.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tif_pixarlog.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tif_predict.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tif_print.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tif_read.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tif_stream.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tif_strip.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tif_swab.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tif_thunder.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tif_tile.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tif_unix.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tif_version.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tif_warning.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tif_write.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tif_zip.Plo at am__quote@
-
-.c.o:
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
- at am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(COMPILE) -c $<
-
-.c.obj:
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
- at am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(COMPILE) -c `$(CYGPATH_W) '$<'`
-
-.c.lo:
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
- at am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(LTCOMPILE) -c -o $@ $<
-
-.cxx.o:
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
- at am__fastdepCXX_FALSE@	$(AM_V_CXX) @AM_BACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(CXXCOMPILE) -c -o $@ $<
-
-.cxx.obj:
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
- at am__fastdepCXX_FALSE@	$(AM_V_CXX) @AM_BACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
-
-.cxx.lo:
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
- at am__fastdepCXX_FALSE@	$(AM_V_CXX) @AM_BACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(LTCXXCOMPILE) -c -o $@ $<
-
-mostlyclean-libtool:
-	-rm -f *.lo
-
-clean-libtool:
-	-rm -rf .libs _libs
-install-libtiffincludeHEADERS: $(libtiffinclude_HEADERS)
-	@$(NORMAL_INSTALL)
-	test -z "$(libtiffincludedir)" || $(MKDIR_P) "$(DESTDIR)$(libtiffincludedir)"
-	@list='$(libtiffinclude_HEADERS)'; test -n "$(libtiffincludedir)" || list=; \
-	for p in $$list; do \
-	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
-	  echo "$$d$$p"; \
-	done | $(am__base_list) | \
-	while read files; do \
-	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libtiffincludedir)'"; \
-	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(libtiffincludedir)" || exit $$?; \
-	done
-
-uninstall-libtiffincludeHEADERS:
-	@$(NORMAL_UNINSTALL)
-	@list='$(libtiffinclude_HEADERS)'; test -n "$(libtiffincludedir)" || list=; \
-	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(libtiffincludedir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(libtiffincludedir)" && rm -f $$files
-install-nodist_libtiffincludeHEADERS: $(nodist_libtiffinclude_HEADERS)
-	@$(NORMAL_INSTALL)
-	test -z "$(libtiffincludedir)" || $(MKDIR_P) "$(DESTDIR)$(libtiffincludedir)"
-	@list='$(nodist_libtiffinclude_HEADERS)'; test -n "$(libtiffincludedir)" || list=; \
-	for p in $$list; do \
-	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
-	  echo "$$d$$p"; \
-	done | $(am__base_list) | \
-	while read files; do \
-	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libtiffincludedir)'"; \
-	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(libtiffincludedir)" || exit $$?; \
-	done
-
-uninstall-nodist_libtiffincludeHEADERS:
-	@$(NORMAL_UNINSTALL)
-	@list='$(nodist_libtiffinclude_HEADERS)'; test -n "$(libtiffincludedir)" || list=; \
-	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(libtiffincludedir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(libtiffincludedir)" && rm -f $$files
-
-ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
-	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
-	unique=`for i in $$list; do \
-	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-	  done | \
-	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
-	      END { if (nonempty) { for (i in files) print i; }; }'`; \
-	mkid -fID $$unique
-tags: TAGS
-
-TAGS:  $(HEADERS) $(SOURCES) tif_config.h.in tiffconf.h.in $(TAGS_DEPENDENCIES) \
-		$(TAGS_FILES) $(LISP)
-	set x; \
-	here=`pwd`; \
-	list='$(SOURCES) $(HEADERS) tif_config.h.in tiffconf.h.in $(LISP) $(TAGS_FILES)'; \
-	unique=`for i in $$list; do \
-	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-	  done | \
-	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
-	      END { if (nonempty) { for (i in files) print i; }; }'`; \
-	shift; \
-	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
-	  test -n "$$unique" || unique=$$empty_fix; \
-	  if test $$# -gt 0; then \
-	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
-	      "$$@" $$unique; \
-	  else \
-	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
-	      $$unique; \
-	  fi; \
-	fi
-ctags: CTAGS
-CTAGS:  $(HEADERS) $(SOURCES) tif_config.h.in tiffconf.h.in $(TAGS_DEPENDENCIES) \
-		$(TAGS_FILES) $(LISP)
-	list='$(SOURCES) $(HEADERS) tif_config.h.in tiffconf.h.in $(LISP) $(TAGS_FILES)'; \
-	unique=`for i in $$list; do \
-	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-	  done | \
-	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
-	      END { if (nonempty) { for (i in files) print i; }; }'`; \
-	test -z "$(CTAGS_ARGS)$$unique" \
-	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
-	     $$unique
-
-GTAGS:
-	here=`$(am__cd) $(top_builddir) && pwd` \
-	  && $(am__cd) $(top_srcdir) \
-	  && gtags -i $(GTAGS_ARGS) "$$here"
-
-distclean-tags:
-	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
-distdir: $(DISTFILES)
-	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
-	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
-	list='$(DISTFILES)'; \
-	  dist_files=`for file in $$list; do echo $$file; done | \
-	  sed -e "s|^$$srcdirstrip/||;t" \
-	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
-	case $$dist_files in \
-	  */*) $(MKDIR_P) `echo "$$dist_files" | \
-			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
-			   sort -u` ;; \
-	esac; \
-	for file in $$dist_files; do \
-	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
-	  if test -d $$d/$$file; then \
-	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
-	    if test -d "$(distdir)/$$file"; then \
-	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
-	    fi; \
-	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
-	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
-	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
-	    fi; \
-	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
-	  else \
-	    test -f "$(distdir)/$$file" \
-	    || cp -p $$d/$$file "$(distdir)/$$file" \
-	    || exit 1; \
-	  fi; \
-	done
-check-am: all-am
-check: check-am
-all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS) tif_config.h \
-		tiffconf.h
-installdirs:
-	for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libtiffincludedir)" "$(DESTDIR)$(libtiffincludedir)"; do \
-	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
-	done
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
-	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
-	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	  `test -z '$(STRIP)' || \
-	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
-mostlyclean-generic:
-
-clean-generic:
-
-distclean-generic:
-	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-
-maintainer-clean-generic:
-	@echo "This command is intended for maintainers to use"
-	@echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
-
-clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
-	clean-noinstPROGRAMS mostlyclean-am
-
-distclean: distclean-am
-	-rm -rf ./$(DEPDIR)
-	-rm -f Makefile
-distclean-am: clean-am distclean-compile distclean-generic \
-	distclean-hdr distclean-tags
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-html-am:
-
-info: info-am
-
-info-am:
-
-install-data-am: install-libtiffincludeHEADERS \
-	install-nodist_libtiffincludeHEADERS
-
-install-dvi: install-dvi-am
-
-install-dvi-am:
-
-install-exec-am: install-libLTLIBRARIES
-
-install-html: install-html-am
-
-install-html-am:
-
-install-info: install-info-am
-
-install-info-am:
-
-install-man:
-
-install-pdf: install-pdf-am
-
-install-pdf-am:
-
-install-ps: install-ps-am
-
-install-ps-am:
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
-	-rm -rf ./$(DEPDIR)
-	-rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-compile mostlyclean-generic \
-	mostlyclean-libtool
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am: uninstall-libLTLIBRARIES uninstall-libtiffincludeHEADERS \
-	uninstall-nodist_libtiffincludeHEADERS
-
-.MAKE: all install-am install-strip
-
-.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
-	clean-libLTLIBRARIES clean-libtool clean-noinstPROGRAMS ctags \
-	distclean distclean-compile distclean-generic distclean-hdr \
-	distclean-libtool distclean-tags distdir dvi dvi-am html \
-	html-am info info-am install install-am install-data \
-	install-data-am install-dvi install-dvi-am install-exec \
-	install-exec-am install-html install-html-am install-info \
-	install-info-am install-libLTLIBRARIES \
-	install-libtiffincludeHEADERS install-man \
-	install-nodist_libtiffincludeHEADERS install-pdf \
-	install-pdf-am install-ps install-ps-am install-strip \
-	installcheck installcheck-am installdirs maintainer-clean \
-	maintainer-clean-generic mostlyclean mostlyclean-compile \
-	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
-	tags uninstall uninstall-am uninstall-libLTLIBRARIES \
-	uninstall-libtiffincludeHEADERS \
-	uninstall-nodist_libtiffincludeHEADERS
-
-
-faxtable: mkg3states
-	(rm -f tif_fax3sm.c && ./mkg3states -b -c const tif_fax3sm.c)
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
diff --git a/Source/LibTIFF/SConstruct b/Source/LibTIFF/SConstruct
deleted file mode 100644
index d1a2620..0000000
--- a/Source/LibTIFF/SConstruct
+++ /dev/null
@@ -1,73 +0,0 @@
-# $Id: SConstruct,v 1.29 2011/04/10 17:14:09 drolon Exp $
-
-# Tag Image File Format (TIFF) Software
-#
-# Copyright (C) 2005, Andrey Kiselev <dron at ak4719.spb.edu>
-#
-# Permission to use, copy, modify, distribute, and sell this software and 
-# its documentation for any purpose is hereby granted without fee, provided
-# that (i) the above copyright notices and this permission notice appear in
-# all copies of the software and related documentation, and (ii) the names of
-# Sam Leffler and Silicon Graphics may not be used in any advertising or
-# publicity relating to the software without the specific, prior written
-# permission of Sam Leffler and Silicon Graphics.
-# 
-# THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
-# EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
-# WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
-# 
-# IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
-# ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
-# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-# WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
-# LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
-# OF THIS SOFTWARE.
-
-# This file contains rules to build software with the SCons tool
-# (see the http://www.scons.org/ for details on SCons).
-
-# Import globally defined options
-Import([ 'env', 'idir_lib' ])
-
-SRCS = [ \
-	'tif_aux.c', \
-	'tif_close.c', \
-	'tif_codec.c', \
-	'tif_color.c', \
-	'tif_compress.c', \
-	'tif_dir.c', \
-	'tif_dirinfo.c', \
-	'tif_dirread.c', \
-	'tif_dirwrite.c', \
-	'tif_dumpmode.c', \
-	'tif_error.c', \
-	'tif_extension.c', \
-	'tif_fax3.c', \
-	'tif_fax3sm.c', \
-	'tif_flush.c', \
-	'tif_getimage.c', \
-	'tif_jbig.c', \
-	'tif_jpeg.c', \
-	'tif_luv.c', \
-	'tif_lzw.c', \
-	'tif_next.c', \
-	'tif_ojpeg.c', \
-	'tif_open.c', \
-	'tif_packbits.c', \
-	'tif_pixarlog.c', \
-	'tif_predict.c', \
-	'tif_print.c', \
-	'tif_read.c', \
-	'tif_strip.c', \
-	'tif_swab.c', \
-	'tif_thunder.c', \
-	'tif_tile.c', \
-	'tif_unix.c', \
-	'tif_version.c', \
-	'tif_warning.c', \
-	'tif_write.c', \
-	'tif_zip.c' ]
-
-StaticLibrary('tiff', SRCS)
-SharedLibrary('tiff', SRCS)
-
diff --git a/Source/LibTIFF/_FI_3151_PluginG3.cpp b/Source/LibTIFF/_FI_3151_PluginG3.cpp
deleted file mode 100644
index 477e91e..0000000
--- a/Source/LibTIFF/_FI_3151_PluginG3.cpp
+++ /dev/null
@@ -1,433 +0,0 @@
-// ==========================================================
-// G3 Fax Loader
-//
-// Design and implementation by
-// - Herv� Drolon (drolon at infonie.fr)
-// - Petr Pytelka (pyta at lightcomp.com)
-//
-// This file is part of FreeImage 3
-//
-// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
-// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
-// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
-// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
-// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
-// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
-// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
-// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
-// THIS DISCLAIMER.
-//
-// Use at your own risk!
-// ==========================================================
-
-#include "../LibTIFF/tiffiop.h"
-
-#include "FreeImage.h"
-#include "Utilities.h"
-
-// ==========================================================
-// Plugin Interface
-// ==========================================================
-
-static int s_format_id;
-
-// ==========================================================
-//   Constant/Macro declarations
-// ==========================================================
-
-#define G3_DEFAULT_WIDTH	1728
-
-#define TIFFhowmany8(x) (((x)&0x07)?((uint32)(x)>>3)+1:(uint32)(x)>>3)
-
-// ==========================================================
-//   libtiff interface 
-// ==========================================================
-
-static tsize_t 
-_g3ReadProc(thandle_t fd, tdata_t buf, tsize_t size) {
-	// returns an error when reading the TIFF header
-	return 0;
-}
-
-static tsize_t
-_g3WriteProc(thandle_t fd, tdata_t buf, tsize_t size) {
-	// returns ok when writing the TIFF header
-	return size;
-}
-
-static toff_t
-_g3SeekProc(thandle_t fd, toff_t off, int whence) {
-	return 0;
-}
-
-static int
-_g3CloseProc(thandle_t fd) {
-	return 0;
-}
-
-static toff_t
-_g3SizeProc(thandle_t fd) {
-	return 0;
-}
-
-static int
-_g3MapProc(thandle_t fd, tdata_t* pbase, toff_t* psize) {
-	return 0;
-}
-
-static void
-_g3UnmapProc(thandle_t fd, tdata_t base, toff_t size) {
-}
-
-// --------------------------------------------------------------
-
-static toff_t
-G3GetFileSize(FreeImageIO *io, fi_handle handle) {
-    long currentPos = io->tell_proc(handle);
-    io->seek_proc(handle, 0, SEEK_END);
-    long fileSize = io->tell_proc(handle);
-    io->seek_proc(handle, currentPos, SEEK_SET);
-    return fileSize;
-}
-
-static BOOL 
-G3ReadFile(FreeImageIO *io, fi_handle handle, tidata_t tif_rawdata, tsize_t tif_rawdatasize) {
-	return ((tsize_t)(io->read_proc(tif_rawdata, tif_rawdatasize, 1, handle) * tif_rawdatasize) == tif_rawdatasize);
-}
-
-// ==========================================================
-// Internal functions
-// ==========================================================
-
-static int 
-copyFaxFile(FreeImageIO *io, fi_handle handle, TIFF* tifin, uint32 xsize, int stretch, FIMEMORY *memory) {
-	BYTE *rowbuf = NULL;
-	BYTE *refbuf = NULL;
-	uint32 row;
-	uint16 badrun;
-	uint16	badfaxrun;
-	uint32	badfaxlines;
-	int ok;
-
-	try {
-
-		uint32 linesize = TIFFhowmany8(xsize);
-		rowbuf = (BYTE*) _TIFFmalloc(linesize);
-		refbuf = (BYTE*) _TIFFmalloc(linesize);
-		if (rowbuf == NULL || refbuf == NULL) {
-			throw FI_MSG_ERROR_MEMORY;
-		}
-
-		tifin->tif_rawdatasize = G3GetFileSize(io, handle);
-		tifin->tif_rawdata = (tidata_t) _TIFFmalloc(tifin->tif_rawdatasize);
-		if (tifin->tif_rawdata == NULL) {
-			throw FI_MSG_ERROR_MEMORY;
-		}
-			
-		if(!G3ReadFile(io, handle, tifin->tif_rawdata, tifin->tif_rawdatasize)) {
-			throw "Read error at scanline 0";
-		}
-		tifin->tif_rawcp = tifin->tif_rawdata;
-		tifin->tif_rawcc = tifin->tif_rawdatasize;
-
-		(*tifin->tif_setupdecode)(tifin);
-		(*tifin->tif_predecode)(tifin, (tsample_t) 0);
-		tifin->tif_row = 0;
-		badfaxlines = 0;
-		badfaxrun = 0;
-
-		_TIFFmemset(refbuf, 0, linesize);
-		row = 0;
-		badrun = 0;		// current run of bad lines 
-		while (tifin->tif_rawcc > 0) {
-			ok = (*tifin->tif_decoderow)(tifin, rowbuf, linesize, 0);
-			if (!ok) {
-				badfaxlines++;
-				badrun++;
-				// regenerate line from previous good line 
-				_TIFFmemcpy(rowbuf, refbuf, linesize);
-			} else {
-				if (badrun > badfaxrun)
-					badfaxrun = badrun;
-				badrun = 0;
-				_TIFFmemcpy(refbuf, rowbuf, linesize);
-			}
-			tifin->tif_row++;
-
-			FreeImage_WriteMemory(rowbuf, linesize, 1, memory);
-			row++;
-			if (stretch) {
-				FreeImage_WriteMemory(rowbuf, linesize, 1, memory);
-				row++;
-			}
-		}
-		if (badrun > badfaxrun)
-			badfaxrun = badrun;
-
-		_TIFFfree(tifin->tif_rawdata);
-		tifin->tif_rawdata = NULL;
-
-		_TIFFfree(rowbuf);
-		_TIFFfree(refbuf);
-
-		/*
-		if (verbose) {
-			fprintf(stderr, "%d rows in input\n", rows);
-			fprintf(stderr, "%ld total bad rows\n", (long) badfaxlines);
-			fprintf(stderr, "%d max consecutive bad rows\n", badfaxrun);
-		}
-		*/
-
-	} catch(const char *message) {
-		if(rowbuf) _TIFFfree(rowbuf);
-		if(refbuf) _TIFFfree(refbuf);
-		if(tifin->tif_rawdata) {
-			_TIFFfree(tifin->tif_rawdata);
-			tifin->tif_rawdata = NULL;
-		}
-		FreeImage_OutputMessageProc(s_format_id, message);
-
-		return -1;
-	}
-
-	return (row);
-}
-
-
-// ==========================================================
-// Plugin Implementation
-// ==========================================================
-
-static const char * DLL_CALLCONV
-Format() {
-	return "G3";
-}
-
-static const char * DLL_CALLCONV 
-Description() {
-	return "Raw fax format CCITT G.3";
-}
-
-static const char * DLL_CALLCONV 
-Extension() {
-	return "g3";
-}
-
-static const char * DLL_CALLCONV 
-RegExpr() {
-	return NULL; // there is now reasonable regexp for raw G3
-}
-
-static const char * DLL_CALLCONV 
-MimeType() {
-	return "image/fax-g3";
-}
-
-static BOOL DLL_CALLCONV 
-SupportsExportDepth(int depth) {
-	return	FALSE;
-}
-
-// ----------------------------------------------------------
-
-static FIBITMAP * DLL_CALLCONV
-Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
-	TIFF *faxTIFF = NULL;
-	FIBITMAP *dib = NULL;
-	FIMEMORY *memory = NULL;
-
-	//int verbose = 0;
-	int	stretch = 0;
-	int rows;
-	float resX = 204.0;
-	float resY = 196.0;
-
-	uint32 xsize = G3_DEFAULT_WIDTH;
-	int compression_in = COMPRESSION_CCITTFAX3;
-	int fillorder_in = FILLORDER_LSB2MSB;
-	uint32 group3options_in = 0;	// 1d-encoded 
-	uint32 group4options_in = 0;	// compressed 
-	int photometric_in = PHOTOMETRIC_MINISWHITE;
-
-	if(handle==NULL) return NULL;
-
-	try {
-		// set default load options
-
-		compression_in = COMPRESSION_CCITTFAX3;			// input is g3-encoded 
-		group3options_in &= ~GROUP3OPT_2DENCODING;		// input is 1d-encoded (g3 only) 
-		fillorder_in = FILLORDER_MSB2LSB;				// input has msb-to-lsb fillorder 
-
-		/*
-		Original input-related fax2tiff options
-
-		while ((c = getopt(argc, argv, "R:X:o:1234ABLMPUW5678abcflmprsuvwz?")) != -1) {
-			switch (c) {
-					// input-related options 
-				case '3':		// input is g3-encoded 
-					compression_in = COMPRESSION_CCITTFAX3;
-					break;
-				case '4':		// input is g4-encoded 
-					compression_in = COMPRESSION_CCITTFAX4;
-					break;
-				case 'U':		// input is uncompressed (g3 and g4) 
-					group3options_in |= GROUP3OPT_UNCOMPRESSED;
-					group4options_in |= GROUP4OPT_UNCOMPRESSED;
-					break;
-				case '1':		// input is 1d-encoded (g3 only) 
-					group3options_in &= ~GROUP3OPT_2DENCODING;
-					break;
-				case '2':		// input is 2d-encoded (g3 only) 
-					group3options_in |= GROUP3OPT_2DENCODING;
-					break;
-				case 'P':	// input has not-aligned EOL (g3 only) 
-					group3options_in &= ~GROUP3OPT_FILLBITS;
-					break;
-				case 'A':		// input has aligned EOL (g3 only) 
-					group3options_in |= GROUP3OPT_FILLBITS;
-					break;
-				case 'W':		// input has 0 mean white 
-					photometric_in = PHOTOMETRIC_MINISWHITE;
-					break;
-				case 'B':		// input has 0 mean black 
-					photometric_in = PHOTOMETRIC_MINISBLACK;
-					break;
-				case 'L':		// input has lsb-to-msb fillorder 
-					fillorder_in = FILLORDER_LSB2MSB;
-					break;
-				case 'M':		// input has msb-to-lsb fillorder 
-					fillorder_in = FILLORDER_MSB2LSB;
-					break;
-				case 'R':		// input resolution 
-					resY = (float) atof(optarg);
-					break;
-				case 'X':		// input width 
-					xsize = (uint32) atoi(optarg);
-					break;
-
-					// output-related options 
-				case 's':		// stretch image by dup'ng scanlines 
-					stretch = 1;
-					break;
-				case 'v':		// -v for info 
-					verbose++;
-					break;
-			}
-		}
-
-		*/
-
-		// open a temporary memory buffer to save decoded scanlines
-		memory = FreeImage_OpenMemory();
-		if(!memory) throw FI_MSG_ERROR_MEMORY;
-		
-		// wrap the raw fax file
-		faxTIFF = TIFFClientOpen("(FakeInput)", "w",
-			// TIFFClientOpen() fails if we don't set existing value here 
-			NULL,
-			_g3ReadProc, _g3WriteProc,
-			_g3SeekProc, _g3CloseProc,
-			_g3SizeProc, _g3MapProc,
-			_g3UnmapProc);
-
-		if (faxTIFF == NULL) {
-			throw "Can not create fake input file";
-		}
-		TIFFSetMode(faxTIFF, O_RDONLY);
-		TIFFSetField(faxTIFF, TIFFTAG_IMAGEWIDTH, xsize);
-		TIFFSetField(faxTIFF, TIFFTAG_SAMPLESPERPIXEL, 1);
-		TIFFSetField(faxTIFF, TIFFTAG_BITSPERSAMPLE, 1);
-		TIFFSetField(faxTIFF, TIFFTAG_FILLORDER, fillorder_in);
-		TIFFSetField(faxTIFF, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
-		TIFFSetField(faxTIFF, TIFFTAG_PHOTOMETRIC, photometric_in);
-		TIFFSetField(faxTIFF, TIFFTAG_YRESOLUTION, resY);
-		TIFFSetField(faxTIFF, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
-
-		// NB: this must be done after directory info is setup 
-		TIFFSetField(faxTIFF, TIFFTAG_COMPRESSION, compression_in);
-		if (compression_in == COMPRESSION_CCITTFAX3)
-			TIFFSetField(faxTIFF, TIFFTAG_GROUP3OPTIONS, group3options_in);
-		else if (compression_in == COMPRESSION_CCITTFAX4)
-			TIFFSetField(faxTIFF, TIFFTAG_GROUP4OPTIONS, group4options_in);
-		
-		resX = 204;
-		if (!stretch) {
-			TIFFGetField(faxTIFF, TIFFTAG_YRESOLUTION, &resY);
-		} else {
-			resY = 196;
-		}
-
-		// decode the raw fax data
-		rows = copyFaxFile(io, handle, faxTIFF, xsize, stretch, memory);
-		if(rows <= 0) throw "Error when decoding raw fax file : check the decoder options";
-
-
-		// allocate the output dib
-		dib = FreeImage_Allocate(xsize, rows, 1);
-		unsigned pitch = FreeImage_GetPitch(dib);
-		uint32 linesize = TIFFhowmany8(xsize);
-
-		// fill the bitmap structure ...
-		// ... palette
-		RGBQUAD *pal = FreeImage_GetPalette(dib);
-		if(photometric_in == PHOTOMETRIC_MINISWHITE) {
-			pal[0].rgbRed = pal[0].rgbGreen = pal[0].rgbBlue = 255;
-			pal[1].rgbRed = pal[1].rgbGreen = pal[1].rgbBlue = 0;
-		} else {
-			pal[0].rgbRed = pal[0].rgbGreen = pal[0].rgbBlue = 0;
-			pal[1].rgbRed = pal[1].rgbGreen = pal[1].rgbBlue = 255;
-		}
-		// ... resolution
-		FreeImage_SetDotsPerMeterX(dib, (unsigned)(resX/0.0254000 + 0.5));
-		FreeImage_SetDotsPerMeterY(dib, (unsigned)(resY/0.0254000 + 0.5));
-
-		// read the decoded scanline and fill the bitmap data
-		FreeImage_SeekMemory(memory, 0, SEEK_SET);
-		BYTE *bits = FreeImage_GetScanLine(dib, rows - 1);
-		for(int k = 0; k < rows; k++) {
-			FreeImage_ReadMemory(bits, linesize, 1, memory);
-			bits -= pitch;
-		}
-
-		// free the TIFF wrapper
-		TIFFClose(faxTIFF);
-
-		// free the memory buffer
-		FreeImage_CloseMemory(memory);
-
-	} catch(const char *message) {
-		if(memory) FreeImage_CloseMemory(memory);
-		if(faxTIFF) TIFFClose(faxTIFF);
-		if(dib) FreeImage_Unload(dib);
-		FreeImage_OutputMessageProc(s_format_id, message);
-		return NULL;
-	}
-
-	return dib;
-
-}
-
-// ==========================================================
-//   Init
-// ==========================================================
-
-void DLL_CALLCONV
-InitG3(Plugin *plugin, int format_id) {
-	s_format_id = format_id;
-
-	plugin->format_proc = Format;
-	plugin->description_proc = Description;
-	plugin->extension_proc = Extension;
-	plugin->regexpr_proc = RegExpr;
-	plugin->open_proc = NULL;
-	plugin->close_proc = NULL;
-	plugin->pagecount_proc = NULL;
-	plugin->pagecapability_proc = NULL;
-	plugin->load_proc = Load;
-	plugin->save_proc = NULL;
-	plugin->validate_proc = NULL;
-	plugin->mime_proc = MimeType;
-	plugin->supports_export_bpp_proc = SupportsExportDepth;
-	plugin->supports_export_type_proc = NULL;
-	plugin->supports_icc_profiles_proc = NULL;
-}
diff --git a/Source/LibTIFF/_FI_3151_PluginTIFF.cpp b/Source/LibTIFF/_FI_3151_PluginTIFF.cpp
deleted file mode 100644
index deca588..0000000
--- a/Source/LibTIFF/_FI_3151_PluginTIFF.cpp
+++ /dev/null
@@ -1,2628 +0,0 @@
-// ==========================================================
-// TIFF Loader and Writer
-//
-// Design and implementation by 
-// - Floris van den Berg (flvdberg at wxs.nl)
-// - Hervé Drolon (drolon at infonie.fr)
-// - Markus Loibl (markus.loibl at epost.de)
-// - Luca Piergentili (l.pierge at terra.es)
-// - Detlev Vendt (detlev.vendt at brillit.de)
-// - Mihail Naydenov (mnaydenov at users.sourceforge.net)
-//
-// This file is part of FreeImage 3
-//
-// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
-// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
-// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
-// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
-// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
-// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
-// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
-// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
-// THIS DISCLAIMER.
-//
-// Use at your own risk!
-// ==========================================================
-
-#ifdef _MSC_VER 
-#pragma warning (disable : 4786) // identifier was truncated to 'number' characters
-#endif
-
-#ifdef unix
-#undef unix
-#endif
-#ifdef __unix
-#undef __unix
-#endif
-
-#include "FreeImage.h"
-#include "Utilities.h"
-#include "../LibTIFF/tiffiop.h"
-#include "../Metadata/FreeImageTag.h"
-#include "../OpenEXR/Half/half.h"
-
-#include "FreeImageIO.h"
-#include "PSDParser.h"
-
-// ----------------------------------------------------------
-//   geotiff interface (see XTIFF.cpp)
-// ----------------------------------------------------------
-
-// Extended TIFF Directory GEO Tag Support
-void XTIFFInitialize();
-
-// GeoTIFF profile
-void tiff_read_geotiff_profile(TIFF *tif, FIBITMAP *dib);
-void tiff_write_geotiff_profile(TIFF *tif, FIBITMAP *dib);
-
-// ----------------------------------------------------------
-//   exif interface (see XTIFF.cpp)
-// ----------------------------------------------------------
-
-// TIFF Exif profile
-BOOL tiff_read_exif_tags(TIFF *tif, TagLib::MDMODEL md_model, FIBITMAP *dib);
-BOOL tiff_write_exif_tags(TIFF *tif, TagLib::MDMODEL md_model, FIBITMAP *dib);
-
-// ----------------------------------------------------------
-//   LogLuv conversion functions interface (see TIFFLogLuv.cpp)
-// ----------------------------------------------------------
-
-void tiff_ConvertLineXYZToRGB(BYTE *target, BYTE *source, double stonits, int width_in_pixels);
-void tiff_ConvertLineRGBToXYZ(BYTE *target, BYTE *source, int width_in_pixels);
-
-// ----------------------------------------------------------
-
-/** Supported loading methods */
-typedef enum {
-	LoadAsRBGA			= 0, 
-	LoadAsCMYK			= 1, 
-	LoadAs8BitTrns		= 2, 
-	LoadAsGenericStrip	= 3, 
-	LoadAsTiled			= 4,
-	LoadAsLogLuv		= 5,
-	LoadAsHalfFloat		= 6
-} TIFFLoadMethod;
-
-// ----------------------------------------------------------
-//   local prototypes
-// ----------------------------------------------------------
-
-static tsize_t _tiffReadProc(thandle_t handle, tdata_t buf, tsize_t size);
-static tsize_t _tiffWriteProc(thandle_t handle, tdata_t buf, tsize_t size);
-static toff_t _tiffSeekProc(thandle_t handle, toff_t off, int whence);
-static int _tiffCloseProc(thandle_t fd);
-static int _tiffMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize);
-static void _tiffUnmapProc(thandle_t fd, tdata_t base, toff_t size);
-
-static uint16 CheckColormap(int n, uint16* r, uint16* g, uint16* b);
-static uint16 GetPhotometric(FIBITMAP *dib);
-
-static void ReadResolution(TIFF *tiff, FIBITMAP *dib);
-static void WriteResolution(TIFF *tiff, FIBITMAP *dib);
-
-static void ReadPalette(TIFF *tiff, uint16 photometric, uint16 bitspersample, FIBITMAP *dib);
-
-static FIBITMAP* CreateImageType(BOOL header_only, FREE_IMAGE_TYPE fit, int width, int height, uint16 bitspersample, uint16 samplesperpixel);
-static FREE_IMAGE_TYPE ReadImageType(TIFF *tiff, uint16 bitspersample, uint16 samplesperpixel);
-static void WriteImageType(TIFF *tiff, FREE_IMAGE_TYPE fit);
-
-static void WriteCompression(TIFF *tiff, uint16 bitspersample, uint16 samplesperpixel, uint16 photometric, int flags);
-
-static BOOL tiff_read_iptc_profile(TIFF *tiff, FIBITMAP *dib);
-static BOOL tiff_read_xmp_profile(TIFF *tiff, FIBITMAP *dib);
-static BOOL tiff_read_exif_profile(TIFF *tiff, FIBITMAP *dib);
-static void ReadMetadata(TIFF *tiff, FIBITMAP *dib);
-
-static BOOL tiff_write_iptc_profile(TIFF *tiff, FIBITMAP *dib);
-static BOOL tiff_write_xmp_profile(TIFF *tiff, FIBITMAP *dib);
-static void WriteMetadata(TIFF *tiff, FIBITMAP *dib);
-
-static TIFFLoadMethod FindLoadMethod(TIFF *tif, uint16 photometric, uint16 bitspersample, uint16 samplesperpixel, FREE_IMAGE_TYPE image_type, int flags);
-
-static void ReadThumbnail(FreeImageIO *io, fi_handle handle, void *data, TIFF *tiff, FIBITMAP *dib);
-
-
-// ==========================================================
-// Plugin Interface
-// ==========================================================
-
-static int s_format_id;
-
-typedef struct {
-    FreeImageIO *io;
-	fi_handle handle;
-	TIFF *tif;
-} fi_TIFFIO;
-
-// ----------------------------------------------------------
-//   libtiff interface 
-// ----------------------------------------------------------
-
-static tsize_t 
-_tiffReadProc(thandle_t handle, tdata_t buf, tsize_t size) {
-	fi_TIFFIO *fio = (fi_TIFFIO*)handle;
-	return fio->io->read_proc(buf, size, 1, fio->handle) * size;
-}
-
-static tsize_t
-_tiffWriteProc(thandle_t handle, tdata_t buf, tsize_t size) {
-	fi_TIFFIO *fio = (fi_TIFFIO*)handle;
-	return fio->io->write_proc(buf, size, 1, fio->handle) * size;
-}
-
-static toff_t
-_tiffSeekProc(thandle_t handle, toff_t off, int whence) {
-	fi_TIFFIO *fio = (fi_TIFFIO*)handle;
-	fio->io->seek_proc(fio->handle, off, whence);
-	return fio->io->tell_proc(fio->handle);
-}
-
-static int
-_tiffCloseProc(thandle_t fd) {
-	return 0;
-}
-
-#include <sys/stat.h>
-
-static toff_t
-_tiffSizeProc(thandle_t handle) {
-    fi_TIFFIO *fio = (fi_TIFFIO*)handle;
-    long currPos = fio->io->tell_proc(fio->handle);
-    fio->io->seek_proc(fio->handle, 0, SEEK_END);
-    long fileSize = fio->io->tell_proc(fio->handle);
-    fio->io->seek_proc(fio->handle, currPos, SEEK_SET);
-    return fileSize;
-}
-
-static int
-_tiffMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize) {
-	return 0;
-}
-
-static void
-_tiffUnmapProc(thandle_t fd, tdata_t base, toff_t size) {
-}
-
-/**
-Open a TIFF file descriptor for reading or writing
- at param handle File handle
- at param name Name of the file handle
- at param mode Specifies if the file is to be opened for reading ("r") or writing ("w")
-*/
-TIFF *
-TIFFFdOpen(thandle_t handle, const char *name, const char *mode) {
-	TIFF *tif;
-
-    // Set up the callback for extended TIFF directory tag support
-	// (see XTIFF.cpp)
-    XTIFFInitialize();	
-	
-	// Open the file; the callback will set everything up
-	tif = TIFFClientOpen(name, mode, handle,
-	    _tiffReadProc, _tiffWriteProc, _tiffSeekProc, _tiffCloseProc,
-	    _tiffSizeProc, _tiffMapProc, _tiffUnmapProc);
-
-	// Warning: tif_fd is declared as 'int' currently (see libTIFF), 
-    // may result in incorrect file pointers inside libTIFF on 
-    // 64bit machines (sizeof(int) != sizeof(long)). 
-    // Needs to be fixed within libTIFF.
-	if (tif) {
-		tif->tif_fd = (long)handle;
-	}
-
-	return tif;
-}
-
-/**
-Open a TIFF file for reading or writing
- at param name
- at param mode
-*/
-TIFF*
-TIFFOpen(const char* name, const char* mode) {
-	return 0;
-}
-
-// ----------------------------------------------------------
-//   TIFF library FreeImage-specific routines.
-// ----------------------------------------------------------
-
-tdata_t
-_TIFFmalloc(tsize_t s) {
-	return malloc(s);
-}
-
-void
-_TIFFfree(tdata_t p) {
-	free(p);
-}
-
-tdata_t
-_TIFFrealloc(tdata_t p, tsize_t s) {
-	return realloc(p, s);
-}
-
-void
-_TIFFmemset(tdata_t p, int v, tsize_t c) {
-	memset(p, v, (size_t) c);
-}
-
-void
-_TIFFmemcpy(tdata_t d, const tdata_t s, tsize_t c) {
-	memcpy(d, s, (size_t) c);
-}
-
-int
-_TIFFmemcmp(const tdata_t p1, const tdata_t p2, tsize_t c) {
-	return (memcmp(p1, p2, (size_t) c));
-}
-
-// ----------------------------------------------------------
-//   in FreeImage warnings and errors are disabled
-// ----------------------------------------------------------
-
-static void
-msdosWarningHandler(const char* module, const char* fmt, va_list ap) {
-}
-
-TIFFErrorHandler _TIFFwarningHandler = msdosWarningHandler;
-
-static void
-msdosErrorHandler(const char* module, const char* fmt, va_list ap) {
-	
-	// use this for diagnostic only (do not use otherwise, even in DEBUG mode)
-	/*
-	if (module != NULL) {
-		char msg[1024];
-		vsprintf(msg, fmt, ap);
-		FreeImage_OutputMessageProc(s_format_id, "%s: %s", module, msg);
-	}
-	*/
-}
-
-TIFFErrorHandler _TIFFerrorHandler = msdosErrorHandler;
-
-// ----------------------------------------------------------
-
-#define CVT(x)      (((x) * 255L) / ((1L<<16)-1))
-#define	SCALE(x)	(((x)*((1L<<16)-1))/255)
-
-// ==========================================================
-// Internal functions
-// ==========================================================
-
-static uint16
-CheckColormap(int n, uint16* r, uint16* g, uint16* b) {
-    while (n-- > 0) {
-        if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256) {
-			return 16;
-		}
-	}
-
-    return 8;
-}
-
-/**
-Get the TIFFTAG_PHOTOMETRIC value from the dib
-*/
-static uint16
-GetPhotometric(FIBITMAP *dib) {
-	FREE_IMAGE_COLOR_TYPE color_type = FreeImage_GetColorType(dib);
-	switch(color_type) {
-		case FIC_MINISWHITE:	// min value is white
-			return PHOTOMETRIC_MINISWHITE;
-		case FIC_MINISBLACK:	// min value is black
-			return PHOTOMETRIC_MINISBLACK;
-		case FIC_PALETTE:		// color map indexed
-			return PHOTOMETRIC_PALETTE;
-		case FIC_RGB:			// RGB color model
-		case FIC_RGBALPHA:		// RGB color model with alpha channel
-			return PHOTOMETRIC_RGB;
-		case FIC_CMYK:			// CMYK color model
-			return PHOTOMETRIC_RGB;	// default to RGB unless the save flag is set to TIFF_CMYK
-		default:
-			return PHOTOMETRIC_MINISBLACK;
-	}
-}
-
-/**
-Get the resolution from the TIFF and fill the dib with universal units
-*/
-static void 
-ReadResolution(TIFF *tiff, FIBITMAP *dib) {
-	float fResX = 300.0;
-	float fResY = 300.0;
-	uint16 resUnit = RESUNIT_INCH;
-
-	TIFFGetField(tiff, TIFFTAG_RESOLUTIONUNIT, &resUnit);
-	TIFFGetField(tiff, TIFFTAG_XRESOLUTION, &fResX);
-	TIFFGetField(tiff, TIFFTAG_YRESOLUTION, &fResY);
-	
-	// If we don't have a valid resolution unit and valid resolution is specified then assume inch
-	if (resUnit == RESUNIT_NONE && fResX > 0.0 && fResY > 0.0) {
-		resUnit = RESUNIT_INCH;
-	}
-	if (resUnit == RESUNIT_INCH) {
-		FreeImage_SetDotsPerMeterX(dib, (unsigned) (fResX/0.0254000 + 0.5));
-		FreeImage_SetDotsPerMeterY(dib, (unsigned) (fResY/0.0254000 + 0.5));
-	} else if(resUnit == RESUNIT_CENTIMETER) {
-		FreeImage_SetDotsPerMeterX(dib, (unsigned) (fResX*100.0 + 0.5));
-		FreeImage_SetDotsPerMeterY(dib, (unsigned) (fResY*100.0 + 0.5));
-	}
-}
-
-/**
-Set the resolution to the TIFF using english units
-*/
-static void 
-WriteResolution(TIFF *tiff, FIBITMAP *dib) {
-	double res;
-
-	TIFFSetField(tiff, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
-
-	res = (unsigned long) (0.5 + 0.0254 * FreeImage_GetDotsPerMeterX(dib));
-	TIFFSetField(tiff, TIFFTAG_XRESOLUTION, res);
-
-	res = (unsigned long) (0.5 + 0.0254 * FreeImage_GetDotsPerMeterY(dib));
-	TIFFSetField(tiff, TIFFTAG_YRESOLUTION, res);
-}
-
-/**
-Fill the dib palette according to the TIFF photometric
-*/
-static void 
-ReadPalette(TIFF *tiff, uint16 photometric, uint16 bitspersample, FIBITMAP *dib) {
-	RGBQUAD *pal = FreeImage_GetPalette(dib);
-
-	switch(photometric) {
-		case PHOTOMETRIC_MINISBLACK:	// bitmap and greyscale image types
-		case PHOTOMETRIC_MINISWHITE:
-			// Monochrome image
-
-			if (bitspersample == 1) {
-				if (photometric == PHOTOMETRIC_MINISWHITE) {
-					pal[0].rgbRed = pal[0].rgbGreen = pal[0].rgbBlue = 255;
-					pal[1].rgbRed = pal[1].rgbGreen = pal[1].rgbBlue = 0;
-				} else {
-					pal[0].rgbRed = pal[0].rgbGreen = pal[0].rgbBlue = 0;
-					pal[1].rgbRed = pal[1].rgbGreen = pal[1].rgbBlue = 255;
-				}
-
-			} else if ((bitspersample == 4) ||(bitspersample == 8)) {
-				// need to build the scale for greyscale images
-				int ncolors = FreeImage_GetColorsUsed(dib);
-
-				if (photometric == PHOTOMETRIC_MINISBLACK) {
-					for (int i = 0; i < ncolors; i++) {
-						pal[i].rgbRed	=
-						pal[i].rgbGreen =
-						pal[i].rgbBlue	= (BYTE)(i*(255/(ncolors-1)));
-					}
-				} else {
-					for (int i = 0; i < ncolors; i++) {
-						pal[i].rgbRed	=
-						pal[i].rgbGreen =
-						pal[i].rgbBlue	= (BYTE)(255-i*(255/(ncolors-1)));
-					}
-				}
-			}
-
-			break;
-
-		case PHOTOMETRIC_PALETTE:	// color map indexed
-			uint16 *red;
-			uint16 *green;
-			uint16 *blue;
-			
-			TIFFGetField(tiff, TIFFTAG_COLORMAP, &red, &green, &blue); 
-
-			// load the palette in the DIB
-
-			if (CheckColormap(1<<bitspersample, red, green, blue) == 16) {
-				for (int i = (1 << bitspersample) - 1; i >= 0; i--) {
-					pal[i].rgbRed =(BYTE) CVT(red[i]);
-					pal[i].rgbGreen = (BYTE) CVT(green[i]);
-					pal[i].rgbBlue = (BYTE) CVT(blue[i]);           
-				}
-			} else {
-				for (int i = (1 << bitspersample) - 1; i >= 0; i--) {
-					pal[i].rgbRed = (BYTE) red[i];
-					pal[i].rgbGreen = (BYTE) green[i];
-					pal[i].rgbBlue = (BYTE) blue[i];        
-				}
-			}
-
-			break;
-	}
-}
-
-/** 
-Allocate a FIBITMAP
- at param header_only If TRUE, allocate a 'header only' FIBITMAP, otherwise allocate a full FIBITMAP
- at param fit Image type
- at param width Image width in pixels
- at param height Image height in pixels
- at param bitspersample # bits per sample
- at param samplesperpixel # samples per pixel
- at return Returns the allocated image if successful, returns NULL otherwise
-*/
-static FIBITMAP* 
-CreateImageType(BOOL header_only, FREE_IMAGE_TYPE fit, int width, int height, uint16 bitspersample, uint16 samplesperpixel) {
-	FIBITMAP *dib = NULL;
-
-	if((width < 0) || (height < 0)) {
-		// check for malicious images
-		return NULL;
-	}
-
-	int bpp = bitspersample * samplesperpixel;
-
-	if(fit == FIT_BITMAP) {
-		// standard bitmap type 
-
-		if(bpp == 16) {
-			
-			if((samplesperpixel == 2) && (bitspersample == 8)) {
-				// 8-bit indexed + 8-bit alpha channel -> convert to 8-bit transparent
-				dib = FreeImage_AllocateHeader(header_only, width, height, 8);
-			} else {
-				// 16-bit RGB -> expect it to be 565
-				dib = FreeImage_AllocateHeader(header_only, width, height, bpp, FI16_565_RED_MASK, FI16_565_GREEN_MASK, FI16_565_BLUE_MASK);
-			}
-			
-		}
-		else {
-
-			dib = FreeImage_AllocateHeader(header_only, width, height, MIN(bpp, 32), FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
-		}
-
-
-	} else {
-		// other bitmap types
-		
-		dib = FreeImage_AllocateHeaderT(header_only, fit, width, height, bpp);
-	}
-
-	return dib;
-}
-
-/** 
-Read the TIFFTAG_SAMPLEFORMAT tag and convert to FREE_IMAGE_TYPE
- at param tiff LibTIFF TIFF Handle
- at param bitspersample # bit per sample
- at param samplesperpixel # samples per pixel
- at return Returns the image type as a FREE_IMAGE_TYPE value
-*/
-static FREE_IMAGE_TYPE 
-ReadImageType(TIFF *tiff, uint16 bitspersample, uint16 samplesperpixel) {
-	uint16 sampleformat = 0;
-	FREE_IMAGE_TYPE fit = FIT_BITMAP ; 
-
-	uint16 bpp = bitspersample * samplesperpixel;
-
-	// try the sampleformat tag
-    if(TIFFGetField(tiff, TIFFTAG_SAMPLEFORMAT, &sampleformat)) {
-
-        switch (sampleformat) {
-			case SAMPLEFORMAT_UINT:
-				switch (bpp) {
-					case 1:
-					case 4:
-					case 8:
-					case 24:
-						fit = FIT_BITMAP;
-						break;
-					case 16:
-						// 8-bit + alpha or 16-bit greyscale
-						if(samplesperpixel == 2) {
-							fit = FIT_BITMAP;
-						} else {
-							fit = FIT_UINT16;
-						}
-						break;
-					case 32:
-						if(samplesperpixel == 4) {
-							fit = FIT_BITMAP;
-						} else {
-							fit = FIT_UINT32;
-						}
-						break;
-					case 48:
-						if(samplesperpixel == 3) {
-							fit = FIT_RGB16;
-						}
-						break;
-					case 64:
-						if(samplesperpixel == 4) {
-							fit = FIT_RGBA16;
-						}
-						break;
-				}
-				break;
-
-			case SAMPLEFORMAT_INT:
-				switch (bpp) {
-					case 16:
-						if(samplesperpixel == 3) {
-							fit = FIT_BITMAP;
-						} else {
-							fit = FIT_INT16;
-						}
-						break;
-					case 32:
-						fit = FIT_INT32;
-						break;
-				}
-				break;
-
-			case SAMPLEFORMAT_IEEEFP:
-				switch (bpp) {
-					case 32:
-						fit = FIT_FLOAT;
-						break;
-					case 48:
-						// 3 x half float => convert to RGBF
-						if((samplesperpixel == 3) && (bitspersample == 16)) {
-							fit = FIT_RGBF;
-						}
-						break;
-					case 64:
-						if(samplesperpixel == 2) {
-							fit = FIT_FLOAT;
-						} else {
-							fit = FIT_DOUBLE;
-						}
-						break;
-					case 96:
-						fit = FIT_RGBF;
-						break;
-					default:
-						if(bpp >= 128) {
-							fit = FIT_RGBAF;
-						}
-					break;
-				}
-				break;
-			case SAMPLEFORMAT_COMPLEXIEEEFP:
-				switch (bpp) {
-					case 64:
-						break;
-					case 128:
-						fit = FIT_COMPLEX;
-						break;
-				}
-				break;
-
-			}
-    }
-	// no sampleformat tag : assume SAMPLEFORMAT_UINT
-	else {
-		if(samplesperpixel == 1) {
-			switch (bpp) {
-				case 16:
-					fit = FIT_UINT16;
-					break;
-					
-				case 32:
-					fit = FIT_UINT32;
-					break;
-			}
-		}
-		else if(samplesperpixel == 3) {
-			if(bpp == 48) fit = FIT_RGB16;
-		}
-		else if(samplesperpixel >= 4) { 
-			if(bitspersample == 16) {
-				fit = FIT_RGBA16;
-			}
-		}
-
-	}
-
-    return fit;
-}
-
-/** 
-Convert FREE_IMAGE_TYPE and write TIFFTAG_SAMPLEFORMAT
- at param tiff LibTIFF TIFF Handle
- at param fit Image type as a FREE_IMAGE_TYPE value
-*/
-static void 
-WriteImageType(TIFF *tiff, FREE_IMAGE_TYPE fit) {
-	switch(fit) {
-		case FIT_BITMAP:	// standard image: 1-, 4-, 8-, 16-, 24-, 32-bit
-		case FIT_UINT16:	// array of unsigned short	: unsigned 16-bit
-		case FIT_UINT32:	// array of unsigned long	: unsigned 32-bit
-		case FIT_RGB16:		// 48-bit RGB image			: 3 x 16-bit
-		case FIT_RGBA16:	// 64-bit RGBA image		: 4 x 16-bit
-			TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
-			break;
-
-		case FIT_INT16:		// array of short	: signed 16-bit
-		case FIT_INT32:		// array of long	: signed 32-bit
-			TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT);
-			break;
-
-		case FIT_FLOAT:		// array of float	: 32-bit
-		case FIT_DOUBLE:	// array of double	: 64-bit
-		case FIT_RGBF:		// 96-bit RGB float image	: 3 x 32-bit IEEE floating point
-		case FIT_RGBAF:		// 128-bit RGBA float image	: 4 x 32-bit IEEE floating point
-			TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);
-			break;
-
-		case FIT_COMPLEX:	// array of COMPLEX : 2 x 64-bit
-			TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_COMPLEXIEEEFP);
-			break;
-	}
-}
-
-/**
-Select the compression algorithm
- at param tiff LibTIFF TIFF Handle
- at param 
-*/
-static void 
-WriteCompression(TIFF *tiff, uint16 bitspersample, uint16 samplesperpixel, uint16 photometric, int flags) {
-	uint16 compression;
-	uint16 bitsperpixel = bitspersample * samplesperpixel;
-
-	if(photometric == PHOTOMETRIC_LOGLUV) {
-		compression = COMPRESSION_SGILOG;
-	} else if ((flags & TIFF_PACKBITS) == TIFF_PACKBITS) {
-		compression = COMPRESSION_PACKBITS;
-	} else if ((flags & TIFF_DEFLATE) == TIFF_DEFLATE) {
-		compression = COMPRESSION_DEFLATE;
-	} else if ((flags & TIFF_ADOBE_DEFLATE) == TIFF_ADOBE_DEFLATE) {
-		compression = COMPRESSION_ADOBE_DEFLATE;
-	} else if ((flags & TIFF_NONE) == TIFF_NONE) {
-		compression = COMPRESSION_NONE;
-	} else if ((bitsperpixel == 1) && ((flags & TIFF_CCITTFAX3) == TIFF_CCITTFAX3)) {
-		compression = COMPRESSION_CCITTFAX3;
-	} else if ((bitsperpixel == 1) && ((flags & TIFF_CCITTFAX4) == TIFF_CCITTFAX4)) {
-		compression = COMPRESSION_CCITTFAX4;
-	} else if ((flags & TIFF_LZW) == TIFF_LZW) {
-		compression = COMPRESSION_LZW;
-	} else if ((flags & TIFF_JPEG) == TIFF_JPEG) {
-		if(((bitsperpixel == 8) && (photometric != PHOTOMETRIC_PALETTE)) || (bitsperpixel == 24)) {
-			compression = COMPRESSION_JPEG;
-			// RowsPerStrip must be multiple of 8 for JPEG
-			uint32 rowsperstrip = (uint32) -1;
-			rowsperstrip = TIFFDefaultStripSize(tiff, rowsperstrip);
-            rowsperstrip = rowsperstrip + (8 - (rowsperstrip % 8));
-			// overwrite previous RowsPerStrip
-			TIFFSetField(tiff, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
-		} else {
-			// default to LZW
-			compression = COMPRESSION_LZW;
-		}
-	}
-	else {
-		// default compression scheme
-
-		switch(bitsperpixel) {
-			case 1:
-				compression = COMPRESSION_CCITTFAX4;
-				break;
-
-			case 4:
-			case 8:
-			case 16:
-			case 24:
-			case 32:
-				compression = COMPRESSION_LZW;
-				break;
-			case 48:
-			case 64:
-			case 96:
-			case 128:
-				compression = COMPRESSION_LZW;
-				break;
-
-			default :
-				compression = COMPRESSION_NONE;
-				break;
-		}
-	}
-
-	TIFFSetField(tiff, TIFFTAG_COMPRESSION, compression);
-
-	if(compression == COMPRESSION_LZW) {
-		// This option is only meaningful with LZW compression: a predictor value of 2 
-		// causes each scanline of the output image to undergo horizontal differencing 
-		// before it is encoded; a value of 1 forces each scanline to be encoded without differencing.
-
-		// Found on LibTIFF mailing list : 
-		// LZW without differencing works well for 1-bit images, 4-bit grayscale images, 
-		// and many palette-color images. But natural 24-bit color images and some 8-bit 
-		// grayscale images do much better with differencing.
-
-		if((bitspersample == 8) || (bitspersample == 16)) {
-			if ((bitsperpixel >= 8) && (photometric != PHOTOMETRIC_PALETTE)) {
-				TIFFSetField(tiff, TIFFTAG_PREDICTOR, 2);
-			} else {
-				TIFFSetField(tiff, TIFFTAG_PREDICTOR, 1);
-			}
-		} else {
-			TIFFSetField(tiff, TIFFTAG_PREDICTOR, 1);
-		}
-	}
-	else if(compression == COMPRESSION_CCITTFAX3) {
-		// try to be compliant with the TIFF Class F specification
-		// that documents the TIFF tags specific to FAX applications
-		// see http://palimpsest.stanford.edu/bytopic/imaging/std/tiff-f.html
-		uint32 group3options = GROUP3OPT_2DENCODING | GROUP3OPT_FILLBITS;	
-		TIFFSetField(tiff, TIFFTAG_GROUP3OPTIONS, group3options);	// 2d-encoded, has aligned EOL
-		TIFFSetField(tiff, TIFFTAG_FILLORDER, FILLORDER_LSB2MSB);	// lsb-to-msb fillorder
-	}
-}
-
-// ==========================================================
-// TIFF metadata routines
-// ==========================================================
-
-/**
-	Read the TIFFTAG_RICHTIFFIPTC tag (IPTC/NAA or Adobe Photoshop profile)
-*/
-static BOOL 
-tiff_read_iptc_profile(TIFF *tiff, FIBITMAP *dib) {
-	BYTE *profile = NULL;
-	uint32 profile_size = 0;
-
-    if(TIFFGetField(tiff,TIFFTAG_RICHTIFFIPTC, &profile_size, &profile) == 1) {
-		if (TIFFIsByteSwapped(tiff) != 0) {
-			TIFFSwabArrayOfLong((uint32 *) profile, (unsigned long)profile_size);
-		}
-
-		return read_iptc_profile(dib, profile, 4 * profile_size);
-	}
-
-	return FALSE;
-}
-
-/**
-	Read the TIFFTAG_XMLPACKET tag (XMP profile)
-	@param dib Input FIBITMAP
-	@param tiff LibTIFF TIFF handle
-	@return Returns TRUE if successful, FALSE otherwise
-*/
-static BOOL  
-tiff_read_xmp_profile(TIFF *tiff, FIBITMAP *dib) {
-	BYTE *profile = NULL;
-	uint32 profile_size = 0;
-
-	if (TIFFGetField(tiff, TIFFTAG_XMLPACKET, &profile_size, &profile) == 1) {
-		// create a tag
-		FITAG *tag = FreeImage_CreateTag();
-		if(!tag) return FALSE;
-
-		FreeImage_SetTagID(tag, TIFFTAG_XMLPACKET);	// 700
-		FreeImage_SetTagKey(tag, g_TagLib_XMPFieldName);
-		FreeImage_SetTagLength(tag, profile_size);
-		FreeImage_SetTagCount(tag, profile_size);
-		FreeImage_SetTagType(tag, FIDT_ASCII);
-		FreeImage_SetTagValue(tag, profile);
-
-		// store the tag
-		FreeImage_SetMetadata(FIMD_XMP, dib, FreeImage_GetTagKey(tag), tag);
-
-		// destroy the tag
-		FreeImage_DeleteTag(tag);
-
-		return TRUE;
-	}
-
-	return FALSE;
-}
-
-/**
-	Read the Exif profile embedded in a TIFF
-	@param dib Input FIBITMAP
-	@param tiff LibTIFF TIFF handle
-	@return Returns TRUE if successful, FALSE otherwise
-*/
-static BOOL 
-tiff_read_exif_profile(TIFF *tiff, FIBITMAP *dib) {
-	BOOL bResult = FALSE;
-    uint32 exif_offset = 0;
-
-	// read EXIF-TIFF tags
-	bResult = tiff_read_exif_tags(tiff, TagLib::EXIF_MAIN, dib);
-
-	// get the IFD offset
-	if(TIFFGetField(tiff, TIFFTAG_EXIFIFD, &exif_offset)) {
-
-		// read EXIF tags
-		if(!TIFFReadEXIFDirectory(tiff, exif_offset)) {
-			return FALSE;
-		}
-
-		// read all known exif tags
-		bResult = tiff_read_exif_tags(tiff, TagLib::EXIF_EXIF, dib);
-	}
-
-	return bResult;
-}
-
-/**
-Read TIFF special profiles
-*/
-static void 
-ReadMetadata(TIFF *tiff, FIBITMAP *dib) {
-
-	// IPTC/NAA
-	tiff_read_iptc_profile(tiff, dib);
-
-	// Adobe XMP
-	tiff_read_xmp_profile(tiff, dib);
-
-	// GeoTIFF
-	tiff_read_geotiff_profile(tiff, dib);
-
-	// Exif-TIFF
-	tiff_read_exif_profile(tiff, dib);
-}
-
-// ----------------------------------------------------------
-
-/**
-	Write the TIFFTAG_RICHTIFFIPTC tag (IPTC/NAA or Adobe Photoshop profile)
-*/
-static BOOL 
-tiff_write_iptc_profile(TIFF *tiff, FIBITMAP *dib) {
-	if(FreeImage_GetMetadataCount(FIMD_IPTC, dib)) {
-		BYTE *profile = NULL;
-		uint32 profile_size = 0;
-		// create a binary profile
-		if(write_iptc_profile(dib, &profile, &profile_size)) {
-			uint32 iptc_size = profile_size;
-			iptc_size += (4-(iptc_size & 0x03)); // Round up for long word alignment
-			BYTE *iptc_profile = (BYTE*)malloc(iptc_size);
-			if(!iptc_profile) {
-				free(profile);
-				return FALSE;
-			}
-			memset(iptc_profile, 0, iptc_size);
-			memcpy(iptc_profile, profile, profile_size);
-			if (TIFFIsByteSwapped(tiff)) {
-				TIFFSwabArrayOfLong((uint32 *) iptc_profile, (unsigned long)iptc_size/4);
-			}
-			// Tag is type TIFF_LONG so byte length is divided by four
-			TIFFSetField(tiff, TIFFTAG_RICHTIFFIPTC, iptc_size/4, iptc_profile);
-			// release the profile data
-			free(iptc_profile);
-			free(profile);
-
-			return TRUE;
-		}
-	}
-
-	return FALSE;
-}
-
-/**
-	Write the TIFFTAG_XMLPACKET tag (XMP profile)
-	@param dib Input FIBITMAP
-	@param tiff LibTIFF TIFF handle
-	@return Returns TRUE if successful, FALSE otherwise
-*/
-static BOOL  
-tiff_write_xmp_profile(TIFF *tiff, FIBITMAP *dib) {
-	FITAG *tag_xmp = NULL;
-	FreeImage_GetMetadata(FIMD_XMP, dib, g_TagLib_XMPFieldName, &tag_xmp);
-
-	if(tag_xmp && (NULL != FreeImage_GetTagValue(tag_xmp))) {
-		
-		TIFFSetField(tiff, TIFFTAG_XMLPACKET, (uint32)FreeImage_GetTagLength(tag_xmp), (BYTE*)FreeImage_GetTagValue(tag_xmp));
-
-		return TRUE;		
-	}
-
-	return FALSE;
-}
-
-/**
-	Write the Exif profile to TIFF
-	@param dib Input FIBITMAP
-	@param tiff LibTIFF TIFF handle
-	@return Returns TRUE if successful, FALSE otherwise
-*/
-static BOOL
-tiff_write_exif_profile(TIFF *tiff, FIBITMAP *dib) {
-	BOOL bResult = FALSE;
-	uint32 exif_offset = 0;
-	
-	// write EXIF_MAIN tags, EXIF_EXIF not supported yet
-	bResult = tiff_write_exif_tags(tiff, TagLib::EXIF_MAIN, dib);
-
-	return bResult;
-}
-
-/**
-Write TIFF special profiles
-*/
-static void 
-WriteMetadata(TIFF *tiff, FIBITMAP *dib) {
-	// IPTC
-	tiff_write_iptc_profile(tiff, dib);
-	
-	// Adobe XMP
-	tiff_write_xmp_profile(tiff, dib);
-	
-	// EXIF_MAIN tags
-	tiff_write_exif_profile(tiff, dib);
-	
-	// GeoTIFF tags
-	tiff_write_geotiff_profile(tiff, dib);
-}
-
-// ==========================================================
-// Plugin Implementation
-// ==========================================================
-
-static const char * DLL_CALLCONV
-Format() {
-	return "TIFF";
-}
-
-static const char * DLL_CALLCONV
-Description() {
-	return "Tagged Image File Format";
-}
-
-static const char * DLL_CALLCONV
-Extension() {
-	return "tif,tiff";
-}
-
-static const char * DLL_CALLCONV
-RegExpr() {
-	return "^[MI][MI][\\x01*][\\x01*]";
-}
-
-static const char * DLL_CALLCONV
-MimeType() {
-	return "image/tiff";
-}
-
-static BOOL DLL_CALLCONV
-Validate(FreeImageIO *io, fi_handle handle) {	
-	BYTE tiff_id1[] = { 0x49, 0x49, 0x2A, 0x00 };
-	BYTE tiff_id2[] = { 0x4D, 0x4D, 0x00, 0x2A };
-	BYTE signature[4] = { 0, 0, 0, 0 };
-
-	io->read_proc(signature, 1, 4, handle);
-
-	if(memcmp(tiff_id1, signature, 4) == 0)
-		return TRUE;
-
-	if(memcmp(tiff_id2, signature, 4) == 0)
-		return TRUE;
-
-	return FALSE;
-}
-
-static BOOL DLL_CALLCONV
-SupportsExportDepth(int depth) {
-	return (
-			(depth == 1)  ||
-			(depth == 4)  ||
-			(depth == 8)  ||
-			(depth == 24) ||
-			(depth == 32)
-		);
-}
-
-static BOOL DLL_CALLCONV 
-SupportsExportType(FREE_IMAGE_TYPE type) {
-	return (
-		(type == FIT_BITMAP)  ||
-		(type == FIT_UINT16)  ||
-		(type == FIT_INT16)   ||
-		(type == FIT_UINT32)  ||
-		(type == FIT_INT32)   ||
-		(type == FIT_FLOAT)   ||
-		(type == FIT_DOUBLE)  ||
-		(type == FIT_COMPLEX) || 
-		(type == FIT_RGB16)   || 
-		(type == FIT_RGBA16)  || 
-		(type == FIT_RGBF)    ||
-		(type == FIT_RGBAF)
-	);
-}
-
-static BOOL DLL_CALLCONV
-SupportsICCProfiles() {
-	return TRUE;
-}
-
-static BOOL DLL_CALLCONV
-SupportsNoPixels() {
-	return TRUE;
-} 
-
-// ----------------------------------------------------------
-
-static void * DLL_CALLCONV
-Open(FreeImageIO *io, fi_handle handle, BOOL read) {
-	// wrapper for TIFF I/O
-	fi_TIFFIO *fio = (fi_TIFFIO*)malloc(sizeof(fi_TIFFIO));
-	if(!fio) return NULL;
-	fio->io = io;
-	fio->handle = handle;
-
-	if (read) {
-		fio->tif = TIFFFdOpen((thandle_t)fio, "", "r");
-	} else {
-		fio->tif = TIFFFdOpen((thandle_t)fio, "", "w");
-	}
-	if(fio->tif == NULL) {
-		free(fio);
-		FreeImage_OutputMessageProc(s_format_id, "Error while opening TIFF: data is invalid");
-		return NULL;
-	}
-	return fio;
-}
-
-static void DLL_CALLCONV
-Close(FreeImageIO *io, fi_handle handle, void *data) {
-	if(data) {
-		fi_TIFFIO *fio = (fi_TIFFIO*)data;
-		TIFFClose(fio->tif);
-		free(fio);
-	}
-}
-
-// ----------------------------------------------------------
-
-static int DLL_CALLCONV
-PageCount(FreeImageIO *io, fi_handle handle, void *data) {
-	if(data) {
-		fi_TIFFIO *fio = (fi_TIFFIO*)data;
-		TIFF *tif = (TIFF *)fio->tif;
-		int nr_ifd = 0;
-
-		do {
-			nr_ifd++;
-		} while (TIFFReadDirectory(tif));
-				
-		return nr_ifd;
-	}
-
-	return 0;
-}
-
-// ----------------------------------------------------------
-
-/**
-check for uncommon bitspersample values (e.g. 10, 12, ...)
- at param photometric TIFFTAG_PHOTOMETRIC tiff tag
- at param bitspersample TIFFTAG_BITSPERSAMPLE tiff tag
- at param samplesperpixel TIFFTAG_SAMPLESPERPIXEL tiff tag
- at return Returns FALSE if a uncommon bit-depth is encountered, returns TRUE otherwise
-*/
-static BOOL 
-IsValidBitsPerSample(uint16 photometric, uint16 bitspersample, uint16 samplesperpixel) {
-
-	switch(bitspersample) {
-		case 1:
-		case 4:
-			if((photometric == PHOTOMETRIC_MINISWHITE) || (photometric == PHOTOMETRIC_MINISBLACK) || (photometric == PHOTOMETRIC_PALETTE)) { 
-				return TRUE;
-			} else {
-				return FALSE;
-			}
-			break;
-		case 8:
-			return TRUE;
-		case 16:
-			if(photometric != PHOTOMETRIC_PALETTE) { 
-				return TRUE;
-			} else {
-				return FALSE;
-			}
-			break;
-		case 32:
-			return TRUE;
-		case 64:
-		case 128:
-			if(photometric == PHOTOMETRIC_MINISBLACK) { 
-				return TRUE;
-			} else {
-				return FALSE;
-			}
-			break;
-		default:
-			return FALSE;
-	}
-}
-
-static TIFFLoadMethod  
-FindLoadMethod(TIFF *tif, FREE_IMAGE_TYPE image_type, int flags) {
-	uint16 bitspersample	= (uint16)-1;
-	uint16 samplesperpixel	= (uint16)-1;
-	uint16 photometric		= (uint16)-1;
-	uint16 planar_config	= (uint16)-1;
-
-	TIFFLoadMethod loadMethod = LoadAsGenericStrip;
-
-	TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric);
-	TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
-	TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
-	TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planar_config);
-
-	BOOL bIsTiled = (TIFFIsTiled(tif) == 0) ? FALSE:TRUE;
-
-	switch(photometric) {
-		// convert to 24 or 32 bits RGB if the image is full color
-		case PHOTOMETRIC_RGB:
-			if((image_type == FIT_RGB16) || (image_type == FIT_RGBA16)) {
-				// load 48-bit RGB and 64-bit RGBA without conversion 
-				loadMethod = LoadAsGenericStrip;
-			} 
-			else if(image_type == FIT_RGBF) {
-				if((samplesperpixel == 3) && (bitspersample == 16)) {
-					// load 3 x 16-bit half as RGBF
-					loadMethod = LoadAsHalfFloat;
-				}
-			}
-			break;
-		case PHOTOMETRIC_YCBCR:
-		case PHOTOMETRIC_CIELAB:
-		case PHOTOMETRIC_ICCLAB:
-		case PHOTOMETRIC_ITULAB:
-			loadMethod = LoadAsRBGA;
-			break;
-		case PHOTOMETRIC_LOGLUV:
-			loadMethod = LoadAsLogLuv;
-			break;
-		case PHOTOMETRIC_SEPARATED:
-			// if image is PHOTOMETRIC_SEPARATED _and_ comes with an ICC profile, 
-			// then the image should preserve its original (CMYK) colour model and 
-			// should be read as CMYK (to keep the match of pixel and profile and 
-			// to avoid multiple conversions. Conversion can be done by changing 
-			// the profile from it's original CMYK to an RGB profile with an 
-			// apropriate color management system. Works with non-tiled TIFFs.
-			if(!bIsTiled) {
-				loadMethod = LoadAsCMYK;
-			}
-			break;
-		case PHOTOMETRIC_MINISWHITE:
-		case PHOTOMETRIC_MINISBLACK:
-		case PHOTOMETRIC_PALETTE:
-			// When samplesperpixel = 2 and bitspersample = 8, set the image as a
-			// 8-bit indexed image + 8-bit alpha layer image
-			// and convert to a 8-bit image with a transparency table
-			if((samplesperpixel > 1) && (bitspersample == 8)) {
-				loadMethod = LoadAs8BitTrns;
-			} else {
-				loadMethod = LoadAsGenericStrip;
-			}
-			break;
-		default:
-			loadMethod = LoadAsGenericStrip;
-			break;
-	}
-
-	if((loadMethod == LoadAsGenericStrip) && bIsTiled) {
-		loadMethod = LoadAsTiled;
-	}
-
-	return loadMethod;
-}
-
-// ==========================================================
-// TIFF thumbnail routines
-// ==========================================================
-
-static FIBITMAP * DLL_CALLCONV
-Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data);
-
-/**
-Read embedded thumbnail
-*/
-static void 
-ReadThumbnail(FreeImageIO *io, fi_handle handle, void *data, TIFF *tiff, FIBITMAP *dib) {
-	FIBITMAP* thumbnail = NULL;
-
-	// read exif thumbnail (IFD 1) ...
-
-	uint32 exif_offset = 0;
-	if(TIFFGetField(tiff, TIFFTAG_EXIFIFD, &exif_offset)) {
-
-		if(TIFFLastDirectory(tiff) != 0) {
-			// save current position
-			long tell_pos = io->tell_proc(handle);
-			tdir_t cur_dir = TIFFCurrentDirectory(tiff);
-
-			// load the thumbnail
-			int page = 1; 
-			int flags = TIFF_DEFAULT;
-			thumbnail = Load(io, handle, page, flags, data);
-			// store the thumbnail (remember to release it later ...)
-			FreeImage_SetThumbnail(dib, thumbnail);
-
-			// restore current position
-			io->seek_proc(handle, tell_pos, SEEK_SET);
-			TIFFSetDirectory(tiff, cur_dir);
-		}
-	}
-
-	// ... or read the first subIFD
-
-	if(!thumbnail) {
-		uint16 subIFD_count = 0;
-		uint32* subIFD_offsets = NULL;
-		// ### Theoretically this should also read the first subIFD from a Photoshop-created file with "pyramid".
-		// It does not however - the tag is there (using Tag Viewer app) but libtiff refuses to read it
-		if(TIFFGetField(tiff, TIFFTAG_SUBIFD, &subIFD_count, &subIFD_offsets)) {
-			if(subIFD_count > 0) {
-				// save current position
-				long tell_pos = io->tell_proc(handle);
-				tdir_t cur_dir = TIFFCurrentDirectory(tiff);
-				if(TIFFSetSubDirectory(tiff, subIFD_offsets[0])) {
-					// load the thumbnail
-					int page = -1; 
-					int flags = TIFF_DEFAULT;
-					thumbnail = Load(io, handle, page, flags, data);
-					// store the thumbnail (remember to release it later ...)
-					FreeImage_SetThumbnail(dib, thumbnail);
-				}
-				// restore current position
-				io->seek_proc(handle, tell_pos, SEEK_SET);
-				TIFFSetDirectory(tiff, cur_dir);
-			}
-		}
-	}
-	
-	// ... or read Photoshop thumbnail
-
-	if(!thumbnail) {
-		uint32 ps_size = 0;
-		void *ps_data = NULL;
-
-		if(TIFFGetField(tiff, TIFFTAG_PHOTOSHOP, &ps_size, &ps_data)) {
-			FIMEMORY *handle = FreeImage_OpenMemory((BYTE*)ps_data, ps_size);
-
-			FreeImageIO io;
-			SetMemoryIO(&io);
-		
-			psdParser parser;
-			parser.ReadImageResources(&io, handle, ps_size);
-
-			FreeImage_SetThumbnail(dib, parser.GetThumbnail());
-			
-			FreeImage_CloseMemory(handle);
-		}
-		
-	}
-
-	// release thumbnail
-	FreeImage_Unload(thumbnail);
-}
-
-// --------------------------------------------------------------------------
-
-static FIBITMAP * DLL_CALLCONV
-Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
-	if (!handle || !data ) {
-		return NULL;
-	}
-	
-	TIFF   *tif = NULL;
-	uint32 height = 0; 
-	uint32 width = 0; 
-	uint16 bitspersample = 1;
-	uint16 samplesperpixel = 1;
-	uint32 rowsperstrip = (uint32)-1;  
-	uint16 photometric = PHOTOMETRIC_MINISWHITE;
-	uint16 compression = (uint16)-1;
-	uint16 planar_config;
-
-	FIBITMAP *dib = NULL;
-	uint32 iccSize = 0;		// ICC profile length
-	void *iccBuf = NULL;	// ICC profile data		
-
-	const BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS;
-	
-	try {	
-		fi_TIFFIO *fio = (fi_TIFFIO*)data;
-		tif = fio->tif;
-
-		if (page != -1) {
-			if (!tif || !TIFFSetDirectory(tif, (tdir_t)page)) {
-				throw "Error encountered while opening TIFF file";			
-			}
-		}
-		
-		const BOOL asCMYK = (flags & TIFF_CMYK) == TIFF_CMYK;
-
-		// first, get the photometric, the compression and basic metadata
-		// ---------------------------------------------------------------------------------
-
-		TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric);
-		TIFFGetField(tif, TIFFTAG_COMPRESSION, &compression);
-
-		// check for HDR formats
-		// ---------------------------------------------------------------------------------
-
-		if(photometric == PHOTOMETRIC_LOGLUV) {
-			// check the compression
-			if(compression != COMPRESSION_SGILOG && compression != COMPRESSION_SGILOG24) {
-				throw "Only support SGILOG compressed LogLuv data";
-			}
-			// set decoder to output in IEEE 32-bit float XYZ values
-			TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_FLOAT);
-		}
-
-		// ---------------------------------------------------------------------------------
-
-		TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
-		TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
-		TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
-		TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
-		TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);   			
-		TIFFGetField(tif, TIFFTAG_ICCPROFILE, &iccSize, &iccBuf);
-		TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planar_config);
-
-		// check for unsupported formats
-		// ---------------------------------------------------------------------------------
-
-		if(IsValidBitsPerSample(photometric, bitspersample, samplesperpixel) == FALSE) {
-			FreeImage_OutputMessageProc(s_format_id, 
-				"Unable to handle this format: bitspersample = %d, samplesperpixel = %d, photometric = %d", 
-				(int)bitspersample, (int)samplesperpixel, (int)photometric);
-			throw (char*)NULL;
-		}
-
-		// ---------------------------------------------------------------------------------
-
-		// get image data type
-
-		FREE_IMAGE_TYPE image_type = ReadImageType(tif, bitspersample, samplesperpixel);
-
-		// get the most appropriate loading method
-
-		TIFFLoadMethod loadMethod = FindLoadMethod(tif, image_type, flags);
-
-		// ---------------------------------------------------------------------------------
-
-		if(loadMethod == LoadAsRBGA) {
-			// ---------------------------------------------------------------------------------
-			// RGB[A] loading using the TIFFReadRGBAImage() API
-			// ---------------------------------------------------------------------------------
-
-			BOOL has_alpha = FALSE;   
-
-			// Read the whole image into one big RGBA buffer and then 
-			// convert it to a DIB. This is using the traditional
-			// TIFFReadRGBAImage() API that we trust.
-			
-			uint32 *raster = NULL;
-
-			if(!header_only) {
-
-				raster = (uint32*)_TIFFmalloc(width * height * sizeof(uint32));
-				if (raster == NULL) {
-					throw FI_MSG_ERROR_MEMORY;
-				}
-
-				// read the image in one chunk into an RGBA array
-
-				if (!TIFFReadRGBAImage(tif, width, height, raster, 1)) {
-					_TIFFfree(raster);
-					throw FI_MSG_ERROR_UNSUPPORTED_FORMAT;
-				}
-			}
-			// TIFFReadRGBAImage always deliveres 3 or 4 samples per pixel images
-			// (RGB or RGBA, see below). Cut-off possibly present channels (additional 
-			// alpha channels) from e.g. Photoshop. Any CMYK(A..) is now treated as RGB,
-			// any additional alpha channel on RGB(AA..) is lost on conversion to RGB(A)
-
-			if(samplesperpixel > 4) { // TODO Write to Extra Channels
-				FreeImage_OutputMessageProc(s_format_id, "Warning: %d additional alpha channel(s) ignored", samplesperpixel-4);
-				samplesperpixel = 4;
-			}
-
-			// create a new DIB (take care of different samples-per-pixel in case 
-			// of converted CMYK image (RGB conversion is on sample per pixel less)
-
-			if (photometric == PHOTOMETRIC_SEPARATED && samplesperpixel == 4) {
-				samplesperpixel = 3;
-			}
-
-			dib = CreateImageType(header_only, image_type, width, height, bitspersample, samplesperpixel);
-			if (dib == NULL) {
-				// free the raster pointer and output an error if allocation failed
-				if(raster) {
-					_TIFFfree(raster);
-				}
-				throw FI_MSG_ERROR_DIB_MEMORY;
-			}
-			
-			// fill in the resolution (english or universal)
-
-			ReadResolution(tif, dib);
-
-			if(!header_only) {
-
-				// read the raster lines and save them in the DIB
-				// with RGB mode, we have to change the order of the 3 samples RGB
-				// We use macros for extracting components from the packed ABGR 
-				// form returned by TIFFReadRGBAImage.
-
-				uint32 *row = &raster[0];
-
-				if (samplesperpixel == 4) {
-					// 32-bit RGBA
-					for (uint32 y = 0; y < height; y++) {
-						BYTE *bits = FreeImage_GetScanLine(dib, y);
-						for (uint32 x = 0; x < width; x++) {
-							bits[FI_RGBA_BLUE]	= (BYTE)TIFFGetB(row[x]);
-							bits[FI_RGBA_GREEN] = (BYTE)TIFFGetG(row[x]);
-							bits[FI_RGBA_RED]	= (BYTE)TIFFGetR(row[x]);
-							bits[FI_RGBA_ALPHA] = (BYTE)TIFFGetA(row[x]);
-
-							if (bits[FI_RGBA_ALPHA] != 0) {
-								has_alpha = TRUE;
-							}
-
-							bits += 4;
-						}
-						row += width;
-					}
-				} else {
-					// 24-bit RGB
-					for (uint32 y = 0; y < height; y++) {
-						BYTE *bits = FreeImage_GetScanLine(dib, y);
-						for (uint32 x = 0; x < width; x++) {
-							bits[FI_RGBA_BLUE]	= (BYTE)TIFFGetB(row[x]);
-							bits[FI_RGBA_GREEN] = (BYTE)TIFFGetG(row[x]);
-							bits[FI_RGBA_RED]	= (BYTE)TIFFGetR(row[x]);
-
-							bits += 3;
-						}
-						row += width;
-					}
-				}
-
-				_TIFFfree(raster);
-			}
-			
-			// ### Not correct when header only
-			FreeImage_SetTransparent(dib, has_alpha);
-
-		} else if(loadMethod == LoadAs8BitTrns) {
-			// ---------------------------------------------------------------------------------
-			// 8-bit + 8-bit alpha layer loading
-			// ---------------------------------------------------------------------------------
-
-			// create a new 8-bit DIB
-			dib = CreateImageType(header_only, image_type, width, height, bitspersample, MIN<uint16>(2, samplesperpixel));
-			if (dib == NULL) {
-				throw FI_MSG_ERROR_MEMORY;
-			}
-
-			// fill in the resolution (english or universal)
-
-			ReadResolution(tif, dib);
-
-			// set up the colormap based on photometric	
-
-			ReadPalette(tif, photometric, bitspersample, dib);
-
-			// calculate the line + pitch (separate for scr & dest)
-
-			const tsize_t src_line = TIFFScanlineSize(tif);
-			// here, the pitch is 2x less than the original as we only keep the first layer				
-			int dst_pitch = FreeImage_GetPitch(dib);
-
-			// transparency table for 8-bit + 8-bit alpha images
-
-			BYTE trns[256]; 
-			// clear the transparency table
-			memset(trns, 0xFF, 256 * sizeof(BYTE));
-
-			// In the tiff file the lines are saved from up to down 
-			// In a DIB the lines must be saved from down to up
-
-			BYTE *bits = FreeImage_GetScanLine(dib, height - 1);
-
-			// read the tiff lines and save them in the DIB
-
-			if(planar_config == PLANARCONFIG_CONTIG && !header_only) {
-
-				BYTE *buf = (BYTE*)malloc(TIFFStripSize(tif) * sizeof(BYTE));
-				if(buf == NULL) {
-					throw FI_MSG_ERROR_MEMORY;
-				}
-
-				for (uint32 y = 0; y < height; y += rowsperstrip) {
-					int32 nrow = (y + rowsperstrip > height ? height - y : rowsperstrip);
-
-					if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, y, 0), buf, nrow * src_line) == -1) {
-						free(buf);
-						throw FI_MSG_ERROR_PARSING;
-					}
-					for (int l = 0; l < nrow; l++) {
-						BYTE *p = bits;
-						BYTE *b = buf + l * src_line;
-
-						for(uint32 x = 0; x < (uint32)(src_line / samplesperpixel); x++) {
-							// copy the 8-bit layer
-							*p = b[0];
-							// convert the 8-bit alpha layer to a trns table
-							trns[ b[0] ] = b[1];
-
-							p++;
-							b += samplesperpixel;
-						}
-						bits -= dst_pitch;
-					}
-				}
-
-				free(buf);
-			}
-			else if(planar_config == PLANARCONFIG_SEPARATE && !header_only) {
-				tsize_t stripsize = TIFFStripSize(tif) * sizeof(BYTE);
-				BYTE *buf = (BYTE*)malloc(2 * stripsize);
-				if(buf == NULL) {
-					throw FI_MSG_ERROR_MEMORY;
-				}
-				BYTE *grey = buf;
-				BYTE *alpha = buf + stripsize;
-
-				for (uint32 y = 0; y < height; y += rowsperstrip) {
-					int32 nrow = (y + rowsperstrip > height ? height - y : rowsperstrip);
-
-					if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, y, 0), grey, nrow * src_line) == -1) {
-						free(buf);
-						throw FI_MSG_ERROR_PARSING;
-					} 
-					if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, y, 1), alpha, nrow * src_line) == -1) {
-						free(buf);
-						throw FI_MSG_ERROR_PARSING;
-					} 
-
-					for (int l = 0; l < nrow; l++) {
-						BYTE *p = bits;
-						BYTE *g = grey + l * src_line;
-						BYTE *a = alpha + l * src_line;
-
-						for(uint32 x = 0; x < (uint32)(src_line); x++) {
-							// copy the 8-bit layer
-							*p = g[0];
-							// convert the 8-bit alpha layer to a trns table
-							trns[ g[0] ] = a[0];
-
-							p++;
-							g++;
-							a++;
-						}
-						bits -= dst_pitch;
-					}
-				}
-
-				free(buf);
-
-			}
-			
-			FreeImage_SetTransparencyTable(dib, &trns[0], 256);
-			FreeImage_SetTransparent(dib, TRUE);
-
-		} else if(loadMethod == LoadAsCMYK) {
-			// ---------------------------------------------------------------------------------
-			// CMYK loading
-			// ---------------------------------------------------------------------------------
-
-			// At this place, samplesperpixel could be > 4, esp. when a CMYK(A) format
-			// is recognized. Where all other formats are handled straight-forward, this
-			// format has to be handled special 
-
-			BOOL isCMYKA = (photometric == PHOTOMETRIC_SEPARATED) && (samplesperpixel > 4);
-
-			// We use a temp dib to store the alpha for the CMYKA to RGBA conversion
-			// NOTE this is until we have Extra channels implementation.
-			// Also then it will be possible to merge LoadAsCMYK with LoadAsGenericStrip
-			
-			FIBITMAP *alpha = NULL;
-			unsigned alpha_pitch = 0;
-			BYTE *alpha_bits = NULL;
-			unsigned alpha_Bpp = 0;
-
-			if(isCMYKA && !asCMYK && !header_only) {
-				if(bitspersample == 16) {
-					alpha = FreeImage_AllocateT(FIT_UINT16, width, height);
-				} else if (bitspersample == 8) {
-					alpha = FreeImage_Allocate(width, height, 8);
-				}
-					
-				if(!alpha) {
-					FreeImage_OutputMessageProc(s_format_id, "Failed to allocate temporary alpha channel");
-				} else {
-					alpha_bits = FreeImage_GetScanLine(alpha, height - 1);
-					alpha_pitch = FreeImage_GetPitch(alpha);
-					alpha_Bpp = FreeImage_GetBPP(alpha) / 8;
-				}
-				
-			}
-			
-			// create a new DIB
-			const uint16 chCount = MIN<uint16>(samplesperpixel, 4);
-			dib = CreateImageType(header_only, image_type, width, height, bitspersample, chCount);
-			if (dib == NULL) {
-				FreeImage_Unload(alpha);
-				throw FI_MSG_ERROR_MEMORY;
-			}
-
-			// fill in the resolution (english or universal)
-
-			ReadResolution(tif, dib);
-
-			if(!header_only) {
-
-				// calculate the line + pitch (separate for scr & dest)
-
-				const tsize_t src_line = TIFFScanlineSize(tif);
-				const tsize_t dst_line = FreeImage_GetLine(dib);
-				const unsigned dib_pitch = FreeImage_GetPitch(dib);
-				const unsigned dibBpp = FreeImage_GetBPP(dib) / 8;
-				const unsigned Bpc = dibBpp / chCount;
-				const unsigned srcBpp = bitspersample * samplesperpixel / 8;
-
-				assert(Bpc <= 2); //< CMYK is only BYTE or SHORT 
-				
-				// In the tiff file the lines are save from up to down 
-				// In a DIB the lines must be saved from down to up
-
-				BYTE *bits = FreeImage_GetScanLine(dib, height - 1);
-
-				// read the tiff lines and save them in the DIB
-
-				BYTE *buf = (BYTE*)malloc(TIFFStripSize(tif) * sizeof(BYTE));
-				if(buf == NULL) {
-					FreeImage_Unload(alpha);
-					throw FI_MSG_ERROR_MEMORY;
-				}
-
-				if(planar_config == PLANARCONFIG_CONTIG) {
-					
-					// - loop for strip blocks -
-					
-					for (uint32 y = 0; y < height; y += rowsperstrip) {
-						const int32 strips = (y + rowsperstrip > height ? height - y : rowsperstrip);
-
-						if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, y, 0), buf, strips * src_line) == -1) {
-							free(buf);
-							FreeImage_Unload(alpha);
-							throw FI_MSG_ERROR_PARSING;
-						} 
-						
-						// - loop for strips -
-						
-						if(src_line != dst_line) {
-							// CMYKA+
-							if(alpha) {
-								for (int l = 0; l < strips; l++) {					
-									for(BYTE *pixel = bits, *al_pixel = alpha_bits, *src_pixel =  buf + l * src_line; pixel < bits + dib_pitch; pixel += dibBpp, al_pixel += alpha_Bpp, src_pixel += srcBpp) {
-										// copy pixel byte by byte
-										BYTE b = 0;
-										for( ; b < dibBpp; ++b) {
-											pixel[b] =  src_pixel[b];
-										}
-										// TODO write the remaining bytes to extra channel(s)
-										
-										// HACK write the first alpha to a separate dib (assume BYTE or WORD)
-										al_pixel[0] = src_pixel[b];
-										if(Bpc > 1) {
-											al_pixel[1] = src_pixel[b + 1];
-										}
-										
-									}
-									bits -= dib_pitch;
-									alpha_bits -= alpha_pitch;
-								}
-							}
-							else {
-								// alpha/extra channels alloc failed
-								for (int l = 0; l < strips; l++) {
-									for(BYTE* pixel = bits, * src_pixel =  buf + l * src_line; pixel < bits + dst_line; pixel += dibBpp, src_pixel += srcBpp) {
-										AssignPixel(pixel, src_pixel, dibBpp);
-									}
-									bits -= dib_pitch;
-								}
-							}
-						}
-						else { 
-							// CMYK to CMYK
-							for (int l = 0; l < strips; l++) {
-								BYTE *b = buf + l * src_line;
-								memcpy(bits, b, src_line);
-								bits -= dib_pitch;
-							}
-						}
-
-					} // height
-				
-				}
-				else if(planar_config == PLANARCONFIG_SEPARATE) {
-
-					BYTE *dib_strip = bits;
-					BYTE *al_strip = alpha_bits;
-
-					// - loop for strip blocks -
-					
-					for (uint32 y = 0; y < height; y += rowsperstrip) {
-						const int32 strips = (y + rowsperstrip > height ? height - y : rowsperstrip);
-						
-						// - loop for channels (planes) -
-						
-						for(uint16 sample = 0; sample < samplesperpixel; sample++) {
-							
-							if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, y, sample), buf, strips * src_line) == -1) {
-								free(buf);
-								FreeImage_Unload(alpha);
-								throw FI_MSG_ERROR_PARSING;
-							} 
-									
-							BYTE *dst_strip = dib_strip;
-							unsigned dst_pitch = dib_pitch;
-							uint16 ch = sample;
-							unsigned Bpp = dibBpp;
-
-							if(sample >= chCount) {
-								// TODO Write to Extra Channel
-								
-								// HACK redirect write to temp alpha
-								if(alpha && sample == chCount) {
-
-									dst_strip = al_strip;
-									dst_pitch = alpha_pitch;
-
-									ch = 0;
-									Bpp = alpha_Bpp;
-								}
-								else {
-									break; 
-								}
-							}
-							
-							const unsigned channelOffset = ch * Bpc;			
-							
-							// - loop for strips in block -
-							
-							BYTE *src_line_begin = buf;
-							BYTE *dst_line_begin = dst_strip;
-							for (int l = 0; l < strips; l++, src_line_begin += src_line, dst_line_begin -= dst_pitch ) {
-								// - loop for pixels in strip -
-								
-								const BYTE* const src_line_end = src_line_begin + src_line;
-								for (BYTE *src_bits = src_line_begin, * dst_bits = dst_line_begin; src_bits < src_line_end; src_bits += Bpc, dst_bits += Bpp) {
-									AssignPixel(dst_bits + channelOffset, src_bits, Bpc);									
-								} // line
-								
-							} // strips
-															
-						} // channels
-							
-						// done with a strip block, incr to the next
-						dib_strip -= strips * dib_pitch;
-						al_strip -= strips * alpha_pitch;
-							
-					} //< height
-					
-				}
-
-				free(buf);
-			
-				if(!asCMYK) {
-					ConvertCMYKtoRGBA(dib);
-					
-					// The ICC Profile is invalid, clear it
-					iccSize = 0;
-					iccBuf = NULL;
-					
-					if(isCMYKA) {
-						// HACK until we have Extra channels. (ConvertCMYKtoRGBA will then do the work)
-						
-						FreeImage_SetChannel(dib, alpha, FICC_ALPHA);
-						FreeImage_Unload(alpha);
-						alpha = NULL;
-					}
-					else {
-						FIBITMAP *t = RemoveAlphaChannel(dib);
-						if(t) {
-							FreeImage_Unload(dib);
-							dib = t;
-						}
-						else {
-							FreeImage_OutputMessageProc(s_format_id, "Cannot allocate memory for buffer. CMYK image converted to RGB + pending Alpha");
-						}
-					}
-				}
-				
-			} // !header_only
-			
-		} else if(loadMethod == LoadAsGenericStrip) {
-			// ---------------------------------------------------------------------------------
-			// Generic loading
-			// ---------------------------------------------------------------------------------
-
-			// create a new DIB
-			const uint16 chCount = MIN<uint16>(samplesperpixel, 4);
-			dib = CreateImageType(header_only, image_type, width, height, bitspersample, chCount);
-			if (dib == NULL) {
-				throw FI_MSG_ERROR_MEMORY;
-			}
-
-			// fill in the resolution (english or universal)
-
-			ReadResolution(tif, dib);
-
-			// set up the colormap based on photometric	
-
-			ReadPalette(tif, photometric, bitspersample, dib);
-	
-			if(!header_only) {
-				// calculate the line + pitch (separate for scr & dest)
-
-				const tsize_t src_line = TIFFScanlineSize(tif);
-				const tsize_t dst_line = FreeImage_GetLine(dib);
-				const unsigned dst_pitch = FreeImage_GetPitch(dib);
-				const unsigned Bpp = FreeImage_GetBPP(dib) / 8;
-				const unsigned srcBpp = bitspersample * samplesperpixel / 8;
-
-				// In the tiff file the lines are save from up to down 
-				// In a DIB the lines must be saved from down to up
-
-				BYTE *bits = FreeImage_GetScanLine(dib, height - 1);
-
-				// read the tiff lines and save them in the DIB
-
-				BYTE *buf = (BYTE*)malloc(TIFFStripSize(tif) * sizeof(BYTE));
-				if(buf == NULL) {
-					throw FI_MSG_ERROR_MEMORY;
-				}
-				
-				BOOL bThrowMessage = FALSE;
-				
-				if(planar_config == PLANARCONFIG_CONTIG) {
-
-					for (uint32 y = 0; y < height; y += rowsperstrip) {
-						int32 strips = (y + rowsperstrip > height ? height - y : rowsperstrip);
-
-						if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, y, 0), buf, strips * src_line) == -1) {
-							// ignore errors as they can be frequent and not really valid errors, especially with fax images
-							bThrowMessage = TRUE;							
-							/*
-							free(buf);
-							throw FI_MSG_ERROR_PARSING;
-							*/
-						} 
-						if(src_line == dst_line) {
-							// channel count match
-							for (int l = 0; l < strips; l++) {							
-								memcpy(bits, buf + l * src_line, src_line);
-								bits -= dst_pitch;
-							}
-						}
-						else {
-							for (int l = 0; l < strips; l++) {
-								for(BYTE *pixel = bits, *src_pixel =  buf + l * src_line; pixel < bits + dst_pitch; pixel += Bpp, src_pixel += srcBpp) {
-									AssignPixel(pixel, src_pixel, Bpp);
-								}
-								bits -= dst_pitch;
-							}
-						}
-					}
-				}
-				else if(planar_config == PLANARCONFIG_SEPARATE) {
-					
-					const unsigned Bpc = bitspersample / 8;
-					BYTE* dib_strip = bits;
-					// - loop for strip blocks -
-					
-					for (uint32 y = 0; y < height; y += rowsperstrip) {
-						const int32 strips = (y + rowsperstrip > height ? height - y : rowsperstrip);
-						
-						// - loop for channels (planes) -
-						
-						for(uint16 sample = 0; sample < samplesperpixel; sample++) {
-							
-							if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, y, sample), buf, strips * src_line) == -1) {
-								// ignore errors as they can be frequent and not really valid errors, especially with fax images
-								bThrowMessage = TRUE;	
-							} 
-									
-							if(sample >= chCount) {
-								// TODO Write to Extra Channel
-								break; 
-							}
-							
-							const unsigned channelOffset = sample * Bpc;			
-							
-							// - loop for strips in block -
-							
-							BYTE* src_line_begin = buf;
-							BYTE* dst_line_begin = dib_strip;
-							for (int l = 0; l < strips; l++, src_line_begin += src_line, dst_line_begin -= dst_pitch ) {
-									
-								// - loop for pixels in strip -
-								
-								const BYTE* const src_line_end = src_line_begin + src_line;
-
-								for (BYTE* src_bits = src_line_begin, * dst_bits = dst_line_begin; src_bits < src_line_end; src_bits += Bpc, dst_bits += Bpp) {
-									// actually assigns channel
-									AssignPixel(dst_bits + channelOffset, src_bits, Bpc); 
-								} // line
-
-							} // strips
-
-						} // channels
-							
-						// done with a strip block, incr to the next
-						dib_strip -= strips * dst_pitch;
-							
-					} // height
-
-				}
-				free(buf);
-				
-				if(bThrowMessage) {
-					FreeImage_OutputMessageProc(s_format_id, "Warning: parsing error. Image may be incomplete or contain invalid data !");
-				}
-				
-#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
-				SwapRedBlue32(dib);
-#endif
-
-			} // !header only
-			
-		} else if(loadMethod == LoadAsTiled) {
-			// ---------------------------------------------------------------------------------
-			// Tiled image loading
-			// ---------------------------------------------------------------------------------
-
-			uint32 tileWidth, tileHeight;
-			uint32 src_line = 0;
-
-			// create a new DIB
-			dib = CreateImageType( header_only, image_type, width, height, bitspersample, samplesperpixel);
-			if (dib == NULL) {
-				throw FI_MSG_ERROR_MEMORY;
-			}
-
-			// fill in the resolution (english or universal)
-
-			ReadResolution(tif, dib);
-
-			// set up the colormap based on photometric	
-
-			ReadPalette(tif, photometric, bitspersample, dib);
-
-			// get the tile geometry
-			if(!TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tileWidth) || !TIFFGetField(tif, TIFFTAG_TILELENGTH, &tileHeight)) {
-				throw "Invalid tiled TIFF image";
-			}
-
-			// read the tiff lines and save them in the DIB
-
-			if(planar_config == PLANARCONFIG_CONTIG && !header_only) {
-				
-				// get the maximum number of bytes required to contain a tile
-				tsize_t tileSize = TIFFTileSize(tif);
-
-				// allocate tile buffer
-				BYTE *tileBuffer = (BYTE*)malloc(tileSize * sizeof(BYTE));
-				if(tileBuffer == NULL) {
-					throw FI_MSG_ERROR_MEMORY;
-				}
-
-				// calculate src line and dst pitch
-				int dst_pitch = FreeImage_GetPitch(dib);
-				int tileRowSize = TIFFTileRowSize(tif);
-				int imageRowSize = TIFFScanlineSize(tif);
-
-
-				// In the tiff file the lines are saved from up to down 
-				// In a DIB the lines must be saved from down to up
-
-				BYTE *bits = FreeImage_GetScanLine(dib, height - 1);
-				
-				uint32 x, y, rowSize;
-				for (y = 0; y < height; y += tileHeight) {						
-					int32 nrows = (y + tileHeight > height ? height - y : tileHeight);					
-
-					for (x = 0, rowSize = 0; x < width; x += tileWidth, rowSize += tileRowSize) {
-						memset(tileBuffer, 0, tileSize);
-
-						// read one tile
-						if (TIFFReadTile(tif, tileBuffer, x, y, 0, 0) < 0) {
-							free(tileBuffer);
-							throw "Corrupted tiled TIFF file";
-						}
-						// convert to strip
-						if(x + tileWidth > width) {
-							src_line = imageRowSize - rowSize;
-						} else {
-							src_line = tileRowSize;
-						}
-						BYTE *src_bits = tileBuffer;
-						BYTE *dst_bits = bits + rowSize;
-						for(int k = 0; k < nrows; k++) {
-							memcpy(dst_bits, src_bits, src_line);
-							src_bits += tileRowSize;
-							dst_bits -= dst_pitch;
-						}
-					}
-
-					bits -= nrows * dst_pitch;
-				}
-
-#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
-				SwapRedBlue32(dib);
-#endif
-				free(tileBuffer);
-			}
-			else if(planar_config == PLANARCONFIG_SEPARATE) {
-				throw "Separated tiled TIFF images are not supported"; 
-			}
-
-
-		} else if(loadMethod == LoadAsLogLuv) {
-			// ---------------------------------------------------------------------------------
-			// RGBF LogLuv compressed loading
-			// ---------------------------------------------------------------------------------
-
-			double	stonits;	// input conversion to nits
-			if (!TIFFGetField(tif, TIFFTAG_STONITS, &stonits)) {
-				stonits = 1;
-			}
-			
-			// create a new DIB
-			dib = CreateImageType(header_only, image_type, width, height, bitspersample, samplesperpixel);
-			if (dib == NULL) {
-				throw FI_MSG_ERROR_MEMORY;
-			}
-
-			// fill in the resolution (english or universal)
-
-			ReadResolution(tif, dib);
-
-			if(planar_config == PLANARCONFIG_CONTIG && !header_only) {
-				// calculate the line + pitch (separate for scr & dest)
-
-				tsize_t src_line = TIFFScanlineSize(tif);
-				int dst_pitch = FreeImage_GetPitch(dib);
-
-				// In the tiff file the lines are save from up to down 
-				// In a DIB the lines must be saved from down to up
-
-				BYTE *bits = FreeImage_GetScanLine(dib, height - 1);
-
-				// read the tiff lines and save them in the DIB
-
-				BYTE *buf = (BYTE*)malloc(TIFFStripSize(tif) * sizeof(BYTE));
-				if(buf == NULL) {
-					throw FI_MSG_ERROR_MEMORY;
-				}
-
-				for (uint32 y = 0; y < height; y += rowsperstrip) {
-					int32 nrow = (y + rowsperstrip > height ? height - y : rowsperstrip);
-
-					if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, y, 0), buf, nrow * src_line) == -1) {
-						free(buf);
-						throw FI_MSG_ERROR_PARSING;
-					} 
-					// convert from XYZ to RGB
-					for (int l = 0; l < nrow; l++) {						
-						tiff_ConvertLineXYZToRGB(bits, buf + l * src_line, stonits, width);
-						bits -= dst_pitch;
-					}
-				}
-
-				free(buf);
-			}
-			else if(planar_config == PLANARCONFIG_SEPARATE) {
-				// this cannot happen according to the LogLuv specification
-				throw "Unable to handle PLANARCONFIG_SEPARATE LogLuv images";
-			}
-
-		} else if(loadMethod == LoadAsHalfFloat) {
-			// ---------------------------------------------------------------------------------
-			// RGBF loading from a half format
-			// ---------------------------------------------------------------------------------
-
-			// create a new DIB
-			dib = CreateImageType(header_only, image_type, width, height, bitspersample, samplesperpixel);
-			if (dib == NULL) {
-				throw FI_MSG_ERROR_MEMORY;
-			}
-
-			// fill in the resolution (english or universal)
-
-			ReadResolution(tif, dib);
-
-			if(!header_only) {
-
-				// calculate the line + pitch (separate for scr & dest)
-
-				tsize_t src_line = TIFFScanlineSize(tif);
-				unsigned dst_pitch = FreeImage_GetPitch(dib);
-
-				// In the tiff file the lines are save from up to down 
-				// In a DIB the lines must be saved from down to up
-
-				BYTE *bits = FreeImage_GetScanLine(dib, height - 1);
-
-				// read the tiff lines and save them in the DIB
-
-				if(planar_config == PLANARCONFIG_CONTIG) {
-
-					BYTE *buf = (BYTE*)malloc(TIFFStripSize(tif) * sizeof(BYTE));
-					if(buf == NULL) {
-						throw FI_MSG_ERROR_MEMORY;
-					}
-
-					for (uint32 y = 0; y < height; y += rowsperstrip) {
-						uint32 nrow = (y + rowsperstrip > height ? height - y : rowsperstrip);
-
-						if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, y, 0), buf, nrow * src_line) == -1) {
-							free(buf);
-							throw FI_MSG_ERROR_PARSING;
-						} 
-
-						// convert from half (16-bit) to float (32-bit)
-						// !!! use OpenEXR half helper class
-
-						half half_value;
-
-						for (uint32 l = 0; l < nrow; l++) {
-							WORD *src_pixel = (WORD*)(buf + l * src_line);
-							float *dst_pixel = (float*)bits;
-
-							for(tsize_t x = 0; x < (tsize_t)(src_line / sizeof(WORD)); x++) {
-								half_value.setBits(src_pixel[x]);
-								dst_pixel[x] = half_value;
-							}
-
-							bits -= dst_pitch;
-						}
-					}
-
-					free(buf);
-				}
-				else if(planar_config == PLANARCONFIG_SEPARATE) {
-					// this use case was never encountered yet
-					throw "Unable to handle PLANARCONFIG_SEPARATE RGB half float images";
-				}
-				
-			} // !header only
-
-		} else {
-			// ---------------------------------------------------------------------------------
-			// Unknown or unsupported format
-			// ---------------------------------------------------------------------------------
-
-			throw FI_MSG_ERROR_UNSUPPORTED_FORMAT;
-		}
-
-		// copy ICC profile data (must be done after FreeImage_Allocate)
-
-		FreeImage_CreateICCProfile(dib, iccBuf, iccSize);		
-		if (photometric == PHOTOMETRIC_SEPARATED && asCMYK) {
-			FreeImage_GetICCProfile(dib)->flags |= FIICC_COLOR_IS_CMYK;
-		}			
-
-		// copy TIFF metadata (must be done after FreeImage_Allocate)
-
-		ReadMetadata(tif, dib);
-
-		// copy TIFF thumbnail (must be done after FreeImage_Allocate)
-		
-		ReadThumbnail(io, handle, data, tif, dib);
-
-		return (FIBITMAP *)dib;
-
-	} catch (const char *message) {			
-		if(dib)	{
-			FreeImage_Unload(dib);
-		}
-		if(message) {
-			FreeImage_OutputMessageProc(s_format_id, message);
-		}
-		return NULL;
-	}
-  
-}
-
-// --------------------------------------------------------------------------
-
-static BOOL 
-SaveOneTIFF(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void *data, unsigned ifd, unsigned ifdCount) {
-	if (!dib || !handle || !data) {
-		return FALSE;
-	} 
-	
-	try { 
-		fi_TIFFIO *fio = (fi_TIFFIO*)data;
-		TIFF *out = fio->tif;
-
-		const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
-
-		const uint32 width = FreeImage_GetWidth(dib);
-		const uint32 height = FreeImage_GetHeight(dib);
-		const uint16 bitsperpixel = (uint16)FreeImage_GetBPP(dib);
-
-		const FIICCPROFILE* iccProfile = FreeImage_GetICCProfile(dib);
-		
-		// setup out-variables based on dib and flag options
-		
-		uint16 bitspersample;
-		uint16 samplesperpixel;
-		uint16 photometric;
-
-		if(image_type == FIT_BITMAP) {
-			// standard image: 1-, 4-, 8-, 16-, 24-, 32-bit
-
-			samplesperpixel = ((bitsperpixel == 24) ? 3 : ((bitsperpixel == 32) ? 4 : 1));
-			bitspersample = bitsperpixel / samplesperpixel;
-			photometric	= GetPhotometric(dib);
-
-			if((bitsperpixel == 8) && FreeImage_IsTransparent(dib)) {
-				// 8-bit transparent picture : convert later to 8-bit + 8-bit alpha
-				samplesperpixel = 2;
-				bitspersample = 8;
-			}
-			else if(bitsperpixel == 32) {
-				// 32-bit images : check for CMYK or alpha transparency
-
-				if((((iccProfile->flags & FIICC_COLOR_IS_CMYK) == FIICC_COLOR_IS_CMYK) || ((flags & TIFF_CMYK) == TIFF_CMYK))) {
-					// CMYK support
-					photometric = PHOTOMETRIC_SEPARATED;
-					TIFFSetField(out, TIFFTAG_INKSET, INKSET_CMYK);
-					TIFFSetField(out, TIFFTAG_NUMBEROFINKS, 4);
-				}
-				else if(photometric == PHOTOMETRIC_RGB) {
-					// transparency mask support
-					uint16 sampleinfo[1]; 
-					// unassociated alpha data is transparency information
-					sampleinfo[0] = EXTRASAMPLE_UNASSALPHA;
-					TIFFSetField(out, TIFFTAG_EXTRASAMPLES, 1, sampleinfo);
-				}
-			}
-		} else if(image_type == FIT_RGB16) {
-			// 48-bit RGB
-
-			samplesperpixel = 3;
-			bitspersample = bitsperpixel / samplesperpixel;
-			photometric	= PHOTOMETRIC_RGB;
-		} else if(image_type == FIT_RGBA16) {
-			// 64-bit RGBA
-
-			samplesperpixel = 4;
-			bitspersample = bitsperpixel / samplesperpixel;
-			if((((iccProfile->flags & FIICC_COLOR_IS_CMYK) == FIICC_COLOR_IS_CMYK) || ((flags & TIFF_CMYK) == TIFF_CMYK))) {
-				// CMYK support
-				photometric = PHOTOMETRIC_SEPARATED;
-				TIFFSetField(out, TIFFTAG_INKSET, INKSET_CMYK);
-				TIFFSetField(out, TIFFTAG_NUMBEROFINKS, 4);
-			}
-			else {
-				photometric	= PHOTOMETRIC_RGB;
-				// transparency mask support
-				uint16 sampleinfo[1]; 
-				// unassociated alpha data is transparency information
-				sampleinfo[0] = EXTRASAMPLE_UNASSALPHA;
-				TIFFSetField(out, TIFFTAG_EXTRASAMPLES, 1, sampleinfo);
-			}
-		} else if(image_type == FIT_RGBF) {
-			// 96-bit RGBF => store with a LogLuv encoding ?
-
-			samplesperpixel = 3;
-			bitspersample = bitsperpixel / samplesperpixel;
-			// the library converts to and from floating-point XYZ CIE values
-			if((flags & TIFF_LOGLUV) == TIFF_LOGLUV) {
-				photometric	= PHOTOMETRIC_LOGLUV;
-				TIFFSetField(out, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_FLOAT);
-				// TIFFSetField(out, TIFFTAG_STONITS, 1.0);   // assume unknown 
-			}
-			else {
-				// store with default compression (LZW) or with input compression flag
-				photometric	= PHOTOMETRIC_RGB;
-			}
-			
-		} else if (image_type == FIT_RGBAF) {
-			// 128-bit RGBAF => store with default compression (LZW) or with input compression flag
-			
-			samplesperpixel = 4;
-			bitspersample = bitsperpixel / samplesperpixel;
-			photometric	= PHOTOMETRIC_RGB;
-		} else {
-			// special image type (int, long, double, ...)
-			
-			samplesperpixel = 1;
-			bitspersample = bitsperpixel;
-			photometric	= PHOTOMETRIC_MINISBLACK;
-		}
-
-		// set image data type
-
-		WriteImageType(out, image_type);
-		
-		// write possible ICC profile
-
-		if (iccProfile->size && iccProfile->data) {
-			TIFFSetField(out, TIFFTAG_ICCPROFILE, iccProfile->size, iccProfile->data);
-		}
-
-		// handle standard width/height/bpp stuff
-
-		TIFFSetField(out, TIFFTAG_IMAGEWIDTH, width);
-		TIFFSetField(out, TIFFTAG_IMAGELENGTH, height);
-		TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, samplesperpixel);
-		TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, bitspersample);
-		TIFFSetField(out, TIFFTAG_PHOTOMETRIC, photometric);
-		TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);	// single image plane 
-		TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
-		TIFFSetField(out, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB);
-		TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(out, (uint32) -1)); 
-
-		// handle metrics
-
-		WriteResolution(out, dib);
-
-		// multi-paging
-
-		if (page >= 0) {
-			char page_number[20];
-			sprintf(page_number, "Page %d", page);
-
-			TIFFSetField(out, TIFFTAG_SUBFILETYPE, FILETYPE_PAGE);
-			TIFFSetField(out, TIFFTAG_PAGENUMBER, (uint16)page, (uint16)0);
-			TIFFSetField(out, TIFFTAG_PAGENAME, page_number);
-
-		} else {
-			// is it a thumbnail ? 
-			TIFFSetField(out, TIFFTAG_SUBFILETYPE, (ifd == 0) ? 0 : FILETYPE_REDUCEDIMAGE);
-		}
-
-		// palettes (image colormaps are automatically scaled to 16-bits)
-
-		if (photometric == PHOTOMETRIC_PALETTE) {
-			uint16 *r, *g, *b;
-			uint16 nColors = (uint16)FreeImage_GetColorsUsed(dib);
-			RGBQUAD *pal = FreeImage_GetPalette(dib);
-
-			r = (uint16 *) _TIFFmalloc(sizeof(uint16) * 3 * nColors);
-			if(r == NULL) {
-				throw FI_MSG_ERROR_MEMORY;
-			}
-			g = r + nColors;
-			b = g + nColors;
-
-			for (int i = nColors - 1; i >= 0; i--) {
-				r[i] = SCALE((uint16)pal[i].rgbRed);
-				g[i] = SCALE((uint16)pal[i].rgbGreen);
-				b[i] = SCALE((uint16)pal[i].rgbBlue);
-			}
-
-			TIFFSetField(out, TIFFTAG_COLORMAP, r, g, b);
-
-			_TIFFfree(r);
-		}
-
-		// compression tag
-
-		WriteCompression(out, bitspersample, samplesperpixel, photometric, flags);
-
-		// metadata
-
-		WriteMetadata(out, dib);
-
-		// thumbnail tag
-
-		if((ifd == 0) && (ifdCount > 1)) {
-			uint32 diroff[1];
-			diroff[0] = 0;
-			TIFFSetField(out, TIFFTAG_SUBIFD, 1, diroff);
-		}
-
-		// read the DIB lines from bottom to top
-		// and save them in the TIF
-		// -------------------------------------
-		
-		const uint32 pitch = FreeImage_GetPitch(dib);
-
-		if(image_type == FIT_BITMAP) {
-			// standard bitmap type
-		
-			switch(bitsperpixel) {
-				case 1 :
-				case 4 :
-				case 8 :
-				{
-					if((bitsperpixel == 8) && FreeImage_IsTransparent(dib)) {
-						// 8-bit transparent picture : convert to 8-bit + 8-bit alpha
-
-						// get the transparency table
-						BYTE *trns = FreeImage_GetTransparencyTable(dib);
-
-						BYTE *buffer = (BYTE *)malloc(2 * width * sizeof(BYTE));
-						if(buffer == NULL) {
-							throw FI_MSG_ERROR_MEMORY;
-						}
-
-						for (int y = height - 1; y >= 0; y--) {
-							BYTE *bits = FreeImage_GetScanLine(dib, y);
-
-							BYTE *p = bits, *b = buffer;
-
-							for(uint32 x = 0; x < width; x++) {
-								// copy the 8-bit layer
-								b[0] = *p;
-								// convert the trns table to a 8-bit alpha layer
-								b[1] = trns[ b[0] ];
-
-								p++;
-								b += samplesperpixel;
-							}
-
-							// write the scanline to disc
-
-							TIFFWriteScanline(out, buffer, height - y - 1, 0);
-						}
-
-						free(buffer);
-					}
-					else {
-						// other cases
-						BYTE *buffer = (BYTE *)malloc(pitch * sizeof(BYTE));
-						if(buffer == NULL) {
-							throw FI_MSG_ERROR_MEMORY;
-						}
-
-						for (uint32 y = 0; y < height; y++) {
-							// get a copy of the scanline
-							memcpy(buffer, FreeImage_GetScanLine(dib, height - y - 1), pitch);
-							// write the scanline to disc
-							TIFFWriteScanline(out, buffer, y, 0);
-						}
-						free(buffer);
-					}
-
-					break;
-				}				
-
-				case 24:
-				case 32:
-				{
-					BYTE *buffer = (BYTE *)malloc(pitch * sizeof(BYTE));
-					if(buffer == NULL) {
-						throw FI_MSG_ERROR_MEMORY;
-					}
-
-					for (uint32 y = 0; y < height; y++) {
-						// get a copy of the scanline
-
-						memcpy(buffer, FreeImage_GetScanLine(dib, height - y - 1), pitch);
-
-#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
-						if (photometric != PHOTOMETRIC_SEPARATED) {
-							// TIFFs store color data RGB(A) instead of BGR(A)
-		
-							BYTE *pBuf = buffer;
-		
-							for (uint32 x = 0; x < width; x++) {
-								INPLACESWAP(pBuf[0], pBuf[2]);
-								pBuf += samplesperpixel;
-							}
-						}
-#endif
-						// write the scanline to disc
-
-						TIFFWriteScanline(out, buffer, y, 0);
-					}
-
-					free(buffer);
-
-					break;
-				}
-			}//< switch (bitsperpixel)
-
-		} else if(image_type == FIT_RGBF && (flags & TIFF_LOGLUV) == TIFF_LOGLUV) {
-			// RGBF image => store as XYZ using a LogLuv encoding
-
-			BYTE *buffer = (BYTE *)malloc(pitch * sizeof(BYTE));
-			if(buffer == NULL) {
-				throw FI_MSG_ERROR_MEMORY;
-			}
-
-			for (uint32 y = 0; y < height; y++) {
-				// get a copy of the scanline and convert from RGB to XYZ
-				tiff_ConvertLineRGBToXYZ(buffer, FreeImage_GetScanLine(dib, height - y - 1), width);
-				// write the scanline to disc
-				TIFFWriteScanline(out, buffer, y, 0);
-			}
-			free(buffer);
-		} else {
-			// just dump the dib (tiff supports all dib types)
-			
-			BYTE *buffer = (BYTE *)malloc(pitch * sizeof(BYTE));
-			if(buffer == NULL) {
-				throw FI_MSG_ERROR_MEMORY;
-			}
-			
-			for (uint32 y = 0; y < height; y++) {
-				// get a copy of the scanline
-				memcpy(buffer, FreeImage_GetScanLine(dib, height - y - 1), pitch);
-				// write the scanline to disc
-				TIFFWriteScanline(out, buffer, y, 0);
-			}
-			free(buffer);
-		}
-
-		// write out the directory tag if we wrote a page other than -1 or if we have a thumbnail to write later
-
-		if( (page >= 0) || ((ifd == 0) && (ifdCount > 1)) ) {
-			TIFFWriteDirectory(out);
-			// else: TIFFClose will WriteDirectory
-		}
-
-		return TRUE;
-		
-	} catch(const char *text) {
-		FreeImage_OutputMessageProc(s_format_id, text);
-		return FALSE;
-	} 
-}
-
-static BOOL DLL_CALLCONV
-Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void *data) {
-	BOOL bResult = FALSE;
-	
-	// handle thumbnail as SubIFD
-	const BOOL bHasThumbnail = (FreeImage_GetThumbnail(dib) != NULL);
-	const unsigned ifdCount = bHasThumbnail ? 2 : 1;
-	
-	FIBITMAP *bitmap = dib;
-
-	for(unsigned ifd = 0; ifd < ifdCount; ifd++) {
-		// redirect dib to thumbnail for the second pass
-		if(ifd == 1) {
-			bitmap = FreeImage_GetThumbnail(dib);
-		}
-
-		bResult = SaveOneTIFF(io, bitmap, handle, page, flags, data, ifd, ifdCount);
-		if(!bResult) {
-			return FALSE;
-		}
-	}
-
-	return bResult;
-}
-
-// ==========================================================
-//   Init
-// ==========================================================
-
-void DLL_CALLCONV
-InitTIFF(Plugin *plugin, int format_id) {
-	s_format_id = format_id;
-
-	plugin->format_proc = Format;
-	plugin->description_proc = Description;
-	plugin->extension_proc = Extension;
-	plugin->regexpr_proc = RegExpr;
-	plugin->open_proc = Open;
-	plugin->close_proc = Close;
-	plugin->pagecount_proc = PageCount;
-	plugin->pagecapability_proc = NULL;
-	plugin->load_proc = Load;
-	plugin->save_proc = Save;
-	plugin->validate_proc = Validate;
-	plugin->mime_proc = MimeType;
-	plugin->supports_export_bpp_proc = SupportsExportDepth;
-	plugin->supports_export_type_proc = SupportsExportType;
-	plugin->supports_icc_profiles_proc = SupportsICCProfiles;
-	plugin->supports_no_pixels_proc = SupportsNoPixels; 
-}
diff --git a/Source/LibTIFF/_FI_3151_XTIFF.cpp b/Source/LibTIFF/_FI_3151_XTIFF.cpp
deleted file mode 100644
index c9bb19d..0000000
--- a/Source/LibTIFF/_FI_3151_XTIFF.cpp
+++ /dev/null
@@ -1,664 +0,0 @@
-// ==========================================================
-// Metadata functions implementation
-// Extended TIFF Directory GEO Tag Support
-//
-// Design and implementation by
-// - Hervé Drolon (drolon at infonie.fr)
-// - Thorsten Radde (support at IdealSoftware.com)
-// - Berend Engelbrecht (softwarecave at users.sourceforge.net)
-// - Mihail Naydenov (mnaydenov at users.sourceforge.net)
-//
-// Based on the LibTIFF xtiffio sample and on LibGeoTIFF
-//
-// This file is part of FreeImage 3
-//
-// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
-// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
-// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
-// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
-// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
-// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
-// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
-// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
-// THIS DISCLAIMER.
-//
-// Use at your own risk!
-// ========================================================== 
-
-#ifdef _MSC_VER
-#pragma warning (disable : 4786) // identifier was truncated to 'number' characters
-#endif
-
-#include "../LibTIFF/tiffiop.h"
-
-#include "FreeImage.h"
-#include "Utilities.h"
-#include "FreeImageTag.h"
-#include "FIRational.h"
-
-// ----------------------------------------------------------
-//   Extended TIFF Directory GEO Tag Support
-// ----------------------------------------------------------
-
-/**
-  Tiff info structure.
-  Entry format:
-  { TAGNUMBER, ReadCount, WriteCount, DataType, FIELDNUM, OkToChange, PassDirCountOnSet, AsciiName }
-
-  For ReadCount, WriteCount, -1 = unknown.
-*/
-static const TIFFFieldInfo xtiffFieldInfo[] = {
-	{ TIFFTAG_GEOPIXELSCALE, -1, -1, TIFF_DOUBLE, FIELD_CUSTOM, TRUE, TRUE, "GeoPixelScale" },
-	{ TIFFTAG_INTERGRAPH_MATRIX, -1, -1, TIFF_DOUBLE, FIELD_CUSTOM, TRUE, TRUE, "Intergraph TransformationMatrix" },
-	{ TIFFTAG_GEOTRANSMATRIX, -1, -1, TIFF_DOUBLE, FIELD_CUSTOM, TRUE, TRUE, "GeoTransformationMatrix" },
-	{ TIFFTAG_GEOTIEPOINTS,	-1, -1, TIFF_DOUBLE, FIELD_CUSTOM, TRUE, TRUE, "GeoTiePoints" },
-	{ TIFFTAG_GEOKEYDIRECTORY,-1,-1, TIFF_SHORT, FIELD_CUSTOM, TRUE, TRUE, "GeoKeyDirectory" },
-	{ TIFFTAG_GEODOUBLEPARAMS, -1, -1, TIFF_DOUBLE,	FIELD_CUSTOM, TRUE,	TRUE, "GeoDoubleParams" },
-	{ TIFFTAG_GEOASCIIPARAMS, -1, -1, TIFF_ASCII, FIELD_CUSTOM, TRUE, FALSE, "GeoASCIIParams" },
-	{ TIFFTAG_JPL_CARTO_IFD, 1, 1, TIFF_LONG, FIELD_CUSTOM, TRUE, TRUE,	"JPL Carto IFD offset" }  /** Don't use this! **/
-};
-
-static void
-_XTIFFLocalDefaultDirectory(TIFF *tif) {
-	int tag_size = sizeof(xtiffFieldInfo) / sizeof(xtiffFieldInfo[0]);
-	// Install the extended Tag field info
-	TIFFMergeFieldInfo(tif, xtiffFieldInfo, tag_size);
-}
-
-static TIFFExtendProc _ParentExtender;
-
-/**
-This is the callback procedure, and is
-called by the DefaultDirectory method
-every time a new TIFF directory is opened.
-*/
-static void
-_XTIFFDefaultDirectory(TIFF *tif) {
-	// set up our own defaults
-	_XTIFFLocalDefaultDirectory(tif);
-
-	/*
-	Since an XTIFF client module may have overridden
-	the default directory method, we call it now to
-	allow it to set up the rest of its own methods.
-	*/
-	if (_ParentExtender)
-		(*_ParentExtender)(tif);
-}
-
-/**
-XTIFF Initializer -- sets up the callback procedure for the TIFF module
-*/
-void
-XTIFFInitialize(void) {
-	static int first_time = 1;
-
-	if (! first_time)
-		return; /* Been there. Done that. */
-	first_time = 0;
-
-	// Grab the inherited method and install
-	_ParentExtender = TIFFSetTagExtender(_XTIFFDefaultDirectory);
-}
-
-// ----------------------------------------------------------
-//   GeoTIFF tag reading / writing
-// ----------------------------------------------------------
-
-void
-tiff_read_geotiff_profile(TIFF *tif, FIBITMAP *dib) {
-	char defaultKey[16];
-
-	size_t tag_size = sizeof(xtiffFieldInfo) / sizeof(xtiffFieldInfo[0]);
-
-	TagLib& tag_lib = TagLib::instance();
-
-	for(unsigned i = 0; i < tag_size; i++) {
-
-		const TIFFFieldInfo *fieldInfo = &xtiffFieldInfo[i];
-
-		if(fieldInfo->field_type == TIFF_ASCII) {
-			char *params = NULL;
-
-			if(TIFFGetField(tif, fieldInfo->field_tag, &params)) {
-				// create a tag
-				FITAG *tag = FreeImage_CreateTag();
-				if(!tag)
-					return;
-
-				WORD tag_id = (WORD)fieldInfo->field_tag;
-
-				FreeImage_SetTagType(tag, (FREE_IMAGE_MDTYPE)fieldInfo->field_type);
-				FreeImage_SetTagID(tag, tag_id);
-				FreeImage_SetTagKey(tag, tag_lib.getTagFieldName(TagLib::GEOTIFF, tag_id, defaultKey));
-				FreeImage_SetTagDescription(tag, tag_lib.getTagDescription(TagLib::GEOTIFF, tag_id));
-				FreeImage_SetTagLength(tag, (DWORD)strlen(params) + 1);
-				FreeImage_SetTagCount(tag, FreeImage_GetTagLength(tag));
-				FreeImage_SetTagValue(tag, params);
-				FreeImage_SetMetadata(FIMD_GEOTIFF, dib, FreeImage_GetTagKey(tag), tag);
-
-				// delete the tag
-				FreeImage_DeleteTag(tag);
-			}
-		} else {
-			short tag_count = 0;
-			void* data = NULL;
-
-			if(TIFFGetField(tif, fieldInfo->field_tag, &tag_count, &data)) {
-				// create a tag
-				FITAG *tag = FreeImage_CreateTag();
-				if(!tag)
-					return;
-
-				WORD tag_id = (WORD)fieldInfo->field_tag;
-				FREE_IMAGE_MDTYPE tag_type = (FREE_IMAGE_MDTYPE)fieldInfo->field_type;
-
-				FreeImage_SetTagType(tag, tag_type);
-				FreeImage_SetTagID(tag, tag_id);
-				FreeImage_SetTagKey(tag, tag_lib.getTagFieldName(TagLib::GEOTIFF, tag_id, defaultKey));
-				FreeImage_SetTagDescription(tag, tag_lib.getTagDescription(TagLib::GEOTIFF, tag_id));
-				FreeImage_SetTagLength(tag, FreeImage_TagDataWidth(tag_type) * tag_count);
-				FreeImage_SetTagCount(tag, tag_count);
-				FreeImage_SetTagValue(tag, data);
-				FreeImage_SetMetadata(FIMD_GEOTIFF, dib, FreeImage_GetTagKey(tag), tag);
-
-				// delete the tag
-				FreeImage_DeleteTag(tag);
-			}
-		}
-	} // for(tag_size)
-}
-
-void
-tiff_write_geotiff_profile(TIFF *tif, FIBITMAP *dib) {
-	char defaultKey[16];
-
-	if(FreeImage_GetMetadataCount(FIMD_GEOTIFF, dib) == 0) {
-		return;
-	}
-
-	size_t tag_size = sizeof(xtiffFieldInfo) / sizeof(xtiffFieldInfo[0]);
-
-	TagLib& tag_lib = TagLib::instance();
-
-	for(unsigned i = 0; i < tag_size; i++) {
-		const TIFFFieldInfo *fieldInfo = &xtiffFieldInfo[i];
-
-		FITAG *tag = NULL;
-		const char *key = tag_lib.getTagFieldName(TagLib::GEOTIFF, (WORD)fieldInfo->field_tag, defaultKey);
-
-		if(FreeImage_GetMetadata(FIMD_GEOTIFF, dib, key, &tag)) {
-			if(FreeImage_GetTagType(tag) == FIDT_ASCII) {
-				TIFFSetField(tif, fieldInfo->field_tag, FreeImage_GetTagValue(tag));
-			} else {
-				TIFFSetField(tif, fieldInfo->field_tag, FreeImage_GetTagCount(tag), FreeImage_GetTagValue(tag));
-			}
-		}
-	}
-}
-
-// ----------------------------------------------------------
-//   EXIF tag reading & writing
-// ----------------------------------------------------------
-
-/**
-Read a single exif tag
-*/
-static BOOL 
-tiff_read_exif_tag(TIFF *tif, TagLib::MDMODEL md_model, FIBITMAP *dib, TagLib& tagLib, TIFFDirectory *td, ttag_t tag) {
-	const TIFFFieldInfo *fip;
-	uint32 value_count;
-	int mem_alloc = 0;
-	void *raw_data = NULL;
-
-	if(tag == TIFFTAG_EXIFIFD) {
-		return TRUE;
-	}
-
-	// get the tag key - use NULL to avoid reading GeoTIFF tags
-	const char *key = tagLib.getTagFieldName(md_model, (WORD)tag, NULL);
-	if(key == NULL) {
-		return TRUE;
-	}
-
-	fip = TIFFFieldWithTag(tif, tag);
-	if(fip == NULL) {
-		return TRUE;
-	}
-
-	// ### for some reason TIFFFieldWithTag returns wrong version (TIFF_LONG vs TIFF_SHORT) for some params, correct this
-	if(fip->field_tag == TIFFTAG_IMAGEWIDTH && fip->field_type == TIFF_SHORT) {
-		fip = TIFFFindFieldInfo(tif, tag, TIFF_LONG);
-	} else if(fip->field_tag == TIFFTAG_IMAGELENGTH && fip->field_type == TIFF_SHORT) {
-		fip = TIFFFindFieldInfo(tif, tag, TIFF_LONG);
-	} else if(fip->field_tag == TIFFTAG_BITSPERSAMPLE && fip->field_type == TIFF_LONG) {
-		fip = TIFFFindFieldInfo(tif, tag, TIFF_SHORT);
-	} else if(fip->field_tag == TIFFTAG_COMPRESSION && fip->field_type == TIFF_LONG) {
-		fip = TIFFFindFieldInfo(tif, tag, TIFF_SHORT);
-	} else if(fip->field_tag == TIFFTAG_PHOTOMETRIC && fip->field_type == TIFF_LONG) {
-		fip = TIFFFindFieldInfo(tif, tag, TIFF_SHORT);
-	} else if(fip->field_tag == TIFFTAG_ROWSPERSTRIP && fip->field_type == TIFF_SHORT) {
-		fip = TIFFFindFieldInfo(tif, tag, TIFF_LONG);
-	} else if(fip->field_tag == TIFFTAG_STRIPOFFSETS && fip->field_type == TIFF_SHORT) {
-		fip = TIFFFindFieldInfo(tif, tag, TIFF_LONG);
-	} else if(fip->field_tag == TIFFTAG_STRIPBYTECOUNTS && fip->field_type == TIFF_SHORT) {
-		fip = TIFFFindFieldInfo(tif, tag, TIFF_LONG);
-	}
-	// ### the tags left unchecked are SGI, Pixar and DNG tags filtered by tagLib.getTagFieldName 
-
-
-	if(fip->field_passcount) { //<- "passcount" means "returns count"
-		if (fip->field_readcount != TIFF_VARIABLE2) { //<- TIFF_VARIABLE2 means "uses LONG count"
-
-			// assume TIFF_VARIABLE (uses SHORT count)
-			uint16 value_count16;
-			if(TIFFGetField(tif, tag, &value_count16, &raw_data) != 1) {
-				return TRUE;
-			}
-			value_count = value_count16;
-		} else {
-			if(TIFFGetField(tif, tag, &value_count, &raw_data) != 1) {
-				return TRUE;
-			}
-		}
-	} else {
-
-		// determine count
-
-		if (fip->field_readcount == TIFF_VARIABLE || fip->field_readcount == TIFF_VARIABLE2) {
-			value_count = 1;
-		} else if (fip->field_readcount == TIFF_SPP) {
-			value_count = td->td_samplesperpixel;
-		} else {
-			value_count = fip->field_readcount;
-		}
-
-		// access fields as pointers to data
-		// (### determining this is NOT robust... and hardly can be. It is implemented looking the _TIFFVGetField code)
-
-		if(fip->field_tag == TIFFTAG_TRANSFERFUNCTION) {
-			// reading this tag cause a bug probably located somewhere inside libtiff
-			return TRUE;
-		}
-
-		if ((fip->field_type == TIFF_ASCII
-		     || fip->field_readcount == TIFF_VARIABLE
-		     || fip->field_readcount == TIFF_VARIABLE2
-		     || fip->field_readcount == TIFF_SPP
-			 || value_count > 1)
-			 
-			 && fip->field_tag != TIFFTAG_PAGENUMBER
-			 && fip->field_tag != TIFFTAG_HALFTONEHINTS
-			 && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING
-			 && fip->field_tag != TIFFTAG_DOTRANGE
-
-			 && fip->field_tag != TIFFTAG_BITSPERSAMPLE	//<- these two are tricky - 
-			 && fip->field_tag != TIFFTAG_COMPRESSION	//<- they are defined as TIFF_VARIABLE but in reality return a single value
-			 ) {
-				 if(TIFFGetField(tif, tag, &raw_data) != 1) {
-					 return TRUE;
-				 }
-		} else {
-
-			// access fields as values
-
-			const int value_size = _TIFFDataSize(fip->field_type);
-			raw_data = _TIFFmalloc(value_size * value_count);
-			mem_alloc = 1;
-			int ok = FALSE;
-			
-			// ### if value_count > 1, tag is PAGENUMBER or HALFTONEHINTS or YCBCRSUBSAMPLING or DOTRANGE, 
-			// all off which are value_count == 2 (see tif_dirinfo.c)
-			switch(value_count)
-			{
-				case 1:
-					ok = TIFFGetField(tif, tag, raw_data);
-					break;
-				case 2:
-					ok = TIFFGetField(tif, tag, raw_data, (BYTE*)(raw_data) + value_size*1);
-					break;
-/* # we might need more in the future:
-				case 3:
-					ok = TIFFGetField(tif, tag, raw_data, (BYTE*)(raw_data) + value_size*1, (BYTE*)(raw_data) + value_size*2);
-					break;
-*/
-				default:
-					FreeImage_OutputMessageProc(FIF_TIFF, "Unimplemented variable number of parameters for Tiff Tag %s", fip->field_name);
-					break;
-			}
-			if(ok != 1) {
-				_TIFFfree(raw_data);
-				return TRUE;
-			}
-		}
-	}
-
-	// build FreeImage tag from Tiff Tag data we collected
-
-	FITAG *fitag = FreeImage_CreateTag();
-	if(!fitag) {
-		if(mem_alloc) {
-			_TIFFfree(raw_data);
-		}
-		return FALSE;
-	}
-
-	FreeImage_SetTagID(fitag, (WORD)tag);
-	FreeImage_SetTagKey(fitag, key);
-
-	switch(fip->field_type) {
-		case TIFF_BYTE:
-			FreeImage_SetTagType(fitag, FIDT_BYTE);
-			FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
-			FreeImage_SetTagCount(fitag, value_count);
-			FreeImage_SetTagValue(fitag, raw_data);
-			break;
-
-		case TIFF_UNDEFINED:
-			FreeImage_SetTagType(fitag, FIDT_UNDEFINED);
-			FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
-			FreeImage_SetTagCount(fitag, value_count);
-			FreeImage_SetTagValue(fitag, raw_data);
-			break;
-
-		case TIFF_SBYTE:
-			FreeImage_SetTagType(fitag, FIDT_SBYTE);
-			FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
-			FreeImage_SetTagCount(fitag, value_count);
-			FreeImage_SetTagValue(fitag, raw_data);
-			break;
-
-		case TIFF_SHORT:
-			FreeImage_SetTagType(fitag, FIDT_SHORT);
-			FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
-			FreeImage_SetTagCount(fitag, value_count);
-			FreeImage_SetTagValue(fitag, raw_data);
-			break;
-
-		case TIFF_SSHORT:
-			FreeImage_SetTagType(fitag, FIDT_SSHORT);
-			FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
-			FreeImage_SetTagCount(fitag, value_count);
-			FreeImage_SetTagValue(fitag, raw_data);
-			break;
-
-		case TIFF_LONG:
-			FreeImage_SetTagType(fitag, FIDT_LONG);
-			FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
-			FreeImage_SetTagCount(fitag, value_count);
-			FreeImage_SetTagValue(fitag, raw_data);
-			break;
-
-		case TIFF_IFD:
-			FreeImage_SetTagType(fitag, FIDT_IFD);
-			FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
-			FreeImage_SetTagCount(fitag, value_count);
-			FreeImage_SetTagValue(fitag, raw_data);
-			break;
-
-		case TIFF_SLONG:
-			FreeImage_SetTagType(fitag, FIDT_SLONG);
-			FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
-			FreeImage_SetTagCount(fitag, value_count);
-			FreeImage_SetTagValue(fitag, raw_data);
-			break;
-
-		case TIFF_RATIONAL: {
-			// LibTIFF converts rational to floats : reconvert floats to rationals
-			DWORD *rvalue = (DWORD*)malloc(2 * value_count * sizeof(DWORD));
-			for(uint32 i = 0; i < value_count; i++) {
-				float *fv = (float*)raw_data;
-				FIRational rational(fv[i]);
-				rvalue[2*i] = rational.getNumerator();
-				rvalue[2*i+1] = rational.getDenominator();
-			}
-			FreeImage_SetTagType(fitag, FIDT_RATIONAL);
-			FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
-			FreeImage_SetTagCount(fitag, value_count);
-			FreeImage_SetTagValue(fitag, rvalue);
-			free(rvalue);
-		}
-		break;
-
-		case TIFF_SRATIONAL: {
-			// LibTIFF converts rational to floats : reconvert floats to rationals
-			LONG *rvalue = (LONG*)malloc(2 * value_count * sizeof(LONG));
-			for(uint32 i = 0; i < value_count; i++) {
-				float *fv = (float*)raw_data;
-				FIRational rational(fv[i]);
-				rvalue[2*i] = rational.getNumerator();
-				rvalue[2*i+1] = rational.getDenominator();
-			}
-			FreeImage_SetTagType(fitag, FIDT_RATIONAL);
-			FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
-			FreeImage_SetTagCount(fitag, value_count);
-			FreeImage_SetTagValue(fitag, rvalue);
-			free(rvalue);
-		}
-		break;
-
-		case TIFF_FLOAT:
-			FreeImage_SetTagType(fitag, FIDT_FLOAT);
-			FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
-			FreeImage_SetTagCount(fitag, value_count);
-			FreeImage_SetTagValue(fitag, raw_data);
-			break;
-
-		case TIFF_DOUBLE:
-			FreeImage_SetTagType(fitag, FIDT_DOUBLE);
-			FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
-			FreeImage_SetTagCount(fitag, value_count);
-			FreeImage_SetTagValue(fitag, raw_data);
-			break;
-
-		default: {
-			size_t length = strlen((char*)raw_data) + 1;
-			FreeImage_SetTagType(fitag, FIDT_ASCII);
-			FreeImage_SetTagLength(fitag, (DWORD)length);
-			FreeImage_SetTagCount(fitag, (DWORD)length);
-			FreeImage_SetTagValue(fitag, raw_data);
-		}
-		break;
-	}
-
-	const char *description = tagLib.getTagDescription(md_model, (WORD)tag);
-	if(description) {
-		FreeImage_SetTagDescription(fitag, description);
-	}
-	// store the tag
-	FreeImage_SetMetadata(tagLib.getFreeImageModel(md_model), dib, FreeImage_GetTagKey(fitag), fitag);
-
-	// destroy the tag
-	FreeImage_DeleteTag(fitag);
-
-	if(mem_alloc) {
-		_TIFFfree(raw_data);
-	}
-	return TRUE;
-}
-
-/**
-Read all known exif tags
-*/
-BOOL 
-tiff_read_exif_tags(TIFF *tif, TagLib::MDMODEL md_model, FIBITMAP *dib) {
-	int  i;
-	short count;
-
-	TagLib& tagLib = TagLib::instance();
-
-	TIFFDirectory *td = &tif->tif_dir;
-
-	count = (short) TIFFGetTagListCount(tif);
-	for(i = 0; i < count; i++) {
-		ttag_t tag = TIFFGetTagListEntry(tif, i);
-		// read the tag
-		if (!tiff_read_exif_tag(tif, md_model, dib, tagLib, td, tag))
-			return FALSE;
-	}
-
-	// we want to know values of standard tags too!!
-
-	// loop over all Core Directory Tags
-	// ### uses private data, but there is no other way
-	if(md_model == TagLib::EXIF_MAIN) {
-
-		ttag_t lastTag = 0;	//<- used to prevent reading some tags twice (as stored in tif_fieldinfo)
-
-		for (int fi = 0, nfi = (int)tif->tif_nfields; nfi > 0; nfi--, fi++) {
-			const TIFFFieldInfo* fip = tif->tif_fieldinfo[fi];
-
-			if(fip->field_tag == lastTag)
-				continue;
-
-			// test if tag value is set
-			// (lifted directly form LibTiff _TIFFWriteDirectory)
-
-			if( fip->field_bit == FIELD_CUSTOM ) {
-				int ci, is_set = FALSE;
-
-				for( ci = 0; ci < td->td_customValueCount; ci++ ) {
-					is_set |= (td->td_customValues[ci].info == fip);
-				}
-
-				if( !is_set ) {
-					continue;
-				}
-
-			} else if(!TIFFFieldSet(tif, fip->field_bit)) {
-				continue;
-			}
-
-			// process *all* other tags (some will be ignored)
-
-			tiff_read_exif_tag(tif, md_model, dib, tagLib, td, fip->field_tag);
-
-
-			lastTag = fip->field_tag;
-		}
-
-	}
-
-	return TRUE;
-
-}
-
-
-/**
-Skip tags that are already handled by the LibTIFF writing process
-*/
-static BOOL 
-skip_write_field(TIFF* tif, ttag_t tag) {
-	switch (tag) {
-		case TIFFTAG_SAMPLEFORMAT:
-		case TIFFTAG_IMAGEWIDTH:
-		case TIFFTAG_IMAGELENGTH:
-		case TIFFTAG_SAMPLESPERPIXEL:
-		case TIFFTAG_BITSPERSAMPLE:
-		case TIFFTAG_PHOTOMETRIC:
-		case TIFFTAG_PLANARCONFIG:
-		case TIFFTAG_ROWSPERSTRIP:
-		case TIFFTAG_RESOLUTIONUNIT:
-		case TIFFTAG_XRESOLUTION:
-		case TIFFTAG_YRESOLUTION:
-		case TIFFTAG_SUBFILETYPE:
-		case TIFFTAG_PAGENUMBER:
-		case TIFFTAG_COLORMAP:
-		case TIFFTAG_ORIENTATION:
-		case TIFFTAG_COMPRESSION:
-		case TIFFTAG_PREDICTOR:
-		case TIFFTAG_GROUP3OPTIONS:
-		case TIFFTAG_FILLORDER:
-			// skip always, values have been set in SaveOneTIFF()
-			return TRUE;
-			break;
-		
-		case TIFFTAG_RICHTIFFIPTC:
-			// skip always, IPTC metadata model is set in tiff_write_iptc_profile()
-			return TRUE;
-			break;
-
-		case TIFFTAG_YCBCRCOEFFICIENTS:
-		case TIFFTAG_REFERENCEBLACKWHITE:
-		case TIFFTAG_YCBCRSUBSAMPLING:
-			// skip as they cannot be filled yet
-			return TRUE;
-			break;
-			
-		case TIFFTAG_PAGENAME:
-		{
-			char *value = NULL;
-			TIFFGetField(tif, TIFFTAG_PAGENAME, &value);
-			// only skip if no value has been set
-			if(value == NULL) {
-				return FALSE;
-			} else {
-				return TRUE;
-			}
-		}
-		default:
-			return FALSE;
-			break;
-	}
-}
-
-/**
-Write all known exif tags
-*/
-BOOL 
-tiff_write_exif_tags(TIFF *tif, TagLib::MDMODEL md_model, FIBITMAP *dib) {
-	char defaultKey[16];
-	size_t tag_size = 0;
-	const TIFFFieldInfo *tiffFieldInfos;
-	
-	// only EXIF_MAIN so far
-	if(md_model != TagLib::EXIF_MAIN) {
-		return FALSE;
-	}
-	
-	if(FreeImage_GetMetadataCount(FIMD_EXIF_MAIN, dib) == 0) {
-		return FALSE;
-	}
-	
-	TagLib& tag_lib = TagLib::instance();
-	tiffFieldInfos = _TIFFGetFieldInfo(&tag_size);
-
-	for(size_t i = 0; i < tag_size; i++) {
-		const TIFFFieldInfo *fieldInfo = &tiffFieldInfos[i];
-
-		if(skip_write_field(tif, fieldInfo->field_tag)) {
-			// skip tags that are already handled by the LibTIFF writing process
-			continue;
-		}
-
-		FITAG *tag = NULL;
-		// get the tag key
-		const char *key = tag_lib.getTagFieldName(TagLib::EXIF_MAIN, (WORD)fieldInfo->field_tag, defaultKey);
-
-		if(FreeImage_GetMetadata(FIMD_EXIF_MAIN, dib, key, &tag)) {
-			FREE_IMAGE_MDTYPE tag_type = FreeImage_GetTagType(tag);
-			TIFFDataType tif_tag_type = fieldInfo->field_type;
-			
-			// check for identical formats
-
-			// (enum value are the sames between FREE_IMAGE_MDTYPE and TIFFDataType types)
-			if((int)tif_tag_type != (int)tag_type) {
-				// skip tag or _TIFFmemcpy will fail
-				continue;
-			}
-			// type of storage may differ (e.g. rationnal array vs float array type)
-			if(_TIFFDataSize(tif_tag_type) != FreeImage_TagDataWidth(tag_type)) {
-				// skip tag or _TIFFmemcpy will fail
-				continue;
-			}
-
-			if(tag_type == FIDT_ASCII) {
-				TIFFSetField(tif, fieldInfo->field_tag, FreeImage_GetTagValue(tag));
-			} else {
-				TIFFSetField(tif, fieldInfo->field_tag, FreeImage_GetTagCount(tag), FreeImage_GetTagValue(tag));
-			}
-		}
-	}
-
-	return TRUE;
-}
diff --git a/Source/LibTIFF/makefile.vc b/Source/LibTIFF/makefile.vc
deleted file mode 100644
index 2544541..0000000
--- a/Source/LibTIFF/makefile.vc
+++ /dev/null
@@ -1,102 +0,0 @@
-# $Id: makefile.vc,v 1.37 2011/04/10 17:14:09 drolon Exp $
-#
-# Copyright (C) 2004, Andrey Kiselev <dron at ak4719.spb.edu>
-#
-# Permission to use, copy, modify, distribute, and sell this software and 
-# its documentation for any purpose is hereby granted without fee, provided
-# that (i) the above copyright notices and this permission notice appear in
-# all copies of the software and related documentation, and (ii) the names of
-# Sam Leffler and Silicon Graphics may not be used in any advertising or
-# publicity relating to the software without the specific, prior written
-# permission of Sam Leffler and Silicon Graphics.
-# 
-# THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
-# EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
-# WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
-# 
-# IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
-# ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
-# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-# WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
-# LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
-# OF THIS SOFTWARE.
-#
-# Makefile for MS Visual C and Watcom C compilers.
-#
-# To build:
-# C:\libtiff\libtiff> nmake /f makefile.vc all
-#
-
-!INCLUDE ..\nmake.opt
-
-INCL	= -I. $(JPEG_INCLUDE) $(ZLIB_INCLUDE) $(JBIG_INCLUDE)
-
-!IFDEF USE_WIN_CRT_LIB
-OBJ_SYSDEP_MODULE = tif_unix.obj
-!ELSE
-OBJ_SYSDEP_MODULE = tif_win32.obj
-!ENDIF
-
-OBJ	= \
-	tif_aux.obj \
-	tif_close.obj \
-	tif_codec.obj \
-	tif_color.obj \
-	tif_compress.obj \
-	tif_dir.obj \
-	tif_dirinfo.obj \
-	tif_dirread.obj \
-	tif_dirwrite.obj \
-	tif_dumpmode.obj \
-	tif_error.obj \
-	tif_extension.obj \
-	tif_fax3.obj \
-	tif_fax3sm.obj \
-	tif_getimage.obj \
-	tif_jbig.obj \
-	tif_jpeg.obj \
-	tif_ojpeg.obj \
-	tif_flush.obj \
-	tif_luv.obj \
-	tif_lzw.obj \
-	tif_next.obj \
-	tif_open.obj \
-	tif_packbits.obj \
-	tif_pixarlog.obj \
-	tif_predict.obj \
-	tif_print.obj \
-	tif_read.obj \
-	tif_stream.obj \
-	tif_swab.obj \
-	tif_strip.obj \
-	tif_thunder.obj \
-	tif_tile.obj \
-	tif_version.obj \
-	tif_warning.obj \
-	tif_write.obj \
-	tif_zip.obj \
-	tif_jbig.obj \
-	$(OBJ_SYSDEP_MODULE)
-
-all:	libtiff.lib $(DLLNAME)
-
-tif_config.h:	tif_config.vc.h
-	copy tif_config.vc.h tif_config.h
-
-tiffconf.h:	tiffconf.vc.h
-	copy tiffconf.vc.h tiffconf.h
-
-libtiff.lib:	tif_config.h tiffconf.h $(OBJ)
-	$(AR) /out:libtiff.lib $(OBJ) $(LIBS)
-
-$(DLLNAME):	tif_config.h tiffconf.h libtiff.def $(OBJ)
-	$(LD) /debug /dll /def:libtiff.def /out:$(DLLNAME) \
-	/implib:libtiff_i.lib $(OBJ) $(LIBS)
-	
-clean:
-	-del tif_config.h tiffconf.h
-	-del *.obj
-	-del *.lib
-	-del *.dll
-	-del *.exe
-	-del *.pdb
diff --git a/Source/LibTIFF/mkg3states.c b/Source/LibTIFF/mkg3states.c
deleted file mode 100644
index 46fac37..0000000
--- a/Source/LibTIFF/mkg3states.c
+++ /dev/null
@@ -1,451 +0,0 @@
-/* "$Id: mkg3states.c,v 1.37 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1991-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/* Initialise fax decoder tables
- * Decoder support is derived, with permission, from the code
- * in Frank Cringle's viewfax program;
- *      Copyright (C) 1990, 1995  Frank D. Cringle.
- */
-#include "tif_config.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
-#include "tif_fax3.h"
-
-#ifndef HAVE_GETOPT
-extern int getopt(int, char**, char*);
-#endif
-
-#define	streq(a,b)	(strcmp(a,b) == 0)
-
-/* NB: can't use names in tif_fax3.h 'cuz they are declared const */
-TIFFFaxTabEnt MainTable[128];
-TIFFFaxTabEnt WhiteTable[4096];
-TIFFFaxTabEnt BlackTable[8192];
-
-struct proto {
-    uint16 code;		/* right justified, lsb-first, zero filled */
-    uint16 val;		/* (pixel count)<<4 + code width  */
-};
-
-static struct proto Pass[] = {
-{ 0x0008, 4 },
-{ 0, 0 }
-};
-
-static struct proto Horiz[]  = {
-{ 0x0004, 3 },
-{ 0, 0 }
-};
-
-static struct proto V0[]  = {
-{ 0x0001, 1 },
-{ 0, 0 }
-};
-
-static struct proto VR[]  = {
-{ 0x0006, (1<<4)+3 },
-{ 0x0030, (2<<4)+6 },
-{ 0x0060, (3<<4)+7 },
-{ 0, 0 }
-};
-
-static struct proto VL[]  = {
-{ 0x0002, (1<<4)+3 },
-{ 0x0010, (2<<4)+6 },
-{ 0x0020, (3<<4)+7 },
-{ 0, 0 }
-};
-
-static struct proto Ext[]  = {
-{ 0x0040, 7 },
-{ 0, 0 }
-};
-
-static struct proto EOLV[]  = {
-{ 0x0000, 7 },
-{ 0, 0 }
-};
-
-static struct proto MakeUpW[] = {
-{ 0x001b, 1029 },
-{ 0x0009, 2053 },
-{ 0x003a, 3078 },
-{ 0x0076, 4103 },
-{ 0x006c, 5128 },
-{ 0x00ec, 6152 },
-{ 0x0026, 7176 },
-{ 0x00a6, 8200 },
-{ 0x0016, 9224 },
-{ 0x00e6, 10248 },
-{ 0x0066, 11273 },
-{ 0x0166, 12297 },
-{ 0x0096, 13321 },
-{ 0x0196, 14345 },
-{ 0x0056, 15369 },
-{ 0x0156, 16393 },
-{ 0x00d6, 17417 },
-{ 0x01d6, 18441 },
-{ 0x0036, 19465 },
-{ 0x0136, 20489 },
-{ 0x00b6, 21513 },
-{ 0x01b6, 22537 },
-{ 0x0032, 23561 },
-{ 0x0132, 24585 },
-{ 0x00b2, 25609 },
-{ 0x0006, 26630 },
-{ 0x01b2, 27657 },
-{ 0, 0 }
-};
-
-static struct proto MakeUpB[] = {
-{ 0x03c0, 1034 },
-{ 0x0130, 2060 },
-{ 0x0930, 3084 },
-{ 0x0da0, 4108 },
-{ 0x0cc0, 5132 },
-{ 0x02c0, 6156 },
-{ 0x0ac0, 7180 },
-{ 0x06c0, 8205 },
-{ 0x16c0, 9229 },
-{ 0x0a40, 10253 },
-{ 0x1a40, 11277 },
-{ 0x0640, 12301 },
-{ 0x1640, 13325 },
-{ 0x09c0, 14349 },
-{ 0x19c0, 15373 },
-{ 0x05c0, 16397 },
-{ 0x15c0, 17421 },
-{ 0x0dc0, 18445 },
-{ 0x1dc0, 19469 },
-{ 0x0940, 20493 },
-{ 0x1940, 21517 },
-{ 0x0540, 22541 },
-{ 0x1540, 23565 },
-{ 0x0b40, 24589 },
-{ 0x1b40, 25613 },
-{ 0x04c0, 26637 },
-{ 0x14c0, 27661 },
-{ 0, 0 }
-};
-
-static struct proto MakeUp[] = {
-{ 0x0080, 28683 },
-{ 0x0180, 29707 },
-{ 0x0580, 30731 },
-{ 0x0480, 31756 },
-{ 0x0c80, 32780 },
-{ 0x0280, 33804 },
-{ 0x0a80, 34828 },
-{ 0x0680, 35852 },
-{ 0x0e80, 36876 },
-{ 0x0380, 37900 },
-{ 0x0b80, 38924 },
-{ 0x0780, 39948 },
-{ 0x0f80, 40972 },
-{ 0, 0 }
-};
-
-static struct proto TermW[] = {
-{ 0x00ac, 8 },
-{ 0x0038, 22 },
-{ 0x000e, 36 },
-{ 0x0001, 52 },
-{ 0x000d, 68 },
-{ 0x0003, 84 },
-{ 0x0007, 100 },
-{ 0x000f, 116 },
-{ 0x0019, 133 },
-{ 0x0005, 149 },
-{ 0x001c, 165 },
-{ 0x0002, 181 },
-{ 0x0004, 198 },
-{ 0x0030, 214 },
-{ 0x000b, 230 },
-{ 0x002b, 246 },
-{ 0x0015, 262 },
-{ 0x0035, 278 },
-{ 0x0072, 295 },
-{ 0x0018, 311 },
-{ 0x0008, 327 },
-{ 0x0074, 343 },
-{ 0x0060, 359 },
-{ 0x0010, 375 },
-{ 0x000a, 391 },
-{ 0x006a, 407 },
-{ 0x0064, 423 },
-{ 0x0012, 439 },
-{ 0x000c, 455 },
-{ 0x0040, 472 },
-{ 0x00c0, 488 },
-{ 0x0058, 504 },
-{ 0x00d8, 520 },
-{ 0x0048, 536 },
-{ 0x00c8, 552 },
-{ 0x0028, 568 },
-{ 0x00a8, 584 },
-{ 0x0068, 600 },
-{ 0x00e8, 616 },
-{ 0x0014, 632 },
-{ 0x0094, 648 },
-{ 0x0054, 664 },
-{ 0x00d4, 680 },
-{ 0x0034, 696 },
-{ 0x00b4, 712 },
-{ 0x0020, 728 },
-{ 0x00a0, 744 },
-{ 0x0050, 760 },
-{ 0x00d0, 776 },
-{ 0x004a, 792 },
-{ 0x00ca, 808 },
-{ 0x002a, 824 },
-{ 0x00aa, 840 },
-{ 0x0024, 856 },
-{ 0x00a4, 872 },
-{ 0x001a, 888 },
-{ 0x009a, 904 },
-{ 0x005a, 920 },
-{ 0x00da, 936 },
-{ 0x0052, 952 },
-{ 0x00d2, 968 },
-{ 0x004c, 984 },
-{ 0x00cc, 1000 },
-{ 0x002c, 1016 },
-{ 0, 0 }
-};
-
-static struct proto TermB[] = {
-{ 0x03b0, 10 },
-{ 0x0002, 19 },
-{ 0x0003, 34 },
-{ 0x0001, 50 },
-{ 0x0006, 67 },
-{ 0x000c, 84 },
-{ 0x0004, 100 },
-{ 0x0018, 117 },
-{ 0x0028, 134 },
-{ 0x0008, 150 },
-{ 0x0010, 167 },
-{ 0x0050, 183 },
-{ 0x0070, 199 },
-{ 0x0020, 216 },
-{ 0x00e0, 232 },
-{ 0x0030, 249 },
-{ 0x03a0, 266 },
-{ 0x0060, 282 },
-{ 0x0040, 298 },
-{ 0x0730, 315 },
-{ 0x00b0, 331 },
-{ 0x01b0, 347 },
-{ 0x0760, 363 },
-{ 0x00a0, 379 },
-{ 0x0740, 395 },
-{ 0x00c0, 411 },
-{ 0x0530, 428 },
-{ 0x0d30, 444 },
-{ 0x0330, 460 },
-{ 0x0b30, 476 },
-{ 0x0160, 492 },
-{ 0x0960, 508 },
-{ 0x0560, 524 },
-{ 0x0d60, 540 },
-{ 0x04b0, 556 },
-{ 0x0cb0, 572 },
-{ 0x02b0, 588 },
-{ 0x0ab0, 604 },
-{ 0x06b0, 620 },
-{ 0x0eb0, 636 },
-{ 0x0360, 652 },
-{ 0x0b60, 668 },
-{ 0x05b0, 684 },
-{ 0x0db0, 700 },
-{ 0x02a0, 716 },
-{ 0x0aa0, 732 },
-{ 0x06a0, 748 },
-{ 0x0ea0, 764 },
-{ 0x0260, 780 },
-{ 0x0a60, 796 },
-{ 0x04a0, 812 },
-{ 0x0ca0, 828 },
-{ 0x0240, 844 },
-{ 0x0ec0, 860 },
-{ 0x01c0, 876 },
-{ 0x0e40, 892 },
-{ 0x0140, 908 },
-{ 0x01a0, 924 },
-{ 0x09a0, 940 },
-{ 0x0d40, 956 },
-{ 0x0340, 972 },
-{ 0x05a0, 988 },
-{ 0x0660, 1004 },
-{ 0x0e60, 1020 },
-{ 0, 0 }
-};
-
-static struct proto EOLH[] = {
-{ 0x0000, 11 },
-{ 0, 0 }
-};
-
-static void
-FillTable(TIFFFaxTabEnt *T, int Size, struct proto *P, int State)
-{
-    int limit = 1 << Size;
-
-    while (P->val) {
-	int width = P->val & 15;
-	int param = P->val >> 4;
-	int incr = 1 << width;
-	int code;
-	for (code = P->code; code < limit; code += incr) {
-	    TIFFFaxTabEnt *E = T+code;
-	    E->State = State;
-	    E->Width = width;
-	    E->Param = param;
-	}
-	P++;
-    }
-}
-
-static	char* storage_class = "";
-static	char* const_class = "";
-static	int packoutput = 1;
-static	char* prebrace = "";
-static	char* postbrace = "";
-
-void
-WriteTable(FILE* fd, const TIFFFaxTabEnt* T, int Size, const char* name)
-{
-    int i;
-    char* sep;
-
-    fprintf(fd, "%s %s TIFFFaxTabEnt %s[%d] = {",
-	storage_class, const_class, name, Size);
-    if (packoutput) {
-	sep = "\n";
-	for (i = 0; i < Size; i++) {
-	    fprintf(fd, "%s%s%d,%d,%d%s",
-		sep, prebrace, T->State, T->Width, (int) T->Param, postbrace);
-	    if (((i+1) % 10) == 0)
-		    sep = ",\n";
-	    else
-		    sep = ",";
-	    T++;
-	}
-    } else {
-	sep = "\n ";
-	for (i = 0; i < Size; i++) {
-	    fprintf(fd, "%s%s%3d,%3d,%4d%s",
-		sep, prebrace, T->State, T->Width, (int) T->Param, postbrace);
-	    if (((i+1) % 6) == 0)
-		    sep = ",\n ";
-	    else
-		    sep = ",";
-	    T++;
-	}
-    }
-    fprintf(fd, "\n};\n");
-}
-
-/* initialise the huffman code tables */
-int
-main(int argc, char* argv[])
-{
-    FILE* fd;
-    char* outputfile;
-    int c;
-    extern int optind;
-    extern char* optarg;
-
-    while ((c = getopt(argc, argv, "c:s:bp")) != -1)
-	switch (c) {
-	case 'c':
-	    const_class = optarg;
-	    break;
-	case 's':
-	    storage_class = optarg;
-	    break;
-	case 'p':
-	    packoutput = 0;
-	    break;
-	case 'b':
-	    prebrace = "{";
-	    postbrace = "}";
-	    break;
-	case '?':
-	    fprintf(stderr,
-		"usage: %s [-c const] [-s storage] [-p] [-b] file\n",
-		argv[0]);
-	    return (-1);
-	}
-    outputfile = optind < argc ? argv[optind] : "g3states.h";
-    fd = fopen(outputfile, "w");
-    if (fd == NULL) {
-	fprintf(stderr, "%s: %s: Cannot create output file.\n",
-	    argv[0], outputfile);
-	return (-2);
-    }
-    FillTable(MainTable, 7, Pass, S_Pass);
-    FillTable(MainTable, 7, Horiz, S_Horiz);
-    FillTable(MainTable, 7, V0, S_V0);
-    FillTable(MainTable, 7, VR, S_VR);
-    FillTable(MainTable, 7, VL, S_VL);
-    FillTable(MainTable, 7, Ext, S_Ext);
-    FillTable(MainTable, 7, EOLV, S_EOL);
-    FillTable(WhiteTable, 12, MakeUpW, S_MakeUpW);
-    FillTable(WhiteTable, 12, MakeUp, S_MakeUp);
-    FillTable(WhiteTable, 12, TermW, S_TermW);
-    FillTable(WhiteTable, 12, EOLH, S_EOL);
-    FillTable(BlackTable, 13, MakeUpB, S_MakeUpB);
-    FillTable(BlackTable, 13, MakeUp, S_MakeUp);
-    FillTable(BlackTable, 13, TermB, S_TermB);
-    FillTable(BlackTable, 13, EOLH, S_EOL);
-
-    fprintf(fd, "/* WARNING, this file was automatically generated by the\n");
-    fprintf(fd, "    mkg3states program */\n");
-    fprintf(fd, "#include \"tiff.h\"\n");
-    fprintf(fd, "#include \"tif_fax3.h\"\n");
-    WriteTable(fd, MainTable, 128, "TIFFFaxMainTable");
-    WriteTable(fd, WhiteTable, 4096, "TIFFFaxWhiteTable");
-    WriteTable(fd, BlackTable, 8192, "TIFFFaxBlackTable");
-    fclose(fd);
-    return (0);
-}
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/mkspans.c b/Source/LibTIFF/mkspans.c
deleted file mode 100644
index 61be306..0000000
--- a/Source/LibTIFF/mkspans.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/* $Id: mkspans.c,v 1.22 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1991-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-#include <string.h>
-#include <stdio.h>
-
-/*
- * Hack program to construct tables used to find
- * runs of zeros and ones in Group 3 Fax encoding.
- */
-
-dumparray(name, runs)
-	char *name;
-	unsigned char runs[256];
-{
-	int i;
-	char *sep;
-	printf("static unsigned char %s[256] = {\n", name);
-	sep = "    ";
-	for (i = 0; i < 256; i++) {
-		printf("%s%d", sep, runs[i]);
-		if (((i + 1) % 16) == 0) {
-			printf(",	/* 0x%02x - 0x%02x */\n", i-15, i);
-			sep = "    ";
-		} else
-			sep = ", ";
-	}
-	printf("\n};\n");
-}
-
-main()
-{
-	unsigned char runs[2][256];
-
-	memset(runs[0], 0, 256*sizeof (char));
-	memset(runs[1], 0, 256*sizeof (char));
-	{ register int run, runlen, i;
-	  runlen = 1;
-	  for (run = 0x80; run != 0xff; run = (run>>1)|0x80) {
-		for (i = run-1; i >= 0; i--) {
-			runs[1][run|i] = runlen;
-			runs[0][(~(run|i)) & 0xff] = runlen;
-		}
-		runlen++;
-	  }
-	  runs[1][0xff] = runs[0][0] = 8;
-	}
-	dumparray("bruns", runs[0]);
-	dumparray("wruns", runs[1]);
-}
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/t4.h b/Source/LibTIFF/t4.h
deleted file mode 100644
index bf366ad..0000000
--- a/Source/LibTIFF/t4.h
+++ /dev/null
@@ -1,292 +0,0 @@
-/* $Id: t4.h,v 1.37 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-#ifndef _T4_
-#define	_T4_
-/*
- * CCITT T.4 1D Huffman runlength codes and
- * related definitions.  Given the small sizes
- * of these tables it does not seem
- * worthwhile to make code & length 8 bits.
- */
-typedef struct tableentry {
-    unsigned short length;	/* bit length of g3 code */
-    unsigned short code;	/* g3 code */
-    short	runlen;		/* run length in bits */
-} tableentry;
-
-#define	EOL	0x001	/* EOL code value - 0000 0000 0000 1 */
-
-/* status values returned instead of a run length */
-#define	G3CODE_EOL	-1	/* NB: ACT_EOL - ACT_WRUNT */
-#define	G3CODE_INVALID	-2	/* NB: ACT_INVALID - ACT_WRUNT */
-#define	G3CODE_EOF	-3	/* end of input data */
-#define	G3CODE_INCOMP	-4	/* incomplete run code */
-
-/*
- * Note that these tables are ordered such that the
- * index into the table is known to be either the
- * run length, or (run length / 64) + a fixed offset.
- *
- * NB: The G3CODE_INVALID entries are only used
- *     during state generation (see mkg3states.c).
- */
-#ifdef G3CODES
-const tableentry TIFFFaxWhiteCodes[] = {
-    { 8, 0x35, 0 },	/* 0011 0101 */
-    { 6, 0x7, 1 },	/* 0001 11 */
-    { 4, 0x7, 2 },	/* 0111 */
-    { 4, 0x8, 3 },	/* 1000 */
-    { 4, 0xB, 4 },	/* 1011 */
-    { 4, 0xC, 5 },	/* 1100 */
-    { 4, 0xE, 6 },	/* 1110 */
-    { 4, 0xF, 7 },	/* 1111 */
-    { 5, 0x13, 8 },	/* 1001 1 */
-    { 5, 0x14, 9 },	/* 1010 0 */
-    { 5, 0x7, 10 },	/* 0011 1 */
-    { 5, 0x8, 11 },	/* 0100 0 */
-    { 6, 0x8, 12 },	/* 0010 00 */
-    { 6, 0x3, 13 },	/* 0000 11 */
-    { 6, 0x34, 14 },	/* 1101 00 */
-    { 6, 0x35, 15 },	/* 1101 01 */
-    { 6, 0x2A, 16 },	/* 1010 10 */
-    { 6, 0x2B, 17 },	/* 1010 11 */
-    { 7, 0x27, 18 },	/* 0100 111 */
-    { 7, 0xC, 19 },	/* 0001 100 */
-    { 7, 0x8, 20 },	/* 0001 000 */
-    { 7, 0x17, 21 },	/* 0010 111 */
-    { 7, 0x3, 22 },	/* 0000 011 */
-    { 7, 0x4, 23 },	/* 0000 100 */
-    { 7, 0x28, 24 },	/* 0101 000 */
-    { 7, 0x2B, 25 },	/* 0101 011 */
-    { 7, 0x13, 26 },	/* 0010 011 */
-    { 7, 0x24, 27 },	/* 0100 100 */
-    { 7, 0x18, 28 },	/* 0011 000 */
-    { 8, 0x2, 29 },	/* 0000 0010 */
-    { 8, 0x3, 30 },	/* 0000 0011 */
-    { 8, 0x1A, 31 },	/* 0001 1010 */
-    { 8, 0x1B, 32 },	/* 0001 1011 */
-    { 8, 0x12, 33 },	/* 0001 0010 */
-    { 8, 0x13, 34 },	/* 0001 0011 */
-    { 8, 0x14, 35 },	/* 0001 0100 */
-    { 8, 0x15, 36 },	/* 0001 0101 */
-    { 8, 0x16, 37 },	/* 0001 0110 */
-    { 8, 0x17, 38 },	/* 0001 0111 */
-    { 8, 0x28, 39 },	/* 0010 1000 */
-    { 8, 0x29, 40 },	/* 0010 1001 */
-    { 8, 0x2A, 41 },	/* 0010 1010 */
-    { 8, 0x2B, 42 },	/* 0010 1011 */
-    { 8, 0x2C, 43 },	/* 0010 1100 */
-    { 8, 0x2D, 44 },	/* 0010 1101 */
-    { 8, 0x4, 45 },	/* 0000 0100 */
-    { 8, 0x5, 46 },	/* 0000 0101 */
-    { 8, 0xA, 47 },	/* 0000 1010 */
-    { 8, 0xB, 48 },	/* 0000 1011 */
-    { 8, 0x52, 49 },	/* 0101 0010 */
-    { 8, 0x53, 50 },	/* 0101 0011 */
-    { 8, 0x54, 51 },	/* 0101 0100 */
-    { 8, 0x55, 52 },	/* 0101 0101 */
-    { 8, 0x24, 53 },	/* 0010 0100 */
-    { 8, 0x25, 54 },	/* 0010 0101 */
-    { 8, 0x58, 55 },	/* 0101 1000 */
-    { 8, 0x59, 56 },	/* 0101 1001 */
-    { 8, 0x5A, 57 },	/* 0101 1010 */
-    { 8, 0x5B, 58 },	/* 0101 1011 */
-    { 8, 0x4A, 59 },	/* 0100 1010 */
-    { 8, 0x4B, 60 },	/* 0100 1011 */
-    { 8, 0x32, 61 },	/* 0011 0010 */
-    { 8, 0x33, 62 },	/* 0011 0011 */
-    { 8, 0x34, 63 },	/* 0011 0100 */
-    { 5, 0x1B, 64 },	/* 1101 1 */
-    { 5, 0x12, 128 },	/* 1001 0 */
-    { 6, 0x17, 192 },	/* 0101 11 */
-    { 7, 0x37, 256 },	/* 0110 111 */
-    { 8, 0x36, 320 },	/* 0011 0110 */
-    { 8, 0x37, 384 },	/* 0011 0111 */
-    { 8, 0x64, 448 },	/* 0110 0100 */
-    { 8, 0x65, 512 },	/* 0110 0101 */
-    { 8, 0x68, 576 },	/* 0110 1000 */
-    { 8, 0x67, 640 },	/* 0110 0111 */
-    { 9, 0xCC, 704 },	/* 0110 0110 0 */
-    { 9, 0xCD, 768 },	/* 0110 0110 1 */
-    { 9, 0xD2, 832 },	/* 0110 1001 0 */
-    { 9, 0xD3, 896 },	/* 0110 1001 1 */
-    { 9, 0xD4, 960 },	/* 0110 1010 0 */
-    { 9, 0xD5, 1024 },	/* 0110 1010 1 */
-    { 9, 0xD6, 1088 },	/* 0110 1011 0 */
-    { 9, 0xD7, 1152 },	/* 0110 1011 1 */
-    { 9, 0xD8, 1216 },	/* 0110 1100 0 */
-    { 9, 0xD9, 1280 },	/* 0110 1100 1 */
-    { 9, 0xDA, 1344 },	/* 0110 1101 0 */
-    { 9, 0xDB, 1408 },	/* 0110 1101 1 */
-    { 9, 0x98, 1472 },	/* 0100 1100 0 */
-    { 9, 0x99, 1536 },	/* 0100 1100 1 */
-    { 9, 0x9A, 1600 },	/* 0100 1101 0 */
-    { 6, 0x18, 1664 },	/* 0110 00 */
-    { 9, 0x9B, 1728 },	/* 0100 1101 1 */
-    { 11, 0x8, 1792 },	/* 0000 0001 000 */
-    { 11, 0xC, 1856 },	/* 0000 0001 100 */
-    { 11, 0xD, 1920 },	/* 0000 0001 101 */
-    { 12, 0x12, 1984 },	/* 0000 0001 0010 */
-    { 12, 0x13, 2048 },	/* 0000 0001 0011 */
-    { 12, 0x14, 2112 },	/* 0000 0001 0100 */
-    { 12, 0x15, 2176 },	/* 0000 0001 0101 */
-    { 12, 0x16, 2240 },	/* 0000 0001 0110 */
-    { 12, 0x17, 2304 },	/* 0000 0001 0111 */
-    { 12, 0x1C, 2368 },	/* 0000 0001 1100 */
-    { 12, 0x1D, 2432 },	/* 0000 0001 1101 */
-    { 12, 0x1E, 2496 },	/* 0000 0001 1110 */
-    { 12, 0x1F, 2560 },	/* 0000 0001 1111 */
-    { 12, 0x1, G3CODE_EOL },	/* 0000 0000 0001 */
-    { 9, 0x1, G3CODE_INVALID },	/* 0000 0000 1 */
-    { 10, 0x1, G3CODE_INVALID },	/* 0000 0000 01 */
-    { 11, 0x1, G3CODE_INVALID },	/* 0000 0000 001 */
-    { 12, 0x0, G3CODE_INVALID },	/* 0000 0000 0000 */
-};
-
-const tableentry TIFFFaxBlackCodes[] = {
-    { 10, 0x37, 0 },	/* 0000 1101 11 */
-    { 3, 0x2, 1 },	/* 010 */
-    { 2, 0x3, 2 },	/* 11 */
-    { 2, 0x2, 3 },	/* 10 */
-    { 3, 0x3, 4 },	/* 011 */
-    { 4, 0x3, 5 },	/* 0011 */
-    { 4, 0x2, 6 },	/* 0010 */
-    { 5, 0x3, 7 },	/* 0001 1 */
-    { 6, 0x5, 8 },	/* 0001 01 */
-    { 6, 0x4, 9 },	/* 0001 00 */
-    { 7, 0x4, 10 },	/* 0000 100 */
-    { 7, 0x5, 11 },	/* 0000 101 */
-    { 7, 0x7, 12 },	/* 0000 111 */
-    { 8, 0x4, 13 },	/* 0000 0100 */
-    { 8, 0x7, 14 },	/* 0000 0111 */
-    { 9, 0x18, 15 },	/* 0000 1100 0 */
-    { 10, 0x17, 16 },	/* 0000 0101 11 */
-    { 10, 0x18, 17 },	/* 0000 0110 00 */
-    { 10, 0x8, 18 },	/* 0000 0010 00 */
-    { 11, 0x67, 19 },	/* 0000 1100 111 */
-    { 11, 0x68, 20 },	/* 0000 1101 000 */
-    { 11, 0x6C, 21 },	/* 0000 1101 100 */
-    { 11, 0x37, 22 },	/* 0000 0110 111 */
-    { 11, 0x28, 23 },	/* 0000 0101 000 */
-    { 11, 0x17, 24 },	/* 0000 0010 111 */
-    { 11, 0x18, 25 },	/* 0000 0011 000 */
-    { 12, 0xCA, 26 },	/* 0000 1100 1010 */
-    { 12, 0xCB, 27 },	/* 0000 1100 1011 */
-    { 12, 0xCC, 28 },	/* 0000 1100 1100 */
-    { 12, 0xCD, 29 },	/* 0000 1100 1101 */
-    { 12, 0x68, 30 },	/* 0000 0110 1000 */
-    { 12, 0x69, 31 },	/* 0000 0110 1001 */
-    { 12, 0x6A, 32 },	/* 0000 0110 1010 */
-    { 12, 0x6B, 33 },	/* 0000 0110 1011 */
-    { 12, 0xD2, 34 },	/* 0000 1101 0010 */
-    { 12, 0xD3, 35 },	/* 0000 1101 0011 */
-    { 12, 0xD4, 36 },	/* 0000 1101 0100 */
-    { 12, 0xD5, 37 },	/* 0000 1101 0101 */
-    { 12, 0xD6, 38 },	/* 0000 1101 0110 */
-    { 12, 0xD7, 39 },	/* 0000 1101 0111 */
-    { 12, 0x6C, 40 },	/* 0000 0110 1100 */
-    { 12, 0x6D, 41 },	/* 0000 0110 1101 */
-    { 12, 0xDA, 42 },	/* 0000 1101 1010 */
-    { 12, 0xDB, 43 },	/* 0000 1101 1011 */
-    { 12, 0x54, 44 },	/* 0000 0101 0100 */
-    { 12, 0x55, 45 },	/* 0000 0101 0101 */
-    { 12, 0x56, 46 },	/* 0000 0101 0110 */
-    { 12, 0x57, 47 },	/* 0000 0101 0111 */
-    { 12, 0x64, 48 },	/* 0000 0110 0100 */
-    { 12, 0x65, 49 },	/* 0000 0110 0101 */
-    { 12, 0x52, 50 },	/* 0000 0101 0010 */
-    { 12, 0x53, 51 },	/* 0000 0101 0011 */
-    { 12, 0x24, 52 },	/* 0000 0010 0100 */
-    { 12, 0x37, 53 },	/* 0000 0011 0111 */
-    { 12, 0x38, 54 },	/* 0000 0011 1000 */
-    { 12, 0x27, 55 },	/* 0000 0010 0111 */
-    { 12, 0x28, 56 },	/* 0000 0010 1000 */
-    { 12, 0x58, 57 },	/* 0000 0101 1000 */
-    { 12, 0x59, 58 },	/* 0000 0101 1001 */
-    { 12, 0x2B, 59 },	/* 0000 0010 1011 */
-    { 12, 0x2C, 60 },	/* 0000 0010 1100 */
-    { 12, 0x5A, 61 },	/* 0000 0101 1010 */
-    { 12, 0x66, 62 },	/* 0000 0110 0110 */
-    { 12, 0x67, 63 },	/* 0000 0110 0111 */
-    { 10, 0xF, 64 },	/* 0000 0011 11 */
-    { 12, 0xC8, 128 },	/* 0000 1100 1000 */
-    { 12, 0xC9, 192 },	/* 0000 1100 1001 */
-    { 12, 0x5B, 256 },	/* 0000 0101 1011 */
-    { 12, 0x33, 320 },	/* 0000 0011 0011 */
-    { 12, 0x34, 384 },	/* 0000 0011 0100 */
-    { 12, 0x35, 448 },	/* 0000 0011 0101 */
-    { 13, 0x6C, 512 },	/* 0000 0011 0110 0 */
-    { 13, 0x6D, 576 },	/* 0000 0011 0110 1 */
-    { 13, 0x4A, 640 },	/* 0000 0010 0101 0 */
-    { 13, 0x4B, 704 },	/* 0000 0010 0101 1 */
-    { 13, 0x4C, 768 },	/* 0000 0010 0110 0 */
-    { 13, 0x4D, 832 },	/* 0000 0010 0110 1 */
-    { 13, 0x72, 896 },	/* 0000 0011 1001 0 */
-    { 13, 0x73, 960 },	/* 0000 0011 1001 1 */
-    { 13, 0x74, 1024 },	/* 0000 0011 1010 0 */
-    { 13, 0x75, 1088 },	/* 0000 0011 1010 1 */
-    { 13, 0x76, 1152 },	/* 0000 0011 1011 0 */
-    { 13, 0x77, 1216 },	/* 0000 0011 1011 1 */
-    { 13, 0x52, 1280 },	/* 0000 0010 1001 0 */
-    { 13, 0x53, 1344 },	/* 0000 0010 1001 1 */
-    { 13, 0x54, 1408 },	/* 0000 0010 1010 0 */
-    { 13, 0x55, 1472 },	/* 0000 0010 1010 1 */
-    { 13, 0x5A, 1536 },	/* 0000 0010 1101 0 */
-    { 13, 0x5B, 1600 },	/* 0000 0010 1101 1 */
-    { 13, 0x64, 1664 },	/* 0000 0011 0010 0 */
-    { 13, 0x65, 1728 },	/* 0000 0011 0010 1 */
-    { 11, 0x8, 1792 },	/* 0000 0001 000 */
-    { 11, 0xC, 1856 },	/* 0000 0001 100 */
-    { 11, 0xD, 1920 },	/* 0000 0001 101 */
-    { 12, 0x12, 1984 },	/* 0000 0001 0010 */
-    { 12, 0x13, 2048 },	/* 0000 0001 0011 */
-    { 12, 0x14, 2112 },	/* 0000 0001 0100 */
-    { 12, 0x15, 2176 },	/* 0000 0001 0101 */
-    { 12, 0x16, 2240 },	/* 0000 0001 0110 */
-    { 12, 0x17, 2304 },	/* 0000 0001 0111 */
-    { 12, 0x1C, 2368 },	/* 0000 0001 1100 */
-    { 12, 0x1D, 2432 },	/* 0000 0001 1101 */
-    { 12, 0x1E, 2496 },	/* 0000 0001 1110 */
-    { 12, 0x1F, 2560 },	/* 0000 0001 1111 */
-    { 12, 0x1, G3CODE_EOL },	/* 0000 0000 0001 */
-    { 9, 0x1, G3CODE_INVALID },	/* 0000 0000 1 */
-    { 10, 0x1, G3CODE_INVALID },	/* 0000 0000 01 */
-    { 11, 0x1, G3CODE_INVALID },	/* 0000 0000 001 */
-    { 12, 0x0, G3CODE_INVALID },	/* 0000 0000 0000 */
-};
-#else
-extern	const tableentry TIFFFaxWhiteCodes[];
-extern	const tableentry TIFFFaxBlackCodes[];
-#endif
-#endif /* _T4_ */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_acorn.c b/Source/LibTIFF/tif_acorn.c
deleted file mode 100644
index d2de42d..0000000
--- a/Source/LibTIFF/tif_acorn.c
+++ /dev/null
@@ -1,526 +0,0 @@
-/* $Header: /cvsroot/freeimage/FreeImage/Source/LibTIFF/tif_acorn.c,v 1.37 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library RISC OS specific Routines.
- * Developed out of the Unix version.
- * Peter Greenham, May 1995
- */
-#include "tiffiop.h"
-#include <stdio.h>
-#include <stdlib.h>
-
-/*
-Low-level file handling
-~~~~~~~~~~~~~~~~~~~~~~~
-The functions in osfcn.h are unavailable when compiling under C, as it's a
-C++ header. Therefore they have been implemented here.
-
-Now, why have I done it this way?
-
-The definitive API library for RISC OS is Jonathan Coxhead's OSLib, which
-uses heavily optimised ARM assembler or even plain inline SWI calls for
-maximum performance and minimum runtime size. However, I don't want to make
-LIBTIFF need that to survive. Therefore I have also emulated the functions
-using macros to _swi() and _swix() defined in the swis.h header, and
-borrowing types from kernel.h, which is less efficient but doesn't need any
-third-party libraries.
- */
-
-#ifdef INCLUDE_OSLIB
-
-#include "osfile.h"
-#include "osgbpb.h"
-#include "osargs.h"
-#include "osfind.h"
-
-#else
-
-/* OSLIB EMULATION STARTS */
-
-#include "kernel.h"
-#include "swis.h"
-
-/* From oslib:types.h */
-typedef unsigned int                            bits;
-typedef unsigned char                           byte;
-#ifndef TRUE
-#define TRUE                                    1
-#endif
-#ifndef FALSE
-#define FALSE                                   0
-#endif
-#ifndef NULL
-#define NULL                                    0
-#endif
-#ifndef SKIP
-#define SKIP                                    0
-#endif
-
-/* From oslib:os.h */
-typedef _kernel_oserror os_error;
-typedef byte os_f;
-
-/* From oslib:osfile.h */
-#undef  OS_File
-#define OS_File                                 0x8
-
-/* From oslib:osgbpb.h */
-#undef  OS_GBPB
-#define OS_GBPB                                 0xC
-#undef  OSGBPB_Write
-#define OSGBPB_Write                            0x2
-#undef  OSGBPB_Read
-#define OSGBPB_Read                             0x4
-
-extern os_error *xosgbpb_write (os_f file,
-      byte *data,
-      int size,
-      int *unwritten);
-extern int osgbpb_write (os_f file,
-      byte *data,
-      int size);
-
-#define	xosgbpb_write(file, data, size, unwritten) \
-	(os_error*) _swix(OS_GBPB, _IN(0)|_IN(1)|_IN(2)|_IN(3)|_IN(4)|_OUT(3), \
-		OSGBPB_WriteAt, \
-		file, \
-		data, \
-		size, \
-		unwritten)
-
-#define	osgbpb_write(file, data, size) \
-	_swi(OS_GBPB, _IN(0)|_IN(1)|_IN(2)|_IN(3)|_RETURN(3), \
-		OSGBPB_Write, \
-		file, \
-		data, \
-		size)
-
-extern os_error *xosgbpb_read (os_f file,
-      byte *buffer,
-      int size,
-      int *unread);
-extern int osgbpb_read (os_f file,
-      byte *buffer,
-      int size);
-
-#define	xosgbpb_read(file, buffer, size, unread) \
-	(os_error*) _swix(OS_GBPB, _IN(0)|_IN(1)|_IN(2)|_IN(3)|_OUT(3), \
-		OSGBPB_Read, \
-		file, \
-		buffer, \
-		size, \
-		unread)
-
-#define	osgbpb_read(file, buffer, size) \
-	_swi(OS_GBPB, _IN(0)|_IN(1)|_IN(2)|_IN(3)|_RETURN(3), \
-		OSGBPB_Read, \
-		file, \
-		buffer, \
-		size)
-
-/* From oslib:osfind.h */
-#undef  OS_Find
-#define OS_Find                                 0xD
-#undef  OSFind_Openin
-#define OSFind_Openin                           0x40
-#undef  OSFind_Openout
-#define OSFind_Openout                          0x80
-#undef  OSFind_Openup
-#define OSFind_Openup                           0xC0
-#undef  OSFind_Close
-#define OSFind_Close                            0x0
-
-#define	xosfind_open(reason, file_name, path, file) \
-	(os_error*) _swix(OS_Find, _IN(0)|_IN(1)|_IN(2)|_OUT(0), \
-		reason, file_name, path, file)
-
-#define	osfind_open(reason, file_name, path) \
-	(os_f) _swi(OS_Find, _IN(0)|_IN(1)|_IN(2)|_RETURN(0), \
-		reason, file_name, path)
-
-extern os_error *xosfind_openin (bits flags,
-      char *file_name,
-      char *path,
-      os_f *file);
-extern os_f osfind_openin (bits flags,
-      char *file_name,
-      char *path);
-
-#define	xosfind_openin(flags, file_name, path, file) \
-	xosfind_open(flags | OSFind_Openin, file_name, path, file)
-
-#define	osfind_openin(flags, file_name, path) \
-	osfind_open(flags | OSFind_Openin, file_name, path)
-
-extern os_error *xosfind_openout (bits flags,
-      char *file_name,
-      char *path,
-      os_f *file);
-extern os_f osfind_openout (bits flags,
-      char *file_name,
-      char *path);
-
-#define	xosfind_openout(flags, file_name, path, file) \
-	xosfind_open(flags | OSFind_Openout, file_name, path, file)
-
-#define	osfind_openout(flags, file_name, path) \
-	osfind_open(flags | OSFind_Openout, file_name, path)
-
-extern os_error *xosfind_openup (bits flags,
-      char *file_name,
-      char *path,
-      os_f *file);
-extern os_f osfind_openup (bits flags,
-      char *file_name,
-      char *path);
-
-#define	xosfind_openup(flags, file_name, path, file) \
-	xosfind_open(flags | OSFind_Openup, file_name, path, file)
-
-#define	osfind_openup(flags, file_name, path) \
-	osfind_open(flags | OSFind_Openup, file_name, path)
-
-extern os_error *xosfind_close (os_f file);
-extern void osfind_close (os_f file);
-
-#define	xosfind_close(file) \
-	(os_error*) _swix(OS_Find, _IN(0)|_IN(1), \
-		OSFind_Close, \
-		file)
-
-#define	osfind_close(file) \
-	(void) _swi(OS_Find, _IN(0)|_IN(1), \
-		OSFind_Close, \
-		file)
-
-/* From oslib:osargs.h */
-#undef  OS_Args
-#define OS_Args                                 0x9
-#undef  OSArgs_ReadPtr
-#define OSArgs_ReadPtr                          0x0
-#undef  OSArgs_SetPtr
-#define OSArgs_SetPtr                           0x1
-#undef  OSArgs_ReadExt
-#define OSArgs_ReadExt                          0x2
-
-extern os_error *xosargs_read_ptr (os_f file,
-      int *ptr);
-extern int osargs_read_ptr (os_f file);
-
-#define	xosargs_read_ptr(file, ptr) \
-	(os_error*) _swix(OS_Args, _IN(0)|_IN(1)|_OUT(2), \
-		OSArgs_ReadPtr, \
-		file, \
-		ptr)
-
-#define	osargs_read_ptr(file) \
-	_swi(OS_Args, _IN(0)|_IN(1)|_RETURN(2), \
-		OSArgs_ReadPtr, \
-		file)
-
-extern os_error *xosargs_set_ptr (os_f file,
-      int ptr);
-extern void osargs_set_ptr (os_f file,
-      int ptr);
-
-#define	xosargs_set_ptr(file, ptr) \
-	(os_error*) _swix(OS_Args, _IN(0)|_IN(1)|_IN(2), \
-		OSArgs_SetPtr, \
-		file, \
-		ptr)
-
-#define	osargs_set_ptr(file, ptr) \
-	(void) _swi(OS_Args, _IN(0)|_IN(1)|_IN(2), \
-		OSArgs_SetPtr, \
-		file, \
-		ptr)
-
-extern os_error *xosargs_read_ext (os_f file,
-      int *ext);
-extern int osargs_read_ext (os_f file);
-
-#define	xosargs_read_ext(file, ext) \
-	(os_error*) _swix(OS_Args, _IN(0)|_IN(1)|_OUT(2), \
-		OSArgs_ReadExt, \
-		file, \
-		ext)
-
-#define	osargs_read_ext(file) \
-	_swi(OS_Args, _IN(0)|_IN(1)|_RETURN(2), \
-		OSArgs_ReadExt, \
-		file)
-
-/* OSLIB EMULATION ENDS */
-
-#endif
-
-#ifndef __osfcn_h
-/* Will be set or not during tiffcomp.h */
-/* You get this to compile under C++? Please say how! */
-
-extern int open(const char* name, int flags, int mode)
-{
-	/* From what I can tell, should return <0 for failure */
-	os_error* e = (os_error*) 1; /* Cheeky way to use a pointer eh? :-) */
-	os_f file = (os_f) -1;
-
-	flags = flags;
-
-	switch(mode)
-	{
-		case O_RDONLY:
-		{
-			e = xosfind_openin(SKIP, name, SKIP, &file);
-			break;
-		}
-		case O_WRONLY:
-		case O_RDWR|O_CREAT:
-		case O_RDWR|O_CREAT|O_TRUNC:
-		{
-			e = xosfind_openout(SKIP, name, SKIP, &file);
-			break;
-		}
-		case O_RDWR:
-		{
-			e = xosfind_openup(SKIP, name, SKIP, &file);
-			break;
-		}
-	}
-	if (e)
-	{
-		file = (os_f) -1;
-	}
-	return (file);
-}
-
-extern int close(int fd)
-{
-	return ((int) xosfind_close((os_f) fd));
-}
-
-extern int write(int fd, const char *buf, int nbytes)
-{
-	/* Returns number of bytes written */
-	return (nbytes - osgbpb_write((os_f) fd, (const byte*) buf, nbytes));
-}
-
-extern int read(int fd, char *buf, int nbytes)
-{
-	/* Returns number of bytes read */
-	return (nbytes - osgbpb_read((os_f) fd, (byte*) buf, nbytes));
-}
-
-extern off_t lseek(int fd, off_t offset, int whence)
-{
-	int absolute = 0;
-
-	switch (whence)
-	{
-		case SEEK_SET:
-		{
-			absolute = (int) offset;
-			break;
-		}
-		case SEEK_CUR:
-		{
-			absolute = osargs_read_ptr((os_f) fd) + (int) offset;
-			break;
-		}
-		case SEEK_END:
-		{
-			absolute = osargs_read_ext((os_f) fd) + (int) offset;
-			break;
-		}
-	}
-
-	osargs_set_ptr((os_f) fd, absolute);
-
-	return ((off_t) osargs_read_ptr((os_f) fd));
-}
-#endif
-
-static tsize_t
-_tiffReadProc(thandle_t fd, tdata_t buf, tsize_t size)
-{
-	return ((tsize_t) read((int) fd, buf, (size_t) size));
-}
-
-static tsize_t
-_tiffWriteProc(thandle_t fd, tdata_t buf, tsize_t size)
-{
-	return ((tsize_t) write((int) fd, buf, (size_t) size));
-}
-
-static toff_t
-_tiffSeekProc(thandle_t fd, toff_t off, int whence)
-{
-	return ((toff_t) lseek((int) fd, (off_t) off, whence));
-}
-
-static int
-_tiffCloseProc(thandle_t fd)
-{
-	return (close((int) fd));
-}
-
-static toff_t
-_tiffSizeProc(thandle_t fd)
-{
-	return (lseek((int) fd, SEEK_END, SEEK_SET));
-}
-
-#ifdef HAVE_MMAP
-#error "I didn't know Acorn had that!"
-#endif
-
-/* !HAVE_MMAP */
-static int
-_tiffMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize)
-{
-	(void) fd; (void) pbase; (void) psize;
-	return (0);
-}
-
-static void
-_tiffUnmapProc(thandle_t fd, tdata_t base, toff_t size)
-{
-	(void) fd; (void) base; (void) size;
-}
-
-/*
- * Open a TIFF file descriptor for read/writing.
- */
-TIFF*
-TIFFFdOpen(int fd, const char* name, const char* mode)
-{
-	TIFF* tif;
-
-	tif = TIFFClientOpen(name, mode,
-		(thandle_t) fd,
-		_tiffReadProc, _tiffWriteProc,
-		_tiffSeekProc, _tiffCloseProc, _tiffSizeProc,
-		_tiffMapProc, _tiffUnmapProc);
-	if (tif)
-	{
-		tif->tif_fd = fd;
-	}
-	return (tif);
-}
-
-/*
- * Open a TIFF file for read/writing.
- */
-TIFF*
-TIFFOpen(const char* name, const char* mode)
-{
-	static const char module[] = "TIFFOpen";
-	int m, fd;
-
-	m = _TIFFgetMode(mode, module);
-
-	if (m == -1)
-	{
-		return ((TIFF*) 0);
-	}
-
-	fd = open(name, 0, m);
-
-	if (fd < 0)
-	{
-		TIFFErrorExt(0, module, "%s: Cannot open", name);
-		return ((TIFF *)0);
-	}
-	return (TIFFFdOpen(fd, name, mode));
-}
-
-void*
-_TIFFmalloc(tsize_t s)
-{
-	return (malloc((size_t) s));
-}
-
-void
-_TIFFfree(tdata_t p)
-{
-	free(p);
-}
-
-void*
-_TIFFrealloc(tdata_t p, tsize_t s)
-{
-	return (realloc(p, (size_t) s));
-}
-
-void
-_TIFFmemset(tdata_t p, int v, tsize_t c)
-{
-	memset(p, v, (size_t) c);
-}
-
-void
-_TIFFmemcpy(tdata_t d, const tdata_t s, tsize_t c)
-{
-	memcpy(d, s, (size_t) c);
-}
-
-int
-_TIFFmemcmp(const tdata_t p1, const tdata_t p2, tsize_t c)
-{
-	return (memcmp(p1, p2, (size_t) c));
-}
-
-static void
-acornWarningHandler(const char* module, const char* fmt, va_list ap)
-{
-	if (module != NULL)
-	{
-		fprintf(stderr, "%s: ", module);
-	}
-	fprintf(stderr, "Warning, ");
-	vfprintf(stderr, fmt, ap);
-	fprintf(stderr, ".\n");
-}
-TIFFErrorHandler _TIFFwarningHandler = acornWarningHandler;
-
-static void
-acornErrorHandler(const char* module, const char* fmt, va_list ap)
-{
-	if (module != NULL)
-	{
-		fprintf(stderr, "%s: ", module);
-	}
-	vfprintf(stderr, fmt, ap);
-	fprintf(stderr, ".\n");
-}
-TIFFErrorHandler _TIFFerrorHandler = acornErrorHandler;
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_apple.c b/Source/LibTIFF/tif_apple.c
deleted file mode 100644
index 0cd2948..0000000
--- a/Source/LibTIFF/tif_apple.c
+++ /dev/null
@@ -1,281 +0,0 @@
-/* $Header: /cvsroot/freeimage/FreeImage/Source/LibTIFF/tif_apple.c,v 1.37 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library Macintosh-specific routines.
- *
- * These routines use only Toolbox and high-level File Manager traps.
- * They make no calls to the THINK C "unix" compatibility library.  Also,
- * malloc is not used directly but it is still referenced internally by
- * the ANSI library in rare cases.  Heap fragmentation by the malloc ring
- * buffer is therefore minimized.
- *
- * O_RDONLY and O_RDWR are treated identically here.  The tif_mode flag is
- * checked in TIFFWriteCheck().
- *
- * Create below fills in a blank creator signature and sets the file type
- * to 'TIFF'.  It is much better for the application to do this by Create'ing
- * the file first and TIFFOpen'ing it later.
- * ---------
- * This code has been "Carbonized", and may not work with older MacOS versions.
- * If so, grab the tif_apple.c out of an older libtiff distribution, like
- * 3.5.5 from www.libtiff.org.
- */
-
-#include "tiffiop.h"
-#include <Errors.h>
-#include <Files.h>
-#include <Memory.h>
-#include <Script.h>
-
-#if defined(__PPCC__) || defined(__SC__) || defined(__MRC__) || defined(applec)
-#define	CtoPstr	c2pstr
-#endif
-
-static tsize_t
-_tiffReadProc(thandle_t fd, tdata_t buf, tsize_t size)
-{
-	return (FSRead((short) fd, (long*) &size, (char*) buf) == noErr ?
-	    size : (tsize_t) -1);
-}
-
-static tsize_t
-_tiffWriteProc(thandle_t fd, tdata_t buf, tsize_t size)
-{
-	return (FSWrite((short) fd, (long*) &size, (char*) buf) == noErr ?
-	    size : (tsize_t) -1);
-}
-
-static toff_t
-_tiffSeekProc(thandle_t fd, toff_t off, int whence)
-{
-	long fpos, size;
-
-	if (GetEOF((short) fd, &size) != noErr)
-		return EOF;
-	(void) GetFPos((short) fd, &fpos);
-
-	switch (whence) {
-	case SEEK_CUR:
-		if (off + fpos > size)
-			SetEOF((short) fd, off + fpos);
-		if (SetFPos((short) fd, fsFromMark, off) != noErr)
-			return EOF;
-		break;
-	case SEEK_END:
-		if (off > 0)
-			SetEOF((short) fd, off + size);
-		if (SetFPos((short) fd, fsFromStart, off + size) != noErr)
-			return EOF;
-		break;
-	case SEEK_SET:
-		if (off > size)
-			SetEOF((short) fd, off);
-		if (SetFPos((short) fd, fsFromStart, off) != noErr)
-			return EOF;
-		break;
-	}
-
-	return (toff_t)(GetFPos((short) fd, &fpos) == noErr ? fpos : EOF);
-}
-
-static int
-_tiffMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize)
-{
-	return (0);
-}
-
-static void
-_tiffUnmapProc(thandle_t fd, tdata_t base, toff_t size)
-{
-}
-
-static int
-_tiffCloseProc(thandle_t fd)
-{
-	return (FSClose((short) fd));
-}
-
-static toff_t
-_tiffSizeProc(thandle_t fd)
-{
-	long size;
-
-	if (GetEOF((short) fd, &size) != noErr) {
-		TIFFErrorExt(fd, "_tiffSizeProc", "%s: Cannot get file size");
-		return (-1L);
-	}
-	return ((toff_t) size);
-}
-
-/*
- * Open a TIFF file descriptor for read/writing.
- */
-TIFF*
-TIFFFdOpen(int fd, const char* name, const char* mode)
-{
-	TIFF* tif;
-
-	tif = TIFFClientOpen(name, mode, (thandle_t) fd,
-	    _tiffReadProc, _tiffWriteProc, _tiffSeekProc, _tiffCloseProc,
-	    _tiffSizeProc, _tiffMapProc, _tiffUnmapProc);
-	if (tif)
-		tif->tif_fd = fd;
-	return (tif);
-}
-
-static void ourc2pstr( char* inString )
-{
-	int	sLen = strlen( inString );
-	BlockMoveData( inString, &inString[1], sLen );
-	inString[0] = sLen;
-}
-
-/*
- * Open a TIFF file for read/writing.
- */
-TIFF*
-TIFFOpen(const char* name, const char* mode)
-{
-	static const char module[] = "TIFFOpen";
-	Str255 pname;
-	FInfo finfo;
-	short fref;
-	OSErr err;
-	FSSpec	fSpec;
-
-	strcpy((char*) pname, name);
-	ourc2pstr((char*) pname);
-	
-	err = FSMakeFSSpec( 0, 0, pname, &fSpec );
-
-	switch (_TIFFgetMode(mode, module)) {
-	default:
-		return ((TIFF*) 0);
-	case O_RDWR | O_CREAT | O_TRUNC:
-		if (FSpGetFInfo(&fSpec, &finfo) == noErr)
-			FSpDelete(&fSpec);
-		/* fall through */
-	case O_RDWR | O_CREAT:
-		if ((err = FSpGetFInfo(&fSpec, &finfo)) == fnfErr) {
-			if (FSpCreate(&fSpec, '    ', 'TIFF', smSystemScript) != noErr)
-				goto badCreate;
-			if (FSpOpenDF(&fSpec, fsRdWrPerm, &fref) != noErr)
-				goto badOpen;
-		} else if (err == noErr) {
-			if (FSpOpenDF(&fSpec, fsRdWrPerm, &fref) != noErr)
-				goto badOpen;
-		} else
-			goto badOpen;
-		break;
-	case O_RDONLY:
-		if (FSpOpenDF(&fSpec, fsRdPerm, &fref) != noErr)
-			goto badOpen;
-		break;
-	case O_RDWR:
-		if (FSpOpenDF(&fSpec, fsRdWrPerm, &fref) != noErr)
-			goto badOpen;
-		break;
-	}
-	return (TIFFFdOpen((int) fref, name, mode));
-badCreate:
-	TIFFErrorExt(0, module, "%s: Cannot create", name);
-	return ((TIFF*) 0);
-badOpen:
-	TIFFErrorExt(0, module, "%s: Cannot open", name);
-	return ((TIFF*) 0);
-}
-
-void
-_TIFFmemset(tdata_t p, int v, tsize_t c)
-{
-	memset(p, v, (size_t) c);
-}
-
-void
-_TIFFmemcpy(tdata_t d, const tdata_t s, tsize_t c)
-{
-	memcpy(d, s, (size_t) c);
-}
-
-int
-_TIFFmemcmp(const tdata_t p1, const tdata_t p2, tsize_t c)
-{
-	return (memcmp(p1, p2, (size_t) c));
-}
-
-tdata_t
-_TIFFmalloc(tsize_t s)
-{
-	return (NewPtr((size_t) s));
-}
-
-void
-_TIFFfree(tdata_t p)
-{
-	DisposePtr(p);
-}
-
-tdata_t
-_TIFFrealloc(tdata_t p, tsize_t s)
-{
-	Ptr n = p;
-
-	SetPtrSize(p, (size_t) s);
-	if (MemError() && (n = NewPtr((size_t) s)) != NULL) {
-		BlockMove(p, n, GetPtrSize(p));
-		DisposePtr(p);
-	}
-	return ((tdata_t) n);
-}
-
-static void
-appleWarningHandler(const char* module, const char* fmt, va_list ap)
-{
-	if (module != NULL)
-		fprintf(stderr, "%s: ", module);
-	fprintf(stderr, "Warning, ");
-	vfprintf(stderr, fmt, ap);
-	fprintf(stderr, ".\n");
-}
-TIFFErrorHandler _TIFFwarningHandler = appleWarningHandler;
-
-static void
-appleErrorHandler(const char* module, const char* fmt, va_list ap)
-{
-	if (module != NULL)
-		fprintf(stderr, "%s: ", module);
-	vfprintf(stderr, fmt, ap);
-	fprintf(stderr, ".\n");
-}
-TIFFErrorHandler _TIFFerrorHandler = appleErrorHandler;
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_atari.c b/Source/LibTIFF/tif_atari.c
deleted file mode 100644
index 62453a1..0000000
--- a/Source/LibTIFF/tif_atari.c
+++ /dev/null
@@ -1,250 +0,0 @@
-/* "$Header: /cvsroot/freeimage/FreeImage/Source/LibTIFF/tif_atari.c,v 1.37 2011/04/10 17:14:09 drolon Exp $" */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library ATARI-specific Routines.
- */
-#include "tiffiop.h"
-#if defined(__TURBOC__)
-#include <tos.h>
-#include <stdio.h>
-#else
-#include <osbind.h>
-#include <fcntl.h>
-#endif
-
-#ifndef O_ACCMODE
-#define O_ACCMODE 3
-#endif
-
-#include <errno.h>
-
-#define AEFILNF   -33
-
-static tsize_t
-_tiffReadProc(thandle_t fd, tdata_t buf, tsize_t size)
-{
-	long r;
-
-	r = Fread((int) fd, size, buf);
-	if (r < 0) {
-		errno = (int)-r;
-		r = -1;
-	}
-	return r;
-}
-
-static tsize_t
-_tiffWriteProc(thandle_t fd, tdata_t buf, tsize_t size)
-{
-	long r;
-
-	r = Fwrite((int) fd, size, buf);
-	if (r < 0) {
-		errno = (int)-r;
-		r = -1;
-	}
-	return r;
-}
-
-static toff_t
-_tiffSeekProc(thandle_t fd, off_t off, int whence)
-{
-	char buf[256];
-	long current_off, expected_off, new_off;
-
-	if (whence == SEEK_END || off <= 0)
-		return Fseek(off, (int) fd, whence);
-	current_off = Fseek(0, (int) fd, SEEK_CUR); /* find out where we are */
-	if (whence == SEEK_SET)
-		expected_off = off;
-	else
-		expected_off = off + current_off;
-	new_off = Fseek(off, (int) fd, whence);
-	if (new_off == expected_off)
-		return new_off;
-	/* otherwise extend file -- zero filling the hole */
-	if (new_off < 0)            /* error? */
-		new_off = Fseek(0, (int) fd, SEEK_END); /* go to eof */
-	_TIFFmemset(buf, 0, sizeof(buf));
-	while (expected_off > new_off) {
-		off = expected_off - new_off;
-		if (off > sizeof(buf))
-			off = sizeof(buf);
-		if ((current_off = Fwrite((int) fd, off, buf)) != off)
-			return (current_off > 0) ?
-			    new_off + current_off : new_off;
-		new_off += off;
-	}
-	return new_off;
-}
-
-static int
-_tiffCloseProc(thandle_t fd)
-{
-	long r;
-
-	r = Fclose((int) fd);
-	if (r < 0) {
-		errno = (int)-r;
-		r = -1;
-	}
-	return (int)r;
-}
-
-static toff_t
-_tiffSizeProc(thandle_t fd)
-{
-	long pos, eof;
-
-	pos = Fseek(0, (int) fd, SEEK_CUR);
-	eof = Fseek(0, (int) fd, SEEK_END);
-	Fseek(pos, (int) fd, SEEK_SET);
-	return eof;
-}
-
-static int
-_tiffMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize)
-{
-	return (0);
-}
-
-static void
-_tiffUnmapProc(thandle_t fd, tdata_t base, toff_t size)
-{
-}
-
-/*
-* Open a TIFF file descriptor for read/writing.
-*/
-TIFF*
-TIFFFdOpen(int fd, const char* name, const char* mode)
-{
-	TIFF* tif;
-
-	tif = TIFFClientOpen(name, mode,
-		(thandle_t) fd,
-		_tiffReadProc, _tiffWriteProc, _tiffSeekProc, _tiffCloseProc,
-		_tiffSizeProc, _tiffMapProc, _tiffUnmapProc);
-	if (tif)
-		tif->tif_fd = fd;
-	return (tif);
-}
-
-/*
-* Open a TIFF file for read/writing.
-*/
-TIFF*
-TIFFOpen(const char* name, const char* mode)
-{
-	static const char module[] = "TIFFOpen";
-	int m;
-	long fd;
-
-	m = _TIFFgetMode(mode, module);
-	if (m == -1)
-		return ((TIFF*)0);
-	if (m & O_TRUNC) {
-		fd = Fcreate(name, 0);
-	} else {
-		fd = Fopen(name, m & O_ACCMODE);
-		if (fd == AEFILNF && m & O_CREAT)
-			fd = Fcreate(name, 0);
-	}
-	if (fd < 0)
-		errno = (int)fd;
-	if (fd < 0) {
-		TIFFErrorExt(0, module, "%s: Cannot open", name);
-		return ((TIFF*)0);
-	}
-	return (TIFFFdOpen(fd, name, mode));
-}
-
-#include <stdlib.h>
-
-tdata_t
-_TIFFmalloc(tsize_t s)
-{
-	return (malloc((size_t) s));
-}
-
-void
-_TIFFfree(tdata_t p)
-{
-	free(p);
-}
-
-tdata_t
-_TIFFrealloc(tdata_t p, tsize_t s)
-{
-	return (realloc(p, (size_t) s));
-}
-
-void
-_TIFFmemset(tdata_t p, int v, size_t c)
-{
-	memset(p, v, (size_t) c);
-}
-
-void
-_TIFFmemcpy(tdata_t d, const tdata_t s, size_t c)
-{
-	memcpy(d, s, (size_t) c);
-}
-
-int
-_TIFFmemcmp(const tdata_t p1, const tdata_t p2, tsize_t c)
-{
-	return (memcmp(p1, p2, (size_t) c));
-}
-
-static void
-atariWarningHandler(const char* module, const char* fmt, va_list ap)
-{
-	if (module != NULL)
-		fprintf(stderr, "%s: ", module);
-	fprintf(stderr, "Warning, ");
-	vfprintf(stderr, fmt, ap);
-	fprintf(stderr, ".\n");
-}
-TIFFErrorHandler _TIFFwarningHandler = atariWarningHandler;
-
-static void
-atariErrorHandler(const char* module, const char* fmt, va_list ap)
-{
-	if (module != NULL)
-		fprintf(stderr, "%s: ", module);
-	vfprintf(stderr, fmt, ap);
-	fprintf(stderr, ".\n");
-}
-TIFFErrorHandler _TIFFerrorHandler = atariErrorHandler;
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_aux.c b/Source/LibTIFF/tif_aux.c
deleted file mode 100644
index 434d701..0000000
--- a/Source/LibTIFF/tif_aux.c
+++ /dev/null
@@ -1,290 +0,0 @@
-/* $Id: tif_aux.c,v 1.37 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1991-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library.
- *
- * Auxiliary Support Routines.
- */
-#include "tiffiop.h"
-#include "tif_predict.h"
-#include <math.h>
-
-tdata_t
-_TIFFCheckRealloc(TIFF* tif, tdata_t buffer,
-		  size_t nmemb, size_t elem_size, const char* what)
-{
-	tdata_t cp = NULL;
-	tsize_t	bytes = nmemb * elem_size;
-
-	/*
-	 * XXX: Check for integer overflow.
-	 */
-	if (nmemb && elem_size && bytes / elem_size == nmemb)
-		cp = _TIFFrealloc(buffer, bytes);
-
-	if (cp == NULL)
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			     "Failed to allocate memory for %s "
-			     "(%ld elements of %ld bytes each)",
-			     what,(long) nmemb, (long) elem_size);
-
-	return cp;
-}
-
-tdata_t
-_TIFFCheckMalloc(TIFF* tif, size_t nmemb, size_t elem_size, const char* what)
-{
-	return _TIFFCheckRealloc(tif, NULL, nmemb, elem_size, what);
-}
-
-static int
-TIFFDefaultTransferFunction(TIFFDirectory* td)
-{
-	uint16 **tf = td->td_transferfunction;
-	tsize_t i, n, nbytes;
-
-	tf[0] = tf[1] = tf[2] = 0;
-	if (td->td_bitspersample >= sizeof(tsize_t) * 8 - 2)
-		return 0;
-
-	n = 1<<td->td_bitspersample;
-	nbytes = n * sizeof (uint16);
-	if (!(tf[0] = (uint16 *)_TIFFmalloc(nbytes)))
-		return 0;
-	tf[0][0] = 0;
-	for (i = 1; i < n; i++) {
-		double t = (double)i/((double) n-1.);
-		tf[0][i] = (uint16)floor(65535.*pow(t, 2.2) + .5);
-	}
-
-	if (td->td_samplesperpixel - td->td_extrasamples > 1) {
-		if (!(tf[1] = (uint16 *)_TIFFmalloc(nbytes)))
-			goto bad;
-		_TIFFmemcpy(tf[1], tf[0], nbytes);
-		if (!(tf[2] = (uint16 *)_TIFFmalloc(nbytes)))
-			goto bad;
-		_TIFFmemcpy(tf[2], tf[0], nbytes);
-	}
-	return 1;
-
-bad:
-	if (tf[0])
-		_TIFFfree(tf[0]);
-	if (tf[1])
-		_TIFFfree(tf[1]);
-	if (tf[2])
-		_TIFFfree(tf[2]);
-	tf[0] = tf[1] = tf[2] = 0;
-	return 0;
-}
-
-static int
-TIFFDefaultRefBlackWhite(TIFFDirectory* td)
-{
-	int i;
-
-	if (!(td->td_refblackwhite = (float *)_TIFFmalloc(6*sizeof (float))))
-		return 0;
-        if (td->td_photometric == PHOTOMETRIC_YCBCR) {
-		/*
-		 * YCbCr (Class Y) images must have the ReferenceBlackWhite
-		 * tag set. Fix the broken images, which lacks that tag.
-		 */
-		td->td_refblackwhite[0] = 0.0F;
-		td->td_refblackwhite[1] = td->td_refblackwhite[3] =
-			td->td_refblackwhite[5] = 255.0F;
-		td->td_refblackwhite[2] = td->td_refblackwhite[4] = 128.0F;
-	} else {
-		/*
-		 * Assume RGB (Class R)
-		 */
-		for (i = 0; i < 3; i++) {
-		    td->td_refblackwhite[2*i+0] = 0;
-		    td->td_refblackwhite[2*i+1] =
-			    (float)((1L<<td->td_bitspersample)-1L);
-		}
-	}
-	return 1;
-}
-
-/*
- * Like TIFFGetField, but return any default
- * value if the tag is not present in the directory.
- *
- * NB:	We use the value in the directory, rather than
- *	explcit values so that defaults exist only one
- *	place in the library -- in TIFFDefaultDirectory.
- */
-int
-TIFFVGetFieldDefaulted(TIFF* tif, ttag_t tag, va_list ap)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-
-	if (TIFFVGetField(tif, tag, ap))
-		return (1);
-	switch (tag) {
-	case TIFFTAG_SUBFILETYPE:
-		*va_arg(ap, uint32 *) = td->td_subfiletype;
-		return (1);
-	case TIFFTAG_BITSPERSAMPLE:
-		*va_arg(ap, uint16 *) = td->td_bitspersample;
-		return (1);
-	case TIFFTAG_THRESHHOLDING:
-		*va_arg(ap, uint16 *) = td->td_threshholding;
-		return (1);
-	case TIFFTAG_FILLORDER:
-		*va_arg(ap, uint16 *) = td->td_fillorder;
-		return (1);
-	case TIFFTAG_ORIENTATION:
-		*va_arg(ap, uint16 *) = td->td_orientation;
-		return (1);
-	case TIFFTAG_SAMPLESPERPIXEL:
-		*va_arg(ap, uint16 *) = td->td_samplesperpixel;
-		return (1);
-	case TIFFTAG_ROWSPERSTRIP:
-		*va_arg(ap, uint32 *) = td->td_rowsperstrip;
-		return (1);
-	case TIFFTAG_MINSAMPLEVALUE:
-		*va_arg(ap, uint16 *) = td->td_minsamplevalue;
-		return (1);
-	case TIFFTAG_MAXSAMPLEVALUE:
-		*va_arg(ap, uint16 *) = td->td_maxsamplevalue;
-		return (1);
-	case TIFFTAG_PLANARCONFIG:
-		*va_arg(ap, uint16 *) = td->td_planarconfig;
-		return (1);
-	case TIFFTAG_RESOLUTIONUNIT:
-		*va_arg(ap, uint16 *) = td->td_resolutionunit;
-		return (1);
-	case TIFFTAG_PREDICTOR:
-                {
-			TIFFPredictorState* sp = (TIFFPredictorState*) tif->tif_data;
-			*va_arg(ap, uint16*) = (uint16) sp->predictor;
-			return 1;
-                }
-	case TIFFTAG_DOTRANGE:
-		*va_arg(ap, uint16 *) = 0;
-		*va_arg(ap, uint16 *) = (1<<td->td_bitspersample)-1;
-		return (1);
-	case TIFFTAG_INKSET:
-		*va_arg(ap, uint16 *) = INKSET_CMYK;
-		return 1;
-	case TIFFTAG_NUMBEROFINKS:
-		*va_arg(ap, uint16 *) = 4;
-		return (1);
-	case TIFFTAG_EXTRASAMPLES:
-		*va_arg(ap, uint16 *) = td->td_extrasamples;
-		*va_arg(ap, uint16 **) = td->td_sampleinfo;
-		return (1);
-	case TIFFTAG_MATTEING:
-		*va_arg(ap, uint16 *) =
-		    (td->td_extrasamples == 1 &&
-		     td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
-		return (1);
-	case TIFFTAG_TILEDEPTH:
-		*va_arg(ap, uint32 *) = td->td_tiledepth;
-		return (1);
-	case TIFFTAG_DATATYPE:
-		*va_arg(ap, uint16 *) = td->td_sampleformat-1;
-		return (1);
-	case TIFFTAG_SAMPLEFORMAT:
-		*va_arg(ap, uint16 *) = td->td_sampleformat;
-                return(1);
-	case TIFFTAG_IMAGEDEPTH:
-		*va_arg(ap, uint32 *) = td->td_imagedepth;
-		return (1);
-	case TIFFTAG_YCBCRCOEFFICIENTS:
-		{
-			/* defaults are from CCIR Recommendation 601-1 */
-			static float ycbcrcoeffs[] = { 0.299f, 0.587f, 0.114f };
-			*va_arg(ap, float **) = ycbcrcoeffs;
-			return 1;
-		}
-	case TIFFTAG_YCBCRSUBSAMPLING:
-		*va_arg(ap, uint16 *) = td->td_ycbcrsubsampling[0];
-		*va_arg(ap, uint16 *) = td->td_ycbcrsubsampling[1];
-		return (1);
-	case TIFFTAG_YCBCRPOSITIONING:
-		*va_arg(ap, uint16 *) = td->td_ycbcrpositioning;
-		return (1);
-	case TIFFTAG_WHITEPOINT:
-		{
-			static float whitepoint[2];
-
-			/* TIFF 6.0 specification tells that it is no default
-			   value for the WhitePoint, but AdobePhotoshop TIFF
-			   Technical Note tells that it should be CIE D50. */
-			whitepoint[0] =	D50_X0 / (D50_X0 + D50_Y0 + D50_Z0);
-			whitepoint[1] =	D50_Y0 / (D50_X0 + D50_Y0 + D50_Z0);
-			*va_arg(ap, float **) = whitepoint;
-			return 1;
-		}
-	case TIFFTAG_TRANSFERFUNCTION:
-		if (!td->td_transferfunction[0] &&
-		    !TIFFDefaultTransferFunction(td)) {
-			TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "No space for \"TransferFunction\" tag");
-			return (0);
-		}
-		*va_arg(ap, uint16 **) = td->td_transferfunction[0];
-		if (td->td_samplesperpixel - td->td_extrasamples > 1) {
-			*va_arg(ap, uint16 **) = td->td_transferfunction[1];
-			*va_arg(ap, uint16 **) = td->td_transferfunction[2];
-		}
-		return (1);
-	case TIFFTAG_REFERENCEBLACKWHITE:
-		if (!td->td_refblackwhite && !TIFFDefaultRefBlackWhite(td))
-			return (0);
-		*va_arg(ap, float **) = td->td_refblackwhite;
-		return (1);
-	}
-	return 0;
-}
-
-/*
- * Like TIFFGetField, but return any default
- * value if the tag is not present in the directory.
- */
-int
-TIFFGetFieldDefaulted(TIFF* tif, ttag_t tag, ...)
-{
-	int ok;
-	va_list ap;
-
-	va_start(ap, tag);
-	ok =  TIFFVGetFieldDefaulted(tif, tag, ap);
-	va_end(ap);
-	return (ok);
-}
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_close.c b/Source/LibTIFF/tif_close.c
deleted file mode 100644
index ffc5d10..0000000
--- a/Source/LibTIFF/tif_close.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/* $Id: tif_close.c,v 1.37 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library.
- */
-#include "tiffiop.h"
-
-/************************************************************************/
-/*                            TIFFCleanup()                             */
-/************************************************************************/
-
-/**
- * Auxiliary function to free the TIFF structure. Given structure will be
- * completetly freed, so you should save opened file handle and pointer
- * to the close procedure in external variables before calling
- * _TIFFCleanup(), if you will need these ones to close the file.
- * 
- * @param tif A TIFF pointer.
- */
-
-void
-TIFFCleanup(TIFF* tif)
-{
-	if (tif->tif_mode != O_RDONLY)
-	    /*
-	     * Flush buffered data and directory (if dirty).
-	     */
-	    TIFFFlush(tif);
-	(*tif->tif_cleanup)(tif);
-	TIFFFreeDirectory(tif);
-
-	if (tif->tif_dirlist)
-		_TIFFfree(tif->tif_dirlist);
-
-	/* Clean up client info links */
-	while( tif->tif_clientinfo )
-	{
-		TIFFClientInfoLink *link = tif->tif_clientinfo;
-
-		tif->tif_clientinfo = link->next;
-		_TIFFfree( link->name );
-		_TIFFfree( link );
-	}
-
-	if (tif->tif_rawdata && (tif->tif_flags&TIFF_MYBUFFER))
-		_TIFFfree(tif->tif_rawdata);
-	if (isMapped(tif))
-		TIFFUnmapFileContents(tif, tif->tif_base, tif->tif_size);
-
-	/* Clean up custom fields */
-	if (tif->tif_nfields > 0)
-	{
-		size_t  i;
-
-	    for (i = 0; i < tif->tif_nfields; i++) 
-	    {
-		TIFFFieldInfo *fld = tif->tif_fieldinfo[i];
-		if (fld->field_bit == FIELD_CUSTOM && 
-		    strncmp("Tag ", fld->field_name, 4) == 0) 
-		{
-		    _TIFFfree(fld->field_name);
-		    _TIFFfree(fld);
-		}
-	    }   
-	  
-	    _TIFFfree(tif->tif_fieldinfo);
-	}
-
-	_TIFFfree(tif);
-}
-
-/************************************************************************/
-/*                            TIFFClose()                               */
-/************************************************************************/
-
-/**
- * Close a previously opened TIFF file.
- *
- * TIFFClose closes a file that was previously opened with TIFFOpen().
- * Any buffered data are flushed to the file, including the contents of
- * the current directory (if modified); and all resources are reclaimed.
- * 
- * @param tif A TIFF pointer.
- */
-
-void
-TIFFClose(TIFF* tif)
-{
-	TIFFCloseProc closeproc = tif->tif_closeproc;
-	thandle_t fd = tif->tif_clientdata;
-
-	TIFFCleanup(tif);
-	(void) (*closeproc)(fd);
-}
-
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_codec.c b/Source/LibTIFF/tif_codec.c
deleted file mode 100644
index 0455c11..0000000
--- a/Source/LibTIFF/tif_codec.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/* $Id: tif_codec.c,v 1.37 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library
- *
- * Builtin Compression Scheme Configuration Support.
- */
-#include "tiffiop.h"
-
-static	int NotConfigured(TIFF*, int);
-
-#ifndef	LZW_SUPPORT
-#define	TIFFInitLZW		NotConfigured
-#endif
-#ifndef	PACKBITS_SUPPORT
-#define	TIFFInitPackBits	NotConfigured
-#endif
-#ifndef	THUNDER_SUPPORT
-#define	TIFFInitThunderScan	NotConfigured
-#endif
-#ifndef	NEXT_SUPPORT
-#define	TIFFInitNeXT		NotConfigured
-#endif
-#ifndef	JPEG_SUPPORT
-#define	TIFFInitJPEG		NotConfigured
-#endif
-#ifndef	OJPEG_SUPPORT
-#define	TIFFInitOJPEG		NotConfigured
-#endif
-#ifndef	CCITT_SUPPORT
-#define	TIFFInitCCITTRLE	NotConfigured
-#define	TIFFInitCCITTRLEW	NotConfigured
-#define	TIFFInitCCITTFax3	NotConfigured
-#define	TIFFInitCCITTFax4	NotConfigured
-#endif
-#ifndef JBIG_SUPPORT
-#define	TIFFInitJBIG		NotConfigured
-#endif
-#ifndef	ZIP_SUPPORT
-#define	TIFFInitZIP		NotConfigured
-#endif
-#ifndef	PIXARLOG_SUPPORT
-#define	TIFFInitPixarLog	NotConfigured
-#endif
-#ifndef LOGLUV_SUPPORT
-#define TIFFInitSGILog		NotConfigured
-#endif
-
-/*
- * Compression schemes statically built into the library.
- */
-#ifdef VMS
-const TIFFCodec _TIFFBuiltinCODECS[] = {
-#else
-TIFFCodec _TIFFBuiltinCODECS[] = {
-#endif
-    { "None",		COMPRESSION_NONE,	TIFFInitDumpMode },
-    { "LZW",		COMPRESSION_LZW,	TIFFInitLZW },
-    { "PackBits",	COMPRESSION_PACKBITS,	TIFFInitPackBits },
-    { "ThunderScan",	COMPRESSION_THUNDERSCAN,TIFFInitThunderScan },
-    { "NeXT",		COMPRESSION_NEXT,	TIFFInitNeXT },
-    { "JPEG",		COMPRESSION_JPEG,	TIFFInitJPEG },
-    { "Old-style JPEG",	COMPRESSION_OJPEG,	TIFFInitOJPEG },
-    { "CCITT RLE",	COMPRESSION_CCITTRLE,	TIFFInitCCITTRLE },
-    { "CCITT RLE/W",	COMPRESSION_CCITTRLEW,	TIFFInitCCITTRLEW },
-    { "CCITT Group 3",	COMPRESSION_CCITTFAX3,	TIFFInitCCITTFax3 },
-    { "CCITT Group 4",	COMPRESSION_CCITTFAX4,	TIFFInitCCITTFax4 },
-    { "ISO JBIG",	COMPRESSION_JBIG,	TIFFInitJBIG },
-    { "Deflate",	COMPRESSION_DEFLATE,	TIFFInitZIP },
-    { "AdobeDeflate",   COMPRESSION_ADOBE_DEFLATE , TIFFInitZIP }, 
-    { "PixarLog",	COMPRESSION_PIXARLOG,	TIFFInitPixarLog },
-    { "SGILog",		COMPRESSION_SGILOG,	TIFFInitSGILog },
-    { "SGILog24",	COMPRESSION_SGILOG24,	TIFFInitSGILog },
-    { NULL,             0,                      NULL }
-};
-
-static int
-_notConfigured(TIFF* tif)
-{
-	const TIFFCodec* c = TIFFFindCODEC(tif->tif_dir.td_compression);
-        char compression_code[20];
-        
-        sprintf( compression_code, "%d", tif->tif_dir.td_compression );
-	TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-                     "%s compression support is not configured", 
-                     c ? c->name : compression_code );
-	return (0);
-}
-
-static int
-NotConfigured(TIFF* tif, int scheme)
-{
-    (void) scheme;
-    
-    tif->tif_decodestatus = FALSE;
-    tif->tif_setupdecode = _notConfigured;
-    tif->tif_encodestatus = FALSE;
-    tif->tif_setupencode = _notConfigured;
-    return (1);
-}
-
-/************************************************************************/
-/*                       TIFFIsCODECConfigured()                        */
-/************************************************************************/
-
-/**
- * Check whether we have working codec for the specific coding scheme.
- * 
- * @return returns 1 if the codec is configured and working. Otherwise
- * 0 will be returned.
- */
-
-int
-TIFFIsCODECConfigured(uint16 scheme)
-{
-	const TIFFCodec* codec = TIFFFindCODEC(scheme);
-
-	if(codec == NULL) {
-            return 0;
-        }
-        if(codec->init == NULL) {
-            return 0;
-        }
-	if(codec->init != NotConfigured){
-            return 1;
-        }
-	return 0;
-}
-
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_color.c b/Source/LibTIFF/tif_color.c
deleted file mode 100644
index 7aa36ef..0000000
--- a/Source/LibTIFF/tif_color.c
+++ /dev/null
@@ -1,287 +0,0 @@
-/* $Id: tif_color.c,v 1.37 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * CIE L*a*b* to CIE XYZ and CIE XYZ to RGB conversion routines are taken
- * from the VIPS library (http://www.vips.ecs.soton.ac.uk) with
- * the permission of John Cupitt, the VIPS author.
- */
-
-/*
- * TIFF Library.
- *
- * Color space conversion routines.
- */
-
-#include "tiffiop.h"
-#include <math.h>
-
-/*
- * Convert color value from the CIE L*a*b* 1976 space to CIE XYZ.
- */
-void
-TIFFCIELabToXYZ(TIFFCIELabToRGB *cielab, uint32 l, int32 a, int32 b,
-		float *X, float *Y, float *Z)
-{
-	float L = (float)l * 100.0F / 255.0F;
-	float cby, tmp;
-
-	if( L < 8.856F ) {
-		*Y = (L * cielab->Y0) / 903.292F;
-		cby = 7.787F * (*Y / cielab->Y0) + 16.0F / 116.0F;
-	} else {
-		cby = (L + 16.0F) / 116.0F;
-		*Y = cielab->Y0 * cby * cby * cby;
-	}
-
-	tmp = (float)a / 500.0F + cby;
-	if( tmp < 0.2069F )
-		*X = cielab->X0 * (tmp - 0.13793F) / 7.787F;
-	else    
-		*X = cielab->X0 * tmp * tmp * tmp;
-
-	tmp = cby - (float)b / 200.0F;
-	if( tmp < 0.2069F )
-		*Z = cielab->Z0 * (tmp - 0.13793F) / 7.787F;
-	else    
-		*Z = cielab->Z0 * tmp * tmp * tmp;
-}
-
-#define RINT(R) ((uint32)((R)>0?((R)+0.5):((R)-0.5)))
-/*
- * Convert color value from the XYZ space to RGB.
- */
-void
-TIFFXYZToRGB(TIFFCIELabToRGB *cielab, float X, float Y, float Z,
-	     uint32 *r, uint32 *g, uint32 *b)
-{
-	int i;
-	float Yr, Yg, Yb;
-	float *matrix = &cielab->display.d_mat[0][0];
-
-	/* Multiply through the matrix to get luminosity values. */
-	Yr =  matrix[0] * X + matrix[1] * Y + matrix[2] * Z;
-	Yg =  matrix[3] * X + matrix[4] * Y + matrix[5] * Z;
-	Yb =  matrix[6] * X + matrix[7] * Y + matrix[8] * Z;
-
-	/* Clip input */
-	Yr = TIFFmax(Yr, cielab->display.d_Y0R);
-	Yg = TIFFmax(Yg, cielab->display.d_Y0G);
-	Yb = TIFFmax(Yb, cielab->display.d_Y0B);
-
-	/* Avoid overflow in case of wrong input values */
-	Yr = TIFFmin(Yr, cielab->display.d_YCR);
-	Yg = TIFFmin(Yg, cielab->display.d_YCG);
-	Yb = TIFFmin(Yb, cielab->display.d_YCB);
-
-	/* Turn luminosity to colour value. */
-	i = (int)((Yr - cielab->display.d_Y0R) / cielab->rstep);
-	i = TIFFmin(cielab->range, i);
-	*r = RINT(cielab->Yr2r[i]);
-
-	i = (int)((Yg - cielab->display.d_Y0G) / cielab->gstep);
-	i = TIFFmin(cielab->range, i);
-	*g = RINT(cielab->Yg2g[i]);
-
-	i = (int)((Yb - cielab->display.d_Y0B) / cielab->bstep);
-	i = TIFFmin(cielab->range, i);
-	*b = RINT(cielab->Yb2b[i]);
-
-	/* Clip output. */
-	*r = TIFFmin(*r, cielab->display.d_Vrwr);
-	*g = TIFFmin(*g, cielab->display.d_Vrwg);
-	*b = TIFFmin(*b, cielab->display.d_Vrwb);
-}
-#undef RINT
-
-/* 
- * Allocate conversion state structures and make look_up tables for
- * the Yr,Yb,Yg <=> r,g,b conversions.
- */
-int
-TIFFCIELabToRGBInit(TIFFCIELabToRGB* cielab,
-		    TIFFDisplay *display, float *refWhite)
-{
-	int i;
-	double gamma;
-
-	cielab->range = CIELABTORGB_TABLE_RANGE;
-
-	_TIFFmemcpy(&cielab->display, display, sizeof(TIFFDisplay));
-
-	/* Red */
-	gamma = 1.0 / cielab->display.d_gammaR ;
-	cielab->rstep =
-		(cielab->display.d_YCR - cielab->display.d_Y0R)	/ cielab->range;
-	for(i = 0; i <= cielab->range; i++) {
-		cielab->Yr2r[i] = cielab->display.d_Vrwr
-		    * ((float)pow((double)i / cielab->range, gamma));
-	}
-
-	/* Green */
-	gamma = 1.0 / cielab->display.d_gammaG ;
-	cielab->gstep =
-	    (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
-	for(i = 0; i <= cielab->range; i++) {
-		cielab->Yg2g[i] = cielab->display.d_Vrwg
-		    * ((float)pow((double)i / cielab->range, gamma));
-	}
-
-	/* Blue */
-	gamma = 1.0 / cielab->display.d_gammaB ;
-	cielab->bstep =
-	    (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
-	for(i = 0; i <= cielab->range; i++) {
-		cielab->Yb2b[i] = cielab->display.d_Vrwb
-		    * ((float)pow((double)i / cielab->range, gamma));
-	}
-
-	/* Init reference white point */
-	cielab->X0 = refWhite[0];
-	cielab->Y0 = refWhite[1];
-	cielab->Z0 = refWhite[2];
-
-	return 0;
-}
-
-/* 
- * Convert color value from the YCbCr space to CIE XYZ.
- * The colorspace conversion algorithm comes from the IJG v5a code;
- * see below for more information on how it works.
- */
-#define	SHIFT			16
-#define	FIX(x)			((int32)((x) * (1L<<SHIFT) + 0.5))
-#define	ONE_HALF		((int32)(1<<(SHIFT-1)))
-#define	Code2V(c, RB, RW, CR)	((((c)-(int32)(RB))*(float)(CR))/(float)(((RW)-(RB)) ? ((RW)-(RB)) : 1))
-#define	CLAMP(f,min,max)	((f)<(min)?(min):(f)>(max)?(max):(f))
-#define HICLAMP(f,max)		((f)>(max)?(max):(f))
-
-void
-TIFFYCbCrtoRGB(TIFFYCbCrToRGB *ycbcr, uint32 Y, int32 Cb, int32 Cr,
-	       uint32 *r, uint32 *g, uint32 *b)
-{
-	int32 i;
-
-	/* XXX: Only 8-bit YCbCr input supported for now */
-	Y = HICLAMP(Y, 255), Cb = CLAMP(Cb, 0, 255), Cr = CLAMP(Cr, 0, 255);
-
-	i = ycbcr->Y_tab[Y] + ycbcr->Cr_r_tab[Cr];
-	*r = CLAMP(i, 0, 255);
-	i = ycbcr->Y_tab[Y]
-	    + (int)((ycbcr->Cb_g_tab[Cb] + ycbcr->Cr_g_tab[Cr]) >> SHIFT);
-	*g = CLAMP(i, 0, 255);
-	i = ycbcr->Y_tab[Y] + ycbcr->Cb_b_tab[Cb];
-	*b = CLAMP(i, 0, 255);
-}
-
-/*
- * Initialize the YCbCr->RGB conversion tables.  The conversion
- * is done according to the 6.0 spec:
- *
- *    R = Y + Cr*(2 - 2*LumaRed)
- *    B = Y + Cb*(2 - 2*LumaBlue)
- *    G =   Y
- *        - LumaBlue*Cb*(2-2*LumaBlue)/LumaGreen
- *        - LumaRed*Cr*(2-2*LumaRed)/LumaGreen
- *
- * To avoid floating point arithmetic the fractional constants that
- * come out of the equations are represented as fixed point values
- * in the range 0...2^16.  We also eliminate multiplications by
- * pre-calculating possible values indexed by Cb and Cr (this code
- * assumes conversion is being done for 8-bit samples).
- */
-int
-TIFFYCbCrToRGBInit(TIFFYCbCrToRGB* ycbcr, float *luma, float *refBlackWhite)
-{
-    TIFFRGBValue* clamptab;
-    int i;
-    
-#define LumaRed	    luma[0]
-#define LumaGreen   luma[1]
-#define LumaBlue    luma[2]
-
-    clamptab = (TIFFRGBValue*)(
-	(tidata_t) ycbcr+TIFFroundup(sizeof (TIFFYCbCrToRGB), sizeof (long)));
-    _TIFFmemset(clamptab, 0, 256);		/* v < 0 => 0 */
-    ycbcr->clamptab = (clamptab += 256);
-    for (i = 0; i < 256; i++)
-	clamptab[i] = (TIFFRGBValue) i;
-    _TIFFmemset(clamptab+256, 255, 2*256);	/* v > 255 => 255 */
-    ycbcr->Cr_r_tab = (int*) (clamptab + 3*256);
-    ycbcr->Cb_b_tab = ycbcr->Cr_r_tab + 256;
-    ycbcr->Cr_g_tab = (int32*) (ycbcr->Cb_b_tab + 256);
-    ycbcr->Cb_g_tab = ycbcr->Cr_g_tab + 256;
-    ycbcr->Y_tab = ycbcr->Cb_g_tab + 256;
-
-    { float f1 = 2-2*LumaRed;		int32 D1 = FIX(f1);
-      float f2 = LumaRed*f1/LumaGreen;	int32 D2 = -FIX(f2);
-      float f3 = 2-2*LumaBlue;		int32 D3 = FIX(f3);
-      float f4 = LumaBlue*f3/LumaGreen;	int32 D4 = -FIX(f4);
-      int x;
-
-#undef LumaBlue
-#undef LumaGreen
-#undef LumaRed
-      
-      /*
-       * i is the actual input pixel value in the range 0..255
-       * Cb and Cr values are in the range -128..127 (actually
-       * they are in a range defined by the ReferenceBlackWhite
-       * tag) so there is some range shifting to do here when
-       * constructing tables indexed by the raw pixel data.
-       */
-      for (i = 0, x = -128; i < 256; i++, x++) {
-	    int32 Cr = (int32)Code2V(x, refBlackWhite[4] - 128.0F,
-			    refBlackWhite[5] - 128.0F, 127);
-	    int32 Cb = (int32)Code2V(x, refBlackWhite[2] - 128.0F,
-			    refBlackWhite[3] - 128.0F, 127);
-
-	    ycbcr->Cr_r_tab[i] = (int32)((D1*Cr + ONE_HALF)>>SHIFT);
-	    ycbcr->Cb_b_tab[i] = (int32)((D3*Cb + ONE_HALF)>>SHIFT);
-	    ycbcr->Cr_g_tab[i] = D2*Cr;
-	    ycbcr->Cb_g_tab[i] = D4*Cb + ONE_HALF;
-	    ycbcr->Y_tab[i] =
-		    (int32)Code2V(x + 128, refBlackWhite[0], refBlackWhite[1], 255);
-      }
-    }
-
-    return 0;
-}
-#undef	HICLAMP
-#undef	CLAMP
-#undef	Code2V
-#undef	SHIFT
-#undef	ONE_HALF
-#undef	FIX
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_compress.c b/Source/LibTIFF/tif_compress.c
deleted file mode 100644
index 7ec707a..0000000
--- a/Source/LibTIFF/tif_compress.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/* $Id: tif_compress.c,v 1.37 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library
- *
- * Compression Scheme Configuration Support.
- */
-#include "tiffiop.h"
-
-static int
-TIFFNoEncode(TIFF* tif, const char* method)
-{
-	const TIFFCodec* c = TIFFFindCODEC(tif->tif_dir.td_compression);
-
-	if (c) { 
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			     "%s %s encoding is not implemented",
-			     c->name, method);
-	} else { 
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			"Compression scheme %u %s encoding is not implemented",
-			     tif->tif_dir.td_compression, method);
-	}
-	return (-1);
-}
-
-int
-_TIFFNoRowEncode(TIFF* tif, tidata_t pp, tsize_t cc, tsample_t s)
-{
-	(void) pp; (void) cc; (void) s;
-	return (TIFFNoEncode(tif, "scanline"));
-}
-
-int
-_TIFFNoStripEncode(TIFF* tif, tidata_t pp, tsize_t cc, tsample_t s)
-{
-	(void) pp; (void) cc; (void) s;
-	return (TIFFNoEncode(tif, "strip"));
-}
-
-int
-_TIFFNoTileEncode(TIFF* tif, tidata_t pp, tsize_t cc, tsample_t s)
-{
-	(void) pp; (void) cc; (void) s;
-	return (TIFFNoEncode(tif, "tile"));
-}
-
-static int
-TIFFNoDecode(TIFF* tif, const char* method)
-{
-	const TIFFCodec* c = TIFFFindCODEC(tif->tif_dir.td_compression);
-
-	if (c)
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			     "%s %s decoding is not implemented",
-			     c->name, method);
-	else
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			     "Compression scheme %u %s decoding is not implemented",
-			     tif->tif_dir.td_compression, method);
-	return (-1);
-}
-
-int
-_TIFFNoRowDecode(TIFF* tif, tidata_t pp, tsize_t cc, tsample_t s)
-{
-	(void) pp; (void) cc; (void) s;
-	return (TIFFNoDecode(tif, "scanline"));
-}
-
-int
-_TIFFNoStripDecode(TIFF* tif, tidata_t pp, tsize_t cc, tsample_t s)
-{
-	(void) pp; (void) cc; (void) s;
-	return (TIFFNoDecode(tif, "strip"));
-}
-
-int
-_TIFFNoTileDecode(TIFF* tif, tidata_t pp, tsize_t cc, tsample_t s)
-{
-	(void) pp; (void) cc; (void) s;
-	return (TIFFNoDecode(tif, "tile"));
-}
-
-int
-_TIFFNoSeek(TIFF* tif, uint32 off)
-{
-	(void) off;
-	TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-		     "Compression algorithm does not support random access");
-	return (0);
-}
-
-int
-_TIFFNoPreCode(TIFF* tif, tsample_t s)
-{
-	(void) tif; (void) s;
-	return (1);
-}
-
-static int _TIFFtrue(TIFF* tif) { (void) tif; return (1); }
-static void _TIFFvoid(TIFF* tif) { (void) tif; }
-
-void
-_TIFFSetDefaultCompressionState(TIFF* tif)
-{
-	tif->tif_decodestatus = TRUE;
-	tif->tif_setupdecode = _TIFFtrue;
-	tif->tif_predecode = _TIFFNoPreCode;
-	tif->tif_decoderow = _TIFFNoRowDecode;
-	tif->tif_decodestrip = _TIFFNoStripDecode;
-	tif->tif_decodetile = _TIFFNoTileDecode;
-	tif->tif_encodestatus = TRUE;
-	tif->tif_setupencode = _TIFFtrue;
-	tif->tif_preencode = _TIFFNoPreCode;
-	tif->tif_postencode = _TIFFtrue;
-	tif->tif_encoderow = _TIFFNoRowEncode;
-	tif->tif_encodestrip = _TIFFNoStripEncode;
-	tif->tif_encodetile = _TIFFNoTileEncode;
-	tif->tif_close = _TIFFvoid;
-	tif->tif_seek = _TIFFNoSeek;
-	tif->tif_cleanup = _TIFFvoid;
-	tif->tif_defstripsize = _TIFFDefaultStripSize;
-	tif->tif_deftilesize = _TIFFDefaultTileSize;
-	tif->tif_flags &= ~(TIFF_NOBITREV|TIFF_NOREADRAW);
-}
-
-int
-TIFFSetCompressionScheme(TIFF* tif, int scheme)
-{
-	const TIFFCodec *c = TIFFFindCODEC((uint16) scheme);
-
-	_TIFFSetDefaultCompressionState(tif);
-	/*
-	 * Don't treat an unknown compression scheme as an error.
-	 * This permits applications to open files with data that
-	 * the library does not have builtin support for, but which
-	 * may still be meaningful.
-	 */
-	return (c ? (*c->init)(tif, scheme) : 1);
-}
-
-/*
- * Other compression schemes may be registered.  Registered
- * schemes can also override the builtin versions provided
- * by this library.
- */
-typedef struct _codec {
-	struct _codec*	next;
-	TIFFCodec*	info;
-} codec_t;
-static	codec_t* registeredCODECS = NULL;
-
-const TIFFCodec*
-TIFFFindCODEC(uint16 scheme)
-{
-	const TIFFCodec* c;
-	codec_t* cd;
-
-	for (cd = registeredCODECS; cd; cd = cd->next)
-		if (cd->info->scheme == scheme)
-			return ((const TIFFCodec*) cd->info);
-	for (c = _TIFFBuiltinCODECS; c->name; c++)
-		if (c->scheme == scheme)
-			return (c);
-	return ((const TIFFCodec*) 0);
-}
-
-TIFFCodec*
-TIFFRegisterCODEC(uint16 scheme, const char* name, TIFFInitMethod init)
-{
-	codec_t* cd = (codec_t*)
-	    _TIFFmalloc(sizeof (codec_t) + sizeof (TIFFCodec) + strlen(name)+1);
-
-	if (cd != NULL) {
-		cd->info = (TIFFCodec*) ((tidata_t) cd + sizeof (codec_t));
-		cd->info->name = (char*)
-		    ((tidata_t) cd->info + sizeof (TIFFCodec));
-		strcpy(cd->info->name, name);
-		cd->info->scheme = scheme;
-		cd->info->init = init;
-		cd->next = registeredCODECS;
-		registeredCODECS = cd;
-	} else {
-		TIFFErrorExt(0, "TIFFRegisterCODEC",
-		    "No space to register compression scheme %s", name);
-		return NULL;
-	}
-	return (cd->info);
-}
-
-void
-TIFFUnRegisterCODEC(TIFFCodec* c)
-{
-	codec_t* cd;
-	codec_t** pcd;
-
-	for (pcd = ®isteredCODECS; (cd = *pcd); pcd = &cd->next)
-		if (cd->info == c) {
-			*pcd = cd->next;
-			_TIFFfree(cd);
-			return;
-		}
-	TIFFErrorExt(0, "TIFFUnRegisterCODEC",
-	    "Cannot remove compression scheme %s; not registered", c->name);
-}
-
-/************************************************************************/
-/*                       TIFFGetConfisuredCODECs()                      */
-/************************************************************************/
-
-/**
- * Get list of configured codecs, both built-in and registered by user.
- * Caller is responsible to free this structure.
- * 
- * @return returns array of TIFFCodec records (the last record should be NULL)
- * or NULL if function failed.
- */
-
-TIFFCodec*
-TIFFGetConfiguredCODECs()
-{
-	int		i = 1;
-        codec_t		*cd;
-        const TIFFCodec	*c;
-	TIFFCodec	*codecs = NULL, *new_codecs;
-
-        for (cd = registeredCODECS; cd; cd = cd->next) {
-                new_codecs = (TIFFCodec *)
-			_TIFFrealloc(codecs, i * sizeof(TIFFCodec));
-		if (!new_codecs) {
-			_TIFFfree (codecs);
-			return NULL;
-		}
-		codecs = new_codecs;
-		_TIFFmemcpy(codecs + i - 1, cd, sizeof(TIFFCodec));
-		i++;
-	}
-        for (c = _TIFFBuiltinCODECS; c->name; c++) {
-                if (TIFFIsCODECConfigured(c->scheme)) {
-                        new_codecs = (TIFFCodec *)
-				_TIFFrealloc(codecs, i * sizeof(TIFFCodec));
-			if (!new_codecs) {
-				_TIFFfree (codecs);
-				return NULL;
-			}
-			codecs = new_codecs;
-			_TIFFmemcpy(codecs + i - 1, (const tdata_t)c, sizeof(TIFFCodec));
-			i++;
-		}
-	}
-
-	new_codecs = (TIFFCodec *) _TIFFrealloc(codecs, i * sizeof(TIFFCodec));
-	if (!new_codecs) {
-		_TIFFfree (codecs);
-		return NULL;
-	}
-	codecs = new_codecs;
-	_TIFFmemset(codecs + i - 1, 0, sizeof(TIFFCodec));
-
-        return codecs;
-}
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_config.h b/Source/LibTIFF/tif_config.h
deleted file mode 100644
index 8fa80c1..0000000
--- a/Source/LibTIFF/tif_config.h
+++ /dev/null
@@ -1,266 +0,0 @@
-/* FreeImage libtiff config */
-
-#ifndef _TIFFCONF_
-#define _TIFFCONF_
-
-/* Define as 0 or 1 according to the floating point format suported by the
-   machine */
-#define HAVE_IEEEFP 1
-
-/* --- byte order --- */
-
-/* Some versions of gcc may have BYTE_ORDER or __BYTE_ORDER defined
-   If your big endian system isn't being detected, add an OS specific check
-*/
-#if (defined(BYTE_ORDER) && BYTE_ORDER==BIG_ENDIAN) || \
-	(defined(__BYTE_ORDER) && __BYTE_ORDER==__BIG_ENDIAN) || \
-	defined(__BIG_ENDIAN__)
-/* Set the native cpu bit order (FILLORDER_LSB2MSB or FILLORDER_MSB2LSB) */
-#define HOST_FILLORDER FILLORDER_MSB2LSB
-/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian (Intel) */
-#define WORDS_BIGENDIAN 1
-#else
-/* Set the native cpu bit order (FILLORDER_LSB2MSB or FILLORDER_MSB2LSB) */
-#define HOST_FILLORDER FILLORDER_LSB2MSB
-/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian (Intel) */
-#undef WORDS_BIGENDIAN
-#endif // BYTE_ORDER
-
-/* --- compression algorithms --- */
-
-/* Support CCITT Group 3 & 4 algorithms */
-#define CCITT_SUPPORT 1
-
-/* Support JPEG compression (requires IJG JPEG library) */
-#define JPEG_SUPPORT 1
-
-/* Support LogLuv high dynamic range encoding */
-#define LOGLUV_SUPPORT 1
-
-/* Support LZW algorithm */
-#define LZW_SUPPORT 1
-
-/* Support NeXT 2-bit RLE algorithm */
-#define NEXT_SUPPORT 1
-
-/* Support Old JPEG compression (read-only) */
-#define OJPEG_SUPPORT 1
-
-/* Support Macintosh PackBits algorithm */
-#define PACKBITS_SUPPORT 1
-
-/* Support Pixar log-format algorithm (requires Zlib) */
-#define PIXARLOG_SUPPORT 1
-
-/* Support ThunderScan 4-bit RLE algorithm */
-#define THUNDER_SUPPORT 1
-
-/* Support Deflate compression */
-#define ZIP_SUPPORT 1
-
-/* --- ``Orthogonal Features'' --- */
-
-/* Support strip chopping (whether or not to convert single-strip uncompressed
-   images to mutiple strips of ~8Kb to reduce memory usage) */
-#define STRIPCHOP_DEFAULT TIFF_STRIPCHOP
-
-/* Enable SubIFD tag (330) support */
-#define SUBIFD_SUPPORT 1
-
-/* Treat extra sample as alpha (default enabled). The RGBA interface will
-   treat a fourth sample with no EXTRASAMPLE_ value as being ASSOCALPHA. Many
-   packages produce RGBA files but don't mark the alpha properly. */
-#define DEFAULT_EXTRASAMPLE_AS_ALPHA 1
-
-/* Pick up YCbCr subsampling info from the JPEG data stream to support files
-   lacking the tag (default enabled). */
-#define CHECK_JPEG_YCBCR_SUBSAMPLING 1
-
-/* --- include files --- */
-
-/* Use the Apple OpenGL framework. */
-/* #undef HAVE_APPLE_OPENGL_FRAMEWORK */
-
-/* Define to 1 if you have the <assert.h> header file. */
-#define HAVE_ASSERT_H 1
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#define HAVE_DLFCN_H 1
-
-/* Define to 1 if you have the <fcntl.h> header file. */
-#define HAVE_FCNTL_H 1
-
-/* Define to 1 if you have the `floor' function. */
-#define HAVE_FLOOR 1
-
-/* Define to 1 if you have the `getopt' function. */
-#define HAVE_GETOPT 1
-
-/* Define as 0 or 1 according to the floating point format suported by the
-   machine */
-#define HAVE_IEEEFP 1
-
-/* Define to 1 if the system has the type `int16'. */
-/* #undef HAVE_INT16 */
-
-/* Define to 1 if the system has the type `int32'. */
-/* #undef HAVE_INT32 */
-
-/* Define to 1 if the system has the type `int8'. */
-/* #undef HAVE_INT8 */
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 1
-
-/* Define to 1 if you have the `isascii' function. */
-#define HAVE_ISASCII 1
-
-/* Define to 1 if you have the `c' library (-lc). */
-#define HAVE_LIBC 1
-
-/* Define to 1 if you have the `m' library (-lm). */
-#define HAVE_LIBM 1
-
-/* Define to 1 if you have the <limits.h> header file. */
-#define HAVE_LIMITS_H 1
-
-/* Define to 1 if you have the <malloc.h> header file. */
-#define HAVE_MALLOC_H 1
-
-/* Define to 1 if you have the `memmove' function. */
-#define HAVE_MEMMOVE 1
-
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* Define to 1 if you have the `memset' function. */
-#define HAVE_MEMSET 1
-
-/* Define to 1 if you have the `mmap' function. */
-#define HAVE_MMAP 1
-
-/* Define to 1 if you have the `pow' function. */
-#define HAVE_POW 1
-
-/* Define if you have POSIX threads libraries and header files. */
-#define HAVE_PTHREAD 1
-
-/* Define to 1 if you have the `sqrt' function. */
-#define HAVE_SQRT 1
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the `strcasecmp' function. */
-#define HAVE_STRCASECMP 1
-
-/* Define to 1 if you have the `strchr' function. */
-#define HAVE_STRCHR 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have the `strrchr' function. */
-#define HAVE_STRRCHR 1
-
-/* Define to 1 if you have the `strstr' function. */
-#define HAVE_STRSTR 1
-
-/* Define to 1 if you have the `strtol' function. */
-#define HAVE_STRTOL 1
-
-/* Define to 1 if you have the `strtoul' function. */
-#define HAVE_STRTOUL 1
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/time.h> header file. */
-#define HAVE_SYS_TIME_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#define HAVE_UNISTD_H 1
-
-/* Define to 1 if you have the <windows.h> header file. */
-/* #undef HAVE_WINDOWS_H */
-
-
-/* Define to 1 if your C compiler doesn't accept -c and -o together. */
-/* #undef NO_MINUS_C_MINUS_O */
-
-
-/* Define to the necessary symbol if this constant uses a non-standard name on
-   your system. */
-/* #undef PTHREAD_CREATE_JOINABLE */
-
-/* The size of a `int', as computed by sizeof. */
-#define SIZEOF_INT 4
-
-/* The size of a `long', as computed by sizeof. */
-#include <limits.h>
-#if (LONG_MAX == +9223372036854775807L)
-#define SIZEOF_LONG 8
-#elif (LONG_MAX == +2147483647)
-#define SIZEOF_LONG 4
-#else
-#error "Cannot detect SIZEOF_LONG"
-#endif
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
-#define TIME_WITH_SYS_TIME 1
-
-/* Define to 1 if your <sys/time.h> declares `struct tm'. */
-/* #undef TM_IN_SYS_TIME */
-
-
-/* Define to 1 if your processor stores words with the most significant byte
-   first (like Motorola and SPARC, unlike Intel and VAX). */
-/* #undef WORDS_BIGENDIAN */
-
-/* Define to 1 if the X Window System is missing or not being used. */
-/* #undef X_DISPLAY_MISSING */
-
-/* Define for large files, on AIX-style hosts. */
-/* #undef _LARGE_FILES */
-
-/* Define to empty if `const' does not conform to ANSI C. */
-/* #undef const */
-
-/* Define to `__inline__' or `__inline' if that's what the C compiler
-   calls it, or to nothing if 'inline' is not supported under any name.  */
-#ifndef __cplusplus
-  #ifdef _MSC_VER
-    #ifndef inline
-    #define inline __inline
-    #endif
-  #else
-    #undef inline
-  #endif // _MSC_VER
-#endif // __cplusplus
-
-#ifdef _MSC_VER 
-#define lfind _lfind
-/* Define to 1 if you have the <search.h> header file. */
-#define HAVE_SEARCH_H 1
-#endif // _MSC_VER
-
-
-/* Define to `long' if <sys/types.h> does not define. */
-/* #undef off_t */
-
-/* Define to `unsigned' if <sys/types.h> does not define. */
-/* #undef size_t */
-
-#endif /* _TIFFCONF_ */
diff --git a/Source/LibTIFF/tif_config.h-vms b/Source/LibTIFF/tif_config.h-vms
deleted file mode 100644
index c2cae57..0000000
--- a/Source/LibTIFF/tif_config.h-vms
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Define to 1 if you have the <assert.h> header file. */
-#define HAVE_ASSERT_H 1
-
-/* Define to 1 if you have the <fcntl.h> header file. */
-#define HAVE_FCNTL_H 1
-
-/* Define as 0 or 1 according to the floating point format suported by the
-   machine */
-#define HAVE_IEEEFP 1
-
-#define HAVE_UNISTD_H 1
-
-#define HAVE_STRING_H 1
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <io.h> header file. */
-//#define HAVE_IO_H 1
-
-/* Define to 1 if you have the <search.h> header file. */
-//#define HAVE_SEARCH_H 1
-
-/* The size of a `int', as computed by sizeof. */
-#define SIZEOF_INT 4
-
-/* The size of a `long', as computed by sizeof. */
-#define SIZEOF_LONG 4
-
-/* Set the native cpu bit order */
-#define HOST_FILLORDER FILLORDER_LSB2MSB
-
-/* Define to 1 if your processor stores words with the most significant byte
-   first (like Motorola and SPARC, unlike Intel and VAX). */
-/* #undef WORDS_BIGENDIAN */
-
-/* Define to `__inline__' or `__inline' if that's what the C compiler
-   calls it, or to nothing if 'inline' is not supported under any name.  */
-/*
-#ifndef __cplusplus
-# ifndef inline
-#  define inline __inline
-# endif
-#endif
-*/
-
-// #define lfind _lfind
diff --git a/Source/LibTIFF/tif_config.h.in b/Source/LibTIFF/tif_config.h.in
deleted file mode 100644
index 86c07e6..0000000
--- a/Source/LibTIFF/tif_config.h.in
+++ /dev/null
@@ -1,309 +0,0 @@
-/* libtiff/tif_config.h.in.  Generated from configure.ac by autoheader.  */
-
-/* Define if building universal (internal helper macro) */
-#undef AC_APPLE_UNIVERSAL_BUILD
-
-/* Support CCITT Group 3 & 4 algorithms */
-#undef CCITT_SUPPORT
-
-/* Pick up YCbCr subsampling info from the JPEG data stream to support files
-   lacking the tag (default enabled). */
-#undef CHECK_JPEG_YCBCR_SUBSAMPLING
-
-/* Support C++ stream API (requires C++ compiler) */
-#undef CXX_SUPPORT
-
-/* Treat extra sample as alpha (default enabled). The RGBA interface will
-   treat a fourth sample with no EXTRASAMPLE_ value as being ASSOCALPHA. Many
-   packages produce RGBA files but don't mark the alpha properly. */
-#undef DEFAULT_EXTRASAMPLE_AS_ALPHA
-
-/* Use the Apple OpenGL framework. */
-#undef HAVE_APPLE_OPENGL_FRAMEWORK
-
-/* Define to 1 if you have the <assert.h> header file. */
-#undef HAVE_ASSERT_H
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#undef HAVE_DLFCN_H
-
-/* Define to 1 if you have the <fcntl.h> header file. */
-#undef HAVE_FCNTL_H
-
-/* Define to 1 if you have the `floor' function. */
-#undef HAVE_FLOOR
-
-/* Define to 1 if you have the `getopt' function. */
-#undef HAVE_GETOPT
-
-/* Define as 0 or 1 according to the floating point format suported by the
-   machine */
-#undef HAVE_IEEEFP
-
-/* Define to 1 if the system has the type `int16'. */
-#undef HAVE_INT16
-
-/* Define to 1 if the system has the type `int32'. */
-#undef HAVE_INT32
-
-/* Define to 1 if the system has the type `int8'. */
-#undef HAVE_INT8
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#undef HAVE_INTTYPES_H
-
-/* Define to 1 if you have the <io.h> header file. */
-#undef HAVE_IO_H
-
-/* Define to 1 if you have the `isascii' function. */
-#undef HAVE_ISASCII
-
-/* Define to 1 if you have the `jbg_newlen' function. */
-#undef HAVE_JBG_NEWLEN
-
-/* Define to 1 if you have the `lfind' function. */
-#undef HAVE_LFIND
-
-/* Define to 1 if you have the `c' library (-lc). */
-#undef HAVE_LIBC
-
-/* Define to 1 if you have the `m' library (-lm). */
-#undef HAVE_LIBM
-
-/* Define to 1 if you have the <limits.h> header file. */
-#undef HAVE_LIMITS_H
-
-/* Define to 1 if you have the <malloc.h> header file. */
-#undef HAVE_MALLOC_H
-
-/* Define to 1 if you have the `memmove' function. */
-#undef HAVE_MEMMOVE
-
-/* Define to 1 if you have the <memory.h> header file. */
-#undef HAVE_MEMORY_H
-
-/* Define to 1 if you have the `memset' function. */
-#undef HAVE_MEMSET
-
-/* Define to 1 if you have the `mmap' function. */
-#undef HAVE_MMAP
-
-/* Define to 1 if you have the `pow' function. */
-#undef HAVE_POW
-
-/* Define if you have POSIX threads libraries and header files. */
-#undef HAVE_PTHREAD
-
-/* Define to 1 if you have the <search.h> header file. */
-#undef HAVE_SEARCH_H
-
-/* Define to 1 if you have the `setmode' function. */
-#undef HAVE_SETMODE
-
-/* Define to 1 if you have the `sqrt' function. */
-#undef HAVE_SQRT
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#undef HAVE_STDINT_H
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#undef HAVE_STDLIB_H
-
-/* Define to 1 if you have the `strcasecmp' function. */
-#undef HAVE_STRCASECMP
-
-/* Define to 1 if you have the `strchr' function. */
-#undef HAVE_STRCHR
-
-/* Define to 1 if you have the <strings.h> header file. */
-#undef HAVE_STRINGS_H
-
-/* Define to 1 if you have the <string.h> header file. */
-#undef HAVE_STRING_H
-
-/* Define to 1 if you have the `strrchr' function. */
-#undef HAVE_STRRCHR
-
-/* Define to 1 if you have the `strstr' function. */
-#undef HAVE_STRSTR
-
-/* Define to 1 if you have the `strtol' function. */
-#undef HAVE_STRTOL
-
-/* Define to 1 if you have the `strtoul' function. */
-#undef HAVE_STRTOUL
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#undef HAVE_SYS_STAT_H
-
-/* Define to 1 if you have the <sys/time.h> header file. */
-#undef HAVE_SYS_TIME_H
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#undef HAVE_SYS_TYPES_H
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#undef HAVE_UNISTD_H
-
-/* Define to 1 if you have the <windows.h> header file. */
-#undef HAVE_WINDOWS_H
-
-/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian
-   (Intel) */
-#undef HOST_BIGENDIAN
-
-/* Set the native cpu bit order (FILLORDER_LSB2MSB or FILLORDER_MSB2LSB) */
-#undef HOST_FILLORDER
-
-/* Support ISO JBIG compression (requires JBIG-KIT library) */
-#undef JBIG_SUPPORT
-
-/* Support JPEG compression (requires IJG JPEG library) */
-#undef JPEG_SUPPORT
-
-/* Support LogLuv high dynamic range encoding */
-#undef LOGLUV_SUPPORT
-
-/* Define to the sub-directory in which libtool stores uninstalled libraries.
-   */
-#undef LT_OBJDIR
-
-/* Support LZW algorithm */
-#undef LZW_SUPPORT
-
-/* Support Microsoft Document Imaging format */
-#undef MDI_SUPPORT
-
-/* Support NeXT 2-bit RLE algorithm */
-#undef NEXT_SUPPORT
-
-/* Define to 1 if your C compiler doesn't accept -c and -o together. */
-#undef NO_MINUS_C_MINUS_O
-
-/* Support Old JPEG compresson (read-only) */
-#undef OJPEG_SUPPORT
-
-/* Name of package */
-#undef PACKAGE
-
-/* Define to the address where bug reports for this package should be sent. */
-#undef PACKAGE_BUGREPORT
-
-/* Define to the full name of this package. */
-#undef PACKAGE_NAME
-
-/* Define to the full name and version of this package. */
-#undef PACKAGE_STRING
-
-/* Define to the one symbol short name of this package. */
-#undef PACKAGE_TARNAME
-
-/* Define to the home page for this package. */
-#undef PACKAGE_URL
-
-/* Define to the version of this package. */
-#undef PACKAGE_VERSION
-
-/* Support Macintosh PackBits algorithm */
-#undef PACKBITS_SUPPORT
-
-/* Support Pixar log-format algorithm (requires Zlib) */
-#undef PIXARLOG_SUPPORT
-
-/* Define to necessary symbol if this constant uses a non-standard name on
-   your system. */
-#undef PTHREAD_CREATE_JOINABLE
-
-/* The size of `int', as computed by sizeof. */
-#undef SIZEOF_INT
-
-/* The size of `long', as computed by sizeof. */
-#undef SIZEOF_LONG
-
-/* The size of `signed long', as computed by sizeof. */
-#undef SIZEOF_SIGNED_LONG
-
-/* The size of `signed long long', as computed by sizeof. */
-#undef SIZEOF_SIGNED_LONG_LONG
-
-/* The size of `unsigned long', as computed by sizeof. */
-#undef SIZEOF_UNSIGNED_LONG
-
-/* The size of `unsigned long long', as computed by sizeof. */
-#undef SIZEOF_UNSIGNED_LONG_LONG
-
-/* Define to 1 if you have the ANSI C header files. */
-#undef STDC_HEADERS
-
-/* Support strip chopping (whether or not to convert single-strip uncompressed
-   images to mutiple strips of specified size to reduce memory usage) */
-#undef STRIPCHOP_DEFAULT
-
-/* Default size of the strip in bytes (when strip chopping enabled) */
-#undef STRIP_SIZE_DEFAULT
-
-/* Enable SubIFD tag (330) support */
-#undef SUBIFD_SUPPORT
-
-/* Support ThunderScan 4-bit RLE algorithm */
-#undef THUNDER_SUPPORT
-
-/* Signed 64-bit type formatter */
-#undef TIFF_INT64_FORMAT
-
-/* Signed 64-bit type */
-#undef TIFF_INT64_T
-
-/* Unsigned 64-bit type formatter */
-#undef TIFF_UINT64_FORMAT
-
-/* Unsigned 64-bit type */
-#undef TIFF_UINT64_T
-
-/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
-#undef TIME_WITH_SYS_TIME
-
-/* Define to 1 if your <sys/time.h> declares `struct tm'. */
-#undef TM_IN_SYS_TIME
-
-/* Version number of package */
-#undef VERSION
-
-/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
-   significant byte first (like Motorola and SPARC, unlike Intel). */
-#if defined AC_APPLE_UNIVERSAL_BUILD
-# if defined __BIG_ENDIAN__
-#  define WORDS_BIGENDIAN 1
-# endif
-#else
-# ifndef WORDS_BIGENDIAN
-#  undef WORDS_BIGENDIAN
-# endif
-#endif
-
-/* Define to 1 if the X Window System is missing or not being used. */
-#undef X_DISPLAY_MISSING
-
-/* Support Deflate compression */
-#undef ZIP_SUPPORT
-
-/* Number of bits in a file offset, on hosts where this is settable. */
-#undef _FILE_OFFSET_BITS
-
-/* Define for large files, on AIX-style hosts. */
-#undef _LARGE_FILES
-
-/* Define to empty if `const' does not conform to ANSI C. */
-#undef const
-
-/* Define to `__inline__' or `__inline' if that's what the C compiler
-   calls it, or to nothing if 'inline' is not supported under any name.  */
-#ifndef __cplusplus
-#undef inline
-#endif
-
-/* Define to `long int' if <sys/types.h> does not define. */
-#undef off_t
-
-/* Define to `unsigned int' if <sys/types.h> does not define. */
-#undef size_t
diff --git a/Source/LibTIFF/tif_config.vc.h b/Source/LibTIFF/tif_config.vc.h
deleted file mode 100644
index 4dd77dd..0000000
--- a/Source/LibTIFF/tif_config.vc.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* Define to 1 if you have the <assert.h> header file. */
-#define HAVE_ASSERT_H 1
-
-/* Define to 1 if you have the <fcntl.h> header file. */
-#define HAVE_FCNTL_H 1
-
-/* Define as 0 or 1 according to the floating point format suported by the
-   machine */
-#define HAVE_IEEEFP 1
-
-/* Define to 1 if you have the `jbg_newlen' function. */
-#define HAVE_JBG_NEWLEN 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <io.h> header file. */
-#define HAVE_IO_H 1
-
-/* Define to 1 if you have the <search.h> header file. */
-#define HAVE_SEARCH_H 1
-
-/* Define to 1 if you have the `setmode' function. */
-#define HAVE_SETMODE 1
-
-/* The size of a `int', as computed by sizeof. */
-#define SIZEOF_INT 4
-
-/* The size of a `long', as computed by sizeof. */
-#define SIZEOF_LONG 4
-
-/* Signed 64-bit type */
-#define TIFF_INT64_T signed __int64
-
-/* Unsigned 64-bit type */
-#define TIFF_UINT64_T unsigned __int64
-
-/* Set the native cpu bit order */
-#define HOST_FILLORDER FILLORDER_LSB2MSB
-
-/* Define to 1 if your processor stores words with the most significant byte
-   first (like Motorola and SPARC, unlike Intel and VAX). */
-/* #undef WORDS_BIGENDIAN */
-
-/* Define to `__inline__' or `__inline' if that's what the C compiler
-   calls it, or to nothing if 'inline' is not supported under any name.  */
-#ifndef __cplusplus
-# ifndef inline
-#  define inline __inline
-# endif
-#endif
-
-#define lfind _lfind
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_config.wince.h b/Source/LibTIFF/tif_config.wince.h
deleted file mode 100644
index 1eadddb..0000000
--- a/Source/LibTIFF/tif_config.wince.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* $Id: tif_config.wince.h,v 1.21 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * TIFF library configuration header for Windows CE platform.
- */
-#ifndef _WIN32_WCE
-# error This version of tif_config.h header is dedicated for Windows CE platform!
-#endif
-
-/* Define to 1 if you have the <assert.h> header file. */
-#define HAVE_ASSERT_H 1
-
-/* Define to 1 if you have the <fcntl.h> header file. */
-#define  HAVE_FCNTL_H 1
-
-/* Define as 0 or 1 according to the floating point format suported by the
-   machine */
-#define HAVE_IEEEFP 1
-
-/* Define to 1 if you have the `jbg_newlen' function. */
-#define HAVE_JBG_NEWLEN 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#undef HAVE_SYS_TYPES_H
-
-/* Define to 1 if you have the <io.h> header file. */
-#define HAVE_IO_H 1
-
-/* Define to 1 if you have the <search.h> header file. */
-#define HAVE_SEARCH_H 1
-
-/* Define to 1 if you have the `setmode' function. */
-#define HAVE_SETMODE 1
-
-/* Define to 1 if you have the `bsearch' function. */
-#define HAVE_BSEARCH 1
-#define bsearch wceex_bsearch
-
-/* Define to 1 if you have the `lfind' function. */
-#define HAVE_LFIND 1
-#define lfind wceex_lfind
-
-/* The size of a `int', as computed by sizeof. */
-#define SIZEOF_INT 4
-
-/* The size of a `long', as computed by sizeof. */
-#define SIZEOF_LONG 4
-
-/* Set the native cpu bit order */
-#define HOST_FILLORDER FILLORDER_LSB2MSB
-
-/* Define to 1 if your processor stores words with the most significant byte
-   first (like Motorola and SPARC, unlike Intel and VAX). */
-/* #undef WORDS_BIGENDIAN */
-
-/* Define to `__inline__' or `__inline' if that's what the C compiler
-   calls it, or to nothing if 'inline' is not supported under any name.  */
-#ifndef __cplusplus
-# ifndef inline
-#  define inline __inline
-# endif
-#endif
-
-
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_dir.c b/Source/LibTIFF/tif_dir.c
deleted file mode 100644
index 1d58801..0000000
--- a/Source/LibTIFF/tif_dir.c
+++ /dev/null
@@ -1,1391 +0,0 @@
-/* $Id: tif_dir.c,v 1.38 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library.
- *
- * Directory Tag Get & Set Routines.
- * (and also some miscellaneous stuff)
- */
-#include "tiffiop.h"
-
-/*
- * These are used in the backwards compatibility code...
- */
-#define DATATYPE_VOID		0       /* !untyped data */
-#define DATATYPE_INT		1       /* !signed integer data */
-#define DATATYPE_UINT		2       /* !unsigned integer data */
-#define DATATYPE_IEEEFP		3       /* !IEEE floating point data */
-
-static void
-setByteArray(void** vpp, void* vp, size_t nmemb, size_t elem_size)
-{
-	if (*vpp)
-		_TIFFfree(*vpp), *vpp = 0;
-	if (vp) {
-		tsize_t	bytes = nmemb * elem_size;
-		if (elem_size && bytes / elem_size == nmemb)
-			*vpp = (void*) _TIFFmalloc(bytes);
-		if (*vpp)
-			_TIFFmemcpy(*vpp, vp, bytes);
-	}
-}
-void _TIFFsetByteArray(void** vpp, void* vp, uint32 n)
-    { setByteArray(vpp, vp, n, 1); }
-void _TIFFsetString(char** cpp, char* cp)
-    { setByteArray((void**) cpp, (void*) cp, strlen(cp)+1, 1); }
-void _TIFFsetNString(char** cpp, char* cp, uint32 n)
-    { setByteArray((void**) cpp, (void*) cp, n, 1); }
-void _TIFFsetShortArray(uint16** wpp, uint16* wp, uint32 n)
-    { setByteArray((void**) wpp, (void*) wp, n, sizeof (uint16)); }
-void _TIFFsetLongArray(uint32** lpp, uint32* lp, uint32 n)
-    { setByteArray((void**) lpp, (void*) lp, n, sizeof (uint32)); }
-void _TIFFsetFloatArray(float** fpp, float* fp, uint32 n)
-    { setByteArray((void**) fpp, (void*) fp, n, sizeof (float)); }
-void _TIFFsetDoubleArray(double** dpp, double* dp, uint32 n)
-    { setByteArray((void**) dpp, (void*) dp, n, sizeof (double)); }
-
-/*
- * Install extra samples information.
- */
-static int
-setExtraSamples(TIFFDirectory* td, va_list ap, uint32* v)
-{
-/* XXX: Unassociated alpha data == 999 is a known Corel Draw bug, see below */
-#define EXTRASAMPLE_COREL_UNASSALPHA 999 
-
-	uint16* va;
-	uint32 i;
-
-	*v = va_arg(ap, uint32);
-	if ((uint16) *v > td->td_samplesperpixel)
-		return 0;
-	va = va_arg(ap, uint16*);
-	if (*v > 0 && va == NULL)		/* typically missing param */
-		return 0;
-	for (i = 0; i < *v; i++) {
-		if (va[i] > EXTRASAMPLE_UNASSALPHA) {
-			/*
-			 * XXX: Corel Draw is known to produce incorrect
-			 * ExtraSamples tags which must be patched here if we
-			 * want to be able to open some of the damaged TIFF
-			 * files: 
-			 */
-			if (va[i] == EXTRASAMPLE_COREL_UNASSALPHA)
-				va[i] = EXTRASAMPLE_UNASSALPHA;
-			else
-				return 0;
-		}
-	}
-	td->td_extrasamples = (uint16) *v;
-	_TIFFsetShortArray(&td->td_sampleinfo, va, td->td_extrasamples);
-	return 1;
-
-#undef EXTRASAMPLE_COREL_UNASSALPHA
-}
-
-static uint32
-checkInkNamesString(TIFF* tif, uint32 slen, const char* s)
-{
-	TIFFDirectory* td = &tif->tif_dir;
-	uint16 i = td->td_samplesperpixel;
-
-	if (slen > 0) {
-		const char* ep = s+slen;
-		const char* cp = s;
-		for (; i > 0; i--) {
-			for (; *cp != '\0'; cp++)
-				if (cp >= ep)
-					goto bad;
-			cp++;				/* skip \0 */
-		}
-		return (cp-s);
-	}
-bad:
-	TIFFErrorExt(tif->tif_clientdata, "TIFFSetField",
-	    "%s: Invalid InkNames value; expecting %d names, found %d",
-	    tif->tif_name,
-	    td->td_samplesperpixel,
-	    td->td_samplesperpixel-i);
-	return (0);
-}
-
-static int
-_TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap)
-{
-	static const char module[] = "_TIFFVSetField";
-
-	TIFFDirectory* td = &tif->tif_dir;
-	int status = 1;
-	uint32 v32, i, v;
-	char* s;
-
-	switch (tag) {
-	case TIFFTAG_SUBFILETYPE:
-		td->td_subfiletype = va_arg(ap, uint32);
-		break;
-	case TIFFTAG_IMAGEWIDTH:
-		td->td_imagewidth = va_arg(ap, uint32);
-		break;
-	case TIFFTAG_IMAGELENGTH:
-		td->td_imagelength = va_arg(ap, uint32);
-		break;
-	case TIFFTAG_BITSPERSAMPLE:
-		td->td_bitspersample = (uint16) va_arg(ap, int);
-		/*
-		 * If the data require post-decoding processing to byte-swap
-		 * samples, set it up here.  Note that since tags are required
-		 * to be ordered, compression code can override this behaviour
-		 * in the setup method if it wants to roll the post decoding
-		 * work in with its normal work.
-		 */
-		if (tif->tif_flags & TIFF_SWAB) {
-			if (td->td_bitspersample == 8)
-				tif->tif_postdecode = _TIFFNoPostDecode;
-			else if (td->td_bitspersample == 16)
-				tif->tif_postdecode = _TIFFSwab16BitData;
-			else if (td->td_bitspersample == 24)
-				tif->tif_postdecode = _TIFFSwab24BitData;
-			else if (td->td_bitspersample == 32)
-				tif->tif_postdecode = _TIFFSwab32BitData;
-			else if (td->td_bitspersample == 64)
-				tif->tif_postdecode = _TIFFSwab64BitData;
-			else if (td->td_bitspersample == 128) /* two 64's */
-				tif->tif_postdecode = _TIFFSwab64BitData;
-		}
-		break;
-	case TIFFTAG_COMPRESSION:
-		v = va_arg(ap, uint32) & 0xffff;
-		/*
-		 * If we're changing the compression scheme, the notify the
-		 * previous module so that it can cleanup any state it's
-		 * setup.
-		 */
-		if (TIFFFieldSet(tif, FIELD_COMPRESSION)) {
-			if (td->td_compression == v)
-				break;
-			(*tif->tif_cleanup)(tif);
-			tif->tif_flags &= ~TIFF_CODERSETUP;
-		}
-		/*
-		 * Setup new compression routine state.
-		 */
-		if( (status = TIFFSetCompressionScheme(tif, v)) != 0 )
-                    td->td_compression = (uint16) v;
-                else
-                    status = 0;
-		break;
-	case TIFFTAG_PHOTOMETRIC:
-		td->td_photometric = (uint16) va_arg(ap, int);
-		break;
-	case TIFFTAG_THRESHHOLDING:
-		td->td_threshholding = (uint16) va_arg(ap, int);
-		break;
-	case TIFFTAG_FILLORDER:
-		v = va_arg(ap, uint32);
-		if (v != FILLORDER_LSB2MSB && v != FILLORDER_MSB2LSB)
-			goto badvalue;
-		td->td_fillorder = (uint16) v;
-		break;
-	case TIFFTAG_ORIENTATION:
-		v = va_arg(ap, uint32);
-		if (v < ORIENTATION_TOPLEFT || ORIENTATION_LEFTBOT < v)
-			goto badvalue;
-		else
-			td->td_orientation = (uint16) v;
-		break;
-	case TIFFTAG_SAMPLESPERPIXEL:
-		/* XXX should cross check -- e.g. if pallette, then 1 */
-		v = va_arg(ap, uint32);
-		if (v == 0)
-			goto badvalue;
-		td->td_samplesperpixel = (uint16) v;
-		break;
-	case TIFFTAG_ROWSPERSTRIP:
-		v32 = va_arg(ap, uint32);
-		if (v32 == 0)
-			goto badvalue32;
-		td->td_rowsperstrip = v32;
-		if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) {
-			td->td_tilelength = v32;
-			td->td_tilewidth = td->td_imagewidth;
-		}
-		break;
-	case TIFFTAG_MINSAMPLEVALUE:
-		td->td_minsamplevalue = (uint16) va_arg(ap, int);
-		break;
-	case TIFFTAG_MAXSAMPLEVALUE:
-		td->td_maxsamplevalue = (uint16) va_arg(ap, int);
-		break;
-	case TIFFTAG_SMINSAMPLEVALUE:
-		td->td_sminsamplevalue = va_arg(ap, double);
-		break;
-	case TIFFTAG_SMAXSAMPLEVALUE:
-		td->td_smaxsamplevalue = va_arg(ap, double);
-		break;
-	case TIFFTAG_XRESOLUTION:
-		td->td_xresolution = (float) va_arg(ap, double);
-		break;
-	case TIFFTAG_YRESOLUTION:
-		td->td_yresolution = (float) va_arg(ap, double);
-		break;
-	case TIFFTAG_PLANARCONFIG:
-		v = va_arg(ap, uint32);
-		if (v != PLANARCONFIG_CONTIG && v != PLANARCONFIG_SEPARATE)
-			goto badvalue;
-		td->td_planarconfig = (uint16) v;
-		break;
-	case TIFFTAG_XPOSITION:
-		td->td_xposition = (float) va_arg(ap, double);
-		break;
-	case TIFFTAG_YPOSITION:
-		td->td_yposition = (float) va_arg(ap, double);
-		break;
-	case TIFFTAG_RESOLUTIONUNIT:
-		v = va_arg(ap, uint32);
-		if (v < RESUNIT_NONE || RESUNIT_CENTIMETER < v)
-			goto badvalue;
-		td->td_resolutionunit = (uint16) v;
-		break;
-	case TIFFTAG_PAGENUMBER:
-		td->td_pagenumber[0] = (uint16) va_arg(ap, int);
-		td->td_pagenumber[1] = (uint16) va_arg(ap, int);
-		break;
-	case TIFFTAG_HALFTONEHINTS:
-		td->td_halftonehints[0] = (uint16) va_arg(ap, int);
-		td->td_halftonehints[1] = (uint16) va_arg(ap, int);
-		break;
-	case TIFFTAG_COLORMAP:
-		v32 = (uint32)(1L<<td->td_bitspersample);
-		_TIFFsetShortArray(&td->td_colormap[0], va_arg(ap, uint16*), v32);
-		_TIFFsetShortArray(&td->td_colormap[1], va_arg(ap, uint16*), v32);
-		_TIFFsetShortArray(&td->td_colormap[2], va_arg(ap, uint16*), v32);
-		break;
-	case TIFFTAG_EXTRASAMPLES:
-		if (!setExtraSamples(td, ap, &v))
-			goto badvalue;
-		break;
-	case TIFFTAG_MATTEING:
-		td->td_extrasamples = (uint16) (va_arg(ap, int) != 0);
-		if (td->td_extrasamples) {
-			uint16 sv = EXTRASAMPLE_ASSOCALPHA;
-			_TIFFsetShortArray(&td->td_sampleinfo, &sv, 1);
-		}
-		break;
-	case TIFFTAG_TILEWIDTH:
-		v32 = va_arg(ap, uint32);
-		if (v32 % 16) {
-			if (tif->tif_mode != O_RDONLY)
-				goto badvalue32;
-			TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
-				"Nonstandard tile width %d, convert file", v32);
-		}
-		td->td_tilewidth = v32;
-		tif->tif_flags |= TIFF_ISTILED;
-		break;
-	case TIFFTAG_TILELENGTH:
-		v32 = va_arg(ap, uint32);
-		if (v32 % 16) {
-			if (tif->tif_mode != O_RDONLY)
-				goto badvalue32;
-			TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
-			    "Nonstandard tile length %d, convert file", v32);
-		}
-		td->td_tilelength = v32;
-		tif->tif_flags |= TIFF_ISTILED;
-		break;
-	case TIFFTAG_TILEDEPTH:
-		v32 = va_arg(ap, uint32);
-		if (v32 == 0)
-			goto badvalue32;
-		td->td_tiledepth = v32;
-		break;
-	case TIFFTAG_DATATYPE:
-		v = va_arg(ap, uint32);
-		switch (v) {
-		case DATATYPE_VOID:	v = SAMPLEFORMAT_VOID;	break;
-		case DATATYPE_INT:	v = SAMPLEFORMAT_INT;	break;
-		case DATATYPE_UINT:	v = SAMPLEFORMAT_UINT;	break;
-		case DATATYPE_IEEEFP:	v = SAMPLEFORMAT_IEEEFP;break;
-		default:		goto badvalue;
-		}
-		td->td_sampleformat = (uint16) v;
-		break;
-	case TIFFTAG_SAMPLEFORMAT:
-		v = va_arg(ap, uint32);
-		if (v < SAMPLEFORMAT_UINT || SAMPLEFORMAT_COMPLEXIEEEFP < v)
-			goto badvalue;
-		td->td_sampleformat = (uint16) v;
-
-                /*  Try to fix up the SWAB function for complex data. */
-                if( td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT 
-                    && td->td_bitspersample == 32
-                    && tif->tif_postdecode == _TIFFSwab32BitData )
-                    tif->tif_postdecode = _TIFFSwab16BitData;
-                else if( (td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT 
-                          || td->td_sampleformat == SAMPLEFORMAT_COMPLEXIEEEFP)
-                         && td->td_bitspersample == 64
-                         && tif->tif_postdecode == _TIFFSwab64BitData )
-                    tif->tif_postdecode = _TIFFSwab32BitData;
-		break;
-	case TIFFTAG_IMAGEDEPTH:
-		td->td_imagedepth = va_arg(ap, uint32);
-		break;
-	case TIFFTAG_SUBIFD:
-		if ((tif->tif_flags & TIFF_INSUBIFD) == 0) {
-			td->td_nsubifd = (uint16) va_arg(ap, int);
-			_TIFFsetLongArray(&td->td_subifd, va_arg(ap, uint32*),
-			    (long) td->td_nsubifd);
-		} else {
-			TIFFErrorExt(tif->tif_clientdata, module,
-				     "%s: Sorry, cannot nest SubIFDs",
-				     tif->tif_name);
-			status = 0;
-		}
-		break;
-	case TIFFTAG_YCBCRPOSITIONING:
-		td->td_ycbcrpositioning = (uint16) va_arg(ap, int);
-		break;
-	case TIFFTAG_YCBCRSUBSAMPLING:
-		td->td_ycbcrsubsampling[0] = (uint16) va_arg(ap, int);
-		td->td_ycbcrsubsampling[1] = (uint16) va_arg(ap, int);
-		break;
-	case TIFFTAG_TRANSFERFUNCTION:
-		v = (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1;
-		for (i = 0; i < v; i++)
-			_TIFFsetShortArray(&td->td_transferfunction[i],
-			    va_arg(ap, uint16*), 1L<<td->td_bitspersample);
-		break;
-	case TIFFTAG_REFERENCEBLACKWHITE:
-		/* XXX should check for null range */
-		_TIFFsetFloatArray(&td->td_refblackwhite, va_arg(ap, float*), 6);
-		break;
-	case TIFFTAG_INKNAMES:
-		v = va_arg(ap, uint32);
-		s = va_arg(ap, char*);
-		v = checkInkNamesString(tif, v, s);
-                status = v > 0;
-		if( v > 0 ) {
-			_TIFFsetNString(&td->td_inknames, s, v);
-			td->td_inknameslen = v;
-		}
-		break;
-        default: {
-            TIFFTagValue *tv;
-            int tv_size, iCustom;
-	    const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY);
-
-            /*
-	     * This can happen if multiple images are open with different
-	     * codecs which have private tags.  The global tag information
-	     * table may then have tags that are valid for one file but not
-	     * the other. If the client tries to set a tag that is not valid
-	     * for the image's codec then we'll arrive here.  This
-	     * happens, for example, when tiffcp is used to convert between
-	     * compression schemes and codec-specific tags are blindly copied.
-             */
-            if(fip == NULL || fip->field_bit != FIELD_CUSTOM) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-			     "%s: Invalid %stag \"%s\" (not supported by codec)",
-			     tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "",
-			     fip ? fip->field_name : "Unknown");
-		status = 0;
-		break;
-            }
-
-            /*
-             * Find the existing entry for this custom value.
-             */
-            tv = NULL;
-            for (iCustom = 0; iCustom < td->td_customValueCount; iCustom++) {
-		    if (td->td_customValues[iCustom].info->field_tag == tag) {
-			    tv = td->td_customValues + iCustom;
-			    if (tv->value != NULL) {
-				    _TIFFfree(tv->value);
-				    tv->value = NULL;
-			    }
-			    break;
-		    }
-            }
-
-            /*
-             * Grow the custom list if the entry was not found.
-             */
-            if(tv == NULL) {
-		TIFFTagValue	*new_customValues;
-		
-		td->td_customValueCount++;
-		new_customValues = (TIFFTagValue *)
-			_TIFFrealloc(td->td_customValues,
-				     sizeof(TIFFTagValue) * td->td_customValueCount);
-		if (!new_customValues) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-		"%s: Failed to allocate space for list of custom values",
-				  tif->tif_name);
-			status = 0;
-			goto end;
-		}
-
-		td->td_customValues = new_customValues;
-
-                tv = td->td_customValues + (td->td_customValueCount - 1);
-                tv->info = fip;
-                tv->value = NULL;
-                tv->count = 0;
-            }
-
-            /*
-             * Set custom value ... save a copy of the custom tag value.
-             */
-	    tv_size = _TIFFDataSize(fip->field_type);
-	    if (tv_size == 0) {
-		    status = 0;
-		    TIFFErrorExt(tif->tif_clientdata, module,
-				 "%s: Bad field type %d for \"%s\"",
-				 tif->tif_name, fip->field_type,
-				 fip->field_name);
-		    goto end;
-	    }
-           
-            if(fip->field_passcount) {
-		    if (fip->field_writecount == TIFF_VARIABLE2)
-			tv->count = (uint32) va_arg(ap, uint32);
-		    else
-			tv->count = (int) va_arg(ap, int);
-	    } else if (fip->field_writecount == TIFF_VARIABLE
-		       || fip->field_writecount == TIFF_VARIABLE2)
-		tv->count = 1;
-	    else if (fip->field_writecount == TIFF_SPP)
-		tv->count = td->td_samplesperpixel;
-	    else
-                tv->count = fip->field_writecount;
-            
-    
-	    if (fip->field_type == TIFF_ASCII)
-		    _TIFFsetString((char **)&tv->value, va_arg(ap, char *));
-	    else {
-		tv->value = _TIFFCheckMalloc(tif, tv_size, tv->count,
-					     "Tag Value");
-		if (!tv->value) {
-		    status = 0;
-		    goto end;
-		}
-
-		if ((fip->field_passcount
-		    || fip->field_writecount == TIFF_VARIABLE
-		    || fip->field_writecount == TIFF_VARIABLE2
-		    || fip->field_writecount == TIFF_SPP
-		    || tv->count > 1)
-		    && fip->field_tag != TIFFTAG_PAGENUMBER
-		    && fip->field_tag != TIFFTAG_HALFTONEHINTS
-		    && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING
-		    && fip->field_tag != TIFFTAG_DOTRANGE) {
-                    _TIFFmemcpy(tv->value, va_arg(ap, void *),
-				tv->count * tv_size);
-		} else {
-		    /*
-		     * XXX: The following loop required to handle
-		     * TIFFTAG_PAGENUMBER, TIFFTAG_HALFTONEHINTS,
-		     * TIFFTAG_YCBCRSUBSAMPLING and TIFFTAG_DOTRANGE tags.
-		     * These tags are actually arrays and should be passed as
-		     * array pointers to TIFFSetField() function, but actually
-		     * passed as a list of separate values. This behaviour
-		     * must be changed in the future!
-		     */
-		    int i;
-		    char *val = (char *)tv->value;
-
-		    for (i = 0; i < tv->count; i++, val += tv_size) {
-			    switch (fip->field_type) {
-				case TIFF_BYTE:
-				case TIFF_UNDEFINED:
-				    {
-					uint8 v = (uint8)va_arg(ap, int);
-					_TIFFmemcpy(val, &v, tv_size);
-				    }
-				    break;
-				case TIFF_SBYTE:
-				    {
-					int8 v = (int8)va_arg(ap, int);
-					_TIFFmemcpy(val, &v, tv_size);
-				    }
-				    break;
-				case TIFF_SHORT:
-				    {
-					uint16 v = (uint16)va_arg(ap, int);
-					_TIFFmemcpy(val, &v, tv_size);
-				    }
-				    break;
-				case TIFF_SSHORT:
-				    {
-					int16 v = (int16)va_arg(ap, int);
-					_TIFFmemcpy(val, &v, tv_size);
-				    }
-				    break;
-				case TIFF_LONG:
-				case TIFF_IFD:
-				    {
-					uint32 v = va_arg(ap, uint32);
-					_TIFFmemcpy(val, &v, tv_size);
-				    }
-				    break;
-				case TIFF_SLONG:
-				    {
-					int32 v = va_arg(ap, int32);
-					_TIFFmemcpy(val, &v, tv_size);
-				    }
-				    break;
-				case TIFF_RATIONAL:
-				case TIFF_SRATIONAL:
-				case TIFF_FLOAT:
-				    {
-					float v = (float)va_arg(ap, double);
-					_TIFFmemcpy(val, &v, tv_size);
-				    }
-				    break;
-				case TIFF_DOUBLE:
-				    {
-					double v = va_arg(ap, double);
-					_TIFFmemcpy(val, &v, tv_size);
-				    }
-				    break;
-				default:
-				    _TIFFmemset(val, 0, tv_size);
-				    status = 0;
-				    break;
-			    }
-		    }
-		}
-	    }
-          }
-	}
-	if (status) {
-		TIFFSetFieldBit(tif, _TIFFFieldWithTag(tif, tag)->field_bit);
-		tif->tif_flags |= TIFF_DIRTYDIRECT;
-	}
-
-end:
-	va_end(ap);
-	return (status);
-badvalue:
-	TIFFErrorExt(tif->tif_clientdata, module,
-		     "%s: Bad value %d for \"%s\" tag",
-		     tif->tif_name, v,
-		     _TIFFFieldWithTag(tif, tag)->field_name);
-	va_end(ap);
-	return (0);
-badvalue32:
-	TIFFErrorExt(tif->tif_clientdata, module,
-		     "%s: Bad value %u for \"%s\" tag",
-		     tif->tif_name, v32,
-		     _TIFFFieldWithTag(tif, tag)->field_name);
-	va_end(ap);
-	return (0);
-}
-
-/*
- * Return 1/0 according to whether or not
- * it is permissible to set the tag's value.
- * Note that we allow ImageLength to be changed
- * so that we can append and extend to images.
- * Any other tag may not be altered once writing
- * has commenced, unless its value has no effect
- * on the format of the data that is written.
- */
-static int
-OkToChangeTag(TIFF* tif, ttag_t tag)
-{
-	const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY);
-	if (!fip) {			/* unknown tag */
-		TIFFErrorExt(tif->tif_clientdata, "TIFFSetField", "%s: Unknown %stag %u",
-		    tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", tag);
-		return (0);
-	}
-	if (tag != TIFFTAG_IMAGELENGTH && (tif->tif_flags & TIFF_BEENWRITING) &&
-	    !fip->field_oktochange) {
-		/*
-		 * Consult info table to see if tag can be changed
-		 * after we've started writing.  We only allow changes
-		 * to those tags that don't/shouldn't affect the
-		 * compression and/or format of the data.
-		 */
-		TIFFErrorExt(tif->tif_clientdata, "TIFFSetField",
-		    "%s: Cannot modify tag \"%s\" while writing",
-		    tif->tif_name, fip->field_name);
-		return (0);
-	}
-	return (1);
-}
-
-/*
- * Record the value of a field in the
- * internal directory structure.  The
- * field will be written to the file
- * when/if the directory structure is
- * updated.
- */
-int
-TIFFSetField(TIFF* tif, ttag_t tag, ...)
-{
-	va_list ap;
-	int status;
-
-	va_start(ap, tag);
-	status = TIFFVSetField(tif, tag, ap);
-	va_end(ap);
-	return (status);
-}
-
-/*
- * Like TIFFSetField, but taking a varargs
- * parameter list.  This routine is useful
- * for building higher-level interfaces on
- * top of the library.
- */
-int
-TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap)
-{
-	return OkToChangeTag(tif, tag) ?
-	    (*tif->tif_tagmethods.vsetfield)(tif, tag, ap) : 0;
-}
-
-static int
-_TIFFVGetField(TIFF* tif, ttag_t tag, va_list ap)
-{
-    TIFFDirectory* td = &tif->tif_dir;
-    int            ret_val = 1;
-
-    switch (tag) {
-	case TIFFTAG_SUBFILETYPE:
-            *va_arg(ap, uint32*) = td->td_subfiletype;
-            break;
-	case TIFFTAG_IMAGEWIDTH:
-            *va_arg(ap, uint32*) = td->td_imagewidth;
-            break;
-	case TIFFTAG_IMAGELENGTH:
-            *va_arg(ap, uint32*) = td->td_imagelength;
-            break;
-	case TIFFTAG_BITSPERSAMPLE:
-            *va_arg(ap, uint16*) = td->td_bitspersample;
-            break;
-	case TIFFTAG_COMPRESSION:
-            *va_arg(ap, uint16*) = td->td_compression;
-            break;
-	case TIFFTAG_PHOTOMETRIC:
-            *va_arg(ap, uint16*) = td->td_photometric;
-            break;
-	case TIFFTAG_THRESHHOLDING:
-            *va_arg(ap, uint16*) = td->td_threshholding;
-            break;
-	case TIFFTAG_FILLORDER:
-            *va_arg(ap, uint16*) = td->td_fillorder;
-            break;
-	case TIFFTAG_ORIENTATION:
-            *va_arg(ap, uint16*) = td->td_orientation;
-            break;
-	case TIFFTAG_SAMPLESPERPIXEL:
-            *va_arg(ap, uint16*) = td->td_samplesperpixel;
-            break;
-	case TIFFTAG_ROWSPERSTRIP:
-            *va_arg(ap, uint32*) = td->td_rowsperstrip;
-            break;
-	case TIFFTAG_MINSAMPLEVALUE:
-            *va_arg(ap, uint16*) = td->td_minsamplevalue;
-            break;
-	case TIFFTAG_MAXSAMPLEVALUE:
-            *va_arg(ap, uint16*) = td->td_maxsamplevalue;
-            break;
-	case TIFFTAG_SMINSAMPLEVALUE:
-            *va_arg(ap, double*) = td->td_sminsamplevalue;
-            break;
-	case TIFFTAG_SMAXSAMPLEVALUE:
-            *va_arg(ap, double*) = td->td_smaxsamplevalue;
-            break;
-	case TIFFTAG_XRESOLUTION:
-            *va_arg(ap, float*) = td->td_xresolution;
-            break;
-	case TIFFTAG_YRESOLUTION:
-            *va_arg(ap, float*) = td->td_yresolution;
-            break;
-	case TIFFTAG_PLANARCONFIG:
-            *va_arg(ap, uint16*) = td->td_planarconfig;
-            break;
-	case TIFFTAG_XPOSITION:
-            *va_arg(ap, float*) = td->td_xposition;
-            break;
-	case TIFFTAG_YPOSITION:
-            *va_arg(ap, float*) = td->td_yposition;
-            break;
-	case TIFFTAG_RESOLUTIONUNIT:
-            *va_arg(ap, uint16*) = td->td_resolutionunit;
-            break;
-	case TIFFTAG_PAGENUMBER:
-            *va_arg(ap, uint16*) = td->td_pagenumber[0];
-            *va_arg(ap, uint16*) = td->td_pagenumber[1];
-            break;
-	case TIFFTAG_HALFTONEHINTS:
-            *va_arg(ap, uint16*) = td->td_halftonehints[0];
-            *va_arg(ap, uint16*) = td->td_halftonehints[1];
-            break;
-	case TIFFTAG_COLORMAP:
-            *va_arg(ap, uint16**) = td->td_colormap[0];
-            *va_arg(ap, uint16**) = td->td_colormap[1];
-            *va_arg(ap, uint16**) = td->td_colormap[2];
-            break;
-	case TIFFTAG_STRIPOFFSETS:
-	case TIFFTAG_TILEOFFSETS:
-            *va_arg(ap, uint32**) = td->td_stripoffset;
-            break;
-	case TIFFTAG_STRIPBYTECOUNTS:
-	case TIFFTAG_TILEBYTECOUNTS:
-            *va_arg(ap, uint32**) = td->td_stripbytecount;
-            break;
-	case TIFFTAG_MATTEING:
-            *va_arg(ap, uint16*) =
-                (td->td_extrasamples == 1 &&
-                 td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
-            break;
-	case TIFFTAG_EXTRASAMPLES:
-            *va_arg(ap, uint16*) = td->td_extrasamples;
-            *va_arg(ap, uint16**) = td->td_sampleinfo;
-            break;
-	case TIFFTAG_TILEWIDTH:
-            *va_arg(ap, uint32*) = td->td_tilewidth;
-            break;
-	case TIFFTAG_TILELENGTH:
-            *va_arg(ap, uint32*) = td->td_tilelength;
-            break;
-	case TIFFTAG_TILEDEPTH:
-            *va_arg(ap, uint32*) = td->td_tiledepth;
-            break;
-	case TIFFTAG_DATATYPE:
-            switch (td->td_sampleformat) {
-		case SAMPLEFORMAT_UINT:
-                    *va_arg(ap, uint16*) = DATATYPE_UINT;
-                    break;
-		case SAMPLEFORMAT_INT:
-                    *va_arg(ap, uint16*) = DATATYPE_INT;
-                    break;
-		case SAMPLEFORMAT_IEEEFP:
-                    *va_arg(ap, uint16*) = DATATYPE_IEEEFP;
-                    break;
-		case SAMPLEFORMAT_VOID:
-                    *va_arg(ap, uint16*) = DATATYPE_VOID;
-                    break;
-            }
-            break;
-	case TIFFTAG_SAMPLEFORMAT:
-            *va_arg(ap, uint16*) = td->td_sampleformat;
-            break;
-	case TIFFTAG_IMAGEDEPTH:
-            *va_arg(ap, uint32*) = td->td_imagedepth;
-            break;
-	case TIFFTAG_SUBIFD:
-            *va_arg(ap, uint16*) = td->td_nsubifd;
-            *va_arg(ap, uint32**) = td->td_subifd;
-            break;
-	case TIFFTAG_YCBCRPOSITIONING:
-            *va_arg(ap, uint16*) = td->td_ycbcrpositioning;
-            break;
-	case TIFFTAG_YCBCRSUBSAMPLING:
-            *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[0];
-            *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[1];
-            break;
-	case TIFFTAG_TRANSFERFUNCTION:
-            *va_arg(ap, uint16**) = td->td_transferfunction[0];
-            if (td->td_samplesperpixel - td->td_extrasamples > 1) {
-                *va_arg(ap, uint16**) = td->td_transferfunction[1];
-                *va_arg(ap, uint16**) = td->td_transferfunction[2];
-            }
-            break;
-	case TIFFTAG_REFERENCEBLACKWHITE:
-	    *va_arg(ap, float**) = td->td_refblackwhite;
-	    break;
-	case TIFFTAG_INKNAMES:
-            *va_arg(ap, char**) = td->td_inknames;
-            break;
-        default:
-        {
-            const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY);
-            int           i;
-            
-            /*
-	     * This can happen if multiple images are open with different
-	     * codecs which have private tags.  The global tag information
-	     * table may then have tags that are valid for one file but not
-	     * the other. If the client tries to get a tag that is not valid
-	     * for the image's codec then we'll arrive here.
-             */
-            if( fip == NULL || fip->field_bit != FIELD_CUSTOM )
-            {
-		    TIFFErrorExt(tif->tif_clientdata, "_TIFFVGetField",
-				 "%s: Invalid %stag \"%s\" "
-				 "(not supported by codec)",
-				 tif->tif_name,
-				 isPseudoTag(tag) ? "pseudo-" : "",
-				 fip ? fip->field_name : "Unknown");
-		    ret_val = 0;
-		    break;
-            }
-
-            /*
-	     * Do we have a custom value?
-	     */
-            ret_val = 0;
-            for (i = 0; i < td->td_customValueCount; i++) {
-		TIFFTagValue *tv = td->td_customValues + i;
-
-		if (tv->info->field_tag != tag)
-			continue;
-                
-		if (fip->field_passcount) {
-			if (fip->field_readcount == TIFF_VARIABLE2) 
-				*va_arg(ap, uint32*) = (uint32)tv->count;
-			else	/* Assume TIFF_VARIABLE */
-				*va_arg(ap, uint16*) = (uint16)tv->count;
-			*va_arg(ap, void **) = tv->value;
-			ret_val = 1;
-                } else {
-			if ((fip->field_type == TIFF_ASCII
-			    || fip->field_readcount == TIFF_VARIABLE
-			    || fip->field_readcount == TIFF_VARIABLE2
-			    || fip->field_readcount == TIFF_SPP
-			    || tv->count > 1)
-			    && fip->field_tag != TIFFTAG_PAGENUMBER
-			    && fip->field_tag != TIFFTAG_HALFTONEHINTS
-			    && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING
-			    && fip->field_tag != TIFFTAG_DOTRANGE) {
-				*va_arg(ap, void **) = tv->value;
-				ret_val = 1;
-			} else {
-			    int j;
-			    char *val = (char *)tv->value;
-
-			    for (j = 0; j < tv->count;
-				 j++, val += _TIFFDataSize(tv->info->field_type)) {
-				switch (fip->field_type) {
-					case TIFF_BYTE:
-					case TIFF_UNDEFINED:
-						*va_arg(ap, uint8*) =
-							*(uint8 *)val;
-						ret_val = 1;
-						break;
-					case TIFF_SBYTE:
-						*va_arg(ap, int8*) =
-							*(int8 *)val;
-						ret_val = 1;
-						break;
-					case TIFF_SHORT:
-						*va_arg(ap, uint16*) =
-							*(uint16 *)val;
-						ret_val = 1;
-						break;
-					case TIFF_SSHORT:
-						*va_arg(ap, int16*) =
-							*(int16 *)val;
-						ret_val = 1;
-						break;
-					case TIFF_LONG:
-					case TIFF_IFD:
-						*va_arg(ap, uint32*) =
-							*(uint32 *)val;
-						ret_val = 1;
-						break;
-					case TIFF_SLONG:
-						*va_arg(ap, int32*) =
-							*(int32 *)val;
-						ret_val = 1;
-						break;
-					case TIFF_RATIONAL:
-					case TIFF_SRATIONAL:
-					case TIFF_FLOAT:
-						*va_arg(ap, float*) =
-							*(float *)val;
-						ret_val = 1;
-						break;
-					case TIFF_DOUBLE:
-						*va_arg(ap, double*) =
-							*(double *)val;
-						ret_val = 1;
-						break;
-					default:
-						ret_val = 0;
-						break;
-				}
-			    }
-			}
-                }
-		break;
-            }
-        }
-    }
-    return(ret_val);
-}
-
-/*
- * Return the value of a field in the
- * internal directory structure.
- */
-int
-TIFFGetField(TIFF* tif, ttag_t tag, ...)
-{
-	int status;
-	va_list ap;
-
-	va_start(ap, tag);
-	status = TIFFVGetField(tif, tag, ap);
-	va_end(ap);
-	return (status);
-}
-
-/*
- * Like TIFFGetField, but taking a varargs
- * parameter list.  This routine is useful
- * for building higher-level interfaces on
- * top of the library.
- */
-int
-TIFFVGetField(TIFF* tif, ttag_t tag, va_list ap)
-{
-	const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY);
-	return (fip && (isPseudoTag(tag) || TIFFFieldSet(tif, fip->field_bit)) ?
-	    (*tif->tif_tagmethods.vgetfield)(tif, tag, ap) : 0);
-}
-
-#define	CleanupField(member) {		\
-    if (td->member) {			\
-	_TIFFfree(td->member);		\
-	td->member = 0;			\
-    }					\
-}
-
-/*
- * Release storage associated with a directory.
- */
-void
-TIFFFreeDirectory(TIFF* tif)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-	int            i;
-
-	_TIFFmemset(td->td_fieldsset, 0, FIELD_SETLONGS);
-	CleanupField(td_colormap[0]);
-	CleanupField(td_colormap[1]);
-	CleanupField(td_colormap[2]);
-	CleanupField(td_sampleinfo);
-	CleanupField(td_subifd);
-	CleanupField(td_inknames);
-	CleanupField(td_refblackwhite);
-	CleanupField(td_transferfunction[0]);
-	CleanupField(td_transferfunction[1]);
-	CleanupField(td_transferfunction[2]);
-	CleanupField(td_stripoffset);
-	CleanupField(td_stripbytecount);
-	TIFFClrFieldBit(tif, FIELD_YCBCRSUBSAMPLING);
-	TIFFClrFieldBit(tif, FIELD_YCBCRPOSITIONING);
-
-	/* Cleanup custom tag values */
-	for( i = 0; i < td->td_customValueCount; i++ ) {
-		if (td->td_customValues[i].value)
-			_TIFFfree(td->td_customValues[i].value);
-	}
-
-	td->td_customValueCount = 0;
-	CleanupField(td_customValues);
-}
-#undef CleanupField
-
-/*
- * Client Tag extension support (from Niles Ritter).
- */
-static TIFFExtendProc _TIFFextender = (TIFFExtendProc) NULL;
-
-TIFFExtendProc
-TIFFSetTagExtender(TIFFExtendProc extender)
-{
-	TIFFExtendProc prev = _TIFFextender;
-	_TIFFextender = extender;
-	return (prev);
-}
-
-/*
- * Setup for a new directory.  Should we automatically call
- * TIFFWriteDirectory() if the current one is dirty?
- *
- * The newly created directory will not exist on the file till
- * TIFFWriteDirectory(), TIFFFlush() or TIFFClose() is called.
- */
-int
-TIFFCreateDirectory(TIFF* tif)
-{
-    TIFFDefaultDirectory(tif);
-    tif->tif_diroff = 0;
-    tif->tif_nextdiroff = 0;
-    tif->tif_curoff = 0;
-    tif->tif_row = (uint32) -1;
-    tif->tif_curstrip = (tstrip_t) -1;
-
-    return 0;
-}
-
-/*
- * Setup a default directory structure.
- */
-int
-TIFFDefaultDirectory(TIFF* tif)
-{
-	register TIFFDirectory* td = &tif->tif_dir;
-
-	size_t tiffFieldInfoCount;
-	const TIFFFieldInfo *tiffFieldInfo =
-	    _TIFFGetFieldInfo(&tiffFieldInfoCount);
-	_TIFFSetupFieldInfo(tif, tiffFieldInfo, tiffFieldInfoCount);
-
-	_TIFFmemset(td, 0, sizeof (*td));
-	td->td_fillorder = FILLORDER_MSB2LSB;
-	td->td_bitspersample = 1;
-	td->td_threshholding = THRESHHOLD_BILEVEL;
-	td->td_orientation = ORIENTATION_TOPLEFT;
-	td->td_samplesperpixel = 1;
-	td->td_rowsperstrip = (uint32) -1;
-	td->td_tilewidth = 0;
-	td->td_tilelength = 0;
-	td->td_tiledepth = 1;
-	td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */
-	td->td_resolutionunit = RESUNIT_INCH;
-	td->td_sampleformat = SAMPLEFORMAT_UINT;
-	td->td_imagedepth = 1;
-	td->td_ycbcrsubsampling[0] = 2;
-	td->td_ycbcrsubsampling[1] = 2;
-	td->td_ycbcrpositioning = YCBCRPOSITION_CENTERED;
-	tif->tif_postdecode = _TIFFNoPostDecode;
-	tif->tif_foundfield = NULL;
-	tif->tif_tagmethods.vsetfield = _TIFFVSetField;
-	tif->tif_tagmethods.vgetfield = _TIFFVGetField;
-	tif->tif_tagmethods.printdir = NULL;
-	/*
-	 *  Give client code a chance to install their own
-	 *  tag extensions & methods, prior to compression overloads.
-	 */
-	if (_TIFFextender)
-		(*_TIFFextender)(tif);
-	(void) TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
-	/*
-	 * NB: The directory is marked dirty as a result of setting
-	 * up the default compression scheme.  However, this really
-	 * isn't correct -- we want TIFF_DIRTYDIRECT to be set only
-	 * if the user does something.  We could just do the setup
-	 * by hand, but it seems better to use the normal mechanism
-	 * (i.e. TIFFSetField).
-	 */
-	tif->tif_flags &= ~TIFF_DIRTYDIRECT;
-
-	/*
-	 * As per http://bugzilla.remotesensing.org/show_bug.cgi?id=19
-	 * we clear the ISTILED flag when setting up a new directory.
-	 * Should we also be clearing stuff like INSUBIFD?
-	 */
-	tif->tif_flags &= ~TIFF_ISTILED;
-        /*
-         * Clear other directory-specific fields.
-         */
-        tif->tif_tilesize = -1;
-        tif->tif_scanlinesize = -1;
-
-	return (1);
-}
-
-static int
-TIFFAdvanceDirectory(TIFF* tif, uint32* nextdir, toff_t* off)
-{
-	static const char module[] = "TIFFAdvanceDirectory";
-	uint16 dircount;
-	if (isMapped(tif))
-	{
-		toff_t poff=*nextdir;
-		if (poff+sizeof(uint16) > tif->tif_size)
-		{
-			TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count",
-			    tif->tif_name);
-			return (0);
-		}
-		_TIFFmemcpy(&dircount, tif->tif_base+poff, sizeof (uint16));
-		if (tif->tif_flags & TIFF_SWAB)
-			TIFFSwabShort(&dircount);
-		poff+=sizeof (uint16)+dircount*sizeof (TIFFDirEntry);
-		if (off != NULL)
-			*off = poff;
-		if (((toff_t) (poff+sizeof (uint32))) > tif->tif_size)
-		{
-			TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory link",
-			    tif->tif_name);
-			return (0);
-		}
-		_TIFFmemcpy(nextdir, tif->tif_base+poff, sizeof (uint32));
-		if (tif->tif_flags & TIFF_SWAB)
-			TIFFSwabLong(nextdir);
-		return (1);
-	}
-	else
-	{
-		if (!SeekOK(tif, *nextdir) ||
-		    !ReadOK(tif, &dircount, sizeof (uint16))) {
-			TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count",
-			    tif->tif_name);
-			return (0);
-		}
-		if (tif->tif_flags & TIFF_SWAB)
-			TIFFSwabShort(&dircount);
-		if (off != NULL)
-			*off = TIFFSeekFile(tif,
-			    dircount*sizeof (TIFFDirEntry), SEEK_CUR);
-		else
-			(void) TIFFSeekFile(tif,
-			    dircount*sizeof (TIFFDirEntry), SEEK_CUR);
-		if (!ReadOK(tif, nextdir, sizeof (uint32))) {
-			TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory link",
-			    tif->tif_name);
-			return (0);
-		}
-		if (tif->tif_flags & TIFF_SWAB)
-			TIFFSwabLong(nextdir);
-		return (1);
-	}
-}
-
-/*
- * Count the number of directories in a file.
- */
-tdir_t
-TIFFNumberOfDirectories(TIFF* tif)
-{
-    toff_t nextdir = tif->tif_header.tiff_diroff;
-    tdir_t n = 0;
-    
-    while (nextdir != 0 && TIFFAdvanceDirectory(tif, &nextdir, NULL))
-        n++;
-    return (n);
-}
-
-/*
- * Set the n-th directory as the current directory.
- * NB: Directories are numbered starting at 0.
- */
-int
-TIFFSetDirectory(TIFF* tif, tdir_t dirn)
-{
-	toff_t nextdir;
-	tdir_t n;
-
-	nextdir = tif->tif_header.tiff_diroff;
-	for (n = dirn; n > 0 && nextdir != 0; n--)
-		if (!TIFFAdvanceDirectory(tif, &nextdir, NULL))
-			return (0);
-	tif->tif_nextdiroff = nextdir;
-	/*
-	 * Set curdir to the actual directory index.  The
-	 * -1 is because TIFFReadDirectory will increment
-	 * tif_curdir after successfully reading the directory.
-	 */
-	tif->tif_curdir = (dirn - n) - 1;
-	/*
-	 * Reset tif_dirnumber counter and start new list of seen directories.
-	 * We need this to prevent IFD loops.
-	 */
-	tif->tif_dirnumber = 0;
-	return (TIFFReadDirectory(tif));
-}
-
-/*
- * Set the current directory to be the directory
- * located at the specified file offset.  This interface
- * is used mainly to access directories linked with
- * the SubIFD tag (e.g. thumbnail images).
- */
-int
-TIFFSetSubDirectory(TIFF* tif, uint32 diroff)
-{
-	tif->tif_nextdiroff = diroff;
-	/*
-	 * Reset tif_dirnumber counter and start new list of seen directories.
-	 * We need this to prevent IFD loops.
-	 */
-	tif->tif_dirnumber = 0;
-	return (TIFFReadDirectory(tif));
-}
-
-/*
- * Return file offset of the current directory.
- */
-uint32
-TIFFCurrentDirOffset(TIFF* tif)
-{
-	return (tif->tif_diroff);
-}
-
-/*
- * Return an indication of whether or not we are
- * at the last directory in the file.
- */
-int
-TIFFLastDirectory(TIFF* tif)
-{
-	return (tif->tif_nextdiroff == 0);
-}
-
-/*
- * Unlink the specified directory from the directory chain.
- */
-int
-TIFFUnlinkDirectory(TIFF* tif, tdir_t dirn)
-{
-	static const char module[] = "TIFFUnlinkDirectory";
-	toff_t nextdir;
-	toff_t off;
-	tdir_t n;
-
-	if (tif->tif_mode == O_RDONLY) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-                             "Can not unlink directory in read-only file");
-		return (0);
-	}
-	/*
-	 * Go to the directory before the one we want
-	 * to unlink and nab the offset of the link
-	 * field we'll need to patch.
-	 */
-	nextdir = tif->tif_header.tiff_diroff;
-	off = sizeof (uint16) + sizeof (uint16);
-	for (n = dirn-1; n > 0; n--) {
-		if (nextdir == 0) {
-			TIFFErrorExt(tif->tif_clientdata, module, "Directory %d does not exist", dirn);
-			return (0);
-		}
-		if (!TIFFAdvanceDirectory(tif, &nextdir, &off))
-			return (0);
-	}
-	/*
-	 * Advance to the directory to be unlinked and fetch
-	 * the offset of the directory that follows.
-	 */
-	if (!TIFFAdvanceDirectory(tif, &nextdir, NULL))
-		return (0);
-	/*
-	 * Go back and patch the link field of the preceding
-	 * directory to point to the offset of the directory
-	 * that follows.
-	 */
-	(void) TIFFSeekFile(tif, off, SEEK_SET);
-	if (tif->tif_flags & TIFF_SWAB)
-		TIFFSwabLong(&nextdir);
-	if (!WriteOK(tif, &nextdir, sizeof (uint32))) {
-		TIFFErrorExt(tif->tif_clientdata, module, "Error writing directory link");
-		return (0);
-	}
-	/*
-	 * Leave directory state setup safely.  We don't have
-	 * facilities for doing inserting and removing directories,
-	 * so it's safest to just invalidate everything.  This
-	 * means that the caller can only append to the directory
-	 * chain.
-	 */
-	(*tif->tif_cleanup)(tif);
-	if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
-		_TIFFfree(tif->tif_rawdata);
-		tif->tif_rawdata = NULL;
-		tif->tif_rawcc = 0;
-	}
-	tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP|TIFF_POSTENCODE);
-	TIFFFreeDirectory(tif);
-	TIFFDefaultDirectory(tif);
-	tif->tif_diroff = 0;			/* force link on next write */
-	tif->tif_nextdiroff = 0;		/* next write must be at end */
-	tif->tif_curoff = 0;
-	tif->tif_row = (uint32) -1;
-	tif->tif_curstrip = (tstrip_t) -1;
-	return (1);
-}
-
-/*			[BFC]
- *
- * Author: Bruce Cameron <cameron at petris.com>
- *
- * Set a table of tags that are to be replaced during directory process by the
- * 'IGNORE' state - or return TRUE/FALSE for the requested tag such that
- * 'ReadDirectory' can use the stored information.
- *
- * FIXME: this is never used properly. Should be removed in the future.
- */
-int
-TIFFReassignTagToIgnore (enum TIFFIgnoreSense task, int TIFFtagID)
-{
-    static int TIFFignoretags [FIELD_LAST];
-    static int tagcount = 0 ;
-    int		i;					/* Loop index */
-    int		j;					/* Loop index */
-
-    switch (task)
-    {
-      case TIS_STORE:
-        if ( tagcount < (FIELD_LAST - 1) )
-        {
-            for ( j = 0 ; j < tagcount ; ++j )
-            {					/* Do not add duplicate tag */
-                if ( TIFFignoretags [j] == TIFFtagID )
-                    return (TRUE) ;
-            }
-            TIFFignoretags [tagcount++] = TIFFtagID ;
-            return (TRUE) ;
-        }
-        break ;
-        
-      case TIS_EXTRACT:
-        for ( i = 0 ; i < tagcount ; ++i )
-        {
-            if ( TIFFignoretags [i] == TIFFtagID )
-                return (TRUE) ;
-        }
-        break;
-        
-      case TIS_EMPTY:
-        tagcount = 0 ;			/* Clear the list */
-        return (TRUE) ;
-        
-      default:
-        break;
-    }
-    
-    return (FALSE);
-}
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_dir.h b/Source/LibTIFF/tif_dir.h
deleted file mode 100644
index 69b3554..0000000
--- a/Source/LibTIFF/tif_dir.h
+++ /dev/null
@@ -1,211 +0,0 @@
-/* $Id: tif_dir.h,v 1.37 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-#ifndef _TIFFDIR_
-#define	_TIFFDIR_
-/*
- * ``Library-private'' Directory-related Definitions.
- */
-
-/*
- * Internal format of a TIFF directory entry.
- */
-typedef	struct {
-#define	FIELD_SETLONGS	4
-	/* bit vector of fields that are set */
-	unsigned long	td_fieldsset[FIELD_SETLONGS];
-
-	uint32  td_imagewidth, td_imagelength, td_imagedepth;
-	uint32  td_tilewidth, td_tilelength, td_tiledepth;
-	uint32  td_subfiletype;
-	uint16  td_bitspersample;
-	uint16  td_sampleformat;
-	uint16  td_compression;
-	uint16  td_photometric;
-	uint16  td_threshholding;
-	uint16  td_fillorder;
-	uint16  td_orientation;
-	uint16  td_samplesperpixel;
-	uint32  td_rowsperstrip;
-	uint16  td_minsamplevalue, td_maxsamplevalue;
-	double  td_sminsamplevalue, td_smaxsamplevalue;
-	float   td_xresolution, td_yresolution;
-	uint16  td_resolutionunit;
-	uint16  td_planarconfig;
-	float   td_xposition, td_yposition;
-	uint16  td_pagenumber[2];
-	uint16* td_colormap[3];
-	uint16  td_halftonehints[2];
-	uint16  td_extrasamples;
-	uint16* td_sampleinfo;
-	/* even though the name is misleading, td_stripsperimage is the number
-	 * of striles (=strips or tiles) per plane, and td_nstrips the total
-	 * number of striles */
-	tstrile_t td_stripsperimage;
-	tstrile_t td_nstrips;            /* size of offset & bytecount arrays */
-	toff_t* td_stripoffset;
-	toff_t* td_stripbytecount;	 /* FIXME: it should be tsize_t array */
-	int     td_stripbytecountsorted; /* is the bytecount array sorted ascending? */
-	uint16  td_nsubifd;
-	uint32* td_subifd;
-	/* YCbCr parameters */
-	uint16  td_ycbcrsubsampling[2];
-	uint16  td_ycbcrpositioning;
-	/* Colorimetry parameters */
-	float*	td_refblackwhite;
-	uint16* td_transferfunction[3];
-	/* CMYK parameters */
-	int     td_inknameslen;
-	char*   td_inknames;
-
-	int     td_customValueCount;
-        TIFFTagValue *td_customValues;
-} TIFFDirectory;
-
-/*
- * Field flags used to indicate fields that have
- * been set in a directory, and to reference fields
- * when manipulating a directory.
- */
-
-/*
- * FIELD_IGNORE is used to signify tags that are to
- * be processed but otherwise ignored.  This permits
- * antiquated tags to be quietly read and discarded.
- * Note that a bit *is* allocated for ignored tags;
- * this is understood by the directory reading logic
- * which uses this fact to avoid special-case handling
- */ 
-#define	FIELD_IGNORE			0
-
-/* multi-item fields */
-#define	FIELD_IMAGEDIMENSIONS		1
-#define FIELD_TILEDIMENSIONS		2
-#define	FIELD_RESOLUTION		3
-#define	FIELD_POSITION			4
-
-/* single-item fields */
-#define	FIELD_SUBFILETYPE		5
-#define	FIELD_BITSPERSAMPLE		6
-#define	FIELD_COMPRESSION		7
-#define	FIELD_PHOTOMETRIC		8
-#define	FIELD_THRESHHOLDING		9
-#define	FIELD_FILLORDER			10
-#define	FIELD_ORIENTATION		15
-#define	FIELD_SAMPLESPERPIXEL		16
-#define	FIELD_ROWSPERSTRIP		17
-#define	FIELD_MINSAMPLEVALUE		18
-#define	FIELD_MAXSAMPLEVALUE		19
-#define	FIELD_PLANARCONFIG		20
-#define	FIELD_RESOLUTIONUNIT		22
-#define	FIELD_PAGENUMBER		23
-#define	FIELD_STRIPBYTECOUNTS		24
-#define	FIELD_STRIPOFFSETS		25
-#define	FIELD_COLORMAP			26
-#define	FIELD_EXTRASAMPLES		31
-#define FIELD_SAMPLEFORMAT		32
-#define	FIELD_SMINSAMPLEVALUE		33
-#define	FIELD_SMAXSAMPLEVALUE		34
-#define FIELD_IMAGEDEPTH		35
-#define FIELD_TILEDEPTH			36
-#define	FIELD_HALFTONEHINTS		37
-#define FIELD_YCBCRSUBSAMPLING		39
-#define FIELD_YCBCRPOSITIONING		40
-#define	FIELD_REFBLACKWHITE		41
-#define	FIELD_TRANSFERFUNCTION		44
-#define	FIELD_INKNAMES			46
-#define	FIELD_SUBIFD			49
-/*      FIELD_CUSTOM (see tiffio.h)     65 */
-/* end of support for well-known tags; codec-private tags follow */
-#define	FIELD_CODEC			66	/* base of codec-private tags */
-
-
-/*
- * Pseudo-tags don't normally need field bits since they
- * are not written to an output file (by definition).
- * The library also has express logic to always query a
- * codec for a pseudo-tag so allocating a field bit for
- * one is a waste.   If codec wants to promote the notion
- * of a pseudo-tag being ``set'' or ``unset'' then it can
- * do using internal state flags without polluting the
- * field bit space defined for real tags.
- */
-#define	FIELD_PSEUDO			0
-
-#define	FIELD_LAST			(32*FIELD_SETLONGS-1)
-
-#define	TIFFExtractData(tif, type, v) \
-    ((uint32) ((tif)->tif_header.tiff_magic == TIFF_BIGENDIAN ? \
-        ((v) >> (tif)->tif_typeshift[type]) & (tif)->tif_typemask[type] : \
-	(v) & (tif)->tif_typemask[type]))
-#define	TIFFInsertData(tif, type, v) \
-    ((uint32) ((tif)->tif_header.tiff_magic == TIFF_BIGENDIAN ? \
-        ((v) & (tif)->tif_typemask[type]) << (tif)->tif_typeshift[type] : \
-	(v) & (tif)->tif_typemask[type]))
-
-
-#define BITn(n)				(((unsigned long)1L)<<((n)&0x1f)) 
-#define BITFIELDn(tif, n)		((tif)->tif_dir.td_fieldsset[(n)/32]) 
-#define TIFFFieldSet(tif, field)	(BITFIELDn(tif, field) & BITn(field)) 
-#define TIFFSetFieldBit(tif, field)	(BITFIELDn(tif, field) |= BITn(field))
-#define TIFFClrFieldBit(tif, field)	(BITFIELDn(tif, field) &= ~BITn(field))
-
-#define	FieldSet(fields, f)		(fields[(f)/32] & BITn(f))
-#define	ResetFieldBit(fields, f)	(fields[(f)/32] &= ~BITn(f))
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-extern	const TIFFFieldInfo *_TIFFGetFieldInfo(size_t *);
-extern	const TIFFFieldInfo *_TIFFGetExifFieldInfo(size_t *);
-extern	void _TIFFSetupFieldInfo(TIFF*, const TIFFFieldInfo[], size_t);
-extern	int _TIFFMergeFieldInfo(TIFF*, const TIFFFieldInfo[], int);
-extern	void _TIFFPrintFieldInfo(TIFF*, FILE*);
-extern	TIFFDataType _TIFFSampleToTagType(TIFF*);
-extern  const TIFFFieldInfo* _TIFFFindOrRegisterFieldInfo( TIFF *tif,
-							   ttag_t tag,
-							   TIFFDataType dt );
-extern  TIFFFieldInfo* _TIFFCreateAnonFieldInfo( TIFF *tif, ttag_t tag,
-                                                 TIFFDataType dt );
-
-#define _TIFFFindFieldInfo	    TIFFFindFieldInfo
-#define _TIFFFindFieldInfoByName    TIFFFindFieldInfoByName
-#define _TIFFFieldWithTag	    TIFFFieldWithTag
-#define _TIFFFieldWithName	    TIFFFieldWithName
-
-#if defined(__cplusplus)
-}
-#endif
-#endif /* _TIFFDIR_ */
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_dirinfo.c b/Source/LibTIFF/tif_dirinfo.c
deleted file mode 100644
index 0df1126..0000000
--- a/Source/LibTIFF/tif_dirinfo.c
+++ /dev/null
@@ -1,884 +0,0 @@
-/* $Id: tif_dirinfo.c,v 1.38 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library.
- *
- * Core Directory Tag Support.
- */
-#include "tiffiop.h"
-#include <stdlib.h>
-#include <string.h>
-
-/*
- * NB: NB: THIS ARRAY IS ASSUMED TO BE SORTED BY TAG.
- *       If a tag can have both LONG and SHORT types then the LONG must be
- *       placed before the SHORT for writing to work properly.
- *
- * NOTE: The second field (field_readcount) and third field (field_writecount)
- *       sometimes use the values TIFF_VARIABLE (-1), TIFF_VARIABLE2 (-3)
- *       and TIFFTAG_SPP (-2). The macros should be used but would throw off 
- *       the formatting of the code, so please interprete the -1, -2 and -3 
- *       values accordingly.
- */
-static const TIFFFieldInfo
-tiffFieldInfo[] = {
-    { TIFFTAG_SUBFILETYPE,	 1, 1,	TIFF_LONG,	FIELD_SUBFILETYPE,
-      1,	0,	"SubfileType" },
-/* XXX SHORT for compatibility w/ old versions of the library */
-    { TIFFTAG_SUBFILETYPE,	 1, 1,	TIFF_SHORT,	FIELD_SUBFILETYPE,
-      1,	0,	"SubfileType" },
-    { TIFFTAG_OSUBFILETYPE,	 1, 1,	TIFF_SHORT,	FIELD_SUBFILETYPE,
-      1,	0,	"OldSubfileType" },
-    { TIFFTAG_IMAGEWIDTH,	 1, 1,	TIFF_LONG,	FIELD_IMAGEDIMENSIONS,
-      0,	0,	"ImageWidth" },
-    { TIFFTAG_IMAGEWIDTH,	 1, 1,	TIFF_SHORT,	FIELD_IMAGEDIMENSIONS,
-      0,	0,	"ImageWidth" },
-    { TIFFTAG_IMAGELENGTH,	 1, 1,	TIFF_LONG,	FIELD_IMAGEDIMENSIONS,
-      1,	0,	"ImageLength" },
-    { TIFFTAG_IMAGELENGTH,	 1, 1,	TIFF_SHORT,	FIELD_IMAGEDIMENSIONS,
-      1,	0,	"ImageLength" },
-    { TIFFTAG_BITSPERSAMPLE,	-1,-1,	TIFF_SHORT,	FIELD_BITSPERSAMPLE,
-      0,	0,	"BitsPerSample" },
-/* XXX LONG for compatibility with some broken TIFF writers */
-    { TIFFTAG_BITSPERSAMPLE,	-1,-1,	TIFF_LONG,	FIELD_BITSPERSAMPLE,
-      0,	0,	"BitsPerSample" },
-    { TIFFTAG_COMPRESSION,	-1, 1,	TIFF_SHORT,	FIELD_COMPRESSION,
-      0,	0,	"Compression" },
-/* XXX LONG for compatibility with some broken TIFF writers */
-    { TIFFTAG_COMPRESSION,	-1, 1,	TIFF_LONG,	FIELD_COMPRESSION,
-      0,	0,	"Compression" },
-    { TIFFTAG_PHOTOMETRIC,	 1, 1,	TIFF_SHORT,	FIELD_PHOTOMETRIC,
-      0,	0,	"PhotometricInterpretation" },
-/* XXX LONG for compatibility with some broken TIFF writers */
-    { TIFFTAG_PHOTOMETRIC,	 1, 1,	TIFF_LONG,	FIELD_PHOTOMETRIC,
-      0,	0,	"PhotometricInterpretation" },
-    { TIFFTAG_THRESHHOLDING,	 1, 1,	TIFF_SHORT,	FIELD_THRESHHOLDING,
-      1,	0,	"Threshholding" },
-    { TIFFTAG_CELLWIDTH,	 1, 1,	TIFF_SHORT,	FIELD_IGNORE,
-      1,	0,	"CellWidth" },
-    { TIFFTAG_CELLLENGTH,	 1, 1,	TIFF_SHORT,	FIELD_IGNORE,
-      1,	0,	"CellLength" },
-    { TIFFTAG_FILLORDER,	 1, 1,	TIFF_SHORT,	FIELD_FILLORDER,
-      0,	0,	"FillOrder" },
-    { TIFFTAG_DOCUMENTNAME,	-1,-1,	TIFF_ASCII,	FIELD_CUSTOM,
-      1,	0,	"DocumentName" },
-    { TIFFTAG_IMAGEDESCRIPTION,	-1,-1,	TIFF_ASCII,	FIELD_CUSTOM,
-      1,	0,	"ImageDescription" },
-    { TIFFTAG_MAKE,		-1,-1,	TIFF_ASCII,	FIELD_CUSTOM,
-      1,	0,	"Make" },
-    { TIFFTAG_MODEL,		-1,-1,	TIFF_ASCII,	FIELD_CUSTOM,
-      1,	0,	"Model" },
-    { TIFFTAG_STRIPOFFSETS,	-1,-1,	TIFF_LONG,	FIELD_STRIPOFFSETS,
-      0,	0,	"StripOffsets" },
-    { TIFFTAG_STRIPOFFSETS,	-1,-1,	TIFF_SHORT,	FIELD_STRIPOFFSETS,
-      0,	0,	"StripOffsets" },
-    { TIFFTAG_ORIENTATION,	 1, 1,	TIFF_SHORT,	FIELD_ORIENTATION,
-      0,	0,	"Orientation" },
-    { TIFFTAG_SAMPLESPERPIXEL,	 1, 1,	TIFF_SHORT,	FIELD_SAMPLESPERPIXEL,
-      0,	0,	"SamplesPerPixel" },
-    { TIFFTAG_ROWSPERSTRIP,	 1, 1,	TIFF_LONG,	FIELD_ROWSPERSTRIP,
-      0,	0,	"RowsPerStrip" },
-    { TIFFTAG_ROWSPERSTRIP,	 1, 1,	TIFF_SHORT,	FIELD_ROWSPERSTRIP,
-      0,	0,	"RowsPerStrip" },
-    { TIFFTAG_STRIPBYTECOUNTS,	-1,-1,	TIFF_LONG,	FIELD_STRIPBYTECOUNTS,
-      0,	0,	"StripByteCounts" },
-    { TIFFTAG_STRIPBYTECOUNTS,	-1,-1,	TIFF_SHORT,	FIELD_STRIPBYTECOUNTS,
-      0,	0,	"StripByteCounts" },
-    { TIFFTAG_MINSAMPLEVALUE,	-2,-1,	TIFF_SHORT,	FIELD_MINSAMPLEVALUE,
-      1,	0,	"MinSampleValue" },
-    { TIFFTAG_MAXSAMPLEVALUE,	-2,-1,	TIFF_SHORT,	FIELD_MAXSAMPLEVALUE,
-      1,	0,	"MaxSampleValue" },
-    { TIFFTAG_XRESOLUTION,	 1, 1,	TIFF_RATIONAL,	FIELD_RESOLUTION,
-      1,	0,	"XResolution" },
-    { TIFFTAG_YRESOLUTION,	 1, 1,	TIFF_RATIONAL,	FIELD_RESOLUTION,
-      1,	0,	"YResolution" },
-    { TIFFTAG_PLANARCONFIG,	 1, 1,	TIFF_SHORT,	FIELD_PLANARCONFIG,
-      0,	0,	"PlanarConfiguration" },
-    { TIFFTAG_PAGENAME,		-1,-1,	TIFF_ASCII,	FIELD_CUSTOM,
-      1,	0,	"PageName" },
-    { TIFFTAG_XPOSITION,	 1, 1,	TIFF_RATIONAL,	FIELD_POSITION,
-      1,	0,	"XPosition" },
-    { TIFFTAG_YPOSITION,	 1, 1,	TIFF_RATIONAL,	FIELD_POSITION,
-      1,	0,	"YPosition" },
-    { TIFFTAG_FREEOFFSETS,	-1,-1,	TIFF_LONG,	FIELD_IGNORE,
-      0,	0,	"FreeOffsets" },
-    { TIFFTAG_FREEBYTECOUNTS,	-1,-1,	TIFF_LONG,	FIELD_IGNORE,
-      0,	0,	"FreeByteCounts" },
-    { TIFFTAG_GRAYRESPONSEUNIT,	 1, 1,	TIFF_SHORT,	FIELD_IGNORE,
-      1,	0,	"GrayResponseUnit" },
-    { TIFFTAG_GRAYRESPONSECURVE,-1,-1,	TIFF_SHORT,	FIELD_IGNORE,
-      1,	0,	"GrayResponseCurve" },
-    { TIFFTAG_RESOLUTIONUNIT,	 1, 1,	TIFF_SHORT,	FIELD_RESOLUTIONUNIT,
-      1,	0,	"ResolutionUnit" },
-    { TIFFTAG_PAGENUMBER,	 2, 2,	TIFF_SHORT,	FIELD_PAGENUMBER,
-      1,	0,	"PageNumber" },
-    { TIFFTAG_COLORRESPONSEUNIT, 1, 1,	TIFF_SHORT,	FIELD_IGNORE,
-      1,	0,	"ColorResponseUnit" },
-    { TIFFTAG_TRANSFERFUNCTION,	-1,-1,	TIFF_SHORT,	FIELD_TRANSFERFUNCTION,
-      1,	0,	"TransferFunction" },
-    { TIFFTAG_SOFTWARE,		-1,-1,	TIFF_ASCII,	FIELD_CUSTOM,
-      1,	0,	"Software" },
-    { TIFFTAG_DATETIME,		20,20,	TIFF_ASCII,	FIELD_CUSTOM,
-      1,	0,	"DateTime" },
-    { TIFFTAG_ARTIST,		-1,-1,	TIFF_ASCII,	FIELD_CUSTOM,
-      1,	0,	"Artist" },
-    { TIFFTAG_HOSTCOMPUTER,	-1,-1,	TIFF_ASCII,	FIELD_CUSTOM,
-      1,	0,	"HostComputer" },
-    { TIFFTAG_WHITEPOINT,	 2, 2,	TIFF_RATIONAL,	FIELD_CUSTOM,
-      1,	0,	"WhitePoint" },
-    { TIFFTAG_PRIMARYCHROMATICITIES,6,6,TIFF_RATIONAL,	FIELD_CUSTOM,
-      1,	0,	"PrimaryChromaticities" },
-    { TIFFTAG_COLORMAP,		-1,-1,	TIFF_SHORT,	FIELD_COLORMAP,
-      1,	0,	"ColorMap" },
-    { TIFFTAG_HALFTONEHINTS,	 2, 2,	TIFF_SHORT,	FIELD_HALFTONEHINTS,
-      1,	0,	"HalftoneHints" },
-    { TIFFTAG_TILEWIDTH,	 1, 1,	TIFF_LONG,	FIELD_TILEDIMENSIONS,
-      0,	0,	"TileWidth" },
-    { TIFFTAG_TILEWIDTH,	 1, 1,	TIFF_SHORT,	FIELD_TILEDIMENSIONS,
-      0,	0,	"TileWidth" },
-    { TIFFTAG_TILELENGTH,	 1, 1,	TIFF_LONG,	FIELD_TILEDIMENSIONS,
-      0,	0,	"TileLength" },
-    { TIFFTAG_TILELENGTH,	 1, 1,	TIFF_SHORT,	FIELD_TILEDIMENSIONS,
-      0,	0,	"TileLength" },
-    { TIFFTAG_TILEOFFSETS,	-1, 1,	TIFF_LONG,	FIELD_STRIPOFFSETS,
-      0,	0,	"TileOffsets" },
-    { TIFFTAG_TILEBYTECOUNTS,	-1, 1,	TIFF_LONG,	FIELD_STRIPBYTECOUNTS,
-      0,	0,	"TileByteCounts" },
-    { TIFFTAG_TILEBYTECOUNTS,	-1, 1,	TIFF_SHORT,	FIELD_STRIPBYTECOUNTS,
-      0,	0,	"TileByteCounts" },
-    { TIFFTAG_SUBIFD,		-1,-1,	TIFF_IFD,	FIELD_SUBIFD,
-      1,	1,	"SubIFD" },
-    { TIFFTAG_SUBIFD,		-1,-1,	TIFF_LONG,	FIELD_SUBIFD,
-      1,	1,	"SubIFD" },
-    { TIFFTAG_INKSET,		 1, 1,	TIFF_SHORT,	FIELD_CUSTOM,
-      0,	0,	"InkSet" },
-    { TIFFTAG_INKNAMES,		-1,-1,	TIFF_ASCII,	FIELD_INKNAMES,
-      1,	1,	"InkNames" },
-    { TIFFTAG_NUMBEROFINKS,	 1, 1,	TIFF_SHORT,	FIELD_CUSTOM,
-      1,	0,	"NumberOfInks" },
-    { TIFFTAG_DOTRANGE,		 2, 2,	TIFF_SHORT,	FIELD_CUSTOM,
-      0,	0,	"DotRange" },
-    { TIFFTAG_DOTRANGE,		 2, 2,	TIFF_BYTE,	FIELD_CUSTOM,
-      0,	0,	"DotRange" },
-    { TIFFTAG_TARGETPRINTER,	-1,-1,	TIFF_ASCII,	FIELD_CUSTOM,
-      1,	0,	"TargetPrinter" },
-    { TIFFTAG_EXTRASAMPLES,	-1,-1,	TIFF_SHORT,	FIELD_EXTRASAMPLES,
-      0,	1,	"ExtraSamples" },
-/* XXX for bogus Adobe Photoshop v2.5 files */
-    { TIFFTAG_EXTRASAMPLES,	-1,-1,	TIFF_BYTE,	FIELD_EXTRASAMPLES,
-      0,	1,	"ExtraSamples" },
-    { TIFFTAG_SAMPLEFORMAT,	-1,-1,	TIFF_SHORT,	FIELD_SAMPLEFORMAT,
-      0,	0,	"SampleFormat" },
-    { TIFFTAG_SMINSAMPLEVALUE,	-2,-1,	TIFF_ANY,	FIELD_SMINSAMPLEVALUE,
-      1,	0,	"SMinSampleValue" },
-    { TIFFTAG_SMAXSAMPLEVALUE,	-2,-1,	TIFF_ANY,	FIELD_SMAXSAMPLEVALUE,
-      1,	0,	"SMaxSampleValue" },
-    { TIFFTAG_CLIPPATH,		-1, -3, TIFF_BYTE,	FIELD_CUSTOM,
-      0,	1,	"ClipPath" },
-    { TIFFTAG_XCLIPPATHUNITS,	 1, 1,	TIFF_SLONG,	FIELD_CUSTOM,
-      0,	0,	"XClipPathUnits" },
-    { TIFFTAG_XCLIPPATHUNITS,	 1, 1,	TIFF_SSHORT,	FIELD_CUSTOM,
-      0,	0,	"XClipPathUnits" },
-    { TIFFTAG_XCLIPPATHUNITS,	 1, 1,	TIFF_SBYTE,	FIELD_CUSTOM,
-      0,	0,	"XClipPathUnits" },
-    { TIFFTAG_YCLIPPATHUNITS,	 1, 1,	TIFF_SLONG,	FIELD_CUSTOM,
-      0,	0,	"YClipPathUnits" },
-    { TIFFTAG_YCLIPPATHUNITS,	 1, 1,	TIFF_SSHORT,	FIELD_CUSTOM,
-      0,	0,	"YClipPathUnits" },
-    { TIFFTAG_YCLIPPATHUNITS,	 1, 1,	TIFF_SBYTE,	FIELD_CUSTOM,
-      0,	0,	"YClipPathUnits" },
-    { TIFFTAG_YCBCRCOEFFICIENTS, 3, 3,	TIFF_RATIONAL,	FIELD_CUSTOM,
-      0,	0,	"YCbCrCoefficients" },
-    { TIFFTAG_YCBCRSUBSAMPLING,	 2, 2,	TIFF_SHORT,	FIELD_YCBCRSUBSAMPLING,
-      0,	0,	"YCbCrSubsampling" },
-    { TIFFTAG_YCBCRPOSITIONING,	 1, 1,	TIFF_SHORT,	FIELD_YCBCRPOSITIONING,
-      0,	0,	"YCbCrPositioning" },
-    { TIFFTAG_REFERENCEBLACKWHITE, 6, 6, TIFF_RATIONAL,	FIELD_REFBLACKWHITE,
-      1,	0,	"ReferenceBlackWhite" },
-/* XXX temporarily accept LONG for backwards compatibility */
-    { TIFFTAG_REFERENCEBLACKWHITE, 6, 6, TIFF_LONG,	FIELD_REFBLACKWHITE,
-      1,	0,	"ReferenceBlackWhite" },
-    { TIFFTAG_XMLPACKET,	-3,-3,	TIFF_BYTE,	FIELD_CUSTOM,
-      0,	1,	"XMLPacket" },
-/* begin SGI tags */
-    { TIFFTAG_MATTEING,		 1, 1,	TIFF_SHORT,	FIELD_EXTRASAMPLES,
-      0,	0,	"Matteing" },
-    { TIFFTAG_DATATYPE,		-2,-1,	TIFF_SHORT,	FIELD_SAMPLEFORMAT,
-      0,	0,	"DataType" },
-    { TIFFTAG_IMAGEDEPTH,	 1, 1,	TIFF_LONG,	FIELD_IMAGEDEPTH,
-      0,	0,	"ImageDepth" },
-    { TIFFTAG_IMAGEDEPTH,	 1, 1,	TIFF_SHORT,	FIELD_IMAGEDEPTH,
-      0,	0,	"ImageDepth" },
-    { TIFFTAG_TILEDEPTH,	 1, 1,	TIFF_LONG,	FIELD_TILEDEPTH,
-      0,	0,	"TileDepth" },
-    { TIFFTAG_TILEDEPTH,	 1, 1,	TIFF_SHORT,	FIELD_TILEDEPTH,
-      0,	0,	"TileDepth" },
-/* end SGI tags */
-/* begin Pixar tags */
-    { TIFFTAG_PIXAR_IMAGEFULLWIDTH,  1, 1, TIFF_LONG,	FIELD_CUSTOM,
-      1,	0,	"ImageFullWidth" },
-    { TIFFTAG_PIXAR_IMAGEFULLLENGTH, 1, 1, TIFF_LONG,	FIELD_CUSTOM,
-      1,	0,	"ImageFullLength" },
-    { TIFFTAG_PIXAR_TEXTUREFORMAT,  -1, -1, TIFF_ASCII,	FIELD_CUSTOM,
-      1,	0,	"TextureFormat" },
-    { TIFFTAG_PIXAR_WRAPMODES,	    -1, -1, TIFF_ASCII,	FIELD_CUSTOM,
-      1,	0,	"TextureWrapModes" },
-    { TIFFTAG_PIXAR_FOVCOT,	     1, 1, TIFF_FLOAT,	FIELD_CUSTOM,
-      1,	0,	"FieldOfViewCotangent" },
-    { TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN,	16,16,	TIFF_FLOAT,
-      FIELD_CUSTOM,	1,	0,	"MatrixWorldToScreen" },
-    { TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA,	16,16,	TIFF_FLOAT,
-       FIELD_CUSTOM,	1,	0,	"MatrixWorldToCamera" },
-    { TIFFTAG_COPYRIGHT,	-1, -1,	TIFF_ASCII,	FIELD_CUSTOM,
-      1,	0,	"Copyright" },
-/* end Pixar tags */
-    { TIFFTAG_RICHTIFFIPTC, -3, -3,	TIFF_LONG,	FIELD_CUSTOM, 
-      0,    1,   "RichTIFFIPTC" },
-    { TIFFTAG_PHOTOSHOP,    -3, -3,	TIFF_BYTE,	FIELD_CUSTOM, 
-      0,    1,   "Photoshop" },
-    { TIFFTAG_EXIFIFD,		1, 1,	TIFF_LONG,	FIELD_CUSTOM,
-      0,	0,	"EXIFIFDOffset" },
-    { TIFFTAG_ICCPROFILE,	-3, -3,	TIFF_UNDEFINED,	FIELD_CUSTOM,
-      0,	1,	"ICC Profile" },
-    { TIFFTAG_GPSIFD,		1, 1,	TIFF_LONG,	FIELD_CUSTOM,
-      0,	0,	"GPSIFDOffset" },
-    { TIFFTAG_STONITS,		 1, 1,	TIFF_DOUBLE,	FIELD_CUSTOM,
-      0,	0,	"StoNits" },
-    { TIFFTAG_INTEROPERABILITYIFD, 1, 1, TIFF_LONG,	FIELD_CUSTOM,
-      0,	0,	"InteroperabilityIFDOffset" },
-/* begin DNG tags */
-    { TIFFTAG_DNGVERSION,	4, 4,	TIFF_BYTE,	FIELD_CUSTOM, 
-      0,	0,	"DNGVersion" },
-    { TIFFTAG_DNGBACKWARDVERSION, 4, 4,	TIFF_BYTE,	FIELD_CUSTOM, 
-      0,	0,	"DNGBackwardVersion" },
-    { TIFFTAG_UNIQUECAMERAMODEL,    -1, -1, TIFF_ASCII,	FIELD_CUSTOM,
-      1,	0,	"UniqueCameraModel" },
-    { TIFFTAG_LOCALIZEDCAMERAMODEL, -1, -1, TIFF_ASCII,	FIELD_CUSTOM,
-      1,	0,	"LocalizedCameraModel" },
-    { TIFFTAG_LOCALIZEDCAMERAMODEL, -1, -1, TIFF_BYTE,	FIELD_CUSTOM,
-      1,	1,	"LocalizedCameraModel" },
-    { TIFFTAG_CFAPLANECOLOR,	-1, -1,	TIFF_BYTE,	FIELD_CUSTOM, 
-      0,	1,	"CFAPlaneColor" },
-    { TIFFTAG_CFALAYOUT,	1, 1,	TIFF_SHORT,	FIELD_CUSTOM, 
-      0,	0,	"CFALayout" },
-    { TIFFTAG_LINEARIZATIONTABLE, -1, -1, TIFF_SHORT,	FIELD_CUSTOM, 
-      0,	1,	"LinearizationTable" },
-    { TIFFTAG_BLACKLEVELREPEATDIM, 2, 2, TIFF_SHORT,	FIELD_CUSTOM, 
-      0,	0,	"BlackLevelRepeatDim" },
-    { TIFFTAG_BLACKLEVEL,	-1, -1,	TIFF_LONG,	FIELD_CUSTOM, 
-      0,	1,	"BlackLevel" },
-    { TIFFTAG_BLACKLEVEL,	-1, -1,	TIFF_SHORT,	FIELD_CUSTOM, 
-      0,	1,	"BlackLevel" },
-    { TIFFTAG_BLACKLEVEL,	-1, -1,	TIFF_RATIONAL,	FIELD_CUSTOM, 
-      0,	1,	"BlackLevel" },
-    { TIFFTAG_BLACKLEVELDELTAH,	-1, -1,	TIFF_SRATIONAL,	FIELD_CUSTOM, 
-      0,	1,	"BlackLevelDeltaH" },
-    { TIFFTAG_BLACKLEVELDELTAV,	-1, -1,	TIFF_SRATIONAL,	FIELD_CUSTOM, 
-      0,	1,	"BlackLevelDeltaV" },
-    { TIFFTAG_WHITELEVEL,	-2, -2,	TIFF_LONG,	FIELD_CUSTOM, 
-      0,	0,	"WhiteLevel" },
-    { TIFFTAG_WHITELEVEL,	-2, -2,	TIFF_SHORT,	FIELD_CUSTOM, 
-      0,	0,	"WhiteLevel" },
-    { TIFFTAG_DEFAULTSCALE,	2, 2,	TIFF_RATIONAL,	FIELD_CUSTOM, 
-      0,	0,	"DefaultScale" },
-    { TIFFTAG_BESTQUALITYSCALE,	1, 1,	TIFF_RATIONAL,	FIELD_CUSTOM, 
-      0,	0,	"BestQualityScale" },
-    { TIFFTAG_DEFAULTCROPORIGIN,	2, 2,	TIFF_LONG,	FIELD_CUSTOM, 
-      0,	0,	"DefaultCropOrigin" },
-    { TIFFTAG_DEFAULTCROPORIGIN,	2, 2,	TIFF_SHORT,	FIELD_CUSTOM, 
-      0,	0,	"DefaultCropOrigin" },
-    { TIFFTAG_DEFAULTCROPORIGIN,	2, 2,	TIFF_RATIONAL,	FIELD_CUSTOM, 
-      0,	0,	"DefaultCropOrigin" },
-    { TIFFTAG_DEFAULTCROPSIZE,	2, 2,	TIFF_LONG,	FIELD_CUSTOM, 
-      0,	0,	"DefaultCropSize" },
-    { TIFFTAG_DEFAULTCROPSIZE,	2, 2,	TIFF_SHORT,	FIELD_CUSTOM, 
-      0,	0,	"DefaultCropSize" },
-    { TIFFTAG_DEFAULTCROPSIZE,	2, 2,	TIFF_RATIONAL,	FIELD_CUSTOM, 
-      0,	0,	"DefaultCropSize" },
-    { TIFFTAG_COLORMATRIX1,	-1, -1,	TIFF_SRATIONAL,	FIELD_CUSTOM, 
-      0,	1,	"ColorMatrix1" },
-    { TIFFTAG_COLORMATRIX2,	-1, -1,	TIFF_SRATIONAL,	FIELD_CUSTOM, 
-      0,	1,	"ColorMatrix2" },
-    { TIFFTAG_CAMERACALIBRATION1,	-1, -1,	TIFF_SRATIONAL,	FIELD_CUSTOM, 
-      0,	1,	"CameraCalibration1" },
-    { TIFFTAG_CAMERACALIBRATION2,	-1, -1,	TIFF_SRATIONAL,	FIELD_CUSTOM, 
-      0,	1,	"CameraCalibration2" },
-    { TIFFTAG_REDUCTIONMATRIX1,	-1, -1,	TIFF_SRATIONAL,	FIELD_CUSTOM, 
-      0,	1,	"ReductionMatrix1" },
-    { TIFFTAG_REDUCTIONMATRIX2,	-1, -1,	TIFF_SRATIONAL,	FIELD_CUSTOM, 
-      0,	1,	"ReductionMatrix2" },
-    { TIFFTAG_ANALOGBALANCE,	-1, -1,	TIFF_RATIONAL,	FIELD_CUSTOM, 
-      0,	1,	"AnalogBalance" },
-    { TIFFTAG_ASSHOTNEUTRAL,	-1, -1,	TIFF_SHORT,	FIELD_CUSTOM, 
-      0,	1,	"AsShotNeutral" },
-    { TIFFTAG_ASSHOTNEUTRAL,	-1, -1,	TIFF_RATIONAL,	FIELD_CUSTOM, 
-      0,	1,	"AsShotNeutral" },
-    { TIFFTAG_ASSHOTWHITEXY,	2, 2,	TIFF_RATIONAL,	FIELD_CUSTOM, 
-      0,	0,	"AsShotWhiteXY" },
-    { TIFFTAG_BASELINEEXPOSURE,	1, 1,	TIFF_SRATIONAL,	FIELD_CUSTOM, 
-      0,	0,	"BaselineExposure" },
-    { TIFFTAG_BASELINENOISE,	1, 1,	TIFF_RATIONAL,	FIELD_CUSTOM, 
-      0,	0,	"BaselineNoise" },
-    { TIFFTAG_BASELINESHARPNESS,	1, 1,	TIFF_RATIONAL,	FIELD_CUSTOM, 
-      0,	0,	"BaselineSharpness" },
-    { TIFFTAG_BAYERGREENSPLIT,	1, 1,	TIFF_LONG,	FIELD_CUSTOM, 
-      0,	0,	"BayerGreenSplit" },
-    { TIFFTAG_LINEARRESPONSELIMIT,	1, 1,	TIFF_RATIONAL,	FIELD_CUSTOM, 
-      0,	0,	"LinearResponseLimit" },
-    { TIFFTAG_CAMERASERIALNUMBER,    -1, -1, TIFF_ASCII,	FIELD_CUSTOM,
-      1,	0,	"CameraSerialNumber" },
-    { TIFFTAG_LENSINFO,	4, 4,	TIFF_RATIONAL,	FIELD_CUSTOM, 
-      0,	0,	"LensInfo" },
-    { TIFFTAG_CHROMABLURRADIUS,	1, 1,	TIFF_RATIONAL,	FIELD_CUSTOM, 
-      0,	0,	"ChromaBlurRadius" },
-    { TIFFTAG_ANTIALIASSTRENGTH,	1, 1,	TIFF_RATIONAL,	FIELD_CUSTOM, 
-      0,	0,	"AntiAliasStrength" },
-    { TIFFTAG_SHADOWSCALE,	1, 1,	TIFF_RATIONAL,	FIELD_CUSTOM, 
-      0,	0,	"ShadowScale" },
-    { TIFFTAG_DNGPRIVATEDATA,    -1, -1, TIFF_BYTE,	FIELD_CUSTOM,
-      0,	1,	"DNGPrivateData" },
-    { TIFFTAG_MAKERNOTESAFETY,	1, 1,	TIFF_SHORT,	FIELD_CUSTOM, 
-      0,	0,	"MakerNoteSafety" },
-    { TIFFTAG_CALIBRATIONILLUMINANT1,	1, 1,	TIFF_SHORT,	FIELD_CUSTOM, 
-      0,	0,	"CalibrationIlluminant1" },
-    { TIFFTAG_CALIBRATIONILLUMINANT2,	1, 1,	TIFF_SHORT,	FIELD_CUSTOM, 
-      0,	0,	"CalibrationIlluminant2" },
-    { TIFFTAG_RAWDATAUNIQUEID,	16, 16,	TIFF_BYTE,	FIELD_CUSTOM, 
-      0,	0,	"RawDataUniqueID" },
-    { TIFFTAG_ORIGINALRAWFILENAME,    -1, -1, TIFF_ASCII,	FIELD_CUSTOM,
-      1,	0,	"OriginalRawFileName" },
-    { TIFFTAG_ORIGINALRAWFILENAME,    -1, -1, TIFF_BYTE,	FIELD_CUSTOM,
-      1,	1,	"OriginalRawFileName" },
-    { TIFFTAG_ORIGINALRAWFILEDATA,    -1, -1, TIFF_UNDEFINED,	FIELD_CUSTOM,
-      0,	1,	"OriginalRawFileData" },
-    { TIFFTAG_ACTIVEAREA,	4, 4,	TIFF_LONG,	FIELD_CUSTOM, 
-      0,	0,	"ActiveArea" },
-    { TIFFTAG_ACTIVEAREA,	4, 4,	TIFF_SHORT,	FIELD_CUSTOM, 
-      0,	0,	"ActiveArea" },
-    { TIFFTAG_MASKEDAREAS,	-1, -1,	TIFF_LONG,	FIELD_CUSTOM, 
-      0,	1,	"MaskedAreas" },
-    { TIFFTAG_ASSHOTICCPROFILE,    -1, -1, TIFF_UNDEFINED,	FIELD_CUSTOM,
-      0,	1,	"AsShotICCProfile" },
-    { TIFFTAG_ASSHOTPREPROFILEMATRIX,	-1, -1,	TIFF_SRATIONAL,	FIELD_CUSTOM, 
-      0,	1,	"AsShotPreProfileMatrix" },
-    { TIFFTAG_CURRENTICCPROFILE,    -1, -1, TIFF_UNDEFINED,	FIELD_CUSTOM,
-      0,	1,	"CurrentICCProfile" },
-    { TIFFTAG_CURRENTPREPROFILEMATRIX,	-1, -1,	TIFF_SRATIONAL,	FIELD_CUSTOM, 
-      0,	1,	"CurrentPreProfileMatrix" },
-/* end DNG tags */
-};
-
-static const TIFFFieldInfo
-exifFieldInfo[] = {
-    { EXIFTAG_EXPOSURETIME,	1, 1,		TIFF_RATIONAL,	FIELD_CUSTOM, 
-      1,	0,	"ExposureTime" },
-    { EXIFTAG_FNUMBER,		1, 1,		TIFF_RATIONAL,	FIELD_CUSTOM, 
-      1,	0,	"FNumber" },
-    { EXIFTAG_EXPOSUREPROGRAM,	1, 1,		TIFF_SHORT,	FIELD_CUSTOM,
-      1,	0,	"ExposureProgram" },
-    { EXIFTAG_SPECTRALSENSITIVITY,    -1, -1,	TIFF_ASCII,	FIELD_CUSTOM,
-      1,	0,	"SpectralSensitivity" },
-    { EXIFTAG_ISOSPEEDRATINGS,  -1, -1,		TIFF_SHORT,	FIELD_CUSTOM,
-      1,	1,	"ISOSpeedRatings" },
-    { EXIFTAG_OECF,	-1, -1,			TIFF_UNDEFINED,	FIELD_CUSTOM,
-      1,	1,	"OptoelectricConversionFactor" },
-    { EXIFTAG_EXIFVERSION,	4, 4,		TIFF_UNDEFINED,	FIELD_CUSTOM,
-      1,	0,	"ExifVersion" },
-    { EXIFTAG_DATETIMEORIGINAL,	20, 20,		TIFF_ASCII,	FIELD_CUSTOM,
-      1,	0,	"DateTimeOriginal" },
-    { EXIFTAG_DATETIMEDIGITIZED, 20, 20,	TIFF_ASCII,	FIELD_CUSTOM,
-      1,	0,	"DateTimeDigitized" },
-    { EXIFTAG_COMPONENTSCONFIGURATION,	 4, 4,	TIFF_UNDEFINED,	FIELD_CUSTOM,
-      1,	0,	"ComponentsConfiguration" },
-    { EXIFTAG_COMPRESSEDBITSPERPIXEL,	 1, 1,	TIFF_RATIONAL,	FIELD_CUSTOM,
-      1,	0,	"CompressedBitsPerPixel" },
-    { EXIFTAG_SHUTTERSPEEDVALUE,	1, 1,	TIFF_SRATIONAL,	FIELD_CUSTOM, 
-      1,	0,	"ShutterSpeedValue" },
-    { EXIFTAG_APERTUREVALUE,	1, 1,		TIFF_RATIONAL,	FIELD_CUSTOM, 
-      1,	0,	"ApertureValue" },
-    { EXIFTAG_BRIGHTNESSVALUE,	1, 1,		TIFF_SRATIONAL,	FIELD_CUSTOM, 
-      1,	0,	"BrightnessValue" },
-    { EXIFTAG_EXPOSUREBIASVALUE,	1, 1,	TIFF_SRATIONAL,	FIELD_CUSTOM, 
-      1,	0,	"ExposureBiasValue" },
-    { EXIFTAG_MAXAPERTUREVALUE,	1, 1,		TIFF_RATIONAL,	FIELD_CUSTOM, 
-      1,	0,	"MaxApertureValue" },
-    { EXIFTAG_SUBJECTDISTANCE,	1, 1,		TIFF_RATIONAL,	FIELD_CUSTOM, 
-      1,	0,	"SubjectDistance" },
-    { EXIFTAG_METERINGMODE,	1, 1,		TIFF_SHORT,	FIELD_CUSTOM,
-      1,	0,	"MeteringMode" },
-    { EXIFTAG_LIGHTSOURCE,	1, 1,		TIFF_SHORT,	FIELD_CUSTOM,
-      1,	0,	"LightSource" },
-    { EXIFTAG_FLASH,	1, 1,			TIFF_SHORT,	FIELD_CUSTOM,
-      1,	0,	"Flash" },
-    { EXIFTAG_FOCALLENGTH,	1, 1,		TIFF_RATIONAL,	FIELD_CUSTOM, 
-      1,	0,	"FocalLength" },
-    { EXIFTAG_SUBJECTAREA,	-1, -1,		TIFF_SHORT,	FIELD_CUSTOM,
-      1,	1,	"SubjectArea" },
-    { EXIFTAG_MAKERNOTE,	-1, -1,		TIFF_UNDEFINED,	FIELD_CUSTOM,
-      1,	1,	"MakerNote" },
-    { EXIFTAG_USERCOMMENT,	-1, -1,		TIFF_UNDEFINED,	FIELD_CUSTOM,
-      1,	1,	"UserComment" },
-    { EXIFTAG_SUBSECTIME,    -1, -1,		TIFF_ASCII,	FIELD_CUSTOM,
-      1,	0,	"SubSecTime" },
-    { EXIFTAG_SUBSECTIMEORIGINAL, -1, -1,	TIFF_ASCII,	FIELD_CUSTOM,
-      1,	0,	"SubSecTimeOriginal" },
-    { EXIFTAG_SUBSECTIMEDIGITIZED,-1, -1,	TIFF_ASCII,	FIELD_CUSTOM,
-      1,	0,	"SubSecTimeDigitized" },
-    { EXIFTAG_FLASHPIXVERSION,	4, 4,		TIFF_UNDEFINED,	FIELD_CUSTOM,
-      1,	0,	"FlashpixVersion" },
-    { EXIFTAG_COLORSPACE,	1, 1,		TIFF_SHORT,	FIELD_CUSTOM,
-      1,	0,	"ColorSpace" },
-    { EXIFTAG_PIXELXDIMENSION,	1, 1,		TIFF_LONG,	FIELD_CUSTOM,
-      1,	0,	"PixelXDimension" },
-    { EXIFTAG_PIXELXDIMENSION,	1, 1,		TIFF_SHORT,	FIELD_CUSTOM,
-      1,	0,	"PixelXDimension" },
-    { EXIFTAG_PIXELYDIMENSION,	1, 1,		TIFF_LONG,	FIELD_CUSTOM,
-      1,	0,	"PixelYDimension" },
-    { EXIFTAG_PIXELYDIMENSION,	1, 1,		TIFF_SHORT,	FIELD_CUSTOM,
-      1,	0,	"PixelYDimension" },
-    { EXIFTAG_RELATEDSOUNDFILE,	13, 13,		TIFF_ASCII,	FIELD_CUSTOM,
-      1,	0,	"RelatedSoundFile" },
-    { EXIFTAG_FLASHENERGY,	1, 1,		TIFF_RATIONAL,	FIELD_CUSTOM, 
-      1,	0,	"FlashEnergy" },
-    { EXIFTAG_SPATIALFREQUENCYRESPONSE,	-1, -1,	TIFF_UNDEFINED,	FIELD_CUSTOM,
-      1,	1,	"SpatialFrequencyResponse" },
-    { EXIFTAG_FOCALPLANEXRESOLUTION,	1, 1,	TIFF_RATIONAL,	FIELD_CUSTOM, 
-      1,	0,	"FocalPlaneXResolution" },
-    { EXIFTAG_FOCALPLANEYRESOLUTION,	1, 1,	TIFF_RATIONAL,	FIELD_CUSTOM, 
-      1,	0,	"FocalPlaneYResolution" },
-    { EXIFTAG_FOCALPLANERESOLUTIONUNIT,	1, 1,	TIFF_SHORT,	FIELD_CUSTOM,
-      1,	0,	"FocalPlaneResolutionUnit" },
-    { EXIFTAG_SUBJECTLOCATION,	2, 2,		TIFF_SHORT,	FIELD_CUSTOM,
-      1,	0,	"SubjectLocation" },
-    { EXIFTAG_EXPOSUREINDEX,	1, 1,		TIFF_RATIONAL,	FIELD_CUSTOM, 
-      1,	0,	"ExposureIndex" },
-    { EXIFTAG_SENSINGMETHOD,	1, 1,		TIFF_SHORT,	FIELD_CUSTOM,
-      1,	0,	"SensingMethod" },
-    { EXIFTAG_FILESOURCE,	1, 1,		TIFF_UNDEFINED,	FIELD_CUSTOM,
-      1,	0,	"FileSource" },
-    { EXIFTAG_SCENETYPE,	1, 1,		TIFF_UNDEFINED,	FIELD_CUSTOM,
-      1,	0,	"SceneType" },
-    { EXIFTAG_CFAPATTERN,	-1, -1,		TIFF_UNDEFINED,	FIELD_CUSTOM,
-      1,	1,	"CFAPattern" },
-    { EXIFTAG_CUSTOMRENDERED,	1, 1,		TIFF_SHORT,	FIELD_CUSTOM,
-      1,	0,	"CustomRendered" },
-    { EXIFTAG_EXPOSUREMODE,	1, 1,		TIFF_SHORT,	FIELD_CUSTOM,
-      1,	0,	"ExposureMode" },
-    { EXIFTAG_WHITEBALANCE,	1, 1,		TIFF_SHORT,	FIELD_CUSTOM,
-      1,	0,	"WhiteBalance" },
-    { EXIFTAG_DIGITALZOOMRATIO,	1, 1,		TIFF_RATIONAL,	FIELD_CUSTOM, 
-      1,	0,	"DigitalZoomRatio" },
-    { EXIFTAG_FOCALLENGTHIN35MMFILM, 1, 1,	TIFF_SHORT,	FIELD_CUSTOM,
-      1,	0,	"FocalLengthIn35mmFilm" },
-    { EXIFTAG_SCENECAPTURETYPE,	1, 1,		TIFF_SHORT,	FIELD_CUSTOM,
-      1,	0,	"SceneCaptureType" },
-    { EXIFTAG_GAINCONTROL,	1, 1,		TIFF_RATIONAL,	FIELD_CUSTOM, 
-      1,	0,	"GainControl" },
-    { EXIFTAG_CONTRAST,		1, 1,		TIFF_SHORT,	FIELD_CUSTOM,
-      1,	0,	"Contrast" },
-    { EXIFTAG_SATURATION,	1, 1,		TIFF_SHORT,	FIELD_CUSTOM,
-      1,	0,	"Saturation" },
-    { EXIFTAG_SHARPNESS,	1, 1,		TIFF_SHORT,	FIELD_CUSTOM,
-      1,	0,	"Sharpness" },
-    { EXIFTAG_DEVICESETTINGDESCRIPTION,	-1, -1,	TIFF_UNDEFINED,	FIELD_CUSTOM,
-      1,	1,	"DeviceSettingDescription" },
-    { EXIFTAG_SUBJECTDISTANCERANGE, 1, 1,	TIFF_SHORT,	FIELD_CUSTOM,
-      1,	0,	"SubjectDistanceRange" },
-    { EXIFTAG_IMAGEUNIQUEID,	33, 33,		TIFF_ASCII,	FIELD_CUSTOM,
-      1,	0,	"ImageUniqueID" }
-};
-
-const TIFFFieldInfo *
-_TIFFGetFieldInfo(size_t *size)
-{
-	*size = TIFFArrayCount(tiffFieldInfo);
-	return tiffFieldInfo;
-}
-
-const TIFFFieldInfo *
-_TIFFGetExifFieldInfo(size_t *size)
-{
-	*size = TIFFArrayCount(exifFieldInfo);
-	return exifFieldInfo;
-}
-
-void
-_TIFFSetupFieldInfo(TIFF* tif, const TIFFFieldInfo info[], size_t n)
-{
-	if (tif->tif_fieldinfo) {
-		size_t  i;
-
-		for (i = 0; i < tif->tif_nfields; i++) 
-		{
-			TIFFFieldInfo *fld = tif->tif_fieldinfo[i];
-			if (fld->field_bit == FIELD_CUSTOM && 
-				strncmp("Tag ", fld->field_name, 4) == 0) {
-					_TIFFfree(fld->field_name);
-					_TIFFfree(fld);
-				}
-		}   
-      
-		_TIFFfree(tif->tif_fieldinfo);
-		tif->tif_nfields = 0;
-	}
-	if (!_TIFFMergeFieldInfo(tif, info, n))
-	{
-		TIFFErrorExt(tif->tif_clientdata, "_TIFFSetupFieldInfo",
-			     "Setting up field info failed");
-	}
-}
-
-static int
-tagCompare(const void* a, const void* b)
-{
-	const TIFFFieldInfo* ta = *(const TIFFFieldInfo**) a;
-	const TIFFFieldInfo* tb = *(const TIFFFieldInfo**) b;
-	/* NB: be careful of return values for 16-bit platforms */
-	if (ta->field_tag != tb->field_tag)
-		return (int)ta->field_tag - (int)tb->field_tag;
-	else
-		return (ta->field_type == TIFF_ANY) ?
-			0 : ((int)tb->field_type - (int)ta->field_type);
-}
-
-static int
-tagNameCompare(const void* a, const void* b)
-{
-	const TIFFFieldInfo* ta = *(const TIFFFieldInfo**) a;
-	const TIFFFieldInfo* tb = *(const TIFFFieldInfo**) b;
-	int ret = strcmp(ta->field_name, tb->field_name);
-
-	if (ret)
-		return ret;
-	else
-		return (ta->field_type == TIFF_ANY) ?
-			0 : ((int)tb->field_type - (int)ta->field_type);
-}
-
-void
-TIFFMergeFieldInfo(TIFF* tif, const TIFFFieldInfo info[], int n)
-{
-	if (_TIFFMergeFieldInfo(tif, info, n) < 0)
-	{
-		TIFFErrorExt(tif->tif_clientdata, "TIFFMergeFieldInfo",
-			     "Merging block of %d fields failed", n);
-	}
-}
-
-int
-_TIFFMergeFieldInfo(TIFF* tif, const TIFFFieldInfo info[], int n)
-{
-	static const char module[] = "_TIFFMergeFieldInfo";
-	static const char reason[] = "for field info array";
-	TIFFFieldInfo** tp;
-	int i;
-
-        tif->tif_foundfield = NULL;
-
-	if (tif->tif_nfields > 0) {
-		tif->tif_fieldinfo = (TIFFFieldInfo**)
-			_TIFFCheckRealloc(tif, tif->tif_fieldinfo,
-					  (tif->tif_nfields + n),
-					  sizeof (TIFFFieldInfo*), reason);
-	} else {
-		tif->tif_fieldinfo = (TIFFFieldInfo**)
-			_TIFFCheckMalloc(tif, n, sizeof (TIFFFieldInfo*),
-					 reason);
-	}
-	if (!tif->tif_fieldinfo) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-			     "Failed to allocate field info array");
-		return 0;
-	}
-	tp = tif->tif_fieldinfo + tif->tif_nfields;
-	for (i = 0; i < n; i++)
-        {
-            const TIFFFieldInfo *fip =
-                _TIFFFindFieldInfo(tif, info[i].field_tag, info[i].field_type);
-
-            /* only add definitions that aren't already present */
-            if (!fip) {
-                *tp++ = (TIFFFieldInfo*) (info + i);
-                tif->tif_nfields++;
-            }
-        }
-
-        /* Sort the field info by tag number */
-        qsort(tif->tif_fieldinfo, tif->tif_nfields,
-	      sizeof (TIFFFieldInfo*), tagCompare);
-
-	return n;
-}
-
-void
-_TIFFPrintFieldInfo(TIFF* tif, FILE* fd)
-{
-	size_t i;
-
-	fprintf(fd, "%s: \n", tif->tif_name);
-	for (i = 0; i < tif->tif_nfields; i++) {
-		const TIFFFieldInfo* fip = tif->tif_fieldinfo[i];
-		fprintf(fd, "field[%2d] %5lu, %2d, %2d, %d, %2d, %5s, %5s, %s\n"
-			, (int)i
-			, (unsigned long) fip->field_tag
-			, fip->field_readcount, fip->field_writecount
-			, fip->field_type
-			, fip->field_bit
-			, fip->field_oktochange ? "TRUE" : "FALSE"
-			, fip->field_passcount ? "TRUE" : "FALSE"
-			, fip->field_name
-		);
-	}
-}
-
-/*
- * Return size of TIFFDataType in bytes
- */
-int
-TIFFDataWidth(TIFFDataType type)
-{
-	switch(type)
-	{
-	case 0:  /* nothing */
-	case 1:  /* TIFF_BYTE */
-	case 2:  /* TIFF_ASCII */
-	case 6:  /* TIFF_SBYTE */
-	case 7:  /* TIFF_UNDEFINED */
-		return 1;
-	case 3:  /* TIFF_SHORT */
-	case 8:  /* TIFF_SSHORT */
-		return 2;
-	case 4:  /* TIFF_LONG */
-	case 9:  /* TIFF_SLONG */
-	case 11: /* TIFF_FLOAT */
-        case 13: /* TIFF_IFD */
-		return 4;
-	case 5:  /* TIFF_RATIONAL */
-	case 10: /* TIFF_SRATIONAL */
-	case 12: /* TIFF_DOUBLE */
-		return 8;
-	default:
-		return 0; /* will return 0 for unknown types */
-	}
-}
-
-/*
- * Return size of TIFFDataType in bytes.
- *
- * XXX: We need a separate function to determine the space needed
- * to store the value. For TIFF_RATIONAL values TIFFDataWidth() returns 8,
- * but we use 4-byte float to represent rationals.
- */
-int
-_TIFFDataSize(TIFFDataType type)
-{
-	switch (type) {
-		case TIFF_BYTE:
-		case TIFF_SBYTE:
-		case TIFF_ASCII:
-		case TIFF_UNDEFINED:
-		    return 1;
-		case TIFF_SHORT:
-		case TIFF_SSHORT:
-		    return 2;
-		case TIFF_LONG:
-		case TIFF_SLONG:
-		case TIFF_FLOAT:
-		case TIFF_IFD:
-		case TIFF_RATIONAL:
-		case TIFF_SRATIONAL:
-		    return 4;
-		case TIFF_DOUBLE:
-		    return 8;
-		default:
-		    return 0;
-	}
-}
-
-/*
- * Return nearest TIFFDataType to the sample type of an image.
- */
-TIFFDataType
-_TIFFSampleToTagType(TIFF* tif)
-{
-	uint32 bps = TIFFhowmany8(tif->tif_dir.td_bitspersample);
-
-	switch (tif->tif_dir.td_sampleformat) {
-	case SAMPLEFORMAT_IEEEFP:
-		return (bps == 4 ? TIFF_FLOAT : TIFF_DOUBLE);
-	case SAMPLEFORMAT_INT:
-		return (bps <= 1 ? TIFF_SBYTE :
-		    bps <= 2 ? TIFF_SSHORT : TIFF_SLONG);
-	case SAMPLEFORMAT_UINT:
-		return (bps <= 1 ? TIFF_BYTE :
-		    bps <= 2 ? TIFF_SHORT : TIFF_LONG);
-	case SAMPLEFORMAT_VOID:
-		return (TIFF_UNDEFINED);
-	}
-	/*NOTREACHED*/
-	return (TIFF_UNDEFINED);
-}
-
-const TIFFFieldInfo*
-_TIFFFindFieldInfo(TIFF* tif, ttag_t tag, TIFFDataType dt)
-{
-        TIFFFieldInfo key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0};
-	TIFFFieldInfo* pkey = &key;
-	const TIFFFieldInfo **ret;
-
-	if (tif->tif_foundfield && tif->tif_foundfield->field_tag == tag &&
-	    (dt == TIFF_ANY || dt == tif->tif_foundfield->field_type))
-		return tif->tif_foundfield;
-
-	/* If we are invoked with no field information, then just return. */
-	if ( !tif->tif_fieldinfo ) {
-		return NULL;
-	}
-
-	/* NB: use sorted search (e.g. binary search) */
-	key.field_tag = tag;
-        key.field_type = dt;
-
-	ret = (const TIFFFieldInfo **) bsearch(&pkey,
-					       tif->tif_fieldinfo, 
-					       tif->tif_nfields,
-					       sizeof(TIFFFieldInfo *), 
-					       tagCompare);
-	return tif->tif_foundfield = (ret ? *ret : NULL);
-}
-
-const TIFFFieldInfo*
-_TIFFFindFieldInfoByName(TIFF* tif, const char *field_name, TIFFDataType dt)
-{
-        TIFFFieldInfo key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0};
-	TIFFFieldInfo* pkey = &key;
-	const TIFFFieldInfo **ret;
-
-	if (tif->tif_foundfield
-	    && streq(tif->tif_foundfield->field_name, field_name)
-	    && (dt == TIFF_ANY || dt == tif->tif_foundfield->field_type))
-		return (tif->tif_foundfield);
-
-	/* If we are invoked with no field information, then just return. */
-	if ( !tif->tif_fieldinfo ) {
-		return NULL;
-	}
-
-	/* NB: use sorted search (e.g. binary search) */
-        key.field_name = (char *)field_name;
-        key.field_type = dt;
-
-        ret = (const TIFFFieldInfo **) lfind(&pkey,
-					     tif->tif_fieldinfo, 
-					     &tif->tif_nfields,
-					     sizeof(TIFFFieldInfo *),
-					     tagNameCompare);
-	return tif->tif_foundfield = (ret ? *ret : NULL);
-}
-
-const TIFFFieldInfo*
-_TIFFFieldWithTag(TIFF* tif, ttag_t tag)
-{
-	const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY);
-	if (!fip) {
-		TIFFErrorExt(tif->tif_clientdata, "TIFFFieldWithTag",
-			     "Internal error, unknown tag 0x%x",
-			     (unsigned int) tag);
-	}
-	return (fip);
-}
-
-const TIFFFieldInfo*
-_TIFFFieldWithName(TIFF* tif, const char *field_name)
-{
-	const TIFFFieldInfo* fip =
-		_TIFFFindFieldInfoByName(tif, field_name, TIFF_ANY);
-	if (!fip) {
-		TIFFErrorExt(tif->tif_clientdata, "TIFFFieldWithName",
-			     "Internal error, unknown tag %s", field_name);
-	}
-	return (fip);
-}
-
-const TIFFFieldInfo*
-_TIFFFindOrRegisterFieldInfo( TIFF *tif, ttag_t tag, TIFFDataType dt )
-
-{
-    const TIFFFieldInfo *fld;
-
-    fld = _TIFFFindFieldInfo( tif, tag, dt );
-    if( fld == NULL )
-    {
-        fld = _TIFFCreateAnonFieldInfo( tif, tag, dt );
-        if (!_TIFFMergeFieldInfo(tif, fld, 1))
-		return NULL;
-    }
-
-    return fld;
-}
-
-TIFFFieldInfo*
-_TIFFCreateAnonFieldInfo(TIFF *tif, ttag_t tag, TIFFDataType field_type)
-{
-	TIFFFieldInfo *fld;
-	(void) tif;
-
-	fld = (TIFFFieldInfo *) _TIFFmalloc(sizeof (TIFFFieldInfo));
-	if (fld == NULL)
-	    return NULL;
-	_TIFFmemset( fld, 0, sizeof(TIFFFieldInfo) );
-
-	fld->field_tag = tag;
-	fld->field_readcount = TIFF_VARIABLE2;
-	fld->field_writecount = TIFF_VARIABLE2;
-	fld->field_type = field_type;
-	fld->field_bit = FIELD_CUSTOM;
-	fld->field_oktochange = TRUE;
-	fld->field_passcount = TRUE;
-	fld->field_name = (char *) _TIFFmalloc(32);
-	if (fld->field_name == NULL) {
-	    _TIFFfree(fld);
-	    return NULL;
-	}
-
-	/* 
-	 * note that this name is a special sign to TIFFClose() and
-	 * _TIFFSetupFieldInfo() to free the field
-	 */
-	sprintf(fld->field_name, "Tag %d", (int) tag);
-
-	return fld;    
-}
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_dirread.c b/Source/LibTIFF/tif_dirread.c
deleted file mode 100644
index b078696..0000000
--- a/Source/LibTIFF/tif_dirread.c
+++ /dev/null
@@ -1,2117 +0,0 @@
-/* $Id: tif_dirread.c,v 1.38 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library.
- *
- * Directory Read Support Routines.
- */
-#include "tiffiop.h"
-
-#define	IGNORE	0		/* tag placeholder used below */
-
-#ifdef HAVE_IEEEFP
-# define	TIFFCvtIEEEFloatToNative(tif, n, fp)
-# define	TIFFCvtIEEEDoubleToNative(tif, n, dp)
-#else
-extern	void TIFFCvtIEEEFloatToNative(TIFF*, uint32, float*);
-extern	void TIFFCvtIEEEDoubleToNative(TIFF*, uint32, double*);
-#endif
-
-static  TIFFDirEntry* TIFFReadDirectoryFind(TIFFDirEntry* dir,
-					    uint16 dircount, uint16 tagid);
-static	int EstimateStripByteCounts(TIFF*, TIFFDirEntry*, uint16);
-static	void MissingRequired(TIFF*, const char*);
-static	int TIFFCheckDirOffset(TIFF*, toff_t);
-static	int CheckDirCount(TIFF*, TIFFDirEntry*, uint32);
-static	uint16 TIFFFetchDirectory(TIFF*, toff_t, TIFFDirEntry**, toff_t *);
-static	tsize_t TIFFFetchData(TIFF*, TIFFDirEntry*, char*);
-static	tsize_t TIFFFetchString(TIFF*, TIFFDirEntry*, char*);
-static	float TIFFFetchRational(TIFF*, TIFFDirEntry*);
-static	int TIFFFetchNormalTag(TIFF*, TIFFDirEntry*);
-static	int TIFFFetchPerSampleShorts(TIFF*, TIFFDirEntry*, uint16*);
-static	int TIFFFetchPerSampleLongs(TIFF*, TIFFDirEntry*, uint32*);
-static	int TIFFFetchPerSampleAnys(TIFF*, TIFFDirEntry*, double*, double*);
-static	int TIFFFetchShortArray(TIFF*, TIFFDirEntry*, uint16*);
-static	int TIFFFetchStripThing(TIFF*, TIFFDirEntry*, long, uint32**);
-static	int TIFFFetchRefBlackWhite(TIFF*, TIFFDirEntry*);
-static	int TIFFFetchSubjectDistance(TIFF*, TIFFDirEntry*);
-static	float TIFFFetchFloat(TIFF*, TIFFDirEntry*);
-static	int TIFFFetchFloatArray(TIFF*, TIFFDirEntry*, float*);
-static	int TIFFFetchDoubleArray(TIFF*, TIFFDirEntry*, double*);
-static	int TIFFFetchAnyArray(TIFF*, TIFFDirEntry*, double*);
-static	int TIFFFetchShortPair(TIFF*, TIFFDirEntry*);
-static	void ChopUpSingleUncompressedStrip(TIFF*);
-
-/*
- * Read the next TIFF directory from a file and convert it to the internal
- * format. We read directories sequentially.
- */
-int
-TIFFReadDirectory(TIFF* tif)
-{
-	static const char module[] = "TIFFReadDirectory";
-
-	int n;
-	TIFFDirectory* td;
-	TIFFDirEntry *dp, *dir = NULL;
-	uint16 iv;
-	uint32 v;
-	const TIFFFieldInfo* fip;
-	size_t fix;
-	uint16 dircount;
-	uint16 previous_tag = 0;
-	int diroutoforderwarning = 0, compressionknown = 0;
-	int haveunknowntags = 0;
-
-	tif->tif_diroff = tif->tif_nextdiroff;
-	/*
-	 * Check whether we have the last offset or bad offset (IFD looping).
-	 */
-	if (!TIFFCheckDirOffset(tif, tif->tif_nextdiroff))
-		return 0;
-	/*
-	 * Cleanup any previous compression state.
-	 */
-	(*tif->tif_cleanup)(tif);
-	tif->tif_curdir++;
-	dircount = TIFFFetchDirectory(tif, tif->tif_nextdiroff,
-				      &dir, &tif->tif_nextdiroff);
-	if (!dircount) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-			     "%s: Failed to read directory at offset %u",
-			     tif->tif_name, tif->tif_nextdiroff);
-		return 0;
-	}
-	{
-		TIFFDirEntry* ma;
-		uint16 mb;
-		for (ma=dir, mb=0; mb<dircount; ma++, mb++)
-		{
-			TIFFDirEntry* na;
-			uint16 nb;
-			for (na=ma+1, nb=mb+1; nb<dircount; na++, nb++)
-			{
-				if (ma->tdir_tag==na->tdir_tag)
-					na->tdir_tag=IGNORE;
-			}
-		}
-	}
-	tif->tif_flags &= ~TIFF_BEENWRITING;	/* reset before new dir */
-	/*
-	 * Setup default value and then make a pass over
-	 * the fields to check type and tag information,
-	 * and to extract info required to size data
-	 * structures.  A second pass is made afterwards
-	 * to read in everthing not taken in the first pass.
-	 */
-	td = &tif->tif_dir;
-	/* free any old stuff and reinit */
-	TIFFFreeDirectory(tif);
-	TIFFDefaultDirectory(tif);
-	/*
-	 * Electronic Arts writes gray-scale TIFF files
-	 * without a PlanarConfiguration directory entry.
-	 * Thus we setup a default value here, even though
-	 * the TIFF spec says there is no default value.
-	 */
-	TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
-
-	/*
-	 * Sigh, we must make a separate pass through the
-	 * directory for the following reason:
-	 *
-	 * We must process the Compression tag in the first pass
-	 * in order to merge in codec-private tag definitions (otherwise
-	 * we may get complaints about unknown tags).  However, the
-	 * Compression tag may be dependent on the SamplesPerPixel
-	 * tag value because older TIFF specs permited Compression
-	 * to be written as a SamplesPerPixel-count tag entry.
-	 * Thus if we don't first figure out the correct SamplesPerPixel
-	 * tag value then we may end up ignoring the Compression tag
-	 * value because it has an incorrect count value (if the
-	 * true value of SamplesPerPixel is not 1).
-	 *
-	 * It sure would have been nice if Aldus had really thought
-	 * this stuff through carefully.
-	 */
-	for (dp = dir, n = dircount; n > 0; n--, dp++) {
-		if (tif->tif_flags & TIFF_SWAB) {
-			TIFFSwabArrayOfShort(&dp->tdir_tag, 2);
-			TIFFSwabArrayOfLong(&dp->tdir_count, 2);
-		}
-		if (dp->tdir_tag == TIFFTAG_SAMPLESPERPIXEL) {
-			if (!TIFFFetchNormalTag(tif, dp))
-				goto bad;
-			dp->tdir_tag = IGNORE;
-		}
-	}
-	/*
-	 * First real pass over the directory.
-	 */
-	fix = 0;
-	for (dp = dir, n = dircount; n > 0; n--, dp++) {
-
-		if (dp->tdir_tag == IGNORE)
-			continue;
-
-		/*
-		 * Silicon Beach (at least) writes unordered
-		 * directory tags (violating the spec).  Handle
-		 * it here, but be obnoxious (maybe they'll fix it?).
-		 */
-		if (dp->tdir_tag < previous_tag) {
-			if (!diroutoforderwarning) {
-				TIFFWarningExt(tif->tif_clientdata, module,
-	"%s: invalid TIFF directory; tags are not sorted in ascending order",
-					    tif->tif_name);
-				diroutoforderwarning = 1;
-			}
-		}
-		previous_tag = dp->tdir_tag;
-		if (fix >= tif->tif_nfields ||
-		    dp->tdir_tag < tif->tif_fieldinfo[fix]->field_tag)
-			fix = 0;			/* O(n^2) */
-		while (fix < tif->tif_nfields &&
-		    tif->tif_fieldinfo[fix]->field_tag < dp->tdir_tag)
-			fix++;
-		if (fix >= tif->tif_nfields ||
-		    tif->tif_fieldinfo[fix]->field_tag != dp->tdir_tag) {
-			/* Unknown tag ... we'll deal with it below */
-			haveunknowntags = 1;
-			continue;
-		}
-		/*
-		 * Null out old tags that we ignore.
-		 */
-		if (tif->tif_fieldinfo[fix]->field_bit == FIELD_IGNORE) {
-	ignore:
-			dp->tdir_tag = IGNORE;
-			continue;
-		}
-		/*
-		 * Check data type.
-		 */
-		fip = tif->tif_fieldinfo[fix];
-		while (dp->tdir_type != (unsigned short) fip->field_type
-		    && fix < tif->tif_nfields) {
-			if (fip->field_type == TIFF_ANY)	/* wildcard */
-				break;
-			fip = tif->tif_fieldinfo[++fix];
-			if (fix >= tif->tif_nfields ||
-			    fip->field_tag != dp->tdir_tag) {
-				TIFFWarningExt(tif->tif_clientdata, module,
-			"%s: wrong data type %d for \"%s\"; tag ignored",
-					    tif->tif_name, dp->tdir_type,
-					    tif->tif_fieldinfo[fix-1]->field_name);
-				goto ignore;
-			}
-		}
-		/*
-		 * Check count if known in advance.
-		 */
-		if (fip->field_readcount != TIFF_VARIABLE
-		    && fip->field_readcount != TIFF_VARIABLE2) {
-			uint32 expected = (fip->field_readcount == TIFF_SPP) ?
-			    (uint32) td->td_samplesperpixel :
-			    (uint32) fip->field_readcount;
-			if (!CheckDirCount(tif, dp, expected))
-				goto ignore;
-		}
-
-		switch (dp->tdir_tag) {
-		case TIFFTAG_COMPRESSION:
-			/*
-			 * The 5.0 spec says the Compression tag has
-			 * one value, while earlier specs say it has
-			 * one value per sample.  Because of this, we
-			 * accept the tag if one value is supplied.
-			 */
-			if (dp->tdir_count == 1) {
-				v = TIFFExtractData(tif,
-				    dp->tdir_type, dp->tdir_offset);
-				if (!TIFFSetField(tif, dp->tdir_tag, (uint16)v))
-					goto bad;
-				else
-					compressionknown = 1;
-				break;
-			/* XXX: workaround for broken TIFFs */
-			} else if (dp->tdir_type == TIFF_LONG) {
-				if (!TIFFFetchPerSampleLongs(tif, dp, &v) ||
-				    !TIFFSetField(tif, dp->tdir_tag, (uint16)v))
-					goto bad;
-			} else {
-				if (!TIFFFetchPerSampleShorts(tif, dp, &iv)
-				    || !TIFFSetField(tif, dp->tdir_tag, iv))
-					goto bad;
-			}
-			dp->tdir_tag = IGNORE;
-			break;
-		case TIFFTAG_STRIPOFFSETS:
-		case TIFFTAG_STRIPBYTECOUNTS:
-		case TIFFTAG_TILEOFFSETS:
-		case TIFFTAG_TILEBYTECOUNTS:
-			TIFFSetFieldBit(tif, fip->field_bit);
-			break;
-		case TIFFTAG_IMAGEWIDTH:
-		case TIFFTAG_IMAGELENGTH:
-		case TIFFTAG_IMAGEDEPTH:
-		case TIFFTAG_TILELENGTH:
-		case TIFFTAG_TILEWIDTH:
-		case TIFFTAG_TILEDEPTH:
-		case TIFFTAG_PLANARCONFIG:
-		case TIFFTAG_ROWSPERSTRIP:
-		case TIFFTAG_EXTRASAMPLES:
-			if (!TIFFFetchNormalTag(tif, dp))
-				goto bad;
-			dp->tdir_tag = IGNORE;
-			break;
-		}
-	}
-
-	/*
-	 * If we saw any unknown tags, make an extra pass over the directory
-	 * to deal with them.  This must be done separately because the tags
-	 * could have become known when we registered a codec after finding
-	 * the Compression tag.  In a correctly-sorted directory there's
-	 * no problem because Compression will come before any codec-private
-	 * tags, but if the sorting is wrong that might not hold.
-	 */
-	if (haveunknowntags) {
-	    fix = 0;
-	    for (dp = dir, n = dircount; n > 0; n--, dp++) {
-		if (dp->tdir_tag == IGNORE)
-			continue;
-		if (fix >= tif->tif_nfields ||
-		    dp->tdir_tag < tif->tif_fieldinfo[fix]->field_tag)
-			fix = 0;			/* O(n^2) */
-		while (fix < tif->tif_nfields &&
-		    tif->tif_fieldinfo[fix]->field_tag < dp->tdir_tag)
-			fix++;
-		if (fix >= tif->tif_nfields ||
-		    tif->tif_fieldinfo[fix]->field_tag != dp->tdir_tag) {
-
-					TIFFWarningExt(tif->tif_clientdata,
-						       module,
-                        "%s: unknown field with tag %d (0x%x) encountered",
-						       tif->tif_name,
-						       dp->tdir_tag,
-						       dp->tdir_tag);
-
-					if (!_TIFFMergeFieldInfo(tif,
-						_TIFFCreateAnonFieldInfo(tif,
-						dp->tdir_tag,
-						(TIFFDataType) dp->tdir_type),
-						1))
-					{
-					TIFFWarningExt(tif->tif_clientdata,
-						       module,
-			"Registering anonymous field with tag %d (0x%x) failed",
-						       dp->tdir_tag,
-						       dp->tdir_tag);
-					dp->tdir_tag = IGNORE;
-					continue;
-					}
-			fix = 0;
-			while (fix < tif->tif_nfields &&
-			       tif->tif_fieldinfo[fix]->field_tag < dp->tdir_tag)
-				fix++;
-		}
-		/*
-		 * Check data type.
-		 */
-		fip = tif->tif_fieldinfo[fix];
-		while (dp->tdir_type != (unsigned short) fip->field_type
-		    && fix < tif->tif_nfields) {
-			if (fip->field_type == TIFF_ANY)	/* wildcard */
-				break;
-			fip = tif->tif_fieldinfo[++fix];
-			if (fix >= tif->tif_nfields ||
-			    fip->field_tag != dp->tdir_tag) {
-				TIFFWarningExt(tif->tif_clientdata, module,
-			"%s: wrong data type %d for \"%s\"; tag ignored",
-					    tif->tif_name, dp->tdir_type,
-					    tif->tif_fieldinfo[fix-1]->field_name);
-				dp->tdir_tag = IGNORE;
-				break;
-			}
-		}
-	    }
-	}
-
-	/*
-	 * XXX: OJPEG hack.
-	 * If a) compression is OJPEG, b) planarconfig tag says it's separate,
-	 * c) strip offsets/bytecounts tag are both present and
-	 * d) both contain exactly one value, then we consistently find
-	 * that the buggy implementation of the buggy compression scheme
-	 * matches contig planarconfig best. So we 'fix-up' the tag here
-	 */
-	if ((td->td_compression==COMPRESSION_OJPEG) &&
-	    (td->td_planarconfig==PLANARCONFIG_SEPARATE)) {
-		dp = TIFFReadDirectoryFind(dir,dircount,TIFFTAG_STRIPOFFSETS);
-		if ((dp!=0) && (dp->tdir_count==1)) {
-			dp = TIFFReadDirectoryFind(dir, dircount,
-						   TIFFTAG_STRIPBYTECOUNTS);
-			if ((dp!=0) && (dp->tdir_count==1)) {
-				td->td_planarconfig=PLANARCONFIG_CONTIG;
-				TIFFWarningExt(tif->tif_clientdata,
-					       "TIFFReadDirectory",
-				"Planarconfig tag value assumed incorrect, "
-				"assuming data is contig instead of chunky");
-			}
-		}
-	}
-
-	/*
-	 * Allocate directory structure and setup defaults.
-	 */
-	if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS)) {
-		MissingRequired(tif, "ImageLength");
-		goto bad;
-	}
-	/* 
-	 * Setup appropriate structures (by strip or by tile)
-	 */
-	if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) {
-		td->td_nstrips = TIFFNumberOfStrips(tif);
-		td->td_tilewidth = td->td_imagewidth;
-		td->td_tilelength = td->td_rowsperstrip;
-		td->td_tiledepth = td->td_imagedepth;
-		tif->tif_flags &= ~TIFF_ISTILED;
-	} else {
-		td->td_nstrips = TIFFNumberOfTiles(tif);
-		tif->tif_flags |= TIFF_ISTILED;
-	}
-	if (!td->td_nstrips) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-			     "%s: cannot handle zero number of %s",
-			     tif->tif_name, isTiled(tif) ? "tiles" : "strips");
-		goto bad;
-	}
-	td->td_stripsperimage = td->td_nstrips;
-	if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
-		td->td_stripsperimage /= td->td_samplesperpixel;
-	if (!TIFFFieldSet(tif, FIELD_STRIPOFFSETS)) {
-		if ((td->td_compression==COMPRESSION_OJPEG) &&
-		    (isTiled(tif)==0) &&
-		    (td->td_nstrips==1)) {
-			/*
-			 * XXX: OJPEG hack.
-			 * If a) compression is OJPEG, b) it's not a tiled TIFF,
-			 * and c) the number of strips is 1,
-			 * then we tolerate the absence of stripoffsets tag,
-			 * because, presumably, all required data is in the
-			 * JpegInterchangeFormat stream.
-			 */
-			TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
-		} else {
-			MissingRequired(tif,
-				isTiled(tif) ? "TileOffsets" : "StripOffsets");
-			goto bad;
-		}
-	}
-
-	/*
-	 * Second pass: extract other information.
-	 */
-	for (dp = dir, n = dircount; n > 0; n--, dp++) {
-		if (dp->tdir_tag == IGNORE)
-			continue;
-		switch (dp->tdir_tag) {
-		case TIFFTAG_MINSAMPLEVALUE:
-		case TIFFTAG_MAXSAMPLEVALUE:
-		case TIFFTAG_BITSPERSAMPLE:
-		case TIFFTAG_DATATYPE:
-		case TIFFTAG_SAMPLEFORMAT:
-			/*
-			 * The 5.0 spec says the Compression tag has
-			 * one value, while earlier specs say it has
-			 * one value per sample.  Because of this, we
-			 * accept the tag if one value is supplied.
-			 *
-			 * The MinSampleValue, MaxSampleValue, BitsPerSample
-			 * DataType and SampleFormat tags are supposed to be
-			 * written as one value/sample, but some vendors
-			 * incorrectly write one value only -- so we accept
-			 * that as well (yech). Other vendors write correct
-			 * value for NumberOfSamples, but incorrect one for
-			 * BitsPerSample and friends, and we will read this
-			 * too.
-			 */
-			if (dp->tdir_count == 1) {
-				v = TIFFExtractData(tif,
-				    dp->tdir_type, dp->tdir_offset);
-				if (!TIFFSetField(tif, dp->tdir_tag, (uint16)v))
-					goto bad;
-			/* XXX: workaround for broken TIFFs */
-			} else if (dp->tdir_tag == TIFFTAG_BITSPERSAMPLE
-				   && dp->tdir_type == TIFF_LONG) {
-				if (!TIFFFetchPerSampleLongs(tif, dp, &v) ||
-				    !TIFFSetField(tif, dp->tdir_tag, (uint16)v))
-					goto bad;
-			} else {
-				if (!TIFFFetchPerSampleShorts(tif, dp, &iv) ||
-				    !TIFFSetField(tif, dp->tdir_tag, iv))
-					goto bad;
-			}
-			break;
-		case TIFFTAG_SMINSAMPLEVALUE:
-			{
-				double minv = 0.0, maxv = 0.0;
-				if (!TIFFFetchPerSampleAnys(tif, dp, &minv, &maxv) ||
-				    !TIFFSetField(tif, dp->tdir_tag, minv))
-					goto bad;
-			}
-			break;
-		case TIFFTAG_SMAXSAMPLEVALUE:
-			{
-				double minv = 0.0, maxv = 0.0;
-				if (!TIFFFetchPerSampleAnys(tif, dp, &minv, &maxv) ||
-				    !TIFFSetField(tif, dp->tdir_tag, maxv))
-					goto bad;
-			}
-			break;
-		case TIFFTAG_STRIPOFFSETS:
-		case TIFFTAG_TILEOFFSETS:
-			if (!TIFFFetchStripThing(tif, dp,
-			    td->td_nstrips, &td->td_stripoffset))
-				goto bad;
-			break;
-		case TIFFTAG_STRIPBYTECOUNTS:
-		case TIFFTAG_TILEBYTECOUNTS:
-			if (!TIFFFetchStripThing(tif, dp,
-			    td->td_nstrips, &td->td_stripbytecount))
-				goto bad;
-			break;
-		case TIFFTAG_COLORMAP:
-		case TIFFTAG_TRANSFERFUNCTION:
-			{
-				char* cp;
-				/*
-				 * TransferFunction can have either 1x or 3x
-				 * data values; Colormap can have only 3x
-				 * items.
-				 */
-				v = 1L<<td->td_bitspersample;
-				if (dp->tdir_tag == TIFFTAG_COLORMAP ||
-				    dp->tdir_count != v) {
-					if (!CheckDirCount(tif, dp, 3 * v))
-						break;
-				}
-				v *= sizeof(uint16);
-				cp = (char *)_TIFFCheckMalloc(tif,
-							      dp->tdir_count,
-							      sizeof (uint16),
-					"to read \"TransferFunction\" tag");
-				if (cp != NULL) {
-					if (TIFFFetchData(tif, dp, cp)) {
-						/*
-						 * This deals with there being
-						 * only one array to apply to
-						 * all samples.
-						 */
-						uint32 c = 1L << td->td_bitspersample;
-						if (dp->tdir_count == c)
-							v = 0L;
-						TIFFSetField(tif, dp->tdir_tag,
-						    cp, cp+v, cp+2*v);
-					}
-					_TIFFfree(cp);
-				}
-				break;
-			}
-		case TIFFTAG_PAGENUMBER:
-		case TIFFTAG_HALFTONEHINTS:
-		case TIFFTAG_YCBCRSUBSAMPLING:
-		case TIFFTAG_DOTRANGE:
-			(void) TIFFFetchShortPair(tif, dp);
-			break;
-		case TIFFTAG_REFERENCEBLACKWHITE:
-			(void) TIFFFetchRefBlackWhite(tif, dp);
-			break;
-/* BEGIN REV 4.0 COMPATIBILITY */
-		case TIFFTAG_OSUBFILETYPE:
-			v = 0L;
-			switch (TIFFExtractData(tif, dp->tdir_type,
-			    dp->tdir_offset)) {
-			case OFILETYPE_REDUCEDIMAGE:
-				v = FILETYPE_REDUCEDIMAGE;
-				break;
-			case OFILETYPE_PAGE:
-				v = FILETYPE_PAGE;
-				break;
-			}
-			if (v)
-				TIFFSetField(tif, TIFFTAG_SUBFILETYPE, v);
-			break;
-/* END REV 4.0 COMPATIBILITY */
-		default:
-			(void) TIFFFetchNormalTag(tif, dp);
-			break;
-		}
-	}
-	/*
-	 * OJPEG hack:
-	 * - If a) compression is OJPEG, and b) photometric tag is missing,
-	 * then we consistently find that photometric should be YCbCr
-	 * - If a) compression is OJPEG, and b) photometric tag says it's RGB,
-	 * then we consistently find that the buggy implementation of the
-	 * buggy compression scheme matches photometric YCbCr instead.
-	 * - If a) compression is OJPEG, and b) bitspersample tag is missing,
-	 * then we consistently find bitspersample should be 8.
-	 * - If a) compression is OJPEG, b) samplesperpixel tag is missing,
-	 * and c) photometric is RGB or YCbCr, then we consistently find
-	 * samplesperpixel should be 3
-	 * - If a) compression is OJPEG, b) samplesperpixel tag is missing,
-	 * and c) photometric is MINISWHITE or MINISBLACK, then we consistently
-	 * find samplesperpixel should be 3
-	 */
-	if (td->td_compression==COMPRESSION_OJPEG)
-	{
-		if (!TIFFFieldSet(tif,FIELD_PHOTOMETRIC))
-		{
-			TIFFWarningExt(tif->tif_clientdata, "TIFFReadDirectory",
-			"Photometric tag is missing, assuming data is YCbCr");
-			if (!TIFFSetField(tif,TIFFTAG_PHOTOMETRIC,PHOTOMETRIC_YCBCR))
-				goto bad;
-		}
-		else if (td->td_photometric==PHOTOMETRIC_RGB)
-		{
-			td->td_photometric=PHOTOMETRIC_YCBCR;
-			TIFFWarningExt(tif->tif_clientdata, "TIFFReadDirectory",
-			"Photometric tag value assumed incorrect, "
-			"assuming data is YCbCr instead of RGB");
-		}
-		if (!TIFFFieldSet(tif,FIELD_BITSPERSAMPLE))
-		{
-			TIFFWarningExt(tif->tif_clientdata,"TIFFReadDirectory",
-		"BitsPerSample tag is missing, assuming 8 bits per sample");
-			if (!TIFFSetField(tif,TIFFTAG_BITSPERSAMPLE,8))
-				goto bad;
-		}
-		if (!TIFFFieldSet(tif,FIELD_SAMPLESPERPIXEL))
-		{
-			if (td->td_photometric==PHOTOMETRIC_RGB)
-			{
-				TIFFWarningExt(tif->tif_clientdata,
-					       "TIFFReadDirectory",
-				"SamplesPerPixel tag is missing, "
-				"assuming correct SamplesPerPixel value is 3");
-				if (!TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,3))
-					goto bad;
-			}
-			if (td->td_photometric==PHOTOMETRIC_YCBCR)
-			{
-				TIFFWarningExt(tif->tif_clientdata,
-					       "TIFFReadDirectory",
-				"SamplesPerPixel tag is missing, "
-				"applying correct SamplesPerPixel value of 3");
-				if (!TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,3))
-					goto bad;
-			}
-			else if ((td->td_photometric==PHOTOMETRIC_MINISWHITE)
-				 || (td->td_photometric==PHOTOMETRIC_MINISBLACK))
-			{
-				/*
-				 * SamplesPerPixel tag is missing, but is not required
-				 * by spec.  Assume correct SamplesPerPixel value of 1.
-				 */
-				if (!TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,1))
-					goto bad;
-			}
-		}
-	}
-	/*
-	 * Verify Palette image has a Colormap.
-	 */
-	if (td->td_photometric == PHOTOMETRIC_PALETTE &&
-	    !TIFFFieldSet(tif, FIELD_COLORMAP)) {
-		if ( tif->tif_dir.td_bitspersample>=8 && tif->tif_dir.td_samplesperpixel==3)
-			tif->tif_dir.td_photometric = PHOTOMETRIC_RGB;
-		else if (tif->tif_dir.td_bitspersample>=8)
-			tif->tif_dir.td_photometric = PHOTOMETRIC_MINISBLACK;
-		else {
-			MissingRequired(tif, "Colormap");
-			goto bad;
-		}
-	}
-	/*
-	 * OJPEG hack:
-	 * We do no further messing with strip/tile offsets/bytecounts in OJPEG
-	 * TIFFs
-	 */
-	if (td->td_compression!=COMPRESSION_OJPEG)
-	{
-		/*
-		 * Attempt to deal with a missing StripByteCounts tag.
-		 */
-		if (!TIFFFieldSet(tif, FIELD_STRIPBYTECOUNTS)) {
-			/*
-			 * Some manufacturers violate the spec by not giving
-			 * the size of the strips.  In this case, assume there
-			 * is one uncompressed strip of data.
-			 */
-			if ((td->td_planarconfig == PLANARCONFIG_CONTIG &&
-			    td->td_nstrips > 1) ||
-			    (td->td_planarconfig == PLANARCONFIG_SEPARATE &&
-			     td->td_nstrips != td->td_samplesperpixel)) {
-			    MissingRequired(tif, "StripByteCounts");
-			    goto bad;
-			}
-			TIFFWarningExt(tif->tif_clientdata, module,
-				"%s: TIFF directory is missing required "
-				"\"%s\" field, calculating from imagelength",
-				tif->tif_name,
-				_TIFFFieldWithTag(tif,TIFFTAG_STRIPBYTECOUNTS)->field_name);
-			if (EstimateStripByteCounts(tif, dir, dircount) < 0)
-			    goto bad;
-		/*
-		 * Assume we have wrong StripByteCount value (in case
-		 * of single strip) in following cases:
-		 *   - it is equal to zero along with StripOffset;
-		 *   - it is larger than file itself (in case of uncompressed
-		 *     image);
-		 *   - it is smaller than the size of the bytes per row
-		 *     multiplied on the number of rows.  The last case should
-		 *     not be checked in the case of writing new image,
-		 *     because we may do not know the exact strip size
-		 *     until the whole image will be written and directory
-		 *     dumped out.
-		 */
-		#define	BYTECOUNTLOOKSBAD \
-		    ( (td->td_stripbytecount[0] == 0 && td->td_stripoffset[0] != 0) || \
-		      (td->td_compression == COMPRESSION_NONE && \
-		       td->td_stripbytecount[0] > TIFFGetFileSize(tif) - td->td_stripoffset[0]) || \
-		      (tif->tif_mode == O_RDONLY && \
-		       td->td_compression == COMPRESSION_NONE && \
-		       td->td_stripbytecount[0] < TIFFScanlineSize(tif) * td->td_imagelength) )
-
-		} else if (td->td_nstrips == 1
-			   && td->td_stripoffset[0] != 0
-			   && BYTECOUNTLOOKSBAD) {
-			/*
-			 * XXX: Plexus (and others) sometimes give a value of
-			 * zero for a tag when they don't know what the
-			 * correct value is!  Try and handle the simple case
-			 * of estimating the size of a one strip image.
-			 */
-			TIFFWarningExt(tif->tif_clientdata, module,
-	"%s: Bogus \"%s\" field, ignoring and calculating from imagelength",
-				    tif->tif_name,
-				    _TIFFFieldWithTag(tif,TIFFTAG_STRIPBYTECOUNTS)->field_name);
-			if(EstimateStripByteCounts(tif, dir, dircount) < 0)
-			    goto bad;
-		} else if (td->td_planarconfig == PLANARCONFIG_CONTIG
-			   && td->td_nstrips > 2
-			   && td->td_compression == COMPRESSION_NONE
-			   && td->td_stripbytecount[0] != td->td_stripbytecount[1]
-                           && td->td_stripbytecount[0] != 0 
-                           && td->td_stripbytecount[1] != 0 ) {
-			/*
-			 * XXX: Some vendors fill StripByteCount array with 
-                         * absolutely wrong values (it can be equal to 
-                         * StripOffset array, for example). Catch this case 
-                         * here.
-			 */
-			TIFFWarningExt(tif->tif_clientdata, module,
-	"%s: Wrong \"%s\" field, ignoring and calculating from imagelength",
-				    tif->tif_name,
-				    _TIFFFieldWithTag(tif,TIFFTAG_STRIPBYTECOUNTS)->field_name);
-			if (EstimateStripByteCounts(tif, dir, dircount) < 0)
-			    goto bad;
-		}
-	}
-	if (dir) {
-		_TIFFfree((char *)dir);
-		dir = NULL;
-	}
-	if (!TIFFFieldSet(tif, FIELD_MAXSAMPLEVALUE))
-		td->td_maxsamplevalue = (uint16)((1L<<td->td_bitspersample)-1);
-	/*
-	 * Setup default compression scheme.
-	 */
-
-	/*
-	 * XXX: We can optimize checking for the strip bounds using the sorted
-	 * bytecounts array. See also comments for TIFFAppendToStrip()
-	 * function in tif_write.c.
-	 */
-	if (td->td_nstrips > 1) {
-		tstrip_t strip;
-
-		td->td_stripbytecountsorted = 1;
-		for (strip = 1; strip < td->td_nstrips; strip++) {
-			if (td->td_stripoffset[strip - 1] >
-			    td->td_stripoffset[strip]) {
-				td->td_stripbytecountsorted = 0;
-				break;
-			}
-		}
-	}
-
-	if (!TIFFFieldSet(tif, FIELD_COMPRESSION))
-		TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
-	/*
-	 * Some manufacturers make life difficult by writing
-	 * large amounts of uncompressed data as a single strip.
-	 * This is contrary to the recommendations of the spec.
-	 * The following makes an attempt at breaking such images
-	 * into strips closer to the recommended 8k bytes.  A
-	 * side effect, however, is that the RowsPerStrip tag
-	 * value may be changed.
-	 */
-	if (td->td_nstrips == 1 && td->td_compression == COMPRESSION_NONE &&
-	    (tif->tif_flags & (TIFF_STRIPCHOP|TIFF_ISTILED)) == TIFF_STRIPCHOP)
-		ChopUpSingleUncompressedStrip(tif);
-
-	/*
-	 * Reinitialize i/o since we are starting on a new directory.
-	 */
-	tif->tif_row = (uint32) -1;
-	tif->tif_curstrip = (tstrip_t) -1;
-	tif->tif_col = (uint32) -1;
-	tif->tif_curtile = (ttile_t) -1;
-	tif->tif_tilesize = (tsize_t) -1;
-
-	tif->tif_scanlinesize = TIFFScanlineSize(tif);
-	if (!tif->tif_scanlinesize) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-			     "%s: cannot handle zero scanline size",
-			     tif->tif_name);
-		return (0);
-	}
-
-	if (isTiled(tif)) {
-		tif->tif_tilesize = TIFFTileSize(tif);
-		if (!tif->tif_tilesize) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-				     "%s: cannot handle zero tile size",
-				     tif->tif_name);
-			return (0);
-		}
-	} else {
-		if (!TIFFStripSize(tif)) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-				     "%s: cannot handle zero strip size",
-				     tif->tif_name);
-			return (0);
-		}
-	}
-	return (1);
-bad:
-	if (dir)
-		_TIFFfree(dir);
-	return (0);
-}
-
-static TIFFDirEntry*
-TIFFReadDirectoryFind(TIFFDirEntry* dir, uint16 dircount, uint16 tagid)
-{
-	TIFFDirEntry* m;
-	uint16 n;
-	for (m=dir, n=0; n<dircount; m++, n++)
-	{
-		if (m->tdir_tag==tagid)
-			return(m);
-	}
-	return(0);
-}
-
-/*
- * Read custom directory from the arbitarry offset.
- * The code is very similar to TIFFReadDirectory().
- */
-int
-TIFFReadCustomDirectory(TIFF* tif, toff_t diroff,
-			const TIFFFieldInfo info[], size_t n)
-{
-	static const char module[] = "TIFFReadCustomDirectory";
-
-	TIFFDirectory* td = &tif->tif_dir;
-	TIFFDirEntry *dp, *dir = NULL;
-	const TIFFFieldInfo* fip;
-	size_t fix;
-	uint16 i, dircount;
-
-	_TIFFSetupFieldInfo(tif, info, n);
-
-	dircount = TIFFFetchDirectory(tif, diroff, &dir, NULL);
-	if (!dircount) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-			"%s: Failed to read custom directory at offset %u",
-			     tif->tif_name, diroff);
-		return 0;
-	}
-
-	TIFFFreeDirectory(tif);
-        _TIFFmemset(&tif->tif_dir, 0, sizeof(TIFFDirectory));
-
-	fix = 0;
-	for (dp = dir, i = dircount; i > 0; i--, dp++) {
-		if (tif->tif_flags & TIFF_SWAB) {
-			TIFFSwabArrayOfShort(&dp->tdir_tag, 2);
-			TIFFSwabArrayOfLong(&dp->tdir_count, 2);
-		}
-
-		if (fix >= tif->tif_nfields || dp->tdir_tag == IGNORE)
-			continue;
-
-		while (fix < tif->tif_nfields &&
-		       tif->tif_fieldinfo[fix]->field_tag < dp->tdir_tag)
-			fix++;
-
-		if (fix >= tif->tif_nfields ||
-		    tif->tif_fieldinfo[fix]->field_tag != dp->tdir_tag) {
-
-			TIFFWarningExt(tif->tif_clientdata, module,
-                        "%s: unknown field with tag %d (0x%x) encountered",
-				    tif->tif_name, dp->tdir_tag, dp->tdir_tag);
-			if (!_TIFFMergeFieldInfo(tif,
-						 _TIFFCreateAnonFieldInfo(tif,
-						 dp->tdir_tag,
-						 (TIFFDataType) dp->tdir_type),
-						 1))
-			{
-				TIFFWarningExt(tif->tif_clientdata, module,
-			"Registering anonymous field with tag %d (0x%x) failed",
-						dp->tdir_tag, dp->tdir_tag);
-				goto ignore;
-			}
-
-			fix = 0;
-			while (fix < tif->tif_nfields &&
-			       tif->tif_fieldinfo[fix]->field_tag < dp->tdir_tag)
-				fix++;
-		}
-		/*
-		 * Null out old tags that we ignore.
-		 */
-		if (tif->tif_fieldinfo[fix]->field_bit == FIELD_IGNORE) {
-	ignore:
-			dp->tdir_tag = IGNORE;
-			continue;
-		}
-		/*
-		 * Check data type.
-		 */
-		fip = tif->tif_fieldinfo[fix];
-		while (dp->tdir_type != (unsigned short) fip->field_type
-                       && fix < tif->tif_nfields) {
-			if (fip->field_type == TIFF_ANY)	/* wildcard */
-				break;
-                        fip = tif->tif_fieldinfo[++fix];
-			if (fix >= tif->tif_nfields ||
-			    fip->field_tag != dp->tdir_tag) {
-				TIFFWarningExt(tif->tif_clientdata, module,
-			"%s: wrong data type %d for \"%s\"; tag ignored",
-					    tif->tif_name, dp->tdir_type,
-					    tif->tif_fieldinfo[fix-1]->field_name);
-				goto ignore;
-			}
-		}
-		/*
-		 * Check count if known in advance.
-		 */
-		if (fip->field_readcount != TIFF_VARIABLE
-		    && fip->field_readcount != TIFF_VARIABLE2) {
-			uint32 expected = (fip->field_readcount == TIFF_SPP) ?
-			    (uint32) td->td_samplesperpixel :
-			    (uint32) fip->field_readcount;
-			if (!CheckDirCount(tif, dp, expected))
-				goto ignore;
-		}
-
-		/*
-		 * EXIF tags which need to be specifically processed.
-		 */
-		switch (dp->tdir_tag) {
-			case EXIFTAG_SUBJECTDISTANCE:
-				(void) TIFFFetchSubjectDistance(tif, dp);
-				break;
-			default:
-				(void) TIFFFetchNormalTag(tif, dp);
-				break;
-		}
-	}
-	
-	if (dir)
-		_TIFFfree(dir);
-	return 1;
-}
-
-/*
- * EXIF is important special case of custom IFD, so we have a special
- * function to read it.
- */
-int
-TIFFReadEXIFDirectory(TIFF* tif, toff_t diroff)
-{
-	size_t exifFieldInfoCount;
-	const TIFFFieldInfo *exifFieldInfo =
-		_TIFFGetExifFieldInfo(&exifFieldInfoCount);
-	return TIFFReadCustomDirectory(tif, diroff, exifFieldInfo,
-				       exifFieldInfoCount);
-}
-
-static int
-EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount)
-{
-	static const char module[] = "EstimateStripByteCounts";
-
-	TIFFDirEntry *dp;
-	TIFFDirectory *td = &tif->tif_dir;
-	uint32 strip;
-
-	if (td->td_stripbytecount)
-		_TIFFfree(td->td_stripbytecount);
-	td->td_stripbytecount = (uint32*)
-	    _TIFFCheckMalloc(tif, td->td_nstrips, sizeof (uint32),
-		"for \"StripByteCounts\" array");
-        if( td->td_stripbytecount == NULL )
-            return -1;
-
-	if (td->td_compression != COMPRESSION_NONE) {
-		uint32 space = (uint32)(sizeof (TIFFHeader)
-		    + sizeof (uint16)
-		    + (dircount * sizeof (TIFFDirEntry))
-		    + sizeof (uint32));
-		toff_t filesize = TIFFGetFileSize(tif);
-		uint16 n;
-
-		/* calculate amount of space used by indirect values */
-		for (dp = dir, n = dircount; n > 0; n--, dp++)
-		{
-			uint32 cc = TIFFDataWidth((TIFFDataType) dp->tdir_type);
-			if (cc == 0) {
-				TIFFErrorExt(tif->tif_clientdata, module,
-			"%s: Cannot determine size of unknown tag type %d",
-					  tif->tif_name, dp->tdir_type);
-				return -1;
-			}
-			cc = cc * dp->tdir_count;
-			if (cc > sizeof (uint32))
-				space += cc;
-		}
-		space = filesize - space;
-		if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
-			space /= td->td_samplesperpixel;
-		for (strip = 0; strip < td->td_nstrips; strip++)
-			td->td_stripbytecount[strip] = space;
-		/*
-		 * This gross hack handles the case were the offset to
-		 * the last strip is past the place where we think the strip
-		 * should begin.  Since a strip of data must be contiguous,
-		 * it's safe to assume that we've overestimated the amount
-		 * of data in the strip and trim this number back accordingly.
-		 */ 
-		strip--;
-		if (((toff_t)(td->td_stripoffset[strip]+
-			      td->td_stripbytecount[strip])) > filesize)
-			td->td_stripbytecount[strip] =
-			    filesize - td->td_stripoffset[strip];
-	} else if (isTiled(tif)) {
-		uint32 bytespertile = TIFFTileSize(tif);
-
-		for (strip = 0; strip < td->td_nstrips; strip++)
-                    td->td_stripbytecount[strip] = bytespertile;
-	} else {
-		uint32 rowbytes = TIFFScanlineSize(tif);
-		uint32 rowsperstrip = td->td_imagelength/td->td_stripsperimage;
-		for (strip = 0; strip < td->td_nstrips; strip++)
-			td->td_stripbytecount[strip] = rowbytes * rowsperstrip;
-	}
-	TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
-	if (!TIFFFieldSet(tif, FIELD_ROWSPERSTRIP))
-		td->td_rowsperstrip = td->td_imagelength;
-	return 1;
-}
-
-static void
-MissingRequired(TIFF* tif, const char* tagname)
-{
-	static const char module[] = "MissingRequired";
-
-	TIFFErrorExt(tif->tif_clientdata, module,
-		  "%s: TIFF directory is missing required \"%s\" field",
-		  tif->tif_name, tagname);
-}
-
-/*
- * Check the directory offset against the list of already seen directory
- * offsets. This is a trick to prevent IFD looping. The one can create TIFF
- * file with looped directory pointers. We will maintain a list of already
- * seen directories and check every IFD offset against that list.
- */
-static int
-TIFFCheckDirOffset(TIFF* tif, toff_t diroff)
-{
-	uint16 n;
-
-	if (diroff == 0)			/* no more directories */
-		return 0;
-
-	for (n = 0; n < tif->tif_dirnumber && tif->tif_dirlist; n++) {
-		if (tif->tif_dirlist[n] == diroff)
-			return 0;
-	}
-
-	tif->tif_dirnumber++;
-
-	if (tif->tif_dirnumber > tif->tif_dirlistsize) {
-		toff_t* new_dirlist;
-
-		/*
-		 * XXX: Reduce memory allocation granularity of the dirlist
-		 * array.
-		 */
-		new_dirlist = (toff_t *)_TIFFCheckRealloc(tif,
-							  tif->tif_dirlist,
-							  tif->tif_dirnumber,
-							  2 * sizeof(toff_t),
-							  "for IFD list");
-		if (!new_dirlist)
-			return 0;
-		tif->tif_dirlistsize = 2 * tif->tif_dirnumber;
-		tif->tif_dirlist = new_dirlist;
-	}
-
-	tif->tif_dirlist[tif->tif_dirnumber - 1] = diroff;
-
-	return 1;
-}
-
-/*
- * Check the count field of a directory entry against a known value.  The
- * caller is expected to skip/ignore the tag if there is a mismatch.
- */
-static int
-CheckDirCount(TIFF* tif, TIFFDirEntry* dir, uint32 count)
-{
-	if (count > dir->tdir_count) {
-		TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
-	"incorrect count for field \"%s\" (%u, expecting %u); tag ignored",
-		    _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name,
-		    dir->tdir_count, count);
-		return (0);
-	} else if (count < dir->tdir_count) {
-		TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
-	"incorrect count for field \"%s\" (%u, expecting %u); tag trimmed",
-		    _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name,
-		    dir->tdir_count, count);
-		dir->tdir_count = count;
-		return (1);
-	}
-	return (1);
-}
-
-/*
- * Read IFD structure from the specified offset. If the pointer to
- * nextdiroff variable has been specified, read it too. Function returns a
- * number of fields in the directory or 0 if failed.
- */
-static uint16
-TIFFFetchDirectory(TIFF* tif, toff_t diroff, TIFFDirEntry **pdir,
-		   toff_t *nextdiroff)
-{
-	static const char module[] = "TIFFFetchDirectory";
-
-	TIFFDirEntry *dir;
-	uint16 dircount;
-
-	assert(pdir);
-
-	tif->tif_diroff = diroff;
-	if (nextdiroff)
-		*nextdiroff = 0;
-	if (!isMapped(tif)) {
-		if (!SeekOK(tif, tif->tif_diroff)) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-				"%s: Seek error accessing TIFF directory",
-				tif->tif_name);
-			return 0;
-		}
-		if (!ReadOK(tif, &dircount, sizeof (uint16))) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-				"%s: Can not read TIFF directory count",
-				tif->tif_name);
-			return 0;
-		}
-		if (tif->tif_flags & TIFF_SWAB)
-			TIFFSwabShort(&dircount);
-		dir = (TIFFDirEntry *)_TIFFCheckMalloc(tif, dircount,
-						sizeof (TIFFDirEntry),
-						"to read TIFF directory");
-		if (dir == NULL)
-			return 0;
-		if (!ReadOK(tif, dir, dircount*sizeof (TIFFDirEntry))) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-				"%.100s: Can not read TIFF directory",
-				tif->tif_name);
-			_TIFFfree(dir);
-			return 0;
-		}
-		/*
-		 * Read offset to next directory for sequential scans if
-		 * needed.
-		 */
-		if (nextdiroff)
-			(void) ReadOK(tif, nextdiroff, sizeof(uint32));
-	} else {
-		toff_t off = tif->tif_diroff;
-
-		/*
-		 * Check for integer overflow when validating the dir_off,
-		 * otherwise a very high offset may cause an OOB read and
-		 * crash the client. Make two comparisons instead of
-		 *
-		 *  off + sizeof(uint16) > tif->tif_size
-		 *
-		 * to avoid overflow.
-		 */
-		if (tif->tif_size < sizeof (uint16) ||
-		    off > tif->tif_size - sizeof(uint16)) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-				"%s: Can not read TIFF directory count",
-				tif->tif_name);
-			return 0;
-		} else {
-			_TIFFmemcpy(&dircount, tif->tif_base + off,
-				    sizeof(uint16));
-		}
-		off += sizeof (uint16);
-		if (tif->tif_flags & TIFF_SWAB)
-			TIFFSwabShort(&dircount);
-		dir = (TIFFDirEntry *)_TIFFCheckMalloc(tif, dircount,
-						sizeof(TIFFDirEntry),
-						"to read TIFF directory");
-		if (dir == NULL)
-			return 0;
-		if (off + dircount * sizeof (TIFFDirEntry) > tif->tif_size) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-				     "%s: Can not read TIFF directory",
-				     tif->tif_name);
-			_TIFFfree(dir);
-			return 0;
-		} else {
-			_TIFFmemcpy(dir, tif->tif_base + off,
-				    dircount * sizeof(TIFFDirEntry));
-		}
-		if (nextdiroff) {
-			off += dircount * sizeof (TIFFDirEntry);
-			if (off + sizeof (uint32) <= tif->tif_size) {
-				_TIFFmemcpy(nextdiroff, tif->tif_base + off,
-					    sizeof (uint32));
-			}
-		}
-	}
-	if (nextdiroff && tif->tif_flags & TIFF_SWAB)
-		TIFFSwabLong(nextdiroff);
-	*pdir = dir;
-	return dircount;
-}
-
-/*
- * Fetch a contiguous directory item.
- */
-static tsize_t
-TIFFFetchData(TIFF* tif, TIFFDirEntry* dir, char* cp)
-{
-	uint32 w = TIFFDataWidth((TIFFDataType) dir->tdir_type);
-	/* 
-	 * FIXME: butecount should have tsize_t type, but for now libtiff
-	 * defines tsize_t as a signed 32-bit integer and we are losing
-	 * ability to read arrays larger than 2^31 bytes. So we are using
-	 * uint32 instead of tsize_t here.
-	 */
-	uint32 cc = dir->tdir_count * w;
-
-	/* Check for overflow. */
-	if (!dir->tdir_count || !w || cc / w != dir->tdir_count)
-		goto bad;
-
-	if (!isMapped(tif)) {
-		if (!SeekOK(tif, dir->tdir_offset))
-			goto bad;
-		if (!ReadOK(tif, cp, cc))
-			goto bad;
-	} else {
-		/* Check for overflow. */
-		if (dir->tdir_offset + cc < dir->tdir_offset
-		    || dir->tdir_offset + cc < cc
-		    || dir->tdir_offset + cc > tif->tif_size)
-			goto bad;
-		_TIFFmemcpy(cp, tif->tif_base + dir->tdir_offset, cc);
-	}
-	if (tif->tif_flags & TIFF_SWAB) {
-		switch (dir->tdir_type) {
-		case TIFF_SHORT:
-		case TIFF_SSHORT:
-			TIFFSwabArrayOfShort((uint16*) cp, dir->tdir_count);
-			break;
-		case TIFF_LONG:
-		case TIFF_SLONG:
-		case TIFF_FLOAT:
-			TIFFSwabArrayOfLong((uint32*) cp, dir->tdir_count);
-			break;
-		case TIFF_RATIONAL:
-		case TIFF_SRATIONAL:
-			TIFFSwabArrayOfLong((uint32*) cp, 2*dir->tdir_count);
-			break;
-		case TIFF_DOUBLE:
-			TIFFSwabArrayOfDouble((double*) cp, dir->tdir_count);
-			break;
-		}
-	}
-	return (cc);
-bad:
-	TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-		     "Error fetching data for field \"%s\"",
-		     _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
-	return (tsize_t) 0;
-}
-
-/*
- * Fetch an ASCII item from the file.
- */
-static tsize_t
-TIFFFetchString(TIFF* tif, TIFFDirEntry* dir, char* cp)
-{
-	if (dir->tdir_count <= 4) {
-		uint32 l = dir->tdir_offset;
-		if (tif->tif_flags & TIFF_SWAB)
-			TIFFSwabLong(&l);
-		_TIFFmemcpy(cp, &l, dir->tdir_count);
-		return (1);
-	}
-	return (TIFFFetchData(tif, dir, cp));
-}
-
-/*
- * Convert numerator+denominator to float.
- */
-static int
-cvtRational(TIFF* tif, TIFFDirEntry* dir, uint32 num, uint32 denom, float* rv)
-{
-	if (denom == 0) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-		    "%s: Rational with zero denominator (num = %u)",
-		    _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name, num);
-		return (0);
-	} else {
-		if (dir->tdir_type == TIFF_RATIONAL)
-			*rv = ((float)num / (float)denom);
-		else
-			*rv = ((float)(int32)num / (float)(int32)denom);
-		return (1);
-	}
-}
-
-/*
- * Fetch a rational item from the file at offset off and return the value as a
- * floating point number.
- */
-static float
-TIFFFetchRational(TIFF* tif, TIFFDirEntry* dir)
-{
-	uint32 l[2];
-	float v;
-
-	return (!TIFFFetchData(tif, dir, (char *)l) ||
-	    !cvtRational(tif, dir, l[0], l[1], &v) ? 1.0f : v);
-}
-
-/*
- * Fetch a single floating point value from the offset field and return it as
- * a native float.
- */
-static float
-TIFFFetchFloat(TIFF* tif, TIFFDirEntry* dir)
-{
-	float v;
-	int32 l = TIFFExtractData(tif, dir->tdir_type, dir->tdir_offset);
-        _TIFFmemcpy(&v, &l, sizeof(float));
-	TIFFCvtIEEEFloatToNative(tif, 1, &v);
-	return (v);
-}
-
-/*
- * Fetch an array of BYTE or SBYTE values.
- */
-static int
-TIFFFetchByteArray(TIFF* tif, TIFFDirEntry* dir, uint8* v)
-{
-    if (dir->tdir_count <= 4) {
-        /*
-         * Extract data from offset field.
-         */
-        if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) {
-	    if (dir->tdir_type == TIFF_SBYTE)
-                switch (dir->tdir_count) {
-                    case 4: v[3] = dir->tdir_offset & 0xff;
-                    case 3: v[2] = (dir->tdir_offset >> 8) & 0xff;
-                    case 2: v[1] = (dir->tdir_offset >> 16) & 0xff;
-		    case 1: v[0] = dir->tdir_offset >> 24;
-                }
-	    else
-                switch (dir->tdir_count) {
-                    case 4: v[3] = dir->tdir_offset & 0xff;
-                    case 3: v[2] = (dir->tdir_offset >> 8) & 0xff;
-                    case 2: v[1] = (dir->tdir_offset >> 16) & 0xff;
-		    case 1: v[0] = dir->tdir_offset >> 24;
-                }
-	} else {
-	    if (dir->tdir_type == TIFF_SBYTE)
-                switch (dir->tdir_count) {
-                    case 4: v[3] = dir->tdir_offset >> 24;
-                    case 3: v[2] = (dir->tdir_offset >> 16) & 0xff;
-                    case 2: v[1] = (dir->tdir_offset >> 8) & 0xff;
-                    case 1: v[0] = dir->tdir_offset & 0xff;
-		}
-	    else
-                switch (dir->tdir_count) {
-                    case 4: v[3] = dir->tdir_offset >> 24;
-                    case 3: v[2] = (dir->tdir_offset >> 16) & 0xff;
-                    case 2: v[1] = (dir->tdir_offset >> 8) & 0xff;
-                    case 1: v[0] = dir->tdir_offset & 0xff;
-		}
-	}
-        return (1);
-    } else
-        return (TIFFFetchData(tif, dir, (char*) v) != 0);	/* XXX */
-}
-
-/*
- * Fetch an array of SHORT or SSHORT values.
- */
-static int
-TIFFFetchShortArray(TIFF* tif, TIFFDirEntry* dir, uint16* v)
-{
-	if (dir->tdir_count <= 2) {
-		if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) {
-			switch (dir->tdir_count) {
-			case 2: v[1] = (uint16) (dir->tdir_offset & 0xffff);
-			case 1: v[0] = (uint16) (dir->tdir_offset >> 16);
-			}
-		} else {
-			switch (dir->tdir_count) {
-			case 2: v[1] = (uint16) (dir->tdir_offset >> 16);
-			case 1: v[0] = (uint16) (dir->tdir_offset & 0xffff);
-			}
-		}
-		return (1);
-	} else
-		return (TIFFFetchData(tif, dir, (char *)v) != 0);
-}
-
-/*
- * Fetch a pair of SHORT or BYTE values. Some tags may have either BYTE
- * or SHORT type and this function works with both ones.
- */
-static int
-TIFFFetchShortPair(TIFF* tif, TIFFDirEntry* dir)
-{
-	/*
-	 * Prevent overflowing the v stack arrays below by performing a sanity
-	 * check on tdir_count, this should never be greater than two.
-	 */
-	if (dir->tdir_count > 2) {
-		TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
-		"unexpected count for field \"%s\", %u, expected 2; ignored",
-			_TIFFFieldWithTag(tif, dir->tdir_tag)->field_name,
-			dir->tdir_count);
-		return 0;
-	}
-
-	switch (dir->tdir_type) {
-		case TIFF_BYTE:
-		case TIFF_SBYTE:
-			{
-			uint8 v[4];
-			return TIFFFetchByteArray(tif, dir, v)
-				&& TIFFSetField(tif, dir->tdir_tag, v[0], v[1]);
-			}
-		case TIFF_SHORT:
-		case TIFF_SSHORT:
-			{
-			uint16 v[2];
-			return TIFFFetchShortArray(tif, dir, v)
-				&& TIFFSetField(tif, dir->tdir_tag, v[0], v[1]);
-			}
-		default:
-			return 0;
-	}
-}
-
-/*
- * Fetch an array of LONG or SLONG values.
- */
-static int
-TIFFFetchLongArray(TIFF* tif, TIFFDirEntry* dir, uint32* v)
-{
-	if (dir->tdir_count == 1) {
-		v[0] = dir->tdir_offset;
-		return (1);
-	} else
-		return (TIFFFetchData(tif, dir, (char*) v) != 0);
-}
-
-/*
- * Fetch an array of RATIONAL or SRATIONAL values.
- */
-static int
-TIFFFetchRationalArray(TIFF* tif, TIFFDirEntry* dir, float* v)
-{
-	int ok = 0;
-	uint32* l;
-
-	l = (uint32*)_TIFFCheckMalloc(tif,
-	    dir->tdir_count, TIFFDataWidth((TIFFDataType) dir->tdir_type),
-	    "to fetch array of rationals");
-	if (l) {
-		if (TIFFFetchData(tif, dir, (char *)l)) {
-			uint32 i;
-			for (i = 0; i < dir->tdir_count; i++) {
-				ok = cvtRational(tif, dir,
-				    l[2*i+0], l[2*i+1], &v[i]);
-				if (!ok)
-					break;
-			}
-		}
-		_TIFFfree((char *)l);
-	}
-	return (ok);
-}
-
-/*
- * Fetch an array of FLOAT values.
- */
-static int
-TIFFFetchFloatArray(TIFF* tif, TIFFDirEntry* dir, float* v)
-{
-
-	if (dir->tdir_count == 1) {
-	        union
-		{
-		  float  f;
-		  uint32 i;
-		} float_union;
-
-		float_union.i=dir->tdir_offset;
-		v[0]=float_union.f;
-		TIFFCvtIEEEFloatToNative(tif, dir->tdir_count, v);
-		return (1);
-	} else	if (TIFFFetchData(tif, dir, (char*) v)) {
-		TIFFCvtIEEEFloatToNative(tif, dir->tdir_count, v);
-		return (1);
-	} else
-		return (0);
-}
-
-/*
- * Fetch an array of DOUBLE values.
- */
-static int
-TIFFFetchDoubleArray(TIFF* tif, TIFFDirEntry* dir, double* v)
-{
-	if (TIFFFetchData(tif, dir, (char*) v)) {
-		TIFFCvtIEEEDoubleToNative(tif, dir->tdir_count, v);
-		return (1);
-	} else
-		return (0);
-}
-
-/*
- * Fetch an array of ANY values.  The actual values are returned as doubles
- * which should be able hold all the types.  Yes, there really should be an
- * tany_t to avoid this potential non-portability ...  Note in particular that
- * we assume that the double return value vector is large enough to read in
- * any fundamental type.  We use that vector as a buffer to read in the base
- * type vector and then convert it in place to double (from end to front of
- * course).
- */
-static int
-TIFFFetchAnyArray(TIFF* tif, TIFFDirEntry* dir, double* v)
-{
-	int i;
-
-	switch (dir->tdir_type) {
-	case TIFF_BYTE:
-	case TIFF_SBYTE:
-		if (!TIFFFetchByteArray(tif, dir, (uint8*) v))
-			return (0);
-		if (dir->tdir_type == TIFF_BYTE) {
-			uint8* vp = (uint8*) v;
-			for (i = dir->tdir_count-1; i >= 0; i--)
-				v[i] = vp[i];
-		} else {
-			int8* vp = (int8*) v;
-			for (i = dir->tdir_count-1; i >= 0; i--)
-				v[i] = vp[i];
-		}
-		break;
-	case TIFF_SHORT:
-	case TIFF_SSHORT:
-		if (!TIFFFetchShortArray(tif, dir, (uint16*) v))
-			return (0);
-		if (dir->tdir_type == TIFF_SHORT) {
-			uint16* vp = (uint16*) v;
-			for (i = dir->tdir_count-1; i >= 0; i--)
-				v[i] = vp[i];
-		} else {
-			int16* vp = (int16*) v;
-			for (i = dir->tdir_count-1; i >= 0; i--)
-				v[i] = vp[i];
-		}
-		break;
-	case TIFF_LONG:
-	case TIFF_SLONG:
-		if (!TIFFFetchLongArray(tif, dir, (uint32*) v))
-			return (0);
-		if (dir->tdir_type == TIFF_LONG) {
-			uint32* vp = (uint32*) v;
-			for (i = dir->tdir_count-1; i >= 0; i--)
-				v[i] = vp[i];
-		} else {
-			int32* vp = (int32*) v;
-			for (i = dir->tdir_count-1; i >= 0; i--)
-				v[i] = vp[i];
-		}
-		break;
-	case TIFF_RATIONAL:
-	case TIFF_SRATIONAL:
-		if (!TIFFFetchRationalArray(tif, dir, (float*) v))
-			return (0);
-		{ float* vp = (float*) v;
-		  for (i = dir->tdir_count-1; i >= 0; i--)
-			v[i] = vp[i];
-		}
-		break;
-	case TIFF_FLOAT:
-		if (!TIFFFetchFloatArray(tif, dir, (float*) v))
-			return (0);
-		{ float* vp = (float*) v;
-		  for (i = dir->tdir_count-1; i >= 0; i--)
-			v[i] = vp[i];
-		}
-		break;
-	case TIFF_DOUBLE:
-		return (TIFFFetchDoubleArray(tif, dir, (double*) v));
-	default:
-		/* TIFF_NOTYPE */
-		/* TIFF_ASCII */
-		/* TIFF_UNDEFINED */
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			     "cannot read TIFF_ANY type %d for field \"%s\"",
-			     dir->tdir_type,
-			     _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
-		return (0);
-	}
-	return (1);
-}
-
-/*
- * Fetch a tag that is not handled by special case code.
- */
-static int
-TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp)
-{
-	static const char mesg[] = "to fetch tag value";
-	int ok = 0;
-	const TIFFFieldInfo* fip = _TIFFFieldWithTag(tif, dp->tdir_tag);
-
-	if (dp->tdir_count > 1) {		/* array of values */
-		char* cp = NULL;
-
-		switch (dp->tdir_type) {
-		case TIFF_BYTE:
-		case TIFF_SBYTE:
-			cp = (char *)_TIFFCheckMalloc(tif,
-			    dp->tdir_count, sizeof (uint8), mesg);
-			ok = cp && TIFFFetchByteArray(tif, dp, (uint8*) cp);
-			break;
-		case TIFF_SHORT:
-		case TIFF_SSHORT:
-			cp = (char *)_TIFFCheckMalloc(tif,
-			    dp->tdir_count, sizeof (uint16), mesg);
-			ok = cp && TIFFFetchShortArray(tif, dp, (uint16*) cp);
-			break;
-		case TIFF_LONG:
-		case TIFF_SLONG:
-			cp = (char *)_TIFFCheckMalloc(tif,
-			    dp->tdir_count, sizeof (uint32), mesg);
-			ok = cp && TIFFFetchLongArray(tif, dp, (uint32*) cp);
-			break;
-		case TIFF_RATIONAL:
-		case TIFF_SRATIONAL:
-			cp = (char *)_TIFFCheckMalloc(tif,
-			    dp->tdir_count, sizeof (float), mesg);
-			ok = cp && TIFFFetchRationalArray(tif, dp, (float*) cp);
-			break;
-		case TIFF_FLOAT:
-			cp = (char *)_TIFFCheckMalloc(tif,
-			    dp->tdir_count, sizeof (float), mesg);
-			ok = cp && TIFFFetchFloatArray(tif, dp, (float*) cp);
-			break;
-		case TIFF_DOUBLE:
-			cp = (char *)_TIFFCheckMalloc(tif,
-			    dp->tdir_count, sizeof (double), mesg);
-			ok = cp && TIFFFetchDoubleArray(tif, dp, (double*) cp);
-			break;
-		case TIFF_ASCII:
-		case TIFF_UNDEFINED:		/* bit of a cheat... */
-			/*
-			 * Some vendors write strings w/o the trailing
-			 * NULL byte, so always append one just in case.
-			 */
-			cp = (char *)_TIFFCheckMalloc(tif, dp->tdir_count + 1,
-						      1, mesg);
-			if( (ok = (cp && TIFFFetchString(tif, dp, cp))) != 0 )
-				cp[dp->tdir_count] = '\0';	/* XXX */
-			break;
-		}
-		if (ok) {
-			ok = (fip->field_passcount ?
-			    TIFFSetField(tif, dp->tdir_tag, dp->tdir_count, cp)
-			  : TIFFSetField(tif, dp->tdir_tag, cp));
-		}
-		if (cp != NULL)
-			_TIFFfree(cp);
-	} else if (CheckDirCount(tif, dp, 1)) {	/* singleton value */
-		switch (dp->tdir_type) {
-		case TIFF_BYTE:
-		case TIFF_SBYTE:
-		case TIFF_SHORT:
-		case TIFF_SSHORT:
-			/*
-			 * If the tag is also acceptable as a LONG or SLONG
-			 * then TIFFSetField will expect an uint32 parameter
-			 * passed to it (through varargs).  Thus, for machines
-			 * where sizeof (int) != sizeof (uint32) we must do
-			 * a careful check here.  It's hard to say if this
-			 * is worth optimizing.
-			 *
-			 * NB: We use TIFFFieldWithTag here knowing that
-			 *     it returns us the first entry in the table
-			 *     for the tag and that that entry is for the
-			 *     widest potential data type the tag may have.
-			 */
-			{ TIFFDataType type = fip->field_type;
-			  if (type != TIFF_LONG && type != TIFF_SLONG) {
-				uint16 v = (uint16)
-			   TIFFExtractData(tif, dp->tdir_type, dp->tdir_offset);
-				ok = (fip->field_passcount ?
-				    TIFFSetField(tif, dp->tdir_tag, 1, &v)
-				  : TIFFSetField(tif, dp->tdir_tag, v));
-				break;
-			  }
-			}
-			/* fall thru... */
-		case TIFF_LONG:
-		case TIFF_SLONG:
-			{ uint32 v32 =
-		    TIFFExtractData(tif, dp->tdir_type, dp->tdir_offset);
-			  ok = (fip->field_passcount ? 
-			      TIFFSetField(tif, dp->tdir_tag, 1, &v32)
-			    : TIFFSetField(tif, dp->tdir_tag, v32));
-			}
-			break;
-		case TIFF_RATIONAL:
-		case TIFF_SRATIONAL:
-		case TIFF_FLOAT:
-			{ float v = (dp->tdir_type == TIFF_FLOAT ? 
-			      TIFFFetchFloat(tif, dp)
-			    : TIFFFetchRational(tif, dp));
-			  ok = (fip->field_passcount ?
-			      TIFFSetField(tif, dp->tdir_tag, 1, &v)
-			    : TIFFSetField(tif, dp->tdir_tag, v));
-			}
-			break;
-		case TIFF_DOUBLE:
-			{ double v;
-			  ok = (TIFFFetchDoubleArray(tif, dp, &v) &&
-			    (fip->field_passcount ?
-			      TIFFSetField(tif, dp->tdir_tag, 1, &v)
-			    : TIFFSetField(tif, dp->tdir_tag, v))
-			  );
-			}
-			break;
-		case TIFF_ASCII:
-		case TIFF_UNDEFINED:		/* bit of a cheat... */
-			{ char c[2];
-			  if( (ok = (TIFFFetchString(tif, dp, c) != 0)) != 0 ) {
-				c[1] = '\0';		/* XXX paranoid */
-				ok = (fip->field_passcount ?
-					TIFFSetField(tif, dp->tdir_tag, 1, c)
-				      : TIFFSetField(tif, dp->tdir_tag, c));
-			  }
-			}
-			break;
-		}
-	}
-	return (ok);
-}
-
-#define	NITEMS(x)	(sizeof (x) / sizeof (x[0]))
-/*
- * Fetch samples/pixel short values for 
- * the specified tag and verify that
- * all values are the same.
- */
-static int
-TIFFFetchPerSampleShorts(TIFF* tif, TIFFDirEntry* dir, uint16* pl)
-{
-    uint16 samples = tif->tif_dir.td_samplesperpixel;
-    int status = 0;
-
-    if (CheckDirCount(tif, dir, (uint32) samples)) {
-        uint16 buf[10];
-        uint16* v = buf;
-
-        if (dir->tdir_count > NITEMS(buf))
-            v = (uint16*) _TIFFCheckMalloc(tif, dir->tdir_count, sizeof(uint16),
-                                      "to fetch per-sample values");
-        if (v && TIFFFetchShortArray(tif, dir, v)) {
-            uint16 i;
-            int check_count = dir->tdir_count;
-            if( samples < check_count )
-                check_count = samples;
-
-            for (i = 1; i < check_count; i++)
-                if (v[i] != v[0]) {
-			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-                "Cannot handle different per-sample values for field \"%s\"",
-			_TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
-			goto bad;
-                }
-            *pl = v[0];
-            status = 1;
-        }
-      bad:
-        if (v && v != buf)
-            _TIFFfree(v);
-    }
-    return (status);
-}
-
-/*
- * Fetch samples/pixel long values for 
- * the specified tag and verify that
- * all values are the same.
- */
-static int
-TIFFFetchPerSampleLongs(TIFF* tif, TIFFDirEntry* dir, uint32* pl)
-{
-    uint16 samples = tif->tif_dir.td_samplesperpixel;
-    int status = 0;
-
-    if (CheckDirCount(tif, dir, (uint32) samples)) {
-        uint32 buf[10];
-        uint32* v = buf;
-
-        if (dir->tdir_count > NITEMS(buf))
-            v = (uint32*) _TIFFCheckMalloc(tif, dir->tdir_count, sizeof(uint32),
-                                      "to fetch per-sample values");
-        if (v && TIFFFetchLongArray(tif, dir, v)) {
-            uint16 i;
-            int check_count = dir->tdir_count;
-
-            if( samples < check_count )
-                check_count = samples;
-            for (i = 1; i < check_count; i++)
-                if (v[i] != v[0]) {
-			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-                "Cannot handle different per-sample values for field \"%s\"",
-			_TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
-			goto bad;
-                }
-            *pl = v[0];
-            status = 1;
-        }
-      bad:
-        if (v && v != buf)
-            _TIFFfree(v);
-    }
-    return (status);
-}
-
-/*
- * Fetch samples/pixel ANY values for the specified tag and returns their min
- * and max.
- */
-static int
-TIFFFetchPerSampleAnys(TIFF* tif, TIFFDirEntry* dir, double* minv, double* maxv)
-{
-    uint16 samples = tif->tif_dir.td_samplesperpixel;
-    int status = 0;
-
-    if (CheckDirCount(tif, dir, (uint32) samples)) {
-        double buf[10];
-        double* v = buf;
-
-        if (dir->tdir_count > NITEMS(buf))
-            v = (double*) _TIFFCheckMalloc(tif, dir->tdir_count, sizeof (double),
-                                      "to fetch per-sample values");
-        if (v && TIFFFetchAnyArray(tif, dir, v)) {
-            uint16 i;
-            int check_count = dir->tdir_count;
-            if( samples < check_count )
-                check_count = samples;
-
-            *minv = *maxv = v[0];
-            for (i = 1; i < check_count; i++)
-            {
-                if (v[i] < *minv)
-                    *minv = v[i];
-                if (v[i] > *maxv)
-                    *maxv = v[i];
-            }
-            status = 1;
-        }
-        if (v && v != buf)
-            _TIFFfree(v);
-    }
-    return (status);
-}
-#undef NITEMS
-
-/*
- * Fetch a set of offsets or lengths.
- * While this routine says "strips", in fact it's also used for tiles.
- */
-static int
-TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, long nstrips, uint32** lpp)
-{
-	register uint32* lp;
-	int status;
-
-        CheckDirCount(tif, dir, (uint32) nstrips);
-
-	/*
-	 * Allocate space for strip information.
-	 */
-	if (*lpp == NULL &&
-	    (*lpp = (uint32 *)_TIFFCheckMalloc(tif,
-	      nstrips, sizeof (uint32), "for strip array")) == NULL)
-		return (0);
-	lp = *lpp;
-        _TIFFmemset( lp, 0, sizeof(uint32) * nstrips );
-
-	if (dir->tdir_type == (int)TIFF_SHORT) {
-		/*
-		 * Handle uint16->uint32 expansion.
-		 */
-		uint16* dp = (uint16*) _TIFFCheckMalloc(tif,
-		    dir->tdir_count, sizeof (uint16), "to fetch strip tag");
-		if (dp == NULL)
-			return (0);
-		if( (status = TIFFFetchShortArray(tif, dir, dp)) != 0 ) {
-                    int i;
-                    
-                    for( i = 0; i < nstrips && i < (int) dir->tdir_count; i++ )
-                    {
-                        lp[i] = dp[i];
-                    }
-		}
-		_TIFFfree((char*) dp);
-
-        } else if( nstrips != (int) dir->tdir_count ) {
-            /* Special case to correct length */
-
-            uint32* dp = (uint32*) _TIFFCheckMalloc(tif,
-		    dir->tdir_count, sizeof (uint32), "to fetch strip tag");
-            if (dp == NULL)
-                return (0);
-
-            status = TIFFFetchLongArray(tif, dir, dp);
-            if( status != 0 ) {
-                int i;
-
-                for( i = 0; i < nstrips && i < (int) dir->tdir_count; i++ )
-                {
-                    lp[i] = dp[i];
-                }
-            }
-
-            _TIFFfree( (char *) dp );
-	} else
-            status = TIFFFetchLongArray(tif, dir, lp);
-        
-	return (status);
-}
-
-/*
- * Fetch and set the RefBlackWhite tag.
- */
-static int
-TIFFFetchRefBlackWhite(TIFF* tif, TIFFDirEntry* dir)
-{
-	static const char mesg[] = "for \"ReferenceBlackWhite\" array";
-	char* cp;
-	int ok;
-
-	if (dir->tdir_type == TIFF_RATIONAL)
-		return (TIFFFetchNormalTag(tif, dir));
-	/*
-	 * Handle LONG's for backward compatibility.
-	 */
-	cp = (char *)_TIFFCheckMalloc(tif, dir->tdir_count,
-				      sizeof (uint32), mesg);
-	if( (ok = (cp && TIFFFetchLongArray(tif, dir, (uint32*) cp))) != 0) {
-		float* fp = (float*)
-		    _TIFFCheckMalloc(tif, dir->tdir_count, sizeof (float), mesg);
-		if( (ok = (fp != NULL)) != 0 ) {
-			uint32 i;
-			for (i = 0; i < dir->tdir_count; i++)
-				fp[i] = (float)((uint32*) cp)[i];
-			ok = TIFFSetField(tif, dir->tdir_tag, fp);
-			_TIFFfree((char*) fp);
-		}
-	}
-	if (cp)
-		_TIFFfree(cp);
-	return (ok);
-}
-
-/*
- * Fetch and set the SubjectDistance EXIF tag.
- */
-static int
-TIFFFetchSubjectDistance(TIFF* tif, TIFFDirEntry* dir)
-{
-	uint32 l[2];
-	float v;
-	int ok = 0;
-
-    if( dir->tdir_count != 1 || dir->tdir_type != TIFF_RATIONAL )
-    {
-		TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
-                       "incorrect count or type for SubjectDistance, tag ignored" );
-		return (0);
-    }
-
-	if (TIFFFetchData(tif, dir, (char *)l)
-	    && cvtRational(tif, dir, l[0], l[1], &v)) {
-		/*
-		 * XXX: Numerator 0xFFFFFFFF means that we have infinite
-		 * distance. Indicate that with a negative floating point
-		 * SubjectDistance value.
-		 */
-		ok = TIFFSetField(tif, dir->tdir_tag,
-				  (l[0] != 0xFFFFFFFF) ? v : -v);
-	}
-
-	return ok;
-}
-
-/*
- * Replace a single strip (tile) of uncompressed data by multiple strips
- * (tiles), each approximately STRIP_SIZE_DEFAULT bytes. This is useful for
- * dealing with large images or for dealing with machines with a limited
- * amount memory.
- */
-static void
-ChopUpSingleUncompressedStrip(TIFF* tif)
-{
-	register TIFFDirectory *td = &tif->tif_dir;
-	uint32 bytecount = td->td_stripbytecount[0];
-	uint32 offset = td->td_stripoffset[0];
-	tsize_t rowbytes = TIFFVTileSize(tif, 1), stripbytes;
-	tstrip_t strip, nstrips, rowsperstrip;
-	uint32* newcounts;
-	uint32* newoffsets;
-
-	/*
-	 * Make the rows hold at least one scanline, but fill specified amount
-	 * of data if possible.
-	 */
-	if (rowbytes > STRIP_SIZE_DEFAULT) {
-		stripbytes = rowbytes;
-		rowsperstrip = 1;
-	} else if (rowbytes > 0 ) {
-		rowsperstrip = STRIP_SIZE_DEFAULT / rowbytes;
-		stripbytes = rowbytes * rowsperstrip;
-	}
-        else
-            return;
-
-	/* 
-	 * never increase the number of strips in an image
-	 */
-	if (rowsperstrip >= td->td_rowsperstrip)
-		return;
-	nstrips = (tstrip_t) TIFFhowmany(bytecount, stripbytes);
-        if( nstrips == 0 ) /* something is wonky, do nothing. */
-            return;
-
-	newcounts = (uint32*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint32),
-				"for chopped \"StripByteCounts\" array");
-	newoffsets = (uint32*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint32),
-				"for chopped \"StripOffsets\" array");
-	if (newcounts == NULL || newoffsets == NULL) {
-	        /*
-		 * Unable to allocate new strip information, give up and use
-		 * the original one strip information.
-		 */
-		if (newcounts != NULL)
-			_TIFFfree(newcounts);
-		if (newoffsets != NULL)
-			_TIFFfree(newoffsets);
-		return;
-	}
-	/*
-	 * Fill the strip information arrays with new bytecounts and offsets
-	 * that reflect the broken-up format.
-	 */
-	for (strip = 0; strip < nstrips; strip++) {
-		if ((uint32)stripbytes > bytecount)
-			stripbytes = bytecount;
-		newcounts[strip] = stripbytes;
-		newoffsets[strip] = offset;
-		offset += stripbytes;
-		bytecount -= stripbytes;
-	}
-	/*
-	 * Replace old single strip info with multi-strip info.
-	 */
-	td->td_stripsperimage = td->td_nstrips = nstrips;
-	TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
-
-	_TIFFfree(td->td_stripbytecount);
-	_TIFFfree(td->td_stripoffset);
-	td->td_stripbytecount = newcounts;
-	td->td_stripoffset = newoffsets;
-	td->td_stripbytecountsorted = 1;
-}
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_dirwrite.c b/Source/LibTIFF/tif_dirwrite.c
deleted file mode 100644
index 859a51f..0000000
--- a/Source/LibTIFF/tif_dirwrite.c
+++ /dev/null
@@ -1,1436 +0,0 @@
-/* $Id: tif_dirwrite.c,v 1.37 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library.
- *
- * Directory Write Support Routines.
- */
-#include "tiffiop.h"
-
-#ifdef HAVE_IEEEFP
-# define	TIFFCvtNativeToIEEEFloat(tif, n, fp)
-# define	TIFFCvtNativeToIEEEDouble(tif, n, dp)
-#else
-extern	void TIFFCvtNativeToIEEEFloat(TIFF*, uint32, float*);
-extern	void TIFFCvtNativeToIEEEDouble(TIFF*, uint32, double*);
-#endif
-
-static	int TIFFWriteNormalTag(TIFF*, TIFFDirEntry*, const TIFFFieldInfo*);
-static	void TIFFSetupShortLong(TIFF*, ttag_t, TIFFDirEntry*, uint32);
-static	void TIFFSetupShort(TIFF*, ttag_t, TIFFDirEntry*, uint16);
-static	int TIFFSetupBytePair(TIFF*, ttag_t, TIFFDirEntry*);
-static	int TIFFSetupShortPair(TIFF*, ttag_t, TIFFDirEntry*);
-static	int TIFFWritePerSampleShorts(TIFF*, ttag_t, TIFFDirEntry*);
-static	int TIFFWritePerSampleAnys(TIFF*, TIFFDataType, ttag_t, TIFFDirEntry*);
-static	int TIFFWriteShortTable(TIFF*, ttag_t, TIFFDirEntry*, uint32, uint16**);
-static	int TIFFWriteShortArray(TIFF*, TIFFDirEntry*, uint16*);
-static	int TIFFWriteLongArray(TIFF *, TIFFDirEntry*, uint32*);
-static	int TIFFWriteRationalArray(TIFF *, TIFFDirEntry*, float*);
-static	int TIFFWriteFloatArray(TIFF *, TIFFDirEntry*, float*);
-static	int TIFFWriteDoubleArray(TIFF *, TIFFDirEntry*, double*);
-static	int TIFFWriteByteArray(TIFF*, TIFFDirEntry*, char*);
-static	int TIFFWriteAnyArray(TIFF*,
-	    TIFFDataType, ttag_t, TIFFDirEntry*, uint32, double*);
-static	int TIFFWriteTransferFunction(TIFF*, TIFFDirEntry*);
-static	int TIFFWriteInkNames(TIFF*, TIFFDirEntry*);
-static	int TIFFWriteData(TIFF*, TIFFDirEntry*, char*);
-static	int TIFFLinkDirectory(TIFF*);
-
-#define	WriteRationalPair(type, tag1, v1, tag2, v2) {		\
-	TIFFWriteRational((tif), (type), (tag1), (dir), (v1))	\
-	TIFFWriteRational((tif), (type), (tag2), (dir)+1, (v2))	\
-	(dir)++;						\
-}
-#define	TIFFWriteRational(tif, type, tag, dir, v)		\
-	(dir)->tdir_tag = (tag);				\
-	(dir)->tdir_type = (type);				\
-	(dir)->tdir_count = 1;					\
-	if (!TIFFWriteRationalArray((tif), (dir), &(v)))	\
-		goto bad;
-
-/*
- * Write the contents of the current directory
- * to the specified file.  This routine doesn't
- * handle overwriting a directory with auxiliary
- * storage that's been changed.
- */
-static int
-_TIFFWriteDirectory(TIFF* tif, int done)
-{
-	uint16 dircount;
-	toff_t diroff;
-	ttag_t tag;
-	uint32 nfields;
-	tsize_t dirsize;
-	char* data;
-	TIFFDirEntry* dir;
-	TIFFDirectory* td;
-	unsigned long b, fields[FIELD_SETLONGS];
-	int fi, nfi;
-
-	if (tif->tif_mode == O_RDONLY)
-		return (1);
-	/*
-	 * Clear write state so that subsequent images with
-	 * different characteristics get the right buffers
-	 * setup for them.
-	 */
-	if (done)
-	{
-		if (tif->tif_flags & TIFF_POSTENCODE) {
-			tif->tif_flags &= ~TIFF_POSTENCODE;
-			if (!(*tif->tif_postencode)(tif)) {
-				TIFFErrorExt(tif->tif_clientdata,
-					     tif->tif_name,
-				"Error post-encoding before directory write");
-				return (0);
-			}
-		}
-		(*tif->tif_close)(tif);		/* shutdown encoder */
-		/*
-		 * Flush any data that might have been written
- 		 * by the compression close+cleanup routines.
-		 */
-		if (tif->tif_rawcc > 0
-                    && (tif->tif_flags & TIFF_BEENWRITING) != 0
-                    && !TIFFFlushData1(tif)) {
-			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			    "Error flushing data before directory write");
-			return (0);
-		}
-		if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
-			_TIFFfree(tif->tif_rawdata);
-			tif->tif_rawdata = NULL;
-			tif->tif_rawcc = 0;
-			tif->tif_rawdatasize = 0;
-		}
-		tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP);
-	}
-
-	td = &tif->tif_dir;
-	/*
-	 * Size the directory so that we can calculate
-	 * offsets for the data items that aren't kept
-	 * in-place in each field.
-	 */
-	nfields = 0;
-	for (b = 0; b <= FIELD_LAST; b++)
-		if (TIFFFieldSet(tif, b) && b != FIELD_CUSTOM)
-			nfields += (b < FIELD_SUBFILETYPE ? 2 : 1);
-	nfields += td->td_customValueCount;
-	dirsize = nfields * sizeof (TIFFDirEntry);
-	data = (char*) _TIFFmalloc(dirsize);
-	if (data == NULL) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			     "Cannot write directory, out of space");
-		return (0);
-	}
-	/*
-	 * Directory hasn't been placed yet, put
-	 * it at the end of the file and link it
-	 * into the existing directory structure.
-	 */
-	if (tif->tif_diroff == 0 && !TIFFLinkDirectory(tif))
-		goto bad;
-	tif->tif_dataoff = (toff_t)(
-	    tif->tif_diroff + sizeof (uint16) + dirsize + sizeof (toff_t));
-	if (tif->tif_dataoff & 1)
-		tif->tif_dataoff++;
-	(void) TIFFSeekFile(tif, tif->tif_dataoff, SEEK_SET);
-	tif->tif_curdir++;
-	dir = (TIFFDirEntry*) data;
-	/*
-	 * Setup external form of directory
-	 * entries and write data items.
-	 */
-	_TIFFmemcpy(fields, td->td_fieldsset, sizeof (fields));
-	/*
-	 * Write out ExtraSamples tag only if
-	 * extra samples are present in the data.
-	 */
-	if (FieldSet(fields, FIELD_EXTRASAMPLES) && !td->td_extrasamples) {
-		ResetFieldBit(fields, FIELD_EXTRASAMPLES);
-		nfields--;
-		dirsize -= sizeof (TIFFDirEntry);
-	}								/*XXX*/
-	for (fi = 0, nfi = tif->tif_nfields; nfi > 0; nfi--, fi++) {
-		const TIFFFieldInfo* fip = tif->tif_fieldinfo[fi];
-
-		/*
-		 * For custom fields, we test to see if the custom field
-		 * is set or not.  For normal fields, we just use the
-		 * FieldSet test.
-		*/
-		if( fip->field_bit == FIELD_CUSTOM )
-		{
-			int ci, is_set = FALSE;
-
-			for( ci = 0; ci < td->td_customValueCount; ci++ )
-				is_set |= (td->td_customValues[ci].info == fip);
-
-			if( !is_set )
-				continue;
-		}
-		else if (!FieldSet(fields, fip->field_bit))
-			continue;
-
-		/*
-		 * Handle other fields.
-		 */
-		switch (fip->field_bit)
-		{
-		case FIELD_STRIPOFFSETS:
-			/*
-			 * We use one field bit for both strip and tile
-
-			 * offsets, and so must be careful in selecting
-			 * the appropriate field descriptor (so that tags
-			 * are written in sorted order).
-			 */
-			tag = isTiled(tif) ?
-			    TIFFTAG_TILEOFFSETS : TIFFTAG_STRIPOFFSETS;
-			if (tag != fip->field_tag)
-				continue;
-			
-			dir->tdir_tag = (uint16) tag;
-			dir->tdir_type = (uint16) TIFF_LONG;
-			dir->tdir_count = (uint32) td->td_nstrips;
-			if (!TIFFWriteLongArray(tif, dir, td->td_stripoffset))
-				goto bad;
-			break;
-		case FIELD_STRIPBYTECOUNTS:
-			/*
-			 * We use one field bit for both strip and tile
-			 * byte counts, and so must be careful in selecting
-			 * the appropriate field descriptor (so that tags
-			 * are written in sorted order).
-			 */
-			tag = isTiled(tif) ?
-			    TIFFTAG_TILEBYTECOUNTS : TIFFTAG_STRIPBYTECOUNTS;
-			if (tag != fip->field_tag)
-				continue;
-			
-			dir->tdir_tag = (uint16) tag;
-			dir->tdir_type = (uint16) TIFF_LONG;
-			dir->tdir_count = (uint32) td->td_nstrips;
-			if (!TIFFWriteLongArray(tif, dir, td->td_stripbytecount))
-				goto bad;
-			break;
-		case FIELD_ROWSPERSTRIP:
-			TIFFSetupShortLong(tif, TIFFTAG_ROWSPERSTRIP,
-			    dir, td->td_rowsperstrip);
-			break;
-		case FIELD_COLORMAP:
-			if (!TIFFWriteShortTable(tif, TIFFTAG_COLORMAP, dir,
-			    3, td->td_colormap))
-				goto bad;
-			break;
-		case FIELD_IMAGEDIMENSIONS:
-			TIFFSetupShortLong(tif, TIFFTAG_IMAGEWIDTH,
-			    dir++, td->td_imagewidth);
-			TIFFSetupShortLong(tif, TIFFTAG_IMAGELENGTH,
-			    dir, td->td_imagelength);
-			break;
-		case FIELD_TILEDIMENSIONS:
-			TIFFSetupShortLong(tif, TIFFTAG_TILEWIDTH,
-			    dir++, td->td_tilewidth);
-			TIFFSetupShortLong(tif, TIFFTAG_TILELENGTH,
-			    dir, td->td_tilelength);
-			break;
-		case FIELD_COMPRESSION:
-			TIFFSetupShort(tif, TIFFTAG_COMPRESSION,
-			    dir, td->td_compression);
-			break;
-		case FIELD_PHOTOMETRIC:
-			TIFFSetupShort(tif, TIFFTAG_PHOTOMETRIC,
-			    dir, td->td_photometric);
-			break;
-		case FIELD_POSITION:
-			WriteRationalPair(TIFF_RATIONAL,
-			    TIFFTAG_XPOSITION, td->td_xposition,
-			    TIFFTAG_YPOSITION, td->td_yposition);
-			break;
-		case FIELD_RESOLUTION:
-			WriteRationalPair(TIFF_RATIONAL,
-			    TIFFTAG_XRESOLUTION, td->td_xresolution,
-			    TIFFTAG_YRESOLUTION, td->td_yresolution);
-			break;
-		case FIELD_BITSPERSAMPLE:
-		case FIELD_MINSAMPLEVALUE:
-		case FIELD_MAXSAMPLEVALUE:
-		case FIELD_SAMPLEFORMAT:
-			if (!TIFFWritePerSampleShorts(tif, fip->field_tag, dir))
-				goto bad;
-			break;
-		case FIELD_SMINSAMPLEVALUE:
-		case FIELD_SMAXSAMPLEVALUE:
-			if (!TIFFWritePerSampleAnys(tif,
-			    _TIFFSampleToTagType(tif), fip->field_tag, dir))
-				goto bad;
-			break;
-		case FIELD_INKNAMES:
-			if (!TIFFWriteInkNames(tif, dir))
-				goto bad;
-			break;
-		case FIELD_TRANSFERFUNCTION:
-			if (!TIFFWriteTransferFunction(tif, dir))
-				goto bad;
-			break;
-		case FIELD_SUBIFD:
-			/*
-			 * XXX: Always write this field using LONG type
-			 * for backward compatibility.
-			 */
-			dir->tdir_tag = (uint16) fip->field_tag;
-			dir->tdir_type = (uint16) TIFF_LONG;
-			dir->tdir_count = (uint32) td->td_nsubifd;
-			if (!TIFFWriteLongArray(tif, dir, td->td_subifd))
-				goto bad;
-			/*
-			 * Total hack: if this directory includes a SubIFD
-			 * tag then force the next <n> directories to be
-			 * written as ``sub directories'' of this one.  This
-			 * is used to write things like thumbnails and
-			 * image masks that one wants to keep out of the
-			 * normal directory linkage access mechanism.
-			 */
-			if (dir->tdir_count > 0) {
-				tif->tif_flags |= TIFF_INSUBIFD;
-				tif->tif_nsubifd = (uint16) dir->tdir_count;
-				if (dir->tdir_count > 1)
-					tif->tif_subifdoff = dir->tdir_offset;
-				else
-					tif->tif_subifdoff = (uint32)(
-					      tif->tif_diroff
-					    + sizeof (uint16)
-					    + ((char*)&dir->tdir_offset-data));
-			}
-			break;
-		default:
-			/*
-			 * XXX: Should be fixed and removed. See comments
-			 * related to these tags in tif_dir.c.
-			 */
-			if (fip->field_tag == TIFFTAG_PAGENUMBER
-			    || fip->field_tag == TIFFTAG_HALFTONEHINTS
-			    || fip->field_tag == TIFFTAG_YCBCRSUBSAMPLING
-			    || fip->field_tag == TIFFTAG_DOTRANGE) {
-				if (fip->field_type == TIFF_BYTE) {
-					if (!TIFFSetupBytePair(tif, fip->field_tag, dir))
-						goto bad;
-				} else if (fip->field_type == TIFF_SHORT) {
-					if (!TIFFSetupShortPair(tif, fip->field_tag, dir))
-						goto bad;
-				}
-			} else if (!TIFFWriteNormalTag(tif, dir, fip))
-				goto bad;
-			break;
-		}
-		dir++;
-                
-		if( fip->field_bit != FIELD_CUSTOM )
-			ResetFieldBit(fields, fip->field_bit);
-	}
-
-	/*
-	 * Write directory.
-	 */
-	dircount = (uint16) nfields;
-	diroff = (uint32) tif->tif_nextdiroff;
-	if (tif->tif_flags & TIFF_SWAB) {
-		/*
-		 * The file's byte order is opposite to the
-		 * native machine architecture.  We overwrite
-		 * the directory information with impunity
-		 * because it'll be released below after we
-		 * write it to the file.  Note that all the
-		 * other tag construction routines assume that
-		 * we do this byte-swapping; i.e. they only
-		 * byte-swap indirect data.
-		 */
-		for (dir = (TIFFDirEntry*) data; dircount; dir++, dircount--) {
-			TIFFSwabArrayOfShort(&dir->tdir_tag, 2);
-			TIFFSwabArrayOfLong(&dir->tdir_count, 2);
-		}
-		dircount = (uint16) nfields;
-		TIFFSwabShort(&dircount);
-		TIFFSwabLong(&diroff);
-	}
-	(void) TIFFSeekFile(tif, tif->tif_diroff, SEEK_SET);
-	if (!WriteOK(tif, &dircount, sizeof (dircount))) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			     "Error writing directory count");
-		goto bad;
-	}
-	if (!WriteOK(tif, data, dirsize)) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			     "Error writing directory contents");
-		goto bad;
-	}
-	if (!WriteOK(tif, &diroff, sizeof (uint32))) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			     "Error writing directory link");
-		goto bad;
-	}
-	if (done) {
-		TIFFFreeDirectory(tif);
-		tif->tif_flags &= ~TIFF_DIRTYDIRECT;
-		(*tif->tif_cleanup)(tif);
-
-		/*
-		* Reset directory-related state for subsequent
-		* directories.
-		*/
-		TIFFCreateDirectory(tif);
-	}
-	_TIFFfree(data);
-	return (1);
-bad:
-	_TIFFfree(data);
-	return (0);
-}
-#undef WriteRationalPair
-
-int
-TIFFWriteDirectory(TIFF* tif)
-{
-	return _TIFFWriteDirectory(tif, TRUE);
-}
-
-/*
- * Similar to TIFFWriteDirectory(), writes the directory out
- * but leaves all data structures in memory so that it can be
- * written again.  This will make a partially written TIFF file
- * readable before it is successfully completed/closed.
- */ 
-int
-TIFFCheckpointDirectory(TIFF* tif)
-{
-	int rc;
-	/* Setup the strips arrays, if they haven't already been. */
-	if (tif->tif_dir.td_stripoffset == NULL)
-	    (void) TIFFSetupStrips(tif);
-	rc = _TIFFWriteDirectory(tif, FALSE);
-	(void) TIFFSetWriteOffset(tif, TIFFSeekFile(tif, 0, SEEK_END));
-	return rc;
-}
-
-static int
-_TIFFWriteCustomDirectory(TIFF* tif, toff_t *pdiroff)
-{
-	uint16 dircount;
-	uint32 nfields;
-	tsize_t dirsize;
-	char* data;
-	TIFFDirEntry* dir;
-	TIFFDirectory* td;
-	unsigned long b, fields[FIELD_SETLONGS];
-	int fi, nfi;
-
-	if (tif->tif_mode == O_RDONLY)
-		return (1);
-
-	td = &tif->tif_dir;
-	/*
-	 * Size the directory so that we can calculate
-	 * offsets for the data items that aren't kept
-	 * in-place in each field.
-	 */
-	nfields = 0;
-	for (b = 0; b <= FIELD_LAST; b++)
-		if (TIFFFieldSet(tif, b) && b != FIELD_CUSTOM)
-			nfields += (b < FIELD_SUBFILETYPE ? 2 : 1);
-	nfields += td->td_customValueCount;
-	dirsize = nfields * sizeof (TIFFDirEntry);
-	data = (char*) _TIFFmalloc(dirsize);
-	if (data == NULL) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			     "Cannot write directory, out of space");
-		return (0);
-	}
-	/*
-	 * Put the directory  at the end of the file.
-	 */
-	tif->tif_diroff = (TIFFSeekFile(tif, (toff_t) 0, SEEK_END)+1) &~ 1;
-	tif->tif_dataoff = (toff_t)(
-	    tif->tif_diroff + sizeof (uint16) + dirsize + sizeof (toff_t));
-	if (tif->tif_dataoff & 1)
-		tif->tif_dataoff++;
-	(void) TIFFSeekFile(tif, tif->tif_dataoff, SEEK_SET);
-	dir = (TIFFDirEntry*) data;
-	/*
-	 * Setup external form of directory
-	 * entries and write data items.
-	 */
-	_TIFFmemcpy(fields, td->td_fieldsset, sizeof (fields));
-
-	for (fi = 0, nfi = tif->tif_nfields; nfi > 0; nfi--, fi++) {
-		const TIFFFieldInfo* fip = tif->tif_fieldinfo[fi];
-
-		/*
-		 * For custom fields, we test to see if the custom field
-		 * is set or not.  For normal fields, we just use the
-		 * FieldSet test.
-		*/
-		if( fip->field_bit == FIELD_CUSTOM )
-		{
-			int ci, is_set = FALSE;
-
-			for( ci = 0; ci < td->td_customValueCount; ci++ )
-				is_set |= (td->td_customValues[ci].info == fip);
-
-			if( !is_set )
-				continue;
-		}
-		else if (!FieldSet(fields, fip->field_bit))
-			continue;
-                
-		if( fip->field_bit != FIELD_CUSTOM )
-			ResetFieldBit(fields, fip->field_bit);
-	}
-
-	/*
-	 * Write directory.
-	 */
-	dircount = (uint16) nfields;
-	*pdiroff = (uint32) tif->tif_nextdiroff;
-	if (tif->tif_flags & TIFF_SWAB) {
-		/*
-		 * The file's byte order is opposite to the
-		 * native machine architecture.  We overwrite
-		 * the directory information with impunity
-		 * because it'll be released below after we
-		 * write it to the file.  Note that all the
-		 * other tag construction routines assume that
-		 * we do this byte-swapping; i.e. they only
-		 * byte-swap indirect data.
-		 */
-		for (dir = (TIFFDirEntry*) data; dircount; dir++, dircount--) {
-			TIFFSwabArrayOfShort(&dir->tdir_tag, 2);
-			TIFFSwabArrayOfLong(&dir->tdir_count, 2);
-		}
-		dircount = (uint16) nfields;
-		TIFFSwabShort(&dircount);
-		TIFFSwabLong(pdiroff);
-	}
-	(void) TIFFSeekFile(tif, tif->tif_diroff, SEEK_SET);
-	if (!WriteOK(tif, &dircount, sizeof (dircount))) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			     "Error writing directory count");
-		goto bad;
-	}
-	if (!WriteOK(tif, data, dirsize)) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			     "Error writing directory contents");
-		goto bad;
-	}
-	if (!WriteOK(tif, pdiroff, sizeof (uint32))) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			     "Error writing directory link");
-		goto bad;
-	}
-	_TIFFfree(data);
-	return (1);
-bad:
-	_TIFFfree(data);
-	return (0);
-}
-
-int
-TIFFWriteCustomDirectory(TIFF* tif, toff_t *pdiroff)
-{
-	return _TIFFWriteCustomDirectory(tif, pdiroff);
-}
-
-/*
- * Process tags that are not special cased.
- */
-static int
-TIFFWriteNormalTag(TIFF* tif, TIFFDirEntry* dir, const TIFFFieldInfo* fip)
-{
-	uint16 wc = (uint16) fip->field_writecount;
-	uint32 wc2;
-
-	dir->tdir_tag = (uint16) fip->field_tag;
-	dir->tdir_type = (uint16) fip->field_type;
-	dir->tdir_count = wc;
-	
-	switch (fip->field_type) {
-	case TIFF_SHORT:
-	case TIFF_SSHORT:
-		if (fip->field_passcount) {
-			uint16* wp;
-			if (wc == (uint16) TIFF_VARIABLE2) {
-				TIFFGetField(tif, fip->field_tag, &wc2, &wp);
-				dir->tdir_count = wc2;
-			} else {	/* Assume TIFF_VARIABLE */
-				TIFFGetField(tif, fip->field_tag, &wc, &wp);
-				dir->tdir_count = wc;
-			}
-			if (!TIFFWriteShortArray(tif, dir, wp))
-				return 0;
-		} else {
-			if (wc == 1) {
-				uint16 sv;
-				TIFFGetField(tif, fip->field_tag, &sv);
-				dir->tdir_offset =
-					TIFFInsertData(tif, dir->tdir_type, sv);
-			} else {
-				uint16* wp;
-				TIFFGetField(tif, fip->field_tag, &wp);
-				if (!TIFFWriteShortArray(tif, dir, wp))
-					return 0;
-			}
-		}
-		break;
-	case TIFF_LONG:
-	case TIFF_SLONG:
-	case TIFF_IFD:
-		if (fip->field_passcount) {
-			uint32* lp;
-			if (wc == (uint16) TIFF_VARIABLE2) {
-				TIFFGetField(tif, fip->field_tag, &wc2, &lp);
-				dir->tdir_count = wc2;
-			} else {	/* Assume TIFF_VARIABLE */
-				TIFFGetField(tif, fip->field_tag, &wc, &lp);
-				dir->tdir_count = wc;
-			}
-			if (!TIFFWriteLongArray(tif, dir, lp))
-				return 0;
-		} else {
-			if (wc == 1) {
-				/* XXX handle LONG->SHORT conversion */
-				TIFFGetField(tif, fip->field_tag,
-					     &dir->tdir_offset);
-			} else {
-				uint32* lp;
-				TIFFGetField(tif, fip->field_tag, &lp);
-				if (!TIFFWriteLongArray(tif, dir, lp))
-					return 0;
-			}
-		}
-		break;
-	case TIFF_RATIONAL:
-	case TIFF_SRATIONAL:
-		if (fip->field_passcount) {
-			float* fp;
-			if (wc == (uint16) TIFF_VARIABLE2) {
-				TIFFGetField(tif, fip->field_tag, &wc2, &fp);
-				dir->tdir_count = wc2;
-			} else {	/* Assume TIFF_VARIABLE */
-				TIFFGetField(tif, fip->field_tag, &wc, &fp);
-				dir->tdir_count = wc;
-			}
-			if (!TIFFWriteRationalArray(tif, dir, fp))
-				return 0;
-		} else {
-			if (wc == 1) {
-				float fv;
-				TIFFGetField(tif, fip->field_tag, &fv);
-				if (!TIFFWriteRationalArray(tif, dir, &fv))
-					return 0;
-			} else {
-				float* fp;
-				TIFFGetField(tif, fip->field_tag, &fp);
-				if (!TIFFWriteRationalArray(tif, dir, fp))
-					return 0;
-			}
-		}
-		break;
-	case TIFF_FLOAT:
-		if (fip->field_passcount) {
-			float* fp;
-			if (wc == (uint16) TIFF_VARIABLE2) {
-				TIFFGetField(tif, fip->field_tag, &wc2, &fp);
-				dir->tdir_count = wc2;
-			} else {	/* Assume TIFF_VARIABLE */
-				TIFFGetField(tif, fip->field_tag, &wc, &fp);
-				dir->tdir_count = wc;
-			}
-			if (!TIFFWriteFloatArray(tif, dir, fp))
-				return 0;
-		} else {
-			if (wc == 1) {
-				float fv;
-				TIFFGetField(tif, fip->field_tag, &fv);
-				if (!TIFFWriteFloatArray(tif, dir, &fv))
-					return 0;
-			} else {
-				float* fp;
-				TIFFGetField(tif, fip->field_tag, &fp);
-				if (!TIFFWriteFloatArray(tif, dir, fp))
-					return 0;
-			}
-		}
-		break;
-	case TIFF_DOUBLE:
-		if (fip->field_passcount) {
-			double* dp;
-			if (wc == (uint16) TIFF_VARIABLE2) {
-				TIFFGetField(tif, fip->field_tag, &wc2, &dp);
-				dir->tdir_count = wc2;
-			} else {	/* Assume TIFF_VARIABLE */
-				TIFFGetField(tif, fip->field_tag, &wc, &dp);
-				dir->tdir_count = wc;
-			}
-			if (!TIFFWriteDoubleArray(tif, dir, dp))
-				return 0;
-		} else {
-			if (wc == 1) {
-				double dv;
-				TIFFGetField(tif, fip->field_tag, &dv);
-				if (!TIFFWriteDoubleArray(tif, dir, &dv))
-					return 0;
-			} else {
-				double* dp;
-				TIFFGetField(tif, fip->field_tag, &dp);
-				if (!TIFFWriteDoubleArray(tif, dir, dp))
-					return 0;
-			}
-		}
-		break;
-	case TIFF_ASCII:
-		{ 
-                    char* cp;
-                    if (fip->field_passcount)
-                    {
-                        if( wc == (uint16) TIFF_VARIABLE2 )
-                            TIFFGetField(tif, fip->field_tag, &wc2, &cp);
-                        else
-                            TIFFGetField(tif, fip->field_tag, &wc, &cp);
-                    }
-                    else
-                        TIFFGetField(tif, fip->field_tag, &cp);
-
-                    dir->tdir_count = (uint32) (strlen(cp) + 1);
-                    if (!TIFFWriteByteArray(tif, dir, cp))
-                        return (0);
-		}
-		break;
-
-        case TIFF_BYTE:
-        case TIFF_SBYTE:          
-		if (fip->field_passcount) {
-			char* cp;
-			if (wc == (uint16) TIFF_VARIABLE2) {
-				TIFFGetField(tif, fip->field_tag, &wc2, &cp);
-				dir->tdir_count = wc2;
-			} else {	/* Assume TIFF_VARIABLE */
-				TIFFGetField(tif, fip->field_tag, &wc, &cp);
-				dir->tdir_count = wc;
-			}
-			if (!TIFFWriteByteArray(tif, dir, cp))
-				return 0;
-		} else {
-			if (wc == 1) {
-				char cv;
-				TIFFGetField(tif, fip->field_tag, &cv);
-				if (!TIFFWriteByteArray(tif, dir, &cv))
-					return 0;
-			} else {
-				char* cp;
-				TIFFGetField(tif, fip->field_tag, &cp);
-				if (!TIFFWriteByteArray(tif, dir, cp))
-					return 0;
-			}
-		}
-                break;
-
-	case TIFF_UNDEFINED:
-		{ char* cp;
-		  if (wc == (unsigned short) TIFF_VARIABLE) {
-			TIFFGetField(tif, fip->field_tag, &wc, &cp);
-			dir->tdir_count = wc;
-		  } else if (wc == (unsigned short) TIFF_VARIABLE2) {
-			TIFFGetField(tif, fip->field_tag, &wc2, &cp);
-			dir->tdir_count = wc2;
-		  } else 
-			TIFFGetField(tif, fip->field_tag, &cp);
-		  if (!TIFFWriteByteArray(tif, dir, cp))
-			return (0);
-		}
-		break;
-
-        case TIFF_NOTYPE:
-                break;
-	}
-	return (1);
-}
-
-/*
- * Setup a directory entry with either a SHORT
- * or LONG type according to the value.
- */
-static void
-TIFFSetupShortLong(TIFF* tif, ttag_t tag, TIFFDirEntry* dir, uint32 v)
-{
-	dir->tdir_tag = (uint16) tag;
-	dir->tdir_count = 1;
-	if (v > 0xffffL) {
-		dir->tdir_type = (short) TIFF_LONG;
-		dir->tdir_offset = v;
-	} else {
-		dir->tdir_type = (short) TIFF_SHORT;
-		dir->tdir_offset = TIFFInsertData(tif, (int) TIFF_SHORT, v);
-	}
-}
-
-/*
- * Setup a SHORT directory entry
- */
-static void
-TIFFSetupShort(TIFF* tif, ttag_t tag, TIFFDirEntry* dir, uint16 v)
-{
-	dir->tdir_tag = (uint16) tag;
-	dir->tdir_count = 1;
-	dir->tdir_type = (short) TIFF_SHORT;
-	dir->tdir_offset = TIFFInsertData(tif, (int) TIFF_SHORT, v);
-}
-#undef MakeShortDirent
-
-#define	NITEMS(x)	(sizeof (x) / sizeof (x[0]))
-/*
- * Setup a directory entry that references a
- * samples/pixel array of SHORT values and
- * (potentially) write the associated indirect
- * values.
- */
-static int
-TIFFWritePerSampleShorts(TIFF* tif, ttag_t tag, TIFFDirEntry* dir)
-{
-	uint16 buf[10], v;
-	uint16* w = buf;
-	uint16 i, samples = tif->tif_dir.td_samplesperpixel;
-	int status;
-
-	if (samples > NITEMS(buf)) {
-		w = (uint16*) _TIFFmalloc(samples * sizeof (uint16));
-		if (w == NULL) {
-			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			    "No space to write per-sample shorts");
-			return (0);
-		}
-	}
-	TIFFGetField(tif, tag, &v);
-	for (i = 0; i < samples; i++)
-		w[i] = v;
-	
-	dir->tdir_tag = (uint16) tag;
-	dir->tdir_type = (uint16) TIFF_SHORT;
-	dir->tdir_count = samples;
-	status = TIFFWriteShortArray(tif, dir, w);
-	if (w != buf)
-		_TIFFfree((char*) w);
-	return (status);
-}
-
-/*
- * Setup a directory entry that references a samples/pixel array of ``type''
- * values and (potentially) write the associated indirect values.  The source
- * data from TIFFGetField() for the specified tag must be returned as double.
- */
-static int
-TIFFWritePerSampleAnys(TIFF* tif,
-    TIFFDataType type, ttag_t tag, TIFFDirEntry* dir)
-{
-	double buf[10], v;
-	double* w = buf;
-	uint16 i, samples = tif->tif_dir.td_samplesperpixel;
-	int status;
-
-	if (samples > NITEMS(buf)) {
-		w = (double*) _TIFFmalloc(samples * sizeof (double));
-		if (w == NULL) {
-			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			    "No space to write per-sample values");
-			return (0);
-		}
-	}
-	TIFFGetField(tif, tag, &v);
-	for (i = 0; i < samples; i++)
-		w[i] = v;
-	status = TIFFWriteAnyArray(tif, type, tag, dir, samples, w);
-	if (w != buf)
-		_TIFFfree(w);
-	return (status);
-}
-#undef NITEMS
-
-/*
- * Setup a pair of bytes that are returned by
- * value, rather than as a reference to an array.
- */
-static int
-TIFFSetupBytePair(TIFF* tif, ttag_t tag, TIFFDirEntry* dir)
-{
-	char v[2];
-
-	TIFFGetField(tif, tag, &v[0], &v[1]);
-
-	dir->tdir_tag = (uint16) tag;
-	dir->tdir_type = (uint16) TIFF_BYTE;
-	dir->tdir_count = 2;
-	return (TIFFWriteByteArray(tif, dir, v));
-}
-
-/*
- * Setup a pair of shorts that are returned by
- * value, rather than as a reference to an array.
- */
-static int
-TIFFSetupShortPair(TIFF* tif, ttag_t tag, TIFFDirEntry* dir)
-{
-	uint16 v[2];
-
-	TIFFGetField(tif, tag, &v[0], &v[1]);
-
-	dir->tdir_tag = (uint16) tag;
-	dir->tdir_type = (uint16) TIFF_SHORT;
-	dir->tdir_count = 2;
-	return (TIFFWriteShortArray(tif, dir, v));
-}
-
-/*
- * Setup a directory entry for an NxM table of shorts,
- * where M is known to be 2**bitspersample, and write
- * the associated indirect data.
- */
-static int
-TIFFWriteShortTable(TIFF* tif,
-    ttag_t tag, TIFFDirEntry* dir, uint32 n, uint16** table)
-{
-	uint32 i, off;
-
-	dir->tdir_tag = (uint16) tag;
-	dir->tdir_type = (short) TIFF_SHORT;
-	/* XXX -- yech, fool TIFFWriteData */
-	dir->tdir_count = (uint32) (1L<<tif->tif_dir.td_bitspersample);
-	off = tif->tif_dataoff;
-	for (i = 0; i < n; i++)
-		if (!TIFFWriteData(tif, dir, (char *)table[i]))
-			return (0);
-	dir->tdir_count *= n;
-	dir->tdir_offset = off;
-	return (1);
-}
-
-/*
- * Write/copy data associated with an ASCII or opaque tag value.
- */
-static int
-TIFFWriteByteArray(TIFF* tif, TIFFDirEntry* dir, char* cp)
-{
-	if (dir->tdir_count <= 4) {
-		if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) {
-			dir->tdir_offset = (uint32)cp[0] << 24;
-			if (dir->tdir_count >= 2)
-				dir->tdir_offset |= (uint32)cp[1] << 16;
-			if (dir->tdir_count >= 3)
-				dir->tdir_offset |= (uint32)cp[2] << 8;
-			if (dir->tdir_count == 4)
-				dir->tdir_offset |= cp[3];
-		} else {
-			dir->tdir_offset = cp[0];
-			if (dir->tdir_count >= 2)
-				dir->tdir_offset |= (uint32) cp[1] << 8;
-			if (dir->tdir_count >= 3)
-				dir->tdir_offset |= (uint32) cp[2] << 16;
-			if (dir->tdir_count == 4)
-				dir->tdir_offset |= (uint32) cp[3] << 24;
-		}
-		return 1;
-	} else
-		return TIFFWriteData(tif, dir, cp);
-}
-
-/*
- * Setup a directory entry of an array of SHORT
- * or SSHORT and write the associated indirect values.
- */
-static int
-TIFFWriteShortArray(TIFF* tif, TIFFDirEntry* dir, uint16* v)
-{
-	if (dir->tdir_count <= 2) {
-		if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) {
-			dir->tdir_offset = (uint32) v[0] << 16;
-			if (dir->tdir_count == 2)
-				dir->tdir_offset |= v[1] & 0xffff;
-		} else {
-			dir->tdir_offset = v[0] & 0xffff;
-			if (dir->tdir_count == 2)
-				dir->tdir_offset |= (uint32) v[1] << 16;
-		}
-		return (1);
-	} else
-		return (TIFFWriteData(tif, dir, (char*) v));
-}
-
-/*
- * Setup a directory entry of an array of LONG
- * or SLONG and write the associated indirect values.
- */
-static int
-TIFFWriteLongArray(TIFF* tif, TIFFDirEntry* dir, uint32* v)
-{
-	if (dir->tdir_count == 1) {
-		dir->tdir_offset = v[0];
-		return (1);
-	} else
-		return (TIFFWriteData(tif, dir, (char*) v));
-}
-
-/*
- * Setup a directory entry of an array of RATIONAL
- * or SRATIONAL and write the associated indirect values.
- */
-static int
-TIFFWriteRationalArray(TIFF* tif, TIFFDirEntry* dir, float* v)
-{
-	uint32 i;
-	uint32* t;
-	int status;
-
-	t = (uint32*) _TIFFmalloc(2 * dir->tdir_count * sizeof (uint32));
-	if (t == NULL) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-		    "No space to write RATIONAL array");
-		return (0);
-	}
-	for (i = 0; i < dir->tdir_count; i++) {
-		float fv = v[i];
-		int sign = 1;
-		uint32 den;
-
-		if (fv < 0) {
-			if (dir->tdir_type == TIFF_RATIONAL) {
-				TIFFWarningExt(tif->tif_clientdata,
-					       tif->tif_name,
-	"\"%s\": Information lost writing value (%g) as (unsigned) RATIONAL",
-				_TIFFFieldWithTag(tif,dir->tdir_tag)->field_name,
-						fv);
-				fv = 0;
-			} else
-				fv = -fv, sign = -1;
-		}
-		den = 1L;
-		if (fv > 0) {
-			while (fv < 1L<<(31-3) && den < 1L<<(31-3))
-				fv *= 1<<3, den *= 1L<<3;
-		}
-		t[2*i+0] = (uint32) (sign * (int32)(fv + 0.5));
-		t[2*i+1] = den;
-	}
-	status = TIFFWriteData(tif, dir, (char *)t);
-	_TIFFfree((char*) t);
-	return (status);
-}
-
-static int
-TIFFWriteFloatArray(TIFF* tif, TIFFDirEntry* dir, float* v)
-{
-	TIFFCvtNativeToIEEEFloat(tif, dir->tdir_count, v);
-	if (dir->tdir_count == 1) {
-		dir->tdir_offset = *(uint32*) &v[0];
-		return (1);
-	} else
-		return (TIFFWriteData(tif, dir, (char*) v));
-}
-
-static int
-TIFFWriteDoubleArray(TIFF* tif, TIFFDirEntry* dir, double* v)
-{
-	TIFFCvtNativeToIEEEDouble(tif, dir->tdir_count, v);
-	return (TIFFWriteData(tif, dir, (char*) v));
-}
-
-/*
- * Write an array of ``type'' values for a specified tag (i.e. this is a tag
- * which is allowed to have different types, e.g. SMaxSampleType).
- * Internally the data values are represented as double since a double can
- * hold any of the TIFF tag types (yes, this should really be an abstract
- * type tany_t for portability).  The data is converted into the specified
- * type in a temporary buffer and then handed off to the appropriate array
- * writer.
- */
-static int
-TIFFWriteAnyArray(TIFF* tif,
-    TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, double* v)
-{
-	char buf[10 * sizeof(double)];
-	char* w = buf;
-	int i, status = 0;
-
-	if (n * TIFFDataWidth(type) > sizeof buf) {
-		w = (char*) _TIFFmalloc(n * TIFFDataWidth(type));
-		if (w == NULL) {
-			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-				     "No space to write array");
-			return (0);
-		}
-	}
-
-	dir->tdir_tag = (uint16) tag;
-	dir->tdir_type = (uint16) type;
-	dir->tdir_count = n;
-
-	switch (type) {
-	case TIFF_BYTE:
-		{ 
-			uint8* bp = (uint8*) w;
-			for (i = 0; i < (int) n; i++)
-				bp[i] = (uint8) v[i];
-			if (!TIFFWriteByteArray(tif, dir, (char*) bp))
-				goto out;
-		}
-		break;
-	case TIFF_SBYTE:
-		{ 
-			int8* bp = (int8*) w;
-			for (i = 0; i < (int) n; i++)
-				bp[i] = (int8) v[i];
-			if (!TIFFWriteByteArray(tif, dir, (char*) bp))
-				goto out;
-		}
-		break;
-	case TIFF_SHORT:
-		{
-			uint16* bp = (uint16*) w;
-			for (i = 0; i < (int) n; i++)
-				bp[i] = (uint16) v[i];
-			if (!TIFFWriteShortArray(tif, dir, (uint16*)bp))
-				goto out;
-		}
-		break;
-	case TIFF_SSHORT:
-		{ 
-			int16* bp = (int16*) w;
-			for (i = 0; i < (int) n; i++)
-				bp[i] = (int16) v[i];
-			if (!TIFFWriteShortArray(tif, dir, (uint16*)bp))
-				goto out;
-		}
-		break;
-	case TIFF_LONG:
-		{
-			uint32* bp = (uint32*) w;
-			for (i = 0; i < (int) n; i++)
-				bp[i] = (uint32) v[i];
-			if (!TIFFWriteLongArray(tif, dir, bp))
-				goto out;
-		}
-		break;
-	case TIFF_SLONG:
-		{
-			int32* bp = (int32*) w;
-			for (i = 0; i < (int) n; i++)
-				bp[i] = (int32) v[i];
-			if (!TIFFWriteLongArray(tif, dir, (uint32*) bp))
-				goto out;
-		}
-		break;
-	case TIFF_FLOAT:
-		{ 
-			float* bp = (float*) w;
-			for (i = 0; i < (int) n; i++)
-				bp[i] = (float) v[i];
-			if (!TIFFWriteFloatArray(tif, dir, bp))
-				goto out;
-		}
-		break;
-	case TIFF_DOUBLE:
-                {
-                    if( !TIFFWriteDoubleArray(tif, dir, v))
-                        goto out;
-                }
-		break;
-	default:
-		/* TIFF_NOTYPE */
-		/* TIFF_ASCII */
-		/* TIFF_UNDEFINED */
-		/* TIFF_RATIONAL */
-		/* TIFF_SRATIONAL */
-		goto out;
-	}
-	status = 1;
- out:
-	if (w != buf)
-		_TIFFfree(w);
-	return (status);
-}
-
-static int
-TIFFWriteTransferFunction(TIFF* tif, TIFFDirEntry* dir)
-{
-	TIFFDirectory* td = &tif->tif_dir;
-	tsize_t n = (1L<<td->td_bitspersample) * sizeof (uint16);
-	uint16** tf = td->td_transferfunction;
-	int ncols;
-
-	/*
-	 * Check if the table can be written as a single column,
-	 * or if it must be written as 3 columns.  Note that we
-	 * write a 3-column tag if there are 2 samples/pixel and
-	 * a single column of data won't suffice--hmm.
-	 */
-	switch (td->td_samplesperpixel - td->td_extrasamples) {
-	default:	if (_TIFFmemcmp(tf[0], tf[2], n)) { ncols = 3; break; }
-	case 2:		if (_TIFFmemcmp(tf[0], tf[1], n)) { ncols = 3; break; }
-	case 1: case 0:	ncols = 1;
-	}
-	return (TIFFWriteShortTable(tif,
-	    TIFFTAG_TRANSFERFUNCTION, dir, ncols, tf));
-}
-
-static int
-TIFFWriteInkNames(TIFF* tif, TIFFDirEntry* dir)
-{
-	TIFFDirectory* td = &tif->tif_dir;
-
-	dir->tdir_tag = TIFFTAG_INKNAMES;
-	dir->tdir_type = (short) TIFF_ASCII;
-	dir->tdir_count = td->td_inknameslen;
-	return (TIFFWriteByteArray(tif, dir, td->td_inknames));
-}
-
-/*
- * Write a contiguous directory item.
- */
-static int
-TIFFWriteData(TIFF* tif, TIFFDirEntry* dir, char* cp)
-{
-	tsize_t cc;
-
-	if (tif->tif_flags & TIFF_SWAB) {
-		switch (dir->tdir_type) {
-		case TIFF_SHORT:
-		case TIFF_SSHORT:
-			TIFFSwabArrayOfShort((uint16*) cp, dir->tdir_count);
-			break;
-		case TIFF_LONG:
-		case TIFF_SLONG:
-		case TIFF_FLOAT:
-			TIFFSwabArrayOfLong((uint32*) cp, dir->tdir_count);
-			break;
-		case TIFF_RATIONAL:
-		case TIFF_SRATIONAL:
-			TIFFSwabArrayOfLong((uint32*) cp, 2*dir->tdir_count);
-			break;
-		case TIFF_DOUBLE:
-			TIFFSwabArrayOfDouble((double*) cp, dir->tdir_count);
-			break;
-		}
-	}
-	dir->tdir_offset = tif->tif_dataoff;
-	cc = dir->tdir_count * TIFFDataWidth((TIFFDataType) dir->tdir_type);
-	if (SeekOK(tif, dir->tdir_offset) &&
-	    WriteOK(tif, cp, cc)) {
-		tif->tif_dataoff += (cc + 1) & ~1;
-		return (1);
-	}
-	TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-		     "Error writing data for field \"%s\"",
-	_TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
-	return (0);
-}
-
-/*
- * Similar to TIFFWriteDirectory(), but if the directory has already
- * been written once, it is relocated to the end of the file, in case it
- * has changed in size.  Note that this will result in the loss of the 
- * previously used directory space. 
- */ 
-
-int 
-TIFFRewriteDirectory( TIFF *tif )
-{
-    static const char module[] = "TIFFRewriteDirectory";
-
-    /* We don't need to do anything special if it hasn't been written. */
-    if( tif->tif_diroff == 0 )
-        return TIFFWriteDirectory( tif );
-
-    /*
-    ** Find and zero the pointer to this directory, so that TIFFLinkDirectory
-    ** will cause it to be added after this directories current pre-link.
-    */
-    
-    /* Is it the first directory in the file? */
-    if (tif->tif_header.tiff_diroff == tif->tif_diroff) 
-    {
-        tif->tif_header.tiff_diroff = 0;
-        tif->tif_diroff = 0;
-
-        TIFFSeekFile(tif, (toff_t)(TIFF_MAGIC_SIZE+TIFF_VERSION_SIZE),
-		     SEEK_SET);
-        if (!WriteOK(tif, &(tif->tif_header.tiff_diroff), 
-                     sizeof (tif->tif_diroff))) 
-        {
-			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-				     "Error updating TIFF header");
-            return (0);
-        }
-    }
-    else
-    {
-        toff_t  nextdir, off;
-
-	nextdir = tif->tif_header.tiff_diroff;
-	do {
-		uint16 dircount;
-
-		if (!SeekOK(tif, nextdir) ||
-		    !ReadOK(tif, &dircount, sizeof (dircount))) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-				     "Error fetching directory count");
-			return (0);
-		}
-		if (tif->tif_flags & TIFF_SWAB)
-			TIFFSwabShort(&dircount);
-		(void) TIFFSeekFile(tif,
-		    dircount * sizeof (TIFFDirEntry), SEEK_CUR);
-		if (!ReadOK(tif, &nextdir, sizeof (nextdir))) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-				     "Error fetching directory link");
-			return (0);
-		}
-		if (tif->tif_flags & TIFF_SWAB)
-			TIFFSwabLong(&nextdir);
-	} while (nextdir != tif->tif_diroff && nextdir != 0);
-        off = TIFFSeekFile(tif, 0, SEEK_CUR); /* get current offset */
-        (void) TIFFSeekFile(tif, off - (toff_t)sizeof(nextdir), SEEK_SET);
-        tif->tif_diroff = 0;
-	if (!WriteOK(tif, &(tif->tif_diroff), sizeof (nextdir))) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-			     "Error writing directory link");
-		return (0);
-	}
-    }
-
-    /*
-    ** Now use TIFFWriteDirectory() normally.
-    */
-
-    return TIFFWriteDirectory( tif );
-}
-
-
-/*
- * Link the current directory into the directory chain for the file.
- */
-static int
-TIFFLinkDirectory(TIFF* tif)
-{
-	static const char module[] = "TIFFLinkDirectory";
-	toff_t nextdir;
-	toff_t diroff, off;
-
-	tif->tif_diroff = (TIFFSeekFile(tif, (toff_t) 0, SEEK_END)+1) &~ 1;
-	diroff = tif->tif_diroff;
-	if (tif->tif_flags & TIFF_SWAB)
-		TIFFSwabLong(&diroff);
-
-	/*
-	 * Handle SubIFDs
-	 */
-        if (tif->tif_flags & TIFF_INSUBIFD) {
-		(void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
-		if (!WriteOK(tif, &diroff, sizeof (diroff))) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-				     "%s: Error writing SubIFD directory link",
-				     tif->tif_name);
-			return (0);
-		}
-		/*
-		 * Advance to the next SubIFD or, if this is
-		 * the last one configured, revert back to the
-		 * normal directory linkage.
-		 */
-		if (--tif->tif_nsubifd)
-			tif->tif_subifdoff += sizeof (diroff);
-		else
-			tif->tif_flags &= ~TIFF_INSUBIFD;
-		return (1);
-	}
-
-	if (tif->tif_header.tiff_diroff == 0) {
-		/*
-		 * First directory, overwrite offset in header.
-		 */
-		tif->tif_header.tiff_diroff = tif->tif_diroff;
-		(void) TIFFSeekFile(tif,
-				    (toff_t)(TIFF_MAGIC_SIZE+TIFF_VERSION_SIZE),
-                                    SEEK_SET);
-		if (!WriteOK(tif, &diroff, sizeof (diroff))) {
-			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-				     "Error writing TIFF header");
-			return (0);
-		}
-		return (1);
-	}
-	/*
-	 * Not the first directory, search to the last and append.
-	 */
-	nextdir = tif->tif_header.tiff_diroff;
-	do {
-		uint16 dircount;
-
-		if (!SeekOK(tif, nextdir) ||
-		    !ReadOK(tif, &dircount, sizeof (dircount))) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-				     "Error fetching directory count");
-			return (0);
-		}
-		if (tif->tif_flags & TIFF_SWAB)
-			TIFFSwabShort(&dircount);
-		(void) TIFFSeekFile(tif,
-		    dircount * sizeof (TIFFDirEntry), SEEK_CUR);
-		if (!ReadOK(tif, &nextdir, sizeof (nextdir))) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-				     "Error fetching directory link");
-			return (0);
-		}
-		if (tif->tif_flags & TIFF_SWAB)
-			TIFFSwabLong(&nextdir);
-	} while (nextdir != 0);
-        off = TIFFSeekFile(tif, 0, SEEK_CUR); /* get current offset */
-        (void) TIFFSeekFile(tif, off - (toff_t)sizeof(nextdir), SEEK_SET);
-	if (!WriteOK(tif, &diroff, sizeof (diroff))) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-			     "Error writing directory link");
-		return (0);
-	}
-	return (1);
-}
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_dumpmode.c b/Source/LibTIFF/tif_dumpmode.c
deleted file mode 100644
index ac6d20b..0000000
--- a/Source/LibTIFF/tif_dumpmode.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/* $Header: /cvsroot/freeimage/FreeImage/Source/LibTIFF/tif_dumpmode.c,v 1.37 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library.
- *
- * "Null" Compression Algorithm Support.
- */
-#include "tiffiop.h"
-
-/*
- * Encode a hunk of pixels.
- */
-static int
-DumpModeEncode(TIFF* tif, tidata_t pp, tsize_t cc, tsample_t s)
-{
-	(void) s;
-	while (cc > 0) {
-		tsize_t n;
-
-		n = cc;
-		if (tif->tif_rawcc + n > tif->tif_rawdatasize)
-			n = tif->tif_rawdatasize - tif->tif_rawcc;
-
-		assert( n > 0 );
-                
-		/*
-		 * Avoid copy if client has setup raw
-		 * data buffer to avoid extra copy.
-		 */
-		if (tif->tif_rawcp != pp)
-			_TIFFmemcpy(tif->tif_rawcp, pp, n);
-		tif->tif_rawcp += n;
-		tif->tif_rawcc += n;
-		pp += n;
-		cc -= n;
-		if (tif->tif_rawcc >= tif->tif_rawdatasize &&
-		    !TIFFFlushData1(tif))
-			return (-1);
-	}
-	return (1);
-}
-
-/*
- * Decode a hunk of pixels.
- */
-static int
-DumpModeDecode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s)
-{
-	(void) s;
-/*         fprintf(stderr,"DumpModeDecode: scanline %ld, expected %ld bytes, got %ld bytes\n", */
-/*                 (long) tif->tif_row, (long) tif->tif_rawcc, (long) cc); */
-	if (tif->tif_rawcc < cc) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-		    "DumpModeDecode: Not enough data for scanline %d",
-		    tif->tif_row);
-		return (0);
-	}
-	/*
-	 * Avoid copy if client has setup raw
-	 * data buffer to avoid extra copy.
-	 */
-	if (tif->tif_rawcp != buf)
-		_TIFFmemcpy(buf, tif->tif_rawcp, cc);
-	tif->tif_rawcp += cc;
-	tif->tif_rawcc -= cc;
-	return (1);
-}
-
-/*
- * Seek forwards nrows in the current strip.
- */
-static int
-DumpModeSeek(TIFF* tif, uint32 nrows)
-{
-	tif->tif_rawcp += nrows * tif->tif_scanlinesize;
-	tif->tif_rawcc -= nrows * tif->tif_scanlinesize;
-	return (1);
-}
-
-/*
- * Initialize dump mode.
- */
-int
-TIFFInitDumpMode(TIFF* tif, int scheme)
-{
-	(void) scheme;
-	tif->tif_decoderow = DumpModeDecode;
-	tif->tif_decodestrip = DumpModeDecode;
-	tif->tif_decodetile = DumpModeDecode;
-	tif->tif_encoderow = DumpModeEncode;
-	tif->tif_encodestrip = DumpModeEncode;
-	tif->tif_encodetile = DumpModeEncode;
-	tif->tif_seek = DumpModeSeek;
-	return (1);
-}
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_error.c b/Source/LibTIFF/tif_error.c
deleted file mode 100644
index 5ee4654..0000000
--- a/Source/LibTIFF/tif_error.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/* $Header: /cvsroot/freeimage/FreeImage/Source/LibTIFF/tif_error.c,v 1.37 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library.
- */
-#include "tiffiop.h"
-
-TIFFErrorHandlerExt _TIFFerrorHandlerExt = NULL;
-
-TIFFErrorHandler
-TIFFSetErrorHandler(TIFFErrorHandler handler)
-{
-	TIFFErrorHandler prev = _TIFFerrorHandler;
-	_TIFFerrorHandler = handler;
-	return (prev);
-}
-
-TIFFErrorHandlerExt
-TIFFSetErrorHandlerExt(TIFFErrorHandlerExt handler)
-{
-	TIFFErrorHandlerExt prev = _TIFFerrorHandlerExt;
-	_TIFFerrorHandlerExt = handler;
-	return (prev);
-}
-
-void
-TIFFError(const char* module, const char* fmt, ...)
-{
-	va_list ap;
-	va_start(ap, fmt);
-	if (_TIFFerrorHandler)
-		(*_TIFFerrorHandler)(module, fmt, ap);
-	if (_TIFFerrorHandlerExt)
-		(*_TIFFerrorHandlerExt)(0, module, fmt, ap);
-	va_end(ap);
-}
-
-void
-TIFFErrorExt(thandle_t fd, const char* module, const char* fmt, ...)
-{
-	va_list ap;
-	va_start(ap, fmt);
-	if (_TIFFerrorHandler)
-		(*_TIFFerrorHandler)(module, fmt, ap);
-	if (_TIFFerrorHandlerExt)
-		(*_TIFFerrorHandlerExt)(fd, module, fmt, ap);
-	va_end(ap);
-}
-
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_extension.c b/Source/LibTIFF/tif_extension.c
deleted file mode 100644
index c6e3acf..0000000
--- a/Source/LibTIFF/tif_extension.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/* $Header: /cvsroot/freeimage/FreeImage/Source/LibTIFF/tif_extension.c,v 1.37 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library.
- *
- * Various routines support external extension of the tag set, and other
- * application extension capabilities. 
- */
-
-#include "tiffiop.h"
-
-int TIFFGetTagListCount( TIFF *tif )
-
-{
-    TIFFDirectory* td = &tif->tif_dir;
-    
-    return td->td_customValueCount;
-}
-
-ttag_t TIFFGetTagListEntry( TIFF *tif, int tag_index )
-
-{
-    TIFFDirectory* td = &tif->tif_dir;
-
-    if( tag_index < 0 || tag_index >= td->td_customValueCount )
-        return (ttag_t) -1;
-    else
-        return td->td_customValues[tag_index].info->field_tag;
-}
-
-/*
-** This provides read/write access to the TIFFTagMethods within the TIFF
-** structure to application code without giving access to the private
-** TIFF structure.
-*/
-TIFFTagMethods *TIFFAccessTagMethods( TIFF *tif )
-
-{
-    return &(tif->tif_tagmethods);
-}
-
-void *TIFFGetClientInfo( TIFF *tif, const char *name )
-
-{
-    TIFFClientInfoLink *link = tif->tif_clientinfo;
-
-    while( link != NULL && strcmp(link->name,name) != 0 )
-        link = link->next;
-
-    if( link != NULL )
-        return link->data;
-    else
-        return NULL;
-}
-
-void TIFFSetClientInfo( TIFF *tif, void *data, const char *name )
-
-{
-    TIFFClientInfoLink *link = tif->tif_clientinfo;
-
-    /*
-    ** Do we have an existing link with this name?  If so, just
-    ** set it.
-    */
-    while( link != NULL && strcmp(link->name,name) != 0 )
-        link = link->next;
-
-    if( link != NULL )
-    {
-        link->data = data;
-        return;
-    }
-
-    /*
-    ** Create a new link.
-    */
-
-    link = (TIFFClientInfoLink *) _TIFFmalloc(sizeof(TIFFClientInfoLink));
-    assert (link != NULL);
-    link->next = tif->tif_clientinfo;
-    link->name = (char *) _TIFFmalloc(strlen(name)+1);
-    assert (link->name != NULL);
-    strcpy(link->name, name);
-    link->data = data;
-
-    tif->tif_clientinfo = link;
-}
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_fax3.c b/Source/LibTIFF/tif_fax3.c
deleted file mode 100644
index 87317e9..0000000
--- a/Source/LibTIFF/tif_fax3.c
+++ /dev/null
@@ -1,1626 +0,0 @@
-/* $Id: tif_fax3.c,v 1.37 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1990-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-#include "tiffiop.h"
-#ifdef CCITT_SUPPORT
-/*
- * TIFF Library.
- *
- * CCITT Group 3 (T.4) and Group 4 (T.6) Compression Support.
- *
- * This file contains support for decoding and encoding TIFF
- * compression algorithms 2, 3, 4, and 32771.
- *
- * Decoder support is derived, with permission, from the code
- * in Frank Cringle's viewfax program;
- *      Copyright (C) 1990, 1995  Frank D. Cringle.
- */
-#include "tif_fax3.h"
-#define	G3CODES
-#include "t4.h"
-#include <stdio.h>
-
-/*
- * Compression+decompression state blocks are
- * derived from this ``base state'' block.
- */
-typedef struct {
-        int     rw_mode;                /* O_RDONLY for decode, else encode */
-	int	mode;			/* operating mode */
-	uint32	rowbytes;		/* bytes in a decoded scanline */
-	uint32	rowpixels;		/* pixels in a scanline */
-
-	uint16	cleanfaxdata;		/* CleanFaxData tag */
-	uint32	badfaxrun;		/* BadFaxRun tag */
-	uint32	badfaxlines;		/* BadFaxLines tag */
-	uint32	groupoptions;		/* Group 3/4 options tag */
-	uint32	recvparams;		/* encoded Class 2 session params */
-	char*	subaddress;		/* subaddress string */
-	uint32	recvtime;		/* time spent receiving (secs) */
-	char*	faxdcs;			/* Table 2/T.30 encoded session params */
-	TIFFVGetMethod vgetparent;	/* super-class method */
-	TIFFVSetMethod vsetparent;	/* super-class method */
-	TIFFPrintMethod printdir;	/* super-class method */
-} Fax3BaseState;
-#define	Fax3State(tif)		((Fax3BaseState*) (tif)->tif_data)
-
-typedef enum { G3_1D, G3_2D } Ttag;
-typedef struct {
-	Fax3BaseState b;
-
-	/* Decoder state info */
-	const unsigned char* bitmap;	/* bit reversal table */
-	uint32	data;			/* current i/o byte/word */
-	int	bit;			/* current i/o bit in byte */
-	int	EOLcnt;			/* count of EOL codes recognized */
-	TIFFFaxFillFunc fill;		/* fill routine */
-	uint32*	runs;			/* b&w runs for current/previous row */
-	uint32*	refruns;		/* runs for reference line */
-	uint32*	curruns;		/* runs for current line */
-
-	/* Encoder state info */
-	Ttag    tag;			/* encoding state */
-	unsigned char*	refline;	/* reference line for 2d decoding */
-	int	k;			/* #rows left that can be 2d encoded */
-	int	maxk;			/* max #rows that can be 2d encoded */
-
-	int line;
-} Fax3CodecState;
-#define	DecoderState(tif)	((Fax3CodecState*) Fax3State(tif))
-#define	EncoderState(tif)	((Fax3CodecState*) Fax3State(tif))
-
-#define	is2DEncoding(sp) \
-	(sp->b.groupoptions & GROUP3OPT_2DENCODING)
-#define	isAligned(p,t)	((((unsigned long)(p)) & (sizeof (t)-1)) == 0)
-
-/*
- * Group 3 and Group 4 Decoding.
- */
-
-/*
- * These macros glue the TIFF library state to
- * the state expected by Frank's decoder.
- */
-#define	DECLARE_STATE(tif, sp, mod)					\
-    static const char module[] = mod;					\
-    Fax3CodecState* sp = DecoderState(tif);				\
-    int a0;				/* reference element */		\
-    int lastx = sp->b.rowpixels;	/* last element in row */	\
-    uint32 BitAcc;			/* bit accumulator */		\
-    int BitsAvail;			/* # valid bits in BitAcc */	\
-    int RunLength;			/* length of current run */	\
-    unsigned char* cp;			/* next byte of input data */	\
-    unsigned char* ep;			/* end of input data */		\
-    uint32* pa;				/* place to stuff next run */	\
-    uint32* thisrun;			/* current row's run array */	\
-    int EOLcnt;				/* # EOL codes recognized */	\
-    const unsigned char* bitmap = sp->bitmap;	/* input data bit reverser */	\
-    const TIFFFaxTabEnt* TabEnt
-#define	DECLARE_STATE_2D(tif, sp, mod)					\
-    DECLARE_STATE(tif, sp, mod);					\
-    int b1;				/* next change on prev line */	\
-    uint32* pb				/* next run in reference line */\
-/*
- * Load any state that may be changed during decoding.
- */
-#define	CACHE_STATE(tif, sp) do {					\
-    BitAcc = sp->data;							\
-    BitsAvail = sp->bit;						\
-    EOLcnt = sp->EOLcnt;						\
-    cp = (unsigned char*) tif->tif_rawcp;				\
-    ep = cp + tif->tif_rawcc;						\
-} while (0)
-/*
- * Save state possibly changed during decoding.
- */
-#define	UNCACHE_STATE(tif, sp) do {					\
-    sp->bit = BitsAvail;						\
-    sp->data = BitAcc;							\
-    sp->EOLcnt = EOLcnt;						\
-    tif->tif_rawcc -= (tidata_t) cp - tif->tif_rawcp;			\
-    tif->tif_rawcp = (tidata_t) cp;					\
-} while (0)
-
-/*
- * Setup state for decoding a strip.
- */
-static int
-Fax3PreDecode(TIFF* tif, tsample_t s)
-{
-	Fax3CodecState* sp = DecoderState(tif);
-
-	(void) s;
-	assert(sp != NULL);
-	sp->bit = 0;			/* force initial read */
-	sp->data = 0;
-	sp->EOLcnt = 0;			/* force initial scan for EOL */
-	/*
-	 * Decoder assumes lsb-to-msb bit order.  Note that we select
-	 * this here rather than in Fax3SetupState so that viewers can
-	 * hold the image open, fiddle with the FillOrder tag value,
-	 * and then re-decode the image.  Otherwise they'd need to close
-	 * and open the image to get the state reset.
-	 */
-	sp->bitmap =
-	    TIFFGetBitRevTable(tif->tif_dir.td_fillorder != FILLORDER_LSB2MSB);
-	if (sp->refruns) {		/* init reference line to white */
-		sp->refruns[0] = (uint32) sp->b.rowpixels;
-		sp->refruns[1] = 0;
-	}
-	sp->line = 0;
-	return (1);
-}
-
-/*
- * Routine for handling various errors/conditions.
- * Note how they are "glued into the decoder" by
- * overriding the definitions used by the decoder.
- */
-
-static void
-Fax3Unexpected(const char* module, TIFF* tif, uint32 line, uint32 a0)
-{
-	TIFFErrorExt(tif->tif_clientdata, module, "%s: Bad code word at line %u of %s %u (x %u)",
-		     tif->tif_name, line, isTiled(tif) ? "tile" : "strip",
-		     (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip),
-		     a0);
-}
-#define	unexpected(table, a0)	Fax3Unexpected(module, tif, sp->line, a0)
-
-static void
-Fax3Extension(const char* module, TIFF* tif, uint32 line, uint32 a0)
-{
-	TIFFErrorExt(tif->tif_clientdata, module,
-		     "%s: Uncompressed data (not supported) at line %u of %s %u (x %u)",
-		     tif->tif_name, line, isTiled(tif) ? "tile" : "strip",
-		     (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip),
-		     a0);
-}
-#define	extension(a0)	Fax3Extension(module, tif, sp->line, a0)
-
-static void
-Fax3BadLength(const char* module, TIFF* tif, uint32 line, uint32 a0, uint32 lastx)
-{
-	TIFFWarningExt(tif->tif_clientdata, module, "%s: %s at line %u of %s %u (got %u, expected %u)",
-		       tif->tif_name,
-		       a0 < lastx ? "Premature EOL" : "Line length mismatch",
-		       line, isTiled(tif) ? "tile" : "strip",
-		       (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip),
-		       a0, lastx);
-}
-#define	badlength(a0,lastx)	Fax3BadLength(module, tif, sp->line, a0, lastx)
-
-static void
-Fax3PrematureEOF(const char* module, TIFF* tif, uint32 line, uint32 a0)
-{
-	TIFFWarningExt(tif->tif_clientdata, module, "%s: Premature EOF at line %u of %s %u (x %u)",
-	    tif->tif_name,
-		       line, isTiled(tif) ? "tile" : "strip",
-		       (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip),
-		       a0);
-}
-#define	prematureEOF(a0)	Fax3PrematureEOF(module, tif, sp->line, a0)
-
-#define	Nop
-
-/*
- * Decode the requested amount of G3 1D-encoded data.
- */
-static int
-Fax3Decode1D(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s)
-{
-	DECLARE_STATE(tif, sp, "Fax3Decode1D");
-
-	(void) s;
-	CACHE_STATE(tif, sp);
-	thisrun = sp->curruns;
-	while ((long)occ > 0) {
-		a0 = 0;
-		RunLength = 0;
-		pa = thisrun;
-#ifdef FAX3_DEBUG
-		printf("\nBitAcc=%08X, BitsAvail = %d\n", BitAcc, BitsAvail);
-		printf("-------------------- %d\n", tif->tif_row);
-		fflush(stdout);
-#endif
-		SYNC_EOL(EOF1D);
-		EXPAND1D(EOF1Da);
-		(*sp->fill)(buf, thisrun, pa, lastx);
-		buf += sp->b.rowbytes;
-		occ -= sp->b.rowbytes;
-		sp->line++;
-		continue;
-	EOF1D:				/* premature EOF */
-		CLEANUP_RUNS();
-	EOF1Da:				/* premature EOF */
-		(*sp->fill)(buf, thisrun, pa, lastx);
-		UNCACHE_STATE(tif, sp);
-		return (-1);
-	}
-	UNCACHE_STATE(tif, sp);
-	return (1);
-}
-
-#define	SWAP(t,a,b)	{ t x; x = (a); (a) = (b); (b) = x; }
-/*
- * Decode the requested amount of G3 2D-encoded data.
- */
-static int
-Fax3Decode2D(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s)
-{
-	DECLARE_STATE_2D(tif, sp, "Fax3Decode2D");
-	int is1D;			/* current line is 1d/2d-encoded */
-
-	(void) s;
-	CACHE_STATE(tif, sp);
-	while ((long)occ > 0) {
-		a0 = 0;
-		RunLength = 0;
-		pa = thisrun = sp->curruns;
-#ifdef FAX3_DEBUG
-		printf("\nBitAcc=%08X, BitsAvail = %d EOLcnt = %d",
-		    BitAcc, BitsAvail, EOLcnt);
-#endif
-		SYNC_EOL(EOF2D);
-		NeedBits8(1, EOF2D);
-		is1D = GetBits(1);	/* 1D/2D-encoding tag bit */
-		ClrBits(1);
-#ifdef FAX3_DEBUG
-		printf(" %s\n-------------------- %d\n",
-		    is1D ? "1D" : "2D", tif->tif_row);
-		fflush(stdout);
-#endif
-		pb = sp->refruns;
-		b1 = *pb++;
-		if (is1D)
-			EXPAND1D(EOF2Da);
-		else
-			EXPAND2D(EOF2Da);
-		(*sp->fill)(buf, thisrun, pa, lastx);
-		SETVALUE(0);		/* imaginary change for reference */
-		SWAP(uint32*, sp->curruns, sp->refruns);
-		buf += sp->b.rowbytes;
-		occ -= sp->b.rowbytes;
-		sp->line++;
-		continue;
-	EOF2D:				/* premature EOF */
-		CLEANUP_RUNS();
-	EOF2Da:				/* premature EOF */
-		(*sp->fill)(buf, thisrun, pa, lastx);
-		UNCACHE_STATE(tif, sp);
-		return (-1);
-	}
-	UNCACHE_STATE(tif, sp);
-	return (1);
-}
-#undef SWAP
-
-/*
- * The ZERO & FILL macros must handle spans < 2*sizeof(long) bytes.
- * For machines with 64-bit longs this is <16 bytes; otherwise
- * this is <8 bytes.  We optimize the code here to reflect the
- * machine characteristics.
- */
-#if SIZEOF_LONG == 8
-# define FILL(n, cp)							    \
-    switch (n) {							    \
-    case 15:(cp)[14] = 0xff; case 14:(cp)[13] = 0xff; case 13: (cp)[12] = 0xff;\
-    case 12:(cp)[11] = 0xff; case 11:(cp)[10] = 0xff; case 10: (cp)[9] = 0xff;\
-    case  9: (cp)[8] = 0xff; case  8: (cp)[7] = 0xff; case  7: (cp)[6] = 0xff;\
-    case  6: (cp)[5] = 0xff; case  5: (cp)[4] = 0xff; case  4: (cp)[3] = 0xff;\
-    case  3: (cp)[2] = 0xff; case  2: (cp)[1] = 0xff;			      \
-    case  1: (cp)[0] = 0xff; (cp) += (n); case 0:  ;			      \
-    }
-# define ZERO(n, cp)							\
-    switch (n) {							\
-    case 15:(cp)[14] = 0; case 14:(cp)[13] = 0; case 13: (cp)[12] = 0;	\
-    case 12:(cp)[11] = 0; case 11:(cp)[10] = 0; case 10: (cp)[9] = 0;	\
-    case  9: (cp)[8] = 0; case  8: (cp)[7] = 0; case  7: (cp)[6] = 0;	\
-    case  6: (cp)[5] = 0; case  5: (cp)[4] = 0; case  4: (cp)[3] = 0;	\
-    case  3: (cp)[2] = 0; case  2: (cp)[1] = 0;				\
-    case  1: (cp)[0] = 0; (cp) += (n); case 0:  ;			\
-    }
-#else
-# define FILL(n, cp)							    \
-    switch (n) {							    \
-    case 7: (cp)[6] = 0xff; case 6: (cp)[5] = 0xff; case 5: (cp)[4] = 0xff; \
-    case 4: (cp)[3] = 0xff; case 3: (cp)[2] = 0xff; case 2: (cp)[1] = 0xff; \
-    case 1: (cp)[0] = 0xff; (cp) += (n); case 0:  ;			    \
-    }
-# define ZERO(n, cp)							\
-    switch (n) {							\
-    case 7: (cp)[6] = 0; case 6: (cp)[5] = 0; case 5: (cp)[4] = 0;	\
-    case 4: (cp)[3] = 0; case 3: (cp)[2] = 0; case 2: (cp)[1] = 0;	\
-    case 1: (cp)[0] = 0; (cp) += (n); case 0:  ;			\
-    }
-#endif
-
-/*
- * Bit-fill a row according to the white/black
- * runs generated during G3/G4 decoding.
- */
-void
-_TIFFFax3fillruns(unsigned char* buf, uint32* runs, uint32* erun, uint32 lastx)
-{
-	static const unsigned char _fillmasks[] =
-	    { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };
-	unsigned char* cp;
-	uint32 x, bx, run;
-	int32 n, nw;
-	long* lp;
-
-	if ((erun-runs)&1)
-	    *erun++ = 0;
-	x = 0;
-	for (; runs < erun; runs += 2) {
-	    run = runs[0];
-	    if (x+run > lastx || run > lastx )
-		run = runs[0] = (uint32) (lastx - x);
-	    if (run) {
-		cp = buf + (x>>3);
-		bx = x&7;
-		if (run > 8-bx) {
-		    if (bx) {			/* align to byte boundary */
-			*cp++ &= 0xff << (8-bx);
-			run -= 8-bx;
-		    }
-		    if( (n = run >> 3) != 0 ) {	/* multiple bytes to fill */
-			if ((n/sizeof (long)) > 1) {
-			    /*
-			     * Align to longword boundary and fill.
-			     */
-			    for (; n && !isAligned(cp, long); n--)
-				    *cp++ = 0x00;
-			    lp = (long*) cp;
-			    nw = (int32)(n / sizeof (long));
-			    n -= nw * sizeof (long);
-			    do {
-				    *lp++ = 0L;
-			    } while (--nw);
-			    cp = (unsigned char*) lp;
-			}
-			ZERO(n, cp);
-			run &= 7;
-		    }
-		    if (run)
-			cp[0] &= 0xff >> run;
-		} else
-		    cp[0] &= ~(_fillmasks[run]>>bx);
-		x += runs[0];
-	    }
-	    run = runs[1];
-	    if (x+run > lastx || run > lastx )
-		run = runs[1] = lastx - x;
-	    if (run) {
-		cp = buf + (x>>3);
-		bx = x&7;
-		if (run > 8-bx) {
-		    if (bx) {			/* align to byte boundary */
-			*cp++ |= 0xff >> bx;
-			run -= 8-bx;
-		    }
-		    if( (n = run>>3) != 0 ) {	/* multiple bytes to fill */
-			if ((n/sizeof (long)) > 1) {
-			    /*
-			     * Align to longword boundary and fill.
-			     */
-			    for (; n && !isAligned(cp, long); n--)
-				*cp++ = 0xff;
-			    lp = (long*) cp;
-			    nw = (int32)(n / sizeof (long));
-			    n -= nw * sizeof (long);
-			    do {
-				*lp++ = -1L;
-			    } while (--nw);
-			    cp = (unsigned char*) lp;
-			}
-			FILL(n, cp);
-			run &= 7;
-		    }
-		    if (run)
-			cp[0] |= 0xff00 >> run;
-		} else
-		    cp[0] |= _fillmasks[run]>>bx;
-		x += runs[1];
-	    }
-	}
-	assert(x == lastx);
-}
-#undef	ZERO
-#undef	FILL
-
-/*
- * Setup G3/G4-related compression/decompression state
- * before data is processed.  This routine is called once
- * per image -- it sets up different state based on whether
- * or not decoding or encoding is being done and whether
- * 1D- or 2D-encoded data is involved.
- */
-static int
-Fax3SetupState(TIFF* tif)
-{
-	TIFFDirectory* td = &tif->tif_dir;
-	Fax3BaseState* sp = Fax3State(tif);
-	int needsRefLine;
-	Fax3CodecState* dsp = (Fax3CodecState*) Fax3State(tif);
-	uint32 rowbytes, rowpixels, nruns;
-
-	if (td->td_bitspersample != 1) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-		    "Bits/sample must be 1 for Group 3/4 encoding/decoding");
-		return (0);
-	}
-	/*
-	 * Calculate the scanline/tile widths.
-	 */
-	if (isTiled(tif)) {
-		rowbytes = TIFFTileRowSize(tif);
-		rowpixels = td->td_tilewidth;
-	} else {
-		rowbytes = TIFFScanlineSize(tif);
-		rowpixels = td->td_imagewidth;
-	}
-	sp->rowbytes = (uint32) rowbytes;
-	sp->rowpixels = (uint32) rowpixels;
-	/*
-	 * Allocate any additional space required for decoding/encoding.
-	 */
-	needsRefLine = (
-	    (sp->groupoptions & GROUP3OPT_2DENCODING) ||
-	    td->td_compression == COMPRESSION_CCITTFAX4
-	);
-
-	/*
-	  Assure that allocation computations do not overflow.
-  
-	  TIFFroundup and TIFFSafeMultiply return zero on integer overflow
-	*/
-	dsp->runs=(uint32*) NULL;
-	nruns = TIFFroundup(rowpixels,32);
-	if (needsRefLine) {
-		nruns = TIFFSafeMultiply(uint32,nruns,2);
-	}
-	if ((nruns == 0) || (TIFFSafeMultiply(uint32,nruns,2) == 0)) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			     "Row pixels integer overflow (rowpixels %u)",
-			     rowpixels);
-		return (0);
-	}
-	dsp->runs = (uint32*) _TIFFCheckMalloc(tif,
-					       TIFFSafeMultiply(uint32,nruns,2),
-					       sizeof (uint32),
-					       "for Group 3/4 run arrays");
-	if (dsp->runs == NULL)
-		return (0);
-	dsp->curruns = dsp->runs;
-	if (needsRefLine)
-		dsp->refruns = dsp->runs + nruns;
-	else
-		dsp->refruns = NULL;
-	if (td->td_compression == COMPRESSION_CCITTFAX3
-	    && is2DEncoding(dsp)) {	/* NB: default is 1D routine */
-		tif->tif_decoderow = Fax3Decode2D;
-		tif->tif_decodestrip = Fax3Decode2D;
-		tif->tif_decodetile = Fax3Decode2D;
-	}
-
-	if (needsRefLine) {		/* 2d encoding */
-		Fax3CodecState* esp = EncoderState(tif);
-		/*
-		 * 2d encoding requires a scanline
-		 * buffer for the ``reference line''; the
-		 * scanline against which delta encoding
-		 * is referenced.  The reference line must
-		 * be initialized to be ``white'' (done elsewhere).
-		 */
-		esp->refline = (unsigned char*) _TIFFmalloc(rowbytes);
-		if (esp->refline == NULL) {
-			TIFFErrorExt(tif->tif_clientdata, "Fax3SetupState",
-			    "%s: No space for Group 3/4 reference line",
-			    tif->tif_name);
-			return (0);
-		}
-	} else					/* 1d encoding */
-		EncoderState(tif)->refline = NULL;
-
-	return (1);
-}
-
-/*
- * CCITT Group 3 FAX Encoding.
- */
-
-#define	Fax3FlushBits(tif, sp) {				\
-	if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize)		\
-		(void) TIFFFlushData1(tif);			\
-	*(tif)->tif_rawcp++ = (tidataval_t) (sp)->data;		\
-	(tif)->tif_rawcc++;					\
-	(sp)->data = 0, (sp)->bit = 8;				\
-}
-#define	_FlushBits(tif) {					\
-	if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize)		\
-		(void) TIFFFlushData1(tif);			\
-	*(tif)->tif_rawcp++ = (tidataval_t) data;		\
-	(tif)->tif_rawcc++;					\
-	data = 0, bit = 8;					\
-}
-static const int _msbmask[9] =
-    { 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
-#define	_PutBits(tif, bits, length) {				\
-	while (length > bit) {					\
-		data |= bits >> (length - bit);			\
-		length -= bit;					\
-		_FlushBits(tif);				\
-	}							\
-	data |= (bits & _msbmask[length]) << (bit - length);	\
-	bit -= length;						\
-	if (bit == 0)						\
-		_FlushBits(tif);				\
-}
-	
-/*
- * Write a variable-length bit-value to
- * the output stream.  Values are
- * assumed to be at most 16 bits.
- */
-static void
-Fax3PutBits(TIFF* tif, unsigned int bits, unsigned int length)
-{
-	Fax3CodecState* sp = EncoderState(tif);
-	unsigned int bit = sp->bit;
-	int data = sp->data;
-
-	_PutBits(tif, bits, length);
-
-	sp->data = data;
-	sp->bit = bit;
-}
-
-/*
- * Write a code to the output stream.
- */
-#define putcode(tif, te)	Fax3PutBits(tif, (te)->code, (te)->length)
-
-#ifdef FAX3_DEBUG
-#define	DEBUG_COLOR(w) (tab == TIFFFaxWhiteCodes ? w "W" : w "B")
-#define	DEBUG_PRINT(what,len) {						\
-    int t;								\
-    printf("%08X/%-2d: %s%5d\t", data, bit, DEBUG_COLOR(what), len);	\
-    for (t = length-1; t >= 0; t--)					\
-	putchar(code & (1<<t) ? '1' : '0');				\
-    putchar('\n');							\
-}
-#endif
-
-/*
- * Write the sequence of codes that describes
- * the specified span of zero's or one's.  The
- * appropriate table that holds the make-up and
- * terminating codes is supplied.
- */
-static void
-putspan(TIFF* tif, int32 span, const tableentry* tab)
-{
-	Fax3CodecState* sp = EncoderState(tif);
-	unsigned int bit = sp->bit;
-	int data = sp->data;
-	unsigned int code, length;
-
-	while (span >= 2624) {
-		const tableentry* te = &tab[63 + (2560>>6)];
-		code = te->code, length = te->length;
-#ifdef FAX3_DEBUG
-		DEBUG_PRINT("MakeUp", te->runlen);
-#endif
-		_PutBits(tif, code, length);
-		span -= te->runlen;
-	}
-	if (span >= 64) {
-		const tableentry* te = &tab[63 + (span>>6)];
-		assert(te->runlen == 64*(span>>6));
-		code = te->code, length = te->length;
-#ifdef FAX3_DEBUG
-		DEBUG_PRINT("MakeUp", te->runlen);
-#endif
-		_PutBits(tif, code, length);
-		span -= te->runlen;
-	}
-	code = tab[span].code, length = tab[span].length;
-#ifdef FAX3_DEBUG
-	DEBUG_PRINT("  Term", tab[span].runlen);
-#endif
-	_PutBits(tif, code, length);
-
-	sp->data = data;
-	sp->bit = bit;
-}
-
-/*
- * Write an EOL code to the output stream.  The zero-fill
- * logic for byte-aligning encoded scanlines is handled
- * here.  We also handle writing the tag bit for the next
- * scanline when doing 2d encoding.
- */
-static void
-Fax3PutEOL(TIFF* tif)
-{
-	Fax3CodecState* sp = EncoderState(tif);
-	unsigned int bit = sp->bit;
-	int data = sp->data;
-	unsigned int code, length, tparm;
-
-	if (sp->b.groupoptions & GROUP3OPT_FILLBITS) {
-		/*
-		 * Force bit alignment so EOL will terminate on
-		 * a byte boundary.  That is, force the bit alignment
-		 * to 16-12 = 4 before putting out the EOL code.
-		 */
-		int align = 8 - 4;
-		if (align != sp->bit) {
-			if (align > sp->bit)
-				align = sp->bit + (8 - align);
-			else
-				align = sp->bit - align;
-			code = 0;
-			tparm=align; 
-			_PutBits(tif, 0, tparm);
-		}
-	}
-	code = EOL, length = 12;
-	if (is2DEncoding(sp))
-		code = (code<<1) | (sp->tag == G3_1D), length++;
-	_PutBits(tif, code, length);
-
-	sp->data = data;
-	sp->bit = bit;
-}
-
-/*
- * Reset encoding state at the start of a strip.
- */
-static int
-Fax3PreEncode(TIFF* tif, tsample_t s)
-{
-	Fax3CodecState* sp = EncoderState(tif);
-
-	(void) s;
-	assert(sp != NULL);
-	sp->bit = 8;
-	sp->data = 0;
-	sp->tag = G3_1D;
-	/*
-	 * This is necessary for Group 4; otherwise it isn't
-	 * needed because the first scanline of each strip ends
-	 * up being copied into the refline.
-	 */
-	if (sp->refline)
-		_TIFFmemset(sp->refline, 0x00, sp->b.rowbytes);
-	if (is2DEncoding(sp)) {
-		float res = tif->tif_dir.td_yresolution;
-		/*
-		 * The CCITT spec says that when doing 2d encoding, you
-		 * should only do it on K consecutive scanlines, where K
-		 * depends on the resolution of the image being encoded
-		 * (2 for <= 200 lpi, 4 for > 200 lpi).  Since the directory
-		 * code initializes td_yresolution to 0, this code will
-		 * select a K of 2 unless the YResolution tag is set
-		 * appropriately.  (Note also that we fudge a little here
-		 * and use 150 lpi to avoid problems with units conversion.)
-		 */
-		if (tif->tif_dir.td_resolutionunit == RESUNIT_CENTIMETER)
-			res *= 2.54f;		/* convert to inches */
-		sp->maxk = (res > 150 ? 4 : 2);
-		sp->k = sp->maxk-1;
-	} else
-		sp->k = sp->maxk = 0;
-	sp->line = 0;
-	return (1);
-}
-
-static const unsigned char zeroruns[256] = {
-    8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,	/* 0x00 - 0x0f */
-    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,	/* 0x10 - 0x1f */
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,	/* 0x20 - 0x2f */
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,	/* 0x30 - 0x3f */
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0x40 - 0x4f */
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0x50 - 0x5f */
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0x60 - 0x6f */
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0x70 - 0x7f */
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x80 - 0x8f */
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x90 - 0x9f */
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0xa0 - 0xaf */
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0xb0 - 0xbf */
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0xc0 - 0xcf */
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0xd0 - 0xdf */
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0xe0 - 0xef */
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0xf0 - 0xff */
-};
-static const unsigned char oneruns[256] = {
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x00 - 0x0f */
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x10 - 0x1f */
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x20 - 0x2f */
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x30 - 0x3f */
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x40 - 0x4f */
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x50 - 0x5f */
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x60 - 0x6f */
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x70 - 0x7f */
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0x80 - 0x8f */
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0x90 - 0x9f */
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0xa0 - 0xaf */
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0xb0 - 0xbf */
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,	/* 0xc0 - 0xcf */
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,	/* 0xd0 - 0xdf */
-    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,	/* 0xe0 - 0xef */
-    4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8,	/* 0xf0 - 0xff */
-};
-
-/*
- * On certain systems it pays to inline
- * the routines that find pixel spans.
- */
-#ifdef VAXC
-static	int32 find0span(unsigned char*, int32, int32);
-static	int32 find1span(unsigned char*, int32, int32);
-#pragma inline(find0span,find1span)
-#endif
-
-/*
- * Find a span of ones or zeros using the supplied
- * table.  The ``base'' of the bit string is supplied
- * along with the start+end bit indices.
- */
-static int32
-find0span(unsigned char* bp, int32 bs, int32 be)
-{
-	int32 bits = be - bs;
-	int32 n, span;
-
-	bp += bs>>3;
-	/*
-	 * Check partial byte on lhs.
-	 */
-	if (bits > 0 && (n = (bs & 7))) {
-		span = zeroruns[(*bp << n) & 0xff];
-		if (span > 8-n)		/* table value too generous */
-			span = 8-n;
-		if (span > bits)	/* constrain span to bit range */
-			span = bits;
-		if (n+span < 8)		/* doesn't extend to edge of byte */
-			return (span);
-		bits -= span;
-		bp++;
-	} else
-		span = 0;
-	if (bits >= (int32)(2 * 8 * sizeof(long))) {
-		long* lp;
-		/*
-		 * Align to longword boundary and check longwords.
-		 */
-		while (!isAligned(bp, long)) {
-			if (*bp != 0x00)
-				return (span + zeroruns[*bp]);
-			span += 8, bits -= 8;
-			bp++;
-		}
-		lp = (long*) bp;
-		while ((bits >= (int32)(8 * sizeof(long))) && (0 == *lp)) {
-			span += 8*sizeof (long), bits -= 8*sizeof (long);
-			lp++;
-		}
-		bp = (unsigned char*) lp;
-	}
-	/*
-	 * Scan full bytes for all 0's.
-	 */
-	while (bits >= 8) {
-		if (*bp != 0x00)	/* end of run */
-			return (span + zeroruns[*bp]);
-		span += 8, bits -= 8;
-		bp++;
-	}
-	/*
-	 * Check partial byte on rhs.
-	 */
-	if (bits > 0) {
-		n = zeroruns[*bp];
-		span += (n > bits ? bits : n);
-	}
-	return (span);
-}
-
-static int32
-find1span(unsigned char* bp, int32 bs, int32 be)
-{
-	int32 bits = be - bs;
-	int32 n, span;
-
-	bp += bs>>3;
-	/*
-	 * Check partial byte on lhs.
-	 */
-	if (bits > 0 && (n = (bs & 7))) {
-		span = oneruns[(*bp << n) & 0xff];
-		if (span > 8-n)		/* table value too generous */
-			span = 8-n;
-		if (span > bits)	/* constrain span to bit range */
-			span = bits;
-		if (n+span < 8)		/* doesn't extend to edge of byte */
-			return (span);
-		bits -= span;
-		bp++;
-	} else
-		span = 0;
-	if (bits >= (int32)(2 * 8 * sizeof(long))) {
-		long* lp;
-		/*
-		 * Align to longword boundary and check longwords.
-		 */
-		while (!isAligned(bp, long)) {
-			if (*bp != 0xff)
-				return (span + oneruns[*bp]);
-			span += 8, bits -= 8;
-			bp++;
-		}
-		lp = (long*) bp;
-		while ((bits >= (int32)(8 * sizeof(long))) && (~0 == *lp)) {
-			span += 8*sizeof (long), bits -= 8*sizeof (long);
-			lp++;
-		}
-		bp = (unsigned char*) lp;
-	}
-	/*
-	 * Scan full bytes for all 1's.
-	 */
-	while (bits >= 8) {
-		if (*bp != 0xff)	/* end of run */
-			return (span + oneruns[*bp]);
-		span += 8, bits -= 8;
-		bp++;
-	}
-	/*
-	 * Check partial byte on rhs.
-	 */
-	if (bits > 0) {
-		n = oneruns[*bp];
-		span += (n > bits ? bits : n);
-	}
-	return (span);
-}
-
-/*
- * Return the offset of the next bit in the range
- * [bs..be] that is different from the specified
- * color.  The end, be, is returned if no such bit
- * exists.
- */
-#define	finddiff(_cp, _bs, _be, _color)	\
-	(_bs + (_color ? find1span(_cp,_bs,_be) : find0span(_cp,_bs,_be)))
-/*
- * Like finddiff, but also check the starting bit
- * against the end in case start > end.
- */
-#define	finddiff2(_cp, _bs, _be, _color) \
-	(_bs < _be ? finddiff(_cp,_bs,_be,_color) : _be)
-
-/*
- * 1d-encode a row of pixels.  The encoding is
- * a sequence of all-white or all-black spans
- * of pixels encoded with Huffman codes.
- */
-static int
-Fax3Encode1DRow(TIFF* tif, unsigned char* bp, uint32 bits)
-{
-	Fax3CodecState* sp = EncoderState(tif);
-	int32 span;
-        uint32 bs = 0;
-
-	for (;;) {
-		span = find0span(bp, bs, bits);		/* white span */
-		putspan(tif, span, TIFFFaxWhiteCodes);
-		bs += span;
-		if (bs >= bits)
-			break;
-		span = find1span(bp, bs, bits);		/* black span */
-		putspan(tif, span, TIFFFaxBlackCodes);
-		bs += span;
-		if (bs >= bits)
-			break;
-	}
-	if (sp->b.mode & (FAXMODE_BYTEALIGN|FAXMODE_WORDALIGN)) {
-		if (sp->bit != 8)			/* byte-align */
-			Fax3FlushBits(tif, sp);
-		if ((sp->b.mode&FAXMODE_WORDALIGN) &&
-		    !isAligned(tif->tif_rawcp, uint16))
-			Fax3FlushBits(tif, sp);
-	}
-	return (1);
-}
-
-static const tableentry horizcode =
-    { 3, 0x1, 0 };	/* 001 */
-static const tableentry passcode =
-    { 4, 0x1, 0 };	/* 0001 */
-static const tableentry vcodes[7] = {
-    { 7, 0x03, 0 },	/* 0000 011 */
-    { 6, 0x03, 0 },	/* 0000 11 */
-    { 3, 0x03, 0 },	/* 011 */
-    { 1, 0x1, 0 },	/* 1 */
-    { 3, 0x2, 0 },	/* 010 */
-    { 6, 0x02, 0 },	/* 0000 10 */
-    { 7, 0x02, 0 }	/* 0000 010 */
-};
-
-/*
- * 2d-encode a row of pixels.  Consult the CCITT
- * documentation for the algorithm.
- */
-static int
-Fax3Encode2DRow(TIFF* tif, unsigned char* bp, unsigned char* rp, uint32 bits)
-{
-#define	PIXEL(buf,ix)	((((buf)[(ix)>>3]) >> (7-((ix)&7))) & 1)
-        uint32 a0 = 0;
-	uint32 a1 = (PIXEL(bp, 0) != 0 ? 0 : finddiff(bp, 0, bits, 0));
-	uint32 b1 = (PIXEL(rp, 0) != 0 ? 0 : finddiff(rp, 0, bits, 0));
-	uint32 a2, b2;
-
-	for (;;) {
-		b2 = finddiff2(rp, b1, bits, PIXEL(rp,b1));
-		if (b2 >= a1) {
-			int32 d = b1 - a1;
-			if (!(-3 <= d && d <= 3)) {	/* horizontal mode */
-				a2 = finddiff2(bp, a1, bits, PIXEL(bp,a1));
-				putcode(tif, &horizcode);
-				if (a0+a1 == 0 || PIXEL(bp, a0) == 0) {
-					putspan(tif, a1-a0, TIFFFaxWhiteCodes);
-					putspan(tif, a2-a1, TIFFFaxBlackCodes);
-				} else {
-					putspan(tif, a1-a0, TIFFFaxBlackCodes);
-					putspan(tif, a2-a1, TIFFFaxWhiteCodes);
-				}
-				a0 = a2;
-			} else {			/* vertical mode */
-				putcode(tif, &vcodes[d+3]);
-				a0 = a1;
-			}
-		} else {				/* pass mode */
-			putcode(tif, &passcode);
-			a0 = b2;
-		}
-		if (a0 >= bits)
-			break;
-		a1 = finddiff(bp, a0, bits, PIXEL(bp,a0));
-		b1 = finddiff(rp, a0, bits, !PIXEL(bp,a0));
-		b1 = finddiff(rp, b1, bits, PIXEL(bp,a0));
-	}
-	return (1);
-#undef PIXEL
-}
-
-/*
- * Encode a buffer of pixels.
- */
-static int
-Fax3Encode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s)
-{
-	Fax3CodecState* sp = EncoderState(tif);
-
-	(void) s;
-	while ((long)cc > 0) {
-		if ((sp->b.mode & FAXMODE_NOEOL) == 0)
-			Fax3PutEOL(tif);
-		if (is2DEncoding(sp)) {
-			if (sp->tag == G3_1D) {
-				if (!Fax3Encode1DRow(tif, bp, sp->b.rowpixels))
-					return (0);
-				sp->tag = G3_2D;
-			} else {
-				if (!Fax3Encode2DRow(tif, bp, sp->refline,
-                                                     sp->b.rowpixels))
-					return (0);
-				sp->k--;
-			}
-			if (sp->k == 0) {
-				sp->tag = G3_1D;
-				sp->k = sp->maxk-1;
-			} else
-				_TIFFmemcpy(sp->refline, bp, sp->b.rowbytes);
-		} else {
-			if (!Fax3Encode1DRow(tif, bp, sp->b.rowpixels))
-				return (0);
-		}
-		bp += sp->b.rowbytes;
-		cc -= sp->b.rowbytes;
-	}
-	return (1);
-}
-
-static int
-Fax3PostEncode(TIFF* tif)
-{
-	Fax3CodecState* sp = EncoderState(tif);
-
-	if (sp->bit != 8)
-		Fax3FlushBits(tif, sp);
-	return (1);
-}
-
-static void
-Fax3Close(TIFF* tif)
-{
-	if ((Fax3State(tif)->mode & FAXMODE_NORTC) == 0) {
-		Fax3CodecState* sp = EncoderState(tif);
-		unsigned int code = EOL;
-		unsigned int length = 12;
-		int i;
-
-		if (is2DEncoding(sp))
-			code = (code<<1) | (sp->tag == G3_1D), length++;
-		for (i = 0; i < 6; i++)
-			Fax3PutBits(tif, code, length);
-		Fax3FlushBits(tif, sp);
-	}
-}
-
-static void
-Fax3Cleanup(TIFF* tif)
-{
-	Fax3CodecState* sp = DecoderState(tif);
-	
-	assert(sp != 0);
-
-	tif->tif_tagmethods.vgetfield = sp->b.vgetparent;
-	tif->tif_tagmethods.vsetfield = sp->b.vsetparent;
-	tif->tif_tagmethods.printdir = sp->b.printdir;
-
-	if (sp->runs)
-		_TIFFfree(sp->runs);
-	if (sp->refline)
-		_TIFFfree(sp->refline);
-
-	if (Fax3State(tif)->subaddress)
-		_TIFFfree(Fax3State(tif)->subaddress);
-	if (Fax3State(tif)->faxdcs)
-		_TIFFfree(Fax3State(tif)->faxdcs);
-
-	_TIFFfree(tif->tif_data);
-	tif->tif_data = NULL;
-
-	_TIFFSetDefaultCompressionState(tif);
-}
-
-#define	FIELD_BADFAXLINES	(FIELD_CODEC+0)
-#define	FIELD_CLEANFAXDATA	(FIELD_CODEC+1)
-#define	FIELD_BADFAXRUN		(FIELD_CODEC+2)
-#define	FIELD_RECVPARAMS	(FIELD_CODEC+3)
-#define	FIELD_SUBADDRESS	(FIELD_CODEC+4)
-#define	FIELD_RECVTIME		(FIELD_CODEC+5)
-#define	FIELD_FAXDCS		(FIELD_CODEC+6)
-
-#define	FIELD_OPTIONS		(FIELD_CODEC+7)
-
-static const TIFFFieldInfo faxFieldInfo[] = {
-    { TIFFTAG_FAXMODE,		 0, 0,	TIFF_ANY,	FIELD_PSEUDO,
-      FALSE,	FALSE,	"FaxMode" },
-    { TIFFTAG_FAXFILLFUNC,	 0, 0,	TIFF_ANY,	FIELD_PSEUDO,
-      FALSE,	FALSE,	"FaxFillFunc" },
-    { TIFFTAG_BADFAXLINES,	 1, 1,	TIFF_LONG,	FIELD_BADFAXLINES,
-      TRUE,	FALSE,	"BadFaxLines" },
-    { TIFFTAG_BADFAXLINES,	 1, 1,	TIFF_SHORT,	FIELD_BADFAXLINES,
-      TRUE,	FALSE,	"BadFaxLines" },
-    { TIFFTAG_CLEANFAXDATA,	 1, 1,	TIFF_SHORT,	FIELD_CLEANFAXDATA,
-      TRUE,	FALSE,	"CleanFaxData" },
-    { TIFFTAG_CONSECUTIVEBADFAXLINES,1,1, TIFF_LONG,	FIELD_BADFAXRUN,
-      TRUE,	FALSE,	"ConsecutiveBadFaxLines" },
-    { TIFFTAG_CONSECUTIVEBADFAXLINES,1,1, TIFF_SHORT,	FIELD_BADFAXRUN,
-      TRUE,	FALSE,	"ConsecutiveBadFaxLines" },
-    { TIFFTAG_FAXRECVPARAMS,	 1, 1, TIFF_LONG,	FIELD_RECVPARAMS,
-      TRUE,	FALSE,	"FaxRecvParams" },
-    { TIFFTAG_FAXSUBADDRESS,	-1,-1, TIFF_ASCII,	FIELD_SUBADDRESS,
-      TRUE,	FALSE,	"FaxSubAddress" },
-    { TIFFTAG_FAXRECVTIME,	 1, 1, TIFF_LONG,	FIELD_RECVTIME,
-      TRUE,	FALSE,	"FaxRecvTime" },
-    { TIFFTAG_FAXDCS,		-1,-1, TIFF_ASCII,	FIELD_FAXDCS,
-      TRUE,	FALSE,	"FaxDcs" },
-};
-static const TIFFFieldInfo fax3FieldInfo[] = {
-    { TIFFTAG_GROUP3OPTIONS,	 1, 1,	TIFF_LONG,	FIELD_OPTIONS,
-      FALSE,	FALSE,	"Group3Options" },
-};
-static const TIFFFieldInfo fax4FieldInfo[] = {
-    { TIFFTAG_GROUP4OPTIONS,	 1, 1,	TIFF_LONG,	FIELD_OPTIONS,
-      FALSE,	FALSE,	"Group4Options" },
-};
-#define	N(a)	(sizeof (a) / sizeof (a[0]))
-
-static int
-Fax3VSetField(TIFF* tif, ttag_t tag, va_list ap)
-{
-	Fax3BaseState* sp = Fax3State(tif);
-	const TIFFFieldInfo* fip;
-
-	assert(sp != 0);
-	assert(sp->vsetparent != 0);
-
-	switch (tag) {
-	case TIFFTAG_FAXMODE:
-		sp->mode = va_arg(ap, int);
-		return 1;			/* NB: pseudo tag */
-	case TIFFTAG_FAXFILLFUNC:
-		DecoderState(tif)->fill = va_arg(ap, TIFFFaxFillFunc);
-		return 1;			/* NB: pseudo tag */
-	case TIFFTAG_GROUP3OPTIONS:
-		/* XXX: avoid reading options if compression mismatches. */
-		if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX3)
-			sp->groupoptions = va_arg(ap, uint32);
-		break;
-	case TIFFTAG_GROUP4OPTIONS:
-		/* XXX: avoid reading options if compression mismatches. */
-		if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4)
-			sp->groupoptions = va_arg(ap, uint32);
-		break;
-	case TIFFTAG_BADFAXLINES:
-		sp->badfaxlines = va_arg(ap, uint32);
-		break;
-	case TIFFTAG_CLEANFAXDATA:
-		sp->cleanfaxdata = (uint16) va_arg(ap, int);
-		break;
-	case TIFFTAG_CONSECUTIVEBADFAXLINES:
-		sp->badfaxrun = va_arg(ap, uint32);
-		break;
-	case TIFFTAG_FAXRECVPARAMS:
-		sp->recvparams = va_arg(ap, uint32);
-		break;
-	case TIFFTAG_FAXSUBADDRESS:
-		_TIFFsetString(&sp->subaddress, va_arg(ap, char*));
-		break;
-	case TIFFTAG_FAXRECVTIME:
-		sp->recvtime = va_arg(ap, uint32);
-		break;
-	case TIFFTAG_FAXDCS:
-		_TIFFsetString(&sp->faxdcs, va_arg(ap, char*));
-		break;
-	default:
-		return (*sp->vsetparent)(tif, tag, ap);
-	}
-	
-	if ((fip = _TIFFFieldWithTag(tif, tag)))
-		TIFFSetFieldBit(tif, fip->field_bit);
-	else
-		return 0;
-
-	tif->tif_flags |= TIFF_DIRTYDIRECT;
-	return 1;
-}
-
-static int
-Fax3VGetField(TIFF* tif, ttag_t tag, va_list ap)
-{
-	Fax3BaseState* sp = Fax3State(tif);
-
-	assert(sp != 0);
-
-	switch (tag) {
-	case TIFFTAG_FAXMODE:
-		*va_arg(ap, int*) = sp->mode;
-		break;
-	case TIFFTAG_FAXFILLFUNC:
-		*va_arg(ap, TIFFFaxFillFunc*) = DecoderState(tif)->fill;
-		break;
-	case TIFFTAG_GROUP3OPTIONS:
-	case TIFFTAG_GROUP4OPTIONS:
-		*va_arg(ap, uint32*) = sp->groupoptions;
-		break;
-	case TIFFTAG_BADFAXLINES:
-		*va_arg(ap, uint32*) = sp->badfaxlines;
-		break;
-	case TIFFTAG_CLEANFAXDATA:
-		*va_arg(ap, uint16*) = sp->cleanfaxdata;
-		break;
-	case TIFFTAG_CONSECUTIVEBADFAXLINES:
-		*va_arg(ap, uint32*) = sp->badfaxrun;
-		break;
-	case TIFFTAG_FAXRECVPARAMS:
-		*va_arg(ap, uint32*) = sp->recvparams;
-		break;
-	case TIFFTAG_FAXSUBADDRESS:
-		*va_arg(ap, char**) = sp->subaddress;
-		break;
-	case TIFFTAG_FAXRECVTIME:
-		*va_arg(ap, uint32*) = sp->recvtime;
-		break;
-	case TIFFTAG_FAXDCS:
-		*va_arg(ap, char**) = sp->faxdcs;
-		break;
-	default:
-		return (*sp->vgetparent)(tif, tag, ap);
-	}
-	return (1);
-}
-
-static void
-Fax3PrintDir(TIFF* tif, FILE* fd, long flags)
-{
-	Fax3BaseState* sp = Fax3State(tif);
-
-	assert(sp != 0);
-
-	(void) flags;
-	if (TIFFFieldSet(tif,FIELD_OPTIONS)) {
-		const char* sep = " ";
-		if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4) {
-			fprintf(fd, "  Group 4 Options:");
-			if (sp->groupoptions & GROUP4OPT_UNCOMPRESSED)
-				fprintf(fd, "%suncompressed data", sep);
-		} else {
-
-			fprintf(fd, "  Group 3 Options:");
-			if (sp->groupoptions & GROUP3OPT_2DENCODING)
-				fprintf(fd, "%s2-d encoding", sep), sep = "+";
-			if (sp->groupoptions & GROUP3OPT_FILLBITS)
-				fprintf(fd, "%sEOL padding", sep), sep = "+";
-			if (sp->groupoptions & GROUP3OPT_UNCOMPRESSED)
-				fprintf(fd, "%suncompressed data", sep);
-		}
-		fprintf(fd, " (%lu = 0x%lx)\n",
-                        (unsigned long) sp->groupoptions,
-                        (unsigned long) sp->groupoptions);
-	}
-	if (TIFFFieldSet(tif,FIELD_CLEANFAXDATA)) {
-		fprintf(fd, "  Fax Data:");
-		switch (sp->cleanfaxdata) {
-		case CLEANFAXDATA_CLEAN:
-			fprintf(fd, " clean");
-			break;
-		case CLEANFAXDATA_REGENERATED:
-			fprintf(fd, " receiver regenerated");
-			break;
-		case CLEANFAXDATA_UNCLEAN:
-			fprintf(fd, " uncorrected errors");
-			break;
-		}
-		fprintf(fd, " (%u = 0x%x)\n",
-		    sp->cleanfaxdata, sp->cleanfaxdata);
-	}
-	if (TIFFFieldSet(tif,FIELD_BADFAXLINES))
-		fprintf(fd, "  Bad Fax Lines: %lu\n",
-                        (unsigned long) sp->badfaxlines);
-	if (TIFFFieldSet(tif,FIELD_BADFAXRUN))
-		fprintf(fd, "  Consecutive Bad Fax Lines: %lu\n",
-		    (unsigned long) sp->badfaxrun);
-	if (TIFFFieldSet(tif,FIELD_RECVPARAMS))
-		fprintf(fd, "  Fax Receive Parameters: %08lx\n",
-		   (unsigned long) sp->recvparams);
-	if (TIFFFieldSet(tif,FIELD_SUBADDRESS))
-		fprintf(fd, "  Fax SubAddress: %s\n", sp->subaddress);
-	if (TIFFFieldSet(tif,FIELD_RECVTIME))
-		fprintf(fd, "  Fax Receive Time: %lu secs\n",
-		    (unsigned long) sp->recvtime);
-	if (TIFFFieldSet(tif,FIELD_FAXDCS))
-		fprintf(fd, "  Fax DCS: %s\n", sp->faxdcs);
-}
-
-static int
-InitCCITTFax3(TIFF* tif)
-{
-	Fax3BaseState* sp;
-
-	/*
-	 * Merge codec-specific tag information.
-	 */
-	if (!_TIFFMergeFieldInfo(tif, faxFieldInfo, N(faxFieldInfo))) {
-		TIFFErrorExt(tif->tif_clientdata, "InitCCITTFax3",
-			"Merging common CCITT Fax codec-specific tags failed");
-		return 0;
-	}
-
-	/*
-	 * Allocate state block so tag methods have storage to record values.
-	 */
-	tif->tif_data = (tidata_t)
-		_TIFFmalloc(sizeof (Fax3CodecState));
-
-	if (tif->tif_data == NULL) {
-		TIFFErrorExt(tif->tif_clientdata, "TIFFInitCCITTFax3",
-		    "%s: No space for state block", tif->tif_name);
-		return (0);
-	}
-
-	sp = Fax3State(tif);
-        sp->rw_mode = tif->tif_mode;
-
-	/*
-	 * Override parent get/set field methods.
-	 */
-	sp->vgetparent = tif->tif_tagmethods.vgetfield;
-	tif->tif_tagmethods.vgetfield = Fax3VGetField; /* hook for codec tags */
-	sp->vsetparent = tif->tif_tagmethods.vsetfield;
-	tif->tif_tagmethods.vsetfield = Fax3VSetField; /* hook for codec tags */
-	sp->printdir = tif->tif_tagmethods.printdir;
-	tif->tif_tagmethods.printdir = Fax3PrintDir;   /* hook for codec tags */
-	sp->groupoptions = 0;	
-	sp->recvparams = 0;
-	sp->subaddress = NULL;
-	sp->faxdcs = NULL;
-
-	if (sp->rw_mode == O_RDONLY) /* FIXME: improve for in place update */
-		tif->tif_flags |= TIFF_NOBITREV; /* decoder does bit reversal */
-	DecoderState(tif)->runs = NULL;
-	TIFFSetField(tif, TIFFTAG_FAXFILLFUNC, _TIFFFax3fillruns);
-	EncoderState(tif)->refline = NULL;
-
-	/*
-	 * Install codec methods.
-	 */
-	tif->tif_setupdecode = Fax3SetupState;
-	tif->tif_predecode = Fax3PreDecode;
-	tif->tif_decoderow = Fax3Decode1D;
-	tif->tif_decodestrip = Fax3Decode1D;
-	tif->tif_decodetile = Fax3Decode1D;
-	tif->tif_setupencode = Fax3SetupState;
-	tif->tif_preencode = Fax3PreEncode;
-	tif->tif_postencode = Fax3PostEncode;
-	tif->tif_encoderow = Fax3Encode;
-	tif->tif_encodestrip = Fax3Encode;
-	tif->tif_encodetile = Fax3Encode;
-	tif->tif_close = Fax3Close;
-	tif->tif_cleanup = Fax3Cleanup;
-
-	return (1);
-}
-
-int
-TIFFInitCCITTFax3(TIFF* tif, int scheme)
-{
-	(void) scheme;
-	if (InitCCITTFax3(tif)) {
-		/*
-		 * Merge codec-specific tag information.
-		 */
-		if (!_TIFFMergeFieldInfo(tif, fax3FieldInfo, N(fax3FieldInfo))) {
-			TIFFErrorExt(tif->tif_clientdata, "TIFFInitCCITTFax3",
-			"Merging CCITT Fax 3 codec-specific tags failed");
-			return 0;
-		}
-
-		/*
-		 * The default format is Class/F-style w/o RTC.
-		 */
-		return TIFFSetField(tif, TIFFTAG_FAXMODE, FAXMODE_CLASSF);
-	} else
-		return 01;
-}
-
-/*
- * CCITT Group 4 (T.6) Facsimile-compatible
- * Compression Scheme Support.
- */
-
-#define	SWAP(t,a,b)	{ t x; x = (a); (a) = (b); (b) = x; }
-/*
- * Decode the requested amount of G4-encoded data.
- */
-static int
-Fax4Decode(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s)
-{
-	DECLARE_STATE_2D(tif, sp, "Fax4Decode");
-
-	(void) s;
-	CACHE_STATE(tif, sp);
-	while ((long)occ > 0) {
-		a0 = 0;
-		RunLength = 0;
-		pa = thisrun = sp->curruns;
-		pb = sp->refruns;
-		b1 = *pb++;
-#ifdef FAX3_DEBUG
-		printf("\nBitAcc=%08X, BitsAvail = %d\n", BitAcc, BitsAvail);
-		printf("-------------------- %d\n", tif->tif_row);
-		fflush(stdout);
-#endif
-		EXPAND2D(EOFG4);
-                if (EOLcnt)
-                    goto EOFG4;
-		(*sp->fill)(buf, thisrun, pa, lastx);
-		SETVALUE(0);		/* imaginary change for reference */
-		SWAP(uint32*, sp->curruns, sp->refruns);
-		buf += sp->b.rowbytes;
-		occ -= sp->b.rowbytes;
-		sp->line++;
-		continue;
-	EOFG4:
-                NeedBits16( 13, BADG4 );
-        BADG4:
-#ifdef FAX3_DEBUG
-                if( GetBits(13) != 0x1001 )
-                    fputs( "Bad EOFB\n", stderr );
-#endif                
-                ClrBits( 13 );
-		(*sp->fill)(buf, thisrun, pa, lastx);
-		UNCACHE_STATE(tif, sp);
-		return ( sp->line ? 1 : -1);	/* don't error on badly-terminated strips */
-	}
-	UNCACHE_STATE(tif, sp);
-	return (1);
-}
-#undef	SWAP
-
-/*
- * Encode the requested amount of data.
- */
-static int
-Fax4Encode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s)
-{
-	Fax3CodecState *sp = EncoderState(tif);
-
-	(void) s;
-	while ((long)cc > 0) {
-		if (!Fax3Encode2DRow(tif, bp, sp->refline, sp->b.rowpixels))
-			return (0);
-		_TIFFmemcpy(sp->refline, bp, sp->b.rowbytes);
-		bp += sp->b.rowbytes;
-		cc -= sp->b.rowbytes;
-	}
-	return (1);
-}
-
-static int
-Fax4PostEncode(TIFF* tif)
-{
-	Fax3CodecState *sp = EncoderState(tif);
-
-	/* terminate strip w/ EOFB */
-	Fax3PutBits(tif, EOL, 12);
-	Fax3PutBits(tif, EOL, 12);
-	if (sp->bit != 8)
-		Fax3FlushBits(tif, sp);
-	return (1);
-}
-
-int
-TIFFInitCCITTFax4(TIFF* tif, int scheme)
-{
-	(void) scheme;
-	if (InitCCITTFax3(tif)) {		/* reuse G3 support */
-		/*
-		 * Merge codec-specific tag information.
-		 */
-		if (!_TIFFMergeFieldInfo(tif, fax4FieldInfo, N(fax4FieldInfo))) {
-			TIFFErrorExt(tif->tif_clientdata, "TIFFInitCCITTFax4",
-			"Merging CCITT Fax 4 codec-specific tags failed");
-			return 0;
-		}
-
-		tif->tif_decoderow = Fax4Decode;
-		tif->tif_decodestrip = Fax4Decode;
-		tif->tif_decodetile = Fax4Decode;
-		tif->tif_encoderow = Fax4Encode;
-		tif->tif_encodestrip = Fax4Encode;
-		tif->tif_encodetile = Fax4Encode;
-		tif->tif_postencode = Fax4PostEncode;
-		/*
-		 * Suppress RTC at the end of each strip.
-		 */
-		return TIFFSetField(tif, TIFFTAG_FAXMODE, FAXMODE_NORTC);
-	} else
-		return (0);
-}
-
-/*
- * CCITT Group 3 1-D Modified Huffman RLE Compression Support.
- * (Compression algorithms 2 and 32771)
- */
-
-/*
- * Decode the requested amount of RLE-encoded data.
- */
-static int
-Fax3DecodeRLE(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s)
-{
-	DECLARE_STATE(tif, sp, "Fax3DecodeRLE");
-	int mode = sp->b.mode;
-
-	(void) s;
-	CACHE_STATE(tif, sp);
-	thisrun = sp->curruns;
-	while ((long)occ > 0) {
-		a0 = 0;
-		RunLength = 0;
-		pa = thisrun;
-#ifdef FAX3_DEBUG
-		printf("\nBitAcc=%08X, BitsAvail = %d\n", BitAcc, BitsAvail);
-		printf("-------------------- %d\n", tif->tif_row);
-		fflush(stdout);
-#endif
-		EXPAND1D(EOFRLE);
-		(*sp->fill)(buf, thisrun, pa, lastx);
-		/*
-		 * Cleanup at the end of the row.
-		 */
-		if (mode & FAXMODE_BYTEALIGN) {
-			int n = BitsAvail - (BitsAvail &~ 7);
-			ClrBits(n);
-		} else if (mode & FAXMODE_WORDALIGN) {
-			int n = BitsAvail - (BitsAvail &~ 15);
-			ClrBits(n);
-			if (BitsAvail == 0 && !isAligned(cp, uint16))
-			    cp++;
-		}
-		buf += sp->b.rowbytes;
-		occ -= sp->b.rowbytes;
-		sp->line++;
-		continue;
-	EOFRLE:				/* premature EOF */
-		(*sp->fill)(buf, thisrun, pa, lastx);
-		UNCACHE_STATE(tif, sp);
-		return (-1);
-	}
-	UNCACHE_STATE(tif, sp);
-	return (1);
-}
-
-int
-TIFFInitCCITTRLE(TIFF* tif, int scheme)
-{
-	(void) scheme;
-	if (InitCCITTFax3(tif)) {		/* reuse G3 support */
-		tif->tif_decoderow = Fax3DecodeRLE;
-		tif->tif_decodestrip = Fax3DecodeRLE;
-		tif->tif_decodetile = Fax3DecodeRLE;
-		/*
-		 * Suppress RTC+EOLs when encoding and byte-align data.
-		 */
-		return TIFFSetField(tif, TIFFTAG_FAXMODE,
-		    FAXMODE_NORTC|FAXMODE_NOEOL|FAXMODE_BYTEALIGN);
-	} else
-		return (0);
-}
-
-int
-TIFFInitCCITTRLEW(TIFF* tif, int scheme)
-{
-	(void) scheme;
-	if (InitCCITTFax3(tif)) {		/* reuse G3 support */
-		tif->tif_decoderow = Fax3DecodeRLE;
-		tif->tif_decodestrip = Fax3DecodeRLE;
-		tif->tif_decodetile = Fax3DecodeRLE;
-		/*
-		 * Suppress RTC+EOLs when encoding and word-align data.
-		 */
-		return TIFFSetField(tif, TIFFTAG_FAXMODE,
-		    FAXMODE_NORTC|FAXMODE_NOEOL|FAXMODE_WORDALIGN);
-	} else
-		return (0);
-}
-#endif /* CCITT_SUPPORT */
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_fax3.h b/Source/LibTIFF/tif_fax3.h
deleted file mode 100644
index b9edaa2..0000000
--- a/Source/LibTIFF/tif_fax3.h
+++ /dev/null
@@ -1,538 +0,0 @@
-/* $Id: tif_fax3.h,v 1.37 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1990-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-#ifndef _FAX3_
-#define	_FAX3_
-/*
- * TIFF Library.
- *
- * CCITT Group 3 (T.4) and Group 4 (T.6) Decompression Support.
- *
- * Decoder support is derived, with permission, from the code
- * in Frank Cringle's viewfax program;
- *      Copyright (C) 1990, 1995  Frank D. Cringle.
- */
-#include "tiff.h"
-
-/*
- * To override the default routine used to image decoded
- * spans one can use the pseduo tag TIFFTAG_FAXFILLFUNC.
- * The routine must have the type signature given below;
- * for example:
- *
- * fillruns(unsigned char* buf, uint32* runs, uint32* erun, uint32 lastx)
- *
- * where buf is place to set the bits, runs is the array of b&w run
- * lengths (white then black), erun is the last run in the array, and
- * lastx is the width of the row in pixels.  Fill routines can assume
- * the run array has room for at least lastx runs and can overwrite
- * data in the run array as needed (e.g. to append zero runs to bring
- * the count up to a nice multiple).
- */
-typedef	void (*TIFFFaxFillFunc)(unsigned char*, uint32*, uint32*, uint32);
-
-/*
- * The default run filler; made external for other decoders.
- */
-#if defined(__cplusplus)
-extern "C" {
-#endif
-extern	void _TIFFFax3fillruns(unsigned char*, uint32*, uint32*, uint32);
-#if defined(__cplusplus)
-}
-#endif
-
-
-/* finite state machine codes */
-#define S_Null		0
-#define S_Pass		1
-#define S_Horiz		2
-#define S_V0		3
-#define S_VR		4
-#define S_VL		5
-#define S_Ext		6
-#define S_TermW		7
-#define S_TermB		8
-#define S_MakeUpW	9
-#define S_MakeUpB	10
-#define S_MakeUp	11
-#define S_EOL		12
-
-typedef struct {		/* state table entry */
-	unsigned char State;	/* see above */
-	unsigned char Width;	/* width of code in bits */
-	uint32	Param;		/* unsigned 32-bit run length in bits */
-} TIFFFaxTabEnt;
-
-extern	const TIFFFaxTabEnt TIFFFaxMainTable[];
-extern	const TIFFFaxTabEnt TIFFFaxWhiteTable[];
-extern	const TIFFFaxTabEnt TIFFFaxBlackTable[];
-
-/*
- * The following macros define the majority of the G3/G4 decoder
- * algorithm using the state tables defined elsewhere.  To build
- * a decoder you need some setup code and some glue code. Note
- * that you may also need/want to change the way the NeedBits*
- * macros get input data if, for example, you know the data to be
- * decoded is properly aligned and oriented (doing so before running
- * the decoder can be a big performance win).
- *
- * Consult the decoder in the TIFF library for an idea of what you
- * need to define and setup to make use of these definitions.
- *
- * NB: to enable a debugging version of these macros define FAX3_DEBUG
- *     before including this file.  Trace output goes to stdout.
- */
-
-#ifndef EndOfData
-#define EndOfData()	(cp >= ep)
-#endif
-/*
- * Need <=8 or <=16 bits of input data.  Unlike viewfax we
- * cannot use/assume a word-aligned, properly bit swizzled
- * input data set because data may come from an arbitrarily
- * aligned, read-only source such as a memory-mapped file.
- * Note also that the viewfax decoder does not check for
- * running off the end of the input data buffer.  This is
- * possible for G3-encoded data because it prescans the input
- * data to count EOL markers, but can cause problems for G4
- * data.  In any event, we don't prescan and must watch for
- * running out of data since we can't permit the library to
- * scan past the end of the input data buffer.
- *
- * Finally, note that we must handle remaindered data at the end
- * of a strip specially.  The coder asks for a fixed number of
- * bits when scanning for the next code.  This may be more bits
- * than are actually present in the data stream.  If we appear
- * to run out of data but still have some number of valid bits
- * remaining then we makeup the requested amount with zeros and
- * return successfully.  If the returned data is incorrect then
- * we should be called again and get a premature EOF error;
- * otherwise we should get the right answer.
- */
-#ifndef NeedBits8
-#define NeedBits8(n,eoflab) do {					\
-    if (BitsAvail < (n)) {						\
-	if (EndOfData()) {						\
-	    if (BitsAvail == 0)			/* no valid bits */	\
-		goto eoflab;						\
-	    BitsAvail = (n);			/* pad with zeros */	\
-	} else {							\
-	    BitAcc |= ((uint32) bitmap[*cp++])<<BitsAvail;		\
-	    BitsAvail += 8;						\
-	}								\
-    }									\
-} while (0)
-#endif
-#ifndef NeedBits16
-#define NeedBits16(n,eoflab) do {					\
-    if (BitsAvail < (n)) {						\
-	if (EndOfData()) {						\
-	    if (BitsAvail == 0)			/* no valid bits */	\
-		goto eoflab;						\
-	    BitsAvail = (n);			/* pad with zeros */	\
-	} else {							\
-	    BitAcc |= ((uint32) bitmap[*cp++])<<BitsAvail;		\
-	    if ((BitsAvail += 8) < (n)) {				\
-		if (EndOfData()) {					\
-		    /* NB: we know BitsAvail is non-zero here */	\
-		    BitsAvail = (n);		/* pad with zeros */	\
-		} else {						\
-		    BitAcc |= ((uint32) bitmap[*cp++])<<BitsAvail;	\
-		    BitsAvail += 8;					\
-		}							\
-	    }								\
-	}								\
-    }									\
-} while (0)
-#endif
-#define GetBits(n)	(BitAcc & ((1<<(n))-1))
-#define ClrBits(n) do {							\
-    BitsAvail -= (n);							\
-    BitAcc >>= (n);							\
-} while (0)
-
-#ifdef FAX3_DEBUG
-static const char* StateNames[] = {
-    "Null   ",
-    "Pass   ",
-    "Horiz  ",
-    "V0     ",
-    "VR     ",
-    "VL     ",
-    "Ext    ",
-    "TermW  ",
-    "TermB  ",
-    "MakeUpW",
-    "MakeUpB",
-    "MakeUp ",
-    "EOL    ",
-};
-#define DEBUG_SHOW putchar(BitAcc & (1 << t) ? '1' : '0')
-#define LOOKUP8(wid,tab,eoflab) do {					\
-    int t;								\
-    NeedBits8(wid,eoflab);						\
-    TabEnt = tab + GetBits(wid);					\
-    printf("%08lX/%d: %s%5d\t", (long) BitAcc, BitsAvail,		\
-	   StateNames[TabEnt->State], TabEnt->Param);			\
-    for (t = 0; t < TabEnt->Width; t++)					\
-	DEBUG_SHOW;							\
-    putchar('\n');							\
-    fflush(stdout);							\
-    ClrBits(TabEnt->Width);						\
-} while (0)
-#define LOOKUP16(wid,tab,eoflab) do {					\
-    int t;								\
-    NeedBits16(wid,eoflab);						\
-    TabEnt = tab + GetBits(wid);					\
-    printf("%08lX/%d: %s%5d\t", (long) BitAcc, BitsAvail,		\
-	   StateNames[TabEnt->State], TabEnt->Param);			\
-    for (t = 0; t < TabEnt->Width; t++)					\
-	DEBUG_SHOW;							\
-    putchar('\n');							\
-    fflush(stdout);							\
-    ClrBits(TabEnt->Width);						\
-} while (0)
-
-#define SETVALUE(x) do {							\
-    *pa++ = RunLength + (x);						\
-    printf("SETVALUE: %d\t%d\n", RunLength + (x), a0);			\
-    a0 += x;								\
-    RunLength = 0;							\
-} while (0)
-#else
-#define LOOKUP8(wid,tab,eoflab) do {					\
-    NeedBits8(wid,eoflab);						\
-    TabEnt = tab + GetBits(wid);					\
-    ClrBits(TabEnt->Width);						\
-} while (0)
-#define LOOKUP16(wid,tab,eoflab) do {					\
-    NeedBits16(wid,eoflab);						\
-    TabEnt = tab + GetBits(wid);					\
-    ClrBits(TabEnt->Width);						\
-} while (0)
-
-/*
- * Append a run to the run length array for the
- * current row and reset decoding state.
- */
-#define SETVALUE(x) do {							\
-    *pa++ = RunLength + (x);						\
-    a0 += (x);								\
-    RunLength = 0;							\
-} while (0)
-#endif
-
-/*
- * Synchronize input decoding at the start of each
- * row by scanning for an EOL (if appropriate) and
- * skipping any trash data that might be present
- * after a decoding error.  Note that the decoding
- * done elsewhere that recognizes an EOL only consumes
- * 11 consecutive zero bits.  This means that if EOLcnt
- * is non-zero then we still need to scan for the final flag
- * bit that is part of the EOL code.
- */
-#define	SYNC_EOL(eoflab) do {						\
-    if (EOLcnt == 0) {							\
-	for (;;) {							\
-	    NeedBits16(11,eoflab);					\
-	    if (GetBits(11) == 0)					\
-		break;							\
-	    ClrBits(1);							\
-	}								\
-    }									\
-    for (;;) {								\
-	NeedBits8(8,eoflab);						\
-	if (GetBits(8))							\
-	    break;							\
-	ClrBits(8);							\
-    }									\
-    while (GetBits(1) == 0)						\
-	ClrBits(1);							\
-    ClrBits(1);				/* EOL bit */			\
-    EOLcnt = 0;				/* reset EOL counter/flag */	\
-} while (0)
-
-/*
- * Cleanup the array of runs after decoding a row.
- * We adjust final runs to insure the user buffer is not
- * overwritten and/or undecoded area is white filled.
- */
-#define	CLEANUP_RUNS() do {						\
-    if (RunLength)							\
-	SETVALUE(0);							\
-    if (a0 != lastx) {							\
-	badlength(a0, lastx);						\
-	while (a0 > lastx && pa > thisrun)				\
-	    a0 -= *--pa;						\
-	if (a0 < lastx) {						\
-	    if (a0 < 0)							\
-		a0 = 0;							\
-	    if ((pa-thisrun)&1)						\
-		SETVALUE(0);						\
-	    SETVALUE(lastx - a0);						\
-	} else if (a0 > lastx) {					\
-	    SETVALUE(lastx);						\
-	    SETVALUE(0);							\
-	}								\
-    }									\
-} while (0)
-
-/*
- * Decode a line of 1D-encoded data.
- *
- * The line expanders are written as macros so that they can be reused
- * but still have direct access to the local variables of the "calling"
- * function.
- *
- * Note that unlike the original version we have to explicitly test for
- * a0 >= lastx after each black/white run is decoded.  This is because
- * the original code depended on the input data being zero-padded to
- * insure the decoder recognized an EOL before running out of data.
- */
-#define EXPAND1D(eoflab) do {						\
-    for (;;) {								\
-	for (;;) {							\
-	    LOOKUP16(12, TIFFFaxWhiteTable, eof1d);			\
-	    switch (TabEnt->State) {					\
-	    case S_EOL:							\
-		EOLcnt = 1;						\
-		goto done1d;						\
-	    case S_TermW:						\
-		SETVALUE(TabEnt->Param);					\
-		goto doneWhite1d;					\
-	    case S_MakeUpW:						\
-	    case S_MakeUp:						\
-		a0 += TabEnt->Param;					\
-		RunLength += TabEnt->Param;				\
-		break;							\
-	    default:							\
-		unexpected("WhiteTable", a0);				\
-		goto done1d;						\
-	    }								\
-	}								\
-    doneWhite1d:							\
-	if (a0 >= lastx)						\
-	    goto done1d;						\
-	for (;;) {							\
-	    LOOKUP16(13, TIFFFaxBlackTable, eof1d);			\
-	    switch (TabEnt->State) {					\
-	    case S_EOL:							\
-		EOLcnt = 1;						\
-		goto done1d;						\
-	    case S_TermB:						\
-		SETVALUE(TabEnt->Param);					\
-		goto doneBlack1d;					\
-	    case S_MakeUpB:						\
-	    case S_MakeUp:						\
-		a0 += TabEnt->Param;					\
-		RunLength += TabEnt->Param;				\
-		break;							\
-	    default:							\
-		unexpected("BlackTable", a0);				\
-		goto done1d;						\
-	    }								\
-	}								\
-    doneBlack1d:							\
-	if (a0 >= lastx)						\
-	    goto done1d;						\
-        if( *(pa-1) == 0 && *(pa-2) == 0 )				\
-            pa -= 2;                                                    \
-    }									\
-eof1d:									\
-    prematureEOF(a0);							\
-    CLEANUP_RUNS();							\
-    goto eoflab;							\
-done1d:									\
-    CLEANUP_RUNS();							\
-} while (0)
-
-/*
- * Update the value of b1 using the array
- * of runs for the reference line.
- */
-#define CHECK_b1 do {							\
-    if (pa != thisrun) while (b1 <= a0 && b1 < lastx) {			\
-	b1 += pb[0] + pb[1];						\
-	pb += 2;							\
-    }									\
-} while (0)
-
-/*
- * Expand a row of 2D-encoded data.
- */
-#define EXPAND2D(eoflab) do {						\
-    while (a0 < lastx) {						\
-	LOOKUP8(7, TIFFFaxMainTable, eof2d);				\
-	switch (TabEnt->State) {					\
-	case S_Pass:							\
-	    CHECK_b1;							\
-	    b1 += *pb++;						\
-	    RunLength += b1 - a0;					\
-	    a0 = b1;							\
-	    b1 += *pb++;						\
-	    break;							\
-	case S_Horiz:							\
-	    if ((pa-thisrun)&1) {					\
-		for (;;) {	/* black first */			\
-		    LOOKUP16(13, TIFFFaxBlackTable, eof2d);		\
-		    switch (TabEnt->State) {				\
-		    case S_TermB:					\
-			SETVALUE(TabEnt->Param);				\
-			goto doneWhite2da;				\
-		    case S_MakeUpB:					\
-		    case S_MakeUp:					\
-			a0 += TabEnt->Param;				\
-			RunLength += TabEnt->Param;			\
-			break;						\
-		    default:						\
-			goto badBlack2d;				\
-		    }							\
-		}							\
-	    doneWhite2da:;						\
-		for (;;) {	/* then white */			\
-		    LOOKUP16(12, TIFFFaxWhiteTable, eof2d);		\
-		    switch (TabEnt->State) {				\
-		    case S_TermW:					\
-			SETVALUE(TabEnt->Param);				\
-			goto doneBlack2da;				\
-		    case S_MakeUpW:					\
-		    case S_MakeUp:					\
-			a0 += TabEnt->Param;				\
-			RunLength += TabEnt->Param;			\
-			break;						\
-		    default:						\
-			goto badWhite2d;				\
-		    }							\
-		}							\
-	    doneBlack2da:;						\
-	    } else {							\
-		for (;;) {	/* white first */			\
-		    LOOKUP16(12, TIFFFaxWhiteTable, eof2d);		\
-		    switch (TabEnt->State) {				\
-		    case S_TermW:					\
-			SETVALUE(TabEnt->Param);				\
-			goto doneWhite2db;				\
-		    case S_MakeUpW:					\
-		    case S_MakeUp:					\
-			a0 += TabEnt->Param;				\
-			RunLength += TabEnt->Param;			\
-			break;						\
-		    default:						\
-			goto badWhite2d;				\
-		    }							\
-		}							\
-	    doneWhite2db:;						\
-		for (;;) {	/* then black */			\
-		    LOOKUP16(13, TIFFFaxBlackTable, eof2d);		\
-		    switch (TabEnt->State) {				\
-		    case S_TermB:					\
-			SETVALUE(TabEnt->Param);				\
-			goto doneBlack2db;				\
-		    case S_MakeUpB:					\
-		    case S_MakeUp:					\
-			a0 += TabEnt->Param;				\
-			RunLength += TabEnt->Param;			\
-			break;						\
-		    default:						\
-			goto badBlack2d;				\
-		    }							\
-		}							\
-	    doneBlack2db:;						\
-	    }								\
-	    CHECK_b1;							\
-	    break;							\
-	case S_V0:							\
-	    CHECK_b1;							\
-	    SETVALUE(b1 - a0);						\
-	    b1 += *pb++;						\
-	    break;							\
-	case S_VR:							\
-	    CHECK_b1;							\
-	    SETVALUE(b1 - a0 + TabEnt->Param);				\
-	    b1 += *pb++;						\
-	    break;							\
-	case S_VL:							\
-	    CHECK_b1;							\
-	    if (b1 <= (int) (a0 + TabEnt->Param)) {			\
-		if (b1 < (int) (a0 + TabEnt->Param) || pa != thisrun) {	\
-		    unexpected("VL", a0);				\
-		    goto eol2d;						\
-		}							\
-	    }								\
-	    SETVALUE(b1 - a0 - TabEnt->Param);				\
-	    b1 -= *--pb;						\
-	    break;							\
-	case S_Ext:							\
-	    *pa++ = lastx - a0;						\
-	    extension(a0);						\
-	    goto eol2d;							\
-	case S_EOL:							\
-	    *pa++ = lastx - a0;						\
-	    NeedBits8(4,eof2d);						\
-	    if (GetBits(4))						\
-		unexpected("EOL", a0);					\
-            ClrBits(4);                                                 \
-	    EOLcnt = 1;							\
-	    goto eol2d;							\
-	default:							\
-	badMain2d:							\
-	    unexpected("MainTable", a0);				\
-	    goto eol2d;							\
-	badBlack2d:							\
-	    unexpected("BlackTable", a0);				\
-	    goto eol2d;							\
-	badWhite2d:							\
-	    unexpected("WhiteTable", a0);				\
-	    goto eol2d;							\
-	eof2d:								\
-	    prematureEOF(a0);						\
-	    CLEANUP_RUNS();						\
-	    goto eoflab;						\
-	}								\
-    }									\
-    if (RunLength) {							\
-	if (RunLength + a0 < lastx) {					\
-	    /* expect a final V0 */					\
-	    NeedBits8(1,eof2d);						\
-	    if (!GetBits(1))						\
-		goto badMain2d;						\
-	    ClrBits(1);							\
-	}								\
-	SETVALUE(0);							\
-    }									\
-eol2d:									\
-    CLEANUP_RUNS();							\
-} while (0)
-#endif /* _FAX3_ */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_fax3sm.c b/Source/LibTIFF/tif_fax3sm.c
deleted file mode 100644
index 822191e..0000000
--- a/Source/LibTIFF/tif_fax3sm.c
+++ /dev/null
@@ -1,1260 +0,0 @@
-/* WARNING, this file was automatically generated by the
-    mkg3states program */
-#include "tiff.h"
-#include "tif_fax3.h"
- const TIFFFaxTabEnt TIFFFaxMainTable[128] = {
-{12,7,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{1,4,0},{3,1,0},
-{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{5,6,2},{3,1,0},{5,3,1},{3,1,0},
-{2,3,0},{3,1,0},{4,3,1},{3,1,0},{1,4,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},
-{4,3,1},{3,1,0},{5,7,3},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},
-{1,4,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{4,6,2},{3,1,0},
-{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{1,4,0},{3,1,0},{5,3,1},{3,1,0},
-{2,3,0},{3,1,0},{4,3,1},{3,1,0},{6,7,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},
-{4,3,1},{3,1,0},{1,4,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},
-{5,6,2},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{1,4,0},{3,1,0},
-{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{4,7,3},{3,1,0},{5,3,1},{3,1,0},
-{2,3,0},{3,1,0},{4,3,1},{3,1,0},{1,4,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},
-{4,3,1},{3,1,0},{4,6,2},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},
-{1,4,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0}
-};
- const TIFFFaxTabEnt TIFFFaxWhiteTable[4096] = {
-{12,11,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},
-{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},
-{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},
-{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
-{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
-{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},
-{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,960},{7,4,6},{7,8,31},{7,5,8},
-{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},
-{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},
-{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},
-{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,11,1792},{7,4,3},
-{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},
-{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},
-{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},
-{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1600},{7,4,5},
-{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
-{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},
-{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},
-{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},
-{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},
-{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},
-{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},
-{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},
-{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},
-{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},
-{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1536},{7,4,5},{7,8,43},{7,6,17},
-{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},
-{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},
-{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,768},{7,4,6},
-{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
-{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,11,1856},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
-{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},
-{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,896},{7,4,6},{7,7,19},{7,5,8},
-{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},
-{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},
-{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5},{7,8,44},{7,6,17},{9,9,1408},{7,4,6},
-{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},
-{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},
-{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},
-{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},
-{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},
-{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
-{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},
-{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},
-{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},
-{7,6,13},{7,4,3},{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6},{7,6,1},{7,5,8},
-{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},
-{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},
-{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,960},{7,4,6},
-{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},
-{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},
-{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},
-{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{11,12,2112},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},
-{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},
-{7,8,40},{7,6,16},{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},
-{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
-{9,9,1600},{7,4,5},{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
-{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},
-{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6},{7,8,32},{7,5,8},
-{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},
-{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},
-{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},
-{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},
-{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},
-{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},
-{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},
-{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1536},{7,4,5},
-{7,8,43},{7,6,17},{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
-{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},
-{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},
-{9,9,768},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},
-{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},
-{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,12,2368},{7,4,3},{7,5,11},{7,4,5},
-{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},
-{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,896},{7,4,6},
-{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},
-{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},
-{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5},{7,8,44},{7,6,17},
-{9,9,1408},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},
-{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},
-{7,8,42},{7,6,16},{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},
-{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
-{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
-{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},
-{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},
-{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},
-{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},
-{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6},
-{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},
-{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},
-{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},
-{9,9,960},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128},
-{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},
-{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{11,12,1984},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
-{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},
-{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},
-{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},
-{7,6,13},{7,4,3},{9,9,1600},{7,4,5},{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8},
-{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},
-{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},
-{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6},
-{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},
-{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},
-{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},
-{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},
-{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},
-{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},
-{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
-{9,9,1536},{7,4,5},{7,8,43},{7,6,17},{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
-{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},
-{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8},
-{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},
-{7,7,26},{7,5,9},{9,9,768},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},
-{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},
-{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,11,1920},{7,4,3},
-{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},
-{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},
-{9,9,896},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},
-{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5},
-{7,8,44},{7,6,17},{9,9,1408},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
-{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},
-{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},
-{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},
-{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},
-{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},
-{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},
-{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},
-{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},
-{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},
-{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1472},{7,4,5},{7,8,43},{7,6,17},
-{9,9,1216},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},
-{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},
-{7,8,41},{7,6,16},{9,9,960},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,704},{7,4,6},
-{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
-{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,12,2240},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
-{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},
-{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,832},{7,4,6},{7,7,19},{7,5,8},
-{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},
-{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},
-{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1600},{7,4,5},{7,8,44},{7,6,17},{9,9,1344},{7,4,6},
-{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},
-{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},
-{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},
-{9,9,1088},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},
-{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},
-{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
-{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},
-{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},
-{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},
-{7,6,13},{7,4,3},{9,9,1536},{7,4,5},{7,8,43},{7,6,17},{9,9,1280},{7,4,6},{7,6,1},{7,5,8},
-{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},
-{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},
-{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,1024},{7,4,6},
-{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},
-{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,768},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},
-{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},
-{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{11,12,2496},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},
-{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},
-{7,8,40},{7,6,16},{9,9,896},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},
-{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
-{9,9,1728},{7,4,5},{7,8,44},{7,6,17},{9,9,1408},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
-{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},
-{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1152},{7,4,6},{7,8,32},{7,5,8},
-{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},
-{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},
-{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},
-{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{12,11,0},{7,4,3},
-{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},
-{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},
-{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},
-{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1472},{7,4,5},
-{7,8,43},{7,6,17},{9,9,1216},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
-{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},
-{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,960},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},
-{9,9,704},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},
-{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},
-{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,11,1792},{7,4,3},{7,5,11},{7,4,5},
-{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},
-{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,832},{7,4,6},
-{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},
-{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},
-{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1600},{7,4,5},{7,8,44},{7,6,17},
-{9,9,1344},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},
-{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},
-{7,8,42},{7,6,16},{9,9,1088},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},
-{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
-{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
-{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},
-{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},
-{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},
-{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},
-{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1536},{7,4,5},{7,8,43},{7,6,17},{9,9,1280},{7,4,6},
-{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},
-{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},
-{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},
-{9,9,1024},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,768},{7,4,6},{7,8,37},{9,5,128},
-{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},
-{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{11,11,1856},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
-{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},
-{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,896},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},
-{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},
-{7,6,13},{7,4,3},{9,9,1728},{7,4,5},{7,8,44},{7,6,17},{9,9,1408},{7,4,6},{7,6,1},{7,5,8},
-{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},
-{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},
-{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1152},{7,4,6},
-{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},
-{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},
-{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},
-{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},
-{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},
-{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},
-{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
-{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
-{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},
-{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,960},{7,4,6},{7,8,31},{7,5,8},
-{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},
-{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},
-{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},
-{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,12,2176},{7,4,3},
-{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},
-{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},
-{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},
-{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1600},{7,4,5},
-{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
-{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},
-{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},
-{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},
-{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},
-{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},
-{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},
-{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},
-{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},
-{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},
-{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1536},{7,4,5},{7,8,43},{7,6,17},
-{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},
-{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},
-{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,768},{7,4,6},
-{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
-{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,12,2432},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
-{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},
-{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,896},{7,4,6},{7,7,19},{7,5,8},
-{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},
-{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},
-{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5},{7,8,44},{7,6,17},{9,9,1408},{7,4,6},
-{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},
-{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},
-{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},
-{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},
-{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},
-{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
-{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},
-{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},
-{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},
-{7,6,13},{7,4,3},{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6},{7,6,1},{7,5,8},
-{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},
-{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},
-{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,960},{7,4,6},
-{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},
-{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},
-{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},
-{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{11,12,2048},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},
-{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},
-{7,8,40},{7,6,16},{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},
-{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
-{9,9,1600},{7,4,5},{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
-{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},
-{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6},{7,8,32},{7,5,8},
-{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},
-{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},
-{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},
-{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},
-{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},
-{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},
-{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},
-{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1536},{7,4,5},
-{7,8,43},{7,6,17},{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
-{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},
-{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},
-{9,9,768},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},
-{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},
-{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,11,1920},{7,4,3},{7,5,11},{7,4,5},
-{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},
-{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,896},{7,4,6},
-{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},
-{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},
-{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5},{7,8,44},{7,6,17},
-{9,9,1408},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},
-{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},
-{7,8,42},{7,6,16},{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},
-{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
-{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
-{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},
-{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},
-{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},
-{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},
-{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6},
-{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},
-{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},
-{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},
-{9,9,960},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128},
-{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},
-{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{11,12,2304},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
-{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},
-{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},
-{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},
-{7,6,13},{7,4,3},{9,9,1600},{7,4,5},{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8},
-{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},
-{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},
-{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6},
-{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},
-{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},
-{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},
-{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},
-{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},
-{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},
-{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
-{9,9,1536},{7,4,5},{7,8,43},{7,6,17},{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
-{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},
-{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8},
-{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},
-{7,7,26},{7,5,9},{9,9,768},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},
-{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},
-{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,12,2560},{7,4,3},
-{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},
-{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},
-{9,9,896},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},
-{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5},
-{7,8,44},{7,6,17},{9,9,1408},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
-{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},
-{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},
-{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},
-{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},
-{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}
-};
- const TIFFFaxTabEnt TIFFFaxBlackTable[8192] = {
-{12,11,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,18},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,17},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1792},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,11,23},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,20},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,11,25},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,128},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,12,56},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,12,30},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1856},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,57},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,11,21},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,54},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,52},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,48},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{11,12,2112},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,12,44},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,36},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,384},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,28},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,12,60},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,40},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2368},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,16},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{10,10,64},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,18},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,10,17},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{11,12,1984},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,50},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,12,34},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1664},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,26},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1408},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,32},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1920},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,12,61},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,42},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{10,13,1024},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{10,13,768},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,12,62},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2240},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,46},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,12,38},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,512},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,11,19},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,24},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,22},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{11,12,2496},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,10,16},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,0},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,10,64},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{12,11,0},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,10,18},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,17},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1792},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,23},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,20},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,11,25},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{10,12,192},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1280},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,12,31},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{11,11,1856},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,58},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,11,21},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,896},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,640},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,49},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2176},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,12,45},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,37},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{10,12,448},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,29},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{10,13,1536},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,12,41},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2432},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,16},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,10,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,10,64},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,18},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,17},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{11,12,2048},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,12,51},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,35},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,320},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,27},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,12,59},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,33},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1920},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,256},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,43},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{10,13,1152},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,55},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,12,63},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{11,12,2304},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,47},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,12,39},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,53},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,19},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,24},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,22},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2560},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,10,16},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,0},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{10,10,64},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{12,11,0},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,10,18},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,10,17},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1792},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,23},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,11,20},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,25},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{10,12,128},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,56},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,30},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{11,11,1856},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,12,57},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,21},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,54},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,12,52},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,48},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2112},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,44},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,36},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{10,12,384},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,12,28},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,60},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,12,40},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{11,12,2368},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,16},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,10,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,10,64},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,18},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,17},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,1984},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,12,50},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,34},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{10,13,1728},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,26},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{10,13,1472},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,12,32},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1920},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,61},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,12,42},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1088},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,832},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,62},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{11,12,2240},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,12,46},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,38},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,576},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,19},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,11,24},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,22},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2496},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,16},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{10,10,64},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{12,11,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,18},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,10,17},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{11,11,1792},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,23},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,11,20},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,25},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,192},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1344},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,31},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1856},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,12,58},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,21},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{10,13,960},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{10,13,704},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,12,49},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2176},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,45},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,12,37},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,448},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,12,29},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1600},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,41},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{11,12,2432},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,10,16},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,0},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,10,64},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,10,18},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,17},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2048},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,51},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,35},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{10,12,320},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,12,27},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,59},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,12,33},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{11,11,1920},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,256},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,12,43},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1216},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,55},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,63},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2304},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,12,47},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,39},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,12,53},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,19},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,11,24},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,11,22},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2560},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,16},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,10,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,10,64},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2}
-};
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_flush.c b/Source/LibTIFF/tif_flush.c
deleted file mode 100644
index 343d0b2..0000000
--- a/Source/LibTIFF/tif_flush.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/* $Header: /cvsroot/freeimage/FreeImage/Source/LibTIFF/tif_flush.c,v 1.37 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library.
- */
-#include "tiffiop.h"
-
-int
-TIFFFlush(TIFF* tif)
-{
-
-	if (tif->tif_mode != O_RDONLY) {
-		if (!TIFFFlushData(tif))
-			return (0);
-		if ((tif->tif_flags & TIFF_DIRTYDIRECT) &&
-		    !TIFFWriteDirectory(tif))
-			return (0);
-	}
-	return (1);
-}
-
-/*
- * Flush buffered data to the file.
- *
- * Frank Warmerdam'2000: I modified this to return 1 if TIFF_BEENWRITING
- * is not set, so that TIFFFlush() will proceed to write out the directory.
- * The documentation says returning 1 is an error indicator, but not having
- * been writing isn't exactly a an error.  Hopefully this doesn't cause
- * problems for other people. 
- */
-int
-TIFFFlushData(TIFF* tif)
-{
-	if ((tif->tif_flags & TIFF_BEENWRITING) == 0)
-		return (0);
-	if (tif->tif_flags & TIFF_POSTENCODE) {
-		tif->tif_flags &= ~TIFF_POSTENCODE;
-		if (!(*tif->tif_postencode)(tif))
-			return (0);
-	}
-	return (TIFFFlushData1(tif));
-}
-
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_getimage.c b/Source/LibTIFF/tif_getimage.c
deleted file mode 100644
index fede5a6..0000000
--- a/Source/LibTIFF/tif_getimage.c
+++ /dev/null
@@ -1,2678 +0,0 @@
-/* $Id: tif_getimage.c,v 1.39 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1991-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library
- *
- * Read and return a packed RGBA image.
- */
-#include "tiffiop.h"
-#include <stdio.h>
-
-static int gtTileContig(TIFFRGBAImage*, uint32*, uint32, uint32);
-static int gtTileSeparate(TIFFRGBAImage*, uint32*, uint32, uint32);
-static int gtStripContig(TIFFRGBAImage*, uint32*, uint32, uint32);
-static int gtStripSeparate(TIFFRGBAImage*, uint32*, uint32, uint32);
-static int PickContigCase(TIFFRGBAImage*);
-static int PickSeparateCase(TIFFRGBAImage*);
-static const char photoTag[] = "PhotometricInterpretation";
-
-/* 
- * Helper constants used in Orientation tag handling
- */
-#define FLIP_VERTICALLY 0x01
-#define FLIP_HORIZONTALLY 0x02
-
-/*
- * Color conversion constants. We will define display types here.
- */
-
-TIFFDisplay display_sRGB = {
-	{			/* XYZ -> luminance matrix */
-		{  3.2410F, -1.5374F, -0.4986F },
-		{  -0.9692F, 1.8760F, 0.0416F },
-		{  0.0556F, -0.2040F, 1.0570F }
-	},	
-	100.0F, 100.0F, 100.0F,	/* Light o/p for reference white */
-	255, 255, 255,		/* Pixel values for ref. white */
-	1.0F, 1.0F, 1.0F,	/* Residual light o/p for black pixel */
-	2.4F, 2.4F, 2.4F,	/* Gamma values for the three guns */
-};
-
-/*
- * Check the image to see if TIFFReadRGBAImage can deal with it.
- * 1/0 is returned according to whether or not the image can
- * be handled.  If 0 is returned, emsg contains the reason
- * why it is being rejected.
- */
-int
-TIFFRGBAImageOK(TIFF* tif, char emsg[1024])
-{
-	TIFFDirectory* td = &tif->tif_dir;
-	uint16 photometric;
-	int colorchannels;
-
-	if (!tif->tif_decodestatus) {
-		sprintf(emsg, "Sorry, requested compression method is not configured");
-		return (0);
-	}
-	switch (td->td_bitspersample) {
-		case 1:
-		case 2:
-		case 4:
-		case 8:
-		case 16:
-			break;
-		default:
-			sprintf(emsg, "Sorry, can not handle images with %d-bit samples",
-			    td->td_bitspersample);
-			return (0);
-	}
-	colorchannels = td->td_samplesperpixel - td->td_extrasamples;
-	if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) {
-		switch (colorchannels) {
-			case 1:
-				photometric = PHOTOMETRIC_MINISBLACK;
-				break;
-			case 3:
-				photometric = PHOTOMETRIC_RGB;
-				break;
-			default:
-				sprintf(emsg, "Missing needed %s tag", photoTag);
-				return (0);
-		}
-	}
-	switch (photometric) {
-		case PHOTOMETRIC_MINISWHITE:
-		case PHOTOMETRIC_MINISBLACK:
-		case PHOTOMETRIC_PALETTE:
-			if (td->td_planarconfig == PLANARCONFIG_CONTIG
-			    && td->td_samplesperpixel != 1
-			    && td->td_bitspersample < 8 ) {
-				sprintf(emsg,
-				    "Sorry, can not handle contiguous data with %s=%d, "
-				    "and %s=%d and Bits/Sample=%d",
-				    photoTag, photometric,
-				    "Samples/pixel", td->td_samplesperpixel,
-				    td->td_bitspersample);
-				return (0);
-			}
-			/*
-			 * We should likely validate that any extra samples are either
-			 * to be ignored, or are alpha, and if alpha we should try to use
-			 * them.  But for now we won't bother with this.
-			*/
-			break;
-		case PHOTOMETRIC_YCBCR:
-			/*
-			 * TODO: if at all meaningful and useful, make more complete
-			 * support check here, or better still, refactor to let supporting
-			 * code decide whether there is support and what meaningfull
-			 * error to return
-			 */
-			break;
-		case PHOTOMETRIC_RGB:
-			if (colorchannels < 3) {
-				sprintf(emsg, "Sorry, can not handle RGB image with %s=%d",
-				    "Color channels", colorchannels);
-				return (0);
-			}
-			break;
-		case PHOTOMETRIC_SEPARATED:
-			{
-				uint16 inkset;
-				TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset);
-				if (inkset != INKSET_CMYK) {
-					sprintf(emsg,
-					    "Sorry, can not handle separated image with %s=%d",
-					    "InkSet", inkset);
-					return 0;
-				}
-				if (td->td_samplesperpixel < 4) {
-					sprintf(emsg,
-					    "Sorry, can not handle separated image with %s=%d",
-					    "Samples/pixel", td->td_samplesperpixel);
-					return 0;
-				}
-				break;
-			}
-		case PHOTOMETRIC_LOGL:
-			if (td->td_compression != COMPRESSION_SGILOG) {
-				sprintf(emsg, "Sorry, LogL data must have %s=%d",
-				    "Compression", COMPRESSION_SGILOG);
-				return (0);
-			}
-			break;
-		case PHOTOMETRIC_LOGLUV:
-			if (td->td_compression != COMPRESSION_SGILOG &&
-			    td->td_compression != COMPRESSION_SGILOG24) {
-				sprintf(emsg, "Sorry, LogLuv data must have %s=%d or %d",
-				    "Compression", COMPRESSION_SGILOG, COMPRESSION_SGILOG24);
-				return (0);
-			}
-			if (td->td_planarconfig != PLANARCONFIG_CONTIG) {
-				sprintf(emsg, "Sorry, can not handle LogLuv images with %s=%d",
-				    "Planarconfiguration", td->td_planarconfig);
-				return (0);
-			}
-			break;
-		case PHOTOMETRIC_CIELAB:
-			break;
-		default:
-			sprintf(emsg, "Sorry, can not handle image with %s=%d",
-			    photoTag, photometric);
-			return (0);
-	}
-	return (1);
-}
-
-void
-TIFFRGBAImageEnd(TIFFRGBAImage* img)
-{
-	if (img->Map)
-		_TIFFfree(img->Map), img->Map = NULL;
-	if (img->BWmap)
-		_TIFFfree(img->BWmap), img->BWmap = NULL;
-	if (img->PALmap)
-		_TIFFfree(img->PALmap), img->PALmap = NULL;
-	if (img->ycbcr)
-		_TIFFfree(img->ycbcr), img->ycbcr = NULL;
-	if (img->cielab)
-		_TIFFfree(img->cielab), img->cielab = NULL;
-	if( img->redcmap ) {
-		_TIFFfree( img->redcmap );
-		_TIFFfree( img->greencmap );
-		_TIFFfree( img->bluecmap );
-	}
-}
-
-static int
-isCCITTCompression(TIFF* tif)
-{
-    uint16 compress;
-    TIFFGetField(tif, TIFFTAG_COMPRESSION, &compress);
-    return (compress == COMPRESSION_CCITTFAX3 ||
-	    compress == COMPRESSION_CCITTFAX4 ||
-	    compress == COMPRESSION_CCITTRLE ||
-	    compress == COMPRESSION_CCITTRLEW);
-}
-
-int
-TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024])
-{
-	uint16* sampleinfo;
-	uint16 extrasamples;
-	uint16 planarconfig;
-	uint16 compress;
-	int colorchannels;
-	uint16 *red_orig, *green_orig, *blue_orig;
-	int n_color;
-
-	/* Initialize to normal values */
-	img->row_offset = 0;
-	img->col_offset = 0;
-	img->redcmap = NULL;
-	img->greencmap = NULL;
-	img->bluecmap = NULL;
-	img->req_orientation = ORIENTATION_BOTLEFT;     /* It is the default */
-
-	img->tif = tif;
-	img->stoponerr = stop;
-	TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &img->bitspersample);
-	switch (img->bitspersample) {
-		case 1:
-		case 2:
-		case 4:
-		case 8:
-		case 16:
-			break;
-		default:
-			sprintf(emsg, "Sorry, can not handle images with %d-bit samples",
-			    img->bitspersample);
-			return (0);
-	}
-	img->alpha = 0;
-	TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &img->samplesperpixel);
-	TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES,
-	    &extrasamples, &sampleinfo);
-	if (extrasamples >= 1)
-	{
-		switch (sampleinfo[0]) {
-			case EXTRASAMPLE_UNSPECIFIED:          /* Workaround for some images without */
-				if (img->samplesperpixel > 3)  /* correct info about alpha channel */
-					img->alpha = EXTRASAMPLE_ASSOCALPHA;
-				break;
-			case EXTRASAMPLE_ASSOCALPHA:           /* data is pre-multiplied */
-			case EXTRASAMPLE_UNASSALPHA:           /* data is not pre-multiplied */
-				img->alpha = sampleinfo[0];
-				break;
-		}
-	}
-
-#ifdef DEFAULT_EXTRASAMPLE_AS_ALPHA
-	if( !TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric))
-		img->photometric = PHOTOMETRIC_MINISWHITE;
-
-	if( extrasamples == 0
-	    && img->samplesperpixel == 4
-	    && img->photometric == PHOTOMETRIC_RGB )
-	{
-		img->alpha = EXTRASAMPLE_ASSOCALPHA;
-		extrasamples = 1;
-	}
-#endif
-
-	colorchannels = img->samplesperpixel - extrasamples;
-	TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &compress);
-	TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planarconfig);
-	if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric)) {
-		switch (colorchannels) {
-			case 1:
-				if (isCCITTCompression(tif))
-					img->photometric = PHOTOMETRIC_MINISWHITE;
-				else
-					img->photometric = PHOTOMETRIC_MINISBLACK;
-				break;
-			case 3:
-				img->photometric = PHOTOMETRIC_RGB;
-				break;
-			default:
-				sprintf(emsg, "Missing needed %s tag", photoTag);
-				return (0);
-		}
-	}
-	switch (img->photometric) {
-		case PHOTOMETRIC_PALETTE:
-			if (!TIFFGetField(tif, TIFFTAG_COLORMAP,
-			    &red_orig, &green_orig, &blue_orig)) {
-				sprintf(emsg, "Missing required \"Colormap\" tag");
-				return (0);
-			}
-
-			/* copy the colormaps so we can modify them */
-			n_color = (1L << img->bitspersample);
-			img->redcmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);
-			img->greencmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);
-			img->bluecmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);
-			if( !img->redcmap || !img->greencmap || !img->bluecmap ) {
-				sprintf(emsg, "Out of memory for colormap copy");
-				return (0);
-			}
-
-			_TIFFmemcpy( img->redcmap, red_orig, n_color * 2 );
-			_TIFFmemcpy( img->greencmap, green_orig, n_color * 2 );
-			_TIFFmemcpy( img->bluecmap, blue_orig, n_color * 2 );
-
-			/* fall thru... */
-		case PHOTOMETRIC_MINISWHITE:
-		case PHOTOMETRIC_MINISBLACK:
-			if (planarconfig == PLANARCONFIG_CONTIG
-			    && img->samplesperpixel != 1
-			    && img->bitspersample < 8 ) {
-				sprintf(emsg,
-				    "Sorry, can not handle contiguous data with %s=%d, "
-				    "and %s=%d and Bits/Sample=%d",
-				    photoTag, img->photometric,
-				    "Samples/pixel", img->samplesperpixel,
-				    img->bitspersample);
-				return (0);
-			}
-			break;
-		case PHOTOMETRIC_YCBCR:
-			/* It would probably be nice to have a reality check here. */
-			if (planarconfig == PLANARCONFIG_CONTIG)
-				/* can rely on libjpeg to convert to RGB */
-				/* XXX should restore current state on exit */
-				switch (compress) {
-					case COMPRESSION_JPEG:
-						/*
-						 * TODO: when complete tests verify complete desubsampling
-						 * and YCbCr handling, remove use of TIFFTAG_JPEGCOLORMODE in
-						 * favor of tif_getimage.c native handling
-						 */
-						TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
-						img->photometric = PHOTOMETRIC_RGB;
-						break;
-					default:
-						/* do nothing */;
-						break;
-				}
-			/*
-			 * TODO: if at all meaningful and useful, make more complete
-			 * support check here, or better still, refactor to let supporting
-			 * code decide whether there is support and what meaningfull
-			 * error to return
-			 */
-			break;
-		case PHOTOMETRIC_RGB:
-			if (colorchannels < 3) {
-				sprintf(emsg, "Sorry, can not handle RGB image with %s=%d",
-				    "Color channels", colorchannels);
-				return (0);
-			}
-			break;
-		case PHOTOMETRIC_SEPARATED:
-			{
-				uint16 inkset;
-				TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset);
-				if (inkset != INKSET_CMYK) {
-					sprintf(emsg, "Sorry, can not handle separated image with %s=%d",
-					    "InkSet", inkset);
-					return (0);
-				}
-				if (img->samplesperpixel < 4) {
-					sprintf(emsg, "Sorry, can not handle separated image with %s=%d",
-					    "Samples/pixel", img->samplesperpixel);
-					return (0);
-				}
-			}
-			break;
-		case PHOTOMETRIC_LOGL:
-			if (compress != COMPRESSION_SGILOG) {
-				sprintf(emsg, "Sorry, LogL data must have %s=%d",
-				    "Compression", COMPRESSION_SGILOG);
-				return (0);
-			}
-			TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT);
-			img->photometric = PHOTOMETRIC_MINISBLACK;	/* little white lie */
-			img->bitspersample = 8;
-			break;
-		case PHOTOMETRIC_LOGLUV:
-			if (compress != COMPRESSION_SGILOG && compress != COMPRESSION_SGILOG24) {
-				sprintf(emsg, "Sorry, LogLuv data must have %s=%d or %d",
-				    "Compression", COMPRESSION_SGILOG, COMPRESSION_SGILOG24);
-				return (0);
-			}
-			if (planarconfig != PLANARCONFIG_CONTIG) {
-				sprintf(emsg, "Sorry, can not handle LogLuv images with %s=%d",
-				    "Planarconfiguration", planarconfig);
-				return (0);
-			}
-			TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT);
-			img->photometric = PHOTOMETRIC_RGB;		/* little white lie */
-			img->bitspersample = 8;
-			break;
-		case PHOTOMETRIC_CIELAB:
-			break;
-		default:
-			sprintf(emsg, "Sorry, can not handle image with %s=%d",
-			    photoTag, img->photometric);
-			return (0);
-	}
-	img->Map = NULL;
-	img->BWmap = NULL;
-	img->PALmap = NULL;
-	img->ycbcr = NULL;
-	img->cielab = NULL;
-	TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &img->width);
-	TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &img->height);
-	TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &img->orientation);
-	img->isContig =
-	    !(planarconfig == PLANARCONFIG_SEPARATE && colorchannels > 1);
-	if (img->isContig) {
-		if (!PickContigCase(img)) {
-			sprintf(emsg, "Sorry, can not handle image");
-			return 0;
-		}
-	} else {
-		if (!PickSeparateCase(img)) {
-			sprintf(emsg, "Sorry, can not handle image");
-			return 0;
-		}
-	}
-	return 1;
-}
-
-int
-TIFFRGBAImageGet(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
-{
-    if (img->get == NULL) {
-		TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No \"get\" routine setup");
-		return (0);
-	}
-	if (img->put.any == NULL) {
-		TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif),
-		"No \"put\" routine setupl; probably can not handle image format");
-		return (0);
-    }
-    return (*img->get)(img, raster, w, h);
-}
-
-/*
- * Read the specified image into an ABGR-format rastertaking in account
- * specified orientation.
- */
-int
-TIFFReadRGBAImageOriented(TIFF* tif,
-			  uint32 rwidth, uint32 rheight, uint32* raster,
-			  int orientation, int stop)
-{
-    char emsg[1024] = "";
-    TIFFRGBAImage img;
-    int ok;
-
-	if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, stop, emsg)) {
-		img.req_orientation = orientation;
-		/* XXX verify rwidth and rheight against width and height */
-		ok = TIFFRGBAImageGet(&img, raster+(rheight-img.height)*rwidth,
-			rwidth, img.height);
-		TIFFRGBAImageEnd(&img);
-	} else {
-		TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg);
-		ok = 0;
-    }
-    return (ok);
-}
-
-/*
- * Read the specified image into an ABGR-format raster. Use bottom left
- * origin for raster by default.
- */
-int
-TIFFReadRGBAImage(TIFF* tif,
-		  uint32 rwidth, uint32 rheight, uint32* raster, int stop)
-{
-	return TIFFReadRGBAImageOriented(tif, rwidth, rheight, raster,
-					 ORIENTATION_BOTLEFT, stop);
-}
-
-static int 
-setorientation(TIFFRGBAImage* img)
-{
-	switch (img->orientation) {
-		case ORIENTATION_TOPLEFT:
-		case ORIENTATION_LEFTTOP:
-			if (img->req_orientation == ORIENTATION_TOPRIGHT ||
-			    img->req_orientation == ORIENTATION_RIGHTTOP)
-				return FLIP_HORIZONTALLY;
-			else if (img->req_orientation == ORIENTATION_BOTRIGHT ||
-			    img->req_orientation == ORIENTATION_RIGHTBOT)
-				return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
-			else if (img->req_orientation == ORIENTATION_BOTLEFT ||
-			    img->req_orientation == ORIENTATION_LEFTBOT)
-				return FLIP_VERTICALLY;
-			else
-				return 0;
-		case ORIENTATION_TOPRIGHT:
-		case ORIENTATION_RIGHTTOP:
-			if (img->req_orientation == ORIENTATION_TOPLEFT ||
-			    img->req_orientation == ORIENTATION_LEFTTOP)
-				return FLIP_HORIZONTALLY;
-			else if (img->req_orientation == ORIENTATION_BOTRIGHT ||
-			    img->req_orientation == ORIENTATION_RIGHTBOT)
-				return FLIP_VERTICALLY;
-			else if (img->req_orientation == ORIENTATION_BOTLEFT ||
-			    img->req_orientation == ORIENTATION_LEFTBOT)
-				return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
-			else
-				return 0;
-		case ORIENTATION_BOTRIGHT:
-		case ORIENTATION_RIGHTBOT:
-			if (img->req_orientation == ORIENTATION_TOPLEFT ||
-			    img->req_orientation == ORIENTATION_LEFTTOP)
-				return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
-			else if (img->req_orientation == ORIENTATION_TOPRIGHT ||
-			    img->req_orientation == ORIENTATION_RIGHTTOP)
-				return FLIP_VERTICALLY;
-			else if (img->req_orientation == ORIENTATION_BOTLEFT ||
-			    img->req_orientation == ORIENTATION_LEFTBOT)
-				return FLIP_HORIZONTALLY;
-			else
-				return 0;
-		case ORIENTATION_BOTLEFT:
-		case ORIENTATION_LEFTBOT:
-			if (img->req_orientation == ORIENTATION_TOPLEFT ||
-			    img->req_orientation == ORIENTATION_LEFTTOP)
-				return FLIP_VERTICALLY;
-			else if (img->req_orientation == ORIENTATION_TOPRIGHT ||
-			    img->req_orientation == ORIENTATION_RIGHTTOP)
-				return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
-			else if (img->req_orientation == ORIENTATION_BOTRIGHT ||
-			    img->req_orientation == ORIENTATION_RIGHTBOT)
-				return FLIP_HORIZONTALLY;
-			else
-				return 0;
-		default:	/* NOTREACHED */
-			return 0;
-	}
-}
-
-/*
- * Get an tile-organized image that has
- *	PlanarConfiguration contiguous if SamplesPerPixel > 1
- * or
- *	SamplesPerPixel == 1
- */	
-static int
-gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
-{
-    TIFF* tif = img->tif;
-    tileContigRoutine put = img->put.contig;
-    uint32 col, row, y, rowstoread;
-    uint32 pos;
-    uint32 tw, th;
-    unsigned char* buf;
-    int32 fromskew, toskew;
-    uint32 nrow;
-    int ret = 1, flip;
-
-    buf = (unsigned char*) _TIFFmalloc(TIFFTileSize(tif));
-    if (buf == 0) {
-		TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for tile buffer");
-		return (0);
-    }
-    _TIFFmemset(buf, 0, TIFFTileSize(tif));
-    TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
-    TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
-
-    flip = setorientation(img);
-    if (flip & FLIP_VERTICALLY) {
-	    y = h - 1;
-	    toskew = -(int32)(tw + w);
-    }
-    else {
-	    y = 0;
-	    toskew = -(int32)(tw - w);
-    }
-     
-    for (row = 0; row < h; row += nrow)
-    {
-        rowstoread = th - (row + img->row_offset) % th;
-    	nrow = (row + rowstoread > h ? h - row : rowstoread);
-	for (col = 0; col < w; col += tw) 
-        {
-            if (TIFFReadTile(tif, buf, col+img->col_offset,
-                             row+img->row_offset, 0, 0) < 0 && img->stoponerr)
-            {
-                ret = 0;
-                break;
-            }
-	    
-            pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif);
-
-    	    if (col + tw > w) 
-            {
-                /*
-                 * Tile is clipped horizontally.  Calculate
-                 * visible portion and skewing factors.
-                 */
-                uint32 npix = w - col;
-                fromskew = tw - npix;
-                (*put)(img, raster+y*w+col, col, y,
-                       npix, nrow, fromskew, toskew + fromskew, buf + pos);
-            }
-            else 
-            {
-                (*put)(img, raster+y*w+col, col, y, tw, nrow, 0, toskew, buf + pos);
-            }
-        }
-
-        y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow);
-    }
-    _TIFFfree(buf);
-
-    if (flip & FLIP_HORIZONTALLY) {
-	    uint32 line;
-
-	    for (line = 0; line < h; line++) {
-		    uint32 *left = raster + (line * w);
-		    uint32 *right = left + w - 1;
-		    
-		    while ( left < right ) {
-			    uint32 temp = *left;
-			    *left = *right;
-			    *right = temp;
-			    left++, right--;
-		    }
-	    }
-    }
-
-    return (ret);
-}
-
-/*
- * Get an tile-organized image that has
- *	 SamplesPerPixel > 1
- *	 PlanarConfiguration separated
- * We assume that all such images are RGB.
- */	
-static int
-gtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
-{
-	TIFF* tif = img->tif;
-	tileSeparateRoutine put = img->put.separate;
-	uint32 col, row, y, rowstoread;
-	uint32 pos;
-	uint32 tw, th;
-	unsigned char* buf;
-	unsigned char* p0;
-	unsigned char* p1;
-	unsigned char* p2;
-	unsigned char* pa;
-	tsize_t tilesize;
-	int32 fromskew, toskew;
-	int alpha = img->alpha;
-	uint32 nrow;
-	int ret = 1, flip;
-
-	tilesize = TIFFTileSize(tif);
-	buf = (unsigned char*) _TIFFmalloc((alpha?4:3)*tilesize);
-	if (buf == 0) {
-		TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for tile buffer");
-		return (0);
-	}
-	_TIFFmemset(buf, 0, (alpha?4:3)*tilesize);
-	p0 = buf;
-	p1 = p0 + tilesize;
-	p2 = p1 + tilesize;
-	pa = (alpha?(p2+tilesize):NULL);
-	TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
-	TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
-
-	flip = setorientation(img);
-	if (flip & FLIP_VERTICALLY) {
-		y = h - 1;
-		toskew = -(int32)(tw + w);
-	}
-	else {
-		y = 0;
-		toskew = -(int32)(tw - w);
-	}
-
-	for (row = 0; row < h; row += nrow)
-	{
-		rowstoread = th - (row + img->row_offset) % th;
-		nrow = (row + rowstoread > h ? h - row : rowstoread);
-		for (col = 0; col < w; col += tw)
-		{
-			if (TIFFReadTile(tif, p0, col+img->col_offset,
-			    row+img->row_offset,0,0) < 0 && img->stoponerr)
-			{
-				ret = 0;
-				break;
-			}
-			if (TIFFReadTile(tif, p1, col+img->col_offset,
-			    row+img->row_offset,0,1) < 0 && img->stoponerr)
-			{
-				ret = 0;
-				break;
-			}
-			if (TIFFReadTile(tif, p2, col+img->col_offset,
-			    row+img->row_offset,0,2) < 0 && img->stoponerr)
-			{
-				ret = 0;
-				break;
-			}
-			if (alpha)
-			{
-				if (TIFFReadTile(tif,pa,col+img->col_offset,
-				    row+img->row_offset,0,3) < 0 && img->stoponerr)
-				{
-					ret = 0;
-					break;
-				}
-			}
-
-			pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif);
-
-			if (col + tw > w)
-			{
-				/*
-				 * Tile is clipped horizontally.  Calculate
-				 * visible portion and skewing factors.
-				 */
-				uint32 npix = w - col;
-				fromskew = tw - npix;
-				(*put)(img, raster+y*w+col, col, y,
-				    npix, nrow, fromskew, toskew + fromskew,
-				    p0 + pos, p1 + pos, p2 + pos, (alpha?(pa+pos):NULL));
-			} else {
-				(*put)(img, raster+y*w+col, col, y,
-				    tw, nrow, 0, toskew, p0 + pos, p1 + pos, p2 + pos, (alpha?(pa+pos):NULL));
-			}
-		}
-
-		y += (flip & FLIP_VERTICALLY ?-(int32) nrow : (int32) nrow);
-	}
-
-	if (flip & FLIP_HORIZONTALLY) {
-		uint32 line;
-
-		for (line = 0; line < h; line++) {
-			uint32 *left = raster + (line * w);
-			uint32 *right = left + w - 1;
-
-			while ( left < right ) {
-				uint32 temp = *left;
-				*left = *right;
-				*right = temp;
-				left++, right--;
-			}
-		}
-	}
-
-	_TIFFfree(buf);
-	return (ret);
-}
-
-/*
- * Get a strip-organized image that has
- *	PlanarConfiguration contiguous if SamplesPerPixel > 1
- * or
- *	SamplesPerPixel == 1
- */	
-static int
-gtStripContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
-{
-	TIFF* tif = img->tif;
-	tileContigRoutine put = img->put.contig;
-	uint32 row, y, nrow, nrowsub, rowstoread;
-	uint32 pos;
-	unsigned char* buf;
-	uint32 rowsperstrip;
-	uint16 subsamplinghor,subsamplingver;
-	uint32 imagewidth = img->width;
-	tsize_t scanline;
-	int32 fromskew, toskew;
-	int ret = 1, flip;
-
-	buf = (unsigned char*) _TIFFmalloc(TIFFStripSize(tif));
-	if (buf == 0) {
-		TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for strip buffer");
-		return (0);
-	}
-	_TIFFmemset(buf, 0, TIFFStripSize(tif));
-
-	flip = setorientation(img);
-	if (flip & FLIP_VERTICALLY) {
-		y = h - 1;
-		toskew = -(int32)(w + w);
-	} else {
-		y = 0;
-		toskew = -(int32)(w - w);
-	}
-
-	TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
-	TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING, &subsamplinghor, &subsamplingver);
-	scanline = TIFFNewScanlineSize(tif);
-	fromskew = (w < imagewidth ? imagewidth - w : 0);
-	for (row = 0; row < h; row += nrow)
-	{
-		rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip;
-		nrow = (row + rowstoread > h ? h - row : rowstoread);
-		nrowsub = nrow;
-		if ((nrowsub%subsamplingver)!=0)
-			nrowsub+=subsamplingver-nrowsub%subsamplingver;
-		if (TIFFReadEncodedStrip(tif,
-		    TIFFComputeStrip(tif,row+img->row_offset, 0),
-		    buf,
-		    ((row + img->row_offset)%rowsperstrip + nrowsub) * scanline) < 0
-		    && img->stoponerr)
-		{
-			ret = 0;
-			break;
-		}
-
-		pos = ((row + img->row_offset) % rowsperstrip) * scanline;
-		(*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, buf + pos);
-		y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow);
-	}
-
-	if (flip & FLIP_HORIZONTALLY) {
-		uint32 line;
-
-		for (line = 0; line < h; line++) {
-			uint32 *left = raster + (line * w);
-			uint32 *right = left + w - 1;
-
-			while ( left < right ) {
-				uint32 temp = *left;
-				*left = *right;
-				*right = temp;
-				left++, right--;
-			}
-		}
-	}
-
-	_TIFFfree(buf);
-	return (ret);
-}
-
-/*
- * Get a strip-organized image with
- *	 SamplesPerPixel > 1
- *	 PlanarConfiguration separated
- * We assume that all such images are RGB.
- */
-static int
-gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
-{
-	TIFF* tif = img->tif;
-	tileSeparateRoutine put = img->put.separate;
-	unsigned char *buf;
-	unsigned char *p0, *p1, *p2, *pa;
-	uint32 row, y, nrow, rowstoread;
-	uint32 pos;
-	tsize_t scanline;
-	uint32 rowsperstrip, offset_row;
-	uint32 imagewidth = img->width;
-	tsize_t stripsize;
-	int32 fromskew, toskew;
-	int alpha = img->alpha;
-	int ret = 1, flip;
-
-	stripsize = TIFFStripSize(tif);
-	p0 = buf = (unsigned char *)_TIFFmalloc((alpha?4:3)*stripsize);
-	if (buf == 0) {
-		TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for tile buffer");
-		return (0);
-	}
-	_TIFFmemset(buf, 0, (alpha?4:3)*stripsize);
-	p1 = p0 + stripsize;
-	p2 = p1 + stripsize;
-	pa = (alpha?(p2+stripsize):NULL);
-
-	flip = setorientation(img);
-	if (flip & FLIP_VERTICALLY) {
-		y = h - 1;
-		toskew = -(int32)(w + w);
-	}
-	else {
-		y = 0;
-		toskew = -(int32)(w - w);
-	}
-
-	TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
-	scanline = TIFFScanlineSize(tif);
-	fromskew = (w < imagewidth ? imagewidth - w : 0);
-	for (row = 0; row < h; row += nrow)
-	{
-		rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip;
-		nrow = (row + rowstoread > h ? h - row : rowstoread);
-		offset_row = row + img->row_offset;
-		if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 0),
-		    p0, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) < 0
-		    && img->stoponerr)
-		{
-			ret = 0;
-			break;
-		}
-		if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 1),
-		    p1, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) < 0
-		    && img->stoponerr)
-		{
-			ret = 0;
-			break;
-		}
-		if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 2),
-		    p2, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) < 0
-		    && img->stoponerr)
-		{
-			ret = 0;
-			break;
-		}
-		if (alpha)
-		{
-			if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 3),
-			    pa, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) < 0
-			    && img->stoponerr)
-			{
-				ret = 0;
-				break;
-			}
-		}
-
-		pos = ((row + img->row_offset) % rowsperstrip) * scanline;
-		(*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, p0 + pos, p1 + pos,
-		    p2 + pos, (alpha?(pa+pos):NULL));
-		y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow);
-	}
-
-	if (flip & FLIP_HORIZONTALLY) {
-		uint32 line;
-
-		for (line = 0; line < h; line++) {
-			uint32 *left = raster + (line * w);
-			uint32 *right = left + w - 1;
-
-			while ( left < right ) {
-				uint32 temp = *left;
-				*left = *right;
-				*right = temp;
-				left++, right--;
-			}
-		}
-	}
-
-	_TIFFfree(buf);
-	return (ret);
-}
-
-/*
- * The following routines move decoded data returned
- * from the TIFF library into rasters filled with packed
- * ABGR pixels (i.e. suitable for passing to lrecwrite.)
- *
- * The routines have been created according to the most
- * important cases and optimized.  PickContigCase and
- * PickSeparateCase analyze the parameters and select
- * the appropriate "get" and "put" routine to use.
- */
-#define	REPEAT8(op)	REPEAT4(op); REPEAT4(op)
-#define	REPEAT4(op)	REPEAT2(op); REPEAT2(op)
-#define	REPEAT2(op)	op; op
-#define	CASE8(x,op)			\
-    switch (x) {			\
-    case 7: op; case 6: op; case 5: op;	\
-    case 4: op; case 3: op; case 2: op;	\
-    case 1: op;				\
-    }
-#define	CASE4(x,op)	switch (x) { case 3: op; case 2: op; case 1: op; }
-#define	NOP
-
-#define	UNROLL8(w, op1, op2) {		\
-    uint32 _x;				\
-    for (_x = w; _x >= 8; _x -= 8) {	\
-	op1;				\
-	REPEAT8(op2);			\
-    }					\
-    if (_x > 0) {			\
-	op1;				\
-	CASE8(_x,op2);			\
-    }					\
-}
-#define	UNROLL4(w, op1, op2) {		\
-    uint32 _x;				\
-    for (_x = w; _x >= 4; _x -= 4) {	\
-	op1;				\
-	REPEAT4(op2);			\
-    }					\
-    if (_x > 0) {			\
-	op1;				\
-	CASE4(_x,op2);			\
-    }					\
-}
-#define	UNROLL2(w, op1, op2) {		\
-    uint32 _x;				\
-    for (_x = w; _x >= 2; _x -= 2) {	\
-	op1;				\
-	REPEAT2(op2);			\
-    }					\
-    if (_x) {				\
-	op1;				\
-	op2;				\
-    }					\
-}
-    
-#define	SKEW(r,g,b,skew)	{ r += skew; g += skew; b += skew; }
-#define	SKEW4(r,g,b,a,skew)	{ r += skew; g += skew; b += skew; a+= skew; }
-
-#define A1 (((uint32)0xffL)<<24)
-#define	PACK(r,g,b)	\
-	((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|A1)
-#define	PACK4(r,g,b,a)	\
-	((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|((uint32)(a)<<24))
-#define W2B(v) (((v)>>8)&0xff)
-#define	PACKW(r,g,b)	\
-	((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|A1)
-#define	PACKW4(r,g,b,a)	\
-	((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|((uint32)W2B(a)<<24))
-
-#define	DECLAREContigPutFunc(name) \
-static void name(\
-    TIFFRGBAImage* img, \
-    uint32* cp, \
-    uint32 x, uint32 y, \
-    uint32 w, uint32 h, \
-    int32 fromskew, int32 toskew, \
-    unsigned char* pp \
-)
-
-/*
- * 8-bit palette => colormap/RGB
- */
-DECLAREContigPutFunc(put8bitcmaptile)
-{
-    uint32** PALmap = img->PALmap;
-    int samplesperpixel = img->samplesperpixel;
-
-    (void) y;
-    while (h-- > 0) {
-	for (x = w; x-- > 0;)
-        {
-	    *cp++ = PALmap[*pp][0];
-            pp += samplesperpixel;
-        }
-	cp += toskew;
-	pp += fromskew;
-    }
-}
-
-/*
- * 4-bit palette => colormap/RGB
- */
-DECLAREContigPutFunc(put4bitcmaptile)
-{
-    uint32** PALmap = img->PALmap;
-
-    (void) x; (void) y;
-    fromskew /= 2;
-    while (h-- > 0) {
-	uint32* bw;
-	UNROLL2(w, bw = PALmap[*pp++], *cp++ = *bw++);
-	cp += toskew;
-	pp += fromskew;
-    }
-}
-
-/*
- * 2-bit palette => colormap/RGB
- */
-DECLAREContigPutFunc(put2bitcmaptile)
-{
-    uint32** PALmap = img->PALmap;
-
-    (void) x; (void) y;
-    fromskew /= 4;
-    while (h-- > 0) {
-	uint32* bw;
-	UNROLL4(w, bw = PALmap[*pp++], *cp++ = *bw++);
-	cp += toskew;
-	pp += fromskew;
-    }
-}
-
-/*
- * 1-bit palette => colormap/RGB
- */
-DECLAREContigPutFunc(put1bitcmaptile)
-{
-    uint32** PALmap = img->PALmap;
-
-    (void) x; (void) y;
-    fromskew /= 8;
-    while (h-- > 0) {
-	uint32* bw;
-	UNROLL8(w, bw = PALmap[*pp++], *cp++ = *bw++);
-	cp += toskew;
-	pp += fromskew;
-    }
-}
-
-/*
- * 8-bit greyscale => colormap/RGB
- */
-DECLAREContigPutFunc(putgreytile)
-{
-    int samplesperpixel = img->samplesperpixel;
-    uint32** BWmap = img->BWmap;
-
-    (void) y;
-    while (h-- > 0) {
-	for (x = w; x-- > 0;)
-        {
-	    *cp++ = BWmap[*pp][0];
-            pp += samplesperpixel;
-        }
-	cp += toskew;
-	pp += fromskew;
-    }
-}
-
-/*
- * 16-bit greyscale => colormap/RGB
- */
-DECLAREContigPutFunc(put16bitbwtile)
-{
-    int samplesperpixel = img->samplesperpixel;
-    uint32** BWmap = img->BWmap;
-
-    (void) y;
-    while (h-- > 0) {
-        uint16 *wp = (uint16 *) pp;
-
-	for (x = w; x-- > 0;)
-        {
-            /* use high order byte of 16bit value */
-
-	    *cp++ = BWmap[*wp >> 8][0];
-            pp += 2 * samplesperpixel;
-            wp += samplesperpixel;
-        }
-	cp += toskew;
-	pp += fromskew;
-    }
-}
-
-/*
- * 1-bit bilevel => colormap/RGB
- */
-DECLAREContigPutFunc(put1bitbwtile)
-{
-    uint32** BWmap = img->BWmap;
-
-    (void) x; (void) y;
-    fromskew /= 8;
-    while (h-- > 0) {
-	uint32* bw;
-	UNROLL8(w, bw = BWmap[*pp++], *cp++ = *bw++);
-	cp += toskew;
-	pp += fromskew;
-    }
-}
-
-/*
- * 2-bit greyscale => colormap/RGB
- */
-DECLAREContigPutFunc(put2bitbwtile)
-{
-    uint32** BWmap = img->BWmap;
-
-    (void) x; (void) y;
-    fromskew /= 4;
-    while (h-- > 0) {
-	uint32* bw;
-	UNROLL4(w, bw = BWmap[*pp++], *cp++ = *bw++);
-	cp += toskew;
-	pp += fromskew;
-    }
-}
-
-/*
- * 4-bit greyscale => colormap/RGB
- */
-DECLAREContigPutFunc(put4bitbwtile)
-{
-    uint32** BWmap = img->BWmap;
-
-    (void) x; (void) y;
-    fromskew /= 2;
-    while (h-- > 0) {
-	uint32* bw;
-	UNROLL2(w, bw = BWmap[*pp++], *cp++ = *bw++);
-	cp += toskew;
-	pp += fromskew;
-    }
-}
-
-/*
- * 8-bit packed samples, no Map => RGB
- */
-DECLAREContigPutFunc(putRGBcontig8bittile)
-{
-    int samplesperpixel = img->samplesperpixel;
-
-    (void) x; (void) y;
-    fromskew *= samplesperpixel;
-    while (h-- > 0) {
-	UNROLL8(w, NOP,
-	    *cp++ = PACK(pp[0], pp[1], pp[2]);
-	    pp += samplesperpixel);
-	cp += toskew;
-	pp += fromskew;
-    }
-}
-
-/*
- * 8-bit packed samples => RGBA w/ associated alpha
- * (known to have Map == NULL)
- */
-DECLAREContigPutFunc(putRGBAAcontig8bittile)
-{
-    int samplesperpixel = img->samplesperpixel;
-
-    (void) x; (void) y;
-    fromskew *= samplesperpixel;
-    while (h-- > 0) {
-	UNROLL8(w, NOP,
-	    *cp++ = PACK4(pp[0], pp[1], pp[2], pp[3]);
-	    pp += samplesperpixel);
-	cp += toskew;
-	pp += fromskew;
-    }
-}
-
-/*
- * 8-bit packed samples => RGBA w/ unassociated alpha
- * (known to have Map == NULL)
- */
-DECLAREContigPutFunc(putRGBUAcontig8bittile)
-{
-	int samplesperpixel = img->samplesperpixel;
-	(void) y;
-	fromskew *= samplesperpixel;
-	while (h-- > 0) {
-		uint32 r, g, b, a;
-		for (x = w; x-- > 0;) {
-			a = pp[3];
-                        r = (a*pp[0] + 127) / 255;
-                        g = (a*pp[1] + 127) / 255;
-                        b = (a*pp[2] + 127) / 255;
-			*cp++ = PACK4(r,g,b,a);
-			pp += samplesperpixel;
-		}
-		cp += toskew;
-		pp += fromskew;
-	}
-}
-
-/*
- * 16-bit packed samples => RGB
- */
-DECLAREContigPutFunc(putRGBcontig16bittile)
-{
-	int samplesperpixel = img->samplesperpixel;
-	uint16 *wp = (uint16 *)pp;
-	(void) y;
-	fromskew *= samplesperpixel;
-	while (h-- > 0) {
-		for (x = w; x-- > 0;) {
-                    *cp++ = PACKW(wp[0],wp[1],wp[2]);
-                    wp += samplesperpixel;
-		}
-		cp += toskew;
-		wp += fromskew;
-	}
-}
-
-/*
- * 16-bit packed samples => RGBA w/ associated alpha
- * (known to have Map == NULL)
- */
-DECLAREContigPutFunc(putRGBAAcontig16bittile)
-{
-	int samplesperpixel = img->samplesperpixel;
-	uint16 *wp = (uint16 *)pp;
-	(void) y;
-	fromskew *= samplesperpixel;
-	while (h-- > 0) {
-		for (x = w; x-- > 0;) {
-                    *cp++ = PACKW4(wp[0],wp[1],wp[2],wp[3]);
-                    wp += samplesperpixel;
-		}
-		cp += toskew;
-		wp += fromskew;
-	}
-}
-
-/*
- * 16-bit packed samples => RGBA w/ unassociated alpha
- * (known to have Map == NULL)
- */
-DECLAREContigPutFunc(putRGBUAcontig16bittile)
-{
-	int samplesperpixel = img->samplesperpixel;
-	uint16 *wp = (uint16 *)pp;
-	(void) y;
-	fromskew *= samplesperpixel;
-	while (h-- > 0) {
-		uint32 r,g,b,a;
-		for (x = w; x-- > 0;) {
-                    a = W2B(wp[3]);
-                    r = (a*W2B(wp[0]) + 127) / 255;
-                    g = (a*W2B(wp[1]) + 127) / 255;
-                    b = (a*W2B(wp[2]) + 127) / 255;
-                    *cp++ = PACK4(r,g,b,a);
-                    wp += samplesperpixel;
-		}
-		cp += toskew;
-		wp += fromskew;
-	}
-}
-
-/*
- * 8-bit packed CMYK samples w/o Map => RGB
- *
- * NB: The conversion of CMYK->RGB is *very* crude.
- */
-DECLAREContigPutFunc(putRGBcontig8bitCMYKtile)
-{
-    int samplesperpixel = img->samplesperpixel;
-    uint16 r, g, b, k;
-
-    (void) x; (void) y;
-    fromskew *= samplesperpixel;
-    while (h-- > 0) {
-	UNROLL8(w, NOP,
-	    k = 255 - pp[3];
-	    r = (k*(255-pp[0]))/255;
-	    g = (k*(255-pp[1]))/255;
-	    b = (k*(255-pp[2]))/255;
-	    *cp++ = PACK(r, g, b);
-	    pp += samplesperpixel);
-	cp += toskew;
-	pp += fromskew;
-    }
-}
-
-/*
- * 8-bit packed CMYK samples w/Map => RGB
- *
- * NB: The conversion of CMYK->RGB is *very* crude.
- */
-DECLAREContigPutFunc(putRGBcontig8bitCMYKMaptile)
-{
-    int samplesperpixel = img->samplesperpixel;
-    TIFFRGBValue* Map = img->Map;
-    uint16 r, g, b, k;
-
-    (void) y;
-    fromskew *= samplesperpixel;
-    while (h-- > 0) {
-	for (x = w; x-- > 0;) {
-	    k = 255 - pp[3];
-	    r = (k*(255-pp[0]))/255;
-	    g = (k*(255-pp[1]))/255;
-	    b = (k*(255-pp[2]))/255;
-	    *cp++ = PACK(Map[r], Map[g], Map[b]);
-	    pp += samplesperpixel;
-	}
-	pp += fromskew;
-	cp += toskew;
-    }
-}
-
-#define	DECLARESepPutFunc(name) \
-static void name(\
-    TIFFRGBAImage* img,\
-    uint32* cp,\
-    uint32 x, uint32 y, \
-    uint32 w, uint32 h,\
-    int32 fromskew, int32 toskew,\
-    unsigned char* r, unsigned char* g, unsigned char* b, unsigned char* a\
-)
-
-/*
- * 8-bit unpacked samples => RGB
- */
-DECLARESepPutFunc(putRGBseparate8bittile)
-{
-    (void) img; (void) x; (void) y; (void) a;
-    while (h-- > 0) {
-	UNROLL8(w, NOP, *cp++ = PACK(*r++, *g++, *b++));
-	SKEW(r, g, b, fromskew);
-	cp += toskew;
-    }
-}
-
-/*
- * 8-bit unpacked samples => RGBA w/ associated alpha
- */
-DECLARESepPutFunc(putRGBAAseparate8bittile)
-{
-	(void) img; (void) x; (void) y;
-	while (h-- > 0) {
-		UNROLL8(w, NOP, *cp++ = PACK4(*r++, *g++, *b++, *a++));
-		SKEW4(r, g, b, a, fromskew);
-		cp += toskew;
-	}
-}
-
-/*
- * 8-bit unpacked samples => RGBA w/ unassociated alpha
- */
-DECLARESepPutFunc(putRGBUAseparate8bittile)
-{
-	(void) img; (void) y;
-	while (h-- > 0) {
-		uint32 rv, gv, bv, av;
-		for (x = w; x-- > 0;) {
-			av = *a++;
-                        rv = (av* *r++ + 127) / 255;
-                        gv = (av* *g++ + 127) / 255;
-                        bv = (av* *b++ + 127) / 255;
-			*cp++ = PACK4(rv,gv,bv,av);
-		}
-		SKEW4(r, g, b, a, fromskew);
-		cp += toskew;
-	}
-}
-
-/*
- * 16-bit unpacked samples => RGB
- */
-DECLARESepPutFunc(putRGBseparate16bittile)
-{
-	uint16 *wr = (uint16*) r;
-	uint16 *wg = (uint16*) g;
-	uint16 *wb = (uint16*) b;
-	(void) img; (void) y; (void) a;
-	while (h-- > 0) {
-		for (x = 0; x < w; x++)
-                    *cp++ = PACKW(*wr++,*wg++,*wb++);
-		SKEW(wr, wg, wb, fromskew);
-		cp += toskew;
-	}
-}
-
-/*
- * 16-bit unpacked samples => RGBA w/ associated alpha
- */
-DECLARESepPutFunc(putRGBAAseparate16bittile)
-{
-	uint16 *wr = (uint16*) r;
-	uint16 *wg = (uint16*) g;
-	uint16 *wb = (uint16*) b;
-	uint16 *wa = (uint16*) a;
-	(void) img; (void) y;
-	while (h-- > 0) {
-		for (x = 0; x < w; x++)
-                    *cp++ = PACKW4(*wr++,*wg++,*wb++,*wa++);
-		SKEW4(wr, wg, wb, wa, fromskew);
-		cp += toskew;
-	}
-}
-
-/*
- * 16-bit unpacked samples => RGBA w/ unassociated alpha
- */
-DECLARESepPutFunc(putRGBUAseparate16bittile)
-{
-	uint16 *wr = (uint16*) r;
-	uint16 *wg = (uint16*) g;
-	uint16 *wb = (uint16*) b;
-	uint16 *wa = (uint16*) a;
-	(void) img; (void) y;
-	while (h-- > 0) {
-		uint32 r,g,b,a;
-		for (x = w; x-- > 0;) {
-                    a = W2B(*wa++);
-                    r = (a*W2B(*wr++) + 127) / 255;
-                    g = (a*W2B(*wg++) + 127) / 255;
-                    b = (a*W2B(*wb++) + 127) / 255;
-                    *cp++ = PACK4(r,g,b,a);
-		}
-		SKEW4(wr, wg, wb, wa, fromskew);
-		cp += toskew;
-	}
-}
-
-/*
- * 8-bit packed CIE L*a*b 1976 samples => RGB
- */
-DECLAREContigPutFunc(putcontig8bitCIELab)
-{
-	float X, Y, Z;
-	uint32 r, g, b;
-	(void) y;
-	fromskew *= 3;
-	while (h-- > 0) {
-		for (x = w; x-- > 0;) {
-			TIFFCIELabToXYZ(img->cielab,
-					(unsigned char)pp[0],
-					(signed char)pp[1],
-					(signed char)pp[2],
-					&X, &Y, &Z);
-			TIFFXYZToRGB(img->cielab, X, Y, Z, &r, &g, &b);
-			*cp++ = PACK(r, g, b);
-			pp += 3;
-		}
-		cp += toskew;
-		pp += fromskew;
-	}
-}
-
-/*
- * YCbCr -> RGB conversion and packing routines.
- */
-
-#define	YCbCrtoRGB(dst, Y) {						\
-	uint32 r, g, b;							\
-	TIFFYCbCrtoRGB(img->ycbcr, (Y), Cb, Cr, &r, &g, &b);		\
-	dst = PACK(r, g, b);						\
-}
-
-/*
- * 8-bit packed YCbCr samples => RGB 
- * This function is generic for different sampling sizes, 
- * and can handle blocks sizes that aren't multiples of the
- * sampling size.  However, it is substantially less optimized
- * than the specific sampling cases.  It is used as a fallback
- * for difficult blocks.
- */
-#ifdef notdef
-static void putcontig8bitYCbCrGenericTile( 
-    TIFFRGBAImage* img, 
-    uint32* cp, 
-    uint32 x, uint32 y, 
-    uint32 w, uint32 h, 
-    int32 fromskew, int32 toskew, 
-    unsigned char* pp,
-    int h_group, 
-    int v_group )
-
-{
-    uint32* cp1 = cp+w+toskew;
-    uint32* cp2 = cp1+w+toskew;
-    uint32* cp3 = cp2+w+toskew;
-    int32 incr = 3*w+4*toskew;
-    int32   Cb, Cr;
-    int     group_size = v_group * h_group + 2;
-
-    (void) y;
-    fromskew = (fromskew * group_size) / h_group;
-
-    for( yy = 0; yy < h; yy++ )
-    {
-        unsigned char *pp_line;
-        int     y_line_group = yy / v_group;
-        int     y_remainder = yy - y_line_group * v_group;
-
-        pp_line = pp + v_line_group * 
-
-        
-        for( xx = 0; xx < w; xx++ )
-        {
-            Cb = pp
-        }
-    }
-    for (; h >= 4; h -= 4) {
-	x = w>>2;
-	do {
-	    Cb = pp[16];
-	    Cr = pp[17];
-
-	    YCbCrtoRGB(cp [0], pp[ 0]);
-	    YCbCrtoRGB(cp [1], pp[ 1]);
-	    YCbCrtoRGB(cp [2], pp[ 2]);
-	    YCbCrtoRGB(cp [3], pp[ 3]);
-	    YCbCrtoRGB(cp1[0], pp[ 4]);
-	    YCbCrtoRGB(cp1[1], pp[ 5]);
-	    YCbCrtoRGB(cp1[2], pp[ 6]);
-	    YCbCrtoRGB(cp1[3], pp[ 7]);
-	    YCbCrtoRGB(cp2[0], pp[ 8]);
-	    YCbCrtoRGB(cp2[1], pp[ 9]);
-	    YCbCrtoRGB(cp2[2], pp[10]);
-	    YCbCrtoRGB(cp2[3], pp[11]);
-	    YCbCrtoRGB(cp3[0], pp[12]);
-	    YCbCrtoRGB(cp3[1], pp[13]);
-	    YCbCrtoRGB(cp3[2], pp[14]);
-	    YCbCrtoRGB(cp3[3], pp[15]);
-
-	    cp += 4, cp1 += 4, cp2 += 4, cp3 += 4;
-	    pp += 18;
-	} while (--x);
-	cp += incr, cp1 += incr, cp2 += incr, cp3 += incr;
-	pp += fromskew;
-    }
-}
-#endif
-
-/*
- * 8-bit packed YCbCr samples w/ 4,4 subsampling => RGB
- */
-DECLAREContigPutFunc(putcontig8bitYCbCr44tile)
-{
-    uint32* cp1 = cp+w+toskew;
-    uint32* cp2 = cp1+w+toskew;
-    uint32* cp3 = cp2+w+toskew;
-    int32 incr = 3*w+4*toskew;
-
-    (void) y;
-    /* adjust fromskew */
-    fromskew = (fromskew * 18) / 4;
-    if ((h & 3) == 0 && (w & 3) == 0) {				        
-        for (; h >= 4; h -= 4) {
-            x = w>>2;
-            do {
-                int32 Cb = pp[16];
-                int32 Cr = pp[17];
-
-                YCbCrtoRGB(cp [0], pp[ 0]);
-                YCbCrtoRGB(cp [1], pp[ 1]);
-                YCbCrtoRGB(cp [2], pp[ 2]);
-                YCbCrtoRGB(cp [3], pp[ 3]);
-                YCbCrtoRGB(cp1[0], pp[ 4]);
-                YCbCrtoRGB(cp1[1], pp[ 5]);
-                YCbCrtoRGB(cp1[2], pp[ 6]);
-                YCbCrtoRGB(cp1[3], pp[ 7]);
-                YCbCrtoRGB(cp2[0], pp[ 8]);
-                YCbCrtoRGB(cp2[1], pp[ 9]);
-                YCbCrtoRGB(cp2[2], pp[10]);
-                YCbCrtoRGB(cp2[3], pp[11]);
-                YCbCrtoRGB(cp3[0], pp[12]);
-                YCbCrtoRGB(cp3[1], pp[13]);
-                YCbCrtoRGB(cp3[2], pp[14]);
-                YCbCrtoRGB(cp3[3], pp[15]);
-
-                cp += 4, cp1 += 4, cp2 += 4, cp3 += 4;
-                pp += 18;
-            } while (--x);
-            cp += incr, cp1 += incr, cp2 += incr, cp3 += incr;
-            pp += fromskew;
-        }
-    } else {
-        while (h > 0) {
-            for (x = w; x > 0;) {
-                int32 Cb = pp[16];
-                int32 Cr = pp[17];
-                switch (x) {
-                default:
-                    switch (h) {
-                    default: YCbCrtoRGB(cp3[3], pp[15]); /* FALLTHROUGH */
-                    case 3:  YCbCrtoRGB(cp2[3], pp[11]); /* FALLTHROUGH */
-                    case 2:  YCbCrtoRGB(cp1[3], pp[ 7]); /* FALLTHROUGH */
-                    case 1:  YCbCrtoRGB(cp [3], pp[ 3]); /* FALLTHROUGH */
-                    }                                    /* FALLTHROUGH */
-                case 3:
-                    switch (h) {
-                    default: YCbCrtoRGB(cp3[2], pp[14]); /* FALLTHROUGH */
-                    case 3:  YCbCrtoRGB(cp2[2], pp[10]); /* FALLTHROUGH */
-                    case 2:  YCbCrtoRGB(cp1[2], pp[ 6]); /* FALLTHROUGH */
-                    case 1:  YCbCrtoRGB(cp [2], pp[ 2]); /* FALLTHROUGH */
-                    }                                    /* FALLTHROUGH */
-                case 2:
-                    switch (h) {
-                    default: YCbCrtoRGB(cp3[1], pp[13]); /* FALLTHROUGH */
-                    case 3:  YCbCrtoRGB(cp2[1], pp[ 9]); /* FALLTHROUGH */
-                    case 2:  YCbCrtoRGB(cp1[1], pp[ 5]); /* FALLTHROUGH */
-                    case 1:  YCbCrtoRGB(cp [1], pp[ 1]); /* FALLTHROUGH */
-                    }                                    /* FALLTHROUGH */
-                case 1:
-                    switch (h) {
-                    default: YCbCrtoRGB(cp3[0], pp[12]); /* FALLTHROUGH */
-                    case 3:  YCbCrtoRGB(cp2[0], pp[ 8]); /* FALLTHROUGH */
-                    case 2:  YCbCrtoRGB(cp1[0], pp[ 4]); /* FALLTHROUGH */
-                    case 1:  YCbCrtoRGB(cp [0], pp[ 0]); /* FALLTHROUGH */
-                    }                                    /* FALLTHROUGH */
-                }
-                if (x < 4) {
-                    cp += x; cp1 += x; cp2 += x; cp3 += x;
-                    x = 0;
-                }
-                else {
-                    cp += 4; cp1 += 4; cp2 += 4; cp3 += 4;
-                    x -= 4;
-                }
-                pp += 18;
-            }
-            if (h <= 4)
-                break;
-            h -= 4;
-            cp += incr, cp1 += incr, cp2 += incr, cp3 += incr;
-            pp += fromskew;
-        }
-    }
-}
-
-/*
- * 8-bit packed YCbCr samples w/ 4,2 subsampling => RGB
- */
-DECLAREContigPutFunc(putcontig8bitYCbCr42tile)
-{
-    uint32* cp1 = cp+w+toskew;
-    int32 incr = 2*toskew+w;
-
-    (void) y;
-    fromskew = (fromskew * 10) / 4;
-    if ((h & 3) == 0 && (w & 1) == 0) {
-        for (; h >= 2; h -= 2) {
-            x = w>>2;
-            do {
-                int32 Cb = pp[8];
-                int32 Cr = pp[9];
-                
-                YCbCrtoRGB(cp [0], pp[0]);
-                YCbCrtoRGB(cp [1], pp[1]);
-                YCbCrtoRGB(cp [2], pp[2]);
-                YCbCrtoRGB(cp [3], pp[3]);
-                YCbCrtoRGB(cp1[0], pp[4]);
-                YCbCrtoRGB(cp1[1], pp[5]);
-                YCbCrtoRGB(cp1[2], pp[6]);
-                YCbCrtoRGB(cp1[3], pp[7]);
-                
-                cp += 4, cp1 += 4;
-                pp += 10;
-            } while (--x);
-            cp += incr, cp1 += incr;
-            pp += fromskew;
-        }
-    } else {
-        while (h > 0) {
-            for (x = w; x > 0;) {
-                int32 Cb = pp[8];
-                int32 Cr = pp[9];
-                switch (x) {
-                default:
-                    switch (h) {
-                    default: YCbCrtoRGB(cp1[3], pp[ 7]); /* FALLTHROUGH */
-                    case 1:  YCbCrtoRGB(cp [3], pp[ 3]); /* FALLTHROUGH */
-                    }                                    /* FALLTHROUGH */
-                case 3:
-                    switch (h) {
-                    default: YCbCrtoRGB(cp1[2], pp[ 6]); /* FALLTHROUGH */
-                    case 1:  YCbCrtoRGB(cp [2], pp[ 2]); /* FALLTHROUGH */
-                    }                                    /* FALLTHROUGH */
-                case 2:
-                    switch (h) {
-                    default: YCbCrtoRGB(cp1[1], pp[ 5]); /* FALLTHROUGH */
-                    case 1:  YCbCrtoRGB(cp [1], pp[ 1]); /* FALLTHROUGH */
-                    }                                    /* FALLTHROUGH */
-                case 1:
-                    switch (h) {
-                    default: YCbCrtoRGB(cp1[0], pp[ 4]); /* FALLTHROUGH */
-                    case 1:  YCbCrtoRGB(cp [0], pp[ 0]); /* FALLTHROUGH */
-                    }                                    /* FALLTHROUGH */
-                }
-                if (x < 4) {
-                    cp += x; cp1 += x;
-                    x = 0;
-                }
-                else {
-                    cp += 4; cp1 += 4;
-                    x -= 4;
-                }
-                pp += 10;
-            }
-            if (h <= 2)
-                break;
-            h -= 2;
-            cp += incr, cp1 += incr;
-            pp += fromskew;
-        }
-    }
-}
-
-/*
- * 8-bit packed YCbCr samples w/ 4,1 subsampling => RGB
- */
-DECLAREContigPutFunc(putcontig8bitYCbCr41tile)
-{
-    (void) y;
-    /* XXX adjust fromskew */
-    do {
-	x = w>>2;
-	do {
-	    int32 Cb = pp[4];
-	    int32 Cr = pp[5];
-
-	    YCbCrtoRGB(cp [0], pp[0]);
-	    YCbCrtoRGB(cp [1], pp[1]);
-	    YCbCrtoRGB(cp [2], pp[2]);
-	    YCbCrtoRGB(cp [3], pp[3]);
-
-	    cp += 4;
-	    pp += 6;
-	} while (--x);
-
-        if( (w&3) != 0 )
-        {
-	    int32 Cb = pp[4];
-	    int32 Cr = pp[5];
-
-            switch( (w&3) ) {
-              case 3: YCbCrtoRGB(cp [2], pp[2]);
-              case 2: YCbCrtoRGB(cp [1], pp[1]);
-              case 1: YCbCrtoRGB(cp [0], pp[0]);
-              case 0: break;
-            }
-
-            cp += (w&3);
-            pp += 6;
-        }
-
-	cp += toskew;
-	pp += fromskew;
-    } while (--h);
-
-}
-
-/*
- * 8-bit packed YCbCr samples w/ 2,2 subsampling => RGB
- */
-DECLAREContigPutFunc(putcontig8bitYCbCr22tile)
-{
-	uint32* cp2;
-	int32 incr = 2*toskew+w;
-	(void) y;
-	fromskew = (fromskew / 2) * 6;
-	cp2 = cp+w+toskew;
-	while (h>=2) {
-		x = w;
-		while (x>=2) {
-			uint32 Cb = pp[4];
-			uint32 Cr = pp[5];
-			YCbCrtoRGB(cp[0], pp[0]);
-			YCbCrtoRGB(cp[1], pp[1]);
-			YCbCrtoRGB(cp2[0], pp[2]);
-			YCbCrtoRGB(cp2[1], pp[3]);
-			cp += 2;
-			cp2 += 2;
-			pp += 6;
-			x -= 2;
-		}
-		if (x==1) {
-			uint32 Cb = pp[4];
-			uint32 Cr = pp[5];
-			YCbCrtoRGB(cp[0], pp[0]);
-			YCbCrtoRGB(cp2[0], pp[2]);
-			cp ++ ;
-			cp2 ++ ;
-			pp += 6;
-		}
-		cp += incr;
-		cp2 += incr;
-		pp += fromskew;
-		h-=2;
-	}
-	if (h==1) {
-		x = w;
-		while (x>=2) {
-			uint32 Cb = pp[4];
-			uint32 Cr = pp[5];
-			YCbCrtoRGB(cp[0], pp[0]);
-			YCbCrtoRGB(cp[1], pp[1]);
-			cp += 2;
-			cp2 += 2;
-			pp += 6;
-			x -= 2;
-		}
-		if (x==1) {
-			uint32 Cb = pp[4];
-			uint32 Cr = pp[5];
-			YCbCrtoRGB(cp[0], pp[0]);
-		}
-	}
-}
-
-/*
- * 8-bit packed YCbCr samples w/ 2,1 subsampling => RGB
- */
-DECLAREContigPutFunc(putcontig8bitYCbCr21tile)
-{
-	(void) y;
-	fromskew = (fromskew * 4) / 2;
-	do {
-		x = w>>1;
-		do {
-			int32 Cb = pp[2];
-			int32 Cr = pp[3];
-
-			YCbCrtoRGB(cp[0], pp[0]);
-			YCbCrtoRGB(cp[1], pp[1]);
-
-			cp += 2;
-			pp += 4;
-		} while (--x);
-
-		if( (w&1) != 0 )
-		{
-			int32 Cb = pp[2];
-			int32 Cr = pp[3];
-
-			YCbCrtoRGB(cp[0], pp[0]);
-
-			cp += 1;
-			pp += 4;
-		}
-
-		cp += toskew;
-		pp += fromskew;
-	} while (--h);
-}
-
-/*
- * 8-bit packed YCbCr samples w/ 1,2 subsampling => RGB
- */
-DECLAREContigPutFunc(putcontig8bitYCbCr12tile)
-{
-	uint32* cp2;
-	int32 incr = 2*toskew+w;
-	(void) y;
-	fromskew = (fromskew / 2) * 4;
-	cp2 = cp+w+toskew;
-	while (h>=2) {
-		x = w;
-		do {
-			uint32 Cb = pp[2];
-			uint32 Cr = pp[3];
-			YCbCrtoRGB(cp[0], pp[0]);
-			YCbCrtoRGB(cp2[0], pp[1]);
-			cp ++;
-			cp2 ++;
-			pp += 4;
-		} while (--x);
-		cp += incr;
-		cp2 += incr;
-		pp += fromskew;
-		h-=2;
-	}
-	if (h==1) {
-		x = w;
-		do {
-			uint32 Cb = pp[2];
-			uint32 Cr = pp[3];
-			YCbCrtoRGB(cp[0], pp[0]);
-			cp ++;
-			pp += 4;
-		} while (--x);
-	}
-}
-
-/*
- * 8-bit packed YCbCr samples w/ no subsampling => RGB
- */
-DECLAREContigPutFunc(putcontig8bitYCbCr11tile)
-{
-	(void) y;
-	fromskew *= 3;
-	do {
-		x = w; /* was x = w>>1; patched 2000/09/25 warmerda at home.com */
-		do {
-			int32 Cb = pp[1];
-			int32 Cr = pp[2];
-
-			YCbCrtoRGB(*cp++, pp[0]);
-
-			pp += 3;
-		} while (--x);
-		cp += toskew;
-		pp += fromskew;
-	} while (--h);
-}
-
-/*
- * 8-bit packed YCbCr samples w/ no subsampling => RGB
- */
-DECLARESepPutFunc(putseparate8bitYCbCr11tile)
-{
-	(void) y;
-	(void) a;
-	/* TODO: naming of input vars is still off, change obfuscating declaration inside define, or resolve obfuscation */
-	while (h-- > 0) {
-		x = w;
-		do {
-			uint32 dr, dg, db;
-			TIFFYCbCrtoRGB(img->ycbcr,*r++,*g++,*b++,&dr,&dg,&db);
-			*cp++ = PACK(dr,dg,db);
-		} while (--x);
-		SKEW(r, g, b, fromskew);
-		cp += toskew;
-	}
-}
-#undef YCbCrtoRGB
-
-static int
-initYCbCrConversion(TIFFRGBAImage* img)
-{
-	static char module[] = "initYCbCrConversion";
-
-	float *luma, *refBlackWhite;
-
-	if (img->ycbcr == NULL) {
-		img->ycbcr = (TIFFYCbCrToRGB*) _TIFFmalloc(
-		    TIFFroundup(sizeof (TIFFYCbCrToRGB), sizeof (long))
-		    + 4*256*sizeof (TIFFRGBValue)
-		    + 2*256*sizeof (int)
-		    + 3*256*sizeof (int32)
-		    );
-		if (img->ycbcr == NULL) {
-			TIFFErrorExt(img->tif->tif_clientdata, module,
-			    "No space for YCbCr->RGB conversion state");
-			return (0);
-		}
-	}
-
-	TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRCOEFFICIENTS, &luma);
-	TIFFGetFieldDefaulted(img->tif, TIFFTAG_REFERENCEBLACKWHITE,
-	    &refBlackWhite);
-	if (TIFFYCbCrToRGBInit(img->ycbcr, luma, refBlackWhite) < 0)
-		return(0);
-	return (1);
-}
-
-static tileContigRoutine
-initCIELabConversion(TIFFRGBAImage* img)
-{
-	static char module[] = "initCIELabConversion";
-
-	float   *whitePoint;
-	float   refWhite[3];
-
-	if (!img->cielab) {
-		img->cielab = (TIFFCIELabToRGB *)
-			_TIFFmalloc(sizeof(TIFFCIELabToRGB));
-		if (!img->cielab) {
-			TIFFErrorExt(img->tif->tif_clientdata, module,
-			    "No space for CIE L*a*b*->RGB conversion state.");
-			return NULL;
-		}
-	}
-
-	TIFFGetFieldDefaulted(img->tif, TIFFTAG_WHITEPOINT, &whitePoint);
-	refWhite[1] = 100.0F;
-	refWhite[0] = whitePoint[0] / whitePoint[1] * refWhite[1];
-	refWhite[2] = (1.0F - whitePoint[0] - whitePoint[1])
-		      / whitePoint[1] * refWhite[1];
-	if (TIFFCIELabToRGBInit(img->cielab, &display_sRGB, refWhite) < 0) {
-		TIFFErrorExt(img->tif->tif_clientdata, module,
-		    "Failed to initialize CIE L*a*b*->RGB conversion state.");
-		_TIFFfree(img->cielab);
-		return NULL;
-	}
-
-	return putcontig8bitCIELab;
-}
-
-/*
- * Greyscale images with less than 8 bits/sample are handled
- * with a table to avoid lots of shifts and masks.  The table
- * is setup so that put*bwtile (below) can retrieve 8/bitspersample
- * pixel values simply by indexing into the table with one
- * number.
- */
-static int
-makebwmap(TIFFRGBAImage* img)
-{
-    TIFFRGBValue* Map = img->Map;
-    int bitspersample = img->bitspersample;
-    int nsamples = 8 / bitspersample;
-    int i;
-    uint32* p;
-
-    if( nsamples == 0 )
-        nsamples = 1;
-
-    img->BWmap = (uint32**) _TIFFmalloc(
-	256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32)));
-    if (img->BWmap == NULL) {
-		TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No space for B&W mapping table");
-		return (0);
-    }
-    p = (uint32*)(img->BWmap + 256);
-    for (i = 0; i < 256; i++) {
-	TIFFRGBValue c;
-	img->BWmap[i] = p;
-	switch (bitspersample) {
-#define	GREY(x)	c = Map[x]; *p++ = PACK(c,c,c);
-	case 1:
-	    GREY(i>>7);
-	    GREY((i>>6)&1);
-	    GREY((i>>5)&1);
-	    GREY((i>>4)&1);
-	    GREY((i>>3)&1);
-	    GREY((i>>2)&1);
-	    GREY((i>>1)&1);
-	    GREY(i&1);
-	    break;
-	case 2:
-	    GREY(i>>6);
-	    GREY((i>>4)&3);
-	    GREY((i>>2)&3);
-	    GREY(i&3);
-	    break;
-	case 4:
-	    GREY(i>>4);
-	    GREY(i&0xf);
-	    break;
-	case 8:
-        case 16:
-	    GREY(i);
-	    break;
-	}
-#undef	GREY
-    }
-    return (1);
-}
-
-/*
- * Construct a mapping table to convert from the range
- * of the data samples to [0,255] --for display.  This
- * process also handles inverting B&W images when needed.
- */ 
-static int
-setupMap(TIFFRGBAImage* img)
-{
-    int32 x, range;
-
-    range = (int32)((1L<<img->bitspersample)-1);
-    
-    /* treat 16 bit the same as eight bit */
-    if( img->bitspersample == 16 )
-        range = (int32) 255;
-
-    img->Map = (TIFFRGBValue*) _TIFFmalloc((range+1) * sizeof (TIFFRGBValue));
-    if (img->Map == NULL) {
-		TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif),
-			"No space for photometric conversion table");
-		return (0);
-    }
-    if (img->photometric == PHOTOMETRIC_MINISWHITE) {
-	for (x = 0; x <= range; x++)
-	    img->Map[x] = (TIFFRGBValue) (((range - x) * 255) / range);
-    } else {
-	for (x = 0; x <= range; x++)
-	    img->Map[x] = (TIFFRGBValue) ((x * 255) / range);
-    }
-    if (img->bitspersample <= 16 &&
-	(img->photometric == PHOTOMETRIC_MINISBLACK ||
-	 img->photometric == PHOTOMETRIC_MINISWHITE)) {
-	/*
-	 * Use photometric mapping table to construct
-	 * unpacking tables for samples <= 8 bits.
-	 */
-	if (!makebwmap(img))
-	    return (0);
-	/* no longer need Map, free it */
-	_TIFFfree(img->Map), img->Map = NULL;
-    }
-    return (1);
-}
-
-static int
-checkcmap(TIFFRGBAImage* img)
-{
-    uint16* r = img->redcmap;
-    uint16* g = img->greencmap;
-    uint16* b = img->bluecmap;
-    long n = 1L<<img->bitspersample;
-
-    while (n-- > 0)
-	if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256)
-	    return (16);
-    return (8);
-}
-
-static void
-cvtcmap(TIFFRGBAImage* img)
-{
-    uint16* r = img->redcmap;
-    uint16* g = img->greencmap;
-    uint16* b = img->bluecmap;
-    long i;
-
-    for (i = (1L<<img->bitspersample)-1; i >= 0; i--) {
-#define	CVT(x)		((uint16)((x)>>8))
-	r[i] = CVT(r[i]);
-	g[i] = CVT(g[i]);
-	b[i] = CVT(b[i]);
-#undef	CVT
-    }
-}
-
-/*
- * Palette images with <= 8 bits/sample are handled
- * with a table to avoid lots of shifts and masks.  The table
- * is setup so that put*cmaptile (below) can retrieve 8/bitspersample
- * pixel values simply by indexing into the table with one
- * number.
- */
-static int
-makecmap(TIFFRGBAImage* img)
-{
-    int bitspersample = img->bitspersample;
-    int nsamples = 8 / bitspersample;
-    uint16* r = img->redcmap;
-    uint16* g = img->greencmap;
-    uint16* b = img->bluecmap;
-    uint32 *p;
-    int i;
-
-    img->PALmap = (uint32**) _TIFFmalloc(
-	256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32)));
-    if (img->PALmap == NULL) {
-		TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No space for Palette mapping table");
-		return (0);
-	}
-    p = (uint32*)(img->PALmap + 256);
-    for (i = 0; i < 256; i++) {
-	TIFFRGBValue c;
-	img->PALmap[i] = p;
-#define	CMAP(x)	c = (TIFFRGBValue) x; *p++ = PACK(r[c]&0xff, g[c]&0xff, b[c]&0xff);
-	switch (bitspersample) {
-	case 1:
-	    CMAP(i>>7);
-	    CMAP((i>>6)&1);
-	    CMAP((i>>5)&1);
-	    CMAP((i>>4)&1);
-	    CMAP((i>>3)&1);
-	    CMAP((i>>2)&1);
-	    CMAP((i>>1)&1);
-	    CMAP(i&1);
-	    break;
-	case 2:
-	    CMAP(i>>6);
-	    CMAP((i>>4)&3);
-	    CMAP((i>>2)&3);
-	    CMAP(i&3);
-	    break;
-	case 4:
-	    CMAP(i>>4);
-	    CMAP(i&0xf);
-	    break;
-	case 8:
-	    CMAP(i);
-	    break;
-	}
-#undef CMAP
-    }
-    return (1);
-}
-
-/* 
- * Construct any mapping table used
- * by the associated put routine.
- */
-static int
-buildMap(TIFFRGBAImage* img)
-{
-    switch (img->photometric) {
-    case PHOTOMETRIC_RGB:
-    case PHOTOMETRIC_YCBCR:
-    case PHOTOMETRIC_SEPARATED:
-	if (img->bitspersample == 8)
-	    break;
-	/* fall thru... */
-    case PHOTOMETRIC_MINISBLACK:
-    case PHOTOMETRIC_MINISWHITE:
-	if (!setupMap(img))
-	    return (0);
-	break;
-    case PHOTOMETRIC_PALETTE:
-	/*
-	 * Convert 16-bit colormap to 8-bit (unless it looks
-	 * like an old-style 8-bit colormap).
-	 */
-	if (checkcmap(img) == 16)
-	    cvtcmap(img);
-	else
-	    TIFFWarningExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "Assuming 8-bit colormap");
-	/*
-	 * Use mapping table and colormap to construct
-	 * unpacking tables for samples < 8 bits.
-	 */
-	if (img->bitspersample <= 8 && !makecmap(img))
-	    return (0);
-	break;
-    }
-    return (1);
-}
-
-/*
- * Select the appropriate conversion routine for packed data.
- */
-static int
-PickContigCase(TIFFRGBAImage* img)
-{
-	img->get = TIFFIsTiled(img->tif) ? gtTileContig : gtStripContig;
-	img->put.contig = NULL;
-	switch (img->photometric) {
-		case PHOTOMETRIC_RGB:
-			switch (img->bitspersample) {
-				case 8:
-					if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
-						img->put.contig = putRGBAAcontig8bittile;
-					else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
-					{
-                                            img->put.contig = putRGBUAcontig8bittile;
-					}
-					else
-                                            img->put.contig = putRGBcontig8bittile;
-					break;
-				case 16:
-					if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
-					{
-                                            img->put.contig = putRGBAAcontig16bittile;
-					}
-					else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
-					{
-                                            img->put.contig = putRGBUAcontig16bittile;
-					}
-					else
-					{
-                                            img->put.contig = putRGBcontig16bittile;
-					}
-					break;
-			}
-			break;
-		case PHOTOMETRIC_SEPARATED:
-			if (buildMap(img)) {
-				if (img->bitspersample == 8) {
-					if (!img->Map)
-						img->put.contig = putRGBcontig8bitCMYKtile;
-					else
-						img->put.contig = putRGBcontig8bitCMYKMaptile;
-				}
-			}
-			break;
-		case PHOTOMETRIC_PALETTE:
-			if (buildMap(img)) {
-				switch (img->bitspersample) {
-					case 8:
-						img->put.contig = put8bitcmaptile;
-						break;
-					case 4:
-						img->put.contig = put4bitcmaptile;
-						break;
-					case 2:
-						img->put.contig = put2bitcmaptile;
-						break;
-					case 1:
-						img->put.contig = put1bitcmaptile;
-						break;
-				}
-			}
-			break;
-		case PHOTOMETRIC_MINISWHITE:
-		case PHOTOMETRIC_MINISBLACK:
-			if (buildMap(img)) {
-				switch (img->bitspersample) {
-					case 16:
-						img->put.contig = put16bitbwtile;
-						break;
-					case 8:
-						img->put.contig = putgreytile;
-						break;
-					case 4:
-						img->put.contig = put4bitbwtile;
-						break;
-					case 2:
-						img->put.contig = put2bitbwtile;
-						break;
-					case 1:
-						img->put.contig = put1bitbwtile;
-						break;
-				}
-			}
-			break;
-		case PHOTOMETRIC_YCBCR:
-			if ((img->bitspersample==8) && (img->samplesperpixel==3))
-			{
-				if (initYCbCrConversion(img)!=0)
-				{
-					/*
-					 * The 6.0 spec says that subsampling must be
-					 * one of 1, 2, or 4, and that vertical subsampling
-					 * must always be <= horizontal subsampling; so
-					 * there are only a few possibilities and we just
-					 * enumerate the cases.
-					 * Joris: added support for the [1,2] case, nonetheless, to accomodate
-					 * some OJPEG files
-					 */
-					uint16 SubsamplingHor;
-					uint16 SubsamplingVer;
-					TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &SubsamplingHor, &SubsamplingVer);
-					switch ((SubsamplingHor<<4)|SubsamplingVer) {
-						case 0x44:
-							img->put.contig = putcontig8bitYCbCr44tile;
-							break;
-						case 0x42:
-							img->put.contig = putcontig8bitYCbCr42tile;
-							break;
-						case 0x41:
-							img->put.contig = putcontig8bitYCbCr41tile;
-							break;
-						case 0x22:
-							img->put.contig = putcontig8bitYCbCr22tile;
-							break;
-						case 0x21:
-							img->put.contig = putcontig8bitYCbCr21tile;
-							break;
-						case 0x12:
-							img->put.contig = putcontig8bitYCbCr12tile;
-							break;
-						case 0x11:
-							img->put.contig = putcontig8bitYCbCr11tile;
-							break;
-					}
-				}
-			}
-			break;
-		case PHOTOMETRIC_CIELAB:
-			if (buildMap(img)) {
-				if (img->bitspersample == 8)
-					img->put.contig = initCIELabConversion(img);
-				break;
-			}
-	}
-	return ((img->get!=NULL) && (img->put.contig!=NULL));
-}
-
-/*
- * Select the appropriate conversion routine for unpacked data.
- *
- * NB: we assume that unpacked single channel data is directed
- *	 to the "packed routines.
- */
-static int
-PickSeparateCase(TIFFRGBAImage* img)
-{
-	img->get = TIFFIsTiled(img->tif) ? gtTileSeparate : gtStripSeparate;
-	img->put.separate = NULL;
-	switch (img->photometric) {
-		case PHOTOMETRIC_RGB:
-			switch (img->bitspersample) {
-				case 8:
-					if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
-						img->put.separate = putRGBAAseparate8bittile;
-					else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
-					{
-                                            img->put.separate = putRGBUAseparate8bittile;
-					}
-					else
-						img->put.separate = putRGBseparate8bittile;
-					break;
-				case 16:
-					if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
-					{
-                                            img->put.separate = putRGBAAseparate16bittile;
-					}
-					else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
-					{
-                                            img->put.separate = putRGBUAseparate16bittile;
-					}
-					else
-					{
-                                            img->put.separate = putRGBseparate16bittile;
-					}
-					break;
-			}
-			break;
-		case PHOTOMETRIC_YCBCR:
-			if ((img->bitspersample==8) && (img->samplesperpixel==3))
-			{
-				if (initYCbCrConversion(img)!=0)
-				{
-					uint16 hs, vs;
-					TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &hs, &vs);
-					switch ((hs<<4)|vs) {
-						case 0x11:
-							img->put.separate = putseparate8bitYCbCr11tile;
-							break;
-						/* TODO: add other cases here */
-					}
-				}
-			}
-			break;
-	}
-	return ((img->get!=NULL) && (img->put.separate!=NULL));
-}
-
-/*
- * Read a whole strip off data from the file, and convert to RGBA form.
- * If this is the last strip, then it will only contain the portion of
- * the strip that is actually within the image space.  The result is
- * organized in bottom to top form.
- */
-
-
-int
-TIFFReadRGBAStrip(TIFF* tif, uint32 row, uint32 * raster )
-
-{
-    char 	emsg[1024] = "";
-    TIFFRGBAImage img;
-    int 	ok;
-    uint32	rowsperstrip, rows_to_read;
-
-    if( TIFFIsTiled( tif ) )
-    {
-		TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
-                  "Can't use TIFFReadRGBAStrip() with tiled file.");
-	return (0);
-    }
-    
-    TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
-    if( (row % rowsperstrip) != 0 )
-    {
-		TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
-				"Row passed to TIFFReadRGBAStrip() must be first in a strip.");
-		return (0);
-    }
-
-    if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, 0, emsg)) {
-
-        img.row_offset = row;
-        img.col_offset = 0;
-
-        if( row + rowsperstrip > img.height )
-            rows_to_read = img.height - row;
-        else
-            rows_to_read = rowsperstrip;
-        
-	ok = TIFFRGBAImageGet(&img, raster, img.width, rows_to_read );
-        
-	TIFFRGBAImageEnd(&img);
-    } else {
-		TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg);
-		ok = 0;
-    }
-    
-    return (ok);
-}
-
-/*
- * Read a whole tile off data from the file, and convert to RGBA form.
- * The returned RGBA data is organized from bottom to top of tile,
- * and may include zeroed areas if the tile extends off the image.
- */
-
-int
-TIFFReadRGBATile(TIFF* tif, uint32 col, uint32 row, uint32 * raster)
-
-{
-    char 	emsg[1024] = "";
-    TIFFRGBAImage img;
-    int 	ok;
-    uint32	tile_xsize, tile_ysize;
-    uint32	read_xsize, read_ysize;
-    uint32	i_row;
-
-    /*
-     * Verify that our request is legal - on a tile file, and on a
-     * tile boundary.
-     */
-    
-    if( !TIFFIsTiled( tif ) )
-    {
-		TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
-				  "Can't use TIFFReadRGBATile() with stripped file.");
-		return (0);
-    }
-    
-    TIFFGetFieldDefaulted(tif, TIFFTAG_TILEWIDTH, &tile_xsize);
-    TIFFGetFieldDefaulted(tif, TIFFTAG_TILELENGTH, &tile_ysize);
-    if( (col % tile_xsize) != 0 || (row % tile_ysize) != 0 )
-    {
-		TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
-                  "Row/col passed to TIFFReadRGBATile() must be top"
-                  "left corner of a tile.");
-	return (0);
-    }
-
-    /*
-     * Setup the RGBA reader.
-     */
-    
-    if (!TIFFRGBAImageOK(tif, emsg) 
-	|| !TIFFRGBAImageBegin(&img, tif, 0, emsg)) {
-	    TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg);
-	    return( 0 );
-    }
-
-    /*
-     * The TIFFRGBAImageGet() function doesn't allow us to get off the
-     * edge of the image, even to fill an otherwise valid tile.  So we
-     * figure out how much we can read, and fix up the tile buffer to
-     * a full tile configuration afterwards.
-     */
-
-    if( row + tile_ysize > img.height )
-        read_ysize = img.height - row;
-    else
-        read_ysize = tile_ysize;
-    
-    if( col + tile_xsize > img.width )
-        read_xsize = img.width - col;
-    else
-        read_xsize = tile_xsize;
-
-    /*
-     * Read the chunk of imagery.
-     */
-    
-    img.row_offset = row;
-    img.col_offset = col;
-
-    ok = TIFFRGBAImageGet(&img, raster, read_xsize, read_ysize );
-        
-    TIFFRGBAImageEnd(&img);
-
-    /*
-     * If our read was incomplete we will need to fix up the tile by
-     * shifting the data around as if a full tile of data is being returned.
-     *
-     * This is all the more complicated because the image is organized in
-     * bottom to top format. 
-     */
-
-    if( read_xsize == tile_xsize && read_ysize == tile_ysize )
-        return( ok );
-
-    for( i_row = 0; i_row < read_ysize; i_row++ ) {
-        memmove( raster + (tile_ysize - i_row - 1) * tile_xsize,
-                 raster + (read_ysize - i_row - 1) * read_xsize,
-                 read_xsize * sizeof(uint32) );
-        _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize+read_xsize,
-                     0, sizeof(uint32) * (tile_xsize - read_xsize) );
-    }
-
-    for( i_row = read_ysize; i_row < tile_ysize; i_row++ ) {
-        _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize,
-                     0, sizeof(uint32) * tile_xsize );
-    }
-
-    return (ok);
-}
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_jbig.c b/Source/LibTIFF/tif_jbig.c
deleted file mode 100644
index c779c9b..0000000
--- a/Source/LibTIFF/tif_jbig.c
+++ /dev/null
@@ -1,385 +0,0 @@
-/* $Id: tif_jbig.c,v 1.23 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library.
- *
- * JBIG Compression Algorithm Support.
- * Contributed by Lee Howard <faxguy at deanox.com>
- * 
- */
-
-#include "tiffiop.h"
-
-#ifdef JBIG_SUPPORT
-#include "jbig.h"
-
-typedef struct
-{
-        uint32  recvparams;     /* encoded Class 2 session params             */
-        char*   subaddress;     /* subaddress string                          */
-        uint32  recvtime;       /* time spend receiving in seconds            */
-        char*   faxdcs;         /* encoded fax parameters (DCS, Table 2/T.30) */
-
-        TIFFVGetMethod vgetparent;
-        TIFFVSetMethod vsetparent;
-} JBIGState;
-
-#define GetJBIGState(tif) ((JBIGState*)(tif)->tif_data)
-
-#define FIELD_RECVPARAMS        (FIELD_CODEC+0)
-#define FIELD_SUBADDRESS        (FIELD_CODEC+1)
-#define FIELD_RECVTIME          (FIELD_CODEC+2)
-#define FIELD_FAXDCS            (FIELD_CODEC+3)
-
-static const TIFFFieldInfo jbigFieldInfo[] = 
-{
-        {TIFFTAG_FAXRECVPARAMS,  1,  1, TIFF_LONG,  FIELD_RECVPARAMS, TRUE, FALSE, "FaxRecvParams"},
-        {TIFFTAG_FAXSUBADDRESS, -1, -1, TIFF_ASCII, FIELD_SUBADDRESS, TRUE, FALSE, "FaxSubAddress"},
-        {TIFFTAG_FAXRECVTIME,    1,  1, TIFF_LONG,  FIELD_RECVTIME,   TRUE, FALSE, "FaxRecvTime"},
-        {TIFFTAG_FAXDCS,        -1, -1, TIFF_ASCII, FIELD_FAXDCS,     TRUE, FALSE, "FaxDcs"},
-};
-
-static int JBIGSetupDecode(TIFF* tif)
-{
-        if (TIFFNumberOfStrips(tif) != 1)
-        {
-                TIFFError("JBIG", "Multistrip images not supported in decoder");
-                return 0;
-        }
-
-        return 1;
-}
-
-static int JBIGDecode(TIFF* tif, tidata_t buffer, tsize_t size, tsample_t s)
-{
-        struct jbg_dec_state decoder;
-        int decodeStatus = 0;
-        unsigned char* pImage = NULL;
-	(void) size, (void) s;
-
-        if (isFillOrder(tif, tif->tif_dir.td_fillorder))
-        {
-                TIFFReverseBits(tif->tif_rawdata, tif->tif_rawdatasize);
-        }
-
-        jbg_dec_init(&decoder);
-
-#if defined(HAVE_JBG_NEWLEN)
-        jbg_newlen(tif->tif_rawdata, tif->tif_rawdatasize);
-        /*
-         * I do not check the return status of jbg_newlen because even if this
-         * function fails it does not necessarily mean that decoding the image
-         * will fail.  It is generally only needed for received fax images
-         * that do not contain the actual length of the image in the BIE
-         * header.  I do not log when an error occurs because that will cause
-         * problems when converting JBIG encoded TIFF's to 
-         * PostScript.  As long as the actual image length is contained in the
-         * BIE header jbg_dec_in should succeed.
-         */
-#endif /* HAVE_JBG_NEWLEN */
-
-        decodeStatus = jbg_dec_in(&decoder, tif->tif_rawdata,
-                                  tif->tif_rawdatasize, NULL);
-        if (JBG_EOK != decodeStatus)
-        {
-		/*
-		 * XXX: JBG_EN constant was defined in pre-2.0 releases of the
-		 * JBIG-KIT. Since the 2.0 the error reporting functions were
-		 * changed. We will handle both cases here.
-		 */
-                TIFFError("JBIG", "Error (%d) decoding: %s", decodeStatus,
-#if defined(JBG_EN)
-			  jbg_strerror(decodeStatus, JBG_EN)
-#else
-                          jbg_strerror(decodeStatus)
-#endif
-			 );
-                return 0;
-        }
-        
-        pImage = jbg_dec_getimage(&decoder, 0);
-        _TIFFmemcpy(buffer, pImage, jbg_dec_getsize(&decoder));
-        jbg_dec_free(&decoder);
-        return 1;
-}
-
-static int JBIGSetupEncode(TIFF* tif)
-{
-        if (TIFFNumberOfStrips(tif) != 1)
-        {
-                TIFFError("JBIG", "Multistrip images not supported in encoder");
-                return 0;
-        }
-
-        return 1;
-}
-
-static int JBIGCopyEncodedData(TIFF* tif, tidata_t pp, tsize_t cc, tsample_t s)
-{
-        (void) s;
-        while (cc > 0) 
-        {
-                tsize_t n = cc;
-
-                if (tif->tif_rawcc + n > tif->tif_rawdatasize)
-                {
-                        n = tif->tif_rawdatasize - tif->tif_rawcc;
-                }
-
-                assert(n > 0);
-                _TIFFmemcpy(tif->tif_rawcp, pp, n);
-                tif->tif_rawcp += n;
-                tif->tif_rawcc += n;
-                pp += n;
-                cc -= n;
-                if (tif->tif_rawcc >= tif->tif_rawdatasize &&
-                    !TIFFFlushData1(tif))
-                {
-                        return (-1);
-                }
-        }
-
-        return (1);
-}
-
-static void JBIGOutputBie(unsigned char* buffer, size_t len, void *userData)
-{
-        TIFF* tif = (TIFF*)userData;
-
-        if (isFillOrder(tif, tif->tif_dir.td_fillorder))
-        {
-                TIFFReverseBits(buffer, len);
-        }
-
-        JBIGCopyEncodedData(tif, buffer, len, 0);
-}
-
-static int JBIGEncode(TIFF* tif, tidata_t buffer, tsize_t size, tsample_t s)
-{
-        TIFFDirectory* dir = &tif->tif_dir;
-        struct jbg_enc_state encoder;
-
-	(void) size, (void) s;
-
-        jbg_enc_init(&encoder, 
-                     dir->td_imagewidth, 
-                     dir->td_imagelength, 
-                     1, 
-                     &buffer,
-                     JBIGOutputBie,
-                     tif);
-        /* 
-         * jbg_enc_out does the "real" encoding.  As data is encoded,
-         * JBIGOutputBie is called, which writes the data to the directory.
-         */
-        jbg_enc_out(&encoder);
-        jbg_enc_free(&encoder);
-
-        return 1;
-}
-
-static void JBIGCleanup(TIFF* tif)
-{
-        JBIGState *sp = GetJBIGState(tif);
-
-        assert(sp != 0);
-
-        tif->tif_tagmethods.vgetfield = sp->vgetparent;
-        tif->tif_tagmethods.vsetfield = sp->vsetparent;
-
-	_TIFFfree(tif->tif_data);
-	tif->tif_data = NULL;
-
-	_TIFFSetDefaultCompressionState(tif);
-}
-
-static void JBIGPrintDir(TIFF* tif, FILE* fd, long flags)
-{
-        JBIGState* codec = GetJBIGState(tif);
-        (void)flags;
-
-        if (TIFFFieldSet(tif, FIELD_RECVPARAMS))
-        {
-                fprintf(fd, 
-                        "  Fax Receive Parameters: %08lx\n",
-                        (unsigned long)codec->recvparams);
-        }
-
-        if (TIFFFieldSet(tif, FIELD_SUBADDRESS))
-        {
-                fprintf(fd, 
-                        "  Fax SubAddress: %s\n", 
-                        codec->subaddress);
-        }
-
-        if (TIFFFieldSet(tif, FIELD_RECVTIME))
-        {
-                fprintf(fd, 
-                        "  Fax Receive Time: %lu secs\n",
-                        (unsigned long)codec->recvtime);
-        }
-
-        if (TIFFFieldSet(tif, FIELD_FAXDCS))
-        {
-                fprintf(fd, 
-                        "  Fax DCS: %s\n", 
-                        codec->faxdcs);
-        }
-}
-
-static int JBIGVGetField(TIFF* tif, ttag_t tag, va_list ap)
-{
-        JBIGState* codec = GetJBIGState(tif);
-
-        switch (tag)
-        {
-                case TIFFTAG_FAXRECVPARAMS:
-                        *va_arg(ap, uint32*) = codec->recvparams;
-                        break;
-                
-                case TIFFTAG_FAXSUBADDRESS:
-                        *va_arg(ap, char**) = codec->subaddress;
-                        break;
-
-                case TIFFTAG_FAXRECVTIME:
-                        *va_arg(ap, uint32*) = codec->recvtime;
-                        break;
-
-                case TIFFTAG_FAXDCS:
-                        *va_arg(ap, char**) = codec->faxdcs;
-                        break;
-
-                default:
-                        return (*codec->vgetparent)(tif, tag, ap);
-        }
-
-        return 1;
-}
-
-static int JBIGVSetField(TIFF* tif, ttag_t tag, va_list ap)
-{
-        JBIGState* codec = GetJBIGState(tif);
-
-        switch (tag)
-        {
-                case TIFFTAG_FAXRECVPARAMS:
-                        codec->recvparams = va_arg(ap, uint32);
-                        break;
-
-                case TIFFTAG_FAXSUBADDRESS:
-                        _TIFFsetString(&codec->subaddress, va_arg(ap, char*));
-                        break;
-
-                case TIFFTAG_FAXRECVTIME:
-                        codec->recvtime = va_arg(ap, uint32);
-                        break;
-
-                case TIFFTAG_FAXDCS:
-                        _TIFFsetString(&codec->faxdcs, va_arg(ap, char*));
-                        break;
-
-                default:
-                        return (*codec->vsetparent)(tif, tag, ap);
-        }
-
-        TIFFSetFieldBit(tif, _TIFFFieldWithTag(tif, tag)->field_bit);
-        tif->tif_flags |= TIFF_DIRTYDIRECT;
-        return 1;
-}
-
-int TIFFInitJBIG(TIFF* tif, int scheme)
-{
-        JBIGState* codec = NULL;
-
-	assert(scheme == COMPRESSION_JBIG);
-
-	/*
-	 * Merge codec-specific tag information.
-	 */
-	if (!_TIFFMergeFieldInfo(tif, jbigFieldInfo,
-				 TIFFArrayCount(jbigFieldInfo))) {
-		TIFFErrorExt(tif->tif_clientdata, "TIFFInitJBIG",
-			     "Merging JBIG codec-specific tags failed");
-		return 0;
-	}
-
-        /* Allocate memory for the JBIGState structure.*/
-        tif->tif_data = (tdata_t)_TIFFmalloc(sizeof(JBIGState));
-        if (tif->tif_data == NULL)
-        {
-                TIFFError("TIFFInitJBIG", "Not enough memory for JBIGState");
-                return 0;
-        }
-        _TIFFmemset(tif->tif_data, 0, sizeof(JBIGState));
-        codec = GetJBIGState(tif);
-
-        /* Initialize codec private fields */
-        codec->recvparams = 0;
-        codec->subaddress = NULL;
-        codec->faxdcs = NULL;
-        codec->recvtime = 0;
-
-	/* 
-	 * Override parent get/set field methods.
-	 */
-        codec->vgetparent = tif->tif_tagmethods.vgetfield;
-        codec->vsetparent = tif->tif_tagmethods.vsetfield;
-        tif->tif_tagmethods.vgetfield = JBIGVGetField;
-        tif->tif_tagmethods.vsetfield = JBIGVSetField;
-        tif->tif_tagmethods.printdir = JBIGPrintDir;
-
-        /*
-         * These flags are set so the JBIG Codec can control when to reverse
-         * bits and when not to and to allow the jbig decoder and bit reverser
-         * to write to memory when necessary.
-         */
-        tif->tif_flags |= TIFF_NOBITREV;
-        tif->tif_flags &= ~TIFF_MAPPED;
-
-        /* Setup the function pointers for encode, decode, and cleanup. */
-        tif->tif_setupdecode = JBIGSetupDecode;
-        tif->tif_decodestrip = JBIGDecode;
-
-        tif->tif_setupencode = JBIGSetupEncode;
-        tif->tif_encodestrip = JBIGEncode;
-        
-        tif->tif_cleanup = JBIGCleanup;
-
-        return 1;
-}
-
-#endif /* JBIG_SUPPORT */
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_jpeg.c b/Source/LibTIFF/tif_jpeg.c
deleted file mode 100644
index d930d80..0000000
--- a/Source/LibTIFF/tif_jpeg.c
+++ /dev/null
@@ -1,2078 +0,0 @@
-/* $Id: tif_jpeg.c,v 1.37 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1994-1997 Sam Leffler
- * Copyright (c) 1994-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-#define WIN32_LEAN_AND_MEAN
-#define VC_EXTRALEAN
-
-#include "tiffiop.h"
-#ifdef JPEG_SUPPORT
-
-/*
- * TIFF Library
- *
- * JPEG Compression support per TIFF Technical Note #2
- * (*not* per the original TIFF 6.0 spec).
- *
- * This file is simply an interface to the libjpeg library written by
- * the Independent JPEG Group.  You need release 5 or later of the IJG
- * code, which you can find on the Internet at ftp.uu.net:/graphics/jpeg/.
- *
- * Contributed by Tom Lane <tgl at sss.pgh.pa.us>.
- */
-#include <setjmp.h>
-
-int TIFFFillStrip(TIFF*, tstrip_t);
-int TIFFFillTile(TIFF*, ttile_t);
-
-/* We undefine FAR to avoid conflict with JPEG definition */
-
-#ifdef FAR
-#undef FAR
-#endif
-
-/*
-  Libjpeg's jmorecfg.h defines INT16 and INT32, but only if XMD_H is
-  not defined.  Unfortunately, the MinGW and Borland compilers include
-  a typedef for INT32, which causes a conflict.  MSVC does not include
-  a conficting typedef given the headers which are included.
-*/
-#if defined(__BORLANDC__) || defined(__MINGW32__)
-# define XMD_H 1
-#endif
-
-/*
-   The windows RPCNDR.H file defines boolean, but defines it with the
-   unsigned char size.  You should compile JPEG library using appropriate
-   definitions in jconfig.h header, but many users compile library in wrong
-   way. That causes errors of the following type:
-
-   "JPEGLib: JPEG parameter struct mismatch: library thinks size is 432,
-   caller expects 464"
-
-   For such users we wil fix the problem here. See install.doc file from
-   the JPEG library distribution for details.
-*/
-
-/* Define "boolean" as unsigned char, not int, per Windows custom. */
-#if defined(WIN32) && !defined(__MINGW32__)
-# ifndef __RPCNDR_H__            /* don't conflict if rpcndr.h already read */
-   typedef unsigned char boolean;
-# endif
-# define HAVE_BOOLEAN            /* prevent jmorecfg.h from redefining it */
-#endif
-
-#include "../LibJPEG/jpeglib.h"
-#include "../LibJPEG/jerror.h"
-
-/*
- * We are using width_in_blocks which is supposed to be private to
- * libjpeg. Unfortunately, the libjpeg delivered with Cygwin has
- * renamed this member to width_in_data_units.  Since the header has
- * also renamed a define, use that unique define name in order to
- * detect the problem header and adjust to suit.
- */
-#if defined(D_MAX_DATA_UNITS_IN_MCU)
-#define width_in_blocks width_in_data_units
-#endif
-
-/*
- * On some machines it may be worthwhile to use _setjmp or sigsetjmp
- * in place of plain setjmp.  These macros will make it easier.
- */
-#define SETJMP(jbuf)		setjmp(jbuf)
-#define LONGJMP(jbuf,code)	longjmp(jbuf,code)
-#define JMP_BUF			jmp_buf
-
-typedef struct jpeg_destination_mgr jpeg_destination_mgr;
-typedef struct jpeg_source_mgr jpeg_source_mgr;
-typedef	struct jpeg_error_mgr jpeg_error_mgr;
-
-/*
- * State block for each open TIFF file using
- * libjpeg to do JPEG compression/decompression.
- *
- * libjpeg's visible state is either a jpeg_compress_struct
- * or jpeg_decompress_struct depending on which way we
- * are going.  comm can be used to refer to the fields
- * which are common to both.
- *
- * NB: cinfo is required to be the first member of JPEGState,
- *     so we can safely cast JPEGState* -> jpeg_xxx_struct*
- *     and vice versa!
- */
-typedef	struct {
-	union {
-		struct jpeg_compress_struct c;
-		struct jpeg_decompress_struct d;
-		struct jpeg_common_struct comm;
-	} cinfo;			/* NB: must be first */
-        int             cinfo_initialized;
-
-	jpeg_error_mgr	err;		/* libjpeg error manager */
-	JMP_BUF		exit_jmpbuf;	/* for catching libjpeg failures */
-	/*
-	 * The following two members could be a union, but
-	 * they're small enough that it's not worth the effort.
-	 */
-	jpeg_destination_mgr dest;	/* data dest for compression */
-	jpeg_source_mgr	src;		/* data source for decompression */
-					/* private state */
-	TIFF*		tif;		/* back link needed by some code */
-	uint16		photometric;	/* copy of PhotometricInterpretation */
-	uint16		h_sampling;	/* luminance sampling factors */
-	uint16		v_sampling;
-	tsize_t		bytesperline;	/* decompressed bytes per scanline */
-	/* pointers to intermediate buffers when processing downsampled data */
-	JSAMPARRAY	ds_buffer[MAX_COMPONENTS];
-	int		scancount;	/* number of "scanlines" accumulated */
-	int		samplesperclump;
-
-	TIFFVGetMethod	vgetparent;	/* super-class method */
-	TIFFVSetMethod	vsetparent;	/* super-class method */
-	TIFFPrintMethod printdir;	/* super-class method */
-	TIFFStripMethod	defsparent;	/* super-class method */
-	TIFFTileMethod	deftparent;	/* super-class method */
-					/* pseudo-tag fields */
-	void*		jpegtables;	/* JPEGTables tag value, or NULL */
-	uint32		jpegtables_length; /* number of bytes in same */
-	int		jpegquality;	/* Compression quality level */
-	int		jpegcolormode;	/* Auto RGB<=>YCbCr convert? */
-	int		jpegtablesmode;	/* What to put in JPEGTables */
-
-        int             ycbcrsampling_fetched;
-	uint32		recvparams;	/* encoded Class 2 session params */
-	char*		subaddress;	/* subaddress string */
-	uint32		recvtime;	/* time spent receiving (secs) */
-	char*		faxdcs;		/* encoded fax parameters (DCS, Table 2/T.30) */
-} JPEGState;
-
-#define	JState(tif)	((JPEGState*)(tif)->tif_data)
-
-static	int JPEGDecode(TIFF*, tidata_t, tsize_t, tsample_t);
-static	int JPEGDecodeRaw(TIFF*, tidata_t, tsize_t, tsample_t);
-static	int JPEGEncode(TIFF*, tidata_t, tsize_t, tsample_t);
-static	int JPEGEncodeRaw(TIFF*, tidata_t, tsize_t, tsample_t);
-static  int JPEGInitializeLibJPEG( TIFF * tif,
-								   int force_encode, int force_decode );
-
-#define	FIELD_JPEGTABLES	(FIELD_CODEC+0)
-#define	FIELD_RECVPARAMS	(FIELD_CODEC+1)
-#define	FIELD_SUBADDRESS	(FIELD_CODEC+2)
-#define	FIELD_RECVTIME		(FIELD_CODEC+3)
-#define	FIELD_FAXDCS		(FIELD_CODEC+4)
-
-static const TIFFFieldInfo jpegFieldInfo[] = {
-    { TIFFTAG_JPEGTABLES,	 -3,-3,	TIFF_UNDEFINED,	FIELD_JPEGTABLES,
-      FALSE,	TRUE,	"JPEGTables" },
-    { TIFFTAG_JPEGQUALITY,	 0, 0,	TIFF_ANY,	FIELD_PSEUDO,
-      TRUE,	FALSE,	"" },
-    { TIFFTAG_JPEGCOLORMODE,	 0, 0,	TIFF_ANY,	FIELD_PSEUDO,
-      FALSE,	FALSE,	"" },
-    { TIFFTAG_JPEGTABLESMODE,	 0, 0,	TIFF_ANY,	FIELD_PSEUDO,
-      FALSE,	FALSE,	"" },
-    /* Specific for JPEG in faxes */
-    { TIFFTAG_FAXRECVPARAMS,	 1, 1, TIFF_LONG,	FIELD_RECVPARAMS,
-      TRUE,	FALSE,	"FaxRecvParams" },
-    { TIFFTAG_FAXSUBADDRESS,	-1,-1, TIFF_ASCII,	FIELD_SUBADDRESS,
-      TRUE,	FALSE,	"FaxSubAddress" },
-    { TIFFTAG_FAXRECVTIME,	 1, 1, TIFF_LONG,	FIELD_RECVTIME,
-      TRUE,	FALSE,	"FaxRecvTime" },
-    { TIFFTAG_FAXDCS,		-1, -1, TIFF_ASCII,	FIELD_FAXDCS,
-	  TRUE,	FALSE,	"FaxDcs" },
-};
-#define	N(a)	(sizeof (a) / sizeof (a[0]))
-
-/*
- * libjpeg interface layer.
- *
- * We use setjmp/longjmp to return control to libtiff
- * when a fatal error is encountered within the JPEG
- * library.  We also direct libjpeg error and warning
- * messages through the appropriate libtiff handlers.
- */
-
-/*
- * Error handling routines (these replace corresponding
- * IJG routines from jerror.c).  These are used for both
- * compression and decompression.
- */
-static void
-TIFFjpeg_error_exit(j_common_ptr cinfo)
-{
-	JPEGState *sp = (JPEGState *) cinfo;	/* NB: cinfo assumed first */
-	char buffer[JMSG_LENGTH_MAX];
-
-	(*cinfo->err->format_message) (cinfo, buffer);
-	TIFFErrorExt(sp->tif->tif_clientdata, "JPEGLib", "%s", buffer);		/* display the error message */
-	jpeg_abort(cinfo);			/* clean up libjpeg state */
-	LONGJMP(sp->exit_jmpbuf, 1);		/* return to libtiff caller */
-}
-
-/*
- * This routine is invoked only for warning messages,
- * since error_exit does its own thing and trace_level
- * is never set > 0.
- */
-static void
-TIFFjpeg_output_message(j_common_ptr cinfo)
-{
-	char buffer[JMSG_LENGTH_MAX];
-
-	(*cinfo->err->format_message) (cinfo, buffer);
-	TIFFWarningExt(((JPEGState *) cinfo)->tif->tif_clientdata, "JPEGLib", "%s", buffer);
-}
-
-/*
- * Interface routines.  This layer of routines exists
- * primarily to limit side-effects from using setjmp.
- * Also, normal/error returns are converted into return
- * values per libtiff practice.
- */
-#define	CALLJPEG(sp, fail, op)	(SETJMP((sp)->exit_jmpbuf) ? (fail) : (op))
-#define	CALLVJPEG(sp, op)	CALLJPEG(sp, 0, ((op),1))
-
-static int
-TIFFjpeg_create_compress(JPEGState* sp)
-{
-	/* initialize JPEG error handling */
-	sp->cinfo.c.err = jpeg_std_error(&sp->err);
-	sp->err.error_exit = TIFFjpeg_error_exit;
-	sp->err.output_message = TIFFjpeg_output_message;
-
-	return CALLVJPEG(sp, jpeg_create_compress(&sp->cinfo.c));
-}
-
-static int
-TIFFjpeg_create_decompress(JPEGState* sp)
-{
-	/* initialize JPEG error handling */
-	sp->cinfo.d.err = jpeg_std_error(&sp->err);
-	sp->err.error_exit = TIFFjpeg_error_exit;
-	sp->err.output_message = TIFFjpeg_output_message;
-
-	return CALLVJPEG(sp, jpeg_create_decompress(&sp->cinfo.d));
-}
-
-static int
-TIFFjpeg_set_defaults(JPEGState* sp)
-{
-	return CALLVJPEG(sp, jpeg_set_defaults(&sp->cinfo.c));
-}
-
-static int
-TIFFjpeg_set_colorspace(JPEGState* sp, J_COLOR_SPACE colorspace)
-{
-	return CALLVJPEG(sp, jpeg_set_colorspace(&sp->cinfo.c, colorspace));
-}
-
-static int
-TIFFjpeg_set_quality(JPEGState* sp, int quality, boolean force_baseline)
-{
-	return CALLVJPEG(sp,
-	    jpeg_set_quality(&sp->cinfo.c, quality, force_baseline));
-}
-
-static int
-TIFFjpeg_suppress_tables(JPEGState* sp, boolean suppress)
-{
-	return CALLVJPEG(sp, jpeg_suppress_tables(&sp->cinfo.c, suppress));
-}
-
-static int
-TIFFjpeg_start_compress(JPEGState* sp, boolean write_all_tables)
-{
-	return CALLVJPEG(sp,
-	    jpeg_start_compress(&sp->cinfo.c, write_all_tables));
-}
-
-static int
-TIFFjpeg_write_scanlines(JPEGState* sp, JSAMPARRAY scanlines, int num_lines)
-{
-	return CALLJPEG(sp, -1, (int) jpeg_write_scanlines(&sp->cinfo.c,
-	    scanlines, (JDIMENSION) num_lines));
-}
-
-static int
-TIFFjpeg_write_raw_data(JPEGState* sp, JSAMPIMAGE data, int num_lines)
-{
-	return CALLJPEG(sp, -1, (int) jpeg_write_raw_data(&sp->cinfo.c,
-	    data, (JDIMENSION) num_lines));
-}
-
-static int
-TIFFjpeg_finish_compress(JPEGState* sp)
-{
-	return CALLVJPEG(sp, jpeg_finish_compress(&sp->cinfo.c));
-}
-
-static int
-TIFFjpeg_write_tables(JPEGState* sp)
-{
-	return CALLVJPEG(sp, jpeg_write_tables(&sp->cinfo.c));
-}
-
-static int
-TIFFjpeg_read_header(JPEGState* sp, boolean require_image)
-{
-	return CALLJPEG(sp, -1, jpeg_read_header(&sp->cinfo.d, require_image));
-}
-
-static int
-TIFFjpeg_start_decompress(JPEGState* sp)
-{
-	return CALLVJPEG(sp, jpeg_start_decompress(&sp->cinfo.d));
-}
-
-static int
-TIFFjpeg_read_scanlines(JPEGState* sp, JSAMPARRAY scanlines, int max_lines)
-{
-	return CALLJPEG(sp, -1, (int) jpeg_read_scanlines(&sp->cinfo.d,
-	    scanlines, (JDIMENSION) max_lines));
-}
-
-static int
-TIFFjpeg_read_raw_data(JPEGState* sp, JSAMPIMAGE data, int max_lines)
-{
-	return CALLJPEG(sp, -1, (int) jpeg_read_raw_data(&sp->cinfo.d,
-	    data, (JDIMENSION) max_lines));
-}
-
-static int
-TIFFjpeg_finish_decompress(JPEGState* sp)
-{
-	return CALLJPEG(sp, -1, (int) jpeg_finish_decompress(&sp->cinfo.d));
-}
-
-static int
-TIFFjpeg_abort(JPEGState* sp)
-{
-	return CALLVJPEG(sp, jpeg_abort(&sp->cinfo.comm));
-}
-
-static int
-TIFFjpeg_destroy(JPEGState* sp)
-{
-	return CALLVJPEG(sp, jpeg_destroy(&sp->cinfo.comm));
-}
-
-static JSAMPARRAY
-TIFFjpeg_alloc_sarray(JPEGState* sp, int pool_id,
-		      JDIMENSION samplesperrow, JDIMENSION numrows)
-{
-	return CALLJPEG(sp, (JSAMPARRAY) NULL,
-	    (*sp->cinfo.comm.mem->alloc_sarray)
-		(&sp->cinfo.comm, pool_id, samplesperrow, numrows));
-}
-
-/*
- * JPEG library destination data manager.
- * These routines direct compressed data from libjpeg into the
- * libtiff output buffer.
- */
-
-static void
-std_init_destination(j_compress_ptr cinfo)
-{
-	JPEGState* sp = (JPEGState*) cinfo;
-	TIFF* tif = sp->tif;
-
-	sp->dest.next_output_byte = (JOCTET*) tif->tif_rawdata;
-	sp->dest.free_in_buffer = (size_t) tif->tif_rawdatasize;
-}
-
-static boolean
-std_empty_output_buffer(j_compress_ptr cinfo)
-{
-	JPEGState* sp = (JPEGState*) cinfo;
-	TIFF* tif = sp->tif;
-
-	/* the entire buffer has been filled */
-	tif->tif_rawcc = tif->tif_rawdatasize;
-	TIFFFlushData1(tif);
-	sp->dest.next_output_byte = (JOCTET*) tif->tif_rawdata;
-	sp->dest.free_in_buffer = (size_t) tif->tif_rawdatasize;
-
-	return (TRUE);
-}
-
-static void
-std_term_destination(j_compress_ptr cinfo)
-{
-	JPEGState* sp = (JPEGState*) cinfo;
-	TIFF* tif = sp->tif;
-
-	tif->tif_rawcp = (tidata_t) sp->dest.next_output_byte;
-	tif->tif_rawcc =
-	    tif->tif_rawdatasize - (tsize_t) sp->dest.free_in_buffer;
-	/* NB: libtiff does the final buffer flush */
-}
-
-static void
-TIFFjpeg_data_dest(JPEGState* sp, TIFF* tif)
-{
-	(void) tif;
-	sp->cinfo.c.dest = &sp->dest;
-	sp->dest.init_destination = std_init_destination;
-	sp->dest.empty_output_buffer = std_empty_output_buffer;
-	sp->dest.term_destination = std_term_destination;
-}
-
-/*
- * Alternate destination manager for outputting to JPEGTables field.
- */
-
-static void
-tables_init_destination(j_compress_ptr cinfo)
-{
-	JPEGState* sp = (JPEGState*) cinfo;
-
-	/* while building, jpegtables_length is allocated buffer size */
-	sp->dest.next_output_byte = (JOCTET*) sp->jpegtables;
-	sp->dest.free_in_buffer = (size_t) sp->jpegtables_length;
-}
-
-static boolean
-tables_empty_output_buffer(j_compress_ptr cinfo)
-{
-	JPEGState* sp = (JPEGState*) cinfo;
-	void* newbuf;
-
-	/* the entire buffer has been filled; enlarge it by 1000 bytes */
-	newbuf = _TIFFrealloc((tdata_t) sp->jpegtables,
-			      (tsize_t) (sp->jpegtables_length + 1000));
-	if (newbuf == NULL)
-		ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 100);
-	sp->dest.next_output_byte = (JOCTET*) newbuf + sp->jpegtables_length;
-	sp->dest.free_in_buffer = (size_t) 1000;
-	sp->jpegtables = newbuf;
-	sp->jpegtables_length += 1000;
-	return (TRUE);
-}
-
-static void
-tables_term_destination(j_compress_ptr cinfo)
-{
-	JPEGState* sp = (JPEGState*) cinfo;
-
-	/* set tables length to number of bytes actually emitted */
-	sp->jpegtables_length -= sp->dest.free_in_buffer;
-}
-
-static int
-TIFFjpeg_tables_dest(JPEGState* sp, TIFF* tif)
-{
-	(void) tif;
-	/*
-	 * Allocate a working buffer for building tables.
-	 * Initial size is 1000 bytes, which is usually adequate.
-	 */
-	if (sp->jpegtables)
-		_TIFFfree(sp->jpegtables);
-	sp->jpegtables_length = 1000;
-	sp->jpegtables = (void*) _TIFFmalloc((tsize_t) sp->jpegtables_length);
-	if (sp->jpegtables == NULL) {
-		sp->jpegtables_length = 0;
-		TIFFErrorExt(sp->tif->tif_clientdata, "TIFFjpeg_tables_dest", "No space for JPEGTables");
-		return (0);
-	}
-	sp->cinfo.c.dest = &sp->dest;
-	sp->dest.init_destination = tables_init_destination;
-	sp->dest.empty_output_buffer = tables_empty_output_buffer;
-	sp->dest.term_destination = tables_term_destination;
-	return (1);
-}
-
-/*
- * JPEG library source data manager.
- * These routines supply compressed data to libjpeg.
- */
-
-static void
-std_init_source(j_decompress_ptr cinfo)
-{
-	JPEGState* sp = (JPEGState*) cinfo;
-	TIFF* tif = sp->tif;
-
-	sp->src.next_input_byte = (const JOCTET*) tif->tif_rawdata;
-	sp->src.bytes_in_buffer = (size_t) tif->tif_rawcc;
-}
-
-static boolean
-std_fill_input_buffer(j_decompress_ptr cinfo)
-{
-	JPEGState* sp = (JPEGState* ) cinfo;
-	static const JOCTET dummy_EOI[2] = { 0xFF, JPEG_EOI };
-
-	/*
-	 * Should never get here since entire strip/tile is
-	 * read into memory before the decompressor is called,
-	 * and thus was supplied by init_source.
-	 */
-	WARNMS(cinfo, JWRN_JPEG_EOF);
-	/* insert a fake EOI marker */
-	sp->src.next_input_byte = dummy_EOI;
-	sp->src.bytes_in_buffer = 2;
-	return (TRUE);
-}
-
-static void
-std_skip_input_data(j_decompress_ptr cinfo, long num_bytes)
-{
-	JPEGState* sp = (JPEGState*) cinfo;
-
-	if (num_bytes > 0) {
-		if (num_bytes > (long) sp->src.bytes_in_buffer) {
-			/* oops, buffer overrun */
-			(void) std_fill_input_buffer(cinfo);
-		} else {
-			sp->src.next_input_byte += (size_t) num_bytes;
-			sp->src.bytes_in_buffer -= (size_t) num_bytes;
-		}
-	}
-}
-
-static void
-std_term_source(j_decompress_ptr cinfo)
-{
-	/* No work necessary here */
-	/* Or must we update tif->tif_rawcp, tif->tif_rawcc ??? */
-	/* (if so, need empty tables_term_source!) */
-	(void) cinfo;
-}
-
-static void
-TIFFjpeg_data_src(JPEGState* sp, TIFF* tif)
-{
-	(void) tif;
-	sp->cinfo.d.src = &sp->src;
-	sp->src.init_source = std_init_source;
-	sp->src.fill_input_buffer = std_fill_input_buffer;
-	sp->src.skip_input_data = std_skip_input_data;
-	sp->src.resync_to_restart = jpeg_resync_to_restart;
-	sp->src.term_source = std_term_source;
-	sp->src.bytes_in_buffer = 0;		/* for safety */
-	sp->src.next_input_byte = NULL;
-}
-
-/*
- * Alternate source manager for reading from JPEGTables.
- * We can share all the code except for the init routine.
- */
-
-static void
-tables_init_source(j_decompress_ptr cinfo)
-{
-	JPEGState* sp = (JPEGState*) cinfo;
-
-	sp->src.next_input_byte = (const JOCTET*) sp->jpegtables;
-	sp->src.bytes_in_buffer = (size_t) sp->jpegtables_length;
-}
-
-static void
-TIFFjpeg_tables_src(JPEGState* sp, TIFF* tif)
-{
-	TIFFjpeg_data_src(sp, tif);
-	sp->src.init_source = tables_init_source;
-}
-
-/*
- * Allocate downsampled-data buffers needed for downsampled I/O.
- * We use values computed in jpeg_start_compress or jpeg_start_decompress.
- * We use libjpeg's allocator so that buffers will be released automatically
- * when done with strip/tile.
- * This is also a handy place to compute samplesperclump, bytesperline.
- */
-static int
-alloc_downsampled_buffers(TIFF* tif, jpeg_component_info* comp_info,
-			  int num_components)
-{
-	JPEGState* sp = JState(tif);
-	int ci;
-	jpeg_component_info* compptr;
-	JSAMPARRAY buf;
-	int samples_per_clump = 0;
-
-	for (ci = 0, compptr = comp_info; ci < num_components;
-	     ci++, compptr++) {
-		samples_per_clump += compptr->h_samp_factor *
-			compptr->v_samp_factor;
-		buf = TIFFjpeg_alloc_sarray(sp, JPOOL_IMAGE,
-				compptr->width_in_blocks * DCTSIZE,
-				(JDIMENSION) (compptr->v_samp_factor*DCTSIZE));
-		if (buf == NULL)
-			return (0);
-		sp->ds_buffer[ci] = buf;
-	}
-	sp->samplesperclump = samples_per_clump;
-	return (1);
-}
-
-
-/*
- * JPEG Decoding.
- */
-
-static int
-JPEGSetupDecode(TIFF* tif)
-{
-	JPEGState* sp = JState(tif);
-	TIFFDirectory *td = &tif->tif_dir;
-
-        JPEGInitializeLibJPEG( tif, 0, 1 );
-
-	assert(sp != NULL);
-	assert(sp->cinfo.comm.is_decompressor);
-
-	/* Read JPEGTables if it is present */
-	if (TIFFFieldSet(tif,FIELD_JPEGTABLES)) {
-		TIFFjpeg_tables_src(sp, tif);
-		if(TIFFjpeg_read_header(sp,FALSE) != JPEG_HEADER_TABLES_ONLY) {
-			TIFFErrorExt(tif->tif_clientdata, "JPEGSetupDecode", "Bogus JPEGTables field");
-			return (0);
-		}
-	}
-
-	/* Grab parameters that are same for all strips/tiles */
-	sp->photometric = td->td_photometric;
-	switch (sp->photometric) {
-	case PHOTOMETRIC_YCBCR:
-		sp->h_sampling = td->td_ycbcrsubsampling[0];
-		sp->v_sampling = td->td_ycbcrsubsampling[1];
-		break;
-	default:
-		/* TIFF 6.0 forbids subsampling of all other color spaces */
-		sp->h_sampling = 1;
-		sp->v_sampling = 1;
-		break;
-	}
-
-	/* Set up for reading normal data */
-	TIFFjpeg_data_src(sp, tif);
-	tif->tif_postdecode = _TIFFNoPostDecode; /* override byte swapping */
-	return (1);
-}
-
-/*
- * Set up for decoding a strip or tile.
- */
-static int
-JPEGPreDecode(TIFF* tif, tsample_t s)
-{
-	JPEGState *sp = JState(tif);
-	TIFFDirectory *td = &tif->tif_dir;
-	static const char module[] = "JPEGPreDecode";
-	uint32 segment_width, segment_height;
-	int downsampled_output;
-	int ci;
-
-	assert(sp != NULL);
-	assert(sp->cinfo.comm.is_decompressor);
-	/*
-	 * Reset decoder state from any previous strip/tile,
-	 * in case application didn't read the whole strip.
-	 */
-	if (!TIFFjpeg_abort(sp))
-		return (0);
-	/*
-	 * Read the header for this strip/tile.
-	 */
-	if (TIFFjpeg_read_header(sp, TRUE) != JPEG_HEADER_OK)
-		return (0);
-	/*
-	 * Check image parameters and set decompression parameters.
-	 */
-	segment_width = td->td_imagewidth;
-	segment_height = td->td_imagelength - tif->tif_row;
-	if (isTiled(tif)) {
-                segment_width = td->td_tilewidth;
-                segment_height = td->td_tilelength;
-		sp->bytesperline = TIFFTileRowSize(tif);
-	} else {
-		if (segment_height > td->td_rowsperstrip)
-			segment_height = td->td_rowsperstrip;
-		sp->bytesperline = TIFFOldScanlineSize(tif);
-	}
-	if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0) {
-		/*
-		 * For PC 2, scale down the expected strip/tile size
-		 * to match a downsampled component
-		 */
-		segment_width = TIFFhowmany(segment_width, sp->h_sampling);
-		segment_height = TIFFhowmany(segment_height, sp->v_sampling);
-	}
-	if (sp->cinfo.d.image_width < segment_width ||
-	    sp->cinfo.d.image_height < segment_height) {
-		TIFFWarningExt(tif->tif_clientdata, module,
-			       "Improper JPEG strip/tile size, "
-			       "expected %dx%d, got %dx%d",
-			       segment_width, segment_height,
-			       sp->cinfo.d.image_width,
-			       sp->cinfo.d.image_height);
-	} 
-	if (sp->cinfo.d.image_width > segment_width ||
-	    sp->cinfo.d.image_height > segment_height) {
-		/*
-		 * This case could be dangerous, if the strip or tile size has
-		 * been reported as less than the amount of data jpeg will
-		 * return, some potential security issues arise. Catch this
-		 * case and error out.
-		 */
-		TIFFErrorExt(tif->tif_clientdata, module,
-			     "JPEG strip/tile size exceeds expected dimensions,"
-			     " expected %dx%d, got %dx%d",
-			     segment_width, segment_height,
-			     sp->cinfo.d.image_width, sp->cinfo.d.image_height);
-		return (0);
-	}
-	if (sp->cinfo.d.num_components !=
-	    (td->td_planarconfig == PLANARCONFIG_CONTIG ?
-	     td->td_samplesperpixel : 1)) {
-		TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG component count");
-		return (0);
-	}
-#ifdef JPEG_LIB_MK1
-	if (12 != td->td_bitspersample && 8 != td->td_bitspersample) {
-			TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG data precision");
-            return (0);
-	}
-        sp->cinfo.d.data_precision = td->td_bitspersample;
-        sp->cinfo.d.bits_in_jsample = td->td_bitspersample;
-#else
-	if (sp->cinfo.d.data_precision != td->td_bitspersample) {
-			TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG data precision");
-            return (0);
-	}
-#endif
-	if (td->td_planarconfig == PLANARCONFIG_CONTIG) {
-		/* Component 0 should have expected sampling factors */
-		if (sp->cinfo.d.comp_info[0].h_samp_factor != sp->h_sampling ||
-		    sp->cinfo.d.comp_info[0].v_samp_factor != sp->v_sampling) {
-				TIFFWarningExt(tif->tif_clientdata, module,
-                                    "Improper JPEG sampling factors %d,%d\n"
-                                    "Apparently should be %d,%d.",
-                                    sp->cinfo.d.comp_info[0].h_samp_factor,
-                                    sp->cinfo.d.comp_info[0].v_samp_factor,
-                                    sp->h_sampling, sp->v_sampling);
-
-				/*
-				 * There are potential security issues here
-				 * for decoders that have already allocated
-				 * buffers based on the expected sampling
-				 * factors. Lets check the sampling factors
-				 * dont exceed what we were expecting.
-				 */
-				if (sp->cinfo.d.comp_info[0].h_samp_factor
-					> sp->h_sampling
-				    || sp->cinfo.d.comp_info[0].v_samp_factor
-					> sp->v_sampling) {
-					TIFFErrorExt(tif->tif_clientdata,
-						     module,
-					"Cannot honour JPEG sampling factors"
-					" that exceed those specified.");
-					return (0);
-				}
-
-			    /*
-			     * XXX: Files written by the Intergraph software
-			     * has different sampling factors stored in the
-			     * TIFF tags and in the JPEG structures. We will
-			     * try to deduce Intergraph files by the presense
-			     * of the tag 33918.
-			     */
-			    if (!_TIFFFindFieldInfo(tif, 33918, TIFF_ANY)) {
-					TIFFWarningExt(tif->tif_clientdata, module,
-					"Decompressor will try reading with "
-					"sampling %d,%d.",
-					sp->cinfo.d.comp_info[0].h_samp_factor,
-					sp->cinfo.d.comp_info[0].v_samp_factor);
-
-				    sp->h_sampling = (uint16)
-					sp->cinfo.d.comp_info[0].h_samp_factor;
-				    sp->v_sampling = (uint16)
-					sp->cinfo.d.comp_info[0].v_samp_factor;
-			    }
-		}
-		/* Rest should have sampling factors 1,1 */
-		for (ci = 1; ci < sp->cinfo.d.num_components; ci++) {
-			if (sp->cinfo.d.comp_info[ci].h_samp_factor != 1 ||
-			    sp->cinfo.d.comp_info[ci].v_samp_factor != 1) {
-				TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG sampling factors");
-				return (0);
-			}
-		}
-	} else {
-		/* PC 2's single component should have sampling factors 1,1 */
-		if (sp->cinfo.d.comp_info[0].h_samp_factor != 1 ||
-		    sp->cinfo.d.comp_info[0].v_samp_factor != 1) {
-			TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG sampling factors");
-			return (0);
-		}
-	}
-	downsampled_output = FALSE;
-	if (td->td_planarconfig == PLANARCONFIG_CONTIG &&
-	    sp->photometric == PHOTOMETRIC_YCBCR &&
-	    sp->jpegcolormode == JPEGCOLORMODE_RGB) {
-	/* Convert YCbCr to RGB */
-		sp->cinfo.d.jpeg_color_space = JCS_YCbCr;
-		sp->cinfo.d.out_color_space = JCS_RGB;
-	} else {
-			/* Suppress colorspace handling */
-		sp->cinfo.d.jpeg_color_space = JCS_UNKNOWN;
-		sp->cinfo.d.out_color_space = JCS_UNKNOWN;
-		if (td->td_planarconfig == PLANARCONFIG_CONTIG &&
-		    (sp->h_sampling != 1 || sp->v_sampling != 1))
-			downsampled_output = TRUE;
-		/* XXX what about up-sampling? */
-	}
-	if (downsampled_output) {
-		/* Need to use raw-data interface to libjpeg */
-		sp->cinfo.d.raw_data_out = TRUE;
-		tif->tif_decoderow = JPEGDecodeRaw;
-		tif->tif_decodestrip = JPEGDecodeRaw;
-		tif->tif_decodetile = JPEGDecodeRaw;
-	} else {
-		/* Use normal interface to libjpeg */
-		sp->cinfo.d.raw_data_out = FALSE;
-		tif->tif_decoderow = JPEGDecode;
-		tif->tif_decodestrip = JPEGDecode;
-		tif->tif_decodetile = JPEGDecode;
-	}
-	/* Start JPEG decompressor */
-	if (!TIFFjpeg_start_decompress(sp))
-		return (0);
-	/* Allocate downsampled-data buffers if needed */
-	if (downsampled_output) {
-		if (!alloc_downsampled_buffers(tif, sp->cinfo.d.comp_info,
-					       sp->cinfo.d.num_components))
-			return (0);
-		sp->scancount = DCTSIZE;	/* mark buffer empty */
-	}
-	return (1);
-}
-
-/*
- * Decode a chunk of pixels.
- * "Standard" case: returned data is not downsampled.
- */
-/*ARGSUSED*/ static int
-JPEGDecode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s)
-{
-    JPEGState *sp = JState(tif);
-    tsize_t nrows;
-    (void) s;
-
-    nrows = cc / sp->bytesperline;
-    if (cc % sp->bytesperline)
-		TIFFWarningExt(tif->tif_clientdata, tif->tif_name, "fractional scanline not read");
-
-    if( nrows > (int) sp->cinfo.d.image_height )
-        nrows = sp->cinfo.d.image_height;
-
-    /* data is expected to be read in multiples of a scanline */
-    if (nrows)
-    {
-        JSAMPROW line_work_buf = NULL;
-
-        /*
-        ** For 6B, only use temporary buffer for 12 bit imagery. 
-        ** For Mk1 always use it. 
-        */
-#if !defined(JPEG_LIB_MK1)        
-        if( sp->cinfo.d.data_precision == 12 )
-#endif
-        {
-            line_work_buf = (JSAMPROW) 
-                _TIFFmalloc(sizeof(short) * sp->cinfo.d.output_width 
-                            * sp->cinfo.d.num_components );
-        }
-
-        do {
-            if( line_work_buf != NULL )
-            {
-                /* 
-                ** In the MK1 case, we aways read into a 16bit buffer, and then
-                ** pack down to 12bit or 8bit.  In 6B case we only read into 16
-                ** bit buffer for 12bit data, which we need to repack. 
-                */
-                if (TIFFjpeg_read_scanlines(sp, &line_work_buf, 1) != 1)
-                    return (0);
-
-                if( sp->cinfo.d.data_precision == 12 )
-                {
-                    int value_pairs = (sp->cinfo.d.output_width 
-                                       * sp->cinfo.d.num_components) / 2;
-                    int iPair;
-
-                    for( iPair = 0; iPair < value_pairs; iPair++ )
-                    {
-                        unsigned char *out_ptr = 
-                            ((unsigned char *) buf) + iPair * 3;
-                        JSAMPLE *in_ptr = line_work_buf + iPair * 2;
-
-                        out_ptr[0] = (in_ptr[0] & 0xff0) >> 4;
-                        out_ptr[1] = ((in_ptr[0] & 0xf) << 4)
-                            | ((in_ptr[1] & 0xf00) >> 8);
-                        out_ptr[2] = ((in_ptr[1] & 0xff) >> 0);
-                    }
-                }
-                else if( sp->cinfo.d.data_precision == 8 )
-                {
-                    int value_count = (sp->cinfo.d.output_width 
-                                       * sp->cinfo.d.num_components);
-                    int iValue;
-
-                    for( iValue = 0; iValue < value_count; iValue++ )
-                    {
-                        ((unsigned char *) buf)[iValue] = 
-                            line_work_buf[iValue] & 0xff;
-                    }
-                }
-            }
-            else
-            {
-                /*
-                ** In the libjpeg6b 8bit case.  We read directly into the 
-                ** TIFF buffer.
-                */
-                JSAMPROW bufptr = (JSAMPROW)buf;
-  
-                if (TIFFjpeg_read_scanlines(sp, &bufptr, 1) != 1)
-                    return (0);
-            }
-
-            ++tif->tif_row;
-            buf += sp->bytesperline;
-            cc -= sp->bytesperline;
-        } while (--nrows > 0);
-
-        if( line_work_buf != NULL )
-            _TIFFfree( line_work_buf );
-    }
-
-    /* Close down the decompressor if we've finished the strip or tile. */
-    return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height
-        || TIFFjpeg_finish_decompress(sp);
-}
-
-/*
- * Decode a chunk of pixels.
- * Returned data is downsampled per sampling factors.
- */
-/*ARGSUSED*/ static int
-JPEGDecodeRaw(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s)
-{
-	JPEGState *sp = JState(tif);
-	tsize_t nrows;
-	(void) s;
-
-    nrows = cc / sp->bytesperline;
-    if (cc % sp->bytesperline)
-		TIFFWarningExt(tif->tif_clientdata, tif->tif_name, "fractional scanline not read");
-
-    if( nrows > (int) sp->cinfo.d.image_height )
-        nrows = sp->cinfo.d.image_height;
-
-    /* data is expected to be read in multiples of a scanline */
-    if (nrows) {
-		/* Cb,Cr both have sampling factors 1, so this is correct */
-		JDIMENSION clumps_per_line = sp->cinfo.d.comp_info[1].downsampled_width;            
-		int samples_per_clump = sp->samplesperclump;
-
-#ifdef JPEG_LIB_MK1
-		unsigned short* tmpbuf = _TIFFmalloc(sizeof(unsigned short) *
-		    sp->cinfo.d.output_width *
-		    sp->cinfo.d.num_components);
-#endif
-
-		do {
-			jpeg_component_info *compptr;
-			int ci, clumpoffset;
-
-			/* Reload downsampled-data buffer if needed */
-			if (sp->scancount >= DCTSIZE) {
-				int n = sp->cinfo.d.max_v_samp_factor * DCTSIZE;
-				if (TIFFjpeg_read_raw_data(sp, sp->ds_buffer, n) != n)
-					return (0);
-				sp->scancount = 0;
-			}
-			/*
-			 * Fastest way to unseparate data is to make one pass
-			 * over the scanline for each row of each component.
-			 */
-			clumpoffset = 0;    /* first sample in clump */
-			for (ci = 0, compptr = sp->cinfo.d.comp_info;
-			    ci < sp->cinfo.d.num_components;
-			    ci++, compptr++) {
-				int hsamp = compptr->h_samp_factor;
-				int vsamp = compptr->v_samp_factor;
-				int ypos;
-
-				for (ypos = 0; ypos < vsamp; ypos++) {
-					JSAMPLE *inptr = sp->ds_buffer[ci][sp->scancount*vsamp + ypos];
-#ifdef JPEG_LIB_MK1
-					JSAMPLE *outptr = (JSAMPLE*)tmpbuf + clumpoffset;
-#else
-					JSAMPLE *outptr = (JSAMPLE*)buf + clumpoffset;
-#endif
-					JDIMENSION nclump;
-
-					if (hsamp == 1) {
-						/* fast path for at least Cb and Cr */
-						for (nclump = clumps_per_line; nclump-- > 0; ) {
-							outptr[0] = *inptr++;
-							outptr += samples_per_clump;
-						}
-					} else {
-						int xpos;
-
-			/* general case */
-						for (nclump = clumps_per_line; nclump-- > 0; ) {
-							for (xpos = 0; xpos < hsamp; xpos++)
-								outptr[xpos] = *inptr++;
-							outptr += samples_per_clump;
-						}
-					}
-					clumpoffset += hsamp;
-				}
-			}
-
-#ifdef JPEG_LIB_MK1
-			{
-				if (sp->cinfo.d.data_precision == 8)
-				{
-					int i=0;
-					int len = sp->cinfo.d.output_width * sp->cinfo.d.num_components;
-					for (i=0; i<len; i++)
-					{
-						((unsigned char*)buf)[i] = tmpbuf[i] & 0xff;
-					}
-				}
-				else
-				{         /* 12-bit  */
-					int value_pairs = (sp->cinfo.d.output_width
-					    * sp->cinfo.d.num_components) / 2;
-					int iPair;
-					for( iPair = 0; iPair < value_pairs; iPair++ )
-					{
-						unsigned char *out_ptr = ((unsigned char *) buf) + iPair * 3;
-						JSAMPLE *in_ptr = tmpbuf + iPair * 2;
-						out_ptr[0] = (in_ptr[0] & 0xff0) >> 4;
-						out_ptr[1] = ((in_ptr[0] & 0xf) << 4)
-						    | ((in_ptr[1] & 0xf00) >> 8);
-						out_ptr[2] = ((in_ptr[1] & 0xff) >> 0);
-					}
-				}
-			}
-#endif
-
-			sp->scancount ++;
-			tif->tif_row += sp->v_sampling;
-			/* increment/decrement of buf and cc is still incorrect, but should not matter
-			 * TODO: resolve this */
-			buf += sp->bytesperline;
-			cc -= sp->bytesperline;
-		} while (--nrows > 0);
-
-#ifdef JPEG_LIB_MK1
-		_TIFFfree(tmpbuf);
-#endif
-
-	}
-
-	/* Close down the decompressor if done. */
-	return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height
-	    || TIFFjpeg_finish_decompress(sp);
-}
-
-
-/*
- * JPEG Encoding.
- */
-
-static void
-unsuppress_quant_table (JPEGState* sp, int tblno)
-{
-	JQUANT_TBL* qtbl;
-
-	if ((qtbl = sp->cinfo.c.quant_tbl_ptrs[tblno]) != NULL)
-		qtbl->sent_table = FALSE;
-}
-
-static void
-unsuppress_huff_table (JPEGState* sp, int tblno)
-{
-	JHUFF_TBL* htbl;
-
-	if ((htbl = sp->cinfo.c.dc_huff_tbl_ptrs[tblno]) != NULL)
-		htbl->sent_table = FALSE;
-	if ((htbl = sp->cinfo.c.ac_huff_tbl_ptrs[tblno]) != NULL)
-		htbl->sent_table = FALSE;
-}
-
-static int
-prepare_JPEGTables(TIFF* tif)
-{
-	JPEGState* sp = JState(tif);
-
-        JPEGInitializeLibJPEG( tif, 0, 0 );
-
-	/* Initialize quant tables for current quality setting */
-	if (!TIFFjpeg_set_quality(sp, sp->jpegquality, FALSE))
-		return (0);
-	/* Mark only the tables we want for output */
-	/* NB: chrominance tables are currently used only with YCbCr */
-	if (!TIFFjpeg_suppress_tables(sp, TRUE))
-		return (0);
-	if (sp->jpegtablesmode & JPEGTABLESMODE_QUANT) {
-		unsuppress_quant_table(sp, 0);
-		if (sp->photometric == PHOTOMETRIC_YCBCR)
-			unsuppress_quant_table(sp, 1);
-	}
-	if (sp->jpegtablesmode & JPEGTABLESMODE_HUFF) {
-		unsuppress_huff_table(sp, 0);
-		if (sp->photometric == PHOTOMETRIC_YCBCR)
-			unsuppress_huff_table(sp, 1);
-	}
-	/* Direct libjpeg output into jpegtables */
-	if (!TIFFjpeg_tables_dest(sp, tif))
-		return (0);
-	/* Emit tables-only datastream */
-	if (!TIFFjpeg_write_tables(sp))
-		return (0);
-
-	return (1);
-}
-
-static int
-JPEGSetupEncode(TIFF* tif)
-{
-	JPEGState* sp = JState(tif);
-	TIFFDirectory *td = &tif->tif_dir;
-	static const char module[] = "JPEGSetupEncode";
-
-        JPEGInitializeLibJPEG( tif, 1, 0 );
-
-	assert(sp != NULL);
-	assert(!sp->cinfo.comm.is_decompressor);
-
-	/*
-	 * Initialize all JPEG parameters to default values.
-	 * Note that jpeg_set_defaults needs legal values for
-	 * in_color_space and input_components.
-	 */
-	sp->cinfo.c.in_color_space = JCS_UNKNOWN;
-	sp->cinfo.c.input_components = 1;
-	if (!TIFFjpeg_set_defaults(sp))
-		return (0);
-	/* Set per-file parameters */
-	sp->photometric = td->td_photometric;
-	switch (sp->photometric) {
-	case PHOTOMETRIC_YCBCR:
-		sp->h_sampling = td->td_ycbcrsubsampling[0];
-		sp->v_sampling = td->td_ycbcrsubsampling[1];
-		/*
-		 * A ReferenceBlackWhite field *must* be present since the
-		 * default value is inappropriate for YCbCr.  Fill in the
-		 * proper value if application didn't set it.
-		 */
-		{
-			float *ref;
-			if (!TIFFGetField(tif, TIFFTAG_REFERENCEBLACKWHITE,
-					  &ref)) {
-				float refbw[6];
-				long top = 1L << td->td_bitspersample;
-				refbw[0] = 0;
-				refbw[1] = (float)(top-1L);
-				refbw[2] = (float)(top>>1);
-				refbw[3] = refbw[1];
-				refbw[4] = refbw[2];
-				refbw[5] = refbw[1];
-				TIFFSetField(tif, TIFFTAG_REFERENCEBLACKWHITE,
-					     refbw);
-			}
-		}
-		break;
-	case PHOTOMETRIC_PALETTE:		/* disallowed by Tech Note */
-	case PHOTOMETRIC_MASK:
-		TIFFErrorExt(tif->tif_clientdata, module,
-			  "PhotometricInterpretation %d not allowed for JPEG",
-			  (int) sp->photometric);
-		return (0);
-	default:
-		/* TIFF 6.0 forbids subsampling of all other color spaces */
-		sp->h_sampling = 1;
-		sp->v_sampling = 1;
-		break;
-	}
-
-	/* Verify miscellaneous parameters */
-
-	/*
-	 * This would need work if libtiff ever supports different
-	 * depths for different components, or if libjpeg ever supports
-	 * run-time selection of depth.  Neither is imminent.
-	 */
-#ifdef JPEG_LIB_MK1
-        /* BITS_IN_JSAMPLE now permits 8 and 12 --- dgilbert */
-	if (td->td_bitspersample != 8 && td->td_bitspersample != 12) 
-#else
-	if (td->td_bitspersample != BITS_IN_JSAMPLE )
-#endif
-	{
-		TIFFErrorExt(tif->tif_clientdata, module, "BitsPerSample %d not allowed for JPEG",
-			  (int) td->td_bitspersample);
-		return (0);
-	}
-	sp->cinfo.c.data_precision = td->td_bitspersample;
-#ifdef JPEG_LIB_MK1
-        sp->cinfo.c.bits_in_jsample = td->td_bitspersample;
-#endif
-	if (isTiled(tif)) {
-		if ((td->td_tilelength % (sp->v_sampling * DCTSIZE)) != 0) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-				  "JPEG tile height must be multiple of %d",
-				  sp->v_sampling * DCTSIZE);
-			return (0);
-		}
-		if ((td->td_tilewidth % (sp->h_sampling * DCTSIZE)) != 0) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-				  "JPEG tile width must be multiple of %d",
-				  sp->h_sampling * DCTSIZE);
-			return (0);
-		}
-	} else {
-		if (td->td_rowsperstrip < td->td_imagelength &&
-		    (td->td_rowsperstrip % (sp->v_sampling * DCTSIZE)) != 0) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-				  "RowsPerStrip must be multiple of %d for JPEG",
-				  sp->v_sampling * DCTSIZE);
-			return (0);
-		}
-	}
-
-	/* Create a JPEGTables field if appropriate */
-	if (sp->jpegtablesmode & (JPEGTABLESMODE_QUANT|JPEGTABLESMODE_HUFF)) {
-                if( sp->jpegtables == NULL
-                    || memcmp(sp->jpegtables,"\0\0\0\0\0\0\0\0\0",8) == 0 )
-                {
-                        if (!prepare_JPEGTables(tif))
-                                return (0);
-                        /* Mark the field present */
-                        /* Can't use TIFFSetField since BEENWRITING is already set! */
-                        tif->tif_flags |= TIFF_DIRTYDIRECT;
-                        TIFFSetFieldBit(tif, FIELD_JPEGTABLES);
-                }
-	} else {
-		/* We do not support application-supplied JPEGTables, */
-		/* so mark the field not present */
-		TIFFClrFieldBit(tif, FIELD_JPEGTABLES);
-	}
-
-	/* Direct libjpeg output to libtiff's output buffer */
-	TIFFjpeg_data_dest(sp, tif);
-
-	return (1);
-}
-
-/*
- * Set encoding state at the start of a strip or tile.
- */
-static int
-JPEGPreEncode(TIFF* tif, tsample_t s)
-{
-	JPEGState *sp = JState(tif);
-	TIFFDirectory *td = &tif->tif_dir;
-	static const char module[] = "JPEGPreEncode";
-	uint32 segment_width, segment_height;
-	int downsampled_input;
-
-	assert(sp != NULL);
-	assert(!sp->cinfo.comm.is_decompressor);
-	/*
-	 * Set encoding parameters for this strip/tile.
-	 */
-	if (isTiled(tif)) {
-		segment_width = td->td_tilewidth;
-		segment_height = td->td_tilelength;
-		sp->bytesperline = TIFFTileRowSize(tif);
-	} else {
-		segment_width = td->td_imagewidth;
-		segment_height = td->td_imagelength - tif->tif_row;
-		if (segment_height > td->td_rowsperstrip)
-			segment_height = td->td_rowsperstrip;
-		sp->bytesperline = TIFFOldScanlineSize(tif);
-	}
-	if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0) {
-		/* for PC 2, scale down the strip/tile size
-		 * to match a downsampled component
-		 */
-		segment_width = TIFFhowmany(segment_width, sp->h_sampling);
-		segment_height = TIFFhowmany(segment_height, sp->v_sampling);
-	}
-	if (segment_width > 65535 || segment_height > 65535) {
-		TIFFErrorExt(tif->tif_clientdata, module, "Strip/tile too large for JPEG");
-		return (0);
-	}
-	sp->cinfo.c.image_width = segment_width;
-	sp->cinfo.c.image_height = segment_height;
-	downsampled_input = FALSE;
-	if (td->td_planarconfig == PLANARCONFIG_CONTIG) {
-		sp->cinfo.c.input_components = td->td_samplesperpixel;
-		if (sp->photometric == PHOTOMETRIC_YCBCR) {
-			if (sp->jpegcolormode == JPEGCOLORMODE_RGB) {
-				sp->cinfo.c.in_color_space = JCS_RGB;
-			} else {
-				sp->cinfo.c.in_color_space = JCS_YCbCr;
-				if (sp->h_sampling != 1 || sp->v_sampling != 1)
-					downsampled_input = TRUE;
-			}
-			if (!TIFFjpeg_set_colorspace(sp, JCS_YCbCr))
-				return (0);
-			/*
-			 * Set Y sampling factors;
-			 * we assume jpeg_set_colorspace() set the rest to 1
-			 */
-			sp->cinfo.c.comp_info[0].h_samp_factor = sp->h_sampling;
-			sp->cinfo.c.comp_info[0].v_samp_factor = sp->v_sampling;
-		} else {
-			if ((td->td_photometric == PHOTOMETRIC_MINISWHITE || td->td_photometric == PHOTOMETRIC_MINISBLACK) && td->td_samplesperpixel == 1)
-				sp->cinfo.c.in_color_space = JCS_GRAYSCALE;
-			else if (td->td_photometric == PHOTOMETRIC_RGB)
-				sp->cinfo.c.in_color_space = JCS_RGB;
-			else if (td->td_photometric == PHOTOMETRIC_SEPARATED && td->td_samplesperpixel == 4)
-				sp->cinfo.c.in_color_space = JCS_CMYK;
-			else
-				sp->cinfo.c.in_color_space = JCS_UNKNOWN;
-			if (!TIFFjpeg_set_colorspace(sp, sp->cinfo.c.in_color_space))
-				return (0);
-			/* jpeg_set_colorspace set all sampling factors to 1 */
-		}
-	} else {
-		sp->cinfo.c.input_components = 1;
-		sp->cinfo.c.in_color_space = JCS_UNKNOWN;
-		if (!TIFFjpeg_set_colorspace(sp, JCS_UNKNOWN))
-			return (0);
-		sp->cinfo.c.comp_info[0].component_id = s;
-		/* jpeg_set_colorspace() set sampling factors to 1 */
-		if (sp->photometric == PHOTOMETRIC_YCBCR && s > 0) {
-			sp->cinfo.c.comp_info[0].quant_tbl_no = 1;
-			sp->cinfo.c.comp_info[0].dc_tbl_no = 1;
-			sp->cinfo.c.comp_info[0].ac_tbl_no = 1;
-		}
-	}
-	/* ensure libjpeg won't write any extraneous markers */
-	sp->cinfo.c.write_JFIF_header = FALSE;
-	sp->cinfo.c.write_Adobe_marker = FALSE;
-	/* set up table handling correctly */
-        if (!TIFFjpeg_set_quality(sp, sp->jpegquality, FALSE))
-                return (0);
-	if (! (sp->jpegtablesmode & JPEGTABLESMODE_QUANT)) {
-		unsuppress_quant_table(sp, 0);
-		unsuppress_quant_table(sp, 1);
-	}
-	if (sp->jpegtablesmode & JPEGTABLESMODE_HUFF)
-		sp->cinfo.c.optimize_coding = FALSE;
-	else
-		sp->cinfo.c.optimize_coding = TRUE;
-	if (downsampled_input) {
-		/* Need to use raw-data interface to libjpeg */
-		sp->cinfo.c.raw_data_in = TRUE;
-		tif->tif_encoderow = JPEGEncodeRaw;
-		tif->tif_encodestrip = JPEGEncodeRaw;
-		tif->tif_encodetile = JPEGEncodeRaw;
-	} else {
-		/* Use normal interface to libjpeg */
-		sp->cinfo.c.raw_data_in = FALSE;
-		tif->tif_encoderow = JPEGEncode;
-		tif->tif_encodestrip = JPEGEncode;
-		tif->tif_encodetile = JPEGEncode;
-	}
-	/* Start JPEG compressor */
-	if (!TIFFjpeg_start_compress(sp, FALSE))
-		return (0);
-	/* Allocate downsampled-data buffers if needed */
-	if (downsampled_input) {
-		if (!alloc_downsampled_buffers(tif, sp->cinfo.c.comp_info,
-					       sp->cinfo.c.num_components))
-			return (0);
-	}
-	sp->scancount = 0;
-
-	return (1);
-}
-
-/*
- * Encode a chunk of pixels.
- * "Standard" case: incoming data is not downsampled.
- */
-static int
-JPEGEncode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s)
-{
-	JPEGState *sp = JState(tif);
-	tsize_t nrows;
-	JSAMPROW bufptr[1];
-
-	(void) s;
-	assert(sp != NULL);
-	/* data is expected to be supplied in multiples of a scanline */
-	nrows = cc / sp->bytesperline;
-	if (cc % sp->bytesperline)
-		TIFFWarningExt(tif->tif_clientdata, tif->tif_name, "fractional scanline discarded");
-
-        /* The last strip will be limited to image size */
-        if( !isTiled(tif) && tif->tif_row+nrows > tif->tif_dir.td_imagelength )
-            nrows = tif->tif_dir.td_imagelength - tif->tif_row;
-
-	while (nrows-- > 0) {
-		bufptr[0] = (JSAMPROW) buf;
-		if (TIFFjpeg_write_scanlines(sp, bufptr, 1) != 1)
-			return (0);
-		if (nrows > 0)
-			tif->tif_row++;
-		buf += sp->bytesperline;
-	}
-	return (1);
-}
-
-/*
- * Encode a chunk of pixels.
- * Incoming data is expected to be downsampled per sampling factors.
- */
-static int
-JPEGEncodeRaw(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s)
-{
-	JPEGState *sp = JState(tif);
-	JSAMPLE* inptr;
-	JSAMPLE* outptr;
-	tsize_t nrows;
-	JDIMENSION clumps_per_line, nclump;
-	int clumpoffset, ci, xpos, ypos;
-	jpeg_component_info* compptr;
-	int samples_per_clump = sp->samplesperclump;
-	tsize_t bytesperclumpline;
-
-	(void) s;
-	assert(sp != NULL);
-	/* data is expected to be supplied in multiples of a clumpline */
-	/* a clumpline is equivalent to v_sampling desubsampled scanlines */
-	/* TODO: the following calculation of bytesperclumpline, should substitute calculation of sp->bytesperline, except that it is per v_sampling lines */
-	bytesperclumpline = (((sp->cinfo.c.image_width+sp->h_sampling-1)/sp->h_sampling)
-			     *(sp->h_sampling*sp->v_sampling+2)*sp->cinfo.c.data_precision+7)
-			    /8;
-
-	nrows = ( cc / bytesperclumpline ) * sp->v_sampling;
-	if (cc % bytesperclumpline)
-		TIFFWarningExt(tif->tif_clientdata, tif->tif_name, "fractional scanline discarded");
-
-	/* Cb,Cr both have sampling factors 1, so this is correct */
-	clumps_per_line = sp->cinfo.c.comp_info[1].downsampled_width;
-
-	while (nrows > 0) {
-		/*
-		 * Fastest way to separate the data is to make one pass
-		 * over the scanline for each row of each component.
-		 */
-		clumpoffset = 0;		/* first sample in clump */
-		for (ci = 0, compptr = sp->cinfo.c.comp_info;
-		     ci < sp->cinfo.c.num_components;
-		     ci++, compptr++) {
-		    int hsamp = compptr->h_samp_factor;
-		    int vsamp = compptr->v_samp_factor;
-		    int padding = (int) (compptr->width_in_blocks * DCTSIZE -
-					 clumps_per_line * hsamp);
-		    for (ypos = 0; ypos < vsamp; ypos++) {
-			inptr = ((JSAMPLE*) buf) + clumpoffset;
-			outptr = sp->ds_buffer[ci][sp->scancount*vsamp + ypos];
-			if (hsamp == 1) {
-			    /* fast path for at least Cb and Cr */
-			    for (nclump = clumps_per_line; nclump-- > 0; ) {
-				*outptr++ = inptr[0];
-				inptr += samples_per_clump;
-			    }
-			} else {
-			    /* general case */
-			    for (nclump = clumps_per_line; nclump-- > 0; ) {
-				for (xpos = 0; xpos < hsamp; xpos++)
-				    *outptr++ = inptr[xpos];
-				inptr += samples_per_clump;
-			    }
-			}
-			/* pad each scanline as needed */
-			for (xpos = 0; xpos < padding; xpos++) {
-			    *outptr = outptr[-1];
-			    outptr++;
-			}
-			clumpoffset += hsamp;
-		    }
-		}
-		sp->scancount++;
-		if (sp->scancount >= DCTSIZE) {
-			int n = sp->cinfo.c.max_v_samp_factor * DCTSIZE;
-			if (TIFFjpeg_write_raw_data(sp, sp->ds_buffer, n) != n)
-				return (0);
-			sp->scancount = 0;
-		}
-		tif->tif_row += sp->v_sampling;
-		buf += bytesperclumpline;
-		nrows -= sp->v_sampling;
-	}
-	return (1);
-}
-
-/*
- * Finish up at the end of a strip or tile.
- */
-static int
-JPEGPostEncode(TIFF* tif)
-{
-	JPEGState *sp = JState(tif);
-
-	if (sp->scancount > 0) {
-		/*
-		 * Need to emit a partial bufferload of downsampled data.
-		 * Pad the data vertically.
-		 */
-		int ci, ypos, n;
-		jpeg_component_info* compptr;
-
-		for (ci = 0, compptr = sp->cinfo.c.comp_info;
-		     ci < sp->cinfo.c.num_components;
-		     ci++, compptr++) {
-			int vsamp = compptr->v_samp_factor;
-			tsize_t row_width = compptr->width_in_blocks * DCTSIZE
-				* sizeof(JSAMPLE);
-			for (ypos = sp->scancount * vsamp;
-			     ypos < DCTSIZE * vsamp; ypos++) {
-				_TIFFmemcpy((tdata_t)sp->ds_buffer[ci][ypos],
-					    (tdata_t)sp->ds_buffer[ci][ypos-1],
-					    row_width);
-
-			}
-		}
-		n = sp->cinfo.c.max_v_samp_factor * DCTSIZE;
-		if (TIFFjpeg_write_raw_data(sp, sp->ds_buffer, n) != n)
-			return (0);
-	}
-
-	return (TIFFjpeg_finish_compress(JState(tif)));
-}
-
-static void
-JPEGCleanup(TIFF* tif)
-{
-	JPEGState *sp = JState(tif);
-	
-	assert(sp != 0);
-
-	tif->tif_tagmethods.vgetfield = sp->vgetparent;
-	tif->tif_tagmethods.vsetfield = sp->vsetparent;
-	tif->tif_tagmethods.printdir = sp->printdir;
-
-	if( sp->cinfo_initialized )
-	    TIFFjpeg_destroy(sp);	/* release libjpeg resources */
-	if (sp->jpegtables)		/* tag value */
-		_TIFFfree(sp->jpegtables);
-	_TIFFfree(tif->tif_data);	/* release local state */
-	tif->tif_data = NULL;
-
-	_TIFFSetDefaultCompressionState(tif);
-}
-
-static void 
-JPEGResetUpsampled( TIFF* tif )
-{
-	JPEGState* sp = JState(tif);
-	TIFFDirectory* td = &tif->tif_dir;
-
-	/*
-	 * Mark whether returned data is up-sampled or not so TIFFStripSize
-	 * and TIFFTileSize return values that reflect the true amount of
-	 * data.
-	 */
-	tif->tif_flags &= ~TIFF_UPSAMPLED;
-	if (td->td_planarconfig == PLANARCONFIG_CONTIG) {
-		if (td->td_photometric == PHOTOMETRIC_YCBCR &&
-		    sp->jpegcolormode == JPEGCOLORMODE_RGB) {
-			tif->tif_flags |= TIFF_UPSAMPLED;
-		} else {
-#ifdef notdef
-			if (td->td_ycbcrsubsampling[0] != 1 ||
-			    td->td_ycbcrsubsampling[1] != 1)
-				; /* XXX what about up-sampling? */
-#endif
-		}
-	}
-
-	/*
-	 * Must recalculate cached tile size in case sampling state changed.
-	 * Should we really be doing this now if image size isn't set? 
-	 */
-        if( tif->tif_tilesize > 0 )
-            tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tsize_t) -1;
-
-        if(tif->tif_scanlinesize > 0 )
-            tif->tif_scanlinesize = TIFFScanlineSize(tif); 
-}
-
-static int
-JPEGVSetField(TIFF* tif, ttag_t tag, va_list ap)
-{
-	JPEGState* sp = JState(tif);
-	const TIFFFieldInfo* fip;
-	uint32 v32;
-
-	assert(sp != NULL);
-
-	switch (tag) {
-	case TIFFTAG_JPEGTABLES:
-		v32 = va_arg(ap, uint32);
-		if (v32 == 0) {
-			/* XXX */
-			return (0);
-		}
-		_TIFFsetByteArray(&sp->jpegtables, va_arg(ap, void*),
-		    (long) v32);
-		sp->jpegtables_length = v32;
-		TIFFSetFieldBit(tif, FIELD_JPEGTABLES);
-		break;
-	case TIFFTAG_JPEGQUALITY:
-		sp->jpegquality = va_arg(ap, int);
-		return (1);			/* pseudo tag */
-	case TIFFTAG_JPEGCOLORMODE:
-		sp->jpegcolormode = va_arg(ap, int);
-                JPEGResetUpsampled( tif );
-		return (1);			/* pseudo tag */
-	case TIFFTAG_PHOTOMETRIC:
-        {
-                int ret_value = (*sp->vsetparent)(tif, tag, ap);
-                JPEGResetUpsampled( tif );
-                return ret_value;
-        }
-	case TIFFTAG_JPEGTABLESMODE:
-		sp->jpegtablesmode = va_arg(ap, int);
-		return (1);			/* pseudo tag */
-	case TIFFTAG_YCBCRSUBSAMPLING:
-                /* mark the fact that we have a real ycbcrsubsampling! */
-		sp->ycbcrsampling_fetched = 1;
-                /* should we be recomputing upsampling info here? */
-		return (*sp->vsetparent)(tif, tag, ap);
-	case TIFFTAG_FAXRECVPARAMS:
-		sp->recvparams = va_arg(ap, uint32);
-		break;
-	case TIFFTAG_FAXSUBADDRESS:
-		_TIFFsetString(&sp->subaddress, va_arg(ap, char*));
-		break;
-	case TIFFTAG_FAXRECVTIME:
-		sp->recvtime = va_arg(ap, uint32);
-		break;
-	case TIFFTAG_FAXDCS:
-		_TIFFsetString(&sp->faxdcs, va_arg(ap, char*));
-		break;
-	default:
-		return (*sp->vsetparent)(tif, tag, ap);
-	}
-
-	if ((fip = _TIFFFieldWithTag(tif, tag))) {
-		TIFFSetFieldBit(tif, fip->field_bit);
-	} else {
-		return (0);
-	}
-
-	tif->tif_flags |= TIFF_DIRTYDIRECT;
-	return (1);
-}
-
-/*
- * Some JPEG-in-TIFF produces do not emit the YCBCRSUBSAMPLING values in
- * the TIFF tags, but still use non-default (2,2) values within the jpeg
- * data stream itself.  In order for TIFF applications to work properly
- * - for instance to get the strip buffer size right - it is imperative
- * that the subsampling be available before we start reading the image
- * data normally.  This function will attempt to load the first strip in
- * order to get the sampling values from the jpeg data stream.  Various
- * hacks are various places are done to ensure this function gets called
- * before the td_ycbcrsubsampling values are used from the directory structure,
- * including calling TIFFGetField() for the YCBCRSUBSAMPLING field from 
- * TIFFStripSize(), and the printing code in tif_print.c. 
- *
- * Note that JPEGPreDeocode() will produce a fairly loud warning when the
- * discovered sampling does not match the default sampling (2,2) or whatever
- * was actually in the tiff tags. 
- *
- * Problems:
- *  o This code will cause one whole strip/tile of compressed data to be
- *    loaded just to get the tags right, even if the imagery is never read.
- *    It would be more efficient to just load a bit of the header, and
- *    initialize things from that. 
- *
- * See the bug in bugzilla for details:
- *
- * http://bugzilla.remotesensing.org/show_bug.cgi?id=168
- *
- * Frank Warmerdam, July 2002
- */
-
-static void 
-JPEGFixupTestSubsampling( TIFF * tif )
-{
-#ifdef CHECK_JPEG_YCBCR_SUBSAMPLING
-    JPEGState *sp = JState(tif);
-    TIFFDirectory *td = &tif->tif_dir;
-
-    JPEGInitializeLibJPEG( tif, 0, 0 );
-
-    /*
-     * Some JPEG-in-TIFF files don't provide the ycbcrsampling tags, 
-     * and use a sampling schema other than the default 2,2.  To handle
-     * this we actually have to scan the header of a strip or tile of
-     * jpeg data to get the sampling.  
-     */
-    if( !sp->cinfo.comm.is_decompressor 
-        || sp->ycbcrsampling_fetched  
-        || td->td_photometric != PHOTOMETRIC_YCBCR )
-        return;
-
-    sp->ycbcrsampling_fetched = 1;
-    if( TIFFIsTiled( tif ) )
-    {
-        if( !TIFFFillTile( tif, 0 ) )
-			return;
-    }
-    else
-    {
-        if( !TIFFFillStrip( tif, 0 ) )
-            return;
-    }
-
-    TIFFSetField( tif, TIFFTAG_YCBCRSUBSAMPLING, 
-                  (uint16) sp->h_sampling, (uint16) sp->v_sampling );
-
-    /*
-    ** We want to clear the loaded strip so the application has time
-    ** to set JPEGCOLORMODE or other behavior modifiers.  This essentially
-    ** undoes the JPEGPreDecode triggers by TIFFFileStrip().  (#1936)
-    */
-    tif->tif_curstrip = -1;
-
-#endif /* CHECK_JPEG_YCBCR_SUBSAMPLING */
-}
-
-static int
-JPEGVGetField(TIFF* tif, ttag_t tag, va_list ap)
-{
-	JPEGState* sp = JState(tif);
-
-	assert(sp != NULL);
-
-	switch (tag) {
-		case TIFFTAG_JPEGTABLES:
-			*va_arg(ap, uint32*) = sp->jpegtables_length;
-			*va_arg(ap, void**) = sp->jpegtables;
-			break;
-		case TIFFTAG_JPEGQUALITY:
-			*va_arg(ap, int*) = sp->jpegquality;
-			break;
-		case TIFFTAG_JPEGCOLORMODE:
-			*va_arg(ap, int*) = sp->jpegcolormode;
-			break;
-		case TIFFTAG_JPEGTABLESMODE:
-			*va_arg(ap, int*) = sp->jpegtablesmode;
-			break;
-		case TIFFTAG_YCBCRSUBSAMPLING:
-			JPEGFixupTestSubsampling( tif );
-			return (*sp->vgetparent)(tif, tag, ap);
-		case TIFFTAG_FAXRECVPARAMS:
-			*va_arg(ap, uint32*) = sp->recvparams;
-			break;
-		case TIFFTAG_FAXSUBADDRESS:
-			*va_arg(ap, char**) = sp->subaddress;
-			break;
-		case TIFFTAG_FAXRECVTIME:
-			*va_arg(ap, uint32*) = sp->recvtime;
-			break;
-		case TIFFTAG_FAXDCS:
-			*va_arg(ap, char**) = sp->faxdcs;
-			break;
-		default:
-			return (*sp->vgetparent)(tif, tag, ap);
-	}
-	return (1);
-}
-
-static void
-JPEGPrintDir(TIFF* tif, FILE* fd, long flags)
-{
-	JPEGState* sp = JState(tif);
-
-	assert(sp != NULL);
-
-	(void) flags;
-	if (TIFFFieldSet(tif,FIELD_JPEGTABLES))
-		fprintf(fd, "  JPEG Tables: (%lu bytes)\n",
-			(unsigned long) sp->jpegtables_length);
-        if (TIFFFieldSet(tif,FIELD_RECVPARAMS))
-                fprintf(fd, "  Fax Receive Parameters: %08lx\n",
-                   (unsigned long) sp->recvparams);
-        if (TIFFFieldSet(tif,FIELD_SUBADDRESS))
-                fprintf(fd, "  Fax SubAddress: %s\n", sp->subaddress);
-        if (TIFFFieldSet(tif,FIELD_RECVTIME))
-                fprintf(fd, "  Fax Receive Time: %lu secs\n",
-                    (unsigned long) sp->recvtime);
-        if (TIFFFieldSet(tif,FIELD_FAXDCS))
-                fprintf(fd, "  Fax DCS: %s\n", sp->faxdcs);
-}
-
-static uint32
-JPEGDefaultStripSize(TIFF* tif, uint32 s)
-{
-	JPEGState* sp = JState(tif);
-	TIFFDirectory *td = &tif->tif_dir;
-
-	s = (*sp->defsparent)(tif, s);
-	if (s < td->td_imagelength)
-		s = TIFFroundup(s, td->td_ycbcrsubsampling[1] * DCTSIZE);
-	return (s);
-}
-
-static void
-JPEGDefaultTileSize(TIFF* tif, uint32* tw, uint32* th)
-{
-	JPEGState* sp = JState(tif);
-	TIFFDirectory *td = &tif->tif_dir;
-
-	(*sp->deftparent)(tif, tw, th);
-	*tw = TIFFroundup(*tw, td->td_ycbcrsubsampling[0] * DCTSIZE);
-	*th = TIFFroundup(*th, td->td_ycbcrsubsampling[1] * DCTSIZE);
-}
-
-/*
- * The JPEG library initialized used to be done in TIFFInitJPEG(), but
- * now that we allow a TIFF file to be opened in update mode it is necessary
- * to have some way of deciding whether compression or decompression is
- * desired other than looking at tif->tif_mode.  We accomplish this by 
- * examining {TILE/STRIP}BYTECOUNTS to see if there is a non-zero entry.
- * If so, we assume decompression is desired. 
- *
- * This is tricky, because TIFFInitJPEG() is called while the directory is
- * being read, and generally speaking the BYTECOUNTS tag won't have been read
- * at that point.  So we try to defer jpeg library initialization till we
- * do have that tag ... basically any access that might require the compressor
- * or decompressor that occurs after the reading of the directory. 
- *
- * In an ideal world compressors or decompressors would be setup
- * at the point where a single tile or strip was accessed (for read or write)
- * so that stuff like update of missing tiles, or replacement of tiles could
- * be done. However, we aren't trying to crack that nut just yet ...
- *
- * NFW, Feb 3rd, 2003.
- */
-
-static int JPEGInitializeLibJPEG( TIFF * tif, int force_encode, int force_decode )
-{
-    JPEGState* sp = JState(tif);
-    uint32 *byte_counts = NULL;
-    int     data_is_empty = TRUE;
-    int     decompress;
-
-
-    if(sp->cinfo_initialized)
-    {
-        if( force_encode && sp->cinfo.comm.is_decompressor )
-            TIFFjpeg_destroy( sp );
-        else if( force_decode && !sp->cinfo.comm.is_decompressor )
-            TIFFjpeg_destroy( sp );
-        else
-            return 1;
-
-        sp->cinfo_initialized = 0;
-    }
-
-    /*
-     * Do we have tile data already?  Make sure we initialize the
-     * the state in decompressor mode if we have tile data, even if we
-     * are not in read-only file access mode. 
-     */
-    if( TIFFIsTiled( tif ) 
-        && TIFFGetField( tif, TIFFTAG_TILEBYTECOUNTS, &byte_counts ) 
-        && byte_counts != NULL )
-    {
-        data_is_empty = byte_counts[0] == 0;
-    }
-    if( !TIFFIsTiled( tif ) 
-        && TIFFGetField( tif, TIFFTAG_STRIPBYTECOUNTS, &byte_counts) 
-        && byte_counts != NULL )
-    {
-        data_is_empty = byte_counts[0] == 0;
-    }
-
-    if( force_decode )
-        decompress = 1;
-    else if( force_encode )
-        decompress = 0;
-    else if( tif->tif_mode == O_RDONLY )
-        decompress = 1;
-    else if( data_is_empty )
-        decompress = 0;
-    else
-        decompress = 1;
-
-    /*
-     * Initialize libjpeg.
-     */
-    if ( decompress ) {
-        if (!TIFFjpeg_create_decompress(sp))
-            return (0);
-
-    } else {
-        if (!TIFFjpeg_create_compress(sp))
-            return (0);
-    }
-
-    sp->cinfo_initialized = TRUE;
-
-    return 1;
-}
-
-int
-TIFFInitJPEG(TIFF* tif, int scheme)
-{
-	JPEGState* sp;
-
-	assert(scheme == COMPRESSION_JPEG);
-
-	/*
-	 * Merge codec-specific tag information.
-	 */
-	if (!_TIFFMergeFieldInfo(tif, jpegFieldInfo, N(jpegFieldInfo))) {
-		TIFFErrorExt(tif->tif_clientdata,
-			     "TIFFInitJPEG",
-			     "Merging JPEG codec-specific tags failed");
-		return 0;
-	}
-
-	/*
-	 * Allocate state block so tag methods have storage to record values.
-	 */
-	tif->tif_data = (tidata_t) _TIFFmalloc(sizeof (JPEGState));
-
-	if (tif->tif_data == NULL) {
-		TIFFErrorExt(tif->tif_clientdata,
-			     "TIFFInitJPEG", "No space for JPEG state block");
-		return 0;
-	}
-        _TIFFmemset(tif->tif_data, 0, sizeof(JPEGState));
-
-	sp = JState(tif);
-	sp->tif = tif;				/* back link */
-
-	/*
-	 * Override parent get/set field methods.
-	 */
-	sp->vgetparent = tif->tif_tagmethods.vgetfield;
-	tif->tif_tagmethods.vgetfield = JPEGVGetField; /* hook for codec tags */
-	sp->vsetparent = tif->tif_tagmethods.vsetfield;
-	tif->tif_tagmethods.vsetfield = JPEGVSetField; /* hook for codec tags */
-	sp->printdir = tif->tif_tagmethods.printdir;
-	tif->tif_tagmethods.printdir = JPEGPrintDir;   /* hook for codec tags */
-
-	/* Default values for codec-specific fields */
-	sp->jpegtables = NULL;
-	sp->jpegtables_length = 0;
-	sp->jpegquality = 75;			/* Default IJG quality */
-	sp->jpegcolormode = JPEGCOLORMODE_RAW;
-	sp->jpegtablesmode = JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF;
-
-        sp->recvparams = 0;
-        sp->subaddress = NULL;
-        sp->faxdcs = NULL;
-
-        sp->ycbcrsampling_fetched = 0;
-
-	/*
-	 * Install codec methods.
-	 */
-	tif->tif_setupdecode = JPEGSetupDecode;
-	tif->tif_predecode = JPEGPreDecode;
-	tif->tif_decoderow = JPEGDecode;
-	tif->tif_decodestrip = JPEGDecode;
-	tif->tif_decodetile = JPEGDecode;
-	tif->tif_setupencode = JPEGSetupEncode;
-	tif->tif_preencode = JPEGPreEncode;
-	tif->tif_postencode = JPEGPostEncode;
-	tif->tif_encoderow = JPEGEncode;
-	tif->tif_encodestrip = JPEGEncode;
-	tif->tif_encodetile = JPEGEncode;
-	tif->tif_cleanup = JPEGCleanup;
-	sp->defsparent = tif->tif_defstripsize;
-	tif->tif_defstripsize = JPEGDefaultStripSize;
-	sp->deftparent = tif->tif_deftilesize;
-	tif->tif_deftilesize = JPEGDefaultTileSize;
-	tif->tif_flags |= TIFF_NOBITREV;	/* no bit reversal, please */
-
-        sp->cinfo_initialized = FALSE;
-
-	/*
-        ** Create a JPEGTables field if no directory has yet been created. 
-        ** We do this just to ensure that sufficient space is reserved for
-        ** the JPEGTables field.  It will be properly created the right
-        ** size later. 
-        */
-        if( tif->tif_diroff == 0 )
-        {
-#define SIZE_OF_JPEGTABLES 2000
-/*
-The following line assumes incorrectly that all JPEG-in-TIFF files will have
-a JPEGTABLES tag generated and causes null-filled JPEGTABLES tags to be written
-when the JPEG data is placed with TIFFWriteRawStrip.  The field bit should be 
-set, anyway, later when actual JPEGTABLES header is generated, so removing it 
-here hopefully is harmless.
-            TIFFSetFieldBit(tif, FIELD_JPEGTABLES);
-*/
-            sp->jpegtables_length = SIZE_OF_JPEGTABLES;
-            sp->jpegtables = (void *) _TIFFmalloc(sp->jpegtables_length);
-	    _TIFFmemset(sp->jpegtables, 0, SIZE_OF_JPEGTABLES);
-#undef SIZE_OF_JPEGTABLES
-        }
-
-        /*
-         * Mark the TIFFTAG_YCBCRSAMPLES as present even if it is not
-         * see: JPEGFixupTestSubsampling().
-         */
-        TIFFSetFieldBit( tif, FIELD_YCBCRSUBSAMPLING );
-
-	return 1;
-}
-#endif /* JPEG_SUPPORT */
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_luv.c b/Source/LibTIFF/tif_luv.c
deleted file mode 100644
index 9874776..0000000
--- a/Source/LibTIFF/tif_luv.c
+++ /dev/null
@@ -1,1629 +0,0 @@
-/* $Id: tif_luv.c,v 1.37 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1997 Greg Ward Larson
- * Copyright (c) 1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler, Greg Larson and Silicon Graphics may not be used in any
- * advertising or publicity relating to the software without the specific,
- * prior written permission of Sam Leffler, Greg Larson and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER, GREG LARSON OR SILICON GRAPHICS BE LIABLE
- * FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-#include "tiffiop.h"
-#ifdef LOGLUV_SUPPORT
-
-/*
- * TIFF Library.
- * LogLuv compression support for high dynamic range images.
- *
- * Contributed by Greg Larson.
- *
- * LogLuv image support uses the TIFF library to store 16 or 10-bit
- * log luminance values with 8 bits each of u and v or a 14-bit index.
- *
- * The codec can take as input and produce as output 32-bit IEEE float values 
- * as well as 16-bit integer values.  A 16-bit luminance is interpreted
- * as a sign bit followed by a 15-bit integer that is converted
- * to and from a linear magnitude using the transformation:
- *
- *	L = 2^( (Le+.5)/256 - 64 )		# real from 15-bit
- *
- *	Le = floor( 256*(log2(L) + 64) )	# 15-bit from real
- *
- * The actual conversion to world luminance units in candelas per sq. meter
- * requires an additional multiplier, which is stored in the TIFFTAG_STONITS.
- * This value is usually set such that a reasonable exposure comes from
- * clamping decoded luminances above 1 to 1 in the displayed image.
- *
- * The 16-bit values for u and v may be converted to real values by dividing
- * each by 32768.  (This allows for negative values, which aren't useful as
- * far as we know, but are left in case of future improvements in human
- * color vision.)
- *
- * Conversion from (u,v), which is actually the CIE (u',v') system for
- * you color scientists, is accomplished by the following transformation:
- *
- *	u = 4*x / (-2*x + 12*y + 3)
- *	v = 9*y / (-2*x + 12*y + 3)
- *
- *	x = 9*u / (6*u - 16*v + 12)
- *	y = 4*v / (6*u - 16*v + 12)
- *
- * This process is greatly simplified by passing 32-bit IEEE floats
- * for each of three CIE XYZ coordinates.  The codec then takes care
- * of conversion to and from LogLuv, though the application is still
- * responsible for interpreting the TIFFTAG_STONITS calibration factor.
- *
- * By definition, a CIE XYZ vector of [1 1 1] corresponds to a neutral white
- * point of (x,y)=(1/3,1/3).  However, most color systems assume some other
- * white point, such as D65, and an absolute color conversion to XYZ then
- * to another color space with a different white point may introduce an
- * unwanted color cast to the image.  It is often desirable, therefore, to
- * perform a white point conversion that maps the input white to [1 1 1]
- * in XYZ, then record the original white point using the TIFFTAG_WHITEPOINT
- * tag value.  A decoder that demands absolute color calibration may use
- * this white point tag to get back the original colors, but usually it
- * will be ignored and the new white point will be used instead that
- * matches the output color space.
- *
- * Pixel information is compressed into one of two basic encodings, depending
- * on the setting of the compression tag, which is one of COMPRESSION_SGILOG
- * or COMPRESSION_SGILOG24.  For COMPRESSION_SGILOG, greyscale data is
- * stored as:
- *
- *	 1       15
- *	|-+---------------|
- *
- * COMPRESSION_SGILOG color data is stored as:
- *
- *	 1       15           8        8
- *	|-+---------------|--------+--------|
- *	 S       Le           ue       ve
- *
- * For the 24-bit COMPRESSION_SGILOG24 color format, the data is stored as:
- *
- *	     10           14
- *	|----------|--------------|
- *	     Le'          Ce
- *
- * There is no sign bit in the 24-bit case, and the (u,v) chromaticity is
- * encoded as an index for optimal color resolution.  The 10 log bits are
- * defined by the following conversions:
- *
- *	L = 2^((Le'+.5)/64 - 12)		# real from 10-bit
- *
- *	Le' = floor( 64*(log2(L) + 12) )	# 10-bit from real
- *
- * The 10 bits of the smaller format may be converted into the 15 bits of
- * the larger format by multiplying by 4 and adding 13314.  Obviously,
- * a smaller range of magnitudes is covered (about 5 orders of magnitude
- * instead of 38), and the lack of a sign bit means that negative luminances
- * are not allowed.  (Well, they aren't allowed in the real world, either,
- * but they are useful for certain types of image processing.)
- *
- * The desired user format is controlled by the setting the internal
- * pseudo tag TIFFTAG_SGILOGDATAFMT to one of:
- *  SGILOGDATAFMT_FLOAT       = IEEE 32-bit float XYZ values
- *  SGILOGDATAFMT_16BIT	      = 16-bit integer encodings of logL, u and v
- * Raw data i/o is also possible using:
- *  SGILOGDATAFMT_RAW         = 32-bit unsigned integer with encoded pixel
- * In addition, the following decoding is provided for ease of display:
- *  SGILOGDATAFMT_8BIT        = 8-bit default RGB gamma-corrected values
- *
- * For grayscale images, we provide the following data formats:
- *  SGILOGDATAFMT_FLOAT       = IEEE 32-bit float Y values
- *  SGILOGDATAFMT_16BIT       = 16-bit integer w/ encoded luminance
- *  SGILOGDATAFMT_8BIT        = 8-bit gray monitor values
- *
- * Note that the COMPRESSION_SGILOG applies a simple run-length encoding
- * scheme by separating the logL, u and v bytes for each row and applying
- * a PackBits type of compression.  Since the 24-bit encoding is not
- * adaptive, the 32-bit color format takes less space in many cases.
- *
- * Further control is provided over the conversion from higher-resolution
- * formats to final encoded values through the pseudo tag
- * TIFFTAG_SGILOGENCODE:
- *  SGILOGENCODE_NODITHER     = do not dither encoded values
- *  SGILOGENCODE_RANDITHER    = apply random dithering during encoding
- *
- * The default value of this tag is SGILOGENCODE_NODITHER for
- * COMPRESSION_SGILOG to maximize run-length encoding and
- * SGILOGENCODE_RANDITHER for COMPRESSION_SGILOG24 to turn
- * quantization errors into noise.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-
-/*
- * State block for each open TIFF
- * file using LogLuv compression/decompression.
- */
-typedef	struct logLuvState LogLuvState;
-
-struct logLuvState {
-	int			user_datafmt;	/* user data format */
-	int			encode_meth;	/* encoding method */
-	int			pixel_size;	/* bytes per pixel */
-
-	tidata_t*		tbuf;		/* translation buffer */
-	int			tbuflen;	/* buffer length */
-	void (*tfunc)(LogLuvState*, tidata_t, int);
-
-	TIFFVSetMethod		vgetparent;	/* super-class method */
-	TIFFVSetMethod		vsetparent;	/* super-class method */
-};
-
-#define	DecoderState(tif)	((LogLuvState*) (tif)->tif_data)
-#define	EncoderState(tif)	((LogLuvState*) (tif)->tif_data)
-
-#define SGILOGDATAFMT_UNKNOWN	-1
-
-#define MINRUN		4	/* minimum run length */
-
-/*
- * Decode a string of 16-bit gray pixels.
- */
-static int
-LogL16Decode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s)
-{
-	LogLuvState* sp = DecoderState(tif);
-	int shft, i, npixels;
-	unsigned char* bp;
-	int16* tp;
-	int16 b;
-	int cc, rc;
-
-	assert(s == 0);
-	assert(sp != NULL);
-
-	npixels = occ / sp->pixel_size;
-
-	if (sp->user_datafmt == SGILOGDATAFMT_16BIT)
-		tp = (int16*) op;
-	else {
-		assert(sp->tbuflen >= npixels);
-		tp = (int16*) sp->tbuf;
-	}
-	_TIFFmemset((tdata_t) tp, 0, npixels*sizeof (tp[0]));
-
-	bp = (unsigned char*) tif->tif_rawcp;
-	cc = tif->tif_rawcc;
-					/* get each byte string */
-	for (shft = 2*8; (shft -= 8) >= 0; ) {
-		for (i = 0; i < npixels && cc > 0; )
-			if (*bp >= 128) {		/* run */
-				rc = *bp++ + (2-128);
-				b = (int16)(*bp++ << shft);
-				cc -= 2;
-				while (rc-- && i < npixels)
-					tp[i++] |= b;
-			} else {			/* non-run */
-				rc = *bp++;		/* nul is noop */
-				while (--cc && rc-- && i < npixels)
-					tp[i++] |= (int16)*bp++ << shft;
-			}
-		if (i != npixels) {
-			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-		"LogL16Decode: Not enough data at row %d (short %d pixels)",
-			    tif->tif_row, npixels - i);
-			tif->tif_rawcp = (tidata_t) bp;
-			tif->tif_rawcc = cc;
-			return (0);
-		}
-	}
-	(*sp->tfunc)(sp, op, npixels);
-	tif->tif_rawcp = (tidata_t) bp;
-	tif->tif_rawcc = cc;
-	return (1);
-}
-
-/*
- * Decode a string of 24-bit pixels.
- */
-static int
-LogLuvDecode24(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s)
-{
-	LogLuvState* sp = DecoderState(tif);
-	int cc, i, npixels;
-	unsigned char* bp;
-	uint32* tp;
-
-	assert(s == 0);
-	assert(sp != NULL);
-
-	npixels = occ / sp->pixel_size;
-
-	if (sp->user_datafmt == SGILOGDATAFMT_RAW)
-		tp = (uint32 *)op;
-	else {
-		assert(sp->tbuflen >= npixels);
-		tp = (uint32 *) sp->tbuf;
-	}
-					/* copy to array of uint32 */
-	bp = (unsigned char*) tif->tif_rawcp;
-	cc = tif->tif_rawcc;
-	for (i = 0; i < npixels && cc > 0; i++) {
-		tp[i] = bp[0] << 16 | bp[1] << 8 | bp[2];
-		bp += 3;
-		cc -= 3;
-	}
-	tif->tif_rawcp = (tidata_t) bp;
-	tif->tif_rawcc = cc;
-	if (i != npixels) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-	    "LogLuvDecode24: Not enough data at row %d (short %d pixels)",
-		    tif->tif_row, npixels - i);
-		return (0);
-	}
-	(*sp->tfunc)(sp, op, npixels);
-	return (1);
-}
-
-/*
- * Decode a string of 32-bit pixels.
- */
-static int
-LogLuvDecode32(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s)
-{
-	LogLuvState* sp;
-	int shft, i, npixels;
-	unsigned char* bp;
-	uint32* tp;
-	uint32 b;
-	int cc, rc;
-
-	assert(s == 0);
-	sp = DecoderState(tif);
-	assert(sp != NULL);
-
-	npixels = occ / sp->pixel_size;
-
-	if (sp->user_datafmt == SGILOGDATAFMT_RAW)
-		tp = (uint32*) op;
-	else {
-		assert(sp->tbuflen >= npixels);
-		tp = (uint32*) sp->tbuf;
-	}
-	_TIFFmemset((tdata_t) tp, 0, npixels*sizeof (tp[0]));
-
-	bp = (unsigned char*) tif->tif_rawcp;
-	cc = tif->tif_rawcc;
-					/* get each byte string */
-	for (shft = 4*8; (shft -= 8) >= 0; ) {
-		for (i = 0; i < npixels && cc > 0; )
-			if (*bp >= 128) {		/* run */
-				rc = *bp++ + (2-128);
-				b = (uint32)*bp++ << shft;
-				cc -= 2;
-				while (rc-- && i < npixels)
-					tp[i++] |= b;
-			} else {			/* non-run */
-				rc = *bp++;		/* nul is noop */
-				while (--cc && rc-- && i < npixels)
-					tp[i++] |= (uint32)*bp++ << shft;
-			}
-		if (i != npixels) {
-			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-		"LogLuvDecode32: Not enough data at row %d (short %d pixels)",
-			    tif->tif_row, npixels - i);
-			tif->tif_rawcp = (tidata_t) bp;
-			tif->tif_rawcc = cc;
-			return (0);
-		}
-	}
-	(*sp->tfunc)(sp, op, npixels);
-	tif->tif_rawcp = (tidata_t) bp;
-	tif->tif_rawcc = cc;
-	return (1);
-}
-
-/*
- * Decode a strip of pixels.  We break it into rows to
- * maintain synchrony with the encode algorithm, which
- * is row by row.
- */
-static int
-LogLuvDecodeStrip(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s)
-{
-	tsize_t rowlen = TIFFScanlineSize(tif);
-
-	assert(cc%rowlen == 0);
-	while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s))
-		bp += rowlen, cc -= rowlen;
-	return (cc == 0);
-}
-
-/*
- * Decode a tile of pixels.  We break it into rows to
- * maintain synchrony with the encode algorithm, which
- * is row by row.
- */
-static int
-LogLuvDecodeTile(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s)
-{
-	tsize_t rowlen = TIFFTileRowSize(tif);
-
-	assert(cc%rowlen == 0);
-	while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s))
-		bp += rowlen, cc -= rowlen;
-	return (cc == 0);
-}
-
-/*
- * Encode a row of 16-bit pixels.
- */
-static int
-LogL16Encode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s)
-{
-	LogLuvState* sp = EncoderState(tif);
-	int shft, i, j, npixels;
-	tidata_t op;
-	int16* tp;
-	int16 b;
-	int occ, rc=0, mask, beg;
-
-	assert(s == 0);
-	assert(sp != NULL);
-	npixels = cc / sp->pixel_size;
-
-	if (sp->user_datafmt == SGILOGDATAFMT_16BIT)
-		tp = (int16*) bp;
-	else {
-		tp = (int16*) sp->tbuf;
-		assert(sp->tbuflen >= npixels);
-		(*sp->tfunc)(sp, bp, npixels);
-	}
-					/* compress each byte string */
-	op = tif->tif_rawcp;
-	occ = tif->tif_rawdatasize - tif->tif_rawcc;
-	for (shft = 2*8; (shft -= 8) >= 0; )
-		for (i = 0; i < npixels; i += rc) {
-			if (occ < 4) {
-				tif->tif_rawcp = op;
-				tif->tif_rawcc = tif->tif_rawdatasize - occ;
-				if (!TIFFFlushData1(tif))
-					return (-1);
-				op = tif->tif_rawcp;
-				occ = tif->tif_rawdatasize - tif->tif_rawcc;
-			}
-			mask = 0xff << shft;		/* find next run */
-			for (beg = i; beg < npixels; beg += rc) {
-				b = (int16) (tp[beg] & mask);
-				rc = 1;
-				while (rc < 127+2 && beg+rc < npixels &&
-						(tp[beg+rc] & mask) == b)
-					rc++;
-				if (rc >= MINRUN)
-					break;		/* long enough */
-			}
-			if (beg-i > 1 && beg-i < MINRUN) {
-				b = (int16) (tp[i] & mask);/*check short run */
-				j = i+1;
-				while ((tp[j++] & mask) == b)
-                                    if (j == beg) {
-                                        *op++ = (tidataval_t)(128-2+j-i);
-                                        *op++ = (tidataval_t) (b >> shft);
-                                        occ -= 2;
-                                        i = beg;
-                                        break;
-                                    }
-			}
-			while (i < beg) {		/* write out non-run */
-				if ((j = beg-i) > 127) j = 127;
-				if (occ < j+3) {
-                                    tif->tif_rawcp = op;
-                                    tif->tif_rawcc = tif->tif_rawdatasize - occ;
-                                    if (!TIFFFlushData1(tif))
-                                        return (-1);
-                                    op = tif->tif_rawcp;
-                                    occ = tif->tif_rawdatasize - tif->tif_rawcc;
-				}
-				*op++ = (tidataval_t) j; occ--;
-				while (j--) {
-					*op++ = (tidataval_t) (tp[i++] >> shft & 0xff);
-					occ--;
-				}
-			}
-			if (rc >= MINRUN) {		/* write out run */
-				*op++ = (tidataval_t) (128-2+rc);
-				*op++ = (tidataval_t) (tp[beg] >> shft & 0xff);
-				occ -= 2;
-			} else
-				rc = 0;
-		}
-	tif->tif_rawcp = op;
-	tif->tif_rawcc = tif->tif_rawdatasize - occ;
-
-	return (1);
-}
-
-/*
- * Encode a row of 24-bit pixels.
- */
-static int
-LogLuvEncode24(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s)
-{
-	LogLuvState* sp = EncoderState(tif);
-	int i, npixels, occ;
-	tidata_t op;
-	uint32* tp;
-
-	assert(s == 0);
-	assert(sp != NULL);
-	npixels = cc / sp->pixel_size;
-
-	if (sp->user_datafmt == SGILOGDATAFMT_RAW)
-		tp = (uint32*) bp;
-	else {
-		tp = (uint32*) sp->tbuf;
-		assert(sp->tbuflen >= npixels);
-		(*sp->tfunc)(sp, bp, npixels);
-	}
-					/* write out encoded pixels */
-	op = tif->tif_rawcp;
-	occ = tif->tif_rawdatasize - tif->tif_rawcc;
-	for (i = npixels; i--; ) {
-		if (occ < 3) {
-			tif->tif_rawcp = op;
-			tif->tif_rawcc = tif->tif_rawdatasize - occ;
-			if (!TIFFFlushData1(tif))
-				return (-1);
-			op = tif->tif_rawcp;
-			occ = tif->tif_rawdatasize - tif->tif_rawcc;
-		}
-		*op++ = (tidataval_t)(*tp >> 16);
-		*op++ = (tidataval_t)(*tp >> 8 & 0xff);
-		*op++ = (tidataval_t)(*tp++ & 0xff);
-		occ -= 3;
-	}
-	tif->tif_rawcp = op;
-	tif->tif_rawcc = tif->tif_rawdatasize - occ;
-
-	return (1);
-}
-
-/*
- * Encode a row of 32-bit pixels.
- */
-static int
-LogLuvEncode32(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s)
-{
-	LogLuvState* sp = EncoderState(tif);
-	int shft, i, j, npixels;
-	tidata_t op;
-	uint32* tp;
-	uint32 b;
-	int occ, rc=0, mask, beg;
-
-	assert(s == 0);
-	assert(sp != NULL);
-
-	npixels = cc / sp->pixel_size;
-
-	if (sp->user_datafmt == SGILOGDATAFMT_RAW)
-		tp = (uint32*) bp;
-	else {
-		tp = (uint32*) sp->tbuf;
-		assert(sp->tbuflen >= npixels);
-		(*sp->tfunc)(sp, bp, npixels);
-	}
-					/* compress each byte string */
-	op = tif->tif_rawcp;
-	occ = tif->tif_rawdatasize - tif->tif_rawcc;
-	for (shft = 4*8; (shft -= 8) >= 0; )
-		for (i = 0; i < npixels; i += rc) {
-			if (occ < 4) {
-				tif->tif_rawcp = op;
-				tif->tif_rawcc = tif->tif_rawdatasize - occ;
-				if (!TIFFFlushData1(tif))
-					return (-1);
-				op = tif->tif_rawcp;
-				occ = tif->tif_rawdatasize - tif->tif_rawcc;
-			}
-			mask = 0xff << shft;		/* find next run */
-			for (beg = i; beg < npixels; beg += rc) {
-				b = tp[beg] & mask;
-				rc = 1;
-				while (rc < 127+2 && beg+rc < npixels &&
-						(tp[beg+rc] & mask) == b)
-					rc++;
-				if (rc >= MINRUN)
-					break;		/* long enough */
-			}
-			if (beg-i > 1 && beg-i < MINRUN) {
-				b = tp[i] & mask;	/* check short run */
-				j = i+1;
-				while ((tp[j++] & mask) == b)
-					if (j == beg) {
-						*op++ = (tidataval_t)(128-2+j-i);
-						*op++ = (tidataval_t)(b >> shft);
-						occ -= 2;
-						i = beg;
-						break;
-					}
-			}
-			while (i < beg) {		/* write out non-run */
-				if ((j = beg-i) > 127) j = 127;
-				if (occ < j+3) {
-					tif->tif_rawcp = op;
-					tif->tif_rawcc = tif->tif_rawdatasize - occ;
-					if (!TIFFFlushData1(tif))
-						return (-1);
-					op = tif->tif_rawcp;
-					occ = tif->tif_rawdatasize - tif->tif_rawcc;
-				}
-				*op++ = (tidataval_t) j; occ--;
-				while (j--) {
-					*op++ = (tidataval_t)(tp[i++] >> shft & 0xff);
-					occ--;
-				}
-			}
-			if (rc >= MINRUN) {		/* write out run */
-				*op++ = (tidataval_t) (128-2+rc);
-				*op++ = (tidataval_t)(tp[beg] >> shft & 0xff);
-				occ -= 2;
-			} else
-				rc = 0;
-		}
-	tif->tif_rawcp = op;
-	tif->tif_rawcc = tif->tif_rawdatasize - occ;
-
-	return (1);
-}
-
-/*
- * Encode a strip of pixels.  We break it into rows to
- * avoid encoding runs across row boundaries.
- */
-static int
-LogLuvEncodeStrip(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s)
-{
-	tsize_t rowlen = TIFFScanlineSize(tif);
-
-	assert(cc%rowlen == 0);
-	while (cc && (*tif->tif_encoderow)(tif, bp, rowlen, s) == 1)
-		bp += rowlen, cc -= rowlen;
-	return (cc == 0);
-}
-
-/*
- * Encode a tile of pixels.  We break it into rows to
- * avoid encoding runs across row boundaries.
- */
-static int
-LogLuvEncodeTile(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s)
-{
-	tsize_t rowlen = TIFFTileRowSize(tif);
-
-	assert(cc%rowlen == 0);
-	while (cc && (*tif->tif_encoderow)(tif, bp, rowlen, s) == 1)
-		bp += rowlen, cc -= rowlen;
-	return (cc == 0);
-}
-
-/*
- * Encode/Decode functions for converting to and from user formats.
- */
-
-#include "uvcode.h"
-
-#ifndef UVSCALE
-#define U_NEU		0.210526316
-#define V_NEU		0.473684211
-#define UVSCALE		410.
-#endif
-
-#ifndef	M_LN2
-#define M_LN2		0.69314718055994530942
-#endif
-#ifndef M_PI
-#define M_PI		3.14159265358979323846
-#endif
-#define log2(x)		((1./M_LN2)*log(x))
-#define exp2(x)		exp(M_LN2*(x))
-
-#define itrunc(x,m)	((m)==SGILOGENCODE_NODITHER ? \
-				(int)(x) : \
-				(int)((x) + rand()*(1./RAND_MAX) - .5))
-
-#if !LOGLUV_PUBLIC
-static
-#endif
-double
-LogL16toY(int p16)		/* compute luminance from 16-bit LogL */
-{
-	int	Le = p16 & 0x7fff;
-	double	Y;
-
-	if (!Le)
-		return (0.);
-	Y = exp(M_LN2/256.*(Le+.5) - M_LN2*64.);
-	return (!(p16 & 0x8000) ? Y : -Y);
-}
-
-#if !LOGLUV_PUBLIC
-static
-#endif
-int
-LogL16fromY(double Y, int em)	/* get 16-bit LogL from Y */
-{
-	if (Y >= 1.8371976e19)
-		return (0x7fff);
-	if (Y <= -1.8371976e19)
-		return (0xffff);
-	if (Y > 5.4136769e-20)
-		return itrunc(256.*(log2(Y) + 64.), em);
-	if (Y < -5.4136769e-20)
-		return (~0x7fff | itrunc(256.*(log2(-Y) + 64.), em));
-	return (0);
-}
-
-static void
-L16toY(LogLuvState* sp, tidata_t op, int n)
-{
-	int16* l16 = (int16*) sp->tbuf;
-	float* yp = (float*) op;
-
-	while (n-- > 0)
-		*yp++ = (float)LogL16toY(*l16++);
-}
-
-static void
-L16toGry(LogLuvState* sp, tidata_t op, int n)
-{
-	int16* l16 = (int16*) sp->tbuf;
-	uint8* gp = (uint8*) op;
-
-	while (n-- > 0) {
-		double Y = LogL16toY(*l16++);
-		*gp++ = (uint8) ((Y <= 0.) ? 0 : (Y >= 1.) ? 255 : (int)(256.*sqrt(Y)));
-	}
-}
-
-static void
-L16fromY(LogLuvState* sp, tidata_t op, int n)
-{
-	int16* l16 = (int16*) sp->tbuf;
-	float* yp = (float*) op;
-
-	while (n-- > 0)
-		*l16++ = (int16) (LogL16fromY(*yp++, sp->encode_meth));
-}
-
-#if !LOGLUV_PUBLIC
-static
-#endif
-void
-XYZtoRGB24(float xyz[3], uint8 rgb[3])
-{
-	double	r, g, b;
-					/* assume CCIR-709 primaries */
-	r =  2.690*xyz[0] + -1.276*xyz[1] + -0.414*xyz[2];
-	g = -1.022*xyz[0] +  1.978*xyz[1] +  0.044*xyz[2];
-	b =  0.061*xyz[0] + -0.224*xyz[1] +  1.163*xyz[2];
-					/* assume 2.0 gamma for speed */
-	/* could use integer sqrt approx., but this is probably faster */
-	rgb[0] = (uint8)((r<=0.) ? 0 : (r >= 1.) ? 255 : (int)(256.*sqrt(r)));
-	rgb[1] = (uint8)((g<=0.) ? 0 : (g >= 1.) ? 255 : (int)(256.*sqrt(g)));
-	rgb[2] = (uint8)((b<=0.) ? 0 : (b >= 1.) ? 255 : (int)(256.*sqrt(b)));
-}
-
-#if !LOGLUV_PUBLIC
-static
-#endif
-double
-LogL10toY(int p10)		/* compute luminance from 10-bit LogL */
-{
-	if (p10 == 0)
-		return (0.);
-	return (exp(M_LN2/64.*(p10+.5) - M_LN2*12.));
-}
-
-#if !LOGLUV_PUBLIC
-static
-#endif
-int
-LogL10fromY(double Y, int em)	/* get 10-bit LogL from Y */
-{
-	if (Y >= 15.742)
-		return (0x3ff);
-	else if (Y <= .00024283)
-		return (0);
-	else
-		return itrunc(64.*(log2(Y) + 12.), em);
-}
-
-#define NANGLES		100
-#define uv2ang(u, v)	( (NANGLES*.499999999/M_PI) \
-				* atan2((v)-V_NEU,(u)-U_NEU) + .5*NANGLES )
-
-static int
-oog_encode(double u, double v)		/* encode out-of-gamut chroma */
-{
-	static int	oog_table[NANGLES];
-	static int	initialized = 0;
-	register int	i;
-	
-	if (!initialized) {		/* set up perimeter table */
-		double	eps[NANGLES], ua, va, ang, epsa;
-		int	ui, vi, ustep;
-		for (i = NANGLES; i--; )
-			eps[i] = 2.;
-		for (vi = UV_NVS; vi--; ) {
-			va = UV_VSTART + (vi+.5)*UV_SQSIZ;
-			ustep = uv_row[vi].nus-1;
-			if (vi == UV_NVS-1 || vi == 0 || ustep <= 0)
-				ustep = 1;
-			for (ui = uv_row[vi].nus-1; ui >= 0; ui -= ustep) {
-				ua = uv_row[vi].ustart + (ui+.5)*UV_SQSIZ;
-				ang = uv2ang(ua, va);
-                                i = (int) ang;
-				epsa = fabs(ang - (i+.5));
-				if (epsa < eps[i]) {
-					oog_table[i] = uv_row[vi].ncum + ui;
-					eps[i] = epsa;
-				}
-			}
-		}
-		for (i = NANGLES; i--; )	/* fill any holes */
-			if (eps[i] > 1.5) {
-				int	i1, i2;
-				for (i1 = 1; i1 < NANGLES/2; i1++)
-					if (eps[(i+i1)%NANGLES] < 1.5)
-						break;
-				for (i2 = 1; i2 < NANGLES/2; i2++)
-					if (eps[(i+NANGLES-i2)%NANGLES] < 1.5)
-						break;
-				if (i1 < i2)
-					oog_table[i] =
-						oog_table[(i+i1)%NANGLES];
-				else
-					oog_table[i] =
-						oog_table[(i+NANGLES-i2)%NANGLES];
-			}
-		initialized = 1;
-	}
-	i = (int) uv2ang(u, v);		/* look up hue angle */
-	return (oog_table[i]);
-}
-
-#undef uv2ang
-#undef NANGLES
-
-#if !LOGLUV_PUBLIC
-static
-#endif
-int
-uv_encode(double u, double v, int em)	/* encode (u',v') coordinates */
-{
-	register int	vi, ui;
-
-	if (v < UV_VSTART)
-		return oog_encode(u, v);
-	vi = itrunc((v - UV_VSTART)*(1./UV_SQSIZ), em);
-	if (vi >= UV_NVS)
-		return oog_encode(u, v);
-	if (u < uv_row[vi].ustart)
-		return oog_encode(u, v);
-	ui = itrunc((u - uv_row[vi].ustart)*(1./UV_SQSIZ), em);
-	if (ui >= uv_row[vi].nus)
-		return oog_encode(u, v);
-
-	return (uv_row[vi].ncum + ui);
-}
-
-#if !LOGLUV_PUBLIC
-static
-#endif
-int
-uv_decode(double *up, double *vp, int c)	/* decode (u',v') index */
-{
-	int	upper, lower;
-	register int	ui, vi;
-
-	if (c < 0 || c >= UV_NDIVS)
-		return (-1);
-	lower = 0;				/* binary search */
-	upper = UV_NVS;
-	while (upper - lower > 1) {
-		vi = (lower + upper) >> 1;
-		ui = c - uv_row[vi].ncum;
-		if (ui > 0)
-			lower = vi;
-		else if (ui < 0)
-			upper = vi;
-		else {
-			lower = vi;
-			break;
-		}
-	}
-	vi = lower;
-	ui = c - uv_row[vi].ncum;
-	*up = uv_row[vi].ustart + (ui+.5)*UV_SQSIZ;
-	*vp = UV_VSTART + (vi+.5)*UV_SQSIZ;
-	return (0);
-}
-
-#if !LOGLUV_PUBLIC
-static
-#endif
-void
-LogLuv24toXYZ(uint32 p, float XYZ[3])
-{
-	int	Ce;
-	double	L, u, v, s, x, y;
-					/* decode luminance */
-	L = LogL10toY(p>>14 & 0x3ff);
-	if (L <= 0.) {
-		XYZ[0] = XYZ[1] = XYZ[2] = 0.;
-		return;
-	}
-					/* decode color */
-	Ce = p & 0x3fff;
-	if (uv_decode(&u, &v, Ce) < 0) {
-		u = U_NEU; v = V_NEU;
-	}
-	s = 1./(6.*u - 16.*v + 12.);
-	x = 9.*u * s;
-	y = 4.*v * s;
-					/* convert to XYZ */
-	XYZ[0] = (float)(x/y * L);
-	XYZ[1] = (float)L;
-	XYZ[2] = (float)((1.-x-y)/y * L);
-}
-
-#if !LOGLUV_PUBLIC
-static
-#endif
-uint32
-LogLuv24fromXYZ(float XYZ[3], int em)
-{
-	int	Le, Ce;
-	double	u, v, s;
-					/* encode luminance */
-	Le = LogL10fromY(XYZ[1], em);
-					/* encode color */
-	s = XYZ[0] + 15.*XYZ[1] + 3.*XYZ[2];
-	if (!Le || s <= 0.) {
-		u = U_NEU;
-		v = V_NEU;
-	} else {
-		u = 4.*XYZ[0] / s;
-		v = 9.*XYZ[1] / s;
-	}
-	Ce = uv_encode(u, v, em);
-	if (Ce < 0)			/* never happens */
-		Ce = uv_encode(U_NEU, V_NEU, SGILOGENCODE_NODITHER);
-					/* combine encodings */
-	return (Le << 14 | Ce);
-}
-
-static void
-Luv24toXYZ(LogLuvState* sp, tidata_t op, int n)
-{
-	uint32* luv = (uint32*) sp->tbuf;
-	float* xyz = (float*) op;
-
-	while (n-- > 0) {
-		LogLuv24toXYZ(*luv, xyz);
-		xyz += 3;
-		luv++;
-	}
-}
-
-static void
-Luv24toLuv48(LogLuvState* sp, tidata_t op, int n)
-{
-	uint32* luv = (uint32*) sp->tbuf;
-	int16* luv3 = (int16*) op;
-
-	while (n-- > 0) {
-		double u, v;
-
-		*luv3++ = (int16)((*luv >> 12 & 0xffd) + 13314);
-		if (uv_decode(&u, &v, *luv&0x3fff) < 0) {
-			u = U_NEU;
-			v = V_NEU;
-		}
-		*luv3++ = (int16)(u * (1L<<15));
-		*luv3++ = (int16)(v * (1L<<15));
-		luv++;
-	}
-}
-
-static void
-Luv24toRGB(LogLuvState* sp, tidata_t op, int n)
-{
-	uint32* luv = (uint32*) sp->tbuf;
-	uint8* rgb = (uint8*) op;
-
-	while (n-- > 0) {
-		float xyz[3];
-
-		LogLuv24toXYZ(*luv++, xyz);
-		XYZtoRGB24(xyz, rgb);
-		rgb += 3;
-	}
-}
-
-static void
-Luv24fromXYZ(LogLuvState* sp, tidata_t op, int n)
-{
-	uint32* luv = (uint32*) sp->tbuf;
-	float* xyz = (float*) op;
-
-	while (n-- > 0) {
-		*luv++ = LogLuv24fromXYZ(xyz, sp->encode_meth);
-		xyz += 3;
-	}
-}
-
-static void
-Luv24fromLuv48(LogLuvState* sp, tidata_t op, int n)
-{
-	uint32* luv = (uint32*) sp->tbuf;
-	int16* luv3 = (int16*) op;
-
-	while (n-- > 0) {
-		int Le, Ce;
-
-		if (luv3[0] <= 0)
-			Le = 0;
-		else if (luv3[0] >= (1<<12)+3314)
-			Le = (1<<10) - 1;
-		else if (sp->encode_meth == SGILOGENCODE_NODITHER)
-			Le = (luv3[0]-3314) >> 2;
-		else
-			Le = itrunc(.25*(luv3[0]-3314.), sp->encode_meth);
-
-		Ce = uv_encode((luv3[1]+.5)/(1<<15), (luv3[2]+.5)/(1<<15),
-					sp->encode_meth);
-		if (Ce < 0)	/* never happens */
-			Ce = uv_encode(U_NEU, V_NEU, SGILOGENCODE_NODITHER);
-		*luv++ = (uint32)Le << 14 | Ce;
-		luv3 += 3;
-	}
-}
-
-#if !LOGLUV_PUBLIC
-static
-#endif
-void
-LogLuv32toXYZ(uint32 p, float XYZ[3])
-{
-	double	L, u, v, s, x, y;
-					/* decode luminance */
-	L = LogL16toY((int)p >> 16);
-	if (L <= 0.) {
-		XYZ[0] = XYZ[1] = XYZ[2] = 0.;
-		return;
-	}
-					/* decode color */
-	u = 1./UVSCALE * ((p>>8 & 0xff) + .5);
-	v = 1./UVSCALE * ((p & 0xff) + .5);
-	s = 1./(6.*u - 16.*v + 12.);
-	x = 9.*u * s;
-	y = 4.*v * s;
-					/* convert to XYZ */
-	XYZ[0] = (float)(x/y * L);
-	XYZ[1] = (float)L;
-	XYZ[2] = (float)((1.-x-y)/y * L);
-}
-
-#if !LOGLUV_PUBLIC
-static
-#endif
-uint32
-LogLuv32fromXYZ(float XYZ[3], int em)
-{
-	unsigned int	Le, ue, ve;
-	double	u, v, s;
-					/* encode luminance */
-	Le = (unsigned int)LogL16fromY(XYZ[1], em);
-					/* encode color */
-	s = XYZ[0] + 15.*XYZ[1] + 3.*XYZ[2];
-	if (!Le || s <= 0.) {
-		u = U_NEU;
-		v = V_NEU;
-	} else {
-		u = 4.*XYZ[0] / s;
-		v = 9.*XYZ[1] / s;
-	}
-	if (u <= 0.) ue = 0;
-	else ue = itrunc(UVSCALE*u, em);
-	if (ue > 255) ue = 255;
-	if (v <= 0.) ve = 0;
-	else ve = itrunc(UVSCALE*v, em);
-	if (ve > 255) ve = 255;
-					/* combine encodings */
-	return (Le << 16 | ue << 8 | ve);
-}
-
-static void
-Luv32toXYZ(LogLuvState* sp, tidata_t op, int n)
-{
-	uint32* luv = (uint32*) sp->tbuf;
-	float* xyz = (float*) op;
-
-	while (n-- > 0) {
-		LogLuv32toXYZ(*luv++, xyz);
-		xyz += 3;
-	}
-}
-
-static void
-Luv32toLuv48(LogLuvState* sp, tidata_t op, int n)
-{
-	uint32* luv = (uint32*) sp->tbuf;
-	int16* luv3 = (int16*) op;
-
-	while (n-- > 0) {
-		double u, v;
-
-		*luv3++ = (int16)(*luv >> 16);
-		u = 1./UVSCALE * ((*luv>>8 & 0xff) + .5);
-		v = 1./UVSCALE * ((*luv & 0xff) + .5);
-		*luv3++ = (int16)(u * (1L<<15));
-		*luv3++ = (int16)(v * (1L<<15));
-		luv++;
-	}
-}
-
-static void
-Luv32toRGB(LogLuvState* sp, tidata_t op, int n)
-{
-	uint32* luv = (uint32*) sp->tbuf;
-	uint8* rgb = (uint8*) op;
-
-	while (n-- > 0) {
-		float xyz[3];
-
-		LogLuv32toXYZ(*luv++, xyz);
-		XYZtoRGB24(xyz, rgb);
-		rgb += 3;
-	}
-}
-
-static void
-Luv32fromXYZ(LogLuvState* sp, tidata_t op, int n)
-{
-	uint32* luv = (uint32*) sp->tbuf;
-	float* xyz = (float*) op;
-
-	while (n-- > 0) {
-		*luv++ = LogLuv32fromXYZ(xyz, sp->encode_meth);
-		xyz += 3;
-	}
-}
-
-static void
-Luv32fromLuv48(LogLuvState* sp, tidata_t op, int n)
-{
-	uint32* luv = (uint32*) sp->tbuf;
-	int16* luv3 = (int16*) op;
-
-	if (sp->encode_meth == SGILOGENCODE_NODITHER) {
-		while (n-- > 0) {
-			*luv++ = (uint32)luv3[0] << 16 |
-				(luv3[1]*(uint32)(UVSCALE+.5) >> 7 & 0xff00) |
-				(luv3[2]*(uint32)(UVSCALE+.5) >> 15 & 0xff);
-			luv3 += 3;
-		}
-		return;
-	}
-	while (n-- > 0) {
-		*luv++ = (uint32)luv3[0] << 16 |
-	(itrunc(luv3[1]*(UVSCALE/(1<<15)), sp->encode_meth) << 8 & 0xff00) |
-		(itrunc(luv3[2]*(UVSCALE/(1<<15)), sp->encode_meth) & 0xff);
-		luv3 += 3;
-	}
-}
-
-static void
-_logLuvNop(LogLuvState* sp, tidata_t op, int n)
-{
-	(void) sp; (void) op; (void) n;
-}
-
-static int
-LogL16GuessDataFmt(TIFFDirectory *td)
-{
-#define	PACK(s,b,f)	(((b)<<6)|((s)<<3)|(f))
-	switch (PACK(td->td_samplesperpixel, td->td_bitspersample, td->td_sampleformat)) {
-	case PACK(1, 32, SAMPLEFORMAT_IEEEFP):
-		return (SGILOGDATAFMT_FLOAT);
-	case PACK(1, 16, SAMPLEFORMAT_VOID):
-	case PACK(1, 16, SAMPLEFORMAT_INT):
-	case PACK(1, 16, SAMPLEFORMAT_UINT):
-		return (SGILOGDATAFMT_16BIT);
-	case PACK(1,  8, SAMPLEFORMAT_VOID):
-	case PACK(1,  8, SAMPLEFORMAT_UINT):
-		return (SGILOGDATAFMT_8BIT);
-	}
-#undef PACK
-	return (SGILOGDATAFMT_UNKNOWN);
-}
-
-static uint32
-multiply(size_t m1, size_t m2)
-{
-	uint32	bytes = m1 * m2;
-
-	if (m1 && bytes / m1 != m2)
-		bytes = 0;
-
-	return bytes;
-}
-
-static int
-LogL16InitState(TIFF* tif)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-	LogLuvState* sp = DecoderState(tif);
-	static const char module[] = "LogL16InitState";
-
-	assert(sp != NULL);
-	assert(td->td_photometric == PHOTOMETRIC_LOGL);
-
-	/* for some reason, we can't do this in TIFFInitLogL16 */
-	if (sp->user_datafmt == SGILOGDATAFMT_UNKNOWN)
-		sp->user_datafmt = LogL16GuessDataFmt(td);
-	switch (sp->user_datafmt) {
-	case SGILOGDATAFMT_FLOAT:
-		sp->pixel_size = sizeof (float);
-		break;
-	case SGILOGDATAFMT_16BIT:
-		sp->pixel_size = sizeof (int16);
-		break;
-	case SGILOGDATAFMT_8BIT:
-		sp->pixel_size = sizeof (uint8);
-		break;
-	default:
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-		    "No support for converting user data format to LogL");
-		return (0);
-	}
-        if( isTiled(tif) )
-            sp->tbuflen = multiply(td->td_tilewidth, td->td_tilelength);
-        else
-            sp->tbuflen = multiply(td->td_imagewidth, td->td_rowsperstrip);
-	if (multiply(sp->tbuflen, sizeof (int16)) == 0 ||
-	    (sp->tbuf = (tidata_t*) _TIFFmalloc(sp->tbuflen * sizeof (int16))) == NULL) {
-		TIFFErrorExt(tif->tif_clientdata, module, "%s: No space for SGILog translation buffer",
-		    tif->tif_name);
-		return (0);
-	}
-	return (1);
-}
-
-static int
-LogLuvGuessDataFmt(TIFFDirectory *td)
-{
-	int guess;
-
-	/*
-	 * If the user didn't tell us their datafmt,
-	 * take our best guess from the bitspersample.
-	 */
-#define	PACK(a,b)	(((a)<<3)|(b))
-	switch (PACK(td->td_bitspersample, td->td_sampleformat)) {
-	case PACK(32, SAMPLEFORMAT_IEEEFP):
-		guess = SGILOGDATAFMT_FLOAT;
-		break;
-	case PACK(32, SAMPLEFORMAT_VOID):
-	case PACK(32, SAMPLEFORMAT_UINT):
-	case PACK(32, SAMPLEFORMAT_INT):
-		guess = SGILOGDATAFMT_RAW;
-		break;
-	case PACK(16, SAMPLEFORMAT_VOID):
-	case PACK(16, SAMPLEFORMAT_INT):
-	case PACK(16, SAMPLEFORMAT_UINT):
-		guess = SGILOGDATAFMT_16BIT;
-		break;
-	case PACK( 8, SAMPLEFORMAT_VOID):
-	case PACK( 8, SAMPLEFORMAT_UINT):
-		guess = SGILOGDATAFMT_8BIT;
-		break;
-	default:
-		guess = SGILOGDATAFMT_UNKNOWN;
-		break;
-#undef PACK
-	}
-	/*
-	 * Double-check samples per pixel.
-	 */
-	switch (td->td_samplesperpixel) {
-	case 1:
-		if (guess != SGILOGDATAFMT_RAW)
-			guess = SGILOGDATAFMT_UNKNOWN;
-		break;
-	case 3:
-		if (guess == SGILOGDATAFMT_RAW)
-			guess = SGILOGDATAFMT_UNKNOWN;
-		break;
-	default:
-		guess = SGILOGDATAFMT_UNKNOWN;
-		break;
-	}
-	return (guess);
-}
-
-static int
-LogLuvInitState(TIFF* tif)
-{
-	TIFFDirectory* td = &tif->tif_dir;
-	LogLuvState* sp = DecoderState(tif);
-	static const char module[] = "LogLuvInitState";
-
-	assert(sp != NULL);
-	assert(td->td_photometric == PHOTOMETRIC_LOGLUV);
-
-	/* for some reason, we can't do this in TIFFInitLogLuv */
-	if (td->td_planarconfig != PLANARCONFIG_CONTIG) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-		    "SGILog compression cannot handle non-contiguous data");
-		return (0);
-	}
-	if (sp->user_datafmt == SGILOGDATAFMT_UNKNOWN)
-		sp->user_datafmt = LogLuvGuessDataFmt(td);
-	switch (sp->user_datafmt) {
-	case SGILOGDATAFMT_FLOAT:
-		sp->pixel_size = 3*sizeof (float);
-		break;
-	case SGILOGDATAFMT_16BIT:
-		sp->pixel_size = 3*sizeof (int16);
-		break;
-	case SGILOGDATAFMT_RAW:
-		sp->pixel_size = sizeof (uint32);
-		break;
-	case SGILOGDATAFMT_8BIT:
-		sp->pixel_size = 3*sizeof (uint8);
-		break;
-	default:
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-		    "No support for converting user data format to LogLuv");
-		return (0);
-	}
-        if( isTiled(tif) )
-            sp->tbuflen = multiply(td->td_tilewidth, td->td_tilelength);
-        else
-            sp->tbuflen = multiply(td->td_imagewidth, td->td_rowsperstrip);
-	if (multiply(sp->tbuflen, sizeof (uint32)) == 0 ||
-	    (sp->tbuf = (tidata_t*) _TIFFmalloc(sp->tbuflen * sizeof (uint32))) == NULL) {
-		TIFFErrorExt(tif->tif_clientdata, module, "%s: No space for SGILog translation buffer",
-		    tif->tif_name);
-		return (0);
-	}
-	return (1);
-}
-
-static int
-LogLuvSetupDecode(TIFF* tif)
-{
-	LogLuvState* sp = DecoderState(tif);
-	TIFFDirectory* td = &tif->tif_dir;
-
-	tif->tif_postdecode = _TIFFNoPostDecode;
-	switch (td->td_photometric) {
-	case PHOTOMETRIC_LOGLUV:
-		if (!LogLuvInitState(tif))
-			break;
-		if (td->td_compression == COMPRESSION_SGILOG24) {
-			tif->tif_decoderow = LogLuvDecode24;
-			switch (sp->user_datafmt) {
-			case SGILOGDATAFMT_FLOAT:
-				sp->tfunc = Luv24toXYZ;
-				break;
-			case SGILOGDATAFMT_16BIT:
-				sp->tfunc = Luv24toLuv48;
-				break;
-			case SGILOGDATAFMT_8BIT:
-				sp->tfunc = Luv24toRGB;
-				break;
-			}
-		} else {
-			tif->tif_decoderow = LogLuvDecode32;
-			switch (sp->user_datafmt) {
-			case SGILOGDATAFMT_FLOAT:
-				sp->tfunc = Luv32toXYZ;
-				break;
-			case SGILOGDATAFMT_16BIT:
-				sp->tfunc = Luv32toLuv48;
-				break;
-			case SGILOGDATAFMT_8BIT:
-				sp->tfunc = Luv32toRGB;
-				break;
-			}
-		}
-		return (1);
-	case PHOTOMETRIC_LOGL:
-		if (!LogL16InitState(tif))
-			break;
-		tif->tif_decoderow = LogL16Decode;
-		switch (sp->user_datafmt) {
-		case SGILOGDATAFMT_FLOAT:
-			sp->tfunc = L16toY;
-			break;
-		case SGILOGDATAFMT_8BIT:
-			sp->tfunc = L16toGry;
-			break;
-		}
-		return (1);
-	default:
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-    "Inappropriate photometric interpretation %d for SGILog compression; %s",
-		    td->td_photometric, "must be either LogLUV or LogL");
-		break;
-	}
-	return (0);
-}
-
-static int
-LogLuvSetupEncode(TIFF* tif)
-{
-	LogLuvState* sp = EncoderState(tif);
-	TIFFDirectory* td = &tif->tif_dir;
-
-	switch (td->td_photometric) {
-	case PHOTOMETRIC_LOGLUV:
-		if (!LogLuvInitState(tif))
-			break;
-		if (td->td_compression == COMPRESSION_SGILOG24) {
-			tif->tif_encoderow = LogLuvEncode24;
-			switch (sp->user_datafmt) {
-			case SGILOGDATAFMT_FLOAT:
-				sp->tfunc = Luv24fromXYZ;
-				break;
-			case SGILOGDATAFMT_16BIT:
-				sp->tfunc = Luv24fromLuv48;
-				break;
-			case SGILOGDATAFMT_RAW:
-				break;
-			default:
-				goto notsupported;
-			}
-		} else {
-			tif->tif_encoderow = LogLuvEncode32;
-			switch (sp->user_datafmt) {
-			case SGILOGDATAFMT_FLOAT:
-				sp->tfunc = Luv32fromXYZ;
-				break;
-			case SGILOGDATAFMT_16BIT:
-				sp->tfunc = Luv32fromLuv48;
-				break;
-			case SGILOGDATAFMT_RAW:
-				break;
-			default:
-				goto notsupported;
-			}
-		}
-		break;
-	case PHOTOMETRIC_LOGL:
-		if (!LogL16InitState(tif))
-			break;
-		tif->tif_encoderow = LogL16Encode;
-		switch (sp->user_datafmt) {
-		case SGILOGDATAFMT_FLOAT:
-			sp->tfunc = L16fromY;
-			break;
-		case SGILOGDATAFMT_16BIT:
-			break;
-		default:
-			goto notsupported;
-		}
-		break;
-	default:
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-    "Inappropriate photometric interpretation %d for SGILog compression; %s",
-    		    td->td_photometric, "must be either LogLUV or LogL");
-		break;
-	}
-	return (1);
-notsupported:
-	TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-	    "SGILog compression supported only for %s, or raw data",
-	    td->td_photometric == PHOTOMETRIC_LOGL ? "Y, L" : "XYZ, Luv");
-	return (0);
-}
-
-static void
-LogLuvClose(TIFF* tif)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-
-	/*
-	 * For consistency, we always want to write out the same
-	 * bitspersample and sampleformat for our TIFF file,
-	 * regardless of the data format being used by the application.
-	 * Since this routine is called after tags have been set but
-	 * before they have been recorded in the file, we reset them here.
-	 */
-	td->td_samplesperpixel =
-	    (td->td_photometric == PHOTOMETRIC_LOGL) ? 1 : 3;
-	td->td_bitspersample = 16;
-	td->td_sampleformat = SAMPLEFORMAT_INT;
-}
-
-static void
-LogLuvCleanup(TIFF* tif)
-{
-	LogLuvState* sp = (LogLuvState *)tif->tif_data;
-
-	assert(sp != 0);
-
-	tif->tif_tagmethods.vgetfield = sp->vgetparent;
-	tif->tif_tagmethods.vsetfield = sp->vsetparent;
-
-	if (sp->tbuf)
-		_TIFFfree(sp->tbuf);
-	_TIFFfree(sp);
-	tif->tif_data = NULL;
-
-	_TIFFSetDefaultCompressionState(tif);
-}
-
-static int
-LogLuvVSetField(TIFF* tif, ttag_t tag, va_list ap)
-{
-	LogLuvState* sp = DecoderState(tif);
-	int bps, fmt;
-
-	switch (tag) {
-	case TIFFTAG_SGILOGDATAFMT:
-		sp->user_datafmt = va_arg(ap, int);
-		/*
-		 * Tweak the TIFF header so that the rest of libtiff knows what
-		 * size of data will be passed between app and library, and
-		 * assume that the app knows what it is doing and is not
-		 * confused by these header manipulations...
-		 */
-		switch (sp->user_datafmt) {
-		case SGILOGDATAFMT_FLOAT:
-			bps = 32, fmt = SAMPLEFORMAT_IEEEFP;
-			break;
-		case SGILOGDATAFMT_16BIT:
-			bps = 16, fmt = SAMPLEFORMAT_INT;
-			break;
-		case SGILOGDATAFMT_RAW:
-			bps = 32, fmt = SAMPLEFORMAT_UINT;
-			TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
-			break;
-		case SGILOGDATAFMT_8BIT:
-			bps = 8, fmt = SAMPLEFORMAT_UINT;
-			break;
-		default:
-			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			    "Unknown data format %d for LogLuv compression",
-			    sp->user_datafmt);
-			return (0);
-		}
-		TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps);
-		TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, fmt);
-		/*
-		 * Must recalculate sizes should bits/sample change.
-		 */
-		tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tsize_t) -1;
-		tif->tif_scanlinesize = TIFFScanlineSize(tif);
-		return (1);
-	case TIFFTAG_SGILOGENCODE:
-		sp->encode_meth = va_arg(ap, int);
-		if (sp->encode_meth != SGILOGENCODE_NODITHER &&
-				sp->encode_meth != SGILOGENCODE_RANDITHER) {
-			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-				"Unknown encoding %d for LogLuv compression",
-				sp->encode_meth);
-			return (0);
-		}
-		return (1);
-	default:
-		return (*sp->vsetparent)(tif, tag, ap);
-	}
-}
-
-static int
-LogLuvVGetField(TIFF* tif, ttag_t tag, va_list ap)
-{
-	LogLuvState *sp = (LogLuvState *)tif->tif_data;
-
-	switch (tag) {
-	case TIFFTAG_SGILOGDATAFMT:
-		*va_arg(ap, int*) = sp->user_datafmt;
-		return (1);
-	default:
-		return (*sp->vgetparent)(tif, tag, ap);
-	}
-}
-
-static const TIFFFieldInfo LogLuvFieldInfo[] = {
-    { TIFFTAG_SGILOGDATAFMT,	  0, 0,	TIFF_SHORT,	FIELD_PSEUDO,
-      TRUE,	FALSE,	"SGILogDataFmt"},
-    { TIFFTAG_SGILOGENCODE,	  0, 0, TIFF_SHORT,	FIELD_PSEUDO,
-      TRUE,	FALSE,	"SGILogEncode"}
-};
-
-int
-TIFFInitSGILog(TIFF* tif, int scheme)
-{
-	static const char module[] = "TIFFInitSGILog";
-	LogLuvState* sp;
-
-	assert(scheme == COMPRESSION_SGILOG24 || scheme == COMPRESSION_SGILOG);
-
-	/*
-	 * Merge codec-specific tag information.
-	 */
-	if (!_TIFFMergeFieldInfo(tif, LogLuvFieldInfo,
-				 TIFFArrayCount(LogLuvFieldInfo))) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-			     "Merging SGILog codec-specific tags failed");
-		return 0;
-	}
-
-	/*
-	 * Allocate state block so tag methods have storage to record values.
-	 */
-	tif->tif_data = (tidata_t) _TIFFmalloc(sizeof (LogLuvState));
-	if (tif->tif_data == NULL)
-		goto bad;
-	sp = (LogLuvState*) tif->tif_data;
-	_TIFFmemset((tdata_t)sp, 0, sizeof (*sp));
-	sp->user_datafmt = SGILOGDATAFMT_UNKNOWN;
-	sp->encode_meth = (scheme == COMPRESSION_SGILOG24) ?
-				SGILOGENCODE_RANDITHER : SGILOGENCODE_NODITHER;
-	sp->tfunc = _logLuvNop;
-
-	/*
-	 * Install codec methods.
-	 * NB: tif_decoderow & tif_encoderow are filled
-	 *     in at setup time.
-	 */
-	tif->tif_setupdecode = LogLuvSetupDecode;
-	tif->tif_decodestrip = LogLuvDecodeStrip;
-	tif->tif_decodetile = LogLuvDecodeTile;
-	tif->tif_setupencode = LogLuvSetupEncode;
-	tif->tif_encodestrip = LogLuvEncodeStrip;
-	tif->tif_encodetile = LogLuvEncodeTile;
-	tif->tif_close = LogLuvClose;
-	tif->tif_cleanup = LogLuvCleanup;
-
-	/* 
-	 * Override parent get/set field methods.
-	 */
-	sp->vgetparent = tif->tif_tagmethods.vgetfield;
-	tif->tif_tagmethods.vgetfield = LogLuvVGetField;   /* hook for codec tags */
-	sp->vsetparent = tif->tif_tagmethods.vsetfield;
-	tif->tif_tagmethods.vsetfield = LogLuvVSetField;   /* hook for codec tags */
-
-	return (1);
-bad:
-	TIFFErrorExt(tif->tif_clientdata, module,
-		     "%s: No space for LogLuv state block", tif->tif_name);
-	return (0);
-}
-#endif /* LOGLUV_SUPPORT */
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_lzw.c b/Source/LibTIFF/tif_lzw.c
deleted file mode 100644
index 089450d..0000000
--- a/Source/LibTIFF/tif_lzw.c
+++ /dev/null
@@ -1,1129 +0,0 @@
-/* $Id: tif_lzw.c,v 1.38 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-#include "tiffiop.h"
-#ifdef LZW_SUPPORT
-/*
- * TIFF Library.
- * Rev 5.0 Lempel-Ziv & Welch Compression Support
- *
- * This code is derived from the compress program whose code is
- * derived from software contributed to Berkeley by James A. Woods,
- * derived from original work by Spencer Thomas and Joseph Orost.
- *
- * The original Berkeley copyright notice appears below in its entirety.
- */
-#include "tif_predict.h"
-
-#include <stdio.h>
-
-/*
- * NB: The 5.0 spec describes a different algorithm than Aldus
- *     implements.  Specifically, Aldus does code length transitions
- *     one code earlier than should be done (for real LZW).
- *     Earlier versions of this library implemented the correct
- *     LZW algorithm, but emitted codes in a bit order opposite
- *     to the TIFF spec.  Thus, to maintain compatibility w/ Aldus
- *     we interpret MSB-LSB ordered codes to be images written w/
- *     old versions of this library, but otherwise adhere to the
- *     Aldus "off by one" algorithm.
- *
- * Future revisions to the TIFF spec are expected to "clarify this issue".
- */
-#define	LZW_COMPAT		/* include backwards compatibility code */
-/*
- * Each strip of data is supposed to be terminated by a CODE_EOI.
- * If the following #define is included, the decoder will also
- * check for end-of-strip w/o seeing this code.  This makes the
- * library more robust, but also slower.
- */
-#define	LZW_CHECKEOS		/* include checks for strips w/o EOI code */
-
-#define MAXCODE(n)	((1L<<(n))-1)
-/*
- * The TIFF spec specifies that encoded bit
- * strings range from 9 to 12 bits.
- */
-#define	BITS_MIN	9		/* start with 9 bits */
-#define	BITS_MAX	12		/* max of 12 bit strings */
-/* predefined codes */
-#define	CODE_CLEAR	256		/* code to clear string table */
-#define	CODE_EOI	257		/* end-of-information code */
-#define CODE_FIRST	258		/* first free code entry */
-#define	CODE_MAX	MAXCODE(BITS_MAX)
-#define	HSIZE		9001L		/* 91% occupancy */
-#define	HSHIFT		(13-8)
-#ifdef LZW_COMPAT
-/* NB: +1024 is for compatibility with old files */
-#define	CSIZE		(MAXCODE(BITS_MAX)+1024L)
-#else
-#define	CSIZE		(MAXCODE(BITS_MAX)+1L)
-#endif
-
-/*
- * State block for each open TIFF file using LZW
- * compression/decompression.  Note that the predictor
- * state block must be first in this data structure.
- */
-typedef	struct {
-	TIFFPredictorState predict;	/* predictor super class */
-
-	unsigned short	nbits;		/* # of bits/code */
-	unsigned short	maxcode;	/* maximum code for lzw_nbits */
-	unsigned short	free_ent;	/* next free entry in hash table */
-	long		nextdata;	/* next bits of i/o */
-	long		nextbits;	/* # of valid bits in lzw_nextdata */
-
-        int             rw_mode;        /* preserve rw_mode from init */
-} LZWBaseState;
-
-#define	lzw_nbits	base.nbits
-#define	lzw_maxcode	base.maxcode
-#define	lzw_free_ent	base.free_ent
-#define	lzw_nextdata	base.nextdata
-#define	lzw_nextbits	base.nextbits
-
-/*
- * Encoding-specific state.
- */
-typedef uint16 hcode_t;			/* codes fit in 16 bits */
-typedef struct {
-	long	hash;
-	hcode_t	code;
-} hash_t;
-
-/*
- * Decoding-specific state.
- */
-typedef struct code_ent {
-	struct code_ent *next;
-	unsigned short	length;		/* string len, including this token */
-	unsigned char	value;		/* data value */
-	unsigned char	firstchar;	/* first token of string */
-} code_t;
-
-typedef	int (*decodeFunc)(TIFF*, tidata_t, tsize_t, tsample_t);
-
-typedef struct {
-	LZWBaseState base;
-
-	/* Decoding specific data */
-	long	dec_nbitsmask;		/* lzw_nbits 1 bits, right adjusted */
-	long	dec_restart;		/* restart count */
-#ifdef LZW_CHECKEOS
-	long	dec_bitsleft;		/* available bits in raw data */
-#endif
-	decodeFunc dec_decode;		/* regular or backwards compatible */
-	code_t*	dec_codep;		/* current recognized code */
-	code_t*	dec_oldcodep;		/* previously recognized code */
-	code_t*	dec_free_entp;		/* next free entry */
-	code_t*	dec_maxcodep;		/* max available entry */
-	code_t*	dec_codetab;		/* kept separate for small machines */
-
-	/* Encoding specific data */
-	int	enc_oldcode;		/* last code encountered */
-	long	enc_checkpoint;		/* point at which to clear table */
-#define CHECK_GAP	10000		/* enc_ratio check interval */
-	long	enc_ratio;		/* current compression ratio */
-	long	enc_incount;		/* (input) data bytes encoded */
-	long	enc_outcount;		/* encoded (output) bytes */
-	tidata_t enc_rawlimit;		/* bound on tif_rawdata buffer */
-	hash_t*	enc_hashtab;		/* kept separate for small machines */
-} LZWCodecState;
-
-#define	LZWState(tif)		((LZWBaseState*) (tif)->tif_data)
-#define	DecoderState(tif)	((LZWCodecState*) LZWState(tif))
-#define	EncoderState(tif)	((LZWCodecState*) LZWState(tif))
-
-static	int LZWDecode(TIFF*, tidata_t, tsize_t, tsample_t);
-#ifdef LZW_COMPAT
-static	int LZWDecodeCompat(TIFF*, tidata_t, tsize_t, tsample_t);
-#endif
-static  void cl_hash(LZWCodecState*);
-
-/*
- * LZW Decoder.
- */
-
-#ifdef LZW_CHECKEOS
-/*
- * This check shouldn't be necessary because each
- * strip is suppose to be terminated with CODE_EOI.
- */
-#define	NextCode(_tif, _sp, _bp, _code, _get) {				\
-	if ((_sp)->dec_bitsleft < nbits) {				\
-		TIFFWarningExt(_tif->tif_clientdata, _tif->tif_name,				\
-		    "LZWDecode: Strip %d not terminated with EOI code", \
-		    _tif->tif_curstrip);				\
-		_code = CODE_EOI;					\
-	} else {							\
-		_get(_sp,_bp,_code);					\
-		(_sp)->dec_bitsleft -= nbits;				\
-	}								\
-}
-#else
-#define	NextCode(tif, sp, bp, code, get) get(sp, bp, code)
-#endif
-
-static int
-LZWSetupDecode(TIFF* tif)
-{
-	LZWCodecState* sp = DecoderState(tif);
-	static const char module[] = " LZWSetupDecode";
-	int code;
-
-        if( sp == NULL )
-        {
-            /*
-             * Allocate state block so tag methods have storage to record 
-			 * values.
-             */
-            tif->tif_data = (tidata_t) _TIFFmalloc(sizeof(LZWCodecState));
-            if (tif->tif_data == NULL)
-            {
-				TIFFErrorExt(tif->tif_clientdata, "LZWPreDecode", "No space for LZW state block");
-                return (0);
-            }
-
-            DecoderState(tif)->dec_codetab = NULL;
-            DecoderState(tif)->dec_decode = NULL;
-            
-            /*
-             * Setup predictor setup.
-             */
-            (void) TIFFPredictorInit(tif);
-
-            sp = DecoderState(tif);
-        }
-            
-	assert(sp != NULL);
-
-	if (sp->dec_codetab == NULL) {
-		sp->dec_codetab = (code_t*)_TIFFmalloc(CSIZE*sizeof (code_t));
-		if (sp->dec_codetab == NULL) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-				     "No space for LZW code table");
-			return (0);
-		}
-		/*
-		 * Pre-load the table.
-		 */
-                code = 255;
-                do {
-                    sp->dec_codetab[code].value = code;
-                    sp->dec_codetab[code].firstchar = code;
-                    sp->dec_codetab[code].length = 1;
-                    sp->dec_codetab[code].next = NULL;
-                } while (code--);
-		/*
-		 * Zero-out the unused entries
-                 */
-                 _TIFFmemset(&sp->dec_codetab[CODE_CLEAR], 0,
-			     (CODE_FIRST - CODE_CLEAR) * sizeof (code_t));
-	}
-	return (1);
-}
-
-/*
- * Setup state for decoding a strip.
- */
-static int
-LZWPreDecode(TIFF* tif, tsample_t s)
-{
-	LZWCodecState *sp = DecoderState(tif);
-
-	(void) s;
-	assert(sp != NULL);
-        if( sp->dec_codetab == NULL )
-        {
-            tif->tif_setupdecode( tif );
-        }
-
-	/*
-	 * Check for old bit-reversed codes.
-	 */
-	if (tif->tif_rawdata[0] == 0 && (tif->tif_rawdata[1] & 0x1)) {
-#ifdef LZW_COMPAT
-		if (!sp->dec_decode) {
-			TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
-			    "Old-style LZW codes, convert file");
-			/*
-			 * Override default decoding methods with
-			 * ones that deal with the old coding.
-			 * Otherwise the predictor versions set
-			 * above will call the compatibility routines
-			 * through the dec_decode method.
-			 */
-			tif->tif_decoderow = LZWDecodeCompat;
-			tif->tif_decodestrip = LZWDecodeCompat;
-			tif->tif_decodetile = LZWDecodeCompat;
-			/*
-			 * If doing horizontal differencing, must
-			 * re-setup the predictor logic since we
-			 * switched the basic decoder methods...
-			 */
-			(*tif->tif_setupdecode)(tif);
-			sp->dec_decode = LZWDecodeCompat;
-		}
-		sp->lzw_maxcode = MAXCODE(BITS_MIN);
-#else /* !LZW_COMPAT */
-		if (!sp->dec_decode) {
-			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			    "Old-style LZW codes not supported");
-			sp->dec_decode = LZWDecode;
-		}
-		return (0);
-#endif/* !LZW_COMPAT */
-	} else {
-		sp->lzw_maxcode = MAXCODE(BITS_MIN)-1;
-		sp->dec_decode = LZWDecode;
-	}
-	sp->lzw_nbits = BITS_MIN;
-	sp->lzw_nextbits = 0;
-	sp->lzw_nextdata = 0;
-
-	sp->dec_restart = 0;
-	sp->dec_nbitsmask = MAXCODE(BITS_MIN);
-#ifdef LZW_CHECKEOS
-	sp->dec_bitsleft = tif->tif_rawcc << 3;
-#endif
-	sp->dec_free_entp = sp->dec_codetab + CODE_FIRST;
-	/*
-	 * Zero entries that are not yet filled in.  We do
-	 * this to guard against bogus input data that causes
-	 * us to index into undefined entries.  If you can
-	 * come up with a way to safely bounds-check input codes
-	 * while decoding then you can remove this operation.
-	 */
-	_TIFFmemset(sp->dec_free_entp, 0, (CSIZE-CODE_FIRST)*sizeof (code_t));
-	sp->dec_oldcodep = &sp->dec_codetab[-1];
-	sp->dec_maxcodep = &sp->dec_codetab[sp->dec_nbitsmask-1];
-	return (1);
-}
-
-/*
- * Decode a "hunk of data".
- */
-#define	GetNextCode(sp, bp, code) {				\
-	nextdata = (nextdata<<8) | *(bp)++;			\
-	nextbits += 8;						\
-	if (nextbits < nbits) {					\
-		nextdata = (nextdata<<8) | *(bp)++;		\
-		nextbits += 8;					\
-	}							\
-	code = (hcode_t)((nextdata >> (nextbits-nbits)) & nbitsmask);	\
-	nextbits -= nbits;					\
-}
-
-static void
-codeLoop(TIFF* tif)
-{
-	TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-	    "LZWDecode: Bogus encoding, loop in the code table; scanline %d",
-	    tif->tif_row);
-}
-
-static int
-LZWDecode(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s)
-{
-	LZWCodecState *sp = DecoderState(tif);
-	char *op = (char*) op0;
-	long occ = (long) occ0;
-	char *tp;
-	unsigned char *bp;
-	hcode_t code;
-	int len;
-	long nbits, nextbits, nextdata, nbitsmask;
-	code_t *codep, *free_entp, *maxcodep, *oldcodep;
-
-	(void) s;
-	assert(sp != NULL);
-        assert(sp->dec_codetab != NULL);
-	/*
-	 * Restart interrupted output operation.
-	 */
-	if (sp->dec_restart) {
-		long residue;
-
-		codep = sp->dec_codep;
-		residue = codep->length - sp->dec_restart;
-		if (residue > occ) {
-			/*
-			 * Residue from previous decode is sufficient
-			 * to satisfy decode request.  Skip to the
-			 * start of the decoded string, place decoded
-			 * values in the output buffer, and return.
-			 */
-			sp->dec_restart += occ;
-			do {
-				codep = codep->next;
-			} while (--residue > occ && codep);
-			if (codep) {
-				tp = op + occ;
-				do {
-					*--tp = codep->value;
-					codep = codep->next;
-				} while (--occ && codep);
-			}
-			return (1);
-		}
-		/*
-		 * Residue satisfies only part of the decode request.
-		 */
-		op += residue, occ -= residue;
-		tp = op;
-		do {
-			int t;
-			--tp;
-			t = codep->value;
-			codep = codep->next;
-			*tp = t;
-		} while (--residue && codep);
-		sp->dec_restart = 0;
-	}
-
-	bp = (unsigned char *)tif->tif_rawcp;
-	nbits = sp->lzw_nbits;
-	nextdata = sp->lzw_nextdata;
-	nextbits = sp->lzw_nextbits;
-	nbitsmask = sp->dec_nbitsmask;
-	oldcodep = sp->dec_oldcodep;
-	free_entp = sp->dec_free_entp;
-	maxcodep = sp->dec_maxcodep;
-
-	while (occ > 0) {
-		NextCode(tif, sp, bp, code, GetNextCode);
-		if (code == CODE_EOI)
-			break;
-		if (code == CODE_CLEAR) {
-			free_entp = sp->dec_codetab + CODE_FIRST;
-			_TIFFmemset(free_entp, 0,
-				    (CSIZE - CODE_FIRST) * sizeof (code_t));
-			nbits = BITS_MIN;
-			nbitsmask = MAXCODE(BITS_MIN);
-			maxcodep = sp->dec_codetab + nbitsmask-1;
-			NextCode(tif, sp, bp, code, GetNextCode);
-			if (code == CODE_EOI)
-				break;
-			if (code == CODE_CLEAR) {
-				TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-				"LZWDecode: Corrupted LZW table at scanline %d",
-					     tif->tif_row);
-				return (0);
-			}
-			*op++ = (char)code, occ--;
-			oldcodep = sp->dec_codetab + code;
-			continue;
-		}
-		codep = sp->dec_codetab + code;
-
-		/*
-	 	 * Add the new entry to the code table.
-	 	 */
-		if (free_entp < &sp->dec_codetab[0] ||
-			free_entp >= &sp->dec_codetab[CSIZE]) {
-			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			"LZWDecode: Corrupted LZW table at scanline %d",
-			tif->tif_row);
-			return (0);
-		}
-
-		free_entp->next = oldcodep;
-		if (free_entp->next < &sp->dec_codetab[0] ||
-			free_entp->next >= &sp->dec_codetab[CSIZE]) {
-			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			"LZWDecode: Corrupted LZW table at scanline %d",
-			tif->tif_row);
-			return (0);
-		}
-		free_entp->firstchar = free_entp->next->firstchar;
-		free_entp->length = free_entp->next->length+1;
-		free_entp->value = (codep < free_entp) ?
-		    codep->firstchar : free_entp->firstchar;
-		if (++free_entp > maxcodep) {
-			if (++nbits > BITS_MAX)		/* should not happen */
-				nbits = BITS_MAX;
-			nbitsmask = MAXCODE(nbits);
-			maxcodep = sp->dec_codetab + nbitsmask-1;
-		}
-		oldcodep = codep;
-		if (code >= 256) {
-			/*
-		 	 * Code maps to a string, copy string
-			 * value to output (written in reverse).
-		 	 */
-			if(codep->length == 0) {
-				TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-	    		    "LZWDecode: Wrong length of decoded string: "
-			    "data probably corrupted at scanline %d",
-			    tif->tif_row);	
-			    return (0);
-			}
-			if (codep->length > occ) {
-				/*
-				 * String is too long for decode buffer,
-				 * locate portion that will fit, copy to
-				 * the decode buffer, and setup restart
-				 * logic for the next decoding call.
-				 */
-				sp->dec_codep = codep;
-				do {
-					codep = codep->next;
-				} while (codep && codep->length > occ);
-				if (codep) {
-					sp->dec_restart = occ;
-					tp = op + occ;
-					do  {
-						*--tp = codep->value;
-						codep = codep->next;
-					}  while (--occ && codep);
-					if (codep)
-						codeLoop(tif);
-				}
-				break;
-			}
-			len = codep->length;
-			tp = op + len;
-			do {
-				int t;
-				--tp;
-				t = codep->value;
-				codep = codep->next;
-				*tp = t;
-			} while (codep && tp > op);
-			if (codep) {
-			    codeLoop(tif);
-			    break;
-			}
-			op += len, occ -= len;
-		} else
-			*op++ = (char)code, occ--;
-	}
-
-	tif->tif_rawcp = (tidata_t) bp;
-	sp->lzw_nbits = (unsigned short) nbits;
-	sp->lzw_nextdata = nextdata;
-	sp->lzw_nextbits = nextbits;
-	sp->dec_nbitsmask = nbitsmask;
-	sp->dec_oldcodep = oldcodep;
-	sp->dec_free_entp = free_entp;
-	sp->dec_maxcodep = maxcodep;
-
-	if (occ > 0) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-		"LZWDecode: Not enough data at scanline %d (short %ld bytes)",
-		    tif->tif_row, occ);
-		return (0);
-	}
-	return (1);
-}
-
-#ifdef LZW_COMPAT
-/*
- * Decode a "hunk of data" for old images.
- */
-#define	GetNextCodeCompat(sp, bp, code) {			\
-	nextdata |= (unsigned long) *(bp)++ << nextbits;	\
-	nextbits += 8;						\
-	if (nextbits < nbits) {					\
-		nextdata |= (unsigned long) *(bp)++ << nextbits;\
-		nextbits += 8;					\
-	}							\
-	code = (hcode_t)(nextdata & nbitsmask);			\
-	nextdata >>= nbits;					\
-	nextbits -= nbits;					\
-}
-
-static int
-LZWDecodeCompat(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s)
-{
-	LZWCodecState *sp = DecoderState(tif);
-	char *op = (char*) op0;
-	long occ = (long) occ0;
-	char *tp;
-	unsigned char *bp;
-	int code, nbits;
-	long nextbits, nextdata, nbitsmask;
-	code_t *codep, *free_entp, *maxcodep, *oldcodep;
-
-	(void) s;
-	assert(sp != NULL);
-	/*
-	 * Restart interrupted output operation.
-	 */
-	if (sp->dec_restart) {
-		long residue;
-
-		codep = sp->dec_codep;
-		residue = codep->length - sp->dec_restart;
-		if (residue > occ) {
-			/*
-			 * Residue from previous decode is sufficient
-			 * to satisfy decode request.  Skip to the
-			 * start of the decoded string, place decoded
-			 * values in the output buffer, and return.
-			 */
-			sp->dec_restart += occ;
-			do {
-				codep = codep->next;
-			} while (--residue > occ);
-			tp = op + occ;
-			do {
-				*--tp = codep->value;
-				codep = codep->next;
-			} while (--occ);
-			return (1);
-		}
-		/*
-		 * Residue satisfies only part of the decode request.
-		 */
-		op += residue, occ -= residue;
-		tp = op;
-		do {
-			*--tp = codep->value;
-			codep = codep->next;
-		} while (--residue);
-		sp->dec_restart = 0;
-	}
-
-	bp = (unsigned char *)tif->tif_rawcp;
-	nbits = sp->lzw_nbits;
-	nextdata = sp->lzw_nextdata;
-	nextbits = sp->lzw_nextbits;
-	nbitsmask = sp->dec_nbitsmask;
-	oldcodep = sp->dec_oldcodep;
-	free_entp = sp->dec_free_entp;
-	maxcodep = sp->dec_maxcodep;
-
-	while (occ > 0) {
-		NextCode(tif, sp, bp, code, GetNextCodeCompat);
-		if (code == CODE_EOI)
-			break;
-		if (code == CODE_CLEAR) {
-			free_entp = sp->dec_codetab + CODE_FIRST;
-			_TIFFmemset(free_entp, 0,
-				    (CSIZE - CODE_FIRST) * sizeof (code_t));
-			nbits = BITS_MIN;
-			nbitsmask = MAXCODE(BITS_MIN);
-			maxcodep = sp->dec_codetab + nbitsmask;
-			NextCode(tif, sp, bp, code, GetNextCodeCompat);
-			if (code == CODE_EOI)
-				break;
-			if (code == CODE_CLEAR) {
-				TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-				"LZWDecode: Corrupted LZW table at scanline %d",
-					     tif->tif_row);
-				return (0);
-			}
-			*op++ = code, occ--;
-			oldcodep = sp->dec_codetab + code;
-			continue;
-		}
-		codep = sp->dec_codetab + code;
-
-		/*
-	 	 * Add the new entry to the code table.
-	 	 */
-		if (free_entp < &sp->dec_codetab[0] ||
-			free_entp >= &sp->dec_codetab[CSIZE]) {
-			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			"LZWDecodeCompat: Corrupted LZW table at scanline %d",
-			tif->tif_row);
-			return (0);
-		}
-
-		free_entp->next = oldcodep;
-		if (free_entp->next < &sp->dec_codetab[0] ||
-			free_entp->next >= &sp->dec_codetab[CSIZE]) {
-			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			"LZWDecodeCompat: Corrupted LZW table at scanline %d",
-			tif->tif_row);
-			return (0);
-		}
-		free_entp->firstchar = free_entp->next->firstchar;
-		free_entp->length = free_entp->next->length+1;
-		free_entp->value = (codep < free_entp) ?
-		    codep->firstchar : free_entp->firstchar;
-		if (++free_entp > maxcodep) {
-			if (++nbits > BITS_MAX)		/* should not happen */
-				nbits = BITS_MAX;
-			nbitsmask = MAXCODE(nbits);
-			maxcodep = sp->dec_codetab + nbitsmask;
-		}
-		oldcodep = codep;
-		if (code >= 256) {
-			char *op_orig = op;
-			/*
-		 	 * Code maps to a string, copy string
-			 * value to output (written in reverse).
-		 	 */
-			if(codep->length == 0) {
-				TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-	    		    "LZWDecodeCompat: Wrong length of decoded "
-			    "string: data probably corrupted at scanline %d",
-			    tif->tif_row);	
-			    return (0);
-			}
-			if (codep->length > occ) {
-				/*
-				 * String is too long for decode buffer,
-				 * locate portion that will fit, copy to
-				 * the decode buffer, and setup restart
-				 * logic for the next decoding call.
-				 */
-				sp->dec_codep = codep;
-				do {
-					codep = codep->next;
-				} while (codep->length > occ);
-				sp->dec_restart = occ;
-				tp = op + occ;
-				do  {
-					*--tp = codep->value;
-					codep = codep->next;
-				}  while (--occ);
-				break;
-			}
-			op += codep->length, occ -= codep->length;
-			tp = op;
-			do {
-				*--tp = codep->value;
-			} while( (codep = codep->next) != NULL && tp > op_orig);
-		} else
-			*op++ = code, occ--;
-	}
-
-	tif->tif_rawcp = (tidata_t) bp;
-	sp->lzw_nbits = nbits;
-	sp->lzw_nextdata = nextdata;
-	sp->lzw_nextbits = nextbits;
-	sp->dec_nbitsmask = nbitsmask;
-	sp->dec_oldcodep = oldcodep;
-	sp->dec_free_entp = free_entp;
-	sp->dec_maxcodep = maxcodep;
-
-	if (occ > 0) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-	    "LZWDecodeCompat: Not enough data at scanline %d (short %ld bytes)",
-		    tif->tif_row, occ);
-		return (0);
-	}
-	return (1);
-}
-#endif /* LZW_COMPAT */
-
-/*
- * LZW Encoding.
- */
-
-static int
-LZWSetupEncode(TIFF* tif)
-{
-	LZWCodecState* sp = EncoderState(tif);
-	static const char module[] = "LZWSetupEncode";
-
-	assert(sp != NULL);
-	sp->enc_hashtab = (hash_t*) _TIFFmalloc(HSIZE*sizeof (hash_t));
-	if (sp->enc_hashtab == NULL) {
-		TIFFErrorExt(tif->tif_clientdata, module, "No space for LZW hash table");
-		return (0);
-	}
-	return (1);
-}
-
-/*
- * Reset encoding state at the start of a strip.
- */
-static int
-LZWPreEncode(TIFF* tif, tsample_t s)
-{
-	LZWCodecState *sp = EncoderState(tif);
-
-	(void) s;
-	assert(sp != NULL);
-        
-        if( sp->enc_hashtab == NULL )
-        {
-            tif->tif_setupencode( tif );
-        }
-
-	sp->lzw_nbits = BITS_MIN;
-	sp->lzw_maxcode = MAXCODE(BITS_MIN);
-	sp->lzw_free_ent = CODE_FIRST;
-	sp->lzw_nextbits = 0;
-	sp->lzw_nextdata = 0;
-	sp->enc_checkpoint = CHECK_GAP;
-	sp->enc_ratio = 0;
-	sp->enc_incount = 0;
-	sp->enc_outcount = 0;
-	/*
-	 * The 4 here insures there is space for 2 max-sized
-	 * codes in LZWEncode and LZWPostDecode.
-	 */
-	sp->enc_rawlimit = tif->tif_rawdata + tif->tif_rawdatasize-1 - 4;
-	cl_hash(sp);		/* clear hash table */
-	sp->enc_oldcode = (hcode_t) -1;	/* generates CODE_CLEAR in LZWEncode */
-	return (1);
-}
-
-#define	CALCRATIO(sp, rat) {					\
-	if (incount > 0x007fffff) { /* NB: shift will overflow */\
-		rat = outcount >> 8;				\
-		rat = (rat == 0 ? 0x7fffffff : incount/rat);	\
-	} else							\
-		rat = (incount<<8) / outcount;			\
-}
-#define	PutNextCode(op, c) {					\
-	nextdata = (nextdata << nbits) | c;			\
-	nextbits += nbits;					\
-	*op++ = (unsigned char)(nextdata >> (nextbits-8));		\
-	nextbits -= 8;						\
-	if (nextbits >= 8) {					\
-		*op++ = (unsigned char)(nextdata >> (nextbits-8));	\
-		nextbits -= 8;					\
-	}							\
-	outcount += nbits;					\
-}
-
-/*
- * Encode a chunk of pixels.
- *
- * Uses an open addressing double hashing (no chaining) on the 
- * prefix code/next character combination.  We do a variant of
- * Knuth's algorithm D (vol. 3, sec. 6.4) along with G. Knott's
- * relatively-prime secondary probe.  Here, the modular division
- * first probe is gives way to a faster exclusive-or manipulation. 
- * Also do block compression with an adaptive reset, whereby the
- * code table is cleared when the compression ratio decreases,
- * but after the table fills.  The variable-length output codes
- * are re-sized at this point, and a CODE_CLEAR is generated
- * for the decoder. 
- */
-static int
-LZWEncode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s)
-{
-	register LZWCodecState *sp = EncoderState(tif);
-	register long fcode;
-	register hash_t *hp;
-	register int h, c;
-	hcode_t ent;
-	long disp;
-	long incount, outcount, checkpoint;
-	long nextdata, nextbits;
-	int free_ent, maxcode, nbits;
-	tidata_t op, limit;
-
-	(void) s;
-	if (sp == NULL)
-		return (0);
-
-        assert(sp->enc_hashtab != NULL);
-
-	/*
-	 * Load local state.
-	 */
-	incount = sp->enc_incount;
-	outcount = sp->enc_outcount;
-	checkpoint = sp->enc_checkpoint;
-	nextdata = sp->lzw_nextdata;
-	nextbits = sp->lzw_nextbits;
-	free_ent = sp->lzw_free_ent;
-	maxcode = sp->lzw_maxcode;
-	nbits = sp->lzw_nbits;
-	op = tif->tif_rawcp;
-	limit = sp->enc_rawlimit;
-	ent = sp->enc_oldcode;
-
-	if (ent == (hcode_t) -1 && cc > 0) {
-		/*
-		 * NB: This is safe because it can only happen
-		 *     at the start of a strip where we know there
-		 *     is space in the data buffer.
-		 */
-		PutNextCode(op, CODE_CLEAR);
-		ent = *bp++; cc--; incount++;
-	}
-	while (cc > 0) {
-		c = *bp++; cc--; incount++;
-		fcode = ((long)c << BITS_MAX) + ent;
-		h = (c << HSHIFT) ^ ent;	/* xor hashing */
-#ifdef _WINDOWS
-		/*
-		 * Check hash index for an overflow.
-		 */
-		if (h >= HSIZE)
-			h -= HSIZE;
-#endif
-		hp = &sp->enc_hashtab[h];
-		if (hp->hash == fcode) {
-			ent = hp->code;
-			continue;
-		}
-		if (hp->hash >= 0) {
-			/*
-			 * Primary hash failed, check secondary hash.
-			 */
-			disp = HSIZE - h;
-			if (h == 0)
-				disp = 1;
-			do {
-				/*
-				 * Avoid pointer arithmetic 'cuz of
-				 * wraparound problems with segments.
-				 */
-				if ((h -= disp) < 0)
-					h += HSIZE;
-				hp = &sp->enc_hashtab[h];
-				if (hp->hash == fcode) {
-					ent = hp->code;
-					goto hit;
-				}
-			} while (hp->hash >= 0);
-		}
-		/*
-		 * New entry, emit code and add to table.
-		 */
-		/*
-		 * Verify there is space in the buffer for the code
-		 * and any potential Clear code that might be emitted
-		 * below.  The value of limit is setup so that there
-		 * are at least 4 bytes free--room for 2 codes.
-		 */
-		if (op > limit) {
-			tif->tif_rawcc = (tsize_t)(op - tif->tif_rawdata);
-			TIFFFlushData1(tif);
-			op = tif->tif_rawdata;
-		}
-		PutNextCode(op, ent);
-		ent = c;
-		hp->code = free_ent++;
-		hp->hash = fcode;
-		if (free_ent == CODE_MAX-1) {
-			/* table is full, emit clear code and reset */
-			cl_hash(sp);
-			sp->enc_ratio = 0;
-			incount = 0;
-			outcount = 0;
-			free_ent = CODE_FIRST;
-			PutNextCode(op, CODE_CLEAR);
-			nbits = BITS_MIN;
-			maxcode = MAXCODE(BITS_MIN);
-		} else {
-			/*
-			 * If the next entry is going to be too big for
-			 * the code size, then increase it, if possible.
-			 */
-			if (free_ent > maxcode) {
-				nbits++;
-				assert(nbits <= BITS_MAX);
-				maxcode = (int) MAXCODE(nbits);
-			} else if (incount >= checkpoint) {
-				long rat;
-				/*
-				 * Check compression ratio and, if things seem
-				 * to be slipping, clear the hash table and
-				 * reset state.  The compression ratio is a
-				 * 24+8-bit fractional number.
-				 */
-				checkpoint = incount+CHECK_GAP;
-				CALCRATIO(sp, rat);
-				if (rat <= sp->enc_ratio) {
-					cl_hash(sp);
-					sp->enc_ratio = 0;
-					incount = 0;
-					outcount = 0;
-					free_ent = CODE_FIRST;
-					PutNextCode(op, CODE_CLEAR);
-					nbits = BITS_MIN;
-					maxcode = MAXCODE(BITS_MIN);
-				} else
-					sp->enc_ratio = rat;
-			}
-		}
-	hit:
-		;
-	}
-
-	/*
-	 * Restore global state.
-	 */
-	sp->enc_incount = incount;
-	sp->enc_outcount = outcount;
-	sp->enc_checkpoint = checkpoint;
-	sp->enc_oldcode = ent;
-	sp->lzw_nextdata = nextdata;
-	sp->lzw_nextbits = nextbits;
-	sp->lzw_free_ent = free_ent;
-	sp->lzw_maxcode = maxcode;
-	sp->lzw_nbits = nbits;
-	tif->tif_rawcp = op;
-	return (1);
-}
-
-/*
- * Finish off an encoded strip by flushing the last
- * string and tacking on an End Of Information code.
- */
-static int
-LZWPostEncode(TIFF* tif)
-{
-	register LZWCodecState *sp = EncoderState(tif);
-	tidata_t op = tif->tif_rawcp;
-	long nextbits = sp->lzw_nextbits;
-	long nextdata = sp->lzw_nextdata;
-	long outcount = sp->enc_outcount;
-	int nbits = sp->lzw_nbits;
-
-	if (op > sp->enc_rawlimit) {
-		tif->tif_rawcc = (tsize_t)(op - tif->tif_rawdata);
-		TIFFFlushData1(tif);
-		op = tif->tif_rawdata;
-	}
-	if (sp->enc_oldcode != (hcode_t) -1) {
-		PutNextCode(op, sp->enc_oldcode);
-		sp->enc_oldcode = (hcode_t) -1;
-	}
-	PutNextCode(op, CODE_EOI);
-	if (nextbits > 0) 
-		*op++ = (unsigned char)(nextdata << (8-nextbits));
-	tif->tif_rawcc = (tsize_t)(op - tif->tif_rawdata);
-	return (1);
-}
-
-/*
- * Reset encoding hash table.
- */
-static void
-cl_hash(LZWCodecState* sp)
-{
-	register hash_t *hp = &sp->enc_hashtab[HSIZE-1];
-	register long i = HSIZE-8;
-
- 	do {
-		i -= 8;
-		hp[-7].hash = -1;
-		hp[-6].hash = -1;
-		hp[-5].hash = -1;
-		hp[-4].hash = -1;
-		hp[-3].hash = -1;
-		hp[-2].hash = -1;
-		hp[-1].hash = -1;
-		hp[ 0].hash = -1;
-		hp -= 8;
-	} while (i >= 0);
-    	for (i += 8; i > 0; i--, hp--)
-		hp->hash = -1;
-}
-
-static void
-LZWCleanup(TIFF* tif)
-{
-	(void)TIFFPredictorCleanup(tif);
-
-	assert(tif->tif_data != 0);
-
-	if (DecoderState(tif)->dec_codetab)
-		_TIFFfree(DecoderState(tif)->dec_codetab);
-
-	if (EncoderState(tif)->enc_hashtab)
-		_TIFFfree(EncoderState(tif)->enc_hashtab);
-
-	_TIFFfree(tif->tif_data);
-	tif->tif_data = NULL;
-
-	_TIFFSetDefaultCompressionState(tif);
-}
-
-int
-TIFFInitLZW(TIFF* tif, int scheme)
-{
-	assert(scheme == COMPRESSION_LZW);
-	/*
-	 * Allocate state block so tag methods have storage to record values.
-	 */
-	tif->tif_data = (tidata_t) _TIFFmalloc(sizeof (LZWCodecState));
-	if (tif->tif_data == NULL)
-		goto bad;
-	DecoderState(tif)->dec_codetab = NULL;
-	DecoderState(tif)->dec_decode = NULL;
-	EncoderState(tif)->enc_hashtab = NULL;
-        LZWState(tif)->rw_mode = tif->tif_mode;
-
-	/*
-	 * Install codec methods.
-	 */
-	tif->tif_setupdecode = LZWSetupDecode;
-	tif->tif_predecode = LZWPreDecode;
-	tif->tif_decoderow = LZWDecode;
-	tif->tif_decodestrip = LZWDecode;
-	tif->tif_decodetile = LZWDecode;
-	tif->tif_setupencode = LZWSetupEncode;
-	tif->tif_preencode = LZWPreEncode;
-	tif->tif_postencode = LZWPostEncode;
-	tif->tif_encoderow = LZWEncode;
-	tif->tif_encodestrip = LZWEncode;
-	tif->tif_encodetile = LZWEncode;
-	tif->tif_cleanup = LZWCleanup;
-	/*
-	 * Setup predictor setup.
-	 */
-	(void) TIFFPredictorInit(tif);
-	return (1);
-bad:
-	TIFFErrorExt(tif->tif_clientdata, "TIFFInitLZW", 
-		     "No space for LZW state block");
-	return (0);
-}
-
-/*
- * Copyright (c) 1985, 1986 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * James A. Woods, derived from original work by Spencer Thomas
- * and Joseph Orost.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-#endif /* LZW_SUPPORT */
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_msdos.c b/Source/LibTIFF/tif_msdos.c
deleted file mode 100644
index 884981f..0000000
--- a/Source/LibTIFF/tif_msdos.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/* $Header: /cvsroot/freeimage/FreeImage/Source/LibTIFF/tif_msdos.c,v 1.35 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library MSDOS-specific Routines.
- */
-#if defined(__WATCOMC__) || defined(__BORLANDC__) || defined(_MSC_VER)
-#include <io.h>		/* for open, close, etc. function prototypes */
-#include <stdio.h>
-#endif
-#include "tiffiop.h"
-
-static tsize_t 
-_tiffReadProc(thandle_t fd, tdata_t buf, tsize_t size)
-{
-	return (read((int) fd, buf, size));
-}
-
-static tsize_t
-_tiffWriteProc(thandle_t fd, tdata_t buf, tsize_t size)
-{
-	return (write((int) fd, buf, size));
-}
-
-static toff_t
-_tiffSeekProc(thandle_t fd, toff_t off, int whence)
-{
-	return (lseek((int) fd, (off_t) off, whence));
-}
-
-static int
-_tiffCloseProc(thandle_t fd)
-{
-	return (close((int) fd));
-}
-
-#include <sys/stat.h>
-
-static toff_t
-_tiffSizeProc(thandle_t fd)
-{
-	struct stat sb;
-	return (fstat((int) fd, &sb) < 0 ? 0 : sb.st_size);
-}
-
-static int
-_tiffMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize)
-{
-	return (0);
-}
-
-static void
-_tiffUnmapProc(thandle_t fd, tdata_t base, toff_t size)
-{
-}
-
-/*
- * Open a TIFF file descriptor for read/writing.
- */
-TIFF*
-TIFFFdOpen(int fd, const char* name, const char* mode)
-{
-	TIFF* tif;
-
-	tif = TIFFClientOpen(name, mode,
-	    (void*) fd,
-	    _tiffReadProc, _tiffWriteProc, _tiffSeekProc, _tiffCloseProc,
-	    _tiffSizeProc, _tiffMapProc, _tiffUnmapProc);
-	if (tif)
-		tif->tif_fd = fd;
-	return (tif);
-}
-
-/*
- * Open a TIFF file for read/writing.
- */
-TIFF*
-TIFFOpen(const char* name, const char* mode)
-{
-	static const char module[] = "TIFFOpen";
-	int m, fd;
-        TIFF *ret;
-
-	m = _TIFFgetMode(mode, module);
-	if (m == -1)
-		return ((TIFF*)0);
-	fd = open(name, m|O_BINARY, 0666);
-	if (fd < 0) {
-		TIFFErrorExt(0, module, "%s: Cannot open", name);
-		return ((TIFF*)0);
-	}
-	return (TIFFFdOpen(fd, name, mode));
-
-        ret = TIFFFdOpen(fd, name, mode);
-
-        if (ret == NULL) close(fd);
-
-        return ret;
-}
-
-#ifdef __GNUC__
-extern	char* malloc();
-extern	char* realloc();
-#else
-#include <malloc.h>
-#endif
-
-tdata_t
-_TIFFmalloc(tsize_t s)
-{
-	return (malloc((size_t) s));
-}
-
-void
-_TIFFfree(tdata_t p)
-{
-	free(p);
-}
-
-tdata_t
-_TIFFrealloc(tdata_t p, tsize_t s)
-{
-	return (realloc(p, (size_t) s));
-}
-
-void
-_TIFFmemset(tdata_t p, int v, tsize_t c)
-{
-	memset(p, v, (size_t) c);
-}
-
-void
-_TIFFmemcpy(tdata_t d, const tdata_t s, tsize_t c)
-{
-	memcpy(d, s, (size_t) c);
-}
-
-int
-_TIFFmemcmp(const tdata_t p1, const tdata_t p2, tsize_t c)
-{
-	return (memcmp(p1, p2, (size_t) c));
-}
-
-static void
-msdosWarningHandler(const char* module, const char* fmt, va_list ap)
-{
-	if (module != NULL)
-		fprintf(stderr, "%s: ", module);
-	fprintf(stderr, "Warning, ");
-	vfprintf(stderr, fmt, ap);
-	fprintf(stderr, ".\n");
-}
-TIFFErrorHandler _TIFFwarningHandler = msdosWarningHandler;
-
-static void
-msdosErrorHandler(const char* module, const char* fmt, va_list ap)
-{
-	if (module != NULL)
-		fprintf(stderr, "%s: ", module);
-	vfprintf(stderr, fmt, ap);
-	fprintf(stderr, ".\n");
-}
-TIFFErrorHandler _TIFFerrorHandler = msdosErrorHandler;
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_next.c b/Source/LibTIFF/tif_next.c
deleted file mode 100644
index 06efefd..0000000
--- a/Source/LibTIFF/tif_next.c
+++ /dev/null
@@ -1,154 +0,0 @@
-/* $Id: tif_next.c,v 1.37 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-#include "tiffiop.h"
-#ifdef NEXT_SUPPORT
-/*
- * TIFF Library.
- *
- * NeXT 2-bit Grey Scale Compression Algorithm Support
- */
-
-#define SETPIXEL(op, v) {			\
-	switch (npixels++ & 3) {		\
-	case 0:	op[0]  = (unsigned char) ((v) << 6); break;	\
-	case 1:	op[0] |= (v) << 4; break;	\
-	case 2:	op[0] |= (v) << 2; break;	\
-	case 3:	*op++ |= (v);	   break;	\
-	}					\
-}
-
-#define LITERALROW	0x00
-#define LITERALSPAN	0x40
-#define WHITE   	((1<<2)-1)
-
-static int
-NeXTDecode(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s)
-{
-	unsigned char *bp, *op;
-	tsize_t cc;
-	tidata_t row;
-	tsize_t scanline, n;
-
-	(void) s;
-	/*
-	 * Each scanline is assumed to start off as all
-	 * white (we assume a PhotometricInterpretation
-	 * of ``min-is-black'').
-	 */
-	for (op = buf, cc = occ; cc-- > 0;)
-		*op++ = 0xff;
-
-	bp = (unsigned char *)tif->tif_rawcp;
-	cc = tif->tif_rawcc;
-	scanline = tif->tif_scanlinesize;
-	for (row = buf; occ > 0; occ -= scanline, row += scanline) {
-		n = *bp++, cc--;
-		switch (n) {
-		case LITERALROW:
-			/*
-			 * The entire scanline is given as literal values.
-			 */
-			if (cc < scanline)
-				goto bad;
-			_TIFFmemcpy(row, bp, scanline);
-			bp += scanline;
-			cc -= scanline;
-			break;
-		case LITERALSPAN: {
-			tsize_t off;
-			/*
-			 * The scanline has a literal span that begins at some
-			 * offset.
-			 */
-			off = (bp[0] * 256) + bp[1];
-			n = (bp[2] * 256) + bp[3];
-			if (cc < 4+n || off+n > scanline)
-				goto bad;
-			_TIFFmemcpy(row+off, bp+4, n);
-			bp += 4+n;
-			cc -= 4+n;
-			break;
-		}
-		default: {
-			uint32 npixels = 0, grey;
-			uint32 imagewidth = tif->tif_dir.td_imagewidth;
-
-			/*
-			 * The scanline is composed of a sequence of constant
-			 * color ``runs''.  We shift into ``run mode'' and
-			 * interpret bytes as codes of the form
-			 * <color><npixels> until we've filled the scanline.
-			 */
-			op = row;
-			for (;;) {
-				grey = (n>>6) & 0x3;
-				n &= 0x3f;
-				/*
-				 * Ensure the run does not exceed the scanline
-				 * bounds, potentially resulting in a security
-				 * issue.
-				 */
-				while (n-- > 0 && npixels < imagewidth)
-					SETPIXEL(op, grey);
-				if (npixels >= imagewidth)
-					break;
-				if (cc == 0)
-					goto bad;
-				n = *bp++, cc--;
-			}
-			break;
-		}
-		}
-	}
-	tif->tif_rawcp = (tidata_t) bp;
-	tif->tif_rawcc = cc;
-	return (1);
-bad:
-	TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "NeXTDecode: Not enough data for scanline %ld",
-	    (long) tif->tif_row);
-	return (0);
-}
-
-int
-TIFFInitNeXT(TIFF* tif, int scheme)
-{
-	(void) scheme;
-	tif->tif_decoderow = NeXTDecode;
-	tif->tif_decodestrip = NeXTDecode;
-	tif->tif_decodetile = NeXTDecode;
-	return (1);
-}
-#endif /* NEXT_SUPPORT */
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_ojpeg.c b/Source/LibTIFF/tif_ojpeg.c
deleted file mode 100644
index 0cd70e9..0000000
--- a/Source/LibTIFF/tif_ojpeg.c
+++ /dev/null
@@ -1,2448 +0,0 @@
-/* $Id: tif_ojpeg.c,v 1.36 2011/04/10 17:14:09 drolon Exp $ */
-
-/* WARNING: The type of JPEG encapsulation defined by the TIFF Version 6.0
-   specification is now totally obsolete and deprecated for new applications and
-   images. This file was was created solely in order to read unconverted images
-   still present on some users' computer systems. It will never be extended
-   to write such files. Writing new-style JPEG compressed TIFFs is implemented
-   in tif_jpeg.c.
-
-   The code is carefully crafted to robustly read all gathered JPEG-in-TIFF
-   testfiles, and anticipate as much as possible all other... But still, it may
-   fail on some. If you encounter problems, please report them on the TIFF
-   mailing list and/or to Joris Van Damme <info at awaresystems.be>.
-
-   Please read the file called "TIFF Technical Note #2" if you need to be
-   convinced this compression scheme is bad and breaks TIFF. That document
-   is linked to from the LibTiff site <http://www.remotesensing.org/libtiff/>
-   and from AWare Systems' TIFF section
-   <http://www.awaresystems.be/imaging/tiff.html>. It is also absorbed
-   in Adobe's specification supplements, marked "draft" up to this day, but
-   supported by the TIFF community.
-
-   This file interfaces with Release 6B of the JPEG Library written by the
-   Independent JPEG Group. Previous versions of this file required a hack inside
-   the LibJpeg library. This version no longer requires that. Remember to
-   remove the hack if you update from the old version.
-
-   Copyright (c) Joris Van Damme <info at awaresystems.be>
-   Copyright (c) AWare Systems <http://www.awaresystems.be/>
-
-   The licence agreement for this file is the same as the rest of the LibTiff
-   library.
-
-   IN NO EVENT SHALL JORIS VAN DAMME OR AWARE SYSTEMS BE LIABLE FOR
-   ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
-   OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-   WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
-   LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
-   OF THIS SOFTWARE.
-
-   Joris Van Damme and/or AWare Systems may be available for custom
-   developement. If you like what you see, and need anything similar or related,
-   contact <info at awaresystems.be>.
-*/
-
-/* What is what, and what is not?
-
-   This decoder starts with an input stream, that is essentially the JpegInterchangeFormat
-   stream, if any, followed by the strile data, if any. This stream is read in
-   OJPEGReadByte and related functions.
-
-   It analyzes the start of this stream, until it encounters non-marker data, i.e.
-   compressed image data. Some of the header markers it sees have no actual content,
-   like the SOI marker, and APP/COM markers that really shouldn't even be there. Some
-   other markers do have content, and the valuable bits and pieces of information
-   in these markers are saved, checking all to verify that the stream is more or
-   less within expected bounds. This happens inside the OJPEGReadHeaderInfoSecStreamXxx
-   functions.
-
-   Some OJPEG imagery contains no valid JPEG header markers. This situation is picked
-   up on if we've seen no SOF marker when we're at the start of the compressed image
-   data. In this case, the tables are read from JpegXxxTables tags, and the other
-   bits and pieces of information is initialized to its most basic value. This is
-   implemented in the OJPEGReadHeaderInfoSecTablesXxx functions.
-
-   When this is complete, a good and valid JPEG header can be assembled, and this is
-   passed through to LibJpeg. When that's done, the remainder of the input stream, i.e.
-   the compressed image data, can be passed through unchanged. This is done in
-   OJPEGWriteStream functions.
-
-   LibTiff rightly expects to know the subsampling values before decompression. Just like
-   in new-style JPEG-in-TIFF, though, or even more so, actually, the YCbCrsubsampling
-   tag is notoriously unreliable. To correct these tag values with the ones inside
-   the JPEG stream, the first part of the input stream is pre-scanned in
-   OJPEGSubsamplingCorrect, making no note of any other data, reporting no warnings
-   or errors, up to the point where either these values are read, or it's clear they
-   aren't there. This means that some of the data is read twice, but we feel speed
-   in correcting these values is important enough to warrant this sacrifice. Allthough
-   there is currently no define or other configuration mechanism to disable this behaviour,
-   the actual header scanning is build to robustly respond with error report if it
-   should encounter an uncorrected mismatch of subsampling values. See
-   OJPEGReadHeaderInfoSecStreamSof.
-
-   The restart interval and restart markers are the most tricky part... The restart
-   interval can be specified in a tag. It can also be set inside the input JPEG stream.
-   It can be used inside the input JPEG stream. If reading from strile data, we've
-   consistenly discovered the need to insert restart markers in between the different
-   striles, as is also probably the most likely interpretation of the original TIFF 6.0
-   specification. With all this setting of interval, and actual use of markers that is not
-   predictable at the time of valid JPEG header assembly, the restart thing may turn
-   out the Achilles heel of this implementation. Fortunately, most OJPEG writer vendors
-   succeed in reading back what they write, which may be the reason why we've been able
-   to discover ways that seem to work.
-
-   Some special provision is made for planarconfig separate OJPEG files. These seem
-   to consistently contain header info, a SOS marker, a plane, SOS marker, plane, SOS,
-   and plane. This may or may not be a valid JPEG configuration, we don't know and don't
-   care. We want LibTiff to be able to access the planes individually, without huge
-   buffering inside LibJpeg, anyway. So we compose headers to feed to LibJpeg, in this
-   case, that allow us to pass a single plane such that LibJpeg sees a valid
-   single-channel JPEG stream. Locating subsequent SOS markers, and thus subsequent
-   planes, is done inside OJPEGReadSecondarySos.
-
-   The benefit of the scheme is... that it works, basically. We know of no other that
-   does. It works without checking software tag, or otherwise going about things in an
-   OJPEG flavor specific manner. Instead, it is a single scheme, that covers the cases
-   with and without JpegInterchangeFormat, with and without striles, with part of
-   the header in JpegInterchangeFormat and remainder in first strile, etc. It is forgiving
-   and robust, may likely work with OJPEG flavors we've not seen yet, and makes most out
-   of the data.
-
-   Another nice side-effect is that a complete JPEG single valid stream is build if
-   planarconfig is not separate (vast majority). We may one day use that to build
-   converters to JPEG, and/or to new-style JPEG compression inside TIFF.
-
-   A dissadvantage is the lack of random access to the individual striles. This is the
-   reason for much of the complicated restart-and-position stuff inside OJPEGPreDecode.
-   Applications would do well accessing all striles in order, as this will result in
-   a single sequential scan of the input stream, and no restarting of LibJpeg decoding
-   session.
-*/
-
-
-#include "tiffiop.h"
-#ifdef OJPEG_SUPPORT
-
-/* Configuration defines here are:
- * JPEG_ENCAP_EXTERNAL: The normal way to call libjpeg, uses longjump. In some environments,
- * 	like eg LibTiffDelphi, this is not possible. For this reason, the actual calls to
- * 	libjpeg, with longjump stuff, are encapsulated in dedicated functions. When
- * 	JPEG_ENCAP_EXTERNAL is defined, these encapsulating functions are declared external
- * 	to this unit, and can be defined elsewhere to use stuff other then longjump.
- * 	The default mode, without JPEG_ENCAP_EXTERNAL, implements the call encapsulators
- * 	here, internally, with normal longjump.
- * SETJMP, LONGJMP, JMP_BUF: On some machines/environments a longjump equivalent is
- * 	conviniently available, but still it may be worthwhile to use _setjmp or sigsetjmp
- * 	in place of plain setjmp. These macros will make it easier. It is useless
- * 	to fiddle with these if you define JPEG_ENCAP_EXTERNAL.
- * OJPEG_BUFFER: Define the size of the desired buffer here. Should be small enough so as to guarantee
- * 	instant processing, optimal streaming and optimal use of processor cache, but also big
- * 	enough so as to not result in significant call overhead. It should be at least a few
- * 	bytes to accomodate some structures (this is verified in asserts), but it would not be
- * 	sensible to make it this small anyway, and it should be at most 64K since it is indexed
- * 	with uint16. We recommend 2K.
- * EGYPTIANWALK: You could also define EGYPTIANWALK here, but it is not used anywhere and has
- * 	absolutely no effect. That is why most people insist the EGYPTIANWALK is a bit silly.
- */
-
-/* #define LIBJPEG_ENCAP_EXTERNAL */
-#define SETJMP(jbuf) setjmp(jbuf)
-#define LONGJMP(jbuf,code) longjmp(jbuf,code)
-#define JMP_BUF jmp_buf
-#define OJPEG_BUFFER 2048
-/* define EGYPTIANWALK */
-
-#define JPEG_MARKER_SOF0 0xC0
-#define JPEG_MARKER_SOF1 0xC1
-#define JPEG_MARKER_SOF3 0xC3
-#define JPEG_MARKER_DHT 0xC4
-#define JPEG_MARKER_RST0 0XD0
-#define JPEG_MARKER_SOI 0xD8
-#define JPEG_MARKER_EOI 0xD9
-#define JPEG_MARKER_SOS 0xDA
-#define JPEG_MARKER_DQT 0xDB
-#define JPEG_MARKER_DRI 0xDD
-#define JPEG_MARKER_APP0 0xE0
-#define JPEG_MARKER_COM 0xFE
-
-#define FIELD_OJPEG_JPEGINTERCHANGEFORMAT (FIELD_CODEC+0)
-#define FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH (FIELD_CODEC+1)
-#define FIELD_OJPEG_JPEGQTABLES (FIELD_CODEC+2)
-#define FIELD_OJPEG_JPEGDCTABLES (FIELD_CODEC+3)
-#define FIELD_OJPEG_JPEGACTABLES (FIELD_CODEC+4)
-#define FIELD_OJPEG_JPEGPROC (FIELD_CODEC+5)
-#define FIELD_OJPEG_JPEGRESTARTINTERVAL (FIELD_CODEC+6)
-#define FIELD_OJPEG_COUNT 7
-
-static const TIFFFieldInfo ojpeg_field_info[] = {
-	{TIFFTAG_JPEGIFOFFSET,1,1,TIFF_LONG,FIELD_OJPEG_JPEGINTERCHANGEFORMAT,TRUE,FALSE,"JpegInterchangeFormat"},
-	{TIFFTAG_JPEGIFBYTECOUNT,1,1,TIFF_LONG,FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH,TRUE,FALSE,"JpegInterchangeFormatLength"},
-	{TIFFTAG_JPEGQTABLES,TIFF_VARIABLE,TIFF_VARIABLE,TIFF_LONG,FIELD_OJPEG_JPEGQTABLES,FALSE,TRUE,"JpegQTables"},
-	{TIFFTAG_JPEGDCTABLES,TIFF_VARIABLE,TIFF_VARIABLE,TIFF_LONG,FIELD_OJPEG_JPEGDCTABLES,FALSE,TRUE,"JpegDcTables"},
-	{TIFFTAG_JPEGACTABLES,TIFF_VARIABLE,TIFF_VARIABLE,TIFF_LONG,FIELD_OJPEG_JPEGACTABLES,FALSE,TRUE,"JpegAcTables"},
-	{TIFFTAG_JPEGPROC,1,1,TIFF_SHORT,FIELD_OJPEG_JPEGPROC,FALSE,FALSE,"JpegProc"},
-	{TIFFTAG_JPEGRESTARTINTERVAL,1,1,TIFF_SHORT,FIELD_OJPEG_JPEGRESTARTINTERVAL,FALSE,FALSE,"JpegRestartInterval"},
-};
-
-#ifndef LIBJPEG_ENCAP_EXTERNAL
-#include <setjmp.h>
-#endif
-
-#include "../LibJPEG/jpeglib.h"
-#include "../LibJPEG/jerror.h"
-
-typedef struct jpeg_error_mgr jpeg_error_mgr;
-typedef struct jpeg_common_struct jpeg_common_struct;
-typedef struct jpeg_decompress_struct jpeg_decompress_struct;
-typedef struct jpeg_source_mgr jpeg_source_mgr;
-
-typedef enum {
-	osibsNotSetYet,
-	osibsJpegInterchangeFormat,
-	osibsStrile,
-	osibsEof
-} OJPEGStateInBufferSource;
-
-typedef enum {
-	ososSoi,
-	ososQTable0,ososQTable1,ososQTable2,ososQTable3,
-	ososDcTable0,ososDcTable1,ososDcTable2,ososDcTable3,
-	ososAcTable0,ososAcTable1,ososAcTable2,ososAcTable3,
-	ososDri,
-	ososSof,
-	ososSos,
-	ososCompressed,
-	ososRst,
-	ososEoi
-} OJPEGStateOutState;
-
-typedef struct {
-	TIFF* tif;
-	#ifndef LIBJPEG_ENCAP_EXTERNAL
-	JMP_BUF exit_jmpbuf;
-	#endif
-	TIFFVGetMethod vgetparent;
-	TIFFVSetMethod vsetparent;
-	toff_t file_size;
-	uint32 image_width;
-	uint32 image_length;
-	uint32 strile_width;
-	uint32 strile_length;
-	uint32 strile_length_total;
-	uint8 samples_per_pixel;
-	uint8 plane_sample_offset;
-	uint8 samples_per_pixel_per_plane;
-	toff_t jpeg_interchange_format;
-	toff_t jpeg_interchange_format_length;
-	uint8 jpeg_proc;
-	uint8 subsamplingcorrect;
-	uint8 subsamplingcorrect_done;
-	uint8 subsampling_tag;
-	uint8 subsampling_hor;
-	uint8 subsampling_ver;
-	uint8 subsampling_force_desubsampling_inside_decompression;
-	uint8 qtable_offset_count;
-	uint8 dctable_offset_count;
-	uint8 actable_offset_count;
-	toff_t qtable_offset[3];
-	toff_t dctable_offset[3];
-	toff_t actable_offset[3];
-	uint8* qtable[4];
-	uint8* dctable[4];
-	uint8* actable[4];
-	uint16 restart_interval;
-	uint8 restart_index;
-	uint8 sof_log;
-	uint8 sof_marker_id;
-	uint32 sof_x;
-	uint32 sof_y;
-	uint8 sof_c[3];
-	uint8 sof_hv[3];
-	uint8 sof_tq[3];
-	uint8 sos_cs[3];
-	uint8 sos_tda[3];
-	struct {
-		uint8 log;
-		OJPEGStateInBufferSource in_buffer_source;
-		tstrile_t in_buffer_next_strile;
-		toff_t in_buffer_file_pos;
-		toff_t in_buffer_file_togo;
-	} sos_end[3];
-	uint8 readheader_done;
-	uint8 writeheader_done;
-	tsample_t write_cursample;
-	tstrile_t write_curstrile;
-	uint8 libjpeg_session_active;
-	uint8 libjpeg_jpeg_query_style;
-	jpeg_error_mgr libjpeg_jpeg_error_mgr;
-	jpeg_decompress_struct libjpeg_jpeg_decompress_struct;
-	jpeg_source_mgr libjpeg_jpeg_source_mgr;
-	uint8 subsampling_convert_log;
-	uint32 subsampling_convert_ylinelen;
-	uint32 subsampling_convert_ylines;
-	uint32 subsampling_convert_clinelen;
-	uint32 subsampling_convert_clines;
-	uint32 subsampling_convert_ybuflen;
-	uint32 subsampling_convert_cbuflen;
-	uint32 subsampling_convert_ycbcrbuflen;
-	uint8* subsampling_convert_ycbcrbuf;
-	uint8* subsampling_convert_ybuf;
-	uint8* subsampling_convert_cbbuf;
-	uint8* subsampling_convert_crbuf;
-	uint32 subsampling_convert_ycbcrimagelen;
-	uint8** subsampling_convert_ycbcrimage;
-	uint32 subsampling_convert_clinelenout;
-	uint32 subsampling_convert_state;
-	uint32 bytes_per_line;   /* if the codec outputs subsampled data, a 'line' in bytes_per_line */
-	uint32 lines_per_strile; /* and lines_per_strile means subsampling_ver desubsampled rows     */
-	OJPEGStateInBufferSource in_buffer_source;
-	tstrile_t in_buffer_next_strile;
-	tstrile_t in_buffer_strile_count;
-	toff_t in_buffer_file_pos;
-	uint8 in_buffer_file_pos_log;
-	toff_t in_buffer_file_togo;
-	uint16 in_buffer_togo;
-	uint8* in_buffer_cur;
-	uint8 in_buffer[OJPEG_BUFFER];
-	OJPEGStateOutState out_state;
-	uint8 out_buffer[OJPEG_BUFFER];
-	uint8* skip_buffer;
-} OJPEGState;
-
-static int OJPEGVGetField(TIFF* tif, ttag_t tag, va_list ap);
-static int OJPEGVSetField(TIFF* tif, ttag_t tag, va_list ap);
-static void OJPEGPrintDir(TIFF* tif, FILE* fd, long flags);
-
-static int OJPEGSetupDecode(TIFF* tif);
-static int OJPEGPreDecode(TIFF* tif, tsample_t s);
-static int OJPEGPreDecodeSkipRaw(TIFF* tif);
-static int OJPEGPreDecodeSkipScanlines(TIFF* tif);
-static int OJPEGDecode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s);
-static int OJPEGDecodeRaw(TIFF* tif, tidata_t buf, tsize_t cc);
-static int OJPEGDecodeScanlines(TIFF* tif, tidata_t buf, tsize_t cc);
-static void OJPEGPostDecode(TIFF* tif, tidata_t buf, tsize_t cc);
-static int OJPEGSetupEncode(TIFF* tif);
-static int OJPEGPreEncode(TIFF* tif, tsample_t s);
-static int OJPEGEncode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s);
-static int OJPEGPostEncode(TIFF* tif);
-static void OJPEGCleanup(TIFF* tif);
-
-static void OJPEGSubsamplingCorrect(TIFF* tif);
-static int OJPEGReadHeaderInfo(TIFF* tif);
-static int OJPEGReadSecondarySos(TIFF* tif, tsample_t s);
-static int OJPEGWriteHeaderInfo(TIFF* tif);
-static void OJPEGLibjpegSessionAbort(TIFF* tif);
-
-static int OJPEGReadHeaderInfoSec(TIFF* tif);
-static int OJPEGReadHeaderInfoSecStreamDri(TIFF* tif);
-static int OJPEGReadHeaderInfoSecStreamDqt(TIFF* tif);
-static int OJPEGReadHeaderInfoSecStreamDht(TIFF* tif);
-static int OJPEGReadHeaderInfoSecStreamSof(TIFF* tif, uint8 marker_id);
-static int OJPEGReadHeaderInfoSecStreamSos(TIFF* tif);
-static int OJPEGReadHeaderInfoSecTablesQTable(TIFF* tif);
-static int OJPEGReadHeaderInfoSecTablesDcTable(TIFF* tif);
-static int OJPEGReadHeaderInfoSecTablesAcTable(TIFF* tif);
-
-static int OJPEGReadBufferFill(OJPEGState* sp);
-static int OJPEGReadByte(OJPEGState* sp, uint8* byte);
-static int OJPEGReadBytePeek(OJPEGState* sp, uint8* byte);
-static void OJPEGReadByteAdvance(OJPEGState* sp);
-static int OJPEGReadWord(OJPEGState* sp, uint16* word);
-static int OJPEGReadBlock(OJPEGState* sp, uint16 len, void* mem);
-static void OJPEGReadSkip(OJPEGState* sp, uint16 len);
-
-static int OJPEGWriteStream(TIFF* tif, void** mem, uint32* len);
-static void OJPEGWriteStreamSoi(TIFF* tif, void** mem, uint32* len);
-static void OJPEGWriteStreamQTable(TIFF* tif, uint8 table_index, void** mem, uint32* len);
-static void OJPEGWriteStreamDcTable(TIFF* tif, uint8 table_index, void** mem, uint32* len);
-static void OJPEGWriteStreamAcTable(TIFF* tif, uint8 table_index, void** mem, uint32* len);
-static void OJPEGWriteStreamDri(TIFF* tif, void** mem, uint32* len);
-static void OJPEGWriteStreamSof(TIFF* tif, void** mem, uint32* len);
-static void OJPEGWriteStreamSos(TIFF* tif, void** mem, uint32* len);
-static int OJPEGWriteStreamCompressed(TIFF* tif, void** mem, uint32* len);
-static void OJPEGWriteStreamRst(TIFF* tif, void** mem, uint32* len);
-static void OJPEGWriteStreamEoi(TIFF* tif, void** mem, uint32* len);
-
-#ifdef LIBJPEG_ENCAP_EXTERNAL
-extern int jpeg_create_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo);
-extern int jpeg_read_header_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, uint8 require_image);
-extern int jpeg_start_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo);
-extern int jpeg_read_scanlines_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* scanlines, uint32 max_lines);
-extern int jpeg_read_raw_data_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* data, uint32 max_lines);
-extern void jpeg_encap_unwind(TIFF* tif);
-#else
-static int jpeg_create_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* j);
-static int jpeg_read_header_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, uint8 require_image);
-static int jpeg_start_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo);
-static int jpeg_read_scanlines_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* scanlines, uint32 max_lines);
-static int jpeg_read_raw_data_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* data, uint32 max_lines);
-static void jpeg_encap_unwind(TIFF* tif);
-#endif
-
-static void OJPEGLibjpegJpegErrorMgrOutputMessage(jpeg_common_struct* cinfo);
-static void OJPEGLibjpegJpegErrorMgrErrorExit(jpeg_common_struct* cinfo);
-static void OJPEGLibjpegJpegSourceMgrInitSource(jpeg_decompress_struct* cinfo);
-static boolean OJPEGLibjpegJpegSourceMgrFillInputBuffer(jpeg_decompress_struct* cinfo);
-static void OJPEGLibjpegJpegSourceMgrSkipInputData(jpeg_decompress_struct* cinfo, long num_bytes);
-static boolean OJPEGLibjpegJpegSourceMgrResyncToRestart(jpeg_decompress_struct* cinfo, int desired);
-static void OJPEGLibjpegJpegSourceMgrTermSource(jpeg_decompress_struct* cinfo);
-
-int
-TIFFInitOJPEG(TIFF* tif, int scheme)
-{
-	static const char module[]="TIFFInitOJPEG";
-	OJPEGState* sp;
-
-	assert(scheme==COMPRESSION_OJPEG);
-
-        /*
-	 * Merge codec-specific tag information.
-	 */
-	if (!_TIFFMergeFieldInfo(tif,ojpeg_field_info,FIELD_OJPEG_COUNT)) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-			     "Merging Old JPEG codec-specific tags failed");
-		return 0;
-	}
-
-	/* state block */
-	sp=_TIFFmalloc(sizeof(OJPEGState));
-	if (sp==NULL)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"No space for OJPEG state block");
-		return(0);
-	}
-	_TIFFmemset(sp,0,sizeof(OJPEGState));
-	sp->tif=tif;
-	sp->jpeg_proc=1;
-	sp->subsampling_hor=2;
-	sp->subsampling_ver=2;
-	TIFFSetField(tif,TIFFTAG_YCBCRSUBSAMPLING,2,2);
-	/* tif codec methods */
-	tif->tif_setupdecode=OJPEGSetupDecode;
-	tif->tif_predecode=OJPEGPreDecode;
-	tif->tif_postdecode=OJPEGPostDecode;
-	tif->tif_decoderow=OJPEGDecode;
-	tif->tif_decodestrip=OJPEGDecode;
-	tif->tif_decodetile=OJPEGDecode;
-	tif->tif_setupencode=OJPEGSetupEncode;
-	tif->tif_preencode=OJPEGPreEncode;
-	tif->tif_postencode=OJPEGPostEncode;
-	tif->tif_encoderow=OJPEGEncode;
-	tif->tif_encodestrip=OJPEGEncode;
-	tif->tif_encodetile=OJPEGEncode;
-	tif->tif_cleanup=OJPEGCleanup;
-	tif->tif_data=(tidata_t)sp;
-	/* tif tag methods */
-	sp->vgetparent=tif->tif_tagmethods.vgetfield;
-	tif->tif_tagmethods.vgetfield=OJPEGVGetField;
-	sp->vsetparent=tif->tif_tagmethods.vsetfield;
-	tif->tif_tagmethods.vsetfield=OJPEGVSetField;
-	tif->tif_tagmethods.printdir=OJPEGPrintDir;
-	/* Some OJPEG files don't have strip or tile offsets or bytecounts tags.
-	   Some others do, but have totally meaningless or corrupt values
-	   in these tags. In these cases, the JpegInterchangeFormat stream is
-	   reliable. In any case, this decoder reads the compressed data itself,
-	   from the most reliable locations, and we need to notify encapsulating
-	   LibTiff not to read raw strips or tiles for us. */
-	tif->tif_flags|=TIFF_NOREADRAW;
-	return(1);
-}
-
-static int
-OJPEGVGetField(TIFF* tif, ttag_t tag, va_list ap)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	switch(tag)
-	{
-		case TIFFTAG_JPEGIFOFFSET:
-			*va_arg(ap,uint32*)=(uint32)sp->jpeg_interchange_format;
-			break;
-		case TIFFTAG_JPEGIFBYTECOUNT:
-			*va_arg(ap,uint32*)=(uint32)sp->jpeg_interchange_format_length;
-			break;
-		case TIFFTAG_YCBCRSUBSAMPLING:
-			if (sp->subsamplingcorrect_done==0)
-				OJPEGSubsamplingCorrect(tif);
-			*va_arg(ap,uint16*)=(uint16)sp->subsampling_hor;
-			*va_arg(ap,uint16*)=(uint16)sp->subsampling_ver;
-			break;
-		case TIFFTAG_JPEGQTABLES:
-			*va_arg(ap,uint32*)=(uint32)sp->qtable_offset_count;
-			*va_arg(ap,void**)=(void*)sp->qtable_offset;
-			break;
-		case TIFFTAG_JPEGDCTABLES:
-			*va_arg(ap,uint32*)=(uint32)sp->dctable_offset_count;
-			*va_arg(ap,void**)=(void*)sp->dctable_offset;
-			break;
-		case TIFFTAG_JPEGACTABLES:
-			*va_arg(ap,uint32*)=(uint32)sp->actable_offset_count;
-			*va_arg(ap,void**)=(void*)sp->actable_offset;
-			break;
-		case TIFFTAG_JPEGPROC:
-			*va_arg(ap,uint16*)=(uint16)sp->jpeg_proc;
-			break;
-		case TIFFTAG_JPEGRESTARTINTERVAL:
-			*va_arg(ap,uint16*)=sp->restart_interval;
-			break;
-		default:
-			return (*sp->vgetparent)(tif,tag,ap);
-	}
-	return (1);
-}
-
-static int
-OJPEGVSetField(TIFF* tif, ttag_t tag, va_list ap)
-{
-	static const char module[]="OJPEGVSetField";
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	uint32 ma;
-	uint32* mb;
-	uint32 n;
-	switch(tag)
-	{
-		case TIFFTAG_JPEGIFOFFSET:
-			sp->jpeg_interchange_format=(toff_t)va_arg(ap,uint32);  
-			break;
-		case TIFFTAG_JPEGIFBYTECOUNT:
-			sp->jpeg_interchange_format_length=(toff_t)va_arg(ap,uint32);  
-			break;
-		case TIFFTAG_YCBCRSUBSAMPLING:
-			sp->subsampling_tag=1;
-			sp->subsampling_hor=(uint8)va_arg(ap,int);
-			sp->subsampling_ver=(uint8)va_arg(ap,int);
-			tif->tif_dir.td_ycbcrsubsampling[0]=sp->subsampling_hor;
-			tif->tif_dir.td_ycbcrsubsampling[1]=sp->subsampling_ver;
-			break;
-		case TIFFTAG_JPEGQTABLES:
-			ma=va_arg(ap,uint32);
-			if (ma!=0)
-			{
-				if (ma>3)
-				{
-					TIFFErrorExt(tif->tif_clientdata,module,"JpegQTables tag has incorrect count");
-					return(0);
-				}
-				sp->qtable_offset_count=(uint8)ma;
-				mb=va_arg(ap,uint32*);
-				for (n=0; n<ma; n++)
-					sp->qtable_offset[n]=(toff_t)mb[n];
-			}
-			break;
-		case TIFFTAG_JPEGDCTABLES:
-			ma=va_arg(ap,uint32);
-			if (ma!=0)
-			{
-				if (ma>3)
-				{
-					TIFFErrorExt(tif->tif_clientdata,module,"JpegDcTables tag has incorrect count");
-					return(0);
-				}
-				sp->dctable_offset_count=(uint8)ma;
-				mb=va_arg(ap,uint32*);
-				for (n=0; n<ma; n++)
-					sp->dctable_offset[n]=(toff_t)mb[n];
-			}
-			break;
-		case TIFFTAG_JPEGACTABLES:
-			ma=va_arg(ap,uint32);
-			if (ma!=0)
-			{
-				if (ma>3)
-				{
-					TIFFErrorExt(tif->tif_clientdata,module,"JpegAcTables tag has incorrect count");
-					return(0);
-				}
-				sp->actable_offset_count=(uint8)ma;
-				mb=va_arg(ap,uint32*);
-				for (n=0; n<ma; n++)
-					sp->actable_offset[n]=(toff_t)mb[n];
-			}
-			break;
-		case TIFFTAG_JPEGPROC:
-			sp->jpeg_proc=(uint8)va_arg(ap,uint32);
-			break;
-		case TIFFTAG_JPEGRESTARTINTERVAL:
-			sp->restart_interval=(uint16)va_arg(ap,uint32);
-			break;
-		default:
-			return (*sp->vsetparent)(tif,tag,ap);
-	}
-	TIFFSetFieldBit(tif,_TIFFFieldWithTag(tif,tag)->field_bit);
-	tif->tif_flags|=TIFF_DIRTYDIRECT;
-	return(1);
-}
-
-static void
-OJPEGPrintDir(TIFF* tif, FILE* fd, long flags)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	uint8 m;
-	(void)flags;
-	assert(sp!=NULL);
-	if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGINTERCHANGEFORMAT))
-		fprintf(fd,"  JpegInterchangeFormat: %lu\n",(unsigned long)sp->jpeg_interchange_format);
-	if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH))
-		fprintf(fd,"  JpegInterchangeFormatLength: %lu\n",(unsigned long)sp->jpeg_interchange_format_length);
-	if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGQTABLES))
-	{
-		fprintf(fd,"  JpegQTables:");
-		for (m=0; m<sp->qtable_offset_count; m++)
-			fprintf(fd," %lu",(unsigned long)sp->qtable_offset[m]);
-		fprintf(fd,"\n");
-	}
-	if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGDCTABLES))
-	{
-		fprintf(fd,"  JpegDcTables:");
-		for (m=0; m<sp->dctable_offset_count; m++)
-			fprintf(fd," %lu",(unsigned long)sp->dctable_offset[m]);
-		fprintf(fd,"\n");
-	}
-	if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGACTABLES))
-	{
-		fprintf(fd,"  JpegAcTables:");
-		for (m=0; m<sp->actable_offset_count; m++)
-			fprintf(fd," %lu",(unsigned long)sp->actable_offset[m]);
-		fprintf(fd,"\n");
-	}
-	if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGPROC))
-		fprintf(fd,"  JpegProc: %u\n",(unsigned int)sp->jpeg_proc);
-	if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGRESTARTINTERVAL))
-		fprintf(fd,"  JpegRestartInterval: %u\n",(unsigned int)sp->restart_interval);
-}
-
-static int
-OJPEGSetupDecode(TIFF* tif)
-{
-	static const char module[]="OJPEGSetupDecode";
-	TIFFWarningExt(tif->tif_clientdata,module,"Depreciated and troublesome old-style JPEG compression mode, please convert to new-style JPEG compression and notify vendor of writing software");
-	return(1);
-}
-
-static int
-OJPEGPreDecode(TIFF* tif, tsample_t s)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	tstrile_t m;
-	if (sp->subsamplingcorrect_done==0)
-		OJPEGSubsamplingCorrect(tif);
-	if (sp->readheader_done==0)
-	{
-		if (OJPEGReadHeaderInfo(tif)==0)
-			return(0);
-	}
-	if (sp->sos_end[s].log==0)
-	{
-		if (OJPEGReadSecondarySos(tif,s)==0)
-			return(0);
-	}
-	if isTiled(tif)
-		m=(tstrile_t)tif->tif_curtile;
-	else
-		m=(tstrile_t)tif->tif_curstrip;
-	if ((sp->writeheader_done!=0) && ((sp->write_cursample!=s) || (sp->write_curstrile>m)))
-	{
-		if (sp->libjpeg_session_active!=0)
-			OJPEGLibjpegSessionAbort(tif);
-		sp->writeheader_done=0;
-	}
-	if (sp->writeheader_done==0)
-	{
-		sp->plane_sample_offset=s;
-		sp->write_cursample=s;
-		sp->write_curstrile=s*tif->tif_dir.td_stripsperimage;
-		if ((sp->in_buffer_file_pos_log==0) ||
-		    (sp->in_buffer_file_pos-sp->in_buffer_togo!=sp->sos_end[s].in_buffer_file_pos))
-		{
-			sp->in_buffer_source=sp->sos_end[s].in_buffer_source;
-			sp->in_buffer_next_strile=sp->sos_end[s].in_buffer_next_strile;
-			sp->in_buffer_file_pos=sp->sos_end[s].in_buffer_file_pos;
-			sp->in_buffer_file_pos_log=0;
-			sp->in_buffer_file_togo=sp->sos_end[s].in_buffer_file_togo;
-			sp->in_buffer_togo=0;
-			sp->in_buffer_cur=0;
-		}
-		if (OJPEGWriteHeaderInfo(tif)==0)
-			return(0);
-	}
-	while (sp->write_curstrile<m)          
-	{
-		if (sp->libjpeg_jpeg_query_style==0)
-		{
-			if (OJPEGPreDecodeSkipRaw(tif)==0)
-				return(0);
-		}
-		else
-		{
-			if (OJPEGPreDecodeSkipScanlines(tif)==0)
-				return(0);
-		}
-		sp->write_curstrile++;
-	}
-	return(1);
-}
-
-static int
-OJPEGPreDecodeSkipRaw(TIFF* tif)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	uint32 m;
-	m=sp->lines_per_strile;
-	if (sp->subsampling_convert_state!=0)
-	{
-		if (sp->subsampling_convert_clines-sp->subsampling_convert_state>=m)
-		{
-			sp->subsampling_convert_state+=m;
-			if (sp->subsampling_convert_state==sp->subsampling_convert_clines)
-				sp->subsampling_convert_state=0;
-			return(1);
-		}
-		m-=sp->subsampling_convert_clines-sp->subsampling_convert_state;
-		sp->subsampling_convert_state=0;
-	}
-	while (m>=sp->subsampling_convert_clines)
-	{
-		if (jpeg_read_raw_data_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),sp->subsampling_convert_ycbcrimage,sp->subsampling_ver*8)==0)
-			return(0);
-		m-=sp->subsampling_convert_clines;
-	}
-	if (m>0)
-	{
-		if (jpeg_read_raw_data_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),sp->subsampling_convert_ycbcrimage,sp->subsampling_ver*8)==0)
-			return(0);
-		sp->subsampling_convert_state=m;
-	}
-	return(1);
-}
-
-static int
-OJPEGPreDecodeSkipScanlines(TIFF* tif)
-{
-	static const char module[]="OJPEGPreDecodeSkipScanlines";
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	uint32 m;
-	if (sp->skip_buffer==NULL)
-	{
-		sp->skip_buffer=_TIFFmalloc(sp->bytes_per_line);
-		if (sp->skip_buffer==NULL)
-		{
-			TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
-			return(0);
-		}
-	}
-	for (m=0; m<sp->lines_per_strile; m++)
-	{
-		if (jpeg_read_scanlines_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),&sp->skip_buffer,1)==0)
-			return(0);
-	}
-	return(1);
-}
-
-static int
-OJPEGDecode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	(void)s;
-	if (sp->libjpeg_jpeg_query_style==0)
-	{
-		if (OJPEGDecodeRaw(tif,buf,cc)==0)
-			return(0);
-	}
-	else
-	{
-		if (OJPEGDecodeScanlines(tif,buf,cc)==0)
-			return(0);
-	}
-	return(1);
-}
-
-static int
-OJPEGDecodeRaw(TIFF* tif, tidata_t buf, tsize_t cc)
-{
-	static const char module[]="OJPEGDecodeRaw";
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	uint8* m;
-	uint32 n;
-	uint8* oy;
-	uint8* ocb;
-	uint8* ocr;
-	uint8* p;
-	uint32 q;
-	uint8* r;
-	uint8 sx,sy;
-	if (cc%sp->bytes_per_line!=0)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Fractional scanline not read");
-		return(0);
-	}
-	assert(cc>0);
-	m=buf;
-	n=cc;
-	do
-	{
-		if (sp->subsampling_convert_state==0)
-		{
-			if (jpeg_read_raw_data_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),sp->subsampling_convert_ycbcrimage,sp->subsampling_ver*8)==0)
-				return(0);
-		}
-		oy=sp->subsampling_convert_ybuf+sp->subsampling_convert_state*sp->subsampling_ver*sp->subsampling_convert_ylinelen;
-		ocb=sp->subsampling_convert_cbbuf+sp->subsampling_convert_state*sp->subsampling_convert_clinelen;
-		ocr=sp->subsampling_convert_crbuf+sp->subsampling_convert_state*sp->subsampling_convert_clinelen;
-		p=m;
-		for (q=0; q<sp->subsampling_convert_clinelenout; q++)
-		{
-			r=oy;
-			for (sy=0; sy<sp->subsampling_ver; sy++)
-			{
-				for (sx=0; sx<sp->subsampling_hor; sx++)
-					*p++=*r++;
-				r+=sp->subsampling_convert_ylinelen-sp->subsampling_hor;
-			}
-			oy+=sp->subsampling_hor;
-			*p++=*ocb++;
-			*p++=*ocr++;
-		}
-		sp->subsampling_convert_state++;
-		if (sp->subsampling_convert_state==sp->subsampling_convert_clines)
-			sp->subsampling_convert_state=0;
-		m+=sp->bytes_per_line;
-		n-=sp->bytes_per_line;
-	} while(n>0);
-	return(1);
-}
-
-static int
-OJPEGDecodeScanlines(TIFF* tif, tidata_t buf, tsize_t cc)
-{
-	static const char module[]="OJPEGDecodeScanlines";
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	uint8* m;
-	uint32 n;
-	if (cc%sp->bytes_per_line!=0)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Fractional scanline not read");
-		return(0);
-	}
-	assert(cc>0);
-	m=buf;
-	n=cc;
-	do
-	{
-		if (jpeg_read_scanlines_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),&m,1)==0)
-			return(0);
-		m+=sp->bytes_per_line;
-		n-=sp->bytes_per_line;
-	} while(n>0);
-	return(1);
-}
-
-static void
-OJPEGPostDecode(TIFF* tif, tidata_t buf, tsize_t cc)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	(void)buf;
-	(void)cc;
-	sp->write_curstrile++;
-	if (sp->write_curstrile%tif->tif_dir.td_stripsperimage==0)
-	{
-		assert(sp->libjpeg_session_active!=0);
-		OJPEGLibjpegSessionAbort(tif);
-		sp->writeheader_done=0;
-	}
-}
-
-static int
-OJPEGSetupEncode(TIFF* tif)
-{
-	static const char module[]="OJPEGSetupEncode";
-	TIFFErrorExt(tif->tif_clientdata,module,"OJPEG encoding not supported; use new-style JPEG compression instead");
-	return(0);
-}
-
-static int
-OJPEGPreEncode(TIFF* tif, tsample_t s)
-{
-	static const char module[]="OJPEGPreEncode";
-	(void)s;
-	TIFFErrorExt(tif->tif_clientdata,module,"OJPEG encoding not supported; use new-style JPEG compression instead");
-	return(0);
-}
-
-static int
-OJPEGEncode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s)
-{
-	static const char module[]="OJPEGEncode";
-	(void)buf;
-	(void)cc;
-	(void)s;
-	TIFFErrorExt(tif->tif_clientdata,module,"OJPEG encoding not supported; use new-style JPEG compression instead");
-	return(0);
-}
-
-static int
-OJPEGPostEncode(TIFF* tif)
-{
-	static const char module[]="OJPEGPostEncode";
-	TIFFErrorExt(tif->tif_clientdata,module,"OJPEG encoding not supported; use new-style JPEG compression instead");
-	return(0);
-}
-
-static void
-OJPEGCleanup(TIFF* tif)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	if (sp!=0)
-	{
-		tif->tif_tagmethods.vgetfield=sp->vgetparent;
-		tif->tif_tagmethods.vsetfield=sp->vsetparent;
-		if (sp->qtable[0]!=0)
-			_TIFFfree(sp->qtable[0]);
-		if (sp->qtable[1]!=0)
-			_TIFFfree(sp->qtable[1]);
-		if (sp->qtable[2]!=0)
-			_TIFFfree(sp->qtable[2]);
-		if (sp->qtable[3]!=0)
-			_TIFFfree(sp->qtable[3]);
-		if (sp->dctable[0]!=0)
-			_TIFFfree(sp->dctable[0]);
-		if (sp->dctable[1]!=0)
-			_TIFFfree(sp->dctable[1]);
-		if (sp->dctable[2]!=0)
-			_TIFFfree(sp->dctable[2]);
-		if (sp->dctable[3]!=0)
-			_TIFFfree(sp->dctable[3]);
-		if (sp->actable[0]!=0)
-			_TIFFfree(sp->actable[0]);
-		if (sp->actable[1]!=0)
-			_TIFFfree(sp->actable[1]);
-		if (sp->actable[2]!=0)
-			_TIFFfree(sp->actable[2]);
-		if (sp->actable[3]!=0)
-			_TIFFfree(sp->actable[3]);
-		if (sp->libjpeg_session_active!=0)
-			OJPEGLibjpegSessionAbort(tif);
-		if (sp->subsampling_convert_ycbcrbuf!=0)
-			_TIFFfree(sp->subsampling_convert_ycbcrbuf);
-		if (sp->subsampling_convert_ycbcrimage!=0)
-			_TIFFfree(sp->subsampling_convert_ycbcrimage);
-		if (sp->skip_buffer!=0)
-			_TIFFfree(sp->skip_buffer);
-		_TIFFfree(sp);
-		tif->tif_data=NULL;
-		_TIFFSetDefaultCompressionState(tif);
-	}
-}
-
-static void
-OJPEGSubsamplingCorrect(TIFF* tif)
-{
-	static const char module[]="OJPEGSubsamplingCorrect";
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	uint8 mh;
-	uint8 mv;
-	assert(sp->subsamplingcorrect_done==0);
-	if ((tif->tif_dir.td_samplesperpixel!=3) || ((tif->tif_dir.td_photometric!=PHOTOMETRIC_YCBCR) &&
-	    (tif->tif_dir.td_photometric!=PHOTOMETRIC_ITULAB)))
-	{
-		if (sp->subsampling_tag!=0)
-			TIFFWarningExt(tif->tif_clientdata,module,"Subsampling tag not appropriate for this Photometric and/or SamplesPerPixel");
-		sp->subsampling_hor=1;
-		sp->subsampling_ver=1;
-		sp->subsampling_force_desubsampling_inside_decompression=0;
-	}
-	else
-	{
-		sp->subsamplingcorrect_done=1;
-		mh=sp->subsampling_hor;
-		mv=sp->subsampling_ver;
-		sp->subsamplingcorrect=1;
-		OJPEGReadHeaderInfoSec(tif);
-		if (sp->subsampling_force_desubsampling_inside_decompression!=0)
-		{
-			sp->subsampling_hor=1;
-			sp->subsampling_ver=1;
-		}
-		sp->subsamplingcorrect=0;
-		if (((sp->subsampling_hor!=mh) || (sp->subsampling_ver!=mv)) && (sp->subsampling_force_desubsampling_inside_decompression==0))
-		{
-			if (sp->subsampling_tag==0)
-				TIFFWarningExt(tif->tif_clientdata,module,"Subsampling tag is not set, yet subsampling inside JPEG data [%d,%d] does not match default values [2,2]; assuming subsampling inside JPEG data is correct",sp->subsampling_hor,sp->subsampling_ver);
-			else
-				TIFFWarningExt(tif->tif_clientdata,module,"Subsampling inside JPEG data [%d,%d] does not match subsampling tag values [%d,%d]; assuming subsampling inside JPEG data is correct",sp->subsampling_hor,sp->subsampling_ver,mh,mv);
-		}
-		if (sp->subsampling_force_desubsampling_inside_decompression!=0)
-		{
-			if (sp->subsampling_tag==0)
-				TIFFWarningExt(tif->tif_clientdata,module,"Subsampling tag is not set, yet subsampling inside JPEG data does not match default values [2,2] (nor any other values allowed in TIFF); assuming subsampling inside JPEG data is correct and desubsampling inside JPEG decompression");
-			else
-				TIFFWarningExt(tif->tif_clientdata,module,"Subsampling inside JPEG data does not match subsampling tag values [%d,%d] (nor any other values allowed in TIFF); assuming subsampling inside JPEG data is correct and desubsampling inside JPEG decompression",mh,mv);
-		}
-		if (sp->subsampling_force_desubsampling_inside_decompression==0)
-		{
-			if (sp->subsampling_hor<sp->subsampling_ver)
-				TIFFWarningExt(tif->tif_clientdata,module,"Subsampling values [%d,%d] are not allowed in TIFF",sp->subsampling_hor,sp->subsampling_ver);
-		}
-	}
-	sp->subsamplingcorrect_done=1;
-}
-
-static int
-OJPEGReadHeaderInfo(TIFF* tif)
-{
-	static const char module[]="OJPEGReadHeaderInfo";
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	assert(sp->readheader_done==0);
-	sp->image_width=tif->tif_dir.td_imagewidth;
-	sp->image_length=tif->tif_dir.td_imagelength;
-	if isTiled(tif)
-	{
-		sp->strile_width=tif->tif_dir.td_tilewidth;
-		sp->strile_length=tif->tif_dir.td_tilelength;
-		sp->strile_length_total=((sp->image_length+sp->strile_length-1)/sp->strile_length)*sp->strile_length;
-	}
-	else
-	{
-		sp->strile_width=sp->image_width;
-		sp->strile_length=tif->tif_dir.td_rowsperstrip;
-		sp->strile_length_total=sp->image_length;
-	}
-	sp->samples_per_pixel=tif->tif_dir.td_samplesperpixel;
-	if (sp->samples_per_pixel==1)
-	{
-		sp->plane_sample_offset=0;
-		sp->samples_per_pixel_per_plane=sp->samples_per_pixel;
-		sp->subsampling_hor=1;
-		sp->subsampling_ver=1;
-	}
-	else
-	{
-		if (sp->samples_per_pixel!=3)
-		{
-			TIFFErrorExt(tif->tif_clientdata,module,"SamplesPerPixel %d not supported for this compression scheme",sp->samples_per_pixel);
-			return(0);
-		}
-		sp->plane_sample_offset=0;
-		if (tif->tif_dir.td_planarconfig==PLANARCONFIG_CONTIG)
-			sp->samples_per_pixel_per_plane=3;
-		else
-			sp->samples_per_pixel_per_plane=1;
-	}
-	if (sp->strile_length<sp->image_length)
-	{
-		if (sp->strile_length%(sp->subsampling_ver*8)!=0)
-		{
-			TIFFErrorExt(tif->tif_clientdata,module,"Incompatible vertical subsampling and image strip/tile length");
-			return(0);
-		}
-		sp->restart_interval=((sp->strile_width+sp->subsampling_hor*8-1)/(sp->subsampling_hor*8))*(sp->strile_length/(sp->subsampling_ver*8));
-	}
-	if (OJPEGReadHeaderInfoSec(tif)==0)
-		return(0);
-	sp->sos_end[0].log=1;
-	sp->sos_end[0].in_buffer_source=sp->in_buffer_source;
-	sp->sos_end[0].in_buffer_next_strile=sp->in_buffer_next_strile;
-	sp->sos_end[0].in_buffer_file_pos=sp->in_buffer_file_pos-sp->in_buffer_togo;
-	sp->sos_end[0].in_buffer_file_togo=sp->in_buffer_file_togo+sp->in_buffer_togo;
-	sp->readheader_done=1;
-	return(1);
-}
-
-static int
-OJPEGReadSecondarySos(TIFF* tif, tsample_t s)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	uint8 m;
-	assert(s>0);
-	assert(s<3);
-	assert(sp->sos_end[0].log!=0);
-	assert(sp->sos_end[s].log==0);
-	sp->plane_sample_offset=s-1;
-	while(sp->sos_end[sp->plane_sample_offset].log==0)
-		sp->plane_sample_offset--;
-	sp->in_buffer_source=sp->sos_end[sp->plane_sample_offset].in_buffer_source;
-	sp->in_buffer_next_strile=sp->sos_end[sp->plane_sample_offset].in_buffer_next_strile;
-	sp->in_buffer_file_pos=sp->sos_end[sp->plane_sample_offset].in_buffer_file_pos;  
-	sp->in_buffer_file_pos_log=0;
-	sp->in_buffer_file_togo=sp->sos_end[sp->plane_sample_offset].in_buffer_file_togo;
-	sp->in_buffer_togo=0;
-	sp->in_buffer_cur=0;
-	while(sp->plane_sample_offset<s)
-	{
-		do
-		{
-			if (OJPEGReadByte(sp,&m)==0)
-				return(0);
-			if (m==255)
-			{
-				do
-				{
-					if (OJPEGReadByte(sp,&m)==0)
-						return(0);
-					if (m!=255)
-						break;
-				} while(1);
-				if (m==JPEG_MARKER_SOS)
-					break;
-			}
-		} while(1);
-		sp->plane_sample_offset++;
-		if (OJPEGReadHeaderInfoSecStreamSos(tif)==0)
-			return(0);
-		sp->sos_end[sp->plane_sample_offset].log=1;
-		sp->sos_end[sp->plane_sample_offset].in_buffer_source=sp->in_buffer_source;
-		sp->sos_end[sp->plane_sample_offset].in_buffer_next_strile=sp->in_buffer_next_strile;
-		sp->sos_end[sp->plane_sample_offset].in_buffer_file_pos=sp->in_buffer_file_pos-sp->in_buffer_togo;
-		sp->sos_end[sp->plane_sample_offset].in_buffer_file_togo=sp->in_buffer_file_togo+sp->in_buffer_togo;
-	}
-	return(1);
-}
-
-static int
-OJPEGWriteHeaderInfo(TIFF* tif)
-{
-	static const char module[]="OJPEGWriteHeaderInfo";
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	uint8** m;
-	uint32 n;
-	assert(sp->libjpeg_session_active==0);
-	sp->out_state=ososSoi;
-	sp->restart_index=0;
-	jpeg_std_error(&(sp->libjpeg_jpeg_error_mgr));
-	sp->libjpeg_jpeg_error_mgr.output_message=OJPEGLibjpegJpegErrorMgrOutputMessage;
-	sp->libjpeg_jpeg_error_mgr.error_exit=OJPEGLibjpegJpegErrorMgrErrorExit;
-	sp->libjpeg_jpeg_decompress_struct.err=&(sp->libjpeg_jpeg_error_mgr);
-	sp->libjpeg_jpeg_decompress_struct.client_data=(void*)tif;
-	if (jpeg_create_decompress_encap(sp,&(sp->libjpeg_jpeg_decompress_struct))==0)
-		return(0);
-	sp->libjpeg_session_active=1;
-	sp->libjpeg_jpeg_source_mgr.bytes_in_buffer=0;
-	sp->libjpeg_jpeg_source_mgr.init_source=OJPEGLibjpegJpegSourceMgrInitSource;
-	sp->libjpeg_jpeg_source_mgr.fill_input_buffer=OJPEGLibjpegJpegSourceMgrFillInputBuffer;
-	sp->libjpeg_jpeg_source_mgr.skip_input_data=OJPEGLibjpegJpegSourceMgrSkipInputData;
-	sp->libjpeg_jpeg_source_mgr.resync_to_restart=OJPEGLibjpegJpegSourceMgrResyncToRestart;
-	sp->libjpeg_jpeg_source_mgr.term_source=OJPEGLibjpegJpegSourceMgrTermSource;
-	sp->libjpeg_jpeg_decompress_struct.src=&(sp->libjpeg_jpeg_source_mgr);
-	if (jpeg_read_header_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),1)==0)
-		return(0);
-	if ((sp->subsampling_force_desubsampling_inside_decompression==0) && (sp->samples_per_pixel_per_plane>1))
-	{
-		sp->libjpeg_jpeg_decompress_struct.raw_data_out=1;
-#if JPEG_LIB_VERSION >= 70
-		sp->libjpeg_jpeg_decompress_struct.do_fancy_upsampling=FALSE;
-#endif
-		sp->libjpeg_jpeg_query_style=0;
-		if (sp->subsampling_convert_log==0)
-		{
-			assert(sp->subsampling_convert_ycbcrbuf==0);
-			assert(sp->subsampling_convert_ycbcrimage==0);
-			sp->subsampling_convert_ylinelen=((sp->strile_width+sp->subsampling_hor*8-1)/(sp->subsampling_hor*8)*sp->subsampling_hor*8);
-			sp->subsampling_convert_ylines=sp->subsampling_ver*8;
-			sp->subsampling_convert_clinelen=sp->subsampling_convert_ylinelen/sp->subsampling_hor;
-			sp->subsampling_convert_clines=8;
-			sp->subsampling_convert_ybuflen=sp->subsampling_convert_ylinelen*sp->subsampling_convert_ylines;
-			sp->subsampling_convert_cbuflen=sp->subsampling_convert_clinelen*sp->subsampling_convert_clines;
-			sp->subsampling_convert_ycbcrbuflen=sp->subsampling_convert_ybuflen+2*sp->subsampling_convert_cbuflen;
-			sp->subsampling_convert_ycbcrbuf=_TIFFmalloc(sp->subsampling_convert_ycbcrbuflen);
-			if (sp->subsampling_convert_ycbcrbuf==0)
-			{
-				TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
-				return(0);
-			}
-			sp->subsampling_convert_ybuf=sp->subsampling_convert_ycbcrbuf;
-			sp->subsampling_convert_cbbuf=sp->subsampling_convert_ybuf+sp->subsampling_convert_ybuflen;
-			sp->subsampling_convert_crbuf=sp->subsampling_convert_cbbuf+sp->subsampling_convert_cbuflen;
-			sp->subsampling_convert_ycbcrimagelen=3+sp->subsampling_convert_ylines+2*sp->subsampling_convert_clines;
-			sp->subsampling_convert_ycbcrimage=_TIFFmalloc(sp->subsampling_convert_ycbcrimagelen*sizeof(uint8*));
-			if (sp->subsampling_convert_ycbcrimage==0)
-			{
-				TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
-				return(0);
-			}
-			m=sp->subsampling_convert_ycbcrimage;
-			*m++=(uint8*)(sp->subsampling_convert_ycbcrimage+3);
-			*m++=(uint8*)(sp->subsampling_convert_ycbcrimage+3+sp->subsampling_convert_ylines);
-			*m++=(uint8*)(sp->subsampling_convert_ycbcrimage+3+sp->subsampling_convert_ylines+sp->subsampling_convert_clines);
-			for (n=0; n<sp->subsampling_convert_ylines; n++)
-				*m++=sp->subsampling_convert_ybuf+n*sp->subsampling_convert_ylinelen;
-			for (n=0; n<sp->subsampling_convert_clines; n++)
-				*m++=sp->subsampling_convert_cbbuf+n*sp->subsampling_convert_clinelen;
-			for (n=0; n<sp->subsampling_convert_clines; n++)
-				*m++=sp->subsampling_convert_crbuf+n*sp->subsampling_convert_clinelen;
-			sp->subsampling_convert_clinelenout=((sp->strile_width+sp->subsampling_hor-1)/sp->subsampling_hor);
-			sp->subsampling_convert_state=0;
-			sp->bytes_per_line=sp->subsampling_convert_clinelenout*(sp->subsampling_ver*sp->subsampling_hor+2);
-			sp->lines_per_strile=((sp->strile_length+sp->subsampling_ver-1)/sp->subsampling_ver);
-			sp->subsampling_convert_log=1;
-		}
-	}
-	else
-	{
-		sp->libjpeg_jpeg_decompress_struct.jpeg_color_space=JCS_UNKNOWN;
-		sp->libjpeg_jpeg_decompress_struct.out_color_space=JCS_UNKNOWN;
-		sp->libjpeg_jpeg_query_style=1;
-		sp->bytes_per_line=sp->samples_per_pixel_per_plane*sp->strile_width;
-		sp->lines_per_strile=sp->strile_length;
-	}
-	if (jpeg_start_decompress_encap(sp,&(sp->libjpeg_jpeg_decompress_struct))==0)
-		return(0);
-	sp->writeheader_done=1;
-	return(1);
-}
-
-static void
-OJPEGLibjpegSessionAbort(TIFF* tif)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	assert(sp->libjpeg_session_active!=0);
-	jpeg_destroy((jpeg_common_struct*)(&(sp->libjpeg_jpeg_decompress_struct)));
-	sp->libjpeg_session_active=0;
-}
-
-static int
-OJPEGReadHeaderInfoSec(TIFF* tif)
-{
-	static const char module[]="OJPEGReadHeaderInfoSec";
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	uint8 m;
-	uint16 n;
-	uint8 o;
-	if (sp->file_size==0)
-		sp->file_size=TIFFGetFileSize(tif);
-	if (sp->jpeg_interchange_format!=0)
-	{
-		if (sp->jpeg_interchange_format>=sp->file_size)
-		{
-			sp->jpeg_interchange_format=0;
-			sp->jpeg_interchange_format_length=0;
-		}
-		else
-		{
-			if ((sp->jpeg_interchange_format_length==0) || (sp->jpeg_interchange_format+sp->jpeg_interchange_format_length>sp->file_size))
-				sp->jpeg_interchange_format_length=sp->file_size-sp->jpeg_interchange_format;
-		}
-	}
-	sp->in_buffer_source=osibsNotSetYet;
-	sp->in_buffer_next_strile=0;
-	sp->in_buffer_strile_count=tif->tif_dir.td_nstrips;   
-	sp->in_buffer_file_togo=0;
-	sp->in_buffer_togo=0;
-	do
-	{
-		if (OJPEGReadBytePeek(sp,&m)==0)
-			return(0);
-		if (m!=255)
-			break;
-		OJPEGReadByteAdvance(sp);
-		do
-		{
-			if (OJPEGReadByte(sp,&m)==0)
-				return(0);
-		} while(m==255);
-		switch(m)
-		{
-			case JPEG_MARKER_SOI:
-				/* this type of marker has no data, and should be skipped */
-				break;
-			case JPEG_MARKER_COM:
-			case JPEG_MARKER_APP0:
-			case JPEG_MARKER_APP0+1:
-			case JPEG_MARKER_APP0+2:
-			case JPEG_MARKER_APP0+3:
-			case JPEG_MARKER_APP0+4:
-			case JPEG_MARKER_APP0+5:
-			case JPEG_MARKER_APP0+6:
-			case JPEG_MARKER_APP0+7:
-			case JPEG_MARKER_APP0+8:
-			case JPEG_MARKER_APP0+9:
-			case JPEG_MARKER_APP0+10:
-			case JPEG_MARKER_APP0+11:
-			case JPEG_MARKER_APP0+12:
-			case JPEG_MARKER_APP0+13:
-			case JPEG_MARKER_APP0+14:
-			case JPEG_MARKER_APP0+15:
-				/* this type of marker has data, but it has no use to us (and no place here) and should be skipped */
-				if (OJPEGReadWord(sp,&n)==0)
-					return(0);
-				if (n<2)
-				{
-					if (sp->subsamplingcorrect==0)
-						TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JPEG data");
-					return(0);
-				}
-				if (n>2)
-					OJPEGReadSkip(sp,n-2);
-				break;
-			case JPEG_MARKER_DRI:
-				if (OJPEGReadHeaderInfoSecStreamDri(tif)==0)
-					return(0);
-				break;
-			case JPEG_MARKER_DQT:
-				if (OJPEGReadHeaderInfoSecStreamDqt(tif)==0)
-					return(0);
-				break;
-			case JPEG_MARKER_DHT:
-				if (OJPEGReadHeaderInfoSecStreamDht(tif)==0)
-					return(0);
-				break;
-			case JPEG_MARKER_SOF0:
-			case JPEG_MARKER_SOF1:
-			case JPEG_MARKER_SOF3:
-				if (OJPEGReadHeaderInfoSecStreamSof(tif,m)==0)
-					return(0);
-				if (sp->subsamplingcorrect!=0)
-					return(1);
-				break;
-			case JPEG_MARKER_SOS:
-				if (sp->subsamplingcorrect!=0)
-					return(1);
-				assert(sp->plane_sample_offset==0);
-				if (OJPEGReadHeaderInfoSecStreamSos(tif)==0)
-					return(0);
-				break;
-			default:
-				TIFFErrorExt(tif->tif_clientdata,module,"Unknown marker type %d in JPEG data",m);
-				return(0);
-		}
-	} while(m!=JPEG_MARKER_SOS);
-	if (sp->subsamplingcorrect)
-		return(1);
-	if (sp->sof_log==0)
-	{
-		if (OJPEGReadHeaderInfoSecTablesQTable(tif)==0)
-			return(0);
-		sp->sof_marker_id=JPEG_MARKER_SOF0;
-		for (o=0; o<sp->samples_per_pixel; o++)
-			sp->sof_c[o]=o;
-		sp->sof_hv[0]=((sp->subsampling_hor<<4)|sp->subsampling_ver);
-		for (o=1; o<sp->samples_per_pixel; o++)
-			sp->sof_hv[o]=17;
-		sp->sof_x=sp->strile_width;
-		sp->sof_y=sp->strile_length_total;
-		sp->sof_log=1;
-		if (OJPEGReadHeaderInfoSecTablesDcTable(tif)==0)
-			return(0);
-		if (OJPEGReadHeaderInfoSecTablesAcTable(tif)==0)
-			return(0);
-		for (o=1; o<sp->samples_per_pixel; o++)
-			sp->sos_cs[o]=o;
-	}
-	return(1);
-}
-
-static int
-OJPEGReadHeaderInfoSecStreamDri(TIFF* tif)
-{
-	/* this could easilly cause trouble in some cases... but no such cases have occured sofar */
-	static const char module[]="OJPEGReadHeaderInfoSecStreamDri";
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	uint16 m;
-	if (OJPEGReadWord(sp,&m)==0)
-		return(0);
-	if (m!=4)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DRI marker in JPEG data");
-		return(0);
-	}
-	if (OJPEGReadWord(sp,&m)==0)
-		return(0);
-	sp->restart_interval=m;
-	return(1);
-}
-
-static int
-OJPEGReadHeaderInfoSecStreamDqt(TIFF* tif)
-{
-	/* this is a table marker, and it is to be saved as a whole for exact pushing on the jpeg stream later on */
-	static const char module[]="OJPEGReadHeaderInfoSecStreamDqt";
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	uint16 m;
-	uint32 na;
-	uint8* nb;
-	uint8 o;
-	if (OJPEGReadWord(sp,&m)==0)
-		return(0);
-	if (m<=2)
-	{
-		if (sp->subsamplingcorrect==0)
-			TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DQT marker in JPEG data");
-		return(0);
-	}
-	if (sp->subsamplingcorrect!=0)
-		OJPEGReadSkip(sp,m-2);
-	else
-	{
-		m-=2;
-		do
-		{
-			if (m<65)
-			{
-				TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DQT marker in JPEG data");
-				return(0);
-			}
-			na=sizeof(uint32)+69;
-			nb=_TIFFmalloc(na);
-			if (nb==0)
-			{
-				TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
-				return(0);
-			}
-			*(uint32*)nb=na;
-			nb[sizeof(uint32)]=255;
-			nb[sizeof(uint32)+1]=JPEG_MARKER_DQT;
-			nb[sizeof(uint32)+2]=0;
-			nb[sizeof(uint32)+3]=67;
-			if (OJPEGReadBlock(sp,65,&nb[sizeof(uint32)+4])==0)
-				return(0);
-			o=nb[sizeof(uint32)+4]&15;
-			if (3<o)
-			{
-				TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DQT marker in JPEG data");
-				return(0);
-			}
-			if (sp->qtable[o]!=0)
-				_TIFFfree(sp->qtable[o]);
-			sp->qtable[o]=nb;
-			m-=65;
-		} while(m>0);
-	}
-	return(1);
-}
-
-static int
-OJPEGReadHeaderInfoSecStreamDht(TIFF* tif)
-{
-	/* this is a table marker, and it is to be saved as a whole for exact pushing on the jpeg stream later on */
-	/* TODO: the following assumes there is only one table in this marker... but i'm not quite sure that assumption is guaranteed correct */
-	static const char module[]="OJPEGReadHeaderInfoSecStreamDht";
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	uint16 m;
-	uint32 na;
-	uint8* nb;
-	uint8 o;
-	if (OJPEGReadWord(sp,&m)==0)
-		return(0);
-	if (m<=2)
-	{
-		if (sp->subsamplingcorrect==0)
-			TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data");
-		return(0);
-	}
-	if (sp->subsamplingcorrect!=0)
-	{
-		OJPEGReadSkip(sp,m-2);
-	}
-	else
-	{
-		na=sizeof(uint32)+2+m;
-		nb=_TIFFmalloc(na);
-		if (nb==0)
-		{
-			TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
-			return(0);
-		}
-		*(uint32*)nb=na;
-		nb[sizeof(uint32)]=255;
-		nb[sizeof(uint32)+1]=JPEG_MARKER_DHT;
-		nb[sizeof(uint32)+2]=(m>>8);
-		nb[sizeof(uint32)+3]=(m&255);
-		if (OJPEGReadBlock(sp,m-2,&nb[sizeof(uint32)+4])==0)
-			return(0);
-		o=nb[sizeof(uint32)+4];
-		if ((o&240)==0)
-		{
-			if (3<o)
-			{
-				TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data");
-				return(0);
-			}
-			if (sp->dctable[o]!=0)
-				_TIFFfree(sp->dctable[o]);
-			sp->dctable[o]=nb;
-		}
-		else
-		{
-			if ((o&240)!=16)
-			{
-				TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data");
-				return(0);
-			}
-			o&=15;
-			if (3<o)
-			{
-				TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data");
-				return(0);
-			}
-			if (sp->actable[o]!=0)
-				_TIFFfree(sp->actable[o]);
-			sp->actable[o]=nb;
-		}
-	}
-	return(1);
-}
-
-static int
-OJPEGReadHeaderInfoSecStreamSof(TIFF* tif, uint8 marker_id)
-{
-	/* this marker needs to be checked, and part of its data needs to be saved for regeneration later on */
-	static const char module[]="OJPEGReadHeaderInfoSecStreamSof";
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	uint16 m;
-	uint16 n;
-	uint8 o;
-	uint16 p;
-	uint16 q;
-	if (sp->sof_log!=0)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JPEG data");
-		return(0);
-	}
-	if (sp->subsamplingcorrect==0)
-		sp->sof_marker_id=marker_id;
-	/* Lf: data length */
-	if (OJPEGReadWord(sp,&m)==0)
-		return(0);
-	if (m<11)
-	{
-		if (sp->subsamplingcorrect==0)
-			TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOF marker in JPEG data");
-		return(0);
-	}
-	m-=8;
-	if (m%3!=0)
-	{
-		if (sp->subsamplingcorrect==0)
-			TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOF marker in JPEG data");
-		return(0);
-	}
-	n=m/3;
-	if (sp->subsamplingcorrect==0)
-	{
-		if (n!=sp->samples_per_pixel)
-		{
-			TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected number of samples");
-			return(0);
-		}
-	}
-	/* P: Sample precision */
-	if (OJPEGReadByte(sp,&o)==0)
-		return(0);
-	if (o!=8)
-	{
-		if (sp->subsamplingcorrect==0)
-			TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected number of bits per sample");
-		return(0);
-	}
-	/* Y: Number of lines, X: Number of samples per line */
-	if (sp->subsamplingcorrect)
-		OJPEGReadSkip(sp,4);
-	else
-	{
-		/* Y: Number of lines */
-		if (OJPEGReadWord(sp,&p)==0)
-			return(0);
-		if ((p<sp->image_length) && (p<sp->strile_length_total))
-		{
-			TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected height");
-			return(0);
-		}
-		sp->sof_y=p;
-		/* X: Number of samples per line */
-		if (OJPEGReadWord(sp,&p)==0)
-			return(0);
-		if ((p<sp->image_width) && (p<sp->strile_width))
-		{
-			TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected width");
-			return(0);
-		}
-		if ((uint32)p>sp->strile_width)
-		{
-			TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data image width exceeds expected image width");
-			return(0);
-		}
-		sp->sof_x=p;
-	}
-	/* Nf: Number of image components in frame */
-	if (OJPEGReadByte(sp,&o)==0)
-		return(0);
-	if (o!=n)
-	{
-		if (sp->subsamplingcorrect==0)
-			TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOF marker in JPEG data");
-		return(0);
-	}
-	/* per component stuff */
-	/* TODO: double-check that flow implies that n cannot be as big as to make us overflow sof_c, sof_hv and sof_tq arrays */
-	for (q=0; q<n; q++)
-	{
-		/* C: Component identifier */
-		if (OJPEGReadByte(sp,&o)==0)
-			return(0);
-		if (sp->subsamplingcorrect==0)
-			sp->sof_c[q]=o;
-		/* H: Horizontal sampling factor, and V: Vertical sampling factor */
-		if (OJPEGReadByte(sp,&o)==0)
-			return(0);
-		if (sp->subsamplingcorrect!=0)
-		{
-			if (q==0)
-			{
-				sp->subsampling_hor=(o>>4);
-				sp->subsampling_ver=(o&15);
-				if (((sp->subsampling_hor!=1) && (sp->subsampling_hor!=2) && (sp->subsampling_hor!=4)) ||
-					((sp->subsampling_ver!=1) && (sp->subsampling_ver!=2) && (sp->subsampling_ver!=4)))
-					sp->subsampling_force_desubsampling_inside_decompression=1;
-			}
-			else
-			{
-				if (o!=17)
-					sp->subsampling_force_desubsampling_inside_decompression=1;
-			}
-		}
-		else
-		{
-			sp->sof_hv[q]=o;
-			if (sp->subsampling_force_desubsampling_inside_decompression==0)
-			{
-				if (q==0)
-				{
-					if (o!=((sp->subsampling_hor<<4)|sp->subsampling_ver))
-					{
-						TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected subsampling values");
-						return(0);
-					}
-				}
-				else
-				{
-					if (o!=17)
-					{
-						TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected subsampling values");
-						return(0);
-					}
-				}
-			}
-		}
-		/* Tq: Quantization table destination selector */
-		if (OJPEGReadByte(sp,&o)==0)
-			return(0);
-		if (sp->subsamplingcorrect==0)
-			sp->sof_tq[q]=o;
-	}
-	if (sp->subsamplingcorrect==0)
-		sp->sof_log=1;
-	return(1);
-}
-
-static int
-OJPEGReadHeaderInfoSecStreamSos(TIFF* tif)
-{
-	/* this marker needs to be checked, and part of its data needs to be saved for regeneration later on */
-	static const char module[]="OJPEGReadHeaderInfoSecStreamSos";
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	uint16 m;
-	uint8 n;
-	uint8 o;
-	assert(sp->subsamplingcorrect==0);
-	if (sp->sof_log==0)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOS marker in JPEG data");
-		return(0);
-	}
-	/* Ls */
-	if (OJPEGReadWord(sp,&m)==0)
-		return(0);
-	if (m!=6+sp->samples_per_pixel_per_plane*2)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOS marker in JPEG data");
-		return(0);
-	}
-	/* Ns */
-	if (OJPEGReadByte(sp,&n)==0)
-		return(0);
-	if (n!=sp->samples_per_pixel_per_plane)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOS marker in JPEG data");
-		return(0);
-	}
-	/* Cs, Td, and Ta */
-	for (o=0; o<sp->samples_per_pixel_per_plane; o++)
-	{
-		/* Cs */
-		if (OJPEGReadByte(sp,&n)==0)
-			return(0);
-		sp->sos_cs[sp->plane_sample_offset+o]=n;
-		/* Td and Ta */
-		if (OJPEGReadByte(sp,&n)==0)
-			return(0);
-		sp->sos_tda[sp->plane_sample_offset+o]=n;
-	}
-	/* skip Ss, Se, Ah, en Al -> no check, as per Tom Lane recommendation, as per LibJpeg source */
-	OJPEGReadSkip(sp,3);
-	return(1);
-}
-
-static int
-OJPEGReadHeaderInfoSecTablesQTable(TIFF* tif)
-{
-	static const char module[]="OJPEGReadHeaderInfoSecTablesQTable";
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	uint8 m;
-	uint8 n;
-	uint32 oa;
-	uint8* ob;
-	uint32 p;
-	if (sp->qtable_offset[0]==0)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Missing JPEG tables");
-		return(0);
-	}
-	sp->in_buffer_file_pos_log=0;
-	for (m=0; m<sp->samples_per_pixel; m++)
-	{
-		if ((sp->qtable_offset[m]!=0) && ((m==0) || (sp->qtable_offset[m]!=sp->qtable_offset[m-1])))
-		{
-			for (n=0; n<m-1; n++)
-			{
-				if (sp->qtable_offset[m]==sp->qtable_offset[n])
-				{
-					TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JpegQTables tag value");
-					return(0);
-				}
-			}
-			oa=sizeof(uint32)+69;
-			ob=_TIFFmalloc(oa);
-			if (ob==0)
-			{
-				TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
-				return(0);
-			}
-			*(uint32*)ob=oa;
-			ob[sizeof(uint32)]=255;
-			ob[sizeof(uint32)+1]=JPEG_MARKER_DQT;
-			ob[sizeof(uint32)+2]=0;
-			ob[sizeof(uint32)+3]=67;
-			ob[sizeof(uint32)+4]=m;
-			TIFFSeekFile(tif,sp->qtable_offset[m],SEEK_SET);
-			p=TIFFReadFile(tif,&ob[sizeof(uint32)+5],64);
-			if (p!=64)
-				return(0);
-			sp->qtable[m]=ob;
-			sp->sof_tq[m]=m;
-		}
-		else
-			sp->sof_tq[m]=sp->sof_tq[m-1];
-	}
-	return(1);
-}
-
-static int
-OJPEGReadHeaderInfoSecTablesDcTable(TIFF* tif)
-{
-	static const char module[]="OJPEGReadHeaderInfoSecTablesDcTable";
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	uint8 m;
-	uint8 n;
-	uint8 o[16];
-	uint32 p;
-	uint32 q;
-	uint32 ra;
-	uint8* rb;
-	if (sp->dctable_offset[0]==0)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Missing JPEG tables");
-		return(0);
-	}
-	sp->in_buffer_file_pos_log=0;
-	for (m=0; m<sp->samples_per_pixel; m++)
-	{
-		if ((sp->dctable_offset[m]!=0) && ((m==0) || (sp->dctable_offset[m]!=sp->dctable_offset[m-1])))
-		{
-			for (n=0; n<m-1; n++)
-			{
-				if (sp->dctable_offset[m]==sp->dctable_offset[n])
-				{
-					TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JpegDcTables tag value");
-					return(0);
-				}
-			}
-			TIFFSeekFile(tif,sp->dctable_offset[m],SEEK_SET);
-			p=TIFFReadFile(tif,o,16);
-			if (p!=16)
-				return(0);
-			q=0;
-			for (n=0; n<16; n++)
-				q+=o[n];
-			ra=sizeof(uint32)+21+q;
-			rb=_TIFFmalloc(ra);
-			if (rb==0)
-			{
-				TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
-				return(0);
-			}
-			*(uint32*)rb=ra;
-			rb[sizeof(uint32)]=255;
-			rb[sizeof(uint32)+1]=JPEG_MARKER_DHT;
-			rb[sizeof(uint32)+2]=((19+q)>>8);
-			rb[sizeof(uint32)+3]=((19+q)&255);
-			rb[sizeof(uint32)+4]=m;
-			for (n=0; n<16; n++)
-				rb[sizeof(uint32)+5+n]=o[n];
-			p=TIFFReadFile(tif,&(rb[sizeof(uint32)+21]),q);
-			if (p!=q)
-				return(0);
-			sp->dctable[m]=rb;
-			sp->sos_tda[m]=(m<<4);
-		}
-		else
-			sp->sos_tda[m]=sp->sos_tda[m-1];
-	}
-	return(1);
-}
-
-static int
-OJPEGReadHeaderInfoSecTablesAcTable(TIFF* tif)
-{
-	static const char module[]="OJPEGReadHeaderInfoSecTablesAcTable";
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	uint8 m;
-	uint8 n;
-	uint8 o[16];
-	uint32 p;
-	uint32 q;
-	uint32 ra;
-	uint8* rb;
-	if (sp->actable_offset[0]==0)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Missing JPEG tables");
-		return(0);
-	}
-	sp->in_buffer_file_pos_log=0;
-	for (m=0; m<sp->samples_per_pixel; m++)
-	{
-		if ((sp->actable_offset[m]!=0) && ((m==0) || (sp->actable_offset[m]!=sp->actable_offset[m-1])))
-		{
-			for (n=0; n<m-1; n++)
-			{
-				if (sp->actable_offset[m]==sp->actable_offset[n])
-				{
-					TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JpegAcTables tag value");
-					return(0);
-				}
-			}
-			TIFFSeekFile(tif,sp->actable_offset[m],SEEK_SET);
-			p=TIFFReadFile(tif,o,16);
-			if (p!=16)
-				return(0);
-			q=0;
-			for (n=0; n<16; n++)
-				q+=o[n];
-			ra=sizeof(uint32)+21+q;
-			rb=_TIFFmalloc(ra);
-			if (rb==0)
-			{
-				TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
-				return(0);
-			}
-			*(uint32*)rb=ra;
-			rb[sizeof(uint32)]=255;
-			rb[sizeof(uint32)+1]=JPEG_MARKER_DHT;
-			rb[sizeof(uint32)+2]=((19+q)>>8);
-			rb[sizeof(uint32)+3]=((19+q)&255);
-			rb[sizeof(uint32)+4]=(16|m);
-			for (n=0; n<16; n++)
-				rb[sizeof(uint32)+5+n]=o[n];
-			p=TIFFReadFile(tif,&(rb[sizeof(uint32)+21]),q);
-			if (p!=q)
-				return(0);
-			sp->actable[m]=rb;
-			sp->sos_tda[m]=(sp->sos_tda[m]|m);
-		}
-		else
-			sp->sos_tda[m]=(sp->sos_tda[m]|(sp->sos_tda[m-1]&15));
-	}
-	return(1);
-}
-
-static int
-OJPEGReadBufferFill(OJPEGState* sp)
-{
-	uint16 m;
-	tsize_t n;
-	/* TODO: double-check: when subsamplingcorrect is set, no call to TIFFErrorExt or TIFFWarningExt should be made
-	 * in any other case, seek or read errors should be passed through */
-	do
-	{
-		if (sp->in_buffer_file_togo!=0)
-		{
-			if (sp->in_buffer_file_pos_log==0)
-			{
-				TIFFSeekFile(sp->tif,sp->in_buffer_file_pos,SEEK_SET);
-				sp->in_buffer_file_pos_log=1;
-			}
-			m=OJPEG_BUFFER;
-			if (m>sp->in_buffer_file_togo)
-				m=(uint16)sp->in_buffer_file_togo;
-			n=TIFFReadFile(sp->tif,sp->in_buffer,(tsize_t)m);
-			if (n==0)
-				return(0);
-			assert(n>0);
-			assert(n<=OJPEG_BUFFER);
-			assert(n<65536);
-			assert((uint16)n<=sp->in_buffer_file_togo);
-			m=(uint16)n;
-			sp->in_buffer_togo=m;
-			sp->in_buffer_cur=sp->in_buffer;
-			sp->in_buffer_file_togo-=m;
-			sp->in_buffer_file_pos+=m;
-			break;
-		}
-		sp->in_buffer_file_pos_log=0;
-		switch(sp->in_buffer_source)
-		{
-			case osibsNotSetYet:
-				if (sp->jpeg_interchange_format!=0)
-				{
-					sp->in_buffer_file_pos=sp->jpeg_interchange_format;
-					sp->in_buffer_file_togo=sp->jpeg_interchange_format_length;
-				}
-				sp->in_buffer_source=osibsJpegInterchangeFormat;
-				break;
-			case osibsJpegInterchangeFormat:
-				sp->in_buffer_source=osibsStrile;
-			case osibsStrile:
-				if (sp->in_buffer_next_strile==sp->in_buffer_strile_count)  
-					sp->in_buffer_source=osibsEof;
-				else
-				{
-					if (sp->tif->tif_dir.td_stripoffset == 0) {
-						TIFFErrorExt(sp->tif->tif_clientdata,sp->tif->tif_name,"Strip offsets are missing");
-						return(0);
-					}
-					sp->in_buffer_file_pos=sp->tif->tif_dir.td_stripoffset[sp->in_buffer_next_strile];  
-					if (sp->in_buffer_file_pos!=0)
-					{
-						if (sp->in_buffer_file_pos>=sp->file_size)
-							sp->in_buffer_file_pos=0;
-						else if (sp->tif->tif_dir.td_stripbytecount==NULL)
-							sp->in_buffer_file_togo=sp->file_size-sp->in_buffer_file_pos;
-						else
-						{
-							if (sp->tif->tif_dir.td_stripbytecount == 0) {
-								TIFFErrorExt(sp->tif->tif_clientdata,sp->tif->tif_name,"Strip byte counts are missing");
-								return(0);
-							}
-							sp->in_buffer_file_togo=sp->tif->tif_dir.td_stripbytecount[sp->in_buffer_next_strile];  
-							if (sp->in_buffer_file_togo==0)
-								sp->in_buffer_file_pos=0;
-							else if (sp->in_buffer_file_pos+sp->in_buffer_file_togo>sp->file_size)
-								sp->in_buffer_file_togo=sp->file_size-sp->in_buffer_file_pos;
-						}
-					}
-					sp->in_buffer_next_strile++;
-				}
-				break;
-			default:
-				return(0);
-		}
-	} while (1);
-	return(1);
-}
-
-static int
-OJPEGReadByte(OJPEGState* sp, uint8* byte)
-{
-	if (sp->in_buffer_togo==0)
-	{
-		if (OJPEGReadBufferFill(sp)==0)
-			return(0);
-		assert(sp->in_buffer_togo>0);
-	}
-	*byte=*(sp->in_buffer_cur);
-	sp->in_buffer_cur++;
-	sp->in_buffer_togo--;
-	return(1);
-}
-
-static int
-OJPEGReadBytePeek(OJPEGState* sp, uint8* byte)
-{
-	if (sp->in_buffer_togo==0)
-	{
-		if (OJPEGReadBufferFill(sp)==0)
-			return(0);
-		assert(sp->in_buffer_togo>0);
-	}
-	*byte=*(sp->in_buffer_cur);
-	return(1);
-}
-
-static void
-OJPEGReadByteAdvance(OJPEGState* sp)
-{
-	assert(sp->in_buffer_togo>0);
-	sp->in_buffer_cur++;
-	sp->in_buffer_togo--;
-}
-
-static int
-OJPEGReadWord(OJPEGState* sp, uint16* word)
-{
-	uint8 m;
-	if (OJPEGReadByte(sp,&m)==0)
-		return(0);
-	*word=(m<<8);
-	if (OJPEGReadByte(sp,&m)==0)
-		return(0);
-	*word|=m;
-	return(1);
-}
-
-static int
-OJPEGReadBlock(OJPEGState* sp, uint16 len, void* mem)
-{
-	uint16 mlen;
-	uint8* mmem;
-	uint16 n;
-	assert(len>0);
-	mlen=len;
-	mmem=mem;
-	do
-	{
-		if (sp->in_buffer_togo==0)
-		{
-			if (OJPEGReadBufferFill(sp)==0)
-				return(0);
-			assert(sp->in_buffer_togo>0);
-		}
-		n=mlen;
-		if (n>sp->in_buffer_togo)
-			n=sp->in_buffer_togo;
-		_TIFFmemcpy(mmem,sp->in_buffer_cur,n);
-		sp->in_buffer_cur+=n;
-		sp->in_buffer_togo-=n;
-		mlen-=n;
-		mmem+=n;
-	} while(mlen>0);
-	return(1);
-}
-
-static void
-OJPEGReadSkip(OJPEGState* sp, uint16 len)
-{
-	uint16 m;
-	uint16 n;
-	m=len;
-	n=m;
-	if (n>sp->in_buffer_togo)
-		n=sp->in_buffer_togo;
-	sp->in_buffer_cur+=n;
-	sp->in_buffer_togo-=n;
-	m-=n;
-	if (m>0)
-	{
-		assert(sp->in_buffer_togo==0);
-		n=m;
-		if (n>sp->in_buffer_file_togo)
-			n=sp->in_buffer_file_togo;
-		sp->in_buffer_file_pos+=n;
-		sp->in_buffer_file_togo-=n;
-		sp->in_buffer_file_pos_log=0;
-		/* we don't skip past jpeginterchangeformat/strile block...
-		 * if that is asked from us, we're dealing with totally bazurk
-		 * data anyway, and we've not seen this happening on any
-		 * testfile, so we might as well likely cause some other
-		 * meaningless error to be passed at some later time
-		 */
-	}
-}
-
-static int
-OJPEGWriteStream(TIFF* tif, void** mem, uint32* len)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	*len=0;
-	do
-	{
-		assert(sp->out_state<=ososEoi);
-		switch(sp->out_state)
-		{
-			case ososSoi:
-				OJPEGWriteStreamSoi(tif,mem,len);
-				break;
-			case ososQTable0:
-				OJPEGWriteStreamQTable(tif,0,mem,len);
-				break;
-			case ososQTable1:
-				OJPEGWriteStreamQTable(tif,1,mem,len);
-				break;
-			case ososQTable2:
-				OJPEGWriteStreamQTable(tif,2,mem,len);
-				break;
-			case ososQTable3:
-				OJPEGWriteStreamQTable(tif,3,mem,len);
-				break;
-			case ososDcTable0:
-				OJPEGWriteStreamDcTable(tif,0,mem,len);
-				break;
-			case ososDcTable1:
-				OJPEGWriteStreamDcTable(tif,1,mem,len);
-				break;
-			case ososDcTable2:
-				OJPEGWriteStreamDcTable(tif,2,mem,len);
-				break;
-			case ososDcTable3:
-				OJPEGWriteStreamDcTable(tif,3,mem,len);
-				break;
-			case ososAcTable0:
-				OJPEGWriteStreamAcTable(tif,0,mem,len);
-				break;
-			case ososAcTable1:
-				OJPEGWriteStreamAcTable(tif,1,mem,len);
-				break;
-			case ososAcTable2:
-				OJPEGWriteStreamAcTable(tif,2,mem,len);
-				break;
-			case ososAcTable3:
-				OJPEGWriteStreamAcTable(tif,3,mem,len);
-				break;
-			case ososDri:
-				OJPEGWriteStreamDri(tif,mem,len);
-				break;
-			case ososSof:
-				OJPEGWriteStreamSof(tif,mem,len);
-				break;
-			case ososSos:
-				OJPEGWriteStreamSos(tif,mem,len);
-				break;
-			case ososCompressed:
-				if (OJPEGWriteStreamCompressed(tif,mem,len)==0)
-					return(0);
-				break;
-			case ososRst:
-				OJPEGWriteStreamRst(tif,mem,len);
-				break;
-			case ososEoi:
-				OJPEGWriteStreamEoi(tif,mem,len);
-				break;
-		}
-	} while (*len==0);
-	return(1);
-}
-
-static void
-OJPEGWriteStreamSoi(TIFF* tif, void** mem, uint32* len)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	assert(OJPEG_BUFFER>=2);
-	sp->out_buffer[0]=255;
-	sp->out_buffer[1]=JPEG_MARKER_SOI;
-	*len=2;
-	*mem=(void*)sp->out_buffer;
-	sp->out_state++;
-}
-
-static void
-OJPEGWriteStreamQTable(TIFF* tif, uint8 table_index, void** mem, uint32* len)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	if (sp->qtable[table_index]!=0)
-	{
-		*mem=(void*)(sp->qtable[table_index]+sizeof(uint32));
-		*len=*((uint32*)sp->qtable[table_index])-sizeof(uint32);
-	}
-	sp->out_state++;
-}
-
-static void
-OJPEGWriteStreamDcTable(TIFF* tif, uint8 table_index, void** mem, uint32* len)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	if (sp->dctable[table_index]!=0)
-	{
-		*mem=(void*)(sp->dctable[table_index]+sizeof(uint32));
-		*len=*((uint32*)sp->dctable[table_index])-sizeof(uint32);
-	}
-	sp->out_state++;
-}
-
-static void
-OJPEGWriteStreamAcTable(TIFF* tif, uint8 table_index, void** mem, uint32* len)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	if (sp->actable[table_index]!=0)
-	{
-		*mem=(void*)(sp->actable[table_index]+sizeof(uint32));
-		*len=*((uint32*)sp->actable[table_index])-sizeof(uint32);
-	}
-	sp->out_state++;
-}
-
-static void
-OJPEGWriteStreamDri(TIFF* tif, void** mem, uint32* len)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	assert(OJPEG_BUFFER>=6);
-	if (sp->restart_interval!=0)
-	{
-		sp->out_buffer[0]=255;
-		sp->out_buffer[1]=JPEG_MARKER_DRI;
-		sp->out_buffer[2]=0;
-		sp->out_buffer[3]=4;
-		sp->out_buffer[4]=(sp->restart_interval>>8);
-		sp->out_buffer[5]=(sp->restart_interval&255);
-		*len=6;
-		*mem=(void*)sp->out_buffer;
-	}
-	sp->out_state++;
-}
-
-static void
-OJPEGWriteStreamSof(TIFF* tif, void** mem, uint32* len)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	uint8 m;
-	assert(OJPEG_BUFFER>=2+8+sp->samples_per_pixel_per_plane*3);
-	assert(255>=8+sp->samples_per_pixel_per_plane*3);
-	sp->out_buffer[0]=255;
-	sp->out_buffer[1]=sp->sof_marker_id;
-	/* Lf */
-	sp->out_buffer[2]=0;
-	sp->out_buffer[3]=8+sp->samples_per_pixel_per_plane*3;
-	/* P */
-	sp->out_buffer[4]=8;
-	/* Y */
-	sp->out_buffer[5]=(sp->sof_y>>8);
-	sp->out_buffer[6]=(sp->sof_y&255);
-	/* X */
-	sp->out_buffer[7]=(sp->sof_x>>8);
-	sp->out_buffer[8]=(sp->sof_x&255);
-	/* Nf */
-	sp->out_buffer[9]=sp->samples_per_pixel_per_plane;
-	for (m=0; m<sp->samples_per_pixel_per_plane; m++)
-	{
-		/* C */
-		sp->out_buffer[10+m*3]=sp->sof_c[sp->plane_sample_offset+m];
-		/* H and V */
-		sp->out_buffer[10+m*3+1]=sp->sof_hv[sp->plane_sample_offset+m];
-		/* Tq */
-		sp->out_buffer[10+m*3+2]=sp->sof_tq[sp->plane_sample_offset+m];
-	}
-	*len=10+sp->samples_per_pixel_per_plane*3;
-	*mem=(void*)sp->out_buffer;
-	sp->out_state++;
-}
-
-static void
-OJPEGWriteStreamSos(TIFF* tif, void** mem, uint32* len)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	uint8 m;
-	assert(OJPEG_BUFFER>=2+6+sp->samples_per_pixel_per_plane*2);
-	assert(255>=6+sp->samples_per_pixel_per_plane*2);
-	sp->out_buffer[0]=255;
-	sp->out_buffer[1]=JPEG_MARKER_SOS;
-	/* Ls */
-	sp->out_buffer[2]=0;
-	sp->out_buffer[3]=6+sp->samples_per_pixel_per_plane*2;
-	/* Ns */
-	sp->out_buffer[4]=sp->samples_per_pixel_per_plane;
-	for (m=0; m<sp->samples_per_pixel_per_plane; m++)
-	{
-		/* Cs */
-		sp->out_buffer[5+m*2]=sp->sos_cs[sp->plane_sample_offset+m];
-		/* Td and Ta */
-		sp->out_buffer[5+m*2+1]=sp->sos_tda[sp->plane_sample_offset+m];
-	}
-	/* Ss */
-	sp->out_buffer[5+sp->samples_per_pixel_per_plane*2]=0;
-	/* Se */
-	sp->out_buffer[5+sp->samples_per_pixel_per_plane*2+1]=63;
-	/* Ah and Al */
-	sp->out_buffer[5+sp->samples_per_pixel_per_plane*2+2]=0;
-	*len=8+sp->samples_per_pixel_per_plane*2;
-	*mem=(void*)sp->out_buffer;
-	sp->out_state++;
-}
-
-static int
-OJPEGWriteStreamCompressed(TIFF* tif, void** mem, uint32* len)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	if (sp->in_buffer_togo==0)
-	{
-		if (OJPEGReadBufferFill(sp)==0)
-			return(0);
-		assert(sp->in_buffer_togo>0);
-	}
-	*len=sp->in_buffer_togo;
-	*mem=(void*)sp->in_buffer_cur;
-	sp->in_buffer_togo=0;
-	if (sp->in_buffer_file_togo==0)
-	{
-		switch(sp->in_buffer_source)
-		{
-			case osibsStrile:
-				if (sp->in_buffer_next_strile<sp->in_buffer_strile_count)  
-					sp->out_state=ososRst;
-				else
-					sp->out_state=ososEoi;
-				break;
-			case osibsEof:
-				sp->out_state=ososEoi;
-				break;
-			default:
-				break;
-		}
-	}
-	return(1);
-}
-
-static void
-OJPEGWriteStreamRst(TIFF* tif, void** mem, uint32* len)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	assert(OJPEG_BUFFER>=2);
-	sp->out_buffer[0]=255;
-	sp->out_buffer[1]=JPEG_MARKER_RST0+sp->restart_index;
-	sp->restart_index++;
-	if (sp->restart_index==8)
-		sp->restart_index=0;
-	*len=2;
-	*mem=(void*)sp->out_buffer;
-	sp->out_state=ososCompressed;
-}
-
-static void
-OJPEGWriteStreamEoi(TIFF* tif, void** mem, uint32* len)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	assert(OJPEG_BUFFER>=2);
-	sp->out_buffer[0]=255;
-	sp->out_buffer[1]=JPEG_MARKER_EOI;
-	*len=2;
-	*mem=(void*)sp->out_buffer;
-}
-
-#ifndef LIBJPEG_ENCAP_EXTERNAL
-static int
-jpeg_create_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo)
-{
-	return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_create_decompress(cinfo),1));
-}
-#endif
-
-#ifndef LIBJPEG_ENCAP_EXTERNAL
-static int
-jpeg_read_header_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, uint8 require_image)
-{
-	return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_read_header(cinfo,require_image),1));
-}
-#endif
-
-#ifndef LIBJPEG_ENCAP_EXTERNAL
-static int
-jpeg_start_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo)
-{
-	return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_start_decompress(cinfo),1));
-}
-#endif
-
-#ifndef LIBJPEG_ENCAP_EXTERNAL
-static int
-jpeg_read_scanlines_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* scanlines, uint32 max_lines)
-{
-	return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_read_scanlines(cinfo,scanlines,max_lines),1));
-}
-#endif
-
-#ifndef LIBJPEG_ENCAP_EXTERNAL
-static int
-jpeg_read_raw_data_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* data, uint32 max_lines)
-{
-	return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_read_raw_data(cinfo,data,max_lines),1));
-}
-#endif
-
-#ifndef LIBJPEG_ENCAP_EXTERNAL
-static void
-jpeg_encap_unwind(TIFF* tif)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	LONGJMP(sp->exit_jmpbuf,1);
-}
-#endif
-
-static void
-OJPEGLibjpegJpegErrorMgrOutputMessage(jpeg_common_struct* cinfo)
-{
-	char buffer[JMSG_LENGTH_MAX];
-	(*cinfo->err->format_message)(cinfo,buffer);
-	TIFFWarningExt(((TIFF*)(cinfo->client_data))->tif_clientdata,"LibJpeg", "%s", buffer);
-}
-
-static void
-OJPEGLibjpegJpegErrorMgrErrorExit(jpeg_common_struct* cinfo)
-{
-	char buffer[JMSG_LENGTH_MAX];
-	(*cinfo->err->format_message)(cinfo,buffer);
-	TIFFErrorExt(((TIFF*)(cinfo->client_data))->tif_clientdata,"LibJpeg", "%s", buffer);
-	jpeg_encap_unwind((TIFF*)(cinfo->client_data));
-}
-
-static void
-OJPEGLibjpegJpegSourceMgrInitSource(jpeg_decompress_struct* cinfo)
-{
-	(void)cinfo;
-}
-
-static boolean
-OJPEGLibjpegJpegSourceMgrFillInputBuffer(jpeg_decompress_struct* cinfo)
-{
-	TIFF* tif=(TIFF*)cinfo->client_data;
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	void* mem=0;
-	uint32 len=0;
-	if (OJPEGWriteStream(tif,&mem,&len)==0)
-	{
-		TIFFErrorExt(tif->tif_clientdata,"LibJpeg","Premature end of JPEG data");
-		jpeg_encap_unwind(tif);
-	}
-	sp->libjpeg_jpeg_source_mgr.bytes_in_buffer=len;
-	sp->libjpeg_jpeg_source_mgr.next_input_byte=mem;
-	return(1);
-}
-
-static void
-OJPEGLibjpegJpegSourceMgrSkipInputData(jpeg_decompress_struct* cinfo, long num_bytes)
-{
-	TIFF* tif=(TIFF*)cinfo->client_data;
-	(void)num_bytes;
-	TIFFErrorExt(tif->tif_clientdata,"LibJpeg","Unexpected error");
-	jpeg_encap_unwind(tif);
-}
-
-static boolean
-OJPEGLibjpegJpegSourceMgrResyncToRestart(jpeg_decompress_struct* cinfo, int desired)
-{
-	TIFF* tif=(TIFF*)cinfo->client_data;
-	(void)desired;
-	TIFFErrorExt(tif->tif_clientdata,"LibJpeg","Unexpected error");
-	jpeg_encap_unwind(tif);
-	return(0);
-}
-
-static void
-OJPEGLibjpegJpegSourceMgrTermSource(jpeg_decompress_struct* cinfo)
-{
-	(void)cinfo;
-}
-
-#endif
-
-
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_open.c b/Source/LibTIFF/tif_open.c
deleted file mode 100644
index bbb2027..0000000
--- a/Source/LibTIFF/tif_open.c
+++ /dev/null
@@ -1,695 +0,0 @@
-/* $Id: tif_open.c,v 1.37 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library.
- */
-#include "tiffiop.h"
-
-static const long typemask[13] = {
-	(long)0L,		/* TIFF_NOTYPE */
-	(long)0x000000ffL,	/* TIFF_BYTE */
-	(long)0xffffffffL,	/* TIFF_ASCII */
-	(long)0x0000ffffL,	/* TIFF_SHORT */
-	(long)0xffffffffL,	/* TIFF_LONG */
-	(long)0xffffffffL,	/* TIFF_RATIONAL */
-	(long)0x000000ffL,	/* TIFF_SBYTE */
-	(long)0x000000ffL,	/* TIFF_UNDEFINED */
-	(long)0x0000ffffL,	/* TIFF_SSHORT */
-	(long)0xffffffffL,	/* TIFF_SLONG */
-	(long)0xffffffffL,	/* TIFF_SRATIONAL */
-	(long)0xffffffffL,	/* TIFF_FLOAT */
-	(long)0xffffffffL,	/* TIFF_DOUBLE */
-};
-static const int bigTypeshift[13] = {
-	0,		/* TIFF_NOTYPE */
-	24,		/* TIFF_BYTE */
-	0,		/* TIFF_ASCII */
-	16,		/* TIFF_SHORT */
-	0,		/* TIFF_LONG */
-	0,		/* TIFF_RATIONAL */
-	24,		/* TIFF_SBYTE */
-	24,		/* TIFF_UNDEFINED */
-	16,		/* TIFF_SSHORT */
-	0,		/* TIFF_SLONG */
-	0,		/* TIFF_SRATIONAL */
-	0,		/* TIFF_FLOAT */
-	0,		/* TIFF_DOUBLE */
-};
-static const int litTypeshift[13] = {
-	0,		/* TIFF_NOTYPE */
-	0,		/* TIFF_BYTE */
-	0,		/* TIFF_ASCII */
-	0,		/* TIFF_SHORT */
-	0,		/* TIFF_LONG */
-	0,		/* TIFF_RATIONAL */
-	0,		/* TIFF_SBYTE */
-	0,		/* TIFF_UNDEFINED */
-	0,		/* TIFF_SSHORT */
-	0,		/* TIFF_SLONG */
-	0,		/* TIFF_SRATIONAL */
-	0,		/* TIFF_FLOAT */
-	0,		/* TIFF_DOUBLE */
-};
-
-/*
- * Dummy functions to fill the omitted client procedures.
- */
-static int
-_tiffDummyMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize)
-{
-	(void) fd; (void) pbase; (void) psize;
-	return (0);
-}
-
-static void
-_tiffDummyUnmapProc(thandle_t fd, tdata_t base, toff_t size)
-{
-	(void) fd; (void) base; (void) size;
-}
-
-/*
- * Initialize the shift & mask tables, and the
- * byte swapping state according to the file
- * contents and the machine architecture.
- */
-static void
-TIFFInitOrder(TIFF* tif, int magic)
-{
-	tif->tif_typemask = typemask;
-	if (magic == TIFF_BIGENDIAN) {
-		tif->tif_typeshift = bigTypeshift;
-#ifndef WORDS_BIGENDIAN
-		tif->tif_flags |= TIFF_SWAB;
-#endif
-	} else {
-		tif->tif_typeshift = litTypeshift;
-#ifdef WORDS_BIGENDIAN
-		tif->tif_flags |= TIFF_SWAB;
-#endif
-	}
-}
-
-int
-_TIFFgetMode(const char* mode, const char* module)
-{
-	int m = -1;
-
-	switch (mode[0]) {
-	case 'r':
-		m = O_RDONLY;
-		if (mode[1] == '+')
-			m = O_RDWR;
-		break;
-	case 'w':
-	case 'a':
-		m = O_RDWR|O_CREAT;
-		if (mode[0] == 'w')
-			m |= O_TRUNC;
-		break;
-	default:
-		TIFFErrorExt(0, module, "\"%s\": Bad mode", mode);
-		break;
-	}
-	return (m);
-}
-
-TIFF*
-TIFFClientOpen(
-	const char* name, const char* mode,
-	thandle_t clientdata,
-	TIFFReadWriteProc readproc,
-	TIFFReadWriteProc writeproc,
-	TIFFSeekProc seekproc,
-	TIFFCloseProc closeproc,
-	TIFFSizeProc sizeproc,
-	TIFFMapFileProc mapproc,
-	TIFFUnmapFileProc unmapproc
-)
-{
-	static const char module[] = "TIFFClientOpen";
-	TIFF *tif;
-	int m;
-	const char* cp;
-
-	m = _TIFFgetMode(mode, module);
-	if (m == -1)
-		goto bad2;
-	tif = (TIFF *)_TIFFmalloc(sizeof (TIFF) + strlen(name) + 1);
-	if (tif == NULL) {
-		TIFFErrorExt(clientdata, module, "%s: Out of memory (TIFF structure)", name);
-		goto bad2;
-	}
-	_TIFFmemset(tif, 0, sizeof (*tif));
-	tif->tif_name = (char *)tif + sizeof (TIFF);
-	strcpy(tif->tif_name, name);
-	tif->tif_mode = m &~ (O_CREAT|O_TRUNC);
-	tif->tif_curdir = (tdir_t) -1;		/* non-existent directory */
-	tif->tif_curoff = 0;
-	tif->tif_curstrip = (tstrip_t) -1;	/* invalid strip */
-	tif->tif_row = (uint32) -1;		/* read/write pre-increment */
-	tif->tif_clientdata = clientdata;
-	if (!readproc || !writeproc || !seekproc || !closeproc || !sizeproc) {
-		TIFFErrorExt(clientdata, module,
-			  "One of the client procedures is NULL pointer.");
-		goto bad2;
-	}
-	tif->tif_readproc = readproc;
-	tif->tif_writeproc = writeproc;
-	tif->tif_seekproc = seekproc;
-	tif->tif_closeproc = closeproc;
-	tif->tif_sizeproc = sizeproc;
-        if (mapproc)
-		tif->tif_mapproc = mapproc;
-	else
-		tif->tif_mapproc = _tiffDummyMapProc;
-	if (unmapproc)
-		tif->tif_unmapproc = unmapproc;
-	else
-		tif->tif_unmapproc = _tiffDummyUnmapProc;
-	_TIFFSetDefaultCompressionState(tif);	/* setup default state */
-	/*
-	 * Default is to return data MSB2LSB and enable the
-	 * use of memory-mapped files and strip chopping when
-	 * a file is opened read-only.
-	 */
-	tif->tif_flags = FILLORDER_MSB2LSB;
-	if (m == O_RDONLY )
-		tif->tif_flags |= TIFF_MAPPED;
-
-#ifdef STRIPCHOP_DEFAULT
-	if (m == O_RDONLY || m == O_RDWR)
-		tif->tif_flags |= STRIPCHOP_DEFAULT;
-#endif
-
-	/*
-	 * Process library-specific flags in the open mode string.
-	 * The following flags may be used to control intrinsic library
-	 * behaviour that may or may not be desirable (usually for
-	 * compatibility with some application that claims to support
-	 * TIFF but only supports some braindead idea of what the
-	 * vendor thinks TIFF is):
-	 *
-	 * 'l'		use little-endian byte order for creating a file
-	 * 'b'		use big-endian byte order for creating a file
-	 * 'L'		read/write information using LSB2MSB bit order
-	 * 'B'		read/write information using MSB2LSB bit order
-	 * 'H'		read/write information using host bit order
-	 * 'M'		enable use of memory-mapped files when supported
-	 * 'm'		disable use of memory-mapped files
-	 * 'C'		enable strip chopping support when reading
-	 * 'c'		disable strip chopping support
-	 * 'h'		read TIFF header only, do not load the first IFD
-	 *
-	 * The use of the 'l' and 'b' flags is strongly discouraged.
-	 * These flags are provided solely because numerous vendors,
-	 * typically on the PC, do not correctly support TIFF; they
-	 * only support the Intel little-endian byte order.  This
-	 * support is not configured by default because it supports
-	 * the violation of the TIFF spec that says that readers *MUST*
-	 * support both byte orders.  It is strongly recommended that
-	 * you not use this feature except to deal with busted apps
-	 * that write invalid TIFF.  And even in those cases you should
-	 * bang on the vendors to fix their software.
-	 *
-	 * The 'L', 'B', and 'H' flags are intended for applications
-	 * that can optimize operations on data by using a particular
-	 * bit order.  By default the library returns data in MSB2LSB
-	 * bit order for compatibiltiy with older versions of this
-	 * library.  Returning data in the bit order of the native cpu
-	 * makes the most sense but also requires applications to check
-	 * the value of the FillOrder tag; something they probably do
-	 * not do right now.
-	 *
-	 * The 'M' and 'm' flags are provided because some virtual memory
-	 * systems exhibit poor behaviour when large images are mapped.
-	 * These options permit clients to control the use of memory-mapped
-	 * files on a per-file basis.
-	 *
-	 * The 'C' and 'c' flags are provided because the library support
-	 * for chopping up large strips into multiple smaller strips is not
-	 * application-transparent and as such can cause problems.  The 'c'
-	 * option permits applications that only want to look at the tags,
-	 * for example, to get the unadulterated TIFF tag information.
-	 */
-	for (cp = mode; *cp; cp++)
-		switch (*cp) {
-		case 'b':
-#ifndef WORDS_BIGENDIAN
-		    if (m&O_CREAT)
-				tif->tif_flags |= TIFF_SWAB;
-#endif
-			break;
-		case 'l':
-#ifdef WORDS_BIGENDIAN
-			if ((m&O_CREAT))
-				tif->tif_flags |= TIFF_SWAB;
-#endif
-			break;
-		case 'B':
-			tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) |
-			    FILLORDER_MSB2LSB;
-			break;
-		case 'L':
-			tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) |
-			    FILLORDER_LSB2MSB;
-			break;
-		case 'H':
-			tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) |
-			    HOST_FILLORDER;
-			break;
-		case 'M':
-			if (m == O_RDONLY)
-				tif->tif_flags |= TIFF_MAPPED;
-			break;
-		case 'm':
-			if (m == O_RDONLY)
-				tif->tif_flags &= ~TIFF_MAPPED;
-			break;
-		case 'C':
-			if (m == O_RDONLY)
-				tif->tif_flags |= TIFF_STRIPCHOP;
-			break;
-		case 'c':
-			if (m == O_RDONLY)
-				tif->tif_flags &= ~TIFF_STRIPCHOP;
-			break;
-		case 'h':
-			tif->tif_flags |= TIFF_HEADERONLY;
-			break;
-		}
-	/*
-	 * Read in TIFF header.
-	 */
-	if ((m & O_TRUNC) ||
-	    !ReadOK(tif, &tif->tif_header, sizeof (TIFFHeader))) {
-		if (tif->tif_mode == O_RDONLY) {
-			TIFFErrorExt(tif->tif_clientdata, name,
-				     "Cannot read TIFF header");
-			goto bad;
-		}
-		/*
-		 * Setup header and write.
-		 */
-#ifdef WORDS_BIGENDIAN
-		tif->tif_header.tiff_magic = tif->tif_flags & TIFF_SWAB
-		    ? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN;
-#else
-		tif->tif_header.tiff_magic = tif->tif_flags & TIFF_SWAB
-		    ? TIFF_BIGENDIAN : TIFF_LITTLEENDIAN;
-#endif
-		tif->tif_header.tiff_version = TIFF_VERSION;
-		if (tif->tif_flags & TIFF_SWAB)
-			TIFFSwabShort(&tif->tif_header.tiff_version);
-		tif->tif_header.tiff_diroff = 0;	/* filled in later */
-
-
-                /*
-                 * The doc for "fopen" for some STD_C_LIBs says that if you 
-                 * open a file for modify ("+"), then you must fseek (or 
-                 * fflush?) between any freads and fwrites.  This is not
-                 * necessary on most systems, but has been shown to be needed
-                 * on Solaris. 
-                 */
-                TIFFSeekFile( tif, 0, SEEK_SET );
-               
-		if (!WriteOK(tif, &tif->tif_header, sizeof (TIFFHeader))) {
-			TIFFErrorExt(tif->tif_clientdata, name,
-				     "Error writing TIFF header");
-			goto bad;
-		}
-		/*
-		 * Setup the byte order handling.
-		 */
-		TIFFInitOrder(tif, tif->tif_header.tiff_magic);
-		/*
-		 * Setup default directory.
-		 */
-		if (!TIFFDefaultDirectory(tif))
-			goto bad;
-		tif->tif_diroff = 0;
-		tif->tif_dirlist = NULL;
-		tif->tif_dirlistsize = 0;
-		tif->tif_dirnumber = 0;
-		return (tif);
-	}
-	/*
-	 * Setup the byte order handling.
-	 */
-	if (tif->tif_header.tiff_magic != TIFF_BIGENDIAN &&
-	    tif->tif_header.tiff_magic != TIFF_LITTLEENDIAN
-#if MDI_SUPPORT
-	    &&
-#if HOST_BIGENDIAN
-	    tif->tif_header.tiff_magic != MDI_BIGENDIAN
-#else
-	    tif->tif_header.tiff_magic != MDI_LITTLEENDIAN
-#endif
-	    ) {
-		TIFFErrorExt(tif->tif_clientdata, name,
-			"Not a TIFF or MDI file, bad magic number %d (0x%x)",
-#else
-	    ) {
-		TIFFErrorExt(tif->tif_clientdata, name,
-			     "Not a TIFF file, bad magic number %d (0x%x)",
-#endif
-		    tif->tif_header.tiff_magic,
-		    tif->tif_header.tiff_magic);
-		goto bad;
-	}
-	TIFFInitOrder(tif, tif->tif_header.tiff_magic);
-	/*
-	 * Swap header if required.
-	 */
-	if (tif->tif_flags & TIFF_SWAB) {
-		TIFFSwabShort(&tif->tif_header.tiff_version);
-		TIFFSwabLong(&tif->tif_header.tiff_diroff);
-	}
-	/*
-	 * Now check version (if needed, it's been byte-swapped).
-	 * Note that this isn't actually a version number, it's a
-	 * magic number that doesn't change (stupid).
-	 */
-	if (tif->tif_header.tiff_version == TIFF_BIGTIFF_VERSION) {
-		TIFFErrorExt(tif->tif_clientdata, name,
-                          "This is a BigTIFF file.  This format not supported\n"
-                          "by this version of libtiff." );
-		goto bad;
-	}
-	if (tif->tif_header.tiff_version != TIFF_VERSION) {
-		TIFFErrorExt(tif->tif_clientdata, name,
-		    "Not a TIFF file, bad version number %d (0x%x)",
-		    tif->tif_header.tiff_version,
-		    tif->tif_header.tiff_version);
-		goto bad;
-	}
-	tif->tif_flags |= TIFF_MYBUFFER;
-	tif->tif_rawcp = tif->tif_rawdata = 0;
-	tif->tif_rawdatasize = 0;
-
-	/*
-	 * Sometimes we do not want to read the first directory (for example,
-	 * it may be broken) and want to proceed to other directories. I this
-	 * case we use the TIFF_HEADERONLY flag to open file and return
-	 * immediately after reading TIFF header.
-	 */
-	if (tif->tif_flags & TIFF_HEADERONLY)
-		return (tif);
-
-	/*
-	 * Setup initial directory.
-	 */
-	switch (mode[0]) {
-	case 'r':
-		tif->tif_nextdiroff = tif->tif_header.tiff_diroff;
-		/*
-		 * Try to use a memory-mapped file if the client
-		 * has not explicitly suppressed usage with the
-		 * 'm' flag in the open mode (see above).
-		 */
-		if ((tif->tif_flags & TIFF_MAPPED) &&
-	!TIFFMapFileContents(tif, (tdata_t*) &tif->tif_base, &tif->tif_size))
-			tif->tif_flags &= ~TIFF_MAPPED;
-		if (TIFFReadDirectory(tif)) {
-			tif->tif_rawcc = -1;
-			tif->tif_flags |= TIFF_BUFFERSETUP;
-			return (tif);
-		}
-		break;
-	case 'a':
-		/*
-		 * New directories are automatically append
-		 * to the end of the directory chain when they
-		 * are written out (see TIFFWriteDirectory).
-		 */
-		if (!TIFFDefaultDirectory(tif))
-			goto bad;
-		return (tif);
-	}
-bad:
-	tif->tif_mode = O_RDONLY;	/* XXX avoid flush */
-        TIFFCleanup(tif);
-bad2:
-	return ((TIFF*)0);
-}
-
-/*
- * Query functions to access private data.
- */
-
-/*
- * Return open file's name.
- */
-const char *
-TIFFFileName(TIFF* tif)
-{
-	return (tif->tif_name);
-}
-
-/*
- * Set the file name.
- */
-const char *
-TIFFSetFileName(TIFF* tif, const char *name)
-{
-	const char* old_name = tif->tif_name;
-	tif->tif_name = (char *)name;
-	return (old_name);
-}
-
-/*
- * Return open file's I/O descriptor.
- */
-int
-TIFFFileno(TIFF* tif)
-{
-	return (tif->tif_fd);
-}
-
-/*
- * Set open file's I/O descriptor, and return previous value.
- */
-int
-TIFFSetFileno(TIFF* tif, int fd)
-{
-        int old_fd = tif->tif_fd;
-	tif->tif_fd = fd;
-	return old_fd;
-}
-
-/*
- * Return open file's clientdata.
- */
-thandle_t
-TIFFClientdata(TIFF* tif)
-{
-	return (tif->tif_clientdata);
-}
-
-/*
- * Set open file's clientdata, and return previous value.
- */
-thandle_t
-TIFFSetClientdata(TIFF* tif, thandle_t newvalue)
-{
-	thandle_t m = tif->tif_clientdata;
-	tif->tif_clientdata = newvalue;
-	return m;
-}
-
-/*
- * Return read/write mode.
- */
-int
-TIFFGetMode(TIFF* tif)
-{
-	return (tif->tif_mode);
-}
-
-/*
- * Return read/write mode.
- */
-int
-TIFFSetMode(TIFF* tif, int mode)
-{
-	int old_mode = tif->tif_mode;
-	tif->tif_mode = mode;
-	return (old_mode);
-}
-
-/*
- * Return nonzero if file is organized in
- * tiles; zero if organized as strips.
- */
-int
-TIFFIsTiled(TIFF* tif)
-{
-	return (isTiled(tif));
-}
-
-/*
- * Return current row being read/written.
- */
-uint32
-TIFFCurrentRow(TIFF* tif)
-{
-	return (tif->tif_row);
-}
-
-/*
- * Return index of the current directory.
- */
-tdir_t
-TIFFCurrentDirectory(TIFF* tif)
-{
-	return (tif->tif_curdir);
-}
-
-/*
- * Return current strip.
- */
-tstrip_t
-TIFFCurrentStrip(TIFF* tif)
-{
-	return (tif->tif_curstrip);
-}
-
-/*
- * Return current tile.
- */
-ttile_t
-TIFFCurrentTile(TIFF* tif)
-{
-	return (tif->tif_curtile);
-}
-
-/*
- * Return nonzero if the file has byte-swapped data.
- */
-int
-TIFFIsByteSwapped(TIFF* tif)
-{
-	return ((tif->tif_flags & TIFF_SWAB) != 0);
-}
-
-/*
- * Return nonzero if the data is returned up-sampled.
- */
-int
-TIFFIsUpSampled(TIFF* tif)
-{
-	return (isUpSampled(tif));
-}
-
-/*
- * Return nonzero if the data is returned in MSB-to-LSB bit order.
- */
-int
-TIFFIsMSB2LSB(TIFF* tif)
-{
-	return (isFillOrder(tif, FILLORDER_MSB2LSB));
-}
-
-/*
- * Return nonzero if given file was written in big-endian order.
- */
-int
-TIFFIsBigEndian(TIFF* tif)
-{
-	return (tif->tif_header.tiff_magic == TIFF_BIGENDIAN);
-}
-
-/*
- * Return pointer to file read method.
- */
-TIFFReadWriteProc
-TIFFGetReadProc(TIFF* tif)
-{
-	return (tif->tif_readproc);
-}
-
-/*
- * Return pointer to file write method.
- */
-TIFFReadWriteProc
-TIFFGetWriteProc(TIFF* tif)
-{
-	return (tif->tif_writeproc);
-}
-
-/*
- * Return pointer to file seek method.
- */
-TIFFSeekProc
-TIFFGetSeekProc(TIFF* tif)
-{
-	return (tif->tif_seekproc);
-}
-
-/*
- * Return pointer to file close method.
- */
-TIFFCloseProc
-TIFFGetCloseProc(TIFF* tif)
-{
-	return (tif->tif_closeproc);
-}
-
-/*
- * Return pointer to file size requesting method.
- */
-TIFFSizeProc
-TIFFGetSizeProc(TIFF* tif)
-{
-	return (tif->tif_sizeproc);
-}
-
-/*
- * Return pointer to memory mapping method.
- */
-TIFFMapFileProc
-TIFFGetMapFileProc(TIFF* tif)
-{
-	return (tif->tif_mapproc);
-}
-
-/*
- * Return pointer to memory unmapping method.
- */
-TIFFUnmapFileProc
-TIFFGetUnmapFileProc(TIFF* tif)
-{
-	return (tif->tif_unmapproc);
-}
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_packbits.c b/Source/LibTIFF/tif_packbits.c
deleted file mode 100644
index 79e9a8e..0000000
--- a/Source/LibTIFF/tif_packbits.c
+++ /dev/null
@@ -1,300 +0,0 @@
-/* $Id: tif_packbits.c,v 1.37 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-#include "tiffiop.h"
-#ifdef PACKBITS_SUPPORT
-/*
- * TIFF Library.
- *
- * PackBits Compression Algorithm Support
- */
-#include <stdio.h>
-
-static int
-PackBitsPreEncode(TIFF* tif, tsample_t s)
-{
-	(void) s;
-
-        if (!(tif->tif_data = (tidata_t)_TIFFmalloc(sizeof(tsize_t))))
-		return (0);
-	/*
-	 * Calculate the scanline/tile-width size in bytes.
-	 */
-	if (isTiled(tif))
-		*(tsize_t*)tif->tif_data = TIFFTileRowSize(tif);
-	else
-		*(tsize_t*)tif->tif_data = TIFFScanlineSize(tif);
-	return (1);
-}
-
-static int
-PackBitsPostEncode(TIFF* tif)
-{
-        if (tif->tif_data)
-            _TIFFfree(tif->tif_data);
-	return (1);
-}
-
-/*
- * NB: tidata is the type representing *(tidata_t);
- *     if tidata_t is made signed then this type must
- *     be adjusted accordingly.
- */
-typedef unsigned char tidata;
-
-/*
- * Encode a run of pixels.
- */
-static int
-PackBitsEncode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s)
-{
-	unsigned char* bp = (unsigned char*) buf;
-	tidata_t op, ep, lastliteral;
-	long n, slop;
-	int b;
-	enum { BASE, LITERAL, RUN, LITERAL_RUN } state;
-
-	(void) s;
-	op = tif->tif_rawcp;
-	ep = tif->tif_rawdata + tif->tif_rawdatasize;
-	state = BASE;
-	lastliteral = 0;
-	while (cc > 0) {
-		/*
-		 * Find the longest string of identical bytes.
-		 */
-		b = *bp++, cc--, n = 1;
-		for (; cc > 0 && b == *bp; cc--, bp++)
-			n++;
-	again:
-		if (op + 2 >= ep) {		/* insure space for new data */
-			/*
-			 * Be careful about writing the last
-			 * literal.  Must write up to that point
-			 * and then copy the remainder to the
-			 * front of the buffer.
-			 */
-			if (state == LITERAL || state == LITERAL_RUN) {
-				slop = op - lastliteral;
-				tif->tif_rawcc += lastliteral - tif->tif_rawcp;
-				if (!TIFFFlushData1(tif))
-					return (-1);
-				op = tif->tif_rawcp;
-				while (slop-- > 0)
-					*op++ = *lastliteral++;
-				lastliteral = tif->tif_rawcp;
-			} else {
-				tif->tif_rawcc += op - tif->tif_rawcp;
-				if (!TIFFFlushData1(tif))
-					return (-1);
-				op = tif->tif_rawcp;
-			}
-		}
-		switch (state) {
-		case BASE:		/* initial state, set run/literal */
-			if (n > 1) {
-				state = RUN;
-				if (n > 128) {
-					*op++ = (tidata) -127;
-					*op++ = (tidataval_t) b;
-					n -= 128;
-					goto again;
-				}
-				*op++ = (tidataval_t)(-(n-1));
-				*op++ = (tidataval_t) b;
-			} else {
-				lastliteral = op;
-				*op++ = 0;
-				*op++ = (tidataval_t) b;
-				state = LITERAL;
-			}
-			break;
-		case LITERAL:		/* last object was literal string */
-			if (n > 1) {
-				state = LITERAL_RUN;
-				if (n > 128) {
-					*op++ = (tidata) -127;
-					*op++ = (tidataval_t) b;
-					n -= 128;
-					goto again;
-				}
-				*op++ = (tidataval_t)(-(n-1));	/* encode run */
-				*op++ = (tidataval_t) b;
-			} else {			/* extend literal */
-				if (++(*lastliteral) == 127)
-					state = BASE;
-				*op++ = (tidataval_t) b;
-			}
-			break;
-		case RUN:		/* last object was run */
-			if (n > 1) {
-				if (n > 128) {
-					*op++ = (tidata) -127;
-					*op++ = (tidataval_t) b;
-					n -= 128;
-					goto again;
-				}
-				*op++ = (tidataval_t)(-(n-1));
-				*op++ = (tidataval_t) b;
-			} else {
-				lastliteral = op;
-				*op++ = 0;
-				*op++ = (tidataval_t) b;
-				state = LITERAL;
-			}
-			break;
-		case LITERAL_RUN:	/* literal followed by a run */
-			/*
-			 * Check to see if previous run should
-			 * be converted to a literal, in which
-			 * case we convert literal-run-literal
-			 * to a single literal.
-			 */
-			if (n == 1 && op[-2] == (tidata) -1 &&
-			    *lastliteral < 126) {
-				state = (((*lastliteral) += 2) == 127 ?
-				    BASE : LITERAL);
-				op[-2] = op[-1];	/* replicate */
-			} else
-				state = RUN;
-			goto again;
-		}
-	}
-	tif->tif_rawcc += op - tif->tif_rawcp;
-	tif->tif_rawcp = op;
-	return (1);
-}
-
-/*
- * Encode a rectangular chunk of pixels.  We break it up
- * into row-sized pieces to insure that encoded runs do
- * not span rows.  Otherwise, there can be problems with
- * the decoder if data is read, for example, by scanlines
- * when it was encoded by strips.
- */
-static int
-PackBitsEncodeChunk(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s)
-{
-	tsize_t rowsize = *(tsize_t*)tif->tif_data;
-
-	while ((long)cc > 0) {
-		int	chunk = rowsize;
-		
-		if( cc < chunk )
-		    chunk = cc;
-
-		if (PackBitsEncode(tif, bp, chunk, s) < 0)
-		    return (-1);
-		bp += chunk;
-		cc -= chunk;
-	}
-	return (1);
-}
-
-static int
-PackBitsDecode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s)
-{
-	char *bp;
-	tsize_t cc;
-	long n;
-	int b;
-
-	(void) s;
-	bp = (char*) tif->tif_rawcp;
-	cc = tif->tif_rawcc;
-	while (cc > 0 && (long)occ > 0) {
-		n = (long) *bp++, cc--;
-		/*
-		 * Watch out for compilers that
-		 * don't sign extend chars...
-		 */
-		if (n >= 128)
-			n -= 256;
-		if (n < 0) {		/* replicate next byte -n+1 times */
-			if (n == -128)	/* nop */
-				continue;
-                        n = -n + 1;
-                        if( occ < n )
-                        {
-							TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
-                                        "PackBitsDecode: discarding %ld bytes "
-                                        "to avoid buffer overrun",
-                                        n - occ);
-                            n = occ;
-                        }
-			occ -= n;
-			b = *bp++, cc--;
-			while (n-- > 0)
-				*op++ = (tidataval_t) b;
-		} else {		/* copy next n+1 bytes literally */
-			if (occ < n + 1)
-                        {
-                            TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
-                                        "PackBitsDecode: discarding %ld bytes "
-                                        "to avoid buffer overrun",
-                                        n - occ + 1);
-                            n = occ - 1;
-                        }
-                        _TIFFmemcpy(op, bp, ++n);
-			op += n; occ -= n;
-			bp += n; cc -= n;
-		}
-	}
-	tif->tif_rawcp = (tidata_t) bp;
-	tif->tif_rawcc = cc;
-	if (occ > 0) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-		    "PackBitsDecode: Not enough data for scanline %ld",
-		    (long) tif->tif_row);
-		return (0);
-	}
-	return (1);
-}
-
-int
-TIFFInitPackBits(TIFF* tif, int scheme)
-{
-	(void) scheme;
-	tif->tif_decoderow = PackBitsDecode;
-	tif->tif_decodestrip = PackBitsDecode;
-	tif->tif_decodetile = PackBitsDecode;
-	tif->tif_preencode = PackBitsPreEncode;
-        tif->tif_postencode = PackBitsPostEncode;
-	tif->tif_encoderow = PackBitsEncode;
-	tif->tif_encodestrip = PackBitsEncodeChunk;
-	tif->tif_encodetile = PackBitsEncodeChunk;
-	return (1);
-}
-#endif /* PACKBITS_SUPPORT */
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_pixarlog.c b/Source/LibTIFF/tif_pixarlog.c
deleted file mode 100644
index 7537af3..0000000
--- a/Source/LibTIFF/tif_pixarlog.c
+++ /dev/null
@@ -1,1371 +0,0 @@
-/* $Id: tif_pixarlog.c,v 1.37 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1996-1997 Sam Leffler
- * Copyright (c) 1996 Pixar
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Pixar, Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Pixar, Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL PIXAR, SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-#include "tiffiop.h"
-#ifdef PIXARLOG_SUPPORT
-
-/*
- * TIFF Library.
- * PixarLog Compression Support
- *
- * Contributed by Dan McCoy.
- *
- * PixarLog film support uses the TIFF library to store companded
- * 11 bit values into a tiff file, which are compressed using the 
- * zip compressor.  
- *
- * The codec can take as input and produce as output 32-bit IEEE float values 
- * as well as 16-bit or 8-bit unsigned integer values.
- *
- * On writing any of the above are converted into the internal
- * 11-bit log format.   In the case of  8 and 16 bit values, the
- * input is assumed to be unsigned linear color values that represent
- * the range 0-1.  In the case of IEEE values, the 0-1 range is assumed to
- * be the normal linear color range, in addition over 1 values are
- * accepted up to a value of about 25.0 to encode "hot" hightlights and such.
- * The encoding is lossless for 8-bit values, slightly lossy for the
- * other bit depths.  The actual color precision should be better
- * than the human eye can perceive with extra room to allow for
- * error introduced by further image computation.  As with any quantized
- * color format, it is possible to perform image calculations which
- * expose the quantization error. This format should certainly be less 
- * susceptable to such errors than standard 8-bit encodings, but more
- * susceptable than straight 16-bit or 32-bit encodings.
- *
- * On reading the internal format is converted to the desired output format.
- * The program can request which format it desires by setting the internal
- * pseudo tag TIFFTAG_PIXARLOGDATAFMT to one of these possible values:
- *  PIXARLOGDATAFMT_FLOAT     = provide IEEE float values.
- *  PIXARLOGDATAFMT_16BIT     = provide unsigned 16-bit integer values
- *  PIXARLOGDATAFMT_8BIT      = provide unsigned 8-bit integer values
- *
- * alternately PIXARLOGDATAFMT_8BITABGR provides unsigned 8-bit integer
- * values with the difference that if there are exactly three or four channels
- * (rgb or rgba) it swaps the channel order (bgr or abgr).
- *
- * PIXARLOGDATAFMT_11BITLOG provides the internal encoding directly
- * packed in 16-bit values.   However no tools are supplied for interpreting
- * these values.
- *
- * "hot" (over 1.0) areas written in floating point get clamped to
- * 1.0 in the integer data types.
- *
- * When the file is closed after writing, the bit depth and sample format
- * are set always to appear as if 8-bit data has been written into it.
- * That way a naive program unaware of the particulars of the encoding
- * gets the format it is most likely able to handle.
- *
- * The codec does it's own horizontal differencing step on the coded
- * values so the libraries predictor stuff should be turned off.
- * The codec also handle byte swapping the encoded values as necessary
- * since the library does not have the information necessary
- * to know the bit depth of the raw unencoded buffer.
- * 
- */
-
-#include "tif_predict.h"
-#include "../ZLib/zlib.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-
-/* Tables for converting to/from 11 bit coded values */
-
-#define  TSIZE	 2048		/* decode table size (11-bit tokens) */
-#define  TSIZEP1 2049		/* Plus one for slop */
-#define  ONE	 1250		/* token value of 1.0 exactly */
-#define  RATIO	 1.004		/* nominal ratio for log part */
-
-#define CODE_MASK 0x7ff         /* 11 bits. */
-
-static float  Fltsize;
-static float  LogK1, LogK2;
-
-#define REPEAT(n, op)   { int i; i=n; do { i--; op; } while (i>0); }
-
-static void
-horizontalAccumulateF(uint16 *wp, int n, int stride, float *op, 
-	float *ToLinearF)
-{
-    register unsigned int  cr, cg, cb, ca, mask;
-    register float  t0, t1, t2, t3;
-
-    if (n >= stride) {
-	mask = CODE_MASK;
-	if (stride == 3) {
-	    t0 = ToLinearF[cr = wp[0]];
-	    t1 = ToLinearF[cg = wp[1]];
-	    t2 = ToLinearF[cb = wp[2]];
-	    op[0] = t0;
-	    op[1] = t1;
-	    op[2] = t2;
-	    n -= 3;
-	    while (n > 0) {
-		wp += 3;
-		op += 3;
-		n -= 3;
-		t0 = ToLinearF[(cr += wp[0]) & mask];
-		t1 = ToLinearF[(cg += wp[1]) & mask];
-		t2 = ToLinearF[(cb += wp[2]) & mask];
-		op[0] = t0;
-		op[1] = t1;
-		op[2] = t2;
-	    }
-	} else if (stride == 4) {
-	    t0 = ToLinearF[cr = wp[0]];
-	    t1 = ToLinearF[cg = wp[1]];
-	    t2 = ToLinearF[cb = wp[2]];
-	    t3 = ToLinearF[ca = wp[3]];
-	    op[0] = t0;
-	    op[1] = t1;
-	    op[2] = t2;
-	    op[3] = t3;
-	    n -= 4;
-	    while (n > 0) {
-		wp += 4;
-		op += 4;
-		n -= 4;
-		t0 = ToLinearF[(cr += wp[0]) & mask];
-		t1 = ToLinearF[(cg += wp[1]) & mask];
-		t2 = ToLinearF[(cb += wp[2]) & mask];
-		t3 = ToLinearF[(ca += wp[3]) & mask];
-		op[0] = t0;
-		op[1] = t1;
-		op[2] = t2;
-		op[3] = t3;
-	    }
-	} else {
-	    REPEAT(stride, *op = ToLinearF[*wp&mask]; wp++; op++)
-	    n -= stride;
-	    while (n > 0) {
-		REPEAT(stride,
-		    wp[stride] += *wp; *op = ToLinearF[*wp&mask]; wp++; op++)
-		n -= stride;
-	    }
-	}
-    }
-}
-
-static void
-horizontalAccumulate12(uint16 *wp, int n, int stride, int16 *op,
-	float *ToLinearF)
-{
-    register unsigned int  cr, cg, cb, ca, mask;
-    register float  t0, t1, t2, t3;
-
-#define SCALE12 2048.0F
-#define CLAMP12(t) (((t) < 3071) ? (uint16) (t) : 3071)
-
-    if (n >= stride) {
-	mask = CODE_MASK;
-	if (stride == 3) {
-	    t0 = ToLinearF[cr = wp[0]] * SCALE12;
-	    t1 = ToLinearF[cg = wp[1]] * SCALE12;
-	    t2 = ToLinearF[cb = wp[2]] * SCALE12;
-	    op[0] = CLAMP12(t0);
-	    op[1] = CLAMP12(t1);
-	    op[2] = CLAMP12(t2);
-	    n -= 3;
-	    while (n > 0) {
-		wp += 3;
-		op += 3;
-		n -= 3;
-		t0 = ToLinearF[(cr += wp[0]) & mask] * SCALE12;
-		t1 = ToLinearF[(cg += wp[1]) & mask] * SCALE12;
-		t2 = ToLinearF[(cb += wp[2]) & mask] * SCALE12;
-		op[0] = CLAMP12(t0);
-		op[1] = CLAMP12(t1);
-		op[2] = CLAMP12(t2);
-	    }
-	} else if (stride == 4) {
-	    t0 = ToLinearF[cr = wp[0]] * SCALE12;
-	    t1 = ToLinearF[cg = wp[1]] * SCALE12;
-	    t2 = ToLinearF[cb = wp[2]] * SCALE12;
-	    t3 = ToLinearF[ca = wp[3]] * SCALE12;
-	    op[0] = CLAMP12(t0);
-	    op[1] = CLAMP12(t1);
-	    op[2] = CLAMP12(t2);
-	    op[3] = CLAMP12(t3);
-	    n -= 4;
-	    while (n > 0) {
-		wp += 4;
-		op += 4;
-		n -= 4;
-		t0 = ToLinearF[(cr += wp[0]) & mask] * SCALE12;
-		t1 = ToLinearF[(cg += wp[1]) & mask] * SCALE12;
-		t2 = ToLinearF[(cb += wp[2]) & mask] * SCALE12;
-		t3 = ToLinearF[(ca += wp[3]) & mask] * SCALE12;
-		op[0] = CLAMP12(t0);
-		op[1] = CLAMP12(t1);
-		op[2] = CLAMP12(t2);
-		op[3] = CLAMP12(t3);
-	    }
-	} else {
-	    REPEAT(stride, t0 = ToLinearF[*wp&mask] * SCALE12;
-                           *op = CLAMP12(t0); wp++; op++)
-	    n -= stride;
-	    while (n > 0) {
-		REPEAT(stride,
-		    wp[stride] += *wp; t0 = ToLinearF[wp[stride]&mask]*SCALE12;
-		    *op = CLAMP12(t0);  wp++; op++)
-		n -= stride;
-	    }
-	}
-    }
-}
-
-static void
-horizontalAccumulate16(uint16 *wp, int n, int stride, uint16 *op,
-	uint16 *ToLinear16)
-{
-    register unsigned int  cr, cg, cb, ca, mask;
-
-    if (n >= stride) {
-	mask = CODE_MASK;
-	if (stride == 3) {
-	    op[0] = ToLinear16[cr = wp[0]];
-	    op[1] = ToLinear16[cg = wp[1]];
-	    op[2] = ToLinear16[cb = wp[2]];
-	    n -= 3;
-	    while (n > 0) {
-		wp += 3;
-		op += 3;
-		n -= 3;
-		op[0] = ToLinear16[(cr += wp[0]) & mask];
-		op[1] = ToLinear16[(cg += wp[1]) & mask];
-		op[2] = ToLinear16[(cb += wp[2]) & mask];
-	    }
-	} else if (stride == 4) {
-	    op[0] = ToLinear16[cr = wp[0]];
-	    op[1] = ToLinear16[cg = wp[1]];
-	    op[2] = ToLinear16[cb = wp[2]];
-	    op[3] = ToLinear16[ca = wp[3]];
-	    n -= 4;
-	    while (n > 0) {
-		wp += 4;
-		op += 4;
-		n -= 4;
-		op[0] = ToLinear16[(cr += wp[0]) & mask];
-		op[1] = ToLinear16[(cg += wp[1]) & mask];
-		op[2] = ToLinear16[(cb += wp[2]) & mask];
-		op[3] = ToLinear16[(ca += wp[3]) & mask];
-	    }
-	} else {
-	    REPEAT(stride, *op = ToLinear16[*wp&mask]; wp++; op++)
-	    n -= stride;
-	    while (n > 0) {
-		REPEAT(stride,
-		    wp[stride] += *wp; *op = ToLinear16[*wp&mask]; wp++; op++)
-		n -= stride;
-	    }
-	}
-    }
-}
-
-/* 
- * Returns the log encoded 11-bit values with the horizontal
- * differencing undone.
- */
-static void
-horizontalAccumulate11(uint16 *wp, int n, int stride, uint16 *op)
-{
-    register unsigned int  cr, cg, cb, ca, mask;
-
-    if (n >= stride) {
-	mask = CODE_MASK;
-	if (stride == 3) {
-	    op[0] = cr = wp[0];  op[1] = cg = wp[1];  op[2] = cb = wp[2];
-	    n -= 3;
-	    while (n > 0) {
-		wp += 3;
-		op += 3;
-		n -= 3;
-		op[0] = (cr += wp[0]) & mask;
-		op[1] = (cg += wp[1]) & mask;
-		op[2] = (cb += wp[2]) & mask;
-	    }
-	} else if (stride == 4) {
-	    op[0] = cr = wp[0];  op[1] = cg = wp[1];
-	    op[2] = cb = wp[2];  op[3] = ca = wp[3];
-	    n -= 4;
-	    while (n > 0) {
-		wp += 4;
-		op += 4;
-		n -= 4;
-		op[0] = (cr += wp[0]) & mask;
-		op[1] = (cg += wp[1]) & mask;
-		op[2] = (cb += wp[2]) & mask;
-		op[3] = (ca += wp[3]) & mask;
-	    } 
-	} else {
-	    REPEAT(stride, *op = *wp&mask; wp++; op++)
-	    n -= stride;
-	    while (n > 0) {
-		REPEAT(stride,
-		    wp[stride] += *wp; *op = *wp&mask; wp++; op++)
-		n -= stride;
-	    }
-	}
-    }
-}
-
-static void
-horizontalAccumulate8(uint16 *wp, int n, int stride, unsigned char *op,
-	unsigned char *ToLinear8)
-{
-    register unsigned int  cr, cg, cb, ca, mask;
-
-    if (n >= stride) {
-	mask = CODE_MASK;
-	if (stride == 3) {
-	    op[0] = ToLinear8[cr = wp[0]];
-	    op[1] = ToLinear8[cg = wp[1]];
-	    op[2] = ToLinear8[cb = wp[2]];
-	    n -= 3;
-	    while (n > 0) {
-		n -= 3;
-		wp += 3;
-		op += 3;
-		op[0] = ToLinear8[(cr += wp[0]) & mask];
-		op[1] = ToLinear8[(cg += wp[1]) & mask];
-		op[2] = ToLinear8[(cb += wp[2]) & mask];
-	    }
-	} else if (stride == 4) {
-	    op[0] = ToLinear8[cr = wp[0]];
-	    op[1] = ToLinear8[cg = wp[1]];
-	    op[2] = ToLinear8[cb = wp[2]];
-	    op[3] = ToLinear8[ca = wp[3]];
-	    n -= 4;
-	    while (n > 0) {
-		n -= 4;
-		wp += 4;
-		op += 4;
-		op[0] = ToLinear8[(cr += wp[0]) & mask];
-		op[1] = ToLinear8[(cg += wp[1]) & mask];
-		op[2] = ToLinear8[(cb += wp[2]) & mask];
-		op[3] = ToLinear8[(ca += wp[3]) & mask];
-	    }
-	} else {
-	    REPEAT(stride, *op = ToLinear8[*wp&mask]; wp++; op++)
-	    n -= stride;
-	    while (n > 0) {
-		REPEAT(stride,
-		    wp[stride] += *wp; *op = ToLinear8[*wp&mask]; wp++; op++)
-		n -= stride;
-	    }
-	}
-    }
-}
-
-
-static void
-horizontalAccumulate8abgr(uint16 *wp, int n, int stride, unsigned char *op,
-	unsigned char *ToLinear8)
-{
-    register unsigned int  cr, cg, cb, ca, mask;
-    register unsigned char  t0, t1, t2, t3;
-
-    if (n >= stride) {
-	mask = CODE_MASK;
-	if (stride == 3) {
-	    op[0] = 0;
-	    t1 = ToLinear8[cb = wp[2]];
-	    t2 = ToLinear8[cg = wp[1]];
-	    t3 = ToLinear8[cr = wp[0]];
-	    op[1] = t1;
-	    op[2] = t2;
-	    op[3] = t3;
-	    n -= 3;
-	    while (n > 0) {
-		n -= 3;
-		wp += 3;
-		op += 4;
-		op[0] = 0;
-		t1 = ToLinear8[(cb += wp[2]) & mask];
-		t2 = ToLinear8[(cg += wp[1]) & mask];
-		t3 = ToLinear8[(cr += wp[0]) & mask];
-		op[1] = t1;
-		op[2] = t2;
-		op[3] = t3;
-	    }
-	} else if (stride == 4) {
-	    t0 = ToLinear8[ca = wp[3]];
-	    t1 = ToLinear8[cb = wp[2]];
-	    t2 = ToLinear8[cg = wp[1]];
-	    t3 = ToLinear8[cr = wp[0]];
-	    op[0] = t0;
-	    op[1] = t1;
-	    op[2] = t2;
-	    op[3] = t3;
-	    n -= 4;
-	    while (n > 0) {
-		n -= 4;
-		wp += 4;
-		op += 4;
-		t0 = ToLinear8[(ca += wp[3]) & mask];
-		t1 = ToLinear8[(cb += wp[2]) & mask];
-		t2 = ToLinear8[(cg += wp[1]) & mask];
-		t3 = ToLinear8[(cr += wp[0]) & mask];
-		op[0] = t0;
-		op[1] = t1;
-		op[2] = t2;
-		op[3] = t3;
-	    }
-	} else {
-	    REPEAT(stride, *op = ToLinear8[*wp&mask]; wp++; op++)
-	    n -= stride;
-	    while (n > 0) {
-		REPEAT(stride,
-		    wp[stride] += *wp; *op = ToLinear8[*wp&mask]; wp++; op++)
-		n -= stride;
-	    }
-	}
-    }
-}
-
-/*
- * State block for each open TIFF
- * file using PixarLog compression/decompression.
- */
-typedef	struct {
-	TIFFPredictorState	predict;
-	z_stream		stream;
-	uint16			*tbuf; 
-	uint16			stride;
-	int			state;
-	int			user_datafmt;
-	int			quality;
-#define PLSTATE_INIT 1
-
-	TIFFVSetMethod		vgetparent;	/* super-class method */
-	TIFFVSetMethod		vsetparent;	/* super-class method */
-
-	float *ToLinearF;
-	uint16 *ToLinear16;
-	unsigned char *ToLinear8;
-	uint16  *FromLT2;
-	uint16  *From14; /* Really for 16-bit data, but we shift down 2 */
-	uint16  *From8;
-	
-} PixarLogState;
-
-static int
-PixarLogMakeTables(PixarLogState *sp)
-{
-
-/*
- *    We make several tables here to convert between various external
- *    representations (float, 16-bit, and 8-bit) and the internal
- *    11-bit companded representation.  The 11-bit representation has two
- *    distinct regions.  A linear bottom end up through .018316 in steps
- *    of about .000073, and a region of constant ratio up to about 25.
- *    These floating point numbers are stored in the main table ToLinearF. 
- *    All other tables are derived from this one.  The tables (and the
- *    ratios) are continuous at the internal seam.
- */
-
-    int  nlin, lt2size;
-    int  i, j;
-    double  b, c, linstep, v;
-    float *ToLinearF;
-    uint16 *ToLinear16;
-    unsigned char *ToLinear8;
-    uint16  *FromLT2;
-    uint16  *From14; /* Really for 16-bit data, but we shift down 2 */
-    uint16  *From8;
-
-    c = log(RATIO);	
-    nlin = (int)(1./c);	/* nlin must be an integer */
-    c = 1./nlin;
-    b = exp(-c*ONE);	/* multiplicative scale factor [b*exp(c*ONE) = 1] */
-    linstep = b*c*exp(1.);
-
-    LogK1 = (float)(1./c);	/* if (v >= 2)  token = k1*log(v*k2) */
-    LogK2 = (float)(1./b);
-    lt2size = (int)(2./linstep) + 1;
-    FromLT2 = (uint16 *)_TIFFmalloc(lt2size*sizeof(uint16));
-    From14 = (uint16 *)_TIFFmalloc(16384*sizeof(uint16));
-    From8 = (uint16 *)_TIFFmalloc(256*sizeof(uint16));
-    ToLinearF = (float *)_TIFFmalloc(TSIZEP1 * sizeof(float));
-    ToLinear16 = (uint16 *)_TIFFmalloc(TSIZEP1 * sizeof(uint16));
-    ToLinear8 = (unsigned char *)_TIFFmalloc(TSIZEP1 * sizeof(unsigned char));
-    if (FromLT2 == NULL || From14  == NULL || From8   == NULL ||
-	 ToLinearF == NULL || ToLinear16 == NULL || ToLinear8 == NULL) {
-	if (FromLT2) _TIFFfree(FromLT2);
-	if (From14) _TIFFfree(From14);
-	if (From8) _TIFFfree(From8);
-	if (ToLinearF) _TIFFfree(ToLinearF);
-	if (ToLinear16) _TIFFfree(ToLinear16);
-	if (ToLinear8) _TIFFfree(ToLinear8);
-	sp->FromLT2 = NULL;
-	sp->From14 = NULL;
-	sp->From8 = NULL;
-	sp->ToLinearF = NULL;
-	sp->ToLinear16 = NULL;
-	sp->ToLinear8 = NULL;
-	return 0;
-    }
-
-    j = 0;
-
-    for (i = 0; i < nlin; i++)  {
-	v = i * linstep;
-	ToLinearF[j++] = (float)v;
-    }
-
-    for (i = nlin; i < TSIZE; i++)
-	ToLinearF[j++] = (float)(b*exp(c*i));
-
-    ToLinearF[2048] = ToLinearF[2047];
-
-    for (i = 0; i < TSIZEP1; i++)  {
-	v = ToLinearF[i]*65535.0 + 0.5;
-	ToLinear16[i] = (v > 65535.0) ? 65535 : (uint16)v;
-	v = ToLinearF[i]*255.0  + 0.5;
-	ToLinear8[i]  = (v > 255.0) ? 255 : (unsigned char)v;
-    }
-
-    j = 0;
-    for (i = 0; i < lt2size; i++)  {
-	if ((i*linstep)*(i*linstep) > ToLinearF[j]*ToLinearF[j+1])
-	    j++;
-	FromLT2[i] = j;
-    }
-
-    /*
-     * Since we lose info anyway on 16-bit data, we set up a 14-bit
-     * table and shift 16-bit values down two bits on input.
-     * saves a little table space.
-     */
-    j = 0;
-    for (i = 0; i < 16384; i++)  {
-	while ((i/16383.)*(i/16383.) > ToLinearF[j]*ToLinearF[j+1])
-	    j++;
-	From14[i] = j;
-    }
-
-    j = 0;
-    for (i = 0; i < 256; i++)  {
-	while ((i/255.)*(i/255.) > ToLinearF[j]*ToLinearF[j+1])
-	    j++;
-	From8[i] = j;
-    }
-
-    Fltsize = (float)(lt2size/2);
-
-    sp->ToLinearF = ToLinearF;
-    sp->ToLinear16 = ToLinear16;
-    sp->ToLinear8 = ToLinear8;
-    sp->FromLT2 = FromLT2;
-    sp->From14 = From14;
-    sp->From8 = From8;
-
-    return 1;
-}
-
-#define	DecoderState(tif)	((PixarLogState*) (tif)->tif_data)
-#define	EncoderState(tif)	((PixarLogState*) (tif)->tif_data)
-
-static	int PixarLogEncode(TIFF*, tidata_t, tsize_t, tsample_t);
-static	int PixarLogDecode(TIFF*, tidata_t, tsize_t, tsample_t);
-
-#define PIXARLOGDATAFMT_UNKNOWN	-1
-
-static int
-PixarLogGuessDataFmt(TIFFDirectory *td)
-{
-	int guess = PIXARLOGDATAFMT_UNKNOWN;
-	int format = td->td_sampleformat;
-
-	/* If the user didn't tell us his datafmt,
-	 * take our best guess from the bitspersample.
-	 */
-	switch (td->td_bitspersample) {
-	 case 32:
-		if (format == SAMPLEFORMAT_IEEEFP)
-			guess = PIXARLOGDATAFMT_FLOAT;
-		break;
-	 case 16:
-		if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT)
-			guess = PIXARLOGDATAFMT_16BIT;
-		break;
-	 case 12:
-		if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_INT)
-			guess = PIXARLOGDATAFMT_12BITPICIO;
-		break;
-	 case 11:
-		if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT)
-			guess = PIXARLOGDATAFMT_11BITLOG;
-		break;
-	 case 8:
-		if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT)
-			guess = PIXARLOGDATAFMT_8BIT;
-		break;
-	}
-
-	return guess;
-}
-
-static uint32
-multiply(size_t m1, size_t m2)
-{
-	uint32	bytes = m1 * m2;
-
-	if (m1 && bytes / m1 != m2)
-		bytes = 0;
-
-	return bytes;
-}
-
-static int
-PixarLogSetupDecode(TIFF* tif)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-	PixarLogState* sp = DecoderState(tif);
-	tsize_t tbuf_size;
-	static const char module[] = "PixarLogSetupDecode";
-
-	assert(sp != NULL);
-
-	/* Make sure no byte swapping happens on the data
-	 * after decompression. */
-	tif->tif_postdecode = _TIFFNoPostDecode;
-
-	/* for some reason, we can't do this in TIFFInitPixarLog */
-
-	sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ?
-	    td->td_samplesperpixel : 1);
-	tbuf_size = multiply(multiply(multiply(sp->stride, td->td_imagewidth),
-				      td->td_rowsperstrip), sizeof(uint16));
-	if (tbuf_size == 0)
-		return (0);
-	sp->tbuf = (uint16 *) _TIFFmalloc(tbuf_size);
-	if (sp->tbuf == NULL)
-		return (0);
-	if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN)
-		sp->user_datafmt = PixarLogGuessDataFmt(td);
-	if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-			"PixarLog compression can't handle bits depth/data format combination (depth: %d)", 
-			td->td_bitspersample);
-		return (0);
-	}
-
-	if (inflateInit(&sp->stream) != Z_OK) {
-		TIFFErrorExt(tif->tif_clientdata, module, "%s: %s", tif->tif_name, sp->stream.msg);
-		return (0);
-	} else {
-		sp->state |= PLSTATE_INIT;
-		return (1);
-	}
-}
-
-/*
- * Setup state for decoding a strip.
- */
-static int
-PixarLogPreDecode(TIFF* tif, tsample_t s)
-{
-	PixarLogState* sp = DecoderState(tif);
-
-	(void) s;
-	assert(sp != NULL);
-	sp->stream.next_in = tif->tif_rawdata;
-	sp->stream.avail_in = tif->tif_rawcc;
-	return (inflateReset(&sp->stream) == Z_OK);
-}
-
-static int
-PixarLogDecode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-	PixarLogState* sp = DecoderState(tif);
-	static const char module[] = "PixarLogDecode";
-	int i, nsamples, llen;
-	uint16 *up;
-
-	switch (sp->user_datafmt) {
-	case PIXARLOGDATAFMT_FLOAT:
-		nsamples = occ / sizeof(float);	/* XXX float == 32 bits */
-		break;
-	case PIXARLOGDATAFMT_16BIT:
-	case PIXARLOGDATAFMT_12BITPICIO:
-	case PIXARLOGDATAFMT_11BITLOG:
-		nsamples = occ / sizeof(uint16); /* XXX uint16 == 16 bits */
-		break;
-	case PIXARLOGDATAFMT_8BIT:
-	case PIXARLOGDATAFMT_8BITABGR:
-		nsamples = occ;
-		break;
-	default:
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			"%d bit input not supported in PixarLog",
-			td->td_bitspersample);
-		return 0;
-	}
-
-	llen = sp->stride * td->td_imagewidth;
-
-	(void) s;
-	assert(sp != NULL);
-	sp->stream.next_out = (unsigned char *) sp->tbuf;
-	sp->stream.avail_out = nsamples * sizeof(uint16);
-	do {
-		int state = inflate(&sp->stream, Z_PARTIAL_FLUSH);
-		if (state == Z_STREAM_END) {
-			break;			/* XXX */
-		}
-		if (state == Z_DATA_ERROR) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-			    "%s: Decoding error at scanline %d, %s",
-			    tif->tif_name, tif->tif_row, sp->stream.msg);
-			if (inflateSync(&sp->stream) != Z_OK)
-				return (0);
-			continue;
-		}
-		if (state != Z_OK) {
-			TIFFErrorExt(tif->tif_clientdata, module, "%s: zlib error: %s",
-			    tif->tif_name, sp->stream.msg);
-			return (0);
-		}
-	} while (sp->stream.avail_out > 0);
-
-	/* hopefully, we got all the bytes we needed */
-	if (sp->stream.avail_out != 0) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-		    "%s: Not enough data at scanline %d (short %d bytes)",
-		    tif->tif_name, tif->tif_row, sp->stream.avail_out);
-		return (0);
-	}
-
-	up = sp->tbuf;
-	/* Swap bytes in the data if from a different endian machine. */
-	if (tif->tif_flags & TIFF_SWAB)
-		TIFFSwabArrayOfShort(up, nsamples);
-
-	/* 
-	 * if llen is not an exact multiple of nsamples, the decode operation
-	 * may overflow the output buffer, so truncate it enough to prevent
-	 * that but still salvage as much data as possible.
-	 */
-	if (nsamples % llen) { 
-		TIFFWarningExt(tif->tif_clientdata, module,
-			"%s: stride %d is not a multiple of sample count, "
-			"%d, data truncated.", tif->tif_name, llen, nsamples);
-		nsamples -= nsamples % llen;
-	}
-
-	for (i = 0; i < nsamples; i += llen, up += llen) {
-		switch (sp->user_datafmt)  {
-		case PIXARLOGDATAFMT_FLOAT:
-			horizontalAccumulateF(up, llen, sp->stride,
-					(float *)op, sp->ToLinearF);
-			op += llen * sizeof(float);
-			break;
-		case PIXARLOGDATAFMT_16BIT:
-			horizontalAccumulate16(up, llen, sp->stride,
-					(uint16 *)op, sp->ToLinear16);
-			op += llen * sizeof(uint16);
-			break;
-		case PIXARLOGDATAFMT_12BITPICIO:
-			horizontalAccumulate12(up, llen, sp->stride,
-					(int16 *)op, sp->ToLinearF);
-			op += llen * sizeof(int16);
-			break;
-		case PIXARLOGDATAFMT_11BITLOG:
-			horizontalAccumulate11(up, llen, sp->stride,
-					(uint16 *)op);
-			op += llen * sizeof(uint16);
-			break;
-		case PIXARLOGDATAFMT_8BIT:
-			horizontalAccumulate8(up, llen, sp->stride,
-					(unsigned char *)op, sp->ToLinear8);
-			op += llen * sizeof(unsigned char);
-			break;
-		case PIXARLOGDATAFMT_8BITABGR:
-			horizontalAccumulate8abgr(up, llen, sp->stride,
-					(unsigned char *)op, sp->ToLinear8);
-			op += llen * sizeof(unsigned char);
-			break;
-		default:
-			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-				  "PixarLogDecode: unsupported bits/sample: %d", 
-				  td->td_bitspersample);
-			return (0);
-		}
-	}
-
-	return (1);
-}
-
-static int
-PixarLogSetupEncode(TIFF* tif)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-	PixarLogState* sp = EncoderState(tif);
-	tsize_t tbuf_size;
-	static const char module[] = "PixarLogSetupEncode";
-
-	assert(sp != NULL);
-
-	/* for some reason, we can't do this in TIFFInitPixarLog */
-
-	sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ?
-	    td->td_samplesperpixel : 1);
-	tbuf_size = multiply(multiply(multiply(sp->stride, td->td_imagewidth),
-				      td->td_rowsperstrip), sizeof(uint16));
-	if (tbuf_size == 0)
-		return (0);
-	sp->tbuf = (uint16 *) _TIFFmalloc(tbuf_size);
-	if (sp->tbuf == NULL)
-		return (0);
-	if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN)
-		sp->user_datafmt = PixarLogGuessDataFmt(td);
-	if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) {
-		TIFFErrorExt(tif->tif_clientdata, module, "PixarLog compression can't handle %d bit linear encodings", td->td_bitspersample);
-		return (0);
-	}
-
-	if (deflateInit(&sp->stream, sp->quality) != Z_OK) {
-		TIFFErrorExt(tif->tif_clientdata, module, "%s: %s", tif->tif_name, sp->stream.msg);
-		return (0);
-	} else {
-		sp->state |= PLSTATE_INIT;
-		return (1);
-	}
-}
-
-/*
- * Reset encoding state at the start of a strip.
- */
-static int
-PixarLogPreEncode(TIFF* tif, tsample_t s)
-{
-	PixarLogState *sp = EncoderState(tif);
-
-	(void) s;
-	assert(sp != NULL);
-	sp->stream.next_out = tif->tif_rawdata;
-	sp->stream.avail_out = tif->tif_rawdatasize;
-	return (deflateReset(&sp->stream) == Z_OK);
-}
-
-static void
-horizontalDifferenceF(float *ip, int n, int stride, uint16 *wp, uint16 *FromLT2)
-{
-
-    int32 r1, g1, b1, a1, r2, g2, b2, a2, mask;
-    float fltsize = Fltsize;
-
-#define  CLAMP(v) ( (v<(float)0.)   ? 0				\
-		  : (v<(float)2.)   ? FromLT2[(int)(v*fltsize)]	\
-		  : (v>(float)24.2) ? 2047			\
-		  : LogK1*log(v*LogK2) + 0.5 )
-
-    mask = CODE_MASK;
-    if (n >= stride) {
-	if (stride == 3) {
-	    r2 = wp[0] = (uint16) CLAMP(ip[0]);
-	    g2 = wp[1] = (uint16) CLAMP(ip[1]);
-	    b2 = wp[2] = (uint16) CLAMP(ip[2]);
-	    n -= 3;
-	    while (n > 0) {
-		n -= 3;
-		wp += 3;
-		ip += 3;
-		r1 = (int32) CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1;
-		g1 = (int32) CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1;
-		b1 = (int32) CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1;
-	    }
-	} else if (stride == 4) {
-	    r2 = wp[0] = (uint16) CLAMP(ip[0]);
-	    g2 = wp[1] = (uint16) CLAMP(ip[1]);
-	    b2 = wp[2] = (uint16) CLAMP(ip[2]);
-	    a2 = wp[3] = (uint16) CLAMP(ip[3]);
-	    n -= 4;
-	    while (n > 0) {
-		n -= 4;
-		wp += 4;
-		ip += 4;
-		r1 = (int32) CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1;
-		g1 = (int32) CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1;
-		b1 = (int32) CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1;
-		a1 = (int32) CLAMP(ip[3]); wp[3] = (a1-a2) & mask; a2 = a1;
-	    }
-	} else {
-	    ip += n - 1;	/* point to last one */
-	    wp += n - 1;	/* point to last one */
-	    n -= stride;
-	    while (n > 0) {
-		REPEAT(stride, wp[0] = (uint16) CLAMP(ip[0]);
-				wp[stride] -= wp[0];
-				wp[stride] &= mask;
-				wp--; ip--)
-		n -= stride;
-	    }
-	    REPEAT(stride, wp[0] = (uint16) CLAMP(ip[0]); wp--; ip--)
-	}
-    }
-}
-
-static void
-horizontalDifference16(unsigned short *ip, int n, int stride, 
-	unsigned short *wp, uint16 *From14)
-{
-    register int  r1, g1, b1, a1, r2, g2, b2, a2, mask;
-
-/* assumption is unsigned pixel values */
-#undef   CLAMP
-#define  CLAMP(v) From14[(v) >> 2]
-
-    mask = CODE_MASK;
-    if (n >= stride) {
-	if (stride == 3) {
-	    r2 = wp[0] = CLAMP(ip[0]);  g2 = wp[1] = CLAMP(ip[1]);
-	    b2 = wp[2] = CLAMP(ip[2]);
-	    n -= 3;
-	    while (n > 0) {
-		n -= 3;
-		wp += 3;
-		ip += 3;
-		r1 = CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1;
-		g1 = CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1;
-		b1 = CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1;
-	    }
-	} else if (stride == 4) {
-	    r2 = wp[0] = CLAMP(ip[0]);  g2 = wp[1] = CLAMP(ip[1]);
-	    b2 = wp[2] = CLAMP(ip[2]);  a2 = wp[3] = CLAMP(ip[3]);
-	    n -= 4;
-	    while (n > 0) {
-		n -= 4;
-		wp += 4;
-		ip += 4;
-		r1 = CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1;
-		g1 = CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1;
-		b1 = CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1;
-		a1 = CLAMP(ip[3]); wp[3] = (a1-a2) & mask; a2 = a1;
-	    }
-	} else {
-	    ip += n - 1;	/* point to last one */
-	    wp += n - 1;	/* point to last one */
-	    n -= stride;
-	    while (n > 0) {
-		REPEAT(stride, wp[0] = CLAMP(ip[0]);
-				wp[stride] -= wp[0];
-				wp[stride] &= mask;
-				wp--; ip--)
-		n -= stride;
-	    }
-	    REPEAT(stride, wp[0] = CLAMP(ip[0]); wp--; ip--)
-	}
-    }
-}
-
-
-static void
-horizontalDifference8(unsigned char *ip, int n, int stride, 
-	unsigned short *wp, uint16 *From8)
-{
-    register int  r1, g1, b1, a1, r2, g2, b2, a2, mask;
-
-#undef	 CLAMP
-#define  CLAMP(v) (From8[(v)])
-
-    mask = CODE_MASK;
-    if (n >= stride) {
-	if (stride == 3) {
-	    r2 = wp[0] = CLAMP(ip[0]);  g2 = wp[1] = CLAMP(ip[1]);
-	    b2 = wp[2] = CLAMP(ip[2]);
-	    n -= 3;
-	    while (n > 0) {
-		n -= 3;
-		r1 = CLAMP(ip[3]); wp[3] = (r1-r2) & mask; r2 = r1;
-		g1 = CLAMP(ip[4]); wp[4] = (g1-g2) & mask; g2 = g1;
-		b1 = CLAMP(ip[5]); wp[5] = (b1-b2) & mask; b2 = b1;
-		wp += 3;
-		ip += 3;
-	    }
-	} else if (stride == 4) {
-	    r2 = wp[0] = CLAMP(ip[0]);  g2 = wp[1] = CLAMP(ip[1]);
-	    b2 = wp[2] = CLAMP(ip[2]);  a2 = wp[3] = CLAMP(ip[3]);
-	    n -= 4;
-	    while (n > 0) {
-		n -= 4;
-		r1 = CLAMP(ip[4]); wp[4] = (r1-r2) & mask; r2 = r1;
-		g1 = CLAMP(ip[5]); wp[5] = (g1-g2) & mask; g2 = g1;
-		b1 = CLAMP(ip[6]); wp[6] = (b1-b2) & mask; b2 = b1;
-		a1 = CLAMP(ip[7]); wp[7] = (a1-a2) & mask; a2 = a1;
-		wp += 4;
-		ip += 4;
-	    }
-	} else {
-	    wp += n + stride - 1;	/* point to last one */
-	    ip += n + stride - 1;	/* point to last one */
-	    n -= stride;
-	    while (n > 0) {
-		REPEAT(stride, wp[0] = CLAMP(ip[0]);
-				wp[stride] -= wp[0];
-				wp[stride] &= mask;
-				wp--; ip--)
-		n -= stride;
-	    }
-	    REPEAT(stride, wp[0] = CLAMP(ip[0]); wp--; ip--)
-	}
-    }
-}
-
-/*
- * Encode a chunk of pixels.
- */
-static int
-PixarLogEncode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-	PixarLogState *sp = EncoderState(tif);
-	static const char module[] = "PixarLogEncode";
-	int	i, n, llen;
-	unsigned short * up;
-
-	(void) s;
-
-	switch (sp->user_datafmt) {
-	case PIXARLOGDATAFMT_FLOAT:
-		n = cc / sizeof(float);		/* XXX float == 32 bits */
-		break;
-	case PIXARLOGDATAFMT_16BIT:
-	case PIXARLOGDATAFMT_12BITPICIO:
-	case PIXARLOGDATAFMT_11BITLOG:
-		n = cc / sizeof(uint16);	/* XXX uint16 == 16 bits */
-		break;
-	case PIXARLOGDATAFMT_8BIT:
-	case PIXARLOGDATAFMT_8BITABGR:
-		n = cc;
-		break;
-	default:
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			"%d bit input not supported in PixarLog",
-			td->td_bitspersample);
-		return 0;
-	}
-
-	llen = sp->stride * td->td_imagewidth;
-
-	for (i = 0, up = sp->tbuf; i < n; i += llen, up += llen) {
-		switch (sp->user_datafmt)  {
-		case PIXARLOGDATAFMT_FLOAT:
-			horizontalDifferenceF((float *)bp, llen, 
-				sp->stride, up, sp->FromLT2);
-			bp += llen * sizeof(float);
-			break;
-		case PIXARLOGDATAFMT_16BIT:
-			horizontalDifference16((uint16 *)bp, llen, 
-				sp->stride, up, sp->From14);
-			bp += llen * sizeof(uint16);
-			break;
-		case PIXARLOGDATAFMT_8BIT:
-			horizontalDifference8((unsigned char *)bp, llen, 
-				sp->stride, up, sp->From8);
-			bp += llen * sizeof(unsigned char);
-			break;
-		default:
-			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-				"%d bit input not supported in PixarLog",
-				td->td_bitspersample);
-			return 0;
-		}
-	}
- 
-	sp->stream.next_in = (unsigned char *) sp->tbuf;
-	sp->stream.avail_in = n * sizeof(uint16);
-
-	do {
-		if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) {
-			TIFFErrorExt(tif->tif_clientdata, module, "%s: Encoder error: %s",
-			    tif->tif_name, sp->stream.msg);
-			return (0);
-		}
-		if (sp->stream.avail_out == 0) {
-			tif->tif_rawcc = tif->tif_rawdatasize;
-			TIFFFlushData1(tif);
-			sp->stream.next_out = tif->tif_rawdata;
-			sp->stream.avail_out = tif->tif_rawdatasize;
-		}
-	} while (sp->stream.avail_in > 0);
-	return (1);
-}
-
-/*
- * Finish off an encoded strip by flushing the last
- * string and tacking on an End Of Information code.
- */
-
-static int
-PixarLogPostEncode(TIFF* tif)
-{
-	PixarLogState *sp = EncoderState(tif);
-	static const char module[] = "PixarLogPostEncode";
-	int state;
-
-	sp->stream.avail_in = 0;
-
-	do {
-		state = deflate(&sp->stream, Z_FINISH);
-		switch (state) {
-		case Z_STREAM_END:
-		case Z_OK:
-		    if (sp->stream.avail_out != (uint32)tif->tif_rawdatasize) {
-			    tif->tif_rawcc =
-				tif->tif_rawdatasize - sp->stream.avail_out;
-			    TIFFFlushData1(tif);
-			    sp->stream.next_out = tif->tif_rawdata;
-			    sp->stream.avail_out = tif->tif_rawdatasize;
-		    }
-		    break;
-		default:
-			TIFFErrorExt(tif->tif_clientdata, module, "%s: zlib error: %s",
-			tif->tif_name, sp->stream.msg);
-		    return (0);
-		}
-	} while (state != Z_STREAM_END);
-	return (1);
-}
-
-static void
-PixarLogClose(TIFF* tif)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-
-	/* In a really sneaky maneuver, on close, we covertly modify both
-	 * bitspersample and sampleformat in the directory to indicate
-	 * 8-bit linear.  This way, the decode "just works" even for
-	 * readers that don't know about PixarLog, or how to set
-	 * the PIXARLOGDATFMT pseudo-tag.
-	 */
-	td->td_bitspersample = 8;
-	td->td_sampleformat = SAMPLEFORMAT_UINT;
-}
-
-static void
-PixarLogCleanup(TIFF* tif)
-{
-	PixarLogState* sp = (PixarLogState*) tif->tif_data;
-
-	assert(sp != 0);
-
-	(void)TIFFPredictorCleanup(tif);
-
-	tif->tif_tagmethods.vgetfield = sp->vgetparent;
-	tif->tif_tagmethods.vsetfield = sp->vsetparent;
-
-	if (sp->FromLT2) _TIFFfree(sp->FromLT2);
-	if (sp->From14) _TIFFfree(sp->From14);
-	if (sp->From8) _TIFFfree(sp->From8);
-	if (sp->ToLinearF) _TIFFfree(sp->ToLinearF);
-	if (sp->ToLinear16) _TIFFfree(sp->ToLinear16);
-	if (sp->ToLinear8) _TIFFfree(sp->ToLinear8);
-	if (sp->state&PLSTATE_INIT) {
-		if (tif->tif_mode == O_RDONLY)
-			inflateEnd(&sp->stream);
-		else
-			deflateEnd(&sp->stream);
-	}
-	if (sp->tbuf)
-		_TIFFfree(sp->tbuf);
-	_TIFFfree(sp);
-	tif->tif_data = NULL;
-
-	_TIFFSetDefaultCompressionState(tif);
-}
-
-static int
-PixarLogVSetField(TIFF* tif, ttag_t tag, va_list ap)
-{
-    PixarLogState *sp = (PixarLogState *)tif->tif_data;
-    int result;
-    static const char module[] = "PixarLogVSetField";
-
-    switch (tag) {
-     case TIFFTAG_PIXARLOGQUALITY:
-		sp->quality = va_arg(ap, int);
-		if (tif->tif_mode != O_RDONLY && (sp->state&PLSTATE_INIT)) {
-			if (deflateParams(&sp->stream,
-			    sp->quality, Z_DEFAULT_STRATEGY) != Z_OK) {
-				TIFFErrorExt(tif->tif_clientdata, module, "%s: zlib error: %s",
-					tif->tif_name, sp->stream.msg);
-				return (0);
-			}
-		}
-		return (1);
-     case TIFFTAG_PIXARLOGDATAFMT:
-	sp->user_datafmt = va_arg(ap, int);
-	/* Tweak the TIFF header so that the rest of libtiff knows what
-	 * size of data will be passed between app and library, and
-	 * assume that the app knows what it is doing and is not
-	 * confused by these header manipulations...
-	 */
-	switch (sp->user_datafmt) {
-	 case PIXARLOGDATAFMT_8BIT:
-	 case PIXARLOGDATAFMT_8BITABGR:
-	    TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
-	    TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
-	    break;
-	 case PIXARLOGDATAFMT_11BITLOG:
-	    TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16);
-	    TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
-	    break;
-	 case PIXARLOGDATAFMT_12BITPICIO:
-	    TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16);
-	    TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT);
-	    break;
-	 case PIXARLOGDATAFMT_16BIT:
-	    TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16);
-	    TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
-	    break;
-	 case PIXARLOGDATAFMT_FLOAT:
-	    TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 32);
-	    TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);
-	    break;
-	}
-	/*
-	 * Must recalculate sizes should bits/sample change.
-	 */
-	tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tsize_t) -1;
-	tif->tif_scanlinesize = TIFFScanlineSize(tif);
-	result = 1;		/* NB: pseudo tag */
-	break;
-     default:
-	result = (*sp->vsetparent)(tif, tag, ap);
-    }
-    return (result);
-}
-
-static int
-PixarLogVGetField(TIFF* tif, ttag_t tag, va_list ap)
-{
-    PixarLogState *sp = (PixarLogState *)tif->tif_data;
-
-    switch (tag) {
-     case TIFFTAG_PIXARLOGQUALITY:
-	*va_arg(ap, int*) = sp->quality;
-	break;
-     case TIFFTAG_PIXARLOGDATAFMT:
-	*va_arg(ap, int*) = sp->user_datafmt;
-	break;
-     default:
-	return (*sp->vgetparent)(tif, tag, ap);
-    }
-    return (1);
-}
-
-static const TIFFFieldInfo pixarlogFieldInfo[] = {
-    {TIFFTAG_PIXARLOGDATAFMT,0,0,TIFF_ANY,  FIELD_PSEUDO,FALSE,FALSE,""},
-    {TIFFTAG_PIXARLOGQUALITY,0,0,TIFF_ANY,  FIELD_PSEUDO,FALSE,FALSE,""}
-};
-
-int
-TIFFInitPixarLog(TIFF* tif, int scheme)
-{
-	static const char module[] = "TIFFInitPixarLog";
-
-	PixarLogState* sp;
-
-	assert(scheme == COMPRESSION_PIXARLOG);
-
-	/*
-	 * Merge codec-specific tag information.
-	 */
-	if (!_TIFFMergeFieldInfo(tif, pixarlogFieldInfo,
-				 TIFFArrayCount(pixarlogFieldInfo))) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-			     "Merging PixarLog codec-specific tags failed");
-		return 0;
-	}
-
-	/*
-	 * Allocate state block so tag methods have storage to record values.
-	 */
-	tif->tif_data = (tidata_t) _TIFFmalloc(sizeof (PixarLogState));
-	if (tif->tif_data == NULL)
-		goto bad;
-	sp = (PixarLogState*) tif->tif_data;
-	_TIFFmemset(sp, 0, sizeof (*sp));
-	sp->stream.data_type = Z_BINARY;
-	sp->user_datafmt = PIXARLOGDATAFMT_UNKNOWN;
-
-	/*
-	 * Install codec methods.
-	 */
-	tif->tif_setupdecode = PixarLogSetupDecode;
-	tif->tif_predecode = PixarLogPreDecode;
-	tif->tif_decoderow = PixarLogDecode;
-	tif->tif_decodestrip = PixarLogDecode;
-	tif->tif_decodetile = PixarLogDecode;
-	tif->tif_setupencode = PixarLogSetupEncode;
-	tif->tif_preencode = PixarLogPreEncode;
-	tif->tif_postencode = PixarLogPostEncode;
-	tif->tif_encoderow = PixarLogEncode;
-	tif->tif_encodestrip = PixarLogEncode;
-	tif->tif_encodetile = PixarLogEncode;
-	tif->tif_close = PixarLogClose;
-	tif->tif_cleanup = PixarLogCleanup;
-
-	/* Override SetField so we can handle our private pseudo-tag */
-	sp->vgetparent = tif->tif_tagmethods.vgetfield;
-	tif->tif_tagmethods.vgetfield = PixarLogVGetField;   /* hook for codec tags */
-	sp->vsetparent = tif->tif_tagmethods.vsetfield;
-	tif->tif_tagmethods.vsetfield = PixarLogVSetField;   /* hook for codec tags */
-
-	/* Default values for codec-specific fields */
-	sp->quality = Z_DEFAULT_COMPRESSION; /* default comp. level */
-	sp->state = 0;
-
-	/* we don't wish to use the predictor, 
-	 * the default is none, which predictor value 1
-	 */
-	(void) TIFFPredictorInit(tif);
-
-	/*
-	 * build the companding tables 
-	 */
-	PixarLogMakeTables(sp);
-
-	return (1);
-bad:
-	TIFFErrorExt(tif->tif_clientdata, module,
-		     "No space for PixarLog state block");
-	return (0);
-}
-#endif /* PIXARLOG_SUPPORT */
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_predict.c b/Source/LibTIFF/tif_predict.c
deleted file mode 100644
index 61fa90f..0000000
--- a/Source/LibTIFF/tif_predict.c
+++ /dev/null
@@ -1,736 +0,0 @@
-/* $Id: tif_predict.c,v 1.37 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library.
- *
- * Predictor Tag Support (used by multiple codecs).
- */
-#include "tiffiop.h"
-#include "tif_predict.h"
-
-#define	PredictorState(tif)	((TIFFPredictorState*) (tif)->tif_data)
-
-static	void horAcc8(TIFF*, tidata_t, tsize_t);
-static	void horAcc16(TIFF*, tidata_t, tsize_t);
-static	void horAcc32(TIFF*, tidata_t, tsize_t);
-static	void swabHorAcc16(TIFF*, tidata_t, tsize_t);
-static	void swabHorAcc32(TIFF*, tidata_t, tsize_t);
-static	void horDiff8(TIFF*, tidata_t, tsize_t);
-static	void horDiff16(TIFF*, tidata_t, tsize_t);
-static	void horDiff32(TIFF*, tidata_t, tsize_t);
-static	void fpAcc(TIFF*, tidata_t, tsize_t);
-static	void fpDiff(TIFF*, tidata_t, tsize_t);
-static	int PredictorDecodeRow(TIFF*, tidata_t, tsize_t, tsample_t);
-static	int PredictorDecodeTile(TIFF*, tidata_t, tsize_t, tsample_t);
-static	int PredictorEncodeRow(TIFF*, tidata_t, tsize_t, tsample_t);
-static	int PredictorEncodeTile(TIFF*, tidata_t, tsize_t, tsample_t);
-
-static int
-PredictorSetup(TIFF* tif)
-{
-	static const char module[] = "PredictorSetup";
-
-	TIFFPredictorState* sp = PredictorState(tif);
-	TIFFDirectory* td = &tif->tif_dir;
-
-	switch (sp->predictor)		/* no differencing */
-	{
-		case PREDICTOR_NONE:
-			return 1;
-		case PREDICTOR_HORIZONTAL:
-			if (td->td_bitspersample != 8
-			    && td->td_bitspersample != 16
-			    && td->td_bitspersample != 32) {
-				TIFFErrorExt(tif->tif_clientdata, module,
-    "Horizontal differencing \"Predictor\" not supported with %d-bit samples",
-					  td->td_bitspersample);
-				return 0;
-			}
-			break;
-		case PREDICTOR_FLOATINGPOINT:
-			if (td->td_sampleformat != SAMPLEFORMAT_IEEEFP) {
-				TIFFErrorExt(tif->tif_clientdata, module,
-	"Floating point \"Predictor\" not supported with %d data format",
-					  td->td_sampleformat);
-				return 0;
-			}
-			break;
-		default:
-			TIFFErrorExt(tif->tif_clientdata, module,
-				  "\"Predictor\" value %d not supported",
-				  sp->predictor);
-			return 0;
-	}
-	sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ?
-	    td->td_samplesperpixel : 1);
-	/*
-	 * Calculate the scanline/tile-width size in bytes.
-	 */
-	if (isTiled(tif))
-		sp->rowsize = TIFFTileRowSize(tif);
-	else
-		sp->rowsize = TIFFScanlineSize(tif);
-
-	return 1;
-}
-
-static int
-PredictorSetupDecode(TIFF* tif)
-{
-	TIFFPredictorState* sp = PredictorState(tif);
-	TIFFDirectory* td = &tif->tif_dir;
-
-	if (!(*sp->setupdecode)(tif) || !PredictorSetup(tif))
-		return 0;
-
-	if (sp->predictor == 2) {
-		switch (td->td_bitspersample) {
-			case 8:  sp->decodepfunc = horAcc8; break;
-			case 16: sp->decodepfunc = horAcc16; break;
-			case 32: sp->decodepfunc = horAcc32; break;
-		}
-		/*
-		 * Override default decoding method with one that does the
-		 * predictor stuff.
-		 */
-                if( tif->tif_decoderow != PredictorDecodeRow )
-                {
-                    sp->decoderow = tif->tif_decoderow;
-                    tif->tif_decoderow = PredictorDecodeRow;
-                    sp->decodestrip = tif->tif_decodestrip;
-                    tif->tif_decodestrip = PredictorDecodeTile;
-                    sp->decodetile = tif->tif_decodetile;
-                    tif->tif_decodetile = PredictorDecodeTile;
-                }
-		/*
-		 * If the data is horizontally differenced 16-bit data that
-		 * requires byte-swapping, then it must be byte swapped before
-		 * the accumulation step.  We do this with a special-purpose
-		 * routine and override the normal post decoding logic that
-		 * the library setup when the directory was read.
-		 */
-		if (tif->tif_flags & TIFF_SWAB) {
-			if (sp->decodepfunc == horAcc16) {
-				sp->decodepfunc = swabHorAcc16;
-				tif->tif_postdecode = _TIFFNoPostDecode;
-			} else if (sp->decodepfunc == horAcc32) {
-				sp->decodepfunc = swabHorAcc32;
-				tif->tif_postdecode = _TIFFNoPostDecode;
-			}
-		}
-	}
-
-	else if (sp->predictor == 3) {
-		sp->decodepfunc = fpAcc;
-		/*
-		 * Override default decoding method with one that does the
-		 * predictor stuff.
-		 */
-                if( tif->tif_decoderow != PredictorDecodeRow )
-                {
-                    sp->decoderow = tif->tif_decoderow;
-                    tif->tif_decoderow = PredictorDecodeRow;
-                    sp->decodestrip = tif->tif_decodestrip;
-                    tif->tif_decodestrip = PredictorDecodeTile;
-                    sp->decodetile = tif->tif_decodetile;
-                    tif->tif_decodetile = PredictorDecodeTile;
-                }
-		/*
-		 * The data should not be swapped outside of the floating
-		 * point predictor, the accumulation routine should return
-		 * byres in the native order.
-		 */
-		if (tif->tif_flags & TIFF_SWAB) {
-			tif->tif_postdecode = _TIFFNoPostDecode;
-		}
-		/*
-		 * Allocate buffer to keep the decoded bytes before
-		 * rearranging in the ight order
-		 */
-	}
-
-	return 1;
-}
-
-static int
-PredictorSetupEncode(TIFF* tif)
-{
-	TIFFPredictorState* sp = PredictorState(tif);
-	TIFFDirectory* td = &tif->tif_dir;
-
-	if (!(*sp->setupencode)(tif) || !PredictorSetup(tif))
-		return 0;
-
-	if (sp->predictor == 2) {
-		switch (td->td_bitspersample) {
-			case 8:  sp->encodepfunc = horDiff8; break;
-			case 16: sp->encodepfunc = horDiff16; break;
-			case 32: sp->encodepfunc = horDiff32; break;
-		}
-		/*
-		 * Override default encoding method with one that does the
-		 * predictor stuff.
-		 */
-                if( tif->tif_encoderow != PredictorEncodeRow )
-                {
-                    sp->encoderow = tif->tif_encoderow;
-                    tif->tif_encoderow = PredictorEncodeRow;
-                    sp->encodestrip = tif->tif_encodestrip;
-                    tif->tif_encodestrip = PredictorEncodeTile;
-                    sp->encodetile = tif->tif_encodetile;
-                    tif->tif_encodetile = PredictorEncodeTile;
-                }
-	}
-	
-	else if (sp->predictor == 3) {
-		sp->encodepfunc = fpDiff;
-		/*
-		 * Override default encoding method with one that does the
-		 * predictor stuff.
-		 */
-                if( tif->tif_encoderow != PredictorEncodeRow )
-                {
-                    sp->encoderow = tif->tif_encoderow;
-                    tif->tif_encoderow = PredictorEncodeRow;
-                    sp->encodestrip = tif->tif_encodestrip;
-                    tif->tif_encodestrip = PredictorEncodeTile;
-                    sp->encodetile = tif->tif_encodetile;
-                    tif->tif_encodetile = PredictorEncodeTile;
-                }
-	}
-
-	return 1;
-}
-
-#define REPEAT4(n, op)		\
-    switch (n) {		\
-    default: { int i; for (i = n-4; i > 0; i--) { op; } } \
-    case 4:  op;		\
-    case 3:  op;		\
-    case 2:  op;		\
-    case 1:  op;		\
-    case 0:  ;			\
-    }
-
-static void
-horAcc8(TIFF* tif, tidata_t cp0, tsize_t cc)
-{
-	tsize_t stride = PredictorState(tif)->stride;
-
-	char* cp = (char*) cp0;
-	if (cc > stride) {
-		cc -= stride;
-		/*
-		 * Pipeline the most common cases.
-		 */
-		if (stride == 3)  {
-			unsigned int cr = cp[0];
-			unsigned int cg = cp[1];
-			unsigned int cb = cp[2];
-			do {
-				cc -= 3, cp += 3;
-				cp[0] = (char) (cr += cp[0]);
-				cp[1] = (char) (cg += cp[1]);
-				cp[2] = (char) (cb += cp[2]);
-			} while ((int32) cc > 0);
-		} else if (stride == 4)  {
-			unsigned int cr = cp[0];
-			unsigned int cg = cp[1];
-			unsigned int cb = cp[2];
-			unsigned int ca = cp[3];
-			do {
-				cc -= 4, cp += 4;
-				cp[0] = (char) (cr += cp[0]);
-				cp[1] = (char) (cg += cp[1]);
-				cp[2] = (char) (cb += cp[2]);
-				cp[3] = (char) (ca += cp[3]);
-			} while ((int32) cc > 0);
-		} else  {
-			do {
-				REPEAT4(stride, cp[stride] =
-					(char) (cp[stride] + *cp); cp++)
-				cc -= stride;
-			} while ((int32) cc > 0);
-		}
-	}
-}
-
-static void
-swabHorAcc16(TIFF* tif, tidata_t cp0, tsize_t cc)
-{
-	tsize_t stride = PredictorState(tif)->stride;
-	uint16* wp = (uint16*) cp0;
-	tsize_t wc = cc / 2;
-
-	if (wc > stride) {
-		TIFFSwabArrayOfShort(wp, wc);
-		wc -= stride;
-		do {
-			REPEAT4(stride, wp[stride] += wp[0]; wp++)
-			wc -= stride;
-		} while ((int32) wc > 0);
-	}
-}
-
-static void
-horAcc16(TIFF* tif, tidata_t cp0, tsize_t cc)
-{
-	tsize_t stride = PredictorState(tif)->stride;
-	uint16* wp = (uint16*) cp0;
-	tsize_t wc = cc / 2;
-
-	if (wc > stride) {
-		wc -= stride;
-		do {
-			REPEAT4(stride, wp[stride] += wp[0]; wp++)
-			wc -= stride;
-		} while ((int32) wc > 0);
-	}
-}
-
-static void
-swabHorAcc32(TIFF* tif, tidata_t cp0, tsize_t cc)
-{
-	tsize_t stride = PredictorState(tif)->stride;
-	uint32* wp = (uint32*) cp0;
-	tsize_t wc = cc / 4;
-
-	if (wc > stride) {
-		TIFFSwabArrayOfLong(wp, wc);
-		wc -= stride;
-		do {
-			REPEAT4(stride, wp[stride] += wp[0]; wp++)
-			wc -= stride;
-		} while ((int32) wc > 0);
-	}
-}
-
-static void
-horAcc32(TIFF* tif, tidata_t cp0, tsize_t cc)
-{
-	tsize_t stride = PredictorState(tif)->stride;
-	uint32* wp = (uint32*) cp0;
-	tsize_t wc = cc / 4;
-
-	if (wc > stride) {
-		wc -= stride;
-		do {
-			REPEAT4(stride, wp[stride] += wp[0]; wp++)
-			wc -= stride;
-		} while ((int32) wc > 0);
-	}
-}
-
-/*
- * Floating point predictor accumulation routine.
- */
-static void
-fpAcc(TIFF* tif, tidata_t cp0, tsize_t cc)
-{
-	tsize_t stride = PredictorState(tif)->stride;
-	uint32 bps = tif->tif_dir.td_bitspersample / 8;
-	tsize_t wc = cc / bps;
-	tsize_t count = cc;
-	uint8 *cp = (uint8 *) cp0;
-	uint8 *tmp = (uint8 *)_TIFFmalloc(cc);
-
-	if (!tmp)
-		return;
-
-	while (count > stride) {
-		REPEAT4(stride, cp[stride] += cp[0]; cp++)
-		count -= stride;
-	}
-
-	_TIFFmemcpy(tmp, cp0, cc);
-	cp = (uint8 *) cp0;
-	for (count = 0; count < wc; count++) {
-		uint32 byte;
-		for (byte = 0; byte < bps; byte++) {
-#if WORDS_BIGENDIAN
-			cp[bps * count + byte] = tmp[byte * wc + count];
-#else
-			cp[bps * count + byte] =
-				tmp[(bps - byte - 1) * wc + count];
-#endif
-		}
-	}
-	_TIFFfree(tmp);
-}
-
-/*
- * Decode a scanline and apply the predictor routine.
- */
-static int
-PredictorDecodeRow(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s)
-{
-	TIFFPredictorState *sp = PredictorState(tif);
-
-	assert(sp != NULL);
-	assert(sp->decoderow != NULL);
-	assert(sp->decodepfunc != NULL);
-
-	if ((*sp->decoderow)(tif, op0, occ0, s)) {
-		(*sp->decodepfunc)(tif, op0, occ0);
-		return 1;
-	} else
-		return 0;
-}
-
-/*
- * Decode a tile/strip and apply the predictor routine.
- * Note that horizontal differencing must be done on a
- * row-by-row basis.  The width of a "row" has already
- * been calculated at pre-decode time according to the
- * strip/tile dimensions.
- */
-static int
-PredictorDecodeTile(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s)
-{
-	TIFFPredictorState *sp = PredictorState(tif);
-
-	assert(sp != NULL);
-	assert(sp->decodetile != NULL);
-
-	if ((*sp->decodetile)(tif, op0, occ0, s)) {
-		tsize_t rowsize = sp->rowsize;
-		assert(rowsize > 0);
-		assert(sp->decodepfunc != NULL);
-		while ((long)occ0 > 0) {
-			(*sp->decodepfunc)(tif, op0, (tsize_t) rowsize);
-			occ0 -= rowsize;
-			op0 += rowsize;
-		}
-		return 1;
-	} else
-		return 0;
-}
-
-static void
-horDiff8(TIFF* tif, tidata_t cp0, tsize_t cc)
-{
-	TIFFPredictorState* sp = PredictorState(tif);
-	tsize_t stride = sp->stride;
-	char* cp = (char*) cp0;
-
-	if (cc > stride) {
-		cc -= stride;
-		/*
-		 * Pipeline the most common cases.
-		 */
-		if (stride == 3) {
-			int r1, g1, b1;
-			int r2 = cp[0];
-			int g2 = cp[1];
-			int b2 = cp[2];
-			do {
-				r1 = cp[3]; cp[3] = r1-r2; r2 = r1;
-				g1 = cp[4]; cp[4] = g1-g2; g2 = g1;
-				b1 = cp[5]; cp[5] = b1-b2; b2 = b1;
-				cp += 3;
-			} while ((int32)(cc -= 3) > 0);
-		} else if (stride == 4) {
-			int r1, g1, b1, a1;
-			int r2 = cp[0];
-			int g2 = cp[1];
-			int b2 = cp[2];
-			int a2 = cp[3];
-			do {
-				r1 = cp[4]; cp[4] = r1-r2; r2 = r1;
-				g1 = cp[5]; cp[5] = g1-g2; g2 = g1;
-				b1 = cp[6]; cp[6] = b1-b2; b2 = b1;
-				a1 = cp[7]; cp[7] = a1-a2; a2 = a1;
-				cp += 4;
-			} while ((int32)(cc -= 4) > 0);
-		} else {
-			cp += cc - 1;
-			do {
-				REPEAT4(stride, cp[stride] -= cp[0]; cp--)
-			} while ((int32)(cc -= stride) > 0);
-		}
-	}
-}
-
-static void
-horDiff16(TIFF* tif, tidata_t cp0, tsize_t cc)
-{
-	TIFFPredictorState* sp = PredictorState(tif);
-	tsize_t stride = sp->stride;
-	int16 *wp = (int16*) cp0;
-	tsize_t wc = cc/2;
-
-	if (wc > stride) {
-		wc -= stride;
-		wp += wc - 1;
-		do {
-			REPEAT4(stride, wp[stride] -= wp[0]; wp--)
-			wc -= stride;
-		} while ((int32) wc > 0);
-	}
-}
-
-static void
-horDiff32(TIFF* tif, tidata_t cp0, tsize_t cc)
-{
-	TIFFPredictorState* sp = PredictorState(tif);
-	tsize_t stride = sp->stride;
-	int32 *wp = (int32*) cp0;
-	tsize_t wc = cc/4;
-
-	if (wc > stride) {
-		wc -= stride;
-		wp += wc - 1;
-		do {
-			REPEAT4(stride, wp[stride] -= wp[0]; wp--)
-			wc -= stride;
-		} while ((int32) wc > 0);
-	}
-}
-
-/*
- * Floating point predictor differencing routine.
- */
-static void
-fpDiff(TIFF* tif, tidata_t cp0, tsize_t cc)
-{
-	tsize_t stride = PredictorState(tif)->stride;
-	uint32 bps = tif->tif_dir.td_bitspersample / 8;
-	tsize_t wc = cc / bps;
-	tsize_t count;
-	uint8 *cp = (uint8 *) cp0;
-	uint8 *tmp = (uint8 *)_TIFFmalloc(cc);
-
-	if (!tmp)
-		return;
-
-	_TIFFmemcpy(tmp, cp0, cc);
-	for (count = 0; count < wc; count++) {
-		uint32 byte;
-		for (byte = 0; byte < bps; byte++) {
-#if WORDS_BIGENDIAN
-			cp[byte * wc + count] =	tmp[bps * count + byte];
-#else
-			cp[(bps - byte - 1) * wc + count] =
-				tmp[bps * count + byte];
-#endif
-		}
-	}
-	_TIFFfree(tmp);
-
-	cp = (uint8 *) cp0;
-	cp += cc - stride - 1;
-	for (count = cc; count > stride; count -= stride)
-		REPEAT4(stride, cp[stride] -= cp[0]; cp--)
-}
-
-static int
-PredictorEncodeRow(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s)
-{
-	TIFFPredictorState *sp = PredictorState(tif);
-
-	assert(sp != NULL);
-	assert(sp->encodepfunc != NULL);
-	assert(sp->encoderow != NULL);
-
-	/* XXX horizontal differencing alters user's data XXX */
-	(*sp->encodepfunc)(tif, bp, cc);
-	return (*sp->encoderow)(tif, bp, cc, s);
-}
-
-static int
-PredictorEncodeTile(TIFF* tif, tidata_t bp0, tsize_t cc0, tsample_t s)
-{
-	static const char module[] = "PredictorEncodeTile";
-	TIFFPredictorState *sp = PredictorState(tif);
-        uint8 *working_copy;
-	tsize_t cc = cc0, rowsize;
-	unsigned char* bp;
-        int result_code;
-
-	assert(sp != NULL);
-	assert(sp->encodepfunc != NULL);
-	assert(sp->encodetile != NULL);
-
-        /* 
-         * Do predictor manipulation in a working buffer to avoid altering
-         * the callers buffer. http://trac.osgeo.org/gdal/ticket/1965
-         */
-        working_copy = (uint8*) _TIFFmalloc(cc0);
-        if( working_copy == NULL )
-        {
-            TIFFErrorExt(tif->tif_clientdata, module, 
-                         "Out of memory allocating %d byte temp buffer.",
-                         cc0 );
-            return 0;
-        }
-        memcpy( working_copy, bp0, cc0 );
-        bp = working_copy;
-
-	rowsize = sp->rowsize;
-	assert(rowsize > 0);
-	assert((cc0%rowsize)==0);
-	while (cc > 0) {
-		(*sp->encodepfunc)(tif, bp, rowsize);
-		cc -= rowsize;
-		bp += rowsize;
-	}
-	result_code = (*sp->encodetile)(tif, working_copy, cc0, s);
-
-        _TIFFfree( working_copy );
-
-        return result_code;
-}
-
-#define	FIELD_PREDICTOR	(FIELD_CODEC+0)		/* XXX */
-
-static const TIFFFieldInfo predictFieldInfo[] = {
-    { TIFFTAG_PREDICTOR,	 1, 1, TIFF_SHORT,	FIELD_PREDICTOR,
-      FALSE,	FALSE,	"Predictor" },
-};
-
-static int
-PredictorVSetField(TIFF* tif, ttag_t tag, va_list ap)
-{
-	TIFFPredictorState *sp = PredictorState(tif);
-
-	assert(sp != NULL);
-	assert(sp->vsetparent != NULL);
-
-	switch (tag) {
-	case TIFFTAG_PREDICTOR:
-		sp->predictor = (uint16) va_arg(ap, int);
-		TIFFSetFieldBit(tif, FIELD_PREDICTOR);
-		break;
-	default:
-		return (*sp->vsetparent)(tif, tag, ap);
-	}
-	tif->tif_flags |= TIFF_DIRTYDIRECT;
-	return 1;
-}
-
-static int
-PredictorVGetField(TIFF* tif, ttag_t tag, va_list ap)
-{
-	TIFFPredictorState *sp = PredictorState(tif);
-
-	assert(sp != NULL);
-	assert(sp->vgetparent != NULL);
-
-	switch (tag) {
-	case TIFFTAG_PREDICTOR:
-		*va_arg(ap, uint16*) = sp->predictor;
-		break;
-	default:
-		return (*sp->vgetparent)(tif, tag, ap);
-	}
-	return 1;
-}
-
-static void
-PredictorPrintDir(TIFF* tif, FILE* fd, long flags)
-{
-	TIFFPredictorState* sp = PredictorState(tif);
-
-	(void) flags;
-	if (TIFFFieldSet(tif,FIELD_PREDICTOR)) {
-		fprintf(fd, "  Predictor: ");
-		switch (sp->predictor) {
-		case 1: fprintf(fd, "none "); break;
-		case 2: fprintf(fd, "horizontal differencing "); break;
-		case 3: fprintf(fd, "floating point predictor "); break;
-		}
-		fprintf(fd, "%u (0x%x)\n", sp->predictor, sp->predictor);
-	}
-	if (sp->printdir)
-		(*sp->printdir)(tif, fd, flags);
-}
-
-int
-TIFFPredictorInit(TIFF* tif)
-{
-	TIFFPredictorState* sp = PredictorState(tif);
-
-	assert(sp != 0);
-
-	/*
-	 * Merge codec-specific tag information.
-	 */
-	if (!_TIFFMergeFieldInfo(tif, predictFieldInfo,
-				 TIFFArrayCount(predictFieldInfo))) {
-		TIFFErrorExt(tif->tif_clientdata, "TIFFPredictorInit",
-			     "Merging Predictor codec-specific tags failed");
-		return 0;
-	}
-
-	/*
-	 * Override parent get/set field methods.
-	 */
-	sp->vgetparent = tif->tif_tagmethods.vgetfield;
-	tif->tif_tagmethods.vgetfield =
-            PredictorVGetField;/* hook for predictor tag */
-	sp->vsetparent = tif->tif_tagmethods.vsetfield;
-	tif->tif_tagmethods.vsetfield =
-            PredictorVSetField;/* hook for predictor tag */
-	sp->printdir = tif->tif_tagmethods.printdir;
-	tif->tif_tagmethods.printdir =
-            PredictorPrintDir;	/* hook for predictor tag */
-
-	sp->setupdecode = tif->tif_setupdecode;
-	tif->tif_setupdecode = PredictorSetupDecode;
-	sp->setupencode = tif->tif_setupencode;
-	tif->tif_setupencode = PredictorSetupEncode;
-
-	sp->predictor = 1;			/* default value */
-	sp->encodepfunc = NULL;			/* no predictor routine */
-	sp->decodepfunc = NULL;			/* no predictor routine */
-	return 1;
-}
-
-int
-TIFFPredictorCleanup(TIFF* tif)
-{
-	TIFFPredictorState* sp = PredictorState(tif);
-
-	assert(sp != 0);
-
-	tif->tif_tagmethods.vgetfield = sp->vgetparent;
-	tif->tif_tagmethods.vsetfield = sp->vsetparent;
-	tif->tif_tagmethods.printdir = sp->printdir;
-	tif->tif_setupdecode = sp->setupdecode;
-	tif->tif_setupencode = sp->setupencode;
-
-	return 1;
-}
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_predict.h b/Source/LibTIFF/tif_predict.h
deleted file mode 100644
index 518d5ca..0000000
--- a/Source/LibTIFF/tif_predict.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/* $Id: tif_predict.h,v 1.37 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1995-1997 Sam Leffler
- * Copyright (c) 1995-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-#ifndef _TIFFPREDICT_
-#define	_TIFFPREDICT_
-/*
- * ``Library-private'' Support for the Predictor Tag
- */
-
-/*
- * Codecs that want to support the Predictor tag must place
- * this structure first in their private state block so that
- * the predictor code can cast tif_data to find its state.
- */
-typedef struct {
-	int		predictor;	/* predictor tag value */
-	int		stride;		/* sample stride over data */
-	tsize_t		rowsize;	/* tile/strip row size */
-
- 	TIFFCodeMethod  encoderow;	/* parent codec encode/decode row */
- 	TIFFCodeMethod  encodestrip;	/* parent codec encode/decode strip */
- 	TIFFCodeMethod  encodetile;	/* parent codec encode/decode tile */ 
- 	TIFFPostMethod  encodepfunc;	/* horizontal differencer */
- 
- 	TIFFCodeMethod  decoderow;	/* parent codec encode/decode row */
- 	TIFFCodeMethod  decodestrip;	/* parent codec encode/decode strip */
- 	TIFFCodeMethod  decodetile;	/* parent codec encode/decode tile */ 
- 	TIFFPostMethod  decodepfunc;	/* horizontal accumulator */
-
-	TIFFVGetMethod	vgetparent;	/* super-class method */
-	TIFFVSetMethod	vsetparent;	/* super-class method */
-	TIFFPrintMethod	printdir;	/* super-class method */
-	TIFFBoolMethod	setupdecode;	/* super-class method */
-	TIFFBoolMethod	setupencode;	/* super-class method */
-} TIFFPredictorState;
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-extern	int TIFFPredictorInit(TIFF*);
-extern	int TIFFPredictorCleanup(TIFF*);
-#if defined(__cplusplus)
-}
-#endif
-#endif /* _TIFFPREDICT_ */
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_print.c b/Source/LibTIFF/tif_print.c
deleted file mode 100644
index 016649d..0000000
--- a/Source/LibTIFF/tif_print.c
+++ /dev/null
@@ -1,642 +0,0 @@
-/* $Id: tif_print.c,v 1.37 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library.
- *
- * Directory Printing Support
- */
-#include "tiffiop.h"
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-
-static const char *photoNames[] = {
-    "min-is-white",				/* PHOTOMETRIC_MINISWHITE */
-    "min-is-black",				/* PHOTOMETRIC_MINISBLACK */
-    "RGB color",				/* PHOTOMETRIC_RGB */
-    "palette color (RGB from colormap)",	/* PHOTOMETRIC_PALETTE */
-    "transparency mask",			/* PHOTOMETRIC_MASK */
-    "separated",				/* PHOTOMETRIC_SEPARATED */
-    "YCbCr",					/* PHOTOMETRIC_YCBCR */
-    "7 (0x7)",
-    "CIE L*a*b*",				/* PHOTOMETRIC_CIELAB */
-};
-#define	NPHOTONAMES	(sizeof (photoNames) / sizeof (photoNames[0]))
-
-static const char *orientNames[] = {
-    "0 (0x0)",
-    "row 0 top, col 0 lhs",			/* ORIENTATION_TOPLEFT */
-    "row 0 top, col 0 rhs",			/* ORIENTATION_TOPRIGHT */
-    "row 0 bottom, col 0 rhs",			/* ORIENTATION_BOTRIGHT */
-    "row 0 bottom, col 0 lhs",			/* ORIENTATION_BOTLEFT */
-    "row 0 lhs, col 0 top",			/* ORIENTATION_LEFTTOP */
-    "row 0 rhs, col 0 top",			/* ORIENTATION_RIGHTTOP */
-    "row 0 rhs, col 0 bottom",			/* ORIENTATION_RIGHTBOT */
-    "row 0 lhs, col 0 bottom",			/* ORIENTATION_LEFTBOT */
-};
-#define	NORIENTNAMES	(sizeof (orientNames) / sizeof (orientNames[0]))
-
-static void
-_TIFFPrintField(FILE* fd, const TIFFFieldInfo *fip,
-		uint32 value_count, void *raw_data)
-{
-	uint32 j;
-		
-	fprintf(fd, "  %s: ", fip->field_name);
-
-	for(j = 0; j < value_count; j++) {
-		if(fip->field_type == TIFF_BYTE)
-			fprintf(fd, "%u", ((uint8 *) raw_data)[j]);
-		else if(fip->field_type == TIFF_UNDEFINED)
-			fprintf(fd, "0x%x",
-				(unsigned int) ((unsigned char *) raw_data)[j]);
-		else if(fip->field_type == TIFF_SBYTE)
-			fprintf(fd, "%d", ((int8 *) raw_data)[j]);
-		else if(fip->field_type == TIFF_SHORT)
-			fprintf(fd, "%u", ((uint16 *) raw_data)[j]);
-		else if(fip->field_type == TIFF_SSHORT)
-			fprintf(fd, "%d", ((int16 *) raw_data)[j]);
-		else if(fip->field_type == TIFF_LONG)
-			fprintf(fd, "%lu",
-				(unsigned long)((uint32 *) raw_data)[j]);
-		else if(fip->field_type == TIFF_SLONG)
-			fprintf(fd, "%ld", (long)((int32 *) raw_data)[j]);
-		else if(fip->field_type == TIFF_RATIONAL
-			|| fip->field_type == TIFF_SRATIONAL
-			|| fip->field_type == TIFF_FLOAT)
-			fprintf(fd, "%f", ((float *) raw_data)[j]);
-		else if(fip->field_type == TIFF_IFD)
-			fprintf(fd, "0x%ulx", ((uint32 *) raw_data)[j]);
-		else if(fip->field_type == TIFF_ASCII) {
-			fprintf(fd, "%s", (char *) raw_data);
-			break;
-		}
-		else if(fip->field_type == TIFF_DOUBLE)
-			fprintf(fd, "%f", ((double *) raw_data)[j]);
-		else if(fip->field_type == TIFF_FLOAT)
-			fprintf(fd, "%f", ((float *)raw_data)[j]);
-		else {
-			fprintf(fd, "<unsupported data type in TIFFPrint>");
-			break;
-		}
-
-		if(j < value_count - 1)
-			fprintf(fd, ",");
-	}
-
-	fprintf(fd, "\n");
-}
-
-static int
-_TIFFPrettyPrintField(TIFF* tif, FILE* fd, ttag_t tag,
-		      uint32 value_count, void *raw_data)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-
-	switch (tag)
-	{
-		case TIFFTAG_INKSET:
-			fprintf(fd, "  Ink Set: ");
-			switch (*((uint16*)raw_data)) {
-				case INKSET_CMYK:
-					fprintf(fd, "CMYK\n");
-					break;
-				default:
-					fprintf(fd, "%u (0x%x)\n",
-						*((uint16*)raw_data),
-						*((uint16*)raw_data));
-					break;
-			}
-			return 1;
-		case TIFFTAG_WHITEPOINT:
-			fprintf(fd, "  White Point: %g-%g\n",
-				((float *)raw_data)[0], ((float *)raw_data)[1]);			return 1;
-		case TIFFTAG_REFERENCEBLACKWHITE:
-		{
-			uint16 i;
-
-			fprintf(fd, "  Reference Black/White:\n");
-			for (i = 0; i < 3; i++)
-			fprintf(fd, "    %2d: %5g %5g\n", i,
-				((float *)raw_data)[2*i+0],
-				((float *)raw_data)[2*i+1]);
-			return 1;
-		}
-		case TIFFTAG_XMLPACKET:
-		{
-			uint32 i;
-			
-			fprintf(fd, "  XMLPacket (XMP Metadata):\n" );
-			for(i = 0; i < value_count; i++)
-				fputc(((char *)raw_data)[i], fd);
-			fprintf( fd, "\n" );
-			return 1;
-		}
-		case TIFFTAG_RICHTIFFIPTC:
-			/*
-			 * XXX: for some weird reason RichTIFFIPTC tag
-			 * defined as array of LONG values.
-			 */
-			fprintf(fd,
-				"  RichTIFFIPTC Data: <present>, %lu bytes\n",
-				(unsigned long) value_count * 4);
-			return 1;
-		case TIFFTAG_PHOTOSHOP:
-			fprintf(fd, "  Photoshop Data: <present>, %lu bytes\n",
-				(unsigned long) value_count);
-			return 1;
-		case TIFFTAG_ICCPROFILE:
-			fprintf(fd, "  ICC Profile: <present>, %lu bytes\n",
-				(unsigned long) value_count);
-			return 1;
-		case TIFFTAG_STONITS:
-			fprintf(fd,
-				"  Sample to Nits conversion factor: %.4e\n",
-				*((double*)raw_data));
-			return 1;
-        }
-
-	return 0;
-}
-
-/*
- * Print the contents of the current directory
- * to the specified stdio file stream.
- */
-void
-TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-	char *sep;
-	uint16 i;
-	long l, n;
-
-	fprintf(fd, "TIFF Directory at offset 0x%lx (%lu)\n",
-		(unsigned long)tif->tif_diroff, (unsigned long)tif->tif_diroff);
-	if (TIFFFieldSet(tif,FIELD_SUBFILETYPE)) {
-		fprintf(fd, "  Subfile Type:");
-		sep = " ";
-		if (td->td_subfiletype & FILETYPE_REDUCEDIMAGE) {
-			fprintf(fd, "%sreduced-resolution image", sep);
-			sep = "/";
-		}
-		if (td->td_subfiletype & FILETYPE_PAGE) {
-			fprintf(fd, "%smulti-page document", sep);
-			sep = "/";
-		}
-		if (td->td_subfiletype & FILETYPE_MASK)
-			fprintf(fd, "%stransparency mask", sep);
-		fprintf(fd, " (%lu = 0x%lx)\n",
-		    (long) td->td_subfiletype, (long) td->td_subfiletype);
-	}
-	if (TIFFFieldSet(tif,FIELD_IMAGEDIMENSIONS)) {
-		fprintf(fd, "  Image Width: %lu Image Length: %lu",
-		    (unsigned long) td->td_imagewidth, (unsigned long) td->td_imagelength);
-		if (TIFFFieldSet(tif,FIELD_IMAGEDEPTH))
-			fprintf(fd, " Image Depth: %lu",
-			    (unsigned long) td->td_imagedepth);
-		fprintf(fd, "\n");
-	}
-	if (TIFFFieldSet(tif,FIELD_TILEDIMENSIONS)) {
-		fprintf(fd, "  Tile Width: %lu Tile Length: %lu",
-		    (unsigned long) td->td_tilewidth, (unsigned long) td->td_tilelength);
-		if (TIFFFieldSet(tif,FIELD_TILEDEPTH))
-			fprintf(fd, " Tile Depth: %lu",
-			    (unsigned long) td->td_tiledepth);
-		fprintf(fd, "\n");
-	}
-	if (TIFFFieldSet(tif,FIELD_RESOLUTION)) {
-		fprintf(fd, "  Resolution: %g, %g",
-		    td->td_xresolution, td->td_yresolution);
-		if (TIFFFieldSet(tif,FIELD_RESOLUTIONUNIT)) {
-			switch (td->td_resolutionunit) {
-			case RESUNIT_NONE:
-				fprintf(fd, " (unitless)");
-				break;
-			case RESUNIT_INCH:
-				fprintf(fd, " pixels/inch");
-				break;
-			case RESUNIT_CENTIMETER:
-				fprintf(fd, " pixels/cm");
-				break;
-			default:
-				fprintf(fd, " (unit %u = 0x%x)",
-				    td->td_resolutionunit,
-				    td->td_resolutionunit);
-				break;
-			}
-		}
-		fprintf(fd, "\n");
-	}
-	if (TIFFFieldSet(tif,FIELD_POSITION))
-		fprintf(fd, "  Position: %g, %g\n",
-		    td->td_xposition, td->td_yposition);
-	if (TIFFFieldSet(tif,FIELD_BITSPERSAMPLE))
-		fprintf(fd, "  Bits/Sample: %u\n", td->td_bitspersample);
-	if (TIFFFieldSet(tif,FIELD_SAMPLEFORMAT)) {
-		fprintf(fd, "  Sample Format: ");
-		switch (td->td_sampleformat) {
-		case SAMPLEFORMAT_VOID:
-			fprintf(fd, "void\n");
-			break;
-		case SAMPLEFORMAT_INT:
-			fprintf(fd, "signed integer\n");
-			break;
-		case SAMPLEFORMAT_UINT:
-			fprintf(fd, "unsigned integer\n");
-			break;
-		case SAMPLEFORMAT_IEEEFP:
-			fprintf(fd, "IEEE floating point\n");
-			break;
-		case SAMPLEFORMAT_COMPLEXINT:
-			fprintf(fd, "complex signed integer\n");
-			break;
-		case SAMPLEFORMAT_COMPLEXIEEEFP:
-			fprintf(fd, "complex IEEE floating point\n");
-			break;
-		default:
-			fprintf(fd, "%u (0x%x)\n",
-			    td->td_sampleformat, td->td_sampleformat);
-			break;
-		}
-	}
-	if (TIFFFieldSet(tif,FIELD_COMPRESSION)) {
-		const TIFFCodec* c = TIFFFindCODEC(td->td_compression);
-		fprintf(fd, "  Compression Scheme: ");
-		if (c)
-			fprintf(fd, "%s\n", c->name);
-		else
-			fprintf(fd, "%u (0x%x)\n",
-			    td->td_compression, td->td_compression);
-	}
-	if (TIFFFieldSet(tif,FIELD_PHOTOMETRIC)) {
-		fprintf(fd, "  Photometric Interpretation: ");
-		if (td->td_photometric < NPHOTONAMES)
-			fprintf(fd, "%s\n", photoNames[td->td_photometric]);
-		else {
-			switch (td->td_photometric) {
-			case PHOTOMETRIC_LOGL:
-				fprintf(fd, "CIE Log2(L)\n");
-				break;
-			case PHOTOMETRIC_LOGLUV:
-				fprintf(fd, "CIE Log2(L) (u',v')\n");
-				break;
-			default:
-				fprintf(fd, "%u (0x%x)\n",
-				    td->td_photometric, td->td_photometric);
-				break;
-			}
-		}
-	}
-	if (TIFFFieldSet(tif,FIELD_EXTRASAMPLES) && td->td_extrasamples) {
-		fprintf(fd, "  Extra Samples: %u<", td->td_extrasamples);
-		sep = "";
-		for (i = 0; i < td->td_extrasamples; i++) {
-			switch (td->td_sampleinfo[i]) {
-			case EXTRASAMPLE_UNSPECIFIED:
-				fprintf(fd, "%sunspecified", sep);
-				break;
-			case EXTRASAMPLE_ASSOCALPHA:
-				fprintf(fd, "%sassoc-alpha", sep);
-				break;
-			case EXTRASAMPLE_UNASSALPHA:
-				fprintf(fd, "%sunassoc-alpha", sep);
-				break;
-			default:
-				fprintf(fd, "%s%u (0x%x)", sep,
-				    td->td_sampleinfo[i], td->td_sampleinfo[i]);
-				break;
-			}
-			sep = ", ";
-		}
-		fprintf(fd, ">\n");
-	}
-	if (TIFFFieldSet(tif,FIELD_INKNAMES)) {
-		char* cp;
-		fprintf(fd, "  Ink Names: ");
-		i = td->td_samplesperpixel;
-		sep = "";
-		for (cp = td->td_inknames; i > 0; cp = strchr(cp,'\0')+1, i--) {
-			fputs(sep, fd);
-			_TIFFprintAscii(fd, cp);
-			sep = ", ";
-		}
-                fputs("\n", fd);
-	}
-	if (TIFFFieldSet(tif,FIELD_THRESHHOLDING)) {
-		fprintf(fd, "  Thresholding: ");
-		switch (td->td_threshholding) {
-		case THRESHHOLD_BILEVEL:
-			fprintf(fd, "bilevel art scan\n");
-			break;
-		case THRESHHOLD_HALFTONE:
-			fprintf(fd, "halftone or dithered scan\n");
-			break;
-		case THRESHHOLD_ERRORDIFFUSE:
-			fprintf(fd, "error diffused\n");
-			break;
-		default:
-			fprintf(fd, "%u (0x%x)\n",
-			    td->td_threshholding, td->td_threshholding);
-			break;
-		}
-	}
-	if (TIFFFieldSet(tif,FIELD_FILLORDER)) {
-		fprintf(fd, "  FillOrder: ");
-		switch (td->td_fillorder) {
-		case FILLORDER_MSB2LSB:
-			fprintf(fd, "msb-to-lsb\n");
-			break;
-		case FILLORDER_LSB2MSB:
-			fprintf(fd, "lsb-to-msb\n");
-			break;
-		default:
-			fprintf(fd, "%u (0x%x)\n",
-			    td->td_fillorder, td->td_fillorder);
-			break;
-		}
-	}
-	if (TIFFFieldSet(tif,FIELD_YCBCRSUBSAMPLING))
-        {
-            /*
-             * For hacky reasons (see tif_jpeg.c - JPEGFixupTestSubsampling),
-             * we need to fetch this rather than trust what is in our
-             * structures.
-             */
-            uint16 subsampling[2];
-
-            TIFFGetField( tif, TIFFTAG_YCBCRSUBSAMPLING, 
-                          subsampling + 0, subsampling + 1 );
-		fprintf(fd, "  YCbCr Subsampling: %u, %u\n",
-                        subsampling[0], subsampling[1] );
-        }
-	if (TIFFFieldSet(tif,FIELD_YCBCRPOSITIONING)) {
-		fprintf(fd, "  YCbCr Positioning: ");
-		switch (td->td_ycbcrpositioning) {
-		case YCBCRPOSITION_CENTERED:
-			fprintf(fd, "centered\n");
-			break;
-		case YCBCRPOSITION_COSITED:
-			fprintf(fd, "cosited\n");
-			break;
-		default:
-			fprintf(fd, "%u (0x%x)\n",
-			    td->td_ycbcrpositioning, td->td_ycbcrpositioning);
-			break;
-		}
-	}
-	if (TIFFFieldSet(tif,FIELD_HALFTONEHINTS))
-		fprintf(fd, "  Halftone Hints: light %u dark %u\n",
-		    td->td_halftonehints[0], td->td_halftonehints[1]);
-	if (TIFFFieldSet(tif,FIELD_ORIENTATION)) {
-		fprintf(fd, "  Orientation: ");
-		if (td->td_orientation < NORIENTNAMES)
-			fprintf(fd, "%s\n", orientNames[td->td_orientation]);
-		else
-			fprintf(fd, "%u (0x%x)\n",
-			    td->td_orientation, td->td_orientation);
-	}
-	if (TIFFFieldSet(tif,FIELD_SAMPLESPERPIXEL))
-		fprintf(fd, "  Samples/Pixel: %u\n", td->td_samplesperpixel);
-	if (TIFFFieldSet(tif,FIELD_ROWSPERSTRIP)) {
-		fprintf(fd, "  Rows/Strip: ");
-		if (td->td_rowsperstrip == (uint32) -1)
-			fprintf(fd, "(infinite)\n");
-		else
-			fprintf(fd, "%lu\n", (unsigned long) td->td_rowsperstrip);
-	}
-	if (TIFFFieldSet(tif,FIELD_MINSAMPLEVALUE))
-		fprintf(fd, "  Min Sample Value: %u\n", td->td_minsamplevalue);
-	if (TIFFFieldSet(tif,FIELD_MAXSAMPLEVALUE))
-		fprintf(fd, "  Max Sample Value: %u\n", td->td_maxsamplevalue);
-	if (TIFFFieldSet(tif,FIELD_SMINSAMPLEVALUE))
-		fprintf(fd, "  SMin Sample Value: %g\n",
-		    td->td_sminsamplevalue);
-	if (TIFFFieldSet(tif,FIELD_SMAXSAMPLEVALUE))
-		fprintf(fd, "  SMax Sample Value: %g\n",
-		    td->td_smaxsamplevalue);
-	if (TIFFFieldSet(tif,FIELD_PLANARCONFIG)) {
-		fprintf(fd, "  Planar Configuration: ");
-		switch (td->td_planarconfig) {
-		case PLANARCONFIG_CONTIG:
-			fprintf(fd, "single image plane\n");
-			break;
-		case PLANARCONFIG_SEPARATE:
-			fprintf(fd, "separate image planes\n");
-			break;
-		default:
-			fprintf(fd, "%u (0x%x)\n",
-			    td->td_planarconfig, td->td_planarconfig);
-			break;
-		}
-	}
-	if (TIFFFieldSet(tif,FIELD_PAGENUMBER))
-		fprintf(fd, "  Page Number: %u-%u\n",
-		    td->td_pagenumber[0], td->td_pagenumber[1]);
-	if (TIFFFieldSet(tif,FIELD_COLORMAP)) {
-		fprintf(fd, "  Color Map: ");
-		if (flags & TIFFPRINT_COLORMAP) {
-			fprintf(fd, "\n");
-			n = 1L<<td->td_bitspersample;
-			for (l = 0; l < n; l++)
-				fprintf(fd, "   %5lu: %5u %5u %5u\n",
-				    l,
-				    td->td_colormap[0][l],
-				    td->td_colormap[1][l],
-				    td->td_colormap[2][l]);
-		} else
-			fprintf(fd, "(present)\n");
-	}
-	if (TIFFFieldSet(tif,FIELD_TRANSFERFUNCTION)) {
-		fprintf(fd, "  Transfer Function: ");
-		if (flags & TIFFPRINT_CURVES) {
-			fprintf(fd, "\n");
-			n = 1L<<td->td_bitspersample;
-			for (l = 0; l < n; l++) {
-				fprintf(fd, "    %2lu: %5u",
-				    l, td->td_transferfunction[0][l]);
-				for (i = 1; i < td->td_samplesperpixel; i++)
-					fprintf(fd, " %5u",
-					    td->td_transferfunction[i][l]);
-				fputc('\n', fd);
-			}
-		} else
-			fprintf(fd, "(present)\n");
-	}
-	if (TIFFFieldSet(tif, FIELD_SUBIFD) && (td->td_subifd)) {
-		fprintf(fd, "  SubIFD Offsets:");
-		for (i = 0; i < td->td_nsubifd; i++)
-			fprintf(fd, " %5lu", (long) td->td_subifd[i]);
-		fputc('\n', fd);
-	}
-
-        /*
-        ** Custom tag support.
-        */
-        {
-            int  i;
-            short count;
-
-            count = (short) TIFFGetTagListCount(tif);
-            for(i = 0; i < count; i++) {
-                ttag_t  tag = TIFFGetTagListEntry(tif, i);
-                const TIFFFieldInfo *fip;
-                uint32 value_count;
-                int mem_alloc = 0;
-                void *raw_data;
-
-                fip = TIFFFieldWithTag(tif, tag);
-                if(fip == NULL)
-			continue;
-
-		if(fip->field_passcount) {
-			if(TIFFGetField(tif, tag, &value_count, &raw_data) != 1)
-				continue;
-		} else {
-			if (fip->field_readcount == TIFF_VARIABLE
-			    || fip->field_readcount == TIFF_VARIABLE2)
-				value_count = 1;
-			else if (fip->field_readcount == TIFF_SPP)
-				value_count = td->td_samplesperpixel;
-			else
-				value_count = fip->field_readcount;
-			if ((fip->field_type == TIFF_ASCII
-			     || fip->field_readcount == TIFF_VARIABLE
-			     || fip->field_readcount == TIFF_VARIABLE2
-			     || fip->field_readcount == TIFF_SPP
-			     || value_count > 1)
-			    && fip->field_tag != TIFFTAG_PAGENUMBER
-			    && fip->field_tag != TIFFTAG_HALFTONEHINTS
-			    && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING
-			    && fip->field_tag != TIFFTAG_DOTRANGE) {
-				if(TIFFGetField(tif, tag, &raw_data) != 1)
-					continue;
-			} else if (fip->field_tag != TIFFTAG_PAGENUMBER
-				   && fip->field_tag != TIFFTAG_HALFTONEHINTS
-				   && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING
-				   && fip->field_tag != TIFFTAG_DOTRANGE) {
-				raw_data = _TIFFmalloc(
-					_TIFFDataSize(fip->field_type)
-					* value_count);
-				mem_alloc = 1;
-				if(TIFFGetField(tif, tag, raw_data) != 1) {
-					_TIFFfree(raw_data);
-					continue;
-				}
-			} else {
-				/* 
-				 * XXX: Should be fixed and removed, see the
-				 * notes related to TIFFTAG_PAGENUMBER,
-				 * TIFFTAG_HALFTONEHINTS,
-				 * TIFFTAG_YCBCRSUBSAMPLING and
-				 * TIFFTAG_DOTRANGE tags in tif_dir.c. */
-				char *tmp;
-				raw_data = _TIFFmalloc(
-					_TIFFDataSize(fip->field_type)
-					* value_count);
-				tmp = raw_data;
-				mem_alloc = 1;
-				if(TIFFGetField(tif, tag, tmp,
-				tmp + _TIFFDataSize(fip->field_type)) != 1) {
-					_TIFFfree(raw_data);
-					continue;
-				}
-			}
-		}
-
-		/*
-		 * Catch the tags which needs to be specially handled and
-		 * pretty print them. If tag not handled in
-		 * _TIFFPrettyPrintField() fall down and print it as any other
-		 * tag.
-		 */
-		if (_TIFFPrettyPrintField(tif, fd, tag, value_count, raw_data)) {
-			if(mem_alloc)
-				_TIFFfree(raw_data);
-			continue;
-		}
-		else
-			_TIFFPrintField(fd, fip, value_count, raw_data);
-
-		if(mem_alloc)
-			_TIFFfree(raw_data);
-            }
-        }
-        
-	if (tif->tif_tagmethods.printdir)
-		(*tif->tif_tagmethods.printdir)(tif, fd, flags);
-	if ((flags & TIFFPRINT_STRIPS) &&
-	    TIFFFieldSet(tif,FIELD_STRIPOFFSETS)) {
-		tstrip_t s;
-
-		fprintf(fd, "  %lu %s:\n",
-		    (long) td->td_nstrips,
-		    isTiled(tif) ? "Tiles" : "Strips");
-		for (s = 0; s < td->td_nstrips; s++)
-			fprintf(fd, "    %3lu: [%8lu, %8lu]\n",
-			    (unsigned long) s,
-			    (unsigned long) td->td_stripoffset[s],
-			    (unsigned long) td->td_stripbytecount[s]);
-	}
-}
-
-void
-_TIFFprintAscii(FILE* fd, const char* cp)
-{
-	for (; *cp != '\0'; cp++) {
-		const char* tp;
-
-		if (isprint((int)*cp)) {
-			fputc(*cp, fd);
-			continue;
-		}
-		for (tp = "\tt\bb\rr\nn\vv"; *tp; tp++)
-			if (*tp++ == *cp)
-				break;
-		if (*tp)
-			fprintf(fd, "\\%c", *tp);
-		else
-			fprintf(fd, "\\%03o", *cp & 0xff);
-	}
-}
-
-void
-_TIFFprintAsciiTag(FILE* fd, const char* name, const char* value)
-{
-	fprintf(fd, "  %s: \"", name);
-	_TIFFprintAscii(fd, value);
-	fprintf(fd, "\"\n");
-}
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_read.c b/Source/LibTIFF/tif_read.c
deleted file mode 100644
index 717e561..0000000
--- a/Source/LibTIFF/tif_read.c
+++ /dev/null
@@ -1,750 +0,0 @@
-/* $Id: tif_read.c,v 1.37 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library.
- * Scanline-oriented Read Support
- */
-#include "tiffiop.h"
-#include <stdio.h>
-
-	int TIFFFillStrip(TIFF*, tstrip_t);
-	int TIFFFillTile(TIFF*, ttile_t);
-static	int TIFFStartStrip(TIFF*, tstrip_t);
-static	int TIFFStartTile(TIFF*, ttile_t);
-static	int TIFFCheckRead(TIFF*, int);
-
-#define	NOSTRIP	((tstrip_t) -1)			/* undefined state */
-#define	NOTILE	((ttile_t) -1)			/* undefined state */
-
-/*
- * Seek to a random row+sample in a file.
- */
-static int
-TIFFSeek(TIFF* tif, uint32 row, tsample_t sample)
-{
-	register TIFFDirectory *td = &tif->tif_dir;
-	tstrip_t strip;
-
-	if (row >= td->td_imagelength) {	/* out of range */
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			     "%lu: Row out of range, max %lu",
-			     (unsigned long) row,
-			     (unsigned long) td->td_imagelength);
-		return (0);
-	}
-	if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
-		if (sample >= td->td_samplesperpixel) {
-			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			    "%lu: Sample out of range, max %lu",
-			    (unsigned long) sample, (unsigned long) td->td_samplesperpixel);
-			return (0);
-		}
-		strip = sample*td->td_stripsperimage + row/td->td_rowsperstrip;
-	} else
-		strip = row / td->td_rowsperstrip;
-	if (strip != tif->tif_curstrip) {	/* different strip, refill */
-		if (!TIFFFillStrip(tif, strip))
-			return (0);
-	} else if (row < tif->tif_row) {
-		/*
-		 * Moving backwards within the same strip: backup
-		 * to the start and then decode forward (below).
-		 *
-		 * NB: If you're planning on lots of random access within a
-		 * strip, it's better to just read and decode the entire
-		 * strip, and then access the decoded data in a random fashion.
-		 */
-		if (!TIFFStartStrip(tif, strip))
-			return (0);
-	}
-	if (row != tif->tif_row) {
-		/*
-		 * Seek forward to the desired row.
-		 */
-		if (!(*tif->tif_seek)(tif, row - tif->tif_row))
-			return (0);
-		tif->tif_row = row;
-	}
-	return (1);
-}
-
-int
-TIFFReadScanline(TIFF* tif, tdata_t buf, uint32 row, tsample_t sample)
-{
-	int e;
-
-	if (!TIFFCheckRead(tif, 0))
-		return (-1);
-	if( (e = TIFFSeek(tif, row, sample)) != 0) {
-		/*
-		 * Decompress desired row into user buffer.
-		 */
-		e = (*tif->tif_decoderow)
-		    (tif, (tidata_t) buf, tif->tif_scanlinesize, sample);
-
-		/* we are now poised at the beginning of the next row */
-		tif->tif_row = row + 1;
-
-		if (e)
-			(*tif->tif_postdecode)(tif, (tidata_t) buf,
-			    tif->tif_scanlinesize);
-	}
-	return (e > 0 ? 1 : -1);
-}
-
-/*
- * Read a strip of data and decompress the specified
- * amount into the user-supplied buffer.
- */
-tsize_t
-TIFFReadEncodedStrip(TIFF* tif, tstrip_t strip, tdata_t buf, tsize_t size)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-	uint32 nrows;
-	tsize_t stripsize;
-        tstrip_t sep_strip, strips_per_sep;
-
-	if (!TIFFCheckRead(tif, 0))
-		return (-1);
-	if (strip >= td->td_nstrips) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			     "%ld: Strip out of range, max %ld",
-			     (long) strip, (long) td->td_nstrips);
-		return (-1);
-	}
-	/*
-	 * Calculate the strip size according to the number of
-	 * rows in the strip (check for truncated last strip on any
-	 * of the separations).
-	 */
-	if( td->td_rowsperstrip >= td->td_imagelength )
-		strips_per_sep = 1;
-	else
-		strips_per_sep = (td->td_imagelength+td->td_rowsperstrip-1)
-		    / td->td_rowsperstrip;
-
-	sep_strip = strip % strips_per_sep;
-
-	if (sep_strip != strips_per_sep-1 ||
-	    (nrows = td->td_imagelength % td->td_rowsperstrip) == 0)
-		nrows = td->td_rowsperstrip;
-
-	stripsize = TIFFVStripSize(tif, nrows);
-	if (size == (tsize_t) -1)
-		size = stripsize;
-	else if (size > stripsize)
-		size = stripsize;
-	if (TIFFFillStrip(tif, strip)
-	    && (*tif->tif_decodestrip)(tif, (tidata_t) buf, size,   
-	    (tsample_t)(strip / td->td_stripsperimage)) > 0 ) {
-		(*tif->tif_postdecode)(tif, (tidata_t) buf, size);
-		return (size);
-	} else
-		return ((tsize_t) -1);
-}
-
-static tsize_t
-TIFFReadRawStrip1(TIFF* tif,
-    tstrip_t strip, tdata_t buf, tsize_t size, const char* module)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-
-	assert((tif->tif_flags&TIFF_NOREADRAW)==0);
-	if (!isMapped(tif)) {
-		tsize_t cc;
-
-		if (!SeekOK(tif, td->td_stripoffset[strip])) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-			    "%s: Seek error at scanline %lu, strip %lu",
-			    tif->tif_name,
-			    (unsigned long) tif->tif_row, (unsigned long) strip);
-			return (-1);
-		}
-		cc = TIFFReadFile(tif, buf, size);
-		if (cc != size) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-		"%s: Read error at scanline %lu; got %lu bytes, expected %lu",
-			    tif->tif_name,
-			    (unsigned long) tif->tif_row,
-			    (unsigned long) cc,
-			    (unsigned long) size);
-			return (-1);
-		}
-	} else {
-		if (td->td_stripoffset[strip] + size > tif->tif_size) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-    "%s: Read error at scanline %lu, strip %lu; got %lu bytes, expected %lu",
-			    tif->tif_name,
-			    (unsigned long) tif->tif_row,
-			    (unsigned long) strip,
-			    (unsigned long) tif->tif_size - td->td_stripoffset[strip],
-			    (unsigned long) size);
-			return (-1);
-		}
-		_TIFFmemcpy(buf, tif->tif_base + td->td_stripoffset[strip],
-                            size);
-	}
-	return (size);
-}
-
-/*
- * Read a strip of data from the file.
- */
-tsize_t
-TIFFReadRawStrip(TIFF* tif, tstrip_t strip, tdata_t buf, tsize_t size)
-{
-	static const char module[] = "TIFFReadRawStrip";
-	TIFFDirectory *td = &tif->tif_dir;
-	/*
-	 * FIXME: butecount should have tsize_t type, but for now libtiff
-	 * defines tsize_t as a signed 32-bit integer and we are losing
-	 * ability to read arrays larger than 2^31 bytes. So we are using
-	 * uint32 instead of tsize_t here.
-	 */
-	uint32 bytecount;
-
-	if (!TIFFCheckRead(tif, 0))
-		return ((tsize_t) -1);
-	if (strip >= td->td_nstrips) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			     "%lu: Strip out of range, max %lu",
-			     (unsigned long) strip,
-			     (unsigned long) td->td_nstrips);
-		return ((tsize_t) -1);
-	}
-	if (tif->tif_flags&TIFF_NOREADRAW)
-	{
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-	"Compression scheme does not support access to raw uncompressed data");
-		return ((tsize_t) -1);
-	}
-	bytecount = td->td_stripbytecount[strip];
-	if (bytecount <= 0) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-		    "%lu: Invalid strip byte count, strip %lu",
-		    (unsigned long) bytecount, (unsigned long) strip);
-		return ((tsize_t) -1);
-	}
-	if (size != (tsize_t)-1 && (uint32)size < bytecount)
-		bytecount = size;
-	return (TIFFReadRawStrip1(tif, strip, buf, bytecount, module));
-}
-
-/*
- * Read the specified strip and setup for decoding. The data buffer is
- * expanded, as necessary, to hold the strip's data.
- */
-int
-TIFFFillStrip(TIFF* tif, tstrip_t strip)
-{
-	static const char module[] = "TIFFFillStrip";
-	TIFFDirectory *td = &tif->tif_dir;
-
-	if ((tif->tif_flags&TIFF_NOREADRAW)==0)
-	{
-		/*
-		 * FIXME: butecount should have tsize_t type, but for now
-		 * libtiff defines tsize_t as a signed 32-bit integer and we
-		 * are losing ability to read arrays larger than 2^31 bytes.
-		 * So we are using uint32 instead of tsize_t here.
-		 */
-		uint32 bytecount = td->td_stripbytecount[strip];
-		if (bytecount <= 0) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-			    "%s: Invalid strip byte count %lu, strip %lu",
-			    tif->tif_name, (unsigned long) bytecount,
-			    (unsigned long) strip);
-			return (0);
-		}
-		if (isMapped(tif) &&
-		    (isFillOrder(tif, td->td_fillorder)
-		    || (tif->tif_flags & TIFF_NOBITREV))) {
-			/*
-			 * The image is mapped into memory and we either don't
-			 * need to flip bits or the compression routine is
-			 * going to handle this operation itself.  In this
-			 * case, avoid copying the raw data and instead just
-			 * reference the data from the memory mapped file
-			 * image.  This assumes that the decompression
-			 * routines do not modify the contents of the raw data
-			 * buffer (if they try to, the application will get a
-			 * fault since the file is mapped read-only).
-			 */
-			if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
-				_TIFFfree(tif->tif_rawdata);
-			tif->tif_flags &= ~TIFF_MYBUFFER;
-			/*
-			 * We must check for overflow, potentially causing
-			 * an OOB read. Instead of simple
-			 *
-			 *  td->td_stripoffset[strip]+bytecount > tif->tif_size
-			 *
-			 * comparison (which can overflow) we do the following
-			 * two comparisons:
-			 */
-			if (bytecount > tif->tif_size ||
-			    td->td_stripoffset[strip] > tif->tif_size - bytecount) {
-				/*
-				 * This error message might seem strange, but
-				 * it's what would happen if a read were done
-				 * instead.
-				 */
-				TIFFErrorExt(tif->tif_clientdata, module,
-
-					"%s: Read error on strip %lu; "
-					"got %lu bytes, expected %lu",
-					tif->tif_name, (unsigned long) strip,
-					(unsigned long) tif->tif_size - td->td_stripoffset[strip],
-					(unsigned long) bytecount);
-				tif->tif_curstrip = NOSTRIP;
-				return (0);
-			}
-			tif->tif_rawdatasize = bytecount;
-			tif->tif_rawdata = tif->tif_base + td->td_stripoffset[strip];
-		} else {
-			/*
-			 * Expand raw data buffer, if needed, to hold data
-			 * strip coming from file (perhaps should set upper
-			 * bound on the size of a buffer we'll use?).
-			 */
-			if (bytecount > (uint32)tif->tif_rawdatasize) {
-				tif->tif_curstrip = NOSTRIP;
-				if ((tif->tif_flags & TIFF_MYBUFFER) == 0) {
-					TIFFErrorExt(tif->tif_clientdata,
-						     module,
-				"%s: Data buffer too small to hold strip %lu",
-						     tif->tif_name,
-						     (unsigned long) strip);
-					return (0);
-				}
-				if (!TIFFReadBufferSetup(tif, 0,
-				    TIFFroundup(bytecount, 1024)))
-					return (0);
-			}
-			if ((uint32)TIFFReadRawStrip1(tif, strip,
-				(unsigned char *)tif->tif_rawdata,
-				bytecount, module) != bytecount)
-				return (0);
-			if (!isFillOrder(tif, td->td_fillorder) &&
-			    (tif->tif_flags & TIFF_NOBITREV) == 0)
-				TIFFReverseBits(tif->tif_rawdata, bytecount);
-		}
-	}
-	return (TIFFStartStrip(tif, strip));
-}
-
-/*
- * Tile-oriented Read Support
- * Contributed by Nancy Cam (Silicon Graphics).
- */
-
-/*
- * Read and decompress a tile of data.  The
- * tile is selected by the (x,y,z,s) coordinates.
- */
-tsize_t
-TIFFReadTile(TIFF* tif,
-    tdata_t buf, uint32 x, uint32 y, uint32 z, tsample_t s)
-{
-	if (!TIFFCheckRead(tif, 1) || !TIFFCheckTile(tif, x, y, z, s))
-		return (-1);
-	return (TIFFReadEncodedTile(tif,
-	    TIFFComputeTile(tif, x, y, z, s), buf, (tsize_t) -1));
-}
-
-/*
- * Read a tile of data and decompress the specified
- * amount into the user-supplied buffer.
- */
-tsize_t
-TIFFReadEncodedTile(TIFF* tif, ttile_t tile, tdata_t buf, tsize_t size)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-	tsize_t tilesize = tif->tif_tilesize;
-
-	if (!TIFFCheckRead(tif, 1))
-		return (-1);
-	if (tile >= td->td_nstrips) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			     "%ld: Tile out of range, max %ld",
-			     (long) tile, (unsigned long) td->td_nstrips);
-		return (-1);
-	}
-	if (size == (tsize_t) -1)
-		size = tilesize;
-	else if (size > tilesize)
-		size = tilesize;
-	if (TIFFFillTile(tif, tile) && (*tif->tif_decodetile)(tif,
-	    (tidata_t) buf, size, (tsample_t)(tile/td->td_stripsperimage))) {
-		(*tif->tif_postdecode)(tif, (tidata_t) buf, size);
-		return (size);
-	} else
-		return (-1);
-}
-
-static tsize_t
-TIFFReadRawTile1(TIFF* tif,
-    ttile_t tile, tdata_t buf, tsize_t size, const char* module)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-
-	assert((tif->tif_flags&TIFF_NOREADRAW)==0);
-	if (!isMapped(tif)) {
-		tsize_t cc;
-
-		if (!SeekOK(tif, td->td_stripoffset[tile])) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-			    "%s: Seek error at row %ld, col %ld, tile %ld",
-			    tif->tif_name,
-			    (long) tif->tif_row,
-			    (long) tif->tif_col,
-			    (long) tile);
-			return ((tsize_t) -1);
-		}
-		cc = TIFFReadFile(tif, buf, size);
-		if (cc != size) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-	    "%s: Read error at row %ld, col %ld; got %lu bytes, expected %lu",
-			    tif->tif_name,
-			    (long) tif->tif_row,
-			    (long) tif->tif_col,
-			    (unsigned long) cc,
-			    (unsigned long) size);
-			return ((tsize_t) -1);
-		}
-	} else {
-		if (td->td_stripoffset[tile] + size > tif->tif_size) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-    "%s: Read error at row %ld, col %ld, tile %ld; got %lu bytes, expected %lu",
-			    tif->tif_name,
-			    (long) tif->tif_row,
-			    (long) tif->tif_col,
-			    (long) tile,
-			    (unsigned long) tif->tif_size - td->td_stripoffset[tile],
-			    (unsigned long) size);
-			return ((tsize_t) -1);
-		}
-		_TIFFmemcpy(buf, tif->tif_base + td->td_stripoffset[tile], size);
-	}
-	return (size);
-}
-
-/*
- * Read a tile of data from the file.
- */
-tsize_t
-TIFFReadRawTile(TIFF* tif, ttile_t tile, tdata_t buf, tsize_t size)
-{
-	static const char module[] = "TIFFReadRawTile";
-	TIFFDirectory *td = &tif->tif_dir;
-	/*
-	 * FIXME: butecount should have tsize_t type, but for now libtiff
-	 * defines tsize_t as a signed 32-bit integer and we are losing
-	 * ability to read arrays larger than 2^31 bytes. So we are using
-	 * uint32 instead of tsize_t here.
-	 */
-	uint32 bytecount;
-
-	if (!TIFFCheckRead(tif, 1))
-		return ((tsize_t) -1);
-	if (tile >= td->td_nstrips) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			     "%lu: Tile out of range, max %lu",
-		    (unsigned long) tile, (unsigned long) td->td_nstrips);
-		return ((tsize_t) -1);
-	}
-	if (tif->tif_flags&TIFF_NOREADRAW)
-	{
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-	"Compression scheme does not support access to raw uncompressed data");
-		return ((tsize_t) -1);
-	}
-	bytecount = td->td_stripbytecount[tile];
-	if (size != (tsize_t) -1 && (uint32)size < bytecount)
-		bytecount = size;
-	return (TIFFReadRawTile1(tif, tile, buf, bytecount, module));
-}
-
-/*
- * Read the specified tile and setup for decoding. The data buffer is
- * expanded, as necessary, to hold the tile's data.
- */
-int
-TIFFFillTile(TIFF* tif, ttile_t tile)
-{
-	static const char module[] = "TIFFFillTile";
-	TIFFDirectory *td = &tif->tif_dir;
-
-	if ((tif->tif_flags&TIFF_NOREADRAW)==0)
-	{
-		/*
-		 * FIXME: butecount should have tsize_t type, but for now
-		 * libtiff defines tsize_t as a signed 32-bit integer and we
-		 * are losing ability to read arrays larger than 2^31 bytes.
-		 * So we are using uint32 instead of tsize_t here.
-		 */
-		uint32 bytecount = td->td_stripbytecount[tile];
-		if (bytecount <= 0) {
-			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			    "%lu: Invalid tile byte count, tile %lu",
-			    (unsigned long) bytecount, (unsigned long) tile);
-			return (0);
-		}
-		if (isMapped(tif) &&
-		    (isFillOrder(tif, td->td_fillorder)
-		     || (tif->tif_flags & TIFF_NOBITREV))) {
-			/*
-			 * The image is mapped into memory and we either don't
-			 * need to flip bits or the compression routine is
-			 * going to handle this operation itself.  In this
-			 * case, avoid copying the raw data and instead just
-			 * reference the data from the memory mapped file
-			 * image.  This assumes that the decompression
-			 * routines do not modify the contents of the raw data
-			 * buffer (if they try to, the application will get a
-			 * fault since the file is mapped read-only).
-			 */
-			if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
-				_TIFFfree(tif->tif_rawdata);
-			tif->tif_flags &= ~TIFF_MYBUFFER;
-			/*
-			 * We must check for overflow, potentially causing
-			 * an OOB read. Instead of simple
-			 *
-			 *  td->td_stripoffset[tile]+bytecount > tif->tif_size
-			 *
-			 * comparison (which can overflow) we do the following
-			 * two comparisons:
-			 */
-			if (bytecount > tif->tif_size ||
-			    td->td_stripoffset[tile] > tif->tif_size - bytecount) {
-				tif->tif_curtile = NOTILE;
-				return (0);
-			}
-			tif->tif_rawdatasize = bytecount;
-			tif->tif_rawdata =
-				tif->tif_base + td->td_stripoffset[tile];
-		} else {
-			/*
-			 * Expand raw data buffer, if needed, to hold data
-			 * tile coming from file (perhaps should set upper
-			 * bound on the size of a buffer we'll use?).
-			 */
-			if (bytecount > (uint32)tif->tif_rawdatasize) {
-				tif->tif_curtile = NOTILE;
-				if ((tif->tif_flags & TIFF_MYBUFFER) == 0) {
-					TIFFErrorExt(tif->tif_clientdata,
-						     module,
-				"%s: Data buffer too small to hold tile %ld",
-						     tif->tif_name,
-						     (long) tile);
-					return (0);
-				}
-				if (!TIFFReadBufferSetup(tif, 0,
-				    TIFFroundup(bytecount, 1024)))
-					return (0);
-			}
-			if ((uint32)TIFFReadRawTile1(tif, tile,
-				(unsigned char *)tif->tif_rawdata,
-				bytecount, module) != bytecount)
-				return (0);
-			if (!isFillOrder(tif, td->td_fillorder) &&
-			    (tif->tif_flags & TIFF_NOBITREV) == 0)
-				TIFFReverseBits(tif->tif_rawdata, bytecount);
-		}
-	}
-	return (TIFFStartTile(tif, tile));
-}
-
-/*
- * Setup the raw data buffer in preparation for
- * reading a strip of raw data.  If the buffer
- * is specified as zero, then a buffer of appropriate
- * size is allocated by the library.  Otherwise,
- * the client must guarantee that the buffer is
- * large enough to hold any individual strip of
- * raw data.
- */
-int
-TIFFReadBufferSetup(TIFF* tif, tdata_t bp, tsize_t size)
-{
-	static const char module[] = "TIFFReadBufferSetup";
-
-	assert((tif->tif_flags&TIFF_NOREADRAW)==0);
-	if (tif->tif_rawdata) {
-		if (tif->tif_flags & TIFF_MYBUFFER)
-			_TIFFfree(tif->tif_rawdata);
-		tif->tif_rawdata = NULL;
-	}
-
-	if (bp) {
-		tif->tif_rawdatasize = size;
-		tif->tif_rawdata = (tidata_t) bp;
-		tif->tif_flags &= ~TIFF_MYBUFFER;
-	} else {
-		tif->tif_rawdatasize = TIFFroundup(size, 1024);
-		if (tif->tif_rawdatasize > 0)
-			tif->tif_rawdata = (tidata_t) _TIFFmalloc(tif->tif_rawdatasize);
-		tif->tif_flags |= TIFF_MYBUFFER;
-	}
-	if ((tif->tif_rawdata == NULL) || (tif->tif_rawdatasize == 0)) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-		    "%s: No space for data buffer at scanline %ld",
-		    tif->tif_name, (long) tif->tif_row);
-		tif->tif_rawdatasize = 0;
-		return (0);
-	}
-	return (1);
-}
-
-/*
- * Set state to appear as if a
- * strip has just been read in.
- */
-static int
-TIFFStartStrip(TIFF* tif, tstrip_t strip)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-
-	if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
-		if (!(*tif->tif_setupdecode)(tif))
-			return (0);
-		tif->tif_flags |= TIFF_CODERSETUP;
-	}
-	tif->tif_curstrip = strip;
-	tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
-	if (tif->tif_flags&TIFF_NOREADRAW)
-	{
-		tif->tif_rawcp = NULL;
-		tif->tif_rawcc = 0;
-	}
-	else
-	{
-		tif->tif_rawcp = tif->tif_rawdata;
-		tif->tif_rawcc = td->td_stripbytecount[strip];
-	}
-	return ((*tif->tif_predecode)(tif,
-			(tsample_t)(strip / td->td_stripsperimage)));
-}
-
-/*
- * Set state to appear as if a
- * tile has just been read in.
- */
-static int
-TIFFStartTile(TIFF* tif, ttile_t tile)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-
-	if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
-		if (!(*tif->tif_setupdecode)(tif))
-			return (0);
-		tif->tif_flags |= TIFF_CODERSETUP;
-	}
-	tif->tif_curtile = tile;
-	tif->tif_row =
-	    (tile % TIFFhowmany(td->td_imagewidth, td->td_tilewidth)) *
-		td->td_tilelength;
-	tif->tif_col =
-	    (tile % TIFFhowmany(td->td_imagelength, td->td_tilelength)) *
-		td->td_tilewidth;
-	if (tif->tif_flags&TIFF_NOREADRAW)
-	{
-		tif->tif_rawcp = NULL;
-		tif->tif_rawcc = 0;
-	}
-	else
-	{
-		tif->tif_rawcp = tif->tif_rawdata;
-		tif->tif_rawcc = td->td_stripbytecount[tile];
-	}
-	return ((*tif->tif_predecode)(tif,
-			(tsample_t)(tile/td->td_stripsperimage)));
-}
-
-static int
-TIFFCheckRead(TIFF* tif, int tiles)
-{
-	if (tif->tif_mode == O_WRONLY) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "File not open for reading");
-		return (0);
-	}
-	if (tiles ^ isTiled(tif)) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name, tiles ?
-		    "Can not read tiles from a stripped image" :
-		    "Can not read scanlines from a tiled image");
-		return (0);
-	}
-	return (1);
-}
-
-void
-_TIFFNoPostDecode(TIFF* tif, tidata_t buf, tsize_t cc)
-{
-    (void) tif; (void) buf; (void) cc;
-}
-
-void
-_TIFFSwab16BitData(TIFF* tif, tidata_t buf, tsize_t cc)
-{
-    (void) tif;
-    assert((cc & 1) == 0);
-    TIFFSwabArrayOfShort((uint16*) buf, cc/2);
-}
-
-void
-_TIFFSwab24BitData(TIFF* tif, tidata_t buf, tsize_t cc)
-{
-    (void) tif;
-    assert((cc % 3) == 0);
-    TIFFSwabArrayOfTriples((uint8*) buf, cc/3);
-}
-
-void
-_TIFFSwab32BitData(TIFF* tif, tidata_t buf, tsize_t cc)
-{
-    (void) tif;
-    assert((cc & 3) == 0);
-    TIFFSwabArrayOfLong((uint32*) buf, cc/4);
-}
-
-void
-_TIFFSwab64BitData(TIFF* tif, tidata_t buf, tsize_t cc)
-{
-    (void) tif;
-    assert((cc & 7) == 0);
-    TIFFSwabArrayOfDouble((double*) buf, cc/8);
-}
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_stream.cxx b/Source/LibTIFF/tif_stream.cxx
deleted file mode 100644
index a3aaea1..0000000
--- a/Source/LibTIFF/tif_stream.cxx
+++ /dev/null
@@ -1,295 +0,0 @@
-/* $Id: tif_stream.cxx,v 1.32 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1996 Sam Leffler
- * Copyright (c) 1991-1996 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library UNIX-specific Routines.
- */
-#include "tiffiop.h"
-#include <iostream>
-
-#ifndef __VMS
-using namespace std;
-#endif
-
-class tiffis_data
-{
-  public:
-
-	istream	*myIS;
-        long	myStreamStartPos;
-};
-
-class tiffos_data
-{
-  public:
-
-	ostream	*myOS;
-	long	myStreamStartPos;
-};
-
-static tsize_t
-_tiffosReadProc(thandle_t, tdata_t, tsize_t)
-{
-        return 0;
-}
-
-static tsize_t
-_tiffisReadProc(thandle_t fd, tdata_t buf, tsize_t size)
-{
-        tiffis_data	*data = (tiffis_data *)fd;
-
-        data->myIS->read((char *)buf, (int)size);
-
-        return data->myIS->gcount();
-}
-
-static tsize_t
-_tiffosWriteProc(thandle_t fd, tdata_t buf, tsize_t size)
-{
-	tiffos_data	*data = (tiffos_data *)fd;
-	ostream		*os = data->myOS;
-	int		pos = os->tellp();
-
-	os->write((const char *)buf, size);
-
-	return ((int)os->tellp()) - pos;
-}
-
-static tsize_t
-_tiffisWriteProc(thandle_t, tdata_t, tsize_t)
-{
-	return 0;
-}
-
-static toff_t
-_tiffosSeekProc(thandle_t fd, toff_t off, int whence)
-{
-	tiffos_data	*data = (tiffos_data *)fd;
-	ostream	*os = data->myOS;
-
-	// if the stream has already failed, don't do anything
-	if( os->fail() )
-		return os->tellp();
-
-	switch(whence) {
-	case SEEK_SET:
-	    os->seekp(data->myStreamStartPos + off, ios::beg);
-		break;
-	case SEEK_CUR:
-		os->seekp(off, ios::cur);
-		break;
-	case SEEK_END:
-		os->seekp(off, ios::end);
-		break;
-	}
-
-	// Attempt to workaround problems with seeking past the end of the
-	// stream.  ofstream doesn't have a problem with this but
-	// ostrstream/ostringstream does. In that situation, add intermediate
-	// '\0' characters.
-	if( os->fail() ) {
-#ifdef __VMS
-		int		old_state;
-#else
-		ios::iostate	old_state;
-#endif
-		toff_t		origin=0;
-
-		old_state = os->rdstate();
-		// reset the fail bit or else tellp() won't work below
-		os->clear(os->rdstate() & ~ios::failbit);
-		switch( whence ) {
-			case SEEK_SET:
-				origin = data->myStreamStartPos;
-				break;
-			case SEEK_CUR:
-				origin = os->tellp();
-				break;
-			case SEEK_END:
-				os->seekp(0, ios::end);
-				origin = os->tellp();
-				break;
-		}
-		// restore original stream state
-		os->clear(old_state);	
-
-		// only do something if desired seek position is valid
-		if( origin + off > data->myStreamStartPos ) {
-			toff_t	num_fill;
-
-			// clear the fail bit 
-			os->clear(os->rdstate() & ~ios::failbit);
-
-			// extend the stream to the expected size
-			os->seekp(0, ios::end);
-			num_fill = origin + off - (toff_t)os->tellp();
-			for( toff_t i = 0; i < num_fill; i++ )
-				os->put('\0');
-
-			// retry the seek
-			os->seekp(origin + off, ios::beg);
-		}
-	}
-
-	return os->tellp();
-}
-
-static toff_t
-_tiffisSeekProc(thandle_t fd, toff_t off, int whence)
-{
-	tiffis_data	*data = (tiffis_data *)fd;
-
-	switch(whence) {
-	case SEEK_SET:
-		data->myIS->seekg(data->myStreamStartPos + off, ios::beg);
-		break;
-	case SEEK_CUR:
-		data->myIS->seekg(off, ios::cur);
-		break;
-	case SEEK_END:
-		data->myIS->seekg(off, ios::end);
-		break;
-	}
-
-	return ((long)data->myIS->tellg()) - data->myStreamStartPos;
-}
-
-static toff_t
-_tiffosSizeProc(thandle_t fd)
-{
-	tiffos_data	*data = (tiffos_data *)fd;
-	ostream		*os = data->myOS;
-	toff_t		pos = os->tellp();
-	toff_t		len;
-
-	os->seekp(0, ios::end);
-	len = os->tellp();
-	os->seekp(pos);
-
-	return len;
-}
-
-static toff_t
-_tiffisSizeProc(thandle_t fd)
-{
-	tiffis_data	*data = (tiffis_data *)fd;
-	int		pos = data->myIS->tellg();
-	int		len;
-
-	data->myIS->seekg(0, ios::end);
-	len = data->myIS->tellg();
-	data->myIS->seekg(pos);
-
-	return len;
-}
-
-static int
-_tiffosCloseProc(thandle_t fd)
-{
-	// Our stream was not allocated by us, so it shouldn't be closed by us.
-	delete (tiffos_data *)fd;
-	return 0;
-}
-
-static int
-_tiffisCloseProc(thandle_t fd)
-{
-	// Our stream was not allocated by us, so it shouldn't be closed by us.
-	delete (tiffis_data *)fd;
-	return 0;
-}
-
-static int
-_tiffDummyMapProc(thandle_t , tdata_t* , toff_t* )
-{
-	return (0);
-}
-
-static void
-_tiffDummyUnmapProc(thandle_t , tdata_t , toff_t )
-{
-}
-
-/*
- * Open a TIFF file descriptor for read/writing.
- */
-static TIFF*
-_tiffStreamOpen(const char* name, const char* mode, void *fd)
-{
-	TIFF*	tif;
-
-	if( strchr(mode, 'w') ) {
-		tiffos_data	*data = new tiffos_data;
-		data->myOS = (ostream *)fd;
-		data->myStreamStartPos = data->myOS->tellp();
-
-		// Open for writing.
-		tif = TIFFClientOpen(name, mode,
-				(thandle_t) data,
-				_tiffosReadProc, _tiffosWriteProc,
-				_tiffosSeekProc, _tiffosCloseProc,
-				_tiffosSizeProc,
-				_tiffDummyMapProc, _tiffDummyUnmapProc);
-	} else {
-		tiffis_data	*data = new tiffis_data;
-		data->myIS = (istream *)fd;
-		data->myStreamStartPos = data->myIS->tellg();
-		// Open for reading.
-		tif = TIFFClientOpen(name, mode,
-				(thandle_t) data,
-				_tiffisReadProc, _tiffisWriteProc,
-				_tiffisSeekProc, _tiffisCloseProc,
-				_tiffisSizeProc,
-				_tiffDummyMapProc, _tiffDummyUnmapProc);
-	}
-
-	return (tif);
-}
-
-TIFF*
-TIFFStreamOpen(const char* name, ostream *os)
-{
-	// If os is either a ostrstream or ostringstream, and has no data
-	// written to it yet, then tellp() will return -1 which will break us.
-	// We workaround this by writing out a dummy character and
-	// then seek back to the beginning.
-	if( !os->fail() && (int)os->tellp() < 0 ) {
-		*os << '\0';
-		os->seekp(0);
-	}
-
-	// NB: We don't support mapped files with streams so add 'm'
-	return _tiffStreamOpen(name, "wm", os);
-}
-
-TIFF*
-TIFFStreamOpen(const char* name, istream *is)
-{
-	// NB: We don't support mapped files with streams so add 'm'
-	return _tiffStreamOpen(name, "rm", is);
-}
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
diff --git a/Source/LibTIFF/tif_strip.c b/Source/LibTIFF/tif_strip.c
deleted file mode 100644
index ed4b485..0000000
--- a/Source/LibTIFF/tif_strip.c
+++ /dev/null
@@ -1,366 +0,0 @@
-/* $Id: tif_strip.c,v 1.37 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1991-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library.
- *
- * Strip-organized Image Support Routines.
- */
-#include "tiffiop.h"
-
-static uint32
-summarize(TIFF* tif, size_t summand1, size_t summand2, const char* where)
-{
-	/*
-	 * XXX: We are using casting to uint32 here, bacause sizeof(size_t)
-	 * may be larger than sizeof(uint32) on 64-bit architectures.
-	 */
-	uint32	bytes = summand1 + summand2;
-
-	if (bytes - summand1 != summand2) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Integer overflow in %s", where);
-		bytes = 0;
-	}
-
-	return (bytes);
-}
-
-static uint32
-multiply(TIFF* tif, size_t nmemb, size_t elem_size, const char* where)
-{
-	uint32	bytes = nmemb * elem_size;
-
-	if (elem_size && bytes / elem_size != nmemb) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Integer overflow in %s", where);
-		bytes = 0;
-	}
-
-	return (bytes);
-}
-
-/*
- * Compute which strip a (row,sample) value is in.
- */
-tstrip_t
-TIFFComputeStrip(TIFF* tif, uint32 row, tsample_t sample)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-	tstrip_t strip;
-
-	strip = row / td->td_rowsperstrip;
-	if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
-		if (sample >= td->td_samplesperpixel) {
-			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			    "%lu: Sample out of range, max %lu",
-			    (unsigned long) sample, (unsigned long) td->td_samplesperpixel);
-			return ((tstrip_t) 0);
-		}
-		strip += sample*td->td_stripsperimage;
-	}
-	return (strip);
-}
-
-/*
- * Compute how many strips are in an image.
- */
-tstrip_t
-TIFFNumberOfStrips(TIFF* tif)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-	tstrip_t nstrips;
-
-	nstrips = (td->td_rowsperstrip == (uint32) -1 ? 1 :
-	     TIFFhowmany(td->td_imagelength, td->td_rowsperstrip));
-	if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
-		nstrips = multiply(tif, nstrips, td->td_samplesperpixel,
-				   "TIFFNumberOfStrips");
-	return (nstrips);
-}
-
-/*
- * Compute the # bytes in a variable height, row-aligned strip.
- */
-tsize_t
-TIFFVStripSize(TIFF* tif, uint32 nrows)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-
-	if (nrows == (uint32) -1)
-		nrows = td->td_imagelength;
-	if (td->td_planarconfig == PLANARCONFIG_CONTIG &&
-	    td->td_photometric == PHOTOMETRIC_YCBCR &&
-	    !isUpSampled(tif)) {
-		/*
-		 * Packed YCbCr data contain one Cb+Cr for every
-		 * HorizontalSampling*VerticalSampling Y values.
-		 * Must also roundup width and height when calculating
-		 * since images that are not a multiple of the
-		 * horizontal/vertical subsampling area include
-		 * YCbCr data for the extended image.
-		 */
-		uint16 ycbcrsubsampling[2];
-		tsize_t w, scanline, samplingarea;
-
-		TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING,
-				      ycbcrsubsampling + 0,
-				      ycbcrsubsampling + 1);
-
-		samplingarea = ycbcrsubsampling[0]*ycbcrsubsampling[1];
-		if (samplingarea == 0) {
-			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-				     "Invalid YCbCr subsampling");
-			return 0;
-		}
-
-		w = TIFFroundup(td->td_imagewidth, ycbcrsubsampling[0]);
-		scanline = TIFFhowmany8(multiply(tif, w, td->td_bitspersample,
-						 "TIFFVStripSize"));
-		nrows = TIFFroundup(nrows, ycbcrsubsampling[1]);
-		/* NB: don't need TIFFhowmany here 'cuz everything is rounded */
-		scanline = multiply(tif, nrows, scanline, "TIFFVStripSize");
-		return ((tsize_t)
-		    summarize(tif, scanline,
-			      multiply(tif, 2, scanline / samplingarea,
-				       "TIFFVStripSize"), "TIFFVStripSize"));
-	} else
-		return ((tsize_t) multiply(tif, nrows, TIFFScanlineSize(tif),
-					   "TIFFVStripSize"));
-}
-
-
-/*
- * Compute the # bytes in a raw strip.
- */
-tsize_t
-TIFFRawStripSize(TIFF* tif, tstrip_t strip)
-{
-	TIFFDirectory* td = &tif->tif_dir;
-	tsize_t bytecount = td->td_stripbytecount[strip];
-
-	if (bytecount <= 0) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			  "%lu: Invalid strip byte count, strip %lu",
-			  (unsigned long) bytecount, (unsigned long) strip);
-		bytecount = (tsize_t) -1;
-	}
-
-	return bytecount;
-}
-
-/*
- * Compute the # bytes in a (row-aligned) strip.
- *
- * Note that if RowsPerStrip is larger than the
- * recorded ImageLength, then the strip size is
- * truncated to reflect the actual space required
- * to hold the strip.
- */
-tsize_t
-TIFFStripSize(TIFF* tif)
-{
-	TIFFDirectory* td = &tif->tif_dir;
-	uint32 rps = td->td_rowsperstrip;
-	if (rps > td->td_imagelength)
-		rps = td->td_imagelength;
-	return (TIFFVStripSize(tif, rps));
-}
-
-/*
- * Compute a default strip size based on the image
- * characteristics and a requested value.  If the
- * request is <1 then we choose a strip size according
- * to certain heuristics.
- */
-uint32
-TIFFDefaultStripSize(TIFF* tif, uint32 request)
-{
-	return (*tif->tif_defstripsize)(tif, request);
-}
-
-uint32
-_TIFFDefaultStripSize(TIFF* tif, uint32 s)
-{
-	if ((int32) s < 1) {
-		/*
-		 * If RowsPerStrip is unspecified, try to break the
-		 * image up into strips that are approximately
-		 * STRIP_SIZE_DEFAULT bytes long.
-		 */
-		tsize_t scanline = TIFFScanlineSize(tif);
-		s = (uint32)STRIP_SIZE_DEFAULT / (scanline == 0 ? 1 : scanline);
-		if (s == 0)		/* very wide images */
-			s = 1;
-	}
-	return (s);
-}
-
-/*
- * Return the number of bytes to read/write in a call to
- * one of the scanline-oriented i/o routines.  Note that
- * this number may be 1/samples-per-pixel if data is
- * stored as separate planes.
- */
-tsize_t
-TIFFScanlineSize(TIFF* tif)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-	tsize_t scanline;
-
-	if (td->td_planarconfig == PLANARCONFIG_CONTIG) {
-		if (td->td_photometric == PHOTOMETRIC_YCBCR
-		    && !isUpSampled(tif)) {
-			uint16 ycbcrsubsampling[2];
-
-			TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING,
-					      ycbcrsubsampling + 0,
-					      ycbcrsubsampling + 1);
-
-			if (ycbcrsubsampling[0]*ycbcrsubsampling[1] == 0) {
-				TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-					     "Invalid YCbCr subsampling");
-				return 0;
-			}
-
-			/* number of sample clumps per line */
-			scanline = TIFFhowmany(td->td_imagewidth,
-					       ycbcrsubsampling[0]);
-			/* number of samples per line */
-			scanline = multiply(tif, scanline,
-					    ycbcrsubsampling[0]*ycbcrsubsampling[1] + 2,
-					    "TIFFScanlineSize");
-		} else {
-			scanline = multiply(tif, td->td_imagewidth,
-					    td->td_samplesperpixel,
-					    "TIFFScanlineSize");
-		}
-	} else
-		scanline = td->td_imagewidth;
-	return ((tsize_t) TIFFhowmany8(multiply(tif, scanline,
-						td->td_bitspersample,
-						"TIFFScanlineSize")));
-}
-
-/*
- * Some stuff depends on this older version of TIFFScanlineSize
- * TODO: resolve this
- */
-tsize_t
-TIFFOldScanlineSize(TIFF* tif)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-	tsize_t scanline;
-
-	scanline = multiply (tif, td->td_bitspersample, td->td_imagewidth,
-			     "TIFFScanlineSize");
-	if (td->td_planarconfig == PLANARCONFIG_CONTIG)
-		scanline = multiply (tif, scanline, td->td_samplesperpixel,
-				     "TIFFScanlineSize");
-	return ((tsize_t) TIFFhowmany8(scanline));
-}
-
-/*
- * Return the number of bytes to read/write in a call to
- * one of the scanline-oriented i/o routines.  Note that
- * this number may be 1/samples-per-pixel if data is
- * stored as separate planes.
- * The ScanlineSize in case of YCbCrSubsampling is defined as the
- * strip size divided by the strip height, i.e. the size of a pack of vertical
- * subsampling lines divided by vertical subsampling. It should thus make
- * sense when multiplied by a multiple of vertical subsampling.
- * Some stuff depends on this newer version of TIFFScanlineSize
- * TODO: resolve this
- */
-tsize_t
-TIFFNewScanlineSize(TIFF* tif)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-	tsize_t scanline;
-
-	if (td->td_planarconfig == PLANARCONFIG_CONTIG) {
-		if (td->td_photometric == PHOTOMETRIC_YCBCR
-		    && !isUpSampled(tif)) {
-			uint16 ycbcrsubsampling[2];
-
-			TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING,
-					      ycbcrsubsampling + 0,
-					      ycbcrsubsampling + 1);
-
-			if (ycbcrsubsampling[0]*ycbcrsubsampling[1] == 0) {
-				TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-					     "Invalid YCbCr subsampling");
-				return 0;
-			}
-
-			return((tsize_t) ((((td->td_imagewidth+ycbcrsubsampling[0]-1)
-					    /ycbcrsubsampling[0])
-					   *(ycbcrsubsampling[0]*ycbcrsubsampling[1]+2)
-					   *td->td_bitspersample+7)
-					  /8)/ycbcrsubsampling[1]);
-
-		} else {
-			scanline = multiply(tif, td->td_imagewidth,
-					    td->td_samplesperpixel,
-					    "TIFFScanlineSize");
-		}
-	} else
-		scanline = td->td_imagewidth;
-	return ((tsize_t) TIFFhowmany8(multiply(tif, scanline,
-						td->td_bitspersample,
-						"TIFFScanlineSize")));
-}
-
-/*
- * Return the number of bytes required to store a complete
- * decoded and packed raster scanline (as opposed to the
- * I/O size returned by TIFFScanlineSize which may be less
- * if data is store as separate planes).
- */
-tsize_t
-TIFFRasterScanlineSize(TIFF* tif)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-	tsize_t scanline;
-	
-	scanline = multiply (tif, td->td_bitspersample, td->td_imagewidth,
-			     "TIFFRasterScanlineSize");
-	if (td->td_planarconfig == PLANARCONFIG_CONTIG) {
-		scanline = multiply (tif, scanline, td->td_samplesperpixel,
-				     "TIFFRasterScanlineSize");
-		return ((tsize_t) TIFFhowmany8(scanline));
-	} else
-		return ((tsize_t) multiply (tif, TIFFhowmany8(scanline),
-					    td->td_samplesperpixel,
-					    "TIFFRasterScanlineSize"));
-}
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_swab.c b/Source/LibTIFF/tif_swab.c
deleted file mode 100644
index aa79731..0000000
--- a/Source/LibTIFF/tif_swab.c
+++ /dev/null
@@ -1,242 +0,0 @@
-/* $Id: tif_swab.c,v 1.37 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library Bit & Byte Swapping Support.
- *
- * XXX We assume short = 16-bits and long = 32-bits XXX
- */
-#include "tiffiop.h"
-
-#ifndef TIFFSwabShort
-void
-TIFFSwabShort(uint16* wp)
-{
-	register unsigned char* cp = (unsigned char*) wp;
-	unsigned char t;
-
-	t = cp[1]; cp[1] = cp[0]; cp[0] = t;
-}
-#endif
-
-#ifndef TIFFSwabLong
-void
-TIFFSwabLong(uint32* lp)
-{
-	register unsigned char* cp = (unsigned char*) lp;
-	unsigned char t;
-
-	t = cp[3]; cp[3] = cp[0]; cp[0] = t;
-	t = cp[2]; cp[2] = cp[1]; cp[1] = t;
-}
-#endif
-
-#ifndef TIFFSwabArrayOfShort
-void
-TIFFSwabArrayOfShort(uint16* wp, register unsigned long n)
-{
-	register unsigned char* cp;
-	register unsigned char t;
-
-	/* XXX unroll loop some */
-	while (n-- > 0) {
-		cp = (unsigned char*) wp;
-		t = cp[1]; cp[1] = cp[0]; cp[0] = t;
-		wp++;
-	}
-}
-#endif
-
-#ifndef TIFFSwabArrayOfTriples
-void
-TIFFSwabArrayOfTriples(uint8* tp, unsigned long n)
-{
-	unsigned char* cp;
-	unsigned char t;
-
-	/* XXX unroll loop some */
-	while (n-- > 0) {
-		cp = (unsigned char*) tp;
-		t = cp[2]; cp[2] = cp[0]; cp[0] = t;
-		tp += 3;
-	}
-}
-#endif
-
-#ifndef TIFFSwabArrayOfLong
-void
-TIFFSwabArrayOfLong(register uint32* lp, register unsigned long n)
-{
-	register unsigned char *cp;
-	register unsigned char t;
-
-	/* XXX unroll loop some */
-	while (n-- > 0) {
-		cp = (unsigned char *)lp;
-		t = cp[3]; cp[3] = cp[0]; cp[0] = t;
-		t = cp[2]; cp[2] = cp[1]; cp[1] = t;
-		lp++;
-	}
-}
-#endif
-
-#ifndef TIFFSwabDouble
-void
-TIFFSwabDouble(double *dp)
-{
-        register uint32* lp = (uint32*) dp;
-        uint32 t;
-
-	TIFFSwabArrayOfLong(lp, 2);
-	t = lp[0]; lp[0] = lp[1]; lp[1] = t;
-}
-#endif
-
-#ifndef TIFFSwabArrayOfDouble
-void
-TIFFSwabArrayOfDouble(double* dp, register unsigned long n)
-{
-	register uint32* lp = (uint32*) dp;
-        register uint32 t;
-
-	TIFFSwabArrayOfLong(lp, n + n);
-        while (n-- > 0) {
-		t = lp[0]; lp[0] = lp[1]; lp[1] = t;
-                lp += 2;
-        }
-}
-#endif
-
-/*
- * Bit reversal tables.  TIFFBitRevTable[<byte>] gives
- * the bit reversed value of <byte>.  Used in various
- * places in the library when the FillOrder requires
- * bit reversal of byte values (e.g. CCITT Fax 3
- * encoding/decoding).  TIFFNoBitRevTable is provided
- * for algorithms that want an equivalent table that
- * do not reverse bit values.
- */
-static const unsigned char TIFFBitRevTable[256] = {
-    0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
-    0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
-    0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
-    0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
-    0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
-    0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
-    0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
-    0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
-    0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
-    0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
-    0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
-    0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
-    0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
-    0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
-    0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
-    0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
-    0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
-    0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
-    0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
-    0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
-    0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
-    0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
-    0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
-    0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
-    0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
-    0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
-    0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
-    0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
-    0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
-    0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
-    0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
-    0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
-};
-static const unsigned char TIFFNoBitRevTable[256] = {
-    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
-    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 
-    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 
-    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 
-    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 
-    0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 
-    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 
-    0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 
-    0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 
-    0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 
-    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 
-    0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 
-    0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 
-    0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 
-    0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 
-    0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 
-    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 
-    0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 
-    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 
-    0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 
-    0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 
-    0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 
-    0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 
-    0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 
-    0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 
-    0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 
-    0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 
-    0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 
-    0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 
-    0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 
-    0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 
-    0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, 
-};
-
-const unsigned char*
-TIFFGetBitRevTable(int reversed)
-{
-	return (reversed ? TIFFBitRevTable : TIFFNoBitRevTable);
-}
-
-void
-TIFFReverseBits(register unsigned char* cp, register unsigned long n)
-{
-	for (; n > 8; n -= 8) {
-		cp[0] = TIFFBitRevTable[cp[0]];
-		cp[1] = TIFFBitRevTable[cp[1]];
-		cp[2] = TIFFBitRevTable[cp[2]];
-		cp[3] = TIFFBitRevTable[cp[3]];
-		cp[4] = TIFFBitRevTable[cp[4]];
-		cp[5] = TIFFBitRevTable[cp[5]];
-		cp[6] = TIFFBitRevTable[cp[6]];
-		cp[7] = TIFFBitRevTable[cp[7]];
-		cp += 8;
-	}
-	while (n-- > 0)
-		*cp = TIFFBitRevTable[*cp], cp++;
-}
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_thunder.c b/Source/LibTIFF/tif_thunder.c
deleted file mode 100644
index 07ba7e2..0000000
--- a/Source/LibTIFF/tif_thunder.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/* $Id: tif_thunder.c,v 1.37 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-#include "tiffiop.h"
-#include <assert.h>
-#ifdef THUNDER_SUPPORT
-/*
- * TIFF Library.
- *
- * ThunderScan 4-bit Compression Algorithm Support
- */
-
-/*
- * ThunderScan uses an encoding scheme designed for
- * 4-bit pixel values.  Data is encoded in bytes, with
- * each byte split into a 2-bit code word and a 6-bit
- * data value.  The encoding gives raw data, runs of
- * pixels, or pixel values encoded as a delta from the
- * previous pixel value.  For the latter, either 2-bit
- * or 3-bit delta values are used, with the deltas packed
- * into a single byte.
- */
-#define	THUNDER_DATA		0x3f	/* mask for 6-bit data */
-#define	THUNDER_CODE		0xc0	/* mask for 2-bit code word */
-/* code values */
-#define	THUNDER_RUN		0x00	/* run of pixels w/ encoded count */
-#define	THUNDER_2BITDELTAS	0x40	/* 3 pixels w/ encoded 2-bit deltas */
-#define	    DELTA2_SKIP		2	/* skip code for 2-bit deltas */
-#define	THUNDER_3BITDELTAS	0x80	/* 2 pixels w/ encoded 3-bit deltas */
-#define	    DELTA3_SKIP		4	/* skip code for 3-bit deltas */
-#define	THUNDER_RAW		0xc0	/* raw data encoded */
-
-static const int twobitdeltas[4] = { 0, 1, 0, -1 };
-static const int threebitdeltas[8] = { 0, 1, 2, 3, 0, -3, -2, -1 };
-
-#define	SETPIXEL(op, v) {                     \
-	lastpixel = (v) & 0xf;                \
-        if ( npixels < maxpixels )         \
-        {                                     \
-	  if (npixels++ & 1)                  \
-	    *op++ |= lastpixel;               \
-	  else                                \
-	    op[0] = (tidataval_t) (lastpixel << 4); \
-        }                                     \
-}
-
-static int
-ThunderSetupDecode(TIFF* tif)
-{
-	static const char module[] = "ThunderSetupDecode";
-
-        if( tif->tif_dir.td_bitspersample != 4 )
-        {
-                TIFFErrorExt(tif->tif_clientdata, module,
-                             "Wrong bitspersample value (%d), Thunder decoder only supports 4bits per sample.",
-                             (int) tif->tif_dir.td_bitspersample );
-                return 0;
-        }
-        
-
-	return (1);
-}
-
-static int
-ThunderDecode(TIFF* tif, tidata_t op, tsize_t maxpixels)
-{
-	register unsigned char *bp;
-	register tsize_t cc;
-	unsigned int lastpixel;
-	tsize_t npixels;
-
-	bp = (unsigned char *)tif->tif_rawcp;
-	cc = tif->tif_rawcc;
-	lastpixel = 0;
-	npixels = 0;
-	while (cc > 0 && npixels < maxpixels) {
-		int n, delta;
-
-		n = *bp++, cc--;
-		switch (n & THUNDER_CODE) {
-		case THUNDER_RUN:		/* pixel run */
-			/*
-			 * Replicate the last pixel n times,
-			 * where n is the lower-order 6 bits.
-			 */
-			if (npixels & 1) {
-				op[0] |= lastpixel;
-				lastpixel = *op++; npixels++; n--;
-			} else
-				lastpixel |= lastpixel << 4;
-			npixels += n;
-			if (npixels < maxpixels) {
-				for (; n > 0; n -= 2)
-					*op++ = (tidataval_t) lastpixel;
-			}
-			if (n == -1)
-				*--op &= 0xf0;
-			lastpixel &= 0xf;
-			break;
-		case THUNDER_2BITDELTAS:	/* 2-bit deltas */
-			if ((delta = ((n >> 4) & 3)) != DELTA2_SKIP)
-				SETPIXEL(op, lastpixel + twobitdeltas[delta]);
-			if ((delta = ((n >> 2) & 3)) != DELTA2_SKIP)
-				SETPIXEL(op, lastpixel + twobitdeltas[delta]);
-			if ((delta = (n & 3)) != DELTA2_SKIP)
-				SETPIXEL(op, lastpixel + twobitdeltas[delta]);
-			break;
-		case THUNDER_3BITDELTAS:	/* 3-bit deltas */
-			if ((delta = ((n >> 3) & 7)) != DELTA3_SKIP)
-				SETPIXEL(op, lastpixel + threebitdeltas[delta]);
-			if ((delta = (n & 7)) != DELTA3_SKIP)
-				SETPIXEL(op, lastpixel + threebitdeltas[delta]);
-			break;
-		case THUNDER_RAW:		/* raw data */
-			SETPIXEL(op, n);
-			break;
-		}
-	}
-	tif->tif_rawcp = (tidata_t) bp;
-	tif->tif_rawcc = cc;
-	if (npixels != maxpixels) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-		    "ThunderDecode: %s data at scanline %ld (%lu != %lu)",
-		    npixels < maxpixels ? "Not enough" : "Too much",
-		    (long) tif->tif_row, (long) npixels, (long) maxpixels);
-		return (0);
-	}
-	return (1);
-}
-
-static int
-ThunderDecodeRow(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s)
-{
-	tidata_t row = buf;
-	
-	(void) s;
-	while ((long)occ > 0) {
-		if (!ThunderDecode(tif, row, tif->tif_dir.td_imagewidth))
-			return (0);
-		occ -= tif->tif_scanlinesize;
-		row += tif->tif_scanlinesize;
-	}
-
-        return (1);
-}
-
-int
-TIFFInitThunderScan(TIFF* tif, int scheme)
-{
-	(void) scheme;
-	tif->tif_decoderow = ThunderDecodeRow;
-	tif->tif_decodestrip = ThunderDecodeRow;
-        tif->tif_setupdecode = ThunderSetupDecode;
-	return (1);
-}
-#endif /* THUNDER_SUPPORT */
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
-
diff --git a/Source/LibTIFF/tif_tile.c b/Source/LibTIFF/tif_tile.c
deleted file mode 100644
index 9e2d967..0000000
--- a/Source/LibTIFF/tif_tile.c
+++ /dev/null
@@ -1,280 +0,0 @@
-/* $Id: tif_tile.c,v 1.37 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1991-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library.
- *
- * Tiled Image Support Routines.
- */
-#include "tiffiop.h"
-
-static uint32
-summarize(TIFF* tif, size_t summand1, size_t summand2, const char* where)
-{
-	/*
-	 * XXX: We are using casting to uint32 here, because sizeof(size_t)
-	 * may be larger than sizeof(uint32) on 64-bit architectures.
-	 */
-	uint32	bytes = summand1 + summand2;
-
-	if (bytes - summand1 != summand2) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Integer overflow in %s", where);
-		bytes = 0;
-	}
-
-	return (bytes);
-}
-
-static uint32
-multiply(TIFF* tif, size_t nmemb, size_t elem_size, const char* where)
-{
-	uint32	bytes = nmemb * elem_size;
-
-	if (elem_size && bytes / elem_size != nmemb) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Integer overflow in %s", where);
-		bytes = 0;
-	}
-
-	return (bytes);
-}
-
-/*
- * Compute which tile an (x,y,z,s) value is in.
- */
-ttile_t
-TIFFComputeTile(TIFF* tif, uint32 x, uint32 y, uint32 z, tsample_t s)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-	uint32 dx = td->td_tilewidth;
-	uint32 dy = td->td_tilelength;
-	uint32 dz = td->td_tiledepth;
-	ttile_t tile = 1;
-
-	if (td->td_imagedepth == 1)
-		z = 0;
-	if (dx == (uint32) -1)
-		dx = td->td_imagewidth;
-	if (dy == (uint32) -1)
-		dy = td->td_imagelength;
-	if (dz == (uint32) -1)
-		dz = td->td_imagedepth;
-	if (dx != 0 && dy != 0 && dz != 0) {
-		uint32 xpt = TIFFhowmany(td->td_imagewidth, dx); 
-		uint32 ypt = TIFFhowmany(td->td_imagelength, dy); 
-		uint32 zpt = TIFFhowmany(td->td_imagedepth, dz); 
-
-		if (td->td_planarconfig == PLANARCONFIG_SEPARATE) 
-			tile = (xpt*ypt*zpt)*s +
-			     (xpt*ypt)*(z/dz) +
-			     xpt*(y/dy) +
-			     x/dx;
-		else
-			tile = (xpt*ypt)*(z/dz) + xpt*(y/dy) + x/dx;
-	}
-	return (tile);
-}
-
-/*
- * Check an (x,y,z,s) coordinate
- * against the image bounds.
- */
-int
-TIFFCheckTile(TIFF* tif, uint32 x, uint32 y, uint32 z, tsample_t s)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-
-	if (x >= td->td_imagewidth) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			     "%lu: Col out of range, max %lu",
-			     (unsigned long) x,
-			     (unsigned long) (td->td_imagewidth - 1));
-		return (0);
-	}
-	if (y >= td->td_imagelength) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			     "%lu: Row out of range, max %lu",
-			     (unsigned long) y,
-			     (unsigned long) (td->td_imagelength - 1));
-		return (0);
-	}
-	if (z >= td->td_imagedepth) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			     "%lu: Depth out of range, max %lu",
-			     (unsigned long) z,
-			     (unsigned long) (td->td_imagedepth - 1));
-		return (0);
-	}
-	if (td->td_planarconfig == PLANARCONFIG_SEPARATE &&
-	    s >= td->td_samplesperpixel) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			     "%lu: Sample out of range, max %lu",
-			     (unsigned long) s,
-			     (unsigned long) (td->td_samplesperpixel - 1));
-		return (0);
-	}
-	return (1);
-}
-
-/*
- * Compute how many tiles are in an image.
- */
-ttile_t
-TIFFNumberOfTiles(TIFF* tif)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-	uint32 dx = td->td_tilewidth;
-	uint32 dy = td->td_tilelength;
-	uint32 dz = td->td_tiledepth;
-	ttile_t ntiles;
-
-	if (dx == (uint32) -1)
-		dx = td->td_imagewidth;
-	if (dy == (uint32) -1)
-		dy = td->td_imagelength;
-	if (dz == (uint32) -1)
-		dz = td->td_imagedepth;
-	ntiles = (dx == 0 || dy == 0 || dz == 0) ? 0 :
-	    multiply(tif, multiply(tif, TIFFhowmany(td->td_imagewidth, dx),
-				   TIFFhowmany(td->td_imagelength, dy),
-				   "TIFFNumberOfTiles"),
-		     TIFFhowmany(td->td_imagedepth, dz), "TIFFNumberOfTiles");
-	if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
-		ntiles = multiply(tif, ntiles, td->td_samplesperpixel,
-				  "TIFFNumberOfTiles");
-	return (ntiles);
-}
-
-/*
- * Compute the # bytes in each row of a tile.
- */
-tsize_t
-TIFFTileRowSize(TIFF* tif)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-	tsize_t rowsize;
-	
-	if (td->td_tilelength == 0 || td->td_tilewidth == 0)
-		return ((tsize_t) 0);
-	rowsize = multiply(tif, td->td_bitspersample, td->td_tilewidth,
-			   "TIFFTileRowSize");
-	if (td->td_planarconfig == PLANARCONFIG_CONTIG)
-		rowsize = multiply(tif, rowsize, td->td_samplesperpixel,
-				   "TIFFTileRowSize");
-	return ((tsize_t) TIFFhowmany8(rowsize));
-}
-
-/*
- * Compute the # bytes in a variable length, row-aligned tile.
- */
-tsize_t
-TIFFVTileSize(TIFF* tif, uint32 nrows)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-	tsize_t tilesize;
-
-	if (td->td_tilelength == 0 || td->td_tilewidth == 0 ||
-	    td->td_tiledepth == 0)
-		return ((tsize_t) 0);
-	if (td->td_planarconfig == PLANARCONFIG_CONTIG &&
-	    td->td_photometric == PHOTOMETRIC_YCBCR &&
-	    !isUpSampled(tif)) {
-		/*
-		 * Packed YCbCr data contain one Cb+Cr for every
-		 * HorizontalSampling*VerticalSampling Y values.
-		 * Must also roundup width and height when calculating
-		 * since images that are not a multiple of the
-		 * horizontal/vertical subsampling area include
-		 * YCbCr data for the extended image.
-		 */
-		tsize_t w =
-		    TIFFroundup(td->td_tilewidth, td->td_ycbcrsubsampling[0]);
-		tsize_t rowsize =
-		    TIFFhowmany8(multiply(tif, w, td->td_bitspersample,
-					  "TIFFVTileSize"));
-		tsize_t samplingarea =
-		    td->td_ycbcrsubsampling[0]*td->td_ycbcrsubsampling[1];
-		if (samplingarea == 0) {
-			TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Invalid YCbCr subsampling");
-			return 0;
-		}
-		nrows = TIFFroundup(nrows, td->td_ycbcrsubsampling[1]);
-		/* NB: don't need TIFFhowmany here 'cuz everything is rounded */
-		tilesize = multiply(tif, nrows, rowsize, "TIFFVTileSize");
-		tilesize = summarize(tif, tilesize,
-				     multiply(tif, 2, tilesize / samplingarea,
-					      "TIFFVTileSize"),
-				     "TIFFVTileSize");
-	} else
-		tilesize = multiply(tif, nrows, TIFFTileRowSize(tif),
-				    "TIFFVTileSize");
-	return ((tsize_t)
-	    multiply(tif, tilesize, td->td_tiledepth, "TIFFVTileSize"));
-}
-
-/*
- * Compute the # bytes in a row-aligned tile.
- */
-tsize_t
-TIFFTileSize(TIFF* tif)
-{
-	return (TIFFVTileSize(tif, tif->tif_dir.td_tilelength));
-}
-
-/*
- * Compute a default tile size based on the image
- * characteristics and a requested value.  If a
- * request is <1 then we choose a size according
- * to certain heuristics.
- */
-void
-TIFFDefaultTileSize(TIFF* tif, uint32* tw, uint32* th)
-{
-	(*tif->tif_deftilesize)(tif, tw, th);
-}
-
-void
-_TIFFDefaultTileSize(TIFF* tif, uint32* tw, uint32* th)
-{
-	(void) tif;
-	if (*(int32*) tw < 1)
-		*tw = 256;
-	if (*(int32*) th < 1)
-		*th = 256;
-	/* roundup to a multiple of 16 per the spec */
-	if (*tw & 0xf)
-		*tw = TIFFroundup(*tw, 16);
-	if (*th & 0xf)
-		*th = TIFFroundup(*th, 16);
-}
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_unix.c b/Source/LibTIFF/tif_unix.c
deleted file mode 100644
index f693df7..0000000
--- a/Source/LibTIFF/tif_unix.c
+++ /dev/null
@@ -1,300 +0,0 @@
-/* $Id: tif_unix.c,v 1.35 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library UNIX-specific Routines. These are should also work with the
- * Windows Common RunTime Library.
- */
-#include "tif_config.h"
-
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-
-#include <stdarg.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
-#ifdef HAVE_FCNTL_H
-# include <fcntl.h>
-#endif
-
-#ifdef HAVE_IO_H
-# include <io.h>
-#endif
-
-#include "tiffiop.h"
-
-static tsize_t
-_tiffReadProc(thandle_t fd, tdata_t buf, tsize_t size)
-{
-	return ((tsize_t) read((int) fd, buf, (size_t) size));
-}
-
-static tsize_t
-_tiffWriteProc(thandle_t fd, tdata_t buf, tsize_t size)
-{
-	return ((tsize_t) write((int) fd, buf, (size_t) size));
-}
-
-static toff_t
-_tiffSeekProc(thandle_t fd, toff_t off, int whence)
-{
-	return ((toff_t) lseek((int) fd, (off_t) off, whence));
-}
-
-static int
-_tiffCloseProc(thandle_t fd)
-{
-	return (close((int) fd));
-}
-
-
-static toff_t
-_tiffSizeProc(thandle_t fd)
-{
-#ifdef _AM29K
-	long fsize;
-	return ((fsize = lseek((int) fd, 0, SEEK_END)) < 0 ? 0 : fsize);
-#else
-	struct stat sb;
-	return (toff_t) (fstat((int) fd, &sb) < 0 ? 0 : sb.st_size);
-#endif
-}
-
-#ifdef HAVE_MMAP
-#include <sys/mman.h>
-
-static int
-_tiffMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize)
-{
-	toff_t size = _tiffSizeProc(fd);
-	if (size != (toff_t) -1) {
-		*pbase = (tdata_t)
-		    mmap(0, size, PROT_READ, MAP_SHARED, (int) fd, 0);
-		if (*pbase != (tdata_t) -1) {
-			*psize = size;
-			return (1);
-		}
-	}
-	return (0);
-}
-
-static void
-_tiffUnmapProc(thandle_t fd, tdata_t base, toff_t size)
-{
-	(void) fd;
-	(void) munmap(base, (off_t) size);
-}
-#else /* !HAVE_MMAP */
-static int
-_tiffMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize)
-{
-	(void) fd; (void) pbase; (void) psize;
-	return (0);
-}
-
-static void
-_tiffUnmapProc(thandle_t fd, tdata_t base, toff_t size)
-{
-	(void) fd; (void) base; (void) size;
-}
-#endif /* !HAVE_MMAP */
-
-/*
- * Open a TIFF file descriptor for read/writing.
- */
-TIFF*
-TIFFFdOpen(int fd, const char* name, const char* mode)
-{
-	TIFF* tif;
-
-	tif = TIFFClientOpen(name, mode,
-	    (thandle_t) fd,
-	    _tiffReadProc, _tiffWriteProc,
-	    _tiffSeekProc, _tiffCloseProc, _tiffSizeProc,
-	    _tiffMapProc, _tiffUnmapProc);
-	if (tif)
-		tif->tif_fd = fd;
-	return (tif);
-}
-
-/*
- * Open a TIFF file for read/writing.
- */
-TIFF*
-TIFFOpen(const char* name, const char* mode)
-{
-	static const char module[] = "TIFFOpen";
-	int m, fd;
-        TIFF* tif;
-
-	m = _TIFFgetMode(mode, module);
-	if (m == -1)
-		return ((TIFF*)0);
-
-/* for cygwin and mingw */        
-#ifdef O_BINARY
-        m |= O_BINARY;
-#endif        
-        
-#ifdef _AM29K
-	fd = open(name, m);
-#else
-	fd = open(name, m, 0666);
-#endif
-	if (fd < 0) {
-		TIFFErrorExt(0, module, "%s: Cannot open", name);
-		return ((TIFF *)0);
-	}
-
-	tif = TIFFFdOpen((int)fd, name, mode);
-	if(!tif)
-		close(fd);
-	return tif;
-}
-
-#ifdef __WIN32__
-#include <windows.h>
-/*
- * Open a TIFF file with a Unicode filename, for read/writing.
- */
-TIFF*
-TIFFOpenW(const wchar_t* name, const char* mode)
-{
-	static const char module[] = "TIFFOpenW";
-	int m, fd;
-	int mbsize;
-	char *mbname;
-	TIFF* tif;
-
-	m = _TIFFgetMode(mode, module);
-	if (m == -1)
-		return ((TIFF*)0);
-
-/* for cygwin and mingw */        
-#ifdef O_BINARY
-        m |= O_BINARY;
-#endif        
-        
-	fd = _wopen(name, m, 0666);
-	if (fd < 0) {
-		TIFFErrorExt(0, module, "%s: Cannot open", name);
-		return ((TIFF *)0);
-	}
-
-	mbname = NULL;
-	mbsize = WideCharToMultiByte(CP_ACP, 0, name, -1, NULL, 0, NULL, NULL);
-	if (mbsize > 0) {
-		mbname = _TIFFmalloc(mbsize);
-		if (!mbname) {
-			TIFFErrorExt(0, module,
-			"Can't allocate space for filename conversion buffer");
-			return ((TIFF*)0);
-		}
-
-		WideCharToMultiByte(CP_ACP, 0, name, -1, mbname, mbsize,
-				    NULL, NULL);
-	}
-
-	tif = TIFFFdOpen((int)fd, (mbname != NULL) ? mbname : "<unknown>",
-			 mode);
-	
-	_TIFFfree(mbname);
-	
-	if(!tif)
-		close(fd);
-	return tif;
-}
-#endif
-
-void*
-_TIFFmalloc(tsize_t s)
-{
-	return (malloc((size_t) s));
-}
-
-void
-_TIFFfree(tdata_t p)
-{
-	free(p);
-}
-
-void*
-_TIFFrealloc(tdata_t p, tsize_t s)
-{
-	return (realloc(p, (size_t) s));
-}
-
-void
-_TIFFmemset(tdata_t p, int v, tsize_t c)
-{
-	memset(p, v, (size_t) c);
-}
-
-void
-_TIFFmemcpy(tdata_t d, const tdata_t s, tsize_t c)
-{
-	memcpy(d, s, (size_t) c);
-}
-
-int
-_TIFFmemcmp(const tdata_t p1, const tdata_t p2, tsize_t c)
-{
-	return (memcmp(p1, p2, (size_t) c));
-}
-
-static void
-unixWarningHandler(const char* module, const char* fmt, va_list ap)
-{
-	if (module != NULL)
-		fprintf(stderr, "%s: ", module);
-	fprintf(stderr, "Warning, ");
-	vfprintf(stderr, fmt, ap);
-	fprintf(stderr, ".\n");
-}
-TIFFErrorHandler _TIFFwarningHandler = unixWarningHandler;
-
-static void
-unixErrorHandler(const char* module, const char* fmt, va_list ap)
-{
-	if (module != NULL)
-		fprintf(stderr, "%s: ", module);
-	vfprintf(stderr, fmt, ap);
-	fprintf(stderr, ".\n");
-}
-TIFFErrorHandler _TIFFerrorHandler = unixErrorHandler;
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_version.c b/Source/LibTIFF/tif_version.c
deleted file mode 100644
index 44c00a3..0000000
--- a/Source/LibTIFF/tif_version.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/* $Header: /cvsroot/freeimage/FreeImage/Source/LibTIFF/tif_version.c,v 1.37 2011/04/10 17:14:09 drolon Exp $ */
-/*
- * Copyright (c) 1992-1997 Sam Leffler
- * Copyright (c) 1992-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-#include "tiffiop.h"
-
-static const char TIFFVersion[] = TIFFLIB_VERSION_STR;
-
-const char*
-TIFFGetVersion(void)
-{
-	return (TIFFVersion);
-}
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_vms.c b/Source/LibTIFF/tif_vms.c
deleted file mode 100644
index 553f507..0000000
--- a/Source/LibTIFF/tif_vms.c
+++ /dev/null
@@ -1,595 +0,0 @@
-/* $Id: tif_vms.c,v 1.21 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library VMS-specific Routines.
- */
-
-#include <stdlib.h>
-#include <unixio.h>
-#include "tiffiop.h"
-#if !HAVE_IEEEFP
-#include <math.h>
-#endif
-
-#ifdef VAXC
-#define	NOSHARE	noshare
-#else
-#define	NOSHARE
-#endif
-
-#ifdef __alpha
-/* Dummy entry point for backwards compatibility */
-void TIFFModeCCITTFax3(void){}
-#endif
-
-static tsize_t
-_tiffReadProc(thandle_t fd, tdata_t buf, tsize_t size)
-{
-	return (read((int) fd, buf, size));
-}
-
-static tsize_t
-_tiffWriteProc(thandle_t fd, tdata_t buf, tsize_t size)
-{
-	return (write((int) fd, buf, size));
-}
-
-static toff_t
-_tiffSeekProc(thandle_t fd, toff_t off, int whence)
-{
-	return ((toff_t) lseek((int) fd, (off_t) off, whence));
-}
-
-static int
-_tiffCloseProc(thandle_t fd)
-{
-	return (close((int) fd));
-}
-
-#include <sys/stat.h>
-
-static toff_t
-_tiffSizeProc(thandle_t fd)
-{
-	struct stat sb;
-	return (toff_t) (fstat((int) fd, &sb) < 0 ? 0 : sb.st_size);
-}
-
-#ifdef HAVE_MMAP
-#include <starlet.h>
-#include <fab.h>
-#include <secdef.h>
-
-/*
- * Table for storing information on current open sections. 
- * (Should really be a linked list)
- */
-#define MAX_MAPPED 100
-static int no_mapped = 0;
-static struct {
-	char *base;
-	char *top;
-	unsigned short channel;
-} map_table[MAX_MAPPED];
-
-/* 
- * This routine maps a file into a private section. Note that this 
- * method of accessing a file is by far the fastest under VMS.
- * The routine may fail (i.e. return 0) for several reasons, for
- * example:
- * - There is no more room for storing the info on sections.
- * - The process is out of open file quota, channels, ...
- * - fd does not describe an opened file.
- * - The file is already opened for write access by this process
- *   or another process
- * - There is no free "hole" in virtual memory that fits the
- *   size of the file
- */
-static int
-_tiffMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize)
-{
-	char name[256];
-	struct FAB fab;
-	unsigned short channel;
-	char *inadr[2], *retadr[2];
-	unsigned long status;
-	long size;
-	
-	if (no_mapped >= MAX_MAPPED)
-		return(0);
-	/*
-	 * We cannot use a file descriptor, we
-	 * must open the file once more.
-	 */
-	if (getname((int)fd, name, 1) == NULL)
-		return(0);
-	/* prepare the FAB for a user file open */
-	fab = cc$rms_fab;
-	fab.fab$l_fop |= FAB$V_UFO;
-	fab.fab$b_fac = FAB$M_GET;
-	fab.fab$b_shr = FAB$M_SHRGET;
-	fab.fab$l_fna = name;
-	fab.fab$b_fns = strlen(name);
-	status = sys$open(&fab);	/* open file & get channel number */
-	if ((status&1) == 0)
-		return(0);
-	channel = (unsigned short)fab.fab$l_stv;
-	inadr[0] = inadr[1] = (char *)0; /* just an address in P0 space */
-	/*
-	 * Map the blocks of the file up to
-	 * the EOF block into virtual memory.
-	 */
-	size = _tiffSizeProc(fd);
-	status = sys$crmpsc(inadr, retadr, 0, SEC$M_EXPREG, 0,0,0, channel,
-		TIFFhowmany(size,512), 0,0,0);
-	if ((status&1) == 0){
-		sys$dassgn(channel);
-		return(0);
-	}
-	*pbase = (tdata_t) retadr[0];	/* starting virtual address */
-	/*
-	 * Use the size of the file up to the
-	 * EOF mark for UNIX compatibility.
-	 */
-	*psize = (toff_t) size;
-	/* Record the section in the table */
-	map_table[no_mapped].base = retadr[0];
-	map_table[no_mapped].top = retadr[1];
-	map_table[no_mapped].channel = channel;
-	no_mapped++;
-
-        return(1);
-}
-
-/*
- * This routine unmaps a section from the virtual address space of 
- * the process, but only if the base was the one returned from a
- * call to TIFFMapFileContents.
- */
-static void
-_tiffUnmapProc(thandle_t fd, tdata_t base, toff_t size)
-{
-	char *inadr[2];
-	int i, j;
-	
-	/* Find the section in the table */
-	for (i = 0;i < no_mapped; i++) {
-		if (map_table[i].base == (char *) base) {
-			/* Unmap the section */
-			inadr[0] = (char *) base;
-			inadr[1] = map_table[i].top;
-			sys$deltva(inadr, 0, 0);
-			sys$dassgn(map_table[i].channel);
-			/* Remove this section from the list */
-			for (j = i+1; j < no_mapped; j++)
-				map_table[j-1] = map_table[j];
-			no_mapped--;
-			return;
-		}
-	}
-}
-#else /* !HAVE_MMAP */
-static int
-_tiffMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize)
-{
-	return (0);
-}
-
-static void
-_tiffUnmapProc(thandle_t fd, tdata_t base, toff_t size)
-{
-}
-#endif /* !HAVE_MMAP */
-
-/*
- * Open a TIFF file descriptor for read/writing.
- */
-TIFF*
-TIFFFdOpen(int fd, const char* name, const char* mode)
-{
-	TIFF* tif;
-
-	tif = TIFFClientOpen(name, mode,
-	    (thandle_t) fd,
-	    _tiffReadProc, _tiffWriteProc, _tiffSeekProc, _tiffCloseProc,
-	    _tiffSizeProc, _tiffMapProc, _tiffUnmapProc);
-	if (tif)
-		tif->tif_fd = fd;
-	return (tif);
-}
-
-/*
- * Open a TIFF file for read/writing.
- */
-TIFF*
-TIFFOpen(const char* name, const char* mode)
-{
-	static const char module[] = "TIFFOpen";
-	int m, fd;
-
-	m = _TIFFgetMode(mode, module);
-	if (m == -1)
-		return ((TIFF*)0);
-        if (m&O_TRUNC){
-                /*
-		 * There is a bug in open in VAXC. If you use
-		 * open w/ m=O_RDWR|O_CREAT|O_TRUNC the
-		 * wrong thing happens.  On the other hand
-		 * creat does the right thing.
-                 */
-                fd = creat((char *) /* bug in stdio.h */ name, 0666,
-		    "alq = 128", "deq = 64", "mbc = 32",
-		    "fop = tef");
-	} else if (m&O_RDWR) {
-		fd = open(name, m, 0666,
-		    "deq = 64", "mbc = 32", "fop = tef", "ctx = stm");
-	} else
-		fd = open(name, m, 0666, "mbc = 32", "ctx = stm");
-	if (fd < 0) {
-		TIFFErrorExt(0, module, "%s: Cannot open", name);
-		return ((TIFF*)0);
-	}
-	return (TIFFFdOpen(fd, name, mode));
-}
-
-tdata_t
-_TIFFmalloc(tsize_t s)
-{
-	return (malloc((size_t) s));
-}
-
-void
-_TIFFfree(tdata_t p)
-{
-	free(p);
-}
-
-tdata_t
-_TIFFrealloc(tdata_t p, tsize_t s)
-{
-	return (realloc(p, (size_t) s));
-}
-
-void
-_TIFFmemset(tdata_t p, int v, tsize_t c)
-{
-	memset(p, v, (size_t) c);
-}
-
-void
-_TIFFmemcpy(tdata_t d, const tdata_t s, tsize_t c)
-{
-	memcpy(d, s, (size_t) c);
-}
-
-int
-_TIFFmemcmp(const tdata_t p1, const tdata_t p2, tsize_t c)
-{
-	return (memcmp(p1, p2, (size_t) c));
-}
-
-/*
- * On the VAX, we need to make those global, writable pointers
- * non-shareable, otherwise they would be made shareable by default.
- * On the AXP, this brain damage has been corrected. 
- * 
- * I (Karsten Spang, krs at kampsax.dk) have dug around in the GCC
- * manual and the GAS code and have come up with the following
- * construct, but I don't have GCC on my VAX, so it is untested.
- * Please tell me if it does not work.
- */
-
-static void
-vmsWarningHandler(const char* module, const char* fmt, va_list ap)
-{
-	if (module != NULL)
-		fprintf(stderr, "%s: ", module);
-	fprintf(stderr, "Warning, ");
-	vfprintf(stderr, fmt, ap);
-	fprintf(stderr, ".\n");
-}
-
-NOSHARE TIFFErrorHandler _TIFFwarningHandler = vmsWarningHandler
-#if defined(VAX) && defined(__GNUC__)
-asm("_$$PsectAttributes_NOSHR$$_TIFFwarningHandler")
-#endif
-;
-
-static void
-vmsErrorHandler(const char* module, const char* fmt, va_list ap)
-{
-	if (module != NULL)
-		fprintf(stderr, "%s: ", module);
-	vfprintf(stderr, fmt, ap);
-	fprintf(stderr, ".\n");
-}
-
-NOSHARE TIFFErrorHandler _TIFFerrorHandler = vmsErrorHandler
-#if defined(VAX) && defined(__GNUC__)
-asm("_$$PsectAttributes_NOSHR$$_TIFFerrorHandler")
-#endif
-;
-
-
-#if !HAVE_IEEEFP
-/* IEEE floting point handling */
-
-typedef	struct ieeedouble {
-	unsigned long	mant2;          /* fix NDR: full 8-byte swap */
-	unsigned long	mant	: 20,
-		        exp	: 11,
-		        sign	: 1;
-} ieeedouble;
-typedef	struct ieeefloat {
-	unsigned long   mant	: 23,
-		        exp	: 8,
-		        sign	: 1;
-} ieeefloat;
-
-/* 
- * NB: These are D_FLOAT's, not G_FLOAT's. A G_FLOAT is
- *  simply a reverse-IEEE float/double.
- */
-
-typedef	struct {
-	unsigned long	mant1	: 7,
-		        exp	: 8,
-		        sign	: 1,
-		        mant2	: 16,
-		        mant3   : 16,
-		        mant4   : 16;
-} nativedouble;
-typedef	struct {
-	unsigned long	mant1	: 7,
-		        exp	: 8,
-		        sign	: 1,
-		        mant2	: 16;
-} nativefloat;
-
-typedef	union {
-	ieeedouble	ieee;
-	nativedouble	native;
-	char		b[8];
-	uint32		l[2];
-	double		d;
-} double_t;
-
-typedef	union {
-	ieeefloat	ieee;
-	nativefloat	native;
-	char		b[4];
-	uint32		l;
-	float		f;
-} float_t;
-
-#if defined(VAXC) || defined(DECC)
-#pragma inline(ieeetod,dtoieee)
-#endif
-
-/*
- * Convert an IEEE double precision number to native double precision.
- * The source is contained in two longwords, the second holding the sign,
- * exponent and the higher order bits of the mantissa, and the first
- * holding the rest of the mantissa as follows:
- * (Note: It is assumed that the number has been eight-byte swapped to
- * LSB first.)
- * 
- * First longword:
- *	32 least significant bits of mantissa
- * Second longword:
- *	0-19:	20 most significant bits of mantissa
- *	20-30:	exponent
- *	31:	sign
- * The exponent is stored as excess 1023.
- * The most significant bit of the mantissa is implied 1, and not stored.
- * If the exponent and mantissa are zero, the number is zero.
- * If the exponent is 0 (i.e. -1023) and the mantissa is non-zero, it is an
- * unnormalized number with the most significant bit NOT implied.
- * If the exponent is 2047, the number is invalid, in case the mantissa is zero,
- * this means overflow (+/- depending of the sign bit), otherwise
- * it simply means invalid number.
- * 
- * If the number is too large for the machine or was specified as overflow, 
- * +/-HUGE_VAL is returned.
- */
-INLINE static void
-ieeetod(double *dp)
-{
-	double_t source;
-	long sign,exp,mant;
-	double dmant;
-
-	source.ieee = ((double_t*)dp)->ieee;
-	sign = source.ieee.sign;
-	exp = source.ieee.exp;
-	mant = source.ieee.mant;
-
-	if (exp == 2047) {
-		if (mant)			/* Not a Number (NAN) */
-			*dp = HUGE_VAL;
-		else				/* +/- infinity */
-			*dp = (sign ? -HUGE_VAL : HUGE_VAL);
-		return;
-	}
-	if (!exp) {
-		if (!(mant || source.ieee.mant2)) {	/* zero */
-			*dp=0;
-			return;
-		} else {			/* Unnormalized number */
-			/* NB: not -1023, the 1 bit is not implied */
-			exp= -1022;
-		}
-	} else {
-		mant |= 1<<20;
-		exp -= 1023;
-	}
-	dmant = (((double) mant) +
-		((double) source.ieee.mant2) / (((double) (1<<16)) *
-		((double) (1<<16)))) / (double) (1<<20);
-	dmant = ldexp(dmant, exp);
-	if (sign)
-		dmant= -dmant;
-	*dp = dmant;
-}
-
-INLINE static void
-dtoieee(double *dp)
-{
-	double_t num;
-	double x;
-	int exp;
-
-	num.d = *dp;
-	if (!num.d) {			/* Zero is just binary all zeros */
-		num.l[0] = num.l[1] = 0;
-		return;
-	}
-
-	if (num.d < 0) {		/* Sign is encoded separately */
-		num.d = -num.d;
-		num.ieee.sign = 1;
-	} else {
-		num.ieee.sign = 0;
-	}
-
-	/* Now separate the absolute value into mantissa and exponent */
-	x = frexp(num.d, &exp);
-
-	/*
-	 * Handle cases where the value is outside the
-	 * range for IEEE floating point numbers. 
-	 * (Overflow cannot happen on a VAX, but underflow
-	 * can happen for G float.)
-	 */
-	if (exp < -1022) {		/* Unnormalized number */
-		x = ldexp(x, -1023-exp);
-		exp = 0;
-	} else if (exp > 1023) {	/* +/- infinity */
-		x = 0;
-		exp = 2047;
-	} else {			/* Get rid of most significant bit */
-		x *= 2;
-		x -= 1;
-		exp += 1022; /* fix NDR: 1.0 -> x=0.5, exp=1 -> ieee.exp = 1023 */
-	}
-	num.ieee.exp = exp;
-
-	x *= (double) (1<<20);
-	num.ieee.mant = (long) x;
-	x -= (double) num.ieee.mant;
-	num.ieee.mant2 = (long) (x*((double) (1<<16)*(double) (1<<16)));
-
-	if (!(num.ieee.mant || num.ieee.exp || num.ieee.mant2)) {
-		/* Avoid negative zero */
-		num.ieee.sign = 0;
-	}
-	((double_t*)dp)->ieee = num.ieee;
-}
-
-/*
- * Beware, these do not handle over/under-flow
- * during conversion from ieee to native format.
- */
-#define	NATIVE2IEEEFLOAT(fp) { \
-    float_t t; \
-    if (t.ieee.exp = (fp)->native.exp) \
-	t.ieee.exp += -129 + 127; \
-    t.ieee.sign = (fp)->native.sign; \
-    t.ieee.mant = ((fp)->native.mant1<<16)|(fp)->native.mant2; \
-    *(fp) = t; \
-}
-#define	IEEEFLOAT2NATIVE(fp) { \
-    float_t t; int v = (fp)->ieee.exp; \
-    if (v) v += -127 + 129;		/* alter bias of exponent */\
-    t.native.exp = v;			/* implicit truncation of exponent */\
-    t.native.sign = (fp)->ieee.sign; \
-    v = (fp)->ieee.mant; \
-    t.native.mant1 = v >> 16; \
-    t.native.mant2 = v;\
-    *(fp) = t; \
-}
-
-#define IEEEDOUBLE2NATIVE(dp) ieeetod(dp)
-
-#define NATIVE2IEEEDOUBLE(dp) dtoieee(dp)
-
-
-/*
- * These unions are used during floating point
- * conversions.  The above macros define the
- * conversion operations.
- */
-void
-TIFFCvtIEEEFloatToNative(TIFF* tif, u_int n, float* f)
-{
-	float_t* fp = (float_t*) f;
-
-	while (n-- > 0) {
-		IEEEFLOAT2NATIVE(fp);
-		fp++;
-	}
-}
-
-void
-TIFFCvtNativeToIEEEFloat(TIFF* tif, u_int n, float* f)
-{
-	float_t* fp = (float_t*) f;
-
-	while (n-- > 0) {
-		NATIVE2IEEEFLOAT(fp);
-		fp++;
-	}
-}
-void
-TIFFCvtIEEEDoubleToNative(TIFF* tif, u_int n, double* f)
-{
-	double_t* fp = (double_t*) f;
-
-	while (n-- > 0) {
-		IEEEDOUBLE2NATIVE(fp);
-		fp++;
-	}
-}
-
-void
-TIFFCvtNativeToIEEEDouble(TIFF* tif, u_int n, double* f)
-{
-	double_t* fp = (double_t*) f;
-
-	while (n-- > 0) {
-		NATIVE2IEEEDOUBLE(fp);
-		fp++;
-	}
-}
-#endif
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_warning.c b/Source/LibTIFF/tif_warning.c
deleted file mode 100644
index f7b6e44..0000000
--- a/Source/LibTIFF/tif_warning.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/* $Header: /cvsroot/freeimage/FreeImage/Source/LibTIFF/tif_warning.c,v 1.37 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library.
- */
-#include "tiffiop.h"
-
-TIFFErrorHandlerExt _TIFFwarningHandlerExt = NULL;
-
-TIFFErrorHandler
-TIFFSetWarningHandler(TIFFErrorHandler handler)
-{
-	TIFFErrorHandler prev = _TIFFwarningHandler;
-	_TIFFwarningHandler = handler;
-	return (prev);
-}
-
-TIFFErrorHandlerExt
-TIFFSetWarningHandlerExt(TIFFErrorHandlerExt handler)
-{
-	TIFFErrorHandlerExt prev = _TIFFwarningHandlerExt;
-	_TIFFwarningHandlerExt = handler;
-	return (prev);
-}
-
-void
-TIFFWarning(const char* module, const char* fmt, ...)
-{
-	va_list ap;
-	va_start(ap, fmt);
-	if (_TIFFwarningHandler)
-		(*_TIFFwarningHandler)(module, fmt, ap);
-	if (_TIFFwarningHandlerExt)
-		(*_TIFFwarningHandlerExt)(0, module, fmt, ap);
-	va_end(ap);
-}
-
-void
-TIFFWarningExt(thandle_t fd, const char* module, const char* fmt, ...)
-{
-	va_list ap;
-	va_start(ap, fmt);
-	if (_TIFFwarningHandler)
-		(*_TIFFwarningHandler)(module, fmt, ap);
-	if (_TIFFwarningHandlerExt)
-		(*_TIFFwarningHandlerExt)(fd, module, fmt, ap);
-	va_end(ap);
-}
-
-
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_win3.c b/Source/LibTIFF/tif_win3.c
deleted file mode 100644
index aa21e3a..0000000
--- a/Source/LibTIFF/tif_win3.c
+++ /dev/null
@@ -1,232 +0,0 @@
-/* $Header: /cvsroot/freeimage/FreeImage/Source/LibTIFF/tif_win3.c,v 1.35 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library Windows 3.x-specific Routines.
- */
-#include "tiffiop.h"
-#if defined(__WATCOMC__) || defined(__BORLANDC__) || defined(_MSC_VER)
-#include <io.h>		/* for open, close, etc. function prototypes */
-#endif
-
-#include <windows.h>
-#include <windowsx.h>
-#include <memory.h>
-
-static tsize_t 
-_tiffReadProc(thandle_t fd, tdata_t buf, tsize_t size)
-{
-	return (_hread(fd, buf, size));
-}
-
-static tsize_t
-_tiffWriteProc(thandle_t fd, tdata_t buf, tsize_t size)
-{
-	return (_hwrite(fd, buf, size));
-}
-
-static toff_t
-_tiffSeekProc(thandle_t fd, toff_t off, int whence)
-{
-	return (_llseek(fd, (off_t) off, whence));
-}
-
-static int
-_tiffCloseProc(thandle_t fd)
-{
-	return (_lclose(fd));
-}
-
-#include <sys/stat.h>
-
-static toff_t
-_tiffSizeProc(thandle_t fd)
-{
-	struct stat sb;
-	return (fstat((int) fd, &sb) < 0 ? 0 : sb.st_size);
-}
-
-static int
-_tiffMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize)
-{
-	return (0);
-}
-
-static void
-_tiffUnmapProc(thandle_t fd, tdata_t base, toff_t size)
-{
-}
-
-/*
- * Open a TIFF file descriptor for read/writing.
- */
-TIFF*
-TIFFFdOpen(int fd, const char* name, const char* mode)
-{
-	TIFF* tif;
-
-	tif = TIFFClientOpen(name, mode,
-	    (thandle_t) fd,
-	    _tiffReadProc, _tiffWriteProc, _tiffSeekProc, _tiffCloseProc,
-	    _tiffSizeProc, _tiffMapProc, _tiffUnmapProc);
-	if (tif)
-		tif->tif_fd = fd;
-	return (tif);
-}
-
-/*
- * Open a TIFF file for read/writing.
- */
-TIFF*
-TIFFOpen(const char* name, const char* mode)
-{
-	static const char module[] = "TIFFOpen";
-	int m, fd;
-	OFSTRUCT of;
-	int mm = 0;
-
-	m = _TIFFgetMode(mode, module);
-	if (m == -1)
-		return ((TIFF*)0);
-	if (m & O_CREAT) {
-		if ((m & O_TRUNC) || OpenFile(name, &of, OF_EXIST) != HFILE_ERROR)
-			mm |= OF_CREATE;
-	}
-	if (m & O_WRONLY)
-		mm |= OF_WRITE;
-	if (m & O_RDWR)
-		mm |= OF_READWRITE;
-	fd = OpenFile(name, &of, mm);
-	if (fd < 0) {
-		TIFFErrorExt(0, module, "%s: Cannot open", name);
-		return ((TIFF*)0);
-	}
-	return (TIFFFdOpen(fd, name, mode));
-}
-
-tdata_t
-_TIFFmalloc(tsize_t s)
-{
-	return (tdata_t) GlobalAllocPtr(GHND, (DWORD) s);
-}
-
-void
-_TIFFfree(tdata_t p)
-{
-	GlobalFreePtr(p);
-}
-
-tdata_t
-_TIFFrealloc(tdata_t p, tsize_t s)
-{
-	return (tdata_t) GlobalReAllocPtr(p, (DWORD) s, GHND);
-}
-
-void
-_TIFFmemset(tdata_t p, int v, tsize_t c)
-{
-	char* pp = (char*) p;
-
-	while (c > 0) {
-		tsize_t chunk = 0x10000 - ((uint32) pp & 0xffff);/* What's left in segment */
-		if (chunk > 0xff00)				/* No more than 0xff00 */
-			chunk = 0xff00;
-		if (chunk > c)					/* No more than needed */
-			chunk = c;
-		memset(pp, v, chunk);
-		pp = (char*) (chunk + (char huge*) pp);
-		c -= chunk;
-	}
-}
-
-void
-_TIFFmemcpy(tdata_t d, const tdata_t s, tsize_t c)
-{
-	if (c > 0xFFFF)
-		hmemcpy((void _huge*) d, (void _huge*) s, c);
-	else
-		(void) memcpy(d, s, (size_t) c);
-}
-
-int
-_TIFFmemcmp(const tdata_t d, const tdata_t s, tsize_t c)
-{
-	char* dd = (char*) d;
-	char* ss = (char*) s;
-	tsize_t chunks, chunkd, chunk;
-	int result;
-
-	while (c > 0) {
-		chunks = 0x10000 - ((uint32) ss & 0xffff);	/* What's left in segment */
-		chunkd = 0x10000 - ((uint32) dd & 0xffff);	/* What's left in segment */
-		chunk = c;					/* Get the largest of     */
-		if (chunk > chunks)				/*   c, chunks, chunkd,   */
-			chunk = chunks;				/*   0xff00               */
-		if (chunk > chunkd)
-			chunk = chunkd;
-		if (chunk > 0xff00)
-			chunk = 0xff00;
-		result = memcmp(dd, ss, chunk);
-		if (result != 0)
-			return (result);
-		dd = (char*) (chunk + (char huge*) dd);
-		ss = (char*) (chunk + (char huge*) ss);
-		c -= chunk;
-	}
-	return (0);
-}
-
-static void
-win3WarningHandler(const char* module, const char* fmt, va_list ap)
-{
-	char e[512] = { '\0' };
-	if (module != NULL)
-		strcat(strcpy(e, module), ":");
-	vsprintf(e+strlen(e), fmt, ap);
-	strcat(e, ".");
-	MessageBox(GetActiveWindow(), e, "LibTIFF Warning",
-	    MB_OK|MB_ICONEXCLAMATION);
-}
-TIFFErrorHandler _TIFFwarningHandler = win3WarningHandler;
-
-static void
-win3ErrorHandler(const char* module, const char* fmt, va_list ap)
-{
-	char e[512] = { '\0' };
-	if (module != NULL)
-		strcat(strcpy(e, module), ":");
-	vsprintf(e+strlen(e), fmt, ap);
-	strcat(e, ".");
-	MessageBox(GetActiveWindow(), e, "LibTIFF Error", MB_OK|MB_ICONSTOP);
-}
-TIFFErrorHandler _TIFFerrorHandler = win3ErrorHandler;
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_win32.c b/Source/LibTIFF/tif_win32.c
deleted file mode 100644
index ddfd778..0000000
--- a/Source/LibTIFF/tif_win32.c
+++ /dev/null
@@ -1,408 +0,0 @@
-/* $Id: tif_win32.c,v 1.35 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library Win32-specific Routines.  Adapted from tif_unix.c 4/5/95 by
- * Scott Wagner (wagner at itek.com), Itek Graphix, Rochester, NY USA
- */
-#include "tiffiop.h"
-
-#include <windows.h>
-
-static tsize_t
-_tiffReadProc(thandle_t fd, tdata_t buf, tsize_t size)
-{
-	DWORD dwSizeRead;
-	if (!ReadFile(fd, buf, size, &dwSizeRead, NULL))
-		return(0);
-	return ((tsize_t) dwSizeRead);
-}
-
-static tsize_t
-_tiffWriteProc(thandle_t fd, tdata_t buf, tsize_t size)
-{
-	DWORD dwSizeWritten;
-	if (!WriteFile(fd, buf, size, &dwSizeWritten, NULL))
-		return(0);
-	return ((tsize_t) dwSizeWritten);
-}
-
-static toff_t
-_tiffSeekProc(thandle_t fd, toff_t off, int whence)
-{
-        ULARGE_INTEGER li;
-	DWORD dwMoveMethod;
-
-	li.QuadPart = off;
-        
-	switch(whence)
-	{
-	case SEEK_SET:
-		dwMoveMethod = FILE_BEGIN;
-		break;
-	case SEEK_CUR:
-		dwMoveMethod = FILE_CURRENT;
-		break;
-	case SEEK_END:
-		dwMoveMethod = FILE_END;
-		break;
-	default:
-		dwMoveMethod = FILE_BEGIN;
-		break;
-	}
-	return ((toff_t)SetFilePointer(fd, (LONG) li.LowPart,
-				       (PLONG)&li.HighPart, dwMoveMethod));
-}
-
-static int
-_tiffCloseProc(thandle_t fd)
-{
-	return (CloseHandle(fd) ? 0 : -1);
-}
-
-static toff_t
-_tiffSizeProc(thandle_t fd)
-{
-	return ((toff_t)GetFileSize(fd, NULL));
-}
-
-static int
-_tiffDummyMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize)
-{
-	(void) fd;
-	(void) pbase;
-	(void) psize;
-	return (0);
-}
-
-/*
- * From "Hermann Josef Hill" <lhill at rhein-zeitung.de>:
- *
- * Windows uses both a handle and a pointer for file mapping,
- * but according to the SDK documentation and Richter's book
- * "Advanced Windows Programming" it is safe to free the handle
- * after obtaining the file mapping pointer
- *
- * This removes a nasty OS dependency and cures a problem
- * with Visual C++ 5.0
- */
-static int
-_tiffMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize)
-{
-	toff_t size;
-	HANDLE hMapFile;
-
-	if ((size = _tiffSizeProc(fd)) == 0xFFFFFFFF)
-		return (0);
-	hMapFile = CreateFileMapping(fd, NULL, PAGE_READONLY, 0, size, NULL);
-	if (hMapFile == NULL)
-		return (0);
-	*pbase = MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0);
-	CloseHandle(hMapFile);
-	if (*pbase == NULL)
-		return (0);
-	*psize = size;
-	return(1);
-}
-
-static void
-_tiffDummyUnmapProc(thandle_t fd, tdata_t base, toff_t size)
-{
-	(void) fd;
-	(void) base;
-	(void) size;
-}
-
-static void
-_tiffUnmapProc(thandle_t fd, tdata_t base, toff_t size)
-{
-	UnmapViewOfFile(base);
-}
-
-/*
- * Open a TIFF file descriptor for read/writing.
- * Note that TIFFFdOpen and TIFFOpen recognise the character 'u' in the mode
- * string, which forces the file to be opened unmapped.
- */
-TIFF*
-TIFFFdOpen(int ifd, const char* name, const char* mode)
-{
-	TIFF* tif;
-	BOOL fSuppressMap = (mode[1] == 'u' || (mode[1]!=0 && mode[2] == 'u'));
-
-	tif = TIFFClientOpen(name, mode, (thandle_t)ifd,
-			_tiffReadProc, _tiffWriteProc,
-			_tiffSeekProc, _tiffCloseProc, _tiffSizeProc,
-			fSuppressMap ? _tiffDummyMapProc : _tiffMapProc,
-			fSuppressMap ? _tiffDummyUnmapProc : _tiffUnmapProc);
-	if (tif)
-		tif->tif_fd = ifd;
-	return (tif);
-}
-
-#ifndef _WIN32_WCE
-
-/*
- * Open a TIFF file for read/writing.
- */
-TIFF*
-TIFFOpen(const char* name, const char* mode)
-{
-	static const char module[] = "TIFFOpen";
-	thandle_t fd;
-	int m;
-	DWORD dwMode;
-	TIFF* tif;
-
-	m = _TIFFgetMode(mode, module);
-
-	switch(m)
-	{
-	case O_RDONLY:
-		dwMode = OPEN_EXISTING;
-		break;
-	case O_RDWR:
-		dwMode = OPEN_ALWAYS;
-		break;
-	case O_RDWR|O_CREAT:
-		dwMode = OPEN_ALWAYS;
-		break;
-	case O_RDWR|O_TRUNC:
-		dwMode = CREATE_ALWAYS;
-		break;
-	case O_RDWR|O_CREAT|O_TRUNC:
-		dwMode = CREATE_ALWAYS;
-		break;
-	default:
-		return ((TIFF*)0);
-	}
-	fd = (thandle_t)CreateFileA(name,
-		(m == O_RDONLY)?GENERIC_READ:(GENERIC_READ | GENERIC_WRITE),
-		FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, dwMode,
-		(m == O_RDONLY)?FILE_ATTRIBUTE_READONLY:FILE_ATTRIBUTE_NORMAL,
-		NULL);
-	if (fd == INVALID_HANDLE_VALUE) {
-		TIFFErrorExt(0, module, "%s: Cannot open", name);
-		return ((TIFF *)0);
-	}
-
-	tif = TIFFFdOpen((int)fd, name, mode);
-	if(!tif)
-		CloseHandle(fd);
-	return tif;
-}
-
-/*
- * Open a TIFF file with a Unicode filename, for read/writing.
- */
-TIFF*
-TIFFOpenW(const wchar_t* name, const char* mode)
-{
-	static const char module[] = "TIFFOpenW";
-	thandle_t fd;
-	int m;
-	DWORD dwMode;
-	int mbsize;
-	char *mbname;
-	TIFF *tif;
-
-	m = _TIFFgetMode(mode, module);
-
-	switch(m) {
-		case O_RDONLY:			dwMode = OPEN_EXISTING; break;
-		case O_RDWR:			dwMode = OPEN_ALWAYS;   break;
-		case O_RDWR|O_CREAT:		dwMode = OPEN_ALWAYS;   break;
-		case O_RDWR|O_TRUNC:		dwMode = CREATE_ALWAYS; break;
-		case O_RDWR|O_CREAT|O_TRUNC:	dwMode = CREATE_ALWAYS; break;
-		default:			return ((TIFF*)0);
-	}
-
-	fd = (thandle_t)CreateFileW(name,
-		(m == O_RDONLY)?GENERIC_READ:(GENERIC_READ|GENERIC_WRITE),
-		FILE_SHARE_READ, NULL, dwMode,
-		(m == O_RDONLY)?FILE_ATTRIBUTE_READONLY:FILE_ATTRIBUTE_NORMAL,
-		NULL);
-	if (fd == INVALID_HANDLE_VALUE) {
-		TIFFErrorExt(0, module, "%S: Cannot open", name);
-		return ((TIFF *)0);
-	}
-
-	mbname = NULL;
-	mbsize = WideCharToMultiByte(CP_ACP, 0, name, -1, NULL, 0, NULL, NULL);
-	if (mbsize > 0) {
-		mbname = (char *)_TIFFmalloc(mbsize);
-		if (!mbname) {
-			TIFFErrorExt(0, module,
-			"Can't allocate space for filename conversion buffer");
-			return ((TIFF*)0);
-		}
-
-		WideCharToMultiByte(CP_ACP, 0, name, -1, mbname, mbsize,
-				    NULL, NULL);
-	}
-
-	tif = TIFFFdOpen((int)fd,
-			 (mbname != NULL) ? mbname : "<unknown>", mode);
-	if(!tif)
-		CloseHandle(fd);
-
-	_TIFFfree(mbname);
-
-	return tif;
-}
-
-#endif /* ndef _WIN32_WCE */
-
-
-tdata_t
-_TIFFmalloc(tsize_t s)
-{
-	return ((tdata_t)GlobalAlloc(GMEM_FIXED, s));
-}
-
-void
-_TIFFfree(tdata_t p)
-{
-	GlobalFree(p);
-	return;
-}
-
-tdata_t
-_TIFFrealloc(tdata_t p, tsize_t s)
-{
-	void* pvTmp;
-	tsize_t old;
-
-	if(p == NULL)
-		return ((tdata_t)GlobalAlloc(GMEM_FIXED, s));
-
-	old = GlobalSize(p);
-
-	if (old>=s) {
-		if ((pvTmp = GlobalAlloc(GMEM_FIXED, s)) != NULL) {
-			CopyMemory(pvTmp, p, s);
-			GlobalFree(p);
-		}
-	} else {
-		if ((pvTmp = GlobalAlloc(GMEM_FIXED, s)) != NULL) {
-			CopyMemory(pvTmp, p, old);
-			GlobalFree(p);
-		}
-	}
-	return ((tdata_t)pvTmp);
-}
-
-void
-_TIFFmemset(void* p, int v, tsize_t c)
-{
-	FillMemory(p, c, (BYTE)v);
-}
-
-void
-_TIFFmemcpy(void* d, const tdata_t s, tsize_t c)
-{
-	CopyMemory(d, s, c);
-}
-
-int
-_TIFFmemcmp(const tdata_t p1, const tdata_t p2, tsize_t c)
-{
-	register const BYTE *pb1 = (const BYTE *) p1;
-	register const BYTE *pb2 = (const BYTE *) p2;
-	register DWORD dwTmp = c;
-	register int iTmp;
-	for (iTmp = 0; dwTmp-- && !iTmp; iTmp = (int)*pb1++ - (int)*pb2++)
-		;
-	return (iTmp);
-}
-
-#ifndef _WIN32_WCE
-
-static void
-Win32WarningHandler(const char* module, const char* fmt, va_list ap)
-{
-#ifndef TIF_PLATFORM_CONSOLE
-	LPTSTR szTitle;
-	LPTSTR szTmp;
-	LPCTSTR szTitleText = "%s Warning";
-	LPCTSTR szDefaultModule = "LIBTIFF";
-	LPCTSTR szTmpModule = (module == NULL) ? szDefaultModule : module;
-	if ((szTitle = (LPTSTR)LocalAlloc(LMEM_FIXED, (strlen(szTmpModule) +
-		strlen(szTitleText) + strlen(fmt) + 128)*sizeof(char))) == NULL)
-		return;
-	sprintf(szTitle, szTitleText, szTmpModule);
-	szTmp = szTitle + (strlen(szTitle)+2)*sizeof(char);
-	vsprintf(szTmp, fmt, ap);
-	MessageBoxA(GetFocus(), szTmp, szTitle, MB_OK | MB_ICONINFORMATION);
-	LocalFree(szTitle);
-	return;
-#else
-	if (module != NULL)
-		fprintf(stderr, "%s: ", module);
-	fprintf(stderr, "Warning, ");
-	vfprintf(stderr, fmt, ap);
-	fprintf(stderr, ".\n");
-#endif        
-}
-TIFFErrorHandler _TIFFwarningHandler = Win32WarningHandler;
-
-static void
-Win32ErrorHandler(const char* module, const char* fmt, va_list ap)
-{
-#ifndef TIF_PLATFORM_CONSOLE
-	LPTSTR szTitle;
-	LPTSTR szTmp;
-	LPCTSTR szTitleText = "%s Error";
-	LPCTSTR szDefaultModule = "LIBTIFF";
-	LPCTSTR szTmpModule = (module == NULL) ? szDefaultModule : module;
-	if ((szTitle = (LPTSTR)LocalAlloc(LMEM_FIXED, (strlen(szTmpModule) +
-		strlen(szTitleText) + strlen(fmt) + 128)*sizeof(char))) == NULL)
-		return;
-	sprintf(szTitle, szTitleText, szTmpModule);
-	szTmp = szTitle + (strlen(szTitle)+2)*sizeof(char);
-	vsprintf(szTmp, fmt, ap);
-	MessageBoxA(GetFocus(), szTmp, szTitle, MB_OK | MB_ICONEXCLAMATION);
-	LocalFree(szTitle);
-	return;
-#else
-	if (module != NULL)
-		fprintf(stderr, "%s: ", module);
-	vfprintf(stderr, fmt, ap);
-	fprintf(stderr, ".\n");
-#endif        
-}
-TIFFErrorHandler _TIFFerrorHandler = Win32ErrorHandler;
-
-#endif /* ndef _WIN32_WCE */
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_wince.c b/Source/LibTIFF/tif_wince.c
deleted file mode 100644
index ecd362a..0000000
--- a/Source/LibTIFF/tif_wince.c
+++ /dev/null
@@ -1,288 +0,0 @@
-/* $Id: tif_wince.c,v 1.18 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * Windows CE-specific routines for TIFF Library.
- * Adapted from tif_win32.c 01/10/2006 by Mateusz Loskot (mateusz at loskot.net)
- */
-
-#ifndef _WIN32_WCE
-# error "Only Windows CE target is supported!"
-#endif
-
-#include "tiffiop.h"
-#include <windows.h>
-
-/* Turn off console support on Windows CE. */
-#undef TIF_PLATFORM_CONSOLE
-
-
-/*
- * Open a TIFF file for read/writing.
- */
-TIFF*
-TIFFOpen(const char* name, const char* mode)
-{
-	static const char module[] = "TIFFOpen";
-	thandle_t fd;
-	int m;
-	DWORD dwMode;
-	TIFF* tif;
-    size_t nLen;
-    size_t nWideLen;
-    wchar_t* wchName;
-
-	m = _TIFFgetMode(mode, module);
-
-	switch(m)
-	{
-	case O_RDONLY:
-		dwMode = OPEN_EXISTING;
-		break;
-	case O_RDWR:
-		dwMode = OPEN_ALWAYS;
-		break;
-	case O_RDWR|O_CREAT:
-		dwMode = OPEN_ALWAYS;
-		break;
-	case O_RDWR|O_TRUNC:
-		dwMode = CREATE_ALWAYS;
-		break;
-	case O_RDWR|O_CREAT|O_TRUNC:
-		dwMode = CREATE_ALWAYS;
-		break;
-	default:
-		return ((TIFF*)0);
-	}
-
-    /* On Windows CE, CreateFile is mapped to CreateFileW,
-     * but file path is passed as char-based string,
-     * so the path has to be converted to wchar_t.
-     */
-
-    nWideLen = 0;
-    wchName = NULL;
-    nLen = strlen(name) + 1;
-    
-    nWideLen = MultiByteToWideChar(CP_ACP, 0, name, nLen, NULL, 0);
-    wchName = (wchar_t*)malloc(sizeof(wchar_t) * nWideLen);
-    if (NULL == wchName)
-    {
-        TIFFErrorExt(0, module, "Memory allocation error!");
-		return ((TIFF *)0);
-    }
-    memset(wchName, 0, sizeof(wchar_t) * nWideLen);
-    MultiByteToWideChar(CP_ACP, 0, name, nLen, wchName, nWideLen);
-
-	fd = (thandle_t)CreateFile(wchName,
-		(m == O_RDONLY)?GENERIC_READ:(GENERIC_READ | GENERIC_WRITE),
-		FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, dwMode,
-		(m == O_RDONLY)?FILE_ATTRIBUTE_READONLY:FILE_ATTRIBUTE_NORMAL,
-		NULL);
-
-    free(wchName);
-
-    if (fd == INVALID_HANDLE_VALUE) {
-		TIFFErrorExt(0, module, "%s: Cannot open", name);
-		return ((TIFF *)0);
-	}
-
-    /* TODO - mloskot: change to TIFFdOpenW and pass wchar path */
-
-	tif = TIFFFdOpen((int)fd, name, mode);
-	if(!tif)
-		CloseHandle(fd);
-	return tif;
-}
-
-/*
- * Open a TIFF file with a Unicode filename, for read/writing.
- */
-TIFF*
-TIFFOpenW(const wchar_t* name, const char* mode)
-{
-	static const char module[] = "TIFFOpenW";
-	thandle_t fd;
-	int m;
-	DWORD dwMode;
-	int mbsize;
-	char *mbname;
-	TIFF *tif;
-
-	m = _TIFFgetMode(mode, module);
-
-	switch(m) {
-		case O_RDONLY:			dwMode = OPEN_EXISTING; break;
-		case O_RDWR:			dwMode = OPEN_ALWAYS;   break;
-		case O_RDWR|O_CREAT:		dwMode = OPEN_ALWAYS;   break;
-		case O_RDWR|O_TRUNC:		dwMode = CREATE_ALWAYS; break;
-		case O_RDWR|O_CREAT|O_TRUNC:	dwMode = CREATE_ALWAYS; break;
-		default:			return ((TIFF*)0);
-	}
-
-    /* On Windows CE, CreateFile is mapped to CreateFileW,
-     * so no conversion of wchar_t to char is required.
-     */
-
-	fd = (thandle_t)CreateFile(name,
-		(m == O_RDONLY)?GENERIC_READ:(GENERIC_READ|GENERIC_WRITE),
-		FILE_SHARE_READ, NULL, dwMode,
-		(m == O_RDONLY)?FILE_ATTRIBUTE_READONLY:FILE_ATTRIBUTE_NORMAL,
-		NULL);
-	if (fd == INVALID_HANDLE_VALUE) {
-		TIFFErrorExt(0, module, "%S: Cannot open", name);
-		return ((TIFF *)0);
-	}
-
-	mbname = NULL;
-	mbsize = WideCharToMultiByte(CP_ACP, 0, name, -1, NULL, 0, NULL, NULL);
-	if (mbsize > 0) {
-		mbname = (char *)_TIFFmalloc(mbsize);
-		if (!mbname) {
-			TIFFErrorExt(0, module,
-			"Can't allocate space for filename conversion buffer");
-			return ((TIFF*)0);
-		}
-
-		WideCharToMultiByte(CP_ACP, 0, name, -1, mbname, mbsize,
-				    NULL, NULL);
-	}
-
-	tif = TIFFFdOpen((int)fd,
-			 (mbname != NULL) ? mbname : "<unknown>", mode);
-	if(!tif)
-		CloseHandle(fd);
-
-	_TIFFfree(mbname);
-
-	return tif;
-}
-
-static void
-Win32WarningHandler(const char* module, const char* fmt, va_list ap)
-{
-    /* On Windows CE, MessageBox is mapped to wide-char based MessageBoxW. */
-
-    size_t nWideLen = 0;
-    LPTSTR szWideTitle = NULL;
-    LPTSTR szWideMsg = NULL;
-
-	LPSTR szTitle;
-	LPSTR szTmp;
-	LPCSTR szTitleText = "%s Warning";
-	LPCSTR szDefaultModule = "LIBTIFF";
-	LPCSTR szTmpModule;
-
-	szTmpModule = (module == NULL) ? szDefaultModule : module;
-	if ((szTitle = (LPSTR)LocalAlloc(LMEM_FIXED,
-        (strlen(szTmpModule) + strlen(szTitleText)
-        + strlen(fmt) + 128) * sizeof(char))) == NULL)
-		return;
-
-	sprintf(szTitle, szTitleText, szTmpModule);
-	szTmp = szTitle + (strlen(szTitle) + 2) * sizeof(char);
-	vsprintf(szTmp, fmt, ap);
-
-    /* Convert error message to Unicode. */
-
-    nWideLen = MultiByteToWideChar(CP_ACP, 0, szTitle, -1, NULL, 0);
-    szWideTitle = (wchar_t*)malloc(sizeof(wchar_t) * nWideLen);
-    MultiByteToWideChar(CP_ACP, 0, szTitle, -1, szWideTitle, nWideLen);
-
-    nWideLen = MultiByteToWideChar(CP_ACP, 0, szTmp, -1, NULL, 0);
-    szWideMsg = (wchar_t*)malloc(sizeof(wchar_t) * nWideLen);
-    MultiByteToWideChar(CP_ACP, 0, szTmp, -1, szWideMsg, nWideLen);
-
-    /* Display message */
-	
-    MessageBox(GetFocus(), szWideMsg, szWideTitle, MB_OK | MB_ICONEXCLAMATION);
-    
-    /* Free resources */
-
-    LocalFree(szTitle);
-    free(szWideMsg);
-    free(szWideTitle);
-}
-
-TIFFErrorHandler _TIFFwarningHandler = Win32WarningHandler;
-
-static void
-Win32ErrorHandler(const char* module, const char* fmt, va_list ap)
-{
-    /* On Windows CE, MessageBox is mapped to wide-char based MessageBoxW. */
-
-    size_t nWideLen = 0;
-    LPTSTR szWideTitle = NULL;
-    LPTSTR szWideMsg = NULL;
-
-    LPSTR szTitle;
-	LPSTR szTmp;
-	LPCSTR szTitleText = "%s Error";
-	LPCSTR szDefaultModule = "LIBTIFF";
-	LPCSTR szTmpModule;
-
-	szTmpModule = (module == NULL) ? szDefaultModule : module;
-	if ((szTitle = (LPSTR)LocalAlloc(LMEM_FIXED,
-        (strlen(szTmpModule) + strlen(szTitleText)
-        + strlen(fmt) + 128) * sizeof(char))) == NULL)
-		return;
-
-	sprintf(szTitle, szTitleText, szTmpModule);
-	szTmp = szTitle + (strlen(szTitle) + 2) * sizeof(char);
-	vsprintf(szTmp, fmt, ap);
-
-    /* Convert error message to Unicode. */
-
-    nWideLen = MultiByteToWideChar(CP_ACP, 0, szTitle, -1, NULL, 0);
-    szWideTitle = (wchar_t*)malloc(sizeof(wchar_t) * nWideLen);
-    MultiByteToWideChar(CP_ACP, 0, szTitle, -1, szWideTitle, nWideLen);
-
-    nWideLen = MultiByteToWideChar(CP_ACP, 0, szTmp, -1, NULL, 0);
-    szWideMsg = (wchar_t*)malloc(sizeof(wchar_t) * nWideLen);
-    MultiByteToWideChar(CP_ACP, 0, szTmp, -1, szWideMsg, nWideLen);
-
-    /* Display message */
-
-	MessageBox(GetFocus(), szWideMsg, szWideTitle, MB_OK | MB_ICONEXCLAMATION);
-
-    /* Free resources */
-
-    LocalFree(szTitle);
-    free(szWideMsg);
-    free(szWideTitle);
-}
-
-TIFFErrorHandler _TIFFerrorHandler = Win32ErrorHandler;
-
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_write.c b/Source/LibTIFF/tif_write.c
deleted file mode 100644
index d9963a2..0000000
--- a/Source/LibTIFF/tif_write.c
+++ /dev/null
@@ -1,718 +0,0 @@
-/* $Id: tif_write.c,v 1.37 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library.
- *
- * Scanline-oriented Write Support
- */
-#include "tiffiop.h"
-#include <stdio.h>
-
-#define	STRIPINCR	20		/* expansion factor on strip array */
-
-#define	WRITECHECKSTRIPS(tif, module)				\
-	(((tif)->tif_flags&TIFF_BEENWRITING) || TIFFWriteCheck((tif),0,module))
-#define	WRITECHECKTILES(tif, module)				\
-	(((tif)->tif_flags&TIFF_BEENWRITING) || TIFFWriteCheck((tif),1,module))
-#define	BUFFERCHECK(tif)					\
-	((((tif)->tif_flags & TIFF_BUFFERSETUP) && tif->tif_rawdata) ||	\
-	    TIFFWriteBufferSetup((tif), NULL, (tsize_t) -1))
-
-static	int TIFFGrowStrips(TIFF*, int, const char*);
-static	int TIFFAppendToStrip(TIFF*, tstrip_t, tidata_t, tsize_t);
-
-int
-TIFFWriteScanline(TIFF* tif, tdata_t buf, uint32 row, tsample_t sample)
-{
-	static const char module[] = "TIFFWriteScanline";
-	register TIFFDirectory *td;
-	int status, imagegrew = 0;
-	tstrip_t strip;
-
-	if (!WRITECHECKSTRIPS(tif, module))
-		return (-1);
-	/*
-	 * Handle delayed allocation of data buffer.  This
-	 * permits it to be sized more intelligently (using
-	 * directory information).
-	 */
-	if (!BUFFERCHECK(tif))
-		return (-1);
-	td = &tif->tif_dir;
-	/*
-	 * Extend image length if needed
-	 * (but only for PlanarConfig=1).
-	 */
-	if (row >= td->td_imagelength) {	/* extend image */
-		if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
-			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-		"Can not change \"ImageLength\" when using separate planes");
-			return (-1);
-		}
-		td->td_imagelength = row+1;
-		imagegrew = 1;
-	}
-	/*
-	 * Calculate strip and check for crossings.
-	 */
-	if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
-		if (sample >= td->td_samplesperpixel) {
-			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			    "%d: Sample out of range, max %d",
-			    sample, td->td_samplesperpixel);
-			return (-1);
-		}
-		strip = sample*td->td_stripsperimage + row/td->td_rowsperstrip;
-	} else
-		strip = row / td->td_rowsperstrip;
-	/*
-	 * Check strip array to make sure there's space. We don't support
-	 * dynamically growing files that have data organized in separate
-	 * bitplanes because it's too painful.  In that case we require that
-	 * the imagelength be set properly before the first write (so that the
-	 * strips array will be fully allocated above).
-	 */
-	if (strip >= td->td_nstrips && !TIFFGrowStrips(tif, 1, module))
-		return (-1);
-	if (strip != tif->tif_curstrip) {
-		/*
-		 * Changing strips -- flush any data present.
-		 */
-		if (!TIFFFlushData(tif))
-			return (-1);
-		tif->tif_curstrip = strip;
-		/*
-		 * Watch out for a growing image.  The value of strips/image
-		 * will initially be 1 (since it can't be deduced until the
-		 * imagelength is known).
-		 */
-		if (strip >= td->td_stripsperimage && imagegrew)
-			td->td_stripsperimage =
-			    TIFFhowmany(td->td_imagelength,td->td_rowsperstrip);
-		tif->tif_row =
-		    (strip % td->td_stripsperimage) * td->td_rowsperstrip;
-		if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
-			if (!(*tif->tif_setupencode)(tif))
-				return (-1);
-			tif->tif_flags |= TIFF_CODERSETUP;
-		}
-        
-		tif->tif_rawcc = 0;
-		tif->tif_rawcp = tif->tif_rawdata;
-
-		if( td->td_stripbytecount[strip] > 0 )
-		{
-			/* if we are writing over existing tiles, zero length */
-			td->td_stripbytecount[strip] = 0;
-
-			/* this forces TIFFAppendToStrip() to do a seek */
-			tif->tif_curoff = 0;
-		}
-
-		if (!(*tif->tif_preencode)(tif, sample))
-			return (-1);
-		tif->tif_flags |= TIFF_POSTENCODE;
-	}
-	/*
-	 * Ensure the write is either sequential or at the
-	 * beginning of a strip (or that we can randomly
-	 * access the data -- i.e. no encoding).
-	 */
-	if (row != tif->tif_row) {
-		if (row < tif->tif_row) {
-			/*
-			 * Moving backwards within the same strip:
-			 * backup to the start and then decode
-			 * forward (below).
-			 */
-			tif->tif_row = (strip % td->td_stripsperimage) *
-			    td->td_rowsperstrip;
-			tif->tif_rawcp = tif->tif_rawdata;
-		}
-		/*
-		 * Seek forward to the desired row.
-		 */
-		if (!(*tif->tif_seek)(tif, row - tif->tif_row))
-			return (-1);
-		tif->tif_row = row;
-	}
-
-        /* swab if needed - note that source buffer will be altered */
-        tif->tif_postdecode( tif, (tidata_t) buf, tif->tif_scanlinesize );
-
-	status = (*tif->tif_encoderow)(tif, (tidata_t) buf,
-	    tif->tif_scanlinesize, sample);
-
-        /* we are now poised at the beginning of the next row */
-	tif->tif_row = row + 1;
-	return (status);
-}
-
-/*
- * Encode the supplied data and write it to the
- * specified strip.
- *
- * NB: Image length must be setup before writing.
- */
-tsize_t
-TIFFWriteEncodedStrip(TIFF* tif, tstrip_t strip, tdata_t data, tsize_t cc)
-{
-	static const char module[] = "TIFFWriteEncodedStrip";
-	TIFFDirectory *td = &tif->tif_dir;
-	tsample_t sample;
-
-	if (!WRITECHECKSTRIPS(tif, module))
-		return ((tsize_t) -1);
-	/*
-	 * Check strip array to make sure there's space.
-	 * We don't support dynamically growing files that
-	 * have data organized in separate bitplanes because
-	 * it's too painful.  In that case we require that
-	 * the imagelength be set properly before the first
-	 * write (so that the strips array will be fully
-	 * allocated above).
-	 */
-	if (strip >= td->td_nstrips) {
-		if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
-			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-		"Can not grow image by strips when using separate planes");
-			return ((tsize_t) -1);
-		}
-		if (!TIFFGrowStrips(tif, 1, module))
-			return ((tsize_t) -1);
-		td->td_stripsperimage =
-		    TIFFhowmany(td->td_imagelength, td->td_rowsperstrip);
-	}
-	/*
-	 * Handle delayed allocation of data buffer.  This
-	 * permits it to be sized according to the directory
-	 * info.
-	 */
-	if (!BUFFERCHECK(tif))
-		return ((tsize_t) -1);
-	tif->tif_curstrip = strip;
-	tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
-	if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
-		if (!(*tif->tif_setupencode)(tif))
-			return ((tsize_t) -1);
-		tif->tif_flags |= TIFF_CODERSETUP;
-	}
-        
-	tif->tif_rawcc = 0;
-	tif->tif_rawcp = tif->tif_rawdata;
-
-        if( td->td_stripbytecount[strip] > 0 )
-        {
-	    /* Force TIFFAppendToStrip() to consider placing data at end
-               of file. */
-            tif->tif_curoff = 0;
-        }
-        
-	tif->tif_flags &= ~TIFF_POSTENCODE;
-	sample = (tsample_t)(strip / td->td_stripsperimage);
-	if (!(*tif->tif_preencode)(tif, sample))
-		return ((tsize_t) -1);
-
-        /* swab if needed - note that source buffer will be altered */
-        tif->tif_postdecode( tif, (tidata_t) data, cc );
-
-	if (!(*tif->tif_encodestrip)(tif, (tidata_t) data, cc, sample))
-		return ((tsize_t) 0);
-	if (!(*tif->tif_postencode)(tif))
-		return ((tsize_t) -1);
-	if (!isFillOrder(tif, td->td_fillorder) &&
-	    (tif->tif_flags & TIFF_NOBITREV) == 0)
-		TIFFReverseBits(tif->tif_rawdata, tif->tif_rawcc);
-	if (tif->tif_rawcc > 0 &&
-	    !TIFFAppendToStrip(tif, strip, tif->tif_rawdata, tif->tif_rawcc))
-		return ((tsize_t) -1);
-	tif->tif_rawcc = 0;
-	tif->tif_rawcp = tif->tif_rawdata;
-	return (cc);
-}
-
-/*
- * Write the supplied data to the specified strip.
- *
- * NB: Image length must be setup before writing.
- */
-tsize_t
-TIFFWriteRawStrip(TIFF* tif, tstrip_t strip, tdata_t data, tsize_t cc)
-{
-	static const char module[] = "TIFFWriteRawStrip";
-	TIFFDirectory *td = &tif->tif_dir;
-
-	if (!WRITECHECKSTRIPS(tif, module))
-		return ((tsize_t) -1);
-	/*
-	 * Check strip array to make sure there's space.
-	 * We don't support dynamically growing files that
-	 * have data organized in separate bitplanes because
-	 * it's too painful.  In that case we require that
-	 * the imagelength be set properly before the first
-	 * write (so that the strips array will be fully
-	 * allocated above).
-	 */
-	if (strip >= td->td_nstrips) {
-		if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
-			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-		"Can not grow image by strips when using separate planes");
-			return ((tsize_t) -1);
-		}
-		/*
-		 * Watch out for a growing image.  The value of
-		 * strips/image will initially be 1 (since it
-		 * can't be deduced until the imagelength is known).
-		 */
-		if (strip >= td->td_stripsperimage)
-			td->td_stripsperimage =
-			    TIFFhowmany(td->td_imagelength,td->td_rowsperstrip);
-		if (!TIFFGrowStrips(tif, 1, module))
-			return ((tsize_t) -1);
-	}
-	tif->tif_curstrip = strip;
-	tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
-	return (TIFFAppendToStrip(tif, strip, (tidata_t) data, cc) ?
-	    cc : (tsize_t) -1);
-}
-
-/*
- * Write and compress a tile of data.  The
- * tile is selected by the (x,y,z,s) coordinates.
- */
-tsize_t
-TIFFWriteTile(TIFF* tif,
-    tdata_t buf, uint32 x, uint32 y, uint32 z, tsample_t s)
-{
-	if (!TIFFCheckTile(tif, x, y, z, s))
-		return (-1);
-	/*
-	 * NB: A tile size of -1 is used instead of tif_tilesize knowing
-	 *     that TIFFWriteEncodedTile will clamp this to the tile size.
-	 *     This is done because the tile size may not be defined until
-	 *     after the output buffer is setup in TIFFWriteBufferSetup.
-	 */
-	return (TIFFWriteEncodedTile(tif,
-	    TIFFComputeTile(tif, x, y, z, s), buf, (tsize_t) -1));
-}
-
-/*
- * Encode the supplied data and write it to the
- * specified tile.  There must be space for the
- * data.  The function clamps individual writes
- * to a tile to the tile size, but does not (and
- * can not) check that multiple writes to the same
- * tile do not write more than tile size data.
- *
- * NB: Image length must be setup before writing; this
- *     interface does not support automatically growing
- *     the image on each write (as TIFFWriteScanline does).
- */
-tsize_t
-TIFFWriteEncodedTile(TIFF* tif, ttile_t tile, tdata_t data, tsize_t cc)
-{
-	static const char module[] = "TIFFWriteEncodedTile";
-	TIFFDirectory *td;
-	tsample_t sample;
-
-	if (!WRITECHECKTILES(tif, module))
-		return ((tsize_t) -1);
-	td = &tif->tif_dir;
-	if (tile >= td->td_nstrips) {
-		TIFFErrorExt(tif->tif_clientdata, module, "%s: Tile %lu out of range, max %lu",
-		    tif->tif_name, (unsigned long) tile, (unsigned long) td->td_nstrips);
-		return ((tsize_t) -1);
-	}
-	/*
-	 * Handle delayed allocation of data buffer.  This
-	 * permits it to be sized more intelligently (using
-	 * directory information).
-	 */
-	if (!BUFFERCHECK(tif))
-		return ((tsize_t) -1);
-	tif->tif_curtile = tile;
-
-	tif->tif_rawcc = 0;
-	tif->tif_rawcp = tif->tif_rawdata;
-
-        if( td->td_stripbytecount[tile] > 0 )
-        {
-	    /* Force TIFFAppendToStrip() to consider placing data at end
-               of file. */
-            tif->tif_curoff = 0;
-        }
-        
-	/* 
-	 * Compute tiles per row & per column to compute
-	 * current row and column
-	 */
-	tif->tif_row = (tile % TIFFhowmany(td->td_imagelength, td->td_tilelength))
-		* td->td_tilelength;
-	tif->tif_col = (tile % TIFFhowmany(td->td_imagewidth, td->td_tilewidth))
-		* td->td_tilewidth;
-
-	if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
-		if (!(*tif->tif_setupencode)(tif))
-			return ((tsize_t) -1);
-		tif->tif_flags |= TIFF_CODERSETUP;
-	}
-	tif->tif_flags &= ~TIFF_POSTENCODE;
-	sample = (tsample_t)(tile/td->td_stripsperimage);
-	if (!(*tif->tif_preencode)(tif, sample))
-		return ((tsize_t) -1);
-	/*
-	 * Clamp write amount to the tile size.  This is mostly
-	 * done so that callers can pass in some large number
-	 * (e.g. -1) and have the tile size used instead.
-	 */
-	if ( cc < 1 || cc > tif->tif_tilesize)
-		cc = tif->tif_tilesize;
-
-        /* swab if needed - note that source buffer will be altered */
-        tif->tif_postdecode( tif, (tidata_t) data, cc );
-
-	if (!(*tif->tif_encodetile)(tif, (tidata_t) data, cc, sample))
-		return ((tsize_t) 0);
-	if (!(*tif->tif_postencode)(tif))
-		return ((tsize_t) -1);
-	if (!isFillOrder(tif, td->td_fillorder) &&
-	    (tif->tif_flags & TIFF_NOBITREV) == 0)
-		TIFFReverseBits((unsigned char *)tif->tif_rawdata, tif->tif_rawcc);
-	if (tif->tif_rawcc > 0 && !TIFFAppendToStrip(tif, tile,
-	    tif->tif_rawdata, tif->tif_rawcc))
-		return ((tsize_t) -1);
-	tif->tif_rawcc = 0;
-	tif->tif_rawcp = tif->tif_rawdata;
-	return (cc);
-}
-
-/*
- * Write the supplied data to the specified strip.
- * There must be space for the data; we don't check
- * if strips overlap!
- *
- * NB: Image length must be setup before writing; this
- *     interface does not support automatically growing
- *     the image on each write (as TIFFWriteScanline does).
- */
-tsize_t
-TIFFWriteRawTile(TIFF* tif, ttile_t tile, tdata_t data, tsize_t cc)
-{
-	static const char module[] = "TIFFWriteRawTile";
-
-	if (!WRITECHECKTILES(tif, module))
-		return ((tsize_t) -1);
-	if (tile >= tif->tif_dir.td_nstrips) {
-		TIFFErrorExt(tif->tif_clientdata, module, "%s: Tile %lu out of range, max %lu",
-		    tif->tif_name, (unsigned long) tile,
-		    (unsigned long) tif->tif_dir.td_nstrips);
-		return ((tsize_t) -1);
-	}
-	return (TIFFAppendToStrip(tif, tile, (tidata_t) data, cc) ?
-	    cc : (tsize_t) -1);
-}
-
-#define	isUnspecified(tif, f) \
-    (TIFFFieldSet(tif,f) && (tif)->tif_dir.td_imagelength == 0)
-
-int
-TIFFSetupStrips(TIFF* tif)
-{
-	TIFFDirectory* td = &tif->tif_dir;
-
-	if (isTiled(tif))
-		td->td_stripsperimage =
-		    isUnspecified(tif, FIELD_TILEDIMENSIONS) ?
-			td->td_samplesperpixel : TIFFNumberOfTiles(tif);
-	else
-		td->td_stripsperimage =
-		    isUnspecified(tif, FIELD_ROWSPERSTRIP) ?
-			td->td_samplesperpixel : TIFFNumberOfStrips(tif);
-	td->td_nstrips = td->td_stripsperimage;
-	if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
-		td->td_stripsperimage /= td->td_samplesperpixel;
-	td->td_stripoffset = (uint32 *)
-	    _TIFFmalloc(td->td_nstrips * sizeof (uint32));
-	td->td_stripbytecount = (uint32 *)
-	    _TIFFmalloc(td->td_nstrips * sizeof (uint32));
-	if (td->td_stripoffset == NULL || td->td_stripbytecount == NULL)
-		return (0);
-	/*
-	 * Place data at the end-of-file
-	 * (by setting offsets to zero).
-	 */
-	_TIFFmemset(td->td_stripoffset, 0, td->td_nstrips*sizeof (uint32));
-	_TIFFmemset(td->td_stripbytecount, 0, td->td_nstrips*sizeof (uint32));
-	TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
-	TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
-	return (1);
-}
-#undef isUnspecified
-
-/*
- * Verify file is writable and that the directory
- * information is setup properly.  In doing the latter
- * we also "freeze" the state of the directory so
- * that important information is not changed.
- */
-int
-TIFFWriteCheck(TIFF* tif, int tiles, const char* module)
-{
-	if (tif->tif_mode == O_RDONLY) {
-		TIFFErrorExt(tif->tif_clientdata, module, "%s: File not open for writing",
-		    tif->tif_name);
-		return (0);
-	}
-	if (tiles ^ isTiled(tif)) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name, tiles ?
-		    "Can not write tiles to a stripped image" :
-		    "Can not write scanlines to a tiled image");
-		return (0);
-	}
-        
-	/*
-	 * On the first write verify all the required information
-	 * has been setup and initialize any data structures that
-	 * had to wait until directory information was set.
-	 * Note that a lot of our work is assumed to remain valid
-	 * because we disallow any of the important parameters
-	 * from changing after we start writing (i.e. once
-	 * TIFF_BEENWRITING is set, TIFFSetField will only allow
-	 * the image's length to be changed).
-	 */
-	if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS)) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-		    "%s: Must set \"ImageWidth\" before writing data",
-		    tif->tif_name);
-		return (0);
-	}
-	if (tif->tif_dir.td_samplesperpixel == 1) {
-		/* 
-		 * Planarconfiguration is irrelevant in case of single band
-		 * images and need not be included. We will set it anyway,
-		 * because this field is used in other parts of library even
-		 * in the single band case.
-		 */
-		if (!TIFFFieldSet(tif, FIELD_PLANARCONFIG))
-                    tif->tif_dir.td_planarconfig = PLANARCONFIG_CONTIG;
-	} else {
-		if (!TIFFFieldSet(tif, FIELD_PLANARCONFIG)) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-		    "%s: Must set \"PlanarConfiguration\" before writing data",
-			    tif->tif_name);
-			return (0);
-		}
-	}
-	if (tif->tif_dir.td_stripoffset == NULL && !TIFFSetupStrips(tif)) {
-		tif->tif_dir.td_nstrips = 0;
-		TIFFErrorExt(tif->tif_clientdata, module, "%s: No space for %s arrays",
-		    tif->tif_name, isTiled(tif) ? "tile" : "strip");
-		return (0);
-	}
-	tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tsize_t) -1;
-	tif->tif_scanlinesize = TIFFScanlineSize(tif);
-	tif->tif_flags |= TIFF_BEENWRITING;
-	return (1);
-}
-
-/*
- * Setup the raw data buffer used for encoding.
- */
-int
-TIFFWriteBufferSetup(TIFF* tif, tdata_t bp, tsize_t size)
-{
-	static const char module[] = "TIFFWriteBufferSetup";
-
-	if (tif->tif_rawdata) {
-		if (tif->tif_flags & TIFF_MYBUFFER) {
-			_TIFFfree(tif->tif_rawdata);
-			tif->tif_flags &= ~TIFF_MYBUFFER;
-		}
-		tif->tif_rawdata = NULL;
-	}
-	if (size == (tsize_t) -1) {
-		size = (isTiled(tif) ?
-		    tif->tif_tilesize : TIFFStripSize(tif));
-		/*
-		 * Make raw data buffer at least 8K
-		 */
-		if (size < 8*1024)
-			size = 8*1024;
-		bp = NULL;			/* NB: force malloc */
-	}
-	if (bp == NULL) {
-		bp = _TIFFmalloc(size);
-		if (bp == NULL) {
-			TIFFErrorExt(tif->tif_clientdata, module, "%s: No space for output buffer",
-			    tif->tif_name);
-			return (0);
-		}
-		tif->tif_flags |= TIFF_MYBUFFER;
-	} else
-		tif->tif_flags &= ~TIFF_MYBUFFER;
-	tif->tif_rawdata = (tidata_t) bp;
-	tif->tif_rawdatasize = size;
-	tif->tif_rawcc = 0;
-	tif->tif_rawcp = tif->tif_rawdata;
-	tif->tif_flags |= TIFF_BUFFERSETUP;
-	return (1);
-}
-
-/*
- * Grow the strip data structures by delta strips.
- */
-static int
-TIFFGrowStrips(TIFF* tif, int delta, const char* module)
-{
-	TIFFDirectory	*td = &tif->tif_dir;
-	uint32		*new_stripoffset, *new_stripbytecount;
-
-	assert(td->td_planarconfig == PLANARCONFIG_CONTIG);
-	new_stripoffset = (uint32*)_TIFFrealloc(td->td_stripoffset,
-		(td->td_nstrips + delta) * sizeof (uint32));
-	new_stripbytecount = (uint32*)_TIFFrealloc(td->td_stripbytecount,
-		(td->td_nstrips + delta) * sizeof (uint32));
-	if (new_stripoffset == NULL || new_stripbytecount == NULL) {
-		if (new_stripoffset)
-			_TIFFfree(new_stripoffset);
-		if (new_stripbytecount)
-			_TIFFfree(new_stripbytecount);
-		td->td_nstrips = 0;
-		TIFFErrorExt(tif->tif_clientdata, module, "%s: No space to expand strip arrays",
-			  tif->tif_name);
-		return (0);
-	}
-	td->td_stripoffset = new_stripoffset;
-	td->td_stripbytecount = new_stripbytecount;
-	_TIFFmemset(td->td_stripoffset + td->td_nstrips,
-		    0, delta*sizeof (uint32));
-	_TIFFmemset(td->td_stripbytecount + td->td_nstrips,
-		    0, delta*sizeof (uint32));
-	td->td_nstrips += delta;
-	return (1);
-}
-
-/*
- * Append the data to the specified strip.
- */
-static int
-TIFFAppendToStrip(TIFF* tif, tstrip_t strip, tidata_t data, tsize_t cc)
-{
-	static const char module[] = "TIFFAppendToStrip";
-	TIFFDirectory *td = &tif->tif_dir;
-
-	if (td->td_stripoffset[strip] == 0 || tif->tif_curoff == 0) {
-            assert(td->td_nstrips > 0);
-
-            if( td->td_stripbytecount[strip] != 0 
-                && td->td_stripoffset[strip] != 0 
-                && td->td_stripbytecount[strip] >= cc )
-            {
-                /* 
-                 * There is already tile data on disk, and the new tile
-                 * data we have to will fit in the same space.  The only 
-                 * aspect of this that is risky is that there could be
-                 * more data to append to this strip before we are done
-                 * depending on how we are getting called.
-                 */
-                if (!SeekOK(tif, td->td_stripoffset[strip])) {
-                    TIFFErrorExt(tif->tif_clientdata, module,
-                                 "Seek error at scanline %lu",
-                                 (unsigned long)tif->tif_row);
-                    return (0);
-                }
-            }
-            else
-            {
-                /* 
-                 * Seek to end of file, and set that as our location to 
-                 * write this strip.
-                 */
-                td->td_stripoffset[strip] = TIFFSeekFile(tif, 0, SEEK_END);
-            }
-
-            tif->tif_curoff = td->td_stripoffset[strip];
-
-            /*
-             * We are starting a fresh strip/tile, so set the size to zero.
-             */
-            td->td_stripbytecount[strip] = 0;
-	}
-
-	if (!WriteOK(tif, data, cc)) {
-		TIFFErrorExt(tif->tif_clientdata, module, "Write error at scanline %lu",
-		    (unsigned long) tif->tif_row);
-		    return (0);
-	}
-	tif->tif_curoff =  tif->tif_curoff+cc;
-	td->td_stripbytecount[strip] += cc;
-	return (1);
-}
-
-/*
- * Internal version of TIFFFlushData that can be
- * called by ``encodestrip routines'' w/o concern
- * for infinite recursion.
- */
-int
-TIFFFlushData1(TIFF* tif)
-{
-	if (tif->tif_rawcc > 0) {
-		if (!isFillOrder(tif, tif->tif_dir.td_fillorder) &&
-		    (tif->tif_flags & TIFF_NOBITREV) == 0)
-			TIFFReverseBits((unsigned char *)tif->tif_rawdata,
-			    tif->tif_rawcc);
-		if (!TIFFAppendToStrip(tif,
-		    isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip,
-		    tif->tif_rawdata, tif->tif_rawcc))
-			return (0);
-		tif->tif_rawcc = 0;
-		tif->tif_rawcp = tif->tif_rawdata;
-	}
-	return (1);
-}
-
-/*
- * Set the current write offset.  This should only be
- * used to set the offset to a known previous location
- * (very carefully), or to 0 so that the next write gets
- * appended to the end of the file.
- */
-void
-TIFFSetWriteOffset(TIFF* tif, toff_t off)
-{
-	tif->tif_curoff = off;
-}
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tif_zip.c b/Source/LibTIFF/tif_zip.c
deleted file mode 100644
index 6e563cb..0000000
--- a/Source/LibTIFF/tif_zip.c
+++ /dev/null
@@ -1,419 +0,0 @@
-/* $Id: tif_zip.c,v 1.37 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1995-1997 Sam Leffler
- * Copyright (c) 1995-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-#include "tiffiop.h"
-#ifdef ZIP_SUPPORT
-/*
- * TIFF Library.
- *
- * ZIP (aka Deflate) Compression Support
- *
- * This file is simply an interface to the zlib library written by
- * Jean-loup Gailly and Mark Adler.  You must use version 1.0 or later
- * of the library: this code assumes the 1.0 API and also depends on
- * the ability to write the zlib header multiple times (one per strip)
- * which was not possible with versions prior to 0.95.  Note also that
- * older versions of this codec avoided this bug by supressing the header
- * entirely.  This means that files written with the old library cannot
- * be read; they should be converted to a different compression scheme
- * and then reconverted.
- *
- * The data format used by the zlib library is described in the files
- * zlib-3.1.doc, deflate-1.1.doc and gzip-4.1.doc, available in the
- * directory ftp://ftp.uu.net/pub/archiving/zip/doc.  The library was
- * last found at ftp://ftp.uu.net/pub/archiving/zip/zlib/zlib-0.99.tar.gz.
- */
-#include "tif_predict.h"
-#include "../ZLib/zlib.h"
-
-#include <stdio.h>
-
-/*
- * Sigh, ZLIB_VERSION is defined as a string so there's no
- * way to do a proper check here.  Instead we guess based
- * on the presence of #defines that were added between the
- * 0.95 and 1.0 distributions.
- */
-#if !defined(Z_NO_COMPRESSION) || !defined(Z_DEFLATED)
-#error "Antiquated ZLIB software; you must use version 1.0 or later"
-#endif
-
-/*
- * State block for each open TIFF
- * file using ZIP compression/decompression.
- */
-typedef	struct {
-	TIFFPredictorState predict;
-	z_stream	stream;
-	int		zipquality;		/* compression level */
-	int		state;			/* state flags */
-#define ZSTATE_INIT_DECODE 0x01
-#define ZSTATE_INIT_ENCODE 0x02
-
-	TIFFVGetMethod	vgetparent;		/* super-class method */
-	TIFFVSetMethod	vsetparent;		/* super-class method */
-} ZIPState;
-
-#define	ZState(tif)		((ZIPState*) (tif)->tif_data)
-#define	DecoderState(tif)	ZState(tif)
-#define	EncoderState(tif)	ZState(tif)
-
-static	int ZIPEncode(TIFF*, tidata_t, tsize_t, tsample_t);
-static	int ZIPDecode(TIFF*, tidata_t, tsize_t, tsample_t);
-
-static int
-ZIPSetupDecode(TIFF* tif)
-{
-	ZIPState* sp = DecoderState(tif);
-	static const char module[] = "ZIPSetupDecode";
-
-	assert(sp != NULL);
-        
-        /* if we were last encoding, terminate this mode */
-	if (sp->state & ZSTATE_INIT_ENCODE) {
-            deflateEnd(&sp->stream);
-            sp->state = 0;
-        }
-
-	if (inflateInit(&sp->stream) != Z_OK) {
-		TIFFErrorExt(tif->tif_clientdata, module, "%s: %s", tif->tif_name, sp->stream.msg);
-		return (0);
-	} else {
-		sp->state |= ZSTATE_INIT_DECODE;
-		return (1);
-	}
-}
-
-/*
- * Setup state for decoding a strip.
- */
-static int
-ZIPPreDecode(TIFF* tif, tsample_t s)
-{
-	ZIPState* sp = DecoderState(tif);
-
-	(void) s;
-	assert(sp != NULL);
-
-        if( (sp->state & ZSTATE_INIT_DECODE) == 0 )
-            tif->tif_setupdecode( tif );
-
-	sp->stream.next_in = tif->tif_rawdata;
-	sp->stream.avail_in = tif->tif_rawcc;
-	return (inflateReset(&sp->stream) == Z_OK);
-}
-
-static int
-ZIPDecode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s)
-{
-	ZIPState* sp = DecoderState(tif);
-	static const char module[] = "ZIPDecode";
-
-	(void) s;
-	assert(sp != NULL);
-        assert(sp->state == ZSTATE_INIT_DECODE);
-
-	sp->stream.next_out = op;
-	sp->stream.avail_out = occ;
-	do {
-		int state = inflate(&sp->stream, Z_PARTIAL_FLUSH);
-		if (state == Z_STREAM_END)
-			break;
-		if (state == Z_DATA_ERROR) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-			    "%s: Decoding error at scanline %d, %s",
-			    tif->tif_name, tif->tif_row, sp->stream.msg);
-			if (inflateSync(&sp->stream) != Z_OK)
-				return (0);
-			continue;
-		}
-		if (state != Z_OK) {
-			TIFFErrorExt(tif->tif_clientdata, module, "%s: zlib error: %s",
-			    tif->tif_name, sp->stream.msg);
-			return (0);
-		}
-	} while (sp->stream.avail_out > 0);
-	if (sp->stream.avail_out != 0) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-		    "%s: Not enough data at scanline %d (short %d bytes)",
-		    tif->tif_name, tif->tif_row, sp->stream.avail_out);
-		return (0);
-	}
-	return (1);
-}
-
-static int
-ZIPSetupEncode(TIFF* tif)
-{
-	ZIPState* sp = EncoderState(tif);
-	static const char module[] = "ZIPSetupEncode";
-
-	assert(sp != NULL);
-	if (sp->state & ZSTATE_INIT_DECODE) {
-            inflateEnd(&sp->stream);
-            sp->state = 0;
-        }
-
-	if (deflateInit(&sp->stream, sp->zipquality) != Z_OK) {
-		TIFFErrorExt(tif->tif_clientdata, module, "%s: %s", tif->tif_name, sp->stream.msg);
-		return (0);
-	} else {
-		sp->state |= ZSTATE_INIT_ENCODE;
-		return (1);
-	}
-}
-
-/*
- * Reset encoding state at the start of a strip.
- */
-static int
-ZIPPreEncode(TIFF* tif, tsample_t s)
-{
-	ZIPState *sp = EncoderState(tif);
-
-	(void) s;
-	assert(sp != NULL);
-        if( sp->state != ZSTATE_INIT_ENCODE )
-            tif->tif_setupencode( tif );
-
-	sp->stream.next_out = tif->tif_rawdata;
-	sp->stream.avail_out = tif->tif_rawdatasize;
-	return (deflateReset(&sp->stream) == Z_OK);
-}
-
-/*
- * Encode a chunk of pixels.
- */
-static int
-ZIPEncode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s)
-{
-	ZIPState *sp = EncoderState(tif);
-	static const char module[] = "ZIPEncode";
-
-        assert(sp != NULL);
-        assert(sp->state == ZSTATE_INIT_ENCODE);
-
-	(void) s;
-	sp->stream.next_in = bp;
-	sp->stream.avail_in = cc;
-	do {
-		if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) {
-			TIFFErrorExt(tif->tif_clientdata, module, "%s: Encoder error: %s",
-			    tif->tif_name, sp->stream.msg);
-			return (0);
-		}
-		if (sp->stream.avail_out == 0) {
-			tif->tif_rawcc = tif->tif_rawdatasize;
-			TIFFFlushData1(tif);
-			sp->stream.next_out = tif->tif_rawdata;
-			sp->stream.avail_out = tif->tif_rawdatasize;
-		}
-	} while (sp->stream.avail_in > 0);
-	return (1);
-}
-
-/*
- * Finish off an encoded strip by flushing the last
- * string and tacking on an End Of Information code.
- */
-static int
-ZIPPostEncode(TIFF* tif)
-{
-	ZIPState *sp = EncoderState(tif);
-	static const char module[] = "ZIPPostEncode";
-	int state;
-
-	sp->stream.avail_in = 0;
-	do {
-		state = deflate(&sp->stream, Z_FINISH);
-		switch (state) {
-		case Z_STREAM_END:
-		case Z_OK:
-		    if ((int)sp->stream.avail_out != (int)tif->tif_rawdatasize)
-                    {
-			    tif->tif_rawcc =
-				tif->tif_rawdatasize - sp->stream.avail_out;
-			    TIFFFlushData1(tif);
-			    sp->stream.next_out = tif->tif_rawdata;
-			    sp->stream.avail_out = tif->tif_rawdatasize;
-		    }
-		    break;
-		default:
-			TIFFErrorExt(tif->tif_clientdata, module, "%s: zlib error: %s",
-			tif->tif_name, sp->stream.msg);
-		    return (0);
-		}
-	} while (state != Z_STREAM_END);
-	return (1);
-}
-
-static void
-ZIPCleanup(TIFF* tif)
-{
-	ZIPState* sp = ZState(tif);
-
-	assert(sp != 0);
-
-	(void)TIFFPredictorCleanup(tif);
-
-	tif->tif_tagmethods.vgetfield = sp->vgetparent;
-	tif->tif_tagmethods.vsetfield = sp->vsetparent;
-
-	if (sp->state & ZSTATE_INIT_ENCODE) {
-            deflateEnd(&sp->stream);
-            sp->state = 0;
-        } else if( sp->state & ZSTATE_INIT_DECODE) {
-            inflateEnd(&sp->stream);
-            sp->state = 0;
-	}
-	_TIFFfree(sp);
-	tif->tif_data = NULL;
-
-	_TIFFSetDefaultCompressionState(tif);
-}
-
-static int
-ZIPVSetField(TIFF* tif, ttag_t tag, va_list ap)
-{
-	ZIPState* sp = ZState(tif);
-	static const char module[] = "ZIPVSetField";
-
-	switch (tag) {
-	case TIFFTAG_ZIPQUALITY:
-		sp->zipquality = va_arg(ap, int);
-		if ( sp->state&ZSTATE_INIT_ENCODE ) {
-			if (deflateParams(&sp->stream,
-			    sp->zipquality, Z_DEFAULT_STRATEGY) != Z_OK) {
-				TIFFErrorExt(tif->tif_clientdata, module, "%s: zlib error: %s",
-				    tif->tif_name, sp->stream.msg);
-				return (0);
-			}
-		}
-		return (1);
-	default:
-		return (*sp->vsetparent)(tif, tag, ap);
-	}
-	/*NOTREACHED*/
-}
-
-static int
-ZIPVGetField(TIFF* tif, ttag_t tag, va_list ap)
-{
-	ZIPState* sp = ZState(tif);
-
-	switch (tag) {
-	case TIFFTAG_ZIPQUALITY:
-		*va_arg(ap, int*) = sp->zipquality;
-		break;
-	default:
-		return (*sp->vgetparent)(tif, tag, ap);
-	}
-	return (1);
-}
-
-static const TIFFFieldInfo zipFieldInfo[] = {
-    { TIFFTAG_ZIPQUALITY,	 0, 0,	TIFF_ANY,	FIELD_PSEUDO,
-      TRUE,	FALSE,	"" },
-};
-
-int
-TIFFInitZIP(TIFF* tif, int scheme)
-{
-	static const char module[] = "TIFFInitZIP";
-	ZIPState* sp;
-
-	assert( (scheme == COMPRESSION_DEFLATE)
-		|| (scheme == COMPRESSION_ADOBE_DEFLATE));
-
-	/*
-	 * Merge codec-specific tag information.
-	 */
-	if (!_TIFFMergeFieldInfo(tif, zipFieldInfo,
-				 TIFFArrayCount(zipFieldInfo))) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-			     "Merging Deflate codec-specific tags failed");
-		return 0;
-	}
-
-	/*
-	 * Allocate state block so tag methods have storage to record values.
-	 */
-	tif->tif_data = (tidata_t) _TIFFmalloc(sizeof (ZIPState));
-	if (tif->tif_data == NULL)
-		goto bad;
-	sp = ZState(tif);
-	sp->stream.zalloc = NULL;
-	sp->stream.zfree = NULL;
-	sp->stream.opaque = NULL;
-	sp->stream.data_type = Z_BINARY;
-
-	/*
-	 * Override parent get/set field methods.
-	 */
-	sp->vgetparent = tif->tif_tagmethods.vgetfield;
-	tif->tif_tagmethods.vgetfield = ZIPVGetField; /* hook for codec tags */
-	sp->vsetparent = tif->tif_tagmethods.vsetfield;
-	tif->tif_tagmethods.vsetfield = ZIPVSetField; /* hook for codec tags */
-
-	/* Default values for codec-specific fields */
-	sp->zipquality = Z_DEFAULT_COMPRESSION;	/* default comp. level */
-	sp->state = 0;
-
-	/*
-	 * Install codec methods.
-	 */
-	tif->tif_setupdecode = ZIPSetupDecode;
-	tif->tif_predecode = ZIPPreDecode;
-	tif->tif_decoderow = ZIPDecode;
-	tif->tif_decodestrip = ZIPDecode;
-	tif->tif_decodetile = ZIPDecode;
-	tif->tif_setupencode = ZIPSetupEncode;
-	tif->tif_preencode = ZIPPreEncode;
-	tif->tif_postencode = ZIPPostEncode;
-	tif->tif_encoderow = ZIPEncode;
-	tif->tif_encodestrip = ZIPEncode;
-	tif->tif_encodetile = ZIPEncode;
-	tif->tif_cleanup = ZIPCleanup;
-	/*
-	 * Setup predictor setup.
-	 */
-	(void) TIFFPredictorInit(tif);
-	return (1);
-bad:
-	TIFFErrorExt(tif->tif_clientdata, module,
-		     "No space for ZIP state block");
-	return (0);
-}
-#endif /* ZIP_SUPORT */
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tiff.h b/Source/LibTIFF/tiff.h
deleted file mode 100644
index b007af9..0000000
--- a/Source/LibTIFF/tiff.h
+++ /dev/null
@@ -1,654 +0,0 @@
-/* $Id: tiff.h,v 1.38 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-#ifndef _TIFF_
-#define	_TIFF_
-
-#include "tif_config.h"
-
-/*
- * Tag Image File Format (TIFF)
- *
- * Based on Rev 6.0 from:
- *    Developer's Desk
- *    Aldus Corporation
- *    411 First Ave. South
- *    Suite 200
- *    Seattle, WA  98104
- *    206-622-5500
- *    
- *    (http://partners.adobe.com/asn/developer/PDFS/TN/TIFF6.pdf)
- *
- * For Big TIFF design notes see the following link
- *    http://www.remotesensing.org/libtiff/bigtiffdesign.html
- */
-#define	TIFF_VERSION	        42
-#define TIFF_BIGTIFF_VERSION    43
-
-#define	TIFF_BIGENDIAN		0x4d4d
-#define	TIFF_LITTLEENDIAN	0x4949
-#define	MDI_LITTLEENDIAN        0x5045
-#define	MDI_BIGENDIAN           0x4550
-/*
- * Intrinsic data types required by the file format:
- *
- * 8-bit quantities	int8/uint8
- * 16-bit quantities	int16/uint16
- * 32-bit quantities	int32/uint32
- * strings		unsigned char*
- */
-
-#ifndef HAVE_INT8
-typedef	signed char int8;	/* NB: non-ANSI compilers may not grok */
-#endif
-typedef	unsigned char uint8;
-#ifndef HAVE_INT16
-typedef	short int16;
-#endif
-typedef	unsigned short uint16;	/* sizeof (uint16) must == 2 */
-#if SIZEOF_INT == 4
-#ifndef HAVE_INT32
-typedef	int int32;
-#endif
-typedef	unsigned int uint32;	/* sizeof (uint32) must == 4 */
-#elif SIZEOF_LONG == 4
-#ifndef HAVE_INT32
-typedef	long int32;
-#endif
-typedef	unsigned long uint32;	/* sizeof (uint32) must == 4 */
-#endif
-
-/* For TIFFReassignTagToIgnore */
-enum TIFFIgnoreSense /* IGNORE tag table */
-{
-	TIS_STORE,
-	TIS_EXTRACT,
-	TIS_EMPTY
-};
-
-/*
- * TIFF header.
- */
-typedef	struct {
-	uint16	tiff_magic;	/* magic number (defines byte order) */
-#define TIFF_MAGIC_SIZE		2
-	uint16	tiff_version;	/* TIFF version number */
-#define TIFF_VERSION_SIZE	2
-	uint32	tiff_diroff;	/* byte offset to first directory */
-#define TIFF_DIROFFSET_SIZE	4
-} TIFFHeader;
-
-
-/*
- * TIFF Image File Directories are comprised of a table of field
- * descriptors of the form shown below.  The table is sorted in
- * ascending order by tag.  The values associated with each entry are
- * disjoint and may appear anywhere in the file (so long as they are
- * placed on a word boundary).
- *
- * If the value is 4 bytes or less, then it is placed in the offset
- * field to save space.  If the value is less than 4 bytes, it is
- * left-justified in the offset field.
- */
-typedef	struct {
-	uint16		tdir_tag;	/* see below */
-	uint16		tdir_type;	/* data type; see below */
-	uint32		tdir_count;	/* number of items; length in spec */
-	uint32		tdir_offset;	/* byte offset to field data */
-} TIFFDirEntry;
-
-/*
- * NB: In the comments below,
- *  - items marked with a + are obsoleted by revision 5.0,
- *  - items marked with a ! are introduced in revision 6.0.
- *  - items marked with a % are introduced post revision 6.0.
- *  - items marked with a $ are obsoleted by revision 6.0.
- *  - items marked with a & are introduced by Adobe DNG specification.
- */
-
-/*
- * Tag data type information.
- *
- * Note: RATIONALs are the ratio of two 32-bit integer values.
- */
-typedef	enum {
-	TIFF_NOTYPE	= 0,	/* placeholder */
-	TIFF_BYTE	= 1,	/* 8-bit unsigned integer */
-	TIFF_ASCII	= 2,	/* 8-bit bytes w/ last byte null */
-	TIFF_SHORT	= 3,	/* 16-bit unsigned integer */
-	TIFF_LONG	= 4,	/* 32-bit unsigned integer */
-	TIFF_RATIONAL	= 5,	/* 64-bit unsigned fraction */
-	TIFF_SBYTE	= 6,	/* !8-bit signed integer */
-	TIFF_UNDEFINED	= 7,	/* !8-bit untyped data */
-	TIFF_SSHORT	= 8,	/* !16-bit signed integer */
-	TIFF_SLONG	= 9,	/* !32-bit signed integer */
-	TIFF_SRATIONAL	= 10,	/* !64-bit signed fraction */
-	TIFF_FLOAT	= 11,	/* !32-bit IEEE floating point */
-	TIFF_DOUBLE	= 12,	/* !64-bit IEEE floating point */
-	TIFF_IFD	= 13	/* %32-bit unsigned integer (offset) */
-} TIFFDataType;
-
-/*
- * TIFF Tag Definitions.
- */
-#define	TIFFTAG_SUBFILETYPE		254	/* subfile data descriptor */
-#define	    FILETYPE_REDUCEDIMAGE	0x1	/* reduced resolution version */
-#define	    FILETYPE_PAGE		0x2	/* one page of many */
-#define	    FILETYPE_MASK		0x4	/* transparency mask */
-#define	TIFFTAG_OSUBFILETYPE		255	/* +kind of data in subfile */
-#define	    OFILETYPE_IMAGE		1	/* full resolution image data */
-#define	    OFILETYPE_REDUCEDIMAGE	2	/* reduced size image data */
-#define	    OFILETYPE_PAGE		3	/* one page of many */
-#define	TIFFTAG_IMAGEWIDTH		256	/* image width in pixels */
-#define	TIFFTAG_IMAGELENGTH		257	/* image height in pixels */
-#define	TIFFTAG_BITSPERSAMPLE		258	/* bits per channel (sample) */
-#define	TIFFTAG_COMPRESSION		259	/* data compression technique */
-#define	    COMPRESSION_NONE		1	/* dump mode */
-#define	    COMPRESSION_CCITTRLE	2	/* CCITT modified Huffman RLE */
-#define	    COMPRESSION_CCITTFAX3	3	/* CCITT Group 3 fax encoding */
-#define     COMPRESSION_CCITT_T4        3       /* CCITT T.4 (TIFF 6 name) */
-#define	    COMPRESSION_CCITTFAX4	4	/* CCITT Group 4 fax encoding */
-#define     COMPRESSION_CCITT_T6        4       /* CCITT T.6 (TIFF 6 name) */
-#define	    COMPRESSION_LZW		5       /* Lempel-Ziv  & Welch */
-#define	    COMPRESSION_OJPEG		6	/* !6.0 JPEG */
-#define	    COMPRESSION_JPEG		7	/* %JPEG DCT compression */
-#define	    COMPRESSION_NEXT		32766	/* NeXT 2-bit RLE */
-#define	    COMPRESSION_CCITTRLEW	32771	/* #1 w/ word alignment */
-#define	    COMPRESSION_PACKBITS	32773	/* Macintosh RLE */
-#define	    COMPRESSION_THUNDERSCAN	32809	/* ThunderScan RLE */
-/* codes 32895-32898 are reserved for ANSI IT8 TIFF/IT <dkelly at apago.com) */
-#define	    COMPRESSION_IT8CTPAD	32895   /* IT8 CT w/padding */
-#define	    COMPRESSION_IT8LW		32896   /* IT8 Linework RLE */
-#define	    COMPRESSION_IT8MP		32897   /* IT8 Monochrome picture */
-#define	    COMPRESSION_IT8BL		32898   /* IT8 Binary line art */
-/* compression codes 32908-32911 are reserved for Pixar */
-#define     COMPRESSION_PIXARFILM	32908   /* Pixar companded 10bit LZW */
-#define	    COMPRESSION_PIXARLOG	32909   /* Pixar companded 11bit ZIP */
-#define	    COMPRESSION_DEFLATE		32946	/* Deflate compression */
-#define     COMPRESSION_ADOBE_DEFLATE   8       /* Deflate compression,
-						   as recognized by Adobe */
-/* compression code 32947 is reserved for Oceana Matrix <dev at oceana.com> */
-#define     COMPRESSION_DCS             32947   /* Kodak DCS encoding */
-#define	    COMPRESSION_JBIG		34661	/* ISO JBIG */
-#define     COMPRESSION_SGILOG		34676	/* SGI Log Luminance RLE */
-#define     COMPRESSION_SGILOG24	34677	/* SGI Log 24-bit packed */
-#define     COMPRESSION_JP2000          34712   /* Leadtools JPEG2000 */
-#define	TIFFTAG_PHOTOMETRIC		262	/* photometric interpretation */
-#define	    PHOTOMETRIC_MINISWHITE	0	/* min value is white */
-#define	    PHOTOMETRIC_MINISBLACK	1	/* min value is black */
-#define	    PHOTOMETRIC_RGB		2	/* RGB color model */
-#define	    PHOTOMETRIC_PALETTE		3	/* color map indexed */
-#define	    PHOTOMETRIC_MASK		4	/* $holdout mask */
-#define	    PHOTOMETRIC_SEPARATED	5	/* !color separations */
-#define	    PHOTOMETRIC_YCBCR		6	/* !CCIR 601 */
-#define	    PHOTOMETRIC_CIELAB		8	/* !1976 CIE L*a*b* */
-#define	    PHOTOMETRIC_ICCLAB		9	/* ICC L*a*b* [Adobe TIFF Technote 4] */
-#define	    PHOTOMETRIC_ITULAB		10	/* ITU L*a*b* */
-#define     PHOTOMETRIC_LOGL		32844	/* CIE Log2(L) */
-#define     PHOTOMETRIC_LOGLUV		32845	/* CIE Log2(L) (u',v') */
-#define	TIFFTAG_THRESHHOLDING		263	/* +thresholding used on data */
-#define	    THRESHHOLD_BILEVEL		1	/* b&w art scan */
-#define	    THRESHHOLD_HALFTONE		2	/* or dithered scan */
-#define	    THRESHHOLD_ERRORDIFFUSE	3	/* usually floyd-steinberg */
-#define	TIFFTAG_CELLWIDTH		264	/* +dithering matrix width */
-#define	TIFFTAG_CELLLENGTH		265	/* +dithering matrix height */
-#define	TIFFTAG_FILLORDER		266	/* data order within a byte */
-#define	    FILLORDER_MSB2LSB		1	/* most significant -> least */
-#define	    FILLORDER_LSB2MSB		2	/* least significant -> most */
-#define	TIFFTAG_DOCUMENTNAME		269	/* name of doc. image is from */
-#define	TIFFTAG_IMAGEDESCRIPTION	270	/* info about image */
-#define	TIFFTAG_MAKE			271	/* scanner manufacturer name */
-#define	TIFFTAG_MODEL			272	/* scanner model name/number */
-#define	TIFFTAG_STRIPOFFSETS		273	/* offsets to data strips */
-#define	TIFFTAG_ORIENTATION		274	/* +image orientation */
-#define	    ORIENTATION_TOPLEFT		1	/* row 0 top, col 0 lhs */
-#define	    ORIENTATION_TOPRIGHT	2	/* row 0 top, col 0 rhs */
-#define	    ORIENTATION_BOTRIGHT	3	/* row 0 bottom, col 0 rhs */
-#define	    ORIENTATION_BOTLEFT		4	/* row 0 bottom, col 0 lhs */
-#define	    ORIENTATION_LEFTTOP		5	/* row 0 lhs, col 0 top */
-#define	    ORIENTATION_RIGHTTOP	6	/* row 0 rhs, col 0 top */
-#define	    ORIENTATION_RIGHTBOT	7	/* row 0 rhs, col 0 bottom */
-#define	    ORIENTATION_LEFTBOT		8	/* row 0 lhs, col 0 bottom */
-#define	TIFFTAG_SAMPLESPERPIXEL		277	/* samples per pixel */
-#define	TIFFTAG_ROWSPERSTRIP		278	/* rows per strip of data */
-#define	TIFFTAG_STRIPBYTECOUNTS		279	/* bytes counts for strips */
-#define	TIFFTAG_MINSAMPLEVALUE		280	/* +minimum sample value */
-#define	TIFFTAG_MAXSAMPLEVALUE		281	/* +maximum sample value */
-#define	TIFFTAG_XRESOLUTION		282	/* pixels/resolution in x */
-#define	TIFFTAG_YRESOLUTION		283	/* pixels/resolution in y */
-#define	TIFFTAG_PLANARCONFIG		284	/* storage organization */
-#define	    PLANARCONFIG_CONTIG		1	/* single image plane */
-#define	    PLANARCONFIG_SEPARATE	2	/* separate planes of data */
-#define	TIFFTAG_PAGENAME		285	/* page name image is from */
-#define	TIFFTAG_XPOSITION		286	/* x page offset of image lhs */
-#define	TIFFTAG_YPOSITION		287	/* y page offset of image lhs */
-#define	TIFFTAG_FREEOFFSETS		288	/* +byte offset to free block */
-#define	TIFFTAG_FREEBYTECOUNTS		289	/* +sizes of free blocks */
-#define	TIFFTAG_GRAYRESPONSEUNIT	290	/* $gray scale curve accuracy */
-#define	    GRAYRESPONSEUNIT_10S	1	/* tenths of a unit */
-#define	    GRAYRESPONSEUNIT_100S	2	/* hundredths of a unit */
-#define	    GRAYRESPONSEUNIT_1000S	3	/* thousandths of a unit */
-#define	    GRAYRESPONSEUNIT_10000S	4	/* ten-thousandths of a unit */
-#define	    GRAYRESPONSEUNIT_100000S	5	/* hundred-thousandths */
-#define	TIFFTAG_GRAYRESPONSECURVE	291	/* $gray scale response curve */
-#define	TIFFTAG_GROUP3OPTIONS		292	/* 32 flag bits */
-#define	TIFFTAG_T4OPTIONS		292	/* TIFF 6.0 proper name alias */
-#define	    GROUP3OPT_2DENCODING	0x1	/* 2-dimensional coding */
-#define	    GROUP3OPT_UNCOMPRESSED	0x2	/* data not compressed */
-#define	    GROUP3OPT_FILLBITS		0x4	/* fill to byte boundary */
-#define	TIFFTAG_GROUP4OPTIONS		293	/* 32 flag bits */
-#define TIFFTAG_T6OPTIONS               293     /* TIFF 6.0 proper name */
-#define	    GROUP4OPT_UNCOMPRESSED	0x2	/* data not compressed */
-#define	TIFFTAG_RESOLUTIONUNIT		296	/* units of resolutions */
-#define	    RESUNIT_NONE		1	/* no meaningful units */
-#define	    RESUNIT_INCH		2	/* english */
-#define	    RESUNIT_CENTIMETER		3	/* metric */
-#define	TIFFTAG_PAGENUMBER		297	/* page numbers of multi-page */
-#define	TIFFTAG_COLORRESPONSEUNIT	300	/* $color curve accuracy */
-#define	    COLORRESPONSEUNIT_10S	1	/* tenths of a unit */
-#define	    COLORRESPONSEUNIT_100S	2	/* hundredths of a unit */
-#define	    COLORRESPONSEUNIT_1000S	3	/* thousandths of a unit */
-#define	    COLORRESPONSEUNIT_10000S	4	/* ten-thousandths of a unit */
-#define	    COLORRESPONSEUNIT_100000S	5	/* hundred-thousandths */
-#define	TIFFTAG_TRANSFERFUNCTION	301	/* !colorimetry info */
-#define	TIFFTAG_SOFTWARE		305	/* name & release */
-#define	TIFFTAG_DATETIME		306	/* creation date and time */
-#define	TIFFTAG_ARTIST			315	/* creator of image */
-#define	TIFFTAG_HOSTCOMPUTER		316	/* machine where created */
-#define	TIFFTAG_PREDICTOR		317	/* prediction scheme w/ LZW */
-#define     PREDICTOR_NONE		1	/* no prediction scheme used */
-#define     PREDICTOR_HORIZONTAL	2	/* horizontal differencing */
-#define     PREDICTOR_FLOATINGPOINT	3	/* floating point predictor */
-#define	TIFFTAG_WHITEPOINT		318	/* image white point */
-#define	TIFFTAG_PRIMARYCHROMATICITIES	319	/* !primary chromaticities */
-#define	TIFFTAG_COLORMAP		320	/* RGB map for pallette image */
-#define	TIFFTAG_HALFTONEHINTS		321	/* !highlight+shadow info */
-#define	TIFFTAG_TILEWIDTH		322	/* !tile width in pixels */
-#define	TIFFTAG_TILELENGTH		323	/* !tile height in pixels */
-#define TIFFTAG_TILEOFFSETS		324	/* !offsets to data tiles */
-#define TIFFTAG_TILEBYTECOUNTS		325	/* !byte counts for tiles */
-#define	TIFFTAG_BADFAXLINES		326	/* lines w/ wrong pixel count */
-#define	TIFFTAG_CLEANFAXDATA		327	/* regenerated line info */
-#define	    CLEANFAXDATA_CLEAN		0	/* no errors detected */
-#define	    CLEANFAXDATA_REGENERATED	1	/* receiver regenerated lines */
-#define	    CLEANFAXDATA_UNCLEAN	2	/* uncorrected errors exist */
-#define	TIFFTAG_CONSECUTIVEBADFAXLINES	328	/* max consecutive bad lines */
-#define	TIFFTAG_SUBIFD			330	/* subimage descriptors */
-#define	TIFFTAG_INKSET			332	/* !inks in separated image */
-#define	    INKSET_CMYK			1	/* !cyan-magenta-yellow-black color */
-#define	    INKSET_MULTIINK		2	/* !multi-ink or hi-fi color */
-#define	TIFFTAG_INKNAMES		333	/* !ascii names of inks */
-#define	TIFFTAG_NUMBEROFINKS		334	/* !number of inks */
-#define	TIFFTAG_DOTRANGE		336	/* !0% and 100% dot codes */
-#define	TIFFTAG_TARGETPRINTER		337	/* !separation target */
-#define	TIFFTAG_EXTRASAMPLES		338	/* !info about extra samples */
-#define	    EXTRASAMPLE_UNSPECIFIED	0	/* !unspecified data */
-#define	    EXTRASAMPLE_ASSOCALPHA	1	/* !associated alpha data */
-#define	    EXTRASAMPLE_UNASSALPHA	2	/* !unassociated alpha data */
-#define	TIFFTAG_SAMPLEFORMAT		339	/* !data sample format */
-#define	    SAMPLEFORMAT_UINT		1	/* !unsigned integer data */
-#define	    SAMPLEFORMAT_INT		2	/* !signed integer data */
-#define	    SAMPLEFORMAT_IEEEFP		3	/* !IEEE floating point data */
-#define	    SAMPLEFORMAT_VOID		4	/* !untyped data */
-#define	    SAMPLEFORMAT_COMPLEXINT	5	/* !complex signed int */
-#define	    SAMPLEFORMAT_COMPLEXIEEEFP	6	/* !complex ieee floating */
-#define	TIFFTAG_SMINSAMPLEVALUE		340	/* !variable MinSampleValue */
-#define	TIFFTAG_SMAXSAMPLEVALUE		341	/* !variable MaxSampleValue */
-#define	TIFFTAG_CLIPPATH		343	/* %ClipPath
-						   [Adobe TIFF technote 2] */
-#define	TIFFTAG_XCLIPPATHUNITS		344	/* %XClipPathUnits
-						   [Adobe TIFF technote 2] */
-#define	TIFFTAG_YCLIPPATHUNITS		345	/* %YClipPathUnits
-						   [Adobe TIFF technote 2] */
-#define	TIFFTAG_INDEXED			346	/* %Indexed
-						   [Adobe TIFF Technote 3] */
-#define	TIFFTAG_JPEGTABLES		347	/* %JPEG table stream */
-#define	TIFFTAG_OPIPROXY		351	/* %OPI Proxy [Adobe TIFF technote] */
-/*
- * Tags 512-521 are obsoleted by Technical Note #2 which specifies a
- * revised JPEG-in-TIFF scheme.
- */
-#define	TIFFTAG_JPEGPROC		512	/* !JPEG processing algorithm */
-#define	    JPEGPROC_BASELINE		1	/* !baseline sequential */
-#define	    JPEGPROC_LOSSLESS		14	/* !Huffman coded lossless */
-#define	TIFFTAG_JPEGIFOFFSET		513	/* !pointer to SOI marker */
-#define	TIFFTAG_JPEGIFBYTECOUNT		514	/* !JFIF stream length */
-#define	TIFFTAG_JPEGRESTARTINTERVAL	515	/* !restart interval length */
-#define	TIFFTAG_JPEGLOSSLESSPREDICTORS	517	/* !lossless proc predictor */
-#define	TIFFTAG_JPEGPOINTTRANSFORM	518	/* !lossless point transform */
-#define	TIFFTAG_JPEGQTABLES		519	/* !Q matrice offsets */
-#define	TIFFTAG_JPEGDCTABLES		520	/* !DCT table offsets */
-#define	TIFFTAG_JPEGACTABLES		521	/* !AC coefficient offsets */
-#define	TIFFTAG_YCBCRCOEFFICIENTS	529	/* !RGB -> YCbCr transform */
-#define	TIFFTAG_YCBCRSUBSAMPLING	530	/* !YCbCr subsampling factors */
-#define	TIFFTAG_YCBCRPOSITIONING	531	/* !subsample positioning */
-#define	    YCBCRPOSITION_CENTERED	1	/* !as in PostScript Level 2 */
-#define	    YCBCRPOSITION_COSITED	2	/* !as in CCIR 601-1 */
-#define	TIFFTAG_REFERENCEBLACKWHITE	532	/* !colorimetry info */
-#define	TIFFTAG_XMLPACKET		700	/* %XML packet
-						   [Adobe XMP Specification,
-						   January 2004 */
-#define TIFFTAG_OPIIMAGEID		32781	/* %OPI ImageID
-						   [Adobe TIFF technote] */
-/* tags 32952-32956 are private tags registered to Island Graphics */
-#define TIFFTAG_REFPTS			32953	/* image reference points */
-#define TIFFTAG_REGIONTACKPOINT		32954	/* region-xform tack point */
-#define TIFFTAG_REGIONWARPCORNERS	32955	/* warp quadrilateral */
-#define TIFFTAG_REGIONAFFINE		32956	/* affine transformation mat */
-/* tags 32995-32999 are private tags registered to SGI */
-#define	TIFFTAG_MATTEING		32995	/* $use ExtraSamples */
-#define	TIFFTAG_DATATYPE		32996	/* $use SampleFormat */
-#define	TIFFTAG_IMAGEDEPTH		32997	/* z depth of image */
-#define	TIFFTAG_TILEDEPTH		32998	/* z depth/data tile */
-/* tags 33300-33309 are private tags registered to Pixar */
-/*
- * TIFFTAG_PIXAR_IMAGEFULLWIDTH and TIFFTAG_PIXAR_IMAGEFULLLENGTH
- * are set when an image has been cropped out of a larger image.  
- * They reflect the size of the original uncropped image.
- * The TIFFTAG_XPOSITION and TIFFTAG_YPOSITION can be used
- * to determine the position of the smaller image in the larger one.
- */
-#define TIFFTAG_PIXAR_IMAGEFULLWIDTH    33300   /* full image size in x */
-#define TIFFTAG_PIXAR_IMAGEFULLLENGTH   33301   /* full image size in y */
- /* Tags 33302-33306 are used to identify special image modes and data
-  * used by Pixar's texture formats.
-  */
-#define TIFFTAG_PIXAR_TEXTUREFORMAT	33302	/* texture map format */
-#define TIFFTAG_PIXAR_WRAPMODES		33303	/* s & t wrap modes */
-#define TIFFTAG_PIXAR_FOVCOT		33304	/* cotan(fov) for env. maps */
-#define TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN 33305
-#define TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA 33306
-/* tag 33405 is a private tag registered to Eastman Kodak */
-#define TIFFTAG_WRITERSERIALNUMBER      33405   /* device serial number */
-/* tag 33432 is listed in the 6.0 spec w/ unknown ownership */
-#define	TIFFTAG_COPYRIGHT		33432	/* copyright string */
-/* IPTC TAG from RichTIFF specifications */
-#define TIFFTAG_RICHTIFFIPTC		33723
-/* 34016-34029 are reserved for ANSI IT8 TIFF/IT <dkelly at apago.com) */
-#define TIFFTAG_IT8SITE			34016	/* site name */
-#define TIFFTAG_IT8COLORSEQUENCE	34017	/* color seq. [RGB,CMYK,etc] */
-#define TIFFTAG_IT8HEADER		34018	/* DDES Header */
-#define TIFFTAG_IT8RASTERPADDING	34019	/* raster scanline padding */
-#define TIFFTAG_IT8BITSPERRUNLENGTH	34020	/* # of bits in short run */
-#define TIFFTAG_IT8BITSPEREXTENDEDRUNLENGTH 34021/* # of bits in long run */
-#define TIFFTAG_IT8COLORTABLE		34022	/* LW colortable */
-#define TIFFTAG_IT8IMAGECOLORINDICATOR	34023	/* BP/BL image color switch */
-#define TIFFTAG_IT8BKGCOLORINDICATOR	34024	/* BP/BL bg color switch */
-#define TIFFTAG_IT8IMAGECOLORVALUE	34025	/* BP/BL image color value */
-#define TIFFTAG_IT8BKGCOLORVALUE	34026	/* BP/BL bg color value */
-#define TIFFTAG_IT8PIXELINTENSITYRANGE	34027	/* MP pixel intensity value */
-#define TIFFTAG_IT8TRANSPARENCYINDICATOR 34028	/* HC transparency switch */
-#define TIFFTAG_IT8COLORCHARACTERIZATION 34029	/* color character. table */
-#define TIFFTAG_IT8HCUSAGE		34030	/* HC usage indicator */
-#define TIFFTAG_IT8TRAPINDICATOR	34031	/* Trapping indicator
-						   (untrapped=0, trapped=1) */
-#define TIFFTAG_IT8CMYKEQUIVALENT	34032	/* CMYK color equivalents */
-/* tags 34232-34236 are private tags registered to Texas Instruments */
-#define TIFFTAG_FRAMECOUNT              34232   /* Sequence Frame Count */
-/* tag 34377 is private tag registered to Adobe for PhotoShop */
-#define TIFFTAG_PHOTOSHOP		34377 
-/* tags 34665, 34853 and 40965 are documented in EXIF specification */
-#define TIFFTAG_EXIFIFD			34665	/* Pointer to EXIF private directory */
-/* tag 34750 is a private tag registered to Adobe? */
-#define TIFFTAG_ICCPROFILE		34675	/* ICC profile data */
-/* tag 34750 is a private tag registered to Pixel Magic */
-#define	TIFFTAG_JBIGOPTIONS		34750	/* JBIG options */
-#define TIFFTAG_GPSIFD			34853	/* Pointer to GPS private directory */
-/* tags 34908-34914 are private tags registered to SGI */
-#define	TIFFTAG_FAXRECVPARAMS		34908	/* encoded Class 2 ses. parms */
-#define	TIFFTAG_FAXSUBADDRESS		34909	/* received SubAddr string */
-#define	TIFFTAG_FAXRECVTIME		34910	/* receive time (secs) */
-#define	TIFFTAG_FAXDCS			34911	/* encoded fax ses. params, Table 2/T.30 */
-/* tags 37439-37443 are registered to SGI <gregl at sgi.com> */
-#define TIFFTAG_STONITS			37439	/* Sample value to Nits */
-/* tag 34929 is a private tag registered to FedEx */
-#define	TIFFTAG_FEDEX_EDR		34929	/* unknown use */
-#define TIFFTAG_INTEROPERABILITYIFD	40965	/* Pointer to Interoperability private directory */
-/* Adobe Digital Negative (DNG) format tags */
-#define TIFFTAG_DNGVERSION		50706	/* &DNG version number */
-#define TIFFTAG_DNGBACKWARDVERSION	50707	/* &DNG compatibility version */
-#define TIFFTAG_UNIQUECAMERAMODEL	50708	/* &name for the camera model */
-#define TIFFTAG_LOCALIZEDCAMERAMODEL	50709	/* &localized camera model
-						   name */
-#define TIFFTAG_CFAPLANECOLOR		50710	/* &CFAPattern->LinearRaw space
-						   mapping */
-#define TIFFTAG_CFALAYOUT		50711	/* &spatial layout of the CFA */
-#define TIFFTAG_LINEARIZATIONTABLE	50712	/* &lookup table description */
-#define TIFFTAG_BLACKLEVELREPEATDIM	50713	/* &repeat pattern size for
-						   the BlackLevel tag */
-#define TIFFTAG_BLACKLEVEL		50714	/* &zero light encoding level */
-#define TIFFTAG_BLACKLEVELDELTAH	50715	/* &zero light encoding level
-						   differences (columns) */
-#define TIFFTAG_BLACKLEVELDELTAV	50716	/* &zero light encoding level
-						   differences (rows) */
-#define TIFFTAG_WHITELEVEL		50717	/* &fully saturated encoding
-						   level */
-#define TIFFTAG_DEFAULTSCALE		50718	/* &default scale factors */
-#define TIFFTAG_DEFAULTCROPORIGIN	50719	/* &origin of the final image
-						   area */
-#define TIFFTAG_DEFAULTCROPSIZE		50720	/* &size of the final image 
-						   area */
-#define TIFFTAG_COLORMATRIX1		50721	/* &XYZ->reference color space
-						   transformation matrix 1 */
-#define TIFFTAG_COLORMATRIX2		50722	/* &XYZ->reference color space
-						   transformation matrix 2 */
-#define TIFFTAG_CAMERACALIBRATION1	50723	/* &calibration matrix 1 */
-#define TIFFTAG_CAMERACALIBRATION2	50724	/* &calibration matrix 2 */
-#define TIFFTAG_REDUCTIONMATRIX1	50725	/* &dimensionality reduction
-						   matrix 1 */
-#define TIFFTAG_REDUCTIONMATRIX2	50726	/* &dimensionality reduction
-						   matrix 2 */
-#define TIFFTAG_ANALOGBALANCE		50727	/* &gain applied the stored raw
-						   values*/
-#define TIFFTAG_ASSHOTNEUTRAL		50728	/* &selected white balance in
-						   linear reference space */
-#define TIFFTAG_ASSHOTWHITEXY		50729	/* &selected white balance in
-						   x-y chromaticity
-						   coordinates */
-#define TIFFTAG_BASELINEEXPOSURE	50730	/* &how much to move the zero
-						   point */
-#define TIFFTAG_BASELINENOISE		50731	/* &relative noise level */
-#define TIFFTAG_BASELINESHARPNESS	50732	/* &relative amount of
-						   sharpening */
-#define TIFFTAG_BAYERGREENSPLIT		50733	/* &how closely the values of
-						   the green pixels in the
-						   blue/green rows track the
-						   values of the green pixels
-						   in the red/green rows */
-#define TIFFTAG_LINEARRESPONSELIMIT	50734	/* &non-linear encoding range */
-#define TIFFTAG_CAMERASERIALNUMBER	50735	/* &camera's serial number */
-#define TIFFTAG_LENSINFO		50736	/* info about the lens */
-#define TIFFTAG_CHROMABLURRADIUS	50737	/* &chroma blur radius */
-#define TIFFTAG_ANTIALIASSTRENGTH	50738	/* &relative strength of the
-						   camera's anti-alias filter */
-#define TIFFTAG_SHADOWSCALE		50739	/* &used by Adobe Camera Raw */
-#define TIFFTAG_DNGPRIVATEDATA		50740	/* &manufacturer's private data */
-#define TIFFTAG_MAKERNOTESAFETY		50741	/* &whether the EXIF MakerNote
-						   tag is safe to preserve
-						   along with the rest of the
-						   EXIF data */
-#define	TIFFTAG_CALIBRATIONILLUMINANT1	50778	/* &illuminant 1 */
-#define TIFFTAG_CALIBRATIONILLUMINANT2	50779	/* &illuminant 2 */
-#define TIFFTAG_BESTQUALITYSCALE	50780	/* &best quality multiplier */
-#define TIFFTAG_RAWDATAUNIQUEID		50781	/* &unique identifier for
-						   the raw image data */
-#define TIFFTAG_ORIGINALRAWFILENAME	50827	/* &file name of the original
-						   raw file */
-#define TIFFTAG_ORIGINALRAWFILEDATA	50828	/* &contents of the original
-						   raw file */
-#define TIFFTAG_ACTIVEAREA		50829	/* &active (non-masked) pixels
-						   of the sensor */
-#define TIFFTAG_MASKEDAREAS		50830	/* &list of coordinates
-						   of fully masked pixels */
-#define TIFFTAG_ASSHOTICCPROFILE	50831	/* &these two tags used to */
-#define TIFFTAG_ASSHOTPREPROFILEMATRIX	50832	/* map cameras's color space
-						   into ICC profile space */
-#define TIFFTAG_CURRENTICCPROFILE	50833	/* & */
-#define TIFFTAG_CURRENTPREPROFILEMATRIX	50834	/* & */
-/* tag 65535 is an undefined tag used by Eastman Kodak */
-#define TIFFTAG_DCSHUESHIFTVALUES       65535   /* hue shift correction data */
-
-/*
- * The following are ``pseudo tags'' that can be used to control
- * codec-specific functionality.  These tags are not written to file.
- * Note that these values start at 0xffff+1 so that they'll never
- * collide with Aldus-assigned tags.
- *
- * If you want your private pseudo tags ``registered'' (i.e. added to
- * this file), please post a bug report via the tracking system at
- * http://www.remotesensing.org/libtiff/bugs.html with the appropriate
- * C definitions to add.
- */
-#define	TIFFTAG_FAXMODE			65536	/* Group 3/4 format control */
-#define	    FAXMODE_CLASSIC	0x0000		/* default, include RTC */
-#define	    FAXMODE_NORTC	0x0001		/* no RTC at end of data */
-#define	    FAXMODE_NOEOL	0x0002		/* no EOL code at end of row */
-#define	    FAXMODE_BYTEALIGN	0x0004		/* byte align row */
-#define	    FAXMODE_WORDALIGN	0x0008		/* word align row */
-#define	    FAXMODE_CLASSF	FAXMODE_NORTC	/* TIFF Class F */
-#define	TIFFTAG_JPEGQUALITY		65537	/* Compression quality level */
-/* Note: quality level is on the IJG 0-100 scale.  Default value is 75 */
-#define	TIFFTAG_JPEGCOLORMODE		65538	/* Auto RGB<=>YCbCr convert? */
-#define	    JPEGCOLORMODE_RAW	0x0000		/* no conversion (default) */
-#define	    JPEGCOLORMODE_RGB	0x0001		/* do auto conversion */
-#define	TIFFTAG_JPEGTABLESMODE		65539	/* What to put in JPEGTables */
-#define	    JPEGTABLESMODE_QUANT 0x0001		/* include quantization tbls */
-#define	    JPEGTABLESMODE_HUFF	0x0002		/* include Huffman tbls */
-/* Note: default is JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF */
-#define	TIFFTAG_FAXFILLFUNC		65540	/* G3/G4 fill function */
-#define	TIFFTAG_PIXARLOGDATAFMT		65549	/* PixarLogCodec I/O data sz */
-#define	    PIXARLOGDATAFMT_8BIT	0	/* regular u_char samples */
-#define	    PIXARLOGDATAFMT_8BITABGR	1	/* ABGR-order u_chars */
-#define	    PIXARLOGDATAFMT_11BITLOG	2	/* 11-bit log-encoded (raw) */
-#define	    PIXARLOGDATAFMT_12BITPICIO	3	/* as per PICIO (1.0==2048) */
-#define	    PIXARLOGDATAFMT_16BIT	4	/* signed short samples */
-#define	    PIXARLOGDATAFMT_FLOAT	5	/* IEEE float samples */
-/* 65550-65556 are allocated to Oceana Matrix <dev at oceana.com> */
-#define TIFFTAG_DCSIMAGERTYPE           65550   /* imager model & filter */
-#define     DCSIMAGERMODEL_M3           0       /* M3 chip (1280 x 1024) */
-#define     DCSIMAGERMODEL_M5           1       /* M5 chip (1536 x 1024) */
-#define     DCSIMAGERMODEL_M6           2       /* M6 chip (3072 x 2048) */
-#define     DCSIMAGERFILTER_IR          0       /* infrared filter */
-#define     DCSIMAGERFILTER_MONO        1       /* monochrome filter */
-#define     DCSIMAGERFILTER_CFA         2       /* color filter array */
-#define     DCSIMAGERFILTER_OTHER       3       /* other filter */
-#define TIFFTAG_DCSINTERPMODE           65551   /* interpolation mode */
-#define     DCSINTERPMODE_NORMAL        0x0     /* whole image, default */
-#define     DCSINTERPMODE_PREVIEW       0x1     /* preview of image (384x256) */
-#define TIFFTAG_DCSBALANCEARRAY         65552   /* color balance values */
-#define TIFFTAG_DCSCORRECTMATRIX        65553   /* color correction values */
-#define TIFFTAG_DCSGAMMA                65554   /* gamma value */
-#define TIFFTAG_DCSTOESHOULDERPTS       65555   /* toe & shoulder points */
-#define TIFFTAG_DCSCALIBRATIONFD        65556   /* calibration file desc */
-/* Note: quality level is on the ZLIB 1-9 scale. Default value is -1 */
-#define	TIFFTAG_ZIPQUALITY		65557	/* compression quality level */
-#define	TIFFTAG_PIXARLOGQUALITY		65558	/* PixarLog uses same scale */
-/* 65559 is allocated to Oceana Matrix <dev at oceana.com> */
-#define TIFFTAG_DCSCLIPRECTANGLE	65559	/* area of image to acquire */
-#define TIFFTAG_SGILOGDATAFMT		65560	/* SGILog user data format */
-#define     SGILOGDATAFMT_FLOAT		0	/* IEEE float samples */
-#define     SGILOGDATAFMT_16BIT		1	/* 16-bit samples */
-#define     SGILOGDATAFMT_RAW		2	/* uninterpreted data */
-#define     SGILOGDATAFMT_8BIT		3	/* 8-bit RGB monitor values */
-#define TIFFTAG_SGILOGENCODE		65561 /* SGILog data encoding control*/
-#define     SGILOGENCODE_NODITHER	0     /* do not dither encoded values*/
-#define     SGILOGENCODE_RANDITHER	1     /* randomly dither encd values */
-
-/*
- * EXIF tags
- */
-#define EXIFTAG_EXPOSURETIME		33434	/* Exposure time */
-#define EXIFTAG_FNUMBER			33437	/* F number */
-#define EXIFTAG_EXPOSUREPROGRAM		34850	/* Exposure program */
-#define EXIFTAG_SPECTRALSENSITIVITY	34852	/* Spectral sensitivity */
-#define EXIFTAG_ISOSPEEDRATINGS		34855	/* ISO speed rating */
-#define EXIFTAG_OECF			34856	/* Optoelectric conversion
-						   factor */
-#define EXIFTAG_EXIFVERSION		36864	/* Exif version */
-#define EXIFTAG_DATETIMEORIGINAL	36867	/* Date and time of original
-						   data generation */
-#define EXIFTAG_DATETIMEDIGITIZED	36868	/* Date and time of digital
-						   data generation */
-#define EXIFTAG_COMPONENTSCONFIGURATION	37121	/* Meaning of each component */
-#define EXIFTAG_COMPRESSEDBITSPERPIXEL	37122	/* Image compression mode */
-#define EXIFTAG_SHUTTERSPEEDVALUE	37377	/* Shutter speed */
-#define EXIFTAG_APERTUREVALUE		37378	/* Aperture */
-#define EXIFTAG_BRIGHTNESSVALUE		37379	/* Brightness */
-#define EXIFTAG_EXPOSUREBIASVALUE	37380	/* Exposure bias */
-#define EXIFTAG_MAXAPERTUREVALUE	37381	/* Maximum lens aperture */
-#define EXIFTAG_SUBJECTDISTANCE		37382	/* Subject distance */
-#define EXIFTAG_METERINGMODE		37383	/* Metering mode */
-#define EXIFTAG_LIGHTSOURCE		37384	/* Light source */
-#define EXIFTAG_FLASH			37385	/* Flash */
-#define EXIFTAG_FOCALLENGTH		37386	/* Lens focal length */
-#define EXIFTAG_SUBJECTAREA		37396	/* Subject area */
-#define EXIFTAG_MAKERNOTE		37500	/* Manufacturer notes */
-#define EXIFTAG_USERCOMMENT		37510	/* User comments */
-#define EXIFTAG_SUBSECTIME		37520	/* DateTime subseconds */
-#define EXIFTAG_SUBSECTIMEORIGINAL	37521	/* DateTimeOriginal subseconds */
-#define EXIFTAG_SUBSECTIMEDIGITIZED	37522	/* DateTimeDigitized subseconds */
-#define EXIFTAG_FLASHPIXVERSION		40960	/* Supported Flashpix version */
-#define EXIFTAG_COLORSPACE		40961	/* Color space information */
-#define EXIFTAG_PIXELXDIMENSION		40962	/* Valid image width */
-#define EXIFTAG_PIXELYDIMENSION		40963	/* Valid image height */
-#define EXIFTAG_RELATEDSOUNDFILE	40964	/* Related audio file */
-#define EXIFTAG_FLASHENERGY		41483	/* Flash energy */
-#define EXIFTAG_SPATIALFREQUENCYRESPONSE 41484	/* Spatial frequency response */
-#define EXIFTAG_FOCALPLANEXRESOLUTION	41486	/* Focal plane X resolution */
-#define EXIFTAG_FOCALPLANEYRESOLUTION	41487	/* Focal plane Y resolution */
-#define EXIFTAG_FOCALPLANERESOLUTIONUNIT 41488	/* Focal plane resolution unit */
-#define EXIFTAG_SUBJECTLOCATION		41492	/* Subject location */
-#define EXIFTAG_EXPOSUREINDEX		41493	/* Exposure index */
-#define EXIFTAG_SENSINGMETHOD		41495	/* Sensing method */
-#define EXIFTAG_FILESOURCE		41728	/* File source */
-#define EXIFTAG_SCENETYPE		41729	/* Scene type */
-#define EXIFTAG_CFAPATTERN		41730	/* CFA pattern */
-#define EXIFTAG_CUSTOMRENDERED		41985	/* Custom image processing */
-#define EXIFTAG_EXPOSUREMODE		41986	/* Exposure mode */
-#define EXIFTAG_WHITEBALANCE		41987	/* White balance */
-#define EXIFTAG_DIGITALZOOMRATIO	41988	/* Digital zoom ratio */
-#define EXIFTAG_FOCALLENGTHIN35MMFILM	41989	/* Focal length in 35 mm film */
-#define EXIFTAG_SCENECAPTURETYPE	41990	/* Scene capture type */
-#define EXIFTAG_GAINCONTROL		41991	/* Gain control */
-#define EXIFTAG_CONTRAST		41992	/* Contrast */
-#define EXIFTAG_SATURATION		41993	/* Saturation */
-#define EXIFTAG_SHARPNESS		41994	/* Sharpness */
-#define EXIFTAG_DEVICESETTINGDESCRIPTION 41995	/* Device settings description */
-#define EXIFTAG_SUBJECTDISTANCERANGE	41996	/* Subject distance range */
-#define EXIFTAG_GAINCONTROL		41991	/* Gain control */
-#define EXIFTAG_GAINCONTROL		41991	/* Gain control */
-#define EXIFTAG_IMAGEUNIQUEID		42016	/* Unique image ID */
-
-#endif /* _TIFF_ */
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tiffconf.h-vms b/Source/LibTIFF/tiffconf.h-vms
deleted file mode 100644
index de717ec..0000000
--- a/Source/LibTIFF/tiffconf.h-vms
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
-  Configuration defines for installed libtiff.
-  This file maintained for backward compatibility. Do not use definitions
-  from this file in your programs.
-*/
-
-#ifndef _TIFFCONF_
-#define _TIFFCONF_
-
-/* Define to 1 if the system has the type `int16'. */
-//#define HAVE_INT16 
-
-/* Define to 1 if the system has the type `int32'. */
-//#define  HAVE_INT32 
-
-/* Define to 1 if the system has the type `int8'. */
-//#define HAVE_INT8 
-
-/* The size of a `int', as computed by sizeof. */
-#define SIZEOF_INT 4
-
-/* The size of a `long', as computed by sizeof. */
-#define SIZEOF_LONG 4
-
-/* Compatibility stuff. */
-
-/* Define as 0 or 1 according to the floating point format suported by the
-   machine */
-#define HAVE_IEEEFP 1
-
-#define HAVE_GETOPT 1
-
-/* Set the native cpu bit order (FILLORDER_LSB2MSB or FILLORDER_MSB2LSB) */
-#define HOST_FILLORDER FILLORDER_LSB2MSB
-
-/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian
-   (Intel) */
-#define HOST_BIGENDIAN 0
-
-/* Support CCITT Group 3 & 4 algorithms */
-#define CCITT_SUPPORT 1
-
-/* Support JPEG compression (requires IJG JPEG library) */
-#define JPEG_SUPPORT 
-
-/* Support LogLuv high dynamic range encoding */
-#define LOGLUV_SUPPORT 1
-
-/* Support LZW algorithm */
-#define LZW_SUPPORT 1
-
-/* Support NeXT 2-bit RLE algorithm */
-#define NEXT_SUPPORT 1
-
-/* Support Old JPEG compresson (read contrib/ojpeg/README first! Compilation
-   fails with unpatched IJG JPEG library) */
-/* #undef OJPEG_SUPPORT */
-
-/* Support Macintosh PackBits algorithm */
-#define PACKBITS_SUPPORT 1
-
-/* Support Pixar log-format algorithm (requires Zlib) */
-/* #undef PIXARLOG_SUPPORT */
-
-/* Support ThunderScan 4-bit RLE algorithm */
-#define THUNDER_SUPPORT 1
-
-/* Support Deflate compression */
-/* #undef ZIP_SUPPORT */
-
-/* Support strip chopping (whether or not to convert single-strip uncompressed
-   images to mutiple strips of ~8Kb to reduce memory usage) */
-#define STRIPCHOP_DEFAULT TIFF_STRIPCHOP
-
-/* Enable SubIFD tag (330) support */
-#define SUBIFD_SUPPORT 1
-
-/* Treat extra sample as alpha (default enabled). The RGBA interface will
-   treat a fourth sample with no EXTRASAMPLE_ value as being ASSOCALPHA. Many
-   packages produce RGBA files but don't mark the alpha properly. */
-#define DEFAULT_EXTRASAMPLE_AS_ALPHA 1
-
-/* Pick up YCbCr subsampling info from the JPEG data stream to support files
-   lacking the tag (default enabled). */
-#define CHECK_JPEG_YCBCR_SUBSAMPLING 1
-
-/*
- * Feature support definitions.
- * XXX: These macros are obsoleted. Don't use them in your apps!
- * Macros stays here for backward compatibility and should be always defined.
- */
-#define COLORIMETRY_SUPPORT
-#define YCBCR_SUPPORT
-#define CMYK_SUPPORT
-#define ICC_SUPPORT
-#define PHOTOSHOP_SUPPORT
-#define IPTC_SUPPORT
-
-#endif /* _TIFFCONF_ */
diff --git a/Source/LibTIFF/tiffconf.h.in b/Source/LibTIFF/tiffconf.h.in
deleted file mode 100644
index 88544d5..0000000
--- a/Source/LibTIFF/tiffconf.h.in
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
-  Configuration defines for installed libtiff.
-  This file maintained for backward compatibility. Do not use definitions
-  from this file in your programs.
-*/
-
-#ifndef _TIFFCONF_
-#define _TIFFCONF_
-
-/* Define to 1 if the system has the type `int16'. */
-#undef HAVE_INT16
-
-/* Define to 1 if the system has the type `int32'. */
-#undef HAVE_INT32
-
-/* Define to 1 if the system has the type `int8'. */
-#undef HAVE_INT8
-
-/* The size of a `int', as computed by sizeof. */
-#undef SIZEOF_INT
-
-/* The size of a `long', as computed by sizeof. */
-#undef SIZEOF_LONG
-
-/* Compatibility stuff. */
-
-/* Define as 0 or 1 according to the floating point format suported by the
-   machine */
-#undef HAVE_IEEEFP
-
-/* Set the native cpu bit order (FILLORDER_LSB2MSB or FILLORDER_MSB2LSB) */
-#undef HOST_FILLORDER
-
-/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian
-   (Intel) */
-#undef HOST_BIGENDIAN
-
-/* Support CCITT Group 3 & 4 algorithms */
-#undef CCITT_SUPPORT
-
-/* Support JPEG compression (requires IJG JPEG library) */
-#undef JPEG_SUPPORT
-
-/* Support JBIG compression (requires JBIG-KIT library) */
-#undef JBIG_SUPPORT
-
-/* Support LogLuv high dynamic range encoding */
-#undef LOGLUV_SUPPORT
-
-/* Support LZW algorithm */
-#undef LZW_SUPPORT
-
-/* Support NeXT 2-bit RLE algorithm */
-#undef NEXT_SUPPORT
-
-/* Support Old JPEG compresson (read contrib/ojpeg/README first! Compilation
-   fails with unpatched IJG JPEG library) */
-#undef OJPEG_SUPPORT
-
-/* Support Macintosh PackBits algorithm */
-#undef PACKBITS_SUPPORT
-
-/* Support Pixar log-format algorithm (requires Zlib) */
-#undef PIXARLOG_SUPPORT
-
-/* Support ThunderScan 4-bit RLE algorithm */
-#undef THUNDER_SUPPORT
-
-/* Support Deflate compression */
-#undef ZIP_SUPPORT
-
-/* Support strip chopping (whether or not to convert single-strip uncompressed
-   images to mutiple strips of ~8Kb to reduce memory usage) */
-#undef STRIPCHOP_DEFAULT
-
-/* Enable SubIFD tag (330) support */
-#undef SUBIFD_SUPPORT
-
-/* Treat extra sample as alpha (default enabled). The RGBA interface will
-   treat a fourth sample with no EXTRASAMPLE_ value as being ASSOCALPHA. Many
-   packages produce RGBA files but don't mark the alpha properly. */
-#undef DEFAULT_EXTRASAMPLE_AS_ALPHA
-
-/* Pick up YCbCr subsampling info from the JPEG data stream to support files
-   lacking the tag (default enabled). */
-#undef CHECK_JPEG_YCBCR_SUBSAMPLING
-
-/* Support MS MDI magic number files as TIFF */
-#undef MDI_SUPPORT
-
-/*
- * Feature support definitions.
- * XXX: These macros are obsoleted. Don't use them in your apps!
- * Macros stays here for backward compatibility and should be always defined.
- */
-#define COLORIMETRY_SUPPORT
-#define YCBCR_SUPPORT
-#define CMYK_SUPPORT
-#define ICC_SUPPORT
-#define PHOTOSHOP_SUPPORT
-#define IPTC_SUPPORT
-
-#endif /* _TIFFCONF_ */
diff --git a/Source/LibTIFF/tiffconf.vc.h b/Source/LibTIFF/tiffconf.vc.h
deleted file mode 100644
index 3d14847..0000000
--- a/Source/LibTIFF/tiffconf.vc.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
-  Configuration defines for installed libtiff.
-  This file maintained for backward compatibility. Do not use definitions
-  from this file in your programs.
-*/
-
-#ifndef _TIFFCONF_
-#define _TIFFCONF_
-
-/* Define to 1 if the system has the type `int16'. */
-/* #undef HAVE_INT16 */
-
-/* Define to 1 if the system has the type `int32'. */
-/* #undef HAVE_INT32 */
-
-/* Define to 1 if the system has the type `int8'. */
-/* #undef HAVE_INT8 */
-
-/* The size of a `int', as computed by sizeof. */
-#define SIZEOF_INT 4
-
-/* The size of a `long', as computed by sizeof. */
-#define SIZEOF_LONG 4
-
-/* Signed 64-bit type formatter */
-#define TIFF_INT64_FORMAT "%I64d"
-
-/* Signed 64-bit type */
-#define TIFF_INT64_T signed __int64
-
-/* Unsigned 64-bit type formatter */
-#define TIFF_UINT64_FORMAT "%I64u"
-
-/* Unsigned 64-bit type */
-#define TIFF_UINT64_T unsigned __int64
-
-/* Compatibility stuff. */
-
-/* Define as 0 or 1 according to the floating point format suported by the
-   machine */
-#define HAVE_IEEEFP 1
-
-/* Set the native cpu bit order (FILLORDER_LSB2MSB or FILLORDER_MSB2LSB) */
-#define HOST_FILLORDER FILLORDER_LSB2MSB
-
-/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian
-   (Intel) */
-#define HOST_BIGENDIAN 0
-
-/* Support CCITT Group 3 & 4 algorithms */
-#define CCITT_SUPPORT 1
-
-/* Support JPEG compression (requires IJG JPEG library) */
-/* #undef JPEG_SUPPORT */
-
-/* Support LogLuv high dynamic range encoding */
-#define LOGLUV_SUPPORT 1
-
-/* Support LZW algorithm */
-#define LZW_SUPPORT 1
-
-/* Support NeXT 2-bit RLE algorithm */
-#define NEXT_SUPPORT 1
-
-/* Support Old JPEG compresson (read contrib/ojpeg/README first! Compilation
-   fails with unpatched IJG JPEG library) */
-/* #undef OJPEG_SUPPORT */
-
-/* Support Macintosh PackBits algorithm */
-#define PACKBITS_SUPPORT 1
-
-/* Support Pixar log-format algorithm (requires Zlib) */
-/* #undef PIXARLOG_SUPPORT */
-
-/* Support ThunderScan 4-bit RLE algorithm */
-#define THUNDER_SUPPORT 1
-
-/* Support Deflate compression */
-/* #undef ZIP_SUPPORT */
-
-/* Support strip chopping (whether or not to convert single-strip uncompressed
-   images to mutiple strips of ~8Kb to reduce memory usage) */
-#define STRIPCHOP_DEFAULT TIFF_STRIPCHOP
-
-/* Enable SubIFD tag (330) support */
-#define SUBIFD_SUPPORT 1
-
-/* Treat extra sample as alpha (default enabled). The RGBA interface will
-   treat a fourth sample with no EXTRASAMPLE_ value as being ASSOCALPHA. Many
-   packages produce RGBA files but don't mark the alpha properly. */
-#define DEFAULT_EXTRASAMPLE_AS_ALPHA 1
-
-/* Pick up YCbCr subsampling info from the JPEG data stream to support files
-   lacking the tag (default enabled). */
-#define CHECK_JPEG_YCBCR_SUBSAMPLING 1
-
-/*
- * Feature support definitions.
- * XXX: These macros are obsoleted. Don't use them in your apps!
- * Macros stays here for backward compatibility and should be always defined.
- */
-#define COLORIMETRY_SUPPORT
-#define YCBCR_SUPPORT
-#define CMYK_SUPPORT
-#define ICC_SUPPORT
-#define PHOTOSHOP_SUPPORT
-#define IPTC_SUPPORT
-
-#endif /* _TIFFCONF_ */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tiffconf.wince.h b/Source/LibTIFF/tiffconf.wince.h
deleted file mode 100644
index 557fc1f..0000000
--- a/Source/LibTIFF/tiffconf.wince.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/* $Id: tiffconf.wince.h,v 1.21 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Windows CE platform tiffconf.wince.h
- * Created by Mateusz Loskot (mateusz at loskot.net)
- *
- * NOTE: Requires WCELIBCEX library with wceex_* functions,
- * It's an extension to C library on Windows CE platform.
- * For example, HAVE_STDIO_H definition indicates there are
- * following files available:
- * stdio.h - from Windows CE / Windows Mobile SDK 
- * wce_stdio.h - from WCELIBCEX library
- */
-
-
-/*
-  Configuration defines for installed libtiff.
-  This file maintained for backward compatibility. Do not use definitions
-  from this file in your programs.
-*/
-
-#ifndef _WIN32_WCE
-# error This version of tif_config.h header is dedicated for Windows CE platform!
-#endif
-
-
-#ifndef _TIFFCONF_
-#define _TIFFCONF_
-
-/* Define to 1 if the system has the type `int16'. */
-/* #undef HAVE_INT16 */
-
-/* Define to 1 if the system has the type `int32'. */
-/* #undef HAVE_INT32 */
-
-/* Define to 1 if the system has the type `int8'. */
-/* #undef HAVE_INT8 */
-
-/* The size of a `int', as computed by sizeof. */
-#define SIZEOF_INT 4
-
-/* The size of a `long', as computed by sizeof. */
-#define SIZEOF_LONG 4
-
-/* Signed 64-bit type formatter */
-#define TIFF_INT64_FORMAT "%I64d"
-
-/* Signed 64-bit type */
-#define TIFF_INT64_T signed __int64
-
-/* Unsigned 64-bit type formatter */
-#define TIFF_UINT64_FORMAT "%I64u"
-
-/* Unsigned 64-bit type */
-#define TIFF_UINT64_T unsigned __int64
-
-/* Compatibility stuff. */
-
-/* Define as 0 or 1 according to the floating point format suported by the
-   machine */
-#define HAVE_IEEEFP 1
-
-/* Set the native cpu bit order (FILLORDER_LSB2MSB or FILLORDER_MSB2LSB) */
-#define HOST_FILLORDER FILLORDER_LSB2MSB
-
-/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian
-   (Intel) */
-#define HOST_BIGENDIAN 0
-
-/* Support CCITT Group 3 & 4 algorithms */
-#define CCITT_SUPPORT 1
-
-/* Support JPEG compression (requires IJG JPEG library) */
-/* #undef JPEG_SUPPORT */
-
-/* Support LogLuv high dynamic range encoding */
-#define LOGLUV_SUPPORT 1
-
-/* Support LZW algorithm */
-#define LZW_SUPPORT 1
-
-/* Support NeXT 2-bit RLE algorithm */
-#define NEXT_SUPPORT 1
-
-/* Support Old JPEG compresson (read contrib/ojpeg/README first! Compilation
-   fails with unpatched IJG JPEG library) */
-/* #undef OJPEG_SUPPORT */
-
-/* Support Macintosh PackBits algorithm */
-#define PACKBITS_SUPPORT 1
-
-/* Support Pixar log-format algorithm (requires Zlib) */
-/* #undef PIXARLOG_SUPPORT */
-
-/* Support ThunderScan 4-bit RLE algorithm */
-#define THUNDER_SUPPORT 1
-
-/* Support Deflate compression */
-/* #undef ZIP_SUPPORT */
-
-/* Support strip chopping (whether or not to convert single-strip uncompressed
-   images to mutiple strips of ~8Kb to reduce memory usage) */
-#define STRIPCHOP_DEFAULT TIFF_STRIPCHOP
-
-/* Enable SubIFD tag (330) support */
-#define SUBIFD_SUPPORT 1
-
-/* Treat extra sample as alpha (default enabled). The RGBA interface will
-   treat a fourth sample with no EXTRASAMPLE_ value as being ASSOCALPHA. Many
-   packages produce RGBA files but don't mark the alpha properly. */
-#define DEFAULT_EXTRASAMPLE_AS_ALPHA 1
-
-/* Pick up YCbCr subsampling info from the JPEG data stream to support files
-   lacking the tag (default enabled). */
-#define CHECK_JPEG_YCBCR_SUBSAMPLING 1
-
-/*
- * Feature support definitions.
- * XXX: These macros are obsoleted. Don't use them in your apps!
- * Macros stays here for backward compatibility and should be always defined.
- */
-#define COLORIMETRY_SUPPORT
-#define YCBCR_SUPPORT
-#define CMYK_SUPPORT
-#define ICC_SUPPORT
-#define PHOTOSHOP_SUPPORT
-#define IPTC_SUPPORT
-
-#endif /* _TIFFCONF_ */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tiffio.h b/Source/LibTIFF/tiffio.h
deleted file mode 100644
index d03672f..0000000
--- a/Source/LibTIFF/tiffio.h
+++ /dev/null
@@ -1,526 +0,0 @@
-/* $Id: tiffio.h,v 1.37 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- */
-
-#ifndef _TIFFIO_
-#define	_TIFFIO_
-
-/*
- * TIFF I/O Library Definitions.
- */
-#include "tiff.h"
-#include "tiffvers.h"
-
-/*
- * TIFF is defined as an incomplete type to hide the
- * library's internal data structures from clients.
- */
-typedef	struct tiff TIFF;
-
-/*
- * The following typedefs define the intrinsic size of
- * data types used in the *exported* interfaces.  These
- * definitions depend on the proper definition of types
- * in tiff.h.  Note also that the varargs interface used
- * to pass tag types and values uses the types defined in
- * tiff.h directly.
- *
- * NB: ttag_t is unsigned int and not unsigned short because
- *     ANSI C requires that the type before the ellipsis be a
- *     promoted type (i.e. one of int, unsigned int, pointer,
- *     or double) and because we defined pseudo-tags that are
- *     outside the range of legal Aldus-assigned tags.
- * NB: tsize_t is int32 and not uint32 because some functions
- *     return -1.
- * NB: toff_t is not off_t for many reasons; TIFFs max out at
- *     32-bit file offsets being the most important, and to ensure
- *     that it is unsigned, rather than signed.
- */
-typedef uint32 ttag_t;          /* directory tag */
-typedef uint16 tdir_t;          /* directory index */
-typedef uint16 tsample_t;       /* sample number */
-typedef uint32 tstrile_t;       /* strip or tile number */
-typedef tstrile_t tstrip_t;     /* strip number */
-typedef tstrile_t ttile_t;      /* tile number */
-typedef int32 tsize_t;          /* i/o size in bytes */
-typedef void* tdata_t;          /* image data ref */
-typedef uint32 toff_t;          /* file offset */
-
-#if !defined(__WIN32__) && (defined(_WIN32) || defined(WIN32))
-#define __WIN32__
-#endif
-
-/*
- * On windows you should define USE_WIN32_FILEIO if you are using tif_win32.c
- * or AVOID_WIN32_FILEIO if you are using something else (like tif_unix.c).
- *
- * By default tif_unix.c is assumed.
- */
-
-#if defined(_WINDOWS) || defined(__WIN32__) || defined(_Windows)
-#  if !defined(__CYGWIN) && !defined(AVOID_WIN32_FILEIO) && !defined(USE_WIN32_FILEIO)
-#    define AVOID_WIN32_FILEIO
-#  endif
-#endif
-
-#if defined(USE_WIN32_FILEIO)
-# define VC_EXTRALEAN
-# include <windows.h>
-# ifdef __WIN32__
-DECLARE_HANDLE(thandle_t);	/* Win32 file handle */
-# else
-typedef	HFILE thandle_t;	/* client data handle */
-# endif /* __WIN32__ */
-#else
-typedef	void* thandle_t;	/* client data handle */
-#endif /* USE_WIN32_FILEIO */
-
-/*
- * Flags to pass to TIFFPrintDirectory to control
- * printing of data structures that are potentially
- * very large.   Bit-or these flags to enable printing
- * multiple items.
- */
-#define	TIFFPRINT_NONE		0x0		/* no extra info */
-#define	TIFFPRINT_STRIPS	0x1		/* strips/tiles info */
-#define	TIFFPRINT_CURVES	0x2		/* color/gray response curves */
-#define	TIFFPRINT_COLORMAP	0x4		/* colormap */
-#define	TIFFPRINT_JPEGQTABLES	0x100		/* JPEG Q matrices */
-#define	TIFFPRINT_JPEGACTABLES	0x200		/* JPEG AC tables */
-#define	TIFFPRINT_JPEGDCTABLES	0x200		/* JPEG DC tables */
-
-/* 
- * Colour conversion stuff
- */
-
-/* reference white */
-#define D65_X0 (95.0470F)
-#define D65_Y0 (100.0F)
-#define D65_Z0 (108.8827F)
-
-#define D50_X0 (96.4250F)
-#define D50_Y0 (100.0F)
-#define D50_Z0 (82.4680F)
-
-/* Structure for holding information about a display device. */
-
-typedef	unsigned char TIFFRGBValue;		/* 8-bit samples */
-
-typedef struct {
-	float d_mat[3][3]; 		/* XYZ -> luminance matrix */
-	float d_YCR;			/* Light o/p for reference white */
-	float d_YCG;
-	float d_YCB;
-	uint32 d_Vrwr;			/* Pixel values for ref. white */
-	uint32 d_Vrwg;
-	uint32 d_Vrwb;
-	float d_Y0R;			/* Residual light for black pixel */
-	float d_Y0G;
-	float d_Y0B;
-	float d_gammaR;			/* Gamma values for the three guns */
-	float d_gammaG;
-	float d_gammaB;
-} TIFFDisplay;
-
-typedef struct {				/* YCbCr->RGB support */
-	TIFFRGBValue* clamptab;			/* range clamping table */
-	int*	Cr_r_tab;
-	int*	Cb_b_tab;
-	int32*	Cr_g_tab;
-	int32*	Cb_g_tab;
-        int32*  Y_tab;
-} TIFFYCbCrToRGB;
-
-typedef struct {				/* CIE Lab 1976->RGB support */
-	int	range;				/* Size of conversion table */
-#define CIELABTORGB_TABLE_RANGE 1500
-	float	rstep, gstep, bstep;
-	float	X0, Y0, Z0;			/* Reference white point */
-	TIFFDisplay display;
-	float	Yr2r[CIELABTORGB_TABLE_RANGE + 1];  /* Conversion of Yr to r */
-	float	Yg2g[CIELABTORGB_TABLE_RANGE + 1];  /* Conversion of Yg to g */
-	float	Yb2b[CIELABTORGB_TABLE_RANGE + 1];  /* Conversion of Yb to b */
-} TIFFCIELabToRGB;
-
-/*
- * RGBA-style image support.
- */
-typedef struct _TIFFRGBAImage TIFFRGBAImage;
-/*
- * The image reading and conversion routines invoke
- * ``put routines'' to copy/image/whatever tiles of
- * raw image data.  A default set of routines are 
- * provided to convert/copy raw image data to 8-bit
- * packed ABGR format rasters.  Applications can supply
- * alternate routines that unpack the data into a
- * different format or, for example, unpack the data
- * and draw the unpacked raster on the display.
- */
-typedef void (*tileContigRoutine)
-    (TIFFRGBAImage*, uint32*, uint32, uint32, uint32, uint32, int32, int32,
-	unsigned char*);
-typedef void (*tileSeparateRoutine)
-    (TIFFRGBAImage*, uint32*, uint32, uint32, uint32, uint32, int32, int32,
-	unsigned char*, unsigned char*, unsigned char*, unsigned char*);
-/*
- * RGBA-reader state.
- */
-struct _TIFFRGBAImage {
-	TIFF* tif;                              /* image handle */
-	int stoponerr;                          /* stop on read error */
-	int isContig;                           /* data is packed/separate */
-	int alpha;                              /* type of alpha data present */
-	uint32 width;                           /* image width */
-	uint32 height;                          /* image height */
-	uint16 bitspersample;                   /* image bits/sample */
-	uint16 samplesperpixel;                 /* image samples/pixel */
-	uint16 orientation;                     /* image orientation */
-	uint16 req_orientation;                 /* requested orientation */
-	uint16 photometric;                     /* image photometric interp */
-	uint16* redcmap;                        /* colormap pallete */
-	uint16* greencmap;
-	uint16* bluecmap;
-	/* get image data routine */
-	int (*get)(TIFFRGBAImage*, uint32*, uint32, uint32);
-	/* put decoded strip/tile */
-	union {
-	    void (*any)(TIFFRGBAImage*);
-	    tileContigRoutine contig;
-	    tileSeparateRoutine separate;
-	} put;
-	TIFFRGBValue* Map;                      /* sample mapping array */
-	uint32** BWmap;                         /* black&white map */
-	uint32** PALmap;                        /* palette image map */
-	TIFFYCbCrToRGB* ycbcr;                  /* YCbCr conversion state */
-	TIFFCIELabToRGB* cielab;                /* CIE L*a*b conversion state */
-
-	int row_offset;
-	int col_offset;
-};
-
-/*
- * Macros for extracting components from the
- * packed ABGR form returned by TIFFReadRGBAImage.
- */
-#define	TIFFGetR(abgr)	((abgr) & 0xff)
-#define	TIFFGetG(abgr)	(((abgr) >> 8) & 0xff)
-#define	TIFFGetB(abgr)	(((abgr) >> 16) & 0xff)
-#define	TIFFGetA(abgr)	(((abgr) >> 24) & 0xff)
-
-/*
- * A CODEC is a software package that implements decoding,
- * encoding, or decoding+encoding of a compression algorithm.
- * The library provides a collection of builtin codecs.
- * More codecs may be registered through calls to the library
- * and/or the builtin implementations may be overridden.
- */
-typedef	int (*TIFFInitMethod)(TIFF*, int);
-typedef struct {
-	char*		name;
-	uint16		scheme;
-	TIFFInitMethod	init;
-} TIFFCodec;
-
-#include <stdio.h>
-#include <stdarg.h>
-
-/* share internal LogLuv conversion routines? */
-#ifndef LOGLUV_PUBLIC
-#define LOGLUV_PUBLIC		1
-#endif
-
-#if !defined(__GNUC__) && !defined(__attribute__)
-#  define __attribute__(x) /*nothing*/
-#endif
-
-#if defined(c_plusplus) || defined(__cplusplus)
-extern "C" {
-#endif
-typedef	void (*TIFFErrorHandler)(const char*, const char*, va_list);
-typedef	void (*TIFFErrorHandlerExt)(thandle_t, const char*, const char*, va_list);
-typedef	tsize_t (*TIFFReadWriteProc)(thandle_t, tdata_t, tsize_t);
-typedef	toff_t (*TIFFSeekProc)(thandle_t, toff_t, int);
-typedef	int (*TIFFCloseProc)(thandle_t);
-typedef	toff_t (*TIFFSizeProc)(thandle_t);
-typedef	int (*TIFFMapFileProc)(thandle_t, tdata_t*, toff_t*);
-typedef	void (*TIFFUnmapFileProc)(thandle_t, tdata_t, toff_t);
-typedef	void (*TIFFExtendProc)(TIFF*); 
-
-extern	const char* TIFFGetVersion(void);
-
-extern	const TIFFCodec* TIFFFindCODEC(uint16);
-extern	TIFFCodec* TIFFRegisterCODEC(uint16, const char*, TIFFInitMethod);
-extern	void TIFFUnRegisterCODEC(TIFFCodec*);
-extern  int TIFFIsCODECConfigured(uint16);
-extern	TIFFCodec* TIFFGetConfiguredCODECs(void);
-
-/*
- * Auxiliary functions.
- */
-
-extern	tdata_t _TIFFmalloc(tsize_t);
-extern	tdata_t _TIFFrealloc(tdata_t, tsize_t);
-extern	void _TIFFmemset(tdata_t, int, tsize_t);
-extern	void _TIFFmemcpy(tdata_t, const tdata_t, tsize_t);
-extern	int _TIFFmemcmp(const tdata_t, const tdata_t, tsize_t);
-extern	void _TIFFfree(tdata_t);
-
-/*
-** Stuff, related to tag handling and creating custom tags.
-*/
-extern  int  TIFFGetTagListCount( TIFF * );
-extern  ttag_t TIFFGetTagListEntry( TIFF *, int tag_index );
-    
-#define	TIFF_ANY	TIFF_NOTYPE	/* for field descriptor searching */
-#define	TIFF_VARIABLE	-1		/* marker for variable length tags */
-#define	TIFF_SPP	-2		/* marker for SamplesPerPixel tags */
-#define	TIFF_VARIABLE2	-3		/* marker for uint32 var-length tags */
-
-#define FIELD_CUSTOM    65    
-
-typedef	struct {
-	ttag_t	field_tag;		/* field's tag */
-	short	field_readcount;	/* read count/TIFF_VARIABLE/TIFF_SPP */
-	short	field_writecount;	/* write count/TIFF_VARIABLE */
-	TIFFDataType field_type;	/* type of associated data */
-        unsigned short field_bit;	/* bit in fieldsset bit vector */
-	unsigned char field_oktochange;	/* if true, can change while writing */
-	unsigned char field_passcount;	/* if true, pass dir count on set */
-	char	*field_name;		/* ASCII name */
-} TIFFFieldInfo;
-
-typedef struct _TIFFTagValue {
-    const TIFFFieldInfo  *info;
-    int             count;
-    void           *value;
-} TIFFTagValue;
-
-extern	void TIFFMergeFieldInfo(TIFF*, const TIFFFieldInfo[], int);
-extern	const TIFFFieldInfo* TIFFFindFieldInfo(TIFF*, ttag_t, TIFFDataType);
-extern  const TIFFFieldInfo* TIFFFindFieldInfoByName(TIFF* , const char *,
-						     TIFFDataType);
-extern	const TIFFFieldInfo* TIFFFieldWithTag(TIFF*, ttag_t);
-extern	const TIFFFieldInfo* TIFFFieldWithName(TIFF*, const char *);
-
-typedef	int (*TIFFVSetMethod)(TIFF*, ttag_t, va_list);
-typedef	int (*TIFFVGetMethod)(TIFF*, ttag_t, va_list);
-typedef	void (*TIFFPrintMethod)(TIFF*, FILE*, long);
-    
-typedef struct {
-    TIFFVSetMethod	vsetfield;	/* tag set routine */
-    TIFFVGetMethod	vgetfield;	/* tag get routine */
-    TIFFPrintMethod	printdir;	/* directory print routine */
-} TIFFTagMethods;
-        
-extern  TIFFTagMethods *TIFFAccessTagMethods( TIFF * );
-extern  void *TIFFGetClientInfo( TIFF *, const char * );
-extern  void TIFFSetClientInfo( TIFF *, void *, const char * );
-
-extern	void TIFFCleanup(TIFF*);
-extern	void TIFFClose(TIFF*);
-extern	int TIFFFlush(TIFF*);
-extern	int TIFFFlushData(TIFF*);
-extern	int TIFFGetField(TIFF*, ttag_t, ...);
-extern	int TIFFVGetField(TIFF*, ttag_t, va_list);
-extern	int TIFFGetFieldDefaulted(TIFF*, ttag_t, ...);
-extern	int TIFFVGetFieldDefaulted(TIFF*, ttag_t, va_list);
-extern	int TIFFReadDirectory(TIFF*);
-extern	int TIFFReadCustomDirectory(TIFF*, toff_t, const TIFFFieldInfo[],
-				    size_t);
-extern	int TIFFReadEXIFDirectory(TIFF*, toff_t);
-extern	tsize_t TIFFScanlineSize(TIFF*);
-extern	tsize_t TIFFOldScanlineSize(TIFF*);
-extern	tsize_t TIFFNewScanlineSize(TIFF*);
-extern	tsize_t TIFFRasterScanlineSize(TIFF*);
-extern	tsize_t TIFFStripSize(TIFF*);
-extern	tsize_t TIFFRawStripSize(TIFF*, tstrip_t);
-extern	tsize_t TIFFVStripSize(TIFF*, uint32);
-extern	tsize_t TIFFTileRowSize(TIFF*);
-extern	tsize_t TIFFTileSize(TIFF*);
-extern	tsize_t TIFFVTileSize(TIFF*, uint32);
-extern	uint32 TIFFDefaultStripSize(TIFF*, uint32);
-extern	void TIFFDefaultTileSize(TIFF*, uint32*, uint32*);
-extern	int TIFFFileno(TIFF*);
-extern  int TIFFSetFileno(TIFF*, int);
-extern  thandle_t TIFFClientdata(TIFF*);
-extern  thandle_t TIFFSetClientdata(TIFF*, thandle_t);
-extern	int TIFFGetMode(TIFF*);
-extern	int TIFFSetMode(TIFF*, int);
-extern	int TIFFIsTiled(TIFF*);
-extern	int TIFFIsByteSwapped(TIFF*);
-extern	int TIFFIsUpSampled(TIFF*);
-extern	int TIFFIsMSB2LSB(TIFF*);
-extern	int TIFFIsBigEndian(TIFF*);
-extern	TIFFReadWriteProc TIFFGetReadProc(TIFF*);
-extern	TIFFReadWriteProc TIFFGetWriteProc(TIFF*);
-extern	TIFFSeekProc TIFFGetSeekProc(TIFF*);
-extern	TIFFCloseProc TIFFGetCloseProc(TIFF*);
-extern	TIFFSizeProc TIFFGetSizeProc(TIFF*);
-extern	TIFFMapFileProc TIFFGetMapFileProc(TIFF*);
-extern	TIFFUnmapFileProc TIFFGetUnmapFileProc(TIFF*);
-extern	uint32 TIFFCurrentRow(TIFF*);
-extern	tdir_t TIFFCurrentDirectory(TIFF*);
-extern	tdir_t TIFFNumberOfDirectories(TIFF*);
-extern	uint32 TIFFCurrentDirOffset(TIFF*);
-extern	tstrip_t TIFFCurrentStrip(TIFF*);
-extern	ttile_t TIFFCurrentTile(TIFF*);
-extern	int TIFFReadBufferSetup(TIFF*, tdata_t, tsize_t);
-extern	int TIFFWriteBufferSetup(TIFF*, tdata_t, tsize_t);
-extern	int TIFFSetupStrips(TIFF *);
-extern  int TIFFWriteCheck(TIFF*, int, const char *);
-extern	void TIFFFreeDirectory(TIFF*);
-extern  int TIFFCreateDirectory(TIFF*);
-extern	int TIFFLastDirectory(TIFF*);
-extern	int TIFFSetDirectory(TIFF*, tdir_t);
-extern	int TIFFSetSubDirectory(TIFF*, uint32);
-extern	int TIFFUnlinkDirectory(TIFF*, tdir_t);
-extern	int TIFFSetField(TIFF*, ttag_t, ...);
-extern	int TIFFVSetField(TIFF*, ttag_t, va_list);
-extern	int TIFFWriteDirectory(TIFF *);
-extern	int TIFFCheckpointDirectory(TIFF *);
-extern	int TIFFRewriteDirectory(TIFF *);
-extern	int TIFFReassignTagToIgnore(enum TIFFIgnoreSense, int);
-
-#if defined(c_plusplus) || defined(__cplusplus)
-extern	void TIFFPrintDirectory(TIFF*, FILE*, long = 0);
-extern	int TIFFReadScanline(TIFF*, tdata_t, uint32, tsample_t = 0);
-extern	int TIFFWriteScanline(TIFF*, tdata_t, uint32, tsample_t = 0);
-extern	int TIFFReadRGBAImage(TIFF*, uint32, uint32, uint32*, int = 0);
-extern	int TIFFReadRGBAImageOriented(TIFF*, uint32, uint32, uint32*,
-				      int = ORIENTATION_BOTLEFT, int = 0);
-#else
-extern	void TIFFPrintDirectory(TIFF*, FILE*, long);
-extern	int TIFFReadScanline(TIFF*, tdata_t, uint32, tsample_t);
-extern	int TIFFWriteScanline(TIFF*, tdata_t, uint32, tsample_t);
-extern	int TIFFReadRGBAImage(TIFF*, uint32, uint32, uint32*, int);
-extern	int TIFFReadRGBAImageOriented(TIFF*, uint32, uint32, uint32*, int, int);
-#endif
-
-extern	int TIFFReadRGBAStrip(TIFF*, tstrip_t, uint32 * );
-extern	int TIFFReadRGBATile(TIFF*, uint32, uint32, uint32 * );
-extern	int TIFFRGBAImageOK(TIFF*, char [1024]);
-extern	int TIFFRGBAImageBegin(TIFFRGBAImage*, TIFF*, int, char [1024]);
-extern	int TIFFRGBAImageGet(TIFFRGBAImage*, uint32*, uint32, uint32);
-extern	void TIFFRGBAImageEnd(TIFFRGBAImage*);
-extern	TIFF* TIFFOpen(const char*, const char*);
-# ifdef __WIN32__
-extern	TIFF* TIFFOpenW(const wchar_t*, const char*);
-# endif /* __WIN32__ */
-extern	TIFF* TIFFFdOpen(int, const char*, const char*);
-extern	TIFF* TIFFClientOpen(const char*, const char*,
-	    thandle_t,
-	    TIFFReadWriteProc, TIFFReadWriteProc,
-	    TIFFSeekProc, TIFFCloseProc,
-	    TIFFSizeProc,
-	    TIFFMapFileProc, TIFFUnmapFileProc);
-extern	const char* TIFFFileName(TIFF*);
-extern	const char* TIFFSetFileName(TIFF*, const char *);
-extern void TIFFError(const char*, const char*, ...) __attribute__((format (printf,2,3)));
-extern void TIFFErrorExt(thandle_t, const char*, const char*, ...) __attribute__((format (printf,3,4)));
-extern void TIFFWarning(const char*, const char*, ...) __attribute__((format (printf,2,3)));
-extern void TIFFWarningExt(thandle_t, const char*, const char*, ...) __attribute__((format (printf,3,4)));
-extern	TIFFErrorHandler TIFFSetErrorHandler(TIFFErrorHandler);
-extern	TIFFErrorHandlerExt TIFFSetErrorHandlerExt(TIFFErrorHandlerExt);
-extern	TIFFErrorHandler TIFFSetWarningHandler(TIFFErrorHandler);
-extern	TIFFErrorHandlerExt TIFFSetWarningHandlerExt(TIFFErrorHandlerExt);
-extern	TIFFExtendProc TIFFSetTagExtender(TIFFExtendProc);
-extern	ttile_t TIFFComputeTile(TIFF*, uint32, uint32, uint32, tsample_t);
-extern	int TIFFCheckTile(TIFF*, uint32, uint32, uint32, tsample_t);
-extern	ttile_t TIFFNumberOfTiles(TIFF*);
-extern	tsize_t TIFFReadTile(TIFF*,
-	    tdata_t, uint32, uint32, uint32, tsample_t);
-extern	tsize_t TIFFWriteTile(TIFF*,
-	    tdata_t, uint32, uint32, uint32, tsample_t);
-extern	tstrip_t TIFFComputeStrip(TIFF*, uint32, tsample_t);
-extern	tstrip_t TIFFNumberOfStrips(TIFF*);
-extern	tsize_t TIFFReadEncodedStrip(TIFF*, tstrip_t, tdata_t, tsize_t);
-extern	tsize_t TIFFReadRawStrip(TIFF*, tstrip_t, tdata_t, tsize_t);
-extern	tsize_t TIFFReadEncodedTile(TIFF*, ttile_t, tdata_t, tsize_t);
-extern	tsize_t TIFFReadRawTile(TIFF*, ttile_t, tdata_t, tsize_t);
-extern	tsize_t TIFFWriteEncodedStrip(TIFF*, tstrip_t, tdata_t, tsize_t);
-extern	tsize_t TIFFWriteRawStrip(TIFF*, tstrip_t, tdata_t, tsize_t);
-extern	tsize_t TIFFWriteEncodedTile(TIFF*, ttile_t, tdata_t, tsize_t);
-extern	tsize_t TIFFWriteRawTile(TIFF*, ttile_t, tdata_t, tsize_t);
-extern	int TIFFDataWidth(TIFFDataType);    /* table of tag datatype widths */
-extern	void TIFFSetWriteOffset(TIFF*, toff_t);
-extern	void TIFFSwabShort(uint16*);
-extern	void TIFFSwabLong(uint32*);
-extern	void TIFFSwabDouble(double*);
-extern	void TIFFSwabArrayOfShort(uint16*, unsigned long);
-extern	void TIFFSwabArrayOfTriples(uint8*, unsigned long);
-extern	void TIFFSwabArrayOfLong(uint32*, unsigned long);
-extern	void TIFFSwabArrayOfDouble(double*, unsigned long);
-extern	void TIFFReverseBits(unsigned char *, unsigned long);
-extern	const unsigned char* TIFFGetBitRevTable(int);
-
-#ifdef LOGLUV_PUBLIC
-#define U_NEU		0.210526316
-#define V_NEU		0.473684211
-#define UVSCALE		410.
-extern	double LogL16toY(int);
-extern	double LogL10toY(int);
-extern	void XYZtoRGB24(float*, uint8*);
-extern	int uv_decode(double*, double*, int);
-extern	void LogLuv24toXYZ(uint32, float*);
-extern	void LogLuv32toXYZ(uint32, float*);
-#if defined(c_plusplus) || defined(__cplusplus)
-extern	int LogL16fromY(double, int = SGILOGENCODE_NODITHER);
-extern	int LogL10fromY(double, int = SGILOGENCODE_NODITHER);
-extern	int uv_encode(double, double, int = SGILOGENCODE_NODITHER);
-extern	uint32 LogLuv24fromXYZ(float*, int = SGILOGENCODE_NODITHER);
-extern	uint32 LogLuv32fromXYZ(float*, int = SGILOGENCODE_NODITHER);
-#else
-extern	int LogL16fromY(double, int);
-extern	int LogL10fromY(double, int);
-extern	int uv_encode(double, double, int);
-extern	uint32 LogLuv24fromXYZ(float*, int);
-extern	uint32 LogLuv32fromXYZ(float*, int);
-#endif
-#endif /* LOGLUV_PUBLIC */
-    
-extern int TIFFCIELabToRGBInit(TIFFCIELabToRGB*, TIFFDisplay *, float*);
-extern void TIFFCIELabToXYZ(TIFFCIELabToRGB *, uint32, int32, int32,
-			    float *, float *, float *);
-extern void TIFFXYZToRGB(TIFFCIELabToRGB *, float, float, float,
-			 uint32 *, uint32 *, uint32 *);
-
-extern int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB*, float*, float*);
-extern void TIFFYCbCrtoRGB(TIFFYCbCrToRGB *, uint32, int32, int32,
-			   uint32 *, uint32 *, uint32 *);
-
-#if defined(c_plusplus) || defined(__cplusplus)
-}
-#endif
-
-#endif /* _TIFFIO_ */
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tiffio.hxx b/Source/LibTIFF/tiffio.hxx
deleted file mode 100644
index fc20d72..0000000
--- a/Source/LibTIFF/tiffio.hxx
+++ /dev/null
@@ -1,49 +0,0 @@
-/* $Id: tiffio.hxx,v 1.32 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-#ifndef _TIFFIO_HXX_
-#define	_TIFFIO_HXX_
-
-/*
- * TIFF I/O library definitions which provide C++ streams API.
- */
-
-#include <iostream>
-#include "tiff.h"
-
-extern	TIFF* TIFFStreamOpen(const char*, std::ostream *);
-extern	TIFF* TIFFStreamOpen(const char*, std::istream *);
-
-#endif /* _TIFFIO_HXX_ */
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c++
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tiffiop.h b/Source/LibTIFF/tiffiop.h
deleted file mode 100644
index c96decf..0000000
--- a/Source/LibTIFF/tiffiop.h
+++ /dev/null
@@ -1,353 +0,0 @@
-/* $Id: tiffiop.h,v 1.37 2011/04/10 17:14:09 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-#ifndef _TIFFIOP_
-#define	_TIFFIOP_
-/*
- * ``Library-private'' definitions.
- */
-
-#include "tif_config.h"
-
-#ifdef HAVE_FCNTL_H
-# include <fcntl.h>
-#endif
-
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-
-#ifdef HAVE_STRING_H
-# include <string.h>
-#endif
-
-#ifdef HAVE_ASSERT_H
-# include <assert.h>
-#else
-# define assert(x) 
-#endif
-
-#ifdef HAVE_SEARCH_H
-# include <search.h>
-#else
-extern void *lfind(const void *, const void *, size_t *, size_t,
-		   int (*)(const void *, const void *));
-#endif
-
-/*
-  Libtiff itself does not require a 64-bit type, but bundled TIFF
-  utilities may use it.  
-*/
-
-#if !defined(__xlC__) && !defined(__xlc__) // Already defined there (#2301)
-#define TIFF_INT64_T signed long long
-#define TIFF_UINT64_T unsigned long long
-#endif
-
-#include "tiffio.h"
-#include "tif_dir.h"
-
-#ifndef STRIP_SIZE_DEFAULT
-# define STRIP_SIZE_DEFAULT 8192
-#endif
-
-#define    streq(a,b)      (strcmp(a,b) == 0)
-
-#ifndef TRUE
-#define	TRUE	1
-#define	FALSE	0
-#endif
-
-typedef struct client_info {
-    struct client_info *next;
-    void      *data;
-    char      *name;
-} TIFFClientInfoLink;
-
-/*
- * Typedefs for ``method pointers'' used internally.
- */
-typedef	unsigned char tidataval_t;	/* internal image data value type */
-typedef	tidataval_t* tidata_t;		/* reference to internal image data */
-
-typedef	void (*TIFFVoidMethod)(TIFF*);
-typedef	int (*TIFFBoolMethod)(TIFF*);
-typedef	int (*TIFFPreMethod)(TIFF*, tsample_t);
-typedef	int (*TIFFCodeMethod)(TIFF*, tidata_t, tsize_t, tsample_t);
-typedef	int (*TIFFSeekMethod)(TIFF*, uint32);
-typedef	void (*TIFFPostMethod)(TIFF*, tidata_t, tsize_t);
-typedef	uint32 (*TIFFStripMethod)(TIFF*, uint32);
-typedef	void (*TIFFTileMethod)(TIFF*, uint32*, uint32*);
-
-struct tiff {
-	char*		tif_name;	/* name of open file */
-	int		tif_fd;		/* open file descriptor */
-	int		tif_mode;	/* open mode (O_*) */
-	uint32		tif_flags;
-#define	TIFF_FILLORDER		0x00003	/* natural bit fill order for machine */
-#define	TIFF_DIRTYHEADER	0x00004	/* header must be written on close */
-#define	TIFF_DIRTYDIRECT	0x00008	/* current directory must be written */
-#define	TIFF_BUFFERSETUP	0x00010	/* data buffers setup */
-#define	TIFF_CODERSETUP		0x00020	/* encoder/decoder setup done */
-#define	TIFF_BEENWRITING	0x00040	/* written 1+ scanlines to file */
-#define	TIFF_SWAB		0x00080	/* byte swap file information */
-#define	TIFF_NOBITREV		0x00100	/* inhibit bit reversal logic */
-#define	TIFF_MYBUFFER		0x00200	/* my raw data buffer; free on close */
-#define	TIFF_ISTILED		0x00400	/* file is tile, not strip- based */
-#define	TIFF_MAPPED		0x00800	/* file is mapped into memory */
-#define	TIFF_POSTENCODE		0x01000	/* need call to postencode routine */
-#define	TIFF_INSUBIFD		0x02000	/* currently writing a subifd */
-#define	TIFF_UPSAMPLED		0x04000	/* library is doing data up-sampling */ 
-#define	TIFF_STRIPCHOP		0x08000	/* enable strip chopping support */
-#define	TIFF_HEADERONLY		0x10000	/* read header only, do not process */
-					/* the first directory */
-#define TIFF_NOREADRAW		0x20000 /* skip reading of raw uncompressed */
-					/* image data */
-#define	TIFF_INCUSTOMIFD	0x40000	/* currently writing a custom IFD */
-	toff_t		tif_diroff;	/* file offset of current directory */
-	toff_t		tif_nextdiroff;	/* file offset of following directory */
-	toff_t*		tif_dirlist;	/* list of offsets to already seen */
-					/* directories to prevent IFD looping */
-	tsize_t		tif_dirlistsize;/* number of entires in offset list */
-	uint16		tif_dirnumber;  /* number of already seen directories */
-	TIFFDirectory	tif_dir;	/* internal rep of current directory */
-	TIFFDirectory	tif_customdir;	/* custom IFDs are separated from
-					   the main ones */
-	TIFFHeader	tif_header;	/* file's header block */
-	const int*	tif_typeshift;	/* data type shift counts */
-	const long*	tif_typemask;	/* data type masks */
-	uint32		tif_row;	/* current scanline */
-	tdir_t		tif_curdir;	/* current directory (index) */
-	tstrip_t	tif_curstrip;	/* current strip for read/write */
-	toff_t		tif_curoff;	/* current offset for read/write */
-	toff_t		tif_dataoff;	/* current offset for writing dir */
-/* SubIFD support */
-	uint16		tif_nsubifd;	/* remaining subifds to write */
-	toff_t		tif_subifdoff;	/* offset for patching SubIFD link */
-/* tiling support */
-	uint32 		tif_col;	/* current column (offset by row too) */
-	ttile_t		tif_curtile;	/* current tile for read/write */
-	tsize_t		tif_tilesize;	/* # of bytes in a tile */
-/* compression scheme hooks */
-	int		tif_decodestatus;
-	TIFFBoolMethod	tif_setupdecode;/* called once before predecode */
-	TIFFPreMethod	tif_predecode;	/* pre- row/strip/tile decoding */
-	TIFFBoolMethod	tif_setupencode;/* called once before preencode */
-	int		tif_encodestatus;
-	TIFFPreMethod	tif_preencode;	/* pre- row/strip/tile encoding */
-	TIFFBoolMethod	tif_postencode;	/* post- row/strip/tile encoding */
-	TIFFCodeMethod	tif_decoderow;	/* scanline decoding routine */
-	TIFFCodeMethod	tif_encoderow;	/* scanline encoding routine */
-	TIFFCodeMethod	tif_decodestrip;/* strip decoding routine */
-	TIFFCodeMethod	tif_encodestrip;/* strip encoding routine */
-	TIFFCodeMethod	tif_decodetile;	/* tile decoding routine */
-	TIFFCodeMethod	tif_encodetile;	/* tile encoding routine */
-	TIFFVoidMethod	tif_close;	/* cleanup-on-close routine */
-	TIFFSeekMethod	tif_seek;	/* position within a strip routine */
-	TIFFVoidMethod	tif_cleanup;	/* cleanup state routine */
-	TIFFStripMethod	tif_defstripsize;/* calculate/constrain strip size */
-	TIFFTileMethod	tif_deftilesize;/* calculate/constrain tile size */
-	tidata_t	tif_data;	/* compression scheme private data */
-/* input/output buffering */
-	tsize_t		tif_scanlinesize;/* # of bytes in a scanline */
-	tsize_t		tif_scanlineskew;/* scanline skew for reading strips */
-	tidata_t	tif_rawdata;	/* raw data buffer */
-	tsize_t		tif_rawdatasize;/* # of bytes in raw data buffer */
-	tidata_t	tif_rawcp;	/* current spot in raw buffer */
-	tsize_t		tif_rawcc;	/* bytes unread from raw buffer */
-/* memory-mapped file support */
-	tidata_t	tif_base;	/* base of mapped file */
-	toff_t		tif_size;	/* size of mapped file region (bytes)
-					   FIXME: it should be tsize_t */
-	TIFFMapFileProc	tif_mapproc;	/* map file method */
-	TIFFUnmapFileProc tif_unmapproc;/* unmap file method */
-/* input/output callback methods */
-	thandle_t	tif_clientdata;	/* callback parameter */
-	TIFFReadWriteProc tif_readproc;	/* read method */
-	TIFFReadWriteProc tif_writeproc;/* write method */
-	TIFFSeekProc	tif_seekproc;	/* lseek method */
-	TIFFCloseProc	tif_closeproc;	/* close method */
-	TIFFSizeProc	tif_sizeproc;	/* filesize method */
-/* post-decoding support */
-	TIFFPostMethod	tif_postdecode;	/* post decoding routine */
-/* tag support */
-	TIFFFieldInfo**	tif_fieldinfo;	/* sorted table of registered tags */
-	size_t		tif_nfields;	/* # entries in registered tag table */
-	const TIFFFieldInfo *tif_foundfield;/* cached pointer to already found tag */
-        TIFFTagMethods  tif_tagmethods; /* tag get/set/print routines */
-        TIFFClientInfoLink *tif_clientinfo; /* extra client information. */
-};
-
-#define	isPseudoTag(t)	(t > 0xffff)	/* is tag value normal or pseudo */
-
-#define	isTiled(tif)	(((tif)->tif_flags & TIFF_ISTILED) != 0)
-#define	isMapped(tif)	(((tif)->tif_flags & TIFF_MAPPED) != 0)
-#define	isFillOrder(tif, o)	(((tif)->tif_flags & (o)) != 0)
-#define	isUpSampled(tif)	(((tif)->tif_flags & TIFF_UPSAMPLED) != 0)
-#define	TIFFReadFile(tif, buf, size) \
-	((*(tif)->tif_readproc)((tif)->tif_clientdata,buf,size))
-#define	TIFFWriteFile(tif, buf, size) \
-	((*(tif)->tif_writeproc)((tif)->tif_clientdata,buf,size))
-#define	TIFFSeekFile(tif, off, whence) \
-	((*(tif)->tif_seekproc)((tif)->tif_clientdata,(toff_t)(off),whence))
-#define	TIFFCloseFile(tif) \
-	((*(tif)->tif_closeproc)((tif)->tif_clientdata))
-#define	TIFFGetFileSize(tif) \
-	((*(tif)->tif_sizeproc)((tif)->tif_clientdata))
-#define	TIFFMapFileContents(tif, paddr, psize) \
-	((*(tif)->tif_mapproc)((tif)->tif_clientdata,paddr,psize))
-#define	TIFFUnmapFileContents(tif, addr, size) \
-	((*(tif)->tif_unmapproc)((tif)->tif_clientdata,addr,size))
-
-/*
- * Default Read/Seek/Write definitions.
- */
-#ifndef ReadOK
-#define	ReadOK(tif, buf, size) \
-	(TIFFReadFile(tif, (tdata_t) buf, (tsize_t)(size)) == (tsize_t)(size))
-#endif
-#ifndef SeekOK
-#define	SeekOK(tif, off) \
-	(TIFFSeekFile(tif, (toff_t) off, SEEK_SET) == (toff_t) off)
-#endif
-#ifndef WriteOK
-#define	WriteOK(tif, buf, size) \
-	(TIFFWriteFile(tif, (tdata_t) buf, (tsize_t) size) == (tsize_t) size)
-#endif
-
-/* NB: the uint32 casts are to silence certain ANSI-C compilers */
-#define TIFFhowmany(x, y) (((uint32)x < (0xffffffff - (uint32)(y-1))) ?	\
-			   ((((uint32)(x))+(((uint32)(y))-1))/((uint32)(y))) : \
-			   0U)
-#define TIFFhowmany8(x) (((x)&0x07)?((uint32)(x)>>3)+1:(uint32)(x)>>3)
-#define	TIFFroundup(x, y) (TIFFhowmany(x,y)*(y))
-
-/* Safe multiply which returns zero if there is an integer overflow */
-#define TIFFSafeMultiply(t,v,m) ((((t)m != (t)0) && (((t)((v*m)/m)) == (t)v)) ? (t)(v*m) : (t)0)
-
-#define TIFFmax(A,B) ((A)>(B)?(A):(B))
-#define TIFFmin(A,B) ((A)<(B)?(A):(B))
-
-#define TIFFArrayCount(a) (sizeof (a) / sizeof ((a)[0]))
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-extern	int _TIFFgetMode(const char*, const char*);
-extern	int _TIFFNoRowEncode(TIFF*, tidata_t, tsize_t, tsample_t);
-extern	int _TIFFNoStripEncode(TIFF*, tidata_t, tsize_t, tsample_t);
-extern	int _TIFFNoTileEncode(TIFF*, tidata_t, tsize_t, tsample_t);
-extern	int _TIFFNoRowDecode(TIFF*, tidata_t, tsize_t, tsample_t);
-extern	int _TIFFNoStripDecode(TIFF*, tidata_t, tsize_t, tsample_t);
-extern	int _TIFFNoTileDecode(TIFF*, tidata_t, tsize_t, tsample_t);
-extern	void _TIFFNoPostDecode(TIFF*, tidata_t, tsize_t);
-extern  int  _TIFFNoPreCode (TIFF*, tsample_t); 
-extern	int _TIFFNoSeek(TIFF*, uint32);
-extern	void _TIFFSwab16BitData(TIFF*, tidata_t, tsize_t);
-extern	void _TIFFSwab24BitData(TIFF*, tidata_t, tsize_t);
-extern	void _TIFFSwab32BitData(TIFF*, tidata_t, tsize_t);
-extern	void _TIFFSwab64BitData(TIFF*, tidata_t, tsize_t);
-extern	int TIFFFlushData1(TIFF*);
-extern	int TIFFDefaultDirectory(TIFF*);
-extern	void _TIFFSetDefaultCompressionState(TIFF*);
-extern	int TIFFSetCompressionScheme(TIFF*, int);
-extern	int TIFFSetDefaultCompressionState(TIFF*);
-extern	uint32 _TIFFDefaultStripSize(TIFF*, uint32);
-extern	void _TIFFDefaultTileSize(TIFF*, uint32*, uint32*);
-extern	int _TIFFDataSize(TIFFDataType);
-
-extern	void _TIFFsetByteArray(void**, void*, uint32);
-extern	void _TIFFsetString(char**, char*);
-extern	void _TIFFsetShortArray(uint16**, uint16*, uint32);
-extern	void _TIFFsetLongArray(uint32**, uint32*, uint32);
-extern	void _TIFFsetFloatArray(float**, float*, uint32);
-extern	void _TIFFsetDoubleArray(double**, double*, uint32);
-
-extern	void _TIFFprintAscii(FILE*, const char*);
-extern	void _TIFFprintAsciiTag(FILE*, const char*, const char*);
-
-extern	TIFFErrorHandler _TIFFwarningHandler;
-extern	TIFFErrorHandler _TIFFerrorHandler;
-extern	TIFFErrorHandlerExt _TIFFwarningHandlerExt;
-extern	TIFFErrorHandlerExt _TIFFerrorHandlerExt;
-
-extern	tdata_t _TIFFCheckMalloc(TIFF*, size_t, size_t, const char*);
-extern	tdata_t _TIFFCheckRealloc(TIFF*, tdata_t, size_t, size_t, const char*);
-
-extern	int TIFFInitDumpMode(TIFF*, int);
-#ifdef PACKBITS_SUPPORT
-extern	int TIFFInitPackBits(TIFF*, int);
-#endif
-#ifdef CCITT_SUPPORT
-extern	int TIFFInitCCITTRLE(TIFF*, int), TIFFInitCCITTRLEW(TIFF*, int);
-extern	int TIFFInitCCITTFax3(TIFF*, int), TIFFInitCCITTFax4(TIFF*, int);
-#endif
-#ifdef THUNDER_SUPPORT
-extern	int TIFFInitThunderScan(TIFF*, int);
-#endif
-#ifdef NEXT_SUPPORT
-extern	int TIFFInitNeXT(TIFF*, int);
-#endif
-#ifdef LZW_SUPPORT
-extern	int TIFFInitLZW(TIFF*, int);
-#endif
-#ifdef OJPEG_SUPPORT
-extern	int TIFFInitOJPEG(TIFF*, int);
-#endif
-#ifdef JPEG_SUPPORT
-extern	int TIFFInitJPEG(TIFF*, int);
-#endif
-#ifdef JBIG_SUPPORT
-extern	int TIFFInitJBIG(TIFF*, int);
-#endif
-#ifdef ZIP_SUPPORT
-extern	int TIFFInitZIP(TIFF*, int);
-#endif
-#ifdef PIXARLOG_SUPPORT
-extern	int TIFFInitPixarLog(TIFF*, int);
-#endif
-#ifdef LOGLUV_SUPPORT
-extern	int TIFFInitSGILog(TIFF*, int);
-#endif
-#ifdef VMS
-extern	const TIFFCodec _TIFFBuiltinCODECS[];
-#else
-extern	TIFFCodec _TIFFBuiltinCODECS[];
-#endif
-
-#if defined(__cplusplus)
-}
-#endif
-#endif /* _TIFFIOP_ */
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF/tiffvers.h b/Source/LibTIFF/tiffvers.h
deleted file mode 100644
index a5607aa..0000000
--- a/Source/LibTIFF/tiffvers.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#define TIFFLIB_VERSION_STR "LIBTIFF, Version 3.9.5\nCopyright (c) 1988-1996 Sam Leffler\nCopyright (c) 1991-1996 Silicon Graphics, Inc."
-/*
- * This define can be used in code that requires
- * compilation-related definitions specific to a
- * version or versions of the library.  Runtime
- * version checking should be done based on the
- * string returned by TIFFGetVersion.
- */
-#define TIFFLIB_VERSION 20110409
diff --git a/Source/LibTIFF/tiffvers.h.in b/Source/LibTIFF/tiffvers.h.in
deleted file mode 100644
index c855630..0000000
--- a/Source/LibTIFF/tiffvers.h.in
+++ /dev/null
@@ -1,9 +0,0 @@
-#define TIFFLIB_VERSION_STR "LIBTIFF, Version LIBTIFF_VERSION\nCopyright (c) 1988-1996 Sam Leffler\nCopyright (c) 1991-1996 Silicon Graphics, Inc."
-/*
- * This define can be used in code that requires
- * compilation-related definitions specific to a
- * version or versions of the library.  Runtime
- * version checking should be done based on the
- * string returned by TIFFGetVersion.
- */
-#define TIFFLIB_VERSION LIBTIFF_RELEASE_DATE
diff --git a/Source/LibTIFF/uvcode.h b/Source/LibTIFF/uvcode.h
deleted file mode 100644
index 50f11d7..0000000
--- a/Source/LibTIFF/uvcode.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/* Version 1.0 generated April 7, 1997 by Greg Ward Larson, SGI */
-#define UV_SQSIZ	(float)0.003500
-#define UV_NDIVS	16289
-#define UV_VSTART	(float)0.016940
-#define UV_NVS		163
-static struct {
-	float	ustart;
-	short	nus, ncum;
-}	uv_row[UV_NVS] = {
-	{ (float)0.247663,	4,	0 },
-	{ (float)0.243779,	6,	4 },
-	{ (float)0.241684,	7,	10 },
-	{ (float)0.237874,	9,	17 },
-	{ (float)0.235906,	10,	26 },
-	{ (float)0.232153,	12,	36 },
-	{ (float)0.228352,	14,	48 },
-	{ (float)0.226259,	15,	62 },
-	{ (float)0.222371,	17,	77 },
-	{ (float)0.220410,	18,	94 },
-	{ (float)0.214710,	21,	112 },
-	{ (float)0.212714,	22,	133 },
-	{ (float)0.210721,	23,	155 },
-	{ (float)0.204976,	26,	178 },
-	{ (float)0.202986,	27,	204 },
-	{ (float)0.199245,	29,	231 },
-	{ (float)0.195525,	31,	260 },
-	{ (float)0.193560,	32,	291 },
-	{ (float)0.189878,	34,	323 },
-	{ (float)0.186216,	36,	357 },
-	{ (float)0.186216,	36,	393 },
-	{ (float)0.182592,	38,	429 },
-	{ (float)0.179003,	40,	467 },
-	{ (float)0.175466,	42,	507 },
-	{ (float)0.172001,	44,	549 },
-	{ (float)0.172001,	44,	593 },
-	{ (float)0.168612,	46,	637 },
-	{ (float)0.168612,	46,	683 },
-	{ (float)0.163575,	49,	729 },
-	{ (float)0.158642,	52,	778 },
-	{ (float)0.158642,	52,	830 },
-	{ (float)0.158642,	52,	882 },
-	{ (float)0.153815,	55,	934 },
-	{ (float)0.153815,	55,	989 },
-	{ (float)0.149097,	58,	1044 },
-	{ (float)0.149097,	58,	1102 },
-	{ (float)0.142746,	62,	1160 },
-	{ (float)0.142746,	62,	1222 },
-	{ (float)0.142746,	62,	1284 },
-	{ (float)0.138270,	65,	1346 },
-	{ (float)0.138270,	65,	1411 },
-	{ (float)0.138270,	65,	1476 },
-	{ (float)0.132166,	69,	1541 },
-	{ (float)0.132166,	69,	1610 },
-	{ (float)0.126204,	73,	1679 },
-	{ (float)0.126204,	73,	1752 },
-	{ (float)0.126204,	73,	1825 },
-	{ (float)0.120381,	77,	1898 },
-	{ (float)0.120381,	77,	1975 },
-	{ (float)0.120381,	77,	2052 },
-	{ (float)0.120381,	77,	2129 },
-	{ (float)0.112962,	82,	2206 },
-	{ (float)0.112962,	82,	2288 },
-	{ (float)0.112962,	82,	2370 },
-	{ (float)0.107450,	86,	2452 },
-	{ (float)0.107450,	86,	2538 },
-	{ (float)0.107450,	86,	2624 },
-	{ (float)0.107450,	86,	2710 },
-	{ (float)0.100343,	91,	2796 },
-	{ (float)0.100343,	91,	2887 },
-	{ (float)0.100343,	91,	2978 },
-	{ (float)0.095126,	95,	3069 },
-	{ (float)0.095126,	95,	3164 },
-	{ (float)0.095126,	95,	3259 },
-	{ (float)0.095126,	95,	3354 },
-	{ (float)0.088276,	100,	3449 },
-	{ (float)0.088276,	100,	3549 },
-	{ (float)0.088276,	100,	3649 },
-	{ (float)0.088276,	100,	3749 },
-	{ (float)0.081523,	105,	3849 },
-	{ (float)0.081523,	105,	3954 },
-	{ (float)0.081523,	105,	4059 },
-	{ (float)0.081523,	105,	4164 },
-	{ (float)0.074861,	110,	4269 },
-	{ (float)0.074861,	110,	4379 },
-	{ (float)0.074861,	110,	4489 },
-	{ (float)0.074861,	110,	4599 },
-	{ (float)0.068290,	115,	4709 },
-	{ (float)0.068290,	115,	4824 },
-	{ (float)0.068290,	115,	4939 },
-	{ (float)0.068290,	115,	5054 },
-	{ (float)0.063573,	119,	5169 },
-	{ (float)0.063573,	119,	5288 },
-	{ (float)0.063573,	119,	5407 },
-	{ (float)0.063573,	119,	5526 },
-	{ (float)0.057219,	124,	5645 },
-	{ (float)0.057219,	124,	5769 },
-	{ (float)0.057219,	124,	5893 },
-	{ (float)0.057219,	124,	6017 },
-	{ (float)0.050985,	129,	6141 },
-	{ (float)0.050985,	129,	6270 },
-	{ (float)0.050985,	129,	6399 },
-	{ (float)0.050985,	129,	6528 },
-	{ (float)0.050985,	129,	6657 },
-	{ (float)0.044859,	134,	6786 },
-	{ (float)0.044859,	134,	6920 },
-	{ (float)0.044859,	134,	7054 },
-	{ (float)0.044859,	134,	7188 },
-	{ (float)0.040571,	138,	7322 },
-	{ (float)0.040571,	138,	7460 },
-	{ (float)0.040571,	138,	7598 },
-	{ (float)0.040571,	138,	7736 },
-	{ (float)0.036339,	142,	7874 },
-	{ (float)0.036339,	142,	8016 },
-	{ (float)0.036339,	142,	8158 },
-	{ (float)0.036339,	142,	8300 },
-	{ (float)0.032139,	146,	8442 },
-	{ (float)0.032139,	146,	8588 },
-	{ (float)0.032139,	146,	8734 },
-	{ (float)0.032139,	146,	8880 },
-	{ (float)0.027947,	150,	9026 },
-	{ (float)0.027947,	150,	9176 },
-	{ (float)0.027947,	150,	9326 },
-	{ (float)0.023739,	154,	9476 },
-	{ (float)0.023739,	154,	9630 },
-	{ (float)0.023739,	154,	9784 },
-	{ (float)0.023739,	154,	9938 },
-	{ (float)0.019504,	158,	10092 },
-	{ (float)0.019504,	158,	10250 },
-	{ (float)0.019504,	158,	10408 },
-	{ (float)0.016976,	161,	10566 },
-	{ (float)0.016976,	161,	10727 },
-	{ (float)0.016976,	161,	10888 },
-	{ (float)0.016976,	161,	11049 },
-	{ (float)0.012639,	165,	11210 },
-	{ (float)0.012639,	165,	11375 },
-	{ (float)0.012639,	165,	11540 },
-	{ (float)0.009991,	168,	11705 },
-	{ (float)0.009991,	168,	11873 },
-	{ (float)0.009991,	168,	12041 },
-	{ (float)0.009016,	170,	12209 },
-	{ (float)0.009016,	170,	12379 },
-	{ (float)0.009016,	170,	12549 },
-	{ (float)0.006217,	173,	12719 },
-	{ (float)0.006217,	173,	12892 },
-	{ (float)0.005097,	175,	13065 },
-	{ (float)0.005097,	175,	13240 },
-	{ (float)0.005097,	175,	13415 },
-	{ (float)0.003909,	177,	13590 },
-	{ (float)0.003909,	177,	13767 },
-	{ (float)0.002340,	177,	13944 },
-	{ (float)0.002389,	170,	14121 },
-	{ (float)0.001068,	164,	14291 },
-	{ (float)0.001653,	157,	14455 },
-	{ (float)0.000717,	150,	14612 },
-	{ (float)0.001614,	143,	14762 },
-	{ (float)0.000270,	136,	14905 },
-	{ (float)0.000484,	129,	15041 },
-	{ (float)0.001103,	123,	15170 },
-	{ (float)0.001242,	115,	15293 },
-	{ (float)0.001188,	109,	15408 },
-	{ (float)0.001011,	103,	15517 },
-	{ (float)0.000709,	97,	15620 },
-	{ (float)0.000301,	89,	15717 },
-	{ (float)0.002416,	82,	15806 },
-	{ (float)0.003251,	76,	15888 },
-	{ (float)0.003246,	69,	15964 },
-	{ (float)0.004141,	62,	16033 },
-	{ (float)0.005963,	55,	16095 },
-	{ (float)0.008839,	47,	16150 },
-	{ (float)0.010490,	40,	16197 },
-	{ (float)0.016994,	31,	16237 },
-	{ (float)0.023659,	21,	16268 },
-};
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/Source/LibTIFF4/ChangeLog b/Source/LibTIFF4/ChangeLog
index aa4d760..1548138 100644
--- a/Source/LibTIFF4/ChangeLog
+++ b/Source/LibTIFF4/ChangeLog
@@ -1,3 +1,428 @@
+2015-01-26  Even Rouault  <even.rouault at spatialys.com>
+
+	* add html/v4.0.4beta.html under version control
+	* HOWTO-RELEASE: write that cvs add html/vX.X.html must be used
+
+2015-01-26  Even Rouault  <even.rouault at spatialys.com>
+
+	* libtiff 4.0.4beta released
+
+2015-01-26  Even Rouault  <even.rouault at spatialys.com>
+
+	* automake: updated to 1.15
+	* libtool: updated to 2.4.5
+
+2015-01-22  Even Rouault  <even.rouault at spatialys.com>
+
+	* tools/tiff2pdf.c: Fix two crashes (oCERT-2014-013)
+
+2015-01-05  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* html/bugs.html: remove note about needing to email the tiff mailing
+	list administrator about being approved for membership, this appears
+	not to be true.
+
+2015-01-05  Olivier Paquet  <olivier.paquet at gmail.com>
+
+	* tools/tiff2pdf.c: Fixed unsigned integer addition overflow detection.
+
+2015-01-03  Even Rouault  <even.rouault at spatialys.com>
+
+	* libtiff/tif_dirread.c: in TIFFCheckDirOffset(), avoid uint16 overflow
+	when reading more than 65535 directories, and effectively error out when
+	reaching that limit.
+
+2014-12-29  Even Rouault  <even.rouault at spatialys.com>
+
+	* libtiff/tif_jpeg.c: in JPEGFixupTags(), recognize SOF2, SOF9 and SOF10
+	markers to avoid emitting a warning (even if, according to the TechNote,
+	there are admitedly unusual/not recommended or even forbidden variants, but
+	they do work well with libjpeg for SOF2, and with libjpeg-turbo for SOF2,
+	SOF9 and SOF10).
+	Define in_color_space and input_components to the right values in
+	JPEGSetupEncode(), before calling jpeg_set_defaults(), as specified by
+	libjpeg API documentation, so as to be compatible with mozjpeg library.
+	Note: the default settings of mozjpeg will produce progressive scans, which
+	is forbidden by the TechNote.
+
+2014-12-29  Even Rouault  <even.rouault at spatialys.com>
+
+	* libtiff/tif_getimage.c: move test on vertical value of YCbCr subsampling.
+	to avoid buffer leak (fix previous fix, found by Coverity scan)
+
+2014-12-29  Even Rouault  <even.rouault at spatialys.com>
+
+	* libtiff/tif_next.c: add new tests to check that we don't read outside of
+	the compressed input stream buffer.
+
+	* libtiff/tif_getimage.c: in OJPEG case, fix checks on strile width/height
+    in the putcontig8bitYCbCr42tile, putcontig8bitYCbCr41tile and
+    putcontig8bitYCbCr21tile cases.
+
+2014-12-27  Even Rouault  <even.rouault at spatialys.com>
+
+	* libtiff/tif_dir.c: in TIFFDefaultDirectory(), reset any already existing
+	extented tags installed by user code through the extender mechaninm before
+	calling the extender callback (GDAL #5054)
+
+2014-12-26  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
+
+	* tools/tiffcrop.c: Fix warnings about variables set but not used.
+
+	* contrib/iptcutil/iptcutil.c: Fix warnings about variables set
+	but not used.
+
+	* tools/tiffgt.c: Fix warnings about unused parameters.
+
+	* libtiff/tif_stream.cxx: Fix warnings about unused parameters.
+
+2014-12-25  Even Rouault  <even.rouault at spatialys.com>
+
+	* libtiff/tif_getimage.c, libtiff/tif_ojpeg.c, libtiff/tif_zip.c: fix
+	various typos found by Debian lintian tool (GDAL #5756)
+
+2014-12-24  Even Rouault  <even.rouault at spatialys.com>
+
+	* libtiff/tif_getimage.c: avoid divide by zero on invalid YCbCr subsampling.
+	http://bugzilla.maptools.org/show_bug.cgi?id=2235
+
+2014-12-24  Even Rouault  <even.rouault at spatialys.com>
+
+	* tools/tiff2pdf.c: fix buffer overflow on some YCbCr JPEG compressed images.
+	http://bugzilla.maptools.org/show_bug.cgi?id=2445
+
+2014-12-24  Even Rouault  <even.rouault at spatialys.com>
+
+	* tools/tiff2pdf.c: fix buffer overflow on YCbCr JPEG compressed image.
+	Derived from patch by Petr Gajdos,
+	http://bugzilla.maptools.org/show_bug.cgi?id=2443
+
+2014-12-23  Even Rouault  <even.rouault at spatialys.com>
+
+	* libtiff/tif_dirread.c: In EstimateStripByteCounts(), check return code
+	of _TIFFFillStriles(). This solves crashing bug on corrupted
+	images generated by afl.
+
+2014-12-23  Even Rouault  <even.rouault at spatialys.com>
+
+	* libtiff/tif_read.c: fix several invalid comparisons of a uint64 value with
+	<= 0 by casting it to int64 first. This solves crashing bug on corrupted
+	images generated by afl.
+
+2014-12-21  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
+
+	* tools/tiffdump.c: Guard against arithmetic overflow when
+	calculating allocation buffer sizes.
+
+2014-12-21  Even Rouault  <even.rouault at spatialys.com>
+
+	* tools/tiff2bw.c: when Photometric=RGB, the utility only works if
+	SamplesPerPixel = 3. Enforce that
+	http://bugzilla.maptools.org/show_bug.cgi?id=2485 (CVE-2014-8127)
+
+2014-12-21  Even Rouault  <even.rouault at spatialys.com>
+
+	* tools/pal2rgb.c, tools/thumbnail.c: fix crash by disabling TIFFTAG_INKNAMES
+	copying. The right fix would be to properly copy it, but not worth the burden
+	for those esoteric utilities.
+	http://bugzilla.maptools.org/show_bug.cgi?id=2484 (CVE-2014-8127)
+
+2014-12-21  Even Rouault  <even.rouault at spatialys.com>
+
+	* tools/thumbnail.c: fix out-of-buffer write
+	http://bugzilla.maptools.org/show_bug.cgi?id=2489 (CVE-2014-8128)
+
+2014-12-21  Even Rouault  <even.rouault at spatialys.com>
+
+	* tools/thumbnail.c, tools/tiffcmp.c: only read/write TIFFTAG_GROUP3OPTIONS
+	or TIFFTAG_GROUP4OPTIONS if compression is COMPRESSION_CCITTFAX3 or
+	COMPRESSION_CCITTFAX4
+	http://bugzilla.maptools.org/show_bug.cgi?id=2493 (CVE-2014-8128)
+
+2014-12-21  Even Rouault  <even.rouault at spatialys.com>
+
+	* libtiff/tif_next.c: check that BitsPerSample = 2. Fixes
+	http://bugzilla.maptools.org/show_bug.cgi?id=2487 (CVE-2014-8129)
+
+2014-12-21  Even Rouault  <even.rouault at spatialys.com>
+
+	* tools/tiff2pdf.c: check return code of TIFFGetField() when reading
+	TIFFTAG_SAMPLESPERPIXEL
+
+2014-12-21  Even Rouault  <even.rouault at spatialys.com>
+
+	* tools/tiffcp.c: fix crash when converting YCbCr JPEG-compressed to none.
+	Based on patch by Tomasz Buchert (http://bugzilla.maptools.org/show_bug.cgi?id=2480)
+	Description: fix for Debian bug #741451
+	tiffcp crashes when converting JPEG-encoded TIFF to a different
+	encoding (like none or lzw). For example this will probably fail:
+	tiffcp -c none jpeg_encoded_file.tif output.tif
+	The reason is that when the input file contains JPEG data,
+	the tiffcp code forces conversion to RGB space. However,
+	the output normally inherits YCbCr subsampling parameters
+	from the input, which leads to a smaller working buffer
+	than necessary. The buffer is subsequently overrun inside
+	cpStripToTile() (called from writeBufferToContigTiles).
+	Note that the resulting TIFF file would be scrambled even
+	if tiffcp wouldn't crash, since the output file would contain
+	RGB data intepreted as subsampled YCbCr values.
+	This patch fixes the problem by forcing RGB space on the output
+	TIF if the input is JPEG-encoded and output is *not* JPEG-encoded.
+	Author: Tomasz Buchert <tomasz.buchert at inria.fr>
+
+2014-12-21  Even Rouault  <even.rouault at spatialys.com>
+
+	Fix various crasher bugs on fuzzed images.
+	* libtiff/tif_dir.c: TIFFSetField(): refuse to set negative values for
+	TIFFTAG_XRESOLUTION and TIFFTAG_YRESOLUTION that cause asserts when writing
+	the directory
+	* libtiff/tif_dirread.c: TIFFReadDirectory(): refuse to read ColorMap or
+	TransferFunction if BitsPerSample has not yet been read, otherwise reading
+	it later will cause user code to crash if BitsPerSample > 1
+	* libtiff/tif_getimage.c: TIFFRGBAImageOK(): return FALSE if LOGLUV with
+	SamplesPerPixel != 3, or if CIELAB with SamplesPerPixel != 3 or BitsPerSample != 8
+	* libtiff/tif_next.c: in the "run mode", use tilewidth for tiled images
+	instead of imagewidth to avoid crash
+	* tools/bmp2tiff.c: fix crash due to int overflow related to input BMP dimensions
+	* tools/tiff2pdf.c: fix crash due to invalid tile count (should likely be checked by
+	libtiff too). Detect invalid settings of BitsPerSample/SamplesPerPixel for CIELAB / ITULAB
+	* tools/tiffcrop.c: fix crash due to invalid TileWidth/TileHeight
+	* tools/tiffdump.c: fix crash due to overflow of entry count.
+
+2014-12-15  Even Rouault  <even.rouault at spatialys.com>
+
+	* libtiff/tif_jpeg.c: Fix regression introduced on 2010-05-07 that caused
+	all tiles/strips to include quantization tables even when the jpegtablesmode
+	had the JPEGTABLESMODE_QUANT bit set.
+	Also add explicit removal of Huffman tables when jpegtablesmode has the
+	JPEGTABLESMODE_HUFF bit set, which avoids Huffman tables to be emitted in the
+	first tile/strip (only useful in update scenarios. create-only was
+	fine)
+
+2014-12-09  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
+
+	* tools/tiff2pdf.c: Assure that memory size calculations for
+	_TIFFmalloc() do not overflow the range of tmsize_t.
+
+2014-12-07  Even Rouault  <even.rouault at spatialys.com>
+
+	* tools/thumbnail.c, tools/tiffcrop.c: "fix" heap read over-run found with
+	Valgrind and Address Sanitizer on test suite
+
+2014-12-07  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
+
+	* tools/tiff2pdf.c (t2p_read_tiff_init): TIFFTAG_TRANSFERFUNCTION
+	tag can return one channel, with the other two channels set to
+	NULL.  The tiff2pdf code was expecting that other two channels
+	were duplicate pointers in the case where there is only one
+	channel.  Detect this condition in order to avoid a crash, and
+	presumably perform correctly with just one channel.
+
+2014-12-06  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
+
+	* tools/tiffdump.c: Fix double-free bug.
+
+2014-11-27  Even Rouault  <even.rouault at spatialys.com>
+
+	* libtiff/tif_config.vc.h: no longer use "#define snprintf _snprintf" with
+	Visual Studio 2015 aka VC 14 aka MSVC 1900
+
+2014-11-20  Even Rouault  <even.rouault at spatialys.com>
+
+	* libtiff/tif_lzw.c: prevent potential null dereference of
+	sp->dec_codetab in LZWPreDecode (bug #2459)
+
+	* libtiff/tif_read.c: in TIFFReadBufferSetup(), avoid passing -1 size
+	to TIFFmalloc() if passed user buffer size is 0 (bug #2459)
+
+	* libtiff/tif_ojpeg.c: make Coverity happier (not a bug, #2459)
+
+	* libtiff/tif_dir.c: in _TIFFVGetField() and _TIFFVSetField(), make
+	Coverity happier (not a bug, #2459)
+
+	* libtiff/tif_dirread.c: in TIFFFetchNormalTag(), make Coverity happier
+	(not a bug, #2459)
+
+	* tools/tiff2pdf.c: close PDF file (bug #2479)
+
+	* tools/fax2ps.c: check malloc()/realloc() result (bug #2470)
+
+	* tools/tiffdump.c: detect cycle in TIFF directory chaining (bug #2463)
+	and avoid passing a NULL pointer to read() if seek() failed before (bug #2459)
+
+	* tools/tiffcrop.c: fix segfault if bad value passed to -Z option
+	(bug #2459) and add missing va_end in dump_info (#2459)
+
+	* tools/gif2tif.c: apply patch for CVE-2013-4243 (#2451)
+
+2014-11-20  Even Rouault  <even.rouault at spatialys.com>
+	* libtiff/tif_jpeg.c: fix segfault in JPEGFixupTagsSubsampling() on
+	corrupted image where tif->tif_dir.td_stripoffset == NULL (bug #2471)
+
+2014-11-20  Even Rouault  <even.rouault at spatialys.com>
+	* automake: updated to 1.14.1
+	* libtool: updated to 2.4.3
+	* HOWTO-RELEASE: small update about autotools building order
+
+2014-10-20  Olivier Paquet  <olivier.paquet at gmail.com>
+	* tools/tiff2pdf.c: Preserve input file directory order when pages
+	are tagged with the same page number.
+
+2014-08-31  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
+
+	* libtiff/tif_dirread.c (TIFFReadDirEntryOutputErr): Incorrect
+	count for tag should be a warning rather than an error since
+	errors terminate processing.
+
+2014-06-07  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
+
+	* tools/tiff2rgba.c (]): Fixed tiff2rgba usage message in that zip
+	was wrongly described.  Fix suggested by Miguel Medalha.
+
+2014-05-06  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
+
+	* libtiff/tif_dirinfo.c (TIFFField) : Fix data type for
+	TIFFTAG_GLOBALPARAMETERSIFD tag.  Patch by Steve Underwood.
+	Reviewed and forwarded by Lee Howard.
+
+2013-11-30  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* libtiff/tif_dir.c: fix last fix for TIFFNumberOfDirectories()
+
+2013-10-21  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* libtiff/tif_dir.c: generate error in case of directory count
+	overflow.
+
+2013-10-01  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* libtiff/tiff.h, libtiff/tif_dirinfo.c: add definitions for
+	TIFF/EP CFARepeatPatternDim and CFAPattern tags (bug #2457)
+
+2013-09-12  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
+
+	* libtiff/tif_dir.c (TIFFAdvanceDirectory): If nextdir is found to
+	be defective, then set it to zero before returning error in order
+	to terminate processing of truncated TIFF.  Issue found and fix
+	suggested by Richard Nolde.
+
+2013-08-14  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* tools/gif2tiff.c: fix possible OOB write (#2452, CVE-2013-4244)
+
+2013-08-13  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* tools/gif2tiff.c: Be more careful about corrupt or
+	hostile input files (#2450, CVE-2013-4231)
+
+	* tools/tiff2pdf.c: terminate after failure of allocating
+	ycbcr buffer (bug #2449, CVE-2013-4232)
+
+2013-07-09  Frank Warmerdam  <warmerdam at google.com>
+
+	* tools/tiffinfo.c: Default various values fetched with
+	TIFFGetField() to avoid being uninitialized.
+
+2013-05-02  Tom Lane  <tgl at sss.pgh.pa.us>
+
+	* tools/tiff2pdf.c: Rewrite JPEG marker parsing in
+	t2p_process_jpeg_strip to be at least marginally competent.  The
+	approach is still fundamentally flawed, but at least now it won't
+	stomp all over memory when given bogus input.  Fixes CVE-2013-1960.
+
+2013-05-02  Tom Lane  <tgl at sss.pgh.pa.us>
+
+	* contrib/dbs/xtiff/xtiff.c, libtiff/tif_codec.c,
+ 	libtiff/tif_dirinfo.c, tools/rgb2ycbcr.c, tools/tiff2bw.c,
+ 	tools/tiff2pdf.c, tools/tiff2ps.c, tools/tiffcrop.c,
+ 	tools/tiffdither.c: Enlarge some fixed-size buffers that weren't
+ 	large enough, and eliminate substantially all uses of sprintf(buf,
+ 	...)  in favor of using snprintf(buf, sizeof(buf), ...), so as to
+ 	protect against overflow of fixed-size buffers.  This responds in
+ 	particular to CVE-2013-1961 concerning overflow in tiff2pdf.c's
+ 	t2p_write_pdf_page(), but in general it seems like a good idea to
+ 	deprecate use of sprintf().
+
+2013-03-29  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
+
+	* configure.ac: Applied patch by Brad Smith to improve pkg-config
+	static linking by adding -lm to Libs.private when needed.
+
+2013-03-05  Tom Lane  <tgl at sss.pgh.pa.us>
+
+	* html/man/tiff2ps.1.html, html/man/tiffcp.1.html,
+ 	html/man/tiffdither.1.html, man/tiff2ps.1, man/tiffcp.1,
+ 	man/tiffdither.1, tools/tiff2ps.c, tools/tiffcp.c,
+ 	tools/tiffdither.c: Sync tool usage printouts and man pages with
+ 	reality (quite a few options had escaped being documented in one
+ 	or both places).  Per an old report from Miroslav Vadkerti.
+
+2013-01-25  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
+
+	* tools/tiff2ps.c:Fix bug in auto rotate option code. Once a
+	rotation angle was set by the auto rotate check, it was retained
+	for all pages that followed instead ofa being retested for each
+	page.  Patch by Richard Nolde.
+
+2013-01-18  Frank Warmerdam  <warmerdam at google.com>
+
+	* libtiff/tif_write.c: tmsize_t related casting warning fixed for
+	64bit linux.
+
+	* libtiff/tif_read.c: uint64/tmsize_t change for MSVC warnings.
+	http://bugzilla.maptools.org/show_bug.cgi?id=2427
+
+2012-12-20  Tom Lane  <tgl at sss.pgh.pa.us>
+
+	* test/raw_decode.c: Relax raw_decode's pixel-value checks so that
+	it will pass with more versions of libjpeg.  (There are at least
+	three in active use now, and JPEG_LIB_VERSION doesn't tell us
+	enough to uniquely identify expected results.)
+
+2012-12-12  Tom Lane  <tgl at sss.pgh.pa.us>
+
+	* libtiff/tif_print.c: Fix TIFFPrintDirectory's handling of
+	field_passcount fields: it had the TIFF_VARIABLE and
+	TIFF_VARIABLE2 cases backwards.
+
+2012-12-10  Tom Lane  <tgl at sss.pgh.pa.us>
+
+	* tools/ppm2tiff.c: Improve previous patch for CVE-2012-4564:
+ 	check the linebytes calculation too, get the max() calculation
+ 	straight, avoid redundant error messages, check for malloc
+ 	failure.
+
+2012-12-10  Tom Lane  <tgl at sss.pgh.pa.us>
+
+	* libtiff/tif_pixarlog.c: Improve previous patch for CVE-2012-4447
+ 	(to enlarge tbuf for possible partial stride at end) so that
+ 	overflow in the integer addition is detected.  Per gripe from
+ 	Huzaifa Sidhpurwala.
+
+2012-12-03  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
+
+	* tools/tiffset.c: tiffset now supports a -u option to unset a
+	tag.  Patch by Zach Baker. See
+	http://bugzilla.maptools.org/show_bug.cgi?id=2419
+
+2012-11-18  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
+
+	* automake: Update Automake to 1.12.5 release.
+
+	* libtiff/tif_{unix,vms,win32}.c (_TIFFmalloc): ANSI C does not
+	require malloc() to return NULL pointer if requested allocation
+	size is zero.  Assure that _TIFFmalloc does.
+
+2012-11-01  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* tools/ppm2tiff.c: avoid zero size buffer vulnerability.
+	CVE-2012-4564 - Thanks to Huzaifa Sidhpurwala of the
+	Red Hat Security Response team for the fix.
+
+2012-10-18  Frank Warmerdam  <warmerdam at google.com>
+
+	* tif_zip.c: Avoid crash on NULL error messages.
+
 2012-09-22  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
 
 	* libtiff 4.0.3 released.
@@ -24,7 +449,7 @@
 
 2012-08-02  Frank Warmerdam  <warmerdam at google.com>
 
-	* libtiff/tif_dirread.c: report error in case of mismatch value 
+	* libtiff/tif_dirread.c: report error in case of mismatch value
 	counts for tags (ie. DotRange).
 
 2012-07-26  Tom Lane  <tgl at sss.pgh.pa.us>
@@ -78,7 +503,7 @@
 
 2012-06-19  Frank Warmerdam  <warmerdam at google.com>
 
-	* libtiff/tif_packbits.c: fix read past end of data buffer. 
+	* libtiff/tif_packbits.c: fix read past end of data buffer.
 
 2012-06-15  Frank Warmerdam  <warmerdam at google.com>
 
@@ -118,7 +543,7 @@
 
 	* libtiff/tif_dir.c, tif_print.c : Remove FIELD_CUSTOM handling for
 	PAGENUMBER, HALFTONEHINTS, and YCBCRSUBSAMPLING.  Implement DOTRANGE
-	differently.  This is to avoid using special TIFFGetField/TIFFSetField 
+	differently.  This is to avoid using special TIFFGetField/TIFFSetField
 	rules for these fields in non-image directories (like EXIF).
 
 2012-06-04  Frank Warmerdam  <warmerdam at google.com>
@@ -214,7 +639,7 @@
 2012-01-31  Frank Warmerdam  <warmerdam at pobox.com>
 
 	* libtiff/tif_dir.c, libtiff/tif_dirread.c: Extra caution around
-	assumption tag fetching is always successful. 
+	assumption tag fetching is always successful.
 
 	* libtiff/tif_jpeg.c: Extra caution for case where sp is NULL.
 
@@ -250,7 +675,7 @@
 	* libtiff/tif_dirread.c: fixes to deal with invalid files where
 	_TIFFFillStriles() fails, and we try to chop up strips (gdal #4372)
 
-	* libtiff/tif_dirread.c: fix error reporting when there is no 
+	* libtiff/tif_dirread.c: fix error reporting when there is no
 	tag information struct and name (gdal #4373)
 
 2011-10-22  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
@@ -295,11 +720,11 @@
 
 2011-04-20  Frank Warmerdam  <warmerdam at pobox.com>
 
-	* libtiff/tif_dirinfo.c,tiffio.h: Remove the obsolete 
-	TIFFMergeFieldInfo/TIFFFindFieldInfo/TIFFFindFieldInfoByName API. 
+	* libtiff/tif_dirinfo.c,tiffio.h: Remove the obsolete
+	TIFFMergeFieldInfo/TIFFFindFieldInfo/TIFFFindFieldInfoByName API.
 	http://bugzilla.maptools.org/show_bug.cgi?id=2315
 
-	* libtiff/libtiff.def: add some missing (64bit) APIs.  
+	* libtiff/libtiff.def: add some missing (64bit) APIs.
 	http://bugzilla.maptools.org/show_bug.cgi?id=2316
 
 2011-04-09  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
@@ -342,8 +767,8 @@
 
 2011-03-21  Frank Warmerdam  <warmerdam at pobox.com>
 
-	* libtiff/tif_thunder.c: Correct potential buffer overflow with 
-	thunder encoded files with wrong bitspersample set.  The libtiff 
+	* libtiff/tif_thunder.c: Correct potential buffer overflow with
+	thunder encoded files with wrong bitspersample set.  The libtiff
 	development team would like to thank Marin Barbella and TippingPoint's
 	Zero Day Initiative for reporting this vulnerability (ZDI-CAN-1004,
 	CVE-2011-1167).
@@ -351,25 +776,25 @@
 
 2011-03-10  Frank Warmerdam  <warmerdam at pobox.com>
 
-	* libtiff/tif_fax3.h: Fix to last change allowing zero length 
+	* libtiff/tif_fax3.h: Fix to last change allowing zero length
 	runs at the start of a scanline - needed for legal cases.
 
 2011-03-02  Frank Warmerdam  <warmerdam at pobox.com>
 
-	* libtiff/tif_fax3.h: Protect against a fax VL(n) codeword commanding 
-	a move left.  Without this, a malicious input file can generate an 
-	indefinitely large series of runs without a0 ever reaching the right 
+	* libtiff/tif_fax3.h: Protect against a fax VL(n) codeword commanding
+	a move left.  Without this, a malicious input file can generate an
+	indefinitely large series of runs without a0 ever reaching the right
 	margin, thus overrunning our buffer of run lengths.  Per CVE-2011-0192.
-	This is a modified version of a patch proposed by Drew Yao of Apple 
-	Product Security.  It adds an unexpected() report, and disallows the 
-	equality case, since emitting a run without increasing a0 still allows 
+	This is a modified version of a patch proposed by Drew Yao of Apple
+	Product Security.  It adds an unexpected() report, and disallows the
+	equality case, since emitting a run without increasing a0 still allows
 	buffer overrun.
 
 2011-02-23  Frank Warmerdam  <warmerdam at pobox.com>
 
 	* libtiff/tif_jpeg.c: avoid divide by zero in degenerate case (#2296)
 
-	* tools/tiff2rgba.c: close source file on error to make leak 
+	* tools/tiff2rgba.c: close source file on error to make leak
 	detection easier.
 
 	* libtiff/tif_getimage.c: avoid leaks if TIFFRGBAImageBegin() fails.
@@ -384,15 +809,15 @@
 2011-02-18  Frank Warmerdam  <warmerdam at pobox.com>
 
 	* configure.ac, configure: Added support for --enable-chunky-strip-read
-	configure option to enable the experimental feature from a couple 
-	months ago for reading big strips in chunks. 
+	configure option to enable the experimental feature from a couple
+	months ago for reading big strips in chunks.
 
-	* configure.ac, tif_read.c, tif_readdir.c, tif_dir.h, tiffiop.h, 
+	* configure.ac, tif_read.c, tif_readdir.c, tif_dir.h, tiffiop.h,
 	tif_write.c, tif_print.c, tif_jpeg.c, tif_dirwrite.c, tif_write.c:
-	Implement optional support for deferring the load of strip/tile 
+	Implement optional support for deferring the load of strip/tile
 	offset and size tags for optimized scanning of directories.  Enabled
 	with the --enable-defer-strile-load configure option (DEFER_STRILE_LOAD
-	#define in tif_config.h). 
+	#define in tif_config.h).
 
 2011-02-11  Frank Warmerdam  <warmerdam at pobox.com>
 
@@ -401,7 +826,7 @@
 2011-02-09  Frank Warmerdam  <warmerdam at pobox.com>
 
 	* libtiff/tif_win32.c: avoid error/warning buffer overrun problem
-	with non-console (popup message) builds on win32. 
+	with non-console (popup message) builds on win32.
 
 	http://bugzilla.maptools.org/show_bug.cgi?id=2293
 
@@ -417,18 +842,18 @@
 
 2011-01-06  Frank Warmerdam  <warmerdam at pobox.com>
 
-	* libtiff/tif_pixarlog.c: Note that tif_rawcc/tif_rawcp are not 
-	maintained.  
+	* libtiff/tif_pixarlog.c: Note that tif_rawcc/tif_rawcp are not
+	maintained.
 
-	* libtiff/tif_zip.c: Maintain tif_rawcc/tif_rawcp when decoding 
+	* libtiff/tif_zip.c: Maintain tif_rawcc/tif_rawcp when decoding
 	for CHUNKY_STRIP_READ_SUPPORT.
 
 	* libtiff/tif_jpeg.c: ensure that rawcc and rawcp are maintained
-	during JPEGPreDecode and JPEGDecode calls.  
-	* libtiff/tif_read.c: larger read ahead for CHUNKY_STRIP_READ_SUPPORT, 
-	as compression formats like JPEG keep 16 lines interleaved in a sense 
-	and might need to touch	quite a bit of data. 
-	
+	during JPEGPreDecode and JPEGDecode calls.
+	* libtiff/tif_read.c: larger read ahead for CHUNKY_STRIP_READ_SUPPORT,
+	as compression formats like JPEG keep 16 lines interleaved in a sense
+	and might need to touch	quite a bit of data.
+
 	http://trac.osgeo.org/gdal/ticket/3894
 
 2011-01-03  Lee Howard <faxguy at howardsilvan.com>
@@ -510,7 +935,7 @@
 
 2010-12-12  Lee Howard <faxguy at howardsilvan.com>
 
-	* tools/tiff2pdf.c: fix colors for images with RGBA 
+	* tools/tiff2pdf.c: fix colors for images with RGBA
 	interleaved data
 	http://bugzilla.maptools.org/show_bug.cgi?id=2250
 
@@ -591,7 +1016,7 @@
 2010-10-21  Frank Warmerdam  <warmerdam at pobox.com>
 
 	* tools/tiffinfo.c: avoid direct reference to _TIFFerrorHandler.
-	
+
 	* libtiff/tif_config.vc.h: define snprintf to _snprintf for tiff2pdf.
 
 	* libtiff/libtiff.def: export _TIFFCheckMalloc for tools.
@@ -692,11 +1117,11 @@
 
 	* libtiff/tif_dirinfo.c: Fix invocation of tag compare function (#2201)
 
-	* tools/tiff2pdf.c: Fix assorted bugs in tiff2pdf: missing "return" 
-	in t2p_read_tiff_size() causes t2p->tiff_datasize to be set entirely 
-	wrong for COMPRESSION_JPEG case, resulting in memory stomp if actual 
-	size is larger.  Also, there are a bunch of places that try to 
-	memset() a malloc'd buffer before checking for malloc failure, which 
+	* tools/tiff2pdf.c: Fix assorted bugs in tiff2pdf: missing "return"
+	in t2p_read_tiff_size() causes t2p->tiff_datasize to be set entirely
+	wrong for COMPRESSION_JPEG case, resulting in memory stomp if actual
+	size is larger.  Also, there are a bunch of places that try to
+	memset() a malloc'd buffer before checking for malloc failure, which
 	would result in core dump if there actually were a failure. (#2211)
 
 2010-06-11  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
@@ -772,13 +1197,13 @@
 
 2010-05-07  Frank Warmerdam  <warmerdam at pobox.com>
 
-	* libtiff/tif_jpeg.c: Ensure that quality is always set in 
-	JPEGPreEncode(), not just when we want to output local tables.  
+	* libtiff/tif_jpeg.c: Ensure that quality is always set in
+	JPEGPreEncode(), not just when we want to output local tables.
 	Otherwise the quality used during compression may not be right and
 	might not match the tables in the tables tag.   This bug only occurs
 	when seeking between directories in the midst of writing blocks.
 	http://trac.osgeo.org/gdal/ticket/3539
-	
+
 2010-05-06  Andrey Kiselev  <dron at ak4719.spb.edu>
 
 	* html/man/TIFFGetField.3tiff.html, html/man/TIFFSetField.3tiff.html:
@@ -801,9 +1226,9 @@
 
 2010-04-21  Frank Warmerdam  <warmerdam at pobox.com>
 
-	* libtiff/tif_jpeg.c: avoid preparing jpeg tables everytime 
-	JPEGSetupEncode() is called if the tables already seem to be 
-	established.  This prevents spurious updates and rewriting of 
+	* libtiff/tif_jpeg.c: avoid preparing jpeg tables everytime
+	JPEGSetupEncode() is called if the tables already seem to be
+	established.  This prevents spurious updates and rewriting of
 	directories with jpegtables when doing updates to existing images.
 	http://trac.osgeo.org/gdal/ticket/3539
 
@@ -828,7 +1253,7 @@
 
 2010-04-02  Frank Warmerdam  <warmerdam at pobox.com>
 
-	* libtiff/tif_read.c (primarily): Add support for 
+	* libtiff/tif_read.c (primarily): Add support for
 	CHUNKY_STRIP_READ_SUPPORT where large strips are
 	read in chunks for applications using TIFFReadScanline().
 	This is intended to make it more practical work with very
@@ -857,11 +1282,11 @@
 2010-02-22  Lee Howard  <faxguy at howardsilvan.com>
 
 	* libtiff/tif_jpeg.c: Do not generate a JPEGTables tag when creating
-	the JPEG TIFF as is is not required in order to prevent it from 
-	being unused and filled with invalid data.  (Leave it to be 
+	the JPEG TIFF as is is not required in order to prevent it from
+	being unused and filled with invalid data.  (Leave it to be
 	generated by later activity.)
 	http://bugzilla.maptools.org/show_bug.cgi?id=2135
-	* tools/tiff2pdf.c: Write the JPEG SOI headers into the TIFF strip 
+	* tools/tiff2pdf.c: Write the JPEG SOI headers into the TIFF strip
 	data rather than skipping them.  This fixes the ability to view in
 	Acrobat Reader, Evince, and Ghostscript.
 	http://bugzilla.maptools.org/show_bug.cgi?id=2135
@@ -872,7 +1297,7 @@
 2009-12-03  Frank Warmerdam  <warmerdam at pobox.com>
 
 	* libtiff/tif_jpeg.c: Made JPEGDecodeRaw() check for buffer overruns.
-	Made so that when working with downsampled images a stub function 
+	Made so that when working with downsampled images a stub function
 	reporting an error is used for tif_decoderow.  We cannot meaningfully
 	support reading scanlines in this situation.  (#1936)
 
@@ -882,17 +1307,17 @@
 
 2009-11-30  Frank Warmerdam  <warmerdam at pobox.com>
 
-	* contrib/dbs/tiff-grayscale.c, contrib/tif-palette.c, 
+	* contrib/dbs/tiff-grayscale.c, contrib/tif-palette.c,
 	tools/ras2tiff.c: Fix resource leaks on error.
 	http://bugzilla.maptools.org/show_bug.cgi?id=2121
 
-	* libtiff/tif_{aux.c,dir.c,dir.h,dirinfo.c}: Return to handling 
+	* libtiff/tif_{aux.c,dir.c,dir.h,dirinfo.c}: Return to handling
 	TIFFTAG_REFERENCEBLACKWHITE as a field in the TIFF directory instead
 	of as a custom(generic) field to avoid a potential reentrancy problem.
 	http://bugzilla.maptools.org/show_bug.cgi?id=2125
-	
+
 	* libtiff/tif_color.c, libtiff/tif_getimage.c, libtiff/tiffio.h,
-	man/TIFFcolor.3tiff: Make TIFFDisplay argument in TIFFCIELabToRGBInit 
+	man/TIFFcolor.3tiff: Make TIFFDisplay argument in TIFFCIELabToRGBInit
 	const, and display_sRGB static and const.
 	http://bugzilla.maptools.org/show_bug.cgi?id=2124
 
@@ -954,7 +1379,7 @@
 2009-09-03  Frank Warmerdam  <warmerdam at pobox.com>
 
 	* libtiff/tif_getimage.c: Fixed error recognition handling in RGBA
-	interface when stoponerror is set. 
+	interface when stoponerror is set.
 	http://bugzilla.maptools.org/show_bug.cgi?id=2071
 
 2009-08-30  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
@@ -1003,7 +1428,7 @@
 
 	* libtiff/tif_dirread.c (TIFFReadCustomDirectory): Apply patch
 	from Jay Berkenbilt for "Bug 1895 - logic error in tif_dirread.c:
-	segfault after setting tdir_tag = IGNORE".	
+	segfault after setting tdir_tag = IGNORE".
 	http://bugzilla.maptools.org/show_bug.cgi?id=1895
 
 2009-08-23  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
@@ -1012,7 +1437,7 @@
 	tiffcrop.sh into a collection of many specific tests.  Re-wrote
 	all of the existing tests to be based on some simple shell
 	functions.  Make distcheck works again.
-	
+
 	Export certain variables (MAKE, MAKEFLAGS, MEMCHECK) to tests and
 	added 'memcheck' and 'ptrcheck' targets to make it easy to run the
 	tests under valgrind.
@@ -1046,7 +1471,7 @@
 	1 on success instead of zero.
 	http://bugzilla.maptools.org/show_bug.cgi?id=2069
 
-	* libtiff/tif_lzw.c: back out patch from #2065 and apply patch from 
+	* libtiff/tif_lzw.c: back out patch from #2065 and apply patch from
 	#1085 for a better underflow fix that errors properly.
 	http://bugzilla.maptools.org/show_bug.cgi?id=2065
 	http://bugzilla.maptools.org/show_bug.cgi?id=1985
@@ -1058,13 +1483,13 @@
 
 2009-06-22  Frank Warmerdam  <warmerdam at pobox.com>
 
-	* libtiff/tif_lzw.c: Fix buffer underflow bug. 
+	* libtiff/tif_lzw.c: Fix buffer underflow bug.
 	http://bugzilla.maptools.org/show_bug.cgi?id=2065
 
 2009-06-21  Frank Warmerdam  <warmerdam at pobox.com>
 
 	* configure.ac, libtiff/tif_jpeg.c, libtiff/tif_jpeg_12.c: add support
-	for dual mode 8/12 bit jpeg support. 
+	for dual mode 8/12 bit jpeg support.
 
 2009-06-03  Frank Warmerdam  <warmerdam at pobox.com>
 
@@ -1081,7 +1506,7 @@
 	* libtiff/{tif_jpeg.c,tif_ojpeg.c,tif_getimage.c}: Fixed various
 	error reports to use "%s" as format string.
 	http://trac.osgeo.org/gdal/ticket/2976
-	
+
 2009-03-12  Frank Warmerdam  <warmerdam at pobox.com>
 
 	* libtiff/{tif_fax3.c,tif_jpeg.c,tif_ojpeg.c}: Fix printdir chaining
@@ -1089,7 +1514,7 @@
 
 2009-02-12  Frank Warmerdam  <warmerdam at pobox.com>
 
-	* libtiff/tif_luv.c: Fix handling of tiled logluv images. 
+	* libtiff/tif_luv.c: Fix handling of tiled logluv images.
 	http://bugzilla.maptools.org/show_bug.cgi?id=2005
 
 2009-02-09  Frank Warmerdam  <warmerdam at pobox.com>
@@ -1105,17 +1530,17 @@
 2009-02-05  Frank Warmerdam  <warmerdam at pobox.com>
 
 	* libtiff/tif_dirread.c: Re-incorporated a sanity check on tag size,
-	but at the 2GB boundary to avoid overflow on 32bit systems. 
+	but at the 2GB boundary to avoid overflow on 32bit systems.
 	http://bugzilla.maptools.org/show_bug.cgi?id=1993
 
 	* libtiff/tif_dirread.c: Remove some assertions that blow due to
-	corrupt files rather than in response to library internal 
-	inconsistencies.  
+	corrupt files rather than in response to library internal
+	inconsistencies.
 	http://bugzilla.maptools.org/show_bug.cgi?id=1995
 	http://bugzilla.maptools.org/show_bug.cgi?id=1991
 
 	* libtiff/tif_dirread.c: Fixed testing for failed result from
-	TIFFReadDirectoryFindFieldInfo().  
+	TIFFReadDirectoryFindFieldInfo().
 	http://bugzilla.maptools.org/show_bug.cgi?id=1992
 
 2009-01-23  Frank Warmerdam  <warmerdam at pobox.com>
@@ -1124,17 +1549,17 @@
 	http://bugzilla.maptools.org/show_bug.cgi?id=1911
 
 	* libtiff/tif_dirwrite.c: Fix byte swapping of next directory offset.
-	
+
 	http://bugzilla.maptools.org/show_bug.cgi?id=1924
 
-	* tools/tiffcrop.c: initialize xres/yres values. 
+	* tools/tiffcrop.c: initialize xres/yres values.
 
 	* test/*.sh - default ${srcdir} to local directory.
 
-	* test/common.sh - start verbose mode after common settings. 
+	* test/common.sh - start verbose mode after common settings.
 
-	* libtiff/tif_dirinfo.c: Replace lfind() with local equivelent to 
-	avoid type mismatches on different platforms. 
+	* libtiff/tif_dirinfo.c: Replace lfind() with local equivelent to
+	avoid type mismatches on different platforms.
 	http://bugzilla.maptools.org/show_bug.cgi?id=1889
 
 2009-01-22  Frank Warmerdam  <warmerdam at pobox.com>
@@ -1143,7 +1568,7 @@
 	tiffsplit.c}: avoid warnings, mostly 32bit/64bit casting issues.
 
 	* port,tools: Introduce libport.h, and include in tools if NEED_LIBPORT
-	defined, primarily to reduce prototype warnings on windows. 
+	defined, primarily to reduce prototype warnings on windows.
 
 	* libtiff/tif_dirinfo.c,tif_dirread.c: Avoid warnings
 	about unused parameters, and uninitialized variables.
@@ -1191,7 +1616,7 @@
 	for TIFFError(), TIFFErrorExt(), TIFFWarning(), and
 	TIFFWarningExt() in order to reveal bugs.
 
-	* Many fixes throughout to work better as a 64-bit build. 
+	* Many fixes throughout to work better as a 64-bit build.
 
 2008-12-30  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
 
@@ -1242,7 +1667,7 @@
 2008-10-09  Frank Warmerdam  <warmerdam at pobox.com>
 
 	* libtiff/tif_jpeg.c: Add #ifdefs for changes needed if using
-	IPP enabled version of libjpeg from Intel. 
+	IPP enabled version of libjpeg from Intel.
 	http://bugzilla.maptools.org/show_bug.cgi?id=1951
 
 2008-09-05  Andrey Kiselev  <dron at ak4719.spb.edu>
@@ -1285,7 +1710,7 @@
 
 2008-07-29  Frank Warmerdam  <warmerdam at pobox.com>
 
-	* tif_strip.c: Replace assertions related to samplesperpixel != 3 or 
+	* tif_strip.c: Replace assertions related to samplesperpixel != 3 or
 	the subsampling values not being 1, 2 or 4 (for jpeg compressed images)
 	with control logic to return runtime errors (c/o Even Rouault) (#1927).
 
@@ -1325,13 +1750,13 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 2008-05-24  Frank Warmerdam  <warmerdam at pobox.com>
 
-	* tif_codec.c: Avoid NULL pointer dereferencing for exotic 
+	* tif_codec.c: Avoid NULL pointer dereferencing for exotic
 	compression codec codes.
 
 	* tif_dirwrite.c: fix potential memory leak.
 
 	* tif_dirread.c: Fix unchecked malloc result.
- 
+
 2008-05-24  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
 
 	* test {tiff2pdf.sh tiff2ps-EPS1.sh tiff2ps-PS1.sh tiff2ps-PS2.sh
@@ -1365,7 +1790,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 	* libtiff/tif_dirinfo.c: Use TIFF_SETGET_ASCII for PIXAR_TEXTUREFORMAT
 	and PIXAR_WRAPMODES instead of TIFF_SETGET_UNDEFINED.  Not exactly clear
-	why this is needed. 
+	why this is needed.
 
 2008-05-09  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
 
@@ -1406,25 +1831,25 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 2008-03-14  Frank Warmerdam  <warmerdam at pobox.com>
 
 	* tif_dirread.c: Removed sanity checks on tags larger than 4MB in
-	TIFFReadDirEntryArray() since they are interfering with seemingly 
+	TIFFReadDirEntryArray() since they are interfering with seemingly
 	legitimate files.  http://trac.osgeo.org/gdal/ticket/2005
 
 2008-02-09  Joris Van Damme  <joris.at.lebbeke at skynet.be>
 
-	* tif_dirread.c: Added handling for the case of number of values for 
-	PageNumber tag different from 2 (previously resulted in an assert 
+	* tif_dirread.c: Added handling for the case of number of values for
+	PageNumber tag different from 2 (previously resulted in an assert
 	indicating lack of handling and was forgotten about)
 
 2008-02-01  Frank Warmerdam  <warmerdam at pobox.com>
 
-	* libtiff/tif_jpeg.c: Do not try to fixup subsampling tags based on 
+	* libtiff/tif_jpeg.c: Do not try to fixup subsampling tags based on
 	the actual jpeg data stream if the first strip/tile has zero size.
 	This is the case when GDAL creates a new file with zero sizes, closes
 	and reopens it.
 
 2008-01-07  Frank Warmerdam  <warmerdam at pobox.com>
 
-	* tools/tiff2ps.c: fix up 64bit issues (from Edward Lam). 
+	* tools/tiff2ps.c: fix up 64bit issues (from Edward Lam).
 
 2008-01-01  Frank Warmerdam  <warmerdam at pobox.com>
 
@@ -1434,14 +1859,14 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	targets.
 
 	* tools/tiffinfo.c, tools/tiffcmp.c, tools/gif2tiff.c, tools/bmp2tiff.c
-	tools/tiff2pdf.c: Fix 64-bit warnings when compiling under MSVC 2005 
-	(x64). 
+	tools/tiff2pdf.c: Fix 64-bit warnings when compiling under MSVC 2005
+	(x64).
 
-	* tools/tiffset.c: Changes to reflect the fact that TIFFFieldWithTag() 
+	* tools/tiffset.c: Changes to reflect the fact that TIFFFieldWithTag()
 	and TIFFFieldWithName() now return TIFFField pointers instead of
 	TIFFFieldInfo pointers.
 
-	* tools/tiffdump.c: Added ssize_t typedef on Windows since it doesn't 
+	* tools/tiffdump.c: Added ssize_t typedef on Windows since it doesn't
 	exist. This makes it compile again on Windows
 
 	* tif_aux.c, tif_getimage.c, tif_next.c, tif_predict.c, tif_win32.c,
@@ -1452,19 +1877,19 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 2007-12-31  Frank Warmerdam  <warmerdam at pobox.com>
 
 	* tif_dirwrite.c: Added TIFFRewriteField().  This new function
-	rewrites one field "on disk" updating an existing directory 
+	rewrites one field "on disk" updating an existing directory
 	entry.  Lots of limitations still...
 
-	* tiffiop.h, tif_write.c, tif_dirread.c, tif_flush.c: Keep track of 
-	TIFF_DIRTYSTRIP separately from TIFF_DIRTYDIRECT to indicate that 
-	the strip offset/size values are dirty but nothing else about the 
+	* tiffiop.h, tif_write.c, tif_dirread.c, tif_flush.c: Keep track of
+	TIFF_DIRTYSTRIP separately from TIFF_DIRTYDIRECT to indicate that
+	the strip offset/size values are dirty but nothing else about the
 	directory is dirty.  In flush handle "just stripmaps dirty" as a
-	special case that just rewrites these values without otherwise 
-	modifying the directory on disk using TIFFRewriteField().  
+	special case that just rewrites these values without otherwise
+	modifying the directory on disk using TIFFRewriteField().
 
 	We also modify logic so that in update mode the directory is not
 	marked dirty on read, but only when something is changed.  This
-	means we need to keep track of updates to the stripmap stuff in 
+	means we need to keep track of updates to the stripmap stuff in
 	TIFFAppendToStrip().
 
 2007-12-10  Frank Warmerdam  <warmerdam at pobox.com>
@@ -1475,7 +1900,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 2007-11-23  Frank Warmerdam  <warmerdam at pobox.com>
 
 	* tif_dir.c, tif_dirread.c, tif_dirwrite.c, tif_read.c, tif_write.c,
-	tiffiop.h: Added TIFF_BUF4WRITE flag to indicate if contents of the 
+	tiffiop.h: Added TIFF_BUF4WRITE flag to indicate if contents of the
 	rawcp/rawcc buffer are for writing and thus may require flushing.
 	Necessary to distinguish whether they need to be written to disk when
 	in mixed read/write mode and doing a mixture of writing followed by
@@ -1488,12 +1913,12 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 2007-11-02  Frank Warmerdam  <warmerdam at pobox.com>
 
-	* tif_write.c: Rip out the fancy logic in TIFFAppendToStrip() for 
-	establishing if an existing tile can be rewritten to the same location 
-	by comparing the current size to all the other blocks in the same 
-	directory.  This is dangerous in many situations and can easily 
+	* tif_write.c: Rip out the fancy logic in TIFFAppendToStrip() for
+	establishing if an existing tile can be rewritten to the same location
+	by comparing the current size to all the other blocks in the same
+	directory.  This is dangerous in many situations and can easily
 	corrupt a file.  (observed in esoteric GDAL situation that's hard to
-	document).  This change involves leaving the stripbytecount[] values 
+	document).  This change involves leaving the stripbytecount[] values
 	unaltered till TIFFAppendToStrip().  Now we only write a block back
 	to the same location it used to be at if the new data is the same
 	size or smaller - otherwise we move it to the end of file.
@@ -1501,30 +1926,30 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	* tif_dirwrite.c: Try to avoid writing out a full readbuffer of tile
 	data when writing the directory just because we have BEENWRITING at
 	some point in the past.  This was causing odd junk to be written out
-	in a tile of data when a single tile had an interleaving of reading 
-	and writing with reading last.  (highlighted by gdal 
-	autotest/gcore/tif_write.py test 7. 
+	in a tile of data when a single tile had an interleaving of reading
+	and writing with reading last.  (highlighted by gdal
+	autotest/gcore/tif_write.py test 7.
 
 	* tif_predict.c: use working buffer in PredictorEncodeTile to avoid
-	modifying callers buffer. 
+	modifying callers buffer.
 	http://trac.osgeo.org/gdal/ticket/1965
 
-	* tif_predict.c/h: more fixes related to last item, keeping a 
+	* tif_predict.c/h: more fixes related to last item, keeping a
 	distinct pfunc for encode and decode cases as these were getting
 	mixed up sometimes.
 	http://trac.osgeo.org/gdal/ticket/1948
 
 2007-11-01  Frank Warmerdam  <warmerdam at pobox.com>
 
-	* tif_predict.c/h, tif_lzw.c, tif_zip.c: Improvements so that 
+	* tif_predict.c/h, tif_lzw.c, tif_zip.c: Improvements so that
 	predictor based encoding and decoding works in read-write update
-	mode properly. 
+	mode properly.
 	http://trac.osgeo.org/gdal/ticket/1948
 
 2007-10-24  Joris Van Damme  <joris.at.lebbeke at skynet.be>
 
-	* tif_dirread.c: Fixed problem with bogus file triggering 
-	assert(td->td_planarconfig == PLANARCONFIG_CONTIG) in 
+	* tif_dirread.c: Fixed problem with bogus file triggering
+	assert(td->td_planarconfig == PLANARCONFIG_CONTIG) in
 	ChopUpSingleUncompressedStrip
 
 2007-10-22  Joris Van Damme  <joris.at.lebbeke at skynet.be>
@@ -1548,10 +1973,10 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 2007-09-29  Joris Van Damme  <joris.at.lebbeke at skynet.be>
 
-	* tif_dirread.c: Strip chopping interfered badly with uncompressed 
-	subsampled images because it tried to divide subsampled rowblocks, 
-	leading to all sorts of errors throughout the library for these 
-	images. Fixed by making strip chopping divide in row counts that 
+	* tif_dirread.c: Strip chopping interfered badly with uncompressed
+	subsampled images because it tried to divide subsampled rowblocks,
+	leading to all sorts of errors throughout the library for these
+	images. Fixed by making strip chopping divide in row counts that
 	are a multiple of vertical subsampling value.
 
 2007-09-28  Joris Van Damme  <joris.at.lebbeke at skynet.be>
@@ -1564,18 +1989,18 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 	* tif_dirread.c: Made calculation of td_maxsamplevalue more robust
 	when dealing with large bitspersample values, shutting up purification
-	tools that warn about truncation, though it remains incorrect and 
+	tools that warn about truncation, though it remains incorrect and
 	indicates a conceptual problem there.
 
-	* tif_open.c: Moved early exit in case of 'h' flag (to disable reading 
-	of first IFD) to proper place because it badly interfered with memory 
-	mapping, resulting in mapping flag even with dummy mapping functions 
-	that returned 0 whilst at the same time the mapping tif_size wasn't 
+	* tif_open.c: Moved early exit in case of 'h' flag (to disable reading
+	of first IFD) to proper place because it badly interfered with memory
+	mapping, resulting in mapping flag even with dummy mapping functions
+	that returned 0 whilst at the same time the mapping tif_size wasn't
 	set, thus resulting in continuous incorrect beyond-eof errors.
 
 2007-09-24  Joris Van Damme  <joris.at.lebbeke at skynet.be>
 
-	* tif_dirinfo.c: Fixed (MSVC) compiler reports about 
+	* tif_dirinfo.c: Fixed (MSVC) compiler reports about
 	inconsistent use of const in tiffFields and exifFields definition
 
 2007-09-20  Frank Warmerdam  <warmerdam at pobox.com>
@@ -1585,7 +2010,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	TIFFWriteDirectoryTagLongLong8Array() function was restructured
 	accordingly.
 
-	* tif_dirread.c: Improvements to error reporting text in 
+	* tif_dirread.c: Improvements to error reporting text in
 	TIFFFetchDirectory().
 
 2007-09-19  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
@@ -1599,27 +2024,27 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 2007-08-24  Frank Warmerdam  <warmerdam at pobox.com>
 
 	* tif_dirwrite.c: Write the tif_nextdiroff value instead of a fixed
-	zero when writing directory contents to preserve the ability to 
+	zero when writing directory contents to preserve the ability to
 	rewrite directories in place, even in the middle of a directory
 	chain.
 
 	* tif_dirinfo.c:  _TIFFMergeFields() now only merges in field
 	definitions that are missing.  Existing definitions are silently
-	ignored. 
+	ignored.
 
 	* tif_dirread.c: Add runtime error for fields for which no definition
-	is found (in addition to an assert for developers) in 
-	TIFFFetchNormalTag().  Not sure if this is needed, but it seems 
+	is found (in addition to an assert for developers) in
+	TIFFFetchNormalTag().  Not sure if this is needed, but it seems
 	prudent.
 
 2007-08-10  Joris Van Damme  <joris.at.lebbeke at skynet.be>
 
-	* libtiff/tif_getimage.c: removed SubsamplingHor and SubsamplingVer 
+	* libtiff/tif_getimage.c: removed SubsamplingHor and SubsamplingVer
 	from _TIFFRGBAImage structure to revert unwanted ABI change.
 
 2007-08-10  Joris Van Damme  <joris.at.lebbeke at skynet.be>
 
-	* libtiff/tif_win32.c: use SetFilePointer instead of 
+	* libtiff/tif_win32.c: use SetFilePointer instead of
 	SetFilePointerEx, as per bug
 
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=1580
@@ -1641,7 +2066,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	* libtiff/tif_dirread.c: Handle the case of MSVC 6 when using 64-bit
 	integer constants.
 
-	* libtiff/{Makefile.am, Makefile.v}: Do not distribute tiffconf.h, 
+	* libtiff/{Makefile.am, Makefile.v}: Do not distribute tiffconf.h,
 	remove tif_config.h/tiffconf.h during cleaning. As per bug
 
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=1573
@@ -1711,14 +2136,14 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	tif_win3.c}: Obsoleted portability stuff removed.
 
 	* tools/tiff2ps.c:  Added support 16-bit images as per bug
-	
+
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=1566
 
 	Patch from William Bader.
 
 	* tools/tiff2pdf.c: Fix for TIFFTAG_JPEGTABLES tag fetching and
 	significant upgrade of the whole utility as per bug
-	
+
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=1560
 
 	Now we don't need tiffiop.h in tiff2pdf anymore and will open output
@@ -1736,7 +2161,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 2007-06-25  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
 
 	* port/strtoull.c: New porting function in case strtoull() is not
-	available on the target system.	
+	available on the target system.
 	* configure.ac: Add configure support for determining sized types
 	in a portable way and performing necessary substitutions in
 	tif_config.h and tiffconf.h.  Updated tiff.h to use the new
@@ -1753,7 +2178,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	* libtiff/{tif_dir.h, tif_dirread.c, tif_dirinfo.c, tif_jpeg.c,
 	tif_fax3.c, tif_jbig.c, tif_luv.c, tif_ojpeg.c, tif_pixarlog.c,
 	tif_predict.c, tif_zip.c}: Finally fix bug
-	
+
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=1274
 
 	by introducing _TIFFMergeFieldInfo() returning integer error status
@@ -1764,7 +2189,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 2007-04-07  Frank Warmerdam  <warmerdam at pobox.com>
 
-	* contrib/addtiffo/tif_overview.c: Fix problems with odd sized output 
+	* contrib/addtiffo/tif_overview.c: Fix problems with odd sized output
 	blocks in TIFF_DownSample_Subsampled() (bug 1542).
 
 2007-04-06  Frank Warmerdam  <warmerdam at pobox.com>
@@ -1772,15 +2197,15 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	* libtiff/tif_jpeg.c: Changed JPEGInitializeLibJPEG() so that it
 	will convert from decompressor to compressor or compress to decompress
 	if required by the force arguments.  This works around a problem in
-	where the JPEGFixupTestSubsampling() may cause a decompressor to 
+	where the JPEGFixupTestSubsampling() may cause a decompressor to
 	be setup on a directory when later a compressor is required with the
-	force flag set.  Occurs with the addtiffo program for instance. 
+	force flag set.  Occurs with the addtiffo program for instance.
 
 2007-04-06  Andrey Kiselev  <dron at ak4719.spb.edu>
 
 	* tools/tiffcrop.c, man/tiffcrop.1: Significant update in
 	functionality from Richard Nolde. As per bug
-	
+
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=1525
 
 2007-03-28  Frank Warmerdam  <warmerdam at pobox.com>
@@ -1792,15 +2217,15 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	* start of BigTIFF upgrade - CVS HEAD unstable until further notice
 
 2007-03-07  Joris Van Damme  <joris.at.lebbeke at skynet.be>
-	
+
 	* libtiff/tif_getimage.c: workaround for 'Fractional scanline' error reading
 	OJPEG images with rowsperstrip that is not a multiple of vertical subsampling
 	factor. This bug is mentioned in:
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=1390
-	http://www.asmail.be/msg0054766825.html 
+	http://www.asmail.be/msg0054766825.html
 
 2007-03-07  Joris Van Damme  <joris.at.lebbeke at skynet.be>
-	
+
 	* libtiff/tif_win32.c: made inclusion of windows.h unconditional
 
 	* libtiff/tif_win32.c: replaced preprocessor indication for consiously
@@ -1850,14 +2275,14 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	larger than 2GB. Fixes bug
 
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=890
-	
+
 	Idea submitted by Matt Hancher.
 
 2007-01-31  Andrey Kiselev  <dron at ak4719.spb.edu>
 
 	* tools/tif2rgba.c: This utility does not work properly on big-endian
 	architectures. It was fixed including the bug
-	
+
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=1149
 
 2007-01-15  Mateusz Loskot <mateusz at loskot.net>
@@ -1874,15 +2299,15 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 2006-11-19  Frank Warmerdam  <warmerdam at pobox.com>
 
-	* libtiff/tif_write.c: TIFFAppendToStrip() - clear sorted flag if 
-	we move a strip. 
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=1359	
+	* libtiff/tif_write.c: TIFFAppendToStrip() - clear sorted flag if
+	we move a strip.
+	http://bugzilla.remotesensing.org/show_bug.cgi?id=1359
 
 2006-10-13  Andrey Kiselev  <dron at ak4719.spb.edu>
 
 	* libtiff/tif_dir.c: More fixes for vulnerabilities, reported
 	in Gentoo bug ():
-	
+
 	http://bugs.gentoo.org/show_bug.cgi?id=142383
 
 	* libtiff/contrib/dbs/xtiff/xtiff.c: Make xtiff utility compilable.
@@ -1916,12 +2341,12 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	* libtiff/tif_lzw.c, libtiff/tif_zip.c: Fixed problems with mixing
 	encoding and decoding on the same read-write TIFF handle.  The LZW
 	code can now maintain encode and decode state at the same time. The
-	ZIP code will switch back and forth as needed.  
+	ZIP code will switch back and forth as needed.
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=757
 
 2006-09-20  Frank Warmerdam  <warmerdam at pobox.com>
 
-	* libtiff: Rename config.h.vc and tif_config.h.vc to config.vc.h and 
+	* libtiff: Rename config.h.vc and tif_config.h.vc to config.vc.h and
 	tif_config.vc.h for easier identification by folks using an IDE.
 
 2006-07-25  Frank Warmerdam  <warmerdam at pobox.com>
@@ -1936,7 +2361,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 2006-07-12  Frank Warmerdam  <warmerdam at pobox.com>
 
-	* tif_dirwrite.c: make sure to use uint32 for wordcount in 
+	* tif_dirwrite.c: make sure to use uint32 for wordcount in
 	TIFFWriteNormanTag if writecount is VARIABLE2 for ASCII fields.
 	It already seems to have been done for other field types.  Needed
 	for "tiffset" on files with geotiff ascii text.
@@ -1964,9 +2389,9 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 2006-06-17  Frank Warmerdam  <warmerdam at pobox.com>
 
 	* tif_readdir.c: Added case in EstimateStripByteCounts() for tiled
-	files.  Modified TIFFReadDirectory() to not invoke 
+	files.  Modified TIFFReadDirectory() to not invoke
 	EstimateStripByteCounts() for case where entry 0 and 1 are unequal
-	but one of them is zero. 
+	but one of them is zero.
 	  http://bugzilla.remotesensing.org/show_bug.cgi?id=1204
 
 2006-06-08  Andrey Kiselev  <dron at ak4719.spb.edu>
@@ -1994,7 +2419,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	* {configure, configure.ac, libtiff/tif_jbig.c, tools/tiffcp.c}: Added
 	support for JBIG compression scheme (34661 code) contributed by Lee
 	Howard. As per bug
-	
+
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=896
 
 	* configure, configure.ac: OJPEG support enabled by default.
@@ -2033,7 +2458,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 2006-04-18  Frank Warmerdam  <warmerdam at pobox.com>
 
 	* nmake.opt: use /EHsc for VS2005 compatibility.  Also define
-	_CRT_SECURE_NO_DEPRECATE to avoid noise on VS2005. 
+	_CRT_SECURE_NO_DEPRECATE to avoid noise on VS2005.
 
 2006-04-12  Joris Van Damme  <joris.at.lebbeke at skynet.be>
 
@@ -2041,7 +2466,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	non-subsampled YCbCr (i.e. separate YCbCr with subsampling [1,1])
 
 2006-04-11  Joris Van Damme  <joris.at.lebbeke at skynet.be>
-	
+
 	* libtiff/tif_getimage.c: Revision of all RGB(A) put routines
 	- Conversion of unassociated alpha to associated alpha now done with
 	  more performant LUT, and calculation more correct
@@ -2050,21 +2475,21 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	- Bugfix of handling of 16bit RGB with unassociated alpha
 
 2006-04-11  Joris Van Damme  <joris.at.lebbeke at skynet.be>
-	
-	* libtiff/tif_getimage.c: 
-	- When there is no alpha, gtTileSeparate and gtStripSeparate allocated 
-	  buffer for alpha strile and filled it, only to never read it back. 
+
+	* libtiff/tif_getimage.c:
+	- When there is no alpha, gtTileSeparate and gtStripSeparate allocated
+	  buffer for alpha strile and filled it, only to never read it back.
 	  Removed allocation and fill.
-	- Minor rename of vars in gtTileSeparate and gtStripSeparate 
+	- Minor rename of vars in gtTileSeparate and gtStripSeparate
 	  anticipating planned functionality extension
 
 2006-04-08  Joris Van Damme  <joris.at.lebbeke at skynet.be>
 
-	* libtiff/tif_getimage.c: renamed pickTileContigCase to PickContigCase 
-	and pickTileSeparateCase to PickSeparateCase as both work on strips as 
+	* libtiff/tif_getimage.c: renamed pickTileContigCase to PickContigCase
+	and pickTileSeparateCase to PickSeparateCase as both work on strips as
 	well
 
-	* libtiff/tif_getimage.c: moved img->get selection from 
+	* libtiff/tif_getimage.c: moved img->get selection from
 	TIFFRGBAImageBegin into PickContigCase and PickSeparateCase to create
 	logical hook for planned functionality extension
 
@@ -2075,9 +2500,9 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 2006-04-07  Joris Van Damme  <joris.at.lebbeke at skynet.be>
 
-	* libtiff/tif_getimage.c: replaced usage of TIFFScanlineSize in 
+	* libtiff/tif_getimage.c: replaced usage of TIFFScanlineSize in
 	gtStripContig with TIFFNewScanlineSize so as to fix buggy behaviour
-	on subsampled images - this ought to get sorted when we feel brave 
+	on subsampled images - this ought to get sorted when we feel brave
 	enough to replace TIFFScanlineSize alltogether
 
 	* libtiff/tif_ojpeg.c: fixed bug in OJPEGReadSkip
@@ -2086,13 +2511,13 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 	* libtiff/tiffio.h: added new type tstrile_t
 
-	* libtiff/tif_dir.h: changed types of td_stripsperimage and td_nstrips 
-	to new tstrile_t, types of td_stripoffset and td_stripbytecount to 
+	* libtiff/tif_dir.h: changed types of td_stripsperimage and td_nstrips
+	to new tstrile_t, types of td_stripoffset and td_stripbytecount to
 	toff_t*
 
 	* libtiff/tif_ojpeg.c: totally new implementation
 
-	* libtiff/tif_dirread.c: added several hacks to suit new support of 
+	* libtiff/tif_dirread.c: added several hacks to suit new support of
 	OJPEG
 
 	* libtiff/tif_getimage.c: removed TIFFTAG_JPEGCOLORMODE handling
@@ -2132,7 +2557,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 	* libtiff/tif_getimage.c: added putcontig8bitYCbCr12tile
 
-	* libtiff/tif_read.c: added support for new TIFF_NOREADRAW flag to 
+	* libtiff/tif_read.c: added support for new TIFF_NOREADRAW flag to
 	prepare	the path for new tif_ojpeg.c
 
 2006-03-23  Andrey Kiselev  <dron at ak4719.spb.edu>
@@ -2248,7 +2673,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 	* libtiff/tif_write.c: Small code rearrangement in TIFFWriteScanline()
 	to avoid crash as per bug
-	
+
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=1081.
 
 2006-02-26  Andrey Kiselev  <dron at ak4719.spb.edu>
@@ -2298,7 +2723,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 2006-02-07  Frank Warmerdam  <warmerdam at pobox.com>
 
 	* tools/tiff2pdf.c: Fixed support for non-YCbCr encoded JPEG
-	compressed TIFF files, per submission from Dan Cobra. 
+	compressed TIFF files, per submission from Dan Cobra.
 
 2006-02-07  Andrey Kiselev  <dron at ak4719.spb.edu>
 
@@ -2330,7 +2755,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 	* libtiff/tif_dirread.c: Use _TIFFGetExifFieldInfo() instead of
 	_TIFFGetFieldInfo() in TIFFReadEXIFDirectory() call as per bug
-	
+
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=1026.
 
 2006-01-23  Andrey Kiselev  <dron at ak4719.spb.edu>
@@ -2396,7 +2821,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 2005-12-26  Andrey Kiselev  <dron at ak4719.spb.edu>
 
-	* libtiff/{tif_dir.c, tif_dir.h, tif_dirread.c, tif_dirinfo.c}: 
+	* libtiff/{tif_dir.c, tif_dir.h, tif_dirread.c, tif_dirinfo.c}:
 	tiffFieldInfo and exifFieldInfo arrays definitions moved back to
 	tif_dirinfo.c; added _TIFFGetFieldInfo() and _TIFFGetExifFieldInfo()
 	private functions to retrieve FieldInfo arrays.
@@ -2423,10 +2848,10 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 2005-12-23  Joris Van Damme  <joris.at.lebbeke at skynet.be>
 
-	* libtiff/tiffio.h: fixed typo that potentially resulted in 
+	* libtiff/tiffio.h: fixed typo that potentially resulted in
 	redefininition of USE_WIN32_FILEIO
 
-	* libtiff/*: Added more 'dual-mode' error handling: Done TIFFWarning 
+	* libtiff/*: Added more 'dual-mode' error handling: Done TIFFWarning
 	calls in core LibTiff.
 
 2005-12-21  Andrey Kiselev  <dron at ak4719.spb.edu>
@@ -2436,10 +2861,10 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 2005-12-21  Joris Van Damme  <joris.at.lebbeke at skynet.be>
 
-	* libtiff/*, contrib/*: Added 'dual-mode' error handling, enabling 
+	* libtiff/*, contrib/*: Added 'dual-mode' error handling, enabling
 	newer code to get context indicator in error handler and still
-	remain compatible with older code: Done TIFFError calls everywhere 
-	except in tools   
+	remain compatible with older code: Done TIFFError calls everywhere
+	except in tools
 
 2005-12-20  Andrey Kiselev  <dron at ak4719.spb.edu>
 
@@ -2512,7 +2937,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=1002
 
 	* .cvsignore: many files added, and a few update according
-	to suggestion of Brad HArds on tiff mailing list. 
+	to suggestion of Brad HArds on tiff mailing list.
 
 2005-11-03  Frank Warmerdam  <warmerdam at pobox.com>
 
@@ -2537,7 +2962,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=946
 
 	* tools/bmp2tiff.c: Fixed possible integer overflow error as per bug
-	
+
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=965
 
 	* libtiff/tif_dirinfo.c: Make XResolution, YResolution and
@@ -2547,7 +2972,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 	* tools/tiffsplit.c: Copy fax related fields over splitted parts
 	as per bug
-	
+
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=983
 
 2005-10-21  Frank Warmerdam  <warmerdam at pobox.com>
@@ -2603,7 +3028,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 	* libtiff/tif_dir.c: When prefreeing tv->value in TIFFSetFieldV
 	also set it to NULL to avoid double free when re-setting custom
-	string fields as per: 
+	string fields as per:
 
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=922
 
@@ -2639,7 +3064,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=831
 
 	Remove TIFFFetchExtraSamples() function, use TIFFFetchNormalTag()
-	instead. 
+	instead.
 
 	* libtiff/tiffconf.h.in: One more attempt to fix the AIX bug
 
@@ -2810,7 +3235,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 2005-05-22  Frank Warmerdam  <warmerdam at pobox.com>
 
-	* libtiff/tif_dirread.c: Changed the code that computes 
+	* libtiff/tif_dirread.c: Changed the code that computes
 	stripbytecount[0] if it appears bogus to ignore if stripoffset[0] is
 	zero. This is a common case with GDAL indicating a "null" tile/strip.
 
@@ -2820,8 +3245,8 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 2005-05-06  Frank Warmerdam  <warmerdam at pobox.com>
 
-	* libtiff/tif_dirread.c: Applied similar change to 
-	TIFFFetchPerSampleLongs and TIFFFetchPerSampleAnys. 
+	* libtiff/tif_dirread.c: Applied similar change to
+	TIFFFetchPerSampleLongs and TIFFFetchPerSampleAnys.
 
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=843
 
@@ -2871,7 +3296,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 	* man/TIFFSetField.3tiff: Fixed definition of the TIFFTAG_INKNAMES tag
 	as per bug
-	
+
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=816
 
 2005-03-30  Andrey Kiselev  <dron at ak4719.spb.edu>
@@ -2981,7 +3406,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 	* libtiff/tiffio.h: Move TIFFOpenW() function into the extern "C"{}
 	block as per bug
-	
+
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=763
 
 2005-02-03  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
@@ -3002,7 +3427,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=320
 
 	* tools/tiff2ps.c: Fixed problem with page sizes as per bug
-	
+
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=742
 
 2005-01-31  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
@@ -3043,7 +3468,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	TIFFRGBAImageBegin() as per bug
 
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=739
-	
+
 2005-01-12  Andrey Kiselev  <dron at ak4719.spb.edu>
 
 	* libtiff/tif_jpeg.c: Added ability to read/write the fax specific
@@ -3072,7 +3497,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	* libtiff/tiff.h: Restore back the workaround for AIX Visual Age C
 	compiler to avoid double definition of BSD types as per bug
 
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=39	
+	http://bugzilla.remotesensing.org/show_bug.cgi?id=39
 
 	* libtiff/Makefile.am: Place the C++ stream API in the separate
 	library called libtiffxx to avoid unneeded dependencies. Probably
@@ -3096,7 +3521,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 	* libtiff/tif_getimage.c: More fixes for multiple-alpha-channelled
 	RGB-images as per bug
-	
+
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=713
 
 
@@ -3132,7 +3557,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 2004-12-15  Frank Warmerdam  <warmerdam at pobox.com>
 
 	* libtiff/tif_getimage.c: #define A1 bracketing for clean build on
-	SunPro compiler. 
+	SunPro compiler.
 
 2004-12-11  Bob Friesenhahn  <bfriesen at simple.dallas.tx.us>
 
@@ -3144,7 +3569,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 	* libtiff/tif_dirwrite.c: Always write TIFFTAG_SUBIFD using LONG type
 	as per bugs
-	
+
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=703
 
 	and
@@ -3164,9 +3589,9 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 	* libtiff/tif_config.in.vc: Removed unneded definitions for
 	read/open/close/lseek functions to fix the
-	
+
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=680
-	
+
 2004-12-03  Andrey Kiselev  <dron at ak4719.spb.edu>
 
 	* libtiff/{tif_dir.c, tif_dirread.c}: Remove TIFFReassignTagToIgnore()
@@ -3202,7 +3627,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 2004-11-26  Frank Warmerdam  <warmerdam at pobox.com>
 
-	* libtiff/makefile.vc: make it easier to rename the libtiff DLL. 
+	* libtiff/makefile.vc: make it easier to rename the libtiff DLL.
 
 2004-11-24  Andrey Kiselev  <dron at ak4719.spb.edu>
 
@@ -3299,7 +3724,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	per bug
 
 	 http://bugzilla.remotesensing.org/show_bug.cgi?id=648
-	
+
 	* libtiff/{tif_jpeg.c, tif_ojpeg.c}: TIFFTAG_JPEGTABLES should have
 	uint32 count. Use this type everywhere.
 
@@ -3312,7 +3737,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	* tools/tiff2rgba.c: removed extra newlines in usage message.
 
 2004-10-30  Andrey Kiselev  <dron at ak4719.spb.edu>
-	
+
 	* libtiff/tif_dirwrite.c: Improvements in tag writing code.
 
 	* tools/tiff2ps.c: Fixed wrong variable data type when read Position
@@ -3327,7 +3752,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 	* libtiff/tif_fax3.c: Fixed case with the wrong decode routines
 	choosing when the incorrect Group4Options tag set. As per bug
-	
+
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=323
 
 	* libtiff/tif_dirwrite.c: Fixed problem with passing count variable of
@@ -3346,7 +3771,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	* tools/tiff2pdf.c: added casts to avoid warnings.
 
 	* libtiff/libtiff.def: Added several more entry points required
-	to link fax2tiff.c against the DLL on windows. 
+	to link fax2tiff.c against the DLL on windows.
 
 2004-10-27  Andrey Kiselev  <dron at ak4719.spb.edu>
 
@@ -3417,7 +3842,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 2004-10-08  Frank Warmerdam  <warmerdam at pobox.com>
 
 	* libtiff/tif_dirinfo.c: Fix bug with tif_foundfield and reallocation
-	of tif_fieldinfo.  
+	of tif_fieldinfo.
 
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=630
 
@@ -3449,7 +3874,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 2004-09-30  Frank Warmerdam  <warmerdam at pobox.com>
 
-	* libtiff/tif_dirinfo.c: changed type of XMLPacket (tag 700) to 
+	* libtiff/tif_dirinfo.c: changed type of XMLPacket (tag 700) to
 	TIFFTAG_BYTE instead of TIFFTAG_UNDEFINED to comply with the info
 	in the Adobe XMP Specification.
 
@@ -3469,7 +3894,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 2004-09-26  Andrey Kiselev  <dron at ak4719.spb.edu>
 
 	* libtiff/{tif_dir.h, tif_dir.c, tif_dirread.c, tif_write.c}:
-	Optimize checking for the strip bounds. 
+	Optimize checking for the strip bounds.
 
 	* libtiff/{tif_dirread.c, tif_strip.c}: TIFFScanlineSize() and
 	TIFFRasterScanlineSize() functions report zero in the case of integer
@@ -3620,7 +4045,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	here
 
 	http://www.asmail.be/msg0054799560.html
-	
+
 	for details.
 
 	* tools/fax2tiff.c: Use the new functions in the code.
@@ -3748,11 +4173,11 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	* tools/tiffsplit.c: Fixed problem with unproperly written multibyte
 	files. Now output files will be written using the same byte order
 	flag as	in the input image. See
-	
+
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=574
-	
+
 	for details.
-	
+
 2004-05-19  Frank Warmerdam  <warmerdam at pobox.com>
 
 	* libtiff/tif_print.c: added (untested) support for printing
@@ -3764,7 +4189,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 	* libtiff/tif_fax3.c: Avoid reading CCITT compression options
 	if compression type mismatches. See
-	
+
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=565
 
 2004-04-30  Andrey Kiselev  <dron at ak4719.spb.edu>
@@ -3809,7 +4234,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 2004-04-04  Frank Warmerdam  <warmerdam at pobox.com>
 
 	* libtiff/tif_open.c: close clientdata if TIFFClientOpen() fails
-	via bad2. 
+	via bad2.
 
 2004-03-26  Andrey Kiselev  <dron at ak4719.spb.edu>
 
@@ -3836,10 +4261,10 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 2004-02-26  Andrey Kiselev  <dron at ak4719.spb.edu>
 
-	* tools/tiffsplit.c: Copy JPEGTables tag contents for JPEG compressed 
+	* tools/tiffsplit.c: Copy JPEGTables tag contents for JPEG compressed
 	images. Reported by Artem Mirolubov.
 
-	* libtiff/tif_dirread.c: Fixed problem with handling TIFF_UNDEFINED 
+	* libtiff/tif_dirread.c: Fixed problem with handling TIFF_UNDEFINED
 	tag type in TIFFFetchNormalTag() as per bug
 
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=508
@@ -3861,8 +4286,8 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 2004-01-30  Frank Warmerdam  <warmerdam at pobox.com>
 
 	* libtiff/libtiff.def: Added TIFFCurrentDirOffset, TIFFWriteCheck,
-	TIFFRGBAImageOK, and TIFFNumberOfDirectories as suggested by 
-	Scott Reynolds. 
+	TIFFRGBAImageOK, and TIFFNumberOfDirectories as suggested by
+	Scott Reynolds.
 
 2004-01-29  Andrey Kiselev  <dron at ak4719.spb.edu>
 
@@ -3880,7 +4305,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	file if TIFFFdOpen() failed as per bug
 
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=468
-	
+
 	* libtiff/tif_open.c: More fixes for
 
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=468
@@ -3904,7 +4329,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	* libtiff/tif_dirwrite.c: Fixed handling of writable ASCII tags that
 	are field_passcount=TRUE properly.  Arguably anonymous custom tags
 	should be declared as passcount=FALSE, but I don't want to change
-	that without a careful review. 
+	that without a careful review.
 
 2004-01-20  Andrey Kiselev  <dron at ak4719.spb.edu>
 
@@ -4067,8 +4492,8 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 2003-11-17  Frank Warmerdam  <warmerdam at pobox.com>
 
-	* tif_dirread.c: do not mark all anonymously defined tags to be 
-	IGNOREd.  
+	* tif_dirread.c: do not mark all anonymously defined tags to be
+	IGNOREd.
 
 2003-11-17  Andrey Kiselev  <dron at ak4719.spb.edu>
 
@@ -4108,15 +4533,15 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 2003-11-09  Frank Warmerdam  <warmerdam at pobox.com>
 
-	* libtiff/tif_tile.c: remove spurious use of "s" (sample) in the 
+	* libtiff/tif_tile.c: remove spurious use of "s" (sample) in the
 	planarconfig_contig case in TIFFComputeTile().
 
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=387
 
 2003-11-09  Andrey Kiselev  <dron at ak4719.spb.edu>
-	
+
 	* libtiff/tiffiop.h: New macros: TIFFmax, TIFFmin and TIFFrint.
-	
+
 2003-11-07  Andrey Kiselev  <dron at ak4719.spb.edu>
 
 	* libtiff/{tiffio.h, tif_strip.c}, man/{TIFFstrip.3t, libtiff.3t}:
@@ -4183,11 +4608,11 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	function TIFFReadRGBAImageOriented() implemented to retrieve raster
 	array with user-specified origin position as suggested by Jason Frank.
 	See
-	
+
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=322
 
 	for details.
-	
+
 	* tools/tiff2rgba.c: Switched to use TIFFReadRGBAImageOriented()
 	instead of TIFFReadRGBAImage().
 
@@ -4268,9 +4693,9 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	encoded write functions use tif_postdecode() to apply byte order
 	swapping (swab) to the application passed data buffer if the same
 	would be done when reading.  This allows us to write pixel data with
-	more than 8 bits per sample to existing files of a non-native byte 
+	more than 8 bits per sample to existing files of a non-native byte
 	order.  One side effect of this change is the applications buffer
-	itself is altered in this case by the act of writing. 
+	itself is altered in this case by the act of writing.
 
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=171
 
@@ -4296,9 +4721,9 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 2003-07-08  Frank Warmerdam  <warmerdam at pobox.com>
 
 	* tif_aux.c, tif_codec.c, tif_dir.c, tif_dirread.c, tif_extension.c,
-	tif_fax3.c, tif_getimage.c, tif_luv.c, tif_lzw.c, tif_next.c, 
+	tif_fax3.c, tif_getimage.c, tif_luv.c, tif_lzw.c, tif_next.c,
 	tif_packbits.c, tif_predict.c, tif_print.c, tif_swab.c, tif_thunder.c:
-	avoid casting warning at /W4. 
+	avoid casting warning at /W4.
 
 2003-07-03  Andrey Kiselev  <dron at ak4719.spb.edu>
 
@@ -4320,11 +4745,11 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 	* libtiff/tif_dirinfo.c: TIFFDataWidth() returns 0 in case of
 	unknown data type.
-	
+
 2003-06-19  Frank Warmerdam  <warmerdam at pobox.com>
 
 	* libtiff/tif_print.c: fixed some serious bugs when printing
-	custom tags ... almost certain to crash. 
+	custom tags ... almost certain to crash.
 
 	* libtiff/tif_dirread.c: Don't ignore custom fields that are
 	autodefined.  Not sure how this got to be like this.
@@ -4335,12 +4760,12 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 	* tools/tiffcmp.c, man/tiffcmp.1: Fixed problem with unused data
 	comparing as per bug
-	
+
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=349
 
 	`-z' option now can be used to set the number of reported different
 	bytes.
-	
+
 2003-06-09  Andrey Kiselev  <dron at ak4719.spb.edu>
 
 	* tools/tiffcp.c, man/tiffcp.1: Added possibility to specify value -1
@@ -4366,7 +4791,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 2003-05-25  Andrey Kiselev  <dron at ak4719.spb.edu>
 
 	* tools/fax2tiff.c: Page numbering fixed, as per bug
-	
+
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=341
 
 2003-05-20  Andrey Kiselev  <dron at ak4719.spb.edu>
@@ -4432,7 +4857,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 	* tools/tiffcp.c: Fixed problem with colorspace conversion for JPEG
 	encoded images. See bug entries
-	
+
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=275
 
 	and
@@ -4493,16 +4918,16 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 	* libtiff/tif_jpeg.c: Modified to defer initialization of jpeg
 	library so that we can check if there is already any tile/strip data
-	before deciding between creating a compressor or a decompressor. 
+	before deciding between creating a compressor or a decompressor.
 
 2003-01-31  Frank Warmerdam  <warmerdam at pobox.com>
 
 	* libtiff/tif_write.c: TIFFWriteCheck() now fails if the image is
-	a pre-existing compressed image.  That is, image writing to 
+	a pre-existing compressed image.  That is, image writing to
 	pre-existing compressed images is not allowed.
 
 	* libtiff/tif_open.c: Removed error if opening a compressed file
-	in update mode. 
+	in update mode.
 
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=198
 
@@ -4515,16 +4940,16 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	* cut 3.6.0 Beta release.
 
 2002-12-20  Andrey Kiselev  <dron at ak4719.spb.edu>
-	
+
 	* tools/fax2ps.c, man/fax2ps.1: Page size was determined
 	in wrong way as per bug
-	
+
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=239
 
 2002-12-17  Frank Warmerdam  <warmerdam at pobox.com>
 
-	* libtiff/tif_dirread.c: Allow wrong sized arrays in 
-	TIFFFetchStripThing(). 
+	* libtiff/tif_dirread.c: Allow wrong sized arrays in
+	TIFFFetchStripThing().
 
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=49
 
@@ -4538,7 +4963,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	* libtiff/tif_dir.c: fixed bug with resetting an existing custom
 	field value.
 
-	* libtiff/tif_dir.c: Fixed potential problem with ascii "custom" 
+	* libtiff/tif_dir.c: Fixed potential problem with ascii "custom"
 	tags in TIFFVGetField() ... added missing break.
 
 2002-10-14  Frank Warmerdam  <warmerdam at pobox.com>
@@ -4550,11 +4975,11 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	the eps by redefining the colorimage operator will get messed up.
 	Patch supplied by William Bader.
 
-	* Makefile.in: added tif_extension.c to file list as per 
+	* Makefile.in: added tif_extension.c to file list as per
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=218.
 
 2002-10-11  Andrey Kiselev  <dron at ak4719.spb.edu>
-	
+
 	* configure, config.site, libtiff/{tif_unix.c, Makefile.in}: Fix for
 	large files (>2GiB) supporting. New option in the config.site:
 	LARGEFILE="yes". Should be enough for I/O of the large files.
@@ -4586,13 +5011,13 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 2002-10-06  Frank Warmerdam  <warmerdam at pobox.com>
 
 	* libtiff/tif_jpeg.c: fixed problem with boolean defined with wrong
-	size on windows.  Use #define boolean hack.  
+	size on windows.  Use #define boolean hack.
 
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=188
 
 	* libtiff/tiff.h: Don't do special type handling in tiff.h unless
 	USING_VISUALAGE is defined.
-	
+
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=39
 
 2002-10-03  Frank Warmerdam  <warmerdam at pobox.com>
@@ -4603,30 +5028,30 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 	* libtiff/tif_dirread.c: Another fix for the fetching SBYTE arrays
 	by the TIFFFetchByteArray() function. Should finally resolve
-	
+
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=52
-	
+
 	* configure: Set -DPIXARLOG_SUPPORT option along with -DZIP_SUPPORT
 
 	* html/Makefile.in: New targets added: html and groffhtml for
 	producing HTML representations of the manual pages automatically.
 	html target uses man2html tool, groffhtml uses groff tool.
-	
+
 2002-09-29  Frank Warmerdam  <warmerdam at pobox.com>
 
 	* configure, libtiff/Makefile.in: Added SCO OpenServer 5.0.6 support
-	from John H. DuBois III.  
+	from John H. DuBois III.
 
 2002-09-15  Andrey Kiselev  <dron at ak4719.spb.edu>
 
 	* Makefile.in, /man/{raw2tiff.1, Makefile.in, libtiff.3}: Added
 	manual page for raw2tiff(1) tool.
-	
+
 2002-09-12  Andrey Kiselev  <dron at ak4719.spb.edu>
 
 	* /libtiff/{tiffio.h, tif_dir.h}: TIFFDataWidth() declaration moved to
 	the tiffio.h header file.
-	
+
 	* Makefile.in, /man/{TIFFDataWidth.3t, Makefile.in, libtiff.3}: Added
 	manual page for TIFFDataWidth() function
 
@@ -4636,8 +5061,8 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	as per http://bugzilla.remotesensing.org/show_bug.cgi?id=196.
 
 	* tools/tiff2ps.c: Don't emit BeginData/EndData DSC comments
-	since we are unable to properly include the amount to skip. 
-	
+	since we are unable to properly include the amount to skip.
+
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=80
 
 2002-09-02  Andrey Kiselev  <dron at ak4719.spb.edu>
@@ -4647,7 +5072,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=52
 
 2002-08-22  Andrey Kiselev  <dron at ak4719.spb.edu>
-	
+
 	* /libtiff/tif_dirinfo.c: Further additions to free custom fields
 	in _TIFFSetupFieldInfo() function.
 	See http://bugzilla.remotesensing.org/show_bug.cgi?id=169 for details.
@@ -4656,14 +5081,14 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	LZWDecode() and LZWDecodeCompat().
 	Fixes http://bugzilla.remotesensing.org/show_bug.cgi?id=190
 	and http://bugzilla.remotesensing.org/show_bug.cgi?id=100
-	
+
 	* /libtiff/tif_lzw.c:
 	Added check for valid code lengths in LZWDecode() and
 	LZWDecodeCompat(). Fixes
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=115
 
 2002-08-16  Andrey Kiselev  <dron at ak4719.spb.edu>
-	
+
 	* /libtiff/{Makefile.vc, libtiff.def}:
 	Missed declarations added.
 
@@ -4674,7 +5099,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=177
 
-	* tif_dir.h: changed FIELD_CODEC to 66 from 64 to avoid overlap 
+	* tif_dir.h: changed FIELD_CODEC to 66 from 64 to avoid overlap
 	with FIELD_CUSTOM as mentioned in bug 169.
 
 	* tif_close.c: added logic to free dynamically created anonymous
@@ -4683,31 +5108,31 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=169
 
 2002-08-10  Andrey Kiselev  <dron at ak4719.spb.edu>
-	
+
 	* /tools/{raw2tiff.c, Makefile.in, Makefile.lcc, Makefile.vc}:
 	New tool: raw2tiff --- raw images to TIFF converter. No manual page yet.
 
 2002-07-31  Frank Warmerdam  <warmerdam at pobox.com>
 
-	* libtiff/tif_jpeg.c: Fixed problem with setting of nrows in 
+	* libtiff/tif_jpeg.c: Fixed problem with setting of nrows in
 	JPEGDecode() as per bugzilla bug (issue 1):
 
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=129
 
 	* libtiff/{tif_jpeg.c,tif_strip.c,tif_print.c}: Hacked tif_jpeg.c to
 	fetch TIFFTAG_YCBCRSUBSAMPLING from the jpeg data stream if it isn't
-	present in the tiff tags. 
+	present in the tiff tags.
 
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=168
 
 	* libtiff/tif_read.c, libtiff/tif_write.c: TIFFReadScanline() and
 	TIFFWriteScanline() now set tif_row explicitly in case the codec has
-	fooled with the value. 
+	fooled with the value.
 
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=129
 
 2002-06-22  Andrey Kiselev  <dron at ak4719.spb.edu>
-	
+
 	* /tools/tiff2ps.c: Added workaround for some software that may crash
 	when last strip of image contains fewer number of scanlines than
 	specified by the `/Height' variable. See
@@ -4723,8 +5148,8 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 2002-06-11  Frank Warmerdam  <warmerdam at pobox.com>
 
-	* libtiff/contrib/win95: renamed to contrib/win_dib.  Added new 
-	Tiffile.cpp example of converting TIFF files into a DIB on Win32.  
+	* libtiff/contrib/win95: renamed to contrib/win_dib.  Added new
+	Tiffile.cpp example of converting TIFF files into a DIB on Win32.
 	This one is described in:
 
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=143
@@ -4740,21 +5165,21 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=131
 
 2002-04-26  Andrey Kiselev  <dron at ak4719.spb.edu>
-	
+
 	* libtiff/libtiff.def: Added missed declaration.
-	
+
 2002-04-22  Andrey Kiselev  <dron at ak4719.spb.edu>
-	
+
 	* tools/fax2tiff.c: Updated to reflect latest changes in libtiff.
 	Closes http://bugzilla.remotesensing.org/show_bug.cgi?id=125
 
 2002-04-20  Andrey Kiselev  <dron at ak4719.spb.edu>
-	
+
 	* libtiff/tif_open.c: Pointers to custom procedures
 	in TIFFClientOpen() are checked to be not NULL-pointers.
-	
+
 2002-04-18  Andrey Kiselev  <dron at ak4719.spb.edu>
-	
+
 	* libtiff/libtiff.def: Added missed declarations.
 
 	* libtiff/tif_pixarlog.c: Updated for using tif_tagmethods structure.
@@ -4764,14 +5189,14 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	* libtiff/tif_lzw.c: Additional checks for data integrity introduced.
 	Should finally close
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=100
-	
+
 2002-04-10  Andrey Kiselev  <dron at ak4719.spb.edu>
 
 	* tools/tiff2ps: Division by zero fixed.
 	Closes http://bugzilla.remotesensing.org/show_bug.cgi?id=88
 
 2002-04-09  Andrey Kiselev  <dron at ak4719.spb.edu>
-	
+
 	* libtiff/: tif_dirwrite.c, tif_write.c, tiffio.h:
 	TIFFCheckpointDirectory() routine added.
 	Closes http://bugzilla.remotesensing.org/show_bug.cgi?id=124
@@ -4803,7 +5228,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	replaced by warnings. Now libtiff should read corrupted LZW-compressed
 	files by skipping bad strips.
 	Closes http://bugzilla.remotesensing.org/show_bug.cgi?id=100
-	
+
 2002-04-03  Frank Warmerdam  <warmerdam at pobox.com>
 
 	* libtiff/tif_dirwrite.c: Removed some dead code.
@@ -4825,18 +5250,18 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=111
 
-	* tif_print.c: Fixed so that ASCII FIELD_CUSTOM values with 
+	* tif_print.c: Fixed so that ASCII FIELD_CUSTOM values with
 	passcount set FALSE can be printed (such as TIFFTAG_SOFTWARE).
 
-	* libtiff/tif_dir.c,tif_dirinfo.c,tif_dir.h,tif_ojpeg.c: modified so 
+	* libtiff/tif_dir.c,tif_dirinfo.c,tif_dir.h,tif_ojpeg.c: modified so
 	that TIFFTAG_SOFTWARE uses FIELD_CUSTOM as an example.
 
 2002-03-26  Dwight Kelly  <dbmalloc at remotesensing.org>
 
 	* libtiff/: tiff.h, tif_dir.c, tif_dir.h, tif_dirinfo.c, tif_dirread.c,
 	tif_dirwrite.c: Added get/put code for new tag XMLPACKET as defined
-	in Adobe XMP Technote. Added missing INKSET tag value from TIFF 6.0 spec 
-	INKSET_MULTIINK (=2). Added missing tags from Adobe TIFF technotes: 
+	in Adobe XMP Technote. Added missing INKSET tag value from TIFF 6.0 spec
+	INKSET_MULTIINK (=2). Added missing tags from Adobe TIFF technotes:
 	CLIPPATH, XCLIPPATHUNITS, YCLIPPATHUNITS, OPIIMAGEID, OPIPROXY and
 	INDEXED. Added PHOTOMETRIC tag value from TIFF technote 4 ICCLAB (=9).
 
@@ -4895,7 +5320,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=94
 
-	* man/Makefile.in: Patch DESTDIR handling 
+	* man/Makefile.in: Patch DESTDIR handling
 
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=95
 
@@ -4933,9 +5358,9 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 2002-01-04  Frank Warmerdam  <warmerdam at pobox.com>
 
-	* libtiff/tif_jpeg.c: fixed computation of segment_width for 
-	tiles files to avoid error about it not matching the 
-	cinfo.d.image_width values ("JPEGPreDecode: Improper JPEG strip/tile 
+	* libtiff/tif_jpeg.c: fixed computation of segment_width for
+	tiles files to avoid error about it not matching the
+	cinfo.d.image_width values ("JPEGPreDecode: Improper JPEG strip/tile
 	size.") for ITIFF files.  Apparently the problem was incorporated since
 	3.5.5, presumably during the OJPEG/JPEG work recently.
 
@@ -4945,7 +5370,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=94
 
-	* libtiff/tif_getimage.c: If DEFAULT_EXTRASAMPLE_AS_ALPHA is 1 
+	* libtiff/tif_getimage.c: If DEFAULT_EXTRASAMPLE_AS_ALPHA is 1
 	(defined in tiffconf.h - 1 by default) then the RGBA interface
 	will assume that a fourth extra sample is ASSOCALPHA if the
 	EXTRASAMPLE value isn't set for it.  This changes the behaviour of
@@ -4957,9 +5382,9 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 2001-12-12  Frank Warmerdam  <warmerdam at pobox.com>
 
-	* libtiff/tif_jpeg.c: allow jpeg data stream sampling values to 
-	override those from tiff directory.  This makes this work with 
-	ImageGear generated files. 
+	* libtiff/tif_jpeg.c: allow jpeg data stream sampling values to
+	override those from tiff directory.  This makes this work with
+	ImageGear generated files.
 
 2001-12-07  Frank Warmerdam  <warmerdam at pobox.com>
 
@@ -4972,7 +5397,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	* Reissue 3.5.7 release.
 
 	* libtiff/mkversion.c: Fix output of TIFF_VERSION to be
-	YYYYMMDD so that it is increasing over time. 
+	YYYYMMDD so that it is increasing over time.
 
 	* Makefile.in: Ensure that tiffvers.h is regenerated in the
 	make release target.
@@ -4997,8 +5422,8 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 2001-10-10  Frank Warmerdam  <warmerdam at pobox.com>
 
-	* libtiff/tiff.h: I have created COMPRESSION_CCITT_T4, 
-	COMPRESSION_CCITT_T6, TIFFTAG_T4OPTIONS and TIFFTAG_T6OPTIONS aliases 
+	* libtiff/tiff.h: I have created COMPRESSION_CCITT_T4,
+	COMPRESSION_CCITT_T6, TIFFTAG_T4OPTIONS and TIFFTAG_T6OPTIONS aliases
 	in keeping with TIFF 6.0 standard in tiff.h
 
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=83
@@ -5018,10 +5443,10 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	error about LZW not being available.
 
 	* libtiff/tif_dir.c: propagate failure to initialize compression
-	back from TIFFSetField() as an error status, so applications can 
+	back from TIFFSetField() as an error status, so applications can
 	detect failure.
 
-	* libtiff/tif_dir.c: removed the auto replacement of 
+	* libtiff/tif_dir.c: removed the auto replacement of
 	COMPRESSION_LZW with COMPRESSION_NONE in _TIFFVSetField().
 
 	* Removed Makefile, tools/Makefile, port/install.sh, man/Makefile
@@ -5029,7 +5454,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 2001-09-22  Frank Warmerdam  <warmerdam at pobox.com>
 
-	* libtiff/tif_ojpeg.c: new update from Scott. 
+	* libtiff/tif_ojpeg.c: new update from Scott.
 
 2001-09-09  Frank Warmerdam  <warmerdam at pobox.com>
 
@@ -5048,7 +5473,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=47
 
-	* tools/tiff2ps.c: added OJPEG YCbCr to RGB support. 
+	* tools/tiff2ps.c: added OJPEG YCbCr to RGB support.
 
 	* libtiff/tif_ojpeg.c: Applied substantial patch from Scott.
 
@@ -5057,14 +5482,14 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	* libtiff/tif_packbits.c: fixed memory overrun error.
 
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=77
-	
+
 2001-08-31  Frank Warmerdam  <warmerdam at pobox.com>
 
 	* libtiff/tif_getimage.c: relax handling of contig case where
 	there are extra samples that are supposed to be ignored.  This
-	should now work for 8bit greyscale or palletted images.  
+	should now work for 8bit greyscale or palletted images.
 
-	http://bugzilla.remotesensing.org/show_bug.cgi?id=75	
+	http://bugzilla.remotesensing.org/show_bug.cgi?id=75
 
 2001-08-28  Frank Warmerdam  <warmerdam at pobox.com>
 
@@ -5077,15 +5502,15 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 	* libtiff/tif_getimage.c: Use memmove() instead of TIFFmemcpy()
 	in TIFFReadRGBATile() to avoid issues in cases of overlapping
-	buffers.  See Bug 69 in Bugzilla. 
+	buffers.  See Bug 69 in Bugzilla.
 
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=69
-	
+
 	* tools/tiff2rgba.c: fixed getopt() call so that -b works again.
 
 2001-08-09  Frank Warmerdam  <warmerdam at pobox.com>
 
-	* libtiff/tiff.h, libtiff/tif_fax3.c: added check for __LP64__ 
+	* libtiff/tiff.h, libtiff/tif_fax3.c: added check for __LP64__
 	when checking for 64 bit architectures as per bugzilla bug 67.
 
 2001-07-27  Frank Warmerdam  <warmerdam at pobox.com>
@@ -5095,7 +5520,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 2001-07-20  Frank Warmerdam  <warmerdam at pobox.com>
 
-	* libtiff/tif_jpeg.c: Define HAVE_BOOLEAN on windows if RPCNDR.H 
+	* libtiff/tif_jpeg.c: Define HAVE_BOOLEAN on windows if RPCNDR.H
 	has been included.
 
 2001-07-19  Frank Warmerdam  <warmerdam at pobox.com>
@@ -5107,11 +5532,11 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 	* libtiff/tif_ojpeg.c: updates from Scott.  Handles colors
 	much better.  Now depends on having patched libjpeg as per
-	patch in contrib/ojpeg/*. 
+	patch in contrib/ojpeg/*.
 
 2001-07-17  Frank Warmerdam  <warmerdam at pobox.com>
 
-	* */Makefile.in: added DESTDIR support. 
+	* */Makefile.in: added DESTDIR support.
 
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=60
 
@@ -5119,20 +5544,20 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 	* configure, libtiff/Makefile.in: applied OpenBSD patches
 	as per:
-	
+
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=61
 
 2001-06-28  Frank Warmerdam  <warmerdam at pobox.com>
 
 	* libtiff/tif_getimage.c: Fixed so that failure is properly
-	reported by gtTileContig, gtStripContig, gtTileSeparate and 
+	reported by gtTileContig, gtStripContig, gtTileSeparate and
 	gtStripSeparate.
 
 	See http://bugzilla.remotesensing.org/show_bug.cgi?id=51
 
-	* tiffcmp.c: Fixed multi samples per pixel support for ContigCompare.  
+	* tiffcmp.c: Fixed multi samples per pixel support for ContigCompare.
 	Updated bug section of tiffcmp.1 to note tiled file issues.
-	
+
 	See http://bugzilla.remotesensing.org/show_bug.cgi?id=53
 
 2001-06-22  Frank Warmerdam  <warmerdam at pobox.com>
@@ -5173,10 +5598,10 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 2001-05-08  Frank Warmerdam  <warmerdam at pobox.com>
 
-	* libtiff/tif_dirinfo.c: moved pixar and copyright flags to 
+	* libtiff/tif_dirinfo.c: moved pixar and copyright flags to
 	ensure everything is in order.
 
-	* libtiff/libtiff.def: added TIFFCreateDirectory and 
+	* libtiff/libtiff.def: added TIFFCreateDirectory and
 	TIFFDefaultStripSize as per:
 
 	  http://bugzilla.remotesensing.org/show_bug.cgi?id=46
@@ -5185,10 +5610,10 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 	* libtiff/tif_dirinfo.c: Modified the TIFF_BYTE definition for
 	TIFFTAG_PHOTOSHOP to use a writecount of TIFF_VARIABLE2 (-3) to
-	force use of uint32 counts instead of short counts. 
+	force use of uint32 counts instead of short counts.
 
 	* libtiff/tif_dirwrite.c: Added support for TIFF_VARIABLE2 in the
-	case of writing TIFF_BYTE/TIFF_SBYTE fields.  
+	case of writing TIFF_BYTE/TIFF_SBYTE fields.
 
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=43
 
@@ -5224,20 +5649,20 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	with the inttypes.h include file on AIX.
 
 	See http://bugzilla.remotesensing.org/show_bug.cgi?id=39
-	
+
 	* VERSION: update to 3.5.7 beta in preparation for release.
 
 	* configure/config.site: modified to check if -lm is needed for
 	MACHDEPLIBS if not supplied by config.site.  Needed for Darwin.
 
-	* config.guess: updated wholesale to an FSF version apparently 
-	from 1998 (as opposed to 1994).  This is mainly inspired by 
+	* config.guess: updated wholesale to an FSF version apparently
+	from 1998 (as opposed to 1994).  This is mainly inspired by
 	providing for MacOS X support.
 
 2001-03-29  Frank Warmerdam  <warmerdam at pobox.com>
 
 	* configure, Makefile.in, etc: added support for OPTIMIZER being
-	set from config.site. 
+	set from config.site.
 
 2001-03-28  Frank Warmerdam  <warmerdam at pobox.com>
 
@@ -5256,7 +5681,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	(in particular short ones) print properly.
 
 	See http://bugzilla.remotesensing.org/show_bug.cgi?id=35
-	
+
 	* tiff2ps.c/tiff2ps.1: Substantial changes to tiff2ps by
 	Bruce A. Mallett.  See check message for detailed information
 	on all the changes, including a faster encoder, fixes for level
@@ -5264,7 +5689,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 2001-03-27  Frank Warmerdam  <warmerdam at pobox.com>
 
-	* libtiff/tiffio.h: Changed "#if LOGLUV_PUBLIC" to 
+	* libtiff/tiffio.h: Changed "#if LOGLUV_PUBLIC" to
 	"#ifdef LOGLUV_PUBLIC" so it will work with VisualAge on AIX.
 
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=39
@@ -5276,7 +5701,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 2001-03-13  Frank Warmerdam  <warmerdam at pobox.com>
 
-	* tif_getimage.c: Added support for 16bit minisblack/miniswhite 
+	* tif_getimage.c: Added support for 16bit minisblack/miniswhite
 	images in RGBA interface.
 
 2001-03-02  Frank Warmerdam  <warmerdam at pobox.com>
@@ -5287,29 +5712,29 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 	* Brent Roman contributed updated tiffcp utility (and tiffcp.1)
 	with support for extracting subimages with the ,n syntax, and also
-	adding the -b bias removal flag. 
+	adding the -b bias removal flag.
 
 2001-02-16  Frank Warmerdam  <warmerdam at pobox.com>
 
 	* libtiff/libtiff.def: Brent Roman submitted new version adding
-	serveral missing entry points. 
+	serveral missing entry points.
 
 	* libtiff/tif_dirinfo.c: don't declare tiffFieldInfo static on VMS.
-	Some sort of weird VMS thing.  
+	Some sort of weird VMS thing.
 
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=31
 
-	* tif_luv.c/tiff.h/tiffio.h: 
-	New version of TIFF LogLuv (SGILOG) modules contributed by Greg Ward 
+	* tif_luv.c/tiff.h/tiffio.h:
+	New version of TIFF LogLuv (SGILOG) modules contributed by Greg Ward
 	(greg at shutterfly.com).  He writes:
 
 	1) I improved the gamut-mapping function in tif_luv.c for imaginary
-	colors, because some images were being super-saturated on the input 
+	colors, because some images were being super-saturated on the input
 	side and this resulted in some strange color shifts in the output.
 
 	2) I added a psuedotag in tiff.h to control random dithering during
-	LogLuv encoding.  This is turned off by default for 32-bit LogLuv and 
-	on for 24-bit LogLuv output.  Dithering improves the average color 
+	LogLuv encoding.  This is turned off by default for 32-bit LogLuv and
+	on for 24-bit LogLuv output.  Dithering improves the average color
 	accuracy over the image.
 
 	3) I added a #define for LOG_LUV_PUBLIC, which is enabled by default in
@@ -5322,20 +5747,20 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 2001-01-23  Frank Warmerdam  <warmerdam at pobox.com>
 
 	* tif_fax3.c: keep rw_mode flag internal to fax3 state to remember
-	whether we are encoding or decoding.  This is to ensure graceful 
+	whether we are encoding or decoding.  This is to ensure graceful
 	recovery if TIFFClientOpen() discovers an attempt to open a compressed
-	file for "r+" access, and subsequently close it, as it resets the 
+	file for "r+" access, and subsequently close it, as it resets the
 	tif_mode flag to O_RDONLY in this case to avoid writes, confusing the
 	compressor's concept of whether it is in encode or decode mode.
 
-2001-01-08  Mike Welles <mike at bangstate.com> 
+2001-01-08  Mike Welles <mike at bangstate.com>
 
 	* Makefile.in:  Now cleaning up after itself after creating the .tar.gz and .zip
-	
+
 2001-01-07  Frank Warmerdam  <warmerdam at pobox.com>
 
 	* html/libtiff.html: Fixed arguments in example for TIFFRGBAImageGet()
-	as per bug report by Patrick Connor. 
+	as per bug report by Patrick Connor.
 
 2000-12-28  Frank Warmerdam  <warmerdam at pobox.com>
 
@@ -5343,12 +5768,12 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 	* Fixed libtiff/makefile.vc to make tiffvers.h not version.h.
 
-2000-12-22  Mike Welles <mike at bangstate.com> 
+2000-12-22  Mike Welles <mike at bangstate.com>
         * added link to CVS mirror from index.html
-	
-	* updated html/internals.html to note that LZW compression is 
-	  not supported by default. 
-	
+
+	* updated html/internals.html to note that LZW compression is
+	  not supported by default.
+
 2000-12-22  Frank Warmerdam  <warmerdam at pobox.com>
 
 	* updated html/libtiff.html to not point at Niles' old JPL web site
@@ -5360,19 +5785,19 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	Leonard Rosenthol <leonardr at lazerware.com>.  May interfere
 	with correct building on older systems.  If so, please let me know.
 
-2000-12-19 Mike Welles <mike at bangsate.com>   
+2000-12-19 Mike Welles <mike at bangsate.com>
 
-	* Took out LZW Encoding from tif_lzw.c 
+	* Took out LZW Encoding from tif_lzw.c
 
 	* Created HOWTO-RELEASE
 
 	* Created html/v3.5.6.html
 
 	* updated index.html
-	
+
 2000-12-01  Frank Warmerdam  <warmerdam at pobox.com>
 
-	* Added patches for EOFB support in tif_fax3.c and tif_fax3.h. 
+	* Added patches for EOFB support in tif_fax3.c and tif_fax3.h.
 	Patches supplied by Frank Cringle <fdc at cliwe.ping.de>
 	Example file at: ftp://ftp.remotesensing.org/pub/libtiff/eofb_396.tif
 
@@ -5386,30 +5811,30 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	targets so libtiff.so will be built with an explicit dependency
 	on libm.so.
 
-	* libtiff/Makefile.in: Use softlinks to link libtiff.so.3 to 
-	libtiff.so.3.5.5.  
+	* libtiff/Makefile.in: Use softlinks to link libtiff.so.3 to
+	libtiff.so.3.5.5.
 
-	* libtiff/Makefile.in & configure: Remove all references to the ALPHA 
-	file, or ALPHA version logic.  Added stuff about DIST_POINT in 
+	* libtiff/Makefile.in & configure: Remove all references to the ALPHA
+	file, or ALPHA version logic.  Added stuff about DIST_POINT in
 	place of DIST_TYPE and the alpha release number stuff.
 
 2000-11-22  Frank Warmerdam  <warmerdam at pobox.com>
 
 	* I have applied a patch from Steffen Moeller <moeller at ebi.ac.uk> to
-	the configure script so that it now accepts the --prefix, and 
-	--exec-prefix directives. 
+	the configure script so that it now accepts the --prefix, and
+	--exec-prefix directives.
 
 2000-11-13  Frank Warmerdam  <warmerda at cs46980-c>
 
-	* I have made a variety of modifications in an effort to ensure the 
+	* I have made a variety of modifications in an effort to ensure the
 	TIFFLIB_VERSION macro is automatically generated from the RELEASE-DATE
-	file which seems to be updated regularly.  
+	file which seems to be updated regularly.
 
-	 o mkversion.c now reads RELEASE-DATE and emits TIFFLIB_VERSION in 
-	   version include file. 
-	 o renamed version.h to tiffvers.h because we now have to install it 
-	   with the public libtiff include files.  
-	 o include tiffvers.h in tiffio.h. 
+	 o mkversion.c now reads RELEASE-DATE and emits TIFFLIB_VERSION in
+	   version include file.
+	 o renamed version.h to tiffvers.h because we now have to install it
+	   with the public libtiff include files.
+	 o include tiffvers.h in tiffio.h.
 	 o updated tif_version.c to use tiffvers.h.
 	 o Updated Makefile.in accordingly.
 
@@ -5423,13 +5848,13 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	See http://bugzilla.remotesensing.org/show_bug.cgi?id=20
 	Some patches from Rick LaMont of Dot C Software.
 
-	* Modified tif_packbits.c encoder to avoid compressing more 
+	* Modified tif_packbits.c encoder to avoid compressing more
 	data than provided if rowsize doesn't factor into provided data
 	(such as occurs for YCbCr).
 
 2000-10-19  Frank Warmerdam  <warmerda at cs46980-c>
 
-	* tools/rgb2ycbcr.c: fixed output strip size to account for vertical 
+	* tools/rgb2ycbcr.c: fixed output strip size to account for vertical
 	roundup if rows_per_strip not a multiple of vertical sample size.
 
 2000-10-16  Frank Warmerdam  <warmerda at cs46980-c>
@@ -5445,8 +5870,8 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 2000-10-12  Frank Warmerdam  <warmerda at cs46980-c>
 
 	* Modified tiff2bw to ensure portions add to 100%, and that
-	white is properly recovered. 
-	
+	white is properly recovered.
+
 	See bug http://bugzilla.remotesensing.org/show_bug.cgi?id=15
 	Patch c/o Stanislav Brabec <utx at penguin.cz>
 
@@ -5460,26 +5885,26 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 2000-09-27  Frank Warmerdam  <warmerda at cs46980-c>
 
-	* Added GNULDdso target an`d switched linux and freebsd to use it. 
+	* Added GNULDdso target an`d switched linux and freebsd to use it.
 
 2000-09-26  Frank Warmerdam  <warmerda at cs46980-c>
 
 	* Applied patch for 0x0000 sequences in tif_fax3.h's definition
-	of EXPAND1D() as per bug 11 (from Roman). 
+	of EXPAND1D() as per bug 11 (from Roman).
 
 2000-09-25  Frank Warmerdam  <warmerda at cs46980-c>
 	* Fixed tiffcomp.h to avoid win32 stuff if unix #defined, to improve
 	cygwin compatibility.
 
 	* Applied patch from Roman Shpount to tif_fax3.c.  This seems to
-	be a proper fix to the buffer sizing problem.  See 
+	be a proper fix to the buffer sizing problem.  See
 	http://bugzilla.remotesensing.org/show_bug.cgi?id=11
 
 	* Fixed tif_getimage.c to fix overrun bug with YCbCr images without
 	downsampling.  http://bugzilla.remotesensing.org/show_bug.cgi?id=10
 	Thanks to Nick Lamb <njl98r at ecs.soton.ac.uk> for reporting the
 	bug and proving the patch.
-	
+
 2000-09-18  Frank Warmerdam  <warmerda at cs46980-c>
 
 	* Fixed tif_jpeg.c so avoid destroying the decompressor before
@@ -5509,15 +5934,15 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 	* Tentatively added support for SAMPLEFORMAT_COMPLEXIEEEFP, and
 	SAMPLEFORMAT_COMPLEXINT.
 
-2000-07-13  Mike Welles <mike at onshore.com> 
+2000-07-13  Mike Welles <mike at onshore.com>
+
+	* index.html, bugs.html: added bugzilla info.
 
-	* index.html, bugs.html: added bugzilla info. 
-	
 2000-07-12  Frank Warmerdam  <warmerda at rommel.atlsci.com>
 
 	* tif_read.c: fix subtle bug with determining the number of
 	rows for strips that are the last strip in a separation but
-	not the last strip of all in TIFFReadEncodedStrip().  
+	not the last strip of all in TIFFReadEncodedStrip().
 
 	* Applied 16/32 bit fix to tif_fax3.c.  Fix supplied by
 	Peter Skarpetis <peters at serendipity-software.com.au>
@@ -5539,7 +5964,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic
 
 	* libtiff/tif_dirread.c: Don't use estimate strip byte count for
 	one tile/strip images with an offset, and byte count of zero. These
-	could be "unpopulated" images. 
+	could be "unpopulated" images.
 
 2000-04-18  Frank Warmerdam  <warmerda at rommel.atlsci.com>
 
@@ -5554,17 +5979,17 @@ Tue Apr 18 16:18:08 2000  Frank Warmerdam  <warmerda at esabot.atlsci.com>
 2000-04-12  Mike Welles	     <mike at onshore.com>
 	* configure:  Fixed stupid mistake in libc6 test on Linux
 
-2000-04-04  Mike Welles	     <mike at onshore.com> 
+2000-04-04  Mike Welles	     <mike at onshore.com>
 	* tif_win32.c:  Applied patch to fix overreads and ovverwrites
-	  caught by BoundsChecker.  From Arvan Pritchard 
-	  <arvan.pritchard at infomatix.co.uk>  (untested). 
-	
-	* tif_getimage.c:  Applied patch to silence VC6 warnings.  From 
+	  caught by BoundsChecker.  From Arvan Pritchard
+	  <arvan.pritchard at infomatix.co.uk>  (untested).
+
+	* tif_getimage.c:  Applied patch to silence VC6 warnings.  From
 	  Arvan Pritchard <arvan.pritchard at informatix.co.uk>
-	
-	* tif_lzw.c:  Applied patch to silence VC6 warnings.  From 
+
+	* tif_lzw.c:  Applied patch to silence VC6 warnings.  From
 	  Arvan Pritchard <arvan.pritchard at informatix.co.uk>
-	
+
 2000-03-28  Frank Warmerdam  <warmerda at cs46980-c>
 
 	* Added contrib/stream (stream io) code submitted by Avi Bleiweiss.
@@ -5574,34 +5999,34 @@ Tue Apr 18 16:18:08 2000  Frank Warmerdam  <warmerda at esabot.atlsci.com>
 	* fax2ps: Fixed mixup of width and height in bounding box statement
 	as per submission by Nalin Dahyabhai <nalin at redhat.com>.
 
-2000-03-27  Mike Welles	     <mike at onshore.com> 
+2000-03-27  Mike Welles	     <mike at onshore.com>
+
+	* fax2ps:  Modified printruns to take uint32 instead of uint16.
+	Patch courtesy of Bernt Herd <herd at herdsoft.com>
 
-	* fax2ps:  Modified printruns to take uint32 instead of uint16.  
-	Patch courtesy of Bernt Herd <herd at herdsoft.com> 
-	
-2000-03-20  Mike Welles	     <mike at onshore.com> 
+2000-03-20  Mike Welles	     <mike at onshore.com>
 
-	* configure: added test for libc6 for linux targets.  Bug reported by 
+	* configure: added test for libc6 for linux targets.  Bug reported by
         Stanislav Brabec <utx at k332.feld.cvut.cz>
 
-	* Added 3.5 docs to html/Makefile.in.  
+	* Added 3.5 docs to html/Makefile.in.
 	Thanks to  Stanislav Brabec <utx at k332.feld.cvut.cz>
 
-	* configure: fixed bugs in sed scripts 
-	(applied sed script s:/@:s;@:;s:/s;;:;: to configure). 
+	* configure: fixed bugs in sed scripts
+	(applied sed script s:/@:s;@:;s:/s;;:;: to configure).
 	fix submitted to Stanislav Brabec <utx at k332.feld.cvut.cz>
 
-	* tools/iptcutil was not in files list, and wasn't being 
+	* tools/iptcutil was not in files list, and wasn't being
 	added to tar archive.  Updated Makefile.in.
 
 2000-03-17  Frank Warmerdam  <warmerda at cs46980-c>
 
 	* tif_fax3.c: Fixed serious bug introduced during the uint16->uint32
-	conversion for the run arrays.  
+	conversion for the run arrays.
 
 2000-03-03  Frank Warmerdam  <warmerda at cs46980-c.mtnk1.on.wave.home.com>
 
-	* Set td_sampleformat default to SAMPLEFORMAT_UINT instead of 
+	* Set td_sampleformat default to SAMPLEFORMAT_UINT instead of
 	SAMPLEFORMAT_VOID in TIFFDefaultDirectory() in tif_dir.c.
 
 2000-03-02  Frank Warmerdam  <warmerda at cs46980-c.mtnk1.on.wave.home.com>
@@ -5622,20 +6047,20 @@ Tue Feb 15 22:01:05 2000  Frank Warmerdam  <warmerda at gdal.velocet.ca>
 	  set to 1, and added default (off) setting in tiffconf.h.  This
 	  should eventually be set by the configure script somehow.
 
-	  The original work on all these 2-4GB changes was done by 
+	  The original work on all these 2-4GB changes was done by
 	  Peter Smith (psmith at creo.com).
 
 	* Modified tif_win32.c to support 2-4GB seeks.
 
 	* tentatively changed toff_t to be unsigned instead of signed to
-	  facilitate support for 2-4GB files. 
+	  facilitate support for 2-4GB files.
 
 	* Updated a variety of files to use toff_t.  Fixed some mixups
 	  between toff_t and tsize_t.
 
 Fri Jan 28 10:13:49 2000  Frank Warmerdam  <warmerda at gdal.velocet.ca>
 
-	* Largely reimplemented contrib/addtiffo to avoid temp files, 
+	* Largely reimplemented contrib/addtiffo to avoid temp files,
 	updating the TIFF file in place.  Fixed a few other bugs to.
 
 	* Set tif_rawdatasize to zero when freeing raw data buffer in
@@ -5644,7 +6069,7 @@ Fri Jan 28 10:13:49 2000  Frank Warmerdam  <warmerda at gdal.velocet.ca>
 	* Enabled "REWRITE_HACK" in tif_write.c by default.
 
 	* Fix bug in tif_write.c when switching between reading one directory
-	and writing to another. 
+	and writing to another.
 
 	* Made TIFFWriteCheck() public, and added TIFFCreateDirectory()
 
@@ -5656,41 +6081,41 @@ Tue Jan  4 13:39:00 2000  Frank Warmerdam  <warmerda at gdal.velocet.ca>
 
 	* Added libtiff/libtiff.def to TIFFILES distribution list.
 
-Mon Dec 27 12:13:39 EST 1999  Mike Welles <mike at onshore.com> 
+Mon Dec 27 12:13:39 EST 1999  Mike Welles <mike at onshore.com>
 
-	* Created lzw compression kit, as a new module (libtiff-lzw-compression-kit). 
+	* Created lzw compression kit, as a new module (libtiff-lzw-compression-kit).
 
 	* Altered descriptions in tools to reflect "by default" lzw not supported
 
-	* Updated index.html to note lzw compression kit. 
-	
+	* Updated index.html to note lzw compression kit.
+
 Tue Dec 21 14:01:51 1999  Frank Warmerdam  <warmerda at gdal.velocet.ca>
 
-	* Added fax3sm_winnt.c to distribution list in Makefile.in. 
+	* Added fax3sm_winnt.c to distribution list in Makefile.in.
 
 Tue Dec 21 11:04:45 EST 1999  Mike Welles <mike at onshore.com> *** 3.5.4 release ***
-	
-	* Aadded Pixar tag support.  Contributed by Phil Beffery <phil at pixar.com> 
 
-	* Made one more change to tif_dir.c for removal of LZW compression. Also added notice 
-	  when LZW compression invoked. 
+	* Aadded Pixar tag support.  Contributed by Phil Beffery <phil at pixar.com>
+
+	* Made one more change to tif_dir.c for removal of LZW compression. Also added notice
+	  when LZW compression invoked.
 
 	* Changed default compression in tools to TIFF_PACKBITS, and changed usage descriptions
 	  in tools to reflect removal of LZW compression
-	  
+
 Mon Dec 20 18:39:02 EST 1999  Mike Welles  <mike at onshore.com>
 
-        * Fixed bug that caused LZW (non) compression to segfault. Added 
-	  warning about LZW compression removed being removed, and why. 
+        * Fixed bug that caused LZW (non) compression to segfault. Added
+	  warning about LZW compression removed being removed, and why.
+
+	* Added nostrip to install in tools/Makefile.in so that debugging
+	  symbols are kept.
 
-	* Added nostrip to install in tools/Makefile.in so that debugging 
-	  symbols are kept. 
-	
 Tue Dec  7 12:04:47 EST 1999  Mike Welles  <mike at onshore.com>
 
-	* Added patch from Ivo Penzar <ivo.penzar at infolink-software.com>, 
-	  supporting Adobe ZIP deflate.  Untested. 
-	
+	* Added patch from Ivo Penzar <ivo.penzar at infolink-software.com>,
+	  supporting Adobe ZIP deflate.  Untested.
+
 Sat Dec  4 15:47:11 1999  Frank Warmerdam  <warmerda at gdal.velocet.ca>
 
 	* Made Packbits the default compression in tools/tiff2rgba.c instead
@@ -5700,12 +6125,12 @@ Tue Nov 30 14:41:43 1999  Frank Warmerdam  <warmerda at gdal.velocet.ca>    *** 3.5
 
 	* Added tif_luv to contrib/djgpp/Makefile.lib.
 
-Tue Nov 30 14:15:32 EST 1999   Mike Welles <mike at onshore.com> 
+Tue Nov 30 14:15:32 EST 1999   Mike Welles <mike at onshore.com>
+
+        * Added zip creation to relase makefile target
 
-        * Added zip creation to relase makefile target 
+	* Added html for TIFFWriteTile.3t man page.
 
-	* Added html for TIFFWriteTile.3t man page. 
-	
 Tue Nov 30 09:20:16 1999  Frank Warmerdam  <warmerda at gdal.velocet.ca>
 
 	* Added some changes to tif_write.c to support rewriting existing
@@ -5718,26 +6143,26 @@ Mon Nov 29 11:43:42 1999  Frank Warmerdam  <warmerda at gdal.velocet.ca>
 
 Sun Nov 28 20:36:18 1999  Frank Warmerdam  <warmerda at gdal.velocet.ca>
 
-	* Added notes on use of makefile.vc in build.html, and fixed 
+	* Added notes on use of makefile.vc in build.html, and fixed
 	email subscription address.
 
-199-11-28  Mike Welles <mike at onshore.com> 
+199-11-28  Mike Welles <mike at onshore.com>
 
-	*  Fixed apocalypse-inducing y2k bug in contrib/ras/ras2tiff.c 
+	*  Fixed apocalypse-inducing y2k bug in contrib/ras/ras2tiff.c
 
 	*  Did some casts cleaning up to reduce compiler warnings in tif_fax3.c,
-	   from Bruce Carmeron <cameron at petris.com> -- modifications of 
-	   changes made by Frank (sun cc still complained on cast). 
+	   from Bruce Carmeron <cameron at petris.com> -- modifications of
+	   changes made by Frank (sun cc still complained on cast).
 
 	*  Added tiffconf.h to install target per request from Bill
 	   Radcliffe <billr at corbis.com>: "We need a way for ImageMagick to
  	   know features have been compiled into the TIFF library in order to
-	   handle things properly".  
-	
+	   handle things properly".
+
 Sat Nov 27 16:49:21 1999  Frank Warmerdam  <warmerda at gdal.velocet.ca>
 
 	* fixed various VC++ warnings as suggested by Gilles Vollant
-	<info at winimage.com>.  
+	<info at winimage.com>.
 
 Wed Nov 24 12:08:16 1999  Frank Warmerdam  <warmerda at gdal.velocet.ca>
 
@@ -5746,59 +6171,59 @@ Wed Nov 24 12:08:16 1999  Frank Warmerdam  <warmerda at gdal.velocet.ca>
 
 1999-11-22  Mike Welles <mike at onshore.com>
 	*  HTML-ized the man pages, added to html/man
-	
-	*  Removed LZW Compression to comply with Unisys patent extortion. 
-	
-1999-09-29  Mike Welles		<mike at onshore.com> 
-	*  Corrected one remaining 16 -> 32 bit value in tif_fax3.c, 
-	   From Ivo Penzar <ivo.penzar at infolink-software.com. 
+
+	*  Removed LZW Compression to comply with Unisys patent extortion.
+
+1999-09-29  Mike Welles		<mike at onshore.com>
+	*  Corrected one remaining 16 -> 32 bit value in tif_fax3.c,
+	   From Ivo Penzar <ivo.penzar at infolink-software.com.
 
 	*  Added patch from Ivo Penzar to have TiffAdvanceDirectory handle
 	   memory mapped files. <ivo.penzar at infolink-software.com>
-	
+
 1999-09-26  Mike Welles 	<mike at onshore.com>  *** 3.5.2 release ***
-	* Corrected alpha versioning.  
+	* Corrected alpha versioning.
 
-	* Removed distinction between  alpha and release targets in Makefile.in. 
+	* Removed distinction between  alpha and release targets in Makefile.in.
 
-	* added release.stamp target, which tags cvs tree, and updates 
+	* added release.stamp target, which tags cvs tree, and updates
 	  "RELEASE-DATE"
 
-	* added releasediff target, which diffs tree with source as of 
+	* added releasediff target, which diffs tree with source as of
 	  date in "RELEASE-DATE"
-	  
-	* Ticked up version to 3.5.2 (alpha 01 -- but I think we'll moving 
-	  away from alpha/non-alpha distinctions). 
 
-	* updated html to reflect release 
-	
+	* Ticked up version to 3.5.2 (alpha 01 -- but I think we'll moving
+	  away from alpha/non-alpha distinctions).
+
+	* updated html to reflect release
+
 1999-09-23    <warmerda at CS46980-B>
 
 	* Set O_BINARY for tif_unix.c open() ... used on cygwin for instance.
 
 	* Added CYGWIN case in configure.
 
-Fri Sep 17 00:13:51 CEST 1999  Mike Welles <mike at onshore.com> 
+Fri Sep 17 00:13:51 CEST 1999  Mike Welles <mike at onshore.com>
+
+	* Applied Francois Dagand's patch to handle fax decompression bug.
+	  (sizes >= 65536 were failing)
 
-	* Applied Francois Dagand's patch to handle fax decompression bug. 
-	  (sizes >= 65536 were failing) 
-	
 Tue Sep 14 21:31:43 1999  Frank Warmerdam  <warmerda at gdal.velocet.ca>
 
-	* Applied "a" mode fix to tif_win32.c/TIFFOpen() as suggested 
+	* Applied "a" mode fix to tif_win32.c/TIFFOpen() as suggested
 	  by Christopher Lawton <clawton at mathworks.com>
 
 Wed Sep  8 08:19:18 1999  Frank Warmerdam  <warmerda at gdal.velocet.ca>
 
-	* Added IRIX/gcc, and OSF/1 4.x support on behalf of 
+	* Added IRIX/gcc, and OSF/1 4.x support on behalf of
 	  Albert Chin-A-Young <china at thewrittenword.com>
 
-	* Added TIFFReassignTagToIgnore() API on behalf of 
+	* Added TIFFReassignTagToIgnore() API on behalf of
 	  Bruce Cameron <cameron at petris.com>.  Man page still pending.
 
 Wed Aug 25 11:39:07 1999  Frank Warmerdam  <warmerda at gdal.velocet.ca>
 
-	* Added test target in Makefile, test_pics.sh script and pics/*.rpt 
+	* Added test target in Makefile, test_pics.sh script and pics/*.rpt
 	files to provide for a rudimentary testsuite.
 
 	* Added contrib/tags back from old distribution ... fixed up a bit.
@@ -5806,7 +6231,7 @@ Wed Aug 25 11:39:07 1999  Frank Warmerdam  <warmerda at gdal.velocet.ca>
 1999-08-16    <warmerda at CS46980-B>
 
 	* Added simple makefile.vc makefiles for building with MS VC++
-	on Windows NT/98/95 in console mode.  Stuff in contrib/win* make give 
+	on Windows NT/98/95 in console mode.  Stuff in contrib/win* make give
 	better solutions for some users.
 
 Mon Aug 16 21:52:11 1999  Frank Warmerdam  <warmerda at gdal.velocet.ca>
@@ -5816,20 +6241,20 @@ Mon Aug 16 21:52:11 1999  Frank Warmerdam  <warmerda at gdal.velocet.ca>
 
 1999-08-16  Michael L. Welles  <mike at kurtz.fake>
 
-	* Updated html/index.html with anon CVS instructions. 
+	* Updated html/index.html with anon CVS instructions.
 
 Mon Aug 16 13:18:41 1999  Frank Warmerdam  <warmerda at gdal.velocet.ca>
 
-	* pre-remove so link before softlink in LINUXdso action in 
+	* pre-remove so link before softlink in LINUXdso action in
 	libtiff/Makefile.in to avoid failure on LINUXdso builds other than
 	the first.
 
 	* Fixed problem with cvtcmap() in tif_getimage.c modifying the
 	colormaps owned by the TIFF handle itself when trying to fixup wrong
 	(eight bit) colormaps.  Corrected by maintaining a private copy of
-	the colormap. 
+	the colormap.
 
-	* Added TIFFReadRGBATile()/TIFFReadRGBAStrip() support in 
+	* Added TIFFReadRGBATile()/TIFFReadRGBAStrip() support in
 	tif_getimage.c.
 
 	* CVS Repository placed at remotesensing.org.  ChangeLog added.
diff --git a/Source/LibTIFF4/LibTIFF4.2003.vcproj b/Source/LibTIFF4/LibTIFF4.2003.vcproj
deleted file mode 100644
index e261b5f..0000000
--- a/Source/LibTIFF4/LibTIFF4.2003.vcproj
+++ /dev/null
@@ -1,279 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="7.10"
-	Name="LibTIFF4"
-	ProjectGUID="{B03A124A-33A7-453B-8DDA-CB4DEF9EB4C9}"
-	SccProjectName=""$/FreeImage/LibTIFF4", MKAAAAAA"
-	SccLocalPath=".">
-	<Platforms>
-		<Platform
-			Name="Win32"/>
-	</Platforms>
-	<Configurations>
-		<Configuration
-			Name="Release|Win32"
-			OutputDirectory=".\Release"
-			IntermediateDirectory=".\Release"
-			ConfigurationType="4"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="FALSE"
-			CharacterSet="2">
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="2"
-				GlobalOptimizations="TRUE"
-				InlineFunctionExpansion="2"
-				EnableIntrinsicFunctions="TRUE"
-				FavorSizeOrSpeed="1"
-				OmitFramePointers="TRUE"
-				OptimizeForProcessor="3"
-				AdditionalIncludeDirectories="..\libtiff\libtiff,..\zlib"
-				PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
-				StringPooling="TRUE"
-				RuntimeLibrary="0"
-				BufferSecurityCheck="FALSE"
-				UsePrecompiledHeader="2"
-				PrecompiledHeaderFile=".\Release/LibTIFF4.pch"
-				AssemblerListingLocation=".\Release/"
-				ObjectFile=".\Release/"
-				ProgramDataBaseFileName=".\Release/"
-				WarningLevel="3"
-				SuppressStartupBanner="TRUE"
-				CompileAs="0"/>
-			<Tool
-				Name="VCCustomBuildTool"/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile=".\Release\LibTIFF4.lib"
-				SuppressStartupBanner="TRUE"/>
-			<Tool
-				Name="VCMIDLTool"/>
-			<Tool
-				Name="VCPostBuildEventTool"/>
-			<Tool
-				Name="VCPreBuildEventTool"/>
-			<Tool
-				Name="VCPreLinkEventTool"/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="1033"/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"/>
-			<Tool
-				Name="VCManagedWrapperGeneratorTool"/>
-			<Tool
-				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
-		</Configuration>
-		<Configuration
-			Name="Debug|Win32"
-			OutputDirectory=".\Debug"
-			IntermediateDirectory=".\Debug"
-			ConfigurationType="4"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="FALSE"
-			CharacterSet="2">
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="0"
-				AdditionalIncludeDirectories="..\libtiff\libtiff"
-				PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
-				StringPooling="TRUE"
-				BasicRuntimeChecks="3"
-				RuntimeLibrary="1"
-				UsePrecompiledHeader="2"
-				PrecompiledHeaderFile=".\Debug/LibTIFF4.pch"
-				AssemblerListingLocation=".\Debug/"
-				ObjectFile=".\Debug/"
-				ProgramDataBaseFileName=".\Debug/"
-				WarningLevel="3"
-				SuppressStartupBanner="TRUE"
-				DebugInformationFormat="4"
-				CompileAs="0"/>
-			<Tool
-				Name="VCCustomBuildTool"/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile=".\Debug\LibTIFF4.lib"
-				SuppressStartupBanner="TRUE"/>
-			<Tool
-				Name="VCMIDLTool"/>
-			<Tool
-				Name="VCPostBuildEventTool"/>
-			<Tool
-				Name="VCPreBuildEventTool"/>
-			<Tool
-				Name="VCPreLinkEventTool"/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="_DEBUG"
-				Culture="1033"/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"/>
-			<Tool
-				Name="VCManagedWrapperGeneratorTool"/>
-			<Tool
-				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Source Files"
-			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
-			<File
-				RelativePath=".\tif_aux.c">
-			</File>
-			<File
-				RelativePath=".\tif_close.c">
-			</File>
-			<File
-				RelativePath=".\tif_codec.c">
-			</File>
-			<File
-				RelativePath=".\tif_color.c">
-			</File>
-			<File
-				RelativePath=".\tif_compress.c">
-			</File>
-			<File
-				RelativePath=".\tif_dir.c">
-			</File>
-			<File
-				RelativePath=".\tif_dirinfo.c">
-			</File>
-			<File
-				RelativePath=".\tif_dirread.c">
-			</File>
-			<File
-				RelativePath=".\tif_dirwrite.c">
-			</File>
-			<File
-				RelativePath=".\tif_dumpmode.c">
-			</File>
-			<File
-				RelativePath=".\tif_error.c">
-			</File>
-			<File
-				RelativePath=".\tif_extension.c">
-			</File>
-			<File
-				RelativePath=".\tif_fax3.c">
-			</File>
-			<File
-				RelativePath=".\tif_fax3sm.c">
-			</File>
-			<File
-				RelativePath=".\tif_flush.c">
-			</File>
-			<File
-				RelativePath=".\tif_getimage.c">
-			</File>
-			<File
-				RelativePath=".\tif_jpeg.c">
-			</File>
-			<File
-				RelativePath=".\tif_luv.c">
-			</File>
-			<File
-				RelativePath=".\tif_lzma.c">
-			</File>
-			<File
-				RelativePath=".\tif_lzw.c">
-			</File>
-			<File
-				RelativePath=".\tif_next.c">
-			</File>
-			<File
-				RelativePath=".\tif_ojpeg.c">
-			</File>
-			<File
-				RelativePath=".\tif_open.c">
-			</File>
-			<File
-				RelativePath=".\tif_packbits.c">
-			</File>
-			<File
-				RelativePath=".\tif_pixarlog.c">
-			</File>
-			<File
-				RelativePath=".\tif_predict.c">
-			</File>
-			<File
-				RelativePath=".\tif_print.c">
-			</File>
-			<File
-				RelativePath=".\tif_read.c">
-			</File>
-			<File
-				RelativePath=".\tif_strip.c">
-			</File>
-			<File
-				RelativePath=".\tif_swab.c">
-			</File>
-			<File
-				RelativePath=".\tif_thunder.c">
-			</File>
-			<File
-				RelativePath=".\tif_tile.c">
-			</File>
-			<File
-				RelativePath=".\tif_version.c">
-			</File>
-			<File
-				RelativePath=".\tif_warning.c">
-			</File>
-			<File
-				RelativePath=".\tif_write.c">
-			</File>
-			<File
-				RelativePath=".\tif_zip.c">
-			</File>
-		</Filter>
-		<Filter
-			Name="Header Files"
-			Filter="h;hpp;hxx;hm;inl">
-			<File
-				RelativePath=".\t4.h">
-			</File>
-			<File
-				RelativePath=".\tif_config.h">
-			</File>
-			<File
-				RelativePath=".\tif_dir.h">
-			</File>
-			<File
-				RelativePath=".\tif_fax3.h">
-			</File>
-			<File
-				RelativePath=".\tif_predict.h">
-			</File>
-			<File
-				RelativePath=".\tiff.h">
-			</File>
-			<File
-				RelativePath=".\tiffconf.h">
-			</File>
-			<File
-				RelativePath=".\tiffio.h">
-			</File>
-			<File
-				RelativePath=".\tiffiop.h">
-			</File>
-			<File
-				RelativePath=".\tiffvers.h">
-			</File>
-			<File
-				RelativePath=".\uvcode.h">
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
diff --git a/Source/LibTIFF4/LibTIFF4.2013.vcxproj b/Source/LibTIFF4/LibTIFF4.2013.vcxproj
new file mode 100644
index 0000000..216344a
--- /dev/null
+++ b/Source/LibTIFF4/LibTIFF4.2013.vcxproj
@@ -0,0 +1,258 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectName>LibTIFF4</ProjectName>
+    <ProjectGuid>{EC085CBD-E9C3-477F-9A97-CB9D5DA30E27}</ProjectGuid>
+    <RootNamespace>LibTIFF4</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>12.0.21005.1</_ProjectFileVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <Optimization>Full</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <OmitFramePointers>true</OmitFramePointers>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <CompileAs>Default</CompileAs>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+      <DebugInformationFormat>None</DebugInformationFormat>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0409</Culture>
+    </ResourceCompile>
+    <Lib>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <LinkTimeCodeGeneration>true</LinkTimeCodeGeneration>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>Full</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <OmitFramePointers>true</OmitFramePointers>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <CompileAs>Default</CompileAs>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+      <DebugInformationFormat>None</DebugInformationFormat>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0409</Culture>
+    </ResourceCompile>
+    <Lib>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <LinkTimeCodeGeneration>true</LinkTimeCodeGeneration>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+      <CompileAs>Default</CompileAs>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0409</Culture>
+    </ResourceCompile>
+    <Lib>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <CompileAs>Default</CompileAs>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0409</Culture>
+    </ResourceCompile>
+    <Lib>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="tif_aux.c" />
+    <ClCompile Include="tif_close.c" />
+    <ClCompile Include="tif_codec.c" />
+    <ClCompile Include="tif_color.c" />
+    <ClCompile Include="tif_compress.c" />
+    <ClCompile Include="tif_dir.c" />
+    <ClCompile Include="tif_dirinfo.c" />
+    <ClCompile Include="tif_dirread.c" />
+    <ClCompile Include="tif_dirwrite.c" />
+    <ClCompile Include="tif_dumpmode.c" />
+    <ClCompile Include="tif_error.c" />
+    <ClCompile Include="tif_extension.c" />
+    <ClCompile Include="tif_fax3.c" />
+    <ClCompile Include="tif_fax3sm.c" />
+    <ClCompile Include="tif_flush.c" />
+    <ClCompile Include="tif_getimage.c" />
+    <ClCompile Include="tif_jpeg.c" />
+    <ClCompile Include="tif_luv.c" />
+    <ClCompile Include="tif_lzma.c" />
+    <ClCompile Include="tif_lzw.c" />
+    <ClCompile Include="tif_next.c" />
+    <ClCompile Include="tif_ojpeg.c" />
+    <ClCompile Include="tif_open.c" />
+    <ClCompile Include="tif_packbits.c" />
+    <ClCompile Include="tif_pixarlog.c" />
+    <ClCompile Include="tif_predict.c" />
+    <ClCompile Include="tif_print.c" />
+    <ClCompile Include="tif_read.c" />
+    <ClCompile Include="tif_strip.c" />
+    <ClCompile Include="tif_swab.c" />
+    <ClCompile Include="tif_thunder.c" />
+    <ClCompile Include="tif_tile.c" />
+    <ClCompile Include="tif_version.c" />
+    <ClCompile Include="tif_warning.c" />
+    <ClCompile Include="tif_write.c" />
+    <ClCompile Include="tif_zip.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="t4.h" />
+    <ClInclude Include="tif_config.h" />
+    <ClInclude Include="tif_dir.h" />
+    <ClInclude Include="tif_fax3.h" />
+    <ClInclude Include="tif_predict.h" />
+    <ClInclude Include="tiff.h" />
+    <ClInclude Include="tiffconf.h" />
+    <ClInclude Include="tiffio.h" />
+    <ClInclude Include="tiffiop.h" />
+    <ClInclude Include="tiffvers.h" />
+    <ClInclude Include="uvcode.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\LibJPEG\LibJPEG.2013.vcxproj">
+      <Project>{5e1d4e5f-e10c-4ba3-b663-f33014fd21d9}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+    <ProjectReference Include="..\ZLib\ZLib.2013.vcxproj">
+      <Project>{33134f61-c1ad-4b6f-9cea-503a9f140c52}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/Source/LibTIFF4/LibTIFF4.2013.vcxproj.filters b/Source/LibTIFF4/LibTIFF4.2013.vcxproj.filters
new file mode 100644
index 0000000..9ed18ab
--- /dev/null
+++ b/Source/LibTIFF4/LibTIFF4.2013.vcxproj.filters
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{39a70406-cbe3-4a09-bbac-abf6bff2f512}</UniqueIdentifier>
+      <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{072366c9-2b77-421b-82a9-5948f2b56228}</UniqueIdentifier>
+      <Extensions>h;hpp;hxx;hm;inl</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="tif_aux.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="tif_close.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="tif_codec.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="tif_color.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="tif_compress.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="tif_dir.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="tif_dirinfo.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="tif_dirread.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="tif_dirwrite.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="tif_dumpmode.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="tif_error.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="tif_extension.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="tif_fax3.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="tif_fax3sm.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="tif_flush.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="tif_getimage.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="tif_jpeg.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="tif_luv.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="tif_lzma.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="tif_lzw.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="tif_next.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="tif_ojpeg.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="tif_open.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="tif_packbits.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="tif_pixarlog.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="tif_predict.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="tif_print.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="tif_read.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="tif_strip.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="tif_swab.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="tif_thunder.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="tif_tile.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="tif_version.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="tif_warning.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="tif_write.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="tif_zip.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="t4.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="tif_config.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="tif_dir.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="tif_fax3.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="tif_predict.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="tiff.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="tiffconf.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="tiffio.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="tiffiop.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="tiffvers.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="uvcode.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/Source/LibTIFF4/mkg3states.c b/Source/LibTIFF4/mkg3states.c
index 7b718fa..0121cff 100644
--- a/Source/LibTIFF4/mkg3states.c
+++ b/Source/LibTIFF4/mkg3states.c
@@ -1,4 +1,4 @@
-/* "$Id: mkg3states.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
+/* "$Id: mkg3states.c,v 1.11 2015/02/19 22:39:58 drolon Exp $ */
 
 /*
  * Copyright (c) 1991-1997 Sam Leffler
diff --git a/Source/LibTIFF4/mkspans.c b/Source/LibTIFF4/mkspans.c
index 1806313..1758f18 100644
--- a/Source/LibTIFF4/mkspans.c
+++ b/Source/LibTIFF4/mkspans.c
@@ -1,4 +1,4 @@
-/* $Id: mkspans.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
+/* $Id: mkspans.c,v 1.11 2015/02/19 22:39:58 drolon Exp $ */
 
 /*
  * Copyright (c) 1991-1997 Sam Leffler
diff --git a/Source/LibTIFF4/t4.h b/Source/LibTIFF4/t4.h
index 32023b0..ae74e8e 100644
--- a/Source/LibTIFF4/t4.h
+++ b/Source/LibTIFF4/t4.h
@@ -1,292 +1,292 @@
-/* $Id: t4.h,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- */
-
-#ifndef _T4_
-#define	_T4_
-/*
- * CCITT T.4 1D Huffman runlength codes and
- * related definitions.  Given the small sizes
- * of these tables it does not seem
- * worthwhile to make code & length 8 bits.
- */
-typedef struct tableentry {
-    unsigned short length;  /* bit length of g3 code */
-    unsigned short code;    /* g3 code */
-    short runlen;           /* run length in bits */
-} tableentry;
-
-#define EOL	0x001	/* EOL code value - 0000 0000 0000 1 */
-
-/* status values returned instead of a run length */
-#define G3CODE_EOL	-1	/* NB: ACT_EOL - ACT_WRUNT */
-#define G3CODE_INVALID	-2	/* NB: ACT_INVALID - ACT_WRUNT */
-#define G3CODE_EOF	-3	/* end of input data */
-#define G3CODE_INCOMP	-4	/* incomplete run code */
-
-/*
- * Note that these tables are ordered such that the
- * index into the table is known to be either the
- * run length, or (run length / 64) + a fixed offset.
- *
- * NB: The G3CODE_INVALID entries are only used
- *     during state generation (see mkg3states.c).
- */
-#ifdef G3CODES
-const tableentry TIFFFaxWhiteCodes[] = {
-    { 8, 0x35, 0 },	/* 0011 0101 */
-    { 6, 0x7, 1 },	/* 0001 11 */
-    { 4, 0x7, 2 },	/* 0111 */
-    { 4, 0x8, 3 },	/* 1000 */
-    { 4, 0xB, 4 },	/* 1011 */
-    { 4, 0xC, 5 },	/* 1100 */
-    { 4, 0xE, 6 },	/* 1110 */
-    { 4, 0xF, 7 },	/* 1111 */
-    { 5, 0x13, 8 },	/* 1001 1 */
-    { 5, 0x14, 9 },	/* 1010 0 */
-    { 5, 0x7, 10 },	/* 0011 1 */
-    { 5, 0x8, 11 },	/* 0100 0 */
-    { 6, 0x8, 12 },	/* 0010 00 */
-    { 6, 0x3, 13 },	/* 0000 11 */
-    { 6, 0x34, 14 },	/* 1101 00 */
-    { 6, 0x35, 15 },	/* 1101 01 */
-    { 6, 0x2A, 16 },	/* 1010 10 */
-    { 6, 0x2B, 17 },	/* 1010 11 */
-    { 7, 0x27, 18 },	/* 0100 111 */
-    { 7, 0xC, 19 },	/* 0001 100 */
-    { 7, 0x8, 20 },	/* 0001 000 */
-    { 7, 0x17, 21 },	/* 0010 111 */
-    { 7, 0x3, 22 },	/* 0000 011 */
-    { 7, 0x4, 23 },	/* 0000 100 */
-    { 7, 0x28, 24 },	/* 0101 000 */
-    { 7, 0x2B, 25 },	/* 0101 011 */
-    { 7, 0x13, 26 },	/* 0010 011 */
-    { 7, 0x24, 27 },	/* 0100 100 */
-    { 7, 0x18, 28 },	/* 0011 000 */
-    { 8, 0x2, 29 },	/* 0000 0010 */
-    { 8, 0x3, 30 },	/* 0000 0011 */
-    { 8, 0x1A, 31 },	/* 0001 1010 */
-    { 8, 0x1B, 32 },	/* 0001 1011 */
-    { 8, 0x12, 33 },	/* 0001 0010 */
-    { 8, 0x13, 34 },	/* 0001 0011 */
-    { 8, 0x14, 35 },	/* 0001 0100 */
-    { 8, 0x15, 36 },	/* 0001 0101 */
-    { 8, 0x16, 37 },	/* 0001 0110 */
-    { 8, 0x17, 38 },	/* 0001 0111 */
-    { 8, 0x28, 39 },	/* 0010 1000 */
-    { 8, 0x29, 40 },	/* 0010 1001 */
-    { 8, 0x2A, 41 },	/* 0010 1010 */
-    { 8, 0x2B, 42 },	/* 0010 1011 */
-    { 8, 0x2C, 43 },	/* 0010 1100 */
-    { 8, 0x2D, 44 },	/* 0010 1101 */
-    { 8, 0x4, 45 },	/* 0000 0100 */
-    { 8, 0x5, 46 },	/* 0000 0101 */
-    { 8, 0xA, 47 },	/* 0000 1010 */
-    { 8, 0xB, 48 },	/* 0000 1011 */
-    { 8, 0x52, 49 },	/* 0101 0010 */
-    { 8, 0x53, 50 },	/* 0101 0011 */
-    { 8, 0x54, 51 },	/* 0101 0100 */
-    { 8, 0x55, 52 },	/* 0101 0101 */
-    { 8, 0x24, 53 },	/* 0010 0100 */
-    { 8, 0x25, 54 },	/* 0010 0101 */
-    { 8, 0x58, 55 },	/* 0101 1000 */
-    { 8, 0x59, 56 },	/* 0101 1001 */
-    { 8, 0x5A, 57 },	/* 0101 1010 */
-    { 8, 0x5B, 58 },	/* 0101 1011 */
-    { 8, 0x4A, 59 },	/* 0100 1010 */
-    { 8, 0x4B, 60 },	/* 0100 1011 */
-    { 8, 0x32, 61 },	/* 0011 0010 */
-    { 8, 0x33, 62 },	/* 0011 0011 */
-    { 8, 0x34, 63 },	/* 0011 0100 */
-    { 5, 0x1B, 64 },	/* 1101 1 */
-    { 5, 0x12, 128 },	/* 1001 0 */
-    { 6, 0x17, 192 },	/* 0101 11 */
-    { 7, 0x37, 256 },	/* 0110 111 */
-    { 8, 0x36, 320 },	/* 0011 0110 */
-    { 8, 0x37, 384 },	/* 0011 0111 */
-    { 8, 0x64, 448 },	/* 0110 0100 */
-    { 8, 0x65, 512 },	/* 0110 0101 */
-    { 8, 0x68, 576 },	/* 0110 1000 */
-    { 8, 0x67, 640 },	/* 0110 0111 */
-    { 9, 0xCC, 704 },	/* 0110 0110 0 */
-    { 9, 0xCD, 768 },	/* 0110 0110 1 */
-    { 9, 0xD2, 832 },	/* 0110 1001 0 */
-    { 9, 0xD3, 896 },	/* 0110 1001 1 */
-    { 9, 0xD4, 960 },	/* 0110 1010 0 */
-    { 9, 0xD5, 1024 },	/* 0110 1010 1 */
-    { 9, 0xD6, 1088 },	/* 0110 1011 0 */
-    { 9, 0xD7, 1152 },	/* 0110 1011 1 */
-    { 9, 0xD8, 1216 },	/* 0110 1100 0 */
-    { 9, 0xD9, 1280 },	/* 0110 1100 1 */
-    { 9, 0xDA, 1344 },	/* 0110 1101 0 */
-    { 9, 0xDB, 1408 },	/* 0110 1101 1 */
-    { 9, 0x98, 1472 },	/* 0100 1100 0 */
-    { 9, 0x99, 1536 },	/* 0100 1100 1 */
-    { 9, 0x9A, 1600 },	/* 0100 1101 0 */
-    { 6, 0x18, 1664 },	/* 0110 00 */
-    { 9, 0x9B, 1728 },	/* 0100 1101 1 */
-    { 11, 0x8, 1792 },	/* 0000 0001 000 */
-    { 11, 0xC, 1856 },	/* 0000 0001 100 */
-    { 11, 0xD, 1920 },	/* 0000 0001 101 */
-    { 12, 0x12, 1984 },	/* 0000 0001 0010 */
-    { 12, 0x13, 2048 },	/* 0000 0001 0011 */
-    { 12, 0x14, 2112 },	/* 0000 0001 0100 */
-    { 12, 0x15, 2176 },	/* 0000 0001 0101 */
-    { 12, 0x16, 2240 },	/* 0000 0001 0110 */
-    { 12, 0x17, 2304 },	/* 0000 0001 0111 */
-    { 12, 0x1C, 2368 },	/* 0000 0001 1100 */
-    { 12, 0x1D, 2432 },	/* 0000 0001 1101 */
-    { 12, 0x1E, 2496 },	/* 0000 0001 1110 */
-    { 12, 0x1F, 2560 },	/* 0000 0001 1111 */
-    { 12, 0x1, G3CODE_EOL },	/* 0000 0000 0001 */
-    { 9, 0x1, G3CODE_INVALID },	/* 0000 0000 1 */
-    { 10, 0x1, G3CODE_INVALID },	/* 0000 0000 01 */
-    { 11, 0x1, G3CODE_INVALID },	/* 0000 0000 001 */
-    { 12, 0x0, G3CODE_INVALID },	/* 0000 0000 0000 */
-};
-
-const tableentry TIFFFaxBlackCodes[] = {
-    { 10, 0x37, 0 },	/* 0000 1101 11 */
-    { 3, 0x2, 1 },	/* 010 */
-    { 2, 0x3, 2 },	/* 11 */
-    { 2, 0x2, 3 },	/* 10 */
-    { 3, 0x3, 4 },	/* 011 */
-    { 4, 0x3, 5 },	/* 0011 */
-    { 4, 0x2, 6 },	/* 0010 */
-    { 5, 0x3, 7 },	/* 0001 1 */
-    { 6, 0x5, 8 },	/* 0001 01 */
-    { 6, 0x4, 9 },	/* 0001 00 */
-    { 7, 0x4, 10 },	/* 0000 100 */
-    { 7, 0x5, 11 },	/* 0000 101 */
-    { 7, 0x7, 12 },	/* 0000 111 */
-    { 8, 0x4, 13 },	/* 0000 0100 */
-    { 8, 0x7, 14 },	/* 0000 0111 */
-    { 9, 0x18, 15 },	/* 0000 1100 0 */
-    { 10, 0x17, 16 },	/* 0000 0101 11 */
-    { 10, 0x18, 17 },	/* 0000 0110 00 */
-    { 10, 0x8, 18 },	/* 0000 0010 00 */
-    { 11, 0x67, 19 },	/* 0000 1100 111 */
-    { 11, 0x68, 20 },	/* 0000 1101 000 */
-    { 11, 0x6C, 21 },	/* 0000 1101 100 */
-    { 11, 0x37, 22 },	/* 0000 0110 111 */
-    { 11, 0x28, 23 },	/* 0000 0101 000 */
-    { 11, 0x17, 24 },	/* 0000 0010 111 */
-    { 11, 0x18, 25 },	/* 0000 0011 000 */
-    { 12, 0xCA, 26 },	/* 0000 1100 1010 */
-    { 12, 0xCB, 27 },	/* 0000 1100 1011 */
-    { 12, 0xCC, 28 },	/* 0000 1100 1100 */
-    { 12, 0xCD, 29 },	/* 0000 1100 1101 */
-    { 12, 0x68, 30 },	/* 0000 0110 1000 */
-    { 12, 0x69, 31 },	/* 0000 0110 1001 */
-    { 12, 0x6A, 32 },	/* 0000 0110 1010 */
-    { 12, 0x6B, 33 },	/* 0000 0110 1011 */
-    { 12, 0xD2, 34 },	/* 0000 1101 0010 */
-    { 12, 0xD3, 35 },	/* 0000 1101 0011 */
-    { 12, 0xD4, 36 },	/* 0000 1101 0100 */
-    { 12, 0xD5, 37 },	/* 0000 1101 0101 */
-    { 12, 0xD6, 38 },	/* 0000 1101 0110 */
-    { 12, 0xD7, 39 },	/* 0000 1101 0111 */
-    { 12, 0x6C, 40 },	/* 0000 0110 1100 */
-    { 12, 0x6D, 41 },	/* 0000 0110 1101 */
-    { 12, 0xDA, 42 },	/* 0000 1101 1010 */
-    { 12, 0xDB, 43 },	/* 0000 1101 1011 */
-    { 12, 0x54, 44 },	/* 0000 0101 0100 */
-    { 12, 0x55, 45 },	/* 0000 0101 0101 */
-    { 12, 0x56, 46 },	/* 0000 0101 0110 */
-    { 12, 0x57, 47 },	/* 0000 0101 0111 */
-    { 12, 0x64, 48 },	/* 0000 0110 0100 */
-    { 12, 0x65, 49 },	/* 0000 0110 0101 */
-    { 12, 0x52, 50 },	/* 0000 0101 0010 */
-    { 12, 0x53, 51 },	/* 0000 0101 0011 */
-    { 12, 0x24, 52 },	/* 0000 0010 0100 */
-    { 12, 0x37, 53 },	/* 0000 0011 0111 */
-    { 12, 0x38, 54 },	/* 0000 0011 1000 */
-    { 12, 0x27, 55 },	/* 0000 0010 0111 */
-    { 12, 0x28, 56 },	/* 0000 0010 1000 */
-    { 12, 0x58, 57 },	/* 0000 0101 1000 */
-    { 12, 0x59, 58 },	/* 0000 0101 1001 */
-    { 12, 0x2B, 59 },	/* 0000 0010 1011 */
-    { 12, 0x2C, 60 },	/* 0000 0010 1100 */
-    { 12, 0x5A, 61 },	/* 0000 0101 1010 */
-    { 12, 0x66, 62 },	/* 0000 0110 0110 */
-    { 12, 0x67, 63 },	/* 0000 0110 0111 */
-    { 10, 0xF, 64 },	/* 0000 0011 11 */
-    { 12, 0xC8, 128 },	/* 0000 1100 1000 */
-    { 12, 0xC9, 192 },	/* 0000 1100 1001 */
-    { 12, 0x5B, 256 },	/* 0000 0101 1011 */
-    { 12, 0x33, 320 },	/* 0000 0011 0011 */
-    { 12, 0x34, 384 },	/* 0000 0011 0100 */
-    { 12, 0x35, 448 },	/* 0000 0011 0101 */
-    { 13, 0x6C, 512 },	/* 0000 0011 0110 0 */
-    { 13, 0x6D, 576 },	/* 0000 0011 0110 1 */
-    { 13, 0x4A, 640 },	/* 0000 0010 0101 0 */
-    { 13, 0x4B, 704 },	/* 0000 0010 0101 1 */
-    { 13, 0x4C, 768 },	/* 0000 0010 0110 0 */
-    { 13, 0x4D, 832 },	/* 0000 0010 0110 1 */
-    { 13, 0x72, 896 },	/* 0000 0011 1001 0 */
-    { 13, 0x73, 960 },	/* 0000 0011 1001 1 */
-    { 13, 0x74, 1024 },	/* 0000 0011 1010 0 */
-    { 13, 0x75, 1088 },	/* 0000 0011 1010 1 */
-    { 13, 0x76, 1152 },	/* 0000 0011 1011 0 */
-    { 13, 0x77, 1216 },	/* 0000 0011 1011 1 */
-    { 13, 0x52, 1280 },	/* 0000 0010 1001 0 */
-    { 13, 0x53, 1344 },	/* 0000 0010 1001 1 */
-    { 13, 0x54, 1408 },	/* 0000 0010 1010 0 */
-    { 13, 0x55, 1472 },	/* 0000 0010 1010 1 */
-    { 13, 0x5A, 1536 },	/* 0000 0010 1101 0 */
-    { 13, 0x5B, 1600 },	/* 0000 0010 1101 1 */
-    { 13, 0x64, 1664 },	/* 0000 0011 0010 0 */
-    { 13, 0x65, 1728 },	/* 0000 0011 0010 1 */
-    { 11, 0x8, 1792 },	/* 0000 0001 000 */
-    { 11, 0xC, 1856 },	/* 0000 0001 100 */
-    { 11, 0xD, 1920 },	/* 0000 0001 101 */
-    { 12, 0x12, 1984 },	/* 0000 0001 0010 */
-    { 12, 0x13, 2048 },	/* 0000 0001 0011 */
-    { 12, 0x14, 2112 },	/* 0000 0001 0100 */
-    { 12, 0x15, 2176 },	/* 0000 0001 0101 */
-    { 12, 0x16, 2240 },	/* 0000 0001 0110 */
-    { 12, 0x17, 2304 },	/* 0000 0001 0111 */
-    { 12, 0x1C, 2368 },	/* 0000 0001 1100 */
-    { 12, 0x1D, 2432 },	/* 0000 0001 1101 */
-    { 12, 0x1E, 2496 },	/* 0000 0001 1110 */
-    { 12, 0x1F, 2560 },	/* 0000 0001 1111 */
-    { 12, 0x1, G3CODE_EOL },	/* 0000 0000 0001 */
-    { 9, 0x1, G3CODE_INVALID },	/* 0000 0000 1 */
-    { 10, 0x1, G3CODE_INVALID },	/* 0000 0000 01 */
-    { 11, 0x1, G3CODE_INVALID },	/* 0000 0000 001 */
-    { 12, 0x0, G3CODE_INVALID },	/* 0000 0000 0000 */
-};
-#else
-extern const tableentry TIFFFaxWhiteCodes[];
-extern const tableentry TIFFFaxBlackCodes[];
-#endif
-#endif /* _T4_ */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Id: t4.h,v 1.11 2015/02/19 22:39:58 drolon Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef _T4_
+#define	_T4_
+/*
+ * CCITT T.4 1D Huffman runlength codes and
+ * related definitions.  Given the small sizes
+ * of these tables it does not seem
+ * worthwhile to make code & length 8 bits.
+ */
+typedef struct tableentry {
+    unsigned short length;  /* bit length of g3 code */
+    unsigned short code;    /* g3 code */
+    short runlen;           /* run length in bits */
+} tableentry;
+
+#define EOL	0x001	/* EOL code value - 0000 0000 0000 1 */
+
+/* status values returned instead of a run length */
+#define G3CODE_EOL	-1	/* NB: ACT_EOL - ACT_WRUNT */
+#define G3CODE_INVALID	-2	/* NB: ACT_INVALID - ACT_WRUNT */
+#define G3CODE_EOF	-3	/* end of input data */
+#define G3CODE_INCOMP	-4	/* incomplete run code */
+
+/*
+ * Note that these tables are ordered such that the
+ * index into the table is known to be either the
+ * run length, or (run length / 64) + a fixed offset.
+ *
+ * NB: The G3CODE_INVALID entries are only used
+ *     during state generation (see mkg3states.c).
+ */
+#ifdef G3CODES
+const tableentry TIFFFaxWhiteCodes[] = {
+    { 8, 0x35, 0 },	/* 0011 0101 */
+    { 6, 0x7, 1 },	/* 0001 11 */
+    { 4, 0x7, 2 },	/* 0111 */
+    { 4, 0x8, 3 },	/* 1000 */
+    { 4, 0xB, 4 },	/* 1011 */
+    { 4, 0xC, 5 },	/* 1100 */
+    { 4, 0xE, 6 },	/* 1110 */
+    { 4, 0xF, 7 },	/* 1111 */
+    { 5, 0x13, 8 },	/* 1001 1 */
+    { 5, 0x14, 9 },	/* 1010 0 */
+    { 5, 0x7, 10 },	/* 0011 1 */
+    { 5, 0x8, 11 },	/* 0100 0 */
+    { 6, 0x8, 12 },	/* 0010 00 */
+    { 6, 0x3, 13 },	/* 0000 11 */
+    { 6, 0x34, 14 },	/* 1101 00 */
+    { 6, 0x35, 15 },	/* 1101 01 */
+    { 6, 0x2A, 16 },	/* 1010 10 */
+    { 6, 0x2B, 17 },	/* 1010 11 */
+    { 7, 0x27, 18 },	/* 0100 111 */
+    { 7, 0xC, 19 },	/* 0001 100 */
+    { 7, 0x8, 20 },	/* 0001 000 */
+    { 7, 0x17, 21 },	/* 0010 111 */
+    { 7, 0x3, 22 },	/* 0000 011 */
+    { 7, 0x4, 23 },	/* 0000 100 */
+    { 7, 0x28, 24 },	/* 0101 000 */
+    { 7, 0x2B, 25 },	/* 0101 011 */
+    { 7, 0x13, 26 },	/* 0010 011 */
+    { 7, 0x24, 27 },	/* 0100 100 */
+    { 7, 0x18, 28 },	/* 0011 000 */
+    { 8, 0x2, 29 },	/* 0000 0010 */
+    { 8, 0x3, 30 },	/* 0000 0011 */
+    { 8, 0x1A, 31 },	/* 0001 1010 */
+    { 8, 0x1B, 32 },	/* 0001 1011 */
+    { 8, 0x12, 33 },	/* 0001 0010 */
+    { 8, 0x13, 34 },	/* 0001 0011 */
+    { 8, 0x14, 35 },	/* 0001 0100 */
+    { 8, 0x15, 36 },	/* 0001 0101 */
+    { 8, 0x16, 37 },	/* 0001 0110 */
+    { 8, 0x17, 38 },	/* 0001 0111 */
+    { 8, 0x28, 39 },	/* 0010 1000 */
+    { 8, 0x29, 40 },	/* 0010 1001 */
+    { 8, 0x2A, 41 },	/* 0010 1010 */
+    { 8, 0x2B, 42 },	/* 0010 1011 */
+    { 8, 0x2C, 43 },	/* 0010 1100 */
+    { 8, 0x2D, 44 },	/* 0010 1101 */
+    { 8, 0x4, 45 },	/* 0000 0100 */
+    { 8, 0x5, 46 },	/* 0000 0101 */
+    { 8, 0xA, 47 },	/* 0000 1010 */
+    { 8, 0xB, 48 },	/* 0000 1011 */
+    { 8, 0x52, 49 },	/* 0101 0010 */
+    { 8, 0x53, 50 },	/* 0101 0011 */
+    { 8, 0x54, 51 },	/* 0101 0100 */
+    { 8, 0x55, 52 },	/* 0101 0101 */
+    { 8, 0x24, 53 },	/* 0010 0100 */
+    { 8, 0x25, 54 },	/* 0010 0101 */
+    { 8, 0x58, 55 },	/* 0101 1000 */
+    { 8, 0x59, 56 },	/* 0101 1001 */
+    { 8, 0x5A, 57 },	/* 0101 1010 */
+    { 8, 0x5B, 58 },	/* 0101 1011 */
+    { 8, 0x4A, 59 },	/* 0100 1010 */
+    { 8, 0x4B, 60 },	/* 0100 1011 */
+    { 8, 0x32, 61 },	/* 0011 0010 */
+    { 8, 0x33, 62 },	/* 0011 0011 */
+    { 8, 0x34, 63 },	/* 0011 0100 */
+    { 5, 0x1B, 64 },	/* 1101 1 */
+    { 5, 0x12, 128 },	/* 1001 0 */
+    { 6, 0x17, 192 },	/* 0101 11 */
+    { 7, 0x37, 256 },	/* 0110 111 */
+    { 8, 0x36, 320 },	/* 0011 0110 */
+    { 8, 0x37, 384 },	/* 0011 0111 */
+    { 8, 0x64, 448 },	/* 0110 0100 */
+    { 8, 0x65, 512 },	/* 0110 0101 */
+    { 8, 0x68, 576 },	/* 0110 1000 */
+    { 8, 0x67, 640 },	/* 0110 0111 */
+    { 9, 0xCC, 704 },	/* 0110 0110 0 */
+    { 9, 0xCD, 768 },	/* 0110 0110 1 */
+    { 9, 0xD2, 832 },	/* 0110 1001 0 */
+    { 9, 0xD3, 896 },	/* 0110 1001 1 */
+    { 9, 0xD4, 960 },	/* 0110 1010 0 */
+    { 9, 0xD5, 1024 },	/* 0110 1010 1 */
+    { 9, 0xD6, 1088 },	/* 0110 1011 0 */
+    { 9, 0xD7, 1152 },	/* 0110 1011 1 */
+    { 9, 0xD8, 1216 },	/* 0110 1100 0 */
+    { 9, 0xD9, 1280 },	/* 0110 1100 1 */
+    { 9, 0xDA, 1344 },	/* 0110 1101 0 */
+    { 9, 0xDB, 1408 },	/* 0110 1101 1 */
+    { 9, 0x98, 1472 },	/* 0100 1100 0 */
+    { 9, 0x99, 1536 },	/* 0100 1100 1 */
+    { 9, 0x9A, 1600 },	/* 0100 1101 0 */
+    { 6, 0x18, 1664 },	/* 0110 00 */
+    { 9, 0x9B, 1728 },	/* 0100 1101 1 */
+    { 11, 0x8, 1792 },	/* 0000 0001 000 */
+    { 11, 0xC, 1856 },	/* 0000 0001 100 */
+    { 11, 0xD, 1920 },	/* 0000 0001 101 */
+    { 12, 0x12, 1984 },	/* 0000 0001 0010 */
+    { 12, 0x13, 2048 },	/* 0000 0001 0011 */
+    { 12, 0x14, 2112 },	/* 0000 0001 0100 */
+    { 12, 0x15, 2176 },	/* 0000 0001 0101 */
+    { 12, 0x16, 2240 },	/* 0000 0001 0110 */
+    { 12, 0x17, 2304 },	/* 0000 0001 0111 */
+    { 12, 0x1C, 2368 },	/* 0000 0001 1100 */
+    { 12, 0x1D, 2432 },	/* 0000 0001 1101 */
+    { 12, 0x1E, 2496 },	/* 0000 0001 1110 */
+    { 12, 0x1F, 2560 },	/* 0000 0001 1111 */
+    { 12, 0x1, G3CODE_EOL },	/* 0000 0000 0001 */
+    { 9, 0x1, G3CODE_INVALID },	/* 0000 0000 1 */
+    { 10, 0x1, G3CODE_INVALID },	/* 0000 0000 01 */
+    { 11, 0x1, G3CODE_INVALID },	/* 0000 0000 001 */
+    { 12, 0x0, G3CODE_INVALID },	/* 0000 0000 0000 */
+};
+
+const tableentry TIFFFaxBlackCodes[] = {
+    { 10, 0x37, 0 },	/* 0000 1101 11 */
+    { 3, 0x2, 1 },	/* 010 */
+    { 2, 0x3, 2 },	/* 11 */
+    { 2, 0x2, 3 },	/* 10 */
+    { 3, 0x3, 4 },	/* 011 */
+    { 4, 0x3, 5 },	/* 0011 */
+    { 4, 0x2, 6 },	/* 0010 */
+    { 5, 0x3, 7 },	/* 0001 1 */
+    { 6, 0x5, 8 },	/* 0001 01 */
+    { 6, 0x4, 9 },	/* 0001 00 */
+    { 7, 0x4, 10 },	/* 0000 100 */
+    { 7, 0x5, 11 },	/* 0000 101 */
+    { 7, 0x7, 12 },	/* 0000 111 */
+    { 8, 0x4, 13 },	/* 0000 0100 */
+    { 8, 0x7, 14 },	/* 0000 0111 */
+    { 9, 0x18, 15 },	/* 0000 1100 0 */
+    { 10, 0x17, 16 },	/* 0000 0101 11 */
+    { 10, 0x18, 17 },	/* 0000 0110 00 */
+    { 10, 0x8, 18 },	/* 0000 0010 00 */
+    { 11, 0x67, 19 },	/* 0000 1100 111 */
+    { 11, 0x68, 20 },	/* 0000 1101 000 */
+    { 11, 0x6C, 21 },	/* 0000 1101 100 */
+    { 11, 0x37, 22 },	/* 0000 0110 111 */
+    { 11, 0x28, 23 },	/* 0000 0101 000 */
+    { 11, 0x17, 24 },	/* 0000 0010 111 */
+    { 11, 0x18, 25 },	/* 0000 0011 000 */
+    { 12, 0xCA, 26 },	/* 0000 1100 1010 */
+    { 12, 0xCB, 27 },	/* 0000 1100 1011 */
+    { 12, 0xCC, 28 },	/* 0000 1100 1100 */
+    { 12, 0xCD, 29 },	/* 0000 1100 1101 */
+    { 12, 0x68, 30 },	/* 0000 0110 1000 */
+    { 12, 0x69, 31 },	/* 0000 0110 1001 */
+    { 12, 0x6A, 32 },	/* 0000 0110 1010 */
+    { 12, 0x6B, 33 },	/* 0000 0110 1011 */
+    { 12, 0xD2, 34 },	/* 0000 1101 0010 */
+    { 12, 0xD3, 35 },	/* 0000 1101 0011 */
+    { 12, 0xD4, 36 },	/* 0000 1101 0100 */
+    { 12, 0xD5, 37 },	/* 0000 1101 0101 */
+    { 12, 0xD6, 38 },	/* 0000 1101 0110 */
+    { 12, 0xD7, 39 },	/* 0000 1101 0111 */
+    { 12, 0x6C, 40 },	/* 0000 0110 1100 */
+    { 12, 0x6D, 41 },	/* 0000 0110 1101 */
+    { 12, 0xDA, 42 },	/* 0000 1101 1010 */
+    { 12, 0xDB, 43 },	/* 0000 1101 1011 */
+    { 12, 0x54, 44 },	/* 0000 0101 0100 */
+    { 12, 0x55, 45 },	/* 0000 0101 0101 */
+    { 12, 0x56, 46 },	/* 0000 0101 0110 */
+    { 12, 0x57, 47 },	/* 0000 0101 0111 */
+    { 12, 0x64, 48 },	/* 0000 0110 0100 */
+    { 12, 0x65, 49 },	/* 0000 0110 0101 */
+    { 12, 0x52, 50 },	/* 0000 0101 0010 */
+    { 12, 0x53, 51 },	/* 0000 0101 0011 */
+    { 12, 0x24, 52 },	/* 0000 0010 0100 */
+    { 12, 0x37, 53 },	/* 0000 0011 0111 */
+    { 12, 0x38, 54 },	/* 0000 0011 1000 */
+    { 12, 0x27, 55 },	/* 0000 0010 0111 */
+    { 12, 0x28, 56 },	/* 0000 0010 1000 */
+    { 12, 0x58, 57 },	/* 0000 0101 1000 */
+    { 12, 0x59, 58 },	/* 0000 0101 1001 */
+    { 12, 0x2B, 59 },	/* 0000 0010 1011 */
+    { 12, 0x2C, 60 },	/* 0000 0010 1100 */
+    { 12, 0x5A, 61 },	/* 0000 0101 1010 */
+    { 12, 0x66, 62 },	/* 0000 0110 0110 */
+    { 12, 0x67, 63 },	/* 0000 0110 0111 */
+    { 10, 0xF, 64 },	/* 0000 0011 11 */
+    { 12, 0xC8, 128 },	/* 0000 1100 1000 */
+    { 12, 0xC9, 192 },	/* 0000 1100 1001 */
+    { 12, 0x5B, 256 },	/* 0000 0101 1011 */
+    { 12, 0x33, 320 },	/* 0000 0011 0011 */
+    { 12, 0x34, 384 },	/* 0000 0011 0100 */
+    { 12, 0x35, 448 },	/* 0000 0011 0101 */
+    { 13, 0x6C, 512 },	/* 0000 0011 0110 0 */
+    { 13, 0x6D, 576 },	/* 0000 0011 0110 1 */
+    { 13, 0x4A, 640 },	/* 0000 0010 0101 0 */
+    { 13, 0x4B, 704 },	/* 0000 0010 0101 1 */
+    { 13, 0x4C, 768 },	/* 0000 0010 0110 0 */
+    { 13, 0x4D, 832 },	/* 0000 0010 0110 1 */
+    { 13, 0x72, 896 },	/* 0000 0011 1001 0 */
+    { 13, 0x73, 960 },	/* 0000 0011 1001 1 */
+    { 13, 0x74, 1024 },	/* 0000 0011 1010 0 */
+    { 13, 0x75, 1088 },	/* 0000 0011 1010 1 */
+    { 13, 0x76, 1152 },	/* 0000 0011 1011 0 */
+    { 13, 0x77, 1216 },	/* 0000 0011 1011 1 */
+    { 13, 0x52, 1280 },	/* 0000 0010 1001 0 */
+    { 13, 0x53, 1344 },	/* 0000 0010 1001 1 */
+    { 13, 0x54, 1408 },	/* 0000 0010 1010 0 */
+    { 13, 0x55, 1472 },	/* 0000 0010 1010 1 */
+    { 13, 0x5A, 1536 },	/* 0000 0010 1101 0 */
+    { 13, 0x5B, 1600 },	/* 0000 0010 1101 1 */
+    { 13, 0x64, 1664 },	/* 0000 0011 0010 0 */
+    { 13, 0x65, 1728 },	/* 0000 0011 0010 1 */
+    { 11, 0x8, 1792 },	/* 0000 0001 000 */
+    { 11, 0xC, 1856 },	/* 0000 0001 100 */
+    { 11, 0xD, 1920 },	/* 0000 0001 101 */
+    { 12, 0x12, 1984 },	/* 0000 0001 0010 */
+    { 12, 0x13, 2048 },	/* 0000 0001 0011 */
+    { 12, 0x14, 2112 },	/* 0000 0001 0100 */
+    { 12, 0x15, 2176 },	/* 0000 0001 0101 */
+    { 12, 0x16, 2240 },	/* 0000 0001 0110 */
+    { 12, 0x17, 2304 },	/* 0000 0001 0111 */
+    { 12, 0x1C, 2368 },	/* 0000 0001 1100 */
+    { 12, 0x1D, 2432 },	/* 0000 0001 1101 */
+    { 12, 0x1E, 2496 },	/* 0000 0001 1110 */
+    { 12, 0x1F, 2560 },	/* 0000 0001 1111 */
+    { 12, 0x1, G3CODE_EOL },	/* 0000 0000 0001 */
+    { 9, 0x1, G3CODE_INVALID },	/* 0000 0000 1 */
+    { 10, 0x1, G3CODE_INVALID },	/* 0000 0000 01 */
+    { 11, 0x1, G3CODE_INVALID },	/* 0000 0000 001 */
+    { 12, 0x0, G3CODE_INVALID },	/* 0000 0000 0000 */
+};
+#else
+extern const tableentry TIFFFaxWhiteCodes[];
+extern const tableentry TIFFFaxBlackCodes[];
+#endif
+#endif /* _T4_ */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tif_aux.c b/Source/LibTIFF4/tif_aux.c
index c80efff..479fe48 100644
--- a/Source/LibTIFF4/tif_aux.c
+++ b/Source/LibTIFF4/tif_aux.c
@@ -1,358 +1,358 @@
-/* $Id: tif_aux.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * Copyright (c) 1991-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library.
- *
- * Auxiliary Support Routines.
- */
-#include "tiffiop.h"
-#include "tif_predict.h"
-#include <math.h>
-
-uint32
-_TIFFMultiply32(TIFF* tif, uint32 first, uint32 second, const char* where)
-{
-	uint32 bytes = first * second;
-
-	if (second && bytes / second != first) {
-		TIFFErrorExt(tif->tif_clientdata, where, "Integer overflow in %s", where);
-		bytes = 0;
-	}
-
-	return bytes;
-}
-
-uint64
-_TIFFMultiply64(TIFF* tif, uint64 first, uint64 second, const char* where)
-{
-	uint64 bytes = first * second;
-
-	if (second && bytes / second != first) {
-		TIFFErrorExt(tif->tif_clientdata, where, "Integer overflow in %s", where);
-		bytes = 0;
-	}
-
-	return bytes;
-}
-
-void*
-_TIFFCheckRealloc(TIFF* tif, void* buffer,
-		  tmsize_t nmemb, tmsize_t elem_size, const char* what)
-{
-	void* cp = NULL;
-	tmsize_t bytes = nmemb * elem_size;
-
-	/*
-	 * XXX: Check for integer overflow.
-	 */
-	if (nmemb && elem_size && bytes / elem_size == nmemb)
-		cp = _TIFFrealloc(buffer, bytes);
-
-	if (cp == NULL) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			     "Failed to allocate memory for %s "
-			     "(%ld elements of %ld bytes each)",
-			     what,(long) nmemb, (long) elem_size);
-	}
-
-	return cp;
-}
-
-void*
-_TIFFCheckMalloc(TIFF* tif, tmsize_t nmemb, tmsize_t elem_size, const char* what)
-{
-	return _TIFFCheckRealloc(tif, NULL, nmemb, elem_size, what);  
-}
-
-static int
-TIFFDefaultTransferFunction(TIFFDirectory* td)
-{
-	uint16 **tf = td->td_transferfunction;
-	tmsize_t i, n, nbytes;
-
-	tf[0] = tf[1] = tf[2] = 0;
-	if (td->td_bitspersample >= sizeof(tmsize_t) * 8 - 2)
-		return 0;
-
-	n = ((tmsize_t)1)<<td->td_bitspersample;
-	nbytes = n * sizeof (uint16);
-	if (!(tf[0] = (uint16 *)_TIFFmalloc(nbytes)))
-		return 0;
-	tf[0][0] = 0;
-	for (i = 1; i < n; i++) {
-		double t = (double)i/((double) n-1.);
-		tf[0][i] = (uint16)floor(65535.*pow(t, 2.2) + .5);
-	}
-
-	if (td->td_samplesperpixel - td->td_extrasamples > 1) {
-		if (!(tf[1] = (uint16 *)_TIFFmalloc(nbytes)))
-			goto bad;
-		_TIFFmemcpy(tf[1], tf[0], nbytes);
-		if (!(tf[2] = (uint16 *)_TIFFmalloc(nbytes)))
-			goto bad;
-		_TIFFmemcpy(tf[2], tf[0], nbytes);
-	}
-	return 1;
-
-bad:
-	if (tf[0])
-		_TIFFfree(tf[0]);
-	if (tf[1])
-		_TIFFfree(tf[1]);
-	if (tf[2])
-		_TIFFfree(tf[2]);
-	tf[0] = tf[1] = tf[2] = 0;
-	return 0;
-}
-
-static int
-TIFFDefaultRefBlackWhite(TIFFDirectory* td)
-{
-	int i;
-
-	if (!(td->td_refblackwhite = (float *)_TIFFmalloc(6*sizeof (float))))
-		return 0;
-        if (td->td_photometric == PHOTOMETRIC_YCBCR) {
-		/*
-		 * YCbCr (Class Y) images must have the ReferenceBlackWhite
-		 * tag set. Fix the broken images, which lacks that tag.
-		 */
-		td->td_refblackwhite[0] = 0.0F;
-		td->td_refblackwhite[1] = td->td_refblackwhite[3] =
-			td->td_refblackwhite[5] = 255.0F;
-		td->td_refblackwhite[2] = td->td_refblackwhite[4] = 128.0F;
-	} else {
-		/*
-		 * Assume RGB (Class R)
-		 */
-		for (i = 0; i < 3; i++) {
-		    td->td_refblackwhite[2*i+0] = 0;
-		    td->td_refblackwhite[2*i+1] =
-			    (float)((1L<<td->td_bitspersample)-1L);
-		}
-	}
-	return 1;
-}
-
-/*
- * Like TIFFGetField, but return any default
- * value if the tag is not present in the directory.
- *
- * NB:	We use the value in the directory, rather than
- *	explcit values so that defaults exist only one
- *	place in the library -- in TIFFDefaultDirectory.
- */
-int
-TIFFVGetFieldDefaulted(TIFF* tif, uint32 tag, va_list ap)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-
-	if (TIFFVGetField(tif, tag, ap))
-		return (1);
-	switch (tag) {
-	case TIFFTAG_SUBFILETYPE:
-		*va_arg(ap, uint32 *) = td->td_subfiletype;
-		return (1);
-	case TIFFTAG_BITSPERSAMPLE:
-		*va_arg(ap, uint16 *) = td->td_bitspersample;
-		return (1);
-	case TIFFTAG_THRESHHOLDING:
-		*va_arg(ap, uint16 *) = td->td_threshholding;
-		return (1);
-	case TIFFTAG_FILLORDER:
-		*va_arg(ap, uint16 *) = td->td_fillorder;
-		return (1);
-	case TIFFTAG_ORIENTATION:
-		*va_arg(ap, uint16 *) = td->td_orientation;
-		return (1);
-	case TIFFTAG_SAMPLESPERPIXEL:
-		*va_arg(ap, uint16 *) = td->td_samplesperpixel;
-		return (1);
-	case TIFFTAG_ROWSPERSTRIP:
-		*va_arg(ap, uint32 *) = td->td_rowsperstrip;
-		return (1);
-	case TIFFTAG_MINSAMPLEVALUE:
-		*va_arg(ap, uint16 *) = td->td_minsamplevalue;
-		return (1);
-	case TIFFTAG_MAXSAMPLEVALUE:
-		*va_arg(ap, uint16 *) = td->td_maxsamplevalue;
-		return (1);
-	case TIFFTAG_PLANARCONFIG:
-		*va_arg(ap, uint16 *) = td->td_planarconfig;
-		return (1);
-	case TIFFTAG_RESOLUTIONUNIT:
-		*va_arg(ap, uint16 *) = td->td_resolutionunit;
-		return (1);
-	case TIFFTAG_PREDICTOR:
-                {
-			TIFFPredictorState* sp = (TIFFPredictorState*) tif->tif_data;
-			*va_arg(ap, uint16*) = (uint16) sp->predictor;
-			return 1;
-                }
-	case TIFFTAG_DOTRANGE:
-		*va_arg(ap, uint16 *) = 0;
-		*va_arg(ap, uint16 *) = (1<<td->td_bitspersample)-1;
-		return (1);
-	case TIFFTAG_INKSET:
-		*va_arg(ap, uint16 *) = INKSET_CMYK;
-		return 1;
-	case TIFFTAG_NUMBEROFINKS:
-		*va_arg(ap, uint16 *) = 4;
-		return (1);
-	case TIFFTAG_EXTRASAMPLES:
-		*va_arg(ap, uint16 *) = td->td_extrasamples;
-		*va_arg(ap, uint16 **) = td->td_sampleinfo;
-		return (1);
-	case TIFFTAG_MATTEING:
-		*va_arg(ap, uint16 *) =
-		    (td->td_extrasamples == 1 &&
-		     td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
-		return (1);
-	case TIFFTAG_TILEDEPTH:
-		*va_arg(ap, uint32 *) = td->td_tiledepth;
-		return (1);
-	case TIFFTAG_DATATYPE:
-		*va_arg(ap, uint16 *) = td->td_sampleformat-1;
-		return (1);
-	case TIFFTAG_SAMPLEFORMAT:
-		*va_arg(ap, uint16 *) = td->td_sampleformat;
-                return(1);
-	case TIFFTAG_IMAGEDEPTH:
-		*va_arg(ap, uint32 *) = td->td_imagedepth;
-		return (1);
-	case TIFFTAG_YCBCRCOEFFICIENTS:
-		{
-			/* defaults are from CCIR Recommendation 601-1 */
-			static float ycbcrcoeffs[] = { 0.299f, 0.587f, 0.114f };
-			*va_arg(ap, float **) = ycbcrcoeffs;
-			return 1;
-		}
-	case TIFFTAG_YCBCRSUBSAMPLING:
-		*va_arg(ap, uint16 *) = td->td_ycbcrsubsampling[0];
-		*va_arg(ap, uint16 *) = td->td_ycbcrsubsampling[1];
-		return (1);
-	case TIFFTAG_YCBCRPOSITIONING:
-		*va_arg(ap, uint16 *) = td->td_ycbcrpositioning;
-		return (1);
-	case TIFFTAG_WHITEPOINT:
-		{
-			static float whitepoint[2];
-
-			/* TIFF 6.0 specification tells that it is no default
-			   value for the WhitePoint, but AdobePhotoshop TIFF
-			   Technical Note tells that it should be CIE D50. */
-			whitepoint[0] =	D50_X0 / (D50_X0 + D50_Y0 + D50_Z0);
-			whitepoint[1] =	D50_Y0 / (D50_X0 + D50_Y0 + D50_Z0);
-			*va_arg(ap, float **) = whitepoint;
-			return 1;
-		}
-	case TIFFTAG_TRANSFERFUNCTION:
-		if (!td->td_transferfunction[0] &&
-		    !TIFFDefaultTransferFunction(td)) {
-			TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "No space for \"TransferFunction\" tag");
-			return (0);
-		}
-		*va_arg(ap, uint16 **) = td->td_transferfunction[0];
-		if (td->td_samplesperpixel - td->td_extrasamples > 1) {
-			*va_arg(ap, uint16 **) = td->td_transferfunction[1];
-			*va_arg(ap, uint16 **) = td->td_transferfunction[2];
-		}
-		return (1);
-	case TIFFTAG_REFERENCEBLACKWHITE:
-		if (!td->td_refblackwhite && !TIFFDefaultRefBlackWhite(td))
-			return (0);
-		*va_arg(ap, float **) = td->td_refblackwhite;
-		return (1);
-	}
-	return 0;
-}
-
-/*
- * Like TIFFGetField, but return any default
- * value if the tag is not present in the directory.
- */
-int
-TIFFGetFieldDefaulted(TIFF* tif, uint32 tag, ...)
-{
-	int ok;
-	va_list ap;
-
-	va_start(ap, tag);
-	ok =  TIFFVGetFieldDefaulted(tif, tag, ap);
-	va_end(ap);
-	return (ok);
-}
-
-struct _Int64Parts {
-	int32 low, high;
-};
-
-typedef union {
-	struct _Int64Parts part;
-	int64 value;
-} _Int64;
-
-float
-_TIFFUInt64ToFloat(uint64 ui64)
-{
-	_Int64 i;
-
-	i.value = ui64;
-	if (i.part.high >= 0) {
-		return (float)i.value;
-	} else {
-		long double df;
-		df = (long double)i.value;
-		df += 18446744073709551616.0; /* adding 2**64 */
-		return (float)df;
-	}
-}
-
-double
-_TIFFUInt64ToDouble(uint64 ui64)
-{
-	_Int64 i;
-
-	i.value = ui64;
-	if (i.part.high >= 0) {
-		return (double)i.value;
-	} else {
-		long double df;
-		df = (long double)i.value;
-		df += 18446744073709551616.0; /* adding 2**64 */
-		return (double)df;
-	}
-}
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Id: tif_aux.c,v 1.11 2015/02/19 22:39:58 drolon Exp $ */
+
+/*
+ * Copyright (c) 1991-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and 
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
+ * 
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Auxiliary Support Routines.
+ */
+#include "tiffiop.h"
+#include "tif_predict.h"
+#include <math.h>
+
+uint32
+_TIFFMultiply32(TIFF* tif, uint32 first, uint32 second, const char* where)
+{
+	uint32 bytes = first * second;
+
+	if (second && bytes / second != first) {
+		TIFFErrorExt(tif->tif_clientdata, where, "Integer overflow in %s", where);
+		bytes = 0;
+	}
+
+	return bytes;
+}
+
+uint64
+_TIFFMultiply64(TIFF* tif, uint64 first, uint64 second, const char* where)
+{
+	uint64 bytes = first * second;
+
+	if (second && bytes / second != first) {
+		TIFFErrorExt(tif->tif_clientdata, where, "Integer overflow in %s", where);
+		bytes = 0;
+	}
+
+	return bytes;
+}
+
+void*
+_TIFFCheckRealloc(TIFF* tif, void* buffer,
+		  tmsize_t nmemb, tmsize_t elem_size, const char* what)
+{
+	void* cp = NULL;
+	tmsize_t bytes = nmemb * elem_size;
+
+	/*
+	 * XXX: Check for integer overflow.
+	 */
+	if (nmemb && elem_size && bytes / elem_size == nmemb)
+		cp = _TIFFrealloc(buffer, bytes);
+
+	if (cp == NULL) {
+		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+			     "Failed to allocate memory for %s "
+			     "(%ld elements of %ld bytes each)",
+			     what,(long) nmemb, (long) elem_size);
+	}
+
+	return cp;
+}
+
+void*
+_TIFFCheckMalloc(TIFF* tif, tmsize_t nmemb, tmsize_t elem_size, const char* what)
+{
+	return _TIFFCheckRealloc(tif, NULL, nmemb, elem_size, what);  
+}
+
+static int
+TIFFDefaultTransferFunction(TIFFDirectory* td)
+{
+	uint16 **tf = td->td_transferfunction;
+	tmsize_t i, n, nbytes;
+
+	tf[0] = tf[1] = tf[2] = 0;
+	if (td->td_bitspersample >= sizeof(tmsize_t) * 8 - 2)
+		return 0;
+
+	n = ((tmsize_t)1)<<td->td_bitspersample;
+	nbytes = n * sizeof (uint16);
+	if (!(tf[0] = (uint16 *)_TIFFmalloc(nbytes)))
+		return 0;
+	tf[0][0] = 0;
+	for (i = 1; i < n; i++) {
+		double t = (double)i/((double) n-1.);
+		tf[0][i] = (uint16)floor(65535.*pow(t, 2.2) + .5);
+	}
+
+	if (td->td_samplesperpixel - td->td_extrasamples > 1) {
+		if (!(tf[1] = (uint16 *)_TIFFmalloc(nbytes)))
+			goto bad;
+		_TIFFmemcpy(tf[1], tf[0], nbytes);
+		if (!(tf[2] = (uint16 *)_TIFFmalloc(nbytes)))
+			goto bad;
+		_TIFFmemcpy(tf[2], tf[0], nbytes);
+	}
+	return 1;
+
+bad:
+	if (tf[0])
+		_TIFFfree(tf[0]);
+	if (tf[1])
+		_TIFFfree(tf[1]);
+	if (tf[2])
+		_TIFFfree(tf[2]);
+	tf[0] = tf[1] = tf[2] = 0;
+	return 0;
+}
+
+static int
+TIFFDefaultRefBlackWhite(TIFFDirectory* td)
+{
+	int i;
+
+	if (!(td->td_refblackwhite = (float *)_TIFFmalloc(6*sizeof (float))))
+		return 0;
+        if (td->td_photometric == PHOTOMETRIC_YCBCR) {
+		/*
+		 * YCbCr (Class Y) images must have the ReferenceBlackWhite
+		 * tag set. Fix the broken images, which lacks that tag.
+		 */
+		td->td_refblackwhite[0] = 0.0F;
+		td->td_refblackwhite[1] = td->td_refblackwhite[3] =
+			td->td_refblackwhite[5] = 255.0F;
+		td->td_refblackwhite[2] = td->td_refblackwhite[4] = 128.0F;
+	} else {
+		/*
+		 * Assume RGB (Class R)
+		 */
+		for (i = 0; i < 3; i++) {
+		    td->td_refblackwhite[2*i+0] = 0;
+		    td->td_refblackwhite[2*i+1] =
+			    (float)((1L<<td->td_bitspersample)-1L);
+		}
+	}
+	return 1;
+}
+
+/*
+ * Like TIFFGetField, but return any default
+ * value if the tag is not present in the directory.
+ *
+ * NB:	We use the value in the directory, rather than
+ *	explcit values so that defaults exist only one
+ *	place in the library -- in TIFFDefaultDirectory.
+ */
+int
+TIFFVGetFieldDefaulted(TIFF* tif, uint32 tag, va_list ap)
+{
+	TIFFDirectory *td = &tif->tif_dir;
+
+	if (TIFFVGetField(tif, tag, ap))
+		return (1);
+	switch (tag) {
+	case TIFFTAG_SUBFILETYPE:
+		*va_arg(ap, uint32 *) = td->td_subfiletype;
+		return (1);
+	case TIFFTAG_BITSPERSAMPLE:
+		*va_arg(ap, uint16 *) = td->td_bitspersample;
+		return (1);
+	case TIFFTAG_THRESHHOLDING:
+		*va_arg(ap, uint16 *) = td->td_threshholding;
+		return (1);
+	case TIFFTAG_FILLORDER:
+		*va_arg(ap, uint16 *) = td->td_fillorder;
+		return (1);
+	case TIFFTAG_ORIENTATION:
+		*va_arg(ap, uint16 *) = td->td_orientation;
+		return (1);
+	case TIFFTAG_SAMPLESPERPIXEL:
+		*va_arg(ap, uint16 *) = td->td_samplesperpixel;
+		return (1);
+	case TIFFTAG_ROWSPERSTRIP:
+		*va_arg(ap, uint32 *) = td->td_rowsperstrip;
+		return (1);
+	case TIFFTAG_MINSAMPLEVALUE:
+		*va_arg(ap, uint16 *) = td->td_minsamplevalue;
+		return (1);
+	case TIFFTAG_MAXSAMPLEVALUE:
+		*va_arg(ap, uint16 *) = td->td_maxsamplevalue;
+		return (1);
+	case TIFFTAG_PLANARCONFIG:
+		*va_arg(ap, uint16 *) = td->td_planarconfig;
+		return (1);
+	case TIFFTAG_RESOLUTIONUNIT:
+		*va_arg(ap, uint16 *) = td->td_resolutionunit;
+		return (1);
+	case TIFFTAG_PREDICTOR:
+                {
+			TIFFPredictorState* sp = (TIFFPredictorState*) tif->tif_data;
+			*va_arg(ap, uint16*) = (uint16) sp->predictor;
+			return 1;
+                }
+	case TIFFTAG_DOTRANGE:
+		*va_arg(ap, uint16 *) = 0;
+		*va_arg(ap, uint16 *) = (1<<td->td_bitspersample)-1;
+		return (1);
+	case TIFFTAG_INKSET:
+		*va_arg(ap, uint16 *) = INKSET_CMYK;
+		return 1;
+	case TIFFTAG_NUMBEROFINKS:
+		*va_arg(ap, uint16 *) = 4;
+		return (1);
+	case TIFFTAG_EXTRASAMPLES:
+		*va_arg(ap, uint16 *) = td->td_extrasamples;
+		*va_arg(ap, uint16 **) = td->td_sampleinfo;
+		return (1);
+	case TIFFTAG_MATTEING:
+		*va_arg(ap, uint16 *) =
+		    (td->td_extrasamples == 1 &&
+		     td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
+		return (1);
+	case TIFFTAG_TILEDEPTH:
+		*va_arg(ap, uint32 *) = td->td_tiledepth;
+		return (1);
+	case TIFFTAG_DATATYPE:
+		*va_arg(ap, uint16 *) = td->td_sampleformat-1;
+		return (1);
+	case TIFFTAG_SAMPLEFORMAT:
+		*va_arg(ap, uint16 *) = td->td_sampleformat;
+                return(1);
+	case TIFFTAG_IMAGEDEPTH:
+		*va_arg(ap, uint32 *) = td->td_imagedepth;
+		return (1);
+	case TIFFTAG_YCBCRCOEFFICIENTS:
+		{
+			/* defaults are from CCIR Recommendation 601-1 */
+			static float ycbcrcoeffs[] = { 0.299f, 0.587f, 0.114f };
+			*va_arg(ap, float **) = ycbcrcoeffs;
+			return 1;
+		}
+	case TIFFTAG_YCBCRSUBSAMPLING:
+		*va_arg(ap, uint16 *) = td->td_ycbcrsubsampling[0];
+		*va_arg(ap, uint16 *) = td->td_ycbcrsubsampling[1];
+		return (1);
+	case TIFFTAG_YCBCRPOSITIONING:
+		*va_arg(ap, uint16 *) = td->td_ycbcrpositioning;
+		return (1);
+	case TIFFTAG_WHITEPOINT:
+		{
+			static float whitepoint[2];
+
+			/* TIFF 6.0 specification tells that it is no default
+			   value for the WhitePoint, but AdobePhotoshop TIFF
+			   Technical Note tells that it should be CIE D50. */
+			whitepoint[0] =	D50_X0 / (D50_X0 + D50_Y0 + D50_Z0);
+			whitepoint[1] =	D50_Y0 / (D50_X0 + D50_Y0 + D50_Z0);
+			*va_arg(ap, float **) = whitepoint;
+			return 1;
+		}
+	case TIFFTAG_TRANSFERFUNCTION:
+		if (!td->td_transferfunction[0] &&
+		    !TIFFDefaultTransferFunction(td)) {
+			TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "No space for \"TransferFunction\" tag");
+			return (0);
+		}
+		*va_arg(ap, uint16 **) = td->td_transferfunction[0];
+		if (td->td_samplesperpixel - td->td_extrasamples > 1) {
+			*va_arg(ap, uint16 **) = td->td_transferfunction[1];
+			*va_arg(ap, uint16 **) = td->td_transferfunction[2];
+		}
+		return (1);
+	case TIFFTAG_REFERENCEBLACKWHITE:
+		if (!td->td_refblackwhite && !TIFFDefaultRefBlackWhite(td))
+			return (0);
+		*va_arg(ap, float **) = td->td_refblackwhite;
+		return (1);
+	}
+	return 0;
+}
+
+/*
+ * Like TIFFGetField, but return any default
+ * value if the tag is not present in the directory.
+ */
+int
+TIFFGetFieldDefaulted(TIFF* tif, uint32 tag, ...)
+{
+	int ok;
+	va_list ap;
+
+	va_start(ap, tag);
+	ok =  TIFFVGetFieldDefaulted(tif, tag, ap);
+	va_end(ap);
+	return (ok);
+}
+
+struct _Int64Parts {
+	int32 low, high;
+};
+
+typedef union {
+	struct _Int64Parts part;
+	int64 value;
+} _Int64;
+
+float
+_TIFFUInt64ToFloat(uint64 ui64)
+{
+	_Int64 i;
+
+	i.value = ui64;
+	if (i.part.high >= 0) {
+		return (float)i.value;
+	} else {
+		long double df;
+		df = (long double)i.value;
+		df += 18446744073709551616.0; /* adding 2**64 */
+		return (float)df;
+	}
+}
+
+double
+_TIFFUInt64ToDouble(uint64 ui64)
+{
+	_Int64 i;
+
+	i.value = ui64;
+	if (i.part.high >= 0) {
+		return (double)i.value;
+	} else {
+		long double df;
+		df = (long double)i.value;
+		df += 18446744073709551616.0; /* adding 2**64 */
+		return (double)df;
+	}
+}
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tif_close.c b/Source/LibTIFF4/tif_close.c
index fb67a96..032466c 100644
--- a/Source/LibTIFF4/tif_close.c
+++ b/Source/LibTIFF4/tif_close.c
@@ -1,140 +1,140 @@
-/* $Id: tif_close.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library.
- */
-#include "tiffiop.h"
-#include <string.h>
-
-/************************************************************************/
-/*                            TIFFCleanup()                             */
-/************************************************************************/
-
-/**
- * Auxiliary function to free the TIFF structure. Given structure will be
- * completetly freed, so you should save opened file handle and pointer
- * to the close procedure in external variables before calling
- * _TIFFCleanup(), if you will need these ones to close the file.
- * 
- * @param tif A TIFF pointer.
- */
-
-void
-TIFFCleanup(TIFF* tif)
-{
-	/*
-         * Flush buffered data and directory (if dirty).
-         */
-	if (tif->tif_mode != O_RDONLY)
-		TIFFFlush(tif);
-	(*tif->tif_cleanup)(tif);
-	TIFFFreeDirectory(tif);
-
-	if (tif->tif_dirlist)
-		_TIFFfree(tif->tif_dirlist);
-
-	/*
-         * Clean up client info links.
-         */
-	while( tif->tif_clientinfo )
-	{
-		TIFFClientInfoLink *link = tif->tif_clientinfo;
-
-		tif->tif_clientinfo = link->next;
-		_TIFFfree( link->name );
-		_TIFFfree( link );
-	}
-
-	if (tif->tif_rawdata && (tif->tif_flags&TIFF_MYBUFFER))
-		_TIFFfree(tif->tif_rawdata);
-	if (isMapped(tif))
-		TIFFUnmapFileContents(tif, tif->tif_base, (toff_t)tif->tif_size);
-
-	/*
-         * Clean up custom fields.
-         */
-	if (tif->tif_fields && tif->tif_nfields > 0) {
-		uint32 i;
-
-		for (i = 0; i < tif->tif_nfields; i++) {
-			TIFFField *fld = tif->tif_fields[i];
-			if (fld->field_bit == FIELD_CUSTOM &&
-			    strncmp("Tag ", fld->field_name, 4) == 0) {
-				_TIFFfree(fld->field_name);
-				_TIFFfree(fld);
-			}
-		}
-
-		_TIFFfree(tif->tif_fields);
-	}
-
-        if (tif->tif_nfieldscompat > 0) {
-                uint32 i;
-
-                for (i = 0; i < tif->tif_nfieldscompat; i++) {
-                        if (tif->tif_fieldscompat[i].allocated_size)
-                                _TIFFfree(tif->tif_fieldscompat[i].fields);
-                }
-                _TIFFfree(tif->tif_fieldscompat);
-        }
-
-	_TIFFfree(tif);
-}
-
-/************************************************************************/
-/*                            TIFFClose()                               */
-/************************************************************************/
-
-/**
- * Close a previously opened TIFF file.
- *
- * TIFFClose closes a file that was previously opened with TIFFOpen().
- * Any buffered data are flushed to the file, including the contents of
- * the current directory (if modified); and all resources are reclaimed.
- * 
- * @param tif A TIFF pointer.
- */
-
-void
-TIFFClose(TIFF* tif)
-{
-	TIFFCloseProc closeproc = tif->tif_closeproc;
-	thandle_t fd = tif->tif_clientdata;
-
-	TIFFCleanup(tif);
-	(void) (*closeproc)(fd);
-}
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Id: tif_close.c,v 1.11 2015/02/19 22:39:58 drolon Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and 
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
+ * 
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ */
+#include "tiffiop.h"
+#include <string.h>
+
+/************************************************************************/
+/*                            TIFFCleanup()                             */
+/************************************************************************/
+
+/**
+ * Auxiliary function to free the TIFF structure. Given structure will be
+ * completetly freed, so you should save opened file handle and pointer
+ * to the close procedure in external variables before calling
+ * _TIFFCleanup(), if you will need these ones to close the file.
+ * 
+ * @param tif A TIFF pointer.
+ */
+
+void
+TIFFCleanup(TIFF* tif)
+{
+	/*
+         * Flush buffered data and directory (if dirty).
+         */
+	if (tif->tif_mode != O_RDONLY)
+		TIFFFlush(tif);
+	(*tif->tif_cleanup)(tif);
+	TIFFFreeDirectory(tif);
+
+	if (tif->tif_dirlist)
+		_TIFFfree(tif->tif_dirlist);
+
+	/*
+         * Clean up client info links.
+         */
+	while( tif->tif_clientinfo )
+	{
+		TIFFClientInfoLink *link = tif->tif_clientinfo;
+
+		tif->tif_clientinfo = link->next;
+		_TIFFfree( link->name );
+		_TIFFfree( link );
+	}
+
+	if (tif->tif_rawdata && (tif->tif_flags&TIFF_MYBUFFER))
+		_TIFFfree(tif->tif_rawdata);
+	if (isMapped(tif))
+		TIFFUnmapFileContents(tif, tif->tif_base, (toff_t)tif->tif_size);
+
+	/*
+         * Clean up custom fields.
+         */
+	if (tif->tif_fields && tif->tif_nfields > 0) {
+		uint32 i;
+
+		for (i = 0; i < tif->tif_nfields; i++) {
+			TIFFField *fld = tif->tif_fields[i];
+			if (fld->field_bit == FIELD_CUSTOM &&
+			    strncmp("Tag ", fld->field_name, 4) == 0) {
+				_TIFFfree(fld->field_name);
+				_TIFFfree(fld);
+			}
+		}
+
+		_TIFFfree(tif->tif_fields);
+	}
+
+        if (tif->tif_nfieldscompat > 0) {
+                uint32 i;
+
+                for (i = 0; i < tif->tif_nfieldscompat; i++) {
+                        if (tif->tif_fieldscompat[i].allocated_size)
+                                _TIFFfree(tif->tif_fieldscompat[i].fields);
+                }
+                _TIFFfree(tif->tif_fieldscompat);
+        }
+
+	_TIFFfree(tif);
+}
+
+/************************************************************************/
+/*                            TIFFClose()                               */
+/************************************************************************/
+
+/**
+ * Close a previously opened TIFF file.
+ *
+ * TIFFClose closes a file that was previously opened with TIFFOpen().
+ * Any buffered data are flushed to the file, including the contents of
+ * the current directory (if modified); and all resources are reclaimed.
+ * 
+ * @param tif A TIFF pointer.
+ */
+
+void
+TIFFClose(TIFF* tif)
+{
+	TIFFCloseProc closeproc = tif->tif_closeproc;
+	thandle_t fd = tif->tif_clientdata;
+
+	TIFFCleanup(tif);
+	(void) (*closeproc)(fd);
+}
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tif_codec.c b/Source/LibTIFF4/tif_codec.c
index ee360a8..3f93744 100644
--- a/Source/LibTIFF4/tif_codec.c
+++ b/Source/LibTIFF4/tif_codec.c
@@ -1,165 +1,166 @@
-/* $Id: tif_codec.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library
- *
- * Builtin Compression Scheme Configuration Support.
- */
-#include "tiffiop.h"
-
-static int NotConfigured(TIFF*, int);
-
-#ifndef LZW_SUPPORT
-#define TIFFInitLZW NotConfigured
-#endif
-#ifndef PACKBITS_SUPPORT
-#define TIFFInitPackBits NotConfigured
-#endif
-#ifndef THUNDER_SUPPORT
-#define TIFFInitThunderScan NotConfigured
-#endif
-#ifndef NEXT_SUPPORT
-#define TIFFInitNeXT NotConfigured
-#endif
-#ifndef JPEG_SUPPORT
-#define TIFFInitJPEG NotConfigured
-#endif
-#ifndef OJPEG_SUPPORT
-#define TIFFInitOJPEG NotConfigured
-#endif
-#ifndef CCITT_SUPPORT
-#define TIFFInitCCITTRLE NotConfigured
-#define TIFFInitCCITTRLEW NotConfigured
-#define TIFFInitCCITTFax3 NotConfigured
-#define TIFFInitCCITTFax4 NotConfigured
-#endif
-#ifndef JBIG_SUPPORT
-#define TIFFInitJBIG NotConfigured
-#endif
-#ifndef ZIP_SUPPORT
-#define TIFFInitZIP NotConfigured
-#endif
-#ifndef PIXARLOG_SUPPORT
-#define TIFFInitPixarLog NotConfigured
-#endif
-#ifndef LOGLUV_SUPPORT
-#define TIFFInitSGILog NotConfigured
-#endif
-#ifndef LZMA_SUPPORT
-#define TIFFInitLZMA NotConfigured
-#endif
-
-/*
- * Compression schemes statically built into the library.
- */
-#ifdef VMS
-const TIFFCodec _TIFFBuiltinCODECS[] = {
-#else
-TIFFCodec _TIFFBuiltinCODECS[] = {
-#endif
-    { "None",		COMPRESSION_NONE,	TIFFInitDumpMode },
-    { "LZW",		COMPRESSION_LZW,	TIFFInitLZW },
-    { "PackBits",	COMPRESSION_PACKBITS,	TIFFInitPackBits },
-    { "ThunderScan",	COMPRESSION_THUNDERSCAN,TIFFInitThunderScan },
-    { "NeXT",		COMPRESSION_NEXT,	TIFFInitNeXT },
-    { "JPEG",		COMPRESSION_JPEG,	TIFFInitJPEG },
-    { "Old-style JPEG",	COMPRESSION_OJPEG,	TIFFInitOJPEG },
-    { "CCITT RLE",	COMPRESSION_CCITTRLE,	TIFFInitCCITTRLE },
-    { "CCITT RLE/W",	COMPRESSION_CCITTRLEW,	TIFFInitCCITTRLEW },
-    { "CCITT Group 3",	COMPRESSION_CCITTFAX3,	TIFFInitCCITTFax3 },
-    { "CCITT Group 4",	COMPRESSION_CCITTFAX4,	TIFFInitCCITTFax4 },
-    { "ISO JBIG",	COMPRESSION_JBIG,	TIFFInitJBIG },
-    { "Deflate",	COMPRESSION_DEFLATE,	TIFFInitZIP },
-    { "AdobeDeflate",   COMPRESSION_ADOBE_DEFLATE , TIFFInitZIP }, 
-    { "PixarLog",	COMPRESSION_PIXARLOG,	TIFFInitPixarLog },
-    { "SGILog",		COMPRESSION_SGILOG,	TIFFInitSGILog },
-    { "SGILog24",	COMPRESSION_SGILOG24,	TIFFInitSGILog },
-    { "LZMA",		COMPRESSION_LZMA,	TIFFInitLZMA },
-    { NULL,             0,                      NULL }
-};
-
-static int
-_notConfigured(TIFF* tif)
-{
-	const TIFFCodec* c = TIFFFindCODEC(tif->tif_dir.td_compression);
-        char compression_code[20];
-        
-        sprintf( compression_code, "%d", tif->tif_dir.td_compression );
-	TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-                     "%s compression support is not configured", 
-                     c ? c->name : compression_code );
-	return (0);
-}
-
-static int
-NotConfigured(TIFF* tif, int scheme)
-{
-	(void) scheme;
-
-	tif->tif_fixuptags = _notConfigured;
-	tif->tif_decodestatus = FALSE;
-	tif->tif_setupdecode = _notConfigured;
-	tif->tif_encodestatus = FALSE;
-	tif->tif_setupencode = _notConfigured;
-	return (1);
-}
-
-/************************************************************************/
-/*                       TIFFIsCODECConfigured()                        */
-/************************************************************************/
-
-/**
- * Check whether we have working codec for the specific coding scheme.
- *
- * @return returns 1 if the codec is configured and working. Otherwise
- * 0 will be returned.
- */
-
-int
-TIFFIsCODECConfigured(uint16 scheme)
-{
-	const TIFFCodec* codec = TIFFFindCODEC(scheme);
-
-	if(codec == NULL) {
-		return 0;
-	}
-	if(codec->init == NULL) {
-		return 0;
-	}
-	if(codec->init != NotConfigured){
-		return 1;
-	}
-	return 0;
-}
-
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Id: tif_codec.c,v 1.11 2015/02/19 22:39:58 drolon Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and 
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
+ * 
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library
+ *
+ * Builtin Compression Scheme Configuration Support.
+ */
+#include "tiffiop.h"
+
+static int NotConfigured(TIFF*, int);
+
+#ifndef LZW_SUPPORT
+#define TIFFInitLZW NotConfigured
+#endif
+#ifndef PACKBITS_SUPPORT
+#define TIFFInitPackBits NotConfigured
+#endif
+#ifndef THUNDER_SUPPORT
+#define TIFFInitThunderScan NotConfigured
+#endif
+#ifndef NEXT_SUPPORT
+#define TIFFInitNeXT NotConfigured
+#endif
+#ifndef JPEG_SUPPORT
+#define TIFFInitJPEG NotConfigured
+#endif
+#ifndef OJPEG_SUPPORT
+#define TIFFInitOJPEG NotConfigured
+#endif
+#ifndef CCITT_SUPPORT
+#define TIFFInitCCITTRLE NotConfigured
+#define TIFFInitCCITTRLEW NotConfigured
+#define TIFFInitCCITTFax3 NotConfigured
+#define TIFFInitCCITTFax4 NotConfigured
+#endif
+#ifndef JBIG_SUPPORT
+#define TIFFInitJBIG NotConfigured
+#endif
+#ifndef ZIP_SUPPORT
+#define TIFFInitZIP NotConfigured
+#endif
+#ifndef PIXARLOG_SUPPORT
+#define TIFFInitPixarLog NotConfigured
+#endif
+#ifndef LOGLUV_SUPPORT
+#define TIFFInitSGILog NotConfigured
+#endif
+#ifndef LZMA_SUPPORT
+#define TIFFInitLZMA NotConfigured
+#endif
+
+/*
+ * Compression schemes statically built into the library.
+ */
+#ifdef VMS
+const TIFFCodec _TIFFBuiltinCODECS[] = {
+#else
+TIFFCodec _TIFFBuiltinCODECS[] = {
+#endif
+    { "None",		COMPRESSION_NONE,	TIFFInitDumpMode },
+    { "LZW",		COMPRESSION_LZW,	TIFFInitLZW },
+    { "PackBits",	COMPRESSION_PACKBITS,	TIFFInitPackBits },
+    { "ThunderScan",	COMPRESSION_THUNDERSCAN,TIFFInitThunderScan },
+    { "NeXT",		COMPRESSION_NEXT,	TIFFInitNeXT },
+    { "JPEG",		COMPRESSION_JPEG,	TIFFInitJPEG },
+    { "Old-style JPEG",	COMPRESSION_OJPEG,	TIFFInitOJPEG },
+    { "CCITT RLE",	COMPRESSION_CCITTRLE,	TIFFInitCCITTRLE },
+    { "CCITT RLE/W",	COMPRESSION_CCITTRLEW,	TIFFInitCCITTRLEW },
+    { "CCITT Group 3",	COMPRESSION_CCITTFAX3,	TIFFInitCCITTFax3 },
+    { "CCITT Group 4",	COMPRESSION_CCITTFAX4,	TIFFInitCCITTFax4 },
+    { "ISO JBIG",	COMPRESSION_JBIG,	TIFFInitJBIG },
+    { "Deflate",	COMPRESSION_DEFLATE,	TIFFInitZIP },
+    { "AdobeDeflate",   COMPRESSION_ADOBE_DEFLATE , TIFFInitZIP }, 
+    { "PixarLog",	COMPRESSION_PIXARLOG,	TIFFInitPixarLog },
+    { "SGILog",		COMPRESSION_SGILOG,	TIFFInitSGILog },
+    { "SGILog24",	COMPRESSION_SGILOG24,	TIFFInitSGILog },
+    { "LZMA",		COMPRESSION_LZMA,	TIFFInitLZMA },
+    { NULL,             0,                      NULL }
+};
+
+static int
+_notConfigured(TIFF* tif)
+{
+	const TIFFCodec* c = TIFFFindCODEC(tif->tif_dir.td_compression);
+        char compression_code[20];
+        
+        snprintf(compression_code, sizeof(compression_code), "%d",
+		 tif->tif_dir.td_compression );
+	TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+                     "%s compression support is not configured", 
+                     c ? c->name : compression_code );
+	return (0);
+}
+
+static int
+NotConfigured(TIFF* tif, int scheme)
+{
+	(void) scheme;
+
+	tif->tif_fixuptags = _notConfigured;
+	tif->tif_decodestatus = FALSE;
+	tif->tif_setupdecode = _notConfigured;
+	tif->tif_encodestatus = FALSE;
+	tif->tif_setupencode = _notConfigured;
+	return (1);
+}
+
+/************************************************************************/
+/*                       TIFFIsCODECConfigured()                        */
+/************************************************************************/
+
+/**
+ * Check whether we have working codec for the specific coding scheme.
+ *
+ * @return returns 1 if the codec is configured and working. Otherwise
+ * 0 will be returned.
+ */
+
+int
+TIFFIsCODECConfigured(uint16 scheme)
+{
+	const TIFFCodec* codec = TIFFFindCODEC(scheme);
+
+	if(codec == NULL) {
+		return 0;
+	}
+	if(codec->init == NULL) {
+		return 0;
+	}
+	if(codec->init != NotConfigured){
+		return 1;
+	}
+	return 0;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tif_color.c b/Source/LibTIFF4/tif_color.c
index 93f6acd..b2ee11b 100644
--- a/Source/LibTIFF4/tif_color.c
+++ b/Source/LibTIFF4/tif_color.c
@@ -1,287 +1,287 @@
-/* $Id: tif_color.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * CIE L*a*b* to CIE XYZ and CIE XYZ to RGB conversion routines are taken
- * from the VIPS library (http://www.vips.ecs.soton.ac.uk) with
- * the permission of John Cupitt, the VIPS author.
- */
-
-/*
- * TIFF Library.
- *
- * Color space conversion routines.
- */
-
-#include "tiffiop.h"
-#include <math.h>
-
-/*
- * Convert color value from the CIE L*a*b* 1976 space to CIE XYZ.
- */
-void
-TIFFCIELabToXYZ(TIFFCIELabToRGB *cielab, uint32 l, int32 a, int32 b,
-		float *X, float *Y, float *Z)
-{
-	float L = (float)l * 100.0F / 255.0F;
-	float cby, tmp;
-
-	if( L < 8.856F ) {
-		*Y = (L * cielab->Y0) / 903.292F;
-		cby = 7.787F * (*Y / cielab->Y0) + 16.0F / 116.0F;
-	} else {
-		cby = (L + 16.0F) / 116.0F;
-		*Y = cielab->Y0 * cby * cby * cby;
-	}
-
-	tmp = (float)a / 500.0F + cby;
-	if( tmp < 0.2069F )
-		*X = cielab->X0 * (tmp - 0.13793F) / 7.787F;
-	else    
-		*X = cielab->X0 * tmp * tmp * tmp;
-
-	tmp = cby - (float)b / 200.0F;
-	if( tmp < 0.2069F )
-		*Z = cielab->Z0 * (tmp - 0.13793F) / 7.787F;
-	else    
-		*Z = cielab->Z0 * tmp * tmp * tmp;
-}
-
-#define RINT(R) ((uint32)((R)>0?((R)+0.5):((R)-0.5)))
-/*
- * Convert color value from the XYZ space to RGB.
- */
-void
-TIFFXYZToRGB(TIFFCIELabToRGB *cielab, float X, float Y, float Z,
-	     uint32 *r, uint32 *g, uint32 *b)
-{
-	int i;
-	float Yr, Yg, Yb;
-	float *matrix = &cielab->display.d_mat[0][0];
-
-	/* Multiply through the matrix to get luminosity values. */
-	Yr =  matrix[0] * X + matrix[1] * Y + matrix[2] * Z;
-	Yg =  matrix[3] * X + matrix[4] * Y + matrix[5] * Z;
-	Yb =  matrix[6] * X + matrix[7] * Y + matrix[8] * Z;
-
-	/* Clip input */
-	Yr = TIFFmax(Yr, cielab->display.d_Y0R);
-	Yg = TIFFmax(Yg, cielab->display.d_Y0G);
-	Yb = TIFFmax(Yb, cielab->display.d_Y0B);
-
-	/* Avoid overflow in case of wrong input values */
-	Yr = TIFFmin(Yr, cielab->display.d_YCR);
-	Yg = TIFFmin(Yg, cielab->display.d_YCG);
-	Yb = TIFFmin(Yb, cielab->display.d_YCB);
-
-	/* Turn luminosity to colour value. */
-	i = (int)((Yr - cielab->display.d_Y0R) / cielab->rstep);
-	i = TIFFmin(cielab->range, i);
-	*r = RINT(cielab->Yr2r[i]);
-
-	i = (int)((Yg - cielab->display.d_Y0G) / cielab->gstep);
-	i = TIFFmin(cielab->range, i);
-	*g = RINT(cielab->Yg2g[i]);
-
-	i = (int)((Yb - cielab->display.d_Y0B) / cielab->bstep);
-	i = TIFFmin(cielab->range, i);
-	*b = RINT(cielab->Yb2b[i]);
-
-	/* Clip output. */
-	*r = TIFFmin(*r, cielab->display.d_Vrwr);
-	*g = TIFFmin(*g, cielab->display.d_Vrwg);
-	*b = TIFFmin(*b, cielab->display.d_Vrwb);
-}
-#undef RINT
-
-/* 
- * Allocate conversion state structures and make look_up tables for
- * the Yr,Yb,Yg <=> r,g,b conversions.
- */
-int
-TIFFCIELabToRGBInit(TIFFCIELabToRGB* cielab,
-		    const TIFFDisplay *display, float *refWhite)
-{
-	int i;
-	double gamma;
-
-	cielab->range = CIELABTORGB_TABLE_RANGE;
-
-	_TIFFmemcpy(&cielab->display, display, sizeof(TIFFDisplay));
-
-	/* Red */
-	gamma = 1.0 / cielab->display.d_gammaR ;
-	cielab->rstep =
-		(cielab->display.d_YCR - cielab->display.d_Y0R)	/ cielab->range;
-	for(i = 0; i <= cielab->range; i++) {
-		cielab->Yr2r[i] = cielab->display.d_Vrwr
-		    * ((float)pow((double)i / cielab->range, gamma));
-	}
-
-	/* Green */
-	gamma = 1.0 / cielab->display.d_gammaG ;
-	cielab->gstep =
-	    (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
-	for(i = 0; i <= cielab->range; i++) {
-		cielab->Yg2g[i] = cielab->display.d_Vrwg
-		    * ((float)pow((double)i / cielab->range, gamma));
-	}
-
-	/* Blue */
-	gamma = 1.0 / cielab->display.d_gammaB ;
-	cielab->bstep =
-	    (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
-	for(i = 0; i <= cielab->range; i++) {
-		cielab->Yb2b[i] = cielab->display.d_Vrwb
-		    * ((float)pow((double)i / cielab->range, gamma));
-	}
-
-	/* Init reference white point */
-	cielab->X0 = refWhite[0];
-	cielab->Y0 = refWhite[1];
-	cielab->Z0 = refWhite[2];
-
-	return 0;
-}
-
-/* 
- * Convert color value from the YCbCr space to CIE XYZ.
- * The colorspace conversion algorithm comes from the IJG v5a code;
- * see below for more information on how it works.
- */
-#define	SHIFT			16
-#define	FIX(x)			((int32)((x) * (1L<<SHIFT) + 0.5))
-#define	ONE_HALF		((int32)(1<<(SHIFT-1)))
-#define	Code2V(c, RB, RW, CR)	((((c)-(int32)(RB))*(float)(CR))/(float)(((RW)-(RB)) ? ((RW)-(RB)) : 1))
-#define	CLAMP(f,min,max)	((f)<(min)?(min):(f)>(max)?(max):(f))
-#define HICLAMP(f,max)		((f)>(max)?(max):(f))
-
-void
-TIFFYCbCrtoRGB(TIFFYCbCrToRGB *ycbcr, uint32 Y, int32 Cb, int32 Cr,
-	       uint32 *r, uint32 *g, uint32 *b)
-{
-	int32 i;
-
-	/* XXX: Only 8-bit YCbCr input supported for now */
-	Y = HICLAMP(Y, 255), Cb = CLAMP(Cb, 0, 255), Cr = CLAMP(Cr, 0, 255);
-
-	i = ycbcr->Y_tab[Y] + ycbcr->Cr_r_tab[Cr];
-	*r = CLAMP(i, 0, 255);
-	i = ycbcr->Y_tab[Y]
-	    + (int)((ycbcr->Cb_g_tab[Cb] + ycbcr->Cr_g_tab[Cr]) >> SHIFT);
-	*g = CLAMP(i, 0, 255);
-	i = ycbcr->Y_tab[Y] + ycbcr->Cb_b_tab[Cb];
-	*b = CLAMP(i, 0, 255);
-}
-
-/*
- * Initialize the YCbCr->RGB conversion tables.  The conversion
- * is done according to the 6.0 spec:
- *
- *    R = Y + Cr*(2 - 2*LumaRed)
- *    B = Y + Cb*(2 - 2*LumaBlue)
- *    G =   Y
- *        - LumaBlue*Cb*(2-2*LumaBlue)/LumaGreen
- *        - LumaRed*Cr*(2-2*LumaRed)/LumaGreen
- *
- * To avoid floating point arithmetic the fractional constants that
- * come out of the equations are represented as fixed point values
- * in the range 0...2^16.  We also eliminate multiplications by
- * pre-calculating possible values indexed by Cb and Cr (this code
- * assumes conversion is being done for 8-bit samples).
- */
-int
-TIFFYCbCrToRGBInit(TIFFYCbCrToRGB* ycbcr, float *luma, float *refBlackWhite)
-{
-    TIFFRGBValue* clamptab;
-    int i;
-    
-#define LumaRed	    luma[0]
-#define LumaGreen   luma[1]
-#define LumaBlue    luma[2]
-
-    clamptab = (TIFFRGBValue*)(
-	(uint8*) ycbcr+TIFFroundup_32(sizeof (TIFFYCbCrToRGB), sizeof (long)));  
-    _TIFFmemset(clamptab, 0, 256);		/* v < 0 => 0 */
-    ycbcr->clamptab = (clamptab += 256);
-    for (i = 0; i < 256; i++)
-	clamptab[i] = (TIFFRGBValue) i;
-    _TIFFmemset(clamptab+256, 255, 2*256);	/* v > 255 => 255 */
-    ycbcr->Cr_r_tab = (int*) (clamptab + 3*256);
-    ycbcr->Cb_b_tab = ycbcr->Cr_r_tab + 256;
-    ycbcr->Cr_g_tab = (int32*) (ycbcr->Cb_b_tab + 256);
-    ycbcr->Cb_g_tab = ycbcr->Cr_g_tab + 256;
-    ycbcr->Y_tab = ycbcr->Cb_g_tab + 256;
-
-    { float f1 = 2-2*LumaRed;		int32 D1 = FIX(f1);
-      float f2 = LumaRed*f1/LumaGreen;	int32 D2 = -FIX(f2);
-      float f3 = 2-2*LumaBlue;		int32 D3 = FIX(f3);
-      float f4 = LumaBlue*f3/LumaGreen;	int32 D4 = -FIX(f4);
-      int x;
-
-#undef LumaBlue
-#undef LumaGreen
-#undef LumaRed
-      
-      /*
-       * i is the actual input pixel value in the range 0..255
-       * Cb and Cr values are in the range -128..127 (actually
-       * they are in a range defined by the ReferenceBlackWhite
-       * tag) so there is some range shifting to do here when
-       * constructing tables indexed by the raw pixel data.
-       */
-      for (i = 0, x = -128; i < 256; i++, x++) {
-	    int32 Cr = (int32)Code2V(x, refBlackWhite[4] - 128.0F,
-			    refBlackWhite[5] - 128.0F, 127);
-	    int32 Cb = (int32)Code2V(x, refBlackWhite[2] - 128.0F,
-			    refBlackWhite[3] - 128.0F, 127);
-
-	    ycbcr->Cr_r_tab[i] = (int32)((D1*Cr + ONE_HALF)>>SHIFT);
-	    ycbcr->Cb_b_tab[i] = (int32)((D3*Cb + ONE_HALF)>>SHIFT);
-	    ycbcr->Cr_g_tab[i] = D2*Cr;
-	    ycbcr->Cb_g_tab[i] = D4*Cb + ONE_HALF;
-	    ycbcr->Y_tab[i] =
-		    (int32)Code2V(x + 128, refBlackWhite[0], refBlackWhite[1], 255);
-      }
-    }
-
-    return 0;
-}
-#undef	HICLAMP
-#undef	CLAMP
-#undef	Code2V
-#undef	SHIFT
-#undef	ONE_HALF
-#undef	FIX
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Id: tif_color.c,v 1.11 2015/02/19 22:39:58 drolon Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and 
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
+ * 
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * CIE L*a*b* to CIE XYZ and CIE XYZ to RGB conversion routines are taken
+ * from the VIPS library (http://www.vips.ecs.soton.ac.uk) with
+ * the permission of John Cupitt, the VIPS author.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Color space conversion routines.
+ */
+
+#include "tiffiop.h"
+#include <math.h>
+
+/*
+ * Convert color value from the CIE L*a*b* 1976 space to CIE XYZ.
+ */
+void
+TIFFCIELabToXYZ(TIFFCIELabToRGB *cielab, uint32 l, int32 a, int32 b,
+		float *X, float *Y, float *Z)
+{
+	float L = (float)l * 100.0F / 255.0F;
+	float cby, tmp;
+
+	if( L < 8.856F ) {
+		*Y = (L * cielab->Y0) / 903.292F;
+		cby = 7.787F * (*Y / cielab->Y0) + 16.0F / 116.0F;
+	} else {
+		cby = (L + 16.0F) / 116.0F;
+		*Y = cielab->Y0 * cby * cby * cby;
+	}
+
+	tmp = (float)a / 500.0F + cby;
+	if( tmp < 0.2069F )
+		*X = cielab->X0 * (tmp - 0.13793F) / 7.787F;
+	else    
+		*X = cielab->X0 * tmp * tmp * tmp;
+
+	tmp = cby - (float)b / 200.0F;
+	if( tmp < 0.2069F )
+		*Z = cielab->Z0 * (tmp - 0.13793F) / 7.787F;
+	else    
+		*Z = cielab->Z0 * tmp * tmp * tmp;
+}
+
+#define RINT(R) ((uint32)((R)>0?((R)+0.5):((R)-0.5)))
+/*
+ * Convert color value from the XYZ space to RGB.
+ */
+void
+TIFFXYZToRGB(TIFFCIELabToRGB *cielab, float X, float Y, float Z,
+	     uint32 *r, uint32 *g, uint32 *b)
+{
+	int i;
+	float Yr, Yg, Yb;
+	float *matrix = &cielab->display.d_mat[0][0];
+
+	/* Multiply through the matrix to get luminosity values. */
+	Yr =  matrix[0] * X + matrix[1] * Y + matrix[2] * Z;
+	Yg =  matrix[3] * X + matrix[4] * Y + matrix[5] * Z;
+	Yb =  matrix[6] * X + matrix[7] * Y + matrix[8] * Z;
+
+	/* Clip input */
+	Yr = TIFFmax(Yr, cielab->display.d_Y0R);
+	Yg = TIFFmax(Yg, cielab->display.d_Y0G);
+	Yb = TIFFmax(Yb, cielab->display.d_Y0B);
+
+	/* Avoid overflow in case of wrong input values */
+	Yr = TIFFmin(Yr, cielab->display.d_YCR);
+	Yg = TIFFmin(Yg, cielab->display.d_YCG);
+	Yb = TIFFmin(Yb, cielab->display.d_YCB);
+
+	/* Turn luminosity to colour value. */
+	i = (int)((Yr - cielab->display.d_Y0R) / cielab->rstep);
+	i = TIFFmin(cielab->range, i);
+	*r = RINT(cielab->Yr2r[i]);
+
+	i = (int)((Yg - cielab->display.d_Y0G) / cielab->gstep);
+	i = TIFFmin(cielab->range, i);
+	*g = RINT(cielab->Yg2g[i]);
+
+	i = (int)((Yb - cielab->display.d_Y0B) / cielab->bstep);
+	i = TIFFmin(cielab->range, i);
+	*b = RINT(cielab->Yb2b[i]);
+
+	/* Clip output. */
+	*r = TIFFmin(*r, cielab->display.d_Vrwr);
+	*g = TIFFmin(*g, cielab->display.d_Vrwg);
+	*b = TIFFmin(*b, cielab->display.d_Vrwb);
+}
+#undef RINT
+
+/* 
+ * Allocate conversion state structures and make look_up tables for
+ * the Yr,Yb,Yg <=> r,g,b conversions.
+ */
+int
+TIFFCIELabToRGBInit(TIFFCIELabToRGB* cielab,
+		    const TIFFDisplay *display, float *refWhite)
+{
+	int i;
+	double gamma;
+
+	cielab->range = CIELABTORGB_TABLE_RANGE;
+
+	_TIFFmemcpy(&cielab->display, display, sizeof(TIFFDisplay));
+
+	/* Red */
+	gamma = 1.0 / cielab->display.d_gammaR ;
+	cielab->rstep =
+		(cielab->display.d_YCR - cielab->display.d_Y0R)	/ cielab->range;
+	for(i = 0; i <= cielab->range; i++) {
+		cielab->Yr2r[i] = cielab->display.d_Vrwr
+		    * ((float)pow((double)i / cielab->range, gamma));
+	}
+
+	/* Green */
+	gamma = 1.0 / cielab->display.d_gammaG ;
+	cielab->gstep =
+	    (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
+	for(i = 0; i <= cielab->range; i++) {
+		cielab->Yg2g[i] = cielab->display.d_Vrwg
+		    * ((float)pow((double)i / cielab->range, gamma));
+	}
+
+	/* Blue */
+	gamma = 1.0 / cielab->display.d_gammaB ;
+	cielab->bstep =
+	    (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
+	for(i = 0; i <= cielab->range; i++) {
+		cielab->Yb2b[i] = cielab->display.d_Vrwb
+		    * ((float)pow((double)i / cielab->range, gamma));
+	}
+
+	/* Init reference white point */
+	cielab->X0 = refWhite[0];
+	cielab->Y0 = refWhite[1];
+	cielab->Z0 = refWhite[2];
+
+	return 0;
+}
+
+/* 
+ * Convert color value from the YCbCr space to CIE XYZ.
+ * The colorspace conversion algorithm comes from the IJG v5a code;
+ * see below for more information on how it works.
+ */
+#define	SHIFT			16
+#define	FIX(x)			((int32)((x) * (1L<<SHIFT) + 0.5))
+#define	ONE_HALF		((int32)(1<<(SHIFT-1)))
+#define	Code2V(c, RB, RW, CR)	((((c)-(int32)(RB))*(float)(CR))/(float)(((RW)-(RB)) ? ((RW)-(RB)) : 1))
+#define	CLAMP(f,min,max)	((f)<(min)?(min):(f)>(max)?(max):(f))
+#define HICLAMP(f,max)		((f)>(max)?(max):(f))
+
+void
+TIFFYCbCrtoRGB(TIFFYCbCrToRGB *ycbcr, uint32 Y, int32 Cb, int32 Cr,
+	       uint32 *r, uint32 *g, uint32 *b)
+{
+	int32 i;
+
+	/* XXX: Only 8-bit YCbCr input supported for now */
+	Y = HICLAMP(Y, 255), Cb = CLAMP(Cb, 0, 255), Cr = CLAMP(Cr, 0, 255);
+
+	i = ycbcr->Y_tab[Y] + ycbcr->Cr_r_tab[Cr];
+	*r = CLAMP(i, 0, 255);
+	i = ycbcr->Y_tab[Y]
+	    + (int)((ycbcr->Cb_g_tab[Cb] + ycbcr->Cr_g_tab[Cr]) >> SHIFT);
+	*g = CLAMP(i, 0, 255);
+	i = ycbcr->Y_tab[Y] + ycbcr->Cb_b_tab[Cb];
+	*b = CLAMP(i, 0, 255);
+}
+
+/*
+ * Initialize the YCbCr->RGB conversion tables.  The conversion
+ * is done according to the 6.0 spec:
+ *
+ *    R = Y + Cr*(2 - 2*LumaRed)
+ *    B = Y + Cb*(2 - 2*LumaBlue)
+ *    G =   Y
+ *        - LumaBlue*Cb*(2-2*LumaBlue)/LumaGreen
+ *        - LumaRed*Cr*(2-2*LumaRed)/LumaGreen
+ *
+ * To avoid floating point arithmetic the fractional constants that
+ * come out of the equations are represented as fixed point values
+ * in the range 0...2^16.  We also eliminate multiplications by
+ * pre-calculating possible values indexed by Cb and Cr (this code
+ * assumes conversion is being done for 8-bit samples).
+ */
+int
+TIFFYCbCrToRGBInit(TIFFYCbCrToRGB* ycbcr, float *luma, float *refBlackWhite)
+{
+    TIFFRGBValue* clamptab;
+    int i;
+    
+#define LumaRed	    luma[0]
+#define LumaGreen   luma[1]
+#define LumaBlue    luma[2]
+
+    clamptab = (TIFFRGBValue*)(
+	(uint8*) ycbcr+TIFFroundup_32(sizeof (TIFFYCbCrToRGB), sizeof (long)));  
+    _TIFFmemset(clamptab, 0, 256);		/* v < 0 => 0 */
+    ycbcr->clamptab = (clamptab += 256);
+    for (i = 0; i < 256; i++)
+	clamptab[i] = (TIFFRGBValue) i;
+    _TIFFmemset(clamptab+256, 255, 2*256);	/* v > 255 => 255 */
+    ycbcr->Cr_r_tab = (int*) (clamptab + 3*256);
+    ycbcr->Cb_b_tab = ycbcr->Cr_r_tab + 256;
+    ycbcr->Cr_g_tab = (int32*) (ycbcr->Cb_b_tab + 256);
+    ycbcr->Cb_g_tab = ycbcr->Cr_g_tab + 256;
+    ycbcr->Y_tab = ycbcr->Cb_g_tab + 256;
+
+    { float f1 = 2-2*LumaRed;		int32 D1 = FIX(f1);
+      float f2 = LumaRed*f1/LumaGreen;	int32 D2 = -FIX(f2);
+      float f3 = 2-2*LumaBlue;		int32 D3 = FIX(f3);
+      float f4 = LumaBlue*f3/LumaGreen;	int32 D4 = -FIX(f4);
+      int x;
+
+#undef LumaBlue
+#undef LumaGreen
+#undef LumaRed
+      
+      /*
+       * i is the actual input pixel value in the range 0..255
+       * Cb and Cr values are in the range -128..127 (actually
+       * they are in a range defined by the ReferenceBlackWhite
+       * tag) so there is some range shifting to do here when
+       * constructing tables indexed by the raw pixel data.
+       */
+      for (i = 0, x = -128; i < 256; i++, x++) {
+	    int32 Cr = (int32)Code2V(x, refBlackWhite[4] - 128.0F,
+			    refBlackWhite[5] - 128.0F, 127);
+	    int32 Cb = (int32)Code2V(x, refBlackWhite[2] - 128.0F,
+			    refBlackWhite[3] - 128.0F, 127);
+
+	    ycbcr->Cr_r_tab[i] = (int32)((D1*Cr + ONE_HALF)>>SHIFT);
+	    ycbcr->Cb_b_tab[i] = (int32)((D3*Cb + ONE_HALF)>>SHIFT);
+	    ycbcr->Cr_g_tab[i] = D2*Cr;
+	    ycbcr->Cb_g_tab[i] = D4*Cb + ONE_HALF;
+	    ycbcr->Y_tab[i] =
+		    (int32)Code2V(x + 128, refBlackWhite[0], refBlackWhite[1], 255);
+      }
+    }
+
+    return 0;
+}
+#undef	HICLAMP
+#undef	CLAMP
+#undef	Code2V
+#undef	SHIFT
+#undef	ONE_HALF
+#undef	FIX
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tif_compress.c b/Source/LibTIFF4/tif_compress.c
index 29ae999..c599cd9 100644
--- a/Source/LibTIFF4/tif_compress.c
+++ b/Source/LibTIFF4/tif_compress.c
@@ -1,304 +1,304 @@
-/* $Id: tif_compress.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library
- *
- * Compression Scheme Configuration Support.
- */
-#include "tiffiop.h"
-
-static int
-TIFFNoEncode(TIFF* tif, const char* method)
-{
-	const TIFFCodec* c = TIFFFindCODEC(tif->tif_dir.td_compression);
-
-	if (c) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			     "%s %s encoding is not implemented",
-			     c->name, method);
-	} else {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			"Compression scheme %u %s encoding is not implemented",
-			     tif->tif_dir.td_compression, method);
-	}
-	return (-1);
-}
-
-int
-_TIFFNoRowEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s)
-{
-	(void) pp; (void) cc; (void) s;
-	return (TIFFNoEncode(tif, "scanline"));
-}
-
-int
-_TIFFNoStripEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s)
-{
-	(void) pp; (void) cc; (void) s;
-	return (TIFFNoEncode(tif, "strip"));
-}
-
-int
-_TIFFNoTileEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s)
-{
-	(void) pp; (void) cc; (void) s;
-	return (TIFFNoEncode(tif, "tile"));
-}
-
-static int
-TIFFNoDecode(TIFF* tif, const char* method)
-{
-	const TIFFCodec* c = TIFFFindCODEC(tif->tif_dir.td_compression);
-
-	if (c)
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			     "%s %s decoding is not implemented",
-			     c->name, method);
-	else
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			     "Compression scheme %u %s decoding is not implemented",
-			     tif->tif_dir.td_compression, method);
-	return (-1);
-}
-
-int
-_TIFFNoFixupTags(TIFF* tif)
-{
-	(void) tif;
-	return (1);
-}
-
-int
-_TIFFNoRowDecode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s)
-{
-	(void) pp; (void) cc; (void) s;
-	return (TIFFNoDecode(tif, "scanline"));
-}
-
-int
-_TIFFNoStripDecode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s)
-{
-	(void) pp; (void) cc; (void) s;
-	return (TIFFNoDecode(tif, "strip"));
-}
-
-int
-_TIFFNoTileDecode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s)
-{
-	(void) pp; (void) cc; (void) s;
-	return (TIFFNoDecode(tif, "tile"));
-}
-
-int
-_TIFFNoSeek(TIFF* tif, uint32 off)
-{
-	(void) off;
-	TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-		     "Compression algorithm does not support random access");
-	return (0);
-}
-
-int
-_TIFFNoPreCode(TIFF* tif, uint16 s)
-{
-	(void) tif; (void) s;
-	return (1);
-}
-
-static int _TIFFtrue(TIFF* tif) { (void) tif; return (1); }
-static void _TIFFvoid(TIFF* tif) { (void) tif; }
-
-void
-_TIFFSetDefaultCompressionState(TIFF* tif)
-{
-	tif->tif_fixuptags = _TIFFNoFixupTags; 
-	tif->tif_decodestatus = TRUE;
-	tif->tif_setupdecode = _TIFFtrue;
-	tif->tif_predecode = _TIFFNoPreCode;
-	tif->tif_decoderow = _TIFFNoRowDecode;  
-	tif->tif_decodestrip = _TIFFNoStripDecode;
-	tif->tif_decodetile = _TIFFNoTileDecode;  
-	tif->tif_encodestatus = TRUE;
-	tif->tif_setupencode = _TIFFtrue;
-	tif->tif_preencode = _TIFFNoPreCode;
-	tif->tif_postencode = _TIFFtrue;
-	tif->tif_encoderow = _TIFFNoRowEncode;
-	tif->tif_encodestrip = _TIFFNoStripEncode;  
-	tif->tif_encodetile = _TIFFNoTileEncode;  
-	tif->tif_close = _TIFFvoid;
-	tif->tif_seek = _TIFFNoSeek;
-	tif->tif_cleanup = _TIFFvoid;
-	tif->tif_defstripsize = _TIFFDefaultStripSize;
-	tif->tif_deftilesize = _TIFFDefaultTileSize;
-	tif->tif_flags &= ~(TIFF_NOBITREV|TIFF_NOREADRAW);
-}
-
-int
-TIFFSetCompressionScheme(TIFF* tif, int scheme)
-{
-	const TIFFCodec *c = TIFFFindCODEC((uint16) scheme);
-
-	_TIFFSetDefaultCompressionState(tif);
-	/*
-	 * Don't treat an unknown compression scheme as an error.
-	 * This permits applications to open files with data that
-	 * the library does not have builtin support for, but which
-	 * may still be meaningful.
-	 */
-	return (c ? (*c->init)(tif, scheme) : 1);
-}
-
-/*
- * Other compression schemes may be registered.  Registered
- * schemes can also override the builtin versions provided
- * by this library.
- */
-typedef struct _codec {
-	struct _codec* next;
-	TIFFCodec* info;
-} codec_t;
-static codec_t* registeredCODECS = NULL;
-
-const TIFFCodec*
-TIFFFindCODEC(uint16 scheme)
-{
-	const TIFFCodec* c;
-	codec_t* cd;
-
-	for (cd = registeredCODECS; cd; cd = cd->next)
-		if (cd->info->scheme == scheme)
-			return ((const TIFFCodec*) cd->info);
-	for (c = _TIFFBuiltinCODECS; c->name; c++)
-		if (c->scheme == scheme)
-			return (c);
-	return ((const TIFFCodec*) 0);
-}
-
-TIFFCodec*
-TIFFRegisterCODEC(uint16 scheme, const char* name, TIFFInitMethod init)
-{
-	codec_t* cd = (codec_t*)
-	    _TIFFmalloc((tmsize_t)(sizeof (codec_t) + sizeof (TIFFCodec) + strlen(name)+1));
-
-	if (cd != NULL) {
-		cd->info = (TIFFCodec*) ((uint8*) cd + sizeof (codec_t));
-		cd->info->name = (char*)
-		    ((uint8*) cd->info + sizeof (TIFFCodec));
-		strcpy(cd->info->name, name);
-		cd->info->scheme = scheme;
-		cd->info->init = init;
-		cd->next = registeredCODECS;
-		registeredCODECS = cd;
-	} else {
-		TIFFErrorExt(0, "TIFFRegisterCODEC",
-		    "No space to register compression scheme %s", name);
-		return NULL;
-	}
-	return (cd->info);
-}
-
-void
-TIFFUnRegisterCODEC(TIFFCodec* c)
-{
-	codec_t* cd;
-	codec_t** pcd;
-
-	for (pcd = ®isteredCODECS; (cd = *pcd); pcd = &cd->next)
-		if (cd->info == c) {
-			*pcd = cd->next;
-			_TIFFfree(cd);
-			return;
-		}
-	TIFFErrorExt(0, "TIFFUnRegisterCODEC",
-	    "Cannot remove compression scheme %s; not registered", c->name);
-}
-
-/************************************************************************/
-/*                       TIFFGetConfisuredCODECs()                      */
-/************************************************************************/
-
-/**
- * Get list of configured codecs, both built-in and registered by user.
- * Caller is responsible to free this structure.
- * 
- * @return returns array of TIFFCodec records (the last record should be NULL)
- * or NULL if function failed.
- */
-
-TIFFCodec*
-TIFFGetConfiguredCODECs()
-{
-	int i = 1;
-	codec_t *cd;
-	const TIFFCodec* c;
-	TIFFCodec* codecs = NULL;
-	TIFFCodec* new_codecs;
-
-	for (cd = registeredCODECS; cd; cd = cd->next) {
-		new_codecs = (TIFFCodec *)
-			_TIFFrealloc(codecs, i * sizeof(TIFFCodec));
-		if (!new_codecs) {
-			_TIFFfree (codecs);
-			return NULL;
-		}
-		codecs = new_codecs;
-		_TIFFmemcpy(codecs + i - 1, cd, sizeof(TIFFCodec));
-		i++;
-	}
-	for (c = _TIFFBuiltinCODECS; c->name; c++) {
-		if (TIFFIsCODECConfigured(c->scheme)) {
-			new_codecs = (TIFFCodec *)
-				_TIFFrealloc(codecs, i * sizeof(TIFFCodec));
-			if (!new_codecs) {
-				_TIFFfree (codecs);
-				return NULL;
-			}
-			codecs = new_codecs;
-			_TIFFmemcpy(codecs + i - 1, (const void*)c, sizeof(TIFFCodec));
-			i++;
-		}
-	}
-
-	new_codecs = (TIFFCodec *) _TIFFrealloc(codecs, i * sizeof(TIFFCodec));
-	if (!new_codecs) {
-		_TIFFfree (codecs);
-		return NULL;
-	}
-	codecs = new_codecs;
-	_TIFFmemset(codecs + i - 1, 0, sizeof(TIFFCodec));
-
-	return codecs;
-}
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Id: tif_compress.c,v 1.11 2015/02/19 22:39:58 drolon Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and 
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
+ * 
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library
+ *
+ * Compression Scheme Configuration Support.
+ */
+#include "tiffiop.h"
+
+static int
+TIFFNoEncode(TIFF* tif, const char* method)
+{
+	const TIFFCodec* c = TIFFFindCODEC(tif->tif_dir.td_compression);
+
+	if (c) {
+		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+			     "%s %s encoding is not implemented",
+			     c->name, method);
+	} else {
+		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+			"Compression scheme %u %s encoding is not implemented",
+			     tif->tif_dir.td_compression, method);
+	}
+	return (-1);
+}
+
+int
+_TIFFNoRowEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s)
+{
+	(void) pp; (void) cc; (void) s;
+	return (TIFFNoEncode(tif, "scanline"));
+}
+
+int
+_TIFFNoStripEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s)
+{
+	(void) pp; (void) cc; (void) s;
+	return (TIFFNoEncode(tif, "strip"));
+}
+
+int
+_TIFFNoTileEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s)
+{
+	(void) pp; (void) cc; (void) s;
+	return (TIFFNoEncode(tif, "tile"));
+}
+
+static int
+TIFFNoDecode(TIFF* tif, const char* method)
+{
+	const TIFFCodec* c = TIFFFindCODEC(tif->tif_dir.td_compression);
+
+	if (c)
+		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+			     "%s %s decoding is not implemented",
+			     c->name, method);
+	else
+		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+			     "Compression scheme %u %s decoding is not implemented",
+			     tif->tif_dir.td_compression, method);
+	return (-1);
+}
+
+int
+_TIFFNoFixupTags(TIFF* tif)
+{
+	(void) tif;
+	return (1);
+}
+
+int
+_TIFFNoRowDecode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s)
+{
+	(void) pp; (void) cc; (void) s;
+	return (TIFFNoDecode(tif, "scanline"));
+}
+
+int
+_TIFFNoStripDecode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s)
+{
+	(void) pp; (void) cc; (void) s;
+	return (TIFFNoDecode(tif, "strip"));
+}
+
+int
+_TIFFNoTileDecode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s)
+{
+	(void) pp; (void) cc; (void) s;
+	return (TIFFNoDecode(tif, "tile"));
+}
+
+int
+_TIFFNoSeek(TIFF* tif, uint32 off)
+{
+	(void) off;
+	TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+		     "Compression algorithm does not support random access");
+	return (0);
+}
+
+int
+_TIFFNoPreCode(TIFF* tif, uint16 s)
+{
+	(void) tif; (void) s;
+	return (1);
+}
+
+static int _TIFFtrue(TIFF* tif) { (void) tif; return (1); }
+static void _TIFFvoid(TIFF* tif) { (void) tif; }
+
+void
+_TIFFSetDefaultCompressionState(TIFF* tif)
+{
+	tif->tif_fixuptags = _TIFFNoFixupTags; 
+	tif->tif_decodestatus = TRUE;
+	tif->tif_setupdecode = _TIFFtrue;
+	tif->tif_predecode = _TIFFNoPreCode;
+	tif->tif_decoderow = _TIFFNoRowDecode;  
+	tif->tif_decodestrip = _TIFFNoStripDecode;
+	tif->tif_decodetile = _TIFFNoTileDecode;  
+	tif->tif_encodestatus = TRUE;
+	tif->tif_setupencode = _TIFFtrue;
+	tif->tif_preencode = _TIFFNoPreCode;
+	tif->tif_postencode = _TIFFtrue;
+	tif->tif_encoderow = _TIFFNoRowEncode;
+	tif->tif_encodestrip = _TIFFNoStripEncode;  
+	tif->tif_encodetile = _TIFFNoTileEncode;  
+	tif->tif_close = _TIFFvoid;
+	tif->tif_seek = _TIFFNoSeek;
+	tif->tif_cleanup = _TIFFvoid;
+	tif->tif_defstripsize = _TIFFDefaultStripSize;
+	tif->tif_deftilesize = _TIFFDefaultTileSize;
+	tif->tif_flags &= ~(TIFF_NOBITREV|TIFF_NOREADRAW);
+}
+
+int
+TIFFSetCompressionScheme(TIFF* tif, int scheme)
+{
+	const TIFFCodec *c = TIFFFindCODEC((uint16) scheme);
+
+	_TIFFSetDefaultCompressionState(tif);
+	/*
+	 * Don't treat an unknown compression scheme as an error.
+	 * This permits applications to open files with data that
+	 * the library does not have builtin support for, but which
+	 * may still be meaningful.
+	 */
+	return (c ? (*c->init)(tif, scheme) : 1);
+}
+
+/*
+ * Other compression schemes may be registered.  Registered
+ * schemes can also override the builtin versions provided
+ * by this library.
+ */
+typedef struct _codec {
+	struct _codec* next;
+	TIFFCodec* info;
+} codec_t;
+static codec_t* registeredCODECS = NULL;
+
+const TIFFCodec*
+TIFFFindCODEC(uint16 scheme)
+{
+	const TIFFCodec* c;
+	codec_t* cd;
+
+	for (cd = registeredCODECS; cd; cd = cd->next)
+		if (cd->info->scheme == scheme)
+			return ((const TIFFCodec*) cd->info);
+	for (c = _TIFFBuiltinCODECS; c->name; c++)
+		if (c->scheme == scheme)
+			return (c);
+	return ((const TIFFCodec*) 0);
+}
+
+TIFFCodec*
+TIFFRegisterCODEC(uint16 scheme, const char* name, TIFFInitMethod init)
+{
+	codec_t* cd = (codec_t*)
+	    _TIFFmalloc((tmsize_t)(sizeof (codec_t) + sizeof (TIFFCodec) + strlen(name)+1));
+
+	if (cd != NULL) {
+		cd->info = (TIFFCodec*) ((uint8*) cd + sizeof (codec_t));
+		cd->info->name = (char*)
+		    ((uint8*) cd->info + sizeof (TIFFCodec));
+		strcpy(cd->info->name, name);
+		cd->info->scheme = scheme;
+		cd->info->init = init;
+		cd->next = registeredCODECS;
+		registeredCODECS = cd;
+	} else {
+		TIFFErrorExt(0, "TIFFRegisterCODEC",
+		    "No space to register compression scheme %s", name);
+		return NULL;
+	}
+	return (cd->info);
+}
+
+void
+TIFFUnRegisterCODEC(TIFFCodec* c)
+{
+	codec_t* cd;
+	codec_t** pcd;
+
+	for (pcd = ®isteredCODECS; (cd = *pcd); pcd = &cd->next)
+		if (cd->info == c) {
+			*pcd = cd->next;
+			_TIFFfree(cd);
+			return;
+		}
+	TIFFErrorExt(0, "TIFFUnRegisterCODEC",
+	    "Cannot remove compression scheme %s; not registered", c->name);
+}
+
+/************************************************************************/
+/*                       TIFFGetConfisuredCODECs()                      */
+/************************************************************************/
+
+/**
+ * Get list of configured codecs, both built-in and registered by user.
+ * Caller is responsible to free this structure.
+ * 
+ * @return returns array of TIFFCodec records (the last record should be NULL)
+ * or NULL if function failed.
+ */
+
+TIFFCodec*
+TIFFGetConfiguredCODECs()
+{
+	int i = 1;
+	codec_t *cd;
+	const TIFFCodec* c;
+	TIFFCodec* codecs = NULL;
+	TIFFCodec* new_codecs;
+
+	for (cd = registeredCODECS; cd; cd = cd->next) {
+		new_codecs = (TIFFCodec *)
+			_TIFFrealloc(codecs, i * sizeof(TIFFCodec));
+		if (!new_codecs) {
+			_TIFFfree (codecs);
+			return NULL;
+		}
+		codecs = new_codecs;
+		_TIFFmemcpy(codecs + i - 1, cd, sizeof(TIFFCodec));
+		i++;
+	}
+	for (c = _TIFFBuiltinCODECS; c->name; c++) {
+		if (TIFFIsCODECConfigured(c->scheme)) {
+			new_codecs = (TIFFCodec *)
+				_TIFFrealloc(codecs, i * sizeof(TIFFCodec));
+			if (!new_codecs) {
+				_TIFFfree (codecs);
+				return NULL;
+			}
+			codecs = new_codecs;
+			_TIFFmemcpy(codecs + i - 1, (const void*)c, sizeof(TIFFCodec));
+			i++;
+		}
+	}
+
+	new_codecs = (TIFFCodec *) _TIFFrealloc(codecs, i * sizeof(TIFFCodec));
+	if (!new_codecs) {
+		_TIFFfree (codecs);
+		return NULL;
+	}
+	codecs = new_codecs;
+	_TIFFmemset(codecs + i - 1, 0, sizeof(TIFFCodec));
+
+	return codecs;
+}
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tif_config.h b/Source/LibTIFF4/tif_config.h
index 800fbce..64391b8 100644
--- a/Source/LibTIFF4/tif_config.h
+++ b/Source/LibTIFF4/tif_config.h
@@ -1,97 +1,97 @@
-#ifndef TIF_CONFIG_H
-#define TIF_CONFIG_H
-
-/* Define to 1 if you have the <assert.h> header file. */
-#define HAVE_ASSERT_H 1
-
-/* Define to 1 if you have the <fcntl.h> header file. */
-#define HAVE_FCNTL_H 1
-
-/* Define as 0 or 1 according to the floating point format suported by the
-   machine */
-#define HAVE_IEEEFP 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <io.h> header file. */
-#define HAVE_IO_H 1
-
-/* Define to 1 if you have the <search.h> header file. */
-#define HAVE_SEARCH_H 1
-
-/* Define to 1 if you have the `setmode' function. */
-#define HAVE_SETMODE 1
-
-/* Define to 1 if you have the `memmove' function. */
-#define HAVE_MEMMOVE 1
-
-/* Define to 1 if you have the `memset' function. */
-#define HAVE_MEMSET 1
-
-/* Signed 32-bit type formatter */
-#define TIFF_INT32_FORMAT "%d"
-
-/* Unsigned 32-bit type formatter */
-#define TIFF_UINT32_FORMAT "%u"
-
-/* Signed 64-bit type formatter */
-#define TIFF_INT64_FORMAT "%ld"
-
-/* Unsigned 64-bit type formatter */
-#define TIFF_UINT64_FORMAT "%lu"
-
-/* Pointer difference type formatter */
-#define TIFF_PTRDIFF_FORMAT "%ld"
-
-/* Signed size type formatter */
-#define TIFF_SSIZE_FORMAT "%ld"
-
-/* 
------------------------------------------------------------------------
-Byte order
------------------------------------------------------------------------
-*/
-
-/*
-Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
-significant byte first (like Motorola and SPARC, unlike Intel).
-Some versions of gcc may have BYTE_ORDER or __BYTE_ORDER defined
-If your big endian system isn't being detected, add an OS specific check
-*/
-#if (defined(BYTE_ORDER) && BYTE_ORDER==BIG_ENDIAN) || \
-	(defined(__BYTE_ORDER) && __BYTE_ORDER==__BIG_ENDIAN) || \
-	defined(__BIG_ENDIAN__)
-/* Set the native cpu bit order (FILLORDER_LSB2MSB or FILLORDER_MSB2LSB) */
-#define HOST_FILLORDER FILLORDER_MSB2LSB
-/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian (Intel) */
-#define WORDS_BIGENDIAN 1
-/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian (Intel) */
-#define HOST_BIGENDIAN 1
-#else
-/* Set the native cpu bit order (FILLORDER_LSB2MSB or FILLORDER_MSB2LSB) */
-#define HOST_FILLORDER FILLORDER_LSB2MSB
-/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian (Intel) */
-#undef WORDS_BIGENDIAN
-/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian (Intel) */
-#undef HOST_BIGENDIAN
-#endif // BYTE_ORDER
-
-#ifdef _WIN32
-#define snprintf _snprintf
-#define lfind _lfind
-#endif // _WIN32
-
-/* Define to `__inline__' or `__inline' if that's what the C compiler
-   calls it, or to nothing if 'inline' is not supported under any name.  */
-#ifndef __cplusplus
-# ifndef inline
-#  define inline __inline
-# endif
-#endif
-
-
-#endif // TIF_CONFIG_H
+#ifndef TIF_CONFIG_H
+#define TIF_CONFIG_H
+
+/* Define to 1 if you have the <assert.h> header file. */
+#define HAVE_ASSERT_H 1
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define as 0 or 1 according to the floating point format suported by the
+   machine */
+#define HAVE_IEEEFP 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <io.h> header file. */
+#define HAVE_IO_H 1
+
+/* Define to 1 if you have the <search.h> header file. */
+#define HAVE_SEARCH_H 1
+
+/* Define to 1 if you have the `setmode' function. */
+#define HAVE_SETMODE 1
+
+/* Define to 1 if you have the `memmove' function. */
+#define HAVE_MEMMOVE 1
+
+/* Define to 1 if you have the `memset' function. */
+#define HAVE_MEMSET 1
+
+/* Signed 32-bit type formatter */
+#define TIFF_INT32_FORMAT "%d"
+
+/* Unsigned 32-bit type formatter */
+#define TIFF_UINT32_FORMAT "%u"
+
+/* Signed 64-bit type formatter */
+#define TIFF_INT64_FORMAT "%ld"
+
+/* Unsigned 64-bit type formatter */
+#define TIFF_UINT64_FORMAT "%lu"
+
+/* Pointer difference type formatter */
+#define TIFF_PTRDIFF_FORMAT "%ld"
+
+/* Signed size type formatter */
+#define TIFF_SSIZE_FORMAT "%ld"
+
+/* 
+-----------------------------------------------------------------------
+Byte order
+-----------------------------------------------------------------------
+*/
+
+/*
+Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+significant byte first (like Motorola and SPARC, unlike Intel).
+Some versions of gcc may have BYTE_ORDER or __BYTE_ORDER defined
+If your big endian system isn't being detected, add an OS specific check
+*/
+#if (defined(BYTE_ORDER) && BYTE_ORDER==BIG_ENDIAN) || \
+	(defined(__BYTE_ORDER) && __BYTE_ORDER==__BIG_ENDIAN) || \
+	defined(__BIG_ENDIAN__)
+/* Set the native cpu bit order (FILLORDER_LSB2MSB or FILLORDER_MSB2LSB) */
+#define HOST_FILLORDER FILLORDER_MSB2LSB
+/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian (Intel) */
+#define WORDS_BIGENDIAN 1
+/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian (Intel) */
+#define HOST_BIGENDIAN 1
+#else
+/* Set the native cpu bit order (FILLORDER_LSB2MSB or FILLORDER_MSB2LSB) */
+#define HOST_FILLORDER FILLORDER_LSB2MSB
+/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian (Intel) */
+#undef WORDS_BIGENDIAN
+/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian (Intel) */
+#undef HOST_BIGENDIAN
+#endif // BYTE_ORDER
+
+#ifdef _WIN32
+#define snprintf _snprintf
+#define lfind _lfind
+#endif // _WIN32
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+   calls it, or to nothing if 'inline' is not supported under any name.  */
+#ifndef __cplusplus
+# ifndef inline
+#  define inline __inline
+# endif
+#endif
+
+
+#endif // TIF_CONFIG_H
diff --git a/Source/LibTIFF4/tif_config.h.in b/Source/LibTIFF4/tif_config.h.in
index ac564b9..0691b4b 100644
--- a/Source/LibTIFF4/tif_config.h.in
+++ b/Source/LibTIFF4/tif_config.h.in
@@ -79,9 +79,6 @@
 /* Define to 1 if you have the `lfind' function. */
 #undef HAVE_LFIND
 
-/* Define to 1 if you have the `m' library (-lm). */
-#undef HAVE_LIBM
-
 /* Define to 1 if you have the <limits.h> header file. */
 #undef HAVE_LIMITS_H
 
@@ -194,8 +191,7 @@
 /* Support LogLuv high dynamic range encoding */
 #undef LOGLUV_SUPPORT
 
-/* Define to the sub-directory in which libtool stores uninstalled libraries.
-   */
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
 #undef LT_OBJDIR
 
 /* Support LZMA2 compression */
@@ -210,9 +206,6 @@
 /* Support NeXT 2-bit RLE algorithm */
 #undef NEXT_SUPPORT
 
-/* Define to 1 if your C compiler doesn't accept -c and -o together. */
-#undef NO_MINUS_C_MINUS_O
-
 /* Support Old JPEG compresson (read-only) */
 #undef OJPEG_SUPPORT
 
diff --git a/Source/LibTIFF4/tif_config.vc.h b/Source/LibTIFF4/tif_config.vc.h
index ad5688a..ef7588c 100644
--- a/Source/LibTIFF4/tif_config.vc.h
+++ b/Source/LibTIFF4/tif_config.vc.h
@@ -1,71 +1,74 @@
-/* Define to 1 if you have the <assert.h> header file. */
-#define HAVE_ASSERT_H 1
-
-/* Define to 1 if you have the <fcntl.h> header file. */
-#define HAVE_FCNTL_H 1
-
-/* Define as 0 or 1 according to the floating point format suported by the
-   machine */
-#define HAVE_IEEEFP 1
-
-/* Define to 1 if you have the `jbg_newlen' function. */
-#define HAVE_JBG_NEWLEN 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <io.h> header file. */
-#define HAVE_IO_H 1
-
-/* Define to 1 if you have the <search.h> header file. */
-#define HAVE_SEARCH_H 1
-
-/* Define to 1 if you have the `setmode' function. */
-#define HAVE_SETMODE 1
-
-/* The size of a `int', as computed by sizeof. */
-#define SIZEOF_INT 4
-
-/* The size of a `long', as computed by sizeof. */
-#define SIZEOF_LONG 4
-
-/* Signed 64-bit type formatter */
-#define TIFF_INT64_FORMAT "%I64d"
-
-/* Signed 64-bit type */
-#define TIFF_INT64_T signed __int64
-
-/* Unsigned 64-bit type formatter */
-#define TIFF_UINT64_FORMAT "%I64u"
-
-/* Unsigned 64-bit type */
-#define TIFF_UINT64_T unsigned __int64
-
-/* Set the native cpu bit order */
-#define HOST_FILLORDER FILLORDER_LSB2MSB
-
-#define snprintf _snprintf
-
-/* Define to 1 if your processor stores words with the most significant byte
-   first (like Motorola and SPARC, unlike Intel and VAX). */
-/* #undef WORDS_BIGENDIAN */
-
-/* Define to `__inline__' or `__inline' if that's what the C compiler
-   calls it, or to nothing if 'inline' is not supported under any name.  */
-#ifndef __cplusplus
-# ifndef inline
-#  define inline __inline
-# endif
-#endif
-
-#define lfind _lfind
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* Define to 1 if you have the <assert.h> header file. */
+#define HAVE_ASSERT_H 1
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define as 0 or 1 according to the floating point format suported by the
+   machine */
+#define HAVE_IEEEFP 1
+
+/* Define to 1 if you have the `jbg_newlen' function. */
+#define HAVE_JBG_NEWLEN 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <io.h> header file. */
+#define HAVE_IO_H 1
+
+/* Define to 1 if you have the <search.h> header file. */
+#define HAVE_SEARCH_H 1
+
+/* Define to 1 if you have the `setmode' function. */
+#define HAVE_SETMODE 1
+
+/* The size of a `int', as computed by sizeof. */
+#define SIZEOF_INT 4
+
+/* The size of a `long', as computed by sizeof. */
+#define SIZEOF_LONG 4
+
+/* Signed 64-bit type formatter */
+#define TIFF_INT64_FORMAT "%I64d"
+
+/* Signed 64-bit type */
+#define TIFF_INT64_T signed __int64
+
+/* Unsigned 64-bit type formatter */
+#define TIFF_UINT64_FORMAT "%I64u"
+
+/* Unsigned 64-bit type */
+#define TIFF_UINT64_T unsigned __int64
+
+/* Set the native cpu bit order */
+#define HOST_FILLORDER FILLORDER_LSB2MSB
+
+/* Visual Studio 2015 / VC 14 / MSVC 19.00 finally has snprintf() */
+#if defined(_MSC_VER) && _MSC_VER < 1900
+#define snprintf _snprintf
+#endif
+
+/* Define to 1 if your processor stores words with the most significant byte
+   first (like Motorola and SPARC, unlike Intel and VAX). */
+/* #undef WORDS_BIGENDIAN */
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+   calls it, or to nothing if 'inline' is not supported under any name.  */
+#ifndef __cplusplus
+# ifndef inline
+#  define inline __inline
+# endif
+#endif
+
+#define lfind _lfind
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tif_config.wince.h b/Source/LibTIFF4/tif_config.wince.h
index bc65cb5..0f01736 100644
--- a/Source/LibTIFF4/tif_config.wince.h
+++ b/Source/LibTIFF4/tif_config.wince.h
@@ -1,71 +1,71 @@
-/* $Id: tif_config.wince.h,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * TIFF library configuration header for Windows CE platform.
- */
-#ifndef _WIN32_WCE
-# error This version of tif_config.h header is dedicated for Windows CE platform!
-#endif
-
-/* Define to 1 if you have the <assert.h> header file. */
-#define HAVE_ASSERT_H 1
-
-/* Define to 1 if you have the <fcntl.h> header file. */
-#define  HAVE_FCNTL_H 1
-
-/* Define as 0 or 1 according to the floating point format suported by the
-   machine */
-#define HAVE_IEEEFP 1
-
-/* Define to 1 if you have the `jbg_newlen' function. */
-#define HAVE_JBG_NEWLEN 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#undef HAVE_SYS_TYPES_H
-
-/* Define to 1 if you have the <io.h> header file. */
-#define HAVE_IO_H 1
-
-/* Define to 1 if you have the <search.h> header file. */
-#define HAVE_SEARCH_H 1
-
-/* Define to 1 if you have the `setmode' function. */
-#define HAVE_SETMODE 1
-
-/* Define to 1 if you have the `bsearch' function. */
-#define HAVE_BSEARCH 1
-#define bsearch wceex_bsearch
-
-/* Define to 1 if you have the `lfind' function. */
-#define HAVE_LFIND 1
-#define lfind wceex_lfind
-
-/* The size of a `int', as computed by sizeof. */
-#define SIZEOF_INT 4
-
-/* Set the native cpu bit order */
-#define HOST_FILLORDER FILLORDER_LSB2MSB
-
-/* Define to 1 if your processor stores words with the most significant byte
-   first (like Motorola and SPARC, unlike Intel and VAX). */
-/* #undef WORDS_BIGENDIAN */
-
-/* Define to `__inline__' or `__inline' if that's what the C compiler
-   calls it, or to nothing if 'inline' is not supported under any name.  */
-#ifndef __cplusplus
-# ifndef inline
-#  define inline __inline
-# endif
-#endif
-
-
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Id: tif_config.wince.h,v 1.11 2015/02/19 22:39:58 drolon Exp $ */
+
+/*
+ * TIFF library configuration header for Windows CE platform.
+ */
+#ifndef _WIN32_WCE
+# error This version of tif_config.h header is dedicated for Windows CE platform!
+#endif
+
+/* Define to 1 if you have the <assert.h> header file. */
+#define HAVE_ASSERT_H 1
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define  HAVE_FCNTL_H 1
+
+/* Define as 0 or 1 according to the floating point format suported by the
+   machine */
+#define HAVE_IEEEFP 1
+
+/* Define to 1 if you have the `jbg_newlen' function. */
+#define HAVE_JBG_NEWLEN 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <io.h> header file. */
+#define HAVE_IO_H 1
+
+/* Define to 1 if you have the <search.h> header file. */
+#define HAVE_SEARCH_H 1
+
+/* Define to 1 if you have the `setmode' function. */
+#define HAVE_SETMODE 1
+
+/* Define to 1 if you have the `bsearch' function. */
+#define HAVE_BSEARCH 1
+#define bsearch wceex_bsearch
+
+/* Define to 1 if you have the `lfind' function. */
+#define HAVE_LFIND 1
+#define lfind wceex_lfind
+
+/* The size of a `int', as computed by sizeof. */
+#define SIZEOF_INT 4
+
+/* Set the native cpu bit order */
+#define HOST_FILLORDER FILLORDER_LSB2MSB
+
+/* Define to 1 if your processor stores words with the most significant byte
+   first (like Motorola and SPARC, unlike Intel and VAX). */
+/* #undef WORDS_BIGENDIAN */
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+   calls it, or to nothing if 'inline' is not supported under any name.  */
+#ifndef __cplusplus
+# ifndef inline
+#  define inline __inline
+# endif
+#endif
+
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tif_dir.c b/Source/LibTIFF4/tif_dir.c
index e0bdc24..515367c 100644
--- a/Source/LibTIFF4/tif_dir.c
+++ b/Source/LibTIFF4/tif_dir.c
@@ -1,1659 +1,1700 @@
-/* $Id: tif_dir.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library.
- *
- * Directory Tag Get & Set Routines.
- * (and also some miscellaneous stuff)
- */
-#include "tiffiop.h"
-
-/*
- * These are used in the backwards compatibility code...
- */
-#define DATATYPE_VOID		0       /* !untyped data */
-#define DATATYPE_INT		1       /* !signed integer data */
-#define DATATYPE_UINT		2       /* !unsigned integer data */
-#define DATATYPE_IEEEFP		3       /* !IEEE floating point data */
-
-static void
-setByteArray(void** vpp, void* vp, size_t nmemb, size_t elem_size)
-{
-	if (*vpp)
-		_TIFFfree(*vpp), *vpp = 0;
-	if (vp) {
-		tmsize_t bytes = (tmsize_t)(nmemb * elem_size);
-		if (elem_size && bytes / elem_size == nmemb)
-			*vpp = (void*) _TIFFmalloc(bytes);
-		if (*vpp)
-			_TIFFmemcpy(*vpp, vp, bytes);
-	}
-}
-void _TIFFsetByteArray(void** vpp, void* vp, uint32 n)
-    { setByteArray(vpp, vp, n, 1); }
-void _TIFFsetString(char** cpp, char* cp)
-    { setByteArray((void**) cpp, (void*) cp, strlen(cp)+1, 1); }
-void _TIFFsetNString(char** cpp, char* cp, uint32 n)
-    { setByteArray((void**) cpp, (void*) cp, n, 1); }
-void _TIFFsetShortArray(uint16** wpp, uint16* wp, uint32 n)
-    { setByteArray((void**) wpp, (void*) wp, n, sizeof (uint16)); }
-void _TIFFsetLongArray(uint32** lpp, uint32* lp, uint32 n)
-    { setByteArray((void**) lpp, (void*) lp, n, sizeof (uint32)); }
-void _TIFFsetLong8Array(uint64** lpp, uint64* lp, uint32 n)
-    { setByteArray((void**) lpp, (void*) lp, n, sizeof (uint64)); }
-void _TIFFsetFloatArray(float** fpp, float* fp, uint32 n)
-    { setByteArray((void**) fpp, (void*) fp, n, sizeof (float)); }
-void _TIFFsetDoubleArray(double** dpp, double* dp, uint32 n)
-    { setByteArray((void**) dpp, (void*) dp, n, sizeof (double)); }
-
-static void
-setDoubleArrayOneValue(double** vpp, double value, size_t nmemb)
-{
-	if (*vpp)
-		_TIFFfree(*vpp);
-	*vpp = _TIFFmalloc(nmemb*sizeof(double));
-	if (*vpp)
-	{
-		while (nmemb--)
-			((double*)*vpp)[nmemb] = value;
-	}
-}
-
-/*
- * Install extra samples information.
- */
-static int
-setExtraSamples(TIFFDirectory* td, va_list ap, uint32* v)
-{
-/* XXX: Unassociated alpha data == 999 is a known Corel Draw bug, see below */
-#define EXTRASAMPLE_COREL_UNASSALPHA 999 
-
-	uint16* va;
-	uint32 i;
-
-	*v = (uint16) va_arg(ap, uint16_vap);
-	if ((uint16) *v > td->td_samplesperpixel)
-		return 0;
-	va = va_arg(ap, uint16*);
-	if (*v > 0 && va == NULL)		/* typically missing param */
-		return 0;
-	for (i = 0; i < *v; i++) {
-		if (va[i] > EXTRASAMPLE_UNASSALPHA) {
-			/*
-			 * XXX: Corel Draw is known to produce incorrect
-			 * ExtraSamples tags which must be patched here if we
-			 * want to be able to open some of the damaged TIFF
-			 * files: 
-			 */
-			if (va[i] == EXTRASAMPLE_COREL_UNASSALPHA)
-				va[i] = EXTRASAMPLE_UNASSALPHA;
-			else
-				return 0;
-		}
-	}
-	td->td_extrasamples = (uint16) *v;
-	_TIFFsetShortArray(&td->td_sampleinfo, va, td->td_extrasamples);
-	return 1;
-
-#undef EXTRASAMPLE_COREL_UNASSALPHA
-}
-
-/*
- * Confirm we have "samplesperpixel" ink names separated by \0.  Returns 
- * zero if the ink names are not as expected.
- */
-static uint32
-checkInkNamesString(TIFF* tif, uint32 slen, const char* s)
-{
-	TIFFDirectory* td = &tif->tif_dir;
-	uint16 i = td->td_samplesperpixel;
-
-	if (slen > 0) {
-		const char* ep = s+slen;
-		const char* cp = s;
-		for (; i > 0; i--) {
-			for (; cp < ep && *cp != '\0'; cp++) {}
-			if (cp >= ep)
-				goto bad;
-			cp++;				/* skip \0 */
-		}
-		return ((uint32)(cp-s));
-	}
-bad:
-	TIFFErrorExt(tif->tif_clientdata, "TIFFSetField",
-	    "%s: Invalid InkNames value; expecting %d names, found %d",
-	    tif->tif_name,
-	    td->td_samplesperpixel,
-	    td->td_samplesperpixel-i);
-	return (0);
-}
-
-static int
-_TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
-{
-	static const char module[] = "_TIFFVSetField";
-
-	TIFFDirectory* td = &tif->tif_dir;
-	int status = 1;
-	uint32 v32, i, v;
-	char* s;
-	const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
-	uint32 standard_tag = tag;
-
-	/*
-	 * We want to force the custom code to be used for custom
-	 * fields even if the tag happens to match a well known 
-	 * one - important for reinterpreted handling of standard
-	 * tag values in custom directories (ie. EXIF) 
-	 */
-	if (fip->field_bit == FIELD_CUSTOM) {
-		standard_tag = 0;
-	}
-
-	switch (standard_tag) {
-	case TIFFTAG_SUBFILETYPE:
-		td->td_subfiletype = (uint32) va_arg(ap, uint32);
-		break;
-	case TIFFTAG_IMAGEWIDTH:
-		td->td_imagewidth = (uint32) va_arg(ap, uint32);
-		break;
-	case TIFFTAG_IMAGELENGTH:
-		td->td_imagelength = (uint32) va_arg(ap, uint32);
-		break;
-	case TIFFTAG_BITSPERSAMPLE:
-		td->td_bitspersample = (uint16) va_arg(ap, uint16_vap);
-		/*
-		 * If the data require post-decoding processing to byte-swap
-		 * samples, set it up here.  Note that since tags are required
-		 * to be ordered, compression code can override this behaviour
-		 * in the setup method if it wants to roll the post decoding
-		 * work in with its normal work.
-		 */
-		if (tif->tif_flags & TIFF_SWAB) {
-			if (td->td_bitspersample == 8)
-				tif->tif_postdecode = _TIFFNoPostDecode;
-			else if (td->td_bitspersample == 16)
-				tif->tif_postdecode = _TIFFSwab16BitData;
-			else if (td->td_bitspersample == 24)
-				tif->tif_postdecode = _TIFFSwab24BitData;
-			else if (td->td_bitspersample == 32)
-				tif->tif_postdecode = _TIFFSwab32BitData;
-			else if (td->td_bitspersample == 64)
-				tif->tif_postdecode = _TIFFSwab64BitData;
-			else if (td->td_bitspersample == 128) /* two 64's */
-				tif->tif_postdecode = _TIFFSwab64BitData;
-		}
-		break;
-	case TIFFTAG_COMPRESSION:
-		v = (uint16) va_arg(ap, uint16_vap);
-		/*
-		 * If we're changing the compression scheme, the notify the
-		 * previous module so that it can cleanup any state it's
-		 * setup.
-		 */
-		if (TIFFFieldSet(tif, FIELD_COMPRESSION)) {
-			if ((uint32)td->td_compression == v)
-				break;
-			(*tif->tif_cleanup)(tif);
-			tif->tif_flags &= ~TIFF_CODERSETUP;
-		}
-		/*
-		 * Setup new compression routine state.
-		 */
-		if( (status = TIFFSetCompressionScheme(tif, v)) != 0 )
-		    td->td_compression = (uint16) v;
-		else
-		    status = 0;
-		break;
-	case TIFFTAG_PHOTOMETRIC:
-		td->td_photometric = (uint16) va_arg(ap, uint16_vap);
-		break;
-	case TIFFTAG_THRESHHOLDING:
-		td->td_threshholding = (uint16) va_arg(ap, uint16_vap);
-		break;
-	case TIFFTAG_FILLORDER:
-		v = (uint16) va_arg(ap, uint16_vap);
-		if (v != FILLORDER_LSB2MSB && v != FILLORDER_MSB2LSB)
-			goto badvalue;
-		td->td_fillorder = (uint16) v;
-		break;
-	case TIFFTAG_ORIENTATION:
-		v = (uint16) va_arg(ap, uint16_vap);
-		if (v < ORIENTATION_TOPLEFT || ORIENTATION_LEFTBOT < v)
-			goto badvalue;
-		else
-			td->td_orientation = (uint16) v;
-		break;
-	case TIFFTAG_SAMPLESPERPIXEL:
-		v = (uint16) va_arg(ap, uint16_vap);
-		if (v == 0)
-			goto badvalue;
-		td->td_samplesperpixel = (uint16) v;
-		break;
-	case TIFFTAG_ROWSPERSTRIP:
-		v32 = (uint32) va_arg(ap, uint32);
-		if (v32 == 0)
-			goto badvalue32;
-		td->td_rowsperstrip = v32;
-		if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) {
-			td->td_tilelength = v32;
-			td->td_tilewidth = td->td_imagewidth;
-		}
-		break;
-	case TIFFTAG_MINSAMPLEVALUE:
-		td->td_minsamplevalue = (uint16) va_arg(ap, uint16_vap);
-		break;
-	case TIFFTAG_MAXSAMPLEVALUE:
-		td->td_maxsamplevalue = (uint16) va_arg(ap, uint16_vap);
-		break;
-	case TIFFTAG_SMINSAMPLEVALUE:
-		if (tif->tif_flags & TIFF_PERSAMPLE)
-			_TIFFsetDoubleArray(&td->td_sminsamplevalue, va_arg(ap, double*), td->td_samplesperpixel);
-		else
-			setDoubleArrayOneValue(&td->td_sminsamplevalue, va_arg(ap, double), td->td_samplesperpixel);
-		break;
-	case TIFFTAG_SMAXSAMPLEVALUE:
-		if (tif->tif_flags & TIFF_PERSAMPLE)
-			_TIFFsetDoubleArray(&td->td_smaxsamplevalue, va_arg(ap, double*), td->td_samplesperpixel);
-		else
-			setDoubleArrayOneValue(&td->td_smaxsamplevalue, va_arg(ap, double), td->td_samplesperpixel);
-		break;
-	case TIFFTAG_XRESOLUTION:
-		td->td_xresolution = (float) va_arg(ap, double);
-		break;
-	case TIFFTAG_YRESOLUTION:
-		td->td_yresolution = (float) va_arg(ap, double);
-		break;
-	case TIFFTAG_PLANARCONFIG:
-		v = (uint16) va_arg(ap, uint16_vap);
-		if (v != PLANARCONFIG_CONTIG && v != PLANARCONFIG_SEPARATE)
-			goto badvalue;
-		td->td_planarconfig = (uint16) v;
-		break;
-	case TIFFTAG_XPOSITION:
-		td->td_xposition = (float) va_arg(ap, double);
-		break;
-	case TIFFTAG_YPOSITION:
-		td->td_yposition = (float) va_arg(ap, double);
-		break;
-	case TIFFTAG_RESOLUTIONUNIT:
-		v = (uint16) va_arg(ap, uint16_vap);
-		if (v < RESUNIT_NONE || RESUNIT_CENTIMETER < v)
-			goto badvalue;
-		td->td_resolutionunit = (uint16) v;
-		break;
-	case TIFFTAG_PAGENUMBER:
-		td->td_pagenumber[0] = (uint16) va_arg(ap, uint16_vap);
-		td->td_pagenumber[1] = (uint16) va_arg(ap, uint16_vap);
-		break;
-	case TIFFTAG_HALFTONEHINTS:
-		td->td_halftonehints[0] = (uint16) va_arg(ap, uint16_vap);
-		td->td_halftonehints[1] = (uint16) va_arg(ap, uint16_vap);
-		break;
-	case TIFFTAG_COLORMAP:
-		v32 = (uint32)(1L<<td->td_bitspersample);
-		_TIFFsetShortArray(&td->td_colormap[0], va_arg(ap, uint16*), v32);
-		_TIFFsetShortArray(&td->td_colormap[1], va_arg(ap, uint16*), v32);
-		_TIFFsetShortArray(&td->td_colormap[2], va_arg(ap, uint16*), v32);
-		break;
-	case TIFFTAG_EXTRASAMPLES:
-		if (!setExtraSamples(td, ap, &v))
-			goto badvalue;
-		break;
-	case TIFFTAG_MATTEING:
-		td->td_extrasamples =  (((uint16) va_arg(ap, uint16_vap)) != 0);
-		if (td->td_extrasamples) {
-			uint16 sv = EXTRASAMPLE_ASSOCALPHA;
-			_TIFFsetShortArray(&td->td_sampleinfo, &sv, 1);
-		}
-		break;
-	case TIFFTAG_TILEWIDTH:
-		v32 = (uint32) va_arg(ap, uint32);
-		if (v32 % 16) {
-			if (tif->tif_mode != O_RDONLY)
-				goto badvalue32;
-			TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
-				"Nonstandard tile width %d, convert file", v32);
-		}
-		td->td_tilewidth = v32;
-		tif->tif_flags |= TIFF_ISTILED;
-		break;
-	case TIFFTAG_TILELENGTH:
-		v32 = (uint32) va_arg(ap, uint32);
-		if (v32 % 16) {
-			if (tif->tif_mode != O_RDONLY)
-				goto badvalue32;
-			TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
-			    "Nonstandard tile length %d, convert file", v32);
-		}
-		td->td_tilelength = v32;
-		tif->tif_flags |= TIFF_ISTILED;
-		break;
-	case TIFFTAG_TILEDEPTH:
-		v32 = (uint32) va_arg(ap, uint32);
-		if (v32 == 0)
-			goto badvalue32;
-		td->td_tiledepth = v32;
-		break;
-	case TIFFTAG_DATATYPE:
-		v = (uint16) va_arg(ap, uint16_vap);
-		switch (v) {
-		case DATATYPE_VOID:	v = SAMPLEFORMAT_VOID;	break;
-		case DATATYPE_INT:	v = SAMPLEFORMAT_INT;	break;
-		case DATATYPE_UINT:	v = SAMPLEFORMAT_UINT;	break;
-		case DATATYPE_IEEEFP:	v = SAMPLEFORMAT_IEEEFP;break;
-		default:		goto badvalue;
-		}
-		td->td_sampleformat = (uint16) v;
-		break;
-	case TIFFTAG_SAMPLEFORMAT:
-		v = (uint16) va_arg(ap, uint16_vap);
-		if (v < SAMPLEFORMAT_UINT || SAMPLEFORMAT_COMPLEXIEEEFP < v)
-			goto badvalue;
-		td->td_sampleformat = (uint16) v;
-
-		/*  Try to fix up the SWAB function for complex data. */
-		if( td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT
-		    && td->td_bitspersample == 32
-		    && tif->tif_postdecode == _TIFFSwab32BitData )
-		    tif->tif_postdecode = _TIFFSwab16BitData;
-		else if( (td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT
-			  || td->td_sampleformat == SAMPLEFORMAT_COMPLEXIEEEFP)
-			 && td->td_bitspersample == 64
-			 && tif->tif_postdecode == _TIFFSwab64BitData )
-		    tif->tif_postdecode = _TIFFSwab32BitData;
-		break;
-	case TIFFTAG_IMAGEDEPTH:
-		td->td_imagedepth = (uint32) va_arg(ap, uint32);
-		break;
-	case TIFFTAG_SUBIFD:
-		if ((tif->tif_flags & TIFF_INSUBIFD) == 0) {
-			td->td_nsubifd = (uint16) va_arg(ap, uint16_vap);
-			_TIFFsetLong8Array(&td->td_subifd, (uint64*) va_arg(ap, uint64*),
-			    (long) td->td_nsubifd);
-		} else {
-			TIFFErrorExt(tif->tif_clientdata, module,
-				     "%s: Sorry, cannot nest SubIFDs",
-				     tif->tif_name);
-			status = 0;
-		}
-		break;
-	case TIFFTAG_YCBCRPOSITIONING:
-		td->td_ycbcrpositioning = (uint16) va_arg(ap, uint16_vap);
-		break;
-	case TIFFTAG_YCBCRSUBSAMPLING:
-		td->td_ycbcrsubsampling[0] = (uint16) va_arg(ap, uint16_vap);
-		td->td_ycbcrsubsampling[1] = (uint16) va_arg(ap, uint16_vap);
-		break;
-	case TIFFTAG_TRANSFERFUNCTION:
-		v = (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1;
-		for (i = 0; i < v; i++)
-			_TIFFsetShortArray(&td->td_transferfunction[i],
-			    va_arg(ap, uint16*), 1L<<td->td_bitspersample);
-		break;
-	case TIFFTAG_REFERENCEBLACKWHITE:
-		/* XXX should check for null range */
-		_TIFFsetFloatArray(&td->td_refblackwhite, va_arg(ap, float*), 6);
-		break;
-	case TIFFTAG_INKNAMES:
-		v = (uint16) va_arg(ap, uint16_vap);
-		s = va_arg(ap, char*);
-		v = checkInkNamesString(tif, v, s);
-		status = v > 0;
-		if( v > 0 ) {
-			_TIFFsetNString(&td->td_inknames, s, v);
-			td->td_inknameslen = v;
-		}
-		break;
-	case TIFFTAG_PERSAMPLE:
-		v = (uint16) va_arg(ap, uint16_vap);
-		if( v == PERSAMPLE_MULTI )
-			tif->tif_flags |= TIFF_PERSAMPLE;
-		else
-			tif->tif_flags &= ~TIFF_PERSAMPLE;
-		break;
-	default: {
-		TIFFTagValue *tv;
-		int tv_size, iCustom;
-
-		/*
-		 * This can happen if multiple images are open with different
-		 * codecs which have private tags.  The global tag information
-		 * table may then have tags that are valid for one file but not
-		 * the other. If the client tries to set a tag that is not valid
-		 * for the image's codec then we'll arrive here.  This
-		 * happens, for example, when tiffcp is used to convert between
-		 * compression schemes and codec-specific tags are blindly copied.
-		 */
-		if(fip == NULL || fip->field_bit != FIELD_CUSTOM) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-			    "%s: Invalid %stag \"%s\" (not supported by codec)",
-			    tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "",
-			    fip ? fip->field_name : "Unknown");
-			status = 0;
-			break;
-		}
-
-		/*
-		 * Find the existing entry for this custom value.
-		 */
-		tv = NULL;
-		for (iCustom = 0; iCustom < td->td_customValueCount; iCustom++) {
-			if (td->td_customValues[iCustom].info->field_tag == tag) {
-				tv = td->td_customValues + iCustom;
-				if (tv->value != NULL) {
-					_TIFFfree(tv->value);
-					tv->value = NULL;
-				}
-				break;
-			}
-		}
-
-		/*
-		 * Grow the custom list if the entry was not found.
-		 */
-		if(tv == NULL) {
-			TIFFTagValue *new_customValues;
-
-			td->td_customValueCount++;
-			new_customValues = (TIFFTagValue *)
-			    _TIFFrealloc(td->td_customValues,
-			    sizeof(TIFFTagValue) * td->td_customValueCount);
-			if (!new_customValues) {
-				TIFFErrorExt(tif->tif_clientdata, module,
-				    "%s: Failed to allocate space for list of custom values",
-				    tif->tif_name);
-				status = 0;
-				goto end;
-			}
-
-			td->td_customValues = new_customValues;
-
-			tv = td->td_customValues + (td->td_customValueCount - 1);
-			tv->info = fip;
-			tv->value = NULL;
-			tv->count = 0;
-		}
-
-		/*
-		 * Set custom value ... save a copy of the custom tag value.
-		 */
-		tv_size = _TIFFDataSize(fip->field_type);
-		if (tv_size == 0) {
-			status = 0;
-			TIFFErrorExt(tif->tif_clientdata, module,
-			    "%s: Bad field type %d for \"%s\"",
-			    tif->tif_name, fip->field_type,
-			    fip->field_name);
-			goto end;
-		}
-
-		if (fip->field_type == TIFF_ASCII)
-		{
-			uint32 ma;
-			char* mb;
-			if (fip->field_passcount)
-			{
-				assert(fip->field_writecount==TIFF_VARIABLE2);
-				ma=(uint32)va_arg(ap,uint32);
-				mb=(char*)va_arg(ap,char*);
-			}
-			else
-			{
-				mb=(char*)va_arg(ap,char*);
-				ma=(uint32)(strlen(mb)+1);
-			}
-			tv->count=ma;
-			setByteArray(&tv->value,mb,ma,1);
-		}
-		else
-		{
-			if (fip->field_passcount) {
-				if (fip->field_writecount == TIFF_VARIABLE2)
-					tv->count = (uint32) va_arg(ap, uint32);
-				else
-					tv->count = (int) va_arg(ap, int);
-			} else if (fip->field_writecount == TIFF_VARIABLE
-			   || fip->field_writecount == TIFF_VARIABLE2)
-				tv->count = 1;
-			else if (fip->field_writecount == TIFF_SPP)
-				tv->count = td->td_samplesperpixel;
-			else
-				tv->count = fip->field_writecount;
-
-			if (tv->count == 0) {
-				status = 0;
-				TIFFErrorExt(tif->tif_clientdata, module,
-					     "%s: Null count for \"%s\" (type "
-					     "%d, writecount %d, passcount %d)",
-					     tif->tif_name,
-					     fip->field_name,
-					     fip->field_type,
-					     fip->field_writecount,
-					     fip->field_passcount);
-				goto end;
-			}
-
-			tv->value = _TIFFCheckMalloc(tif, tv->count, tv_size,
-			    "custom tag binary object");
-			if (!tv->value) {
-				status = 0;
-				goto end;
-			}
-
-			if (fip->field_tag == TIFFTAG_DOTRANGE 
-			    && strcmp(fip->field_name,"DotRange") == 0) {
-				/* TODO: This is an evil exception and should not have been
-				   handled this way ... likely best if we move it into
-				   the directory structure with an explicit field in 
-				   libtiff 4.1 and assign it a FIELD_ value */
-				uint16 v[2];
-				v[0] = (uint16)va_arg(ap, int);
-				v[1] = (uint16)va_arg(ap, int);
-				_TIFFmemcpy(tv->value, &v, 4);
-			}
-
-			else if (fip->field_passcount
-				  || fip->field_writecount == TIFF_VARIABLE
-				  || fip->field_writecount == TIFF_VARIABLE2
-				  || fip->field_writecount == TIFF_SPP
-				  || tv->count > 1) {
-				_TIFFmemcpy(tv->value, va_arg(ap, void *),
-				    tv->count * tv_size);
-			} else {
-				char *val = (char *)tv->value;
-				assert( tv->count == 1 );
-
-				switch (fip->field_type) {
-				case TIFF_BYTE:
-				case TIFF_UNDEFINED:
-					{
-						uint8 v = (uint8)va_arg(ap, int);
-						_TIFFmemcpy(val, &v, tv_size);
-					}
-					break;
-				case TIFF_SBYTE:
-					{
-						int8 v = (int8)va_arg(ap, int);
-						_TIFFmemcpy(val, &v, tv_size);
-					}
-					break;
-				case TIFF_SHORT:
-					{
-						uint16 v = (uint16)va_arg(ap, int);
-						_TIFFmemcpy(val, &v, tv_size);
-					}
-					break;
-				case TIFF_SSHORT:
-					{
-						int16 v = (int16)va_arg(ap, int);
-						_TIFFmemcpy(val, &v, tv_size);
-					}
-					break;
-				case TIFF_LONG:
-				case TIFF_IFD:
-					{
-						uint32 v = va_arg(ap, uint32);
-						_TIFFmemcpy(val, &v, tv_size);
-					}
-					break;
-				case TIFF_SLONG:
-					{
-						int32 v = va_arg(ap, int32);
-						_TIFFmemcpy(val, &v, tv_size);
-					}
-					break;
-				case TIFF_LONG8:
-				case TIFF_IFD8:
-					{
-						uint64 v = va_arg(ap, uint64);
-						_TIFFmemcpy(val, &v, tv_size);
-					}
-					break;
-				case TIFF_SLONG8:
-					{
-						int64 v = va_arg(ap, int64);
-						_TIFFmemcpy(val, &v, tv_size);
-					}
-					break;
-				case TIFF_RATIONAL:
-				case TIFF_SRATIONAL:
-				case TIFF_FLOAT:
-					{
-						float v = (float)va_arg(ap, double);
-						_TIFFmemcpy(val, &v, tv_size);
-					}
-					break;
-				case TIFF_DOUBLE:
-					{
-						double v = va_arg(ap, double);
-						_TIFFmemcpy(val, &v, tv_size);
-					}
-					break;
-				default:
-					_TIFFmemset(val, 0, tv_size);
-					status = 0;
-					break;
-				}
-			}
-		}
-	}
-	}
-	if (status) {
-		const TIFFField* fip=TIFFFieldWithTag(tif,tag);
-		if (fip)                
-			TIFFSetFieldBit(tif, fip->field_bit);
-		tif->tif_flags |= TIFF_DIRTYDIRECT;
-	}
-
-end:
-	va_end(ap);
-	return (status);
-badvalue:
-        {
-		const TIFFField* fip=TIFFFieldWithTag(tif,tag);
-		TIFFErrorExt(tif->tif_clientdata, module,
-		     "%s: Bad value %u for \"%s\" tag",
-		     tif->tif_name, v,
-		     fip ? fip->field_name : "Unknown");
-		va_end(ap);
-        }
-	return (0);
-badvalue32:
-        {
-		const TIFFField* fip=TIFFFieldWithTag(tif,tag);
-		TIFFErrorExt(tif->tif_clientdata, module,
-		     "%s: Bad value %u for \"%s\" tag",
-		     tif->tif_name, v32,
-		     fip ? fip->field_name : "Unknown");
-		va_end(ap);
-        }
-	return (0);
-}
-
-/*
- * Return 1/0 according to whether or not
- * it is permissible to set the tag's value.
- * Note that we allow ImageLength to be changed
- * so that we can append and extend to images.
- * Any other tag may not be altered once writing
- * has commenced, unless its value has no effect
- * on the format of the data that is written.
- */
-static int
-OkToChangeTag(TIFF* tif, uint32 tag)
-{
-	const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY);
-	if (!fip) {			/* unknown tag */
-		TIFFErrorExt(tif->tif_clientdata, "TIFFSetField", "%s: Unknown %stag %u",
-		    tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", tag);
-		return (0);
-	}
-	if (tag != TIFFTAG_IMAGELENGTH && (tif->tif_flags & TIFF_BEENWRITING) &&
-	    !fip->field_oktochange) {
-		/*
-		 * Consult info table to see if tag can be changed
-		 * after we've started writing.  We only allow changes
-		 * to those tags that don't/shouldn't affect the
-		 * compression and/or format of the data.
-		 */
-		TIFFErrorExt(tif->tif_clientdata, "TIFFSetField",
-		    "%s: Cannot modify tag \"%s\" while writing",
-		    tif->tif_name, fip->field_name);
-		return (0);
-	}
-	return (1);
-}
-
-/*
- * Record the value of a field in the
- * internal directory structure.  The
- * field will be written to the file
- * when/if the directory structure is
- * updated.
- */
-int
-TIFFSetField(TIFF* tif, uint32 tag, ...)
-{
-	va_list ap;
-	int status;
-
-	va_start(ap, tag);
-	status = TIFFVSetField(tif, tag, ap);
-	va_end(ap);
-	return (status);
-}
-
-/*
- * Clear the contents of the field in the internal structure.
- */
-int
-TIFFUnsetField(TIFF* tif, uint32 tag)
-{
-    const TIFFField *fip =  TIFFFieldWithTag(tif, tag);
-    TIFFDirectory* td = &tif->tif_dir;
-
-    if( !fip )
-        return 0;
-
-    if( fip->field_bit != FIELD_CUSTOM )
-        TIFFClrFieldBit(tif, fip->field_bit);
-    else
-    {
-        TIFFTagValue *tv = NULL;
-        int i;
-
-        for (i = 0; i < td->td_customValueCount; i++) {
-                
-            tv = td->td_customValues + i;
-            if( tv->info->field_tag == tag )
-                break;
-        }
-
-        if( i < td->td_customValueCount )
-        {
-            _TIFFfree(tv->value);
-            for( ; i < td->td_customValueCount-1; i++) {
-                td->td_customValues[i] = td->td_customValues[i+1];
-            }
-            td->td_customValueCount--;
-        }
-    }
-        
-    tif->tif_flags |= TIFF_DIRTYDIRECT;
-
-    return (1);
-}
-
-/*
- * Like TIFFSetField, but taking a varargs
- * parameter list.  This routine is useful
- * for building higher-level interfaces on
- * top of the library.
- */
-int
-TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
-{
-	return OkToChangeTag(tif, tag) ?
-	    (*tif->tif_tagmethods.vsetfield)(tif, tag, ap) : 0;
-}
-
-static int
-_TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
-{
-	TIFFDirectory* td = &tif->tif_dir;
-	int ret_val = 1;
-	uint32 standard_tag = tag;
-	const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY);
-	
-	/*
-	 * We want to force the custom code to be used for custom
-	 * fields even if the tag happens to match a well known 
-	 * one - important for reinterpreted handling of standard
-	 * tag values in custom directories (ie. EXIF) 
-	 */
-	if (fip->field_bit == FIELD_CUSTOM) {
-		standard_tag = 0;
-	}
-
-	switch (standard_tag) {
-		case TIFFTAG_SUBFILETYPE:
-			*va_arg(ap, uint32*) = td->td_subfiletype;
-			break;
-		case TIFFTAG_IMAGEWIDTH:
-			*va_arg(ap, uint32*) = td->td_imagewidth;
-			break;
-		case TIFFTAG_IMAGELENGTH:
-			*va_arg(ap, uint32*) = td->td_imagelength;
-			break;
-		case TIFFTAG_BITSPERSAMPLE:
-			*va_arg(ap, uint16*) = td->td_bitspersample;
-			break;
-		case TIFFTAG_COMPRESSION:
-			*va_arg(ap, uint16*) = td->td_compression;
-			break;
-		case TIFFTAG_PHOTOMETRIC:
-			*va_arg(ap, uint16*) = td->td_photometric;
-			break;
-		case TIFFTAG_THRESHHOLDING:
-			*va_arg(ap, uint16*) = td->td_threshholding;
-			break;
-		case TIFFTAG_FILLORDER:
-			*va_arg(ap, uint16*) = td->td_fillorder;
-			break;
-		case TIFFTAG_ORIENTATION:
-			*va_arg(ap, uint16*) = td->td_orientation;
-			break;
-		case TIFFTAG_SAMPLESPERPIXEL:
-			*va_arg(ap, uint16*) = td->td_samplesperpixel;
-			break;
-		case TIFFTAG_ROWSPERSTRIP:
-			*va_arg(ap, uint32*) = td->td_rowsperstrip;
-			break;
-		case TIFFTAG_MINSAMPLEVALUE:
-			*va_arg(ap, uint16*) = td->td_minsamplevalue;
-			break;
-		case TIFFTAG_MAXSAMPLEVALUE:
-			*va_arg(ap, uint16*) = td->td_maxsamplevalue;
-			break;
-		case TIFFTAG_SMINSAMPLEVALUE:
-			if (tif->tif_flags & TIFF_PERSAMPLE)
-				*va_arg(ap, double**) = td->td_sminsamplevalue;
-			else
-			{
-				/* libtiff historially treats this as a single value. */
-				uint16 i;
-				double v = td->td_sminsamplevalue[0];
-				for (i=1; i < td->td_samplesperpixel; ++i)
-					if( td->td_sminsamplevalue[i] < v )
-						v = td->td_sminsamplevalue[i];
-				*va_arg(ap, double*) = v;
-			}
-			break;
-		case TIFFTAG_SMAXSAMPLEVALUE:
-			if (tif->tif_flags & TIFF_PERSAMPLE)
-				*va_arg(ap, double**) = td->td_smaxsamplevalue;
-			else
-			{
-				/* libtiff historially treats this as a single value. */
-				uint16 i;
-				double v = td->td_smaxsamplevalue[0];
-				for (i=1; i < td->td_samplesperpixel; ++i)
-					if( td->td_smaxsamplevalue[i] > v )
-						v = td->td_smaxsamplevalue[i];
-				*va_arg(ap, double*) = v;
-			}
-			break;
-		case TIFFTAG_XRESOLUTION:
-			*va_arg(ap, float*) = td->td_xresolution;
-			break;
-		case TIFFTAG_YRESOLUTION:
-			*va_arg(ap, float*) = td->td_yresolution;
-			break;
-		case TIFFTAG_PLANARCONFIG:
-			*va_arg(ap, uint16*) = td->td_planarconfig;
-			break;
-		case TIFFTAG_XPOSITION:
-			*va_arg(ap, float*) = td->td_xposition;
-			break;
-		case TIFFTAG_YPOSITION:
-			*va_arg(ap, float*) = td->td_yposition;
-			break;
-		case TIFFTAG_RESOLUTIONUNIT:
-			*va_arg(ap, uint16*) = td->td_resolutionunit;
-			break;
-		case TIFFTAG_PAGENUMBER:
-			*va_arg(ap, uint16*) = td->td_pagenumber[0];
-			*va_arg(ap, uint16*) = td->td_pagenumber[1];
-			break;
-		case TIFFTAG_HALFTONEHINTS:
-			*va_arg(ap, uint16*) = td->td_halftonehints[0];
-			*va_arg(ap, uint16*) = td->td_halftonehints[1];
-			break;
-		case TIFFTAG_COLORMAP:
-			*va_arg(ap, uint16**) = td->td_colormap[0];
-			*va_arg(ap, uint16**) = td->td_colormap[1];
-			*va_arg(ap, uint16**) = td->td_colormap[2];
-			break;
-		case TIFFTAG_STRIPOFFSETS:
-		case TIFFTAG_TILEOFFSETS:
-			_TIFFFillStriles( tif );
-			*va_arg(ap, uint64**) = td->td_stripoffset;
-			break;
-		case TIFFTAG_STRIPBYTECOUNTS:
-		case TIFFTAG_TILEBYTECOUNTS:
-			_TIFFFillStriles( tif );
-			*va_arg(ap, uint64**) = td->td_stripbytecount;
-			break;
-		case TIFFTAG_MATTEING:
-			*va_arg(ap, uint16*) =
-			    (td->td_extrasamples == 1 &&
-			    td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
-			break;
-		case TIFFTAG_EXTRASAMPLES:
-			*va_arg(ap, uint16*) = td->td_extrasamples;
-			*va_arg(ap, uint16**) = td->td_sampleinfo;
-			break;
-		case TIFFTAG_TILEWIDTH:
-			*va_arg(ap, uint32*) = td->td_tilewidth;
-			break;
-		case TIFFTAG_TILELENGTH:
-			*va_arg(ap, uint32*) = td->td_tilelength;
-			break;
-		case TIFFTAG_TILEDEPTH:
-			*va_arg(ap, uint32*) = td->td_tiledepth;
-			break;
-		case TIFFTAG_DATATYPE:
-			switch (td->td_sampleformat) {
-				case SAMPLEFORMAT_UINT:
-					*va_arg(ap, uint16*) = DATATYPE_UINT;
-					break;
-				case SAMPLEFORMAT_INT:
-					*va_arg(ap, uint16*) = DATATYPE_INT;
-					break;
-				case SAMPLEFORMAT_IEEEFP:
-					*va_arg(ap, uint16*) = DATATYPE_IEEEFP;
-					break;
-				case SAMPLEFORMAT_VOID:
-					*va_arg(ap, uint16*) = DATATYPE_VOID;
-					break;
-			}
-			break;
-		case TIFFTAG_SAMPLEFORMAT:
-			*va_arg(ap, uint16*) = td->td_sampleformat;
-			break;
-		case TIFFTAG_IMAGEDEPTH:
-			*va_arg(ap, uint32*) = td->td_imagedepth;
-			break;
-		case TIFFTAG_SUBIFD:
-			*va_arg(ap, uint16*) = td->td_nsubifd;
-			*va_arg(ap, uint64**) = td->td_subifd;
-			break;
-		case TIFFTAG_YCBCRPOSITIONING:
-			*va_arg(ap, uint16*) = td->td_ycbcrpositioning;
-			break;
-		case TIFFTAG_YCBCRSUBSAMPLING:
-			*va_arg(ap, uint16*) = td->td_ycbcrsubsampling[0];
-			*va_arg(ap, uint16*) = td->td_ycbcrsubsampling[1];
-			break;
-		case TIFFTAG_TRANSFERFUNCTION:
-			*va_arg(ap, uint16**) = td->td_transferfunction[0];
-			if (td->td_samplesperpixel - td->td_extrasamples > 1) {
-				*va_arg(ap, uint16**) = td->td_transferfunction[1];
-				*va_arg(ap, uint16**) = td->td_transferfunction[2];
-			}
-			break;
-		case TIFFTAG_REFERENCEBLACKWHITE:
-			*va_arg(ap, float**) = td->td_refblackwhite;
-			break;
-		case TIFFTAG_INKNAMES:
-			*va_arg(ap, char**) = td->td_inknames;
-			break;
-		default:
-			{
-				int i;
-
-				/*
-				 * This can happen if multiple images are open
-				 * with different codecs which have private
-				 * tags.  The global tag information table may
-				 * then have tags that are valid for one file
-				 * but not the other. If the client tries to
-				 * get a tag that is not valid for the image's
-				 * codec then we'll arrive here.
-				 */
-				if( fip == NULL || fip->field_bit != FIELD_CUSTOM )
-				{
-					TIFFErrorExt(tif->tif_clientdata, "_TIFFVGetField",
-					    "%s: Invalid %stag \"%s\" "
-					    "(not supported by codec)",
-					    tif->tif_name,
-					    isPseudoTag(tag) ? "pseudo-" : "",
-					    fip ? fip->field_name : "Unknown");
-					ret_val = 0;
-					break;
-				}
-
-				/*
-				 * Do we have a custom value?
-				 */
-				ret_val = 0;
-				for (i = 0; i < td->td_customValueCount; i++) {
-					TIFFTagValue *tv = td->td_customValues + i;
-
-					if (tv->info->field_tag != tag)
-						continue;
-
-					if (fip->field_passcount) {
-						if (fip->field_readcount == TIFF_VARIABLE2)
-							*va_arg(ap, uint32*) = (uint32)tv->count;
-						else  /* Assume TIFF_VARIABLE */
-							*va_arg(ap, uint16*) = (uint16)tv->count;
-						*va_arg(ap, void **) = tv->value;
-						ret_val = 1;
-					} else if (fip->field_tag == TIFFTAG_DOTRANGE
-						   && strcmp(fip->field_name,"DotRange") == 0) {
-						/* TODO: This is an evil exception and should not have been
-						   handled this way ... likely best if we move it into
-						   the directory structure with an explicit field in 
-						   libtiff 4.1 and assign it a FIELD_ value */
-						*va_arg(ap, uint16*) = ((uint16 *)tv->value)[0];
-						*va_arg(ap, uint16*) = ((uint16 *)tv->value)[1];
-						ret_val = 1;
-					} else {
-						if (fip->field_type == TIFF_ASCII
-						    || fip->field_readcount == TIFF_VARIABLE
-						    || fip->field_readcount == TIFF_VARIABLE2
-						    || fip->field_readcount == TIFF_SPP
-						    || tv->count > 1) {
-							*va_arg(ap, void **) = tv->value;
-							ret_val = 1;
-						} else {
-							char *val = (char *)tv->value;
-							assert( tv->count == 1 );
-							switch (fip->field_type) {
-							case TIFF_BYTE:
-							case TIFF_UNDEFINED:
-								*va_arg(ap, uint8*) =
-									*(uint8 *)val;
-								ret_val = 1;
-								break;
-							case TIFF_SBYTE:
-								*va_arg(ap, int8*) =
-									*(int8 *)val;
-								ret_val = 1;
-								break;
-							case TIFF_SHORT:
-								*va_arg(ap, uint16*) =
-									*(uint16 *)val;
-								ret_val = 1;
-								break;
-							case TIFF_SSHORT:
-								*va_arg(ap, int16*) =
-									*(int16 *)val;
-								ret_val = 1;
-								break;
-							case TIFF_LONG:
-							case TIFF_IFD:
-								*va_arg(ap, uint32*) =
-									*(uint32 *)val;
-								ret_val = 1;
-								break;
-							case TIFF_SLONG:
-								*va_arg(ap, int32*) =
-									*(int32 *)val;
-								ret_val = 1;
-								break;
-							case TIFF_LONG8:
-							case TIFF_IFD8:
-								*va_arg(ap, uint64*) =
-									*(uint64 *)val;
-								ret_val = 1;
-								break;
-							case TIFF_SLONG8:
-								*va_arg(ap, int64*) =
-									*(int64 *)val;
-								ret_val = 1;
-								break;
-							case TIFF_RATIONAL:
-							case TIFF_SRATIONAL:
-							case TIFF_FLOAT:
-								*va_arg(ap, float*) =
-									*(float *)val;
-								ret_val = 1;
-								break;
-							case TIFF_DOUBLE:
-								*va_arg(ap, double*) =
-									*(double *)val;
-								ret_val = 1;
-								break;
-							default:
-								ret_val = 0;
-								break;
-							}
-						}
-					}
-					break;
-				}
-			}
-	}
-	return(ret_val);
-}
-
-/*
- * Return the value of a field in the
- * internal directory structure.
- */
-int
-TIFFGetField(TIFF* tif, uint32 tag, ...)
-{
-	int status;
-	va_list ap;
-
-	va_start(ap, tag);
-	status = TIFFVGetField(tif, tag, ap);
-	va_end(ap);
-	return (status);
-}
-
-/*
- * Like TIFFGetField, but taking a varargs
- * parameter list.  This routine is useful
- * for building higher-level interfaces on
- * top of the library.
- */
-int
-TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
-{
-	const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY);
-	return (fip && (isPseudoTag(tag) || TIFFFieldSet(tif, fip->field_bit)) ?
-	    (*tif->tif_tagmethods.vgetfield)(tif, tag, ap) : 0);
-}
-
-#define	CleanupField(member) {		\
-    if (td->member) {			\
-	_TIFFfree(td->member);		\
-	td->member = 0;			\
-    }					\
-}
-
-/*
- * Release storage associated with a directory.
- */
-void
-TIFFFreeDirectory(TIFF* tif)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-	int            i;
-
-	_TIFFmemset(td->td_fieldsset, 0, FIELD_SETLONGS);
-	CleanupField(td_sminsamplevalue);
-	CleanupField(td_smaxsamplevalue);
-	CleanupField(td_colormap[0]);
-	CleanupField(td_colormap[1]);
-	CleanupField(td_colormap[2]);
-	CleanupField(td_sampleinfo);
-	CleanupField(td_subifd);
-	CleanupField(td_inknames);
-	CleanupField(td_refblackwhite);
-	CleanupField(td_transferfunction[0]);
-	CleanupField(td_transferfunction[1]);
-	CleanupField(td_transferfunction[2]);
-	CleanupField(td_stripoffset);
-	CleanupField(td_stripbytecount);
-	TIFFClrFieldBit(tif, FIELD_YCBCRSUBSAMPLING);
-	TIFFClrFieldBit(tif, FIELD_YCBCRPOSITIONING);
-
-	/* Cleanup custom tag values */
-	for( i = 0; i < td->td_customValueCount; i++ ) {
-		if (td->td_customValues[i].value)
-			_TIFFfree(td->td_customValues[i].value);
-	}
-
-	td->td_customValueCount = 0;
-	CleanupField(td_customValues);
-
-#if defined(DEFER_STRILE_LOAD)
-        _TIFFmemset( &(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry));
-        _TIFFmemset( &(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry));
-#endif        
-}
-#undef CleanupField
-
-/*
- * Client Tag extension support (from Niles Ritter).
- */
-static TIFFExtendProc _TIFFextender = (TIFFExtendProc) NULL;
-
-TIFFExtendProc
-TIFFSetTagExtender(TIFFExtendProc extender)
-{
-	TIFFExtendProc prev = _TIFFextender;
-	_TIFFextender = extender;
-	return (prev);
-}
-
-/*
- * Setup for a new directory.  Should we automatically call
- * TIFFWriteDirectory() if the current one is dirty?
- *
- * The newly created directory will not exist on the file till
- * TIFFWriteDirectory(), TIFFFlush() or TIFFClose() is called.
- */
-int
-TIFFCreateDirectory(TIFF* tif)
-{
-	TIFFDefaultDirectory(tif);
-	tif->tif_diroff = 0;
-	tif->tif_nextdiroff = 0;
-	tif->tif_curoff = 0;
-	tif->tif_row = (uint32) -1;
-	tif->tif_curstrip = (uint32) -1;
-
-	return 0;
-}
-
-int
-TIFFCreateCustomDirectory(TIFF* tif, const TIFFFieldArray* infoarray)
-{
-	TIFFDefaultDirectory(tif);
-
-	/*
-	 * Reset the field definitions to match the application provided list. 
-	 * Hopefully TIFFDefaultDirectory() won't have done anything irreversable
-	 * based on it's assumption this is an image directory.
-	 */
-	_TIFFSetupFields(tif, infoarray);
-
-	tif->tif_diroff = 0;
-	tif->tif_nextdiroff = 0;
-	tif->tif_curoff = 0;
-	tif->tif_row = (uint32) -1;
-	tif->tif_curstrip = (uint32) -1;
-
-	return 0;
-}
-
-int
-TIFFCreateEXIFDirectory(TIFF* tif)
-{
-	const TIFFFieldArray* exifFieldArray;
-	exifFieldArray = _TIFFGetExifFields();
-	return TIFFCreateCustomDirectory(tif, exifFieldArray);
-}
-
-/*
- * Setup a default directory structure.
- */
-int
-TIFFDefaultDirectory(TIFF* tif)
-{
-	register TIFFDirectory* td = &tif->tif_dir;
-	const TIFFFieldArray* tiffFieldArray;
-
-	tiffFieldArray = _TIFFGetFields();
-	_TIFFSetupFields(tif, tiffFieldArray);   
-
-	_TIFFmemset(td, 0, sizeof (*td));
-	td->td_fillorder = FILLORDER_MSB2LSB;
-	td->td_bitspersample = 1;
-	td->td_threshholding = THRESHHOLD_BILEVEL;
-	td->td_orientation = ORIENTATION_TOPLEFT;
-	td->td_samplesperpixel = 1;
-	td->td_rowsperstrip = (uint32) -1;
-	td->td_tilewidth = 0;
-	td->td_tilelength = 0;
-	td->td_tiledepth = 1;
-	td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */  
-	td->td_resolutionunit = RESUNIT_INCH;
-	td->td_sampleformat = SAMPLEFORMAT_UINT;
-	td->td_imagedepth = 1;
-	td->td_ycbcrsubsampling[0] = 2;
-	td->td_ycbcrsubsampling[1] = 2;
-	td->td_ycbcrpositioning = YCBCRPOSITION_CENTERED;
-	tif->tif_postdecode = _TIFFNoPostDecode;  
-	tif->tif_foundfield = NULL;
-	tif->tif_tagmethods.vsetfield = _TIFFVSetField;  
-	tif->tif_tagmethods.vgetfield = _TIFFVGetField;
-	tif->tif_tagmethods.printdir = NULL;
-	/*
-	 *  Give client code a chance to install their own
-	 *  tag extensions & methods, prior to compression overloads.
-	 */
-	if (_TIFFextender)
-		(*_TIFFextender)(tif);
-	(void) TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
-	/*
-	 * NB: The directory is marked dirty as a result of setting
-	 * up the default compression scheme.  However, this really
-	 * isn't correct -- we want TIFF_DIRTYDIRECT to be set only
-	 * if the user does something.  We could just do the setup
-	 * by hand, but it seems better to use the normal mechanism
-	 * (i.e. TIFFSetField).
-	 */
-	tif->tif_flags &= ~TIFF_DIRTYDIRECT;
-
-	/*
-	 * As per http://bugzilla.remotesensing.org/show_bug.cgi?id=19
-	 * we clear the ISTILED flag when setting up a new directory.
-	 * Should we also be clearing stuff like INSUBIFD?
-	 */
-	tif->tif_flags &= ~TIFF_ISTILED;
-
-	return (1);
-}
-
-static int
-TIFFAdvanceDirectory(TIFF* tif, uint64* nextdir, uint64* off)
-{
-	static const char module[] = "TIFFAdvanceDirectory";
-	if (isMapped(tif))
-	{
-		uint64 poff=*nextdir;
-		if (!(tif->tif_flags&TIFF_BIGTIFF))
-		{
-			tmsize_t poffa,poffb,poffc,poffd;
-			uint16 dircount;
-			uint32 nextdir32;
-			poffa=(tmsize_t)poff;
-			poffb=poffa+sizeof(uint16);
-			if (((uint64)poffa!=poff)||(poffb<poffa)||(poffb<(tmsize_t)sizeof(uint16))||(poffb>tif->tif_size))
-			{
-				TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory count");
-				return(0);
-			}
-			_TIFFmemcpy(&dircount,tif->tif_base+poffa,sizeof(uint16));
-			if (tif->tif_flags&TIFF_SWAB)
-				TIFFSwabShort(&dircount);
-			poffc=poffb+dircount*12;
-			poffd=poffc+sizeof(uint32);
-			if ((poffc<poffb)||(poffc<dircount*12)||(poffd<poffc)||(poffd<(tmsize_t)sizeof(uint32))||(poffd>tif->tif_size))
-			{
-				TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory link");
-				return(0);
-			}
-			if (off!=NULL)
-				*off=(uint64)poffc;
-			_TIFFmemcpy(&nextdir32,tif->tif_base+poffc,sizeof(uint32));
-			if (tif->tif_flags&TIFF_SWAB)
-				TIFFSwabLong(&nextdir32);
-			*nextdir=nextdir32;
-		}
-		else
-		{
-			tmsize_t poffa,poffb,poffc,poffd;
-			uint64 dircount64;
-			uint16 dircount16;
-			poffa=(tmsize_t)poff;
-			poffb=poffa+sizeof(uint64);
-			if (((uint64)poffa!=poff)||(poffb<poffa)||(poffb<(tmsize_t)sizeof(uint64))||(poffb>tif->tif_size))
-			{
-				TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory count");
-				return(0);
-			}
-			_TIFFmemcpy(&dircount64,tif->tif_base+poffa,sizeof(uint64));
-			if (tif->tif_flags&TIFF_SWAB)
-				TIFFSwabLong8(&dircount64);
-			if (dircount64>0xFFFF)
-			{
-				TIFFErrorExt(tif->tif_clientdata,module,"Sanity check on directory count failed");
-				return(0);
-			}
-			dircount16=(uint16)dircount64;
-			poffc=poffb+dircount16*20;
-			poffd=poffc+sizeof(uint64);
-			if ((poffc<poffb)||(poffc<dircount16*20)||(poffd<poffc)||(poffd<(tmsize_t)sizeof(uint64))||(poffd>tif->tif_size))
-			{
-				TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory link");
-				return(0);
-			}
-			if (off!=NULL)
-				*off=(uint64)poffc;
-			_TIFFmemcpy(nextdir,tif->tif_base+poffc,sizeof(uint64));
-			if (tif->tif_flags&TIFF_SWAB)
-				TIFFSwabLong8(nextdir);
-		}
-		return(1);
-	}
-	else
-	{
-		if (!(tif->tif_flags&TIFF_BIGTIFF))
-		{
-			uint16 dircount;
-			uint32 nextdir32;
-			if (!SeekOK(tif, *nextdir) ||
-			    !ReadOK(tif, &dircount, sizeof (uint16))) {
-				TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count",
-				    tif->tif_name);
-				return (0);
-			}
-			if (tif->tif_flags & TIFF_SWAB)
-				TIFFSwabShort(&dircount);
-			if (off != NULL)
-				*off = TIFFSeekFile(tif,
-				    dircount*12, SEEK_CUR);
-			else
-				(void) TIFFSeekFile(tif,
-				    dircount*12, SEEK_CUR);
-			if (!ReadOK(tif, &nextdir32, sizeof (uint32))) {
-				TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory link",
-				    tif->tif_name);
-				return (0);
-			}
-			if (tif->tif_flags & TIFF_SWAB)
-				TIFFSwabLong(&nextdir32);
-			*nextdir=nextdir32;
-		}
-		else
-		{
-			uint64 dircount64;
-			uint16 dircount16;
-			if (!SeekOK(tif, *nextdir) ||
-			    !ReadOK(tif, &dircount64, sizeof (uint64))) {
-				TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count",
-				    tif->tif_name);
-				return (0);
-			}
-			if (tif->tif_flags & TIFF_SWAB)
-				TIFFSwabLong8(&dircount64);
-			if (dircount64>0xFFFF)
-			{
-				TIFFErrorExt(tif->tif_clientdata, module, "Error fetching directory count");
-				return(0);
-			}
-			dircount16 = (uint16)dircount64;
-			if (off != NULL)
-				*off = TIFFSeekFile(tif,
-				    dircount16*20, SEEK_CUR);
-			else
-				(void) TIFFSeekFile(tif,
-				    dircount16*20, SEEK_CUR);
-			if (!ReadOK(tif, nextdir, sizeof (uint64))) {
-				TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory link",
-				    tif->tif_name);
-				return (0);
-			}
-			if (tif->tif_flags & TIFF_SWAB)
-				TIFFSwabLong8(nextdir);
-		}
-		return (1);
-	}
-}
-
-/*
- * Count the number of directories in a file.
- */
-uint16
-TIFFNumberOfDirectories(TIFF* tif)
-{
-	uint64 nextdir;
-	uint16 n;
-	if (!(tif->tif_flags&TIFF_BIGTIFF))
-		nextdir = tif->tif_header.classic.tiff_diroff;
-	else
-		nextdir = tif->tif_header.big.tiff_diroff;
-	n = 0;
-	while (nextdir != 0 && TIFFAdvanceDirectory(tif, &nextdir, NULL))
-		n++;
-	return (n);
-}
-
-/*
- * Set the n-th directory as the current directory.
- * NB: Directories are numbered starting at 0.
- */
-int
-TIFFSetDirectory(TIFF* tif, uint16 dirn)
-{
-	uint64 nextdir;
-	uint16 n;
-
-	if (!(tif->tif_flags&TIFF_BIGTIFF))
-		nextdir = tif->tif_header.classic.tiff_diroff;
-	else
-		nextdir = tif->tif_header.big.tiff_diroff;
-	for (n = dirn; n > 0 && nextdir != 0; n--)
-		if (!TIFFAdvanceDirectory(tif, &nextdir, NULL))
-			return (0);
-	tif->tif_nextdiroff = nextdir;
-	/*
-	 * Set curdir to the actual directory index.  The
-	 * -1 is because TIFFReadDirectory will increment
-	 * tif_curdir after successfully reading the directory.
-	 */
-	tif->tif_curdir = (dirn - n) - 1;
-	/*
-	 * Reset tif_dirnumber counter and start new list of seen directories.
-	 * We need this to prevent IFD loops.
-	 */
-	tif->tif_dirnumber = 0;
-	return (TIFFReadDirectory(tif));
-}
-
-/*
- * Set the current directory to be the directory
- * located at the specified file offset.  This interface
- * is used mainly to access directories linked with
- * the SubIFD tag (e.g. thumbnail images).
- */
-int
-TIFFSetSubDirectory(TIFF* tif, uint64 diroff)
-{
-	tif->tif_nextdiroff = diroff;
-	/*
-	 * Reset tif_dirnumber counter and start new list of seen directories.
-	 * We need this to prevent IFD loops.
-	 */
-	tif->tif_dirnumber = 0;
-	return (TIFFReadDirectory(tif));
-}
-
-/*
- * Return file offset of the current directory.
- */
-uint64
-TIFFCurrentDirOffset(TIFF* tif)
-{
-	return (tif->tif_diroff);
-}
-
-/*
- * Return an indication of whether or not we are
- * at the last directory in the file.
- */
-int
-TIFFLastDirectory(TIFF* tif)
-{
-	return (tif->tif_nextdiroff == 0);
-}
-
-/*
- * Unlink the specified directory from the directory chain.
- */
-int
-TIFFUnlinkDirectory(TIFF* tif, uint16 dirn)
-{
-	static const char module[] = "TIFFUnlinkDirectory";
-	uint64 nextdir;
-	uint64 off;
-	uint16 n;
-
-	if (tif->tif_mode == O_RDONLY) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-                             "Can not unlink directory in read-only file");
-		return (0);
-	}
-	/*
-	 * Go to the directory before the one we want
-	 * to unlink and nab the offset of the link
-	 * field we'll need to patch.
-	 */
-	if (!(tif->tif_flags&TIFF_BIGTIFF))
-	{
-		nextdir = tif->tif_header.classic.tiff_diroff;
-		off = 4;
-	}
-	else
-	{
-		nextdir = tif->tif_header.big.tiff_diroff;
-		off = 8;
-	}
-	for (n = dirn-1; n > 0; n--) {
-		if (nextdir == 0) {
-			TIFFErrorExt(tif->tif_clientdata, module, "Directory %d does not exist", dirn);
-			return (0);
-		}
-		if (!TIFFAdvanceDirectory(tif, &nextdir, &off))
-			return (0);
-	}
-	/*
-	 * Advance to the directory to be unlinked and fetch
-	 * the offset of the directory that follows.
-	 */
-	if (!TIFFAdvanceDirectory(tif, &nextdir, NULL))
-		return (0);
-	/*
-	 * Go back and patch the link field of the preceding
-	 * directory to point to the offset of the directory
-	 * that follows.
-	 */
-	(void) TIFFSeekFile(tif, off, SEEK_SET);
-	if (!(tif->tif_flags&TIFF_BIGTIFF))
-	{
-		uint32 nextdir32;
-		nextdir32=(uint32)nextdir;
-		assert((uint64)nextdir32==nextdir);
-		if (tif->tif_flags & TIFF_SWAB)
-			TIFFSwabLong(&nextdir32);
-		if (!WriteOK(tif, &nextdir32, sizeof (uint32))) {
-			TIFFErrorExt(tif->tif_clientdata, module, "Error writing directory link");
-			return (0);
-		}
-	}
-	else
-	{
-		if (tif->tif_flags & TIFF_SWAB)
-			TIFFSwabLong8(&nextdir);
-		if (!WriteOK(tif, &nextdir, sizeof (uint64))) {
-			TIFFErrorExt(tif->tif_clientdata, module, "Error writing directory link");
-			return (0);
-		}
-	}
-	/*
-	 * Leave directory state setup safely.  We don't have
-	 * facilities for doing inserting and removing directories,
-	 * so it's safest to just invalidate everything.  This
-	 * means that the caller can only append to the directory
-	 * chain.
-	 */
-	(*tif->tif_cleanup)(tif);
-	if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
-		_TIFFfree(tif->tif_rawdata);
-		tif->tif_rawdata = NULL;
-		tif->tif_rawcc = 0;
-                tif->tif_rawdataoff = 0;
-                tif->tif_rawdataloaded = 0;
-	}
-	tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP|TIFF_POSTENCODE|TIFF_BUF4WRITE);
-	TIFFFreeDirectory(tif);
-	TIFFDefaultDirectory(tif);
-	tif->tif_diroff = 0;			/* force link on next write */
-	tif->tif_nextdiroff = 0;		/* next write must be at end */
-	tif->tif_curoff = 0;
-	tif->tif_row = (uint32) -1;
-	tif->tif_curstrip = (uint32) -1;
-	return (1);
-}
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Id: tif_dir.c,v 1.12 2015/02/19 22:39:58 drolon Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and 
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
+ * 
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Directory Tag Get & Set Routines.
+ * (and also some miscellaneous stuff)
+ */
+#include "tiffiop.h"
+
+/*
+ * These are used in the backwards compatibility code...
+ */
+#define DATATYPE_VOID		0       /* !untyped data */
+#define DATATYPE_INT		1       /* !signed integer data */
+#define DATATYPE_UINT		2       /* !unsigned integer data */
+#define DATATYPE_IEEEFP		3       /* !IEEE floating point data */
+
+static void
+setByteArray(void** vpp, void* vp, size_t nmemb, size_t elem_size)
+{
+	if (*vpp)
+		_TIFFfree(*vpp), *vpp = 0;
+	if (vp) {
+		tmsize_t bytes = (tmsize_t)(nmemb * elem_size);
+		if (elem_size && bytes / elem_size == nmemb)
+			*vpp = (void*) _TIFFmalloc(bytes);
+		if (*vpp)
+			_TIFFmemcpy(*vpp, vp, bytes);
+	}
+}
+void _TIFFsetByteArray(void** vpp, void* vp, uint32 n)
+    { setByteArray(vpp, vp, n, 1); }
+void _TIFFsetString(char** cpp, char* cp)
+    { setByteArray((void**) cpp, (void*) cp, strlen(cp)+1, 1); }
+void _TIFFsetNString(char** cpp, char* cp, uint32 n)
+    { setByteArray((void**) cpp, (void*) cp, n, 1); }
+void _TIFFsetShortArray(uint16** wpp, uint16* wp, uint32 n)
+    { setByteArray((void**) wpp, (void*) wp, n, sizeof (uint16)); }
+void _TIFFsetLongArray(uint32** lpp, uint32* lp, uint32 n)
+    { setByteArray((void**) lpp, (void*) lp, n, sizeof (uint32)); }
+void _TIFFsetLong8Array(uint64** lpp, uint64* lp, uint32 n)
+    { setByteArray((void**) lpp, (void*) lp, n, sizeof (uint64)); }
+void _TIFFsetFloatArray(float** fpp, float* fp, uint32 n)
+    { setByteArray((void**) fpp, (void*) fp, n, sizeof (float)); }
+void _TIFFsetDoubleArray(double** dpp, double* dp, uint32 n)
+    { setByteArray((void**) dpp, (void*) dp, n, sizeof (double)); }
+
+static void
+setDoubleArrayOneValue(double** vpp, double value, size_t nmemb)
+{
+	if (*vpp)
+		_TIFFfree(*vpp);
+	*vpp = _TIFFmalloc(nmemb*sizeof(double));
+	if (*vpp)
+	{
+		while (nmemb--)
+			((double*)*vpp)[nmemb] = value;
+	}
+}
+
+/*
+ * Install extra samples information.
+ */
+static int
+setExtraSamples(TIFFDirectory* td, va_list ap, uint32* v)
+{
+/* XXX: Unassociated alpha data == 999 is a known Corel Draw bug, see below */
+#define EXTRASAMPLE_COREL_UNASSALPHA 999 
+
+	uint16* va;
+	uint32 i;
+
+	*v = (uint16) va_arg(ap, uint16_vap);
+	if ((uint16) *v > td->td_samplesperpixel)
+		return 0;
+	va = va_arg(ap, uint16*);
+	if (*v > 0 && va == NULL)		/* typically missing param */
+		return 0;
+	for (i = 0; i < *v; i++) {
+		if (va[i] > EXTRASAMPLE_UNASSALPHA) {
+			/*
+			 * XXX: Corel Draw is known to produce incorrect
+			 * ExtraSamples tags which must be patched here if we
+			 * want to be able to open some of the damaged TIFF
+			 * files: 
+			 */
+			if (va[i] == EXTRASAMPLE_COREL_UNASSALPHA)
+				va[i] = EXTRASAMPLE_UNASSALPHA;
+			else
+				return 0;
+		}
+	}
+	td->td_extrasamples = (uint16) *v;
+	_TIFFsetShortArray(&td->td_sampleinfo, va, td->td_extrasamples);
+	return 1;
+
+#undef EXTRASAMPLE_COREL_UNASSALPHA
+}
+
+/*
+ * Confirm we have "samplesperpixel" ink names separated by \0.  Returns 
+ * zero if the ink names are not as expected.
+ */
+static uint32
+checkInkNamesString(TIFF* tif, uint32 slen, const char* s)
+{
+	TIFFDirectory* td = &tif->tif_dir;
+	uint16 i = td->td_samplesperpixel;
+
+	if (slen > 0) {
+		const char* ep = s+slen;
+		const char* cp = s;
+		for (; i > 0; i--) {
+			for (; cp < ep && *cp != '\0'; cp++) {}
+			if (cp >= ep)
+				goto bad;
+			cp++;				/* skip \0 */
+		}
+		return ((uint32)(cp-s));
+	}
+bad:
+	TIFFErrorExt(tif->tif_clientdata, "TIFFSetField",
+	    "%s: Invalid InkNames value; expecting %d names, found %d",
+	    tif->tif_name,
+	    td->td_samplesperpixel,
+	    td->td_samplesperpixel-i);
+	return (0);
+}
+
+static int
+_TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
+{
+	static const char module[] = "_TIFFVSetField";
+
+	TIFFDirectory* td = &tif->tif_dir;
+	int status = 1;
+	uint32 v32, i, v;
+    double dblval;
+	char* s;
+	const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
+	uint32 standard_tag = tag;
+	if( fip == NULL ) /* cannot happen since OkToChangeTag() already checks it */
+	    return 0;
+	/*
+	 * We want to force the custom code to be used for custom
+	 * fields even if the tag happens to match a well known 
+	 * one - important for reinterpreted handling of standard
+	 * tag values in custom directories (ie. EXIF) 
+	 */
+	if (fip->field_bit == FIELD_CUSTOM) {
+		standard_tag = 0;
+	}
+
+	switch (standard_tag) {
+	case TIFFTAG_SUBFILETYPE:
+		td->td_subfiletype = (uint32) va_arg(ap, uint32);
+		break;
+	case TIFFTAG_IMAGEWIDTH:
+		td->td_imagewidth = (uint32) va_arg(ap, uint32);
+		break;
+	case TIFFTAG_IMAGELENGTH:
+		td->td_imagelength = (uint32) va_arg(ap, uint32);
+		break;
+	case TIFFTAG_BITSPERSAMPLE:
+		td->td_bitspersample = (uint16) va_arg(ap, uint16_vap);
+		/*
+		 * If the data require post-decoding processing to byte-swap
+		 * samples, set it up here.  Note that since tags are required
+		 * to be ordered, compression code can override this behaviour
+		 * in the setup method if it wants to roll the post decoding
+		 * work in with its normal work.
+		 */
+		if (tif->tif_flags & TIFF_SWAB) {
+			if (td->td_bitspersample == 8)
+				tif->tif_postdecode = _TIFFNoPostDecode;
+			else if (td->td_bitspersample == 16)
+				tif->tif_postdecode = _TIFFSwab16BitData;
+			else if (td->td_bitspersample == 24)
+				tif->tif_postdecode = _TIFFSwab24BitData;
+			else if (td->td_bitspersample == 32)
+				tif->tif_postdecode = _TIFFSwab32BitData;
+			else if (td->td_bitspersample == 64)
+				tif->tif_postdecode = _TIFFSwab64BitData;
+			else if (td->td_bitspersample == 128) /* two 64's */
+				tif->tif_postdecode = _TIFFSwab64BitData;
+		}
+		break;
+	case TIFFTAG_COMPRESSION:
+		v = (uint16) va_arg(ap, uint16_vap);
+		/*
+		 * If we're changing the compression scheme, the notify the
+		 * previous module so that it can cleanup any state it's
+		 * setup.
+		 */
+		if (TIFFFieldSet(tif, FIELD_COMPRESSION)) {
+			if ((uint32)td->td_compression == v)
+				break;
+			(*tif->tif_cleanup)(tif);
+			tif->tif_flags &= ~TIFF_CODERSETUP;
+		}
+		/*
+		 * Setup new compression routine state.
+		 */
+		if( (status = TIFFSetCompressionScheme(tif, v)) != 0 )
+		    td->td_compression = (uint16) v;
+		else
+		    status = 0;
+		break;
+	case TIFFTAG_PHOTOMETRIC:
+		td->td_photometric = (uint16) va_arg(ap, uint16_vap);
+		break;
+	case TIFFTAG_THRESHHOLDING:
+		td->td_threshholding = (uint16) va_arg(ap, uint16_vap);
+		break;
+	case TIFFTAG_FILLORDER:
+		v = (uint16) va_arg(ap, uint16_vap);
+		if (v != FILLORDER_LSB2MSB && v != FILLORDER_MSB2LSB)
+			goto badvalue;
+		td->td_fillorder = (uint16) v;
+		break;
+	case TIFFTAG_ORIENTATION:
+		v = (uint16) va_arg(ap, uint16_vap);
+		if (v < ORIENTATION_TOPLEFT || ORIENTATION_LEFTBOT < v)
+			goto badvalue;
+		else
+			td->td_orientation = (uint16) v;
+		break;
+	case TIFFTAG_SAMPLESPERPIXEL:
+		v = (uint16) va_arg(ap, uint16_vap);
+		if (v == 0)
+			goto badvalue;
+		td->td_samplesperpixel = (uint16) v;
+		break;
+	case TIFFTAG_ROWSPERSTRIP:
+		v32 = (uint32) va_arg(ap, uint32);
+		if (v32 == 0)
+			goto badvalue32;
+		td->td_rowsperstrip = v32;
+		if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) {
+			td->td_tilelength = v32;
+			td->td_tilewidth = td->td_imagewidth;
+		}
+		break;
+	case TIFFTAG_MINSAMPLEVALUE:
+		td->td_minsamplevalue = (uint16) va_arg(ap, uint16_vap);
+		break;
+	case TIFFTAG_MAXSAMPLEVALUE:
+		td->td_maxsamplevalue = (uint16) va_arg(ap, uint16_vap);
+		break;
+	case TIFFTAG_SMINSAMPLEVALUE:
+		if (tif->tif_flags & TIFF_PERSAMPLE)
+			_TIFFsetDoubleArray(&td->td_sminsamplevalue, va_arg(ap, double*), td->td_samplesperpixel);
+		else
+			setDoubleArrayOneValue(&td->td_sminsamplevalue, va_arg(ap, double), td->td_samplesperpixel);
+		break;
+	case TIFFTAG_SMAXSAMPLEVALUE:
+		if (tif->tif_flags & TIFF_PERSAMPLE)
+			_TIFFsetDoubleArray(&td->td_smaxsamplevalue, va_arg(ap, double*), td->td_samplesperpixel);
+		else
+			setDoubleArrayOneValue(&td->td_smaxsamplevalue, va_arg(ap, double), td->td_samplesperpixel);
+		break;
+	case TIFFTAG_XRESOLUTION:
+        dblval = va_arg(ap, double);
+        if( dblval < 0 )
+            goto badvaluedouble;
+		td->td_xresolution = (float) dblval;
+		break;
+	case TIFFTAG_YRESOLUTION:
+        dblval = va_arg(ap, double);
+        if( dblval < 0 )
+            goto badvaluedouble;
+		td->td_yresolution = (float) dblval;
+		break;
+	case TIFFTAG_PLANARCONFIG:
+		v = (uint16) va_arg(ap, uint16_vap);
+		if (v != PLANARCONFIG_CONTIG && v != PLANARCONFIG_SEPARATE)
+			goto badvalue;
+		td->td_planarconfig = (uint16) v;
+		break;
+	case TIFFTAG_XPOSITION:
+		td->td_xposition = (float) va_arg(ap, double);
+		break;
+	case TIFFTAG_YPOSITION:
+		td->td_yposition = (float) va_arg(ap, double);
+		break;
+	case TIFFTAG_RESOLUTIONUNIT:
+		v = (uint16) va_arg(ap, uint16_vap);
+		if (v < RESUNIT_NONE || RESUNIT_CENTIMETER < v)
+			goto badvalue;
+		td->td_resolutionunit = (uint16) v;
+		break;
+	case TIFFTAG_PAGENUMBER:
+		td->td_pagenumber[0] = (uint16) va_arg(ap, uint16_vap);
+		td->td_pagenumber[1] = (uint16) va_arg(ap, uint16_vap);
+		break;
+	case TIFFTAG_HALFTONEHINTS:
+		td->td_halftonehints[0] = (uint16) va_arg(ap, uint16_vap);
+		td->td_halftonehints[1] = (uint16) va_arg(ap, uint16_vap);
+		break;
+	case TIFFTAG_COLORMAP:
+		v32 = (uint32)(1L<<td->td_bitspersample);
+		_TIFFsetShortArray(&td->td_colormap[0], va_arg(ap, uint16*), v32);
+		_TIFFsetShortArray(&td->td_colormap[1], va_arg(ap, uint16*), v32);
+		_TIFFsetShortArray(&td->td_colormap[2], va_arg(ap, uint16*), v32);
+		break;
+	case TIFFTAG_EXTRASAMPLES:
+		if (!setExtraSamples(td, ap, &v))
+			goto badvalue;
+		break;
+	case TIFFTAG_MATTEING:
+		td->td_extrasamples =  (((uint16) va_arg(ap, uint16_vap)) != 0);
+		if (td->td_extrasamples) {
+			uint16 sv = EXTRASAMPLE_ASSOCALPHA;
+			_TIFFsetShortArray(&td->td_sampleinfo, &sv, 1);
+		}
+		break;
+	case TIFFTAG_TILEWIDTH:
+		v32 = (uint32) va_arg(ap, uint32);
+		if (v32 % 16) {
+			if (tif->tif_mode != O_RDONLY)
+				goto badvalue32;
+			TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
+				"Nonstandard tile width %d, convert file", v32);
+		}
+		td->td_tilewidth = v32;
+		tif->tif_flags |= TIFF_ISTILED;
+		break;
+	case TIFFTAG_TILELENGTH:
+		v32 = (uint32) va_arg(ap, uint32);
+		if (v32 % 16) {
+			if (tif->tif_mode != O_RDONLY)
+				goto badvalue32;
+			TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
+			    "Nonstandard tile length %d, convert file", v32);
+		}
+		td->td_tilelength = v32;
+		tif->tif_flags |= TIFF_ISTILED;
+		break;
+	case TIFFTAG_TILEDEPTH:
+		v32 = (uint32) va_arg(ap, uint32);
+		if (v32 == 0)
+			goto badvalue32;
+		td->td_tiledepth = v32;
+		break;
+	case TIFFTAG_DATATYPE:
+		v = (uint16) va_arg(ap, uint16_vap);
+		switch (v) {
+		case DATATYPE_VOID:	v = SAMPLEFORMAT_VOID;	break;
+		case DATATYPE_INT:	v = SAMPLEFORMAT_INT;	break;
+		case DATATYPE_UINT:	v = SAMPLEFORMAT_UINT;	break;
+		case DATATYPE_IEEEFP:	v = SAMPLEFORMAT_IEEEFP;break;
+		default:		goto badvalue;
+		}
+		td->td_sampleformat = (uint16) v;
+		break;
+	case TIFFTAG_SAMPLEFORMAT:
+		v = (uint16) va_arg(ap, uint16_vap);
+		if (v < SAMPLEFORMAT_UINT || SAMPLEFORMAT_COMPLEXIEEEFP < v)
+			goto badvalue;
+		td->td_sampleformat = (uint16) v;
+
+		/*  Try to fix up the SWAB function for complex data. */
+		if( td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT
+		    && td->td_bitspersample == 32
+		    && tif->tif_postdecode == _TIFFSwab32BitData )
+		    tif->tif_postdecode = _TIFFSwab16BitData;
+		else if( (td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT
+			  || td->td_sampleformat == SAMPLEFORMAT_COMPLEXIEEEFP)
+			 && td->td_bitspersample == 64
+			 && tif->tif_postdecode == _TIFFSwab64BitData )
+		    tif->tif_postdecode = _TIFFSwab32BitData;
+		break;
+	case TIFFTAG_IMAGEDEPTH:
+		td->td_imagedepth = (uint32) va_arg(ap, uint32);
+		break;
+	case TIFFTAG_SUBIFD:
+		if ((tif->tif_flags & TIFF_INSUBIFD) == 0) {
+			td->td_nsubifd = (uint16) va_arg(ap, uint16_vap);
+			_TIFFsetLong8Array(&td->td_subifd, (uint64*) va_arg(ap, uint64*),
+			    (long) td->td_nsubifd);
+		} else {
+			TIFFErrorExt(tif->tif_clientdata, module,
+				     "%s: Sorry, cannot nest SubIFDs",
+				     tif->tif_name);
+			status = 0;
+		}
+		break;
+	case TIFFTAG_YCBCRPOSITIONING:
+		td->td_ycbcrpositioning = (uint16) va_arg(ap, uint16_vap);
+		break;
+	case TIFFTAG_YCBCRSUBSAMPLING:
+		td->td_ycbcrsubsampling[0] = (uint16) va_arg(ap, uint16_vap);
+		td->td_ycbcrsubsampling[1] = (uint16) va_arg(ap, uint16_vap);
+		break;
+	case TIFFTAG_TRANSFERFUNCTION:
+		v = (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1;
+		for (i = 0; i < v; i++)
+			_TIFFsetShortArray(&td->td_transferfunction[i],
+			    va_arg(ap, uint16*), 1L<<td->td_bitspersample);
+		break;
+	case TIFFTAG_REFERENCEBLACKWHITE:
+		/* XXX should check for null range */
+		_TIFFsetFloatArray(&td->td_refblackwhite, va_arg(ap, float*), 6);
+		break;
+	case TIFFTAG_INKNAMES:
+		v = (uint16) va_arg(ap, uint16_vap);
+		s = va_arg(ap, char*);
+		v = checkInkNamesString(tif, v, s);
+		status = v > 0;
+		if( v > 0 ) {
+			_TIFFsetNString(&td->td_inknames, s, v);
+			td->td_inknameslen = v;
+		}
+		break;
+	case TIFFTAG_PERSAMPLE:
+		v = (uint16) va_arg(ap, uint16_vap);
+		if( v == PERSAMPLE_MULTI )
+			tif->tif_flags |= TIFF_PERSAMPLE;
+		else
+			tif->tif_flags &= ~TIFF_PERSAMPLE;
+		break;
+	default: {
+		TIFFTagValue *tv;
+		int tv_size, iCustom;
+
+		/*
+		 * This can happen if multiple images are open with different
+		 * codecs which have private tags.  The global tag information
+		 * table may then have tags that are valid for one file but not
+		 * the other. If the client tries to set a tag that is not valid
+		 * for the image's codec then we'll arrive here.  This
+		 * happens, for example, when tiffcp is used to convert between
+		 * compression schemes and codec-specific tags are blindly copied.
+		 */
+		if(fip->field_bit != FIELD_CUSTOM) {
+			TIFFErrorExt(tif->tif_clientdata, module,
+			    "%s: Invalid %stag \"%s\" (not supported by codec)",
+			    tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "",
+			    fip->field_name);
+			status = 0;
+			break;
+		}
+
+		/*
+		 * Find the existing entry for this custom value.
+		 */
+		tv = NULL;
+		for (iCustom = 0; iCustom < td->td_customValueCount; iCustom++) {
+			if (td->td_customValues[iCustom].info->field_tag == tag) {
+				tv = td->td_customValues + iCustom;
+				if (tv->value != NULL) {
+					_TIFFfree(tv->value);
+					tv->value = NULL;
+				}
+				break;
+			}
+		}
+
+		/*
+		 * Grow the custom list if the entry was not found.
+		 */
+		if(tv == NULL) {
+			TIFFTagValue *new_customValues;
+
+			td->td_customValueCount++;
+			new_customValues = (TIFFTagValue *)
+			    _TIFFrealloc(td->td_customValues,
+			    sizeof(TIFFTagValue) * td->td_customValueCount);
+			if (!new_customValues) {
+				TIFFErrorExt(tif->tif_clientdata, module,
+				    "%s: Failed to allocate space for list of custom values",
+				    tif->tif_name);
+				status = 0;
+				goto end;
+			}
+
+			td->td_customValues = new_customValues;
+
+			tv = td->td_customValues + (td->td_customValueCount - 1);
+			tv->info = fip;
+			tv->value = NULL;
+			tv->count = 0;
+		}
+
+		/*
+		 * Set custom value ... save a copy of the custom tag value.
+		 */
+		tv_size = _TIFFDataSize(fip->field_type);
+		if (tv_size == 0) {
+			status = 0;
+			TIFFErrorExt(tif->tif_clientdata, module,
+			    "%s: Bad field type %d for \"%s\"",
+			    tif->tif_name, fip->field_type,
+			    fip->field_name);
+			goto end;
+		}
+
+		if (fip->field_type == TIFF_ASCII)
+		{
+			uint32 ma;
+			char* mb;
+			if (fip->field_passcount)
+			{
+				assert(fip->field_writecount==TIFF_VARIABLE2);
+				ma=(uint32)va_arg(ap,uint32);
+				mb=(char*)va_arg(ap,char*);
+			}
+			else
+			{
+				mb=(char*)va_arg(ap,char*);
+				ma=(uint32)(strlen(mb)+1);
+			}
+			tv->count=ma;
+			setByteArray(&tv->value,mb,ma,1);
+		}
+		else
+		{
+			if (fip->field_passcount) {
+				if (fip->field_writecount == TIFF_VARIABLE2)
+					tv->count = (uint32) va_arg(ap, uint32);
+				else
+					tv->count = (int) va_arg(ap, int);
+			} else if (fip->field_writecount == TIFF_VARIABLE
+			   || fip->field_writecount == TIFF_VARIABLE2)
+				tv->count = 1;
+			else if (fip->field_writecount == TIFF_SPP)
+				tv->count = td->td_samplesperpixel;
+			else
+				tv->count = fip->field_writecount;
+
+			if (tv->count == 0) {
+				status = 0;
+				TIFFErrorExt(tif->tif_clientdata, module,
+					     "%s: Null count for \"%s\" (type "
+					     "%d, writecount %d, passcount %d)",
+					     tif->tif_name,
+					     fip->field_name,
+					     fip->field_type,
+					     fip->field_writecount,
+					     fip->field_passcount);
+				goto end;
+			}
+
+			tv->value = _TIFFCheckMalloc(tif, tv->count, tv_size,
+			    "custom tag binary object");
+			if (!tv->value) {
+				status = 0;
+				goto end;
+			}
+
+			if (fip->field_tag == TIFFTAG_DOTRANGE 
+			    && strcmp(fip->field_name,"DotRange") == 0) {
+				/* TODO: This is an evil exception and should not have been
+				   handled this way ... likely best if we move it into
+				   the directory structure with an explicit field in 
+				   libtiff 4.1 and assign it a FIELD_ value */
+				uint16 v[2];
+				v[0] = (uint16)va_arg(ap, int);
+				v[1] = (uint16)va_arg(ap, int);
+				_TIFFmemcpy(tv->value, &v, 4);
+			}
+
+			else if (fip->field_passcount
+				  || fip->field_writecount == TIFF_VARIABLE
+				  || fip->field_writecount == TIFF_VARIABLE2
+				  || fip->field_writecount == TIFF_SPP
+				  || tv->count > 1) {
+				_TIFFmemcpy(tv->value, va_arg(ap, void *),
+				    tv->count * tv_size);
+			} else {
+				char *val = (char *)tv->value;
+				assert( tv->count == 1 );
+
+				switch (fip->field_type) {
+				case TIFF_BYTE:
+				case TIFF_UNDEFINED:
+					{
+						uint8 v = (uint8)va_arg(ap, int);
+						_TIFFmemcpy(val, &v, tv_size);
+					}
+					break;
+				case TIFF_SBYTE:
+					{
+						int8 v = (int8)va_arg(ap, int);
+						_TIFFmemcpy(val, &v, tv_size);
+					}
+					break;
+				case TIFF_SHORT:
+					{
+						uint16 v = (uint16)va_arg(ap, int);
+						_TIFFmemcpy(val, &v, tv_size);
+					}
+					break;
+				case TIFF_SSHORT:
+					{
+						int16 v = (int16)va_arg(ap, int);
+						_TIFFmemcpy(val, &v, tv_size);
+					}
+					break;
+				case TIFF_LONG:
+				case TIFF_IFD:
+					{
+						uint32 v = va_arg(ap, uint32);
+						_TIFFmemcpy(val, &v, tv_size);
+					}
+					break;
+				case TIFF_SLONG:
+					{
+						int32 v = va_arg(ap, int32);
+						_TIFFmemcpy(val, &v, tv_size);
+					}
+					break;
+				case TIFF_LONG8:
+				case TIFF_IFD8:
+					{
+						uint64 v = va_arg(ap, uint64);
+						_TIFFmemcpy(val, &v, tv_size);
+					}
+					break;
+				case TIFF_SLONG8:
+					{
+						int64 v = va_arg(ap, int64);
+						_TIFFmemcpy(val, &v, tv_size);
+					}
+					break;
+				case TIFF_RATIONAL:
+				case TIFF_SRATIONAL:
+				case TIFF_FLOAT:
+					{
+						float v = (float)va_arg(ap, double);
+						_TIFFmemcpy(val, &v, tv_size);
+					}
+					break;
+				case TIFF_DOUBLE:
+					{
+						double v = va_arg(ap, double);
+						_TIFFmemcpy(val, &v, tv_size);
+					}
+					break;
+				default:
+					_TIFFmemset(val, 0, tv_size);
+					status = 0;
+					break;
+				}
+			}
+		}
+	}
+	}
+	if (status) {
+		const TIFFField* fip=TIFFFieldWithTag(tif,tag);
+		if (fip)                
+			TIFFSetFieldBit(tif, fip->field_bit);
+		tif->tif_flags |= TIFF_DIRTYDIRECT;
+	}
+
+end:
+	va_end(ap);
+	return (status);
+badvalue:
+        {
+		const TIFFField* fip=TIFFFieldWithTag(tif,tag);
+		TIFFErrorExt(tif->tif_clientdata, module,
+		     "%s: Bad value %u for \"%s\" tag",
+		     tif->tif_name, v,
+		     fip ? fip->field_name : "Unknown");
+		va_end(ap);
+        }
+	return (0);
+badvalue32:
+        {
+		const TIFFField* fip=TIFFFieldWithTag(tif,tag);
+		TIFFErrorExt(tif->tif_clientdata, module,
+		     "%s: Bad value %u for \"%s\" tag",
+		     tif->tif_name, v32,
+		     fip ? fip->field_name : "Unknown");
+		va_end(ap);
+        }
+	return (0);
+badvaluedouble:
+        {
+        const TIFFField* fip=TIFFFieldWithTag(tif,tag);
+        TIFFErrorExt(tif->tif_clientdata, module,
+             "%s: Bad value %f for \"%s\" tag",
+             tif->tif_name, dblval,
+             fip ? fip->field_name : "Unknown");
+        va_end(ap);
+        }
+    return (0);
+}
+
+/*
+ * Return 1/0 according to whether or not
+ * it is permissible to set the tag's value.
+ * Note that we allow ImageLength to be changed
+ * so that we can append and extend to images.
+ * Any other tag may not be altered once writing
+ * has commenced, unless its value has no effect
+ * on the format of the data that is written.
+ */
+static int
+OkToChangeTag(TIFF* tif, uint32 tag)
+{
+	const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY);
+	if (!fip) {			/* unknown tag */
+		TIFFErrorExt(tif->tif_clientdata, "TIFFSetField", "%s: Unknown %stag %u",
+		    tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", tag);
+		return (0);
+	}
+	if (tag != TIFFTAG_IMAGELENGTH && (tif->tif_flags & TIFF_BEENWRITING) &&
+	    !fip->field_oktochange) {
+		/*
+		 * Consult info table to see if tag can be changed
+		 * after we've started writing.  We only allow changes
+		 * to those tags that don't/shouldn't affect the
+		 * compression and/or format of the data.
+		 */
+		TIFFErrorExt(tif->tif_clientdata, "TIFFSetField",
+		    "%s: Cannot modify tag \"%s\" while writing",
+		    tif->tif_name, fip->field_name);
+		return (0);
+	}
+	return (1);
+}
+
+/*
+ * Record the value of a field in the
+ * internal directory structure.  The
+ * field will be written to the file
+ * when/if the directory structure is
+ * updated.
+ */
+int
+TIFFSetField(TIFF* tif, uint32 tag, ...)
+{
+	va_list ap;
+	int status;
+
+	va_start(ap, tag);
+	status = TIFFVSetField(tif, tag, ap);
+	va_end(ap);
+	return (status);
+}
+
+/*
+ * Clear the contents of the field in the internal structure.
+ */
+int
+TIFFUnsetField(TIFF* tif, uint32 tag)
+{
+    const TIFFField *fip =  TIFFFieldWithTag(tif, tag);
+    TIFFDirectory* td = &tif->tif_dir;
+
+    if( !fip )
+        return 0;
+
+    if( fip->field_bit != FIELD_CUSTOM )
+        TIFFClrFieldBit(tif, fip->field_bit);
+    else
+    {
+        TIFFTagValue *tv = NULL;
+        int i;
+
+        for (i = 0; i < td->td_customValueCount; i++) {
+                
+            tv = td->td_customValues + i;
+            if( tv->info->field_tag == tag )
+                break;
+        }
+
+        if( i < td->td_customValueCount )
+        {
+            _TIFFfree(tv->value);
+            for( ; i < td->td_customValueCount-1; i++) {
+                td->td_customValues[i] = td->td_customValues[i+1];
+            }
+            td->td_customValueCount--;
+        }
+    }
+        
+    tif->tif_flags |= TIFF_DIRTYDIRECT;
+
+    return (1);
+}
+
+/*
+ * Like TIFFSetField, but taking a varargs
+ * parameter list.  This routine is useful
+ * for building higher-level interfaces on
+ * top of the library.
+ */
+int
+TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
+{
+	return OkToChangeTag(tif, tag) ?
+	    (*tif->tif_tagmethods.vsetfield)(tif, tag, ap) : 0;
+}
+
+static int
+_TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
+{
+	TIFFDirectory* td = &tif->tif_dir;
+	int ret_val = 1;
+	uint32 standard_tag = tag;
+	const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY);
+	if( fip == NULL ) /* cannot happen since TIFFGetField() already checks it */
+	    return 0;
+	
+	/*
+	 * We want to force the custom code to be used for custom
+	 * fields even if the tag happens to match a well known 
+	 * one - important for reinterpreted handling of standard
+	 * tag values in custom directories (ie. EXIF) 
+	 */
+	if (fip->field_bit == FIELD_CUSTOM) {
+		standard_tag = 0;
+	}
+
+	switch (standard_tag) {
+		case TIFFTAG_SUBFILETYPE:
+			*va_arg(ap, uint32*) = td->td_subfiletype;
+			break;
+		case TIFFTAG_IMAGEWIDTH:
+			*va_arg(ap, uint32*) = td->td_imagewidth;
+			break;
+		case TIFFTAG_IMAGELENGTH:
+			*va_arg(ap, uint32*) = td->td_imagelength;
+			break;
+		case TIFFTAG_BITSPERSAMPLE:
+			*va_arg(ap, uint16*) = td->td_bitspersample;
+			break;
+		case TIFFTAG_COMPRESSION:
+			*va_arg(ap, uint16*) = td->td_compression;
+			break;
+		case TIFFTAG_PHOTOMETRIC:
+			*va_arg(ap, uint16*) = td->td_photometric;
+			break;
+		case TIFFTAG_THRESHHOLDING:
+			*va_arg(ap, uint16*) = td->td_threshholding;
+			break;
+		case TIFFTAG_FILLORDER:
+			*va_arg(ap, uint16*) = td->td_fillorder;
+			break;
+		case TIFFTAG_ORIENTATION:
+			*va_arg(ap, uint16*) = td->td_orientation;
+			break;
+		case TIFFTAG_SAMPLESPERPIXEL:
+			*va_arg(ap, uint16*) = td->td_samplesperpixel;
+			break;
+		case TIFFTAG_ROWSPERSTRIP:
+			*va_arg(ap, uint32*) = td->td_rowsperstrip;
+			break;
+		case TIFFTAG_MINSAMPLEVALUE:
+			*va_arg(ap, uint16*) = td->td_minsamplevalue;
+			break;
+		case TIFFTAG_MAXSAMPLEVALUE:
+			*va_arg(ap, uint16*) = td->td_maxsamplevalue;
+			break;
+		case TIFFTAG_SMINSAMPLEVALUE:
+			if (tif->tif_flags & TIFF_PERSAMPLE)
+				*va_arg(ap, double**) = td->td_sminsamplevalue;
+			else
+			{
+				/* libtiff historially treats this as a single value. */
+				uint16 i;
+				double v = td->td_sminsamplevalue[0];
+				for (i=1; i < td->td_samplesperpixel; ++i)
+					if( td->td_sminsamplevalue[i] < v )
+						v = td->td_sminsamplevalue[i];
+				*va_arg(ap, double*) = v;
+			}
+			break;
+		case TIFFTAG_SMAXSAMPLEVALUE:
+			if (tif->tif_flags & TIFF_PERSAMPLE)
+				*va_arg(ap, double**) = td->td_smaxsamplevalue;
+			else
+			{
+				/* libtiff historially treats this as a single value. */
+				uint16 i;
+				double v = td->td_smaxsamplevalue[0];
+				for (i=1; i < td->td_samplesperpixel; ++i)
+					if( td->td_smaxsamplevalue[i] > v )
+						v = td->td_smaxsamplevalue[i];
+				*va_arg(ap, double*) = v;
+			}
+			break;
+		case TIFFTAG_XRESOLUTION:
+			*va_arg(ap, float*) = td->td_xresolution;
+			break;
+		case TIFFTAG_YRESOLUTION:
+			*va_arg(ap, float*) = td->td_yresolution;
+			break;
+		case TIFFTAG_PLANARCONFIG:
+			*va_arg(ap, uint16*) = td->td_planarconfig;
+			break;
+		case TIFFTAG_XPOSITION:
+			*va_arg(ap, float*) = td->td_xposition;
+			break;
+		case TIFFTAG_YPOSITION:
+			*va_arg(ap, float*) = td->td_yposition;
+			break;
+		case TIFFTAG_RESOLUTIONUNIT:
+			*va_arg(ap, uint16*) = td->td_resolutionunit;
+			break;
+		case TIFFTAG_PAGENUMBER:
+			*va_arg(ap, uint16*) = td->td_pagenumber[0];
+			*va_arg(ap, uint16*) = td->td_pagenumber[1];
+			break;
+		case TIFFTAG_HALFTONEHINTS:
+			*va_arg(ap, uint16*) = td->td_halftonehints[0];
+			*va_arg(ap, uint16*) = td->td_halftonehints[1];
+			break;
+		case TIFFTAG_COLORMAP:
+			*va_arg(ap, uint16**) = td->td_colormap[0];
+			*va_arg(ap, uint16**) = td->td_colormap[1];
+			*va_arg(ap, uint16**) = td->td_colormap[2];
+			break;
+		case TIFFTAG_STRIPOFFSETS:
+		case TIFFTAG_TILEOFFSETS:
+			_TIFFFillStriles( tif );
+			*va_arg(ap, uint64**) = td->td_stripoffset;
+			break;
+		case TIFFTAG_STRIPBYTECOUNTS:
+		case TIFFTAG_TILEBYTECOUNTS:
+			_TIFFFillStriles( tif );
+			*va_arg(ap, uint64**) = td->td_stripbytecount;
+			break;
+		case TIFFTAG_MATTEING:
+			*va_arg(ap, uint16*) =
+			    (td->td_extrasamples == 1 &&
+			    td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
+			break;
+		case TIFFTAG_EXTRASAMPLES:
+			*va_arg(ap, uint16*) = td->td_extrasamples;
+			*va_arg(ap, uint16**) = td->td_sampleinfo;
+			break;
+		case TIFFTAG_TILEWIDTH:
+			*va_arg(ap, uint32*) = td->td_tilewidth;
+			break;
+		case TIFFTAG_TILELENGTH:
+			*va_arg(ap, uint32*) = td->td_tilelength;
+			break;
+		case TIFFTAG_TILEDEPTH:
+			*va_arg(ap, uint32*) = td->td_tiledepth;
+			break;
+		case TIFFTAG_DATATYPE:
+			switch (td->td_sampleformat) {
+				case SAMPLEFORMAT_UINT:
+					*va_arg(ap, uint16*) = DATATYPE_UINT;
+					break;
+				case SAMPLEFORMAT_INT:
+					*va_arg(ap, uint16*) = DATATYPE_INT;
+					break;
+				case SAMPLEFORMAT_IEEEFP:
+					*va_arg(ap, uint16*) = DATATYPE_IEEEFP;
+					break;
+				case SAMPLEFORMAT_VOID:
+					*va_arg(ap, uint16*) = DATATYPE_VOID;
+					break;
+			}
+			break;
+		case TIFFTAG_SAMPLEFORMAT:
+			*va_arg(ap, uint16*) = td->td_sampleformat;
+			break;
+		case TIFFTAG_IMAGEDEPTH:
+			*va_arg(ap, uint32*) = td->td_imagedepth;
+			break;
+		case TIFFTAG_SUBIFD:
+			*va_arg(ap, uint16*) = td->td_nsubifd;
+			*va_arg(ap, uint64**) = td->td_subifd;
+			break;
+		case TIFFTAG_YCBCRPOSITIONING:
+			*va_arg(ap, uint16*) = td->td_ycbcrpositioning;
+			break;
+		case TIFFTAG_YCBCRSUBSAMPLING:
+			*va_arg(ap, uint16*) = td->td_ycbcrsubsampling[0];
+			*va_arg(ap, uint16*) = td->td_ycbcrsubsampling[1];
+			break;
+		case TIFFTAG_TRANSFERFUNCTION:
+			*va_arg(ap, uint16**) = td->td_transferfunction[0];
+			if (td->td_samplesperpixel - td->td_extrasamples > 1) {
+				*va_arg(ap, uint16**) = td->td_transferfunction[1];
+				*va_arg(ap, uint16**) = td->td_transferfunction[2];
+			}
+			break;
+		case TIFFTAG_REFERENCEBLACKWHITE:
+			*va_arg(ap, float**) = td->td_refblackwhite;
+			break;
+		case TIFFTAG_INKNAMES:
+			*va_arg(ap, char**) = td->td_inknames;
+			break;
+		default:
+			{
+				int i;
+
+				/*
+				 * This can happen if multiple images are open
+				 * with different codecs which have private
+				 * tags.  The global tag information table may
+				 * then have tags that are valid for one file
+				 * but not the other. If the client tries to
+				 * get a tag that is not valid for the image's
+				 * codec then we'll arrive here.
+				 */
+				if( fip->field_bit != FIELD_CUSTOM )
+				{
+					TIFFErrorExt(tif->tif_clientdata, "_TIFFVGetField",
+					    "%s: Invalid %stag \"%s\" "
+					    "(not supported by codec)",
+					    tif->tif_name,
+					    isPseudoTag(tag) ? "pseudo-" : "",
+					    fip->field_name);
+					ret_val = 0;
+					break;
+				}
+
+				/*
+				 * Do we have a custom value?
+				 */
+				ret_val = 0;
+				for (i = 0; i < td->td_customValueCount; i++) {
+					TIFFTagValue *tv = td->td_customValues + i;
+
+					if (tv->info->field_tag != tag)
+						continue;
+
+					if (fip->field_passcount) {
+						if (fip->field_readcount == TIFF_VARIABLE2)
+							*va_arg(ap, uint32*) = (uint32)tv->count;
+						else  /* Assume TIFF_VARIABLE */
+							*va_arg(ap, uint16*) = (uint16)tv->count;
+						*va_arg(ap, void **) = tv->value;
+						ret_val = 1;
+					} else if (fip->field_tag == TIFFTAG_DOTRANGE
+						   && strcmp(fip->field_name,"DotRange") == 0) {
+						/* TODO: This is an evil exception and should not have been
+						   handled this way ... likely best if we move it into
+						   the directory structure with an explicit field in 
+						   libtiff 4.1 and assign it a FIELD_ value */
+						*va_arg(ap, uint16*) = ((uint16 *)tv->value)[0];
+						*va_arg(ap, uint16*) = ((uint16 *)tv->value)[1];
+						ret_val = 1;
+					} else {
+						if (fip->field_type == TIFF_ASCII
+						    || fip->field_readcount == TIFF_VARIABLE
+						    || fip->field_readcount == TIFF_VARIABLE2
+						    || fip->field_readcount == TIFF_SPP
+						    || tv->count > 1) {
+							*va_arg(ap, void **) = tv->value;
+							ret_val = 1;
+						} else {
+							char *val = (char *)tv->value;
+							assert( tv->count == 1 );
+							switch (fip->field_type) {
+							case TIFF_BYTE:
+							case TIFF_UNDEFINED:
+								*va_arg(ap, uint8*) =
+									*(uint8 *)val;
+								ret_val = 1;
+								break;
+							case TIFF_SBYTE:
+								*va_arg(ap, int8*) =
+									*(int8 *)val;
+								ret_val = 1;
+								break;
+							case TIFF_SHORT:
+								*va_arg(ap, uint16*) =
+									*(uint16 *)val;
+								ret_val = 1;
+								break;
+							case TIFF_SSHORT:
+								*va_arg(ap, int16*) =
+									*(int16 *)val;
+								ret_val = 1;
+								break;
+							case TIFF_LONG:
+							case TIFF_IFD:
+								*va_arg(ap, uint32*) =
+									*(uint32 *)val;
+								ret_val = 1;
+								break;
+							case TIFF_SLONG:
+								*va_arg(ap, int32*) =
+									*(int32 *)val;
+								ret_val = 1;
+								break;
+							case TIFF_LONG8:
+							case TIFF_IFD8:
+								*va_arg(ap, uint64*) =
+									*(uint64 *)val;
+								ret_val = 1;
+								break;
+							case TIFF_SLONG8:
+								*va_arg(ap, int64*) =
+									*(int64 *)val;
+								ret_val = 1;
+								break;
+							case TIFF_RATIONAL:
+							case TIFF_SRATIONAL:
+							case TIFF_FLOAT:
+								*va_arg(ap, float*) =
+									*(float *)val;
+								ret_val = 1;
+								break;
+							case TIFF_DOUBLE:
+								*va_arg(ap, double*) =
+									*(double *)val;
+								ret_val = 1;
+								break;
+							default:
+								ret_val = 0;
+								break;
+							}
+						}
+					}
+					break;
+				}
+			}
+	}
+	return(ret_val);
+}
+
+/*
+ * Return the value of a field in the
+ * internal directory structure.
+ */
+int
+TIFFGetField(TIFF* tif, uint32 tag, ...)
+{
+	int status;
+	va_list ap;
+
+	va_start(ap, tag);
+	status = TIFFVGetField(tif, tag, ap);
+	va_end(ap);
+	return (status);
+}
+
+/*
+ * Like TIFFGetField, but taking a varargs
+ * parameter list.  This routine is useful
+ * for building higher-level interfaces on
+ * top of the library.
+ */
+int
+TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
+{
+	const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY);
+	return (fip && (isPseudoTag(tag) || TIFFFieldSet(tif, fip->field_bit)) ?
+	    (*tif->tif_tagmethods.vgetfield)(tif, tag, ap) : 0);
+}
+
+#define	CleanupField(member) {		\
+    if (td->member) {			\
+	_TIFFfree(td->member);		\
+	td->member = 0;			\
+    }					\
+}
+
+/*
+ * Release storage associated with a directory.
+ */
+void
+TIFFFreeDirectory(TIFF* tif)
+{
+	TIFFDirectory *td = &tif->tif_dir;
+	int            i;
+
+	_TIFFmemset(td->td_fieldsset, 0, FIELD_SETLONGS);
+	CleanupField(td_sminsamplevalue);
+	CleanupField(td_smaxsamplevalue);
+	CleanupField(td_colormap[0]);
+	CleanupField(td_colormap[1]);
+	CleanupField(td_colormap[2]);
+	CleanupField(td_sampleinfo);
+	CleanupField(td_subifd);
+	CleanupField(td_inknames);
+	CleanupField(td_refblackwhite);
+	CleanupField(td_transferfunction[0]);
+	CleanupField(td_transferfunction[1]);
+	CleanupField(td_transferfunction[2]);
+	CleanupField(td_stripoffset);
+	CleanupField(td_stripbytecount);
+	TIFFClrFieldBit(tif, FIELD_YCBCRSUBSAMPLING);
+	TIFFClrFieldBit(tif, FIELD_YCBCRPOSITIONING);
+
+	/* Cleanup custom tag values */
+	for( i = 0; i < td->td_customValueCount; i++ ) {
+		if (td->td_customValues[i].value)
+			_TIFFfree(td->td_customValues[i].value);
+	}
+
+	td->td_customValueCount = 0;
+	CleanupField(td_customValues);
+
+#if defined(DEFER_STRILE_LOAD)
+        _TIFFmemset( &(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry));
+        _TIFFmemset( &(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry));
+#endif        
+}
+#undef CleanupField
+
+/*
+ * Client Tag extension support (from Niles Ritter).
+ */
+static TIFFExtendProc _TIFFextender = (TIFFExtendProc) NULL;
+
+TIFFExtendProc
+TIFFSetTagExtender(TIFFExtendProc extender)
+{
+	TIFFExtendProc prev = _TIFFextender;
+	_TIFFextender = extender;
+	return (prev);
+}
+
+/*
+ * Setup for a new directory.  Should we automatically call
+ * TIFFWriteDirectory() if the current one is dirty?
+ *
+ * The newly created directory will not exist on the file till
+ * TIFFWriteDirectory(), TIFFFlush() or TIFFClose() is called.
+ */
+int
+TIFFCreateDirectory(TIFF* tif)
+{
+	TIFFDefaultDirectory(tif);
+	tif->tif_diroff = 0;
+	tif->tif_nextdiroff = 0;
+	tif->tif_curoff = 0;
+	tif->tif_row = (uint32) -1;
+	tif->tif_curstrip = (uint32) -1;
+
+	return 0;
+}
+
+int
+TIFFCreateCustomDirectory(TIFF* tif, const TIFFFieldArray* infoarray)
+{
+	TIFFDefaultDirectory(tif);
+
+	/*
+	 * Reset the field definitions to match the application provided list. 
+	 * Hopefully TIFFDefaultDirectory() won't have done anything irreversable
+	 * based on it's assumption this is an image directory.
+	 */
+	_TIFFSetupFields(tif, infoarray);
+
+	tif->tif_diroff = 0;
+	tif->tif_nextdiroff = 0;
+	tif->tif_curoff = 0;
+	tif->tif_row = (uint32) -1;
+	tif->tif_curstrip = (uint32) -1;
+
+	return 0;
+}
+
+int
+TIFFCreateEXIFDirectory(TIFF* tif)
+{
+	const TIFFFieldArray* exifFieldArray;
+	exifFieldArray = _TIFFGetExifFields();
+	return TIFFCreateCustomDirectory(tif, exifFieldArray);
+}
+
+/*
+ * Setup a default directory structure.
+ */
+int
+TIFFDefaultDirectory(TIFF* tif)
+{
+	register TIFFDirectory* td = &tif->tif_dir;
+	const TIFFFieldArray* tiffFieldArray;
+
+	tiffFieldArray = _TIFFGetFields();
+	_TIFFSetupFields(tif, tiffFieldArray);   
+
+	_TIFFmemset(td, 0, sizeof (*td));
+	td->td_fillorder = FILLORDER_MSB2LSB;
+	td->td_bitspersample = 1;
+	td->td_threshholding = THRESHHOLD_BILEVEL;
+	td->td_orientation = ORIENTATION_TOPLEFT;
+	td->td_samplesperpixel = 1;
+	td->td_rowsperstrip = (uint32) -1;
+	td->td_tilewidth = 0;
+	td->td_tilelength = 0;
+	td->td_tiledepth = 1;
+	td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */  
+	td->td_resolutionunit = RESUNIT_INCH;
+	td->td_sampleformat = SAMPLEFORMAT_UINT;
+	td->td_imagedepth = 1;
+	td->td_ycbcrsubsampling[0] = 2;
+	td->td_ycbcrsubsampling[1] = 2;
+	td->td_ycbcrpositioning = YCBCRPOSITION_CENTERED;
+	tif->tif_postdecode = _TIFFNoPostDecode;  
+	tif->tif_foundfield = NULL;
+	tif->tif_tagmethods.vsetfield = _TIFFVSetField;  
+	tif->tif_tagmethods.vgetfield = _TIFFVGetField;
+	tif->tif_tagmethods.printdir = NULL;
+	/*
+	 *  Give client code a chance to install their own
+	 *  tag extensions & methods, prior to compression overloads,
+	 *  but do some prior cleanup first. (http://trac.osgeo.org/gdal/ticket/5054)
+	 */
+	if (tif->tif_nfieldscompat > 0) {
+		uint32 i;
+
+		for (i = 0; i < tif->tif_nfieldscompat; i++) {
+				if (tif->tif_fieldscompat[i].allocated_size)
+						_TIFFfree(tif->tif_fieldscompat[i].fields);
+		}
+		_TIFFfree(tif->tif_fieldscompat);
+		tif->tif_nfieldscompat = 0;
+		tif->tif_fieldscompat = NULL;
+	}
+	if (_TIFFextender)
+		(*_TIFFextender)(tif);
+	(void) TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
+	/*
+	 * NB: The directory is marked dirty as a result of setting
+	 * up the default compression scheme.  However, this really
+	 * isn't correct -- we want TIFF_DIRTYDIRECT to be set only
+	 * if the user does something.  We could just do the setup
+	 * by hand, but it seems better to use the normal mechanism
+	 * (i.e. TIFFSetField).
+	 */
+	tif->tif_flags &= ~TIFF_DIRTYDIRECT;
+
+	/*
+	 * As per http://bugzilla.remotesensing.org/show_bug.cgi?id=19
+	 * we clear the ISTILED flag when setting up a new directory.
+	 * Should we also be clearing stuff like INSUBIFD?
+	 */
+	tif->tif_flags &= ~TIFF_ISTILED;
+
+	return (1);
+}
+
+static int
+TIFFAdvanceDirectory(TIFF* tif, uint64* nextdir, uint64* off)
+{
+	static const char module[] = "TIFFAdvanceDirectory";
+	if (isMapped(tif))
+	{
+		uint64 poff=*nextdir;
+		if (!(tif->tif_flags&TIFF_BIGTIFF))
+		{
+			tmsize_t poffa,poffb,poffc,poffd;
+			uint16 dircount;
+			uint32 nextdir32;
+			poffa=(tmsize_t)poff;
+			poffb=poffa+sizeof(uint16);
+			if (((uint64)poffa!=poff)||(poffb<poffa)||(poffb<(tmsize_t)sizeof(uint16))||(poffb>tif->tif_size))
+			{
+				TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory count");
+                                  *nextdir=0;
+				return(0);
+			}
+			_TIFFmemcpy(&dircount,tif->tif_base+poffa,sizeof(uint16));
+			if (tif->tif_flags&TIFF_SWAB)
+				TIFFSwabShort(&dircount);
+			poffc=poffb+dircount*12;
+			poffd=poffc+sizeof(uint32);
+			if ((poffc<poffb)||(poffc<dircount*12)||(poffd<poffc)||(poffd<(tmsize_t)sizeof(uint32))||(poffd>tif->tif_size))
+			{
+				TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory link");
+				return(0);
+			}
+			if (off!=NULL)
+				*off=(uint64)poffc;
+			_TIFFmemcpy(&nextdir32,tif->tif_base+poffc,sizeof(uint32));
+			if (tif->tif_flags&TIFF_SWAB)
+				TIFFSwabLong(&nextdir32);
+			*nextdir=nextdir32;
+		}
+		else
+		{
+			tmsize_t poffa,poffb,poffc,poffd;
+			uint64 dircount64;
+			uint16 dircount16;
+			poffa=(tmsize_t)poff;
+			poffb=poffa+sizeof(uint64);
+			if (((uint64)poffa!=poff)||(poffb<poffa)||(poffb<(tmsize_t)sizeof(uint64))||(poffb>tif->tif_size))
+			{
+				TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory count");
+				return(0);
+			}
+			_TIFFmemcpy(&dircount64,tif->tif_base+poffa,sizeof(uint64));
+			if (tif->tif_flags&TIFF_SWAB)
+				TIFFSwabLong8(&dircount64);
+			if (dircount64>0xFFFF)
+			{
+				TIFFErrorExt(tif->tif_clientdata,module,"Sanity check on directory count failed");
+				return(0);
+			}
+			dircount16=(uint16)dircount64;
+			poffc=poffb+dircount16*20;
+			poffd=poffc+sizeof(uint64);
+			if ((poffc<poffb)||(poffc<dircount16*20)||(poffd<poffc)||(poffd<(tmsize_t)sizeof(uint64))||(poffd>tif->tif_size))
+			{
+				TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory link");
+				return(0);
+			}
+			if (off!=NULL)
+				*off=(uint64)poffc;
+			_TIFFmemcpy(nextdir,tif->tif_base+poffc,sizeof(uint64));
+			if (tif->tif_flags&TIFF_SWAB)
+				TIFFSwabLong8(nextdir);
+		}
+		return(1);
+	}
+	else
+	{
+		if (!(tif->tif_flags&TIFF_BIGTIFF))
+		{
+			uint16 dircount;
+			uint32 nextdir32;
+			if (!SeekOK(tif, *nextdir) ||
+			    !ReadOK(tif, &dircount, sizeof (uint16))) {
+				TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count",
+				    tif->tif_name);
+				return (0);
+			}
+			if (tif->tif_flags & TIFF_SWAB)
+				TIFFSwabShort(&dircount);
+			if (off != NULL)
+				*off = TIFFSeekFile(tif,
+				    dircount*12, SEEK_CUR);
+			else
+				(void) TIFFSeekFile(tif,
+				    dircount*12, SEEK_CUR);
+			if (!ReadOK(tif, &nextdir32, sizeof (uint32))) {
+				TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory link",
+				    tif->tif_name);
+				return (0);
+			}
+			if (tif->tif_flags & TIFF_SWAB)
+				TIFFSwabLong(&nextdir32);
+			*nextdir=nextdir32;
+		}
+		else
+		{
+			uint64 dircount64;
+			uint16 dircount16;
+			if (!SeekOK(tif, *nextdir) ||
+			    !ReadOK(tif, &dircount64, sizeof (uint64))) {
+				TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count",
+				    tif->tif_name);
+				return (0);
+			}
+			if (tif->tif_flags & TIFF_SWAB)
+				TIFFSwabLong8(&dircount64);
+			if (dircount64>0xFFFF)
+			{
+				TIFFErrorExt(tif->tif_clientdata, module, "Error fetching directory count");
+				return(0);
+			}
+			dircount16 = (uint16)dircount64;
+			if (off != NULL)
+				*off = TIFFSeekFile(tif,
+				    dircount16*20, SEEK_CUR);
+			else
+				(void) TIFFSeekFile(tif,
+				    dircount16*20, SEEK_CUR);
+			if (!ReadOK(tif, nextdir, sizeof (uint64))) {
+				TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory link",
+				    tif->tif_name);
+				return (0);
+			}
+			if (tif->tif_flags & TIFF_SWAB)
+				TIFFSwabLong8(nextdir);
+		}
+		return (1);
+	}
+}
+
+/*
+ * Count the number of directories in a file.
+ */
+uint16
+TIFFNumberOfDirectories(TIFF* tif)
+{
+	static const char module[] = "TIFFNumberOfDirectories";
+	uint64 nextdir;
+	uint16 n;
+	if (!(tif->tif_flags&TIFF_BIGTIFF))
+		nextdir = tif->tif_header.classic.tiff_diroff;
+	else
+		nextdir = tif->tif_header.big.tiff_diroff;
+	n = 0;
+	while (nextdir != 0 && TIFFAdvanceDirectory(tif, &nextdir, NULL))
+        {
+		if(++n == 0)
+                {
+                        TIFFErrorExt(tif->tif_clientdata, module,
+                                     "Directory count exceeded 65535 limit, giving up on counting.");
+                        return (65535);
+                }
+        }
+	return (n);
+}
+
+/*
+ * Set the n-th directory as the current directory.
+ * NB: Directories are numbered starting at 0.
+ */
+int
+TIFFSetDirectory(TIFF* tif, uint16 dirn)
+{
+	uint64 nextdir;
+	uint16 n;
+
+	if (!(tif->tif_flags&TIFF_BIGTIFF))
+		nextdir = tif->tif_header.classic.tiff_diroff;
+	else
+		nextdir = tif->tif_header.big.tiff_diroff;
+	for (n = dirn; n > 0 && nextdir != 0; n--)
+		if (!TIFFAdvanceDirectory(tif, &nextdir, NULL))
+			return (0);
+	tif->tif_nextdiroff = nextdir;
+	/*
+	 * Set curdir to the actual directory index.  The
+	 * -1 is because TIFFReadDirectory will increment
+	 * tif_curdir after successfully reading the directory.
+	 */
+	tif->tif_curdir = (dirn - n) - 1;
+	/*
+	 * Reset tif_dirnumber counter and start new list of seen directories.
+	 * We need this to prevent IFD loops.
+	 */
+	tif->tif_dirnumber = 0;
+	return (TIFFReadDirectory(tif));
+}
+
+/*
+ * Set the current directory to be the directory
+ * located at the specified file offset.  This interface
+ * is used mainly to access directories linked with
+ * the SubIFD tag (e.g. thumbnail images).
+ */
+int
+TIFFSetSubDirectory(TIFF* tif, uint64 diroff)
+{
+	tif->tif_nextdiroff = diroff;
+	/*
+	 * Reset tif_dirnumber counter and start new list of seen directories.
+	 * We need this to prevent IFD loops.
+	 */
+	tif->tif_dirnumber = 0;
+	return (TIFFReadDirectory(tif));
+}
+
+/*
+ * Return file offset of the current directory.
+ */
+uint64
+TIFFCurrentDirOffset(TIFF* tif)
+{
+	return (tif->tif_diroff);
+}
+
+/*
+ * Return an indication of whether or not we are
+ * at the last directory in the file.
+ */
+int
+TIFFLastDirectory(TIFF* tif)
+{
+	return (tif->tif_nextdiroff == 0);
+}
+
+/*
+ * Unlink the specified directory from the directory chain.
+ */
+int
+TIFFUnlinkDirectory(TIFF* tif, uint16 dirn)
+{
+	static const char module[] = "TIFFUnlinkDirectory";
+	uint64 nextdir;
+	uint64 off;
+	uint16 n;
+
+	if (tif->tif_mode == O_RDONLY) {
+		TIFFErrorExt(tif->tif_clientdata, module,
+                             "Can not unlink directory in read-only file");
+		return (0);
+	}
+	/*
+	 * Go to the directory before the one we want
+	 * to unlink and nab the offset of the link
+	 * field we'll need to patch.
+	 */
+	if (!(tif->tif_flags&TIFF_BIGTIFF))
+	{
+		nextdir = tif->tif_header.classic.tiff_diroff;
+		off = 4;
+	}
+	else
+	{
+		nextdir = tif->tif_header.big.tiff_diroff;
+		off = 8;
+	}
+	for (n = dirn-1; n > 0; n--) {
+		if (nextdir == 0) {
+			TIFFErrorExt(tif->tif_clientdata, module, "Directory %d does not exist", dirn);
+			return (0);
+		}
+		if (!TIFFAdvanceDirectory(tif, &nextdir, &off))
+			return (0);
+	}
+	/*
+	 * Advance to the directory to be unlinked and fetch
+	 * the offset of the directory that follows.
+	 */
+	if (!TIFFAdvanceDirectory(tif, &nextdir, NULL))
+		return (0);
+	/*
+	 * Go back and patch the link field of the preceding
+	 * directory to point to the offset of the directory
+	 * that follows.
+	 */
+	(void) TIFFSeekFile(tif, off, SEEK_SET);
+	if (!(tif->tif_flags&TIFF_BIGTIFF))
+	{
+		uint32 nextdir32;
+		nextdir32=(uint32)nextdir;
+		assert((uint64)nextdir32==nextdir);
+		if (tif->tif_flags & TIFF_SWAB)
+			TIFFSwabLong(&nextdir32);
+		if (!WriteOK(tif, &nextdir32, sizeof (uint32))) {
+			TIFFErrorExt(tif->tif_clientdata, module, "Error writing directory link");
+			return (0);
+		}
+	}
+	else
+	{
+		if (tif->tif_flags & TIFF_SWAB)
+			TIFFSwabLong8(&nextdir);
+		if (!WriteOK(tif, &nextdir, sizeof (uint64))) {
+			TIFFErrorExt(tif->tif_clientdata, module, "Error writing directory link");
+			return (0);
+		}
+	}
+	/*
+	 * Leave directory state setup safely.  We don't have
+	 * facilities for doing inserting and removing directories,
+	 * so it's safest to just invalidate everything.  This
+	 * means that the caller can only append to the directory
+	 * chain.
+	 */
+	(*tif->tif_cleanup)(tif);
+	if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
+		_TIFFfree(tif->tif_rawdata);
+		tif->tif_rawdata = NULL;
+		tif->tif_rawcc = 0;
+                tif->tif_rawdataoff = 0;
+                tif->tif_rawdataloaded = 0;
+	}
+	tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP|TIFF_POSTENCODE|TIFF_BUF4WRITE);
+	TIFFFreeDirectory(tif);
+	TIFFDefaultDirectory(tif);
+	tif->tif_diroff = 0;			/* force link on next write */
+	tif->tif_nextdiroff = 0;		/* next write must be at end */
+	tif->tif_curoff = 0;
+	tif->tif_row = (uint32) -1;
+	tif->tif_curstrip = (uint32) -1;
+	return (1);
+}
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tif_dir.h b/Source/LibTIFF4/tif_dir.h
index 410dab2..ae060b0 100644
--- a/Source/LibTIFF4/tif_dir.h
+++ b/Source/LibTIFF4/tif_dir.h
@@ -1,308 +1,308 @@
-/* $Id: tif_dir.h,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-#ifndef _TIFFDIR_
-#define	_TIFFDIR_
-/*
- * ``Library-private'' Directory-related Definitions.
- */
-
-typedef struct {
-	const TIFFField *info;
-	int             count;
-	void           *value;
-} TIFFTagValue;
-
-/*
- * TIFF Image File Directories are comprised of a table of field
- * descriptors of the form shown below.  The table is sorted in
- * ascending order by tag.  The values associated with each entry are
- * disjoint and may appear anywhere in the file (so long as they are
- * placed on a word boundary).
- *
- * If the value is 4 bytes or less, in ClassicTIFF, or 8 bytes or less in
- * BigTIFF, then it is placed in the offset field to save space. If so,
- * it is left-justified in the offset field.
- */
-typedef struct {
-	uint16 tdir_tag;        /* see below */
-	uint16 tdir_type;       /* data type; see below */
-	uint64 tdir_count;      /* number of items; length in spec */
-	union {
-		uint16 toff_short;
-		uint32 toff_long;
-		uint64 toff_long8;
-	} tdir_offset;		/* either offset or the data itself if fits */
-} TIFFDirEntry;
-
-/*
- * Internal format of a TIFF directory entry.
- */
-typedef struct {
-#define FIELD_SETLONGS 4
-	/* bit vector of fields that are set */
-	unsigned long td_fieldsset[FIELD_SETLONGS];
-
-	uint32  td_imagewidth, td_imagelength, td_imagedepth;
-	uint32  td_tilewidth, td_tilelength, td_tiledepth;
-	uint32  td_subfiletype;
-	uint16  td_bitspersample;
-	uint16  td_sampleformat;
-	uint16  td_compression;
-	uint16  td_photometric;
-	uint16  td_threshholding;
-	uint16  td_fillorder;
-	uint16  td_orientation;
-	uint16  td_samplesperpixel;
-	uint32  td_rowsperstrip;
-	uint16  td_minsamplevalue, td_maxsamplevalue;
-	double* td_sminsamplevalue;
-	double* td_smaxsamplevalue;
-	float   td_xresolution, td_yresolution;
-	uint16  td_resolutionunit;
-	uint16  td_planarconfig;
-	float   td_xposition, td_yposition;
-	uint16  td_pagenumber[2];
-	uint16* td_colormap[3];
-	uint16  td_halftonehints[2];
-	uint16  td_extrasamples;
-	uint16* td_sampleinfo;
-	/* even though the name is misleading, td_stripsperimage is the number
-	 * of striles (=strips or tiles) per plane, and td_nstrips the total
-	 * number of striles */
-	uint32  td_stripsperimage;  
-	uint32  td_nstrips;              /* size of offset & bytecount arrays */
-	uint64* td_stripoffset;
-	uint64* td_stripbytecount;
-	int     td_stripbytecountsorted; /* is the bytecount array sorted ascending? */
-#if defined(DEFER_STRILE_LOAD)
-        TIFFDirEntry td_stripoffset_entry;    /* for deferred loading */
-        TIFFDirEntry td_stripbytecount_entry; /* for deferred loading */
-#endif
-	uint16  td_nsubifd;
-	uint64* td_subifd;
-	/* YCbCr parameters */
-	uint16  td_ycbcrsubsampling[2];
-	uint16  td_ycbcrpositioning;
-	/* Colorimetry parameters */
-	uint16* td_transferfunction[3];
-	float*	td_refblackwhite;
-	/* CMYK parameters */
-	int     td_inknameslen;
-	char*   td_inknames;
-
-	int     td_customValueCount;
-        TIFFTagValue *td_customValues;
-} TIFFDirectory;
-
-/*
- * Field flags used to indicate fields that have been set in a directory, and
- * to reference fields when manipulating a directory.
- */
-
-/*
- * FIELD_IGNORE is used to signify tags that are to be processed but otherwise
- * ignored.  This permits antiquated tags to be quietly read and discarded.
- * Note that a bit *is* allocated for ignored tags; this is understood by the
- * directory reading logic which uses this fact to avoid special-case handling
- */
-#define FIELD_IGNORE                   0
-
-/* multi-item fields */
-#define FIELD_IMAGEDIMENSIONS          1
-#define FIELD_TILEDIMENSIONS           2
-#define FIELD_RESOLUTION               3
-#define FIELD_POSITION                 4
-
-/* single-item fields */
-#define FIELD_SUBFILETYPE              5
-#define FIELD_BITSPERSAMPLE            6
-#define FIELD_COMPRESSION              7
-#define FIELD_PHOTOMETRIC              8
-#define FIELD_THRESHHOLDING            9
-#define FIELD_FILLORDER                10
-#define FIELD_ORIENTATION              15
-#define FIELD_SAMPLESPERPIXEL          16
-#define FIELD_ROWSPERSTRIP             17
-#define FIELD_MINSAMPLEVALUE           18
-#define FIELD_MAXSAMPLEVALUE           19
-#define FIELD_PLANARCONFIG             20
-#define FIELD_RESOLUTIONUNIT           22
-#define FIELD_PAGENUMBER               23
-#define FIELD_STRIPBYTECOUNTS          24
-#define FIELD_STRIPOFFSETS             25
-#define FIELD_COLORMAP                 26
-#define FIELD_EXTRASAMPLES             31
-#define FIELD_SAMPLEFORMAT             32
-#define FIELD_SMINSAMPLEVALUE          33
-#define FIELD_SMAXSAMPLEVALUE          34
-#define FIELD_IMAGEDEPTH               35
-#define FIELD_TILEDEPTH                36
-#define FIELD_HALFTONEHINTS            37
-#define FIELD_YCBCRSUBSAMPLING         39
-#define FIELD_YCBCRPOSITIONING         40
-#define	FIELD_REFBLACKWHITE            41
-#define FIELD_TRANSFERFUNCTION         44
-#define FIELD_INKNAMES                 46
-#define FIELD_SUBIFD                   49
-/*      FIELD_CUSTOM (see tiffio.h)    65 */
-/* end of support for well-known tags; codec-private tags follow */
-#define FIELD_CODEC                    66  /* base of codec-private tags */
-
-
-/*
- * Pseudo-tags don't normally need field bits since they are not written to an
- * output file (by definition). The library also has express logic to always
- * query a codec for a pseudo-tag so allocating a field bit for one is a
- * waste.   If codec wants to promote the notion of a pseudo-tag being ``set''
- * or ``unset'' then it can do using internal state flags without polluting
- * the field bit space defined for real tags.
- */
-#define FIELD_PSEUDO			0
-
-#define FIELD_LAST			(32*FIELD_SETLONGS-1)
-
-#define BITn(n)				(((unsigned long)1L)<<((n)&0x1f))
-#define BITFIELDn(tif, n)		((tif)->tif_dir.td_fieldsset[(n)/32])
-#define TIFFFieldSet(tif, field)	(BITFIELDn(tif, field) & BITn(field))
-#define TIFFSetFieldBit(tif, field)	(BITFIELDn(tif, field) |= BITn(field))
-#define TIFFClrFieldBit(tif, field)	(BITFIELDn(tif, field) &= ~BITn(field))
-
-#define FieldSet(fields, f)		(fields[(f)/32] & BITn(f))
-#define ResetFieldBit(fields, f)	(fields[(f)/32] &= ~BITn(f))
-
-typedef enum {
-	TIFF_SETGET_UNDEFINED = 0,
-	TIFF_SETGET_ASCII = 1,
-	TIFF_SETGET_UINT8 = 2,
-	TIFF_SETGET_SINT8 = 3,
-	TIFF_SETGET_UINT16 = 4,
-	TIFF_SETGET_SINT16 = 5,
-	TIFF_SETGET_UINT32 = 6,
-	TIFF_SETGET_SINT32 = 7,
-	TIFF_SETGET_UINT64 = 8,
-	TIFF_SETGET_SINT64 = 9,
-	TIFF_SETGET_FLOAT = 10,
-	TIFF_SETGET_DOUBLE = 11,
-	TIFF_SETGET_IFD8 = 12,
-	TIFF_SETGET_INT = 13,
-	TIFF_SETGET_UINT16_PAIR = 14,
-	TIFF_SETGET_C0_ASCII = 15,
-	TIFF_SETGET_C0_UINT8 = 16,
-	TIFF_SETGET_C0_SINT8 = 17,
-	TIFF_SETGET_C0_UINT16 = 18,
-	TIFF_SETGET_C0_SINT16 = 19,
-	TIFF_SETGET_C0_UINT32 = 20,
-	TIFF_SETGET_C0_SINT32 = 21,
-	TIFF_SETGET_C0_UINT64 = 22,
-	TIFF_SETGET_C0_SINT64 = 23,
-	TIFF_SETGET_C0_FLOAT = 24,
-	TIFF_SETGET_C0_DOUBLE = 25,
-	TIFF_SETGET_C0_IFD8 = 26,
-	TIFF_SETGET_C16_ASCII = 27,
-	TIFF_SETGET_C16_UINT8 = 28,
-	TIFF_SETGET_C16_SINT8 = 29,
-	TIFF_SETGET_C16_UINT16 = 30,
-	TIFF_SETGET_C16_SINT16 = 31,
-	TIFF_SETGET_C16_UINT32 = 32,
-	TIFF_SETGET_C16_SINT32 = 33,
-	TIFF_SETGET_C16_UINT64 = 34,
-	TIFF_SETGET_C16_SINT64 = 35,
-	TIFF_SETGET_C16_FLOAT = 36,
-	TIFF_SETGET_C16_DOUBLE = 37,
-	TIFF_SETGET_C16_IFD8 = 38,
-	TIFF_SETGET_C32_ASCII = 39,
-	TIFF_SETGET_C32_UINT8 = 40,
-	TIFF_SETGET_C32_SINT8 = 41,
-	TIFF_SETGET_C32_UINT16 = 42,
-	TIFF_SETGET_C32_SINT16 = 43,
-	TIFF_SETGET_C32_UINT32 = 44,
-	TIFF_SETGET_C32_SINT32 = 45,
-	TIFF_SETGET_C32_UINT64 = 46,
-	TIFF_SETGET_C32_SINT64 = 47,
-	TIFF_SETGET_C32_FLOAT = 48,
-	TIFF_SETGET_C32_DOUBLE = 49,
-	TIFF_SETGET_C32_IFD8 = 50,
-	TIFF_SETGET_OTHER = 51
-} TIFFSetGetFieldType;
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-extern const TIFFFieldArray* _TIFFGetFields(void);
-extern const TIFFFieldArray* _TIFFGetExifFields(void);
-extern void _TIFFSetupFields(TIFF* tif, const TIFFFieldArray* infoarray);
-extern void _TIFFPrintFieldInfo(TIFF*, FILE*);
-
-extern int _TIFFFillStriles(TIFF*);        
-
-typedef enum {
-	tfiatImage,
-	tfiatExif,
-	tfiatOther
-} TIFFFieldArrayType;
-
-struct _TIFFFieldArray {
-	TIFFFieldArrayType type;    /* array type, will be used to determine if IFD is image and such */
-	uint32 allocated_size;      /* 0 if array is constant, other if modified by future definition extension support */
-	uint32 count;               /* number of elements in fields array */
-	TIFFField* fields;          /* actual field info */
-};
-
-struct _TIFFField {
-	uint32 field_tag;                       /* field's tag */
-	short field_readcount;                  /* read count/TIFF_VARIABLE/TIFF_SPP */
-	short field_writecount;                 /* write count/TIFF_VARIABLE */
-	TIFFDataType field_type;                /* type of associated data */
-	uint32 reserved;                        /* reserved for future extension */
-	TIFFSetGetFieldType set_field_type;     /* type to be passed to TIFFSetField */
-	TIFFSetGetFieldType get_field_type;     /* type to be passed to TIFFGetField */
-	unsigned short field_bit;               /* bit in fieldsset bit vector */
-	unsigned char field_oktochange;         /* if true, can change while writing */
-	unsigned char field_passcount;          /* if true, pass dir count on set */
-	char* field_name;                       /* ASCII name */
-	TIFFFieldArray* field_subfields;        /* if field points to child ifds, child ifd field definition array */
-};
-
-extern int _TIFFMergeFields(TIFF*, const TIFFField[], uint32);
-extern const TIFFField* _TIFFFindOrRegisterField(TIFF *, uint32, TIFFDataType);
-extern  TIFFField* _TIFFCreateAnonField(TIFF *, uint32, TIFFDataType);
-
-#if defined(__cplusplus)
-}
-#endif
-#endif /* _TIFFDIR_ */
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Id: tif_dir.h,v 1.11 2015/02/19 22:39:58 drolon Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and 
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
+ * 
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef _TIFFDIR_
+#define	_TIFFDIR_
+/*
+ * ``Library-private'' Directory-related Definitions.
+ */
+
+typedef struct {
+	const TIFFField *info;
+	int             count;
+	void           *value;
+} TIFFTagValue;
+
+/*
+ * TIFF Image File Directories are comprised of a table of field
+ * descriptors of the form shown below.  The table is sorted in
+ * ascending order by tag.  The values associated with each entry are
+ * disjoint and may appear anywhere in the file (so long as they are
+ * placed on a word boundary).
+ *
+ * If the value is 4 bytes or less, in ClassicTIFF, or 8 bytes or less in
+ * BigTIFF, then it is placed in the offset field to save space. If so,
+ * it is left-justified in the offset field.
+ */
+typedef struct {
+	uint16 tdir_tag;        /* see below */
+	uint16 tdir_type;       /* data type; see below */
+	uint64 tdir_count;      /* number of items; length in spec */
+	union {
+		uint16 toff_short;
+		uint32 toff_long;
+		uint64 toff_long8;
+	} tdir_offset;		/* either offset or the data itself if fits */
+} TIFFDirEntry;
+
+/*
+ * Internal format of a TIFF directory entry.
+ */
+typedef struct {
+#define FIELD_SETLONGS 4
+	/* bit vector of fields that are set */
+	unsigned long td_fieldsset[FIELD_SETLONGS];
+
+	uint32  td_imagewidth, td_imagelength, td_imagedepth;
+	uint32  td_tilewidth, td_tilelength, td_tiledepth;
+	uint32  td_subfiletype;
+	uint16  td_bitspersample;
+	uint16  td_sampleformat;
+	uint16  td_compression;
+	uint16  td_photometric;
+	uint16  td_threshholding;
+	uint16  td_fillorder;
+	uint16  td_orientation;
+	uint16  td_samplesperpixel;
+	uint32  td_rowsperstrip;
+	uint16  td_minsamplevalue, td_maxsamplevalue;
+	double* td_sminsamplevalue;
+	double* td_smaxsamplevalue;
+	float   td_xresolution, td_yresolution;
+	uint16  td_resolutionunit;
+	uint16  td_planarconfig;
+	float   td_xposition, td_yposition;
+	uint16  td_pagenumber[2];
+	uint16* td_colormap[3];
+	uint16  td_halftonehints[2];
+	uint16  td_extrasamples;
+	uint16* td_sampleinfo;
+	/* even though the name is misleading, td_stripsperimage is the number
+	 * of striles (=strips or tiles) per plane, and td_nstrips the total
+	 * number of striles */
+	uint32  td_stripsperimage;  
+	uint32  td_nstrips;              /* size of offset & bytecount arrays */
+	uint64* td_stripoffset;
+	uint64* td_stripbytecount;
+	int     td_stripbytecountsorted; /* is the bytecount array sorted ascending? */
+#if defined(DEFER_STRILE_LOAD)
+        TIFFDirEntry td_stripoffset_entry;    /* for deferred loading */
+        TIFFDirEntry td_stripbytecount_entry; /* for deferred loading */
+#endif
+	uint16  td_nsubifd;
+	uint64* td_subifd;
+	/* YCbCr parameters */
+	uint16  td_ycbcrsubsampling[2];
+	uint16  td_ycbcrpositioning;
+	/* Colorimetry parameters */
+	uint16* td_transferfunction[3];
+	float*	td_refblackwhite;
+	/* CMYK parameters */
+	int     td_inknameslen;
+	char*   td_inknames;
+
+	int     td_customValueCount;
+        TIFFTagValue *td_customValues;
+} TIFFDirectory;
+
+/*
+ * Field flags used to indicate fields that have been set in a directory, and
+ * to reference fields when manipulating a directory.
+ */
+
+/*
+ * FIELD_IGNORE is used to signify tags that are to be processed but otherwise
+ * ignored.  This permits antiquated tags to be quietly read and discarded.
+ * Note that a bit *is* allocated for ignored tags; this is understood by the
+ * directory reading logic which uses this fact to avoid special-case handling
+ */
+#define FIELD_IGNORE                   0
+
+/* multi-item fields */
+#define FIELD_IMAGEDIMENSIONS          1
+#define FIELD_TILEDIMENSIONS           2
+#define FIELD_RESOLUTION               3
+#define FIELD_POSITION                 4
+
+/* single-item fields */
+#define FIELD_SUBFILETYPE              5
+#define FIELD_BITSPERSAMPLE            6
+#define FIELD_COMPRESSION              7
+#define FIELD_PHOTOMETRIC              8
+#define FIELD_THRESHHOLDING            9
+#define FIELD_FILLORDER                10
+#define FIELD_ORIENTATION              15
+#define FIELD_SAMPLESPERPIXEL          16
+#define FIELD_ROWSPERSTRIP             17
+#define FIELD_MINSAMPLEVALUE           18
+#define FIELD_MAXSAMPLEVALUE           19
+#define FIELD_PLANARCONFIG             20
+#define FIELD_RESOLUTIONUNIT           22
+#define FIELD_PAGENUMBER               23
+#define FIELD_STRIPBYTECOUNTS          24
+#define FIELD_STRIPOFFSETS             25
+#define FIELD_COLORMAP                 26
+#define FIELD_EXTRASAMPLES             31
+#define FIELD_SAMPLEFORMAT             32
+#define FIELD_SMINSAMPLEVALUE          33
+#define FIELD_SMAXSAMPLEVALUE          34
+#define FIELD_IMAGEDEPTH               35
+#define FIELD_TILEDEPTH                36
+#define FIELD_HALFTONEHINTS            37
+#define FIELD_YCBCRSUBSAMPLING         39
+#define FIELD_YCBCRPOSITIONING         40
+#define	FIELD_REFBLACKWHITE            41
+#define FIELD_TRANSFERFUNCTION         44
+#define FIELD_INKNAMES                 46
+#define FIELD_SUBIFD                   49
+/*      FIELD_CUSTOM (see tiffio.h)    65 */
+/* end of support for well-known tags; codec-private tags follow */
+#define FIELD_CODEC                    66  /* base of codec-private tags */
+
+
+/*
+ * Pseudo-tags don't normally need field bits since they are not written to an
+ * output file (by definition). The library also has express logic to always
+ * query a codec for a pseudo-tag so allocating a field bit for one is a
+ * waste.   If codec wants to promote the notion of a pseudo-tag being ``set''
+ * or ``unset'' then it can do using internal state flags without polluting
+ * the field bit space defined for real tags.
+ */
+#define FIELD_PSEUDO			0
+
+#define FIELD_LAST			(32*FIELD_SETLONGS-1)
+
+#define BITn(n)				(((unsigned long)1L)<<((n)&0x1f))
+#define BITFIELDn(tif, n)		((tif)->tif_dir.td_fieldsset[(n)/32])
+#define TIFFFieldSet(tif, field)	(BITFIELDn(tif, field) & BITn(field))
+#define TIFFSetFieldBit(tif, field)	(BITFIELDn(tif, field) |= BITn(field))
+#define TIFFClrFieldBit(tif, field)	(BITFIELDn(tif, field) &= ~BITn(field))
+
+#define FieldSet(fields, f)		(fields[(f)/32] & BITn(f))
+#define ResetFieldBit(fields, f)	(fields[(f)/32] &= ~BITn(f))
+
+typedef enum {
+	TIFF_SETGET_UNDEFINED = 0,
+	TIFF_SETGET_ASCII = 1,
+	TIFF_SETGET_UINT8 = 2,
+	TIFF_SETGET_SINT8 = 3,
+	TIFF_SETGET_UINT16 = 4,
+	TIFF_SETGET_SINT16 = 5,
+	TIFF_SETGET_UINT32 = 6,
+	TIFF_SETGET_SINT32 = 7,
+	TIFF_SETGET_UINT64 = 8,
+	TIFF_SETGET_SINT64 = 9,
+	TIFF_SETGET_FLOAT = 10,
+	TIFF_SETGET_DOUBLE = 11,
+	TIFF_SETGET_IFD8 = 12,
+	TIFF_SETGET_INT = 13,
+	TIFF_SETGET_UINT16_PAIR = 14,
+	TIFF_SETGET_C0_ASCII = 15,
+	TIFF_SETGET_C0_UINT8 = 16,
+	TIFF_SETGET_C0_SINT8 = 17,
+	TIFF_SETGET_C0_UINT16 = 18,
+	TIFF_SETGET_C0_SINT16 = 19,
+	TIFF_SETGET_C0_UINT32 = 20,
+	TIFF_SETGET_C0_SINT32 = 21,
+	TIFF_SETGET_C0_UINT64 = 22,
+	TIFF_SETGET_C0_SINT64 = 23,
+	TIFF_SETGET_C0_FLOAT = 24,
+	TIFF_SETGET_C0_DOUBLE = 25,
+	TIFF_SETGET_C0_IFD8 = 26,
+	TIFF_SETGET_C16_ASCII = 27,
+	TIFF_SETGET_C16_UINT8 = 28,
+	TIFF_SETGET_C16_SINT8 = 29,
+	TIFF_SETGET_C16_UINT16 = 30,
+	TIFF_SETGET_C16_SINT16 = 31,
+	TIFF_SETGET_C16_UINT32 = 32,
+	TIFF_SETGET_C16_SINT32 = 33,
+	TIFF_SETGET_C16_UINT64 = 34,
+	TIFF_SETGET_C16_SINT64 = 35,
+	TIFF_SETGET_C16_FLOAT = 36,
+	TIFF_SETGET_C16_DOUBLE = 37,
+	TIFF_SETGET_C16_IFD8 = 38,
+	TIFF_SETGET_C32_ASCII = 39,
+	TIFF_SETGET_C32_UINT8 = 40,
+	TIFF_SETGET_C32_SINT8 = 41,
+	TIFF_SETGET_C32_UINT16 = 42,
+	TIFF_SETGET_C32_SINT16 = 43,
+	TIFF_SETGET_C32_UINT32 = 44,
+	TIFF_SETGET_C32_SINT32 = 45,
+	TIFF_SETGET_C32_UINT64 = 46,
+	TIFF_SETGET_C32_SINT64 = 47,
+	TIFF_SETGET_C32_FLOAT = 48,
+	TIFF_SETGET_C32_DOUBLE = 49,
+	TIFF_SETGET_C32_IFD8 = 50,
+	TIFF_SETGET_OTHER = 51
+} TIFFSetGetFieldType;
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+extern const TIFFFieldArray* _TIFFGetFields(void);
+extern const TIFFFieldArray* _TIFFGetExifFields(void);
+extern void _TIFFSetupFields(TIFF* tif, const TIFFFieldArray* infoarray);
+extern void _TIFFPrintFieldInfo(TIFF*, FILE*);
+
+extern int _TIFFFillStriles(TIFF*);        
+
+typedef enum {
+	tfiatImage,
+	tfiatExif,
+	tfiatOther
+} TIFFFieldArrayType;
+
+struct _TIFFFieldArray {
+	TIFFFieldArrayType type;    /* array type, will be used to determine if IFD is image and such */
+	uint32 allocated_size;      /* 0 if array is constant, other if modified by future definition extension support */
+	uint32 count;               /* number of elements in fields array */
+	TIFFField* fields;          /* actual field info */
+};
+
+struct _TIFFField {
+	uint32 field_tag;                       /* field's tag */
+	short field_readcount;                  /* read count/TIFF_VARIABLE/TIFF_SPP */
+	short field_writecount;                 /* write count/TIFF_VARIABLE */
+	TIFFDataType field_type;                /* type of associated data */
+	uint32 reserved;                        /* reserved for future extension */
+	TIFFSetGetFieldType set_field_type;     /* type to be passed to TIFFSetField */
+	TIFFSetGetFieldType get_field_type;     /* type to be passed to TIFFGetField */
+	unsigned short field_bit;               /* bit in fieldsset bit vector */
+	unsigned char field_oktochange;         /* if true, can change while writing */
+	unsigned char field_passcount;          /* if true, pass dir count on set */
+	char* field_name;                       /* ASCII name */
+	TIFFFieldArray* field_subfields;        /* if field points to child ifds, child ifd field definition array */
+};
+
+extern int _TIFFMergeFields(TIFF*, const TIFFField[], uint32);
+extern const TIFFField* _TIFFFindOrRegisterField(TIFF *, uint32, TIFFDataType);
+extern  TIFFField* _TIFFCreateAnonField(TIFF *, uint32, TIFFDataType);
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* _TIFFDIR_ */
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tif_dirinfo.c b/Source/LibTIFF4/tif_dirinfo.c
index 9c8bd4c..2250351 100644
--- a/Source/LibTIFF4/tif_dirinfo.c
+++ b/Source/LibTIFF4/tif_dirinfo.c
@@ -1,957 +1,959 @@
-/* $Id: tif_dirinfo.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library.
- *
- * Core Directory Tag Support.
- */
-#include "tiffiop.h"
-#include <stdlib.h>
-
-/*
- * NOTE: THIS ARRAY IS ASSUMED TO BE SORTED BY TAG.
- *
- * NOTE: The second field (field_readcount) and third field (field_writecount)
- *       sometimes use the values TIFF_VARIABLE (-1), TIFF_VARIABLE2 (-3)
- *       and TIFF_SPP (-2). The macros should be used but would throw off
- *       the formatting of the code, so please interprete the -1, -2 and -3
- *       values accordingly.
- */
-
-static TIFFFieldArray tiffFieldArray;
-static TIFFFieldArray exifFieldArray;
-
-static TIFFField
-tiffFields[] = {
-	{ TIFFTAG_SUBFILETYPE, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_SUBFILETYPE, 1, 0, "SubfileType", NULL },
-	{ TIFFTAG_OSUBFILETYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_SUBFILETYPE, 1, 0, "OldSubfileType", NULL },
-	{ TIFFTAG_IMAGEWIDTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_IMAGEDIMENSIONS, 0, 0, "ImageWidth", NULL },
-	{ TIFFTAG_IMAGELENGTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_IMAGEDIMENSIONS, 1, 0, "ImageLength", NULL },
-	{ TIFFTAG_BITSPERSAMPLE, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_BITSPERSAMPLE, 0, 0, "BitsPerSample", NULL },
-	{ TIFFTAG_COMPRESSION, -1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_COMPRESSION, 0, 0, "Compression", NULL },
-	{ TIFFTAG_PHOTOMETRIC, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_PHOTOMETRIC, 0, 0, "PhotometricInterpretation", NULL },
-	{ TIFFTAG_THRESHHOLDING, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_THRESHHOLDING, 1, 0, "Threshholding", NULL },
-	{ TIFFTAG_CELLWIDTH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "CellWidth", NULL },
-	{ TIFFTAG_CELLLENGTH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "CellLength", NULL },
-	{ TIFFTAG_FILLORDER, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_FILLORDER, 0, 0, "FillOrder", NULL },
-	{ TIFFTAG_DOCUMENTNAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DocumentName", NULL },
-	{ TIFFTAG_IMAGEDESCRIPTION, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageDescription", NULL },
-	{ TIFFTAG_MAKE, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Make", NULL },
-	{ TIFFTAG_MODEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Model", NULL },
-	{ TIFFTAG_STRIPOFFSETS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPOFFSETS, 0, 0, "StripOffsets", NULL },
-	{ TIFFTAG_ORIENTATION, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_ORIENTATION, 0, 0, "Orientation", NULL },
-	{ TIFFTAG_SAMPLESPERPIXEL, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_SAMPLESPERPIXEL, 0, 0, "SamplesPerPixel", NULL },
-	{ TIFFTAG_ROWSPERSTRIP, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_ROWSPERSTRIP, 0, 0, "RowsPerStrip", NULL },
-	{ TIFFTAG_STRIPBYTECOUNTS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPBYTECOUNTS, 0, 0, "StripByteCounts", NULL },
-	{ TIFFTAG_MINSAMPLEVALUE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_MINSAMPLEVALUE, 1, 0, "MinSampleValue", NULL },
-	{ TIFFTAG_MAXSAMPLEVALUE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_MAXSAMPLEVALUE, 1, 0, "MaxSampleValue", NULL },
-	{ TIFFTAG_XRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_RESOLUTION, 1, 0, "XResolution", NULL },
-	{ TIFFTAG_YRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_RESOLUTION, 1, 0, "YResolution", NULL },
-	{ TIFFTAG_PLANARCONFIG, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_PLANARCONFIG, 0, 0, "PlanarConfiguration", NULL },
-	{ TIFFTAG_PAGENAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PageName", NULL },
-	{ TIFFTAG_XPOSITION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_POSITION, 1, 0, "XPosition", NULL },
-	{ TIFFTAG_YPOSITION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_POSITION, 1, 0, "YPosition", NULL },
-	{ TIFFTAG_FREEOFFSETS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 0, 0, "FreeOffsets", NULL },
-	{ TIFFTAG_FREEBYTECOUNTS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 0, 0, "FreeByteCounts", NULL },
-	{ TIFFTAG_GRAYRESPONSEUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "GrayResponseUnit", NULL },
-	{ TIFFTAG_GRAYRESPONSECURVE, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "GrayResponseCurve", NULL },
-	{ TIFFTAG_RESOLUTIONUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_RESOLUTIONUNIT, 1, 0, "ResolutionUnit", NULL },
-	{ TIFFTAG_PAGENUMBER, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_PAGENUMBER, 1, 0, "PageNumber", NULL },
-	{ TIFFTAG_COLORRESPONSEUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "ColorResponseUnit", NULL },
-	{ TIFFTAG_TRANSFERFUNCTION, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_OTHER, TIFF_SETGET_UNDEFINED, FIELD_TRANSFERFUNCTION, 1, 0, "TransferFunction", NULL },
-	{ TIFFTAG_SOFTWARE, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Software", NULL },
-	{ TIFFTAG_DATETIME, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateTime", NULL },
-	{ TIFFTAG_ARTIST, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Artist", NULL },
-	{ TIFFTAG_HOSTCOMPUTER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "HostComputer", NULL },
-	{ TIFFTAG_WHITEPOINT, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "WhitePoint", NULL },
-	{ TIFFTAG_PRIMARYCHROMATICITIES, 6, 6, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PrimaryChromaticities", NULL },
-	{ TIFFTAG_COLORMAP, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_OTHER, TIFF_SETGET_UNDEFINED, FIELD_COLORMAP, 1, 0, "ColorMap", NULL },
-	{ TIFFTAG_HALFTONEHINTS, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_HALFTONEHINTS, 1, 0, "HalftoneHints", NULL },
-	{ TIFFTAG_TILEWIDTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_TILEDIMENSIONS, 0, 0, "TileWidth", NULL },
-	{ TIFFTAG_TILELENGTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_TILEDIMENSIONS, 0, 0, "TileLength", NULL },
-	{ TIFFTAG_TILEOFFSETS, -1, 1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPOFFSETS, 0, 0, "TileOffsets", NULL },
-	{ TIFFTAG_TILEBYTECOUNTS, -1, 1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPBYTECOUNTS, 0, 0, "TileByteCounts", NULL },
-	{ TIFFTAG_SUBIFD, -1, -1, TIFF_IFD8, 0, TIFF_SETGET_C16_IFD8, TIFF_SETGET_UNDEFINED, FIELD_SUBIFD, 1, 1, "SubIFD", &tiffFieldArray },
-	{ TIFFTAG_INKSET, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "InkSet", NULL },
-	{ TIFFTAG_INKNAMES, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_C16_ASCII, TIFF_SETGET_UNDEFINED, FIELD_INKNAMES, 1, 1, "InkNames", NULL },
-	{ TIFFTAG_NUMBEROFINKS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "NumberOfInks", NULL },
-	{ TIFFTAG_DOTRANGE, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DotRange", NULL },
-	{ TIFFTAG_TARGETPRINTER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TargetPrinter", NULL },
-	{ TIFFTAG_EXTRASAMPLES, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_EXTRASAMPLES, 0, 1, "ExtraSamples", NULL },
-	{ TIFFTAG_SAMPLEFORMAT, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_SAMPLEFORMAT, 0, 0, "SampleFormat", NULL },
-	{ TIFFTAG_SMINSAMPLEVALUE, -2, -1, TIFF_ANY, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_SMINSAMPLEVALUE, 1, 0, "SMinSampleValue", NULL },
-	{ TIFFTAG_SMAXSAMPLEVALUE, -2, -1, TIFF_ANY, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_SMAXSAMPLEVALUE, 1, 0, "SMaxSampleValue", NULL },
-	{ TIFFTAG_CLIPPATH, -1, -3, TIFF_BYTE, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ClipPath", NULL },
-	{ TIFFTAG_XCLIPPATHUNITS, 1, 1, TIFF_SLONG, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "XClipPathUnits", NULL },
-	{ TIFFTAG_XCLIPPATHUNITS, 1, 1, TIFF_SBYTE, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "XClipPathUnits", NULL },
-	{ TIFFTAG_YCLIPPATHUNITS, 1, 1, TIFF_SLONG, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "YClipPathUnits", NULL },
-	{ TIFFTAG_YCBCRCOEFFICIENTS, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "YCbCrCoefficients", NULL },
-	{ TIFFTAG_YCBCRSUBSAMPLING, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_YCBCRSUBSAMPLING, 0, 0, "YCbCrSubsampling", NULL },
-	{ TIFFTAG_YCBCRPOSITIONING, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_YCBCRPOSITIONING, 0, 0, "YCbCrPositioning", NULL },
-	{ TIFFTAG_REFERENCEBLACKWHITE, 6, 6, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_REFBLACKWHITE, 1, 0, "ReferenceBlackWhite", NULL },
-	{ TIFFTAG_XMLPACKET, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "XMLPacket", NULL },
-	/* begin SGI tags */
-	{ TIFFTAG_MATTEING, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_EXTRASAMPLES, 0, 0, "Matteing", NULL },
-	{ TIFFTAG_DATATYPE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_SAMPLEFORMAT, 0, 0, "DataType", NULL },
-	{ TIFFTAG_IMAGEDEPTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_IMAGEDEPTH, 0, 0, "ImageDepth", NULL },
-	{ TIFFTAG_TILEDEPTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_TILEDEPTH, 0, 0, "TileDepth", NULL },
-	/* end SGI tags */
-	/* begin Pixar tags */
-	{ TIFFTAG_PIXAR_IMAGEFULLWIDTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageFullWidth", NULL },
-	{ TIFFTAG_PIXAR_IMAGEFULLLENGTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageFullLength", NULL },
-	{ TIFFTAG_PIXAR_TEXTUREFORMAT, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TextureFormat", NULL },
-	{ TIFFTAG_PIXAR_WRAPMODES, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TextureWrapModes", NULL },
-	{ TIFFTAG_PIXAR_FOVCOT, 1, 1, TIFF_FLOAT, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FieldOfViewCotangent", NULL },
-	{ TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN, 16, 16, TIFF_FLOAT, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MatrixWorldToScreen", NULL },
-	{ TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA, 16, 16, TIFF_FLOAT, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MatrixWorldToCamera", NULL },
-	{ TIFFTAG_COPYRIGHT, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Copyright", NULL },
-	/* end Pixar tags */
-	{ TIFFTAG_RICHTIFFIPTC, -3, -3, TIFF_LONG, 0, TIFF_SETGET_C32_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "RichTIFFIPTC", NULL },
-	{ TIFFTAG_PHOTOSHOP, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "Photoshop", NULL },
-	{ TIFFTAG_EXIFIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "EXIFIFDOffset", &exifFieldArray },
-	{ TIFFTAG_ICCPROFILE, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ICC Profile", NULL },
-	{ TIFFTAG_GPSIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "GPSIFDOffset", NULL },
-	{ TIFFTAG_FAXRECVPARAMS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_CUSTOM, TRUE, FALSE, "FaxRecvParams", NULL },
-	{ TIFFTAG_FAXSUBADDRESS, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_ASCII, FIELD_CUSTOM, TRUE, FALSE, "FaxSubAddress", NULL },
-	{ TIFFTAG_FAXRECVTIME, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_CUSTOM, TRUE, FALSE, "FaxRecvTime", NULL },
-	{ TIFFTAG_FAXDCS, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_ASCII, FIELD_CUSTOM, TRUE, FALSE, "FaxDcs", NULL },
-	{ TIFFTAG_STONITS, 1, 1, TIFF_DOUBLE, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "StoNits", NULL },
-	{ TIFFTAG_INTEROPERABILITYIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "InteroperabilityIFDOffset", NULL },
-	/* begin DNG tags */
-	{ TIFFTAG_DNGVERSION, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DNGVersion", NULL },
-	{ TIFFTAG_DNGBACKWARDVERSION, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DNGBackwardVersion", NULL },
-	{ TIFFTAG_UNIQUECAMERAMODEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "UniqueCameraModel", NULL },
-	{ TIFFTAG_LOCALIZEDCAMERAMODEL, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "LocalizedCameraModel", NULL },
-	{ TIFFTAG_CFAPLANECOLOR, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CFAPlaneColor", NULL },
-	{ TIFFTAG_CFALAYOUT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CFALayout", NULL },
-	{ TIFFTAG_LINEARIZATIONTABLE, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "LinearizationTable", NULL },
-	{ TIFFTAG_BLACKLEVELREPEATDIM, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BlackLevelRepeatDim", NULL },
-	{ TIFFTAG_BLACKLEVEL, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "BlackLevel", NULL },
-	{ TIFFTAG_BLACKLEVELDELTAH, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "BlackLevelDeltaH", NULL },
-	{ TIFFTAG_BLACKLEVELDELTAV, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "BlackLevelDeltaV", NULL },
-	{ TIFFTAG_WHITELEVEL, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "WhiteLevel", NULL },
-	{ TIFFTAG_DEFAULTSCALE, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DefaultScale", NULL },
-	{ TIFFTAG_BESTQUALITYSCALE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BestQualityScale", NULL },
-	{ TIFFTAG_DEFAULTCROPORIGIN, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DefaultCropOrigin", NULL },
-	{ TIFFTAG_DEFAULTCROPSIZE, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DefaultCropSize", NULL },
-	{ TIFFTAG_COLORMATRIX1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ColorMatrix1", NULL },
-	{ TIFFTAG_COLORMATRIX2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ColorMatrix2", NULL },
-	{ TIFFTAG_CAMERACALIBRATION1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CameraCalibration1", NULL },
-	{ TIFFTAG_CAMERACALIBRATION2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CameraCalibration2", NULL },
-	{ TIFFTAG_REDUCTIONMATRIX1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ReductionMatrix1", NULL },
-	{ TIFFTAG_REDUCTIONMATRIX2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ReductionMatrix2", NULL },
-	{ TIFFTAG_ANALOGBALANCE, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "AnalogBalance", NULL },
-	{ TIFFTAG_ASSHOTNEUTRAL, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "AsShotNeutral", NULL },
-	{ TIFFTAG_ASSHOTWHITEXY, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "AsShotWhiteXY", NULL },
-	{ TIFFTAG_BASELINEEXPOSURE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BaselineExposure", NULL },
-	{ TIFFTAG_BASELINENOISE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BaselineNoise", NULL },
-	{ TIFFTAG_BASELINESHARPNESS, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BaselineSharpness", NULL },
-	{ TIFFTAG_BAYERGREENSPLIT, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BayerGreenSplit", NULL },
-	{ TIFFTAG_LINEARRESPONSELIMIT, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "LinearResponseLimit", NULL },
-	{ TIFFTAG_CAMERASERIALNUMBER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CameraSerialNumber", NULL },
-	{ TIFFTAG_LENSINFO, 4, 4, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "LensInfo", NULL },
-	{ TIFFTAG_CHROMABLURRADIUS, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ChromaBlurRadius", NULL },
-	{ TIFFTAG_ANTIALIASSTRENGTH, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "AntiAliasStrength", NULL },
-	{ TIFFTAG_SHADOWSCALE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ShadowScale", NULL },
-	{ TIFFTAG_DNGPRIVATEDATA, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "DNGPrivateData", NULL },
-	{ TIFFTAG_MAKERNOTESAFETY, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "MakerNoteSafety", NULL },
-	{ TIFFTAG_CALIBRATIONILLUMINANT1, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CalibrationIlluminant1", NULL },
-	{ TIFFTAG_CALIBRATIONILLUMINANT2, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CalibrationIlluminant2", NULL },
-	{ TIFFTAG_RAWDATAUNIQUEID, 16, 16, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "RawDataUniqueID", NULL },
-	{ TIFFTAG_ORIGINALRAWFILENAME, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OriginalRawFileName", NULL },
-	{ TIFFTAG_ORIGINALRAWFILEDATA, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "OriginalRawFileData", NULL },
-	{ TIFFTAG_ACTIVEAREA, 4, 4, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ActiveArea", NULL },
-	{ TIFFTAG_MASKEDAREAS, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "MaskedAreas", NULL },
-	{ TIFFTAG_ASSHOTICCPROFILE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "AsShotICCProfile", NULL },
-	{ TIFFTAG_ASSHOTPREPROFILEMATRIX, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "AsShotPreProfileMatrix", NULL },
-	{ TIFFTAG_CURRENTICCPROFILE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CurrentICCProfile", NULL },
-	{ TIFFTAG_CURRENTPREPROFILEMATRIX, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CurrentPreProfileMatrix", NULL },
-	{ TIFFTAG_PERSAMPLE, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "PerSample", NULL},
-	/* end DNG tags */
-	/* begin TIFF/FX tags */
-    { TIFFTAG_INDEXED, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "Indexed" },
-    { TIFFTAG_GLOBALPARAMETERSIFD, 1, 1, TIFF_IFD, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "GlobalParametersIFD", NULL },
-    { TIFFTAG_PROFILETYPE, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ProfileType", NULL },
-    { TIFFTAG_FAXPROFILE, 1, 1, TIFF_BYTE, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "FaxProfile", NULL },
-    { TIFFTAG_CODINGMETHODS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CodingMethods", NULL },
-    { TIFFTAG_VERSIONYEAR, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "VersionYear", NULL },
-    { TIFFTAG_MODENUMBER, 1, 1, TIFF_BYTE, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ModeNumber", NULL },
-    { TIFFTAG_DECODE, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "Decode", NULL },
-    { TIFFTAG_IMAGEBASECOLOR, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ImageBaseColor", NULL },
-    { TIFFTAG_T82OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "T82Options", NULL },
-    { TIFFTAG_STRIPROWCOUNTS, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "StripRowCounts", NULL },
-    { TIFFTAG_IMAGELAYER, 2, 2, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ImageLayer", NULL },
-	/* end DNG tags */
-	/* begin pseudo tags */
-};
-
-static TIFFField
-exifFields[] = {
-	{ EXIFTAG_EXPOSURETIME, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureTime", NULL },
-	{ EXIFTAG_FNUMBER, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FNumber", NULL },
-	{ EXIFTAG_EXPOSUREPROGRAM, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureProgram", NULL },
-	{ EXIFTAG_SPECTRALSENSITIVITY, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SpectralSensitivity", NULL },
-	{ EXIFTAG_ISOSPEEDRATINGS, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ISOSpeedRatings", NULL },
-	{ EXIFTAG_OECF, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OptoelectricConversionFactor", NULL },
-	{ EXIFTAG_EXIFVERSION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExifVersion", NULL },
-	{ EXIFTAG_DATETIMEORIGINAL, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateTimeOriginal", NULL },
-	{ EXIFTAG_DATETIMEDIGITIZED, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateTimeDigitized", NULL },
-	{ EXIFTAG_COMPONENTSCONFIGURATION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ComponentsConfiguration", NULL },
-	{ EXIFTAG_COMPRESSEDBITSPERPIXEL, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CompressedBitsPerPixel", NULL },
-	{ EXIFTAG_SHUTTERSPEEDVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ShutterSpeedValue", NULL },
-	{ EXIFTAG_APERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ApertureValue", NULL },
-	{ EXIFTAG_BRIGHTNESSVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BrightnessValue", NULL },
-	{ EXIFTAG_EXPOSUREBIASVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureBiasValue", NULL },
-	{ EXIFTAG_MAXAPERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MaxApertureValue", NULL },
-	{ EXIFTAG_SUBJECTDISTANCE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectDistance", NULL },
-	{ EXIFTAG_METERINGMODE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MeteringMode", NULL },
-	{ EXIFTAG_LIGHTSOURCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LightSource", NULL },
-	{ EXIFTAG_FLASH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Flash", NULL },
-	{ EXIFTAG_FOCALLENGTH, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalLength", NULL },
-	{ EXIFTAG_SUBJECTAREA, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "SubjectArea", NULL },
-	{ EXIFTAG_MAKERNOTE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "MakerNote", NULL },
-	{ EXIFTAG_USERCOMMENT, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "UserComment", NULL },
-	{ EXIFTAG_SUBSECTIME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTime", NULL },
-	{ EXIFTAG_SUBSECTIMEORIGINAL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTimeOriginal", NULL },
-	{ EXIFTAG_SUBSECTIMEDIGITIZED, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTimeDigitized", NULL },
-	{ EXIFTAG_FLASHPIXVERSION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FlashpixVersion", NULL },
-	{ EXIFTAG_COLORSPACE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ColorSpace", NULL },
-	{ EXIFTAG_PIXELXDIMENSION, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PixelXDimension", NULL },
-	{ EXIFTAG_PIXELYDIMENSION, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PixelYDimension", NULL },
-	{ EXIFTAG_RELATEDSOUNDFILE, 13, 13, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "RelatedSoundFile", NULL },
-	{ EXIFTAG_FLASHENERGY, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FlashEnergy", NULL },
-	{ EXIFTAG_SPATIALFREQUENCYRESPONSE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "SpatialFrequencyResponse", NULL },
-	{ EXIFTAG_FOCALPLANEXRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneXResolution", NULL },
-	{ EXIFTAG_FOCALPLANEYRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneYResolution", NULL },
-	{ EXIFTAG_FOCALPLANERESOLUTIONUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneResolutionUnit", NULL },
-	{ EXIFTAG_SUBJECTLOCATION, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectLocation", NULL },
-	{ EXIFTAG_EXPOSUREINDEX, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureIndex", NULL },
-	{ EXIFTAG_SENSINGMETHOD, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SensingMethod", NULL },
-	{ EXIFTAG_FILESOURCE, 1, 1, TIFF_UNDEFINED, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FileSource", NULL },
-	{ EXIFTAG_SCENETYPE, 1, 1, TIFF_UNDEFINED, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SceneType", NULL },
-	{ EXIFTAG_CFAPATTERN, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CFAPattern", NULL },
-	{ EXIFTAG_CUSTOMRENDERED, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CustomRendered", NULL },
-	{ EXIFTAG_EXPOSUREMODE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureMode", NULL },
-	{ EXIFTAG_WHITEBALANCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "WhiteBalance", NULL },
-	{ EXIFTAG_DIGITALZOOMRATIO, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DigitalZoomRatio", NULL },
-	{ EXIFTAG_FOCALLENGTHIN35MMFILM, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalLengthIn35mmFilm", NULL },
-	{ EXIFTAG_SCENECAPTURETYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SceneCaptureType", NULL },
-	{ EXIFTAG_GAINCONTROL, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "GainControl", NULL },
-	{ EXIFTAG_CONTRAST, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Contrast", NULL },
-	{ EXIFTAG_SATURATION, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Saturation", NULL },
-	{ EXIFTAG_SHARPNESS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Sharpness", NULL },
-	{ EXIFTAG_DEVICESETTINGDESCRIPTION, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "DeviceSettingDescription", NULL },
-	{ EXIFTAG_SUBJECTDISTANCERANGE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectDistanceRange", NULL },
-	{ EXIFTAG_IMAGEUNIQUEID, 33, 33, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageUniqueID", NULL }
-};
-
-static TIFFFieldArray
-tiffFieldArray = { tfiatImage, 0, TIFFArrayCount(tiffFields), tiffFields };
-static TIFFFieldArray
-exifFieldArray = { tfiatExif, 0, TIFFArrayCount(exifFields), exifFields };
-
-/*
- *  We have our own local lfind() equivelent to avoid subtle differences
- *  in types passed to lfind() on different systems. 
- */
-
-static void *
-td_lfind(const void *key, const void *base, size_t *nmemb, size_t size,
-         int(*compar)(const void *, const void *))
-{
-    char *element, *end;
-
-    end = (char *)base + *nmemb * size;
-    for (element = (char *)base; element < end; element += size)
-        if (!compar(key, element))		/* key found */
-            return element;
-
-    return NULL;
-}
-
-const TIFFFieldArray*
-_TIFFGetFields(void)
-{
-	return(&tiffFieldArray);
-}
-
-const TIFFFieldArray*
-_TIFFGetExifFields(void)
-{
-	return(&exifFieldArray);
-}
-
-void
-_TIFFSetupFields(TIFF* tif, const TIFFFieldArray* fieldarray)
-{
-	if (tif->tif_fields && tif->tif_nfields > 0) {
-		uint32 i;
-
-		for (i = 0; i < tif->tif_nfields; i++) {
-			TIFFField *fld = tif->tif_fields[i];
-			if (fld->field_bit == FIELD_CUSTOM &&
-				strncmp("Tag ", fld->field_name, 4) == 0) {
-					_TIFFfree(fld->field_name);
-					_TIFFfree(fld);
-				}
-		}
-
-		_TIFFfree(tif->tif_fields);
-		tif->tif_fields = NULL;
-		tif->tif_nfields = 0;
-	}
-	if (!_TIFFMergeFields(tif, fieldarray->fields, fieldarray->count)) {
-		TIFFErrorExt(tif->tif_clientdata, "_TIFFSetupFields",
-			     "Setting up field info failed");
-	}
-}
-
-static int
-tagCompare(const void* a, const void* b)
-{
-	const TIFFField* ta = *(const TIFFField**) a;
-	const TIFFField* tb = *(const TIFFField**) b;
-	/* NB: be careful of return values for 16-bit platforms */
-	if (ta->field_tag != tb->field_tag)
-		return (int)ta->field_tag - (int)tb->field_tag;
-	else
-		return (ta->field_type == TIFF_ANY) ?
-			0 : ((int)tb->field_type - (int)ta->field_type);
-}
-
-static int
-tagNameCompare(const void* a, const void* b)
-{
-	const TIFFField* ta = *(const TIFFField**) a;
-	const TIFFField* tb = *(const TIFFField**) b;
-	int ret = strcmp(ta->field_name, tb->field_name);
-
-	if (ret)
-		return ret;
-	else
-		return (ta->field_type == TIFF_ANY) ?
-			0 : ((int)tb->field_type - (int)ta->field_type);
-}
-
-int
-_TIFFMergeFields(TIFF* tif, const TIFFField info[], uint32 n)
-{
-	static const char module[] = "_TIFFMergeFields";
-	static const char reason[] = "for fields array";
-	/* TIFFField** tp; */
-	uint32 i;
-
-        tif->tif_foundfield = NULL;
-
-	if (tif->tif_fields && tif->tif_nfields > 0) {
-		tif->tif_fields = (TIFFField**)
-			_TIFFCheckRealloc(tif, tif->tif_fields,
-					  (tif->tif_nfields + n),
-					  sizeof(TIFFField *), reason);
-	} else {
-		tif->tif_fields = (TIFFField **)
-			_TIFFCheckMalloc(tif, n, sizeof(TIFFField *),
-					 reason);
-	}
-	if (!tif->tif_fields) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-			     "Failed to allocate fields array");
-		return 0;
-	}
-
-	/* tp = tif->tif_fields + tif->tif_nfields; */
-	for (i = 0; i < n; i++) {
-		const TIFFField *fip =
-			TIFFFindField(tif, info[i].field_tag, TIFF_ANY);
-
-                /* only add definitions that aren't already present */
-		if (!fip) {
-                        tif->tif_fields[tif->tif_nfields] = (TIFFField *) (info+i);
-                        tif->tif_nfields++;
-                }
-	}
-
-        /* Sort the field info by tag number */
-	qsort(tif->tif_fields, tif->tif_nfields,
-	      sizeof(TIFFField *), tagCompare);
-
-	return n;
-}
-
-void
-_TIFFPrintFieldInfo(TIFF* tif, FILE* fd)
-{
-	uint32 i;
-
-	fprintf(fd, "%s: \n", tif->tif_name);
-	for (i = 0; i < tif->tif_nfields; i++) {
-		const TIFFField* fip = tif->tif_fields[i];
-		fprintf(fd, "field[%2d] %5lu, %2d, %2d, %d, %2d, %5s, %5s, %s\n"
-			, (int)i
-			, (unsigned long) fip->field_tag
-			, fip->field_readcount, fip->field_writecount
-			, fip->field_type
-			, fip->field_bit
-			, fip->field_oktochange ? "TRUE" : "FALSE"
-			, fip->field_passcount ? "TRUE" : "FALSE"
-			, fip->field_name
-		);
-	}
-}
-
-/*
- * Return size of TIFFDataType in bytes
- */
-int
-TIFFDataWidth(TIFFDataType type)
-{
-	switch(type)
-	{
-		case 0:  /* nothing */
-		case TIFF_BYTE:
-		case TIFF_ASCII:
-		case TIFF_SBYTE:
-		case TIFF_UNDEFINED:
-			return 1;
-		case TIFF_SHORT:
-		case TIFF_SSHORT:
-			return 2;
-		case TIFF_LONG:
-		case TIFF_SLONG:
-		case TIFF_FLOAT:
-		case TIFF_IFD:
-			return 4;
-		case TIFF_RATIONAL:
-		case TIFF_SRATIONAL:
-		case TIFF_DOUBLE:
-		case TIFF_LONG8:
-		case TIFF_SLONG8:
-		case TIFF_IFD8:
-			return 8;
-		default:
-			return 0; /* will return 0 for unknown types */
-	}
-}
-
-/*
- * Return size of TIFFDataType in bytes.
- *
- * XXX: We need a separate function to determine the space needed
- * to store the value. For TIFF_RATIONAL values TIFFDataWidth() returns 8,
- * but we use 4-byte float to represent rationals.
- */
-int
-_TIFFDataSize(TIFFDataType type)
-{
-	switch (type)
-	{
-		case TIFF_BYTE:
-		case TIFF_SBYTE:
-		case TIFF_ASCII:
-		case TIFF_UNDEFINED:
-		    return 1;
-		case TIFF_SHORT:
-		case TIFF_SSHORT:
-		    return 2;
-		case TIFF_LONG:
-		case TIFF_SLONG:
-		case TIFF_FLOAT:
-		case TIFF_IFD:
-		case TIFF_RATIONAL:
-		case TIFF_SRATIONAL:
-		    return 4;
-		case TIFF_DOUBLE:
-		case TIFF_LONG8:
-		case TIFF_SLONG8:
-		case TIFF_IFD8:
-		    return 8;
-		default:
-		    return 0;
-	}
-}
-
-const TIFFField*
-TIFFFindField(TIFF* tif, uint32 tag, TIFFDataType dt)
-{
-	TIFFField key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0, 0, 0, NULL, NULL};
-	TIFFField* pkey = &key;
-	const TIFFField **ret;
-	if (tif->tif_foundfield && tif->tif_foundfield->field_tag == tag &&
-	    (dt == TIFF_ANY || dt == tif->tif_foundfield->field_type))
-		return tif->tif_foundfield;
-
-	/* If we are invoked with no field information, then just return. */
-	if (!tif->tif_fields)
-		return NULL;
-
-	/* NB: use sorted search (e.g. binary search) */
-
-	key.field_tag = tag;
-	key.field_type = dt;
-
-	ret = (const TIFFField **) bsearch(&pkey, tif->tif_fields,
-					   tif->tif_nfields,
-					   sizeof(TIFFField *), tagCompare);
-	return tif->tif_foundfield = (ret ? *ret : NULL);
-}
-
-const TIFFField*
-_TIFFFindFieldByName(TIFF* tif, const char *field_name, TIFFDataType dt)
-{
-	TIFFField key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0, 0, 0, NULL, NULL};
-	TIFFField* pkey = &key;
-	const TIFFField **ret;
-	if (tif->tif_foundfield
-	    && streq(tif->tif_foundfield->field_name, field_name)
-	    && (dt == TIFF_ANY || dt == tif->tif_foundfield->field_type))
-		return (tif->tif_foundfield);
-
-	/* If we are invoked with no field information, then just return. */
-	if (!tif->tif_fields)
-		return NULL;
-
-	/* NB: use linear search since list is sorted by key#, not name */
-
-	key.field_name = (char *)field_name;
-	key.field_type = dt;
-
-	ret = (const TIFFField **) 
-            td_lfind(&pkey, tif->tif_fields, &tif->tif_nfields,
-                     sizeof(TIFFField *), tagNameCompare);
-
-	return tif->tif_foundfield = (ret ? *ret : NULL);
-}
-
-const TIFFField*
-TIFFFieldWithTag(TIFF* tif, uint32 tag)
-{
-	const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY);
-	if (!fip) {
-		TIFFErrorExt(tif->tif_clientdata, "TIFFFieldWithTag",
-			     "Internal error, unknown tag 0x%x",
-			     (unsigned int) tag);
-	}
-	return (fip);
-}
-
-const TIFFField*
-TIFFFieldWithName(TIFF* tif, const char *field_name)
-{
-	const TIFFField* fip =
-		_TIFFFindFieldByName(tif, field_name, TIFF_ANY);
-	if (!fip) {
-		TIFFErrorExt(tif->tif_clientdata, "TIFFFieldWithName",
-			     "Internal error, unknown tag %s", field_name);
-	}
-	return (fip);
-}
-
-uint32
-TIFFFieldTag(const TIFFField* fip)
-{
-	return fip->field_tag;
-}
-
-const char *
-TIFFFieldName(const TIFFField* fip)
-{
-	return fip->field_name;
-}
-
-TIFFDataType
-TIFFFieldDataType(const TIFFField* fip)
-{
-	return fip->field_type;
-}
-
-int
-TIFFFieldPassCount(const TIFFField* fip)
-{
-	return fip->field_passcount;
-}
-
-int
-TIFFFieldReadCount(const TIFFField* fip)
-{
-	return fip->field_readcount;
-}
-
-int
-TIFFFieldWriteCount(const TIFFField* fip)
-{
-	return fip->field_writecount;
-}
-
-const TIFFField*
-_TIFFFindOrRegisterField(TIFF *tif, uint32 tag, TIFFDataType dt)
-
-{
-	const TIFFField *fld;
-
-	fld = TIFFFindField(tif, tag, dt);
-	if (fld == NULL) {
-		fld = _TIFFCreateAnonField(tif, tag, dt);
-		if (!_TIFFMergeFields(tif, fld, 1))
-			return NULL;
-	}
-
-	return fld;
-}
-
-TIFFField*
-_TIFFCreateAnonField(TIFF *tif, uint32 tag, TIFFDataType field_type)
-{
-	TIFFField *fld;
-	(void) tif;
-
-	fld = (TIFFField *) _TIFFmalloc(sizeof (TIFFField));
-	if (fld == NULL)
-	    return NULL;
-	_TIFFmemset(fld, 0, sizeof(TIFFField));
-
-	fld->field_tag = tag;
-	fld->field_readcount = TIFF_VARIABLE2;
-	fld->field_writecount = TIFF_VARIABLE2;
-	fld->field_type = field_type;
-	fld->reserved = 0;
-	switch (field_type)
-	{
-		case TIFF_BYTE:
-		case TIFF_UNDEFINED:
-			fld->set_field_type = TIFF_SETGET_C32_UINT8;
-			fld->get_field_type = TIFF_SETGET_C32_UINT8;
-			break;
-		case TIFF_ASCII:
-			fld->set_field_type = TIFF_SETGET_C32_ASCII;
-			fld->get_field_type = TIFF_SETGET_C32_ASCII;
-			break;
-		case TIFF_SHORT:
-			fld->set_field_type = TIFF_SETGET_C32_UINT16;
-			fld->get_field_type = TIFF_SETGET_C32_UINT16;
-			break;
-		case TIFF_LONG:
-			fld->set_field_type = TIFF_SETGET_C32_UINT32;
-			fld->get_field_type = TIFF_SETGET_C32_UINT32;
-			break;
-		case TIFF_RATIONAL:
-		case TIFF_SRATIONAL:
-		case TIFF_FLOAT:
-			fld->set_field_type = TIFF_SETGET_C32_FLOAT;
-			fld->get_field_type = TIFF_SETGET_C32_FLOAT;
-			break;
-		case TIFF_SBYTE:
-			fld->set_field_type = TIFF_SETGET_C32_SINT8;
-			fld->get_field_type = TIFF_SETGET_C32_SINT8;
-			break;
-		case TIFF_SSHORT:
-			fld->set_field_type = TIFF_SETGET_C32_SINT16;
-			fld->get_field_type = TIFF_SETGET_C32_SINT16;
-			break;
-		case TIFF_SLONG:
-			fld->set_field_type = TIFF_SETGET_C32_SINT32;
-			fld->get_field_type = TIFF_SETGET_C32_SINT32;
-			break;
-		case TIFF_DOUBLE:
-			fld->set_field_type = TIFF_SETGET_C32_DOUBLE;
-			fld->get_field_type = TIFF_SETGET_C32_DOUBLE;
-			break;
-		case TIFF_IFD:
-		case TIFF_IFD8:
-			fld->set_field_type = TIFF_SETGET_C32_IFD8;
-			fld->get_field_type = TIFF_SETGET_C32_IFD8;
-			break;
-		case TIFF_LONG8:
-			fld->set_field_type = TIFF_SETGET_C32_UINT64;
-			fld->get_field_type = TIFF_SETGET_C32_UINT64;
-			break;
-		case TIFF_SLONG8:
-			fld->set_field_type = TIFF_SETGET_C32_SINT64;
-			fld->get_field_type = TIFF_SETGET_C32_SINT64;
-			break;
-		default:
-			fld->set_field_type = TIFF_SETGET_UNDEFINED;
-			fld->get_field_type = TIFF_SETGET_UNDEFINED;
-			break;
-	}
-	fld->field_bit = FIELD_CUSTOM;
-	fld->field_oktochange = TRUE;
-	fld->field_passcount = TRUE;
-	fld->field_name = (char *) _TIFFmalloc(32);
-	if (fld->field_name == NULL) {
-	    _TIFFfree(fld);
-	    return NULL;
-	}
-	fld->field_subfields = NULL;
-
-	/* 
-	 * note that this name is a special sign to TIFFClose() and
-	 * _TIFFSetupFields() to free the field
-	 */
-	sprintf(fld->field_name, "Tag %d", (int) tag);
-
-	return fld;    
-}
-
-/****************************************************************************
- *               O B S O L E T E D    I N T E R F A C E S
- *
- * Don't use this stuff in your applications, it may be removed in the future
- * libtiff versions.
- ****************************************************************************/
-
-static TIFFSetGetFieldType
-_TIFFSetGetType(TIFFDataType type, short count, unsigned char passcount)
-{
-	if (type == TIFF_ASCII && count == TIFF_VARIABLE && passcount == 0)
-		return TIFF_SETGET_ASCII;
-
-	else if (count == 1 && passcount == 0) {
-		switch (type)
-		{
-			case TIFF_BYTE:
-			case TIFF_UNDEFINED:
-				return TIFF_SETGET_UINT8;
-			case TIFF_ASCII:
-				return TIFF_SETGET_ASCII;
-			case TIFF_SHORT:
-				return TIFF_SETGET_UINT16;
-			case TIFF_LONG:
-				return TIFF_SETGET_UINT32;
-			case TIFF_RATIONAL:
-			case TIFF_SRATIONAL:
-			case TIFF_FLOAT:
-				return TIFF_SETGET_FLOAT;
-			case TIFF_SBYTE:
-				return TIFF_SETGET_SINT8;
-			case TIFF_SSHORT:
-				return TIFF_SETGET_SINT16;
-			case TIFF_SLONG:
-				return TIFF_SETGET_SINT32;
-			case TIFF_DOUBLE:
-				return TIFF_SETGET_DOUBLE;
-			case TIFF_IFD:
-			case TIFF_IFD8:
-				return TIFF_SETGET_IFD8;
-			case TIFF_LONG8:
-				return TIFF_SETGET_UINT64;
-			case TIFF_SLONG8:
-				return TIFF_SETGET_SINT64;
-			default:
-				return TIFF_SETGET_UNDEFINED;
-		}
-	}
-
-	else if (count >= 1 && passcount == 0) {
-		switch (type)
-		{
-			case TIFF_BYTE:
-			case TIFF_UNDEFINED:
-				return TIFF_SETGET_C0_UINT8;
-			case TIFF_ASCII:
-				return TIFF_SETGET_C0_ASCII;
-			case TIFF_SHORT:
-				return TIFF_SETGET_C0_UINT16;
-			case TIFF_LONG:
-				return TIFF_SETGET_C0_UINT32;
-			case TIFF_RATIONAL:
-			case TIFF_SRATIONAL:
-			case TIFF_FLOAT:
-				return TIFF_SETGET_C0_FLOAT;
-			case TIFF_SBYTE:
-				return TIFF_SETGET_C0_SINT8;
-			case TIFF_SSHORT:
-				return TIFF_SETGET_C0_SINT16;
-			case TIFF_SLONG:
-				return TIFF_SETGET_C0_SINT32;
-			case TIFF_DOUBLE:
-				return TIFF_SETGET_C0_DOUBLE;
-			case TIFF_IFD:
-			case TIFF_IFD8:
-				return TIFF_SETGET_C0_IFD8;
-			case TIFF_LONG8:
-				return TIFF_SETGET_C0_UINT64;
-			case TIFF_SLONG8:
-				return TIFF_SETGET_C0_SINT64;
-			default:
-				return TIFF_SETGET_UNDEFINED;
-		}
-	}
-
-	else if (count == TIFF_VARIABLE && passcount == 1) {
-		switch (type)
-		{
-			case TIFF_BYTE:
-			case TIFF_UNDEFINED:
-				return TIFF_SETGET_C16_UINT8;
-			case TIFF_ASCII:
-				return TIFF_SETGET_C16_ASCII;
-			case TIFF_SHORT:
-				return TIFF_SETGET_C16_UINT16;
-			case TIFF_LONG:
-				return TIFF_SETGET_C16_UINT32;
-			case TIFF_RATIONAL:
-			case TIFF_SRATIONAL:
-			case TIFF_FLOAT:
-				return TIFF_SETGET_C16_FLOAT;
-			case TIFF_SBYTE:
-				return TIFF_SETGET_C16_SINT8;
-			case TIFF_SSHORT:
-				return TIFF_SETGET_C16_SINT16;
-			case TIFF_SLONG:
-				return TIFF_SETGET_C16_SINT32;
-			case TIFF_DOUBLE:
-				return TIFF_SETGET_C16_DOUBLE;
-			case TIFF_IFD:
-			case TIFF_IFD8:
-				return TIFF_SETGET_C16_IFD8;
-			case TIFF_LONG8:
-				return TIFF_SETGET_C16_UINT64;
-			case TIFF_SLONG8:
-				return TIFF_SETGET_C16_SINT64;
-			default:
-				return TIFF_SETGET_UNDEFINED;
-		}
-	}
-
-	else if (count == TIFF_VARIABLE2 && passcount == 1) {
-		switch (type)
-		{
-			case TIFF_BYTE:
-			case TIFF_UNDEFINED:
-				return TIFF_SETGET_C32_UINT8;
-			case TIFF_ASCII:
-				return TIFF_SETGET_C32_ASCII;
-			case TIFF_SHORT:
-				return TIFF_SETGET_C32_UINT16;
-			case TIFF_LONG:
-				return TIFF_SETGET_C32_UINT32;
-			case TIFF_RATIONAL:
-			case TIFF_SRATIONAL:
-			case TIFF_FLOAT:
-				return TIFF_SETGET_C32_FLOAT;
-			case TIFF_SBYTE:
-				return TIFF_SETGET_C32_SINT8;
-			case TIFF_SSHORT:
-				return TIFF_SETGET_C32_SINT16;
-			case TIFF_SLONG:
-				return TIFF_SETGET_C32_SINT32;
-			case TIFF_DOUBLE:
-				return TIFF_SETGET_C32_DOUBLE;
-			case TIFF_IFD:
-			case TIFF_IFD8:
-				return TIFF_SETGET_C32_IFD8;
-			case TIFF_LONG8:
-				return TIFF_SETGET_C32_UINT64;
-			case TIFF_SLONG8:
-				return TIFF_SETGET_C32_SINT64;
-			default:
-				return TIFF_SETGET_UNDEFINED;
-		}
-	}
-
-	return TIFF_SETGET_UNDEFINED;
-}
-
-int
-TIFFMergeFieldInfo(TIFF* tif, const TIFFFieldInfo info[], uint32 n)
-{
-	static const char module[] = "TIFFMergeFieldInfo";
-	static const char reason[] = "for fields array";
-	TIFFField *tp;
-	size_t nfields;
-	uint32 i;
-
-	if (tif->tif_nfieldscompat > 0) {
-		tif->tif_fieldscompat = (TIFFFieldArray *)
-			_TIFFCheckRealloc(tif, tif->tif_fieldscompat,
-					  tif->tif_nfieldscompat + 1,
-					  sizeof(TIFFFieldArray), reason);
-	} else {
-		tif->tif_fieldscompat = (TIFFFieldArray *)
-			_TIFFCheckMalloc(tif, 1, sizeof(TIFFFieldArray),
-					 reason);
-	}
-	if (!tif->tif_fieldscompat) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-			     "Failed to allocate fields array");
-		return -1;
-	}
-	nfields = tif->tif_nfieldscompat++;
-
-	tif->tif_fieldscompat[nfields].type = tfiatOther;
-	tif->tif_fieldscompat[nfields].allocated_size = n;
-	tif->tif_fieldscompat[nfields].count = n;
-	tif->tif_fieldscompat[nfields].fields =
-		(TIFFField *)_TIFFCheckMalloc(tif, n, sizeof(TIFFField),
-					      reason);
-	if (!tif->tif_fieldscompat[nfields].fields) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-			     "Failed to allocate fields array");
-		return -1;
-	}
-
-	tp = tif->tif_fieldscompat[nfields].fields;
-	for (i = 0; i < n; i++) {
-		tp->field_tag = info[i].field_tag;
-		tp->field_readcount = info[i].field_readcount;
-		tp->field_writecount = info[i].field_writecount;
-		tp->field_type = info[i].field_type;
-		tp->reserved = 0;
-		tp->set_field_type =
-		     _TIFFSetGetType(info[i].field_type,
-				info[i].field_readcount,
-				info[i].field_passcount);
-		tp->get_field_type =
-		     _TIFFSetGetType(info[i].field_type,
-				info[i].field_readcount,
-				info[i].field_passcount);
-		tp->field_bit = info[i].field_bit;
-		tp->field_oktochange = info[i].field_oktochange;
-		tp->field_passcount = info[i].field_passcount;
-		tp->field_name = info[i].field_name;
-		tp->field_subfields = NULL;
-		tp++;
-	}
-
-	if (!_TIFFMergeFields(tif, tif->tif_fieldscompat[nfields].fields, n)) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-			     "Setting up field info failed");
-		return -1;
-	}
-
-	return 0;
-}
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Id: tif_dirinfo.c,v 1.11 2015/02/19 22:39:58 drolon Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Core Directory Tag Support.
+ */
+#include "tiffiop.h"
+#include <stdlib.h>
+
+/*
+ * NOTE: THIS ARRAY IS ASSUMED TO BE SORTED BY TAG.
+ *
+ * NOTE: The second field (field_readcount) and third field (field_writecount)
+ *       sometimes use the values TIFF_VARIABLE (-1), TIFF_VARIABLE2 (-3)
+ *       and TIFF_SPP (-2). The macros should be used but would throw off
+ *       the formatting of the code, so please interprete the -1, -2 and -3
+ *       values accordingly.
+ */
+
+static TIFFFieldArray tiffFieldArray;
+static TIFFFieldArray exifFieldArray;
+
+static TIFFField
+tiffFields[] = {
+	{ TIFFTAG_SUBFILETYPE, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_SUBFILETYPE, 1, 0, "SubfileType", NULL },
+	{ TIFFTAG_OSUBFILETYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_SUBFILETYPE, 1, 0, "OldSubfileType", NULL },
+	{ TIFFTAG_IMAGEWIDTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_IMAGEDIMENSIONS, 0, 0, "ImageWidth", NULL },
+	{ TIFFTAG_IMAGELENGTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_IMAGEDIMENSIONS, 1, 0, "ImageLength", NULL },
+	{ TIFFTAG_BITSPERSAMPLE, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_BITSPERSAMPLE, 0, 0, "BitsPerSample", NULL },
+	{ TIFFTAG_COMPRESSION, -1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_COMPRESSION, 0, 0, "Compression", NULL },
+	{ TIFFTAG_PHOTOMETRIC, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_PHOTOMETRIC, 0, 0, "PhotometricInterpretation", NULL },
+	{ TIFFTAG_THRESHHOLDING, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_THRESHHOLDING, 1, 0, "Threshholding", NULL },
+	{ TIFFTAG_CELLWIDTH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "CellWidth", NULL },
+	{ TIFFTAG_CELLLENGTH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "CellLength", NULL },
+	{ TIFFTAG_FILLORDER, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_FILLORDER, 0, 0, "FillOrder", NULL },
+	{ TIFFTAG_DOCUMENTNAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DocumentName", NULL },
+	{ TIFFTAG_IMAGEDESCRIPTION, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageDescription", NULL },
+	{ TIFFTAG_MAKE, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Make", NULL },
+	{ TIFFTAG_MODEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Model", NULL },
+	{ TIFFTAG_STRIPOFFSETS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPOFFSETS, 0, 0, "StripOffsets", NULL },
+	{ TIFFTAG_ORIENTATION, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_ORIENTATION, 0, 0, "Orientation", NULL },
+	{ TIFFTAG_SAMPLESPERPIXEL, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_SAMPLESPERPIXEL, 0, 0, "SamplesPerPixel", NULL },
+	{ TIFFTAG_ROWSPERSTRIP, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_ROWSPERSTRIP, 0, 0, "RowsPerStrip", NULL },
+	{ TIFFTAG_STRIPBYTECOUNTS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPBYTECOUNTS, 0, 0, "StripByteCounts", NULL },
+	{ TIFFTAG_MINSAMPLEVALUE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_MINSAMPLEVALUE, 1, 0, "MinSampleValue", NULL },
+	{ TIFFTAG_MAXSAMPLEVALUE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_MAXSAMPLEVALUE, 1, 0, "MaxSampleValue", NULL },
+	{ TIFFTAG_XRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_RESOLUTION, 1, 0, "XResolution", NULL },
+	{ TIFFTAG_YRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_RESOLUTION, 1, 0, "YResolution", NULL },
+	{ TIFFTAG_PLANARCONFIG, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_PLANARCONFIG, 0, 0, "PlanarConfiguration", NULL },
+	{ TIFFTAG_PAGENAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PageName", NULL },
+	{ TIFFTAG_XPOSITION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_POSITION, 1, 0, "XPosition", NULL },
+	{ TIFFTAG_YPOSITION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_POSITION, 1, 0, "YPosition", NULL },
+	{ TIFFTAG_FREEOFFSETS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 0, 0, "FreeOffsets", NULL },
+	{ TIFFTAG_FREEBYTECOUNTS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 0, 0, "FreeByteCounts", NULL },
+	{ TIFFTAG_GRAYRESPONSEUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "GrayResponseUnit", NULL },
+	{ TIFFTAG_GRAYRESPONSECURVE, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "GrayResponseCurve", NULL },
+	{ TIFFTAG_RESOLUTIONUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_RESOLUTIONUNIT, 1, 0, "ResolutionUnit", NULL },
+	{ TIFFTAG_PAGENUMBER, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_PAGENUMBER, 1, 0, "PageNumber", NULL },
+	{ TIFFTAG_COLORRESPONSEUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "ColorResponseUnit", NULL },
+	{ TIFFTAG_TRANSFERFUNCTION, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_OTHER, TIFF_SETGET_UNDEFINED, FIELD_TRANSFERFUNCTION, 1, 0, "TransferFunction", NULL },
+	{ TIFFTAG_SOFTWARE, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Software", NULL },
+	{ TIFFTAG_DATETIME, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateTime", NULL },
+	{ TIFFTAG_ARTIST, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Artist", NULL },
+	{ TIFFTAG_HOSTCOMPUTER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "HostComputer", NULL },
+	{ TIFFTAG_WHITEPOINT, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "WhitePoint", NULL },
+	{ TIFFTAG_PRIMARYCHROMATICITIES, 6, 6, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PrimaryChromaticities", NULL },
+	{ TIFFTAG_COLORMAP, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_OTHER, TIFF_SETGET_UNDEFINED, FIELD_COLORMAP, 1, 0, "ColorMap", NULL },
+	{ TIFFTAG_HALFTONEHINTS, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_HALFTONEHINTS, 1, 0, "HalftoneHints", NULL },
+	{ TIFFTAG_TILEWIDTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_TILEDIMENSIONS, 0, 0, "TileWidth", NULL },
+	{ TIFFTAG_TILELENGTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_TILEDIMENSIONS, 0, 0, "TileLength", NULL },
+	{ TIFFTAG_TILEOFFSETS, -1, 1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPOFFSETS, 0, 0, "TileOffsets", NULL },
+	{ TIFFTAG_TILEBYTECOUNTS, -1, 1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPBYTECOUNTS, 0, 0, "TileByteCounts", NULL },
+	{ TIFFTAG_SUBIFD, -1, -1, TIFF_IFD8, 0, TIFF_SETGET_C16_IFD8, TIFF_SETGET_UNDEFINED, FIELD_SUBIFD, 1, 1, "SubIFD", &tiffFieldArray },
+	{ TIFFTAG_INKSET, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "InkSet", NULL },
+	{ TIFFTAG_INKNAMES, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_C16_ASCII, TIFF_SETGET_UNDEFINED, FIELD_INKNAMES, 1, 1, "InkNames", NULL },
+	{ TIFFTAG_NUMBEROFINKS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "NumberOfInks", NULL },
+	{ TIFFTAG_DOTRANGE, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DotRange", NULL },
+	{ TIFFTAG_TARGETPRINTER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TargetPrinter", NULL },
+	{ TIFFTAG_EXTRASAMPLES, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_EXTRASAMPLES, 0, 1, "ExtraSamples", NULL },
+	{ TIFFTAG_SAMPLEFORMAT, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_SAMPLEFORMAT, 0, 0, "SampleFormat", NULL },
+	{ TIFFTAG_SMINSAMPLEVALUE, -2, -1, TIFF_ANY, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_SMINSAMPLEVALUE, 1, 0, "SMinSampleValue", NULL },
+	{ TIFFTAG_SMAXSAMPLEVALUE, -2, -1, TIFF_ANY, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_SMAXSAMPLEVALUE, 1, 0, "SMaxSampleValue", NULL },
+	{ TIFFTAG_CLIPPATH, -1, -3, TIFF_BYTE, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ClipPath", NULL },
+	{ TIFFTAG_XCLIPPATHUNITS, 1, 1, TIFF_SLONG, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "XClipPathUnits", NULL },
+	{ TIFFTAG_XCLIPPATHUNITS, 1, 1, TIFF_SBYTE, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "XClipPathUnits", NULL },
+	{ TIFFTAG_YCLIPPATHUNITS, 1, 1, TIFF_SLONG, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "YClipPathUnits", NULL },
+	{ TIFFTAG_YCBCRCOEFFICIENTS, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "YCbCrCoefficients", NULL },
+	{ TIFFTAG_YCBCRSUBSAMPLING, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_YCBCRSUBSAMPLING, 0, 0, "YCbCrSubsampling", NULL },
+	{ TIFFTAG_YCBCRPOSITIONING, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_YCBCRPOSITIONING, 0, 0, "YCbCrPositioning", NULL },
+	{ TIFFTAG_REFERENCEBLACKWHITE, 6, 6, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_REFBLACKWHITE, 1, 0, "ReferenceBlackWhite", NULL },
+	{ TIFFTAG_XMLPACKET, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "XMLPacket", NULL },
+	/* begin SGI tags */
+	{ TIFFTAG_MATTEING, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_EXTRASAMPLES, 0, 0, "Matteing", NULL },
+	{ TIFFTAG_DATATYPE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_SAMPLEFORMAT, 0, 0, "DataType", NULL },
+	{ TIFFTAG_IMAGEDEPTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_IMAGEDEPTH, 0, 0, "ImageDepth", NULL },
+	{ TIFFTAG_TILEDEPTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_TILEDEPTH, 0, 0, "TileDepth", NULL },
+	/* end SGI tags */
+	/* begin Pixar tags */
+	{ TIFFTAG_PIXAR_IMAGEFULLWIDTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageFullWidth", NULL },
+	{ TIFFTAG_PIXAR_IMAGEFULLLENGTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageFullLength", NULL },
+	{ TIFFTAG_PIXAR_TEXTUREFORMAT, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TextureFormat", NULL },
+	{ TIFFTAG_PIXAR_WRAPMODES, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TextureWrapModes", NULL },
+	{ TIFFTAG_PIXAR_FOVCOT, 1, 1, TIFF_FLOAT, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FieldOfViewCotangent", NULL },
+	{ TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN, 16, 16, TIFF_FLOAT, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MatrixWorldToScreen", NULL },
+	{ TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA, 16, 16, TIFF_FLOAT, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MatrixWorldToCamera", NULL },
+	{ TIFFTAG_CFAREPEATPATTERNDIM, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED,	FIELD_CUSTOM, 0,	0,	"CFARepeatPatternDim", NULL },
+	{ TIFFTAG_CFAPATTERN,	4, 4,	TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0,	0,	"CFAPattern" , NULL},
+	{ TIFFTAG_COPYRIGHT, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Copyright", NULL },
+	/* end Pixar tags */
+	{ TIFFTAG_RICHTIFFIPTC, -3, -3, TIFF_LONG, 0, TIFF_SETGET_C32_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "RichTIFFIPTC", NULL },
+	{ TIFFTAG_PHOTOSHOP, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "Photoshop", NULL },
+	{ TIFFTAG_EXIFIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "EXIFIFDOffset", &exifFieldArray },
+	{ TIFFTAG_ICCPROFILE, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ICC Profile", NULL },
+	{ TIFFTAG_GPSIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "GPSIFDOffset", NULL },
+	{ TIFFTAG_FAXRECVPARAMS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_CUSTOM, TRUE, FALSE, "FaxRecvParams", NULL },
+	{ TIFFTAG_FAXSUBADDRESS, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_ASCII, FIELD_CUSTOM, TRUE, FALSE, "FaxSubAddress", NULL },
+	{ TIFFTAG_FAXRECVTIME, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_CUSTOM, TRUE, FALSE, "FaxRecvTime", NULL },
+	{ TIFFTAG_FAXDCS, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_ASCII, FIELD_CUSTOM, TRUE, FALSE, "FaxDcs", NULL },
+	{ TIFFTAG_STONITS, 1, 1, TIFF_DOUBLE, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "StoNits", NULL },
+	{ TIFFTAG_INTEROPERABILITYIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "InteroperabilityIFDOffset", NULL },
+	/* begin DNG tags */
+	{ TIFFTAG_DNGVERSION, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DNGVersion", NULL },
+	{ TIFFTAG_DNGBACKWARDVERSION, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DNGBackwardVersion", NULL },
+	{ TIFFTAG_UNIQUECAMERAMODEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "UniqueCameraModel", NULL },
+	{ TIFFTAG_LOCALIZEDCAMERAMODEL, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "LocalizedCameraModel", NULL },
+	{ TIFFTAG_CFAPLANECOLOR, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CFAPlaneColor", NULL },
+	{ TIFFTAG_CFALAYOUT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CFALayout", NULL },
+	{ TIFFTAG_LINEARIZATIONTABLE, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "LinearizationTable", NULL },
+	{ TIFFTAG_BLACKLEVELREPEATDIM, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BlackLevelRepeatDim", NULL },
+	{ TIFFTAG_BLACKLEVEL, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "BlackLevel", NULL },
+	{ TIFFTAG_BLACKLEVELDELTAH, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "BlackLevelDeltaH", NULL },
+	{ TIFFTAG_BLACKLEVELDELTAV, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "BlackLevelDeltaV", NULL },
+	{ TIFFTAG_WHITELEVEL, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "WhiteLevel", NULL },
+	{ TIFFTAG_DEFAULTSCALE, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DefaultScale", NULL },
+	{ TIFFTAG_BESTQUALITYSCALE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BestQualityScale", NULL },
+	{ TIFFTAG_DEFAULTCROPORIGIN, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DefaultCropOrigin", NULL },
+	{ TIFFTAG_DEFAULTCROPSIZE, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DefaultCropSize", NULL },
+	{ TIFFTAG_COLORMATRIX1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ColorMatrix1", NULL },
+	{ TIFFTAG_COLORMATRIX2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ColorMatrix2", NULL },
+	{ TIFFTAG_CAMERACALIBRATION1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CameraCalibration1", NULL },
+	{ TIFFTAG_CAMERACALIBRATION2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CameraCalibration2", NULL },
+	{ TIFFTAG_REDUCTIONMATRIX1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ReductionMatrix1", NULL },
+	{ TIFFTAG_REDUCTIONMATRIX2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ReductionMatrix2", NULL },
+	{ TIFFTAG_ANALOGBALANCE, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "AnalogBalance", NULL },
+	{ TIFFTAG_ASSHOTNEUTRAL, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "AsShotNeutral", NULL },
+	{ TIFFTAG_ASSHOTWHITEXY, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "AsShotWhiteXY", NULL },
+	{ TIFFTAG_BASELINEEXPOSURE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BaselineExposure", NULL },
+	{ TIFFTAG_BASELINENOISE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BaselineNoise", NULL },
+	{ TIFFTAG_BASELINESHARPNESS, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BaselineSharpness", NULL },
+	{ TIFFTAG_BAYERGREENSPLIT, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BayerGreenSplit", NULL },
+	{ TIFFTAG_LINEARRESPONSELIMIT, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "LinearResponseLimit", NULL },
+	{ TIFFTAG_CAMERASERIALNUMBER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CameraSerialNumber", NULL },
+	{ TIFFTAG_LENSINFO, 4, 4, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "LensInfo", NULL },
+	{ TIFFTAG_CHROMABLURRADIUS, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ChromaBlurRadius", NULL },
+	{ TIFFTAG_ANTIALIASSTRENGTH, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "AntiAliasStrength", NULL },
+	{ TIFFTAG_SHADOWSCALE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ShadowScale", NULL },
+	{ TIFFTAG_DNGPRIVATEDATA, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "DNGPrivateData", NULL },
+	{ TIFFTAG_MAKERNOTESAFETY, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "MakerNoteSafety", NULL },
+	{ TIFFTAG_CALIBRATIONILLUMINANT1, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CalibrationIlluminant1", NULL },
+	{ TIFFTAG_CALIBRATIONILLUMINANT2, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CalibrationIlluminant2", NULL },
+	{ TIFFTAG_RAWDATAUNIQUEID, 16, 16, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "RawDataUniqueID", NULL },
+	{ TIFFTAG_ORIGINALRAWFILENAME, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OriginalRawFileName", NULL },
+	{ TIFFTAG_ORIGINALRAWFILEDATA, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "OriginalRawFileData", NULL },
+	{ TIFFTAG_ACTIVEAREA, 4, 4, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ActiveArea", NULL },
+	{ TIFFTAG_MASKEDAREAS, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "MaskedAreas", NULL },
+	{ TIFFTAG_ASSHOTICCPROFILE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "AsShotICCProfile", NULL },
+	{ TIFFTAG_ASSHOTPREPROFILEMATRIX, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "AsShotPreProfileMatrix", NULL },
+	{ TIFFTAG_CURRENTICCPROFILE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CurrentICCProfile", NULL },
+	{ TIFFTAG_CURRENTPREPROFILEMATRIX, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CurrentPreProfileMatrix", NULL },
+	{ TIFFTAG_PERSAMPLE, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "PerSample", NULL},
+	/* end DNG tags */
+	/* begin TIFF/FX tags */
+        { TIFFTAG_INDEXED, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "Indexed", NULL },
+        { TIFFTAG_GLOBALPARAMETERSIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "GlobalParametersIFD", NULL },
+        { TIFFTAG_PROFILETYPE, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ProfileType", NULL },
+        { TIFFTAG_FAXPROFILE, 1, 1, TIFF_BYTE, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "FaxProfile", NULL },
+        { TIFFTAG_CODINGMETHODS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CodingMethods", NULL },
+        { TIFFTAG_VERSIONYEAR, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "VersionYear", NULL },
+        { TIFFTAG_MODENUMBER, 1, 1, TIFF_BYTE, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ModeNumber", NULL },
+        { TIFFTAG_DECODE, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "Decode", NULL },
+        { TIFFTAG_IMAGEBASECOLOR, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ImageBaseColor", NULL },
+        { TIFFTAG_T82OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "T82Options", NULL },
+        { TIFFTAG_STRIPROWCOUNTS, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "StripRowCounts", NULL },
+        { TIFFTAG_IMAGELAYER, 2, 2, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ImageLayer", NULL },
+	/* end TIFF/FX tags */
+	/* begin pseudo tags */
+};
+
+static TIFFField
+exifFields[] = {
+	{ EXIFTAG_EXPOSURETIME, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureTime", NULL },
+	{ EXIFTAG_FNUMBER, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FNumber", NULL },
+	{ EXIFTAG_EXPOSUREPROGRAM, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureProgram", NULL },
+	{ EXIFTAG_SPECTRALSENSITIVITY, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SpectralSensitivity", NULL },
+	{ EXIFTAG_ISOSPEEDRATINGS, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ISOSpeedRatings", NULL },
+	{ EXIFTAG_OECF, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OptoelectricConversionFactor", NULL },
+	{ EXIFTAG_EXIFVERSION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExifVersion", NULL },
+	{ EXIFTAG_DATETIMEORIGINAL, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateTimeOriginal", NULL },
+	{ EXIFTAG_DATETIMEDIGITIZED, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateTimeDigitized", NULL },
+	{ EXIFTAG_COMPONENTSCONFIGURATION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ComponentsConfiguration", NULL },
+	{ EXIFTAG_COMPRESSEDBITSPERPIXEL, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CompressedBitsPerPixel", NULL },
+	{ EXIFTAG_SHUTTERSPEEDVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ShutterSpeedValue", NULL },
+	{ EXIFTAG_APERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ApertureValue", NULL },
+	{ EXIFTAG_BRIGHTNESSVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BrightnessValue", NULL },
+	{ EXIFTAG_EXPOSUREBIASVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureBiasValue", NULL },
+	{ EXIFTAG_MAXAPERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MaxApertureValue", NULL },
+	{ EXIFTAG_SUBJECTDISTANCE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectDistance", NULL },
+	{ EXIFTAG_METERINGMODE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MeteringMode", NULL },
+	{ EXIFTAG_LIGHTSOURCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LightSource", NULL },
+	{ EXIFTAG_FLASH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Flash", NULL },
+	{ EXIFTAG_FOCALLENGTH, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalLength", NULL },
+	{ EXIFTAG_SUBJECTAREA, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "SubjectArea", NULL },
+	{ EXIFTAG_MAKERNOTE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "MakerNote", NULL },
+	{ EXIFTAG_USERCOMMENT, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "UserComment", NULL },
+	{ EXIFTAG_SUBSECTIME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTime", NULL },
+	{ EXIFTAG_SUBSECTIMEORIGINAL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTimeOriginal", NULL },
+	{ EXIFTAG_SUBSECTIMEDIGITIZED, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTimeDigitized", NULL },
+	{ EXIFTAG_FLASHPIXVERSION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FlashpixVersion", NULL },
+	{ EXIFTAG_COLORSPACE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ColorSpace", NULL },
+	{ EXIFTAG_PIXELXDIMENSION, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PixelXDimension", NULL },
+	{ EXIFTAG_PIXELYDIMENSION, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PixelYDimension", NULL },
+	{ EXIFTAG_RELATEDSOUNDFILE, 13, 13, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "RelatedSoundFile", NULL },
+	{ EXIFTAG_FLASHENERGY, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FlashEnergy", NULL },
+	{ EXIFTAG_SPATIALFREQUENCYRESPONSE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "SpatialFrequencyResponse", NULL },
+	{ EXIFTAG_FOCALPLANEXRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneXResolution", NULL },
+	{ EXIFTAG_FOCALPLANEYRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneYResolution", NULL },
+	{ EXIFTAG_FOCALPLANERESOLUTIONUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneResolutionUnit", NULL },
+	{ EXIFTAG_SUBJECTLOCATION, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectLocation", NULL },
+	{ EXIFTAG_EXPOSUREINDEX, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureIndex", NULL },
+	{ EXIFTAG_SENSINGMETHOD, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SensingMethod", NULL },
+	{ EXIFTAG_FILESOURCE, 1, 1, TIFF_UNDEFINED, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FileSource", NULL },
+	{ EXIFTAG_SCENETYPE, 1, 1, TIFF_UNDEFINED, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SceneType", NULL },
+	{ EXIFTAG_CFAPATTERN, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CFAPattern", NULL },
+	{ EXIFTAG_CUSTOMRENDERED, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CustomRendered", NULL },
+	{ EXIFTAG_EXPOSUREMODE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureMode", NULL },
+	{ EXIFTAG_WHITEBALANCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "WhiteBalance", NULL },
+	{ EXIFTAG_DIGITALZOOMRATIO, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DigitalZoomRatio", NULL },
+	{ EXIFTAG_FOCALLENGTHIN35MMFILM, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalLengthIn35mmFilm", NULL },
+	{ EXIFTAG_SCENECAPTURETYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SceneCaptureType", NULL },
+	{ EXIFTAG_GAINCONTROL, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "GainControl", NULL },
+	{ EXIFTAG_CONTRAST, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Contrast", NULL },
+	{ EXIFTAG_SATURATION, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Saturation", NULL },
+	{ EXIFTAG_SHARPNESS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Sharpness", NULL },
+	{ EXIFTAG_DEVICESETTINGDESCRIPTION, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "DeviceSettingDescription", NULL },
+	{ EXIFTAG_SUBJECTDISTANCERANGE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectDistanceRange", NULL },
+	{ EXIFTAG_IMAGEUNIQUEID, 33, 33, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageUniqueID", NULL }
+};
+
+static TIFFFieldArray
+tiffFieldArray = { tfiatImage, 0, TIFFArrayCount(tiffFields), tiffFields };
+static TIFFFieldArray
+exifFieldArray = { tfiatExif, 0, TIFFArrayCount(exifFields), exifFields };
+
+/*
+ *  We have our own local lfind() equivelent to avoid subtle differences
+ *  in types passed to lfind() on different systems. 
+ */
+
+static void *
+td_lfind(const void *key, const void *base, size_t *nmemb, size_t size,
+         int(*compar)(const void *, const void *))
+{
+    char *element, *end;
+
+    end = (char *)base + *nmemb * size;
+    for (element = (char *)base; element < end; element += size)
+        if (!compar(key, element))		/* key found */
+            return element;
+
+    return NULL;
+}
+
+const TIFFFieldArray*
+_TIFFGetFields(void)
+{
+	return(&tiffFieldArray);
+}
+
+const TIFFFieldArray*
+_TIFFGetExifFields(void)
+{
+	return(&exifFieldArray);
+}
+
+void
+_TIFFSetupFields(TIFF* tif, const TIFFFieldArray* fieldarray)
+{
+	if (tif->tif_fields && tif->tif_nfields > 0) {
+		uint32 i;
+
+		for (i = 0; i < tif->tif_nfields; i++) {
+			TIFFField *fld = tif->tif_fields[i];
+			if (fld->field_bit == FIELD_CUSTOM &&
+				strncmp("Tag ", fld->field_name, 4) == 0) {
+					_TIFFfree(fld->field_name);
+					_TIFFfree(fld);
+				}
+		}
+
+		_TIFFfree(tif->tif_fields);
+		tif->tif_fields = NULL;
+		tif->tif_nfields = 0;
+	}
+	if (!_TIFFMergeFields(tif, fieldarray->fields, fieldarray->count)) {
+		TIFFErrorExt(tif->tif_clientdata, "_TIFFSetupFields",
+			     "Setting up field info failed");
+	}
+}
+
+static int
+tagCompare(const void* a, const void* b)
+{
+	const TIFFField* ta = *(const TIFFField**) a;
+	const TIFFField* tb = *(const TIFFField**) b;
+	/* NB: be careful of return values for 16-bit platforms */
+	if (ta->field_tag != tb->field_tag)
+		return (int)ta->field_tag - (int)tb->field_tag;
+	else
+		return (ta->field_type == TIFF_ANY) ?
+			0 : ((int)tb->field_type - (int)ta->field_type);
+}
+
+static int
+tagNameCompare(const void* a, const void* b)
+{
+	const TIFFField* ta = *(const TIFFField**) a;
+	const TIFFField* tb = *(const TIFFField**) b;
+	int ret = strcmp(ta->field_name, tb->field_name);
+
+	if (ret)
+		return ret;
+	else
+		return (ta->field_type == TIFF_ANY) ?
+			0 : ((int)tb->field_type - (int)ta->field_type);
+}
+
+int
+_TIFFMergeFields(TIFF* tif, const TIFFField info[], uint32 n)
+{
+	static const char module[] = "_TIFFMergeFields";
+	static const char reason[] = "for fields array";
+	/* TIFFField** tp; */
+	uint32 i;
+
+        tif->tif_foundfield = NULL;
+
+	if (tif->tif_fields && tif->tif_nfields > 0) {
+		tif->tif_fields = (TIFFField**)
+			_TIFFCheckRealloc(tif, tif->tif_fields,
+					  (tif->tif_nfields + n),
+					  sizeof(TIFFField *), reason);
+	} else {
+		tif->tif_fields = (TIFFField **)
+			_TIFFCheckMalloc(tif, n, sizeof(TIFFField *),
+					 reason);
+	}
+	if (!tif->tif_fields) {
+		TIFFErrorExt(tif->tif_clientdata, module,
+			     "Failed to allocate fields array");
+		return 0;
+	}
+
+	/* tp = tif->tif_fields + tif->tif_nfields; */
+	for (i = 0; i < n; i++) {
+		const TIFFField *fip =
+			TIFFFindField(tif, info[i].field_tag, TIFF_ANY);
+
+                /* only add definitions that aren't already present */
+		if (!fip) {
+                        tif->tif_fields[tif->tif_nfields] = (TIFFField *) (info+i);
+                        tif->tif_nfields++;
+                }
+	}
+
+        /* Sort the field info by tag number */
+	qsort(tif->tif_fields, tif->tif_nfields,
+	      sizeof(TIFFField *), tagCompare);
+
+	return n;
+}
+
+void
+_TIFFPrintFieldInfo(TIFF* tif, FILE* fd)
+{
+	uint32 i;
+
+	fprintf(fd, "%s: \n", tif->tif_name);
+	for (i = 0; i < tif->tif_nfields; i++) {
+		const TIFFField* fip = tif->tif_fields[i];
+		fprintf(fd, "field[%2d] %5lu, %2d, %2d, %d, %2d, %5s, %5s, %s\n"
+			, (int)i
+			, (unsigned long) fip->field_tag
+			, fip->field_readcount, fip->field_writecount
+			, fip->field_type
+			, fip->field_bit
+			, fip->field_oktochange ? "TRUE" : "FALSE"
+			, fip->field_passcount ? "TRUE" : "FALSE"
+			, fip->field_name
+		);
+	}
+}
+
+/*
+ * Return size of TIFFDataType in bytes
+ */
+int
+TIFFDataWidth(TIFFDataType type)
+{
+	switch(type)
+	{
+		case 0:  /* nothing */
+		case TIFF_BYTE:
+		case TIFF_ASCII:
+		case TIFF_SBYTE:
+		case TIFF_UNDEFINED:
+			return 1;
+		case TIFF_SHORT:
+		case TIFF_SSHORT:
+			return 2;
+		case TIFF_LONG:
+		case TIFF_SLONG:
+		case TIFF_FLOAT:
+		case TIFF_IFD:
+			return 4;
+		case TIFF_RATIONAL:
+		case TIFF_SRATIONAL:
+		case TIFF_DOUBLE:
+		case TIFF_LONG8:
+		case TIFF_SLONG8:
+		case TIFF_IFD8:
+			return 8;
+		default:
+			return 0; /* will return 0 for unknown types */
+	}
+}
+
+/*
+ * Return size of TIFFDataType in bytes.
+ *
+ * XXX: We need a separate function to determine the space needed
+ * to store the value. For TIFF_RATIONAL values TIFFDataWidth() returns 8,
+ * but we use 4-byte float to represent rationals.
+ */
+int
+_TIFFDataSize(TIFFDataType type)
+{
+	switch (type)
+	{
+		case TIFF_BYTE:
+		case TIFF_SBYTE:
+		case TIFF_ASCII:
+		case TIFF_UNDEFINED:
+		    return 1;
+		case TIFF_SHORT:
+		case TIFF_SSHORT:
+		    return 2;
+		case TIFF_LONG:
+		case TIFF_SLONG:
+		case TIFF_FLOAT:
+		case TIFF_IFD:
+		case TIFF_RATIONAL:
+		case TIFF_SRATIONAL:
+		    return 4;
+		case TIFF_DOUBLE:
+		case TIFF_LONG8:
+		case TIFF_SLONG8:
+		case TIFF_IFD8:
+		    return 8;
+		default:
+		    return 0;
+	}
+}
+
+const TIFFField*
+TIFFFindField(TIFF* tif, uint32 tag, TIFFDataType dt)
+{
+	TIFFField key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0, 0, 0, NULL, NULL};
+	TIFFField* pkey = &key;
+	const TIFFField **ret;
+	if (tif->tif_foundfield && tif->tif_foundfield->field_tag == tag &&
+	    (dt == TIFF_ANY || dt == tif->tif_foundfield->field_type))
+		return tif->tif_foundfield;
+
+	/* If we are invoked with no field information, then just return. */
+	if (!tif->tif_fields)
+		return NULL;
+
+	/* NB: use sorted search (e.g. binary search) */
+
+	key.field_tag = tag;
+	key.field_type = dt;
+
+	ret = (const TIFFField **) bsearch(&pkey, tif->tif_fields,
+					   tif->tif_nfields,
+					   sizeof(TIFFField *), tagCompare);
+	return tif->tif_foundfield = (ret ? *ret : NULL);
+}
+
+const TIFFField*
+_TIFFFindFieldByName(TIFF* tif, const char *field_name, TIFFDataType dt)
+{
+	TIFFField key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0, 0, 0, NULL, NULL};
+	TIFFField* pkey = &key;
+	const TIFFField **ret;
+	if (tif->tif_foundfield
+	    && streq(tif->tif_foundfield->field_name, field_name)
+	    && (dt == TIFF_ANY || dt == tif->tif_foundfield->field_type))
+		return (tif->tif_foundfield);
+
+	/* If we are invoked with no field information, then just return. */
+	if (!tif->tif_fields)
+		return NULL;
+
+	/* NB: use linear search since list is sorted by key#, not name */
+
+	key.field_name = (char *)field_name;
+	key.field_type = dt;
+
+	ret = (const TIFFField **) 
+            td_lfind(&pkey, tif->tif_fields, &tif->tif_nfields,
+                     sizeof(TIFFField *), tagNameCompare);
+
+	return tif->tif_foundfield = (ret ? *ret : NULL);
+}
+
+const TIFFField*
+TIFFFieldWithTag(TIFF* tif, uint32 tag)
+{
+	const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY);
+	if (!fip) {
+		TIFFErrorExt(tif->tif_clientdata, "TIFFFieldWithTag",
+			     "Internal error, unknown tag 0x%x",
+			     (unsigned int) tag);
+	}
+	return (fip);
+}
+
+const TIFFField*
+TIFFFieldWithName(TIFF* tif, const char *field_name)
+{
+	const TIFFField* fip =
+		_TIFFFindFieldByName(tif, field_name, TIFF_ANY);
+	if (!fip) {
+		TIFFErrorExt(tif->tif_clientdata, "TIFFFieldWithName",
+			     "Internal error, unknown tag %s", field_name);
+	}
+	return (fip);
+}
+
+uint32
+TIFFFieldTag(const TIFFField* fip)
+{
+	return fip->field_tag;
+}
+
+const char *
+TIFFFieldName(const TIFFField* fip)
+{
+	return fip->field_name;
+}
+
+TIFFDataType
+TIFFFieldDataType(const TIFFField* fip)
+{
+	return fip->field_type;
+}
+
+int
+TIFFFieldPassCount(const TIFFField* fip)
+{
+	return fip->field_passcount;
+}
+
+int
+TIFFFieldReadCount(const TIFFField* fip)
+{
+	return fip->field_readcount;
+}
+
+int
+TIFFFieldWriteCount(const TIFFField* fip)
+{
+	return fip->field_writecount;
+}
+
+const TIFFField*
+_TIFFFindOrRegisterField(TIFF *tif, uint32 tag, TIFFDataType dt)
+
+{
+	const TIFFField *fld;
+
+	fld = TIFFFindField(tif, tag, dt);
+	if (fld == NULL) {
+		fld = _TIFFCreateAnonField(tif, tag, dt);
+		if (!_TIFFMergeFields(tif, fld, 1))
+			return NULL;
+	}
+
+	return fld;
+}
+
+TIFFField*
+_TIFFCreateAnonField(TIFF *tif, uint32 tag, TIFFDataType field_type)
+{
+	TIFFField *fld;
+	(void) tif;
+
+	fld = (TIFFField *) _TIFFmalloc(sizeof (TIFFField));
+	if (fld == NULL)
+	    return NULL;
+	_TIFFmemset(fld, 0, sizeof(TIFFField));
+
+	fld->field_tag = tag;
+	fld->field_readcount = TIFF_VARIABLE2;
+	fld->field_writecount = TIFF_VARIABLE2;
+	fld->field_type = field_type;
+	fld->reserved = 0;
+	switch (field_type)
+	{
+		case TIFF_BYTE:
+		case TIFF_UNDEFINED:
+			fld->set_field_type = TIFF_SETGET_C32_UINT8;
+			fld->get_field_type = TIFF_SETGET_C32_UINT8;
+			break;
+		case TIFF_ASCII:
+			fld->set_field_type = TIFF_SETGET_C32_ASCII;
+			fld->get_field_type = TIFF_SETGET_C32_ASCII;
+			break;
+		case TIFF_SHORT:
+			fld->set_field_type = TIFF_SETGET_C32_UINT16;
+			fld->get_field_type = TIFF_SETGET_C32_UINT16;
+			break;
+		case TIFF_LONG:
+			fld->set_field_type = TIFF_SETGET_C32_UINT32;
+			fld->get_field_type = TIFF_SETGET_C32_UINT32;
+			break;
+		case TIFF_RATIONAL:
+		case TIFF_SRATIONAL:
+		case TIFF_FLOAT:
+			fld->set_field_type = TIFF_SETGET_C32_FLOAT;
+			fld->get_field_type = TIFF_SETGET_C32_FLOAT;
+			break;
+		case TIFF_SBYTE:
+			fld->set_field_type = TIFF_SETGET_C32_SINT8;
+			fld->get_field_type = TIFF_SETGET_C32_SINT8;
+			break;
+		case TIFF_SSHORT:
+			fld->set_field_type = TIFF_SETGET_C32_SINT16;
+			fld->get_field_type = TIFF_SETGET_C32_SINT16;
+			break;
+		case TIFF_SLONG:
+			fld->set_field_type = TIFF_SETGET_C32_SINT32;
+			fld->get_field_type = TIFF_SETGET_C32_SINT32;
+			break;
+		case TIFF_DOUBLE:
+			fld->set_field_type = TIFF_SETGET_C32_DOUBLE;
+			fld->get_field_type = TIFF_SETGET_C32_DOUBLE;
+			break;
+		case TIFF_IFD:
+		case TIFF_IFD8:
+			fld->set_field_type = TIFF_SETGET_C32_IFD8;
+			fld->get_field_type = TIFF_SETGET_C32_IFD8;
+			break;
+		case TIFF_LONG8:
+			fld->set_field_type = TIFF_SETGET_C32_UINT64;
+			fld->get_field_type = TIFF_SETGET_C32_UINT64;
+			break;
+		case TIFF_SLONG8:
+			fld->set_field_type = TIFF_SETGET_C32_SINT64;
+			fld->get_field_type = TIFF_SETGET_C32_SINT64;
+			break;
+		default:
+			fld->set_field_type = TIFF_SETGET_UNDEFINED;
+			fld->get_field_type = TIFF_SETGET_UNDEFINED;
+			break;
+	}
+	fld->field_bit = FIELD_CUSTOM;
+	fld->field_oktochange = TRUE;
+	fld->field_passcount = TRUE;
+	fld->field_name = (char *) _TIFFmalloc(32);
+	if (fld->field_name == NULL) {
+	    _TIFFfree(fld);
+	    return NULL;
+	}
+	fld->field_subfields = NULL;
+
+	/* 
+	 * note that this name is a special sign to TIFFClose() and
+	 * _TIFFSetupFields() to free the field
+	 */
+	snprintf(fld->field_name, 32, "Tag %d", (int) tag);
+
+	return fld;    
+}
+
+/****************************************************************************
+ *               O B S O L E T E D    I N T E R F A C E S
+ *
+ * Don't use this stuff in your applications, it may be removed in the future
+ * libtiff versions.
+ ****************************************************************************/
+
+static TIFFSetGetFieldType
+_TIFFSetGetType(TIFFDataType type, short count, unsigned char passcount)
+{
+	if (type == TIFF_ASCII && count == TIFF_VARIABLE && passcount == 0)
+		return TIFF_SETGET_ASCII;
+
+	else if (count == 1 && passcount == 0) {
+		switch (type)
+		{
+			case TIFF_BYTE:
+			case TIFF_UNDEFINED:
+				return TIFF_SETGET_UINT8;
+			case TIFF_ASCII:
+				return TIFF_SETGET_ASCII;
+			case TIFF_SHORT:
+				return TIFF_SETGET_UINT16;
+			case TIFF_LONG:
+				return TIFF_SETGET_UINT32;
+			case TIFF_RATIONAL:
+			case TIFF_SRATIONAL:
+			case TIFF_FLOAT:
+				return TIFF_SETGET_FLOAT;
+			case TIFF_SBYTE:
+				return TIFF_SETGET_SINT8;
+			case TIFF_SSHORT:
+				return TIFF_SETGET_SINT16;
+			case TIFF_SLONG:
+				return TIFF_SETGET_SINT32;
+			case TIFF_DOUBLE:
+				return TIFF_SETGET_DOUBLE;
+			case TIFF_IFD:
+			case TIFF_IFD8:
+				return TIFF_SETGET_IFD8;
+			case TIFF_LONG8:
+				return TIFF_SETGET_UINT64;
+			case TIFF_SLONG8:
+				return TIFF_SETGET_SINT64;
+			default:
+				return TIFF_SETGET_UNDEFINED;
+		}
+	}
+
+	else if (count >= 1 && passcount == 0) {
+		switch (type)
+		{
+			case TIFF_BYTE:
+			case TIFF_UNDEFINED:
+				return TIFF_SETGET_C0_UINT8;
+			case TIFF_ASCII:
+				return TIFF_SETGET_C0_ASCII;
+			case TIFF_SHORT:
+				return TIFF_SETGET_C0_UINT16;
+			case TIFF_LONG:
+				return TIFF_SETGET_C0_UINT32;
+			case TIFF_RATIONAL:
+			case TIFF_SRATIONAL:
+			case TIFF_FLOAT:
+				return TIFF_SETGET_C0_FLOAT;
+			case TIFF_SBYTE:
+				return TIFF_SETGET_C0_SINT8;
+			case TIFF_SSHORT:
+				return TIFF_SETGET_C0_SINT16;
+			case TIFF_SLONG:
+				return TIFF_SETGET_C0_SINT32;
+			case TIFF_DOUBLE:
+				return TIFF_SETGET_C0_DOUBLE;
+			case TIFF_IFD:
+			case TIFF_IFD8:
+				return TIFF_SETGET_C0_IFD8;
+			case TIFF_LONG8:
+				return TIFF_SETGET_C0_UINT64;
+			case TIFF_SLONG8:
+				return TIFF_SETGET_C0_SINT64;
+			default:
+				return TIFF_SETGET_UNDEFINED;
+		}
+	}
+
+	else if (count == TIFF_VARIABLE && passcount == 1) {
+		switch (type)
+		{
+			case TIFF_BYTE:
+			case TIFF_UNDEFINED:
+				return TIFF_SETGET_C16_UINT8;
+			case TIFF_ASCII:
+				return TIFF_SETGET_C16_ASCII;
+			case TIFF_SHORT:
+				return TIFF_SETGET_C16_UINT16;
+			case TIFF_LONG:
+				return TIFF_SETGET_C16_UINT32;
+			case TIFF_RATIONAL:
+			case TIFF_SRATIONAL:
+			case TIFF_FLOAT:
+				return TIFF_SETGET_C16_FLOAT;
+			case TIFF_SBYTE:
+				return TIFF_SETGET_C16_SINT8;
+			case TIFF_SSHORT:
+				return TIFF_SETGET_C16_SINT16;
+			case TIFF_SLONG:
+				return TIFF_SETGET_C16_SINT32;
+			case TIFF_DOUBLE:
+				return TIFF_SETGET_C16_DOUBLE;
+			case TIFF_IFD:
+			case TIFF_IFD8:
+				return TIFF_SETGET_C16_IFD8;
+			case TIFF_LONG8:
+				return TIFF_SETGET_C16_UINT64;
+			case TIFF_SLONG8:
+				return TIFF_SETGET_C16_SINT64;
+			default:
+				return TIFF_SETGET_UNDEFINED;
+		}
+	}
+
+	else if (count == TIFF_VARIABLE2 && passcount == 1) {
+		switch (type)
+		{
+			case TIFF_BYTE:
+			case TIFF_UNDEFINED:
+				return TIFF_SETGET_C32_UINT8;
+			case TIFF_ASCII:
+				return TIFF_SETGET_C32_ASCII;
+			case TIFF_SHORT:
+				return TIFF_SETGET_C32_UINT16;
+			case TIFF_LONG:
+				return TIFF_SETGET_C32_UINT32;
+			case TIFF_RATIONAL:
+			case TIFF_SRATIONAL:
+			case TIFF_FLOAT:
+				return TIFF_SETGET_C32_FLOAT;
+			case TIFF_SBYTE:
+				return TIFF_SETGET_C32_SINT8;
+			case TIFF_SSHORT:
+				return TIFF_SETGET_C32_SINT16;
+			case TIFF_SLONG:
+				return TIFF_SETGET_C32_SINT32;
+			case TIFF_DOUBLE:
+				return TIFF_SETGET_C32_DOUBLE;
+			case TIFF_IFD:
+			case TIFF_IFD8:
+				return TIFF_SETGET_C32_IFD8;
+			case TIFF_LONG8:
+				return TIFF_SETGET_C32_UINT64;
+			case TIFF_SLONG8:
+				return TIFF_SETGET_C32_SINT64;
+			default:
+				return TIFF_SETGET_UNDEFINED;
+		}
+	}
+
+	return TIFF_SETGET_UNDEFINED;
+}
+
+int
+TIFFMergeFieldInfo(TIFF* tif, const TIFFFieldInfo info[], uint32 n)
+{
+	static const char module[] = "TIFFMergeFieldInfo";
+	static const char reason[] = "for fields array";
+	TIFFField *tp;
+	size_t nfields;
+	uint32 i;
+
+	if (tif->tif_nfieldscompat > 0) {
+		tif->tif_fieldscompat = (TIFFFieldArray *)
+			_TIFFCheckRealloc(tif, tif->tif_fieldscompat,
+					  tif->tif_nfieldscompat + 1,
+					  sizeof(TIFFFieldArray), reason);
+	} else {
+		tif->tif_fieldscompat = (TIFFFieldArray *)
+			_TIFFCheckMalloc(tif, 1, sizeof(TIFFFieldArray),
+					 reason);
+	}
+	if (!tif->tif_fieldscompat) {
+		TIFFErrorExt(tif->tif_clientdata, module,
+			     "Failed to allocate fields array");
+		return -1;
+	}
+	nfields = tif->tif_nfieldscompat++;
+
+	tif->tif_fieldscompat[nfields].type = tfiatOther;
+	tif->tif_fieldscompat[nfields].allocated_size = n;
+	tif->tif_fieldscompat[nfields].count = n;
+	tif->tif_fieldscompat[nfields].fields =
+		(TIFFField *)_TIFFCheckMalloc(tif, n, sizeof(TIFFField),
+					      reason);
+	if (!tif->tif_fieldscompat[nfields].fields) {
+		TIFFErrorExt(tif->tif_clientdata, module,
+			     "Failed to allocate fields array");
+		return -1;
+	}
+
+	tp = tif->tif_fieldscompat[nfields].fields;
+	for (i = 0; i < n; i++) {
+		tp->field_tag = info[i].field_tag;
+		tp->field_readcount = info[i].field_readcount;
+		tp->field_writecount = info[i].field_writecount;
+		tp->field_type = info[i].field_type;
+		tp->reserved = 0;
+		tp->set_field_type =
+		     _TIFFSetGetType(info[i].field_type,
+				info[i].field_readcount,
+				info[i].field_passcount);
+		tp->get_field_type =
+		     _TIFFSetGetType(info[i].field_type,
+				info[i].field_readcount,
+				info[i].field_passcount);
+		tp->field_bit = info[i].field_bit;
+		tp->field_oktochange = info[i].field_oktochange;
+		tp->field_passcount = info[i].field_passcount;
+		tp->field_name = info[i].field_name;
+		tp->field_subfields = NULL;
+		tp++;
+	}
+
+	if (!_TIFFMergeFields(tif, tif->tif_fieldscompat[nfields].fields, n)) {
+		TIFFErrorExt(tif->tif_clientdata, module,
+			     "Setting up field info failed");
+		return -1;
+	}
+
+	return 0;
+}
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tif_dirread.c b/Source/LibTIFF4/tif_dirread.c
index 68ade70..a046f93 100644
--- a/Source/LibTIFF4/tif_dirread.c
+++ b/Source/LibTIFF4/tif_dirread.c
@@ -1,5613 +1,5640 @@
-/* $Id: tif_dirread.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library.
- *
- * Directory Read Support Routines.
- */
-
-/* Suggested pending improvements:
- * - add a field 'ignore' to the TIFFDirEntry structure, to flag status,
- *   eliminating current use of the IGNORE value, and therefore eliminating
- *   current irrational behaviour on tags with tag id code 0
- * - add a field 'field_info' to the TIFFDirEntry structure, and set that with
- *   the pointer to the appropriate TIFFField structure early on in
- *   TIFFReadDirectory, so as to eliminate current possibly repetitive lookup.
- */
-
-#include "tiffiop.h"
-
-#define IGNORE 0          /* tag placeholder used below */
-#define FAILED_FII    ((uint32) -1)
-
-#ifdef HAVE_IEEEFP
-# define TIFFCvtIEEEFloatToNative(tif, n, fp)
-# define TIFFCvtIEEEDoubleToNative(tif, n, dp)
-#else
-extern void TIFFCvtIEEEFloatToNative(TIFF*, uint32, float*);
-extern void TIFFCvtIEEEDoubleToNative(TIFF*, uint32, double*);
-#endif
-
-enum TIFFReadDirEntryErr {
-	TIFFReadDirEntryErrOk = 0,
-	TIFFReadDirEntryErrCount = 1,
-	TIFFReadDirEntryErrType = 2,
-	TIFFReadDirEntryErrIo = 3,
-	TIFFReadDirEntryErrRange = 4,
-	TIFFReadDirEntryErrPsdif = 5,
-	TIFFReadDirEntryErrSizesan = 6,
-	TIFFReadDirEntryErrAlloc = 7,
-};
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryByte(TIFF* tif, TIFFDirEntry* direntry, uint8* value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryLong(TIFF* tif, TIFFDirEntry* direntry, uint32* value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8(TIFF* tif, TIFFDirEntry* direntry, uint64* value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryFloat(TIFF* tif, TIFFDirEntry* direntry, float* value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryDouble(TIFF* tif, TIFFDirEntry* direntry, double* value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8(TIFF* tif, TIFFDirEntry* direntry, uint64* value);
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* direntry, uint32* count, uint32 desttypesize, void** value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryByteArray(TIFF* tif, TIFFDirEntry* direntry, uint8** value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntrySbyteArray(TIFF* tif, TIFFDirEntry* direntry, int8** value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryShortArray(TIFF* tif, TIFFDirEntry* direntry, uint16** value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntrySshortArray(TIFF* tif, TIFFDirEntry* direntry, int16** value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryLongArray(TIFF* tif, TIFFDirEntry* direntry, uint32** value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntrySlongArray(TIFF* tif, TIFFDirEntry* direntry, int32** value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8Array(TIFF* tif, TIFFDirEntry* direntry, uint64** value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntrySlong8Array(TIFF* tif, TIFFDirEntry* direntry, int64** value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryFloatArray(TIFF* tif, TIFFDirEntry* direntry, float** value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryDoubleArray(TIFF* tif, TIFFDirEntry* direntry, double** value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8Array(TIFF* tif, TIFFDirEntry* direntry, uint64** value);
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryPersampleShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value);
-#if 0
-static enum TIFFReadDirEntryErr TIFFReadDirEntryPersampleDouble(TIFF* tif, TIFFDirEntry* direntry, double* value);
-#endif
-
-static void TIFFReadDirEntryCheckedByte(TIFF* tif, TIFFDirEntry* direntry, uint8* value);
-static void TIFFReadDirEntryCheckedSbyte(TIFF* tif, TIFFDirEntry* direntry, int8* value);
-static void TIFFReadDirEntryCheckedShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value);
-static void TIFFReadDirEntryCheckedSshort(TIFF* tif, TIFFDirEntry* direntry, int16* value);
-static void TIFFReadDirEntryCheckedLong(TIFF* tif, TIFFDirEntry* direntry, uint32* value);
-static void TIFFReadDirEntryCheckedSlong(TIFF* tif, TIFFDirEntry* direntry, int32* value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedLong8(TIFF* tif, TIFFDirEntry* direntry, uint64* value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSlong8(TIFF* tif, TIFFDirEntry* direntry, int64* value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedRational(TIFF* tif, TIFFDirEntry* direntry, double* value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSrational(TIFF* tif, TIFFDirEntry* direntry, double* value);
-static void TIFFReadDirEntryCheckedFloat(TIFF* tif, TIFFDirEntry* direntry, float* value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedDouble(TIFF* tif, TIFFDirEntry* direntry, double* value);
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSbyte(int8 value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteShort(uint16 value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSshort(int16 value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteLong(uint32 value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSlong(int32 value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteLong8(uint64 value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSlong8(int64 value);
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteByte(uint8 value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteShort(uint16 value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSshort(int16 value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteLong(uint32 value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSlong(int32 value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteLong8(uint64 value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSlong8(int64 value);
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSbyte(int8 value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSshort(int16 value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortLong(uint32 value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSlong(int32 value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortLong8(uint64 value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSlong8(int64 value);
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortShort(uint16 value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortLong(uint32 value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortSlong(int32 value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortLong8(uint64 value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortSlong8(int64 value);
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSbyte(int8 value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSshort(int16 value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSlong(int32 value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongLong8(uint64 value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSlong8(int64 value);
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlongLong(uint32 value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlongLong8(uint64 value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlongSlong8(int64 value);
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Sbyte(int8 value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Sshort(int16 value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Slong(int32 value);
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Slong8(int64 value);
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlong8Long8(uint64 value);
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryData(TIFF* tif, uint64 offset, tmsize_t size, void* dest);
-static void TIFFReadDirEntryOutputErr(TIFF* tif, enum TIFFReadDirEntryErr err, const char* module, const char* tagname, int recover);
-
-static void TIFFReadDirectoryCheckOrder(TIFF* tif, TIFFDirEntry* dir, uint16 dircount);
-static TIFFDirEntry* TIFFReadDirectoryFindEntry(TIFF* tif, TIFFDirEntry* dir, uint16 dircount, uint16 tagid);
-static void TIFFReadDirectoryFindFieldInfo(TIFF* tif, uint16 tagid, uint32* fii);
-
-static int EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount);
-static void MissingRequired(TIFF*, const char*);
-static int TIFFCheckDirOffset(TIFF* tif, uint64 diroff);
-static int CheckDirCount(TIFF*, TIFFDirEntry*, uint32);
-static uint16 TIFFFetchDirectory(TIFF* tif, uint64 diroff, TIFFDirEntry** pdir, uint64* nextdiroff);
-static int TIFFFetchNormalTag(TIFF*, TIFFDirEntry*, int recover);
-static int TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, uint32 nstrips, uint64** lpp);
-static int TIFFFetchSubjectDistance(TIFF*, TIFFDirEntry*);
-static void ChopUpSingleUncompressedStrip(TIFF*);
-static uint64 TIFFReadUInt64(const uint8 *value);
-
-typedef union _UInt64Aligned_t
-{
-        double d;
-	uint64 l;
-	uint32 i[2];
-	uint16 s[4];
-	uint8  c[8];
-} UInt64Aligned_t;
-
-/*
-  Unaligned safe copy of a uint64 value from an octet array.
-*/
-static uint64 TIFFReadUInt64(const uint8 *value)
-{
-	UInt64Aligned_t result;
-
-	result.c[0]=value[0];
-	result.c[1]=value[1];
-	result.c[2]=value[2];
-	result.c[3]=value[3];
-	result.c[4]=value[4];
-	result.c[5]=value[5];
-	result.c[6]=value[6];
-	result.c[7]=value[7];
-
-	return result.l;
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryByte(TIFF* tif, TIFFDirEntry* direntry, uint8* value)
-{
-	enum TIFFReadDirEntryErr err;
-	if (direntry->tdir_count!=1)
-		return(TIFFReadDirEntryErrCount);
-	switch (direntry->tdir_type)
-	{
-		case TIFF_BYTE:
-			TIFFReadDirEntryCheckedByte(tif,direntry,value);
-			return(TIFFReadDirEntryErrOk);
-		case TIFF_SBYTE:
-			{
-				int8 m;
-				TIFFReadDirEntryCheckedSbyte(tif,direntry,&m);
-				err=TIFFReadDirEntryCheckRangeByteSbyte(m);
-				if (err!=TIFFReadDirEntryErrOk)
-					return(err);
-				*value=(uint8)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_SHORT:
-			{
-				uint16 m;
-				TIFFReadDirEntryCheckedShort(tif,direntry,&m);
-				err=TIFFReadDirEntryCheckRangeByteShort(m);
-				if (err!=TIFFReadDirEntryErrOk)
-					return(err);
-				*value=(uint8)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_SSHORT:
-			{
-				int16 m;
-				TIFFReadDirEntryCheckedSshort(tif,direntry,&m);
-				err=TIFFReadDirEntryCheckRangeByteSshort(m);
-				if (err!=TIFFReadDirEntryErrOk)
-					return(err);
-				*value=(uint8)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_LONG:
-			{
-				uint32 m;
-				TIFFReadDirEntryCheckedLong(tif,direntry,&m);
-				err=TIFFReadDirEntryCheckRangeByteLong(m);
-				if (err!=TIFFReadDirEntryErrOk)
-					return(err);
-				*value=(uint8)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_SLONG:
-			{
-				int32 m;
-				TIFFReadDirEntryCheckedSlong(tif,direntry,&m);
-				err=TIFFReadDirEntryCheckRangeByteSlong(m);
-				if (err!=TIFFReadDirEntryErrOk)
-					return(err);
-				*value=(uint8)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_LONG8:
-			{
-				uint64 m;
-				err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m);
-				if (err!=TIFFReadDirEntryErrOk)
-					return(err);
-				err=TIFFReadDirEntryCheckRangeByteLong8(m);
-				if (err!=TIFFReadDirEntryErrOk)
-					return(err);
-				*value=(uint8)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_SLONG8:
-			{
-				int64 m;
-				err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m);
-				if (err!=TIFFReadDirEntryErrOk)
-					return(err);
-				err=TIFFReadDirEntryCheckRangeByteSlong8(m);
-				if (err!=TIFFReadDirEntryErrOk)
-					return(err);
-				*value=(uint8)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		default:
-			return(TIFFReadDirEntryErrType);
-	}
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value)
-{
-	enum TIFFReadDirEntryErr err;
-	if (direntry->tdir_count!=1)
-		return(TIFFReadDirEntryErrCount);
-	switch (direntry->tdir_type)
-	{
-		case TIFF_BYTE:
-			{
-				uint8 m;
-				TIFFReadDirEntryCheckedByte(tif,direntry,&m);
-				*value=(uint16)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_SBYTE:
-			{
-				int8 m;
-				TIFFReadDirEntryCheckedSbyte(tif,direntry,&m);
-				err=TIFFReadDirEntryCheckRangeShortSbyte(m);
-				if (err!=TIFFReadDirEntryErrOk)
-					return(err);
-				*value=(uint16)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_SHORT:
-			TIFFReadDirEntryCheckedShort(tif,direntry,value);
-			return(TIFFReadDirEntryErrOk);
-		case TIFF_SSHORT:
-			{
-				int16 m;
-				TIFFReadDirEntryCheckedSshort(tif,direntry,&m);
-				err=TIFFReadDirEntryCheckRangeShortSshort(m);
-				if (err!=TIFFReadDirEntryErrOk)
-					return(err);
-				*value=(uint16)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_LONG:
-			{
-				uint32 m;
-				TIFFReadDirEntryCheckedLong(tif,direntry,&m);
-				err=TIFFReadDirEntryCheckRangeShortLong(m);
-				if (err!=TIFFReadDirEntryErrOk)
-					return(err);
-				*value=(uint16)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_SLONG:
-			{
-				int32 m;
-				TIFFReadDirEntryCheckedSlong(tif,direntry,&m);
-				err=TIFFReadDirEntryCheckRangeShortSlong(m);
-				if (err!=TIFFReadDirEntryErrOk)
-					return(err);
-				*value=(uint16)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_LONG8:
-			{
-				uint64 m;
-				err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m);
-				if (err!=TIFFReadDirEntryErrOk)
-					return(err);
-				err=TIFFReadDirEntryCheckRangeShortLong8(m);
-				if (err!=TIFFReadDirEntryErrOk)
-					return(err);
-				*value=(uint16)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_SLONG8:
-			{
-				int64 m;
-				err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m);
-				if (err!=TIFFReadDirEntryErrOk)
-					return(err);
-				err=TIFFReadDirEntryCheckRangeShortSlong8(m);
-				if (err!=TIFFReadDirEntryErrOk)
-					return(err);
-				*value=(uint16)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		default:
-			return(TIFFReadDirEntryErrType);
-	}
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryLong(TIFF* tif, TIFFDirEntry* direntry, uint32* value)
-{
-	enum TIFFReadDirEntryErr err;
-	if (direntry->tdir_count!=1)
-		return(TIFFReadDirEntryErrCount);
-	switch (direntry->tdir_type)
-	{
-		case TIFF_BYTE:
-			{
-				uint8 m;
-				TIFFReadDirEntryCheckedByte(tif,direntry,&m);
-				*value=(uint32)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_SBYTE:
-			{
-				int8 m;
-				TIFFReadDirEntryCheckedSbyte(tif,direntry,&m);
-				err=TIFFReadDirEntryCheckRangeLongSbyte(m);
-				if (err!=TIFFReadDirEntryErrOk)
-					return(err);
-				*value=(uint32)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_SHORT:
-			{
-				uint16 m;
-				TIFFReadDirEntryCheckedShort(tif,direntry,&m);
-				*value=(uint32)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_SSHORT:
-			{
-				int16 m;
-				TIFFReadDirEntryCheckedSshort(tif,direntry,&m);
-				err=TIFFReadDirEntryCheckRangeLongSshort(m);
-				if (err!=TIFFReadDirEntryErrOk)
-					return(err);
-				*value=(uint32)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_LONG:
-			TIFFReadDirEntryCheckedLong(tif,direntry,value);
-			return(TIFFReadDirEntryErrOk);
-		case TIFF_SLONG:
-			{
-				int32 m;
-				TIFFReadDirEntryCheckedSlong(tif,direntry,&m);
-				err=TIFFReadDirEntryCheckRangeLongSlong(m);
-				if (err!=TIFFReadDirEntryErrOk)
-					return(err);
-				*value=(uint32)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_LONG8:
-			{
-				uint64 m;
-				err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m);
-				if (err!=TIFFReadDirEntryErrOk)
-					return(err);
-				err=TIFFReadDirEntryCheckRangeLongLong8(m);
-				if (err!=TIFFReadDirEntryErrOk)
-					return(err);
-				*value=(uint32)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_SLONG8:
-			{
-				int64 m;
-				err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m);
-				if (err!=TIFFReadDirEntryErrOk)
-					return(err);
-				err=TIFFReadDirEntryCheckRangeLongSlong8(m);
-				if (err!=TIFFReadDirEntryErrOk)
-					return(err);
-				*value=(uint32)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		default:
-			return(TIFFReadDirEntryErrType);
-	}
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8(TIFF* tif, TIFFDirEntry* direntry, uint64* value)
-{
-	enum TIFFReadDirEntryErr err;
-	if (direntry->tdir_count!=1)
-		return(TIFFReadDirEntryErrCount);
-	switch (direntry->tdir_type)
-	{
-		case TIFF_BYTE:
-			{
-				uint8 m;
-				TIFFReadDirEntryCheckedByte(tif,direntry,&m);
-				*value=(uint64)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_SBYTE:
-			{
-				int8 m;
-				TIFFReadDirEntryCheckedSbyte(tif,direntry,&m);
-				err=TIFFReadDirEntryCheckRangeLong8Sbyte(m);
-				if (err!=TIFFReadDirEntryErrOk)
-					return(err);
-				*value=(uint64)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_SHORT:
-			{
-				uint16 m;
-				TIFFReadDirEntryCheckedShort(tif,direntry,&m);
-				*value=(uint64)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_SSHORT:
-			{
-				int16 m;
-				TIFFReadDirEntryCheckedSshort(tif,direntry,&m);
-				err=TIFFReadDirEntryCheckRangeLong8Sshort(m);
-				if (err!=TIFFReadDirEntryErrOk)
-					return(err);
-				*value=(uint64)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_LONG:
-			{
-				uint32 m;
-				TIFFReadDirEntryCheckedLong(tif,direntry,&m);
-				*value=(uint64)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_SLONG:
-			{
-				int32 m;
-				TIFFReadDirEntryCheckedSlong(tif,direntry,&m);
-				err=TIFFReadDirEntryCheckRangeLong8Slong(m);
-				if (err!=TIFFReadDirEntryErrOk)
-					return(err);
-				*value=(uint64)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_LONG8:
-			err=TIFFReadDirEntryCheckedLong8(tif,direntry,value);
-			return(err);
-		case TIFF_SLONG8:
-			{
-				int64 m;
-				err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m);
-				if (err!=TIFFReadDirEntryErrOk)
-					return(err);
-				err=TIFFReadDirEntryCheckRangeLong8Slong8(m);
-				if (err!=TIFFReadDirEntryErrOk)
-					return(err);
-				*value=(uint64)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		default:
-			return(TIFFReadDirEntryErrType);
-	}
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryFloat(TIFF* tif, TIFFDirEntry* direntry, float* value)
-{
-	enum TIFFReadDirEntryErr err;
-	if (direntry->tdir_count!=1)
-		return(TIFFReadDirEntryErrCount);
-	switch (direntry->tdir_type)
-	{
-		case TIFF_BYTE:
-			{
-				uint8 m;
-				TIFFReadDirEntryCheckedByte(tif,direntry,&m);
-				*value=(float)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_SBYTE:
-			{
-				int8 m;
-				TIFFReadDirEntryCheckedSbyte(tif,direntry,&m);
-				*value=(float)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_SHORT:
-			{
-				uint16 m;
-				TIFFReadDirEntryCheckedShort(tif,direntry,&m);
-				*value=(float)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_SSHORT:
-			{
-				int16 m;
-				TIFFReadDirEntryCheckedSshort(tif,direntry,&m);
-				*value=(float)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_LONG:
-			{
-				uint32 m;
-				TIFFReadDirEntryCheckedLong(tif,direntry,&m);
-				*value=(float)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_SLONG:
-			{
-				int32 m;
-				TIFFReadDirEntryCheckedSlong(tif,direntry,&m);
-				*value=(float)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_LONG8:
-			{
-				uint64 m;
-				err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m);
-				if (err!=TIFFReadDirEntryErrOk)
-					return(err);
-#if defined(__WIN32__) && (_MSC_VER < 1500)
-				/*
-				 * XXX: MSVC 6.0 does not support conversion
-				 * of 64-bit integers into floating point
-				 * values.
-				 */
-				*value = _TIFFUInt64ToFloat(m);
-#else
-				*value=(float)m;
-#endif
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_SLONG8:
-			{
-				int64 m;
-				err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m);
-				if (err!=TIFFReadDirEntryErrOk)
-					return(err);
-				*value=(float)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_RATIONAL:
-			{
-				double m;
-				err=TIFFReadDirEntryCheckedRational(tif,direntry,&m);
-				if (err!=TIFFReadDirEntryErrOk)
-					return(err);
-				*value=(float)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_SRATIONAL:
-			{
-				double m;
-				err=TIFFReadDirEntryCheckedSrational(tif,direntry,&m);
-				if (err!=TIFFReadDirEntryErrOk)
-					return(err);
-				*value=(float)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_FLOAT:
-			TIFFReadDirEntryCheckedFloat(tif,direntry,value);
-			return(TIFFReadDirEntryErrOk);
-		case TIFF_DOUBLE:
-			{
-				double m;
-				err=TIFFReadDirEntryCheckedDouble(tif,direntry,&m);
-				if (err!=TIFFReadDirEntryErrOk)
-					return(err);
-				*value=(float)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		default:
-			return(TIFFReadDirEntryErrType);
-	}
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryDouble(TIFF* tif, TIFFDirEntry* direntry, double* value)
-{
-	enum TIFFReadDirEntryErr err;
-	if (direntry->tdir_count!=1)
-		return(TIFFReadDirEntryErrCount);
-	switch (direntry->tdir_type)
-	{
-		case TIFF_BYTE:
-			{
-				uint8 m;
-				TIFFReadDirEntryCheckedByte(tif,direntry,&m);
-				*value=(double)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_SBYTE:
-			{
-				int8 m;
-				TIFFReadDirEntryCheckedSbyte(tif,direntry,&m);
-				*value=(double)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_SHORT:
-			{
-				uint16 m;
-				TIFFReadDirEntryCheckedShort(tif,direntry,&m);
-				*value=(double)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_SSHORT:
-			{
-				int16 m;
-				TIFFReadDirEntryCheckedSshort(tif,direntry,&m);
-				*value=(double)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_LONG:
-			{
-				uint32 m;
-				TIFFReadDirEntryCheckedLong(tif,direntry,&m);
-				*value=(double)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_SLONG:
-			{
-				int32 m;
-				TIFFReadDirEntryCheckedSlong(tif,direntry,&m);
-				*value=(double)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_LONG8:
-			{
-				uint64 m;
-				err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m);
-				if (err!=TIFFReadDirEntryErrOk)
-					return(err);
-#if defined(__WIN32__) && (_MSC_VER < 1500)
-				/*
-				 * XXX: MSVC 6.0 does not support conversion
-				 * of 64-bit integers into floating point
-				 * values.
-				 */
-				*value = _TIFFUInt64ToDouble(m);
-#else
-				*value = (double)m;
-#endif
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_SLONG8:
-			{
-				int64 m;
-				err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m);
-				if (err!=TIFFReadDirEntryErrOk)
-					return(err);
-				*value=(double)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_RATIONAL:
-			err=TIFFReadDirEntryCheckedRational(tif,direntry,value);
-			return(err);
-		case TIFF_SRATIONAL:
-			err=TIFFReadDirEntryCheckedSrational(tif,direntry,value);
-			return(err);
-		case TIFF_FLOAT:
-			{
-				float m;
-				TIFFReadDirEntryCheckedFloat(tif,direntry,&m);
-				*value=(double)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_DOUBLE:
-			err=TIFFReadDirEntryCheckedDouble(tif,direntry,value);
-			return(err);
-		default:
-			return(TIFFReadDirEntryErrType);
-	}
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8(TIFF* tif, TIFFDirEntry* direntry, uint64* value)
-{
-	enum TIFFReadDirEntryErr err;
-	if (direntry->tdir_count!=1)
-		return(TIFFReadDirEntryErrCount);
-	switch (direntry->tdir_type)
-	{
-		case TIFF_LONG:
-		case TIFF_IFD:
-			{
-				uint32 m;
-				TIFFReadDirEntryCheckedLong(tif,direntry,&m);
-				*value=(uint64)m;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_LONG8:
-		case TIFF_IFD8:
-			err=TIFFReadDirEntryCheckedLong8(tif,direntry,value);
-			return(err);
-		default:
-			return(TIFFReadDirEntryErrType);
-	}
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* direntry, uint32* count, uint32 desttypesize, void** value)
-{
-	int typesize;
-	uint32 datasize;
-	void* data;
-	typesize=TIFFDataWidth(direntry->tdir_type);
-	if ((direntry->tdir_count==0)||(typesize==0))
-	{
-		*value=0;
-		return(TIFFReadDirEntryErrOk);
-	}
-        (void) desttypesize;
-
-        /* 
-         * As a sanity check, make sure we have no more than a 2GB tag array 
-         * in either the current data type or the dest data type.  This also
-         * avoids problems with overflow of tmsize_t on 32bit systems.
-         */
-	if ((uint64)(2147483647/typesize)<direntry->tdir_count)
-		return(TIFFReadDirEntryErrSizesan);
-	if ((uint64)(2147483647/desttypesize)<direntry->tdir_count)
-		return(TIFFReadDirEntryErrSizesan);
-
-	*count=(uint32)direntry->tdir_count;
-	datasize=(*count)*typesize;
-	assert((tmsize_t)datasize>0);
-	data=_TIFFCheckMalloc(tif, *count, typesize, "ReadDirEntryArray");
-	if (data==0)
-		return(TIFFReadDirEntryErrAlloc);
-	if (!(tif->tif_flags&TIFF_BIGTIFF))
-	{
-		if (datasize<=4)
-			_TIFFmemcpy(data,&direntry->tdir_offset,datasize);
-		else
-		{
-			enum TIFFReadDirEntryErr err;
-			uint32 offset = direntry->tdir_offset.toff_long;
-			if (tif->tif_flags&TIFF_SWAB)
-				TIFFSwabLong(&offset);
-			err=TIFFReadDirEntryData(tif,(uint64)offset,(tmsize_t)datasize,data);
-			if (err!=TIFFReadDirEntryErrOk)
-			{
-				_TIFFfree(data);
-				return(err);
-			}
-		}
-	}
-	else
-	{
-		if (datasize<=8)
-			_TIFFmemcpy(data,&direntry->tdir_offset,datasize);
-		else
-		{
-			enum TIFFReadDirEntryErr err;
-			uint64 offset = direntry->tdir_offset.toff_long8;
-			if (tif->tif_flags&TIFF_SWAB)
-				TIFFSwabLong8(&offset);
-			err=TIFFReadDirEntryData(tif,offset,(tmsize_t)datasize,data);
-			if (err!=TIFFReadDirEntryErrOk)
-			{
-				_TIFFfree(data);
-				return(err);
-			}
-		}
-	}
-	*value=data;
-	return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryByteArray(TIFF* tif, TIFFDirEntry* direntry, uint8** value)
-{
-	enum TIFFReadDirEntryErr err;
-	uint32 count;
-	void* origdata;
-	uint8* data;
-	switch (direntry->tdir_type)
-	{
-		case TIFF_ASCII:
-		case TIFF_UNDEFINED:
-		case TIFF_BYTE:
-		case TIFF_SBYTE:
-		case TIFF_SHORT:
-		case TIFF_SSHORT:
-		case TIFF_LONG:
-		case TIFF_SLONG:
-		case TIFF_LONG8:
-		case TIFF_SLONG8:
-			break;
-		default:
-			return(TIFFReadDirEntryErrType);
-	}
-	err=TIFFReadDirEntryArray(tif,direntry,&count,1,&origdata);
-	if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
-	{
-		*value=0;
-		return(err);
-	}
-	switch (direntry->tdir_type)
-	{
-		case TIFF_ASCII:
-		case TIFF_UNDEFINED:
-		case TIFF_BYTE:
-			*value=(uint8*)origdata;
-			return(TIFFReadDirEntryErrOk);
-		case TIFF_SBYTE:
-			{
-				int8* m;
-				uint32 n;
-				m=(int8*)origdata;
-				for (n=0; n<count; n++)
-				{
-					err=TIFFReadDirEntryCheckRangeByteSbyte(*m);
-					if (err!=TIFFReadDirEntryErrOk)
-					{
-						_TIFFfree(origdata);
-						return(err);
-					}
-					m++;
-				}
-				*value=(uint8*)origdata;
-				return(TIFFReadDirEntryErrOk);
-			}
-	}
-	data=(uint8*)_TIFFmalloc(count);
-	if (data==0)
-	{
-		_TIFFfree(origdata);
-		return(TIFFReadDirEntryErrAlloc);
-	}
-	switch (direntry->tdir_type)
-	{
-		case TIFF_SHORT:
-			{
-				uint16* ma;
-				uint8* mb;
-				uint32 n;
-				ma=(uint16*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabShort(ma);
-					err=TIFFReadDirEntryCheckRangeByteShort(*ma);
-					if (err!=TIFFReadDirEntryErrOk)
-						break;
-					*mb++=(uint8)(*ma++);
-				}
-			}
-			break;
-		case TIFF_SSHORT:
-			{
-				int16* ma;
-				uint8* mb;
-				uint32 n;
-				ma=(int16*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabShort((uint16*)ma);
-					err=TIFFReadDirEntryCheckRangeByteSshort(*ma);
-					if (err!=TIFFReadDirEntryErrOk)
-						break;
-					*mb++=(uint8)(*ma++);
-				}
-			}
-			break;
-		case TIFF_LONG:
-			{
-				uint32* ma;
-				uint8* mb;
-				uint32 n;
-				ma=(uint32*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong(ma);
-					err=TIFFReadDirEntryCheckRangeByteLong(*ma);
-					if (err!=TIFFReadDirEntryErrOk)
-						break;
-					*mb++=(uint8)(*ma++);
-				}
-			}
-			break;
-		case TIFF_SLONG:
-			{
-				int32* ma;
-				uint8* mb;
-				uint32 n;
-				ma=(int32*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong((uint32*)ma);
-					err=TIFFReadDirEntryCheckRangeByteSlong(*ma);
-					if (err!=TIFFReadDirEntryErrOk)
-						break;
-					*mb++=(uint8)(*ma++);
-				}
-			}
-			break;
-		case TIFF_LONG8:
-			{
-				uint64* ma;
-				uint8* mb;
-				uint32 n;
-				ma=(uint64*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong8(ma);
-					err=TIFFReadDirEntryCheckRangeByteLong8(*ma);
-					if (err!=TIFFReadDirEntryErrOk)
-						break;
-					*mb++=(uint8)(*ma++);
-				}
-			}
-			break;
-		case TIFF_SLONG8:
-			{
-				int64* ma;
-				uint8* mb;
-				uint32 n;
-				ma=(int64*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong8((uint64*)ma);
-					err=TIFFReadDirEntryCheckRangeByteSlong8(*ma);
-					if (err!=TIFFReadDirEntryErrOk)
-						break;
-					*mb++=(uint8)(*ma++);
-				}
-			}
-			break;
-	}
-	_TIFFfree(origdata);
-	if (err!=TIFFReadDirEntryErrOk)
-	{
-		_TIFFfree(data);
-		return(err);
-	}
-	*value=data;
-	return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntrySbyteArray(TIFF* tif, TIFFDirEntry* direntry, int8** value)
-{
-	enum TIFFReadDirEntryErr err;
-	uint32 count;
-	void* origdata;
-	int8* data;
-	switch (direntry->tdir_type)
-	{
-		case TIFF_UNDEFINED:
-		case TIFF_BYTE:
-		case TIFF_SBYTE:
-		case TIFF_SHORT:
-		case TIFF_SSHORT:
-		case TIFF_LONG:
-		case TIFF_SLONG:
-		case TIFF_LONG8:
-		case TIFF_SLONG8:
-			break;
-		default:
-			return(TIFFReadDirEntryErrType);
-	}
-	err=TIFFReadDirEntryArray(tif,direntry,&count,1,&origdata);
-	if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
-	{
-		*value=0;
-		return(err);
-	}
-	switch (direntry->tdir_type)
-	{
-		case TIFF_UNDEFINED:
-		case TIFF_BYTE:
-			{
-				uint8* m;
-				uint32 n;
-				m=(uint8*)origdata;
-				for (n=0; n<count; n++)
-				{
-					err=TIFFReadDirEntryCheckRangeSbyteByte(*m);
-					if (err!=TIFFReadDirEntryErrOk)
-					{
-						_TIFFfree(origdata);
-						return(err);
-					}
-					m++;
-				}
-				*value=(int8*)origdata;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_SBYTE:
-			*value=(int8*)origdata;
-			return(TIFFReadDirEntryErrOk);
-	}
-	data=(int8*)_TIFFmalloc(count);
-	if (data==0)
-	{
-		_TIFFfree(origdata);
-		return(TIFFReadDirEntryErrAlloc);
-	}
-	switch (direntry->tdir_type)
-	{
-		case TIFF_SHORT:
-			{
-				uint16* ma;
-				int8* mb;
-				uint32 n;
-				ma=(uint16*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabShort(ma);
-					err=TIFFReadDirEntryCheckRangeSbyteShort(*ma);
-					if (err!=TIFFReadDirEntryErrOk)
-						break;
-					*mb++=(int8)(*ma++);
-				}
-			}
-			break;
-		case TIFF_SSHORT:
-			{
-				int16* ma;
-				int8* mb;
-				uint32 n;
-				ma=(int16*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabShort((uint16*)ma);
-					err=TIFFReadDirEntryCheckRangeSbyteSshort(*ma);
-					if (err!=TIFFReadDirEntryErrOk)
-						break;
-					*mb++=(int8)(*ma++);
-				}
-			}
-			break;
-		case TIFF_LONG:
-			{
-				uint32* ma;
-				int8* mb;
-				uint32 n;
-				ma=(uint32*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong(ma);
-					err=TIFFReadDirEntryCheckRangeSbyteLong(*ma);
-					if (err!=TIFFReadDirEntryErrOk)
-						break;
-					*mb++=(int8)(*ma++);
-				}
-			}
-			break;
-		case TIFF_SLONG:
-			{
-				int32* ma;
-				int8* mb;
-				uint32 n;
-				ma=(int32*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong((uint32*)ma);
-					err=TIFFReadDirEntryCheckRangeSbyteSlong(*ma);
-					if (err!=TIFFReadDirEntryErrOk)
-						break;
-					*mb++=(int8)(*ma++);
-				}
-			}
-			break;
-		case TIFF_LONG8:
-			{
-				uint64* ma;
-				int8* mb;
-				uint32 n;
-				ma=(uint64*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong8(ma);
-					err=TIFFReadDirEntryCheckRangeSbyteLong8(*ma);
-					if (err!=TIFFReadDirEntryErrOk)
-						break;
-					*mb++=(int8)(*ma++);
-				}
-			}
-			break;
-		case TIFF_SLONG8:
-			{
-				int64* ma;
-				int8* mb;
-				uint32 n;
-				ma=(int64*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong8((uint64*)ma);
-					err=TIFFReadDirEntryCheckRangeSbyteSlong8(*ma);
-					if (err!=TIFFReadDirEntryErrOk)
-						break;
-					*mb++=(int8)(*ma++);
-				}
-			}
-			break;
-	}
-	_TIFFfree(origdata);
-	if (err!=TIFFReadDirEntryErrOk)
-	{
-		_TIFFfree(data);
-		return(err);
-	}
-	*value=data;
-	return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryShortArray(TIFF* tif, TIFFDirEntry* direntry, uint16** value)
-{
-	enum TIFFReadDirEntryErr err;
-	uint32 count;
-	void* origdata;
-	uint16* data;
-	switch (direntry->tdir_type)
-	{
-		case TIFF_BYTE:
-		case TIFF_SBYTE:
-		case TIFF_SHORT:
-		case TIFF_SSHORT:
-		case TIFF_LONG:
-		case TIFF_SLONG:
-		case TIFF_LONG8:
-		case TIFF_SLONG8:
-			break;
-		default:
-			return(TIFFReadDirEntryErrType);
-	}
-	err=TIFFReadDirEntryArray(tif,direntry,&count,2,&origdata);
-	if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
-	{
-		*value=0;
-		return(err);
-	}
-	switch (direntry->tdir_type)
-	{
-		case TIFF_SHORT:
-			*value=(uint16*)origdata;
-			if (tif->tif_flags&TIFF_SWAB)
-				TIFFSwabArrayOfShort(*value,count);  
-			return(TIFFReadDirEntryErrOk);
-		case TIFF_SSHORT:
-			{
-				int16* m;
-				uint32 n;
-				m=(int16*)origdata;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabShort((uint16*)m);
-					err=TIFFReadDirEntryCheckRangeShortSshort(*m);
-					if (err!=TIFFReadDirEntryErrOk)
-					{
-						_TIFFfree(origdata);
-						return(err);
-					}
-					m++;
-				}
-				*value=(uint16*)origdata;
-				return(TIFFReadDirEntryErrOk);
-			}
-	}
-	data=(uint16*)_TIFFmalloc(count*2);
-	if (data==0)
-	{
-		_TIFFfree(origdata);
-		return(TIFFReadDirEntryErrAlloc);
-	}
-	switch (direntry->tdir_type)
-	{
-		case TIFF_BYTE:
-			{
-				uint8* ma;
-				uint16* mb;
-				uint32 n;
-				ma=(uint8*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-					*mb++=(uint16)(*ma++);
-			}
-			break;
-		case TIFF_SBYTE:
-			{
-				int8* ma;
-				uint16* mb;
-				uint32 n;
-				ma=(int8*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					err=TIFFReadDirEntryCheckRangeShortSbyte(*ma);
-					if (err!=TIFFReadDirEntryErrOk)
-						break;
-					*mb++=(uint16)(*ma++);
-				}
-			}
-			break;
-		case TIFF_LONG:
-			{
-				uint32* ma;
-				uint16* mb;
-				uint32 n;
-				ma=(uint32*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong(ma);
-					err=TIFFReadDirEntryCheckRangeShortLong(*ma);
-					if (err!=TIFFReadDirEntryErrOk)
-						break;
-					*mb++=(uint16)(*ma++);
-				}
-			}
-			break;
-		case TIFF_SLONG:
-			{
-				int32* ma;
-				uint16* mb;
-				uint32 n;
-				ma=(int32*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong((uint32*)ma);
-					err=TIFFReadDirEntryCheckRangeShortSlong(*ma);
-					if (err!=TIFFReadDirEntryErrOk)
-						break;
-					*mb++=(uint16)(*ma++);
-				}
-			}
-			break;
-		case TIFF_LONG8:
-			{
-				uint64* ma;
-				uint16* mb;
-				uint32 n;
-				ma=(uint64*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong8(ma);
-					err=TIFFReadDirEntryCheckRangeShortLong8(*ma);
-					if (err!=TIFFReadDirEntryErrOk)
-						break;
-					*mb++=(uint16)(*ma++);
-				}
-			}
-			break;
-		case TIFF_SLONG8:
-			{
-				int64* ma;
-				uint16* mb;
-				uint32 n;
-				ma=(int64*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong8((uint64*)ma);
-					err=TIFFReadDirEntryCheckRangeShortSlong8(*ma);
-					if (err!=TIFFReadDirEntryErrOk)
-						break;
-					*mb++=(uint16)(*ma++);
-				}
-			}
-			break;
-	}
-	_TIFFfree(origdata);
-	if (err!=TIFFReadDirEntryErrOk)
-	{
-		_TIFFfree(data);
-		return(err);
-	}
-	*value=data;
-	return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntrySshortArray(TIFF* tif, TIFFDirEntry* direntry, int16** value)
-{
-	enum TIFFReadDirEntryErr err;
-	uint32 count;
-	void* origdata;
-	int16* data;
-	switch (direntry->tdir_type)
-	{
-		case TIFF_BYTE:
-		case TIFF_SBYTE:
-		case TIFF_SHORT:
-		case TIFF_SSHORT:
-		case TIFF_LONG:
-		case TIFF_SLONG:
-		case TIFF_LONG8:
-		case TIFF_SLONG8:
-			break;
-		default:
-			return(TIFFReadDirEntryErrType);
-	}
-	err=TIFFReadDirEntryArray(tif,direntry,&count,2,&origdata);
-	if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
-	{
-		*value=0;
-		return(err);
-	}
-	switch (direntry->tdir_type)
-	{
-		case TIFF_SHORT:
-			{
-				uint16* m;
-				uint32 n;
-				m=(uint16*)origdata;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabShort(m);
-					err=TIFFReadDirEntryCheckRangeSshortShort(*m);
-					if (err!=TIFFReadDirEntryErrOk)
-					{
-						_TIFFfree(origdata);
-						return(err);
-					}
-					m++;
-				}
-				*value=(int16*)origdata;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_SSHORT:
-			*value=(int16*)origdata;
-			if (tif->tif_flags&TIFF_SWAB)
-				TIFFSwabArrayOfShort((uint16*)(*value),count);
-			return(TIFFReadDirEntryErrOk);
-	}
-	data=(int16*)_TIFFmalloc(count*2);
-	if (data==0)
-	{
-		_TIFFfree(origdata);
-		return(TIFFReadDirEntryErrAlloc);
-	}
-	switch (direntry->tdir_type)
-	{
-		case TIFF_BYTE:
-			{
-				uint8* ma;
-				int16* mb;
-				uint32 n;
-				ma=(uint8*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-					*mb++=(int16)(*ma++);
-			}
-			break;
-		case TIFF_SBYTE:
-			{
-				int8* ma;
-				int16* mb;
-				uint32 n;
-				ma=(int8*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-					*mb++=(int16)(*ma++);
-			}
-			break;
-		case TIFF_LONG:
-			{
-				uint32* ma;
-				int16* mb;
-				uint32 n;
-				ma=(uint32*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong(ma);
-					err=TIFFReadDirEntryCheckRangeSshortLong(*ma);
-					if (err!=TIFFReadDirEntryErrOk)
-						break;
-					*mb++=(int16)(*ma++);
-				}
-			}
-			break;
-		case TIFF_SLONG:
-			{
-				int32* ma;
-				int16* mb;
-				uint32 n;
-				ma=(int32*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong((uint32*)ma);
-					err=TIFFReadDirEntryCheckRangeSshortSlong(*ma);
-					if (err!=TIFFReadDirEntryErrOk)
-						break;
-					*mb++=(int16)(*ma++);
-				}
-			}
-			break;
-		case TIFF_LONG8:
-			{
-				uint64* ma;
-				int16* mb;
-				uint32 n;
-				ma=(uint64*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong8(ma);
-					err=TIFFReadDirEntryCheckRangeSshortLong8(*ma);
-					if (err!=TIFFReadDirEntryErrOk)
-						break;
-					*mb++=(int16)(*ma++);
-				}
-			}
-			break;
-		case TIFF_SLONG8:
-			{
-				int64* ma;
-				int16* mb;
-				uint32 n;
-				ma=(int64*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong8((uint64*)ma);
-					err=TIFFReadDirEntryCheckRangeSshortSlong8(*ma);
-					if (err!=TIFFReadDirEntryErrOk)
-						break;
-					*mb++=(int16)(*ma++);
-				}
-			}
-			break;
-	}
-	_TIFFfree(origdata);
-	if (err!=TIFFReadDirEntryErrOk)
-	{
-		_TIFFfree(data);
-		return(err);
-	}
-	*value=data;
-	return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryLongArray(TIFF* tif, TIFFDirEntry* direntry, uint32** value)
-{
-	enum TIFFReadDirEntryErr err;
-	uint32 count;
-	void* origdata;
-	uint32* data;
-	switch (direntry->tdir_type)
-	{
-		case TIFF_BYTE:
-		case TIFF_SBYTE:
-		case TIFF_SHORT:
-		case TIFF_SSHORT:
-		case TIFF_LONG:
-		case TIFF_SLONG:
-		case TIFF_LONG8:
-		case TIFF_SLONG8:
-			break;
-		default:
-			return(TIFFReadDirEntryErrType);
-	}
-	err=TIFFReadDirEntryArray(tif,direntry,&count,4,&origdata);
-	if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
-	{
-		*value=0;
-		return(err);
-	}
-	switch (direntry->tdir_type)
-	{
-		case TIFF_LONG:
-			*value=(uint32*)origdata;
-			if (tif->tif_flags&TIFF_SWAB)
-				TIFFSwabArrayOfLong(*value,count);
-			return(TIFFReadDirEntryErrOk);
-		case TIFF_SLONG:
-			{
-				int32* m;
-				uint32 n;
-				m=(int32*)origdata;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong((uint32*)m);
-					err=TIFFReadDirEntryCheckRangeLongSlong(*m);
-					if (err!=TIFFReadDirEntryErrOk)
-					{
-						_TIFFfree(origdata);
-						return(err);
-					}
-					m++;
-				}
-				*value=(uint32*)origdata;
-				return(TIFFReadDirEntryErrOk);
-			}
-	}
-	data=(uint32*)_TIFFmalloc(count*4);
-	if (data==0)
-	{
-		_TIFFfree(origdata);
-		return(TIFFReadDirEntryErrAlloc);
-	}
-	switch (direntry->tdir_type)
-	{
-		case TIFF_BYTE:
-			{
-				uint8* ma;
-				uint32* mb;
-				uint32 n;
-				ma=(uint8*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-					*mb++=(uint32)(*ma++);
-			}
-			break;
-		case TIFF_SBYTE:
-			{
-				int8* ma;
-				uint32* mb;
-				uint32 n;
-				ma=(int8*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					err=TIFFReadDirEntryCheckRangeLongSbyte(*ma);
-					if (err!=TIFFReadDirEntryErrOk)
-						break;
-					*mb++=(uint32)(*ma++);
-				}
-			}
-			break;
-		case TIFF_SHORT:
-			{
-				uint16* ma;
-				uint32* mb;
-				uint32 n;
-				ma=(uint16*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabShort(ma);
-					*mb++=(uint32)(*ma++);
-				}
-			}
-			break;
-		case TIFF_SSHORT:
-			{
-				int16* ma;
-				uint32* mb;
-				uint32 n;
-				ma=(int16*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabShort((uint16*)ma);
-					err=TIFFReadDirEntryCheckRangeLongSshort(*ma);
-					if (err!=TIFFReadDirEntryErrOk)
-						break;
-					*mb++=(uint32)(*ma++);
-				}
-			}
-			break;
-		case TIFF_LONG8:
-			{
-				uint64* ma;
-				uint32* mb;
-				uint32 n;
-				ma=(uint64*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong8(ma);
-					err=TIFFReadDirEntryCheckRangeLongLong8(*ma);
-					if (err!=TIFFReadDirEntryErrOk)
-						break;
-					*mb++=(uint32)(*ma++);
-				}
-			}
-			break;
-		case TIFF_SLONG8:
-			{
-				int64* ma;
-				uint32* mb;
-				uint32 n;
-				ma=(int64*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong8((uint64*)ma);
-					err=TIFFReadDirEntryCheckRangeLongSlong8(*ma);
-					if (err!=TIFFReadDirEntryErrOk)
-						break;
-					*mb++=(uint32)(*ma++);
-				}
-			}
-			break;
-	}
-	_TIFFfree(origdata);
-	if (err!=TIFFReadDirEntryErrOk)
-	{
-		_TIFFfree(data);
-		return(err);
-	}
-	*value=data;
-	return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntrySlongArray(TIFF* tif, TIFFDirEntry* direntry, int32** value)
-{
-	enum TIFFReadDirEntryErr err;
-	uint32 count;
-	void* origdata;
-	int32* data;
-	switch (direntry->tdir_type)
-	{
-		case TIFF_BYTE:
-		case TIFF_SBYTE:
-		case TIFF_SHORT:
-		case TIFF_SSHORT:
-		case TIFF_LONG:
-		case TIFF_SLONG:
-		case TIFF_LONG8:
-		case TIFF_SLONG8:
-			break;
-		default:
-			return(TIFFReadDirEntryErrType);
-	}
-	err=TIFFReadDirEntryArray(tif,direntry,&count,4,&origdata);
-	if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
-	{
-		*value=0;
-		return(err);
-	}
-	switch (direntry->tdir_type)
-	{
-		case TIFF_LONG:
-			{
-				uint32* m;
-				uint32 n;
-				m=(uint32*)origdata;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong((uint32*)m);
-					err=TIFFReadDirEntryCheckRangeSlongLong(*m);
-					if (err!=TIFFReadDirEntryErrOk)
-					{
-						_TIFFfree(origdata);
-						return(err);
-					}
-					m++;
-				}
-				*value=(int32*)origdata;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_SLONG:
-			*value=(int32*)origdata;
-			if (tif->tif_flags&TIFF_SWAB)
-				TIFFSwabArrayOfLong((uint32*)(*value),count);
-			return(TIFFReadDirEntryErrOk);
-	}
-	data=(int32*)_TIFFmalloc(count*4);
-	if (data==0)
-	{
-		_TIFFfree(origdata);
-		return(TIFFReadDirEntryErrAlloc);
-	}
-	switch (direntry->tdir_type)
-	{
-		case TIFF_BYTE:
-			{
-				uint8* ma;
-				int32* mb;
-				uint32 n;
-				ma=(uint8*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-					*mb++=(int32)(*ma++);
-			}
-			break;
-		case TIFF_SBYTE:
-			{
-				int8* ma;
-				int32* mb;
-				uint32 n;
-				ma=(int8*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-					*mb++=(int32)(*ma++);
-			}
-			break;
-		case TIFF_SHORT:
-			{
-				uint16* ma;
-				int32* mb;
-				uint32 n;
-				ma=(uint16*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabShort(ma);
-					*mb++=(int32)(*ma++);
-				}
-			}
-			break;
-		case TIFF_SSHORT:
-			{
-				int16* ma;
-				int32* mb;
-				uint32 n;
-				ma=(int16*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabShort((uint16*)ma);
-					*mb++=(int32)(*ma++);
-				}
-			}
-			break;
-		case TIFF_LONG8:
-			{
-				uint64* ma;
-				int32* mb;
-				uint32 n;
-				ma=(uint64*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong8(ma);
-					err=TIFFReadDirEntryCheckRangeSlongLong8(*ma);
-					if (err!=TIFFReadDirEntryErrOk)
-						break;
-					*mb++=(int32)(*ma++);
-				}
-			}
-			break;
-		case TIFF_SLONG8:
-			{
-				int64* ma;
-				int32* mb;
-				uint32 n;
-				ma=(int64*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong8((uint64*)ma);
-					err=TIFFReadDirEntryCheckRangeSlongSlong8(*ma);
-					if (err!=TIFFReadDirEntryErrOk)
-						break;
-					*mb++=(int32)(*ma++);
-				}
-			}
-			break;
-	}
-	_TIFFfree(origdata);
-	if (err!=TIFFReadDirEntryErrOk)
-	{
-		_TIFFfree(data);
-		return(err);
-	}
-	*value=data;
-	return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8Array(TIFF* tif, TIFFDirEntry* direntry, uint64** value)
-{
-	enum TIFFReadDirEntryErr err;
-	uint32 count;
-	void* origdata;
-	uint64* data;
-	switch (direntry->tdir_type)
-	{
-		case TIFF_BYTE:
-		case TIFF_SBYTE:
-		case TIFF_SHORT:
-		case TIFF_SSHORT:
-		case TIFF_LONG:
-		case TIFF_SLONG:
-		case TIFF_LONG8:
-		case TIFF_SLONG8:
-			break;
-		default:
-			return(TIFFReadDirEntryErrType);
-	}
-	err=TIFFReadDirEntryArray(tif,direntry,&count,8,&origdata);
-	if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
-	{
-		*value=0;
-		return(err);
-	}
-	switch (direntry->tdir_type)
-	{
-		case TIFF_LONG8:
-			*value=(uint64*)origdata;
-			if (tif->tif_flags&TIFF_SWAB)
-				TIFFSwabArrayOfLong8(*value,count);
-			return(TIFFReadDirEntryErrOk);
-		case TIFF_SLONG8:
-			{
-				int64* m;
-				uint32 n;
-				m=(int64*)origdata;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong8((uint64*)m);
-					err=TIFFReadDirEntryCheckRangeLong8Slong8(*m);
-					if (err!=TIFFReadDirEntryErrOk)
-					{
-						_TIFFfree(origdata);
-						return(err);
-					}
-					m++;
-				}
-				*value=(uint64*)origdata;
-				return(TIFFReadDirEntryErrOk);
-			}
-	}
-	data=(uint64*)_TIFFmalloc(count*8);
-	if (data==0)
-	{
-		_TIFFfree(origdata);
-		return(TIFFReadDirEntryErrAlloc);
-	}
-	switch (direntry->tdir_type)
-	{
-		case TIFF_BYTE:
-			{
-				uint8* ma;
-				uint64* mb;
-				uint32 n;
-				ma=(uint8*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-					*mb++=(uint64)(*ma++);
-			}
-			break;
-		case TIFF_SBYTE:
-			{
-				int8* ma;
-				uint64* mb;
-				uint32 n;
-				ma=(int8*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					err=TIFFReadDirEntryCheckRangeLong8Sbyte(*ma);
-					if (err!=TIFFReadDirEntryErrOk)
-						break;
-					*mb++=(uint64)(*ma++);
-				}
-			}
-			break;
-		case TIFF_SHORT:
-			{
-				uint16* ma;
-				uint64* mb;
-				uint32 n;
-				ma=(uint16*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabShort(ma);
-					*mb++=(uint64)(*ma++);
-				}
-			}
-			break;
-		case TIFF_SSHORT:
-			{
-				int16* ma;
-				uint64* mb;
-				uint32 n;
-				ma=(int16*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabShort((uint16*)ma);
-					err=TIFFReadDirEntryCheckRangeLong8Sshort(*ma);
-					if (err!=TIFFReadDirEntryErrOk)
-						break;
-					*mb++=(uint64)(*ma++);
-				}
-			}
-			break;
-		case TIFF_LONG:
-			{
-				uint32* ma;
-				uint64* mb;
-				uint32 n;
-				ma=(uint32*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong(ma);
-					*mb++=(uint64)(*ma++);
-				}
-			}
-			break;
-		case TIFF_SLONG:
-			{
-				int32* ma;
-				uint64* mb;
-				uint32 n;
-				ma=(int32*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong((uint32*)ma);
-					err=TIFFReadDirEntryCheckRangeLong8Slong(*ma);
-					if (err!=TIFFReadDirEntryErrOk)
-						break;
-					*mb++=(uint64)(*ma++);
-				}
-			}
-			break;
-	}
-	_TIFFfree(origdata);
-	if (err!=TIFFReadDirEntryErrOk)
-	{
-		_TIFFfree(data);
-		return(err);
-	}
-	*value=data;
-	return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntrySlong8Array(TIFF* tif, TIFFDirEntry* direntry, int64** value)
-{
-	enum TIFFReadDirEntryErr err;
-	uint32 count;
-	void* origdata;
-	int64* data;
-	switch (direntry->tdir_type)
-	{
-		case TIFF_BYTE:
-		case TIFF_SBYTE:
-		case TIFF_SHORT:
-		case TIFF_SSHORT:
-		case TIFF_LONG:
-		case TIFF_SLONG:
-		case TIFF_LONG8:
-		case TIFF_SLONG8:
-			break;
-		default:
-			return(TIFFReadDirEntryErrType);
-	}
-	err=TIFFReadDirEntryArray(tif,direntry,&count,8,&origdata);
-	if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
-	{
-		*value=0;
-		return(err);
-	}
-	switch (direntry->tdir_type)
-	{
-		case TIFF_LONG8:
-			{
-				uint64* m;
-				uint32 n;
-				m=(uint64*)origdata;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong8(m);
-					err=TIFFReadDirEntryCheckRangeSlong8Long8(*m);
-					if (err!=TIFFReadDirEntryErrOk)
-					{
-						_TIFFfree(origdata);
-						return(err);
-					}
-					m++;
-				}
-				*value=(int64*)origdata;
-				return(TIFFReadDirEntryErrOk);
-			}
-		case TIFF_SLONG8:
-			*value=(int64*)origdata;
-			if (tif->tif_flags&TIFF_SWAB)
-				TIFFSwabArrayOfLong8((uint64*)(*value),count);
-			return(TIFFReadDirEntryErrOk);
-	}
-	data=(int64*)_TIFFmalloc(count*8);
-	if (data==0)
-	{
-		_TIFFfree(origdata);
-		return(TIFFReadDirEntryErrAlloc);
-	}
-	switch (direntry->tdir_type)
-	{
-		case TIFF_BYTE:
-			{
-				uint8* ma;
-				int64* mb;
-				uint32 n;
-				ma=(uint8*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-					*mb++=(int64)(*ma++);
-			}
-			break;
-		case TIFF_SBYTE:
-			{
-				int8* ma;
-				int64* mb;
-				uint32 n;
-				ma=(int8*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-					*mb++=(int64)(*ma++);
-			}
-			break;
-		case TIFF_SHORT:
-			{
-				uint16* ma;
-				int64* mb;
-				uint32 n;
-				ma=(uint16*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabShort(ma);
-					*mb++=(int64)(*ma++);
-				}
-			}
-			break;
-		case TIFF_SSHORT:
-			{
-				int16* ma;
-				int64* mb;
-				uint32 n;
-				ma=(int16*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabShort((uint16*)ma);
-					*mb++=(int64)(*ma++);
-				}
-			}
-			break;
-		case TIFF_LONG:
-			{
-				uint32* ma;
-				int64* mb;
-				uint32 n;
-				ma=(uint32*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong(ma);
-					*mb++=(int64)(*ma++);
-				}
-			}
-			break;
-		case TIFF_SLONG:
-			{
-				int32* ma;
-				int64* mb;
-				uint32 n;
-				ma=(int32*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong((uint32*)ma);
-					*mb++=(int64)(*ma++);
-				}
-			}
-			break;
-	}
-	_TIFFfree(origdata);
-	if (err!=TIFFReadDirEntryErrOk)
-	{
-		_TIFFfree(data);
-		return(err);
-	}
-	*value=data;
-	return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryFloatArray(TIFF* tif, TIFFDirEntry* direntry, float** value)
-{
-	enum TIFFReadDirEntryErr err;
-	uint32 count;
-	void* origdata;
-	float* data;
-	switch (direntry->tdir_type)
-	{
-		case TIFF_BYTE:
-		case TIFF_SBYTE:
-		case TIFF_SHORT:
-		case TIFF_SSHORT:
-		case TIFF_LONG:
-		case TIFF_SLONG:
-		case TIFF_LONG8:
-		case TIFF_SLONG8:
-		case TIFF_RATIONAL:
-		case TIFF_SRATIONAL:
-		case TIFF_FLOAT:
-		case TIFF_DOUBLE:
-			break;
-		default:
-			return(TIFFReadDirEntryErrType);
-	}
-	err=TIFFReadDirEntryArray(tif,direntry,&count,4,&origdata);
-	if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
-	{
-		*value=0;
-		return(err);
-	}
-	switch (direntry->tdir_type)
-	{
-		case TIFF_FLOAT:
-			if (tif->tif_flags&TIFF_SWAB)
-				TIFFSwabArrayOfLong((uint32*)origdata,count);  
-			TIFFCvtIEEEDoubleToNative(tif,count,(float*)origdata);
-			*value=(float*)origdata;
-			return(TIFFReadDirEntryErrOk);
-	}
-	data=(float*)_TIFFmalloc(count*sizeof(float));
-	if (data==0)
-	{
-		_TIFFfree(origdata);
-		return(TIFFReadDirEntryErrAlloc);
-	}
-	switch (direntry->tdir_type)
-	{
-		case TIFF_BYTE:
-			{
-				uint8* ma;
-				float* mb;
-				uint32 n;
-				ma=(uint8*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-					*mb++=(float)(*ma++);
-			}
-			break;
-		case TIFF_SBYTE:
-			{
-				int8* ma;
-				float* mb;
-				uint32 n;
-				ma=(int8*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-					*mb++=(float)(*ma++);
-			}
-			break;
-		case TIFF_SHORT:
-			{
-				uint16* ma;
-				float* mb;
-				uint32 n;
-				ma=(uint16*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabShort(ma);
-					*mb++=(float)(*ma++);
-				}
-			}
-			break;
-		case TIFF_SSHORT:
-			{
-				int16* ma;
-				float* mb;
-				uint32 n;
-				ma=(int16*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabShort((uint16*)ma);
-					*mb++=(float)(*ma++);
-				}
-			}
-			break;
-		case TIFF_LONG:
-			{
-				uint32* ma;
-				float* mb;
-				uint32 n;
-				ma=(uint32*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong(ma);
-					*mb++=(float)(*ma++);
-				}
-			}
-			break;
-		case TIFF_SLONG:
-			{
-				int32* ma;
-				float* mb;
-				uint32 n;
-				ma=(int32*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong((uint32*)ma);
-					*mb++=(float)(*ma++);
-				}
-			}
-			break;
-		case TIFF_LONG8:
-			{
-				uint64* ma;
-				float* mb;
-				uint32 n;
-				ma=(uint64*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong8(ma);
-#if defined(__WIN32__) && (_MSC_VER < 1500)
-					/*
-					 * XXX: MSVC 6.0 does not support
-					 * conversion of 64-bit integers into
-					 * floating point values.
-					 */
-					*mb++ = _TIFFUInt64ToFloat(*ma++);
-#else
-					*mb++ = (float)(*ma++);
-#endif
-				}
-			}
-			break;
-		case TIFF_SLONG8:
-			{
-				int64* ma;
-				float* mb;
-				uint32 n;
-				ma=(int64*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong8((uint64*)ma);
-					*mb++=(float)(*ma++);
-				}
-			}
-			break;
-		case TIFF_RATIONAL:
-			{
-				uint32* ma;
-				uint32 maa;
-				uint32 mab;
-				float* mb;
-				uint32 n;
-				ma=(uint32*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong(ma);
-					maa=*ma++;
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong(ma);
-					mab=*ma++;
-					if (mab==0)
-						*mb++=0.0;
-					else
-						*mb++=(float)maa/(float)mab;
-				}
-			}
-			break;
-		case TIFF_SRATIONAL:
-			{
-				uint32* ma;
-				int32 maa;
-				uint32 mab;
-				float* mb;
-				uint32 n;
-				ma=(uint32*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong(ma);
-					maa=*(int32*)ma;
-					ma++;
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong(ma);
-					mab=*ma++;
-					if (mab==0)
-						*mb++=0.0;
-					else
-						*mb++=(float)maa/(float)mab;
-				}
-			}
-			break;
-		case TIFF_DOUBLE:
-			{
-				double* ma;
-				float* mb;
-				uint32 n;
-				if (tif->tif_flags&TIFF_SWAB)
-					TIFFSwabArrayOfLong8((uint64*)origdata,count);
-				TIFFCvtIEEEDoubleToNative(tif,count,(double*)origdata);
-				ma=(double*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-					*mb++=(float)(*ma++);
-			}
-			break;
-	}
-	_TIFFfree(origdata);
-	if (err!=TIFFReadDirEntryErrOk)
-	{
-		_TIFFfree(data);
-		return(err);
-	}
-	*value=data;
-	return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr
-TIFFReadDirEntryDoubleArray(TIFF* tif, TIFFDirEntry* direntry, double** value)
-{
-	enum TIFFReadDirEntryErr err;
-	uint32 count;
-	void* origdata;
-	double* data;
-	switch (direntry->tdir_type)
-	{
-		case TIFF_BYTE:
-		case TIFF_SBYTE:
-		case TIFF_SHORT:
-		case TIFF_SSHORT:
-		case TIFF_LONG:
-		case TIFF_SLONG:
-		case TIFF_LONG8:
-		case TIFF_SLONG8:
-		case TIFF_RATIONAL:
-		case TIFF_SRATIONAL:
-		case TIFF_FLOAT:
-		case TIFF_DOUBLE:
-			break;
-		default:
-			return(TIFFReadDirEntryErrType);
-	}
-	err=TIFFReadDirEntryArray(tif,direntry,&count,8,&origdata);
-	if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
-	{
-		*value=0;
-		return(err);
-	}
-	switch (direntry->tdir_type)
-	{
-		case TIFF_DOUBLE:
-			if (tif->tif_flags&TIFF_SWAB)
-				TIFFSwabArrayOfLong8((uint64*)origdata,count);
-			TIFFCvtIEEEDoubleToNative(tif,count,(double*)origdata);
-			*value=(double*)origdata;
-			return(TIFFReadDirEntryErrOk);
-	}
-	data=(double*)_TIFFmalloc(count*sizeof(double));
-	if (data==0)
-	{
-		_TIFFfree(origdata);
-		return(TIFFReadDirEntryErrAlloc);
-	}
-	switch (direntry->tdir_type)
-	{
-		case TIFF_BYTE:
-			{
-				uint8* ma;
-				double* mb;
-				uint32 n;
-				ma=(uint8*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-					*mb++=(double)(*ma++);
-			}
-			break;
-		case TIFF_SBYTE:
-			{
-				int8* ma;
-				double* mb;
-				uint32 n;
-				ma=(int8*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-					*mb++=(double)(*ma++);
-			}
-			break;
-		case TIFF_SHORT:
-			{
-				uint16* ma;
-				double* mb;
-				uint32 n;
-				ma=(uint16*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabShort(ma);
-					*mb++=(double)(*ma++);
-				}
-			}
-			break;
-		case TIFF_SSHORT:
-			{
-				int16* ma;
-				double* mb;
-				uint32 n;
-				ma=(int16*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabShort((uint16*)ma);
-					*mb++=(double)(*ma++);
-				}
-			}
-			break;
-		case TIFF_LONG:
-			{
-				uint32* ma;
-				double* mb;
-				uint32 n;
-				ma=(uint32*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong(ma);
-					*mb++=(double)(*ma++);
-				}
-			}
-			break;
-		case TIFF_SLONG:
-			{
-				int32* ma;
-				double* mb;
-				uint32 n;
-				ma=(int32*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong((uint32*)ma);
-					*mb++=(double)(*ma++);
-				}
-			}
-			break;
-		case TIFF_LONG8:
-			{
-				uint64* ma;
-				double* mb;
-				uint32 n;
-				ma=(uint64*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong8(ma);
-#if defined(__WIN32__) && (_MSC_VER < 1500)
-					/*
-					 * XXX: MSVC 6.0 does not support
-					 * conversion of 64-bit integers into
-					 * floating point values.
-					 */
-					*mb++ = _TIFFUInt64ToDouble(*ma++);
-#else
-					*mb++ = (double)(*ma++);
-#endif
-				}
-			}
-			break;
-		case TIFF_SLONG8:
-			{
-				int64* ma;
-				double* mb;
-				uint32 n;
-				ma=(int64*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong8((uint64*)ma);
-					*mb++=(double)(*ma++);
-				}
-			}
-			break;
-		case TIFF_RATIONAL:
-			{
-				uint32* ma;
-				uint32 maa;
-				uint32 mab;
-				double* mb;
-				uint32 n;
-				ma=(uint32*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong(ma);
-					maa=*ma++;
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong(ma);
-					mab=*ma++;
-					if (mab==0)
-						*mb++=0.0;
-					else
-						*mb++=(double)maa/(double)mab;
-				}
-			}
-			break;
-		case TIFF_SRATIONAL:
-			{
-				uint32* ma;
-				int32 maa;
-				uint32 mab;
-				double* mb;
-				uint32 n;
-				ma=(uint32*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong(ma);
-					maa=*(int32*)ma;
-					ma++;
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong(ma);
-					mab=*ma++;
-					if (mab==0)
-						*mb++=0.0;
-					else
-						*mb++=(double)maa/(double)mab;
-				}
-			}
-			break;
-		case TIFF_FLOAT:
-			{
-				float* ma;
-				double* mb;
-				uint32 n;
-				if (tif->tif_flags&TIFF_SWAB)
-					TIFFSwabArrayOfLong((uint32*)origdata,count);  
-				TIFFCvtIEEEFloatToNative(tif,count,(float*)origdata);
-				ma=(float*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-					*mb++=(double)(*ma++);
-			}
-			break;
-	}
-	_TIFFfree(origdata);
-	if (err!=TIFFReadDirEntryErrOk)
-	{
-		_TIFFfree(data);
-		return(err);
-	}
-	*value=data;
-	return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8Array(TIFF* tif, TIFFDirEntry* direntry, uint64** value)
-{
-	enum TIFFReadDirEntryErr err;
-	uint32 count;
-	void* origdata;
-	uint64* data;
-	switch (direntry->tdir_type)
-	{
-		case TIFF_LONG:
-		case TIFF_LONG8:
-		case TIFF_IFD:
-		case TIFF_IFD8:
-			break;
-		default:
-			return(TIFFReadDirEntryErrType);
-	}
-	err=TIFFReadDirEntryArray(tif,direntry,&count,8,&origdata);
-	if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
-	{
-		*value=0;
-		return(err);
-	}
-	switch (direntry->tdir_type)
-	{
-		case TIFF_LONG8:
-		case TIFF_IFD8:
-			*value=(uint64*)origdata;
-			if (tif->tif_flags&TIFF_SWAB)
-				TIFFSwabArrayOfLong8(*value,count);
-			return(TIFFReadDirEntryErrOk);
-	}
-	data=(uint64*)_TIFFmalloc(count*8);
-	if (data==0)
-	{
-		_TIFFfree(origdata);
-		return(TIFFReadDirEntryErrAlloc);
-	}
-	switch (direntry->tdir_type)
-	{
-		case TIFF_LONG:
-		case TIFF_IFD:
-			{
-				uint32* ma;
-				uint64* mb;
-				uint32 n;
-				ma=(uint32*)origdata;
-				mb=data;
-				for (n=0; n<count; n++)
-				{
-					if (tif->tif_flags&TIFF_SWAB)
-						TIFFSwabLong(ma);
-					*mb++=(uint64)(*ma++);
-				}
-			}
-			break;
-	}
-	_TIFFfree(origdata);
-	if (err!=TIFFReadDirEntryErrOk)
-	{
-		_TIFFfree(data);
-		return(err);
-	}
-	*value=data;
-	return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryPersampleShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value)
-{
-	enum TIFFReadDirEntryErr err;
-	uint16* m;
-	uint16* na;
-	uint16 nb;
-	if (direntry->tdir_count<(uint64)tif->tif_dir.td_samplesperpixel)
-		return(TIFFReadDirEntryErrCount);
-	err=TIFFReadDirEntryShortArray(tif,direntry,&m);
-	if (err!=TIFFReadDirEntryErrOk)
-		return(err);
-	na=m;
-	nb=tif->tif_dir.td_samplesperpixel;
-	*value=*na++;
-	nb--;
-	while (nb>0)
-	{
-		if (*na++!=*value)
-		{
-			err=TIFFReadDirEntryErrPsdif;
-			break;
-		}
-		nb--;
-	}
-	_TIFFfree(m);
-	return(err);
-}
-
-#if 0
-static enum TIFFReadDirEntryErr TIFFReadDirEntryPersampleDouble(TIFF* tif, TIFFDirEntry* direntry, double* value)
-{
-	enum TIFFReadDirEntryErr err;
-	double* m;
-	double* na;
-	uint16 nb;
-	if (direntry->tdir_count<(uint64)tif->tif_dir.td_samplesperpixel)
-		return(TIFFReadDirEntryErrCount);
-	err=TIFFReadDirEntryDoubleArray(tif,direntry,&m);
-	if (err!=TIFFReadDirEntryErrOk)
-		return(err);
-	na=m;
-	nb=tif->tif_dir.td_samplesperpixel;
-	*value=*na++;
-	nb--;
-	while (nb>0)
-	{
-		if (*na++!=*value)
-		{
-			err=TIFFReadDirEntryErrPsdif;
-			break;
-		}
-		nb--;
-	}
-	_TIFFfree(m);
-	return(err);
-}
-#endif
-
-static void TIFFReadDirEntryCheckedByte(TIFF* tif, TIFFDirEntry* direntry, uint8* value)
-{
-	(void) tif;
-	*value=*(uint8*)(&direntry->tdir_offset);
-}
-
-static void TIFFReadDirEntryCheckedSbyte(TIFF* tif, TIFFDirEntry* direntry, int8* value)
-{
-	(void) tif;
-	*value=*(int8*)(&direntry->tdir_offset);
-}
-
-static void TIFFReadDirEntryCheckedShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value)
-{
-	*value = direntry->tdir_offset.toff_short;
-	/* *value=*(uint16*)(&direntry->tdir_offset); */
-	if (tif->tif_flags&TIFF_SWAB)
-		TIFFSwabShort(value);
-}
-
-static void TIFFReadDirEntryCheckedSshort(TIFF* tif, TIFFDirEntry* direntry, int16* value)
-{
-	*value=*(int16*)(&direntry->tdir_offset);
-	if (tif->tif_flags&TIFF_SWAB)
-		TIFFSwabShort((uint16*)value);
-}
-
-static void TIFFReadDirEntryCheckedLong(TIFF* tif, TIFFDirEntry* direntry, uint32* value)
-{
-	*value=*(uint32*)(&direntry->tdir_offset);
-	if (tif->tif_flags&TIFF_SWAB)
-		TIFFSwabLong(value);
-}
-
-static void TIFFReadDirEntryCheckedSlong(TIFF* tif, TIFFDirEntry* direntry, int32* value)
-{
-	*value=*(int32*)(&direntry->tdir_offset);
-	if (tif->tif_flags&TIFF_SWAB)
-		TIFFSwabLong((uint32*)value);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedLong8(TIFF* tif, TIFFDirEntry* direntry, uint64* value)
-{
-	if (!(tif->tif_flags&TIFF_BIGTIFF))
-	{
-		enum TIFFReadDirEntryErr err;
-		uint32 offset = direntry->tdir_offset.toff_long;
-		if (tif->tif_flags&TIFF_SWAB)
-			TIFFSwabLong(&offset);
-		err=TIFFReadDirEntryData(tif,offset,8,value);
-		if (err!=TIFFReadDirEntryErrOk)
-			return(err);
-	}
-	else
-		*value = direntry->tdir_offset.toff_long8;
-	if (tif->tif_flags&TIFF_SWAB)
-		TIFFSwabLong8(value);
-	return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSlong8(TIFF* tif, TIFFDirEntry* direntry, int64* value)
-{
-	if (!(tif->tif_flags&TIFF_BIGTIFF))
-	{
-		enum TIFFReadDirEntryErr err;
-		uint32 offset = direntry->tdir_offset.toff_long;
-		if (tif->tif_flags&TIFF_SWAB)
-			TIFFSwabLong(&offset);
-		err=TIFFReadDirEntryData(tif,offset,8,value);
-		if (err!=TIFFReadDirEntryErrOk)
-			return(err);
-	}
-	else
-		*value=*(int64*)(&direntry->tdir_offset);
-	if (tif->tif_flags&TIFF_SWAB)
-		TIFFSwabLong8((uint64*)value);
-	return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedRational(TIFF* tif, TIFFDirEntry* direntry, double* value)
-{
-	UInt64Aligned_t m;
-
-	assert(sizeof(double)==8);
-	assert(sizeof(uint64)==8);
-	assert(sizeof(uint32)==4);
-	if (!(tif->tif_flags&TIFF_BIGTIFF))
-	{
-		enum TIFFReadDirEntryErr err;
-		uint32 offset = direntry->tdir_offset.toff_long;
-		if (tif->tif_flags&TIFF_SWAB)
-			TIFFSwabLong(&offset);
-		err=TIFFReadDirEntryData(tif,offset,8,m.i);
-		if (err!=TIFFReadDirEntryErrOk)
-			return(err);
-	}
-	else
-		m.l = direntry->tdir_offset.toff_long8;
-	if (tif->tif_flags&TIFF_SWAB)
-		TIFFSwabArrayOfLong(m.i,2);
-	if (m.i[0]==0)
-		*value=0.0;
-	else
-		*value=(double)m.i[0]/(double)m.i[1];
-	return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSrational(TIFF* tif, TIFFDirEntry* direntry, double* value)
-{
-	UInt64Aligned_t m;
-	assert(sizeof(double)==8);
-	assert(sizeof(uint64)==8);
-	assert(sizeof(int32)==4);
-	assert(sizeof(uint32)==4);
-	if (!(tif->tif_flags&TIFF_BIGTIFF))
-	{
-		enum TIFFReadDirEntryErr err;
-		uint32 offset = direntry->tdir_offset.toff_long;
-		if (tif->tif_flags&TIFF_SWAB)
-			TIFFSwabLong(&offset);
-		err=TIFFReadDirEntryData(tif,offset,8,m.i);
-		if (err!=TIFFReadDirEntryErrOk)
-			return(err);
-	}
-	else
-		m.l=direntry->tdir_offset.toff_long8;
-	if (tif->tif_flags&TIFF_SWAB)
-		TIFFSwabArrayOfLong(m.i,2);
-	if ((int32)m.i[0]==0)
-		*value=0.0;
-	else
-		*value=(double)((int32)m.i[0])/(double)m.i[1];
-	return(TIFFReadDirEntryErrOk);
-}
-
-static void TIFFReadDirEntryCheckedFloat(TIFF* tif, TIFFDirEntry* direntry, float* value)
-{
-         union
-	 {
-	   float  f;
-	   uint32 i;
-	 } float_union;
-	assert(sizeof(float)==4);
-	assert(sizeof(uint32)==4);
-	assert(sizeof(float_union)==4);
-	float_union.i=*(uint32*)(&direntry->tdir_offset);
-	*value=float_union.f;
-	if (tif->tif_flags&TIFF_SWAB)
-		TIFFSwabLong((uint32*)value);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedDouble(TIFF* tif, TIFFDirEntry* direntry, double* value)
-{
-	assert(sizeof(double)==8);
-	assert(sizeof(uint64)==8);
-	assert(sizeof(UInt64Aligned_t)==8);
-	if (!(tif->tif_flags&TIFF_BIGTIFF))
-	{
-		enum TIFFReadDirEntryErr err;
-		uint32 offset = direntry->tdir_offset.toff_long;
-		if (tif->tif_flags&TIFF_SWAB)
-			TIFFSwabLong(&offset);
-		err=TIFFReadDirEntryData(tif,offset,8,value);
-		if (err!=TIFFReadDirEntryErrOk)
-			return(err);
-	}
-	else
-	{
-	       UInt64Aligned_t uint64_union;
-	       uint64_union.l=direntry->tdir_offset.toff_long8;
-	       *value=uint64_union.d;
-	}
-	if (tif->tif_flags&TIFF_SWAB)
-		TIFFSwabLong8((uint64*)value);
-	return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSbyte(int8 value)
-{
-	if (value<0)
-		return(TIFFReadDirEntryErrRange);
-	else
-		return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteShort(uint16 value)
-{
-	if (value>0xFF)
-		return(TIFFReadDirEntryErrRange);
-	else
-		return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSshort(int16 value)
-{
-	if ((value<0)||(value>0xFF))
-		return(TIFFReadDirEntryErrRange);
-	else
-		return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteLong(uint32 value)
-{
-	if (value>0xFF)
-		return(TIFFReadDirEntryErrRange);
-	else
-		return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSlong(int32 value)
-{
-	if ((value<0)||(value>0xFF))
-		return(TIFFReadDirEntryErrRange);
-	else
-		return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteLong8(uint64 value)
-{
-	if (value>0xFF)
-		return(TIFFReadDirEntryErrRange);
-	else
-		return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSlong8(int64 value)
-{
-	if ((value<0)||(value>0xFF))
-		return(TIFFReadDirEntryErrRange);
-	else
-		return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteByte(uint8 value)
-{
-	if (value>0x7F)
-		return(TIFFReadDirEntryErrRange);
-	else
-		return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteShort(uint16 value)
-{
-	if (value>0x7F)
-		return(TIFFReadDirEntryErrRange);
-	else
-		return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSshort(int16 value)
-{
-	if ((value<-0x80)||(value>0x7F))
-		return(TIFFReadDirEntryErrRange);
-	else
-		return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteLong(uint32 value)
-{
-	if (value>0x7F)
-		return(TIFFReadDirEntryErrRange);
-	else
-		return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSlong(int32 value)
-{
-	if ((value<-0x80)||(value>0x7F))
-		return(TIFFReadDirEntryErrRange);
-	else
-		return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteLong8(uint64 value)
-{
-	if (value>0x7F)
-		return(TIFFReadDirEntryErrRange);
-	else
-		return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSlong8(int64 value)
-{
-	if ((value<-0x80)||(value>0x7F))
-		return(TIFFReadDirEntryErrRange);
-	else
-		return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSbyte(int8 value)
-{
-	if (value<0)
-		return(TIFFReadDirEntryErrRange);
-	else
-		return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSshort(int16 value)
-{
-	if (value<0)
-		return(TIFFReadDirEntryErrRange);
-	else
-		return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortLong(uint32 value)
-{
-	if (value>0xFFFF)
-		return(TIFFReadDirEntryErrRange);
-	else
-		return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSlong(int32 value)
-{
-	if ((value<0)||(value>0xFFFF))
-		return(TIFFReadDirEntryErrRange);
-	else
-		return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortLong8(uint64 value)
-{
-	if (value>0xFFFF)
-		return(TIFFReadDirEntryErrRange);
-	else
-		return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSlong8(int64 value)
-{
-	if ((value<0)||(value>0xFFFF))
-		return(TIFFReadDirEntryErrRange);
-	else
-		return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortShort(uint16 value)
-{
-	if (value>0x7FFF)
-		return(TIFFReadDirEntryErrRange);
-	else
-		return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortLong(uint32 value)
-{
-	if (value>0x7FFF)
-		return(TIFFReadDirEntryErrRange);
-	else
-		return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortSlong(int32 value)
-{
-	if ((value<-0x8000)||(value>0x7FFF))
-		return(TIFFReadDirEntryErrRange);
-	else
-		return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortLong8(uint64 value)
-{
-	if (value>0x7FFF)
-		return(TIFFReadDirEntryErrRange);
-	else
-		return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortSlong8(int64 value)
-{
-	if ((value<-0x8000)||(value>0x7FFF))
-		return(TIFFReadDirEntryErrRange);
-	else
-		return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSbyte(int8 value)
-{
-	if (value<0)
-		return(TIFFReadDirEntryErrRange);
-	else
-		return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSshort(int16 value)
-{
-	if (value<0)
-		return(TIFFReadDirEntryErrRange);
-	else
-		return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSlong(int32 value)
-{
-	if (value<0)
-		return(TIFFReadDirEntryErrRange);
-	else
-		return(TIFFReadDirEntryErrOk);
-}
-
-/*
- * Largest 32-bit unsigned integer value.
- */
-#if defined(__WIN32__) && defined(_MSC_VER)
-# define TIFF_UINT32_MAX 0xFFFFFFFFI64
-#else
-# define TIFF_UINT32_MAX 0xFFFFFFFFLL
-#endif
-
-static enum TIFFReadDirEntryErr
-TIFFReadDirEntryCheckRangeLongLong8(uint64 value)
-{
-	if (value > TIFF_UINT32_MAX)
-		return(TIFFReadDirEntryErrRange);
-	else
-		return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr
-TIFFReadDirEntryCheckRangeLongSlong8(int64 value)
-{
-	if ((value<0) || (value > TIFF_UINT32_MAX))
-		return(TIFFReadDirEntryErrRange);
-	else
-		return(TIFFReadDirEntryErrOk);
-}
-
-#undef TIFF_UINT32_MAX
-
-static enum TIFFReadDirEntryErr
-TIFFReadDirEntryCheckRangeSlongLong(uint32 value)
-{
-	if (value > 0x7FFFFFFFUL)
-		return(TIFFReadDirEntryErrRange);
-	else
-		return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr
-TIFFReadDirEntryCheckRangeSlongLong8(uint64 value)
-{
-	if (value > 0x7FFFFFFFUL)
-		return(TIFFReadDirEntryErrRange);
-	else
-		return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr
-TIFFReadDirEntryCheckRangeSlongSlong8(int64 value)
-{
-	if ((value < 0L-0x80000000L) || (value > 0x7FFFFFFFL))
-		return(TIFFReadDirEntryErrRange);
-	else
-		return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr
-TIFFReadDirEntryCheckRangeLong8Sbyte(int8 value)
-{
-	if (value < 0)
-		return(TIFFReadDirEntryErrRange);
-	else
-		return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr
-TIFFReadDirEntryCheckRangeLong8Sshort(int16 value)
-{
-	if (value < 0)
-		return(TIFFReadDirEntryErrRange);
-	else
-		return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr
-TIFFReadDirEntryCheckRangeLong8Slong(int32 value)
-{
-	if (value < 0)
-		return(TIFFReadDirEntryErrRange);
-	else
-		return(TIFFReadDirEntryErrOk);
-}
-
-static enum TIFFReadDirEntryErr
-TIFFReadDirEntryCheckRangeLong8Slong8(int64 value)
-{
-	if (value < 0)
-		return(TIFFReadDirEntryErrRange);
-	else
-		return(TIFFReadDirEntryErrOk);
-}
-
-/*
- * Largest 64-bit signed integer value.
- */
-#if defined(__WIN32__) && defined(_MSC_VER)
-# define TIFF_INT64_MAX 0x7FFFFFFFFFFFFFFFI64
-#else
-# define TIFF_INT64_MAX 0x7FFFFFFFFFFFFFFFLL
-#endif
-
-static enum TIFFReadDirEntryErr
-TIFFReadDirEntryCheckRangeSlong8Long8(uint64 value)
-{
-	if (value > TIFF_INT64_MAX)
-		return(TIFFReadDirEntryErrRange);
-	else
-		return(TIFFReadDirEntryErrOk);
-}
-
-#undef TIFF_INT64_MAX
-
-static enum TIFFReadDirEntryErr
-TIFFReadDirEntryData(TIFF* tif, uint64 offset, tmsize_t size, void* dest)
-{
-	assert(size>0);
-	if (!isMapped(tif)) {
-		if (!SeekOK(tif,offset))
-			return(TIFFReadDirEntryErrIo);
-		if (!ReadOK(tif,dest,size))
-			return(TIFFReadDirEntryErrIo);
-	} else {
-		size_t ma,mb;
-		ma=(size_t)offset;
-		mb=ma+size;
-		if (((uint64)ma!=offset)
-		    || (mb < ma)
-		    || (mb - ma != (size_t) size)
-		    || (mb < (size_t)size)
-		    || (mb > (size_t)tif->tif_size)
-		    )
-			return(TIFFReadDirEntryErrIo);
-		_TIFFmemcpy(dest,tif->tif_base+ma,size);
-	}
-	return(TIFFReadDirEntryErrOk);
-}
-
-static void TIFFReadDirEntryOutputErr(TIFF* tif, enum TIFFReadDirEntryErr err, const char* module, const char* tagname, int recover)
-{
-	if (!recover) {
-		switch (err) {
-			case TIFFReadDirEntryErrCount:
-				TIFFErrorExt(tif->tif_clientdata, module,
-					     "Incorrect count for \"%s\"",
-					     tagname);
-				break;
-			case TIFFReadDirEntryErrType:
-				TIFFErrorExt(tif->tif_clientdata, module,
-					     "Incompatible type for \"%s\"",
-					     tagname);
-				break;
-			case TIFFReadDirEntryErrIo:
-				TIFFErrorExt(tif->tif_clientdata, module,
-					     "IO error during reading of \"%s\"",
-					     tagname);
-				break;
-			case TIFFReadDirEntryErrRange:
-				TIFFErrorExt(tif->tif_clientdata, module,
-					     "Incorrect value for \"%s\"",
-					     tagname);
-				break;
-			case TIFFReadDirEntryErrPsdif:
-				TIFFErrorExt(tif->tif_clientdata, module,
-			"Cannot handle different values per sample for \"%s\"",
-					     tagname);
-				break;
-			case TIFFReadDirEntryErrSizesan:
-				TIFFErrorExt(tif->tif_clientdata, module,
-				"Sanity check on size of \"%s\" value failed",
-					     tagname);
-				break;
-			case TIFFReadDirEntryErrAlloc:
-				TIFFErrorExt(tif->tif_clientdata, module,
-					     "Out of memory reading of \"%s\"",
-					     tagname);
-				break;
-			default:
-				assert(0);   /* we should never get here */
-				break;
-		}
-	} else {
-		switch (err) {
-			case TIFFReadDirEntryErrCount:
-				TIFFErrorExt(tif->tif_clientdata, module,
-				"Incorrect count for \"%s\"; tag ignored",
-					     tagname);
-				break;
-			case TIFFReadDirEntryErrType:
-				TIFFWarningExt(tif->tif_clientdata, module,
-				"Incompatible type for \"%s\"; tag ignored",
-					       tagname);
-				break;
-			case TIFFReadDirEntryErrIo:
-				TIFFWarningExt(tif->tif_clientdata, module,
-			"IO error during reading of \"%s\"; tag ignored",
-					       tagname);
-				break;
-			case TIFFReadDirEntryErrRange:
-				TIFFWarningExt(tif->tif_clientdata, module,
-				"Incorrect value for \"%s\"; tag ignored",
-					       tagname);
-				break;
-			case TIFFReadDirEntryErrPsdif:
-				TIFFWarningExt(tif->tif_clientdata, module,
-	"Cannot handle different values per sample for \"%s\"; tag ignored",
-					       tagname);
-				break;
-			case TIFFReadDirEntryErrSizesan:
-				TIFFWarningExt(tif->tif_clientdata, module,
-		"Sanity check on size of \"%s\" value failed; tag ignored",
-					       tagname);
-				break;
-			case TIFFReadDirEntryErrAlloc:
-				TIFFWarningExt(tif->tif_clientdata, module,
-				"Out of memory reading of \"%s\"; tag ignored",
-					       tagname);
-				break;
-			default:
-				assert(0);   /* we should never get here */
-				break;
-		}
-	}
-}
-
-/*
- * Read the next TIFF directory from a file and convert it to the internal
- * format. We read directories sequentially.
- */
-int
-TIFFReadDirectory(TIFF* tif)
-{
-	static const char module[] = "TIFFReadDirectory";
-	TIFFDirEntry* dir;
-	uint16 dircount;
-	TIFFDirEntry* dp;
-	uint16 di;
-	const TIFFField* fip;
-	uint32 fii=FAILED_FII;
-        toff_t nextdiroff;
-	tif->tif_diroff=tif->tif_nextdiroff;
-	if (!TIFFCheckDirOffset(tif,tif->tif_nextdiroff))
-		return 0;           /* last offset or bad offset (IFD looping) */
-	(*tif->tif_cleanup)(tif);   /* cleanup any previous compression state */
-	tif->tif_curdir++;
-        nextdiroff = tif->tif_nextdiroff;
-	dircount=TIFFFetchDirectory(tif,nextdiroff,&dir,&tif->tif_nextdiroff);
-	if (!dircount)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,
-		    "Failed to read directory at offset " TIFF_UINT64_FORMAT,nextdiroff);
-		return 0;
-	}
-	TIFFReadDirectoryCheckOrder(tif,dir,dircount);
-
-        /*
-         * Mark duplicates of any tag to be ignored (bugzilla 1994)
-         * to avoid certain pathological problems.
-         */
-	{
-		TIFFDirEntry* ma;
-		uint16 mb;
-		for (ma=dir, mb=0; mb<dircount; ma++, mb++)
-		{
-			TIFFDirEntry* na;
-			uint16 nb;
-			for (na=ma+1, nb=mb+1; nb<dircount; na++, nb++)
-			{
-				if (ma->tdir_tag==na->tdir_tag)
-					na->tdir_tag=IGNORE;
-			}
-		}
-	}
-        
-	tif->tif_flags &= ~TIFF_BEENWRITING;    /* reset before new dir */
-	tif->tif_flags &= ~TIFF_BUF4WRITE;      /* reset before new dir */
-	/* free any old stuff and reinit */
-	TIFFFreeDirectory(tif);
-	TIFFDefaultDirectory(tif);
-	/*
-	 * Electronic Arts writes gray-scale TIFF files
-	 * without a PlanarConfiguration directory entry.
-	 * Thus we setup a default value here, even though
-	 * the TIFF spec says there is no default value.
-	 */
-	TIFFSetField(tif,TIFFTAG_PLANARCONFIG,PLANARCONFIG_CONTIG);
-	/*
-	 * Setup default value and then make a pass over
-	 * the fields to check type and tag information,
-	 * and to extract info required to size data
-	 * structures.  A second pass is made afterwards
-	 * to read in everthing not taken in the first pass.
-	 * But we must process the Compression tag first
-	 * in order to merge in codec-private tag definitions (otherwise
-	 * we may get complaints about unknown tags).  However, the
-	 * Compression tag may be dependent on the SamplesPerPixel
-	 * tag value because older TIFF specs permited Compression
-	 * to be written as a SamplesPerPixel-count tag entry.
-	 * Thus if we don't first figure out the correct SamplesPerPixel
-	 * tag value then we may end up ignoring the Compression tag
-	 * value because it has an incorrect count value (if the
-	 * true value of SamplesPerPixel is not 1).
-	 */
-	dp=TIFFReadDirectoryFindEntry(tif,dir,dircount,TIFFTAG_SAMPLESPERPIXEL);
-	if (dp)
-	{
-		if (!TIFFFetchNormalTag(tif,dp,0))
-			goto bad;
-		dp->tdir_tag=IGNORE;
-	}
-	dp=TIFFReadDirectoryFindEntry(tif,dir,dircount,TIFFTAG_COMPRESSION);
-	if (dp)
-	{
-		/*
-		 * The 5.0 spec says the Compression tag has one value, while
-		 * earlier specs say it has one value per sample.  Because of
-		 * this, we accept the tag if one value is supplied with either
-		 * count.
-		 */
-		uint16 value;
-		enum TIFFReadDirEntryErr err;
-		err=TIFFReadDirEntryShort(tif,dp,&value);
-		if (err==TIFFReadDirEntryErrCount)
-			err=TIFFReadDirEntryPersampleShort(tif,dp,&value);
-		if (err!=TIFFReadDirEntryErrOk)
-		{
-			TIFFReadDirEntryOutputErr(tif,err,module,"Compression",0);
-			goto bad;
-		}
-		if (!TIFFSetField(tif,TIFFTAG_COMPRESSION,value))
-			goto bad;
-		dp->tdir_tag=IGNORE;
-	}
-	else
-	{
-		if (!TIFFSetField(tif,TIFFTAG_COMPRESSION,COMPRESSION_NONE))
-			goto bad;
-	}
-	/*
-	 * First real pass over the directory.
-	 */
-	for (di=0, dp=dir; di<dircount; di++, dp++)
-	{
-		if (dp->tdir_tag!=IGNORE)
-		{
-			TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii);
-			if (fii == FAILED_FII)
-			{
-				TIFFWarningExt(tif->tif_clientdata, module,
-				    "Unknown field with tag %d (0x%x) encountered",
-				    dp->tdir_tag,dp->tdir_tag);
-                                /* the following knowingly leaks the 
-                                   anonymous field structure */
-				if (!_TIFFMergeFields(tif,
-					_TIFFCreateAnonField(tif,
-						dp->tdir_tag,
-						(TIFFDataType) dp->tdir_type),
-					1)) {
-					TIFFWarningExt(tif->tif_clientdata,
-					    module,
-					    "Registering anonymous field with tag %d (0x%x) failed",
-					    dp->tdir_tag,
-					    dp->tdir_tag);
-					dp->tdir_tag=IGNORE;
-				} else {
-					TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii);
-					assert(fii != FAILED_FII);
-				}
-			}
-		}
-		if (dp->tdir_tag!=IGNORE)
-		{
-			fip=tif->tif_fields[fii];
-			if (fip->field_bit==FIELD_IGNORE)
-				dp->tdir_tag=IGNORE;
-			else
-			{
-				switch (dp->tdir_tag)
-				{
-					case TIFFTAG_STRIPOFFSETS:
-					case TIFFTAG_STRIPBYTECOUNTS:
-					case TIFFTAG_TILEOFFSETS:
-					case TIFFTAG_TILEBYTECOUNTS:
-						TIFFSetFieldBit(tif,fip->field_bit);
-						break;
-					case TIFFTAG_IMAGEWIDTH:
-					case TIFFTAG_IMAGELENGTH:
-					case TIFFTAG_IMAGEDEPTH:
-					case TIFFTAG_TILELENGTH:
-					case TIFFTAG_TILEWIDTH:
-					case TIFFTAG_TILEDEPTH:
-					case TIFFTAG_PLANARCONFIG:
-					case TIFFTAG_ROWSPERSTRIP:
-					case TIFFTAG_EXTRASAMPLES:
-						if (!TIFFFetchNormalTag(tif,dp,0))
-							goto bad;
-						dp->tdir_tag=IGNORE;
-						break;
-				}
-			}
-		}
-	}
-	/*
-	 * XXX: OJPEG hack.
-	 * If a) compression is OJPEG, b) planarconfig tag says it's separate,
-	 * c) strip offsets/bytecounts tag are both present and
-	 * d) both contain exactly one value, then we consistently find
-	 * that the buggy implementation of the buggy compression scheme
-	 * matches contig planarconfig best. So we 'fix-up' the tag here
-	 */
-	if ((tif->tif_dir.td_compression==COMPRESSION_OJPEG)&&
-	    (tif->tif_dir.td_planarconfig==PLANARCONFIG_SEPARATE))
-	{
-        if (!_TIFFFillStriles(tif))
-            goto bad;
-		dp=TIFFReadDirectoryFindEntry(tif,dir,dircount,TIFFTAG_STRIPOFFSETS);
-		if ((dp!=0)&&(dp->tdir_count==1))
-		{
-			dp=TIFFReadDirectoryFindEntry(tif,dir,dircount,
-			    TIFFTAG_STRIPBYTECOUNTS);
-			if ((dp!=0)&&(dp->tdir_count==1))
-			{
-				tif->tif_dir.td_planarconfig=PLANARCONFIG_CONTIG;
-				TIFFWarningExt(tif->tif_clientdata,module,
-				    "Planarconfig tag value assumed incorrect, "
-				    "assuming data is contig instead of chunky");
-			}
-		}
-	}
-	/*
-	 * Allocate directory structure and setup defaults.
-	 */
-	if (!TIFFFieldSet(tif,FIELD_IMAGEDIMENSIONS))
-	{
-		MissingRequired(tif,"ImageLength");
-		goto bad;
-	}
-	/*
-	 * Setup appropriate structures (by strip or by tile)
-	 */
-	if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) {
-		tif->tif_dir.td_nstrips = TIFFNumberOfStrips(tif);  
-		tif->tif_dir.td_tilewidth = tif->tif_dir.td_imagewidth;
-		tif->tif_dir.td_tilelength = tif->tif_dir.td_rowsperstrip;
-		tif->tif_dir.td_tiledepth = tif->tif_dir.td_imagedepth;
-		tif->tif_flags &= ~TIFF_ISTILED;
-	} else {
-		tif->tif_dir.td_nstrips = TIFFNumberOfTiles(tif);
-		tif->tif_flags |= TIFF_ISTILED;
-	}
-	if (!tif->tif_dir.td_nstrips) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-		    "Cannot handle zero number of %s",
-		    isTiled(tif) ? "tiles" : "strips");
-		goto bad;
-	}
-	tif->tif_dir.td_stripsperimage = tif->tif_dir.td_nstrips;
-	if (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE)
-		tif->tif_dir.td_stripsperimage /= tif->tif_dir.td_samplesperpixel;
-	if (!TIFFFieldSet(tif, FIELD_STRIPOFFSETS)) {
-		if ((tif->tif_dir.td_compression==COMPRESSION_OJPEG) &&
-		    (isTiled(tif)==0) &&
-		    (tif->tif_dir.td_nstrips==1)) {
-			/*
-			 * XXX: OJPEG hack.
-			 * If a) compression is OJPEG, b) it's not a tiled TIFF,
-			 * and c) the number of strips is 1,
-			 * then we tolerate the absence of stripoffsets tag,
-			 * because, presumably, all required data is in the
-			 * JpegInterchangeFormat stream.
-			 */
-			TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
-		} else {
-			MissingRequired(tif,
-				isTiled(tif) ? "TileOffsets" : "StripOffsets");
-			goto bad;
-		}
-	}
-	/*
-	 * Second pass: extract other information.
-	 */
-	for (di=0, dp=dir; di<dircount; di++, dp++)
-	{
-		switch (dp->tdir_tag)
-		{
-			case IGNORE:
-				break;
-			case TIFFTAG_MINSAMPLEVALUE:
-			case TIFFTAG_MAXSAMPLEVALUE:
-			case TIFFTAG_BITSPERSAMPLE:
-			case TIFFTAG_DATATYPE:
-			case TIFFTAG_SAMPLEFORMAT:
-				/*
-				 * The MinSampleValue, MaxSampleValue, BitsPerSample
-				 * DataType and SampleFormat tags are supposed to be
-				 * written as one value/sample, but some vendors
-				 * incorrectly write one value only -- so we accept
-				 * that as well (yech). Other vendors write correct
-				 * value for NumberOfSamples, but incorrect one for
-				 * BitsPerSample and friends, and we will read this
-				 * too.
-				 */
-				{
-					uint16 value;
-					enum TIFFReadDirEntryErr err;
-					err=TIFFReadDirEntryShort(tif,dp,&value);
-					if (err==TIFFReadDirEntryErrCount)
-						err=TIFFReadDirEntryPersampleShort(tif,dp,&value);
-					if (err!=TIFFReadDirEntryErrOk)
-					{
-						fip = TIFFFieldWithTag(tif,dp->tdir_tag);
-						TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",0);
-						goto bad;
-					}
-					if (!TIFFSetField(tif,dp->tdir_tag,value))
-						goto bad;
-				}
-				break;
-			case TIFFTAG_SMINSAMPLEVALUE:
-			case TIFFTAG_SMAXSAMPLEVALUE:
-				{
-
-					double *data;
-					enum TIFFReadDirEntryErr err;
-					uint32 saved_flags;
-					int m;
-					if (dp->tdir_count != (uint64)tif->tif_dir.td_samplesperpixel)
-						err = TIFFReadDirEntryErrCount;
-					else
-						err = TIFFReadDirEntryDoubleArray(tif, dp, &data);
-					if (err!=TIFFReadDirEntryErrOk)
-					{
-						fip = TIFFFieldWithTag(tif,dp->tdir_tag);
-						TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",0);
-						goto bad;
-					}
-					saved_flags = tif->tif_flags;
-					tif->tif_flags |= TIFF_PERSAMPLE;
-					m = TIFFSetField(tif,dp->tdir_tag,data);
-					tif->tif_flags = saved_flags;
-					_TIFFfree(data);
-					if (!m)
-						goto bad;
-				}
-				break;
-			case TIFFTAG_STRIPOFFSETS:
-			case TIFFTAG_TILEOFFSETS:
-#if defined(DEFER_STRILE_LOAD)
-                                _TIFFmemcpy( &(tif->tif_dir.td_stripoffset_entry),
-                                             dp, sizeof(TIFFDirEntry) );
-#else                          
-				if (!TIFFFetchStripThing(tif,dp,tif->tif_dir.td_nstrips,&tif->tif_dir.td_stripoffset))  
-					goto bad;
-#endif                                
-				break;
-			case TIFFTAG_STRIPBYTECOUNTS:
-			case TIFFTAG_TILEBYTECOUNTS:
-#if defined(DEFER_STRILE_LOAD)
-                                _TIFFmemcpy( &(tif->tif_dir.td_stripbytecount_entry),
-                                             dp, sizeof(TIFFDirEntry) );
-#else                          
-				if (!TIFFFetchStripThing(tif,dp,tif->tif_dir.td_nstrips,&tif->tif_dir.td_stripbytecount))  
-					goto bad;
-#endif                                
-				break;
-			case TIFFTAG_COLORMAP:
-			case TIFFTAG_TRANSFERFUNCTION:
-				{
-					enum TIFFReadDirEntryErr err;
-					uint32 countpersample;
-					uint32 countrequired;
-					uint32 incrementpersample;
-					uint16* value=NULL;
-					countpersample=(1L<<tif->tif_dir.td_bitspersample);
-					if ((dp->tdir_tag==TIFFTAG_TRANSFERFUNCTION)&&(dp->tdir_count==(uint64)countpersample))
-					{
-						countrequired=countpersample;
-						incrementpersample=0;
-					}
-					else
-					{
-						countrequired=3*countpersample;
-						incrementpersample=countpersample;
-					}
-					if (dp->tdir_count!=(uint64)countrequired)
-						err=TIFFReadDirEntryErrCount;
-					else
-						err=TIFFReadDirEntryShortArray(tif,dp,&value);
-					if (err!=TIFFReadDirEntryErrOk)
-                    {
-						fip = TIFFFieldWithTag(tif,dp->tdir_tag);
-						TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",1);
-                    }
-					else
-					{
-						TIFFSetField(tif,dp->tdir_tag,value,value+incrementpersample,value+2*incrementpersample);
-						_TIFFfree(value);
-					}
-				}
-				break;
-/* BEGIN REV 4.0 COMPATIBILITY */
-			case TIFFTAG_OSUBFILETYPE:
-				{
-					uint16 valueo;
-					uint32 value;
-					if (TIFFReadDirEntryShort(tif,dp,&valueo)==TIFFReadDirEntryErrOk)
-					{
-						switch (valueo)
-						{
-							case OFILETYPE_REDUCEDIMAGE: value=FILETYPE_REDUCEDIMAGE; break;
-							case OFILETYPE_PAGE: value=FILETYPE_PAGE; break;
-							default: value=0; break;
-						}
-						if (value!=0)
-							TIFFSetField(tif,TIFFTAG_SUBFILETYPE,value);
-					}
-				}
-				break;
-/* END REV 4.0 COMPATIBILITY */
-			default:
-				(void) TIFFFetchNormalTag(tif, dp, TRUE);
-				break;
-		}
-	}
-	/*
-	 * OJPEG hack:
-	 * - If a) compression is OJPEG, and b) photometric tag is missing,
-	 * then we consistently find that photometric should be YCbCr
-	 * - If a) compression is OJPEG, and b) photometric tag says it's RGB,
-	 * then we consistently find that the buggy implementation of the
-	 * buggy compression scheme matches photometric YCbCr instead.
-	 * - If a) compression is OJPEG, and b) bitspersample tag is missing,
-	 * then we consistently find bitspersample should be 8.
-	 * - If a) compression is OJPEG, b) samplesperpixel tag is missing,
-	 * and c) photometric is RGB or YCbCr, then we consistently find
-	 * samplesperpixel should be 3
-	 * - If a) compression is OJPEG, b) samplesperpixel tag is missing,
-	 * and c) photometric is MINISWHITE or MINISBLACK, then we consistently
-	 * find samplesperpixel should be 3
-	 */
-	if (tif->tif_dir.td_compression==COMPRESSION_OJPEG)
-	{
-		if (!TIFFFieldSet(tif,FIELD_PHOTOMETRIC))
-		{
-			TIFFWarningExt(tif->tif_clientdata, module,
-			    "Photometric tag is missing, assuming data is YCbCr");
-			if (!TIFFSetField(tif,TIFFTAG_PHOTOMETRIC,PHOTOMETRIC_YCBCR))
-				goto bad;
-		}
-		else if (tif->tif_dir.td_photometric==PHOTOMETRIC_RGB)
-		{
-			tif->tif_dir.td_photometric=PHOTOMETRIC_YCBCR;
-			TIFFWarningExt(tif->tif_clientdata, module,
-			    "Photometric tag value assumed incorrect, "
-			    "assuming data is YCbCr instead of RGB");
-		}
-		if (!TIFFFieldSet(tif,FIELD_BITSPERSAMPLE))
-		{
-			TIFFWarningExt(tif->tif_clientdata,module,
-			    "BitsPerSample tag is missing, assuming 8 bits per sample");
-			if (!TIFFSetField(tif,TIFFTAG_BITSPERSAMPLE,8))
-				goto bad;
-		}
-		if (!TIFFFieldSet(tif,FIELD_SAMPLESPERPIXEL))
-		{
-			if (tif->tif_dir.td_photometric==PHOTOMETRIC_RGB)
-			{
-				TIFFWarningExt(tif->tif_clientdata,module,
-				    "SamplesPerPixel tag is missing, "
-				    "assuming correct SamplesPerPixel value is 3");
-				if (!TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,3))
-					goto bad;
-			}
-			if (tif->tif_dir.td_photometric==PHOTOMETRIC_YCBCR)
-			{
-				TIFFWarningExt(tif->tif_clientdata,module,
-				    "SamplesPerPixel tag is missing, "
-				    "applying correct SamplesPerPixel value of 3");
-				if (!TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,3))
-					goto bad;
-			}
-			else if ((tif->tif_dir.td_photometric==PHOTOMETRIC_MINISWHITE)
-				 || (tif->tif_dir.td_photometric==PHOTOMETRIC_MINISBLACK))
-			{
-				/*
-				 * SamplesPerPixel tag is missing, but is not required
-				 * by spec.  Assume correct SamplesPerPixel value of 1.
-				 */
-				if (!TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,1))
-					goto bad;
-			}
-		}
-	}
-	/*
-	 * Verify Palette image has a Colormap.
-	 */
-	if (tif->tif_dir.td_photometric == PHOTOMETRIC_PALETTE &&
-	    !TIFFFieldSet(tif, FIELD_COLORMAP)) {
-		if ( tif->tif_dir.td_bitspersample>=8 && tif->tif_dir.td_samplesperpixel==3)
-			tif->tif_dir.td_photometric = PHOTOMETRIC_RGB;
-		else if (tif->tif_dir.td_bitspersample>=8)
-			tif->tif_dir.td_photometric = PHOTOMETRIC_MINISBLACK;
-		else {
-			MissingRequired(tif, "Colormap");
-			goto bad;
-		}
-	}
-	/*
-	 * OJPEG hack:
-	 * We do no further messing with strip/tile offsets/bytecounts in OJPEG
-	 * TIFFs
-	 */
-	if (tif->tif_dir.td_compression!=COMPRESSION_OJPEG)
-	{
-		/*
-		 * Attempt to deal with a missing StripByteCounts tag.
-		 */
-		if (!TIFFFieldSet(tif, FIELD_STRIPBYTECOUNTS)) {
-			/*
-			 * Some manufacturers violate the spec by not giving
-			 * the size of the strips.  In this case, assume there
-			 * is one uncompressed strip of data.
-			 */
-			if ((tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG &&
-			    tif->tif_dir.td_nstrips > 1) ||
-			    (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE &&
-			     tif->tif_dir.td_nstrips != (uint32)tif->tif_dir.td_samplesperpixel)) {
-			    MissingRequired(tif, "StripByteCounts");
-			    goto bad;
-			}
-			TIFFWarningExt(tif->tif_clientdata, module,
-				"TIFF directory is missing required "
-				"\"StripByteCounts\" field, calculating from imagelength");
-			if (EstimateStripByteCounts(tif, dir, dircount) < 0)
-			    goto bad;
-		/*
-		 * Assume we have wrong StripByteCount value (in case
-		 * of single strip) in following cases:
-		 *   - it is equal to zero along with StripOffset;
-		 *   - it is larger than file itself (in case of uncompressed
-		 *     image);
-		 *   - it is smaller than the size of the bytes per row
-		 *     multiplied on the number of rows.  The last case should
-		 *     not be checked in the case of writing new image,
-		 *     because we may do not know the exact strip size
-		 *     until the whole image will be written and directory
-		 *     dumped out.
-		 */
-		#define	BYTECOUNTLOOKSBAD \
-		    ( (tif->tif_dir.td_stripbytecount[0] == 0 && tif->tif_dir.td_stripoffset[0] != 0) || \
-		      (tif->tif_dir.td_compression == COMPRESSION_NONE && \
-		       tif->tif_dir.td_stripbytecount[0] > TIFFGetFileSize(tif) - tif->tif_dir.td_stripoffset[0]) || \
-		      (tif->tif_mode == O_RDONLY && \
-		       tif->tif_dir.td_compression == COMPRESSION_NONE && \
-		       tif->tif_dir.td_stripbytecount[0] < TIFFScanlineSize64(tif) * tif->tif_dir.td_imagelength) )
-
-		} else if (tif->tif_dir.td_nstrips == 1
-                           && _TIFFFillStriles(tif)
-			   && tif->tif_dir.td_stripoffset[0] != 0
-			   && BYTECOUNTLOOKSBAD) {
-			/*
-			 * XXX: Plexus (and others) sometimes give a value of
-			 * zero for a tag when they don't know what the
-			 * correct value is!  Try and handle the simple case
-			 * of estimating the size of a one strip image.
-			 */
-			TIFFWarningExt(tif->tif_clientdata, module,
-			    "Bogus \"StripByteCounts\" field, ignoring and calculating from imagelength");
-			if(EstimateStripByteCounts(tif, dir, dircount) < 0)
-			    goto bad;
-
-#if !defined(DEFER_STRILE_LOAD)
-		} else if (tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG
-			   && tif->tif_dir.td_nstrips > 2
-			   && tif->tif_dir.td_compression == COMPRESSION_NONE
-			   && tif->tif_dir.td_stripbytecount[0] != tif->tif_dir.td_stripbytecount[1]
-			   && tif->tif_dir.td_stripbytecount[0] != 0
-			   && tif->tif_dir.td_stripbytecount[1] != 0 ) {
-			/*
-			 * XXX: Some vendors fill StripByteCount array with
-			 * absolutely wrong values (it can be equal to
-			 * StripOffset array, for example). Catch this case
-			 * here.
-                         *
-                         * We avoid this check if deferring strile loading
-                         * as it would always force us to load the strip/tile
-                         * information.
-			 */
-			TIFFWarningExt(tif->tif_clientdata, module,
-			    "Wrong \"StripByteCounts\" field, ignoring and calculating from imagelength");
-			if (EstimateStripByteCounts(tif, dir, dircount) < 0)
-			    goto bad;
-#endif /* !defined(DEFER_STRILE_LOAD) */                        
-		}
-	}
-	if (dir)
-	{
-		_TIFFfree(dir);
-		dir=NULL;
-	}
-	if (!TIFFFieldSet(tif, FIELD_MAXSAMPLEVALUE))
-	{
-		if (tif->tif_dir.td_bitspersample>=16)
-			tif->tif_dir.td_maxsamplevalue=0xFFFF;
-		else
-			tif->tif_dir.td_maxsamplevalue = (uint16)((1L<<tif->tif_dir.td_bitspersample)-1);
-	}
-	/*
-	 * XXX: We can optimize checking for the strip bounds using the sorted
-	 * bytecounts array. See also comments for TIFFAppendToStrip()
-	 * function in tif_write.c.
-	 */
-#if !defined(DEFER_STRILE_LOAD)        
-	if (tif->tif_dir.td_nstrips > 1) {
-		uint32 strip;
-
-		tif->tif_dir.td_stripbytecountsorted = 1;
-		for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++) {
-			if (tif->tif_dir.td_stripoffset[strip - 1] >
-			    tif->tif_dir.td_stripoffset[strip]) {
-				tif->tif_dir.td_stripbytecountsorted = 0;
-				break;
-			}
-		}
-	}
-#endif /* !defined(DEFER_STRILE_LOAD) */
-        
-	/*
-	 * An opportunity for compression mode dependent tag fixup
-	 */
-	(*tif->tif_fixuptags)(tif);
-
-	/*
-	 * Some manufacturers make life difficult by writing
-	 * large amounts of uncompressed data as a single strip.
-	 * This is contrary to the recommendations of the spec.
-	 * The following makes an attempt at breaking such images
-	 * into strips closer to the recommended 8k bytes.  A
-	 * side effect, however, is that the RowsPerStrip tag
-	 * value may be changed.
-	 */
-	if ((tif->tif_dir.td_planarconfig==PLANARCONFIG_CONTIG)&&
-	    (tif->tif_dir.td_nstrips==1)&&
-	    (tif->tif_dir.td_compression==COMPRESSION_NONE)&&  
-	    ((tif->tif_flags&(TIFF_STRIPCHOP|TIFF_ISTILED))==TIFF_STRIPCHOP))
-    {
-        if ( !_TIFFFillStriles(tif) || !tif->tif_dir.td_stripbytecount )
-            return 0;
-		ChopUpSingleUncompressedStrip(tif);
-    }
-
-        /*
-         * Clear the dirty directory flag. 
-         */
-	tif->tif_flags &= ~TIFF_DIRTYDIRECT;
-	tif->tif_flags &= ~TIFF_DIRTYSTRIP;
-
-	/*
-	 * Reinitialize i/o since we are starting on a new directory.
-	 */
-	tif->tif_row = (uint32) -1;
-	tif->tif_curstrip = (uint32) -1;
-	tif->tif_col = (uint32) -1;
-	tif->tif_curtile = (uint32) -1;
-	tif->tif_tilesize = (tmsize_t) -1;
-
-	tif->tif_scanlinesize = TIFFScanlineSize(tif);
-	if (!tif->tif_scanlinesize) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-		    "Cannot handle zero scanline size");
-		return (0);
-	}
-
-	if (isTiled(tif)) {
-		tif->tif_tilesize = TIFFTileSize(tif);
-		if (!tif->tif_tilesize) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-			     "Cannot handle zero tile size");
-			return (0);
-		}
-	} else {
-		if (!TIFFStripSize(tif)) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-			    "Cannot handle zero strip size");
-			return (0);
-		}
-	}
-	return (1);
-bad:
-	if (dir)
-		_TIFFfree(dir);
-	return (0);
-}
-
-static void
-TIFFReadDirectoryCheckOrder(TIFF* tif, TIFFDirEntry* dir, uint16 dircount)
-{
-	static const char module[] = "TIFFReadDirectoryCheckOrder";
-	uint16 m;
-	uint16 n;
-	TIFFDirEntry* o;
-	m=0;
-	for (n=0, o=dir; n<dircount; n++, o++)
-	{
-		if (o->tdir_tag<m)
-		{
-			TIFFWarningExt(tif->tif_clientdata,module,
-			    "Invalid TIFF directory; tags are not sorted in ascending order");
-			break;
-		}
-		m=o->tdir_tag+1;
-	}
-}
-
-static TIFFDirEntry*
-TIFFReadDirectoryFindEntry(TIFF* tif, TIFFDirEntry* dir, uint16 dircount, uint16 tagid)
-{
-	TIFFDirEntry* m;
-	uint16 n;
-	(void) tif;
-	for (m=dir, n=0; n<dircount; m++, n++)
-	{
-		if (m->tdir_tag==tagid)
-			return(m);
-	}
-	return(0);
-}
-
-static void
-TIFFReadDirectoryFindFieldInfo(TIFF* tif, uint16 tagid, uint32* fii)
-{
-	int32 ma,mb,mc;
-	ma=-1;
-	mc=(int32)tif->tif_nfields;
-	while (1)
-	{
-		if (ma+1==mc)
-		{
-			*fii = FAILED_FII;
-			return;
-		}
-		mb=(ma+mc)/2;
-		if (tif->tif_fields[mb]->field_tag==(uint32)tagid)
-			break;
-		if (tif->tif_fields[mb]->field_tag<(uint32)tagid)
-			ma=mb;
-		else
-			mc=mb;
-	}
-	while (1)
-	{
-		if (mb==0)
-			break;
-		if (tif->tif_fields[mb-1]->field_tag!=(uint32)tagid)
-			break;
-		mb--;
-	}
-	*fii=mb;
-}
-
-/*
- * Read custom directory from the arbitarry offset.
- * The code is very similar to TIFFReadDirectory().
- */
-int
-TIFFReadCustomDirectory(TIFF* tif, toff_t diroff,
-			const TIFFFieldArray* infoarray)
-{
-	static const char module[] = "TIFFReadCustomDirectory";
-	TIFFDirEntry* dir;
-	uint16 dircount;
-	TIFFDirEntry* dp;
-	uint16 di;
-	const TIFFField* fip;
-	uint32 fii;
-	_TIFFSetupFields(tif, infoarray);
-	dircount=TIFFFetchDirectory(tif,diroff,&dir,NULL);
-	if (!dircount)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,
-		    "Failed to read custom directory at offset " TIFF_UINT64_FORMAT,diroff);
-		return 0;
-	}
-	TIFFFreeDirectory(tif);
-	_TIFFmemset(&tif->tif_dir, 0, sizeof(TIFFDirectory));
-	TIFFReadDirectoryCheckOrder(tif,dir,dircount);
-	for (di=0, dp=dir; di<dircount; di++, dp++)
-	{
-		TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii);
-		if (fii == FAILED_FII)
-		{
-			TIFFWarningExt(tif->tif_clientdata, module,
-			    "Unknown field with tag %d (0x%x) encountered",
-			    dp->tdir_tag, dp->tdir_tag);
-			if (!_TIFFMergeFields(tif, _TIFFCreateAnonField(tif,
-						dp->tdir_tag,
-						(TIFFDataType) dp->tdir_type),
-					     1)) {
-				TIFFWarningExt(tif->tif_clientdata, module,
-				    "Registering anonymous field with tag %d (0x%x) failed",
-				    dp->tdir_tag, dp->tdir_tag);
-				dp->tdir_tag=IGNORE;
-			} else {
-				TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii);
-				assert( fii != FAILED_FII );
-			}
-		}
-		if (dp->tdir_tag!=IGNORE)
-		{
-			fip=tif->tif_fields[fii];
-			if (fip->field_bit==FIELD_IGNORE)
-				dp->tdir_tag=IGNORE;
-			else
-			{
-				/* check data type */
-				while ((fip->field_type!=TIFF_ANY)&&(fip->field_type!=dp->tdir_type))
-				{
-					fii++;
-					if ((fii==tif->tif_nfields)||
-					    (tif->tif_fields[fii]->field_tag!=(uint32)dp->tdir_tag))
-					{
-						fii=0xFFFF;
-						break;
-					}
-					fip=tif->tif_fields[fii];
-				}
-				if (fii==0xFFFF)
-				{
-					TIFFWarningExt(tif->tif_clientdata, module,
-					    "Wrong data type %d for \"%s\"; tag ignored",
-					    dp->tdir_type,fip->field_name);
-					dp->tdir_tag=IGNORE;
-				}
-				else
-				{
-					/* check count if known in advance */
-					if ((fip->field_readcount!=TIFF_VARIABLE)&&
-					    (fip->field_readcount!=TIFF_VARIABLE2))
-					{
-						uint32 expected;
-						if (fip->field_readcount==TIFF_SPP)
-							expected=(uint32)tif->tif_dir.td_samplesperpixel;
-						else
-							expected=(uint32)fip->field_readcount;
-						if (!CheckDirCount(tif,dp,expected))
-							dp->tdir_tag=IGNORE;
-					}
-				}
-			}
-			switch (dp->tdir_tag)
-			{
-				case IGNORE:
-					break;
-				case EXIFTAG_SUBJECTDISTANCE:
-					(void) TIFFFetchSubjectDistance(tif,dp);
-					break;
-				default:
-					(void) TIFFFetchNormalTag(tif, dp, TRUE);
-					break;
-			}
-		}
-	}
-	if (dir)
-		_TIFFfree(dir);
-	return 1;
-}
-
-/*
- * EXIF is important special case of custom IFD, so we have a special
- * function to read it.
- */
-int
-TIFFReadEXIFDirectory(TIFF* tif, toff_t diroff)
-{
-	const TIFFFieldArray* exifFieldArray;
-	exifFieldArray = _TIFFGetExifFields();
-	return TIFFReadCustomDirectory(tif, diroff, exifFieldArray);  
-}
-
-static int
-EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount)
-{
-	static const char module[] = "EstimateStripByteCounts";
-
-	TIFFDirEntry *dp;
-	TIFFDirectory *td = &tif->tif_dir;
-	uint32 strip;
-
-    _TIFFFillStriles( tif );
-
-	if (td->td_stripbytecount)
-		_TIFFfree(td->td_stripbytecount);
-	td->td_stripbytecount = (uint64*)
-	    _TIFFCheckMalloc(tif, td->td_nstrips, sizeof (uint64),
-		"for \"StripByteCounts\" array");
-        if( td->td_stripbytecount == NULL )
-            return -1;
-
-	if (td->td_compression != COMPRESSION_NONE) {
-		uint64 space;
-		uint64 filesize;
-		uint16 n;
-		filesize = TIFFGetFileSize(tif);
-		if (!(tif->tif_flags&TIFF_BIGTIFF))
-			space=sizeof(TIFFHeaderClassic)+2+dircount*12+4;
-		else
-			space=sizeof(TIFFHeaderBig)+8+dircount*20+8;
-		/* calculate amount of space used by indirect values */
-		for (dp = dir, n = dircount; n > 0; n--, dp++)
-		{
-			uint32 typewidth = TIFFDataWidth((TIFFDataType) dp->tdir_type);
-			uint64 datasize;
-			typewidth = TIFFDataWidth((TIFFDataType) dp->tdir_type);
-			if (typewidth == 0) {
-				TIFFErrorExt(tif->tif_clientdata, module,
-				    "Cannot determine size of unknown tag type %d",
-				    dp->tdir_type);
-				return -1;
-			}
-			datasize=(uint64)typewidth*dp->tdir_count;
-			if (!(tif->tif_flags&TIFF_BIGTIFF))
-			{
-				if (datasize<=4)
-					datasize=0;
-			}
-			else
-			{
-				if (datasize<=8)
-					datasize=0;
-			}
-			space+=datasize;
-		}
-		space = filesize - space;
-		if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
-			space /= td->td_samplesperpixel;
-		for (strip = 0; strip < td->td_nstrips; strip++)
-			td->td_stripbytecount[strip] = space;
-		/*
-		 * This gross hack handles the case were the offset to
-		 * the last strip is past the place where we think the strip
-		 * should begin.  Since a strip of data must be contiguous,
-		 * it's safe to assume that we've overestimated the amount
-		 * of data in the strip and trim this number back accordingly.
-		 */
-		strip--;
-		if (td->td_stripoffset[strip]+td->td_stripbytecount[strip] > filesize)
-			td->td_stripbytecount[strip] = filesize - td->td_stripoffset[strip];
-	} else if (isTiled(tif)) {
-		uint64 bytespertile = TIFFTileSize64(tif);
-
-		for (strip = 0; strip < td->td_nstrips; strip++)
-		    td->td_stripbytecount[strip] = bytespertile;
-	} else {
-		uint64 rowbytes = TIFFScanlineSize64(tif);
-		uint32 rowsperstrip = td->td_imagelength/td->td_stripsperimage;
-		for (strip = 0; strip < td->td_nstrips; strip++)
-			td->td_stripbytecount[strip] = rowbytes * rowsperstrip;
-	}
-	TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
-	if (!TIFFFieldSet(tif, FIELD_ROWSPERSTRIP))
-		td->td_rowsperstrip = td->td_imagelength;
-	return 1;
-}
-
-static void
-MissingRequired(TIFF* tif, const char* tagname)
-{
-	static const char module[] = "MissingRequired";
-
-	TIFFErrorExt(tif->tif_clientdata, module,
-	    "TIFF directory is missing required \"%s\" field",
-	    tagname);
-}
-
-/*
- * Check the directory offset against the list of already seen directory
- * offsets. This is a trick to prevent IFD looping. The one can create TIFF
- * file with looped directory pointers. We will maintain a list of already
- * seen directories and check every IFD offset against that list.
- */
-static int
-TIFFCheckDirOffset(TIFF* tif, uint64 diroff)
-{
-	uint16 n;
-
-	if (diroff == 0)			/* no more directories */
-		return 0;
-
-	for (n = 0; n < tif->tif_dirnumber && tif->tif_dirlist; n++) {
-		if (tif->tif_dirlist[n] == diroff)
-			return 0;
-	}
-
-	tif->tif_dirnumber++;
-
-	if (tif->tif_dirnumber > tif->tif_dirlistsize) {
-		uint64* new_dirlist;
-
-		/*
-		 * XXX: Reduce memory allocation granularity of the dirlist
-		 * array.
-		 */
-		new_dirlist = (uint64*)_TIFFCheckRealloc(tif, tif->tif_dirlist,
-		    tif->tif_dirnumber, 2 * sizeof(uint64), "for IFD list");
-		if (!new_dirlist)
-			return 0;
-		tif->tif_dirlistsize = 2 * tif->tif_dirnumber;
-		tif->tif_dirlist = new_dirlist;
-	}
-
-	tif->tif_dirlist[tif->tif_dirnumber - 1] = diroff;
-
-	return 1;
-}
-
-/*
- * Check the count field of a directory entry against a known value.  The
- * caller is expected to skip/ignore the tag if there is a mismatch.
- */
-static int
-CheckDirCount(TIFF* tif, TIFFDirEntry* dir, uint32 count)
-{
-	if ((uint64)count > dir->tdir_count) {
-		const TIFFField* fip = TIFFFieldWithTag(tif, dir->tdir_tag);
-		TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
-	"incorrect count for field \"%s\" (" TIFF_UINT64_FORMAT ", expecting %u); tag ignored",
-		    fip ? fip->field_name : "unknown tagname",
-		    dir->tdir_count, count);
-		return (0);
-	} else if ((uint64)count < dir->tdir_count) {
-		const TIFFField* fip = TIFFFieldWithTag(tif, dir->tdir_tag);
-		TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
-	"incorrect count for field \"%s\" (" TIFF_UINT64_FORMAT ", expecting %u); tag trimmed",
-		    fip ? fip->field_name : "unknown tagname",
-		    dir->tdir_count, count);
-		dir->tdir_count = count;
-		return (1);
-	}
-	return (1);
-}
-
-/*
- * Read IFD structure from the specified offset. If the pointer to
- * nextdiroff variable has been specified, read it too. Function returns a
- * number of fields in the directory or 0 if failed.
- */
-static uint16
-TIFFFetchDirectory(TIFF* tif, uint64 diroff, TIFFDirEntry** pdir,
-                   uint64 *nextdiroff)
-{
-	static const char module[] = "TIFFFetchDirectory";
-
-	void* origdir;
-	uint16 dircount16;
-	uint32 dirsize;
-	TIFFDirEntry* dir;
-	uint8* ma;
-	TIFFDirEntry* mb;
-	uint16 n;
-
-	assert(pdir);
-
-	tif->tif_diroff = diroff;
-	if (nextdiroff)
-		*nextdiroff = 0;
-	if (!isMapped(tif)) {
-		if (!SeekOK(tif, tif->tif_diroff)) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-				"%s: Seek error accessing TIFF directory",
-				tif->tif_name);
-			return 0;
-		}
-		if (!(tif->tif_flags&TIFF_BIGTIFF))
-		{
-			if (!ReadOK(tif, &dircount16, sizeof (uint16))) {
-				TIFFErrorExt(tif->tif_clientdata, module,
-				    "%s: Can not read TIFF directory count",
-				    tif->tif_name);
-				return 0;
-			}
-			if (tif->tif_flags & TIFF_SWAB)
-				TIFFSwabShort(&dircount16);
-			if (dircount16>4096)
-			{
-				TIFFErrorExt(tif->tif_clientdata, module,
-				    "Sanity check on directory count failed, this is probably not a valid IFD offset");
-				return 0;
-			}
-			dirsize = 12;
-		} else {
-			uint64 dircount64;
-			if (!ReadOK(tif, &dircount64, sizeof (uint64))) {
-				TIFFErrorExt(tif->tif_clientdata, module,
-					"%s: Can not read TIFF directory count",
-					tif->tif_name);
-				return 0;
-			}
-			if (tif->tif_flags & TIFF_SWAB)
-				TIFFSwabLong8(&dircount64);
-			if (dircount64>4096)
-			{
-				TIFFErrorExt(tif->tif_clientdata, module,
-				    "Sanity check on directory count failed, this is probably not a valid IFD offset");
-				return 0;
-			}
-			dircount16 = (uint16)dircount64;
-			dirsize = 20;
-		}
-		origdir = _TIFFCheckMalloc(tif, dircount16,
-		    dirsize, "to read TIFF directory");
-		if (origdir == NULL)
-			return 0;
-		if (!ReadOK(tif, origdir, (tmsize_t)(dircount16*dirsize))) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-				"%.100s: Can not read TIFF directory",
-				tif->tif_name);
-			_TIFFfree(origdir);
-			return 0;
-		}
-		/*
-		 * Read offset to next directory for sequential scans if
-		 * needed.
-		 */
-		if (nextdiroff)
-		{
-			if (!(tif->tif_flags&TIFF_BIGTIFF))
-			{
-				uint32 nextdiroff32;
-				if (!ReadOK(tif, &nextdiroff32, sizeof(uint32)))
-					nextdiroff32 = 0;
-				if (tif->tif_flags&TIFF_SWAB)
-					TIFFSwabLong(&nextdiroff32);
-				*nextdiroff=nextdiroff32;
-			} else {
-				if (!ReadOK(tif, nextdiroff, sizeof(uint64)))
-					*nextdiroff = 0;
-				if (tif->tif_flags&TIFF_SWAB)
-					TIFFSwabLong8(nextdiroff);
-			}
-		}
-	} else {
-		tmsize_t m;
-		tmsize_t off = (tmsize_t) tif->tif_diroff;
-		if ((uint64)off!=tif->tif_diroff)
-		{
-			TIFFErrorExt(tif->tif_clientdata,module,"Can not read TIFF directory count");
-			return(0);
-		}
-
-		/*
-		 * Check for integer overflow when validating the dir_off,
-		 * otherwise a very high offset may cause an OOB read and
-		 * crash the client. Make two comparisons instead of
-		 *
-		 *  off + sizeof(uint16) > tif->tif_size
-		 *
-		 * to avoid overflow.
-		 */
-		if (!(tif->tif_flags&TIFF_BIGTIFF))
-		{
-			m=off+sizeof(uint16);
-			if ((m<off)||(m<(tmsize_t)sizeof(uint16))||(m>tif->tif_size)) {
-				TIFFErrorExt(tif->tif_clientdata, module,
-					"Can not read TIFF directory count");
-				return 0;
-			} else {
-				_TIFFmemcpy(&dircount16, tif->tif_base + off,
-					    sizeof(uint16));
-			}
-			off += sizeof (uint16);
-			if (tif->tif_flags & TIFF_SWAB)
-				TIFFSwabShort(&dircount16);
-			if (dircount16>4096)
-			{
-				TIFFErrorExt(tif->tif_clientdata, module,
-				    "Sanity check on directory count failed, this is probably not a valid IFD offset");
-				return 0;
-			}
-			dirsize = 12;
-		}
-		else
-		{
-			tmsize_t m;
-			uint64 dircount64;
-			m=off+sizeof(uint64);
-			if ((m<off)||(m<(tmsize_t)sizeof(uint64))||(m>tif->tif_size)) {
-				TIFFErrorExt(tif->tif_clientdata, module,
-					"Can not read TIFF directory count");
-				return 0;
-			} else {
-				_TIFFmemcpy(&dircount64, tif->tif_base + off,
-					    sizeof(uint64));
-			}
-			off += sizeof (uint64);
-			if (tif->tif_flags & TIFF_SWAB)
-				TIFFSwabLong8(&dircount64);
-			if (dircount64>4096)
-			{
-				TIFFErrorExt(tif->tif_clientdata, module,
-				    "Sanity check on directory count failed, this is probably not a valid IFD offset");
-				return 0;
-			}
-			dircount16 = (uint16)dircount64;
-			dirsize = 20;
-		}
-		if (dircount16 == 0 )
-		{
-			TIFFErrorExt(tif->tif_clientdata, module,
-			             "Sanity check on directory count failed, zero tag directories not supported");
-			return 0;
-		}
-		origdir = _TIFFCheckMalloc(tif, dircount16,
-						dirsize,
-						"to read TIFF directory");
-		if (origdir == NULL)
-			return 0;
-		m=off+dircount16*dirsize;
-		if ((m<off)||(m<(tmsize_t)(dircount16*dirsize))||(m>tif->tif_size)) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-				     "Can not read TIFF directory");
-			_TIFFfree(origdir);
-			return 0;
-		} else {
-			_TIFFmemcpy(origdir, tif->tif_base + off,
-				    dircount16 * dirsize);
-		}
-		if (nextdiroff) {
-			off += dircount16 * dirsize;
-			if (!(tif->tif_flags&TIFF_BIGTIFF))
-			{
-				uint32 nextdiroff32;
-				m=off+sizeof(uint32);
-				if ((m<off)||(m<(tmsize_t)sizeof(uint32))||(m>tif->tif_size))
-					nextdiroff32 = 0;
-				else
-					_TIFFmemcpy(&nextdiroff32, tif->tif_base + off,
-						    sizeof (uint32));
-				if (tif->tif_flags&TIFF_SWAB)
-					TIFFSwabLong(&nextdiroff32);
-				*nextdiroff = nextdiroff32;
-			}
-			else
-			{
-				m=off+sizeof(uint64);
-				if ((m<off)||(m<(tmsize_t)sizeof(uint64))||(m>tif->tif_size))
-					*nextdiroff = 0;
-				else
-					_TIFFmemcpy(nextdiroff, tif->tif_base + off,
-						    sizeof (uint64));
-				if (tif->tif_flags&TIFF_SWAB)
-					TIFFSwabLong8(nextdiroff);
-			}
-		}
-	}
-	dir = (TIFFDirEntry*)_TIFFCheckMalloc(tif, dircount16,
-						sizeof(TIFFDirEntry),
-						"to read TIFF directory");
-	if (dir==0)
-	{
-		_TIFFfree(origdir);
-		return 0;
-	}
-	ma=(uint8*)origdir;
-	mb=dir;
-	for (n=0; n<dircount16; n++)
-	{
-		if (tif->tif_flags&TIFF_SWAB)
-			TIFFSwabShort((uint16*)ma);
-		mb->tdir_tag=*(uint16*)ma;
-		ma+=sizeof(uint16);
-		if (tif->tif_flags&TIFF_SWAB)
-			TIFFSwabShort((uint16*)ma);
-		mb->tdir_type=*(uint16*)ma;
-		ma+=sizeof(uint16);
-		if (!(tif->tif_flags&TIFF_BIGTIFF))
-		{
-			if (tif->tif_flags&TIFF_SWAB)
-				TIFFSwabLong((uint32*)ma);
-			mb->tdir_count=(uint64)(*(uint32*)ma);
-			ma+=sizeof(uint32);
-			*(uint32*)(&mb->tdir_offset)=*(uint32*)ma;
-			ma+=sizeof(uint32);
-		}
-		else
-		{
-			if (tif->tif_flags&TIFF_SWAB)
-				TIFFSwabLong8((uint64*)ma);
-                        mb->tdir_count=TIFFReadUInt64(ma);
-			ma+=sizeof(uint64);
-			mb->tdir_offset.toff_long8=TIFFReadUInt64(ma);
-			ma+=sizeof(uint64);
-		}
-		mb++;
-	}
-	_TIFFfree(origdir);
-	*pdir = dir;
-	return dircount16;
-}
-
-/*
- * Fetch a tag that is not handled by special case code.
- */
-static int
-TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover)
-{
-	static const char module[] = "TIFFFetchNormalTag";
-	enum TIFFReadDirEntryErr err;
-	uint32 fii;
-	const TIFFField* fip = NULL;
-	TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii);
-        if( fii == FAILED_FII )
-        {
-            TIFFErrorExt(tif->tif_clientdata, "TIFFFetchNormalTag",
-                         "No definition found for tag %d",
-                         dp->tdir_tag);
-            return 0;
-        }
-	fip=tif->tif_fields[fii];
-	assert(fip->set_field_type!=TIFF_SETGET_OTHER);  /* if so, we shouldn't arrive here but deal with this in specialized code */
-	assert(fip->set_field_type!=TIFF_SETGET_INT);    /* if so, we shouldn't arrive here as this is only the case for pseudo-tags */
-	err=TIFFReadDirEntryErrOk;
-	switch (fip->set_field_type)
-	{
-		case TIFF_SETGET_UNDEFINED:
-			break;
-		case TIFF_SETGET_ASCII:
-			{
-				uint8* data;
-				assert(fip->field_passcount==0);
-				err=TIFFReadDirEntryByteArray(tif,dp,&data);
-				if (err==TIFFReadDirEntryErrOk)
-				{
-					uint8* ma;
-					uint32 mb;
-					int n;
-					ma=data;
-					mb=0;
-					while (mb<(uint32)dp->tdir_count)
-					{
-						if (*ma==0)
-							break;
-						ma++;
-						mb++;
-					}
-					if (mb+1<(uint32)dp->tdir_count)
-						TIFFWarningExt(tif->tif_clientdata,module,"ASCII value for tag \"%s\" contains null byte in value; value incorrectly truncated during reading due to implementation limitations",fip->field_name);
-					else if (mb+1>(uint32)dp->tdir_count)
-					{
-						uint8* o;
-						TIFFWarningExt(tif->tif_clientdata,module,"ASCII value for tag \"%s\" does not end in null byte",fip->field_name);
-						if ((uint32)dp->tdir_count+1!=dp->tdir_count+1)
-							o=NULL;
-						else
-							o=_TIFFmalloc((uint32)dp->tdir_count+1);
-						if (o==NULL)
-						{
-							if (data!=NULL)
-								_TIFFfree(data);
-							return(0);
-						}
-						_TIFFmemcpy(o,data,(uint32)dp->tdir_count);
-						o[(uint32)dp->tdir_count]=0;
-						if (data!=0)
-							_TIFFfree(data);
-						data=o;
-					}
-					n=TIFFSetField(tif,dp->tdir_tag,data);
-					if (data!=0)
-						_TIFFfree(data);
-					if (!n)
-						return(0);
-				}
-			}
-			break;
-		case TIFF_SETGET_UINT8:
-			{
-				uint8 data=0;
-				assert(fip->field_readcount==1);
-				assert(fip->field_passcount==0);
-				err=TIFFReadDirEntryByte(tif,dp,&data);
-				if (err==TIFFReadDirEntryErrOk)
-				{
-					if (!TIFFSetField(tif,dp->tdir_tag,data))
-						return(0);
-				}
-			}
-			break;
-		case TIFF_SETGET_UINT16:
-			{
-				uint16 data;
-				assert(fip->field_readcount==1);
-				assert(fip->field_passcount==0);
-				err=TIFFReadDirEntryShort(tif,dp,&data);
-				if (err==TIFFReadDirEntryErrOk)
-				{
-					if (!TIFFSetField(tif,dp->tdir_tag,data))
-						return(0);
-				}
-			}
-			break;
-		case TIFF_SETGET_UINT32:
-			{
-				uint32 data;
-				assert(fip->field_readcount==1);
-				assert(fip->field_passcount==0);
-				err=TIFFReadDirEntryLong(tif,dp,&data);
-				if (err==TIFFReadDirEntryErrOk)
-				{
-					if (!TIFFSetField(tif,dp->tdir_tag,data))
-						return(0);
-				}
-			}
-			break;
-		case TIFF_SETGET_UINT64:
-			{
-				uint64 data;
-				assert(fip->field_readcount==1);
-				assert(fip->field_passcount==0);
-				err=TIFFReadDirEntryLong8(tif,dp,&data);
-				if (err==TIFFReadDirEntryErrOk)
-				{
-					if (!TIFFSetField(tif,dp->tdir_tag,data))
-						return(0);
-				}
-			}
-			break;
-		case TIFF_SETGET_FLOAT:
-			{
-				float data;
-				assert(fip->field_readcount==1);
-				assert(fip->field_passcount==0);
-				err=TIFFReadDirEntryFloat(tif,dp,&data);
-				if (err==TIFFReadDirEntryErrOk)
-				{
-					if (!TIFFSetField(tif,dp->tdir_tag,data))
-						return(0);
-				}
-			}
-			break;
-		case TIFF_SETGET_DOUBLE:
-			{
-				double data;
-				assert(fip->field_readcount==1);
-				assert(fip->field_passcount==0);
-				err=TIFFReadDirEntryDouble(tif,dp,&data);
-				if (err==TIFFReadDirEntryErrOk)
-				{
-					if (!TIFFSetField(tif,dp->tdir_tag,data))
-						return(0);
-				}
-			}
-			break;
-		case TIFF_SETGET_IFD8:
-			{
-				uint64 data;
-				assert(fip->field_readcount==1);
-				assert(fip->field_passcount==0);
-				err=TIFFReadDirEntryIfd8(tif,dp,&data);
-				if (err==TIFFReadDirEntryErrOk)
-				{
-					if (!TIFFSetField(tif,dp->tdir_tag,data))
-						return(0);
-				}
-			}
-			break;
-		case TIFF_SETGET_UINT16_PAIR:
-			{
-				uint16* data;
-				assert(fip->field_readcount==2);
-				assert(fip->field_passcount==0);
-				if (dp->tdir_count!=2) {
-					TIFFWarningExt(tif->tif_clientdata,module,
-						       "incorrect count for field \"%s\", expected 2, got %d",
-						       fip->field_name,(int)dp->tdir_count);
-					return(0);
-				}
-				err=TIFFReadDirEntryShortArray(tif,dp,&data);
-				if (err==TIFFReadDirEntryErrOk)
-				{
-					int m;
-					m=TIFFSetField(tif,dp->tdir_tag,data[0],data[1]);
-					_TIFFfree(data);
-					if (!m)
-						return(0);
-				}
-			}
-			break;
-		case TIFF_SETGET_C0_UINT8:
-			{
-				uint8* data;
-				assert(fip->field_readcount>=1);
-				assert(fip->field_passcount==0);
-				if (dp->tdir_count!=(uint64)fip->field_readcount) {
-					TIFFWarningExt(tif->tif_clientdata,module,
-						       "incorrect count for field \"%s\", expected %d, got %d",
-						       fip->field_name,(int) fip->field_readcount, (int)dp->tdir_count);
-					return 0;
-				}
-				else
-				{
-					err=TIFFReadDirEntryByteArray(tif,dp,&data);
-					if (err==TIFFReadDirEntryErrOk)
-					{
-						int m;
-						m=TIFFSetField(tif,dp->tdir_tag,data);
-						if (data!=0)
-							_TIFFfree(data);
-						if (!m)
-							return(0);
-					}
-				}
-			}
-			break;
-		case TIFF_SETGET_C0_UINT16:
-			{
-				uint16* data;
-				assert(fip->field_readcount>=1);
-				assert(fip->field_passcount==0);
-				if (dp->tdir_count!=(uint64)fip->field_readcount)
-                                    /* corrupt file */;
-				else
-				{
-					err=TIFFReadDirEntryShortArray(tif,dp,&data);
-					if (err==TIFFReadDirEntryErrOk)
-					{
-						int m;
-						m=TIFFSetField(tif,dp->tdir_tag,data);
-						if (data!=0)
-							_TIFFfree(data);
-						if (!m)
-							return(0);
-					}
-				}
-			}
-			break;
-		case TIFF_SETGET_C0_UINT32:
-			{
-				uint32* data;
-				assert(fip->field_readcount>=1);
-				assert(fip->field_passcount==0);
-				if (dp->tdir_count!=(uint64)fip->field_readcount)
-                                    /* corrupt file */;
-				else
-				{
-					err=TIFFReadDirEntryLongArray(tif,dp,&data);
-					if (err==TIFFReadDirEntryErrOk)
-					{
-						int m;
-						m=TIFFSetField(tif,dp->tdir_tag,data);
-						if (data!=0)
-							_TIFFfree(data);
-						if (!m)
-							return(0);
-					}
-				}
-			}
-			break;
-		case TIFF_SETGET_C0_FLOAT:
-			{
-				float* data;
-				assert(fip->field_readcount>=1);
-				assert(fip->field_passcount==0);
-				if (dp->tdir_count!=(uint64)fip->field_readcount)
-                                    /* corrupt file */;
-				else
-				{
-					err=TIFFReadDirEntryFloatArray(tif,dp,&data);
-					if (err==TIFFReadDirEntryErrOk)
-					{
-						int m;
-						m=TIFFSetField(tif,dp->tdir_tag,data);
-						if (data!=0)
-							_TIFFfree(data);
-						if (!m)
-							return(0);
-					}
-				}
-			}
-			break;
-		case TIFF_SETGET_C16_ASCII:
-			{
-				uint8* data;
-				assert(fip->field_readcount==TIFF_VARIABLE);
-				assert(fip->field_passcount==1);
-				if (dp->tdir_count>0xFFFF)
-					err=TIFFReadDirEntryErrCount;
-				else
-				{
-					err=TIFFReadDirEntryByteArray(tif,dp,&data);
-					if (err==TIFFReadDirEntryErrOk)
-					{
-						int m;
-						m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data);
-						if (data!=0)
-							_TIFFfree(data);
-						if (!m)
-							return(0);
-					}
-				}
-			}
-			break;
-		case TIFF_SETGET_C16_UINT8:
-			{
-				uint8* data;
-				assert(fip->field_readcount==TIFF_VARIABLE);
-				assert(fip->field_passcount==1);
-				if (dp->tdir_count>0xFFFF)
-					err=TIFFReadDirEntryErrCount;
-				else
-				{
-					err=TIFFReadDirEntryByteArray(tif,dp,&data);
-					if (err==TIFFReadDirEntryErrOk)
-					{
-						int m;
-						m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data);
-						if (data!=0)
-							_TIFFfree(data);
-						if (!m)
-							return(0);
-					}
-				}
-			}
-			break;
-		case TIFF_SETGET_C16_UINT16:
-			{
-				uint16* data;
-				assert(fip->field_readcount==TIFF_VARIABLE);
-				assert(fip->field_passcount==1);
-				if (dp->tdir_count>0xFFFF)
-					err=TIFFReadDirEntryErrCount;
-				else
-				{
-					err=TIFFReadDirEntryShortArray(tif,dp,&data);
-					if (err==TIFFReadDirEntryErrOk)
-					{
-						int m;
-						m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data);
-						if (data!=0)
-							_TIFFfree(data);
-						if (!m)
-							return(0);
-					}
-				}
-			}
-			break;
-		case TIFF_SETGET_C16_UINT32:
-			{
-				uint32* data;
-				assert(fip->field_readcount==TIFF_VARIABLE);
-				assert(fip->field_passcount==1);
-				if (dp->tdir_count>0xFFFF)
-					err=TIFFReadDirEntryErrCount;
-				else
-				{
-					err=TIFFReadDirEntryLongArray(tif,dp,&data);
-					if (err==TIFFReadDirEntryErrOk)
-					{
-						int m;
-						m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data);
-						if (data!=0)
-							_TIFFfree(data);
-						if (!m)
-							return(0);
-					}
-				}
-			}
-			break;
-		case TIFF_SETGET_C16_UINT64:
-			{
-				uint64* data;
-				assert(fip->field_readcount==TIFF_VARIABLE);
-				assert(fip->field_passcount==1);
-				if (dp->tdir_count>0xFFFF)
-					err=TIFFReadDirEntryErrCount;
-				else
-				{
-					err=TIFFReadDirEntryLong8Array(tif,dp,&data);
-					if (err==TIFFReadDirEntryErrOk)
-					{
-						int m;
-						m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data);
-						if (data!=0)
-							_TIFFfree(data);
-						if (!m)
-							return(0);
-					}
-				}
-			}
-			break;
-		case TIFF_SETGET_C16_FLOAT:
-			{
-				float* data;
-				assert(fip->field_readcount==TIFF_VARIABLE);
-				assert(fip->field_passcount==1);
-				if (dp->tdir_count>0xFFFF)
-					err=TIFFReadDirEntryErrCount;
-				else
-				{
-					err=TIFFReadDirEntryFloatArray(tif,dp,&data);
-					if (err==TIFFReadDirEntryErrOk)
-					{
-						int m;
-						m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data);
-						if (data!=0)
-							_TIFFfree(data);
-						if (!m)
-							return(0);
-					}
-				}
-			}
-			break;
-		case TIFF_SETGET_C16_DOUBLE:
-			{
-				double* data;
-				assert(fip->field_readcount==TIFF_VARIABLE);
-				assert(fip->field_passcount==1);
-				if (dp->tdir_count>0xFFFF)
-					err=TIFFReadDirEntryErrCount;
-				else
-				{
-					err=TIFFReadDirEntryDoubleArray(tif,dp,&data);
-					if (err==TIFFReadDirEntryErrOk)
-					{
-						int m;
-						m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data);
-						if (data!=0)
-							_TIFFfree(data);
-						if (!m)
-							return(0);
-					}
-				}
-			}
-			break;
-		case TIFF_SETGET_C16_IFD8:
-			{
-				uint64* data;
-				assert(fip->field_readcount==TIFF_VARIABLE);
-				assert(fip->field_passcount==1);
-				if (dp->tdir_count>0xFFFF)
-					err=TIFFReadDirEntryErrCount;
-				else
-				{
-					err=TIFFReadDirEntryIfd8Array(tif,dp,&data);
-					if (err==TIFFReadDirEntryErrOk)
-					{
-						int m;
-						m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data);
-						if (data!=0)
-							_TIFFfree(data);
-						if (!m)
-							return(0);
-					}
-				}
-			}
-			break;
-		case TIFF_SETGET_C32_ASCII:
-			{
-				uint8* data;
-				assert(fip->field_readcount==TIFF_VARIABLE2);
-				assert(fip->field_passcount==1);
-				err=TIFFReadDirEntryByteArray(tif,dp,&data);
-				if (err==TIFFReadDirEntryErrOk)
-				{
-					int m;
-					m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
-					if (data!=0)
-						_TIFFfree(data);
-					if (!m)
-						return(0);
-				}
-			}
-			break;
-		case TIFF_SETGET_C32_UINT8:
-			{
-				uint8* data;
-				assert(fip->field_readcount==TIFF_VARIABLE2);
-				assert(fip->field_passcount==1);
-				err=TIFFReadDirEntryByteArray(tif,dp,&data);
-				if (err==TIFFReadDirEntryErrOk)
-				{
-					int m;
-					m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
-					if (data!=0)
-						_TIFFfree(data);
-					if (!m)
-						return(0);
-				}
-			}
-			break;
-		case TIFF_SETGET_C32_SINT8:
-			{
-				int8* data = NULL;
-				assert(fip->field_readcount==TIFF_VARIABLE2);
-				assert(fip->field_passcount==1);
-				err=TIFFReadDirEntrySbyteArray(tif,dp,&data);
-				if (err==TIFFReadDirEntryErrOk)
-				{
-					int m;
-					m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
-					if (data!=0)
-						_TIFFfree(data);
-					if (!m)
-						return(0);
-				}
-			}
-			break;
-		case TIFF_SETGET_C32_UINT16:
-			{
-				uint16* data;
-				assert(fip->field_readcount==TIFF_VARIABLE2);
-				assert(fip->field_passcount==1);
-				err=TIFFReadDirEntryShortArray(tif,dp,&data);
-				if (err==TIFFReadDirEntryErrOk)
-				{
-					int m;
-					m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
-					if (data!=0)
-						_TIFFfree(data);
-					if (!m)
-						return(0);
-				}
-			}
-			break;
-		case TIFF_SETGET_C32_SINT16:
-			{
-				int16* data = NULL;
-				assert(fip->field_readcount==TIFF_VARIABLE2);
-				assert(fip->field_passcount==1);
-				err=TIFFReadDirEntrySshortArray(tif,dp,&data);
-				if (err==TIFFReadDirEntryErrOk)
-				{
-					int m;
-					m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
-					if (data!=0)
-						_TIFFfree(data);
-					if (!m)
-						return(0);
-				}
-			}
-			break;
-		case TIFF_SETGET_C32_UINT32:
-			{
-				uint32* data;
-				assert(fip->field_readcount==TIFF_VARIABLE2);
-				assert(fip->field_passcount==1);
-				err=TIFFReadDirEntryLongArray(tif,dp,&data);
-				if (err==TIFFReadDirEntryErrOk)
-				{
-					int m;
-					m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
-					if (data!=0)
-						_TIFFfree(data);
-					if (!m)
-						return(0);
-				}
-			}
-			break;
-		case TIFF_SETGET_C32_SINT32:
-			{
-				int32* data = NULL;
-				assert(fip->field_readcount==TIFF_VARIABLE2);
-				assert(fip->field_passcount==1);
-				err=TIFFReadDirEntrySlongArray(tif,dp,&data);
-				if (err==TIFFReadDirEntryErrOk)
-				{
-					int m;
-					m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
-					if (data!=0)
-						_TIFFfree(data);
-					if (!m)
-						return(0);
-				}
-			}
-			break;
-		case TIFF_SETGET_C32_UINT64:
-			{
-				uint64* data;
-				assert(fip->field_readcount==TIFF_VARIABLE2);
-				assert(fip->field_passcount==1);
-				err=TIFFReadDirEntryLong8Array(tif,dp,&data);
-				if (err==TIFFReadDirEntryErrOk)
-				{
-					int m;
-					m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
-					if (data!=0)
-						_TIFFfree(data);
-					if (!m)
-						return(0);
-				}
-			}
-			break;
-		case TIFF_SETGET_C32_SINT64:
-			{
-				int64* data = NULL;
-				assert(fip->field_readcount==TIFF_VARIABLE2);
-				assert(fip->field_passcount==1);
-				err=TIFFReadDirEntrySlong8Array(tif,dp,&data);
-				if (err==TIFFReadDirEntryErrOk)
-				{
-					int m;
-					m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
-					if (data!=0)
-						_TIFFfree(data);
-					if (!m)
-						return(0);
-				}
-			}
-			break;
-		case TIFF_SETGET_C32_FLOAT:
-			{
-				float* data;
-				assert(fip->field_readcount==TIFF_VARIABLE2);
-				assert(fip->field_passcount==1);
-				err=TIFFReadDirEntryFloatArray(tif,dp,&data);
-				if (err==TIFFReadDirEntryErrOk)
-				{
-					int m;
-					m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
-					if (data!=0)
-						_TIFFfree(data);
-					if (!m)
-						return(0);
-				}
-			}
-			break;
-		case TIFF_SETGET_C32_DOUBLE:
-			{
-				double* data;
-				assert(fip->field_readcount==TIFF_VARIABLE2);
-				assert(fip->field_passcount==1);
-				err=TIFFReadDirEntryDoubleArray(tif,dp,&data);
-				if (err==TIFFReadDirEntryErrOk)
-				{
-					int m;
-					m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
-					if (data!=0)
-						_TIFFfree(data);
-					if (!m)
-						return(0);
-				}
-			}
-			break;
-		case TIFF_SETGET_C32_IFD8:
-			{
-				uint64* data;
-				assert(fip->field_readcount==TIFF_VARIABLE2);
-				assert(fip->field_passcount==1);
-				err=TIFFReadDirEntryIfd8Array(tif,dp,&data);
-				if (err==TIFFReadDirEntryErrOk)
-				{
-					int m;
-					m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
-					if (data!=0)
-						_TIFFfree(data);
-					if (!m)
-						return(0);
-				}
-			}
-			break;
-		default:
-			assert(0);    /* we should never get here */
-			break;
-	}
-	if (err!=TIFFReadDirEntryErrOk)
-	{
-		TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",recover);
-		return(0);
-	}
-	return(1);
-}
-
-/*
- * Fetch a set of offsets or lengths.
- * While this routine says "strips", in fact it's also used for tiles.
- */
-static int
-TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, uint32 nstrips, uint64** lpp)
-{
-	static const char module[] = "TIFFFetchStripThing";
-	enum TIFFReadDirEntryErr err;
-	uint64* data;
-	err=TIFFReadDirEntryLong8Array(tif,dir,&data);
-	if (err!=TIFFReadDirEntryErrOk)
-	{
-		const TIFFField* fip = TIFFFieldWithTag(tif,dir->tdir_tag); 
-		TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",0);
-		return(0);
-	}
-	if (dir->tdir_count!=(uint64)nstrips)
-	{
-		uint64* resizeddata;
-		resizeddata=(uint64*)_TIFFCheckMalloc(tif,nstrips,sizeof(uint64),"for strip array");
-		if (resizeddata==0) {
-			_TIFFfree(data);
-			return(0);
-		}
-		if (dir->tdir_count<(uint64)nstrips)
-		{
-			_TIFFmemcpy(resizeddata,data,(uint32)dir->tdir_count*sizeof(uint64));
-			_TIFFmemset(resizeddata+(uint32)dir->tdir_count,0,(nstrips-(uint32)dir->tdir_count)*sizeof(uint64));
-		}
-		else
-			_TIFFmemcpy(resizeddata,data,nstrips*sizeof(uint64));
-		_TIFFfree(data);
-		data=resizeddata;
-	}
-	*lpp=data;
-	return(1);
-}
-
-/*
- * Fetch and set the SubjectDistance EXIF tag.
- */
-static int
-TIFFFetchSubjectDistance(TIFF* tif, TIFFDirEntry* dir)
-{
-	static const char module[] = "TIFFFetchSubjectDistance";
-	enum TIFFReadDirEntryErr err;
-	UInt64Aligned_t m;
-    m.l=0;
-	assert(sizeof(double)==8);
-	assert(sizeof(uint64)==8);
-	assert(sizeof(uint32)==4);
-	if (dir->tdir_count!=1)
-		err=TIFFReadDirEntryErrCount;
-	else if (dir->tdir_type!=TIFF_RATIONAL)
-		err=TIFFReadDirEntryErrType;
-	else
-	{
-		if (!(tif->tif_flags&TIFF_BIGTIFF))
-		{
-			uint32 offset;
-			offset=*(uint32*)(&dir->tdir_offset);
-			if (tif->tif_flags&TIFF_SWAB)
-				TIFFSwabLong(&offset);
-			err=TIFFReadDirEntryData(tif,offset,8,m.i);
-		}
-		else
-		{
-			m.l=dir->tdir_offset.toff_long8;
-			err=TIFFReadDirEntryErrOk;
-		}
-	}
-	if (err==TIFFReadDirEntryErrOk)
-	{
-		double n;
-		if (tif->tif_flags&TIFF_SWAB)
-			TIFFSwabArrayOfLong(m.i,2);
-		if (m.i[0]==0)
-			n=0.0;
-		else if (m.i[0]==0xFFFFFFFF)
-			/*
-			 * XXX: Numerator 0xFFFFFFFF means that we have infinite
-			 * distance. Indicate that with a negative floating point
-			 * SubjectDistance value.
-			 */
-			n=-1.0;
-		else
-			n=(double)m.i[0]/(double)m.i[1];
-		return(TIFFSetField(tif,dir->tdir_tag,n));
-	}
-	else
-	{
-		TIFFReadDirEntryOutputErr(tif,err,module,"SubjectDistance",TRUE);
-		return(0);
-	}
-}
-
-/*
- * Replace a single strip (tile) of uncompressed data by multiple strips
- * (tiles), each approximately STRIP_SIZE_DEFAULT bytes. This is useful for
- * dealing with large images or for dealing with machines with a limited
- * amount memory.
- */
-static void
-ChopUpSingleUncompressedStrip(TIFF* tif)
-{
-	register TIFFDirectory *td = &tif->tif_dir;
-	uint64 bytecount;
-	uint64 offset;
-	uint32 rowblock;
-	uint64 rowblockbytes;
-	uint64 stripbytes;
-	uint32 strip;
-	uint64 nstrips64;
-	uint32 nstrips32;
-	uint32 rowsperstrip;
-	uint64* newcounts;
-	uint64* newoffsets;
-
-	bytecount = td->td_stripbytecount[0];
-	offset = td->td_stripoffset[0];
-	assert(td->td_planarconfig == PLANARCONFIG_CONTIG);
-	if ((td->td_photometric == PHOTOMETRIC_YCBCR)&&
-	    (!isUpSampled(tif)))
-		rowblock = td->td_ycbcrsubsampling[1];
-	else
-		rowblock = 1;
-	rowblockbytes = TIFFVTileSize64(tif, rowblock);
-	/*
-	 * Make the rows hold at least one scanline, but fill specified amount
-	 * of data if possible.
-	 */
-	if (rowblockbytes > STRIP_SIZE_DEFAULT) {
-		stripbytes = rowblockbytes;
-		rowsperstrip = rowblock;
-	} else if (rowblockbytes > 0 ) {
-		uint32 rowblocksperstrip;
-		rowblocksperstrip = (uint32) (STRIP_SIZE_DEFAULT / rowblockbytes);
-		rowsperstrip = rowblocksperstrip * rowblock;
-		stripbytes = rowblocksperstrip * rowblockbytes;
-	}
-	else
-	    return;
-
-	/*
-	 * never increase the number of strips in an image
-	 */
-	if (rowsperstrip >= td->td_rowsperstrip)
-		return;
-	nstrips64 = TIFFhowmany_64(bytecount, stripbytes);
-	if ((nstrips64==0)||(nstrips64>0xFFFFFFFF)) /* something is wonky, do nothing. */
-	    return;
-	nstrips32 = (uint32)nstrips64;
-
-	newcounts = (uint64*) _TIFFCheckMalloc(tif, nstrips32, sizeof (uint64),
-				"for chopped \"StripByteCounts\" array");
-	newoffsets = (uint64*) _TIFFCheckMalloc(tif, nstrips32, sizeof (uint64),
-				"for chopped \"StripOffsets\" array");
-	if (newcounts == NULL || newoffsets == NULL) {
-		/*
-		 * Unable to allocate new strip information, give up and use
-		 * the original one strip information.
-		 */
-		if (newcounts != NULL)
-			_TIFFfree(newcounts);
-		if (newoffsets != NULL)
-			_TIFFfree(newoffsets);
-		return;
-	}
-	/*
-	 * Fill the strip information arrays with new bytecounts and offsets
-	 * that reflect the broken-up format.
-	 */
-	for (strip = 0; strip < nstrips32; strip++) {
-		if (stripbytes > bytecount)
-			stripbytes = bytecount;
-		newcounts[strip] = stripbytes;
-		newoffsets[strip] = offset;
-		offset += stripbytes;
-		bytecount -= stripbytes;
-	}
-	/*
-	 * Replace old single strip info with multi-strip info.
-	 */
-	td->td_stripsperimage = td->td_nstrips = nstrips32;
-	TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
-
-	_TIFFfree(td->td_stripbytecount);
-	_TIFFfree(td->td_stripoffset);
-	td->td_stripbytecount = newcounts;
-	td->td_stripoffset = newoffsets;
-	td->td_stripbytecountsorted = 1;
-}
-
-int _TIFFFillStriles( TIFF *tif )
-{
-#if defined(DEFER_STRILE_LOAD)
-        register TIFFDirectory *td = &tif->tif_dir;
-        int return_value = 1;
-
-        if( td->td_stripoffset != NULL )
-                return 1;
-
-        if( td->td_stripoffset_entry.tdir_count == 0 )
-                return 0;
-
-        if (!TIFFFetchStripThing(tif,&(td->td_stripoffset_entry),
-                                 td->td_nstrips,&td->td_stripoffset))
-        {
-                return_value = 0;
-        }
-
-        if (!TIFFFetchStripThing(tif,&(td->td_stripbytecount_entry),
-                                 td->td_nstrips,&td->td_stripbytecount))
-        {
-                return_value = 0;
-        }
-
-        _TIFFmemset( &(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry));
-        _TIFFmemset( &(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry));
-
-	if (tif->tif_dir.td_nstrips > 1 && return_value == 1 ) {
-		uint32 strip;
-
-		tif->tif_dir.td_stripbytecountsorted = 1;
-		for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++) {
-			if (tif->tif_dir.td_stripoffset[strip - 1] >
-			    tif->tif_dir.td_stripoffset[strip]) {
-				tif->tif_dir.td_stripbytecountsorted = 0;
-				break;
-			}
-		}
-	}
-
-        return return_value;
-#else /* !defined(DEFER_STRILE_LOAD) */
-        (void) tif;
-        return 1;
-#endif 
-}
-
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Id: tif_dirread.c,v 1.11 2015/02/19 22:39:58 drolon Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Directory Read Support Routines.
+ */
+
+/* Suggested pending improvements:
+ * - add a field 'ignore' to the TIFFDirEntry structure, to flag status,
+ *   eliminating current use of the IGNORE value, and therefore eliminating
+ *   current irrational behaviour on tags with tag id code 0
+ * - add a field 'field_info' to the TIFFDirEntry structure, and set that with
+ *   the pointer to the appropriate TIFFField structure early on in
+ *   TIFFReadDirectory, so as to eliminate current possibly repetitive lookup.
+ */
+
+#include "tiffiop.h"
+
+#define IGNORE 0          /* tag placeholder used below */
+#define FAILED_FII    ((uint32) -1)
+
+#ifdef HAVE_IEEEFP
+# define TIFFCvtIEEEFloatToNative(tif, n, fp)
+# define TIFFCvtIEEEDoubleToNative(tif, n, dp)
+#else
+extern void TIFFCvtIEEEFloatToNative(TIFF*, uint32, float*);
+extern void TIFFCvtIEEEDoubleToNative(TIFF*, uint32, double*);
+#endif
+
+enum TIFFReadDirEntryErr {
+	TIFFReadDirEntryErrOk = 0,
+	TIFFReadDirEntryErrCount = 1,
+	TIFFReadDirEntryErrType = 2,
+	TIFFReadDirEntryErrIo = 3,
+	TIFFReadDirEntryErrRange = 4,
+	TIFFReadDirEntryErrPsdif = 5,
+	TIFFReadDirEntryErrSizesan = 6,
+	TIFFReadDirEntryErrAlloc = 7,
+};
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryByte(TIFF* tif, TIFFDirEntry* direntry, uint8* value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryLong(TIFF* tif, TIFFDirEntry* direntry, uint32* value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8(TIFF* tif, TIFFDirEntry* direntry, uint64* value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryFloat(TIFF* tif, TIFFDirEntry* direntry, float* value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryDouble(TIFF* tif, TIFFDirEntry* direntry, double* value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8(TIFF* tif, TIFFDirEntry* direntry, uint64* value);
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* direntry, uint32* count, uint32 desttypesize, void** value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryByteArray(TIFF* tif, TIFFDirEntry* direntry, uint8** value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntrySbyteArray(TIFF* tif, TIFFDirEntry* direntry, int8** value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryShortArray(TIFF* tif, TIFFDirEntry* direntry, uint16** value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntrySshortArray(TIFF* tif, TIFFDirEntry* direntry, int16** value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryLongArray(TIFF* tif, TIFFDirEntry* direntry, uint32** value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntrySlongArray(TIFF* tif, TIFFDirEntry* direntry, int32** value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8Array(TIFF* tif, TIFFDirEntry* direntry, uint64** value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntrySlong8Array(TIFF* tif, TIFFDirEntry* direntry, int64** value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryFloatArray(TIFF* tif, TIFFDirEntry* direntry, float** value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryDoubleArray(TIFF* tif, TIFFDirEntry* direntry, double** value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8Array(TIFF* tif, TIFFDirEntry* direntry, uint64** value);
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryPersampleShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value);
+#if 0
+static enum TIFFReadDirEntryErr TIFFReadDirEntryPersampleDouble(TIFF* tif, TIFFDirEntry* direntry, double* value);
+#endif
+
+static void TIFFReadDirEntryCheckedByte(TIFF* tif, TIFFDirEntry* direntry, uint8* value);
+static void TIFFReadDirEntryCheckedSbyte(TIFF* tif, TIFFDirEntry* direntry, int8* value);
+static void TIFFReadDirEntryCheckedShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value);
+static void TIFFReadDirEntryCheckedSshort(TIFF* tif, TIFFDirEntry* direntry, int16* value);
+static void TIFFReadDirEntryCheckedLong(TIFF* tif, TIFFDirEntry* direntry, uint32* value);
+static void TIFFReadDirEntryCheckedSlong(TIFF* tif, TIFFDirEntry* direntry, int32* value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedLong8(TIFF* tif, TIFFDirEntry* direntry, uint64* value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSlong8(TIFF* tif, TIFFDirEntry* direntry, int64* value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedRational(TIFF* tif, TIFFDirEntry* direntry, double* value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSrational(TIFF* tif, TIFFDirEntry* direntry, double* value);
+static void TIFFReadDirEntryCheckedFloat(TIFF* tif, TIFFDirEntry* direntry, float* value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedDouble(TIFF* tif, TIFFDirEntry* direntry, double* value);
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSbyte(int8 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteShort(uint16 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSshort(int16 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteLong(uint32 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSlong(int32 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteLong8(uint64 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSlong8(int64 value);
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteByte(uint8 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteShort(uint16 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSshort(int16 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteLong(uint32 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSlong(int32 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteLong8(uint64 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSlong8(int64 value);
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSbyte(int8 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSshort(int16 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortLong(uint32 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSlong(int32 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortLong8(uint64 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSlong8(int64 value);
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortShort(uint16 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortLong(uint32 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortSlong(int32 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortLong8(uint64 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortSlong8(int64 value);
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSbyte(int8 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSshort(int16 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSlong(int32 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongLong8(uint64 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSlong8(int64 value);
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlongLong(uint32 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlongLong8(uint64 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlongSlong8(int64 value);
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Sbyte(int8 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Sshort(int16 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Slong(int32 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Slong8(int64 value);
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlong8Long8(uint64 value);
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryData(TIFF* tif, uint64 offset, tmsize_t size, void* dest);
+static void TIFFReadDirEntryOutputErr(TIFF* tif, enum TIFFReadDirEntryErr err, const char* module, const char* tagname, int recover);
+
+static void TIFFReadDirectoryCheckOrder(TIFF* tif, TIFFDirEntry* dir, uint16 dircount);
+static TIFFDirEntry* TIFFReadDirectoryFindEntry(TIFF* tif, TIFFDirEntry* dir, uint16 dircount, uint16 tagid);
+static void TIFFReadDirectoryFindFieldInfo(TIFF* tif, uint16 tagid, uint32* fii);
+
+static int EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount);
+static void MissingRequired(TIFF*, const char*);
+static int TIFFCheckDirOffset(TIFF* tif, uint64 diroff);
+static int CheckDirCount(TIFF*, TIFFDirEntry*, uint32);
+static uint16 TIFFFetchDirectory(TIFF* tif, uint64 diroff, TIFFDirEntry** pdir, uint64* nextdiroff);
+static int TIFFFetchNormalTag(TIFF*, TIFFDirEntry*, int recover);
+static int TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, uint32 nstrips, uint64** lpp);
+static int TIFFFetchSubjectDistance(TIFF*, TIFFDirEntry*);
+static void ChopUpSingleUncompressedStrip(TIFF*);
+static uint64 TIFFReadUInt64(const uint8 *value);
+
+typedef union _UInt64Aligned_t
+{
+        double d;
+	uint64 l;
+	uint32 i[2];
+	uint16 s[4];
+	uint8  c[8];
+} UInt64Aligned_t;
+
+/*
+  Unaligned safe copy of a uint64 value from an octet array.
+*/
+static uint64 TIFFReadUInt64(const uint8 *value)
+{
+	UInt64Aligned_t result;
+
+	result.c[0]=value[0];
+	result.c[1]=value[1];
+	result.c[2]=value[2];
+	result.c[3]=value[3];
+	result.c[4]=value[4];
+	result.c[5]=value[5];
+	result.c[6]=value[6];
+	result.c[7]=value[7];
+
+	return result.l;
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryByte(TIFF* tif, TIFFDirEntry* direntry, uint8* value)
+{
+	enum TIFFReadDirEntryErr err;
+	if (direntry->tdir_count!=1)
+		return(TIFFReadDirEntryErrCount);
+	switch (direntry->tdir_type)
+	{
+		case TIFF_BYTE:
+			TIFFReadDirEntryCheckedByte(tif,direntry,value);
+			return(TIFFReadDirEntryErrOk);
+		case TIFF_SBYTE:
+			{
+				int8 m;
+				TIFFReadDirEntryCheckedSbyte(tif,direntry,&m);
+				err=TIFFReadDirEntryCheckRangeByteSbyte(m);
+				if (err!=TIFFReadDirEntryErrOk)
+					return(err);
+				*value=(uint8)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_SHORT:
+			{
+				uint16 m;
+				TIFFReadDirEntryCheckedShort(tif,direntry,&m);
+				err=TIFFReadDirEntryCheckRangeByteShort(m);
+				if (err!=TIFFReadDirEntryErrOk)
+					return(err);
+				*value=(uint8)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_SSHORT:
+			{
+				int16 m;
+				TIFFReadDirEntryCheckedSshort(tif,direntry,&m);
+				err=TIFFReadDirEntryCheckRangeByteSshort(m);
+				if (err!=TIFFReadDirEntryErrOk)
+					return(err);
+				*value=(uint8)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_LONG:
+			{
+				uint32 m;
+				TIFFReadDirEntryCheckedLong(tif,direntry,&m);
+				err=TIFFReadDirEntryCheckRangeByteLong(m);
+				if (err!=TIFFReadDirEntryErrOk)
+					return(err);
+				*value=(uint8)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_SLONG:
+			{
+				int32 m;
+				TIFFReadDirEntryCheckedSlong(tif,direntry,&m);
+				err=TIFFReadDirEntryCheckRangeByteSlong(m);
+				if (err!=TIFFReadDirEntryErrOk)
+					return(err);
+				*value=(uint8)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_LONG8:
+			{
+				uint64 m;
+				err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m);
+				if (err!=TIFFReadDirEntryErrOk)
+					return(err);
+				err=TIFFReadDirEntryCheckRangeByteLong8(m);
+				if (err!=TIFFReadDirEntryErrOk)
+					return(err);
+				*value=(uint8)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_SLONG8:
+			{
+				int64 m;
+				err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m);
+				if (err!=TIFFReadDirEntryErrOk)
+					return(err);
+				err=TIFFReadDirEntryCheckRangeByteSlong8(m);
+				if (err!=TIFFReadDirEntryErrOk)
+					return(err);
+				*value=(uint8)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		default:
+			return(TIFFReadDirEntryErrType);
+	}
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value)
+{
+	enum TIFFReadDirEntryErr err;
+	if (direntry->tdir_count!=1)
+		return(TIFFReadDirEntryErrCount);
+	switch (direntry->tdir_type)
+	{
+		case TIFF_BYTE:
+			{
+				uint8 m;
+				TIFFReadDirEntryCheckedByte(tif,direntry,&m);
+				*value=(uint16)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_SBYTE:
+			{
+				int8 m;
+				TIFFReadDirEntryCheckedSbyte(tif,direntry,&m);
+				err=TIFFReadDirEntryCheckRangeShortSbyte(m);
+				if (err!=TIFFReadDirEntryErrOk)
+					return(err);
+				*value=(uint16)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_SHORT:
+			TIFFReadDirEntryCheckedShort(tif,direntry,value);
+			return(TIFFReadDirEntryErrOk);
+		case TIFF_SSHORT:
+			{
+				int16 m;
+				TIFFReadDirEntryCheckedSshort(tif,direntry,&m);
+				err=TIFFReadDirEntryCheckRangeShortSshort(m);
+				if (err!=TIFFReadDirEntryErrOk)
+					return(err);
+				*value=(uint16)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_LONG:
+			{
+				uint32 m;
+				TIFFReadDirEntryCheckedLong(tif,direntry,&m);
+				err=TIFFReadDirEntryCheckRangeShortLong(m);
+				if (err!=TIFFReadDirEntryErrOk)
+					return(err);
+				*value=(uint16)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_SLONG:
+			{
+				int32 m;
+				TIFFReadDirEntryCheckedSlong(tif,direntry,&m);
+				err=TIFFReadDirEntryCheckRangeShortSlong(m);
+				if (err!=TIFFReadDirEntryErrOk)
+					return(err);
+				*value=(uint16)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_LONG8:
+			{
+				uint64 m;
+				err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m);
+				if (err!=TIFFReadDirEntryErrOk)
+					return(err);
+				err=TIFFReadDirEntryCheckRangeShortLong8(m);
+				if (err!=TIFFReadDirEntryErrOk)
+					return(err);
+				*value=(uint16)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_SLONG8:
+			{
+				int64 m;
+				err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m);
+				if (err!=TIFFReadDirEntryErrOk)
+					return(err);
+				err=TIFFReadDirEntryCheckRangeShortSlong8(m);
+				if (err!=TIFFReadDirEntryErrOk)
+					return(err);
+				*value=(uint16)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		default:
+			return(TIFFReadDirEntryErrType);
+	}
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryLong(TIFF* tif, TIFFDirEntry* direntry, uint32* value)
+{
+	enum TIFFReadDirEntryErr err;
+	if (direntry->tdir_count!=1)
+		return(TIFFReadDirEntryErrCount);
+	switch (direntry->tdir_type)
+	{
+		case TIFF_BYTE:
+			{
+				uint8 m;
+				TIFFReadDirEntryCheckedByte(tif,direntry,&m);
+				*value=(uint32)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_SBYTE:
+			{
+				int8 m;
+				TIFFReadDirEntryCheckedSbyte(tif,direntry,&m);
+				err=TIFFReadDirEntryCheckRangeLongSbyte(m);
+				if (err!=TIFFReadDirEntryErrOk)
+					return(err);
+				*value=(uint32)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_SHORT:
+			{
+				uint16 m;
+				TIFFReadDirEntryCheckedShort(tif,direntry,&m);
+				*value=(uint32)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_SSHORT:
+			{
+				int16 m;
+				TIFFReadDirEntryCheckedSshort(tif,direntry,&m);
+				err=TIFFReadDirEntryCheckRangeLongSshort(m);
+				if (err!=TIFFReadDirEntryErrOk)
+					return(err);
+				*value=(uint32)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_LONG:
+			TIFFReadDirEntryCheckedLong(tif,direntry,value);
+			return(TIFFReadDirEntryErrOk);
+		case TIFF_SLONG:
+			{
+				int32 m;
+				TIFFReadDirEntryCheckedSlong(tif,direntry,&m);
+				err=TIFFReadDirEntryCheckRangeLongSlong(m);
+				if (err!=TIFFReadDirEntryErrOk)
+					return(err);
+				*value=(uint32)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_LONG8:
+			{
+				uint64 m;
+				err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m);
+				if (err!=TIFFReadDirEntryErrOk)
+					return(err);
+				err=TIFFReadDirEntryCheckRangeLongLong8(m);
+				if (err!=TIFFReadDirEntryErrOk)
+					return(err);
+				*value=(uint32)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_SLONG8:
+			{
+				int64 m;
+				err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m);
+				if (err!=TIFFReadDirEntryErrOk)
+					return(err);
+				err=TIFFReadDirEntryCheckRangeLongSlong8(m);
+				if (err!=TIFFReadDirEntryErrOk)
+					return(err);
+				*value=(uint32)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		default:
+			return(TIFFReadDirEntryErrType);
+	}
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8(TIFF* tif, TIFFDirEntry* direntry, uint64* value)
+{
+	enum TIFFReadDirEntryErr err;
+	if (direntry->tdir_count!=1)
+		return(TIFFReadDirEntryErrCount);
+	switch (direntry->tdir_type)
+	{
+		case TIFF_BYTE:
+			{
+				uint8 m;
+				TIFFReadDirEntryCheckedByte(tif,direntry,&m);
+				*value=(uint64)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_SBYTE:
+			{
+				int8 m;
+				TIFFReadDirEntryCheckedSbyte(tif,direntry,&m);
+				err=TIFFReadDirEntryCheckRangeLong8Sbyte(m);
+				if (err!=TIFFReadDirEntryErrOk)
+					return(err);
+				*value=(uint64)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_SHORT:
+			{
+				uint16 m;
+				TIFFReadDirEntryCheckedShort(tif,direntry,&m);
+				*value=(uint64)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_SSHORT:
+			{
+				int16 m;
+				TIFFReadDirEntryCheckedSshort(tif,direntry,&m);
+				err=TIFFReadDirEntryCheckRangeLong8Sshort(m);
+				if (err!=TIFFReadDirEntryErrOk)
+					return(err);
+				*value=(uint64)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_LONG:
+			{
+				uint32 m;
+				TIFFReadDirEntryCheckedLong(tif,direntry,&m);
+				*value=(uint64)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_SLONG:
+			{
+				int32 m;
+				TIFFReadDirEntryCheckedSlong(tif,direntry,&m);
+				err=TIFFReadDirEntryCheckRangeLong8Slong(m);
+				if (err!=TIFFReadDirEntryErrOk)
+					return(err);
+				*value=(uint64)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_LONG8:
+			err=TIFFReadDirEntryCheckedLong8(tif,direntry,value);
+			return(err);
+		case TIFF_SLONG8:
+			{
+				int64 m;
+				err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m);
+				if (err!=TIFFReadDirEntryErrOk)
+					return(err);
+				err=TIFFReadDirEntryCheckRangeLong8Slong8(m);
+				if (err!=TIFFReadDirEntryErrOk)
+					return(err);
+				*value=(uint64)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		default:
+			return(TIFFReadDirEntryErrType);
+	}
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryFloat(TIFF* tif, TIFFDirEntry* direntry, float* value)
+{
+	enum TIFFReadDirEntryErr err;
+	if (direntry->tdir_count!=1)
+		return(TIFFReadDirEntryErrCount);
+	switch (direntry->tdir_type)
+	{
+		case TIFF_BYTE:
+			{
+				uint8 m;
+				TIFFReadDirEntryCheckedByte(tif,direntry,&m);
+				*value=(float)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_SBYTE:
+			{
+				int8 m;
+				TIFFReadDirEntryCheckedSbyte(tif,direntry,&m);
+				*value=(float)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_SHORT:
+			{
+				uint16 m;
+				TIFFReadDirEntryCheckedShort(tif,direntry,&m);
+				*value=(float)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_SSHORT:
+			{
+				int16 m;
+				TIFFReadDirEntryCheckedSshort(tif,direntry,&m);
+				*value=(float)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_LONG:
+			{
+				uint32 m;
+				TIFFReadDirEntryCheckedLong(tif,direntry,&m);
+				*value=(float)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_SLONG:
+			{
+				int32 m;
+				TIFFReadDirEntryCheckedSlong(tif,direntry,&m);
+				*value=(float)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_LONG8:
+			{
+				uint64 m;
+				err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m);
+				if (err!=TIFFReadDirEntryErrOk)
+					return(err);
+#if defined(__WIN32__) && (_MSC_VER < 1500)
+				/*
+				 * XXX: MSVC 6.0 does not support conversion
+				 * of 64-bit integers into floating point
+				 * values.
+				 */
+				*value = _TIFFUInt64ToFloat(m);
+#else
+				*value=(float)m;
+#endif
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_SLONG8:
+			{
+				int64 m;
+				err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m);
+				if (err!=TIFFReadDirEntryErrOk)
+					return(err);
+				*value=(float)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_RATIONAL:
+			{
+				double m;
+				err=TIFFReadDirEntryCheckedRational(tif,direntry,&m);
+				if (err!=TIFFReadDirEntryErrOk)
+					return(err);
+				*value=(float)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_SRATIONAL:
+			{
+				double m;
+				err=TIFFReadDirEntryCheckedSrational(tif,direntry,&m);
+				if (err!=TIFFReadDirEntryErrOk)
+					return(err);
+				*value=(float)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_FLOAT:
+			TIFFReadDirEntryCheckedFloat(tif,direntry,value);
+			return(TIFFReadDirEntryErrOk);
+		case TIFF_DOUBLE:
+			{
+				double m;
+				err=TIFFReadDirEntryCheckedDouble(tif,direntry,&m);
+				if (err!=TIFFReadDirEntryErrOk)
+					return(err);
+				*value=(float)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		default:
+			return(TIFFReadDirEntryErrType);
+	}
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryDouble(TIFF* tif, TIFFDirEntry* direntry, double* value)
+{
+	enum TIFFReadDirEntryErr err;
+	if (direntry->tdir_count!=1)
+		return(TIFFReadDirEntryErrCount);
+	switch (direntry->tdir_type)
+	{
+		case TIFF_BYTE:
+			{
+				uint8 m;
+				TIFFReadDirEntryCheckedByte(tif,direntry,&m);
+				*value=(double)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_SBYTE:
+			{
+				int8 m;
+				TIFFReadDirEntryCheckedSbyte(tif,direntry,&m);
+				*value=(double)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_SHORT:
+			{
+				uint16 m;
+				TIFFReadDirEntryCheckedShort(tif,direntry,&m);
+				*value=(double)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_SSHORT:
+			{
+				int16 m;
+				TIFFReadDirEntryCheckedSshort(tif,direntry,&m);
+				*value=(double)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_LONG:
+			{
+				uint32 m;
+				TIFFReadDirEntryCheckedLong(tif,direntry,&m);
+				*value=(double)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_SLONG:
+			{
+				int32 m;
+				TIFFReadDirEntryCheckedSlong(tif,direntry,&m);
+				*value=(double)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_LONG8:
+			{
+				uint64 m;
+				err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m);
+				if (err!=TIFFReadDirEntryErrOk)
+					return(err);
+#if defined(__WIN32__) && (_MSC_VER < 1500)
+				/*
+				 * XXX: MSVC 6.0 does not support conversion
+				 * of 64-bit integers into floating point
+				 * values.
+				 */
+				*value = _TIFFUInt64ToDouble(m);
+#else
+				*value = (double)m;
+#endif
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_SLONG8:
+			{
+				int64 m;
+				err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m);
+				if (err!=TIFFReadDirEntryErrOk)
+					return(err);
+				*value=(double)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_RATIONAL:
+			err=TIFFReadDirEntryCheckedRational(tif,direntry,value);
+			return(err);
+		case TIFF_SRATIONAL:
+			err=TIFFReadDirEntryCheckedSrational(tif,direntry,value);
+			return(err);
+		case TIFF_FLOAT:
+			{
+				float m;
+				TIFFReadDirEntryCheckedFloat(tif,direntry,&m);
+				*value=(double)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_DOUBLE:
+			err=TIFFReadDirEntryCheckedDouble(tif,direntry,value);
+			return(err);
+		default:
+			return(TIFFReadDirEntryErrType);
+	}
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8(TIFF* tif, TIFFDirEntry* direntry, uint64* value)
+{
+	enum TIFFReadDirEntryErr err;
+	if (direntry->tdir_count!=1)
+		return(TIFFReadDirEntryErrCount);
+	switch (direntry->tdir_type)
+	{
+		case TIFF_LONG:
+		case TIFF_IFD:
+			{
+				uint32 m;
+				TIFFReadDirEntryCheckedLong(tif,direntry,&m);
+				*value=(uint64)m;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_LONG8:
+		case TIFF_IFD8:
+			err=TIFFReadDirEntryCheckedLong8(tif,direntry,value);
+			return(err);
+		default:
+			return(TIFFReadDirEntryErrType);
+	}
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* direntry, uint32* count, uint32 desttypesize, void** value)
+{
+	int typesize;
+	uint32 datasize;
+	void* data;
+	typesize=TIFFDataWidth(direntry->tdir_type);
+	if ((direntry->tdir_count==0)||(typesize==0))
+	{
+		*value=0;
+		return(TIFFReadDirEntryErrOk);
+	}
+        (void) desttypesize;
+
+        /* 
+         * As a sanity check, make sure we have no more than a 2GB tag array 
+         * in either the current data type or the dest data type.  This also
+         * avoids problems with overflow of tmsize_t on 32bit systems.
+         */
+	if ((uint64)(2147483647/typesize)<direntry->tdir_count)
+		return(TIFFReadDirEntryErrSizesan);
+	if ((uint64)(2147483647/desttypesize)<direntry->tdir_count)
+		return(TIFFReadDirEntryErrSizesan);
+
+	*count=(uint32)direntry->tdir_count;
+	datasize=(*count)*typesize;
+	assert((tmsize_t)datasize>0);
+	data=_TIFFCheckMalloc(tif, *count, typesize, "ReadDirEntryArray");
+	if (data==0)
+		return(TIFFReadDirEntryErrAlloc);
+	if (!(tif->tif_flags&TIFF_BIGTIFF))
+	{
+		if (datasize<=4)
+			_TIFFmemcpy(data,&direntry->tdir_offset,datasize);
+		else
+		{
+			enum TIFFReadDirEntryErr err;
+			uint32 offset = direntry->tdir_offset.toff_long;
+			if (tif->tif_flags&TIFF_SWAB)
+				TIFFSwabLong(&offset);
+			err=TIFFReadDirEntryData(tif,(uint64)offset,(tmsize_t)datasize,data);
+			if (err!=TIFFReadDirEntryErrOk)
+			{
+				_TIFFfree(data);
+				return(err);
+			}
+		}
+	}
+	else
+	{
+		if (datasize<=8)
+			_TIFFmemcpy(data,&direntry->tdir_offset,datasize);
+		else
+		{
+			enum TIFFReadDirEntryErr err;
+			uint64 offset = direntry->tdir_offset.toff_long8;
+			if (tif->tif_flags&TIFF_SWAB)
+				TIFFSwabLong8(&offset);
+			err=TIFFReadDirEntryData(tif,offset,(tmsize_t)datasize,data);
+			if (err!=TIFFReadDirEntryErrOk)
+			{
+				_TIFFfree(data);
+				return(err);
+			}
+		}
+	}
+	*value=data;
+	return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryByteArray(TIFF* tif, TIFFDirEntry* direntry, uint8** value)
+{
+	enum TIFFReadDirEntryErr err;
+	uint32 count;
+	void* origdata;
+	uint8* data;
+	switch (direntry->tdir_type)
+	{
+		case TIFF_ASCII:
+		case TIFF_UNDEFINED:
+		case TIFF_BYTE:
+		case TIFF_SBYTE:
+		case TIFF_SHORT:
+		case TIFF_SSHORT:
+		case TIFF_LONG:
+		case TIFF_SLONG:
+		case TIFF_LONG8:
+		case TIFF_SLONG8:
+			break;
+		default:
+			return(TIFFReadDirEntryErrType);
+	}
+	err=TIFFReadDirEntryArray(tif,direntry,&count,1,&origdata);
+	if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
+	{
+		*value=0;
+		return(err);
+	}
+	switch (direntry->tdir_type)
+	{
+		case TIFF_ASCII:
+		case TIFF_UNDEFINED:
+		case TIFF_BYTE:
+			*value=(uint8*)origdata;
+			return(TIFFReadDirEntryErrOk);
+		case TIFF_SBYTE:
+			{
+				int8* m;
+				uint32 n;
+				m=(int8*)origdata;
+				for (n=0; n<count; n++)
+				{
+					err=TIFFReadDirEntryCheckRangeByteSbyte(*m);
+					if (err!=TIFFReadDirEntryErrOk)
+					{
+						_TIFFfree(origdata);
+						return(err);
+					}
+					m++;
+				}
+				*value=(uint8*)origdata;
+				return(TIFFReadDirEntryErrOk);
+			}
+	}
+	data=(uint8*)_TIFFmalloc(count);
+	if (data==0)
+	{
+		_TIFFfree(origdata);
+		return(TIFFReadDirEntryErrAlloc);
+	}
+	switch (direntry->tdir_type)
+	{
+		case TIFF_SHORT:
+			{
+				uint16* ma;
+				uint8* mb;
+				uint32 n;
+				ma=(uint16*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabShort(ma);
+					err=TIFFReadDirEntryCheckRangeByteShort(*ma);
+					if (err!=TIFFReadDirEntryErrOk)
+						break;
+					*mb++=(uint8)(*ma++);
+				}
+			}
+			break;
+		case TIFF_SSHORT:
+			{
+				int16* ma;
+				uint8* mb;
+				uint32 n;
+				ma=(int16*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabShort((uint16*)ma);
+					err=TIFFReadDirEntryCheckRangeByteSshort(*ma);
+					if (err!=TIFFReadDirEntryErrOk)
+						break;
+					*mb++=(uint8)(*ma++);
+				}
+			}
+			break;
+		case TIFF_LONG:
+			{
+				uint32* ma;
+				uint8* mb;
+				uint32 n;
+				ma=(uint32*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong(ma);
+					err=TIFFReadDirEntryCheckRangeByteLong(*ma);
+					if (err!=TIFFReadDirEntryErrOk)
+						break;
+					*mb++=(uint8)(*ma++);
+				}
+			}
+			break;
+		case TIFF_SLONG:
+			{
+				int32* ma;
+				uint8* mb;
+				uint32 n;
+				ma=(int32*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong((uint32*)ma);
+					err=TIFFReadDirEntryCheckRangeByteSlong(*ma);
+					if (err!=TIFFReadDirEntryErrOk)
+						break;
+					*mb++=(uint8)(*ma++);
+				}
+			}
+			break;
+		case TIFF_LONG8:
+			{
+				uint64* ma;
+				uint8* mb;
+				uint32 n;
+				ma=(uint64*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong8(ma);
+					err=TIFFReadDirEntryCheckRangeByteLong8(*ma);
+					if (err!=TIFFReadDirEntryErrOk)
+						break;
+					*mb++=(uint8)(*ma++);
+				}
+			}
+			break;
+		case TIFF_SLONG8:
+			{
+				int64* ma;
+				uint8* mb;
+				uint32 n;
+				ma=(int64*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong8((uint64*)ma);
+					err=TIFFReadDirEntryCheckRangeByteSlong8(*ma);
+					if (err!=TIFFReadDirEntryErrOk)
+						break;
+					*mb++=(uint8)(*ma++);
+				}
+			}
+			break;
+	}
+	_TIFFfree(origdata);
+	if (err!=TIFFReadDirEntryErrOk)
+	{
+		_TIFFfree(data);
+		return(err);
+	}
+	*value=data;
+	return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntrySbyteArray(TIFF* tif, TIFFDirEntry* direntry, int8** value)
+{
+	enum TIFFReadDirEntryErr err;
+	uint32 count;
+	void* origdata;
+	int8* data;
+	switch (direntry->tdir_type)
+	{
+		case TIFF_UNDEFINED:
+		case TIFF_BYTE:
+		case TIFF_SBYTE:
+		case TIFF_SHORT:
+		case TIFF_SSHORT:
+		case TIFF_LONG:
+		case TIFF_SLONG:
+		case TIFF_LONG8:
+		case TIFF_SLONG8:
+			break;
+		default:
+			return(TIFFReadDirEntryErrType);
+	}
+	err=TIFFReadDirEntryArray(tif,direntry,&count,1,&origdata);
+	if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
+	{
+		*value=0;
+		return(err);
+	}
+	switch (direntry->tdir_type)
+	{
+		case TIFF_UNDEFINED:
+		case TIFF_BYTE:
+			{
+				uint8* m;
+				uint32 n;
+				m=(uint8*)origdata;
+				for (n=0; n<count; n++)
+				{
+					err=TIFFReadDirEntryCheckRangeSbyteByte(*m);
+					if (err!=TIFFReadDirEntryErrOk)
+					{
+						_TIFFfree(origdata);
+						return(err);
+					}
+					m++;
+				}
+				*value=(int8*)origdata;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_SBYTE:
+			*value=(int8*)origdata;
+			return(TIFFReadDirEntryErrOk);
+	}
+	data=(int8*)_TIFFmalloc(count);
+	if (data==0)
+	{
+		_TIFFfree(origdata);
+		return(TIFFReadDirEntryErrAlloc);
+	}
+	switch (direntry->tdir_type)
+	{
+		case TIFF_SHORT:
+			{
+				uint16* ma;
+				int8* mb;
+				uint32 n;
+				ma=(uint16*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabShort(ma);
+					err=TIFFReadDirEntryCheckRangeSbyteShort(*ma);
+					if (err!=TIFFReadDirEntryErrOk)
+						break;
+					*mb++=(int8)(*ma++);
+				}
+			}
+			break;
+		case TIFF_SSHORT:
+			{
+				int16* ma;
+				int8* mb;
+				uint32 n;
+				ma=(int16*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabShort((uint16*)ma);
+					err=TIFFReadDirEntryCheckRangeSbyteSshort(*ma);
+					if (err!=TIFFReadDirEntryErrOk)
+						break;
+					*mb++=(int8)(*ma++);
+				}
+			}
+			break;
+		case TIFF_LONG:
+			{
+				uint32* ma;
+				int8* mb;
+				uint32 n;
+				ma=(uint32*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong(ma);
+					err=TIFFReadDirEntryCheckRangeSbyteLong(*ma);
+					if (err!=TIFFReadDirEntryErrOk)
+						break;
+					*mb++=(int8)(*ma++);
+				}
+			}
+			break;
+		case TIFF_SLONG:
+			{
+				int32* ma;
+				int8* mb;
+				uint32 n;
+				ma=(int32*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong((uint32*)ma);
+					err=TIFFReadDirEntryCheckRangeSbyteSlong(*ma);
+					if (err!=TIFFReadDirEntryErrOk)
+						break;
+					*mb++=(int8)(*ma++);
+				}
+			}
+			break;
+		case TIFF_LONG8:
+			{
+				uint64* ma;
+				int8* mb;
+				uint32 n;
+				ma=(uint64*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong8(ma);
+					err=TIFFReadDirEntryCheckRangeSbyteLong8(*ma);
+					if (err!=TIFFReadDirEntryErrOk)
+						break;
+					*mb++=(int8)(*ma++);
+				}
+			}
+			break;
+		case TIFF_SLONG8:
+			{
+				int64* ma;
+				int8* mb;
+				uint32 n;
+				ma=(int64*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong8((uint64*)ma);
+					err=TIFFReadDirEntryCheckRangeSbyteSlong8(*ma);
+					if (err!=TIFFReadDirEntryErrOk)
+						break;
+					*mb++=(int8)(*ma++);
+				}
+			}
+			break;
+	}
+	_TIFFfree(origdata);
+	if (err!=TIFFReadDirEntryErrOk)
+	{
+		_TIFFfree(data);
+		return(err);
+	}
+	*value=data;
+	return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryShortArray(TIFF* tif, TIFFDirEntry* direntry, uint16** value)
+{
+	enum TIFFReadDirEntryErr err;
+	uint32 count;
+	void* origdata;
+	uint16* data;
+	switch (direntry->tdir_type)
+	{
+		case TIFF_BYTE:
+		case TIFF_SBYTE:
+		case TIFF_SHORT:
+		case TIFF_SSHORT:
+		case TIFF_LONG:
+		case TIFF_SLONG:
+		case TIFF_LONG8:
+		case TIFF_SLONG8:
+			break;
+		default:
+			return(TIFFReadDirEntryErrType);
+	}
+	err=TIFFReadDirEntryArray(tif,direntry,&count,2,&origdata);
+	if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
+	{
+		*value=0;
+		return(err);
+	}
+	switch (direntry->tdir_type)
+	{
+		case TIFF_SHORT:
+			*value=(uint16*)origdata;
+			if (tif->tif_flags&TIFF_SWAB)
+				TIFFSwabArrayOfShort(*value,count);  
+			return(TIFFReadDirEntryErrOk);
+		case TIFF_SSHORT:
+			{
+				int16* m;
+				uint32 n;
+				m=(int16*)origdata;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabShort((uint16*)m);
+					err=TIFFReadDirEntryCheckRangeShortSshort(*m);
+					if (err!=TIFFReadDirEntryErrOk)
+					{
+						_TIFFfree(origdata);
+						return(err);
+					}
+					m++;
+				}
+				*value=(uint16*)origdata;
+				return(TIFFReadDirEntryErrOk);
+			}
+	}
+	data=(uint16*)_TIFFmalloc(count*2);
+	if (data==0)
+	{
+		_TIFFfree(origdata);
+		return(TIFFReadDirEntryErrAlloc);
+	}
+	switch (direntry->tdir_type)
+	{
+		case TIFF_BYTE:
+			{
+				uint8* ma;
+				uint16* mb;
+				uint32 n;
+				ma=(uint8*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+					*mb++=(uint16)(*ma++);
+			}
+			break;
+		case TIFF_SBYTE:
+			{
+				int8* ma;
+				uint16* mb;
+				uint32 n;
+				ma=(int8*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					err=TIFFReadDirEntryCheckRangeShortSbyte(*ma);
+					if (err!=TIFFReadDirEntryErrOk)
+						break;
+					*mb++=(uint16)(*ma++);
+				}
+			}
+			break;
+		case TIFF_LONG:
+			{
+				uint32* ma;
+				uint16* mb;
+				uint32 n;
+				ma=(uint32*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong(ma);
+					err=TIFFReadDirEntryCheckRangeShortLong(*ma);
+					if (err!=TIFFReadDirEntryErrOk)
+						break;
+					*mb++=(uint16)(*ma++);
+				}
+			}
+			break;
+		case TIFF_SLONG:
+			{
+				int32* ma;
+				uint16* mb;
+				uint32 n;
+				ma=(int32*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong((uint32*)ma);
+					err=TIFFReadDirEntryCheckRangeShortSlong(*ma);
+					if (err!=TIFFReadDirEntryErrOk)
+						break;
+					*mb++=(uint16)(*ma++);
+				}
+			}
+			break;
+		case TIFF_LONG8:
+			{
+				uint64* ma;
+				uint16* mb;
+				uint32 n;
+				ma=(uint64*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong8(ma);
+					err=TIFFReadDirEntryCheckRangeShortLong8(*ma);
+					if (err!=TIFFReadDirEntryErrOk)
+						break;
+					*mb++=(uint16)(*ma++);
+				}
+			}
+			break;
+		case TIFF_SLONG8:
+			{
+				int64* ma;
+				uint16* mb;
+				uint32 n;
+				ma=(int64*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong8((uint64*)ma);
+					err=TIFFReadDirEntryCheckRangeShortSlong8(*ma);
+					if (err!=TIFFReadDirEntryErrOk)
+						break;
+					*mb++=(uint16)(*ma++);
+				}
+			}
+			break;
+	}
+	_TIFFfree(origdata);
+	if (err!=TIFFReadDirEntryErrOk)
+	{
+		_TIFFfree(data);
+		return(err);
+	}
+	*value=data;
+	return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntrySshortArray(TIFF* tif, TIFFDirEntry* direntry, int16** value)
+{
+	enum TIFFReadDirEntryErr err;
+	uint32 count;
+	void* origdata;
+	int16* data;
+	switch (direntry->tdir_type)
+	{
+		case TIFF_BYTE:
+		case TIFF_SBYTE:
+		case TIFF_SHORT:
+		case TIFF_SSHORT:
+		case TIFF_LONG:
+		case TIFF_SLONG:
+		case TIFF_LONG8:
+		case TIFF_SLONG8:
+			break;
+		default:
+			return(TIFFReadDirEntryErrType);
+	}
+	err=TIFFReadDirEntryArray(tif,direntry,&count,2,&origdata);
+	if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
+	{
+		*value=0;
+		return(err);
+	}
+	switch (direntry->tdir_type)
+	{
+		case TIFF_SHORT:
+			{
+				uint16* m;
+				uint32 n;
+				m=(uint16*)origdata;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabShort(m);
+					err=TIFFReadDirEntryCheckRangeSshortShort(*m);
+					if (err!=TIFFReadDirEntryErrOk)
+					{
+						_TIFFfree(origdata);
+						return(err);
+					}
+					m++;
+				}
+				*value=(int16*)origdata;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_SSHORT:
+			*value=(int16*)origdata;
+			if (tif->tif_flags&TIFF_SWAB)
+				TIFFSwabArrayOfShort((uint16*)(*value),count);
+			return(TIFFReadDirEntryErrOk);
+	}
+	data=(int16*)_TIFFmalloc(count*2);
+	if (data==0)
+	{
+		_TIFFfree(origdata);
+		return(TIFFReadDirEntryErrAlloc);
+	}
+	switch (direntry->tdir_type)
+	{
+		case TIFF_BYTE:
+			{
+				uint8* ma;
+				int16* mb;
+				uint32 n;
+				ma=(uint8*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+					*mb++=(int16)(*ma++);
+			}
+			break;
+		case TIFF_SBYTE:
+			{
+				int8* ma;
+				int16* mb;
+				uint32 n;
+				ma=(int8*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+					*mb++=(int16)(*ma++);
+			}
+			break;
+		case TIFF_LONG:
+			{
+				uint32* ma;
+				int16* mb;
+				uint32 n;
+				ma=(uint32*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong(ma);
+					err=TIFFReadDirEntryCheckRangeSshortLong(*ma);
+					if (err!=TIFFReadDirEntryErrOk)
+						break;
+					*mb++=(int16)(*ma++);
+				}
+			}
+			break;
+		case TIFF_SLONG:
+			{
+				int32* ma;
+				int16* mb;
+				uint32 n;
+				ma=(int32*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong((uint32*)ma);
+					err=TIFFReadDirEntryCheckRangeSshortSlong(*ma);
+					if (err!=TIFFReadDirEntryErrOk)
+						break;
+					*mb++=(int16)(*ma++);
+				}
+			}
+			break;
+		case TIFF_LONG8:
+			{
+				uint64* ma;
+				int16* mb;
+				uint32 n;
+				ma=(uint64*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong8(ma);
+					err=TIFFReadDirEntryCheckRangeSshortLong8(*ma);
+					if (err!=TIFFReadDirEntryErrOk)
+						break;
+					*mb++=(int16)(*ma++);
+				}
+			}
+			break;
+		case TIFF_SLONG8:
+			{
+				int64* ma;
+				int16* mb;
+				uint32 n;
+				ma=(int64*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong8((uint64*)ma);
+					err=TIFFReadDirEntryCheckRangeSshortSlong8(*ma);
+					if (err!=TIFFReadDirEntryErrOk)
+						break;
+					*mb++=(int16)(*ma++);
+				}
+			}
+			break;
+	}
+	_TIFFfree(origdata);
+	if (err!=TIFFReadDirEntryErrOk)
+	{
+		_TIFFfree(data);
+		return(err);
+	}
+	*value=data;
+	return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryLongArray(TIFF* tif, TIFFDirEntry* direntry, uint32** value)
+{
+	enum TIFFReadDirEntryErr err;
+	uint32 count;
+	void* origdata;
+	uint32* data;
+	switch (direntry->tdir_type)
+	{
+		case TIFF_BYTE:
+		case TIFF_SBYTE:
+		case TIFF_SHORT:
+		case TIFF_SSHORT:
+		case TIFF_LONG:
+		case TIFF_SLONG:
+		case TIFF_LONG8:
+		case TIFF_SLONG8:
+			break;
+		default:
+			return(TIFFReadDirEntryErrType);
+	}
+	err=TIFFReadDirEntryArray(tif,direntry,&count,4,&origdata);
+	if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
+	{
+		*value=0;
+		return(err);
+	}
+	switch (direntry->tdir_type)
+	{
+		case TIFF_LONG:
+			*value=(uint32*)origdata;
+			if (tif->tif_flags&TIFF_SWAB)
+				TIFFSwabArrayOfLong(*value,count);
+			return(TIFFReadDirEntryErrOk);
+		case TIFF_SLONG:
+			{
+				int32* m;
+				uint32 n;
+				m=(int32*)origdata;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong((uint32*)m);
+					err=TIFFReadDirEntryCheckRangeLongSlong(*m);
+					if (err!=TIFFReadDirEntryErrOk)
+					{
+						_TIFFfree(origdata);
+						return(err);
+					}
+					m++;
+				}
+				*value=(uint32*)origdata;
+				return(TIFFReadDirEntryErrOk);
+			}
+	}
+	data=(uint32*)_TIFFmalloc(count*4);
+	if (data==0)
+	{
+		_TIFFfree(origdata);
+		return(TIFFReadDirEntryErrAlloc);
+	}
+	switch (direntry->tdir_type)
+	{
+		case TIFF_BYTE:
+			{
+				uint8* ma;
+				uint32* mb;
+				uint32 n;
+				ma=(uint8*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+					*mb++=(uint32)(*ma++);
+			}
+			break;
+		case TIFF_SBYTE:
+			{
+				int8* ma;
+				uint32* mb;
+				uint32 n;
+				ma=(int8*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					err=TIFFReadDirEntryCheckRangeLongSbyte(*ma);
+					if (err!=TIFFReadDirEntryErrOk)
+						break;
+					*mb++=(uint32)(*ma++);
+				}
+			}
+			break;
+		case TIFF_SHORT:
+			{
+				uint16* ma;
+				uint32* mb;
+				uint32 n;
+				ma=(uint16*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabShort(ma);
+					*mb++=(uint32)(*ma++);
+				}
+			}
+			break;
+		case TIFF_SSHORT:
+			{
+				int16* ma;
+				uint32* mb;
+				uint32 n;
+				ma=(int16*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabShort((uint16*)ma);
+					err=TIFFReadDirEntryCheckRangeLongSshort(*ma);
+					if (err!=TIFFReadDirEntryErrOk)
+						break;
+					*mb++=(uint32)(*ma++);
+				}
+			}
+			break;
+		case TIFF_LONG8:
+			{
+				uint64* ma;
+				uint32* mb;
+				uint32 n;
+				ma=(uint64*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong8(ma);
+					err=TIFFReadDirEntryCheckRangeLongLong8(*ma);
+					if (err!=TIFFReadDirEntryErrOk)
+						break;
+					*mb++=(uint32)(*ma++);
+				}
+			}
+			break;
+		case TIFF_SLONG8:
+			{
+				int64* ma;
+				uint32* mb;
+				uint32 n;
+				ma=(int64*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong8((uint64*)ma);
+					err=TIFFReadDirEntryCheckRangeLongSlong8(*ma);
+					if (err!=TIFFReadDirEntryErrOk)
+						break;
+					*mb++=(uint32)(*ma++);
+				}
+			}
+			break;
+	}
+	_TIFFfree(origdata);
+	if (err!=TIFFReadDirEntryErrOk)
+	{
+		_TIFFfree(data);
+		return(err);
+	}
+	*value=data;
+	return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntrySlongArray(TIFF* tif, TIFFDirEntry* direntry, int32** value)
+{
+	enum TIFFReadDirEntryErr err;
+	uint32 count;
+	void* origdata;
+	int32* data;
+	switch (direntry->tdir_type)
+	{
+		case TIFF_BYTE:
+		case TIFF_SBYTE:
+		case TIFF_SHORT:
+		case TIFF_SSHORT:
+		case TIFF_LONG:
+		case TIFF_SLONG:
+		case TIFF_LONG8:
+		case TIFF_SLONG8:
+			break;
+		default:
+			return(TIFFReadDirEntryErrType);
+	}
+	err=TIFFReadDirEntryArray(tif,direntry,&count,4,&origdata);
+	if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
+	{
+		*value=0;
+		return(err);
+	}
+	switch (direntry->tdir_type)
+	{
+		case TIFF_LONG:
+			{
+				uint32* m;
+				uint32 n;
+				m=(uint32*)origdata;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong((uint32*)m);
+					err=TIFFReadDirEntryCheckRangeSlongLong(*m);
+					if (err!=TIFFReadDirEntryErrOk)
+					{
+						_TIFFfree(origdata);
+						return(err);
+					}
+					m++;
+				}
+				*value=(int32*)origdata;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_SLONG:
+			*value=(int32*)origdata;
+			if (tif->tif_flags&TIFF_SWAB)
+				TIFFSwabArrayOfLong((uint32*)(*value),count);
+			return(TIFFReadDirEntryErrOk);
+	}
+	data=(int32*)_TIFFmalloc(count*4);
+	if (data==0)
+	{
+		_TIFFfree(origdata);
+		return(TIFFReadDirEntryErrAlloc);
+	}
+	switch (direntry->tdir_type)
+	{
+		case TIFF_BYTE:
+			{
+				uint8* ma;
+				int32* mb;
+				uint32 n;
+				ma=(uint8*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+					*mb++=(int32)(*ma++);
+			}
+			break;
+		case TIFF_SBYTE:
+			{
+				int8* ma;
+				int32* mb;
+				uint32 n;
+				ma=(int8*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+					*mb++=(int32)(*ma++);
+			}
+			break;
+		case TIFF_SHORT:
+			{
+				uint16* ma;
+				int32* mb;
+				uint32 n;
+				ma=(uint16*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabShort(ma);
+					*mb++=(int32)(*ma++);
+				}
+			}
+			break;
+		case TIFF_SSHORT:
+			{
+				int16* ma;
+				int32* mb;
+				uint32 n;
+				ma=(int16*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabShort((uint16*)ma);
+					*mb++=(int32)(*ma++);
+				}
+			}
+			break;
+		case TIFF_LONG8:
+			{
+				uint64* ma;
+				int32* mb;
+				uint32 n;
+				ma=(uint64*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong8(ma);
+					err=TIFFReadDirEntryCheckRangeSlongLong8(*ma);
+					if (err!=TIFFReadDirEntryErrOk)
+						break;
+					*mb++=(int32)(*ma++);
+				}
+			}
+			break;
+		case TIFF_SLONG8:
+			{
+				int64* ma;
+				int32* mb;
+				uint32 n;
+				ma=(int64*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong8((uint64*)ma);
+					err=TIFFReadDirEntryCheckRangeSlongSlong8(*ma);
+					if (err!=TIFFReadDirEntryErrOk)
+						break;
+					*mb++=(int32)(*ma++);
+				}
+			}
+			break;
+	}
+	_TIFFfree(origdata);
+	if (err!=TIFFReadDirEntryErrOk)
+	{
+		_TIFFfree(data);
+		return(err);
+	}
+	*value=data;
+	return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8Array(TIFF* tif, TIFFDirEntry* direntry, uint64** value)
+{
+	enum TIFFReadDirEntryErr err;
+	uint32 count;
+	void* origdata;
+	uint64* data;
+	switch (direntry->tdir_type)
+	{
+		case TIFF_BYTE:
+		case TIFF_SBYTE:
+		case TIFF_SHORT:
+		case TIFF_SSHORT:
+		case TIFF_LONG:
+		case TIFF_SLONG:
+		case TIFF_LONG8:
+		case TIFF_SLONG8:
+			break;
+		default:
+			return(TIFFReadDirEntryErrType);
+	}
+	err=TIFFReadDirEntryArray(tif,direntry,&count,8,&origdata);
+	if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
+	{
+		*value=0;
+		return(err);
+	}
+	switch (direntry->tdir_type)
+	{
+		case TIFF_LONG8:
+			*value=(uint64*)origdata;
+			if (tif->tif_flags&TIFF_SWAB)
+				TIFFSwabArrayOfLong8(*value,count);
+			return(TIFFReadDirEntryErrOk);
+		case TIFF_SLONG8:
+			{
+				int64* m;
+				uint32 n;
+				m=(int64*)origdata;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong8((uint64*)m);
+					err=TIFFReadDirEntryCheckRangeLong8Slong8(*m);
+					if (err!=TIFFReadDirEntryErrOk)
+					{
+						_TIFFfree(origdata);
+						return(err);
+					}
+					m++;
+				}
+				*value=(uint64*)origdata;
+				return(TIFFReadDirEntryErrOk);
+			}
+	}
+	data=(uint64*)_TIFFmalloc(count*8);
+	if (data==0)
+	{
+		_TIFFfree(origdata);
+		return(TIFFReadDirEntryErrAlloc);
+	}
+	switch (direntry->tdir_type)
+	{
+		case TIFF_BYTE:
+			{
+				uint8* ma;
+				uint64* mb;
+				uint32 n;
+				ma=(uint8*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+					*mb++=(uint64)(*ma++);
+			}
+			break;
+		case TIFF_SBYTE:
+			{
+				int8* ma;
+				uint64* mb;
+				uint32 n;
+				ma=(int8*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					err=TIFFReadDirEntryCheckRangeLong8Sbyte(*ma);
+					if (err!=TIFFReadDirEntryErrOk)
+						break;
+					*mb++=(uint64)(*ma++);
+				}
+			}
+			break;
+		case TIFF_SHORT:
+			{
+				uint16* ma;
+				uint64* mb;
+				uint32 n;
+				ma=(uint16*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabShort(ma);
+					*mb++=(uint64)(*ma++);
+				}
+			}
+			break;
+		case TIFF_SSHORT:
+			{
+				int16* ma;
+				uint64* mb;
+				uint32 n;
+				ma=(int16*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabShort((uint16*)ma);
+					err=TIFFReadDirEntryCheckRangeLong8Sshort(*ma);
+					if (err!=TIFFReadDirEntryErrOk)
+						break;
+					*mb++=(uint64)(*ma++);
+				}
+			}
+			break;
+		case TIFF_LONG:
+			{
+				uint32* ma;
+				uint64* mb;
+				uint32 n;
+				ma=(uint32*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong(ma);
+					*mb++=(uint64)(*ma++);
+				}
+			}
+			break;
+		case TIFF_SLONG:
+			{
+				int32* ma;
+				uint64* mb;
+				uint32 n;
+				ma=(int32*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong((uint32*)ma);
+					err=TIFFReadDirEntryCheckRangeLong8Slong(*ma);
+					if (err!=TIFFReadDirEntryErrOk)
+						break;
+					*mb++=(uint64)(*ma++);
+				}
+			}
+			break;
+	}
+	_TIFFfree(origdata);
+	if (err!=TIFFReadDirEntryErrOk)
+	{
+		_TIFFfree(data);
+		return(err);
+	}
+	*value=data;
+	return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntrySlong8Array(TIFF* tif, TIFFDirEntry* direntry, int64** value)
+{
+	enum TIFFReadDirEntryErr err;
+	uint32 count;
+	void* origdata;
+	int64* data;
+	switch (direntry->tdir_type)
+	{
+		case TIFF_BYTE:
+		case TIFF_SBYTE:
+		case TIFF_SHORT:
+		case TIFF_SSHORT:
+		case TIFF_LONG:
+		case TIFF_SLONG:
+		case TIFF_LONG8:
+		case TIFF_SLONG8:
+			break;
+		default:
+			return(TIFFReadDirEntryErrType);
+	}
+	err=TIFFReadDirEntryArray(tif,direntry,&count,8,&origdata);
+	if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
+	{
+		*value=0;
+		return(err);
+	}
+	switch (direntry->tdir_type)
+	{
+		case TIFF_LONG8:
+			{
+				uint64* m;
+				uint32 n;
+				m=(uint64*)origdata;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong8(m);
+					err=TIFFReadDirEntryCheckRangeSlong8Long8(*m);
+					if (err!=TIFFReadDirEntryErrOk)
+					{
+						_TIFFfree(origdata);
+						return(err);
+					}
+					m++;
+				}
+				*value=(int64*)origdata;
+				return(TIFFReadDirEntryErrOk);
+			}
+		case TIFF_SLONG8:
+			*value=(int64*)origdata;
+			if (tif->tif_flags&TIFF_SWAB)
+				TIFFSwabArrayOfLong8((uint64*)(*value),count);
+			return(TIFFReadDirEntryErrOk);
+	}
+	data=(int64*)_TIFFmalloc(count*8);
+	if (data==0)
+	{
+		_TIFFfree(origdata);
+		return(TIFFReadDirEntryErrAlloc);
+	}
+	switch (direntry->tdir_type)
+	{
+		case TIFF_BYTE:
+			{
+				uint8* ma;
+				int64* mb;
+				uint32 n;
+				ma=(uint8*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+					*mb++=(int64)(*ma++);
+			}
+			break;
+		case TIFF_SBYTE:
+			{
+				int8* ma;
+				int64* mb;
+				uint32 n;
+				ma=(int8*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+					*mb++=(int64)(*ma++);
+			}
+			break;
+		case TIFF_SHORT:
+			{
+				uint16* ma;
+				int64* mb;
+				uint32 n;
+				ma=(uint16*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabShort(ma);
+					*mb++=(int64)(*ma++);
+				}
+			}
+			break;
+		case TIFF_SSHORT:
+			{
+				int16* ma;
+				int64* mb;
+				uint32 n;
+				ma=(int16*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabShort((uint16*)ma);
+					*mb++=(int64)(*ma++);
+				}
+			}
+			break;
+		case TIFF_LONG:
+			{
+				uint32* ma;
+				int64* mb;
+				uint32 n;
+				ma=(uint32*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong(ma);
+					*mb++=(int64)(*ma++);
+				}
+			}
+			break;
+		case TIFF_SLONG:
+			{
+				int32* ma;
+				int64* mb;
+				uint32 n;
+				ma=(int32*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong((uint32*)ma);
+					*mb++=(int64)(*ma++);
+				}
+			}
+			break;
+	}
+	_TIFFfree(origdata);
+	if (err!=TIFFReadDirEntryErrOk)
+	{
+		_TIFFfree(data);
+		return(err);
+	}
+	*value=data;
+	return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryFloatArray(TIFF* tif, TIFFDirEntry* direntry, float** value)
+{
+	enum TIFFReadDirEntryErr err;
+	uint32 count;
+	void* origdata;
+	float* data;
+	switch (direntry->tdir_type)
+	{
+		case TIFF_BYTE:
+		case TIFF_SBYTE:
+		case TIFF_SHORT:
+		case TIFF_SSHORT:
+		case TIFF_LONG:
+		case TIFF_SLONG:
+		case TIFF_LONG8:
+		case TIFF_SLONG8:
+		case TIFF_RATIONAL:
+		case TIFF_SRATIONAL:
+		case TIFF_FLOAT:
+		case TIFF_DOUBLE:
+			break;
+		default:
+			return(TIFFReadDirEntryErrType);
+	}
+	err=TIFFReadDirEntryArray(tif,direntry,&count,4,&origdata);
+	if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
+	{
+		*value=0;
+		return(err);
+	}
+	switch (direntry->tdir_type)
+	{
+		case TIFF_FLOAT:
+			if (tif->tif_flags&TIFF_SWAB)
+				TIFFSwabArrayOfLong((uint32*)origdata,count);  
+			TIFFCvtIEEEDoubleToNative(tif,count,(float*)origdata);
+			*value=(float*)origdata;
+			return(TIFFReadDirEntryErrOk);
+	}
+	data=(float*)_TIFFmalloc(count*sizeof(float));
+	if (data==0)
+	{
+		_TIFFfree(origdata);
+		return(TIFFReadDirEntryErrAlloc);
+	}
+	switch (direntry->tdir_type)
+	{
+		case TIFF_BYTE:
+			{
+				uint8* ma;
+				float* mb;
+				uint32 n;
+				ma=(uint8*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+					*mb++=(float)(*ma++);
+			}
+			break;
+		case TIFF_SBYTE:
+			{
+				int8* ma;
+				float* mb;
+				uint32 n;
+				ma=(int8*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+					*mb++=(float)(*ma++);
+			}
+			break;
+		case TIFF_SHORT:
+			{
+				uint16* ma;
+				float* mb;
+				uint32 n;
+				ma=(uint16*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabShort(ma);
+					*mb++=(float)(*ma++);
+				}
+			}
+			break;
+		case TIFF_SSHORT:
+			{
+				int16* ma;
+				float* mb;
+				uint32 n;
+				ma=(int16*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabShort((uint16*)ma);
+					*mb++=(float)(*ma++);
+				}
+			}
+			break;
+		case TIFF_LONG:
+			{
+				uint32* ma;
+				float* mb;
+				uint32 n;
+				ma=(uint32*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong(ma);
+					*mb++=(float)(*ma++);
+				}
+			}
+			break;
+		case TIFF_SLONG:
+			{
+				int32* ma;
+				float* mb;
+				uint32 n;
+				ma=(int32*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong((uint32*)ma);
+					*mb++=(float)(*ma++);
+				}
+			}
+			break;
+		case TIFF_LONG8:
+			{
+				uint64* ma;
+				float* mb;
+				uint32 n;
+				ma=(uint64*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong8(ma);
+#if defined(__WIN32__) && (_MSC_VER < 1500)
+					/*
+					 * XXX: MSVC 6.0 does not support
+					 * conversion of 64-bit integers into
+					 * floating point values.
+					 */
+					*mb++ = _TIFFUInt64ToFloat(*ma++);
+#else
+					*mb++ = (float)(*ma++);
+#endif
+				}
+			}
+			break;
+		case TIFF_SLONG8:
+			{
+				int64* ma;
+				float* mb;
+				uint32 n;
+				ma=(int64*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong8((uint64*)ma);
+					*mb++=(float)(*ma++);
+				}
+			}
+			break;
+		case TIFF_RATIONAL:
+			{
+				uint32* ma;
+				uint32 maa;
+				uint32 mab;
+				float* mb;
+				uint32 n;
+				ma=(uint32*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong(ma);
+					maa=*ma++;
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong(ma);
+					mab=*ma++;
+					if (mab==0)
+						*mb++=0.0;
+					else
+						*mb++=(float)maa/(float)mab;
+				}
+			}
+			break;
+		case TIFF_SRATIONAL:
+			{
+				uint32* ma;
+				int32 maa;
+				uint32 mab;
+				float* mb;
+				uint32 n;
+				ma=(uint32*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong(ma);
+					maa=*(int32*)ma;
+					ma++;
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong(ma);
+					mab=*ma++;
+					if (mab==0)
+						*mb++=0.0;
+					else
+						*mb++=(float)maa/(float)mab;
+				}
+			}
+			break;
+		case TIFF_DOUBLE:
+			{
+				double* ma;
+				float* mb;
+				uint32 n;
+				if (tif->tif_flags&TIFF_SWAB)
+					TIFFSwabArrayOfLong8((uint64*)origdata,count);
+				TIFFCvtIEEEDoubleToNative(tif,count,(double*)origdata);
+				ma=(double*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+					*mb++=(float)(*ma++);
+			}
+			break;
+	}
+	_TIFFfree(origdata);
+	if (err!=TIFFReadDirEntryErrOk)
+	{
+		_TIFFfree(data);
+		return(err);
+	}
+	*value=data;
+	return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryDoubleArray(TIFF* tif, TIFFDirEntry* direntry, double** value)
+{
+	enum TIFFReadDirEntryErr err;
+	uint32 count;
+	void* origdata;
+	double* data;
+	switch (direntry->tdir_type)
+	{
+		case TIFF_BYTE:
+		case TIFF_SBYTE:
+		case TIFF_SHORT:
+		case TIFF_SSHORT:
+		case TIFF_LONG:
+		case TIFF_SLONG:
+		case TIFF_LONG8:
+		case TIFF_SLONG8:
+		case TIFF_RATIONAL:
+		case TIFF_SRATIONAL:
+		case TIFF_FLOAT:
+		case TIFF_DOUBLE:
+			break;
+		default:
+			return(TIFFReadDirEntryErrType);
+	}
+	err=TIFFReadDirEntryArray(tif,direntry,&count,8,&origdata);
+	if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
+	{
+		*value=0;
+		return(err);
+	}
+	switch (direntry->tdir_type)
+	{
+		case TIFF_DOUBLE:
+			if (tif->tif_flags&TIFF_SWAB)
+				TIFFSwabArrayOfLong8((uint64*)origdata,count);
+			TIFFCvtIEEEDoubleToNative(tif,count,(double*)origdata);
+			*value=(double*)origdata;
+			return(TIFFReadDirEntryErrOk);
+	}
+	data=(double*)_TIFFmalloc(count*sizeof(double));
+	if (data==0)
+	{
+		_TIFFfree(origdata);
+		return(TIFFReadDirEntryErrAlloc);
+	}
+	switch (direntry->tdir_type)
+	{
+		case TIFF_BYTE:
+			{
+				uint8* ma;
+				double* mb;
+				uint32 n;
+				ma=(uint8*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+					*mb++=(double)(*ma++);
+			}
+			break;
+		case TIFF_SBYTE:
+			{
+				int8* ma;
+				double* mb;
+				uint32 n;
+				ma=(int8*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+					*mb++=(double)(*ma++);
+			}
+			break;
+		case TIFF_SHORT:
+			{
+				uint16* ma;
+				double* mb;
+				uint32 n;
+				ma=(uint16*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabShort(ma);
+					*mb++=(double)(*ma++);
+				}
+			}
+			break;
+		case TIFF_SSHORT:
+			{
+				int16* ma;
+				double* mb;
+				uint32 n;
+				ma=(int16*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabShort((uint16*)ma);
+					*mb++=(double)(*ma++);
+				}
+			}
+			break;
+		case TIFF_LONG:
+			{
+				uint32* ma;
+				double* mb;
+				uint32 n;
+				ma=(uint32*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong(ma);
+					*mb++=(double)(*ma++);
+				}
+			}
+			break;
+		case TIFF_SLONG:
+			{
+				int32* ma;
+				double* mb;
+				uint32 n;
+				ma=(int32*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong((uint32*)ma);
+					*mb++=(double)(*ma++);
+				}
+			}
+			break;
+		case TIFF_LONG8:
+			{
+				uint64* ma;
+				double* mb;
+				uint32 n;
+				ma=(uint64*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong8(ma);
+#if defined(__WIN32__) && (_MSC_VER < 1500)
+					/*
+					 * XXX: MSVC 6.0 does not support
+					 * conversion of 64-bit integers into
+					 * floating point values.
+					 */
+					*mb++ = _TIFFUInt64ToDouble(*ma++);
+#else
+					*mb++ = (double)(*ma++);
+#endif
+				}
+			}
+			break;
+		case TIFF_SLONG8:
+			{
+				int64* ma;
+				double* mb;
+				uint32 n;
+				ma=(int64*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong8((uint64*)ma);
+					*mb++=(double)(*ma++);
+				}
+			}
+			break;
+		case TIFF_RATIONAL:
+			{
+				uint32* ma;
+				uint32 maa;
+				uint32 mab;
+				double* mb;
+				uint32 n;
+				ma=(uint32*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong(ma);
+					maa=*ma++;
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong(ma);
+					mab=*ma++;
+					if (mab==0)
+						*mb++=0.0;
+					else
+						*mb++=(double)maa/(double)mab;
+				}
+			}
+			break;
+		case TIFF_SRATIONAL:
+			{
+				uint32* ma;
+				int32 maa;
+				uint32 mab;
+				double* mb;
+				uint32 n;
+				ma=(uint32*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong(ma);
+					maa=*(int32*)ma;
+					ma++;
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong(ma);
+					mab=*ma++;
+					if (mab==0)
+						*mb++=0.0;
+					else
+						*mb++=(double)maa/(double)mab;
+				}
+			}
+			break;
+		case TIFF_FLOAT:
+			{
+				float* ma;
+				double* mb;
+				uint32 n;
+				if (tif->tif_flags&TIFF_SWAB)
+					TIFFSwabArrayOfLong((uint32*)origdata,count);  
+				TIFFCvtIEEEFloatToNative(tif,count,(float*)origdata);
+				ma=(float*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+					*mb++=(double)(*ma++);
+			}
+			break;
+	}
+	_TIFFfree(origdata);
+	if (err!=TIFFReadDirEntryErrOk)
+	{
+		_TIFFfree(data);
+		return(err);
+	}
+	*value=data;
+	return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8Array(TIFF* tif, TIFFDirEntry* direntry, uint64** value)
+{
+	enum TIFFReadDirEntryErr err;
+	uint32 count;
+	void* origdata;
+	uint64* data;
+	switch (direntry->tdir_type)
+	{
+		case TIFF_LONG:
+		case TIFF_LONG8:
+		case TIFF_IFD:
+		case TIFF_IFD8:
+			break;
+		default:
+			return(TIFFReadDirEntryErrType);
+	}
+	err=TIFFReadDirEntryArray(tif,direntry,&count,8,&origdata);
+	if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
+	{
+		*value=0;
+		return(err);
+	}
+	switch (direntry->tdir_type)
+	{
+		case TIFF_LONG8:
+		case TIFF_IFD8:
+			*value=(uint64*)origdata;
+			if (tif->tif_flags&TIFF_SWAB)
+				TIFFSwabArrayOfLong8(*value,count);
+			return(TIFFReadDirEntryErrOk);
+	}
+	data=(uint64*)_TIFFmalloc(count*8);
+	if (data==0)
+	{
+		_TIFFfree(origdata);
+		return(TIFFReadDirEntryErrAlloc);
+	}
+	switch (direntry->tdir_type)
+	{
+		case TIFF_LONG:
+		case TIFF_IFD:
+			{
+				uint32* ma;
+				uint64* mb;
+				uint32 n;
+				ma=(uint32*)origdata;
+				mb=data;
+				for (n=0; n<count; n++)
+				{
+					if (tif->tif_flags&TIFF_SWAB)
+						TIFFSwabLong(ma);
+					*mb++=(uint64)(*ma++);
+				}
+			}
+			break;
+	}
+	_TIFFfree(origdata);
+	if (err!=TIFFReadDirEntryErrOk)
+	{
+		_TIFFfree(data);
+		return(err);
+	}
+	*value=data;
+	return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryPersampleShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value)
+{
+	enum TIFFReadDirEntryErr err;
+	uint16* m;
+	uint16* na;
+	uint16 nb;
+	if (direntry->tdir_count<(uint64)tif->tif_dir.td_samplesperpixel)
+		return(TIFFReadDirEntryErrCount);
+	err=TIFFReadDirEntryShortArray(tif,direntry,&m);
+	if (err!=TIFFReadDirEntryErrOk)
+		return(err);
+	na=m;
+	nb=tif->tif_dir.td_samplesperpixel;
+	*value=*na++;
+	nb--;
+	while (nb>0)
+	{
+		if (*na++!=*value)
+		{
+			err=TIFFReadDirEntryErrPsdif;
+			break;
+		}
+		nb--;
+	}
+	_TIFFfree(m);
+	return(err);
+}
+
+#if 0
+static enum TIFFReadDirEntryErr TIFFReadDirEntryPersampleDouble(TIFF* tif, TIFFDirEntry* direntry, double* value)
+{
+	enum TIFFReadDirEntryErr err;
+	double* m;
+	double* na;
+	uint16 nb;
+	if (direntry->tdir_count<(uint64)tif->tif_dir.td_samplesperpixel)
+		return(TIFFReadDirEntryErrCount);
+	err=TIFFReadDirEntryDoubleArray(tif,direntry,&m);
+	if (err!=TIFFReadDirEntryErrOk)
+		return(err);
+	na=m;
+	nb=tif->tif_dir.td_samplesperpixel;
+	*value=*na++;
+	nb--;
+	while (nb>0)
+	{
+		if (*na++!=*value)
+		{
+			err=TIFFReadDirEntryErrPsdif;
+			break;
+		}
+		nb--;
+	}
+	_TIFFfree(m);
+	return(err);
+}
+#endif
+
+static void TIFFReadDirEntryCheckedByte(TIFF* tif, TIFFDirEntry* direntry, uint8* value)
+{
+	(void) tif;
+	*value=*(uint8*)(&direntry->tdir_offset);
+}
+
+static void TIFFReadDirEntryCheckedSbyte(TIFF* tif, TIFFDirEntry* direntry, int8* value)
+{
+	(void) tif;
+	*value=*(int8*)(&direntry->tdir_offset);
+}
+
+static void TIFFReadDirEntryCheckedShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value)
+{
+	*value = direntry->tdir_offset.toff_short;
+	/* *value=*(uint16*)(&direntry->tdir_offset); */
+	if (tif->tif_flags&TIFF_SWAB)
+		TIFFSwabShort(value);
+}
+
+static void TIFFReadDirEntryCheckedSshort(TIFF* tif, TIFFDirEntry* direntry, int16* value)
+{
+	*value=*(int16*)(&direntry->tdir_offset);
+	if (tif->tif_flags&TIFF_SWAB)
+		TIFFSwabShort((uint16*)value);
+}
+
+static void TIFFReadDirEntryCheckedLong(TIFF* tif, TIFFDirEntry* direntry, uint32* value)
+{
+	*value=*(uint32*)(&direntry->tdir_offset);
+	if (tif->tif_flags&TIFF_SWAB)
+		TIFFSwabLong(value);
+}
+
+static void TIFFReadDirEntryCheckedSlong(TIFF* tif, TIFFDirEntry* direntry, int32* value)
+{
+	*value=*(int32*)(&direntry->tdir_offset);
+	if (tif->tif_flags&TIFF_SWAB)
+		TIFFSwabLong((uint32*)value);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedLong8(TIFF* tif, TIFFDirEntry* direntry, uint64* value)
+{
+	if (!(tif->tif_flags&TIFF_BIGTIFF))
+	{
+		enum TIFFReadDirEntryErr err;
+		uint32 offset = direntry->tdir_offset.toff_long;
+		if (tif->tif_flags&TIFF_SWAB)
+			TIFFSwabLong(&offset);
+		err=TIFFReadDirEntryData(tif,offset,8,value);
+		if (err!=TIFFReadDirEntryErrOk)
+			return(err);
+	}
+	else
+		*value = direntry->tdir_offset.toff_long8;
+	if (tif->tif_flags&TIFF_SWAB)
+		TIFFSwabLong8(value);
+	return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSlong8(TIFF* tif, TIFFDirEntry* direntry, int64* value)
+{
+	if (!(tif->tif_flags&TIFF_BIGTIFF))
+	{
+		enum TIFFReadDirEntryErr err;
+		uint32 offset = direntry->tdir_offset.toff_long;
+		if (tif->tif_flags&TIFF_SWAB)
+			TIFFSwabLong(&offset);
+		err=TIFFReadDirEntryData(tif,offset,8,value);
+		if (err!=TIFFReadDirEntryErrOk)
+			return(err);
+	}
+	else
+		*value=*(int64*)(&direntry->tdir_offset);
+	if (tif->tif_flags&TIFF_SWAB)
+		TIFFSwabLong8((uint64*)value);
+	return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedRational(TIFF* tif, TIFFDirEntry* direntry, double* value)
+{
+	UInt64Aligned_t m;
+
+	assert(sizeof(double)==8);
+	assert(sizeof(uint64)==8);
+	assert(sizeof(uint32)==4);
+	if (!(tif->tif_flags&TIFF_BIGTIFF))
+	{
+		enum TIFFReadDirEntryErr err;
+		uint32 offset = direntry->tdir_offset.toff_long;
+		if (tif->tif_flags&TIFF_SWAB)
+			TIFFSwabLong(&offset);
+		err=TIFFReadDirEntryData(tif,offset,8,m.i);
+		if (err!=TIFFReadDirEntryErrOk)
+			return(err);
+	}
+	else
+		m.l = direntry->tdir_offset.toff_long8;
+	if (tif->tif_flags&TIFF_SWAB)
+		TIFFSwabArrayOfLong(m.i,2);
+	if (m.i[0]==0)
+		*value=0.0;
+	else
+		*value=(double)m.i[0]/(double)m.i[1];
+	return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSrational(TIFF* tif, TIFFDirEntry* direntry, double* value)
+{
+	UInt64Aligned_t m;
+	assert(sizeof(double)==8);
+	assert(sizeof(uint64)==8);
+	assert(sizeof(int32)==4);
+	assert(sizeof(uint32)==4);
+	if (!(tif->tif_flags&TIFF_BIGTIFF))
+	{
+		enum TIFFReadDirEntryErr err;
+		uint32 offset = direntry->tdir_offset.toff_long;
+		if (tif->tif_flags&TIFF_SWAB)
+			TIFFSwabLong(&offset);
+		err=TIFFReadDirEntryData(tif,offset,8,m.i);
+		if (err!=TIFFReadDirEntryErrOk)
+			return(err);
+	}
+	else
+		m.l=direntry->tdir_offset.toff_long8;
+	if (tif->tif_flags&TIFF_SWAB)
+		TIFFSwabArrayOfLong(m.i,2);
+	if ((int32)m.i[0]==0)
+		*value=0.0;
+	else
+		*value=(double)((int32)m.i[0])/(double)m.i[1];
+	return(TIFFReadDirEntryErrOk);
+}
+
+static void TIFFReadDirEntryCheckedFloat(TIFF* tif, TIFFDirEntry* direntry, float* value)
+{
+         union
+	 {
+	   float  f;
+	   uint32 i;
+	 } float_union;
+	assert(sizeof(float)==4);
+	assert(sizeof(uint32)==4);
+	assert(sizeof(float_union)==4);
+	float_union.i=*(uint32*)(&direntry->tdir_offset);
+	*value=float_union.f;
+	if (tif->tif_flags&TIFF_SWAB)
+		TIFFSwabLong((uint32*)value);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedDouble(TIFF* tif, TIFFDirEntry* direntry, double* value)
+{
+	assert(sizeof(double)==8);
+	assert(sizeof(uint64)==8);
+	assert(sizeof(UInt64Aligned_t)==8);
+	if (!(tif->tif_flags&TIFF_BIGTIFF))
+	{
+		enum TIFFReadDirEntryErr err;
+		uint32 offset = direntry->tdir_offset.toff_long;
+		if (tif->tif_flags&TIFF_SWAB)
+			TIFFSwabLong(&offset);
+		err=TIFFReadDirEntryData(tif,offset,8,value);
+		if (err!=TIFFReadDirEntryErrOk)
+			return(err);
+	}
+	else
+	{
+	       UInt64Aligned_t uint64_union;
+	       uint64_union.l=direntry->tdir_offset.toff_long8;
+	       *value=uint64_union.d;
+	}
+	if (tif->tif_flags&TIFF_SWAB)
+		TIFFSwabLong8((uint64*)value);
+	return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSbyte(int8 value)
+{
+	if (value<0)
+		return(TIFFReadDirEntryErrRange);
+	else
+		return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteShort(uint16 value)
+{
+	if (value>0xFF)
+		return(TIFFReadDirEntryErrRange);
+	else
+		return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSshort(int16 value)
+{
+	if ((value<0)||(value>0xFF))
+		return(TIFFReadDirEntryErrRange);
+	else
+		return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteLong(uint32 value)
+{
+	if (value>0xFF)
+		return(TIFFReadDirEntryErrRange);
+	else
+		return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSlong(int32 value)
+{
+	if ((value<0)||(value>0xFF))
+		return(TIFFReadDirEntryErrRange);
+	else
+		return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteLong8(uint64 value)
+{
+	if (value>0xFF)
+		return(TIFFReadDirEntryErrRange);
+	else
+		return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSlong8(int64 value)
+{
+	if ((value<0)||(value>0xFF))
+		return(TIFFReadDirEntryErrRange);
+	else
+		return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteByte(uint8 value)
+{
+	if (value>0x7F)
+		return(TIFFReadDirEntryErrRange);
+	else
+		return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteShort(uint16 value)
+{
+	if (value>0x7F)
+		return(TIFFReadDirEntryErrRange);
+	else
+		return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSshort(int16 value)
+{
+	if ((value<-0x80)||(value>0x7F))
+		return(TIFFReadDirEntryErrRange);
+	else
+		return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteLong(uint32 value)
+{
+	if (value>0x7F)
+		return(TIFFReadDirEntryErrRange);
+	else
+		return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSlong(int32 value)
+{
+	if ((value<-0x80)||(value>0x7F))
+		return(TIFFReadDirEntryErrRange);
+	else
+		return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteLong8(uint64 value)
+{
+	if (value>0x7F)
+		return(TIFFReadDirEntryErrRange);
+	else
+		return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSlong8(int64 value)
+{
+	if ((value<-0x80)||(value>0x7F))
+		return(TIFFReadDirEntryErrRange);
+	else
+		return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSbyte(int8 value)
+{
+	if (value<0)
+		return(TIFFReadDirEntryErrRange);
+	else
+		return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSshort(int16 value)
+{
+	if (value<0)
+		return(TIFFReadDirEntryErrRange);
+	else
+		return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortLong(uint32 value)
+{
+	if (value>0xFFFF)
+		return(TIFFReadDirEntryErrRange);
+	else
+		return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSlong(int32 value)
+{
+	if ((value<0)||(value>0xFFFF))
+		return(TIFFReadDirEntryErrRange);
+	else
+		return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortLong8(uint64 value)
+{
+	if (value>0xFFFF)
+		return(TIFFReadDirEntryErrRange);
+	else
+		return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSlong8(int64 value)
+{
+	if ((value<0)||(value>0xFFFF))
+		return(TIFFReadDirEntryErrRange);
+	else
+		return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortShort(uint16 value)
+{
+	if (value>0x7FFF)
+		return(TIFFReadDirEntryErrRange);
+	else
+		return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortLong(uint32 value)
+{
+	if (value>0x7FFF)
+		return(TIFFReadDirEntryErrRange);
+	else
+		return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortSlong(int32 value)
+{
+	if ((value<-0x8000)||(value>0x7FFF))
+		return(TIFFReadDirEntryErrRange);
+	else
+		return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortLong8(uint64 value)
+{
+	if (value>0x7FFF)
+		return(TIFFReadDirEntryErrRange);
+	else
+		return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortSlong8(int64 value)
+{
+	if ((value<-0x8000)||(value>0x7FFF))
+		return(TIFFReadDirEntryErrRange);
+	else
+		return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSbyte(int8 value)
+{
+	if (value<0)
+		return(TIFFReadDirEntryErrRange);
+	else
+		return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSshort(int16 value)
+{
+	if (value<0)
+		return(TIFFReadDirEntryErrRange);
+	else
+		return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSlong(int32 value)
+{
+	if (value<0)
+		return(TIFFReadDirEntryErrRange);
+	else
+		return(TIFFReadDirEntryErrOk);
+}
+
+/*
+ * Largest 32-bit unsigned integer value.
+ */
+#if defined(__WIN32__) && defined(_MSC_VER)
+# define TIFF_UINT32_MAX 0xFFFFFFFFI64
+#else
+# define TIFF_UINT32_MAX 0xFFFFFFFFLL
+#endif
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeLongLong8(uint64 value)
+{
+	if (value > TIFF_UINT32_MAX)
+		return(TIFFReadDirEntryErrRange);
+	else
+		return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeLongSlong8(int64 value)
+{
+	if ((value<0) || (value > TIFF_UINT32_MAX))
+		return(TIFFReadDirEntryErrRange);
+	else
+		return(TIFFReadDirEntryErrOk);
+}
+
+#undef TIFF_UINT32_MAX
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeSlongLong(uint32 value)
+{
+	if (value > 0x7FFFFFFFUL)
+		return(TIFFReadDirEntryErrRange);
+	else
+		return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeSlongLong8(uint64 value)
+{
+	if (value > 0x7FFFFFFFUL)
+		return(TIFFReadDirEntryErrRange);
+	else
+		return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeSlongSlong8(int64 value)
+{
+	if ((value < 0L-0x80000000L) || (value > 0x7FFFFFFFL))
+		return(TIFFReadDirEntryErrRange);
+	else
+		return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeLong8Sbyte(int8 value)
+{
+	if (value < 0)
+		return(TIFFReadDirEntryErrRange);
+	else
+		return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeLong8Sshort(int16 value)
+{
+	if (value < 0)
+		return(TIFFReadDirEntryErrRange);
+	else
+		return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeLong8Slong(int32 value)
+{
+	if (value < 0)
+		return(TIFFReadDirEntryErrRange);
+	else
+		return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeLong8Slong8(int64 value)
+{
+	if (value < 0)
+		return(TIFFReadDirEntryErrRange);
+	else
+		return(TIFFReadDirEntryErrOk);
+}
+
+/*
+ * Largest 64-bit signed integer value.
+ */
+#if defined(__WIN32__) && defined(_MSC_VER)
+# define TIFF_INT64_MAX 0x7FFFFFFFFFFFFFFFI64
+#else
+# define TIFF_INT64_MAX 0x7FFFFFFFFFFFFFFFLL
+#endif
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeSlong8Long8(uint64 value)
+{
+	if (value > TIFF_INT64_MAX)
+		return(TIFFReadDirEntryErrRange);
+	else
+		return(TIFFReadDirEntryErrOk);
+}
+
+#undef TIFF_INT64_MAX
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryData(TIFF* tif, uint64 offset, tmsize_t size, void* dest)
+{
+	assert(size>0);
+	if (!isMapped(tif)) {
+		if (!SeekOK(tif,offset))
+			return(TIFFReadDirEntryErrIo);
+		if (!ReadOK(tif,dest,size))
+			return(TIFFReadDirEntryErrIo);
+	} else {
+		size_t ma,mb;
+		ma=(size_t)offset;
+		mb=ma+size;
+		if (((uint64)ma!=offset)
+		    || (mb < ma)
+		    || (mb - ma != (size_t) size)
+		    || (mb < (size_t)size)
+		    || (mb > (size_t)tif->tif_size)
+		    )
+			return(TIFFReadDirEntryErrIo);
+		_TIFFmemcpy(dest,tif->tif_base+ma,size);
+	}
+	return(TIFFReadDirEntryErrOk);
+}
+
+static void TIFFReadDirEntryOutputErr(TIFF* tif, enum TIFFReadDirEntryErr err, const char* module, const char* tagname, int recover)
+{
+	if (!recover) {
+		switch (err) {
+			case TIFFReadDirEntryErrCount:
+				TIFFErrorExt(tif->tif_clientdata, module,
+					     "Incorrect count for \"%s\"",
+					     tagname);
+				break;
+			case TIFFReadDirEntryErrType:
+				TIFFErrorExt(tif->tif_clientdata, module,
+					     "Incompatible type for \"%s\"",
+					     tagname);
+				break;
+			case TIFFReadDirEntryErrIo:
+				TIFFErrorExt(tif->tif_clientdata, module,
+					     "IO error during reading of \"%s\"",
+					     tagname);
+				break;
+			case TIFFReadDirEntryErrRange:
+				TIFFErrorExt(tif->tif_clientdata, module,
+					     "Incorrect value for \"%s\"",
+					     tagname);
+				break;
+			case TIFFReadDirEntryErrPsdif:
+				TIFFErrorExt(tif->tif_clientdata, module,
+			"Cannot handle different values per sample for \"%s\"",
+					     tagname);
+				break;
+			case TIFFReadDirEntryErrSizesan:
+				TIFFErrorExt(tif->tif_clientdata, module,
+				"Sanity check on size of \"%s\" value failed",
+					     tagname);
+				break;
+			case TIFFReadDirEntryErrAlloc:
+				TIFFErrorExt(tif->tif_clientdata, module,
+					     "Out of memory reading of \"%s\"",
+					     tagname);
+				break;
+			default:
+				assert(0);   /* we should never get here */
+				break;
+		}
+	} else {
+		switch (err) {
+			case TIFFReadDirEntryErrCount:
+				TIFFWarningExt(tif->tif_clientdata, module,
+				"Incorrect count for \"%s\"; tag ignored",
+					     tagname);
+				break;
+			case TIFFReadDirEntryErrType:
+				TIFFWarningExt(tif->tif_clientdata, module,
+				"Incompatible type for \"%s\"; tag ignored",
+					       tagname);
+				break;
+			case TIFFReadDirEntryErrIo:
+				TIFFWarningExt(tif->tif_clientdata, module,
+			"IO error during reading of \"%s\"; tag ignored",
+					       tagname);
+				break;
+			case TIFFReadDirEntryErrRange:
+				TIFFWarningExt(tif->tif_clientdata, module,
+				"Incorrect value for \"%s\"; tag ignored",
+					       tagname);
+				break;
+			case TIFFReadDirEntryErrPsdif:
+				TIFFWarningExt(tif->tif_clientdata, module,
+	"Cannot handle different values per sample for \"%s\"; tag ignored",
+					       tagname);
+				break;
+			case TIFFReadDirEntryErrSizesan:
+				TIFFWarningExt(tif->tif_clientdata, module,
+		"Sanity check on size of \"%s\" value failed; tag ignored",
+					       tagname);
+				break;
+			case TIFFReadDirEntryErrAlloc:
+				TIFFWarningExt(tif->tif_clientdata, module,
+				"Out of memory reading of \"%s\"; tag ignored",
+					       tagname);
+				break;
+			default:
+				assert(0);   /* we should never get here */
+				break;
+		}
+	}
+}
+
+/*
+ * Read the next TIFF directory from a file and convert it to the internal
+ * format. We read directories sequentially.
+ */
+int
+TIFFReadDirectory(TIFF* tif)
+{
+	static const char module[] = "TIFFReadDirectory";
+	TIFFDirEntry* dir;
+	uint16 dircount;
+	TIFFDirEntry* dp;
+	uint16 di;
+	const TIFFField* fip;
+	uint32 fii=FAILED_FII;
+        toff_t nextdiroff;
+    int bitspersample_read = FALSE;
+
+	tif->tif_diroff=tif->tif_nextdiroff;
+	if (!TIFFCheckDirOffset(tif,tif->tif_nextdiroff))
+		return 0;           /* last offset or bad offset (IFD looping) */
+	(*tif->tif_cleanup)(tif);   /* cleanup any previous compression state */
+	tif->tif_curdir++;
+        nextdiroff = tif->tif_nextdiroff;
+	dircount=TIFFFetchDirectory(tif,nextdiroff,&dir,&tif->tif_nextdiroff);
+	if (!dircount)
+	{
+		TIFFErrorExt(tif->tif_clientdata,module,
+		    "Failed to read directory at offset " TIFF_UINT64_FORMAT,nextdiroff);
+		return 0;
+	}
+	TIFFReadDirectoryCheckOrder(tif,dir,dircount);
+
+        /*
+         * Mark duplicates of any tag to be ignored (bugzilla 1994)
+         * to avoid certain pathological problems.
+         */
+	{
+		TIFFDirEntry* ma;
+		uint16 mb;
+		for (ma=dir, mb=0; mb<dircount; ma++, mb++)
+		{
+			TIFFDirEntry* na;
+			uint16 nb;
+			for (na=ma+1, nb=mb+1; nb<dircount; na++, nb++)
+			{
+				if (ma->tdir_tag==na->tdir_tag)
+					na->tdir_tag=IGNORE;
+			}
+		}
+	}
+        
+	tif->tif_flags &= ~TIFF_BEENWRITING;    /* reset before new dir */
+	tif->tif_flags &= ~TIFF_BUF4WRITE;      /* reset before new dir */
+	/* free any old stuff and reinit */
+	TIFFFreeDirectory(tif);
+	TIFFDefaultDirectory(tif);
+	/*
+	 * Electronic Arts writes gray-scale TIFF files
+	 * without a PlanarConfiguration directory entry.
+	 * Thus we setup a default value here, even though
+	 * the TIFF spec says there is no default value.
+	 */
+	TIFFSetField(tif,TIFFTAG_PLANARCONFIG,PLANARCONFIG_CONTIG);
+	/*
+	 * Setup default value and then make a pass over
+	 * the fields to check type and tag information,
+	 * and to extract info required to size data
+	 * structures.  A second pass is made afterwards
+	 * to read in everthing not taken in the first pass.
+	 * But we must process the Compression tag first
+	 * in order to merge in codec-private tag definitions (otherwise
+	 * we may get complaints about unknown tags).  However, the
+	 * Compression tag may be dependent on the SamplesPerPixel
+	 * tag value because older TIFF specs permited Compression
+	 * to be written as a SamplesPerPixel-count tag entry.
+	 * Thus if we don't first figure out the correct SamplesPerPixel
+	 * tag value then we may end up ignoring the Compression tag
+	 * value because it has an incorrect count value (if the
+	 * true value of SamplesPerPixel is not 1).
+	 */
+	dp=TIFFReadDirectoryFindEntry(tif,dir,dircount,TIFFTAG_SAMPLESPERPIXEL);
+	if (dp)
+	{
+		if (!TIFFFetchNormalTag(tif,dp,0))
+			goto bad;
+		dp->tdir_tag=IGNORE;
+	}
+	dp=TIFFReadDirectoryFindEntry(tif,dir,dircount,TIFFTAG_COMPRESSION);
+	if (dp)
+	{
+		/*
+		 * The 5.0 spec says the Compression tag has one value, while
+		 * earlier specs say it has one value per sample.  Because of
+		 * this, we accept the tag if one value is supplied with either
+		 * count.
+		 */
+		uint16 value;
+		enum TIFFReadDirEntryErr err;
+		err=TIFFReadDirEntryShort(tif,dp,&value);
+		if (err==TIFFReadDirEntryErrCount)
+			err=TIFFReadDirEntryPersampleShort(tif,dp,&value);
+		if (err!=TIFFReadDirEntryErrOk)
+		{
+			TIFFReadDirEntryOutputErr(tif,err,module,"Compression",0);
+			goto bad;
+		}
+		if (!TIFFSetField(tif,TIFFTAG_COMPRESSION,value))
+			goto bad;
+		dp->tdir_tag=IGNORE;
+	}
+	else
+	{
+		if (!TIFFSetField(tif,TIFFTAG_COMPRESSION,COMPRESSION_NONE))
+			goto bad;
+	}
+	/*
+	 * First real pass over the directory.
+	 */
+	for (di=0, dp=dir; di<dircount; di++, dp++)
+	{
+		if (dp->tdir_tag!=IGNORE)
+		{
+			TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii);
+			if (fii == FAILED_FII)
+			{
+				TIFFWarningExt(tif->tif_clientdata, module,
+				    "Unknown field with tag %d (0x%x) encountered",
+				    dp->tdir_tag,dp->tdir_tag);
+                                /* the following knowingly leaks the 
+                                   anonymous field structure */
+				if (!_TIFFMergeFields(tif,
+					_TIFFCreateAnonField(tif,
+						dp->tdir_tag,
+						(TIFFDataType) dp->tdir_type),
+					1)) {
+					TIFFWarningExt(tif->tif_clientdata,
+					    module,
+					    "Registering anonymous field with tag %d (0x%x) failed",
+					    dp->tdir_tag,
+					    dp->tdir_tag);
+					dp->tdir_tag=IGNORE;
+				} else {
+					TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii);
+					assert(fii != FAILED_FII);
+				}
+			}
+		}
+		if (dp->tdir_tag!=IGNORE)
+		{
+			fip=tif->tif_fields[fii];
+			if (fip->field_bit==FIELD_IGNORE)
+				dp->tdir_tag=IGNORE;
+			else
+			{
+				switch (dp->tdir_tag)
+				{
+					case TIFFTAG_STRIPOFFSETS:
+					case TIFFTAG_STRIPBYTECOUNTS:
+					case TIFFTAG_TILEOFFSETS:
+					case TIFFTAG_TILEBYTECOUNTS:
+						TIFFSetFieldBit(tif,fip->field_bit);
+						break;
+					case TIFFTAG_IMAGEWIDTH:
+					case TIFFTAG_IMAGELENGTH:
+					case TIFFTAG_IMAGEDEPTH:
+					case TIFFTAG_TILELENGTH:
+					case TIFFTAG_TILEWIDTH:
+					case TIFFTAG_TILEDEPTH:
+					case TIFFTAG_PLANARCONFIG:
+					case TIFFTAG_ROWSPERSTRIP:
+					case TIFFTAG_EXTRASAMPLES:
+						if (!TIFFFetchNormalTag(tif,dp,0))
+							goto bad;
+						dp->tdir_tag=IGNORE;
+						break;
+				}
+			}
+		}
+	}
+	/*
+	 * XXX: OJPEG hack.
+	 * If a) compression is OJPEG, b) planarconfig tag says it's separate,
+	 * c) strip offsets/bytecounts tag are both present and
+	 * d) both contain exactly one value, then we consistently find
+	 * that the buggy implementation of the buggy compression scheme
+	 * matches contig planarconfig best. So we 'fix-up' the tag here
+	 */
+	if ((tif->tif_dir.td_compression==COMPRESSION_OJPEG)&&
+	    (tif->tif_dir.td_planarconfig==PLANARCONFIG_SEPARATE))
+	{
+        if (!_TIFFFillStriles(tif))
+            goto bad;
+		dp=TIFFReadDirectoryFindEntry(tif,dir,dircount,TIFFTAG_STRIPOFFSETS);
+		if ((dp!=0)&&(dp->tdir_count==1))
+		{
+			dp=TIFFReadDirectoryFindEntry(tif,dir,dircount,
+			    TIFFTAG_STRIPBYTECOUNTS);
+			if ((dp!=0)&&(dp->tdir_count==1))
+			{
+				tif->tif_dir.td_planarconfig=PLANARCONFIG_CONTIG;
+				TIFFWarningExt(tif->tif_clientdata,module,
+				    "Planarconfig tag value assumed incorrect, "
+				    "assuming data is contig instead of chunky");
+			}
+		}
+	}
+	/*
+	 * Allocate directory structure and setup defaults.
+	 */
+	if (!TIFFFieldSet(tif,FIELD_IMAGEDIMENSIONS))
+	{
+		MissingRequired(tif,"ImageLength");
+		goto bad;
+	}
+	/*
+	 * Setup appropriate structures (by strip or by tile)
+	 */
+	if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) {
+		tif->tif_dir.td_nstrips = TIFFNumberOfStrips(tif);  
+		tif->tif_dir.td_tilewidth = tif->tif_dir.td_imagewidth;
+		tif->tif_dir.td_tilelength = tif->tif_dir.td_rowsperstrip;
+		tif->tif_dir.td_tiledepth = tif->tif_dir.td_imagedepth;
+		tif->tif_flags &= ~TIFF_ISTILED;
+	} else {
+		tif->tif_dir.td_nstrips = TIFFNumberOfTiles(tif);
+		tif->tif_flags |= TIFF_ISTILED;
+	}
+	if (!tif->tif_dir.td_nstrips) {
+		TIFFErrorExt(tif->tif_clientdata, module,
+		    "Cannot handle zero number of %s",
+		    isTiled(tif) ? "tiles" : "strips");
+		goto bad;
+	}
+	tif->tif_dir.td_stripsperimage = tif->tif_dir.td_nstrips;
+	if (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE)
+		tif->tif_dir.td_stripsperimage /= tif->tif_dir.td_samplesperpixel;
+	if (!TIFFFieldSet(tif, FIELD_STRIPOFFSETS)) {
+		if ((tif->tif_dir.td_compression==COMPRESSION_OJPEG) &&
+		    (isTiled(tif)==0) &&
+		    (tif->tif_dir.td_nstrips==1)) {
+			/*
+			 * XXX: OJPEG hack.
+			 * If a) compression is OJPEG, b) it's not a tiled TIFF,
+			 * and c) the number of strips is 1,
+			 * then we tolerate the absence of stripoffsets tag,
+			 * because, presumably, all required data is in the
+			 * JpegInterchangeFormat stream.
+			 */
+			TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
+		} else {
+			MissingRequired(tif,
+				isTiled(tif) ? "TileOffsets" : "StripOffsets");
+			goto bad;
+		}
+	}
+	/*
+	 * Second pass: extract other information.
+	 */
+	for (di=0, dp=dir; di<dircount; di++, dp++)
+	{
+		switch (dp->tdir_tag)
+		{
+			case IGNORE:
+				break;
+			case TIFFTAG_MINSAMPLEVALUE:
+			case TIFFTAG_MAXSAMPLEVALUE:
+			case TIFFTAG_BITSPERSAMPLE:
+			case TIFFTAG_DATATYPE:
+			case TIFFTAG_SAMPLEFORMAT:
+				/*
+				 * The MinSampleValue, MaxSampleValue, BitsPerSample
+				 * DataType and SampleFormat tags are supposed to be
+				 * written as one value/sample, but some vendors
+				 * incorrectly write one value only -- so we accept
+				 * that as well (yech). Other vendors write correct
+				 * value for NumberOfSamples, but incorrect one for
+				 * BitsPerSample and friends, and we will read this
+				 * too.
+				 */
+				{
+					uint16 value;
+					enum TIFFReadDirEntryErr err;
+					err=TIFFReadDirEntryShort(tif,dp,&value);
+					if (err==TIFFReadDirEntryErrCount)
+						err=TIFFReadDirEntryPersampleShort(tif,dp,&value);
+					if (err!=TIFFReadDirEntryErrOk)
+					{
+						fip = TIFFFieldWithTag(tif,dp->tdir_tag);
+						TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",0);
+						goto bad;
+					}
+					if (!TIFFSetField(tif,dp->tdir_tag,value))
+						goto bad;
+                    if( dp->tdir_tag == TIFFTAG_BITSPERSAMPLE )
+                        bitspersample_read = TRUE;
+				}
+				break;
+			case TIFFTAG_SMINSAMPLEVALUE:
+			case TIFFTAG_SMAXSAMPLEVALUE:
+				{
+
+					double *data;
+					enum TIFFReadDirEntryErr err;
+					uint32 saved_flags;
+					int m;
+					if (dp->tdir_count != (uint64)tif->tif_dir.td_samplesperpixel)
+						err = TIFFReadDirEntryErrCount;
+					else
+						err = TIFFReadDirEntryDoubleArray(tif, dp, &data);
+					if (err!=TIFFReadDirEntryErrOk)
+					{
+						fip = TIFFFieldWithTag(tif,dp->tdir_tag);
+						TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",0);
+						goto bad;
+					}
+					saved_flags = tif->tif_flags;
+					tif->tif_flags |= TIFF_PERSAMPLE;
+					m = TIFFSetField(tif,dp->tdir_tag,data);
+					tif->tif_flags = saved_flags;
+					_TIFFfree(data);
+					if (!m)
+						goto bad;
+				}
+				break;
+			case TIFFTAG_STRIPOFFSETS:
+			case TIFFTAG_TILEOFFSETS:
+#if defined(DEFER_STRILE_LOAD)
+                                _TIFFmemcpy( &(tif->tif_dir.td_stripoffset_entry),
+                                             dp, sizeof(TIFFDirEntry) );
+#else                          
+				if (!TIFFFetchStripThing(tif,dp,tif->tif_dir.td_nstrips,&tif->tif_dir.td_stripoffset))  
+					goto bad;
+#endif                                
+				break;
+			case TIFFTAG_STRIPBYTECOUNTS:
+			case TIFFTAG_TILEBYTECOUNTS:
+#if defined(DEFER_STRILE_LOAD)
+                                _TIFFmemcpy( &(tif->tif_dir.td_stripbytecount_entry),
+                                             dp, sizeof(TIFFDirEntry) );
+#else                          
+				if (!TIFFFetchStripThing(tif,dp,tif->tif_dir.td_nstrips,&tif->tif_dir.td_stripbytecount))  
+					goto bad;
+#endif                                
+				break;
+			case TIFFTAG_COLORMAP:
+			case TIFFTAG_TRANSFERFUNCTION:
+				{
+					enum TIFFReadDirEntryErr err;
+					uint32 countpersample;
+					uint32 countrequired;
+					uint32 incrementpersample;
+					uint16* value=NULL;
+                    /* It would be dangerous to instanciate those tag values */
+                    /* since if td_bitspersample has not yet been read (due to */
+                    /* unordered tags), it could be read afterwards with a */
+                    /* values greater than the default one (1), which may cause */
+                    /* crashes in user code */
+                    if( !bitspersample_read )
+                    {
+                        fip = TIFFFieldWithTag(tif,dp->tdir_tag);
+                        TIFFWarningExt(tif->tif_clientdata,module,
+                                       "Ignoring %s since BitsPerSample tag not found",
+                                       fip ? fip->field_name : "unknown tagname");
+                        continue;
+                    }
+					countpersample=(1L<<tif->tif_dir.td_bitspersample);
+					if ((dp->tdir_tag==TIFFTAG_TRANSFERFUNCTION)&&(dp->tdir_count==(uint64)countpersample))
+					{
+						countrequired=countpersample;
+						incrementpersample=0;
+					}
+					else
+					{
+						countrequired=3*countpersample;
+						incrementpersample=countpersample;
+					}
+					if (dp->tdir_count!=(uint64)countrequired)
+						err=TIFFReadDirEntryErrCount;
+					else
+						err=TIFFReadDirEntryShortArray(tif,dp,&value);
+					if (err!=TIFFReadDirEntryErrOk)
+                    {
+						fip = TIFFFieldWithTag(tif,dp->tdir_tag);
+						TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",1);
+                    }
+					else
+					{
+						TIFFSetField(tif,dp->tdir_tag,value,value+incrementpersample,value+2*incrementpersample);
+						_TIFFfree(value);
+					}
+				}
+				break;
+/* BEGIN REV 4.0 COMPATIBILITY */
+			case TIFFTAG_OSUBFILETYPE:
+				{
+					uint16 valueo;
+					uint32 value;
+					if (TIFFReadDirEntryShort(tif,dp,&valueo)==TIFFReadDirEntryErrOk)
+					{
+						switch (valueo)
+						{
+							case OFILETYPE_REDUCEDIMAGE: value=FILETYPE_REDUCEDIMAGE; break;
+							case OFILETYPE_PAGE: value=FILETYPE_PAGE; break;
+							default: value=0; break;
+						}
+						if (value!=0)
+							TIFFSetField(tif,TIFFTAG_SUBFILETYPE,value);
+					}
+				}
+				break;
+/* END REV 4.0 COMPATIBILITY */
+			default:
+				(void) TIFFFetchNormalTag(tif, dp, TRUE);
+				break;
+		}
+	}
+	/*
+	 * OJPEG hack:
+	 * - If a) compression is OJPEG, and b) photometric tag is missing,
+	 * then we consistently find that photometric should be YCbCr
+	 * - If a) compression is OJPEG, and b) photometric tag says it's RGB,
+	 * then we consistently find that the buggy implementation of the
+	 * buggy compression scheme matches photometric YCbCr instead.
+	 * - If a) compression is OJPEG, and b) bitspersample tag is missing,
+	 * then we consistently find bitspersample should be 8.
+	 * - If a) compression is OJPEG, b) samplesperpixel tag is missing,
+	 * and c) photometric is RGB or YCbCr, then we consistently find
+	 * samplesperpixel should be 3
+	 * - If a) compression is OJPEG, b) samplesperpixel tag is missing,
+	 * and c) photometric is MINISWHITE or MINISBLACK, then we consistently
+	 * find samplesperpixel should be 3
+	 */
+	if (tif->tif_dir.td_compression==COMPRESSION_OJPEG)
+	{
+		if (!TIFFFieldSet(tif,FIELD_PHOTOMETRIC))
+		{
+			TIFFWarningExt(tif->tif_clientdata, module,
+			    "Photometric tag is missing, assuming data is YCbCr");
+			if (!TIFFSetField(tif,TIFFTAG_PHOTOMETRIC,PHOTOMETRIC_YCBCR))
+				goto bad;
+		}
+		else if (tif->tif_dir.td_photometric==PHOTOMETRIC_RGB)
+		{
+			tif->tif_dir.td_photometric=PHOTOMETRIC_YCBCR;
+			TIFFWarningExt(tif->tif_clientdata, module,
+			    "Photometric tag value assumed incorrect, "
+			    "assuming data is YCbCr instead of RGB");
+		}
+		if (!TIFFFieldSet(tif,FIELD_BITSPERSAMPLE))
+		{
+			TIFFWarningExt(tif->tif_clientdata,module,
+			    "BitsPerSample tag is missing, assuming 8 bits per sample");
+			if (!TIFFSetField(tif,TIFFTAG_BITSPERSAMPLE,8))
+				goto bad;
+		}
+		if (!TIFFFieldSet(tif,FIELD_SAMPLESPERPIXEL))
+		{
+			if (tif->tif_dir.td_photometric==PHOTOMETRIC_RGB)
+			{
+				TIFFWarningExt(tif->tif_clientdata,module,
+				    "SamplesPerPixel tag is missing, "
+				    "assuming correct SamplesPerPixel value is 3");
+				if (!TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,3))
+					goto bad;
+			}
+			if (tif->tif_dir.td_photometric==PHOTOMETRIC_YCBCR)
+			{
+				TIFFWarningExt(tif->tif_clientdata,module,
+				    "SamplesPerPixel tag is missing, "
+				    "applying correct SamplesPerPixel value of 3");
+				if (!TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,3))
+					goto bad;
+			}
+			else if ((tif->tif_dir.td_photometric==PHOTOMETRIC_MINISWHITE)
+				 || (tif->tif_dir.td_photometric==PHOTOMETRIC_MINISBLACK))
+			{
+				/*
+				 * SamplesPerPixel tag is missing, but is not required
+				 * by spec.  Assume correct SamplesPerPixel value of 1.
+				 */
+				if (!TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,1))
+					goto bad;
+			}
+		}
+	}
+	/*
+	 * Verify Palette image has a Colormap.
+	 */
+	if (tif->tif_dir.td_photometric == PHOTOMETRIC_PALETTE &&
+	    !TIFFFieldSet(tif, FIELD_COLORMAP)) {
+		if ( tif->tif_dir.td_bitspersample>=8 && tif->tif_dir.td_samplesperpixel==3)
+			tif->tif_dir.td_photometric = PHOTOMETRIC_RGB;
+		else if (tif->tif_dir.td_bitspersample>=8)
+			tif->tif_dir.td_photometric = PHOTOMETRIC_MINISBLACK;
+		else {
+			MissingRequired(tif, "Colormap");
+			goto bad;
+		}
+	}
+	/*
+	 * OJPEG hack:
+	 * We do no further messing with strip/tile offsets/bytecounts in OJPEG
+	 * TIFFs
+	 */
+	if (tif->tif_dir.td_compression!=COMPRESSION_OJPEG)
+	{
+		/*
+		 * Attempt to deal with a missing StripByteCounts tag.
+		 */
+		if (!TIFFFieldSet(tif, FIELD_STRIPBYTECOUNTS)) {
+			/*
+			 * Some manufacturers violate the spec by not giving
+			 * the size of the strips.  In this case, assume there
+			 * is one uncompressed strip of data.
+			 */
+			if ((tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG &&
+			    tif->tif_dir.td_nstrips > 1) ||
+			    (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE &&
+			     tif->tif_dir.td_nstrips != (uint32)tif->tif_dir.td_samplesperpixel)) {
+			    MissingRequired(tif, "StripByteCounts");
+			    goto bad;
+			}
+			TIFFWarningExt(tif->tif_clientdata, module,
+				"TIFF directory is missing required "
+				"\"StripByteCounts\" field, calculating from imagelength");
+			if (EstimateStripByteCounts(tif, dir, dircount) < 0)
+			    goto bad;
+		/*
+		 * Assume we have wrong StripByteCount value (in case
+		 * of single strip) in following cases:
+		 *   - it is equal to zero along with StripOffset;
+		 *   - it is larger than file itself (in case of uncompressed
+		 *     image);
+		 *   - it is smaller than the size of the bytes per row
+		 *     multiplied on the number of rows.  The last case should
+		 *     not be checked in the case of writing new image,
+		 *     because we may do not know the exact strip size
+		 *     until the whole image will be written and directory
+		 *     dumped out.
+		 */
+		#define	BYTECOUNTLOOKSBAD \
+		    ( (tif->tif_dir.td_stripbytecount[0] == 0 && tif->tif_dir.td_stripoffset[0] != 0) || \
+		      (tif->tif_dir.td_compression == COMPRESSION_NONE && \
+		       tif->tif_dir.td_stripbytecount[0] > TIFFGetFileSize(tif) - tif->tif_dir.td_stripoffset[0]) || \
+		      (tif->tif_mode == O_RDONLY && \
+		       tif->tif_dir.td_compression == COMPRESSION_NONE && \
+		       tif->tif_dir.td_stripbytecount[0] < TIFFScanlineSize64(tif) * tif->tif_dir.td_imagelength) )
+
+		} else if (tif->tif_dir.td_nstrips == 1
+                           && _TIFFFillStriles(tif)
+			   && tif->tif_dir.td_stripoffset[0] != 0
+			   && BYTECOUNTLOOKSBAD) {
+			/*
+			 * XXX: Plexus (and others) sometimes give a value of
+			 * zero for a tag when they don't know what the
+			 * correct value is!  Try and handle the simple case
+			 * of estimating the size of a one strip image.
+			 */
+			TIFFWarningExt(tif->tif_clientdata, module,
+			    "Bogus \"StripByteCounts\" field, ignoring and calculating from imagelength");
+			if(EstimateStripByteCounts(tif, dir, dircount) < 0)
+			    goto bad;
+
+#if !defined(DEFER_STRILE_LOAD)
+		} else if (tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG
+			   && tif->tif_dir.td_nstrips > 2
+			   && tif->tif_dir.td_compression == COMPRESSION_NONE
+			   && tif->tif_dir.td_stripbytecount[0] != tif->tif_dir.td_stripbytecount[1]
+			   && tif->tif_dir.td_stripbytecount[0] != 0
+			   && tif->tif_dir.td_stripbytecount[1] != 0 ) {
+			/*
+			 * XXX: Some vendors fill StripByteCount array with
+			 * absolutely wrong values (it can be equal to
+			 * StripOffset array, for example). Catch this case
+			 * here.
+                         *
+                         * We avoid this check if deferring strile loading
+                         * as it would always force us to load the strip/tile
+                         * information.
+			 */
+			TIFFWarningExt(tif->tif_clientdata, module,
+			    "Wrong \"StripByteCounts\" field, ignoring and calculating from imagelength");
+			if (EstimateStripByteCounts(tif, dir, dircount) < 0)
+			    goto bad;
+#endif /* !defined(DEFER_STRILE_LOAD) */                        
+		}
+	}
+	if (dir)
+	{
+		_TIFFfree(dir);
+		dir=NULL;
+	}
+	if (!TIFFFieldSet(tif, FIELD_MAXSAMPLEVALUE))
+	{
+		if (tif->tif_dir.td_bitspersample>=16)
+			tif->tif_dir.td_maxsamplevalue=0xFFFF;
+		else
+			tif->tif_dir.td_maxsamplevalue = (uint16)((1L<<tif->tif_dir.td_bitspersample)-1);
+	}
+	/*
+	 * XXX: We can optimize checking for the strip bounds using the sorted
+	 * bytecounts array. See also comments for TIFFAppendToStrip()
+	 * function in tif_write.c.
+	 */
+#if !defined(DEFER_STRILE_LOAD)        
+	if (tif->tif_dir.td_nstrips > 1) {
+		uint32 strip;
+
+		tif->tif_dir.td_stripbytecountsorted = 1;
+		for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++) {
+			if (tif->tif_dir.td_stripoffset[strip - 1] >
+			    tif->tif_dir.td_stripoffset[strip]) {
+				tif->tif_dir.td_stripbytecountsorted = 0;
+				break;
+			}
+		}
+	}
+#endif /* !defined(DEFER_STRILE_LOAD) */
+        
+	/*
+	 * An opportunity for compression mode dependent tag fixup
+	 */
+	(*tif->tif_fixuptags)(tif);
+
+	/*
+	 * Some manufacturers make life difficult by writing
+	 * large amounts of uncompressed data as a single strip.
+	 * This is contrary to the recommendations of the spec.
+	 * The following makes an attempt at breaking such images
+	 * into strips closer to the recommended 8k bytes.  A
+	 * side effect, however, is that the RowsPerStrip tag
+	 * value may be changed.
+	 */
+	if ((tif->tif_dir.td_planarconfig==PLANARCONFIG_CONTIG)&&
+	    (tif->tif_dir.td_nstrips==1)&&
+	    (tif->tif_dir.td_compression==COMPRESSION_NONE)&&  
+	    ((tif->tif_flags&(TIFF_STRIPCHOP|TIFF_ISTILED))==TIFF_STRIPCHOP))
+    {
+        if ( !_TIFFFillStriles(tif) || !tif->tif_dir.td_stripbytecount )
+            return 0;
+		ChopUpSingleUncompressedStrip(tif);
+    }
+
+        /*
+         * Clear the dirty directory flag. 
+         */
+	tif->tif_flags &= ~TIFF_DIRTYDIRECT;
+	tif->tif_flags &= ~TIFF_DIRTYSTRIP;
+
+	/*
+	 * Reinitialize i/o since we are starting on a new directory.
+	 */
+	tif->tif_row = (uint32) -1;
+	tif->tif_curstrip = (uint32) -1;
+	tif->tif_col = (uint32) -1;
+	tif->tif_curtile = (uint32) -1;
+	tif->tif_tilesize = (tmsize_t) -1;
+
+	tif->tif_scanlinesize = TIFFScanlineSize(tif);
+	if (!tif->tif_scanlinesize) {
+		TIFFErrorExt(tif->tif_clientdata, module,
+		    "Cannot handle zero scanline size");
+		return (0);
+	}
+
+	if (isTiled(tif)) {
+		tif->tif_tilesize = TIFFTileSize(tif);
+		if (!tif->tif_tilesize) {
+			TIFFErrorExt(tif->tif_clientdata, module,
+			     "Cannot handle zero tile size");
+			return (0);
+		}
+	} else {
+		if (!TIFFStripSize(tif)) {
+			TIFFErrorExt(tif->tif_clientdata, module,
+			    "Cannot handle zero strip size");
+			return (0);
+		}
+	}
+	return (1);
+bad:
+	if (dir)
+		_TIFFfree(dir);
+	return (0);
+}
+
+static void
+TIFFReadDirectoryCheckOrder(TIFF* tif, TIFFDirEntry* dir, uint16 dircount)
+{
+	static const char module[] = "TIFFReadDirectoryCheckOrder";
+	uint16 m;
+	uint16 n;
+	TIFFDirEntry* o;
+	m=0;
+	for (n=0, o=dir; n<dircount; n++, o++)
+	{
+		if (o->tdir_tag<m)
+		{
+			TIFFWarningExt(tif->tif_clientdata,module,
+			    "Invalid TIFF directory; tags are not sorted in ascending order");
+			break;
+		}
+		m=o->tdir_tag+1;
+	}
+}
+
+static TIFFDirEntry*
+TIFFReadDirectoryFindEntry(TIFF* tif, TIFFDirEntry* dir, uint16 dircount, uint16 tagid)
+{
+	TIFFDirEntry* m;
+	uint16 n;
+	(void) tif;
+	for (m=dir, n=0; n<dircount; m++, n++)
+	{
+		if (m->tdir_tag==tagid)
+			return(m);
+	}
+	return(0);
+}
+
+static void
+TIFFReadDirectoryFindFieldInfo(TIFF* tif, uint16 tagid, uint32* fii)
+{
+	int32 ma,mb,mc;
+	ma=-1;
+	mc=(int32)tif->tif_nfields;
+	while (1)
+	{
+		if (ma+1==mc)
+		{
+			*fii = FAILED_FII;
+			return;
+		}
+		mb=(ma+mc)/2;
+		if (tif->tif_fields[mb]->field_tag==(uint32)tagid)
+			break;
+		if (tif->tif_fields[mb]->field_tag<(uint32)tagid)
+			ma=mb;
+		else
+			mc=mb;
+	}
+	while (1)
+	{
+		if (mb==0)
+			break;
+		if (tif->tif_fields[mb-1]->field_tag!=(uint32)tagid)
+			break;
+		mb--;
+	}
+	*fii=mb;
+}
+
+/*
+ * Read custom directory from the arbitarry offset.
+ * The code is very similar to TIFFReadDirectory().
+ */
+int
+TIFFReadCustomDirectory(TIFF* tif, toff_t diroff,
+			const TIFFFieldArray* infoarray)
+{
+	static const char module[] = "TIFFReadCustomDirectory";
+	TIFFDirEntry* dir;
+	uint16 dircount;
+	TIFFDirEntry* dp;
+	uint16 di;
+	const TIFFField* fip;
+	uint32 fii;
+	_TIFFSetupFields(tif, infoarray);
+	dircount=TIFFFetchDirectory(tif,diroff,&dir,NULL);
+	if (!dircount)
+	{
+		TIFFErrorExt(tif->tif_clientdata,module,
+		    "Failed to read custom directory at offset " TIFF_UINT64_FORMAT,diroff);
+		return 0;
+	}
+	TIFFFreeDirectory(tif);
+	_TIFFmemset(&tif->tif_dir, 0, sizeof(TIFFDirectory));
+	TIFFReadDirectoryCheckOrder(tif,dir,dircount);
+	for (di=0, dp=dir; di<dircount; di++, dp++)
+	{
+		TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii);
+		if (fii == FAILED_FII)
+		{
+			TIFFWarningExt(tif->tif_clientdata, module,
+			    "Unknown field with tag %d (0x%x) encountered",
+			    dp->tdir_tag, dp->tdir_tag);
+			if (!_TIFFMergeFields(tif, _TIFFCreateAnonField(tif,
+						dp->tdir_tag,
+						(TIFFDataType) dp->tdir_type),
+					     1)) {
+				TIFFWarningExt(tif->tif_clientdata, module,
+				    "Registering anonymous field with tag %d (0x%x) failed",
+				    dp->tdir_tag, dp->tdir_tag);
+				dp->tdir_tag=IGNORE;
+			} else {
+				TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii);
+				assert( fii != FAILED_FII );
+			}
+		}
+		if (dp->tdir_tag!=IGNORE)
+		{
+			fip=tif->tif_fields[fii];
+			if (fip->field_bit==FIELD_IGNORE)
+				dp->tdir_tag=IGNORE;
+			else
+			{
+				/* check data type */
+				while ((fip->field_type!=TIFF_ANY)&&(fip->field_type!=dp->tdir_type))
+				{
+					fii++;
+					if ((fii==tif->tif_nfields)||
+					    (tif->tif_fields[fii]->field_tag!=(uint32)dp->tdir_tag))
+					{
+						fii=0xFFFF;
+						break;
+					}
+					fip=tif->tif_fields[fii];
+				}
+				if (fii==0xFFFF)
+				{
+					TIFFWarningExt(tif->tif_clientdata, module,
+					    "Wrong data type %d for \"%s\"; tag ignored",
+					    dp->tdir_type,fip->field_name);
+					dp->tdir_tag=IGNORE;
+				}
+				else
+				{
+					/* check count if known in advance */
+					if ((fip->field_readcount!=TIFF_VARIABLE)&&
+					    (fip->field_readcount!=TIFF_VARIABLE2))
+					{
+						uint32 expected;
+						if (fip->field_readcount==TIFF_SPP)
+							expected=(uint32)tif->tif_dir.td_samplesperpixel;
+						else
+							expected=(uint32)fip->field_readcount;
+						if (!CheckDirCount(tif,dp,expected))
+							dp->tdir_tag=IGNORE;
+					}
+				}
+			}
+			switch (dp->tdir_tag)
+			{
+				case IGNORE:
+					break;
+				case EXIFTAG_SUBJECTDISTANCE:
+					(void) TIFFFetchSubjectDistance(tif,dp);
+					break;
+				default:
+					(void) TIFFFetchNormalTag(tif, dp, TRUE);
+					break;
+			}
+		}
+	}
+	if (dir)
+		_TIFFfree(dir);
+	return 1;
+}
+
+/*
+ * EXIF is important special case of custom IFD, so we have a special
+ * function to read it.
+ */
+int
+TIFFReadEXIFDirectory(TIFF* tif, toff_t diroff)
+{
+	const TIFFFieldArray* exifFieldArray;
+	exifFieldArray = _TIFFGetExifFields();
+	return TIFFReadCustomDirectory(tif, diroff, exifFieldArray);  
+}
+
+static int
+EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount)
+{
+	static const char module[] = "EstimateStripByteCounts";
+
+	TIFFDirEntry *dp;
+	TIFFDirectory *td = &tif->tif_dir;
+	uint32 strip;
+
+    if( !_TIFFFillStriles( tif ) )
+        return -1;
+
+	if (td->td_stripbytecount)
+		_TIFFfree(td->td_stripbytecount);
+	td->td_stripbytecount = (uint64*)
+	    _TIFFCheckMalloc(tif, td->td_nstrips, sizeof (uint64),
+		"for \"StripByteCounts\" array");
+        if( td->td_stripbytecount == NULL )
+            return -1;
+
+	if (td->td_compression != COMPRESSION_NONE) {
+		uint64 space;
+		uint64 filesize;
+		uint16 n;
+		filesize = TIFFGetFileSize(tif);
+		if (!(tif->tif_flags&TIFF_BIGTIFF))
+			space=sizeof(TIFFHeaderClassic)+2+dircount*12+4;
+		else
+			space=sizeof(TIFFHeaderBig)+8+dircount*20+8;
+		/* calculate amount of space used by indirect values */
+		for (dp = dir, n = dircount; n > 0; n--, dp++)
+		{
+			uint32 typewidth = TIFFDataWidth((TIFFDataType) dp->tdir_type);
+			uint64 datasize;
+			typewidth = TIFFDataWidth((TIFFDataType) dp->tdir_type);
+			if (typewidth == 0) {
+				TIFFErrorExt(tif->tif_clientdata, module,
+				    "Cannot determine size of unknown tag type %d",
+				    dp->tdir_type);
+				return -1;
+			}
+			datasize=(uint64)typewidth*dp->tdir_count;
+			if (!(tif->tif_flags&TIFF_BIGTIFF))
+			{
+				if (datasize<=4)
+					datasize=0;
+			}
+			else
+			{
+				if (datasize<=8)
+					datasize=0;
+			}
+			space+=datasize;
+		}
+		space = filesize - space;
+		if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
+			space /= td->td_samplesperpixel;
+		for (strip = 0; strip < td->td_nstrips; strip++)
+			td->td_stripbytecount[strip] = space;
+		/*
+		 * This gross hack handles the case were the offset to
+		 * the last strip is past the place where we think the strip
+		 * should begin.  Since a strip of data must be contiguous,
+		 * it's safe to assume that we've overestimated the amount
+		 * of data in the strip and trim this number back accordingly.
+		 */
+		strip--;
+		if (td->td_stripoffset[strip]+td->td_stripbytecount[strip] > filesize)
+			td->td_stripbytecount[strip] = filesize - td->td_stripoffset[strip];
+	} else if (isTiled(tif)) {
+		uint64 bytespertile = TIFFTileSize64(tif);
+
+		for (strip = 0; strip < td->td_nstrips; strip++)
+		    td->td_stripbytecount[strip] = bytespertile;
+	} else {
+		uint64 rowbytes = TIFFScanlineSize64(tif);
+		uint32 rowsperstrip = td->td_imagelength/td->td_stripsperimage;
+		for (strip = 0; strip < td->td_nstrips; strip++)
+			td->td_stripbytecount[strip] = rowbytes * rowsperstrip;
+	}
+	TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
+	if (!TIFFFieldSet(tif, FIELD_ROWSPERSTRIP))
+		td->td_rowsperstrip = td->td_imagelength;
+	return 1;
+}
+
+static void
+MissingRequired(TIFF* tif, const char* tagname)
+{
+	static const char module[] = "MissingRequired";
+
+	TIFFErrorExt(tif->tif_clientdata, module,
+	    "TIFF directory is missing required \"%s\" field",
+	    tagname);
+}
+
+/*
+ * Check the directory offset against the list of already seen directory
+ * offsets. This is a trick to prevent IFD looping. The one can create TIFF
+ * file with looped directory pointers. We will maintain a list of already
+ * seen directories and check every IFD offset against that list.
+ */
+static int
+TIFFCheckDirOffset(TIFF* tif, uint64 diroff)
+{
+	uint16 n;
+
+	if (diroff == 0)			/* no more directories */
+		return 0;
+	if (tif->tif_dirnumber == 65535) {
+	    TIFFErrorExt(tif->tif_clientdata, "TIFFCheckDirOffset",
+			 "Cannot handle more than 65535 TIFF directories");
+	    return 0;
+	}
+
+	for (n = 0; n < tif->tif_dirnumber && tif->tif_dirlist; n++) {
+		if (tif->tif_dirlist[n] == diroff)
+			return 0;
+	}
+
+	tif->tif_dirnumber++;
+
+	if (tif->tif_dirnumber > tif->tif_dirlistsize) {
+		uint64* new_dirlist;
+
+		/*
+		 * XXX: Reduce memory allocation granularity of the dirlist
+		 * array.
+		 */
+		new_dirlist = (uint64*)_TIFFCheckRealloc(tif, tif->tif_dirlist,
+		    tif->tif_dirnumber, 2 * sizeof(uint64), "for IFD list");
+		if (!new_dirlist)
+			return 0;
+		if( tif->tif_dirnumber >= 32768 )
+		    tif->tif_dirlistsize = 65535;
+		else
+		    tif->tif_dirlistsize = 2 * tif->tif_dirnumber;
+		tif->tif_dirlist = new_dirlist;
+	}
+
+	tif->tif_dirlist[tif->tif_dirnumber - 1] = diroff;
+
+	return 1;
+}
+
+/*
+ * Check the count field of a directory entry against a known value.  The
+ * caller is expected to skip/ignore the tag if there is a mismatch.
+ */
+static int
+CheckDirCount(TIFF* tif, TIFFDirEntry* dir, uint32 count)
+{
+	if ((uint64)count > dir->tdir_count) {
+		const TIFFField* fip = TIFFFieldWithTag(tif, dir->tdir_tag);
+		TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
+	"incorrect count for field \"%s\" (" TIFF_UINT64_FORMAT ", expecting %u); tag ignored",
+		    fip ? fip->field_name : "unknown tagname",
+		    dir->tdir_count, count);
+		return (0);
+	} else if ((uint64)count < dir->tdir_count) {
+		const TIFFField* fip = TIFFFieldWithTag(tif, dir->tdir_tag);
+		TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
+	"incorrect count for field \"%s\" (" TIFF_UINT64_FORMAT ", expecting %u); tag trimmed",
+		    fip ? fip->field_name : "unknown tagname",
+		    dir->tdir_count, count);
+		dir->tdir_count = count;
+		return (1);
+	}
+	return (1);
+}
+
+/*
+ * Read IFD structure from the specified offset. If the pointer to
+ * nextdiroff variable has been specified, read it too. Function returns a
+ * number of fields in the directory or 0 if failed.
+ */
+static uint16
+TIFFFetchDirectory(TIFF* tif, uint64 diroff, TIFFDirEntry** pdir,
+                   uint64 *nextdiroff)
+{
+	static const char module[] = "TIFFFetchDirectory";
+
+	void* origdir;
+	uint16 dircount16;
+	uint32 dirsize;
+	TIFFDirEntry* dir;
+	uint8* ma;
+	TIFFDirEntry* mb;
+	uint16 n;
+
+	assert(pdir);
+
+	tif->tif_diroff = diroff;
+	if (nextdiroff)
+		*nextdiroff = 0;
+	if (!isMapped(tif)) {
+		if (!SeekOK(tif, tif->tif_diroff)) {
+			TIFFErrorExt(tif->tif_clientdata, module,
+				"%s: Seek error accessing TIFF directory",
+				tif->tif_name);
+			return 0;
+		}
+		if (!(tif->tif_flags&TIFF_BIGTIFF))
+		{
+			if (!ReadOK(tif, &dircount16, sizeof (uint16))) {
+				TIFFErrorExt(tif->tif_clientdata, module,
+				    "%s: Can not read TIFF directory count",
+				    tif->tif_name);
+				return 0;
+			}
+			if (tif->tif_flags & TIFF_SWAB)
+				TIFFSwabShort(&dircount16);
+			if (dircount16>4096)
+			{
+				TIFFErrorExt(tif->tif_clientdata, module,
+				    "Sanity check on directory count failed, this is probably not a valid IFD offset");
+				return 0;
+			}
+			dirsize = 12;
+		} else {
+			uint64 dircount64;
+			if (!ReadOK(tif, &dircount64, sizeof (uint64))) {
+				TIFFErrorExt(tif->tif_clientdata, module,
+					"%s: Can not read TIFF directory count",
+					tif->tif_name);
+				return 0;
+			}
+			if (tif->tif_flags & TIFF_SWAB)
+				TIFFSwabLong8(&dircount64);
+			if (dircount64>4096)
+			{
+				TIFFErrorExt(tif->tif_clientdata, module,
+				    "Sanity check on directory count failed, this is probably not a valid IFD offset");
+				return 0;
+			}
+			dircount16 = (uint16)dircount64;
+			dirsize = 20;
+		}
+		origdir = _TIFFCheckMalloc(tif, dircount16,
+		    dirsize, "to read TIFF directory");
+		if (origdir == NULL)
+			return 0;
+		if (!ReadOK(tif, origdir, (tmsize_t)(dircount16*dirsize))) {
+			TIFFErrorExt(tif->tif_clientdata, module,
+				"%.100s: Can not read TIFF directory",
+				tif->tif_name);
+			_TIFFfree(origdir);
+			return 0;
+		}
+		/*
+		 * Read offset to next directory for sequential scans if
+		 * needed.
+		 */
+		if (nextdiroff)
+		{
+			if (!(tif->tif_flags&TIFF_BIGTIFF))
+			{
+				uint32 nextdiroff32;
+				if (!ReadOK(tif, &nextdiroff32, sizeof(uint32)))
+					nextdiroff32 = 0;
+				if (tif->tif_flags&TIFF_SWAB)
+					TIFFSwabLong(&nextdiroff32);
+				*nextdiroff=nextdiroff32;
+			} else {
+				if (!ReadOK(tif, nextdiroff, sizeof(uint64)))
+					*nextdiroff = 0;
+				if (tif->tif_flags&TIFF_SWAB)
+					TIFFSwabLong8(nextdiroff);
+			}
+		}
+	} else {
+		tmsize_t m;
+		tmsize_t off = (tmsize_t) tif->tif_diroff;
+		if ((uint64)off!=tif->tif_diroff)
+		{
+			TIFFErrorExt(tif->tif_clientdata,module,"Can not read TIFF directory count");
+			return(0);
+		}
+
+		/*
+		 * Check for integer overflow when validating the dir_off,
+		 * otherwise a very high offset may cause an OOB read and
+		 * crash the client. Make two comparisons instead of
+		 *
+		 *  off + sizeof(uint16) > tif->tif_size
+		 *
+		 * to avoid overflow.
+		 */
+		if (!(tif->tif_flags&TIFF_BIGTIFF))
+		{
+			m=off+sizeof(uint16);
+			if ((m<off)||(m<(tmsize_t)sizeof(uint16))||(m>tif->tif_size)) {
+				TIFFErrorExt(tif->tif_clientdata, module,
+					"Can not read TIFF directory count");
+				return 0;
+			} else {
+				_TIFFmemcpy(&dircount16, tif->tif_base + off,
+					    sizeof(uint16));
+			}
+			off += sizeof (uint16);
+			if (tif->tif_flags & TIFF_SWAB)
+				TIFFSwabShort(&dircount16);
+			if (dircount16>4096)
+			{
+				TIFFErrorExt(tif->tif_clientdata, module,
+				    "Sanity check on directory count failed, this is probably not a valid IFD offset");
+				return 0;
+			}
+			dirsize = 12;
+		}
+		else
+		{
+			tmsize_t m;
+			uint64 dircount64;
+			m=off+sizeof(uint64);
+			if ((m<off)||(m<(tmsize_t)sizeof(uint64))||(m>tif->tif_size)) {
+				TIFFErrorExt(tif->tif_clientdata, module,
+					"Can not read TIFF directory count");
+				return 0;
+			} else {
+				_TIFFmemcpy(&dircount64, tif->tif_base + off,
+					    sizeof(uint64));
+			}
+			off += sizeof (uint64);
+			if (tif->tif_flags & TIFF_SWAB)
+				TIFFSwabLong8(&dircount64);
+			if (dircount64>4096)
+			{
+				TIFFErrorExt(tif->tif_clientdata, module,
+				    "Sanity check on directory count failed, this is probably not a valid IFD offset");
+				return 0;
+			}
+			dircount16 = (uint16)dircount64;
+			dirsize = 20;
+		}
+		if (dircount16 == 0 )
+		{
+			TIFFErrorExt(tif->tif_clientdata, module,
+			             "Sanity check on directory count failed, zero tag directories not supported");
+			return 0;
+		}
+		origdir = _TIFFCheckMalloc(tif, dircount16,
+						dirsize,
+						"to read TIFF directory");
+		if (origdir == NULL)
+			return 0;
+		m=off+dircount16*dirsize;
+		if ((m<off)||(m<(tmsize_t)(dircount16*dirsize))||(m>tif->tif_size)) {
+			TIFFErrorExt(tif->tif_clientdata, module,
+				     "Can not read TIFF directory");
+			_TIFFfree(origdir);
+			return 0;
+		} else {
+			_TIFFmemcpy(origdir, tif->tif_base + off,
+				    dircount16 * dirsize);
+		}
+		if (nextdiroff) {
+			off += dircount16 * dirsize;
+			if (!(tif->tif_flags&TIFF_BIGTIFF))
+			{
+				uint32 nextdiroff32;
+				m=off+sizeof(uint32);
+				if ((m<off)||(m<(tmsize_t)sizeof(uint32))||(m>tif->tif_size))
+					nextdiroff32 = 0;
+				else
+					_TIFFmemcpy(&nextdiroff32, tif->tif_base + off,
+						    sizeof (uint32));
+				if (tif->tif_flags&TIFF_SWAB)
+					TIFFSwabLong(&nextdiroff32);
+				*nextdiroff = nextdiroff32;
+			}
+			else
+			{
+				m=off+sizeof(uint64);
+				if ((m<off)||(m<(tmsize_t)sizeof(uint64))||(m>tif->tif_size))
+					*nextdiroff = 0;
+				else
+					_TIFFmemcpy(nextdiroff, tif->tif_base + off,
+						    sizeof (uint64));
+				if (tif->tif_flags&TIFF_SWAB)
+					TIFFSwabLong8(nextdiroff);
+			}
+		}
+	}
+	dir = (TIFFDirEntry*)_TIFFCheckMalloc(tif, dircount16,
+						sizeof(TIFFDirEntry),
+						"to read TIFF directory");
+	if (dir==0)
+	{
+		_TIFFfree(origdir);
+		return 0;
+	}
+	ma=(uint8*)origdir;
+	mb=dir;
+	for (n=0; n<dircount16; n++)
+	{
+		if (tif->tif_flags&TIFF_SWAB)
+			TIFFSwabShort((uint16*)ma);
+		mb->tdir_tag=*(uint16*)ma;
+		ma+=sizeof(uint16);
+		if (tif->tif_flags&TIFF_SWAB)
+			TIFFSwabShort((uint16*)ma);
+		mb->tdir_type=*(uint16*)ma;
+		ma+=sizeof(uint16);
+		if (!(tif->tif_flags&TIFF_BIGTIFF))
+		{
+			if (tif->tif_flags&TIFF_SWAB)
+				TIFFSwabLong((uint32*)ma);
+			mb->tdir_count=(uint64)(*(uint32*)ma);
+			ma+=sizeof(uint32);
+			*(uint32*)(&mb->tdir_offset)=*(uint32*)ma;
+			ma+=sizeof(uint32);
+		}
+		else
+		{
+			if (tif->tif_flags&TIFF_SWAB)
+				TIFFSwabLong8((uint64*)ma);
+                        mb->tdir_count=TIFFReadUInt64(ma);
+			ma+=sizeof(uint64);
+			mb->tdir_offset.toff_long8=TIFFReadUInt64(ma);
+			ma+=sizeof(uint64);
+		}
+		mb++;
+	}
+	_TIFFfree(origdir);
+	*pdir = dir;
+	return dircount16;
+}
+
+/*
+ * Fetch a tag that is not handled by special case code.
+ */
+static int
+TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover)
+{
+	static const char module[] = "TIFFFetchNormalTag";
+	enum TIFFReadDirEntryErr err;
+	uint32 fii;
+	const TIFFField* fip = NULL;
+	TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii);
+        if( fii == FAILED_FII )
+        {
+            TIFFErrorExt(tif->tif_clientdata, "TIFFFetchNormalTag",
+                         "No definition found for tag %d",
+                         dp->tdir_tag);
+            return 0;
+        }
+	fip=tif->tif_fields[fii];
+	assert(fip != NULL); /* should not happen */
+	assert(fip->set_field_type!=TIFF_SETGET_OTHER);  /* if so, we shouldn't arrive here but deal with this in specialized code */
+	assert(fip->set_field_type!=TIFF_SETGET_INT);    /* if so, we shouldn't arrive here as this is only the case for pseudo-tags */
+	err=TIFFReadDirEntryErrOk;
+	switch (fip->set_field_type)
+	{
+		case TIFF_SETGET_UNDEFINED:
+			break;
+		case TIFF_SETGET_ASCII:
+			{
+				uint8* data;
+				assert(fip->field_passcount==0);
+				err=TIFFReadDirEntryByteArray(tif,dp,&data);
+				if (err==TIFFReadDirEntryErrOk)
+				{
+					uint8* ma;
+					uint32 mb;
+					int n;
+					ma=data;
+					mb=0;
+					while (mb<(uint32)dp->tdir_count)
+					{
+						if (*ma==0)
+							break;
+						ma++;
+						mb++;
+					}
+					if (mb+1<(uint32)dp->tdir_count)
+						TIFFWarningExt(tif->tif_clientdata,module,"ASCII value for tag \"%s\" contains null byte in value; value incorrectly truncated during reading due to implementation limitations",fip->field_name);
+					else if (mb+1>(uint32)dp->tdir_count)
+					{
+						uint8* o;
+						TIFFWarningExt(tif->tif_clientdata,module,"ASCII value for tag \"%s\" does not end in null byte",fip->field_name);
+						if ((uint32)dp->tdir_count+1!=dp->tdir_count+1)
+							o=NULL;
+						else
+							o=_TIFFmalloc((uint32)dp->tdir_count+1);
+						if (o==NULL)
+						{
+							if (data!=NULL)
+								_TIFFfree(data);
+							return(0);
+						}
+						_TIFFmemcpy(o,data,(uint32)dp->tdir_count);
+						o[(uint32)dp->tdir_count]=0;
+						if (data!=0)
+							_TIFFfree(data);
+						data=o;
+					}
+					n=TIFFSetField(tif,dp->tdir_tag,data);
+					if (data!=0)
+						_TIFFfree(data);
+					if (!n)
+						return(0);
+				}
+			}
+			break;
+		case TIFF_SETGET_UINT8:
+			{
+				uint8 data=0;
+				assert(fip->field_readcount==1);
+				assert(fip->field_passcount==0);
+				err=TIFFReadDirEntryByte(tif,dp,&data);
+				if (err==TIFFReadDirEntryErrOk)
+				{
+					if (!TIFFSetField(tif,dp->tdir_tag,data))
+						return(0);
+				}
+			}
+			break;
+		case TIFF_SETGET_UINT16:
+			{
+				uint16 data;
+				assert(fip->field_readcount==1);
+				assert(fip->field_passcount==0);
+				err=TIFFReadDirEntryShort(tif,dp,&data);
+				if (err==TIFFReadDirEntryErrOk)
+				{
+					if (!TIFFSetField(tif,dp->tdir_tag,data))
+						return(0);
+				}
+			}
+			break;
+		case TIFF_SETGET_UINT32:
+			{
+				uint32 data;
+				assert(fip->field_readcount==1);
+				assert(fip->field_passcount==0);
+				err=TIFFReadDirEntryLong(tif,dp,&data);
+				if (err==TIFFReadDirEntryErrOk)
+				{
+					if (!TIFFSetField(tif,dp->tdir_tag,data))
+						return(0);
+				}
+			}
+			break;
+		case TIFF_SETGET_UINT64:
+			{
+				uint64 data;
+				assert(fip->field_readcount==1);
+				assert(fip->field_passcount==0);
+				err=TIFFReadDirEntryLong8(tif,dp,&data);
+				if (err==TIFFReadDirEntryErrOk)
+				{
+					if (!TIFFSetField(tif,dp->tdir_tag,data))
+						return(0);
+				}
+			}
+			break;
+		case TIFF_SETGET_FLOAT:
+			{
+				float data;
+				assert(fip->field_readcount==1);
+				assert(fip->field_passcount==0);
+				err=TIFFReadDirEntryFloat(tif,dp,&data);
+				if (err==TIFFReadDirEntryErrOk)
+				{
+					if (!TIFFSetField(tif,dp->tdir_tag,data))
+						return(0);
+				}
+			}
+			break;
+		case TIFF_SETGET_DOUBLE:
+			{
+				double data;
+				assert(fip->field_readcount==1);
+				assert(fip->field_passcount==0);
+				err=TIFFReadDirEntryDouble(tif,dp,&data);
+				if (err==TIFFReadDirEntryErrOk)
+				{
+					if (!TIFFSetField(tif,dp->tdir_tag,data))
+						return(0);
+				}
+			}
+			break;
+		case TIFF_SETGET_IFD8:
+			{
+				uint64 data;
+				assert(fip->field_readcount==1);
+				assert(fip->field_passcount==0);
+				err=TIFFReadDirEntryIfd8(tif,dp,&data);
+				if (err==TIFFReadDirEntryErrOk)
+				{
+					if (!TIFFSetField(tif,dp->tdir_tag,data))
+						return(0);
+				}
+			}
+			break;
+		case TIFF_SETGET_UINT16_PAIR:
+			{
+				uint16* data;
+				assert(fip->field_readcount==2);
+				assert(fip->field_passcount==0);
+				if (dp->tdir_count!=2) {
+					TIFFWarningExt(tif->tif_clientdata,module,
+						       "incorrect count for field \"%s\", expected 2, got %d",
+						       fip->field_name,(int)dp->tdir_count);
+					return(0);
+				}
+				err=TIFFReadDirEntryShortArray(tif,dp,&data);
+				if (err==TIFFReadDirEntryErrOk)
+				{
+					int m;
+					m=TIFFSetField(tif,dp->tdir_tag,data[0],data[1]);
+					_TIFFfree(data);
+					if (!m)
+						return(0);
+				}
+			}
+			break;
+		case TIFF_SETGET_C0_UINT8:
+			{
+				uint8* data;
+				assert(fip->field_readcount>=1);
+				assert(fip->field_passcount==0);
+				if (dp->tdir_count!=(uint64)fip->field_readcount) {
+					TIFFWarningExt(tif->tif_clientdata,module,
+						       "incorrect count for field \"%s\", expected %d, got %d",
+						       fip->field_name,(int) fip->field_readcount, (int)dp->tdir_count);
+					return 0;
+				}
+				else
+				{
+					err=TIFFReadDirEntryByteArray(tif,dp,&data);
+					if (err==TIFFReadDirEntryErrOk)
+					{
+						int m;
+						m=TIFFSetField(tif,dp->tdir_tag,data);
+						if (data!=0)
+							_TIFFfree(data);
+						if (!m)
+							return(0);
+					}
+				}
+			}
+			break;
+		case TIFF_SETGET_C0_UINT16:
+			{
+				uint16* data;
+				assert(fip->field_readcount>=1);
+				assert(fip->field_passcount==0);
+				if (dp->tdir_count!=(uint64)fip->field_readcount)
+                                    /* corrupt file */;
+				else
+				{
+					err=TIFFReadDirEntryShortArray(tif,dp,&data);
+					if (err==TIFFReadDirEntryErrOk)
+					{
+						int m;
+						m=TIFFSetField(tif,dp->tdir_tag,data);
+						if (data!=0)
+							_TIFFfree(data);
+						if (!m)
+							return(0);
+					}
+				}
+			}
+			break;
+		case TIFF_SETGET_C0_UINT32:
+			{
+				uint32* data;
+				assert(fip->field_readcount>=1);
+				assert(fip->field_passcount==0);
+				if (dp->tdir_count!=(uint64)fip->field_readcount)
+                                    /* corrupt file */;
+				else
+				{
+					err=TIFFReadDirEntryLongArray(tif,dp,&data);
+					if (err==TIFFReadDirEntryErrOk)
+					{
+						int m;
+						m=TIFFSetField(tif,dp->tdir_tag,data);
+						if (data!=0)
+							_TIFFfree(data);
+						if (!m)
+							return(0);
+					}
+				}
+			}
+			break;
+		case TIFF_SETGET_C0_FLOAT:
+			{
+				float* data;
+				assert(fip->field_readcount>=1);
+				assert(fip->field_passcount==0);
+				if (dp->tdir_count!=(uint64)fip->field_readcount)
+                                    /* corrupt file */;
+				else
+				{
+					err=TIFFReadDirEntryFloatArray(tif,dp,&data);
+					if (err==TIFFReadDirEntryErrOk)
+					{
+						int m;
+						m=TIFFSetField(tif,dp->tdir_tag,data);
+						if (data!=0)
+							_TIFFfree(data);
+						if (!m)
+							return(0);
+					}
+				}
+			}
+			break;
+		case TIFF_SETGET_C16_ASCII:
+			{
+				uint8* data;
+				assert(fip->field_readcount==TIFF_VARIABLE);
+				assert(fip->field_passcount==1);
+				if (dp->tdir_count>0xFFFF)
+					err=TIFFReadDirEntryErrCount;
+				else
+				{
+					err=TIFFReadDirEntryByteArray(tif,dp,&data);
+					if (err==TIFFReadDirEntryErrOk)
+					{
+						int m;
+						m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data);
+						if (data!=0)
+							_TIFFfree(data);
+						if (!m)
+							return(0);
+					}
+				}
+			}
+			break;
+		case TIFF_SETGET_C16_UINT8:
+			{
+				uint8* data;
+				assert(fip->field_readcount==TIFF_VARIABLE);
+				assert(fip->field_passcount==1);
+				if (dp->tdir_count>0xFFFF)
+					err=TIFFReadDirEntryErrCount;
+				else
+				{
+					err=TIFFReadDirEntryByteArray(tif,dp,&data);
+					if (err==TIFFReadDirEntryErrOk)
+					{
+						int m;
+						m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data);
+						if (data!=0)
+							_TIFFfree(data);
+						if (!m)
+							return(0);
+					}
+				}
+			}
+			break;
+		case TIFF_SETGET_C16_UINT16:
+			{
+				uint16* data;
+				assert(fip->field_readcount==TIFF_VARIABLE);
+				assert(fip->field_passcount==1);
+				if (dp->tdir_count>0xFFFF)
+					err=TIFFReadDirEntryErrCount;
+				else
+				{
+					err=TIFFReadDirEntryShortArray(tif,dp,&data);
+					if (err==TIFFReadDirEntryErrOk)
+					{
+						int m;
+						m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data);
+						if (data!=0)
+							_TIFFfree(data);
+						if (!m)
+							return(0);
+					}
+				}
+			}
+			break;
+		case TIFF_SETGET_C16_UINT32:
+			{
+				uint32* data;
+				assert(fip->field_readcount==TIFF_VARIABLE);
+				assert(fip->field_passcount==1);
+				if (dp->tdir_count>0xFFFF)
+					err=TIFFReadDirEntryErrCount;
+				else
+				{
+					err=TIFFReadDirEntryLongArray(tif,dp,&data);
+					if (err==TIFFReadDirEntryErrOk)
+					{
+						int m;
+						m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data);
+						if (data!=0)
+							_TIFFfree(data);
+						if (!m)
+							return(0);
+					}
+				}
+			}
+			break;
+		case TIFF_SETGET_C16_UINT64:
+			{
+				uint64* data;
+				assert(fip->field_readcount==TIFF_VARIABLE);
+				assert(fip->field_passcount==1);
+				if (dp->tdir_count>0xFFFF)
+					err=TIFFReadDirEntryErrCount;
+				else
+				{
+					err=TIFFReadDirEntryLong8Array(tif,dp,&data);
+					if (err==TIFFReadDirEntryErrOk)
+					{
+						int m;
+						m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data);
+						if (data!=0)
+							_TIFFfree(data);
+						if (!m)
+							return(0);
+					}
+				}
+			}
+			break;
+		case TIFF_SETGET_C16_FLOAT:
+			{
+				float* data;
+				assert(fip->field_readcount==TIFF_VARIABLE);
+				assert(fip->field_passcount==1);
+				if (dp->tdir_count>0xFFFF)
+					err=TIFFReadDirEntryErrCount;
+				else
+				{
+					err=TIFFReadDirEntryFloatArray(tif,dp,&data);
+					if (err==TIFFReadDirEntryErrOk)
+					{
+						int m;
+						m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data);
+						if (data!=0)
+							_TIFFfree(data);
+						if (!m)
+							return(0);
+					}
+				}
+			}
+			break;
+		case TIFF_SETGET_C16_DOUBLE:
+			{
+				double* data;
+				assert(fip->field_readcount==TIFF_VARIABLE);
+				assert(fip->field_passcount==1);
+				if (dp->tdir_count>0xFFFF)
+					err=TIFFReadDirEntryErrCount;
+				else
+				{
+					err=TIFFReadDirEntryDoubleArray(tif,dp,&data);
+					if (err==TIFFReadDirEntryErrOk)
+					{
+						int m;
+						m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data);
+						if (data!=0)
+							_TIFFfree(data);
+						if (!m)
+							return(0);
+					}
+				}
+			}
+			break;
+		case TIFF_SETGET_C16_IFD8:
+			{
+				uint64* data;
+				assert(fip->field_readcount==TIFF_VARIABLE);
+				assert(fip->field_passcount==1);
+				if (dp->tdir_count>0xFFFF)
+					err=TIFFReadDirEntryErrCount;
+				else
+				{
+					err=TIFFReadDirEntryIfd8Array(tif,dp,&data);
+					if (err==TIFFReadDirEntryErrOk)
+					{
+						int m;
+						m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data);
+						if (data!=0)
+							_TIFFfree(data);
+						if (!m)
+							return(0);
+					}
+				}
+			}
+			break;
+		case TIFF_SETGET_C32_ASCII:
+			{
+				uint8* data;
+				assert(fip->field_readcount==TIFF_VARIABLE2);
+				assert(fip->field_passcount==1);
+				err=TIFFReadDirEntryByteArray(tif,dp,&data);
+				if (err==TIFFReadDirEntryErrOk)
+				{
+					int m;
+					m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
+					if (data!=0)
+						_TIFFfree(data);
+					if (!m)
+						return(0);
+				}
+			}
+			break;
+		case TIFF_SETGET_C32_UINT8:
+			{
+				uint8* data;
+				assert(fip->field_readcount==TIFF_VARIABLE2);
+				assert(fip->field_passcount==1);
+				err=TIFFReadDirEntryByteArray(tif,dp,&data);
+				if (err==TIFFReadDirEntryErrOk)
+				{
+					int m;
+					m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
+					if (data!=0)
+						_TIFFfree(data);
+					if (!m)
+						return(0);
+				}
+			}
+			break;
+		case TIFF_SETGET_C32_SINT8:
+			{
+				int8* data = NULL;
+				assert(fip->field_readcount==TIFF_VARIABLE2);
+				assert(fip->field_passcount==1);
+				err=TIFFReadDirEntrySbyteArray(tif,dp,&data);
+				if (err==TIFFReadDirEntryErrOk)
+				{
+					int m;
+					m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
+					if (data!=0)
+						_TIFFfree(data);
+					if (!m)
+						return(0);
+				}
+			}
+			break;
+		case TIFF_SETGET_C32_UINT16:
+			{
+				uint16* data;
+				assert(fip->field_readcount==TIFF_VARIABLE2);
+				assert(fip->field_passcount==1);
+				err=TIFFReadDirEntryShortArray(tif,dp,&data);
+				if (err==TIFFReadDirEntryErrOk)
+				{
+					int m;
+					m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
+					if (data!=0)
+						_TIFFfree(data);
+					if (!m)
+						return(0);
+				}
+			}
+			break;
+		case TIFF_SETGET_C32_SINT16:
+			{
+				int16* data = NULL;
+				assert(fip->field_readcount==TIFF_VARIABLE2);
+				assert(fip->field_passcount==1);
+				err=TIFFReadDirEntrySshortArray(tif,dp,&data);
+				if (err==TIFFReadDirEntryErrOk)
+				{
+					int m;
+					m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
+					if (data!=0)
+						_TIFFfree(data);
+					if (!m)
+						return(0);
+				}
+			}
+			break;
+		case TIFF_SETGET_C32_UINT32:
+			{
+				uint32* data;
+				assert(fip->field_readcount==TIFF_VARIABLE2);
+				assert(fip->field_passcount==1);
+				err=TIFFReadDirEntryLongArray(tif,dp,&data);
+				if (err==TIFFReadDirEntryErrOk)
+				{
+					int m;
+					m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
+					if (data!=0)
+						_TIFFfree(data);
+					if (!m)
+						return(0);
+				}
+			}
+			break;
+		case TIFF_SETGET_C32_SINT32:
+			{
+				int32* data = NULL;
+				assert(fip->field_readcount==TIFF_VARIABLE2);
+				assert(fip->field_passcount==1);
+				err=TIFFReadDirEntrySlongArray(tif,dp,&data);
+				if (err==TIFFReadDirEntryErrOk)
+				{
+					int m;
+					m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
+					if (data!=0)
+						_TIFFfree(data);
+					if (!m)
+						return(0);
+				}
+			}
+			break;
+		case TIFF_SETGET_C32_UINT64:
+			{
+				uint64* data;
+				assert(fip->field_readcount==TIFF_VARIABLE2);
+				assert(fip->field_passcount==1);
+				err=TIFFReadDirEntryLong8Array(tif,dp,&data);
+				if (err==TIFFReadDirEntryErrOk)
+				{
+					int m;
+					m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
+					if (data!=0)
+						_TIFFfree(data);
+					if (!m)
+						return(0);
+				}
+			}
+			break;
+		case TIFF_SETGET_C32_SINT64:
+			{
+				int64* data = NULL;
+				assert(fip->field_readcount==TIFF_VARIABLE2);
+				assert(fip->field_passcount==1);
+				err=TIFFReadDirEntrySlong8Array(tif,dp,&data);
+				if (err==TIFFReadDirEntryErrOk)
+				{
+					int m;
+					m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
+					if (data!=0)
+						_TIFFfree(data);
+					if (!m)
+						return(0);
+				}
+			}
+			break;
+		case TIFF_SETGET_C32_FLOAT:
+			{
+				float* data;
+				assert(fip->field_readcount==TIFF_VARIABLE2);
+				assert(fip->field_passcount==1);
+				err=TIFFReadDirEntryFloatArray(tif,dp,&data);
+				if (err==TIFFReadDirEntryErrOk)
+				{
+					int m;
+					m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
+					if (data!=0)
+						_TIFFfree(data);
+					if (!m)
+						return(0);
+				}
+			}
+			break;
+		case TIFF_SETGET_C32_DOUBLE:
+			{
+				double* data;
+				assert(fip->field_readcount==TIFF_VARIABLE2);
+				assert(fip->field_passcount==1);
+				err=TIFFReadDirEntryDoubleArray(tif,dp,&data);
+				if (err==TIFFReadDirEntryErrOk)
+				{
+					int m;
+					m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
+					if (data!=0)
+						_TIFFfree(data);
+					if (!m)
+						return(0);
+				}
+			}
+			break;
+		case TIFF_SETGET_C32_IFD8:
+			{
+				uint64* data;
+				assert(fip->field_readcount==TIFF_VARIABLE2);
+				assert(fip->field_passcount==1);
+				err=TIFFReadDirEntryIfd8Array(tif,dp,&data);
+				if (err==TIFFReadDirEntryErrOk)
+				{
+					int m;
+					m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
+					if (data!=0)
+						_TIFFfree(data);
+					if (!m)
+						return(0);
+				}
+			}
+			break;
+		default:
+			assert(0);    /* we should never get here */
+			break;
+	}
+	if (err!=TIFFReadDirEntryErrOk)
+	{
+		TIFFReadDirEntryOutputErr(tif,err,module,fip->field_name,recover);
+		return(0);
+	}
+	return(1);
+}
+
+/*
+ * Fetch a set of offsets or lengths.
+ * While this routine says "strips", in fact it's also used for tiles.
+ */
+static int
+TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, uint32 nstrips, uint64** lpp)
+{
+	static const char module[] = "TIFFFetchStripThing";
+	enum TIFFReadDirEntryErr err;
+	uint64* data;
+	err=TIFFReadDirEntryLong8Array(tif,dir,&data);
+	if (err!=TIFFReadDirEntryErrOk)
+	{
+		const TIFFField* fip = TIFFFieldWithTag(tif,dir->tdir_tag); 
+		TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",0);
+		return(0);
+	}
+	if (dir->tdir_count!=(uint64)nstrips)
+	{
+		uint64* resizeddata;
+		resizeddata=(uint64*)_TIFFCheckMalloc(tif,nstrips,sizeof(uint64),"for strip array");
+		if (resizeddata==0) {
+			_TIFFfree(data);
+			return(0);
+		}
+		if (dir->tdir_count<(uint64)nstrips)
+		{
+			_TIFFmemcpy(resizeddata,data,(uint32)dir->tdir_count*sizeof(uint64));
+			_TIFFmemset(resizeddata+(uint32)dir->tdir_count,0,(nstrips-(uint32)dir->tdir_count)*sizeof(uint64));
+		}
+		else
+			_TIFFmemcpy(resizeddata,data,nstrips*sizeof(uint64));
+		_TIFFfree(data);
+		data=resizeddata;
+	}
+	*lpp=data;
+	return(1);
+}
+
+/*
+ * Fetch and set the SubjectDistance EXIF tag.
+ */
+static int
+TIFFFetchSubjectDistance(TIFF* tif, TIFFDirEntry* dir)
+{
+	static const char module[] = "TIFFFetchSubjectDistance";
+	enum TIFFReadDirEntryErr err;
+	UInt64Aligned_t m;
+    m.l=0;
+	assert(sizeof(double)==8);
+	assert(sizeof(uint64)==8);
+	assert(sizeof(uint32)==4);
+	if (dir->tdir_count!=1)
+		err=TIFFReadDirEntryErrCount;
+	else if (dir->tdir_type!=TIFF_RATIONAL)
+		err=TIFFReadDirEntryErrType;
+	else
+	{
+		if (!(tif->tif_flags&TIFF_BIGTIFF))
+		{
+			uint32 offset;
+			offset=*(uint32*)(&dir->tdir_offset);
+			if (tif->tif_flags&TIFF_SWAB)
+				TIFFSwabLong(&offset);
+			err=TIFFReadDirEntryData(tif,offset,8,m.i);
+		}
+		else
+		{
+			m.l=dir->tdir_offset.toff_long8;
+			err=TIFFReadDirEntryErrOk;
+		}
+	}
+	if (err==TIFFReadDirEntryErrOk)
+	{
+		double n;
+		if (tif->tif_flags&TIFF_SWAB)
+			TIFFSwabArrayOfLong(m.i,2);
+		if (m.i[0]==0)
+			n=0.0;
+		else if (m.i[0]==0xFFFFFFFF)
+			/*
+			 * XXX: Numerator 0xFFFFFFFF means that we have infinite
+			 * distance. Indicate that with a negative floating point
+			 * SubjectDistance value.
+			 */
+			n=-1.0;
+		else
+			n=(double)m.i[0]/(double)m.i[1];
+		return(TIFFSetField(tif,dir->tdir_tag,n));
+	}
+	else
+	{
+		TIFFReadDirEntryOutputErr(tif,err,module,"SubjectDistance",TRUE);
+		return(0);
+	}
+}
+
+/*
+ * Replace a single strip (tile) of uncompressed data by multiple strips
+ * (tiles), each approximately STRIP_SIZE_DEFAULT bytes. This is useful for
+ * dealing with large images or for dealing with machines with a limited
+ * amount memory.
+ */
+static void
+ChopUpSingleUncompressedStrip(TIFF* tif)
+{
+	register TIFFDirectory *td = &tif->tif_dir;
+	uint64 bytecount;
+	uint64 offset;
+	uint32 rowblock;
+	uint64 rowblockbytes;
+	uint64 stripbytes;
+	uint32 strip;
+	uint64 nstrips64;
+	uint32 nstrips32;
+	uint32 rowsperstrip;
+	uint64* newcounts;
+	uint64* newoffsets;
+
+	bytecount = td->td_stripbytecount[0];
+	offset = td->td_stripoffset[0];
+	assert(td->td_planarconfig == PLANARCONFIG_CONTIG);
+	if ((td->td_photometric == PHOTOMETRIC_YCBCR)&&
+	    (!isUpSampled(tif)))
+		rowblock = td->td_ycbcrsubsampling[1];
+	else
+		rowblock = 1;
+	rowblockbytes = TIFFVTileSize64(tif, rowblock);
+	/*
+	 * Make the rows hold at least one scanline, but fill specified amount
+	 * of data if possible.
+	 */
+	if (rowblockbytes > STRIP_SIZE_DEFAULT) {
+		stripbytes = rowblockbytes;
+		rowsperstrip = rowblock;
+	} else if (rowblockbytes > 0 ) {
+		uint32 rowblocksperstrip;
+		rowblocksperstrip = (uint32) (STRIP_SIZE_DEFAULT / rowblockbytes);
+		rowsperstrip = rowblocksperstrip * rowblock;
+		stripbytes = rowblocksperstrip * rowblockbytes;
+	}
+	else
+	    return;
+
+	/*
+	 * never increase the number of strips in an image
+	 */
+	if (rowsperstrip >= td->td_rowsperstrip)
+		return;
+	nstrips64 = TIFFhowmany_64(bytecount, stripbytes);
+	if ((nstrips64==0)||(nstrips64>0xFFFFFFFF)) /* something is wonky, do nothing. */
+	    return;
+	nstrips32 = (uint32)nstrips64;
+
+	newcounts = (uint64*) _TIFFCheckMalloc(tif, nstrips32, sizeof (uint64),
+				"for chopped \"StripByteCounts\" array");
+	newoffsets = (uint64*) _TIFFCheckMalloc(tif, nstrips32, sizeof (uint64),
+				"for chopped \"StripOffsets\" array");
+	if (newcounts == NULL || newoffsets == NULL) {
+		/*
+		 * Unable to allocate new strip information, give up and use
+		 * the original one strip information.
+		 */
+		if (newcounts != NULL)
+			_TIFFfree(newcounts);
+		if (newoffsets != NULL)
+			_TIFFfree(newoffsets);
+		return;
+	}
+	/*
+	 * Fill the strip information arrays with new bytecounts and offsets
+	 * that reflect the broken-up format.
+	 */
+	for (strip = 0; strip < nstrips32; strip++) {
+		if (stripbytes > bytecount)
+			stripbytes = bytecount;
+		newcounts[strip] = stripbytes;
+		newoffsets[strip] = offset;
+		offset += stripbytes;
+		bytecount -= stripbytes;
+	}
+	/*
+	 * Replace old single strip info with multi-strip info.
+	 */
+	td->td_stripsperimage = td->td_nstrips = nstrips32;
+	TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
+
+	_TIFFfree(td->td_stripbytecount);
+	_TIFFfree(td->td_stripoffset);
+	td->td_stripbytecount = newcounts;
+	td->td_stripoffset = newoffsets;
+	td->td_stripbytecountsorted = 1;
+}
+
+int _TIFFFillStriles( TIFF *tif )
+{
+#if defined(DEFER_STRILE_LOAD)
+        register TIFFDirectory *td = &tif->tif_dir;
+        int return_value = 1;
+
+        if( td->td_stripoffset != NULL )
+                return 1;
+
+        if( td->td_stripoffset_entry.tdir_count == 0 )
+                return 0;
+
+        if (!TIFFFetchStripThing(tif,&(td->td_stripoffset_entry),
+                                 td->td_nstrips,&td->td_stripoffset))
+        {
+                return_value = 0;
+        }
+
+        if (!TIFFFetchStripThing(tif,&(td->td_stripbytecount_entry),
+                                 td->td_nstrips,&td->td_stripbytecount))
+        {
+                return_value = 0;
+        }
+
+        _TIFFmemset( &(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry));
+        _TIFFmemset( &(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry));
+
+	if (tif->tif_dir.td_nstrips > 1 && return_value == 1 ) {
+		uint32 strip;
+
+		tif->tif_dir.td_stripbytecountsorted = 1;
+		for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++) {
+			if (tif->tif_dir.td_stripoffset[strip - 1] >
+			    tif->tif_dir.td_stripoffset[strip]) {
+				tif->tif_dir.td_stripbytecountsorted = 0;
+				break;
+			}
+		}
+	}
+
+        return return_value;
+#else /* !defined(DEFER_STRILE_LOAD) */
+        (void) tif;
+        return 1;
+#endif 
+}
+
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tif_dirwrite.c b/Source/LibTIFF4/tif_dirwrite.c
index 312d6a0..7d964e0 100644
--- a/Source/LibTIFF4/tif_dirwrite.c
+++ b/Source/LibTIFF4/tif_dirwrite.c
@@ -1,2910 +1,2910 @@
-/* $Id: tif_dirwrite.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library.
- *
- * Directory Write Support Routines.
- */
-#include "tiffiop.h"
-
-#ifdef HAVE_IEEEFP
-#define TIFFCvtNativeToIEEEFloat(tif, n, fp)
-#define TIFFCvtNativeToIEEEDouble(tif, n, dp)
-#else
-extern void TIFFCvtNativeToIEEEFloat(TIFF* tif, uint32 n, float* fp);
-extern void TIFFCvtNativeToIEEEDouble(TIFF* tif, uint32 n, double* dp);
-#endif
-
-static int TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff);
-
-static int TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value);
-#if 0
-static int TIFFWriteDirectoryTagSampleformatPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value);
-#endif
-
-static int TIFFWriteDirectoryTagAscii(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, char* value);
-static int TIFFWriteDirectoryTagUndefinedArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value);
-#ifdef notdef
-static int TIFFWriteDirectoryTagByte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value);
-#endif
-static int TIFFWriteDirectoryTagByteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value);
-#if 0
-static int TIFFWriteDirectoryTagBytePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value);
-#endif
-#ifdef notdef
-static int TIFFWriteDirectoryTagSbyte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value);
-#endif
-static int TIFFWriteDirectoryTagSbyteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int8* value);
-#if 0
-static int TIFFWriteDirectoryTagSbytePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value);
-#endif
-static int TIFFWriteDirectoryTagShort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value);
-static int TIFFWriteDirectoryTagShortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint16* value);
-static int TIFFWriteDirectoryTagShortPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value);
-#ifdef notdef
-static int TIFFWriteDirectoryTagSshort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value);
-#endif
-static int TIFFWriteDirectoryTagSshortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int16* value);
-#if 0
-static int TIFFWriteDirectoryTagSshortPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value);
-#endif
-static int TIFFWriteDirectoryTagLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value);
-static int TIFFWriteDirectoryTagLongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value);
-#if 0
-static int TIFFWriteDirectoryTagLongPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value);
-#endif
-#ifdef notdef
-static int TIFFWriteDirectoryTagSlong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value);
-#endif
-static int TIFFWriteDirectoryTagSlongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int32* value);
-#if 0
-static int TIFFWriteDirectoryTagSlongPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value);
-#endif
-#ifdef notdef
-static int TIFFWriteDirectoryTagLong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint64 value);
-#endif
-static int TIFFWriteDirectoryTagLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
-#ifdef notdef
-static int TIFFWriteDirectoryTagSlong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int64 value);
-#endif
-static int TIFFWriteDirectoryTagSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int64* value);
-static int TIFFWriteDirectoryTagRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value);
-static int TIFFWriteDirectoryTagRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value);
-static int TIFFWriteDirectoryTagSrationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value);
-#ifdef notdef
-static int TIFFWriteDirectoryTagFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value);
-#endif
-static int TIFFWriteDirectoryTagFloatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value);
-#if 0
-static int TIFFWriteDirectoryTagFloatPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value);
-#endif
-#ifdef notdef
-static int TIFFWriteDirectoryTagDouble(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value);
-#endif
-static int TIFFWriteDirectoryTagDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value);
-#if 0
-static int TIFFWriteDirectoryTagDoublePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value);
-#endif
-static int TIFFWriteDirectoryTagIfdArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value);
-#ifdef notdef
-static int TIFFWriteDirectoryTagIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
-#endif
-static int TIFFWriteDirectoryTagShortLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value);
-static int TIFFWriteDirectoryTagLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
-static int TIFFWriteDirectoryTagIfdIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
-#ifdef notdef
-static int TIFFWriteDirectoryTagShortLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
-#endif
-static int TIFFWriteDirectoryTagColormap(TIFF* tif, uint32* ndir, TIFFDirEntry* dir);
-static int TIFFWriteDirectoryTagTransferfunction(TIFF* tif, uint32* ndir, TIFFDirEntry* dir);
-static int TIFFWriteDirectoryTagSubifd(TIFF* tif, uint32* ndir, TIFFDirEntry* dir);
-
-static int TIFFWriteDirectoryTagCheckedAscii(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, char* value);
-static int TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value);
-#ifdef notdef
-static int TIFFWriteDirectoryTagCheckedByte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value);
-#endif
-static int TIFFWriteDirectoryTagCheckedByteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value);
-#ifdef notdef
-static int TIFFWriteDirectoryTagCheckedSbyte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value);
-#endif
-static int TIFFWriteDirectoryTagCheckedSbyteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int8* value);
-static int TIFFWriteDirectoryTagCheckedShort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value);
-static int TIFFWriteDirectoryTagCheckedShortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint16* value);
-#ifdef notdef
-static int TIFFWriteDirectoryTagCheckedSshort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value);
-#endif
-static int TIFFWriteDirectoryTagCheckedSshortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int16* value);
-static int TIFFWriteDirectoryTagCheckedLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value);
-static int TIFFWriteDirectoryTagCheckedLongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value);
-#ifdef notdef
-static int TIFFWriteDirectoryTagCheckedSlong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value);
-#endif
-static int TIFFWriteDirectoryTagCheckedSlongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int32* value);
-#ifdef notdef
-static int TIFFWriteDirectoryTagCheckedLong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint64 value);
-#endif
-static int TIFFWriteDirectoryTagCheckedLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
-#ifdef notdef
-static int TIFFWriteDirectoryTagCheckedSlong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int64 value);
-#endif
-static int TIFFWriteDirectoryTagCheckedSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int64* value);
-static int TIFFWriteDirectoryTagCheckedRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value);
-static int TIFFWriteDirectoryTagCheckedRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value);
-static int TIFFWriteDirectoryTagCheckedSrationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value);
-#ifdef notdef
-static int TIFFWriteDirectoryTagCheckedFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value);
-#endif
-static int TIFFWriteDirectoryTagCheckedFloatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value);
-#ifdef notdef
-static int TIFFWriteDirectoryTagCheckedDouble(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value);
-#endif
-static int TIFFWriteDirectoryTagCheckedDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value);
-static int TIFFWriteDirectoryTagCheckedIfdArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value);
-static int TIFFWriteDirectoryTagCheckedIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
-
-static int TIFFWriteDirectoryTagData(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 datatype, uint32 count, uint32 datalength, void* data);
-
-static int TIFFLinkDirectory(TIFF*);
-
-/*
- * Write the contents of the current directory
- * to the specified file.  This routine doesn't
- * handle overwriting a directory with auxiliary
- * storage that's been changed.
- */
-int
-TIFFWriteDirectory(TIFF* tif)
-{
-	return TIFFWriteDirectorySec(tif,TRUE,TRUE,NULL);
-}
-
-/*
- * Similar to TIFFWriteDirectory(), writes the directory out
- * but leaves all data structures in memory so that it can be
- * written again.  This will make a partially written TIFF file
- * readable before it is successfully completed/closed.
- */
-int
-TIFFCheckpointDirectory(TIFF* tif)
-{
-	int rc;
-	/* Setup the strips arrays, if they haven't already been. */
-	if (tif->tif_dir.td_stripoffset == NULL)
-	    (void) TIFFSetupStrips(tif);
-	rc = TIFFWriteDirectorySec(tif,TRUE,FALSE,NULL);
-	(void) TIFFSetWriteOffset(tif, TIFFSeekFile(tif, 0, SEEK_END));
-	return rc;
-}
-
-int
-TIFFWriteCustomDirectory(TIFF* tif, uint64* pdiroff)
-{
-	return TIFFWriteDirectorySec(tif,FALSE,FALSE,pdiroff);
-}
-
-/*
- * Similar to TIFFWriteDirectory(), but if the directory has already
- * been written once, it is relocated to the end of the file, in case it
- * has changed in size.  Note that this will result in the loss of the
- * previously used directory space. 
- */ 
-int
-TIFFRewriteDirectory( TIFF *tif )
-{
-	static const char module[] = "TIFFRewriteDirectory";
-
-	/* We don't need to do anything special if it hasn't been written. */
-	if( tif->tif_diroff == 0 )
-		return TIFFWriteDirectory( tif );
-
-	/*
-	 * Find and zero the pointer to this directory, so that TIFFLinkDirectory
-	 * will cause it to be added after this directories current pre-link.
-	 */
-
-	if (!(tif->tif_flags&TIFF_BIGTIFF))
-	{
-		if (tif->tif_header.classic.tiff_diroff == tif->tif_diroff)
-		{
-			tif->tif_header.classic.tiff_diroff = 0;
-			tif->tif_diroff = 0;
-
-			TIFFSeekFile(tif,4,SEEK_SET);
-			if (!WriteOK(tif, &(tif->tif_header.classic.tiff_diroff),4))
-			{
-				TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-				    "Error updating TIFF header");
-				return (0);
-			}
-		}
-		else
-		{
-			uint32 nextdir;
-			nextdir = tif->tif_header.classic.tiff_diroff;
-			while(1) {
-				uint16 dircount;
-				uint32 nextnextdir;
-
-				if (!SeekOK(tif, nextdir) ||
-				    !ReadOK(tif, &dircount, 2)) {
-					TIFFErrorExt(tif->tif_clientdata, module,
-					     "Error fetching directory count");
-					return (0);
-				}
-				if (tif->tif_flags & TIFF_SWAB)
-					TIFFSwabShort(&dircount);
-				(void) TIFFSeekFile(tif,
-				    nextdir+2+dircount*12, SEEK_SET);
-				if (!ReadOK(tif, &nextnextdir, 4)) {
-					TIFFErrorExt(tif->tif_clientdata, module,
-					     "Error fetching directory link");
-					return (0);
-				}
-				if (tif->tif_flags & TIFF_SWAB)
-					TIFFSwabLong(&nextnextdir);
-				if (nextnextdir==tif->tif_diroff)
-				{
-					uint32 m;
-					m=0;
-					(void) TIFFSeekFile(tif,
-					    nextdir+2+dircount*12, SEEK_SET);
-					if (!WriteOK(tif, &m, 4)) {
-						TIFFErrorExt(tif->tif_clientdata, module,
-						     "Error writing directory link");
-						return (0);
-					}
-					tif->tif_diroff=0;
-					break;
-				}
-				nextdir=nextnextdir;
-			}
-		}
-	}
-	else
-	{
-		if (tif->tif_header.big.tiff_diroff == tif->tif_diroff)
-		{
-			tif->tif_header.big.tiff_diroff = 0;
-			tif->tif_diroff = 0;
-
-			TIFFSeekFile(tif,8,SEEK_SET);
-			if (!WriteOK(tif, &(tif->tif_header.big.tiff_diroff),8))
-			{
-				TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-				    "Error updating TIFF header");
-				return (0);
-			}
-		}
-		else
-		{
-			uint64 nextdir;
-			nextdir = tif->tif_header.big.tiff_diroff;
-			while(1) {
-				uint64 dircount64;
-				uint16 dircount;
-				uint64 nextnextdir;
-
-				if (!SeekOK(tif, nextdir) ||
-				    !ReadOK(tif, &dircount64, 8)) {
-					TIFFErrorExt(tif->tif_clientdata, module,
-					     "Error fetching directory count");
-					return (0);
-				}
-				if (tif->tif_flags & TIFF_SWAB)
-					TIFFSwabLong8(&dircount64);
-				if (dircount64>0xFFFF)
-				{
-					TIFFErrorExt(tif->tif_clientdata, module,
-					     "Sanity check on tag count failed, likely corrupt TIFF");
-					return (0);
-				}
-				dircount=(uint16)dircount64;
-				(void) TIFFSeekFile(tif,
-				    nextdir+8+dircount*20, SEEK_SET);
-				if (!ReadOK(tif, &nextnextdir, 8)) {
-					TIFFErrorExt(tif->tif_clientdata, module,
-					     "Error fetching directory link");
-					return (0);
-				}
-				if (tif->tif_flags & TIFF_SWAB)
-					TIFFSwabLong8(&nextnextdir);
-				if (nextnextdir==tif->tif_diroff)
-				{
-					uint64 m;
-					m=0;
-					(void) TIFFSeekFile(tif,
-					    nextdir+8+dircount*20, SEEK_SET);
-					if (!WriteOK(tif, &m, 8)) {
-						TIFFErrorExt(tif->tif_clientdata, module,
-						     "Error writing directory link");
-						return (0);
-					}
-					tif->tif_diroff=0;
-					break;
-				}
-				nextdir=nextnextdir;
-			}
-		}
-	}
-
-	/*
-	 * Now use TIFFWriteDirectory() normally.
-	 */
-
-	return TIFFWriteDirectory( tif );
-}
-
-static int
-TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff)
-{
-	static const char module[] = "TIFFWriteDirectorySec";
-	uint32 ndir;
-	TIFFDirEntry* dir;
-	uint32 dirsize;
-	void* dirmem;
-	uint32 m;
-	if (tif->tif_mode == O_RDONLY)
-		return (1);
-
-        _TIFFFillStriles( tif );
-        
-	/*
-	 * Clear write state so that subsequent images with
-	 * different characteristics get the right buffers
-	 * setup for them.
-	 */
-	if (imagedone)
-	{
-		if (tif->tif_flags & TIFF_POSTENCODE)
-		{
-			tif->tif_flags &= ~TIFF_POSTENCODE;
-			if (!(*tif->tif_postencode)(tif))
-			{
-				TIFFErrorExt(tif->tif_clientdata,module,
-				    "Error post-encoding before directory write");
-				return (0);
-			}
-		}
-		(*tif->tif_close)(tif);       /* shutdown encoder */
-		/*
-		 * Flush any data that might have been written
-		 * by the compression close+cleanup routines.  But
-                 * be careful not to write stuff if we didn't add data
-                 * in the previous steps as the "rawcc" data may well be
-                 * a previously read tile/strip in mixed read/write mode.
-		 */
-		if (tif->tif_rawcc > 0 
-		    && (tif->tif_flags & TIFF_BEENWRITING) != 0 )
-		{
-		    if( !TIFFFlushData1(tif) )
-                    {
-			TIFFErrorExt(tif->tif_clientdata, module,
-			    "Error flushing data before directory write");
-			return (0);
-                    }
-		}
-		if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
-		{
-			_TIFFfree(tif->tif_rawdata);
-			tif->tif_rawdata = NULL;
-			tif->tif_rawcc = 0;
-			tif->tif_rawdatasize = 0;
-                        tif->tif_rawdataoff = 0;
-                        tif->tif_rawdataloaded = 0;
-		}
-		tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP);
-	}
-	dir=NULL;
-	dirmem=NULL;
-	dirsize=0;
-	while (1)
-	{
-		ndir=0;
-		if (isimage)
-		{
-			if (TIFFFieldSet(tif,FIELD_IMAGEDIMENSIONS))
-			{
-				if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_IMAGEWIDTH,tif->tif_dir.td_imagewidth))
-					goto bad;
-				if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_IMAGELENGTH,tif->tif_dir.td_imagelength))
-					goto bad;
-			}
-			if (TIFFFieldSet(tif,FIELD_TILEDIMENSIONS))
-			{
-				if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_TILEWIDTH,tif->tif_dir.td_tilewidth))
-					goto bad;
-				if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_TILELENGTH,tif->tif_dir.td_tilelength))
-					goto bad;
-			}
-			if (TIFFFieldSet(tif,FIELD_RESOLUTION))
-			{
-				if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_XRESOLUTION,tif->tif_dir.td_xresolution))
-					goto bad;
-				if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_YRESOLUTION,tif->tif_dir.td_yresolution))
-					goto bad;
-			}
-			if (TIFFFieldSet(tif,FIELD_POSITION))
-			{
-				if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_XPOSITION,tif->tif_dir.td_xposition))
-					goto bad;
-				if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_YPOSITION,tif->tif_dir.td_yposition))
-					goto bad;
-			}
-			if (TIFFFieldSet(tif,FIELD_SUBFILETYPE))
-			{
-				if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,TIFFTAG_SUBFILETYPE,tif->tif_dir.td_subfiletype))
-					goto bad;
-			}
-			if (TIFFFieldSet(tif,FIELD_BITSPERSAMPLE))
-			{
-				if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_BITSPERSAMPLE,tif->tif_dir.td_bitspersample))
-					goto bad;
-			}
-			if (TIFFFieldSet(tif,FIELD_COMPRESSION))
-			{
-				if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_COMPRESSION,tif->tif_dir.td_compression))
-					goto bad;
-			}
-			if (TIFFFieldSet(tif,FIELD_PHOTOMETRIC))
-			{
-				if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_PHOTOMETRIC,tif->tif_dir.td_photometric))
-					goto bad;
-			}
-			if (TIFFFieldSet(tif,FIELD_THRESHHOLDING))
-			{
-				if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_THRESHHOLDING,tif->tif_dir.td_threshholding))
-					goto bad;
-			}
-			if (TIFFFieldSet(tif,FIELD_FILLORDER))
-			{
-				if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_FILLORDER,tif->tif_dir.td_fillorder))
-					goto bad;
-			}
-			if (TIFFFieldSet(tif,FIELD_ORIENTATION))
-			{
-				if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_ORIENTATION,tif->tif_dir.td_orientation))
-					goto bad;
-			}
-			if (TIFFFieldSet(tif,FIELD_SAMPLESPERPIXEL))
-			{
-				if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_SAMPLESPERPIXEL,tif->tif_dir.td_samplesperpixel))
-					goto bad;
-			}
-			if (TIFFFieldSet(tif,FIELD_ROWSPERSTRIP))
-			{
-				if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_ROWSPERSTRIP,tif->tif_dir.td_rowsperstrip))
-					goto bad;
-			}
-			if (TIFFFieldSet(tif,FIELD_MINSAMPLEVALUE))
-			{
-				if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_MINSAMPLEVALUE,tif->tif_dir.td_minsamplevalue))
-					goto bad;
-			}
-			if (TIFFFieldSet(tif,FIELD_MAXSAMPLEVALUE))
-			{
-				if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_MAXSAMPLEVALUE,tif->tif_dir.td_maxsamplevalue))
-					goto bad;
-			}
-			if (TIFFFieldSet(tif,FIELD_PLANARCONFIG))
-			{
-				if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_PLANARCONFIG,tif->tif_dir.td_planarconfig))
-					goto bad;
-			}
-			if (TIFFFieldSet(tif,FIELD_RESOLUTIONUNIT))
-			{
-				if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_RESOLUTIONUNIT,tif->tif_dir.td_resolutionunit))
-					goto bad;
-			}
-			if (TIFFFieldSet(tif,FIELD_PAGENUMBER))
-			{
-				if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_PAGENUMBER,2,&tif->tif_dir.td_pagenumber[0]))
-					goto bad;
-			}
-			if (TIFFFieldSet(tif,FIELD_STRIPBYTECOUNTS))
-			{
-				if (!isTiled(tif))
-				{
-					if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_STRIPBYTECOUNTS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripbytecount))
-						goto bad;
-				}
-				else
-				{
-					if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_TILEBYTECOUNTS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripbytecount))
-						goto bad;
-				}
-			}
-			if (TIFFFieldSet(tif,FIELD_STRIPOFFSETS))
-			{
-				if (!isTiled(tif))
-				{
-					if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_STRIPOFFSETS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripoffset))
-						goto bad;
-				}
-				else
-				{
-					if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_TILEOFFSETS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripoffset))
-						goto bad;
-				}
-			}
-			if (TIFFFieldSet(tif,FIELD_COLORMAP))
-			{
-				if (!TIFFWriteDirectoryTagColormap(tif,&ndir,dir))
-					goto bad;
-			}
-			if (TIFFFieldSet(tif,FIELD_EXTRASAMPLES))
-			{
-				if (tif->tif_dir.td_extrasamples)
-				{
-					uint16 na;
-					uint16* nb;
-					TIFFGetFieldDefaulted(tif,TIFFTAG_EXTRASAMPLES,&na,&nb);
-					if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_EXTRASAMPLES,na,nb))
-						goto bad;
-				}
-			}
-			if (TIFFFieldSet(tif,FIELD_SAMPLEFORMAT))
-			{
-				if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_SAMPLEFORMAT,tif->tif_dir.td_sampleformat))
-					goto bad;
-			}
-			if (TIFFFieldSet(tif,FIELD_SMINSAMPLEVALUE))
-			{
-				if (!TIFFWriteDirectoryTagSampleformatArray(tif,&ndir,dir,TIFFTAG_SMINSAMPLEVALUE,tif->tif_dir.td_samplesperpixel,tif->tif_dir.td_sminsamplevalue))
-					goto bad;
-			}
-			if (TIFFFieldSet(tif,FIELD_SMAXSAMPLEVALUE))
-			{
-				if (!TIFFWriteDirectoryTagSampleformatArray(tif,&ndir,dir,TIFFTAG_SMAXSAMPLEVALUE,tif->tif_dir.td_samplesperpixel,tif->tif_dir.td_smaxsamplevalue))
-					goto bad;
-			}
-			if (TIFFFieldSet(tif,FIELD_IMAGEDEPTH))
-			{
-				if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,TIFFTAG_IMAGEDEPTH,tif->tif_dir.td_imagedepth))
-					goto bad;
-			}
-			if (TIFFFieldSet(tif,FIELD_TILEDEPTH))
-			{
-				if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,TIFFTAG_TILEDEPTH,tif->tif_dir.td_tiledepth))
-					goto bad;
-			}
-			if (TIFFFieldSet(tif,FIELD_HALFTONEHINTS))
-			{
-				if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_HALFTONEHINTS,2,&tif->tif_dir.td_halftonehints[0]))
-					goto bad;
-			}
-			if (TIFFFieldSet(tif,FIELD_YCBCRSUBSAMPLING))
-			{
-				if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_YCBCRSUBSAMPLING,2,&tif->tif_dir.td_ycbcrsubsampling[0]))
-					goto bad;
-			}
-			if (TIFFFieldSet(tif,FIELD_YCBCRPOSITIONING))
-			{
-				if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_YCBCRPOSITIONING,tif->tif_dir.td_ycbcrpositioning))
-					goto bad;
-			}
-			if (TIFFFieldSet(tif,FIELD_REFBLACKWHITE))
-			{
-				if (!TIFFWriteDirectoryTagRationalArray(tif,&ndir,dir,TIFFTAG_REFERENCEBLACKWHITE,6,tif->tif_dir.td_refblackwhite))
-					goto bad;
-			}
-			if (TIFFFieldSet(tif,FIELD_TRANSFERFUNCTION))
-			{
-				if (!TIFFWriteDirectoryTagTransferfunction(tif,&ndir,dir))
-					goto bad;
-			}
-			if (TIFFFieldSet(tif,FIELD_INKNAMES))
-			{
-				if (!TIFFWriteDirectoryTagAscii(tif,&ndir,dir,TIFFTAG_INKNAMES,tif->tif_dir.td_inknameslen,tif->tif_dir.td_inknames))
-					goto bad;
-			}
-			if (TIFFFieldSet(tif,FIELD_SUBIFD))
-			{
-				if (!TIFFWriteDirectoryTagSubifd(tif,&ndir,dir))
-					goto bad;
-			}
-			{
-				uint32 n;
-				for (n=0; n<tif->tif_nfields; n++) {
-					const TIFFField* o;
-					o = tif->tif_fields[n];
-					if ((o->field_bit>=FIELD_CODEC)&&(TIFFFieldSet(tif,o->field_bit)))
-					{
-						switch (o->get_field_type)
-						{
-							case TIFF_SETGET_ASCII:
-								{
-									uint32 pa;
-									char* pb;
-									assert(o->field_type==TIFF_ASCII);
-									assert(o->field_readcount==TIFF_VARIABLE);
-									assert(o->field_passcount==0);
-									TIFFGetField(tif,o->field_tag,&pb);
-									pa=(uint32)(strlen(pb));
-									if (!TIFFWriteDirectoryTagAscii(tif,&ndir,dir,o->field_tag,pa,pb))
-										goto bad;
-								}
-								break;
-							case TIFF_SETGET_UINT16:
-								{
-									uint16 p;
-									assert(o->field_type==TIFF_SHORT);
-									assert(o->field_readcount==1);
-									assert(o->field_passcount==0);
-									TIFFGetField(tif,o->field_tag,&p);
-									if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,o->field_tag,p))
-										goto bad;
-								}
-								break;
-							case TIFF_SETGET_UINT32:
-								{
-									uint32 p;
-									assert(o->field_type==TIFF_LONG);
-									assert(o->field_readcount==1);
-									assert(o->field_passcount==0);
-									TIFFGetField(tif,o->field_tag,&p);
-									if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,o->field_tag,p))
-										goto bad;
-								}
-								break;
-							case TIFF_SETGET_C32_UINT8:
-								{
-									uint32 pa;
-									void* pb;
-									assert(o->field_type==TIFF_UNDEFINED);
-									assert(o->field_readcount==TIFF_VARIABLE2);
-									assert(o->field_passcount==1);
-									TIFFGetField(tif,o->field_tag,&pa,&pb);
-									if (!TIFFWriteDirectoryTagUndefinedArray(tif,&ndir,dir,o->field_tag,pa,pb))
-										goto bad;
-								}
-								break;
-							default:
-								assert(0);   /* we should never get here */
-								break;
-						}
-					}
-				}
-			}
-		}
-		for (m=0; m<(uint32)(tif->tif_dir.td_customValueCount); m++)
-		{
-			switch (tif->tif_dir.td_customValues[m].info->field_type)
-			{
-				case TIFF_ASCII:
-					if (!TIFFWriteDirectoryTagAscii(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
-						goto bad;
-					break;
-				case TIFF_UNDEFINED:
-					if (!TIFFWriteDirectoryTagUndefinedArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
-						goto bad;
-					break;
-				case TIFF_BYTE:
-					if (!TIFFWriteDirectoryTagByteArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
-						goto bad;
-					break;
-				case TIFF_SBYTE:
-					if (!TIFFWriteDirectoryTagSbyteArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
-						goto bad;
-					break;
-				case TIFF_SHORT:
-					if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
-						goto bad;
-					break;
-				case TIFF_SSHORT:
-					if (!TIFFWriteDirectoryTagSshortArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
-						goto bad;
-					break;
-				case TIFF_LONG:
-					if (!TIFFWriteDirectoryTagLongArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
-						goto bad;
-					break;
-				case TIFF_SLONG:
-					if (!TIFFWriteDirectoryTagSlongArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
-						goto bad;
-					break;
-				case TIFF_LONG8:
-					if (!TIFFWriteDirectoryTagLong8Array(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
-						goto bad;
-					break;
-				case TIFF_SLONG8:
-					if (!TIFFWriteDirectoryTagSlong8Array(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
-						goto bad;
-					break;
-				case TIFF_RATIONAL:
-					if (!TIFFWriteDirectoryTagRationalArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
-						goto bad;
-					break;
-				case TIFF_SRATIONAL:
-					if (!TIFFWriteDirectoryTagSrationalArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
-						goto bad;
-					break;
-				case TIFF_FLOAT:
-					if (!TIFFWriteDirectoryTagFloatArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
-						goto bad;
-					break;
-				case TIFF_DOUBLE:
-					if (!TIFFWriteDirectoryTagDoubleArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
-						goto bad;
-					break;
-				case TIFF_IFD:
-					if (!TIFFWriteDirectoryTagIfdArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
-						goto bad;
-					break;
-				case TIFF_IFD8:
-					if (!TIFFWriteDirectoryTagIfdIfd8Array(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
-						goto bad;
-					break;
-				default:
-					assert(0);   /* we should never get here */
-					break;
-			}
-		}
-		if (dir!=NULL)
-			break;
-		dir=_TIFFmalloc(ndir*sizeof(TIFFDirEntry));
-		if (dir==NULL)
-		{
-			TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
-			goto bad;
-		}
-		if (isimage)
-		{
-			if ((tif->tif_diroff==0)&&(!TIFFLinkDirectory(tif)))
-				goto bad;
-		}
-		else
-			tif->tif_diroff=(TIFFSeekFile(tif,0,SEEK_END)+1)&(~1);
-		if (pdiroff!=NULL)
-			*pdiroff=tif->tif_diroff;
-		if (!(tif->tif_flags&TIFF_BIGTIFF))
-			dirsize=2+ndir*12+4;
-		else
-			dirsize=8+ndir*20+8;
-		tif->tif_dataoff=tif->tif_diroff+dirsize;
-		if (!(tif->tif_flags&TIFF_BIGTIFF))
-			tif->tif_dataoff=(uint32)tif->tif_dataoff;
-		if ((tif->tif_dataoff<tif->tif_diroff)||(tif->tif_dataoff<(uint64)dirsize))
-		{
-			TIFFErrorExt(tif->tif_clientdata,module,"Maximum TIFF file size exceeded");
-			goto bad;
-		}
-		if (tif->tif_dataoff&1)
-			tif->tif_dataoff++;
-		if (isimage)
-			tif->tif_curdir++;
-	}
-	if (isimage)
-	{
-		if (TIFFFieldSet(tif,FIELD_SUBIFD)&&(tif->tif_subifdoff==0))
-		{
-			uint32 na;
-			TIFFDirEntry* nb;
-			for (na=0, nb=dir; ; na++, nb++)
-			{
-				assert(na<ndir);
-				if (nb->tdir_tag==TIFFTAG_SUBIFD)
-					break;
-			}
-			if (!(tif->tif_flags&TIFF_BIGTIFF))
-				tif->tif_subifdoff=tif->tif_diroff+2+na*12+8;
-			else
-				tif->tif_subifdoff=tif->tif_diroff+8+na*20+12;
-		}
-	}
-	dirmem=_TIFFmalloc(dirsize);
-	if (dirmem==NULL)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
-		goto bad;
-	}
-	if (!(tif->tif_flags&TIFF_BIGTIFF))
-	{
-		uint8* n;
-		uint32 nTmp;
-		TIFFDirEntry* o;
-		n=dirmem;
-		*(uint16*)n=ndir;
-		if (tif->tif_flags&TIFF_SWAB)
-			TIFFSwabShort((uint16*)n);
-		n+=2;
-		o=dir;
-		for (m=0; m<ndir; m++)
-		{
-			*(uint16*)n=o->tdir_tag;
-			if (tif->tif_flags&TIFF_SWAB)
-				TIFFSwabShort((uint16*)n);
-			n+=2;
-			*(uint16*)n=o->tdir_type;
-			if (tif->tif_flags&TIFF_SWAB)
-				TIFFSwabShort((uint16*)n);
-			n+=2;
-			nTmp = (uint32)o->tdir_count;
-			_TIFFmemcpy(n,&nTmp,4);
-			if (tif->tif_flags&TIFF_SWAB)
-				TIFFSwabLong((uint32*)n);
-			n+=4;
-			/* This is correct. The data has been */
-			/* swabbed previously in TIFFWriteDirectoryTagData */
-			_TIFFmemcpy(n,&o->tdir_offset,4);
-			n+=4;
-			o++;
-		}
-		nTmp = (uint32)tif->tif_nextdiroff;
-		if (tif->tif_flags&TIFF_SWAB)
-			TIFFSwabLong(&nTmp);
-		_TIFFmemcpy(n,&nTmp,4);
-	}
-	else
-	{
-		uint8* n;
-		TIFFDirEntry* o;
-		n=dirmem;
-		*(uint64*)n=ndir;
-		if (tif->tif_flags&TIFF_SWAB)
-			TIFFSwabLong8((uint64*)n);
-		n+=8;
-		o=dir;
-		for (m=0; m<ndir; m++)
-		{
-			*(uint16*)n=o->tdir_tag;
-			if (tif->tif_flags&TIFF_SWAB)
-				TIFFSwabShort((uint16*)n);
-			n+=2;
-			*(uint16*)n=o->tdir_type;
-			if (tif->tif_flags&TIFF_SWAB)
-				TIFFSwabShort((uint16*)n);
-			n+=2;
-			_TIFFmemcpy(n,&o->tdir_count,8);
-			if (tif->tif_flags&TIFF_SWAB)
-				TIFFSwabLong8((uint64*)n);
-			n+=8;
-			_TIFFmemcpy(n,&o->tdir_offset,8);
-			n+=8;
-			o++;
-		}
-		_TIFFmemcpy(n,&tif->tif_nextdiroff,8);
-		if (tif->tif_flags&TIFF_SWAB)
-			TIFFSwabLong8((uint64*)n);
-	}
-	_TIFFfree(dir);
-	dir=NULL;
-	if (!SeekOK(tif,tif->tif_diroff))
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"IO error writing directory");
-		goto bad;
-	}
-	if (!WriteOK(tif,dirmem,(tmsize_t)dirsize))
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"IO error writing directory");
-		goto bad;
-	}
-	_TIFFfree(dirmem);
-	if (imagedone)
-	{
-		TIFFFreeDirectory(tif);
-		tif->tif_flags &= ~TIFF_DIRTYDIRECT;
-		tif->tif_flags &= ~TIFF_DIRTYSTRIP;
-		(*tif->tif_cleanup)(tif);
-		/*
-		* Reset directory-related state for subsequent
-		* directories.
-		*/
-		TIFFCreateDirectory(tif);
-	}
-	return(1);
-bad:
-	if (dir!=NULL)
-		_TIFFfree(dir);
-	if (dirmem!=NULL)
-		_TIFFfree(dirmem);
-	return(0);
-}
-
-static int
-TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value)
-{
-	static const char module[] = "TIFFWriteDirectoryTagSampleformatArray";
-	void* conv;
-	uint32 i;
-	int ok;
-	conv = _TIFFmalloc(count*sizeof(double));
-	if (conv == NULL)
-	{
-		TIFFErrorExt(tif->tif_clientdata, module, "Out of memory");
-		return (0);
-	}
-
-	switch (tif->tif_dir.td_sampleformat)
-	{
-		case SAMPLEFORMAT_IEEEFP:
-			if (tif->tif_dir.td_bitspersample<=32)
-			{
-				for (i = 0; i < count; ++i)
-					((float*)conv)[i] = (float)value[i];
-				ok = TIFFWriteDirectoryTagFloatArray(tif,ndir,dir,tag,count,(float*)conv);
-			}
-			else
-			{
-				ok = TIFFWriteDirectoryTagDoubleArray(tif,ndir,dir,tag,count,value);
-			}
-			break;
-		case SAMPLEFORMAT_INT:
-			if (tif->tif_dir.td_bitspersample<=8)
-			{
-				for (i = 0; i < count; ++i)
-					((int8*)conv)[i] = (int8)value[i];
-				ok = TIFFWriteDirectoryTagSbyteArray(tif,ndir,dir,tag,count,(int8*)conv);
-			}
-			else if (tif->tif_dir.td_bitspersample<=16)
-			{
-				for (i = 0; i < count; ++i)
-					((int16*)conv)[i] = (int16)value[i];
-				ok = TIFFWriteDirectoryTagSshortArray(tif,ndir,dir,tag,count,(int16*)conv);
-			}
-			else
-			{
-				for (i = 0; i < count; ++i)
-					((int32*)conv)[i] = (int32)value[i];
-				ok = TIFFWriteDirectoryTagSlongArray(tif,ndir,dir,tag,count,(int32*)conv);
-			}
-			break;
-		case SAMPLEFORMAT_UINT:
-			if (tif->tif_dir.td_bitspersample<=8)
-			{
-				for (i = 0; i < count; ++i)
-					((uint8*)conv)[i] = (uint8)value[i];
-				ok = TIFFWriteDirectoryTagByteArray(tif,ndir,dir,tag,count,(uint8*)conv);
-			}
-			else if (tif->tif_dir.td_bitspersample<=16)
-			{
-				for (i = 0; i < count; ++i)
-					((uint16*)conv)[i] = (uint16)value[i];
-				ok = TIFFWriteDirectoryTagShortArray(tif,ndir,dir,tag,count,(uint16*)conv);
-			}
-			else
-			{
-				for (i = 0; i < count; ++i)
-					((uint32*)conv)[i] = (uint32)value[i];
-				ok = TIFFWriteDirectoryTagLongArray(tif,ndir,dir,tag,count,(uint32*)conv);
-			}
-			break;
-		default:
-			ok = 0;
-	}
-
-	_TIFFfree(conv);
-	return (ok);
-}
-
-#if 0
-static int
-TIFFWriteDirectoryTagSampleformatPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
-{
-	switch (tif->tif_dir.td_sampleformat)
-	{
-		case SAMPLEFORMAT_IEEEFP:
-			if (tif->tif_dir.td_bitspersample<=32)
-				return(TIFFWriteDirectoryTagFloatPerSample(tif,ndir,dir,tag,(float)value));
-			else
-				return(TIFFWriteDirectoryTagDoublePerSample(tif,ndir,dir,tag,value));
-		case SAMPLEFORMAT_INT:
-			if (tif->tif_dir.td_bitspersample<=8)
-				return(TIFFWriteDirectoryTagSbytePerSample(tif,ndir,dir,tag,(int8)value));
-			else if (tif->tif_dir.td_bitspersample<=16)
-				return(TIFFWriteDirectoryTagSshortPerSample(tif,ndir,dir,tag,(int16)value));
-			else
-				return(TIFFWriteDirectoryTagSlongPerSample(tif,ndir,dir,tag,(int32)value));
-		case SAMPLEFORMAT_UINT:
-			if (tif->tif_dir.td_bitspersample<=8)
-				return(TIFFWriteDirectoryTagBytePerSample(tif,ndir,dir,tag,(uint8)value));
-			else if (tif->tif_dir.td_bitspersample<=16)
-				return(TIFFWriteDirectoryTagShortPerSample(tif,ndir,dir,tag,(uint16)value));
-			else
-				return(TIFFWriteDirectoryTagLongPerSample(tif,ndir,dir,tag,(uint32)value));
-		default:
-			return(1);
-	}
-}
-#endif
-
-static int
-TIFFWriteDirectoryTagAscii(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, char* value)
-{
-	if (dir==NULL)
-	{
-		(*ndir)++;
-		return(1);
-	}
-	return(TIFFWriteDirectoryTagCheckedAscii(tif,ndir,dir,tag,count,value));
-}
-
-static int
-TIFFWriteDirectoryTagUndefinedArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value)
-{
-	if (dir==NULL)
-	{
-		(*ndir)++;
-		return(1);
-	}
-	return(TIFFWriteDirectoryTagCheckedUndefinedArray(tif,ndir,dir,tag,count,value));
-}
-
-#ifdef notdef
-static int
-TIFFWriteDirectoryTagByte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value)
-{
-	if (dir==NULL)
-	{
-		(*ndir)++;
-		return(1);
-	}
-	return(TIFFWriteDirectoryTagCheckedByte(tif,ndir,dir,tag,value));
-}
-#endif
-
-static int
-TIFFWriteDirectoryTagByteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value)
-{
-	if (dir==NULL)
-	{
-		(*ndir)++;
-		return(1);
-	}
-	return(TIFFWriteDirectoryTagCheckedByteArray(tif,ndir,dir,tag,count,value));
-}
-
-#if 0
-static int
-TIFFWriteDirectoryTagBytePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value)
-{
-	static const char module[] = "TIFFWriteDirectoryTagBytePerSample";
-	uint8* m;
-	uint8* na;
-	uint16 nb;
-	int o;
-	if (dir==NULL)
-	{
-		(*ndir)++;
-		return(1);
-	}
-	m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(uint8));
-	if (m==NULL)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
-		return(0);
-	}
-	for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
-		*na=value;
-	o=TIFFWriteDirectoryTagCheckedByteArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
-	_TIFFfree(m);
-	return(o);
-}
-#endif
-
-#ifdef notdef
-static int
-TIFFWriteDirectoryTagSbyte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value)
-{
-	if (dir==NULL)
-	{
-		(*ndir)++;
-		return(1);
-	}
-	return(TIFFWriteDirectoryTagCheckedSbyte(tif,ndir,dir,tag,value));
-}
-#endif
-
-static int
-TIFFWriteDirectoryTagSbyteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int8* value)
-{
-	if (dir==NULL)
-	{
-		(*ndir)++;
-		return(1);
-	}
-	return(TIFFWriteDirectoryTagCheckedSbyteArray(tif,ndir,dir,tag,count,value));
-}
-
-#if 0
-static int
-TIFFWriteDirectoryTagSbytePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value)
-{
-	static const char module[] = "TIFFWriteDirectoryTagSbytePerSample";
-	int8* m;
-	int8* na;
-	uint16 nb;
-	int o;
-	if (dir==NULL)
-	{
-		(*ndir)++;
-		return(1);
-	}
-	m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(int8));
-	if (m==NULL)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
-		return(0);
-	}
-	for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
-		*na=value;
-	o=TIFFWriteDirectoryTagCheckedSbyteArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
-	_TIFFfree(m);
-	return(o);
-}
-#endif
-
-static int
-TIFFWriteDirectoryTagShort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value)
-{
-	if (dir==NULL)
-	{
-		(*ndir)++;
-		return(1);
-	}
-	return(TIFFWriteDirectoryTagCheckedShort(tif,ndir,dir,tag,value));
-}
-
-static int
-TIFFWriteDirectoryTagShortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint16* value)
-{
-	if (dir==NULL)
-	{
-		(*ndir)++;
-		return(1);
-	}
-	return(TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,tag,count,value));
-}
-
-static int
-TIFFWriteDirectoryTagShortPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value)
-{
-	static const char module[] = "TIFFWriteDirectoryTagShortPerSample";
-	uint16* m;
-	uint16* na;
-	uint16 nb;
-	int o;
-	if (dir==NULL)
-	{
-		(*ndir)++;
-		return(1);
-	}
-	m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(uint16));
-	if (m==NULL)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
-		return(0);
-	}
-	for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
-		*na=value;
-	o=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
-	_TIFFfree(m);
-	return(o);
-}
-
-#ifdef notdef
-static int
-TIFFWriteDirectoryTagSshort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value)
-{
-	if (dir==NULL)
-	{
-		(*ndir)++;
-		return(1);
-	}
-	return(TIFFWriteDirectoryTagCheckedSshort(tif,ndir,dir,tag,value));
-}
-#endif
-
-static int
-TIFFWriteDirectoryTagSshortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int16* value)
-{
-	if (dir==NULL)
-	{
-		(*ndir)++;
-		return(1);
-	}
-	return(TIFFWriteDirectoryTagCheckedSshortArray(tif,ndir,dir,tag,count,value));
-}
-
-#if 0
-static int
-TIFFWriteDirectoryTagSshortPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value)
-{
-	static const char module[] = "TIFFWriteDirectoryTagSshortPerSample";
-	int16* m;
-	int16* na;
-	uint16 nb;
-	int o;
-	if (dir==NULL)
-	{
-		(*ndir)++;
-		return(1);
-	}
-	m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(int16));
-	if (m==NULL)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
-		return(0);
-	}
-	for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
-		*na=value;
-	o=TIFFWriteDirectoryTagCheckedSshortArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
-	_TIFFfree(m);
-	return(o);
-}
-#endif
-
-static int
-TIFFWriteDirectoryTagLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value)
-{
-	if (dir==NULL)
-	{
-		(*ndir)++;
-		return(1);
-	}
-	return(TIFFWriteDirectoryTagCheckedLong(tif,ndir,dir,tag,value));
-}
-
-static int
-TIFFWriteDirectoryTagLongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value)
-{
-	if (dir==NULL)
-	{
-		(*ndir)++;
-		return(1);
-	}
-	return(TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,count,value));
-}
-
-#if 0
-static int
-TIFFWriteDirectoryTagLongPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value)
-{
-	static const char module[] = "TIFFWriteDirectoryTagLongPerSample";
-	uint32* m;
-	uint32* na;
-	uint16 nb;
-	int o;
-	if (dir==NULL)
-	{
-		(*ndir)++;
-		return(1);
-	}
-	m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(uint32));
-	if (m==NULL)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
-		return(0);
-	}
-	for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
-		*na=value;
-	o=TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
-	_TIFFfree(m);
-	return(o);
-}
-#endif
-
-#ifdef notdef
-static int
-TIFFWriteDirectoryTagSlong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value)
-{
-	if (dir==NULL)
-	{
-		(*ndir)++;
-		return(1);
-	}
-	return(TIFFWriteDirectoryTagCheckedSlong(tif,ndir,dir,tag,value));
-}
-#endif
-
-static int
-TIFFWriteDirectoryTagSlongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int32* value)
-{
-	if (dir==NULL)
-	{
-		(*ndir)++;
-		return(1);
-	}
-	return(TIFFWriteDirectoryTagCheckedSlongArray(tif,ndir,dir,tag,count,value));
-}
-
-#if 0
-static int
-TIFFWriteDirectoryTagSlongPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value)
-{
-	static const char module[] = "TIFFWriteDirectoryTagSlongPerSample";
-	int32* m;
-	int32* na;
-	uint16 nb;
-	int o;
-	if (dir==NULL)
-	{
-		(*ndir)++;
-		return(1);
-	}
-	m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(int32));
-	if (m==NULL)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
-		return(0);
-	}
-	for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
-		*na=value;
-	o=TIFFWriteDirectoryTagCheckedSlongArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
-	_TIFFfree(m);
-	return(o);
-}
-#endif
-
-#ifdef notdef
-static int
-TIFFWriteDirectoryTagLong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint64 value)
-{
-	if (dir==NULL)
-	{
-		(*ndir)++;
-		return(1);
-	}
-	return(TIFFWriteDirectoryTagCheckedLong8(tif,ndir,dir,tag,value));
-}
-#endif
-
-static int
-TIFFWriteDirectoryTagLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
-{
-	if (dir==NULL)
-	{
-		(*ndir)++;
-		return(1);
-	}
-	return(TIFFWriteDirectoryTagCheckedLong8Array(tif,ndir,dir,tag,count,value));
-}
-
-#ifdef notdef
-static int
-TIFFWriteDirectoryTagSlong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int64 value)
-{
-	if (dir==NULL)
-	{
-		(*ndir)++;
-		return(1);
-	}
-	return(TIFFWriteDirectoryTagCheckedSlong8(tif,ndir,dir,tag,value));
-}
-#endif
-
-static int
-TIFFWriteDirectoryTagSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int64* value)
-{
-	if (dir==NULL)
-	{
-		(*ndir)++;
-		return(1);
-	}
-	return(TIFFWriteDirectoryTagCheckedSlong8Array(tif,ndir,dir,tag,count,value));
-}
-
-static int
-TIFFWriteDirectoryTagRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
-{
-	if (dir==NULL)
-	{
-		(*ndir)++;
-		return(1);
-	}
-	return(TIFFWriteDirectoryTagCheckedRational(tif,ndir,dir,tag,value));
-}
-
-static int
-TIFFWriteDirectoryTagRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
-{
-	if (dir==NULL)
-	{
-		(*ndir)++;
-		return(1);
-	}
-	return(TIFFWriteDirectoryTagCheckedRationalArray(tif,ndir,dir,tag,count,value));
-}
-
-static int
-TIFFWriteDirectoryTagSrationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
-{
-	if (dir==NULL)
-	{
-		(*ndir)++;
-		return(1);
-	}
-	return(TIFFWriteDirectoryTagCheckedSrationalArray(tif,ndir,dir,tag,count,value));
-}
-
-#ifdef notdef
-static int TIFFWriteDirectoryTagFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value)
-{
-	if (dir==NULL)
-	{
-		(*ndir)++;
-		return(1);
-	}
-	return(TIFFWriteDirectoryTagCheckedFloat(tif,ndir,dir,tag,value));
-}
-#endif
-
-static int TIFFWriteDirectoryTagFloatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
-{
-	if (dir==NULL)
-	{
-		(*ndir)++;
-		return(1);
-	}
-	return(TIFFWriteDirectoryTagCheckedFloatArray(tif,ndir,dir,tag,count,value));
-}
-
-#if 0
-static int TIFFWriteDirectoryTagFloatPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value)
-{
-	static const char module[] = "TIFFWriteDirectoryTagFloatPerSample";
-	float* m;
-	float* na;
-	uint16 nb;
-	int o;
-	if (dir==NULL)
-	{
-		(*ndir)++;
-		return(1);
-	}
-	m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(float));
-	if (m==NULL)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
-		return(0);
-	}
-	for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
-		*na=value;
-	o=TIFFWriteDirectoryTagCheckedFloatArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
-	_TIFFfree(m);
-	return(o);
-}
-#endif
-
-#ifdef notdef
-static int TIFFWriteDirectoryTagDouble(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
-{
-	if (dir==NULL)
-	{
-		(*ndir)++;
-		return(1);
-	}
-	return(TIFFWriteDirectoryTagCheckedDouble(tif,ndir,dir,tag,value));
-}
-#endif
-
-static int TIFFWriteDirectoryTagDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value)
-{
-	if (dir==NULL)
-	{
-		(*ndir)++;
-		return(1);
-	}
-	return(TIFFWriteDirectoryTagCheckedDoubleArray(tif,ndir,dir,tag,count,value));
-}
-
-#if 0
-static int TIFFWriteDirectoryTagDoublePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
-{
-	static const char module[] = "TIFFWriteDirectoryTagDoublePerSample";
-	double* m;
-	double* na;
-	uint16 nb;
-	int o;
-	if (dir==NULL)
-	{
-		(*ndir)++;
-		return(1);
-	}
-	m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(double));
-	if (m==NULL)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
-		return(0);
-	}
-	for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
-		*na=value;
-	o=TIFFWriteDirectoryTagCheckedDoubleArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
-	_TIFFfree(m);
-	return(o);
-}
-#endif
-
-static int
-TIFFWriteDirectoryTagIfdArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value)
-{
-	if (dir==NULL)
-	{
-		(*ndir)++;
-		return(1);
-	}
-	return(TIFFWriteDirectoryTagCheckedIfdArray(tif,ndir,dir,tag,count,value));
-}
-
-#ifdef notdef
-static int
-TIFFWriteDirectoryTagIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
-{
-	if (dir==NULL)
-	{
-		(*ndir)++;
-		return(1);
-	}
-	return(TIFFWriteDirectoryTagCheckedIfd8Array(tif,ndir,dir,tag,count,value));
-}
-#endif
-
-static int
-TIFFWriteDirectoryTagShortLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value)
-{
-	if (dir==NULL)
-	{
-		(*ndir)++;
-		return(1);
-	}
-	if (value<=0xFFFF)
-		return(TIFFWriteDirectoryTagCheckedShort(tif,ndir,dir,tag,(uint16)value));
-	else
-		return(TIFFWriteDirectoryTagCheckedLong(tif,ndir,dir,tag,value));
-}
-
-/************************************************************************/
-/*                TIFFWriteDirectoryTagLongLong8Array()                 */
-/*                                                                      */
-/*      Write out LONG8 array as LONG8 for BigTIFF or LONG for          */
-/*      Classic TIFF with some checking.                                */
-/************************************************************************/
-
-static int
-TIFFWriteDirectoryTagLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
-{
-    static const char module[] = "TIFFWriteDirectoryTagLongLong8Array";
-    uint64* ma;
-    uint32 mb;
-    uint32* p;
-    uint32* q;
-    int o;
-
-    /* is this just a counting pass? */
-    if (dir==NULL)
-    {
-        (*ndir)++;
-        return(1);
-    }
-
-    /* We always write LONG8 for BigTIFF, no checking needed. */
-    if( tif->tif_flags&TIFF_BIGTIFF )
-        return TIFFWriteDirectoryTagCheckedLong8Array(tif,ndir,dir,
-                                                      tag,count,value);
-
-    /*
-    ** For classic tiff we want to verify everything is in range for LONG
-    ** and convert to long format.
-    */
-
-    p = _TIFFmalloc(count*sizeof(uint32));
-    if (p==NULL)
-    {
-        TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
-        return(0);
-    }
-
-    for (q=p, ma=value, mb=0; mb<count; ma++, mb++, q++)
-    {
-        if (*ma>0xFFFFFFFF)
-        {
-            TIFFErrorExt(tif->tif_clientdata,module,
-                         "Attempt to write value larger than 0xFFFFFFFF in Classic TIFF file.");
-            _TIFFfree(p);
-            return(0);
-        }
-        *q= (uint32)(*ma);
-    }
-
-    o=TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,count,p);
-    _TIFFfree(p);
-
-    return(o);
-}
-
-/************************************************************************/
-/*                 TIFFWriteDirectoryTagIfdIfd8Array()                  */
-/*                                                                      */
-/*      Write either IFD8 or IFD array depending on file type.          */
-/************************************************************************/
-
-static int
-TIFFWriteDirectoryTagIfdIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
-{
-    static const char module[] = "TIFFWriteDirectoryTagIfdIfd8Array";
-    uint64* ma;
-    uint32 mb;
-    uint32* p;
-    uint32* q;
-    int o;
-
-    /* is this just a counting pass? */
-    if (dir==NULL)
-    {
-        (*ndir)++;
-        return(1);
-    }
-
-    /* We always write IFD8 for BigTIFF, no checking needed. */
-    if( tif->tif_flags&TIFF_BIGTIFF )
-        return TIFFWriteDirectoryTagCheckedIfd8Array(tif,ndir,dir,
-                                                     tag,count,value);
-
-    /*
-    ** For classic tiff we want to verify everything is in range for IFD
-    ** and convert to long format.
-    */
-
-    p = _TIFFmalloc(count*sizeof(uint32));
-    if (p==NULL)
-    {
-        TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
-        return(0);
-    }
-
-    for (q=p, ma=value, mb=0; mb<count; ma++, mb++, q++)
-    {
-        if (*ma>0xFFFFFFFF)
-        {
-            TIFFErrorExt(tif->tif_clientdata,module,
-                         "Attempt to write value larger than 0xFFFFFFFF in Classic TIFF file.");
-            _TIFFfree(p);
-            return(0);
-        }
-        *q= (uint32)(*ma);
-    }
-
-    o=TIFFWriteDirectoryTagCheckedIfdArray(tif,ndir,dir,tag,count,p);
-    _TIFFfree(p);
-
-    return(o);
-}
-
-#ifdef notdef
-static int
-TIFFWriteDirectoryTagShortLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
-{
-	static const char module[] = "TIFFWriteDirectoryTagShortLongLong8Array";
-	uint64* ma;
-	uint32 mb;
-	uint8 n;
-	int o;
-	if (dir==NULL)
-	{
-		(*ndir)++;
-		return(1);
-	}
-	n=0;
-	for (ma=value, mb=0; mb<count; ma++, mb++)
-	{
-		if ((n==0)&&(*ma>0xFFFF))
-			n=1;
-		if ((n==1)&&(*ma>0xFFFFFFFF))
-		{
-			n=2;
-			break;
-		}
-	}
-	if (n==0)
-	{
-		uint16* p;
-		uint16* q;
-		p=_TIFFmalloc(count*sizeof(uint16));
-		if (p==NULL)
-		{
-			TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
-			return(0);
-		}
-		for (ma=value, mb=0, q=p; mb<count; ma++, mb++, q++)
-			*q=(uint16)(*ma);
-		o=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,tag,count,p);
-		_TIFFfree(p);
-	}
-	else if (n==1)
-	{
-		uint32* p;
-		uint32* q;
-		p=_TIFFmalloc(count*sizeof(uint32));
-		if (p==NULL)
-		{
-			TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
-			return(0);
-		}
-		for (ma=value, mb=0, q=p; mb<count; ma++, mb++, q++)
-			*q=(uint32)(*ma);
-		o=TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,count,p);
-		_TIFFfree(p);
-	}
-	else
-	{
-		assert(n==2);
-		o=TIFFWriteDirectoryTagCheckedLong8Array(tif,ndir,dir,tag,count,value);
-	}
-	return(o);
-}
-#endif
-static int
-TIFFWriteDirectoryTagColormap(TIFF* tif, uint32* ndir, TIFFDirEntry* dir)
-{
-	static const char module[] = "TIFFWriteDirectoryTagColormap";
-	uint32 m;
-	uint16* n;
-	int o;
-	if (dir==NULL)
-	{
-		(*ndir)++;
-		return(1);
-	}
-	m=(1<<tif->tif_dir.td_bitspersample);
-	n=_TIFFmalloc(3*m*sizeof(uint16));
-	if (n==NULL)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
-		return(0);
-	}
-	_TIFFmemcpy(&n[0],tif->tif_dir.td_colormap[0],m*sizeof(uint16));
-	_TIFFmemcpy(&n[m],tif->tif_dir.td_colormap[1],m*sizeof(uint16));
-	_TIFFmemcpy(&n[2*m],tif->tif_dir.td_colormap[2],m*sizeof(uint16));
-	o=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,TIFFTAG_COLORMAP,3*m,n);
-	_TIFFfree(n);
-	return(o);
-}
-
-static int
-TIFFWriteDirectoryTagTransferfunction(TIFF* tif, uint32* ndir, TIFFDirEntry* dir)
-{
-	static const char module[] = "TIFFWriteDirectoryTagTransferfunction";
-	uint32 m;
-	uint16 n;
-	uint16* o;
-	int p;
-	if (dir==NULL)
-	{
-		(*ndir)++;
-		return(1);
-	}
-	m=(1<<tif->tif_dir.td_bitspersample);
-	n=tif->tif_dir.td_samplesperpixel-tif->tif_dir.td_extrasamples;
-	/*
-	 * Check if the table can be written as a single column,
-	 * or if it must be written as 3 columns.  Note that we
-	 * write a 3-column tag if there are 2 samples/pixel and
-	 * a single column of data won't suffice--hmm.
-	 */
-	if (n>3)
-		n=3;
-	if (n==3)
-	{
-		if (!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],tif->tif_dir.td_transferfunction[2],m*sizeof(uint16)))
-			n=2;
-	}
-	if (n==2)
-	{
-		if (!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],tif->tif_dir.td_transferfunction[1],m*sizeof(uint16)))
-			n=1;
-	}
-	if (n==0)
-		n=1;
-	o=_TIFFmalloc(n*m*sizeof(uint16));
-	if (o==NULL)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
-		return(0);
-	}
-	_TIFFmemcpy(&o[0],tif->tif_dir.td_transferfunction[0],m*sizeof(uint16));
-	if (n>1)
-		_TIFFmemcpy(&o[m],tif->tif_dir.td_transferfunction[1],m*sizeof(uint16));
-	if (n>2)
-		_TIFFmemcpy(&o[2*m],tif->tif_dir.td_transferfunction[2],m*sizeof(uint16));
-	p=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,TIFFTAG_TRANSFERFUNCTION,n*m,o);
-	_TIFFfree(o);
-	return(p);
-}
-
-static int
-TIFFWriteDirectoryTagSubifd(TIFF* tif, uint32* ndir, TIFFDirEntry* dir)
-{
-	static const char module[] = "TIFFWriteDirectoryTagSubifd";
-	uint64 m;
-	int n;
-	if (tif->tif_dir.td_nsubifd==0)
-		return(1);
-	if (dir==NULL)
-	{
-		(*ndir)++;
-		return(1);
-	}
-	m=tif->tif_dataoff;
-	if (!(tif->tif_flags&TIFF_BIGTIFF))
-	{
-		uint32* o;
-		uint64* pa;
-		uint32* pb;
-		uint16 p;
-		o=_TIFFmalloc(tif->tif_dir.td_nsubifd*sizeof(uint32));
-		if (o==NULL)
-		{
-			TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
-			return(0);
-		}
-		pa=tif->tif_dir.td_subifd;
-		pb=o;
-		for (p=0; p < tif->tif_dir.td_nsubifd; p++)
-		{
-                        assert(pa != 0);
-			assert(*pa <= 0xFFFFFFFFUL);
-			*pb++=(uint32)(*pa++);
-		}
-		n=TIFFWriteDirectoryTagCheckedIfdArray(tif,ndir,dir,TIFFTAG_SUBIFD,tif->tif_dir.td_nsubifd,o);
-		_TIFFfree(o);
-	}
-	else
-		n=TIFFWriteDirectoryTagCheckedIfd8Array(tif,ndir,dir,TIFFTAG_SUBIFD,tif->tif_dir.td_nsubifd,tif->tif_dir.td_subifd);
-	if (!n)
-		return(0);
-	/*
-	 * Total hack: if this directory includes a SubIFD
-	 * tag then force the next <n> directories to be
-	 * written as ``sub directories'' of this one.  This
-	 * is used to write things like thumbnails and
-	 * image masks that one wants to keep out of the
-	 * normal directory linkage access mechanism.
-	 */
-	tif->tif_flags|=TIFF_INSUBIFD;
-	tif->tif_nsubifd=tif->tif_dir.td_nsubifd;
-	if (tif->tif_dir.td_nsubifd==1)
-		tif->tif_subifdoff=0;
-	else
-		tif->tif_subifdoff=m;
-	return(1);
-}
-
-static int
-TIFFWriteDirectoryTagCheckedAscii(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, char* value)
-{
-	assert(sizeof(char)==1);
-	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_ASCII,count,count,value));
-}
-
-static int
-TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value)
-{
-	assert(sizeof(uint8)==1);
-	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_UNDEFINED,count,count,value));
-}
-
-#ifdef notdef
-static int
-TIFFWriteDirectoryTagCheckedByte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value)
-{
-	assert(sizeof(uint8)==1);
-	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_BYTE,1,1,&value));
-}
-#endif
-
-static int
-TIFFWriteDirectoryTagCheckedByteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value)
-{
-	assert(sizeof(uint8)==1);
-	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_BYTE,count,count,value));
-}
-
-#ifdef notdef
-static int
-TIFFWriteDirectoryTagCheckedSbyte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value)
-{
-	assert(sizeof(int8)==1);
-	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SBYTE,1,1,&value));
-}
-#endif
-
-static int
-TIFFWriteDirectoryTagCheckedSbyteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int8* value)
-{
-	assert(sizeof(int8)==1);
-	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SBYTE,count,count,value));
-}
-
-static int
-TIFFWriteDirectoryTagCheckedShort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value)
-{
-	uint16 m;
-	assert(sizeof(uint16)==2);
-	m=value;
-	if (tif->tif_flags&TIFF_SWAB)
-		TIFFSwabShort(&m);
-	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SHORT,1,2,&m));
-}
-
-static int
-TIFFWriteDirectoryTagCheckedShortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint16* value)
-{
-	assert(count<0x80000000);
-	assert(sizeof(uint16)==2);
-	if (tif->tif_flags&TIFF_SWAB)
-		TIFFSwabArrayOfShort(value,count);
-	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SHORT,count,count*2,value));
-}
-
-#ifdef notdef
-static int
-TIFFWriteDirectoryTagCheckedSshort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value)
-{
-	int16 m;
-	assert(sizeof(int16)==2);
-	m=value;
-	if (tif->tif_flags&TIFF_SWAB)
-		TIFFSwabShort((uint16*)(&m));
-	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SSHORT,1,2,&m));
-}
-#endif
-
-static int
-TIFFWriteDirectoryTagCheckedSshortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int16* value)
-{
-	assert(count<0x80000000);
-	assert(sizeof(int16)==2);
-	if (tif->tif_flags&TIFF_SWAB)
-		TIFFSwabArrayOfShort((uint16*)value,count);
-	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SSHORT,count,count*2,value));
-}
-
-static int
-TIFFWriteDirectoryTagCheckedLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value)
-{
-	uint32 m;
-	assert(sizeof(uint32)==4);
-	m=value;
-	if (tif->tif_flags&TIFF_SWAB)
-		TIFFSwabLong(&m);
-	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG,1,4,&m));
-}
-
-static int
-TIFFWriteDirectoryTagCheckedLongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value)
-{
-	assert(count<0x40000000);
-	assert(sizeof(uint32)==4);
-	if (tif->tif_flags&TIFF_SWAB)
-		TIFFSwabArrayOfLong(value,count);
-	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG,count,count*4,value));
-}
-
-#ifdef notdef
-static int
-TIFFWriteDirectoryTagCheckedSlong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value)
-{
-	int32 m;
-	assert(sizeof(int32)==4);
-	m=value;
-	if (tif->tif_flags&TIFF_SWAB)
-		TIFFSwabLong((uint32*)(&m));
-	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG,1,4,&m));
-}
-#endif
-
-static int
-TIFFWriteDirectoryTagCheckedSlongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int32* value)
-{
-	assert(count<0x40000000);
-	assert(sizeof(int32)==4);
-	if (tif->tif_flags&TIFF_SWAB)
-		TIFFSwabArrayOfLong((uint32*)value,count);
-	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG,count,count*4,value));
-}
-
-#ifdef notdef
-static int
-TIFFWriteDirectoryTagCheckedLong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint64 value)
-{
-	uint64 m;
-	assert(sizeof(uint64)==8);
-	assert(tif->tif_flags&TIFF_BIGTIFF);
-	m=value;
-	if (tif->tif_flags&TIFF_SWAB)
-		TIFFSwabLong8(&m);
-	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG8,1,8,&m));
-}
-#endif
-
-static int
-TIFFWriteDirectoryTagCheckedLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
-{
-	assert(count<0x20000000);
-	assert(sizeof(uint64)==8);
-	assert(tif->tif_flags&TIFF_BIGTIFF);
-	if (tif->tif_flags&TIFF_SWAB)
-		TIFFSwabArrayOfLong8(value,count);
-	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG8,count,count*8,value));
-}
-
-#ifdef notdef
-static int
-TIFFWriteDirectoryTagCheckedSlong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int64 value)
-{
-	int64 m;
-	assert(sizeof(int64)==8);
-	assert(tif->tif_flags&TIFF_BIGTIFF);
-	m=value;
-	if (tif->tif_flags&TIFF_SWAB)
-		TIFFSwabLong8((uint64*)(&m));
-	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG8,1,8,&m));
-}
-#endif
-
-static int
-TIFFWriteDirectoryTagCheckedSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int64* value)
-{
-	assert(count<0x20000000);
-	assert(sizeof(int64)==8);
-	assert(tif->tif_flags&TIFF_BIGTIFF);
-	if (tif->tif_flags&TIFF_SWAB)
-		TIFFSwabArrayOfLong8((uint64*)value,count);
-	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG8,count,count*8,value));
-}
-
-static int
-TIFFWriteDirectoryTagCheckedRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
-{
-	uint32 m[2];
-	assert(value>=0.0);
-	assert(sizeof(uint32)==4);
-	if (value<=0.0)
-	{
-		m[0]=0;
-		m[1]=1;
-	}
-	else if (value==(double)(uint32)value)
-	{
-		m[0]=(uint32)value;
-		m[1]=1;
-	}
-	else if (value<1.0)
-	{
-		m[0]=(uint32)(value*0xFFFFFFFF);
-		m[1]=0xFFFFFFFF;
-	}
-	else
-	{
-		m[0]=0xFFFFFFFF;
-		m[1]=(uint32)(0xFFFFFFFF/value);
-	}
-	if (tif->tif_flags&TIFF_SWAB)
-	{
-		TIFFSwabLong(&m[0]);
-		TIFFSwabLong(&m[1]);
-	}
-	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_RATIONAL,1,8,&m[0]));
-}
-
-static int
-TIFFWriteDirectoryTagCheckedRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
-{
-	static const char module[] = "TIFFWriteDirectoryTagCheckedRationalArray";
-	uint32* m;
-	float* na;
-	uint32* nb;
-	uint32 nc;
-	int o;
-	assert(sizeof(uint32)==4);
-	m=_TIFFmalloc(count*2*sizeof(uint32));
-	if (m==NULL)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
-		return(0);
-	}
-	for (na=value, nb=m, nc=0; nc<count; na++, nb+=2, nc++)
-	{
-		if (*na<=0.0)
-		{
-			nb[0]=0;
-			nb[1]=1;
-		}
-		else if (*na==(float)(uint32)(*na))
-		{
-			nb[0]=(uint32)(*na);
-			nb[1]=1;
-		}
-		else if (*na<1.0)
-		{
-			nb[0]=(uint32)((*na)*0xFFFFFFFF);
-			nb[1]=0xFFFFFFFF;
-		}
-		else
-		{
-			nb[0]=0xFFFFFFFF;
-			nb[1]=(uint32)(0xFFFFFFFF/(*na));
-		}
-	}
-	if (tif->tif_flags&TIFF_SWAB)
-		TIFFSwabArrayOfLong(m,count*2);
-	o=TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_RATIONAL,count,count*8,&m[0]);
-	_TIFFfree(m);
-	return(o);
-}
-
-static int
-TIFFWriteDirectoryTagCheckedSrationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
-{
-	static const char module[] = "TIFFWriteDirectoryTagCheckedSrationalArray";
-	int32* m;
-	float* na;
-	int32* nb;
-	uint32 nc;
-	int o;
-	assert(sizeof(int32)==4);
-	m=_TIFFmalloc(count*2*sizeof(int32));
-	if (m==NULL)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
-		return(0);
-	}
-	for (na=value, nb=m, nc=0; nc<count; na++, nb+=2, nc++)
-	{
-		if (*na<0.0)
-		{
-			if (*na==(int32)(*na))
-			{
-				nb[0]=(int32)(*na);
-				nb[1]=1;
-			}
-			else if (*na>-1.0)
-			{
-				nb[0]=-(int32)((-*na)*0x7FFFFFFF);
-				nb[1]=0x7FFFFFFF;
-			}
-			else
-			{
-				nb[0]=-0x7FFFFFFF;
-				nb[1]=(int32)(0x7FFFFFFF/(-*na));
-			}
-		}
-		else
-		{
-			if (*na==(int32)(*na))
-			{
-				nb[0]=(int32)(*na);
-				nb[1]=1;
-			}
-			else if (*na<1.0)
-			{
-				nb[0]=(int32)((*na)*0x7FFFFFFF);
-				nb[1]=0x7FFFFFFF;
-			}
-			else
-			{
-				nb[0]=0x7FFFFFFF;
-				nb[1]=(int32)(0x7FFFFFFF/(*na));
-			}
-		}
-	}
-	if (tif->tif_flags&TIFF_SWAB)
-		TIFFSwabArrayOfLong((uint32*)m,count*2);
-	o=TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SRATIONAL,count,count*8,&m[0]);
-	_TIFFfree(m);
-	return(o);
-}
-
-#ifdef notdef
-static int
-TIFFWriteDirectoryTagCheckedFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value)
-{
-	float m;
-	assert(sizeof(float)==4);
-	m=value;
-	TIFFCvtNativeToIEEEFloat(tif,1,&m);
-	if (tif->tif_flags&TIFF_SWAB)
-		TIFFSwabFloat(&m);
-	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_FLOAT,1,4,&m));
-}
-#endif
-
-static int
-TIFFWriteDirectoryTagCheckedFloatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
-{
-	assert(count<0x40000000);
-	assert(sizeof(float)==4);
-	TIFFCvtNativeToIEEEFloat(tif,count,&value);
-	if (tif->tif_flags&TIFF_SWAB)
-		TIFFSwabArrayOfFloat(value,count);
-	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_FLOAT,count,count*4,value));
-}
-
-#ifdef notdef
-static int
-TIFFWriteDirectoryTagCheckedDouble(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
-{
-	double m;
-	assert(sizeof(double)==8);
-	m=value;
-	TIFFCvtNativeToIEEEDouble(tif,1,&m);
-	if (tif->tif_flags&TIFF_SWAB)
-		TIFFSwabDouble(&m);
-	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_DOUBLE,1,8,&m));
-}
-#endif
-
-static int
-TIFFWriteDirectoryTagCheckedDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value)
-{
-	assert(count<0x20000000);
-	assert(sizeof(double)==8);
-	TIFFCvtNativeToIEEEDouble(tif,count,&value);
-	if (tif->tif_flags&TIFF_SWAB)
-		TIFFSwabArrayOfDouble(value,count);
-	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_DOUBLE,count,count*8,value));
-}
-
-static int
-TIFFWriteDirectoryTagCheckedIfdArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value)
-{
-	assert(count<0x40000000);
-	assert(sizeof(uint32)==4);
-	if (tif->tif_flags&TIFF_SWAB)
-		TIFFSwabArrayOfLong(value,count);
-	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_IFD,count,count*4,value));
-}
-
-static int
-TIFFWriteDirectoryTagCheckedIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
-{
-	assert(count<0x20000000);
-	assert(sizeof(uint64)==8);
-	assert(tif->tif_flags&TIFF_BIGTIFF);
-	if (tif->tif_flags&TIFF_SWAB)
-		TIFFSwabArrayOfLong8(value,count);
-	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_IFD8,count,count*8,value));
-}
-
-static int
-TIFFWriteDirectoryTagData(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 datatype, uint32 count, uint32 datalength, void* data)
-{
-	static const char module[] = "TIFFWriteDirectoryTagData";
-	uint32 m;
-	m=0;
-	while (m<(*ndir))
-	{
-		assert(dir[m].tdir_tag!=tag);
-		if (dir[m].tdir_tag>tag)
-			break;
-		m++;
-	}
-	if (m<(*ndir))
-	{
-		uint32 n;
-		for (n=*ndir; n>m; n--)
-			dir[n]=dir[n-1];
-	}
-	dir[m].tdir_tag=tag;
-	dir[m].tdir_type=datatype;
-	dir[m].tdir_count=count;
-	dir[m].tdir_offset.toff_long8 = 0;
-	if (datalength<=((tif->tif_flags&TIFF_BIGTIFF)?0x8U:0x4U))
-		_TIFFmemcpy(&dir[m].tdir_offset,data,datalength);
-	else
-	{
-		uint64 na,nb;
-		na=tif->tif_dataoff;
-		nb=na+datalength;
-		if (!(tif->tif_flags&TIFF_BIGTIFF))
-			nb=(uint32)nb;
-		if ((nb<na)||(nb<datalength))
-		{
-			TIFFErrorExt(tif->tif_clientdata,module,"Maximum TIFF file size exceeded");
-			return(0);
-		}
-		if (!SeekOK(tif,na))
-		{
-			TIFFErrorExt(tif->tif_clientdata,module,"IO error writing tag data");
-			return(0);
-		}
-		assert(datalength<0x80000000UL);
-		if (!WriteOK(tif,data,(tmsize_t)datalength))
-		{
-			TIFFErrorExt(tif->tif_clientdata,module,"IO error writing tag data");
-			return(0);
-		}
-		tif->tif_dataoff=nb;
-		if (tif->tif_dataoff&1)
-			tif->tif_dataoff++;
-		if (!(tif->tif_flags&TIFF_BIGTIFF))
-		{
-			uint32 o;
-			o=(uint32)na;
-			if (tif->tif_flags&TIFF_SWAB)
-				TIFFSwabLong(&o);
-			_TIFFmemcpy(&dir[m].tdir_offset,&o,4);
-		}
-		else
-		{
-			dir[m].tdir_offset.toff_long8 = na;
-			if (tif->tif_flags&TIFF_SWAB)
-				TIFFSwabLong8(&dir[m].tdir_offset.toff_long8);
-		}
-	}
-	(*ndir)++;
-	return(1);
-}
-
-/*
- * Link the current directory into the directory chain for the file.
- */
-static int
-TIFFLinkDirectory(TIFF* tif)
-{
-	static const char module[] = "TIFFLinkDirectory";
-
-	tif->tif_diroff = (TIFFSeekFile(tif,0,SEEK_END)+1) &~ 1;
-
-	/*
-	 * Handle SubIFDs
-	 */
-	if (tif->tif_flags & TIFF_INSUBIFD)
-	{
-		if (!(tif->tif_flags&TIFF_BIGTIFF))
-		{
-			uint32 m;
-			m = (uint32)tif->tif_diroff;
-			if (tif->tif_flags & TIFF_SWAB)
-				TIFFSwabLong(&m);
-			(void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
-			if (!WriteOK(tif, &m, 4)) {
-				TIFFErrorExt(tif->tif_clientdata, module,
-				     "Error writing SubIFD directory link");
-				return (0);
-			}
-			/*
-			 * Advance to the next SubIFD or, if this is
-			 * the last one configured, revert back to the
-			 * normal directory linkage.
-			 */
-			if (--tif->tif_nsubifd)
-				tif->tif_subifdoff += 4;
-			else
-				tif->tif_flags &= ~TIFF_INSUBIFD;
-			return (1);
-		}
-		else
-		{
-			uint64 m;
-			m = tif->tif_diroff;
-			if (tif->tif_flags & TIFF_SWAB)
-				TIFFSwabLong8(&m);
-			(void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
-			if (!WriteOK(tif, &m, 8)) {
-				TIFFErrorExt(tif->tif_clientdata, module,
-				     "Error writing SubIFD directory link");
-				return (0);
-			}
-			/*
-			 * Advance to the next SubIFD or, if this is
-			 * the last one configured, revert back to the
-			 * normal directory linkage.
-			 */
-			if (--tif->tif_nsubifd)
-				tif->tif_subifdoff += 8;
-			else
-				tif->tif_flags &= ~TIFF_INSUBIFD;
-			return (1);
-		}
-	}
-
-	if (!(tif->tif_flags&TIFF_BIGTIFF))
-	{
-		uint32 m;
-		uint32 nextdir;
-		m = (uint32)(tif->tif_diroff);
-		if (tif->tif_flags & TIFF_SWAB)
-			TIFFSwabLong(&m);
-		if (tif->tif_header.classic.tiff_diroff == 0) {
-			/*
-			 * First directory, overwrite offset in header.
-			 */
-			tif->tif_header.classic.tiff_diroff = (uint32) tif->tif_diroff;
-			(void) TIFFSeekFile(tif,4, SEEK_SET);
-			if (!WriteOK(tif, &m, 4)) {
-				TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-					     "Error writing TIFF header");
-				return (0);
-			}
-			return (1);
-		}
-		/*
-		 * Not the first directory, search to the last and append.
-		 */
-		nextdir = tif->tif_header.classic.tiff_diroff;
-		while(1) {
-			uint16 dircount;
-			uint32 nextnextdir;
-
-			if (!SeekOK(tif, nextdir) ||
-			    !ReadOK(tif, &dircount, 2)) {
-				TIFFErrorExt(tif->tif_clientdata, module,
-					     "Error fetching directory count");
-				return (0);
-			}
-			if (tif->tif_flags & TIFF_SWAB)
-				TIFFSwabShort(&dircount);
-			(void) TIFFSeekFile(tif,
-			    nextdir+2+dircount*12, SEEK_SET);
-			if (!ReadOK(tif, &nextnextdir, 4)) {
-				TIFFErrorExt(tif->tif_clientdata, module,
-					     "Error fetching directory link");
-				return (0);
-			}
-			if (tif->tif_flags & TIFF_SWAB)
-				TIFFSwabLong(&nextnextdir);
-			if (nextnextdir==0)
-			{
-				(void) TIFFSeekFile(tif,
-				    nextdir+2+dircount*12, SEEK_SET);
-				if (!WriteOK(tif, &m, 4)) {
-					TIFFErrorExt(tif->tif_clientdata, module,
-					     "Error writing directory link");
-					return (0);
-				}
-				break;
-			}
-			nextdir=nextnextdir;
-		}
-	}
-	else
-	{
-		uint64 m;
-		uint64 nextdir;
-		m = tif->tif_diroff;
-		if (tif->tif_flags & TIFF_SWAB)
-			TIFFSwabLong8(&m);
-		if (tif->tif_header.big.tiff_diroff == 0) {
-			/*
-			 * First directory, overwrite offset in header.
-			 */
-			tif->tif_header.big.tiff_diroff = tif->tif_diroff;
-			(void) TIFFSeekFile(tif,8, SEEK_SET);
-			if (!WriteOK(tif, &m, 8)) {
-				TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-					     "Error writing TIFF header");
-				return (0);
-			}
-			return (1);
-		}
-		/*
-		 * Not the first directory, search to the last and append.
-		 */
-		nextdir = tif->tif_header.big.tiff_diroff;
-		while(1) {
-			uint64 dircount64;
-			uint16 dircount;
-			uint64 nextnextdir;
-
-			if (!SeekOK(tif, nextdir) ||
-			    !ReadOK(tif, &dircount64, 8)) {
-				TIFFErrorExt(tif->tif_clientdata, module,
-					     "Error fetching directory count");
-				return (0);
-			}
-			if (tif->tif_flags & TIFF_SWAB)
-				TIFFSwabLong8(&dircount64);
-			if (dircount64>0xFFFF)
-			{
-				TIFFErrorExt(tif->tif_clientdata, module,
-					     "Sanity check on tag count failed, likely corrupt TIFF");
-				return (0);
-			}
-			dircount=(uint16)dircount64;
-			(void) TIFFSeekFile(tif,
-			    nextdir+8+dircount*20, SEEK_SET);
-			if (!ReadOK(tif, &nextnextdir, 8)) {
-				TIFFErrorExt(tif->tif_clientdata, module,
-					     "Error fetching directory link");
-				return (0);
-			}
-			if (tif->tif_flags & TIFF_SWAB)
-				TIFFSwabLong8(&nextnextdir);
-			if (nextnextdir==0)
-			{
-				(void) TIFFSeekFile(tif,
-				    nextdir+8+dircount*20, SEEK_SET);
-				if (!WriteOK(tif, &m, 8)) {
-					TIFFErrorExt(tif->tif_clientdata, module,
-					     "Error writing directory link");
-					return (0);
-				}
-				break;
-			}
-			nextdir=nextnextdir;
-		}
-	}
-	return (1);
-}
-
-/************************************************************************/
-/*                          TIFFRewriteField()                          */
-/*                                                                      */
-/*      Rewrite a field in the directory on disk without regard to      */
-/*      updating the TIFF directory structure in memory.  Currently     */
-/*      only supported for field that already exist in the on-disk      */
-/*      directory.  Mainly used for updating stripoffset /              */
-/*      stripbytecount values after the directory is already on         */
-/*      disk.                                                           */
-/*                                                                      */
-/*      Returns zero on failure, and one on success.                    */
-/************************************************************************/
-
-int
-_TIFFRewriteField(TIFF* tif, uint16 tag, TIFFDataType in_datatype, 
-                  tmsize_t count, void* data)
-{
-    static const char module[] = "TIFFResetField";
-    /* const TIFFField* fip = NULL; */
-    uint16 dircount;
-    tmsize_t dirsize;
-    uint8 direntry_raw[20];
-    uint16 entry_tag = 0;
-    uint16 entry_type = 0;
-    uint64 entry_count = 0;
-    uint64 entry_offset = 0;
-    int    value_in_entry = 0;
-    uint64 read_offset;
-    uint8 *buf_to_write = NULL;
-    TIFFDataType datatype;
-
-/* -------------------------------------------------------------------- */
-/*      Find field definition.                                          */
-/* -------------------------------------------------------------------- */
-    /*fip =*/ TIFFFindField(tif, tag, TIFF_ANY);
-
-/* -------------------------------------------------------------------- */
-/*      Do some checking this is a straight forward case.               */
-/* -------------------------------------------------------------------- */
-    if( isMapped(tif) )
-    {
-        TIFFErrorExt( tif->tif_clientdata, module, 
-                      "Memory mapped files not currently supported for this operation." );
-        return 0;
-    }
-
-    if( tif->tif_diroff == 0 )
-    {
-        TIFFErrorExt( tif->tif_clientdata, module, 
-                      "Attempt to reset field on directory not already on disk." );
-        return 0;
-    }
-
-/* -------------------------------------------------------------------- */
-/*      Read the directory entry count.                                 */
-/* -------------------------------------------------------------------- */
-    if (!SeekOK(tif, tif->tif_diroff)) {
-        TIFFErrorExt(tif->tif_clientdata, module,
-                     "%s: Seek error accessing TIFF directory",
-                     tif->tif_name);
-        return 0;
-    }
-
-    read_offset = tif->tif_diroff;
-
-    if (!(tif->tif_flags&TIFF_BIGTIFF))
-    {
-        if (!ReadOK(tif, &dircount, sizeof (uint16))) {
-            TIFFErrorExt(tif->tif_clientdata, module,
-                         "%s: Can not read TIFF directory count",
-                         tif->tif_name);
-            return 0;
-        }
-        if (tif->tif_flags & TIFF_SWAB)
-            TIFFSwabShort(&dircount);
-        dirsize = 12;
-        read_offset += 2;
-    } else {
-        uint64 dircount64;
-        if (!ReadOK(tif, &dircount64, sizeof (uint64))) {
-            TIFFErrorExt(tif->tif_clientdata, module,
-                         "%s: Can not read TIFF directory count",
-                         tif->tif_name);
-            return 0;
-        }
-        if (tif->tif_flags & TIFF_SWAB)
-            TIFFSwabLong8(&dircount64);
-        dircount = (uint16)dircount64;
-        dirsize = 20;
-        read_offset += 8;
-    }
-
-/* -------------------------------------------------------------------- */
-/*      Read through directory to find target tag.                      */
-/* -------------------------------------------------------------------- */
-    while( dircount > 0 )
-    {
-        if (!ReadOK(tif, direntry_raw, dirsize)) {
-            TIFFErrorExt(tif->tif_clientdata, module,
-                         "%s: Can not read TIFF directory entry.",
-                         tif->tif_name);
-            return 0;
-        }
-
-        memcpy( &entry_tag, direntry_raw + 0, sizeof(uint16) );
-        if (tif->tif_flags&TIFF_SWAB)
-            TIFFSwabShort( &entry_tag );
-
-        if( entry_tag == tag )
-            break;
-
-        read_offset += dirsize;
-    }
-
-    if( entry_tag != tag )
-    {
-        TIFFErrorExt(tif->tif_clientdata, module,
-                     "%s: Could not find tag %d.",
-                     tif->tif_name, tag );
-        return 0;
-    }
-
-/* -------------------------------------------------------------------- */
-/*      Extract the type, count and offset for this entry.              */
-/* -------------------------------------------------------------------- */
-    memcpy( &entry_type, direntry_raw + 2, sizeof(uint16) );
-    if (tif->tif_flags&TIFF_SWAB)
-        TIFFSwabShort( &entry_type );
-
-    if (!(tif->tif_flags&TIFF_BIGTIFF))
-    {
-        uint32 value;
-        
-        memcpy( &value, direntry_raw + 4, sizeof(uint32) );
-        if (tif->tif_flags&TIFF_SWAB)
-            TIFFSwabLong( &value );
-        entry_count = value;
-
-        memcpy( &value, direntry_raw + 8, sizeof(uint32) );
-        if (tif->tif_flags&TIFF_SWAB)
-            TIFFSwabLong( &value );
-        entry_offset = value;
-    }
-    else
-    {
-        memcpy( &entry_count, direntry_raw + 4, sizeof(uint64) );
-        if (tif->tif_flags&TIFF_SWAB)
-            TIFFSwabLong8( &entry_count );
-
-        memcpy( &entry_offset, direntry_raw + 12, sizeof(uint64) );
-        if (tif->tif_flags&TIFF_SWAB)
-            TIFFSwabLong8( &entry_offset );
-    }
-
-/* -------------------------------------------------------------------- */
-/*      What data type do we want to write this as?                     */
-/* -------------------------------------------------------------------- */
-    if( TIFFDataWidth(in_datatype) == 8 && !(tif->tif_flags&TIFF_BIGTIFF) )
-    {
-        if( in_datatype == TIFF_LONG8 )
-            datatype = TIFF_LONG;
-        else if( in_datatype == TIFF_SLONG8 )
-            datatype = TIFF_SLONG;
-        else if( in_datatype == TIFF_IFD8 )
-            datatype = TIFF_IFD;
-        else
-            datatype = in_datatype;
-    }
-    else 
-        datatype = in_datatype;
-
-/* -------------------------------------------------------------------- */
-/*      Prepare buffer of actual data to write.  This includes          */
-/*      swabbing as needed.                                             */
-/* -------------------------------------------------------------------- */
-    buf_to_write =
-	    (uint8 *)_TIFFCheckMalloc(tif, count, TIFFDataWidth(datatype),
-				      "for field buffer.");
-    if (!buf_to_write)
-        return 0;
-
-    if( datatype == in_datatype )
-        memcpy( buf_to_write, data, count * TIFFDataWidth(datatype) );
-    else if( datatype == TIFF_SLONG && in_datatype == TIFF_SLONG8 )
-    {
-	tmsize_t i;
-
-        for( i = 0; i < count; i++ )
-        {
-            ((int32 *) buf_to_write)[i] = 
-                (int32) ((int64 *) data)[i];
-            if( (int64) ((int32 *) buf_to_write)[i] != ((int64 *) data)[i] )
-            {
-                _TIFFfree( buf_to_write );
-                TIFFErrorExt( tif->tif_clientdata, module, 
-                              "Value exceeds 32bit range of output type." );
-                return 0;
-            }
-        }
-    }
-    else if( (datatype == TIFF_LONG && in_datatype == TIFF_LONG8)
-             || (datatype == TIFF_IFD && in_datatype == TIFF_IFD8) )
-    {
-	tmsize_t i;
-
-        for( i = 0; i < count; i++ )
-        {
-            ((uint32 *) buf_to_write)[i] = 
-                (uint32) ((uint64 *) data)[i];
-            if( (uint64) ((uint32 *) buf_to_write)[i] != ((uint64 *) data)[i] )
-            {
-                _TIFFfree( buf_to_write );
-                TIFFErrorExt( tif->tif_clientdata, module, 
-                              "Value exceeds 32bit range of output type." );
-                return 0;
-            }
-        }
-    }
-
-    if( TIFFDataWidth(datatype) > 1 && (tif->tif_flags&TIFF_SWAB) )
-    {
-        if( TIFFDataWidth(datatype) == 2 )
-            TIFFSwabArrayOfShort( (uint16 *) buf_to_write, count );
-        else if( TIFFDataWidth(datatype) == 4 )
-            TIFFSwabArrayOfLong( (uint32 *) buf_to_write, count );
-        else if( TIFFDataWidth(datatype) == 8 )
-            TIFFSwabArrayOfLong8( (uint64 *) buf_to_write, count );
-    }
-
-/* -------------------------------------------------------------------- */
-/*      Is this a value that fits into the directory entry?             */
-/* -------------------------------------------------------------------- */
-    if (!(tif->tif_flags&TIFF_BIGTIFF))
-    {
-        if( TIFFDataWidth(datatype) * count <= 4 )
-        {
-            entry_offset = read_offset + 8;
-            value_in_entry = 1;
-        }
-    }
-    else
-    {
-        if( TIFFDataWidth(datatype) * count <= 8 )
-        {
-            entry_offset = read_offset + 12;
-            value_in_entry = 1;
-        }
-    }
-
-/* -------------------------------------------------------------------- */
-/*      If the tag type, and count match, then we just write it out     */
-/*      over the old values without altering the directory entry at     */
-/*      all.                                                            */
-/* -------------------------------------------------------------------- */
-    if( entry_count == (uint64)count && entry_type == (uint16) datatype )
-    {
-        if (!SeekOK(tif, entry_offset)) {
-            _TIFFfree( buf_to_write );
-            TIFFErrorExt(tif->tif_clientdata, module,
-                         "%s: Seek error accessing TIFF directory",
-                         tif->tif_name);
-            return 0;
-        }
-        if (!WriteOK(tif, buf_to_write, count*TIFFDataWidth(datatype))) {
-            _TIFFfree( buf_to_write );
-            TIFFErrorExt(tif->tif_clientdata, module,
-                         "Error writing directory link");
-            return (0);
-        }
-
-        _TIFFfree( buf_to_write );
-        return 1;
-    }
-
-/* -------------------------------------------------------------------- */
-/*      Otherwise, we write the new tag data at the end of the file.    */
-/* -------------------------------------------------------------------- */
-    if( !value_in_entry )
-    {
-        entry_offset = TIFFSeekFile(tif,0,SEEK_END);
-        
-        if (!WriteOK(tif, buf_to_write, count*TIFFDataWidth(datatype))) {
-            _TIFFfree( buf_to_write );
-            TIFFErrorExt(tif->tif_clientdata, module,
-                         "Error writing directory link");
-            return (0);
-        }
-        
-        _TIFFfree( buf_to_write );
-    }
-    else
-    {
-        memcpy( &entry_offset, buf_to_write, count*TIFFDataWidth(datatype));
-    }
-
-/* -------------------------------------------------------------------- */
-/*      Adjust the directory entry.                                     */
-/* -------------------------------------------------------------------- */
-    entry_type = datatype;
-    memcpy( direntry_raw + 2, &entry_type, sizeof(uint16) );
-    if (tif->tif_flags&TIFF_SWAB)
-        TIFFSwabShort( (uint16 *) (direntry_raw + 2) );
-
-    if (!(tif->tif_flags&TIFF_BIGTIFF))
-    {
-        uint32 value;
-
-        value = (uint32) entry_count;
-        memcpy( direntry_raw + 4, &value, sizeof(uint32) );
-        if (tif->tif_flags&TIFF_SWAB)
-            TIFFSwabLong( (uint32 *) (direntry_raw + 4) );
-
-        value = (uint32) entry_offset;
-        memcpy( direntry_raw + 8, &value, sizeof(uint32) );
-        if (tif->tif_flags&TIFF_SWAB)
-            TIFFSwabLong( (uint32 *) (direntry_raw + 8) );
-    }
-    else
-    {
-        memcpy( direntry_raw + 4, &entry_count, sizeof(uint64) );
-        if (tif->tif_flags&TIFF_SWAB)
-            TIFFSwabLong8( (uint64 *) (direntry_raw + 4) );
-
-        memcpy( direntry_raw + 12, &entry_offset, sizeof(uint64) );
-        if (tif->tif_flags&TIFF_SWAB)
-            TIFFSwabLong8( (uint64 *) (direntry_raw + 12) );
-    }
-
-/* -------------------------------------------------------------------- */
-/*      Write the directory entry out to disk.                          */
-/* -------------------------------------------------------------------- */
-    if (!SeekOK(tif, read_offset )) {
-        TIFFErrorExt(tif->tif_clientdata, module,
-                     "%s: Seek error accessing TIFF directory",
-                     tif->tif_name);
-        return 0;
-    }
-
-    if (!WriteOK(tif, direntry_raw,dirsize))
-    {
-        TIFFErrorExt(tif->tif_clientdata, module,
-                     "%s: Can not write TIFF directory entry.",
-                     tif->tif_name);
-        return 0;
-    }
-    
-    return 1;
-}
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Id: tif_dirwrite.c,v 1.11 2015/02/19 22:39:58 drolon Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Directory Write Support Routines.
+ */
+#include "tiffiop.h"
+
+#ifdef HAVE_IEEEFP
+#define TIFFCvtNativeToIEEEFloat(tif, n, fp)
+#define TIFFCvtNativeToIEEEDouble(tif, n, dp)
+#else
+extern void TIFFCvtNativeToIEEEFloat(TIFF* tif, uint32 n, float* fp);
+extern void TIFFCvtNativeToIEEEDouble(TIFF* tif, uint32 n, double* dp);
+#endif
+
+static int TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff);
+
+static int TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value);
+#if 0
+static int TIFFWriteDirectoryTagSampleformatPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value);
+#endif
+
+static int TIFFWriteDirectoryTagAscii(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, char* value);
+static int TIFFWriteDirectoryTagUndefinedArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagByte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value);
+#endif
+static int TIFFWriteDirectoryTagByteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value);
+#if 0
+static int TIFFWriteDirectoryTagBytePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value);
+#endif
+#ifdef notdef
+static int TIFFWriteDirectoryTagSbyte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value);
+#endif
+static int TIFFWriteDirectoryTagSbyteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int8* value);
+#if 0
+static int TIFFWriteDirectoryTagSbytePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value);
+#endif
+static int TIFFWriteDirectoryTagShort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value);
+static int TIFFWriteDirectoryTagShortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint16* value);
+static int TIFFWriteDirectoryTagShortPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagSshort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value);
+#endif
+static int TIFFWriteDirectoryTagSshortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int16* value);
+#if 0
+static int TIFFWriteDirectoryTagSshortPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value);
+#endif
+static int TIFFWriteDirectoryTagLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value);
+static int TIFFWriteDirectoryTagLongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value);
+#if 0
+static int TIFFWriteDirectoryTagLongPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value);
+#endif
+#ifdef notdef
+static int TIFFWriteDirectoryTagSlong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value);
+#endif
+static int TIFFWriteDirectoryTagSlongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int32* value);
+#if 0
+static int TIFFWriteDirectoryTagSlongPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value);
+#endif
+#ifdef notdef
+static int TIFFWriteDirectoryTagLong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint64 value);
+#endif
+static int TIFFWriteDirectoryTagLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagSlong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int64 value);
+#endif
+static int TIFFWriteDirectoryTagSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int64* value);
+static int TIFFWriteDirectoryTagRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value);
+static int TIFFWriteDirectoryTagRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value);
+static int TIFFWriteDirectoryTagSrationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value);
+#endif
+static int TIFFWriteDirectoryTagFloatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value);
+#if 0
+static int TIFFWriteDirectoryTagFloatPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value);
+#endif
+#ifdef notdef
+static int TIFFWriteDirectoryTagDouble(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value);
+#endif
+static int TIFFWriteDirectoryTagDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value);
+#if 0
+static int TIFFWriteDirectoryTagDoublePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value);
+#endif
+static int TIFFWriteDirectoryTagIfdArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
+#endif
+static int TIFFWriteDirectoryTagShortLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value);
+static int TIFFWriteDirectoryTagLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
+static int TIFFWriteDirectoryTagIfdIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagShortLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
+#endif
+static int TIFFWriteDirectoryTagColormap(TIFF* tif, uint32* ndir, TIFFDirEntry* dir);
+static int TIFFWriteDirectoryTagTransferfunction(TIFF* tif, uint32* ndir, TIFFDirEntry* dir);
+static int TIFFWriteDirectoryTagSubifd(TIFF* tif, uint32* ndir, TIFFDirEntry* dir);
+
+static int TIFFWriteDirectoryTagCheckedAscii(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, char* value);
+static int TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagCheckedByte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value);
+#endif
+static int TIFFWriteDirectoryTagCheckedByteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagCheckedSbyte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value);
+#endif
+static int TIFFWriteDirectoryTagCheckedSbyteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int8* value);
+static int TIFFWriteDirectoryTagCheckedShort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value);
+static int TIFFWriteDirectoryTagCheckedShortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint16* value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagCheckedSshort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value);
+#endif
+static int TIFFWriteDirectoryTagCheckedSshortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int16* value);
+static int TIFFWriteDirectoryTagCheckedLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value);
+static int TIFFWriteDirectoryTagCheckedLongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagCheckedSlong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value);
+#endif
+static int TIFFWriteDirectoryTagCheckedSlongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int32* value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagCheckedLong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint64 value);
+#endif
+static int TIFFWriteDirectoryTagCheckedLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagCheckedSlong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int64 value);
+#endif
+static int TIFFWriteDirectoryTagCheckedSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int64* value);
+static int TIFFWriteDirectoryTagCheckedRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value);
+static int TIFFWriteDirectoryTagCheckedRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value);
+static int TIFFWriteDirectoryTagCheckedSrationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagCheckedFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value);
+#endif
+static int TIFFWriteDirectoryTagCheckedFloatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagCheckedDouble(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value);
+#endif
+static int TIFFWriteDirectoryTagCheckedDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value);
+static int TIFFWriteDirectoryTagCheckedIfdArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value);
+static int TIFFWriteDirectoryTagCheckedIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
+
+static int TIFFWriteDirectoryTagData(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 datatype, uint32 count, uint32 datalength, void* data);
+
+static int TIFFLinkDirectory(TIFF*);
+
+/*
+ * Write the contents of the current directory
+ * to the specified file.  This routine doesn't
+ * handle overwriting a directory with auxiliary
+ * storage that's been changed.
+ */
+int
+TIFFWriteDirectory(TIFF* tif)
+{
+	return TIFFWriteDirectorySec(tif,TRUE,TRUE,NULL);
+}
+
+/*
+ * Similar to TIFFWriteDirectory(), writes the directory out
+ * but leaves all data structures in memory so that it can be
+ * written again.  This will make a partially written TIFF file
+ * readable before it is successfully completed/closed.
+ */
+int
+TIFFCheckpointDirectory(TIFF* tif)
+{
+	int rc;
+	/* Setup the strips arrays, if they haven't already been. */
+	if (tif->tif_dir.td_stripoffset == NULL)
+	    (void) TIFFSetupStrips(tif);
+	rc = TIFFWriteDirectorySec(tif,TRUE,FALSE,NULL);
+	(void) TIFFSetWriteOffset(tif, TIFFSeekFile(tif, 0, SEEK_END));
+	return rc;
+}
+
+int
+TIFFWriteCustomDirectory(TIFF* tif, uint64* pdiroff)
+{
+	return TIFFWriteDirectorySec(tif,FALSE,FALSE,pdiroff);
+}
+
+/*
+ * Similar to TIFFWriteDirectory(), but if the directory has already
+ * been written once, it is relocated to the end of the file, in case it
+ * has changed in size.  Note that this will result in the loss of the
+ * previously used directory space. 
+ */ 
+int
+TIFFRewriteDirectory( TIFF *tif )
+{
+	static const char module[] = "TIFFRewriteDirectory";
+
+	/* We don't need to do anything special if it hasn't been written. */
+	if( tif->tif_diroff == 0 )
+		return TIFFWriteDirectory( tif );
+
+	/*
+	 * Find and zero the pointer to this directory, so that TIFFLinkDirectory
+	 * will cause it to be added after this directories current pre-link.
+	 */
+
+	if (!(tif->tif_flags&TIFF_BIGTIFF))
+	{
+		if (tif->tif_header.classic.tiff_diroff == tif->tif_diroff)
+		{
+			tif->tif_header.classic.tiff_diroff = 0;
+			tif->tif_diroff = 0;
+
+			TIFFSeekFile(tif,4,SEEK_SET);
+			if (!WriteOK(tif, &(tif->tif_header.classic.tiff_diroff),4))
+			{
+				TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+				    "Error updating TIFF header");
+				return (0);
+			}
+		}
+		else
+		{
+			uint32 nextdir;
+			nextdir = tif->tif_header.classic.tiff_diroff;
+			while(1) {
+				uint16 dircount;
+				uint32 nextnextdir;
+
+				if (!SeekOK(tif, nextdir) ||
+				    !ReadOK(tif, &dircount, 2)) {
+					TIFFErrorExt(tif->tif_clientdata, module,
+					     "Error fetching directory count");
+					return (0);
+				}
+				if (tif->tif_flags & TIFF_SWAB)
+					TIFFSwabShort(&dircount);
+				(void) TIFFSeekFile(tif,
+				    nextdir+2+dircount*12, SEEK_SET);
+				if (!ReadOK(tif, &nextnextdir, 4)) {
+					TIFFErrorExt(tif->tif_clientdata, module,
+					     "Error fetching directory link");
+					return (0);
+				}
+				if (tif->tif_flags & TIFF_SWAB)
+					TIFFSwabLong(&nextnextdir);
+				if (nextnextdir==tif->tif_diroff)
+				{
+					uint32 m;
+					m=0;
+					(void) TIFFSeekFile(tif,
+					    nextdir+2+dircount*12, SEEK_SET);
+					if (!WriteOK(tif, &m, 4)) {
+						TIFFErrorExt(tif->tif_clientdata, module,
+						     "Error writing directory link");
+						return (0);
+					}
+					tif->tif_diroff=0;
+					break;
+				}
+				nextdir=nextnextdir;
+			}
+		}
+	}
+	else
+	{
+		if (tif->tif_header.big.tiff_diroff == tif->tif_diroff)
+		{
+			tif->tif_header.big.tiff_diroff = 0;
+			tif->tif_diroff = 0;
+
+			TIFFSeekFile(tif,8,SEEK_SET);
+			if (!WriteOK(tif, &(tif->tif_header.big.tiff_diroff),8))
+			{
+				TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+				    "Error updating TIFF header");
+				return (0);
+			}
+		}
+		else
+		{
+			uint64 nextdir;
+			nextdir = tif->tif_header.big.tiff_diroff;
+			while(1) {
+				uint64 dircount64;
+				uint16 dircount;
+				uint64 nextnextdir;
+
+				if (!SeekOK(tif, nextdir) ||
+				    !ReadOK(tif, &dircount64, 8)) {
+					TIFFErrorExt(tif->tif_clientdata, module,
+					     "Error fetching directory count");
+					return (0);
+				}
+				if (tif->tif_flags & TIFF_SWAB)
+					TIFFSwabLong8(&dircount64);
+				if (dircount64>0xFFFF)
+				{
+					TIFFErrorExt(tif->tif_clientdata, module,
+					     "Sanity check on tag count failed, likely corrupt TIFF");
+					return (0);
+				}
+				dircount=(uint16)dircount64;
+				(void) TIFFSeekFile(tif,
+				    nextdir+8+dircount*20, SEEK_SET);
+				if (!ReadOK(tif, &nextnextdir, 8)) {
+					TIFFErrorExt(tif->tif_clientdata, module,
+					     "Error fetching directory link");
+					return (0);
+				}
+				if (tif->tif_flags & TIFF_SWAB)
+					TIFFSwabLong8(&nextnextdir);
+				if (nextnextdir==tif->tif_diroff)
+				{
+					uint64 m;
+					m=0;
+					(void) TIFFSeekFile(tif,
+					    nextdir+8+dircount*20, SEEK_SET);
+					if (!WriteOK(tif, &m, 8)) {
+						TIFFErrorExt(tif->tif_clientdata, module,
+						     "Error writing directory link");
+						return (0);
+					}
+					tif->tif_diroff=0;
+					break;
+				}
+				nextdir=nextnextdir;
+			}
+		}
+	}
+
+	/*
+	 * Now use TIFFWriteDirectory() normally.
+	 */
+
+	return TIFFWriteDirectory( tif );
+}
+
+static int
+TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff)
+{
+	static const char module[] = "TIFFWriteDirectorySec";
+	uint32 ndir;
+	TIFFDirEntry* dir;
+	uint32 dirsize;
+	void* dirmem;
+	uint32 m;
+	if (tif->tif_mode == O_RDONLY)
+		return (1);
+
+        _TIFFFillStriles( tif );
+        
+	/*
+	 * Clear write state so that subsequent images with
+	 * different characteristics get the right buffers
+	 * setup for them.
+	 */
+	if (imagedone)
+	{
+		if (tif->tif_flags & TIFF_POSTENCODE)
+		{
+			tif->tif_flags &= ~TIFF_POSTENCODE;
+			if (!(*tif->tif_postencode)(tif))
+			{
+				TIFFErrorExt(tif->tif_clientdata,module,
+				    "Error post-encoding before directory write");
+				return (0);
+			}
+		}
+		(*tif->tif_close)(tif);       /* shutdown encoder */
+		/*
+		 * Flush any data that might have been written
+		 * by the compression close+cleanup routines.  But
+                 * be careful not to write stuff if we didn't add data
+                 * in the previous steps as the "rawcc" data may well be
+                 * a previously read tile/strip in mixed read/write mode.
+		 */
+		if (tif->tif_rawcc > 0 
+		    && (tif->tif_flags & TIFF_BEENWRITING) != 0 )
+		{
+		    if( !TIFFFlushData1(tif) )
+                    {
+			TIFFErrorExt(tif->tif_clientdata, module,
+			    "Error flushing data before directory write");
+			return (0);
+                    }
+		}
+		if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
+		{
+			_TIFFfree(tif->tif_rawdata);
+			tif->tif_rawdata = NULL;
+			tif->tif_rawcc = 0;
+			tif->tif_rawdatasize = 0;
+                        tif->tif_rawdataoff = 0;
+                        tif->tif_rawdataloaded = 0;
+		}
+		tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP);
+	}
+	dir=NULL;
+	dirmem=NULL;
+	dirsize=0;
+	while (1)
+	{
+		ndir=0;
+		if (isimage)
+		{
+			if (TIFFFieldSet(tif,FIELD_IMAGEDIMENSIONS))
+			{
+				if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_IMAGEWIDTH,tif->tif_dir.td_imagewidth))
+					goto bad;
+				if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_IMAGELENGTH,tif->tif_dir.td_imagelength))
+					goto bad;
+			}
+			if (TIFFFieldSet(tif,FIELD_TILEDIMENSIONS))
+			{
+				if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_TILEWIDTH,tif->tif_dir.td_tilewidth))
+					goto bad;
+				if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_TILELENGTH,tif->tif_dir.td_tilelength))
+					goto bad;
+			}
+			if (TIFFFieldSet(tif,FIELD_RESOLUTION))
+			{
+				if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_XRESOLUTION,tif->tif_dir.td_xresolution))
+					goto bad;
+				if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_YRESOLUTION,tif->tif_dir.td_yresolution))
+					goto bad;
+			}
+			if (TIFFFieldSet(tif,FIELD_POSITION))
+			{
+				if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_XPOSITION,tif->tif_dir.td_xposition))
+					goto bad;
+				if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_YPOSITION,tif->tif_dir.td_yposition))
+					goto bad;
+			}
+			if (TIFFFieldSet(tif,FIELD_SUBFILETYPE))
+			{
+				if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,TIFFTAG_SUBFILETYPE,tif->tif_dir.td_subfiletype))
+					goto bad;
+			}
+			if (TIFFFieldSet(tif,FIELD_BITSPERSAMPLE))
+			{
+				if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_BITSPERSAMPLE,tif->tif_dir.td_bitspersample))
+					goto bad;
+			}
+			if (TIFFFieldSet(tif,FIELD_COMPRESSION))
+			{
+				if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_COMPRESSION,tif->tif_dir.td_compression))
+					goto bad;
+			}
+			if (TIFFFieldSet(tif,FIELD_PHOTOMETRIC))
+			{
+				if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_PHOTOMETRIC,tif->tif_dir.td_photometric))
+					goto bad;
+			}
+			if (TIFFFieldSet(tif,FIELD_THRESHHOLDING))
+			{
+				if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_THRESHHOLDING,tif->tif_dir.td_threshholding))
+					goto bad;
+			}
+			if (TIFFFieldSet(tif,FIELD_FILLORDER))
+			{
+				if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_FILLORDER,tif->tif_dir.td_fillorder))
+					goto bad;
+			}
+			if (TIFFFieldSet(tif,FIELD_ORIENTATION))
+			{
+				if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_ORIENTATION,tif->tif_dir.td_orientation))
+					goto bad;
+			}
+			if (TIFFFieldSet(tif,FIELD_SAMPLESPERPIXEL))
+			{
+				if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_SAMPLESPERPIXEL,tif->tif_dir.td_samplesperpixel))
+					goto bad;
+			}
+			if (TIFFFieldSet(tif,FIELD_ROWSPERSTRIP))
+			{
+				if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_ROWSPERSTRIP,tif->tif_dir.td_rowsperstrip))
+					goto bad;
+			}
+			if (TIFFFieldSet(tif,FIELD_MINSAMPLEVALUE))
+			{
+				if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_MINSAMPLEVALUE,tif->tif_dir.td_minsamplevalue))
+					goto bad;
+			}
+			if (TIFFFieldSet(tif,FIELD_MAXSAMPLEVALUE))
+			{
+				if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_MAXSAMPLEVALUE,tif->tif_dir.td_maxsamplevalue))
+					goto bad;
+			}
+			if (TIFFFieldSet(tif,FIELD_PLANARCONFIG))
+			{
+				if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_PLANARCONFIG,tif->tif_dir.td_planarconfig))
+					goto bad;
+			}
+			if (TIFFFieldSet(tif,FIELD_RESOLUTIONUNIT))
+			{
+				if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_RESOLUTIONUNIT,tif->tif_dir.td_resolutionunit))
+					goto bad;
+			}
+			if (TIFFFieldSet(tif,FIELD_PAGENUMBER))
+			{
+				if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_PAGENUMBER,2,&tif->tif_dir.td_pagenumber[0]))
+					goto bad;
+			}
+			if (TIFFFieldSet(tif,FIELD_STRIPBYTECOUNTS))
+			{
+				if (!isTiled(tif))
+				{
+					if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_STRIPBYTECOUNTS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripbytecount))
+						goto bad;
+				}
+				else
+				{
+					if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_TILEBYTECOUNTS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripbytecount))
+						goto bad;
+				}
+			}
+			if (TIFFFieldSet(tif,FIELD_STRIPOFFSETS))
+			{
+				if (!isTiled(tif))
+				{
+					if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_STRIPOFFSETS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripoffset))
+						goto bad;
+				}
+				else
+				{
+					if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_TILEOFFSETS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripoffset))
+						goto bad;
+				}
+			}
+			if (TIFFFieldSet(tif,FIELD_COLORMAP))
+			{
+				if (!TIFFWriteDirectoryTagColormap(tif,&ndir,dir))
+					goto bad;
+			}
+			if (TIFFFieldSet(tif,FIELD_EXTRASAMPLES))
+			{
+				if (tif->tif_dir.td_extrasamples)
+				{
+					uint16 na;
+					uint16* nb;
+					TIFFGetFieldDefaulted(tif,TIFFTAG_EXTRASAMPLES,&na,&nb);
+					if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_EXTRASAMPLES,na,nb))
+						goto bad;
+				}
+			}
+			if (TIFFFieldSet(tif,FIELD_SAMPLEFORMAT))
+			{
+				if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_SAMPLEFORMAT,tif->tif_dir.td_sampleformat))
+					goto bad;
+			}
+			if (TIFFFieldSet(tif,FIELD_SMINSAMPLEVALUE))
+			{
+				if (!TIFFWriteDirectoryTagSampleformatArray(tif,&ndir,dir,TIFFTAG_SMINSAMPLEVALUE,tif->tif_dir.td_samplesperpixel,tif->tif_dir.td_sminsamplevalue))
+					goto bad;
+			}
+			if (TIFFFieldSet(tif,FIELD_SMAXSAMPLEVALUE))
+			{
+				if (!TIFFWriteDirectoryTagSampleformatArray(tif,&ndir,dir,TIFFTAG_SMAXSAMPLEVALUE,tif->tif_dir.td_samplesperpixel,tif->tif_dir.td_smaxsamplevalue))
+					goto bad;
+			}
+			if (TIFFFieldSet(tif,FIELD_IMAGEDEPTH))
+			{
+				if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,TIFFTAG_IMAGEDEPTH,tif->tif_dir.td_imagedepth))
+					goto bad;
+			}
+			if (TIFFFieldSet(tif,FIELD_TILEDEPTH))
+			{
+				if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,TIFFTAG_TILEDEPTH,tif->tif_dir.td_tiledepth))
+					goto bad;
+			}
+			if (TIFFFieldSet(tif,FIELD_HALFTONEHINTS))
+			{
+				if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_HALFTONEHINTS,2,&tif->tif_dir.td_halftonehints[0]))
+					goto bad;
+			}
+			if (TIFFFieldSet(tif,FIELD_YCBCRSUBSAMPLING))
+			{
+				if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_YCBCRSUBSAMPLING,2,&tif->tif_dir.td_ycbcrsubsampling[0]))
+					goto bad;
+			}
+			if (TIFFFieldSet(tif,FIELD_YCBCRPOSITIONING))
+			{
+				if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_YCBCRPOSITIONING,tif->tif_dir.td_ycbcrpositioning))
+					goto bad;
+			}
+			if (TIFFFieldSet(tif,FIELD_REFBLACKWHITE))
+			{
+				if (!TIFFWriteDirectoryTagRationalArray(tif,&ndir,dir,TIFFTAG_REFERENCEBLACKWHITE,6,tif->tif_dir.td_refblackwhite))
+					goto bad;
+			}
+			if (TIFFFieldSet(tif,FIELD_TRANSFERFUNCTION))
+			{
+				if (!TIFFWriteDirectoryTagTransferfunction(tif,&ndir,dir))
+					goto bad;
+			}
+			if (TIFFFieldSet(tif,FIELD_INKNAMES))
+			{
+				if (!TIFFWriteDirectoryTagAscii(tif,&ndir,dir,TIFFTAG_INKNAMES,tif->tif_dir.td_inknameslen,tif->tif_dir.td_inknames))
+					goto bad;
+			}
+			if (TIFFFieldSet(tif,FIELD_SUBIFD))
+			{
+				if (!TIFFWriteDirectoryTagSubifd(tif,&ndir,dir))
+					goto bad;
+			}
+			{
+				uint32 n;
+				for (n=0; n<tif->tif_nfields; n++) {
+					const TIFFField* o;
+					o = tif->tif_fields[n];
+					if ((o->field_bit>=FIELD_CODEC)&&(TIFFFieldSet(tif,o->field_bit)))
+					{
+						switch (o->get_field_type)
+						{
+							case TIFF_SETGET_ASCII:
+								{
+									uint32 pa;
+									char* pb;
+									assert(o->field_type==TIFF_ASCII);
+									assert(o->field_readcount==TIFF_VARIABLE);
+									assert(o->field_passcount==0);
+									TIFFGetField(tif,o->field_tag,&pb);
+									pa=(uint32)(strlen(pb));
+									if (!TIFFWriteDirectoryTagAscii(tif,&ndir,dir,o->field_tag,pa,pb))
+										goto bad;
+								}
+								break;
+							case TIFF_SETGET_UINT16:
+								{
+									uint16 p;
+									assert(o->field_type==TIFF_SHORT);
+									assert(o->field_readcount==1);
+									assert(o->field_passcount==0);
+									TIFFGetField(tif,o->field_tag,&p);
+									if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,o->field_tag,p))
+										goto bad;
+								}
+								break;
+							case TIFF_SETGET_UINT32:
+								{
+									uint32 p;
+									assert(o->field_type==TIFF_LONG);
+									assert(o->field_readcount==1);
+									assert(o->field_passcount==0);
+									TIFFGetField(tif,o->field_tag,&p);
+									if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,o->field_tag,p))
+										goto bad;
+								}
+								break;
+							case TIFF_SETGET_C32_UINT8:
+								{
+									uint32 pa;
+									void* pb;
+									assert(o->field_type==TIFF_UNDEFINED);
+									assert(o->field_readcount==TIFF_VARIABLE2);
+									assert(o->field_passcount==1);
+									TIFFGetField(tif,o->field_tag,&pa,&pb);
+									if (!TIFFWriteDirectoryTagUndefinedArray(tif,&ndir,dir,o->field_tag,pa,pb))
+										goto bad;
+								}
+								break;
+							default:
+								assert(0);   /* we should never get here */
+								break;
+						}
+					}
+				}
+			}
+		}
+		for (m=0; m<(uint32)(tif->tif_dir.td_customValueCount); m++)
+		{
+			switch (tif->tif_dir.td_customValues[m].info->field_type)
+			{
+				case TIFF_ASCII:
+					if (!TIFFWriteDirectoryTagAscii(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
+						goto bad;
+					break;
+				case TIFF_UNDEFINED:
+					if (!TIFFWriteDirectoryTagUndefinedArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
+						goto bad;
+					break;
+				case TIFF_BYTE:
+					if (!TIFFWriteDirectoryTagByteArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
+						goto bad;
+					break;
+				case TIFF_SBYTE:
+					if (!TIFFWriteDirectoryTagSbyteArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
+						goto bad;
+					break;
+				case TIFF_SHORT:
+					if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
+						goto bad;
+					break;
+				case TIFF_SSHORT:
+					if (!TIFFWriteDirectoryTagSshortArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
+						goto bad;
+					break;
+				case TIFF_LONG:
+					if (!TIFFWriteDirectoryTagLongArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
+						goto bad;
+					break;
+				case TIFF_SLONG:
+					if (!TIFFWriteDirectoryTagSlongArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
+						goto bad;
+					break;
+				case TIFF_LONG8:
+					if (!TIFFWriteDirectoryTagLong8Array(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
+						goto bad;
+					break;
+				case TIFF_SLONG8:
+					if (!TIFFWriteDirectoryTagSlong8Array(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
+						goto bad;
+					break;
+				case TIFF_RATIONAL:
+					if (!TIFFWriteDirectoryTagRationalArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
+						goto bad;
+					break;
+				case TIFF_SRATIONAL:
+					if (!TIFFWriteDirectoryTagSrationalArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
+						goto bad;
+					break;
+				case TIFF_FLOAT:
+					if (!TIFFWriteDirectoryTagFloatArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
+						goto bad;
+					break;
+				case TIFF_DOUBLE:
+					if (!TIFFWriteDirectoryTagDoubleArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
+						goto bad;
+					break;
+				case TIFF_IFD:
+					if (!TIFFWriteDirectoryTagIfdArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
+						goto bad;
+					break;
+				case TIFF_IFD8:
+					if (!TIFFWriteDirectoryTagIfdIfd8Array(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
+						goto bad;
+					break;
+				default:
+					assert(0);   /* we should never get here */
+					break;
+			}
+		}
+		if (dir!=NULL)
+			break;
+		dir=_TIFFmalloc(ndir*sizeof(TIFFDirEntry));
+		if (dir==NULL)
+		{
+			TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+			goto bad;
+		}
+		if (isimage)
+		{
+			if ((tif->tif_diroff==0)&&(!TIFFLinkDirectory(tif)))
+				goto bad;
+		}
+		else
+			tif->tif_diroff=(TIFFSeekFile(tif,0,SEEK_END)+1)&(~1);
+		if (pdiroff!=NULL)
+			*pdiroff=tif->tif_diroff;
+		if (!(tif->tif_flags&TIFF_BIGTIFF))
+			dirsize=2+ndir*12+4;
+		else
+			dirsize=8+ndir*20+8;
+		tif->tif_dataoff=tif->tif_diroff+dirsize;
+		if (!(tif->tif_flags&TIFF_BIGTIFF))
+			tif->tif_dataoff=(uint32)tif->tif_dataoff;
+		if ((tif->tif_dataoff<tif->tif_diroff)||(tif->tif_dataoff<(uint64)dirsize))
+		{
+			TIFFErrorExt(tif->tif_clientdata,module,"Maximum TIFF file size exceeded");
+			goto bad;
+		}
+		if (tif->tif_dataoff&1)
+			tif->tif_dataoff++;
+		if (isimage)
+			tif->tif_curdir++;
+	}
+	if (isimage)
+	{
+		if (TIFFFieldSet(tif,FIELD_SUBIFD)&&(tif->tif_subifdoff==0))
+		{
+			uint32 na;
+			TIFFDirEntry* nb;
+			for (na=0, nb=dir; ; na++, nb++)
+			{
+				assert(na<ndir);
+				if (nb->tdir_tag==TIFFTAG_SUBIFD)
+					break;
+			}
+			if (!(tif->tif_flags&TIFF_BIGTIFF))
+				tif->tif_subifdoff=tif->tif_diroff+2+na*12+8;
+			else
+				tif->tif_subifdoff=tif->tif_diroff+8+na*20+12;
+		}
+	}
+	dirmem=_TIFFmalloc(dirsize);
+	if (dirmem==NULL)
+	{
+		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+		goto bad;
+	}
+	if (!(tif->tif_flags&TIFF_BIGTIFF))
+	{
+		uint8* n;
+		uint32 nTmp;
+		TIFFDirEntry* o;
+		n=dirmem;
+		*(uint16*)n=ndir;
+		if (tif->tif_flags&TIFF_SWAB)
+			TIFFSwabShort((uint16*)n);
+		n+=2;
+		o=dir;
+		for (m=0; m<ndir; m++)
+		{
+			*(uint16*)n=o->tdir_tag;
+			if (tif->tif_flags&TIFF_SWAB)
+				TIFFSwabShort((uint16*)n);
+			n+=2;
+			*(uint16*)n=o->tdir_type;
+			if (tif->tif_flags&TIFF_SWAB)
+				TIFFSwabShort((uint16*)n);
+			n+=2;
+			nTmp = (uint32)o->tdir_count;
+			_TIFFmemcpy(n,&nTmp,4);
+			if (tif->tif_flags&TIFF_SWAB)
+				TIFFSwabLong((uint32*)n);
+			n+=4;
+			/* This is correct. The data has been */
+			/* swabbed previously in TIFFWriteDirectoryTagData */
+			_TIFFmemcpy(n,&o->tdir_offset,4);
+			n+=4;
+			o++;
+		}
+		nTmp = (uint32)tif->tif_nextdiroff;
+		if (tif->tif_flags&TIFF_SWAB)
+			TIFFSwabLong(&nTmp);
+		_TIFFmemcpy(n,&nTmp,4);
+	}
+	else
+	{
+		uint8* n;
+		TIFFDirEntry* o;
+		n=dirmem;
+		*(uint64*)n=ndir;
+		if (tif->tif_flags&TIFF_SWAB)
+			TIFFSwabLong8((uint64*)n);
+		n+=8;
+		o=dir;
+		for (m=0; m<ndir; m++)
+		{
+			*(uint16*)n=o->tdir_tag;
+			if (tif->tif_flags&TIFF_SWAB)
+				TIFFSwabShort((uint16*)n);
+			n+=2;
+			*(uint16*)n=o->tdir_type;
+			if (tif->tif_flags&TIFF_SWAB)
+				TIFFSwabShort((uint16*)n);
+			n+=2;
+			_TIFFmemcpy(n,&o->tdir_count,8);
+			if (tif->tif_flags&TIFF_SWAB)
+				TIFFSwabLong8((uint64*)n);
+			n+=8;
+			_TIFFmemcpy(n,&o->tdir_offset,8);
+			n+=8;
+			o++;
+		}
+		_TIFFmemcpy(n,&tif->tif_nextdiroff,8);
+		if (tif->tif_flags&TIFF_SWAB)
+			TIFFSwabLong8((uint64*)n);
+	}
+	_TIFFfree(dir);
+	dir=NULL;
+	if (!SeekOK(tif,tif->tif_diroff))
+	{
+		TIFFErrorExt(tif->tif_clientdata,module,"IO error writing directory");
+		goto bad;
+	}
+	if (!WriteOK(tif,dirmem,(tmsize_t)dirsize))
+	{
+		TIFFErrorExt(tif->tif_clientdata,module,"IO error writing directory");
+		goto bad;
+	}
+	_TIFFfree(dirmem);
+	if (imagedone)
+	{
+		TIFFFreeDirectory(tif);
+		tif->tif_flags &= ~TIFF_DIRTYDIRECT;
+		tif->tif_flags &= ~TIFF_DIRTYSTRIP;
+		(*tif->tif_cleanup)(tif);
+		/*
+		* Reset directory-related state for subsequent
+		* directories.
+		*/
+		TIFFCreateDirectory(tif);
+	}
+	return(1);
+bad:
+	if (dir!=NULL)
+		_TIFFfree(dir);
+	if (dirmem!=NULL)
+		_TIFFfree(dirmem);
+	return(0);
+}
+
+static int
+TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value)
+{
+	static const char module[] = "TIFFWriteDirectoryTagSampleformatArray";
+	void* conv;
+	uint32 i;
+	int ok;
+	conv = _TIFFmalloc(count*sizeof(double));
+	if (conv == NULL)
+	{
+		TIFFErrorExt(tif->tif_clientdata, module, "Out of memory");
+		return (0);
+	}
+
+	switch (tif->tif_dir.td_sampleformat)
+	{
+		case SAMPLEFORMAT_IEEEFP:
+			if (tif->tif_dir.td_bitspersample<=32)
+			{
+				for (i = 0; i < count; ++i)
+					((float*)conv)[i] = (float)value[i];
+				ok = TIFFWriteDirectoryTagFloatArray(tif,ndir,dir,tag,count,(float*)conv);
+			}
+			else
+			{
+				ok = TIFFWriteDirectoryTagDoubleArray(tif,ndir,dir,tag,count,value);
+			}
+			break;
+		case SAMPLEFORMAT_INT:
+			if (tif->tif_dir.td_bitspersample<=8)
+			{
+				for (i = 0; i < count; ++i)
+					((int8*)conv)[i] = (int8)value[i];
+				ok = TIFFWriteDirectoryTagSbyteArray(tif,ndir,dir,tag,count,(int8*)conv);
+			}
+			else if (tif->tif_dir.td_bitspersample<=16)
+			{
+				for (i = 0; i < count; ++i)
+					((int16*)conv)[i] = (int16)value[i];
+				ok = TIFFWriteDirectoryTagSshortArray(tif,ndir,dir,tag,count,(int16*)conv);
+			}
+			else
+			{
+				for (i = 0; i < count; ++i)
+					((int32*)conv)[i] = (int32)value[i];
+				ok = TIFFWriteDirectoryTagSlongArray(tif,ndir,dir,tag,count,(int32*)conv);
+			}
+			break;
+		case SAMPLEFORMAT_UINT:
+			if (tif->tif_dir.td_bitspersample<=8)
+			{
+				for (i = 0; i < count; ++i)
+					((uint8*)conv)[i] = (uint8)value[i];
+				ok = TIFFWriteDirectoryTagByteArray(tif,ndir,dir,tag,count,(uint8*)conv);
+			}
+			else if (tif->tif_dir.td_bitspersample<=16)
+			{
+				for (i = 0; i < count; ++i)
+					((uint16*)conv)[i] = (uint16)value[i];
+				ok = TIFFWriteDirectoryTagShortArray(tif,ndir,dir,tag,count,(uint16*)conv);
+			}
+			else
+			{
+				for (i = 0; i < count; ++i)
+					((uint32*)conv)[i] = (uint32)value[i];
+				ok = TIFFWriteDirectoryTagLongArray(tif,ndir,dir,tag,count,(uint32*)conv);
+			}
+			break;
+		default:
+			ok = 0;
+	}
+
+	_TIFFfree(conv);
+	return (ok);
+}
+
+#if 0
+static int
+TIFFWriteDirectoryTagSampleformatPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
+{
+	switch (tif->tif_dir.td_sampleformat)
+	{
+		case SAMPLEFORMAT_IEEEFP:
+			if (tif->tif_dir.td_bitspersample<=32)
+				return(TIFFWriteDirectoryTagFloatPerSample(tif,ndir,dir,tag,(float)value));
+			else
+				return(TIFFWriteDirectoryTagDoublePerSample(tif,ndir,dir,tag,value));
+		case SAMPLEFORMAT_INT:
+			if (tif->tif_dir.td_bitspersample<=8)
+				return(TIFFWriteDirectoryTagSbytePerSample(tif,ndir,dir,tag,(int8)value));
+			else if (tif->tif_dir.td_bitspersample<=16)
+				return(TIFFWriteDirectoryTagSshortPerSample(tif,ndir,dir,tag,(int16)value));
+			else
+				return(TIFFWriteDirectoryTagSlongPerSample(tif,ndir,dir,tag,(int32)value));
+		case SAMPLEFORMAT_UINT:
+			if (tif->tif_dir.td_bitspersample<=8)
+				return(TIFFWriteDirectoryTagBytePerSample(tif,ndir,dir,tag,(uint8)value));
+			else if (tif->tif_dir.td_bitspersample<=16)
+				return(TIFFWriteDirectoryTagShortPerSample(tif,ndir,dir,tag,(uint16)value));
+			else
+				return(TIFFWriteDirectoryTagLongPerSample(tif,ndir,dir,tag,(uint32)value));
+		default:
+			return(1);
+	}
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagAscii(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, char* value)
+{
+	if (dir==NULL)
+	{
+		(*ndir)++;
+		return(1);
+	}
+	return(TIFFWriteDirectoryTagCheckedAscii(tif,ndir,dir,tag,count,value));
+}
+
+static int
+TIFFWriteDirectoryTagUndefinedArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value)
+{
+	if (dir==NULL)
+	{
+		(*ndir)++;
+		return(1);
+	}
+	return(TIFFWriteDirectoryTagCheckedUndefinedArray(tif,ndir,dir,tag,count,value));
+}
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagByte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value)
+{
+	if (dir==NULL)
+	{
+		(*ndir)++;
+		return(1);
+	}
+	return(TIFFWriteDirectoryTagCheckedByte(tif,ndir,dir,tag,value));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagByteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value)
+{
+	if (dir==NULL)
+	{
+		(*ndir)++;
+		return(1);
+	}
+	return(TIFFWriteDirectoryTagCheckedByteArray(tif,ndir,dir,tag,count,value));
+}
+
+#if 0
+static int
+TIFFWriteDirectoryTagBytePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value)
+{
+	static const char module[] = "TIFFWriteDirectoryTagBytePerSample";
+	uint8* m;
+	uint8* na;
+	uint16 nb;
+	int o;
+	if (dir==NULL)
+	{
+		(*ndir)++;
+		return(1);
+	}
+	m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(uint8));
+	if (m==NULL)
+	{
+		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+		return(0);
+	}
+	for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
+		*na=value;
+	o=TIFFWriteDirectoryTagCheckedByteArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
+	_TIFFfree(m);
+	return(o);
+}
+#endif
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagSbyte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value)
+{
+	if (dir==NULL)
+	{
+		(*ndir)++;
+		return(1);
+	}
+	return(TIFFWriteDirectoryTagCheckedSbyte(tif,ndir,dir,tag,value));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagSbyteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int8* value)
+{
+	if (dir==NULL)
+	{
+		(*ndir)++;
+		return(1);
+	}
+	return(TIFFWriteDirectoryTagCheckedSbyteArray(tif,ndir,dir,tag,count,value));
+}
+
+#if 0
+static int
+TIFFWriteDirectoryTagSbytePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value)
+{
+	static const char module[] = "TIFFWriteDirectoryTagSbytePerSample";
+	int8* m;
+	int8* na;
+	uint16 nb;
+	int o;
+	if (dir==NULL)
+	{
+		(*ndir)++;
+		return(1);
+	}
+	m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(int8));
+	if (m==NULL)
+	{
+		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+		return(0);
+	}
+	for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
+		*na=value;
+	o=TIFFWriteDirectoryTagCheckedSbyteArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
+	_TIFFfree(m);
+	return(o);
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagShort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value)
+{
+	if (dir==NULL)
+	{
+		(*ndir)++;
+		return(1);
+	}
+	return(TIFFWriteDirectoryTagCheckedShort(tif,ndir,dir,tag,value));
+}
+
+static int
+TIFFWriteDirectoryTagShortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint16* value)
+{
+	if (dir==NULL)
+	{
+		(*ndir)++;
+		return(1);
+	}
+	return(TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,tag,count,value));
+}
+
+static int
+TIFFWriteDirectoryTagShortPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value)
+{
+	static const char module[] = "TIFFWriteDirectoryTagShortPerSample";
+	uint16* m;
+	uint16* na;
+	uint16 nb;
+	int o;
+	if (dir==NULL)
+	{
+		(*ndir)++;
+		return(1);
+	}
+	m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(uint16));
+	if (m==NULL)
+	{
+		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+		return(0);
+	}
+	for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
+		*na=value;
+	o=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
+	_TIFFfree(m);
+	return(o);
+}
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagSshort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value)
+{
+	if (dir==NULL)
+	{
+		(*ndir)++;
+		return(1);
+	}
+	return(TIFFWriteDirectoryTagCheckedSshort(tif,ndir,dir,tag,value));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagSshortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int16* value)
+{
+	if (dir==NULL)
+	{
+		(*ndir)++;
+		return(1);
+	}
+	return(TIFFWriteDirectoryTagCheckedSshortArray(tif,ndir,dir,tag,count,value));
+}
+
+#if 0
+static int
+TIFFWriteDirectoryTagSshortPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value)
+{
+	static const char module[] = "TIFFWriteDirectoryTagSshortPerSample";
+	int16* m;
+	int16* na;
+	uint16 nb;
+	int o;
+	if (dir==NULL)
+	{
+		(*ndir)++;
+		return(1);
+	}
+	m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(int16));
+	if (m==NULL)
+	{
+		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+		return(0);
+	}
+	for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
+		*na=value;
+	o=TIFFWriteDirectoryTagCheckedSshortArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
+	_TIFFfree(m);
+	return(o);
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value)
+{
+	if (dir==NULL)
+	{
+		(*ndir)++;
+		return(1);
+	}
+	return(TIFFWriteDirectoryTagCheckedLong(tif,ndir,dir,tag,value));
+}
+
+static int
+TIFFWriteDirectoryTagLongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value)
+{
+	if (dir==NULL)
+	{
+		(*ndir)++;
+		return(1);
+	}
+	return(TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,count,value));
+}
+
+#if 0
+static int
+TIFFWriteDirectoryTagLongPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value)
+{
+	static const char module[] = "TIFFWriteDirectoryTagLongPerSample";
+	uint32* m;
+	uint32* na;
+	uint16 nb;
+	int o;
+	if (dir==NULL)
+	{
+		(*ndir)++;
+		return(1);
+	}
+	m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(uint32));
+	if (m==NULL)
+	{
+		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+		return(0);
+	}
+	for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
+		*na=value;
+	o=TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
+	_TIFFfree(m);
+	return(o);
+}
+#endif
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagSlong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value)
+{
+	if (dir==NULL)
+	{
+		(*ndir)++;
+		return(1);
+	}
+	return(TIFFWriteDirectoryTagCheckedSlong(tif,ndir,dir,tag,value));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagSlongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int32* value)
+{
+	if (dir==NULL)
+	{
+		(*ndir)++;
+		return(1);
+	}
+	return(TIFFWriteDirectoryTagCheckedSlongArray(tif,ndir,dir,tag,count,value));
+}
+
+#if 0
+static int
+TIFFWriteDirectoryTagSlongPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value)
+{
+	static const char module[] = "TIFFWriteDirectoryTagSlongPerSample";
+	int32* m;
+	int32* na;
+	uint16 nb;
+	int o;
+	if (dir==NULL)
+	{
+		(*ndir)++;
+		return(1);
+	}
+	m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(int32));
+	if (m==NULL)
+	{
+		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+		return(0);
+	}
+	for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
+		*na=value;
+	o=TIFFWriteDirectoryTagCheckedSlongArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
+	_TIFFfree(m);
+	return(o);
+}
+#endif
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagLong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint64 value)
+{
+	if (dir==NULL)
+	{
+		(*ndir)++;
+		return(1);
+	}
+	return(TIFFWriteDirectoryTagCheckedLong8(tif,ndir,dir,tag,value));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
+{
+	if (dir==NULL)
+	{
+		(*ndir)++;
+		return(1);
+	}
+	return(TIFFWriteDirectoryTagCheckedLong8Array(tif,ndir,dir,tag,count,value));
+}
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagSlong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int64 value)
+{
+	if (dir==NULL)
+	{
+		(*ndir)++;
+		return(1);
+	}
+	return(TIFFWriteDirectoryTagCheckedSlong8(tif,ndir,dir,tag,value));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int64* value)
+{
+	if (dir==NULL)
+	{
+		(*ndir)++;
+		return(1);
+	}
+	return(TIFFWriteDirectoryTagCheckedSlong8Array(tif,ndir,dir,tag,count,value));
+}
+
+static int
+TIFFWriteDirectoryTagRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
+{
+	if (dir==NULL)
+	{
+		(*ndir)++;
+		return(1);
+	}
+	return(TIFFWriteDirectoryTagCheckedRational(tif,ndir,dir,tag,value));
+}
+
+static int
+TIFFWriteDirectoryTagRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
+{
+	if (dir==NULL)
+	{
+		(*ndir)++;
+		return(1);
+	}
+	return(TIFFWriteDirectoryTagCheckedRationalArray(tif,ndir,dir,tag,count,value));
+}
+
+static int
+TIFFWriteDirectoryTagSrationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
+{
+	if (dir==NULL)
+	{
+		(*ndir)++;
+		return(1);
+	}
+	return(TIFFWriteDirectoryTagCheckedSrationalArray(tif,ndir,dir,tag,count,value));
+}
+
+#ifdef notdef
+static int TIFFWriteDirectoryTagFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value)
+{
+	if (dir==NULL)
+	{
+		(*ndir)++;
+		return(1);
+	}
+	return(TIFFWriteDirectoryTagCheckedFloat(tif,ndir,dir,tag,value));
+}
+#endif
+
+static int TIFFWriteDirectoryTagFloatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
+{
+	if (dir==NULL)
+	{
+		(*ndir)++;
+		return(1);
+	}
+	return(TIFFWriteDirectoryTagCheckedFloatArray(tif,ndir,dir,tag,count,value));
+}
+
+#if 0
+static int TIFFWriteDirectoryTagFloatPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value)
+{
+	static const char module[] = "TIFFWriteDirectoryTagFloatPerSample";
+	float* m;
+	float* na;
+	uint16 nb;
+	int o;
+	if (dir==NULL)
+	{
+		(*ndir)++;
+		return(1);
+	}
+	m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(float));
+	if (m==NULL)
+	{
+		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+		return(0);
+	}
+	for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
+		*na=value;
+	o=TIFFWriteDirectoryTagCheckedFloatArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
+	_TIFFfree(m);
+	return(o);
+}
+#endif
+
+#ifdef notdef
+static int TIFFWriteDirectoryTagDouble(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
+{
+	if (dir==NULL)
+	{
+		(*ndir)++;
+		return(1);
+	}
+	return(TIFFWriteDirectoryTagCheckedDouble(tif,ndir,dir,tag,value));
+}
+#endif
+
+static int TIFFWriteDirectoryTagDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value)
+{
+	if (dir==NULL)
+	{
+		(*ndir)++;
+		return(1);
+	}
+	return(TIFFWriteDirectoryTagCheckedDoubleArray(tif,ndir,dir,tag,count,value));
+}
+
+#if 0
+static int TIFFWriteDirectoryTagDoublePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
+{
+	static const char module[] = "TIFFWriteDirectoryTagDoublePerSample";
+	double* m;
+	double* na;
+	uint16 nb;
+	int o;
+	if (dir==NULL)
+	{
+		(*ndir)++;
+		return(1);
+	}
+	m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(double));
+	if (m==NULL)
+	{
+		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+		return(0);
+	}
+	for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
+		*na=value;
+	o=TIFFWriteDirectoryTagCheckedDoubleArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
+	_TIFFfree(m);
+	return(o);
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagIfdArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value)
+{
+	if (dir==NULL)
+	{
+		(*ndir)++;
+		return(1);
+	}
+	return(TIFFWriteDirectoryTagCheckedIfdArray(tif,ndir,dir,tag,count,value));
+}
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
+{
+	if (dir==NULL)
+	{
+		(*ndir)++;
+		return(1);
+	}
+	return(TIFFWriteDirectoryTagCheckedIfd8Array(tif,ndir,dir,tag,count,value));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagShortLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value)
+{
+	if (dir==NULL)
+	{
+		(*ndir)++;
+		return(1);
+	}
+	if (value<=0xFFFF)
+		return(TIFFWriteDirectoryTagCheckedShort(tif,ndir,dir,tag,(uint16)value));
+	else
+		return(TIFFWriteDirectoryTagCheckedLong(tif,ndir,dir,tag,value));
+}
+
+/************************************************************************/
+/*                TIFFWriteDirectoryTagLongLong8Array()                 */
+/*                                                                      */
+/*      Write out LONG8 array as LONG8 for BigTIFF or LONG for          */
+/*      Classic TIFF with some checking.                                */
+/************************************************************************/
+
+static int
+TIFFWriteDirectoryTagLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
+{
+    static const char module[] = "TIFFWriteDirectoryTagLongLong8Array";
+    uint64* ma;
+    uint32 mb;
+    uint32* p;
+    uint32* q;
+    int o;
+
+    /* is this just a counting pass? */
+    if (dir==NULL)
+    {
+        (*ndir)++;
+        return(1);
+    }
+
+    /* We always write LONG8 for BigTIFF, no checking needed. */
+    if( tif->tif_flags&TIFF_BIGTIFF )
+        return TIFFWriteDirectoryTagCheckedLong8Array(tif,ndir,dir,
+                                                      tag,count,value);
+
+    /*
+    ** For classic tiff we want to verify everything is in range for LONG
+    ** and convert to long format.
+    */
+
+    p = _TIFFmalloc(count*sizeof(uint32));
+    if (p==NULL)
+    {
+        TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+        return(0);
+    }
+
+    for (q=p, ma=value, mb=0; mb<count; ma++, mb++, q++)
+    {
+        if (*ma>0xFFFFFFFF)
+        {
+            TIFFErrorExt(tif->tif_clientdata,module,
+                         "Attempt to write value larger than 0xFFFFFFFF in Classic TIFF file.");
+            _TIFFfree(p);
+            return(0);
+        }
+        *q= (uint32)(*ma);
+    }
+
+    o=TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,count,p);
+    _TIFFfree(p);
+
+    return(o);
+}
+
+/************************************************************************/
+/*                 TIFFWriteDirectoryTagIfdIfd8Array()                  */
+/*                                                                      */
+/*      Write either IFD8 or IFD array depending on file type.          */
+/************************************************************************/
+
+static int
+TIFFWriteDirectoryTagIfdIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
+{
+    static const char module[] = "TIFFWriteDirectoryTagIfdIfd8Array";
+    uint64* ma;
+    uint32 mb;
+    uint32* p;
+    uint32* q;
+    int o;
+
+    /* is this just a counting pass? */
+    if (dir==NULL)
+    {
+        (*ndir)++;
+        return(1);
+    }
+
+    /* We always write IFD8 for BigTIFF, no checking needed. */
+    if( tif->tif_flags&TIFF_BIGTIFF )
+        return TIFFWriteDirectoryTagCheckedIfd8Array(tif,ndir,dir,
+                                                     tag,count,value);
+
+    /*
+    ** For classic tiff we want to verify everything is in range for IFD
+    ** and convert to long format.
+    */
+
+    p = _TIFFmalloc(count*sizeof(uint32));
+    if (p==NULL)
+    {
+        TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+        return(0);
+    }
+
+    for (q=p, ma=value, mb=0; mb<count; ma++, mb++, q++)
+    {
+        if (*ma>0xFFFFFFFF)
+        {
+            TIFFErrorExt(tif->tif_clientdata,module,
+                         "Attempt to write value larger than 0xFFFFFFFF in Classic TIFF file.");
+            _TIFFfree(p);
+            return(0);
+        }
+        *q= (uint32)(*ma);
+    }
+
+    o=TIFFWriteDirectoryTagCheckedIfdArray(tif,ndir,dir,tag,count,p);
+    _TIFFfree(p);
+
+    return(o);
+}
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagShortLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
+{
+	static const char module[] = "TIFFWriteDirectoryTagShortLongLong8Array";
+	uint64* ma;
+	uint32 mb;
+	uint8 n;
+	int o;
+	if (dir==NULL)
+	{
+		(*ndir)++;
+		return(1);
+	}
+	n=0;
+	for (ma=value, mb=0; mb<count; ma++, mb++)
+	{
+		if ((n==0)&&(*ma>0xFFFF))
+			n=1;
+		if ((n==1)&&(*ma>0xFFFFFFFF))
+		{
+			n=2;
+			break;
+		}
+	}
+	if (n==0)
+	{
+		uint16* p;
+		uint16* q;
+		p=_TIFFmalloc(count*sizeof(uint16));
+		if (p==NULL)
+		{
+			TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+			return(0);
+		}
+		for (ma=value, mb=0, q=p; mb<count; ma++, mb++, q++)
+			*q=(uint16)(*ma);
+		o=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,tag,count,p);
+		_TIFFfree(p);
+	}
+	else if (n==1)
+	{
+		uint32* p;
+		uint32* q;
+		p=_TIFFmalloc(count*sizeof(uint32));
+		if (p==NULL)
+		{
+			TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+			return(0);
+		}
+		for (ma=value, mb=0, q=p; mb<count; ma++, mb++, q++)
+			*q=(uint32)(*ma);
+		o=TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,count,p);
+		_TIFFfree(p);
+	}
+	else
+	{
+		assert(n==2);
+		o=TIFFWriteDirectoryTagCheckedLong8Array(tif,ndir,dir,tag,count,value);
+	}
+	return(o);
+}
+#endif
+static int
+TIFFWriteDirectoryTagColormap(TIFF* tif, uint32* ndir, TIFFDirEntry* dir)
+{
+	static const char module[] = "TIFFWriteDirectoryTagColormap";
+	uint32 m;
+	uint16* n;
+	int o;
+	if (dir==NULL)
+	{
+		(*ndir)++;
+		return(1);
+	}
+	m=(1<<tif->tif_dir.td_bitspersample);
+	n=_TIFFmalloc(3*m*sizeof(uint16));
+	if (n==NULL)
+	{
+		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+		return(0);
+	}
+	_TIFFmemcpy(&n[0],tif->tif_dir.td_colormap[0],m*sizeof(uint16));
+	_TIFFmemcpy(&n[m],tif->tif_dir.td_colormap[1],m*sizeof(uint16));
+	_TIFFmemcpy(&n[2*m],tif->tif_dir.td_colormap[2],m*sizeof(uint16));
+	o=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,TIFFTAG_COLORMAP,3*m,n);
+	_TIFFfree(n);
+	return(o);
+}
+
+static int
+TIFFWriteDirectoryTagTransferfunction(TIFF* tif, uint32* ndir, TIFFDirEntry* dir)
+{
+	static const char module[] = "TIFFWriteDirectoryTagTransferfunction";
+	uint32 m;
+	uint16 n;
+	uint16* o;
+	int p;
+	if (dir==NULL)
+	{
+		(*ndir)++;
+		return(1);
+	}
+	m=(1<<tif->tif_dir.td_bitspersample);
+	n=tif->tif_dir.td_samplesperpixel-tif->tif_dir.td_extrasamples;
+	/*
+	 * Check if the table can be written as a single column,
+	 * or if it must be written as 3 columns.  Note that we
+	 * write a 3-column tag if there are 2 samples/pixel and
+	 * a single column of data won't suffice--hmm.
+	 */
+	if (n>3)
+		n=3;
+	if (n==3)
+	{
+		if (!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],tif->tif_dir.td_transferfunction[2],m*sizeof(uint16)))
+			n=2;
+	}
+	if (n==2)
+	{
+		if (!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],tif->tif_dir.td_transferfunction[1],m*sizeof(uint16)))
+			n=1;
+	}
+	if (n==0)
+		n=1;
+	o=_TIFFmalloc(n*m*sizeof(uint16));
+	if (o==NULL)
+	{
+		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+		return(0);
+	}
+	_TIFFmemcpy(&o[0],tif->tif_dir.td_transferfunction[0],m*sizeof(uint16));
+	if (n>1)
+		_TIFFmemcpy(&o[m],tif->tif_dir.td_transferfunction[1],m*sizeof(uint16));
+	if (n>2)
+		_TIFFmemcpy(&o[2*m],tif->tif_dir.td_transferfunction[2],m*sizeof(uint16));
+	p=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,TIFFTAG_TRANSFERFUNCTION,n*m,o);
+	_TIFFfree(o);
+	return(p);
+}
+
+static int
+TIFFWriteDirectoryTagSubifd(TIFF* tif, uint32* ndir, TIFFDirEntry* dir)
+{
+	static const char module[] = "TIFFWriteDirectoryTagSubifd";
+	uint64 m;
+	int n;
+	if (tif->tif_dir.td_nsubifd==0)
+		return(1);
+	if (dir==NULL)
+	{
+		(*ndir)++;
+		return(1);
+	}
+	m=tif->tif_dataoff;
+	if (!(tif->tif_flags&TIFF_BIGTIFF))
+	{
+		uint32* o;
+		uint64* pa;
+		uint32* pb;
+		uint16 p;
+		o=_TIFFmalloc(tif->tif_dir.td_nsubifd*sizeof(uint32));
+		if (o==NULL)
+		{
+			TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+			return(0);
+		}
+		pa=tif->tif_dir.td_subifd;
+		pb=o;
+		for (p=0; p < tif->tif_dir.td_nsubifd; p++)
+		{
+                        assert(pa != 0);
+			assert(*pa <= 0xFFFFFFFFUL);
+			*pb++=(uint32)(*pa++);
+		}
+		n=TIFFWriteDirectoryTagCheckedIfdArray(tif,ndir,dir,TIFFTAG_SUBIFD,tif->tif_dir.td_nsubifd,o);
+		_TIFFfree(o);
+	}
+	else
+		n=TIFFWriteDirectoryTagCheckedIfd8Array(tif,ndir,dir,TIFFTAG_SUBIFD,tif->tif_dir.td_nsubifd,tif->tif_dir.td_subifd);
+	if (!n)
+		return(0);
+	/*
+	 * Total hack: if this directory includes a SubIFD
+	 * tag then force the next <n> directories to be
+	 * written as ``sub directories'' of this one.  This
+	 * is used to write things like thumbnails and
+	 * image masks that one wants to keep out of the
+	 * normal directory linkage access mechanism.
+	 */
+	tif->tif_flags|=TIFF_INSUBIFD;
+	tif->tif_nsubifd=tif->tif_dir.td_nsubifd;
+	if (tif->tif_dir.td_nsubifd==1)
+		tif->tif_subifdoff=0;
+	else
+		tif->tif_subifdoff=m;
+	return(1);
+}
+
+static int
+TIFFWriteDirectoryTagCheckedAscii(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, char* value)
+{
+	assert(sizeof(char)==1);
+	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_ASCII,count,count,value));
+}
+
+static int
+TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value)
+{
+	assert(sizeof(uint8)==1);
+	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_UNDEFINED,count,count,value));
+}
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagCheckedByte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value)
+{
+	assert(sizeof(uint8)==1);
+	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_BYTE,1,1,&value));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagCheckedByteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value)
+{
+	assert(sizeof(uint8)==1);
+	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_BYTE,count,count,value));
+}
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagCheckedSbyte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value)
+{
+	assert(sizeof(int8)==1);
+	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SBYTE,1,1,&value));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagCheckedSbyteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int8* value)
+{
+	assert(sizeof(int8)==1);
+	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SBYTE,count,count,value));
+}
+
+static int
+TIFFWriteDirectoryTagCheckedShort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value)
+{
+	uint16 m;
+	assert(sizeof(uint16)==2);
+	m=value;
+	if (tif->tif_flags&TIFF_SWAB)
+		TIFFSwabShort(&m);
+	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SHORT,1,2,&m));
+}
+
+static int
+TIFFWriteDirectoryTagCheckedShortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint16* value)
+{
+	assert(count<0x80000000);
+	assert(sizeof(uint16)==2);
+	if (tif->tif_flags&TIFF_SWAB)
+		TIFFSwabArrayOfShort(value,count);
+	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SHORT,count,count*2,value));
+}
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagCheckedSshort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value)
+{
+	int16 m;
+	assert(sizeof(int16)==2);
+	m=value;
+	if (tif->tif_flags&TIFF_SWAB)
+		TIFFSwabShort((uint16*)(&m));
+	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SSHORT,1,2,&m));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagCheckedSshortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int16* value)
+{
+	assert(count<0x80000000);
+	assert(sizeof(int16)==2);
+	if (tif->tif_flags&TIFF_SWAB)
+		TIFFSwabArrayOfShort((uint16*)value,count);
+	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SSHORT,count,count*2,value));
+}
+
+static int
+TIFFWriteDirectoryTagCheckedLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value)
+{
+	uint32 m;
+	assert(sizeof(uint32)==4);
+	m=value;
+	if (tif->tif_flags&TIFF_SWAB)
+		TIFFSwabLong(&m);
+	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG,1,4,&m));
+}
+
+static int
+TIFFWriteDirectoryTagCheckedLongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value)
+{
+	assert(count<0x40000000);
+	assert(sizeof(uint32)==4);
+	if (tif->tif_flags&TIFF_SWAB)
+		TIFFSwabArrayOfLong(value,count);
+	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG,count,count*4,value));
+}
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagCheckedSlong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value)
+{
+	int32 m;
+	assert(sizeof(int32)==4);
+	m=value;
+	if (tif->tif_flags&TIFF_SWAB)
+		TIFFSwabLong((uint32*)(&m));
+	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG,1,4,&m));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagCheckedSlongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int32* value)
+{
+	assert(count<0x40000000);
+	assert(sizeof(int32)==4);
+	if (tif->tif_flags&TIFF_SWAB)
+		TIFFSwabArrayOfLong((uint32*)value,count);
+	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG,count,count*4,value));
+}
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagCheckedLong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint64 value)
+{
+	uint64 m;
+	assert(sizeof(uint64)==8);
+	assert(tif->tif_flags&TIFF_BIGTIFF);
+	m=value;
+	if (tif->tif_flags&TIFF_SWAB)
+		TIFFSwabLong8(&m);
+	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG8,1,8,&m));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagCheckedLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
+{
+	assert(count<0x20000000);
+	assert(sizeof(uint64)==8);
+	assert(tif->tif_flags&TIFF_BIGTIFF);
+	if (tif->tif_flags&TIFF_SWAB)
+		TIFFSwabArrayOfLong8(value,count);
+	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG8,count,count*8,value));
+}
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagCheckedSlong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int64 value)
+{
+	int64 m;
+	assert(sizeof(int64)==8);
+	assert(tif->tif_flags&TIFF_BIGTIFF);
+	m=value;
+	if (tif->tif_flags&TIFF_SWAB)
+		TIFFSwabLong8((uint64*)(&m));
+	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG8,1,8,&m));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagCheckedSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int64* value)
+{
+	assert(count<0x20000000);
+	assert(sizeof(int64)==8);
+	assert(tif->tif_flags&TIFF_BIGTIFF);
+	if (tif->tif_flags&TIFF_SWAB)
+		TIFFSwabArrayOfLong8((uint64*)value,count);
+	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG8,count,count*8,value));
+}
+
+static int
+TIFFWriteDirectoryTagCheckedRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
+{
+	uint32 m[2];
+	assert(value>=0.0);
+	assert(sizeof(uint32)==4);
+	if (value<=0.0)
+	{
+		m[0]=0;
+		m[1]=1;
+	}
+	else if (value==(double)(uint32)value)
+	{
+		m[0]=(uint32)value;
+		m[1]=1;
+	}
+	else if (value<1.0)
+	{
+		m[0]=(uint32)(value*0xFFFFFFFF);
+		m[1]=0xFFFFFFFF;
+	}
+	else
+	{
+		m[0]=0xFFFFFFFF;
+		m[1]=(uint32)(0xFFFFFFFF/value);
+	}
+	if (tif->tif_flags&TIFF_SWAB)
+	{
+		TIFFSwabLong(&m[0]);
+		TIFFSwabLong(&m[1]);
+	}
+	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_RATIONAL,1,8,&m[0]));
+}
+
+static int
+TIFFWriteDirectoryTagCheckedRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
+{
+	static const char module[] = "TIFFWriteDirectoryTagCheckedRationalArray";
+	uint32* m;
+	float* na;
+	uint32* nb;
+	uint32 nc;
+	int o;
+	assert(sizeof(uint32)==4);
+	m=_TIFFmalloc(count*2*sizeof(uint32));
+	if (m==NULL)
+	{
+		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+		return(0);
+	}
+	for (na=value, nb=m, nc=0; nc<count; na++, nb+=2, nc++)
+	{
+		if (*na<=0.0)
+		{
+			nb[0]=0;
+			nb[1]=1;
+		}
+		else if (*na==(float)(uint32)(*na))
+		{
+			nb[0]=(uint32)(*na);
+			nb[1]=1;
+		}
+		else if (*na<1.0)
+		{
+			nb[0]=(uint32)((*na)*0xFFFFFFFF);
+			nb[1]=0xFFFFFFFF;
+		}
+		else
+		{
+			nb[0]=0xFFFFFFFF;
+			nb[1]=(uint32)(0xFFFFFFFF/(*na));
+		}
+	}
+	if (tif->tif_flags&TIFF_SWAB)
+		TIFFSwabArrayOfLong(m,count*2);
+	o=TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_RATIONAL,count,count*8,&m[0]);
+	_TIFFfree(m);
+	return(o);
+}
+
+static int
+TIFFWriteDirectoryTagCheckedSrationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
+{
+	static const char module[] = "TIFFWriteDirectoryTagCheckedSrationalArray";
+	int32* m;
+	float* na;
+	int32* nb;
+	uint32 nc;
+	int o;
+	assert(sizeof(int32)==4);
+	m=_TIFFmalloc(count*2*sizeof(int32));
+	if (m==NULL)
+	{
+		TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+		return(0);
+	}
+	for (na=value, nb=m, nc=0; nc<count; na++, nb+=2, nc++)
+	{
+		if (*na<0.0)
+		{
+			if (*na==(int32)(*na))
+			{
+				nb[0]=(int32)(*na);
+				nb[1]=1;
+			}
+			else if (*na>-1.0)
+			{
+				nb[0]=-(int32)((-*na)*0x7FFFFFFF);
+				nb[1]=0x7FFFFFFF;
+			}
+			else
+			{
+				nb[0]=-0x7FFFFFFF;
+				nb[1]=(int32)(0x7FFFFFFF/(-*na));
+			}
+		}
+		else
+		{
+			if (*na==(int32)(*na))
+			{
+				nb[0]=(int32)(*na);
+				nb[1]=1;
+			}
+			else if (*na<1.0)
+			{
+				nb[0]=(int32)((*na)*0x7FFFFFFF);
+				nb[1]=0x7FFFFFFF;
+			}
+			else
+			{
+				nb[0]=0x7FFFFFFF;
+				nb[1]=(int32)(0x7FFFFFFF/(*na));
+			}
+		}
+	}
+	if (tif->tif_flags&TIFF_SWAB)
+		TIFFSwabArrayOfLong((uint32*)m,count*2);
+	o=TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SRATIONAL,count,count*8,&m[0]);
+	_TIFFfree(m);
+	return(o);
+}
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagCheckedFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value)
+{
+	float m;
+	assert(sizeof(float)==4);
+	m=value;
+	TIFFCvtNativeToIEEEFloat(tif,1,&m);
+	if (tif->tif_flags&TIFF_SWAB)
+		TIFFSwabFloat(&m);
+	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_FLOAT,1,4,&m));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagCheckedFloatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
+{
+	assert(count<0x40000000);
+	assert(sizeof(float)==4);
+	TIFFCvtNativeToIEEEFloat(tif,count,&value);
+	if (tif->tif_flags&TIFF_SWAB)
+		TIFFSwabArrayOfFloat(value,count);
+	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_FLOAT,count,count*4,value));
+}
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagCheckedDouble(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
+{
+	double m;
+	assert(sizeof(double)==8);
+	m=value;
+	TIFFCvtNativeToIEEEDouble(tif,1,&m);
+	if (tif->tif_flags&TIFF_SWAB)
+		TIFFSwabDouble(&m);
+	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_DOUBLE,1,8,&m));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagCheckedDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value)
+{
+	assert(count<0x20000000);
+	assert(sizeof(double)==8);
+	TIFFCvtNativeToIEEEDouble(tif,count,&value);
+	if (tif->tif_flags&TIFF_SWAB)
+		TIFFSwabArrayOfDouble(value,count);
+	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_DOUBLE,count,count*8,value));
+}
+
+static int
+TIFFWriteDirectoryTagCheckedIfdArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value)
+{
+	assert(count<0x40000000);
+	assert(sizeof(uint32)==4);
+	if (tif->tif_flags&TIFF_SWAB)
+		TIFFSwabArrayOfLong(value,count);
+	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_IFD,count,count*4,value));
+}
+
+static int
+TIFFWriteDirectoryTagCheckedIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
+{
+	assert(count<0x20000000);
+	assert(sizeof(uint64)==8);
+	assert(tif->tif_flags&TIFF_BIGTIFF);
+	if (tif->tif_flags&TIFF_SWAB)
+		TIFFSwabArrayOfLong8(value,count);
+	return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_IFD8,count,count*8,value));
+}
+
+static int
+TIFFWriteDirectoryTagData(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 datatype, uint32 count, uint32 datalength, void* data)
+{
+	static const char module[] = "TIFFWriteDirectoryTagData";
+	uint32 m;
+	m=0;
+	while (m<(*ndir))
+	{
+		assert(dir[m].tdir_tag!=tag);
+		if (dir[m].tdir_tag>tag)
+			break;
+		m++;
+	}
+	if (m<(*ndir))
+	{
+		uint32 n;
+		for (n=*ndir; n>m; n--)
+			dir[n]=dir[n-1];
+	}
+	dir[m].tdir_tag=tag;
+	dir[m].tdir_type=datatype;
+	dir[m].tdir_count=count;
+	dir[m].tdir_offset.toff_long8 = 0;
+	if (datalength<=((tif->tif_flags&TIFF_BIGTIFF)?0x8U:0x4U))
+		_TIFFmemcpy(&dir[m].tdir_offset,data,datalength);
+	else
+	{
+		uint64 na,nb;
+		na=tif->tif_dataoff;
+		nb=na+datalength;
+		if (!(tif->tif_flags&TIFF_BIGTIFF))
+			nb=(uint32)nb;
+		if ((nb<na)||(nb<datalength))
+		{
+			TIFFErrorExt(tif->tif_clientdata,module,"Maximum TIFF file size exceeded");
+			return(0);
+		}
+		if (!SeekOK(tif,na))
+		{
+			TIFFErrorExt(tif->tif_clientdata,module,"IO error writing tag data");
+			return(0);
+		}
+		assert(datalength<0x80000000UL);
+		if (!WriteOK(tif,data,(tmsize_t)datalength))
+		{
+			TIFFErrorExt(tif->tif_clientdata,module,"IO error writing tag data");
+			return(0);
+		}
+		tif->tif_dataoff=nb;
+		if (tif->tif_dataoff&1)
+			tif->tif_dataoff++;
+		if (!(tif->tif_flags&TIFF_BIGTIFF))
+		{
+			uint32 o;
+			o=(uint32)na;
+			if (tif->tif_flags&TIFF_SWAB)
+				TIFFSwabLong(&o);
+			_TIFFmemcpy(&dir[m].tdir_offset,&o,4);
+		}
+		else
+		{
+			dir[m].tdir_offset.toff_long8 = na;
+			if (tif->tif_flags&TIFF_SWAB)
+				TIFFSwabLong8(&dir[m].tdir_offset.toff_long8);
+		}
+	}
+	(*ndir)++;
+	return(1);
+}
+
+/*
+ * Link the current directory into the directory chain for the file.
+ */
+static int
+TIFFLinkDirectory(TIFF* tif)
+{
+	static const char module[] = "TIFFLinkDirectory";
+
+	tif->tif_diroff = (TIFFSeekFile(tif,0,SEEK_END)+1) &~ 1;
+
+	/*
+	 * Handle SubIFDs
+	 */
+	if (tif->tif_flags & TIFF_INSUBIFD)
+	{
+		if (!(tif->tif_flags&TIFF_BIGTIFF))
+		{
+			uint32 m;
+			m = (uint32)tif->tif_diroff;
+			if (tif->tif_flags & TIFF_SWAB)
+				TIFFSwabLong(&m);
+			(void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
+			if (!WriteOK(tif, &m, 4)) {
+				TIFFErrorExt(tif->tif_clientdata, module,
+				     "Error writing SubIFD directory link");
+				return (0);
+			}
+			/*
+			 * Advance to the next SubIFD or, if this is
+			 * the last one configured, revert back to the
+			 * normal directory linkage.
+			 */
+			if (--tif->tif_nsubifd)
+				tif->tif_subifdoff += 4;
+			else
+				tif->tif_flags &= ~TIFF_INSUBIFD;
+			return (1);
+		}
+		else
+		{
+			uint64 m;
+			m = tif->tif_diroff;
+			if (tif->tif_flags & TIFF_SWAB)
+				TIFFSwabLong8(&m);
+			(void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
+			if (!WriteOK(tif, &m, 8)) {
+				TIFFErrorExt(tif->tif_clientdata, module,
+				     "Error writing SubIFD directory link");
+				return (0);
+			}
+			/*
+			 * Advance to the next SubIFD or, if this is
+			 * the last one configured, revert back to the
+			 * normal directory linkage.
+			 */
+			if (--tif->tif_nsubifd)
+				tif->tif_subifdoff += 8;
+			else
+				tif->tif_flags &= ~TIFF_INSUBIFD;
+			return (1);
+		}
+	}
+
+	if (!(tif->tif_flags&TIFF_BIGTIFF))
+	{
+		uint32 m;
+		uint32 nextdir;
+		m = (uint32)(tif->tif_diroff);
+		if (tif->tif_flags & TIFF_SWAB)
+			TIFFSwabLong(&m);
+		if (tif->tif_header.classic.tiff_diroff == 0) {
+			/*
+			 * First directory, overwrite offset in header.
+			 */
+			tif->tif_header.classic.tiff_diroff = (uint32) tif->tif_diroff;
+			(void) TIFFSeekFile(tif,4, SEEK_SET);
+			if (!WriteOK(tif, &m, 4)) {
+				TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+					     "Error writing TIFF header");
+				return (0);
+			}
+			return (1);
+		}
+		/*
+		 * Not the first directory, search to the last and append.
+		 */
+		nextdir = tif->tif_header.classic.tiff_diroff;
+		while(1) {
+			uint16 dircount;
+			uint32 nextnextdir;
+
+			if (!SeekOK(tif, nextdir) ||
+			    !ReadOK(tif, &dircount, 2)) {
+				TIFFErrorExt(tif->tif_clientdata, module,
+					     "Error fetching directory count");
+				return (0);
+			}
+			if (tif->tif_flags & TIFF_SWAB)
+				TIFFSwabShort(&dircount);
+			(void) TIFFSeekFile(tif,
+			    nextdir+2+dircount*12, SEEK_SET);
+			if (!ReadOK(tif, &nextnextdir, 4)) {
+				TIFFErrorExt(tif->tif_clientdata, module,
+					     "Error fetching directory link");
+				return (0);
+			}
+			if (tif->tif_flags & TIFF_SWAB)
+				TIFFSwabLong(&nextnextdir);
+			if (nextnextdir==0)
+			{
+				(void) TIFFSeekFile(tif,
+				    nextdir+2+dircount*12, SEEK_SET);
+				if (!WriteOK(tif, &m, 4)) {
+					TIFFErrorExt(tif->tif_clientdata, module,
+					     "Error writing directory link");
+					return (0);
+				}
+				break;
+			}
+			nextdir=nextnextdir;
+		}
+	}
+	else
+	{
+		uint64 m;
+		uint64 nextdir;
+		m = tif->tif_diroff;
+		if (tif->tif_flags & TIFF_SWAB)
+			TIFFSwabLong8(&m);
+		if (tif->tif_header.big.tiff_diroff == 0) {
+			/*
+			 * First directory, overwrite offset in header.
+			 */
+			tif->tif_header.big.tiff_diroff = tif->tif_diroff;
+			(void) TIFFSeekFile(tif,8, SEEK_SET);
+			if (!WriteOK(tif, &m, 8)) {
+				TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+					     "Error writing TIFF header");
+				return (0);
+			}
+			return (1);
+		}
+		/*
+		 * Not the first directory, search to the last and append.
+		 */
+		nextdir = tif->tif_header.big.tiff_diroff;
+		while(1) {
+			uint64 dircount64;
+			uint16 dircount;
+			uint64 nextnextdir;
+
+			if (!SeekOK(tif, nextdir) ||
+			    !ReadOK(tif, &dircount64, 8)) {
+				TIFFErrorExt(tif->tif_clientdata, module,
+					     "Error fetching directory count");
+				return (0);
+			}
+			if (tif->tif_flags & TIFF_SWAB)
+				TIFFSwabLong8(&dircount64);
+			if (dircount64>0xFFFF)
+			{
+				TIFFErrorExt(tif->tif_clientdata, module,
+					     "Sanity check on tag count failed, likely corrupt TIFF");
+				return (0);
+			}
+			dircount=(uint16)dircount64;
+			(void) TIFFSeekFile(tif,
+			    nextdir+8+dircount*20, SEEK_SET);
+			if (!ReadOK(tif, &nextnextdir, 8)) {
+				TIFFErrorExt(tif->tif_clientdata, module,
+					     "Error fetching directory link");
+				return (0);
+			}
+			if (tif->tif_flags & TIFF_SWAB)
+				TIFFSwabLong8(&nextnextdir);
+			if (nextnextdir==0)
+			{
+				(void) TIFFSeekFile(tif,
+				    nextdir+8+dircount*20, SEEK_SET);
+				if (!WriteOK(tif, &m, 8)) {
+					TIFFErrorExt(tif->tif_clientdata, module,
+					     "Error writing directory link");
+					return (0);
+				}
+				break;
+			}
+			nextdir=nextnextdir;
+		}
+	}
+	return (1);
+}
+
+/************************************************************************/
+/*                          TIFFRewriteField()                          */
+/*                                                                      */
+/*      Rewrite a field in the directory on disk without regard to      */
+/*      updating the TIFF directory structure in memory.  Currently     */
+/*      only supported for field that already exist in the on-disk      */
+/*      directory.  Mainly used for updating stripoffset /              */
+/*      stripbytecount values after the directory is already on         */
+/*      disk.                                                           */
+/*                                                                      */
+/*      Returns zero on failure, and one on success.                    */
+/************************************************************************/
+
+int
+_TIFFRewriteField(TIFF* tif, uint16 tag, TIFFDataType in_datatype, 
+                  tmsize_t count, void* data)
+{
+    static const char module[] = "TIFFResetField";
+    /* const TIFFField* fip = NULL; */
+    uint16 dircount;
+    tmsize_t dirsize;
+    uint8 direntry_raw[20];
+    uint16 entry_tag = 0;
+    uint16 entry_type = 0;
+    uint64 entry_count = 0;
+    uint64 entry_offset = 0;
+    int    value_in_entry = 0;
+    uint64 read_offset;
+    uint8 *buf_to_write = NULL;
+    TIFFDataType datatype;
+
+/* -------------------------------------------------------------------- */
+/*      Find field definition.                                          */
+/* -------------------------------------------------------------------- */
+    /*fip =*/ TIFFFindField(tif, tag, TIFF_ANY);
+
+/* -------------------------------------------------------------------- */
+/*      Do some checking this is a straight forward case.               */
+/* -------------------------------------------------------------------- */
+    if( isMapped(tif) )
+    {
+        TIFFErrorExt( tif->tif_clientdata, module, 
+                      "Memory mapped files not currently supported for this operation." );
+        return 0;
+    }
+
+    if( tif->tif_diroff == 0 )
+    {
+        TIFFErrorExt( tif->tif_clientdata, module, 
+                      "Attempt to reset field on directory not already on disk." );
+        return 0;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Read the directory entry count.                                 */
+/* -------------------------------------------------------------------- */
+    if (!SeekOK(tif, tif->tif_diroff)) {
+        TIFFErrorExt(tif->tif_clientdata, module,
+                     "%s: Seek error accessing TIFF directory",
+                     tif->tif_name);
+        return 0;
+    }
+
+    read_offset = tif->tif_diroff;
+
+    if (!(tif->tif_flags&TIFF_BIGTIFF))
+    {
+        if (!ReadOK(tif, &dircount, sizeof (uint16))) {
+            TIFFErrorExt(tif->tif_clientdata, module,
+                         "%s: Can not read TIFF directory count",
+                         tif->tif_name);
+            return 0;
+        }
+        if (tif->tif_flags & TIFF_SWAB)
+            TIFFSwabShort(&dircount);
+        dirsize = 12;
+        read_offset += 2;
+    } else {
+        uint64 dircount64;
+        if (!ReadOK(tif, &dircount64, sizeof (uint64))) {
+            TIFFErrorExt(tif->tif_clientdata, module,
+                         "%s: Can not read TIFF directory count",
+                         tif->tif_name);
+            return 0;
+        }
+        if (tif->tif_flags & TIFF_SWAB)
+            TIFFSwabLong8(&dircount64);
+        dircount = (uint16)dircount64;
+        dirsize = 20;
+        read_offset += 8;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Read through directory to find target tag.                      */
+/* -------------------------------------------------------------------- */
+    while( dircount > 0 )
+    {
+        if (!ReadOK(tif, direntry_raw, dirsize)) {
+            TIFFErrorExt(tif->tif_clientdata, module,
+                         "%s: Can not read TIFF directory entry.",
+                         tif->tif_name);
+            return 0;
+        }
+
+        memcpy( &entry_tag, direntry_raw + 0, sizeof(uint16) );
+        if (tif->tif_flags&TIFF_SWAB)
+            TIFFSwabShort( &entry_tag );
+
+        if( entry_tag == tag )
+            break;
+
+        read_offset += dirsize;
+    }
+
+    if( entry_tag != tag )
+    {
+        TIFFErrorExt(tif->tif_clientdata, module,
+                     "%s: Could not find tag %d.",
+                     tif->tif_name, tag );
+        return 0;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Extract the type, count and offset for this entry.              */
+/* -------------------------------------------------------------------- */
+    memcpy( &entry_type, direntry_raw + 2, sizeof(uint16) );
+    if (tif->tif_flags&TIFF_SWAB)
+        TIFFSwabShort( &entry_type );
+
+    if (!(tif->tif_flags&TIFF_BIGTIFF))
+    {
+        uint32 value;
+        
+        memcpy( &value, direntry_raw + 4, sizeof(uint32) );
+        if (tif->tif_flags&TIFF_SWAB)
+            TIFFSwabLong( &value );
+        entry_count = value;
+
+        memcpy( &value, direntry_raw + 8, sizeof(uint32) );
+        if (tif->tif_flags&TIFF_SWAB)
+            TIFFSwabLong( &value );
+        entry_offset = value;
+    }
+    else
+    {
+        memcpy( &entry_count, direntry_raw + 4, sizeof(uint64) );
+        if (tif->tif_flags&TIFF_SWAB)
+            TIFFSwabLong8( &entry_count );
+
+        memcpy( &entry_offset, direntry_raw + 12, sizeof(uint64) );
+        if (tif->tif_flags&TIFF_SWAB)
+            TIFFSwabLong8( &entry_offset );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      What data type do we want to write this as?                     */
+/* -------------------------------------------------------------------- */
+    if( TIFFDataWidth(in_datatype) == 8 && !(tif->tif_flags&TIFF_BIGTIFF) )
+    {
+        if( in_datatype == TIFF_LONG8 )
+            datatype = TIFF_LONG;
+        else if( in_datatype == TIFF_SLONG8 )
+            datatype = TIFF_SLONG;
+        else if( in_datatype == TIFF_IFD8 )
+            datatype = TIFF_IFD;
+        else
+            datatype = in_datatype;
+    }
+    else 
+        datatype = in_datatype;
+
+/* -------------------------------------------------------------------- */
+/*      Prepare buffer of actual data to write.  This includes          */
+/*      swabbing as needed.                                             */
+/* -------------------------------------------------------------------- */
+    buf_to_write =
+	    (uint8 *)_TIFFCheckMalloc(tif, count, TIFFDataWidth(datatype),
+				      "for field buffer.");
+    if (!buf_to_write)
+        return 0;
+
+    if( datatype == in_datatype )
+        memcpy( buf_to_write, data, count * TIFFDataWidth(datatype) );
+    else if( datatype == TIFF_SLONG && in_datatype == TIFF_SLONG8 )
+    {
+	tmsize_t i;
+
+        for( i = 0; i < count; i++ )
+        {
+            ((int32 *) buf_to_write)[i] = 
+                (int32) ((int64 *) data)[i];
+            if( (int64) ((int32 *) buf_to_write)[i] != ((int64 *) data)[i] )
+            {
+                _TIFFfree( buf_to_write );
+                TIFFErrorExt( tif->tif_clientdata, module, 
+                              "Value exceeds 32bit range of output type." );
+                return 0;
+            }
+        }
+    }
+    else if( (datatype == TIFF_LONG && in_datatype == TIFF_LONG8)
+             || (datatype == TIFF_IFD && in_datatype == TIFF_IFD8) )
+    {
+	tmsize_t i;
+
+        for( i = 0; i < count; i++ )
+        {
+            ((uint32 *) buf_to_write)[i] = 
+                (uint32) ((uint64 *) data)[i];
+            if( (uint64) ((uint32 *) buf_to_write)[i] != ((uint64 *) data)[i] )
+            {
+                _TIFFfree( buf_to_write );
+                TIFFErrorExt( tif->tif_clientdata, module, 
+                              "Value exceeds 32bit range of output type." );
+                return 0;
+            }
+        }
+    }
+
+    if( TIFFDataWidth(datatype) > 1 && (tif->tif_flags&TIFF_SWAB) )
+    {
+        if( TIFFDataWidth(datatype) == 2 )
+            TIFFSwabArrayOfShort( (uint16 *) buf_to_write, count );
+        else if( TIFFDataWidth(datatype) == 4 )
+            TIFFSwabArrayOfLong( (uint32 *) buf_to_write, count );
+        else if( TIFFDataWidth(datatype) == 8 )
+            TIFFSwabArrayOfLong8( (uint64 *) buf_to_write, count );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Is this a value that fits into the directory entry?             */
+/* -------------------------------------------------------------------- */
+    if (!(tif->tif_flags&TIFF_BIGTIFF))
+    {
+        if( TIFFDataWidth(datatype) * count <= 4 )
+        {
+            entry_offset = read_offset + 8;
+            value_in_entry = 1;
+        }
+    }
+    else
+    {
+        if( TIFFDataWidth(datatype) * count <= 8 )
+        {
+            entry_offset = read_offset + 12;
+            value_in_entry = 1;
+        }
+    }
+
+/* -------------------------------------------------------------------- */
+/*      If the tag type, and count match, then we just write it out     */
+/*      over the old values without altering the directory entry at     */
+/*      all.                                                            */
+/* -------------------------------------------------------------------- */
+    if( entry_count == (uint64)count && entry_type == (uint16) datatype )
+    {
+        if (!SeekOK(tif, entry_offset)) {
+            _TIFFfree( buf_to_write );
+            TIFFErrorExt(tif->tif_clientdata, module,
+                         "%s: Seek error accessing TIFF directory",
+                         tif->tif_name);
+            return 0;
+        }
+        if (!WriteOK(tif, buf_to_write, count*TIFFDataWidth(datatype))) {
+            _TIFFfree( buf_to_write );
+            TIFFErrorExt(tif->tif_clientdata, module,
+                         "Error writing directory link");
+            return (0);
+        }
+
+        _TIFFfree( buf_to_write );
+        return 1;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Otherwise, we write the new tag data at the end of the file.    */
+/* -------------------------------------------------------------------- */
+    if( !value_in_entry )
+    {
+        entry_offset = TIFFSeekFile(tif,0,SEEK_END);
+        
+        if (!WriteOK(tif, buf_to_write, count*TIFFDataWidth(datatype))) {
+            _TIFFfree( buf_to_write );
+            TIFFErrorExt(tif->tif_clientdata, module,
+                         "Error writing directory link");
+            return (0);
+        }
+        
+        _TIFFfree( buf_to_write );
+    }
+    else
+    {
+        memcpy( &entry_offset, buf_to_write, count*TIFFDataWidth(datatype));
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Adjust the directory entry.                                     */
+/* -------------------------------------------------------------------- */
+    entry_type = datatype;
+    memcpy( direntry_raw + 2, &entry_type, sizeof(uint16) );
+    if (tif->tif_flags&TIFF_SWAB)
+        TIFFSwabShort( (uint16 *) (direntry_raw + 2) );
+
+    if (!(tif->tif_flags&TIFF_BIGTIFF))
+    {
+        uint32 value;
+
+        value = (uint32) entry_count;
+        memcpy( direntry_raw + 4, &value, sizeof(uint32) );
+        if (tif->tif_flags&TIFF_SWAB)
+            TIFFSwabLong( (uint32 *) (direntry_raw + 4) );
+
+        value = (uint32) entry_offset;
+        memcpy( direntry_raw + 8, &value, sizeof(uint32) );
+        if (tif->tif_flags&TIFF_SWAB)
+            TIFFSwabLong( (uint32 *) (direntry_raw + 8) );
+    }
+    else
+    {
+        memcpy( direntry_raw + 4, &entry_count, sizeof(uint64) );
+        if (tif->tif_flags&TIFF_SWAB)
+            TIFFSwabLong8( (uint64 *) (direntry_raw + 4) );
+
+        memcpy( direntry_raw + 12, &entry_offset, sizeof(uint64) );
+        if (tif->tif_flags&TIFF_SWAB)
+            TIFFSwabLong8( (uint64 *) (direntry_raw + 12) );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Write the directory entry out to disk.                          */
+/* -------------------------------------------------------------------- */
+    if (!SeekOK(tif, read_offset )) {
+        TIFFErrorExt(tif->tif_clientdata, module,
+                     "%s: Seek error accessing TIFF directory",
+                     tif->tif_name);
+        return 0;
+    }
+
+    if (!WriteOK(tif, direntry_raw,dirsize))
+    {
+        TIFFErrorExt(tif->tif_clientdata, module,
+                     "%s: Can not write TIFF directory entry.",
+                     tif->tif_name);
+        return 0;
+    }
+    
+    return 1;
+}
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tif_dumpmode.c b/Source/LibTIFF4/tif_dumpmode.c
index 4cae954..8885e04 100644
--- a/Source/LibTIFF4/tif_dumpmode.c
+++ b/Source/LibTIFF4/tif_dumpmode.c
@@ -1,143 +1,143 @@
-/* $Header: /cvsroot/freeimage/FreeImage/Source/LibTIFF4/tif_dumpmode.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library.
- *
- * "Null" Compression Algorithm Support.
- */
-#include "tiffiop.h"
-
-static int
-DumpFixupTags(TIFF* tif)
-{
-	(void) tif;
-	return (1);
-}
-
-/*
- * Encode a hunk of pixels.
- */
-static int
-DumpModeEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s)
-{
-	(void) s;
-	while (cc > 0) {
-		tmsize_t n;
-
-		n = cc;
-		if (tif->tif_rawcc + n > tif->tif_rawdatasize)
-			n = tif->tif_rawdatasize - tif->tif_rawcc;
-
-		assert( n > 0 );
-
-		/*
-		 * Avoid copy if client has setup raw
-		 * data buffer to avoid extra copy.
-		 */
-		if (tif->tif_rawcp != pp)
-			_TIFFmemcpy(tif->tif_rawcp, pp, n);
-		tif->tif_rawcp += n;
-		tif->tif_rawcc += n;
-		pp += n;
-		cc -= n;
-		if (tif->tif_rawcc >= tif->tif_rawdatasize &&
-		    !TIFFFlushData1(tif))
-			return (-1);
-	}
-	return (1);
-}
-
-/*
- * Decode a hunk of pixels.
- */
-static int
-DumpModeDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
-{
-	static const char module[] = "DumpModeDecode";
-	(void) s;
-	if (tif->tif_rawcc < cc) {
-#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
-		TIFFErrorExt(tif->tif_clientdata, module,
-"Not enough data for scanline %lu, expected a request for at most %I64d bytes, got a request for %I64d bytes",
-		             (unsigned long) tif->tif_row,
-		             (signed __int64) tif->tif_rawcc,
-		             (signed __int64) cc);
-#else
-		TIFFErrorExt(tif->tif_clientdata, module,
-"Not enough data for scanline %lu, expected a request for at most %lld bytes, got a request for %lld bytes",
-		             (unsigned long) tif->tif_row,
-		             (signed long long) tif->tif_rawcc,
-		             (signed long long) cc);
-#endif
-		return (0);
-	}
-	/*
-	 * Avoid copy if client has setup raw
-	 * data buffer to avoid extra copy.
-	 */
-	if (tif->tif_rawcp != buf)
-		_TIFFmemcpy(buf, tif->tif_rawcp, cc);
-	tif->tif_rawcp += cc;
-	tif->tif_rawcc -= cc;  
-	return (1);
-}
-
-/*
- * Seek forwards nrows in the current strip.
- */
-static int
-DumpModeSeek(TIFF* tif, uint32 nrows)
-{
-	tif->tif_rawcp += nrows * tif->tif_scanlinesize;
-	tif->tif_rawcc -= nrows * tif->tif_scanlinesize;
-	return (1);
-}
-
-/*
- * Initialize dump mode.
- */
-int
-TIFFInitDumpMode(TIFF* tif, int scheme)
-{
-	(void) scheme;
-	tif->tif_fixuptags = DumpFixupTags;  
-	tif->tif_decoderow = DumpModeDecode;
-	tif->tif_decodestrip = DumpModeDecode;
-	tif->tif_decodetile = DumpModeDecode;
-	tif->tif_encoderow = DumpModeEncode;
-	tif->tif_encodestrip = DumpModeEncode;
-	tif->tif_encodetile = DumpModeEncode; 
-	tif->tif_seek = DumpModeSeek;
-	return (1);
-}
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Header: /cvsroot/freeimage/FreeImage/Source/LibTIFF4/tif_dumpmode.c,v 1.11 2015/02/19 22:39:58 drolon Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and 
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
+ * 
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * "Null" Compression Algorithm Support.
+ */
+#include "tiffiop.h"
+
+static int
+DumpFixupTags(TIFF* tif)
+{
+	(void) tif;
+	return (1);
+}
+
+/*
+ * Encode a hunk of pixels.
+ */
+static int
+DumpModeEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s)
+{
+	(void) s;
+	while (cc > 0) {
+		tmsize_t n;
+
+		n = cc;
+		if (tif->tif_rawcc + n > tif->tif_rawdatasize)
+			n = tif->tif_rawdatasize - tif->tif_rawcc;
+
+		assert( n > 0 );
+
+		/*
+		 * Avoid copy if client has setup raw
+		 * data buffer to avoid extra copy.
+		 */
+		if (tif->tif_rawcp != pp)
+			_TIFFmemcpy(tif->tif_rawcp, pp, n);
+		tif->tif_rawcp += n;
+		tif->tif_rawcc += n;
+		pp += n;
+		cc -= n;
+		if (tif->tif_rawcc >= tif->tif_rawdatasize &&
+		    !TIFFFlushData1(tif))
+			return (-1);
+	}
+	return (1);
+}
+
+/*
+ * Decode a hunk of pixels.
+ */
+static int
+DumpModeDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
+{
+	static const char module[] = "DumpModeDecode";
+	(void) s;
+	if (tif->tif_rawcc < cc) {
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+		TIFFErrorExt(tif->tif_clientdata, module,
+"Not enough data for scanline %lu, expected a request for at most %I64d bytes, got a request for %I64d bytes",
+		             (unsigned long) tif->tif_row,
+		             (signed __int64) tif->tif_rawcc,
+		             (signed __int64) cc);
+#else
+		TIFFErrorExt(tif->tif_clientdata, module,
+"Not enough data for scanline %lu, expected a request for at most %lld bytes, got a request for %lld bytes",
+		             (unsigned long) tif->tif_row,
+		             (signed long long) tif->tif_rawcc,
+		             (signed long long) cc);
+#endif
+		return (0);
+	}
+	/*
+	 * Avoid copy if client has setup raw
+	 * data buffer to avoid extra copy.
+	 */
+	if (tif->tif_rawcp != buf)
+		_TIFFmemcpy(buf, tif->tif_rawcp, cc);
+	tif->tif_rawcp += cc;
+	tif->tif_rawcc -= cc;  
+	return (1);
+}
+
+/*
+ * Seek forwards nrows in the current strip.
+ */
+static int
+DumpModeSeek(TIFF* tif, uint32 nrows)
+{
+	tif->tif_rawcp += nrows * tif->tif_scanlinesize;
+	tif->tif_rawcc -= nrows * tif->tif_scanlinesize;
+	return (1);
+}
+
+/*
+ * Initialize dump mode.
+ */
+int
+TIFFInitDumpMode(TIFF* tif, int scheme)
+{
+	(void) scheme;
+	tif->tif_fixuptags = DumpFixupTags;  
+	tif->tif_decoderow = DumpModeDecode;
+	tif->tif_decodestrip = DumpModeDecode;
+	tif->tif_decodetile = DumpModeDecode;
+	tif->tif_encoderow = DumpModeEncode;
+	tif->tif_encodestrip = DumpModeEncode;
+	tif->tif_encodetile = DumpModeEncode; 
+	tif->tif_seek = DumpModeSeek;
+	return (1);
+}
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tif_error.c b/Source/LibTIFF4/tif_error.c
index c2fd071..60547cb 100644
--- a/Source/LibTIFF4/tif_error.c
+++ b/Source/LibTIFF4/tif_error.c
@@ -1,80 +1,80 @@
-/* $Header: /cvsroot/freeimage/FreeImage/Source/LibTIFF4/tif_error.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library.
- */
-#include "tiffiop.h"
-
-TIFFErrorHandlerExt _TIFFerrorHandlerExt = NULL;
-
-TIFFErrorHandler
-TIFFSetErrorHandler(TIFFErrorHandler handler)
-{
-	TIFFErrorHandler prev = _TIFFerrorHandler;
-	_TIFFerrorHandler = handler;
-	return (prev);
-}
-
-TIFFErrorHandlerExt
-TIFFSetErrorHandlerExt(TIFFErrorHandlerExt handler)
-{
-	TIFFErrorHandlerExt prev = _TIFFerrorHandlerExt;
-	_TIFFerrorHandlerExt = handler;
-	return (prev);
-}
-
-void
-TIFFError(const char* module, const char* fmt, ...)
-{
-	va_list ap;
-	va_start(ap, fmt);
-	if (_TIFFerrorHandler)
-		(*_TIFFerrorHandler)(module, fmt, ap);
-	if (_TIFFerrorHandlerExt)
-		(*_TIFFerrorHandlerExt)(0, module, fmt, ap);
-	va_end(ap);
-}
-
-void
-TIFFErrorExt(thandle_t fd, const char* module, const char* fmt, ...)
-{
-	va_list ap;
-	va_start(ap, fmt);
-	if (_TIFFerrorHandler)
-		(*_TIFFerrorHandler)(module, fmt, ap);
-	if (_TIFFerrorHandlerExt)
-		(*_TIFFerrorHandlerExt)(fd, module, fmt, ap);
-	va_end(ap);
-}
-
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Header: /cvsroot/freeimage/FreeImage/Source/LibTIFF4/tif_error.c,v 1.11 2015/02/19 22:39:58 drolon Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and 
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
+ * 
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ */
+#include "tiffiop.h"
+
+TIFFErrorHandlerExt _TIFFerrorHandlerExt = NULL;
+
+TIFFErrorHandler
+TIFFSetErrorHandler(TIFFErrorHandler handler)
+{
+	TIFFErrorHandler prev = _TIFFerrorHandler;
+	_TIFFerrorHandler = handler;
+	return (prev);
+}
+
+TIFFErrorHandlerExt
+TIFFSetErrorHandlerExt(TIFFErrorHandlerExt handler)
+{
+	TIFFErrorHandlerExt prev = _TIFFerrorHandlerExt;
+	_TIFFerrorHandlerExt = handler;
+	return (prev);
+}
+
+void
+TIFFError(const char* module, const char* fmt, ...)
+{
+	va_list ap;
+	va_start(ap, fmt);
+	if (_TIFFerrorHandler)
+		(*_TIFFerrorHandler)(module, fmt, ap);
+	if (_TIFFerrorHandlerExt)
+		(*_TIFFerrorHandlerExt)(0, module, fmt, ap);
+	va_end(ap);
+}
+
+void
+TIFFErrorExt(thandle_t fd, const char* module, const char* fmt, ...)
+{
+	va_list ap;
+	va_start(ap, fmt);
+	if (_TIFFerrorHandler)
+		(*_TIFFerrorHandler)(module, fmt, ap);
+	if (_TIFFerrorHandlerExt)
+		(*_TIFFerrorHandlerExt)(fd, module, fmt, ap);
+	va_end(ap);
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tif_extension.c b/Source/LibTIFF4/tif_extension.c
index c84ac2a..3e4f924 100644
--- a/Source/LibTIFF4/tif_extension.c
+++ b/Source/LibTIFF4/tif_extension.c
@@ -1,118 +1,118 @@
-/* $Header: /cvsroot/freeimage/FreeImage/Source/LibTIFF4/tif_extension.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library.
- *
- * Various routines support external extension of the tag set, and other
- * application extension capabilities. 
- */
-
-#include "tiffiop.h"
-
-int TIFFGetTagListCount( TIFF *tif )
-
-{
-    TIFFDirectory* td = &tif->tif_dir;
-    
-    return td->td_customValueCount;
-}
-
-uint32 TIFFGetTagListEntry( TIFF *tif, int tag_index )
-
-{
-    TIFFDirectory* td = &tif->tif_dir;
-
-    if( tag_index < 0 || tag_index >= td->td_customValueCount )
-        return (uint32)(-1);
-    else
-        return td->td_customValues[tag_index].info->field_tag;
-}
-
-/*
-** This provides read/write access to the TIFFTagMethods within the TIFF
-** structure to application code without giving access to the private
-** TIFF structure.
-*/
-TIFFTagMethods *TIFFAccessTagMethods( TIFF *tif )
-
-{
-    return &(tif->tif_tagmethods);
-}
-
-void *TIFFGetClientInfo( TIFF *tif, const char *name )
-
-{
-    TIFFClientInfoLink *link = tif->tif_clientinfo;
-
-    while( link != NULL && strcmp(link->name,name) != 0 )
-        link = link->next;
-
-    if( link != NULL )
-        return link->data;
-    else
-        return NULL;
-}
-
-void TIFFSetClientInfo( TIFF *tif, void *data, const char *name )
-
-{
-    TIFFClientInfoLink *link = tif->tif_clientinfo;
-
-    /*
-    ** Do we have an existing link with this name?  If so, just
-    ** set it.
-    */
-    while( link != NULL && strcmp(link->name,name) != 0 )
-        link = link->next;
-
-    if( link != NULL )
-    {
-        link->data = data;
-        return;
-    }
-
-    /*
-    ** Create a new link.
-    */
-
-    link = (TIFFClientInfoLink *) _TIFFmalloc(sizeof(TIFFClientInfoLink));
-    assert (link != NULL);
-    link->next = tif->tif_clientinfo;
-    link->name = (char *) _TIFFmalloc((tmsize_t)(strlen(name)+1));
-    assert (link->name != NULL);
-    strcpy(link->name, name);
-    link->data = data;
-
-    tif->tif_clientinfo = link;
-}
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Header: /cvsroot/freeimage/FreeImage/Source/LibTIFF4/tif_extension.c,v 1.11 2015/02/19 22:39:58 drolon Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and 
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
+ * 
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Various routines support external extension of the tag set, and other
+ * application extension capabilities. 
+ */
+
+#include "tiffiop.h"
+
+int TIFFGetTagListCount( TIFF *tif )
+
+{
+    TIFFDirectory* td = &tif->tif_dir;
+    
+    return td->td_customValueCount;
+}
+
+uint32 TIFFGetTagListEntry( TIFF *tif, int tag_index )
+
+{
+    TIFFDirectory* td = &tif->tif_dir;
+
+    if( tag_index < 0 || tag_index >= td->td_customValueCount )
+        return (uint32)(-1);
+    else
+        return td->td_customValues[tag_index].info->field_tag;
+}
+
+/*
+** This provides read/write access to the TIFFTagMethods within the TIFF
+** structure to application code without giving access to the private
+** TIFF structure.
+*/
+TIFFTagMethods *TIFFAccessTagMethods( TIFF *tif )
+
+{
+    return &(tif->tif_tagmethods);
+}
+
+void *TIFFGetClientInfo( TIFF *tif, const char *name )
+
+{
+    TIFFClientInfoLink *link = tif->tif_clientinfo;
+
+    while( link != NULL && strcmp(link->name,name) != 0 )
+        link = link->next;
+
+    if( link != NULL )
+        return link->data;
+    else
+        return NULL;
+}
+
+void TIFFSetClientInfo( TIFF *tif, void *data, const char *name )
+
+{
+    TIFFClientInfoLink *link = tif->tif_clientinfo;
+
+    /*
+    ** Do we have an existing link with this name?  If so, just
+    ** set it.
+    */
+    while( link != NULL && strcmp(link->name,name) != 0 )
+        link = link->next;
+
+    if( link != NULL )
+    {
+        link->data = data;
+        return;
+    }
+
+    /*
+    ** Create a new link.
+    */
+
+    link = (TIFFClientInfoLink *) _TIFFmalloc(sizeof(TIFFClientInfoLink));
+    assert (link != NULL);
+    link->next = tif->tif_clientinfo;
+    link->name = (char *) _TIFFmalloc((tmsize_t)(strlen(name)+1));
+    assert (link->name != NULL);
+    strcpy(link->name, name);
+    link->data = data;
+
+    tif->tif_clientinfo = link;
+}
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tif_fax3.c b/Source/LibTIFF4/tif_fax3.c
index 496b10f..afa418c 100644
--- a/Source/LibTIFF4/tif_fax3.c
+++ b/Source/LibTIFF4/tif_fax3.c
@@ -1,1595 +1,1595 @@
-/* $Id: tif_fax3.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * Copyright (c) 1990-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-#include "tiffiop.h"
-#ifdef CCITT_SUPPORT
-/*
- * TIFF Library.
- *
- * CCITT Group 3 (T.4) and Group 4 (T.6) Compression Support.
- *
- * This file contains support for decoding and encoding TIFF
- * compression algorithms 2, 3, 4, and 32771.
- *
- * Decoder support is derived, with permission, from the code
- * in Frank Cringle's viewfax program;
- *      Copyright (C) 1990, 1995  Frank D. Cringle.
- */
-#include "tif_fax3.h"
-#define	G3CODES
-#include "t4.h"
-#include <stdio.h>
-
-/*
- * Compression+decompression state blocks are
- * derived from this ``base state'' block.
- */
-typedef struct {
-	int      rw_mode;                /* O_RDONLY for decode, else encode */
-	int      mode;                   /* operating mode */
-	tmsize_t rowbytes;               /* bytes in a decoded scanline */
-	uint32   rowpixels;              /* pixels in a scanline */
-
-	uint16   cleanfaxdata;           /* CleanFaxData tag */
-	uint32   badfaxrun;              /* BadFaxRun tag */
-	uint32   badfaxlines;            /* BadFaxLines tag */
-	uint32   groupoptions;           /* Group 3/4 options tag */
-
-	TIFFVGetMethod  vgetparent;      /* super-class method */
-	TIFFVSetMethod  vsetparent;      /* super-class method */
-	TIFFPrintMethod printdir;        /* super-class method */
-} Fax3BaseState;
-#define	Fax3State(tif)		((Fax3BaseState*) (tif)->tif_data)
-
-typedef enum { G3_1D, G3_2D } Ttag;
-typedef struct {
-	Fax3BaseState b;
-
-	/* Decoder state info */
-	const unsigned char* bitmap;	/* bit reversal table */
-	uint32	data;			/* current i/o byte/word */
-	int	bit;			/* current i/o bit in byte */
-	int	EOLcnt;			/* count of EOL codes recognized */
-	TIFFFaxFillFunc fill;		/* fill routine */
-	uint32*	runs;			/* b&w runs for current/previous row */
-	uint32*	refruns;		/* runs for reference line */
-	uint32*	curruns;		/* runs for current line */
-
-	/* Encoder state info */
-	Ttag    tag;			/* encoding state */
-	unsigned char*	refline;	/* reference line for 2d decoding */
-	int	k;			/* #rows left that can be 2d encoded */
-	int	maxk;			/* max #rows that can be 2d encoded */
-
-	int line;
-} Fax3CodecState;
-#define DecoderState(tif) ((Fax3CodecState*) Fax3State(tif))
-#define EncoderState(tif) ((Fax3CodecState*) Fax3State(tif))
-
-#define is2DEncoding(sp) (sp->b.groupoptions & GROUP3OPT_2DENCODING)
-#define isAligned(p,t) ((((size_t)(p)) & (sizeof (t)-1)) == 0)
-
-/*
- * Group 3 and Group 4 Decoding.
- */
-
-/*
- * These macros glue the TIFF library state to
- * the state expected by Frank's decoder.
- */
-#define	DECLARE_STATE(tif, sp, mod)					\
-    static const char module[] = mod;					\
-    Fax3CodecState* sp = DecoderState(tif);				\
-    int a0;				/* reference element */		\
-    int lastx = sp->b.rowpixels;	/* last element in row */	\
-    uint32 BitAcc;			/* bit accumulator */		\
-    int BitsAvail;			/* # valid bits in BitAcc */	\
-    int RunLength;			/* length of current run */	\
-    unsigned char* cp;			/* next byte of input data */	\
-    unsigned char* ep;			/* end of input data */		\
-    uint32* pa;				/* place to stuff next run */	\
-    uint32* thisrun;			/* current row's run array */	\
-    int EOLcnt;				/* # EOL codes recognized */	\
-    const unsigned char* bitmap = sp->bitmap;	/* input data bit reverser */	\
-    const TIFFFaxTabEnt* TabEnt
-#define	DECLARE_STATE_2D(tif, sp, mod)					\
-    DECLARE_STATE(tif, sp, mod);					\
-    int b1;				/* next change on prev line */	\
-    uint32* pb				/* next run in reference line */\
-/*
- * Load any state that may be changed during decoding.
- */
-#define	CACHE_STATE(tif, sp) do {					\
-    BitAcc = sp->data;							\
-    BitsAvail = sp->bit;						\
-    EOLcnt = sp->EOLcnt;						\
-    cp = (unsigned char*) tif->tif_rawcp;				\
-    ep = cp + tif->tif_rawcc;						\
-} while (0)
-/*
- * Save state possibly changed during decoding.
- */
-#define	UNCACHE_STATE(tif, sp) do {					\
-    sp->bit = BitsAvail;						\
-    sp->data = BitAcc;							\
-    sp->EOLcnt = EOLcnt;						\
-    tif->tif_rawcc -= (tmsize_t)((uint8*) cp - tif->tif_rawcp);		\
-    tif->tif_rawcp = (uint8*) cp;					\
-} while (0)
-
-/*
- * Setup state for decoding a strip.
- */
-static int
-Fax3PreDecode(TIFF* tif, uint16 s)
-{
-	Fax3CodecState* sp = DecoderState(tif);
-
-	(void) s;
-	assert(sp != NULL);
-	sp->bit = 0;			/* force initial read */
-	sp->data = 0;
-	sp->EOLcnt = 0;			/* force initial scan for EOL */
-	/*
-	 * Decoder assumes lsb-to-msb bit order.  Note that we select
-	 * this here rather than in Fax3SetupState so that viewers can
-	 * hold the image open, fiddle with the FillOrder tag value,
-	 * and then re-decode the image.  Otherwise they'd need to close
-	 * and open the image to get the state reset.
-	 */
-	sp->bitmap =
-	    TIFFGetBitRevTable(tif->tif_dir.td_fillorder != FILLORDER_LSB2MSB);
-	if (sp->refruns) {		/* init reference line to white */
-		sp->refruns[0] = (uint32) sp->b.rowpixels;
-		sp->refruns[1] = 0;
-	}
-	sp->line = 0;
-	return (1);
-}
-
-/*
- * Routine for handling various errors/conditions.
- * Note how they are "glued into the decoder" by
- * overriding the definitions used by the decoder.
- */
-
-static void
-Fax3Unexpected(const char* module, TIFF* tif, uint32 line, uint32 a0)
-{
-	TIFFErrorExt(tif->tif_clientdata, module, "Bad code word at line %u of %s %u (x %u)",
-	    line, isTiled(tif) ? "tile" : "strip",
-	    (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip),
-	    a0);
-}
-#define	unexpected(table, a0)	Fax3Unexpected(module, tif, sp->line, a0)
-
-static void
-Fax3Extension(const char* module, TIFF* tif, uint32 line, uint32 a0)
-{
-	TIFFErrorExt(tif->tif_clientdata, module,
-	    "Uncompressed data (not supported) at line %u of %s %u (x %u)",
-	    line, isTiled(tif) ? "tile" : "strip",
-	    (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip),
-	    a0);
-}
-#define	extension(a0)	Fax3Extension(module, tif, sp->line, a0)
-
-static void
-Fax3BadLength(const char* module, TIFF* tif, uint32 line, uint32 a0, uint32 lastx)
-{
-	TIFFWarningExt(tif->tif_clientdata, module, "%s at line %u of %s %u (got %u, expected %u)",
-	    a0 < lastx ? "Premature EOL" : "Line length mismatch",
-	    line, isTiled(tif) ? "tile" : "strip",
-	    (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip),
-	    a0, lastx);
-}
-#define	badlength(a0,lastx)	Fax3BadLength(module, tif, sp->line, a0, lastx)
-
-static void
-Fax3PrematureEOF(const char* module, TIFF* tif, uint32 line, uint32 a0)
-{
-	TIFFWarningExt(tif->tif_clientdata, module, "Premature EOF at line %u of %s %u (x %u)",
-	    line, isTiled(tif) ? "tile" : "strip",
-	    (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip),
-	    a0);
-}
-#define	prematureEOF(a0)	Fax3PrematureEOF(module, tif, sp->line, a0)
-
-#define	Nop
-
-/*
- * Decode the requested amount of G3 1D-encoded data.
- */
-static int
-Fax3Decode1D(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s)
-{
-	DECLARE_STATE(tif, sp, "Fax3Decode1D");
-	(void) s;
-	if (occ % sp->b.rowbytes)
-	{
-		TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read");
-		return (-1);
-	}
-	CACHE_STATE(tif, sp);
-	thisrun = sp->curruns;
-	while (occ > 0) {
-		a0 = 0;
-		RunLength = 0;
-		pa = thisrun;
-#ifdef FAX3_DEBUG
-		printf("\nBitAcc=%08X, BitsAvail = %d\n", BitAcc, BitsAvail);
-		printf("-------------------- %d\n", tif->tif_row);
-		fflush(stdout);
-#endif
-		SYNC_EOL(EOF1D);
-		EXPAND1D(EOF1Da);
-		(*sp->fill)(buf, thisrun, pa, lastx);
-		buf += sp->b.rowbytes;
-		occ -= sp->b.rowbytes;
-		sp->line++;
-		continue;
-	EOF1D:				/* premature EOF */
-		CLEANUP_RUNS();
-	EOF1Da:				/* premature EOF */
-		(*sp->fill)(buf, thisrun, pa, lastx);
-		UNCACHE_STATE(tif, sp);
-		return (-1);
-	}
-	UNCACHE_STATE(tif, sp);
-	return (1);
-}
-
-#define	SWAP(t,a,b)	{ t x; x = (a); (a) = (b); (b) = x; }
-/*
- * Decode the requested amount of G3 2D-encoded data.
- */
-static int
-Fax3Decode2D(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s)
-{
-	DECLARE_STATE_2D(tif, sp, "Fax3Decode2D");
-	int is1D;			/* current line is 1d/2d-encoded */
-	(void) s;
-	if (occ % sp->b.rowbytes)
-	{
-		TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read");
-		return (-1);
-	}
-	CACHE_STATE(tif, sp);
-	while (occ > 0) {
-		a0 = 0;
-		RunLength = 0;
-		pa = thisrun = sp->curruns;
-#ifdef FAX3_DEBUG
-		printf("\nBitAcc=%08X, BitsAvail = %d EOLcnt = %d",
-		    BitAcc, BitsAvail, EOLcnt);
-#endif
-		SYNC_EOL(EOF2D);
-		NeedBits8(1, EOF2D);
-		is1D = GetBits(1);	/* 1D/2D-encoding tag bit */
-		ClrBits(1);
-#ifdef FAX3_DEBUG
-		printf(" %s\n-------------------- %d\n",
-		    is1D ? "1D" : "2D", tif->tif_row);
-		fflush(stdout);
-#endif
-		pb = sp->refruns;
-		b1 = *pb++;
-		if (is1D)
-			EXPAND1D(EOF2Da);
-		else
-			EXPAND2D(EOF2Da);
-		(*sp->fill)(buf, thisrun, pa, lastx);
-		SETVALUE(0);		/* imaginary change for reference */
-		SWAP(uint32*, sp->curruns, sp->refruns);
-		buf += sp->b.rowbytes;
-		occ -= sp->b.rowbytes;
-		sp->line++;
-		continue;
-	EOF2D:				/* premature EOF */
-		CLEANUP_RUNS();
-	EOF2Da:				/* premature EOF */
-		(*sp->fill)(buf, thisrun, pa, lastx);
-		UNCACHE_STATE(tif, sp);
-		return (-1);
-	}
-	UNCACHE_STATE(tif, sp);
-	return (1);
-}
-#undef SWAP
-
-/*
- * The ZERO & FILL macros must handle spans < 2*sizeof(long) bytes.
- * For machines with 64-bit longs this is <16 bytes; otherwise
- * this is <8 bytes.  We optimize the code here to reflect the
- * machine characteristics.
- */
-#if SIZEOF_UNSIGNED_LONG == 8
-# define FILL(n, cp)							    \
-    switch (n) {							    \
-    case 15:(cp)[14] = 0xff; case 14:(cp)[13] = 0xff; case 13: (cp)[12] = 0xff;\
-    case 12:(cp)[11] = 0xff; case 11:(cp)[10] = 0xff; case 10: (cp)[9] = 0xff;\
-    case  9: (cp)[8] = 0xff; case  8: (cp)[7] = 0xff; case  7: (cp)[6] = 0xff;\
-    case  6: (cp)[5] = 0xff; case  5: (cp)[4] = 0xff; case  4: (cp)[3] = 0xff;\
-    case  3: (cp)[2] = 0xff; case  2: (cp)[1] = 0xff;			      \
-    case  1: (cp)[0] = 0xff; (cp) += (n); case 0:  ;			      \
-    }
-# define ZERO(n, cp)							\
-    switch (n) {							\
-    case 15:(cp)[14] = 0; case 14:(cp)[13] = 0; case 13: (cp)[12] = 0;	\
-    case 12:(cp)[11] = 0; case 11:(cp)[10] = 0; case 10: (cp)[9] = 0;	\
-    case  9: (cp)[8] = 0; case  8: (cp)[7] = 0; case  7: (cp)[6] = 0;	\
-    case  6: (cp)[5] = 0; case  5: (cp)[4] = 0; case  4: (cp)[3] = 0;	\
-    case  3: (cp)[2] = 0; case  2: (cp)[1] = 0;				\
-    case  1: (cp)[0] = 0; (cp) += (n); case 0:  ;			\
-    }
-#else
-# define FILL(n, cp)							    \
-    switch (n) {							    \
-    case 7: (cp)[6] = 0xff; case 6: (cp)[5] = 0xff; case 5: (cp)[4] = 0xff; \
-    case 4: (cp)[3] = 0xff; case 3: (cp)[2] = 0xff; case 2: (cp)[1] = 0xff; \
-    case 1: (cp)[0] = 0xff; (cp) += (n); case 0:  ;			    \
-    }
-# define ZERO(n, cp)							\
-    switch (n) {							\
-    case 7: (cp)[6] = 0; case 6: (cp)[5] = 0; case 5: (cp)[4] = 0;	\
-    case 4: (cp)[3] = 0; case 3: (cp)[2] = 0; case 2: (cp)[1] = 0;	\
-    case 1: (cp)[0] = 0; (cp) += (n); case 0:  ;			\
-    }
-#endif
-
-/*
- * Bit-fill a row according to the white/black
- * runs generated during G3/G4 decoding.
- */
-void
-_TIFFFax3fillruns(unsigned char* buf, uint32* runs, uint32* erun, uint32 lastx)
-{
-	static const unsigned char _fillmasks[] =
-	    { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };
-	unsigned char* cp;
-	uint32 x, bx, run;
-	int32 n, nw;
-	long* lp;
-
-	if ((erun-runs)&1)
-	    *erun++ = 0;
-	x = 0;
-	for (; runs < erun; runs += 2) {
-	    run = runs[0];
-	    if (x+run > lastx || run > lastx )
-		run = runs[0] = (uint32) (lastx - x);
-	    if (run) {
-		cp = buf + (x>>3);
-		bx = x&7;
-		if (run > 8-bx) {
-		    if (bx) {			/* align to byte boundary */
-			*cp++ &= 0xff << (8-bx);
-			run -= 8-bx;
-		    }
-		    if( (n = run >> 3) != 0 ) {	/* multiple bytes to fill */
-			if ((n/sizeof (long)) > 1) {
-			    /*
-			     * Align to longword boundary and fill.
-			     */
-			    for (; n && !isAligned(cp, long); n--)
-				    *cp++ = 0x00;
-			    lp = (long*) cp;
-			    nw = (int32)(n / sizeof (long));
-			    n -= nw * sizeof (long);
-			    do {
-				    *lp++ = 0L;
-			    } while (--nw);
-			    cp = (unsigned char*) lp;
-			}
-			ZERO(n, cp);
-			run &= 7;
-		    }
-		    if (run)
-			cp[0] &= 0xff >> run;
-		} else
-		    cp[0] &= ~(_fillmasks[run]>>bx);
-		x += runs[0];
-	    }
-	    run = runs[1];
-	    if (x+run > lastx || run > lastx )
-		run = runs[1] = lastx - x;
-	    if (run) {
-		cp = buf + (x>>3);
-		bx = x&7;
-		if (run > 8-bx) {
-		    if (bx) {			/* align to byte boundary */
-			*cp++ |= 0xff >> bx;
-			run -= 8-bx;
-		    }
-		    if( (n = run>>3) != 0 ) {	/* multiple bytes to fill */
-			if ((n/sizeof (long)) > 1) {
-			    /*
-			     * Align to longword boundary and fill.
-			     */
-			    for (; n && !isAligned(cp, long); n--)
-				*cp++ = 0xff;
-			    lp = (long*) cp;
-			    nw = (int32)(n / sizeof (long));
-			    n -= nw * sizeof (long);
-			    do {
-				*lp++ = -1L;
-			    } while (--nw);
-			    cp = (unsigned char*) lp;
-			}
-			FILL(n, cp);
-			run &= 7;
-		    }
-		    if (run)
-			cp[0] |= 0xff00 >> run;
-		} else
-		    cp[0] |= _fillmasks[run]>>bx;
-		x += runs[1];
-	    }
-	}
-	assert(x == lastx);
-}
-#undef	ZERO
-#undef	FILL
-
-static int
-Fax3FixupTags(TIFF* tif)
-{
-	(void) tif;
-	return (1);
-}
-
-/*
- * Setup G3/G4-related compression/decompression state
- * before data is processed.  This routine is called once
- * per image -- it sets up different state based on whether
- * or not decoding or encoding is being done and whether
- * 1D- or 2D-encoded data is involved.
- */
-static int
-Fax3SetupState(TIFF* tif)
-{
-	static const char module[] = "Fax3SetupState";
-	TIFFDirectory* td = &tif->tif_dir;
-	Fax3BaseState* sp = Fax3State(tif);
-	int needsRefLine;
-	Fax3CodecState* dsp = (Fax3CodecState*) Fax3State(tif);
-	tmsize_t rowbytes;
-	uint32 rowpixels, nruns;
-
-	if (td->td_bitspersample != 1) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-		    "Bits/sample must be 1 for Group 3/4 encoding/decoding");
-		return (0);
-	}
-	/*
-	 * Calculate the scanline/tile widths.
-	 */
-	if (isTiled(tif)) {
-		rowbytes = TIFFTileRowSize(tif);
-		rowpixels = td->td_tilewidth;
-	} else {
-		rowbytes = TIFFScanlineSize(tif);
-		rowpixels = td->td_imagewidth;
-	}
-	sp->rowbytes = rowbytes;
-	sp->rowpixels = rowpixels;
-	/*
-	 * Allocate any additional space required for decoding/encoding.
-	 */
-	needsRefLine = (
-	    (sp->groupoptions & GROUP3OPT_2DENCODING) ||
-	    td->td_compression == COMPRESSION_CCITTFAX4
-	);
-
-	/*
-	  Assure that allocation computations do not overflow.
-	  
-	  TIFFroundup and TIFFSafeMultiply return zero on integer overflow
-	*/
-	dsp->runs=(uint32*) NULL;
-	nruns = TIFFroundup_32(rowpixels,32);
-	if (needsRefLine) {
-		nruns = TIFFSafeMultiply(uint32,nruns,2);
-	}
-	if ((nruns == 0) || (TIFFSafeMultiply(uint32,nruns,2) == 0)) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			     "Row pixels integer overflow (rowpixels %u)",
-			     rowpixels);
-		return (0);
-	}
-	dsp->runs = (uint32*) _TIFFCheckMalloc(tif,
-					       TIFFSafeMultiply(uint32,nruns,2),
-					       sizeof (uint32),
-					       "for Group 3/4 run arrays");
-	if (dsp->runs == NULL)
-		return (0);
-	memset( dsp->runs, 0, TIFFSafeMultiply(uint32,nruns,2)*sizeof(uint32));
-	dsp->curruns = dsp->runs;
-	if (needsRefLine)
-		dsp->refruns = dsp->runs + nruns;
-	else
-		dsp->refruns = NULL;
-	if (td->td_compression == COMPRESSION_CCITTFAX3
-	    && is2DEncoding(dsp)) {	/* NB: default is 1D routine */
-		tif->tif_decoderow = Fax3Decode2D;
-		tif->tif_decodestrip = Fax3Decode2D;
-		tif->tif_decodetile = Fax3Decode2D;
-	}
-
-	if (needsRefLine) {		/* 2d encoding */
-		Fax3CodecState* esp = EncoderState(tif);
-		/*
-		 * 2d encoding requires a scanline
-		 * buffer for the ``reference line''; the
-		 * scanline against which delta encoding
-		 * is referenced.  The reference line must
-		 * be initialized to be ``white'' (done elsewhere).
-		 */
-		esp->refline = (unsigned char*) _TIFFmalloc(rowbytes);
-		if (esp->refline == NULL) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-			    "No space for Group 3/4 reference line");
-			return (0);
-		}
-	} else					/* 1d encoding */
-		EncoderState(tif)->refline = NULL;
-
-	return (1);
-}
-
-/*
- * CCITT Group 3 FAX Encoding.
- */
-
-#define	Fax3FlushBits(tif, sp) {				\
-	if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize)		\
-		(void) TIFFFlushData1(tif);			\
-	*(tif)->tif_rawcp++ = (uint8) (sp)->data;		\
-	(tif)->tif_rawcc++;					\
-	(sp)->data = 0, (sp)->bit = 8;				\
-}
-#define	_FlushBits(tif) {					\
-	if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize)		\
-		(void) TIFFFlushData1(tif);			\
-	*(tif)->tif_rawcp++ = (uint8) data;		\
-	(tif)->tif_rawcc++;					\
-	data = 0, bit = 8;					\
-}
-static const int _msbmask[9] =
-    { 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
-#define	_PutBits(tif, bits, length) {				\
-	while (length > bit) {					\
-		data |= bits >> (length - bit);			\
-		length -= bit;					\
-		_FlushBits(tif);				\
-	}							\
-        assert( length < 9 );                                   \
-	data |= (bits & _msbmask[length]) << (bit - length);	\
-	bit -= length;						\
-	if (bit == 0)						\
-		_FlushBits(tif);				\
-}
-	
-/*
- * Write a variable-length bit-value to
- * the output stream.  Values are
- * assumed to be at most 16 bits.
- */
-static void
-Fax3PutBits(TIFF* tif, unsigned int bits, unsigned int length)
-{
-	Fax3CodecState* sp = EncoderState(tif);
-	unsigned int bit = sp->bit;
-	int data = sp->data;
-
-	_PutBits(tif, bits, length);
-
-	sp->data = data;
-	sp->bit = bit;
-}
-
-/*
- * Write a code to the output stream.
- */
-#define putcode(tif, te)	Fax3PutBits(tif, (te)->code, (te)->length)
-
-#ifdef FAX3_DEBUG
-#define	DEBUG_COLOR(w) (tab == TIFFFaxWhiteCodes ? w "W" : w "B")
-#define	DEBUG_PRINT(what,len) {						\
-    int t;								\
-    printf("%08X/%-2d: %s%5d\t", data, bit, DEBUG_COLOR(what), len);	\
-    for (t = length-1; t >= 0; t--)					\
-	putchar(code & (1<<t) ? '1' : '0');				\
-    putchar('\n');							\
-}
-#endif
-
-/*
- * Write the sequence of codes that describes
- * the specified span of zero's or one's.  The
- * appropriate table that holds the make-up and
- * terminating codes is supplied.
- */
-static void
-putspan(TIFF* tif, int32 span, const tableentry* tab)
-{
-	Fax3CodecState* sp = EncoderState(tif);
-	unsigned int bit = sp->bit;
-	int data = sp->data;
-	unsigned int code, length;
-
-	while (span >= 2624) {
-		const tableentry* te = &tab[63 + (2560>>6)];
-		code = te->code, length = te->length;
-#ifdef FAX3_DEBUG
-		DEBUG_PRINT("MakeUp", te->runlen);
-#endif
-		_PutBits(tif, code, length);
-		span -= te->runlen;
-	}
-	if (span >= 64) {
-		const tableentry* te = &tab[63 + (span>>6)];
-		assert(te->runlen == 64*(span>>6));
-		code = te->code, length = te->length;
-#ifdef FAX3_DEBUG
-		DEBUG_PRINT("MakeUp", te->runlen);
-#endif
-		_PutBits(tif, code, length);
-		span -= te->runlen;
-	}
-	code = tab[span].code, length = tab[span].length;
-#ifdef FAX3_DEBUG
-	DEBUG_PRINT("  Term", tab[span].runlen);
-#endif
-	_PutBits(tif, code, length);
-
-	sp->data = data;
-	sp->bit = bit;
-}
-
-/*
- * Write an EOL code to the output stream.  The zero-fill
- * logic for byte-aligning encoded scanlines is handled
- * here.  We also handle writing the tag bit for the next
- * scanline when doing 2d encoding.
- */
-static void
-Fax3PutEOL(TIFF* tif)
-{
-	Fax3CodecState* sp = EncoderState(tif);
-	unsigned int bit = sp->bit;
-	int data = sp->data;
-	unsigned int code, length, tparm;
-
-	if (sp->b.groupoptions & GROUP3OPT_FILLBITS) {
-		/*
-		 * Force bit alignment so EOL will terminate on
-		 * a byte boundary.  That is, force the bit alignment
-		 * to 16-12 = 4 before putting out the EOL code.
-		 */
-		int align = 8 - 4;
-		if (align != sp->bit) {
-			if (align > sp->bit)
-				align = sp->bit + (8 - align);
-			else
-				align = sp->bit - align;
-			code = 0;
-			tparm=align; 
-			_PutBits(tif, 0, tparm);
-		}
-	}
-	code = EOL, length = 12;
-	if (is2DEncoding(sp))
-		code = (code<<1) | (sp->tag == G3_1D), length++;
-	_PutBits(tif, code, length);
-
-	sp->data = data;
-	sp->bit = bit;
-}
-
-/*
- * Reset encoding state at the start of a strip.
- */
-static int
-Fax3PreEncode(TIFF* tif, uint16 s)
-{
-	Fax3CodecState* sp = EncoderState(tif);
-
-	(void) s;
-	assert(sp != NULL);
-	sp->bit = 8;
-	sp->data = 0;
-	sp->tag = G3_1D;
-	/*
-	 * This is necessary for Group 4; otherwise it isn't
-	 * needed because the first scanline of each strip ends
-	 * up being copied into the refline.
-	 */
-	if (sp->refline)
-		_TIFFmemset(sp->refline, 0x00, sp->b.rowbytes);
-	if (is2DEncoding(sp)) {
-		float res = tif->tif_dir.td_yresolution;
-		/*
-		 * The CCITT spec says that when doing 2d encoding, you
-		 * should only do it on K consecutive scanlines, where K
-		 * depends on the resolution of the image being encoded
-		 * (2 for <= 200 lpi, 4 for > 200 lpi).  Since the directory
-		 * code initializes td_yresolution to 0, this code will
-		 * select a K of 2 unless the YResolution tag is set
-		 * appropriately.  (Note also that we fudge a little here
-		 * and use 150 lpi to avoid problems with units conversion.)
-		 */
-		if (tif->tif_dir.td_resolutionunit == RESUNIT_CENTIMETER)
-			res *= 2.54f;		/* convert to inches */
-		sp->maxk = (res > 150 ? 4 : 2);
-		sp->k = sp->maxk-1;
-	} else
-		sp->k = sp->maxk = 0;
-	sp->line = 0;
-	return (1);
-}
-
-static const unsigned char zeroruns[256] = {
-    8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,	/* 0x00 - 0x0f */
-    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,	/* 0x10 - 0x1f */
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,	/* 0x20 - 0x2f */
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,	/* 0x30 - 0x3f */
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0x40 - 0x4f */
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0x50 - 0x5f */
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0x60 - 0x6f */
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0x70 - 0x7f */
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x80 - 0x8f */
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x90 - 0x9f */
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0xa0 - 0xaf */
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0xb0 - 0xbf */
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0xc0 - 0xcf */
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0xd0 - 0xdf */
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0xe0 - 0xef */
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0xf0 - 0xff */
-};
-static const unsigned char oneruns[256] = {
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x00 - 0x0f */
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x10 - 0x1f */
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x20 - 0x2f */
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x30 - 0x3f */
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x40 - 0x4f */
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x50 - 0x5f */
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x60 - 0x6f */
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x70 - 0x7f */
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0x80 - 0x8f */
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0x90 - 0x9f */
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0xa0 - 0xaf */
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0xb0 - 0xbf */
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,	/* 0xc0 - 0xcf */
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,	/* 0xd0 - 0xdf */
-    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,	/* 0xe0 - 0xef */
-    4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8,	/* 0xf0 - 0xff */
-};
-
-/*
- * On certain systems it pays to inline
- * the routines that find pixel spans.
- */
-#ifdef VAXC
-static	int32 find0span(unsigned char*, int32, int32);
-static	int32 find1span(unsigned char*, int32, int32);
-#pragma inline(find0span,find1span)
-#endif
-
-/*
- * Find a span of ones or zeros using the supplied
- * table.  The ``base'' of the bit string is supplied
- * along with the start+end bit indices.
- */
-inline static int32
-find0span(unsigned char* bp, int32 bs, int32 be)
-{
-	int32 bits = be - bs;
-	int32 n, span;
-
-	bp += bs>>3;
-	/*
-	 * Check partial byte on lhs.
-	 */
-	if (bits > 0 && (n = (bs & 7))) {
-		span = zeroruns[(*bp << n) & 0xff];
-		if (span > 8-n)		/* table value too generous */
-			span = 8-n;
-		if (span > bits)	/* constrain span to bit range */
-			span = bits;
-		if (n+span < 8)		/* doesn't extend to edge of byte */
-			return (span);
-		bits -= span;
-		bp++;
-	} else
-		span = 0;
-	if (bits >= (int32)(2 * 8 * sizeof(long))) {
-		long* lp;
-		/*
-		 * Align to longword boundary and check longwords.
-		 */
-		while (!isAligned(bp, long)) {
-			if (*bp != 0x00)
-				return (span + zeroruns[*bp]);
-			span += 8, bits -= 8;
-			bp++;
-		}
-		lp = (long*) bp;
-		while ((bits >= (int32)(8 * sizeof(long))) && (0 == *lp)) {
-			span += 8*sizeof (long), bits -= 8*sizeof (long);
-			lp++;
-		}
-		bp = (unsigned char*) lp;
-	}
-	/*
-	 * Scan full bytes for all 0's.
-	 */
-	while (bits >= 8) {
-		if (*bp != 0x00)	/* end of run */
-			return (span + zeroruns[*bp]);
-		span += 8, bits -= 8;
-		bp++;
-	}
-	/*
-	 * Check partial byte on rhs.
-	 */
-	if (bits > 0) {
-		n = zeroruns[*bp];
-		span += (n > bits ? bits : n);
-	}
-	return (span);
-}
-
-inline static int32
-find1span(unsigned char* bp, int32 bs, int32 be)
-{
-	int32 bits = be - bs;
-	int32 n, span;
-
-	bp += bs>>3;
-	/*
-	 * Check partial byte on lhs.
-	 */
-	if (bits > 0 && (n = (bs & 7))) {
-		span = oneruns[(*bp << n) & 0xff];
-		if (span > 8-n)		/* table value too generous */
-			span = 8-n;
-		if (span > bits)	/* constrain span to bit range */
-			span = bits;
-		if (n+span < 8)		/* doesn't extend to edge of byte */
-			return (span);
-		bits -= span;
-		bp++;
-	} else
-		span = 0;
-	if (bits >= (int32)(2 * 8 * sizeof(long))) {
-		long* lp;
-		/*
-		 * Align to longword boundary and check longwords.
-		 */
-		while (!isAligned(bp, long)) {
-			if (*bp != 0xff)
-				return (span + oneruns[*bp]);
-			span += 8, bits -= 8;
-			bp++;
-		}
-		lp = (long*) bp;
-		while ((bits >= (int32)(8 * sizeof(long))) && (~0 == *lp)) {
-			span += 8*sizeof (long), bits -= 8*sizeof (long);
-			lp++;
-		}
-		bp = (unsigned char*) lp;
-	}
-	/*
-	 * Scan full bytes for all 1's.
-	 */
-	while (bits >= 8) {
-		if (*bp != 0xff)	/* end of run */
-			return (span + oneruns[*bp]);
-		span += 8, bits -= 8;
-		bp++;
-	}
-	/*
-	 * Check partial byte on rhs.
-	 */
-	if (bits > 0) {
-		n = oneruns[*bp];
-		span += (n > bits ? bits : n);
-	}
-	return (span);
-}
-
-/*
- * Return the offset of the next bit in the range
- * [bs..be] that is different from the specified
- * color.  The end, be, is returned if no such bit
- * exists.
- */
-#define	finddiff(_cp, _bs, _be, _color)	\
-	(_bs + (_color ? find1span(_cp,_bs,_be) : find0span(_cp,_bs,_be)))
-/*
- * Like finddiff, but also check the starting bit
- * against the end in case start > end.
- */
-#define	finddiff2(_cp, _bs, _be, _color) \
-	(_bs < _be ? finddiff(_cp,_bs,_be,_color) : _be)
-
-/*
- * 1d-encode a row of pixels.  The encoding is
- * a sequence of all-white or all-black spans
- * of pixels encoded with Huffman codes.
- */
-static int
-Fax3Encode1DRow(TIFF* tif, unsigned char* bp, uint32 bits)
-{
-	Fax3CodecState* sp = EncoderState(tif);
-	int32 span;
-        uint32 bs = 0;
-
-	for (;;) {
-		span = find0span(bp, bs, bits);		/* white span */
-		putspan(tif, span, TIFFFaxWhiteCodes);
-		bs += span;
-		if (bs >= bits)
-			break;
-		span = find1span(bp, bs, bits);		/* black span */
-		putspan(tif, span, TIFFFaxBlackCodes);
-		bs += span;
-		if (bs >= bits)
-			break;
-	}
-	if (sp->b.mode & (FAXMODE_BYTEALIGN|FAXMODE_WORDALIGN)) {
-		if (sp->bit != 8)			/* byte-align */
-			Fax3FlushBits(tif, sp);
-		if ((sp->b.mode&FAXMODE_WORDALIGN) &&
-		    !isAligned(tif->tif_rawcp, uint16))
-			Fax3FlushBits(tif, sp);
-	}
-	return (1);
-}
-
-static const tableentry horizcode =
-    { 3, 0x1, 0 };	/* 001 */
-static const tableentry passcode =
-    { 4, 0x1, 0 };	/* 0001 */
-static const tableentry vcodes[7] = {
-    { 7, 0x03, 0 },	/* 0000 011 */
-    { 6, 0x03, 0 },	/* 0000 11 */
-    { 3, 0x03, 0 },	/* 011 */
-    { 1, 0x1, 0 },	/* 1 */
-    { 3, 0x2, 0 },	/* 010 */
-    { 6, 0x02, 0 },	/* 0000 10 */
-    { 7, 0x02, 0 }	/* 0000 010 */
-};
-
-/*
- * 2d-encode a row of pixels.  Consult the CCITT
- * documentation for the algorithm.
- */
-static int
-Fax3Encode2DRow(TIFF* tif, unsigned char* bp, unsigned char* rp, uint32 bits)
-{
-#define	PIXEL(buf,ix)	((((buf)[(ix)>>3]) >> (7-((ix)&7))) & 1)
-        uint32 a0 = 0;
-	uint32 a1 = (PIXEL(bp, 0) != 0 ? 0 : finddiff(bp, 0, bits, 0));
-	uint32 b1 = (PIXEL(rp, 0) != 0 ? 0 : finddiff(rp, 0, bits, 0));
-	uint32 a2, b2;
-
-	for (;;) {
-		b2 = finddiff2(rp, b1, bits, PIXEL(rp,b1));
-		if (b2 >= a1) {
-			int32 d = b1 - a1;
-			if (!(-3 <= d && d <= 3)) {	/* horizontal mode */
-				a2 = finddiff2(bp, a1, bits, PIXEL(bp,a1));
-				putcode(tif, &horizcode);
-				if (a0+a1 == 0 || PIXEL(bp, a0) == 0) {
-					putspan(tif, a1-a0, TIFFFaxWhiteCodes);
-					putspan(tif, a2-a1, TIFFFaxBlackCodes);
-				} else {
-					putspan(tif, a1-a0, TIFFFaxBlackCodes);
-					putspan(tif, a2-a1, TIFFFaxWhiteCodes);
-				}
-				a0 = a2;
-			} else {			/* vertical mode */
-				putcode(tif, &vcodes[d+3]);
-				a0 = a1;
-			}
-		} else {				/* pass mode */
-			putcode(tif, &passcode);
-			a0 = b2;
-		}
-		if (a0 >= bits)
-			break;
-		a1 = finddiff(bp, a0, bits, PIXEL(bp,a0));
-		b1 = finddiff(rp, a0, bits, !PIXEL(bp,a0));
-		b1 = finddiff(rp, b1, bits, PIXEL(bp,a0));
-	}
-	return (1);
-#undef PIXEL
-}
-
-/*
- * Encode a buffer of pixels.
- */
-static int
-Fax3Encode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
-{
-	static const char module[] = "Fax3Encode";
-	Fax3CodecState* sp = EncoderState(tif);
-	(void) s;
-	if (cc % sp->b.rowbytes)
-	{
-		TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be written");
-		return (0);
-	}
-	while (cc > 0) {
-		if ((sp->b.mode & FAXMODE_NOEOL) == 0)
-			Fax3PutEOL(tif);
-		if (is2DEncoding(sp)) {
-			if (sp->tag == G3_1D) {
-				if (!Fax3Encode1DRow(tif, bp, sp->b.rowpixels))
-					return (0);
-				sp->tag = G3_2D;
-			} else {
-				if (!Fax3Encode2DRow(tif, bp, sp->refline,
-				    sp->b.rowpixels))
-					return (0);
-				sp->k--;
-			}
-			if (sp->k == 0) {
-				sp->tag = G3_1D;
-				sp->k = sp->maxk-1;
-			} else
-				_TIFFmemcpy(sp->refline, bp, sp->b.rowbytes);
-		} else {
-			if (!Fax3Encode1DRow(tif, bp, sp->b.rowpixels))
-				return (0);
-		}
-		bp += sp->b.rowbytes;
-		cc -= sp->b.rowbytes;
-	}
-	return (1);
-}
-
-static int
-Fax3PostEncode(TIFF* tif)
-{
-	Fax3CodecState* sp = EncoderState(tif);
-
-	if (sp->bit != 8)
-		Fax3FlushBits(tif, sp);
-	return (1);
-}
-
-static void
-Fax3Close(TIFF* tif)
-{
-	if ((Fax3State(tif)->mode & FAXMODE_NORTC) == 0) {
-		Fax3CodecState* sp = EncoderState(tif);
-		unsigned int code = EOL;
-		unsigned int length = 12;
-		int i;
-
-		if (is2DEncoding(sp))
-			code = (code<<1) | (sp->tag == G3_1D), length++;
-		for (i = 0; i < 6; i++)
-			Fax3PutBits(tif, code, length);
-		Fax3FlushBits(tif, sp);
-	}
-}
-
-static void
-Fax3Cleanup(TIFF* tif)
-{
-	Fax3CodecState* sp = DecoderState(tif);
-	
-	assert(sp != 0);
-
-	tif->tif_tagmethods.vgetfield = sp->b.vgetparent;
-	tif->tif_tagmethods.vsetfield = sp->b.vsetparent;
-	tif->tif_tagmethods.printdir = sp->b.printdir;
-
-	if (sp->runs)
-		_TIFFfree(sp->runs);
-	if (sp->refline)
-		_TIFFfree(sp->refline);
-
-	_TIFFfree(tif->tif_data);
-	tif->tif_data = NULL;
-
-	_TIFFSetDefaultCompressionState(tif);
-}
-
-#define	FIELD_BADFAXLINES	(FIELD_CODEC+0)
-#define	FIELD_CLEANFAXDATA	(FIELD_CODEC+1)
-#define	FIELD_BADFAXRUN		(FIELD_CODEC+2)
-
-#define	FIELD_OPTIONS		(FIELD_CODEC+7)
-
-static const TIFFField faxFields[] = {
-    { TIFFTAG_FAXMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "FaxMode", NULL },
-    { TIFFTAG_FAXFILLFUNC, 0, 0, TIFF_ANY, 0, TIFF_SETGET_OTHER, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "FaxFillFunc", NULL },
-    { TIFFTAG_BADFAXLINES, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_BADFAXLINES, TRUE, FALSE, "BadFaxLines", NULL },
-    { TIFFTAG_CLEANFAXDATA, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UINT16, FIELD_CLEANFAXDATA, TRUE, FALSE, "CleanFaxData", NULL },
-    { TIFFTAG_CONSECUTIVEBADFAXLINES, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_BADFAXRUN, TRUE, FALSE, "ConsecutiveBadFaxLines", NULL }};
-static const TIFFField fax3Fields[] = {
-    { TIFFTAG_GROUP3OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_OPTIONS, FALSE, FALSE, "Group3Options", NULL },
-};
-static const TIFFField fax4Fields[] = {
-    { TIFFTAG_GROUP4OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_OPTIONS, FALSE, FALSE, "Group4Options", NULL },
-};
-
-static int
-Fax3VSetField(TIFF* tif, uint32 tag, va_list ap)
-{
-	Fax3BaseState* sp = Fax3State(tif);
-	const TIFFField* fip;
-
-	assert(sp != 0);
-	assert(sp->vsetparent != 0);
-
-	switch (tag) {
-	case TIFFTAG_FAXMODE:
-		sp->mode = (int) va_arg(ap, int);
-		return 1;			/* NB: pseudo tag */
-	case TIFFTAG_FAXFILLFUNC:
-		DecoderState(tif)->fill = va_arg(ap, TIFFFaxFillFunc);
-		return 1;			/* NB: pseudo tag */
-	case TIFFTAG_GROUP3OPTIONS:
-		/* XXX: avoid reading options if compression mismatches. */
-		if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX3)
-			sp->groupoptions = (uint32) va_arg(ap, uint32);
-		break;
-	case TIFFTAG_GROUP4OPTIONS:
-		/* XXX: avoid reading options if compression mismatches. */
-		if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4)
-			sp->groupoptions = (uint32) va_arg(ap, uint32);
-		break;
-	case TIFFTAG_BADFAXLINES:
-		sp->badfaxlines = (uint32) va_arg(ap, uint32);
-		break;
-	case TIFFTAG_CLEANFAXDATA:
-		sp->cleanfaxdata = (uint16) va_arg(ap, uint16_vap);
-		break;
-	case TIFFTAG_CONSECUTIVEBADFAXLINES:
-		sp->badfaxrun = (uint32) va_arg(ap, uint32);
-		break;
-	default:
-		return (*sp->vsetparent)(tif, tag, ap);
-	}
-	
-	if ((fip = TIFFFieldWithTag(tif, tag)))
-		TIFFSetFieldBit(tif, fip->field_bit);
-	else
-		return 0;
-
-	tif->tif_flags |= TIFF_DIRTYDIRECT;
-	return 1;
-}
-
-static int
-Fax3VGetField(TIFF* tif, uint32 tag, va_list ap)
-{
-	Fax3BaseState* sp = Fax3State(tif);
-
-	assert(sp != 0);
-
-	switch (tag) {
-	case TIFFTAG_FAXMODE:
-		*va_arg(ap, int*) = sp->mode;
-		break;
-	case TIFFTAG_FAXFILLFUNC:
-		*va_arg(ap, TIFFFaxFillFunc*) = DecoderState(tif)->fill;
-		break;
-	case TIFFTAG_GROUP3OPTIONS:
-	case TIFFTAG_GROUP4OPTIONS:
-		*va_arg(ap, uint32*) = sp->groupoptions;
-		break;
-	case TIFFTAG_BADFAXLINES:
-		*va_arg(ap, uint32*) = sp->badfaxlines;
-		break;
-	case TIFFTAG_CLEANFAXDATA:
-		*va_arg(ap, uint16*) = sp->cleanfaxdata;
-		break;
-	case TIFFTAG_CONSECUTIVEBADFAXLINES:
-		*va_arg(ap, uint32*) = sp->badfaxrun;
-		break;
-	default:
-		return (*sp->vgetparent)(tif, tag, ap);
-	}
-	return (1);
-}
-
-static void
-Fax3PrintDir(TIFF* tif, FILE* fd, long flags)
-{
-	Fax3BaseState* sp = Fax3State(tif);
-
-	assert(sp != 0);
-
-	(void) flags;
-	if (TIFFFieldSet(tif,FIELD_OPTIONS)) {
-		const char* sep = " ";
-		if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4) {
-			fprintf(fd, "  Group 4 Options:");
-			if (sp->groupoptions & GROUP4OPT_UNCOMPRESSED)
-				fprintf(fd, "%suncompressed data", sep);
-		} else {
-
-			fprintf(fd, "  Group 3 Options:");
-			if (sp->groupoptions & GROUP3OPT_2DENCODING)
-				fprintf(fd, "%s2-d encoding", sep), sep = "+";
-			if (sp->groupoptions & GROUP3OPT_FILLBITS)
-				fprintf(fd, "%sEOL padding", sep), sep = "+";
-			if (sp->groupoptions & GROUP3OPT_UNCOMPRESSED)
-				fprintf(fd, "%suncompressed data", sep);
-		}
-		fprintf(fd, " (%lu = 0x%lx)\n",
-                        (unsigned long) sp->groupoptions,
-                        (unsigned long) sp->groupoptions);
-	}
-	if (TIFFFieldSet(tif,FIELD_CLEANFAXDATA)) {
-		fprintf(fd, "  Fax Data:");
-		switch (sp->cleanfaxdata) {
-		case CLEANFAXDATA_CLEAN:
-			fprintf(fd, " clean");
-			break;
-		case CLEANFAXDATA_REGENERATED:
-			fprintf(fd, " receiver regenerated");
-			break;
-		case CLEANFAXDATA_UNCLEAN:
-			fprintf(fd, " uncorrected errors");
-			break;
-		}
-		fprintf(fd, " (%u = 0x%x)\n",
-		    sp->cleanfaxdata, sp->cleanfaxdata);
-	}
-	if (TIFFFieldSet(tif,FIELD_BADFAXLINES))
-		fprintf(fd, "  Bad Fax Lines: %lu\n",
-                        (unsigned long) sp->badfaxlines);
-	if (TIFFFieldSet(tif,FIELD_BADFAXRUN))
-		fprintf(fd, "  Consecutive Bad Fax Lines: %lu\n",
-		    (unsigned long) sp->badfaxrun);
-	if (sp->printdir)
-		(*sp->printdir)(tif, fd, flags);
-}
-
-static int
-InitCCITTFax3(TIFF* tif)
-{
-	static const char module[] = "InitCCITTFax3";
-	Fax3BaseState* sp;
-
-	/*
-	 * Merge codec-specific tag information.
-	 */
-	if (!_TIFFMergeFields(tif, faxFields, TIFFArrayCount(faxFields))) {
-		TIFFErrorExt(tif->tif_clientdata, "InitCCITTFax3",
-			"Merging common CCITT Fax codec-specific tags failed");
-		return 0;
-	}
-
-	/*
-	 * Allocate state block so tag methods have storage to record values.
-	 */
-	tif->tif_data = (uint8*)
-		_TIFFmalloc(sizeof (Fax3CodecState));
-
-	if (tif->tif_data == NULL) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-		    "No space for state block");
-		return (0);
-	}
-
-	sp = Fax3State(tif);
-        sp->rw_mode = tif->tif_mode;
-
-	/*
-	 * Override parent get/set field methods.
-	 */
-	sp->vgetparent = tif->tif_tagmethods.vgetfield;
-	tif->tif_tagmethods.vgetfield = Fax3VGetField; /* hook for codec tags */
-	sp->vsetparent = tif->tif_tagmethods.vsetfield;
-	tif->tif_tagmethods.vsetfield = Fax3VSetField; /* hook for codec tags */
-	sp->printdir = tif->tif_tagmethods.printdir;
-	tif->tif_tagmethods.printdir = Fax3PrintDir;   /* hook for codec tags */
-	sp->groupoptions = 0;	
-
-	if (sp->rw_mode == O_RDONLY) /* FIXME: improve for in place update */
-		tif->tif_flags |= TIFF_NOBITREV; /* decoder does bit reversal */
-	DecoderState(tif)->runs = NULL;
-	TIFFSetField(tif, TIFFTAG_FAXFILLFUNC, _TIFFFax3fillruns);
-	EncoderState(tif)->refline = NULL;
-
-	/*
-	 * Install codec methods.
-	 */
-	tif->tif_fixuptags = Fax3FixupTags;
-	tif->tif_setupdecode = Fax3SetupState;
-	tif->tif_predecode = Fax3PreDecode;
-	tif->tif_decoderow = Fax3Decode1D;
-	tif->tif_decodestrip = Fax3Decode1D;
-	tif->tif_decodetile = Fax3Decode1D;
-	tif->tif_setupencode = Fax3SetupState;
-	tif->tif_preencode = Fax3PreEncode;
-	tif->tif_postencode = Fax3PostEncode;
-	tif->tif_encoderow = Fax3Encode;
-	tif->tif_encodestrip = Fax3Encode;
-	tif->tif_encodetile = Fax3Encode;
-	tif->tif_close = Fax3Close;
-	tif->tif_cleanup = Fax3Cleanup;
-
-	return (1);
-}
-
-int
-TIFFInitCCITTFax3(TIFF* tif, int scheme)
-{
-	(void) scheme;
-	if (InitCCITTFax3(tif)) {
-		/*
-		 * Merge codec-specific tag information.
-		 */
-		if (!_TIFFMergeFields(tif, fax3Fields,
-				      TIFFArrayCount(fax3Fields))) {
-			TIFFErrorExt(tif->tif_clientdata, "TIFFInitCCITTFax3",
-			"Merging CCITT Fax 3 codec-specific tags failed");
-			return 0;
-		}
-
-		/*
-		 * The default format is Class/F-style w/o RTC.
-		 */
-		return TIFFSetField(tif, TIFFTAG_FAXMODE, FAXMODE_CLASSF);
-	} else
-		return 01;
-}
-
-/*
- * CCITT Group 4 (T.6) Facsimile-compatible
- * Compression Scheme Support.
- */
-
-#define SWAP(t,a,b) { t x; x = (a); (a) = (b); (b) = x; }
-/*
- * Decode the requested amount of G4-encoded data.
- */
-static int
-Fax4Decode(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s)
-{
-	DECLARE_STATE_2D(tif, sp, "Fax4Decode");
-	(void) s;
-	if (occ % sp->b.rowbytes)
-	{
-		TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read");
-		return (-1);
-	}
-	CACHE_STATE(tif, sp);
-	while (occ > 0) {
-		a0 = 0;
-		RunLength = 0;
-		pa = thisrun = sp->curruns;
-		pb = sp->refruns;
-		b1 = *pb++;
-#ifdef FAX3_DEBUG
-		printf("\nBitAcc=%08X, BitsAvail = %d\n", BitAcc, BitsAvail);
-		printf("-------------------- %d\n", tif->tif_row);
-		fflush(stdout);
-#endif
-		EXPAND2D(EOFG4);
-                if (EOLcnt)
-                    goto EOFG4;
-		(*sp->fill)(buf, thisrun, pa, lastx);
-		SETVALUE(0);		/* imaginary change for reference */
-		SWAP(uint32*, sp->curruns, sp->refruns);
-		buf += sp->b.rowbytes;
-		occ -= sp->b.rowbytes;
-		sp->line++;
-		continue;
-	EOFG4:
-                NeedBits16( 13, BADG4 );
-        BADG4:
-#ifdef FAX3_DEBUG
-                if( GetBits(13) != 0x1001 )
-                    fputs( "Bad EOFB\n", stderr );
-#endif                
-                ClrBits( 13 );
-		(*sp->fill)(buf, thisrun, pa, lastx);
-		UNCACHE_STATE(tif, sp);
-		return ( sp->line ? 1 : -1);	/* don't error on badly-terminated strips */
-	}
-	UNCACHE_STATE(tif, sp);
-	return (1);
-}
-#undef	SWAP
-
-/*
- * Encode the requested amount of data.
- */
-static int
-Fax4Encode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
-{
-	static const char module[] = "Fax4Encode";
-	Fax3CodecState *sp = EncoderState(tif);
-	(void) s;
-	if (cc % sp->b.rowbytes)
-	{
-		TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be written");
-		return (0);
-	}
-	while (cc > 0) {
-		if (!Fax3Encode2DRow(tif, bp, sp->refline, sp->b.rowpixels))
-			return (0);
-		_TIFFmemcpy(sp->refline, bp, sp->b.rowbytes);
-		bp += sp->b.rowbytes;
-		cc -= sp->b.rowbytes;
-	}
-	return (1);
-}
-
-static int
-Fax4PostEncode(TIFF* tif)
-{
-	Fax3CodecState *sp = EncoderState(tif);
-
-	/* terminate strip w/ EOFB */
-	Fax3PutBits(tif, EOL, 12);
-	Fax3PutBits(tif, EOL, 12);
-	if (sp->bit != 8)
-		Fax3FlushBits(tif, sp);
-	return (1);
-}
-
-int
-TIFFInitCCITTFax4(TIFF* tif, int scheme)
-{
-	(void) scheme;
-	if (InitCCITTFax3(tif)) {		/* reuse G3 support */
-		/*
-		 * Merge codec-specific tag information.
-		 */
-		if (!_TIFFMergeFields(tif, fax4Fields,
-				      TIFFArrayCount(fax4Fields))) {
-			TIFFErrorExt(tif->tif_clientdata, "TIFFInitCCITTFax4",
-			"Merging CCITT Fax 4 codec-specific tags failed");
-			return 0;
-		}
-
-		tif->tif_decoderow = Fax4Decode;
-		tif->tif_decodestrip = Fax4Decode;
-		tif->tif_decodetile = Fax4Decode;
-		tif->tif_encoderow = Fax4Encode;
-		tif->tif_encodestrip = Fax4Encode;
-		tif->tif_encodetile = Fax4Encode;
-		tif->tif_postencode = Fax4PostEncode;
-		/*
-		 * Suppress RTC at the end of each strip.
-		 */
-		return TIFFSetField(tif, TIFFTAG_FAXMODE, FAXMODE_NORTC);
-	} else
-		return (0);
-}
-
-/*
- * CCITT Group 3 1-D Modified Huffman RLE Compression Support.
- * (Compression algorithms 2 and 32771)
- */
-
-/*
- * Decode the requested amount of RLE-encoded data.
- */
-static int
-Fax3DecodeRLE(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s)
-{
-	DECLARE_STATE(tif, sp, "Fax3DecodeRLE");
-	int mode = sp->b.mode;
-	(void) s;
-	if (occ % sp->b.rowbytes)
-	{
-		TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read");
-		return (-1);
-	}
-	CACHE_STATE(tif, sp);
-	thisrun = sp->curruns;
-	while (occ > 0) {
-		a0 = 0;
-		RunLength = 0;
-		pa = thisrun;
-#ifdef FAX3_DEBUG
-		printf("\nBitAcc=%08X, BitsAvail = %d\n", BitAcc, BitsAvail);
-		printf("-------------------- %d\n", tif->tif_row);
-		fflush(stdout);
-#endif
-		EXPAND1D(EOFRLE);
-		(*sp->fill)(buf, thisrun, pa, lastx);
-		/*
-		 * Cleanup at the end of the row.
-		 */
-		if (mode & FAXMODE_BYTEALIGN) {
-			int n = BitsAvail - (BitsAvail &~ 7);
-			ClrBits(n);
-		} else if (mode & FAXMODE_WORDALIGN) {
-			int n = BitsAvail - (BitsAvail &~ 15);
-			ClrBits(n);
-			if (BitsAvail == 0 && !isAligned(cp, uint16))
-			    cp++;
-		}
-		buf += sp->b.rowbytes;
-		occ -= sp->b.rowbytes;
-		sp->line++;
-		continue;
-	EOFRLE:				/* premature EOF */
-		(*sp->fill)(buf, thisrun, pa, lastx);
-		UNCACHE_STATE(tif, sp);
-		return (-1);
-	}
-	UNCACHE_STATE(tif, sp);
-	return (1);
-}
-
-int
-TIFFInitCCITTRLE(TIFF* tif, int scheme)
-{
-	(void) scheme;
-	if (InitCCITTFax3(tif)) {		/* reuse G3 support */
-		tif->tif_decoderow = Fax3DecodeRLE;
-		tif->tif_decodestrip = Fax3DecodeRLE;
-		tif->tif_decodetile = Fax3DecodeRLE;
-		/*
-		 * Suppress RTC+EOLs when encoding and byte-align data.
-		 */
-		return TIFFSetField(tif, TIFFTAG_FAXMODE,
-		    FAXMODE_NORTC|FAXMODE_NOEOL|FAXMODE_BYTEALIGN);
-	} else
-		return (0);
-}
-
-int
-TIFFInitCCITTRLEW(TIFF* tif, int scheme)
-{
-	(void) scheme;
-	if (InitCCITTFax3(tif)) {		/* reuse G3 support */
-		tif->tif_decoderow = Fax3DecodeRLE;
-		tif->tif_decodestrip = Fax3DecodeRLE;
-		tif->tif_decodetile = Fax3DecodeRLE;  
-		/*
-		 * Suppress RTC+EOLs when encoding and word-align data.
-		 */
-		return TIFFSetField(tif, TIFFTAG_FAXMODE,
-		    FAXMODE_NORTC|FAXMODE_NOEOL|FAXMODE_WORDALIGN);
-	} else
-		return (0);
-}
-#endif /* CCITT_SUPPORT */
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Id: tif_fax3.c,v 1.11 2015/02/19 22:39:58 drolon Exp $ */
+
+/*
+ * Copyright (c) 1990-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and 
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
+ * 
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
+ * OF THIS SOFTWARE.
+ */
+
+#include "tiffiop.h"
+#ifdef CCITT_SUPPORT
+/*
+ * TIFF Library.
+ *
+ * CCITT Group 3 (T.4) and Group 4 (T.6) Compression Support.
+ *
+ * This file contains support for decoding and encoding TIFF
+ * compression algorithms 2, 3, 4, and 32771.
+ *
+ * Decoder support is derived, with permission, from the code
+ * in Frank Cringle's viewfax program;
+ *      Copyright (C) 1990, 1995  Frank D. Cringle.
+ */
+#include "tif_fax3.h"
+#define	G3CODES
+#include "t4.h"
+#include <stdio.h>
+
+/*
+ * Compression+decompression state blocks are
+ * derived from this ``base state'' block.
+ */
+typedef struct {
+	int      rw_mode;                /* O_RDONLY for decode, else encode */
+	int      mode;                   /* operating mode */
+	tmsize_t rowbytes;               /* bytes in a decoded scanline */
+	uint32   rowpixels;              /* pixels in a scanline */
+
+	uint16   cleanfaxdata;           /* CleanFaxData tag */
+	uint32   badfaxrun;              /* BadFaxRun tag */
+	uint32   badfaxlines;            /* BadFaxLines tag */
+	uint32   groupoptions;           /* Group 3/4 options tag */
+
+	TIFFVGetMethod  vgetparent;      /* super-class method */
+	TIFFVSetMethod  vsetparent;      /* super-class method */
+	TIFFPrintMethod printdir;        /* super-class method */
+} Fax3BaseState;
+#define	Fax3State(tif)		((Fax3BaseState*) (tif)->tif_data)
+
+typedef enum { G3_1D, G3_2D } Ttag;
+typedef struct {
+	Fax3BaseState b;
+
+	/* Decoder state info */
+	const unsigned char* bitmap;	/* bit reversal table */
+	uint32	data;			/* current i/o byte/word */
+	int	bit;			/* current i/o bit in byte */
+	int	EOLcnt;			/* count of EOL codes recognized */
+	TIFFFaxFillFunc fill;		/* fill routine */
+	uint32*	runs;			/* b&w runs for current/previous row */
+	uint32*	refruns;		/* runs for reference line */
+	uint32*	curruns;		/* runs for current line */
+
+	/* Encoder state info */
+	Ttag    tag;			/* encoding state */
+	unsigned char*	refline;	/* reference line for 2d decoding */
+	int	k;			/* #rows left that can be 2d encoded */
+	int	maxk;			/* max #rows that can be 2d encoded */
+
+	int line;
+} Fax3CodecState;
+#define DecoderState(tif) ((Fax3CodecState*) Fax3State(tif))
+#define EncoderState(tif) ((Fax3CodecState*) Fax3State(tif))
+
+#define is2DEncoding(sp) (sp->b.groupoptions & GROUP3OPT_2DENCODING)
+#define isAligned(p,t) ((((size_t)(p)) & (sizeof (t)-1)) == 0)
+
+/*
+ * Group 3 and Group 4 Decoding.
+ */
+
+/*
+ * These macros glue the TIFF library state to
+ * the state expected by Frank's decoder.
+ */
+#define	DECLARE_STATE(tif, sp, mod)					\
+    static const char module[] = mod;					\
+    Fax3CodecState* sp = DecoderState(tif);				\
+    int a0;				/* reference element */		\
+    int lastx = sp->b.rowpixels;	/* last element in row */	\
+    uint32 BitAcc;			/* bit accumulator */		\
+    int BitsAvail;			/* # valid bits in BitAcc */	\
+    int RunLength;			/* length of current run */	\
+    unsigned char* cp;			/* next byte of input data */	\
+    unsigned char* ep;			/* end of input data */		\
+    uint32* pa;				/* place to stuff next run */	\
+    uint32* thisrun;			/* current row's run array */	\
+    int EOLcnt;				/* # EOL codes recognized */	\
+    const unsigned char* bitmap = sp->bitmap;	/* input data bit reverser */	\
+    const TIFFFaxTabEnt* TabEnt
+#define	DECLARE_STATE_2D(tif, sp, mod)					\
+    DECLARE_STATE(tif, sp, mod);					\
+    int b1;				/* next change on prev line */	\
+    uint32* pb				/* next run in reference line */\
+/*
+ * Load any state that may be changed during decoding.
+ */
+#define	CACHE_STATE(tif, sp) do {					\
+    BitAcc = sp->data;							\
+    BitsAvail = sp->bit;						\
+    EOLcnt = sp->EOLcnt;						\
+    cp = (unsigned char*) tif->tif_rawcp;				\
+    ep = cp + tif->tif_rawcc;						\
+} while (0)
+/*
+ * Save state possibly changed during decoding.
+ */
+#define	UNCACHE_STATE(tif, sp) do {					\
+    sp->bit = BitsAvail;						\
+    sp->data = BitAcc;							\
+    sp->EOLcnt = EOLcnt;						\
+    tif->tif_rawcc -= (tmsize_t)((uint8*) cp - tif->tif_rawcp);		\
+    tif->tif_rawcp = (uint8*) cp;					\
+} while (0)
+
+/*
+ * Setup state for decoding a strip.
+ */
+static int
+Fax3PreDecode(TIFF* tif, uint16 s)
+{
+	Fax3CodecState* sp = DecoderState(tif);
+
+	(void) s;
+	assert(sp != NULL);
+	sp->bit = 0;			/* force initial read */
+	sp->data = 0;
+	sp->EOLcnt = 0;			/* force initial scan for EOL */
+	/*
+	 * Decoder assumes lsb-to-msb bit order.  Note that we select
+	 * this here rather than in Fax3SetupState so that viewers can
+	 * hold the image open, fiddle with the FillOrder tag value,
+	 * and then re-decode the image.  Otherwise they'd need to close
+	 * and open the image to get the state reset.
+	 */
+	sp->bitmap =
+	    TIFFGetBitRevTable(tif->tif_dir.td_fillorder != FILLORDER_LSB2MSB);
+	if (sp->refruns) {		/* init reference line to white */
+		sp->refruns[0] = (uint32) sp->b.rowpixels;
+		sp->refruns[1] = 0;
+	}
+	sp->line = 0;
+	return (1);
+}
+
+/*
+ * Routine for handling various errors/conditions.
+ * Note how they are "glued into the decoder" by
+ * overriding the definitions used by the decoder.
+ */
+
+static void
+Fax3Unexpected(const char* module, TIFF* tif, uint32 line, uint32 a0)
+{
+	TIFFErrorExt(tif->tif_clientdata, module, "Bad code word at line %u of %s %u (x %u)",
+	    line, isTiled(tif) ? "tile" : "strip",
+	    (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip),
+	    a0);
+}
+#define	unexpected(table, a0)	Fax3Unexpected(module, tif, sp->line, a0)
+
+static void
+Fax3Extension(const char* module, TIFF* tif, uint32 line, uint32 a0)
+{
+	TIFFErrorExt(tif->tif_clientdata, module,
+	    "Uncompressed data (not supported) at line %u of %s %u (x %u)",
+	    line, isTiled(tif) ? "tile" : "strip",
+	    (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip),
+	    a0);
+}
+#define	extension(a0)	Fax3Extension(module, tif, sp->line, a0)
+
+static void
+Fax3BadLength(const char* module, TIFF* tif, uint32 line, uint32 a0, uint32 lastx)
+{
+	TIFFWarningExt(tif->tif_clientdata, module, "%s at line %u of %s %u (got %u, expected %u)",
+	    a0 < lastx ? "Premature EOL" : "Line length mismatch",
+	    line, isTiled(tif) ? "tile" : "strip",
+	    (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip),
+	    a0, lastx);
+}
+#define	badlength(a0,lastx)	Fax3BadLength(module, tif, sp->line, a0, lastx)
+
+static void
+Fax3PrematureEOF(const char* module, TIFF* tif, uint32 line, uint32 a0)
+{
+	TIFFWarningExt(tif->tif_clientdata, module, "Premature EOF at line %u of %s %u (x %u)",
+	    line, isTiled(tif) ? "tile" : "strip",
+	    (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip),
+	    a0);
+}
+#define	prematureEOF(a0)	Fax3PrematureEOF(module, tif, sp->line, a0)
+
+#define	Nop
+
+/*
+ * Decode the requested amount of G3 1D-encoded data.
+ */
+static int
+Fax3Decode1D(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s)
+{
+	DECLARE_STATE(tif, sp, "Fax3Decode1D");
+	(void) s;
+	if (occ % sp->b.rowbytes)
+	{
+		TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read");
+		return (-1);
+	}
+	CACHE_STATE(tif, sp);
+	thisrun = sp->curruns;
+	while (occ > 0) {
+		a0 = 0;
+		RunLength = 0;
+		pa = thisrun;
+#ifdef FAX3_DEBUG
+		printf("\nBitAcc=%08X, BitsAvail = %d\n", BitAcc, BitsAvail);
+		printf("-------------------- %d\n", tif->tif_row);
+		fflush(stdout);
+#endif
+		SYNC_EOL(EOF1D);
+		EXPAND1D(EOF1Da);
+		(*sp->fill)(buf, thisrun, pa, lastx);
+		buf += sp->b.rowbytes;
+		occ -= sp->b.rowbytes;
+		sp->line++;
+		continue;
+	EOF1D:				/* premature EOF */
+		CLEANUP_RUNS();
+	EOF1Da:				/* premature EOF */
+		(*sp->fill)(buf, thisrun, pa, lastx);
+		UNCACHE_STATE(tif, sp);
+		return (-1);
+	}
+	UNCACHE_STATE(tif, sp);
+	return (1);
+}
+
+#define	SWAP(t,a,b)	{ t x; x = (a); (a) = (b); (b) = x; }
+/*
+ * Decode the requested amount of G3 2D-encoded data.
+ */
+static int
+Fax3Decode2D(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s)
+{
+	DECLARE_STATE_2D(tif, sp, "Fax3Decode2D");
+	int is1D;			/* current line is 1d/2d-encoded */
+	(void) s;
+	if (occ % sp->b.rowbytes)
+	{
+		TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read");
+		return (-1);
+	}
+	CACHE_STATE(tif, sp);
+	while (occ > 0) {
+		a0 = 0;
+		RunLength = 0;
+		pa = thisrun = sp->curruns;
+#ifdef FAX3_DEBUG
+		printf("\nBitAcc=%08X, BitsAvail = %d EOLcnt = %d",
+		    BitAcc, BitsAvail, EOLcnt);
+#endif
+		SYNC_EOL(EOF2D);
+		NeedBits8(1, EOF2D);
+		is1D = GetBits(1);	/* 1D/2D-encoding tag bit */
+		ClrBits(1);
+#ifdef FAX3_DEBUG
+		printf(" %s\n-------------------- %d\n",
+		    is1D ? "1D" : "2D", tif->tif_row);
+		fflush(stdout);
+#endif
+		pb = sp->refruns;
+		b1 = *pb++;
+		if (is1D)
+			EXPAND1D(EOF2Da);
+		else
+			EXPAND2D(EOF2Da);
+		(*sp->fill)(buf, thisrun, pa, lastx);
+		SETVALUE(0);		/* imaginary change for reference */
+		SWAP(uint32*, sp->curruns, sp->refruns);
+		buf += sp->b.rowbytes;
+		occ -= sp->b.rowbytes;
+		sp->line++;
+		continue;
+	EOF2D:				/* premature EOF */
+		CLEANUP_RUNS();
+	EOF2Da:				/* premature EOF */
+		(*sp->fill)(buf, thisrun, pa, lastx);
+		UNCACHE_STATE(tif, sp);
+		return (-1);
+	}
+	UNCACHE_STATE(tif, sp);
+	return (1);
+}
+#undef SWAP
+
+/*
+ * The ZERO & FILL macros must handle spans < 2*sizeof(long) bytes.
+ * For machines with 64-bit longs this is <16 bytes; otherwise
+ * this is <8 bytes.  We optimize the code here to reflect the
+ * machine characteristics.
+ */
+#if SIZEOF_UNSIGNED_LONG == 8
+# define FILL(n, cp)							    \
+    switch (n) {							    \
+    case 15:(cp)[14] = 0xff; case 14:(cp)[13] = 0xff; case 13: (cp)[12] = 0xff;\
+    case 12:(cp)[11] = 0xff; case 11:(cp)[10] = 0xff; case 10: (cp)[9] = 0xff;\
+    case  9: (cp)[8] = 0xff; case  8: (cp)[7] = 0xff; case  7: (cp)[6] = 0xff;\
+    case  6: (cp)[5] = 0xff; case  5: (cp)[4] = 0xff; case  4: (cp)[3] = 0xff;\
+    case  3: (cp)[2] = 0xff; case  2: (cp)[1] = 0xff;			      \
+    case  1: (cp)[0] = 0xff; (cp) += (n); case 0:  ;			      \
+    }
+# define ZERO(n, cp)							\
+    switch (n) {							\
+    case 15:(cp)[14] = 0; case 14:(cp)[13] = 0; case 13: (cp)[12] = 0;	\
+    case 12:(cp)[11] = 0; case 11:(cp)[10] = 0; case 10: (cp)[9] = 0;	\
+    case  9: (cp)[8] = 0; case  8: (cp)[7] = 0; case  7: (cp)[6] = 0;	\
+    case  6: (cp)[5] = 0; case  5: (cp)[4] = 0; case  4: (cp)[3] = 0;	\
+    case  3: (cp)[2] = 0; case  2: (cp)[1] = 0;				\
+    case  1: (cp)[0] = 0; (cp) += (n); case 0:  ;			\
+    }
+#else
+# define FILL(n, cp)							    \
+    switch (n) {							    \
+    case 7: (cp)[6] = 0xff; case 6: (cp)[5] = 0xff; case 5: (cp)[4] = 0xff; \
+    case 4: (cp)[3] = 0xff; case 3: (cp)[2] = 0xff; case 2: (cp)[1] = 0xff; \
+    case 1: (cp)[0] = 0xff; (cp) += (n); case 0:  ;			    \
+    }
+# define ZERO(n, cp)							\
+    switch (n) {							\
+    case 7: (cp)[6] = 0; case 6: (cp)[5] = 0; case 5: (cp)[4] = 0;	\
+    case 4: (cp)[3] = 0; case 3: (cp)[2] = 0; case 2: (cp)[1] = 0;	\
+    case 1: (cp)[0] = 0; (cp) += (n); case 0:  ;			\
+    }
+#endif
+
+/*
+ * Bit-fill a row according to the white/black
+ * runs generated during G3/G4 decoding.
+ */
+void
+_TIFFFax3fillruns(unsigned char* buf, uint32* runs, uint32* erun, uint32 lastx)
+{
+	static const unsigned char _fillmasks[] =
+	    { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };
+	unsigned char* cp;
+	uint32 x, bx, run;
+	int32 n, nw;
+	long* lp;
+
+	if ((erun-runs)&1)
+	    *erun++ = 0;
+	x = 0;
+	for (; runs < erun; runs += 2) {
+	    run = runs[0];
+	    if (x+run > lastx || run > lastx )
+		run = runs[0] = (uint32) (lastx - x);
+	    if (run) {
+		cp = buf + (x>>3);
+		bx = x&7;
+		if (run > 8-bx) {
+		    if (bx) {			/* align to byte boundary */
+			*cp++ &= 0xff << (8-bx);
+			run -= 8-bx;
+		    }
+		    if( (n = run >> 3) != 0 ) {	/* multiple bytes to fill */
+			if ((n/sizeof (long)) > 1) {
+			    /*
+			     * Align to longword boundary and fill.
+			     */
+			    for (; n && !isAligned(cp, long); n--)
+				    *cp++ = 0x00;
+			    lp = (long*) cp;
+			    nw = (int32)(n / sizeof (long));
+			    n -= nw * sizeof (long);
+			    do {
+				    *lp++ = 0L;
+			    } while (--nw);
+			    cp = (unsigned char*) lp;
+			}
+			ZERO(n, cp);
+			run &= 7;
+		    }
+		    if (run)
+			cp[0] &= 0xff >> run;
+		} else
+		    cp[0] &= ~(_fillmasks[run]>>bx);
+		x += runs[0];
+	    }
+	    run = runs[1];
+	    if (x+run > lastx || run > lastx )
+		run = runs[1] = lastx - x;
+	    if (run) {
+		cp = buf + (x>>3);
+		bx = x&7;
+		if (run > 8-bx) {
+		    if (bx) {			/* align to byte boundary */
+			*cp++ |= 0xff >> bx;
+			run -= 8-bx;
+		    }
+		    if( (n = run>>3) != 0 ) {	/* multiple bytes to fill */
+			if ((n/sizeof (long)) > 1) {
+			    /*
+			     * Align to longword boundary and fill.
+			     */
+			    for (; n && !isAligned(cp, long); n--)
+				*cp++ = 0xff;
+			    lp = (long*) cp;
+			    nw = (int32)(n / sizeof (long));
+			    n -= nw * sizeof (long);
+			    do {
+				*lp++ = -1L;
+			    } while (--nw);
+			    cp = (unsigned char*) lp;
+			}
+			FILL(n, cp);
+			run &= 7;
+		    }
+		    if (run)
+			cp[0] |= 0xff00 >> run;
+		} else
+		    cp[0] |= _fillmasks[run]>>bx;
+		x += runs[1];
+	    }
+	}
+	assert(x == lastx);
+}
+#undef	ZERO
+#undef	FILL
+
+static int
+Fax3FixupTags(TIFF* tif)
+{
+	(void) tif;
+	return (1);
+}
+
+/*
+ * Setup G3/G4-related compression/decompression state
+ * before data is processed.  This routine is called once
+ * per image -- it sets up different state based on whether
+ * or not decoding or encoding is being done and whether
+ * 1D- or 2D-encoded data is involved.
+ */
+static int
+Fax3SetupState(TIFF* tif)
+{
+	static const char module[] = "Fax3SetupState";
+	TIFFDirectory* td = &tif->tif_dir;
+	Fax3BaseState* sp = Fax3State(tif);
+	int needsRefLine;
+	Fax3CodecState* dsp = (Fax3CodecState*) Fax3State(tif);
+	tmsize_t rowbytes;
+	uint32 rowpixels, nruns;
+
+	if (td->td_bitspersample != 1) {
+		TIFFErrorExt(tif->tif_clientdata, module,
+		    "Bits/sample must be 1 for Group 3/4 encoding/decoding");
+		return (0);
+	}
+	/*
+	 * Calculate the scanline/tile widths.
+	 */
+	if (isTiled(tif)) {
+		rowbytes = TIFFTileRowSize(tif);
+		rowpixels = td->td_tilewidth;
+	} else {
+		rowbytes = TIFFScanlineSize(tif);
+		rowpixels = td->td_imagewidth;
+	}
+	sp->rowbytes = rowbytes;
+	sp->rowpixels = rowpixels;
+	/*
+	 * Allocate any additional space required for decoding/encoding.
+	 */
+	needsRefLine = (
+	    (sp->groupoptions & GROUP3OPT_2DENCODING) ||
+	    td->td_compression == COMPRESSION_CCITTFAX4
+	);
+
+	/*
+	  Assure that allocation computations do not overflow.
+	  
+	  TIFFroundup and TIFFSafeMultiply return zero on integer overflow
+	*/
+	dsp->runs=(uint32*) NULL;
+	nruns = TIFFroundup_32(rowpixels,32);
+	if (needsRefLine) {
+		nruns = TIFFSafeMultiply(uint32,nruns,2);
+	}
+	if ((nruns == 0) || (TIFFSafeMultiply(uint32,nruns,2) == 0)) {
+		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+			     "Row pixels integer overflow (rowpixels %u)",
+			     rowpixels);
+		return (0);
+	}
+	dsp->runs = (uint32*) _TIFFCheckMalloc(tif,
+					       TIFFSafeMultiply(uint32,nruns,2),
+					       sizeof (uint32),
+					       "for Group 3/4 run arrays");
+	if (dsp->runs == NULL)
+		return (0);
+	memset( dsp->runs, 0, TIFFSafeMultiply(uint32,nruns,2)*sizeof(uint32));
+	dsp->curruns = dsp->runs;
+	if (needsRefLine)
+		dsp->refruns = dsp->runs + nruns;
+	else
+		dsp->refruns = NULL;
+	if (td->td_compression == COMPRESSION_CCITTFAX3
+	    && is2DEncoding(dsp)) {	/* NB: default is 1D routine */
+		tif->tif_decoderow = Fax3Decode2D;
+		tif->tif_decodestrip = Fax3Decode2D;
+		tif->tif_decodetile = Fax3Decode2D;
+	}
+
+	if (needsRefLine) {		/* 2d encoding */
+		Fax3CodecState* esp = EncoderState(tif);
+		/*
+		 * 2d encoding requires a scanline
+		 * buffer for the ``reference line''; the
+		 * scanline against which delta encoding
+		 * is referenced.  The reference line must
+		 * be initialized to be ``white'' (done elsewhere).
+		 */
+		esp->refline = (unsigned char*) _TIFFmalloc(rowbytes);
+		if (esp->refline == NULL) {
+			TIFFErrorExt(tif->tif_clientdata, module,
+			    "No space for Group 3/4 reference line");
+			return (0);
+		}
+	} else					/* 1d encoding */
+		EncoderState(tif)->refline = NULL;
+
+	return (1);
+}
+
+/*
+ * CCITT Group 3 FAX Encoding.
+ */
+
+#define	Fax3FlushBits(tif, sp) {				\
+	if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize)		\
+		(void) TIFFFlushData1(tif);			\
+	*(tif)->tif_rawcp++ = (uint8) (sp)->data;		\
+	(tif)->tif_rawcc++;					\
+	(sp)->data = 0, (sp)->bit = 8;				\
+}
+#define	_FlushBits(tif) {					\
+	if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize)		\
+		(void) TIFFFlushData1(tif);			\
+	*(tif)->tif_rawcp++ = (uint8) data;		\
+	(tif)->tif_rawcc++;					\
+	data = 0, bit = 8;					\
+}
+static const int _msbmask[9] =
+    { 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
+#define	_PutBits(tif, bits, length) {				\
+	while (length > bit) {					\
+		data |= bits >> (length - bit);			\
+		length -= bit;					\
+		_FlushBits(tif);				\
+	}							\
+        assert( length < 9 );                                   \
+	data |= (bits & _msbmask[length]) << (bit - length);	\
+	bit -= length;						\
+	if (bit == 0)						\
+		_FlushBits(tif);				\
+}
+	
+/*
+ * Write a variable-length bit-value to
+ * the output stream.  Values are
+ * assumed to be at most 16 bits.
+ */
+static void
+Fax3PutBits(TIFF* tif, unsigned int bits, unsigned int length)
+{
+	Fax3CodecState* sp = EncoderState(tif);
+	unsigned int bit = sp->bit;
+	int data = sp->data;
+
+	_PutBits(tif, bits, length);
+
+	sp->data = data;
+	sp->bit = bit;
+}
+
+/*
+ * Write a code to the output stream.
+ */
+#define putcode(tif, te)	Fax3PutBits(tif, (te)->code, (te)->length)
+
+#ifdef FAX3_DEBUG
+#define	DEBUG_COLOR(w) (tab == TIFFFaxWhiteCodes ? w "W" : w "B")
+#define	DEBUG_PRINT(what,len) {						\
+    int t;								\
+    printf("%08X/%-2d: %s%5d\t", data, bit, DEBUG_COLOR(what), len);	\
+    for (t = length-1; t >= 0; t--)					\
+	putchar(code & (1<<t) ? '1' : '0');				\
+    putchar('\n');							\
+}
+#endif
+
+/*
+ * Write the sequence of codes that describes
+ * the specified span of zero's or one's.  The
+ * appropriate table that holds the make-up and
+ * terminating codes is supplied.
+ */
+static void
+putspan(TIFF* tif, int32 span, const tableentry* tab)
+{
+	Fax3CodecState* sp = EncoderState(tif);
+	unsigned int bit = sp->bit;
+	int data = sp->data;
+	unsigned int code, length;
+
+	while (span >= 2624) {
+		const tableentry* te = &tab[63 + (2560>>6)];
+		code = te->code, length = te->length;
+#ifdef FAX3_DEBUG
+		DEBUG_PRINT("MakeUp", te->runlen);
+#endif
+		_PutBits(tif, code, length);
+		span -= te->runlen;
+	}
+	if (span >= 64) {
+		const tableentry* te = &tab[63 + (span>>6)];
+		assert(te->runlen == 64*(span>>6));
+		code = te->code, length = te->length;
+#ifdef FAX3_DEBUG
+		DEBUG_PRINT("MakeUp", te->runlen);
+#endif
+		_PutBits(tif, code, length);
+		span -= te->runlen;
+	}
+	code = tab[span].code, length = tab[span].length;
+#ifdef FAX3_DEBUG
+	DEBUG_PRINT("  Term", tab[span].runlen);
+#endif
+	_PutBits(tif, code, length);
+
+	sp->data = data;
+	sp->bit = bit;
+}
+
+/*
+ * Write an EOL code to the output stream.  The zero-fill
+ * logic for byte-aligning encoded scanlines is handled
+ * here.  We also handle writing the tag bit for the next
+ * scanline when doing 2d encoding.
+ */
+static void
+Fax3PutEOL(TIFF* tif)
+{
+	Fax3CodecState* sp = EncoderState(tif);
+	unsigned int bit = sp->bit;
+	int data = sp->data;
+	unsigned int code, length, tparm;
+
+	if (sp->b.groupoptions & GROUP3OPT_FILLBITS) {
+		/*
+		 * Force bit alignment so EOL will terminate on
+		 * a byte boundary.  That is, force the bit alignment
+		 * to 16-12 = 4 before putting out the EOL code.
+		 */
+		int align = 8 - 4;
+		if (align != sp->bit) {
+			if (align > sp->bit)
+				align = sp->bit + (8 - align);
+			else
+				align = sp->bit - align;
+			code = 0;
+			tparm=align; 
+			_PutBits(tif, 0, tparm);
+		}
+	}
+	code = EOL, length = 12;
+	if (is2DEncoding(sp))
+		code = (code<<1) | (sp->tag == G3_1D), length++;
+	_PutBits(tif, code, length);
+
+	sp->data = data;
+	sp->bit = bit;
+}
+
+/*
+ * Reset encoding state at the start of a strip.
+ */
+static int
+Fax3PreEncode(TIFF* tif, uint16 s)
+{
+	Fax3CodecState* sp = EncoderState(tif);
+
+	(void) s;
+	assert(sp != NULL);
+	sp->bit = 8;
+	sp->data = 0;
+	sp->tag = G3_1D;
+	/*
+	 * This is necessary for Group 4; otherwise it isn't
+	 * needed because the first scanline of each strip ends
+	 * up being copied into the refline.
+	 */
+	if (sp->refline)
+		_TIFFmemset(sp->refline, 0x00, sp->b.rowbytes);
+	if (is2DEncoding(sp)) {
+		float res = tif->tif_dir.td_yresolution;
+		/*
+		 * The CCITT spec says that when doing 2d encoding, you
+		 * should only do it on K consecutive scanlines, where K
+		 * depends on the resolution of the image being encoded
+		 * (2 for <= 200 lpi, 4 for > 200 lpi).  Since the directory
+		 * code initializes td_yresolution to 0, this code will
+		 * select a K of 2 unless the YResolution tag is set
+		 * appropriately.  (Note also that we fudge a little here
+		 * and use 150 lpi to avoid problems with units conversion.)
+		 */
+		if (tif->tif_dir.td_resolutionunit == RESUNIT_CENTIMETER)
+			res *= 2.54f;		/* convert to inches */
+		sp->maxk = (res > 150 ? 4 : 2);
+		sp->k = sp->maxk-1;
+	} else
+		sp->k = sp->maxk = 0;
+	sp->line = 0;
+	return (1);
+}
+
+static const unsigned char zeroruns[256] = {
+    8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,	/* 0x00 - 0x0f */
+    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,	/* 0x10 - 0x1f */
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,	/* 0x20 - 0x2f */
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,	/* 0x30 - 0x3f */
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0x40 - 0x4f */
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0x50 - 0x5f */
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0x60 - 0x6f */
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0x70 - 0x7f */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x80 - 0x8f */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x90 - 0x9f */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0xa0 - 0xaf */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0xb0 - 0xbf */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0xc0 - 0xcf */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0xd0 - 0xdf */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0xe0 - 0xef */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0xf0 - 0xff */
+};
+static const unsigned char oneruns[256] = {
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x00 - 0x0f */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x10 - 0x1f */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x20 - 0x2f */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x30 - 0x3f */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x40 - 0x4f */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x50 - 0x5f */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x60 - 0x6f */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x70 - 0x7f */
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0x80 - 0x8f */
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0x90 - 0x9f */
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0xa0 - 0xaf */
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0xb0 - 0xbf */
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,	/* 0xc0 - 0xcf */
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,	/* 0xd0 - 0xdf */
+    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,	/* 0xe0 - 0xef */
+    4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8,	/* 0xf0 - 0xff */
+};
+
+/*
+ * On certain systems it pays to inline
+ * the routines that find pixel spans.
+ */
+#ifdef VAXC
+static	int32 find0span(unsigned char*, int32, int32);
+static	int32 find1span(unsigned char*, int32, int32);
+#pragma inline(find0span,find1span)
+#endif
+
+/*
+ * Find a span of ones or zeros using the supplied
+ * table.  The ``base'' of the bit string is supplied
+ * along with the start+end bit indices.
+ */
+inline static int32
+find0span(unsigned char* bp, int32 bs, int32 be)
+{
+	int32 bits = be - bs;
+	int32 n, span;
+
+	bp += bs>>3;
+	/*
+	 * Check partial byte on lhs.
+	 */
+	if (bits > 0 && (n = (bs & 7))) {
+		span = zeroruns[(*bp << n) & 0xff];
+		if (span > 8-n)		/* table value too generous */
+			span = 8-n;
+		if (span > bits)	/* constrain span to bit range */
+			span = bits;
+		if (n+span < 8)		/* doesn't extend to edge of byte */
+			return (span);
+		bits -= span;
+		bp++;
+	} else
+		span = 0;
+	if (bits >= (int32)(2 * 8 * sizeof(long))) {
+		long* lp;
+		/*
+		 * Align to longword boundary and check longwords.
+		 */
+		while (!isAligned(bp, long)) {
+			if (*bp != 0x00)
+				return (span + zeroruns[*bp]);
+			span += 8, bits -= 8;
+			bp++;
+		}
+		lp = (long*) bp;
+		while ((bits >= (int32)(8 * sizeof(long))) && (0 == *lp)) {
+			span += 8*sizeof (long), bits -= 8*sizeof (long);
+			lp++;
+		}
+		bp = (unsigned char*) lp;
+	}
+	/*
+	 * Scan full bytes for all 0's.
+	 */
+	while (bits >= 8) {
+		if (*bp != 0x00)	/* end of run */
+			return (span + zeroruns[*bp]);
+		span += 8, bits -= 8;
+		bp++;
+	}
+	/*
+	 * Check partial byte on rhs.
+	 */
+	if (bits > 0) {
+		n = zeroruns[*bp];
+		span += (n > bits ? bits : n);
+	}
+	return (span);
+}
+
+inline static int32
+find1span(unsigned char* bp, int32 bs, int32 be)
+{
+	int32 bits = be - bs;
+	int32 n, span;
+
+	bp += bs>>3;
+	/*
+	 * Check partial byte on lhs.
+	 */
+	if (bits > 0 && (n = (bs & 7))) {
+		span = oneruns[(*bp << n) & 0xff];
+		if (span > 8-n)		/* table value too generous */
+			span = 8-n;
+		if (span > bits)	/* constrain span to bit range */
+			span = bits;
+		if (n+span < 8)		/* doesn't extend to edge of byte */
+			return (span);
+		bits -= span;
+		bp++;
+	} else
+		span = 0;
+	if (bits >= (int32)(2 * 8 * sizeof(long))) {
+		long* lp;
+		/*
+		 * Align to longword boundary and check longwords.
+		 */
+		while (!isAligned(bp, long)) {
+			if (*bp != 0xff)
+				return (span + oneruns[*bp]);
+			span += 8, bits -= 8;
+			bp++;
+		}
+		lp = (long*) bp;
+		while ((bits >= (int32)(8 * sizeof(long))) && (~0 == *lp)) {
+			span += 8*sizeof (long), bits -= 8*sizeof (long);
+			lp++;
+		}
+		bp = (unsigned char*) lp;
+	}
+	/*
+	 * Scan full bytes for all 1's.
+	 */
+	while (bits >= 8) {
+		if (*bp != 0xff)	/* end of run */
+			return (span + oneruns[*bp]);
+		span += 8, bits -= 8;
+		bp++;
+	}
+	/*
+	 * Check partial byte on rhs.
+	 */
+	if (bits > 0) {
+		n = oneruns[*bp];
+		span += (n > bits ? bits : n);
+	}
+	return (span);
+}
+
+/*
+ * Return the offset of the next bit in the range
+ * [bs..be] that is different from the specified
+ * color.  The end, be, is returned if no such bit
+ * exists.
+ */
+#define	finddiff(_cp, _bs, _be, _color)	\
+	(_bs + (_color ? find1span(_cp,_bs,_be) : find0span(_cp,_bs,_be)))
+/*
+ * Like finddiff, but also check the starting bit
+ * against the end in case start > end.
+ */
+#define	finddiff2(_cp, _bs, _be, _color) \
+	(_bs < _be ? finddiff(_cp,_bs,_be,_color) : _be)
+
+/*
+ * 1d-encode a row of pixels.  The encoding is
+ * a sequence of all-white or all-black spans
+ * of pixels encoded with Huffman codes.
+ */
+static int
+Fax3Encode1DRow(TIFF* tif, unsigned char* bp, uint32 bits)
+{
+	Fax3CodecState* sp = EncoderState(tif);
+	int32 span;
+        uint32 bs = 0;
+
+	for (;;) {
+		span = find0span(bp, bs, bits);		/* white span */
+		putspan(tif, span, TIFFFaxWhiteCodes);
+		bs += span;
+		if (bs >= bits)
+			break;
+		span = find1span(bp, bs, bits);		/* black span */
+		putspan(tif, span, TIFFFaxBlackCodes);
+		bs += span;
+		if (bs >= bits)
+			break;
+	}
+	if (sp->b.mode & (FAXMODE_BYTEALIGN|FAXMODE_WORDALIGN)) {
+		if (sp->bit != 8)			/* byte-align */
+			Fax3FlushBits(tif, sp);
+		if ((sp->b.mode&FAXMODE_WORDALIGN) &&
+		    !isAligned(tif->tif_rawcp, uint16))
+			Fax3FlushBits(tif, sp);
+	}
+	return (1);
+}
+
+static const tableentry horizcode =
+    { 3, 0x1, 0 };	/* 001 */
+static const tableentry passcode =
+    { 4, 0x1, 0 };	/* 0001 */
+static const tableentry vcodes[7] = {
+    { 7, 0x03, 0 },	/* 0000 011 */
+    { 6, 0x03, 0 },	/* 0000 11 */
+    { 3, 0x03, 0 },	/* 011 */
+    { 1, 0x1, 0 },	/* 1 */
+    { 3, 0x2, 0 },	/* 010 */
+    { 6, 0x02, 0 },	/* 0000 10 */
+    { 7, 0x02, 0 }	/* 0000 010 */
+};
+
+/*
+ * 2d-encode a row of pixels.  Consult the CCITT
+ * documentation for the algorithm.
+ */
+static int
+Fax3Encode2DRow(TIFF* tif, unsigned char* bp, unsigned char* rp, uint32 bits)
+{
+#define	PIXEL(buf,ix)	((((buf)[(ix)>>3]) >> (7-((ix)&7))) & 1)
+        uint32 a0 = 0;
+	uint32 a1 = (PIXEL(bp, 0) != 0 ? 0 : finddiff(bp, 0, bits, 0));
+	uint32 b1 = (PIXEL(rp, 0) != 0 ? 0 : finddiff(rp, 0, bits, 0));
+	uint32 a2, b2;
+
+	for (;;) {
+		b2 = finddiff2(rp, b1, bits, PIXEL(rp,b1));
+		if (b2 >= a1) {
+			int32 d = b1 - a1;
+			if (!(-3 <= d && d <= 3)) {	/* horizontal mode */
+				a2 = finddiff2(bp, a1, bits, PIXEL(bp,a1));
+				putcode(tif, &horizcode);
+				if (a0+a1 == 0 || PIXEL(bp, a0) == 0) {
+					putspan(tif, a1-a0, TIFFFaxWhiteCodes);
+					putspan(tif, a2-a1, TIFFFaxBlackCodes);
+				} else {
+					putspan(tif, a1-a0, TIFFFaxBlackCodes);
+					putspan(tif, a2-a1, TIFFFaxWhiteCodes);
+				}
+				a0 = a2;
+			} else {			/* vertical mode */
+				putcode(tif, &vcodes[d+3]);
+				a0 = a1;
+			}
+		} else {				/* pass mode */
+			putcode(tif, &passcode);
+			a0 = b2;
+		}
+		if (a0 >= bits)
+			break;
+		a1 = finddiff(bp, a0, bits, PIXEL(bp,a0));
+		b1 = finddiff(rp, a0, bits, !PIXEL(bp,a0));
+		b1 = finddiff(rp, b1, bits, PIXEL(bp,a0));
+	}
+	return (1);
+#undef PIXEL
+}
+
+/*
+ * Encode a buffer of pixels.
+ */
+static int
+Fax3Encode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
+{
+	static const char module[] = "Fax3Encode";
+	Fax3CodecState* sp = EncoderState(tif);
+	(void) s;
+	if (cc % sp->b.rowbytes)
+	{
+		TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be written");
+		return (0);
+	}
+	while (cc > 0) {
+		if ((sp->b.mode & FAXMODE_NOEOL) == 0)
+			Fax3PutEOL(tif);
+		if (is2DEncoding(sp)) {
+			if (sp->tag == G3_1D) {
+				if (!Fax3Encode1DRow(tif, bp, sp->b.rowpixels))
+					return (0);
+				sp->tag = G3_2D;
+			} else {
+				if (!Fax3Encode2DRow(tif, bp, sp->refline,
+				    sp->b.rowpixels))
+					return (0);
+				sp->k--;
+			}
+			if (sp->k == 0) {
+				sp->tag = G3_1D;
+				sp->k = sp->maxk-1;
+			} else
+				_TIFFmemcpy(sp->refline, bp, sp->b.rowbytes);
+		} else {
+			if (!Fax3Encode1DRow(tif, bp, sp->b.rowpixels))
+				return (0);
+		}
+		bp += sp->b.rowbytes;
+		cc -= sp->b.rowbytes;
+	}
+	return (1);
+}
+
+static int
+Fax3PostEncode(TIFF* tif)
+{
+	Fax3CodecState* sp = EncoderState(tif);
+
+	if (sp->bit != 8)
+		Fax3FlushBits(tif, sp);
+	return (1);
+}
+
+static void
+Fax3Close(TIFF* tif)
+{
+	if ((Fax3State(tif)->mode & FAXMODE_NORTC) == 0) {
+		Fax3CodecState* sp = EncoderState(tif);
+		unsigned int code = EOL;
+		unsigned int length = 12;
+		int i;
+
+		if (is2DEncoding(sp))
+			code = (code<<1) | (sp->tag == G3_1D), length++;
+		for (i = 0; i < 6; i++)
+			Fax3PutBits(tif, code, length);
+		Fax3FlushBits(tif, sp);
+	}
+}
+
+static void
+Fax3Cleanup(TIFF* tif)
+{
+	Fax3CodecState* sp = DecoderState(tif);
+	
+	assert(sp != 0);
+
+	tif->tif_tagmethods.vgetfield = sp->b.vgetparent;
+	tif->tif_tagmethods.vsetfield = sp->b.vsetparent;
+	tif->tif_tagmethods.printdir = sp->b.printdir;
+
+	if (sp->runs)
+		_TIFFfree(sp->runs);
+	if (sp->refline)
+		_TIFFfree(sp->refline);
+
+	_TIFFfree(tif->tif_data);
+	tif->tif_data = NULL;
+
+	_TIFFSetDefaultCompressionState(tif);
+}
+
+#define	FIELD_BADFAXLINES	(FIELD_CODEC+0)
+#define	FIELD_CLEANFAXDATA	(FIELD_CODEC+1)
+#define	FIELD_BADFAXRUN		(FIELD_CODEC+2)
+
+#define	FIELD_OPTIONS		(FIELD_CODEC+7)
+
+static const TIFFField faxFields[] = {
+    { TIFFTAG_FAXMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "FaxMode", NULL },
+    { TIFFTAG_FAXFILLFUNC, 0, 0, TIFF_ANY, 0, TIFF_SETGET_OTHER, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "FaxFillFunc", NULL },
+    { TIFFTAG_BADFAXLINES, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_BADFAXLINES, TRUE, FALSE, "BadFaxLines", NULL },
+    { TIFFTAG_CLEANFAXDATA, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UINT16, FIELD_CLEANFAXDATA, TRUE, FALSE, "CleanFaxData", NULL },
+    { TIFFTAG_CONSECUTIVEBADFAXLINES, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_BADFAXRUN, TRUE, FALSE, "ConsecutiveBadFaxLines", NULL }};
+static const TIFFField fax3Fields[] = {
+    { TIFFTAG_GROUP3OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_OPTIONS, FALSE, FALSE, "Group3Options", NULL },
+};
+static const TIFFField fax4Fields[] = {
+    { TIFFTAG_GROUP4OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_OPTIONS, FALSE, FALSE, "Group4Options", NULL },
+};
+
+static int
+Fax3VSetField(TIFF* tif, uint32 tag, va_list ap)
+{
+	Fax3BaseState* sp = Fax3State(tif);
+	const TIFFField* fip;
+
+	assert(sp != 0);
+	assert(sp->vsetparent != 0);
+
+	switch (tag) {
+	case TIFFTAG_FAXMODE:
+		sp->mode = (int) va_arg(ap, int);
+		return 1;			/* NB: pseudo tag */
+	case TIFFTAG_FAXFILLFUNC:
+		DecoderState(tif)->fill = va_arg(ap, TIFFFaxFillFunc);
+		return 1;			/* NB: pseudo tag */
+	case TIFFTAG_GROUP3OPTIONS:
+		/* XXX: avoid reading options if compression mismatches. */
+		if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX3)
+			sp->groupoptions = (uint32) va_arg(ap, uint32);
+		break;
+	case TIFFTAG_GROUP4OPTIONS:
+		/* XXX: avoid reading options if compression mismatches. */
+		if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4)
+			sp->groupoptions = (uint32) va_arg(ap, uint32);
+		break;
+	case TIFFTAG_BADFAXLINES:
+		sp->badfaxlines = (uint32) va_arg(ap, uint32);
+		break;
+	case TIFFTAG_CLEANFAXDATA:
+		sp->cleanfaxdata = (uint16) va_arg(ap, uint16_vap);
+		break;
+	case TIFFTAG_CONSECUTIVEBADFAXLINES:
+		sp->badfaxrun = (uint32) va_arg(ap, uint32);
+		break;
+	default:
+		return (*sp->vsetparent)(tif, tag, ap);
+	}
+	
+	if ((fip = TIFFFieldWithTag(tif, tag)))
+		TIFFSetFieldBit(tif, fip->field_bit);
+	else
+		return 0;
+
+	tif->tif_flags |= TIFF_DIRTYDIRECT;
+	return 1;
+}
+
+static int
+Fax3VGetField(TIFF* tif, uint32 tag, va_list ap)
+{
+	Fax3BaseState* sp = Fax3State(tif);
+
+	assert(sp != 0);
+
+	switch (tag) {
+	case TIFFTAG_FAXMODE:
+		*va_arg(ap, int*) = sp->mode;
+		break;
+	case TIFFTAG_FAXFILLFUNC:
+		*va_arg(ap, TIFFFaxFillFunc*) = DecoderState(tif)->fill;
+		break;
+	case TIFFTAG_GROUP3OPTIONS:
+	case TIFFTAG_GROUP4OPTIONS:
+		*va_arg(ap, uint32*) = sp->groupoptions;
+		break;
+	case TIFFTAG_BADFAXLINES:
+		*va_arg(ap, uint32*) = sp->badfaxlines;
+		break;
+	case TIFFTAG_CLEANFAXDATA:
+		*va_arg(ap, uint16*) = sp->cleanfaxdata;
+		break;
+	case TIFFTAG_CONSECUTIVEBADFAXLINES:
+		*va_arg(ap, uint32*) = sp->badfaxrun;
+		break;
+	default:
+		return (*sp->vgetparent)(tif, tag, ap);
+	}
+	return (1);
+}
+
+static void
+Fax3PrintDir(TIFF* tif, FILE* fd, long flags)
+{
+	Fax3BaseState* sp = Fax3State(tif);
+
+	assert(sp != 0);
+
+	(void) flags;
+	if (TIFFFieldSet(tif,FIELD_OPTIONS)) {
+		const char* sep = " ";
+		if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4) {
+			fprintf(fd, "  Group 4 Options:");
+			if (sp->groupoptions & GROUP4OPT_UNCOMPRESSED)
+				fprintf(fd, "%suncompressed data", sep);
+		} else {
+
+			fprintf(fd, "  Group 3 Options:");
+			if (sp->groupoptions & GROUP3OPT_2DENCODING)
+				fprintf(fd, "%s2-d encoding", sep), sep = "+";
+			if (sp->groupoptions & GROUP3OPT_FILLBITS)
+				fprintf(fd, "%sEOL padding", sep), sep = "+";
+			if (sp->groupoptions & GROUP3OPT_UNCOMPRESSED)
+				fprintf(fd, "%suncompressed data", sep);
+		}
+		fprintf(fd, " (%lu = 0x%lx)\n",
+                        (unsigned long) sp->groupoptions,
+                        (unsigned long) sp->groupoptions);
+	}
+	if (TIFFFieldSet(tif,FIELD_CLEANFAXDATA)) {
+		fprintf(fd, "  Fax Data:");
+		switch (sp->cleanfaxdata) {
+		case CLEANFAXDATA_CLEAN:
+			fprintf(fd, " clean");
+			break;
+		case CLEANFAXDATA_REGENERATED:
+			fprintf(fd, " receiver regenerated");
+			break;
+		case CLEANFAXDATA_UNCLEAN:
+			fprintf(fd, " uncorrected errors");
+			break;
+		}
+		fprintf(fd, " (%u = 0x%x)\n",
+		    sp->cleanfaxdata, sp->cleanfaxdata);
+	}
+	if (TIFFFieldSet(tif,FIELD_BADFAXLINES))
+		fprintf(fd, "  Bad Fax Lines: %lu\n",
+                        (unsigned long) sp->badfaxlines);
+	if (TIFFFieldSet(tif,FIELD_BADFAXRUN))
+		fprintf(fd, "  Consecutive Bad Fax Lines: %lu\n",
+		    (unsigned long) sp->badfaxrun);
+	if (sp->printdir)
+		(*sp->printdir)(tif, fd, flags);
+}
+
+static int
+InitCCITTFax3(TIFF* tif)
+{
+	static const char module[] = "InitCCITTFax3";
+	Fax3BaseState* sp;
+
+	/*
+	 * Merge codec-specific tag information.
+	 */
+	if (!_TIFFMergeFields(tif, faxFields, TIFFArrayCount(faxFields))) {
+		TIFFErrorExt(tif->tif_clientdata, "InitCCITTFax3",
+			"Merging common CCITT Fax codec-specific tags failed");
+		return 0;
+	}
+
+	/*
+	 * Allocate state block so tag methods have storage to record values.
+	 */
+	tif->tif_data = (uint8*)
+		_TIFFmalloc(sizeof (Fax3CodecState));
+
+	if (tif->tif_data == NULL) {
+		TIFFErrorExt(tif->tif_clientdata, module,
+		    "No space for state block");
+		return (0);
+	}
+
+	sp = Fax3State(tif);
+        sp->rw_mode = tif->tif_mode;
+
+	/*
+	 * Override parent get/set field methods.
+	 */
+	sp->vgetparent = tif->tif_tagmethods.vgetfield;
+	tif->tif_tagmethods.vgetfield = Fax3VGetField; /* hook for codec tags */
+	sp->vsetparent = tif->tif_tagmethods.vsetfield;
+	tif->tif_tagmethods.vsetfield = Fax3VSetField; /* hook for codec tags */
+	sp->printdir = tif->tif_tagmethods.printdir;
+	tif->tif_tagmethods.printdir = Fax3PrintDir;   /* hook for codec tags */
+	sp->groupoptions = 0;	
+
+	if (sp->rw_mode == O_RDONLY) /* FIXME: improve for in place update */
+		tif->tif_flags |= TIFF_NOBITREV; /* decoder does bit reversal */
+	DecoderState(tif)->runs = NULL;
+	TIFFSetField(tif, TIFFTAG_FAXFILLFUNC, _TIFFFax3fillruns);
+	EncoderState(tif)->refline = NULL;
+
+	/*
+	 * Install codec methods.
+	 */
+	tif->tif_fixuptags = Fax3FixupTags;
+	tif->tif_setupdecode = Fax3SetupState;
+	tif->tif_predecode = Fax3PreDecode;
+	tif->tif_decoderow = Fax3Decode1D;
+	tif->tif_decodestrip = Fax3Decode1D;
+	tif->tif_decodetile = Fax3Decode1D;
+	tif->tif_setupencode = Fax3SetupState;
+	tif->tif_preencode = Fax3PreEncode;
+	tif->tif_postencode = Fax3PostEncode;
+	tif->tif_encoderow = Fax3Encode;
+	tif->tif_encodestrip = Fax3Encode;
+	tif->tif_encodetile = Fax3Encode;
+	tif->tif_close = Fax3Close;
+	tif->tif_cleanup = Fax3Cleanup;
+
+	return (1);
+}
+
+int
+TIFFInitCCITTFax3(TIFF* tif, int scheme)
+{
+	(void) scheme;
+	if (InitCCITTFax3(tif)) {
+		/*
+		 * Merge codec-specific tag information.
+		 */
+		if (!_TIFFMergeFields(tif, fax3Fields,
+				      TIFFArrayCount(fax3Fields))) {
+			TIFFErrorExt(tif->tif_clientdata, "TIFFInitCCITTFax3",
+			"Merging CCITT Fax 3 codec-specific tags failed");
+			return 0;
+		}
+
+		/*
+		 * The default format is Class/F-style w/o RTC.
+		 */
+		return TIFFSetField(tif, TIFFTAG_FAXMODE, FAXMODE_CLASSF);
+	} else
+		return 01;
+}
+
+/*
+ * CCITT Group 4 (T.6) Facsimile-compatible
+ * Compression Scheme Support.
+ */
+
+#define SWAP(t,a,b) { t x; x = (a); (a) = (b); (b) = x; }
+/*
+ * Decode the requested amount of G4-encoded data.
+ */
+static int
+Fax4Decode(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s)
+{
+	DECLARE_STATE_2D(tif, sp, "Fax4Decode");
+	(void) s;
+	if (occ % sp->b.rowbytes)
+	{
+		TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read");
+		return (-1);
+	}
+	CACHE_STATE(tif, sp);
+	while (occ > 0) {
+		a0 = 0;
+		RunLength = 0;
+		pa = thisrun = sp->curruns;
+		pb = sp->refruns;
+		b1 = *pb++;
+#ifdef FAX3_DEBUG
+		printf("\nBitAcc=%08X, BitsAvail = %d\n", BitAcc, BitsAvail);
+		printf("-------------------- %d\n", tif->tif_row);
+		fflush(stdout);
+#endif
+		EXPAND2D(EOFG4);
+                if (EOLcnt)
+                    goto EOFG4;
+		(*sp->fill)(buf, thisrun, pa, lastx);
+		SETVALUE(0);		/* imaginary change for reference */
+		SWAP(uint32*, sp->curruns, sp->refruns);
+		buf += sp->b.rowbytes;
+		occ -= sp->b.rowbytes;
+		sp->line++;
+		continue;
+	EOFG4:
+                NeedBits16( 13, BADG4 );
+        BADG4:
+#ifdef FAX3_DEBUG
+                if( GetBits(13) != 0x1001 )
+                    fputs( "Bad EOFB\n", stderr );
+#endif                
+                ClrBits( 13 );
+		(*sp->fill)(buf, thisrun, pa, lastx);
+		UNCACHE_STATE(tif, sp);
+		return ( sp->line ? 1 : -1);	/* don't error on badly-terminated strips */
+	}
+	UNCACHE_STATE(tif, sp);
+	return (1);
+}
+#undef	SWAP
+
+/*
+ * Encode the requested amount of data.
+ */
+static int
+Fax4Encode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
+{
+	static const char module[] = "Fax4Encode";
+	Fax3CodecState *sp = EncoderState(tif);
+	(void) s;
+	if (cc % sp->b.rowbytes)
+	{
+		TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be written");
+		return (0);
+	}
+	while (cc > 0) {
+		if (!Fax3Encode2DRow(tif, bp, sp->refline, sp->b.rowpixels))
+			return (0);
+		_TIFFmemcpy(sp->refline, bp, sp->b.rowbytes);
+		bp += sp->b.rowbytes;
+		cc -= sp->b.rowbytes;
+	}
+	return (1);
+}
+
+static int
+Fax4PostEncode(TIFF* tif)
+{
+	Fax3CodecState *sp = EncoderState(tif);
+
+	/* terminate strip w/ EOFB */
+	Fax3PutBits(tif, EOL, 12);
+	Fax3PutBits(tif, EOL, 12);
+	if (sp->bit != 8)
+		Fax3FlushBits(tif, sp);
+	return (1);
+}
+
+int
+TIFFInitCCITTFax4(TIFF* tif, int scheme)
+{
+	(void) scheme;
+	if (InitCCITTFax3(tif)) {		/* reuse G3 support */
+		/*
+		 * Merge codec-specific tag information.
+		 */
+		if (!_TIFFMergeFields(tif, fax4Fields,
+				      TIFFArrayCount(fax4Fields))) {
+			TIFFErrorExt(tif->tif_clientdata, "TIFFInitCCITTFax4",
+			"Merging CCITT Fax 4 codec-specific tags failed");
+			return 0;
+		}
+
+		tif->tif_decoderow = Fax4Decode;
+		tif->tif_decodestrip = Fax4Decode;
+		tif->tif_decodetile = Fax4Decode;
+		tif->tif_encoderow = Fax4Encode;
+		tif->tif_encodestrip = Fax4Encode;
+		tif->tif_encodetile = Fax4Encode;
+		tif->tif_postencode = Fax4PostEncode;
+		/*
+		 * Suppress RTC at the end of each strip.
+		 */
+		return TIFFSetField(tif, TIFFTAG_FAXMODE, FAXMODE_NORTC);
+	} else
+		return (0);
+}
+
+/*
+ * CCITT Group 3 1-D Modified Huffman RLE Compression Support.
+ * (Compression algorithms 2 and 32771)
+ */
+
+/*
+ * Decode the requested amount of RLE-encoded data.
+ */
+static int
+Fax3DecodeRLE(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s)
+{
+	DECLARE_STATE(tif, sp, "Fax3DecodeRLE");
+	int mode = sp->b.mode;
+	(void) s;
+	if (occ % sp->b.rowbytes)
+	{
+		TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read");
+		return (-1);
+	}
+	CACHE_STATE(tif, sp);
+	thisrun = sp->curruns;
+	while (occ > 0) {
+		a0 = 0;
+		RunLength = 0;
+		pa = thisrun;
+#ifdef FAX3_DEBUG
+		printf("\nBitAcc=%08X, BitsAvail = %d\n", BitAcc, BitsAvail);
+		printf("-------------------- %d\n", tif->tif_row);
+		fflush(stdout);
+#endif
+		EXPAND1D(EOFRLE);
+		(*sp->fill)(buf, thisrun, pa, lastx);
+		/*
+		 * Cleanup at the end of the row.
+		 */
+		if (mode & FAXMODE_BYTEALIGN) {
+			int n = BitsAvail - (BitsAvail &~ 7);
+			ClrBits(n);
+		} else if (mode & FAXMODE_WORDALIGN) {
+			int n = BitsAvail - (BitsAvail &~ 15);
+			ClrBits(n);
+			if (BitsAvail == 0 && !isAligned(cp, uint16))
+			    cp++;
+		}
+		buf += sp->b.rowbytes;
+		occ -= sp->b.rowbytes;
+		sp->line++;
+		continue;
+	EOFRLE:				/* premature EOF */
+		(*sp->fill)(buf, thisrun, pa, lastx);
+		UNCACHE_STATE(tif, sp);
+		return (-1);
+	}
+	UNCACHE_STATE(tif, sp);
+	return (1);
+}
+
+int
+TIFFInitCCITTRLE(TIFF* tif, int scheme)
+{
+	(void) scheme;
+	if (InitCCITTFax3(tif)) {		/* reuse G3 support */
+		tif->tif_decoderow = Fax3DecodeRLE;
+		tif->tif_decodestrip = Fax3DecodeRLE;
+		tif->tif_decodetile = Fax3DecodeRLE;
+		/*
+		 * Suppress RTC+EOLs when encoding and byte-align data.
+		 */
+		return TIFFSetField(tif, TIFFTAG_FAXMODE,
+		    FAXMODE_NORTC|FAXMODE_NOEOL|FAXMODE_BYTEALIGN);
+	} else
+		return (0);
+}
+
+int
+TIFFInitCCITTRLEW(TIFF* tif, int scheme)
+{
+	(void) scheme;
+	if (InitCCITTFax3(tif)) {		/* reuse G3 support */
+		tif->tif_decoderow = Fax3DecodeRLE;
+		tif->tif_decodestrip = Fax3DecodeRLE;
+		tif->tif_decodetile = Fax3DecodeRLE;  
+		/*
+		 * Suppress RTC+EOLs when encoding and word-align data.
+		 */
+		return TIFFSetField(tif, TIFFTAG_FAXMODE,
+		    FAXMODE_NORTC|FAXMODE_NOEOL|FAXMODE_WORDALIGN);
+	} else
+		return (0);
+}
+#endif /* CCITT_SUPPORT */
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tif_fax3.h b/Source/LibTIFF4/tif_fax3.h
index fd304c9..7712c55 100644
--- a/Source/LibTIFF4/tif_fax3.h
+++ b/Source/LibTIFF4/tif_fax3.h
@@ -1,538 +1,538 @@
-/* $Id: tif_fax3.h,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * Copyright (c) 1990-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-#ifndef _FAX3_
-#define	_FAX3_
-/*
- * TIFF Library.
- *
- * CCITT Group 3 (T.4) and Group 4 (T.6) Decompression Support.
- *
- * Decoder support is derived, with permission, from the code
- * in Frank Cringle's viewfax program;
- *      Copyright (C) 1990, 1995  Frank D. Cringle.
- */
-#include "tiff.h"
-
-/*
- * To override the default routine used to image decoded
- * spans one can use the pseduo tag TIFFTAG_FAXFILLFUNC.
- * The routine must have the type signature given below;
- * for example:
- *
- * fillruns(unsigned char* buf, uint32* runs, uint32* erun, uint32 lastx)
- *
- * where buf is place to set the bits, runs is the array of b&w run
- * lengths (white then black), erun is the last run in the array, and
- * lastx is the width of the row in pixels.  Fill routines can assume
- * the run array has room for at least lastx runs and can overwrite
- * data in the run array as needed (e.g. to append zero runs to bring
- * the count up to a nice multiple).
- */
-typedef void (*TIFFFaxFillFunc)(unsigned char*, uint32*, uint32*, uint32);
-
-/*
- * The default run filler; made external for other decoders.
- */
-#if defined(__cplusplus)
-extern "C" {
-#endif
-extern void _TIFFFax3fillruns(unsigned char*, uint32*, uint32*, uint32);
-#if defined(__cplusplus)
-}
-#endif
-
-
-/* finite state machine codes */
-#define S_Null     0
-#define S_Pass     1
-#define S_Horiz    2
-#define S_V0       3
-#define S_VR       4
-#define S_VL       5
-#define S_Ext      6
-#define S_TermW    7
-#define S_TermB    8
-#define S_MakeUpW  9
-#define S_MakeUpB  10
-#define S_MakeUp   11
-#define S_EOL      12
-
-typedef struct {                /* state table entry */
-	unsigned char State;    /* see above */
-	unsigned char Width;    /* width of code in bits */
-	uint32 Param;           /* unsigned 32-bit run length in bits */
-} TIFFFaxTabEnt;
-
-extern const TIFFFaxTabEnt TIFFFaxMainTable[];
-extern const TIFFFaxTabEnt TIFFFaxWhiteTable[];
-extern const TIFFFaxTabEnt TIFFFaxBlackTable[];
-
-/*
- * The following macros define the majority of the G3/G4 decoder
- * algorithm using the state tables defined elsewhere.  To build
- * a decoder you need some setup code and some glue code. Note
- * that you may also need/want to change the way the NeedBits*
- * macros get input data if, for example, you know the data to be
- * decoded is properly aligned and oriented (doing so before running
- * the decoder can be a big performance win).
- *
- * Consult the decoder in the TIFF library for an idea of what you
- * need to define and setup to make use of these definitions.
- *
- * NB: to enable a debugging version of these macros define FAX3_DEBUG
- *     before including this file.  Trace output goes to stdout.
- */
-
-#ifndef EndOfData
-#define EndOfData()	(cp >= ep)
-#endif
-/*
- * Need <=8 or <=16 bits of input data.  Unlike viewfax we
- * cannot use/assume a word-aligned, properly bit swizzled
- * input data set because data may come from an arbitrarily
- * aligned, read-only source such as a memory-mapped file.
- * Note also that the viewfax decoder does not check for
- * running off the end of the input data buffer.  This is
- * possible for G3-encoded data because it prescans the input
- * data to count EOL markers, but can cause problems for G4
- * data.  In any event, we don't prescan and must watch for
- * running out of data since we can't permit the library to
- * scan past the end of the input data buffer.
- *
- * Finally, note that we must handle remaindered data at the end
- * of a strip specially.  The coder asks for a fixed number of
- * bits when scanning for the next code.  This may be more bits
- * than are actually present in the data stream.  If we appear
- * to run out of data but still have some number of valid bits
- * remaining then we makeup the requested amount with zeros and
- * return successfully.  If the returned data is incorrect then
- * we should be called again and get a premature EOF error;
- * otherwise we should get the right answer.
- */
-#ifndef NeedBits8
-#define NeedBits8(n,eoflab) do {					\
-    if (BitsAvail < (n)) {						\
-	if (EndOfData()) {						\
-	    if (BitsAvail == 0)			/* no valid bits */	\
-		goto eoflab;						\
-	    BitsAvail = (n);			/* pad with zeros */	\
-	} else {							\
-	    BitAcc |= ((uint32) bitmap[*cp++])<<BitsAvail;		\
-	    BitsAvail += 8;						\
-	}								\
-    }									\
-} while (0)
-#endif
-#ifndef NeedBits16
-#define NeedBits16(n,eoflab) do {					\
-    if (BitsAvail < (n)) {						\
-	if (EndOfData()) {						\
-	    if (BitsAvail == 0)			/* no valid bits */	\
-		goto eoflab;						\
-	    BitsAvail = (n);			/* pad with zeros */	\
-	} else {							\
-	    BitAcc |= ((uint32) bitmap[*cp++])<<BitsAvail;		\
-	    if ((BitsAvail += 8) < (n)) {				\
-		if (EndOfData()) {					\
-		    /* NB: we know BitsAvail is non-zero here */	\
-		    BitsAvail = (n);		/* pad with zeros */	\
-		} else {						\
-		    BitAcc |= ((uint32) bitmap[*cp++])<<BitsAvail;	\
-		    BitsAvail += 8;					\
-		}							\
-	    }								\
-	}								\
-    }									\
-} while (0)
-#endif
-#define GetBits(n)	(BitAcc & ((1<<(n))-1))
-#define ClrBits(n) do {							\
-    BitsAvail -= (n);							\
-    BitAcc >>= (n);							\
-} while (0)
-
-#ifdef FAX3_DEBUG
-static const char* StateNames[] = {
-    "Null   ",
-    "Pass   ",
-    "Horiz  ",
-    "V0     ",
-    "VR     ",
-    "VL     ",
-    "Ext    ",
-    "TermW  ",
-    "TermB  ",
-    "MakeUpW",
-    "MakeUpB",
-    "MakeUp ",
-    "EOL    ",
-};
-#define DEBUG_SHOW putchar(BitAcc & (1 << t) ? '1' : '0')
-#define LOOKUP8(wid,tab,eoflab) do {					\
-    int t;								\
-    NeedBits8(wid,eoflab);						\
-    TabEnt = tab + GetBits(wid);					\
-    printf("%08lX/%d: %s%5d\t", (long) BitAcc, BitsAvail,		\
-	   StateNames[TabEnt->State], TabEnt->Param);			\
-    for (t = 0; t < TabEnt->Width; t++)					\
-	DEBUG_SHOW;							\
-    putchar('\n');							\
-    fflush(stdout);							\
-    ClrBits(TabEnt->Width);						\
-} while (0)
-#define LOOKUP16(wid,tab,eoflab) do {					\
-    int t;								\
-    NeedBits16(wid,eoflab);						\
-    TabEnt = tab + GetBits(wid);					\
-    printf("%08lX/%d: %s%5d\t", (long) BitAcc, BitsAvail,		\
-	   StateNames[TabEnt->State], TabEnt->Param);			\
-    for (t = 0; t < TabEnt->Width; t++)					\
-	DEBUG_SHOW;							\
-    putchar('\n');							\
-    fflush(stdout);							\
-    ClrBits(TabEnt->Width);						\
-} while (0)
-
-#define SETVALUE(x) do {							\
-    *pa++ = RunLength + (x);						\
-    printf("SETVALUE: %d\t%d\n", RunLength + (x), a0);			\
-    a0 += x;								\
-    RunLength = 0;							\
-} while (0)
-#else
-#define LOOKUP8(wid,tab,eoflab) do {					\
-    NeedBits8(wid,eoflab);						\
-    TabEnt = tab + GetBits(wid);					\
-    ClrBits(TabEnt->Width);						\
-} while (0)
-#define LOOKUP16(wid,tab,eoflab) do {					\
-    NeedBits16(wid,eoflab);						\
-    TabEnt = tab + GetBits(wid);					\
-    ClrBits(TabEnt->Width);						\
-} while (0)
-
-/*
- * Append a run to the run length array for the
- * current row and reset decoding state.
- */
-#define SETVALUE(x) do {							\
-    *pa++ = RunLength + (x);						\
-    a0 += (x);								\
-    RunLength = 0;							\
-} while (0)
-#endif
-
-/*
- * Synchronize input decoding at the start of each
- * row by scanning for an EOL (if appropriate) and
- * skipping any trash data that might be present
- * after a decoding error.  Note that the decoding
- * done elsewhere that recognizes an EOL only consumes
- * 11 consecutive zero bits.  This means that if EOLcnt
- * is non-zero then we still need to scan for the final flag
- * bit that is part of the EOL code.
- */
-#define	SYNC_EOL(eoflab) do {						\
-    if (EOLcnt == 0) {							\
-	for (;;) {							\
-	    NeedBits16(11,eoflab);					\
-	    if (GetBits(11) == 0)					\
-		break;							\
-	    ClrBits(1);							\
-	}								\
-    }									\
-    for (;;) {								\
-	NeedBits8(8,eoflab);						\
-	if (GetBits(8))							\
-	    break;							\
-	ClrBits(8);							\
-    }									\
-    while (GetBits(1) == 0)						\
-	ClrBits(1);							\
-    ClrBits(1);				/* EOL bit */			\
-    EOLcnt = 0;				/* reset EOL counter/flag */	\
-} while (0)
-
-/*
- * Cleanup the array of runs after decoding a row.
- * We adjust final runs to insure the user buffer is not
- * overwritten and/or undecoded area is white filled.
- */
-#define	CLEANUP_RUNS() do {						\
-    if (RunLength)							\
-	SETVALUE(0);							\
-    if (a0 != lastx) {							\
-	badlength(a0, lastx);						\
-	while (a0 > lastx && pa > thisrun)				\
-	    a0 -= *--pa;						\
-	if (a0 < lastx) {						\
-	    if (a0 < 0)							\
-		a0 = 0;							\
-	    if ((pa-thisrun)&1)						\
-		SETVALUE(0);						\
-	    SETVALUE(lastx - a0);						\
-	} else if (a0 > lastx) {					\
-	    SETVALUE(lastx);						\
-	    SETVALUE(0);							\
-	}								\
-    }									\
-} while (0)
-
-/*
- * Decode a line of 1D-encoded data.
- *
- * The line expanders are written as macros so that they can be reused
- * but still have direct access to the local variables of the "calling"
- * function.
- *
- * Note that unlike the original version we have to explicitly test for
- * a0 >= lastx after each black/white run is decoded.  This is because
- * the original code depended on the input data being zero-padded to
- * insure the decoder recognized an EOL before running out of data.
- */
-#define EXPAND1D(eoflab) do {						\
-    for (;;) {								\
-	for (;;) {							\
-	    LOOKUP16(12, TIFFFaxWhiteTable, eof1d);			\
-	    switch (TabEnt->State) {					\
-	    case S_EOL:							\
-		EOLcnt = 1;						\
-		goto done1d;						\
-	    case S_TermW:						\
-		SETVALUE(TabEnt->Param);					\
-		goto doneWhite1d;					\
-	    case S_MakeUpW:						\
-	    case S_MakeUp:						\
-		a0 += TabEnt->Param;					\
-		RunLength += TabEnt->Param;				\
-		break;							\
-	    default:							\
-		unexpected("WhiteTable", a0);				\
-		goto done1d;						\
-	    }								\
-	}								\
-    doneWhite1d:							\
-	if (a0 >= lastx)						\
-	    goto done1d;						\
-	for (;;) {							\
-	    LOOKUP16(13, TIFFFaxBlackTable, eof1d);			\
-	    switch (TabEnt->State) {					\
-	    case S_EOL:							\
-		EOLcnt = 1;						\
-		goto done1d;						\
-	    case S_TermB:						\
-		SETVALUE(TabEnt->Param);					\
-		goto doneBlack1d;					\
-	    case S_MakeUpB:						\
-	    case S_MakeUp:						\
-		a0 += TabEnt->Param;					\
-		RunLength += TabEnt->Param;				\
-		break;							\
-	    default:							\
-		unexpected("BlackTable", a0);				\
-		goto done1d;						\
-	    }								\
-	}								\
-    doneBlack1d:							\
-	if (a0 >= lastx)						\
-	    goto done1d;						\
-        if( *(pa-1) == 0 && *(pa-2) == 0 )				\
-            pa -= 2;                                                    \
-    }									\
-eof1d:									\
-    prematureEOF(a0);							\
-    CLEANUP_RUNS();							\
-    goto eoflab;							\
-done1d:									\
-    CLEANUP_RUNS();							\
-} while (0)
-
-/*
- * Update the value of b1 using the array
- * of runs for the reference line.
- */
-#define CHECK_b1 do {							\
-    if (pa != thisrun) while (b1 <= a0 && b1 < lastx) {			\
-	b1 += pb[0] + pb[1];						\
-	pb += 2;							\
-    }									\
-} while (0)
-
-/*
- * Expand a row of 2D-encoded data.
- */
-#define EXPAND2D(eoflab) do {						\
-    while (a0 < lastx) {						\
-	LOOKUP8(7, TIFFFaxMainTable, eof2d);				\
-	switch (TabEnt->State) {					\
-	case S_Pass:							\
-	    CHECK_b1;							\
-	    b1 += *pb++;						\
-	    RunLength += b1 - a0;					\
-	    a0 = b1;							\
-	    b1 += *pb++;						\
-	    break;							\
-	case S_Horiz:							\
-	    if ((pa-thisrun)&1) {					\
-		for (;;) {	/* black first */			\
-		    LOOKUP16(13, TIFFFaxBlackTable, eof2d);		\
-		    switch (TabEnt->State) {				\
-		    case S_TermB:					\
-			SETVALUE(TabEnt->Param);				\
-			goto doneWhite2da;				\
-		    case S_MakeUpB:					\
-		    case S_MakeUp:					\
-			a0 += TabEnt->Param;				\
-			RunLength += TabEnt->Param;			\
-			break;						\
-		    default:						\
-			goto badBlack2d;				\
-		    }							\
-		}							\
-	    doneWhite2da:;						\
-		for (;;) {	/* then white */			\
-		    LOOKUP16(12, TIFFFaxWhiteTable, eof2d);		\
-		    switch (TabEnt->State) {				\
-		    case S_TermW:					\
-			SETVALUE(TabEnt->Param);				\
-			goto doneBlack2da;				\
-		    case S_MakeUpW:					\
-		    case S_MakeUp:					\
-			a0 += TabEnt->Param;				\
-			RunLength += TabEnt->Param;			\
-			break;						\
-		    default:						\
-			goto badWhite2d;				\
-		    }							\
-		}							\
-	    doneBlack2da:;						\
-	    } else {							\
-		for (;;) {	/* white first */			\
-		    LOOKUP16(12, TIFFFaxWhiteTable, eof2d);		\
-		    switch (TabEnt->State) {				\
-		    case S_TermW:					\
-			SETVALUE(TabEnt->Param);				\
-			goto doneWhite2db;				\
-		    case S_MakeUpW:					\
-		    case S_MakeUp:					\
-			a0 += TabEnt->Param;				\
-			RunLength += TabEnt->Param;			\
-			break;						\
-		    default:						\
-			goto badWhite2d;				\
-		    }							\
-		}							\
-	    doneWhite2db:;						\
-		for (;;) {	/* then black */			\
-		    LOOKUP16(13, TIFFFaxBlackTable, eof2d);		\
-		    switch (TabEnt->State) {				\
-		    case S_TermB:					\
-			SETVALUE(TabEnt->Param);				\
-			goto doneBlack2db;				\
-		    case S_MakeUpB:					\
-		    case S_MakeUp:					\
-			a0 += TabEnt->Param;				\
-			RunLength += TabEnt->Param;			\
-			break;						\
-		    default:						\
-			goto badBlack2d;				\
-		    }							\
-		}							\
-	    doneBlack2db:;						\
-	    }								\
-	    CHECK_b1;							\
-	    break;							\
-	case S_V0:							\
-	    CHECK_b1;							\
-	    SETVALUE(b1 - a0);						\
-	    b1 += *pb++;						\
-	    break;							\
-	case S_VR:							\
-	    CHECK_b1;							\
-	    SETVALUE(b1 - a0 + TabEnt->Param);				\
-	    b1 += *pb++;						\
-	    break;							\
-	case S_VL:							\
-	    CHECK_b1;							\
-	    if (b1 <= (int) (a0 + TabEnt->Param)) {			\
-		if (b1 < (int) (a0 + TabEnt->Param) || pa != thisrun) {	\
-		    unexpected("VL", a0);				\
-		    goto eol2d;						\
-		}							\
-	    }								\
-	    SETVALUE(b1 - a0 - TabEnt->Param);				\
-	    b1 -= *--pb;						\
-	    break;							\
-	case S_Ext:							\
-	    *pa++ = lastx - a0;						\
-	    extension(a0);						\
-	    goto eol2d;							\
-	case S_EOL:							\
-	    *pa++ = lastx - a0;						\
-	    NeedBits8(4,eof2d);						\
-	    if (GetBits(4))						\
-		unexpected("EOL", a0);					\
-            ClrBits(4);                                                 \
-	    EOLcnt = 1;							\
-	    goto eol2d;							\
-	default:							\
-	badMain2d:							\
-	    unexpected("MainTable", a0);				\
-	    goto eol2d;							\
-	badBlack2d:							\
-	    unexpected("BlackTable", a0);				\
-	    goto eol2d;							\
-	badWhite2d:							\
-	    unexpected("WhiteTable", a0);				\
-	    goto eol2d;							\
-	eof2d:								\
-	    prematureEOF(a0);						\
-	    CLEANUP_RUNS();						\
-	    goto eoflab;						\
-	}								\
-    }									\
-    if (RunLength) {							\
-	if (RunLength + a0 < lastx) {					\
-	    /* expect a final V0 */					\
-	    NeedBits8(1,eof2d);						\
-	    if (!GetBits(1))						\
-		goto badMain2d;						\
-	    ClrBits(1);							\
-	}								\
-	SETVALUE(0);							\
-    }									\
-eol2d:									\
-    CLEANUP_RUNS();							\
-} while (0)
-#endif /* _FAX3_ */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Id: tif_fax3.h,v 1.11 2015/02/19 22:39:58 drolon Exp $ */
+
+/*
+ * Copyright (c) 1990-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and 
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
+ * 
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef _FAX3_
+#define	_FAX3_
+/*
+ * TIFF Library.
+ *
+ * CCITT Group 3 (T.4) and Group 4 (T.6) Decompression Support.
+ *
+ * Decoder support is derived, with permission, from the code
+ * in Frank Cringle's viewfax program;
+ *      Copyright (C) 1990, 1995  Frank D. Cringle.
+ */
+#include "tiff.h"
+
+/*
+ * To override the default routine used to image decoded
+ * spans one can use the pseduo tag TIFFTAG_FAXFILLFUNC.
+ * The routine must have the type signature given below;
+ * for example:
+ *
+ * fillruns(unsigned char* buf, uint32* runs, uint32* erun, uint32 lastx)
+ *
+ * where buf is place to set the bits, runs is the array of b&w run
+ * lengths (white then black), erun is the last run in the array, and
+ * lastx is the width of the row in pixels.  Fill routines can assume
+ * the run array has room for at least lastx runs and can overwrite
+ * data in the run array as needed (e.g. to append zero runs to bring
+ * the count up to a nice multiple).
+ */
+typedef void (*TIFFFaxFillFunc)(unsigned char*, uint32*, uint32*, uint32);
+
+/*
+ * The default run filler; made external for other decoders.
+ */
+#if defined(__cplusplus)
+extern "C" {
+#endif
+extern void _TIFFFax3fillruns(unsigned char*, uint32*, uint32*, uint32);
+#if defined(__cplusplus)
+}
+#endif
+
+
+/* finite state machine codes */
+#define S_Null     0
+#define S_Pass     1
+#define S_Horiz    2
+#define S_V0       3
+#define S_VR       4
+#define S_VL       5
+#define S_Ext      6
+#define S_TermW    7
+#define S_TermB    8
+#define S_MakeUpW  9
+#define S_MakeUpB  10
+#define S_MakeUp   11
+#define S_EOL      12
+
+typedef struct {                /* state table entry */
+	unsigned char State;    /* see above */
+	unsigned char Width;    /* width of code in bits */
+	uint32 Param;           /* unsigned 32-bit run length in bits */
+} TIFFFaxTabEnt;
+
+extern const TIFFFaxTabEnt TIFFFaxMainTable[];
+extern const TIFFFaxTabEnt TIFFFaxWhiteTable[];
+extern const TIFFFaxTabEnt TIFFFaxBlackTable[];
+
+/*
+ * The following macros define the majority of the G3/G4 decoder
+ * algorithm using the state tables defined elsewhere.  To build
+ * a decoder you need some setup code and some glue code. Note
+ * that you may also need/want to change the way the NeedBits*
+ * macros get input data if, for example, you know the data to be
+ * decoded is properly aligned and oriented (doing so before running
+ * the decoder can be a big performance win).
+ *
+ * Consult the decoder in the TIFF library for an idea of what you
+ * need to define and setup to make use of these definitions.
+ *
+ * NB: to enable a debugging version of these macros define FAX3_DEBUG
+ *     before including this file.  Trace output goes to stdout.
+ */
+
+#ifndef EndOfData
+#define EndOfData()	(cp >= ep)
+#endif
+/*
+ * Need <=8 or <=16 bits of input data.  Unlike viewfax we
+ * cannot use/assume a word-aligned, properly bit swizzled
+ * input data set because data may come from an arbitrarily
+ * aligned, read-only source such as a memory-mapped file.
+ * Note also that the viewfax decoder does not check for
+ * running off the end of the input data buffer.  This is
+ * possible for G3-encoded data because it prescans the input
+ * data to count EOL markers, but can cause problems for G4
+ * data.  In any event, we don't prescan and must watch for
+ * running out of data since we can't permit the library to
+ * scan past the end of the input data buffer.
+ *
+ * Finally, note that we must handle remaindered data at the end
+ * of a strip specially.  The coder asks for a fixed number of
+ * bits when scanning for the next code.  This may be more bits
+ * than are actually present in the data stream.  If we appear
+ * to run out of data but still have some number of valid bits
+ * remaining then we makeup the requested amount with zeros and
+ * return successfully.  If the returned data is incorrect then
+ * we should be called again and get a premature EOF error;
+ * otherwise we should get the right answer.
+ */
+#ifndef NeedBits8
+#define NeedBits8(n,eoflab) do {					\
+    if (BitsAvail < (n)) {						\
+	if (EndOfData()) {						\
+	    if (BitsAvail == 0)			/* no valid bits */	\
+		goto eoflab;						\
+	    BitsAvail = (n);			/* pad with zeros */	\
+	} else {							\
+	    BitAcc |= ((uint32) bitmap[*cp++])<<BitsAvail;		\
+	    BitsAvail += 8;						\
+	}								\
+    }									\
+} while (0)
+#endif
+#ifndef NeedBits16
+#define NeedBits16(n,eoflab) do {					\
+    if (BitsAvail < (n)) {						\
+	if (EndOfData()) {						\
+	    if (BitsAvail == 0)			/* no valid bits */	\
+		goto eoflab;						\
+	    BitsAvail = (n);			/* pad with zeros */	\
+	} else {							\
+	    BitAcc |= ((uint32) bitmap[*cp++])<<BitsAvail;		\
+	    if ((BitsAvail += 8) < (n)) {				\
+		if (EndOfData()) {					\
+		    /* NB: we know BitsAvail is non-zero here */	\
+		    BitsAvail = (n);		/* pad with zeros */	\
+		} else {						\
+		    BitAcc |= ((uint32) bitmap[*cp++])<<BitsAvail;	\
+		    BitsAvail += 8;					\
+		}							\
+	    }								\
+	}								\
+    }									\
+} while (0)
+#endif
+#define GetBits(n)	(BitAcc & ((1<<(n))-1))
+#define ClrBits(n) do {							\
+    BitsAvail -= (n);							\
+    BitAcc >>= (n);							\
+} while (0)
+
+#ifdef FAX3_DEBUG
+static const char* StateNames[] = {
+    "Null   ",
+    "Pass   ",
+    "Horiz  ",
+    "V0     ",
+    "VR     ",
+    "VL     ",
+    "Ext    ",
+    "TermW  ",
+    "TermB  ",
+    "MakeUpW",
+    "MakeUpB",
+    "MakeUp ",
+    "EOL    ",
+};
+#define DEBUG_SHOW putchar(BitAcc & (1 << t) ? '1' : '0')
+#define LOOKUP8(wid,tab,eoflab) do {					\
+    int t;								\
+    NeedBits8(wid,eoflab);						\
+    TabEnt = tab + GetBits(wid);					\
+    printf("%08lX/%d: %s%5d\t", (long) BitAcc, BitsAvail,		\
+	   StateNames[TabEnt->State], TabEnt->Param);			\
+    for (t = 0; t < TabEnt->Width; t++)					\
+	DEBUG_SHOW;							\
+    putchar('\n');							\
+    fflush(stdout);							\
+    ClrBits(TabEnt->Width);						\
+} while (0)
+#define LOOKUP16(wid,tab,eoflab) do {					\
+    int t;								\
+    NeedBits16(wid,eoflab);						\
+    TabEnt = tab + GetBits(wid);					\
+    printf("%08lX/%d: %s%5d\t", (long) BitAcc, BitsAvail,		\
+	   StateNames[TabEnt->State], TabEnt->Param);			\
+    for (t = 0; t < TabEnt->Width; t++)					\
+	DEBUG_SHOW;							\
+    putchar('\n');							\
+    fflush(stdout);							\
+    ClrBits(TabEnt->Width);						\
+} while (0)
+
+#define SETVALUE(x) do {							\
+    *pa++ = RunLength + (x);						\
+    printf("SETVALUE: %d\t%d\n", RunLength + (x), a0);			\
+    a0 += x;								\
+    RunLength = 0;							\
+} while (0)
+#else
+#define LOOKUP8(wid,tab,eoflab) do {					\
+    NeedBits8(wid,eoflab);						\
+    TabEnt = tab + GetBits(wid);					\
+    ClrBits(TabEnt->Width);						\
+} while (0)
+#define LOOKUP16(wid,tab,eoflab) do {					\
+    NeedBits16(wid,eoflab);						\
+    TabEnt = tab + GetBits(wid);					\
+    ClrBits(TabEnt->Width);						\
+} while (0)
+
+/*
+ * Append a run to the run length array for the
+ * current row and reset decoding state.
+ */
+#define SETVALUE(x) do {							\
+    *pa++ = RunLength + (x);						\
+    a0 += (x);								\
+    RunLength = 0;							\
+} while (0)
+#endif
+
+/*
+ * Synchronize input decoding at the start of each
+ * row by scanning for an EOL (if appropriate) and
+ * skipping any trash data that might be present
+ * after a decoding error.  Note that the decoding
+ * done elsewhere that recognizes an EOL only consumes
+ * 11 consecutive zero bits.  This means that if EOLcnt
+ * is non-zero then we still need to scan for the final flag
+ * bit that is part of the EOL code.
+ */
+#define	SYNC_EOL(eoflab) do {						\
+    if (EOLcnt == 0) {							\
+	for (;;) {							\
+	    NeedBits16(11,eoflab);					\
+	    if (GetBits(11) == 0)					\
+		break;							\
+	    ClrBits(1);							\
+	}								\
+    }									\
+    for (;;) {								\
+	NeedBits8(8,eoflab);						\
+	if (GetBits(8))							\
+	    break;							\
+	ClrBits(8);							\
+    }									\
+    while (GetBits(1) == 0)						\
+	ClrBits(1);							\
+    ClrBits(1);				/* EOL bit */			\
+    EOLcnt = 0;				/* reset EOL counter/flag */	\
+} while (0)
+
+/*
+ * Cleanup the array of runs after decoding a row.
+ * We adjust final runs to insure the user buffer is not
+ * overwritten and/or undecoded area is white filled.
+ */
+#define	CLEANUP_RUNS() do {						\
+    if (RunLength)							\
+	SETVALUE(0);							\
+    if (a0 != lastx) {							\
+	badlength(a0, lastx);						\
+	while (a0 > lastx && pa > thisrun)				\
+	    a0 -= *--pa;						\
+	if (a0 < lastx) {						\
+	    if (a0 < 0)							\
+		a0 = 0;							\
+	    if ((pa-thisrun)&1)						\
+		SETVALUE(0);						\
+	    SETVALUE(lastx - a0);						\
+	} else if (a0 > lastx) {					\
+	    SETVALUE(lastx);						\
+	    SETVALUE(0);							\
+	}								\
+    }									\
+} while (0)
+
+/*
+ * Decode a line of 1D-encoded data.
+ *
+ * The line expanders are written as macros so that they can be reused
+ * but still have direct access to the local variables of the "calling"
+ * function.
+ *
+ * Note that unlike the original version we have to explicitly test for
+ * a0 >= lastx after each black/white run is decoded.  This is because
+ * the original code depended on the input data being zero-padded to
+ * insure the decoder recognized an EOL before running out of data.
+ */
+#define EXPAND1D(eoflab) do {						\
+    for (;;) {								\
+	for (;;) {							\
+	    LOOKUP16(12, TIFFFaxWhiteTable, eof1d);			\
+	    switch (TabEnt->State) {					\
+	    case S_EOL:							\
+		EOLcnt = 1;						\
+		goto done1d;						\
+	    case S_TermW:						\
+		SETVALUE(TabEnt->Param);					\
+		goto doneWhite1d;					\
+	    case S_MakeUpW:						\
+	    case S_MakeUp:						\
+		a0 += TabEnt->Param;					\
+		RunLength += TabEnt->Param;				\
+		break;							\
+	    default:							\
+		unexpected("WhiteTable", a0);				\
+		goto done1d;						\
+	    }								\
+	}								\
+    doneWhite1d:							\
+	if (a0 >= lastx)						\
+	    goto done1d;						\
+	for (;;) {							\
+	    LOOKUP16(13, TIFFFaxBlackTable, eof1d);			\
+	    switch (TabEnt->State) {					\
+	    case S_EOL:							\
+		EOLcnt = 1;						\
+		goto done1d;						\
+	    case S_TermB:						\
+		SETVALUE(TabEnt->Param);					\
+		goto doneBlack1d;					\
+	    case S_MakeUpB:						\
+	    case S_MakeUp:						\
+		a0 += TabEnt->Param;					\
+		RunLength += TabEnt->Param;				\
+		break;							\
+	    default:							\
+		unexpected("BlackTable", a0);				\
+		goto done1d;						\
+	    }								\
+	}								\
+    doneBlack1d:							\
+	if (a0 >= lastx)						\
+	    goto done1d;						\
+        if( *(pa-1) == 0 && *(pa-2) == 0 )				\
+            pa -= 2;                                                    \
+    }									\
+eof1d:									\
+    prematureEOF(a0);							\
+    CLEANUP_RUNS();							\
+    goto eoflab;							\
+done1d:									\
+    CLEANUP_RUNS();							\
+} while (0)
+
+/*
+ * Update the value of b1 using the array
+ * of runs for the reference line.
+ */
+#define CHECK_b1 do {							\
+    if (pa != thisrun) while (b1 <= a0 && b1 < lastx) {			\
+	b1 += pb[0] + pb[1];						\
+	pb += 2;							\
+    }									\
+} while (0)
+
+/*
+ * Expand a row of 2D-encoded data.
+ */
+#define EXPAND2D(eoflab) do {						\
+    while (a0 < lastx) {						\
+	LOOKUP8(7, TIFFFaxMainTable, eof2d);				\
+	switch (TabEnt->State) {					\
+	case S_Pass:							\
+	    CHECK_b1;							\
+	    b1 += *pb++;						\
+	    RunLength += b1 - a0;					\
+	    a0 = b1;							\
+	    b1 += *pb++;						\
+	    break;							\
+	case S_Horiz:							\
+	    if ((pa-thisrun)&1) {					\
+		for (;;) {	/* black first */			\
+		    LOOKUP16(13, TIFFFaxBlackTable, eof2d);		\
+		    switch (TabEnt->State) {				\
+		    case S_TermB:					\
+			SETVALUE(TabEnt->Param);				\
+			goto doneWhite2da;				\
+		    case S_MakeUpB:					\
+		    case S_MakeUp:					\
+			a0 += TabEnt->Param;				\
+			RunLength += TabEnt->Param;			\
+			break;						\
+		    default:						\
+			goto badBlack2d;				\
+		    }							\
+		}							\
+	    doneWhite2da:;						\
+		for (;;) {	/* then white */			\
+		    LOOKUP16(12, TIFFFaxWhiteTable, eof2d);		\
+		    switch (TabEnt->State) {				\
+		    case S_TermW:					\
+			SETVALUE(TabEnt->Param);				\
+			goto doneBlack2da;				\
+		    case S_MakeUpW:					\
+		    case S_MakeUp:					\
+			a0 += TabEnt->Param;				\
+			RunLength += TabEnt->Param;			\
+			break;						\
+		    default:						\
+			goto badWhite2d;				\
+		    }							\
+		}							\
+	    doneBlack2da:;						\
+	    } else {							\
+		for (;;) {	/* white first */			\
+		    LOOKUP16(12, TIFFFaxWhiteTable, eof2d);		\
+		    switch (TabEnt->State) {				\
+		    case S_TermW:					\
+			SETVALUE(TabEnt->Param);				\
+			goto doneWhite2db;				\
+		    case S_MakeUpW:					\
+		    case S_MakeUp:					\
+			a0 += TabEnt->Param;				\
+			RunLength += TabEnt->Param;			\
+			break;						\
+		    default:						\
+			goto badWhite2d;				\
+		    }							\
+		}							\
+	    doneWhite2db:;						\
+		for (;;) {	/* then black */			\
+		    LOOKUP16(13, TIFFFaxBlackTable, eof2d);		\
+		    switch (TabEnt->State) {				\
+		    case S_TermB:					\
+			SETVALUE(TabEnt->Param);				\
+			goto doneBlack2db;				\
+		    case S_MakeUpB:					\
+		    case S_MakeUp:					\
+			a0 += TabEnt->Param;				\
+			RunLength += TabEnt->Param;			\
+			break;						\
+		    default:						\
+			goto badBlack2d;				\
+		    }							\
+		}							\
+	    doneBlack2db:;						\
+	    }								\
+	    CHECK_b1;							\
+	    break;							\
+	case S_V0:							\
+	    CHECK_b1;							\
+	    SETVALUE(b1 - a0);						\
+	    b1 += *pb++;						\
+	    break;							\
+	case S_VR:							\
+	    CHECK_b1;							\
+	    SETVALUE(b1 - a0 + TabEnt->Param);				\
+	    b1 += *pb++;						\
+	    break;							\
+	case S_VL:							\
+	    CHECK_b1;							\
+	    if (b1 <= (int) (a0 + TabEnt->Param)) {			\
+		if (b1 < (int) (a0 + TabEnt->Param) || pa != thisrun) {	\
+		    unexpected("VL", a0);				\
+		    goto eol2d;						\
+		}							\
+	    }								\
+	    SETVALUE(b1 - a0 - TabEnt->Param);				\
+	    b1 -= *--pb;						\
+	    break;							\
+	case S_Ext:							\
+	    *pa++ = lastx - a0;						\
+	    extension(a0);						\
+	    goto eol2d;							\
+	case S_EOL:							\
+	    *pa++ = lastx - a0;						\
+	    NeedBits8(4,eof2d);						\
+	    if (GetBits(4))						\
+		unexpected("EOL", a0);					\
+            ClrBits(4);                                                 \
+	    EOLcnt = 1;							\
+	    goto eol2d;							\
+	default:							\
+	badMain2d:							\
+	    unexpected("MainTable", a0);				\
+	    goto eol2d;							\
+	badBlack2d:							\
+	    unexpected("BlackTable", a0);				\
+	    goto eol2d;							\
+	badWhite2d:							\
+	    unexpected("WhiteTable", a0);				\
+	    goto eol2d;							\
+	eof2d:								\
+	    prematureEOF(a0);						\
+	    CLEANUP_RUNS();						\
+	    goto eoflab;						\
+	}								\
+    }									\
+    if (RunLength) {							\
+	if (RunLength + a0 < lastx) {					\
+	    /* expect a final V0 */					\
+	    NeedBits8(1,eof2d);						\
+	    if (!GetBits(1))						\
+		goto badMain2d;						\
+	    ClrBits(1);							\
+	}								\
+	SETVALUE(0);							\
+    }									\
+eol2d:									\
+    CLEANUP_RUNS();							\
+} while (0)
+#endif /* _FAX3_ */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tif_fax3sm.c b/Source/LibTIFF4/tif_fax3sm.c
index 1e2fe42..822191e 100644
--- a/Source/LibTIFF4/tif_fax3sm.c
+++ b/Source/LibTIFF4/tif_fax3sm.c
@@ -1,1260 +1,1260 @@
-/* WARNING, this file was automatically generated by the
-    mkg3states program */
-#include "tiff.h"
-#include "tif_fax3.h"
- const TIFFFaxTabEnt TIFFFaxMainTable[128] = {
-{12,7,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{1,4,0},{3,1,0},
-{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{5,6,2},{3,1,0},{5,3,1},{3,1,0},
-{2,3,0},{3,1,0},{4,3,1},{3,1,0},{1,4,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},
-{4,3,1},{3,1,0},{5,7,3},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},
-{1,4,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{4,6,2},{3,1,0},
-{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{1,4,0},{3,1,0},{5,3,1},{3,1,0},
-{2,3,0},{3,1,0},{4,3,1},{3,1,0},{6,7,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},
-{4,3,1},{3,1,0},{1,4,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},
-{5,6,2},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{1,4,0},{3,1,0},
-{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{4,7,3},{3,1,0},{5,3,1},{3,1,0},
-{2,3,0},{3,1,0},{4,3,1},{3,1,0},{1,4,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},
-{4,3,1},{3,1,0},{4,6,2},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},
-{1,4,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0}
-};
- const TIFFFaxTabEnt TIFFFaxWhiteTable[4096] = {
-{12,11,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},
-{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},
-{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},
-{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
-{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
-{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},
-{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,960},{7,4,6},{7,8,31},{7,5,8},
-{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},
-{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},
-{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},
-{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,11,1792},{7,4,3},
-{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},
-{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},
-{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},
-{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1600},{7,4,5},
-{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
-{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},
-{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},
-{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},
-{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},
-{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},
-{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},
-{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},
-{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},
-{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},
-{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1536},{7,4,5},{7,8,43},{7,6,17},
-{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},
-{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},
-{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,768},{7,4,6},
-{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
-{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,11,1856},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
-{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},
-{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,896},{7,4,6},{7,7,19},{7,5,8},
-{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},
-{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},
-{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5},{7,8,44},{7,6,17},{9,9,1408},{7,4,6},
-{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},
-{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},
-{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},
-{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},
-{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},
-{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
-{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},
-{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},
-{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},
-{7,6,13},{7,4,3},{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6},{7,6,1},{7,5,8},
-{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},
-{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},
-{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,960},{7,4,6},
-{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},
-{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},
-{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},
-{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{11,12,2112},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},
-{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},
-{7,8,40},{7,6,16},{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},
-{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
-{9,9,1600},{7,4,5},{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
-{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},
-{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6},{7,8,32},{7,5,8},
-{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},
-{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},
-{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},
-{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},
-{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},
-{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},
-{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},
-{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1536},{7,4,5},
-{7,8,43},{7,6,17},{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
-{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},
-{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},
-{9,9,768},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},
-{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},
-{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,12,2368},{7,4,3},{7,5,11},{7,4,5},
-{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},
-{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,896},{7,4,6},
-{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},
-{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},
-{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5},{7,8,44},{7,6,17},
-{9,9,1408},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},
-{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},
-{7,8,42},{7,6,16},{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},
-{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
-{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
-{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},
-{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},
-{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},
-{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},
-{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6},
-{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},
-{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},
-{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},
-{9,9,960},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128},
-{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},
-{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{11,12,1984},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
-{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},
-{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},
-{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},
-{7,6,13},{7,4,3},{9,9,1600},{7,4,5},{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8},
-{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},
-{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},
-{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6},
-{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},
-{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},
-{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},
-{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},
-{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},
-{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},
-{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
-{9,9,1536},{7,4,5},{7,8,43},{7,6,17},{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
-{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},
-{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8},
-{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},
-{7,7,26},{7,5,9},{9,9,768},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},
-{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},
-{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,11,1920},{7,4,3},
-{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},
-{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},
-{9,9,896},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},
-{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5},
-{7,8,44},{7,6,17},{9,9,1408},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
-{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},
-{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},
-{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},
-{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},
-{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},
-{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},
-{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},
-{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},
-{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},
-{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1472},{7,4,5},{7,8,43},{7,6,17},
-{9,9,1216},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},
-{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},
-{7,8,41},{7,6,16},{9,9,960},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,704},{7,4,6},
-{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
-{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,12,2240},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
-{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},
-{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,832},{7,4,6},{7,7,19},{7,5,8},
-{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},
-{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},
-{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1600},{7,4,5},{7,8,44},{7,6,17},{9,9,1344},{7,4,6},
-{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},
-{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},
-{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},
-{9,9,1088},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},
-{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},
-{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
-{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},
-{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},
-{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},
-{7,6,13},{7,4,3},{9,9,1536},{7,4,5},{7,8,43},{7,6,17},{9,9,1280},{7,4,6},{7,6,1},{7,5,8},
-{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},
-{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},
-{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,1024},{7,4,6},
-{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},
-{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,768},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},
-{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},
-{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{11,12,2496},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},
-{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},
-{7,8,40},{7,6,16},{9,9,896},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},
-{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
-{9,9,1728},{7,4,5},{7,8,44},{7,6,17},{9,9,1408},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
-{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},
-{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1152},{7,4,6},{7,8,32},{7,5,8},
-{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},
-{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},
-{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},
-{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{12,11,0},{7,4,3},
-{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},
-{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},
-{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},
-{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1472},{7,4,5},
-{7,8,43},{7,6,17},{9,9,1216},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
-{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},
-{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,960},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},
-{9,9,704},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},
-{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},
-{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,11,1792},{7,4,3},{7,5,11},{7,4,5},
-{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},
-{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,832},{7,4,6},
-{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},
-{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},
-{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1600},{7,4,5},{7,8,44},{7,6,17},
-{9,9,1344},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},
-{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},
-{7,8,42},{7,6,16},{9,9,1088},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},
-{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
-{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
-{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},
-{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},
-{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},
-{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},
-{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1536},{7,4,5},{7,8,43},{7,6,17},{9,9,1280},{7,4,6},
-{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},
-{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},
-{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},
-{9,9,1024},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,768},{7,4,6},{7,8,37},{9,5,128},
-{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},
-{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{11,11,1856},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
-{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},
-{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,896},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},
-{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},
-{7,6,13},{7,4,3},{9,9,1728},{7,4,5},{7,8,44},{7,6,17},{9,9,1408},{7,4,6},{7,6,1},{7,5,8},
-{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},
-{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},
-{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1152},{7,4,6},
-{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},
-{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},
-{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},
-{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},
-{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},
-{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},
-{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
-{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
-{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},
-{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,960},{7,4,6},{7,8,31},{7,5,8},
-{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},
-{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},
-{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},
-{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,12,2176},{7,4,3},
-{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},
-{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},
-{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},
-{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1600},{7,4,5},
-{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
-{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},
-{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},
-{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},
-{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},
-{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},
-{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},
-{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},
-{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},
-{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},
-{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1536},{7,4,5},{7,8,43},{7,6,17},
-{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},
-{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},
-{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,768},{7,4,6},
-{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
-{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,12,2432},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
-{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},
-{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,896},{7,4,6},{7,7,19},{7,5,8},
-{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},
-{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},
-{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5},{7,8,44},{7,6,17},{9,9,1408},{7,4,6},
-{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},
-{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},
-{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},
-{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},
-{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},
-{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
-{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},
-{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},
-{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},
-{7,6,13},{7,4,3},{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6},{7,6,1},{7,5,8},
-{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},
-{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},
-{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,960},{7,4,6},
-{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},
-{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},
-{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},
-{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{11,12,2048},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},
-{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},
-{7,8,40},{7,6,16},{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},
-{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
-{9,9,1600},{7,4,5},{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
-{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},
-{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6},{7,8,32},{7,5,8},
-{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},
-{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},
-{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},
-{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},
-{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},
-{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},
-{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},
-{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1536},{7,4,5},
-{7,8,43},{7,6,17},{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
-{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},
-{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},
-{9,9,768},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},
-{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},
-{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,11,1920},{7,4,3},{7,5,11},{7,4,5},
-{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},
-{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,896},{7,4,6},
-{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},
-{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},
-{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5},{7,8,44},{7,6,17},
-{9,9,1408},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},
-{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},
-{7,8,42},{7,6,16},{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},
-{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
-{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
-{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},
-{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},
-{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},
-{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},
-{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6},
-{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},
-{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},
-{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},
-{9,9,960},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128},
-{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},
-{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{11,12,2304},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
-{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},
-{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},
-{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},
-{7,6,13},{7,4,3},{9,9,1600},{7,4,5},{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8},
-{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},
-{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},
-{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6},
-{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},
-{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},
-{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},
-{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},
-{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},
-{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},
-{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
-{9,9,1536},{7,4,5},{7,8,43},{7,6,17},{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
-{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},
-{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8},
-{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},
-{7,7,26},{7,5,9},{9,9,768},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},
-{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},
-{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,12,2560},{7,4,3},
-{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},
-{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},
-{9,9,896},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
-{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},
-{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5},
-{7,8,44},{7,6,17},{9,9,1408},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
-{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
-{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},
-{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},
-{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},
-{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},
-{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},
-{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}
-};
- const TIFFFaxTabEnt TIFFFaxBlackTable[8192] = {
-{12,11,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,18},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,17},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1792},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,11,23},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,20},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,11,25},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,128},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,12,56},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,12,30},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1856},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,57},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,11,21},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,54},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,52},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,48},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{11,12,2112},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,12,44},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,36},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,384},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,28},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,12,60},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,40},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2368},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,16},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{10,10,64},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,18},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,10,17},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{11,12,1984},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,50},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,12,34},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1664},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,26},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1408},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,32},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1920},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,12,61},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,42},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{10,13,1024},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{10,13,768},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,12,62},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2240},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,46},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,12,38},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,512},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,11,19},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,24},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,22},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{11,12,2496},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,10,16},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,0},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,10,64},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{12,11,0},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,10,18},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,17},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1792},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,23},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,20},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,11,25},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{10,12,192},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1280},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,12,31},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{11,11,1856},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,58},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,11,21},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,896},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,640},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,49},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2176},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,12,45},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,37},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{10,12,448},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,29},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{10,13,1536},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,12,41},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2432},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,16},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,10,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,10,64},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,18},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,17},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{11,12,2048},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,12,51},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,35},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,320},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,27},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,12,59},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,33},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1920},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,256},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,43},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{10,13,1152},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,55},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,12,63},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{11,12,2304},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,47},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,12,39},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,53},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,19},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,24},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,22},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2560},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,10,16},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,0},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{10,10,64},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{12,11,0},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,10,18},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,10,17},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1792},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,23},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,11,20},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,25},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{10,12,128},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,56},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,30},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{11,11,1856},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,12,57},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,21},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,54},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,12,52},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,48},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2112},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,44},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,36},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{10,12,384},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,12,28},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,60},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,12,40},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{11,12,2368},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,16},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,10,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,10,64},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,18},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,17},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,1984},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,12,50},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,34},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{10,13,1728},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,26},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{10,13,1472},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,12,32},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1920},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,61},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,12,42},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1088},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,832},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,62},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{11,12,2240},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,12,46},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,38},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,576},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,19},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,11,24},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,22},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2496},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,16},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{10,10,64},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{12,11,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,18},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,10,17},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{11,11,1792},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,23},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,11,20},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,25},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,192},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1344},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,31},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1856},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,12,58},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,21},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{10,13,960},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{10,13,704},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,12,49},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2176},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,45},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,12,37},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,448},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,12,29},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1600},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,41},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{11,12,2432},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,10,16},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,0},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,10,64},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,10,18},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,17},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2048},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,51},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,35},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{10,12,320},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,12,27},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,59},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,12,33},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{11,11,1920},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,256},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,12,43},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1216},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,55},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,63},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2304},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,12,47},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,39},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,12,53},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,19},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,11,24},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,11,22},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2560},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,16},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2},{8,10,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
-{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,10,64},{8,2,3},
-{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
-{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
-{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
-{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
-{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
-{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
-{8,3,4},{8,2,2}
-};
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* WARNING, this file was automatically generated by the
+    mkg3states program */
+#include "tiff.h"
+#include "tif_fax3.h"
+ const TIFFFaxTabEnt TIFFFaxMainTable[128] = {
+{12,7,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{1,4,0},{3,1,0},
+{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{5,6,2},{3,1,0},{5,3,1},{3,1,0},
+{2,3,0},{3,1,0},{4,3,1},{3,1,0},{1,4,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},
+{4,3,1},{3,1,0},{5,7,3},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},
+{1,4,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{4,6,2},{3,1,0},
+{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{1,4,0},{3,1,0},{5,3,1},{3,1,0},
+{2,3,0},{3,1,0},{4,3,1},{3,1,0},{6,7,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},
+{4,3,1},{3,1,0},{1,4,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},
+{5,6,2},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{1,4,0},{3,1,0},
+{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{4,7,3},{3,1,0},{5,3,1},{3,1,0},
+{2,3,0},{3,1,0},{4,3,1},{3,1,0},{1,4,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},
+{4,3,1},{3,1,0},{4,6,2},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},
+{1,4,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0}
+};
+ const TIFFFaxTabEnt TIFFFaxWhiteTable[4096] = {
+{12,11,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},
+{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},
+{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},
+{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
+{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
+{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},
+{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,960},{7,4,6},{7,8,31},{7,5,8},
+{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},
+{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},
+{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},
+{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,11,1792},{7,4,3},
+{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},
+{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},
+{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},
+{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1600},{7,4,5},
+{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
+{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},
+{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},
+{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},
+{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},
+{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},
+{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},
+{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},
+{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},
+{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},
+{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1536},{7,4,5},{7,8,43},{7,6,17},
+{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},
+{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},
+{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,768},{7,4,6},
+{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
+{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,11,1856},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
+{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},
+{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,896},{7,4,6},{7,7,19},{7,5,8},
+{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},
+{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},
+{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5},{7,8,44},{7,6,17},{9,9,1408},{7,4,6},
+{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},
+{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},
+{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},
+{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},
+{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},
+{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
+{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},
+{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},
+{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},
+{7,6,13},{7,4,3},{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6},{7,6,1},{7,5,8},
+{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},
+{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},
+{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,960},{7,4,6},
+{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},
+{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},
+{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},
+{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{11,12,2112},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},
+{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},
+{7,8,40},{7,6,16},{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},
+{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
+{9,9,1600},{7,4,5},{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
+{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},
+{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6},{7,8,32},{7,5,8},
+{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},
+{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},
+{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},
+{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},
+{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},
+{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},
+{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},
+{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1536},{7,4,5},
+{7,8,43},{7,6,17},{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
+{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},
+{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},
+{9,9,768},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},
+{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},
+{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,12,2368},{7,4,3},{7,5,11},{7,4,5},
+{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},
+{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,896},{7,4,6},
+{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},
+{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},
+{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5},{7,8,44},{7,6,17},
+{9,9,1408},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},
+{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},
+{7,8,42},{7,6,16},{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},
+{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
+{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
+{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},
+{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},
+{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},
+{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},
+{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6},
+{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},
+{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},
+{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},
+{9,9,960},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128},
+{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},
+{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{11,12,1984},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
+{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},
+{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},
+{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},
+{7,6,13},{7,4,3},{9,9,1600},{7,4,5},{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8},
+{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},
+{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},
+{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6},
+{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},
+{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},
+{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},
+{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},
+{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},
+{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},
+{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
+{9,9,1536},{7,4,5},{7,8,43},{7,6,17},{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
+{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},
+{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8},
+{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},
+{7,7,26},{7,5,9},{9,9,768},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},
+{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},
+{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,11,1920},{7,4,3},
+{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},
+{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},
+{9,9,896},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},
+{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5},
+{7,8,44},{7,6,17},{9,9,1408},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
+{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},
+{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},
+{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},
+{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},
+{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},
+{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},
+{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},
+{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},
+{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},
+{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1472},{7,4,5},{7,8,43},{7,6,17},
+{9,9,1216},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},
+{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},
+{7,8,41},{7,6,16},{9,9,960},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,704},{7,4,6},
+{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
+{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,12,2240},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
+{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},
+{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,832},{7,4,6},{7,7,19},{7,5,8},
+{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},
+{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},
+{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1600},{7,4,5},{7,8,44},{7,6,17},{9,9,1344},{7,4,6},
+{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},
+{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},
+{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},
+{9,9,1088},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},
+{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},
+{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
+{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},
+{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},
+{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},
+{7,6,13},{7,4,3},{9,9,1536},{7,4,5},{7,8,43},{7,6,17},{9,9,1280},{7,4,6},{7,6,1},{7,5,8},
+{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},
+{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},
+{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,1024},{7,4,6},
+{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},
+{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,768},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},
+{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},
+{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{11,12,2496},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},
+{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},
+{7,8,40},{7,6,16},{9,9,896},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},
+{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
+{9,9,1728},{7,4,5},{7,8,44},{7,6,17},{9,9,1408},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
+{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},
+{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1152},{7,4,6},{7,8,32},{7,5,8},
+{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},
+{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},
+{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},
+{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{12,11,0},{7,4,3},
+{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},
+{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},
+{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},
+{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1472},{7,4,5},
+{7,8,43},{7,6,17},{9,9,1216},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
+{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},
+{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,960},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},
+{9,9,704},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},
+{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},
+{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,11,1792},{7,4,3},{7,5,11},{7,4,5},
+{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},
+{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,832},{7,4,6},
+{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},
+{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},
+{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1600},{7,4,5},{7,8,44},{7,6,17},
+{9,9,1344},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},
+{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},
+{7,8,42},{7,6,16},{9,9,1088},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},
+{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
+{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
+{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},
+{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},
+{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},
+{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},
+{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1536},{7,4,5},{7,8,43},{7,6,17},{9,9,1280},{7,4,6},
+{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},
+{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},
+{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},
+{9,9,1024},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,768},{7,4,6},{7,8,37},{9,5,128},
+{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},
+{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{11,11,1856},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
+{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},
+{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,896},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},
+{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},
+{7,6,13},{7,4,3},{9,9,1728},{7,4,5},{7,8,44},{7,6,17},{9,9,1408},{7,4,6},{7,6,1},{7,5,8},
+{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},
+{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},
+{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1152},{7,4,6},
+{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},
+{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},
+{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},
+{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},
+{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},
+{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},
+{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
+{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
+{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},
+{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,960},{7,4,6},{7,8,31},{7,5,8},
+{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},
+{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},
+{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},
+{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,12,2176},{7,4,3},
+{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},
+{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},
+{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},
+{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1600},{7,4,5},
+{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
+{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},
+{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},
+{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},
+{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},
+{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},
+{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},
+{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},
+{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},
+{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},
+{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1536},{7,4,5},{7,8,43},{7,6,17},
+{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},
+{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},
+{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,768},{7,4,6},
+{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
+{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,12,2432},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
+{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},
+{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,896},{7,4,6},{7,7,19},{7,5,8},
+{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},
+{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},
+{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5},{7,8,44},{7,6,17},{9,9,1408},{7,4,6},
+{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},
+{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},
+{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},
+{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},
+{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},
+{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
+{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},
+{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},
+{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},
+{7,6,13},{7,4,3},{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6},{7,6,1},{7,5,8},
+{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},
+{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},
+{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,960},{7,4,6},
+{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},
+{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},
+{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},
+{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{11,12,2048},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},
+{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},
+{7,8,40},{7,6,16},{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},
+{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
+{9,9,1600},{7,4,5},{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
+{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},
+{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6},{7,8,32},{7,5,8},
+{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},
+{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},
+{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},
+{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},
+{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},
+{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},
+{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},
+{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1536},{7,4,5},
+{7,8,43},{7,6,17},{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
+{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},
+{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},
+{9,9,768},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},
+{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},
+{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,11,1920},{7,4,3},{7,5,11},{7,4,5},
+{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},
+{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,896},{7,4,6},
+{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},
+{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},
+{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5},{7,8,44},{7,6,17},
+{9,9,1408},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},
+{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},
+{7,8,42},{7,6,16},{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},
+{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
+{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
+{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},
+{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},
+{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},
+{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},
+{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6},
+{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},
+{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},
+{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},
+{9,9,960},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128},
+{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},
+{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{11,12,2304},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
+{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},
+{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},
+{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},
+{7,6,13},{7,4,3},{9,9,1600},{7,4,5},{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8},
+{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},
+{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},
+{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6},
+{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},
+{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},
+{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},
+{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},
+{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},
+{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},
+{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
+{9,9,1536},{7,4,5},{7,8,43},{7,6,17},{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
+{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},
+{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8},
+{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},
+{7,7,26},{7,5,9},{9,9,768},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},
+{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},
+{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,12,2560},{7,4,3},
+{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},
+{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},
+{9,9,896},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},
+{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5},
+{7,8,44},{7,6,17},{9,9,1408},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
+{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},
+{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},
+{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},
+{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},
+{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}
+};
+ const TIFFFaxTabEnt TIFFFaxBlackTable[8192] = {
+{12,11,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,18},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,17},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1792},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,11,23},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,20},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,11,25},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,128},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,56},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,30},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1856},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,57},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,11,21},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,54},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,52},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,48},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{11,12,2112},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,44},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,36},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,384},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,28},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,60},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,40},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2368},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,16},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{10,10,64},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,18},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,10,17},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{11,12,1984},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,50},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,34},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1664},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,26},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1408},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,32},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1920},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,61},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,42},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{10,13,1024},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{10,13,768},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,62},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2240},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,46},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,38},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,512},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,11,19},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,24},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,22},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{11,12,2496},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,10,16},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,0},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,10,64},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{12,11,0},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,10,18},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,17},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1792},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,23},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,20},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,11,25},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{10,12,192},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1280},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,31},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{11,11,1856},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,58},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,11,21},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,896},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,640},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,49},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2176},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,45},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,37},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{10,12,448},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,29},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{10,13,1536},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,41},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2432},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,16},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,10,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,10,64},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,18},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,17},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{11,12,2048},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,51},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,35},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,320},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,27},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,59},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,33},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1920},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,256},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,43},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{10,13,1152},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,55},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,63},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{11,12,2304},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,47},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,39},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,53},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,19},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,24},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,22},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2560},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,10,16},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,0},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{10,10,64},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{12,11,0},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,10,18},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,10,17},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1792},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,23},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,11,20},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,25},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{10,12,128},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,56},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,30},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{11,11,1856},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,57},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,21},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,54},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,52},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,48},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2112},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,44},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,36},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{10,12,384},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,28},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,60},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,40},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{11,12,2368},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,16},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,10,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,10,64},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,18},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,17},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,1984},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,50},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,34},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{10,13,1728},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,26},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{10,13,1472},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,32},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1920},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,61},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,42},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1088},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,832},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,62},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{11,12,2240},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,46},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,38},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,576},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,19},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,11,24},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,22},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2496},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,16},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{10,10,64},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{12,11,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,18},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,10,17},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{11,11,1792},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,23},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,11,20},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,25},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,192},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1344},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,31},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1856},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,58},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,21},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{10,13,960},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{10,13,704},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,49},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2176},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,45},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,37},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,448},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,29},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1600},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,41},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{11,12,2432},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,10,16},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,0},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,10,64},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,10,18},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,17},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2048},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,51},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,35},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{10,12,320},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,27},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,59},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,33},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{11,11,1920},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,256},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,43},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1216},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,55},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,63},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2304},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,47},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,39},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,53},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,19},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,11,24},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,11,22},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2560},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,16},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,10,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,10,64},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2}
+};
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tif_flush.c b/Source/LibTIFF4/tif_flush.c
index 50b4ec5..9df5344 100644
--- a/Source/LibTIFF4/tif_flush.c
+++ b/Source/LibTIFF4/tif_flush.c
@@ -1,118 +1,118 @@
-/* $Id: tif_flush.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library.
- */
-#include "tiffiop.h"
-
-int
-TIFFFlush(TIFF* tif)
-{
-    if( tif->tif_mode == O_RDONLY )
-        return 1;
-
-    if (!TIFFFlushData(tif))
-        return (0);
-                
-    /* In update (r+) mode we try to detect the case where 
-       only the strip/tile map has been altered, and we try to 
-       rewrite only that portion of the directory without 
-       making any other changes */
-                
-    if( (tif->tif_flags & TIFF_DIRTYSTRIP)
-        && !(tif->tif_flags & TIFF_DIRTYDIRECT) 
-        && tif->tif_mode == O_RDWR )
-    {
-        uint64  *offsets=NULL, *sizes=NULL;
-
-        if( TIFFIsTiled(tif) )
-        {
-            if( TIFFGetField( tif, TIFFTAG_TILEOFFSETS, &offsets ) 
-                && TIFFGetField( tif, TIFFTAG_TILEBYTECOUNTS, &sizes ) 
-                && _TIFFRewriteField( tif, TIFFTAG_TILEOFFSETS, TIFF_LONG8, 
-                                      tif->tif_dir.td_nstrips, offsets )
-                && _TIFFRewriteField( tif, TIFFTAG_TILEBYTECOUNTS, TIFF_LONG8, 
-                                      tif->tif_dir.td_nstrips, sizes ) )
-            {
-                tif->tif_flags &= ~TIFF_DIRTYSTRIP;
-                tif->tif_flags &= ~TIFF_BEENWRITING;
-                return 1;
-            }
-        }
-        else
-        {
-            if( TIFFGetField( tif, TIFFTAG_STRIPOFFSETS, &offsets ) 
-                && TIFFGetField( tif, TIFFTAG_STRIPBYTECOUNTS, &sizes ) 
-                && _TIFFRewriteField( tif, TIFFTAG_STRIPOFFSETS, TIFF_LONG8, 
-                                      tif->tif_dir.td_nstrips, offsets )
-                && _TIFFRewriteField( tif, TIFFTAG_STRIPBYTECOUNTS, TIFF_LONG8, 
-                                      tif->tif_dir.td_nstrips, sizes ) )
-            {
-                tif->tif_flags &= ~TIFF_DIRTYSTRIP;
-                tif->tif_flags &= ~TIFF_BEENWRITING;
-                return 1;
-            }
-        }
-    }
-
-    if ((tif->tif_flags & (TIFF_DIRTYDIRECT|TIFF_DIRTYSTRIP)) 
-        && !TIFFRewriteDirectory(tif))
-        return (0);
-
-    return (1);
-}
-
-/*
- * Flush buffered data to the file.
- *
- * Frank Warmerdam'2000: I modified this to return 1 if TIFF_BEENWRITING
- * is not set, so that TIFFFlush() will proceed to write out the directory.
- * The documentation says returning 1 is an error indicator, but not having
- * been writing isn't exactly a an error.  Hopefully this doesn't cause
- * problems for other people. 
- */
-int
-TIFFFlushData(TIFF* tif)
-{
-	if ((tif->tif_flags & TIFF_BEENWRITING) == 0)
-		return (1);
-	if (tif->tif_flags & TIFF_POSTENCODE) {
-		tif->tif_flags &= ~TIFF_POSTENCODE;
-		if (!(*tif->tif_postencode)(tif))
-			return (0);
-	}
-	return (TIFFFlushData1(tif));
-}
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Id: tif_flush.c,v 1.11 2015/02/19 22:39:58 drolon Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and 
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
+ * 
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ */
+#include "tiffiop.h"
+
+int
+TIFFFlush(TIFF* tif)
+{
+    if( tif->tif_mode == O_RDONLY )
+        return 1;
+
+    if (!TIFFFlushData(tif))
+        return (0);
+                
+    /* In update (r+) mode we try to detect the case where 
+       only the strip/tile map has been altered, and we try to 
+       rewrite only that portion of the directory without 
+       making any other changes */
+                
+    if( (tif->tif_flags & TIFF_DIRTYSTRIP)
+        && !(tif->tif_flags & TIFF_DIRTYDIRECT) 
+        && tif->tif_mode == O_RDWR )
+    {
+        uint64  *offsets=NULL, *sizes=NULL;
+
+        if( TIFFIsTiled(tif) )
+        {
+            if( TIFFGetField( tif, TIFFTAG_TILEOFFSETS, &offsets ) 
+                && TIFFGetField( tif, TIFFTAG_TILEBYTECOUNTS, &sizes ) 
+                && _TIFFRewriteField( tif, TIFFTAG_TILEOFFSETS, TIFF_LONG8, 
+                                      tif->tif_dir.td_nstrips, offsets )
+                && _TIFFRewriteField( tif, TIFFTAG_TILEBYTECOUNTS, TIFF_LONG8, 
+                                      tif->tif_dir.td_nstrips, sizes ) )
+            {
+                tif->tif_flags &= ~TIFF_DIRTYSTRIP;
+                tif->tif_flags &= ~TIFF_BEENWRITING;
+                return 1;
+            }
+        }
+        else
+        {
+            if( TIFFGetField( tif, TIFFTAG_STRIPOFFSETS, &offsets ) 
+                && TIFFGetField( tif, TIFFTAG_STRIPBYTECOUNTS, &sizes ) 
+                && _TIFFRewriteField( tif, TIFFTAG_STRIPOFFSETS, TIFF_LONG8, 
+                                      tif->tif_dir.td_nstrips, offsets )
+                && _TIFFRewriteField( tif, TIFFTAG_STRIPBYTECOUNTS, TIFF_LONG8, 
+                                      tif->tif_dir.td_nstrips, sizes ) )
+            {
+                tif->tif_flags &= ~TIFF_DIRTYSTRIP;
+                tif->tif_flags &= ~TIFF_BEENWRITING;
+                return 1;
+            }
+        }
+    }
+
+    if ((tif->tif_flags & (TIFF_DIRTYDIRECT|TIFF_DIRTYSTRIP)) 
+        && !TIFFRewriteDirectory(tif))
+        return (0);
+
+    return (1);
+}
+
+/*
+ * Flush buffered data to the file.
+ *
+ * Frank Warmerdam'2000: I modified this to return 1 if TIFF_BEENWRITING
+ * is not set, so that TIFFFlush() will proceed to write out the directory.
+ * The documentation says returning 1 is an error indicator, but not having
+ * been writing isn't exactly a an error.  Hopefully this doesn't cause
+ * problems for other people. 
+ */
+int
+TIFFFlushData(TIFF* tif)
+{
+	if ((tif->tif_flags & TIFF_BEENWRITING) == 0)
+		return (1);
+	if (tif->tif_flags & TIFF_POSTENCODE) {
+		tif->tif_flags &= ~TIFF_POSTENCODE;
+		if (!(*tif->tif_postencode)(tif))
+			return (0);
+	}
+	return (TIFFFlushData1(tif));
+}
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tif_getimage.c b/Source/LibTIFF4/tif_getimage.c
index dc06f30..5ded7f0 100644
--- a/Source/LibTIFF4/tif_getimage.c
+++ b/Source/LibTIFF4/tif_getimage.c
@@ -1,2867 +1,2890 @@
-/* $Id: tif_getimage.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * Copyright (c) 1991-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library
- *
- * Read and return a packed RGBA image.
- */
-#include "tiffiop.h"
-#include <stdio.h>
-
-static int gtTileContig(TIFFRGBAImage*, uint32*, uint32, uint32);
-static int gtTileSeparate(TIFFRGBAImage*, uint32*, uint32, uint32);
-static int gtStripContig(TIFFRGBAImage*, uint32*, uint32, uint32);
-static int gtStripSeparate(TIFFRGBAImage*, uint32*, uint32, uint32);
-static int PickContigCase(TIFFRGBAImage*);
-static int PickSeparateCase(TIFFRGBAImage*);
-
-static int BuildMapUaToAa(TIFFRGBAImage* img);
-static int BuildMapBitdepth16To8(TIFFRGBAImage* img);
-
-static const char photoTag[] = "PhotometricInterpretation";
-
-/* 
- * Helper constants used in Orientation tag handling
- */
-#define FLIP_VERTICALLY 0x01
-#define FLIP_HORIZONTALLY 0x02
-
-/*
- * Color conversion constants. We will define display types here.
- */
-
-static const TIFFDisplay display_sRGB = {
-	{			/* XYZ -> luminance matrix */
-		{  3.2410F, -1.5374F, -0.4986F },
-		{  -0.9692F, 1.8760F, 0.0416F },
-		{  0.0556F, -0.2040F, 1.0570F }
-	},	
-	100.0F, 100.0F, 100.0F,	/* Light o/p for reference white */
-	255, 255, 255,		/* Pixel values for ref. white */
-	1.0F, 1.0F, 1.0F,	/* Residual light o/p for black pixel */
-	2.4F, 2.4F, 2.4F,	/* Gamma values for the three guns */
-};
-
-/*
- * Check the image to see if TIFFReadRGBAImage can deal with it.
- * 1/0 is returned according to whether or not the image can
- * be handled.  If 0 is returned, emsg contains the reason
- * why it is being rejected.
- */
-int
-TIFFRGBAImageOK(TIFF* tif, char emsg[1024])
-{
-	TIFFDirectory* td = &tif->tif_dir;
-	uint16 photometric;
-	int colorchannels;
-
-	if (!tif->tif_decodestatus) {
-		sprintf(emsg, "Sorry, requested compression method is not configured");
-		return (0);
-	}
-	switch (td->td_bitspersample) {
-		case 1:
-		case 2:
-		case 4:
-		case 8:
-		case 16:
-			break;
-		default:
-			sprintf(emsg, "Sorry, can not handle images with %d-bit samples",
-			    td->td_bitspersample);
-			return (0);
-	}
-	colorchannels = td->td_samplesperpixel - td->td_extrasamples;
-	if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) {
-		switch (colorchannels) {
-			case 1:
-				photometric = PHOTOMETRIC_MINISBLACK;
-				break;
-			case 3:
-				photometric = PHOTOMETRIC_RGB;
-				break;
-			default:
-				sprintf(emsg, "Missing needed %s tag", photoTag);
-				return (0);
-		}
-	}
-	switch (photometric) {
-		case PHOTOMETRIC_MINISWHITE:
-		case PHOTOMETRIC_MINISBLACK:
-		case PHOTOMETRIC_PALETTE:
-			if (td->td_planarconfig == PLANARCONFIG_CONTIG
-			    && td->td_samplesperpixel != 1
-			    && td->td_bitspersample < 8 ) {
-				sprintf(emsg,
-				    "Sorry, can not handle contiguous data with %s=%d, "
-				    "and %s=%d and Bits/Sample=%d",
-				    photoTag, photometric,
-				    "Samples/pixel", td->td_samplesperpixel,
-				    td->td_bitspersample);
-				return (0);
-			}
-			/*
-			 * We should likely validate that any extra samples are either
-			 * to be ignored, or are alpha, and if alpha we should try to use
-			 * them.  But for now we won't bother with this.
-			*/
-			break;
-		case PHOTOMETRIC_YCBCR:
-			/*
-			 * TODO: if at all meaningful and useful, make more complete
-			 * support check here, or better still, refactor to let supporting
-			 * code decide whether there is support and what meaningfull
-			 * error to return
-			 */
-			break;
-		case PHOTOMETRIC_RGB:
-			if (colorchannels < 3) {
-				sprintf(emsg, "Sorry, can not handle RGB image with %s=%d",
-				    "Color channels", colorchannels);
-				return (0);
-			}
-			break;
-		case PHOTOMETRIC_SEPARATED:
-			{
-				uint16 inkset;
-				TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset);
-				if (inkset != INKSET_CMYK) {
-					sprintf(emsg,
-					    "Sorry, can not handle separated image with %s=%d",
-					    "InkSet", inkset);
-					return 0;
-				}
-				if (td->td_samplesperpixel < 4) {
-					sprintf(emsg,
-					    "Sorry, can not handle separated image with %s=%d",
-					    "Samples/pixel", td->td_samplesperpixel);
-					return 0;
-				}
-				break;
-			}
-		case PHOTOMETRIC_LOGL:
-			if (td->td_compression != COMPRESSION_SGILOG) {
-				sprintf(emsg, "Sorry, LogL data must have %s=%d",
-				    "Compression", COMPRESSION_SGILOG);
-				return (0);
-			}
-			break;
-		case PHOTOMETRIC_LOGLUV:
-			if (td->td_compression != COMPRESSION_SGILOG &&
-			    td->td_compression != COMPRESSION_SGILOG24) {
-				sprintf(emsg, "Sorry, LogLuv data must have %s=%d or %d",
-				    "Compression", COMPRESSION_SGILOG, COMPRESSION_SGILOG24);
-				return (0);
-			}
-			if (td->td_planarconfig != PLANARCONFIG_CONTIG) {
-				sprintf(emsg, "Sorry, can not handle LogLuv images with %s=%d",
-				    "Planarconfiguration", td->td_planarconfig);
-				return (0);
-			}
-			break;
-		case PHOTOMETRIC_CIELAB:
-			break;
-		default:
-			sprintf(emsg, "Sorry, can not handle image with %s=%d",
-			    photoTag, photometric);
-			return (0);
-	}
-	return (1);
-}
-
-void
-TIFFRGBAImageEnd(TIFFRGBAImage* img)
-{
-	if (img->Map)
-		_TIFFfree(img->Map), img->Map = NULL;
-	if (img->BWmap)
-		_TIFFfree(img->BWmap), img->BWmap = NULL;
-	if (img->PALmap)
-		_TIFFfree(img->PALmap), img->PALmap = NULL;
-	if (img->ycbcr)
-		_TIFFfree(img->ycbcr), img->ycbcr = NULL;
-	if (img->cielab)
-		_TIFFfree(img->cielab), img->cielab = NULL;
-	if (img->UaToAa)
-		_TIFFfree(img->UaToAa), img->UaToAa = NULL;
-	if (img->Bitdepth16To8)
-		_TIFFfree(img->Bitdepth16To8), img->Bitdepth16To8 = NULL;
-
-	if( img->redcmap ) {
-		_TIFFfree( img->redcmap );
-		_TIFFfree( img->greencmap );
-		_TIFFfree( img->bluecmap );
-                img->redcmap = img->greencmap = img->bluecmap = NULL;
-	}
-}
-
-static int
-isCCITTCompression(TIFF* tif)
-{
-    uint16 compress;
-    TIFFGetField(tif, TIFFTAG_COMPRESSION, &compress);
-    return (compress == COMPRESSION_CCITTFAX3 ||
-	    compress == COMPRESSION_CCITTFAX4 ||
-	    compress == COMPRESSION_CCITTRLE ||
-	    compress == COMPRESSION_CCITTRLEW);
-}
-
-int
-TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024])
-{
-	uint16* sampleinfo;
-	uint16 extrasamples;
-	uint16 planarconfig;
-	uint16 compress;
-	int colorchannels;
-	uint16 *red_orig, *green_orig, *blue_orig;
-	int n_color;
-
-	/* Initialize to normal values */
-	img->row_offset = 0;
-	img->col_offset = 0;
-	img->redcmap = NULL;
-	img->greencmap = NULL;
-	img->bluecmap = NULL;
-	img->req_orientation = ORIENTATION_BOTLEFT;     /* It is the default */
-
-	img->tif = tif;
-	img->stoponerr = stop;
-	TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &img->bitspersample);
-	switch (img->bitspersample) {
-		case 1:
-		case 2:
-		case 4:
-		case 8:
-		case 16:
-			break;
-		default:
-			sprintf(emsg, "Sorry, can not handle images with %d-bit samples",
-			    img->bitspersample);
-			goto fail_return;
-	}
-	img->alpha = 0;
-	TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &img->samplesperpixel);
-	TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES,
-	    &extrasamples, &sampleinfo);
-	if (extrasamples >= 1)
-	{
-		switch (sampleinfo[0]) {
-			case EXTRASAMPLE_UNSPECIFIED:          /* Workaround for some images without */
-				if (img->samplesperpixel > 3)  /* correct info about alpha channel */
-					img->alpha = EXTRASAMPLE_ASSOCALPHA;
-				break;
-			case EXTRASAMPLE_ASSOCALPHA:           /* data is pre-multiplied */
-			case EXTRASAMPLE_UNASSALPHA:           /* data is not pre-multiplied */
-				img->alpha = sampleinfo[0];
-				break;
-		}
-	}
-
-#ifdef DEFAULT_EXTRASAMPLE_AS_ALPHA
-	if( !TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric))
-		img->photometric = PHOTOMETRIC_MINISWHITE;
-
-	if( extrasamples == 0
-	    && img->samplesperpixel == 4
-	    && img->photometric == PHOTOMETRIC_RGB )
-	{
-		img->alpha = EXTRASAMPLE_ASSOCALPHA;
-		extrasamples = 1;
-	}
-#endif
-
-	colorchannels = img->samplesperpixel - extrasamples;
-	TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &compress);
-	TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planarconfig);
-	if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric)) {
-		switch (colorchannels) {
-			case 1:
-				if (isCCITTCompression(tif))
-					img->photometric = PHOTOMETRIC_MINISWHITE;
-				else
-					img->photometric = PHOTOMETRIC_MINISBLACK;
-				break;
-			case 3:
-				img->photometric = PHOTOMETRIC_RGB;
-				break;
-			default:
-				sprintf(emsg, "Missing needed %s tag", photoTag);
-                                goto fail_return;
-		}
-	}
-	switch (img->photometric) {
-		case PHOTOMETRIC_PALETTE:
-			if (!TIFFGetField(tif, TIFFTAG_COLORMAP,
-			    &red_orig, &green_orig, &blue_orig)) {
-				sprintf(emsg, "Missing required \"Colormap\" tag");
-                                goto fail_return;
-			}
-
-			/* copy the colormaps so we can modify them */
-			n_color = (1L << img->bitspersample);
-			img->redcmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);
-			img->greencmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);
-			img->bluecmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);
-			if( !img->redcmap || !img->greencmap || !img->bluecmap ) {
-				sprintf(emsg, "Out of memory for colormap copy");
-                                goto fail_return;
-			}
-
-			_TIFFmemcpy( img->redcmap, red_orig, n_color * 2 );
-			_TIFFmemcpy( img->greencmap, green_orig, n_color * 2 );
-			_TIFFmemcpy( img->bluecmap, blue_orig, n_color * 2 );
-
-			/* fall thru... */
-		case PHOTOMETRIC_MINISWHITE:
-		case PHOTOMETRIC_MINISBLACK:
-			if (planarconfig == PLANARCONFIG_CONTIG
-			    && img->samplesperpixel != 1
-			    && img->bitspersample < 8 ) {
-				sprintf(emsg,
-				    "Sorry, can not handle contiguous data with %s=%d, "
-				    "and %s=%d and Bits/Sample=%d",
-				    photoTag, img->photometric,
-				    "Samples/pixel", img->samplesperpixel,
-				    img->bitspersample);
-                                goto fail_return;
-			}
-			break;
-		case PHOTOMETRIC_YCBCR:
-			/* It would probably be nice to have a reality check here. */
-			if (planarconfig == PLANARCONFIG_CONTIG)
-				/* can rely on libjpeg to convert to RGB */
-				/* XXX should restore current state on exit */
-				switch (compress) {
-					case COMPRESSION_JPEG:
-						/*
-						 * TODO: when complete tests verify complete desubsampling
-						 * and YCbCr handling, remove use of TIFFTAG_JPEGCOLORMODE in
-						 * favor of tif_getimage.c native handling
-						 */
-						TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
-						img->photometric = PHOTOMETRIC_RGB;
-						break;
-					default:
-						/* do nothing */;
-						break;
-				}
-			/*
-			 * TODO: if at all meaningful and useful, make more complete
-			 * support check here, or better still, refactor to let supporting
-			 * code decide whether there is support and what meaningfull
-			 * error to return
-			 */
-			break;
-		case PHOTOMETRIC_RGB:
-			if (colorchannels < 3) {
-				sprintf(emsg, "Sorry, can not handle RGB image with %s=%d",
-				    "Color channels", colorchannels);
-                                goto fail_return;
-			}
-			break;
-		case PHOTOMETRIC_SEPARATED:
-			{
-				uint16 inkset;
-				TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset);
-				if (inkset != INKSET_CMYK) {
-					sprintf(emsg, "Sorry, can not handle separated image with %s=%d",
-					    "InkSet", inkset);
-                                        goto fail_return;
-				}
-				if (img->samplesperpixel < 4) {
-					sprintf(emsg, "Sorry, can not handle separated image with %s=%d",
-					    "Samples/pixel", img->samplesperpixel);
-                                        goto fail_return;
-				}
-			}
-			break;
-		case PHOTOMETRIC_LOGL:
-			if (compress != COMPRESSION_SGILOG) {
-				sprintf(emsg, "Sorry, LogL data must have %s=%d",
-				    "Compression", COMPRESSION_SGILOG);
-                                goto fail_return;
-			}
-			TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT);
-			img->photometric = PHOTOMETRIC_MINISBLACK;	/* little white lie */
-			img->bitspersample = 8;
-			break;
-		case PHOTOMETRIC_LOGLUV:
-			if (compress != COMPRESSION_SGILOG && compress != COMPRESSION_SGILOG24) {
-				sprintf(emsg, "Sorry, LogLuv data must have %s=%d or %d",
-				    "Compression", COMPRESSION_SGILOG, COMPRESSION_SGILOG24);
-                                goto fail_return;
-			}
-			if (planarconfig != PLANARCONFIG_CONTIG) {
-				sprintf(emsg, "Sorry, can not handle LogLuv images with %s=%d",
-				    "Planarconfiguration", planarconfig);
-				return (0);
-			}
-			TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT);
-			img->photometric = PHOTOMETRIC_RGB;		/* little white lie */
-			img->bitspersample = 8;
-			break;
-		case PHOTOMETRIC_CIELAB:
-			break;
-		default:
-			sprintf(emsg, "Sorry, can not handle image with %s=%d",
-			    photoTag, img->photometric);
-                        goto fail_return;
-	}
-	img->Map = NULL;
-	img->BWmap = NULL;
-	img->PALmap = NULL;
-	img->ycbcr = NULL;
-	img->cielab = NULL;
-	img->UaToAa = NULL;
-	img->Bitdepth16To8 = NULL;
-	TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &img->width);
-	TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &img->height);
-	TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &img->orientation);
-	img->isContig =
-	    !(planarconfig == PLANARCONFIG_SEPARATE && img->samplesperpixel > 1);
-	if (img->isContig) {
-		if (!PickContigCase(img)) {
-			sprintf(emsg, "Sorry, can not handle image");
-			goto fail_return;
-		}
-	} else {
-		if (!PickSeparateCase(img)) {
-			sprintf(emsg, "Sorry, can not handle image");
-			goto fail_return;
-		}
-	}
-	return 1;
-
-  fail_return:
-        _TIFFfree( img->redcmap );
-        _TIFFfree( img->greencmap );
-        _TIFFfree( img->bluecmap );
-        img->redcmap = img->greencmap = img->bluecmap = NULL;
-        return 0;
-}
-
-int
-TIFFRGBAImageGet(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
-{
-    if (img->get == NULL) {
-		TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No \"get\" routine setup");
-		return (0);
-	}
-	if (img->put.any == NULL) {
-		TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif),
-		"No \"put\" routine setupl; probably can not handle image format");
-		return (0);
-    }
-    return (*img->get)(img, raster, w, h);
-}
-
-/*
- * Read the specified image into an ABGR-format rastertaking in account
- * specified orientation.
- */
-int
-TIFFReadRGBAImageOriented(TIFF* tif,
-			  uint32 rwidth, uint32 rheight, uint32* raster,
-			  int orientation, int stop)
-{
-    char emsg[1024] = "";
-    TIFFRGBAImage img;
-    int ok;
-
-	if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, stop, emsg)) {
-		img.req_orientation = orientation;
-		/* XXX verify rwidth and rheight against width and height */
-		ok = TIFFRGBAImageGet(&img, raster+(rheight-img.height)*rwidth,
-			rwidth, img.height);
-		TIFFRGBAImageEnd(&img);
-	} else {
-		TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg);
-		ok = 0;
-    }
-    return (ok);
-}
-
-/*
- * Read the specified image into an ABGR-format raster. Use bottom left
- * origin for raster by default.
- */
-int
-TIFFReadRGBAImage(TIFF* tif,
-		  uint32 rwidth, uint32 rheight, uint32* raster, int stop)
-{
-	return TIFFReadRGBAImageOriented(tif, rwidth, rheight, raster,
-					 ORIENTATION_BOTLEFT, stop);
-}
-
-static int 
-setorientation(TIFFRGBAImage* img)
-{
-	switch (img->orientation) {
-		case ORIENTATION_TOPLEFT:
-		case ORIENTATION_LEFTTOP:
-			if (img->req_orientation == ORIENTATION_TOPRIGHT ||
-			    img->req_orientation == ORIENTATION_RIGHTTOP)
-				return FLIP_HORIZONTALLY;
-			else if (img->req_orientation == ORIENTATION_BOTRIGHT ||
-			    img->req_orientation == ORIENTATION_RIGHTBOT)
-				return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
-			else if (img->req_orientation == ORIENTATION_BOTLEFT ||
-			    img->req_orientation == ORIENTATION_LEFTBOT)
-				return FLIP_VERTICALLY;
-			else
-				return 0;
-		case ORIENTATION_TOPRIGHT:
-		case ORIENTATION_RIGHTTOP:
-			if (img->req_orientation == ORIENTATION_TOPLEFT ||
-			    img->req_orientation == ORIENTATION_LEFTTOP)
-				return FLIP_HORIZONTALLY;
-			else if (img->req_orientation == ORIENTATION_BOTRIGHT ||
-			    img->req_orientation == ORIENTATION_RIGHTBOT)
-				return FLIP_VERTICALLY;
-			else if (img->req_orientation == ORIENTATION_BOTLEFT ||
-			    img->req_orientation == ORIENTATION_LEFTBOT)
-				return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
-			else
-				return 0;
-		case ORIENTATION_BOTRIGHT:
-		case ORIENTATION_RIGHTBOT:
-			if (img->req_orientation == ORIENTATION_TOPLEFT ||
-			    img->req_orientation == ORIENTATION_LEFTTOP)
-				return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
-			else if (img->req_orientation == ORIENTATION_TOPRIGHT ||
-			    img->req_orientation == ORIENTATION_RIGHTTOP)
-				return FLIP_VERTICALLY;
-			else if (img->req_orientation == ORIENTATION_BOTLEFT ||
-			    img->req_orientation == ORIENTATION_LEFTBOT)
-				return FLIP_HORIZONTALLY;
-			else
-				return 0;
-		case ORIENTATION_BOTLEFT:
-		case ORIENTATION_LEFTBOT:
-			if (img->req_orientation == ORIENTATION_TOPLEFT ||
-			    img->req_orientation == ORIENTATION_LEFTTOP)
-				return FLIP_VERTICALLY;
-			else if (img->req_orientation == ORIENTATION_TOPRIGHT ||
-			    img->req_orientation == ORIENTATION_RIGHTTOP)
-				return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
-			else if (img->req_orientation == ORIENTATION_BOTRIGHT ||
-			    img->req_orientation == ORIENTATION_RIGHTBOT)
-				return FLIP_HORIZONTALLY;
-			else
-				return 0;
-		default:	/* NOTREACHED */
-			return 0;
-	}
-}
-
-/*
- * Get an tile-organized image that has
- *	PlanarConfiguration contiguous if SamplesPerPixel > 1
- * or
- *	SamplesPerPixel == 1
- */	
-static int
-gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
-{
-    TIFF* tif = img->tif;
-    tileContigRoutine put = img->put.contig;
-    uint32 col, row, y, rowstoread;
-    tmsize_t pos;
-    uint32 tw, th;
-    unsigned char* buf;
-    int32 fromskew, toskew;
-    uint32 nrow;
-    int ret = 1, flip;
-
-    buf = (unsigned char*) _TIFFmalloc(TIFFTileSize(tif));
-    if (buf == 0) {
-		TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "No space for tile buffer");
-		return (0);
-    }
-    _TIFFmemset(buf, 0, TIFFTileSize(tif));
-    TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
-    TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
-
-    flip = setorientation(img);
-    if (flip & FLIP_VERTICALLY) {
-	    y = h - 1;
-	    toskew = -(int32)(tw + w);
-    }
-    else {
-	    y = 0;
-	    toskew = -(int32)(tw - w);
-    }
-     
-    for (row = 0; row < h; row += nrow)
-    {
-        rowstoread = th - (row + img->row_offset) % th;
-    	nrow = (row + rowstoread > h ? h - row : rowstoread);
-	for (col = 0; col < w; col += tw) 
-        {
-	    if (TIFFReadTile(tif, buf, col+img->col_offset,  
-			     row+img->row_offset, 0, 0)==(tmsize_t)(-1) && img->stoponerr)
-            {
-                ret = 0;
-                break;
-            }
-	    
-	    pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif);  
-
-    	    if (col + tw > w) 
-            {
-                /*
-                 * Tile is clipped horizontally.  Calculate
-                 * visible portion and skewing factors.
-                 */
-                uint32 npix = w - col;
-                fromskew = tw - npix;
-                (*put)(img, raster+y*w+col, col, y,
-                       npix, nrow, fromskew, toskew + fromskew, buf + pos);
-            }
-            else 
-            {
-                (*put)(img, raster+y*w+col, col, y, tw, nrow, 0, toskew, buf + pos);
-            }
-        }
-
-        y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow);
-    }
-    _TIFFfree(buf);
-
-    if (flip & FLIP_HORIZONTALLY) {
-	    uint32 line;
-
-	    for (line = 0; line < h; line++) {
-		    uint32 *left = raster + (line * w);
-		    uint32 *right = left + w - 1;
-		    
-		    while ( left < right ) {
-			    uint32 temp = *left;
-			    *left = *right;
-			    *right = temp;
-			    left++, right--;
-		    }
-	    }
-    }
-
-    return (ret);
-}
-
-/*
- * Get an tile-organized image that has
- *	 SamplesPerPixel > 1
- *	 PlanarConfiguration separated
- * We assume that all such images are RGB.
- */	
-static int
-gtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
-{
-	TIFF* tif = img->tif;
-	tileSeparateRoutine put = img->put.separate;
-	uint32 col, row, y, rowstoread;
-	tmsize_t pos;
-	uint32 tw, th;
-	unsigned char* buf;
-	unsigned char* p0;
-	unsigned char* p1;
-	unsigned char* p2;
-	unsigned char* pa;
-	tmsize_t tilesize;
-	tmsize_t bufsize;
-	int32 fromskew, toskew;
-	int alpha = img->alpha;
-	uint32 nrow;
-	int ret = 1, flip;
-        int colorchannels;
-
-	tilesize = TIFFTileSize(tif);  
-	bufsize = TIFFSafeMultiply(tmsize_t,alpha?4:3,tilesize);
-	if (bufsize == 0) {
-		TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in %s", "gtTileSeparate");
-		return (0);
-	}
-	buf = (unsigned char*) _TIFFmalloc(bufsize);
-	if (buf == 0) {
-		TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "No space for tile buffer");
-		return (0);
-	}
-	_TIFFmemset(buf, 0, bufsize);
-	p0 = buf;
-	p1 = p0 + tilesize;
-	p2 = p1 + tilesize;
-	pa = (alpha?(p2+tilesize):NULL);
-	TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
-	TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
-
-	flip = setorientation(img);
-	if (flip & FLIP_VERTICALLY) {
-		y = h - 1;
-		toskew = -(int32)(tw + w);
-	}
-	else {
-		y = 0;
-		toskew = -(int32)(tw - w);
-	}
-
-        switch( img->photometric )
-        {
-          case PHOTOMETRIC_MINISWHITE:
-          case PHOTOMETRIC_MINISBLACK:
-          case PHOTOMETRIC_PALETTE:
-            colorchannels = 1;
-            p2 = p1 = p0;
-            break;
-
-          default:
-            colorchannels = 3;
-            break;
-        }
-
-	for (row = 0; row < h; row += nrow)
-	{
-		rowstoread = th - (row + img->row_offset) % th;
-		nrow = (row + rowstoread > h ? h - row : rowstoread);
-		for (col = 0; col < w; col += tw)
-		{
-			if (TIFFReadTile(tif, p0, col+img->col_offset,  
-			    row+img->row_offset,0,0)==(tmsize_t)(-1) && img->stoponerr)
-			{
-				ret = 0;
-				break;
-			}
-			if (colorchannels > 1 
-                            && TIFFReadTile(tif, p1, col+img->col_offset,  
-                                            row+img->row_offset,0,1) == (tmsize_t)(-1) 
-                            && img->stoponerr)
-			{
-				ret = 0;
-				break;
-			}
-			if (colorchannels > 1 
-                            && TIFFReadTile(tif, p2, col+img->col_offset,  
-                                            row+img->row_offset,0,2) == (tmsize_t)(-1) 
-                            && img->stoponerr)
-			{
-				ret = 0;
-				break;
-			}
-			if (alpha
-                            && TIFFReadTile(tif,pa,col+img->col_offset,  
-                                            row+img->row_offset,0,colorchannels) == (tmsize_t)(-1) 
-                            && img->stoponerr)
-                        {
-                            ret = 0;
-                            break;
-			}
-
-			pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif);  
-
-			if (col + tw > w)
-			{
-				/*
-				 * Tile is clipped horizontally.  Calculate
-				 * visible portion and skewing factors.
-				 */
-				uint32 npix = w - col;
-				fromskew = tw - npix;
-				(*put)(img, raster+y*w+col, col, y,
-				    npix, nrow, fromskew, toskew + fromskew,
-				    p0 + pos, p1 + pos, p2 + pos, (alpha?(pa+pos):NULL));
-			} else {
-				(*put)(img, raster+y*w+col, col, y,
-				    tw, nrow, 0, toskew, p0 + pos, p1 + pos, p2 + pos, (alpha?(pa+pos):NULL));
-			}
-		}
-
-		y += (flip & FLIP_VERTICALLY ?-(int32) nrow : (int32) nrow);
-	}
-
-	if (flip & FLIP_HORIZONTALLY) {
-		uint32 line;
-
-		for (line = 0; line < h; line++) {
-			uint32 *left = raster + (line * w);
-			uint32 *right = left + w - 1;
-
-			while ( left < right ) {
-				uint32 temp = *left;
-				*left = *right;
-				*right = temp;
-				left++, right--;
-			}
-		}
-	}
-
-	_TIFFfree(buf);
-	return (ret);
-}
-
-/*
- * Get a strip-organized image that has
- *	PlanarConfiguration contiguous if SamplesPerPixel > 1
- * or
- *	SamplesPerPixel == 1
- */	
-static int
-gtStripContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
-{
-	TIFF* tif = img->tif;
-	tileContigRoutine put = img->put.contig;
-	uint32 row, y, nrow, nrowsub, rowstoread;
-	tmsize_t pos;
-	unsigned char* buf;
-	uint32 rowsperstrip;
-	uint16 subsamplinghor,subsamplingver;
-	uint32 imagewidth = img->width;
-	tmsize_t scanline;
-	int32 fromskew, toskew;
-	int ret = 1, flip;
-
-	buf = (unsigned char*) _TIFFmalloc(TIFFStripSize(tif));
-	if (buf == 0) {
-		TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for strip buffer");
-		return (0);
-	}
-	_TIFFmemset(buf, 0, TIFFStripSize(tif));
-
-	flip = setorientation(img);
-	if (flip & FLIP_VERTICALLY) {
-		y = h - 1;
-		toskew = -(int32)(w + w);
-	} else {
-		y = 0;
-		toskew = -(int32)(w - w);
-	}
-
-	TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
-	TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING, &subsamplinghor, &subsamplingver);
-	scanline = TIFFScanlineSize(tif);
-	fromskew = (w < imagewidth ? imagewidth - w : 0);
-	for (row = 0; row < h; row += nrow)
-	{
-		rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip;
-		nrow = (row + rowstoread > h ? h - row : rowstoread);
-		nrowsub = nrow;
-		if ((nrowsub%subsamplingver)!=0)
-			nrowsub+=subsamplingver-nrowsub%subsamplingver;
-		if (TIFFReadEncodedStrip(tif,
-		    TIFFComputeStrip(tif,row+img->row_offset, 0),
-		    buf,
-		    ((row + img->row_offset)%rowsperstrip + nrowsub) * scanline)==(tmsize_t)(-1)
-		    && img->stoponerr)
-		{
-			ret = 0;
-			break;
-		}
-
-		pos = ((row + img->row_offset) % rowsperstrip) * scanline;
-		(*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, buf + pos);
-		y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow);
-	}
-
-	if (flip & FLIP_HORIZONTALLY) {
-		uint32 line;
-
-		for (line = 0; line < h; line++) {
-			uint32 *left = raster + (line * w);
-			uint32 *right = left + w - 1;
-
-			while ( left < right ) {
-				uint32 temp = *left;
-				*left = *right;
-				*right = temp;
-				left++, right--;
-			}
-		}
-	}
-
-	_TIFFfree(buf);
-	return (ret);
-}
-
-/*
- * Get a strip-organized image with
- *	 SamplesPerPixel > 1
- *	 PlanarConfiguration separated
- * We assume that all such images are RGB.
- */
-static int
-gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
-{
-	TIFF* tif = img->tif;
-	tileSeparateRoutine put = img->put.separate;
-	unsigned char *buf;
-	unsigned char *p0, *p1, *p2, *pa;
-	uint32 row, y, nrow, rowstoread;
-	tmsize_t pos;
-	tmsize_t scanline;
-	uint32 rowsperstrip, offset_row;
-	uint32 imagewidth = img->width;
-	tmsize_t stripsize;
-	tmsize_t bufsize;
-	int32 fromskew, toskew;
-	int alpha = img->alpha;
-	int ret = 1, flip, colorchannels;
-
-	stripsize = TIFFStripSize(tif);  
-	bufsize = TIFFSafeMultiply(tmsize_t,alpha?4:3,stripsize);
-	if (bufsize == 0) {
-		TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in %s", "gtStripSeparate");
-		return (0);
-	}
-	p0 = buf = (unsigned char *)_TIFFmalloc(bufsize);
-	if (buf == 0) {
-		TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for tile buffer");
-		return (0);
-	}
-	_TIFFmemset(buf, 0, bufsize);
-	p1 = p0 + stripsize;
-	p2 = p1 + stripsize;
-	pa = (alpha?(p2+stripsize):NULL);
-
-	flip = setorientation(img);
-	if (flip & FLIP_VERTICALLY) {
-		y = h - 1;
-		toskew = -(int32)(w + w);
-	}
-	else {
-		y = 0;
-		toskew = -(int32)(w - w);
-	}
-
-        switch( img->photometric )
-        {
-          case PHOTOMETRIC_MINISWHITE:
-          case PHOTOMETRIC_MINISBLACK:
-          case PHOTOMETRIC_PALETTE:
-            colorchannels = 1;
-            p2 = p1 = p0;
-            break;
-
-          default:
-            colorchannels = 3;
-            break;
-        }
-
-	TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
-	scanline = TIFFScanlineSize(tif);  
-	fromskew = (w < imagewidth ? imagewidth - w : 0);
-	for (row = 0; row < h; row += nrow)
-	{
-		rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip;
-		nrow = (row + rowstoread > h ? h - row : rowstoread);
-		offset_row = row + img->row_offset;
-		if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 0),
-		    p0, ((row + img->row_offset)%rowsperstrip + nrow) * scanline)==(tmsize_t)(-1)
-		    && img->stoponerr)
-		{
-			ret = 0;
-			break;
-		}
-		if (colorchannels > 1 
-                    && TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 1),
-                                            p1, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) == (tmsize_t)(-1)
-		    && img->stoponerr)
-		{
-			ret = 0;
-			break;
-		}
-		if (colorchannels > 1 
-                    && TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 2),
-                                            p2, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) == (tmsize_t)(-1)
-		    && img->stoponerr)
-		{
-			ret = 0;
-			break;
-		}
-		if (alpha)
-		{
-			if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, colorchannels),
-			    pa, ((row + img->row_offset)%rowsperstrip + nrow) * scanline)==(tmsize_t)(-1)
-			    && img->stoponerr)
-			{
-				ret = 0;
-				break;
-			}
-		}
-
-		pos = ((row + img->row_offset) % rowsperstrip) * scanline;
-		(*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, p0 + pos, p1 + pos,
-		    p2 + pos, (alpha?(pa+pos):NULL));
-		y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow);
-	}
-
-	if (flip & FLIP_HORIZONTALLY) {
-		uint32 line;
-
-		for (line = 0; line < h; line++) {
-			uint32 *left = raster + (line * w);
-			uint32 *right = left + w - 1;
-
-			while ( left < right ) {
-				uint32 temp = *left;
-				*left = *right;
-				*right = temp;
-				left++, right--;
-			}
-		}
-	}
-
-	_TIFFfree(buf);
-	return (ret);
-}
-
-/*
- * The following routines move decoded data returned
- * from the TIFF library into rasters filled with packed
- * ABGR pixels (i.e. suitable for passing to lrecwrite.)
- *
- * The routines have been created according to the most
- * important cases and optimized.  PickContigCase and
- * PickSeparateCase analyze the parameters and select
- * the appropriate "get" and "put" routine to use.
- */
-#define	REPEAT8(op)	REPEAT4(op); REPEAT4(op)
-#define	REPEAT4(op)	REPEAT2(op); REPEAT2(op)
-#define	REPEAT2(op)	op; op
-#define	CASE8(x,op)			\
-    switch (x) {			\
-    case 7: op; case 6: op; case 5: op;	\
-    case 4: op; case 3: op; case 2: op;	\
-    case 1: op;				\
-    }
-#define	CASE4(x,op)	switch (x) { case 3: op; case 2: op; case 1: op; }
-#define	NOP
-
-#define	UNROLL8(w, op1, op2) {		\
-    uint32 _x;				\
-    for (_x = w; _x >= 8; _x -= 8) {	\
-	op1;				\
-	REPEAT8(op2);			\
-    }					\
-    if (_x > 0) {			\
-	op1;				\
-	CASE8(_x,op2);			\
-    }					\
-}
-#define	UNROLL4(w, op1, op2) {		\
-    uint32 _x;				\
-    for (_x = w; _x >= 4; _x -= 4) {	\
-	op1;				\
-	REPEAT4(op2);			\
-    }					\
-    if (_x > 0) {			\
-	op1;				\
-	CASE4(_x,op2);			\
-    }					\
-}
-#define	UNROLL2(w, op1, op2) {		\
-    uint32 _x;				\
-    for (_x = w; _x >= 2; _x -= 2) {	\
-	op1;				\
-	REPEAT2(op2);			\
-    }					\
-    if (_x) {				\
-	op1;				\
-	op2;				\
-    }					\
-}
-    
-#define	SKEW(r,g,b,skew)	{ r += skew; g += skew; b += skew; }
-#define	SKEW4(r,g,b,a,skew)	{ r += skew; g += skew; b += skew; a+= skew; }
-
-#define A1 (((uint32)0xffL)<<24)
-#define	PACK(r,g,b)	\
-	((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|A1)
-#define	PACK4(r,g,b,a)	\
-	((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|((uint32)(a)<<24))
-#define W2B(v) (((v)>>8)&0xff)
-/* TODO: PACKW should have be made redundant in favor of Bitdepth16To8 LUT */
-#define	PACKW(r,g,b)	\
-	((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|A1)
-#define	PACKW4(r,g,b,a)	\
-	((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|((uint32)W2B(a)<<24))
-
-#define	DECLAREContigPutFunc(name) \
-static void name(\
-    TIFFRGBAImage* img, \
-    uint32* cp, \
-    uint32 x, uint32 y, \
-    uint32 w, uint32 h, \
-    int32 fromskew, int32 toskew, \
-    unsigned char* pp \
-)
-
-/*
- * 8-bit palette => colormap/RGB
- */
-DECLAREContigPutFunc(put8bitcmaptile)
-{
-    uint32** PALmap = img->PALmap;
-    int samplesperpixel = img->samplesperpixel;
-
-    (void) y;
-    while (h-- > 0) {
-	for (x = w; x-- > 0;)
-        {
-	    *cp++ = PALmap[*pp][0];
-            pp += samplesperpixel;
-        }
-	cp += toskew;
-	pp += fromskew;
-    }
-}
-
-/*
- * 4-bit palette => colormap/RGB
- */
-DECLAREContigPutFunc(put4bitcmaptile)
-{
-    uint32** PALmap = img->PALmap;
-
-    (void) x; (void) y;
-    fromskew /= 2;
-    while (h-- > 0) {
-	uint32* bw;
-	UNROLL2(w, bw = PALmap[*pp++], *cp++ = *bw++);
-	cp += toskew;
-	pp += fromskew;
-    }
-}
-
-/*
- * 2-bit palette => colormap/RGB
- */
-DECLAREContigPutFunc(put2bitcmaptile)
-{
-    uint32** PALmap = img->PALmap;
-
-    (void) x; (void) y;
-    fromskew /= 4;
-    while (h-- > 0) {
-	uint32* bw;
-	UNROLL4(w, bw = PALmap[*pp++], *cp++ = *bw++);
-	cp += toskew;
-	pp += fromskew;
-    }
-}
-
-/*
- * 1-bit palette => colormap/RGB
- */
-DECLAREContigPutFunc(put1bitcmaptile)
-{
-    uint32** PALmap = img->PALmap;
-
-    (void) x; (void) y;
-    fromskew /= 8;
-    while (h-- > 0) {
-	uint32* bw;
-	UNROLL8(w, bw = PALmap[*pp++], *cp++ = *bw++);
-	cp += toskew;
-	pp += fromskew;
-    }
-}
-
-/*
- * 8-bit greyscale => colormap/RGB
- */
-DECLAREContigPutFunc(putgreytile)
-{
-    int samplesperpixel = img->samplesperpixel;
-    uint32** BWmap = img->BWmap;
-
-    (void) y;
-    while (h-- > 0) {
-	for (x = w; x-- > 0;)
-        {
-	    *cp++ = BWmap[*pp][0];
-            pp += samplesperpixel;
-        }
-	cp += toskew;
-	pp += fromskew;
-    }
-}
-
-/*
- * 8-bit greyscale with associated alpha => colormap/RGBA
- */
-DECLAREContigPutFunc(putagreytile)
-{
-    int samplesperpixel = img->samplesperpixel;
-    uint32** BWmap = img->BWmap;
-
-    (void) y;
-    while (h-- > 0) {
-	for (x = w; x-- > 0;)
-        {
-            *cp++ = BWmap[*pp][0] & (*(pp+1) << 24 | ~A1);
-            pp += samplesperpixel;
-        }
-	cp += toskew;
-	pp += fromskew;
-    }
-}
-
-/*
- * 16-bit greyscale => colormap/RGB
- */
-DECLAREContigPutFunc(put16bitbwtile)
-{
-    int samplesperpixel = img->samplesperpixel;
-    uint32** BWmap = img->BWmap;
-
-    (void) y;
-    while (h-- > 0) {
-        uint16 *wp = (uint16 *) pp;
-
-	for (x = w; x-- > 0;)
-        {
-            /* use high order byte of 16bit value */
-
-	    *cp++ = BWmap[*wp >> 8][0];
-            pp += 2 * samplesperpixel;
-            wp += samplesperpixel;
-        }
-	cp += toskew;
-	pp += fromskew;
-    }
-}
-
-/*
- * 1-bit bilevel => colormap/RGB
- */
-DECLAREContigPutFunc(put1bitbwtile)
-{
-    uint32** BWmap = img->BWmap;
-
-    (void) x; (void) y;
-    fromskew /= 8;
-    while (h-- > 0) {
-	uint32* bw;
-	UNROLL8(w, bw = BWmap[*pp++], *cp++ = *bw++);
-	cp += toskew;
-	pp += fromskew;
-    }
-}
-
-/*
- * 2-bit greyscale => colormap/RGB
- */
-DECLAREContigPutFunc(put2bitbwtile)
-{
-    uint32** BWmap = img->BWmap;
-
-    (void) x; (void) y;
-    fromskew /= 4;
-    while (h-- > 0) {
-	uint32* bw;
-	UNROLL4(w, bw = BWmap[*pp++], *cp++ = *bw++);
-	cp += toskew;
-	pp += fromskew;
-    }
-}
-
-/*
- * 4-bit greyscale => colormap/RGB
- */
-DECLAREContigPutFunc(put4bitbwtile)
-{
-    uint32** BWmap = img->BWmap;
-
-    (void) x; (void) y;
-    fromskew /= 2;
-    while (h-- > 0) {
-	uint32* bw;
-	UNROLL2(w, bw = BWmap[*pp++], *cp++ = *bw++);
-	cp += toskew;
-	pp += fromskew;
-    }
-}
-
-/*
- * 8-bit packed samples, no Map => RGB
- */
-DECLAREContigPutFunc(putRGBcontig8bittile)
-{
-    int samplesperpixel = img->samplesperpixel;
-
-    (void) x; (void) y;
-    fromskew *= samplesperpixel;
-    while (h-- > 0) {
-	UNROLL8(w, NOP,
-	    *cp++ = PACK(pp[0], pp[1], pp[2]);
-	    pp += samplesperpixel);
-	cp += toskew;
-	pp += fromskew;
-    }
-}
-
-/*
- * 8-bit packed samples => RGBA w/ associated alpha
- * (known to have Map == NULL)
- */
-DECLAREContigPutFunc(putRGBAAcontig8bittile)
-{
-    int samplesperpixel = img->samplesperpixel;
-
-    (void) x; (void) y;
-    fromskew *= samplesperpixel;
-    while (h-- > 0) {
-	UNROLL8(w, NOP,
-	    *cp++ = PACK4(pp[0], pp[1], pp[2], pp[3]);
-	    pp += samplesperpixel);
-	cp += toskew;
-	pp += fromskew;
-    }
-}
-
-/*
- * 8-bit packed samples => RGBA w/ unassociated alpha
- * (known to have Map == NULL)
- */
-DECLAREContigPutFunc(putRGBUAcontig8bittile)
-{
-	int samplesperpixel = img->samplesperpixel;
-	(void) y;
-	fromskew *= samplesperpixel;
-	while (h-- > 0) {
-		uint32 r, g, b, a;
-		uint8* m;
-		for (x = w; x-- > 0;) {
-			a = pp[3];
-			m = img->UaToAa+(a<<8);
-			r = m[pp[0]];
-			g = m[pp[1]];
-			b = m[pp[2]];
-			*cp++ = PACK4(r,g,b,a);
-			pp += samplesperpixel;
-		}
-		cp += toskew;
-		pp += fromskew;
-	}
-}
-
-/*
- * 16-bit packed samples => RGB
- */
-DECLAREContigPutFunc(putRGBcontig16bittile)
-{
-	int samplesperpixel = img->samplesperpixel;
-	uint16 *wp = (uint16 *)pp;
-	(void) y;
-	fromskew *= samplesperpixel;
-	while (h-- > 0) {
-		for (x = w; x-- > 0;) {
-			*cp++ = PACK(img->Bitdepth16To8[wp[0]],
-			    img->Bitdepth16To8[wp[1]],
-			    img->Bitdepth16To8[wp[2]]);
-			wp += samplesperpixel;
-		}
-		cp += toskew;
-		wp += fromskew;
-	}
-}
-
-/*
- * 16-bit packed samples => RGBA w/ associated alpha
- * (known to have Map == NULL)
- */
-DECLAREContigPutFunc(putRGBAAcontig16bittile)
-{
-	int samplesperpixel = img->samplesperpixel;
-	uint16 *wp = (uint16 *)pp;
-	(void) y;
-	fromskew *= samplesperpixel;
-	while (h-- > 0) {
-		for (x = w; x-- > 0;) {
-			*cp++ = PACK4(img->Bitdepth16To8[wp[0]],
-			    img->Bitdepth16To8[wp[1]],
-			    img->Bitdepth16To8[wp[2]],
-			    img->Bitdepth16To8[wp[3]]);
-			wp += samplesperpixel;
-		}
-		cp += toskew;
-		wp += fromskew;
-	}
-}
-
-/*
- * 16-bit packed samples => RGBA w/ unassociated alpha
- * (known to have Map == NULL)
- */
-DECLAREContigPutFunc(putRGBUAcontig16bittile)
-{
-	int samplesperpixel = img->samplesperpixel;
-	uint16 *wp = (uint16 *)pp;
-	(void) y;
-	fromskew *= samplesperpixel;
-	while (h-- > 0) {
-		uint32 r,g,b,a;
-		uint8* m;
-		for (x = w; x-- > 0;) {
-			a = img->Bitdepth16To8[wp[3]];
-			m = img->UaToAa+(a<<8);
-			r = m[img->Bitdepth16To8[wp[0]]];
-			g = m[img->Bitdepth16To8[wp[1]]];
-			b = m[img->Bitdepth16To8[wp[2]]];
-			*cp++ = PACK4(r,g,b,a);
-			wp += samplesperpixel;
-		}
-		cp += toskew;
-		wp += fromskew;
-	}
-}
-
-/*
- * 8-bit packed CMYK samples w/o Map => RGB
- *
- * NB: The conversion of CMYK->RGB is *very* crude.
- */
-DECLAREContigPutFunc(putRGBcontig8bitCMYKtile)
-{
-    int samplesperpixel = img->samplesperpixel;
-    uint16 r, g, b, k;
-
-    (void) x; (void) y;
-    fromskew *= samplesperpixel;
-    while (h-- > 0) {
-	UNROLL8(w, NOP,
-	    k = 255 - pp[3];
-	    r = (k*(255-pp[0]))/255;
-	    g = (k*(255-pp[1]))/255;
-	    b = (k*(255-pp[2]))/255;
-	    *cp++ = PACK(r, g, b);
-	    pp += samplesperpixel);
-	cp += toskew;
-	pp += fromskew;
-    }
-}
-
-/*
- * 8-bit packed CMYK samples w/Map => RGB
- *
- * NB: The conversion of CMYK->RGB is *very* crude.
- */
-DECLAREContigPutFunc(putRGBcontig8bitCMYKMaptile)
-{
-    int samplesperpixel = img->samplesperpixel;
-    TIFFRGBValue* Map = img->Map;
-    uint16 r, g, b, k;
-
-    (void) y;
-    fromskew *= samplesperpixel;
-    while (h-- > 0) {
-	for (x = w; x-- > 0;) {
-	    k = 255 - pp[3];
-	    r = (k*(255-pp[0]))/255;
-	    g = (k*(255-pp[1]))/255;
-	    b = (k*(255-pp[2]))/255;
-	    *cp++ = PACK(Map[r], Map[g], Map[b]);
-	    pp += samplesperpixel;
-	}
-	pp += fromskew;
-	cp += toskew;
-    }
-}
-
-#define	DECLARESepPutFunc(name) \
-static void name(\
-    TIFFRGBAImage* img,\
-    uint32* cp,\
-    uint32 x, uint32 y, \
-    uint32 w, uint32 h,\
-    int32 fromskew, int32 toskew,\
-    unsigned char* r, unsigned char* g, unsigned char* b, unsigned char* a\
-)
-
-/*
- * 8-bit unpacked samples => RGB
- */
-DECLARESepPutFunc(putRGBseparate8bittile)
-{
-    (void) img; (void) x; (void) y; (void) a;
-    while (h-- > 0) {
-	UNROLL8(w, NOP, *cp++ = PACK(*r++, *g++, *b++));
-	SKEW(r, g, b, fromskew);
-	cp += toskew;
-    }
-}
-
-/*
- * 8-bit unpacked samples => RGBA w/ associated alpha
- */
-DECLARESepPutFunc(putRGBAAseparate8bittile)
-{
-	(void) img; (void) x; (void) y; 
-	while (h-- > 0) {
-		UNROLL8(w, NOP, *cp++ = PACK4(*r++, *g++, *b++, *a++));
-		SKEW4(r, g, b, a, fromskew);
-		cp += toskew;
-	}
-}
-
-/*
- * 8-bit unpacked CMYK samples => RGBA
- */
-DECLARESepPutFunc(putCMYKseparate8bittile)
-{
-	(void) img; (void) y;
-	while (h-- > 0) {
-		uint32 rv, gv, bv, kv;
-		for (x = w; x-- > 0;) {
-			kv = 255 - *a++;
-			rv = (kv*(255-*r++))/255;
-			gv = (kv*(255-*g++))/255;
-			bv = (kv*(255-*b++))/255;
-			*cp++ = PACK4(rv,gv,bv,255);
-		}
-		SKEW4(r, g, b, a, fromskew);
-		cp += toskew;
-	}
-}
-
-/*
- * 8-bit unpacked samples => RGBA w/ unassociated alpha
- */
-DECLARESepPutFunc(putRGBUAseparate8bittile)
-{
-	(void) img; (void) y;
-	while (h-- > 0) {
-		uint32 rv, gv, bv, av;
-		uint8* m;
-		for (x = w; x-- > 0;) {
-			av = *a++;
-			m = img->UaToAa+(av<<8);
-			rv = m[*r++];
-			gv = m[*g++];
-			bv = m[*b++];
-			*cp++ = PACK4(rv,gv,bv,av);
-		}
-		SKEW4(r, g, b, a, fromskew);
-		cp += toskew;
-	}
-}
-
-/*
- * 16-bit unpacked samples => RGB
- */
-DECLARESepPutFunc(putRGBseparate16bittile)
-{
-	uint16 *wr = (uint16*) r;
-	uint16 *wg = (uint16*) g;
-	uint16 *wb = (uint16*) b;
-	(void) img; (void) y; (void) a;
-	while (h-- > 0) {
-		for (x = 0; x < w; x++)
-			*cp++ = PACK(img->Bitdepth16To8[*wr++],
-			    img->Bitdepth16To8[*wg++],
-			    img->Bitdepth16To8[*wb++]);
-		SKEW(wr, wg, wb, fromskew);
-		cp += toskew;
-	}
-}
-
-/*
- * 16-bit unpacked samples => RGBA w/ associated alpha
- */
-DECLARESepPutFunc(putRGBAAseparate16bittile)
-{
-	uint16 *wr = (uint16*) r;
-	uint16 *wg = (uint16*) g;
-	uint16 *wb = (uint16*) b;
-	uint16 *wa = (uint16*) a;
-	(void) img; (void) y;
-	while (h-- > 0) {
-		for (x = 0; x < w; x++)
-			*cp++ = PACK4(img->Bitdepth16To8[*wr++],
-			    img->Bitdepth16To8[*wg++],
-			    img->Bitdepth16To8[*wb++],
-			    img->Bitdepth16To8[*wa++]);
-		SKEW4(wr, wg, wb, wa, fromskew);
-		cp += toskew;
-	}
-}
-
-/*
- * 16-bit unpacked samples => RGBA w/ unassociated alpha
- */
-DECLARESepPutFunc(putRGBUAseparate16bittile)
-{
-	uint16 *wr = (uint16*) r;
-	uint16 *wg = (uint16*) g;
-	uint16 *wb = (uint16*) b;
-	uint16 *wa = (uint16*) a;
-	(void) img; (void) y;
-	while (h-- > 0) {
-		uint32 r,g,b,a;
-		uint8* m;
-		for (x = w; x-- > 0;) {
-			a = img->Bitdepth16To8[*wa++];
-			m = img->UaToAa+(a<<8);
-			r = m[img->Bitdepth16To8[*wr++]];
-			g = m[img->Bitdepth16To8[*wg++]];
-			b = m[img->Bitdepth16To8[*wb++]];
-			*cp++ = PACK4(r,g,b,a);
-		}
-		SKEW4(wr, wg, wb, wa, fromskew);
-		cp += toskew;
-	}
-}
-
-/*
- * 8-bit packed CIE L*a*b 1976 samples => RGB
- */
-DECLAREContigPutFunc(putcontig8bitCIELab)
-{
-	float X, Y, Z;
-	uint32 r, g, b;
-	(void) y;
-	fromskew *= 3;
-	while (h-- > 0) {
-		for (x = w; x-- > 0;) {
-			TIFFCIELabToXYZ(img->cielab,
-					(unsigned char)pp[0],
-					(signed char)pp[1],
-					(signed char)pp[2],
-					&X, &Y, &Z);
-			TIFFXYZToRGB(img->cielab, X, Y, Z, &r, &g, &b);
-			*cp++ = PACK(r, g, b);
-			pp += 3;
-		}
-		cp += toskew;
-		pp += fromskew;
-	}
-}
-
-/*
- * YCbCr -> RGB conversion and packing routines.
- */
-
-#define	YCbCrtoRGB(dst, Y) {						\
-	uint32 r, g, b;							\
-	TIFFYCbCrtoRGB(img->ycbcr, (Y), Cb, Cr, &r, &g, &b);		\
-	dst = PACK(r, g, b);						\
-}
-
-/*
- * 8-bit packed YCbCr samples => RGB 
- * This function is generic for different sampling sizes, 
- * and can handle blocks sizes that aren't multiples of the
- * sampling size.  However, it is substantially less optimized
- * than the specific sampling cases.  It is used as a fallback
- * for difficult blocks.
- */
-#ifdef notdef
-static void putcontig8bitYCbCrGenericTile( 
-    TIFFRGBAImage* img, 
-    uint32* cp, 
-    uint32 x, uint32 y, 
-    uint32 w, uint32 h, 
-    int32 fromskew, int32 toskew, 
-    unsigned char* pp,
-    int h_group, 
-    int v_group )
-
-{
-    uint32* cp1 = cp+w+toskew;
-    uint32* cp2 = cp1+w+toskew;
-    uint32* cp3 = cp2+w+toskew;
-    int32 incr = 3*w+4*toskew;
-    int32   Cb, Cr;
-    int     group_size = v_group * h_group + 2;
-
-    (void) y;
-    fromskew = (fromskew * group_size) / h_group;
-
-    for( yy = 0; yy < h; yy++ )
-    {
-        unsigned char *pp_line;
-        int     y_line_group = yy / v_group;
-        int     y_remainder = yy - y_line_group * v_group;
-
-        pp_line = pp + v_line_group * 
-
-        
-        for( xx = 0; xx < w; xx++ )
-        {
-            Cb = pp
-        }
-    }
-    for (; h >= 4; h -= 4) {
-	x = w>>2;
-	do {
-	    Cb = pp[16];
-	    Cr = pp[17];
-
-	    YCbCrtoRGB(cp [0], pp[ 0]);
-	    YCbCrtoRGB(cp [1], pp[ 1]);
-	    YCbCrtoRGB(cp [2], pp[ 2]);
-	    YCbCrtoRGB(cp [3], pp[ 3]);
-	    YCbCrtoRGB(cp1[0], pp[ 4]);
-	    YCbCrtoRGB(cp1[1], pp[ 5]);
-	    YCbCrtoRGB(cp1[2], pp[ 6]);
-	    YCbCrtoRGB(cp1[3], pp[ 7]);
-	    YCbCrtoRGB(cp2[0], pp[ 8]);
-	    YCbCrtoRGB(cp2[1], pp[ 9]);
-	    YCbCrtoRGB(cp2[2], pp[10]);
-	    YCbCrtoRGB(cp2[3], pp[11]);
-	    YCbCrtoRGB(cp3[0], pp[12]);
-	    YCbCrtoRGB(cp3[1], pp[13]);
-	    YCbCrtoRGB(cp3[2], pp[14]);
-	    YCbCrtoRGB(cp3[3], pp[15]);
-
-	    cp += 4, cp1 += 4, cp2 += 4, cp3 += 4;
-	    pp += 18;
-	} while (--x);
-	cp += incr, cp1 += incr, cp2 += incr, cp3 += incr;
-	pp += fromskew;
-    }
-}
-#endif
-
-/*
- * 8-bit packed YCbCr samples w/ 4,4 subsampling => RGB
- */
-DECLAREContigPutFunc(putcontig8bitYCbCr44tile)
-{
-    uint32* cp1 = cp+w+toskew;
-    uint32* cp2 = cp1+w+toskew;
-    uint32* cp3 = cp2+w+toskew;
-    int32 incr = 3*w+4*toskew;
-
-    (void) y;
-    /* adjust fromskew */
-    fromskew = (fromskew * 18) / 4;
-    if ((h & 3) == 0 && (w & 3) == 0) {				        
-        for (; h >= 4; h -= 4) {
-            x = w>>2;
-            do {
-                int32 Cb = pp[16];
-                int32 Cr = pp[17];
-
-                YCbCrtoRGB(cp [0], pp[ 0]);
-                YCbCrtoRGB(cp [1], pp[ 1]);
-                YCbCrtoRGB(cp [2], pp[ 2]);
-                YCbCrtoRGB(cp [3], pp[ 3]);
-                YCbCrtoRGB(cp1[0], pp[ 4]);
-                YCbCrtoRGB(cp1[1], pp[ 5]);
-                YCbCrtoRGB(cp1[2], pp[ 6]);
-                YCbCrtoRGB(cp1[3], pp[ 7]);
-                YCbCrtoRGB(cp2[0], pp[ 8]);
-                YCbCrtoRGB(cp2[1], pp[ 9]);
-                YCbCrtoRGB(cp2[2], pp[10]);
-                YCbCrtoRGB(cp2[3], pp[11]);
-                YCbCrtoRGB(cp3[0], pp[12]);
-                YCbCrtoRGB(cp3[1], pp[13]);
-                YCbCrtoRGB(cp3[2], pp[14]);
-                YCbCrtoRGB(cp3[3], pp[15]);
-
-                cp += 4, cp1 += 4, cp2 += 4, cp3 += 4;
-                pp += 18;
-            } while (--x);
-            cp += incr, cp1 += incr, cp2 += incr, cp3 += incr;
-            pp += fromskew;
-        }
-    } else {
-        while (h > 0) {
-            for (x = w; x > 0;) {
-                int32 Cb = pp[16];
-                int32 Cr = pp[17];
-                switch (x) {
-                default:
-                    switch (h) {
-                    default: YCbCrtoRGB(cp3[3], pp[15]); /* FALLTHROUGH */
-                    case 3:  YCbCrtoRGB(cp2[3], pp[11]); /* FALLTHROUGH */
-                    case 2:  YCbCrtoRGB(cp1[3], pp[ 7]); /* FALLTHROUGH */
-                    case 1:  YCbCrtoRGB(cp [3], pp[ 3]); /* FALLTHROUGH */
-                    }                                    /* FALLTHROUGH */
-                case 3:
-                    switch (h) {
-                    default: YCbCrtoRGB(cp3[2], pp[14]); /* FALLTHROUGH */
-                    case 3:  YCbCrtoRGB(cp2[2], pp[10]); /* FALLTHROUGH */
-                    case 2:  YCbCrtoRGB(cp1[2], pp[ 6]); /* FALLTHROUGH */
-                    case 1:  YCbCrtoRGB(cp [2], pp[ 2]); /* FALLTHROUGH */
-                    }                                    /* FALLTHROUGH */
-                case 2:
-                    switch (h) {
-                    default: YCbCrtoRGB(cp3[1], pp[13]); /* FALLTHROUGH */
-                    case 3:  YCbCrtoRGB(cp2[1], pp[ 9]); /* FALLTHROUGH */
-                    case 2:  YCbCrtoRGB(cp1[1], pp[ 5]); /* FALLTHROUGH */
-                    case 1:  YCbCrtoRGB(cp [1], pp[ 1]); /* FALLTHROUGH */
-                    }                                    /* FALLTHROUGH */
-                case 1:
-                    switch (h) {
-                    default: YCbCrtoRGB(cp3[0], pp[12]); /* FALLTHROUGH */
-                    case 3:  YCbCrtoRGB(cp2[0], pp[ 8]); /* FALLTHROUGH */
-                    case 2:  YCbCrtoRGB(cp1[0], pp[ 4]); /* FALLTHROUGH */
-                    case 1:  YCbCrtoRGB(cp [0], pp[ 0]); /* FALLTHROUGH */
-                    }                                    /* FALLTHROUGH */
-                }
-                if (x < 4) {
-                    cp += x; cp1 += x; cp2 += x; cp3 += x;
-                    x = 0;
-                }
-                else {
-                    cp += 4; cp1 += 4; cp2 += 4; cp3 += 4;
-                    x -= 4;
-                }
-                pp += 18;
-            }
-            if (h <= 4)
-                break;
-            h -= 4;
-            cp += incr, cp1 += incr, cp2 += incr, cp3 += incr;
-            pp += fromskew;
-        }
-    }
-}
-
-/*
- * 8-bit packed YCbCr samples w/ 4,2 subsampling => RGB
- */
-DECLAREContigPutFunc(putcontig8bitYCbCr42tile)
-{
-    uint32* cp1 = cp+w+toskew;
-    int32 incr = 2*toskew+w;
-
-    (void) y;
-    fromskew = (fromskew * 10) / 4;
-    if ((h & 3) == 0 && (w & 1) == 0) {
-        for (; h >= 2; h -= 2) {
-            x = w>>2;
-            do {
-                int32 Cb = pp[8];
-                int32 Cr = pp[9];
-                
-                YCbCrtoRGB(cp [0], pp[0]);
-                YCbCrtoRGB(cp [1], pp[1]);
-                YCbCrtoRGB(cp [2], pp[2]);
-                YCbCrtoRGB(cp [3], pp[3]);
-                YCbCrtoRGB(cp1[0], pp[4]);
-                YCbCrtoRGB(cp1[1], pp[5]);
-                YCbCrtoRGB(cp1[2], pp[6]);
-                YCbCrtoRGB(cp1[3], pp[7]);
-                
-                cp += 4, cp1 += 4;
-                pp += 10;
-            } while (--x);
-            cp += incr, cp1 += incr;
-            pp += fromskew;
-        }
-    } else {
-        while (h > 0) {
-            for (x = w; x > 0;) {
-                int32 Cb = pp[8];
-                int32 Cr = pp[9];
-                switch (x) {
-                default:
-                    switch (h) {
-                    default: YCbCrtoRGB(cp1[3], pp[ 7]); /* FALLTHROUGH */
-                    case 1:  YCbCrtoRGB(cp [3], pp[ 3]); /* FALLTHROUGH */
-                    }                                    /* FALLTHROUGH */
-                case 3:
-                    switch (h) {
-                    default: YCbCrtoRGB(cp1[2], pp[ 6]); /* FALLTHROUGH */
-                    case 1:  YCbCrtoRGB(cp [2], pp[ 2]); /* FALLTHROUGH */
-                    }                                    /* FALLTHROUGH */
-                case 2:
-                    switch (h) {
-                    default: YCbCrtoRGB(cp1[1], pp[ 5]); /* FALLTHROUGH */
-                    case 1:  YCbCrtoRGB(cp [1], pp[ 1]); /* FALLTHROUGH */
-                    }                                    /* FALLTHROUGH */
-                case 1:
-                    switch (h) {
-                    default: YCbCrtoRGB(cp1[0], pp[ 4]); /* FALLTHROUGH */
-                    case 1:  YCbCrtoRGB(cp [0], pp[ 0]); /* FALLTHROUGH */
-                    }                                    /* FALLTHROUGH */
-                }
-                if (x < 4) {
-                    cp += x; cp1 += x;
-                    x = 0;
-                }
-                else {
-                    cp += 4; cp1 += 4;
-                    x -= 4;
-                }
-                pp += 10;
-            }
-            if (h <= 2)
-                break;
-            h -= 2;
-            cp += incr, cp1 += incr;
-            pp += fromskew;
-        }
-    }
-}
-
-/*
- * 8-bit packed YCbCr samples w/ 4,1 subsampling => RGB
- */
-DECLAREContigPutFunc(putcontig8bitYCbCr41tile)
-{
-    (void) y;
-    /* XXX adjust fromskew */
-    do {
-	x = w>>2;
-	do {
-	    int32 Cb = pp[4];
-	    int32 Cr = pp[5];
-
-	    YCbCrtoRGB(cp [0], pp[0]);
-	    YCbCrtoRGB(cp [1], pp[1]);
-	    YCbCrtoRGB(cp [2], pp[2]);
-	    YCbCrtoRGB(cp [3], pp[3]);
-
-	    cp += 4;
-	    pp += 6;
-	} while (--x);
-
-        if( (w&3) != 0 )
-        {
-	    int32 Cb = pp[4];
-	    int32 Cr = pp[5];
-
-            switch( (w&3) ) {
-              case 3: YCbCrtoRGB(cp [2], pp[2]);
-              case 2: YCbCrtoRGB(cp [1], pp[1]);
-              case 1: YCbCrtoRGB(cp [0], pp[0]);
-              case 0: break;
-            }
-
-            cp += (w&3);
-            pp += 6;
-        }
-
-	cp += toskew;
-	pp += fromskew;
-    } while (--h);
-
-}
-
-/*
- * 8-bit packed YCbCr samples w/ 2,2 subsampling => RGB
- */
-DECLAREContigPutFunc(putcontig8bitYCbCr22tile)
-{
-	uint32* cp2;
-	int32 incr = 2*toskew+w;
-	(void) y;
-	fromskew = (fromskew / 2) * 6;
-	cp2 = cp+w+toskew;
-	while (h>=2) {
-		x = w;
-		while (x>=2) {
-			uint32 Cb = pp[4];
-			uint32 Cr = pp[5];
-			YCbCrtoRGB(cp[0], pp[0]);
-			YCbCrtoRGB(cp[1], pp[1]);
-			YCbCrtoRGB(cp2[0], pp[2]);
-			YCbCrtoRGB(cp2[1], pp[3]);
-			cp += 2;
-			cp2 += 2;
-			pp += 6;
-			x -= 2;
-		}
-		if (x==1) {
-			uint32 Cb = pp[4];
-			uint32 Cr = pp[5];
-			YCbCrtoRGB(cp[0], pp[0]);
-			YCbCrtoRGB(cp2[0], pp[2]);
-			cp ++ ;
-			cp2 ++ ;
-			pp += 6;
-		}
-		cp += incr;
-		cp2 += incr;
-		pp += fromskew;
-		h-=2;
-	}
-	if (h==1) {
-		x = w;
-		while (x>=2) {
-			uint32 Cb = pp[4];
-			uint32 Cr = pp[5];
-			YCbCrtoRGB(cp[0], pp[0]);
-			YCbCrtoRGB(cp[1], pp[1]);
-			cp += 2;
-			cp2 += 2;
-			pp += 6;
-			x -= 2;
-		}
-		if (x==1) {
-			uint32 Cb = pp[4];
-			uint32 Cr = pp[5];
-			YCbCrtoRGB(cp[0], pp[0]);
-		}
-	}
-}
-
-/*
- * 8-bit packed YCbCr samples w/ 2,1 subsampling => RGB
- */
-DECLAREContigPutFunc(putcontig8bitYCbCr21tile)
-{
-	(void) y;
-	fromskew = (fromskew * 4) / 2;
-	do {
-		x = w>>1;
-		do {
-			int32 Cb = pp[2];
-			int32 Cr = pp[3];
-
-			YCbCrtoRGB(cp[0], pp[0]);
-			YCbCrtoRGB(cp[1], pp[1]);
-
-			cp += 2;
-			pp += 4;
-		} while (--x);
-
-		if( (w&1) != 0 )
-		{
-			int32 Cb = pp[2];
-			int32 Cr = pp[3];
-
-			YCbCrtoRGB(cp[0], pp[0]);
-
-			cp += 1;
-			pp += 4;
-		}
-
-		cp += toskew;
-		pp += fromskew;
-	} while (--h);
-}
-
-/*
- * 8-bit packed YCbCr samples w/ 1,2 subsampling => RGB
- */
-DECLAREContigPutFunc(putcontig8bitYCbCr12tile)
-{
-	uint32* cp2;
-	int32 incr = 2*toskew+w;
-	(void) y;
-	fromskew = (fromskew / 2) * 4;
-	cp2 = cp+w+toskew;
-	while (h>=2) {
-		x = w;
-		do {
-			uint32 Cb = pp[2];
-			uint32 Cr = pp[3];
-			YCbCrtoRGB(cp[0], pp[0]);
-			YCbCrtoRGB(cp2[0], pp[1]);
-			cp ++;
-			cp2 ++;
-			pp += 4;
-		} while (--x);
-		cp += incr;
-		cp2 += incr;
-		pp += fromskew;
-		h-=2;
-	}
-	if (h==1) {
-		x = w;
-		do {
-			uint32 Cb = pp[2];
-			uint32 Cr = pp[3];
-			YCbCrtoRGB(cp[0], pp[0]);
-			cp ++;
-			pp += 4;
-		} while (--x);
-	}
-}
-
-/*
- * 8-bit packed YCbCr samples w/ no subsampling => RGB
- */
-DECLAREContigPutFunc(putcontig8bitYCbCr11tile)
-{
-	(void) y;
-	fromskew *= 3;
-	do {
-		x = w; /* was x = w>>1; patched 2000/09/25 warmerda at home.com */
-		do {
-			int32 Cb = pp[1];
-			int32 Cr = pp[2];
-
-			YCbCrtoRGB(*cp++, pp[0]);
-
-			pp += 3;
-		} while (--x);
-		cp += toskew;
-		pp += fromskew;
-	} while (--h);
-}
-
-/*
- * 8-bit packed YCbCr samples w/ no subsampling => RGB
- */
-DECLARESepPutFunc(putseparate8bitYCbCr11tile)
-{
-	(void) y;
-	(void) a;
-	/* TODO: naming of input vars is still off, change obfuscating declaration inside define, or resolve obfuscation */
-	while (h-- > 0) {
-		x = w;
-		do {
-			uint32 dr, dg, db;
-			TIFFYCbCrtoRGB(img->ycbcr,*r++,*g++,*b++,&dr,&dg,&db);
-			*cp++ = PACK(dr,dg,db);
-		} while (--x);
-		SKEW(r, g, b, fromskew);
-		cp += toskew;
-	}
-}
-#undef YCbCrtoRGB
-
-static int
-initYCbCrConversion(TIFFRGBAImage* img)
-{
-	static const char module[] = "initYCbCrConversion";
-
-	float *luma, *refBlackWhite;
-
-	if (img->ycbcr == NULL) {
-		img->ycbcr = (TIFFYCbCrToRGB*) _TIFFmalloc(
-		    TIFFroundup_32(sizeof (TIFFYCbCrToRGB), sizeof (long))  
-		    + 4*256*sizeof (TIFFRGBValue)
-		    + 2*256*sizeof (int)
-		    + 3*256*sizeof (int32)
-		    );
-		if (img->ycbcr == NULL) {
-			TIFFErrorExt(img->tif->tif_clientdata, module,
-			    "No space for YCbCr->RGB conversion state");
-			return (0);
-		}
-	}
-
-	TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRCOEFFICIENTS, &luma);
-	TIFFGetFieldDefaulted(img->tif, TIFFTAG_REFERENCEBLACKWHITE,
-	    &refBlackWhite);
-	if (TIFFYCbCrToRGBInit(img->ycbcr, luma, refBlackWhite) < 0)
-		return(0);
-	return (1);
-}
-
-static tileContigRoutine
-initCIELabConversion(TIFFRGBAImage* img)
-{
-	static const char module[] = "initCIELabConversion";
-
-	float   *whitePoint;
-	float   refWhite[3];
-
-	if (!img->cielab) {
-		img->cielab = (TIFFCIELabToRGB *)
-			_TIFFmalloc(sizeof(TIFFCIELabToRGB));
-		if (!img->cielab) {
-			TIFFErrorExt(img->tif->tif_clientdata, module,
-			    "No space for CIE L*a*b*->RGB conversion state.");
-			return NULL;
-		}
-	}
-
-	TIFFGetFieldDefaulted(img->tif, TIFFTAG_WHITEPOINT, &whitePoint);
-	refWhite[1] = 100.0F;
-	refWhite[0] = whitePoint[0] / whitePoint[1] * refWhite[1];
-	refWhite[2] = (1.0F - whitePoint[0] - whitePoint[1])
-		      / whitePoint[1] * refWhite[1];
-	if (TIFFCIELabToRGBInit(img->cielab, &display_sRGB, refWhite) < 0) {
-		TIFFErrorExt(img->tif->tif_clientdata, module,
-		    "Failed to initialize CIE L*a*b*->RGB conversion state.");
-		_TIFFfree(img->cielab);
-		return NULL;
-	}
-
-	return putcontig8bitCIELab;
-}
-
-/*
- * Greyscale images with less than 8 bits/sample are handled
- * with a table to avoid lots of shifts and masks.  The table
- * is setup so that put*bwtile (below) can retrieve 8/bitspersample
- * pixel values simply by indexing into the table with one
- * number.
- */
-static int
-makebwmap(TIFFRGBAImage* img)
-{
-    TIFFRGBValue* Map = img->Map;
-    int bitspersample = img->bitspersample;
-    int nsamples = 8 / bitspersample;
-    int i;
-    uint32* p;
-
-    if( nsamples == 0 )
-        nsamples = 1;
-
-    img->BWmap = (uint32**) _TIFFmalloc(
-	256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32)));
-    if (img->BWmap == NULL) {
-		TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No space for B&W mapping table");
-		return (0);
-    }
-    p = (uint32*)(img->BWmap + 256);
-    for (i = 0; i < 256; i++) {
-	TIFFRGBValue c;
-	img->BWmap[i] = p;
-	switch (bitspersample) {
-#define	GREY(x)	c = Map[x]; *p++ = PACK(c,c,c);
-	case 1:
-	    GREY(i>>7);
-	    GREY((i>>6)&1);
-	    GREY((i>>5)&1);
-	    GREY((i>>4)&1);
-	    GREY((i>>3)&1);
-	    GREY((i>>2)&1);
-	    GREY((i>>1)&1);
-	    GREY(i&1);
-	    break;
-	case 2:
-	    GREY(i>>6);
-	    GREY((i>>4)&3);
-	    GREY((i>>2)&3);
-	    GREY(i&3);
-	    break;
-	case 4:
-	    GREY(i>>4);
-	    GREY(i&0xf);
-	    break;
-	case 8:
-        case 16:
-	    GREY(i);
-	    break;
-	}
-#undef	GREY
-    }
-    return (1);
-}
-
-/*
- * Construct a mapping table to convert from the range
- * of the data samples to [0,255] --for display.  This
- * process also handles inverting B&W images when needed.
- */ 
-static int
-setupMap(TIFFRGBAImage* img)
-{
-    int32 x, range;
-
-    range = (int32)((1L<<img->bitspersample)-1);
-    
-    /* treat 16 bit the same as eight bit */
-    if( img->bitspersample == 16 )
-        range = (int32) 255;
-
-    img->Map = (TIFFRGBValue*) _TIFFmalloc((range+1) * sizeof (TIFFRGBValue));
-    if (img->Map == NULL) {
-		TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif),
-			"No space for photometric conversion table");
-		return (0);
-    }
-    if (img->photometric == PHOTOMETRIC_MINISWHITE) {
-	for (x = 0; x <= range; x++)
-	    img->Map[x] = (TIFFRGBValue) (((range - x) * 255) / range);
-    } else {
-	for (x = 0; x <= range; x++)
-	    img->Map[x] = (TIFFRGBValue) ((x * 255) / range);
-    }
-    if (img->bitspersample <= 16 &&
-	(img->photometric == PHOTOMETRIC_MINISBLACK ||
-	 img->photometric == PHOTOMETRIC_MINISWHITE)) {
-	/*
-	 * Use photometric mapping table to construct
-	 * unpacking tables for samples <= 8 bits.
-	 */
-	if (!makebwmap(img))
-	    return (0);
-	/* no longer need Map, free it */
-	_TIFFfree(img->Map), img->Map = NULL;
-    }
-    return (1);
-}
-
-static int
-checkcmap(TIFFRGBAImage* img)
-{
-    uint16* r = img->redcmap;
-    uint16* g = img->greencmap;
-    uint16* b = img->bluecmap;
-    long n = 1L<<img->bitspersample;
-
-    while (n-- > 0)
-	if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256)
-	    return (16);
-    return (8);
-}
-
-static void
-cvtcmap(TIFFRGBAImage* img)
-{
-    uint16* r = img->redcmap;
-    uint16* g = img->greencmap;
-    uint16* b = img->bluecmap;
-    long i;
-
-    for (i = (1L<<img->bitspersample)-1; i >= 0; i--) {
-#define	CVT(x)		((uint16)((x)>>8))
-	r[i] = CVT(r[i]);
-	g[i] = CVT(g[i]);
-	b[i] = CVT(b[i]);
-#undef	CVT
-    }
-}
-
-/*
- * Palette images with <= 8 bits/sample are handled
- * with a table to avoid lots of shifts and masks.  The table
- * is setup so that put*cmaptile (below) can retrieve 8/bitspersample
- * pixel values simply by indexing into the table with one
- * number.
- */
-static int
-makecmap(TIFFRGBAImage* img)
-{
-    int bitspersample = img->bitspersample;
-    int nsamples = 8 / bitspersample;
-    uint16* r = img->redcmap;
-    uint16* g = img->greencmap;
-    uint16* b = img->bluecmap;
-    uint32 *p;
-    int i;
-
-    img->PALmap = (uint32**) _TIFFmalloc(
-	256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32)));
-    if (img->PALmap == NULL) {
-		TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No space for Palette mapping table");
-		return (0);
-	}
-    p = (uint32*)(img->PALmap + 256);
-    for (i = 0; i < 256; i++) {
-	TIFFRGBValue c;
-	img->PALmap[i] = p;
-#define	CMAP(x)	c = (TIFFRGBValue) x; *p++ = PACK(r[c]&0xff, g[c]&0xff, b[c]&0xff);
-	switch (bitspersample) {
-	case 1:
-	    CMAP(i>>7);
-	    CMAP((i>>6)&1);
-	    CMAP((i>>5)&1);
-	    CMAP((i>>4)&1);
-	    CMAP((i>>3)&1);
-	    CMAP((i>>2)&1);
-	    CMAP((i>>1)&1);
-	    CMAP(i&1);
-	    break;
-	case 2:
-	    CMAP(i>>6);
-	    CMAP((i>>4)&3);
-	    CMAP((i>>2)&3);
-	    CMAP(i&3);
-	    break;
-	case 4:
-	    CMAP(i>>4);
-	    CMAP(i&0xf);
-	    break;
-	case 8:
-	    CMAP(i);
-	    break;
-	}
-#undef CMAP
-    }
-    return (1);
-}
-
-/* 
- * Construct any mapping table used
- * by the associated put routine.
- */
-static int
-buildMap(TIFFRGBAImage* img)
-{
-    switch (img->photometric) {
-    case PHOTOMETRIC_RGB:
-    case PHOTOMETRIC_YCBCR:
-    case PHOTOMETRIC_SEPARATED:
-	if (img->bitspersample == 8)
-	    break;
-	/* fall thru... */
-    case PHOTOMETRIC_MINISBLACK:
-    case PHOTOMETRIC_MINISWHITE:
-	if (!setupMap(img))
-	    return (0);
-	break;
-    case PHOTOMETRIC_PALETTE:
-	/*
-	 * Convert 16-bit colormap to 8-bit (unless it looks
-	 * like an old-style 8-bit colormap).
-	 */
-	if (checkcmap(img) == 16)
-	    cvtcmap(img);
-	else
-	    TIFFWarningExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "Assuming 8-bit colormap");
-	/*
-	 * Use mapping table and colormap to construct
-	 * unpacking tables for samples < 8 bits.
-	 */
-	if (img->bitspersample <= 8 && !makecmap(img))
-	    return (0);
-	break;
-    }
-    return (1);
-}
-
-/*
- * Select the appropriate conversion routine for packed data.
- */
-static int
-PickContigCase(TIFFRGBAImage* img)
-{
-	img->get = TIFFIsTiled(img->tif) ? gtTileContig : gtStripContig;
-	img->put.contig = NULL;
-	switch (img->photometric) {
-		case PHOTOMETRIC_RGB:
-			switch (img->bitspersample) {
-				case 8:
-					if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
-						img->put.contig = putRGBAAcontig8bittile;
-					else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
-					{
-						if (BuildMapUaToAa(img))
-							img->put.contig = putRGBUAcontig8bittile;
-					}
-					else
-						img->put.contig = putRGBcontig8bittile;
-					break;
-				case 16:
-					if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
-					{
-						if (BuildMapBitdepth16To8(img))
-							img->put.contig = putRGBAAcontig16bittile;
-					}
-					else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
-					{
-						if (BuildMapBitdepth16To8(img) &&
-						    BuildMapUaToAa(img))
-							img->put.contig = putRGBUAcontig16bittile;
-					}
-					else
-					{
-						if (BuildMapBitdepth16To8(img))
-							img->put.contig = putRGBcontig16bittile;
-					}
-					break;
-			}
-			break;
-		case PHOTOMETRIC_SEPARATED:
-			if (buildMap(img)) {
-				if (img->bitspersample == 8) {
-					if (!img->Map)
-						img->put.contig = putRGBcontig8bitCMYKtile;
-					else
-						img->put.contig = putRGBcontig8bitCMYKMaptile;
-				}
-			}
-			break;
-		case PHOTOMETRIC_PALETTE:
-			if (buildMap(img)) {
-				switch (img->bitspersample) {
-					case 8:
-						img->put.contig = put8bitcmaptile;
-						break;
-					case 4:
-						img->put.contig = put4bitcmaptile;
-						break;
-					case 2:
-						img->put.contig = put2bitcmaptile;
-						break;
-					case 1:
-						img->put.contig = put1bitcmaptile;
-						break;
-				}
-			}
-			break;
-		case PHOTOMETRIC_MINISWHITE:
-		case PHOTOMETRIC_MINISBLACK:
-			if (buildMap(img)) {
-				switch (img->bitspersample) {
-					case 16:
-						img->put.contig = put16bitbwtile;
-						break;
-					case 8:
-						if (img->alpha && img->samplesperpixel == 2)
-							img->put.contig = putagreytile;
-						else
-							img->put.contig = putgreytile;
-						break;
-					case 4:
-						img->put.contig = put4bitbwtile;
-						break;
-					case 2:
-						img->put.contig = put2bitbwtile;
-						break;
-					case 1:
-						img->put.contig = put1bitbwtile;
-						break;
-				}
-			}
-			break;
-		case PHOTOMETRIC_YCBCR:
-			if ((img->bitspersample==8) && (img->samplesperpixel==3))
-			{
-				if (initYCbCrConversion(img)!=0)
-				{
-					/*
-					 * The 6.0 spec says that subsampling must be
-					 * one of 1, 2, or 4, and that vertical subsampling
-					 * must always be <= horizontal subsampling; so
-					 * there are only a few possibilities and we just
-					 * enumerate the cases.
-					 * Joris: added support for the [1,2] case, nonetheless, to accomodate
-					 * some OJPEG files
-					 */
-					uint16 SubsamplingHor;
-					uint16 SubsamplingVer;
-					TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &SubsamplingHor, &SubsamplingVer);
-					switch ((SubsamplingHor<<4)|SubsamplingVer) {
-						case 0x44:
-							img->put.contig = putcontig8bitYCbCr44tile;
-							break;
-						case 0x42:
-							img->put.contig = putcontig8bitYCbCr42tile;
-							break;
-						case 0x41:
-							img->put.contig = putcontig8bitYCbCr41tile;
-							break;
-						case 0x22:
-							img->put.contig = putcontig8bitYCbCr22tile;
-							break;
-						case 0x21:
-							img->put.contig = putcontig8bitYCbCr21tile;
-							break;
-						case 0x12:
-							img->put.contig = putcontig8bitYCbCr12tile;
-							break;
-						case 0x11:
-							img->put.contig = putcontig8bitYCbCr11tile;
-							break;
-					}
-				}
-			}
-			break;
-		case PHOTOMETRIC_CIELAB:
-			if (buildMap(img)) {
-				if (img->bitspersample == 8)
-					img->put.contig = initCIELabConversion(img);
-				break;
-			}
-	}
-	return ((img->get!=NULL) && (img->put.contig!=NULL));
-}
-
-/*
- * Select the appropriate conversion routine for unpacked data.
- *
- * NB: we assume that unpacked single channel data is directed
- *	 to the "packed routines.
- */
-static int
-PickSeparateCase(TIFFRGBAImage* img)
-{
-	img->get = TIFFIsTiled(img->tif) ? gtTileSeparate : gtStripSeparate;
-	img->put.separate = NULL;
-	switch (img->photometric) {
-	case PHOTOMETRIC_MINISWHITE:
-	case PHOTOMETRIC_MINISBLACK:
-		/* greyscale images processed pretty much as RGB by gtTileSeparate */
-	case PHOTOMETRIC_RGB:
-		switch (img->bitspersample) {
-		case 8:
-			if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
-				img->put.separate = putRGBAAseparate8bittile;
-			else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
-			{
-				if (BuildMapUaToAa(img))
-					img->put.separate = putRGBUAseparate8bittile;
-			}
-			else
-				img->put.separate = putRGBseparate8bittile;
-			break;
-		case 16:
-			if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
-			{
-				if (BuildMapBitdepth16To8(img))
-					img->put.separate = putRGBAAseparate16bittile;
-			}
-			else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
-			{
-				if (BuildMapBitdepth16To8(img) &&
-				    BuildMapUaToAa(img))
-					img->put.separate = putRGBUAseparate16bittile;
-			}
-			else
-			{
-				if (BuildMapBitdepth16To8(img))
-					img->put.separate = putRGBseparate16bittile;
-			}
-			break;
-		}
-		break;
-	case PHOTOMETRIC_SEPARATED:
-		if (img->bitspersample == 8 && img->samplesperpixel == 4)
-		{
-			img->alpha = 1; // Not alpha, but seems like the only way to get 4th band
-			img->put.separate = putCMYKseparate8bittile;
-		}
-		break;
-	case PHOTOMETRIC_YCBCR:
-		if ((img->bitspersample==8) && (img->samplesperpixel==3))
-		{
-			if (initYCbCrConversion(img)!=0)
-			{
-				uint16 hs, vs;
-				TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &hs, &vs);
-				switch ((hs<<4)|vs) {
-				case 0x11:
-					img->put.separate = putseparate8bitYCbCr11tile;
-					break;
-					/* TODO: add other cases here */
-				}
-			}
-		}
-		break;
-	}
-	return ((img->get!=NULL) && (img->put.separate!=NULL));
-}
-
-static int
-BuildMapUaToAa(TIFFRGBAImage* img)
-{
-	static const char module[]="BuildMapUaToAa";
-	uint8* m;
-	uint16 na,nv;
-	assert(img->UaToAa==NULL);
-	img->UaToAa=_TIFFmalloc(65536);
-	if (img->UaToAa==NULL)
-	{
-		TIFFErrorExt(img->tif->tif_clientdata,module,"Out of memory");
-		return(0);
-	}
-	m=img->UaToAa;
-	for (na=0; na<256; na++)
-	{
-		for (nv=0; nv<256; nv++)
-			*m++=(nv*na+127)/255;
-	}
-	return(1);
-}
-
-static int
-BuildMapBitdepth16To8(TIFFRGBAImage* img)
-{
-	static const char module[]="BuildMapBitdepth16To8";
-	uint8* m;
-	uint32 n;
-	assert(img->Bitdepth16To8==NULL);
-	img->Bitdepth16To8=_TIFFmalloc(65536);
-	if (img->Bitdepth16To8==NULL)
-	{
-		TIFFErrorExt(img->tif->tif_clientdata,module,"Out of memory");
-		return(0);
-	}
-	m=img->Bitdepth16To8;
-	for (n=0; n<65536; n++)
-		*m++=(n+128)/257;
-	return(1);
-}
-
-
-/*
- * Read a whole strip off data from the file, and convert to RGBA form.
- * If this is the last strip, then it will only contain the portion of
- * the strip that is actually within the image space.  The result is
- * organized in bottom to top form.
- */
-
-
-int
-TIFFReadRGBAStrip(TIFF* tif, uint32 row, uint32 * raster )
-
-{
-    char 	emsg[1024] = "";
-    TIFFRGBAImage img;
-    int 	ok;
-    uint32	rowsperstrip, rows_to_read;
-
-    if( TIFFIsTiled( tif ) )
-    {
-		TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
-                  "Can't use TIFFReadRGBAStrip() with tiled file.");
-	return (0);
-    }
-    
-    TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
-    if( (row % rowsperstrip) != 0 )
-    {
-		TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
-				"Row passed to TIFFReadRGBAStrip() must be first in a strip.");
-		return (0);
-    }
-
-    if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, 0, emsg)) {
-
-        img.row_offset = row;
-        img.col_offset = 0;
-
-        if( row + rowsperstrip > img.height )
-            rows_to_read = img.height - row;
-        else
-            rows_to_read = rowsperstrip;
-        
-	ok = TIFFRGBAImageGet(&img, raster, img.width, rows_to_read );
-        
-	TIFFRGBAImageEnd(&img);
-    } else {
-		TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg);
-		ok = 0;
-    }
-    
-    return (ok);
-}
-
-/*
- * Read a whole tile off data from the file, and convert to RGBA form.
- * The returned RGBA data is organized from bottom to top of tile,
- * and may include zeroed areas if the tile extends off the image.
- */
-
-int
-TIFFReadRGBATile(TIFF* tif, uint32 col, uint32 row, uint32 * raster)
-
-{
-    char 	emsg[1024] = "";
-    TIFFRGBAImage img;
-    int 	ok;
-    uint32	tile_xsize, tile_ysize;
-    uint32	read_xsize, read_ysize;
-    uint32	i_row;
-
-    /*
-     * Verify that our request is legal - on a tile file, and on a
-     * tile boundary.
-     */
-    
-    if( !TIFFIsTiled( tif ) )
-    {
-		TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
-				  "Can't use TIFFReadRGBATile() with stripped file.");
-		return (0);
-    }
-    
-    TIFFGetFieldDefaulted(tif, TIFFTAG_TILEWIDTH, &tile_xsize);
-    TIFFGetFieldDefaulted(tif, TIFFTAG_TILELENGTH, &tile_ysize);
-    if( (col % tile_xsize) != 0 || (row % tile_ysize) != 0 )
-    {
-		TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
-                  "Row/col passed to TIFFReadRGBATile() must be top"
-                  "left corner of a tile.");
-	return (0);
-    }
-
-    /*
-     * Setup the RGBA reader.
-     */
-    
-    if (!TIFFRGBAImageOK(tif, emsg) 
-	|| !TIFFRGBAImageBegin(&img, tif, 0, emsg)) {
-	    TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg);
-	    return( 0 );
-    }
-
-    /*
-     * The TIFFRGBAImageGet() function doesn't allow us to get off the
-     * edge of the image, even to fill an otherwise valid tile.  So we
-     * figure out how much we can read, and fix up the tile buffer to
-     * a full tile configuration afterwards.
-     */
-
-    if( row + tile_ysize > img.height )
-        read_ysize = img.height - row;
-    else
-        read_ysize = tile_ysize;
-    
-    if( col + tile_xsize > img.width )
-        read_xsize = img.width - col;
-    else
-        read_xsize = tile_xsize;
-
-    /*
-     * Read the chunk of imagery.
-     */
-    
-    img.row_offset = row;
-    img.col_offset = col;
-
-    ok = TIFFRGBAImageGet(&img, raster, read_xsize, read_ysize );
-        
-    TIFFRGBAImageEnd(&img);
-
-    /*
-     * If our read was incomplete we will need to fix up the tile by
-     * shifting the data around as if a full tile of data is being returned.
-     *
-     * This is all the more complicated because the image is organized in
-     * bottom to top format. 
-     */
-
-    if( read_xsize == tile_xsize && read_ysize == tile_ysize )
-        return( ok );
-
-    for( i_row = 0; i_row < read_ysize; i_row++ ) {
-        memmove( raster + (tile_ysize - i_row - 1) * tile_xsize,
-                 raster + (read_ysize - i_row - 1) * read_xsize,
-                 read_xsize * sizeof(uint32) );
-        _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize+read_xsize,
-                     0, sizeof(uint32) * (tile_xsize - read_xsize) );
-    }
-
-    for( i_row = read_ysize; i_row < tile_ysize; i_row++ ) {
-        _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize,
-                     0, sizeof(uint32) * tile_xsize );
-    }
-
-    return (ok);
-}
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Id: tif_getimage.c,v 1.11 2015/02/19 22:39:58 drolon Exp $ */
+
+/*
+ * Copyright (c) 1991-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and 
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
+ * 
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library
+ *
+ * Read and return a packed RGBA image.
+ */
+#include "tiffiop.h"
+#include <stdio.h>
+
+static int gtTileContig(TIFFRGBAImage*, uint32*, uint32, uint32);
+static int gtTileSeparate(TIFFRGBAImage*, uint32*, uint32, uint32);
+static int gtStripContig(TIFFRGBAImage*, uint32*, uint32, uint32);
+static int gtStripSeparate(TIFFRGBAImage*, uint32*, uint32, uint32);
+static int PickContigCase(TIFFRGBAImage*);
+static int PickSeparateCase(TIFFRGBAImage*);
+
+static int BuildMapUaToAa(TIFFRGBAImage* img);
+static int BuildMapBitdepth16To8(TIFFRGBAImage* img);
+
+static const char photoTag[] = "PhotometricInterpretation";
+
+/* 
+ * Helper constants used in Orientation tag handling
+ */
+#define FLIP_VERTICALLY 0x01
+#define FLIP_HORIZONTALLY 0x02
+
+/*
+ * Color conversion constants. We will define display types here.
+ */
+
+static const TIFFDisplay display_sRGB = {
+	{			/* XYZ -> luminance matrix */
+		{  3.2410F, -1.5374F, -0.4986F },
+		{  -0.9692F, 1.8760F, 0.0416F },
+		{  0.0556F, -0.2040F, 1.0570F }
+	},	
+	100.0F, 100.0F, 100.0F,	/* Light o/p for reference white */
+	255, 255, 255,		/* Pixel values for ref. white */
+	1.0F, 1.0F, 1.0F,	/* Residual light o/p for black pixel */
+	2.4F, 2.4F, 2.4F,	/* Gamma values for the three guns */
+};
+
+/*
+ * Check the image to see if TIFFReadRGBAImage can deal with it.
+ * 1/0 is returned according to whether or not the image can
+ * be handled.  If 0 is returned, emsg contains the reason
+ * why it is being rejected.
+ */
+int
+TIFFRGBAImageOK(TIFF* tif, char emsg[1024])
+{
+	TIFFDirectory* td = &tif->tif_dir;
+	uint16 photometric;
+	int colorchannels;
+
+	if (!tif->tif_decodestatus) {
+		sprintf(emsg, "Sorry, requested compression method is not configured");
+		return (0);
+	}
+	switch (td->td_bitspersample) {
+		case 1:
+		case 2:
+		case 4:
+		case 8:
+		case 16:
+			break;
+		default:
+			sprintf(emsg, "Sorry, can not handle images with %d-bit samples",
+			    td->td_bitspersample);
+			return (0);
+	}
+	colorchannels = td->td_samplesperpixel - td->td_extrasamples;
+	if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) {
+		switch (colorchannels) {
+			case 1:
+				photometric = PHOTOMETRIC_MINISBLACK;
+				break;
+			case 3:
+				photometric = PHOTOMETRIC_RGB;
+				break;
+			default:
+				sprintf(emsg, "Missing needed %s tag", photoTag);
+				return (0);
+		}
+	}
+	switch (photometric) {
+		case PHOTOMETRIC_MINISWHITE:
+		case PHOTOMETRIC_MINISBLACK:
+		case PHOTOMETRIC_PALETTE:
+			if (td->td_planarconfig == PLANARCONFIG_CONTIG
+			    && td->td_samplesperpixel != 1
+			    && td->td_bitspersample < 8 ) {
+				sprintf(emsg,
+				    "Sorry, can not handle contiguous data with %s=%d, "
+				    "and %s=%d and Bits/Sample=%d",
+				    photoTag, photometric,
+				    "Samples/pixel", td->td_samplesperpixel,
+				    td->td_bitspersample);
+				return (0);
+			}
+			/*
+			 * We should likely validate that any extra samples are either
+			 * to be ignored, or are alpha, and if alpha we should try to use
+			 * them.  But for now we won't bother with this.
+			*/
+			break;
+		case PHOTOMETRIC_YCBCR:
+			/*
+			 * TODO: if at all meaningful and useful, make more complete
+			 * support check here, or better still, refactor to let supporting
+			 * code decide whether there is support and what meaningfull
+			 * error to return
+			 */
+			break;
+		case PHOTOMETRIC_RGB:
+			if (colorchannels < 3) {
+				sprintf(emsg, "Sorry, can not handle RGB image with %s=%d",
+				    "Color channels", colorchannels);
+				return (0);
+			}
+			break;
+		case PHOTOMETRIC_SEPARATED:
+			{
+				uint16 inkset;
+				TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset);
+				if (inkset != INKSET_CMYK) {
+					sprintf(emsg,
+					    "Sorry, can not handle separated image with %s=%d",
+					    "InkSet", inkset);
+					return 0;
+				}
+				if (td->td_samplesperpixel < 4) {
+					sprintf(emsg,
+					    "Sorry, can not handle separated image with %s=%d",
+					    "Samples/pixel", td->td_samplesperpixel);
+					return 0;
+				}
+				break;
+			}
+		case PHOTOMETRIC_LOGL:
+			if (td->td_compression != COMPRESSION_SGILOG) {
+				sprintf(emsg, "Sorry, LogL data must have %s=%d",
+				    "Compression", COMPRESSION_SGILOG);
+				return (0);
+			}
+			break;
+		case PHOTOMETRIC_LOGLUV:
+			if (td->td_compression != COMPRESSION_SGILOG &&
+			    td->td_compression != COMPRESSION_SGILOG24) {
+				sprintf(emsg, "Sorry, LogLuv data must have %s=%d or %d",
+				    "Compression", COMPRESSION_SGILOG, COMPRESSION_SGILOG24);
+				return (0);
+			}
+			if (td->td_planarconfig != PLANARCONFIG_CONTIG) {
+				sprintf(emsg, "Sorry, can not handle LogLuv images with %s=%d",
+				    "Planarconfiguration", td->td_planarconfig);
+				return (0);
+			}
+			if( td->td_samplesperpixel != 3 )
+            {
+                sprintf(emsg,
+                        "Sorry, can not handle image with %s=%d",
+                        "Samples/pixel", td->td_samplesperpixel);
+                return 0;
+            }
+			break;
+		case PHOTOMETRIC_CIELAB:
+            if( td->td_samplesperpixel != 3 || td->td_bitspersample != 8 )
+            {
+                sprintf(emsg,
+                        "Sorry, can not handle image with %s=%d and %s=%d",
+                        "Samples/pixel", td->td_samplesperpixel,
+                        "Bits/sample", td->td_bitspersample);
+                return 0;
+            }
+			break;
+		default:
+			sprintf(emsg, "Sorry, can not handle image with %s=%d",
+			    photoTag, photometric);
+			return (0);
+	}
+	return (1);
+}
+
+void
+TIFFRGBAImageEnd(TIFFRGBAImage* img)
+{
+	if (img->Map)
+		_TIFFfree(img->Map), img->Map = NULL;
+	if (img->BWmap)
+		_TIFFfree(img->BWmap), img->BWmap = NULL;
+	if (img->PALmap)
+		_TIFFfree(img->PALmap), img->PALmap = NULL;
+	if (img->ycbcr)
+		_TIFFfree(img->ycbcr), img->ycbcr = NULL;
+	if (img->cielab)
+		_TIFFfree(img->cielab), img->cielab = NULL;
+	if (img->UaToAa)
+		_TIFFfree(img->UaToAa), img->UaToAa = NULL;
+	if (img->Bitdepth16To8)
+		_TIFFfree(img->Bitdepth16To8), img->Bitdepth16To8 = NULL;
+
+	if( img->redcmap ) {
+		_TIFFfree( img->redcmap );
+		_TIFFfree( img->greencmap );
+		_TIFFfree( img->bluecmap );
+                img->redcmap = img->greencmap = img->bluecmap = NULL;
+	}
+}
+
+static int
+isCCITTCompression(TIFF* tif)
+{
+    uint16 compress;
+    TIFFGetField(tif, TIFFTAG_COMPRESSION, &compress);
+    return (compress == COMPRESSION_CCITTFAX3 ||
+	    compress == COMPRESSION_CCITTFAX4 ||
+	    compress == COMPRESSION_CCITTRLE ||
+	    compress == COMPRESSION_CCITTRLEW);
+}
+
+int
+TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024])
+{
+	uint16* sampleinfo;
+	uint16 extrasamples;
+	uint16 planarconfig;
+	uint16 compress;
+	int colorchannels;
+	uint16 *red_orig, *green_orig, *blue_orig;
+	int n_color;
+
+	/* Initialize to normal values */
+	img->row_offset = 0;
+	img->col_offset = 0;
+	img->redcmap = NULL;
+	img->greencmap = NULL;
+	img->bluecmap = NULL;
+	img->req_orientation = ORIENTATION_BOTLEFT;     /* It is the default */
+
+	img->tif = tif;
+	img->stoponerr = stop;
+	TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &img->bitspersample);
+	switch (img->bitspersample) {
+		case 1:
+		case 2:
+		case 4:
+		case 8:
+		case 16:
+			break;
+		default:
+			sprintf(emsg, "Sorry, can not handle images with %d-bit samples",
+			    img->bitspersample);
+			goto fail_return;
+	}
+	img->alpha = 0;
+	TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &img->samplesperpixel);
+	TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES,
+	    &extrasamples, &sampleinfo);
+	if (extrasamples >= 1)
+	{
+		switch (sampleinfo[0]) {
+			case EXTRASAMPLE_UNSPECIFIED:          /* Workaround for some images without */
+				if (img->samplesperpixel > 3)  /* correct info about alpha channel */
+					img->alpha = EXTRASAMPLE_ASSOCALPHA;
+				break;
+			case EXTRASAMPLE_ASSOCALPHA:           /* data is pre-multiplied */
+			case EXTRASAMPLE_UNASSALPHA:           /* data is not pre-multiplied */
+				img->alpha = sampleinfo[0];
+				break;
+		}
+	}
+
+#ifdef DEFAULT_EXTRASAMPLE_AS_ALPHA
+	if( !TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric))
+		img->photometric = PHOTOMETRIC_MINISWHITE;
+
+	if( extrasamples == 0
+	    && img->samplesperpixel == 4
+	    && img->photometric == PHOTOMETRIC_RGB )
+	{
+		img->alpha = EXTRASAMPLE_ASSOCALPHA;
+		extrasamples = 1;
+	}
+#endif
+
+	colorchannels = img->samplesperpixel - extrasamples;
+	TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &compress);
+	TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planarconfig);
+	if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric)) {
+		switch (colorchannels) {
+			case 1:
+				if (isCCITTCompression(tif))
+					img->photometric = PHOTOMETRIC_MINISWHITE;
+				else
+					img->photometric = PHOTOMETRIC_MINISBLACK;
+				break;
+			case 3:
+				img->photometric = PHOTOMETRIC_RGB;
+				break;
+			default:
+				sprintf(emsg, "Missing needed %s tag", photoTag);
+                                goto fail_return;
+		}
+	}
+	switch (img->photometric) {
+		case PHOTOMETRIC_PALETTE:
+			if (!TIFFGetField(tif, TIFFTAG_COLORMAP,
+			    &red_orig, &green_orig, &blue_orig)) {
+				sprintf(emsg, "Missing required \"Colormap\" tag");
+                                goto fail_return;
+			}
+
+			/* copy the colormaps so we can modify them */
+			n_color = (1L << img->bitspersample);
+			img->redcmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);
+			img->greencmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);
+			img->bluecmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);
+			if( !img->redcmap || !img->greencmap || !img->bluecmap ) {
+				sprintf(emsg, "Out of memory for colormap copy");
+                                goto fail_return;
+			}
+
+			_TIFFmemcpy( img->redcmap, red_orig, n_color * 2 );
+			_TIFFmemcpy( img->greencmap, green_orig, n_color * 2 );
+			_TIFFmemcpy( img->bluecmap, blue_orig, n_color * 2 );
+
+			/* fall thru... */
+		case PHOTOMETRIC_MINISWHITE:
+		case PHOTOMETRIC_MINISBLACK:
+			if (planarconfig == PLANARCONFIG_CONTIG
+			    && img->samplesperpixel != 1
+			    && img->bitspersample < 8 ) {
+				sprintf(emsg,
+				    "Sorry, can not handle contiguous data with %s=%d, "
+				    "and %s=%d and Bits/Sample=%d",
+				    photoTag, img->photometric,
+				    "Samples/pixel", img->samplesperpixel,
+				    img->bitspersample);
+                                goto fail_return;
+			}
+			break;
+		case PHOTOMETRIC_YCBCR:
+			/* It would probably be nice to have a reality check here. */
+			if (planarconfig == PLANARCONFIG_CONTIG)
+				/* can rely on libjpeg to convert to RGB */
+				/* XXX should restore current state on exit */
+				switch (compress) {
+					case COMPRESSION_JPEG:
+						/*
+						 * TODO: when complete tests verify complete desubsampling
+						 * and YCbCr handling, remove use of TIFFTAG_JPEGCOLORMODE in
+						 * favor of tif_getimage.c native handling
+						 */
+						TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
+						img->photometric = PHOTOMETRIC_RGB;
+						break;
+					default:
+						/* do nothing */;
+						break;
+				}
+			/*
+			 * TODO: if at all meaningful and useful, make more complete
+			 * support check here, or better still, refactor to let supporting
+			 * code decide whether there is support and what meaningfull
+			 * error to return
+			 */
+			break;
+		case PHOTOMETRIC_RGB:
+			if (colorchannels < 3) {
+				sprintf(emsg, "Sorry, can not handle RGB image with %s=%d",
+				    "Color channels", colorchannels);
+                                goto fail_return;
+			}
+			break;
+		case PHOTOMETRIC_SEPARATED:
+			{
+				uint16 inkset;
+				TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset);
+				if (inkset != INKSET_CMYK) {
+					sprintf(emsg, "Sorry, can not handle separated image with %s=%d",
+					    "InkSet", inkset);
+                                        goto fail_return;
+				}
+				if (img->samplesperpixel < 4) {
+					sprintf(emsg, "Sorry, can not handle separated image with %s=%d",
+					    "Samples/pixel", img->samplesperpixel);
+                                        goto fail_return;
+				}
+			}
+			break;
+		case PHOTOMETRIC_LOGL:
+			if (compress != COMPRESSION_SGILOG) {
+				sprintf(emsg, "Sorry, LogL data must have %s=%d",
+				    "Compression", COMPRESSION_SGILOG);
+                                goto fail_return;
+			}
+			TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT);
+			img->photometric = PHOTOMETRIC_MINISBLACK;	/* little white lie */
+			img->bitspersample = 8;
+			break;
+		case PHOTOMETRIC_LOGLUV:
+			if (compress != COMPRESSION_SGILOG && compress != COMPRESSION_SGILOG24) {
+				sprintf(emsg, "Sorry, LogLuv data must have %s=%d or %d",
+				    "Compression", COMPRESSION_SGILOG, COMPRESSION_SGILOG24);
+                                goto fail_return;
+			}
+			if (planarconfig != PLANARCONFIG_CONTIG) {
+				sprintf(emsg, "Sorry, can not handle LogLuv images with %s=%d",
+				    "Planarconfiguration", planarconfig);
+				return (0);
+			}
+			TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT);
+			img->photometric = PHOTOMETRIC_RGB;		/* little white lie */
+			img->bitspersample = 8;
+			break;
+		case PHOTOMETRIC_CIELAB:
+			break;
+		default:
+			sprintf(emsg, "Sorry, can not handle image with %s=%d",
+			    photoTag, img->photometric);
+                        goto fail_return;
+	}
+	img->Map = NULL;
+	img->BWmap = NULL;
+	img->PALmap = NULL;
+	img->ycbcr = NULL;
+	img->cielab = NULL;
+	img->UaToAa = NULL;
+	img->Bitdepth16To8 = NULL;
+	TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &img->width);
+	TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &img->height);
+	TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &img->orientation);
+	img->isContig =
+	    !(planarconfig == PLANARCONFIG_SEPARATE && img->samplesperpixel > 1);
+	if (img->isContig) {
+		if (!PickContigCase(img)) {
+			sprintf(emsg, "Sorry, can not handle image");
+			goto fail_return;
+		}
+	} else {
+		if (!PickSeparateCase(img)) {
+			sprintf(emsg, "Sorry, can not handle image");
+			goto fail_return;
+		}
+	}
+	return 1;
+
+  fail_return:
+        _TIFFfree( img->redcmap );
+        _TIFFfree( img->greencmap );
+        _TIFFfree( img->bluecmap );
+        img->redcmap = img->greencmap = img->bluecmap = NULL;
+        return 0;
+}
+
+int
+TIFFRGBAImageGet(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
+{
+    if (img->get == NULL) {
+		TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No \"get\" routine setup");
+		return (0);
+	}
+	if (img->put.any == NULL) {
+		TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif),
+		"No \"put\" routine setupl; probably can not handle image format");
+		return (0);
+    }
+    return (*img->get)(img, raster, w, h);
+}
+
+/*
+ * Read the specified image into an ABGR-format rastertaking in account
+ * specified orientation.
+ */
+int
+TIFFReadRGBAImageOriented(TIFF* tif,
+			  uint32 rwidth, uint32 rheight, uint32* raster,
+			  int orientation, int stop)
+{
+    char emsg[1024] = "";
+    TIFFRGBAImage img;
+    int ok;
+
+	if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, stop, emsg)) {
+		img.req_orientation = orientation;
+		/* XXX verify rwidth and rheight against width and height */
+		ok = TIFFRGBAImageGet(&img, raster+(rheight-img.height)*rwidth,
+			rwidth, img.height);
+		TIFFRGBAImageEnd(&img);
+	} else {
+		TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg);
+		ok = 0;
+    }
+    return (ok);
+}
+
+/*
+ * Read the specified image into an ABGR-format raster. Use bottom left
+ * origin for raster by default.
+ */
+int
+TIFFReadRGBAImage(TIFF* tif,
+		  uint32 rwidth, uint32 rheight, uint32* raster, int stop)
+{
+	return TIFFReadRGBAImageOriented(tif, rwidth, rheight, raster,
+					 ORIENTATION_BOTLEFT, stop);
+}
+
+static int 
+setorientation(TIFFRGBAImage* img)
+{
+	switch (img->orientation) {
+		case ORIENTATION_TOPLEFT:
+		case ORIENTATION_LEFTTOP:
+			if (img->req_orientation == ORIENTATION_TOPRIGHT ||
+			    img->req_orientation == ORIENTATION_RIGHTTOP)
+				return FLIP_HORIZONTALLY;
+			else if (img->req_orientation == ORIENTATION_BOTRIGHT ||
+			    img->req_orientation == ORIENTATION_RIGHTBOT)
+				return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
+			else if (img->req_orientation == ORIENTATION_BOTLEFT ||
+			    img->req_orientation == ORIENTATION_LEFTBOT)
+				return FLIP_VERTICALLY;
+			else
+				return 0;
+		case ORIENTATION_TOPRIGHT:
+		case ORIENTATION_RIGHTTOP:
+			if (img->req_orientation == ORIENTATION_TOPLEFT ||
+			    img->req_orientation == ORIENTATION_LEFTTOP)
+				return FLIP_HORIZONTALLY;
+			else if (img->req_orientation == ORIENTATION_BOTRIGHT ||
+			    img->req_orientation == ORIENTATION_RIGHTBOT)
+				return FLIP_VERTICALLY;
+			else if (img->req_orientation == ORIENTATION_BOTLEFT ||
+			    img->req_orientation == ORIENTATION_LEFTBOT)
+				return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
+			else
+				return 0;
+		case ORIENTATION_BOTRIGHT:
+		case ORIENTATION_RIGHTBOT:
+			if (img->req_orientation == ORIENTATION_TOPLEFT ||
+			    img->req_orientation == ORIENTATION_LEFTTOP)
+				return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
+			else if (img->req_orientation == ORIENTATION_TOPRIGHT ||
+			    img->req_orientation == ORIENTATION_RIGHTTOP)
+				return FLIP_VERTICALLY;
+			else if (img->req_orientation == ORIENTATION_BOTLEFT ||
+			    img->req_orientation == ORIENTATION_LEFTBOT)
+				return FLIP_HORIZONTALLY;
+			else
+				return 0;
+		case ORIENTATION_BOTLEFT:
+		case ORIENTATION_LEFTBOT:
+			if (img->req_orientation == ORIENTATION_TOPLEFT ||
+			    img->req_orientation == ORIENTATION_LEFTTOP)
+				return FLIP_VERTICALLY;
+			else if (img->req_orientation == ORIENTATION_TOPRIGHT ||
+			    img->req_orientation == ORIENTATION_RIGHTTOP)
+				return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
+			else if (img->req_orientation == ORIENTATION_BOTRIGHT ||
+			    img->req_orientation == ORIENTATION_RIGHTBOT)
+				return FLIP_HORIZONTALLY;
+			else
+				return 0;
+		default:	/* NOTREACHED */
+			return 0;
+	}
+}
+
+/*
+ * Get an tile-organized image that has
+ *	PlanarConfiguration contiguous if SamplesPerPixel > 1
+ * or
+ *	SamplesPerPixel == 1
+ */	
+static int
+gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
+{
+    TIFF* tif = img->tif;
+    tileContigRoutine put = img->put.contig;
+    uint32 col, row, y, rowstoread;
+    tmsize_t pos;
+    uint32 tw, th;
+    unsigned char* buf;
+    int32 fromskew, toskew;
+    uint32 nrow;
+    int ret = 1, flip;
+
+    buf = (unsigned char*) _TIFFmalloc(TIFFTileSize(tif));
+    if (buf == 0) {
+		TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "No space for tile buffer");
+		return (0);
+    }
+    _TIFFmemset(buf, 0, TIFFTileSize(tif));
+    TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
+    TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
+
+    flip = setorientation(img);
+    if (flip & FLIP_VERTICALLY) {
+	    y = h - 1;
+	    toskew = -(int32)(tw + w);
+    }
+    else {
+	    y = 0;
+	    toskew = -(int32)(tw - w);
+    }
+     
+    for (row = 0; row < h; row += nrow)
+    {
+        rowstoread = th - (row + img->row_offset) % th;
+    	nrow = (row + rowstoread > h ? h - row : rowstoread);
+	for (col = 0; col < w; col += tw) 
+        {
+	    if (TIFFReadTile(tif, buf, col+img->col_offset,  
+			     row+img->row_offset, 0, 0)==(tmsize_t)(-1) && img->stoponerr)
+            {
+                ret = 0;
+                break;
+            }
+	    
+	    pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif);  
+
+    	    if (col + tw > w) 
+            {
+                /*
+                 * Tile is clipped horizontally.  Calculate
+                 * visible portion and skewing factors.
+                 */
+                uint32 npix = w - col;
+                fromskew = tw - npix;
+                (*put)(img, raster+y*w+col, col, y,
+                       npix, nrow, fromskew, toskew + fromskew, buf + pos);
+            }
+            else 
+            {
+                (*put)(img, raster+y*w+col, col, y, tw, nrow, 0, toskew, buf + pos);
+            }
+        }
+
+        y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow);
+    }
+    _TIFFfree(buf);
+
+    if (flip & FLIP_HORIZONTALLY) {
+	    uint32 line;
+
+	    for (line = 0; line < h; line++) {
+		    uint32 *left = raster + (line * w);
+		    uint32 *right = left + w - 1;
+		    
+		    while ( left < right ) {
+			    uint32 temp = *left;
+			    *left = *right;
+			    *right = temp;
+			    left++, right--;
+		    }
+	    }
+    }
+
+    return (ret);
+}
+
+/*
+ * Get an tile-organized image that has
+ *	 SamplesPerPixel > 1
+ *	 PlanarConfiguration separated
+ * We assume that all such images are RGB.
+ */	
+static int
+gtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
+{
+	TIFF* tif = img->tif;
+	tileSeparateRoutine put = img->put.separate;
+	uint32 col, row, y, rowstoread;
+	tmsize_t pos;
+	uint32 tw, th;
+	unsigned char* buf;
+	unsigned char* p0;
+	unsigned char* p1;
+	unsigned char* p2;
+	unsigned char* pa;
+	tmsize_t tilesize;
+	tmsize_t bufsize;
+	int32 fromskew, toskew;
+	int alpha = img->alpha;
+	uint32 nrow;
+	int ret = 1, flip;
+        int colorchannels;
+
+	tilesize = TIFFTileSize(tif);  
+	bufsize = TIFFSafeMultiply(tmsize_t,alpha?4:3,tilesize);
+	if (bufsize == 0) {
+		TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in %s", "gtTileSeparate");
+		return (0);
+	}
+	buf = (unsigned char*) _TIFFmalloc(bufsize);
+	if (buf == 0) {
+		TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "No space for tile buffer");
+		return (0);
+	}
+	_TIFFmemset(buf, 0, bufsize);
+	p0 = buf;
+	p1 = p0 + tilesize;
+	p2 = p1 + tilesize;
+	pa = (alpha?(p2+tilesize):NULL);
+	TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
+	TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
+
+	flip = setorientation(img);
+	if (flip & FLIP_VERTICALLY) {
+		y = h - 1;
+		toskew = -(int32)(tw + w);
+	}
+	else {
+		y = 0;
+		toskew = -(int32)(tw - w);
+	}
+
+        switch( img->photometric )
+        {
+          case PHOTOMETRIC_MINISWHITE:
+          case PHOTOMETRIC_MINISBLACK:
+          case PHOTOMETRIC_PALETTE:
+            colorchannels = 1;
+            p2 = p1 = p0;
+            break;
+
+          default:
+            colorchannels = 3;
+            break;
+        }
+
+	for (row = 0; row < h; row += nrow)
+	{
+		rowstoread = th - (row + img->row_offset) % th;
+		nrow = (row + rowstoread > h ? h - row : rowstoread);
+		for (col = 0; col < w; col += tw)
+		{
+			if (TIFFReadTile(tif, p0, col+img->col_offset,  
+			    row+img->row_offset,0,0)==(tmsize_t)(-1) && img->stoponerr)
+			{
+				ret = 0;
+				break;
+			}
+			if (colorchannels > 1 
+                            && TIFFReadTile(tif, p1, col+img->col_offset,  
+                                            row+img->row_offset,0,1) == (tmsize_t)(-1) 
+                            && img->stoponerr)
+			{
+				ret = 0;
+				break;
+			}
+			if (colorchannels > 1 
+                            && TIFFReadTile(tif, p2, col+img->col_offset,  
+                                            row+img->row_offset,0,2) == (tmsize_t)(-1) 
+                            && img->stoponerr)
+			{
+				ret = 0;
+				break;
+			}
+			if (alpha
+                            && TIFFReadTile(tif,pa,col+img->col_offset,  
+                                            row+img->row_offset,0,colorchannels) == (tmsize_t)(-1) 
+                            && img->stoponerr)
+                        {
+                            ret = 0;
+                            break;
+			}
+
+			pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif);  
+
+			if (col + tw > w)
+			{
+				/*
+				 * Tile is clipped horizontally.  Calculate
+				 * visible portion and skewing factors.
+				 */
+				uint32 npix = w - col;
+				fromskew = tw - npix;
+				(*put)(img, raster+y*w+col, col, y,
+				    npix, nrow, fromskew, toskew + fromskew,
+				    p0 + pos, p1 + pos, p2 + pos, (alpha?(pa+pos):NULL));
+			} else {
+				(*put)(img, raster+y*w+col, col, y,
+				    tw, nrow, 0, toskew, p0 + pos, p1 + pos, p2 + pos, (alpha?(pa+pos):NULL));
+			}
+		}
+
+		y += (flip & FLIP_VERTICALLY ?-(int32) nrow : (int32) nrow);
+	}
+
+	if (flip & FLIP_HORIZONTALLY) {
+		uint32 line;
+
+		for (line = 0; line < h; line++) {
+			uint32 *left = raster + (line * w);
+			uint32 *right = left + w - 1;
+
+			while ( left < right ) {
+				uint32 temp = *left;
+				*left = *right;
+				*right = temp;
+				left++, right--;
+			}
+		}
+	}
+
+	_TIFFfree(buf);
+	return (ret);
+}
+
+/*
+ * Get a strip-organized image that has
+ *	PlanarConfiguration contiguous if SamplesPerPixel > 1
+ * or
+ *	SamplesPerPixel == 1
+ */	
+static int
+gtStripContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
+{
+	TIFF* tif = img->tif;
+	tileContigRoutine put = img->put.contig;
+	uint32 row, y, nrow, nrowsub, rowstoread;
+	tmsize_t pos;
+	unsigned char* buf;
+	uint32 rowsperstrip;
+	uint16 subsamplinghor,subsamplingver;
+	uint32 imagewidth = img->width;
+	tmsize_t scanline;
+	int32 fromskew, toskew;
+	int ret = 1, flip;
+
+	TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING, &subsamplinghor, &subsamplingver);
+	if( subsamplingver == 0 ) {
+		TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Invalid vertical YCbCr subsampling");
+		return (0);
+	}
+
+	buf = (unsigned char*) _TIFFmalloc(TIFFStripSize(tif));
+	if (buf == 0) {
+		TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for strip buffer");
+		return (0);
+	}
+	_TIFFmemset(buf, 0, TIFFStripSize(tif));
+
+	flip = setorientation(img);
+	if (flip & FLIP_VERTICALLY) {
+		y = h - 1;
+		toskew = -(int32)(w + w);
+	} else {
+		y = 0;
+		toskew = -(int32)(w - w);
+	}
+
+	TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
+
+	scanline = TIFFScanlineSize(tif);
+	fromskew = (w < imagewidth ? imagewidth - w : 0);
+	for (row = 0; row < h; row += nrow)
+	{
+		rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip;
+		nrow = (row + rowstoread > h ? h - row : rowstoread);
+		nrowsub = nrow;
+		if ((nrowsub%subsamplingver)!=0)
+			nrowsub+=subsamplingver-nrowsub%subsamplingver;
+		if (TIFFReadEncodedStrip(tif,
+		    TIFFComputeStrip(tif,row+img->row_offset, 0),
+		    buf,
+		    ((row + img->row_offset)%rowsperstrip + nrowsub) * scanline)==(tmsize_t)(-1)
+		    && img->stoponerr)
+		{
+			ret = 0;
+			break;
+		}
+
+		pos = ((row + img->row_offset) % rowsperstrip) * scanline;
+		(*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, buf + pos);
+		y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow);
+	}
+
+	if (flip & FLIP_HORIZONTALLY) {
+		uint32 line;
+
+		for (line = 0; line < h; line++) {
+			uint32 *left = raster + (line * w);
+			uint32 *right = left + w - 1;
+
+			while ( left < right ) {
+				uint32 temp = *left;
+				*left = *right;
+				*right = temp;
+				left++, right--;
+			}
+		}
+	}
+
+	_TIFFfree(buf);
+	return (ret);
+}
+
+/*
+ * Get a strip-organized image with
+ *	 SamplesPerPixel > 1
+ *	 PlanarConfiguration separated
+ * We assume that all such images are RGB.
+ */
+static int
+gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
+{
+	TIFF* tif = img->tif;
+	tileSeparateRoutine put = img->put.separate;
+	unsigned char *buf;
+	unsigned char *p0, *p1, *p2, *pa;
+	uint32 row, y, nrow, rowstoread;
+	tmsize_t pos;
+	tmsize_t scanline;
+	uint32 rowsperstrip, offset_row;
+	uint32 imagewidth = img->width;
+	tmsize_t stripsize;
+	tmsize_t bufsize;
+	int32 fromskew, toskew;
+	int alpha = img->alpha;
+	int ret = 1, flip, colorchannels;
+
+	stripsize = TIFFStripSize(tif);  
+	bufsize = TIFFSafeMultiply(tmsize_t,alpha?4:3,stripsize);
+	if (bufsize == 0) {
+		TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in %s", "gtStripSeparate");
+		return (0);
+	}
+	p0 = buf = (unsigned char *)_TIFFmalloc(bufsize);
+	if (buf == 0) {
+		TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for tile buffer");
+		return (0);
+	}
+	_TIFFmemset(buf, 0, bufsize);
+	p1 = p0 + stripsize;
+	p2 = p1 + stripsize;
+	pa = (alpha?(p2+stripsize):NULL);
+
+	flip = setorientation(img);
+	if (flip & FLIP_VERTICALLY) {
+		y = h - 1;
+		toskew = -(int32)(w + w);
+	}
+	else {
+		y = 0;
+		toskew = -(int32)(w - w);
+	}
+
+        switch( img->photometric )
+        {
+          case PHOTOMETRIC_MINISWHITE:
+          case PHOTOMETRIC_MINISBLACK:
+          case PHOTOMETRIC_PALETTE:
+            colorchannels = 1;
+            p2 = p1 = p0;
+            break;
+
+          default:
+            colorchannels = 3;
+            break;
+        }
+
+	TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
+	scanline = TIFFScanlineSize(tif);  
+	fromskew = (w < imagewidth ? imagewidth - w : 0);
+	for (row = 0; row < h; row += nrow)
+	{
+		rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip;
+		nrow = (row + rowstoread > h ? h - row : rowstoread);
+		offset_row = row + img->row_offset;
+		if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 0),
+		    p0, ((row + img->row_offset)%rowsperstrip + nrow) * scanline)==(tmsize_t)(-1)
+		    && img->stoponerr)
+		{
+			ret = 0;
+			break;
+		}
+		if (colorchannels > 1 
+                    && TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 1),
+                                            p1, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) == (tmsize_t)(-1)
+		    && img->stoponerr)
+		{
+			ret = 0;
+			break;
+		}
+		if (colorchannels > 1 
+                    && TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 2),
+                                            p2, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) == (tmsize_t)(-1)
+		    && img->stoponerr)
+		{
+			ret = 0;
+			break;
+		}
+		if (alpha)
+		{
+			if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, colorchannels),
+			    pa, ((row + img->row_offset)%rowsperstrip + nrow) * scanline)==(tmsize_t)(-1)
+			    && img->stoponerr)
+			{
+				ret = 0;
+				break;
+			}
+		}
+
+		pos = ((row + img->row_offset) % rowsperstrip) * scanline;
+		(*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, p0 + pos, p1 + pos,
+		    p2 + pos, (alpha?(pa+pos):NULL));
+		y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow);
+	}
+
+	if (flip & FLIP_HORIZONTALLY) {
+		uint32 line;
+
+		for (line = 0; line < h; line++) {
+			uint32 *left = raster + (line * w);
+			uint32 *right = left + w - 1;
+
+			while ( left < right ) {
+				uint32 temp = *left;
+				*left = *right;
+				*right = temp;
+				left++, right--;
+			}
+		}
+	}
+
+	_TIFFfree(buf);
+	return (ret);
+}
+
+/*
+ * The following routines move decoded data returned
+ * from the TIFF library into rasters filled with packed
+ * ABGR pixels (i.e. suitable for passing to lrecwrite.)
+ *
+ * The routines have been created according to the most
+ * important cases and optimized.  PickContigCase and
+ * PickSeparateCase analyze the parameters and select
+ * the appropriate "get" and "put" routine to use.
+ */
+#define	REPEAT8(op)	REPEAT4(op); REPEAT4(op)
+#define	REPEAT4(op)	REPEAT2(op); REPEAT2(op)
+#define	REPEAT2(op)	op; op
+#define	CASE8(x,op)			\
+    switch (x) {			\
+    case 7: op; case 6: op; case 5: op;	\
+    case 4: op; case 3: op; case 2: op;	\
+    case 1: op;				\
+    }
+#define	CASE4(x,op)	switch (x) { case 3: op; case 2: op; case 1: op; }
+#define	NOP
+
+#define	UNROLL8(w, op1, op2) {		\
+    uint32 _x;				\
+    for (_x = w; _x >= 8; _x -= 8) {	\
+	op1;				\
+	REPEAT8(op2);			\
+    }					\
+    if (_x > 0) {			\
+	op1;				\
+	CASE8(_x,op2);			\
+    }					\
+}
+#define	UNROLL4(w, op1, op2) {		\
+    uint32 _x;				\
+    for (_x = w; _x >= 4; _x -= 4) {	\
+	op1;				\
+	REPEAT4(op2);			\
+    }					\
+    if (_x > 0) {			\
+	op1;				\
+	CASE4(_x,op2);			\
+    }					\
+}
+#define	UNROLL2(w, op1, op2) {		\
+    uint32 _x;				\
+    for (_x = w; _x >= 2; _x -= 2) {	\
+	op1;				\
+	REPEAT2(op2);			\
+    }					\
+    if (_x) {				\
+	op1;				\
+	op2;				\
+    }					\
+}
+    
+#define	SKEW(r,g,b,skew)	{ r += skew; g += skew; b += skew; }
+#define	SKEW4(r,g,b,a,skew)	{ r += skew; g += skew; b += skew; a+= skew; }
+
+#define A1 (((uint32)0xffL)<<24)
+#define	PACK(r,g,b)	\
+	((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|A1)
+#define	PACK4(r,g,b,a)	\
+	((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|((uint32)(a)<<24))
+#define W2B(v) (((v)>>8)&0xff)
+/* TODO: PACKW should have be made redundant in favor of Bitdepth16To8 LUT */
+#define	PACKW(r,g,b)	\
+	((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|A1)
+#define	PACKW4(r,g,b,a)	\
+	((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|((uint32)W2B(a)<<24))
+
+#define	DECLAREContigPutFunc(name) \
+static void name(\
+    TIFFRGBAImage* img, \
+    uint32* cp, \
+    uint32 x, uint32 y, \
+    uint32 w, uint32 h, \
+    int32 fromskew, int32 toskew, \
+    unsigned char* pp \
+)
+
+/*
+ * 8-bit palette => colormap/RGB
+ */
+DECLAREContigPutFunc(put8bitcmaptile)
+{
+    uint32** PALmap = img->PALmap;
+    int samplesperpixel = img->samplesperpixel;
+
+    (void) y;
+    while (h-- > 0) {
+	for (x = w; x-- > 0;)
+        {
+	    *cp++ = PALmap[*pp][0];
+            pp += samplesperpixel;
+        }
+	cp += toskew;
+	pp += fromskew;
+    }
+}
+
+/*
+ * 4-bit palette => colormap/RGB
+ */
+DECLAREContigPutFunc(put4bitcmaptile)
+{
+    uint32** PALmap = img->PALmap;
+
+    (void) x; (void) y;
+    fromskew /= 2;
+    while (h-- > 0) {
+	uint32* bw;
+	UNROLL2(w, bw = PALmap[*pp++], *cp++ = *bw++);
+	cp += toskew;
+	pp += fromskew;
+    }
+}
+
+/*
+ * 2-bit palette => colormap/RGB
+ */
+DECLAREContigPutFunc(put2bitcmaptile)
+{
+    uint32** PALmap = img->PALmap;
+
+    (void) x; (void) y;
+    fromskew /= 4;
+    while (h-- > 0) {
+	uint32* bw;
+	UNROLL4(w, bw = PALmap[*pp++], *cp++ = *bw++);
+	cp += toskew;
+	pp += fromskew;
+    }
+}
+
+/*
+ * 1-bit palette => colormap/RGB
+ */
+DECLAREContigPutFunc(put1bitcmaptile)
+{
+    uint32** PALmap = img->PALmap;
+
+    (void) x; (void) y;
+    fromskew /= 8;
+    while (h-- > 0) {
+	uint32* bw;
+	UNROLL8(w, bw = PALmap[*pp++], *cp++ = *bw++);
+	cp += toskew;
+	pp += fromskew;
+    }
+}
+
+/*
+ * 8-bit greyscale => colormap/RGB
+ */
+DECLAREContigPutFunc(putgreytile)
+{
+    int samplesperpixel = img->samplesperpixel;
+    uint32** BWmap = img->BWmap;
+
+    (void) y;
+    while (h-- > 0) {
+	for (x = w; x-- > 0;)
+        {
+	    *cp++ = BWmap[*pp][0];
+            pp += samplesperpixel;
+        }
+	cp += toskew;
+	pp += fromskew;
+    }
+}
+
+/*
+ * 8-bit greyscale with associated alpha => colormap/RGBA
+ */
+DECLAREContigPutFunc(putagreytile)
+{
+    int samplesperpixel = img->samplesperpixel;
+    uint32** BWmap = img->BWmap;
+
+    (void) y;
+    while (h-- > 0) {
+	for (x = w; x-- > 0;)
+        {
+            *cp++ = BWmap[*pp][0] & (*(pp+1) << 24 | ~A1);
+            pp += samplesperpixel;
+        }
+	cp += toskew;
+	pp += fromskew;
+    }
+}
+
+/*
+ * 16-bit greyscale => colormap/RGB
+ */
+DECLAREContigPutFunc(put16bitbwtile)
+{
+    int samplesperpixel = img->samplesperpixel;
+    uint32** BWmap = img->BWmap;
+
+    (void) y;
+    while (h-- > 0) {
+        uint16 *wp = (uint16 *) pp;
+
+	for (x = w; x-- > 0;)
+        {
+            /* use high order byte of 16bit value */
+
+	    *cp++ = BWmap[*wp >> 8][0];
+            pp += 2 * samplesperpixel;
+            wp += samplesperpixel;
+        }
+	cp += toskew;
+	pp += fromskew;
+    }
+}
+
+/*
+ * 1-bit bilevel => colormap/RGB
+ */
+DECLAREContigPutFunc(put1bitbwtile)
+{
+    uint32** BWmap = img->BWmap;
+
+    (void) x; (void) y;
+    fromskew /= 8;
+    while (h-- > 0) {
+	uint32* bw;
+	UNROLL8(w, bw = BWmap[*pp++], *cp++ = *bw++);
+	cp += toskew;
+	pp += fromskew;
+    }
+}
+
+/*
+ * 2-bit greyscale => colormap/RGB
+ */
+DECLAREContigPutFunc(put2bitbwtile)
+{
+    uint32** BWmap = img->BWmap;
+
+    (void) x; (void) y;
+    fromskew /= 4;
+    while (h-- > 0) {
+	uint32* bw;
+	UNROLL4(w, bw = BWmap[*pp++], *cp++ = *bw++);
+	cp += toskew;
+	pp += fromskew;
+    }
+}
+
+/*
+ * 4-bit greyscale => colormap/RGB
+ */
+DECLAREContigPutFunc(put4bitbwtile)
+{
+    uint32** BWmap = img->BWmap;
+
+    (void) x; (void) y;
+    fromskew /= 2;
+    while (h-- > 0) {
+	uint32* bw;
+	UNROLL2(w, bw = BWmap[*pp++], *cp++ = *bw++);
+	cp += toskew;
+	pp += fromskew;
+    }
+}
+
+/*
+ * 8-bit packed samples, no Map => RGB
+ */
+DECLAREContigPutFunc(putRGBcontig8bittile)
+{
+    int samplesperpixel = img->samplesperpixel;
+
+    (void) x; (void) y;
+    fromskew *= samplesperpixel;
+    while (h-- > 0) {
+	UNROLL8(w, NOP,
+	    *cp++ = PACK(pp[0], pp[1], pp[2]);
+	    pp += samplesperpixel);
+	cp += toskew;
+	pp += fromskew;
+    }
+}
+
+/*
+ * 8-bit packed samples => RGBA w/ associated alpha
+ * (known to have Map == NULL)
+ */
+DECLAREContigPutFunc(putRGBAAcontig8bittile)
+{
+    int samplesperpixel = img->samplesperpixel;
+
+    (void) x; (void) y;
+    fromskew *= samplesperpixel;
+    while (h-- > 0) {
+	UNROLL8(w, NOP,
+	    *cp++ = PACK4(pp[0], pp[1], pp[2], pp[3]);
+	    pp += samplesperpixel);
+	cp += toskew;
+	pp += fromskew;
+    }
+}
+
+/*
+ * 8-bit packed samples => RGBA w/ unassociated alpha
+ * (known to have Map == NULL)
+ */
+DECLAREContigPutFunc(putRGBUAcontig8bittile)
+{
+	int samplesperpixel = img->samplesperpixel;
+	(void) y;
+	fromskew *= samplesperpixel;
+	while (h-- > 0) {
+		uint32 r, g, b, a;
+		uint8* m;
+		for (x = w; x-- > 0;) {
+			a = pp[3];
+			m = img->UaToAa+(a<<8);
+			r = m[pp[0]];
+			g = m[pp[1]];
+			b = m[pp[2]];
+			*cp++ = PACK4(r,g,b,a);
+			pp += samplesperpixel;
+		}
+		cp += toskew;
+		pp += fromskew;
+	}
+}
+
+/*
+ * 16-bit packed samples => RGB
+ */
+DECLAREContigPutFunc(putRGBcontig16bittile)
+{
+	int samplesperpixel = img->samplesperpixel;
+	uint16 *wp = (uint16 *)pp;
+	(void) y;
+	fromskew *= samplesperpixel;
+	while (h-- > 0) {
+		for (x = w; x-- > 0;) {
+			*cp++ = PACK(img->Bitdepth16To8[wp[0]],
+			    img->Bitdepth16To8[wp[1]],
+			    img->Bitdepth16To8[wp[2]]);
+			wp += samplesperpixel;
+		}
+		cp += toskew;
+		wp += fromskew;
+	}
+}
+
+/*
+ * 16-bit packed samples => RGBA w/ associated alpha
+ * (known to have Map == NULL)
+ */
+DECLAREContigPutFunc(putRGBAAcontig16bittile)
+{
+	int samplesperpixel = img->samplesperpixel;
+	uint16 *wp = (uint16 *)pp;
+	(void) y;
+	fromskew *= samplesperpixel;
+	while (h-- > 0) {
+		for (x = w; x-- > 0;) {
+			*cp++ = PACK4(img->Bitdepth16To8[wp[0]],
+			    img->Bitdepth16To8[wp[1]],
+			    img->Bitdepth16To8[wp[2]],
+			    img->Bitdepth16To8[wp[3]]);
+			wp += samplesperpixel;
+		}
+		cp += toskew;
+		wp += fromskew;
+	}
+}
+
+/*
+ * 16-bit packed samples => RGBA w/ unassociated alpha
+ * (known to have Map == NULL)
+ */
+DECLAREContigPutFunc(putRGBUAcontig16bittile)
+{
+	int samplesperpixel = img->samplesperpixel;
+	uint16 *wp = (uint16 *)pp;
+	(void) y;
+	fromskew *= samplesperpixel;
+	while (h-- > 0) {
+		uint32 r,g,b,a;
+		uint8* m;
+		for (x = w; x-- > 0;) {
+			a = img->Bitdepth16To8[wp[3]];
+			m = img->UaToAa+(a<<8);
+			r = m[img->Bitdepth16To8[wp[0]]];
+			g = m[img->Bitdepth16To8[wp[1]]];
+			b = m[img->Bitdepth16To8[wp[2]]];
+			*cp++ = PACK4(r,g,b,a);
+			wp += samplesperpixel;
+		}
+		cp += toskew;
+		wp += fromskew;
+	}
+}
+
+/*
+ * 8-bit packed CMYK samples w/o Map => RGB
+ *
+ * NB: The conversion of CMYK->RGB is *very* crude.
+ */
+DECLAREContigPutFunc(putRGBcontig8bitCMYKtile)
+{
+    int samplesperpixel = img->samplesperpixel;
+    uint16 r, g, b, k;
+
+    (void) x; (void) y;
+    fromskew *= samplesperpixel;
+    while (h-- > 0) {
+	UNROLL8(w, NOP,
+	    k = 255 - pp[3];
+	    r = (k*(255-pp[0]))/255;
+	    g = (k*(255-pp[1]))/255;
+	    b = (k*(255-pp[2]))/255;
+	    *cp++ = PACK(r, g, b);
+	    pp += samplesperpixel);
+	cp += toskew;
+	pp += fromskew;
+    }
+}
+
+/*
+ * 8-bit packed CMYK samples w/Map => RGB
+ *
+ * NB: The conversion of CMYK->RGB is *very* crude.
+ */
+DECLAREContigPutFunc(putRGBcontig8bitCMYKMaptile)
+{
+    int samplesperpixel = img->samplesperpixel;
+    TIFFRGBValue* Map = img->Map;
+    uint16 r, g, b, k;
+
+    (void) y;
+    fromskew *= samplesperpixel;
+    while (h-- > 0) {
+	for (x = w; x-- > 0;) {
+	    k = 255 - pp[3];
+	    r = (k*(255-pp[0]))/255;
+	    g = (k*(255-pp[1]))/255;
+	    b = (k*(255-pp[2]))/255;
+	    *cp++ = PACK(Map[r], Map[g], Map[b]);
+	    pp += samplesperpixel;
+	}
+	pp += fromskew;
+	cp += toskew;
+    }
+}
+
+#define	DECLARESepPutFunc(name) \
+static void name(\
+    TIFFRGBAImage* img,\
+    uint32* cp,\
+    uint32 x, uint32 y, \
+    uint32 w, uint32 h,\
+    int32 fromskew, int32 toskew,\
+    unsigned char* r, unsigned char* g, unsigned char* b, unsigned char* a\
+)
+
+/*
+ * 8-bit unpacked samples => RGB
+ */
+DECLARESepPutFunc(putRGBseparate8bittile)
+{
+    (void) img; (void) x; (void) y; (void) a;
+    while (h-- > 0) {
+	UNROLL8(w, NOP, *cp++ = PACK(*r++, *g++, *b++));
+	SKEW(r, g, b, fromskew);
+	cp += toskew;
+    }
+}
+
+/*
+ * 8-bit unpacked samples => RGBA w/ associated alpha
+ */
+DECLARESepPutFunc(putRGBAAseparate8bittile)
+{
+	(void) img; (void) x; (void) y; 
+	while (h-- > 0) {
+		UNROLL8(w, NOP, *cp++ = PACK4(*r++, *g++, *b++, *a++));
+		SKEW4(r, g, b, a, fromskew);
+		cp += toskew;
+	}
+}
+
+/*
+ * 8-bit unpacked CMYK samples => RGBA
+ */
+DECLARESepPutFunc(putCMYKseparate8bittile)
+{
+	(void) img; (void) y;
+	while (h-- > 0) {
+		uint32 rv, gv, bv, kv;
+		for (x = w; x-- > 0;) {
+			kv = 255 - *a++;
+			rv = (kv*(255-*r++))/255;
+			gv = (kv*(255-*g++))/255;
+			bv = (kv*(255-*b++))/255;
+			*cp++ = PACK4(rv,gv,bv,255);
+		}
+		SKEW4(r, g, b, a, fromskew);
+		cp += toskew;
+	}
+}
+
+/*
+ * 8-bit unpacked samples => RGBA w/ unassociated alpha
+ */
+DECLARESepPutFunc(putRGBUAseparate8bittile)
+{
+	(void) img; (void) y;
+	while (h-- > 0) {
+		uint32 rv, gv, bv, av;
+		uint8* m;
+		for (x = w; x-- > 0;) {
+			av = *a++;
+			m = img->UaToAa+(av<<8);
+			rv = m[*r++];
+			gv = m[*g++];
+			bv = m[*b++];
+			*cp++ = PACK4(rv,gv,bv,av);
+		}
+		SKEW4(r, g, b, a, fromskew);
+		cp += toskew;
+	}
+}
+
+/*
+ * 16-bit unpacked samples => RGB
+ */
+DECLARESepPutFunc(putRGBseparate16bittile)
+{
+	uint16 *wr = (uint16*) r;
+	uint16 *wg = (uint16*) g;
+	uint16 *wb = (uint16*) b;
+	(void) img; (void) y; (void) a;
+	while (h-- > 0) {
+		for (x = 0; x < w; x++)
+			*cp++ = PACK(img->Bitdepth16To8[*wr++],
+			    img->Bitdepth16To8[*wg++],
+			    img->Bitdepth16To8[*wb++]);
+		SKEW(wr, wg, wb, fromskew);
+		cp += toskew;
+	}
+}
+
+/*
+ * 16-bit unpacked samples => RGBA w/ associated alpha
+ */
+DECLARESepPutFunc(putRGBAAseparate16bittile)
+{
+	uint16 *wr = (uint16*) r;
+	uint16 *wg = (uint16*) g;
+	uint16 *wb = (uint16*) b;
+	uint16 *wa = (uint16*) a;
+	(void) img; (void) y;
+	while (h-- > 0) {
+		for (x = 0; x < w; x++)
+			*cp++ = PACK4(img->Bitdepth16To8[*wr++],
+			    img->Bitdepth16To8[*wg++],
+			    img->Bitdepth16To8[*wb++],
+			    img->Bitdepth16To8[*wa++]);
+		SKEW4(wr, wg, wb, wa, fromskew);
+		cp += toskew;
+	}
+}
+
+/*
+ * 16-bit unpacked samples => RGBA w/ unassociated alpha
+ */
+DECLARESepPutFunc(putRGBUAseparate16bittile)
+{
+	uint16 *wr = (uint16*) r;
+	uint16 *wg = (uint16*) g;
+	uint16 *wb = (uint16*) b;
+	uint16 *wa = (uint16*) a;
+	(void) img; (void) y;
+	while (h-- > 0) {
+		uint32 r,g,b,a;
+		uint8* m;
+		for (x = w; x-- > 0;) {
+			a = img->Bitdepth16To8[*wa++];
+			m = img->UaToAa+(a<<8);
+			r = m[img->Bitdepth16To8[*wr++]];
+			g = m[img->Bitdepth16To8[*wg++]];
+			b = m[img->Bitdepth16To8[*wb++]];
+			*cp++ = PACK4(r,g,b,a);
+		}
+		SKEW4(wr, wg, wb, wa, fromskew);
+		cp += toskew;
+	}
+}
+
+/*
+ * 8-bit packed CIE L*a*b 1976 samples => RGB
+ */
+DECLAREContigPutFunc(putcontig8bitCIELab)
+{
+	float X, Y, Z;
+	uint32 r, g, b;
+	(void) y;
+	fromskew *= 3;
+	while (h-- > 0) {
+		for (x = w; x-- > 0;) {
+			TIFFCIELabToXYZ(img->cielab,
+					(unsigned char)pp[0],
+					(signed char)pp[1],
+					(signed char)pp[2],
+					&X, &Y, &Z);
+			TIFFXYZToRGB(img->cielab, X, Y, Z, &r, &g, &b);
+			*cp++ = PACK(r, g, b);
+			pp += 3;
+		}
+		cp += toskew;
+		pp += fromskew;
+	}
+}
+
+/*
+ * YCbCr -> RGB conversion and packing routines.
+ */
+
+#define	YCbCrtoRGB(dst, Y) {						\
+	uint32 r, g, b;							\
+	TIFFYCbCrtoRGB(img->ycbcr, (Y), Cb, Cr, &r, &g, &b);		\
+	dst = PACK(r, g, b);						\
+}
+
+/*
+ * 8-bit packed YCbCr samples => RGB 
+ * This function is generic for different sampling sizes, 
+ * and can handle blocks sizes that aren't multiples of the
+ * sampling size.  However, it is substantially less optimized
+ * than the specific sampling cases.  It is used as a fallback
+ * for difficult blocks.
+ */
+#ifdef notdef
+static void putcontig8bitYCbCrGenericTile( 
+    TIFFRGBAImage* img, 
+    uint32* cp, 
+    uint32 x, uint32 y, 
+    uint32 w, uint32 h, 
+    int32 fromskew, int32 toskew, 
+    unsigned char* pp,
+    int h_group, 
+    int v_group )
+
+{
+    uint32* cp1 = cp+w+toskew;
+    uint32* cp2 = cp1+w+toskew;
+    uint32* cp3 = cp2+w+toskew;
+    int32 incr = 3*w+4*toskew;
+    int32   Cb, Cr;
+    int     group_size = v_group * h_group + 2;
+
+    (void) y;
+    fromskew = (fromskew * group_size) / h_group;
+
+    for( yy = 0; yy < h; yy++ )
+    {
+        unsigned char *pp_line;
+        int     y_line_group = yy / v_group;
+        int     y_remainder = yy - y_line_group * v_group;
+
+        pp_line = pp + v_line_group * 
+
+        
+        for( xx = 0; xx < w; xx++ )
+        {
+            Cb = pp
+        }
+    }
+    for (; h >= 4; h -= 4) {
+	x = w>>2;
+	do {
+	    Cb = pp[16];
+	    Cr = pp[17];
+
+	    YCbCrtoRGB(cp [0], pp[ 0]);
+	    YCbCrtoRGB(cp [1], pp[ 1]);
+	    YCbCrtoRGB(cp [2], pp[ 2]);
+	    YCbCrtoRGB(cp [3], pp[ 3]);
+	    YCbCrtoRGB(cp1[0], pp[ 4]);
+	    YCbCrtoRGB(cp1[1], pp[ 5]);
+	    YCbCrtoRGB(cp1[2], pp[ 6]);
+	    YCbCrtoRGB(cp1[3], pp[ 7]);
+	    YCbCrtoRGB(cp2[0], pp[ 8]);
+	    YCbCrtoRGB(cp2[1], pp[ 9]);
+	    YCbCrtoRGB(cp2[2], pp[10]);
+	    YCbCrtoRGB(cp2[3], pp[11]);
+	    YCbCrtoRGB(cp3[0], pp[12]);
+	    YCbCrtoRGB(cp3[1], pp[13]);
+	    YCbCrtoRGB(cp3[2], pp[14]);
+	    YCbCrtoRGB(cp3[3], pp[15]);
+
+	    cp += 4, cp1 += 4, cp2 += 4, cp3 += 4;
+	    pp += 18;
+	} while (--x);
+	cp += incr, cp1 += incr, cp2 += incr, cp3 += incr;
+	pp += fromskew;
+    }
+}
+#endif
+
+/*
+ * 8-bit packed YCbCr samples w/ 4,4 subsampling => RGB
+ */
+DECLAREContigPutFunc(putcontig8bitYCbCr44tile)
+{
+    uint32* cp1 = cp+w+toskew;
+    uint32* cp2 = cp1+w+toskew;
+    uint32* cp3 = cp2+w+toskew;
+    int32 incr = 3*w+4*toskew;
+
+    (void) y;
+    /* adjust fromskew */
+    fromskew = (fromskew * 18) / 4;
+    if ((h & 3) == 0 && (w & 3) == 0) {				        
+        for (; h >= 4; h -= 4) {
+            x = w>>2;
+            do {
+                int32 Cb = pp[16];
+                int32 Cr = pp[17];
+
+                YCbCrtoRGB(cp [0], pp[ 0]);
+                YCbCrtoRGB(cp [1], pp[ 1]);
+                YCbCrtoRGB(cp [2], pp[ 2]);
+                YCbCrtoRGB(cp [3], pp[ 3]);
+                YCbCrtoRGB(cp1[0], pp[ 4]);
+                YCbCrtoRGB(cp1[1], pp[ 5]);
+                YCbCrtoRGB(cp1[2], pp[ 6]);
+                YCbCrtoRGB(cp1[3], pp[ 7]);
+                YCbCrtoRGB(cp2[0], pp[ 8]);
+                YCbCrtoRGB(cp2[1], pp[ 9]);
+                YCbCrtoRGB(cp2[2], pp[10]);
+                YCbCrtoRGB(cp2[3], pp[11]);
+                YCbCrtoRGB(cp3[0], pp[12]);
+                YCbCrtoRGB(cp3[1], pp[13]);
+                YCbCrtoRGB(cp3[2], pp[14]);
+                YCbCrtoRGB(cp3[3], pp[15]);
+
+                cp += 4, cp1 += 4, cp2 += 4, cp3 += 4;
+                pp += 18;
+            } while (--x);
+            cp += incr, cp1 += incr, cp2 += incr, cp3 += incr;
+            pp += fromskew;
+        }
+    } else {
+        while (h > 0) {
+            for (x = w; x > 0;) {
+                int32 Cb = pp[16];
+                int32 Cr = pp[17];
+                switch (x) {
+                default:
+                    switch (h) {
+                    default: YCbCrtoRGB(cp3[3], pp[15]); /* FALLTHROUGH */
+                    case 3:  YCbCrtoRGB(cp2[3], pp[11]); /* FALLTHROUGH */
+                    case 2:  YCbCrtoRGB(cp1[3], pp[ 7]); /* FALLTHROUGH */
+                    case 1:  YCbCrtoRGB(cp [3], pp[ 3]); /* FALLTHROUGH */
+                    }                                    /* FALLTHROUGH */
+                case 3:
+                    switch (h) {
+                    default: YCbCrtoRGB(cp3[2], pp[14]); /* FALLTHROUGH */
+                    case 3:  YCbCrtoRGB(cp2[2], pp[10]); /* FALLTHROUGH */
+                    case 2:  YCbCrtoRGB(cp1[2], pp[ 6]); /* FALLTHROUGH */
+                    case 1:  YCbCrtoRGB(cp [2], pp[ 2]); /* FALLTHROUGH */
+                    }                                    /* FALLTHROUGH */
+                case 2:
+                    switch (h) {
+                    default: YCbCrtoRGB(cp3[1], pp[13]); /* FALLTHROUGH */
+                    case 3:  YCbCrtoRGB(cp2[1], pp[ 9]); /* FALLTHROUGH */
+                    case 2:  YCbCrtoRGB(cp1[1], pp[ 5]); /* FALLTHROUGH */
+                    case 1:  YCbCrtoRGB(cp [1], pp[ 1]); /* FALLTHROUGH */
+                    }                                    /* FALLTHROUGH */
+                case 1:
+                    switch (h) {
+                    default: YCbCrtoRGB(cp3[0], pp[12]); /* FALLTHROUGH */
+                    case 3:  YCbCrtoRGB(cp2[0], pp[ 8]); /* FALLTHROUGH */
+                    case 2:  YCbCrtoRGB(cp1[0], pp[ 4]); /* FALLTHROUGH */
+                    case 1:  YCbCrtoRGB(cp [0], pp[ 0]); /* FALLTHROUGH */
+                    }                                    /* FALLTHROUGH */
+                }
+                if (x < 4) {
+                    cp += x; cp1 += x; cp2 += x; cp3 += x;
+                    x = 0;
+                }
+                else {
+                    cp += 4; cp1 += 4; cp2 += 4; cp3 += 4;
+                    x -= 4;
+                }
+                pp += 18;
+            }
+            if (h <= 4)
+                break;
+            h -= 4;
+            cp += incr, cp1 += incr, cp2 += incr, cp3 += incr;
+            pp += fromskew;
+        }
+    }
+}
+
+/*
+ * 8-bit packed YCbCr samples w/ 4,2 subsampling => RGB
+ */
+DECLAREContigPutFunc(putcontig8bitYCbCr42tile)
+{
+    uint32* cp1 = cp+w+toskew;
+    int32 incr = 2*toskew+w;
+
+    (void) y;
+    fromskew = (fromskew * 10) / 4;
+    if ((w & 3) == 0 && (h & 1) == 0) {
+        for (; h >= 2; h -= 2) {
+            x = w>>2;
+            do {
+                int32 Cb = pp[8];
+                int32 Cr = pp[9];
+                
+                YCbCrtoRGB(cp [0], pp[0]);
+                YCbCrtoRGB(cp [1], pp[1]);
+                YCbCrtoRGB(cp [2], pp[2]);
+                YCbCrtoRGB(cp [3], pp[3]);
+                YCbCrtoRGB(cp1[0], pp[4]);
+                YCbCrtoRGB(cp1[1], pp[5]);
+                YCbCrtoRGB(cp1[2], pp[6]);
+                YCbCrtoRGB(cp1[3], pp[7]);
+                
+                cp += 4, cp1 += 4;
+                pp += 10;
+            } while (--x);
+            cp += incr, cp1 += incr;
+            pp += fromskew;
+        }
+    } else {
+        while (h > 0) {
+            for (x = w; x > 0;) {
+                int32 Cb = pp[8];
+                int32 Cr = pp[9];
+                switch (x) {
+                default:
+                    switch (h) {
+                    default: YCbCrtoRGB(cp1[3], pp[ 7]); /* FALLTHROUGH */
+                    case 1:  YCbCrtoRGB(cp [3], pp[ 3]); /* FALLTHROUGH */
+                    }                                    /* FALLTHROUGH */
+                case 3:
+                    switch (h) {
+                    default: YCbCrtoRGB(cp1[2], pp[ 6]); /* FALLTHROUGH */
+                    case 1:  YCbCrtoRGB(cp [2], pp[ 2]); /* FALLTHROUGH */
+                    }                                    /* FALLTHROUGH */
+                case 2:
+                    switch (h) {
+                    default: YCbCrtoRGB(cp1[1], pp[ 5]); /* FALLTHROUGH */
+                    case 1:  YCbCrtoRGB(cp [1], pp[ 1]); /* FALLTHROUGH */
+                    }                                    /* FALLTHROUGH */
+                case 1:
+                    switch (h) {
+                    default: YCbCrtoRGB(cp1[0], pp[ 4]); /* FALLTHROUGH */
+                    case 1:  YCbCrtoRGB(cp [0], pp[ 0]); /* FALLTHROUGH */
+                    }                                    /* FALLTHROUGH */
+                }
+                if (x < 4) {
+                    cp += x; cp1 += x;
+                    x = 0;
+                }
+                else {
+                    cp += 4; cp1 += 4;
+                    x -= 4;
+                }
+                pp += 10;
+            }
+            if (h <= 2)
+                break;
+            h -= 2;
+            cp += incr, cp1 += incr;
+            pp += fromskew;
+        }
+    }
+}
+
+/*
+ * 8-bit packed YCbCr samples w/ 4,1 subsampling => RGB
+ */
+DECLAREContigPutFunc(putcontig8bitYCbCr41tile)
+{
+    (void) y;
+    /* XXX adjust fromskew */
+    do {
+	x = w>>2;
+	while(x>0) {
+	    int32 Cb = pp[4];
+	    int32 Cr = pp[5];
+
+	    YCbCrtoRGB(cp [0], pp[0]);
+	    YCbCrtoRGB(cp [1], pp[1]);
+	    YCbCrtoRGB(cp [2], pp[2]);
+	    YCbCrtoRGB(cp [3], pp[3]);
+
+	    cp += 4;
+	    pp += 6;
+		x--;
+	}
+
+        if( (w&3) != 0 )
+        {
+	    int32 Cb = pp[4];
+	    int32 Cr = pp[5];
+
+            switch( (w&3) ) {
+              case 3: YCbCrtoRGB(cp [2], pp[2]);
+              case 2: YCbCrtoRGB(cp [1], pp[1]);
+              case 1: YCbCrtoRGB(cp [0], pp[0]);
+              case 0: break;
+            }
+
+            cp += (w&3);
+            pp += 6;
+        }
+
+	cp += toskew;
+	pp += fromskew;
+    } while (--h);
+
+}
+
+/*
+ * 8-bit packed YCbCr samples w/ 2,2 subsampling => RGB
+ */
+DECLAREContigPutFunc(putcontig8bitYCbCr22tile)
+{
+	uint32* cp2;
+	int32 incr = 2*toskew+w;
+	(void) y;
+	fromskew = (fromskew / 2) * 6;
+	cp2 = cp+w+toskew;
+	while (h>=2) {
+		x = w;
+		while (x>=2) {
+			uint32 Cb = pp[4];
+			uint32 Cr = pp[5];
+			YCbCrtoRGB(cp[0], pp[0]);
+			YCbCrtoRGB(cp[1], pp[1]);
+			YCbCrtoRGB(cp2[0], pp[2]);
+			YCbCrtoRGB(cp2[1], pp[3]);
+			cp += 2;
+			cp2 += 2;
+			pp += 6;
+			x -= 2;
+		}
+		if (x==1) {
+			uint32 Cb = pp[4];
+			uint32 Cr = pp[5];
+			YCbCrtoRGB(cp[0], pp[0]);
+			YCbCrtoRGB(cp2[0], pp[2]);
+			cp ++ ;
+			cp2 ++ ;
+			pp += 6;
+		}
+		cp += incr;
+		cp2 += incr;
+		pp += fromskew;
+		h-=2;
+	}
+	if (h==1) {
+		x = w;
+		while (x>=2) {
+			uint32 Cb = pp[4];
+			uint32 Cr = pp[5];
+			YCbCrtoRGB(cp[0], pp[0]);
+			YCbCrtoRGB(cp[1], pp[1]);
+			cp += 2;
+			cp2 += 2;
+			pp += 6;
+			x -= 2;
+		}
+		if (x==1) {
+			uint32 Cb = pp[4];
+			uint32 Cr = pp[5];
+			YCbCrtoRGB(cp[0], pp[0]);
+		}
+	}
+}
+
+/*
+ * 8-bit packed YCbCr samples w/ 2,1 subsampling => RGB
+ */
+DECLAREContigPutFunc(putcontig8bitYCbCr21tile)
+{
+	(void) y;
+	fromskew = (fromskew * 4) / 2;
+	do {
+		x = w>>1;
+		while(x>0) {
+			int32 Cb = pp[2];
+			int32 Cr = pp[3];
+
+			YCbCrtoRGB(cp[0], pp[0]);
+			YCbCrtoRGB(cp[1], pp[1]);
+
+			cp += 2;
+			pp += 4;
+			x --;
+		}
+
+		if( (w&1) != 0 )
+		{
+			int32 Cb = pp[2];
+			int32 Cr = pp[3];
+
+			YCbCrtoRGB(cp[0], pp[0]);
+
+			cp += 1;
+			pp += 4;
+		}
+
+		cp += toskew;
+		pp += fromskew;
+	} while (--h);
+}
+
+/*
+ * 8-bit packed YCbCr samples w/ 1,2 subsampling => RGB
+ */
+DECLAREContigPutFunc(putcontig8bitYCbCr12tile)
+{
+	uint32* cp2;
+	int32 incr = 2*toskew+w;
+	(void) y;
+	fromskew = (fromskew / 2) * 4;
+	cp2 = cp+w+toskew;
+	while (h>=2) {
+		x = w;
+		do {
+			uint32 Cb = pp[2];
+			uint32 Cr = pp[3];
+			YCbCrtoRGB(cp[0], pp[0]);
+			YCbCrtoRGB(cp2[0], pp[1]);
+			cp ++;
+			cp2 ++;
+			pp += 4;
+		} while (--x);
+		cp += incr;
+		cp2 += incr;
+		pp += fromskew;
+		h-=2;
+	}
+	if (h==1) {
+		x = w;
+		do {
+			uint32 Cb = pp[2];
+			uint32 Cr = pp[3];
+			YCbCrtoRGB(cp[0], pp[0]);
+			cp ++;
+			pp += 4;
+		} while (--x);
+	}
+}
+
+/*
+ * 8-bit packed YCbCr samples w/ no subsampling => RGB
+ */
+DECLAREContigPutFunc(putcontig8bitYCbCr11tile)
+{
+	(void) y;
+	fromskew *= 3;
+	do {
+		x = w; /* was x = w>>1; patched 2000/09/25 warmerda at home.com */
+		do {
+			int32 Cb = pp[1];
+			int32 Cr = pp[2];
+
+			YCbCrtoRGB(*cp++, pp[0]);
+
+			pp += 3;
+		} while (--x);
+		cp += toskew;
+		pp += fromskew;
+	} while (--h);
+}
+
+/*
+ * 8-bit packed YCbCr samples w/ no subsampling => RGB
+ */
+DECLARESepPutFunc(putseparate8bitYCbCr11tile)
+{
+	(void) y;
+	(void) a;
+	/* TODO: naming of input vars is still off, change obfuscating declaration inside define, or resolve obfuscation */
+	while (h-- > 0) {
+		x = w;
+		do {
+			uint32 dr, dg, db;
+			TIFFYCbCrtoRGB(img->ycbcr,*r++,*g++,*b++,&dr,&dg,&db);
+			*cp++ = PACK(dr,dg,db);
+		} while (--x);
+		SKEW(r, g, b, fromskew);
+		cp += toskew;
+	}
+}
+#undef YCbCrtoRGB
+
+static int
+initYCbCrConversion(TIFFRGBAImage* img)
+{
+	static const char module[] = "initYCbCrConversion";
+
+	float *luma, *refBlackWhite;
+
+	if (img->ycbcr == NULL) {
+		img->ycbcr = (TIFFYCbCrToRGB*) _TIFFmalloc(
+		    TIFFroundup_32(sizeof (TIFFYCbCrToRGB), sizeof (long))  
+		    + 4*256*sizeof (TIFFRGBValue)
+		    + 2*256*sizeof (int)
+		    + 3*256*sizeof (int32)
+		    );
+		if (img->ycbcr == NULL) {
+			TIFFErrorExt(img->tif->tif_clientdata, module,
+			    "No space for YCbCr->RGB conversion state");
+			return (0);
+		}
+	}
+
+	TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRCOEFFICIENTS, &luma);
+	TIFFGetFieldDefaulted(img->tif, TIFFTAG_REFERENCEBLACKWHITE,
+	    &refBlackWhite);
+	if (TIFFYCbCrToRGBInit(img->ycbcr, luma, refBlackWhite) < 0)
+		return(0);
+	return (1);
+}
+
+static tileContigRoutine
+initCIELabConversion(TIFFRGBAImage* img)
+{
+	static const char module[] = "initCIELabConversion";
+
+	float   *whitePoint;
+	float   refWhite[3];
+
+	if (!img->cielab) {
+		img->cielab = (TIFFCIELabToRGB *)
+			_TIFFmalloc(sizeof(TIFFCIELabToRGB));
+		if (!img->cielab) {
+			TIFFErrorExt(img->tif->tif_clientdata, module,
+			    "No space for CIE L*a*b*->RGB conversion state.");
+			return NULL;
+		}
+	}
+
+	TIFFGetFieldDefaulted(img->tif, TIFFTAG_WHITEPOINT, &whitePoint);
+	refWhite[1] = 100.0F;
+	refWhite[0] = whitePoint[0] / whitePoint[1] * refWhite[1];
+	refWhite[2] = (1.0F - whitePoint[0] - whitePoint[1])
+		      / whitePoint[1] * refWhite[1];
+	if (TIFFCIELabToRGBInit(img->cielab, &display_sRGB, refWhite) < 0) {
+		TIFFErrorExt(img->tif->tif_clientdata, module,
+		    "Failed to initialize CIE L*a*b*->RGB conversion state.");
+		_TIFFfree(img->cielab);
+		return NULL;
+	}
+
+	return putcontig8bitCIELab;
+}
+
+/*
+ * Greyscale images with less than 8 bits/sample are handled
+ * with a table to avoid lots of shifts and masks.  The table
+ * is setup so that put*bwtile (below) can retrieve 8/bitspersample
+ * pixel values simply by indexing into the table with one
+ * number.
+ */
+static int
+makebwmap(TIFFRGBAImage* img)
+{
+    TIFFRGBValue* Map = img->Map;
+    int bitspersample = img->bitspersample;
+    int nsamples = 8 / bitspersample;
+    int i;
+    uint32* p;
+
+    if( nsamples == 0 )
+        nsamples = 1;
+
+    img->BWmap = (uint32**) _TIFFmalloc(
+	256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32)));
+    if (img->BWmap == NULL) {
+		TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No space for B&W mapping table");
+		return (0);
+    }
+    p = (uint32*)(img->BWmap + 256);
+    for (i = 0; i < 256; i++) {
+	TIFFRGBValue c;
+	img->BWmap[i] = p;
+	switch (bitspersample) {
+#define	GREY(x)	c = Map[x]; *p++ = PACK(c,c,c);
+	case 1:
+	    GREY(i>>7);
+	    GREY((i>>6)&1);
+	    GREY((i>>5)&1);
+	    GREY((i>>4)&1);
+	    GREY((i>>3)&1);
+	    GREY((i>>2)&1);
+	    GREY((i>>1)&1);
+	    GREY(i&1);
+	    break;
+	case 2:
+	    GREY(i>>6);
+	    GREY((i>>4)&3);
+	    GREY((i>>2)&3);
+	    GREY(i&3);
+	    break;
+	case 4:
+	    GREY(i>>4);
+	    GREY(i&0xf);
+	    break;
+	case 8:
+        case 16:
+	    GREY(i);
+	    break;
+	}
+#undef	GREY
+    }
+    return (1);
+}
+
+/*
+ * Construct a mapping table to convert from the range
+ * of the data samples to [0,255] --for display.  This
+ * process also handles inverting B&W images when needed.
+ */ 
+static int
+setupMap(TIFFRGBAImage* img)
+{
+    int32 x, range;
+
+    range = (int32)((1L<<img->bitspersample)-1);
+    
+    /* treat 16 bit the same as eight bit */
+    if( img->bitspersample == 16 )
+        range = (int32) 255;
+
+    img->Map = (TIFFRGBValue*) _TIFFmalloc((range+1) * sizeof (TIFFRGBValue));
+    if (img->Map == NULL) {
+		TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif),
+			"No space for photometric conversion table");
+		return (0);
+    }
+    if (img->photometric == PHOTOMETRIC_MINISWHITE) {
+	for (x = 0; x <= range; x++)
+	    img->Map[x] = (TIFFRGBValue) (((range - x) * 255) / range);
+    } else {
+	for (x = 0; x <= range; x++)
+	    img->Map[x] = (TIFFRGBValue) ((x * 255) / range);
+    }
+    if (img->bitspersample <= 16 &&
+	(img->photometric == PHOTOMETRIC_MINISBLACK ||
+	 img->photometric == PHOTOMETRIC_MINISWHITE)) {
+	/*
+	 * Use photometric mapping table to construct
+	 * unpacking tables for samples <= 8 bits.
+	 */
+	if (!makebwmap(img))
+	    return (0);
+	/* no longer need Map, free it */
+	_TIFFfree(img->Map), img->Map = NULL;
+    }
+    return (1);
+}
+
+static int
+checkcmap(TIFFRGBAImage* img)
+{
+    uint16* r = img->redcmap;
+    uint16* g = img->greencmap;
+    uint16* b = img->bluecmap;
+    long n = 1L<<img->bitspersample;
+
+    while (n-- > 0)
+	if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256)
+	    return (16);
+    return (8);
+}
+
+static void
+cvtcmap(TIFFRGBAImage* img)
+{
+    uint16* r = img->redcmap;
+    uint16* g = img->greencmap;
+    uint16* b = img->bluecmap;
+    long i;
+
+    for (i = (1L<<img->bitspersample)-1; i >= 0; i--) {
+#define	CVT(x)		((uint16)((x)>>8))
+	r[i] = CVT(r[i]);
+	g[i] = CVT(g[i]);
+	b[i] = CVT(b[i]);
+#undef	CVT
+    }
+}
+
+/*
+ * Palette images with <= 8 bits/sample are handled
+ * with a table to avoid lots of shifts and masks.  The table
+ * is setup so that put*cmaptile (below) can retrieve 8/bitspersample
+ * pixel values simply by indexing into the table with one
+ * number.
+ */
+static int
+makecmap(TIFFRGBAImage* img)
+{
+    int bitspersample = img->bitspersample;
+    int nsamples = 8 / bitspersample;
+    uint16* r = img->redcmap;
+    uint16* g = img->greencmap;
+    uint16* b = img->bluecmap;
+    uint32 *p;
+    int i;
+
+    img->PALmap = (uint32**) _TIFFmalloc(
+	256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32)));
+    if (img->PALmap == NULL) {
+		TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No space for Palette mapping table");
+		return (0);
+	}
+    p = (uint32*)(img->PALmap + 256);
+    for (i = 0; i < 256; i++) {
+	TIFFRGBValue c;
+	img->PALmap[i] = p;
+#define	CMAP(x)	c = (TIFFRGBValue) x; *p++ = PACK(r[c]&0xff, g[c]&0xff, b[c]&0xff);
+	switch (bitspersample) {
+	case 1:
+	    CMAP(i>>7);
+	    CMAP((i>>6)&1);
+	    CMAP((i>>5)&1);
+	    CMAP((i>>4)&1);
+	    CMAP((i>>3)&1);
+	    CMAP((i>>2)&1);
+	    CMAP((i>>1)&1);
+	    CMAP(i&1);
+	    break;
+	case 2:
+	    CMAP(i>>6);
+	    CMAP((i>>4)&3);
+	    CMAP((i>>2)&3);
+	    CMAP(i&3);
+	    break;
+	case 4:
+	    CMAP(i>>4);
+	    CMAP(i&0xf);
+	    break;
+	case 8:
+	    CMAP(i);
+	    break;
+	}
+#undef CMAP
+    }
+    return (1);
+}
+
+/* 
+ * Construct any mapping table used
+ * by the associated put routine.
+ */
+static int
+buildMap(TIFFRGBAImage* img)
+{
+    switch (img->photometric) {
+    case PHOTOMETRIC_RGB:
+    case PHOTOMETRIC_YCBCR:
+    case PHOTOMETRIC_SEPARATED:
+	if (img->bitspersample == 8)
+	    break;
+	/* fall thru... */
+    case PHOTOMETRIC_MINISBLACK:
+    case PHOTOMETRIC_MINISWHITE:
+	if (!setupMap(img))
+	    return (0);
+	break;
+    case PHOTOMETRIC_PALETTE:
+	/*
+	 * Convert 16-bit colormap to 8-bit (unless it looks
+	 * like an old-style 8-bit colormap).
+	 */
+	if (checkcmap(img) == 16)
+	    cvtcmap(img);
+	else
+	    TIFFWarningExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "Assuming 8-bit colormap");
+	/*
+	 * Use mapping table and colormap to construct
+	 * unpacking tables for samples < 8 bits.
+	 */
+	if (img->bitspersample <= 8 && !makecmap(img))
+	    return (0);
+	break;
+    }
+    return (1);
+}
+
+/*
+ * Select the appropriate conversion routine for packed data.
+ */
+static int
+PickContigCase(TIFFRGBAImage* img)
+{
+	img->get = TIFFIsTiled(img->tif) ? gtTileContig : gtStripContig;
+	img->put.contig = NULL;
+	switch (img->photometric) {
+		case PHOTOMETRIC_RGB:
+			switch (img->bitspersample) {
+				case 8:
+					if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
+						img->put.contig = putRGBAAcontig8bittile;
+					else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
+					{
+						if (BuildMapUaToAa(img))
+							img->put.contig = putRGBUAcontig8bittile;
+					}
+					else
+						img->put.contig = putRGBcontig8bittile;
+					break;
+				case 16:
+					if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
+					{
+						if (BuildMapBitdepth16To8(img))
+							img->put.contig = putRGBAAcontig16bittile;
+					}
+					else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
+					{
+						if (BuildMapBitdepth16To8(img) &&
+						    BuildMapUaToAa(img))
+							img->put.contig = putRGBUAcontig16bittile;
+					}
+					else
+					{
+						if (BuildMapBitdepth16To8(img))
+							img->put.contig = putRGBcontig16bittile;
+					}
+					break;
+			}
+			break;
+		case PHOTOMETRIC_SEPARATED:
+			if (buildMap(img)) {
+				if (img->bitspersample == 8) {
+					if (!img->Map)
+						img->put.contig = putRGBcontig8bitCMYKtile;
+					else
+						img->put.contig = putRGBcontig8bitCMYKMaptile;
+				}
+			}
+			break;
+		case PHOTOMETRIC_PALETTE:
+			if (buildMap(img)) {
+				switch (img->bitspersample) {
+					case 8:
+						img->put.contig = put8bitcmaptile;
+						break;
+					case 4:
+						img->put.contig = put4bitcmaptile;
+						break;
+					case 2:
+						img->put.contig = put2bitcmaptile;
+						break;
+					case 1:
+						img->put.contig = put1bitcmaptile;
+						break;
+				}
+			}
+			break;
+		case PHOTOMETRIC_MINISWHITE:
+		case PHOTOMETRIC_MINISBLACK:
+			if (buildMap(img)) {
+				switch (img->bitspersample) {
+					case 16:
+						img->put.contig = put16bitbwtile;
+						break;
+					case 8:
+						if (img->alpha && img->samplesperpixel == 2)
+							img->put.contig = putagreytile;
+						else
+							img->put.contig = putgreytile;
+						break;
+					case 4:
+						img->put.contig = put4bitbwtile;
+						break;
+					case 2:
+						img->put.contig = put2bitbwtile;
+						break;
+					case 1:
+						img->put.contig = put1bitbwtile;
+						break;
+				}
+			}
+			break;
+		case PHOTOMETRIC_YCBCR:
+			if ((img->bitspersample==8) && (img->samplesperpixel==3))
+			{
+				if (initYCbCrConversion(img)!=0)
+				{
+					/*
+					 * The 6.0 spec says that subsampling must be
+					 * one of 1, 2, or 4, and that vertical subsampling
+					 * must always be <= horizontal subsampling; so
+					 * there are only a few possibilities and we just
+					 * enumerate the cases.
+					 * Joris: added support for the [1,2] case, nonetheless, to accommodate
+					 * some OJPEG files
+					 */
+					uint16 SubsamplingHor;
+					uint16 SubsamplingVer;
+					TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &SubsamplingHor, &SubsamplingVer);
+					switch ((SubsamplingHor<<4)|SubsamplingVer) {
+						case 0x44:
+							img->put.contig = putcontig8bitYCbCr44tile;
+							break;
+						case 0x42:
+							img->put.contig = putcontig8bitYCbCr42tile;
+							break;
+						case 0x41:
+							img->put.contig = putcontig8bitYCbCr41tile;
+							break;
+						case 0x22:
+							img->put.contig = putcontig8bitYCbCr22tile;
+							break;
+						case 0x21:
+							img->put.contig = putcontig8bitYCbCr21tile;
+							break;
+						case 0x12:
+							img->put.contig = putcontig8bitYCbCr12tile;
+							break;
+						case 0x11:
+							img->put.contig = putcontig8bitYCbCr11tile;
+							break;
+					}
+				}
+			}
+			break;
+		case PHOTOMETRIC_CIELAB:
+			if (buildMap(img)) {
+				if (img->bitspersample == 8)
+					img->put.contig = initCIELabConversion(img);
+				break;
+			}
+	}
+	return ((img->get!=NULL) && (img->put.contig!=NULL));
+}
+
+/*
+ * Select the appropriate conversion routine for unpacked data.
+ *
+ * NB: we assume that unpacked single channel data is directed
+ *	 to the "packed routines.
+ */
+static int
+PickSeparateCase(TIFFRGBAImage* img)
+{
+	img->get = TIFFIsTiled(img->tif) ? gtTileSeparate : gtStripSeparate;
+	img->put.separate = NULL;
+	switch (img->photometric) {
+	case PHOTOMETRIC_MINISWHITE:
+	case PHOTOMETRIC_MINISBLACK:
+		/* greyscale images processed pretty much as RGB by gtTileSeparate */
+	case PHOTOMETRIC_RGB:
+		switch (img->bitspersample) {
+		case 8:
+			if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
+				img->put.separate = putRGBAAseparate8bittile;
+			else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
+			{
+				if (BuildMapUaToAa(img))
+					img->put.separate = putRGBUAseparate8bittile;
+			}
+			else
+				img->put.separate = putRGBseparate8bittile;
+			break;
+		case 16:
+			if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
+			{
+				if (BuildMapBitdepth16To8(img))
+					img->put.separate = putRGBAAseparate16bittile;
+			}
+			else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
+			{
+				if (BuildMapBitdepth16To8(img) &&
+				    BuildMapUaToAa(img))
+					img->put.separate = putRGBUAseparate16bittile;
+			}
+			else
+			{
+				if (BuildMapBitdepth16To8(img))
+					img->put.separate = putRGBseparate16bittile;
+			}
+			break;
+		}
+		break;
+	case PHOTOMETRIC_SEPARATED:
+		if (img->bitspersample == 8 && img->samplesperpixel == 4)
+		{
+			img->alpha = 1; // Not alpha, but seems like the only way to get 4th band
+			img->put.separate = putCMYKseparate8bittile;
+		}
+		break;
+	case PHOTOMETRIC_YCBCR:
+		if ((img->bitspersample==8) && (img->samplesperpixel==3))
+		{
+			if (initYCbCrConversion(img)!=0)
+			{
+				uint16 hs, vs;
+				TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &hs, &vs);
+				switch ((hs<<4)|vs) {
+				case 0x11:
+					img->put.separate = putseparate8bitYCbCr11tile;
+					break;
+					/* TODO: add other cases here */
+				}
+			}
+		}
+		break;
+	}
+	return ((img->get!=NULL) && (img->put.separate!=NULL));
+}
+
+static int
+BuildMapUaToAa(TIFFRGBAImage* img)
+{
+	static const char module[]="BuildMapUaToAa";
+	uint8* m;
+	uint16 na,nv;
+	assert(img->UaToAa==NULL);
+	img->UaToAa=_TIFFmalloc(65536);
+	if (img->UaToAa==NULL)
+	{
+		TIFFErrorExt(img->tif->tif_clientdata,module,"Out of memory");
+		return(0);
+	}
+	m=img->UaToAa;
+	for (na=0; na<256; na++)
+	{
+		for (nv=0; nv<256; nv++)
+			*m++=(nv*na+127)/255;
+	}
+	return(1);
+}
+
+static int
+BuildMapBitdepth16To8(TIFFRGBAImage* img)
+{
+	static const char module[]="BuildMapBitdepth16To8";
+	uint8* m;
+	uint32 n;
+	assert(img->Bitdepth16To8==NULL);
+	img->Bitdepth16To8=_TIFFmalloc(65536);
+	if (img->Bitdepth16To8==NULL)
+	{
+		TIFFErrorExt(img->tif->tif_clientdata,module,"Out of memory");
+		return(0);
+	}
+	m=img->Bitdepth16To8;
+	for (n=0; n<65536; n++)
+		*m++=(n+128)/257;
+	return(1);
+}
+
+
+/*
+ * Read a whole strip off data from the file, and convert to RGBA form.
+ * If this is the last strip, then it will only contain the portion of
+ * the strip that is actually within the image space.  The result is
+ * organized in bottom to top form.
+ */
+
+
+int
+TIFFReadRGBAStrip(TIFF* tif, uint32 row, uint32 * raster )
+
+{
+    char 	emsg[1024] = "";
+    TIFFRGBAImage img;
+    int 	ok;
+    uint32	rowsperstrip, rows_to_read;
+
+    if( TIFFIsTiled( tif ) )
+    {
+		TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
+                  "Can't use TIFFReadRGBAStrip() with tiled file.");
+	return (0);
+    }
+    
+    TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
+    if( (row % rowsperstrip) != 0 )
+    {
+		TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
+				"Row passed to TIFFReadRGBAStrip() must be first in a strip.");
+		return (0);
+    }
+
+    if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, 0, emsg)) {
+
+        img.row_offset = row;
+        img.col_offset = 0;
+
+        if( row + rowsperstrip > img.height )
+            rows_to_read = img.height - row;
+        else
+            rows_to_read = rowsperstrip;
+        
+	ok = TIFFRGBAImageGet(&img, raster, img.width, rows_to_read );
+        
+	TIFFRGBAImageEnd(&img);
+    } else {
+		TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg);
+		ok = 0;
+    }
+    
+    return (ok);
+}
+
+/*
+ * Read a whole tile off data from the file, and convert to RGBA form.
+ * The returned RGBA data is organized from bottom to top of tile,
+ * and may include zeroed areas if the tile extends off the image.
+ */
+
+int
+TIFFReadRGBATile(TIFF* tif, uint32 col, uint32 row, uint32 * raster)
+
+{
+    char 	emsg[1024] = "";
+    TIFFRGBAImage img;
+    int 	ok;
+    uint32	tile_xsize, tile_ysize;
+    uint32	read_xsize, read_ysize;
+    uint32	i_row;
+
+    /*
+     * Verify that our request is legal - on a tile file, and on a
+     * tile boundary.
+     */
+    
+    if( !TIFFIsTiled( tif ) )
+    {
+		TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
+				  "Can't use TIFFReadRGBATile() with stripped file.");
+		return (0);
+    }
+    
+    TIFFGetFieldDefaulted(tif, TIFFTAG_TILEWIDTH, &tile_xsize);
+    TIFFGetFieldDefaulted(tif, TIFFTAG_TILELENGTH, &tile_ysize);
+    if( (col % tile_xsize) != 0 || (row % tile_ysize) != 0 )
+    {
+		TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
+                  "Row/col passed to TIFFReadRGBATile() must be top"
+                  "left corner of a tile.");
+	return (0);
+    }
+
+    /*
+     * Setup the RGBA reader.
+     */
+    
+    if (!TIFFRGBAImageOK(tif, emsg) 
+	|| !TIFFRGBAImageBegin(&img, tif, 0, emsg)) {
+	    TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg);
+	    return( 0 );
+    }
+
+    /*
+     * The TIFFRGBAImageGet() function doesn't allow us to get off the
+     * edge of the image, even to fill an otherwise valid tile.  So we
+     * figure out how much we can read, and fix up the tile buffer to
+     * a full tile configuration afterwards.
+     */
+
+    if( row + tile_ysize > img.height )
+        read_ysize = img.height - row;
+    else
+        read_ysize = tile_ysize;
+    
+    if( col + tile_xsize > img.width )
+        read_xsize = img.width - col;
+    else
+        read_xsize = tile_xsize;
+
+    /*
+     * Read the chunk of imagery.
+     */
+    
+    img.row_offset = row;
+    img.col_offset = col;
+
+    ok = TIFFRGBAImageGet(&img, raster, read_xsize, read_ysize );
+        
+    TIFFRGBAImageEnd(&img);
+
+    /*
+     * If our read was incomplete we will need to fix up the tile by
+     * shifting the data around as if a full tile of data is being returned.
+     *
+     * This is all the more complicated because the image is organized in
+     * bottom to top format. 
+     */
+
+    if( read_xsize == tile_xsize && read_ysize == tile_ysize )
+        return( ok );
+
+    for( i_row = 0; i_row < read_ysize; i_row++ ) {
+        memmove( raster + (tile_ysize - i_row - 1) * tile_xsize,
+                 raster + (read_ysize - i_row - 1) * read_xsize,
+                 read_xsize * sizeof(uint32) );
+        _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize+read_xsize,
+                     0, sizeof(uint32) * (tile_xsize - read_xsize) );
+    }
+
+    for( i_row = read_ysize; i_row < tile_ysize; i_row++ ) {
+        _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize,
+                     0, sizeof(uint32) * tile_xsize );
+    }
+
+    return (ok);
+}
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tif_jbig.c b/Source/LibTIFF4/tif_jbig.c
index 644ea90..4d027f5 100644
--- a/Source/LibTIFF4/tif_jbig.c
+++ b/Source/LibTIFF4/tif_jbig.c
@@ -1,4 +1,4 @@
-/* $Id: tif_jbig.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
+/* $Id: tif_jbig.c,v 1.11 2015/02/19 22:39:58 drolon Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
diff --git a/Source/LibTIFF4/tif_jpeg.c b/Source/LibTIFF4/tif_jpeg.c
index e087e8a..d30bca0 100644
--- a/Source/LibTIFF4/tif_jpeg.c
+++ b/Source/LibTIFF4/tif_jpeg.c
@@ -1,2304 +1,2354 @@
-/* $Id: tif_jpeg.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * Copyright (c) 1994-1997 Sam Leffler
- * Copyright (c) 1994-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-#define WIN32_LEAN_AND_MEAN
-#define VC_EXTRALEAN
-
-#include "tiffiop.h"
-#ifdef JPEG_SUPPORT
-
-/*
- * TIFF Library
- *
- * JPEG Compression support per TIFF Technical Note #2
- * (*not* per the original TIFF 6.0 spec).
- *
- * This file is simply an interface to the libjpeg library written by
- * the Independent JPEG Group.  You need release 5 or later of the IJG
- * code, which you can find on the Internet at ftp.uu.net:/graphics/jpeg/.
- *
- * Contributed by Tom Lane <tgl at sss.pgh.pa.us>.
- */
-#include <setjmp.h>
-
-int TIFFFillStrip(TIFF* tif, uint32 strip);
-int TIFFFillTile(TIFF* tif, uint32 tile);
-int TIFFReInitJPEG_12( TIFF *tif, int scheme, int is_encode );
-
-/* We undefine FAR to avoid conflict with JPEG definition */
-
-#ifdef FAR
-#undef FAR
-#endif
-
-/*
-  Libjpeg's jmorecfg.h defines INT16 and INT32, but only if XMD_H is
-  not defined.  Unfortunately, the MinGW and Borland compilers include
-  a typedef for INT32, which causes a conflict.  MSVC does not include
-  a conficting typedef given the headers which are included.
-*/
-#if defined(__BORLANDC__) || defined(__MINGW32__)
-# define XMD_H 1
-#endif
-
-/*
-   The windows RPCNDR.H file defines boolean, but defines it with the
-   unsigned char size.  You should compile JPEG library using appropriate
-   definitions in jconfig.h header, but many users compile library in wrong
-   way. That causes errors of the following type:
-
-   "JPEGLib: JPEG parameter struct mismatch: library thinks size is 432,
-   caller expects 464"
-
-   For such users we wil fix the problem here. See install.doc file from
-   the JPEG library distribution for details.
-*/
-
-/* Define "boolean" as unsigned char, not int, per Windows custom. */
-#if defined(__WIN32__) && !defined(__MINGW32__)
-# ifndef __RPCNDR_H__            /* don't conflict if rpcndr.h already read */
-   typedef unsigned char boolean;
-# endif
-# define HAVE_BOOLEAN            /* prevent jmorecfg.h from redefining it */
-#endif
-
-#include "../LibJPEG/jpeglib.h"
-#include "../LibJPEG/jerror.h"
-
-/* 
- * Do we want to do special processing suitable for when JSAMPLE is a
- * 16bit value?  
- */
-
-#if defined(JPEG_LIB_MK1)
-#  define JPEG_LIB_MK1_OR_12BIT 1
-#elif BITS_IN_JSAMPLE == 12
-#  define JPEG_LIB_MK1_OR_12BIT 1
-#endif
-
-/*
- * We are using width_in_blocks which is supposed to be private to
- * libjpeg. Unfortunately, the libjpeg delivered with Cygwin has
- * renamed this member to width_in_data_units.  Since the header has
- * also renamed a define, use that unique define name in order to
- * detect the problem header and adjust to suit.
- */
-#if defined(D_MAX_DATA_UNITS_IN_MCU)
-#define width_in_blocks width_in_data_units
-#endif
-
-/*
- * On some machines it may be worthwhile to use _setjmp or sigsetjmp
- * in place of plain setjmp.  These macros will make it easier.
- */
-#define SETJMP(jbuf)		setjmp(jbuf)
-#define LONGJMP(jbuf,code)	longjmp(jbuf,code)
-#define JMP_BUF			jmp_buf
-
-typedef struct jpeg_destination_mgr jpeg_destination_mgr;
-typedef struct jpeg_source_mgr jpeg_source_mgr;
-typedef struct jpeg_error_mgr jpeg_error_mgr;
-
-/*
- * State block for each open TIFF file using
- * libjpeg to do JPEG compression/decompression.
- *
- * libjpeg's visible state is either a jpeg_compress_struct
- * or jpeg_decompress_struct depending on which way we
- * are going.  comm can be used to refer to the fields
- * which are common to both.
- *
- * NB: cinfo is required to be the first member of JPEGState,
- *     so we can safely cast JPEGState* -> jpeg_xxx_struct*
- *     and vice versa!
- */
-typedef struct {
-	union {
-		struct jpeg_compress_struct c;
-		struct jpeg_decompress_struct d;
-		struct jpeg_common_struct comm;
-	} cinfo;			/* NB: must be first */
-	int             cinfo_initialized;
-
-	jpeg_error_mgr	err;		/* libjpeg error manager */
-	JMP_BUF		exit_jmpbuf;	/* for catching libjpeg failures */
-	/*
-	 * The following two members could be a union, but
-	 * they're small enough that it's not worth the effort.
-	 */
-	jpeg_destination_mgr dest;	/* data dest for compression */
-	jpeg_source_mgr	src;		/* data source for decompression */
-					/* private state */
-	TIFF*		tif;		/* back link needed by some code */
-	uint16		photometric;	/* copy of PhotometricInterpretation */
-	uint16		h_sampling;	/* luminance sampling factors */
-	uint16		v_sampling;
-	tmsize_t   	bytesperline;	/* decompressed bytes per scanline */
-	/* pointers to intermediate buffers when processing downsampled data */
-	JSAMPARRAY	ds_buffer[MAX_COMPONENTS];
-	int		scancount;	/* number of "scanlines" accumulated */
-	int		samplesperclump;
-
-	TIFFVGetMethod	vgetparent;	/* super-class method */
-	TIFFVSetMethod	vsetparent;	/* super-class method */
-	TIFFPrintMethod printdir;	/* super-class method */
-	TIFFStripMethod	defsparent;	/* super-class method */
-	TIFFTileMethod	deftparent;	/* super-class method */
-					/* pseudo-tag fields */
-	void*		jpegtables;	/* JPEGTables tag value, or NULL */
-	uint32		jpegtables_length; /* number of bytes in same */
-	int		jpegquality;	/* Compression quality level */
-	int		jpegcolormode;	/* Auto RGB<=>YCbCr convert? */
-	int		jpegtablesmode;	/* What to put in JPEGTables */
-
-        int             ycbcrsampling_fetched;
-} JPEGState;
-
-#define	JState(tif)	((JPEGState*)(tif)->tif_data)
-
-static int JPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s);
-static int JPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s);
-static int JPEGEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s);
-static int JPEGEncodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s);
-static int JPEGInitializeLibJPEG(TIFF * tif, int decode );
-static int DecodeRowError(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s);
-
-#define	FIELD_JPEGTABLES	(FIELD_CODEC+0)
-
-static const TIFFField jpegFields[] = {
-    { TIFFTAG_JPEGTABLES, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_C32_UINT8, FIELD_JPEGTABLES, FALSE, TRUE, "JPEGTables", NULL },
-    { TIFFTAG_JPEGQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL },
-    { TIFFTAG_JPEGCOLORMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL },
-    { TIFFTAG_JPEGTABLESMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL }
-};
-
-/*
- * libjpeg interface layer.
- *
- * We use setjmp/longjmp to return control to libtiff
- * when a fatal error is encountered within the JPEG
- * library.  We also direct libjpeg error and warning
- * messages through the appropriate libtiff handlers.
- */
-
-/*
- * Error handling routines (these replace corresponding
- * IJG routines from jerror.c).  These are used for both
- * compression and decompression.
- */
-static void
-TIFFjpeg_error_exit(j_common_ptr cinfo)
-{
-	JPEGState *sp = (JPEGState *) cinfo;	/* NB: cinfo assumed first */
-	char buffer[JMSG_LENGTH_MAX];
-
-	(*cinfo->err->format_message) (cinfo, buffer);
-	TIFFErrorExt(sp->tif->tif_clientdata, "JPEGLib", "%s", buffer);		/* display the error message */
-	jpeg_abort(cinfo);			/* clean up libjpeg state */
-	LONGJMP(sp->exit_jmpbuf, 1);		/* return to libtiff caller */
-}
-
-/*
- * This routine is invoked only for warning messages,
- * since error_exit does its own thing and trace_level
- * is never set > 0.
- */
-static void
-TIFFjpeg_output_message(j_common_ptr cinfo)
-{
-	char buffer[JMSG_LENGTH_MAX];
-
-	(*cinfo->err->format_message) (cinfo, buffer);
-	TIFFWarningExt(((JPEGState *) cinfo)->tif->tif_clientdata, "JPEGLib", "%s", buffer);
-}
-
-/*
- * Interface routines.  This layer of routines exists
- * primarily to limit side-effects from using setjmp.
- * Also, normal/error returns are converted into return
- * values per libtiff practice.
- */
-#define	CALLJPEG(sp, fail, op)	(SETJMP((sp)->exit_jmpbuf) ? (fail) : (op))
-#define	CALLVJPEG(sp, op)	CALLJPEG(sp, 0, ((op),1))
-
-static int
-TIFFjpeg_create_compress(JPEGState* sp)
-{
-	/* initialize JPEG error handling */
-	sp->cinfo.c.err = jpeg_std_error(&sp->err);
-	sp->err.error_exit = TIFFjpeg_error_exit;
-	sp->err.output_message = TIFFjpeg_output_message;
-
-	return CALLVJPEG(sp, jpeg_create_compress(&sp->cinfo.c));
-}
-
-static int
-TIFFjpeg_create_decompress(JPEGState* sp)
-{
-	/* initialize JPEG error handling */
-	sp->cinfo.d.err = jpeg_std_error(&sp->err);
-	sp->err.error_exit = TIFFjpeg_error_exit;
-	sp->err.output_message = TIFFjpeg_output_message;
-
-	return CALLVJPEG(sp, jpeg_create_decompress(&sp->cinfo.d));
-}
-
-static int
-TIFFjpeg_set_defaults(JPEGState* sp)
-{
-	return CALLVJPEG(sp, jpeg_set_defaults(&sp->cinfo.c));
-}
-
-static int
-TIFFjpeg_set_colorspace(JPEGState* sp, J_COLOR_SPACE colorspace)
-{
-	return CALLVJPEG(sp, jpeg_set_colorspace(&sp->cinfo.c, colorspace));
-}
-
-static int
-TIFFjpeg_set_quality(JPEGState* sp, int quality, boolean force_baseline)
-{
-	return CALLVJPEG(sp,
-	    jpeg_set_quality(&sp->cinfo.c, quality, force_baseline));
-}
-
-static int
-TIFFjpeg_suppress_tables(JPEGState* sp, boolean suppress)
-{
-	return CALLVJPEG(sp, jpeg_suppress_tables(&sp->cinfo.c, suppress));
-}
-
-static int
-TIFFjpeg_start_compress(JPEGState* sp, boolean write_all_tables)
-{
-	return CALLVJPEG(sp,
-	    jpeg_start_compress(&sp->cinfo.c, write_all_tables));
-}
-
-static int
-TIFFjpeg_write_scanlines(JPEGState* sp, JSAMPARRAY scanlines, int num_lines)
-{
-	return CALLJPEG(sp, -1, (int) jpeg_write_scanlines(&sp->cinfo.c,
-	    scanlines, (JDIMENSION) num_lines));
-}
-
-static int
-TIFFjpeg_write_raw_data(JPEGState* sp, JSAMPIMAGE data, int num_lines)
-{
-	return CALLJPEG(sp, -1, (int) jpeg_write_raw_data(&sp->cinfo.c,
-	    data, (JDIMENSION) num_lines));
-}
-
-static int
-TIFFjpeg_finish_compress(JPEGState* sp)
-{
-	return CALLVJPEG(sp, jpeg_finish_compress(&sp->cinfo.c));
-}
-
-static int
-TIFFjpeg_write_tables(JPEGState* sp)
-{
-	return CALLVJPEG(sp, jpeg_write_tables(&sp->cinfo.c));
-}
-
-static int
-TIFFjpeg_read_header(JPEGState* sp, boolean require_image)
-{
-	return CALLJPEG(sp, -1, jpeg_read_header(&sp->cinfo.d, require_image));
-}
-
-static int
-TIFFjpeg_start_decompress(JPEGState* sp)
-{
-	return CALLVJPEG(sp, jpeg_start_decompress(&sp->cinfo.d));
-}
-
-static int
-TIFFjpeg_read_scanlines(JPEGState* sp, JSAMPARRAY scanlines, int max_lines)
-{
-	return CALLJPEG(sp, -1, (int) jpeg_read_scanlines(&sp->cinfo.d,
-	    scanlines, (JDIMENSION) max_lines));
-}
-
-static int
-TIFFjpeg_read_raw_data(JPEGState* sp, JSAMPIMAGE data, int max_lines)
-{
-	return CALLJPEG(sp, -1, (int) jpeg_read_raw_data(&sp->cinfo.d,
-	    data, (JDIMENSION) max_lines));
-}
-
-static int
-TIFFjpeg_finish_decompress(JPEGState* sp)
-{
-	return CALLJPEG(sp, -1, (int) jpeg_finish_decompress(&sp->cinfo.d));
-}
-
-static int
-TIFFjpeg_abort(JPEGState* sp)
-{
-	return CALLVJPEG(sp, jpeg_abort(&sp->cinfo.comm));
-}
-
-static int
-TIFFjpeg_destroy(JPEGState* sp)
-{
-	return CALLVJPEG(sp, jpeg_destroy(&sp->cinfo.comm));
-}
-
-static JSAMPARRAY
-TIFFjpeg_alloc_sarray(JPEGState* sp, int pool_id,
-		      JDIMENSION samplesperrow, JDIMENSION numrows)
-{
-	return CALLJPEG(sp, (JSAMPARRAY) NULL,
-	    (*sp->cinfo.comm.mem->alloc_sarray)
-		(&sp->cinfo.comm, pool_id, samplesperrow, numrows));
-}
-
-/*
- * JPEG library destination data manager.
- * These routines direct compressed data from libjpeg into the
- * libtiff output buffer.
- */
-
-static void
-std_init_destination(j_compress_ptr cinfo)
-{
-	JPEGState* sp = (JPEGState*) cinfo;
-	TIFF* tif = sp->tif;
-
-	sp->dest.next_output_byte = (JOCTET*) tif->tif_rawdata;
-	sp->dest.free_in_buffer = (size_t) tif->tif_rawdatasize;
-}
-
-static boolean
-std_empty_output_buffer(j_compress_ptr cinfo)
-{
-	JPEGState* sp = (JPEGState*) cinfo;
-	TIFF* tif = sp->tif;
-
-	/* the entire buffer has been filled */
-	tif->tif_rawcc = tif->tif_rawdatasize;
-
-#ifdef IPPJ_HUFF
-       /*
-        * The Intel IPP performance library does not necessarily fill up
-        * the whole output buffer on each pass, so only dump out the parts
-        * that have been filled.
-        *   http://trac.osgeo.org/gdal/wiki/JpegIPP
-        */
-       if ( sp->dest.free_in_buffer >= 0 ) {
-               tif->tif_rawcc = tif->tif_rawdatasize - sp->dest.free_in_buffer;
-       }
-#endif
-
-	TIFFFlushData1(tif);
-	sp->dest.next_output_byte = (JOCTET*) tif->tif_rawdata;
-	sp->dest.free_in_buffer = (size_t) tif->tif_rawdatasize;
-
-	return (TRUE);
-}
-
-static void
-std_term_destination(j_compress_ptr cinfo)
-{
-	JPEGState* sp = (JPEGState*) cinfo;
-	TIFF* tif = sp->tif;
-
-	tif->tif_rawcp = (uint8*) sp->dest.next_output_byte;
-	tif->tif_rawcc =
-	    tif->tif_rawdatasize - (tmsize_t) sp->dest.free_in_buffer;
-	/* NB: libtiff does the final buffer flush */
-}
-
-static void
-TIFFjpeg_data_dest(JPEGState* sp, TIFF* tif)
-{
-	(void) tif;
-	sp->cinfo.c.dest = &sp->dest;
-	sp->dest.init_destination = std_init_destination;
-	sp->dest.empty_output_buffer = std_empty_output_buffer;
-	sp->dest.term_destination = std_term_destination;
-}
-
-/*
- * Alternate destination manager for outputting to JPEGTables field.
- */
-
-static void
-tables_init_destination(j_compress_ptr cinfo)
-{
-	JPEGState* sp = (JPEGState*) cinfo;
-
-	/* while building, jpegtables_length is allocated buffer size */
-	sp->dest.next_output_byte = (JOCTET*) sp->jpegtables;
-	sp->dest.free_in_buffer = (size_t) sp->jpegtables_length;
-}
-
-static boolean
-tables_empty_output_buffer(j_compress_ptr cinfo)
-{
-	JPEGState* sp = (JPEGState*) cinfo;
-	void* newbuf;
-
-	/* the entire buffer has been filled; enlarge it by 1000 bytes */
-	newbuf = _TIFFrealloc((void*) sp->jpegtables,
-			      (tmsize_t) (sp->jpegtables_length + 1000));
-	if (newbuf == NULL)
-		ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 100);
-	sp->dest.next_output_byte = (JOCTET*) newbuf + sp->jpegtables_length;
-	sp->dest.free_in_buffer = (size_t) 1000;
-	sp->jpegtables = newbuf;
-	sp->jpegtables_length += 1000;
-	return (TRUE);
-}
-
-static void
-tables_term_destination(j_compress_ptr cinfo)
-{
-	JPEGState* sp = (JPEGState*) cinfo;
-
-	/* set tables length to number of bytes actually emitted */
-	sp->jpegtables_length -= (uint32) sp->dest.free_in_buffer;
-}
-
-static int
-TIFFjpeg_tables_dest(JPEGState* sp, TIFF* tif)
-{
-	(void) tif;
-	/*
-	 * Allocate a working buffer for building tables.
-	 * Initial size is 1000 bytes, which is usually adequate.
-	 */
-	if (sp->jpegtables)
-		_TIFFfree(sp->jpegtables);
-	sp->jpegtables_length = 1000;
-	sp->jpegtables = (void*) _TIFFmalloc((tmsize_t) sp->jpegtables_length);
-	if (sp->jpegtables == NULL) {
-		sp->jpegtables_length = 0;
-		TIFFErrorExt(sp->tif->tif_clientdata, "TIFFjpeg_tables_dest", "No space for JPEGTables");
-		return (0);
-	}
-	sp->cinfo.c.dest = &sp->dest;
-	sp->dest.init_destination = tables_init_destination;
-	sp->dest.empty_output_buffer = tables_empty_output_buffer;
-	sp->dest.term_destination = tables_term_destination;
-	return (1);
-}
-
-/*
- * JPEG library source data manager.
- * These routines supply compressed data to libjpeg.
- */
-
-static void
-std_init_source(j_decompress_ptr cinfo)
-{
-	JPEGState* sp = (JPEGState*) cinfo;
-	TIFF* tif = sp->tif;
-
-	sp->src.next_input_byte = (const JOCTET*) tif->tif_rawdata;
-	sp->src.bytes_in_buffer = (size_t) tif->tif_rawcc;
-}
-
-static boolean
-std_fill_input_buffer(j_decompress_ptr cinfo)
-{
-	JPEGState* sp = (JPEGState* ) cinfo;
-	static const JOCTET dummy_EOI[2] = { 0xFF, JPEG_EOI };
-
-#ifdef IPPJ_HUFF
-        /*
-         * The Intel IPP performance library does not necessarily read the whole
-         * input buffer in one pass, so it is possible to get here with data
-         * yet to read. 
-         * 
-         * We just return without doing anything, until the entire buffer has
-         * been read.  
-         * http://trac.osgeo.org/gdal/wiki/JpegIPP
-         */
-        if( sp->src.bytes_in_buffer > 0 ) {
-            return (TRUE);
-        }
-#endif
-
-	/*
-         * Normally the whole strip/tile is read and so we don't need to do
-         * a fill.  In the case of CHUNKY_STRIP_READ_SUPPORT we might not have
-         * all the data, but the rawdata is refreshed between scanlines and
-         * we push this into the io machinery in JPEGDecode(). 	 
-         * http://trac.osgeo.org/gdal/ticket/3894
-	 */
-        
-	WARNMS(cinfo, JWRN_JPEG_EOF);
-	/* insert a fake EOI marker */
-	sp->src.next_input_byte = dummy_EOI;
-	sp->src.bytes_in_buffer = 2;
-	return (TRUE);
-}
-
-static void
-std_skip_input_data(j_decompress_ptr cinfo, long num_bytes)
-{
-	JPEGState* sp = (JPEGState*) cinfo;
-
-	if (num_bytes > 0) {
-		if ((size_t)num_bytes > sp->src.bytes_in_buffer) {
-			/* oops, buffer overrun */
-			(void) std_fill_input_buffer(cinfo);
-		} else {
-			sp->src.next_input_byte += (size_t) num_bytes;
-			sp->src.bytes_in_buffer -= (size_t) num_bytes;
-		}
-	}
-}
-
-static void
-std_term_source(j_decompress_ptr cinfo)
-{
-	/* No work necessary here */
-	(void) cinfo;
-}
-
-static void
-TIFFjpeg_data_src(JPEGState* sp, TIFF* tif)
-{
-	(void) tif;
-	sp->cinfo.d.src = &sp->src;
-	sp->src.init_source = std_init_source;
-	sp->src.fill_input_buffer = std_fill_input_buffer;
-	sp->src.skip_input_data = std_skip_input_data;
-	sp->src.resync_to_restart = jpeg_resync_to_restart;
-	sp->src.term_source = std_term_source;
-	sp->src.bytes_in_buffer = 0;		/* for safety */
-	sp->src.next_input_byte = NULL;
-}
-
-/*
- * Alternate source manager for reading from JPEGTables.
- * We can share all the code except for the init routine.
- */
-
-static void
-tables_init_source(j_decompress_ptr cinfo)
-{
-	JPEGState* sp = (JPEGState*) cinfo;
-
-	sp->src.next_input_byte = (const JOCTET*) sp->jpegtables;
-	sp->src.bytes_in_buffer = (size_t) sp->jpegtables_length;
-}
-
-static void
-TIFFjpeg_tables_src(JPEGState* sp, TIFF* tif)
-{
-	TIFFjpeg_data_src(sp, tif);
-	sp->src.init_source = tables_init_source;
-}
-
-/*
- * Allocate downsampled-data buffers needed for downsampled I/O.
- * We use values computed in jpeg_start_compress or jpeg_start_decompress.
- * We use libjpeg's allocator so that buffers will be released automatically
- * when done with strip/tile.
- * This is also a handy place to compute samplesperclump, bytesperline.
- */
-static int
-alloc_downsampled_buffers(TIFF* tif, jpeg_component_info* comp_info,
-			  int num_components)
-{
-	JPEGState* sp = JState(tif);
-	int ci;
-	jpeg_component_info* compptr;
-	JSAMPARRAY buf;
-	int samples_per_clump = 0;
-
-	for (ci = 0, compptr = comp_info; ci < num_components;
-	     ci++, compptr++) {
-		samples_per_clump += compptr->h_samp_factor *
-			compptr->v_samp_factor;
-		buf = TIFFjpeg_alloc_sarray(sp, JPOOL_IMAGE,
-				compptr->width_in_blocks * DCTSIZE,
-				(JDIMENSION) (compptr->v_samp_factor*DCTSIZE));
-		if (buf == NULL)
-			return (0);
-		sp->ds_buffer[ci] = buf;
-	}
-	sp->samplesperclump = samples_per_clump;
-	return (1);
-}
-
-
-/*
- * JPEG Decoding.
- */
-
-#ifdef CHECK_JPEG_YCBCR_SUBSAMPLING
-
-#define JPEG_MARKER_SOF0 0xC0
-#define JPEG_MARKER_SOF1 0xC1
-#define JPEG_MARKER_SOF3 0xC3
-#define JPEG_MARKER_DHT 0xC4
-#define JPEG_MARKER_SOI 0xD8
-#define JPEG_MARKER_SOS 0xDA
-#define JPEG_MARKER_DQT 0xDB
-#define JPEG_MARKER_DRI 0xDD
-#define JPEG_MARKER_APP0 0xE0
-#define JPEG_MARKER_COM 0xFE
-struct JPEGFixupTagsSubsamplingData
-{
-	TIFF* tif;
-	void* buffer;
-	uint32 buffersize;
-	uint8* buffercurrentbyte;
-	uint32 bufferbytesleft;
-	uint64 fileoffset;
-	uint64 filebytesleft;
-	uint8 filepositioned;
-};
-static void JPEGFixupTagsSubsampling(TIFF* tif);
-static int JPEGFixupTagsSubsamplingSec(struct JPEGFixupTagsSubsamplingData* data);
-static int JPEGFixupTagsSubsamplingReadByte(struct JPEGFixupTagsSubsamplingData* data, uint8* result);
-static int JPEGFixupTagsSubsamplingReadWord(struct JPEGFixupTagsSubsamplingData* data, uint16* result);
-static void JPEGFixupTagsSubsamplingSkip(struct JPEGFixupTagsSubsamplingData* data, uint16 skiplength);
-
-#endif
-
-static int
-JPEGFixupTags(TIFF* tif)
-{
-#ifdef CHECK_JPEG_YCBCR_SUBSAMPLING
-	if ((tif->tif_dir.td_photometric==PHOTOMETRIC_YCBCR)&&
-	    (tif->tif_dir.td_planarconfig==PLANARCONFIG_CONTIG)&&
-	    (tif->tif_dir.td_samplesperpixel==3))
-		JPEGFixupTagsSubsampling(tif);
-#endif
-        
-	return(1);
-}
-
-#ifdef CHECK_JPEG_YCBCR_SUBSAMPLING
-
-static void
-JPEGFixupTagsSubsampling(TIFF* tif)
-{
-	/*
-	 * Some JPEG-in-TIFF produces do not emit the YCBCRSUBSAMPLING values in
-	 * the TIFF tags, but still use non-default (2,2) values within the jpeg
-	 * data stream itself.  In order for TIFF applications to work properly
-	 * - for instance to get the strip buffer size right - it is imperative
-	 * that the subsampling be available before we start reading the image
-	 * data normally.  This function will attempt to analyze the first strip in
-	 * order to get the sampling values from the jpeg data stream.
-	 *
-	 * Note that JPEGPreDeocode() will produce a fairly loud warning when the
-	 * discovered sampling does not match the default sampling (2,2) or whatever
-	 * was actually in the tiff tags.
-	 *
-	 * See the bug in bugzilla for details:
-	 *
-	 * http://bugzilla.remotesensing.org/show_bug.cgi?id=168
-	 *
-	 * Frank Warmerdam, July 2002
-	 * Joris Van Damme, May 2007
-	 */
-	static const char module[] = "JPEGFixupTagsSubsampling";
-	struct JPEGFixupTagsSubsamplingData m;
-
-        _TIFFFillStriles( tif );
-        
-        if( tif->tif_dir.td_stripbytecount == NULL
-            || tif->tif_dir.td_stripbytecount[0] == 0 )
-        {
-            /* Do not even try to check if the first strip/tile does not
-               yet exist, as occurs when GDAL has created a new NULL file
-               for instance. */
-            return;
-        }
-
-	m.tif=tif;
-	m.buffersize=2048;
-	m.buffer=_TIFFmalloc(m.buffersize);
-	if (m.buffer==NULL)
-	{
-		TIFFWarningExt(tif->tif_clientdata,module,
-		    "Unable to allocate memory for auto-correcting of subsampling values; auto-correcting skipped");
-		return;
-	}
-	m.buffercurrentbyte=NULL;
-	m.bufferbytesleft=0;
-	m.fileoffset=tif->tif_dir.td_stripoffset[0];
-	m.filepositioned=0;
-	m.filebytesleft=tif->tif_dir.td_stripbytecount[0];
-	if (!JPEGFixupTagsSubsamplingSec(&m))
-		TIFFWarningExt(tif->tif_clientdata,module,
-		    "Unable to auto-correct subsampling values, likely corrupt JPEG compressed data in first strip/tile; auto-correcting skipped");
-	_TIFFfree(m.buffer);
-}
-
-static int
-JPEGFixupTagsSubsamplingSec(struct JPEGFixupTagsSubsamplingData* data)
-{
-	static const char module[] = "JPEGFixupTagsSubsamplingSec";
-	uint8 m;
-	while (1)
-	{
-		while (1)
-		{
-			if (!JPEGFixupTagsSubsamplingReadByte(data,&m))
-				return(0);
-			if (m==255)
-				break;
-		}
-		while (1)
-		{
-			if (!JPEGFixupTagsSubsamplingReadByte(data,&m))
-				return(0);
-			if (m!=255)
-				break;
-		}
-		switch (m)
-		{
-			case JPEG_MARKER_SOI:
-				/* this type of marker has no data and should be skipped */
-				break;
-			case JPEG_MARKER_COM:
-			case JPEG_MARKER_APP0:
-			case JPEG_MARKER_APP0+1:
-			case JPEG_MARKER_APP0+2:
-			case JPEG_MARKER_APP0+3:
-			case JPEG_MARKER_APP0+4:
-			case JPEG_MARKER_APP0+5:
-			case JPEG_MARKER_APP0+6:
-			case JPEG_MARKER_APP0+7:
-			case JPEG_MARKER_APP0+8:
-			case JPEG_MARKER_APP0+9:
-			case JPEG_MARKER_APP0+10:
-			case JPEG_MARKER_APP0+11:
-			case JPEG_MARKER_APP0+12:
-			case JPEG_MARKER_APP0+13:
-			case JPEG_MARKER_APP0+14:
-			case JPEG_MARKER_APP0+15:
-			case JPEG_MARKER_DQT:
-			case JPEG_MARKER_SOS:
-			case JPEG_MARKER_DHT:
-			case JPEG_MARKER_DRI:
-				/* this type of marker has data, but it has no use to us and should be skipped */
-				{
-					uint16 n;
-					if (!JPEGFixupTagsSubsamplingReadWord(data,&n))
-						return(0);
-					if (n<2)
-						return(0);
-					n-=2;
-					if (n>0)
-						JPEGFixupTagsSubsamplingSkip(data,n);
-				}
-				break;
-			case JPEG_MARKER_SOF0:
-			case JPEG_MARKER_SOF1:
-				/* this marker contains the subsampling factors we're scanning for */
-				{
-					uint16 n;
-					uint16 o;
-					uint8 p;
-					uint8 ph,pv;
-					if (!JPEGFixupTagsSubsamplingReadWord(data,&n))
-						return(0);
-					if (n!=8+data->tif->tif_dir.td_samplesperpixel*3)
-						return(0);
-					JPEGFixupTagsSubsamplingSkip(data,7);
-					if (!JPEGFixupTagsSubsamplingReadByte(data,&p))
-						return(0);
-					ph=(p>>4);
-					pv=(p&15);
-					JPEGFixupTagsSubsamplingSkip(data,1);
-					for (o=1; o<data->tif->tif_dir.td_samplesperpixel; o++)
-					{
-						JPEGFixupTagsSubsamplingSkip(data,1);
-						if (!JPEGFixupTagsSubsamplingReadByte(data,&p))
-							return(0);
-						if (p!=0x11)
-						{
-							TIFFWarningExt(data->tif->tif_clientdata,module,
-							    "Subsampling values inside JPEG compressed data have no TIFF equivalent, auto-correction of TIFF subsampling values failed");
-							return(1);
-						}
-						JPEGFixupTagsSubsamplingSkip(data,1);
-					}
-					if (((ph!=1)&&(ph!=2)&&(ph!=4))||((pv!=1)&&(pv!=2)&&(pv!=4)))
-					{
-						TIFFWarningExt(data->tif->tif_clientdata,module,
-						    "Subsampling values inside JPEG compressed data have no TIFF equivalent, auto-correction of TIFF subsampling values failed");
-						return(1);
-					}
-					if ((ph!=data->tif->tif_dir.td_ycbcrsubsampling[0])||(pv!=data->tif->tif_dir.td_ycbcrsubsampling[1]))
-					{
-						TIFFWarningExt(data->tif->tif_clientdata,module,
-						    "Auto-corrected former TIFF subsampling values [%d,%d] to match subsampling values inside JPEG compressed data [%d,%d]",
-						    (int)data->tif->tif_dir.td_ycbcrsubsampling[0],
-						    (int)data->tif->tif_dir.td_ycbcrsubsampling[1],
-						    (int)ph,(int)pv);
-						data->tif->tif_dir.td_ycbcrsubsampling[0]=ph;
-						data->tif->tif_dir.td_ycbcrsubsampling[1]=pv;
-					}
-				}
-				return(1);
-			default:
-				return(0);
-		}
-	}
-}
-
-static int
-JPEGFixupTagsSubsamplingReadByte(struct JPEGFixupTagsSubsamplingData* data, uint8* result)
-{
-	if (data->bufferbytesleft==0)
-	{
-		uint32 m;
-		if (data->filebytesleft==0)
-			return(0);
-		if (!data->filepositioned)
-		{
-			TIFFSeekFile(data->tif,data->fileoffset,SEEK_SET);
-			data->filepositioned=1;
-		}
-		m=data->buffersize;
-		if ((uint64)m>data->filebytesleft)
-			m=(uint32)data->filebytesleft;
-		assert(m<0x80000000UL);
-		if (TIFFReadFile(data->tif,data->buffer,(tmsize_t)m)!=(tmsize_t)m)
-			return(0);
-		data->buffercurrentbyte=data->buffer;
-		data->bufferbytesleft=m;
-		data->fileoffset+=m;
-		data->filebytesleft-=m;
-	}
-	*result=*data->buffercurrentbyte;
-	data->buffercurrentbyte++;
-	data->bufferbytesleft--;
-	return(1);
-}
-
-static int
-JPEGFixupTagsSubsamplingReadWord(struct JPEGFixupTagsSubsamplingData* data, uint16* result)
-{
-	uint8 ma;
-	uint8 mb;
-	if (!JPEGFixupTagsSubsamplingReadByte(data,&ma))
-		return(0);
-	if (!JPEGFixupTagsSubsamplingReadByte(data,&mb))
-		return(0);
-	*result=(ma<<8)|mb;
-	return(1);
-}
-
-static void
-JPEGFixupTagsSubsamplingSkip(struct JPEGFixupTagsSubsamplingData* data, uint16 skiplength)
-{
-	if ((uint32)skiplength<=data->bufferbytesleft)
-	{
-		data->buffercurrentbyte+=skiplength;
-		data->bufferbytesleft-=skiplength;
-	}
-	else
-	{
-		uint16 m;
-		m=skiplength-data->bufferbytesleft;
-		if (m<=data->filebytesleft)
-		{
-			data->bufferbytesleft=0;
-			data->fileoffset+=m;
-			data->filebytesleft-=m;
-			data->filepositioned=0;
-		}
-		else
-		{
-			data->bufferbytesleft=0;
-			data->filebytesleft=0;
-		}
-	}
-}
-
-#endif
-
-
-static int
-JPEGSetupDecode(TIFF* tif)
-{
-	JPEGState* sp = JState(tif);
-	TIFFDirectory *td = &tif->tif_dir;
-
-#if defined(JPEG_DUAL_MODE_8_12) && !defined(TIFFInitJPEG)
-        if( tif->tif_dir.td_bitspersample == 12 )
-            return TIFFReInitJPEG_12( tif, COMPRESSION_JPEG, 0 );
-#endif
-
-	JPEGInitializeLibJPEG( tif, TRUE );
-
-	assert(sp != NULL);
-	assert(sp->cinfo.comm.is_decompressor);
-
-	/* Read JPEGTables if it is present */
-	if (TIFFFieldSet(tif,FIELD_JPEGTABLES)) {
-		TIFFjpeg_tables_src(sp, tif);
-		if(TIFFjpeg_read_header(sp,FALSE) != JPEG_HEADER_TABLES_ONLY) {
-			TIFFErrorExt(tif->tif_clientdata, "JPEGSetupDecode", "Bogus JPEGTables field");
-			return (0);
-		}
-	}
-
-	/* Grab parameters that are same for all strips/tiles */
-	sp->photometric = td->td_photometric;
-	switch (sp->photometric) {
-	case PHOTOMETRIC_YCBCR:
-		sp->h_sampling = td->td_ycbcrsubsampling[0];
-		sp->v_sampling = td->td_ycbcrsubsampling[1];
-		break;
-	default:
-		/* TIFF 6.0 forbids subsampling of all other color spaces */
-		sp->h_sampling = 1;
-		sp->v_sampling = 1;
-		break;
-	}
-
-	/* Set up for reading normal data */
-	TIFFjpeg_data_src(sp, tif);
-	tif->tif_postdecode = _TIFFNoPostDecode; /* override byte swapping */
-	return (1);
-}
-
-/*
- * Set up for decoding a strip or tile.
- */
-static int
-JPEGPreDecode(TIFF* tif, uint16 s)
-{
-	JPEGState *sp = JState(tif);
-	TIFFDirectory *td = &tif->tif_dir;
-	static const char module[] = "JPEGPreDecode";
-	uint32 segment_width, segment_height;
-	int downsampled_output;
-	int ci;
-
-	assert(sp != NULL);
-  
-	if (sp->cinfo.comm.is_decompressor == 0)
-	{
-		tif->tif_setupdecode( tif );
-	}
-  
-	assert(sp->cinfo.comm.is_decompressor);
-	/*
-	 * Reset decoder state from any previous strip/tile,
-	 * in case application didn't read the whole strip.
-	 */
-	if (!TIFFjpeg_abort(sp))
-		return (0);
-	/*
-	 * Read the header for this strip/tile.
-	 */
-        
-	if (TIFFjpeg_read_header(sp, TRUE) != JPEG_HEADER_OK)
-		return (0);
-
-        tif->tif_rawcp = (uint8*) sp->src.next_input_byte;
-        tif->tif_rawcc = sp->src.bytes_in_buffer;
-
-	/*
-	 * Check image parameters and set decompression parameters.
-	 */
-	segment_width = td->td_imagewidth;
-	segment_height = td->td_imagelength - tif->tif_row;
-	if (isTiled(tif)) {
-                segment_width = td->td_tilewidth;
-                segment_height = td->td_tilelength;
-		sp->bytesperline = TIFFTileRowSize(tif);
-	} else {
-		if (segment_height > td->td_rowsperstrip)
-			segment_height = td->td_rowsperstrip;
-		sp->bytesperline = TIFFScanlineSize(tif);
-	}
-	if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0) {
-		/*
-		 * For PC 2, scale down the expected strip/tile size
-		 * to match a downsampled component
-		 */
-		segment_width = TIFFhowmany_32(segment_width, sp->h_sampling);
-		segment_height = TIFFhowmany_32(segment_height, sp->v_sampling);
-	}
-	if (sp->cinfo.d.image_width < segment_width ||
-	    sp->cinfo.d.image_height < segment_height) {
-		TIFFWarningExt(tif->tif_clientdata, module,
-			       "Improper JPEG strip/tile size, "
-			       "expected %dx%d, got %dx%d",
-			       segment_width, segment_height,
-			       sp->cinfo.d.image_width,
-			       sp->cinfo.d.image_height);
-	} 
-	if (sp->cinfo.d.image_width > segment_width ||
-	    sp->cinfo.d.image_height > segment_height) {
-		/*
-		 * This case could be dangerous, if the strip or tile size has
-		 * been reported as less than the amount of data jpeg will
-		 * return, some potential security issues arise. Catch this
-		 * case and error out.
-		 */
-		TIFFErrorExt(tif->tif_clientdata, module,
-			     "JPEG strip/tile size exceeds expected dimensions,"
-			     " expected %dx%d, got %dx%d",
-			     segment_width, segment_height,
-			     sp->cinfo.d.image_width, sp->cinfo.d.image_height);
-		return (0);
-	}
-	if (sp->cinfo.d.num_components !=
-	    (td->td_planarconfig == PLANARCONFIG_CONTIG ?
-	     td->td_samplesperpixel : 1)) {
-		TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG component count");
-		return (0);
-	}
-#ifdef JPEG_LIB_MK1
-	if (12 != td->td_bitspersample && 8 != td->td_bitspersample) {
-		TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG data precision");
-		return (0);
-	}
-	sp->cinfo.d.data_precision = td->td_bitspersample;
-	sp->cinfo.d.bits_in_jsample = td->td_bitspersample;
-#else
-	if (sp->cinfo.d.data_precision != td->td_bitspersample) {
-		TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG data precision");
-		return (0);
-	}
-#endif
-	if (td->td_planarconfig == PLANARCONFIG_CONTIG) {
-		/* Component 0 should have expected sampling factors */
-		if (sp->cinfo.d.comp_info[0].h_samp_factor != sp->h_sampling ||
-		    sp->cinfo.d.comp_info[0].v_samp_factor != sp->v_sampling) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-				       "Improper JPEG sampling factors %d,%d\n"
-				       "Apparently should be %d,%d.",
-				       sp->cinfo.d.comp_info[0].h_samp_factor,
-				       sp->cinfo.d.comp_info[0].v_samp_factor,
-				       sp->h_sampling, sp->v_sampling);
-			return (0);
-		}
-		/* Rest should have sampling factors 1,1 */
-		for (ci = 1; ci < sp->cinfo.d.num_components; ci++) {
-			if (sp->cinfo.d.comp_info[ci].h_samp_factor != 1 ||
-			    sp->cinfo.d.comp_info[ci].v_samp_factor != 1) {
-				TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG sampling factors");
-				return (0);
-			}
-		}
-	} else {
-		/* PC 2's single component should have sampling factors 1,1 */
-		if (sp->cinfo.d.comp_info[0].h_samp_factor != 1 ||
-		    sp->cinfo.d.comp_info[0].v_samp_factor != 1) {
-			TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG sampling factors");
-			return (0);
-		}
-	}
-	downsampled_output = FALSE;
-	if (td->td_planarconfig == PLANARCONFIG_CONTIG &&
-	    sp->photometric == PHOTOMETRIC_YCBCR &&
-	    sp->jpegcolormode == JPEGCOLORMODE_RGB) {
-		/* Convert YCbCr to RGB */
-		sp->cinfo.d.jpeg_color_space = JCS_YCbCr;
-		sp->cinfo.d.out_color_space = JCS_RGB;
-	} else {
-		/* Suppress colorspace handling */
-		sp->cinfo.d.jpeg_color_space = JCS_UNKNOWN;
-		sp->cinfo.d.out_color_space = JCS_UNKNOWN;
-		if (td->td_planarconfig == PLANARCONFIG_CONTIG &&
-		    (sp->h_sampling != 1 || sp->v_sampling != 1))
-			downsampled_output = TRUE;
-		/* XXX what about up-sampling? */
-	}
-	if (downsampled_output) {
-		/* Need to use raw-data interface to libjpeg */
-		sp->cinfo.d.raw_data_out = TRUE;
-#if JPEG_LIB_VERSION >= 70
-		sp->cinfo.d.do_fancy_upsampling = FALSE;
-#endif /* JPEG_LIB_VERSION >= 70 */
-		tif->tif_decoderow = DecodeRowError;
-		tif->tif_decodestrip = JPEGDecodeRaw;
-		tif->tif_decodetile = JPEGDecodeRaw;
-	} else {
-		/* Use normal interface to libjpeg */
-		sp->cinfo.d.raw_data_out = FALSE;
-		tif->tif_decoderow = JPEGDecode;
-		tif->tif_decodestrip = JPEGDecode;
-		tif->tif_decodetile = JPEGDecode;  
-	}
-	/* Start JPEG decompressor */
-	if (!TIFFjpeg_start_decompress(sp))
-		return (0);
-	/* Allocate downsampled-data buffers if needed */
-	if (downsampled_output) {
-		if (!alloc_downsampled_buffers(tif, sp->cinfo.d.comp_info,
-					       sp->cinfo.d.num_components))
-			return (0);
-		sp->scancount = DCTSIZE;	/* mark buffer empty */
-	}
-	return (1);
-}
-
-/*
- * Decode a chunk of pixels.
- * "Standard" case: returned data is not downsampled.
- */
-/*ARGSUSED*/ static int
-JPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
-{
-	JPEGState *sp = JState(tif);
-	tmsize_t nrows;
-	(void) s;
-
-        /*
-        ** Update available information, buffer may have been refilled
-        ** between decode requests
-        */
-	sp->src.next_input_byte = (const JOCTET*) tif->tif_rawcp;
-	sp->src.bytes_in_buffer = (size_t) tif->tif_rawcc;
-
-        if( sp->bytesperline == 0 )
-                return 0;
-        
-	nrows = cc / sp->bytesperline;
-	if (cc % sp->bytesperline)
-		TIFFWarningExt(tif->tif_clientdata, tif->tif_name, "fractional scanline not read");
-
-	if( nrows > (tmsize_t) sp->cinfo.d.image_height )
-		nrows = sp->cinfo.d.image_height;
-
-	/* data is expected to be read in multiples of a scanline */
-	if (nrows)
-	{
-		JSAMPROW line_work_buf = NULL;
-
-		/*
-		 * For 6B, only use temporary buffer for 12 bit imagery.
-		 * For Mk1 always use it.
-		 */
-#if !defined(JPEG_LIB_MK1)
-		if( sp->cinfo.d.data_precision == 12 )
-#endif
-		{
-			line_work_buf = (JSAMPROW)
-			    _TIFFmalloc(sizeof(short) * sp->cinfo.d.output_width
-			    * sp->cinfo.d.num_components );
-		}
-
-		do {
-			if( line_work_buf != NULL )
-			{
-				/*
-				 * In the MK1 case, we aways read into a 16bit buffer, and then
-				 * pack down to 12bit or 8bit.  In 6B case we only read into 16
-				 * bit buffer for 12bit data, which we need to repack.
-				*/
-				if (TIFFjpeg_read_scanlines(sp, &line_work_buf, 1) != 1)
-					return (0);
-
-				if( sp->cinfo.d.data_precision == 12 )
-				{
-					int value_pairs = (sp->cinfo.d.output_width
-					    * sp->cinfo.d.num_components) / 2;
-					int iPair;
-
-					for( iPair = 0; iPair < value_pairs; iPair++ )
-					{
-						unsigned char *out_ptr =
-						    ((unsigned char *) buf) + iPair * 3;
-						JSAMPLE *in_ptr = line_work_buf + iPair * 2;
-
-						out_ptr[0] = (in_ptr[0] & 0xff0) >> 4;
-						out_ptr[1] = ((in_ptr[0] & 0xf) << 4)
-						    | ((in_ptr[1] & 0xf00) >> 8);
-						out_ptr[2] = ((in_ptr[1] & 0xff) >> 0);
-					}
-				}
-				else if( sp->cinfo.d.data_precision == 8 )
-				{
-					int value_count = (sp->cinfo.d.output_width
-					    * sp->cinfo.d.num_components);
-					int iValue;
-
-					for( iValue = 0; iValue < value_count; iValue++ )
-					{
-						((unsigned char *) buf)[iValue] =
-						    line_work_buf[iValue] & 0xff;
-					}
-				}
-			}
-			else
-			{
-				/*
-				 * In the libjpeg6b 8bit case.  We read directly into the
-				 * TIFF buffer.
-				*/
-				JSAMPROW bufptr = (JSAMPROW)buf;
-
-				if (TIFFjpeg_read_scanlines(sp, &bufptr, 1) != 1)
-					return (0);
-			}
-
-			++tif->tif_row;
-			buf += sp->bytesperline;
-			cc -= sp->bytesperline;
-		} while (--nrows > 0);
-
-		if( line_work_buf != NULL )
-			_TIFFfree( line_work_buf );
-	}
-
-        /* Update information on consumed data */
-        tif->tif_rawcp = (uint8*) sp->src.next_input_byte;
-        tif->tif_rawcc = sp->src.bytes_in_buffer;
-                
-	/* Close down the decompressor if we've finished the strip or tile. */
-	return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height
-	    || TIFFjpeg_finish_decompress(sp);
-}
-
-/*ARGSUSED*/ static int
-DecodeRowError(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
-
-{
-    (void) buf;
-    (void) cc;
-    (void) s;
-
-    TIFFErrorExt(tif->tif_clientdata, "TIFFReadScanline",
-                 "scanline oriented access is not supported for downsampled JPEG compressed images, consider enabling TIFF_JPEGCOLORMODE as JPEGCOLORMODE_RGB." );
-    return 0;
-}
-
-/*
- * Decode a chunk of pixels.
- * Returned data is downsampled per sampling factors.
- */
-/*ARGSUSED*/ static int
-JPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
-{
-	JPEGState *sp = JState(tif);
-	tmsize_t nrows;
-	(void) s;
-
-	/* data is expected to be read in multiples of a scanline */
-	if ( (nrows = sp->cinfo.d.image_height) ) {
-
-		/* Cb,Cr both have sampling factors 1, so this is correct */
-		JDIMENSION clumps_per_line = sp->cinfo.d.comp_info[1].downsampled_width;            
-		int samples_per_clump = sp->samplesperclump;
-
-#if defined(JPEG_LIB_MK1_OR_12BIT)
-		unsigned short* tmpbuf = _TIFFmalloc(sizeof(unsigned short) *
-						     sp->cinfo.d.output_width *
-						     sp->cinfo.d.num_components);
-		if(tmpbuf==NULL) {
-                        TIFFErrorExt(tif->tif_clientdata, "JPEGDecodeRaw",
-				     "Out of memory");
-			return 0;
-                }
-#endif
-
-		do {
-			jpeg_component_info *compptr;
-			int ci, clumpoffset;
-
-                        if( cc < sp->bytesperline ) {
-				TIFFErrorExt(tif->tif_clientdata, "JPEGDecodeRaw",
-					     "application buffer not large enough for all data.");
-				return 0;
-                        }
-
-			/* Reload downsampled-data buffer if needed */
-			if (sp->scancount >= DCTSIZE) {
-				int n = sp->cinfo.d.max_v_samp_factor * DCTSIZE;
-				if (TIFFjpeg_read_raw_data(sp, sp->ds_buffer, n) != n)
-					return (0);
-				sp->scancount = 0;
-			}
-			/*
-			 * Fastest way to unseparate data is to make one pass
-			 * over the scanline for each row of each component.
-			 */
-			clumpoffset = 0;    /* first sample in clump */
-			for (ci = 0, compptr = sp->cinfo.d.comp_info;
-			     ci < sp->cinfo.d.num_components;
-			     ci++, compptr++) {
-				int hsamp = compptr->h_samp_factor;
-				int vsamp = compptr->v_samp_factor;
-				int ypos;
-
-				for (ypos = 0; ypos < vsamp; ypos++) {
-					JSAMPLE *inptr = sp->ds_buffer[ci][sp->scancount*vsamp + ypos];
-					JDIMENSION nclump;
-#if defined(JPEG_LIB_MK1_OR_12BIT)
-					JSAMPLE *outptr = (JSAMPLE*)tmpbuf + clumpoffset;
-#else
-					JSAMPLE *outptr = (JSAMPLE*)buf + clumpoffset;
-					if (cc < (tmsize_t) (clumpoffset + samples_per_clump*(clumps_per_line-1) + hsamp)) {
-						TIFFErrorExt(tif->tif_clientdata, "JPEGDecodeRaw",
-							     "application buffer not large enough for all data, possible subsampling issue");
-						return 0;
-					}
-#endif
-
-					if (hsamp == 1) {
-						/* fast path for at least Cb and Cr */
-						for (nclump = clumps_per_line; nclump-- > 0; ) {
-							outptr[0] = *inptr++;
-							outptr += samples_per_clump;
-						}
-					} else {
-						int xpos;
-
-						/* general case */
-						for (nclump = clumps_per_line; nclump-- > 0; ) {
-							for (xpos = 0; xpos < hsamp; xpos++)
-								outptr[xpos] = *inptr++;
-							outptr += samples_per_clump;
-						}
-					}
-					clumpoffset += hsamp;
-				}
-			}
-
-#if defined(JPEG_LIB_MK1_OR_12BIT)
-			{
-				if (sp->cinfo.d.data_precision == 8)
-				{
-					int i=0;
-					int len = sp->cinfo.d.output_width * sp->cinfo.d.num_components;
-					for (i=0; i<len; i++)
-					{
-						((unsigned char*)buf)[i] = tmpbuf[i] & 0xff;
-					}
-				}
-				else
-				{         /* 12-bit */
-					int value_pairs = (sp->cinfo.d.output_width
-							   * sp->cinfo.d.num_components) / 2;
-					int iPair;
-					for( iPair = 0; iPair < value_pairs; iPair++ )
-					{
-						unsigned char *out_ptr = ((unsigned char *) buf) + iPair * 3;
-						JSAMPLE *in_ptr = (JSAMPLE *) (tmpbuf + iPair * 2);
-						out_ptr[0] = (in_ptr[0] & 0xff0) >> 4;
-						out_ptr[1] = ((in_ptr[0] & 0xf) << 4)
-							| ((in_ptr[1] & 0xf00) >> 8);
-						out_ptr[2] = ((in_ptr[1] & 0xff) >> 0);
-					}
-				}
-			}
-#endif
-
-			sp->scancount ++;
-			tif->tif_row += sp->v_sampling;
-
-			buf += sp->bytesperline;
-			cc -= sp->bytesperline;
-
-			nrows -= sp->v_sampling;
-		} while (nrows > 0);
-
-#if defined(JPEG_LIB_MK1_OR_12BIT)
-		_TIFFfree(tmpbuf);
-#endif
-
-	}
-
-	/* Close down the decompressor if done. */
-	return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height
-		|| TIFFjpeg_finish_decompress(sp);
-}
-
-
-/*
- * JPEG Encoding.
- */
-
-static void
-unsuppress_quant_table (JPEGState* sp, int tblno)
-{
-	JQUANT_TBL* qtbl;
-
-	if ((qtbl = sp->cinfo.c.quant_tbl_ptrs[tblno]) != NULL)
-		qtbl->sent_table = FALSE;
-}
-
-static void
-unsuppress_huff_table (JPEGState* sp, int tblno)
-{
-	JHUFF_TBL* htbl;
-
-	if ((htbl = sp->cinfo.c.dc_huff_tbl_ptrs[tblno]) != NULL)
-		htbl->sent_table = FALSE;
-	if ((htbl = sp->cinfo.c.ac_huff_tbl_ptrs[tblno]) != NULL)
-		htbl->sent_table = FALSE;
-}
-
-static int
-prepare_JPEGTables(TIFF* tif)
-{
-	JPEGState* sp = JState(tif);
-
-	/* Initialize quant tables for current quality setting */
-	if (!TIFFjpeg_set_quality(sp, sp->jpegquality, FALSE))
-		return (0);
-	/* Mark only the tables we want for output */
-	/* NB: chrominance tables are currently used only with YCbCr */
-	if (!TIFFjpeg_suppress_tables(sp, TRUE))
-		return (0);
-	if (sp->jpegtablesmode & JPEGTABLESMODE_QUANT) {
-		unsuppress_quant_table(sp, 0);
-		if (sp->photometric == PHOTOMETRIC_YCBCR)
-			unsuppress_quant_table(sp, 1);
-	}
-	if (sp->jpegtablesmode & JPEGTABLESMODE_HUFF) {
-		unsuppress_huff_table(sp, 0);
-		if (sp->photometric == PHOTOMETRIC_YCBCR)
-			unsuppress_huff_table(sp, 1);
-	}
-	/* Direct libjpeg output into jpegtables */
-	if (!TIFFjpeg_tables_dest(sp, tif))
-		return (0);
-	/* Emit tables-only datastream */
-	if (!TIFFjpeg_write_tables(sp))
-		return (0);
-
-	return (1);
-}
-
-static int
-JPEGSetupEncode(TIFF* tif)
-{
-	JPEGState* sp = JState(tif);
-	TIFFDirectory *td = &tif->tif_dir;
-	static const char module[] = "JPEGSetupEncode";
-
-#if defined(JPEG_DUAL_MODE_8_12) && !defined(TIFFInitJPEG)
-        if( tif->tif_dir.td_bitspersample == 12 )
-            return TIFFReInitJPEG_12( tif, COMPRESSION_JPEG, 1 );
-#endif
-
-        JPEGInitializeLibJPEG( tif, FALSE );
-
-	assert(sp != NULL);
-	assert(!sp->cinfo.comm.is_decompressor);
-
-	/*
-	 * Initialize all JPEG parameters to default values.
-	 * Note that jpeg_set_defaults needs legal values for
-	 * in_color_space and input_components.
-	 */
-	sp->cinfo.c.in_color_space = JCS_UNKNOWN;
-	sp->cinfo.c.input_components = 1;
-	if (!TIFFjpeg_set_defaults(sp))
-		return (0);
-	/* Set per-file parameters */
-	sp->photometric = td->td_photometric;
-	switch (sp->photometric) {
-	case PHOTOMETRIC_YCBCR:
-		sp->h_sampling = td->td_ycbcrsubsampling[0];
-		sp->v_sampling = td->td_ycbcrsubsampling[1];
-		/*
-		 * A ReferenceBlackWhite field *must* be present since the
-		 * default value is inappropriate for YCbCr.  Fill in the
-		 * proper value if application didn't set it.
-		 */
-		{
-			float *ref;
-			if (!TIFFGetField(tif, TIFFTAG_REFERENCEBLACKWHITE,
-					  &ref)) {
-				float refbw[6];
-				long top = 1L << td->td_bitspersample;
-				refbw[0] = 0;
-				refbw[1] = (float)(top-1L);
-				refbw[2] = (float)(top>>1);
-				refbw[3] = refbw[1];
-				refbw[4] = refbw[2];
-				refbw[5] = refbw[1];
-				TIFFSetField(tif, TIFFTAG_REFERENCEBLACKWHITE,
-					     refbw);
-			}
-		}
-		break;
-	case PHOTOMETRIC_PALETTE:		/* disallowed by Tech Note */
-	case PHOTOMETRIC_MASK:
-		TIFFErrorExt(tif->tif_clientdata, module,
-			  "PhotometricInterpretation %d not allowed for JPEG",
-			  (int) sp->photometric);
-		return (0);
-	default:
-		/* TIFF 6.0 forbids subsampling of all other color spaces */
-		sp->h_sampling = 1;
-		sp->v_sampling = 1;
-		break;
-	}
-
-	/* Verify miscellaneous parameters */
-
-	/*
-	 * This would need work if libtiff ever supports different
-	 * depths for different components, or if libjpeg ever supports
-	 * run-time selection of depth.  Neither is imminent.
-	 */
-#ifdef JPEG_LIB_MK1
-        /* BITS_IN_JSAMPLE now permits 8 and 12 --- dgilbert */
-	if (td->td_bitspersample != 8 && td->td_bitspersample != 12) 
-#else
-	if (td->td_bitspersample != BITS_IN_JSAMPLE )
-#endif
-	{
-		TIFFErrorExt(tif->tif_clientdata, module, "BitsPerSample %d not allowed for JPEG",
-			  (int) td->td_bitspersample);
-		return (0);
-	}
-	sp->cinfo.c.data_precision = td->td_bitspersample;
-#ifdef JPEG_LIB_MK1
-        sp->cinfo.c.bits_in_jsample = td->td_bitspersample;
-#endif
-	if (isTiled(tif)) {
-		if ((td->td_tilelength % (sp->v_sampling * DCTSIZE)) != 0) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-				  "JPEG tile height must be multiple of %d",
-				  sp->v_sampling * DCTSIZE);
-			return (0);
-		}
-		if ((td->td_tilewidth % (sp->h_sampling * DCTSIZE)) != 0) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-				  "JPEG tile width must be multiple of %d",
-				  sp->h_sampling * DCTSIZE);
-			return (0);
-		}
-	} else {
-		if (td->td_rowsperstrip < td->td_imagelength &&
-		    (td->td_rowsperstrip % (sp->v_sampling * DCTSIZE)) != 0) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-				  "RowsPerStrip must be multiple of %d for JPEG",
-				  sp->v_sampling * DCTSIZE);
-			return (0);
-		}
-	}
-
-	/* Create a JPEGTables field if appropriate */
-	if (sp->jpegtablesmode & (JPEGTABLESMODE_QUANT|JPEGTABLESMODE_HUFF)) {
-                if( sp->jpegtables == NULL
-                    || memcmp(sp->jpegtables,"\0\0\0\0\0\0\0\0\0",8) == 0 )
-                {
-                        if (!prepare_JPEGTables(tif))
-                                return (0);
-                        /* Mark the field present */
-                        /* Can't use TIFFSetField since BEENWRITING is already set! */
-                        tif->tif_flags |= TIFF_DIRTYDIRECT;
-                        TIFFSetFieldBit(tif, FIELD_JPEGTABLES);
-                }
-	} else {
-		/* We do not support application-supplied JPEGTables, */
-		/* so mark the field not present */
-		TIFFClrFieldBit(tif, FIELD_JPEGTABLES);
-	}
-
-	/* Direct libjpeg output to libtiff's output buffer */
-	TIFFjpeg_data_dest(sp, tif);
-
-	return (1);
-}
-
-/*
- * Set encoding state at the start of a strip or tile.
- */
-static int
-JPEGPreEncode(TIFF* tif, uint16 s)
-{
-	JPEGState *sp = JState(tif);
-	TIFFDirectory *td = &tif->tif_dir;
-	static const char module[] = "JPEGPreEncode";
-	uint32 segment_width, segment_height;
-	int downsampled_input;
-
-	assert(sp != NULL);
-  
-	if (sp->cinfo.comm.is_decompressor == 1)
-	{
-		tif->tif_setupencode( tif );
-	}
-  
-	assert(!sp->cinfo.comm.is_decompressor);
-	/*
-	 * Set encoding parameters for this strip/tile.
-	 */
-	if (isTiled(tif)) {
-		segment_width = td->td_tilewidth;
-		segment_height = td->td_tilelength;
-		sp->bytesperline = TIFFTileRowSize(tif);
-	} else {
-		segment_width = td->td_imagewidth;
-		segment_height = td->td_imagelength - tif->tif_row;
-		if (segment_height > td->td_rowsperstrip)
-			segment_height = td->td_rowsperstrip;
-		sp->bytesperline = TIFFScanlineSize(tif);
-	}
-	if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0) {
-		/* for PC 2, scale down the strip/tile size
-		 * to match a downsampled component
-		 */
-		segment_width = TIFFhowmany_32(segment_width, sp->h_sampling); 
-		segment_height = TIFFhowmany_32(segment_height, sp->v_sampling);
-	}
-	if (segment_width > 65535 || segment_height > 65535) {
-		TIFFErrorExt(tif->tif_clientdata, module, "Strip/tile too large for JPEG");
-		return (0);
-	}
-	sp->cinfo.c.image_width = segment_width;
-	sp->cinfo.c.image_height = segment_height;
-	downsampled_input = FALSE;
-	if (td->td_planarconfig == PLANARCONFIG_CONTIG) {
-		sp->cinfo.c.input_components = td->td_samplesperpixel;
-		if (sp->photometric == PHOTOMETRIC_YCBCR) {
-			if (sp->jpegcolormode == JPEGCOLORMODE_RGB) {
-				sp->cinfo.c.in_color_space = JCS_RGB;
-			} else {
-				sp->cinfo.c.in_color_space = JCS_YCbCr;
-				if (sp->h_sampling != 1 || sp->v_sampling != 1)
-					downsampled_input = TRUE;
-			}
-			if (!TIFFjpeg_set_colorspace(sp, JCS_YCbCr))
-				return (0);
-			/*
-			 * Set Y sampling factors;
-			 * we assume jpeg_set_colorspace() set the rest to 1
-			 */
-			sp->cinfo.c.comp_info[0].h_samp_factor = sp->h_sampling;
-			sp->cinfo.c.comp_info[0].v_samp_factor = sp->v_sampling;
-		} else {
-			if ((td->td_photometric == PHOTOMETRIC_MINISWHITE || td->td_photometric == PHOTOMETRIC_MINISBLACK) && td->td_samplesperpixel == 1)
-				sp->cinfo.c.in_color_space = JCS_GRAYSCALE;
-			else if (td->td_photometric == PHOTOMETRIC_RGB && td->td_samplesperpixel == 3)
-				sp->cinfo.c.in_color_space = JCS_RGB;
-			else if (td->td_photometric == PHOTOMETRIC_SEPARATED && td->td_samplesperpixel == 4)
-				sp->cinfo.c.in_color_space = JCS_CMYK;
-			else
-				sp->cinfo.c.in_color_space = JCS_UNKNOWN;
-			if (!TIFFjpeg_set_colorspace(sp, sp->cinfo.c.in_color_space))
-				return (0);
-			/* jpeg_set_colorspace set all sampling factors to 1 */
-		}
-	} else {
-		sp->cinfo.c.input_components = 1;
-		sp->cinfo.c.in_color_space = JCS_UNKNOWN;
-		if (!TIFFjpeg_set_colorspace(sp, JCS_UNKNOWN))
-			return (0);
-		sp->cinfo.c.comp_info[0].component_id = s;
-		/* jpeg_set_colorspace() set sampling factors to 1 */
-		if (sp->photometric == PHOTOMETRIC_YCBCR && s > 0) {
-			sp->cinfo.c.comp_info[0].quant_tbl_no = 1;
-			sp->cinfo.c.comp_info[0].dc_tbl_no = 1;
-			sp->cinfo.c.comp_info[0].ac_tbl_no = 1;
-		}
-	}
-	/* ensure libjpeg won't write any extraneous markers */
-	sp->cinfo.c.write_JFIF_header = FALSE;
-	sp->cinfo.c.write_Adobe_marker = FALSE;
-	/* set up table handling correctly */
-        if (!TIFFjpeg_set_quality(sp, sp->jpegquality, FALSE))
-		return (0);
-	if (! (sp->jpegtablesmode & JPEGTABLESMODE_QUANT)) {
-		unsuppress_quant_table(sp, 0);
-		unsuppress_quant_table(sp, 1);
-	}
-	if (sp->jpegtablesmode & JPEGTABLESMODE_HUFF)
-		sp->cinfo.c.optimize_coding = FALSE;
-	else
-		sp->cinfo.c.optimize_coding = TRUE;
-	if (downsampled_input) {
-		/* Need to use raw-data interface to libjpeg */
-		sp->cinfo.c.raw_data_in = TRUE;
-		tif->tif_encoderow = JPEGEncodeRaw;
-		tif->tif_encodestrip = JPEGEncodeRaw;
-		tif->tif_encodetile = JPEGEncodeRaw;
-	} else {
-		/* Use normal interface to libjpeg */
-		sp->cinfo.c.raw_data_in = FALSE;
-		tif->tif_encoderow = JPEGEncode;
-		tif->tif_encodestrip = JPEGEncode;
-		tif->tif_encodetile = JPEGEncode;
-	}
-	/* Start JPEG compressor */
-	if (!TIFFjpeg_start_compress(sp, FALSE))
-		return (0);
-	/* Allocate downsampled-data buffers if needed */
-	if (downsampled_input) {
-		if (!alloc_downsampled_buffers(tif, sp->cinfo.c.comp_info,
-					       sp->cinfo.c.num_components))
-			return (0);
-	}
-	sp->scancount = 0;
-
-	return (1);
-}
-
-/*
- * Encode a chunk of pixels.
- * "Standard" case: incoming data is not downsampled.
- */
-static int
-JPEGEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
-{
-	JPEGState *sp = JState(tif);
-	tmsize_t nrows;
-	JSAMPROW bufptr[1];
-        short *line16 = NULL;
-        int    line16_count = 0;
-
-	(void) s;
-	assert(sp != NULL);
-	/* data is expected to be supplied in multiples of a scanline */
-	nrows = cc / sp->bytesperline;
-	if (cc % sp->bytesperline)
-            TIFFWarningExt(tif->tif_clientdata, tif->tif_name, 
-                           "fractional scanline discarded");
-
-        /* The last strip will be limited to image size */
-        if( !isTiled(tif) && tif->tif_row+nrows > tif->tif_dir.td_imagelength )
-            nrows = tif->tif_dir.td_imagelength - tif->tif_row;
-
-        if( sp->cinfo.c.data_precision == 12 )
-        {
-            line16_count = (sp->bytesperline * 2) / 3;
-            line16 = (short *) _TIFFmalloc(sizeof(short) * line16_count);
-	    // FIXME: undiagnosed malloc failure
-        }
-            
-	while (nrows-- > 0) {
-
-            if( sp->cinfo.c.data_precision == 12 )
-            {
-
-                int value_pairs = line16_count / 2;
-                int iPair;
-
-		bufptr[0] = (JSAMPROW) line16;
-
-                for( iPair = 0; iPair < value_pairs; iPair++ )
-                {
-                    unsigned char *in_ptr =
-                        ((unsigned char *) buf) + iPair * 3;
-                    JSAMPLE *out_ptr = (JSAMPLE *) (line16 + iPair * 2);
-
-                    out_ptr[0] = (in_ptr[0] << 4) | ((in_ptr[1] & 0xf0) >> 4);
-                    out_ptr[1] = ((in_ptr[1] & 0x0f) << 8) | in_ptr[2];
-                }
-            }
-            else
-            {
-		bufptr[0] = (JSAMPROW) buf;
-            }
-            if (TIFFjpeg_write_scanlines(sp, bufptr, 1) != 1)
-                return (0);
-            if (nrows > 0)
-                tif->tif_row++;
-            buf += sp->bytesperline;
-	}
-
-        if( sp->cinfo.c.data_precision == 12 )
-        {
-            _TIFFfree( line16 );
-        }
-            
-	return (1);
-}
-
-/*
- * Encode a chunk of pixels.
- * Incoming data is expected to be downsampled per sampling factors.
- */
-static int
-JPEGEncodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
-{
-	JPEGState *sp = JState(tif);
-	JSAMPLE* inptr;
-	JSAMPLE* outptr;
-	tmsize_t nrows;
-	JDIMENSION clumps_per_line, nclump;
-	int clumpoffset, ci, xpos, ypos;
-	jpeg_component_info* compptr;
-	int samples_per_clump = sp->samplesperclump;
-	tmsize_t bytesperclumpline;
-
-	(void) s;
-	assert(sp != NULL);
-	/* data is expected to be supplied in multiples of a clumpline */
-	/* a clumpline is equivalent to v_sampling desubsampled scanlines */
-	/* TODO: the following calculation of bytesperclumpline, should substitute calculation of sp->bytesperline, except that it is per v_sampling lines */
-	bytesperclumpline = (((sp->cinfo.c.image_width+sp->h_sampling-1)/sp->h_sampling)
-			     *(sp->h_sampling*sp->v_sampling+2)*sp->cinfo.c.data_precision+7)
-			    /8;
-
-	nrows = ( cc / bytesperclumpline ) * sp->v_sampling;
-	if (cc % bytesperclumpline)
-		TIFFWarningExt(tif->tif_clientdata, tif->tif_name, "fractional scanline discarded");
-
-	/* Cb,Cr both have sampling factors 1, so this is correct */
-	clumps_per_line = sp->cinfo.c.comp_info[1].downsampled_width;
-
-	while (nrows > 0) {
-		/*
-		 * Fastest way to separate the data is to make one pass
-		 * over the scanline for each row of each component.
-		 */
-		clumpoffset = 0;		/* first sample in clump */
-		for (ci = 0, compptr = sp->cinfo.c.comp_info;
-		     ci < sp->cinfo.c.num_components;
-		     ci++, compptr++) {
-		    int hsamp = compptr->h_samp_factor;
-		    int vsamp = compptr->v_samp_factor;
-		    int padding = (int) (compptr->width_in_blocks * DCTSIZE -
-					 clumps_per_line * hsamp);
-		    for (ypos = 0; ypos < vsamp; ypos++) {
-			inptr = ((JSAMPLE*) buf) + clumpoffset;
-			outptr = sp->ds_buffer[ci][sp->scancount*vsamp + ypos];
-			if (hsamp == 1) {
-			    /* fast path for at least Cb and Cr */
-			    for (nclump = clumps_per_line; nclump-- > 0; ) {
-				*outptr++ = inptr[0];
-				inptr += samples_per_clump;
-			    }
-			} else {
-			    /* general case */
-			    for (nclump = clumps_per_line; nclump-- > 0; ) {
-				for (xpos = 0; xpos < hsamp; xpos++)
-				    *outptr++ = inptr[xpos];
-				inptr += samples_per_clump;
-			    }
-			}
-			/* pad each scanline as needed */
-			for (xpos = 0; xpos < padding; xpos++) {
-			    *outptr = outptr[-1];
-			    outptr++;
-			}
-			clumpoffset += hsamp;
-		    }
-		}
-		sp->scancount++;
-		if (sp->scancount >= DCTSIZE) {
-			int n = sp->cinfo.c.max_v_samp_factor * DCTSIZE;
-			if (TIFFjpeg_write_raw_data(sp, sp->ds_buffer, n) != n)
-				return (0);
-			sp->scancount = 0;
-		}
-		tif->tif_row += sp->v_sampling;
-		buf += bytesperclumpline;
-		nrows -= sp->v_sampling;
-	}
-	return (1);
-}
-
-/*
- * Finish up at the end of a strip or tile.
- */
-static int
-JPEGPostEncode(TIFF* tif)
-{
-	JPEGState *sp = JState(tif);
-
-	if (sp->scancount > 0) {
-		/*
-		 * Need to emit a partial bufferload of downsampled data.
-		 * Pad the data vertically.
-		 */
-		int ci, ypos, n;
-		jpeg_component_info* compptr;
-
-		for (ci = 0, compptr = sp->cinfo.c.comp_info;
-		     ci < sp->cinfo.c.num_components;
-		     ci++, compptr++) {
-			int vsamp = compptr->v_samp_factor;
-			tmsize_t row_width = compptr->width_in_blocks * DCTSIZE
-				* sizeof(JSAMPLE);
-			for (ypos = sp->scancount * vsamp;
-			     ypos < DCTSIZE * vsamp; ypos++) {
-				_TIFFmemcpy((void*)sp->ds_buffer[ci][ypos],
-					    (void*)sp->ds_buffer[ci][ypos-1],
-					    row_width);
-
-			}
-		}
-		n = sp->cinfo.c.max_v_samp_factor * DCTSIZE;
-		if (TIFFjpeg_write_raw_data(sp, sp->ds_buffer, n) != n)
-			return (0);
-	}
-
-	return (TIFFjpeg_finish_compress(JState(tif)));
-}
-
-static void
-JPEGCleanup(TIFF* tif)
-{
-	JPEGState *sp = JState(tif);
-	
-	assert(sp != 0);
-
-	tif->tif_tagmethods.vgetfield = sp->vgetparent;
-	tif->tif_tagmethods.vsetfield = sp->vsetparent;
-	tif->tif_tagmethods.printdir = sp->printdir;
-
-	if( sp != NULL ) {
-		if( sp->cinfo_initialized )
-		    TIFFjpeg_destroy(sp);	/* release libjpeg resources */
-		if (sp->jpegtables)		/* tag value */
-			_TIFFfree(sp->jpegtables);
-	}
-	_TIFFfree(tif->tif_data);	/* release local state */
-	tif->tif_data = NULL;
-
-	_TIFFSetDefaultCompressionState(tif);
-}
-
-static void 
-JPEGResetUpsampled( TIFF* tif )
-{
-	JPEGState* sp = JState(tif);
-	TIFFDirectory* td = &tif->tif_dir;
-
-	/*
-	 * Mark whether returned data is up-sampled or not so TIFFStripSize
-	 * and TIFFTileSize return values that reflect the true amount of
-	 * data.
-	 */
-	tif->tif_flags &= ~TIFF_UPSAMPLED;
-	if (td->td_planarconfig == PLANARCONFIG_CONTIG) {
-		if (td->td_photometric == PHOTOMETRIC_YCBCR &&
-		    sp->jpegcolormode == JPEGCOLORMODE_RGB) {
-			tif->tif_flags |= TIFF_UPSAMPLED;
-		} else {
-#ifdef notdef
-			if (td->td_ycbcrsubsampling[0] != 1 ||
-			    td->td_ycbcrsubsampling[1] != 1)
-				; /* XXX what about up-sampling? */
-#endif
-		}
-	}
-
-	/*
-	 * Must recalculate cached tile size in case sampling state changed.
-	 * Should we really be doing this now if image size isn't set? 
-	 */
-        if( tif->tif_tilesize > 0 )
-            tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)(-1);   
-        if( tif->tif_scanlinesize > 0 )
-            tif->tif_scanlinesize = TIFFScanlineSize(tif); 
-}
-
-static int
-JPEGVSetField(TIFF* tif, uint32 tag, va_list ap)
-{
-	JPEGState* sp = JState(tif);
-	const TIFFField* fip;
-	uint32 v32;
-
-	assert(sp != NULL);
-
-	switch (tag) {
-	case TIFFTAG_JPEGTABLES:
-		v32 = (uint32) va_arg(ap, uint32);
-		if (v32 == 0) {
-			/* XXX */
-			return (0);
-		}
-		_TIFFsetByteArray(&sp->jpegtables, va_arg(ap, void*),
-		    (long) v32);
-		sp->jpegtables_length = v32;
-		TIFFSetFieldBit(tif, FIELD_JPEGTABLES);
-		break;
-	case TIFFTAG_JPEGQUALITY:
-		sp->jpegquality = (int) va_arg(ap, int);
-		return (1);			/* pseudo tag */
-	case TIFFTAG_JPEGCOLORMODE:
-		sp->jpegcolormode = (int) va_arg(ap, int);
-		JPEGResetUpsampled( tif );
-		return (1);			/* pseudo tag */
-	case TIFFTAG_PHOTOMETRIC:
-	{
-		int ret_value = (*sp->vsetparent)(tif, tag, ap);
-		JPEGResetUpsampled( tif );
-		return ret_value;
-	}
-	case TIFFTAG_JPEGTABLESMODE:
-		sp->jpegtablesmode = (int) va_arg(ap, int);
-		return (1);			/* pseudo tag */
-	case TIFFTAG_YCBCRSUBSAMPLING:
-		/* mark the fact that we have a real ycbcrsubsampling! */
-		sp->ycbcrsampling_fetched = 1;
-		/* should we be recomputing upsampling info here? */
-		return (*sp->vsetparent)(tif, tag, ap);
-	default:
-		return (*sp->vsetparent)(tif, tag, ap);
-	}
-
-	if ((fip = TIFFFieldWithTag(tif, tag))) {
-		TIFFSetFieldBit(tif, fip->field_bit);
-	} else {
-		return (0);
-	}
-
-	tif->tif_flags |= TIFF_DIRTYDIRECT;
-	return (1);
-}
-
-static int
-JPEGVGetField(TIFF* tif, uint32 tag, va_list ap)
-{
-	JPEGState* sp = JState(tif);
-
-	assert(sp != NULL);
-
-	switch (tag) {
-		case TIFFTAG_JPEGTABLES:
-			*va_arg(ap, uint32*) = sp->jpegtables_length;
-			*va_arg(ap, void**) = sp->jpegtables;
-			break;
-		case TIFFTAG_JPEGQUALITY:
-			*va_arg(ap, int*) = sp->jpegquality;
-			break;
-		case TIFFTAG_JPEGCOLORMODE:
-			*va_arg(ap, int*) = sp->jpegcolormode;
-			break;
-		case TIFFTAG_JPEGTABLESMODE:
-			*va_arg(ap, int*) = sp->jpegtablesmode;
-			break;
-		default:
-			return (*sp->vgetparent)(tif, tag, ap);
-	}
-	return (1);
-}
-
-static void
-JPEGPrintDir(TIFF* tif, FILE* fd, long flags)
-{
-	JPEGState* sp = JState(tif);
-
-	assert(sp != NULL);
-	(void) flags;
-
-        if( sp != NULL ) {
-		if (TIFFFieldSet(tif,FIELD_JPEGTABLES))
-			fprintf(fd, "  JPEG Tables: (%lu bytes)\n",
-				(unsigned long) sp->jpegtables_length);
-		if (sp->printdir)
-			(*sp->printdir)(tif, fd, flags);
-	}
-}
-
-static uint32
-JPEGDefaultStripSize(TIFF* tif, uint32 s)
-{
-	JPEGState* sp = JState(tif);
-	TIFFDirectory *td = &tif->tif_dir;
-
-	s = (*sp->defsparent)(tif, s);
-	if (s < td->td_imagelength)
-		s = TIFFroundup_32(s, td->td_ycbcrsubsampling[1] * DCTSIZE);
-	return (s);
-}
-
-static void
-JPEGDefaultTileSize(TIFF* tif, uint32* tw, uint32* th)
-{
-	JPEGState* sp = JState(tif);
-	TIFFDirectory *td = &tif->tif_dir;
-
-	(*sp->deftparent)(tif, tw, th);
-	*tw = TIFFroundup_32(*tw, td->td_ycbcrsubsampling[0] * DCTSIZE);
-	*th = TIFFroundup_32(*th, td->td_ycbcrsubsampling[1] * DCTSIZE);
-}
-
-/*
- * The JPEG library initialized used to be done in TIFFInitJPEG(), but
- * now that we allow a TIFF file to be opened in update mode it is necessary
- * to have some way of deciding whether compression or decompression is
- * desired other than looking at tif->tif_mode.  We accomplish this by 
- * examining {TILE/STRIP}BYTECOUNTS to see if there is a non-zero entry.
- * If so, we assume decompression is desired. 
- *
- * This is tricky, because TIFFInitJPEG() is called while the directory is
- * being read, and generally speaking the BYTECOUNTS tag won't have been read
- * at that point.  So we try to defer jpeg library initialization till we
- * do have that tag ... basically any access that might require the compressor
- * or decompressor that occurs after the reading of the directory. 
- *
- * In an ideal world compressors or decompressors would be setup
- * at the point where a single tile or strip was accessed (for read or write)
- * so that stuff like update of missing tiles, or replacement of tiles could
- * be done. However, we aren't trying to crack that nut just yet ...
- *
- * NFW, Feb 3rd, 2003.
- */
-
-static int JPEGInitializeLibJPEG( TIFF * tif, int decompress )
-{
-    JPEGState* sp = JState(tif);
-
-    if(sp->cinfo_initialized)
-    {
-        if( !decompress && sp->cinfo.comm.is_decompressor )
-            TIFFjpeg_destroy( sp );
-        else if( decompress && !sp->cinfo.comm.is_decompressor )
-            TIFFjpeg_destroy( sp );
-        else
-            return 1;
-
-        sp->cinfo_initialized = 0;
-    }
-
-    /*
-     * Initialize libjpeg.
-     */
-    if ( decompress ) {
-        if (!TIFFjpeg_create_decompress(sp))
-            return (0);
-    } else {
-        if (!TIFFjpeg_create_compress(sp))
-            return (0);
-    }
-
-    sp->cinfo_initialized = TRUE;
-
-    return 1;
-}
-
-int
-TIFFInitJPEG(TIFF* tif, int scheme)
-{
-	JPEGState* sp;
-
-	assert(scheme == COMPRESSION_JPEG);
-
-	/*
-	 * Merge codec-specific tag information.
-	 */
-	if (!_TIFFMergeFields(tif, jpegFields, TIFFArrayCount(jpegFields))) {
-		TIFFErrorExt(tif->tif_clientdata,
-			     "TIFFInitJPEG",
-			     "Merging JPEG codec-specific tags failed");
-		return 0;
-	}
-
-	/*
-	 * Allocate state block so tag methods have storage to record values.
-	 */
-	tif->tif_data = (uint8*) _TIFFmalloc(sizeof (JPEGState));
-
-	if (tif->tif_data == NULL) {
-		TIFFErrorExt(tif->tif_clientdata,
-			     "TIFFInitJPEG", "No space for JPEG state block");
-		return 0;
-	}
-        _TIFFmemset(tif->tif_data, 0, sizeof(JPEGState));
-
-	sp = JState(tif);
-	sp->tif = tif;				/* back link */
-
-	/*
-	 * Override parent get/set field methods.
-	 */
-	sp->vgetparent = tif->tif_tagmethods.vgetfield;
-	tif->tif_tagmethods.vgetfield = JPEGVGetField; /* hook for codec tags */
-	sp->vsetparent = tif->tif_tagmethods.vsetfield;
-	tif->tif_tagmethods.vsetfield = JPEGVSetField; /* hook for codec tags */
-	sp->printdir = tif->tif_tagmethods.printdir;
-	tif->tif_tagmethods.printdir = JPEGPrintDir;   /* hook for codec tags */
-
-	/* Default values for codec-specific fields */
-	sp->jpegtables = NULL;
-	sp->jpegtables_length = 0;
-	sp->jpegquality = 75;			/* Default IJG quality */
-	sp->jpegcolormode = JPEGCOLORMODE_RAW;
-	sp->jpegtablesmode = JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF;
-        sp->ycbcrsampling_fetched = 0;
-
-	/*
-	 * Install codec methods.
-	 */
-	tif->tif_fixuptags = JPEGFixupTags;
-	tif->tif_setupdecode = JPEGSetupDecode;
-	tif->tif_predecode = JPEGPreDecode;
-	tif->tif_decoderow = JPEGDecode;
-	tif->tif_decodestrip = JPEGDecode;
-	tif->tif_decodetile = JPEGDecode;
-	tif->tif_setupencode = JPEGSetupEncode;
-	tif->tif_preencode = JPEGPreEncode;
-	tif->tif_postencode = JPEGPostEncode;
-	tif->tif_encoderow = JPEGEncode;
-	tif->tif_encodestrip = JPEGEncode;
-	tif->tif_encodetile = JPEGEncode;  
-	tif->tif_cleanup = JPEGCleanup;
-	sp->defsparent = tif->tif_defstripsize;
-	tif->tif_defstripsize = JPEGDefaultStripSize;
-	sp->deftparent = tif->tif_deftilesize;
-	tif->tif_deftilesize = JPEGDefaultTileSize;
-	tif->tif_flags |= TIFF_NOBITREV;	/* no bit reversal, please */
-
-        sp->cinfo_initialized = FALSE;
-
-	/*
-        ** Create a JPEGTables field if no directory has yet been created. 
-        ** We do this just to ensure that sufficient space is reserved for
-        ** the JPEGTables field.  It will be properly created the right
-        ** size later. 
-        */
-        if( tif->tif_diroff == 0 )
-        {
-#define SIZE_OF_JPEGTABLES 2000
-/*
-The following line assumes incorrectly that all JPEG-in-TIFF files will have
-a JPEGTABLES tag generated and causes null-filled JPEGTABLES tags to be written
-when the JPEG data is placed with TIFFWriteRawStrip.  The field bit should be 
-set, anyway, later when actual JPEGTABLES header is generated, so removing it 
-here hopefully is harmless.
-            TIFFSetFieldBit(tif, FIELD_JPEGTABLES);
-*/
-            sp->jpegtables_length = SIZE_OF_JPEGTABLES;
-            sp->jpegtables = (void *) _TIFFmalloc(sp->jpegtables_length);
-	    // FIXME: NULL-deref after malloc failure
-	    _TIFFmemset(sp->jpegtables, 0, SIZE_OF_JPEGTABLES);
-#undef SIZE_OF_JPEGTABLES
-        }
-
-	return 1;
-}
-#endif /* JPEG_SUPPORT */
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Id: tif_jpeg.c,v 1.11 2015/02/19 22:39:58 drolon Exp $ */
+
+/*
+ * Copyright (c) 1994-1997 Sam Leffler
+ * Copyright (c) 1994-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and 
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
+ * 
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
+ * OF THIS SOFTWARE.
+ */
+
+#define WIN32_LEAN_AND_MEAN
+#define VC_EXTRALEAN
+
+#include "tiffiop.h"
+#ifdef JPEG_SUPPORT
+
+/*
+ * TIFF Library
+ *
+ * JPEG Compression support per TIFF Technical Note #2
+ * (*not* per the original TIFF 6.0 spec).
+ *
+ * This file is simply an interface to the libjpeg library written by
+ * the Independent JPEG Group.  You need release 5 or later of the IJG
+ * code, which you can find on the Internet at ftp.uu.net:/graphics/jpeg/.
+ *
+ * Contributed by Tom Lane <tgl at sss.pgh.pa.us>.
+ */
+#include <setjmp.h>
+
+int TIFFFillStrip(TIFF* tif, uint32 strip);
+int TIFFFillTile(TIFF* tif, uint32 tile);
+int TIFFReInitJPEG_12( TIFF *tif, int scheme, int is_encode );
+
+/* We undefine FAR to avoid conflict with JPEG definition */
+
+#ifdef FAR
+#undef FAR
+#endif
+
+/*
+  Libjpeg's jmorecfg.h defines INT16 and INT32, but only if XMD_H is
+  not defined.  Unfortunately, the MinGW and Borland compilers include
+  a typedef for INT32, which causes a conflict.  MSVC does not include
+  a conficting typedef given the headers which are included.
+*/
+#if defined(__BORLANDC__) || defined(__MINGW32__)
+# define XMD_H 1
+#endif
+
+/*
+   The windows RPCNDR.H file defines boolean, but defines it with the
+   unsigned char size.  You should compile JPEG library using appropriate
+   definitions in jconfig.h header, but many users compile library in wrong
+   way. That causes errors of the following type:
+
+   "JPEGLib: JPEG parameter struct mismatch: library thinks size is 432,
+   caller expects 464"
+
+   For such users we wil fix the problem here. See install.doc file from
+   the JPEG library distribution for details.
+*/
+
+/* Define "boolean" as unsigned char, not int, per Windows custom. */
+#if defined(__WIN32__) && !defined(__MINGW32__)
+# ifndef __RPCNDR_H__            /* don't conflict if rpcndr.h already read */
+   typedef unsigned char boolean;
+# endif
+# define HAVE_BOOLEAN            /* prevent jmorecfg.h from redefining it */
+#endif
+
+#include "../LibJPEG/jpeglib.h"
+#include "../LibJPEG/jerror.h"
+
+/* 
+ * Do we want to do special processing suitable for when JSAMPLE is a
+ * 16bit value?  
+ */
+
+#if defined(JPEG_LIB_MK1)
+#  define JPEG_LIB_MK1_OR_12BIT 1
+#elif BITS_IN_JSAMPLE == 12
+#  define JPEG_LIB_MK1_OR_12BIT 1
+#endif
+
+/*
+ * We are using width_in_blocks which is supposed to be private to
+ * libjpeg. Unfortunately, the libjpeg delivered with Cygwin has
+ * renamed this member to width_in_data_units.  Since the header has
+ * also renamed a define, use that unique define name in order to
+ * detect the problem header and adjust to suit.
+ */
+#if defined(D_MAX_DATA_UNITS_IN_MCU)
+#define width_in_blocks width_in_data_units
+#endif
+
+/*
+ * On some machines it may be worthwhile to use _setjmp or sigsetjmp
+ * in place of plain setjmp.  These macros will make it easier.
+ */
+#define SETJMP(jbuf)		setjmp(jbuf)
+#define LONGJMP(jbuf,code)	longjmp(jbuf,code)
+#define JMP_BUF			jmp_buf
+
+typedef struct jpeg_destination_mgr jpeg_destination_mgr;
+typedef struct jpeg_source_mgr jpeg_source_mgr;
+typedef struct jpeg_error_mgr jpeg_error_mgr;
+
+/*
+ * State block for each open TIFF file using
+ * libjpeg to do JPEG compression/decompression.
+ *
+ * libjpeg's visible state is either a jpeg_compress_struct
+ * or jpeg_decompress_struct depending on which way we
+ * are going.  comm can be used to refer to the fields
+ * which are common to both.
+ *
+ * NB: cinfo is required to be the first member of JPEGState,
+ *     so we can safely cast JPEGState* -> jpeg_xxx_struct*
+ *     and vice versa!
+ */
+typedef struct {
+	union {
+		struct jpeg_compress_struct c;
+		struct jpeg_decompress_struct d;
+		struct jpeg_common_struct comm;
+	} cinfo;			/* NB: must be first */
+	int             cinfo_initialized;
+
+	jpeg_error_mgr	err;		/* libjpeg error manager */
+	JMP_BUF		exit_jmpbuf;	/* for catching libjpeg failures */
+	/*
+	 * The following two members could be a union, but
+	 * they're small enough that it's not worth the effort.
+	 */
+	jpeg_destination_mgr dest;	/* data dest for compression */
+	jpeg_source_mgr	src;		/* data source for decompression */
+					/* private state */
+	TIFF*		tif;		/* back link needed by some code */
+	uint16		photometric;	/* copy of PhotometricInterpretation */
+	uint16		h_sampling;	/* luminance sampling factors */
+	uint16		v_sampling;
+	tmsize_t   	bytesperline;	/* decompressed bytes per scanline */
+	/* pointers to intermediate buffers when processing downsampled data */
+	JSAMPARRAY	ds_buffer[MAX_COMPONENTS];
+	int		scancount;	/* number of "scanlines" accumulated */
+	int		samplesperclump;
+
+	TIFFVGetMethod	vgetparent;	/* super-class method */
+	TIFFVSetMethod	vsetparent;	/* super-class method */
+	TIFFPrintMethod printdir;	/* super-class method */
+	TIFFStripMethod	defsparent;	/* super-class method */
+	TIFFTileMethod	deftparent;	/* super-class method */
+					/* pseudo-tag fields */
+	void*		jpegtables;	/* JPEGTables tag value, or NULL */
+	uint32		jpegtables_length; /* number of bytes in same */
+	int		jpegquality;	/* Compression quality level */
+	int		jpegcolormode;	/* Auto RGB<=>YCbCr convert? */
+	int		jpegtablesmode;	/* What to put in JPEGTables */
+
+        int             ycbcrsampling_fetched;
+} JPEGState;
+
+#define	JState(tif)	((JPEGState*)(tif)->tif_data)
+
+static int JPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s);
+static int JPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s);
+static int JPEGEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s);
+static int JPEGEncodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s);
+static int JPEGInitializeLibJPEG(TIFF * tif, int decode );
+static int DecodeRowError(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s);
+
+#define	FIELD_JPEGTABLES	(FIELD_CODEC+0)
+
+static const TIFFField jpegFields[] = {
+    { TIFFTAG_JPEGTABLES, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_C32_UINT8, FIELD_JPEGTABLES, FALSE, TRUE, "JPEGTables", NULL },
+    { TIFFTAG_JPEGQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL },
+    { TIFFTAG_JPEGCOLORMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL },
+    { TIFFTAG_JPEGTABLESMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL }
+};
+
+/*
+ * libjpeg interface layer.
+ *
+ * We use setjmp/longjmp to return control to libtiff
+ * when a fatal error is encountered within the JPEG
+ * library.  We also direct libjpeg error and warning
+ * messages through the appropriate libtiff handlers.
+ */
+
+/*
+ * Error handling routines (these replace corresponding
+ * IJG routines from jerror.c).  These are used for both
+ * compression and decompression.
+ */
+static void
+TIFFjpeg_error_exit(j_common_ptr cinfo)
+{
+	JPEGState *sp = (JPEGState *) cinfo;	/* NB: cinfo assumed first */
+	char buffer[JMSG_LENGTH_MAX];
+
+	(*cinfo->err->format_message) (cinfo, buffer);
+	TIFFErrorExt(sp->tif->tif_clientdata, "JPEGLib", "%s", buffer);		/* display the error message */
+	jpeg_abort(cinfo);			/* clean up libjpeg state */
+	LONGJMP(sp->exit_jmpbuf, 1);		/* return to libtiff caller */
+}
+
+/*
+ * This routine is invoked only for warning messages,
+ * since error_exit does its own thing and trace_level
+ * is never set > 0.
+ */
+static void
+TIFFjpeg_output_message(j_common_ptr cinfo)
+{
+	char buffer[JMSG_LENGTH_MAX];
+
+	(*cinfo->err->format_message) (cinfo, buffer);
+	TIFFWarningExt(((JPEGState *) cinfo)->tif->tif_clientdata, "JPEGLib", "%s", buffer);
+}
+
+/*
+ * Interface routines.  This layer of routines exists
+ * primarily to limit side-effects from using setjmp.
+ * Also, normal/error returns are converted into return
+ * values per libtiff practice.
+ */
+#define	CALLJPEG(sp, fail, op)	(SETJMP((sp)->exit_jmpbuf) ? (fail) : (op))
+#define	CALLVJPEG(sp, op)	CALLJPEG(sp, 0, ((op),1))
+
+static int
+TIFFjpeg_create_compress(JPEGState* sp)
+{
+	/* initialize JPEG error handling */
+	sp->cinfo.c.err = jpeg_std_error(&sp->err);
+	sp->err.error_exit = TIFFjpeg_error_exit;
+	sp->err.output_message = TIFFjpeg_output_message;
+
+	return CALLVJPEG(sp, jpeg_create_compress(&sp->cinfo.c));
+}
+
+static int
+TIFFjpeg_create_decompress(JPEGState* sp)
+{
+	/* initialize JPEG error handling */
+	sp->cinfo.d.err = jpeg_std_error(&sp->err);
+	sp->err.error_exit = TIFFjpeg_error_exit;
+	sp->err.output_message = TIFFjpeg_output_message;
+
+	return CALLVJPEG(sp, jpeg_create_decompress(&sp->cinfo.d));
+}
+
+static int
+TIFFjpeg_set_defaults(JPEGState* sp)
+{
+	return CALLVJPEG(sp, jpeg_set_defaults(&sp->cinfo.c));
+}
+
+static int
+TIFFjpeg_set_colorspace(JPEGState* sp, J_COLOR_SPACE colorspace)
+{
+	return CALLVJPEG(sp, jpeg_set_colorspace(&sp->cinfo.c, colorspace));
+}
+
+static int
+TIFFjpeg_set_quality(JPEGState* sp, int quality, boolean force_baseline)
+{
+	return CALLVJPEG(sp,
+	    jpeg_set_quality(&sp->cinfo.c, quality, force_baseline));
+}
+
+static int
+TIFFjpeg_suppress_tables(JPEGState* sp, boolean suppress)
+{
+	return CALLVJPEG(sp, jpeg_suppress_tables(&sp->cinfo.c, suppress));
+}
+
+static int
+TIFFjpeg_start_compress(JPEGState* sp, boolean write_all_tables)
+{
+	return CALLVJPEG(sp,
+	    jpeg_start_compress(&sp->cinfo.c, write_all_tables));
+}
+
+static int
+TIFFjpeg_write_scanlines(JPEGState* sp, JSAMPARRAY scanlines, int num_lines)
+{
+	return CALLJPEG(sp, -1, (int) jpeg_write_scanlines(&sp->cinfo.c,
+	    scanlines, (JDIMENSION) num_lines));
+}
+
+static int
+TIFFjpeg_write_raw_data(JPEGState* sp, JSAMPIMAGE data, int num_lines)
+{
+	return CALLJPEG(sp, -1, (int) jpeg_write_raw_data(&sp->cinfo.c,
+	    data, (JDIMENSION) num_lines));
+}
+
+static int
+TIFFjpeg_finish_compress(JPEGState* sp)
+{
+	return CALLVJPEG(sp, jpeg_finish_compress(&sp->cinfo.c));
+}
+
+static int
+TIFFjpeg_write_tables(JPEGState* sp)
+{
+	return CALLVJPEG(sp, jpeg_write_tables(&sp->cinfo.c));
+}
+
+static int
+TIFFjpeg_read_header(JPEGState* sp, boolean require_image)
+{
+	return CALLJPEG(sp, -1, jpeg_read_header(&sp->cinfo.d, require_image));
+}
+
+static int
+TIFFjpeg_start_decompress(JPEGState* sp)
+{
+	return CALLVJPEG(sp, jpeg_start_decompress(&sp->cinfo.d));
+}
+
+static int
+TIFFjpeg_read_scanlines(JPEGState* sp, JSAMPARRAY scanlines, int max_lines)
+{
+	return CALLJPEG(sp, -1, (int) jpeg_read_scanlines(&sp->cinfo.d,
+	    scanlines, (JDIMENSION) max_lines));
+}
+
+static int
+TIFFjpeg_read_raw_data(JPEGState* sp, JSAMPIMAGE data, int max_lines)
+{
+	return CALLJPEG(sp, -1, (int) jpeg_read_raw_data(&sp->cinfo.d,
+	    data, (JDIMENSION) max_lines));
+}
+
+static int
+TIFFjpeg_finish_decompress(JPEGState* sp)
+{
+	return CALLJPEG(sp, -1, (int) jpeg_finish_decompress(&sp->cinfo.d));
+}
+
+static int
+TIFFjpeg_abort(JPEGState* sp)
+{
+	return CALLVJPEG(sp, jpeg_abort(&sp->cinfo.comm));
+}
+
+static int
+TIFFjpeg_destroy(JPEGState* sp)
+{
+	return CALLVJPEG(sp, jpeg_destroy(&sp->cinfo.comm));
+}
+
+static JSAMPARRAY
+TIFFjpeg_alloc_sarray(JPEGState* sp, int pool_id,
+		      JDIMENSION samplesperrow, JDIMENSION numrows)
+{
+	return CALLJPEG(sp, (JSAMPARRAY) NULL,
+	    (*sp->cinfo.comm.mem->alloc_sarray)
+		(&sp->cinfo.comm, pool_id, samplesperrow, numrows));
+}
+
+/*
+ * JPEG library destination data manager.
+ * These routines direct compressed data from libjpeg into the
+ * libtiff output buffer.
+ */
+
+static void
+std_init_destination(j_compress_ptr cinfo)
+{
+	JPEGState* sp = (JPEGState*) cinfo;
+	TIFF* tif = sp->tif;
+
+	sp->dest.next_output_byte = (JOCTET*) tif->tif_rawdata;
+	sp->dest.free_in_buffer = (size_t) tif->tif_rawdatasize;
+}
+
+static boolean
+std_empty_output_buffer(j_compress_ptr cinfo)
+{
+	JPEGState* sp = (JPEGState*) cinfo;
+	TIFF* tif = sp->tif;
+
+	/* the entire buffer has been filled */
+	tif->tif_rawcc = tif->tif_rawdatasize;
+
+#ifdef IPPJ_HUFF
+       /*
+        * The Intel IPP performance library does not necessarily fill up
+        * the whole output buffer on each pass, so only dump out the parts
+        * that have been filled.
+        *   http://trac.osgeo.org/gdal/wiki/JpegIPP
+        */
+       if ( sp->dest.free_in_buffer >= 0 ) {
+               tif->tif_rawcc = tif->tif_rawdatasize - sp->dest.free_in_buffer;
+       }
+#endif
+
+	TIFFFlushData1(tif);
+	sp->dest.next_output_byte = (JOCTET*) tif->tif_rawdata;
+	sp->dest.free_in_buffer = (size_t) tif->tif_rawdatasize;
+
+	return (TRUE);
+}
+
+static void
+std_term_destination(j_compress_ptr cinfo)
+{
+	JPEGState* sp = (JPEGState*) cinfo;
+	TIFF* tif = sp->tif;
+
+	tif->tif_rawcp = (uint8*) sp->dest.next_output_byte;
+	tif->tif_rawcc =
+	    tif->tif_rawdatasize - (tmsize_t) sp->dest.free_in_buffer;
+	/* NB: libtiff does the final buffer flush */
+}
+
+static void
+TIFFjpeg_data_dest(JPEGState* sp, TIFF* tif)
+{
+	(void) tif;
+	sp->cinfo.c.dest = &sp->dest;
+	sp->dest.init_destination = std_init_destination;
+	sp->dest.empty_output_buffer = std_empty_output_buffer;
+	sp->dest.term_destination = std_term_destination;
+}
+
+/*
+ * Alternate destination manager for outputting to JPEGTables field.
+ */
+
+static void
+tables_init_destination(j_compress_ptr cinfo)
+{
+	JPEGState* sp = (JPEGState*) cinfo;
+
+	/* while building, jpegtables_length is allocated buffer size */
+	sp->dest.next_output_byte = (JOCTET*) sp->jpegtables;
+	sp->dest.free_in_buffer = (size_t) sp->jpegtables_length;
+}
+
+static boolean
+tables_empty_output_buffer(j_compress_ptr cinfo)
+{
+	JPEGState* sp = (JPEGState*) cinfo;
+	void* newbuf;
+
+	/* the entire buffer has been filled; enlarge it by 1000 bytes */
+	newbuf = _TIFFrealloc((void*) sp->jpegtables,
+			      (tmsize_t) (sp->jpegtables_length + 1000));
+	if (newbuf == NULL)
+		ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 100);
+	sp->dest.next_output_byte = (JOCTET*) newbuf + sp->jpegtables_length;
+	sp->dest.free_in_buffer = (size_t) 1000;
+	sp->jpegtables = newbuf;
+	sp->jpegtables_length += 1000;
+	return (TRUE);
+}
+
+static void
+tables_term_destination(j_compress_ptr cinfo)
+{
+	JPEGState* sp = (JPEGState*) cinfo;
+
+	/* set tables length to number of bytes actually emitted */
+	sp->jpegtables_length -= (uint32) sp->dest.free_in_buffer;
+}
+
+static int
+TIFFjpeg_tables_dest(JPEGState* sp, TIFF* tif)
+{
+	(void) tif;
+	/*
+	 * Allocate a working buffer for building tables.
+	 * Initial size is 1000 bytes, which is usually adequate.
+	 */
+	if (sp->jpegtables)
+		_TIFFfree(sp->jpegtables);
+	sp->jpegtables_length = 1000;
+	sp->jpegtables = (void*) _TIFFmalloc((tmsize_t) sp->jpegtables_length);
+	if (sp->jpegtables == NULL) {
+		sp->jpegtables_length = 0;
+		TIFFErrorExt(sp->tif->tif_clientdata, "TIFFjpeg_tables_dest", "No space for JPEGTables");
+		return (0);
+	}
+	sp->cinfo.c.dest = &sp->dest;
+	sp->dest.init_destination = tables_init_destination;
+	sp->dest.empty_output_buffer = tables_empty_output_buffer;
+	sp->dest.term_destination = tables_term_destination;
+	return (1);
+}
+
+/*
+ * JPEG library source data manager.
+ * These routines supply compressed data to libjpeg.
+ */
+
+static void
+std_init_source(j_decompress_ptr cinfo)
+{
+	JPEGState* sp = (JPEGState*) cinfo;
+	TIFF* tif = sp->tif;
+
+	sp->src.next_input_byte = (const JOCTET*) tif->tif_rawdata;
+	sp->src.bytes_in_buffer = (size_t) tif->tif_rawcc;
+}
+
+static boolean
+std_fill_input_buffer(j_decompress_ptr cinfo)
+{
+	JPEGState* sp = (JPEGState* ) cinfo;
+	static const JOCTET dummy_EOI[2] = { 0xFF, JPEG_EOI };
+
+#ifdef IPPJ_HUFF
+        /*
+         * The Intel IPP performance library does not necessarily read the whole
+         * input buffer in one pass, so it is possible to get here with data
+         * yet to read. 
+         * 
+         * We just return without doing anything, until the entire buffer has
+         * been read.  
+         * http://trac.osgeo.org/gdal/wiki/JpegIPP
+         */
+        if( sp->src.bytes_in_buffer > 0 ) {
+            return (TRUE);
+        }
+#endif
+
+	/*
+         * Normally the whole strip/tile is read and so we don't need to do
+         * a fill.  In the case of CHUNKY_STRIP_READ_SUPPORT we might not have
+         * all the data, but the rawdata is refreshed between scanlines and
+         * we push this into the io machinery in JPEGDecode(). 	 
+         * http://trac.osgeo.org/gdal/ticket/3894
+	 */
+        
+	WARNMS(cinfo, JWRN_JPEG_EOF);
+	/* insert a fake EOI marker */
+	sp->src.next_input_byte = dummy_EOI;
+	sp->src.bytes_in_buffer = 2;
+	return (TRUE);
+}
+
+static void
+std_skip_input_data(j_decompress_ptr cinfo, long num_bytes)
+{
+	JPEGState* sp = (JPEGState*) cinfo;
+
+	if (num_bytes > 0) {
+		if ((size_t)num_bytes > sp->src.bytes_in_buffer) {
+			/* oops, buffer overrun */
+			(void) std_fill_input_buffer(cinfo);
+		} else {
+			sp->src.next_input_byte += (size_t) num_bytes;
+			sp->src.bytes_in_buffer -= (size_t) num_bytes;
+		}
+	}
+}
+
+static void
+std_term_source(j_decompress_ptr cinfo)
+{
+	/* No work necessary here */
+	(void) cinfo;
+}
+
+static void
+TIFFjpeg_data_src(JPEGState* sp, TIFF* tif)
+{
+	(void) tif;
+	sp->cinfo.d.src = &sp->src;
+	sp->src.init_source = std_init_source;
+	sp->src.fill_input_buffer = std_fill_input_buffer;
+	sp->src.skip_input_data = std_skip_input_data;
+	sp->src.resync_to_restart = jpeg_resync_to_restart;
+	sp->src.term_source = std_term_source;
+	sp->src.bytes_in_buffer = 0;		/* for safety */
+	sp->src.next_input_byte = NULL;
+}
+
+/*
+ * Alternate source manager for reading from JPEGTables.
+ * We can share all the code except for the init routine.
+ */
+
+static void
+tables_init_source(j_decompress_ptr cinfo)
+{
+	JPEGState* sp = (JPEGState*) cinfo;
+
+	sp->src.next_input_byte = (const JOCTET*) sp->jpegtables;
+	sp->src.bytes_in_buffer = (size_t) sp->jpegtables_length;
+}
+
+static void
+TIFFjpeg_tables_src(JPEGState* sp, TIFF* tif)
+{
+	TIFFjpeg_data_src(sp, tif);
+	sp->src.init_source = tables_init_source;
+}
+
+/*
+ * Allocate downsampled-data buffers needed for downsampled I/O.
+ * We use values computed in jpeg_start_compress or jpeg_start_decompress.
+ * We use libjpeg's allocator so that buffers will be released automatically
+ * when done with strip/tile.
+ * This is also a handy place to compute samplesperclump, bytesperline.
+ */
+static int
+alloc_downsampled_buffers(TIFF* tif, jpeg_component_info* comp_info,
+			  int num_components)
+{
+	JPEGState* sp = JState(tif);
+	int ci;
+	jpeg_component_info* compptr;
+	JSAMPARRAY buf;
+	int samples_per_clump = 0;
+
+	for (ci = 0, compptr = comp_info; ci < num_components;
+	     ci++, compptr++) {
+		samples_per_clump += compptr->h_samp_factor *
+			compptr->v_samp_factor;
+		buf = TIFFjpeg_alloc_sarray(sp, JPOOL_IMAGE,
+				compptr->width_in_blocks * DCTSIZE,
+				(JDIMENSION) (compptr->v_samp_factor*DCTSIZE));
+		if (buf == NULL)
+			return (0);
+		sp->ds_buffer[ci] = buf;
+	}
+	sp->samplesperclump = samples_per_clump;
+	return (1);
+}
+
+
+/*
+ * JPEG Decoding.
+ */
+
+#ifdef CHECK_JPEG_YCBCR_SUBSAMPLING
+
+#define JPEG_MARKER_SOF0 0xC0
+#define JPEG_MARKER_SOF1 0xC1
+#define JPEG_MARKER_SOF2 0xC2
+#define JPEG_MARKER_SOF9 0xC9
+#define JPEG_MARKER_SOF10 0xCA
+#define JPEG_MARKER_DHT 0xC4
+#define JPEG_MARKER_SOI 0xD8
+#define JPEG_MARKER_SOS 0xDA
+#define JPEG_MARKER_DQT 0xDB
+#define JPEG_MARKER_DRI 0xDD
+#define JPEG_MARKER_APP0 0xE0
+#define JPEG_MARKER_COM 0xFE
+struct JPEGFixupTagsSubsamplingData
+{
+	TIFF* tif;
+	void* buffer;
+	uint32 buffersize;
+	uint8* buffercurrentbyte;
+	uint32 bufferbytesleft;
+	uint64 fileoffset;
+	uint64 filebytesleft;
+	uint8 filepositioned;
+};
+static void JPEGFixupTagsSubsampling(TIFF* tif);
+static int JPEGFixupTagsSubsamplingSec(struct JPEGFixupTagsSubsamplingData* data);
+static int JPEGFixupTagsSubsamplingReadByte(struct JPEGFixupTagsSubsamplingData* data, uint8* result);
+static int JPEGFixupTagsSubsamplingReadWord(struct JPEGFixupTagsSubsamplingData* data, uint16* result);
+static void JPEGFixupTagsSubsamplingSkip(struct JPEGFixupTagsSubsamplingData* data, uint16 skiplength);
+
+#endif
+
+static int
+JPEGFixupTags(TIFF* tif)
+{
+#ifdef CHECK_JPEG_YCBCR_SUBSAMPLING
+	if ((tif->tif_dir.td_photometric==PHOTOMETRIC_YCBCR)&&
+	    (tif->tif_dir.td_planarconfig==PLANARCONFIG_CONTIG)&&
+	    (tif->tif_dir.td_samplesperpixel==3))
+		JPEGFixupTagsSubsampling(tif);
+#endif
+        
+	return(1);
+}
+
+#ifdef CHECK_JPEG_YCBCR_SUBSAMPLING
+
+static void
+JPEGFixupTagsSubsampling(TIFF* tif)
+{
+	/*
+	 * Some JPEG-in-TIFF produces do not emit the YCBCRSUBSAMPLING values in
+	 * the TIFF tags, but still use non-default (2,2) values within the jpeg
+	 * data stream itself.  In order for TIFF applications to work properly
+	 * - for instance to get the strip buffer size right - it is imperative
+	 * that the subsampling be available before we start reading the image
+	 * data normally.  This function will attempt to analyze the first strip in
+	 * order to get the sampling values from the jpeg data stream.
+	 *
+	 * Note that JPEGPreDeocode() will produce a fairly loud warning when the
+	 * discovered sampling does not match the default sampling (2,2) or whatever
+	 * was actually in the tiff tags.
+	 *
+	 * See the bug in bugzilla for details:
+	 *
+	 * http://bugzilla.remotesensing.org/show_bug.cgi?id=168
+	 *
+	 * Frank Warmerdam, July 2002
+	 * Joris Van Damme, May 2007
+	 */
+	static const char module[] = "JPEGFixupTagsSubsampling";
+	struct JPEGFixupTagsSubsamplingData m;
+
+        _TIFFFillStriles( tif );
+        
+        if( tif->tif_dir.td_stripbytecount == NULL
+            || tif->tif_dir.td_stripoffset == NULL
+            || tif->tif_dir.td_stripbytecount[0] == 0 )
+        {
+            /* Do not even try to check if the first strip/tile does not
+               yet exist, as occurs when GDAL has created a new NULL file
+               for instance. */
+            return;
+        }
+
+	m.tif=tif;
+	m.buffersize=2048;
+	m.buffer=_TIFFmalloc(m.buffersize);
+	if (m.buffer==NULL)
+	{
+		TIFFWarningExt(tif->tif_clientdata,module,
+		    "Unable to allocate memory for auto-correcting of subsampling values; auto-correcting skipped");
+		return;
+	}
+	m.buffercurrentbyte=NULL;
+	m.bufferbytesleft=0;
+	m.fileoffset=tif->tif_dir.td_stripoffset[0];
+	m.filepositioned=0;
+	m.filebytesleft=tif->tif_dir.td_stripbytecount[0];
+	if (!JPEGFixupTagsSubsamplingSec(&m))
+		TIFFWarningExt(tif->tif_clientdata,module,
+		    "Unable to auto-correct subsampling values, likely corrupt JPEG compressed data in first strip/tile; auto-correcting skipped");
+	_TIFFfree(m.buffer);
+}
+
+static int
+JPEGFixupTagsSubsamplingSec(struct JPEGFixupTagsSubsamplingData* data)
+{
+	static const char module[] = "JPEGFixupTagsSubsamplingSec";
+	uint8 m;
+	while (1)
+	{
+		while (1)
+		{
+			if (!JPEGFixupTagsSubsamplingReadByte(data,&m))
+				return(0);
+			if (m==255)
+				break;
+		}
+		while (1)
+		{
+			if (!JPEGFixupTagsSubsamplingReadByte(data,&m))
+				return(0);
+			if (m!=255)
+				break;
+		}
+		switch (m)
+		{
+			case JPEG_MARKER_SOI:
+				/* this type of marker has no data and should be skipped */
+				break;
+			case JPEG_MARKER_COM:
+			case JPEG_MARKER_APP0:
+			case JPEG_MARKER_APP0+1:
+			case JPEG_MARKER_APP0+2:
+			case JPEG_MARKER_APP0+3:
+			case JPEG_MARKER_APP0+4:
+			case JPEG_MARKER_APP0+5:
+			case JPEG_MARKER_APP0+6:
+			case JPEG_MARKER_APP0+7:
+			case JPEG_MARKER_APP0+8:
+			case JPEG_MARKER_APP0+9:
+			case JPEG_MARKER_APP0+10:
+			case JPEG_MARKER_APP0+11:
+			case JPEG_MARKER_APP0+12:
+			case JPEG_MARKER_APP0+13:
+			case JPEG_MARKER_APP0+14:
+			case JPEG_MARKER_APP0+15:
+			case JPEG_MARKER_DQT:
+			case JPEG_MARKER_SOS:
+			case JPEG_MARKER_DHT:
+			case JPEG_MARKER_DRI:
+				/* this type of marker has data, but it has no use to us and should be skipped */
+				{
+					uint16 n;
+					if (!JPEGFixupTagsSubsamplingReadWord(data,&n))
+						return(0);
+					if (n<2)
+						return(0);
+					n-=2;
+					if (n>0)
+						JPEGFixupTagsSubsamplingSkip(data,n);
+				}
+				break;
+			case JPEG_MARKER_SOF0: /* Baseline sequential Huffman */
+			case JPEG_MARKER_SOF1: /* Extended sequential Huffman */
+			case JPEG_MARKER_SOF2: /* Progressive Huffman: normally not allowed by TechNote, but that doesn't hurt supporting it */
+			case JPEG_MARKER_SOF9: /* Extended sequential arithmetic */
+			case JPEG_MARKER_SOF10: /* Progressive arithmetic: normally not allowed by TechNote, but that doesn't hurt supporting it */
+				/* this marker contains the subsampling factors we're scanning for */
+				{
+					uint16 n;
+					uint16 o;
+					uint8 p;
+					uint8 ph,pv;
+					if (!JPEGFixupTagsSubsamplingReadWord(data,&n))
+						return(0);
+					if (n!=8+data->tif->tif_dir.td_samplesperpixel*3)
+						return(0);
+					JPEGFixupTagsSubsamplingSkip(data,7);
+					if (!JPEGFixupTagsSubsamplingReadByte(data,&p))
+						return(0);
+					ph=(p>>4);
+					pv=(p&15);
+					JPEGFixupTagsSubsamplingSkip(data,1);
+					for (o=1; o<data->tif->tif_dir.td_samplesperpixel; o++)
+					{
+						JPEGFixupTagsSubsamplingSkip(data,1);
+						if (!JPEGFixupTagsSubsamplingReadByte(data,&p))
+							return(0);
+						if (p!=0x11)
+						{
+							TIFFWarningExt(data->tif->tif_clientdata,module,
+							    "Subsampling values inside JPEG compressed data have no TIFF equivalent, auto-correction of TIFF subsampling values failed");
+							return(1);
+						}
+						JPEGFixupTagsSubsamplingSkip(data,1);
+					}
+					if (((ph!=1)&&(ph!=2)&&(ph!=4))||((pv!=1)&&(pv!=2)&&(pv!=4)))
+					{
+						TIFFWarningExt(data->tif->tif_clientdata,module,
+						    "Subsampling values inside JPEG compressed data have no TIFF equivalent, auto-correction of TIFF subsampling values failed");
+						return(1);
+					}
+					if ((ph!=data->tif->tif_dir.td_ycbcrsubsampling[0])||(pv!=data->tif->tif_dir.td_ycbcrsubsampling[1]))
+					{
+						TIFFWarningExt(data->tif->tif_clientdata,module,
+						    "Auto-corrected former TIFF subsampling values [%d,%d] to match subsampling values inside JPEG compressed data [%d,%d]",
+						    (int)data->tif->tif_dir.td_ycbcrsubsampling[0],
+						    (int)data->tif->tif_dir.td_ycbcrsubsampling[1],
+						    (int)ph,(int)pv);
+						data->tif->tif_dir.td_ycbcrsubsampling[0]=ph;
+						data->tif->tif_dir.td_ycbcrsubsampling[1]=pv;
+					}
+				}
+				return(1);
+			default:
+				return(0);
+		}
+	}
+}
+
+static int
+JPEGFixupTagsSubsamplingReadByte(struct JPEGFixupTagsSubsamplingData* data, uint8* result)
+{
+	if (data->bufferbytesleft==0)
+	{
+		uint32 m;
+		if (data->filebytesleft==0)
+			return(0);
+		if (!data->filepositioned)
+		{
+			TIFFSeekFile(data->tif,data->fileoffset,SEEK_SET);
+			data->filepositioned=1;
+		}
+		m=data->buffersize;
+		if ((uint64)m>data->filebytesleft)
+			m=(uint32)data->filebytesleft;
+		assert(m<0x80000000UL);
+		if (TIFFReadFile(data->tif,data->buffer,(tmsize_t)m)!=(tmsize_t)m)
+			return(0);
+		data->buffercurrentbyte=data->buffer;
+		data->bufferbytesleft=m;
+		data->fileoffset+=m;
+		data->filebytesleft-=m;
+	}
+	*result=*data->buffercurrentbyte;
+	data->buffercurrentbyte++;
+	data->bufferbytesleft--;
+	return(1);
+}
+
+static int
+JPEGFixupTagsSubsamplingReadWord(struct JPEGFixupTagsSubsamplingData* data, uint16* result)
+{
+	uint8 ma;
+	uint8 mb;
+	if (!JPEGFixupTagsSubsamplingReadByte(data,&ma))
+		return(0);
+	if (!JPEGFixupTagsSubsamplingReadByte(data,&mb))
+		return(0);
+	*result=(ma<<8)|mb;
+	return(1);
+}
+
+static void
+JPEGFixupTagsSubsamplingSkip(struct JPEGFixupTagsSubsamplingData* data, uint16 skiplength)
+{
+	if ((uint32)skiplength<=data->bufferbytesleft)
+	{
+		data->buffercurrentbyte+=skiplength;
+		data->bufferbytesleft-=skiplength;
+	}
+	else
+	{
+		uint16 m;
+		m=skiplength-data->bufferbytesleft;
+		if (m<=data->filebytesleft)
+		{
+			data->bufferbytesleft=0;
+			data->fileoffset+=m;
+			data->filebytesleft-=m;
+			data->filepositioned=0;
+		}
+		else
+		{
+			data->bufferbytesleft=0;
+			data->filebytesleft=0;
+		}
+	}
+}
+
+#endif
+
+
+static int
+JPEGSetupDecode(TIFF* tif)
+{
+	JPEGState* sp = JState(tif);
+	TIFFDirectory *td = &tif->tif_dir;
+
+#if defined(JPEG_DUAL_MODE_8_12) && !defined(TIFFInitJPEG)
+        if( tif->tif_dir.td_bitspersample == 12 )
+            return TIFFReInitJPEG_12( tif, COMPRESSION_JPEG, 0 );
+#endif
+
+	JPEGInitializeLibJPEG( tif, TRUE );
+
+	assert(sp != NULL);
+	assert(sp->cinfo.comm.is_decompressor);
+
+	/* Read JPEGTables if it is present */
+	if (TIFFFieldSet(tif,FIELD_JPEGTABLES)) {
+		TIFFjpeg_tables_src(sp, tif);
+		if(TIFFjpeg_read_header(sp,FALSE) != JPEG_HEADER_TABLES_ONLY) {
+			TIFFErrorExt(tif->tif_clientdata, "JPEGSetupDecode", "Bogus JPEGTables field");
+			return (0);
+		}
+	}
+
+	/* Grab parameters that are same for all strips/tiles */
+	sp->photometric = td->td_photometric;
+	switch (sp->photometric) {
+	case PHOTOMETRIC_YCBCR:
+		sp->h_sampling = td->td_ycbcrsubsampling[0];
+		sp->v_sampling = td->td_ycbcrsubsampling[1];
+		break;
+	default:
+		/* TIFF 6.0 forbids subsampling of all other color spaces */
+		sp->h_sampling = 1;
+		sp->v_sampling = 1;
+		break;
+	}
+
+	/* Set up for reading normal data */
+	TIFFjpeg_data_src(sp, tif);
+	tif->tif_postdecode = _TIFFNoPostDecode; /* override byte swapping */
+	return (1);
+}
+
+/*
+ * Set up for decoding a strip or tile.
+ */
+static int
+JPEGPreDecode(TIFF* tif, uint16 s)
+{
+	JPEGState *sp = JState(tif);
+	TIFFDirectory *td = &tif->tif_dir;
+	static const char module[] = "JPEGPreDecode";
+	uint32 segment_width, segment_height;
+	int downsampled_output;
+	int ci;
+
+	assert(sp != NULL);
+  
+	if (sp->cinfo.comm.is_decompressor == 0)
+	{
+		tif->tif_setupdecode( tif );
+	}
+  
+	assert(sp->cinfo.comm.is_decompressor);
+	/*
+	 * Reset decoder state from any previous strip/tile,
+	 * in case application didn't read the whole strip.
+	 */
+	if (!TIFFjpeg_abort(sp))
+		return (0);
+	/*
+	 * Read the header for this strip/tile.
+	 */
+        
+	if (TIFFjpeg_read_header(sp, TRUE) != JPEG_HEADER_OK)
+		return (0);
+
+        tif->tif_rawcp = (uint8*) sp->src.next_input_byte;
+        tif->tif_rawcc = sp->src.bytes_in_buffer;
+
+	/*
+	 * Check image parameters and set decompression parameters.
+	 */
+	segment_width = td->td_imagewidth;
+	segment_height = td->td_imagelength - tif->tif_row;
+	if (isTiled(tif)) {
+                segment_width = td->td_tilewidth;
+                segment_height = td->td_tilelength;
+		sp->bytesperline = TIFFTileRowSize(tif);
+	} else {
+		if (segment_height > td->td_rowsperstrip)
+			segment_height = td->td_rowsperstrip;
+		sp->bytesperline = TIFFScanlineSize(tif);
+	}
+	if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0) {
+		/*
+		 * For PC 2, scale down the expected strip/tile size
+		 * to match a downsampled component
+		 */
+		segment_width = TIFFhowmany_32(segment_width, sp->h_sampling);
+		segment_height = TIFFhowmany_32(segment_height, sp->v_sampling);
+	}
+	if (sp->cinfo.d.image_width < segment_width ||
+	    sp->cinfo.d.image_height < segment_height) {
+		TIFFWarningExt(tif->tif_clientdata, module,
+			       "Improper JPEG strip/tile size, "
+			       "expected %dx%d, got %dx%d",
+			       segment_width, segment_height,
+			       sp->cinfo.d.image_width,
+			       sp->cinfo.d.image_height);
+	} 
+	if (sp->cinfo.d.image_width > segment_width ||
+	    sp->cinfo.d.image_height > segment_height) {
+		/*
+		 * This case could be dangerous, if the strip or tile size has
+		 * been reported as less than the amount of data jpeg will
+		 * return, some potential security issues arise. Catch this
+		 * case and error out.
+		 */
+		TIFFErrorExt(tif->tif_clientdata, module,
+			     "JPEG strip/tile size exceeds expected dimensions,"
+			     " expected %dx%d, got %dx%d",
+			     segment_width, segment_height,
+			     sp->cinfo.d.image_width, sp->cinfo.d.image_height);
+		return (0);
+	}
+	if (sp->cinfo.d.num_components !=
+	    (td->td_planarconfig == PLANARCONFIG_CONTIG ?
+	     td->td_samplesperpixel : 1)) {
+		TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG component count");
+		return (0);
+	}
+#ifdef JPEG_LIB_MK1
+	if (12 != td->td_bitspersample && 8 != td->td_bitspersample) {
+		TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG data precision");
+		return (0);
+	}
+	sp->cinfo.d.data_precision = td->td_bitspersample;
+	sp->cinfo.d.bits_in_jsample = td->td_bitspersample;
+#else
+	if (sp->cinfo.d.data_precision != td->td_bitspersample) {
+		TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG data precision");
+		return (0);
+	}
+#endif
+	if (td->td_planarconfig == PLANARCONFIG_CONTIG) {
+		/* Component 0 should have expected sampling factors */
+		if (sp->cinfo.d.comp_info[0].h_samp_factor != sp->h_sampling ||
+		    sp->cinfo.d.comp_info[0].v_samp_factor != sp->v_sampling) {
+			TIFFErrorExt(tif->tif_clientdata, module,
+				       "Improper JPEG sampling factors %d,%d\n"
+				       "Apparently should be %d,%d.",
+				       sp->cinfo.d.comp_info[0].h_samp_factor,
+				       sp->cinfo.d.comp_info[0].v_samp_factor,
+				       sp->h_sampling, sp->v_sampling);
+			return (0);
+		}
+		/* Rest should have sampling factors 1,1 */
+		for (ci = 1; ci < sp->cinfo.d.num_components; ci++) {
+			if (sp->cinfo.d.comp_info[ci].h_samp_factor != 1 ||
+			    sp->cinfo.d.comp_info[ci].v_samp_factor != 1) {
+				TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG sampling factors");
+				return (0);
+			}
+		}
+	} else {
+		/* PC 2's single component should have sampling factors 1,1 */
+		if (sp->cinfo.d.comp_info[0].h_samp_factor != 1 ||
+		    sp->cinfo.d.comp_info[0].v_samp_factor != 1) {
+			TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG sampling factors");
+			return (0);
+		}
+	}
+	downsampled_output = FALSE;
+	if (td->td_planarconfig == PLANARCONFIG_CONTIG &&
+	    sp->photometric == PHOTOMETRIC_YCBCR &&
+	    sp->jpegcolormode == JPEGCOLORMODE_RGB) {
+		/* Convert YCbCr to RGB */
+		sp->cinfo.d.jpeg_color_space = JCS_YCbCr;
+		sp->cinfo.d.out_color_space = JCS_RGB;
+	} else {
+		/* Suppress colorspace handling */
+		sp->cinfo.d.jpeg_color_space = JCS_UNKNOWN;
+		sp->cinfo.d.out_color_space = JCS_UNKNOWN;
+		if (td->td_planarconfig == PLANARCONFIG_CONTIG &&
+		    (sp->h_sampling != 1 || sp->v_sampling != 1))
+			downsampled_output = TRUE;
+		/* XXX what about up-sampling? */
+	}
+	if (downsampled_output) {
+		/* Need to use raw-data interface to libjpeg */
+		sp->cinfo.d.raw_data_out = TRUE;
+#if JPEG_LIB_VERSION >= 70
+		sp->cinfo.d.do_fancy_upsampling = FALSE;
+#endif /* JPEG_LIB_VERSION >= 70 */
+		tif->tif_decoderow = DecodeRowError;
+		tif->tif_decodestrip = JPEGDecodeRaw;
+		tif->tif_decodetile = JPEGDecodeRaw;
+	} else {
+		/* Use normal interface to libjpeg */
+		sp->cinfo.d.raw_data_out = FALSE;
+		tif->tif_decoderow = JPEGDecode;
+		tif->tif_decodestrip = JPEGDecode;
+		tif->tif_decodetile = JPEGDecode;  
+	}
+	/* Start JPEG decompressor */
+	if (!TIFFjpeg_start_decompress(sp))
+		return (0);
+	/* Allocate downsampled-data buffers if needed */
+	if (downsampled_output) {
+		if (!alloc_downsampled_buffers(tif, sp->cinfo.d.comp_info,
+					       sp->cinfo.d.num_components))
+			return (0);
+		sp->scancount = DCTSIZE;	/* mark buffer empty */
+	}
+	return (1);
+}
+
+/*
+ * Decode a chunk of pixels.
+ * "Standard" case: returned data is not downsampled.
+ */
+/*ARGSUSED*/ static int
+JPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
+{
+	JPEGState *sp = JState(tif);
+	tmsize_t nrows;
+	(void) s;
+
+        /*
+        ** Update available information, buffer may have been refilled
+        ** between decode requests
+        */
+	sp->src.next_input_byte = (const JOCTET*) tif->tif_rawcp;
+	sp->src.bytes_in_buffer = (size_t) tif->tif_rawcc;
+
+        if( sp->bytesperline == 0 )
+                return 0;
+        
+	nrows = cc / sp->bytesperline;
+	if (cc % sp->bytesperline)
+		TIFFWarningExt(tif->tif_clientdata, tif->tif_name, "fractional scanline not read");
+
+	if( nrows > (tmsize_t) sp->cinfo.d.image_height )
+		nrows = sp->cinfo.d.image_height;
+
+	/* data is expected to be read in multiples of a scanline */
+	if (nrows)
+	{
+		JSAMPROW line_work_buf = NULL;
+
+		/*
+		 * For 6B, only use temporary buffer for 12 bit imagery.
+		 * For Mk1 always use it.
+		 */
+#if !defined(JPEG_LIB_MK1)
+		if( sp->cinfo.d.data_precision == 12 )
+#endif
+		{
+			line_work_buf = (JSAMPROW)
+			    _TIFFmalloc(sizeof(short) * sp->cinfo.d.output_width
+			    * sp->cinfo.d.num_components );
+		}
+
+		do {
+			if( line_work_buf != NULL )
+			{
+				/*
+				 * In the MK1 case, we aways read into a 16bit buffer, and then
+				 * pack down to 12bit or 8bit.  In 6B case we only read into 16
+				 * bit buffer for 12bit data, which we need to repack.
+				*/
+				if (TIFFjpeg_read_scanlines(sp, &line_work_buf, 1) != 1)
+					return (0);
+
+				if( sp->cinfo.d.data_precision == 12 )
+				{
+					int value_pairs = (sp->cinfo.d.output_width
+					    * sp->cinfo.d.num_components) / 2;
+					int iPair;
+
+					for( iPair = 0; iPair < value_pairs; iPair++ )
+					{
+						unsigned char *out_ptr =
+						    ((unsigned char *) buf) + iPair * 3;
+						JSAMPLE *in_ptr = line_work_buf + iPair * 2;
+
+						out_ptr[0] = (in_ptr[0] & 0xff0) >> 4;
+						out_ptr[1] = ((in_ptr[0] & 0xf) << 4)
+						    | ((in_ptr[1] & 0xf00) >> 8);
+						out_ptr[2] = ((in_ptr[1] & 0xff) >> 0);
+					}
+				}
+				else if( sp->cinfo.d.data_precision == 8 )
+				{
+					int value_count = (sp->cinfo.d.output_width
+					    * sp->cinfo.d.num_components);
+					int iValue;
+
+					for( iValue = 0; iValue < value_count; iValue++ )
+					{
+						((unsigned char *) buf)[iValue] =
+						    line_work_buf[iValue] & 0xff;
+					}
+				}
+			}
+			else
+			{
+				/*
+				 * In the libjpeg6b 8bit case.  We read directly into the
+				 * TIFF buffer.
+				*/
+				JSAMPROW bufptr = (JSAMPROW)buf;
+
+				if (TIFFjpeg_read_scanlines(sp, &bufptr, 1) != 1)
+					return (0);
+			}
+
+			++tif->tif_row;
+			buf += sp->bytesperline;
+			cc -= sp->bytesperline;
+		} while (--nrows > 0);
+
+		if( line_work_buf != NULL )
+			_TIFFfree( line_work_buf );
+	}
+
+        /* Update information on consumed data */
+        tif->tif_rawcp = (uint8*) sp->src.next_input_byte;
+        tif->tif_rawcc = sp->src.bytes_in_buffer;
+                
+	/* Close down the decompressor if we've finished the strip or tile. */
+	return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height
+	    || TIFFjpeg_finish_decompress(sp);
+}
+
+/*ARGSUSED*/ static int
+DecodeRowError(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
+
+{
+    (void) buf;
+    (void) cc;
+    (void) s;
+
+    TIFFErrorExt(tif->tif_clientdata, "TIFFReadScanline",
+                 "scanline oriented access is not supported for downsampled JPEG compressed images, consider enabling TIFF_JPEGCOLORMODE as JPEGCOLORMODE_RGB." );
+    return 0;
+}
+
+/*
+ * Decode a chunk of pixels.
+ * Returned data is downsampled per sampling factors.
+ */
+/*ARGSUSED*/ static int
+JPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
+{
+	JPEGState *sp = JState(tif);
+	tmsize_t nrows;
+	(void) s;
+
+	/* data is expected to be read in multiples of a scanline */
+	if ( (nrows = sp->cinfo.d.image_height) ) {
+
+		/* Cb,Cr both have sampling factors 1, so this is correct */
+		JDIMENSION clumps_per_line = sp->cinfo.d.comp_info[1].downsampled_width;            
+		int samples_per_clump = sp->samplesperclump;
+
+#if defined(JPEG_LIB_MK1_OR_12BIT)
+		unsigned short* tmpbuf = _TIFFmalloc(sizeof(unsigned short) *
+						     sp->cinfo.d.output_width *
+						     sp->cinfo.d.num_components);
+		if(tmpbuf==NULL) {
+                        TIFFErrorExt(tif->tif_clientdata, "JPEGDecodeRaw",
+				     "Out of memory");
+			return 0;
+                }
+#endif
+
+		do {
+			jpeg_component_info *compptr;
+			int ci, clumpoffset;
+
+                        if( cc < sp->bytesperline ) {
+				TIFFErrorExt(tif->tif_clientdata, "JPEGDecodeRaw",
+					     "application buffer not large enough for all data.");
+				return 0;
+                        }
+
+			/* Reload downsampled-data buffer if needed */
+			if (sp->scancount >= DCTSIZE) {
+				int n = sp->cinfo.d.max_v_samp_factor * DCTSIZE;
+				if (TIFFjpeg_read_raw_data(sp, sp->ds_buffer, n) != n)
+					return (0);
+				sp->scancount = 0;
+			}
+			/*
+			 * Fastest way to unseparate data is to make one pass
+			 * over the scanline for each row of each component.
+			 */
+			clumpoffset = 0;    /* first sample in clump */
+			for (ci = 0, compptr = sp->cinfo.d.comp_info;
+			     ci < sp->cinfo.d.num_components;
+			     ci++, compptr++) {
+				int hsamp = compptr->h_samp_factor;
+				int vsamp = compptr->v_samp_factor;
+				int ypos;
+
+				for (ypos = 0; ypos < vsamp; ypos++) {
+					JSAMPLE *inptr = sp->ds_buffer[ci][sp->scancount*vsamp + ypos];
+					JDIMENSION nclump;
+#if defined(JPEG_LIB_MK1_OR_12BIT)
+					JSAMPLE *outptr = (JSAMPLE*)tmpbuf + clumpoffset;
+#else
+					JSAMPLE *outptr = (JSAMPLE*)buf + clumpoffset;
+					if (cc < (tmsize_t) (clumpoffset + samples_per_clump*(clumps_per_line-1) + hsamp)) {
+						TIFFErrorExt(tif->tif_clientdata, "JPEGDecodeRaw",
+							     "application buffer not large enough for all data, possible subsampling issue");
+						return 0;
+					}
+#endif
+
+					if (hsamp == 1) {
+						/* fast path for at least Cb and Cr */
+						for (nclump = clumps_per_line; nclump-- > 0; ) {
+							outptr[0] = *inptr++;
+							outptr += samples_per_clump;
+						}
+					} else {
+						int xpos;
+
+						/* general case */
+						for (nclump = clumps_per_line; nclump-- > 0; ) {
+							for (xpos = 0; xpos < hsamp; xpos++)
+								outptr[xpos] = *inptr++;
+							outptr += samples_per_clump;
+						}
+					}
+					clumpoffset += hsamp;
+				}
+			}
+
+#if defined(JPEG_LIB_MK1_OR_12BIT)
+			{
+				if (sp->cinfo.d.data_precision == 8)
+				{
+					int i=0;
+					int len = sp->cinfo.d.output_width * sp->cinfo.d.num_components;
+					for (i=0; i<len; i++)
+					{
+						((unsigned char*)buf)[i] = tmpbuf[i] & 0xff;
+					}
+				}
+				else
+				{         /* 12-bit */
+					int value_pairs = (sp->cinfo.d.output_width
+							   * sp->cinfo.d.num_components) / 2;
+					int iPair;
+					for( iPair = 0; iPair < value_pairs; iPair++ )
+					{
+						unsigned char *out_ptr = ((unsigned char *) buf) + iPair * 3;
+						JSAMPLE *in_ptr = (JSAMPLE *) (tmpbuf + iPair * 2);
+						out_ptr[0] = (in_ptr[0] & 0xff0) >> 4;
+						out_ptr[1] = ((in_ptr[0] & 0xf) << 4)
+							| ((in_ptr[1] & 0xf00) >> 8);
+						out_ptr[2] = ((in_ptr[1] & 0xff) >> 0);
+					}
+				}
+			}
+#endif
+
+			sp->scancount ++;
+			tif->tif_row += sp->v_sampling;
+
+			buf += sp->bytesperline;
+			cc -= sp->bytesperline;
+
+			nrows -= sp->v_sampling;
+		} while (nrows > 0);
+
+#if defined(JPEG_LIB_MK1_OR_12BIT)
+		_TIFFfree(tmpbuf);
+#endif
+
+	}
+
+	/* Close down the decompressor if done. */
+	return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height
+		|| TIFFjpeg_finish_decompress(sp);
+}
+
+
+/*
+ * JPEG Encoding.
+ */
+
+static void
+unsuppress_quant_table (JPEGState* sp, int tblno)
+{
+	JQUANT_TBL* qtbl;
+
+	if ((qtbl = sp->cinfo.c.quant_tbl_ptrs[tblno]) != NULL)
+		qtbl->sent_table = FALSE;
+}
+
+static void
+suppress_quant_table (JPEGState* sp, int tblno)
+{
+	JQUANT_TBL* qtbl;
+
+	if ((qtbl = sp->cinfo.c.quant_tbl_ptrs[tblno]) != NULL)
+		qtbl->sent_table = TRUE;
+}
+
+static void
+unsuppress_huff_table (JPEGState* sp, int tblno)
+{
+	JHUFF_TBL* htbl;
+
+	if ((htbl = sp->cinfo.c.dc_huff_tbl_ptrs[tblno]) != NULL)
+		htbl->sent_table = FALSE;
+	if ((htbl = sp->cinfo.c.ac_huff_tbl_ptrs[tblno]) != NULL)
+		htbl->sent_table = FALSE;
+}
+
+static void
+suppress_huff_table (JPEGState* sp, int tblno)
+{
+	JHUFF_TBL* htbl;
+
+	if ((htbl = sp->cinfo.c.dc_huff_tbl_ptrs[tblno]) != NULL)
+		htbl->sent_table = TRUE;
+	if ((htbl = sp->cinfo.c.ac_huff_tbl_ptrs[tblno]) != NULL)
+		htbl->sent_table = TRUE;
+}
+
+static int
+prepare_JPEGTables(TIFF* tif)
+{
+	JPEGState* sp = JState(tif);
+
+	/* Initialize quant tables for current quality setting */
+	if (!TIFFjpeg_set_quality(sp, sp->jpegquality, FALSE))
+		return (0);
+	/* Mark only the tables we want for output */
+	/* NB: chrominance tables are currently used only with YCbCr */
+	if (!TIFFjpeg_suppress_tables(sp, TRUE))
+		return (0);
+	if (sp->jpegtablesmode & JPEGTABLESMODE_QUANT) {
+		unsuppress_quant_table(sp, 0);
+		if (sp->photometric == PHOTOMETRIC_YCBCR)
+			unsuppress_quant_table(sp, 1);
+	}
+	if (sp->jpegtablesmode & JPEGTABLESMODE_HUFF) {
+		unsuppress_huff_table(sp, 0);
+		if (sp->photometric == PHOTOMETRIC_YCBCR)
+			unsuppress_huff_table(sp, 1);
+	}
+	/* Direct libjpeg output into jpegtables */
+	if (!TIFFjpeg_tables_dest(sp, tif))
+		return (0);
+	/* Emit tables-only datastream */
+	if (!TIFFjpeg_write_tables(sp))
+		return (0);
+
+	return (1);
+}
+
+static int
+JPEGSetupEncode(TIFF* tif)
+{
+	JPEGState* sp = JState(tif);
+	TIFFDirectory *td = &tif->tif_dir;
+	static const char module[] = "JPEGSetupEncode";
+
+#if defined(JPEG_DUAL_MODE_8_12) && !defined(TIFFInitJPEG)
+        if( tif->tif_dir.td_bitspersample == 12 )
+            return TIFFReInitJPEG_12( tif, COMPRESSION_JPEG, 1 );
+#endif
+
+        JPEGInitializeLibJPEG( tif, FALSE );
+
+	assert(sp != NULL);
+	assert(!sp->cinfo.comm.is_decompressor);
+
+	sp->photometric = td->td_photometric;
+
+	/*
+	 * Initialize all JPEG parameters to default values.
+	 * Note that jpeg_set_defaults needs legal values for
+	 * in_color_space and input_components.
+	 */
+	if (td->td_planarconfig == PLANARCONFIG_CONTIG) {
+		sp->cinfo.c.input_components = td->td_samplesperpixel;
+		if (sp->photometric == PHOTOMETRIC_YCBCR) {
+			if (sp->jpegcolormode == JPEGCOLORMODE_RGB) {
+				sp->cinfo.c.in_color_space = JCS_RGB;
+			} else {
+				sp->cinfo.c.in_color_space = JCS_YCbCr;
+			}
+		} else {
+			if ((td->td_photometric == PHOTOMETRIC_MINISWHITE || td->td_photometric == PHOTOMETRIC_MINISBLACK) && td->td_samplesperpixel == 1)
+				sp->cinfo.c.in_color_space = JCS_GRAYSCALE;
+			else if (td->td_photometric == PHOTOMETRIC_RGB && td->td_samplesperpixel == 3)
+				sp->cinfo.c.in_color_space = JCS_RGB;
+			else if (td->td_photometric == PHOTOMETRIC_SEPARATED && td->td_samplesperpixel == 4)
+				sp->cinfo.c.in_color_space = JCS_CMYK;
+			else
+				sp->cinfo.c.in_color_space = JCS_UNKNOWN;
+		}
+	} else {
+		sp->cinfo.c.input_components = 1;
+		sp->cinfo.c.in_color_space = JCS_UNKNOWN;
+	}
+	if (!TIFFjpeg_set_defaults(sp))
+		return (0);
+	/* Set per-file parameters */
+	switch (sp->photometric) {
+	case PHOTOMETRIC_YCBCR:
+		sp->h_sampling = td->td_ycbcrsubsampling[0];
+		sp->v_sampling = td->td_ycbcrsubsampling[1];
+		/*
+		 * A ReferenceBlackWhite field *must* be present since the
+		 * default value is inappropriate for YCbCr.  Fill in the
+		 * proper value if application didn't set it.
+		 */
+		{
+			float *ref;
+			if (!TIFFGetField(tif, TIFFTAG_REFERENCEBLACKWHITE,
+					  &ref)) {
+				float refbw[6];
+				long top = 1L << td->td_bitspersample;
+				refbw[0] = 0;
+				refbw[1] = (float)(top-1L);
+				refbw[2] = (float)(top>>1);
+				refbw[3] = refbw[1];
+				refbw[4] = refbw[2];
+				refbw[5] = refbw[1];
+				TIFFSetField(tif, TIFFTAG_REFERENCEBLACKWHITE,
+					     refbw);
+			}
+		}
+		break;
+	case PHOTOMETRIC_PALETTE:		/* disallowed by Tech Note */
+	case PHOTOMETRIC_MASK:
+		TIFFErrorExt(tif->tif_clientdata, module,
+			  "PhotometricInterpretation %d not allowed for JPEG",
+			  (int) sp->photometric);
+		return (0);
+	default:
+		/* TIFF 6.0 forbids subsampling of all other color spaces */
+		sp->h_sampling = 1;
+		sp->v_sampling = 1;
+		break;
+	}
+
+	/* Verify miscellaneous parameters */
+
+	/*
+	 * This would need work if libtiff ever supports different
+	 * depths for different components, or if libjpeg ever supports
+	 * run-time selection of depth.  Neither is imminent.
+	 */
+#ifdef JPEG_LIB_MK1
+        /* BITS_IN_JSAMPLE now permits 8 and 12 --- dgilbert */
+	if (td->td_bitspersample != 8 && td->td_bitspersample != 12) 
+#else
+	if (td->td_bitspersample != BITS_IN_JSAMPLE )
+#endif
+	{
+		TIFFErrorExt(tif->tif_clientdata, module, "BitsPerSample %d not allowed for JPEG",
+			  (int) td->td_bitspersample);
+		return (0);
+	}
+	sp->cinfo.c.data_precision = td->td_bitspersample;
+#ifdef JPEG_LIB_MK1
+        sp->cinfo.c.bits_in_jsample = td->td_bitspersample;
+#endif
+	if (isTiled(tif)) {
+		if ((td->td_tilelength % (sp->v_sampling * DCTSIZE)) != 0) {
+			TIFFErrorExt(tif->tif_clientdata, module,
+				  "JPEG tile height must be multiple of %d",
+				  sp->v_sampling * DCTSIZE);
+			return (0);
+		}
+		if ((td->td_tilewidth % (sp->h_sampling * DCTSIZE)) != 0) {
+			TIFFErrorExt(tif->tif_clientdata, module,
+				  "JPEG tile width must be multiple of %d",
+				  sp->h_sampling * DCTSIZE);
+			return (0);
+		}
+	} else {
+		if (td->td_rowsperstrip < td->td_imagelength &&
+		    (td->td_rowsperstrip % (sp->v_sampling * DCTSIZE)) != 0) {
+			TIFFErrorExt(tif->tif_clientdata, module,
+				  "RowsPerStrip must be multiple of %d for JPEG",
+				  sp->v_sampling * DCTSIZE);
+			return (0);
+		}
+	}
+
+	/* Create a JPEGTables field if appropriate */
+	if (sp->jpegtablesmode & (JPEGTABLESMODE_QUANT|JPEGTABLESMODE_HUFF)) {
+                if( sp->jpegtables == NULL
+                    || memcmp(sp->jpegtables,"\0\0\0\0\0\0\0\0\0",8) == 0 )
+                {
+                        if (!prepare_JPEGTables(tif))
+                                return (0);
+                        /* Mark the field present */
+                        /* Can't use TIFFSetField since BEENWRITING is already set! */
+                        tif->tif_flags |= TIFF_DIRTYDIRECT;
+                        TIFFSetFieldBit(tif, FIELD_JPEGTABLES);
+                }
+	} else {
+		/* We do not support application-supplied JPEGTables, */
+		/* so mark the field not present */
+		TIFFClrFieldBit(tif, FIELD_JPEGTABLES);
+	}
+
+	/* Direct libjpeg output to libtiff's output buffer */
+	TIFFjpeg_data_dest(sp, tif);
+
+	return (1);
+}
+
+/*
+ * Set encoding state at the start of a strip or tile.
+ */
+static int
+JPEGPreEncode(TIFF* tif, uint16 s)
+{
+	JPEGState *sp = JState(tif);
+	TIFFDirectory *td = &tif->tif_dir;
+	static const char module[] = "JPEGPreEncode";
+	uint32 segment_width, segment_height;
+	int downsampled_input;
+
+	assert(sp != NULL);
+  
+	if (sp->cinfo.comm.is_decompressor == 1)
+	{
+		tif->tif_setupencode( tif );
+	}
+  
+	assert(!sp->cinfo.comm.is_decompressor);
+	/*
+	 * Set encoding parameters for this strip/tile.
+	 */
+	if (isTiled(tif)) {
+		segment_width = td->td_tilewidth;
+		segment_height = td->td_tilelength;
+		sp->bytesperline = TIFFTileRowSize(tif);
+	} else {
+		segment_width = td->td_imagewidth;
+		segment_height = td->td_imagelength - tif->tif_row;
+		if (segment_height > td->td_rowsperstrip)
+			segment_height = td->td_rowsperstrip;
+		sp->bytesperline = TIFFScanlineSize(tif);
+	}
+	if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0) {
+		/* for PC 2, scale down the strip/tile size
+		 * to match a downsampled component
+		 */
+		segment_width = TIFFhowmany_32(segment_width, sp->h_sampling); 
+		segment_height = TIFFhowmany_32(segment_height, sp->v_sampling);
+	}
+	if (segment_width > 65535 || segment_height > 65535) {
+		TIFFErrorExt(tif->tif_clientdata, module, "Strip/tile too large for JPEG");
+		return (0);
+	}
+	sp->cinfo.c.image_width = segment_width;
+	sp->cinfo.c.image_height = segment_height;
+	downsampled_input = FALSE;
+	if (td->td_planarconfig == PLANARCONFIG_CONTIG) {
+		sp->cinfo.c.input_components = td->td_samplesperpixel;
+		if (sp->photometric == PHOTOMETRIC_YCBCR) {
+			if (sp->jpegcolormode != JPEGCOLORMODE_RGB) {
+				if (sp->h_sampling != 1 || sp->v_sampling != 1)
+					downsampled_input = TRUE;
+			}
+			if (!TIFFjpeg_set_colorspace(sp, JCS_YCbCr))
+				return (0);
+			/*
+			 * Set Y sampling factors;
+			 * we assume jpeg_set_colorspace() set the rest to 1
+			 */
+			sp->cinfo.c.comp_info[0].h_samp_factor = sp->h_sampling;
+			sp->cinfo.c.comp_info[0].v_samp_factor = sp->v_sampling;
+		} else {
+			if (!TIFFjpeg_set_colorspace(sp, sp->cinfo.c.in_color_space))
+				return (0);
+			/* jpeg_set_colorspace set all sampling factors to 1 */
+		}
+	} else {
+		if (!TIFFjpeg_set_colorspace(sp, JCS_UNKNOWN))
+			return (0);
+		sp->cinfo.c.comp_info[0].component_id = s;
+		/* jpeg_set_colorspace() set sampling factors to 1 */
+		if (sp->photometric == PHOTOMETRIC_YCBCR && s > 0) {
+			sp->cinfo.c.comp_info[0].quant_tbl_no = 1;
+			sp->cinfo.c.comp_info[0].dc_tbl_no = 1;
+			sp->cinfo.c.comp_info[0].ac_tbl_no = 1;
+		}
+	}
+	/* ensure libjpeg won't write any extraneous markers */
+	sp->cinfo.c.write_JFIF_header = FALSE;
+	sp->cinfo.c.write_Adobe_marker = FALSE;
+	/* set up table handling correctly */
+	/* calling TIFFjpeg_set_quality() causes quantization tables to be flagged */
+	/* as being to be emitted, which we don't want in the JPEGTABLESMODE_QUANT */
+	/* mode, so we must manually suppress them. However TIFFjpeg_set_quality() */
+	/* should really be called when dealing with files with directories with */
+	/* mixed qualities. see http://trac.osgeo.org/gdal/ticket/3539 */
+	if (!TIFFjpeg_set_quality(sp, sp->jpegquality, FALSE))
+		return (0);
+	if (sp->jpegtablesmode & JPEGTABLESMODE_QUANT) {
+		suppress_quant_table(sp, 0);
+		suppress_quant_table(sp, 1);
+	}
+	else {
+		unsuppress_quant_table(sp, 0);
+		unsuppress_quant_table(sp, 1);
+	}
+	if (sp->jpegtablesmode & JPEGTABLESMODE_HUFF)
+	{
+		/* Explicit suppression is only needed if we did not go through the */
+		/* prepare_JPEGTables() code path, which may be the case if updating */
+		/* an existing file */
+		suppress_huff_table(sp, 0);
+		suppress_huff_table(sp, 1);
+		sp->cinfo.c.optimize_coding = FALSE;
+	}
+	else
+		sp->cinfo.c.optimize_coding = TRUE;
+	if (downsampled_input) {
+		/* Need to use raw-data interface to libjpeg */
+		sp->cinfo.c.raw_data_in = TRUE;
+		tif->tif_encoderow = JPEGEncodeRaw;
+		tif->tif_encodestrip = JPEGEncodeRaw;
+		tif->tif_encodetile = JPEGEncodeRaw;
+	} else {
+		/* Use normal interface to libjpeg */
+		sp->cinfo.c.raw_data_in = FALSE;
+		tif->tif_encoderow = JPEGEncode;
+		tif->tif_encodestrip = JPEGEncode;
+		tif->tif_encodetile = JPEGEncode;
+	}
+	/* Start JPEG compressor */
+	if (!TIFFjpeg_start_compress(sp, FALSE))
+		return (0);
+	/* Allocate downsampled-data buffers if needed */
+	if (downsampled_input) {
+		if (!alloc_downsampled_buffers(tif, sp->cinfo.c.comp_info,
+					       sp->cinfo.c.num_components))
+			return (0);
+	}
+	sp->scancount = 0;
+
+	return (1);
+}
+
+/*
+ * Encode a chunk of pixels.
+ * "Standard" case: incoming data is not downsampled.
+ */
+static int
+JPEGEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
+{
+	JPEGState *sp = JState(tif);
+	tmsize_t nrows;
+	JSAMPROW bufptr[1];
+        short *line16 = NULL;
+        int    line16_count = 0;
+
+	(void) s;
+	assert(sp != NULL);
+	/* data is expected to be supplied in multiples of a scanline */
+	nrows = cc / sp->bytesperline;
+	if (cc % sp->bytesperline)
+            TIFFWarningExt(tif->tif_clientdata, tif->tif_name, 
+                           "fractional scanline discarded");
+
+        /* The last strip will be limited to image size */
+        if( !isTiled(tif) && tif->tif_row+nrows > tif->tif_dir.td_imagelength )
+            nrows = tif->tif_dir.td_imagelength - tif->tif_row;
+
+        if( sp->cinfo.c.data_precision == 12 )
+        {
+            line16_count = (sp->bytesperline * 2) / 3;
+            line16 = (short *) _TIFFmalloc(sizeof(short) * line16_count);
+	    // FIXME: undiagnosed malloc failure
+        }
+            
+	while (nrows-- > 0) {
+
+            if( sp->cinfo.c.data_precision == 12 )
+            {
+
+                int value_pairs = line16_count / 2;
+                int iPair;
+
+		bufptr[0] = (JSAMPROW) line16;
+
+                for( iPair = 0; iPair < value_pairs; iPair++ )
+                {
+                    unsigned char *in_ptr =
+                        ((unsigned char *) buf) + iPair * 3;
+                    JSAMPLE *out_ptr = (JSAMPLE *) (line16 + iPair * 2);
+
+                    out_ptr[0] = (in_ptr[0] << 4) | ((in_ptr[1] & 0xf0) >> 4);
+                    out_ptr[1] = ((in_ptr[1] & 0x0f) << 8) | in_ptr[2];
+                }
+            }
+            else
+            {
+		bufptr[0] = (JSAMPROW) buf;
+            }
+            if (TIFFjpeg_write_scanlines(sp, bufptr, 1) != 1)
+                return (0);
+            if (nrows > 0)
+                tif->tif_row++;
+            buf += sp->bytesperline;
+	}
+
+        if( sp->cinfo.c.data_precision == 12 )
+        {
+            _TIFFfree( line16 );
+        }
+            
+	return (1);
+}
+
+/*
+ * Encode a chunk of pixels.
+ * Incoming data is expected to be downsampled per sampling factors.
+ */
+static int
+JPEGEncodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
+{
+	JPEGState *sp = JState(tif);
+	JSAMPLE* inptr;
+	JSAMPLE* outptr;
+	tmsize_t nrows;
+	JDIMENSION clumps_per_line, nclump;
+	int clumpoffset, ci, xpos, ypos;
+	jpeg_component_info* compptr;
+	int samples_per_clump = sp->samplesperclump;
+	tmsize_t bytesperclumpline;
+
+	(void) s;
+	assert(sp != NULL);
+	/* data is expected to be supplied in multiples of a clumpline */
+	/* a clumpline is equivalent to v_sampling desubsampled scanlines */
+	/* TODO: the following calculation of bytesperclumpline, should substitute calculation of sp->bytesperline, except that it is per v_sampling lines */
+	bytesperclumpline = (((sp->cinfo.c.image_width+sp->h_sampling-1)/sp->h_sampling)
+			     *(sp->h_sampling*sp->v_sampling+2)*sp->cinfo.c.data_precision+7)
+			    /8;
+
+	nrows = ( cc / bytesperclumpline ) * sp->v_sampling;
+	if (cc % bytesperclumpline)
+		TIFFWarningExt(tif->tif_clientdata, tif->tif_name, "fractional scanline discarded");
+
+	/* Cb,Cr both have sampling factors 1, so this is correct */
+	clumps_per_line = sp->cinfo.c.comp_info[1].downsampled_width;
+
+	while (nrows > 0) {
+		/*
+		 * Fastest way to separate the data is to make one pass
+		 * over the scanline for each row of each component.
+		 */
+		clumpoffset = 0;		/* first sample in clump */
+		for (ci = 0, compptr = sp->cinfo.c.comp_info;
+		     ci < sp->cinfo.c.num_components;
+		     ci++, compptr++) {
+		    int hsamp = compptr->h_samp_factor;
+		    int vsamp = compptr->v_samp_factor;
+		    int padding = (int) (compptr->width_in_blocks * DCTSIZE -
+					 clumps_per_line * hsamp);
+		    for (ypos = 0; ypos < vsamp; ypos++) {
+			inptr = ((JSAMPLE*) buf) + clumpoffset;
+			outptr = sp->ds_buffer[ci][sp->scancount*vsamp + ypos];
+			if (hsamp == 1) {
+			    /* fast path for at least Cb and Cr */
+			    for (nclump = clumps_per_line; nclump-- > 0; ) {
+				*outptr++ = inptr[0];
+				inptr += samples_per_clump;
+			    }
+			} else {
+			    /* general case */
+			    for (nclump = clumps_per_line; nclump-- > 0; ) {
+				for (xpos = 0; xpos < hsamp; xpos++)
+				    *outptr++ = inptr[xpos];
+				inptr += samples_per_clump;
+			    }
+			}
+			/* pad each scanline as needed */
+			for (xpos = 0; xpos < padding; xpos++) {
+			    *outptr = outptr[-1];
+			    outptr++;
+			}
+			clumpoffset += hsamp;
+		    }
+		}
+		sp->scancount++;
+		if (sp->scancount >= DCTSIZE) {
+			int n = sp->cinfo.c.max_v_samp_factor * DCTSIZE;
+			if (TIFFjpeg_write_raw_data(sp, sp->ds_buffer, n) != n)
+				return (0);
+			sp->scancount = 0;
+		}
+		tif->tif_row += sp->v_sampling;
+		buf += bytesperclumpline;
+		nrows -= sp->v_sampling;
+	}
+	return (1);
+}
+
+/*
+ * Finish up at the end of a strip or tile.
+ */
+static int
+JPEGPostEncode(TIFF* tif)
+{
+	JPEGState *sp = JState(tif);
+
+	if (sp->scancount > 0) {
+		/*
+		 * Need to emit a partial bufferload of downsampled data.
+		 * Pad the data vertically.
+		 */
+		int ci, ypos, n;
+		jpeg_component_info* compptr;
+
+		for (ci = 0, compptr = sp->cinfo.c.comp_info;
+		     ci < sp->cinfo.c.num_components;
+		     ci++, compptr++) {
+			int vsamp = compptr->v_samp_factor;
+			tmsize_t row_width = compptr->width_in_blocks * DCTSIZE
+				* sizeof(JSAMPLE);
+			for (ypos = sp->scancount * vsamp;
+			     ypos < DCTSIZE * vsamp; ypos++) {
+				_TIFFmemcpy((void*)sp->ds_buffer[ci][ypos],
+					    (void*)sp->ds_buffer[ci][ypos-1],
+					    row_width);
+
+			}
+		}
+		n = sp->cinfo.c.max_v_samp_factor * DCTSIZE;
+		if (TIFFjpeg_write_raw_data(sp, sp->ds_buffer, n) != n)
+			return (0);
+	}
+
+	return (TIFFjpeg_finish_compress(JState(tif)));
+}
+
+static void
+JPEGCleanup(TIFF* tif)
+{
+	JPEGState *sp = JState(tif);
+	
+	assert(sp != 0);
+
+	tif->tif_tagmethods.vgetfield = sp->vgetparent;
+	tif->tif_tagmethods.vsetfield = sp->vsetparent;
+	tif->tif_tagmethods.printdir = sp->printdir;
+
+	if( sp != NULL ) {
+		if( sp->cinfo_initialized )
+		    TIFFjpeg_destroy(sp);	/* release libjpeg resources */
+		if (sp->jpegtables)		/* tag value */
+			_TIFFfree(sp->jpegtables);
+	}
+	_TIFFfree(tif->tif_data);	/* release local state */
+	tif->tif_data = NULL;
+
+	_TIFFSetDefaultCompressionState(tif);
+}
+
+static void 
+JPEGResetUpsampled( TIFF* tif )
+{
+	JPEGState* sp = JState(tif);
+	TIFFDirectory* td = &tif->tif_dir;
+
+	/*
+	 * Mark whether returned data is up-sampled or not so TIFFStripSize
+	 * and TIFFTileSize return values that reflect the true amount of
+	 * data.
+	 */
+	tif->tif_flags &= ~TIFF_UPSAMPLED;
+	if (td->td_planarconfig == PLANARCONFIG_CONTIG) {
+		if (td->td_photometric == PHOTOMETRIC_YCBCR &&
+		    sp->jpegcolormode == JPEGCOLORMODE_RGB) {
+			tif->tif_flags |= TIFF_UPSAMPLED;
+		} else {
+#ifdef notdef
+			if (td->td_ycbcrsubsampling[0] != 1 ||
+			    td->td_ycbcrsubsampling[1] != 1)
+				; /* XXX what about up-sampling? */
+#endif
+		}
+	}
+
+	/*
+	 * Must recalculate cached tile size in case sampling state changed.
+	 * Should we really be doing this now if image size isn't set? 
+	 */
+        if( tif->tif_tilesize > 0 )
+            tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)(-1);   
+        if( tif->tif_scanlinesize > 0 )
+            tif->tif_scanlinesize = TIFFScanlineSize(tif); 
+}
+
+static int
+JPEGVSetField(TIFF* tif, uint32 tag, va_list ap)
+{
+	JPEGState* sp = JState(tif);
+	const TIFFField* fip;
+	uint32 v32;
+
+	assert(sp != NULL);
+
+	switch (tag) {
+	case TIFFTAG_JPEGTABLES:
+		v32 = (uint32) va_arg(ap, uint32);
+		if (v32 == 0) {
+			/* XXX */
+			return (0);
+		}
+		_TIFFsetByteArray(&sp->jpegtables, va_arg(ap, void*),
+		    (long) v32);
+		sp->jpegtables_length = v32;
+		TIFFSetFieldBit(tif, FIELD_JPEGTABLES);
+		break;
+	case TIFFTAG_JPEGQUALITY:
+		sp->jpegquality = (int) va_arg(ap, int);
+		return (1);			/* pseudo tag */
+	case TIFFTAG_JPEGCOLORMODE:
+		sp->jpegcolormode = (int) va_arg(ap, int);
+		JPEGResetUpsampled( tif );
+		return (1);			/* pseudo tag */
+	case TIFFTAG_PHOTOMETRIC:
+	{
+		int ret_value = (*sp->vsetparent)(tif, tag, ap);
+		JPEGResetUpsampled( tif );
+		return ret_value;
+	}
+	case TIFFTAG_JPEGTABLESMODE:
+		sp->jpegtablesmode = (int) va_arg(ap, int);
+		return (1);			/* pseudo tag */
+	case TIFFTAG_YCBCRSUBSAMPLING:
+		/* mark the fact that we have a real ycbcrsubsampling! */
+		sp->ycbcrsampling_fetched = 1;
+		/* should we be recomputing upsampling info here? */
+		return (*sp->vsetparent)(tif, tag, ap);
+	default:
+		return (*sp->vsetparent)(tif, tag, ap);
+	}
+
+	if ((fip = TIFFFieldWithTag(tif, tag))) {
+		TIFFSetFieldBit(tif, fip->field_bit);
+	} else {
+		return (0);
+	}
+
+	tif->tif_flags |= TIFF_DIRTYDIRECT;
+	return (1);
+}
+
+static int
+JPEGVGetField(TIFF* tif, uint32 tag, va_list ap)
+{
+	JPEGState* sp = JState(tif);
+
+	assert(sp != NULL);
+
+	switch (tag) {
+		case TIFFTAG_JPEGTABLES:
+			*va_arg(ap, uint32*) = sp->jpegtables_length;
+			*va_arg(ap, void**) = sp->jpegtables;
+			break;
+		case TIFFTAG_JPEGQUALITY:
+			*va_arg(ap, int*) = sp->jpegquality;
+			break;
+		case TIFFTAG_JPEGCOLORMODE:
+			*va_arg(ap, int*) = sp->jpegcolormode;
+			break;
+		case TIFFTAG_JPEGTABLESMODE:
+			*va_arg(ap, int*) = sp->jpegtablesmode;
+			break;
+		default:
+			return (*sp->vgetparent)(tif, tag, ap);
+	}
+	return (1);
+}
+
+static void
+JPEGPrintDir(TIFF* tif, FILE* fd, long flags)
+{
+	JPEGState* sp = JState(tif);
+
+	assert(sp != NULL);
+	(void) flags;
+
+        if( sp != NULL ) {
+		if (TIFFFieldSet(tif,FIELD_JPEGTABLES))
+			fprintf(fd, "  JPEG Tables: (%lu bytes)\n",
+				(unsigned long) sp->jpegtables_length);
+		if (sp->printdir)
+			(*sp->printdir)(tif, fd, flags);
+	}
+}
+
+static uint32
+JPEGDefaultStripSize(TIFF* tif, uint32 s)
+{
+	JPEGState* sp = JState(tif);
+	TIFFDirectory *td = &tif->tif_dir;
+
+	s = (*sp->defsparent)(tif, s);
+	if (s < td->td_imagelength)
+		s = TIFFroundup_32(s, td->td_ycbcrsubsampling[1] * DCTSIZE);
+	return (s);
+}
+
+static void
+JPEGDefaultTileSize(TIFF* tif, uint32* tw, uint32* th)
+{
+	JPEGState* sp = JState(tif);
+	TIFFDirectory *td = &tif->tif_dir;
+
+	(*sp->deftparent)(tif, tw, th);
+	*tw = TIFFroundup_32(*tw, td->td_ycbcrsubsampling[0] * DCTSIZE);
+	*th = TIFFroundup_32(*th, td->td_ycbcrsubsampling[1] * DCTSIZE);
+}
+
+/*
+ * The JPEG library initialized used to be done in TIFFInitJPEG(), but
+ * now that we allow a TIFF file to be opened in update mode it is necessary
+ * to have some way of deciding whether compression or decompression is
+ * desired other than looking at tif->tif_mode.  We accomplish this by 
+ * examining {TILE/STRIP}BYTECOUNTS to see if there is a non-zero entry.
+ * If so, we assume decompression is desired. 
+ *
+ * This is tricky, because TIFFInitJPEG() is called while the directory is
+ * being read, and generally speaking the BYTECOUNTS tag won't have been read
+ * at that point.  So we try to defer jpeg library initialization till we
+ * do have that tag ... basically any access that might require the compressor
+ * or decompressor that occurs after the reading of the directory. 
+ *
+ * In an ideal world compressors or decompressors would be setup
+ * at the point where a single tile or strip was accessed (for read or write)
+ * so that stuff like update of missing tiles, or replacement of tiles could
+ * be done. However, we aren't trying to crack that nut just yet ...
+ *
+ * NFW, Feb 3rd, 2003.
+ */
+
+static int JPEGInitializeLibJPEG( TIFF * tif, int decompress )
+{
+    JPEGState* sp = JState(tif);
+
+    if(sp->cinfo_initialized)
+    {
+        if( !decompress && sp->cinfo.comm.is_decompressor )
+            TIFFjpeg_destroy( sp );
+        else if( decompress && !sp->cinfo.comm.is_decompressor )
+            TIFFjpeg_destroy( sp );
+        else
+            return 1;
+
+        sp->cinfo_initialized = 0;
+    }
+
+    /*
+     * Initialize libjpeg.
+     */
+    if ( decompress ) {
+        if (!TIFFjpeg_create_decompress(sp))
+            return (0);
+    } else {
+        if (!TIFFjpeg_create_compress(sp))
+            return (0);
+    }
+
+    sp->cinfo_initialized = TRUE;
+
+    return 1;
+}
+
+int
+TIFFInitJPEG(TIFF* tif, int scheme)
+{
+	JPEGState* sp;
+
+	assert(scheme == COMPRESSION_JPEG);
+
+	/*
+	 * Merge codec-specific tag information.
+	 */
+	if (!_TIFFMergeFields(tif, jpegFields, TIFFArrayCount(jpegFields))) {
+		TIFFErrorExt(tif->tif_clientdata,
+			     "TIFFInitJPEG",
+			     "Merging JPEG codec-specific tags failed");
+		return 0;
+	}
+
+	/*
+	 * Allocate state block so tag methods have storage to record values.
+	 */
+	tif->tif_data = (uint8*) _TIFFmalloc(sizeof (JPEGState));
+
+	if (tif->tif_data == NULL) {
+		TIFFErrorExt(tif->tif_clientdata,
+			     "TIFFInitJPEG", "No space for JPEG state block");
+		return 0;
+	}
+        _TIFFmemset(tif->tif_data, 0, sizeof(JPEGState));
+
+	sp = JState(tif);
+	sp->tif = tif;				/* back link */
+
+	/*
+	 * Override parent get/set field methods.
+	 */
+	sp->vgetparent = tif->tif_tagmethods.vgetfield;
+	tif->tif_tagmethods.vgetfield = JPEGVGetField; /* hook for codec tags */
+	sp->vsetparent = tif->tif_tagmethods.vsetfield;
+	tif->tif_tagmethods.vsetfield = JPEGVSetField; /* hook for codec tags */
+	sp->printdir = tif->tif_tagmethods.printdir;
+	tif->tif_tagmethods.printdir = JPEGPrintDir;   /* hook for codec tags */
+
+	/* Default values for codec-specific fields */
+	sp->jpegtables = NULL;
+	sp->jpegtables_length = 0;
+	sp->jpegquality = 75;			/* Default IJG quality */
+	sp->jpegcolormode = JPEGCOLORMODE_RAW;
+	sp->jpegtablesmode = JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF;
+        sp->ycbcrsampling_fetched = 0;
+
+	/*
+	 * Install codec methods.
+	 */
+	tif->tif_fixuptags = JPEGFixupTags;
+	tif->tif_setupdecode = JPEGSetupDecode;
+	tif->tif_predecode = JPEGPreDecode;
+	tif->tif_decoderow = JPEGDecode;
+	tif->tif_decodestrip = JPEGDecode;
+	tif->tif_decodetile = JPEGDecode;
+	tif->tif_setupencode = JPEGSetupEncode;
+	tif->tif_preencode = JPEGPreEncode;
+	tif->tif_postencode = JPEGPostEncode;
+	tif->tif_encoderow = JPEGEncode;
+	tif->tif_encodestrip = JPEGEncode;
+	tif->tif_encodetile = JPEGEncode;  
+	tif->tif_cleanup = JPEGCleanup;
+	sp->defsparent = tif->tif_defstripsize;
+	tif->tif_defstripsize = JPEGDefaultStripSize;
+	sp->deftparent = tif->tif_deftilesize;
+	tif->tif_deftilesize = JPEGDefaultTileSize;
+	tif->tif_flags |= TIFF_NOBITREV;	/* no bit reversal, please */
+
+        sp->cinfo_initialized = FALSE;
+
+	/*
+        ** Create a JPEGTables field if no directory has yet been created. 
+        ** We do this just to ensure that sufficient space is reserved for
+        ** the JPEGTables field.  It will be properly created the right
+        ** size later. 
+        */
+        if( tif->tif_diroff == 0 )
+        {
+#define SIZE_OF_JPEGTABLES 2000
+/*
+The following line assumes incorrectly that all JPEG-in-TIFF files will have
+a JPEGTABLES tag generated and causes null-filled JPEGTABLES tags to be written
+when the JPEG data is placed with TIFFWriteRawStrip.  The field bit should be 
+set, anyway, later when actual JPEGTABLES header is generated, so removing it 
+here hopefully is harmless.
+            TIFFSetFieldBit(tif, FIELD_JPEGTABLES);
+*/
+            sp->jpegtables_length = SIZE_OF_JPEGTABLES;
+            sp->jpegtables = (void *) _TIFFmalloc(sp->jpegtables_length);
+	    // FIXME: NULL-deref after malloc failure
+	    _TIFFmemset(sp->jpegtables, 0, SIZE_OF_JPEGTABLES);
+#undef SIZE_OF_JPEGTABLES
+        }
+
+	return 1;
+}
+#endif /* JPEG_SUPPORT */
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tif_luv.c b/Source/LibTIFF4/tif_luv.c
index 113509c..ef9a941 100644
--- a/Source/LibTIFF4/tif_luv.c
+++ b/Source/LibTIFF4/tif_luv.c
@@ -1,1683 +1,1683 @@
-/* $Id: tif_luv.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * Copyright (c) 1997 Greg Ward Larson
- * Copyright (c) 1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler, Greg Larson and Silicon Graphics may not be used in any
- * advertising or publicity relating to the software without the specific,
- * prior written permission of Sam Leffler, Greg Larson and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER, GREG LARSON OR SILICON GRAPHICS BE LIABLE
- * FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-#include "tiffiop.h"
-#ifdef LOGLUV_SUPPORT
-
-/*
- * TIFF Library.
- * LogLuv compression support for high dynamic range images.
- *
- * Contributed by Greg Larson.
- *
- * LogLuv image support uses the TIFF library to store 16 or 10-bit
- * log luminance values with 8 bits each of u and v or a 14-bit index.
- *
- * The codec can take as input and produce as output 32-bit IEEE float values 
- * as well as 16-bit integer values.  A 16-bit luminance is interpreted
- * as a sign bit followed by a 15-bit integer that is converted
- * to and from a linear magnitude using the transformation:
- *
- *	L = 2^( (Le+.5)/256 - 64 )		# real from 15-bit
- *
- *	Le = floor( 256*(log2(L) + 64) )	# 15-bit from real
- *
- * The actual conversion to world luminance units in candelas per sq. meter
- * requires an additional multiplier, which is stored in the TIFFTAG_STONITS.
- * This value is usually set such that a reasonable exposure comes from
- * clamping decoded luminances above 1 to 1 in the displayed image.
- *
- * The 16-bit values for u and v may be converted to real values by dividing
- * each by 32768.  (This allows for negative values, which aren't useful as
- * far as we know, but are left in case of future improvements in human
- * color vision.)
- *
- * Conversion from (u,v), which is actually the CIE (u',v') system for
- * you color scientists, is accomplished by the following transformation:
- *
- *	u = 4*x / (-2*x + 12*y + 3)
- *	v = 9*y / (-2*x + 12*y + 3)
- *
- *	x = 9*u / (6*u - 16*v + 12)
- *	y = 4*v / (6*u - 16*v + 12)
- *
- * This process is greatly simplified by passing 32-bit IEEE floats
- * for each of three CIE XYZ coordinates.  The codec then takes care
- * of conversion to and from LogLuv, though the application is still
- * responsible for interpreting the TIFFTAG_STONITS calibration factor.
- *
- * By definition, a CIE XYZ vector of [1 1 1] corresponds to a neutral white
- * point of (x,y)=(1/3,1/3).  However, most color systems assume some other
- * white point, such as D65, and an absolute color conversion to XYZ then
- * to another color space with a different white point may introduce an
- * unwanted color cast to the image.  It is often desirable, therefore, to
- * perform a white point conversion that maps the input white to [1 1 1]
- * in XYZ, then record the original white point using the TIFFTAG_WHITEPOINT
- * tag value.  A decoder that demands absolute color calibration may use
- * this white point tag to get back the original colors, but usually it
- * will be ignored and the new white point will be used instead that
- * matches the output color space.
- *
- * Pixel information is compressed into one of two basic encodings, depending
- * on the setting of the compression tag, which is one of COMPRESSION_SGILOG
- * or COMPRESSION_SGILOG24.  For COMPRESSION_SGILOG, greyscale data is
- * stored as:
- *
- *	 1       15
- *	|-+---------------|
- *
- * COMPRESSION_SGILOG color data is stored as:
- *
- *	 1       15           8        8
- *	|-+---------------|--------+--------|
- *	 S       Le           ue       ve
- *
- * For the 24-bit COMPRESSION_SGILOG24 color format, the data is stored as:
- *
- *	     10           14
- *	|----------|--------------|
- *	     Le'          Ce
- *
- * There is no sign bit in the 24-bit case, and the (u,v) chromaticity is
- * encoded as an index for optimal color resolution.  The 10 log bits are
- * defined by the following conversions:
- *
- *	L = 2^((Le'+.5)/64 - 12)		# real from 10-bit
- *
- *	Le' = floor( 64*(log2(L) + 12) )	# 10-bit from real
- *
- * The 10 bits of the smaller format may be converted into the 15 bits of
- * the larger format by multiplying by 4 and adding 13314.  Obviously,
- * a smaller range of magnitudes is covered (about 5 orders of magnitude
- * instead of 38), and the lack of a sign bit means that negative luminances
- * are not allowed.  (Well, they aren't allowed in the real world, either,
- * but they are useful for certain types of image processing.)
- *
- * The desired user format is controlled by the setting the internal
- * pseudo tag TIFFTAG_SGILOGDATAFMT to one of:
- *  SGILOGDATAFMT_FLOAT       = IEEE 32-bit float XYZ values
- *  SGILOGDATAFMT_16BIT	      = 16-bit integer encodings of logL, u and v
- * Raw data i/o is also possible using:
- *  SGILOGDATAFMT_RAW         = 32-bit unsigned integer with encoded pixel
- * In addition, the following decoding is provided for ease of display:
- *  SGILOGDATAFMT_8BIT        = 8-bit default RGB gamma-corrected values
- *
- * For grayscale images, we provide the following data formats:
- *  SGILOGDATAFMT_FLOAT       = IEEE 32-bit float Y values
- *  SGILOGDATAFMT_16BIT       = 16-bit integer w/ encoded luminance
- *  SGILOGDATAFMT_8BIT        = 8-bit gray monitor values
- *
- * Note that the COMPRESSION_SGILOG applies a simple run-length encoding
- * scheme by separating the logL, u and v bytes for each row and applying
- * a PackBits type of compression.  Since the 24-bit encoding is not
- * adaptive, the 32-bit color format takes less space in many cases.
- *
- * Further control is provided over the conversion from higher-resolution
- * formats to final encoded values through the pseudo tag
- * TIFFTAG_SGILOGENCODE:
- *  SGILOGENCODE_NODITHER     = do not dither encoded values
- *  SGILOGENCODE_RANDITHER    = apply random dithering during encoding
- *
- * The default value of this tag is SGILOGENCODE_NODITHER for
- * COMPRESSION_SGILOG to maximize run-length encoding and
- * SGILOGENCODE_RANDITHER for COMPRESSION_SGILOG24 to turn
- * quantization errors into noise.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-
-/*
- * State block for each open TIFF
- * file using LogLuv compression/decompression.
- */
-typedef struct logLuvState LogLuvState;
-
-struct logLuvState {
-	int                     user_datafmt;   /* user data format */
-	int                     encode_meth;    /* encoding method */
-	int                     pixel_size;     /* bytes per pixel */
-
-	uint8*                  tbuf;           /* translation buffer */
-	tmsize_t                tbuflen;        /* buffer length */
-	void (*tfunc)(LogLuvState*, uint8*, tmsize_t);
-
-	TIFFVSetMethod          vgetparent;     /* super-class method */
-	TIFFVSetMethod          vsetparent;     /* super-class method */
-};
-
-#define DecoderState(tif)	((LogLuvState*) (tif)->tif_data)
-#define EncoderState(tif)	((LogLuvState*) (tif)->tif_data)
-
-#define SGILOGDATAFMT_UNKNOWN -1
-
-#define MINRUN 4 /* minimum run length */
-
-/*
- * Decode a string of 16-bit gray pixels.
- */
-static int
-LogL16Decode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
-{
-	static const char module[] = "LogL16Decode";
-	LogLuvState* sp = DecoderState(tif);
-	int shft;
-	tmsize_t i;
-	tmsize_t npixels;
-	unsigned char* bp;
-	int16* tp;
-	int16 b;
-	tmsize_t cc;
-	int rc;
-
-	assert(s == 0);
-	assert(sp != NULL);
-
-	npixels = occ / sp->pixel_size;
-
-	if (sp->user_datafmt == SGILOGDATAFMT_16BIT)
-		tp = (int16*) op;
-	else {
-		assert(sp->tbuflen >= npixels);
-		tp = (int16*) sp->tbuf;
-	}
-	_TIFFmemset((void*) tp, 0, npixels*sizeof (tp[0]));
-
-	bp = (unsigned char*) tif->tif_rawcp;
-	cc = tif->tif_rawcc;
-	/* get each byte string */
-	for (shft = 2*8; (shft -= 8) >= 0; ) {
-		for (i = 0; i < npixels && cc > 0; )
-			if (*bp >= 128) {		/* run */
-				rc = *bp++ + (2-128);   /* TODO: potential input buffer overrun when decoding corrupt or truncated data */
-				b = (int16)(*bp++ << shft);
-				cc -= 2;
-				while (rc-- && i < npixels)
-					tp[i++] |= b;
-			} else {			/* non-run */
-				rc = *bp++;		/* nul is noop */
-				while (--cc && rc-- && i < npixels)
-					tp[i++] |= (int16)*bp++ << shft;
-			}
-		if (i != npixels) {
-#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
-			TIFFErrorExt(tif->tif_clientdata, module,
-			    "Not enough data at row %lu (short %I64d pixels)",
-				     (unsigned long) tif->tif_row,
-				     (unsigned __int64) (npixels - i));
-#else
-			TIFFErrorExt(tif->tif_clientdata, module,
-			    "Not enough data at row %lu (short %llu pixels)",
-				     (unsigned long) tif->tif_row,
-				     (unsigned long long) (npixels - i));
-#endif
-			tif->tif_rawcp = (uint8*) bp;
-			tif->tif_rawcc = cc;
-			return (0);
-		}
-	}
-	(*sp->tfunc)(sp, op, npixels);
-	tif->tif_rawcp = (uint8*) bp;
-	tif->tif_rawcc = cc;
-	return (1);
-}
-
-/*
- * Decode a string of 24-bit pixels.
- */
-static int
-LogLuvDecode24(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
-{
-	static const char module[] = "LogLuvDecode24";
-	LogLuvState* sp = DecoderState(tif);
-	tmsize_t cc;
-	tmsize_t i;
-	tmsize_t npixels;
-	unsigned char* bp;
-	uint32* tp;
-
-	assert(s == 0);
-	assert(sp != NULL);
-
-	npixels = occ / sp->pixel_size;
-
-	if (sp->user_datafmt == SGILOGDATAFMT_RAW)
-		tp = (uint32 *)op;
-	else {
-		assert(sp->tbuflen >= npixels);
-		tp = (uint32 *) sp->tbuf;
-	}
-	/* copy to array of uint32 */
-	bp = (unsigned char*) tif->tif_rawcp;
-	cc = tif->tif_rawcc;
-	for (i = 0; i < npixels && cc > 0; i++) {
-		tp[i] = bp[0] << 16 | bp[1] << 8 | bp[2];
-		bp += 3;
-		cc -= 3;
-	}
-	tif->tif_rawcp = (uint8*) bp;
-	tif->tif_rawcc = cc;
-	if (i != npixels) {
-#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
-		TIFFErrorExt(tif->tif_clientdata, module,
-			"Not enough data at row %lu (short %I64d pixels)",
-			     (unsigned long) tif->tif_row,
-			     (unsigned __int64) (npixels - i));
-#else
-		TIFFErrorExt(tif->tif_clientdata, module,
-			"Not enough data at row %lu (short %llu pixels)",
-			     (unsigned long) tif->tif_row,
-			     (unsigned long long) (npixels - i));
-#endif
-		return (0);
-	}
-	(*sp->tfunc)(sp, op, npixels);
-	return (1);
-}
-
-/*
- * Decode a string of 32-bit pixels.
- */
-static int
-LogLuvDecode32(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
-{
-	static const char module[] = "LogLuvDecode32";
-	LogLuvState* sp;
-	int shft;
-	tmsize_t i;
-	tmsize_t npixels;
-	unsigned char* bp;
-	uint32* tp;
-	uint32 b;
-	tmsize_t cc;
-	int rc;
-
-	assert(s == 0);
-	sp = DecoderState(tif);
-	assert(sp != NULL);
-
-	npixels = occ / sp->pixel_size;
-
-	if (sp->user_datafmt == SGILOGDATAFMT_RAW)
-		tp = (uint32*) op;
-	else {
-		assert(sp->tbuflen >= npixels);
-		tp = (uint32*) sp->tbuf;
-	}
-	_TIFFmemset((void*) tp, 0, npixels*sizeof (tp[0]));
-
-	bp = (unsigned char*) tif->tif_rawcp;
-	cc = tif->tif_rawcc;
-	/* get each byte string */
-	for (shft = 4*8; (shft -= 8) >= 0; ) {
-		for (i = 0; i < npixels && cc > 0; )
-			if (*bp >= 128) {		/* run */
-				rc = *bp++ + (2-128);
-				b = (uint32)*bp++ << shft;
-				cc -= 2;                /* TODO: potential input buffer overrun when decoding corrupt or truncated data */
-				while (rc-- && i < npixels)
-					tp[i++] |= b;
-			} else {			/* non-run */
-				rc = *bp++;		/* nul is noop */
-				while (--cc && rc-- && i < npixels)
-					tp[i++] |= (uint32)*bp++ << shft;
-			}
-		if (i != npixels) {
-#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
-			TIFFErrorExt(tif->tif_clientdata, module,
-			"Not enough data at row %lu (short %I64d pixels)",
-				     (unsigned long) tif->tif_row,
-				     (unsigned __int64) (npixels - i));
-#else
-			TIFFErrorExt(tif->tif_clientdata, module,
-			"Not enough data at row %lu (short %llu pixels)",
-				     (unsigned long) tif->tif_row,
-				     (unsigned long long) (npixels - i));
-#endif
-			tif->tif_rawcp = (uint8*) bp;
-			tif->tif_rawcc = cc;
-			return (0);
-		}
-	}
-	(*sp->tfunc)(sp, op, npixels);
-	tif->tif_rawcp = (uint8*) bp;
-	tif->tif_rawcc = cc;
-	return (1);
-}
-
-/*
- * Decode a strip of pixels.  We break it into rows to
- * maintain synchrony with the encode algorithm, which
- * is row by row.
- */
-static int
-LogLuvDecodeStrip(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
-{
-	tmsize_t rowlen = TIFFScanlineSize(tif);
-
-	assert(cc%rowlen == 0);
-	while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s))
-		bp += rowlen, cc -= rowlen;
-	return (cc == 0);
-}
-
-/*
- * Decode a tile of pixels.  We break it into rows to
- * maintain synchrony with the encode algorithm, which
- * is row by row.
- */
-static int
-LogLuvDecodeTile(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
-{
-	tmsize_t rowlen = TIFFTileRowSize(tif);
-
-	assert(cc%rowlen == 0);
-	while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s))
-		bp += rowlen, cc -= rowlen;
-	return (cc == 0);
-}
-
-/*
- * Encode a row of 16-bit pixels.
- */
-static int
-LogL16Encode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
-{
-	LogLuvState* sp = EncoderState(tif);
-	int shft;
-	tmsize_t i;
-	tmsize_t j;
-	tmsize_t npixels;
-	uint8* op;
-	int16* tp;
-	int16 b;
-	tmsize_t occ;
-	int rc=0, mask;
-	tmsize_t beg;
-
-	assert(s == 0);
-	assert(sp != NULL);
-	npixels = cc / sp->pixel_size;
-
-	if (sp->user_datafmt == SGILOGDATAFMT_16BIT)
-		tp = (int16*) bp;
-	else {
-		tp = (int16*) sp->tbuf;
-		assert(sp->tbuflen >= npixels);
-		(*sp->tfunc)(sp, bp, npixels);
-	}
-	/* compress each byte string */
-	op = tif->tif_rawcp;
-	occ = tif->tif_rawdatasize - tif->tif_rawcc;
-	for (shft = 2*8; (shft -= 8) >= 0; )
-		for (i = 0; i < npixels; i += rc) {
-			if (occ < 4) {
-				tif->tif_rawcp = op;
-				tif->tif_rawcc = tif->tif_rawdatasize - occ;
-				if (!TIFFFlushData1(tif))
-					return (-1);
-				op = tif->tif_rawcp;
-				occ = tif->tif_rawdatasize - tif->tif_rawcc;
-			}
-			mask = 0xff << shft;		/* find next run */
-			for (beg = i; beg < npixels; beg += rc) {
-				b = (int16) (tp[beg] & mask);
-				rc = 1;
-				while (rc < 127+2 && beg+rc < npixels &&
-				    (tp[beg+rc] & mask) == b)
-					rc++;
-				if (rc >= MINRUN)
-					break;		/* long enough */
-			}
-			if (beg-i > 1 && beg-i < MINRUN) {
-				b = (int16) (tp[i] & mask);/*check short run */
-				j = i+1;
-				while ((tp[j++] & mask) == b)
-					if (j == beg) {
-						*op++ = (uint8)(128-2+j-i);
-						*op++ = (uint8)(b >> shft);
-						occ -= 2;
-						i = beg;
-						break;
-					}
-			}
-			while (i < beg) {		/* write out non-run */
-				if ((j = beg-i) > 127) j = 127;
-				if (occ < j+3) {
-					tif->tif_rawcp = op;
-					tif->tif_rawcc = tif->tif_rawdatasize - occ;
-					if (!TIFFFlushData1(tif))
-						return (-1);
-					op = tif->tif_rawcp;
-					occ = tif->tif_rawdatasize - tif->tif_rawcc;
-				}
-				*op++ = (uint8) j; occ--;
-				while (j--) {
-					*op++ = (uint8) (tp[i++] >> shft & 0xff);
-					occ--;
-				}
-			}
-			if (rc >= MINRUN) {		/* write out run */
-				*op++ = (uint8) (128-2+rc);
-				*op++ = (uint8) (tp[beg] >> shft & 0xff);
-				occ -= 2;
-			} else
-				rc = 0;
-		}
-	tif->tif_rawcp = op;
-	tif->tif_rawcc = tif->tif_rawdatasize - occ;
-
-	return (1);
-}
-
-/*
- * Encode a row of 24-bit pixels.
- */
-static int
-LogLuvEncode24(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
-{
-	LogLuvState* sp = EncoderState(tif);
-	tmsize_t i;
-	tmsize_t npixels;
-	tmsize_t occ;
-	uint8* op;
-	uint32* tp;
-
-	assert(s == 0);
-	assert(sp != NULL);
-	npixels = cc / sp->pixel_size;
-
-	if (sp->user_datafmt == SGILOGDATAFMT_RAW)
-		tp = (uint32*) bp;
-	else {
-		tp = (uint32*) sp->tbuf;
-		assert(sp->tbuflen >= npixels);
-		(*sp->tfunc)(sp, bp, npixels);
-	}
-	/* write out encoded pixels */
-	op = tif->tif_rawcp;
-	occ = tif->tif_rawdatasize - tif->tif_rawcc;
-	for (i = npixels; i--; ) {
-		if (occ < 3) {
-			tif->tif_rawcp = op;
-			tif->tif_rawcc = tif->tif_rawdatasize - occ;
-			if (!TIFFFlushData1(tif))
-				return (-1);
-			op = tif->tif_rawcp;
-			occ = tif->tif_rawdatasize - tif->tif_rawcc;
-		}
-		*op++ = (uint8)(*tp >> 16);
-		*op++ = (uint8)(*tp >> 8 & 0xff);
-		*op++ = (uint8)(*tp++ & 0xff);
-		occ -= 3;
-	}
-	tif->tif_rawcp = op;
-	tif->tif_rawcc = tif->tif_rawdatasize - occ;
-
-	return (1);
-}
-
-/*
- * Encode a row of 32-bit pixels.
- */
-static int
-LogLuvEncode32(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
-{
-	LogLuvState* sp = EncoderState(tif);
-	int shft;
-	tmsize_t i;
-	tmsize_t j;
-	tmsize_t npixels;
-	uint8* op;
-	uint32* tp;
-	uint32 b;
-	tmsize_t occ;
-	int rc=0, mask;
-	tmsize_t beg;
-
-	assert(s == 0);
-	assert(sp != NULL);
-
-	npixels = cc / sp->pixel_size;
-
-	if (sp->user_datafmt == SGILOGDATAFMT_RAW)
-		tp = (uint32*) bp;
-	else {
-		tp = (uint32*) sp->tbuf;
-		assert(sp->tbuflen >= npixels);
-		(*sp->tfunc)(sp, bp, npixels);
-	}
-	/* compress each byte string */
-	op = tif->tif_rawcp;
-	occ = tif->tif_rawdatasize - tif->tif_rawcc;
-	for (shft = 4*8; (shft -= 8) >= 0; )
-		for (i = 0; i < npixels; i += rc) {
-			if (occ < 4) {
-				tif->tif_rawcp = op;
-				tif->tif_rawcc = tif->tif_rawdatasize - occ;
-				if (!TIFFFlushData1(tif))
-					return (-1);
-				op = tif->tif_rawcp;
-				occ = tif->tif_rawdatasize - tif->tif_rawcc;
-			}
-			mask = 0xff << shft;		/* find next run */
-			for (beg = i; beg < npixels; beg += rc) {
-				b = tp[beg] & mask;
-				rc = 1;
-				while (rc < 127+2 && beg+rc < npixels &&
-						(tp[beg+rc] & mask) == b)
-					rc++;
-				if (rc >= MINRUN)
-					break;		/* long enough */
-			}
-			if (beg-i > 1 && beg-i < MINRUN) {
-				b = tp[i] & mask;	/* check short run */
-				j = i+1;
-				while ((tp[j++] & mask) == b)
-					if (j == beg) {
-						*op++ = (uint8)(128-2+j-i);
-						*op++ = (uint8)(b >> shft);
-						occ -= 2;
-						i = beg;
-						break;
-					}
-			}
-			while (i < beg) {		/* write out non-run */
-				if ((j = beg-i) > 127) j = 127;
-				if (occ < j+3) {
-					tif->tif_rawcp = op;
-					tif->tif_rawcc = tif->tif_rawdatasize - occ;
-					if (!TIFFFlushData1(tif))
-						return (-1);
-					op = tif->tif_rawcp;
-					occ = tif->tif_rawdatasize - tif->tif_rawcc;
-				}
-				*op++ = (uint8) j; occ--;
-				while (j--) {
-					*op++ = (uint8)(tp[i++] >> shft & 0xff);
-					occ--;
-				}
-			}
-			if (rc >= MINRUN) {		/* write out run */
-				*op++ = (uint8) (128-2+rc);
-				*op++ = (uint8)(tp[beg] >> shft & 0xff);
-				occ -= 2;
-			} else
-				rc = 0;
-		}
-	tif->tif_rawcp = op;
-	tif->tif_rawcc = tif->tif_rawdatasize - occ;
-
-	return (1);
-}
-
-/*
- * Encode a strip of pixels.  We break it into rows to
- * avoid encoding runs across row boundaries.
- */
-static int
-LogLuvEncodeStrip(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
-{
-	tmsize_t rowlen = TIFFScanlineSize(tif);
-
-	assert(cc%rowlen == 0);
-	while (cc && (*tif->tif_encoderow)(tif, bp, rowlen, s) == 1)
-		bp += rowlen, cc -= rowlen;
-	return (cc == 0);
-}
-
-/*
- * Encode a tile of pixels.  We break it into rows to
- * avoid encoding runs across row boundaries.
- */
-static int
-LogLuvEncodeTile(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
-{
-	tmsize_t rowlen = TIFFTileRowSize(tif);
-
-	assert(cc%rowlen == 0);
-	while (cc && (*tif->tif_encoderow)(tif, bp, rowlen, s) == 1)
-		bp += rowlen, cc -= rowlen;
-	return (cc == 0);
-}
-
-/*
- * Encode/Decode functions for converting to and from user formats.
- */
-
-#include "uvcode.h"
-
-#ifndef UVSCALE
-#define U_NEU		0.210526316
-#define V_NEU		0.473684211
-#define UVSCALE		410.
-#endif
-
-#ifndef	M_LN2
-#define M_LN2		0.69314718055994530942
-#endif
-#ifndef M_PI
-#define M_PI		3.14159265358979323846
-#endif
-#define log2(x)		((1./M_LN2)*log(x))
-#define exp2(x)		exp(M_LN2*(x))
-
-#define itrunc(x,m)	((m)==SGILOGENCODE_NODITHER ? \
-				(int)(x) : \
-				(int)((x) + rand()*(1./RAND_MAX) - .5))
-
-#if !LOGLUV_PUBLIC
-static
-#endif
-double
-LogL16toY(int p16)		/* compute luminance from 16-bit LogL */
-{
-	int	Le = p16 & 0x7fff;
-	double	Y;
-
-	if (!Le)
-		return (0.);
-	Y = exp(M_LN2/256.*(Le+.5) - M_LN2*64.);
-	return (!(p16 & 0x8000) ? Y : -Y);
-}
-
-#if !LOGLUV_PUBLIC
-static
-#endif
-int
-LogL16fromY(double Y, int em)	/* get 16-bit LogL from Y */
-{
-	if (Y >= 1.8371976e19)
-		return (0x7fff);
-	if (Y <= -1.8371976e19)
-		return (0xffff);
-	if (Y > 5.4136769e-20)
-		return itrunc(256.*(log2(Y) + 64.), em);
-	if (Y < -5.4136769e-20)
-		return (~0x7fff | itrunc(256.*(log2(-Y) + 64.), em));
-	return (0);
-}
-
-static void
-L16toY(LogLuvState* sp, uint8* op, tmsize_t n)
-{
-	int16* l16 = (int16*) sp->tbuf;
-	float* yp = (float*) op;
-
-	while (n-- > 0)
-		*yp++ = (float)LogL16toY(*l16++);
-}
-
-static void
-L16toGry(LogLuvState* sp, uint8* op, tmsize_t n)
-{
-	int16* l16 = (int16*) sp->tbuf;
-	uint8* gp = (uint8*) op;
-
-	while (n-- > 0) {
-		double Y = LogL16toY(*l16++);
-		*gp++ = (uint8) ((Y <= 0.) ? 0 : (Y >= 1.) ? 255 : (int)(256.*sqrt(Y)));
-	}
-}
-
-static void
-L16fromY(LogLuvState* sp, uint8* op, tmsize_t n)
-{
-	int16* l16 = (int16*) sp->tbuf;
-	float* yp = (float*) op;
-
-	while (n-- > 0)
-		*l16++ = (int16) (LogL16fromY(*yp++, sp->encode_meth));
-}
-
-#if !LOGLUV_PUBLIC
-static
-#endif
-void
-XYZtoRGB24(float xyz[3], uint8 rgb[3])
-{
-	double	r, g, b;
-					/* assume CCIR-709 primaries */
-	r =  2.690*xyz[0] + -1.276*xyz[1] + -0.414*xyz[2];
-	g = -1.022*xyz[0] +  1.978*xyz[1] +  0.044*xyz[2];
-	b =  0.061*xyz[0] + -0.224*xyz[1] +  1.163*xyz[2];
-					/* assume 2.0 gamma for speed */
-	/* could use integer sqrt approx., but this is probably faster */
-	rgb[0] = (uint8)((r<=0.) ? 0 : (r >= 1.) ? 255 : (int)(256.*sqrt(r)));
-	rgb[1] = (uint8)((g<=0.) ? 0 : (g >= 1.) ? 255 : (int)(256.*sqrt(g)));
-	rgb[2] = (uint8)((b<=0.) ? 0 : (b >= 1.) ? 255 : (int)(256.*sqrt(b)));
-}
-
-#if !LOGLUV_PUBLIC
-static
-#endif
-double
-LogL10toY(int p10)		/* compute luminance from 10-bit LogL */
-{
-	if (p10 == 0)
-		return (0.);
-	return (exp(M_LN2/64.*(p10+.5) - M_LN2*12.));
-}
-
-#if !LOGLUV_PUBLIC
-static
-#endif
-int
-LogL10fromY(double Y, int em)	/* get 10-bit LogL from Y */
-{
-	if (Y >= 15.742)
-		return (0x3ff);
-	else if (Y <= .00024283)
-		return (0);
-	else
-		return itrunc(64.*(log2(Y) + 12.), em);
-}
-
-#define NANGLES		100
-#define uv2ang(u, v)	( (NANGLES*.499999999/M_PI) \
-				* atan2((v)-V_NEU,(u)-U_NEU) + .5*NANGLES )
-
-static int
-oog_encode(double u, double v)		/* encode out-of-gamut chroma */
-{
-	static int	oog_table[NANGLES];
-	static int	initialized = 0;
-	register int	i;
-
-	if (!initialized) {		/* set up perimeter table */
-		double	eps[NANGLES], ua, va, ang, epsa;
-		int	ui, vi, ustep;
-		for (i = NANGLES; i--; )
-			eps[i] = 2.;
-		for (vi = UV_NVS; vi--; ) {
-			va = UV_VSTART + (vi+.5)*UV_SQSIZ;
-			ustep = uv_row[vi].nus-1;
-			if (vi == UV_NVS-1 || vi == 0 || ustep <= 0)
-				ustep = 1;
-			for (ui = uv_row[vi].nus-1; ui >= 0; ui -= ustep) {
-				ua = uv_row[vi].ustart + (ui+.5)*UV_SQSIZ;
-				ang = uv2ang(ua, va);
-				i = (int) ang;
-				epsa = fabs(ang - (i+.5));
-				if (epsa < eps[i]) {
-					oog_table[i] = uv_row[vi].ncum + ui;
-					eps[i] = epsa;
-				}
-			}
-		}
-		for (i = NANGLES; i--; )	/* fill any holes */
-			if (eps[i] > 1.5) {
-				int	i1, i2;
-				for (i1 = 1; i1 < NANGLES/2; i1++)
-					if (eps[(i+i1)%NANGLES] < 1.5)
-						break;
-				for (i2 = 1; i2 < NANGLES/2; i2++)
-					if (eps[(i+NANGLES-i2)%NANGLES] < 1.5)
-						break;
-				if (i1 < i2)
-					oog_table[i] =
-						oog_table[(i+i1)%NANGLES];
-				else
-					oog_table[i] =
-						oog_table[(i+NANGLES-i2)%NANGLES];
-			}
-		initialized = 1;
-	}
-	i = (int) uv2ang(u, v);		/* look up hue angle */
-	return (oog_table[i]);
-}
-
-#undef uv2ang
-#undef NANGLES
-
-#if !LOGLUV_PUBLIC
-static
-#endif
-int
-uv_encode(double u, double v, int em)	/* encode (u',v') coordinates */
-{
-	register int	vi, ui;
-
-	if (v < UV_VSTART)
-		return oog_encode(u, v);
-	vi = itrunc((v - UV_VSTART)*(1./UV_SQSIZ), em);
-	if (vi >= UV_NVS)
-		return oog_encode(u, v);
-	if (u < uv_row[vi].ustart)
-		return oog_encode(u, v);
-	ui = itrunc((u - uv_row[vi].ustart)*(1./UV_SQSIZ), em);
-	if (ui >= uv_row[vi].nus)
-		return oog_encode(u, v);
-
-	return (uv_row[vi].ncum + ui);
-}
-
-#if !LOGLUV_PUBLIC
-static
-#endif
-int
-uv_decode(double *up, double *vp, int c)	/* decode (u',v') index */
-{
-	int	upper, lower;
-	register int	ui, vi;
-
-	if (c < 0 || c >= UV_NDIVS)
-		return (-1);
-	lower = 0;				/* binary search */
-	upper = UV_NVS;
-	while (upper - lower > 1) {
-		vi = (lower + upper) >> 1;
-		ui = c - uv_row[vi].ncum;
-		if (ui > 0)
-			lower = vi;
-		else if (ui < 0)
-			upper = vi;
-		else {
-			lower = vi;
-			break;
-		}
-	}
-	vi = lower;
-	ui = c - uv_row[vi].ncum;
-	*up = uv_row[vi].ustart + (ui+.5)*UV_SQSIZ;
-	*vp = UV_VSTART + (vi+.5)*UV_SQSIZ;
-	return (0);
-}
-
-#if !LOGLUV_PUBLIC
-static
-#endif
-void
-LogLuv24toXYZ(uint32 p, float XYZ[3])
-{
-	int	Ce;
-	double	L, u, v, s, x, y;
-					/* decode luminance */
-	L = LogL10toY(p>>14 & 0x3ff);
-	if (L <= 0.) {
-		XYZ[0] = XYZ[1] = XYZ[2] = 0.;
-		return;
-	}
-					/* decode color */
-	Ce = p & 0x3fff;
-	if (uv_decode(&u, &v, Ce) < 0) {
-		u = U_NEU; v = V_NEU;
-	}
-	s = 1./(6.*u - 16.*v + 12.);
-	x = 9.*u * s;
-	y = 4.*v * s;
-					/* convert to XYZ */
-	XYZ[0] = (float)(x/y * L);
-	XYZ[1] = (float)L;
-	XYZ[2] = (float)((1.-x-y)/y * L);
-}
-
-#if !LOGLUV_PUBLIC
-static
-#endif
-uint32
-LogLuv24fromXYZ(float XYZ[3], int em)
-{
-	int	Le, Ce;
-	double	u, v, s;
-					/* encode luminance */
-	Le = LogL10fromY(XYZ[1], em);
-					/* encode color */
-	s = XYZ[0] + 15.*XYZ[1] + 3.*XYZ[2];
-	if (!Le || s <= 0.) {
-		u = U_NEU;
-		v = V_NEU;
-	} else {
-		u = 4.*XYZ[0] / s;
-		v = 9.*XYZ[1] / s;
-	}
-	Ce = uv_encode(u, v, em);
-	if (Ce < 0)			/* never happens */
-		Ce = uv_encode(U_NEU, V_NEU, SGILOGENCODE_NODITHER);
-					/* combine encodings */
-	return (Le << 14 | Ce);
-}
-
-static void
-Luv24toXYZ(LogLuvState* sp, uint8* op, tmsize_t n)
-{
-	uint32* luv = (uint32*) sp->tbuf;  
-	float* xyz = (float*) op;
-
-	while (n-- > 0) {
-		LogLuv24toXYZ(*luv, xyz);
-		xyz += 3;
-		luv++;
-	}
-}
-
-static void
-Luv24toLuv48(LogLuvState* sp, uint8* op, tmsize_t n)
-{
-	uint32* luv = (uint32*) sp->tbuf;  
-	int16* luv3 = (int16*) op;
-
-	while (n-- > 0) {
-		double u, v;
-
-		*luv3++ = (int16)((*luv >> 12 & 0xffd) + 13314);
-		if (uv_decode(&u, &v, *luv&0x3fff) < 0) {
-			u = U_NEU;
-			v = V_NEU;
-		}
-		*luv3++ = (int16)(u * (1L<<15));
-		*luv3++ = (int16)(v * (1L<<15));
-		luv++;
-	}
-}
-
-static void
-Luv24toRGB(LogLuvState* sp, uint8* op, tmsize_t n)
-{
-	uint32* luv = (uint32*) sp->tbuf;  
-	uint8* rgb = (uint8*) op;
-
-	while (n-- > 0) {
-		float xyz[3];
-
-		LogLuv24toXYZ(*luv++, xyz);
-		XYZtoRGB24(xyz, rgb);
-		rgb += 3;
-	}
-}
-
-static void
-Luv24fromXYZ(LogLuvState* sp, uint8* op, tmsize_t n)
-{
-	uint32* luv = (uint32*) sp->tbuf;  
-	float* xyz = (float*) op;
-
-	while (n-- > 0) {
-		*luv++ = LogLuv24fromXYZ(xyz, sp->encode_meth);
-		xyz += 3;
-	}
-}
-
-static void
-Luv24fromLuv48(LogLuvState* sp, uint8* op, tmsize_t n)
-{
-	uint32* luv = (uint32*) sp->tbuf;  
-	int16* luv3 = (int16*) op;
-
-	while (n-- > 0) {
-		int Le, Ce;
-
-		if (luv3[0] <= 0)
-			Le = 0;
-		else if (luv3[0] >= (1<<12)+3314)
-			Le = (1<<10) - 1;
-		else if (sp->encode_meth == SGILOGENCODE_NODITHER)
-			Le = (luv3[0]-3314) >> 2;
-		else
-			Le = itrunc(.25*(luv3[0]-3314.), sp->encode_meth);
-
-		Ce = uv_encode((luv3[1]+.5)/(1<<15), (luv3[2]+.5)/(1<<15),
-					sp->encode_meth);
-		if (Ce < 0)	/* never happens */
-			Ce = uv_encode(U_NEU, V_NEU, SGILOGENCODE_NODITHER);
-		*luv++ = (uint32)Le << 14 | Ce;
-		luv3 += 3;
-	}
-}
-
-#if !LOGLUV_PUBLIC
-static
-#endif
-void
-LogLuv32toXYZ(uint32 p, float XYZ[3])
-{
-	double	L, u, v, s, x, y;
-					/* decode luminance */
-	L = LogL16toY((int)p >> 16);
-	if (L <= 0.) {
-		XYZ[0] = XYZ[1] = XYZ[2] = 0.;
-		return;
-	}
-					/* decode color */
-	u = 1./UVSCALE * ((p>>8 & 0xff) + .5);
-	v = 1./UVSCALE * ((p & 0xff) + .5);
-	s = 1./(6.*u - 16.*v + 12.);
-	x = 9.*u * s;
-	y = 4.*v * s;
-					/* convert to XYZ */
-	XYZ[0] = (float)(x/y * L);
-	XYZ[1] = (float)L;
-	XYZ[2] = (float)((1.-x-y)/y * L);
-}
-
-#if !LOGLUV_PUBLIC
-static
-#endif
-uint32
-LogLuv32fromXYZ(float XYZ[3], int em)
-{
-	unsigned int	Le, ue, ve;
-	double	u, v, s;
-					/* encode luminance */
-	Le = (unsigned int)LogL16fromY(XYZ[1], em);
-					/* encode color */
-	s = XYZ[0] + 15.*XYZ[1] + 3.*XYZ[2];
-	if (!Le || s <= 0.) {
-		u = U_NEU;
-		v = V_NEU;
-	} else {
-		u = 4.*XYZ[0] / s;
-		v = 9.*XYZ[1] / s;
-	}
-	if (u <= 0.) ue = 0;
-	else ue = itrunc(UVSCALE*u, em);
-	if (ue > 255) ue = 255;
-	if (v <= 0.) ve = 0;
-	else ve = itrunc(UVSCALE*v, em);
-	if (ve > 255) ve = 255;
-					/* combine encodings */
-	return (Le << 16 | ue << 8 | ve);
-}
-
-static void
-Luv32toXYZ(LogLuvState* sp, uint8* op, tmsize_t n)
-{
-	uint32* luv = (uint32*) sp->tbuf;  
-	float* xyz = (float*) op;
-
-	while (n-- > 0) {
-		LogLuv32toXYZ(*luv++, xyz);
-		xyz += 3;
-	}
-}
-
-static void
-Luv32toLuv48(LogLuvState* sp, uint8* op, tmsize_t n)
-{
-	uint32* luv = (uint32*) sp->tbuf;  
-	int16* luv3 = (int16*) op;
-
-	while (n-- > 0) {
-		double u, v;
-
-		*luv3++ = (int16)(*luv >> 16);
-		u = 1./UVSCALE * ((*luv>>8 & 0xff) + .5);
-		v = 1./UVSCALE * ((*luv & 0xff) + .5);
-		*luv3++ = (int16)(u * (1L<<15));
-		*luv3++ = (int16)(v * (1L<<15));
-		luv++;
-	}
-}
-
-static void
-Luv32toRGB(LogLuvState* sp, uint8* op, tmsize_t n)
-{
-	uint32* luv = (uint32*) sp->tbuf;  
-	uint8* rgb = (uint8*) op;
-
-	while (n-- > 0) {
-		float xyz[3];
-
-		LogLuv32toXYZ(*luv++, xyz);
-		XYZtoRGB24(xyz, rgb);
-		rgb += 3;
-	}
-}
-
-static void
-Luv32fromXYZ(LogLuvState* sp, uint8* op, tmsize_t n)
-{
-	uint32* luv = (uint32*) sp->tbuf;  
-	float* xyz = (float*) op;
-
-	while (n-- > 0) {
-		*luv++ = LogLuv32fromXYZ(xyz, sp->encode_meth);
-		xyz += 3;
-	}
-}
-
-static void
-Luv32fromLuv48(LogLuvState* sp, uint8* op, tmsize_t n)
-{
-	uint32* luv = (uint32*) sp->tbuf;
-	int16* luv3 = (int16*) op;
-
-	if (sp->encode_meth == SGILOGENCODE_NODITHER) {
-		while (n-- > 0) {
-			*luv++ = (uint32)luv3[0] << 16 |
-				(luv3[1]*(uint32)(UVSCALE+.5) >> 7 & 0xff00) |
-				(luv3[2]*(uint32)(UVSCALE+.5) >> 15 & 0xff);
-			luv3 += 3;
-		}
-		return;
-	}
-	while (n-- > 0) {
-		*luv++ = (uint32)luv3[0] << 16 |
-	(itrunc(luv3[1]*(UVSCALE/(1<<15)), sp->encode_meth) << 8 & 0xff00) |
-		(itrunc(luv3[2]*(UVSCALE/(1<<15)), sp->encode_meth) & 0xff);
-		luv3 += 3;
-	}
-}
-
-static void
-_logLuvNop(LogLuvState* sp, uint8* op, tmsize_t n)
-{
-	(void) sp; (void) op; (void) n;
-}
-
-static int
-LogL16GuessDataFmt(TIFFDirectory *td)
-{
-#define	PACK(s,b,f)	(((b)<<6)|((s)<<3)|(f))
-	switch (PACK(td->td_samplesperpixel, td->td_bitspersample, td->td_sampleformat)) {
-	case PACK(1, 32, SAMPLEFORMAT_IEEEFP):
-		return (SGILOGDATAFMT_FLOAT);
-	case PACK(1, 16, SAMPLEFORMAT_VOID):
-	case PACK(1, 16, SAMPLEFORMAT_INT):
-	case PACK(1, 16, SAMPLEFORMAT_UINT):
-		return (SGILOGDATAFMT_16BIT);
-	case PACK(1,  8, SAMPLEFORMAT_VOID):
-	case PACK(1,  8, SAMPLEFORMAT_UINT):
-		return (SGILOGDATAFMT_8BIT);
-	}
-#undef PACK
-	return (SGILOGDATAFMT_UNKNOWN);
-}
-
-static tmsize_t
-multiply_ms(tmsize_t m1, tmsize_t m2)
-{
-	tmsize_t bytes = m1 * m2;
-
-	if (m1 && bytes / m1 != m2)
-		bytes = 0;
-
-	return bytes;
-}
-
-static int
-LogL16InitState(TIFF* tif)
-{
-	static const char module[] = "LogL16InitState";
-	TIFFDirectory *td = &tif->tif_dir;
-	LogLuvState* sp = DecoderState(tif);
-
-	assert(sp != NULL);
-	assert(td->td_photometric == PHOTOMETRIC_LOGL);
-
-	/* for some reason, we can't do this in TIFFInitLogL16 */
-	if (sp->user_datafmt == SGILOGDATAFMT_UNKNOWN)
-		sp->user_datafmt = LogL16GuessDataFmt(td);
-	switch (sp->user_datafmt) {
-	case SGILOGDATAFMT_FLOAT:
-		sp->pixel_size = sizeof (float);
-		break;
-	case SGILOGDATAFMT_16BIT:
-		sp->pixel_size = sizeof (int16);
-		break;
-	case SGILOGDATAFMT_8BIT:
-		sp->pixel_size = sizeof (uint8);
-		break;
-	default:
-		TIFFErrorExt(tif->tif_clientdata, module,
-		    "No support for converting user data format to LogL");
-		return (0);
-	}
-        if( isTiled(tif) )
-            sp->tbuflen = multiply_ms(td->td_tilewidth, td->td_tilelength);
-        else
-            sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_rowsperstrip);
-	if (multiply_ms(sp->tbuflen, sizeof (int16)) == 0 ||
-	    (sp->tbuf = (uint8*) _TIFFmalloc(sp->tbuflen * sizeof (int16))) == NULL) {
-		TIFFErrorExt(tif->tif_clientdata, module, "No space for SGILog translation buffer");
-		return (0);
-	}
-	return (1);
-}
-
-static int
-LogLuvGuessDataFmt(TIFFDirectory *td)
-{
-	int guess;
-
-	/*
-	 * If the user didn't tell us their datafmt,
-	 * take our best guess from the bitspersample.
-	 */
-#define	PACK(a,b)	(((a)<<3)|(b))
-	switch (PACK(td->td_bitspersample, td->td_sampleformat)) {
-	case PACK(32, SAMPLEFORMAT_IEEEFP):
-		guess = SGILOGDATAFMT_FLOAT;
-		break;
-	case PACK(32, SAMPLEFORMAT_VOID):
-	case PACK(32, SAMPLEFORMAT_UINT):
-	case PACK(32, SAMPLEFORMAT_INT):
-		guess = SGILOGDATAFMT_RAW;
-		break;
-	case PACK(16, SAMPLEFORMAT_VOID):
-	case PACK(16, SAMPLEFORMAT_INT):
-	case PACK(16, SAMPLEFORMAT_UINT):
-		guess = SGILOGDATAFMT_16BIT;
-		break;
-	case PACK( 8, SAMPLEFORMAT_VOID):
-	case PACK( 8, SAMPLEFORMAT_UINT):
-		guess = SGILOGDATAFMT_8BIT;
-		break;
-	default:
-		guess = SGILOGDATAFMT_UNKNOWN;
-		break;
-#undef PACK
-	}
-	/*
-	 * Double-check samples per pixel.
-	 */
-	switch (td->td_samplesperpixel) {
-	case 1:
-		if (guess != SGILOGDATAFMT_RAW)
-			guess = SGILOGDATAFMT_UNKNOWN;
-		break;
-	case 3:
-		if (guess == SGILOGDATAFMT_RAW)
-			guess = SGILOGDATAFMT_UNKNOWN;
-		break;
-	default:
-		guess = SGILOGDATAFMT_UNKNOWN;
-		break;
-	}
-	return (guess);
-}
-
-static int
-LogLuvInitState(TIFF* tif)
-{
-	static const char module[] = "LogLuvInitState";
-	TIFFDirectory* td = &tif->tif_dir;
-	LogLuvState* sp = DecoderState(tif);
-
-	assert(sp != NULL);
-	assert(td->td_photometric == PHOTOMETRIC_LOGLUV);
-
-	/* for some reason, we can't do this in TIFFInitLogLuv */
-	if (td->td_planarconfig != PLANARCONFIG_CONTIG) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-		    "SGILog compression cannot handle non-contiguous data");
-		return (0);
-	}
-	if (sp->user_datafmt == SGILOGDATAFMT_UNKNOWN)
-		sp->user_datafmt = LogLuvGuessDataFmt(td);
-	switch (sp->user_datafmt) {
-	case SGILOGDATAFMT_FLOAT:
-		sp->pixel_size = 3*sizeof (float);
-		break;
-	case SGILOGDATAFMT_16BIT:
-		sp->pixel_size = 3*sizeof (int16);
-		break;
-	case SGILOGDATAFMT_RAW:
-		sp->pixel_size = sizeof (uint32);
-		break;
-	case SGILOGDATAFMT_8BIT:
-		sp->pixel_size = 3*sizeof (uint8);
-		break;
-	default:
-		TIFFErrorExt(tif->tif_clientdata, module,
-		    "No support for converting user data format to LogLuv");
-		return (0);
-	}
-        if( isTiled(tif) )
-            sp->tbuflen = multiply_ms(td->td_tilewidth, td->td_tilelength);
-        else
-            sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_rowsperstrip);
-	if (multiply_ms(sp->tbuflen, sizeof (uint32)) == 0 ||
-	    (sp->tbuf = (uint8*) _TIFFmalloc(sp->tbuflen * sizeof (uint32))) == NULL) {
-		TIFFErrorExt(tif->tif_clientdata, module, "No space for SGILog translation buffer");
-		return (0);
-	}
-	return (1);
-}
-
-static int
-LogLuvFixupTags(TIFF* tif)
-{
-	(void) tif;
-	return (1);
-}
-
-static int
-LogLuvSetupDecode(TIFF* tif)
-{
-	static const char module[] = "LogLuvSetupDecode";
-	LogLuvState* sp = DecoderState(tif);
-	TIFFDirectory* td = &tif->tif_dir;
-
-	tif->tif_postdecode = _TIFFNoPostDecode;
-	switch (td->td_photometric) {
-	case PHOTOMETRIC_LOGLUV:
-		if (!LogLuvInitState(tif))
-			break;
-		if (td->td_compression == COMPRESSION_SGILOG24) {
-			tif->tif_decoderow = LogLuvDecode24;
-			switch (sp->user_datafmt) {
-			case SGILOGDATAFMT_FLOAT:
-				sp->tfunc = Luv24toXYZ;  
-				break;
-			case SGILOGDATAFMT_16BIT:
-				sp->tfunc = Luv24toLuv48;  
-				break;
-			case SGILOGDATAFMT_8BIT:
-				sp->tfunc = Luv24toRGB;
-				break;
-			}
-		} else {
-			tif->tif_decoderow = LogLuvDecode32;
-			switch (sp->user_datafmt) {
-			case SGILOGDATAFMT_FLOAT:
-				sp->tfunc = Luv32toXYZ;
-				break;
-			case SGILOGDATAFMT_16BIT:
-				sp->tfunc = Luv32toLuv48;
-				break;
-			case SGILOGDATAFMT_8BIT:
-				sp->tfunc = Luv32toRGB;
-				break;
-			}
-		}
-		return (1);
-	case PHOTOMETRIC_LOGL:
-		if (!LogL16InitState(tif))
-			break;
-		tif->tif_decoderow = LogL16Decode;
-		switch (sp->user_datafmt) {
-		case SGILOGDATAFMT_FLOAT:
-			sp->tfunc = L16toY;
-			break;
-		case SGILOGDATAFMT_8BIT:
-			sp->tfunc = L16toGry;
-			break;
-		}
-		return (1);
-	default:
-		TIFFErrorExt(tif->tif_clientdata, module,
-		    "Inappropriate photometric interpretation %d for SGILog compression; %s",
-		    td->td_photometric, "must be either LogLUV or LogL");
-		break;
-	}
-	return (0);
-}
-
-static int
-LogLuvSetupEncode(TIFF* tif)
-{
-	static const char module[] = "LogLuvSetupEncode";
-	LogLuvState* sp = EncoderState(tif);
-	TIFFDirectory* td = &tif->tif_dir;
-
-	switch (td->td_photometric) {
-	case PHOTOMETRIC_LOGLUV:
-		if (!LogLuvInitState(tif))
-			break;
-		if (td->td_compression == COMPRESSION_SGILOG24) {
-			tif->tif_encoderow = LogLuvEncode24;
-			switch (sp->user_datafmt) {
-			case SGILOGDATAFMT_FLOAT:
-				sp->tfunc = Luv24fromXYZ;
-				break;
-			case SGILOGDATAFMT_16BIT:
-				sp->tfunc = Luv24fromLuv48;  
-				break;
-			case SGILOGDATAFMT_RAW:
-				break;
-			default:
-				goto notsupported;
-			}
-		} else {
-			tif->tif_encoderow = LogLuvEncode32;  
-			switch (sp->user_datafmt) {
-			case SGILOGDATAFMT_FLOAT:
-				sp->tfunc = Luv32fromXYZ;  
-				break;
-			case SGILOGDATAFMT_16BIT:
-				sp->tfunc = Luv32fromLuv48;  
-				break;
-			case SGILOGDATAFMT_RAW:
-				break;
-			default:
-				goto notsupported;
-			}
-		}
-		break;
-	case PHOTOMETRIC_LOGL:
-		if (!LogL16InitState(tif))
-			break;
-		tif->tif_encoderow = LogL16Encode;  
-		switch (sp->user_datafmt) {
-		case SGILOGDATAFMT_FLOAT:
-			sp->tfunc = L16fromY;
-			break;
-		case SGILOGDATAFMT_16BIT:
-			break;
-		default:
-			goto notsupported;
-		}
-		break;
-	default:
-		TIFFErrorExt(tif->tif_clientdata, module,
-		    "Inappropriate photometric interpretation %d for SGILog compression; %s",
-		    td->td_photometric, "must be either LogLUV or LogL");
-		break;
-	}
-	return (1);
-notsupported:
-	TIFFErrorExt(tif->tif_clientdata, module,
-	    "SGILog compression supported only for %s, or raw data",
-	    td->td_photometric == PHOTOMETRIC_LOGL ? "Y, L" : "XYZ, Luv");
-	return (0);
-}
-
-static void
-LogLuvClose(TIFF* tif)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-
-	/*
-	 * For consistency, we always want to write out the same
-	 * bitspersample and sampleformat for our TIFF file,
-	 * regardless of the data format being used by the application.
-	 * Since this routine is called after tags have been set but
-	 * before they have been recorded in the file, we reset them here.
-	 */
-	td->td_samplesperpixel =
-	    (td->td_photometric == PHOTOMETRIC_LOGL) ? 1 : 3;
-	td->td_bitspersample = 16;
-	td->td_sampleformat = SAMPLEFORMAT_INT;
-}
-
-static void
-LogLuvCleanup(TIFF* tif)
-{
-	LogLuvState* sp = (LogLuvState *)tif->tif_data;
-
-	assert(sp != 0);
-
-	tif->tif_tagmethods.vgetfield = sp->vgetparent;
-	tif->tif_tagmethods.vsetfield = sp->vsetparent;
-
-	if (sp->tbuf)
-		_TIFFfree(sp->tbuf);
-	_TIFFfree(sp);
-	tif->tif_data = NULL;
-
-	_TIFFSetDefaultCompressionState(tif);
-}
-
-static int
-LogLuvVSetField(TIFF* tif, uint32 tag, va_list ap)
-{
-	static const char module[] = "LogLuvVSetField";
-	LogLuvState* sp = DecoderState(tif);
-	int bps, fmt;
-
-	switch (tag) {
-	case TIFFTAG_SGILOGDATAFMT:
-		sp->user_datafmt = (int) va_arg(ap, int);
-		/*
-		 * Tweak the TIFF header so that the rest of libtiff knows what
-		 * size of data will be passed between app and library, and
-		 * assume that the app knows what it is doing and is not
-		 * confused by these header manipulations...
-		 */
-		switch (sp->user_datafmt) {
-		case SGILOGDATAFMT_FLOAT:
-			bps = 32, fmt = SAMPLEFORMAT_IEEEFP;
-			break;
-		case SGILOGDATAFMT_16BIT:
-			bps = 16, fmt = SAMPLEFORMAT_INT;
-			break;
-		case SGILOGDATAFMT_RAW:
-			bps = 32, fmt = SAMPLEFORMAT_UINT;
-			TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
-			break;
-		case SGILOGDATAFMT_8BIT:
-			bps = 8, fmt = SAMPLEFORMAT_UINT;
-			break;
-		default:
-			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			    "Unknown data format %d for LogLuv compression",
-			    sp->user_datafmt);
-			return (0);
-		}
-		TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps);
-		TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, fmt);
-		/*
-		 * Must recalculate sizes should bits/sample change.
-		 */
-		tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t) -1;
-		tif->tif_scanlinesize = TIFFScanlineSize(tif);
-		return (1);
-	case TIFFTAG_SGILOGENCODE:
-		sp->encode_meth = (int) va_arg(ap, int);
-		if (sp->encode_meth != SGILOGENCODE_NODITHER &&
-		    sp->encode_meth != SGILOGENCODE_RANDITHER) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-			    "Unknown encoding %d for LogLuv compression",
-			    sp->encode_meth);
-			return (0);
-		}
-		return (1);
-	default:
-		return (*sp->vsetparent)(tif, tag, ap);
-	}
-}
-
-static int
-LogLuvVGetField(TIFF* tif, uint32 tag, va_list ap)
-{
-	LogLuvState *sp = (LogLuvState *)tif->tif_data;
-
-	switch (tag) {
-	case TIFFTAG_SGILOGDATAFMT:
-		*va_arg(ap, int*) = sp->user_datafmt;
-		return (1);
-	default:
-		return (*sp->vgetparent)(tif, tag, ap);
-	}
-}
-
-static const TIFFField LogLuvFields[] = {
-    { TIFFTAG_SGILOGDATAFMT, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "SGILogDataFmt", NULL},
-    { TIFFTAG_SGILOGENCODE, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "SGILogEncode", NULL}
-};
-
-int
-TIFFInitSGILog(TIFF* tif, int scheme)
-{
-	static const char module[] = "TIFFInitSGILog";
-	LogLuvState* sp;
-
-	assert(scheme == COMPRESSION_SGILOG24 || scheme == COMPRESSION_SGILOG);
-
-	/*
-	 * Merge codec-specific tag information.
-	 */
-	if (!_TIFFMergeFields(tif, LogLuvFields,
-			      TIFFArrayCount(LogLuvFields))) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-		    "Merging SGILog codec-specific tags failed");
-		return 0;
-	}
-
-	/*
-	 * Allocate state block so tag methods have storage to record values.
-	 */
-	tif->tif_data = (uint8*) _TIFFmalloc(sizeof (LogLuvState));
-	if (tif->tif_data == NULL)
-		goto bad;
-	sp = (LogLuvState*) tif->tif_data;
-	_TIFFmemset((void*)sp, 0, sizeof (*sp));
-	sp->user_datafmt = SGILOGDATAFMT_UNKNOWN;
-	sp->encode_meth = (scheme == COMPRESSION_SGILOG24) ?
-	    SGILOGENCODE_RANDITHER : SGILOGENCODE_NODITHER;
-	sp->tfunc = _logLuvNop;
-
-	/*
-	 * Install codec methods.
-	 * NB: tif_decoderow & tif_encoderow are filled
-	 *     in at setup time.
-	 */
-	tif->tif_fixuptags = LogLuvFixupTags;  
-	tif->tif_setupdecode = LogLuvSetupDecode;
-	tif->tif_decodestrip = LogLuvDecodeStrip;
-	tif->tif_decodetile = LogLuvDecodeTile;
-	tif->tif_setupencode = LogLuvSetupEncode;
-	tif->tif_encodestrip = LogLuvEncodeStrip;  
-	tif->tif_encodetile = LogLuvEncodeTile;
-	tif->tif_close = LogLuvClose;
-	tif->tif_cleanup = LogLuvCleanup;
-
-	/*
-	 * Override parent get/set field methods.
-	 */
-	sp->vgetparent = tif->tif_tagmethods.vgetfield;
-	tif->tif_tagmethods.vgetfield = LogLuvVGetField;   /* hook for codec tags */
-	sp->vsetparent = tif->tif_tagmethods.vsetfield;
-	tif->tif_tagmethods.vsetfield = LogLuvVSetField;   /* hook for codec tags */
-
-	return (1);
-bad:
-	TIFFErrorExt(tif->tif_clientdata, module,
-		     "%s: No space for LogLuv state block", tif->tif_name);
-	return (0);
-}
-#endif /* LOGLUV_SUPPORT */
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Id: tif_luv.c,v 1.11 2015/02/19 22:39:58 drolon Exp $ */
+
+/*
+ * Copyright (c) 1997 Greg Ward Larson
+ * Copyright (c) 1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and 
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler, Greg Larson and Silicon Graphics may not be used in any
+ * advertising or publicity relating to the software without the specific,
+ * prior written permission of Sam Leffler, Greg Larson and Silicon Graphics.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
+ * 
+ * IN NO EVENT SHALL SAM LEFFLER, GREG LARSON OR SILICON GRAPHICS BE LIABLE
+ * FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
+ * OF THIS SOFTWARE.
+ */
+
+#include "tiffiop.h"
+#ifdef LOGLUV_SUPPORT
+
+/*
+ * TIFF Library.
+ * LogLuv compression support for high dynamic range images.
+ *
+ * Contributed by Greg Larson.
+ *
+ * LogLuv image support uses the TIFF library to store 16 or 10-bit
+ * log luminance values with 8 bits each of u and v or a 14-bit index.
+ *
+ * The codec can take as input and produce as output 32-bit IEEE float values 
+ * as well as 16-bit integer values.  A 16-bit luminance is interpreted
+ * as a sign bit followed by a 15-bit integer that is converted
+ * to and from a linear magnitude using the transformation:
+ *
+ *	L = 2^( (Le+.5)/256 - 64 )		# real from 15-bit
+ *
+ *	Le = floor( 256*(log2(L) + 64) )	# 15-bit from real
+ *
+ * The actual conversion to world luminance units in candelas per sq. meter
+ * requires an additional multiplier, which is stored in the TIFFTAG_STONITS.
+ * This value is usually set such that a reasonable exposure comes from
+ * clamping decoded luminances above 1 to 1 in the displayed image.
+ *
+ * The 16-bit values for u and v may be converted to real values by dividing
+ * each by 32768.  (This allows for negative values, which aren't useful as
+ * far as we know, but are left in case of future improvements in human
+ * color vision.)
+ *
+ * Conversion from (u,v), which is actually the CIE (u',v') system for
+ * you color scientists, is accomplished by the following transformation:
+ *
+ *	u = 4*x / (-2*x + 12*y + 3)
+ *	v = 9*y / (-2*x + 12*y + 3)
+ *
+ *	x = 9*u / (6*u - 16*v + 12)
+ *	y = 4*v / (6*u - 16*v + 12)
+ *
+ * This process is greatly simplified by passing 32-bit IEEE floats
+ * for each of three CIE XYZ coordinates.  The codec then takes care
+ * of conversion to and from LogLuv, though the application is still
+ * responsible for interpreting the TIFFTAG_STONITS calibration factor.
+ *
+ * By definition, a CIE XYZ vector of [1 1 1] corresponds to a neutral white
+ * point of (x,y)=(1/3,1/3).  However, most color systems assume some other
+ * white point, such as D65, and an absolute color conversion to XYZ then
+ * to another color space with a different white point may introduce an
+ * unwanted color cast to the image.  It is often desirable, therefore, to
+ * perform a white point conversion that maps the input white to [1 1 1]
+ * in XYZ, then record the original white point using the TIFFTAG_WHITEPOINT
+ * tag value.  A decoder that demands absolute color calibration may use
+ * this white point tag to get back the original colors, but usually it
+ * will be ignored and the new white point will be used instead that
+ * matches the output color space.
+ *
+ * Pixel information is compressed into one of two basic encodings, depending
+ * on the setting of the compression tag, which is one of COMPRESSION_SGILOG
+ * or COMPRESSION_SGILOG24.  For COMPRESSION_SGILOG, greyscale data is
+ * stored as:
+ *
+ *	 1       15
+ *	|-+---------------|
+ *
+ * COMPRESSION_SGILOG color data is stored as:
+ *
+ *	 1       15           8        8
+ *	|-+---------------|--------+--------|
+ *	 S       Le           ue       ve
+ *
+ * For the 24-bit COMPRESSION_SGILOG24 color format, the data is stored as:
+ *
+ *	     10           14
+ *	|----------|--------------|
+ *	     Le'          Ce
+ *
+ * There is no sign bit in the 24-bit case, and the (u,v) chromaticity is
+ * encoded as an index for optimal color resolution.  The 10 log bits are
+ * defined by the following conversions:
+ *
+ *	L = 2^((Le'+.5)/64 - 12)		# real from 10-bit
+ *
+ *	Le' = floor( 64*(log2(L) + 12) )	# 10-bit from real
+ *
+ * The 10 bits of the smaller format may be converted into the 15 bits of
+ * the larger format by multiplying by 4 and adding 13314.  Obviously,
+ * a smaller range of magnitudes is covered (about 5 orders of magnitude
+ * instead of 38), and the lack of a sign bit means that negative luminances
+ * are not allowed.  (Well, they aren't allowed in the real world, either,
+ * but they are useful for certain types of image processing.)
+ *
+ * The desired user format is controlled by the setting the internal
+ * pseudo tag TIFFTAG_SGILOGDATAFMT to one of:
+ *  SGILOGDATAFMT_FLOAT       = IEEE 32-bit float XYZ values
+ *  SGILOGDATAFMT_16BIT	      = 16-bit integer encodings of logL, u and v
+ * Raw data i/o is also possible using:
+ *  SGILOGDATAFMT_RAW         = 32-bit unsigned integer with encoded pixel
+ * In addition, the following decoding is provided for ease of display:
+ *  SGILOGDATAFMT_8BIT        = 8-bit default RGB gamma-corrected values
+ *
+ * For grayscale images, we provide the following data formats:
+ *  SGILOGDATAFMT_FLOAT       = IEEE 32-bit float Y values
+ *  SGILOGDATAFMT_16BIT       = 16-bit integer w/ encoded luminance
+ *  SGILOGDATAFMT_8BIT        = 8-bit gray monitor values
+ *
+ * Note that the COMPRESSION_SGILOG applies a simple run-length encoding
+ * scheme by separating the logL, u and v bytes for each row and applying
+ * a PackBits type of compression.  Since the 24-bit encoding is not
+ * adaptive, the 32-bit color format takes less space in many cases.
+ *
+ * Further control is provided over the conversion from higher-resolution
+ * formats to final encoded values through the pseudo tag
+ * TIFFTAG_SGILOGENCODE:
+ *  SGILOGENCODE_NODITHER     = do not dither encoded values
+ *  SGILOGENCODE_RANDITHER    = apply random dithering during encoding
+ *
+ * The default value of this tag is SGILOGENCODE_NODITHER for
+ * COMPRESSION_SGILOG to maximize run-length encoding and
+ * SGILOGENCODE_RANDITHER for COMPRESSION_SGILOG24 to turn
+ * quantization errors into noise.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+/*
+ * State block for each open TIFF
+ * file using LogLuv compression/decompression.
+ */
+typedef struct logLuvState LogLuvState;
+
+struct logLuvState {
+	int                     user_datafmt;   /* user data format */
+	int                     encode_meth;    /* encoding method */
+	int                     pixel_size;     /* bytes per pixel */
+
+	uint8*                  tbuf;           /* translation buffer */
+	tmsize_t                tbuflen;        /* buffer length */
+	void (*tfunc)(LogLuvState*, uint8*, tmsize_t);
+
+	TIFFVSetMethod          vgetparent;     /* super-class method */
+	TIFFVSetMethod          vsetparent;     /* super-class method */
+};
+
+#define DecoderState(tif)	((LogLuvState*) (tif)->tif_data)
+#define EncoderState(tif)	((LogLuvState*) (tif)->tif_data)
+
+#define SGILOGDATAFMT_UNKNOWN -1
+
+#define MINRUN 4 /* minimum run length */
+
+/*
+ * Decode a string of 16-bit gray pixels.
+ */
+static int
+LogL16Decode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
+{
+	static const char module[] = "LogL16Decode";
+	LogLuvState* sp = DecoderState(tif);
+	int shft;
+	tmsize_t i;
+	tmsize_t npixels;
+	unsigned char* bp;
+	int16* tp;
+	int16 b;
+	tmsize_t cc;
+	int rc;
+
+	assert(s == 0);
+	assert(sp != NULL);
+
+	npixels = occ / sp->pixel_size;
+
+	if (sp->user_datafmt == SGILOGDATAFMT_16BIT)
+		tp = (int16*) op;
+	else {
+		assert(sp->tbuflen >= npixels);
+		tp = (int16*) sp->tbuf;
+	}
+	_TIFFmemset((void*) tp, 0, npixels*sizeof (tp[0]));
+
+	bp = (unsigned char*) tif->tif_rawcp;
+	cc = tif->tif_rawcc;
+	/* get each byte string */
+	for (shft = 2*8; (shft -= 8) >= 0; ) {
+		for (i = 0; i < npixels && cc > 0; )
+			if (*bp >= 128) {		/* run */
+				rc = *bp++ + (2-128);   /* TODO: potential input buffer overrun when decoding corrupt or truncated data */
+				b = (int16)(*bp++ << shft);
+				cc -= 2;
+				while (rc-- && i < npixels)
+					tp[i++] |= b;
+			} else {			/* non-run */
+				rc = *bp++;		/* nul is noop */
+				while (--cc && rc-- && i < npixels)
+					tp[i++] |= (int16)*bp++ << shft;
+			}
+		if (i != npixels) {
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+			TIFFErrorExt(tif->tif_clientdata, module,
+			    "Not enough data at row %lu (short %I64d pixels)",
+				     (unsigned long) tif->tif_row,
+				     (unsigned __int64) (npixels - i));
+#else
+			TIFFErrorExt(tif->tif_clientdata, module,
+			    "Not enough data at row %lu (short %llu pixels)",
+				     (unsigned long) tif->tif_row,
+				     (unsigned long long) (npixels - i));
+#endif
+			tif->tif_rawcp = (uint8*) bp;
+			tif->tif_rawcc = cc;
+			return (0);
+		}
+	}
+	(*sp->tfunc)(sp, op, npixels);
+	tif->tif_rawcp = (uint8*) bp;
+	tif->tif_rawcc = cc;
+	return (1);
+}
+
+/*
+ * Decode a string of 24-bit pixels.
+ */
+static int
+LogLuvDecode24(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
+{
+	static const char module[] = "LogLuvDecode24";
+	LogLuvState* sp = DecoderState(tif);
+	tmsize_t cc;
+	tmsize_t i;
+	tmsize_t npixels;
+	unsigned char* bp;
+	uint32* tp;
+
+	assert(s == 0);
+	assert(sp != NULL);
+
+	npixels = occ / sp->pixel_size;
+
+	if (sp->user_datafmt == SGILOGDATAFMT_RAW)
+		tp = (uint32 *)op;
+	else {
+		assert(sp->tbuflen >= npixels);
+		tp = (uint32 *) sp->tbuf;
+	}
+	/* copy to array of uint32 */
+	bp = (unsigned char*) tif->tif_rawcp;
+	cc = tif->tif_rawcc;
+	for (i = 0; i < npixels && cc > 0; i++) {
+		tp[i] = bp[0] << 16 | bp[1] << 8 | bp[2];
+		bp += 3;
+		cc -= 3;
+	}
+	tif->tif_rawcp = (uint8*) bp;
+	tif->tif_rawcc = cc;
+	if (i != npixels) {
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+		TIFFErrorExt(tif->tif_clientdata, module,
+			"Not enough data at row %lu (short %I64d pixels)",
+			     (unsigned long) tif->tif_row,
+			     (unsigned __int64) (npixels - i));
+#else
+		TIFFErrorExt(tif->tif_clientdata, module,
+			"Not enough data at row %lu (short %llu pixels)",
+			     (unsigned long) tif->tif_row,
+			     (unsigned long long) (npixels - i));
+#endif
+		return (0);
+	}
+	(*sp->tfunc)(sp, op, npixels);
+	return (1);
+}
+
+/*
+ * Decode a string of 32-bit pixels.
+ */
+static int
+LogLuvDecode32(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
+{
+	static const char module[] = "LogLuvDecode32";
+	LogLuvState* sp;
+	int shft;
+	tmsize_t i;
+	tmsize_t npixels;
+	unsigned char* bp;
+	uint32* tp;
+	uint32 b;
+	tmsize_t cc;
+	int rc;
+
+	assert(s == 0);
+	sp = DecoderState(tif);
+	assert(sp != NULL);
+
+	npixels = occ / sp->pixel_size;
+
+	if (sp->user_datafmt == SGILOGDATAFMT_RAW)
+		tp = (uint32*) op;
+	else {
+		assert(sp->tbuflen >= npixels);
+		tp = (uint32*) sp->tbuf;
+	}
+	_TIFFmemset((void*) tp, 0, npixels*sizeof (tp[0]));
+
+	bp = (unsigned char*) tif->tif_rawcp;
+	cc = tif->tif_rawcc;
+	/* get each byte string */
+	for (shft = 4*8; (shft -= 8) >= 0; ) {
+		for (i = 0; i < npixels && cc > 0; )
+			if (*bp >= 128) {		/* run */
+				rc = *bp++ + (2-128);
+				b = (uint32)*bp++ << shft;
+				cc -= 2;                /* TODO: potential input buffer overrun when decoding corrupt or truncated data */
+				while (rc-- && i < npixels)
+					tp[i++] |= b;
+			} else {			/* non-run */
+				rc = *bp++;		/* nul is noop */
+				while (--cc && rc-- && i < npixels)
+					tp[i++] |= (uint32)*bp++ << shft;
+			}
+		if (i != npixels) {
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+			TIFFErrorExt(tif->tif_clientdata, module,
+			"Not enough data at row %lu (short %I64d pixels)",
+				     (unsigned long) tif->tif_row,
+				     (unsigned __int64) (npixels - i));
+#else
+			TIFFErrorExt(tif->tif_clientdata, module,
+			"Not enough data at row %lu (short %llu pixels)",
+				     (unsigned long) tif->tif_row,
+				     (unsigned long long) (npixels - i));
+#endif
+			tif->tif_rawcp = (uint8*) bp;
+			tif->tif_rawcc = cc;
+			return (0);
+		}
+	}
+	(*sp->tfunc)(sp, op, npixels);
+	tif->tif_rawcp = (uint8*) bp;
+	tif->tif_rawcc = cc;
+	return (1);
+}
+
+/*
+ * Decode a strip of pixels.  We break it into rows to
+ * maintain synchrony with the encode algorithm, which
+ * is row by row.
+ */
+static int
+LogLuvDecodeStrip(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
+{
+	tmsize_t rowlen = TIFFScanlineSize(tif);
+
+	assert(cc%rowlen == 0);
+	while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s))
+		bp += rowlen, cc -= rowlen;
+	return (cc == 0);
+}
+
+/*
+ * Decode a tile of pixels.  We break it into rows to
+ * maintain synchrony with the encode algorithm, which
+ * is row by row.
+ */
+static int
+LogLuvDecodeTile(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
+{
+	tmsize_t rowlen = TIFFTileRowSize(tif);
+
+	assert(cc%rowlen == 0);
+	while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s))
+		bp += rowlen, cc -= rowlen;
+	return (cc == 0);
+}
+
+/*
+ * Encode a row of 16-bit pixels.
+ */
+static int
+LogL16Encode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
+{
+	LogLuvState* sp = EncoderState(tif);
+	int shft;
+	tmsize_t i;
+	tmsize_t j;
+	tmsize_t npixels;
+	uint8* op;
+	int16* tp;
+	int16 b;
+	tmsize_t occ;
+	int rc=0, mask;
+	tmsize_t beg;
+
+	assert(s == 0);
+	assert(sp != NULL);
+	npixels = cc / sp->pixel_size;
+
+	if (sp->user_datafmt == SGILOGDATAFMT_16BIT)
+		tp = (int16*) bp;
+	else {
+		tp = (int16*) sp->tbuf;
+		assert(sp->tbuflen >= npixels);
+		(*sp->tfunc)(sp, bp, npixels);
+	}
+	/* compress each byte string */
+	op = tif->tif_rawcp;
+	occ = tif->tif_rawdatasize - tif->tif_rawcc;
+	for (shft = 2*8; (shft -= 8) >= 0; )
+		for (i = 0; i < npixels; i += rc) {
+			if (occ < 4) {
+				tif->tif_rawcp = op;
+				tif->tif_rawcc = tif->tif_rawdatasize - occ;
+				if (!TIFFFlushData1(tif))
+					return (-1);
+				op = tif->tif_rawcp;
+				occ = tif->tif_rawdatasize - tif->tif_rawcc;
+			}
+			mask = 0xff << shft;		/* find next run */
+			for (beg = i; beg < npixels; beg += rc) {
+				b = (int16) (tp[beg] & mask);
+				rc = 1;
+				while (rc < 127+2 && beg+rc < npixels &&
+				    (tp[beg+rc] & mask) == b)
+					rc++;
+				if (rc >= MINRUN)
+					break;		/* long enough */
+			}
+			if (beg-i > 1 && beg-i < MINRUN) {
+				b = (int16) (tp[i] & mask);/*check short run */
+				j = i+1;
+				while ((tp[j++] & mask) == b)
+					if (j == beg) {
+						*op++ = (uint8)(128-2+j-i);
+						*op++ = (uint8)(b >> shft);
+						occ -= 2;
+						i = beg;
+						break;
+					}
+			}
+			while (i < beg) {		/* write out non-run */
+				if ((j = beg-i) > 127) j = 127;
+				if (occ < j+3) {
+					tif->tif_rawcp = op;
+					tif->tif_rawcc = tif->tif_rawdatasize - occ;
+					if (!TIFFFlushData1(tif))
+						return (-1);
+					op = tif->tif_rawcp;
+					occ = tif->tif_rawdatasize - tif->tif_rawcc;
+				}
+				*op++ = (uint8) j; occ--;
+				while (j--) {
+					*op++ = (uint8) (tp[i++] >> shft & 0xff);
+					occ--;
+				}
+			}
+			if (rc >= MINRUN) {		/* write out run */
+				*op++ = (uint8) (128-2+rc);
+				*op++ = (uint8) (tp[beg] >> shft & 0xff);
+				occ -= 2;
+			} else
+				rc = 0;
+		}
+	tif->tif_rawcp = op;
+	tif->tif_rawcc = tif->tif_rawdatasize - occ;
+
+	return (1);
+}
+
+/*
+ * Encode a row of 24-bit pixels.
+ */
+static int
+LogLuvEncode24(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
+{
+	LogLuvState* sp = EncoderState(tif);
+	tmsize_t i;
+	tmsize_t npixels;
+	tmsize_t occ;
+	uint8* op;
+	uint32* tp;
+
+	assert(s == 0);
+	assert(sp != NULL);
+	npixels = cc / sp->pixel_size;
+
+	if (sp->user_datafmt == SGILOGDATAFMT_RAW)
+		tp = (uint32*) bp;
+	else {
+		tp = (uint32*) sp->tbuf;
+		assert(sp->tbuflen >= npixels);
+		(*sp->tfunc)(sp, bp, npixels);
+	}
+	/* write out encoded pixels */
+	op = tif->tif_rawcp;
+	occ = tif->tif_rawdatasize - tif->tif_rawcc;
+	for (i = npixels; i--; ) {
+		if (occ < 3) {
+			tif->tif_rawcp = op;
+			tif->tif_rawcc = tif->tif_rawdatasize - occ;
+			if (!TIFFFlushData1(tif))
+				return (-1);
+			op = tif->tif_rawcp;
+			occ = tif->tif_rawdatasize - tif->tif_rawcc;
+		}
+		*op++ = (uint8)(*tp >> 16);
+		*op++ = (uint8)(*tp >> 8 & 0xff);
+		*op++ = (uint8)(*tp++ & 0xff);
+		occ -= 3;
+	}
+	tif->tif_rawcp = op;
+	tif->tif_rawcc = tif->tif_rawdatasize - occ;
+
+	return (1);
+}
+
+/*
+ * Encode a row of 32-bit pixels.
+ */
+static int
+LogLuvEncode32(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
+{
+	LogLuvState* sp = EncoderState(tif);
+	int shft;
+	tmsize_t i;
+	tmsize_t j;
+	tmsize_t npixels;
+	uint8* op;
+	uint32* tp;
+	uint32 b;
+	tmsize_t occ;
+	int rc=0, mask;
+	tmsize_t beg;
+
+	assert(s == 0);
+	assert(sp != NULL);
+
+	npixels = cc / sp->pixel_size;
+
+	if (sp->user_datafmt == SGILOGDATAFMT_RAW)
+		tp = (uint32*) bp;
+	else {
+		tp = (uint32*) sp->tbuf;
+		assert(sp->tbuflen >= npixels);
+		(*sp->tfunc)(sp, bp, npixels);
+	}
+	/* compress each byte string */
+	op = tif->tif_rawcp;
+	occ = tif->tif_rawdatasize - tif->tif_rawcc;
+	for (shft = 4*8; (shft -= 8) >= 0; )
+		for (i = 0; i < npixels; i += rc) {
+			if (occ < 4) {
+				tif->tif_rawcp = op;
+				tif->tif_rawcc = tif->tif_rawdatasize - occ;
+				if (!TIFFFlushData1(tif))
+					return (-1);
+				op = tif->tif_rawcp;
+				occ = tif->tif_rawdatasize - tif->tif_rawcc;
+			}
+			mask = 0xff << shft;		/* find next run */
+			for (beg = i; beg < npixels; beg += rc) {
+				b = tp[beg] & mask;
+				rc = 1;
+				while (rc < 127+2 && beg+rc < npixels &&
+						(tp[beg+rc] & mask) == b)
+					rc++;
+				if (rc >= MINRUN)
+					break;		/* long enough */
+			}
+			if (beg-i > 1 && beg-i < MINRUN) {
+				b = tp[i] & mask;	/* check short run */
+				j = i+1;
+				while ((tp[j++] & mask) == b)
+					if (j == beg) {
+						*op++ = (uint8)(128-2+j-i);
+						*op++ = (uint8)(b >> shft);
+						occ -= 2;
+						i = beg;
+						break;
+					}
+			}
+			while (i < beg) {		/* write out non-run */
+				if ((j = beg-i) > 127) j = 127;
+				if (occ < j+3) {
+					tif->tif_rawcp = op;
+					tif->tif_rawcc = tif->tif_rawdatasize - occ;
+					if (!TIFFFlushData1(tif))
+						return (-1);
+					op = tif->tif_rawcp;
+					occ = tif->tif_rawdatasize - tif->tif_rawcc;
+				}
+				*op++ = (uint8) j; occ--;
+				while (j--) {
+					*op++ = (uint8)(tp[i++] >> shft & 0xff);
+					occ--;
+				}
+			}
+			if (rc >= MINRUN) {		/* write out run */
+				*op++ = (uint8) (128-2+rc);
+				*op++ = (uint8)(tp[beg] >> shft & 0xff);
+				occ -= 2;
+			} else
+				rc = 0;
+		}
+	tif->tif_rawcp = op;
+	tif->tif_rawcc = tif->tif_rawdatasize - occ;
+
+	return (1);
+}
+
+/*
+ * Encode a strip of pixels.  We break it into rows to
+ * avoid encoding runs across row boundaries.
+ */
+static int
+LogLuvEncodeStrip(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
+{
+	tmsize_t rowlen = TIFFScanlineSize(tif);
+
+	assert(cc%rowlen == 0);
+	while (cc && (*tif->tif_encoderow)(tif, bp, rowlen, s) == 1)
+		bp += rowlen, cc -= rowlen;
+	return (cc == 0);
+}
+
+/*
+ * Encode a tile of pixels.  We break it into rows to
+ * avoid encoding runs across row boundaries.
+ */
+static int
+LogLuvEncodeTile(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
+{
+	tmsize_t rowlen = TIFFTileRowSize(tif);
+
+	assert(cc%rowlen == 0);
+	while (cc && (*tif->tif_encoderow)(tif, bp, rowlen, s) == 1)
+		bp += rowlen, cc -= rowlen;
+	return (cc == 0);
+}
+
+/*
+ * Encode/Decode functions for converting to and from user formats.
+ */
+
+#include "uvcode.h"
+
+#ifndef UVSCALE
+#define U_NEU		0.210526316
+#define V_NEU		0.473684211
+#define UVSCALE		410.
+#endif
+
+#ifndef	M_LN2
+#define M_LN2		0.69314718055994530942
+#endif
+#ifndef M_PI
+#define M_PI		3.14159265358979323846
+#endif
+#define log2(x)		((1./M_LN2)*log(x))
+#define exp2(x)		exp(M_LN2*(x))
+
+#define itrunc(x,m)	((m)==SGILOGENCODE_NODITHER ? \
+				(int)(x) : \
+				(int)((x) + rand()*(1./RAND_MAX) - .5))
+
+#if !LOGLUV_PUBLIC
+static
+#endif
+double
+LogL16toY(int p16)		/* compute luminance from 16-bit LogL */
+{
+	int	Le = p16 & 0x7fff;
+	double	Y;
+
+	if (!Le)
+		return (0.);
+	Y = exp(M_LN2/256.*(Le+.5) - M_LN2*64.);
+	return (!(p16 & 0x8000) ? Y : -Y);
+}
+
+#if !LOGLUV_PUBLIC
+static
+#endif
+int
+LogL16fromY(double Y, int em)	/* get 16-bit LogL from Y */
+{
+	if (Y >= 1.8371976e19)
+		return (0x7fff);
+	if (Y <= -1.8371976e19)
+		return (0xffff);
+	if (Y > 5.4136769e-20)
+		return itrunc(256.*(log2(Y) + 64.), em);
+	if (Y < -5.4136769e-20)
+		return (~0x7fff | itrunc(256.*(log2(-Y) + 64.), em));
+	return (0);
+}
+
+static void
+L16toY(LogLuvState* sp, uint8* op, tmsize_t n)
+{
+	int16* l16 = (int16*) sp->tbuf;
+	float* yp = (float*) op;
+
+	while (n-- > 0)
+		*yp++ = (float)LogL16toY(*l16++);
+}
+
+static void
+L16toGry(LogLuvState* sp, uint8* op, tmsize_t n)
+{
+	int16* l16 = (int16*) sp->tbuf;
+	uint8* gp = (uint8*) op;
+
+	while (n-- > 0) {
+		double Y = LogL16toY(*l16++);
+		*gp++ = (uint8) ((Y <= 0.) ? 0 : (Y >= 1.) ? 255 : (int)(256.*sqrt(Y)));
+	}
+}
+
+static void
+L16fromY(LogLuvState* sp, uint8* op, tmsize_t n)
+{
+	int16* l16 = (int16*) sp->tbuf;
+	float* yp = (float*) op;
+
+	while (n-- > 0)
+		*l16++ = (int16) (LogL16fromY(*yp++, sp->encode_meth));
+}
+
+#if !LOGLUV_PUBLIC
+static
+#endif
+void
+XYZtoRGB24(float xyz[3], uint8 rgb[3])
+{
+	double	r, g, b;
+					/* assume CCIR-709 primaries */
+	r =  2.690*xyz[0] + -1.276*xyz[1] + -0.414*xyz[2];
+	g = -1.022*xyz[0] +  1.978*xyz[1] +  0.044*xyz[2];
+	b =  0.061*xyz[0] + -0.224*xyz[1] +  1.163*xyz[2];
+					/* assume 2.0 gamma for speed */
+	/* could use integer sqrt approx., but this is probably faster */
+	rgb[0] = (uint8)((r<=0.) ? 0 : (r >= 1.) ? 255 : (int)(256.*sqrt(r)));
+	rgb[1] = (uint8)((g<=0.) ? 0 : (g >= 1.) ? 255 : (int)(256.*sqrt(g)));
+	rgb[2] = (uint8)((b<=0.) ? 0 : (b >= 1.) ? 255 : (int)(256.*sqrt(b)));
+}
+
+#if !LOGLUV_PUBLIC
+static
+#endif
+double
+LogL10toY(int p10)		/* compute luminance from 10-bit LogL */
+{
+	if (p10 == 0)
+		return (0.);
+	return (exp(M_LN2/64.*(p10+.5) - M_LN2*12.));
+}
+
+#if !LOGLUV_PUBLIC
+static
+#endif
+int
+LogL10fromY(double Y, int em)	/* get 10-bit LogL from Y */
+{
+	if (Y >= 15.742)
+		return (0x3ff);
+	else if (Y <= .00024283)
+		return (0);
+	else
+		return itrunc(64.*(log2(Y) + 12.), em);
+}
+
+#define NANGLES		100
+#define uv2ang(u, v)	( (NANGLES*.499999999/M_PI) \
+				* atan2((v)-V_NEU,(u)-U_NEU) + .5*NANGLES )
+
+static int
+oog_encode(double u, double v)		/* encode out-of-gamut chroma */
+{
+	static int	oog_table[NANGLES];
+	static int	initialized = 0;
+	register int	i;
+
+	if (!initialized) {		/* set up perimeter table */
+		double	eps[NANGLES], ua, va, ang, epsa;
+		int	ui, vi, ustep;
+		for (i = NANGLES; i--; )
+			eps[i] = 2.;
+		for (vi = UV_NVS; vi--; ) {
+			va = UV_VSTART + (vi+.5)*UV_SQSIZ;
+			ustep = uv_row[vi].nus-1;
+			if (vi == UV_NVS-1 || vi == 0 || ustep <= 0)
+				ustep = 1;
+			for (ui = uv_row[vi].nus-1; ui >= 0; ui -= ustep) {
+				ua = uv_row[vi].ustart + (ui+.5)*UV_SQSIZ;
+				ang = uv2ang(ua, va);
+				i = (int) ang;
+				epsa = fabs(ang - (i+.5));
+				if (epsa < eps[i]) {
+					oog_table[i] = uv_row[vi].ncum + ui;
+					eps[i] = epsa;
+				}
+			}
+		}
+		for (i = NANGLES; i--; )	/* fill any holes */
+			if (eps[i] > 1.5) {
+				int	i1, i2;
+				for (i1 = 1; i1 < NANGLES/2; i1++)
+					if (eps[(i+i1)%NANGLES] < 1.5)
+						break;
+				for (i2 = 1; i2 < NANGLES/2; i2++)
+					if (eps[(i+NANGLES-i2)%NANGLES] < 1.5)
+						break;
+				if (i1 < i2)
+					oog_table[i] =
+						oog_table[(i+i1)%NANGLES];
+				else
+					oog_table[i] =
+						oog_table[(i+NANGLES-i2)%NANGLES];
+			}
+		initialized = 1;
+	}
+	i = (int) uv2ang(u, v);		/* look up hue angle */
+	return (oog_table[i]);
+}
+
+#undef uv2ang
+#undef NANGLES
+
+#if !LOGLUV_PUBLIC
+static
+#endif
+int
+uv_encode(double u, double v, int em)	/* encode (u',v') coordinates */
+{
+	register int	vi, ui;
+
+	if (v < UV_VSTART)
+		return oog_encode(u, v);
+	vi = itrunc((v - UV_VSTART)*(1./UV_SQSIZ), em);
+	if (vi >= UV_NVS)
+		return oog_encode(u, v);
+	if (u < uv_row[vi].ustart)
+		return oog_encode(u, v);
+	ui = itrunc((u - uv_row[vi].ustart)*(1./UV_SQSIZ), em);
+	if (ui >= uv_row[vi].nus)
+		return oog_encode(u, v);
+
+	return (uv_row[vi].ncum + ui);
+}
+
+#if !LOGLUV_PUBLIC
+static
+#endif
+int
+uv_decode(double *up, double *vp, int c)	/* decode (u',v') index */
+{
+	int	upper, lower;
+	register int	ui, vi;
+
+	if (c < 0 || c >= UV_NDIVS)
+		return (-1);
+	lower = 0;				/* binary search */
+	upper = UV_NVS;
+	while (upper - lower > 1) {
+		vi = (lower + upper) >> 1;
+		ui = c - uv_row[vi].ncum;
+		if (ui > 0)
+			lower = vi;
+		else if (ui < 0)
+			upper = vi;
+		else {
+			lower = vi;
+			break;
+		}
+	}
+	vi = lower;
+	ui = c - uv_row[vi].ncum;
+	*up = uv_row[vi].ustart + (ui+.5)*UV_SQSIZ;
+	*vp = UV_VSTART + (vi+.5)*UV_SQSIZ;
+	return (0);
+}
+
+#if !LOGLUV_PUBLIC
+static
+#endif
+void
+LogLuv24toXYZ(uint32 p, float XYZ[3])
+{
+	int	Ce;
+	double	L, u, v, s, x, y;
+					/* decode luminance */
+	L = LogL10toY(p>>14 & 0x3ff);
+	if (L <= 0.) {
+		XYZ[0] = XYZ[1] = XYZ[2] = 0.;
+		return;
+	}
+					/* decode color */
+	Ce = p & 0x3fff;
+	if (uv_decode(&u, &v, Ce) < 0) {
+		u = U_NEU; v = V_NEU;
+	}
+	s = 1./(6.*u - 16.*v + 12.);
+	x = 9.*u * s;
+	y = 4.*v * s;
+					/* convert to XYZ */
+	XYZ[0] = (float)(x/y * L);
+	XYZ[1] = (float)L;
+	XYZ[2] = (float)((1.-x-y)/y * L);
+}
+
+#if !LOGLUV_PUBLIC
+static
+#endif
+uint32
+LogLuv24fromXYZ(float XYZ[3], int em)
+{
+	int	Le, Ce;
+	double	u, v, s;
+					/* encode luminance */
+	Le = LogL10fromY(XYZ[1], em);
+					/* encode color */
+	s = XYZ[0] + 15.*XYZ[1] + 3.*XYZ[2];
+	if (!Le || s <= 0.) {
+		u = U_NEU;
+		v = V_NEU;
+	} else {
+		u = 4.*XYZ[0] / s;
+		v = 9.*XYZ[1] / s;
+	}
+	Ce = uv_encode(u, v, em);
+	if (Ce < 0)			/* never happens */
+		Ce = uv_encode(U_NEU, V_NEU, SGILOGENCODE_NODITHER);
+					/* combine encodings */
+	return (Le << 14 | Ce);
+}
+
+static void
+Luv24toXYZ(LogLuvState* sp, uint8* op, tmsize_t n)
+{
+	uint32* luv = (uint32*) sp->tbuf;  
+	float* xyz = (float*) op;
+
+	while (n-- > 0) {
+		LogLuv24toXYZ(*luv, xyz);
+		xyz += 3;
+		luv++;
+	}
+}
+
+static void
+Luv24toLuv48(LogLuvState* sp, uint8* op, tmsize_t n)
+{
+	uint32* luv = (uint32*) sp->tbuf;  
+	int16* luv3 = (int16*) op;
+
+	while (n-- > 0) {
+		double u, v;
+
+		*luv3++ = (int16)((*luv >> 12 & 0xffd) + 13314);
+		if (uv_decode(&u, &v, *luv&0x3fff) < 0) {
+			u = U_NEU;
+			v = V_NEU;
+		}
+		*luv3++ = (int16)(u * (1L<<15));
+		*luv3++ = (int16)(v * (1L<<15));
+		luv++;
+	}
+}
+
+static void
+Luv24toRGB(LogLuvState* sp, uint8* op, tmsize_t n)
+{
+	uint32* luv = (uint32*) sp->tbuf;  
+	uint8* rgb = (uint8*) op;
+
+	while (n-- > 0) {
+		float xyz[3];
+
+		LogLuv24toXYZ(*luv++, xyz);
+		XYZtoRGB24(xyz, rgb);
+		rgb += 3;
+	}
+}
+
+static void
+Luv24fromXYZ(LogLuvState* sp, uint8* op, tmsize_t n)
+{
+	uint32* luv = (uint32*) sp->tbuf;  
+	float* xyz = (float*) op;
+
+	while (n-- > 0) {
+		*luv++ = LogLuv24fromXYZ(xyz, sp->encode_meth);
+		xyz += 3;
+	}
+}
+
+static void
+Luv24fromLuv48(LogLuvState* sp, uint8* op, tmsize_t n)
+{
+	uint32* luv = (uint32*) sp->tbuf;  
+	int16* luv3 = (int16*) op;
+
+	while (n-- > 0) {
+		int Le, Ce;
+
+		if (luv3[0] <= 0)
+			Le = 0;
+		else if (luv3[0] >= (1<<12)+3314)
+			Le = (1<<10) - 1;
+		else if (sp->encode_meth == SGILOGENCODE_NODITHER)
+			Le = (luv3[0]-3314) >> 2;
+		else
+			Le = itrunc(.25*(luv3[0]-3314.), sp->encode_meth);
+
+		Ce = uv_encode((luv3[1]+.5)/(1<<15), (luv3[2]+.5)/(1<<15),
+					sp->encode_meth);
+		if (Ce < 0)	/* never happens */
+			Ce = uv_encode(U_NEU, V_NEU, SGILOGENCODE_NODITHER);
+		*luv++ = (uint32)Le << 14 | Ce;
+		luv3 += 3;
+	}
+}
+
+#if !LOGLUV_PUBLIC
+static
+#endif
+void
+LogLuv32toXYZ(uint32 p, float XYZ[3])
+{
+	double	L, u, v, s, x, y;
+					/* decode luminance */
+	L = LogL16toY((int)p >> 16);
+	if (L <= 0.) {
+		XYZ[0] = XYZ[1] = XYZ[2] = 0.;
+		return;
+	}
+					/* decode color */
+	u = 1./UVSCALE * ((p>>8 & 0xff) + .5);
+	v = 1./UVSCALE * ((p & 0xff) + .5);
+	s = 1./(6.*u - 16.*v + 12.);
+	x = 9.*u * s;
+	y = 4.*v * s;
+					/* convert to XYZ */
+	XYZ[0] = (float)(x/y * L);
+	XYZ[1] = (float)L;
+	XYZ[2] = (float)((1.-x-y)/y * L);
+}
+
+#if !LOGLUV_PUBLIC
+static
+#endif
+uint32
+LogLuv32fromXYZ(float XYZ[3], int em)
+{
+	unsigned int	Le, ue, ve;
+	double	u, v, s;
+					/* encode luminance */
+	Le = (unsigned int)LogL16fromY(XYZ[1], em);
+					/* encode color */
+	s = XYZ[0] + 15.*XYZ[1] + 3.*XYZ[2];
+	if (!Le || s <= 0.) {
+		u = U_NEU;
+		v = V_NEU;
+	} else {
+		u = 4.*XYZ[0] / s;
+		v = 9.*XYZ[1] / s;
+	}
+	if (u <= 0.) ue = 0;
+	else ue = itrunc(UVSCALE*u, em);
+	if (ue > 255) ue = 255;
+	if (v <= 0.) ve = 0;
+	else ve = itrunc(UVSCALE*v, em);
+	if (ve > 255) ve = 255;
+					/* combine encodings */
+	return (Le << 16 | ue << 8 | ve);
+}
+
+static void
+Luv32toXYZ(LogLuvState* sp, uint8* op, tmsize_t n)
+{
+	uint32* luv = (uint32*) sp->tbuf;  
+	float* xyz = (float*) op;
+
+	while (n-- > 0) {
+		LogLuv32toXYZ(*luv++, xyz);
+		xyz += 3;
+	}
+}
+
+static void
+Luv32toLuv48(LogLuvState* sp, uint8* op, tmsize_t n)
+{
+	uint32* luv = (uint32*) sp->tbuf;  
+	int16* luv3 = (int16*) op;
+
+	while (n-- > 0) {
+		double u, v;
+
+		*luv3++ = (int16)(*luv >> 16);
+		u = 1./UVSCALE * ((*luv>>8 & 0xff) + .5);
+		v = 1./UVSCALE * ((*luv & 0xff) + .5);
+		*luv3++ = (int16)(u * (1L<<15));
+		*luv3++ = (int16)(v * (1L<<15));
+		luv++;
+	}
+}
+
+static void
+Luv32toRGB(LogLuvState* sp, uint8* op, tmsize_t n)
+{
+	uint32* luv = (uint32*) sp->tbuf;  
+	uint8* rgb = (uint8*) op;
+
+	while (n-- > 0) {
+		float xyz[3];
+
+		LogLuv32toXYZ(*luv++, xyz);
+		XYZtoRGB24(xyz, rgb);
+		rgb += 3;
+	}
+}
+
+static void
+Luv32fromXYZ(LogLuvState* sp, uint8* op, tmsize_t n)
+{
+	uint32* luv = (uint32*) sp->tbuf;  
+	float* xyz = (float*) op;
+
+	while (n-- > 0) {
+		*luv++ = LogLuv32fromXYZ(xyz, sp->encode_meth);
+		xyz += 3;
+	}
+}
+
+static void
+Luv32fromLuv48(LogLuvState* sp, uint8* op, tmsize_t n)
+{
+	uint32* luv = (uint32*) sp->tbuf;
+	int16* luv3 = (int16*) op;
+
+	if (sp->encode_meth == SGILOGENCODE_NODITHER) {
+		while (n-- > 0) {
+			*luv++ = (uint32)luv3[0] << 16 |
+				(luv3[1]*(uint32)(UVSCALE+.5) >> 7 & 0xff00) |
+				(luv3[2]*(uint32)(UVSCALE+.5) >> 15 & 0xff);
+			luv3 += 3;
+		}
+		return;
+	}
+	while (n-- > 0) {
+		*luv++ = (uint32)luv3[0] << 16 |
+	(itrunc(luv3[1]*(UVSCALE/(1<<15)), sp->encode_meth) << 8 & 0xff00) |
+		(itrunc(luv3[2]*(UVSCALE/(1<<15)), sp->encode_meth) & 0xff);
+		luv3 += 3;
+	}
+}
+
+static void
+_logLuvNop(LogLuvState* sp, uint8* op, tmsize_t n)
+{
+	(void) sp; (void) op; (void) n;
+}
+
+static int
+LogL16GuessDataFmt(TIFFDirectory *td)
+{
+#define	PACK(s,b,f)	(((b)<<6)|((s)<<3)|(f))
+	switch (PACK(td->td_samplesperpixel, td->td_bitspersample, td->td_sampleformat)) {
+	case PACK(1, 32, SAMPLEFORMAT_IEEEFP):
+		return (SGILOGDATAFMT_FLOAT);
+	case PACK(1, 16, SAMPLEFORMAT_VOID):
+	case PACK(1, 16, SAMPLEFORMAT_INT):
+	case PACK(1, 16, SAMPLEFORMAT_UINT):
+		return (SGILOGDATAFMT_16BIT);
+	case PACK(1,  8, SAMPLEFORMAT_VOID):
+	case PACK(1,  8, SAMPLEFORMAT_UINT):
+		return (SGILOGDATAFMT_8BIT);
+	}
+#undef PACK
+	return (SGILOGDATAFMT_UNKNOWN);
+}
+
+static tmsize_t
+multiply_ms(tmsize_t m1, tmsize_t m2)
+{
+	tmsize_t bytes = m1 * m2;
+
+	if (m1 && bytes / m1 != m2)
+		bytes = 0;
+
+	return bytes;
+}
+
+static int
+LogL16InitState(TIFF* tif)
+{
+	static const char module[] = "LogL16InitState";
+	TIFFDirectory *td = &tif->tif_dir;
+	LogLuvState* sp = DecoderState(tif);
+
+	assert(sp != NULL);
+	assert(td->td_photometric == PHOTOMETRIC_LOGL);
+
+	/* for some reason, we can't do this in TIFFInitLogL16 */
+	if (sp->user_datafmt == SGILOGDATAFMT_UNKNOWN)
+		sp->user_datafmt = LogL16GuessDataFmt(td);
+	switch (sp->user_datafmt) {
+	case SGILOGDATAFMT_FLOAT:
+		sp->pixel_size = sizeof (float);
+		break;
+	case SGILOGDATAFMT_16BIT:
+		sp->pixel_size = sizeof (int16);
+		break;
+	case SGILOGDATAFMT_8BIT:
+		sp->pixel_size = sizeof (uint8);
+		break;
+	default:
+		TIFFErrorExt(tif->tif_clientdata, module,
+		    "No support for converting user data format to LogL");
+		return (0);
+	}
+        if( isTiled(tif) )
+            sp->tbuflen = multiply_ms(td->td_tilewidth, td->td_tilelength);
+        else
+            sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_rowsperstrip);
+	if (multiply_ms(sp->tbuflen, sizeof (int16)) == 0 ||
+	    (sp->tbuf = (uint8*) _TIFFmalloc(sp->tbuflen * sizeof (int16))) == NULL) {
+		TIFFErrorExt(tif->tif_clientdata, module, "No space for SGILog translation buffer");
+		return (0);
+	}
+	return (1);
+}
+
+static int
+LogLuvGuessDataFmt(TIFFDirectory *td)
+{
+	int guess;
+
+	/*
+	 * If the user didn't tell us their datafmt,
+	 * take our best guess from the bitspersample.
+	 */
+#define	PACK(a,b)	(((a)<<3)|(b))
+	switch (PACK(td->td_bitspersample, td->td_sampleformat)) {
+	case PACK(32, SAMPLEFORMAT_IEEEFP):
+		guess = SGILOGDATAFMT_FLOAT;
+		break;
+	case PACK(32, SAMPLEFORMAT_VOID):
+	case PACK(32, SAMPLEFORMAT_UINT):
+	case PACK(32, SAMPLEFORMAT_INT):
+		guess = SGILOGDATAFMT_RAW;
+		break;
+	case PACK(16, SAMPLEFORMAT_VOID):
+	case PACK(16, SAMPLEFORMAT_INT):
+	case PACK(16, SAMPLEFORMAT_UINT):
+		guess = SGILOGDATAFMT_16BIT;
+		break;
+	case PACK( 8, SAMPLEFORMAT_VOID):
+	case PACK( 8, SAMPLEFORMAT_UINT):
+		guess = SGILOGDATAFMT_8BIT;
+		break;
+	default:
+		guess = SGILOGDATAFMT_UNKNOWN;
+		break;
+#undef PACK
+	}
+	/*
+	 * Double-check samples per pixel.
+	 */
+	switch (td->td_samplesperpixel) {
+	case 1:
+		if (guess != SGILOGDATAFMT_RAW)
+			guess = SGILOGDATAFMT_UNKNOWN;
+		break;
+	case 3:
+		if (guess == SGILOGDATAFMT_RAW)
+			guess = SGILOGDATAFMT_UNKNOWN;
+		break;
+	default:
+		guess = SGILOGDATAFMT_UNKNOWN;
+		break;
+	}
+	return (guess);
+}
+
+static int
+LogLuvInitState(TIFF* tif)
+{
+	static const char module[] = "LogLuvInitState";
+	TIFFDirectory* td = &tif->tif_dir;
+	LogLuvState* sp = DecoderState(tif);
+
+	assert(sp != NULL);
+	assert(td->td_photometric == PHOTOMETRIC_LOGLUV);
+
+	/* for some reason, we can't do this in TIFFInitLogLuv */
+	if (td->td_planarconfig != PLANARCONFIG_CONTIG) {
+		TIFFErrorExt(tif->tif_clientdata, module,
+		    "SGILog compression cannot handle non-contiguous data");
+		return (0);
+	}
+	if (sp->user_datafmt == SGILOGDATAFMT_UNKNOWN)
+		sp->user_datafmt = LogLuvGuessDataFmt(td);
+	switch (sp->user_datafmt) {
+	case SGILOGDATAFMT_FLOAT:
+		sp->pixel_size = 3*sizeof (float);
+		break;
+	case SGILOGDATAFMT_16BIT:
+		sp->pixel_size = 3*sizeof (int16);
+		break;
+	case SGILOGDATAFMT_RAW:
+		sp->pixel_size = sizeof (uint32);
+		break;
+	case SGILOGDATAFMT_8BIT:
+		sp->pixel_size = 3*sizeof (uint8);
+		break;
+	default:
+		TIFFErrorExt(tif->tif_clientdata, module,
+		    "No support for converting user data format to LogLuv");
+		return (0);
+	}
+        if( isTiled(tif) )
+            sp->tbuflen = multiply_ms(td->td_tilewidth, td->td_tilelength);
+        else
+            sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_rowsperstrip);
+	if (multiply_ms(sp->tbuflen, sizeof (uint32)) == 0 ||
+	    (sp->tbuf = (uint8*) _TIFFmalloc(sp->tbuflen * sizeof (uint32))) == NULL) {
+		TIFFErrorExt(tif->tif_clientdata, module, "No space for SGILog translation buffer");
+		return (0);
+	}
+	return (1);
+}
+
+static int
+LogLuvFixupTags(TIFF* tif)
+{
+	(void) tif;
+	return (1);
+}
+
+static int
+LogLuvSetupDecode(TIFF* tif)
+{
+	static const char module[] = "LogLuvSetupDecode";
+	LogLuvState* sp = DecoderState(tif);
+	TIFFDirectory* td = &tif->tif_dir;
+
+	tif->tif_postdecode = _TIFFNoPostDecode;
+	switch (td->td_photometric) {
+	case PHOTOMETRIC_LOGLUV:
+		if (!LogLuvInitState(tif))
+			break;
+		if (td->td_compression == COMPRESSION_SGILOG24) {
+			tif->tif_decoderow = LogLuvDecode24;
+			switch (sp->user_datafmt) {
+			case SGILOGDATAFMT_FLOAT:
+				sp->tfunc = Luv24toXYZ;  
+				break;
+			case SGILOGDATAFMT_16BIT:
+				sp->tfunc = Luv24toLuv48;  
+				break;
+			case SGILOGDATAFMT_8BIT:
+				sp->tfunc = Luv24toRGB;
+				break;
+			}
+		} else {
+			tif->tif_decoderow = LogLuvDecode32;
+			switch (sp->user_datafmt) {
+			case SGILOGDATAFMT_FLOAT:
+				sp->tfunc = Luv32toXYZ;
+				break;
+			case SGILOGDATAFMT_16BIT:
+				sp->tfunc = Luv32toLuv48;
+				break;
+			case SGILOGDATAFMT_8BIT:
+				sp->tfunc = Luv32toRGB;
+				break;
+			}
+		}
+		return (1);
+	case PHOTOMETRIC_LOGL:
+		if (!LogL16InitState(tif))
+			break;
+		tif->tif_decoderow = LogL16Decode;
+		switch (sp->user_datafmt) {
+		case SGILOGDATAFMT_FLOAT:
+			sp->tfunc = L16toY;
+			break;
+		case SGILOGDATAFMT_8BIT:
+			sp->tfunc = L16toGry;
+			break;
+		}
+		return (1);
+	default:
+		TIFFErrorExt(tif->tif_clientdata, module,
+		    "Inappropriate photometric interpretation %d for SGILog compression; %s",
+		    td->td_photometric, "must be either LogLUV or LogL");
+		break;
+	}
+	return (0);
+}
+
+static int
+LogLuvSetupEncode(TIFF* tif)
+{
+	static const char module[] = "LogLuvSetupEncode";
+	LogLuvState* sp = EncoderState(tif);
+	TIFFDirectory* td = &tif->tif_dir;
+
+	switch (td->td_photometric) {
+	case PHOTOMETRIC_LOGLUV:
+		if (!LogLuvInitState(tif))
+			break;
+		if (td->td_compression == COMPRESSION_SGILOG24) {
+			tif->tif_encoderow = LogLuvEncode24;
+			switch (sp->user_datafmt) {
+			case SGILOGDATAFMT_FLOAT:
+				sp->tfunc = Luv24fromXYZ;
+				break;
+			case SGILOGDATAFMT_16BIT:
+				sp->tfunc = Luv24fromLuv48;  
+				break;
+			case SGILOGDATAFMT_RAW:
+				break;
+			default:
+				goto notsupported;
+			}
+		} else {
+			tif->tif_encoderow = LogLuvEncode32;  
+			switch (sp->user_datafmt) {
+			case SGILOGDATAFMT_FLOAT:
+				sp->tfunc = Luv32fromXYZ;  
+				break;
+			case SGILOGDATAFMT_16BIT:
+				sp->tfunc = Luv32fromLuv48;  
+				break;
+			case SGILOGDATAFMT_RAW:
+				break;
+			default:
+				goto notsupported;
+			}
+		}
+		break;
+	case PHOTOMETRIC_LOGL:
+		if (!LogL16InitState(tif))
+			break;
+		tif->tif_encoderow = LogL16Encode;  
+		switch (sp->user_datafmt) {
+		case SGILOGDATAFMT_FLOAT:
+			sp->tfunc = L16fromY;
+			break;
+		case SGILOGDATAFMT_16BIT:
+			break;
+		default:
+			goto notsupported;
+		}
+		break;
+	default:
+		TIFFErrorExt(tif->tif_clientdata, module,
+		    "Inappropriate photometric interpretation %d for SGILog compression; %s",
+		    td->td_photometric, "must be either LogLUV or LogL");
+		break;
+	}
+	return (1);
+notsupported:
+	TIFFErrorExt(tif->tif_clientdata, module,
+	    "SGILog compression supported only for %s, or raw data",
+	    td->td_photometric == PHOTOMETRIC_LOGL ? "Y, L" : "XYZ, Luv");
+	return (0);
+}
+
+static void
+LogLuvClose(TIFF* tif)
+{
+	TIFFDirectory *td = &tif->tif_dir;
+
+	/*
+	 * For consistency, we always want to write out the same
+	 * bitspersample and sampleformat for our TIFF file,
+	 * regardless of the data format being used by the application.
+	 * Since this routine is called after tags have been set but
+	 * before they have been recorded in the file, we reset them here.
+	 */
+	td->td_samplesperpixel =
+	    (td->td_photometric == PHOTOMETRIC_LOGL) ? 1 : 3;
+	td->td_bitspersample = 16;
+	td->td_sampleformat = SAMPLEFORMAT_INT;
+}
+
+static void
+LogLuvCleanup(TIFF* tif)
+{
+	LogLuvState* sp = (LogLuvState *)tif->tif_data;
+
+	assert(sp != 0);
+
+	tif->tif_tagmethods.vgetfield = sp->vgetparent;
+	tif->tif_tagmethods.vsetfield = sp->vsetparent;
+
+	if (sp->tbuf)
+		_TIFFfree(sp->tbuf);
+	_TIFFfree(sp);
+	tif->tif_data = NULL;
+
+	_TIFFSetDefaultCompressionState(tif);
+}
+
+static int
+LogLuvVSetField(TIFF* tif, uint32 tag, va_list ap)
+{
+	static const char module[] = "LogLuvVSetField";
+	LogLuvState* sp = DecoderState(tif);
+	int bps, fmt;
+
+	switch (tag) {
+	case TIFFTAG_SGILOGDATAFMT:
+		sp->user_datafmt = (int) va_arg(ap, int);
+		/*
+		 * Tweak the TIFF header so that the rest of libtiff knows what
+		 * size of data will be passed between app and library, and
+		 * assume that the app knows what it is doing and is not
+		 * confused by these header manipulations...
+		 */
+		switch (sp->user_datafmt) {
+		case SGILOGDATAFMT_FLOAT:
+			bps = 32, fmt = SAMPLEFORMAT_IEEEFP;
+			break;
+		case SGILOGDATAFMT_16BIT:
+			bps = 16, fmt = SAMPLEFORMAT_INT;
+			break;
+		case SGILOGDATAFMT_RAW:
+			bps = 32, fmt = SAMPLEFORMAT_UINT;
+			TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
+			break;
+		case SGILOGDATAFMT_8BIT:
+			bps = 8, fmt = SAMPLEFORMAT_UINT;
+			break;
+		default:
+			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+			    "Unknown data format %d for LogLuv compression",
+			    sp->user_datafmt);
+			return (0);
+		}
+		TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps);
+		TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, fmt);
+		/*
+		 * Must recalculate sizes should bits/sample change.
+		 */
+		tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t) -1;
+		tif->tif_scanlinesize = TIFFScanlineSize(tif);
+		return (1);
+	case TIFFTAG_SGILOGENCODE:
+		sp->encode_meth = (int) va_arg(ap, int);
+		if (sp->encode_meth != SGILOGENCODE_NODITHER &&
+		    sp->encode_meth != SGILOGENCODE_RANDITHER) {
+			TIFFErrorExt(tif->tif_clientdata, module,
+			    "Unknown encoding %d for LogLuv compression",
+			    sp->encode_meth);
+			return (0);
+		}
+		return (1);
+	default:
+		return (*sp->vsetparent)(tif, tag, ap);
+	}
+}
+
+static int
+LogLuvVGetField(TIFF* tif, uint32 tag, va_list ap)
+{
+	LogLuvState *sp = (LogLuvState *)tif->tif_data;
+
+	switch (tag) {
+	case TIFFTAG_SGILOGDATAFMT:
+		*va_arg(ap, int*) = sp->user_datafmt;
+		return (1);
+	default:
+		return (*sp->vgetparent)(tif, tag, ap);
+	}
+}
+
+static const TIFFField LogLuvFields[] = {
+    { TIFFTAG_SGILOGDATAFMT, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "SGILogDataFmt", NULL},
+    { TIFFTAG_SGILOGENCODE, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "SGILogEncode", NULL}
+};
+
+int
+TIFFInitSGILog(TIFF* tif, int scheme)
+{
+	static const char module[] = "TIFFInitSGILog";
+	LogLuvState* sp;
+
+	assert(scheme == COMPRESSION_SGILOG24 || scheme == COMPRESSION_SGILOG);
+
+	/*
+	 * Merge codec-specific tag information.
+	 */
+	if (!_TIFFMergeFields(tif, LogLuvFields,
+			      TIFFArrayCount(LogLuvFields))) {
+		TIFFErrorExt(tif->tif_clientdata, module,
+		    "Merging SGILog codec-specific tags failed");
+		return 0;
+	}
+
+	/*
+	 * Allocate state block so tag methods have storage to record values.
+	 */
+	tif->tif_data = (uint8*) _TIFFmalloc(sizeof (LogLuvState));
+	if (tif->tif_data == NULL)
+		goto bad;
+	sp = (LogLuvState*) tif->tif_data;
+	_TIFFmemset((void*)sp, 0, sizeof (*sp));
+	sp->user_datafmt = SGILOGDATAFMT_UNKNOWN;
+	sp->encode_meth = (scheme == COMPRESSION_SGILOG24) ?
+	    SGILOGENCODE_RANDITHER : SGILOGENCODE_NODITHER;
+	sp->tfunc = _logLuvNop;
+
+	/*
+	 * Install codec methods.
+	 * NB: tif_decoderow & tif_encoderow are filled
+	 *     in at setup time.
+	 */
+	tif->tif_fixuptags = LogLuvFixupTags;  
+	tif->tif_setupdecode = LogLuvSetupDecode;
+	tif->tif_decodestrip = LogLuvDecodeStrip;
+	tif->tif_decodetile = LogLuvDecodeTile;
+	tif->tif_setupencode = LogLuvSetupEncode;
+	tif->tif_encodestrip = LogLuvEncodeStrip;  
+	tif->tif_encodetile = LogLuvEncodeTile;
+	tif->tif_close = LogLuvClose;
+	tif->tif_cleanup = LogLuvCleanup;
+
+	/*
+	 * Override parent get/set field methods.
+	 */
+	sp->vgetparent = tif->tif_tagmethods.vgetfield;
+	tif->tif_tagmethods.vgetfield = LogLuvVGetField;   /* hook for codec tags */
+	sp->vsetparent = tif->tif_tagmethods.vsetfield;
+	tif->tif_tagmethods.vsetfield = LogLuvVSetField;   /* hook for codec tags */
+
+	return (1);
+bad:
+	TIFFErrorExt(tif->tif_clientdata, module,
+		     "%s: No space for LogLuv state block", tif->tif_name);
+	return (0);
+}
+#endif /* LOGLUV_SUPPORT */
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tif_lzma.c b/Source/LibTIFF4/tif_lzma.c
index 31c2ff3..9cc09f9 100644
--- a/Source/LibTIFF4/tif_lzma.c
+++ b/Source/LibTIFF4/tif_lzma.c
@@ -1,495 +1,495 @@
-/* $Id: tif_lzma.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * Copyright (c) 2010, Andrey Kiselev <dron at ak4719.spb.edu>
- *
- * Permission to use, copy, modify, distribute, and sell this software and
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- */
-
-#include "tiffiop.h"
-#ifdef LZMA_SUPPORT
-/*
- * TIFF Library.
- *
- * LZMA2 Compression Support
- *
- * You need an LZMA2 SDK to link with. See http://tukaani.org/xz/ for details.
- *
- * The codec is derived from ZLIB codec (tif_zip.c).
- */
-
-#include "tif_predict.h"
-#include "lzma.h"
-
-#include <stdio.h>
-
-/*
- * State block for each open TIFF file using LZMA2 compression/decompression.
- */
-typedef struct {
-	TIFFPredictorState predict;
-        lzma_stream	stream;
-	lzma_filter	filters[LZMA_FILTERS_MAX + 1];
-	lzma_options_delta opt_delta;		/* delta filter options */
-	lzma_options_lzma opt_lzma;		/* LZMA2 filter options */
-	int             preset;			/* compression level */
-	lzma_check	check;			/* type of the integrity check */
-	int             state;			/* state flags */
-#define LSTATE_INIT_DECODE 0x01
-#define LSTATE_INIT_ENCODE 0x02
-
-	TIFFVGetMethod  vgetparent;            /* super-class method */
-	TIFFVSetMethod  vsetparent;            /* super-class method */
-} LZMAState;
-
-#define LState(tif)             ((LZMAState*) (tif)->tif_data)
-#define DecoderState(tif)       LState(tif)
-#define EncoderState(tif)       LState(tif)
-
-static int LZMAEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s);
-static int LZMADecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s);
-
-static const char *
-LZMAStrerror(lzma_ret ret)
-{
-	switch (ret) {
-		case LZMA_OK:
-		    return "operation completed successfully";
-		case LZMA_STREAM_END:
-		    return "end of stream was reached";
-		case LZMA_NO_CHECK:
-		    return "input stream has no integrity check";
-		case LZMA_UNSUPPORTED_CHECK:
-		    return "cannot calculate the integrity check";
-		case LZMA_GET_CHECK:
-		    return "integrity check type is now available";
-		case LZMA_MEM_ERROR:
-		    return "cannot allocate memory";
-		case LZMA_MEMLIMIT_ERROR:
-		    return "memory usage limit was reached";
-		case LZMA_FORMAT_ERROR:
-		    return "file format not recognized";
-		case LZMA_OPTIONS_ERROR:
-		    return "invalid or unsupported options";
-		case LZMA_DATA_ERROR:
-		    return "data is corrupt";
-		case LZMA_BUF_ERROR:
-		    return "no progress is possible (stream is truncated or corrupt)";
-		case LZMA_PROG_ERROR:
-		    return "programming error";
-		default:
-		    return "unindentified liblzma error";
-	}
-}
-
-static int
-LZMAFixupTags(TIFF* tif)
-{
-	(void) tif;
-	return 1;
-}
-
-static int
-LZMASetupDecode(TIFF* tif)
-{
-	LZMAState* sp = DecoderState(tif);
-
-	assert(sp != NULL);
-        
-        /* if we were last encoding, terminate this mode */
-	if (sp->state & LSTATE_INIT_ENCODE) {
-	    lzma_end(&sp->stream);
-	    sp->state = 0;
-	}
-
-	sp->state |= LSTATE_INIT_DECODE;
-	return 1;
-}
-
-/*
- * Setup state for decoding a strip.
- */
-static int
-LZMAPreDecode(TIFF* tif, uint16 s)
-{
-	static const char module[] = "LZMAPreDecode";
-	LZMAState* sp = DecoderState(tif);
-	lzma_ret ret;
-
-	(void) s;
-	assert(sp != NULL);
-
-	if( (sp->state & LSTATE_INIT_DECODE) == 0 )
-            tif->tif_setupdecode(tif);
-
-	sp->stream.next_in = tif->tif_rawdata;
-	sp->stream.avail_in = (size_t) tif->tif_rawcc;
-	if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-			     "Liblzma cannot deal with buffers this size");
-		return 0;
-	}
-
-	/*
-	 * Disable memory limit when decoding. UINT64_MAX is a flag to disable
-	 * the limit, we are passing (uint64_t)-1 which should be the same.
-	 */
-	ret = lzma_stream_decoder(&sp->stream, (uint64_t)-1, 0);
-	if (ret != LZMA_OK) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-			     "Error initializing the stream decoder, %s",
-			     LZMAStrerror(ret));
-		return 0;
-	}
-	return 1;
-}
-
-static int
-LZMADecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
-{
-	static const char module[] = "LZMADecode";
-	LZMAState* sp = DecoderState(tif);
-
-	(void) s;
-	assert(sp != NULL);
-	assert(sp->state == LSTATE_INIT_DECODE);
-
-        sp->stream.next_in = tif->tif_rawcp;
-        sp->stream.avail_in = (size_t) tif->tif_rawcc;
-
-	sp->stream.next_out = op;
-	sp->stream.avail_out = (size_t) occ;
-	if ((tmsize_t)sp->stream.avail_out != occ) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-			     "Liblzma cannot deal with buffers this size");
-		return 0;
-	}
-
-	do {
-		/*
-		 * Save the current stream state to properly recover from the
-		 * decoding errors later.
-		 */
-		const uint8_t *next_in = sp->stream.next_in;
-		size_t avail_in = sp->stream.avail_in;
-
-		lzma_ret ret = lzma_code(&sp->stream, LZMA_RUN);
-		if (ret == LZMA_STREAM_END)
-			break;
-		if (ret == LZMA_MEMLIMIT_ERROR) {
-			lzma_ret r = lzma_stream_decoder(&sp->stream,
-							 lzma_memusage(&sp->stream), 0);
-			if (r != LZMA_OK) {
-				TIFFErrorExt(tif->tif_clientdata, module,
-					     "Error initializing the stream decoder, %s",
-					     LZMAStrerror(r));
-				break;
-			}
-			sp->stream.next_in = next_in;
-			sp->stream.avail_in = avail_in;
-			continue;
-		}
-		if (ret != LZMA_OK) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-			    "Decoding error at scanline %lu, %s",
-			    (unsigned long) tif->tif_row, LZMAStrerror(ret));
-			break;
-		}
-	} while (sp->stream.avail_out > 0);
-	if (sp->stream.avail_out != 0) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-		    "Not enough data at scanline %lu (short %lu bytes)",
-		    (unsigned long) tif->tif_row, (unsigned long) sp->stream.avail_out);
-		return 0;
-	}
-
-        tif->tif_rawcp = (uint8 *)sp->stream.next_in; /* cast away const */
-        tif->tif_rawcc = sp->stream.avail_in;
-        
-	return 1;
-}
-
-static int
-LZMASetupEncode(TIFF* tif)
-{
-	LZMAState* sp = EncoderState(tif);
-
-	assert(sp != NULL);
-	if (sp->state & LSTATE_INIT_DECODE) {
-		lzma_end(&sp->stream);
-		sp->state = 0;
-	}
-
-	sp->state |= LSTATE_INIT_ENCODE;
-	return 1;
-}
-
-/*
- * Reset encoding state at the start of a strip.
- */
-static int
-LZMAPreEncode(TIFF* tif, uint16 s)
-{
-	static const char module[] = "LZMAPreEncode";
-	LZMAState *sp = EncoderState(tif);
-
-	(void) s;
-	assert(sp != NULL);
-	if( sp->state != LSTATE_INIT_ENCODE )
-            tif->tif_setupencode(tif);
-
-	sp->stream.next_out = tif->tif_rawdata;
-	sp->stream.avail_out = (size_t)tif->tif_rawdatasize;
-	if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-			     "Liblzma cannot deal with buffers this size");
-		return 0;
-	}
-	return (lzma_stream_encoder(&sp->stream, sp->filters, sp->check) == LZMA_OK);
-}
-
-/*
- * Encode a chunk of pixels.
- */
-static int
-LZMAEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
-{
-	static const char module[] = "LZMAEncode";
-	LZMAState *sp = EncoderState(tif);
-
-	assert(sp != NULL);
-	assert(sp->state == LSTATE_INIT_ENCODE);
-
-	(void) s;
-	sp->stream.next_in = bp;
-	sp->stream.avail_in = (size_t) cc;
-	if ((tmsize_t)sp->stream.avail_in != cc) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-			     "Liblzma cannot deal with buffers this size");
-		return 0;
-	}
-	do {
-		lzma_ret ret = lzma_code(&sp->stream, LZMA_RUN);
-		if (ret != LZMA_OK) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-				"Encoding error at scanline %lu, %s",
-				(unsigned long) tif->tif_row, LZMAStrerror(ret));
-			return 0;
-		}
-		if (sp->stream.avail_out == 0) {
-			tif->tif_rawcc = tif->tif_rawdatasize;
-			TIFFFlushData1(tif);
-			sp->stream.next_out = tif->tif_rawdata;
-			sp->stream.avail_out = (size_t)tif->tif_rawdatasize;  /* this is a safe typecast, as check is made already in LZMAPreEncode */
-		}
-	} while (sp->stream.avail_in > 0);
-	return 1;
-}
-
-/*
- * Finish off an encoded strip by flushing the last
- * string and tacking on an End Of Information code.
- */
-static int
-LZMAPostEncode(TIFF* tif)
-{
-	static const char module[] = "LZMAPostEncode";
-	LZMAState *sp = EncoderState(tif);
-	lzma_ret ret;
-
-	sp->stream.avail_in = 0;
-	do {
-		ret = lzma_code(&sp->stream, LZMA_FINISH);
-		switch (ret) {
-		case LZMA_STREAM_END:
-		case LZMA_OK:
-			if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) {
-				tif->tif_rawcc =
-					tif->tif_rawdatasize - sp->stream.avail_out;
-				TIFFFlushData1(tif);
-				sp->stream.next_out = tif->tif_rawdata;
-				sp->stream.avail_out = (size_t)tif->tif_rawdatasize;  /* this is a safe typecast, as check is made already in ZIPPreEncode */
-			}
-			break;
-		default:
-			TIFFErrorExt(tif->tif_clientdata, module, "Liblzma error: %s",
-				     LZMAStrerror(ret));
-			return 0;
-		}
-	} while (ret != LZMA_STREAM_END);
-	return 1;
-}
-
-static void
-LZMACleanup(TIFF* tif)
-{
-	LZMAState* sp = LState(tif);
-
-	assert(sp != 0);
-
-	(void)TIFFPredictorCleanup(tif);
-
-	tif->tif_tagmethods.vgetfield = sp->vgetparent;
-	tif->tif_tagmethods.vsetfield = sp->vsetparent;
-
-	if (sp->state) {
-		lzma_end(&sp->stream);
-		sp->state = 0;
-	}
-	_TIFFfree(sp);
-	tif->tif_data = NULL;
-
-	_TIFFSetDefaultCompressionState(tif);
-}
-
-static int
-LZMAVSetField(TIFF* tif, uint32 tag, va_list ap)
-{
-	static const char module[] = "LZMAVSetField";
-	LZMAState* sp = LState(tif);
-
-	switch (tag) {
-	case TIFFTAG_LZMAPRESET:
-		sp->preset = (int) va_arg(ap, int);
-		lzma_lzma_preset(&sp->opt_lzma, sp->preset);
-		if (sp->state & LSTATE_INIT_ENCODE) {
-			lzma_ret ret = lzma_stream_encoder(&sp->stream,
-							   sp->filters,
-							   sp->check);
-			if (ret != LZMA_OK) {
-				TIFFErrorExt(tif->tif_clientdata, module,
-					     "Liblzma error: %s",
-					     LZMAStrerror(ret));
-			}
-		}
-		return 1;
-	default:
-		return (*sp->vsetparent)(tif, tag, ap);
-	}
-	/*NOTREACHED*/
-}
-
-static int
-LZMAVGetField(TIFF* tif, uint32 tag, va_list ap)
-{
-	LZMAState* sp = LState(tif);
-
-	switch (tag) {
-	case TIFFTAG_LZMAPRESET:
-		*va_arg(ap, int*) = sp->preset;
-		break;
-	default:
-		return (*sp->vgetparent)(tif, tag, ap);
-	}
-	return 1;
-}
-
-static const TIFFField lzmaFields[] = {
-	{ TIFFTAG_LZMAPRESET, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED,
-		FIELD_PSEUDO, TRUE, FALSE, "LZMA2 Compression Preset", NULL },
-};
-
-int
-TIFFInitLZMA(TIFF* tif, int scheme)
-{
-	static const char module[] = "TIFFInitLZMA";
-	LZMAState* sp;
-	lzma_stream tmp_stream = LZMA_STREAM_INIT;
-
-	assert( scheme == COMPRESSION_LZMA );
-
-	/*
-	 * Merge codec-specific tag information.
-	 */
-	if (!_TIFFMergeFields(tif, lzmaFields, TIFFArrayCount(lzmaFields))) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-			     "Merging LZMA2 codec-specific tags failed");
-		return 0;
-	}
-
-	/*
-	 * Allocate state block so tag methods have storage to record values.
-	 */
-	tif->tif_data = (uint8*) _TIFFmalloc(sizeof(LZMAState));
-	if (tif->tif_data == NULL)
-		goto bad;
-	sp = LState(tif);
-	memcpy(&sp->stream, &tmp_stream, sizeof(lzma_stream));
-
-	/*
-	 * Override parent get/set field methods.
-	 */
-	sp->vgetparent = tif->tif_tagmethods.vgetfield;
-	tif->tif_tagmethods.vgetfield = LZMAVGetField;	/* hook for codec tags */
-	sp->vsetparent = tif->tif_tagmethods.vsetfield;
-	tif->tif_tagmethods.vsetfield = LZMAVSetField;	/* hook for codec tags */
-
-	/* Default values for codec-specific fields */
-	sp->preset = LZMA_PRESET_DEFAULT;		/* default comp. level */
-	sp->check = LZMA_CHECK_NONE;
-	sp->state = 0;
-
-	/* Data filters. So far we are using delta and LZMA2 filters only. */
-	sp->opt_delta.type = LZMA_DELTA_TYPE_BYTE;
-	/*
-	 * The sample size in bytes seems to be reasonable distance for delta
-	 * filter.
-	 */
-	sp->opt_delta.dist = (tif->tif_dir.td_bitspersample % 8) ?
-		1 : tif->tif_dir.td_bitspersample / 8;
-	sp->filters[0].id = LZMA_FILTER_DELTA;
-	sp->filters[0].options = &sp->opt_delta;
-
-	lzma_lzma_preset(&sp->opt_lzma, sp->preset);
-	sp->filters[1].id = LZMA_FILTER_LZMA2;
-	sp->filters[1].options = &sp->opt_lzma;
-
-	sp->filters[2].id = LZMA_VLI_UNKNOWN;
-	sp->filters[2].options = NULL;
-
-	/*
-	 * Install codec methods.
-	 */
-	tif->tif_fixuptags = LZMAFixupTags;
-	tif->tif_setupdecode = LZMASetupDecode;
-	tif->tif_predecode = LZMAPreDecode;
-	tif->tif_decoderow = LZMADecode;
-	tif->tif_decodestrip = LZMADecode;
-	tif->tif_decodetile = LZMADecode;
-	tif->tif_setupencode = LZMASetupEncode;
-	tif->tif_preencode = LZMAPreEncode;
-	tif->tif_postencode = LZMAPostEncode;
-	tif->tif_encoderow = LZMAEncode;
-	tif->tif_encodestrip = LZMAEncode;
-	tif->tif_encodetile = LZMAEncode;
-	tif->tif_cleanup = LZMACleanup;
-	/*
-	 * Setup predictor setup.
-	 */
-	(void) TIFFPredictorInit(tif);
-	return 1;
-bad:
-	TIFFErrorExt(tif->tif_clientdata, module,
-		     "No space for LZMA2 state block");
-	return 0;
-}
-#endif /* LZMA_SUPORT */
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
+/* $Id: tif_lzma.c,v 1.11 2015/02/19 22:39:58 drolon Exp $ */
+
+/*
+ * Copyright (c) 2010, Andrey Kiselev <dron at ak4719.spb.edu>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include "tiffiop.h"
+#ifdef LZMA_SUPPORT
+/*
+ * TIFF Library.
+ *
+ * LZMA2 Compression Support
+ *
+ * You need an LZMA2 SDK to link with. See http://tukaani.org/xz/ for details.
+ *
+ * The codec is derived from ZLIB codec (tif_zip.c).
+ */
+
+#include "tif_predict.h"
+#include "lzma.h"
+
+#include <stdio.h>
+
+/*
+ * State block for each open TIFF file using LZMA2 compression/decompression.
+ */
+typedef struct {
+	TIFFPredictorState predict;
+        lzma_stream	stream;
+	lzma_filter	filters[LZMA_FILTERS_MAX + 1];
+	lzma_options_delta opt_delta;		/* delta filter options */
+	lzma_options_lzma opt_lzma;		/* LZMA2 filter options */
+	int             preset;			/* compression level */
+	lzma_check	check;			/* type of the integrity check */
+	int             state;			/* state flags */
+#define LSTATE_INIT_DECODE 0x01
+#define LSTATE_INIT_ENCODE 0x02
+
+	TIFFVGetMethod  vgetparent;            /* super-class method */
+	TIFFVSetMethod  vsetparent;            /* super-class method */
+} LZMAState;
+
+#define LState(tif)             ((LZMAState*) (tif)->tif_data)
+#define DecoderState(tif)       LState(tif)
+#define EncoderState(tif)       LState(tif)
+
+static int LZMAEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s);
+static int LZMADecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s);
+
+static const char *
+LZMAStrerror(lzma_ret ret)
+{
+	switch (ret) {
+		case LZMA_OK:
+		    return "operation completed successfully";
+		case LZMA_STREAM_END:
+		    return "end of stream was reached";
+		case LZMA_NO_CHECK:
+		    return "input stream has no integrity check";
+		case LZMA_UNSUPPORTED_CHECK:
+		    return "cannot calculate the integrity check";
+		case LZMA_GET_CHECK:
+		    return "integrity check type is now available";
+		case LZMA_MEM_ERROR:
+		    return "cannot allocate memory";
+		case LZMA_MEMLIMIT_ERROR:
+		    return "memory usage limit was reached";
+		case LZMA_FORMAT_ERROR:
+		    return "file format not recognized";
+		case LZMA_OPTIONS_ERROR:
+		    return "invalid or unsupported options";
+		case LZMA_DATA_ERROR:
+		    return "data is corrupt";
+		case LZMA_BUF_ERROR:
+		    return "no progress is possible (stream is truncated or corrupt)";
+		case LZMA_PROG_ERROR:
+		    return "programming error";
+		default:
+		    return "unindentified liblzma error";
+	}
+}
+
+static int
+LZMAFixupTags(TIFF* tif)
+{
+	(void) tif;
+	return 1;
+}
+
+static int
+LZMASetupDecode(TIFF* tif)
+{
+	LZMAState* sp = DecoderState(tif);
+
+	assert(sp != NULL);
+        
+        /* if we were last encoding, terminate this mode */
+	if (sp->state & LSTATE_INIT_ENCODE) {
+	    lzma_end(&sp->stream);
+	    sp->state = 0;
+	}
+
+	sp->state |= LSTATE_INIT_DECODE;
+	return 1;
+}
+
+/*
+ * Setup state for decoding a strip.
+ */
+static int
+LZMAPreDecode(TIFF* tif, uint16 s)
+{
+	static const char module[] = "LZMAPreDecode";
+	LZMAState* sp = DecoderState(tif);
+	lzma_ret ret;
+
+	(void) s;
+	assert(sp != NULL);
+
+	if( (sp->state & LSTATE_INIT_DECODE) == 0 )
+            tif->tif_setupdecode(tif);
+
+	sp->stream.next_in = tif->tif_rawdata;
+	sp->stream.avail_in = (size_t) tif->tif_rawcc;
+	if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc) {
+		TIFFErrorExt(tif->tif_clientdata, module,
+			     "Liblzma cannot deal with buffers this size");
+		return 0;
+	}
+
+	/*
+	 * Disable memory limit when decoding. UINT64_MAX is a flag to disable
+	 * the limit, we are passing (uint64_t)-1 which should be the same.
+	 */
+	ret = lzma_stream_decoder(&sp->stream, (uint64_t)-1, 0);
+	if (ret != LZMA_OK) {
+		TIFFErrorExt(tif->tif_clientdata, module,
+			     "Error initializing the stream decoder, %s",
+			     LZMAStrerror(ret));
+		return 0;
+	}
+	return 1;
+}
+
+static int
+LZMADecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
+{
+	static const char module[] = "LZMADecode";
+	LZMAState* sp = DecoderState(tif);
+
+	(void) s;
+	assert(sp != NULL);
+	assert(sp->state == LSTATE_INIT_DECODE);
+
+        sp->stream.next_in = tif->tif_rawcp;
+        sp->stream.avail_in = (size_t) tif->tif_rawcc;
+
+	sp->stream.next_out = op;
+	sp->stream.avail_out = (size_t) occ;
+	if ((tmsize_t)sp->stream.avail_out != occ) {
+		TIFFErrorExt(tif->tif_clientdata, module,
+			     "Liblzma cannot deal with buffers this size");
+		return 0;
+	}
+
+	do {
+		/*
+		 * Save the current stream state to properly recover from the
+		 * decoding errors later.
+		 */
+		const uint8_t *next_in = sp->stream.next_in;
+		size_t avail_in = sp->stream.avail_in;
+
+		lzma_ret ret = lzma_code(&sp->stream, LZMA_RUN);
+		if (ret == LZMA_STREAM_END)
+			break;
+		if (ret == LZMA_MEMLIMIT_ERROR) {
+			lzma_ret r = lzma_stream_decoder(&sp->stream,
+							 lzma_memusage(&sp->stream), 0);
+			if (r != LZMA_OK) {
+				TIFFErrorExt(tif->tif_clientdata, module,
+					     "Error initializing the stream decoder, %s",
+					     LZMAStrerror(r));
+				break;
+			}
+			sp->stream.next_in = next_in;
+			sp->stream.avail_in = avail_in;
+			continue;
+		}
+		if (ret != LZMA_OK) {
+			TIFFErrorExt(tif->tif_clientdata, module,
+			    "Decoding error at scanline %lu, %s",
+			    (unsigned long) tif->tif_row, LZMAStrerror(ret));
+			break;
+		}
+	} while (sp->stream.avail_out > 0);
+	if (sp->stream.avail_out != 0) {
+		TIFFErrorExt(tif->tif_clientdata, module,
+		    "Not enough data at scanline %lu (short %lu bytes)",
+		    (unsigned long) tif->tif_row, (unsigned long) sp->stream.avail_out);
+		return 0;
+	}
+
+        tif->tif_rawcp = (uint8 *)sp->stream.next_in; /* cast away const */
+        tif->tif_rawcc = sp->stream.avail_in;
+        
+	return 1;
+}
+
+static int
+LZMASetupEncode(TIFF* tif)
+{
+	LZMAState* sp = EncoderState(tif);
+
+	assert(sp != NULL);
+	if (sp->state & LSTATE_INIT_DECODE) {
+		lzma_end(&sp->stream);
+		sp->state = 0;
+	}
+
+	sp->state |= LSTATE_INIT_ENCODE;
+	return 1;
+}
+
+/*
+ * Reset encoding state at the start of a strip.
+ */
+static int
+LZMAPreEncode(TIFF* tif, uint16 s)
+{
+	static const char module[] = "LZMAPreEncode";
+	LZMAState *sp = EncoderState(tif);
+
+	(void) s;
+	assert(sp != NULL);
+	if( sp->state != LSTATE_INIT_ENCODE )
+            tif->tif_setupencode(tif);
+
+	sp->stream.next_out = tif->tif_rawdata;
+	sp->stream.avail_out = (size_t)tif->tif_rawdatasize;
+	if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) {
+		TIFFErrorExt(tif->tif_clientdata, module,
+			     "Liblzma cannot deal with buffers this size");
+		return 0;
+	}
+	return (lzma_stream_encoder(&sp->stream, sp->filters, sp->check) == LZMA_OK);
+}
+
+/*
+ * Encode a chunk of pixels.
+ */
+static int
+LZMAEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
+{
+	static const char module[] = "LZMAEncode";
+	LZMAState *sp = EncoderState(tif);
+
+	assert(sp != NULL);
+	assert(sp->state == LSTATE_INIT_ENCODE);
+
+	(void) s;
+	sp->stream.next_in = bp;
+	sp->stream.avail_in = (size_t) cc;
+	if ((tmsize_t)sp->stream.avail_in != cc) {
+		TIFFErrorExt(tif->tif_clientdata, module,
+			     "Liblzma cannot deal with buffers this size");
+		return 0;
+	}
+	do {
+		lzma_ret ret = lzma_code(&sp->stream, LZMA_RUN);
+		if (ret != LZMA_OK) {
+			TIFFErrorExt(tif->tif_clientdata, module,
+				"Encoding error at scanline %lu, %s",
+				(unsigned long) tif->tif_row, LZMAStrerror(ret));
+			return 0;
+		}
+		if (sp->stream.avail_out == 0) {
+			tif->tif_rawcc = tif->tif_rawdatasize;
+			TIFFFlushData1(tif);
+			sp->stream.next_out = tif->tif_rawdata;
+			sp->stream.avail_out = (size_t)tif->tif_rawdatasize;  /* this is a safe typecast, as check is made already in LZMAPreEncode */
+		}
+	} while (sp->stream.avail_in > 0);
+	return 1;
+}
+
+/*
+ * Finish off an encoded strip by flushing the last
+ * string and tacking on an End Of Information code.
+ */
+static int
+LZMAPostEncode(TIFF* tif)
+{
+	static const char module[] = "LZMAPostEncode";
+	LZMAState *sp = EncoderState(tif);
+	lzma_ret ret;
+
+	sp->stream.avail_in = 0;
+	do {
+		ret = lzma_code(&sp->stream, LZMA_FINISH);
+		switch (ret) {
+		case LZMA_STREAM_END:
+		case LZMA_OK:
+			if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) {
+				tif->tif_rawcc =
+					tif->tif_rawdatasize - sp->stream.avail_out;
+				TIFFFlushData1(tif);
+				sp->stream.next_out = tif->tif_rawdata;
+				sp->stream.avail_out = (size_t)tif->tif_rawdatasize;  /* this is a safe typecast, as check is made already in ZIPPreEncode */
+			}
+			break;
+		default:
+			TIFFErrorExt(tif->tif_clientdata, module, "Liblzma error: %s",
+				     LZMAStrerror(ret));
+			return 0;
+		}
+	} while (ret != LZMA_STREAM_END);
+	return 1;
+}
+
+static void
+LZMACleanup(TIFF* tif)
+{
+	LZMAState* sp = LState(tif);
+
+	assert(sp != 0);
+
+	(void)TIFFPredictorCleanup(tif);
+
+	tif->tif_tagmethods.vgetfield = sp->vgetparent;
+	tif->tif_tagmethods.vsetfield = sp->vsetparent;
+
+	if (sp->state) {
+		lzma_end(&sp->stream);
+		sp->state = 0;
+	}
+	_TIFFfree(sp);
+	tif->tif_data = NULL;
+
+	_TIFFSetDefaultCompressionState(tif);
+}
+
+static int
+LZMAVSetField(TIFF* tif, uint32 tag, va_list ap)
+{
+	static const char module[] = "LZMAVSetField";
+	LZMAState* sp = LState(tif);
+
+	switch (tag) {
+	case TIFFTAG_LZMAPRESET:
+		sp->preset = (int) va_arg(ap, int);
+		lzma_lzma_preset(&sp->opt_lzma, sp->preset);
+		if (sp->state & LSTATE_INIT_ENCODE) {
+			lzma_ret ret = lzma_stream_encoder(&sp->stream,
+							   sp->filters,
+							   sp->check);
+			if (ret != LZMA_OK) {
+				TIFFErrorExt(tif->tif_clientdata, module,
+					     "Liblzma error: %s",
+					     LZMAStrerror(ret));
+			}
+		}
+		return 1;
+	default:
+		return (*sp->vsetparent)(tif, tag, ap);
+	}
+	/*NOTREACHED*/
+}
+
+static int
+LZMAVGetField(TIFF* tif, uint32 tag, va_list ap)
+{
+	LZMAState* sp = LState(tif);
+
+	switch (tag) {
+	case TIFFTAG_LZMAPRESET:
+		*va_arg(ap, int*) = sp->preset;
+		break;
+	default:
+		return (*sp->vgetparent)(tif, tag, ap);
+	}
+	return 1;
+}
+
+static const TIFFField lzmaFields[] = {
+	{ TIFFTAG_LZMAPRESET, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED,
+		FIELD_PSEUDO, TRUE, FALSE, "LZMA2 Compression Preset", NULL },
+};
+
+int
+TIFFInitLZMA(TIFF* tif, int scheme)
+{
+	static const char module[] = "TIFFInitLZMA";
+	LZMAState* sp;
+	lzma_stream tmp_stream = LZMA_STREAM_INIT;
+
+	assert( scheme == COMPRESSION_LZMA );
+
+	/*
+	 * Merge codec-specific tag information.
+	 */
+	if (!_TIFFMergeFields(tif, lzmaFields, TIFFArrayCount(lzmaFields))) {
+		TIFFErrorExt(tif->tif_clientdata, module,
+			     "Merging LZMA2 codec-specific tags failed");
+		return 0;
+	}
+
+	/*
+	 * Allocate state block so tag methods have storage to record values.
+	 */
+	tif->tif_data = (uint8*) _TIFFmalloc(sizeof(LZMAState));
+	if (tif->tif_data == NULL)
+		goto bad;
+	sp = LState(tif);
+	memcpy(&sp->stream, &tmp_stream, sizeof(lzma_stream));
+
+	/*
+	 * Override parent get/set field methods.
+	 */
+	sp->vgetparent = tif->tif_tagmethods.vgetfield;
+	tif->tif_tagmethods.vgetfield = LZMAVGetField;	/* hook for codec tags */
+	sp->vsetparent = tif->tif_tagmethods.vsetfield;
+	tif->tif_tagmethods.vsetfield = LZMAVSetField;	/* hook for codec tags */
+
+	/* Default values for codec-specific fields */
+	sp->preset = LZMA_PRESET_DEFAULT;		/* default comp. level */
+	sp->check = LZMA_CHECK_NONE;
+	sp->state = 0;
+
+	/* Data filters. So far we are using delta and LZMA2 filters only. */
+	sp->opt_delta.type = LZMA_DELTA_TYPE_BYTE;
+	/*
+	 * The sample size in bytes seems to be reasonable distance for delta
+	 * filter.
+	 */
+	sp->opt_delta.dist = (tif->tif_dir.td_bitspersample % 8) ?
+		1 : tif->tif_dir.td_bitspersample / 8;
+	sp->filters[0].id = LZMA_FILTER_DELTA;
+	sp->filters[0].options = &sp->opt_delta;
+
+	lzma_lzma_preset(&sp->opt_lzma, sp->preset);
+	sp->filters[1].id = LZMA_FILTER_LZMA2;
+	sp->filters[1].options = &sp->opt_lzma;
+
+	sp->filters[2].id = LZMA_VLI_UNKNOWN;
+	sp->filters[2].options = NULL;
+
+	/*
+	 * Install codec methods.
+	 */
+	tif->tif_fixuptags = LZMAFixupTags;
+	tif->tif_setupdecode = LZMASetupDecode;
+	tif->tif_predecode = LZMAPreDecode;
+	tif->tif_decoderow = LZMADecode;
+	tif->tif_decodestrip = LZMADecode;
+	tif->tif_decodetile = LZMADecode;
+	tif->tif_setupencode = LZMASetupEncode;
+	tif->tif_preencode = LZMAPreEncode;
+	tif->tif_postencode = LZMAPostEncode;
+	tif->tif_encoderow = LZMAEncode;
+	tif->tif_encodestrip = LZMAEncode;
+	tif->tif_encodetile = LZMAEncode;
+	tif->tif_cleanup = LZMACleanup;
+	/*
+	 * Setup predictor setup.
+	 */
+	(void) TIFFPredictorInit(tif);
+	return 1;
+bad:
+	TIFFErrorExt(tif->tif_clientdata, module,
+		     "No space for LZMA2 state block");
+	return 0;
+}
+#endif /* LZMA_SUPORT */
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
diff --git a/Source/LibTIFF4/tif_lzw.c b/Source/LibTIFF4/tif_lzw.c
index 972f92b..84c77f3 100644
--- a/Source/LibTIFF4/tif_lzw.c
+++ b/Source/LibTIFF4/tif_lzw.c
@@ -1,1167 +1,1169 @@
-/* $Id: tif_lzw.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-#include "tiffiop.h"
-#ifdef LZW_SUPPORT
-/*
- * TIFF Library.  
- * Rev 5.0 Lempel-Ziv & Welch Compression Support
- *
- * This code is derived from the compress program whose code is
- * derived from software contributed to Berkeley by James A. Woods,
- * derived from original work by Spencer Thomas and Joseph Orost.
- *
- * The original Berkeley copyright notice appears below in its entirety.
- */
-#include "tif_predict.h"
-
-#include <stdio.h>
-
-/*
- * NB: The 5.0 spec describes a different algorithm than Aldus
- *     implements.  Specifically, Aldus does code length transitions
- *     one code earlier than should be done (for real LZW).
- *     Earlier versions of this library implemented the correct
- *     LZW algorithm, but emitted codes in a bit order opposite
- *     to the TIFF spec.  Thus, to maintain compatibility w/ Aldus
- *     we interpret MSB-LSB ordered codes to be images written w/
- *     old versions of this library, but otherwise adhere to the
- *     Aldus "off by one" algorithm.
- *
- * Future revisions to the TIFF spec are expected to "clarify this issue".
- */
-#define LZW_COMPAT              /* include backwards compatibility code */
-/*
- * Each strip of data is supposed to be terminated by a CODE_EOI.
- * If the following #define is included, the decoder will also
- * check for end-of-strip w/o seeing this code.  This makes the
- * library more robust, but also slower.
- */
-#define LZW_CHECKEOS            /* include checks for strips w/o EOI code */
-
-#define MAXCODE(n)	((1L<<(n))-1)
-/*
- * The TIFF spec specifies that encoded bit
- * strings range from 9 to 12 bits.
- */
-#define BITS_MIN        9               /* start with 9 bits */
-#define BITS_MAX        12              /* max of 12 bit strings */
-/* predefined codes */
-#define CODE_CLEAR      256             /* code to clear string table */
-#define CODE_EOI        257             /* end-of-information code */
-#define CODE_FIRST      258             /* first free code entry */
-#define CODE_MAX        MAXCODE(BITS_MAX)
-#define HSIZE           9001L           /* 91% occupancy */
-#define HSHIFT          (13-8)
-#ifdef LZW_COMPAT
-/* NB: +1024 is for compatibility with old files */
-#define CSIZE           (MAXCODE(BITS_MAX)+1024L)
-#else
-#define CSIZE           (MAXCODE(BITS_MAX)+1L)
-#endif
-
-/*
- * State block for each open TIFF file using LZW
- * compression/decompression.  Note that the predictor
- * state block must be first in this data structure.
- */
-typedef struct {
-	TIFFPredictorState predict;     /* predictor super class */
-
-	unsigned short  nbits;          /* # of bits/code */
-	unsigned short  maxcode;        /* maximum code for lzw_nbits */
-	unsigned short  free_ent;       /* next free entry in hash table */
-	long            nextdata;       /* next bits of i/o */
-	long            nextbits;       /* # of valid bits in lzw_nextdata */
-
-	int             rw_mode;        /* preserve rw_mode from init */
-} LZWBaseState;
-
-#define lzw_nbits       base.nbits
-#define lzw_maxcode     base.maxcode
-#define lzw_free_ent    base.free_ent
-#define lzw_nextdata    base.nextdata
-#define lzw_nextbits    base.nextbits
-
-/*
- * Encoding-specific state.
- */
-typedef uint16 hcode_t;			/* codes fit in 16 bits */
-typedef struct {
-	long	hash;
-	hcode_t	code;
-} hash_t;
-
-/*
- * Decoding-specific state.
- */
-typedef struct code_ent {
-	struct code_ent *next;
-	unsigned short	length;		/* string len, including this token */
-	unsigned char	value;		/* data value */
-	unsigned char	firstchar;	/* first token of string */
-} code_t;
-
-typedef int (*decodeFunc)(TIFF*, uint8*, tmsize_t, uint16);
-
-typedef struct {
-	LZWBaseState base;
-
-	/* Decoding specific data */
-	long    dec_nbitsmask;		/* lzw_nbits 1 bits, right adjusted */
-	long    dec_restart;		/* restart count */
-#ifdef LZW_CHECKEOS
-	uint64  dec_bitsleft;		/* available bits in raw data */
-#endif
-	decodeFunc dec_decode;		/* regular or backwards compatible */
-	code_t* dec_codep;		/* current recognized code */
-	code_t* dec_oldcodep;		/* previously recognized code */
-	code_t* dec_free_entp;		/* next free entry */
-	code_t* dec_maxcodep;		/* max available entry */
-	code_t* dec_codetab;		/* kept separate for small machines */
-
-	/* Encoding specific data */
-	int     enc_oldcode;		/* last code encountered */
-	long    enc_checkpoint;		/* point at which to clear table */
-#define CHECK_GAP	10000		/* enc_ratio check interval */
-	long    enc_ratio;		/* current compression ratio */
-	long    enc_incount;		/* (input) data bytes encoded */
-	long    enc_outcount;		/* encoded (output) bytes */
-	uint8*  enc_rawlimit;		/* bound on tif_rawdata buffer */
-	hash_t* enc_hashtab;		/* kept separate for small machines */
-} LZWCodecState;
-
-#define LZWState(tif)		((LZWBaseState*) (tif)->tif_data)
-#define DecoderState(tif)	((LZWCodecState*) LZWState(tif))
-#define EncoderState(tif)	((LZWCodecState*) LZWState(tif))
-
-static int LZWDecode(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s);
-#ifdef LZW_COMPAT
-static int LZWDecodeCompat(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s);
-#endif
-static void cl_hash(LZWCodecState*);
-
-/*
- * LZW Decoder.
- */
-
-#ifdef LZW_CHECKEOS
-/*
- * This check shouldn't be necessary because each
- * strip is suppose to be terminated with CODE_EOI.
- */
-#define	NextCode(_tif, _sp, _bp, _code, _get) {				\
-	if ((_sp)->dec_bitsleft < (uint64)nbits) {			\
-		TIFFWarningExt(_tif->tif_clientdata, module,		\
-		    "LZWDecode: Strip %d not terminated with EOI code", \
-		    _tif->tif_curstrip);				\
-		_code = CODE_EOI;					\
-	} else {							\
-		_get(_sp,_bp,_code);					\
-		(_sp)->dec_bitsleft -= nbits;				\
-	}								\
-}
-#else
-#define	NextCode(tif, sp, bp, code, get) get(sp, bp, code)
-#endif
-
-static int
-LZWFixupTags(TIFF* tif)
-{
-	(void) tif;
-	return (1);
-}
-
-static int
-LZWSetupDecode(TIFF* tif)
-{
-	static const char module[] = "LZWSetupDecode";
-	LZWCodecState* sp = DecoderState(tif);
-	int code;
-
-	if( sp == NULL )
-	{
-		/*
-		 * Allocate state block so tag methods have storage to record
-		 * values.
-		*/
-		tif->tif_data = (uint8*) _TIFFmalloc(sizeof(LZWCodecState));
-		if (tif->tif_data == NULL)
-		{
-			TIFFErrorExt(tif->tif_clientdata, module, "No space for LZW state block");
-			return (0);
-		}
-
-		DecoderState(tif)->dec_codetab = NULL;
-		DecoderState(tif)->dec_decode = NULL;
-
-		/*
-		 * Setup predictor setup.
-		 */
-		(void) TIFFPredictorInit(tif);
-
-		sp = DecoderState(tif);
-	}
-
-	assert(sp != NULL);
-
-	if (sp->dec_codetab == NULL) {
-		sp->dec_codetab = (code_t*)_TIFFmalloc(CSIZE*sizeof (code_t));
-		if (sp->dec_codetab == NULL) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-				     "No space for LZW code table");
-			return (0);
-		}
-		/*
-		 * Pre-load the table.
-		 */
-		code = 255;
-		do {
-			sp->dec_codetab[code].value = code;
-			sp->dec_codetab[code].firstchar = code;
-			sp->dec_codetab[code].length = 1;
-			sp->dec_codetab[code].next = NULL;
-		} while (code--);
-		/*
-		 * Zero-out the unused entries
-                 */
-                 _TIFFmemset(&sp->dec_codetab[CODE_CLEAR], 0,
-			     (CODE_FIRST - CODE_CLEAR) * sizeof (code_t));
-	}
-	return (1);
-}
-
-/*
- * Setup state for decoding a strip.
- */
-static int
-LZWPreDecode(TIFF* tif, uint16 s)
-{
-	static const char module[] = "LZWPreDecode";
-	LZWCodecState *sp = DecoderState(tif);
-
-	(void) s;
-	assert(sp != NULL);
-	if( sp->dec_codetab == NULL )
-        {
-            tif->tif_setupdecode( tif );
-        }
-
-	/*
-	 * Check for old bit-reversed codes.
-	 */
-	if (tif->tif_rawdata[0] == 0 && (tif->tif_rawdata[1] & 0x1)) {
-#ifdef LZW_COMPAT
-		if (!sp->dec_decode) {
-			TIFFWarningExt(tif->tif_clientdata, module,
-			    "Old-style LZW codes, convert file");
-			/*
-			 * Override default decoding methods with
-			 * ones that deal with the old coding.
-			 * Otherwise the predictor versions set
-			 * above will call the compatibility routines
-			 * through the dec_decode method.
-			 */
-			tif->tif_decoderow = LZWDecodeCompat;
-			tif->tif_decodestrip = LZWDecodeCompat;
-			tif->tif_decodetile = LZWDecodeCompat;
-			/*
-			 * If doing horizontal differencing, must
-			 * re-setup the predictor logic since we
-			 * switched the basic decoder methods...
-			 */
-			(*tif->tif_setupdecode)(tif);
-			sp->dec_decode = LZWDecodeCompat;
-		}
-		sp->lzw_maxcode = MAXCODE(BITS_MIN);
-#else /* !LZW_COMPAT */
-		if (!sp->dec_decode) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-			    "Old-style LZW codes not supported");
-			sp->dec_decode = LZWDecode;
-		}
-		return (0);
-#endif/* !LZW_COMPAT */
-	} else {
-		sp->lzw_maxcode = MAXCODE(BITS_MIN)-1;
-		sp->dec_decode = LZWDecode;
-	}
-	sp->lzw_nbits = BITS_MIN;
-	sp->lzw_nextbits = 0;
-	sp->lzw_nextdata = 0;
-
-	sp->dec_restart = 0;
-	sp->dec_nbitsmask = MAXCODE(BITS_MIN);
-#ifdef LZW_CHECKEOS
-	sp->dec_bitsleft = ((uint64)tif->tif_rawcc) << 3;
-#endif
-	sp->dec_free_entp = sp->dec_codetab + CODE_FIRST;
-	/*
-	 * Zero entries that are not yet filled in.  We do
-	 * this to guard against bogus input data that causes
-	 * us to index into undefined entries.  If you can
-	 * come up with a way to safely bounds-check input codes
-	 * while decoding then you can remove this operation.
-	 */
-	_TIFFmemset(sp->dec_free_entp, 0, (CSIZE-CODE_FIRST)*sizeof (code_t));
-	sp->dec_oldcodep = &sp->dec_codetab[-1];
-	sp->dec_maxcodep = &sp->dec_codetab[sp->dec_nbitsmask-1];
-	return (1);
-}
-
-/*
- * Decode a "hunk of data".
- */
-#define	GetNextCode(sp, bp, code) {				\
-	nextdata = (nextdata<<8) | *(bp)++;			\
-	nextbits += 8;						\
-	if (nextbits < nbits) {					\
-		nextdata = (nextdata<<8) | *(bp)++;		\
-		nextbits += 8;					\
-	}							\
-	code = (hcode_t)((nextdata >> (nextbits-nbits)) & nbitsmask);	\
-	nextbits -= nbits;					\
-}
-
-static void
-codeLoop(TIFF* tif, const char* module)
-{
-	TIFFErrorExt(tif->tif_clientdata, module,
-	    "Bogus encoding, loop in the code table; scanline %d",
-	    tif->tif_row);
-}
-
-static int
-LZWDecode(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
-{
-	static const char module[] = "LZWDecode";
-	LZWCodecState *sp = DecoderState(tif);
-	char *op = (char*) op0;
-	long occ = (long) occ0;
-	char *tp;
-	unsigned char *bp;
-	hcode_t code;
-	int len;
-	long nbits, nextbits, nextdata, nbitsmask;
-	code_t *codep, *free_entp, *maxcodep, *oldcodep;
-
-	(void) s;
-	assert(sp != NULL);
-        assert(sp->dec_codetab != NULL);
-
-	/*
-	  Fail if value does not fit in long.
-	*/
-	if ((tmsize_t) occ != occ0)
-	        return (0);
-	/*
-	 * Restart interrupted output operation.
-	 */
-	if (sp->dec_restart) {
-		long residue;
-
-		codep = sp->dec_codep;
-		residue = codep->length - sp->dec_restart;
-		if (residue > occ) {
-			/*
-			 * Residue from previous decode is sufficient
-			 * to satisfy decode request.  Skip to the
-			 * start of the decoded string, place decoded
-			 * values in the output buffer, and return.
-			 */
-			sp->dec_restart += occ;
-			do {
-				codep = codep->next;
-			} while (--residue > occ && codep);
-			if (codep) {
-				tp = op + occ;
-				do {
-					*--tp = codep->value;
-					codep = codep->next;
-				} while (--occ && codep);
-			}
-			return (1);
-		}
-		/*
-		 * Residue satisfies only part of the decode request.
-		 */
-		op += residue, occ -= residue;
-		tp = op;
-		do {
-			int t;
-			--tp;
-			t = codep->value;
-			codep = codep->next;
-			*tp = t;
-		} while (--residue && codep);
-		sp->dec_restart = 0;
-	}
-
-	bp = (unsigned char *)tif->tif_rawcp;
-	nbits = sp->lzw_nbits;
-	nextdata = sp->lzw_nextdata;
-	nextbits = sp->lzw_nextbits;
-	nbitsmask = sp->dec_nbitsmask;
-	oldcodep = sp->dec_oldcodep;
-	free_entp = sp->dec_free_entp;
-	maxcodep = sp->dec_maxcodep;
-
-	while (occ > 0) {
-		NextCode(tif, sp, bp, code, GetNextCode);
-		if (code == CODE_EOI)
-			break;
-		if (code == CODE_CLEAR) {
-			free_entp = sp->dec_codetab + CODE_FIRST;
-			_TIFFmemset(free_entp, 0,
-				    (CSIZE - CODE_FIRST) * sizeof (code_t));
-			nbits = BITS_MIN;
-			nbitsmask = MAXCODE(BITS_MIN);
-			maxcodep = sp->dec_codetab + nbitsmask-1;
-			NextCode(tif, sp, bp, code, GetNextCode);
-			if (code == CODE_EOI)
-				break;
-			if (code >= CODE_CLEAR) {
-				TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-				"LZWDecode: Corrupted LZW table at scanline %d",
-					     tif->tif_row);
-				return (0);
-			}
-			*op++ = (char)code, occ--;
-			oldcodep = sp->dec_codetab + code;
-			continue;
-		}
-		codep = sp->dec_codetab + code;
-
-		/*
-		 * Add the new entry to the code table.
-		 */
-		if (free_entp < &sp->dec_codetab[0] ||
-		    free_entp >= &sp->dec_codetab[CSIZE]) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-			    "Corrupted LZW table at scanline %d",
-			    tif->tif_row);
-			return (0);
-		}
-
-		free_entp->next = oldcodep;
-		if (free_entp->next < &sp->dec_codetab[0] ||
-		    free_entp->next >= &sp->dec_codetab[CSIZE]) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-			    "Corrupted LZW table at scanline %d",
-			    tif->tif_row);
-			return (0);
-		}
-		free_entp->firstchar = free_entp->next->firstchar;
-		free_entp->length = free_entp->next->length+1;
-		free_entp->value = (codep < free_entp) ?
-		    codep->firstchar : free_entp->firstchar;
-		if (++free_entp > maxcodep) {
-			if (++nbits > BITS_MAX)		/* should not happen */
-				nbits = BITS_MAX;
-			nbitsmask = MAXCODE(nbits);
-			maxcodep = sp->dec_codetab + nbitsmask-1;
-		}
-		oldcodep = codep;
-		if (code >= 256) {
-			/*
-			 * Code maps to a string, copy string
-			 * value to output (written in reverse).
-			 */
-			if(codep->length == 0) {
-				TIFFErrorExt(tif->tif_clientdata, module,
-				    "Wrong length of decoded string: "
-				    "data probably corrupted at scanline %d",
-				    tif->tif_row);
-				return (0);
-			}
-			if (codep->length > occ) {
-				/*
-				 * String is too long for decode buffer,
-				 * locate portion that will fit, copy to
-				 * the decode buffer, and setup restart
-				 * logic for the next decoding call.
-				 */
-				sp->dec_codep = codep;
-				do {
-					codep = codep->next;
-				} while (codep && codep->length > occ);
-				if (codep) {
-					sp->dec_restart = (long)occ;
-					tp = op + occ;
-					do  {
-						*--tp = codep->value;
-						codep = codep->next;
-					}  while (--occ && codep);
-					if (codep)
-						codeLoop(tif, module);
-				}
-				break;
-			}
-			len = codep->length;
-			tp = op + len;
-			do {
-				int t;
-				--tp;
-				t = codep->value;
-				codep = codep->next;
-				*tp = t;
-			} while (codep && tp > op);
-			if (codep) {
-			    codeLoop(tif, module);
-			    break;
-			}
-			assert(occ >= len);
-			op += len, occ -= len;
-		} else
-			*op++ = (char)code, occ--;
-	}
-
-	tif->tif_rawcp = (uint8*) bp;
-	sp->lzw_nbits = (unsigned short) nbits;
-	sp->lzw_nextdata = nextdata;
-	sp->lzw_nextbits = nextbits;
-	sp->dec_nbitsmask = nbitsmask;
-	sp->dec_oldcodep = oldcodep;
-	sp->dec_free_entp = free_entp;
-	sp->dec_maxcodep = maxcodep;
-
-	if (occ > 0) {
-#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
-		TIFFErrorExt(tif->tif_clientdata, module,
-			"Not enough data at scanline %d (short %I64d bytes)",
-			     tif->tif_row, (unsigned __int64) occ);
-#else
-		TIFFErrorExt(tif->tif_clientdata, module,
-			"Not enough data at scanline %d (short %llu bytes)",
-			     tif->tif_row, (unsigned long long) occ);
-#endif
-		return (0);
-	}
-	return (1);
-}
-
-#ifdef LZW_COMPAT
-/*
- * Decode a "hunk of data" for old images.
- */
-#define	GetNextCodeCompat(sp, bp, code) {			\
-	nextdata |= (unsigned long) *(bp)++ << nextbits;	\
-	nextbits += 8;						\
-	if (nextbits < nbits) {					\
-		nextdata |= (unsigned long) *(bp)++ << nextbits;\
-		nextbits += 8;					\
-	}							\
-	code = (hcode_t)(nextdata & nbitsmask);			\
-	nextdata >>= nbits;					\
-	nextbits -= nbits;					\
-}
-
-static int
-LZWDecodeCompat(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
-{
-	static const char module[] = "LZWDecodeCompat";
-	LZWCodecState *sp = DecoderState(tif);
-	char *op = (char*) op0;
-	long occ = (long) occ0;
-	char *tp;
-	unsigned char *bp;
-	int code, nbits;
-	long nextbits, nextdata, nbitsmask;
-	code_t *codep, *free_entp, *maxcodep, *oldcodep;
-
-	(void) s;
-	assert(sp != NULL);
-
-	/*
-	  Fail if value does not fit in long.
-	*/
-	if ((tmsize_t) occ != occ0)
-	        return (0);
-
-	/*
-	 * Restart interrupted output operation.
-	 */
-	if (sp->dec_restart) {
-		long residue;
-
-		codep = sp->dec_codep;
-		residue = codep->length - sp->dec_restart;
-		if (residue > occ) {
-			/*
-			 * Residue from previous decode is sufficient
-			 * to satisfy decode request.  Skip to the
-			 * start of the decoded string, place decoded
-			 * values in the output buffer, and return.
-			 */
-			sp->dec_restart += occ;
-			do {
-				codep = codep->next;
-			} while (--residue > occ);
-			tp = op + occ;
-			do {
-				*--tp = codep->value;
-				codep = codep->next;
-			} while (--occ);
-			return (1);
-		}
-		/*
-		 * Residue satisfies only part of the decode request.
-		 */
-		op += residue, occ -= residue;
-		tp = op;
-		do {
-			*--tp = codep->value;
-			codep = codep->next;
-		} while (--residue);
-		sp->dec_restart = 0;
-	}
-
-	bp = (unsigned char *)tif->tif_rawcp;
-	nbits = sp->lzw_nbits;
-	nextdata = sp->lzw_nextdata;
-	nextbits = sp->lzw_nextbits;
-	nbitsmask = sp->dec_nbitsmask;
-	oldcodep = sp->dec_oldcodep;
-	free_entp = sp->dec_free_entp;
-	maxcodep = sp->dec_maxcodep;
-
-	while (occ > 0) {
-		NextCode(tif, sp, bp, code, GetNextCodeCompat);
-		if (code == CODE_EOI)
-			break;
-		if (code == CODE_CLEAR) {
-			free_entp = sp->dec_codetab + CODE_FIRST;
-			_TIFFmemset(free_entp, 0,
-				    (CSIZE - CODE_FIRST) * sizeof (code_t));
-			nbits = BITS_MIN;
-			nbitsmask = MAXCODE(BITS_MIN);
-			maxcodep = sp->dec_codetab + nbitsmask;
-			NextCode(tif, sp, bp, code, GetNextCodeCompat);
-			if (code == CODE_EOI)
-				break;
-			if (code >= CODE_CLEAR) {
-				TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-				"LZWDecode: Corrupted LZW table at scanline %d",
-					     tif->tif_row);
-				return (0);
-			}
-			*op++ = code, occ--;
-			oldcodep = sp->dec_codetab + code;
-			continue;
-		}
-		codep = sp->dec_codetab + code;
-
-		/*
-		 * Add the new entry to the code table.
-		 */
-		if (free_entp < &sp->dec_codetab[0] ||
-		    free_entp >= &sp->dec_codetab[CSIZE]) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-			    "Corrupted LZW table at scanline %d", tif->tif_row);
-			return (0);
-		}
-
-		free_entp->next = oldcodep;
-		if (free_entp->next < &sp->dec_codetab[0] ||
-		    free_entp->next >= &sp->dec_codetab[CSIZE]) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-			    "Corrupted LZW table at scanline %d", tif->tif_row);
-			return (0);
-		}
-		free_entp->firstchar = free_entp->next->firstchar;
-		free_entp->length = free_entp->next->length+1;
-		free_entp->value = (codep < free_entp) ?
-		    codep->firstchar : free_entp->firstchar;
-		if (++free_entp > maxcodep) {
-			if (++nbits > BITS_MAX)		/* should not happen */
-				nbits = BITS_MAX;
-			nbitsmask = MAXCODE(nbits);
-			maxcodep = sp->dec_codetab + nbitsmask;
-		}
-		oldcodep = codep;
-		if (code >= 256) {
-			/*
-			 * Code maps to a string, copy string
-			 * value to output (written in reverse).
-			 */
-			if(codep->length == 0) {
-				TIFFErrorExt(tif->tif_clientdata, module,
-				    "Wrong length of decoded "
-				    "string: data probably corrupted at scanline %d",
-				    tif->tif_row);
-				return (0);
-			}
-			if (codep->length > occ) {
-				/*
-				 * String is too long for decode buffer,
-				 * locate portion that will fit, copy to
-				 * the decode buffer, and setup restart
-				 * logic for the next decoding call.
-				 */
-				sp->dec_codep = codep;
-				do {
-					codep = codep->next;
-				} while (codep->length > occ);
-				sp->dec_restart = occ;
-				tp = op + occ;
-				do  {
-					*--tp = codep->value;
-					codep = codep->next;
-				}  while (--occ);
-				break;
-			}
-			assert(occ >= codep->length);
-			op += codep->length, occ -= codep->length;
-			tp = op;
-			do {
-				*--tp = codep->value;
-			} while( (codep = codep->next) != NULL );
-		} else
-			*op++ = code, occ--;
-	}
-
-	tif->tif_rawcp = (uint8*) bp;
-	sp->lzw_nbits = nbits;
-	sp->lzw_nextdata = nextdata;
-	sp->lzw_nextbits = nextbits;
-	sp->dec_nbitsmask = nbitsmask;
-	sp->dec_oldcodep = oldcodep;
-	sp->dec_free_entp = free_entp;
-	sp->dec_maxcodep = maxcodep;
-
-	if (occ > 0) {
-#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
-		TIFFErrorExt(tif->tif_clientdata, module,
-			"Not enough data at scanline %d (short %I64d bytes)",
-			     tif->tif_row, (unsigned __int64) occ);
-#else
-		TIFFErrorExt(tif->tif_clientdata, module,
-			"Not enough data at scanline %d (short %llu bytes)",
-			     tif->tif_row, (unsigned long long) occ);
-#endif
-		return (0);
-	}
-	return (1);
-}
-#endif /* LZW_COMPAT */
-
-/*
- * LZW Encoding.
- */
-
-static int
-LZWSetupEncode(TIFF* tif)
-{
-	static const char module[] = "LZWSetupEncode";
-	LZWCodecState* sp = EncoderState(tif);
-
-	assert(sp != NULL);
-	sp->enc_hashtab = (hash_t*) _TIFFmalloc(HSIZE*sizeof (hash_t));
-	if (sp->enc_hashtab == NULL) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-			     "No space for LZW hash table");
-		return (0);
-	}
-	return (1);
-}
-
-/*
- * Reset encoding state at the start of a strip.
- */
-static int
-LZWPreEncode(TIFF* tif, uint16 s)
-{
-	LZWCodecState *sp = EncoderState(tif);
-
-	(void) s;
-	assert(sp != NULL);
-
-	if( sp->enc_hashtab == NULL )
-        {
-            tif->tif_setupencode( tif );
-        }
-
-	sp->lzw_nbits = BITS_MIN;
-	sp->lzw_maxcode = MAXCODE(BITS_MIN);
-	sp->lzw_free_ent = CODE_FIRST;
-	sp->lzw_nextbits = 0;
-	sp->lzw_nextdata = 0;
-	sp->enc_checkpoint = CHECK_GAP;
-	sp->enc_ratio = 0;
-	sp->enc_incount = 0;
-	sp->enc_outcount = 0;
-	/*
-	 * The 4 here insures there is space for 2 max-sized
-	 * codes in LZWEncode and LZWPostDecode.
-	 */
-	sp->enc_rawlimit = tif->tif_rawdata + tif->tif_rawdatasize-1 - 4;
-	cl_hash(sp);		/* clear hash table */
-	sp->enc_oldcode = (hcode_t) -1;	/* generates CODE_CLEAR in LZWEncode */
-	return (1);
-}
-
-#define	CALCRATIO(sp, rat) {					\
-	if (incount > 0x007fffff) { /* NB: shift will overflow */\
-		rat = outcount >> 8;				\
-		rat = (rat == 0 ? 0x7fffffff : incount/rat);	\
-	} else							\
-		rat = (incount<<8) / outcount;			\
-}
-#define	PutNextCode(op, c) {					\
-	nextdata = (nextdata << nbits) | c;			\
-	nextbits += nbits;					\
-	*op++ = (unsigned char)(nextdata >> (nextbits-8));		\
-	nextbits -= 8;						\
-	if (nextbits >= 8) {					\
-		*op++ = (unsigned char)(nextdata >> (nextbits-8));	\
-		nextbits -= 8;					\
-	}							\
-	outcount += nbits;					\
-}
-
-/*
- * Encode a chunk of pixels.
- *
- * Uses an open addressing double hashing (no chaining) on the 
- * prefix code/next character combination.  We do a variant of
- * Knuth's algorithm D (vol. 3, sec. 6.4) along with G. Knott's
- * relatively-prime secondary probe.  Here, the modular division
- * first probe is gives way to a faster exclusive-or manipulation. 
- * Also do block compression with an adaptive reset, whereby the
- * code table is cleared when the compression ratio decreases,
- * but after the table fills.  The variable-length output codes
- * are re-sized at this point, and a CODE_CLEAR is generated
- * for the decoder. 
- */
-static int
-LZWEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
-{
-	register LZWCodecState *sp = EncoderState(tif);
-	register long fcode;
-	register hash_t *hp;
-	register int h, c;
-	hcode_t ent;
-	long disp;
-	long incount, outcount, checkpoint;
-	long nextdata, nextbits;
-	int free_ent, maxcode, nbits;
-	uint8* op;
-	uint8* limit;
-
-	(void) s;
-	if (sp == NULL)
-		return (0);
-
-        assert(sp->enc_hashtab != NULL);
-
-	/*
-	 * Load local state.
-	 */
-	incount = sp->enc_incount;
-	outcount = sp->enc_outcount;
-	checkpoint = sp->enc_checkpoint;
-	nextdata = sp->lzw_nextdata;
-	nextbits = sp->lzw_nextbits;
-	free_ent = sp->lzw_free_ent;
-	maxcode = sp->lzw_maxcode;
-	nbits = sp->lzw_nbits;
-	op = tif->tif_rawcp;
-	limit = sp->enc_rawlimit;
-	ent = sp->enc_oldcode;
-
-	if (ent == (hcode_t) -1 && cc > 0) {
-		/*
-		 * NB: This is safe because it can only happen
-		 *     at the start of a strip where we know there
-		 *     is space in the data buffer.
-		 */
-		PutNextCode(op, CODE_CLEAR);
-		ent = *bp++; cc--; incount++;
-	}
-	while (cc > 0) {
-		c = *bp++; cc--; incount++;
-		fcode = ((long)c << BITS_MAX) + ent;
-		h = (c << HSHIFT) ^ ent;	/* xor hashing */
-#ifdef _WINDOWS
-		/*
-		 * Check hash index for an overflow.
-		 */
-		if (h >= HSIZE)
-			h -= HSIZE;
-#endif
-		hp = &sp->enc_hashtab[h];
-		if (hp->hash == fcode) {
-			ent = hp->code;
-			continue;
-		}
-		if (hp->hash >= 0) {
-			/*
-			 * Primary hash failed, check secondary hash.
-			 */
-			disp = HSIZE - h;
-			if (h == 0)
-				disp = 1;
-			do {
-				/*
-				 * Avoid pointer arithmetic 'cuz of
-				 * wraparound problems with segments.
-				 */
-				if ((h -= disp) < 0)
-					h += HSIZE;
-				hp = &sp->enc_hashtab[h];
-				if (hp->hash == fcode) {
-					ent = hp->code;
-					goto hit;
-				}
-			} while (hp->hash >= 0);
-		}
-		/*
-		 * New entry, emit code and add to table.
-		 */
-		/*
-		 * Verify there is space in the buffer for the code
-		 * and any potential Clear code that might be emitted
-		 * below.  The value of limit is setup so that there
-		 * are at least 4 bytes free--room for 2 codes.
-		 */
-		if (op > limit) {
-			tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata);
-			TIFFFlushData1(tif);
-			op = tif->tif_rawdata;
-		}
-		PutNextCode(op, ent);
-		ent = c;
-		hp->code = free_ent++;
-		hp->hash = fcode;
-		if (free_ent == CODE_MAX-1) {
-			/* table is full, emit clear code and reset */
-			cl_hash(sp);
-			sp->enc_ratio = 0;
-			incount = 0;
-			outcount = 0;
-			free_ent = CODE_FIRST;
-			PutNextCode(op, CODE_CLEAR);
-			nbits = BITS_MIN;
-			maxcode = MAXCODE(BITS_MIN);
-		} else {
-			/*
-			 * If the next entry is going to be too big for
-			 * the code size, then increase it, if possible.
-			 */
-			if (free_ent > maxcode) {
-				nbits++;
-				assert(nbits <= BITS_MAX);
-				maxcode = (int) MAXCODE(nbits);
-			} else if (incount >= checkpoint) {
-				long rat;
-				/*
-				 * Check compression ratio and, if things seem
-				 * to be slipping, clear the hash table and
-				 * reset state.  The compression ratio is a
-				 * 24+8-bit fractional number.
-				 */
-				checkpoint = incount+CHECK_GAP;
-				CALCRATIO(sp, rat);
-				if (rat <= sp->enc_ratio) {
-					cl_hash(sp);
-					sp->enc_ratio = 0;
-					incount = 0;
-					outcount = 0;
-					free_ent = CODE_FIRST;
-					PutNextCode(op, CODE_CLEAR);
-					nbits = BITS_MIN;
-					maxcode = MAXCODE(BITS_MIN);
-				} else
-					sp->enc_ratio = rat;
-			}
-		}
-	hit:
-		;
-	}
-
-	/*
-	 * Restore global state.
-	 */
-	sp->enc_incount = incount;
-	sp->enc_outcount = outcount;
-	sp->enc_checkpoint = checkpoint;
-	sp->enc_oldcode = ent;
-	sp->lzw_nextdata = nextdata;
-	sp->lzw_nextbits = nextbits;
-	sp->lzw_free_ent = free_ent;
-	sp->lzw_maxcode = maxcode;
-	sp->lzw_nbits = nbits;
-	tif->tif_rawcp = op;
-	return (1);
-}
-
-/*
- * Finish off an encoded strip by flushing the last
- * string and tacking on an End Of Information code.
- */
-static int
-LZWPostEncode(TIFF* tif)
-{
-	register LZWCodecState *sp = EncoderState(tif);
-	uint8* op = tif->tif_rawcp;
-	long nextbits = sp->lzw_nextbits;
-	long nextdata = sp->lzw_nextdata;
-	long outcount = sp->enc_outcount;
-	int nbits = sp->lzw_nbits;
-
-	if (op > sp->enc_rawlimit) {
-		tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata);
-		TIFFFlushData1(tif);
-		op = tif->tif_rawdata;
-	}
-	if (sp->enc_oldcode != (hcode_t) -1) {
-		PutNextCode(op, sp->enc_oldcode);
-		sp->enc_oldcode = (hcode_t) -1;
-	}
-	PutNextCode(op, CODE_EOI);
-	if (nextbits > 0) 
-		*op++ = (unsigned char)(nextdata << (8-nextbits));
-	tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata);
-	return (1);
-}
-
-/*
- * Reset encoding hash table.
- */
-static void
-cl_hash(LZWCodecState* sp)
-{
-	register hash_t *hp = &sp->enc_hashtab[HSIZE-1];
-	register long i = HSIZE-8;
-
-	do {
-		i -= 8;
-		hp[-7].hash = -1;
-		hp[-6].hash = -1;
-		hp[-5].hash = -1;
-		hp[-4].hash = -1;
-		hp[-3].hash = -1;
-		hp[-2].hash = -1;
-		hp[-1].hash = -1;
-		hp[ 0].hash = -1;
-		hp -= 8;
-	} while (i >= 0);
-	for (i += 8; i > 0; i--, hp--)
-		hp->hash = -1;
-}
-
-static void
-LZWCleanup(TIFF* tif)
-{
-	(void)TIFFPredictorCleanup(tif);
-
-	assert(tif->tif_data != 0);
-
-	if (DecoderState(tif)->dec_codetab)
-		_TIFFfree(DecoderState(tif)->dec_codetab);
-
-	if (EncoderState(tif)->enc_hashtab)
-		_TIFFfree(EncoderState(tif)->enc_hashtab);
-
-	_TIFFfree(tif->tif_data);
-	tif->tif_data = NULL;
-
-	_TIFFSetDefaultCompressionState(tif);
-}
-
-int
-TIFFInitLZW(TIFF* tif, int scheme)
-{
-	static const char module[] = "TIFFInitLZW";
-	assert(scheme == COMPRESSION_LZW);
-	/*
-	 * Allocate state block so tag methods have storage to record values.
-	 */
-	tif->tif_data = (uint8*) _TIFFmalloc(sizeof (LZWCodecState));
-	if (tif->tif_data == NULL)
-		goto bad;
-	DecoderState(tif)->dec_codetab = NULL;
-	DecoderState(tif)->dec_decode = NULL;
-	EncoderState(tif)->enc_hashtab = NULL;
-        LZWState(tif)->rw_mode = tif->tif_mode;
-
-	/*
-	 * Install codec methods.
-	 */
-	tif->tif_fixuptags = LZWFixupTags; 
-	tif->tif_setupdecode = LZWSetupDecode;
-	tif->tif_predecode = LZWPreDecode;
-	tif->tif_decoderow = LZWDecode;
-	tif->tif_decodestrip = LZWDecode;
-	tif->tif_decodetile = LZWDecode;
-	tif->tif_setupencode = LZWSetupEncode;
-	tif->tif_preencode = LZWPreEncode;
-	tif->tif_postencode = LZWPostEncode;
-	tif->tif_encoderow = LZWEncode;
-	tif->tif_encodestrip = LZWEncode;
-	tif->tif_encodetile = LZWEncode;
-	tif->tif_cleanup = LZWCleanup;
-	/*
-	 * Setup predictor setup.
-	 */
-	(void) TIFFPredictorInit(tif);
-	return (1);
-bad:
-	TIFFErrorExt(tif->tif_clientdata, module, 
-		     "No space for LZW state block");
-	return (0);
-}
-
-/*
- * Copyright (c) 1985, 1986 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * James A. Woods, derived from original work by Spencer Thomas
- * and Joseph Orost.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-#endif /* LZW_SUPPORT */
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Id: tif_lzw.c,v 1.11 2015/02/19 22:39:58 drolon Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and 
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
+ * 
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
+ * OF THIS SOFTWARE.
+ */
+
+#include "tiffiop.h"
+#ifdef LZW_SUPPORT
+/*
+ * TIFF Library.  
+ * Rev 5.0 Lempel-Ziv & Welch Compression Support
+ *
+ * This code is derived from the compress program whose code is
+ * derived from software contributed to Berkeley by James A. Woods,
+ * derived from original work by Spencer Thomas and Joseph Orost.
+ *
+ * The original Berkeley copyright notice appears below in its entirety.
+ */
+#include "tif_predict.h"
+
+#include <stdio.h>
+
+/*
+ * NB: The 5.0 spec describes a different algorithm than Aldus
+ *     implements.  Specifically, Aldus does code length transitions
+ *     one code earlier than should be done (for real LZW).
+ *     Earlier versions of this library implemented the correct
+ *     LZW algorithm, but emitted codes in a bit order opposite
+ *     to the TIFF spec.  Thus, to maintain compatibility w/ Aldus
+ *     we interpret MSB-LSB ordered codes to be images written w/
+ *     old versions of this library, but otherwise adhere to the
+ *     Aldus "off by one" algorithm.
+ *
+ * Future revisions to the TIFF spec are expected to "clarify this issue".
+ */
+#define LZW_COMPAT              /* include backwards compatibility code */
+/*
+ * Each strip of data is supposed to be terminated by a CODE_EOI.
+ * If the following #define is included, the decoder will also
+ * check for end-of-strip w/o seeing this code.  This makes the
+ * library more robust, but also slower.
+ */
+#define LZW_CHECKEOS            /* include checks for strips w/o EOI code */
+
+#define MAXCODE(n)	((1L<<(n))-1)
+/*
+ * The TIFF spec specifies that encoded bit
+ * strings range from 9 to 12 bits.
+ */
+#define BITS_MIN        9               /* start with 9 bits */
+#define BITS_MAX        12              /* max of 12 bit strings */
+/* predefined codes */
+#define CODE_CLEAR      256             /* code to clear string table */
+#define CODE_EOI        257             /* end-of-information code */
+#define CODE_FIRST      258             /* first free code entry */
+#define CODE_MAX        MAXCODE(BITS_MAX)
+#define HSIZE           9001L           /* 91% occupancy */
+#define HSHIFT          (13-8)
+#ifdef LZW_COMPAT
+/* NB: +1024 is for compatibility with old files */
+#define CSIZE           (MAXCODE(BITS_MAX)+1024L)
+#else
+#define CSIZE           (MAXCODE(BITS_MAX)+1L)
+#endif
+
+/*
+ * State block for each open TIFF file using LZW
+ * compression/decompression.  Note that the predictor
+ * state block must be first in this data structure.
+ */
+typedef struct {
+	TIFFPredictorState predict;     /* predictor super class */
+
+	unsigned short  nbits;          /* # of bits/code */
+	unsigned short  maxcode;        /* maximum code for lzw_nbits */
+	unsigned short  free_ent;       /* next free entry in hash table */
+	long            nextdata;       /* next bits of i/o */
+	long            nextbits;       /* # of valid bits in lzw_nextdata */
+
+	int             rw_mode;        /* preserve rw_mode from init */
+} LZWBaseState;
+
+#define lzw_nbits       base.nbits
+#define lzw_maxcode     base.maxcode
+#define lzw_free_ent    base.free_ent
+#define lzw_nextdata    base.nextdata
+#define lzw_nextbits    base.nextbits
+
+/*
+ * Encoding-specific state.
+ */
+typedef uint16 hcode_t;			/* codes fit in 16 bits */
+typedef struct {
+	long	hash;
+	hcode_t	code;
+} hash_t;
+
+/*
+ * Decoding-specific state.
+ */
+typedef struct code_ent {
+	struct code_ent *next;
+	unsigned short	length;		/* string len, including this token */
+	unsigned char	value;		/* data value */
+	unsigned char	firstchar;	/* first token of string */
+} code_t;
+
+typedef int (*decodeFunc)(TIFF*, uint8*, tmsize_t, uint16);
+
+typedef struct {
+	LZWBaseState base;
+
+	/* Decoding specific data */
+	long    dec_nbitsmask;		/* lzw_nbits 1 bits, right adjusted */
+	long    dec_restart;		/* restart count */
+#ifdef LZW_CHECKEOS
+	uint64  dec_bitsleft;		/* available bits in raw data */
+#endif
+	decodeFunc dec_decode;		/* regular or backwards compatible */
+	code_t* dec_codep;		/* current recognized code */
+	code_t* dec_oldcodep;		/* previously recognized code */
+	code_t* dec_free_entp;		/* next free entry */
+	code_t* dec_maxcodep;		/* max available entry */
+	code_t* dec_codetab;		/* kept separate for small machines */
+
+	/* Encoding specific data */
+	int     enc_oldcode;		/* last code encountered */
+	long    enc_checkpoint;		/* point at which to clear table */
+#define CHECK_GAP	10000		/* enc_ratio check interval */
+	long    enc_ratio;		/* current compression ratio */
+	long    enc_incount;		/* (input) data bytes encoded */
+	long    enc_outcount;		/* encoded (output) bytes */
+	uint8*  enc_rawlimit;		/* bound on tif_rawdata buffer */
+	hash_t* enc_hashtab;		/* kept separate for small machines */
+} LZWCodecState;
+
+#define LZWState(tif)		((LZWBaseState*) (tif)->tif_data)
+#define DecoderState(tif)	((LZWCodecState*) LZWState(tif))
+#define EncoderState(tif)	((LZWCodecState*) LZWState(tif))
+
+static int LZWDecode(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s);
+#ifdef LZW_COMPAT
+static int LZWDecodeCompat(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s);
+#endif
+static void cl_hash(LZWCodecState*);
+
+/*
+ * LZW Decoder.
+ */
+
+#ifdef LZW_CHECKEOS
+/*
+ * This check shouldn't be necessary because each
+ * strip is suppose to be terminated with CODE_EOI.
+ */
+#define	NextCode(_tif, _sp, _bp, _code, _get) {				\
+	if ((_sp)->dec_bitsleft < (uint64)nbits) {			\
+		TIFFWarningExt(_tif->tif_clientdata, module,		\
+		    "LZWDecode: Strip %d not terminated with EOI code", \
+		    _tif->tif_curstrip);				\
+		_code = CODE_EOI;					\
+	} else {							\
+		_get(_sp,_bp,_code);					\
+		(_sp)->dec_bitsleft -= nbits;				\
+	}								\
+}
+#else
+#define	NextCode(tif, sp, bp, code, get) get(sp, bp, code)
+#endif
+
+static int
+LZWFixupTags(TIFF* tif)
+{
+	(void) tif;
+	return (1);
+}
+
+static int
+LZWSetupDecode(TIFF* tif)
+{
+	static const char module[] = "LZWSetupDecode";
+	LZWCodecState* sp = DecoderState(tif);
+	int code;
+
+	if( sp == NULL )
+	{
+		/*
+		 * Allocate state block so tag methods have storage to record
+		 * values.
+		*/
+		tif->tif_data = (uint8*) _TIFFmalloc(sizeof(LZWCodecState));
+		if (tif->tif_data == NULL)
+		{
+			TIFFErrorExt(tif->tif_clientdata, module, "No space for LZW state block");
+			return (0);
+		}
+
+		DecoderState(tif)->dec_codetab = NULL;
+		DecoderState(tif)->dec_decode = NULL;
+
+		/*
+		 * Setup predictor setup.
+		 */
+		(void) TIFFPredictorInit(tif);
+
+		sp = DecoderState(tif);
+	}
+
+	assert(sp != NULL);
+
+	if (sp->dec_codetab == NULL) {
+		sp->dec_codetab = (code_t*)_TIFFmalloc(CSIZE*sizeof (code_t));
+		if (sp->dec_codetab == NULL) {
+			TIFFErrorExt(tif->tif_clientdata, module,
+				     "No space for LZW code table");
+			return (0);
+		}
+		/*
+		 * Pre-load the table.
+		 */
+		code = 255;
+		do {
+			sp->dec_codetab[code].value = code;
+			sp->dec_codetab[code].firstchar = code;
+			sp->dec_codetab[code].length = 1;
+			sp->dec_codetab[code].next = NULL;
+		} while (code--);
+		/*
+		 * Zero-out the unused entries
+                 */
+                 _TIFFmemset(&sp->dec_codetab[CODE_CLEAR], 0,
+			     (CODE_FIRST - CODE_CLEAR) * sizeof (code_t));
+	}
+	return (1);
+}
+
+/*
+ * Setup state for decoding a strip.
+ */
+static int
+LZWPreDecode(TIFF* tif, uint16 s)
+{
+	static const char module[] = "LZWPreDecode";
+	LZWCodecState *sp = DecoderState(tif);
+
+	(void) s;
+	assert(sp != NULL);
+	if( sp->dec_codetab == NULL )
+        {
+            tif->tif_setupdecode( tif );
+	    if( sp->dec_codetab == NULL )
+		return (0);
+        }
+
+	/*
+	 * Check for old bit-reversed codes.
+	 */
+	if (tif->tif_rawdata[0] == 0 && (tif->tif_rawdata[1] & 0x1)) {
+#ifdef LZW_COMPAT
+		if (!sp->dec_decode) {
+			TIFFWarningExt(tif->tif_clientdata, module,
+			    "Old-style LZW codes, convert file");
+			/*
+			 * Override default decoding methods with
+			 * ones that deal with the old coding.
+			 * Otherwise the predictor versions set
+			 * above will call the compatibility routines
+			 * through the dec_decode method.
+			 */
+			tif->tif_decoderow = LZWDecodeCompat;
+			tif->tif_decodestrip = LZWDecodeCompat;
+			tif->tif_decodetile = LZWDecodeCompat;
+			/*
+			 * If doing horizontal differencing, must
+			 * re-setup the predictor logic since we
+			 * switched the basic decoder methods...
+			 */
+			(*tif->tif_setupdecode)(tif);
+			sp->dec_decode = LZWDecodeCompat;
+		}
+		sp->lzw_maxcode = MAXCODE(BITS_MIN);
+#else /* !LZW_COMPAT */
+		if (!sp->dec_decode) {
+			TIFFErrorExt(tif->tif_clientdata, module,
+			    "Old-style LZW codes not supported");
+			sp->dec_decode = LZWDecode;
+		}
+		return (0);
+#endif/* !LZW_COMPAT */
+	} else {
+		sp->lzw_maxcode = MAXCODE(BITS_MIN)-1;
+		sp->dec_decode = LZWDecode;
+	}
+	sp->lzw_nbits = BITS_MIN;
+	sp->lzw_nextbits = 0;
+	sp->lzw_nextdata = 0;
+
+	sp->dec_restart = 0;
+	sp->dec_nbitsmask = MAXCODE(BITS_MIN);
+#ifdef LZW_CHECKEOS
+	sp->dec_bitsleft = ((uint64)tif->tif_rawcc) << 3;
+#endif
+	sp->dec_free_entp = sp->dec_codetab + CODE_FIRST;
+	/*
+	 * Zero entries that are not yet filled in.  We do
+	 * this to guard against bogus input data that causes
+	 * us to index into undefined entries.  If you can
+	 * come up with a way to safely bounds-check input codes
+	 * while decoding then you can remove this operation.
+	 */
+	_TIFFmemset(sp->dec_free_entp, 0, (CSIZE-CODE_FIRST)*sizeof (code_t));
+	sp->dec_oldcodep = &sp->dec_codetab[-1];
+	sp->dec_maxcodep = &sp->dec_codetab[sp->dec_nbitsmask-1];
+	return (1);
+}
+
+/*
+ * Decode a "hunk of data".
+ */
+#define	GetNextCode(sp, bp, code) {				\
+	nextdata = (nextdata<<8) | *(bp)++;			\
+	nextbits += 8;						\
+	if (nextbits < nbits) {					\
+		nextdata = (nextdata<<8) | *(bp)++;		\
+		nextbits += 8;					\
+	}							\
+	code = (hcode_t)((nextdata >> (nextbits-nbits)) & nbitsmask);	\
+	nextbits -= nbits;					\
+}
+
+static void
+codeLoop(TIFF* tif, const char* module)
+{
+	TIFFErrorExt(tif->tif_clientdata, module,
+	    "Bogus encoding, loop in the code table; scanline %d",
+	    tif->tif_row);
+}
+
+static int
+LZWDecode(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
+{
+	static const char module[] = "LZWDecode";
+	LZWCodecState *sp = DecoderState(tif);
+	char *op = (char*) op0;
+	long occ = (long) occ0;
+	char *tp;
+	unsigned char *bp;
+	hcode_t code;
+	int len;
+	long nbits, nextbits, nextdata, nbitsmask;
+	code_t *codep, *free_entp, *maxcodep, *oldcodep;
+
+	(void) s;
+	assert(sp != NULL);
+        assert(sp->dec_codetab != NULL);
+
+	/*
+	  Fail if value does not fit in long.
+	*/
+	if ((tmsize_t) occ != occ0)
+	        return (0);
+	/*
+	 * Restart interrupted output operation.
+	 */
+	if (sp->dec_restart) {
+		long residue;
+
+		codep = sp->dec_codep;
+		residue = codep->length - sp->dec_restart;
+		if (residue > occ) {
+			/*
+			 * Residue from previous decode is sufficient
+			 * to satisfy decode request.  Skip to the
+			 * start of the decoded string, place decoded
+			 * values in the output buffer, and return.
+			 */
+			sp->dec_restart += occ;
+			do {
+				codep = codep->next;
+			} while (--residue > occ && codep);
+			if (codep) {
+				tp = op + occ;
+				do {
+					*--tp = codep->value;
+					codep = codep->next;
+				} while (--occ && codep);
+			}
+			return (1);
+		}
+		/*
+		 * Residue satisfies only part of the decode request.
+		 */
+		op += residue, occ -= residue;
+		tp = op;
+		do {
+			int t;
+			--tp;
+			t = codep->value;
+			codep = codep->next;
+			*tp = t;
+		} while (--residue && codep);
+		sp->dec_restart = 0;
+	}
+
+	bp = (unsigned char *)tif->tif_rawcp;
+	nbits = sp->lzw_nbits;
+	nextdata = sp->lzw_nextdata;
+	nextbits = sp->lzw_nextbits;
+	nbitsmask = sp->dec_nbitsmask;
+	oldcodep = sp->dec_oldcodep;
+	free_entp = sp->dec_free_entp;
+	maxcodep = sp->dec_maxcodep;
+
+	while (occ > 0) {
+		NextCode(tif, sp, bp, code, GetNextCode);
+		if (code == CODE_EOI)
+			break;
+		if (code == CODE_CLEAR) {
+			free_entp = sp->dec_codetab + CODE_FIRST;
+			_TIFFmemset(free_entp, 0,
+				    (CSIZE - CODE_FIRST) * sizeof (code_t));
+			nbits = BITS_MIN;
+			nbitsmask = MAXCODE(BITS_MIN);
+			maxcodep = sp->dec_codetab + nbitsmask-1;
+			NextCode(tif, sp, bp, code, GetNextCode);
+			if (code == CODE_EOI)
+				break;
+			if (code >= CODE_CLEAR) {
+				TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+				"LZWDecode: Corrupted LZW table at scanline %d",
+					     tif->tif_row);
+				return (0);
+			}
+			*op++ = (char)code, occ--;
+			oldcodep = sp->dec_codetab + code;
+			continue;
+		}
+		codep = sp->dec_codetab + code;
+
+		/*
+		 * Add the new entry to the code table.
+		 */
+		if (free_entp < &sp->dec_codetab[0] ||
+		    free_entp >= &sp->dec_codetab[CSIZE]) {
+			TIFFErrorExt(tif->tif_clientdata, module,
+			    "Corrupted LZW table at scanline %d",
+			    tif->tif_row);
+			return (0);
+		}
+
+		free_entp->next = oldcodep;
+		if (free_entp->next < &sp->dec_codetab[0] ||
+		    free_entp->next >= &sp->dec_codetab[CSIZE]) {
+			TIFFErrorExt(tif->tif_clientdata, module,
+			    "Corrupted LZW table at scanline %d",
+			    tif->tif_row);
+			return (0);
+		}
+		free_entp->firstchar = free_entp->next->firstchar;
+		free_entp->length = free_entp->next->length+1;
+		free_entp->value = (codep < free_entp) ?
+		    codep->firstchar : free_entp->firstchar;
+		if (++free_entp > maxcodep) {
+			if (++nbits > BITS_MAX)		/* should not happen */
+				nbits = BITS_MAX;
+			nbitsmask = MAXCODE(nbits);
+			maxcodep = sp->dec_codetab + nbitsmask-1;
+		}
+		oldcodep = codep;
+		if (code >= 256) {
+			/*
+			 * Code maps to a string, copy string
+			 * value to output (written in reverse).
+			 */
+			if(codep->length == 0) {
+				TIFFErrorExt(tif->tif_clientdata, module,
+				    "Wrong length of decoded string: "
+				    "data probably corrupted at scanline %d",
+				    tif->tif_row);
+				return (0);
+			}
+			if (codep->length > occ) {
+				/*
+				 * String is too long for decode buffer,
+				 * locate portion that will fit, copy to
+				 * the decode buffer, and setup restart
+				 * logic for the next decoding call.
+				 */
+				sp->dec_codep = codep;
+				do {
+					codep = codep->next;
+				} while (codep && codep->length > occ);
+				if (codep) {
+					sp->dec_restart = (long)occ;
+					tp = op + occ;
+					do  {
+						*--tp = codep->value;
+						codep = codep->next;
+					}  while (--occ && codep);
+					if (codep)
+						codeLoop(tif, module);
+				}
+				break;
+			}
+			len = codep->length;
+			tp = op + len;
+			do {
+				int t;
+				--tp;
+				t = codep->value;
+				codep = codep->next;
+				*tp = t;
+			} while (codep && tp > op);
+			if (codep) {
+			    codeLoop(tif, module);
+			    break;
+			}
+			assert(occ >= len);
+			op += len, occ -= len;
+		} else
+			*op++ = (char)code, occ--;
+	}
+
+	tif->tif_rawcp = (uint8*) bp;
+	sp->lzw_nbits = (unsigned short) nbits;
+	sp->lzw_nextdata = nextdata;
+	sp->lzw_nextbits = nextbits;
+	sp->dec_nbitsmask = nbitsmask;
+	sp->dec_oldcodep = oldcodep;
+	sp->dec_free_entp = free_entp;
+	sp->dec_maxcodep = maxcodep;
+
+	if (occ > 0) {
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+		TIFFErrorExt(tif->tif_clientdata, module,
+			"Not enough data at scanline %d (short %I64d bytes)",
+			     tif->tif_row, (unsigned __int64) occ);
+#else
+		TIFFErrorExt(tif->tif_clientdata, module,
+			"Not enough data at scanline %d (short %llu bytes)",
+			     tif->tif_row, (unsigned long long) occ);
+#endif
+		return (0);
+	}
+	return (1);
+}
+
+#ifdef LZW_COMPAT
+/*
+ * Decode a "hunk of data" for old images.
+ */
+#define	GetNextCodeCompat(sp, bp, code) {			\
+	nextdata |= (unsigned long) *(bp)++ << nextbits;	\
+	nextbits += 8;						\
+	if (nextbits < nbits) {					\
+		nextdata |= (unsigned long) *(bp)++ << nextbits;\
+		nextbits += 8;					\
+	}							\
+	code = (hcode_t)(nextdata & nbitsmask);			\
+	nextdata >>= nbits;					\
+	nextbits -= nbits;					\
+}
+
+static int
+LZWDecodeCompat(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
+{
+	static const char module[] = "LZWDecodeCompat";
+	LZWCodecState *sp = DecoderState(tif);
+	char *op = (char*) op0;
+	long occ = (long) occ0;
+	char *tp;
+	unsigned char *bp;
+	int code, nbits;
+	long nextbits, nextdata, nbitsmask;
+	code_t *codep, *free_entp, *maxcodep, *oldcodep;
+
+	(void) s;
+	assert(sp != NULL);
+
+	/*
+	  Fail if value does not fit in long.
+	*/
+	if ((tmsize_t) occ != occ0)
+	        return (0);
+
+	/*
+	 * Restart interrupted output operation.
+	 */
+	if (sp->dec_restart) {
+		long residue;
+
+		codep = sp->dec_codep;
+		residue = codep->length - sp->dec_restart;
+		if (residue > occ) {
+			/*
+			 * Residue from previous decode is sufficient
+			 * to satisfy decode request.  Skip to the
+			 * start of the decoded string, place decoded
+			 * values in the output buffer, and return.
+			 */
+			sp->dec_restart += occ;
+			do {
+				codep = codep->next;
+			} while (--residue > occ);
+			tp = op + occ;
+			do {
+				*--tp = codep->value;
+				codep = codep->next;
+			} while (--occ);
+			return (1);
+		}
+		/*
+		 * Residue satisfies only part of the decode request.
+		 */
+		op += residue, occ -= residue;
+		tp = op;
+		do {
+			*--tp = codep->value;
+			codep = codep->next;
+		} while (--residue);
+		sp->dec_restart = 0;
+	}
+
+	bp = (unsigned char *)tif->tif_rawcp;
+	nbits = sp->lzw_nbits;
+	nextdata = sp->lzw_nextdata;
+	nextbits = sp->lzw_nextbits;
+	nbitsmask = sp->dec_nbitsmask;
+	oldcodep = sp->dec_oldcodep;
+	free_entp = sp->dec_free_entp;
+	maxcodep = sp->dec_maxcodep;
+
+	while (occ > 0) {
+		NextCode(tif, sp, bp, code, GetNextCodeCompat);
+		if (code == CODE_EOI)
+			break;
+		if (code == CODE_CLEAR) {
+			free_entp = sp->dec_codetab + CODE_FIRST;
+			_TIFFmemset(free_entp, 0,
+				    (CSIZE - CODE_FIRST) * sizeof (code_t));
+			nbits = BITS_MIN;
+			nbitsmask = MAXCODE(BITS_MIN);
+			maxcodep = sp->dec_codetab + nbitsmask;
+			NextCode(tif, sp, bp, code, GetNextCodeCompat);
+			if (code == CODE_EOI)
+				break;
+			if (code >= CODE_CLEAR) {
+				TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+				"LZWDecode: Corrupted LZW table at scanline %d",
+					     tif->tif_row);
+				return (0);
+			}
+			*op++ = code, occ--;
+			oldcodep = sp->dec_codetab + code;
+			continue;
+		}
+		codep = sp->dec_codetab + code;
+
+		/*
+		 * Add the new entry to the code table.
+		 */
+		if (free_entp < &sp->dec_codetab[0] ||
+		    free_entp >= &sp->dec_codetab[CSIZE]) {
+			TIFFErrorExt(tif->tif_clientdata, module,
+			    "Corrupted LZW table at scanline %d", tif->tif_row);
+			return (0);
+		}
+
+		free_entp->next = oldcodep;
+		if (free_entp->next < &sp->dec_codetab[0] ||
+		    free_entp->next >= &sp->dec_codetab[CSIZE]) {
+			TIFFErrorExt(tif->tif_clientdata, module,
+			    "Corrupted LZW table at scanline %d", tif->tif_row);
+			return (0);
+		}
+		free_entp->firstchar = free_entp->next->firstchar;
+		free_entp->length = free_entp->next->length+1;
+		free_entp->value = (codep < free_entp) ?
+		    codep->firstchar : free_entp->firstchar;
+		if (++free_entp > maxcodep) {
+			if (++nbits > BITS_MAX)		/* should not happen */
+				nbits = BITS_MAX;
+			nbitsmask = MAXCODE(nbits);
+			maxcodep = sp->dec_codetab + nbitsmask;
+		}
+		oldcodep = codep;
+		if (code >= 256) {
+			/*
+			 * Code maps to a string, copy string
+			 * value to output (written in reverse).
+			 */
+			if(codep->length == 0) {
+				TIFFErrorExt(tif->tif_clientdata, module,
+				    "Wrong length of decoded "
+				    "string: data probably corrupted at scanline %d",
+				    tif->tif_row);
+				return (0);
+			}
+			if (codep->length > occ) {
+				/*
+				 * String is too long for decode buffer,
+				 * locate portion that will fit, copy to
+				 * the decode buffer, and setup restart
+				 * logic for the next decoding call.
+				 */
+				sp->dec_codep = codep;
+				do {
+					codep = codep->next;
+				} while (codep->length > occ);
+				sp->dec_restart = occ;
+				tp = op + occ;
+				do  {
+					*--tp = codep->value;
+					codep = codep->next;
+				}  while (--occ);
+				break;
+			}
+			assert(occ >= codep->length);
+			op += codep->length, occ -= codep->length;
+			tp = op;
+			do {
+				*--tp = codep->value;
+			} while( (codep = codep->next) != NULL );
+		} else
+			*op++ = code, occ--;
+	}
+
+	tif->tif_rawcp = (uint8*) bp;
+	sp->lzw_nbits = nbits;
+	sp->lzw_nextdata = nextdata;
+	sp->lzw_nextbits = nextbits;
+	sp->dec_nbitsmask = nbitsmask;
+	sp->dec_oldcodep = oldcodep;
+	sp->dec_free_entp = free_entp;
+	sp->dec_maxcodep = maxcodep;
+
+	if (occ > 0) {
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+		TIFFErrorExt(tif->tif_clientdata, module,
+			"Not enough data at scanline %d (short %I64d bytes)",
+			     tif->tif_row, (unsigned __int64) occ);
+#else
+		TIFFErrorExt(tif->tif_clientdata, module,
+			"Not enough data at scanline %d (short %llu bytes)",
+			     tif->tif_row, (unsigned long long) occ);
+#endif
+		return (0);
+	}
+	return (1);
+}
+#endif /* LZW_COMPAT */
+
+/*
+ * LZW Encoding.
+ */
+
+static int
+LZWSetupEncode(TIFF* tif)
+{
+	static const char module[] = "LZWSetupEncode";
+	LZWCodecState* sp = EncoderState(tif);
+
+	assert(sp != NULL);
+	sp->enc_hashtab = (hash_t*) _TIFFmalloc(HSIZE*sizeof (hash_t));
+	if (sp->enc_hashtab == NULL) {
+		TIFFErrorExt(tif->tif_clientdata, module,
+			     "No space for LZW hash table");
+		return (0);
+	}
+	return (1);
+}
+
+/*
+ * Reset encoding state at the start of a strip.
+ */
+static int
+LZWPreEncode(TIFF* tif, uint16 s)
+{
+	LZWCodecState *sp = EncoderState(tif);
+
+	(void) s;
+	assert(sp != NULL);
+
+	if( sp->enc_hashtab == NULL )
+        {
+            tif->tif_setupencode( tif );
+        }
+
+	sp->lzw_nbits = BITS_MIN;
+	sp->lzw_maxcode = MAXCODE(BITS_MIN);
+	sp->lzw_free_ent = CODE_FIRST;
+	sp->lzw_nextbits = 0;
+	sp->lzw_nextdata = 0;
+	sp->enc_checkpoint = CHECK_GAP;
+	sp->enc_ratio = 0;
+	sp->enc_incount = 0;
+	sp->enc_outcount = 0;
+	/*
+	 * The 4 here insures there is space for 2 max-sized
+	 * codes in LZWEncode and LZWPostDecode.
+	 */
+	sp->enc_rawlimit = tif->tif_rawdata + tif->tif_rawdatasize-1 - 4;
+	cl_hash(sp);		/* clear hash table */
+	sp->enc_oldcode = (hcode_t) -1;	/* generates CODE_CLEAR in LZWEncode */
+	return (1);
+}
+
+#define	CALCRATIO(sp, rat) {					\
+	if (incount > 0x007fffff) { /* NB: shift will overflow */\
+		rat = outcount >> 8;				\
+		rat = (rat == 0 ? 0x7fffffff : incount/rat);	\
+	} else							\
+		rat = (incount<<8) / outcount;			\
+}
+#define	PutNextCode(op, c) {					\
+	nextdata = (nextdata << nbits) | c;			\
+	nextbits += nbits;					\
+	*op++ = (unsigned char)(nextdata >> (nextbits-8));		\
+	nextbits -= 8;						\
+	if (nextbits >= 8) {					\
+		*op++ = (unsigned char)(nextdata >> (nextbits-8));	\
+		nextbits -= 8;					\
+	}							\
+	outcount += nbits;					\
+}
+
+/*
+ * Encode a chunk of pixels.
+ *
+ * Uses an open addressing double hashing (no chaining) on the 
+ * prefix code/next character combination.  We do a variant of
+ * Knuth's algorithm D (vol. 3, sec. 6.4) along with G. Knott's
+ * relatively-prime secondary probe.  Here, the modular division
+ * first probe is gives way to a faster exclusive-or manipulation. 
+ * Also do block compression with an adaptive reset, whereby the
+ * code table is cleared when the compression ratio decreases,
+ * but after the table fills.  The variable-length output codes
+ * are re-sized at this point, and a CODE_CLEAR is generated
+ * for the decoder. 
+ */
+static int
+LZWEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
+{
+	register LZWCodecState *sp = EncoderState(tif);
+	register long fcode;
+	register hash_t *hp;
+	register int h, c;
+	hcode_t ent;
+	long disp;
+	long incount, outcount, checkpoint;
+	long nextdata, nextbits;
+	int free_ent, maxcode, nbits;
+	uint8* op;
+	uint8* limit;
+
+	(void) s;
+	if (sp == NULL)
+		return (0);
+
+        assert(sp->enc_hashtab != NULL);
+
+	/*
+	 * Load local state.
+	 */
+	incount = sp->enc_incount;
+	outcount = sp->enc_outcount;
+	checkpoint = sp->enc_checkpoint;
+	nextdata = sp->lzw_nextdata;
+	nextbits = sp->lzw_nextbits;
+	free_ent = sp->lzw_free_ent;
+	maxcode = sp->lzw_maxcode;
+	nbits = sp->lzw_nbits;
+	op = tif->tif_rawcp;
+	limit = sp->enc_rawlimit;
+	ent = sp->enc_oldcode;
+
+	if (ent == (hcode_t) -1 && cc > 0) {
+		/*
+		 * NB: This is safe because it can only happen
+		 *     at the start of a strip where we know there
+		 *     is space in the data buffer.
+		 */
+		PutNextCode(op, CODE_CLEAR);
+		ent = *bp++; cc--; incount++;
+	}
+	while (cc > 0) {
+		c = *bp++; cc--; incount++;
+		fcode = ((long)c << BITS_MAX) + ent;
+		h = (c << HSHIFT) ^ ent;	/* xor hashing */
+#ifdef _WINDOWS
+		/*
+		 * Check hash index for an overflow.
+		 */
+		if (h >= HSIZE)
+			h -= HSIZE;
+#endif
+		hp = &sp->enc_hashtab[h];
+		if (hp->hash == fcode) {
+			ent = hp->code;
+			continue;
+		}
+		if (hp->hash >= 0) {
+			/*
+			 * Primary hash failed, check secondary hash.
+			 */
+			disp = HSIZE - h;
+			if (h == 0)
+				disp = 1;
+			do {
+				/*
+				 * Avoid pointer arithmetic 'cuz of
+				 * wraparound problems with segments.
+				 */
+				if ((h -= disp) < 0)
+					h += HSIZE;
+				hp = &sp->enc_hashtab[h];
+				if (hp->hash == fcode) {
+					ent = hp->code;
+					goto hit;
+				}
+			} while (hp->hash >= 0);
+		}
+		/*
+		 * New entry, emit code and add to table.
+		 */
+		/*
+		 * Verify there is space in the buffer for the code
+		 * and any potential Clear code that might be emitted
+		 * below.  The value of limit is setup so that there
+		 * are at least 4 bytes free--room for 2 codes.
+		 */
+		if (op > limit) {
+			tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata);
+			TIFFFlushData1(tif);
+			op = tif->tif_rawdata;
+		}
+		PutNextCode(op, ent);
+		ent = c;
+		hp->code = free_ent++;
+		hp->hash = fcode;
+		if (free_ent == CODE_MAX-1) {
+			/* table is full, emit clear code and reset */
+			cl_hash(sp);
+			sp->enc_ratio = 0;
+			incount = 0;
+			outcount = 0;
+			free_ent = CODE_FIRST;
+			PutNextCode(op, CODE_CLEAR);
+			nbits = BITS_MIN;
+			maxcode = MAXCODE(BITS_MIN);
+		} else {
+			/*
+			 * If the next entry is going to be too big for
+			 * the code size, then increase it, if possible.
+			 */
+			if (free_ent > maxcode) {
+				nbits++;
+				assert(nbits <= BITS_MAX);
+				maxcode = (int) MAXCODE(nbits);
+			} else if (incount >= checkpoint) {
+				long rat;
+				/*
+				 * Check compression ratio and, if things seem
+				 * to be slipping, clear the hash table and
+				 * reset state.  The compression ratio is a
+				 * 24+8-bit fractional number.
+				 */
+				checkpoint = incount+CHECK_GAP;
+				CALCRATIO(sp, rat);
+				if (rat <= sp->enc_ratio) {
+					cl_hash(sp);
+					sp->enc_ratio = 0;
+					incount = 0;
+					outcount = 0;
+					free_ent = CODE_FIRST;
+					PutNextCode(op, CODE_CLEAR);
+					nbits = BITS_MIN;
+					maxcode = MAXCODE(BITS_MIN);
+				} else
+					sp->enc_ratio = rat;
+			}
+		}
+	hit:
+		;
+	}
+
+	/*
+	 * Restore global state.
+	 */
+	sp->enc_incount = incount;
+	sp->enc_outcount = outcount;
+	sp->enc_checkpoint = checkpoint;
+	sp->enc_oldcode = ent;
+	sp->lzw_nextdata = nextdata;
+	sp->lzw_nextbits = nextbits;
+	sp->lzw_free_ent = free_ent;
+	sp->lzw_maxcode = maxcode;
+	sp->lzw_nbits = nbits;
+	tif->tif_rawcp = op;
+	return (1);
+}
+
+/*
+ * Finish off an encoded strip by flushing the last
+ * string and tacking on an End Of Information code.
+ */
+static int
+LZWPostEncode(TIFF* tif)
+{
+	register LZWCodecState *sp = EncoderState(tif);
+	uint8* op = tif->tif_rawcp;
+	long nextbits = sp->lzw_nextbits;
+	long nextdata = sp->lzw_nextdata;
+	long outcount = sp->enc_outcount;
+	int nbits = sp->lzw_nbits;
+
+	if (op > sp->enc_rawlimit) {
+		tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata);
+		TIFFFlushData1(tif);
+		op = tif->tif_rawdata;
+	}
+	if (sp->enc_oldcode != (hcode_t) -1) {
+		PutNextCode(op, sp->enc_oldcode);
+		sp->enc_oldcode = (hcode_t) -1;
+	}
+	PutNextCode(op, CODE_EOI);
+	if (nextbits > 0) 
+		*op++ = (unsigned char)(nextdata << (8-nextbits));
+	tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata);
+	return (1);
+}
+
+/*
+ * Reset encoding hash table.
+ */
+static void
+cl_hash(LZWCodecState* sp)
+{
+	register hash_t *hp = &sp->enc_hashtab[HSIZE-1];
+	register long i = HSIZE-8;
+
+	do {
+		i -= 8;
+		hp[-7].hash = -1;
+		hp[-6].hash = -1;
+		hp[-5].hash = -1;
+		hp[-4].hash = -1;
+		hp[-3].hash = -1;
+		hp[-2].hash = -1;
+		hp[-1].hash = -1;
+		hp[ 0].hash = -1;
+		hp -= 8;
+	} while (i >= 0);
+	for (i += 8; i > 0; i--, hp--)
+		hp->hash = -1;
+}
+
+static void
+LZWCleanup(TIFF* tif)
+{
+	(void)TIFFPredictorCleanup(tif);
+
+	assert(tif->tif_data != 0);
+
+	if (DecoderState(tif)->dec_codetab)
+		_TIFFfree(DecoderState(tif)->dec_codetab);
+
+	if (EncoderState(tif)->enc_hashtab)
+		_TIFFfree(EncoderState(tif)->enc_hashtab);
+
+	_TIFFfree(tif->tif_data);
+	tif->tif_data = NULL;
+
+	_TIFFSetDefaultCompressionState(tif);
+}
+
+int
+TIFFInitLZW(TIFF* tif, int scheme)
+{
+	static const char module[] = "TIFFInitLZW";
+	assert(scheme == COMPRESSION_LZW);
+	/*
+	 * Allocate state block so tag methods have storage to record values.
+	 */
+	tif->tif_data = (uint8*) _TIFFmalloc(sizeof (LZWCodecState));
+	if (tif->tif_data == NULL)
+		goto bad;
+	DecoderState(tif)->dec_codetab = NULL;
+	DecoderState(tif)->dec_decode = NULL;
+	EncoderState(tif)->enc_hashtab = NULL;
+        LZWState(tif)->rw_mode = tif->tif_mode;
+
+	/*
+	 * Install codec methods.
+	 */
+	tif->tif_fixuptags = LZWFixupTags; 
+	tif->tif_setupdecode = LZWSetupDecode;
+	tif->tif_predecode = LZWPreDecode;
+	tif->tif_decoderow = LZWDecode;
+	tif->tif_decodestrip = LZWDecode;
+	tif->tif_decodetile = LZWDecode;
+	tif->tif_setupencode = LZWSetupEncode;
+	tif->tif_preencode = LZWPreEncode;
+	tif->tif_postencode = LZWPostEncode;
+	tif->tif_encoderow = LZWEncode;
+	tif->tif_encodestrip = LZWEncode;
+	tif->tif_encodetile = LZWEncode;
+	tif->tif_cleanup = LZWCleanup;
+	/*
+	 * Setup predictor setup.
+	 */
+	(void) TIFFPredictorInit(tif);
+	return (1);
+bad:
+	TIFFErrorExt(tif->tif_clientdata, module, 
+		     "No space for LZW state block");
+	return (0);
+}
+
+/*
+ * Copyright (c) 1985, 1986 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * James A. Woods, derived from original work by Spencer Thomas
+ * and Joseph Orost.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#endif /* LZW_SUPPORT */
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tif_next.c b/Source/LibTIFF4/tif_next.c
index cfe2ead..6ec55c8 100644
--- a/Source/LibTIFF4/tif_next.c
+++ b/Source/LibTIFF4/tif_next.c
@@ -1,160 +1,181 @@
-/* $Id: tif_next.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-#include "tiffiop.h"
-#ifdef NEXT_SUPPORT
-/*
- * TIFF Library.
- *
- * NeXT 2-bit Grey Scale Compression Algorithm Support
- */
-
-#define SETPIXEL(op, v) {			\
-	switch (npixels++ & 3) {		\
-	case 0:	op[0]  = (unsigned char) ((v) << 6); break;	\
-	case 1:	op[0] |= (v) << 4; break;	\
-	case 2:	op[0] |= (v) << 2; break;	\
-	case 3:	*op++ |= (v);	   break;	\
-	}					\
-}
-
-#define LITERALROW	0x00
-#define LITERALSPAN	0x40
-#define WHITE   	((1<<2)-1)
-
-static int
-NeXTDecode(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s)
-{
-	static const char module[] = "NeXTDecode";
-	unsigned char *bp, *op;
-	tmsize_t cc;
-	uint8* row;
-	tmsize_t scanline, n;
-
-	(void) s;
-	/*
-	 * Each scanline is assumed to start off as all
-	 * white (we assume a PhotometricInterpretation
-	 * of ``min-is-black'').
-	 */
-	for (op = (unsigned char*) buf, cc = occ; cc-- > 0;)
-		*op++ = 0xff;
-
-	bp = (unsigned char *)tif->tif_rawcp;
-	cc = tif->tif_rawcc;
-	scanline = tif->tif_scanlinesize;
-	if (occ % scanline)
-	{
-		TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read");
-		return (0);
-	}
-	for (row = buf; occ > 0; occ -= scanline, row += scanline) {
-		n = *bp++, cc--;
-		switch (n) {
-		case LITERALROW:
-			/*
-			 * The entire scanline is given as literal values.
-			 */
-			if (cc < scanline)
-				goto bad;
-			_TIFFmemcpy(row, bp, scanline);
-			bp += scanline;
-			cc -= scanline;
-			break;
-		case LITERALSPAN: {
-			tmsize_t off;
-			/*
-			 * The scanline has a literal span that begins at some
-			 * offset.
-			 */
-			off = (bp[0] * 256) + bp[1];
-			n = (bp[2] * 256) + bp[3];
-			if (cc < 4+n || off+n > scanline)
-				goto bad;
-			_TIFFmemcpy(row+off, bp+4, n);
-			bp += 4+n;
-			cc -= 4+n;
-			break;
-		}
-		default: {
-			uint32 npixels = 0, grey;
-			uint32 imagewidth = tif->tif_dir.td_imagewidth;
-
-			/*
-			 * The scanline is composed of a sequence of constant
-			 * color ``runs''.  We shift into ``run mode'' and
-			 * interpret bytes as codes of the form
-			 * <color><npixels> until we've filled the scanline.
-			 */
-			op = row;
-			for (;;) {
-				grey = (uint32)((n>>6) & 0x3);
-				n &= 0x3f;
-				/*
-				 * Ensure the run does not exceed the scanline
-				 * bounds, potentially resulting in a security
-				 * issue.
-				 */
-				while (n-- > 0 && npixels < imagewidth)
-					SETPIXEL(op, grey);
-				if (npixels >= imagewidth)
-					break;
-				if (cc == 0)
-					goto bad;
-				n = *bp++, cc--;
-			}
-			break;
-		}
-		}
-	}
-	tif->tif_rawcp = (uint8*) bp;
-	tif->tif_rawcc = cc;
-	return (1);
-bad:
-	TIFFErrorExt(tif->tif_clientdata, module, "Not enough data for scanline %ld",
-	    (long) tif->tif_row);
-	return (0);
-}
-
-int
-TIFFInitNeXT(TIFF* tif, int scheme)
-{
-	(void) scheme;
-	tif->tif_decoderow = NeXTDecode;  
-	tif->tif_decodestrip = NeXTDecode;  
-	tif->tif_decodetile = NeXTDecode;
-	return (1);
-}
-#endif /* NEXT_SUPPORT */
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Id: tif_next.c,v 1.11 2015/02/19 22:39:58 drolon Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and 
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
+ * 
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
+ * OF THIS SOFTWARE.
+ */
+
+#include "tiffiop.h"
+#ifdef NEXT_SUPPORT
+/*
+ * TIFF Library.
+ *
+ * NeXT 2-bit Grey Scale Compression Algorithm Support
+ */
+
+#define SETPIXEL(op, v) {			\
+	switch (npixels++ & 3) {		\
+	case 0:	op[0]  = (unsigned char) ((v) << 6); break;	\
+	case 1:	op[0] |= (v) << 4; break;	\
+	case 2:	op[0] |= (v) << 2; break;	\
+	case 3:	*op++ |= (v);	   break;	\
+	}					\
+}
+
+#define LITERALROW	0x00
+#define LITERALSPAN	0x40
+#define WHITE   	((1<<2)-1)
+
+static int
+NeXTDecode(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s)
+{
+	static const char module[] = "NeXTDecode";
+	unsigned char *bp, *op;
+	tmsize_t cc;
+	uint8* row;
+	tmsize_t scanline, n;
+
+	(void) s;
+	/*
+	 * Each scanline is assumed to start off as all
+	 * white (we assume a PhotometricInterpretation
+	 * of ``min-is-black'').
+	 */
+	for (op = (unsigned char*) buf, cc = occ; cc-- > 0;)
+		*op++ = 0xff;
+
+	bp = (unsigned char *)tif->tif_rawcp;
+	cc = tif->tif_rawcc;
+	scanline = tif->tif_scanlinesize;
+	if (occ % scanline)
+	{
+		TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read");
+		return (0);
+	}
+	for (row = buf; cc > 0 && occ > 0; occ -= scanline, row += scanline) {
+		n = *bp++, cc--;
+		switch (n) {
+		case LITERALROW:
+			/*
+			 * The entire scanline is given as literal values.
+			 */
+			if (cc < scanline)
+				goto bad;
+			_TIFFmemcpy(row, bp, scanline);
+			bp += scanline;
+			cc -= scanline;
+			break;
+		case LITERALSPAN: {
+			tmsize_t off;
+			/*
+			 * The scanline has a literal span that begins at some
+			 * offset.
+			 */
+			if( cc < 4 )
+				goto bad;
+			off = (bp[0] * 256) + bp[1];
+			n = (bp[2] * 256) + bp[3];
+			if (cc < 4+n || off+n > scanline)
+				goto bad;
+			_TIFFmemcpy(row+off, bp+4, n);
+			bp += 4+n;
+			cc -= 4+n;
+			break;
+		}
+		default: {
+			uint32 npixels = 0, grey;
+			uint32 imagewidth = tif->tif_dir.td_imagewidth;
+            if( isTiled(tif) )
+                imagewidth = tif->tif_dir.td_tilewidth;
+
+			/*
+			 * The scanline is composed of a sequence of constant
+			 * color ``runs''.  We shift into ``run mode'' and
+			 * interpret bytes as codes of the form
+			 * <color><npixels> until we've filled the scanline.
+			 */
+			op = row;
+			for (;;) {
+				grey = (uint32)((n>>6) & 0x3);
+				n &= 0x3f;
+				/*
+				 * Ensure the run does not exceed the scanline
+				 * bounds, potentially resulting in a security
+				 * issue.
+				 */
+				while (n-- > 0 && npixels < imagewidth)
+					SETPIXEL(op, grey);
+				if (npixels >= imagewidth)
+					break;
+				if (cc == 0)
+					goto bad;
+				n = *bp++, cc--;
+			}
+			break;
+		}
+		}
+	}
+	tif->tif_rawcp = (uint8*) bp;
+	tif->tif_rawcc = cc;
+	return (1);
+bad:
+	TIFFErrorExt(tif->tif_clientdata, module, "Not enough data for scanline %ld",
+	    (long) tif->tif_row);
+	return (0);
+}
+
+static int
+NeXTPreDecode(TIFF* tif, uint16 s)
+{
+	static const char module[] = "NeXTPreDecode";
+	TIFFDirectory *td = &tif->tif_dir;
+	(void)s;
+
+	if( td->td_bitspersample != 2 )
+	{
+		TIFFErrorExt(tif->tif_clientdata, module, "Unsupported BitsPerSample = %d",
+					 td->td_bitspersample);
+		return (0);
+	}
+	return (1);
+}
+	
+int
+TIFFInitNeXT(TIFF* tif, int scheme)
+{
+	(void) scheme;
+	tif->tif_predecode = NeXTPreDecode;  
+	tif->tif_decoderow = NeXTDecode;  
+	tif->tif_decodestrip = NeXTDecode;  
+	tif->tif_decodetile = NeXTDecode;
+	return (1);
+}
+#endif /* NEXT_SUPPORT */
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tif_ojpeg.c b/Source/LibTIFF4/tif_ojpeg.c
index fe74748..b3d0831 100644
--- a/Source/LibTIFF4/tif_ojpeg.c
+++ b/Source/LibTIFF4/tif_ojpeg.c
@@ -1,2496 +1,2501 @@
-/* $Id: tif_ojpeg.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/* WARNING: The type of JPEG encapsulation defined by the TIFF Version 6.0
-   specification is now totally obsolete and deprecated for new applications and
-   images. This file was was created solely in order to read unconverted images
-   still present on some users' computer systems. It will never be extended
-   to write such files. Writing new-style JPEG compressed TIFFs is implemented
-   in tif_jpeg.c.
-
-   The code is carefully crafted to robustly read all gathered JPEG-in-TIFF
-   testfiles, and anticipate as much as possible all other... But still, it may
-   fail on some. If you encounter problems, please report them on the TIFF
-   mailing list and/or to Joris Van Damme <info at awaresystems.be>.
-
-   Please read the file called "TIFF Technical Note #2" if you need to be
-   convinced this compression scheme is bad and breaks TIFF. That document
-   is linked to from the LibTiff site <http://www.remotesensing.org/libtiff/>
-   and from AWare Systems' TIFF section
-   <http://www.awaresystems.be/imaging/tiff.html>. It is also absorbed
-   in Adobe's specification supplements, marked "draft" up to this day, but
-   supported by the TIFF community.
-
-   This file interfaces with Release 6B of the JPEG Library written by the
-   Independent JPEG Group. Previous versions of this file required a hack inside
-   the LibJpeg library. This version no longer requires that. Remember to
-   remove the hack if you update from the old version.
-
-   Copyright (c) Joris Van Damme <info at awaresystems.be>
-   Copyright (c) AWare Systems <http://www.awaresystems.be/>
-
-   The licence agreement for this file is the same as the rest of the LibTiff
-   library.
-
-   IN NO EVENT SHALL JORIS VAN DAMME OR AWARE SYSTEMS BE LIABLE FOR
-   ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
-   OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-   WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
-   LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
-   OF THIS SOFTWARE.
-
-   Joris Van Damme and/or AWare Systems may be available for custom
-   developement. If you like what you see, and need anything similar or related,
-   contact <info at awaresystems.be>.
-*/
-
-/* What is what, and what is not?
-
-   This decoder starts with an input stream, that is essentially the JpegInterchangeFormat
-   stream, if any, followed by the strile data, if any. This stream is read in
-   OJPEGReadByte and related functions.
-
-   It analyzes the start of this stream, until it encounters non-marker data, i.e.
-   compressed image data. Some of the header markers it sees have no actual content,
-   like the SOI marker, and APP/COM markers that really shouldn't even be there. Some
-   other markers do have content, and the valuable bits and pieces of information
-   in these markers are saved, checking all to verify that the stream is more or
-   less within expected bounds. This happens inside the OJPEGReadHeaderInfoSecStreamXxx
-   functions.
-
-   Some OJPEG imagery contains no valid JPEG header markers. This situation is picked
-   up on if we've seen no SOF marker when we're at the start of the compressed image
-   data. In this case, the tables are read from JpegXxxTables tags, and the other
-   bits and pieces of information is initialized to its most basic value. This is
-   implemented in the OJPEGReadHeaderInfoSecTablesXxx functions.
-
-   When this is complete, a good and valid JPEG header can be assembled, and this is
-   passed through to LibJpeg. When that's done, the remainder of the input stream, i.e.
-   the compressed image data, can be passed through unchanged. This is done in
-   OJPEGWriteStream functions.
-
-   LibTiff rightly expects to know the subsampling values before decompression. Just like
-   in new-style JPEG-in-TIFF, though, or even more so, actually, the YCbCrsubsampling
-   tag is notoriously unreliable. To correct these tag values with the ones inside
-   the JPEG stream, the first part of the input stream is pre-scanned in
-   OJPEGSubsamplingCorrect, making no note of any other data, reporting no warnings
-   or errors, up to the point where either these values are read, or it's clear they
-   aren't there. This means that some of the data is read twice, but we feel speed
-   in correcting these values is important enough to warrant this sacrifice. Allthough
-   there is currently no define or other configuration mechanism to disable this behaviour,
-   the actual header scanning is build to robustly respond with error report if it
-   should encounter an uncorrected mismatch of subsampling values. See
-   OJPEGReadHeaderInfoSecStreamSof.
-
-   The restart interval and restart markers are the most tricky part... The restart
-   interval can be specified in a tag. It can also be set inside the input JPEG stream.
-   It can be used inside the input JPEG stream. If reading from strile data, we've
-   consistenly discovered the need to insert restart markers in between the different
-   striles, as is also probably the most likely interpretation of the original TIFF 6.0
-   specification. With all this setting of interval, and actual use of markers that is not
-   predictable at the time of valid JPEG header assembly, the restart thing may turn
-   out the Achilles heel of this implementation. Fortunately, most OJPEG writer vendors
-   succeed in reading back what they write, which may be the reason why we've been able
-   to discover ways that seem to work.
-
-   Some special provision is made for planarconfig separate OJPEG files. These seem
-   to consistently contain header info, a SOS marker, a plane, SOS marker, plane, SOS,
-   and plane. This may or may not be a valid JPEG configuration, we don't know and don't
-   care. We want LibTiff to be able to access the planes individually, without huge
-   buffering inside LibJpeg, anyway. So we compose headers to feed to LibJpeg, in this
-   case, that allow us to pass a single plane such that LibJpeg sees a valid
-   single-channel JPEG stream. Locating subsequent SOS markers, and thus subsequent
-   planes, is done inside OJPEGReadSecondarySos.
-
-   The benefit of the scheme is... that it works, basically. We know of no other that
-   does. It works without checking software tag, or otherwise going about things in an
-   OJPEG flavor specific manner. Instead, it is a single scheme, that covers the cases
-   with and without JpegInterchangeFormat, with and without striles, with part of
-   the header in JpegInterchangeFormat and remainder in first strile, etc. It is forgiving
-   and robust, may likely work with OJPEG flavors we've not seen yet, and makes most out
-   of the data.
-
-   Another nice side-effect is that a complete JPEG single valid stream is build if
-   planarconfig is not separate (vast majority). We may one day use that to build
-   converters to JPEG, and/or to new-style JPEG compression inside TIFF.
-
-   A dissadvantage is the lack of random access to the individual striles. This is the
-   reason for much of the complicated restart-and-position stuff inside OJPEGPreDecode.
-   Applications would do well accessing all striles in order, as this will result in
-   a single sequential scan of the input stream, and no restarting of LibJpeg decoding
-   session.
-*/
-
-#define WIN32_LEAN_AND_MEAN
-#define VC_EXTRALEAN
-
-#include "tiffiop.h"
-#ifdef OJPEG_SUPPORT
-
-/* Configuration defines here are:
- * JPEG_ENCAP_EXTERNAL: The normal way to call libjpeg, uses longjump. In some environments,
- * 	like eg LibTiffDelphi, this is not possible. For this reason, the actual calls to
- * 	libjpeg, with longjump stuff, are encapsulated in dedicated functions. When
- * 	JPEG_ENCAP_EXTERNAL is defined, these encapsulating functions are declared external
- * 	to this unit, and can be defined elsewhere to use stuff other then longjump.
- * 	The default mode, without JPEG_ENCAP_EXTERNAL, implements the call encapsulators
- * 	here, internally, with normal longjump.
- * SETJMP, LONGJMP, JMP_BUF: On some machines/environments a longjump equivalent is
- * 	conviniently available, but still it may be worthwhile to use _setjmp or sigsetjmp
- * 	in place of plain setjmp. These macros will make it easier. It is useless
- * 	to fiddle with these if you define JPEG_ENCAP_EXTERNAL.
- * OJPEG_BUFFER: Define the size of the desired buffer here. Should be small enough so as to guarantee
- * 	instant processing, optimal streaming and optimal use of processor cache, but also big
- * 	enough so as to not result in significant call overhead. It should be at least a few
- * 	bytes to accomodate some structures (this is verified in asserts), but it would not be
- * 	sensible to make it this small anyway, and it should be at most 64K since it is indexed
- * 	with uint16. We recommend 2K.
- * EGYPTIANWALK: You could also define EGYPTIANWALK here, but it is not used anywhere and has
- * 	absolutely no effect. That is why most people insist the EGYPTIANWALK is a bit silly.
- */
-
-/* define LIBJPEG_ENCAP_EXTERNAL */
-#define SETJMP(jbuf) setjmp(jbuf)
-#define LONGJMP(jbuf,code) longjmp(jbuf,code)
-#define JMP_BUF jmp_buf
-#define OJPEG_BUFFER 2048
-/* define EGYPTIANWALK */
-
-#define JPEG_MARKER_SOF0 0xC0
-#define JPEG_MARKER_SOF1 0xC1
-#define JPEG_MARKER_SOF3 0xC3
-#define JPEG_MARKER_DHT 0xC4
-#define JPEG_MARKER_RST0 0XD0
-#define JPEG_MARKER_SOI 0xD8
-#define JPEG_MARKER_EOI 0xD9
-#define JPEG_MARKER_SOS 0xDA
-#define JPEG_MARKER_DQT 0xDB
-#define JPEG_MARKER_DRI 0xDD
-#define JPEG_MARKER_APP0 0xE0
-#define JPEG_MARKER_COM 0xFE
-
-#define FIELD_OJPEG_JPEGINTERCHANGEFORMAT (FIELD_CODEC+0)
-#define FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH (FIELD_CODEC+1)
-#define FIELD_OJPEG_JPEGQTABLES (FIELD_CODEC+2)
-#define FIELD_OJPEG_JPEGDCTABLES (FIELD_CODEC+3)
-#define FIELD_OJPEG_JPEGACTABLES (FIELD_CODEC+4)
-#define FIELD_OJPEG_JPEGPROC (FIELD_CODEC+5)
-#define FIELD_OJPEG_JPEGRESTARTINTERVAL (FIELD_CODEC+6)
-
-static const TIFFField ojpegFields[] = {
-	{TIFFTAG_JPEGIFOFFSET,1,1,TIFF_LONG8,0,TIFF_SETGET_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGINTERCHANGEFORMAT,TRUE,FALSE,"JpegInterchangeFormat",NULL},
-	{TIFFTAG_JPEGIFBYTECOUNT,1,1,TIFF_LONG8,0,TIFF_SETGET_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH,TRUE,FALSE,"JpegInterchangeFormatLength",NULL},
-	{TIFFTAG_JPEGQTABLES,TIFF_VARIABLE2,TIFF_VARIABLE2,TIFF_LONG8,0,TIFF_SETGET_C32_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGQTABLES,FALSE,TRUE,"JpegQTables",NULL},
-	{TIFFTAG_JPEGDCTABLES,TIFF_VARIABLE2,TIFF_VARIABLE2,TIFF_LONG8,0,TIFF_SETGET_C32_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGDCTABLES,FALSE,TRUE,"JpegDcTables",NULL},
-	{TIFFTAG_JPEGACTABLES,TIFF_VARIABLE2,TIFF_VARIABLE2,TIFF_LONG8,0,TIFF_SETGET_C32_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGACTABLES,FALSE,TRUE,"JpegAcTables",NULL},
-	{TIFFTAG_JPEGPROC,1,1,TIFF_SHORT,0,TIFF_SETGET_UINT16,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGPROC,FALSE,FALSE,"JpegProc",NULL},
-	{TIFFTAG_JPEGRESTARTINTERVAL,1,1,TIFF_SHORT,0,TIFF_SETGET_UINT16,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGRESTARTINTERVAL,FALSE,FALSE,"JpegRestartInterval",NULL},
-};
-
-#ifndef LIBJPEG_ENCAP_EXTERNAL
-#include <setjmp.h>
-#endif
-
-/* We undefine FAR to avoid conflict with JPEG definition */
-
-#ifdef FAR
-#undef FAR
-#endif
-
-/*
-  Libjpeg's jmorecfg.h defines INT16 and INT32, but only if XMD_H is
-  not defined.  Unfortunately, the MinGW and Borland compilers include
-  a typedef for INT32, which causes a conflict.  MSVC does not include
-  a conficting typedef given the headers which are included.
-*/
-#if defined(__BORLANDC__) || defined(__MINGW32__)
-# define XMD_H 1
-#endif
-
-/* Define "boolean" as unsigned char, not int, per Windows custom. */
-#if defined(__WIN32__) && !defined(__MINGW32__)
-# ifndef __RPCNDR_H__            /* don't conflict if rpcndr.h already read */
-   typedef unsigned char boolean;
-# endif
-# define HAVE_BOOLEAN            /* prevent jmorecfg.h from redefining it */
-#endif
-
-#include "../LibJPEG/jpeglib.h"
-#include "../LibJPEG/jerror.h"
-
-typedef struct jpeg_error_mgr jpeg_error_mgr;
-typedef struct jpeg_common_struct jpeg_common_struct;
-typedef struct jpeg_decompress_struct jpeg_decompress_struct;
-typedef struct jpeg_source_mgr jpeg_source_mgr;
-
-typedef enum {
-	osibsNotSetYet,
-	osibsJpegInterchangeFormat,
-	osibsStrile,
-	osibsEof
-} OJPEGStateInBufferSource;
-
-typedef enum {
-	ososSoi,
-	ososQTable0,ososQTable1,ososQTable2,ososQTable3,
-	ososDcTable0,ososDcTable1,ososDcTable2,ososDcTable3,
-	ososAcTable0,ososAcTable1,ososAcTable2,ososAcTable3,
-	ososDri,
-	ososSof,
-	ososSos,
-	ososCompressed,
-	ososRst,
-	ososEoi
-} OJPEGStateOutState;
-
-typedef struct {
-	TIFF* tif;
-	#ifndef LIBJPEG_ENCAP_EXTERNAL
-	JMP_BUF exit_jmpbuf;
-	#endif
-	TIFFVGetMethod vgetparent;
-	TIFFVSetMethod vsetparent;
-	TIFFPrintMethod printdir;
-	uint64 file_size;
-	uint32 image_width;
-	uint32 image_length;
-	uint32 strile_width;
-	uint32 strile_length;
-	uint32 strile_length_total;
-	uint8 samples_per_pixel;
-	uint8 plane_sample_offset;
-	uint8 samples_per_pixel_per_plane;
-	uint64 jpeg_interchange_format;
-	uint64 jpeg_interchange_format_length;
-	uint8 jpeg_proc;
-	uint8 subsamplingcorrect;
-	uint8 subsamplingcorrect_done;
-	uint8 subsampling_tag;
-	uint8 subsampling_hor;
-	uint8 subsampling_ver;
-	uint8 subsampling_force_desubsampling_inside_decompression;
-	uint8 qtable_offset_count;
-	uint8 dctable_offset_count;
-	uint8 actable_offset_count;
-	uint64 qtable_offset[3];
-	uint64 dctable_offset[3];
-	uint64 actable_offset[3];
-	uint8* qtable[4];
-	uint8* dctable[4];
-	uint8* actable[4];
-	uint16 restart_interval;
-	uint8 restart_index;
-	uint8 sof_log;
-	uint8 sof_marker_id;
-	uint32 sof_x;
-	uint32 sof_y;
-	uint8 sof_c[3];
-	uint8 sof_hv[3];
-	uint8 sof_tq[3];
-	uint8 sos_cs[3];
-	uint8 sos_tda[3];
-	struct {
-		uint8 log;
-		OJPEGStateInBufferSource in_buffer_source;
-		uint32 in_buffer_next_strile;
-		uint64 in_buffer_file_pos;
-		uint64 in_buffer_file_togo;
-	} sos_end[3];
-	uint8 readheader_done;
-	uint8 writeheader_done;
-	uint16 write_cursample;
-	uint32 write_curstrile;
-	uint8 libjpeg_session_active;
-	uint8 libjpeg_jpeg_query_style;
-	jpeg_error_mgr libjpeg_jpeg_error_mgr;
-	jpeg_decompress_struct libjpeg_jpeg_decompress_struct;
-	jpeg_source_mgr libjpeg_jpeg_source_mgr;
-	uint8 subsampling_convert_log;
-	uint32 subsampling_convert_ylinelen;
-	uint32 subsampling_convert_ylines;
-	uint32 subsampling_convert_clinelen;
-	uint32 subsampling_convert_clines;
-	uint32 subsampling_convert_ybuflen;
-	uint32 subsampling_convert_cbuflen;
-	uint32 subsampling_convert_ycbcrbuflen;
-	uint8* subsampling_convert_ycbcrbuf;
-	uint8* subsampling_convert_ybuf;
-	uint8* subsampling_convert_cbbuf;
-	uint8* subsampling_convert_crbuf;
-	uint32 subsampling_convert_ycbcrimagelen;
-	uint8** subsampling_convert_ycbcrimage;
-	uint32 subsampling_convert_clinelenout;
-	uint32 subsampling_convert_state;
-	uint32 bytes_per_line;   /* if the codec outputs subsampled data, a 'line' in bytes_per_line */
-	uint32 lines_per_strile; /* and lines_per_strile means subsampling_ver desubsampled rows     */
-	OJPEGStateInBufferSource in_buffer_source;
-	uint32 in_buffer_next_strile;
-	uint32 in_buffer_strile_count;
-	uint64 in_buffer_file_pos;
-	uint8 in_buffer_file_pos_log;
-	uint64 in_buffer_file_togo;
-	uint16 in_buffer_togo;
-	uint8* in_buffer_cur;
-	uint8 in_buffer[OJPEG_BUFFER];
-	OJPEGStateOutState out_state;
-	uint8 out_buffer[OJPEG_BUFFER];
-	uint8* skip_buffer;
-} OJPEGState;
-
-static int OJPEGVGetField(TIFF* tif, uint32 tag, va_list ap);
-static int OJPEGVSetField(TIFF* tif, uint32 tag, va_list ap);
-static void OJPEGPrintDir(TIFF* tif, FILE* fd, long flags);
-
-static int OJPEGFixupTags(TIFF* tif);
-static int OJPEGSetupDecode(TIFF* tif);
-static int OJPEGPreDecode(TIFF* tif, uint16 s);
-static int OJPEGPreDecodeSkipRaw(TIFF* tif);
-static int OJPEGPreDecodeSkipScanlines(TIFF* tif);
-static int OJPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s);
-static int OJPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc);
-static int OJPEGDecodeScanlines(TIFF* tif, uint8* buf, tmsize_t cc);
-static void OJPEGPostDecode(TIFF* tif, uint8* buf, tmsize_t cc);
-static int OJPEGSetupEncode(TIFF* tif);
-static int OJPEGPreEncode(TIFF* tif, uint16 s);
-static int OJPEGEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s);
-static int OJPEGPostEncode(TIFF* tif);
-static void OJPEGCleanup(TIFF* tif);
-
-static void OJPEGSubsamplingCorrect(TIFF* tif);
-static int OJPEGReadHeaderInfo(TIFF* tif);
-static int OJPEGReadSecondarySos(TIFF* tif, uint16 s);
-static int OJPEGWriteHeaderInfo(TIFF* tif);
-static void OJPEGLibjpegSessionAbort(TIFF* tif);
-
-static int OJPEGReadHeaderInfoSec(TIFF* tif);
-static int OJPEGReadHeaderInfoSecStreamDri(TIFF* tif);
-static int OJPEGReadHeaderInfoSecStreamDqt(TIFF* tif);
-static int OJPEGReadHeaderInfoSecStreamDht(TIFF* tif);
-static int OJPEGReadHeaderInfoSecStreamSof(TIFF* tif, uint8 marker_id);
-static int OJPEGReadHeaderInfoSecStreamSos(TIFF* tif);
-static int OJPEGReadHeaderInfoSecTablesQTable(TIFF* tif);
-static int OJPEGReadHeaderInfoSecTablesDcTable(TIFF* tif);
-static int OJPEGReadHeaderInfoSecTablesAcTable(TIFF* tif);
-
-static int OJPEGReadBufferFill(OJPEGState* sp);
-static int OJPEGReadByte(OJPEGState* sp, uint8* byte);
-static int OJPEGReadBytePeek(OJPEGState* sp, uint8* byte);
-static void OJPEGReadByteAdvance(OJPEGState* sp);
-static int OJPEGReadWord(OJPEGState* sp, uint16* word);
-static int OJPEGReadBlock(OJPEGState* sp, uint16 len, void* mem);
-static void OJPEGReadSkip(OJPEGState* sp, uint16 len);
-
-static int OJPEGWriteStream(TIFF* tif, void** mem, uint32* len);
-static void OJPEGWriteStreamSoi(TIFF* tif, void** mem, uint32* len);
-static void OJPEGWriteStreamQTable(TIFF* tif, uint8 table_index, void** mem, uint32* len);
-static void OJPEGWriteStreamDcTable(TIFF* tif, uint8 table_index, void** mem, uint32* len);
-static void OJPEGWriteStreamAcTable(TIFF* tif, uint8 table_index, void** mem, uint32* len);
-static void OJPEGWriteStreamDri(TIFF* tif, void** mem, uint32* len);
-static void OJPEGWriteStreamSof(TIFF* tif, void** mem, uint32* len);
-static void OJPEGWriteStreamSos(TIFF* tif, void** mem, uint32* len);
-static int OJPEGWriteStreamCompressed(TIFF* tif, void** mem, uint32* len);
-static void OJPEGWriteStreamRst(TIFF* tif, void** mem, uint32* len);
-static void OJPEGWriteStreamEoi(TIFF* tif, void** mem, uint32* len);
-
-#ifdef LIBJPEG_ENCAP_EXTERNAL
-extern int jpeg_create_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo);
-extern int jpeg_read_header_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, uint8 require_image);
-extern int jpeg_start_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo);
-extern int jpeg_read_scanlines_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* scanlines, uint32 max_lines);
-extern int jpeg_read_raw_data_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* data, uint32 max_lines);
-extern void jpeg_encap_unwind(TIFF* tif);
-#else
-static int jpeg_create_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* j);
-static int jpeg_read_header_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, uint8 require_image);
-static int jpeg_start_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo);
-static int jpeg_read_scanlines_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* scanlines, uint32 max_lines);
-static int jpeg_read_raw_data_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* data, uint32 max_lines);
-static void jpeg_encap_unwind(TIFF* tif);
-#endif
-
-static void OJPEGLibjpegJpegErrorMgrOutputMessage(jpeg_common_struct* cinfo);
-static void OJPEGLibjpegJpegErrorMgrErrorExit(jpeg_common_struct* cinfo);
-static void OJPEGLibjpegJpegSourceMgrInitSource(jpeg_decompress_struct* cinfo);
-static boolean OJPEGLibjpegJpegSourceMgrFillInputBuffer(jpeg_decompress_struct* cinfo);
-static void OJPEGLibjpegJpegSourceMgrSkipInputData(jpeg_decompress_struct* cinfo, long num_bytes);
-static boolean OJPEGLibjpegJpegSourceMgrResyncToRestart(jpeg_decompress_struct* cinfo, int desired);
-static void OJPEGLibjpegJpegSourceMgrTermSource(jpeg_decompress_struct* cinfo);
-
-int
-TIFFInitOJPEG(TIFF* tif, int scheme)
-{
-	static const char module[]="TIFFInitOJPEG";
-	OJPEGState* sp;
-
-	assert(scheme==COMPRESSION_OJPEG);
-
-        /*
-	 * Merge codec-specific tag information.
-	 */
-	if (!_TIFFMergeFields(tif, ojpegFields, TIFFArrayCount(ojpegFields))) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-		    "Merging Old JPEG codec-specific tags failed");
-		return 0;
-	}
-
-	/* state block */
-	sp=_TIFFmalloc(sizeof(OJPEGState));
-	if (sp==NULL)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"No space for OJPEG state block");
-		return(0);
-	}
-	_TIFFmemset(sp,0,sizeof(OJPEGState));
-	sp->tif=tif;
-	sp->jpeg_proc=1;
-	sp->subsampling_hor=2;
-	sp->subsampling_ver=2;
-	TIFFSetField(tif,TIFFTAG_YCBCRSUBSAMPLING,2,2);
-	/* tif codec methods */
-	tif->tif_fixuptags=OJPEGFixupTags;  
-	tif->tif_setupdecode=OJPEGSetupDecode;
-	tif->tif_predecode=OJPEGPreDecode;
-	tif->tif_postdecode=OJPEGPostDecode;  
-	tif->tif_decoderow=OJPEGDecode;  
-	tif->tif_decodestrip=OJPEGDecode;  
-	tif->tif_decodetile=OJPEGDecode;  
-	tif->tif_setupencode=OJPEGSetupEncode;
-	tif->tif_preencode=OJPEGPreEncode;
-	tif->tif_postencode=OJPEGPostEncode;
-	tif->tif_encoderow=OJPEGEncode;  
-	tif->tif_encodestrip=OJPEGEncode;  
-	tif->tif_encodetile=OJPEGEncode;  
-	tif->tif_cleanup=OJPEGCleanup;
-	tif->tif_data=(uint8*)sp;
-	/* tif tag methods */
-	sp->vgetparent=tif->tif_tagmethods.vgetfield;
-	tif->tif_tagmethods.vgetfield=OJPEGVGetField;
-	sp->vsetparent=tif->tif_tagmethods.vsetfield;
-	tif->tif_tagmethods.vsetfield=OJPEGVSetField;
-	sp->printdir=tif->tif_tagmethods.printdir;
-	tif->tif_tagmethods.printdir=OJPEGPrintDir;
-	/* Some OJPEG files don't have strip or tile offsets or bytecounts tags.
-	   Some others do, but have totally meaningless or corrupt values
-	   in these tags. In these cases, the JpegInterchangeFormat stream is
-	   reliable. In any case, this decoder reads the compressed data itself,
-	   from the most reliable locations, and we need to notify encapsulating
-	   LibTiff not to read raw strips or tiles for us. */
-	tif->tif_flags|=TIFF_NOREADRAW;
-	return(1);
-}
-
-static int
-OJPEGVGetField(TIFF* tif, uint32 tag, va_list ap)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	switch(tag)
-	{
-		case TIFFTAG_JPEGIFOFFSET:
-			*va_arg(ap,uint64*)=(uint64)sp->jpeg_interchange_format;
-			break;
-		case TIFFTAG_JPEGIFBYTECOUNT:
-			*va_arg(ap,uint64*)=(uint64)sp->jpeg_interchange_format_length;
-			break;
-		case TIFFTAG_YCBCRSUBSAMPLING:
-			if (sp->subsamplingcorrect_done==0)
-				OJPEGSubsamplingCorrect(tif);
-			*va_arg(ap,uint16*)=(uint16)sp->subsampling_hor;
-			*va_arg(ap,uint16*)=(uint16)sp->subsampling_ver;
-			break;
-		case TIFFTAG_JPEGQTABLES:
-			*va_arg(ap,uint32*)=(uint32)sp->qtable_offset_count;
-			*va_arg(ap,void**)=(void*)sp->qtable_offset; 
-			break;
-		case TIFFTAG_JPEGDCTABLES:
-			*va_arg(ap,uint32*)=(uint32)sp->dctable_offset_count;
-			*va_arg(ap,void**)=(void*)sp->dctable_offset;  
-			break;
-		case TIFFTAG_JPEGACTABLES:
-			*va_arg(ap,uint32*)=(uint32)sp->actable_offset_count;
-			*va_arg(ap,void**)=(void*)sp->actable_offset;
-			break;
-		case TIFFTAG_JPEGPROC:
-			*va_arg(ap,uint16*)=(uint16)sp->jpeg_proc;
-			break;
-		case TIFFTAG_JPEGRESTARTINTERVAL:
-			*va_arg(ap,uint16*)=sp->restart_interval;
-			break;
-		default:
-			return (*sp->vgetparent)(tif,tag,ap);
-	}
-	return (1);
-}
-
-static int
-OJPEGVSetField(TIFF* tif, uint32 tag, va_list ap)
-{
-	static const char module[]="OJPEGVSetField";
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	uint32 ma;
-	uint64* mb;
-	uint32 n;
-	switch(tag)
-	{
-		case TIFFTAG_JPEGIFOFFSET:
-			sp->jpeg_interchange_format=(uint64)va_arg(ap,uint64);
-			break;
-		case TIFFTAG_JPEGIFBYTECOUNT:
-			sp->jpeg_interchange_format_length=(uint64)va_arg(ap,uint64);
-			break;
-		case TIFFTAG_YCBCRSUBSAMPLING:
-			sp->subsampling_tag=1;
-			sp->subsampling_hor=(uint8)va_arg(ap,uint16_vap);
-			sp->subsampling_ver=(uint8)va_arg(ap,uint16_vap);
-			tif->tif_dir.td_ycbcrsubsampling[0]=sp->subsampling_hor;
-			tif->tif_dir.td_ycbcrsubsampling[1]=sp->subsampling_ver;
-			break;
-		case TIFFTAG_JPEGQTABLES:
-			ma=(uint32)va_arg(ap,uint32);
-			if (ma!=0)
-			{
-				if (ma>3)
-				{
-					TIFFErrorExt(tif->tif_clientdata,module,"JpegQTables tag has incorrect count");
-					return(0);
-				}
-				sp->qtable_offset_count=(uint8)ma;
-				mb=(uint64*)va_arg(ap,uint64*);
-				for (n=0; n<ma; n++)
-					sp->qtable_offset[n]=mb[n];
-			}
-			break;
-		case TIFFTAG_JPEGDCTABLES:
-			ma=(uint32)va_arg(ap,uint32);
-			if (ma!=0)
-			{
-				if (ma>3)
-				{
-					TIFFErrorExt(tif->tif_clientdata,module,"JpegDcTables tag has incorrect count");
-					return(0);
-				}
-				sp->dctable_offset_count=(uint8)ma;
-				mb=(uint64*)va_arg(ap,uint64*);
-				for (n=0; n<ma; n++)
-					sp->dctable_offset[n]=mb[n];
-			}
-			break;
-		case TIFFTAG_JPEGACTABLES:
-			ma=(uint32)va_arg(ap,uint32);
-			if (ma!=0)
-			{
-				if (ma>3)
-				{
-					TIFFErrorExt(tif->tif_clientdata,module,"JpegAcTables tag has incorrect count");
-					return(0);
-				}
-				sp->actable_offset_count=(uint8)ma;
-				mb=(uint64*)va_arg(ap,uint64*);
-				for (n=0; n<ma; n++)
-					sp->actable_offset[n]=mb[n];
-			}
-			break;
-		case TIFFTAG_JPEGPROC:
-			sp->jpeg_proc=(uint8)va_arg(ap,uint16_vap);
-			break;
-		case TIFFTAG_JPEGRESTARTINTERVAL:
-			sp->restart_interval=(uint16)va_arg(ap,uint16_vap);
-			break;
-		default:
-			return (*sp->vsetparent)(tif,tag,ap);
-	}
-	TIFFSetFieldBit(tif,TIFFFieldWithTag(tif,tag)->field_bit);
-	tif->tif_flags|=TIFF_DIRTYDIRECT;
-	return(1);
-}
-
-static void
-OJPEGPrintDir(TIFF* tif, FILE* fd, long flags)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	uint8 m;
-	(void)flags;
-	assert(sp!=NULL);
-	if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGINTERCHANGEFORMAT))
-		fprintf(fd,"  JpegInterchangeFormat: " TIFF_UINT64_FORMAT "\n",(TIFF_UINT64_T)sp->jpeg_interchange_format);  
-	if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH))
-		fprintf(fd,"  JpegInterchangeFormatLength: " TIFF_UINT64_FORMAT "\n",(TIFF_UINT64_T)sp->jpeg_interchange_format_length);  
-	if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGQTABLES))
-	{
-		fprintf(fd,"  JpegQTables:");
-		for (m=0; m<sp->qtable_offset_count; m++)
-			fprintf(fd," " TIFF_UINT64_FORMAT,(TIFF_UINT64_T)sp->qtable_offset[m]);
-		fprintf(fd,"\n");
-	}
-	if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGDCTABLES))
-	{
-		fprintf(fd,"  JpegDcTables:");
-		for (m=0; m<sp->dctable_offset_count; m++)
-			fprintf(fd," " TIFF_UINT64_FORMAT,(TIFF_UINT64_T)sp->dctable_offset[m]);
-		fprintf(fd,"\n");
-	}
-	if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGACTABLES))
-	{
-		fprintf(fd,"  JpegAcTables:");
-		for (m=0; m<sp->actable_offset_count; m++)
-			fprintf(fd," " TIFF_UINT64_FORMAT,(TIFF_UINT64_T)sp->actable_offset[m]);
-		fprintf(fd,"\n");
-	}
-	if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGPROC))
-		fprintf(fd,"  JpegProc: %u\n",(unsigned int)sp->jpeg_proc);
-	if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGRESTARTINTERVAL))
-		fprintf(fd,"  JpegRestartInterval: %u\n",(unsigned int)sp->restart_interval);
-	if (sp->printdir)
-		(*sp->printdir)(tif, fd, flags);
-}
-
-static int
-OJPEGFixupTags(TIFF* tif)
-{
-	(void) tif;
-	return(1);
-}
-
-static int
-OJPEGSetupDecode(TIFF* tif)
-{
-	static const char module[]="OJPEGSetupDecode";
-	TIFFWarningExt(tif->tif_clientdata,module,"Depreciated and troublesome old-style JPEG compression mode, please convert to new-style JPEG compression and notify vendor of writing software");
-	return(1);
-}
-
-static int
-OJPEGPreDecode(TIFF* tif, uint16 s)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	uint32 m;
-	if (sp->subsamplingcorrect_done==0)
-		OJPEGSubsamplingCorrect(tif);
-	if (sp->readheader_done==0)
-	{
-		if (OJPEGReadHeaderInfo(tif)==0)
-			return(0);
-	}
-	if (sp->sos_end[s].log==0)
-	{
-		if (OJPEGReadSecondarySos(tif,s)==0)
-			return(0);
-	}
-	if isTiled(tif)
-		m=tif->tif_curtile;
-	else
-		m=tif->tif_curstrip;
-	if ((sp->writeheader_done!=0) && ((sp->write_cursample!=s) || (sp->write_curstrile>m)))
-	{
-		if (sp->libjpeg_session_active!=0)
-			OJPEGLibjpegSessionAbort(tif);
-		sp->writeheader_done=0;
-	}
-	if (sp->writeheader_done==0)
-	{
-		sp->plane_sample_offset=(uint8)s;
-		sp->write_cursample=s;
-		sp->write_curstrile=s*tif->tif_dir.td_stripsperimage;
-		if ((sp->in_buffer_file_pos_log==0) ||
-		    (sp->in_buffer_file_pos-sp->in_buffer_togo!=sp->sos_end[s].in_buffer_file_pos))
-		{
-			sp->in_buffer_source=sp->sos_end[s].in_buffer_source;
-			sp->in_buffer_next_strile=sp->sos_end[s].in_buffer_next_strile;
-			sp->in_buffer_file_pos=sp->sos_end[s].in_buffer_file_pos;
-			sp->in_buffer_file_pos_log=0;
-			sp->in_buffer_file_togo=sp->sos_end[s].in_buffer_file_togo;
-			sp->in_buffer_togo=0;
-			sp->in_buffer_cur=0;
-		}
-		if (OJPEGWriteHeaderInfo(tif)==0)
-			return(0);
-	}
-	while (sp->write_curstrile<m)          
-	{
-		if (sp->libjpeg_jpeg_query_style==0)
-		{
-			if (OJPEGPreDecodeSkipRaw(tif)==0)
-				return(0);
-		}
-		else
-		{
-			if (OJPEGPreDecodeSkipScanlines(tif)==0)
-				return(0);
-		}
-		sp->write_curstrile++;
-	}
-	return(1);
-}
-
-static int
-OJPEGPreDecodeSkipRaw(TIFF* tif)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	uint32 m;
-	m=sp->lines_per_strile;
-	if (sp->subsampling_convert_state!=0)
-	{
-		if (sp->subsampling_convert_clines-sp->subsampling_convert_state>=m)
-		{
-			sp->subsampling_convert_state+=m;
-			if (sp->subsampling_convert_state==sp->subsampling_convert_clines)
-				sp->subsampling_convert_state=0;
-			return(1);
-		}
-		m-=sp->subsampling_convert_clines-sp->subsampling_convert_state;
-		sp->subsampling_convert_state=0;
-	}
-	while (m>=sp->subsampling_convert_clines)
-	{
-		if (jpeg_read_raw_data_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),sp->subsampling_convert_ycbcrimage,sp->subsampling_ver*8)==0)
-			return(0);
-		m-=sp->subsampling_convert_clines;
-	}
-	if (m>0)
-	{
-		if (jpeg_read_raw_data_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),sp->subsampling_convert_ycbcrimage,sp->subsampling_ver*8)==0)
-			return(0);
-		sp->subsampling_convert_state=m;
-	}
-	return(1);
-}
-
-static int
-OJPEGPreDecodeSkipScanlines(TIFF* tif)
-{
-	static const char module[]="OJPEGPreDecodeSkipScanlines";
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	uint32 m;
-	if (sp->skip_buffer==NULL)
-	{
-		sp->skip_buffer=_TIFFmalloc(sp->bytes_per_line);
-		if (sp->skip_buffer==NULL)
-		{
-			TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
-			return(0);
-		}
-	}
-	for (m=0; m<sp->lines_per_strile; m++)
-	{
-		if (jpeg_read_scanlines_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),&sp->skip_buffer,1)==0)
-			return(0);
-	}
-	return(1);
-}
-
-static int
-OJPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	(void)s;
-	if (sp->libjpeg_jpeg_query_style==0)
-	{
-		if (OJPEGDecodeRaw(tif,buf,cc)==0)
-			return(0);
-	}
-	else
-	{
-		if (OJPEGDecodeScanlines(tif,buf,cc)==0)
-			return(0);
-	}
-	return(1);
-}
-
-static int
-OJPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc)
-{
-	static const char module[]="OJPEGDecodeRaw";
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	uint8* m;
-	tmsize_t n;
-	uint8* oy;
-	uint8* ocb;
-	uint8* ocr;
-	uint8* p;
-	uint32 q;
-	uint8* r;
-	uint8 sx,sy;
-	if (cc%sp->bytes_per_line!=0)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Fractional scanline not read");
-		return(0);
-	}
-	assert(cc>0);
-	m=buf;
-	n=cc;
-	do
-	{
-		if (sp->subsampling_convert_state==0)
-		{
-			if (jpeg_read_raw_data_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),sp->subsampling_convert_ycbcrimage,sp->subsampling_ver*8)==0)
-				return(0);
-		}
-		oy=sp->subsampling_convert_ybuf+sp->subsampling_convert_state*sp->subsampling_ver*sp->subsampling_convert_ylinelen;
-		ocb=sp->subsampling_convert_cbbuf+sp->subsampling_convert_state*sp->subsampling_convert_clinelen;
-		ocr=sp->subsampling_convert_crbuf+sp->subsampling_convert_state*sp->subsampling_convert_clinelen;
-		p=m;
-		for (q=0; q<sp->subsampling_convert_clinelenout; q++)
-		{
-			r=oy;
-			for (sy=0; sy<sp->subsampling_ver; sy++)
-			{
-				for (sx=0; sx<sp->subsampling_hor; sx++)
-					*p++=*r++;
-				r+=sp->subsampling_convert_ylinelen-sp->subsampling_hor;
-			}
-			oy+=sp->subsampling_hor;
-			*p++=*ocb++;
-			*p++=*ocr++;
-		}
-		sp->subsampling_convert_state++;
-		if (sp->subsampling_convert_state==sp->subsampling_convert_clines)
-			sp->subsampling_convert_state=0;
-		m+=sp->bytes_per_line;
-		n-=sp->bytes_per_line;
-	} while(n>0);
-	return(1);
-}
-
-static int
-OJPEGDecodeScanlines(TIFF* tif, uint8* buf, tmsize_t cc)
-{
-	static const char module[]="OJPEGDecodeScanlines";
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	uint8* m;
-	tmsize_t n;
-	if (cc%sp->bytes_per_line!=0)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Fractional scanline not read");
-		return(0);
-	}
-	assert(cc>0);
-	m=buf;
-	n=cc;
-	do
-	{
-		if (jpeg_read_scanlines_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),&m,1)==0)
-			return(0);
-		m+=sp->bytes_per_line;
-		n-=sp->bytes_per_line;
-	} while(n>0);
-	return(1);
-}
-
-static void
-OJPEGPostDecode(TIFF* tif, uint8* buf, tmsize_t cc)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	(void)buf;
-	(void)cc;
-	sp->write_curstrile++;
-	if (sp->write_curstrile%tif->tif_dir.td_stripsperimage==0)  
-	{
-		assert(sp->libjpeg_session_active!=0);
-		OJPEGLibjpegSessionAbort(tif);
-		sp->writeheader_done=0;
-	}
-}
-
-static int
-OJPEGSetupEncode(TIFF* tif)
-{
-	static const char module[]="OJPEGSetupEncode";
-	TIFFErrorExt(tif->tif_clientdata,module,"OJPEG encoding not supported; use new-style JPEG compression instead");
-	return(0);
-}
-
-static int
-OJPEGPreEncode(TIFF* tif, uint16 s)
-{
-	static const char module[]="OJPEGPreEncode";
-	(void)s;
-	TIFFErrorExt(tif->tif_clientdata,module,"OJPEG encoding not supported; use new-style JPEG compression instead");
-	return(0);
-}
-
-static int
-OJPEGEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
-{
-	static const char module[]="OJPEGEncode";
-	(void)buf;
-	(void)cc;
-	(void)s;
-	TIFFErrorExt(tif->tif_clientdata,module,"OJPEG encoding not supported; use new-style JPEG compression instead");
-	return(0);
-}
-
-static int
-OJPEGPostEncode(TIFF* tif)
-{
-	static const char module[]="OJPEGPostEncode";
-	TIFFErrorExt(tif->tif_clientdata,module,"OJPEG encoding not supported; use new-style JPEG compression instead");
-	return(0);
-}
-
-static void
-OJPEGCleanup(TIFF* tif)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	if (sp!=0)
-	{
-		tif->tif_tagmethods.vgetfield=sp->vgetparent;
-		tif->tif_tagmethods.vsetfield=sp->vsetparent;
-		tif->tif_tagmethods.printdir=sp->printdir;
-		if (sp->qtable[0]!=0)
-			_TIFFfree(sp->qtable[0]);
-		if (sp->qtable[1]!=0)
-			_TIFFfree(sp->qtable[1]);
-		if (sp->qtable[2]!=0)
-			_TIFFfree(sp->qtable[2]);
-		if (sp->qtable[3]!=0)
-			_TIFFfree(sp->qtable[3]);
-		if (sp->dctable[0]!=0)
-			_TIFFfree(sp->dctable[0]);
-		if (sp->dctable[1]!=0)
-			_TIFFfree(sp->dctable[1]);
-		if (sp->dctable[2]!=0)
-			_TIFFfree(sp->dctable[2]);
-		if (sp->dctable[3]!=0)
-			_TIFFfree(sp->dctable[3]);
-		if (sp->actable[0]!=0)
-			_TIFFfree(sp->actable[0]);
-		if (sp->actable[1]!=0)
-			_TIFFfree(sp->actable[1]);
-		if (sp->actable[2]!=0)
-			_TIFFfree(sp->actable[2]);
-		if (sp->actable[3]!=0)
-			_TIFFfree(sp->actable[3]);
-		if (sp->libjpeg_session_active!=0)
-			OJPEGLibjpegSessionAbort(tif);
-		if (sp->subsampling_convert_ycbcrbuf!=0)
-			_TIFFfree(sp->subsampling_convert_ycbcrbuf);
-		if (sp->subsampling_convert_ycbcrimage!=0)
-			_TIFFfree(sp->subsampling_convert_ycbcrimage);
-		if (sp->skip_buffer!=0)
-			_TIFFfree(sp->skip_buffer);
-		_TIFFfree(sp);
-		tif->tif_data=NULL;
-		_TIFFSetDefaultCompressionState(tif);
-	}
-}
-
-static void
-OJPEGSubsamplingCorrect(TIFF* tif)
-{
-	static const char module[]="OJPEGSubsamplingCorrect";
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	uint8 mh;
-	uint8 mv;
-        _TIFFFillStriles( tif );
-        
-	assert(sp->subsamplingcorrect_done==0);
-	if ((tif->tif_dir.td_samplesperpixel!=3) || ((tif->tif_dir.td_photometric!=PHOTOMETRIC_YCBCR) &&
-	    (tif->tif_dir.td_photometric!=PHOTOMETRIC_ITULAB)))
-	{
-		if (sp->subsampling_tag!=0)
-			TIFFWarningExt(tif->tif_clientdata,module,"Subsampling tag not appropriate for this Photometric and/or SamplesPerPixel");
-		sp->subsampling_hor=1;
-		sp->subsampling_ver=1;
-		sp->subsampling_force_desubsampling_inside_decompression=0;
-	}
-	else
-	{
-		sp->subsamplingcorrect_done=1;
-		mh=sp->subsampling_hor;
-		mv=sp->subsampling_ver;
-		sp->subsamplingcorrect=1;
-		OJPEGReadHeaderInfoSec(tif);
-		if (sp->subsampling_force_desubsampling_inside_decompression!=0)
-		{
-			sp->subsampling_hor=1;
-			sp->subsampling_ver=1;
-		}
-		sp->subsamplingcorrect=0;
-		if (((sp->subsampling_hor!=mh) || (sp->subsampling_ver!=mv)) && (sp->subsampling_force_desubsampling_inside_decompression==0))
-		{
-			if (sp->subsampling_tag==0)
-				TIFFWarningExt(tif->tif_clientdata,module,"Subsampling tag is not set, yet subsampling inside JPEG data [%d,%d] does not match default values [2,2]; assuming subsampling inside JPEG data is correct",sp->subsampling_hor,sp->subsampling_ver);
-			else
-				TIFFWarningExt(tif->tif_clientdata,module,"Subsampling inside JPEG data [%d,%d] does not match subsampling tag values [%d,%d]; assuming subsampling inside JPEG data is correct",sp->subsampling_hor,sp->subsampling_ver,mh,mv);
-		}
-		if (sp->subsampling_force_desubsampling_inside_decompression!=0)
-		{
-			if (sp->subsampling_tag==0)
-				TIFFWarningExt(tif->tif_clientdata,module,"Subsampling tag is not set, yet subsampling inside JPEG data does not match default values [2,2] (nor any other values allowed in TIFF); assuming subsampling inside JPEG data is correct and desubsampling inside JPEG decompression");
-			else
-				TIFFWarningExt(tif->tif_clientdata,module,"Subsampling inside JPEG data does not match subsampling tag values [%d,%d] (nor any other values allowed in TIFF); assuming subsampling inside JPEG data is correct and desubsampling inside JPEG decompression",mh,mv);
-		}
-		if (sp->subsampling_force_desubsampling_inside_decompression==0)
-		{
-			if (sp->subsampling_hor<sp->subsampling_ver)
-				TIFFWarningExt(tif->tif_clientdata,module,"Subsampling values [%d,%d] are not allowed in TIFF",sp->subsampling_hor,sp->subsampling_ver);
-		}
-	}
-	sp->subsamplingcorrect_done=1;
-}
-
-static int
-OJPEGReadHeaderInfo(TIFF* tif)
-{
-	static const char module[]="OJPEGReadHeaderInfo";
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	assert(sp->readheader_done==0);
-	sp->image_width=tif->tif_dir.td_imagewidth;
-	sp->image_length=tif->tif_dir.td_imagelength;
-	if isTiled(tif)
-	{
-		sp->strile_width=tif->tif_dir.td_tilewidth;
-		sp->strile_length=tif->tif_dir.td_tilelength;
-		sp->strile_length_total=((sp->image_length+sp->strile_length-1)/sp->strile_length)*sp->strile_length;
-	}
-	else
-	{
-		sp->strile_width=sp->image_width;
-		sp->strile_length=tif->tif_dir.td_rowsperstrip;
-		sp->strile_length_total=sp->image_length;
-	}
-	if (tif->tif_dir.td_samplesperpixel==1)
-	{
-		sp->samples_per_pixel=1;
-		sp->plane_sample_offset=0;
-		sp->samples_per_pixel_per_plane=sp->samples_per_pixel;
-		sp->subsampling_hor=1;
-		sp->subsampling_ver=1;
-	}
-	else
-	{
-		if (tif->tif_dir.td_samplesperpixel!=3)
-		{
-			TIFFErrorExt(tif->tif_clientdata,module,"SamplesPerPixel %d not supported for this compression scheme",sp->samples_per_pixel);
-			return(0);
-		}
-		sp->samples_per_pixel=3;
-		sp->plane_sample_offset=0;
-		if (tif->tif_dir.td_planarconfig==PLANARCONFIG_CONTIG)
-			sp->samples_per_pixel_per_plane=3;
-		else
-			sp->samples_per_pixel_per_plane=1;
-	}
-	if (sp->strile_length<sp->image_length)
-	{
-		if (sp->strile_length%(sp->subsampling_ver*8)!=0)
-		{
-			TIFFErrorExt(tif->tif_clientdata,module,"Incompatible vertical subsampling and image strip/tile length");
-			return(0);
-		}
-		sp->restart_interval=((sp->strile_width+sp->subsampling_hor*8-1)/(sp->subsampling_hor*8))*(sp->strile_length/(sp->subsampling_ver*8));
-	}
-	if (OJPEGReadHeaderInfoSec(tif)==0)
-		return(0);
-	sp->sos_end[0].log=1;
-	sp->sos_end[0].in_buffer_source=sp->in_buffer_source;
-	sp->sos_end[0].in_buffer_next_strile=sp->in_buffer_next_strile;
-	sp->sos_end[0].in_buffer_file_pos=sp->in_buffer_file_pos-sp->in_buffer_togo;
-	sp->sos_end[0].in_buffer_file_togo=sp->in_buffer_file_togo+sp->in_buffer_togo; 
-	sp->readheader_done=1;
-	return(1);
-}
-
-static int
-OJPEGReadSecondarySos(TIFF* tif, uint16 s)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	uint8 m;
-	assert(s>0);
-	assert(s<3);
-	assert(sp->sos_end[0].log!=0);
-	assert(sp->sos_end[s].log==0);
-	sp->plane_sample_offset=s-1;
-	while(sp->sos_end[sp->plane_sample_offset].log==0)
-		sp->plane_sample_offset--;
-	sp->in_buffer_source=sp->sos_end[sp->plane_sample_offset].in_buffer_source;
-	sp->in_buffer_next_strile=sp->sos_end[sp->plane_sample_offset].in_buffer_next_strile;
-	sp->in_buffer_file_pos=sp->sos_end[sp->plane_sample_offset].in_buffer_file_pos;
-	sp->in_buffer_file_pos_log=0;
-	sp->in_buffer_file_togo=sp->sos_end[sp->plane_sample_offset].in_buffer_file_togo;
-	sp->in_buffer_togo=0;
-	sp->in_buffer_cur=0;
-	while(sp->plane_sample_offset<s)
-	{
-		do
-		{
-			if (OJPEGReadByte(sp,&m)==0)
-				return(0);
-			if (m==255)
-			{
-				do
-				{
-					if (OJPEGReadByte(sp,&m)==0)
-						return(0);
-					if (m!=255)
-						break;
-				} while(1);
-				if (m==JPEG_MARKER_SOS)
-					break;
-			}
-		} while(1);
-		sp->plane_sample_offset++;
-		if (OJPEGReadHeaderInfoSecStreamSos(tif)==0)
-			return(0);
-		sp->sos_end[sp->plane_sample_offset].log=1;
-		sp->sos_end[sp->plane_sample_offset].in_buffer_source=sp->in_buffer_source;
-		sp->sos_end[sp->plane_sample_offset].in_buffer_next_strile=sp->in_buffer_next_strile;
-		sp->sos_end[sp->plane_sample_offset].in_buffer_file_pos=sp->in_buffer_file_pos-sp->in_buffer_togo;
-		sp->sos_end[sp->plane_sample_offset].in_buffer_file_togo=sp->in_buffer_file_togo+sp->in_buffer_togo;
-	}
-	return(1);
-}
-
-static int
-OJPEGWriteHeaderInfo(TIFF* tif)
-{
-	static const char module[]="OJPEGWriteHeaderInfo";
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	uint8** m;
-	uint32 n;
-	/* if a previous attempt failed, don't try again */
-	if (sp->libjpeg_session_active != 0) 
-		return 0;
-	sp->out_state=ososSoi;
-	sp->restart_index=0;
-	jpeg_std_error(&(sp->libjpeg_jpeg_error_mgr));
-	sp->libjpeg_jpeg_error_mgr.output_message=OJPEGLibjpegJpegErrorMgrOutputMessage;
-	sp->libjpeg_jpeg_error_mgr.error_exit=OJPEGLibjpegJpegErrorMgrErrorExit;
-	sp->libjpeg_jpeg_decompress_struct.err=&(sp->libjpeg_jpeg_error_mgr);
-	sp->libjpeg_jpeg_decompress_struct.client_data=(void*)tif;
-	if (jpeg_create_decompress_encap(sp,&(sp->libjpeg_jpeg_decompress_struct))==0)
-		return(0);
-	sp->libjpeg_session_active=1;
-	sp->libjpeg_jpeg_source_mgr.bytes_in_buffer=0;
-	sp->libjpeg_jpeg_source_mgr.init_source=OJPEGLibjpegJpegSourceMgrInitSource;
-	sp->libjpeg_jpeg_source_mgr.fill_input_buffer=OJPEGLibjpegJpegSourceMgrFillInputBuffer;
-	sp->libjpeg_jpeg_source_mgr.skip_input_data=OJPEGLibjpegJpegSourceMgrSkipInputData;
-	sp->libjpeg_jpeg_source_mgr.resync_to_restart=OJPEGLibjpegJpegSourceMgrResyncToRestart;
-	sp->libjpeg_jpeg_source_mgr.term_source=OJPEGLibjpegJpegSourceMgrTermSource;
-	sp->libjpeg_jpeg_decompress_struct.src=&(sp->libjpeg_jpeg_source_mgr);
-	if (jpeg_read_header_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),1)==0)
-		return(0);
-	if ((sp->subsampling_force_desubsampling_inside_decompression==0) && (sp->samples_per_pixel_per_plane>1))
-	{
-		sp->libjpeg_jpeg_decompress_struct.raw_data_out=1;
-#if JPEG_LIB_VERSION >= 70
-		sp->libjpeg_jpeg_decompress_struct.do_fancy_upsampling=FALSE;
-#endif
-		sp->libjpeg_jpeg_query_style=0;
-		if (sp->subsampling_convert_log==0)
-		{
-			assert(sp->subsampling_convert_ycbcrbuf==0);
-			assert(sp->subsampling_convert_ycbcrimage==0);
-			sp->subsampling_convert_ylinelen=((sp->strile_width+sp->subsampling_hor*8-1)/(sp->subsampling_hor*8)*sp->subsampling_hor*8);
-			sp->subsampling_convert_ylines=sp->subsampling_ver*8;
-			sp->subsampling_convert_clinelen=sp->subsampling_convert_ylinelen/sp->subsampling_hor;
-			sp->subsampling_convert_clines=8;
-			sp->subsampling_convert_ybuflen=sp->subsampling_convert_ylinelen*sp->subsampling_convert_ylines;
-			sp->subsampling_convert_cbuflen=sp->subsampling_convert_clinelen*sp->subsampling_convert_clines;
-			sp->subsampling_convert_ycbcrbuflen=sp->subsampling_convert_ybuflen+2*sp->subsampling_convert_cbuflen;
-			sp->subsampling_convert_ycbcrbuf=_TIFFmalloc(sp->subsampling_convert_ycbcrbuflen);
-			if (sp->subsampling_convert_ycbcrbuf==0)
-			{
-				TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
-				return(0);
-			}
-			sp->subsampling_convert_ybuf=sp->subsampling_convert_ycbcrbuf;
-			sp->subsampling_convert_cbbuf=sp->subsampling_convert_ybuf+sp->subsampling_convert_ybuflen;
-			sp->subsampling_convert_crbuf=sp->subsampling_convert_cbbuf+sp->subsampling_convert_cbuflen;
-			sp->subsampling_convert_ycbcrimagelen=3+sp->subsampling_convert_ylines+2*sp->subsampling_convert_clines;
-			sp->subsampling_convert_ycbcrimage=_TIFFmalloc(sp->subsampling_convert_ycbcrimagelen*sizeof(uint8*));
-			if (sp->subsampling_convert_ycbcrimage==0)
-			{
-				TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
-				return(0);
-			}
-			m=sp->subsampling_convert_ycbcrimage;
-			*m++=(uint8*)(sp->subsampling_convert_ycbcrimage+3);
-			*m++=(uint8*)(sp->subsampling_convert_ycbcrimage+3+sp->subsampling_convert_ylines);
-			*m++=(uint8*)(sp->subsampling_convert_ycbcrimage+3+sp->subsampling_convert_ylines+sp->subsampling_convert_clines);
-			for (n=0; n<sp->subsampling_convert_ylines; n++)
-				*m++=sp->subsampling_convert_ybuf+n*sp->subsampling_convert_ylinelen;
-			for (n=0; n<sp->subsampling_convert_clines; n++)
-				*m++=sp->subsampling_convert_cbbuf+n*sp->subsampling_convert_clinelen;
-			for (n=0; n<sp->subsampling_convert_clines; n++)
-				*m++=sp->subsampling_convert_crbuf+n*sp->subsampling_convert_clinelen;
-			sp->subsampling_convert_clinelenout=((sp->strile_width+sp->subsampling_hor-1)/sp->subsampling_hor);
-			sp->subsampling_convert_state=0;
-			sp->bytes_per_line=sp->subsampling_convert_clinelenout*(sp->subsampling_ver*sp->subsampling_hor+2);
-			sp->lines_per_strile=((sp->strile_length+sp->subsampling_ver-1)/sp->subsampling_ver);
-			sp->subsampling_convert_log=1;
-		}
-	}
-	else
-	{
-		sp->libjpeg_jpeg_decompress_struct.jpeg_color_space=JCS_UNKNOWN;
-		sp->libjpeg_jpeg_decompress_struct.out_color_space=JCS_UNKNOWN;
-		sp->libjpeg_jpeg_query_style=1;
-		sp->bytes_per_line=sp->samples_per_pixel_per_plane*sp->strile_width;
-		sp->lines_per_strile=sp->strile_length;
-	}
-	if (jpeg_start_decompress_encap(sp,&(sp->libjpeg_jpeg_decompress_struct))==0)
-		return(0);
-	sp->writeheader_done=1;
-	return(1);
-}
-
-static void
-OJPEGLibjpegSessionAbort(TIFF* tif)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	assert(sp->libjpeg_session_active!=0);
-	jpeg_destroy((jpeg_common_struct*)(&(sp->libjpeg_jpeg_decompress_struct)));
-	sp->libjpeg_session_active=0;
-}
-
-static int
-OJPEGReadHeaderInfoSec(TIFF* tif)
-{
-	static const char module[]="OJPEGReadHeaderInfoSec";
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	uint8 m;
-	uint16 n;
-	uint8 o;
-	if (sp->file_size==0)
-		sp->file_size=TIFFGetFileSize(tif);
-	if (sp->jpeg_interchange_format!=0)
-	{
-		if (sp->jpeg_interchange_format>=sp->file_size)
-		{
-			sp->jpeg_interchange_format=0;
-			sp->jpeg_interchange_format_length=0;
-		}
-		else
-		{
-			if ((sp->jpeg_interchange_format_length==0) || (sp->jpeg_interchange_format+sp->jpeg_interchange_format_length>sp->file_size))
-				sp->jpeg_interchange_format_length=sp->file_size-sp->jpeg_interchange_format;
-		}
-	}
-	sp->in_buffer_source=osibsNotSetYet;
-	sp->in_buffer_next_strile=0;
-	sp->in_buffer_strile_count=tif->tif_dir.td_nstrips;
-	sp->in_buffer_file_togo=0;
-	sp->in_buffer_togo=0;
-	do
-	{
-		if (OJPEGReadBytePeek(sp,&m)==0)
-			return(0);
-		if (m!=255)
-			break;
-		OJPEGReadByteAdvance(sp);
-		do
-		{
-			if (OJPEGReadByte(sp,&m)==0)
-				return(0);
-		} while(m==255);
-		switch(m)
-		{
-			case JPEG_MARKER_SOI:
-				/* this type of marker has no data, and should be skipped */
-				break;
-			case JPEG_MARKER_COM:
-			case JPEG_MARKER_APP0:
-			case JPEG_MARKER_APP0+1:
-			case JPEG_MARKER_APP0+2:
-			case JPEG_MARKER_APP0+3:
-			case JPEG_MARKER_APP0+4:
-			case JPEG_MARKER_APP0+5:
-			case JPEG_MARKER_APP0+6:
-			case JPEG_MARKER_APP0+7:
-			case JPEG_MARKER_APP0+8:
-			case JPEG_MARKER_APP0+9:
-			case JPEG_MARKER_APP0+10:
-			case JPEG_MARKER_APP0+11:
-			case JPEG_MARKER_APP0+12:
-			case JPEG_MARKER_APP0+13:
-			case JPEG_MARKER_APP0+14:
-			case JPEG_MARKER_APP0+15:
-				/* this type of marker has data, but it has no use to us (and no place here) and should be skipped */
-				if (OJPEGReadWord(sp,&n)==0)
-					return(0);
-				if (n<2)
-				{
-					if (sp->subsamplingcorrect==0)
-						TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JPEG data");
-					return(0);
-				}
-				if (n>2)
-					OJPEGReadSkip(sp,n-2);
-				break;
-			case JPEG_MARKER_DRI:
-				if (OJPEGReadHeaderInfoSecStreamDri(tif)==0)
-					return(0);
-				break;
-			case JPEG_MARKER_DQT:
-				if (OJPEGReadHeaderInfoSecStreamDqt(tif)==0)
-					return(0);
-				break;
-			case JPEG_MARKER_DHT:
-				if (OJPEGReadHeaderInfoSecStreamDht(tif)==0)
-					return(0);
-				break;
-			case JPEG_MARKER_SOF0:
-			case JPEG_MARKER_SOF1:
-			case JPEG_MARKER_SOF3:
-				if (OJPEGReadHeaderInfoSecStreamSof(tif,m)==0)
-					return(0);
-				if (sp->subsamplingcorrect!=0)
-					return(1);
-				break;
-			case JPEG_MARKER_SOS:
-				if (sp->subsamplingcorrect!=0)
-					return(1);
-				assert(sp->plane_sample_offset==0);
-				if (OJPEGReadHeaderInfoSecStreamSos(tif)==0)
-					return(0);
-				break;
-			default:
-				TIFFErrorExt(tif->tif_clientdata,module,"Unknown marker type %d in JPEG data",m);
-				return(0);
-		}
-	} while(m!=JPEG_MARKER_SOS);
-	if (sp->subsamplingcorrect)
-		return(1);
-	if (sp->sof_log==0)
-	{
-		if (OJPEGReadHeaderInfoSecTablesQTable(tif)==0)
-			return(0);
-		sp->sof_marker_id=JPEG_MARKER_SOF0;
-		for (o=0; o<sp->samples_per_pixel; o++)
-			sp->sof_c[o]=o;
-		sp->sof_hv[0]=((sp->subsampling_hor<<4)|sp->subsampling_ver);
-		for (o=1; o<sp->samples_per_pixel; o++)
-			sp->sof_hv[o]=17;
-		sp->sof_x=sp->strile_width;
-		sp->sof_y=sp->strile_length_total;
-		sp->sof_log=1;
-		if (OJPEGReadHeaderInfoSecTablesDcTable(tif)==0)
-			return(0);
-		if (OJPEGReadHeaderInfoSecTablesAcTable(tif)==0)
-			return(0);
-		for (o=1; o<sp->samples_per_pixel; o++)
-			sp->sos_cs[o]=o;
-	}
-	return(1);
-}
-
-static int
-OJPEGReadHeaderInfoSecStreamDri(TIFF* tif)
-{
-	/* this could easilly cause trouble in some cases... but no such cases have occured sofar */
-	static const char module[]="OJPEGReadHeaderInfoSecStreamDri";
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	uint16 m;
-	if (OJPEGReadWord(sp,&m)==0)
-		return(0);
-	if (m!=4)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DRI marker in JPEG data");
-		return(0);
-	}
-	if (OJPEGReadWord(sp,&m)==0)
-		return(0);
-	sp->restart_interval=m;
-	return(1);
-}
-
-static int
-OJPEGReadHeaderInfoSecStreamDqt(TIFF* tif)
-{
-	/* this is a table marker, and it is to be saved as a whole for exact pushing on the jpeg stream later on */
-	static const char module[]="OJPEGReadHeaderInfoSecStreamDqt";
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	uint16 m;
-	uint32 na;
-	uint8* nb;
-	uint8 o;
-	if (OJPEGReadWord(sp,&m)==0)
-		return(0);
-	if (m<=2)
-	{
-		if (sp->subsamplingcorrect==0)
-			TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DQT marker in JPEG data");
-		return(0);
-	}
-	if (sp->subsamplingcorrect!=0)
-		OJPEGReadSkip(sp,m-2);
-	else
-	{
-		m-=2;
-		do
-		{
-			if (m<65)
-			{
-				TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DQT marker in JPEG data");
-				return(0);
-			}
-			na=sizeof(uint32)+69;
-			nb=_TIFFmalloc(na);
-			if (nb==0)
-			{
-				TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
-				return(0);
-			}
-			*(uint32*)nb=na;
-			nb[sizeof(uint32)]=255;
-			nb[sizeof(uint32)+1]=JPEG_MARKER_DQT;
-			nb[sizeof(uint32)+2]=0;
-			nb[sizeof(uint32)+3]=67;
-			if (OJPEGReadBlock(sp,65,&nb[sizeof(uint32)+4])==0) {
-				_TIFFfree(nb);
-				return(0);
-			}
-			o=nb[sizeof(uint32)+4]&15;
-			if (3<o)
-			{
-				TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DQT marker in JPEG data");
-				_TIFFfree(nb);
-				return(0);
-			}
-			if (sp->qtable[o]!=0)
-				_TIFFfree(sp->qtable[o]);
-			sp->qtable[o]=nb;
-			m-=65;
-		} while(m>0);
-	}
-	return(1);
-}
-
-static int
-OJPEGReadHeaderInfoSecStreamDht(TIFF* tif)
-{
-	/* this is a table marker, and it is to be saved as a whole for exact pushing on the jpeg stream later on */
-	/* TODO: the following assumes there is only one table in this marker... but i'm not quite sure that assumption is guaranteed correct */
-	static const char module[]="OJPEGReadHeaderInfoSecStreamDht";
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	uint16 m;
-	uint32 na;
-	uint8* nb;
-	uint8 o;
-	if (OJPEGReadWord(sp,&m)==0)
-		return(0);
-	if (m<=2)
-	{
-		if (sp->subsamplingcorrect==0)
-			TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data");
-		return(0);
-	}
-	if (sp->subsamplingcorrect!=0)
-	{
-		OJPEGReadSkip(sp,m-2);
-	}
-	else
-	{
-		na=sizeof(uint32)+2+m;
-		nb=_TIFFmalloc(na);
-		if (nb==0)
-		{
-			TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
-			return(0);
-		}
-		*(uint32*)nb=na;
-		nb[sizeof(uint32)]=255;
-		nb[sizeof(uint32)+1]=JPEG_MARKER_DHT;
-		nb[sizeof(uint32)+2]=(m>>8);
-		nb[sizeof(uint32)+3]=(m&255);
-		if (OJPEGReadBlock(sp,m-2,&nb[sizeof(uint32)+4])==0)
-			return(0);
-		o=nb[sizeof(uint32)+4];
-		if ((o&240)==0)
-		{
-			if (3<o)
-			{
-				TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data");
-				return(0);
-			}
-			if (sp->dctable[o]!=0)
-				_TIFFfree(sp->dctable[o]);
-			sp->dctable[o]=nb;
-		}
-		else
-		{
-			if ((o&240)!=16)
-			{
-				TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data");
-				return(0);
-			}
-			o&=15;
-			if (3<o)
-			{
-				TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data");
-				return(0);
-			}
-			if (sp->actable[o]!=0)
-				_TIFFfree(sp->actable[o]);
-			sp->actable[o]=nb;
-		}
-	}
-	return(1);
-}
-
-static int
-OJPEGReadHeaderInfoSecStreamSof(TIFF* tif, uint8 marker_id)
-{
-	/* this marker needs to be checked, and part of its data needs to be saved for regeneration later on */
-	static const char module[]="OJPEGReadHeaderInfoSecStreamSof";
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	uint16 m;
-	uint16 n;
-	uint8 o;
-	uint16 p;
-	uint16 q;
-	if (sp->sof_log!=0)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JPEG data");
-		return(0);
-	}
-	if (sp->subsamplingcorrect==0)
-		sp->sof_marker_id=marker_id;
-	/* Lf: data length */
-	if (OJPEGReadWord(sp,&m)==0)
-		return(0);
-	if (m<11)
-	{
-		if (sp->subsamplingcorrect==0)
-			TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOF marker in JPEG data");
-		return(0);
-	}
-	m-=8;
-	if (m%3!=0)
-	{
-		if (sp->subsamplingcorrect==0)
-			TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOF marker in JPEG data");
-		return(0);
-	}
-	n=m/3;
-	if (sp->subsamplingcorrect==0)
-	{
-		if (n!=sp->samples_per_pixel)
-		{
-			TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected number of samples");
-			return(0);
-		}
-	}
-	/* P: Sample precision */
-	if (OJPEGReadByte(sp,&o)==0)
-		return(0);
-	if (o!=8)
-	{
-		if (sp->subsamplingcorrect==0)
-			TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected number of bits per sample");
-		return(0);
-	}
-	/* Y: Number of lines, X: Number of samples per line */
-	if (sp->subsamplingcorrect)
-		OJPEGReadSkip(sp,4);
-	else
-	{
-		/* Y: Number of lines */
-		if (OJPEGReadWord(sp,&p)==0)
-			return(0);
-		if (((uint32)p<sp->image_length) && ((uint32)p<sp->strile_length_total))
-		{
-			TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected height");
-			return(0);
-		}
-		sp->sof_y=p;
-		/* X: Number of samples per line */
-		if (OJPEGReadWord(sp,&p)==0)
-			return(0);
-		if (((uint32)p<sp->image_width) && ((uint32)p<sp->strile_width))
-		{
-			TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected width");
-			return(0);
-		}
-		if ((uint32)p>sp->strile_width)
-		{
-			TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data image width exceeds expected image width");
-			return(0);
-		}
-		sp->sof_x=p;
-	}
-	/* Nf: Number of image components in frame */
-	if (OJPEGReadByte(sp,&o)==0)
-		return(0);
-	if (o!=n)
-	{
-		if (sp->subsamplingcorrect==0)
-			TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOF marker in JPEG data");
-		return(0);
-	}
-	/* per component stuff */
-	/* TODO: double-check that flow implies that n cannot be as big as to make us overflow sof_c, sof_hv and sof_tq arrays */
-	for (q=0; q<n; q++)
-	{
-		/* C: Component identifier */
-		if (OJPEGReadByte(sp,&o)==0)
-			return(0);
-		if (sp->subsamplingcorrect==0)
-			sp->sof_c[q]=o;
-		/* H: Horizontal sampling factor, and V: Vertical sampling factor */
-		if (OJPEGReadByte(sp,&o)==0)
-			return(0);
-		if (sp->subsamplingcorrect!=0)
-		{
-			if (q==0)
-			{
-				sp->subsampling_hor=(o>>4);
-				sp->subsampling_ver=(o&15);
-				if (((sp->subsampling_hor!=1) && (sp->subsampling_hor!=2) && (sp->subsampling_hor!=4)) ||
-					((sp->subsampling_ver!=1) && (sp->subsampling_ver!=2) && (sp->subsampling_ver!=4)))
-					sp->subsampling_force_desubsampling_inside_decompression=1;
-			}
-			else
-			{
-				if (o!=17)
-					sp->subsampling_force_desubsampling_inside_decompression=1;
-			}
-		}
-		else
-		{
-			sp->sof_hv[q]=o;
-			if (sp->subsampling_force_desubsampling_inside_decompression==0)
-			{
-				if (q==0)
-				{
-					if (o!=((sp->subsampling_hor<<4)|sp->subsampling_ver))
-					{
-						TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected subsampling values");
-						return(0);
-					}
-				}
-				else
-				{
-					if (o!=17)
-					{
-						TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected subsampling values");
-						return(0);
-					}
-				}
-			}
-		}
-		/* Tq: Quantization table destination selector */
-		if (OJPEGReadByte(sp,&o)==0)
-			return(0);
-		if (sp->subsamplingcorrect==0)
-			sp->sof_tq[q]=o;
-	}
-	if (sp->subsamplingcorrect==0)
-		sp->sof_log=1;
-	return(1);
-}
-
-static int
-OJPEGReadHeaderInfoSecStreamSos(TIFF* tif)
-{
-	/* this marker needs to be checked, and part of its data needs to be saved for regeneration later on */
-	static const char module[]="OJPEGReadHeaderInfoSecStreamSos";
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	uint16 m;
-	uint8 n;
-	uint8 o;
-	assert(sp->subsamplingcorrect==0);
-	if (sp->sof_log==0)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOS marker in JPEG data");
-		return(0);
-	}
-	/* Ls */
-	if (OJPEGReadWord(sp,&m)==0)
-		return(0);
-	if (m!=6+sp->samples_per_pixel_per_plane*2)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOS marker in JPEG data");
-		return(0);
-	}
-	/* Ns */
-	if (OJPEGReadByte(sp,&n)==0)
-		return(0);
-	if (n!=sp->samples_per_pixel_per_plane)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOS marker in JPEG data");
-		return(0);
-	}
-	/* Cs, Td, and Ta */
-	for (o=0; o<sp->samples_per_pixel_per_plane; o++)
-	{
-		/* Cs */
-		if (OJPEGReadByte(sp,&n)==0)
-			return(0);
-		sp->sos_cs[sp->plane_sample_offset+o]=n;
-		/* Td and Ta */
-		if (OJPEGReadByte(sp,&n)==0)
-			return(0);
-		sp->sos_tda[sp->plane_sample_offset+o]=n;
-	}
-	/* skip Ss, Se, Ah, en Al -> no check, as per Tom Lane recommendation, as per LibJpeg source */
-	OJPEGReadSkip(sp,3);
-	return(1);
-}
-
-static int
-OJPEGReadHeaderInfoSecTablesQTable(TIFF* tif)
-{
-	static const char module[]="OJPEGReadHeaderInfoSecTablesQTable";
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	uint8 m;
-	uint8 n;
-	uint32 oa;
-	uint8* ob;
-	uint32 p;
-	if (sp->qtable_offset[0]==0)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Missing JPEG tables");
-		return(0);
-	}
-	sp->in_buffer_file_pos_log=0;
-	for (m=0; m<sp->samples_per_pixel; m++)
-	{
-		if ((sp->qtable_offset[m]!=0) && ((m==0) || (sp->qtable_offset[m]!=sp->qtable_offset[m-1])))
-		{
-			for (n=0; n<m-1; n++)
-			{
-				if (sp->qtable_offset[m]==sp->qtable_offset[n])
-				{
-					TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JpegQTables tag value");
-					return(0);
-				}
-			}
-			oa=sizeof(uint32)+69;
-			ob=_TIFFmalloc(oa);
-			if (ob==0)
-			{
-				TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
-				return(0);
-			}
-			*(uint32*)ob=oa;
-			ob[sizeof(uint32)]=255;
-			ob[sizeof(uint32)+1]=JPEG_MARKER_DQT;
-			ob[sizeof(uint32)+2]=0;
-			ob[sizeof(uint32)+3]=67;
-			ob[sizeof(uint32)+4]=m;
-			TIFFSeekFile(tif,sp->qtable_offset[m],SEEK_SET); 
-			p=TIFFReadFile(tif,&ob[sizeof(uint32)+5],64);
-			if (p!=64)
-				return(0);
-			sp->qtable[m]=ob;
-			sp->sof_tq[m]=m;
-		}
-		else
-			sp->sof_tq[m]=sp->sof_tq[m-1];
-	}
-	return(1);
-}
-
-static int
-OJPEGReadHeaderInfoSecTablesDcTable(TIFF* tif)
-{
-	static const char module[]="OJPEGReadHeaderInfoSecTablesDcTable";
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	uint8 m;
-	uint8 n;
-	uint8 o[16];
-	uint32 p;
-	uint32 q;
-	uint32 ra;
-	uint8* rb;
-	if (sp->dctable_offset[0]==0)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Missing JPEG tables");
-		return(0);
-	}
-	sp->in_buffer_file_pos_log=0;
-	for (m=0; m<sp->samples_per_pixel; m++)
-	{
-		if ((sp->dctable_offset[m]!=0) && ((m==0) || (sp->dctable_offset[m]!=sp->dctable_offset[m-1])))
-		{
-			for (n=0; n<m-1; n++)
-			{
-				if (sp->dctable_offset[m]==sp->dctable_offset[n])
-				{
-					TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JpegDcTables tag value");
-					return(0);
-				}
-			}
-			TIFFSeekFile(tif,sp->dctable_offset[m],SEEK_SET);
-			p=TIFFReadFile(tif,o,16);
-			if (p!=16)
-				return(0);
-			q=0;
-			for (n=0; n<16; n++)
-				q+=o[n];
-			ra=sizeof(uint32)+21+q;
-			rb=_TIFFmalloc(ra);
-			if (rb==0)
-			{
-				TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
-				return(0);
-			}
-			*(uint32*)rb=ra;
-			rb[sizeof(uint32)]=255;
-			rb[sizeof(uint32)+1]=JPEG_MARKER_DHT;
-			rb[sizeof(uint32)+2]=((19+q)>>8);
-			rb[sizeof(uint32)+3]=((19+q)&255);
-			rb[sizeof(uint32)+4]=m;
-			for (n=0; n<16; n++)
-				rb[sizeof(uint32)+5+n]=o[n];
-			p=TIFFReadFile(tif,&(rb[sizeof(uint32)+21]),q);
-			if (p!=q)
-				return(0);
-			sp->dctable[m]=rb;
-			sp->sos_tda[m]=(m<<4);
-		}
-		else
-			sp->sos_tda[m]=sp->sos_tda[m-1];
-	}
-	return(1);
-}
-
-static int
-OJPEGReadHeaderInfoSecTablesAcTable(TIFF* tif)
-{
-	static const char module[]="OJPEGReadHeaderInfoSecTablesAcTable";
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	uint8 m;
-	uint8 n;
-	uint8 o[16];
-	uint32 p;
-	uint32 q;
-	uint32 ra;
-	uint8* rb;
-	if (sp->actable_offset[0]==0)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Missing JPEG tables");
-		return(0);
-	}
-	sp->in_buffer_file_pos_log=0;
-	for (m=0; m<sp->samples_per_pixel; m++)
-	{
-		if ((sp->actable_offset[m]!=0) && ((m==0) || (sp->actable_offset[m]!=sp->actable_offset[m-1])))
-		{
-			for (n=0; n<m-1; n++)
-			{
-				if (sp->actable_offset[m]==sp->actable_offset[n])
-				{
-					TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JpegAcTables tag value");
-					return(0);
-				}
-			}
-			TIFFSeekFile(tif,sp->actable_offset[m],SEEK_SET);  
-			p=TIFFReadFile(tif,o,16);
-			if (p!=16)
-				return(0);
-			q=0;
-			for (n=0; n<16; n++)
-				q+=o[n];
-			ra=sizeof(uint32)+21+q;
-			rb=_TIFFmalloc(ra);
-			if (rb==0)
-			{
-				TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
-				return(0);
-			}
-			*(uint32*)rb=ra;
-			rb[sizeof(uint32)]=255;
-			rb[sizeof(uint32)+1]=JPEG_MARKER_DHT;
-			rb[sizeof(uint32)+2]=((19+q)>>8);
-			rb[sizeof(uint32)+3]=((19+q)&255);
-			rb[sizeof(uint32)+4]=(16|m);
-			for (n=0; n<16; n++)
-				rb[sizeof(uint32)+5+n]=o[n];
-			p=TIFFReadFile(tif,&(rb[sizeof(uint32)+21]),q);
-			if (p!=q)
-				return(0);
-			sp->actable[m]=rb;
-			sp->sos_tda[m]=(sp->sos_tda[m]|m);
-		}
-		else
-			sp->sos_tda[m]=(sp->sos_tda[m]|(sp->sos_tda[m-1]&15));
-	}
-	return(1);
-}
-
-static int
-OJPEGReadBufferFill(OJPEGState* sp)
-{
-	uint16 m;
-	tmsize_t n;
-	/* TODO: double-check: when subsamplingcorrect is set, no call to TIFFErrorExt or TIFFWarningExt should be made
-	 * in any other case, seek or read errors should be passed through */
-	do
-	{
-		if (sp->in_buffer_file_togo!=0)
-		{
-			if (sp->in_buffer_file_pos_log==0)
-			{
-				TIFFSeekFile(sp->tif,sp->in_buffer_file_pos,SEEK_SET);
-				sp->in_buffer_file_pos_log=1;
-			}
-			m=OJPEG_BUFFER;
-			if ((uint64)m>sp->in_buffer_file_togo)
-				m=(uint16)sp->in_buffer_file_togo;
-			n=TIFFReadFile(sp->tif,sp->in_buffer,(tmsize_t)m);
-			if (n==0)
-				return(0);
-			assert(n>0);
-			assert(n<=OJPEG_BUFFER);
-			assert(n<65536);
-			assert((uint64)n<=sp->in_buffer_file_togo);
-			m=(uint16)n;
-			sp->in_buffer_togo=m;
-			sp->in_buffer_cur=sp->in_buffer;
-			sp->in_buffer_file_togo-=m;
-			sp->in_buffer_file_pos+=m;
-			break;
-		}
-		sp->in_buffer_file_pos_log=0;
-		switch(sp->in_buffer_source)
-		{
-			case osibsNotSetYet:
-				if (sp->jpeg_interchange_format!=0)
-				{
-					sp->in_buffer_file_pos=sp->jpeg_interchange_format;
-					sp->in_buffer_file_togo=sp->jpeg_interchange_format_length;
-				}
-				sp->in_buffer_source=osibsJpegInterchangeFormat;
-				break;
-			case osibsJpegInterchangeFormat:
-				sp->in_buffer_source=osibsStrile;
-			case osibsStrile:
-				if (!_TIFFFillStriles( sp->tif ) 
-				    || sp->tif->tif_dir.td_stripoffset == NULL
-				    || sp->tif->tif_dir.td_stripbytecount == NULL)
-					return 0;
-
-				if (sp->in_buffer_next_strile==sp->in_buffer_strile_count)
-					sp->in_buffer_source=osibsEof;
-				else
-				{
-					sp->in_buffer_file_pos=sp->tif->tif_dir.td_stripoffset[sp->in_buffer_next_strile];
-					if (sp->in_buffer_file_pos!=0)
-					{
-						if (sp->in_buffer_file_pos>=sp->file_size)
-							sp->in_buffer_file_pos=0;
-						else if (sp->tif->tif_dir.td_stripbytecount==NULL)
-							sp->in_buffer_file_togo=sp->file_size-sp->in_buffer_file_pos;
-						else
-						{
-							if (sp->tif->tif_dir.td_stripbytecount == 0) {
-								TIFFErrorExt(sp->tif->tif_clientdata,sp->tif->tif_name,"Strip byte counts are missing");
-								return(0);
-							}
-							sp->in_buffer_file_togo=sp->tif->tif_dir.td_stripbytecount[sp->in_buffer_next_strile];
-							if (sp->in_buffer_file_togo==0)
-								sp->in_buffer_file_pos=0;
-							else if (sp->in_buffer_file_pos+sp->in_buffer_file_togo>sp->file_size)
-								sp->in_buffer_file_togo=sp->file_size-sp->in_buffer_file_pos;
-						}
-					}
-					sp->in_buffer_next_strile++;
-				}
-				break;
-			default:
-				return(0);
-		}
-	} while (1);
-	return(1);
-}
-
-static int
-OJPEGReadByte(OJPEGState* sp, uint8* byte)
-{
-	if (sp->in_buffer_togo==0)
-	{
-		if (OJPEGReadBufferFill(sp)==0)
-			return(0);
-		assert(sp->in_buffer_togo>0);
-	}
-	*byte=*(sp->in_buffer_cur);
-	sp->in_buffer_cur++;
-	sp->in_buffer_togo--;
-	return(1);
-}
-
-static int
-OJPEGReadBytePeek(OJPEGState* sp, uint8* byte)
-{
-	if (sp->in_buffer_togo==0)
-	{
-		if (OJPEGReadBufferFill(sp)==0)
-			return(0);
-		assert(sp->in_buffer_togo>0);
-	}
-	*byte=*(sp->in_buffer_cur);
-	return(1);
-}
-
-static void
-OJPEGReadByteAdvance(OJPEGState* sp)
-{
-	assert(sp->in_buffer_togo>0);
-	sp->in_buffer_cur++;
-	sp->in_buffer_togo--;
-}
-
-static int
-OJPEGReadWord(OJPEGState* sp, uint16* word)
-{
-	uint8 m;
-	if (OJPEGReadByte(sp,&m)==0)
-		return(0);
-	*word=(m<<8);
-	if (OJPEGReadByte(sp,&m)==0)
-		return(0);
-	*word|=m;
-	return(1);
-}
-
-static int
-OJPEGReadBlock(OJPEGState* sp, uint16 len, void* mem)
-{
-	uint16 mlen;
-	uint8* mmem;
-	uint16 n;
-	assert(len>0);
-	mlen=len;
-	mmem=mem;
-	do
-	{
-		if (sp->in_buffer_togo==0)
-		{
-			if (OJPEGReadBufferFill(sp)==0)
-				return(0);
-			assert(sp->in_buffer_togo>0);
-		}
-		n=mlen;
-		if (n>sp->in_buffer_togo)
-			n=sp->in_buffer_togo;
-		_TIFFmemcpy(mmem,sp->in_buffer_cur,n);
-		sp->in_buffer_cur+=n;
-		sp->in_buffer_togo-=n;
-		mlen-=n;
-		mmem+=n;
-	} while(mlen>0);
-	return(1);
-}
-
-static void
-OJPEGReadSkip(OJPEGState* sp, uint16 len)
-{
-	uint16 m;
-	uint16 n;
-	m=len;
-	n=m;
-	if (n>sp->in_buffer_togo)
-		n=sp->in_buffer_togo;
-	sp->in_buffer_cur+=n;
-	sp->in_buffer_togo-=n;
-	m-=n;
-	if (m>0)
-	{
-		assert(sp->in_buffer_togo==0);
-		n=m;
-		if ((uint64)n>sp->in_buffer_file_togo)
-			n=(uint16)sp->in_buffer_file_togo;
-		sp->in_buffer_file_pos+=n;
-		sp->in_buffer_file_togo-=n;
-		sp->in_buffer_file_pos_log=0;
-		/* we don't skip past jpeginterchangeformat/strile block...
-		 * if that is asked from us, we're dealing with totally bazurk
-		 * data anyway, and we've not seen this happening on any
-		 * testfile, so we might as well likely cause some other
-		 * meaningless error to be passed at some later time
-		 */
-	}
-}
-
-static int
-OJPEGWriteStream(TIFF* tif, void** mem, uint32* len)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	*len=0;
-	do
-	{
-		assert(sp->out_state<=ososEoi);
-		switch(sp->out_state)
-		{
-			case ososSoi:
-				OJPEGWriteStreamSoi(tif,mem,len);
-				break;
-			case ososQTable0:
-				OJPEGWriteStreamQTable(tif,0,mem,len);
-				break;
-			case ososQTable1:
-				OJPEGWriteStreamQTable(tif,1,mem,len);
-				break;
-			case ososQTable2:
-				OJPEGWriteStreamQTable(tif,2,mem,len);
-				break;
-			case ososQTable3:
-				OJPEGWriteStreamQTable(tif,3,mem,len);
-				break;
-			case ososDcTable0:
-				OJPEGWriteStreamDcTable(tif,0,mem,len);
-				break;
-			case ososDcTable1:
-				OJPEGWriteStreamDcTable(tif,1,mem,len);
-				break;
-			case ososDcTable2:
-				OJPEGWriteStreamDcTable(tif,2,mem,len);
-				break;
-			case ososDcTable3:
-				OJPEGWriteStreamDcTable(tif,3,mem,len);
-				break;
-			case ososAcTable0:
-				OJPEGWriteStreamAcTable(tif,0,mem,len);
-				break;
-			case ososAcTable1:
-				OJPEGWriteStreamAcTable(tif,1,mem,len);
-				break;
-			case ososAcTable2:
-				OJPEGWriteStreamAcTable(tif,2,mem,len);
-				break;
-			case ososAcTable3:
-				OJPEGWriteStreamAcTable(tif,3,mem,len);
-				break;
-			case ososDri:
-				OJPEGWriteStreamDri(tif,mem,len);
-				break;
-			case ososSof:
-				OJPEGWriteStreamSof(tif,mem,len);
-				break;
-			case ososSos:
-				OJPEGWriteStreamSos(tif,mem,len);
-				break;
-			case ososCompressed:
-				if (OJPEGWriteStreamCompressed(tif,mem,len)==0)
-					return(0);
-				break;
-			case ososRst:
-				OJPEGWriteStreamRst(tif,mem,len);
-				break;
-			case ososEoi:
-				OJPEGWriteStreamEoi(tif,mem,len);
-				break;
-		}
-	} while (*len==0);
-	return(1);
-}
-
-static void
-OJPEGWriteStreamSoi(TIFF* tif, void** mem, uint32* len)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	assert(OJPEG_BUFFER>=2);
-	sp->out_buffer[0]=255;
-	sp->out_buffer[1]=JPEG_MARKER_SOI;
-	*len=2;
-	*mem=(void*)sp->out_buffer;
-	sp->out_state++;
-}
-
-static void
-OJPEGWriteStreamQTable(TIFF* tif, uint8 table_index, void** mem, uint32* len)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	if (sp->qtable[table_index]!=0)
-	{
-		*mem=(void*)(sp->qtable[table_index]+sizeof(uint32));
-		*len=*((uint32*)sp->qtable[table_index])-sizeof(uint32);
-	}
-	sp->out_state++;
-}
-
-static void
-OJPEGWriteStreamDcTable(TIFF* tif, uint8 table_index, void** mem, uint32* len)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	if (sp->dctable[table_index]!=0)
-	{
-		*mem=(void*)(sp->dctable[table_index]+sizeof(uint32));
-		*len=*((uint32*)sp->dctable[table_index])-sizeof(uint32);
-	}
-	sp->out_state++;
-}
-
-static void
-OJPEGWriteStreamAcTable(TIFF* tif, uint8 table_index, void** mem, uint32* len)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	if (sp->actable[table_index]!=0)
-	{
-		*mem=(void*)(sp->actable[table_index]+sizeof(uint32));
-		*len=*((uint32*)sp->actable[table_index])-sizeof(uint32);
-	}
-	sp->out_state++;
-}
-
-static void
-OJPEGWriteStreamDri(TIFF* tif, void** mem, uint32* len)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	assert(OJPEG_BUFFER>=6);
-	if (sp->restart_interval!=0)
-	{
-		sp->out_buffer[0]=255;
-		sp->out_buffer[1]=JPEG_MARKER_DRI;
-		sp->out_buffer[2]=0;
-		sp->out_buffer[3]=4;
-		sp->out_buffer[4]=(sp->restart_interval>>8);
-		sp->out_buffer[5]=(sp->restart_interval&255);
-		*len=6;
-		*mem=(void*)sp->out_buffer;
-	}
-	sp->out_state++;
-}
-
-static void
-OJPEGWriteStreamSof(TIFF* tif, void** mem, uint32* len)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	uint8 m;
-	assert(OJPEG_BUFFER>=2+8+sp->samples_per_pixel_per_plane*3);
-	assert(255>=8+sp->samples_per_pixel_per_plane*3);
-	sp->out_buffer[0]=255;
-	sp->out_buffer[1]=sp->sof_marker_id;
-	/* Lf */
-	sp->out_buffer[2]=0;
-	sp->out_buffer[3]=8+sp->samples_per_pixel_per_plane*3;
-	/* P */
-	sp->out_buffer[4]=8;
-	/* Y */
-	sp->out_buffer[5]=(sp->sof_y>>8);
-	sp->out_buffer[6]=(sp->sof_y&255);
-	/* X */
-	sp->out_buffer[7]=(sp->sof_x>>8);
-	sp->out_buffer[8]=(sp->sof_x&255);
-	/* Nf */
-	sp->out_buffer[9]=sp->samples_per_pixel_per_plane;
-	for (m=0; m<sp->samples_per_pixel_per_plane; m++)
-	{
-		/* C */
-		sp->out_buffer[10+m*3]=sp->sof_c[sp->plane_sample_offset+m];
-		/* H and V */
-		sp->out_buffer[10+m*3+1]=sp->sof_hv[sp->plane_sample_offset+m];
-		/* Tq */
-		sp->out_buffer[10+m*3+2]=sp->sof_tq[sp->plane_sample_offset+m];
-	}
-	*len=10+sp->samples_per_pixel_per_plane*3;
-	*mem=(void*)sp->out_buffer;
-	sp->out_state++;
-}
-
-static void
-OJPEGWriteStreamSos(TIFF* tif, void** mem, uint32* len)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	uint8 m;
-	assert(OJPEG_BUFFER>=2+6+sp->samples_per_pixel_per_plane*2);
-	assert(255>=6+sp->samples_per_pixel_per_plane*2);
-	sp->out_buffer[0]=255;
-	sp->out_buffer[1]=JPEG_MARKER_SOS;
-	/* Ls */
-	sp->out_buffer[2]=0;
-	sp->out_buffer[3]=6+sp->samples_per_pixel_per_plane*2;
-	/* Ns */
-	sp->out_buffer[4]=sp->samples_per_pixel_per_plane;
-	for (m=0; m<sp->samples_per_pixel_per_plane; m++)
-	{
-		/* Cs */
-		sp->out_buffer[5+m*2]=sp->sos_cs[sp->plane_sample_offset+m];
-		/* Td and Ta */
-		sp->out_buffer[5+m*2+1]=sp->sos_tda[sp->plane_sample_offset+m];
-	}
-	/* Ss */
-	sp->out_buffer[5+sp->samples_per_pixel_per_plane*2]=0;
-	/* Se */
-	sp->out_buffer[5+sp->samples_per_pixel_per_plane*2+1]=63;
-	/* Ah and Al */
-	sp->out_buffer[5+sp->samples_per_pixel_per_plane*2+2]=0;
-	*len=8+sp->samples_per_pixel_per_plane*2;
-	*mem=(void*)sp->out_buffer;
-	sp->out_state++;
-}
-
-static int
-OJPEGWriteStreamCompressed(TIFF* tif, void** mem, uint32* len)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	if (sp->in_buffer_togo==0)
-	{
-		if (OJPEGReadBufferFill(sp)==0)
-			return(0);
-		assert(sp->in_buffer_togo>0);
-	}
-	*len=sp->in_buffer_togo;
-	*mem=(void*)sp->in_buffer_cur;
-	sp->in_buffer_togo=0;
-	if (sp->in_buffer_file_togo==0)
-	{
-		switch(sp->in_buffer_source)
-		{
-			case osibsStrile:
-				if (sp->in_buffer_next_strile<sp->in_buffer_strile_count)
-					sp->out_state=ososRst;
-				else
-					sp->out_state=ososEoi;
-				break;
-			case osibsEof:
-				sp->out_state=ososEoi;
-				break;
-			default:
-				break;
-		}
-	}
-	return(1);
-}
-
-static void
-OJPEGWriteStreamRst(TIFF* tif, void** mem, uint32* len)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	assert(OJPEG_BUFFER>=2);
-	sp->out_buffer[0]=255;
-	sp->out_buffer[1]=JPEG_MARKER_RST0+sp->restart_index;
-	sp->restart_index++;
-	if (sp->restart_index==8)
-		sp->restart_index=0;
-	*len=2;
-	*mem=(void*)sp->out_buffer;
-	sp->out_state=ososCompressed;
-}
-
-static void
-OJPEGWriteStreamEoi(TIFF* tif, void** mem, uint32* len)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	assert(OJPEG_BUFFER>=2);
-	sp->out_buffer[0]=255;
-	sp->out_buffer[1]=JPEG_MARKER_EOI;
-	*len=2;
-	*mem=(void*)sp->out_buffer;
-}
-
-#ifndef LIBJPEG_ENCAP_EXTERNAL
-static int
-jpeg_create_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo)
-{
-	return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_create_decompress(cinfo),1));
-}
-#endif
-
-#ifndef LIBJPEG_ENCAP_EXTERNAL
-static int
-jpeg_read_header_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, uint8 require_image)
-{
-	return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_read_header(cinfo,require_image),1));
-}
-#endif
-
-#ifndef LIBJPEG_ENCAP_EXTERNAL
-static int
-jpeg_start_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo)
-{
-	return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_start_decompress(cinfo),1));
-}
-#endif
-
-#ifndef LIBJPEG_ENCAP_EXTERNAL
-static int
-jpeg_read_scanlines_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* scanlines, uint32 max_lines)
-{
-	return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_read_scanlines(cinfo,scanlines,max_lines),1));
-}
-#endif
-
-#ifndef LIBJPEG_ENCAP_EXTERNAL
-static int
-jpeg_read_raw_data_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* data, uint32 max_lines)
-{
-	return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_read_raw_data(cinfo,data,max_lines),1));
-}
-#endif
-
-#ifndef LIBJPEG_ENCAP_EXTERNAL
-static void
-jpeg_encap_unwind(TIFF* tif)
-{
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	LONGJMP(sp->exit_jmpbuf,1);
-}
-#endif
-
-static void
-OJPEGLibjpegJpegErrorMgrOutputMessage(jpeg_common_struct* cinfo)
-{
-	char buffer[JMSG_LENGTH_MAX];
-	(*cinfo->err->format_message)(cinfo,buffer);
-	TIFFWarningExt(((TIFF*)(cinfo->client_data))->tif_clientdata,"LibJpeg","%s",buffer);
-}
-
-static void
-OJPEGLibjpegJpegErrorMgrErrorExit(jpeg_common_struct* cinfo)
-{
-	char buffer[JMSG_LENGTH_MAX];
-	(*cinfo->err->format_message)(cinfo,buffer);
-	TIFFErrorExt(((TIFF*)(cinfo->client_data))->tif_clientdata,"LibJpeg","%s",buffer);
-	jpeg_encap_unwind((TIFF*)(cinfo->client_data));
-}
-
-static void
-OJPEGLibjpegJpegSourceMgrInitSource(jpeg_decompress_struct* cinfo)
-{
-	(void)cinfo;
-}
-
-static boolean
-OJPEGLibjpegJpegSourceMgrFillInputBuffer(jpeg_decompress_struct* cinfo)
-{
-	TIFF* tif=(TIFF*)cinfo->client_data;
-	OJPEGState* sp=(OJPEGState*)tif->tif_data;
-	void* mem=0;
-	uint32 len=0U;
-	if (OJPEGWriteStream(tif,&mem,&len)==0)
-	{
-		TIFFErrorExt(tif->tif_clientdata,"LibJpeg","Premature end of JPEG data");
-		jpeg_encap_unwind(tif);
-	}
-	sp->libjpeg_jpeg_source_mgr.bytes_in_buffer=len;
-	sp->libjpeg_jpeg_source_mgr.next_input_byte=mem;
-	return(1);
-}
-
-static void
-OJPEGLibjpegJpegSourceMgrSkipInputData(jpeg_decompress_struct* cinfo, long num_bytes)
-{
-	TIFF* tif=(TIFF*)cinfo->client_data;
-	(void)num_bytes;
-	TIFFErrorExt(tif->tif_clientdata,"LibJpeg","Unexpected error");
-	jpeg_encap_unwind(tif);
-}
-
-static boolean
-OJPEGLibjpegJpegSourceMgrResyncToRestart(jpeg_decompress_struct* cinfo, int desired)
-{
-	TIFF* tif=(TIFF*)cinfo->client_data;
-	(void)desired;
-	TIFFErrorExt(tif->tif_clientdata,"LibJpeg","Unexpected error");
-	jpeg_encap_unwind(tif);
-	return(0);
-}
-
-static void
-OJPEGLibjpegJpegSourceMgrTermSource(jpeg_decompress_struct* cinfo)
-{
-	(void)cinfo;
-}
-
-#endif
-
-
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Id: tif_ojpeg.c,v 1.11 2015/02/19 22:39:58 drolon Exp $ */
+
+/* WARNING: The type of JPEG encapsulation defined by the TIFF Version 6.0
+   specification is now totally obsolete and deprecated for new applications and
+   images. This file was was created solely in order to read unconverted images
+   still present on some users' computer systems. It will never be extended
+   to write such files. Writing new-style JPEG compressed TIFFs is implemented
+   in tif_jpeg.c.
+
+   The code is carefully crafted to robustly read all gathered JPEG-in-TIFF
+   testfiles, and anticipate as much as possible all other... But still, it may
+   fail on some. If you encounter problems, please report them on the TIFF
+   mailing list and/or to Joris Van Damme <info at awaresystems.be>.
+
+   Please read the file called "TIFF Technical Note #2" if you need to be
+   convinced this compression scheme is bad and breaks TIFF. That document
+   is linked to from the LibTiff site <http://www.remotesensing.org/libtiff/>
+   and from AWare Systems' TIFF section
+   <http://www.awaresystems.be/imaging/tiff.html>. It is also absorbed
+   in Adobe's specification supplements, marked "draft" up to this day, but
+   supported by the TIFF community.
+
+   This file interfaces with Release 6B of the JPEG Library written by the
+   Independent JPEG Group. Previous versions of this file required a hack inside
+   the LibJpeg library. This version no longer requires that. Remember to
+   remove the hack if you update from the old version.
+
+   Copyright (c) Joris Van Damme <info at awaresystems.be>
+   Copyright (c) AWare Systems <http://www.awaresystems.be/>
+
+   The licence agreement for this file is the same as the rest of the LibTiff
+   library.
+
+   IN NO EVENT SHALL JORIS VAN DAMME OR AWARE SYSTEMS BE LIABLE FOR
+   ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+   OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+   WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+   LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+   OF THIS SOFTWARE.
+
+   Joris Van Damme and/or AWare Systems may be available for custom
+   development. If you like what you see, and need anything similar or related,
+   contact <info at awaresystems.be>.
+*/
+
+/* What is what, and what is not?
+
+   This decoder starts with an input stream, that is essentially the JpegInterchangeFormat
+   stream, if any, followed by the strile data, if any. This stream is read in
+   OJPEGReadByte and related functions.
+
+   It analyzes the start of this stream, until it encounters non-marker data, i.e.
+   compressed image data. Some of the header markers it sees have no actual content,
+   like the SOI marker, and APP/COM markers that really shouldn't even be there. Some
+   other markers do have content, and the valuable bits and pieces of information
+   in these markers are saved, checking all to verify that the stream is more or
+   less within expected bounds. This happens inside the OJPEGReadHeaderInfoSecStreamXxx
+   functions.
+
+   Some OJPEG imagery contains no valid JPEG header markers. This situation is picked
+   up on if we've seen no SOF marker when we're at the start of the compressed image
+   data. In this case, the tables are read from JpegXxxTables tags, and the other
+   bits and pieces of information is initialized to its most basic value. This is
+   implemented in the OJPEGReadHeaderInfoSecTablesXxx functions.
+
+   When this is complete, a good and valid JPEG header can be assembled, and this is
+   passed through to LibJpeg. When that's done, the remainder of the input stream, i.e.
+   the compressed image data, can be passed through unchanged. This is done in
+   OJPEGWriteStream functions.
+
+   LibTiff rightly expects to know the subsampling values before decompression. Just like
+   in new-style JPEG-in-TIFF, though, or even more so, actually, the YCbCrsubsampling
+   tag is notoriously unreliable. To correct these tag values with the ones inside
+   the JPEG stream, the first part of the input stream is pre-scanned in
+   OJPEGSubsamplingCorrect, making no note of any other data, reporting no warnings
+   or errors, up to the point where either these values are read, or it's clear they
+   aren't there. This means that some of the data is read twice, but we feel speed
+   in correcting these values is important enough to warrant this sacrifice. Allthough
+   there is currently no define or other configuration mechanism to disable this behaviour,
+   the actual header scanning is build to robustly respond with error report if it
+   should encounter an uncorrected mismatch of subsampling values. See
+   OJPEGReadHeaderInfoSecStreamSof.
+
+   The restart interval and restart markers are the most tricky part... The restart
+   interval can be specified in a tag. It can also be set inside the input JPEG stream.
+   It can be used inside the input JPEG stream. If reading from strile data, we've
+   consistenly discovered the need to insert restart markers in between the different
+   striles, as is also probably the most likely interpretation of the original TIFF 6.0
+   specification. With all this setting of interval, and actual use of markers that is not
+   predictable at the time of valid JPEG header assembly, the restart thing may turn
+   out the Achilles heel of this implementation. Fortunately, most OJPEG writer vendors
+   succeed in reading back what they write, which may be the reason why we've been able
+   to discover ways that seem to work.
+
+   Some special provision is made for planarconfig separate OJPEG files. These seem
+   to consistently contain header info, a SOS marker, a plane, SOS marker, plane, SOS,
+   and plane. This may or may not be a valid JPEG configuration, we don't know and don't
+   care. We want LibTiff to be able to access the planes individually, without huge
+   buffering inside LibJpeg, anyway. So we compose headers to feed to LibJpeg, in this
+   case, that allow us to pass a single plane such that LibJpeg sees a valid
+   single-channel JPEG stream. Locating subsequent SOS markers, and thus subsequent
+   planes, is done inside OJPEGReadSecondarySos.
+
+   The benefit of the scheme is... that it works, basically. We know of no other that
+   does. It works without checking software tag, or otherwise going about things in an
+   OJPEG flavor specific manner. Instead, it is a single scheme, that covers the cases
+   with and without JpegInterchangeFormat, with and without striles, with part of
+   the header in JpegInterchangeFormat and remainder in first strile, etc. It is forgiving
+   and robust, may likely work with OJPEG flavors we've not seen yet, and makes most out
+   of the data.
+
+   Another nice side-effect is that a complete JPEG single valid stream is build if
+   planarconfig is not separate (vast majority). We may one day use that to build
+   converters to JPEG, and/or to new-style JPEG compression inside TIFF.
+
+   A dissadvantage is the lack of random access to the individual striles. This is the
+   reason for much of the complicated restart-and-position stuff inside OJPEGPreDecode.
+   Applications would do well accessing all striles in order, as this will result in
+   a single sequential scan of the input stream, and no restarting of LibJpeg decoding
+   session.
+*/
+
+#define WIN32_LEAN_AND_MEAN
+#define VC_EXTRALEAN
+
+#include "tiffiop.h"
+#ifdef OJPEG_SUPPORT
+
+/* Configuration defines here are:
+ * JPEG_ENCAP_EXTERNAL: The normal way to call libjpeg, uses longjump. In some environments,
+ * 	like eg LibTiffDelphi, this is not possible. For this reason, the actual calls to
+ * 	libjpeg, with longjump stuff, are encapsulated in dedicated functions. When
+ * 	JPEG_ENCAP_EXTERNAL is defined, these encapsulating functions are declared external
+ * 	to this unit, and can be defined elsewhere to use stuff other then longjump.
+ * 	The default mode, without JPEG_ENCAP_EXTERNAL, implements the call encapsulators
+ * 	here, internally, with normal longjump.
+ * SETJMP, LONGJMP, JMP_BUF: On some machines/environments a longjump equivalent is
+ * 	conviniently available, but still it may be worthwhile to use _setjmp or sigsetjmp
+ * 	in place of plain setjmp. These macros will make it easier. It is useless
+ * 	to fiddle with these if you define JPEG_ENCAP_EXTERNAL.
+ * OJPEG_BUFFER: Define the size of the desired buffer here. Should be small enough so as to guarantee
+ * 	instant processing, optimal streaming and optimal use of processor cache, but also big
+ * 	enough so as to not result in significant call overhead. It should be at least a few
+ * 	bytes to accommodate some structures (this is verified in asserts), but it would not be
+ * 	sensible to make it this small anyway, and it should be at most 64K since it is indexed
+ * 	with uint16. We recommend 2K.
+ * EGYPTIANWALK: You could also define EGYPTIANWALK here, but it is not used anywhere and has
+ * 	absolutely no effect. That is why most people insist the EGYPTIANWALK is a bit silly.
+ */
+
+/* define LIBJPEG_ENCAP_EXTERNAL */
+#define SETJMP(jbuf) setjmp(jbuf)
+#define LONGJMP(jbuf,code) longjmp(jbuf,code)
+#define JMP_BUF jmp_buf
+#define OJPEG_BUFFER 2048
+/* define EGYPTIANWALK */
+
+#define JPEG_MARKER_SOF0 0xC0
+#define JPEG_MARKER_SOF1 0xC1
+#define JPEG_MARKER_SOF3 0xC3
+#define JPEG_MARKER_DHT 0xC4
+#define JPEG_MARKER_RST0 0XD0
+#define JPEG_MARKER_SOI 0xD8
+#define JPEG_MARKER_EOI 0xD9
+#define JPEG_MARKER_SOS 0xDA
+#define JPEG_MARKER_DQT 0xDB
+#define JPEG_MARKER_DRI 0xDD
+#define JPEG_MARKER_APP0 0xE0
+#define JPEG_MARKER_COM 0xFE
+
+#define FIELD_OJPEG_JPEGINTERCHANGEFORMAT (FIELD_CODEC+0)
+#define FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH (FIELD_CODEC+1)
+#define FIELD_OJPEG_JPEGQTABLES (FIELD_CODEC+2)
+#define FIELD_OJPEG_JPEGDCTABLES (FIELD_CODEC+3)
+#define FIELD_OJPEG_JPEGACTABLES (FIELD_CODEC+4)
+#define FIELD_OJPEG_JPEGPROC (FIELD_CODEC+5)
+#define FIELD_OJPEG_JPEGRESTARTINTERVAL (FIELD_CODEC+6)
+
+static const TIFFField ojpegFields[] = {
+	{TIFFTAG_JPEGIFOFFSET,1,1,TIFF_LONG8,0,TIFF_SETGET_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGINTERCHANGEFORMAT,TRUE,FALSE,"JpegInterchangeFormat",NULL},
+	{TIFFTAG_JPEGIFBYTECOUNT,1,1,TIFF_LONG8,0,TIFF_SETGET_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH,TRUE,FALSE,"JpegInterchangeFormatLength",NULL},
+	{TIFFTAG_JPEGQTABLES,TIFF_VARIABLE2,TIFF_VARIABLE2,TIFF_LONG8,0,TIFF_SETGET_C32_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGQTABLES,FALSE,TRUE,"JpegQTables",NULL},
+	{TIFFTAG_JPEGDCTABLES,TIFF_VARIABLE2,TIFF_VARIABLE2,TIFF_LONG8,0,TIFF_SETGET_C32_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGDCTABLES,FALSE,TRUE,"JpegDcTables",NULL},
+	{TIFFTAG_JPEGACTABLES,TIFF_VARIABLE2,TIFF_VARIABLE2,TIFF_LONG8,0,TIFF_SETGET_C32_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGACTABLES,FALSE,TRUE,"JpegAcTables",NULL},
+	{TIFFTAG_JPEGPROC,1,1,TIFF_SHORT,0,TIFF_SETGET_UINT16,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGPROC,FALSE,FALSE,"JpegProc",NULL},
+	{TIFFTAG_JPEGRESTARTINTERVAL,1,1,TIFF_SHORT,0,TIFF_SETGET_UINT16,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGRESTARTINTERVAL,FALSE,FALSE,"JpegRestartInterval",NULL},
+};
+
+#ifndef LIBJPEG_ENCAP_EXTERNAL
+#include <setjmp.h>
+#endif
+
+/* We undefine FAR to avoid conflict with JPEG definition */
+
+#ifdef FAR
+#undef FAR
+#endif
+
+/*
+  Libjpeg's jmorecfg.h defines INT16 and INT32, but only if XMD_H is
+  not defined.  Unfortunately, the MinGW and Borland compilers include
+  a typedef for INT32, which causes a conflict.  MSVC does not include
+  a conficting typedef given the headers which are included.
+*/
+#if defined(__BORLANDC__) || defined(__MINGW32__)
+# define XMD_H 1
+#endif
+
+/* Define "boolean" as unsigned char, not int, per Windows custom. */
+#if defined(__WIN32__) && !defined(__MINGW32__)
+# ifndef __RPCNDR_H__            /* don't conflict if rpcndr.h already read */
+   typedef unsigned char boolean;
+# endif
+# define HAVE_BOOLEAN            /* prevent jmorecfg.h from redefining it */
+#endif
+
+#include "../LibJPEG/jpeglib.h"
+#include "../LibJPEG/jerror.h"
+
+typedef struct jpeg_error_mgr jpeg_error_mgr;
+typedef struct jpeg_common_struct jpeg_common_struct;
+typedef struct jpeg_decompress_struct jpeg_decompress_struct;
+typedef struct jpeg_source_mgr jpeg_source_mgr;
+
+typedef enum {
+	osibsNotSetYet,
+	osibsJpegInterchangeFormat,
+	osibsStrile,
+	osibsEof
+} OJPEGStateInBufferSource;
+
+typedef enum {
+	ososSoi,
+	ososQTable0,ososQTable1,ososQTable2,ososQTable3,
+	ososDcTable0,ososDcTable1,ososDcTable2,ososDcTable3,
+	ososAcTable0,ososAcTable1,ososAcTable2,ososAcTable3,
+	ososDri,
+	ososSof,
+	ososSos,
+	ososCompressed,
+	ososRst,
+	ososEoi
+} OJPEGStateOutState;
+
+typedef struct {
+	TIFF* tif;
+	#ifndef LIBJPEG_ENCAP_EXTERNAL
+	JMP_BUF exit_jmpbuf;
+	#endif
+	TIFFVGetMethod vgetparent;
+	TIFFVSetMethod vsetparent;
+	TIFFPrintMethod printdir;
+	uint64 file_size;
+	uint32 image_width;
+	uint32 image_length;
+	uint32 strile_width;
+	uint32 strile_length;
+	uint32 strile_length_total;
+	uint8 samples_per_pixel;
+	uint8 plane_sample_offset;
+	uint8 samples_per_pixel_per_plane;
+	uint64 jpeg_interchange_format;
+	uint64 jpeg_interchange_format_length;
+	uint8 jpeg_proc;
+	uint8 subsamplingcorrect;
+	uint8 subsamplingcorrect_done;
+	uint8 subsampling_tag;
+	uint8 subsampling_hor;
+	uint8 subsampling_ver;
+	uint8 subsampling_force_desubsampling_inside_decompression;
+	uint8 qtable_offset_count;
+	uint8 dctable_offset_count;
+	uint8 actable_offset_count;
+	uint64 qtable_offset[3];
+	uint64 dctable_offset[3];
+	uint64 actable_offset[3];
+	uint8* qtable[4];
+	uint8* dctable[4];
+	uint8* actable[4];
+	uint16 restart_interval;
+	uint8 restart_index;
+	uint8 sof_log;
+	uint8 sof_marker_id;
+	uint32 sof_x;
+	uint32 sof_y;
+	uint8 sof_c[3];
+	uint8 sof_hv[3];
+	uint8 sof_tq[3];
+	uint8 sos_cs[3];
+	uint8 sos_tda[3];
+	struct {
+		uint8 log;
+		OJPEGStateInBufferSource in_buffer_source;
+		uint32 in_buffer_next_strile;
+		uint64 in_buffer_file_pos;
+		uint64 in_buffer_file_togo;
+	} sos_end[3];
+	uint8 readheader_done;
+	uint8 writeheader_done;
+	uint16 write_cursample;
+	uint32 write_curstrile;
+	uint8 libjpeg_session_active;
+	uint8 libjpeg_jpeg_query_style;
+	jpeg_error_mgr libjpeg_jpeg_error_mgr;
+	jpeg_decompress_struct libjpeg_jpeg_decompress_struct;
+	jpeg_source_mgr libjpeg_jpeg_source_mgr;
+	uint8 subsampling_convert_log;
+	uint32 subsampling_convert_ylinelen;
+	uint32 subsampling_convert_ylines;
+	uint32 subsampling_convert_clinelen;
+	uint32 subsampling_convert_clines;
+	uint32 subsampling_convert_ybuflen;
+	uint32 subsampling_convert_cbuflen;
+	uint32 subsampling_convert_ycbcrbuflen;
+	uint8* subsampling_convert_ycbcrbuf;
+	uint8* subsampling_convert_ybuf;
+	uint8* subsampling_convert_cbbuf;
+	uint8* subsampling_convert_crbuf;
+	uint32 subsampling_convert_ycbcrimagelen;
+	uint8** subsampling_convert_ycbcrimage;
+	uint32 subsampling_convert_clinelenout;
+	uint32 subsampling_convert_state;
+	uint32 bytes_per_line;   /* if the codec outputs subsampled data, a 'line' in bytes_per_line */
+	uint32 lines_per_strile; /* and lines_per_strile means subsampling_ver desubsampled rows     */
+	OJPEGStateInBufferSource in_buffer_source;
+	uint32 in_buffer_next_strile;
+	uint32 in_buffer_strile_count;
+	uint64 in_buffer_file_pos;
+	uint8 in_buffer_file_pos_log;
+	uint64 in_buffer_file_togo;
+	uint16 in_buffer_togo;
+	uint8* in_buffer_cur;
+	uint8 in_buffer[OJPEG_BUFFER];
+	OJPEGStateOutState out_state;
+	uint8 out_buffer[OJPEG_BUFFER];
+	uint8* skip_buffer;
+} OJPEGState;
+
+static int OJPEGVGetField(TIFF* tif, uint32 tag, va_list ap);
+static int OJPEGVSetField(TIFF* tif, uint32 tag, va_list ap);
+static void OJPEGPrintDir(TIFF* tif, FILE* fd, long flags);
+
+static int OJPEGFixupTags(TIFF* tif);
+static int OJPEGSetupDecode(TIFF* tif);
+static int OJPEGPreDecode(TIFF* tif, uint16 s);
+static int OJPEGPreDecodeSkipRaw(TIFF* tif);
+static int OJPEGPreDecodeSkipScanlines(TIFF* tif);
+static int OJPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s);
+static int OJPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc);
+static int OJPEGDecodeScanlines(TIFF* tif, uint8* buf, tmsize_t cc);
+static void OJPEGPostDecode(TIFF* tif, uint8* buf, tmsize_t cc);
+static int OJPEGSetupEncode(TIFF* tif);
+static int OJPEGPreEncode(TIFF* tif, uint16 s);
+static int OJPEGEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s);
+static int OJPEGPostEncode(TIFF* tif);
+static void OJPEGCleanup(TIFF* tif);
+
+static void OJPEGSubsamplingCorrect(TIFF* tif);
+static int OJPEGReadHeaderInfo(TIFF* tif);
+static int OJPEGReadSecondarySos(TIFF* tif, uint16 s);
+static int OJPEGWriteHeaderInfo(TIFF* tif);
+static void OJPEGLibjpegSessionAbort(TIFF* tif);
+
+static int OJPEGReadHeaderInfoSec(TIFF* tif);
+static int OJPEGReadHeaderInfoSecStreamDri(TIFF* tif);
+static int OJPEGReadHeaderInfoSecStreamDqt(TIFF* tif);
+static int OJPEGReadHeaderInfoSecStreamDht(TIFF* tif);
+static int OJPEGReadHeaderInfoSecStreamSof(TIFF* tif, uint8 marker_id);
+static int OJPEGReadHeaderInfoSecStreamSos(TIFF* tif);
+static int OJPEGReadHeaderInfoSecTablesQTable(TIFF* tif);
+static int OJPEGReadHeaderInfoSecTablesDcTable(TIFF* tif);
+static int OJPEGReadHeaderInfoSecTablesAcTable(TIFF* tif);
+
+static int OJPEGReadBufferFill(OJPEGState* sp);
+static int OJPEGReadByte(OJPEGState* sp, uint8* byte);
+static int OJPEGReadBytePeek(OJPEGState* sp, uint8* byte);
+static void OJPEGReadByteAdvance(OJPEGState* sp);
+static int OJPEGReadWord(OJPEGState* sp, uint16* word);
+static int OJPEGReadBlock(OJPEGState* sp, uint16 len, void* mem);
+static void OJPEGReadSkip(OJPEGState* sp, uint16 len);
+
+static int OJPEGWriteStream(TIFF* tif, void** mem, uint32* len);
+static void OJPEGWriteStreamSoi(TIFF* tif, void** mem, uint32* len);
+static void OJPEGWriteStreamQTable(TIFF* tif, uint8 table_index, void** mem, uint32* len);
+static void OJPEGWriteStreamDcTable(TIFF* tif, uint8 table_index, void** mem, uint32* len);
+static void OJPEGWriteStreamAcTable(TIFF* tif, uint8 table_index, void** mem, uint32* len);
+static void OJPEGWriteStreamDri(TIFF* tif, void** mem, uint32* len);
+static void OJPEGWriteStreamSof(TIFF* tif, void** mem, uint32* len);
+static void OJPEGWriteStreamSos(TIFF* tif, void** mem, uint32* len);
+static int OJPEGWriteStreamCompressed(TIFF* tif, void** mem, uint32* len);
+static void OJPEGWriteStreamRst(TIFF* tif, void** mem, uint32* len);
+static void OJPEGWriteStreamEoi(TIFF* tif, void** mem, uint32* len);
+
+#ifdef LIBJPEG_ENCAP_EXTERNAL
+extern int jpeg_create_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo);
+extern int jpeg_read_header_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, uint8 require_image);
+extern int jpeg_start_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo);
+extern int jpeg_read_scanlines_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* scanlines, uint32 max_lines);
+extern int jpeg_read_raw_data_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* data, uint32 max_lines);
+extern void jpeg_encap_unwind(TIFF* tif);
+#else
+static int jpeg_create_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* j);
+static int jpeg_read_header_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, uint8 require_image);
+static int jpeg_start_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo);
+static int jpeg_read_scanlines_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* scanlines, uint32 max_lines);
+static int jpeg_read_raw_data_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* data, uint32 max_lines);
+static void jpeg_encap_unwind(TIFF* tif);
+#endif
+
+static void OJPEGLibjpegJpegErrorMgrOutputMessage(jpeg_common_struct* cinfo);
+static void OJPEGLibjpegJpegErrorMgrErrorExit(jpeg_common_struct* cinfo);
+static void OJPEGLibjpegJpegSourceMgrInitSource(jpeg_decompress_struct* cinfo);
+static boolean OJPEGLibjpegJpegSourceMgrFillInputBuffer(jpeg_decompress_struct* cinfo);
+static void OJPEGLibjpegJpegSourceMgrSkipInputData(jpeg_decompress_struct* cinfo, long num_bytes);
+static boolean OJPEGLibjpegJpegSourceMgrResyncToRestart(jpeg_decompress_struct* cinfo, int desired);
+static void OJPEGLibjpegJpegSourceMgrTermSource(jpeg_decompress_struct* cinfo);
+
+int
+TIFFInitOJPEG(TIFF* tif, int scheme)
+{
+	static const char module[]="TIFFInitOJPEG";
+	OJPEGState* sp;
+
+	assert(scheme==COMPRESSION_OJPEG);
+
+        /*
+	 * Merge codec-specific tag information.
+	 */
+	if (!_TIFFMergeFields(tif, ojpegFields, TIFFArrayCount(ojpegFields))) {
+		TIFFErrorExt(tif->tif_clientdata, module,
+		    "Merging Old JPEG codec-specific tags failed");
+		return 0;
+	}
+
+	/* state block */
+	sp=_TIFFmalloc(sizeof(OJPEGState));
+	if (sp==NULL)
+	{
+		TIFFErrorExt(tif->tif_clientdata,module,"No space for OJPEG state block");
+		return(0);
+	}
+	_TIFFmemset(sp,0,sizeof(OJPEGState));
+	sp->tif=tif;
+	sp->jpeg_proc=1;
+	sp->subsampling_hor=2;
+	sp->subsampling_ver=2;
+	TIFFSetField(tif,TIFFTAG_YCBCRSUBSAMPLING,2,2);
+	/* tif codec methods */
+	tif->tif_fixuptags=OJPEGFixupTags;  
+	tif->tif_setupdecode=OJPEGSetupDecode;
+	tif->tif_predecode=OJPEGPreDecode;
+	tif->tif_postdecode=OJPEGPostDecode;  
+	tif->tif_decoderow=OJPEGDecode;  
+	tif->tif_decodestrip=OJPEGDecode;  
+	tif->tif_decodetile=OJPEGDecode;  
+	tif->tif_setupencode=OJPEGSetupEncode;
+	tif->tif_preencode=OJPEGPreEncode;
+	tif->tif_postencode=OJPEGPostEncode;
+	tif->tif_encoderow=OJPEGEncode;  
+	tif->tif_encodestrip=OJPEGEncode;  
+	tif->tif_encodetile=OJPEGEncode;  
+	tif->tif_cleanup=OJPEGCleanup;
+	tif->tif_data=(uint8*)sp;
+	/* tif tag methods */
+	sp->vgetparent=tif->tif_tagmethods.vgetfield;
+	tif->tif_tagmethods.vgetfield=OJPEGVGetField;
+	sp->vsetparent=tif->tif_tagmethods.vsetfield;
+	tif->tif_tagmethods.vsetfield=OJPEGVSetField;
+	sp->printdir=tif->tif_tagmethods.printdir;
+	tif->tif_tagmethods.printdir=OJPEGPrintDir;
+	/* Some OJPEG files don't have strip or tile offsets or bytecounts tags.
+	   Some others do, but have totally meaningless or corrupt values
+	   in these tags. In these cases, the JpegInterchangeFormat stream is
+	   reliable. In any case, this decoder reads the compressed data itself,
+	   from the most reliable locations, and we need to notify encapsulating
+	   LibTiff not to read raw strips or tiles for us. */
+	tif->tif_flags|=TIFF_NOREADRAW;
+	return(1);
+}
+
+static int
+OJPEGVGetField(TIFF* tif, uint32 tag, va_list ap)
+{
+	OJPEGState* sp=(OJPEGState*)tif->tif_data;
+	switch(tag)
+	{
+		case TIFFTAG_JPEGIFOFFSET:
+			*va_arg(ap,uint64*)=(uint64)sp->jpeg_interchange_format;
+			break;
+		case TIFFTAG_JPEGIFBYTECOUNT:
+			*va_arg(ap,uint64*)=(uint64)sp->jpeg_interchange_format_length;
+			break;
+		case TIFFTAG_YCBCRSUBSAMPLING:
+			if (sp->subsamplingcorrect_done==0)
+				OJPEGSubsamplingCorrect(tif);
+			*va_arg(ap,uint16*)=(uint16)sp->subsampling_hor;
+			*va_arg(ap,uint16*)=(uint16)sp->subsampling_ver;
+			break;
+		case TIFFTAG_JPEGQTABLES:
+			*va_arg(ap,uint32*)=(uint32)sp->qtable_offset_count;
+			*va_arg(ap,void**)=(void*)sp->qtable_offset; 
+			break;
+		case TIFFTAG_JPEGDCTABLES:
+			*va_arg(ap,uint32*)=(uint32)sp->dctable_offset_count;
+			*va_arg(ap,void**)=(void*)sp->dctable_offset;  
+			break;
+		case TIFFTAG_JPEGACTABLES:
+			*va_arg(ap,uint32*)=(uint32)sp->actable_offset_count;
+			*va_arg(ap,void**)=(void*)sp->actable_offset;
+			break;
+		case TIFFTAG_JPEGPROC:
+			*va_arg(ap,uint16*)=(uint16)sp->jpeg_proc;
+			break;
+		case TIFFTAG_JPEGRESTARTINTERVAL:
+			*va_arg(ap,uint16*)=sp->restart_interval;
+			break;
+		default:
+			return (*sp->vgetparent)(tif,tag,ap);
+	}
+	return (1);
+}
+
+static int
+OJPEGVSetField(TIFF* tif, uint32 tag, va_list ap)
+{
+	static const char module[]="OJPEGVSetField";
+	OJPEGState* sp=(OJPEGState*)tif->tif_data;
+	uint32 ma;
+	uint64* mb;
+	uint32 n;
+	const TIFFField* fip;
+
+	switch(tag)
+	{
+		case TIFFTAG_JPEGIFOFFSET:
+			sp->jpeg_interchange_format=(uint64)va_arg(ap,uint64);
+			break;
+		case TIFFTAG_JPEGIFBYTECOUNT:
+			sp->jpeg_interchange_format_length=(uint64)va_arg(ap,uint64);
+			break;
+		case TIFFTAG_YCBCRSUBSAMPLING:
+			sp->subsampling_tag=1;
+			sp->subsampling_hor=(uint8)va_arg(ap,uint16_vap);
+			sp->subsampling_ver=(uint8)va_arg(ap,uint16_vap);
+			tif->tif_dir.td_ycbcrsubsampling[0]=sp->subsampling_hor;
+			tif->tif_dir.td_ycbcrsubsampling[1]=sp->subsampling_ver;
+			break;
+		case TIFFTAG_JPEGQTABLES:
+			ma=(uint32)va_arg(ap,uint32);
+			if (ma!=0)
+			{
+				if (ma>3)
+				{
+					TIFFErrorExt(tif->tif_clientdata,module,"JpegQTables tag has incorrect count");
+					return(0);
+				}
+				sp->qtable_offset_count=(uint8)ma;
+				mb=(uint64*)va_arg(ap,uint64*);
+				for (n=0; n<ma; n++)
+					sp->qtable_offset[n]=mb[n];
+			}
+			break;
+		case TIFFTAG_JPEGDCTABLES:
+			ma=(uint32)va_arg(ap,uint32);
+			if (ma!=0)
+			{
+				if (ma>3)
+				{
+					TIFFErrorExt(tif->tif_clientdata,module,"JpegDcTables tag has incorrect count");
+					return(0);
+				}
+				sp->dctable_offset_count=(uint8)ma;
+				mb=(uint64*)va_arg(ap,uint64*);
+				for (n=0; n<ma; n++)
+					sp->dctable_offset[n]=mb[n];
+			}
+			break;
+		case TIFFTAG_JPEGACTABLES:
+			ma=(uint32)va_arg(ap,uint32);
+			if (ma!=0)
+			{
+				if (ma>3)
+				{
+					TIFFErrorExt(tif->tif_clientdata,module,"JpegAcTables tag has incorrect count");
+					return(0);
+				}
+				sp->actable_offset_count=(uint8)ma;
+				mb=(uint64*)va_arg(ap,uint64*);
+				for (n=0; n<ma; n++)
+					sp->actable_offset[n]=mb[n];
+			}
+			break;
+		case TIFFTAG_JPEGPROC:
+			sp->jpeg_proc=(uint8)va_arg(ap,uint16_vap);
+			break;
+		case TIFFTAG_JPEGRESTARTINTERVAL:
+			sp->restart_interval=(uint16)va_arg(ap,uint16_vap);
+			break;
+		default:
+			return (*sp->vsetparent)(tif,tag,ap);
+	}
+	fip = TIFFFieldWithTag(tif,tag);
+	if( fip == NULL ) /* shouldn't happen */
+	    return(0);
+	TIFFSetFieldBit(tif,fip->field_bit);
+	tif->tif_flags|=TIFF_DIRTYDIRECT;
+	return(1);
+}
+
+static void
+OJPEGPrintDir(TIFF* tif, FILE* fd, long flags)
+{
+	OJPEGState* sp=(OJPEGState*)tif->tif_data;
+	uint8 m;
+	(void)flags;
+	assert(sp!=NULL);
+	if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGINTERCHANGEFORMAT))
+		fprintf(fd,"  JpegInterchangeFormat: " TIFF_UINT64_FORMAT "\n",(TIFF_UINT64_T)sp->jpeg_interchange_format);  
+	if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH))
+		fprintf(fd,"  JpegInterchangeFormatLength: " TIFF_UINT64_FORMAT "\n",(TIFF_UINT64_T)sp->jpeg_interchange_format_length);  
+	if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGQTABLES))
+	{
+		fprintf(fd,"  JpegQTables:");
+		for (m=0; m<sp->qtable_offset_count; m++)
+			fprintf(fd," " TIFF_UINT64_FORMAT,(TIFF_UINT64_T)sp->qtable_offset[m]);
+		fprintf(fd,"\n");
+	}
+	if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGDCTABLES))
+	{
+		fprintf(fd,"  JpegDcTables:");
+		for (m=0; m<sp->dctable_offset_count; m++)
+			fprintf(fd," " TIFF_UINT64_FORMAT,(TIFF_UINT64_T)sp->dctable_offset[m]);
+		fprintf(fd,"\n");
+	}
+	if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGACTABLES))
+	{
+		fprintf(fd,"  JpegAcTables:");
+		for (m=0; m<sp->actable_offset_count; m++)
+			fprintf(fd," " TIFF_UINT64_FORMAT,(TIFF_UINT64_T)sp->actable_offset[m]);
+		fprintf(fd,"\n");
+	}
+	if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGPROC))
+		fprintf(fd,"  JpegProc: %u\n",(unsigned int)sp->jpeg_proc);
+	if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGRESTARTINTERVAL))
+		fprintf(fd,"  JpegRestartInterval: %u\n",(unsigned int)sp->restart_interval);
+	if (sp->printdir)
+		(*sp->printdir)(tif, fd, flags);
+}
+
+static int
+OJPEGFixupTags(TIFF* tif)
+{
+	(void) tif;
+	return(1);
+}
+
+static int
+OJPEGSetupDecode(TIFF* tif)
+{
+	static const char module[]="OJPEGSetupDecode";
+	TIFFWarningExt(tif->tif_clientdata,module,"Depreciated and troublesome old-style JPEG compression mode, please convert to new-style JPEG compression and notify vendor of writing software");
+	return(1);
+}
+
+static int
+OJPEGPreDecode(TIFF* tif, uint16 s)
+{
+	OJPEGState* sp=(OJPEGState*)tif->tif_data;
+	uint32 m;
+	if (sp->subsamplingcorrect_done==0)
+		OJPEGSubsamplingCorrect(tif);
+	if (sp->readheader_done==0)
+	{
+		if (OJPEGReadHeaderInfo(tif)==0)
+			return(0);
+	}
+	if (sp->sos_end[s].log==0)
+	{
+		if (OJPEGReadSecondarySos(tif,s)==0)
+			return(0);
+	}
+	if isTiled(tif)
+		m=tif->tif_curtile;
+	else
+		m=tif->tif_curstrip;
+	if ((sp->writeheader_done!=0) && ((sp->write_cursample!=s) || (sp->write_curstrile>m)))
+	{
+		if (sp->libjpeg_session_active!=0)
+			OJPEGLibjpegSessionAbort(tif);
+		sp->writeheader_done=0;
+	}
+	if (sp->writeheader_done==0)
+	{
+		sp->plane_sample_offset=(uint8)s;
+		sp->write_cursample=s;
+		sp->write_curstrile=s*tif->tif_dir.td_stripsperimage;
+		if ((sp->in_buffer_file_pos_log==0) ||
+		    (sp->in_buffer_file_pos-sp->in_buffer_togo!=sp->sos_end[s].in_buffer_file_pos))
+		{
+			sp->in_buffer_source=sp->sos_end[s].in_buffer_source;
+			sp->in_buffer_next_strile=sp->sos_end[s].in_buffer_next_strile;
+			sp->in_buffer_file_pos=sp->sos_end[s].in_buffer_file_pos;
+			sp->in_buffer_file_pos_log=0;
+			sp->in_buffer_file_togo=sp->sos_end[s].in_buffer_file_togo;
+			sp->in_buffer_togo=0;
+			sp->in_buffer_cur=0;
+		}
+		if (OJPEGWriteHeaderInfo(tif)==0)
+			return(0);
+	}
+	while (sp->write_curstrile<m)          
+	{
+		if (sp->libjpeg_jpeg_query_style==0)
+		{
+			if (OJPEGPreDecodeSkipRaw(tif)==0)
+				return(0);
+		}
+		else
+		{
+			if (OJPEGPreDecodeSkipScanlines(tif)==0)
+				return(0);
+		}
+		sp->write_curstrile++;
+	}
+	return(1);
+}
+
+static int
+OJPEGPreDecodeSkipRaw(TIFF* tif)
+{
+	OJPEGState* sp=(OJPEGState*)tif->tif_data;
+	uint32 m;
+	m=sp->lines_per_strile;
+	if (sp->subsampling_convert_state!=0)
+	{
+		if (sp->subsampling_convert_clines-sp->subsampling_convert_state>=m)
+		{
+			sp->subsampling_convert_state+=m;
+			if (sp->subsampling_convert_state==sp->subsampling_convert_clines)
+				sp->subsampling_convert_state=0;
+			return(1);
+		}
+		m-=sp->subsampling_convert_clines-sp->subsampling_convert_state;
+		sp->subsampling_convert_state=0;
+	}
+	while (m>=sp->subsampling_convert_clines)
+	{
+		if (jpeg_read_raw_data_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),sp->subsampling_convert_ycbcrimage,sp->subsampling_ver*8)==0)
+			return(0);
+		m-=sp->subsampling_convert_clines;
+	}
+	if (m>0)
+	{
+		if (jpeg_read_raw_data_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),sp->subsampling_convert_ycbcrimage,sp->subsampling_ver*8)==0)
+			return(0);
+		sp->subsampling_convert_state=m;
+	}
+	return(1);
+}
+
+static int
+OJPEGPreDecodeSkipScanlines(TIFF* tif)
+{
+	static const char module[]="OJPEGPreDecodeSkipScanlines";
+	OJPEGState* sp=(OJPEGState*)tif->tif_data;
+	uint32 m;
+	if (sp->skip_buffer==NULL)
+	{
+		sp->skip_buffer=_TIFFmalloc(sp->bytes_per_line);
+		if (sp->skip_buffer==NULL)
+		{
+			TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+			return(0);
+		}
+	}
+	for (m=0; m<sp->lines_per_strile; m++)
+	{
+		if (jpeg_read_scanlines_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),&sp->skip_buffer,1)==0)
+			return(0);
+	}
+	return(1);
+}
+
+static int
+OJPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
+{
+	OJPEGState* sp=(OJPEGState*)tif->tif_data;
+	(void)s;
+	if (sp->libjpeg_jpeg_query_style==0)
+	{
+		if (OJPEGDecodeRaw(tif,buf,cc)==0)
+			return(0);
+	}
+	else
+	{
+		if (OJPEGDecodeScanlines(tif,buf,cc)==0)
+			return(0);
+	}
+	return(1);
+}
+
+static int
+OJPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc)
+{
+	static const char module[]="OJPEGDecodeRaw";
+	OJPEGState* sp=(OJPEGState*)tif->tif_data;
+	uint8* m;
+	tmsize_t n;
+	uint8* oy;
+	uint8* ocb;
+	uint8* ocr;
+	uint8* p;
+	uint32 q;
+	uint8* r;
+	uint8 sx,sy;
+	if (cc%sp->bytes_per_line!=0)
+	{
+		TIFFErrorExt(tif->tif_clientdata,module,"Fractional scanline not read");
+		return(0);
+	}
+	assert(cc>0);
+	m=buf;
+	n=cc;
+	do
+	{
+		if (sp->subsampling_convert_state==0)
+		{
+			if (jpeg_read_raw_data_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),sp->subsampling_convert_ycbcrimage,sp->subsampling_ver*8)==0)
+				return(0);
+		}
+		oy=sp->subsampling_convert_ybuf+sp->subsampling_convert_state*sp->subsampling_ver*sp->subsampling_convert_ylinelen;
+		ocb=sp->subsampling_convert_cbbuf+sp->subsampling_convert_state*sp->subsampling_convert_clinelen;
+		ocr=sp->subsampling_convert_crbuf+sp->subsampling_convert_state*sp->subsampling_convert_clinelen;
+		p=m;
+		for (q=0; q<sp->subsampling_convert_clinelenout; q++)
+		{
+			r=oy;
+			for (sy=0; sy<sp->subsampling_ver; sy++)
+			{
+				for (sx=0; sx<sp->subsampling_hor; sx++)
+					*p++=*r++;
+				r+=sp->subsampling_convert_ylinelen-sp->subsampling_hor;
+			}
+			oy+=sp->subsampling_hor;
+			*p++=*ocb++;
+			*p++=*ocr++;
+		}
+		sp->subsampling_convert_state++;
+		if (sp->subsampling_convert_state==sp->subsampling_convert_clines)
+			sp->subsampling_convert_state=0;
+		m+=sp->bytes_per_line;
+		n-=sp->bytes_per_line;
+	} while(n>0);
+	return(1);
+}
+
+static int
+OJPEGDecodeScanlines(TIFF* tif, uint8* buf, tmsize_t cc)
+{
+	static const char module[]="OJPEGDecodeScanlines";
+	OJPEGState* sp=(OJPEGState*)tif->tif_data;
+	uint8* m;
+	tmsize_t n;
+	if (cc%sp->bytes_per_line!=0)
+	{
+		TIFFErrorExt(tif->tif_clientdata,module,"Fractional scanline not read");
+		return(0);
+	}
+	assert(cc>0);
+	m=buf;
+	n=cc;
+	do
+	{
+		if (jpeg_read_scanlines_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),&m,1)==0)
+			return(0);
+		m+=sp->bytes_per_line;
+		n-=sp->bytes_per_line;
+	} while(n>0);
+	return(1);
+}
+
+static void
+OJPEGPostDecode(TIFF* tif, uint8* buf, tmsize_t cc)
+{
+	OJPEGState* sp=(OJPEGState*)tif->tif_data;
+	(void)buf;
+	(void)cc;
+	sp->write_curstrile++;
+	if (sp->write_curstrile%tif->tif_dir.td_stripsperimage==0)  
+	{
+		assert(sp->libjpeg_session_active!=0);
+		OJPEGLibjpegSessionAbort(tif);
+		sp->writeheader_done=0;
+	}
+}
+
+static int
+OJPEGSetupEncode(TIFF* tif)
+{
+	static const char module[]="OJPEGSetupEncode";
+	TIFFErrorExt(tif->tif_clientdata,module,"OJPEG encoding not supported; use new-style JPEG compression instead");
+	return(0);
+}
+
+static int
+OJPEGPreEncode(TIFF* tif, uint16 s)
+{
+	static const char module[]="OJPEGPreEncode";
+	(void)s;
+	TIFFErrorExt(tif->tif_clientdata,module,"OJPEG encoding not supported; use new-style JPEG compression instead");
+	return(0);
+}
+
+static int
+OJPEGEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
+{
+	static const char module[]="OJPEGEncode";
+	(void)buf;
+	(void)cc;
+	(void)s;
+	TIFFErrorExt(tif->tif_clientdata,module,"OJPEG encoding not supported; use new-style JPEG compression instead");
+	return(0);
+}
+
+static int
+OJPEGPostEncode(TIFF* tif)
+{
+	static const char module[]="OJPEGPostEncode";
+	TIFFErrorExt(tif->tif_clientdata,module,"OJPEG encoding not supported; use new-style JPEG compression instead");
+	return(0);
+}
+
+static void
+OJPEGCleanup(TIFF* tif)
+{
+	OJPEGState* sp=(OJPEGState*)tif->tif_data;
+	if (sp!=0)
+	{
+		tif->tif_tagmethods.vgetfield=sp->vgetparent;
+		tif->tif_tagmethods.vsetfield=sp->vsetparent;
+		tif->tif_tagmethods.printdir=sp->printdir;
+		if (sp->qtable[0]!=0)
+			_TIFFfree(sp->qtable[0]);
+		if (sp->qtable[1]!=0)
+			_TIFFfree(sp->qtable[1]);
+		if (sp->qtable[2]!=0)
+			_TIFFfree(sp->qtable[2]);
+		if (sp->qtable[3]!=0)
+			_TIFFfree(sp->qtable[3]);
+		if (sp->dctable[0]!=0)
+			_TIFFfree(sp->dctable[0]);
+		if (sp->dctable[1]!=0)
+			_TIFFfree(sp->dctable[1]);
+		if (sp->dctable[2]!=0)
+			_TIFFfree(sp->dctable[2]);
+		if (sp->dctable[3]!=0)
+			_TIFFfree(sp->dctable[3]);
+		if (sp->actable[0]!=0)
+			_TIFFfree(sp->actable[0]);
+		if (sp->actable[1]!=0)
+			_TIFFfree(sp->actable[1]);
+		if (sp->actable[2]!=0)
+			_TIFFfree(sp->actable[2]);
+		if (sp->actable[3]!=0)
+			_TIFFfree(sp->actable[3]);
+		if (sp->libjpeg_session_active!=0)
+			OJPEGLibjpegSessionAbort(tif);
+		if (sp->subsampling_convert_ycbcrbuf!=0)
+			_TIFFfree(sp->subsampling_convert_ycbcrbuf);
+		if (sp->subsampling_convert_ycbcrimage!=0)
+			_TIFFfree(sp->subsampling_convert_ycbcrimage);
+		if (sp->skip_buffer!=0)
+			_TIFFfree(sp->skip_buffer);
+		_TIFFfree(sp);
+		tif->tif_data=NULL;
+		_TIFFSetDefaultCompressionState(tif);
+	}
+}
+
+static void
+OJPEGSubsamplingCorrect(TIFF* tif)
+{
+	static const char module[]="OJPEGSubsamplingCorrect";
+	OJPEGState* sp=(OJPEGState*)tif->tif_data;
+	uint8 mh;
+	uint8 mv;
+        _TIFFFillStriles( tif );
+        
+	assert(sp->subsamplingcorrect_done==0);
+	if ((tif->tif_dir.td_samplesperpixel!=3) || ((tif->tif_dir.td_photometric!=PHOTOMETRIC_YCBCR) &&
+	    (tif->tif_dir.td_photometric!=PHOTOMETRIC_ITULAB)))
+	{
+		if (sp->subsampling_tag!=0)
+			TIFFWarningExt(tif->tif_clientdata,module,"Subsampling tag not appropriate for this Photometric and/or SamplesPerPixel");
+		sp->subsampling_hor=1;
+		sp->subsampling_ver=1;
+		sp->subsampling_force_desubsampling_inside_decompression=0;
+	}
+	else
+	{
+		sp->subsamplingcorrect_done=1;
+		mh=sp->subsampling_hor;
+		mv=sp->subsampling_ver;
+		sp->subsamplingcorrect=1;
+		OJPEGReadHeaderInfoSec(tif);
+		if (sp->subsampling_force_desubsampling_inside_decompression!=0)
+		{
+			sp->subsampling_hor=1;
+			sp->subsampling_ver=1;
+		}
+		sp->subsamplingcorrect=0;
+		if (((sp->subsampling_hor!=mh) || (sp->subsampling_ver!=mv)) && (sp->subsampling_force_desubsampling_inside_decompression==0))
+		{
+			if (sp->subsampling_tag==0)
+				TIFFWarningExt(tif->tif_clientdata,module,"Subsampling tag is not set, yet subsampling inside JPEG data [%d,%d] does not match default values [2,2]; assuming subsampling inside JPEG data is correct",sp->subsampling_hor,sp->subsampling_ver);
+			else
+				TIFFWarningExt(tif->tif_clientdata,module,"Subsampling inside JPEG data [%d,%d] does not match subsampling tag values [%d,%d]; assuming subsampling inside JPEG data is correct",sp->subsampling_hor,sp->subsampling_ver,mh,mv);
+		}
+		if (sp->subsampling_force_desubsampling_inside_decompression!=0)
+		{
+			if (sp->subsampling_tag==0)
+				TIFFWarningExt(tif->tif_clientdata,module,"Subsampling tag is not set, yet subsampling inside JPEG data does not match default values [2,2] (nor any other values allowed in TIFF); assuming subsampling inside JPEG data is correct and desubsampling inside JPEG decompression");
+			else
+				TIFFWarningExt(tif->tif_clientdata,module,"Subsampling inside JPEG data does not match subsampling tag values [%d,%d] (nor any other values allowed in TIFF); assuming subsampling inside JPEG data is correct and desubsampling inside JPEG decompression",mh,mv);
+		}
+		if (sp->subsampling_force_desubsampling_inside_decompression==0)
+		{
+			if (sp->subsampling_hor<sp->subsampling_ver)
+				TIFFWarningExt(tif->tif_clientdata,module,"Subsampling values [%d,%d] are not allowed in TIFF",sp->subsampling_hor,sp->subsampling_ver);
+		}
+	}
+	sp->subsamplingcorrect_done=1;
+}
+
+static int
+OJPEGReadHeaderInfo(TIFF* tif)
+{
+	static const char module[]="OJPEGReadHeaderInfo";
+	OJPEGState* sp=(OJPEGState*)tif->tif_data;
+	assert(sp->readheader_done==0);
+	sp->image_width=tif->tif_dir.td_imagewidth;
+	sp->image_length=tif->tif_dir.td_imagelength;
+	if isTiled(tif)
+	{
+		sp->strile_width=tif->tif_dir.td_tilewidth;
+		sp->strile_length=tif->tif_dir.td_tilelength;
+		sp->strile_length_total=((sp->image_length+sp->strile_length-1)/sp->strile_length)*sp->strile_length;
+	}
+	else
+	{
+		sp->strile_width=sp->image_width;
+		sp->strile_length=tif->tif_dir.td_rowsperstrip;
+		sp->strile_length_total=sp->image_length;
+	}
+	if (tif->tif_dir.td_samplesperpixel==1)
+	{
+		sp->samples_per_pixel=1;
+		sp->plane_sample_offset=0;
+		sp->samples_per_pixel_per_plane=sp->samples_per_pixel;
+		sp->subsampling_hor=1;
+		sp->subsampling_ver=1;
+	}
+	else
+	{
+		if (tif->tif_dir.td_samplesperpixel!=3)
+		{
+			TIFFErrorExt(tif->tif_clientdata,module,"SamplesPerPixel %d not supported for this compression scheme",sp->samples_per_pixel);
+			return(0);
+		}
+		sp->samples_per_pixel=3;
+		sp->plane_sample_offset=0;
+		if (tif->tif_dir.td_planarconfig==PLANARCONFIG_CONTIG)
+			sp->samples_per_pixel_per_plane=3;
+		else
+			sp->samples_per_pixel_per_plane=1;
+	}
+	if (sp->strile_length<sp->image_length)
+	{
+		if (sp->strile_length%(sp->subsampling_ver*8)!=0)
+		{
+			TIFFErrorExt(tif->tif_clientdata,module,"Incompatible vertical subsampling and image strip/tile length");
+			return(0);
+		}
+		sp->restart_interval=((sp->strile_width+sp->subsampling_hor*8-1)/(sp->subsampling_hor*8))*(sp->strile_length/(sp->subsampling_ver*8));
+	}
+	if (OJPEGReadHeaderInfoSec(tif)==0)
+		return(0);
+	sp->sos_end[0].log=1;
+	sp->sos_end[0].in_buffer_source=sp->in_buffer_source;
+	sp->sos_end[0].in_buffer_next_strile=sp->in_buffer_next_strile;
+	sp->sos_end[0].in_buffer_file_pos=sp->in_buffer_file_pos-sp->in_buffer_togo;
+	sp->sos_end[0].in_buffer_file_togo=sp->in_buffer_file_togo+sp->in_buffer_togo; 
+	sp->readheader_done=1;
+	return(1);
+}
+
+static int
+OJPEGReadSecondarySos(TIFF* tif, uint16 s)
+{
+	OJPEGState* sp=(OJPEGState*)tif->tif_data;
+	uint8 m;
+	assert(s>0);
+	assert(s<3);
+	assert(sp->sos_end[0].log!=0);
+	assert(sp->sos_end[s].log==0);
+	sp->plane_sample_offset=s-1;
+	while(sp->sos_end[sp->plane_sample_offset].log==0)
+		sp->plane_sample_offset--;
+	sp->in_buffer_source=sp->sos_end[sp->plane_sample_offset].in_buffer_source;
+	sp->in_buffer_next_strile=sp->sos_end[sp->plane_sample_offset].in_buffer_next_strile;
+	sp->in_buffer_file_pos=sp->sos_end[sp->plane_sample_offset].in_buffer_file_pos;
+	sp->in_buffer_file_pos_log=0;
+	sp->in_buffer_file_togo=sp->sos_end[sp->plane_sample_offset].in_buffer_file_togo;
+	sp->in_buffer_togo=0;
+	sp->in_buffer_cur=0;
+	while(sp->plane_sample_offset<s)
+	{
+		do
+		{
+			if (OJPEGReadByte(sp,&m)==0)
+				return(0);
+			if (m==255)
+			{
+				do
+				{
+					if (OJPEGReadByte(sp,&m)==0)
+						return(0);
+					if (m!=255)
+						break;
+				} while(1);
+				if (m==JPEG_MARKER_SOS)
+					break;
+			}
+		} while(1);
+		sp->plane_sample_offset++;
+		if (OJPEGReadHeaderInfoSecStreamSos(tif)==0)
+			return(0);
+		sp->sos_end[sp->plane_sample_offset].log=1;
+		sp->sos_end[sp->plane_sample_offset].in_buffer_source=sp->in_buffer_source;
+		sp->sos_end[sp->plane_sample_offset].in_buffer_next_strile=sp->in_buffer_next_strile;
+		sp->sos_end[sp->plane_sample_offset].in_buffer_file_pos=sp->in_buffer_file_pos-sp->in_buffer_togo;
+		sp->sos_end[sp->plane_sample_offset].in_buffer_file_togo=sp->in_buffer_file_togo+sp->in_buffer_togo;
+	}
+	return(1);
+}
+
+static int
+OJPEGWriteHeaderInfo(TIFF* tif)
+{
+	static const char module[]="OJPEGWriteHeaderInfo";
+	OJPEGState* sp=(OJPEGState*)tif->tif_data;
+	uint8** m;
+	uint32 n;
+	/* if a previous attempt failed, don't try again */
+	if (sp->libjpeg_session_active != 0) 
+		return 0;
+	sp->out_state=ososSoi;
+	sp->restart_index=0;
+	jpeg_std_error(&(sp->libjpeg_jpeg_error_mgr));
+	sp->libjpeg_jpeg_error_mgr.output_message=OJPEGLibjpegJpegErrorMgrOutputMessage;
+	sp->libjpeg_jpeg_error_mgr.error_exit=OJPEGLibjpegJpegErrorMgrErrorExit;
+	sp->libjpeg_jpeg_decompress_struct.err=&(sp->libjpeg_jpeg_error_mgr);
+	sp->libjpeg_jpeg_decompress_struct.client_data=(void*)tif;
+	if (jpeg_create_decompress_encap(sp,&(sp->libjpeg_jpeg_decompress_struct))==0)
+		return(0);
+	sp->libjpeg_session_active=1;
+	sp->libjpeg_jpeg_source_mgr.bytes_in_buffer=0;
+	sp->libjpeg_jpeg_source_mgr.init_source=OJPEGLibjpegJpegSourceMgrInitSource;
+	sp->libjpeg_jpeg_source_mgr.fill_input_buffer=OJPEGLibjpegJpegSourceMgrFillInputBuffer;
+	sp->libjpeg_jpeg_source_mgr.skip_input_data=OJPEGLibjpegJpegSourceMgrSkipInputData;
+	sp->libjpeg_jpeg_source_mgr.resync_to_restart=OJPEGLibjpegJpegSourceMgrResyncToRestart;
+	sp->libjpeg_jpeg_source_mgr.term_source=OJPEGLibjpegJpegSourceMgrTermSource;
+	sp->libjpeg_jpeg_decompress_struct.src=&(sp->libjpeg_jpeg_source_mgr);
+	if (jpeg_read_header_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),1)==0)
+		return(0);
+	if ((sp->subsampling_force_desubsampling_inside_decompression==0) && (sp->samples_per_pixel_per_plane>1))
+	{
+		sp->libjpeg_jpeg_decompress_struct.raw_data_out=1;
+#if JPEG_LIB_VERSION >= 70
+		sp->libjpeg_jpeg_decompress_struct.do_fancy_upsampling=FALSE;
+#endif
+		sp->libjpeg_jpeg_query_style=0;
+		if (sp->subsampling_convert_log==0)
+		{
+			assert(sp->subsampling_convert_ycbcrbuf==0);
+			assert(sp->subsampling_convert_ycbcrimage==0);
+			sp->subsampling_convert_ylinelen=((sp->strile_width+sp->subsampling_hor*8-1)/(sp->subsampling_hor*8)*sp->subsampling_hor*8);
+			sp->subsampling_convert_ylines=sp->subsampling_ver*8;
+			sp->subsampling_convert_clinelen=sp->subsampling_convert_ylinelen/sp->subsampling_hor;
+			sp->subsampling_convert_clines=8;
+			sp->subsampling_convert_ybuflen=sp->subsampling_convert_ylinelen*sp->subsampling_convert_ylines;
+			sp->subsampling_convert_cbuflen=sp->subsampling_convert_clinelen*sp->subsampling_convert_clines;
+			sp->subsampling_convert_ycbcrbuflen=sp->subsampling_convert_ybuflen+2*sp->subsampling_convert_cbuflen;
+			sp->subsampling_convert_ycbcrbuf=_TIFFmalloc(sp->subsampling_convert_ycbcrbuflen);
+			if (sp->subsampling_convert_ycbcrbuf==0)
+			{
+				TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+				return(0);
+			}
+			sp->subsampling_convert_ybuf=sp->subsampling_convert_ycbcrbuf;
+			sp->subsampling_convert_cbbuf=sp->subsampling_convert_ybuf+sp->subsampling_convert_ybuflen;
+			sp->subsampling_convert_crbuf=sp->subsampling_convert_cbbuf+sp->subsampling_convert_cbuflen;
+			sp->subsampling_convert_ycbcrimagelen=3+sp->subsampling_convert_ylines+2*sp->subsampling_convert_clines;
+			sp->subsampling_convert_ycbcrimage=_TIFFmalloc(sp->subsampling_convert_ycbcrimagelen*sizeof(uint8*));
+			if (sp->subsampling_convert_ycbcrimage==0)
+			{
+				TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+				return(0);
+			}
+			m=sp->subsampling_convert_ycbcrimage;
+			*m++=(uint8*)(sp->subsampling_convert_ycbcrimage+3);
+			*m++=(uint8*)(sp->subsampling_convert_ycbcrimage+3+sp->subsampling_convert_ylines);
+			*m++=(uint8*)(sp->subsampling_convert_ycbcrimage+3+sp->subsampling_convert_ylines+sp->subsampling_convert_clines);
+			for (n=0; n<sp->subsampling_convert_ylines; n++)
+				*m++=sp->subsampling_convert_ybuf+n*sp->subsampling_convert_ylinelen;
+			for (n=0; n<sp->subsampling_convert_clines; n++)
+				*m++=sp->subsampling_convert_cbbuf+n*sp->subsampling_convert_clinelen;
+			for (n=0; n<sp->subsampling_convert_clines; n++)
+				*m++=sp->subsampling_convert_crbuf+n*sp->subsampling_convert_clinelen;
+			sp->subsampling_convert_clinelenout=((sp->strile_width+sp->subsampling_hor-1)/sp->subsampling_hor);
+			sp->subsampling_convert_state=0;
+			sp->bytes_per_line=sp->subsampling_convert_clinelenout*(sp->subsampling_ver*sp->subsampling_hor+2);
+			sp->lines_per_strile=((sp->strile_length+sp->subsampling_ver-1)/sp->subsampling_ver);
+			sp->subsampling_convert_log=1;
+		}
+	}
+	else
+	{
+		sp->libjpeg_jpeg_decompress_struct.jpeg_color_space=JCS_UNKNOWN;
+		sp->libjpeg_jpeg_decompress_struct.out_color_space=JCS_UNKNOWN;
+		sp->libjpeg_jpeg_query_style=1;
+		sp->bytes_per_line=sp->samples_per_pixel_per_plane*sp->strile_width;
+		sp->lines_per_strile=sp->strile_length;
+	}
+	if (jpeg_start_decompress_encap(sp,&(sp->libjpeg_jpeg_decompress_struct))==0)
+		return(0);
+	sp->writeheader_done=1;
+	return(1);
+}
+
+static void
+OJPEGLibjpegSessionAbort(TIFF* tif)
+{
+	OJPEGState* sp=(OJPEGState*)tif->tif_data;
+	assert(sp->libjpeg_session_active!=0);
+	jpeg_destroy((jpeg_common_struct*)(&(sp->libjpeg_jpeg_decompress_struct)));
+	sp->libjpeg_session_active=0;
+}
+
+static int
+OJPEGReadHeaderInfoSec(TIFF* tif)
+{
+	static const char module[]="OJPEGReadHeaderInfoSec";
+	OJPEGState* sp=(OJPEGState*)tif->tif_data;
+	uint8 m;
+	uint16 n;
+	uint8 o;
+	if (sp->file_size==0)
+		sp->file_size=TIFFGetFileSize(tif);
+	if (sp->jpeg_interchange_format!=0)
+	{
+		if (sp->jpeg_interchange_format>=sp->file_size)
+		{
+			sp->jpeg_interchange_format=0;
+			sp->jpeg_interchange_format_length=0;
+		}
+		else
+		{
+			if ((sp->jpeg_interchange_format_length==0) || (sp->jpeg_interchange_format+sp->jpeg_interchange_format_length>sp->file_size))
+				sp->jpeg_interchange_format_length=sp->file_size-sp->jpeg_interchange_format;
+		}
+	}
+	sp->in_buffer_source=osibsNotSetYet;
+	sp->in_buffer_next_strile=0;
+	sp->in_buffer_strile_count=tif->tif_dir.td_nstrips;
+	sp->in_buffer_file_togo=0;
+	sp->in_buffer_togo=0;
+	do
+	{
+		if (OJPEGReadBytePeek(sp,&m)==0)
+			return(0);
+		if (m!=255)
+			break;
+		OJPEGReadByteAdvance(sp);
+		do
+		{
+			if (OJPEGReadByte(sp,&m)==0)
+				return(0);
+		} while(m==255);
+		switch(m)
+		{
+			case JPEG_MARKER_SOI:
+				/* this type of marker has no data, and should be skipped */
+				break;
+			case JPEG_MARKER_COM:
+			case JPEG_MARKER_APP0:
+			case JPEG_MARKER_APP0+1:
+			case JPEG_MARKER_APP0+2:
+			case JPEG_MARKER_APP0+3:
+			case JPEG_MARKER_APP0+4:
+			case JPEG_MARKER_APP0+5:
+			case JPEG_MARKER_APP0+6:
+			case JPEG_MARKER_APP0+7:
+			case JPEG_MARKER_APP0+8:
+			case JPEG_MARKER_APP0+9:
+			case JPEG_MARKER_APP0+10:
+			case JPEG_MARKER_APP0+11:
+			case JPEG_MARKER_APP0+12:
+			case JPEG_MARKER_APP0+13:
+			case JPEG_MARKER_APP0+14:
+			case JPEG_MARKER_APP0+15:
+				/* this type of marker has data, but it has no use to us (and no place here) and should be skipped */
+				if (OJPEGReadWord(sp,&n)==0)
+					return(0);
+				if (n<2)
+				{
+					if (sp->subsamplingcorrect==0)
+						TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JPEG data");
+					return(0);
+				}
+				if (n>2)
+					OJPEGReadSkip(sp,n-2);
+				break;
+			case JPEG_MARKER_DRI:
+				if (OJPEGReadHeaderInfoSecStreamDri(tif)==0)
+					return(0);
+				break;
+			case JPEG_MARKER_DQT:
+				if (OJPEGReadHeaderInfoSecStreamDqt(tif)==0)
+					return(0);
+				break;
+			case JPEG_MARKER_DHT:
+				if (OJPEGReadHeaderInfoSecStreamDht(tif)==0)
+					return(0);
+				break;
+			case JPEG_MARKER_SOF0:
+			case JPEG_MARKER_SOF1:
+			case JPEG_MARKER_SOF3:
+				if (OJPEGReadHeaderInfoSecStreamSof(tif,m)==0)
+					return(0);
+				if (sp->subsamplingcorrect!=0)
+					return(1);
+				break;
+			case JPEG_MARKER_SOS:
+				if (sp->subsamplingcorrect!=0)
+					return(1);
+				assert(sp->plane_sample_offset==0);
+				if (OJPEGReadHeaderInfoSecStreamSos(tif)==0)
+					return(0);
+				break;
+			default:
+				TIFFErrorExt(tif->tif_clientdata,module,"Unknown marker type %d in JPEG data",m);
+				return(0);
+		}
+	} while(m!=JPEG_MARKER_SOS);
+	if (sp->subsamplingcorrect)
+		return(1);
+	if (sp->sof_log==0)
+	{
+		if (OJPEGReadHeaderInfoSecTablesQTable(tif)==0)
+			return(0);
+		sp->sof_marker_id=JPEG_MARKER_SOF0;
+		for (o=0; o<sp->samples_per_pixel; o++)
+			sp->sof_c[o]=o;
+		sp->sof_hv[0]=((sp->subsampling_hor<<4)|sp->subsampling_ver);
+		for (o=1; o<sp->samples_per_pixel; o++)
+			sp->sof_hv[o]=17;
+		sp->sof_x=sp->strile_width;
+		sp->sof_y=sp->strile_length_total;
+		sp->sof_log=1;
+		if (OJPEGReadHeaderInfoSecTablesDcTable(tif)==0)
+			return(0);
+		if (OJPEGReadHeaderInfoSecTablesAcTable(tif)==0)
+			return(0);
+		for (o=1; o<sp->samples_per_pixel; o++)
+			sp->sos_cs[o]=o;
+	}
+	return(1);
+}
+
+static int
+OJPEGReadHeaderInfoSecStreamDri(TIFF* tif)
+{
+	/* this could easilly cause trouble in some cases... but no such cases have occured sofar */
+	static const char module[]="OJPEGReadHeaderInfoSecStreamDri";
+	OJPEGState* sp=(OJPEGState*)tif->tif_data;
+	uint16 m;
+	if (OJPEGReadWord(sp,&m)==0)
+		return(0);
+	if (m!=4)
+	{
+		TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DRI marker in JPEG data");
+		return(0);
+	}
+	if (OJPEGReadWord(sp,&m)==0)
+		return(0);
+	sp->restart_interval=m;
+	return(1);
+}
+
+static int
+OJPEGReadHeaderInfoSecStreamDqt(TIFF* tif)
+{
+	/* this is a table marker, and it is to be saved as a whole for exact pushing on the jpeg stream later on */
+	static const char module[]="OJPEGReadHeaderInfoSecStreamDqt";
+	OJPEGState* sp=(OJPEGState*)tif->tif_data;
+	uint16 m;
+	uint32 na;
+	uint8* nb;
+	uint8 o;
+	if (OJPEGReadWord(sp,&m)==0)
+		return(0);
+	if (m<=2)
+	{
+		if (sp->subsamplingcorrect==0)
+			TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DQT marker in JPEG data");
+		return(0);
+	}
+	if (sp->subsamplingcorrect!=0)
+		OJPEGReadSkip(sp,m-2);
+	else
+	{
+		m-=2;
+		do
+		{
+			if (m<65)
+			{
+				TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DQT marker in JPEG data");
+				return(0);
+			}
+			na=sizeof(uint32)+69;
+			nb=_TIFFmalloc(na);
+			if (nb==0)
+			{
+				TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+				return(0);
+			}
+			*(uint32*)nb=na;
+			nb[sizeof(uint32)]=255;
+			nb[sizeof(uint32)+1]=JPEG_MARKER_DQT;
+			nb[sizeof(uint32)+2]=0;
+			nb[sizeof(uint32)+3]=67;
+			if (OJPEGReadBlock(sp,65,&nb[sizeof(uint32)+4])==0) {
+				_TIFFfree(nb);
+				return(0);
+			}
+			o=nb[sizeof(uint32)+4]&15;
+			if (3<o)
+			{
+				TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DQT marker in JPEG data");
+				_TIFFfree(nb);
+				return(0);
+			}
+			if (sp->qtable[o]!=0)
+				_TIFFfree(sp->qtable[o]);
+			sp->qtable[o]=nb;
+			m-=65;
+		} while(m>0);
+	}
+	return(1);
+}
+
+static int
+OJPEGReadHeaderInfoSecStreamDht(TIFF* tif)
+{
+	/* this is a table marker, and it is to be saved as a whole for exact pushing on the jpeg stream later on */
+	/* TODO: the following assumes there is only one table in this marker... but i'm not quite sure that assumption is guaranteed correct */
+	static const char module[]="OJPEGReadHeaderInfoSecStreamDht";
+	OJPEGState* sp=(OJPEGState*)tif->tif_data;
+	uint16 m;
+	uint32 na;
+	uint8* nb;
+	uint8 o;
+	if (OJPEGReadWord(sp,&m)==0)
+		return(0);
+	if (m<=2)
+	{
+		if (sp->subsamplingcorrect==0)
+			TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data");
+		return(0);
+	}
+	if (sp->subsamplingcorrect!=0)
+	{
+		OJPEGReadSkip(sp,m-2);
+	}
+	else
+	{
+		na=sizeof(uint32)+2+m;
+		nb=_TIFFmalloc(na);
+		if (nb==0)
+		{
+			TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+			return(0);
+		}
+		*(uint32*)nb=na;
+		nb[sizeof(uint32)]=255;
+		nb[sizeof(uint32)+1]=JPEG_MARKER_DHT;
+		nb[sizeof(uint32)+2]=(m>>8);
+		nb[sizeof(uint32)+3]=(m&255);
+		if (OJPEGReadBlock(sp,m-2,&nb[sizeof(uint32)+4])==0)
+			return(0);
+		o=nb[sizeof(uint32)+4];
+		if ((o&240)==0)
+		{
+			if (3<o)
+			{
+				TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data");
+				return(0);
+			}
+			if (sp->dctable[o]!=0)
+				_TIFFfree(sp->dctable[o]);
+			sp->dctable[o]=nb;
+		}
+		else
+		{
+			if ((o&240)!=16)
+			{
+				TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data");
+				return(0);
+			}
+			o&=15;
+			if (3<o)
+			{
+				TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data");
+				return(0);
+			}
+			if (sp->actable[o]!=0)
+				_TIFFfree(sp->actable[o]);
+			sp->actable[o]=nb;
+		}
+	}
+	return(1);
+}
+
+static int
+OJPEGReadHeaderInfoSecStreamSof(TIFF* tif, uint8 marker_id)
+{
+	/* this marker needs to be checked, and part of its data needs to be saved for regeneration later on */
+	static const char module[]="OJPEGReadHeaderInfoSecStreamSof";
+	OJPEGState* sp=(OJPEGState*)tif->tif_data;
+	uint16 m;
+	uint16 n;
+	uint8 o;
+	uint16 p;
+	uint16 q;
+	if (sp->sof_log!=0)
+	{
+		TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JPEG data");
+		return(0);
+	}
+	if (sp->subsamplingcorrect==0)
+		sp->sof_marker_id=marker_id;
+	/* Lf: data length */
+	if (OJPEGReadWord(sp,&m)==0)
+		return(0);
+	if (m<11)
+	{
+		if (sp->subsamplingcorrect==0)
+			TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOF marker in JPEG data");
+		return(0);
+	}
+	m-=8;
+	if (m%3!=0)
+	{
+		if (sp->subsamplingcorrect==0)
+			TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOF marker in JPEG data");
+		return(0);
+	}
+	n=m/3;
+	if (sp->subsamplingcorrect==0)
+	{
+		if (n!=sp->samples_per_pixel)
+		{
+			TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected number of samples");
+			return(0);
+		}
+	}
+	/* P: Sample precision */
+	if (OJPEGReadByte(sp,&o)==0)
+		return(0);
+	if (o!=8)
+	{
+		if (sp->subsamplingcorrect==0)
+			TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected number of bits per sample");
+		return(0);
+	}
+	/* Y: Number of lines, X: Number of samples per line */
+	if (sp->subsamplingcorrect)
+		OJPEGReadSkip(sp,4);
+	else
+	{
+		/* Y: Number of lines */
+		if (OJPEGReadWord(sp,&p)==0)
+			return(0);
+		if (((uint32)p<sp->image_length) && ((uint32)p<sp->strile_length_total))
+		{
+			TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected height");
+			return(0);
+		}
+		sp->sof_y=p;
+		/* X: Number of samples per line */
+		if (OJPEGReadWord(sp,&p)==0)
+			return(0);
+		if (((uint32)p<sp->image_width) && ((uint32)p<sp->strile_width))
+		{
+			TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected width");
+			return(0);
+		}
+		if ((uint32)p>sp->strile_width)
+		{
+			TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data image width exceeds expected image width");
+			return(0);
+		}
+		sp->sof_x=p;
+	}
+	/* Nf: Number of image components in frame */
+	if (OJPEGReadByte(sp,&o)==0)
+		return(0);
+	if (o!=n)
+	{
+		if (sp->subsamplingcorrect==0)
+			TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOF marker in JPEG data");
+		return(0);
+	}
+	/* per component stuff */
+	/* TODO: double-check that flow implies that n cannot be as big as to make us overflow sof_c, sof_hv and sof_tq arrays */
+	for (q=0; q<n; q++)
+	{
+		/* C: Component identifier */
+		if (OJPEGReadByte(sp,&o)==0)
+			return(0);
+		if (sp->subsamplingcorrect==0)
+			sp->sof_c[q]=o;
+		/* H: Horizontal sampling factor, and V: Vertical sampling factor */
+		if (OJPEGReadByte(sp,&o)==0)
+			return(0);
+		if (sp->subsamplingcorrect!=0)
+		{
+			if (q==0)
+			{
+				sp->subsampling_hor=(o>>4);
+				sp->subsampling_ver=(o&15);
+				if (((sp->subsampling_hor!=1) && (sp->subsampling_hor!=2) && (sp->subsampling_hor!=4)) ||
+					((sp->subsampling_ver!=1) && (sp->subsampling_ver!=2) && (sp->subsampling_ver!=4)))
+					sp->subsampling_force_desubsampling_inside_decompression=1;
+			}
+			else
+			{
+				if (o!=17)
+					sp->subsampling_force_desubsampling_inside_decompression=1;
+			}
+		}
+		else
+		{
+			sp->sof_hv[q]=o;
+			if (sp->subsampling_force_desubsampling_inside_decompression==0)
+			{
+				if (q==0)
+				{
+					if (o!=((sp->subsampling_hor<<4)|sp->subsampling_ver))
+					{
+						TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected subsampling values");
+						return(0);
+					}
+				}
+				else
+				{
+					if (o!=17)
+					{
+						TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected subsampling values");
+						return(0);
+					}
+				}
+			}
+		}
+		/* Tq: Quantization table destination selector */
+		if (OJPEGReadByte(sp,&o)==0)
+			return(0);
+		if (sp->subsamplingcorrect==0)
+			sp->sof_tq[q]=o;
+	}
+	if (sp->subsamplingcorrect==0)
+		sp->sof_log=1;
+	return(1);
+}
+
+static int
+OJPEGReadHeaderInfoSecStreamSos(TIFF* tif)
+{
+	/* this marker needs to be checked, and part of its data needs to be saved for regeneration later on */
+	static const char module[]="OJPEGReadHeaderInfoSecStreamSos";
+	OJPEGState* sp=(OJPEGState*)tif->tif_data;
+	uint16 m;
+	uint8 n;
+	uint8 o;
+	assert(sp->subsamplingcorrect==0);
+	if (sp->sof_log==0)
+	{
+		TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOS marker in JPEG data");
+		return(0);
+	}
+	/* Ls */
+	if (OJPEGReadWord(sp,&m)==0)
+		return(0);
+	if (m!=6+sp->samples_per_pixel_per_plane*2)
+	{
+		TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOS marker in JPEG data");
+		return(0);
+	}
+	/* Ns */
+	if (OJPEGReadByte(sp,&n)==0)
+		return(0);
+	if (n!=sp->samples_per_pixel_per_plane)
+	{
+		TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOS marker in JPEG data");
+		return(0);
+	}
+	/* Cs, Td, and Ta */
+	for (o=0; o<sp->samples_per_pixel_per_plane; o++)
+	{
+		/* Cs */
+		if (OJPEGReadByte(sp,&n)==0)
+			return(0);
+		sp->sos_cs[sp->plane_sample_offset+o]=n;
+		/* Td and Ta */
+		if (OJPEGReadByte(sp,&n)==0)
+			return(0);
+		sp->sos_tda[sp->plane_sample_offset+o]=n;
+	}
+	/* skip Ss, Se, Ah, en Al -> no check, as per Tom Lane recommendation, as per LibJpeg source */
+	OJPEGReadSkip(sp,3);
+	return(1);
+}
+
+static int
+OJPEGReadHeaderInfoSecTablesQTable(TIFF* tif)
+{
+	static const char module[]="OJPEGReadHeaderInfoSecTablesQTable";
+	OJPEGState* sp=(OJPEGState*)tif->tif_data;
+	uint8 m;
+	uint8 n;
+	uint32 oa;
+	uint8* ob;
+	uint32 p;
+	if (sp->qtable_offset[0]==0)
+	{
+		TIFFErrorExt(tif->tif_clientdata,module,"Missing JPEG tables");
+		return(0);
+	}
+	sp->in_buffer_file_pos_log=0;
+	for (m=0; m<sp->samples_per_pixel; m++)
+	{
+		if ((sp->qtable_offset[m]!=0) && ((m==0) || (sp->qtable_offset[m]!=sp->qtable_offset[m-1])))
+		{
+			for (n=0; n<m-1; n++)
+			{
+				if (sp->qtable_offset[m]==sp->qtable_offset[n])
+				{
+					TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JpegQTables tag value");
+					return(0);
+				}
+			}
+			oa=sizeof(uint32)+69;
+			ob=_TIFFmalloc(oa);
+			if (ob==0)
+			{
+				TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+				return(0);
+			}
+			*(uint32*)ob=oa;
+			ob[sizeof(uint32)]=255;
+			ob[sizeof(uint32)+1]=JPEG_MARKER_DQT;
+			ob[sizeof(uint32)+2]=0;
+			ob[sizeof(uint32)+3]=67;
+			ob[sizeof(uint32)+4]=m;
+			TIFFSeekFile(tif,sp->qtable_offset[m],SEEK_SET); 
+			p=TIFFReadFile(tif,&ob[sizeof(uint32)+5],64);
+			if (p!=64)
+				return(0);
+			sp->qtable[m]=ob;
+			sp->sof_tq[m]=m;
+		}
+		else
+			sp->sof_tq[m]=sp->sof_tq[m-1];
+	}
+	return(1);
+}
+
+static int
+OJPEGReadHeaderInfoSecTablesDcTable(TIFF* tif)
+{
+	static const char module[]="OJPEGReadHeaderInfoSecTablesDcTable";
+	OJPEGState* sp=(OJPEGState*)tif->tif_data;
+	uint8 m;
+	uint8 n;
+	uint8 o[16];
+	uint32 p;
+	uint32 q;
+	uint32 ra;
+	uint8* rb;
+	if (sp->dctable_offset[0]==0)
+	{
+		TIFFErrorExt(tif->tif_clientdata,module,"Missing JPEG tables");
+		return(0);
+	}
+	sp->in_buffer_file_pos_log=0;
+	for (m=0; m<sp->samples_per_pixel; m++)
+	{
+		if ((sp->dctable_offset[m]!=0) && ((m==0) || (sp->dctable_offset[m]!=sp->dctable_offset[m-1])))
+		{
+			for (n=0; n<m-1; n++)
+			{
+				if (sp->dctable_offset[m]==sp->dctable_offset[n])
+				{
+					TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JpegDcTables tag value");
+					return(0);
+				}
+			}
+			TIFFSeekFile(tif,sp->dctable_offset[m],SEEK_SET);
+			p=TIFFReadFile(tif,o,16);
+			if (p!=16)
+				return(0);
+			q=0;
+			for (n=0; n<16; n++)
+				q+=o[n];
+			ra=sizeof(uint32)+21+q;
+			rb=_TIFFmalloc(ra);
+			if (rb==0)
+			{
+				TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+				return(0);
+			}
+			*(uint32*)rb=ra;
+			rb[sizeof(uint32)]=255;
+			rb[sizeof(uint32)+1]=JPEG_MARKER_DHT;
+			rb[sizeof(uint32)+2]=((19+q)>>8);
+			rb[sizeof(uint32)+3]=((19+q)&255);
+			rb[sizeof(uint32)+4]=m;
+			for (n=0; n<16; n++)
+				rb[sizeof(uint32)+5+n]=o[n];
+			p=TIFFReadFile(tif,&(rb[sizeof(uint32)+21]),q);
+			if (p!=q)
+				return(0);
+			sp->dctable[m]=rb;
+			sp->sos_tda[m]=(m<<4);
+		}
+		else
+			sp->sos_tda[m]=sp->sos_tda[m-1];
+	}
+	return(1);
+}
+
+static int
+OJPEGReadHeaderInfoSecTablesAcTable(TIFF* tif)
+{
+	static const char module[]="OJPEGReadHeaderInfoSecTablesAcTable";
+	OJPEGState* sp=(OJPEGState*)tif->tif_data;
+	uint8 m;
+	uint8 n;
+	uint8 o[16];
+	uint32 p;
+	uint32 q;
+	uint32 ra;
+	uint8* rb;
+	if (sp->actable_offset[0]==0)
+	{
+		TIFFErrorExt(tif->tif_clientdata,module,"Missing JPEG tables");
+		return(0);
+	}
+	sp->in_buffer_file_pos_log=0;
+	for (m=0; m<sp->samples_per_pixel; m++)
+	{
+		if ((sp->actable_offset[m]!=0) && ((m==0) || (sp->actable_offset[m]!=sp->actable_offset[m-1])))
+		{
+			for (n=0; n<m-1; n++)
+			{
+				if (sp->actable_offset[m]==sp->actable_offset[n])
+				{
+					TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JpegAcTables tag value");
+					return(0);
+				}
+			}
+			TIFFSeekFile(tif,sp->actable_offset[m],SEEK_SET);  
+			p=TIFFReadFile(tif,o,16);
+			if (p!=16)
+				return(0);
+			q=0;
+			for (n=0; n<16; n++)
+				q+=o[n];
+			ra=sizeof(uint32)+21+q;
+			rb=_TIFFmalloc(ra);
+			if (rb==0)
+			{
+				TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+				return(0);
+			}
+			*(uint32*)rb=ra;
+			rb[sizeof(uint32)]=255;
+			rb[sizeof(uint32)+1]=JPEG_MARKER_DHT;
+			rb[sizeof(uint32)+2]=((19+q)>>8);
+			rb[sizeof(uint32)+3]=((19+q)&255);
+			rb[sizeof(uint32)+4]=(16|m);
+			for (n=0; n<16; n++)
+				rb[sizeof(uint32)+5+n]=o[n];
+			p=TIFFReadFile(tif,&(rb[sizeof(uint32)+21]),q);
+			if (p!=q)
+				return(0);
+			sp->actable[m]=rb;
+			sp->sos_tda[m]=(sp->sos_tda[m]|m);
+		}
+		else
+			sp->sos_tda[m]=(sp->sos_tda[m]|(sp->sos_tda[m-1]&15));
+	}
+	return(1);
+}
+
+static int
+OJPEGReadBufferFill(OJPEGState* sp)
+{
+	uint16 m;
+	tmsize_t n;
+	/* TODO: double-check: when subsamplingcorrect is set, no call to TIFFErrorExt or TIFFWarningExt should be made
+	 * in any other case, seek or read errors should be passed through */
+	do
+	{
+		if (sp->in_buffer_file_togo!=0)
+		{
+			if (sp->in_buffer_file_pos_log==0)
+			{
+				TIFFSeekFile(sp->tif,sp->in_buffer_file_pos,SEEK_SET);
+				sp->in_buffer_file_pos_log=1;
+			}
+			m=OJPEG_BUFFER;
+			if ((uint64)m>sp->in_buffer_file_togo)
+				m=(uint16)sp->in_buffer_file_togo;
+			n=TIFFReadFile(sp->tif,sp->in_buffer,(tmsize_t)m);
+			if (n==0)
+				return(0);
+			assert(n>0);
+			assert(n<=OJPEG_BUFFER);
+			assert(n<65536);
+			assert((uint64)n<=sp->in_buffer_file_togo);
+			m=(uint16)n;
+			sp->in_buffer_togo=m;
+			sp->in_buffer_cur=sp->in_buffer;
+			sp->in_buffer_file_togo-=m;
+			sp->in_buffer_file_pos+=m;
+			break;
+		}
+		sp->in_buffer_file_pos_log=0;
+		switch(sp->in_buffer_source)
+		{
+			case osibsNotSetYet:
+				if (sp->jpeg_interchange_format!=0)
+				{
+					sp->in_buffer_file_pos=sp->jpeg_interchange_format;
+					sp->in_buffer_file_togo=sp->jpeg_interchange_format_length;
+				}
+				sp->in_buffer_source=osibsJpegInterchangeFormat;
+				break;
+			case osibsJpegInterchangeFormat:
+				sp->in_buffer_source=osibsStrile;
+			case osibsStrile:
+				if (!_TIFFFillStriles( sp->tif ) 
+				    || sp->tif->tif_dir.td_stripoffset == NULL
+				    || sp->tif->tif_dir.td_stripbytecount == NULL)
+					return 0;
+
+				if (sp->in_buffer_next_strile==sp->in_buffer_strile_count)
+					sp->in_buffer_source=osibsEof;
+				else
+				{
+					sp->in_buffer_file_pos=sp->tif->tif_dir.td_stripoffset[sp->in_buffer_next_strile];
+					if (sp->in_buffer_file_pos!=0)
+					{
+						if (sp->in_buffer_file_pos>=sp->file_size)
+							sp->in_buffer_file_pos=0;
+						else if (sp->tif->tif_dir.td_stripbytecount==NULL)
+							sp->in_buffer_file_togo=sp->file_size-sp->in_buffer_file_pos;
+						else
+						{
+							if (sp->tif->tif_dir.td_stripbytecount == 0) {
+								TIFFErrorExt(sp->tif->tif_clientdata,sp->tif->tif_name,"Strip byte counts are missing");
+								return(0);
+							}
+							sp->in_buffer_file_togo=sp->tif->tif_dir.td_stripbytecount[sp->in_buffer_next_strile];
+							if (sp->in_buffer_file_togo==0)
+								sp->in_buffer_file_pos=0;
+							else if (sp->in_buffer_file_pos+sp->in_buffer_file_togo>sp->file_size)
+								sp->in_buffer_file_togo=sp->file_size-sp->in_buffer_file_pos;
+						}
+					}
+					sp->in_buffer_next_strile++;
+				}
+				break;
+			default:
+				return(0);
+		}
+	} while (1);
+	return(1);
+}
+
+static int
+OJPEGReadByte(OJPEGState* sp, uint8* byte)
+{
+	if (sp->in_buffer_togo==0)
+	{
+		if (OJPEGReadBufferFill(sp)==0)
+			return(0);
+		assert(sp->in_buffer_togo>0);
+	}
+	*byte=*(sp->in_buffer_cur);
+	sp->in_buffer_cur++;
+	sp->in_buffer_togo--;
+	return(1);
+}
+
+static int
+OJPEGReadBytePeek(OJPEGState* sp, uint8* byte)
+{
+	if (sp->in_buffer_togo==0)
+	{
+		if (OJPEGReadBufferFill(sp)==0)
+			return(0);
+		assert(sp->in_buffer_togo>0);
+	}
+	*byte=*(sp->in_buffer_cur);
+	return(1);
+}
+
+static void
+OJPEGReadByteAdvance(OJPEGState* sp)
+{
+	assert(sp->in_buffer_togo>0);
+	sp->in_buffer_cur++;
+	sp->in_buffer_togo--;
+}
+
+static int
+OJPEGReadWord(OJPEGState* sp, uint16* word)
+{
+	uint8 m;
+	if (OJPEGReadByte(sp,&m)==0)
+		return(0);
+	*word=(m<<8);
+	if (OJPEGReadByte(sp,&m)==0)
+		return(0);
+	*word|=m;
+	return(1);
+}
+
+static int
+OJPEGReadBlock(OJPEGState* sp, uint16 len, void* mem)
+{
+	uint16 mlen;
+	uint8* mmem;
+	uint16 n;
+	assert(len>0);
+	mlen=len;
+	mmem=mem;
+	do
+	{
+		if (sp->in_buffer_togo==0)
+		{
+			if (OJPEGReadBufferFill(sp)==0)
+				return(0);
+			assert(sp->in_buffer_togo>0);
+		}
+		n=mlen;
+		if (n>sp->in_buffer_togo)
+			n=sp->in_buffer_togo;
+		_TIFFmemcpy(mmem,sp->in_buffer_cur,n);
+		sp->in_buffer_cur+=n;
+		sp->in_buffer_togo-=n;
+		mlen-=n;
+		mmem+=n;
+	} while(mlen>0);
+	return(1);
+}
+
+static void
+OJPEGReadSkip(OJPEGState* sp, uint16 len)
+{
+	uint16 m;
+	uint16 n;
+	m=len;
+	n=m;
+	if (n>sp->in_buffer_togo)
+		n=sp->in_buffer_togo;
+	sp->in_buffer_cur+=n;
+	sp->in_buffer_togo-=n;
+	m-=n;
+	if (m>0)
+	{
+		assert(sp->in_buffer_togo==0);
+		n=m;
+		if ((uint64)n>sp->in_buffer_file_togo)
+			n=(uint16)sp->in_buffer_file_togo;
+		sp->in_buffer_file_pos+=n;
+		sp->in_buffer_file_togo-=n;
+		sp->in_buffer_file_pos_log=0;
+		/* we don't skip past jpeginterchangeformat/strile block...
+		 * if that is asked from us, we're dealing with totally bazurk
+		 * data anyway, and we've not seen this happening on any
+		 * testfile, so we might as well likely cause some other
+		 * meaningless error to be passed at some later time
+		 */
+	}
+}
+
+static int
+OJPEGWriteStream(TIFF* tif, void** mem, uint32* len)
+{
+	OJPEGState* sp=(OJPEGState*)tif->tif_data;
+	*len=0;
+	do
+	{
+		assert(sp->out_state<=ososEoi);
+		switch(sp->out_state)
+		{
+			case ososSoi:
+				OJPEGWriteStreamSoi(tif,mem,len);
+				break;
+			case ososQTable0:
+				OJPEGWriteStreamQTable(tif,0,mem,len);
+				break;
+			case ososQTable1:
+				OJPEGWriteStreamQTable(tif,1,mem,len);
+				break;
+			case ososQTable2:
+				OJPEGWriteStreamQTable(tif,2,mem,len);
+				break;
+			case ososQTable3:
+				OJPEGWriteStreamQTable(tif,3,mem,len);
+				break;
+			case ososDcTable0:
+				OJPEGWriteStreamDcTable(tif,0,mem,len);
+				break;
+			case ososDcTable1:
+				OJPEGWriteStreamDcTable(tif,1,mem,len);
+				break;
+			case ososDcTable2:
+				OJPEGWriteStreamDcTable(tif,2,mem,len);
+				break;
+			case ososDcTable3:
+				OJPEGWriteStreamDcTable(tif,3,mem,len);
+				break;
+			case ososAcTable0:
+				OJPEGWriteStreamAcTable(tif,0,mem,len);
+				break;
+			case ososAcTable1:
+				OJPEGWriteStreamAcTable(tif,1,mem,len);
+				break;
+			case ososAcTable2:
+				OJPEGWriteStreamAcTable(tif,2,mem,len);
+				break;
+			case ososAcTable3:
+				OJPEGWriteStreamAcTable(tif,3,mem,len);
+				break;
+			case ososDri:
+				OJPEGWriteStreamDri(tif,mem,len);
+				break;
+			case ososSof:
+				OJPEGWriteStreamSof(tif,mem,len);
+				break;
+			case ososSos:
+				OJPEGWriteStreamSos(tif,mem,len);
+				break;
+			case ososCompressed:
+				if (OJPEGWriteStreamCompressed(tif,mem,len)==0)
+					return(0);
+				break;
+			case ososRst:
+				OJPEGWriteStreamRst(tif,mem,len);
+				break;
+			case ososEoi:
+				OJPEGWriteStreamEoi(tif,mem,len);
+				break;
+		}
+	} while (*len==0);
+	return(1);
+}
+
+static void
+OJPEGWriteStreamSoi(TIFF* tif, void** mem, uint32* len)
+{
+	OJPEGState* sp=(OJPEGState*)tif->tif_data;
+	assert(OJPEG_BUFFER>=2);
+	sp->out_buffer[0]=255;
+	sp->out_buffer[1]=JPEG_MARKER_SOI;
+	*len=2;
+	*mem=(void*)sp->out_buffer;
+	sp->out_state++;
+}
+
+static void
+OJPEGWriteStreamQTable(TIFF* tif, uint8 table_index, void** mem, uint32* len)
+{
+	OJPEGState* sp=(OJPEGState*)tif->tif_data;
+	if (sp->qtable[table_index]!=0)
+	{
+		*mem=(void*)(sp->qtable[table_index]+sizeof(uint32));
+		*len=*((uint32*)sp->qtable[table_index])-sizeof(uint32);
+	}
+	sp->out_state++;
+}
+
+static void
+OJPEGWriteStreamDcTable(TIFF* tif, uint8 table_index, void** mem, uint32* len)
+{
+	OJPEGState* sp=(OJPEGState*)tif->tif_data;
+	if (sp->dctable[table_index]!=0)
+	{
+		*mem=(void*)(sp->dctable[table_index]+sizeof(uint32));
+		*len=*((uint32*)sp->dctable[table_index])-sizeof(uint32);
+	}
+	sp->out_state++;
+}
+
+static void
+OJPEGWriteStreamAcTable(TIFF* tif, uint8 table_index, void** mem, uint32* len)
+{
+	OJPEGState* sp=(OJPEGState*)tif->tif_data;
+	if (sp->actable[table_index]!=0)
+	{
+		*mem=(void*)(sp->actable[table_index]+sizeof(uint32));
+		*len=*((uint32*)sp->actable[table_index])-sizeof(uint32);
+	}
+	sp->out_state++;
+}
+
+static void
+OJPEGWriteStreamDri(TIFF* tif, void** mem, uint32* len)
+{
+	OJPEGState* sp=(OJPEGState*)tif->tif_data;
+	assert(OJPEG_BUFFER>=6);
+	if (sp->restart_interval!=0)
+	{
+		sp->out_buffer[0]=255;
+		sp->out_buffer[1]=JPEG_MARKER_DRI;
+		sp->out_buffer[2]=0;
+		sp->out_buffer[3]=4;
+		sp->out_buffer[4]=(sp->restart_interval>>8);
+		sp->out_buffer[5]=(sp->restart_interval&255);
+		*len=6;
+		*mem=(void*)sp->out_buffer;
+	}
+	sp->out_state++;
+}
+
+static void
+OJPEGWriteStreamSof(TIFF* tif, void** mem, uint32* len)
+{
+	OJPEGState* sp=(OJPEGState*)tif->tif_data;
+	uint8 m;
+	assert(OJPEG_BUFFER>=2+8+sp->samples_per_pixel_per_plane*3);
+	assert(255>=8+sp->samples_per_pixel_per_plane*3);
+	sp->out_buffer[0]=255;
+	sp->out_buffer[1]=sp->sof_marker_id;
+	/* Lf */
+	sp->out_buffer[2]=0;
+	sp->out_buffer[3]=8+sp->samples_per_pixel_per_plane*3;
+	/* P */
+	sp->out_buffer[4]=8;
+	/* Y */
+	sp->out_buffer[5]=(sp->sof_y>>8);
+	sp->out_buffer[6]=(sp->sof_y&255);
+	/* X */
+	sp->out_buffer[7]=(sp->sof_x>>8);
+	sp->out_buffer[8]=(sp->sof_x&255);
+	/* Nf */
+	sp->out_buffer[9]=sp->samples_per_pixel_per_plane;
+	for (m=0; m<sp->samples_per_pixel_per_plane; m++)
+	{
+		/* C */
+		sp->out_buffer[10+m*3]=sp->sof_c[sp->plane_sample_offset+m];
+		/* H and V */
+		sp->out_buffer[10+m*3+1]=sp->sof_hv[sp->plane_sample_offset+m];
+		/* Tq */
+		sp->out_buffer[10+m*3+2]=sp->sof_tq[sp->plane_sample_offset+m];
+	}
+	*len=10+sp->samples_per_pixel_per_plane*3;
+	*mem=(void*)sp->out_buffer;
+	sp->out_state++;
+}
+
+static void
+OJPEGWriteStreamSos(TIFF* tif, void** mem, uint32* len)
+{
+	OJPEGState* sp=(OJPEGState*)tif->tif_data;
+	uint8 m;
+	assert(OJPEG_BUFFER>=2+6+sp->samples_per_pixel_per_plane*2);
+	assert(255>=6+sp->samples_per_pixel_per_plane*2);
+	sp->out_buffer[0]=255;
+	sp->out_buffer[1]=JPEG_MARKER_SOS;
+	/* Ls */
+	sp->out_buffer[2]=0;
+	sp->out_buffer[3]=6+sp->samples_per_pixel_per_plane*2;
+	/* Ns */
+	sp->out_buffer[4]=sp->samples_per_pixel_per_plane;
+	for (m=0; m<sp->samples_per_pixel_per_plane; m++)
+	{
+		/* Cs */
+		sp->out_buffer[5+m*2]=sp->sos_cs[sp->plane_sample_offset+m];
+		/* Td and Ta */
+		sp->out_buffer[5+m*2+1]=sp->sos_tda[sp->plane_sample_offset+m];
+	}
+	/* Ss */
+	sp->out_buffer[5+sp->samples_per_pixel_per_plane*2]=0;
+	/* Se */
+	sp->out_buffer[5+sp->samples_per_pixel_per_plane*2+1]=63;
+	/* Ah and Al */
+	sp->out_buffer[5+sp->samples_per_pixel_per_plane*2+2]=0;
+	*len=8+sp->samples_per_pixel_per_plane*2;
+	*mem=(void*)sp->out_buffer;
+	sp->out_state++;
+}
+
+static int
+OJPEGWriteStreamCompressed(TIFF* tif, void** mem, uint32* len)
+{
+	OJPEGState* sp=(OJPEGState*)tif->tif_data;
+	if (sp->in_buffer_togo==0)
+	{
+		if (OJPEGReadBufferFill(sp)==0)
+			return(0);
+		assert(sp->in_buffer_togo>0);
+	}
+	*len=sp->in_buffer_togo;
+	*mem=(void*)sp->in_buffer_cur;
+	sp->in_buffer_togo=0;
+	if (sp->in_buffer_file_togo==0)
+	{
+		switch(sp->in_buffer_source)
+		{
+			case osibsStrile:
+				if (sp->in_buffer_next_strile<sp->in_buffer_strile_count)
+					sp->out_state=ososRst;
+				else
+					sp->out_state=ososEoi;
+				break;
+			case osibsEof:
+				sp->out_state=ososEoi;
+				break;
+			default:
+				break;
+		}
+	}
+	return(1);
+}
+
+static void
+OJPEGWriteStreamRst(TIFF* tif, void** mem, uint32* len)
+{
+	OJPEGState* sp=(OJPEGState*)tif->tif_data;
+	assert(OJPEG_BUFFER>=2);
+	sp->out_buffer[0]=255;
+	sp->out_buffer[1]=JPEG_MARKER_RST0+sp->restart_index;
+	sp->restart_index++;
+	if (sp->restart_index==8)
+		sp->restart_index=0;
+	*len=2;
+	*mem=(void*)sp->out_buffer;
+	sp->out_state=ososCompressed;
+}
+
+static void
+OJPEGWriteStreamEoi(TIFF* tif, void** mem, uint32* len)
+{
+	OJPEGState* sp=(OJPEGState*)tif->tif_data;
+	assert(OJPEG_BUFFER>=2);
+	sp->out_buffer[0]=255;
+	sp->out_buffer[1]=JPEG_MARKER_EOI;
+	*len=2;
+	*mem=(void*)sp->out_buffer;
+}
+
+#ifndef LIBJPEG_ENCAP_EXTERNAL
+static int
+jpeg_create_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo)
+{
+	return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_create_decompress(cinfo),1));
+}
+#endif
+
+#ifndef LIBJPEG_ENCAP_EXTERNAL
+static int
+jpeg_read_header_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, uint8 require_image)
+{
+	return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_read_header(cinfo,require_image),1));
+}
+#endif
+
+#ifndef LIBJPEG_ENCAP_EXTERNAL
+static int
+jpeg_start_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo)
+{
+	return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_start_decompress(cinfo),1));
+}
+#endif
+
+#ifndef LIBJPEG_ENCAP_EXTERNAL
+static int
+jpeg_read_scanlines_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* scanlines, uint32 max_lines)
+{
+	return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_read_scanlines(cinfo,scanlines,max_lines),1));
+}
+#endif
+
+#ifndef LIBJPEG_ENCAP_EXTERNAL
+static int
+jpeg_read_raw_data_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* data, uint32 max_lines)
+{
+	return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_read_raw_data(cinfo,data,max_lines),1));
+}
+#endif
+
+#ifndef LIBJPEG_ENCAP_EXTERNAL
+static void
+jpeg_encap_unwind(TIFF* tif)
+{
+	OJPEGState* sp=(OJPEGState*)tif->tif_data;
+	LONGJMP(sp->exit_jmpbuf,1);
+}
+#endif
+
+static void
+OJPEGLibjpegJpegErrorMgrOutputMessage(jpeg_common_struct* cinfo)
+{
+	char buffer[JMSG_LENGTH_MAX];
+	(*cinfo->err->format_message)(cinfo,buffer);
+	TIFFWarningExt(((TIFF*)(cinfo->client_data))->tif_clientdata,"LibJpeg","%s",buffer);
+}
+
+static void
+OJPEGLibjpegJpegErrorMgrErrorExit(jpeg_common_struct* cinfo)
+{
+	char buffer[JMSG_LENGTH_MAX];
+	(*cinfo->err->format_message)(cinfo,buffer);
+	TIFFErrorExt(((TIFF*)(cinfo->client_data))->tif_clientdata,"LibJpeg","%s",buffer);
+	jpeg_encap_unwind((TIFF*)(cinfo->client_data));
+}
+
+static void
+OJPEGLibjpegJpegSourceMgrInitSource(jpeg_decompress_struct* cinfo)
+{
+	(void)cinfo;
+}
+
+static boolean
+OJPEGLibjpegJpegSourceMgrFillInputBuffer(jpeg_decompress_struct* cinfo)
+{
+	TIFF* tif=(TIFF*)cinfo->client_data;
+	OJPEGState* sp=(OJPEGState*)tif->tif_data;
+	void* mem=0;
+	uint32 len=0U;
+	if (OJPEGWriteStream(tif,&mem,&len)==0)
+	{
+		TIFFErrorExt(tif->tif_clientdata,"LibJpeg","Premature end of JPEG data");
+		jpeg_encap_unwind(tif);
+	}
+	sp->libjpeg_jpeg_source_mgr.bytes_in_buffer=len;
+	sp->libjpeg_jpeg_source_mgr.next_input_byte=mem;
+	return(1);
+}
+
+static void
+OJPEGLibjpegJpegSourceMgrSkipInputData(jpeg_decompress_struct* cinfo, long num_bytes)
+{
+	TIFF* tif=(TIFF*)cinfo->client_data;
+	(void)num_bytes;
+	TIFFErrorExt(tif->tif_clientdata,"LibJpeg","Unexpected error");
+	jpeg_encap_unwind(tif);
+}
+
+static boolean
+OJPEGLibjpegJpegSourceMgrResyncToRestart(jpeg_decompress_struct* cinfo, int desired)
+{
+	TIFF* tif=(TIFF*)cinfo->client_data;
+	(void)desired;
+	TIFFErrorExt(tif->tif_clientdata,"LibJpeg","Unexpected error");
+	jpeg_encap_unwind(tif);
+	return(0);
+}
+
+static void
+OJPEGLibjpegJpegSourceMgrTermSource(jpeg_decompress_struct* cinfo)
+{
+	(void)cinfo;
+}
+
+#endif
+
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tif_open.c b/Source/LibTIFF4/tif_open.c
index 14cc6ee..7b0b7d6 100644
--- a/Source/LibTIFF4/tif_open.c
+++ b/Source/LibTIFF4/tif_open.c
@@ -1,725 +1,725 @@
-/* $Id: tif_open.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library.
- */
-#include "tiffiop.h"
-
-/*
- * Dummy functions to fill the omitted client procedures.
- */
-static int
-_tiffDummyMapProc(thandle_t fd, void** pbase, toff_t* psize)
-{
-	(void) fd; (void) pbase; (void) psize;
-	return (0);
-}
-
-static void
-_tiffDummyUnmapProc(thandle_t fd, void* base, toff_t size)
-{
-	(void) fd; (void) base; (void) size;
-}
-
-int
-_TIFFgetMode(const char* mode, const char* module)
-{
-	int m = -1;
-
-	switch (mode[0]) {
-	case 'r':
-		m = O_RDONLY;
-		if (mode[1] == '+')
-			m = O_RDWR;
-		break;
-	case 'w':
-	case 'a':
-		m = O_RDWR|O_CREAT;
-		if (mode[0] == 'w')
-			m |= O_TRUNC;
-		break;
-	default:
-		TIFFErrorExt(0, module, "\"%s\": Bad mode", mode);
-		break;
-	}
-	return (m);
-}
-
-TIFF*
-TIFFClientOpen(
-	const char* name, const char* mode,
-	thandle_t clientdata,
-	TIFFReadWriteProc readproc,
-	TIFFReadWriteProc writeproc,
-	TIFFSeekProc seekproc,
-	TIFFCloseProc closeproc,
-	TIFFSizeProc sizeproc,
-	TIFFMapFileProc mapproc,
-	TIFFUnmapFileProc unmapproc
-)
-{
-	static const char module[] = "TIFFClientOpen";
-	TIFF *tif;
-	int m;
-	const char* cp;
-
-	/* The following are configuration checks. They should be redundant, but should not
-	 * compile to any actual code in an optimised release build anyway. If any of them
-	 * fail, (makefile-based or other) configuration is not correct */
-	assert(sizeof(uint8)==1);
-	assert(sizeof(int8)==1);
-	assert(sizeof(uint16)==2);
-	assert(sizeof(int16)==2);
-	assert(sizeof(uint32)==4);
-	assert(sizeof(int32)==4);
-	assert(sizeof(uint64)==8);
-	assert(sizeof(int64)==8);
-	assert(sizeof(tmsize_t)==sizeof(void*));
-	{
-		union{
-			uint8 a8[2];
-			uint16 a16;
-		} n;
-		n.a8[0]=1;
-		n.a8[1]=0;
-		#ifdef WORDS_BIGENDIAN
-		assert(n.a16==256);
-		#else
-		assert(n.a16==1);
-		#endif
-	}
-
-	m = _TIFFgetMode(mode, module);
-	if (m == -1)
-		goto bad2;
-	tif = (TIFF *)_TIFFmalloc((tmsize_t)(sizeof (TIFF) + strlen(name) + 1));
-	if (tif == NULL) {
-		TIFFErrorExt(clientdata, module, "%s: Out of memory (TIFF structure)", name);
-		goto bad2;
-	}
-	_TIFFmemset(tif, 0, sizeof (*tif));
-	tif->tif_name = (char *)tif + sizeof (TIFF);
-	strcpy(tif->tif_name, name);
-	tif->tif_mode = m &~ (O_CREAT|O_TRUNC);
-	tif->tif_curdir = (uint16) -1;		/* non-existent directory */
-	tif->tif_curoff = 0;
-	tif->tif_curstrip = (uint32) -1;	/* invalid strip */
-	tif->tif_row = (uint32) -1;		/* read/write pre-increment */
-	tif->tif_clientdata = clientdata;
-	if (!readproc || !writeproc || !seekproc || !closeproc || !sizeproc) {
-		TIFFErrorExt(clientdata, module,
-		    "One of the client procedures is NULL pointer.");
-		goto bad2;
-	}
-	tif->tif_readproc = readproc;
-	tif->tif_writeproc = writeproc;
-	tif->tif_seekproc = seekproc;
-	tif->tif_closeproc = closeproc;
-	tif->tif_sizeproc = sizeproc;
-	if (mapproc)
-		tif->tif_mapproc = mapproc;
-	else
-		tif->tif_mapproc = _tiffDummyMapProc;
-	if (unmapproc)
-		tif->tif_unmapproc = unmapproc;
-	else
-		tif->tif_unmapproc = _tiffDummyUnmapProc;
-	_TIFFSetDefaultCompressionState(tif);    /* setup default state */
-	/*
-	 * Default is to return data MSB2LSB and enable the
-	 * use of memory-mapped files and strip chopping when
-	 * a file is opened read-only.
-	 */
-	tif->tif_flags = FILLORDER_MSB2LSB;
-	if (m == O_RDONLY )
-		tif->tif_flags |= TIFF_MAPPED;
-
-	#ifdef STRIPCHOP_DEFAULT
-	if (m == O_RDONLY || m == O_RDWR)
-		tif->tif_flags |= STRIPCHOP_DEFAULT;
-	#endif
-
-	/*
-	 * Process library-specific flags in the open mode string.
-	 * The following flags may be used to control intrinsic library
-	 * behaviour that may or may not be desirable (usually for
-	 * compatibility with some application that claims to support
-	 * TIFF but only supports some braindead idea of what the
-	 * vendor thinks TIFF is):
-	 *
-	 * 'l' use little-endian byte order for creating a file
-	 * 'b' use big-endian byte order for creating a file
-	 * 'L' read/write information using LSB2MSB bit order
-	 * 'B' read/write information using MSB2LSB bit order
-	 * 'H' read/write information using host bit order
-	 * 'M' enable use of memory-mapped files when supported
-	 * 'm' disable use of memory-mapped files
-	 * 'C' enable strip chopping support when reading
-	 * 'c' disable strip chopping support
-	 * 'h' read TIFF header only, do not load the first IFD
-	 * '4' ClassicTIFF for creating a file (default)
-	 * '8' BigTIFF for creating a file
-	 *
-	 * The use of the 'l' and 'b' flags is strongly discouraged.
-	 * These flags are provided solely because numerous vendors,
-	 * typically on the PC, do not correctly support TIFF; they
-	 * only support the Intel little-endian byte order.  This
-	 * support is not configured by default because it supports
-	 * the violation of the TIFF spec that says that readers *MUST*
-	 * support both byte orders.  It is strongly recommended that
-	 * you not use this feature except to deal with busted apps
-	 * that write invalid TIFF.  And even in those cases you should
-	 * bang on the vendors to fix their software.
-	 *
-	 * The 'L', 'B', and 'H' flags are intended for applications
-	 * that can optimize operations on data by using a particular
-	 * bit order.  By default the library returns data in MSB2LSB
-	 * bit order for compatibiltiy with older versions of this
-	 * library.  Returning data in the bit order of the native cpu
-	 * makes the most sense but also requires applications to check
-	 * the value of the FillOrder tag; something they probably do
-	 * not do right now.
-	 *
-	 * The 'M' and 'm' flags are provided because some virtual memory
-	 * systems exhibit poor behaviour when large images are mapped.
-	 * These options permit clients to control the use of memory-mapped
-	 * files on a per-file basis.
-	 *
-	 * The 'C' and 'c' flags are provided because the library support
-	 * for chopping up large strips into multiple smaller strips is not
-	 * application-transparent and as such can cause problems.  The 'c'
-	 * option permits applications that only want to look at the tags,
-	 * for example, to get the unadulterated TIFF tag information.
-	 */
-	for (cp = mode; *cp; cp++)
-		switch (*cp) {
-			case 'b':
-				#ifndef WORDS_BIGENDIAN
-				if (m&O_CREAT)
-					tif->tif_flags |= TIFF_SWAB;
-				#endif
-				break;
-			case 'l':
-				#ifdef WORDS_BIGENDIAN
-				if ((m&O_CREAT))
-					tif->tif_flags |= TIFF_SWAB;
-				#endif
-				break;
-			case 'B':
-				tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) |
-				    FILLORDER_MSB2LSB;
-				break;
-			case 'L':
-				tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) |
-				    FILLORDER_LSB2MSB;
-				break;
-			case 'H':
-				tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) |
-				    HOST_FILLORDER;
-				break;
-			case 'M':
-				if (m == O_RDONLY)
-					tif->tif_flags |= TIFF_MAPPED;
-				break;
-			case 'm':
-				if (m == O_RDONLY)
-					tif->tif_flags &= ~TIFF_MAPPED;
-				break;
-			case 'C':
-				if (m == O_RDONLY)
-					tif->tif_flags |= TIFF_STRIPCHOP;
-				break;
-			case 'c':
-				if (m == O_RDONLY)
-					tif->tif_flags &= ~TIFF_STRIPCHOP;
-				break;
-			case 'h':
-				tif->tif_flags |= TIFF_HEADERONLY;
-				break;
-			case '8':
-				if (m&O_CREAT)
-					tif->tif_flags |= TIFF_BIGTIFF;
-				break;
-		}
-	/*
-	 * Read in TIFF header.
-	 */
-	if ((m & O_TRUNC) ||
-	    !ReadOK(tif, &tif->tif_header, sizeof (TIFFHeaderClassic))) {
-		if (tif->tif_mode == O_RDONLY) {
-			TIFFErrorExt(tif->tif_clientdata, name,
-			    "Cannot read TIFF header");
-			goto bad;
-		}
-		/*
-		 * Setup header and write.
-		 */
-		#ifdef WORDS_BIGENDIAN
-		tif->tif_header.common.tiff_magic = tif->tif_flags & TIFF_SWAB
-		    ? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN;
-		#else
-		tif->tif_header.common.tiff_magic = tif->tif_flags & TIFF_SWAB
-		    ? TIFF_BIGENDIAN : TIFF_LITTLEENDIAN;
-		#endif
-		if (!(tif->tif_flags&TIFF_BIGTIFF))
-		{
-			tif->tif_header.common.tiff_version = TIFF_VERSION_CLASSIC;
-			tif->tif_header.classic.tiff_diroff = 0;
-			if (tif->tif_flags & TIFF_SWAB)
-				TIFFSwabShort(&tif->tif_header.common.tiff_version);
-			tif->tif_header_size = sizeof(TIFFHeaderClassic);
-		}
-		else
-		{
-			tif->tif_header.common.tiff_version = TIFF_VERSION_BIG;
-			tif->tif_header.big.tiff_offsetsize = 8;
-			tif->tif_header.big.tiff_unused = 0;
-			tif->tif_header.big.tiff_diroff = 0;
-			if (tif->tif_flags & TIFF_SWAB)
-			{
-				TIFFSwabShort(&tif->tif_header.common.tiff_version);
-				TIFFSwabShort(&tif->tif_header.big.tiff_offsetsize);
-			}
-			tif->tif_header_size = sizeof (TIFFHeaderBig);
-		}
-		/*
-		 * The doc for "fopen" for some STD_C_LIBs says that if you
-		 * open a file for modify ("+"), then you must fseek (or
-		 * fflush?) between any freads and fwrites.  This is not
-		 * necessary on most systems, but has been shown to be needed
-		 * on Solaris.
-		 */
-		TIFFSeekFile( tif, 0, SEEK_SET );
-		if (!WriteOK(tif, &tif->tif_header, (tmsize_t)(tif->tif_header_size))) {
-			TIFFErrorExt(tif->tif_clientdata, name,
-			    "Error writing TIFF header");
-			goto bad;
-		}
-		/*
-		 * Setup the byte order handling.
-		 */
-		if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN) {
-			#ifndef WORDS_BIGENDIAN
-			tif->tif_flags |= TIFF_SWAB;
-			#endif
-		} else {
-			#ifdef WORDS_BIGENDIAN
-			tif->tif_flags |= TIFF_SWAB;
-			#endif
-		}
-		/*
-		 * Setup default directory.
-		 */
-		if (!TIFFDefaultDirectory(tif))
-			goto bad;
-		tif->tif_diroff = 0;
-		tif->tif_dirlist = NULL;
-		tif->tif_dirlistsize = 0;
-		tif->tif_dirnumber = 0;
-		return (tif);
-	}
-	/*
-	 * Setup the byte order handling.
-	 */
-	if (tif->tif_header.common.tiff_magic != TIFF_BIGENDIAN &&
-	    tif->tif_header.common.tiff_magic != TIFF_LITTLEENDIAN
-	    #if MDI_SUPPORT
-	    &&
-	    #if HOST_BIGENDIAN
-	    tif->tif_header.common.tiff_magic != MDI_BIGENDIAN
-	    #else
-	    tif->tif_header.common.tiff_magic != MDI_LITTLEENDIAN
-	    #endif
-	    ) {
-		TIFFErrorExt(tif->tif_clientdata, name,
-		    "Not a TIFF or MDI file, bad magic number %d (0x%x)",
-	    #else
-	    ) {
-		TIFFErrorExt(tif->tif_clientdata, name,
-		    "Not a TIFF file, bad magic number %d (0x%x)",
-	    #endif
-		    tif->tif_header.common.tiff_magic,
-		    tif->tif_header.common.tiff_magic);
-		goto bad;
-	}
-	if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN) {
-		#ifndef WORDS_BIGENDIAN
-		tif->tif_flags |= TIFF_SWAB;
-		#endif
-	} else {
-		#ifdef WORDS_BIGENDIAN
-		tif->tif_flags |= TIFF_SWAB;
-		#endif
-	}
-	if (tif->tif_flags & TIFF_SWAB) 
-		TIFFSwabShort(&tif->tif_header.common.tiff_version);
-	if ((tif->tif_header.common.tiff_version != TIFF_VERSION_CLASSIC)&&
-	    (tif->tif_header.common.tiff_version != TIFF_VERSION_BIG)) {
-		TIFFErrorExt(tif->tif_clientdata, name,
-		    "Not a TIFF file, bad version number %d (0x%x)",
-		    tif->tif_header.common.tiff_version,
-		    tif->tif_header.common.tiff_version);
-		goto bad;
-	}
-	if (tif->tif_header.common.tiff_version == TIFF_VERSION_CLASSIC)
-	{
-		if (tif->tif_flags & TIFF_SWAB)
-			TIFFSwabLong(&tif->tif_header.classic.tiff_diroff);
-		tif->tif_header_size = sizeof(TIFFHeaderClassic);
-	}
-	else
-	{
-		if (!ReadOK(tif, ((uint8*)(&tif->tif_header) + sizeof(TIFFHeaderClassic)), (sizeof(TIFFHeaderBig)-sizeof(TIFFHeaderClassic))))
-		{
-			TIFFErrorExt(tif->tif_clientdata, name,
-			    "Cannot read TIFF header");
-			goto bad;
-		}
-		if (tif->tif_flags & TIFF_SWAB)
-		{
-			TIFFSwabShort(&tif->tif_header.big.tiff_offsetsize);
-			TIFFSwabLong8(&tif->tif_header.big.tiff_diroff);
-		}
-		if (tif->tif_header.big.tiff_offsetsize != 8)
-		{
-			TIFFErrorExt(tif->tif_clientdata, name,
-			    "Not a TIFF file, bad BigTIFF offsetsize %d (0x%x)",
-			    tif->tif_header.big.tiff_offsetsize,
-			    tif->tif_header.big.tiff_offsetsize);
-			goto bad;
-		}
-		if (tif->tif_header.big.tiff_unused != 0)
-		{
-			TIFFErrorExt(tif->tif_clientdata, name,
-			    "Not a TIFF file, bad BigTIFF unused %d (0x%x)",
-			    tif->tif_header.big.tiff_unused,
-			    tif->tif_header.big.tiff_unused);
-			goto bad;
-		}
-		tif->tif_header_size = sizeof(TIFFHeaderBig);
-		tif->tif_flags |= TIFF_BIGTIFF;
-	}
-	tif->tif_flags |= TIFF_MYBUFFER;
-	tif->tif_rawcp = tif->tif_rawdata = 0;
-	tif->tif_rawdatasize = 0;
-        tif->tif_rawdataoff = 0;
-        tif->tif_rawdataloaded = 0;
-
-	switch (mode[0]) {
-		case 'r':
-			if (!(tif->tif_flags&TIFF_BIGTIFF))
-				tif->tif_nextdiroff = tif->tif_header.classic.tiff_diroff;
-			else
-				tif->tif_nextdiroff = tif->tif_header.big.tiff_diroff;
-			/*
-			 * Try to use a memory-mapped file if the client
-			 * has not explicitly suppressed usage with the
-			 * 'm' flag in the open mode (see above).
-			 */
-			if (tif->tif_flags & TIFF_MAPPED)
-			{
-				toff_t n;
-				if (TIFFMapFileContents(tif,(void**)(&tif->tif_base),&n))
-				{
-					tif->tif_size=(tmsize_t)n;
-					assert((toff_t)tif->tif_size==n);
-				}
-				else
-					tif->tif_flags &= ~TIFF_MAPPED;
-			}
-			/*
-			 * Sometimes we do not want to read the first directory (for example,
-			 * it may be broken) and want to proceed to other directories. I this
-			 * case we use the TIFF_HEADERONLY flag to open file and return
-			 * immediately after reading TIFF header.
-			 */
-			if (tif->tif_flags & TIFF_HEADERONLY)
-				return (tif);
-
-			/*
-			 * Setup initial directory.
-			 */
-			if (TIFFReadDirectory(tif)) {
-				tif->tif_rawcc = (tmsize_t)-1;
-				tif->tif_flags |= TIFF_BUFFERSETUP;
-				return (tif);
-			}
-			break;
-		case 'a':
-			/*
-			 * New directories are automatically append
-			 * to the end of the directory chain when they
-			 * are written out (see TIFFWriteDirectory).
-			 */
-			if (!TIFFDefaultDirectory(tif))
-				goto bad;
-			return (tif);
-	}
-bad:
-	tif->tif_mode = O_RDONLY;	/* XXX avoid flush */
-        TIFFCleanup(tif);
-bad2:
-	return ((TIFF*)0);
-}
-
-/*
- * Query functions to access private data.
- */
-
-/*
- * Return open file's name.
- */
-const char *
-TIFFFileName(TIFF* tif)
-{
-	return (tif->tif_name);
-}
-
-/*
- * Set the file name.
- */
-const char *
-TIFFSetFileName(TIFF* tif, const char *name)
-{
-	const char* old_name = tif->tif_name;
-	tif->tif_name = (char *)name;
-	return (old_name);
-}
-
-/*
- * Return open file's I/O descriptor.
- */
-int
-TIFFFileno(TIFF* tif)
-{
-	return (tif->tif_fd);
-}
-
-/*
- * Set open file's I/O descriptor, and return previous value.
- */
-int
-TIFFSetFileno(TIFF* tif, int fd)
-{
-        int old_fd = tif->tif_fd;
-	tif->tif_fd = fd;
-	return old_fd;
-}
-
-/*
- * Return open file's clientdata.
- */
-thandle_t
-TIFFClientdata(TIFF* tif)
-{
-	return (tif->tif_clientdata);
-}
-
-/*
- * Set open file's clientdata, and return previous value.
- */
-thandle_t
-TIFFSetClientdata(TIFF* tif, thandle_t newvalue)
-{
-	thandle_t m = tif->tif_clientdata;
-	tif->tif_clientdata = newvalue;
-	return m;
-}
-
-/*
- * Return read/write mode.
- */
-int
-TIFFGetMode(TIFF* tif)
-{
-	return (tif->tif_mode);
-}
-
-/*
- * Return read/write mode.
- */
-int
-TIFFSetMode(TIFF* tif, int mode)
-{
-	int old_mode = tif->tif_mode;
-	tif->tif_mode = mode;
-	return (old_mode);
-}
-
-/*
- * Return nonzero if file is organized in
- * tiles; zero if organized as strips.
- */
-int
-TIFFIsTiled(TIFF* tif)
-{
-	return (isTiled(tif));
-}
-
-/*
- * Return current row being read/written.
- */
-uint32
-TIFFCurrentRow(TIFF* tif)
-{
-	return (tif->tif_row);
-}
-
-/*
- * Return index of the current directory.
- */
-uint16
-TIFFCurrentDirectory(TIFF* tif)
-{
-	return (tif->tif_curdir);
-}
-
-/*
- * Return current strip.
- */
-uint32
-TIFFCurrentStrip(TIFF* tif)
-{
-	return (tif->tif_curstrip);
-}
-
-/*
- * Return current tile.
- */
-uint32
-TIFFCurrentTile(TIFF* tif)
-{
-	return (tif->tif_curtile);
-}
-
-/*
- * Return nonzero if the file has byte-swapped data.
- */
-int
-TIFFIsByteSwapped(TIFF* tif)
-{
-	return ((tif->tif_flags & TIFF_SWAB) != 0);
-}
-
-/*
- * Return nonzero if the data is returned up-sampled.
- */
-int
-TIFFIsUpSampled(TIFF* tif)
-{
-	return (isUpSampled(tif));
-}
-
-/*
- * Return nonzero if the data is returned in MSB-to-LSB bit order.
- */
-int
-TIFFIsMSB2LSB(TIFF* tif)
-{
-	return (isFillOrder(tif, FILLORDER_MSB2LSB));
-}
-
-/*
- * Return nonzero if given file was written in big-endian order.
- */
-int
-TIFFIsBigEndian(TIFF* tif)
-{
-	return (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN);
-}
-
-/*
- * Return pointer to file read method.
- */
-TIFFReadWriteProc
-TIFFGetReadProc(TIFF* tif)
-{
-	return (tif->tif_readproc);
-}
-
-/*
- * Return pointer to file write method.
- */
-TIFFReadWriteProc
-TIFFGetWriteProc(TIFF* tif)
-{
-	return (tif->tif_writeproc);
-}
-
-/*
- * Return pointer to file seek method.
- */
-TIFFSeekProc
-TIFFGetSeekProc(TIFF* tif)
-{
-	return (tif->tif_seekproc);
-}
-
-/*
- * Return pointer to file close method.
- */
-TIFFCloseProc
-TIFFGetCloseProc(TIFF* tif)
-{
-	return (tif->tif_closeproc);
-}
-
-/*
- * Return pointer to file size requesting method.
- */
-TIFFSizeProc
-TIFFGetSizeProc(TIFF* tif)
-{
-	return (tif->tif_sizeproc);
-}
-
-/*
- * Return pointer to memory mapping method.
- */
-TIFFMapFileProc
-TIFFGetMapFileProc(TIFF* tif)
-{
-	return (tif->tif_mapproc);
-}
-
-/*
- * Return pointer to memory unmapping method.
- */
-TIFFUnmapFileProc
-TIFFGetUnmapFileProc(TIFF* tif)
-{
-	return (tif->tif_unmapproc);
-}
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Id: tif_open.c,v 1.11 2015/02/19 22:39:58 drolon Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and 
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
+ * 
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ */
+#include "tiffiop.h"
+
+/*
+ * Dummy functions to fill the omitted client procedures.
+ */
+static int
+_tiffDummyMapProc(thandle_t fd, void** pbase, toff_t* psize)
+{
+	(void) fd; (void) pbase; (void) psize;
+	return (0);
+}
+
+static void
+_tiffDummyUnmapProc(thandle_t fd, void* base, toff_t size)
+{
+	(void) fd; (void) base; (void) size;
+}
+
+int
+_TIFFgetMode(const char* mode, const char* module)
+{
+	int m = -1;
+
+	switch (mode[0]) {
+	case 'r':
+		m = O_RDONLY;
+		if (mode[1] == '+')
+			m = O_RDWR;
+		break;
+	case 'w':
+	case 'a':
+		m = O_RDWR|O_CREAT;
+		if (mode[0] == 'w')
+			m |= O_TRUNC;
+		break;
+	default:
+		TIFFErrorExt(0, module, "\"%s\": Bad mode", mode);
+		break;
+	}
+	return (m);
+}
+
+TIFF*
+TIFFClientOpen(
+	const char* name, const char* mode,
+	thandle_t clientdata,
+	TIFFReadWriteProc readproc,
+	TIFFReadWriteProc writeproc,
+	TIFFSeekProc seekproc,
+	TIFFCloseProc closeproc,
+	TIFFSizeProc sizeproc,
+	TIFFMapFileProc mapproc,
+	TIFFUnmapFileProc unmapproc
+)
+{
+	static const char module[] = "TIFFClientOpen";
+	TIFF *tif;
+	int m;
+	const char* cp;
+
+	/* The following are configuration checks. They should be redundant, but should not
+	 * compile to any actual code in an optimised release build anyway. If any of them
+	 * fail, (makefile-based or other) configuration is not correct */
+	assert(sizeof(uint8)==1);
+	assert(sizeof(int8)==1);
+	assert(sizeof(uint16)==2);
+	assert(sizeof(int16)==2);
+	assert(sizeof(uint32)==4);
+	assert(sizeof(int32)==4);
+	assert(sizeof(uint64)==8);
+	assert(sizeof(int64)==8);
+	assert(sizeof(tmsize_t)==sizeof(void*));
+	{
+		union{
+			uint8 a8[2];
+			uint16 a16;
+		} n;
+		n.a8[0]=1;
+		n.a8[1]=0;
+		#ifdef WORDS_BIGENDIAN
+		assert(n.a16==256);
+		#else
+		assert(n.a16==1);
+		#endif
+	}
+
+	m = _TIFFgetMode(mode, module);
+	if (m == -1)
+		goto bad2;
+	tif = (TIFF *)_TIFFmalloc((tmsize_t)(sizeof (TIFF) + strlen(name) + 1));
+	if (tif == NULL) {
+		TIFFErrorExt(clientdata, module, "%s: Out of memory (TIFF structure)", name);
+		goto bad2;
+	}
+	_TIFFmemset(tif, 0, sizeof (*tif));
+	tif->tif_name = (char *)tif + sizeof (TIFF);
+	strcpy(tif->tif_name, name);
+	tif->tif_mode = m &~ (O_CREAT|O_TRUNC);
+	tif->tif_curdir = (uint16) -1;		/* non-existent directory */
+	tif->tif_curoff = 0;
+	tif->tif_curstrip = (uint32) -1;	/* invalid strip */
+	tif->tif_row = (uint32) -1;		/* read/write pre-increment */
+	tif->tif_clientdata = clientdata;
+	if (!readproc || !writeproc || !seekproc || !closeproc || !sizeproc) {
+		TIFFErrorExt(clientdata, module,
+		    "One of the client procedures is NULL pointer.");
+		goto bad2;
+	}
+	tif->tif_readproc = readproc;
+	tif->tif_writeproc = writeproc;
+	tif->tif_seekproc = seekproc;
+	tif->tif_closeproc = closeproc;
+	tif->tif_sizeproc = sizeproc;
+	if (mapproc)
+		tif->tif_mapproc = mapproc;
+	else
+		tif->tif_mapproc = _tiffDummyMapProc;
+	if (unmapproc)
+		tif->tif_unmapproc = unmapproc;
+	else
+		tif->tif_unmapproc = _tiffDummyUnmapProc;
+	_TIFFSetDefaultCompressionState(tif);    /* setup default state */
+	/*
+	 * Default is to return data MSB2LSB and enable the
+	 * use of memory-mapped files and strip chopping when
+	 * a file is opened read-only.
+	 */
+	tif->tif_flags = FILLORDER_MSB2LSB;
+	if (m == O_RDONLY )
+		tif->tif_flags |= TIFF_MAPPED;
+
+	#ifdef STRIPCHOP_DEFAULT
+	if (m == O_RDONLY || m == O_RDWR)
+		tif->tif_flags |= STRIPCHOP_DEFAULT;
+	#endif
+
+	/*
+	 * Process library-specific flags in the open mode string.
+	 * The following flags may be used to control intrinsic library
+	 * behaviour that may or may not be desirable (usually for
+	 * compatibility with some application that claims to support
+	 * TIFF but only supports some braindead idea of what the
+	 * vendor thinks TIFF is):
+	 *
+	 * 'l' use little-endian byte order for creating a file
+	 * 'b' use big-endian byte order for creating a file
+	 * 'L' read/write information using LSB2MSB bit order
+	 * 'B' read/write information using MSB2LSB bit order
+	 * 'H' read/write information using host bit order
+	 * 'M' enable use of memory-mapped files when supported
+	 * 'm' disable use of memory-mapped files
+	 * 'C' enable strip chopping support when reading
+	 * 'c' disable strip chopping support
+	 * 'h' read TIFF header only, do not load the first IFD
+	 * '4' ClassicTIFF for creating a file (default)
+	 * '8' BigTIFF for creating a file
+	 *
+	 * The use of the 'l' and 'b' flags is strongly discouraged.
+	 * These flags are provided solely because numerous vendors,
+	 * typically on the PC, do not correctly support TIFF; they
+	 * only support the Intel little-endian byte order.  This
+	 * support is not configured by default because it supports
+	 * the violation of the TIFF spec that says that readers *MUST*
+	 * support both byte orders.  It is strongly recommended that
+	 * you not use this feature except to deal with busted apps
+	 * that write invalid TIFF.  And even in those cases you should
+	 * bang on the vendors to fix their software.
+	 *
+	 * The 'L', 'B', and 'H' flags are intended for applications
+	 * that can optimize operations on data by using a particular
+	 * bit order.  By default the library returns data in MSB2LSB
+	 * bit order for compatibiltiy with older versions of this
+	 * library.  Returning data in the bit order of the native cpu
+	 * makes the most sense but also requires applications to check
+	 * the value of the FillOrder tag; something they probably do
+	 * not do right now.
+	 *
+	 * The 'M' and 'm' flags are provided because some virtual memory
+	 * systems exhibit poor behaviour when large images are mapped.
+	 * These options permit clients to control the use of memory-mapped
+	 * files on a per-file basis.
+	 *
+	 * The 'C' and 'c' flags are provided because the library support
+	 * for chopping up large strips into multiple smaller strips is not
+	 * application-transparent and as such can cause problems.  The 'c'
+	 * option permits applications that only want to look at the tags,
+	 * for example, to get the unadulterated TIFF tag information.
+	 */
+	for (cp = mode; *cp; cp++)
+		switch (*cp) {
+			case 'b':
+				#ifndef WORDS_BIGENDIAN
+				if (m&O_CREAT)
+					tif->tif_flags |= TIFF_SWAB;
+				#endif
+				break;
+			case 'l':
+				#ifdef WORDS_BIGENDIAN
+				if ((m&O_CREAT))
+					tif->tif_flags |= TIFF_SWAB;
+				#endif
+				break;
+			case 'B':
+				tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) |
+				    FILLORDER_MSB2LSB;
+				break;
+			case 'L':
+				tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) |
+				    FILLORDER_LSB2MSB;
+				break;
+			case 'H':
+				tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) |
+				    HOST_FILLORDER;
+				break;
+			case 'M':
+				if (m == O_RDONLY)
+					tif->tif_flags |= TIFF_MAPPED;
+				break;
+			case 'm':
+				if (m == O_RDONLY)
+					tif->tif_flags &= ~TIFF_MAPPED;
+				break;
+			case 'C':
+				if (m == O_RDONLY)
+					tif->tif_flags |= TIFF_STRIPCHOP;
+				break;
+			case 'c':
+				if (m == O_RDONLY)
+					tif->tif_flags &= ~TIFF_STRIPCHOP;
+				break;
+			case 'h':
+				tif->tif_flags |= TIFF_HEADERONLY;
+				break;
+			case '8':
+				if (m&O_CREAT)
+					tif->tif_flags |= TIFF_BIGTIFF;
+				break;
+		}
+	/*
+	 * Read in TIFF header.
+	 */
+	if ((m & O_TRUNC) ||
+	    !ReadOK(tif, &tif->tif_header, sizeof (TIFFHeaderClassic))) {
+		if (tif->tif_mode == O_RDONLY) {
+			TIFFErrorExt(tif->tif_clientdata, name,
+			    "Cannot read TIFF header");
+			goto bad;
+		}
+		/*
+		 * Setup header and write.
+		 */
+		#ifdef WORDS_BIGENDIAN
+		tif->tif_header.common.tiff_magic = tif->tif_flags & TIFF_SWAB
+		    ? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN;
+		#else
+		tif->tif_header.common.tiff_magic = tif->tif_flags & TIFF_SWAB
+		    ? TIFF_BIGENDIAN : TIFF_LITTLEENDIAN;
+		#endif
+		if (!(tif->tif_flags&TIFF_BIGTIFF))
+		{
+			tif->tif_header.common.tiff_version = TIFF_VERSION_CLASSIC;
+			tif->tif_header.classic.tiff_diroff = 0;
+			if (tif->tif_flags & TIFF_SWAB)
+				TIFFSwabShort(&tif->tif_header.common.tiff_version);
+			tif->tif_header_size = sizeof(TIFFHeaderClassic);
+		}
+		else
+		{
+			tif->tif_header.common.tiff_version = TIFF_VERSION_BIG;
+			tif->tif_header.big.tiff_offsetsize = 8;
+			tif->tif_header.big.tiff_unused = 0;
+			tif->tif_header.big.tiff_diroff = 0;
+			if (tif->tif_flags & TIFF_SWAB)
+			{
+				TIFFSwabShort(&tif->tif_header.common.tiff_version);
+				TIFFSwabShort(&tif->tif_header.big.tiff_offsetsize);
+			}
+			tif->tif_header_size = sizeof (TIFFHeaderBig);
+		}
+		/*
+		 * The doc for "fopen" for some STD_C_LIBs says that if you
+		 * open a file for modify ("+"), then you must fseek (or
+		 * fflush?) between any freads and fwrites.  This is not
+		 * necessary on most systems, but has been shown to be needed
+		 * on Solaris.
+		 */
+		TIFFSeekFile( tif, 0, SEEK_SET );
+		if (!WriteOK(tif, &tif->tif_header, (tmsize_t)(tif->tif_header_size))) {
+			TIFFErrorExt(tif->tif_clientdata, name,
+			    "Error writing TIFF header");
+			goto bad;
+		}
+		/*
+		 * Setup the byte order handling.
+		 */
+		if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN) {
+			#ifndef WORDS_BIGENDIAN
+			tif->tif_flags |= TIFF_SWAB;
+			#endif
+		} else {
+			#ifdef WORDS_BIGENDIAN
+			tif->tif_flags |= TIFF_SWAB;
+			#endif
+		}
+		/*
+		 * Setup default directory.
+		 */
+		if (!TIFFDefaultDirectory(tif))
+			goto bad;
+		tif->tif_diroff = 0;
+		tif->tif_dirlist = NULL;
+		tif->tif_dirlistsize = 0;
+		tif->tif_dirnumber = 0;
+		return (tif);
+	}
+	/*
+	 * Setup the byte order handling.
+	 */
+	if (tif->tif_header.common.tiff_magic != TIFF_BIGENDIAN &&
+	    tif->tif_header.common.tiff_magic != TIFF_LITTLEENDIAN
+	    #if MDI_SUPPORT
+	    &&
+	    #if HOST_BIGENDIAN
+	    tif->tif_header.common.tiff_magic != MDI_BIGENDIAN
+	    #else
+	    tif->tif_header.common.tiff_magic != MDI_LITTLEENDIAN
+	    #endif
+	    ) {
+		TIFFErrorExt(tif->tif_clientdata, name,
+		    "Not a TIFF or MDI file, bad magic number %d (0x%x)",
+	    #else
+	    ) {
+		TIFFErrorExt(tif->tif_clientdata, name,
+		    "Not a TIFF file, bad magic number %d (0x%x)",
+	    #endif
+		    tif->tif_header.common.tiff_magic,
+		    tif->tif_header.common.tiff_magic);
+		goto bad;
+	}
+	if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN) {
+		#ifndef WORDS_BIGENDIAN
+		tif->tif_flags |= TIFF_SWAB;
+		#endif
+	} else {
+		#ifdef WORDS_BIGENDIAN
+		tif->tif_flags |= TIFF_SWAB;
+		#endif
+	}
+	if (tif->tif_flags & TIFF_SWAB) 
+		TIFFSwabShort(&tif->tif_header.common.tiff_version);
+	if ((tif->tif_header.common.tiff_version != TIFF_VERSION_CLASSIC)&&
+	    (tif->tif_header.common.tiff_version != TIFF_VERSION_BIG)) {
+		TIFFErrorExt(tif->tif_clientdata, name,
+		    "Not a TIFF file, bad version number %d (0x%x)",
+		    tif->tif_header.common.tiff_version,
+		    tif->tif_header.common.tiff_version);
+		goto bad;
+	}
+	if (tif->tif_header.common.tiff_version == TIFF_VERSION_CLASSIC)
+	{
+		if (tif->tif_flags & TIFF_SWAB)
+			TIFFSwabLong(&tif->tif_header.classic.tiff_diroff);
+		tif->tif_header_size = sizeof(TIFFHeaderClassic);
+	}
+	else
+	{
+		if (!ReadOK(tif, ((uint8*)(&tif->tif_header) + sizeof(TIFFHeaderClassic)), (sizeof(TIFFHeaderBig)-sizeof(TIFFHeaderClassic))))
+		{
+			TIFFErrorExt(tif->tif_clientdata, name,
+			    "Cannot read TIFF header");
+			goto bad;
+		}
+		if (tif->tif_flags & TIFF_SWAB)
+		{
+			TIFFSwabShort(&tif->tif_header.big.tiff_offsetsize);
+			TIFFSwabLong8(&tif->tif_header.big.tiff_diroff);
+		}
+		if (tif->tif_header.big.tiff_offsetsize != 8)
+		{
+			TIFFErrorExt(tif->tif_clientdata, name,
+			    "Not a TIFF file, bad BigTIFF offsetsize %d (0x%x)",
+			    tif->tif_header.big.tiff_offsetsize,
+			    tif->tif_header.big.tiff_offsetsize);
+			goto bad;
+		}
+		if (tif->tif_header.big.tiff_unused != 0)
+		{
+			TIFFErrorExt(tif->tif_clientdata, name,
+			    "Not a TIFF file, bad BigTIFF unused %d (0x%x)",
+			    tif->tif_header.big.tiff_unused,
+			    tif->tif_header.big.tiff_unused);
+			goto bad;
+		}
+		tif->tif_header_size = sizeof(TIFFHeaderBig);
+		tif->tif_flags |= TIFF_BIGTIFF;
+	}
+	tif->tif_flags |= TIFF_MYBUFFER;
+	tif->tif_rawcp = tif->tif_rawdata = 0;
+	tif->tif_rawdatasize = 0;
+        tif->tif_rawdataoff = 0;
+        tif->tif_rawdataloaded = 0;
+
+	switch (mode[0]) {
+		case 'r':
+			if (!(tif->tif_flags&TIFF_BIGTIFF))
+				tif->tif_nextdiroff = tif->tif_header.classic.tiff_diroff;
+			else
+				tif->tif_nextdiroff = tif->tif_header.big.tiff_diroff;
+			/*
+			 * Try to use a memory-mapped file if the client
+			 * has not explicitly suppressed usage with the
+			 * 'm' flag in the open mode (see above).
+			 */
+			if (tif->tif_flags & TIFF_MAPPED)
+			{
+				toff_t n;
+				if (TIFFMapFileContents(tif,(void**)(&tif->tif_base),&n))
+				{
+					tif->tif_size=(tmsize_t)n;
+					assert((toff_t)tif->tif_size==n);
+				}
+				else
+					tif->tif_flags &= ~TIFF_MAPPED;
+			}
+			/*
+			 * Sometimes we do not want to read the first directory (for example,
+			 * it may be broken) and want to proceed to other directories. I this
+			 * case we use the TIFF_HEADERONLY flag to open file and return
+			 * immediately after reading TIFF header.
+			 */
+			if (tif->tif_flags & TIFF_HEADERONLY)
+				return (tif);
+
+			/*
+			 * Setup initial directory.
+			 */
+			if (TIFFReadDirectory(tif)) {
+				tif->tif_rawcc = (tmsize_t)-1;
+				tif->tif_flags |= TIFF_BUFFERSETUP;
+				return (tif);
+			}
+			break;
+		case 'a':
+			/*
+			 * New directories are automatically append
+			 * to the end of the directory chain when they
+			 * are written out (see TIFFWriteDirectory).
+			 */
+			if (!TIFFDefaultDirectory(tif))
+				goto bad;
+			return (tif);
+	}
+bad:
+	tif->tif_mode = O_RDONLY;	/* XXX avoid flush */
+        TIFFCleanup(tif);
+bad2:
+	return ((TIFF*)0);
+}
+
+/*
+ * Query functions to access private data.
+ */
+
+/*
+ * Return open file's name.
+ */
+const char *
+TIFFFileName(TIFF* tif)
+{
+	return (tif->tif_name);
+}
+
+/*
+ * Set the file name.
+ */
+const char *
+TIFFSetFileName(TIFF* tif, const char *name)
+{
+	const char* old_name = tif->tif_name;
+	tif->tif_name = (char *)name;
+	return (old_name);
+}
+
+/*
+ * Return open file's I/O descriptor.
+ */
+int
+TIFFFileno(TIFF* tif)
+{
+	return (tif->tif_fd);
+}
+
+/*
+ * Set open file's I/O descriptor, and return previous value.
+ */
+int
+TIFFSetFileno(TIFF* tif, int fd)
+{
+        int old_fd = tif->tif_fd;
+	tif->tif_fd = fd;
+	return old_fd;
+}
+
+/*
+ * Return open file's clientdata.
+ */
+thandle_t
+TIFFClientdata(TIFF* tif)
+{
+	return (tif->tif_clientdata);
+}
+
+/*
+ * Set open file's clientdata, and return previous value.
+ */
+thandle_t
+TIFFSetClientdata(TIFF* tif, thandle_t newvalue)
+{
+	thandle_t m = tif->tif_clientdata;
+	tif->tif_clientdata = newvalue;
+	return m;
+}
+
+/*
+ * Return read/write mode.
+ */
+int
+TIFFGetMode(TIFF* tif)
+{
+	return (tif->tif_mode);
+}
+
+/*
+ * Return read/write mode.
+ */
+int
+TIFFSetMode(TIFF* tif, int mode)
+{
+	int old_mode = tif->tif_mode;
+	tif->tif_mode = mode;
+	return (old_mode);
+}
+
+/*
+ * Return nonzero if file is organized in
+ * tiles; zero if organized as strips.
+ */
+int
+TIFFIsTiled(TIFF* tif)
+{
+	return (isTiled(tif));
+}
+
+/*
+ * Return current row being read/written.
+ */
+uint32
+TIFFCurrentRow(TIFF* tif)
+{
+	return (tif->tif_row);
+}
+
+/*
+ * Return index of the current directory.
+ */
+uint16
+TIFFCurrentDirectory(TIFF* tif)
+{
+	return (tif->tif_curdir);
+}
+
+/*
+ * Return current strip.
+ */
+uint32
+TIFFCurrentStrip(TIFF* tif)
+{
+	return (tif->tif_curstrip);
+}
+
+/*
+ * Return current tile.
+ */
+uint32
+TIFFCurrentTile(TIFF* tif)
+{
+	return (tif->tif_curtile);
+}
+
+/*
+ * Return nonzero if the file has byte-swapped data.
+ */
+int
+TIFFIsByteSwapped(TIFF* tif)
+{
+	return ((tif->tif_flags & TIFF_SWAB) != 0);
+}
+
+/*
+ * Return nonzero if the data is returned up-sampled.
+ */
+int
+TIFFIsUpSampled(TIFF* tif)
+{
+	return (isUpSampled(tif));
+}
+
+/*
+ * Return nonzero if the data is returned in MSB-to-LSB bit order.
+ */
+int
+TIFFIsMSB2LSB(TIFF* tif)
+{
+	return (isFillOrder(tif, FILLORDER_MSB2LSB));
+}
+
+/*
+ * Return nonzero if given file was written in big-endian order.
+ */
+int
+TIFFIsBigEndian(TIFF* tif)
+{
+	return (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN);
+}
+
+/*
+ * Return pointer to file read method.
+ */
+TIFFReadWriteProc
+TIFFGetReadProc(TIFF* tif)
+{
+	return (tif->tif_readproc);
+}
+
+/*
+ * Return pointer to file write method.
+ */
+TIFFReadWriteProc
+TIFFGetWriteProc(TIFF* tif)
+{
+	return (tif->tif_writeproc);
+}
+
+/*
+ * Return pointer to file seek method.
+ */
+TIFFSeekProc
+TIFFGetSeekProc(TIFF* tif)
+{
+	return (tif->tif_seekproc);
+}
+
+/*
+ * Return pointer to file close method.
+ */
+TIFFCloseProc
+TIFFGetCloseProc(TIFF* tif)
+{
+	return (tif->tif_closeproc);
+}
+
+/*
+ * Return pointer to file size requesting method.
+ */
+TIFFSizeProc
+TIFFGetSizeProc(TIFF* tif)
+{
+	return (tif->tif_sizeproc);
+}
+
+/*
+ * Return pointer to memory mapping method.
+ */
+TIFFMapFileProc
+TIFFGetMapFileProc(TIFF* tif)
+{
+	return (tif->tif_mapproc);
+}
+
+/*
+ * Return pointer to memory unmapping method.
+ */
+TIFFUnmapFileProc
+TIFFGetUnmapFileProc(TIFF* tif)
+{
+	return (tif->tif_unmapproc);
+}
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tif_packbits.c b/Source/LibTIFF4/tif_packbits.c
index 56d5969..289fa6c 100644
--- a/Source/LibTIFF4/tif_packbits.c
+++ b/Source/LibTIFF4/tif_packbits.c
@@ -1,300 +1,300 @@
-/* $Id: tif_packbits.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-#include "tiffiop.h"
-#ifdef PACKBITS_SUPPORT
-/*
- * TIFF Library.
- *
- * PackBits Compression Algorithm Support
- */
-#include <stdio.h>
-
-static int
-PackBitsPreEncode(TIFF* tif, uint16 s)
-{
-	(void) s;
-
-	if (!(tif->tif_data = (uint8*)_TIFFmalloc(sizeof(tmsize_t))))
-		return (0);
-	/*
-	 * Calculate the scanline/tile-width size in bytes.
-	 */
-	if (isTiled(tif))
-		*(tmsize_t*)tif->tif_data = TIFFTileRowSize(tif);
-	else
-		*(tmsize_t*)tif->tif_data = TIFFScanlineSize(tif);
-	return (1);
-}
-
-static int
-PackBitsPostEncode(TIFF* tif)
-{
-        if (tif->tif_data)
-            _TIFFfree(tif->tif_data);
-	return (1);
-}
-
-/*
- * Encode a run of pixels.
- */
-static int
-PackBitsEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
-{
-	unsigned char* bp = (unsigned char*) buf;
-	uint8* op;
-	uint8* ep;
-	uint8* lastliteral;
-	long n, slop;
-	int b;
-	enum { BASE, LITERAL, RUN, LITERAL_RUN } state;
-
-	(void) s;
-	op = tif->tif_rawcp;
-	ep = tif->tif_rawdata + tif->tif_rawdatasize;
-	state = BASE;
-	lastliteral = 0;
-	while (cc > 0) {
-		/*
-		 * Find the longest string of identical bytes.
-		 */
-		b = *bp++, cc--, n = 1;
-		for (; cc > 0 && b == *bp; cc--, bp++)
-			n++;
-	again:
-		if (op + 2 >= ep) {		/* insure space for new data */
-			/*
-			 * Be careful about writing the last
-			 * literal.  Must write up to that point
-			 * and then copy the remainder to the
-			 * front of the buffer.
-			 */
-			if (state == LITERAL || state == LITERAL_RUN) {
-				slop = (long)(op - lastliteral);
-				tif->tif_rawcc += (tmsize_t)(lastliteral - tif->tif_rawcp);
-				if (!TIFFFlushData1(tif))
-					return (-1);
-				op = tif->tif_rawcp;
-				while (slop-- > 0)
-					*op++ = *lastliteral++;
-				lastliteral = tif->tif_rawcp;
-			} else {
-				tif->tif_rawcc += (tmsize_t)(op - tif->tif_rawcp);
-				if (!TIFFFlushData1(tif))
-					return (-1);
-				op = tif->tif_rawcp;
-			}
-		}
-		switch (state) {
-		case BASE:		/* initial state, set run/literal */
-			if (n > 1) {
-				state = RUN;
-				if (n > 128) {
-					*op++ = (uint8) -127;
-					*op++ = (uint8) b;
-					n -= 128;
-					goto again;
-				}
-				*op++ = (uint8)(-(n-1));
-				*op++ = (uint8) b;
-			} else {
-				lastliteral = op;
-				*op++ = 0;
-				*op++ = (uint8) b;
-				state = LITERAL;
-			}
-			break;
-		case LITERAL:		/* last object was literal string */
-			if (n > 1) {
-				state = LITERAL_RUN;
-				if (n > 128) {
-					*op++ = (uint8) -127;
-					*op++ = (uint8) b;
-					n -= 128;
-					goto again;
-				}
-				*op++ = (uint8)(-(n-1));	/* encode run */
-				*op++ = (uint8) b;
-			} else {			/* extend literal */
-				if (++(*lastliteral) == 127)
-					state = BASE;
-				*op++ = (uint8) b;
-			}
-			break;
-		case RUN:		/* last object was run */
-			if (n > 1) {
-				if (n > 128) {
-					*op++ = (uint8) -127;
-					*op++ = (uint8) b;
-					n -= 128;
-					goto again;
-				}
-				*op++ = (uint8)(-(n-1));
-				*op++ = (uint8) b;
-			} else {
-				lastliteral = op;
-				*op++ = 0;
-				*op++ = (uint8) b;
-				state = LITERAL;
-			}
-			break;
-		case LITERAL_RUN:	/* literal followed by a run */
-			/*
-			 * Check to see if previous run should
-			 * be converted to a literal, in which
-			 * case we convert literal-run-literal
-			 * to a single literal.
-			 */
-			if (n == 1 && op[-2] == (uint8) -1 &&
-			    *lastliteral < 126) {
-				state = (((*lastliteral) += 2) == 127 ?
-				    BASE : LITERAL);
-				op[-2] = op[-1];	/* replicate */
-			} else
-				state = RUN;
-			goto again;
-		}
-	}
-	tif->tif_rawcc += (tmsize_t)(op - tif->tif_rawcp);
-	tif->tif_rawcp = op;
-	return (1);
-}
-
-/*
- * Encode a rectangular chunk of pixels.  We break it up
- * into row-sized pieces to insure that encoded runs do
- * not span rows.  Otherwise, there can be problems with
- * the decoder if data is read, for example, by scanlines
- * when it was encoded by strips.
- */
-static int
-PackBitsEncodeChunk(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
-{
-	tmsize_t rowsize = *(tmsize_t*)tif->tif_data;
-
-	while (cc > 0) {
-		tmsize_t chunk = rowsize;
-		
-		if( cc < chunk )
-		    chunk = cc;
-
-		if (PackBitsEncode(tif, bp, chunk, s) < 0)
-		    return (-1);
-		bp += chunk;
-		cc -= chunk;
-	}
-	return (1);
-}
-
-static int
-PackBitsDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
-{
-	static const char module[] = "PackBitsDecode";
-	char *bp;
-	tmsize_t cc;
-	long n;
-	int b;
-
-	(void) s;
-	bp = (char*) tif->tif_rawcp;
-	cc = tif->tif_rawcc;
-	while (cc > 0 && occ > 0) {
-		n = (long) *bp++, cc--;
-		/*
-		 * Watch out for compilers that
-		 * don't sign extend chars...
-		 */
-		if (n >= 128)
-			n -= 256;
-		if (n < 0) {		/* replicate next byte -n+1 times */
-			if (n == -128)	/* nop */
-				continue;
-			n = -n + 1;
-			if( occ < (tmsize_t)n )
-			{
-				TIFFWarningExt(tif->tif_clientdata, module,
-				    "Discarding %lu bytes to avoid buffer overrun",
-				    (unsigned long) ((tmsize_t)n - occ));
-				n = (long)occ;
-			}
-			occ -= n;
-			b = *bp++, cc--;
-			while (n-- > 0)
-				*op++ = (uint8) b;
-		} else {		/* copy next n+1 bytes literally */
-			if (occ < (tmsize_t)(n + 1))
-			{
-				TIFFWarningExt(tif->tif_clientdata, module,
-				    "Discarding %lu bytes to avoid buffer overrun",
-				    (unsigned long) ((tmsize_t)n - occ + 1));
-				n = (long)occ - 1;
-			}
-			if (cc < (tmsize_t) (n+1)) 
-			{
-				TIFFWarningExt(tif->tif_clientdata, module,
-					       "Terminating PackBitsDecode due to lack of data.");
-				break;
-			}
-			_TIFFmemcpy(op, bp, ++n);
-			op += n; occ -= n;
-			bp += n; cc -= n;
-		}
-	}
-	tif->tif_rawcp = (uint8*) bp;
-	tif->tif_rawcc = cc;
-	if (occ > 0) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-		    "Not enough data for scanline %lu",
-		    (unsigned long) tif->tif_row);
-		return (0);
-	}
-	return (1);
-}
-
-int
-TIFFInitPackBits(TIFF* tif, int scheme)
-{
-	(void) scheme;
-	tif->tif_decoderow = PackBitsDecode;
-	tif->tif_decodestrip = PackBitsDecode;
-	tif->tif_decodetile = PackBitsDecode;
-	tif->tif_preencode = PackBitsPreEncode;
-	tif->tif_postencode = PackBitsPostEncode;
-	tif->tif_encoderow = PackBitsEncode;
-	tif->tif_encodestrip = PackBitsEncodeChunk;
-	tif->tif_encodetile = PackBitsEncodeChunk;
-	return (1);
-}
-#endif /* PACKBITS_SUPPORT */
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Id: tif_packbits.c,v 1.11 2015/02/19 22:39:58 drolon Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and 
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
+ * 
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
+ * OF THIS SOFTWARE.
+ */
+
+#include "tiffiop.h"
+#ifdef PACKBITS_SUPPORT
+/*
+ * TIFF Library.
+ *
+ * PackBits Compression Algorithm Support
+ */
+#include <stdio.h>
+
+static int
+PackBitsPreEncode(TIFF* tif, uint16 s)
+{
+	(void) s;
+
+	if (!(tif->tif_data = (uint8*)_TIFFmalloc(sizeof(tmsize_t))))
+		return (0);
+	/*
+	 * Calculate the scanline/tile-width size in bytes.
+	 */
+	if (isTiled(tif))
+		*(tmsize_t*)tif->tif_data = TIFFTileRowSize(tif);
+	else
+		*(tmsize_t*)tif->tif_data = TIFFScanlineSize(tif);
+	return (1);
+}
+
+static int
+PackBitsPostEncode(TIFF* tif)
+{
+        if (tif->tif_data)
+            _TIFFfree(tif->tif_data);
+	return (1);
+}
+
+/*
+ * Encode a run of pixels.
+ */
+static int
+PackBitsEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
+{
+	unsigned char* bp = (unsigned char*) buf;
+	uint8* op;
+	uint8* ep;
+	uint8* lastliteral;
+	long n, slop;
+	int b;
+	enum { BASE, LITERAL, RUN, LITERAL_RUN } state;
+
+	(void) s;
+	op = tif->tif_rawcp;
+	ep = tif->tif_rawdata + tif->tif_rawdatasize;
+	state = BASE;
+	lastliteral = 0;
+	while (cc > 0) {
+		/*
+		 * Find the longest string of identical bytes.
+		 */
+		b = *bp++, cc--, n = 1;
+		for (; cc > 0 && b == *bp; cc--, bp++)
+			n++;
+	again:
+		if (op + 2 >= ep) {		/* insure space for new data */
+			/*
+			 * Be careful about writing the last
+			 * literal.  Must write up to that point
+			 * and then copy the remainder to the
+			 * front of the buffer.
+			 */
+			if (state == LITERAL || state == LITERAL_RUN) {
+				slop = (long)(op - lastliteral);
+				tif->tif_rawcc += (tmsize_t)(lastliteral - tif->tif_rawcp);
+				if (!TIFFFlushData1(tif))
+					return (-1);
+				op = tif->tif_rawcp;
+				while (slop-- > 0)
+					*op++ = *lastliteral++;
+				lastliteral = tif->tif_rawcp;
+			} else {
+				tif->tif_rawcc += (tmsize_t)(op - tif->tif_rawcp);
+				if (!TIFFFlushData1(tif))
+					return (-1);
+				op = tif->tif_rawcp;
+			}
+		}
+		switch (state) {
+		case BASE:		/* initial state, set run/literal */
+			if (n > 1) {
+				state = RUN;
+				if (n > 128) {
+					*op++ = (uint8) -127;
+					*op++ = (uint8) b;
+					n -= 128;
+					goto again;
+				}
+				*op++ = (uint8)(-(n-1));
+				*op++ = (uint8) b;
+			} else {
+				lastliteral = op;
+				*op++ = 0;
+				*op++ = (uint8) b;
+				state = LITERAL;
+			}
+			break;
+		case LITERAL:		/* last object was literal string */
+			if (n > 1) {
+				state = LITERAL_RUN;
+				if (n > 128) {
+					*op++ = (uint8) -127;
+					*op++ = (uint8) b;
+					n -= 128;
+					goto again;
+				}
+				*op++ = (uint8)(-(n-1));	/* encode run */
+				*op++ = (uint8) b;
+			} else {			/* extend literal */
+				if (++(*lastliteral) == 127)
+					state = BASE;
+				*op++ = (uint8) b;
+			}
+			break;
+		case RUN:		/* last object was run */
+			if (n > 1) {
+				if (n > 128) {
+					*op++ = (uint8) -127;
+					*op++ = (uint8) b;
+					n -= 128;
+					goto again;
+				}
+				*op++ = (uint8)(-(n-1));
+				*op++ = (uint8) b;
+			} else {
+				lastliteral = op;
+				*op++ = 0;
+				*op++ = (uint8) b;
+				state = LITERAL;
+			}
+			break;
+		case LITERAL_RUN:	/* literal followed by a run */
+			/*
+			 * Check to see if previous run should
+			 * be converted to a literal, in which
+			 * case we convert literal-run-literal
+			 * to a single literal.
+			 */
+			if (n == 1 && op[-2] == (uint8) -1 &&
+			    *lastliteral < 126) {
+				state = (((*lastliteral) += 2) == 127 ?
+				    BASE : LITERAL);
+				op[-2] = op[-1];	/* replicate */
+			} else
+				state = RUN;
+			goto again;
+		}
+	}
+	tif->tif_rawcc += (tmsize_t)(op - tif->tif_rawcp);
+	tif->tif_rawcp = op;
+	return (1);
+}
+
+/*
+ * Encode a rectangular chunk of pixels.  We break it up
+ * into row-sized pieces to insure that encoded runs do
+ * not span rows.  Otherwise, there can be problems with
+ * the decoder if data is read, for example, by scanlines
+ * when it was encoded by strips.
+ */
+static int
+PackBitsEncodeChunk(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
+{
+	tmsize_t rowsize = *(tmsize_t*)tif->tif_data;
+
+	while (cc > 0) {
+		tmsize_t chunk = rowsize;
+		
+		if( cc < chunk )
+		    chunk = cc;
+
+		if (PackBitsEncode(tif, bp, chunk, s) < 0)
+		    return (-1);
+		bp += chunk;
+		cc -= chunk;
+	}
+	return (1);
+}
+
+static int
+PackBitsDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
+{
+	static const char module[] = "PackBitsDecode";
+	char *bp;
+	tmsize_t cc;
+	long n;
+	int b;
+
+	(void) s;
+	bp = (char*) tif->tif_rawcp;
+	cc = tif->tif_rawcc;
+	while (cc > 0 && occ > 0) {
+		n = (long) *bp++, cc--;
+		/*
+		 * Watch out for compilers that
+		 * don't sign extend chars...
+		 */
+		if (n >= 128)
+			n -= 256;
+		if (n < 0) {		/* replicate next byte -n+1 times */
+			if (n == -128)	/* nop */
+				continue;
+			n = -n + 1;
+			if( occ < (tmsize_t)n )
+			{
+				TIFFWarningExt(tif->tif_clientdata, module,
+				    "Discarding %lu bytes to avoid buffer overrun",
+				    (unsigned long) ((tmsize_t)n - occ));
+				n = (long)occ;
+			}
+			occ -= n;
+			b = *bp++, cc--;
+			while (n-- > 0)
+				*op++ = (uint8) b;
+		} else {		/* copy next n+1 bytes literally */
+			if (occ < (tmsize_t)(n + 1))
+			{
+				TIFFWarningExt(tif->tif_clientdata, module,
+				    "Discarding %lu bytes to avoid buffer overrun",
+				    (unsigned long) ((tmsize_t)n - occ + 1));
+				n = (long)occ - 1;
+			}
+			if (cc < (tmsize_t) (n+1)) 
+			{
+				TIFFWarningExt(tif->tif_clientdata, module,
+					       "Terminating PackBitsDecode due to lack of data.");
+				break;
+			}
+			_TIFFmemcpy(op, bp, ++n);
+			op += n; occ -= n;
+			bp += n; cc -= n;
+		}
+	}
+	tif->tif_rawcp = (uint8*) bp;
+	tif->tif_rawcc = cc;
+	if (occ > 0) {
+		TIFFErrorExt(tif->tif_clientdata, module,
+		    "Not enough data for scanline %lu",
+		    (unsigned long) tif->tif_row);
+		return (0);
+	}
+	return (1);
+}
+
+int
+TIFFInitPackBits(TIFF* tif, int scheme)
+{
+	(void) scheme;
+	tif->tif_decoderow = PackBitsDecode;
+	tif->tif_decodestrip = PackBitsDecode;
+	tif->tif_decodetile = PackBitsDecode;
+	tif->tif_preencode = PackBitsPreEncode;
+	tif->tif_postencode = PackBitsPostEncode;
+	tif->tif_encoderow = PackBitsEncode;
+	tif->tif_encodestrip = PackBitsEncodeChunk;
+	tif->tif_encodetile = PackBitsEncodeChunk;
+	return (1);
+}
+#endif /* PACKBITS_SUPPORT */
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tif_pixarlog.c b/Source/LibTIFF4/tif_pixarlog.c
index 1a38d0d..89133e8 100644
--- a/Source/LibTIFF4/tif_pixarlog.c
+++ b/Source/LibTIFF4/tif_pixarlog.c
@@ -1,1426 +1,1442 @@
-/* $Id: tif_pixarlog.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * Copyright (c) 1996-1997 Sam Leffler
- * Copyright (c) 1996 Pixar
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Pixar, Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Pixar, Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL PIXAR, SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-#include "tiffiop.h"
-#ifdef PIXARLOG_SUPPORT
-
-/*
- * TIFF Library.
- * PixarLog Compression Support
- *
- * Contributed by Dan McCoy.
- *
- * PixarLog film support uses the TIFF library to store companded
- * 11 bit values into a tiff file, which are compressed using the 
- * zip compressor.  
- *
- * The codec can take as input and produce as output 32-bit IEEE float values 
- * as well as 16-bit or 8-bit unsigned integer values.
- *
- * On writing any of the above are converted into the internal
- * 11-bit log format.   In the case of  8 and 16 bit values, the
- * input is assumed to be unsigned linear color values that represent
- * the range 0-1.  In the case of IEEE values, the 0-1 range is assumed to
- * be the normal linear color range, in addition over 1 values are
- * accepted up to a value of about 25.0 to encode "hot" hightlights and such.
- * The encoding is lossless for 8-bit values, slightly lossy for the
- * other bit depths.  The actual color precision should be better
- * than the human eye can perceive with extra room to allow for
- * error introduced by further image computation.  As with any quantized
- * color format, it is possible to perform image calculations which
- * expose the quantization error. This format should certainly be less 
- * susceptable to such errors than standard 8-bit encodings, but more
- * susceptable than straight 16-bit or 32-bit encodings.
- *
- * On reading the internal format is converted to the desired output format.
- * The program can request which format it desires by setting the internal
- * pseudo tag TIFFTAG_PIXARLOGDATAFMT to one of these possible values:
- *  PIXARLOGDATAFMT_FLOAT     = provide IEEE float values.
- *  PIXARLOGDATAFMT_16BIT     = provide unsigned 16-bit integer values
- *  PIXARLOGDATAFMT_8BIT      = provide unsigned 8-bit integer values
- *
- * alternately PIXARLOGDATAFMT_8BITABGR provides unsigned 8-bit integer
- * values with the difference that if there are exactly three or four channels
- * (rgb or rgba) it swaps the channel order (bgr or abgr).
- *
- * PIXARLOGDATAFMT_11BITLOG provides the internal encoding directly
- * packed in 16-bit values.   However no tools are supplied for interpreting
- * these values.
- *
- * "hot" (over 1.0) areas written in floating point get clamped to
- * 1.0 in the integer data types.
- *
- * When the file is closed after writing, the bit depth and sample format
- * are set always to appear as if 8-bit data has been written into it.
- * That way a naive program unaware of the particulars of the encoding
- * gets the format it is most likely able to handle.
- *
- * The codec does it's own horizontal differencing step on the coded
- * values so the libraries predictor stuff should be turned off.
- * The codec also handle byte swapping the encoded values as necessary
- * since the library does not have the information necessary
- * to know the bit depth of the raw unencoded buffer.
- *
- * NOTE: This decoder does not appear to update tif_rawcp, and tif_rawcc.
- * This can cause problems with the implementation of CHUNKY_STRIP_READ_SUPPORT
- * as noted in http://trac.osgeo.org/gdal/ticket/3894.   FrankW - Jan'11
- */
-
-#include "tif_predict.h"
-#include "../ZLib/zlib.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-
-/* Tables for converting to/from 11 bit coded values */
-
-#define  TSIZE	 2048		/* decode table size (11-bit tokens) */
-#define  TSIZEP1 2049		/* Plus one for slop */
-#define  ONE	 1250		/* token value of 1.0 exactly */
-#define  RATIO	 1.004		/* nominal ratio for log part */
-
-#define CODE_MASK 0x7ff         /* 11 bits. */
-
-static float  Fltsize;
-static float  LogK1, LogK2;
-
-#define REPEAT(n, op)   { int i; i=n; do { i--; op; } while (i>0); }
-
-static void
-horizontalAccumulateF(uint16 *wp, int n, int stride, float *op,
-	float *ToLinearF)
-{
-    register unsigned int  cr, cg, cb, ca, mask;
-    register float  t0, t1, t2, t3;
-
-    if (n >= stride) {
-	mask = CODE_MASK;
-	if (stride == 3) {
-	    t0 = ToLinearF[cr = (wp[0] & mask)];
-	    t1 = ToLinearF[cg = (wp[1] & mask)];
-	    t2 = ToLinearF[cb = (wp[2] & mask)];
-	    op[0] = t0;
-	    op[1] = t1;
-	    op[2] = t2;
-	    n -= 3;
-	    while (n > 0) {
-		wp += 3;
-		op += 3;
-		n -= 3;
-		t0 = ToLinearF[(cr += wp[0]) & mask];
-		t1 = ToLinearF[(cg += wp[1]) & mask];
-		t2 = ToLinearF[(cb += wp[2]) & mask];
-		op[0] = t0;
-		op[1] = t1;
-		op[2] = t2;
-	    }
-	} else if (stride == 4) {
-	    t0 = ToLinearF[cr = (wp[0] & mask)];
-	    t1 = ToLinearF[cg = (wp[1] & mask)];
-	    t2 = ToLinearF[cb = (wp[2] & mask)];
-	    t3 = ToLinearF[ca = (wp[3] & mask)];
-	    op[0] = t0;
-	    op[1] = t1;
-	    op[2] = t2;
-	    op[3] = t3;
-	    n -= 4;
-	    while (n > 0) {
-		wp += 4;
-		op += 4;
-		n -= 4;
-		t0 = ToLinearF[(cr += wp[0]) & mask];
-		t1 = ToLinearF[(cg += wp[1]) & mask];
-		t2 = ToLinearF[(cb += wp[2]) & mask];
-		t3 = ToLinearF[(ca += wp[3]) & mask];
-		op[0] = t0;
-		op[1] = t1;
-		op[2] = t2;
-		op[3] = t3;
-	    }
-	} else {
-	    REPEAT(stride, *op = ToLinearF[*wp&mask]; wp++; op++)
-	    n -= stride;
-	    while (n > 0) {
-		REPEAT(stride,
-		    wp[stride] += *wp; *op = ToLinearF[*wp&mask]; wp++; op++)
-		n -= stride;
-	    }
-	}
-    }
-}
-
-static void
-horizontalAccumulate12(uint16 *wp, int n, int stride, int16 *op,
-	float *ToLinearF)
-{
-    register unsigned int  cr, cg, cb, ca, mask;
-    register float  t0, t1, t2, t3;
-
-#define SCALE12 2048.0F
-#define CLAMP12(t) (((t) < 3071) ? (uint16) (t) : 3071)
-
-    if (n >= stride) {
-	mask = CODE_MASK;
-	if (stride == 3) {
-	    t0 = ToLinearF[cr = (wp[0] & mask)] * SCALE12;
-	    t1 = ToLinearF[cg = (wp[1] & mask)] * SCALE12;
-	    t2 = ToLinearF[cb = (wp[2] & mask)] * SCALE12;
-	    op[0] = CLAMP12(t0);
-	    op[1] = CLAMP12(t1);
-	    op[2] = CLAMP12(t2);
-	    n -= 3;
-	    while (n > 0) {
-		wp += 3;
-		op += 3;
-		n -= 3;
-		t0 = ToLinearF[(cr += wp[0]) & mask] * SCALE12;
-		t1 = ToLinearF[(cg += wp[1]) & mask] * SCALE12;
-		t2 = ToLinearF[(cb += wp[2]) & mask] * SCALE12;
-		op[0] = CLAMP12(t0);
-		op[1] = CLAMP12(t1);
-		op[2] = CLAMP12(t2);
-	    }
-	} else if (stride == 4) {
-	    t0 = ToLinearF[cr = (wp[0] & mask)] * SCALE12;
-	    t1 = ToLinearF[cg = (wp[1] & mask)] * SCALE12;
-	    t2 = ToLinearF[cb = (wp[2] & mask)] * SCALE12;
-	    t3 = ToLinearF[ca = (wp[3] & mask)] * SCALE12;
-	    op[0] = CLAMP12(t0);
-	    op[1] = CLAMP12(t1);
-	    op[2] = CLAMP12(t2);
-	    op[3] = CLAMP12(t3);
-	    n -= 4;
-	    while (n > 0) {
-		wp += 4;
-		op += 4;
-		n -= 4;
-		t0 = ToLinearF[(cr += wp[0]) & mask] * SCALE12;
-		t1 = ToLinearF[(cg += wp[1]) & mask] * SCALE12;
-		t2 = ToLinearF[(cb += wp[2]) & mask] * SCALE12;
-		t3 = ToLinearF[(ca += wp[3]) & mask] * SCALE12;
-		op[0] = CLAMP12(t0);
-		op[1] = CLAMP12(t1);
-		op[2] = CLAMP12(t2);
-		op[3] = CLAMP12(t3);
-	    }
-	} else {
-	    REPEAT(stride, t0 = ToLinearF[*wp&mask] * SCALE12;
-                           *op = CLAMP12(t0); wp++; op++)
-	    n -= stride;
-	    while (n > 0) {
-		REPEAT(stride,
-		    wp[stride] += *wp; t0 = ToLinearF[wp[stride]&mask]*SCALE12;
-		    *op = CLAMP12(t0);  wp++; op++)
-		n -= stride;
-	    }
-	}
-    }
-}
-
-static void
-horizontalAccumulate16(uint16 *wp, int n, int stride, uint16 *op,
-	uint16 *ToLinear16)
-{
-    register unsigned int  cr, cg, cb, ca, mask;
-
-    if (n >= stride) {
-	mask = CODE_MASK;
-	if (stride == 3) {
-	    op[0] = ToLinear16[cr = (wp[0] & mask)];
-	    op[1] = ToLinear16[cg = (wp[1] & mask)];
-	    op[2] = ToLinear16[cb = (wp[2] & mask)];
-	    n -= 3;
-	    while (n > 0) {
-		wp += 3;
-		op += 3;
-		n -= 3;
-		op[0] = ToLinear16[(cr += wp[0]) & mask];
-		op[1] = ToLinear16[(cg += wp[1]) & mask];
-		op[2] = ToLinear16[(cb += wp[2]) & mask];
-	    }
-	} else if (stride == 4) {
-	    op[0] = ToLinear16[cr = (wp[0] & mask)];
-	    op[1] = ToLinear16[cg = (wp[1] & mask)];
-	    op[2] = ToLinear16[cb = (wp[2] & mask)];
-	    op[3] = ToLinear16[ca = (wp[3] & mask)];
-	    n -= 4;
-	    while (n > 0) {
-		wp += 4;
-		op += 4;
-		n -= 4;
-		op[0] = ToLinear16[(cr += wp[0]) & mask];
-		op[1] = ToLinear16[(cg += wp[1]) & mask];
-		op[2] = ToLinear16[(cb += wp[2]) & mask];
-		op[3] = ToLinear16[(ca += wp[3]) & mask];
-	    }
-	} else {
-	    REPEAT(stride, *op = ToLinear16[*wp&mask]; wp++; op++)
-	    n -= stride;
-	    while (n > 0) {
-		REPEAT(stride,
-		    wp[stride] += *wp; *op = ToLinear16[*wp&mask]; wp++; op++)
-		n -= stride;
-	    }
-	}
-    }
-}
-
-/* 
- * Returns the log encoded 11-bit values with the horizontal
- * differencing undone.
- */
-static void
-horizontalAccumulate11(uint16 *wp, int n, int stride, uint16 *op)
-{
-    register unsigned int  cr, cg, cb, ca, mask;
-
-    if (n >= stride) {
-	mask = CODE_MASK;
-	if (stride == 3) {
-	    op[0] = cr = wp[0];  op[1] = cg = wp[1];  op[2] = cb = wp[2];
-	    n -= 3;
-	    while (n > 0) {
-		wp += 3;
-		op += 3;
-		n -= 3;
-		op[0] = (cr += wp[0]) & mask;
-		op[1] = (cg += wp[1]) & mask;
-		op[2] = (cb += wp[2]) & mask;
-	    }
-	} else if (stride == 4) {
-	    op[0] = cr = wp[0];  op[1] = cg = wp[1];
-	    op[2] = cb = wp[2];  op[3] = ca = wp[3];
-	    n -= 4;
-	    while (n > 0) {
-		wp += 4;
-		op += 4;
-		n -= 4;
-		op[0] = (cr += wp[0]) & mask;
-		op[1] = (cg += wp[1]) & mask;
-		op[2] = (cb += wp[2]) & mask;
-		op[3] = (ca += wp[3]) & mask;
-	    } 
-	} else {
-	    REPEAT(stride, *op = *wp&mask; wp++; op++)
-	    n -= stride;
-	    while (n > 0) {
-		REPEAT(stride,
-		    wp[stride] += *wp; *op = *wp&mask; wp++; op++)
-		n -= stride;
-	    }
-	}
-    }
-}
-
-static void
-horizontalAccumulate8(uint16 *wp, int n, int stride, unsigned char *op,
-	unsigned char *ToLinear8)
-{
-    register unsigned int  cr, cg, cb, ca, mask;
-
-    if (n >= stride) {
-	mask = CODE_MASK;
-	if (stride == 3) {
-	    op[0] = ToLinear8[cr = (wp[0] & mask)];
-	    op[1] = ToLinear8[cg = (wp[1] & mask)];
-	    op[2] = ToLinear8[cb = (wp[2] & mask)];
-	    n -= 3;
-	    while (n > 0) {
-		n -= 3;
-		wp += 3;
-		op += 3;
-		op[0] = ToLinear8[(cr += wp[0]) & mask];
-		op[1] = ToLinear8[(cg += wp[1]) & mask];
-		op[2] = ToLinear8[(cb += wp[2]) & mask];
-	    }
-	} else if (stride == 4) {
-	    op[0] = ToLinear8[cr = (wp[0] & mask)];
-	    op[1] = ToLinear8[cg = (wp[1] & mask)];
-	    op[2] = ToLinear8[cb = (wp[2] & mask)];
-	    op[3] = ToLinear8[ca = (wp[3] & mask)];
-	    n -= 4;
-	    while (n > 0) {
-		n -= 4;
-		wp += 4;
-		op += 4;
-		op[0] = ToLinear8[(cr += wp[0]) & mask];
-		op[1] = ToLinear8[(cg += wp[1]) & mask];
-		op[2] = ToLinear8[(cb += wp[2]) & mask];
-		op[3] = ToLinear8[(ca += wp[3]) & mask];
-	    }
-	} else {
-	    REPEAT(stride, *op = ToLinear8[*wp&mask]; wp++; op++)
-	    n -= stride;
-	    while (n > 0) {
-		REPEAT(stride,
-		    wp[stride] += *wp; *op = ToLinear8[*wp&mask]; wp++; op++)
-		n -= stride;
-	    }
-	}
-    }
-}
-
-
-static void
-horizontalAccumulate8abgr(uint16 *wp, int n, int stride, unsigned char *op,
-	unsigned char *ToLinear8)
-{
-    register unsigned int  cr, cg, cb, ca, mask;
-    register unsigned char  t0, t1, t2, t3;
-
-    if (n >= stride) {
-	mask = CODE_MASK;
-	if (stride == 3) {
-	    op[0] = 0;
-	    t1 = ToLinear8[cb = (wp[2] & mask)];
-	    t2 = ToLinear8[cg = (wp[1] & mask)];
-	    t3 = ToLinear8[cr = (wp[0] & mask)];
-	    op[1] = t1;
-	    op[2] = t2;
-	    op[3] = t3;
-	    n -= 3;
-	    while (n > 0) {
-		n -= 3;
-		wp += 3;
-		op += 4;
-		op[0] = 0;
-		t1 = ToLinear8[(cb += wp[2]) & mask];
-		t2 = ToLinear8[(cg += wp[1]) & mask];
-		t3 = ToLinear8[(cr += wp[0]) & mask];
-		op[1] = t1;
-		op[2] = t2;
-		op[3] = t3;
-	    }
-	} else if (stride == 4) {
-	    t0 = ToLinear8[ca = (wp[3] & mask)];
-	    t1 = ToLinear8[cb = (wp[2] & mask)];
-	    t2 = ToLinear8[cg = (wp[1] & mask)];
-	    t3 = ToLinear8[cr = (wp[0] & mask)];
-	    op[0] = t0;
-	    op[1] = t1;
-	    op[2] = t2;
-	    op[3] = t3;
-	    n -= 4;
-	    while (n > 0) {
-		n -= 4;
-		wp += 4;
-		op += 4;
-		t0 = ToLinear8[(ca += wp[3]) & mask];
-		t1 = ToLinear8[(cb += wp[2]) & mask];
-		t2 = ToLinear8[(cg += wp[1]) & mask];
-		t3 = ToLinear8[(cr += wp[0]) & mask];
-		op[0] = t0;
-		op[1] = t1;
-		op[2] = t2;
-		op[3] = t3;
-	    }
-	} else {
-	    REPEAT(stride, *op = ToLinear8[*wp&mask]; wp++; op++)
-	    n -= stride;
-	    while (n > 0) {
-		REPEAT(stride,
-		    wp[stride] += *wp; *op = ToLinear8[*wp&mask]; wp++; op++)
-		n -= stride;
-	    }
-	}
-    }
-}
-
-/*
- * State block for each open TIFF
- * file using PixarLog compression/decompression.
- */
-typedef	struct {
-	TIFFPredictorState	predict;
-	z_stream		stream;
-	uint16			*tbuf; 
-	uint16			stride;
-	int			state;
-	int			user_datafmt;
-	int			quality;
-#define PLSTATE_INIT 1
-
-	TIFFVSetMethod		vgetparent;	/* super-class method */
-	TIFFVSetMethod		vsetparent;	/* super-class method */
-
-	float *ToLinearF;
-	uint16 *ToLinear16;
-	unsigned char *ToLinear8;
-	uint16  *FromLT2;
-	uint16  *From14; /* Really for 16-bit data, but we shift down 2 */
-	uint16  *From8;
-	
-} PixarLogState;
-
-static int
-PixarLogMakeTables(PixarLogState *sp)
-{
-
-/*
- *    We make several tables here to convert between various external
- *    representations (float, 16-bit, and 8-bit) and the internal
- *    11-bit companded representation.  The 11-bit representation has two
- *    distinct regions.  A linear bottom end up through .018316 in steps
- *    of about .000073, and a region of constant ratio up to about 25.
- *    These floating point numbers are stored in the main table ToLinearF. 
- *    All other tables are derived from this one.  The tables (and the
- *    ratios) are continuous at the internal seam.
- */
-
-    int  nlin, lt2size;
-    int  i, j;
-    double  b, c, linstep, v;
-    float *ToLinearF;
-    uint16 *ToLinear16;
-    unsigned char *ToLinear8;
-    uint16  *FromLT2;
-    uint16  *From14; /* Really for 16-bit data, but we shift down 2 */
-    uint16  *From8;
-
-    c = log(RATIO);	
-    nlin = (int)(1./c);	/* nlin must be an integer */
-    c = 1./nlin;
-    b = exp(-c*ONE);	/* multiplicative scale factor [b*exp(c*ONE) = 1] */
-    linstep = b*c*exp(1.);
-
-    LogK1 = (float)(1./c);	/* if (v >= 2)  token = k1*log(v*k2) */
-    LogK2 = (float)(1./b);
-    lt2size = (int)(2./linstep) + 1;
-    FromLT2 = (uint16 *)_TIFFmalloc(lt2size*sizeof(uint16));
-    From14 = (uint16 *)_TIFFmalloc(16384*sizeof(uint16));
-    From8 = (uint16 *)_TIFFmalloc(256*sizeof(uint16));
-    ToLinearF = (float *)_TIFFmalloc(TSIZEP1 * sizeof(float));
-    ToLinear16 = (uint16 *)_TIFFmalloc(TSIZEP1 * sizeof(uint16));
-    ToLinear8 = (unsigned char *)_TIFFmalloc(TSIZEP1 * sizeof(unsigned char));
-    if (FromLT2 == NULL || From14  == NULL || From8   == NULL ||
-	 ToLinearF == NULL || ToLinear16 == NULL || ToLinear8 == NULL) {
-	if (FromLT2) _TIFFfree(FromLT2);
-	if (From14) _TIFFfree(From14);
-	if (From8) _TIFFfree(From8);
-	if (ToLinearF) _TIFFfree(ToLinearF);
-	if (ToLinear16) _TIFFfree(ToLinear16);
-	if (ToLinear8) _TIFFfree(ToLinear8);
-	sp->FromLT2 = NULL;
-	sp->From14 = NULL;
-	sp->From8 = NULL;
-	sp->ToLinearF = NULL;
-	sp->ToLinear16 = NULL;
-	sp->ToLinear8 = NULL;
-	return 0;
-    }
-
-    j = 0;
-
-    for (i = 0; i < nlin; i++)  {
-	v = i * linstep;
-	ToLinearF[j++] = (float)v;
-    }
-
-    for (i = nlin; i < TSIZE; i++)
-	ToLinearF[j++] = (float)(b*exp(c*i));
-
-    ToLinearF[2048] = ToLinearF[2047];
-
-    for (i = 0; i < TSIZEP1; i++)  {
-	v = ToLinearF[i]*65535.0 + 0.5;
-	ToLinear16[i] = (v > 65535.0) ? 65535 : (uint16)v;
-	v = ToLinearF[i]*255.0  + 0.5;
-	ToLinear8[i]  = (v > 255.0) ? 255 : (unsigned char)v;
-    }
-
-    j = 0;
-    for (i = 0; i < lt2size; i++)  {
-	if ((i*linstep)*(i*linstep) > ToLinearF[j]*ToLinearF[j+1])
-	    j++;
-	FromLT2[i] = j;
-    }
-
-    /*
-     * Since we lose info anyway on 16-bit data, we set up a 14-bit
-     * table and shift 16-bit values down two bits on input.
-     * saves a little table space.
-     */
-    j = 0;
-    for (i = 0; i < 16384; i++)  {
-	while ((i/16383.)*(i/16383.) > ToLinearF[j]*ToLinearF[j+1])
-	    j++;
-	From14[i] = j;
-    }
-
-    j = 0;
-    for (i = 0; i < 256; i++)  {
-	while ((i/255.)*(i/255.) > ToLinearF[j]*ToLinearF[j+1])
-	    j++;
-	From8[i] = j;
-    }
-
-    Fltsize = (float)(lt2size/2);
-
-    sp->ToLinearF = ToLinearF;
-    sp->ToLinear16 = ToLinear16;
-    sp->ToLinear8 = ToLinear8;
-    sp->FromLT2 = FromLT2;
-    sp->From14 = From14;
-    sp->From8 = From8;
-
-    return 1;
-}
-
-#define DecoderState(tif)	((PixarLogState*) (tif)->tif_data)
-#define EncoderState(tif)	((PixarLogState*) (tif)->tif_data)
-
-static int PixarLogEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s);
-static int PixarLogDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s);
-
-#define PIXARLOGDATAFMT_UNKNOWN	-1
-
-static int
-PixarLogGuessDataFmt(TIFFDirectory *td)
-{
-	int guess = PIXARLOGDATAFMT_UNKNOWN;
-	int format = td->td_sampleformat;
-
-	/* If the user didn't tell us his datafmt,
-	 * take our best guess from the bitspersample.
-	 */
-	switch (td->td_bitspersample) {
-	 case 32:
-		if (format == SAMPLEFORMAT_IEEEFP)
-			guess = PIXARLOGDATAFMT_FLOAT;
-		break;
-	 case 16:
-		if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT)
-			guess = PIXARLOGDATAFMT_16BIT;
-		break;
-	 case 12:
-		if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_INT)
-			guess = PIXARLOGDATAFMT_12BITPICIO;
-		break;
-	 case 11:
-		if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT)
-			guess = PIXARLOGDATAFMT_11BITLOG;
-		break;
-	 case 8:
-		if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT)
-			guess = PIXARLOGDATAFMT_8BIT;
-		break;
-	}
-
-	return guess;
-}
-
-static tmsize_t
-multiply_ms(tmsize_t m1, tmsize_t m2)
-{
-	tmsize_t bytes = m1 * m2;
-
-	if (m1 && bytes / m1 != m2)
-		bytes = 0;
-
-	return bytes;
-}
-
-static int
-PixarLogFixupTags(TIFF* tif)
-{
-	(void) tif;
-	return (1);
-}
-
-static int
-PixarLogSetupDecode(TIFF* tif)
-{
-	static const char module[] = "PixarLogSetupDecode";
-	TIFFDirectory *td = &tif->tif_dir;
-	PixarLogState* sp = DecoderState(tif);
-	tmsize_t tbuf_size;
-
-	assert(sp != NULL);
-
-	/* Make sure no byte swapping happens on the data
-	 * after decompression. */
-	tif->tif_postdecode = _TIFFNoPostDecode;  
-
-	/* for some reason, we can't do this in TIFFInitPixarLog */
-
-	sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ?
-	    td->td_samplesperpixel : 1);
-	tbuf_size = multiply_ms(multiply_ms(multiply_ms(sp->stride, td->td_imagewidth),
-				      td->td_rowsperstrip), sizeof(uint16));
-	if (tbuf_size == 0)
-		return (0);   /* TODO: this is an error return without error report through TIFFErrorExt */
-	sp->tbuf = (uint16 *) _TIFFmalloc(tbuf_size+sizeof(uint16)*sp->stride);
-	if (sp->tbuf == NULL)
-		return (0);
-	if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN)
-		sp->user_datafmt = PixarLogGuessDataFmt(td);
-	if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-			"PixarLog compression can't handle bits depth/data format combination (depth: %d)", 
-			td->td_bitspersample);
-		return (0);
-	}
-
-	if (inflateInit(&sp->stream) != Z_OK) {
-		TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg);
-		return (0);
-	} else {
-		sp->state |= PLSTATE_INIT;
-		return (1);
-	}
-}
-
-/*
- * Setup state for decoding a strip.
- */
-static int
-PixarLogPreDecode(TIFF* tif, uint16 s)
-{
-	static const char module[] = "PixarLogPreDecode";
-	PixarLogState* sp = DecoderState(tif);
-
-	(void) s;
-	assert(sp != NULL);
-	sp->stream.next_in = tif->tif_rawdata;
-	assert(sizeof(sp->stream.avail_in)==4);  /* if this assert gets raised,
-	    we need to simplify this code to reflect a ZLib that is likely updated
-	    to deal with 8byte memory sizes, though this code will respond
-	    apropriately even before we simplify it */
-	sp->stream.avail_in = (uInt) tif->tif_rawcc;
-	if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc)
-	{
-		TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
-		return (0);
-	}
-	return (inflateReset(&sp->stream) == Z_OK);
-}
-
-static int
-PixarLogDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
-{
-	static const char module[] = "PixarLogDecode";
-	TIFFDirectory *td = &tif->tif_dir;
-	PixarLogState* sp = DecoderState(tif);
-	tmsize_t i;
-	tmsize_t nsamples;
-	int llen;
-	uint16 *up;
-
-	switch (sp->user_datafmt) {
-	case PIXARLOGDATAFMT_FLOAT:
-		nsamples = occ / sizeof(float);	/* XXX float == 32 bits */
-		break;
-	case PIXARLOGDATAFMT_16BIT:
-	case PIXARLOGDATAFMT_12BITPICIO:
-	case PIXARLOGDATAFMT_11BITLOG:
-		nsamples = occ / sizeof(uint16); /* XXX uint16 == 16 bits */
-		break;
-	case PIXARLOGDATAFMT_8BIT:
-	case PIXARLOGDATAFMT_8BITABGR:
-		nsamples = occ;
-		break;
-	default:
-		TIFFErrorExt(tif->tif_clientdata, module,
-			"%d bit input not supported in PixarLog",
-			td->td_bitspersample);
-		return 0;
-	}
-
-	llen = sp->stride * td->td_imagewidth;
-
-	(void) s;
-	assert(sp != NULL);
-	sp->stream.next_out = (unsigned char *) sp->tbuf;
-	assert(sizeof(sp->stream.avail_out)==4);  /* if this assert gets raised,
-	    we need to simplify this code to reflect a ZLib that is likely updated
-	    to deal with 8byte memory sizes, though this code will respond
-	    apropriately even before we simplify it */
-	sp->stream.avail_out = (uInt) (nsamples * sizeof(uint16));
-	if (sp->stream.avail_out != nsamples * sizeof(uint16))
-	{
-		TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
-		return (0);
-	}
-	do {
-		int state = inflate(&sp->stream, Z_PARTIAL_FLUSH);
-		if (state == Z_STREAM_END) {
-			break;			/* XXX */
-		}
-		if (state == Z_DATA_ERROR) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-			    "Decoding error at scanline %lu, %s",
-			    (unsigned long) tif->tif_row, sp->stream.msg);
-			if (inflateSync(&sp->stream) != Z_OK)
-				return (0);
-			continue;
-		}
-		if (state != Z_OK) {
-			TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s",
-			    sp->stream.msg);
-			return (0);
-		}
-	} while (sp->stream.avail_out > 0);
-
-	/* hopefully, we got all the bytes we needed */
-	if (sp->stream.avail_out != 0) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-		    "Not enough data at scanline %lu (short " TIFF_UINT64_FORMAT " bytes)",
-		    (unsigned long) tif->tif_row, (TIFF_UINT64_T) sp->stream.avail_out);
-		return (0);
-	}
-
-	up = sp->tbuf;
-	/* Swap bytes in the data if from a different endian machine. */
-	if (tif->tif_flags & TIFF_SWAB)
-		TIFFSwabArrayOfShort(up, nsamples);
-
-	/*
-	 * if llen is not an exact multiple of nsamples, the decode operation
-	 * may overflow the output buffer, so truncate it enough to prevent
-	 * that but still salvage as much data as possible.
-	 */
-	if (nsamples % llen) { 
-		TIFFWarningExt(tif->tif_clientdata, module,
-			"stride %lu is not a multiple of sample count, "
-			"%lu, data truncated.", (unsigned long) llen, (unsigned long) nsamples);
-		nsamples -= nsamples % llen;
-	}
-
-	for (i = 0; i < nsamples; i += llen, up += llen) {
-		switch (sp->user_datafmt)  {
-		case PIXARLOGDATAFMT_FLOAT:
-			horizontalAccumulateF(up, llen, sp->stride,
-					(float *)op, sp->ToLinearF);
-			op += llen * sizeof(float);
-			break;
-		case PIXARLOGDATAFMT_16BIT:
-			horizontalAccumulate16(up, llen, sp->stride,
-					(uint16 *)op, sp->ToLinear16);
-			op += llen * sizeof(uint16);
-			break;
-		case PIXARLOGDATAFMT_12BITPICIO:
-			horizontalAccumulate12(up, llen, sp->stride,
-					(int16 *)op, sp->ToLinearF);
-			op += llen * sizeof(int16);
-			break;
-		case PIXARLOGDATAFMT_11BITLOG:
-			horizontalAccumulate11(up, llen, sp->stride,
-					(uint16 *)op);
-			op += llen * sizeof(uint16);
-			break;
-		case PIXARLOGDATAFMT_8BIT:
-			horizontalAccumulate8(up, llen, sp->stride,
-					(unsigned char *)op, sp->ToLinear8);
-			op += llen * sizeof(unsigned char);
-			break;
-		case PIXARLOGDATAFMT_8BITABGR:
-			horizontalAccumulate8abgr(up, llen, sp->stride,
-					(unsigned char *)op, sp->ToLinear8);
-			op += llen * sizeof(unsigned char);
-			break;
-		default:
-			TIFFErrorExt(tif->tif_clientdata, module,
-				  "Unsupported bits/sample: %d",
-				  td->td_bitspersample);
-			return (0);
-		}
-	}
-
-	return (1);
-}
-
-static int
-PixarLogSetupEncode(TIFF* tif)
-{
-	static const char module[] = "PixarLogSetupEncode";
-	TIFFDirectory *td = &tif->tif_dir;
-	PixarLogState* sp = EncoderState(tif);
-	tmsize_t tbuf_size;
-
-	assert(sp != NULL);
-
-	/* for some reason, we can't do this in TIFFInitPixarLog */
-
-	sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ?
-	    td->td_samplesperpixel : 1);
-	tbuf_size = multiply_ms(multiply_ms(multiply_ms(sp->stride, td->td_imagewidth),
-				      td->td_rowsperstrip), sizeof(uint16));
-	if (tbuf_size == 0)
-		return (0);  /* TODO: this is an error return without error report through TIFFErrorExt */
-	sp->tbuf = (uint16 *) _TIFFmalloc(tbuf_size);
-	if (sp->tbuf == NULL)
-		return (0);
-	if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN)
-		sp->user_datafmt = PixarLogGuessDataFmt(td);
-	if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) {
-		TIFFErrorExt(tif->tif_clientdata, module, "PixarLog compression can't handle %d bit linear encodings", td->td_bitspersample);
-		return (0);
-	}
-
-	if (deflateInit(&sp->stream, sp->quality) != Z_OK) {
-		TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg);
-		return (0);
-	} else {
-		sp->state |= PLSTATE_INIT;
-		return (1);
-	}
-}
-
-/*
- * Reset encoding state at the start of a strip.
- */
-static int
-PixarLogPreEncode(TIFF* tif, uint16 s)
-{
-	static const char module[] = "PixarLogPreEncode";
-	PixarLogState *sp = EncoderState(tif);
-
-	(void) s;
-	assert(sp != NULL);
-	sp->stream.next_out = tif->tif_rawdata;
-	assert(sizeof(sp->stream.avail_out)==4);  /* if this assert gets raised,
-	    we need to simplify this code to reflect a ZLib that is likely updated
-	    to deal with 8byte memory sizes, though this code will respond
-	    apropriately even before we simplify it */
-	sp->stream.avail_out = tif->tif_rawdatasize;
-	if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize)
-	{
-		TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
-		return (0);
-	}
-	return (deflateReset(&sp->stream) == Z_OK);
-}
-
-static void
-horizontalDifferenceF(float *ip, int n, int stride, uint16 *wp, uint16 *FromLT2)
-{
-    int32 r1, g1, b1, a1, r2, g2, b2, a2, mask;
-    float fltsize = Fltsize;
-
-#define  CLAMP(v) ( (v<(float)0.)   ? 0				\
-		  : (v<(float)2.)   ? FromLT2[(int)(v*fltsize)]	\
-		  : (v>(float)24.2) ? 2047			\
-		  : LogK1*log(v*LogK2) + 0.5 )
-
-    mask = CODE_MASK;
-    if (n >= stride) {
-	if (stride == 3) {
-	    r2 = wp[0] = (uint16) CLAMP(ip[0]);
-	    g2 = wp[1] = (uint16) CLAMP(ip[1]);
-	    b2 = wp[2] = (uint16) CLAMP(ip[2]);
-	    n -= 3;
-	    while (n > 0) {
-		n -= 3;
-		wp += 3;
-		ip += 3;
-		r1 = (int32) CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1;
-		g1 = (int32) CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1;
-		b1 = (int32) CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1;
-	    }
-	} else if (stride == 4) {
-	    r2 = wp[0] = (uint16) CLAMP(ip[0]);
-	    g2 = wp[1] = (uint16) CLAMP(ip[1]);
-	    b2 = wp[2] = (uint16) CLAMP(ip[2]);
-	    a2 = wp[3] = (uint16) CLAMP(ip[3]);
-	    n -= 4;
-	    while (n > 0) {
-		n -= 4;
-		wp += 4;
-		ip += 4;
-		r1 = (int32) CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1;
-		g1 = (int32) CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1;
-		b1 = (int32) CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1;
-		a1 = (int32) CLAMP(ip[3]); wp[3] = (a1-a2) & mask; a2 = a1;
-	    }
-	} else {
-	    ip += n - 1;	/* point to last one */
-	    wp += n - 1;	/* point to last one */
-	    n -= stride;
-	    while (n > 0) {
-		REPEAT(stride, wp[0] = (uint16) CLAMP(ip[0]);
-				wp[stride] -= wp[0];
-				wp[stride] &= mask;
-				wp--; ip--)
-		n -= stride;
-	    }
-	    REPEAT(stride, wp[0] = (uint16) CLAMP(ip[0]); wp--; ip--)
-	}
-    }
-}
-
-static void
-horizontalDifference16(unsigned short *ip, int n, int stride, 
-	unsigned short *wp, uint16 *From14)
-{
-    register int  r1, g1, b1, a1, r2, g2, b2, a2, mask;
-
-/* assumption is unsigned pixel values */
-#undef   CLAMP
-#define  CLAMP(v) From14[(v) >> 2]
-
-    mask = CODE_MASK;
-    if (n >= stride) {
-	if (stride == 3) {
-	    r2 = wp[0] = CLAMP(ip[0]);  g2 = wp[1] = CLAMP(ip[1]);
-	    b2 = wp[2] = CLAMP(ip[2]);
-	    n -= 3;
-	    while (n > 0) {
-		n -= 3;
-		wp += 3;
-		ip += 3;
-		r1 = CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1;
-		g1 = CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1;
-		b1 = CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1;
-	    }
-	} else if (stride == 4) {
-	    r2 = wp[0] = CLAMP(ip[0]);  g2 = wp[1] = CLAMP(ip[1]);
-	    b2 = wp[2] = CLAMP(ip[2]);  a2 = wp[3] = CLAMP(ip[3]);
-	    n -= 4;
-	    while (n > 0) {
-		n -= 4;
-		wp += 4;
-		ip += 4;
-		r1 = CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1;
-		g1 = CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1;
-		b1 = CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1;
-		a1 = CLAMP(ip[3]); wp[3] = (a1-a2) & mask; a2 = a1;
-	    }
-	} else {
-	    ip += n - 1;	/* point to last one */
-	    wp += n - 1;	/* point to last one */
-	    n -= stride;
-	    while (n > 0) {
-		REPEAT(stride, wp[0] = CLAMP(ip[0]);
-				wp[stride] -= wp[0];
-				wp[stride] &= mask;
-				wp--; ip--)
-		n -= stride;
-	    }
-	    REPEAT(stride, wp[0] = CLAMP(ip[0]); wp--; ip--)
-	}
-    }
-}
-
-
-static void
-horizontalDifference8(unsigned char *ip, int n, int stride, 
-	unsigned short *wp, uint16 *From8)
-{
-    register int  r1, g1, b1, a1, r2, g2, b2, a2, mask;
-
-#undef	 CLAMP
-#define  CLAMP(v) (From8[(v)])
-
-    mask = CODE_MASK;
-    if (n >= stride) {
-	if (stride == 3) {
-	    r2 = wp[0] = CLAMP(ip[0]);  g2 = wp[1] = CLAMP(ip[1]);
-	    b2 = wp[2] = CLAMP(ip[2]);
-	    n -= 3;
-	    while (n > 0) {
-		n -= 3;
-		r1 = CLAMP(ip[3]); wp[3] = (r1-r2) & mask; r2 = r1;
-		g1 = CLAMP(ip[4]); wp[4] = (g1-g2) & mask; g2 = g1;
-		b1 = CLAMP(ip[5]); wp[5] = (b1-b2) & mask; b2 = b1;
-		wp += 3;
-		ip += 3;
-	    }
-	} else if (stride == 4) {
-	    r2 = wp[0] = CLAMP(ip[0]);  g2 = wp[1] = CLAMP(ip[1]);
-	    b2 = wp[2] = CLAMP(ip[2]);  a2 = wp[3] = CLAMP(ip[3]);
-	    n -= 4;
-	    while (n > 0) {
-		n -= 4;
-		r1 = CLAMP(ip[4]); wp[4] = (r1-r2) & mask; r2 = r1;
-		g1 = CLAMP(ip[5]); wp[5] = (g1-g2) & mask; g2 = g1;
-		b1 = CLAMP(ip[6]); wp[6] = (b1-b2) & mask; b2 = b1;
-		a1 = CLAMP(ip[7]); wp[7] = (a1-a2) & mask; a2 = a1;
-		wp += 4;
-		ip += 4;
-	    }
-	} else {
-	    wp += n + stride - 1;	/* point to last one */
-	    ip += n + stride - 1;	/* point to last one */
-	    n -= stride;
-	    while (n > 0) {
-		REPEAT(stride, wp[0] = CLAMP(ip[0]);
-				wp[stride] -= wp[0];
-				wp[stride] &= mask;
-				wp--; ip--)
-		n -= stride;
-	    }
-	    REPEAT(stride, wp[0] = CLAMP(ip[0]); wp--; ip--)
-	}
-    }
-}
-
-/*
- * Encode a chunk of pixels.
- */
-static int
-PixarLogEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
-{
-	static const char module[] = "PixarLogEncode";
-	TIFFDirectory *td = &tif->tif_dir;
-	PixarLogState *sp = EncoderState(tif);
-	tmsize_t i;
-	tmsize_t n;
-	int llen;
-	unsigned short * up;
-
-	(void) s;
-
-	switch (sp->user_datafmt) {
-	case PIXARLOGDATAFMT_FLOAT:
-		n = cc / sizeof(float);		/* XXX float == 32 bits */
-		break;
-	case PIXARLOGDATAFMT_16BIT:
-	case PIXARLOGDATAFMT_12BITPICIO:
-	case PIXARLOGDATAFMT_11BITLOG:
-		n = cc / sizeof(uint16);	/* XXX uint16 == 16 bits */
-		break;
-	case PIXARLOGDATAFMT_8BIT:
-	case PIXARLOGDATAFMT_8BITABGR:
-		n = cc;
-		break;
-	default:
-		TIFFErrorExt(tif->tif_clientdata, module,
-			"%d bit input not supported in PixarLog",
-			td->td_bitspersample);
-		return 0;
-	}
-
-	llen = sp->stride * td->td_imagewidth;
-
-	for (i = 0, up = sp->tbuf; i < n; i += llen, up += llen) {
-		switch (sp->user_datafmt)  {
-		case PIXARLOGDATAFMT_FLOAT:
-			horizontalDifferenceF((float *)bp, llen, 
-				sp->stride, up, sp->FromLT2);
-			bp += llen * sizeof(float);
-			break;
-		case PIXARLOGDATAFMT_16BIT:
-			horizontalDifference16((uint16 *)bp, llen, 
-				sp->stride, up, sp->From14);
-			bp += llen * sizeof(uint16);
-			break;
-		case PIXARLOGDATAFMT_8BIT:
-			horizontalDifference8((unsigned char *)bp, llen, 
-				sp->stride, up, sp->From8);
-			bp += llen * sizeof(unsigned char);
-			break;
-		default:
-			TIFFErrorExt(tif->tif_clientdata, module,
-				"%d bit input not supported in PixarLog",
-				td->td_bitspersample);
-			return 0;
-		}
-	}
- 
-	sp->stream.next_in = (unsigned char *) sp->tbuf;
-	assert(sizeof(sp->stream.avail_in)==4);  /* if this assert gets raised,
-	    we need to simplify this code to reflect a ZLib that is likely updated
-	    to deal with 8byte memory sizes, though this code will respond
-	    apropriately even before we simplify it */
-	sp->stream.avail_in = (uInt) (n * sizeof(uint16));
-	if ((sp->stream.avail_in / sizeof(uint16)) != (uInt) n)
-	{
-		TIFFErrorExt(tif->tif_clientdata, module,
-			     "ZLib cannot deal with buffers this size");
-		return (0);
-	}
-
-	do {
-		if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) {
-			TIFFErrorExt(tif->tif_clientdata, module, "Encoder error: %s",
-			    sp->stream.msg);
-			return (0);
-		}
-		if (sp->stream.avail_out == 0) {
-			tif->tif_rawcc = tif->tif_rawdatasize;
-			TIFFFlushData1(tif);
-			sp->stream.next_out = tif->tif_rawdata;
-			sp->stream.avail_out = (uInt) tif->tif_rawdatasize;  /* this is a safe typecast, as check is made already in PixarLogPreEncode */
-		}
-	} while (sp->stream.avail_in > 0);
-	return (1);
-}
-
-/*
- * Finish off an encoded strip by flushing the last
- * string and tacking on an End Of Information code.
- */
-
-static int
-PixarLogPostEncode(TIFF* tif)
-{
-	static const char module[] = "PixarLogPostEncode";
-	PixarLogState *sp = EncoderState(tif);
-	int state;
-
-	sp->stream.avail_in = 0;
-
-	do {
-		state = deflate(&sp->stream, Z_FINISH);
-		switch (state) {
-		case Z_STREAM_END:
-		case Z_OK:
-		    if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) {
-			    tif->tif_rawcc =
-				tif->tif_rawdatasize - sp->stream.avail_out;
-			    TIFFFlushData1(tif);
-			    sp->stream.next_out = tif->tif_rawdata;
-			    sp->stream.avail_out = (uInt) tif->tif_rawdatasize;  /* this is a safe typecast, as check is made already in PixarLogPreEncode */
-		    }
-		    break;
-		default:
-			TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s",
-			sp->stream.msg);
-		    return (0);
-		}
-	} while (state != Z_STREAM_END);
-	return (1);
-}
-
-static void
-PixarLogClose(TIFF* tif)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-
-	/* In a really sneaky (and really incorrect, and untruthfull, and
-	 * troublesome, and error-prone) maneuver that completely goes against
-	 * the spirit of TIFF, and breaks TIFF, on close, we covertly
-	 * modify both bitspersample and sampleformat in the directory to
-	 * indicate 8-bit linear.  This way, the decode "just works" even for
-	 * readers that don't know about PixarLog, or how to set
-	 * the PIXARLOGDATFMT pseudo-tag.
-	 */
-	td->td_bitspersample = 8;
-	td->td_sampleformat = SAMPLEFORMAT_UINT;
-}
-
-static void
-PixarLogCleanup(TIFF* tif)
-{
-	PixarLogState* sp = (PixarLogState*) tif->tif_data;
-
-	assert(sp != 0);
-
-	(void)TIFFPredictorCleanup(tif);
-
-	tif->tif_tagmethods.vgetfield = sp->vgetparent;
-	tif->tif_tagmethods.vsetfield = sp->vsetparent;
-
-	if (sp->FromLT2) _TIFFfree(sp->FromLT2);
-	if (sp->From14) _TIFFfree(sp->From14);
-	if (sp->From8) _TIFFfree(sp->From8);
-	if (sp->ToLinearF) _TIFFfree(sp->ToLinearF);
-	if (sp->ToLinear16) _TIFFfree(sp->ToLinear16);
-	if (sp->ToLinear8) _TIFFfree(sp->ToLinear8);
-	if (sp->state&PLSTATE_INIT) {
-		if (tif->tif_mode == O_RDONLY)
-			inflateEnd(&sp->stream);
-		else
-			deflateEnd(&sp->stream);
-	}
-	if (sp->tbuf)
-		_TIFFfree(sp->tbuf);
-	_TIFFfree(sp);
-	tif->tif_data = NULL;
-
-	_TIFFSetDefaultCompressionState(tif);
-}
-
-static int
-PixarLogVSetField(TIFF* tif, uint32 tag, va_list ap)
-{
-    static const char module[] = "PixarLogVSetField";
-    PixarLogState *sp = (PixarLogState *)tif->tif_data;
-    int result;
-
-    switch (tag) {
-     case TIFFTAG_PIXARLOGQUALITY:
-		sp->quality = (int) va_arg(ap, int);
-		if (tif->tif_mode != O_RDONLY && (sp->state&PLSTATE_INIT)) {
-			if (deflateParams(&sp->stream,
-			    sp->quality, Z_DEFAULT_STRATEGY) != Z_OK) {
-				TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s",
-					sp->stream.msg);
-				return (0);
-			}
-		}
-		return (1);
-     case TIFFTAG_PIXARLOGDATAFMT:
-	sp->user_datafmt = (int) va_arg(ap, int);
-	/* Tweak the TIFF header so that the rest of libtiff knows what
-	 * size of data will be passed between app and library, and
-	 * assume that the app knows what it is doing and is not
-	 * confused by these header manipulations...
-	 */
-	switch (sp->user_datafmt) {
-	 case PIXARLOGDATAFMT_8BIT:
-	 case PIXARLOGDATAFMT_8BITABGR:
-	    TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
-	    TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
-	    break;
-	 case PIXARLOGDATAFMT_11BITLOG:
-	    TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16);
-	    TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
-	    break;
-	 case PIXARLOGDATAFMT_12BITPICIO:
-	    TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16);
-	    TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT);
-	    break;
-	 case PIXARLOGDATAFMT_16BIT:
-	    TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16);
-	    TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
-	    break;
-	 case PIXARLOGDATAFMT_FLOAT:
-	    TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 32);
-	    TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);
-	    break;
-	}
-	/*
-	 * Must recalculate sizes should bits/sample change.
-	 */
-	tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)(-1);
-	tif->tif_scanlinesize = TIFFScanlineSize(tif);
-	result = 1;		/* NB: pseudo tag */
-	break;
-     default:
-	result = (*sp->vsetparent)(tif, tag, ap);
-    }
-    return (result);
-}
-
-static int
-PixarLogVGetField(TIFF* tif, uint32 tag, va_list ap)
-{
-    PixarLogState *sp = (PixarLogState *)tif->tif_data;
-
-    switch (tag) {
-     case TIFFTAG_PIXARLOGQUALITY:
-	*va_arg(ap, int*) = sp->quality;
-	break;
-     case TIFFTAG_PIXARLOGDATAFMT:
-	*va_arg(ap, int*) = sp->user_datafmt;
-	break;
-     default:
-	return (*sp->vgetparent)(tif, tag, ap);
-    }
-    return (1);
-}
-
-static const TIFFField pixarlogFields[] = {
-    {TIFFTAG_PIXARLOGDATAFMT, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL},
-    {TIFFTAG_PIXARLOGQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL}
-};
-
-int
-TIFFInitPixarLog(TIFF* tif, int scheme)
-{
-	static const char module[] = "TIFFInitPixarLog";
-
-	PixarLogState* sp;
-
-	assert(scheme == COMPRESSION_PIXARLOG);
-
-	/*
-	 * Merge codec-specific tag information.
-	 */
-	if (!_TIFFMergeFields(tif, pixarlogFields,
-			      TIFFArrayCount(pixarlogFields))) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-			     "Merging PixarLog codec-specific tags failed");
-		return 0;
-	}
-
-	/*
-	 * Allocate state block so tag methods have storage to record values.
-	 */
-	tif->tif_data = (uint8*) _TIFFmalloc(sizeof (PixarLogState));
-	if (tif->tif_data == NULL)
-		goto bad;
-	sp = (PixarLogState*) tif->tif_data;
-	_TIFFmemset(sp, 0, sizeof (*sp));
-	sp->stream.data_type = Z_BINARY;
-	sp->user_datafmt = PIXARLOGDATAFMT_UNKNOWN;
-
-	/*
-	 * Install codec methods.
-	 */
-	tif->tif_fixuptags = PixarLogFixupTags; 
-	tif->tif_setupdecode = PixarLogSetupDecode;
-	tif->tif_predecode = PixarLogPreDecode;
-	tif->tif_decoderow = PixarLogDecode;
-	tif->tif_decodestrip = PixarLogDecode;  
-	tif->tif_decodetile = PixarLogDecode;
-	tif->tif_setupencode = PixarLogSetupEncode;
-	tif->tif_preencode = PixarLogPreEncode;
-	tif->tif_postencode = PixarLogPostEncode;
-	tif->tif_encoderow = PixarLogEncode;  
-	tif->tif_encodestrip = PixarLogEncode;
-	tif->tif_encodetile = PixarLogEncode;  
-	tif->tif_close = PixarLogClose;
-	tif->tif_cleanup = PixarLogCleanup;
-
-	/* Override SetField so we can handle our private pseudo-tag */
-	sp->vgetparent = tif->tif_tagmethods.vgetfield;
-	tif->tif_tagmethods.vgetfield = PixarLogVGetField;   /* hook for codec tags */
-	sp->vsetparent = tif->tif_tagmethods.vsetfield;
-	tif->tif_tagmethods.vsetfield = PixarLogVSetField;   /* hook for codec tags */
-
-	/* Default values for codec-specific fields */
-	sp->quality = Z_DEFAULT_COMPRESSION; /* default comp. level */
-	sp->state = 0;
-
-	/* we don't wish to use the predictor, 
-	 * the default is none, which predictor value 1
-	 */
-	(void) TIFFPredictorInit(tif);
-
-	/*
-	 * build the companding tables 
-	 */
-	PixarLogMakeTables(sp);
-
-	return (1);
-bad:
-	TIFFErrorExt(tif->tif_clientdata, module,
-		     "No space for PixarLog state block");
-	return (0);
-}
-#endif /* PIXARLOG_SUPPORT */
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Id: tif_pixarlog.c,v 1.13 2015/02/19 22:39:59 drolon Exp $ */
+
+/*
+ * Copyright (c) 1996-1997 Sam Leffler
+ * Copyright (c) 1996 Pixar
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and 
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Pixar, Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Pixar, Sam Leffler and Silicon Graphics.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
+ * 
+ * IN NO EVENT SHALL PIXAR, SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
+ * OF THIS SOFTWARE.
+ */
+
+#include "tiffiop.h"
+#ifdef PIXARLOG_SUPPORT
+
+/*
+ * TIFF Library.
+ * PixarLog Compression Support
+ *
+ * Contributed by Dan McCoy.
+ *
+ * PixarLog film support uses the TIFF library to store companded
+ * 11 bit values into a tiff file, which are compressed using the 
+ * zip compressor.  
+ *
+ * The codec can take as input and produce as output 32-bit IEEE float values 
+ * as well as 16-bit or 8-bit unsigned integer values.
+ *
+ * On writing any of the above are converted into the internal
+ * 11-bit log format.   In the case of  8 and 16 bit values, the
+ * input is assumed to be unsigned linear color values that represent
+ * the range 0-1.  In the case of IEEE values, the 0-1 range is assumed to
+ * be the normal linear color range, in addition over 1 values are
+ * accepted up to a value of about 25.0 to encode "hot" hightlights and such.
+ * The encoding is lossless for 8-bit values, slightly lossy for the
+ * other bit depths.  The actual color precision should be better
+ * than the human eye can perceive with extra room to allow for
+ * error introduced by further image computation.  As with any quantized
+ * color format, it is possible to perform image calculations which
+ * expose the quantization error. This format should certainly be less 
+ * susceptable to such errors than standard 8-bit encodings, but more
+ * susceptable than straight 16-bit or 32-bit encodings.
+ *
+ * On reading the internal format is converted to the desired output format.
+ * The program can request which format it desires by setting the internal
+ * pseudo tag TIFFTAG_PIXARLOGDATAFMT to one of these possible values:
+ *  PIXARLOGDATAFMT_FLOAT     = provide IEEE float values.
+ *  PIXARLOGDATAFMT_16BIT     = provide unsigned 16-bit integer values
+ *  PIXARLOGDATAFMT_8BIT      = provide unsigned 8-bit integer values
+ *
+ * alternately PIXARLOGDATAFMT_8BITABGR provides unsigned 8-bit integer
+ * values with the difference that if there are exactly three or four channels
+ * (rgb or rgba) it swaps the channel order (bgr or abgr).
+ *
+ * PIXARLOGDATAFMT_11BITLOG provides the internal encoding directly
+ * packed in 16-bit values.   However no tools are supplied for interpreting
+ * these values.
+ *
+ * "hot" (over 1.0) areas written in floating point get clamped to
+ * 1.0 in the integer data types.
+ *
+ * When the file is closed after writing, the bit depth and sample format
+ * are set always to appear as if 8-bit data has been written into it.
+ * That way a naive program unaware of the particulars of the encoding
+ * gets the format it is most likely able to handle.
+ *
+ * The codec does it's own horizontal differencing step on the coded
+ * values so the libraries predictor stuff should be turned off.
+ * The codec also handle byte swapping the encoded values as necessary
+ * since the library does not have the information necessary
+ * to know the bit depth of the raw unencoded buffer.
+ *
+ * NOTE: This decoder does not appear to update tif_rawcp, and tif_rawcc.
+ * This can cause problems with the implementation of CHUNKY_STRIP_READ_SUPPORT
+ * as noted in http://trac.osgeo.org/gdal/ticket/3894.   FrankW - Jan'11
+ */
+
+#include "tif_predict.h"
+#include "../ZLib/zlib.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+/* Tables for converting to/from 11 bit coded values */
+
+#define  TSIZE	 2048		/* decode table size (11-bit tokens) */
+#define  TSIZEP1 2049		/* Plus one for slop */
+#define  ONE	 1250		/* token value of 1.0 exactly */
+#define  RATIO	 1.004		/* nominal ratio for log part */
+
+#define CODE_MASK 0x7ff         /* 11 bits. */
+
+static float  Fltsize;
+static float  LogK1, LogK2;
+
+#define REPEAT(n, op)   { int i; i=n; do { i--; op; } while (i>0); }
+
+static void
+horizontalAccumulateF(uint16 *wp, int n, int stride, float *op,
+	float *ToLinearF)
+{
+    register unsigned int  cr, cg, cb, ca, mask;
+    register float  t0, t1, t2, t3;
+
+    if (n >= stride) {
+	mask = CODE_MASK;
+	if (stride == 3) {
+	    t0 = ToLinearF[cr = (wp[0] & mask)];
+	    t1 = ToLinearF[cg = (wp[1] & mask)];
+	    t2 = ToLinearF[cb = (wp[2] & mask)];
+	    op[0] = t0;
+	    op[1] = t1;
+	    op[2] = t2;
+	    n -= 3;
+	    while (n > 0) {
+		wp += 3;
+		op += 3;
+		n -= 3;
+		t0 = ToLinearF[(cr += wp[0]) & mask];
+		t1 = ToLinearF[(cg += wp[1]) & mask];
+		t2 = ToLinearF[(cb += wp[2]) & mask];
+		op[0] = t0;
+		op[1] = t1;
+		op[2] = t2;
+	    }
+	} else if (stride == 4) {
+	    t0 = ToLinearF[cr = (wp[0] & mask)];
+	    t1 = ToLinearF[cg = (wp[1] & mask)];
+	    t2 = ToLinearF[cb = (wp[2] & mask)];
+	    t3 = ToLinearF[ca = (wp[3] & mask)];
+	    op[0] = t0;
+	    op[1] = t1;
+	    op[2] = t2;
+	    op[3] = t3;
+	    n -= 4;
+	    while (n > 0) {
+		wp += 4;
+		op += 4;
+		n -= 4;
+		t0 = ToLinearF[(cr += wp[0]) & mask];
+		t1 = ToLinearF[(cg += wp[1]) & mask];
+		t2 = ToLinearF[(cb += wp[2]) & mask];
+		t3 = ToLinearF[(ca += wp[3]) & mask];
+		op[0] = t0;
+		op[1] = t1;
+		op[2] = t2;
+		op[3] = t3;
+	    }
+	} else {
+	    REPEAT(stride, *op = ToLinearF[*wp&mask]; wp++; op++)
+	    n -= stride;
+	    while (n > 0) {
+		REPEAT(stride,
+		    wp[stride] += *wp; *op = ToLinearF[*wp&mask]; wp++; op++)
+		n -= stride;
+	    }
+	}
+    }
+}
+
+static void
+horizontalAccumulate12(uint16 *wp, int n, int stride, int16 *op,
+	float *ToLinearF)
+{
+    register unsigned int  cr, cg, cb, ca, mask;
+    register float  t0, t1, t2, t3;
+
+#define SCALE12 2048.0F
+#define CLAMP12(t) (((t) < 3071) ? (uint16) (t) : 3071)
+
+    if (n >= stride) {
+	mask = CODE_MASK;
+	if (stride == 3) {
+	    t0 = ToLinearF[cr = (wp[0] & mask)] * SCALE12;
+	    t1 = ToLinearF[cg = (wp[1] & mask)] * SCALE12;
+	    t2 = ToLinearF[cb = (wp[2] & mask)] * SCALE12;
+	    op[0] = CLAMP12(t0);
+	    op[1] = CLAMP12(t1);
+	    op[2] = CLAMP12(t2);
+	    n -= 3;
+	    while (n > 0) {
+		wp += 3;
+		op += 3;
+		n -= 3;
+		t0 = ToLinearF[(cr += wp[0]) & mask] * SCALE12;
+		t1 = ToLinearF[(cg += wp[1]) & mask] * SCALE12;
+		t2 = ToLinearF[(cb += wp[2]) & mask] * SCALE12;
+		op[0] = CLAMP12(t0);
+		op[1] = CLAMP12(t1);
+		op[2] = CLAMP12(t2);
+	    }
+	} else if (stride == 4) {
+	    t0 = ToLinearF[cr = (wp[0] & mask)] * SCALE12;
+	    t1 = ToLinearF[cg = (wp[1] & mask)] * SCALE12;
+	    t2 = ToLinearF[cb = (wp[2] & mask)] * SCALE12;
+	    t3 = ToLinearF[ca = (wp[3] & mask)] * SCALE12;
+	    op[0] = CLAMP12(t0);
+	    op[1] = CLAMP12(t1);
+	    op[2] = CLAMP12(t2);
+	    op[3] = CLAMP12(t3);
+	    n -= 4;
+	    while (n > 0) {
+		wp += 4;
+		op += 4;
+		n -= 4;
+		t0 = ToLinearF[(cr += wp[0]) & mask] * SCALE12;
+		t1 = ToLinearF[(cg += wp[1]) & mask] * SCALE12;
+		t2 = ToLinearF[(cb += wp[2]) & mask] * SCALE12;
+		t3 = ToLinearF[(ca += wp[3]) & mask] * SCALE12;
+		op[0] = CLAMP12(t0);
+		op[1] = CLAMP12(t1);
+		op[2] = CLAMP12(t2);
+		op[3] = CLAMP12(t3);
+	    }
+	} else {
+	    REPEAT(stride, t0 = ToLinearF[*wp&mask] * SCALE12;
+                           *op = CLAMP12(t0); wp++; op++)
+	    n -= stride;
+	    while (n > 0) {
+		REPEAT(stride,
+		    wp[stride] += *wp; t0 = ToLinearF[wp[stride]&mask]*SCALE12;
+		    *op = CLAMP12(t0);  wp++; op++)
+		n -= stride;
+	    }
+	}
+    }
+}
+
+static void
+horizontalAccumulate16(uint16 *wp, int n, int stride, uint16 *op,
+	uint16 *ToLinear16)
+{
+    register unsigned int  cr, cg, cb, ca, mask;
+
+    if (n >= stride) {
+	mask = CODE_MASK;
+	if (stride == 3) {
+	    op[0] = ToLinear16[cr = (wp[0] & mask)];
+	    op[1] = ToLinear16[cg = (wp[1] & mask)];
+	    op[2] = ToLinear16[cb = (wp[2] & mask)];
+	    n -= 3;
+	    while (n > 0) {
+		wp += 3;
+		op += 3;
+		n -= 3;
+		op[0] = ToLinear16[(cr += wp[0]) & mask];
+		op[1] = ToLinear16[(cg += wp[1]) & mask];
+		op[2] = ToLinear16[(cb += wp[2]) & mask];
+	    }
+	} else if (stride == 4) {
+	    op[0] = ToLinear16[cr = (wp[0] & mask)];
+	    op[1] = ToLinear16[cg = (wp[1] & mask)];
+	    op[2] = ToLinear16[cb = (wp[2] & mask)];
+	    op[3] = ToLinear16[ca = (wp[3] & mask)];
+	    n -= 4;
+	    while (n > 0) {
+		wp += 4;
+		op += 4;
+		n -= 4;
+		op[0] = ToLinear16[(cr += wp[0]) & mask];
+		op[1] = ToLinear16[(cg += wp[1]) & mask];
+		op[2] = ToLinear16[(cb += wp[2]) & mask];
+		op[3] = ToLinear16[(ca += wp[3]) & mask];
+	    }
+	} else {
+	    REPEAT(stride, *op = ToLinear16[*wp&mask]; wp++; op++)
+	    n -= stride;
+	    while (n > 0) {
+		REPEAT(stride,
+		    wp[stride] += *wp; *op = ToLinear16[*wp&mask]; wp++; op++)
+		n -= stride;
+	    }
+	}
+    }
+}
+
+/* 
+ * Returns the log encoded 11-bit values with the horizontal
+ * differencing undone.
+ */
+static void
+horizontalAccumulate11(uint16 *wp, int n, int stride, uint16 *op)
+{
+    register unsigned int  cr, cg, cb, ca, mask;
+
+    if (n >= stride) {
+	mask = CODE_MASK;
+	if (stride == 3) {
+	    op[0] = cr = wp[0];  op[1] = cg = wp[1];  op[2] = cb = wp[2];
+	    n -= 3;
+	    while (n > 0) {
+		wp += 3;
+		op += 3;
+		n -= 3;
+		op[0] = (cr += wp[0]) & mask;
+		op[1] = (cg += wp[1]) & mask;
+		op[2] = (cb += wp[2]) & mask;
+	    }
+	} else if (stride == 4) {
+	    op[0] = cr = wp[0];  op[1] = cg = wp[1];
+	    op[2] = cb = wp[2];  op[3] = ca = wp[3];
+	    n -= 4;
+	    while (n > 0) {
+		wp += 4;
+		op += 4;
+		n -= 4;
+		op[0] = (cr += wp[0]) & mask;
+		op[1] = (cg += wp[1]) & mask;
+		op[2] = (cb += wp[2]) & mask;
+		op[3] = (ca += wp[3]) & mask;
+	    } 
+	} else {
+	    REPEAT(stride, *op = *wp&mask; wp++; op++)
+	    n -= stride;
+	    while (n > 0) {
+		REPEAT(stride,
+		    wp[stride] += *wp; *op = *wp&mask; wp++; op++)
+		n -= stride;
+	    }
+	}
+    }
+}
+
+static void
+horizontalAccumulate8(uint16 *wp, int n, int stride, unsigned char *op,
+	unsigned char *ToLinear8)
+{
+    register unsigned int  cr, cg, cb, ca, mask;
+
+    if (n >= stride) {
+	mask = CODE_MASK;
+	if (stride == 3) {
+	    op[0] = ToLinear8[cr = (wp[0] & mask)];
+	    op[1] = ToLinear8[cg = (wp[1] & mask)];
+	    op[2] = ToLinear8[cb = (wp[2] & mask)];
+	    n -= 3;
+	    while (n > 0) {
+		n -= 3;
+		wp += 3;
+		op += 3;
+		op[0] = ToLinear8[(cr += wp[0]) & mask];
+		op[1] = ToLinear8[(cg += wp[1]) & mask];
+		op[2] = ToLinear8[(cb += wp[2]) & mask];
+	    }
+	} else if (stride == 4) {
+	    op[0] = ToLinear8[cr = (wp[0] & mask)];
+	    op[1] = ToLinear8[cg = (wp[1] & mask)];
+	    op[2] = ToLinear8[cb = (wp[2] & mask)];
+	    op[3] = ToLinear8[ca = (wp[3] & mask)];
+	    n -= 4;
+	    while (n > 0) {
+		n -= 4;
+		wp += 4;
+		op += 4;
+		op[0] = ToLinear8[(cr += wp[0]) & mask];
+		op[1] = ToLinear8[(cg += wp[1]) & mask];
+		op[2] = ToLinear8[(cb += wp[2]) & mask];
+		op[3] = ToLinear8[(ca += wp[3]) & mask];
+	    }
+	} else {
+	    REPEAT(stride, *op = ToLinear8[*wp&mask]; wp++; op++)
+	    n -= stride;
+	    while (n > 0) {
+		REPEAT(stride,
+		    wp[stride] += *wp; *op = ToLinear8[*wp&mask]; wp++; op++)
+		n -= stride;
+	    }
+	}
+    }
+}
+
+
+static void
+horizontalAccumulate8abgr(uint16 *wp, int n, int stride, unsigned char *op,
+	unsigned char *ToLinear8)
+{
+    register unsigned int  cr, cg, cb, ca, mask;
+    register unsigned char  t0, t1, t2, t3;
+
+    if (n >= stride) {
+	mask = CODE_MASK;
+	if (stride == 3) {
+	    op[0] = 0;
+	    t1 = ToLinear8[cb = (wp[2] & mask)];
+	    t2 = ToLinear8[cg = (wp[1] & mask)];
+	    t3 = ToLinear8[cr = (wp[0] & mask)];
+	    op[1] = t1;
+	    op[2] = t2;
+	    op[3] = t3;
+	    n -= 3;
+	    while (n > 0) {
+		n -= 3;
+		wp += 3;
+		op += 4;
+		op[0] = 0;
+		t1 = ToLinear8[(cb += wp[2]) & mask];
+		t2 = ToLinear8[(cg += wp[1]) & mask];
+		t3 = ToLinear8[(cr += wp[0]) & mask];
+		op[1] = t1;
+		op[2] = t2;
+		op[3] = t3;
+	    }
+	} else if (stride == 4) {
+	    t0 = ToLinear8[ca = (wp[3] & mask)];
+	    t1 = ToLinear8[cb = (wp[2] & mask)];
+	    t2 = ToLinear8[cg = (wp[1] & mask)];
+	    t3 = ToLinear8[cr = (wp[0] & mask)];
+	    op[0] = t0;
+	    op[1] = t1;
+	    op[2] = t2;
+	    op[3] = t3;
+	    n -= 4;
+	    while (n > 0) {
+		n -= 4;
+		wp += 4;
+		op += 4;
+		t0 = ToLinear8[(ca += wp[3]) & mask];
+		t1 = ToLinear8[(cb += wp[2]) & mask];
+		t2 = ToLinear8[(cg += wp[1]) & mask];
+		t3 = ToLinear8[(cr += wp[0]) & mask];
+		op[0] = t0;
+		op[1] = t1;
+		op[2] = t2;
+		op[3] = t3;
+	    }
+	} else {
+	    REPEAT(stride, *op = ToLinear8[*wp&mask]; wp++; op++)
+	    n -= stride;
+	    while (n > 0) {
+		REPEAT(stride,
+		    wp[stride] += *wp; *op = ToLinear8[*wp&mask]; wp++; op++)
+		n -= stride;
+	    }
+	}
+    }
+}
+
+/*
+ * State block for each open TIFF
+ * file using PixarLog compression/decompression.
+ */
+typedef	struct {
+	TIFFPredictorState	predict;
+	z_stream		stream;
+	uint16			*tbuf; 
+	uint16			stride;
+	int			state;
+	int			user_datafmt;
+	int			quality;
+#define PLSTATE_INIT 1
+
+	TIFFVSetMethod		vgetparent;	/* super-class method */
+	TIFFVSetMethod		vsetparent;	/* super-class method */
+
+	float *ToLinearF;
+	uint16 *ToLinear16;
+	unsigned char *ToLinear8;
+	uint16  *FromLT2;
+	uint16  *From14; /* Really for 16-bit data, but we shift down 2 */
+	uint16  *From8;
+	
+} PixarLogState;
+
+static int
+PixarLogMakeTables(PixarLogState *sp)
+{
+
+/*
+ *    We make several tables here to convert between various external
+ *    representations (float, 16-bit, and 8-bit) and the internal
+ *    11-bit companded representation.  The 11-bit representation has two
+ *    distinct regions.  A linear bottom end up through .018316 in steps
+ *    of about .000073, and a region of constant ratio up to about 25.
+ *    These floating point numbers are stored in the main table ToLinearF. 
+ *    All other tables are derived from this one.  The tables (and the
+ *    ratios) are continuous at the internal seam.
+ */
+
+    int  nlin, lt2size;
+    int  i, j;
+    double  b, c, linstep, v;
+    float *ToLinearF;
+    uint16 *ToLinear16;
+    unsigned char *ToLinear8;
+    uint16  *FromLT2;
+    uint16  *From14; /* Really for 16-bit data, but we shift down 2 */
+    uint16  *From8;
+
+    c = log(RATIO);	
+    nlin = (int)(1./c);	/* nlin must be an integer */
+    c = 1./nlin;
+    b = exp(-c*ONE);	/* multiplicative scale factor [b*exp(c*ONE) = 1] */
+    linstep = b*c*exp(1.);
+
+    LogK1 = (float)(1./c);	/* if (v >= 2)  token = k1*log(v*k2) */
+    LogK2 = (float)(1./b);
+    lt2size = (int)(2./linstep) + 1;
+    FromLT2 = (uint16 *)_TIFFmalloc(lt2size*sizeof(uint16));
+    From14 = (uint16 *)_TIFFmalloc(16384*sizeof(uint16));
+    From8 = (uint16 *)_TIFFmalloc(256*sizeof(uint16));
+    ToLinearF = (float *)_TIFFmalloc(TSIZEP1 * sizeof(float));
+    ToLinear16 = (uint16 *)_TIFFmalloc(TSIZEP1 * sizeof(uint16));
+    ToLinear8 = (unsigned char *)_TIFFmalloc(TSIZEP1 * sizeof(unsigned char));
+    if (FromLT2 == NULL || From14  == NULL || From8   == NULL ||
+	 ToLinearF == NULL || ToLinear16 == NULL || ToLinear8 == NULL) {
+	if (FromLT2) _TIFFfree(FromLT2);
+	if (From14) _TIFFfree(From14);
+	if (From8) _TIFFfree(From8);
+	if (ToLinearF) _TIFFfree(ToLinearF);
+	if (ToLinear16) _TIFFfree(ToLinear16);
+	if (ToLinear8) _TIFFfree(ToLinear8);
+	sp->FromLT2 = NULL;
+	sp->From14 = NULL;
+	sp->From8 = NULL;
+	sp->ToLinearF = NULL;
+	sp->ToLinear16 = NULL;
+	sp->ToLinear8 = NULL;
+	return 0;
+    }
+
+    j = 0;
+
+    for (i = 0; i < nlin; i++)  {
+	v = i * linstep;
+	ToLinearF[j++] = (float)v;
+    }
+
+    for (i = nlin; i < TSIZE; i++)
+	ToLinearF[j++] = (float)(b*exp(c*i));
+
+    ToLinearF[2048] = ToLinearF[2047];
+
+    for (i = 0; i < TSIZEP1; i++)  {
+	v = ToLinearF[i]*65535.0 + 0.5;
+	ToLinear16[i] = (v > 65535.0) ? 65535 : (uint16)v;
+	v = ToLinearF[i]*255.0  + 0.5;
+	ToLinear8[i]  = (v > 255.0) ? 255 : (unsigned char)v;
+    }
+
+    j = 0;
+    for (i = 0; i < lt2size; i++)  {
+	if ((i*linstep)*(i*linstep) > ToLinearF[j]*ToLinearF[j+1])
+	    j++;
+	FromLT2[i] = j;
+    }
+
+    /*
+     * Since we lose info anyway on 16-bit data, we set up a 14-bit
+     * table and shift 16-bit values down two bits on input.
+     * saves a little table space.
+     */
+    j = 0;
+    for (i = 0; i < 16384; i++)  {
+	while ((i/16383.)*(i/16383.) > ToLinearF[j]*ToLinearF[j+1])
+	    j++;
+	From14[i] = j;
+    }
+
+    j = 0;
+    for (i = 0; i < 256; i++)  {
+	while ((i/255.)*(i/255.) > ToLinearF[j]*ToLinearF[j+1])
+	    j++;
+	From8[i] = j;
+    }
+
+    Fltsize = (float)(lt2size/2);
+
+    sp->ToLinearF = ToLinearF;
+    sp->ToLinear16 = ToLinear16;
+    sp->ToLinear8 = ToLinear8;
+    sp->FromLT2 = FromLT2;
+    sp->From14 = From14;
+    sp->From8 = From8;
+
+    return 1;
+}
+
+#define DecoderState(tif)	((PixarLogState*) (tif)->tif_data)
+#define EncoderState(tif)	((PixarLogState*) (tif)->tif_data)
+
+static int PixarLogEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s);
+static int PixarLogDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s);
+
+#define PIXARLOGDATAFMT_UNKNOWN	-1
+
+static int
+PixarLogGuessDataFmt(TIFFDirectory *td)
+{
+	int guess = PIXARLOGDATAFMT_UNKNOWN;
+	int format = td->td_sampleformat;
+
+	/* If the user didn't tell us his datafmt,
+	 * take our best guess from the bitspersample.
+	 */
+	switch (td->td_bitspersample) {
+	 case 32:
+		if (format == SAMPLEFORMAT_IEEEFP)
+			guess = PIXARLOGDATAFMT_FLOAT;
+		break;
+	 case 16:
+		if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT)
+			guess = PIXARLOGDATAFMT_16BIT;
+		break;
+	 case 12:
+		if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_INT)
+			guess = PIXARLOGDATAFMT_12BITPICIO;
+		break;
+	 case 11:
+		if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT)
+			guess = PIXARLOGDATAFMT_11BITLOG;
+		break;
+	 case 8:
+		if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT)
+			guess = PIXARLOGDATAFMT_8BIT;
+		break;
+	}
+
+	return guess;
+}
+
+static tmsize_t
+multiply_ms(tmsize_t m1, tmsize_t m2)
+{
+	tmsize_t bytes = m1 * m2;
+
+	if (m1 && bytes / m1 != m2)
+		bytes = 0;
+
+	return bytes;
+}
+
+static tmsize_t
+add_ms(tmsize_t m1, tmsize_t m2)
+{
+	tmsize_t bytes = m1 + m2;
+
+	/* if either input is zero, assume overflow already occurred */
+	if (m1 == 0 || m2 == 0)
+		bytes = 0;
+	else if (bytes <= m1 || bytes <= m2)
+		bytes = 0;
+
+	return bytes;
+}
+
+static int
+PixarLogFixupTags(TIFF* tif)
+{
+	(void) tif;
+	return (1);
+}
+
+static int
+PixarLogSetupDecode(TIFF* tif)
+{
+	static const char module[] = "PixarLogSetupDecode";
+	TIFFDirectory *td = &tif->tif_dir;
+	PixarLogState* sp = DecoderState(tif);
+	tmsize_t tbuf_size;
+
+	assert(sp != NULL);
+
+	/* Make sure no byte swapping happens on the data
+	 * after decompression. */
+	tif->tif_postdecode = _TIFFNoPostDecode;  
+
+	/* for some reason, we can't do this in TIFFInitPixarLog */
+
+	sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ?
+	    td->td_samplesperpixel : 1);
+	tbuf_size = multiply_ms(multiply_ms(multiply_ms(sp->stride, td->td_imagewidth),
+				      td->td_rowsperstrip), sizeof(uint16));
+	/* add one more stride in case input ends mid-stride */
+	tbuf_size = add_ms(tbuf_size, sizeof(uint16) * sp->stride);
+	if (tbuf_size == 0)
+		return (0);   /* TODO: this is an error return without error report through TIFFErrorExt */
+	sp->tbuf = (uint16 *) _TIFFmalloc(tbuf_size);
+	if (sp->tbuf == NULL)
+		return (0);
+	if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN)
+		sp->user_datafmt = PixarLogGuessDataFmt(td);
+	if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) {
+		TIFFErrorExt(tif->tif_clientdata, module,
+			"PixarLog compression can't handle bits depth/data format combination (depth: %d)", 
+			td->td_bitspersample);
+		return (0);
+	}
+
+	if (inflateInit(&sp->stream) != Z_OK) {
+		TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg);
+		return (0);
+	} else {
+		sp->state |= PLSTATE_INIT;
+		return (1);
+	}
+}
+
+/*
+ * Setup state for decoding a strip.
+ */
+static int
+PixarLogPreDecode(TIFF* tif, uint16 s)
+{
+	static const char module[] = "PixarLogPreDecode";
+	PixarLogState* sp = DecoderState(tif);
+
+	(void) s;
+	assert(sp != NULL);
+	sp->stream.next_in = tif->tif_rawdata;
+	assert(sizeof(sp->stream.avail_in)==4);  /* if this assert gets raised,
+	    we need to simplify this code to reflect a ZLib that is likely updated
+	    to deal with 8byte memory sizes, though this code will respond
+	    apropriately even before we simplify it */
+	sp->stream.avail_in = (uInt) tif->tif_rawcc;
+	if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc)
+	{
+		TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
+		return (0);
+	}
+	return (inflateReset(&sp->stream) == Z_OK);
+}
+
+static int
+PixarLogDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
+{
+	static const char module[] = "PixarLogDecode";
+	TIFFDirectory *td = &tif->tif_dir;
+	PixarLogState* sp = DecoderState(tif);
+	tmsize_t i;
+	tmsize_t nsamples;
+	int llen;
+	uint16 *up;
+
+	switch (sp->user_datafmt) {
+	case PIXARLOGDATAFMT_FLOAT:
+		nsamples = occ / sizeof(float);	/* XXX float == 32 bits */
+		break;
+	case PIXARLOGDATAFMT_16BIT:
+	case PIXARLOGDATAFMT_12BITPICIO:
+	case PIXARLOGDATAFMT_11BITLOG:
+		nsamples = occ / sizeof(uint16); /* XXX uint16 == 16 bits */
+		break;
+	case PIXARLOGDATAFMT_8BIT:
+	case PIXARLOGDATAFMT_8BITABGR:
+		nsamples = occ;
+		break;
+	default:
+		TIFFErrorExt(tif->tif_clientdata, module,
+			"%d bit input not supported in PixarLog",
+			td->td_bitspersample);
+		return 0;
+	}
+
+	llen = sp->stride * td->td_imagewidth;
+
+	(void) s;
+	assert(sp != NULL);
+	sp->stream.next_out = (unsigned char *) sp->tbuf;
+	assert(sizeof(sp->stream.avail_out)==4);  /* if this assert gets raised,
+	    we need to simplify this code to reflect a ZLib that is likely updated
+	    to deal with 8byte memory sizes, though this code will respond
+	    apropriately even before we simplify it */
+	sp->stream.avail_out = (uInt) (nsamples * sizeof(uint16));
+	if (sp->stream.avail_out != nsamples * sizeof(uint16))
+	{
+		TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
+		return (0);
+	}
+	do {
+		int state = inflate(&sp->stream, Z_PARTIAL_FLUSH);
+		if (state == Z_STREAM_END) {
+			break;			/* XXX */
+		}
+		if (state == Z_DATA_ERROR) {
+			TIFFErrorExt(tif->tif_clientdata, module,
+			    "Decoding error at scanline %lu, %s",
+			    (unsigned long) tif->tif_row, sp->stream.msg);
+			if (inflateSync(&sp->stream) != Z_OK)
+				return (0);
+			continue;
+		}
+		if (state != Z_OK) {
+			TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s",
+			    sp->stream.msg);
+			return (0);
+		}
+	} while (sp->stream.avail_out > 0);
+
+	/* hopefully, we got all the bytes we needed */
+	if (sp->stream.avail_out != 0) {
+		TIFFErrorExt(tif->tif_clientdata, module,
+		    "Not enough data at scanline %lu (short " TIFF_UINT64_FORMAT " bytes)",
+		    (unsigned long) tif->tif_row, (TIFF_UINT64_T) sp->stream.avail_out);
+		return (0);
+	}
+
+	up = sp->tbuf;
+	/* Swap bytes in the data if from a different endian machine. */
+	if (tif->tif_flags & TIFF_SWAB)
+		TIFFSwabArrayOfShort(up, nsamples);
+
+	/*
+	 * if llen is not an exact multiple of nsamples, the decode operation
+	 * may overflow the output buffer, so truncate it enough to prevent
+	 * that but still salvage as much data as possible.
+	 */
+	if (nsamples % llen) { 
+		TIFFWarningExt(tif->tif_clientdata, module,
+			"stride %lu is not a multiple of sample count, "
+			"%lu, data truncated.", (unsigned long) llen, (unsigned long) nsamples);
+		nsamples -= nsamples % llen;
+	}
+
+	for (i = 0; i < nsamples; i += llen, up += llen) {
+		switch (sp->user_datafmt)  {
+		case PIXARLOGDATAFMT_FLOAT:
+			horizontalAccumulateF(up, llen, sp->stride,
+					(float *)op, sp->ToLinearF);
+			op += llen * sizeof(float);
+			break;
+		case PIXARLOGDATAFMT_16BIT:
+			horizontalAccumulate16(up, llen, sp->stride,
+					(uint16 *)op, sp->ToLinear16);
+			op += llen * sizeof(uint16);
+			break;
+		case PIXARLOGDATAFMT_12BITPICIO:
+			horizontalAccumulate12(up, llen, sp->stride,
+					(int16 *)op, sp->ToLinearF);
+			op += llen * sizeof(int16);
+			break;
+		case PIXARLOGDATAFMT_11BITLOG:
+			horizontalAccumulate11(up, llen, sp->stride,
+					(uint16 *)op);
+			op += llen * sizeof(uint16);
+			break;
+		case PIXARLOGDATAFMT_8BIT:
+			horizontalAccumulate8(up, llen, sp->stride,
+					(unsigned char *)op, sp->ToLinear8);
+			op += llen * sizeof(unsigned char);
+			break;
+		case PIXARLOGDATAFMT_8BITABGR:
+			horizontalAccumulate8abgr(up, llen, sp->stride,
+					(unsigned char *)op, sp->ToLinear8);
+			op += llen * sizeof(unsigned char);
+			break;
+		default:
+			TIFFErrorExt(tif->tif_clientdata, module,
+				  "Unsupported bits/sample: %d",
+				  td->td_bitspersample);
+			return (0);
+		}
+	}
+
+	return (1);
+}
+
+static int
+PixarLogSetupEncode(TIFF* tif)
+{
+	static const char module[] = "PixarLogSetupEncode";
+	TIFFDirectory *td = &tif->tif_dir;
+	PixarLogState* sp = EncoderState(tif);
+	tmsize_t tbuf_size;
+
+	assert(sp != NULL);
+
+	/* for some reason, we can't do this in TIFFInitPixarLog */
+
+	sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ?
+	    td->td_samplesperpixel : 1);
+	tbuf_size = multiply_ms(multiply_ms(multiply_ms(sp->stride, td->td_imagewidth),
+				      td->td_rowsperstrip), sizeof(uint16));
+	if (tbuf_size == 0)
+		return (0);  /* TODO: this is an error return without error report through TIFFErrorExt */
+	sp->tbuf = (uint16 *) _TIFFmalloc(tbuf_size);
+	if (sp->tbuf == NULL)
+		return (0);
+	if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN)
+		sp->user_datafmt = PixarLogGuessDataFmt(td);
+	if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) {
+		TIFFErrorExt(tif->tif_clientdata, module, "PixarLog compression can't handle %d bit linear encodings", td->td_bitspersample);
+		return (0);
+	}
+
+	if (deflateInit(&sp->stream, sp->quality) != Z_OK) {
+		TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg);
+		return (0);
+	} else {
+		sp->state |= PLSTATE_INIT;
+		return (1);
+	}
+}
+
+/*
+ * Reset encoding state at the start of a strip.
+ */
+static int
+PixarLogPreEncode(TIFF* tif, uint16 s)
+{
+	static const char module[] = "PixarLogPreEncode";
+	PixarLogState *sp = EncoderState(tif);
+
+	(void) s;
+	assert(sp != NULL);
+	sp->stream.next_out = tif->tif_rawdata;
+	assert(sizeof(sp->stream.avail_out)==4);  /* if this assert gets raised,
+	    we need to simplify this code to reflect a ZLib that is likely updated
+	    to deal with 8byte memory sizes, though this code will respond
+	    apropriately even before we simplify it */
+	sp->stream.avail_out = tif->tif_rawdatasize;
+	if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize)
+	{
+		TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
+		return (0);
+	}
+	return (deflateReset(&sp->stream) == Z_OK);
+}
+
+static void
+horizontalDifferenceF(float *ip, int n, int stride, uint16 *wp, uint16 *FromLT2)
+{
+    int32 r1, g1, b1, a1, r2, g2, b2, a2, mask;
+    float fltsize = Fltsize;
+
+#define  CLAMP(v) ( (v<(float)0.)   ? 0				\
+		  : (v<(float)2.)   ? FromLT2[(int)(v*fltsize)]	\
+		  : (v>(float)24.2) ? 2047			\
+		  : LogK1*log(v*LogK2) + 0.5 )
+
+    mask = CODE_MASK;
+    if (n >= stride) {
+	if (stride == 3) {
+	    r2 = wp[0] = (uint16) CLAMP(ip[0]);
+	    g2 = wp[1] = (uint16) CLAMP(ip[1]);
+	    b2 = wp[2] = (uint16) CLAMP(ip[2]);
+	    n -= 3;
+	    while (n > 0) {
+		n -= 3;
+		wp += 3;
+		ip += 3;
+		r1 = (int32) CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1;
+		g1 = (int32) CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1;
+		b1 = (int32) CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1;
+	    }
+	} else if (stride == 4) {
+	    r2 = wp[0] = (uint16) CLAMP(ip[0]);
+	    g2 = wp[1] = (uint16) CLAMP(ip[1]);
+	    b2 = wp[2] = (uint16) CLAMP(ip[2]);
+	    a2 = wp[3] = (uint16) CLAMP(ip[3]);
+	    n -= 4;
+	    while (n > 0) {
+		n -= 4;
+		wp += 4;
+		ip += 4;
+		r1 = (int32) CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1;
+		g1 = (int32) CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1;
+		b1 = (int32) CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1;
+		a1 = (int32) CLAMP(ip[3]); wp[3] = (a1-a2) & mask; a2 = a1;
+	    }
+	} else {
+	    ip += n - 1;	/* point to last one */
+	    wp += n - 1;	/* point to last one */
+	    n -= stride;
+	    while (n > 0) {
+		REPEAT(stride, wp[0] = (uint16) CLAMP(ip[0]);
+				wp[stride] -= wp[0];
+				wp[stride] &= mask;
+				wp--; ip--)
+		n -= stride;
+	    }
+	    REPEAT(stride, wp[0] = (uint16) CLAMP(ip[0]); wp--; ip--)
+	}
+    }
+}
+
+static void
+horizontalDifference16(unsigned short *ip, int n, int stride, 
+	unsigned short *wp, uint16 *From14)
+{
+    register int  r1, g1, b1, a1, r2, g2, b2, a2, mask;
+
+/* assumption is unsigned pixel values */
+#undef   CLAMP
+#define  CLAMP(v) From14[(v) >> 2]
+
+    mask = CODE_MASK;
+    if (n >= stride) {
+	if (stride == 3) {
+	    r2 = wp[0] = CLAMP(ip[0]);  g2 = wp[1] = CLAMP(ip[1]);
+	    b2 = wp[2] = CLAMP(ip[2]);
+	    n -= 3;
+	    while (n > 0) {
+		n -= 3;
+		wp += 3;
+		ip += 3;
+		r1 = CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1;
+		g1 = CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1;
+		b1 = CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1;
+	    }
+	} else if (stride == 4) {
+	    r2 = wp[0] = CLAMP(ip[0]);  g2 = wp[1] = CLAMP(ip[1]);
+	    b2 = wp[2] = CLAMP(ip[2]);  a2 = wp[3] = CLAMP(ip[3]);
+	    n -= 4;
+	    while (n > 0) {
+		n -= 4;
+		wp += 4;
+		ip += 4;
+		r1 = CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1;
+		g1 = CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1;
+		b1 = CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1;
+		a1 = CLAMP(ip[3]); wp[3] = (a1-a2) & mask; a2 = a1;
+	    }
+	} else {
+	    ip += n - 1;	/* point to last one */
+	    wp += n - 1;	/* point to last one */
+	    n -= stride;
+	    while (n > 0) {
+		REPEAT(stride, wp[0] = CLAMP(ip[0]);
+				wp[stride] -= wp[0];
+				wp[stride] &= mask;
+				wp--; ip--)
+		n -= stride;
+	    }
+	    REPEAT(stride, wp[0] = CLAMP(ip[0]); wp--; ip--)
+	}
+    }
+}
+
+
+static void
+horizontalDifference8(unsigned char *ip, int n, int stride, 
+	unsigned short *wp, uint16 *From8)
+{
+    register int  r1, g1, b1, a1, r2, g2, b2, a2, mask;
+
+#undef	 CLAMP
+#define  CLAMP(v) (From8[(v)])
+
+    mask = CODE_MASK;
+    if (n >= stride) {
+	if (stride == 3) {
+	    r2 = wp[0] = CLAMP(ip[0]);  g2 = wp[1] = CLAMP(ip[1]);
+	    b2 = wp[2] = CLAMP(ip[2]);
+	    n -= 3;
+	    while (n > 0) {
+		n -= 3;
+		r1 = CLAMP(ip[3]); wp[3] = (r1-r2) & mask; r2 = r1;
+		g1 = CLAMP(ip[4]); wp[4] = (g1-g2) & mask; g2 = g1;
+		b1 = CLAMP(ip[5]); wp[5] = (b1-b2) & mask; b2 = b1;
+		wp += 3;
+		ip += 3;
+	    }
+	} else if (stride == 4) {
+	    r2 = wp[0] = CLAMP(ip[0]);  g2 = wp[1] = CLAMP(ip[1]);
+	    b2 = wp[2] = CLAMP(ip[2]);  a2 = wp[3] = CLAMP(ip[3]);
+	    n -= 4;
+	    while (n > 0) {
+		n -= 4;
+		r1 = CLAMP(ip[4]); wp[4] = (r1-r2) & mask; r2 = r1;
+		g1 = CLAMP(ip[5]); wp[5] = (g1-g2) & mask; g2 = g1;
+		b1 = CLAMP(ip[6]); wp[6] = (b1-b2) & mask; b2 = b1;
+		a1 = CLAMP(ip[7]); wp[7] = (a1-a2) & mask; a2 = a1;
+		wp += 4;
+		ip += 4;
+	    }
+	} else {
+	    wp += n + stride - 1;	/* point to last one */
+	    ip += n + stride - 1;	/* point to last one */
+	    n -= stride;
+	    while (n > 0) {
+		REPEAT(stride, wp[0] = CLAMP(ip[0]);
+				wp[stride] -= wp[0];
+				wp[stride] &= mask;
+				wp--; ip--)
+		n -= stride;
+	    }
+	    REPEAT(stride, wp[0] = CLAMP(ip[0]); wp--; ip--)
+	}
+    }
+}
+
+/*
+ * Encode a chunk of pixels.
+ */
+static int
+PixarLogEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
+{
+	static const char module[] = "PixarLogEncode";
+	TIFFDirectory *td = &tif->tif_dir;
+	PixarLogState *sp = EncoderState(tif);
+	tmsize_t i;
+	tmsize_t n;
+	int llen;
+	unsigned short * up;
+
+	(void) s;
+
+	switch (sp->user_datafmt) {
+	case PIXARLOGDATAFMT_FLOAT:
+		n = cc / sizeof(float);		/* XXX float == 32 bits */
+		break;
+	case PIXARLOGDATAFMT_16BIT:
+	case PIXARLOGDATAFMT_12BITPICIO:
+	case PIXARLOGDATAFMT_11BITLOG:
+		n = cc / sizeof(uint16);	/* XXX uint16 == 16 bits */
+		break;
+	case PIXARLOGDATAFMT_8BIT:
+	case PIXARLOGDATAFMT_8BITABGR:
+		n = cc;
+		break;
+	default:
+		TIFFErrorExt(tif->tif_clientdata, module,
+			"%d bit input not supported in PixarLog",
+			td->td_bitspersample);
+		return 0;
+	}
+
+	llen = sp->stride * td->td_imagewidth;
+
+	for (i = 0, up = sp->tbuf; i < n; i += llen, up += llen) {
+		switch (sp->user_datafmt)  {
+		case PIXARLOGDATAFMT_FLOAT:
+			horizontalDifferenceF((float *)bp, llen, 
+				sp->stride, up, sp->FromLT2);
+			bp += llen * sizeof(float);
+			break;
+		case PIXARLOGDATAFMT_16BIT:
+			horizontalDifference16((uint16 *)bp, llen, 
+				sp->stride, up, sp->From14);
+			bp += llen * sizeof(uint16);
+			break;
+		case PIXARLOGDATAFMT_8BIT:
+			horizontalDifference8((unsigned char *)bp, llen, 
+				sp->stride, up, sp->From8);
+			bp += llen * sizeof(unsigned char);
+			break;
+		default:
+			TIFFErrorExt(tif->tif_clientdata, module,
+				"%d bit input not supported in PixarLog",
+				td->td_bitspersample);
+			return 0;
+		}
+	}
+ 
+	sp->stream.next_in = (unsigned char *) sp->tbuf;
+	assert(sizeof(sp->stream.avail_in)==4);  /* if this assert gets raised,
+	    we need to simplify this code to reflect a ZLib that is likely updated
+	    to deal with 8byte memory sizes, though this code will respond
+	    apropriately even before we simplify it */
+	sp->stream.avail_in = (uInt) (n * sizeof(uint16));
+	if ((sp->stream.avail_in / sizeof(uint16)) != (uInt) n)
+	{
+		TIFFErrorExt(tif->tif_clientdata, module,
+			     "ZLib cannot deal with buffers this size");
+		return (0);
+	}
+
+	do {
+		if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) {
+			TIFFErrorExt(tif->tif_clientdata, module, "Encoder error: %s",
+			    sp->stream.msg);
+			return (0);
+		}
+		if (sp->stream.avail_out == 0) {
+			tif->tif_rawcc = tif->tif_rawdatasize;
+			TIFFFlushData1(tif);
+			sp->stream.next_out = tif->tif_rawdata;
+			sp->stream.avail_out = (uInt) tif->tif_rawdatasize;  /* this is a safe typecast, as check is made already in PixarLogPreEncode */
+		}
+	} while (sp->stream.avail_in > 0);
+	return (1);
+}
+
+/*
+ * Finish off an encoded strip by flushing the last
+ * string and tacking on an End Of Information code.
+ */
+
+static int
+PixarLogPostEncode(TIFF* tif)
+{
+	static const char module[] = "PixarLogPostEncode";
+	PixarLogState *sp = EncoderState(tif);
+	int state;
+
+	sp->stream.avail_in = 0;
+
+	do {
+		state = deflate(&sp->stream, Z_FINISH);
+		switch (state) {
+		case Z_STREAM_END:
+		case Z_OK:
+		    if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) {
+			    tif->tif_rawcc =
+				tif->tif_rawdatasize - sp->stream.avail_out;
+			    TIFFFlushData1(tif);
+			    sp->stream.next_out = tif->tif_rawdata;
+			    sp->stream.avail_out = (uInt) tif->tif_rawdatasize;  /* this is a safe typecast, as check is made already in PixarLogPreEncode */
+		    }
+		    break;
+		default:
+			TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s",
+			sp->stream.msg);
+		    return (0);
+		}
+	} while (state != Z_STREAM_END);
+	return (1);
+}
+
+static void
+PixarLogClose(TIFF* tif)
+{
+	TIFFDirectory *td = &tif->tif_dir;
+
+	/* In a really sneaky (and really incorrect, and untruthfull, and
+	 * troublesome, and error-prone) maneuver that completely goes against
+	 * the spirit of TIFF, and breaks TIFF, on close, we covertly
+	 * modify both bitspersample and sampleformat in the directory to
+	 * indicate 8-bit linear.  This way, the decode "just works" even for
+	 * readers that don't know about PixarLog, or how to set
+	 * the PIXARLOGDATFMT pseudo-tag.
+	 */
+	td->td_bitspersample = 8;
+	td->td_sampleformat = SAMPLEFORMAT_UINT;
+}
+
+static void
+PixarLogCleanup(TIFF* tif)
+{
+	PixarLogState* sp = (PixarLogState*) tif->tif_data;
+
+	assert(sp != 0);
+
+	(void)TIFFPredictorCleanup(tif);
+
+	tif->tif_tagmethods.vgetfield = sp->vgetparent;
+	tif->tif_tagmethods.vsetfield = sp->vsetparent;
+
+	if (sp->FromLT2) _TIFFfree(sp->FromLT2);
+	if (sp->From14) _TIFFfree(sp->From14);
+	if (sp->From8) _TIFFfree(sp->From8);
+	if (sp->ToLinearF) _TIFFfree(sp->ToLinearF);
+	if (sp->ToLinear16) _TIFFfree(sp->ToLinear16);
+	if (sp->ToLinear8) _TIFFfree(sp->ToLinear8);
+	if (sp->state&PLSTATE_INIT) {
+		if (tif->tif_mode == O_RDONLY)
+			inflateEnd(&sp->stream);
+		else
+			deflateEnd(&sp->stream);
+	}
+	if (sp->tbuf)
+		_TIFFfree(sp->tbuf);
+	_TIFFfree(sp);
+	tif->tif_data = NULL;
+
+	_TIFFSetDefaultCompressionState(tif);
+}
+
+static int
+PixarLogVSetField(TIFF* tif, uint32 tag, va_list ap)
+{
+    static const char module[] = "PixarLogVSetField";
+    PixarLogState *sp = (PixarLogState *)tif->tif_data;
+    int result;
+
+    switch (tag) {
+     case TIFFTAG_PIXARLOGQUALITY:
+		sp->quality = (int) va_arg(ap, int);
+		if (tif->tif_mode != O_RDONLY && (sp->state&PLSTATE_INIT)) {
+			if (deflateParams(&sp->stream,
+			    sp->quality, Z_DEFAULT_STRATEGY) != Z_OK) {
+				TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s",
+					sp->stream.msg);
+				return (0);
+			}
+		}
+		return (1);
+     case TIFFTAG_PIXARLOGDATAFMT:
+	sp->user_datafmt = (int) va_arg(ap, int);
+	/* Tweak the TIFF header so that the rest of libtiff knows what
+	 * size of data will be passed between app and library, and
+	 * assume that the app knows what it is doing and is not
+	 * confused by these header manipulations...
+	 */
+	switch (sp->user_datafmt) {
+	 case PIXARLOGDATAFMT_8BIT:
+	 case PIXARLOGDATAFMT_8BITABGR:
+	    TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
+	    TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
+	    break;
+	 case PIXARLOGDATAFMT_11BITLOG:
+	    TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16);
+	    TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
+	    break;
+	 case PIXARLOGDATAFMT_12BITPICIO:
+	    TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16);
+	    TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT);
+	    break;
+	 case PIXARLOGDATAFMT_16BIT:
+	    TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16);
+	    TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
+	    break;
+	 case PIXARLOGDATAFMT_FLOAT:
+	    TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 32);
+	    TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);
+	    break;
+	}
+	/*
+	 * Must recalculate sizes should bits/sample change.
+	 */
+	tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)(-1);
+	tif->tif_scanlinesize = TIFFScanlineSize(tif);
+	result = 1;		/* NB: pseudo tag */
+	break;
+     default:
+	result = (*sp->vsetparent)(tif, tag, ap);
+    }
+    return (result);
+}
+
+static int
+PixarLogVGetField(TIFF* tif, uint32 tag, va_list ap)
+{
+    PixarLogState *sp = (PixarLogState *)tif->tif_data;
+
+    switch (tag) {
+     case TIFFTAG_PIXARLOGQUALITY:
+	*va_arg(ap, int*) = sp->quality;
+	break;
+     case TIFFTAG_PIXARLOGDATAFMT:
+	*va_arg(ap, int*) = sp->user_datafmt;
+	break;
+     default:
+	return (*sp->vgetparent)(tif, tag, ap);
+    }
+    return (1);
+}
+
+static const TIFFField pixarlogFields[] = {
+    {TIFFTAG_PIXARLOGDATAFMT, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL},
+    {TIFFTAG_PIXARLOGQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL}
+};
+
+int
+TIFFInitPixarLog(TIFF* tif, int scheme)
+{
+	static const char module[] = "TIFFInitPixarLog";
+
+	PixarLogState* sp;
+
+	assert(scheme == COMPRESSION_PIXARLOG);
+
+	/*
+	 * Merge codec-specific tag information.
+	 */
+	if (!_TIFFMergeFields(tif, pixarlogFields,
+			      TIFFArrayCount(pixarlogFields))) {
+		TIFFErrorExt(tif->tif_clientdata, module,
+			     "Merging PixarLog codec-specific tags failed");
+		return 0;
+	}
+
+	/*
+	 * Allocate state block so tag methods have storage to record values.
+	 */
+	tif->tif_data = (uint8*) _TIFFmalloc(sizeof (PixarLogState));
+	if (tif->tif_data == NULL)
+		goto bad;
+	sp = (PixarLogState*) tif->tif_data;
+	_TIFFmemset(sp, 0, sizeof (*sp));
+	sp->stream.data_type = Z_BINARY;
+	sp->user_datafmt = PIXARLOGDATAFMT_UNKNOWN;
+
+	/*
+	 * Install codec methods.
+	 */
+	tif->tif_fixuptags = PixarLogFixupTags; 
+	tif->tif_setupdecode = PixarLogSetupDecode;
+	tif->tif_predecode = PixarLogPreDecode;
+	tif->tif_decoderow = PixarLogDecode;
+	tif->tif_decodestrip = PixarLogDecode;  
+	tif->tif_decodetile = PixarLogDecode;
+	tif->tif_setupencode = PixarLogSetupEncode;
+	tif->tif_preencode = PixarLogPreEncode;
+	tif->tif_postencode = PixarLogPostEncode;
+	tif->tif_encoderow = PixarLogEncode;  
+	tif->tif_encodestrip = PixarLogEncode;
+	tif->tif_encodetile = PixarLogEncode;  
+	tif->tif_close = PixarLogClose;
+	tif->tif_cleanup = PixarLogCleanup;
+
+	/* Override SetField so we can handle our private pseudo-tag */
+	sp->vgetparent = tif->tif_tagmethods.vgetfield;
+	tif->tif_tagmethods.vgetfield = PixarLogVGetField;   /* hook for codec tags */
+	sp->vsetparent = tif->tif_tagmethods.vsetfield;
+	tif->tif_tagmethods.vsetfield = PixarLogVSetField;   /* hook for codec tags */
+
+	/* Default values for codec-specific fields */
+	sp->quality = Z_DEFAULT_COMPRESSION; /* default comp. level */
+	sp->state = 0;
+
+	/* we don't wish to use the predictor, 
+	 * the default is none, which predictor value 1
+	 */
+	(void) TIFFPredictorInit(tif);
+
+	/*
+	 * build the companding tables 
+	 */
+	PixarLogMakeTables(sp);
+
+	return (1);
+bad:
+	TIFFErrorExt(tif->tif_clientdata, module,
+		     "No space for PixarLog state block");
+	return (0);
+}
+#endif /* PIXARLOG_SUPPORT */
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tif_predict.c b/Source/LibTIFF4/tif_predict.c
index dfe1a38..4c3861b 100644
--- a/Source/LibTIFF4/tif_predict.c
+++ b/Source/LibTIFF4/tif_predict.c
@@ -1,764 +1,764 @@
-/* $Id: tif_predict.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library.
- *
- * Predictor Tag Support (used by multiple codecs).
- */
-#include "tiffiop.h"
-#include "tif_predict.h"
-
-#define	PredictorState(tif)	((TIFFPredictorState*) (tif)->tif_data)
-
-static void horAcc8(TIFF* tif, uint8* cp0, tmsize_t cc);
-static void horAcc16(TIFF* tif, uint8* cp0, tmsize_t cc);
-static void horAcc32(TIFF* tif, uint8* cp0, tmsize_t cc);
-static void swabHorAcc16(TIFF* tif, uint8* cp0, tmsize_t cc);
-static void swabHorAcc32(TIFF* tif, uint8* cp0, tmsize_t cc);
-static void horDiff8(TIFF* tif, uint8* cp0, tmsize_t cc);
-static void horDiff16(TIFF* tif, uint8* cp0, tmsize_t cc);
-static void horDiff32(TIFF* tif, uint8* cp0, tmsize_t cc);
-static void fpAcc(TIFF* tif, uint8* cp0, tmsize_t cc);
-static void fpDiff(TIFF* tif, uint8* cp0, tmsize_t cc);
-static int PredictorDecodeRow(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s);
-static int PredictorDecodeTile(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s);
-static int PredictorEncodeRow(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s);
-static int PredictorEncodeTile(TIFF* tif, uint8* bp0, tmsize_t cc0, uint16 s);
-
-static int
-PredictorSetup(TIFF* tif)
-{
-	static const char module[] = "PredictorSetup";
-
-	TIFFPredictorState* sp = PredictorState(tif);
-	TIFFDirectory* td = &tif->tif_dir;
-
-	switch (sp->predictor)		/* no differencing */
-	{
-		case PREDICTOR_NONE:
-			return 1;
-		case PREDICTOR_HORIZONTAL:
-			if (td->td_bitspersample != 8
-			    && td->td_bitspersample != 16
-			    && td->td_bitspersample != 32) {
-				TIFFErrorExt(tif->tif_clientdata, module,
-				    "Horizontal differencing \"Predictor\" not supported with %d-bit samples",
-				    td->td_bitspersample);
-				return 0;
-			}
-			break;
-		case PREDICTOR_FLOATINGPOINT:
-			if (td->td_sampleformat != SAMPLEFORMAT_IEEEFP) {
-				TIFFErrorExt(tif->tif_clientdata, module,
-				    "Floating point \"Predictor\" not supported with %d data format",
-				    td->td_sampleformat);
-				return 0;
-			}
-			break;
-		default:
-			TIFFErrorExt(tif->tif_clientdata, module,
-			    "\"Predictor\" value %d not supported",
-			    sp->predictor);
-			return 0;
-	}
-	sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ?
-	    td->td_samplesperpixel : 1);
-	/*
-	 * Calculate the scanline/tile-width size in bytes.
-	 */
-	if (isTiled(tif))
-		sp->rowsize = TIFFTileRowSize(tif);
-	else
-		sp->rowsize = TIFFScanlineSize(tif);
-	if (sp->rowsize == 0)
-		return 0;
-
-	return 1;
-}
-
-static int
-PredictorSetupDecode(TIFF* tif)
-{
-	TIFFPredictorState* sp = PredictorState(tif);
-	TIFFDirectory* td = &tif->tif_dir;
-
-	if (!(*sp->setupdecode)(tif) || !PredictorSetup(tif))
-		return 0;
-
-	if (sp->predictor == 2) {
-		switch (td->td_bitspersample) {
-			case 8:  sp->decodepfunc = horAcc8; break;
-			case 16: sp->decodepfunc = horAcc16; break;
-			case 32: sp->decodepfunc = horAcc32; break;
-		}
-		/*
-		 * Override default decoding method with one that does the
-		 * predictor stuff.
-		 */
-                if( tif->tif_decoderow != PredictorDecodeRow )
-                {
-                    sp->decoderow = tif->tif_decoderow;
-                    tif->tif_decoderow = PredictorDecodeRow;
-                    sp->decodestrip = tif->tif_decodestrip;
-                    tif->tif_decodestrip = PredictorDecodeTile;
-                    sp->decodetile = tif->tif_decodetile;
-                    tif->tif_decodetile = PredictorDecodeTile;
-                }
-
-		/*
-		 * If the data is horizontally differenced 16-bit data that
-		 * requires byte-swapping, then it must be byte swapped before
-		 * the accumulation step.  We do this with a special-purpose
-		 * routine and override the normal post decoding logic that
-		 * the library setup when the directory was read.
-		 */
-		if (tif->tif_flags & TIFF_SWAB) {
-			if (sp->decodepfunc == horAcc16) {
-				sp->decodepfunc = swabHorAcc16;
-				tif->tif_postdecode = _TIFFNoPostDecode;
-            } else if (sp->decodepfunc == horAcc32) {
-				sp->decodepfunc = swabHorAcc32;
-				tif->tif_postdecode = _TIFFNoPostDecode;
-            }
-		}
-	}
-
-	else if (sp->predictor == 3) {
-		sp->decodepfunc = fpAcc;
-		/*
-		 * Override default decoding method with one that does the
-		 * predictor stuff.
-		 */
-                if( tif->tif_decoderow != PredictorDecodeRow )
-                {
-                    sp->decoderow = tif->tif_decoderow;
-                    tif->tif_decoderow = PredictorDecodeRow;
-                    sp->decodestrip = tif->tif_decodestrip;
-                    tif->tif_decodestrip = PredictorDecodeTile;
-                    sp->decodetile = tif->tif_decodetile;
-                    tif->tif_decodetile = PredictorDecodeTile;
-                }
-		/*
-		 * The data should not be swapped outside of the floating
-		 * point predictor, the accumulation routine should return
-		 * byres in the native order.
-		 */
-		if (tif->tif_flags & TIFF_SWAB) {
-			tif->tif_postdecode = _TIFFNoPostDecode;
-		}
-		/*
-		 * Allocate buffer to keep the decoded bytes before
-		 * rearranging in the ight order
-		 */
-	}
-
-	return 1;
-}
-
-static int
-PredictorSetupEncode(TIFF* tif)
-{
-	TIFFPredictorState* sp = PredictorState(tif);
-	TIFFDirectory* td = &tif->tif_dir;
-
-	if (!(*sp->setupencode)(tif) || !PredictorSetup(tif))
-		return 0;
-
-	if (sp->predictor == 2) {
-		switch (td->td_bitspersample) {
-			case 8:  sp->encodepfunc = horDiff8; break;
-			case 16: sp->encodepfunc = horDiff16; break;
-			case 32: sp->encodepfunc = horDiff32; break;
-		}
-		/*
-		 * Override default encoding method with one that does the
-		 * predictor stuff.
-		 */
-                if( tif->tif_encoderow != PredictorEncodeRow )
-                {
-                    sp->encoderow = tif->tif_encoderow;
-                    tif->tif_encoderow = PredictorEncodeRow;
-                    sp->encodestrip = tif->tif_encodestrip;
-                    tif->tif_encodestrip = PredictorEncodeTile;
-                    sp->encodetile = tif->tif_encodetile;
-                    tif->tif_encodetile = PredictorEncodeTile;
-                }
-	}
-
-	else if (sp->predictor == 3) {
-		sp->encodepfunc = fpDiff;
-		/*
-		 * Override default encoding method with one that does the
-		 * predictor stuff.
-		 */
-                if( tif->tif_encoderow != PredictorEncodeRow )
-                {
-                    sp->encoderow = tif->tif_encoderow;
-                    tif->tif_encoderow = PredictorEncodeRow;
-                    sp->encodestrip = tif->tif_encodestrip;
-                    tif->tif_encodestrip = PredictorEncodeTile;
-                    sp->encodetile = tif->tif_encodetile;
-                    tif->tif_encodetile = PredictorEncodeTile;
-                }
-	}
-
-	return 1;
-}
-
-#define REPEAT4(n, op)		\
-    switch (n) {		\
-    default: { tmsize_t i; for (i = n-4; i > 0; i--) { op; } } \
-    case 4:  op;		\
-    case 3:  op;		\
-    case 2:  op;		\
-    case 1:  op;		\
-    case 0:  ;			\
-    }
-
-static void
-horAcc8(TIFF* tif, uint8* cp0, tmsize_t cc)
-{
-	tmsize_t stride = PredictorState(tif)->stride;
-
-	char* cp = (char*) cp0;
-	assert((cc%stride)==0);
-	if (cc > stride) {
-		/*
-		 * Pipeline the most common cases.
-		 */
-		if (stride == 3)  {
-			unsigned int cr = cp[0];
-			unsigned int cg = cp[1];
-			unsigned int cb = cp[2];
-			cc -= 3;
-			cp += 3;
-			while (cc>0) {
-				cp[0] = (char) (cr += cp[0]);
-				cp[1] = (char) (cg += cp[1]);
-				cp[2] = (char) (cb += cp[2]);
-				cc -= 3;
-				cp += 3;
-			}
-		} else if (stride == 4)  {
-			unsigned int cr = cp[0];
-			unsigned int cg = cp[1];
-			unsigned int cb = cp[2];
-			unsigned int ca = cp[3];
-			cc -= 4;
-			cp += 4;
-			while (cc>0) {
-				cp[0] = (char) (cr += cp[0]);
-				cp[1] = (char) (cg += cp[1]);
-				cp[2] = (char) (cb += cp[2]);
-				cp[3] = (char) (ca += cp[3]);
-				cc -= 4;
-				cp += 4;
-			}
-		} else  {
-			cc -= stride;
-			do {
-				REPEAT4(stride, cp[stride] =
-					(char) (cp[stride] + *cp); cp++)
-				cc -= stride;
-			} while (cc>0);
-		}
-	}
-}
-
-static void
-swabHorAcc16(TIFF* tif, uint8* cp0, tmsize_t cc)
-{
-	tmsize_t stride = PredictorState(tif)->stride;
-	uint16* wp = (uint16*) cp0;
-	tmsize_t wc = cc / 2;
-
-	assert((cc%(2*stride))==0);
-
-	if (wc > stride) {
-		TIFFSwabArrayOfShort(wp, wc);
-		wc -= stride;
-		do {
-			REPEAT4(stride, wp[stride] += wp[0]; wp++)
-			wc -= stride;
-		} while (wc > 0);
-	}
-}
-
-static void
-horAcc16(TIFF* tif, uint8* cp0, tmsize_t cc)
-{
-	tmsize_t stride = PredictorState(tif)->stride;
-	uint16* wp = (uint16*) cp0;
-	tmsize_t wc = cc / 2;
-
-	assert((cc%(2*stride))==0);
-
-	if (wc > stride) {
-		wc -= stride;
-		do {
-			REPEAT4(stride, wp[stride] += wp[0]; wp++)
-			wc -= stride;
-		} while (wc > 0);
-	}
-}
-
-static void
-swabHorAcc32(TIFF* tif, uint8* cp0, tmsize_t cc)
-{
-	tmsize_t stride = PredictorState(tif)->stride;
-	uint32* wp = (uint32*) cp0;
-	tmsize_t wc = cc / 4;
-
-	assert((cc%(4*stride))==0);
-
-	if (wc > stride) {
-		TIFFSwabArrayOfLong(wp, wc);
-		wc -= stride;
-		do {
-			REPEAT4(stride, wp[stride] += wp[0]; wp++)
-			wc -= stride;
-		} while (wc > 0);
-	}
-}
-
-static void
-horAcc32(TIFF* tif, uint8* cp0, tmsize_t cc)
-{
-	tmsize_t stride = PredictorState(tif)->stride;
-	uint32* wp = (uint32*) cp0;
-	tmsize_t wc = cc / 4;
-
-	assert((cc%(4*stride))==0);
-
-	if (wc > stride) {
-		wc -= stride;
-		do {
-			REPEAT4(stride, wp[stride] += wp[0]; wp++)
-			wc -= stride;
-		} while (wc > 0);
-	}
-}
-
-/*
- * Floating point predictor accumulation routine.
- */
-static void
-fpAcc(TIFF* tif, uint8* cp0, tmsize_t cc)
-{
-	tmsize_t stride = PredictorState(tif)->stride;
-	uint32 bps = tif->tif_dir.td_bitspersample / 8;
-	tmsize_t wc = cc / bps;
-	tmsize_t count = cc;
-	uint8 *cp = (uint8 *) cp0;
-	uint8 *tmp = (uint8 *)_TIFFmalloc(cc);
-
-	assert((cc%(bps*stride))==0);
-
-	if (!tmp)
-		return;
-
-	while (count > stride) {
-		REPEAT4(stride, cp[stride] += cp[0]; cp++)
-		count -= stride;
-	}
-
-	_TIFFmemcpy(tmp, cp0, cc);
-	cp = (uint8 *) cp0;
-	for (count = 0; count < wc; count++) {
-		uint32 byte;
-		for (byte = 0; byte < bps; byte++) {
-			#if WORDS_BIGENDIAN
-			cp[bps * count + byte] = tmp[byte * wc + count];
-			#else
-			cp[bps * count + byte] =
-				tmp[(bps - byte - 1) * wc + count];
-			#endif
-		}
-	}
-	_TIFFfree(tmp);
-}
-
-/*
- * Decode a scanline and apply the predictor routine.
- */
-static int
-PredictorDecodeRow(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
-{
-	TIFFPredictorState *sp = PredictorState(tif);
-
-	assert(sp != NULL);
-	assert(sp->decoderow != NULL);
-	assert(sp->decodepfunc != NULL);  
-
-	if ((*sp->decoderow)(tif, op0, occ0, s)) {
-		(*sp->decodepfunc)(tif, op0, occ0);
-		return 1;
-	} else
-		return 0;
-}
-
-/*
- * Decode a tile/strip and apply the predictor routine.
- * Note that horizontal differencing must be done on a
- * row-by-row basis.  The width of a "row" has already
- * been calculated at pre-decode time according to the
- * strip/tile dimensions.
- */
-static int
-PredictorDecodeTile(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
-{
-	TIFFPredictorState *sp = PredictorState(tif);
-
-	assert(sp != NULL);
-	assert(sp->decodetile != NULL);
-
-	if ((*sp->decodetile)(tif, op0, occ0, s)) {
-		tmsize_t rowsize = sp->rowsize;
-		assert(rowsize > 0);
-		assert((occ0%rowsize)==0);
-		assert(sp->decodepfunc != NULL);
-		while (occ0 > 0) {
-			(*sp->decodepfunc)(tif, op0, rowsize);
-			occ0 -= rowsize;
-			op0 += rowsize;
-		}
-		return 1;
-	} else
-		return 0;
-}
-
-static void
-horDiff8(TIFF* tif, uint8* cp0, tmsize_t cc)
-{
-	TIFFPredictorState* sp = PredictorState(tif);
-	tmsize_t stride = sp->stride;
-	char* cp = (char*) cp0;
-
-	assert((cc%stride)==0);
-
-	if (cc > stride) {
-		cc -= stride;
-		/*
-		 * Pipeline the most common cases.
-		 */
-		if (stride == 3) {
-			int r1, g1, b1;
-			int r2 = cp[0];
-			int g2 = cp[1];
-			int b2 = cp[2];
-			do {
-				r1 = cp[3]; cp[3] = r1-r2; r2 = r1;
-				g1 = cp[4]; cp[4] = g1-g2; g2 = g1;
-				b1 = cp[5]; cp[5] = b1-b2; b2 = b1;
-				cp += 3;
-			} while ((cc -= 3) > 0);
-		} else if (stride == 4) {
-			int r1, g1, b1, a1;
-			int r2 = cp[0];
-			int g2 = cp[1];
-			int b2 = cp[2];
-			int a2 = cp[3];
-			do {
-				r1 = cp[4]; cp[4] = r1-r2; r2 = r1;
-				g1 = cp[5]; cp[5] = g1-g2; g2 = g1;
-				b1 = cp[6]; cp[6] = b1-b2; b2 = b1;
-				a1 = cp[7]; cp[7] = a1-a2; a2 = a1;
-				cp += 4;
-			} while ((cc -= 4) > 0);
-		} else {
-			cp += cc - 1;
-			do {
-				REPEAT4(stride, cp[stride] -= cp[0]; cp--)
-			} while ((cc -= stride) > 0);
-		}
-	}
-}
-
-static void
-horDiff16(TIFF* tif, uint8* cp0, tmsize_t cc)
-{
-	TIFFPredictorState* sp = PredictorState(tif);
-	tmsize_t stride = sp->stride;
-	int16 *wp = (int16*) cp0;
-	tmsize_t wc = cc/2;
-
-	assert((cc%(2*stride))==0);
-
-	if (wc > stride) {
-		wc -= stride;
-		wp += wc - 1;
-		do {
-			REPEAT4(stride, wp[stride] -= wp[0]; wp--)
-			wc -= stride;
-		} while (wc > 0);
-	}
-}
-
-static void
-horDiff32(TIFF* tif, uint8* cp0, tmsize_t cc)
-{
-	TIFFPredictorState* sp = PredictorState(tif);
-	tmsize_t stride = sp->stride;
-	int32 *wp = (int32*) cp0;
-	tmsize_t wc = cc/4;
-
-	assert((cc%(4*stride))==0);
-
-	if (wc > stride) {
-		wc -= stride;
-		wp += wc - 1;
-		do {
-			REPEAT4(stride, wp[stride] -= wp[0]; wp--)
-			wc -= stride;
-		} while (wc > 0);
-	}
-}
-
-/*
- * Floating point predictor differencing routine.
- */
-static void
-fpDiff(TIFF* tif, uint8* cp0, tmsize_t cc)
-{
-	tmsize_t stride = PredictorState(tif)->stride;
-	uint32 bps = tif->tif_dir.td_bitspersample / 8;
-	tmsize_t wc = cc / bps;
-	tmsize_t count;
-	uint8 *cp = (uint8 *) cp0;
-	uint8 *tmp = (uint8 *)_TIFFmalloc(cc);
-
-	assert((cc%(bps*stride))==0);
-
-	if (!tmp)
-		return;
-
-	_TIFFmemcpy(tmp, cp0, cc);
-	for (count = 0; count < wc; count++) {
-		uint32 byte;
-		for (byte = 0; byte < bps; byte++) {
-			#if WORDS_BIGENDIAN
-			cp[byte * wc + count] = tmp[bps * count + byte];
-			#else
-			cp[(bps - byte - 1) * wc + count] =
-				tmp[bps * count + byte];
-			#endif
-		}
-	}
-	_TIFFfree(tmp);
-
-	cp = (uint8 *) cp0;
-	cp += cc - stride - 1;
-	for (count = cc; count > stride; count -= stride)
-		REPEAT4(stride, cp[stride] -= cp[0]; cp--)
-}
-
-static int
-PredictorEncodeRow(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
-{
-	TIFFPredictorState *sp = PredictorState(tif);
-
-	assert(sp != NULL);
-	assert(sp->encodepfunc != NULL);
-	assert(sp->encoderow != NULL);
-
-	/* XXX horizontal differencing alters user's data XXX */
-	(*sp->encodepfunc)(tif, bp, cc);
-	return (*sp->encoderow)(tif, bp, cc, s);
-}
-
-static int
-PredictorEncodeTile(TIFF* tif, uint8* bp0, tmsize_t cc0, uint16 s)
-{
-	static const char module[] = "PredictorEncodeTile";
-	TIFFPredictorState *sp = PredictorState(tif);
-        uint8 *working_copy;
-	tmsize_t cc = cc0, rowsize;
-	unsigned char* bp;
-        int result_code;
-
-	assert(sp != NULL);
-	assert(sp->encodepfunc != NULL);
-	assert(sp->encodetile != NULL);
-
-        /* 
-         * Do predictor manipulation in a working buffer to avoid altering
-         * the callers buffer. http://trac.osgeo.org/gdal/ticket/1965
-         */
-        working_copy = (uint8*) _TIFFmalloc(cc0);
-        if( working_copy == NULL )
-        {
-            TIFFErrorExt(tif->tif_clientdata, module, 
-                         "Out of memory allocating " TIFF_SSIZE_FORMAT " byte temp buffer.",
-                         cc0 );
-            return 0;
-        }
-        memcpy( working_copy, bp0, cc0 );
-        bp = working_copy;
-
-	rowsize = sp->rowsize;
-	assert(rowsize > 0);
-	assert((cc0%rowsize)==0);
-	while (cc > 0) {
-		(*sp->encodepfunc)(tif, bp, rowsize);
-		cc -= rowsize;
-		bp += rowsize;
-	}
-	result_code = (*sp->encodetile)(tif, working_copy, cc0, s);
-
-        _TIFFfree( working_copy );
-
-        return result_code;
-}
-
-#define	FIELD_PREDICTOR	(FIELD_CODEC+0)		/* XXX */
-
-static const TIFFField predictFields[] = {
-    { TIFFTAG_PREDICTOR, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UINT16, FIELD_PREDICTOR, FALSE, FALSE, "Predictor", NULL },
-};
-
-static int
-PredictorVSetField(TIFF* tif, uint32 tag, va_list ap)
-{
-	TIFFPredictorState *sp = PredictorState(tif);
-
-	assert(sp != NULL);
-	assert(sp->vsetparent != NULL);
-
-	switch (tag) {
-	case TIFFTAG_PREDICTOR:
-		sp->predictor = (uint16) va_arg(ap, uint16_vap);
-		TIFFSetFieldBit(tif, FIELD_PREDICTOR);
-		break;
-	default:
-		return (*sp->vsetparent)(tif, tag, ap);
-	}
-	tif->tif_flags |= TIFF_DIRTYDIRECT;
-	return 1;
-}
-
-static int
-PredictorVGetField(TIFF* tif, uint32 tag, va_list ap)
-{
-	TIFFPredictorState *sp = PredictorState(tif);
-
-	assert(sp != NULL);
-	assert(sp->vgetparent != NULL);
-
-	switch (tag) {
-	case TIFFTAG_PREDICTOR:
-		*va_arg(ap, uint16*) = sp->predictor;
-		break;
-	default:
-		return (*sp->vgetparent)(tif, tag, ap);
-	}
-	return 1;
-}
-
-static void
-PredictorPrintDir(TIFF* tif, FILE* fd, long flags)
-{
-	TIFFPredictorState* sp = PredictorState(tif);
-
-	(void) flags;
-	if (TIFFFieldSet(tif,FIELD_PREDICTOR)) {
-		fprintf(fd, "  Predictor: ");
-		switch (sp->predictor) {
-			case 1: fprintf(fd, "none "); break;
-			case 2: fprintf(fd, "horizontal differencing "); break;
-			case 3: fprintf(fd, "floating point predictor "); break;
-		}
-		fprintf(fd, "%u (0x%x)\n", sp->predictor, sp->predictor);
-	}
-	if (sp->printdir)
-		(*sp->printdir)(tif, fd, flags);
-}
-
-int
-TIFFPredictorInit(TIFF* tif)
-{
-	TIFFPredictorState* sp = PredictorState(tif);
-
-	assert(sp != 0);
-
-	/*
-	 * Merge codec-specific tag information.
-	 */
-	if (!_TIFFMergeFields(tif, predictFields,
-			      TIFFArrayCount(predictFields))) {
-		TIFFErrorExt(tif->tif_clientdata, "TIFFPredictorInit",
-		    "Merging Predictor codec-specific tags failed");
-		return 0;
-	}
-
-	/*
-	 * Override parent get/set field methods.
-	 */
-	sp->vgetparent = tif->tif_tagmethods.vgetfield;
-	tif->tif_tagmethods.vgetfield =
-            PredictorVGetField;/* hook for predictor tag */
-	sp->vsetparent = tif->tif_tagmethods.vsetfield;
-	tif->tif_tagmethods.vsetfield =
-	    PredictorVSetField;/* hook for predictor tag */
-	sp->printdir = tif->tif_tagmethods.printdir;
-	tif->tif_tagmethods.printdir =
-            PredictorPrintDir;	/* hook for predictor tag */
-
-	sp->setupdecode = tif->tif_setupdecode;
-	tif->tif_setupdecode = PredictorSetupDecode;
-	sp->setupencode = tif->tif_setupencode;
-	tif->tif_setupencode = PredictorSetupEncode;
-
-	sp->predictor = 1;			/* default value */
-	sp->encodepfunc = NULL;			/* no predictor routine */
-	sp->decodepfunc = NULL;			/* no predictor routine */
-	return 1;
-}
-
-int
-TIFFPredictorCleanup(TIFF* tif)
-{
-	TIFFPredictorState* sp = PredictorState(tif);
-
-	assert(sp != 0);
-
-	tif->tif_tagmethods.vgetfield = sp->vgetparent;
-	tif->tif_tagmethods.vsetfield = sp->vsetparent;
-	tif->tif_tagmethods.printdir = sp->printdir;
-	tif->tif_setupdecode = sp->setupdecode;
-	tif->tif_setupencode = sp->setupencode;
-
-	return 1;
-}
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Id: tif_predict.c,v 1.11 2015/02/19 22:39:59 drolon Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and 
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
+ * 
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Predictor Tag Support (used by multiple codecs).
+ */
+#include "tiffiop.h"
+#include "tif_predict.h"
+
+#define	PredictorState(tif)	((TIFFPredictorState*) (tif)->tif_data)
+
+static void horAcc8(TIFF* tif, uint8* cp0, tmsize_t cc);
+static void horAcc16(TIFF* tif, uint8* cp0, tmsize_t cc);
+static void horAcc32(TIFF* tif, uint8* cp0, tmsize_t cc);
+static void swabHorAcc16(TIFF* tif, uint8* cp0, tmsize_t cc);
+static void swabHorAcc32(TIFF* tif, uint8* cp0, tmsize_t cc);
+static void horDiff8(TIFF* tif, uint8* cp0, tmsize_t cc);
+static void horDiff16(TIFF* tif, uint8* cp0, tmsize_t cc);
+static void horDiff32(TIFF* tif, uint8* cp0, tmsize_t cc);
+static void fpAcc(TIFF* tif, uint8* cp0, tmsize_t cc);
+static void fpDiff(TIFF* tif, uint8* cp0, tmsize_t cc);
+static int PredictorDecodeRow(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s);
+static int PredictorDecodeTile(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s);
+static int PredictorEncodeRow(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s);
+static int PredictorEncodeTile(TIFF* tif, uint8* bp0, tmsize_t cc0, uint16 s);
+
+static int
+PredictorSetup(TIFF* tif)
+{
+	static const char module[] = "PredictorSetup";
+
+	TIFFPredictorState* sp = PredictorState(tif);
+	TIFFDirectory* td = &tif->tif_dir;
+
+	switch (sp->predictor)		/* no differencing */
+	{
+		case PREDICTOR_NONE:
+			return 1;
+		case PREDICTOR_HORIZONTAL:
+			if (td->td_bitspersample != 8
+			    && td->td_bitspersample != 16
+			    && td->td_bitspersample != 32) {
+				TIFFErrorExt(tif->tif_clientdata, module,
+				    "Horizontal differencing \"Predictor\" not supported with %d-bit samples",
+				    td->td_bitspersample);
+				return 0;
+			}
+			break;
+		case PREDICTOR_FLOATINGPOINT:
+			if (td->td_sampleformat != SAMPLEFORMAT_IEEEFP) {
+				TIFFErrorExt(tif->tif_clientdata, module,
+				    "Floating point \"Predictor\" not supported with %d data format",
+				    td->td_sampleformat);
+				return 0;
+			}
+			break;
+		default:
+			TIFFErrorExt(tif->tif_clientdata, module,
+			    "\"Predictor\" value %d not supported",
+			    sp->predictor);
+			return 0;
+	}
+	sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ?
+	    td->td_samplesperpixel : 1);
+	/*
+	 * Calculate the scanline/tile-width size in bytes.
+	 */
+	if (isTiled(tif))
+		sp->rowsize = TIFFTileRowSize(tif);
+	else
+		sp->rowsize = TIFFScanlineSize(tif);
+	if (sp->rowsize == 0)
+		return 0;
+
+	return 1;
+}
+
+static int
+PredictorSetupDecode(TIFF* tif)
+{
+	TIFFPredictorState* sp = PredictorState(tif);
+	TIFFDirectory* td = &tif->tif_dir;
+
+	if (!(*sp->setupdecode)(tif) || !PredictorSetup(tif))
+		return 0;
+
+	if (sp->predictor == 2) {
+		switch (td->td_bitspersample) {
+			case 8:  sp->decodepfunc = horAcc8; break;
+			case 16: sp->decodepfunc = horAcc16; break;
+			case 32: sp->decodepfunc = horAcc32; break;
+		}
+		/*
+		 * Override default decoding method with one that does the
+		 * predictor stuff.
+		 */
+                if( tif->tif_decoderow != PredictorDecodeRow )
+                {
+                    sp->decoderow = tif->tif_decoderow;
+                    tif->tif_decoderow = PredictorDecodeRow;
+                    sp->decodestrip = tif->tif_decodestrip;
+                    tif->tif_decodestrip = PredictorDecodeTile;
+                    sp->decodetile = tif->tif_decodetile;
+                    tif->tif_decodetile = PredictorDecodeTile;
+                }
+
+		/*
+		 * If the data is horizontally differenced 16-bit data that
+		 * requires byte-swapping, then it must be byte swapped before
+		 * the accumulation step.  We do this with a special-purpose
+		 * routine and override the normal post decoding logic that
+		 * the library setup when the directory was read.
+		 */
+		if (tif->tif_flags & TIFF_SWAB) {
+			if (sp->decodepfunc == horAcc16) {
+				sp->decodepfunc = swabHorAcc16;
+				tif->tif_postdecode = _TIFFNoPostDecode;
+            } else if (sp->decodepfunc == horAcc32) {
+				sp->decodepfunc = swabHorAcc32;
+				tif->tif_postdecode = _TIFFNoPostDecode;
+            }
+		}
+	}
+
+	else if (sp->predictor == 3) {
+		sp->decodepfunc = fpAcc;
+		/*
+		 * Override default decoding method with one that does the
+		 * predictor stuff.
+		 */
+                if( tif->tif_decoderow != PredictorDecodeRow )
+                {
+                    sp->decoderow = tif->tif_decoderow;
+                    tif->tif_decoderow = PredictorDecodeRow;
+                    sp->decodestrip = tif->tif_decodestrip;
+                    tif->tif_decodestrip = PredictorDecodeTile;
+                    sp->decodetile = tif->tif_decodetile;
+                    tif->tif_decodetile = PredictorDecodeTile;
+                }
+		/*
+		 * The data should not be swapped outside of the floating
+		 * point predictor, the accumulation routine should return
+		 * byres in the native order.
+		 */
+		if (tif->tif_flags & TIFF_SWAB) {
+			tif->tif_postdecode = _TIFFNoPostDecode;
+		}
+		/*
+		 * Allocate buffer to keep the decoded bytes before
+		 * rearranging in the ight order
+		 */
+	}
+
+	return 1;
+}
+
+static int
+PredictorSetupEncode(TIFF* tif)
+{
+	TIFFPredictorState* sp = PredictorState(tif);
+	TIFFDirectory* td = &tif->tif_dir;
+
+	if (!(*sp->setupencode)(tif) || !PredictorSetup(tif))
+		return 0;
+
+	if (sp->predictor == 2) {
+		switch (td->td_bitspersample) {
+			case 8:  sp->encodepfunc = horDiff8; break;
+			case 16: sp->encodepfunc = horDiff16; break;
+			case 32: sp->encodepfunc = horDiff32; break;
+		}
+		/*
+		 * Override default encoding method with one that does the
+		 * predictor stuff.
+		 */
+                if( tif->tif_encoderow != PredictorEncodeRow )
+                {
+                    sp->encoderow = tif->tif_encoderow;
+                    tif->tif_encoderow = PredictorEncodeRow;
+                    sp->encodestrip = tif->tif_encodestrip;
+                    tif->tif_encodestrip = PredictorEncodeTile;
+                    sp->encodetile = tif->tif_encodetile;
+                    tif->tif_encodetile = PredictorEncodeTile;
+                }
+	}
+
+	else if (sp->predictor == 3) {
+		sp->encodepfunc = fpDiff;
+		/*
+		 * Override default encoding method with one that does the
+		 * predictor stuff.
+		 */
+                if( tif->tif_encoderow != PredictorEncodeRow )
+                {
+                    sp->encoderow = tif->tif_encoderow;
+                    tif->tif_encoderow = PredictorEncodeRow;
+                    sp->encodestrip = tif->tif_encodestrip;
+                    tif->tif_encodestrip = PredictorEncodeTile;
+                    sp->encodetile = tif->tif_encodetile;
+                    tif->tif_encodetile = PredictorEncodeTile;
+                }
+	}
+
+	return 1;
+}
+
+#define REPEAT4(n, op)		\
+    switch (n) {		\
+    default: { tmsize_t i; for (i = n-4; i > 0; i--) { op; } } \
+    case 4:  op;		\
+    case 3:  op;		\
+    case 2:  op;		\
+    case 1:  op;		\
+    case 0:  ;			\
+    }
+
+static void
+horAcc8(TIFF* tif, uint8* cp0, tmsize_t cc)
+{
+	tmsize_t stride = PredictorState(tif)->stride;
+
+	char* cp = (char*) cp0;
+	assert((cc%stride)==0);
+	if (cc > stride) {
+		/*
+		 * Pipeline the most common cases.
+		 */
+		if (stride == 3)  {
+			unsigned int cr = cp[0];
+			unsigned int cg = cp[1];
+			unsigned int cb = cp[2];
+			cc -= 3;
+			cp += 3;
+			while (cc>0) {
+				cp[0] = (char) (cr += cp[0]);
+				cp[1] = (char) (cg += cp[1]);
+				cp[2] = (char) (cb += cp[2]);
+				cc -= 3;
+				cp += 3;
+			}
+		} else if (stride == 4)  {
+			unsigned int cr = cp[0];
+			unsigned int cg = cp[1];
+			unsigned int cb = cp[2];
+			unsigned int ca = cp[3];
+			cc -= 4;
+			cp += 4;
+			while (cc>0) {
+				cp[0] = (char) (cr += cp[0]);
+				cp[1] = (char) (cg += cp[1]);
+				cp[2] = (char) (cb += cp[2]);
+				cp[3] = (char) (ca += cp[3]);
+				cc -= 4;
+				cp += 4;
+			}
+		} else  {
+			cc -= stride;
+			do {
+				REPEAT4(stride, cp[stride] =
+					(char) (cp[stride] + *cp); cp++)
+				cc -= stride;
+			} while (cc>0);
+		}
+	}
+}
+
+static void
+swabHorAcc16(TIFF* tif, uint8* cp0, tmsize_t cc)
+{
+	tmsize_t stride = PredictorState(tif)->stride;
+	uint16* wp = (uint16*) cp0;
+	tmsize_t wc = cc / 2;
+
+	assert((cc%(2*stride))==0);
+
+	if (wc > stride) {
+		TIFFSwabArrayOfShort(wp, wc);
+		wc -= stride;
+		do {
+			REPEAT4(stride, wp[stride] += wp[0]; wp++)
+			wc -= stride;
+		} while (wc > 0);
+	}
+}
+
+static void
+horAcc16(TIFF* tif, uint8* cp0, tmsize_t cc)
+{
+	tmsize_t stride = PredictorState(tif)->stride;
+	uint16* wp = (uint16*) cp0;
+	tmsize_t wc = cc / 2;
+
+	assert((cc%(2*stride))==0);
+
+	if (wc > stride) {
+		wc -= stride;
+		do {
+			REPEAT4(stride, wp[stride] += wp[0]; wp++)
+			wc -= stride;
+		} while (wc > 0);
+	}
+}
+
+static void
+swabHorAcc32(TIFF* tif, uint8* cp0, tmsize_t cc)
+{
+	tmsize_t stride = PredictorState(tif)->stride;
+	uint32* wp = (uint32*) cp0;
+	tmsize_t wc = cc / 4;
+
+	assert((cc%(4*stride))==0);
+
+	if (wc > stride) {
+		TIFFSwabArrayOfLong(wp, wc);
+		wc -= stride;
+		do {
+			REPEAT4(stride, wp[stride] += wp[0]; wp++)
+			wc -= stride;
+		} while (wc > 0);
+	}
+}
+
+static void
+horAcc32(TIFF* tif, uint8* cp0, tmsize_t cc)
+{
+	tmsize_t stride = PredictorState(tif)->stride;
+	uint32* wp = (uint32*) cp0;
+	tmsize_t wc = cc / 4;
+
+	assert((cc%(4*stride))==0);
+
+	if (wc > stride) {
+		wc -= stride;
+		do {
+			REPEAT4(stride, wp[stride] += wp[0]; wp++)
+			wc -= stride;
+		} while (wc > 0);
+	}
+}
+
+/*
+ * Floating point predictor accumulation routine.
+ */
+static void
+fpAcc(TIFF* tif, uint8* cp0, tmsize_t cc)
+{
+	tmsize_t stride = PredictorState(tif)->stride;
+	uint32 bps = tif->tif_dir.td_bitspersample / 8;
+	tmsize_t wc = cc / bps;
+	tmsize_t count = cc;
+	uint8 *cp = (uint8 *) cp0;
+	uint8 *tmp = (uint8 *)_TIFFmalloc(cc);
+
+	assert((cc%(bps*stride))==0);
+
+	if (!tmp)
+		return;
+
+	while (count > stride) {
+		REPEAT4(stride, cp[stride] += cp[0]; cp++)
+		count -= stride;
+	}
+
+	_TIFFmemcpy(tmp, cp0, cc);
+	cp = (uint8 *) cp0;
+	for (count = 0; count < wc; count++) {
+		uint32 byte;
+		for (byte = 0; byte < bps; byte++) {
+			#if WORDS_BIGENDIAN
+			cp[bps * count + byte] = tmp[byte * wc + count];
+			#else
+			cp[bps * count + byte] =
+				tmp[(bps - byte - 1) * wc + count];
+			#endif
+		}
+	}
+	_TIFFfree(tmp);
+}
+
+/*
+ * Decode a scanline and apply the predictor routine.
+ */
+static int
+PredictorDecodeRow(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
+{
+	TIFFPredictorState *sp = PredictorState(tif);
+
+	assert(sp != NULL);
+	assert(sp->decoderow != NULL);
+	assert(sp->decodepfunc != NULL);  
+
+	if ((*sp->decoderow)(tif, op0, occ0, s)) {
+		(*sp->decodepfunc)(tif, op0, occ0);
+		return 1;
+	} else
+		return 0;
+}
+
+/*
+ * Decode a tile/strip and apply the predictor routine.
+ * Note that horizontal differencing must be done on a
+ * row-by-row basis.  The width of a "row" has already
+ * been calculated at pre-decode time according to the
+ * strip/tile dimensions.
+ */
+static int
+PredictorDecodeTile(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
+{
+	TIFFPredictorState *sp = PredictorState(tif);
+
+	assert(sp != NULL);
+	assert(sp->decodetile != NULL);
+
+	if ((*sp->decodetile)(tif, op0, occ0, s)) {
+		tmsize_t rowsize = sp->rowsize;
+		assert(rowsize > 0);
+		assert((occ0%rowsize)==0);
+		assert(sp->decodepfunc != NULL);
+		while (occ0 > 0) {
+			(*sp->decodepfunc)(tif, op0, rowsize);
+			occ0 -= rowsize;
+			op0 += rowsize;
+		}
+		return 1;
+	} else
+		return 0;
+}
+
+static void
+horDiff8(TIFF* tif, uint8* cp0, tmsize_t cc)
+{
+	TIFFPredictorState* sp = PredictorState(tif);
+	tmsize_t stride = sp->stride;
+	char* cp = (char*) cp0;
+
+	assert((cc%stride)==0);
+
+	if (cc > stride) {
+		cc -= stride;
+		/*
+		 * Pipeline the most common cases.
+		 */
+		if (stride == 3) {
+			int r1, g1, b1;
+			int r2 = cp[0];
+			int g2 = cp[1];
+			int b2 = cp[2];
+			do {
+				r1 = cp[3]; cp[3] = r1-r2; r2 = r1;
+				g1 = cp[4]; cp[4] = g1-g2; g2 = g1;
+				b1 = cp[5]; cp[5] = b1-b2; b2 = b1;
+				cp += 3;
+			} while ((cc -= 3) > 0);
+		} else if (stride == 4) {
+			int r1, g1, b1, a1;
+			int r2 = cp[0];
+			int g2 = cp[1];
+			int b2 = cp[2];
+			int a2 = cp[3];
+			do {
+				r1 = cp[4]; cp[4] = r1-r2; r2 = r1;
+				g1 = cp[5]; cp[5] = g1-g2; g2 = g1;
+				b1 = cp[6]; cp[6] = b1-b2; b2 = b1;
+				a1 = cp[7]; cp[7] = a1-a2; a2 = a1;
+				cp += 4;
+			} while ((cc -= 4) > 0);
+		} else {
+			cp += cc - 1;
+			do {
+				REPEAT4(stride, cp[stride] -= cp[0]; cp--)
+			} while ((cc -= stride) > 0);
+		}
+	}
+}
+
+static void
+horDiff16(TIFF* tif, uint8* cp0, tmsize_t cc)
+{
+	TIFFPredictorState* sp = PredictorState(tif);
+	tmsize_t stride = sp->stride;
+	int16 *wp = (int16*) cp0;
+	tmsize_t wc = cc/2;
+
+	assert((cc%(2*stride))==0);
+
+	if (wc > stride) {
+		wc -= stride;
+		wp += wc - 1;
+		do {
+			REPEAT4(stride, wp[stride] -= wp[0]; wp--)
+			wc -= stride;
+		} while (wc > 0);
+	}
+}
+
+static void
+horDiff32(TIFF* tif, uint8* cp0, tmsize_t cc)
+{
+	TIFFPredictorState* sp = PredictorState(tif);
+	tmsize_t stride = sp->stride;
+	int32 *wp = (int32*) cp0;
+	tmsize_t wc = cc/4;
+
+	assert((cc%(4*stride))==0);
+
+	if (wc > stride) {
+		wc -= stride;
+		wp += wc - 1;
+		do {
+			REPEAT4(stride, wp[stride] -= wp[0]; wp--)
+			wc -= stride;
+		} while (wc > 0);
+	}
+}
+
+/*
+ * Floating point predictor differencing routine.
+ */
+static void
+fpDiff(TIFF* tif, uint8* cp0, tmsize_t cc)
+{
+	tmsize_t stride = PredictorState(tif)->stride;
+	uint32 bps = tif->tif_dir.td_bitspersample / 8;
+	tmsize_t wc = cc / bps;
+	tmsize_t count;
+	uint8 *cp = (uint8 *) cp0;
+	uint8 *tmp = (uint8 *)_TIFFmalloc(cc);
+
+	assert((cc%(bps*stride))==0);
+
+	if (!tmp)
+		return;
+
+	_TIFFmemcpy(tmp, cp0, cc);
+	for (count = 0; count < wc; count++) {
+		uint32 byte;
+		for (byte = 0; byte < bps; byte++) {
+			#if WORDS_BIGENDIAN
+			cp[byte * wc + count] = tmp[bps * count + byte];
+			#else
+			cp[(bps - byte - 1) * wc + count] =
+				tmp[bps * count + byte];
+			#endif
+		}
+	}
+	_TIFFfree(tmp);
+
+	cp = (uint8 *) cp0;
+	cp += cc - stride - 1;
+	for (count = cc; count > stride; count -= stride)
+		REPEAT4(stride, cp[stride] -= cp[0]; cp--)
+}
+
+static int
+PredictorEncodeRow(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
+{
+	TIFFPredictorState *sp = PredictorState(tif);
+
+	assert(sp != NULL);
+	assert(sp->encodepfunc != NULL);
+	assert(sp->encoderow != NULL);
+
+	/* XXX horizontal differencing alters user's data XXX */
+	(*sp->encodepfunc)(tif, bp, cc);
+	return (*sp->encoderow)(tif, bp, cc, s);
+}
+
+static int
+PredictorEncodeTile(TIFF* tif, uint8* bp0, tmsize_t cc0, uint16 s)
+{
+	static const char module[] = "PredictorEncodeTile";
+	TIFFPredictorState *sp = PredictorState(tif);
+        uint8 *working_copy;
+	tmsize_t cc = cc0, rowsize;
+	unsigned char* bp;
+        int result_code;
+
+	assert(sp != NULL);
+	assert(sp->encodepfunc != NULL);
+	assert(sp->encodetile != NULL);
+
+        /* 
+         * Do predictor manipulation in a working buffer to avoid altering
+         * the callers buffer. http://trac.osgeo.org/gdal/ticket/1965
+         */
+        working_copy = (uint8*) _TIFFmalloc(cc0);
+        if( working_copy == NULL )
+        {
+            TIFFErrorExt(tif->tif_clientdata, module, 
+                         "Out of memory allocating " TIFF_SSIZE_FORMAT " byte temp buffer.",
+                         cc0 );
+            return 0;
+        }
+        memcpy( working_copy, bp0, cc0 );
+        bp = working_copy;
+
+	rowsize = sp->rowsize;
+	assert(rowsize > 0);
+	assert((cc0%rowsize)==0);
+	while (cc > 0) {
+		(*sp->encodepfunc)(tif, bp, rowsize);
+		cc -= rowsize;
+		bp += rowsize;
+	}
+	result_code = (*sp->encodetile)(tif, working_copy, cc0, s);
+
+        _TIFFfree( working_copy );
+
+        return result_code;
+}
+
+#define	FIELD_PREDICTOR	(FIELD_CODEC+0)		/* XXX */
+
+static const TIFFField predictFields[] = {
+    { TIFFTAG_PREDICTOR, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UINT16, FIELD_PREDICTOR, FALSE, FALSE, "Predictor", NULL },
+};
+
+static int
+PredictorVSetField(TIFF* tif, uint32 tag, va_list ap)
+{
+	TIFFPredictorState *sp = PredictorState(tif);
+
+	assert(sp != NULL);
+	assert(sp->vsetparent != NULL);
+
+	switch (tag) {
+	case TIFFTAG_PREDICTOR:
+		sp->predictor = (uint16) va_arg(ap, uint16_vap);
+		TIFFSetFieldBit(tif, FIELD_PREDICTOR);
+		break;
+	default:
+		return (*sp->vsetparent)(tif, tag, ap);
+	}
+	tif->tif_flags |= TIFF_DIRTYDIRECT;
+	return 1;
+}
+
+static int
+PredictorVGetField(TIFF* tif, uint32 tag, va_list ap)
+{
+	TIFFPredictorState *sp = PredictorState(tif);
+
+	assert(sp != NULL);
+	assert(sp->vgetparent != NULL);
+
+	switch (tag) {
+	case TIFFTAG_PREDICTOR:
+		*va_arg(ap, uint16*) = sp->predictor;
+		break;
+	default:
+		return (*sp->vgetparent)(tif, tag, ap);
+	}
+	return 1;
+}
+
+static void
+PredictorPrintDir(TIFF* tif, FILE* fd, long flags)
+{
+	TIFFPredictorState* sp = PredictorState(tif);
+
+	(void) flags;
+	if (TIFFFieldSet(tif,FIELD_PREDICTOR)) {
+		fprintf(fd, "  Predictor: ");
+		switch (sp->predictor) {
+			case 1: fprintf(fd, "none "); break;
+			case 2: fprintf(fd, "horizontal differencing "); break;
+			case 3: fprintf(fd, "floating point predictor "); break;
+		}
+		fprintf(fd, "%u (0x%x)\n", sp->predictor, sp->predictor);
+	}
+	if (sp->printdir)
+		(*sp->printdir)(tif, fd, flags);
+}
+
+int
+TIFFPredictorInit(TIFF* tif)
+{
+	TIFFPredictorState* sp = PredictorState(tif);
+
+	assert(sp != 0);
+
+	/*
+	 * Merge codec-specific tag information.
+	 */
+	if (!_TIFFMergeFields(tif, predictFields,
+			      TIFFArrayCount(predictFields))) {
+		TIFFErrorExt(tif->tif_clientdata, "TIFFPredictorInit",
+		    "Merging Predictor codec-specific tags failed");
+		return 0;
+	}
+
+	/*
+	 * Override parent get/set field methods.
+	 */
+	sp->vgetparent = tif->tif_tagmethods.vgetfield;
+	tif->tif_tagmethods.vgetfield =
+            PredictorVGetField;/* hook for predictor tag */
+	sp->vsetparent = tif->tif_tagmethods.vsetfield;
+	tif->tif_tagmethods.vsetfield =
+	    PredictorVSetField;/* hook for predictor tag */
+	sp->printdir = tif->tif_tagmethods.printdir;
+	tif->tif_tagmethods.printdir =
+            PredictorPrintDir;	/* hook for predictor tag */
+
+	sp->setupdecode = tif->tif_setupdecode;
+	tif->tif_setupdecode = PredictorSetupDecode;
+	sp->setupencode = tif->tif_setupencode;
+	tif->tif_setupencode = PredictorSetupEncode;
+
+	sp->predictor = 1;			/* default value */
+	sp->encodepfunc = NULL;			/* no predictor routine */
+	sp->decodepfunc = NULL;			/* no predictor routine */
+	return 1;
+}
+
+int
+TIFFPredictorCleanup(TIFF* tif)
+{
+	TIFFPredictorState* sp = PredictorState(tif);
+
+	assert(sp != 0);
+
+	tif->tif_tagmethods.vgetfield = sp->vgetparent;
+	tif->tif_tagmethods.vsetfield = sp->vsetparent;
+	tif->tif_tagmethods.printdir = sp->printdir;
+	tif->tif_setupdecode = sp->setupdecode;
+	tif->tif_setupencode = sp->setupencode;
+
+	return 1;
+}
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tif_predict.h b/Source/LibTIFF4/tif_predict.h
index 7df6066..5b869ea 100644
--- a/Source/LibTIFF4/tif_predict.h
+++ b/Source/LibTIFF4/tif_predict.h
@@ -1,77 +1,77 @@
-/* $Id: tif_predict.h,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * Copyright (c) 1995-1997 Sam Leffler
- * Copyright (c) 1995-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- */
-
-#ifndef _TIFFPREDICT_
-#define	_TIFFPREDICT_
-/*
- * ``Library-private'' Support for the Predictor Tag
- */
-
-/*
- * Codecs that want to support the Predictor tag must place
- * this structure first in their private state block so that
- * the predictor code can cast tif_data to find its state.
- */
-typedef struct {
-	int             predictor;	/* predictor tag value */
-	tmsize_t        stride;		/* sample stride over data */
-	tmsize_t        rowsize;	/* tile/strip row size */
-
-	TIFFCodeMethod  encoderow;	/* parent codec encode/decode row */
-	TIFFCodeMethod  encodestrip;	/* parent codec encode/decode strip */
-	TIFFCodeMethod  encodetile;	/* parent codec encode/decode tile */ 
-	TIFFPostMethod  encodepfunc;	/* horizontal differencer */
-
-	TIFFCodeMethod  decoderow;	/* parent codec encode/decode row */
-	TIFFCodeMethod  decodestrip;	/* parent codec encode/decode strip */
-	TIFFCodeMethod  decodetile;	/* parent codec encode/decode tile */ 
-	TIFFPostMethod  decodepfunc;	/* horizontal accumulator */
-
-	TIFFVGetMethod  vgetparent;	/* super-class method */
-	TIFFVSetMethod  vsetparent;	/* super-class method */
-	TIFFPrintMethod printdir;	/* super-class method */
-	TIFFBoolMethod  setupdecode;	/* super-class method */
-	TIFFBoolMethod  setupencode;	/* super-class method */
-} TIFFPredictorState;
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-extern int TIFFPredictorInit(TIFF*);
-extern int TIFFPredictorCleanup(TIFF*);
-#if defined(__cplusplus)
-}
-#endif
-#endif /* _TIFFPREDICT_ */
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Id: tif_predict.h,v 1.11 2015/02/19 22:39:59 drolon Exp $ */
+
+/*
+ * Copyright (c) 1995-1997 Sam Leffler
+ * Copyright (c) 1995-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef _TIFFPREDICT_
+#define	_TIFFPREDICT_
+/*
+ * ``Library-private'' Support for the Predictor Tag
+ */
+
+/*
+ * Codecs that want to support the Predictor tag must place
+ * this structure first in their private state block so that
+ * the predictor code can cast tif_data to find its state.
+ */
+typedef struct {
+	int             predictor;	/* predictor tag value */
+	tmsize_t        stride;		/* sample stride over data */
+	tmsize_t        rowsize;	/* tile/strip row size */
+
+	TIFFCodeMethod  encoderow;	/* parent codec encode/decode row */
+	TIFFCodeMethod  encodestrip;	/* parent codec encode/decode strip */
+	TIFFCodeMethod  encodetile;	/* parent codec encode/decode tile */ 
+	TIFFPostMethod  encodepfunc;	/* horizontal differencer */
+
+	TIFFCodeMethod  decoderow;	/* parent codec encode/decode row */
+	TIFFCodeMethod  decodestrip;	/* parent codec encode/decode strip */
+	TIFFCodeMethod  decodetile;	/* parent codec encode/decode tile */ 
+	TIFFPostMethod  decodepfunc;	/* horizontal accumulator */
+
+	TIFFVGetMethod  vgetparent;	/* super-class method */
+	TIFFVSetMethod  vsetparent;	/* super-class method */
+	TIFFPrintMethod printdir;	/* super-class method */
+	TIFFBoolMethod  setupdecode;	/* super-class method */
+	TIFFBoolMethod  setupencode;	/* super-class method */
+} TIFFPredictorState;
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+extern int TIFFPredictorInit(TIFF*);
+extern int TIFFPredictorCleanup(TIFF*);
+#if defined(__cplusplus)
+}
+#endif
+#endif /* _TIFFPREDICT_ */
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tif_print.c b/Source/LibTIFF4/tif_print.c
index 9b2b09e..5fbd182 100644
--- a/Source/LibTIFF4/tif_print.c
+++ b/Source/LibTIFF4/tif_print.c
@@ -1,716 +1,716 @@
-/* $Id: tif_print.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library.
- *
- * Directory Printing Support
- */
-#include "tiffiop.h"
-#include <stdio.h>
-
-#include <ctype.h>
-
-static void
-_TIFFprintAsciiBounded(FILE* fd, const char* cp, int max_chars);
-
-static const char *photoNames[] = {
-    "min-is-white",				/* PHOTOMETRIC_MINISWHITE */
-    "min-is-black",				/* PHOTOMETRIC_MINISBLACK */
-    "RGB color",				/* PHOTOMETRIC_RGB */
-    "palette color (RGB from colormap)",	/* PHOTOMETRIC_PALETTE */
-    "transparency mask",			/* PHOTOMETRIC_MASK */
-    "separated",				/* PHOTOMETRIC_SEPARATED */
-    "YCbCr",					/* PHOTOMETRIC_YCBCR */
-    "7 (0x7)",
-    "CIE L*a*b*",				/* PHOTOMETRIC_CIELAB */
-    "ICC L*a*b*",				/* PHOTOMETRIC_ICCLAB */
-    "ITU L*a*b*" 				/* PHOTOMETRIC_ITULAB */
-};
-#define	NPHOTONAMES	(sizeof (photoNames) / sizeof (photoNames[0]))
-
-static const char *orientNames[] = {
-    "0 (0x0)",
-    "row 0 top, col 0 lhs",			/* ORIENTATION_TOPLEFT */
-    "row 0 top, col 0 rhs",			/* ORIENTATION_TOPRIGHT */
-    "row 0 bottom, col 0 rhs",			/* ORIENTATION_BOTRIGHT */
-    "row 0 bottom, col 0 lhs",			/* ORIENTATION_BOTLEFT */
-    "row 0 lhs, col 0 top",			/* ORIENTATION_LEFTTOP */
-    "row 0 rhs, col 0 top",			/* ORIENTATION_RIGHTTOP */
-    "row 0 rhs, col 0 bottom",			/* ORIENTATION_RIGHTBOT */
-    "row 0 lhs, col 0 bottom",			/* ORIENTATION_LEFTBOT */
-};
-#define	NORIENTNAMES	(sizeof (orientNames) / sizeof (orientNames[0]))
-
-static void
-_TIFFPrintField(FILE* fd, const TIFFField *fip,
-		uint32 value_count, void *raw_data)
-{
-	uint32 j;
-		
-	fprintf(fd, "  %s: ", fip->field_name);
-
-	for(j = 0; j < value_count; j++) {
-		if(fip->field_type == TIFF_BYTE)
-			fprintf(fd, "%u", ((uint8 *) raw_data)[j]);
-		else if(fip->field_type == TIFF_UNDEFINED)
-			fprintf(fd, "0x%x",
-			    (unsigned int) ((unsigned char *) raw_data)[j]);
-		else if(fip->field_type == TIFF_SBYTE)
-			fprintf(fd, "%d", ((int8 *) raw_data)[j]);
-		else if(fip->field_type == TIFF_SHORT)
-			fprintf(fd, "%u", ((uint16 *) raw_data)[j]);
-		else if(fip->field_type == TIFF_SSHORT)
-			fprintf(fd, "%d", ((int16 *) raw_data)[j]);
-		else if(fip->field_type == TIFF_LONG)
-			fprintf(fd, "%lu",
-			    (unsigned long)((uint32 *) raw_data)[j]);
-		else if(fip->field_type == TIFF_SLONG)
-			fprintf(fd, "%ld", (long)((int32 *) raw_data)[j]);
-		else if(fip->field_type == TIFF_IFD)
-			fprintf(fd, "0x%lx",
-				(unsigned long)((uint32 *) raw_data)[j]);
-		else if(fip->field_type == TIFF_RATIONAL
-			|| fip->field_type == TIFF_SRATIONAL
-			|| fip->field_type == TIFF_FLOAT)
-			fprintf(fd, "%f", ((float *) raw_data)[j]);
-		else if(fip->field_type == TIFF_LONG8)
-#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
-			fprintf(fd, "%I64u",
-			    (unsigned __int64)((uint64 *) raw_data)[j]);
-#else
-			fprintf(fd, "%llu",
-			    (unsigned long long)((uint64 *) raw_data)[j]);
-#endif
-		else if(fip->field_type == TIFF_SLONG8)
-#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
-			fprintf(fd, "%I64d", (__int64)((int64 *) raw_data)[j]);
-#else
-			fprintf(fd, "%lld", (long long)((int64 *) raw_data)[j]);
-#endif
-		else if(fip->field_type == TIFF_IFD8)
-#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
-			fprintf(fd, "0x%I64x",
-				(unsigned __int64)((uint64 *) raw_data)[j]);
-#else
-			fprintf(fd, "0x%llx",
-				(unsigned long long)((uint64 *) raw_data)[j]);
-#endif
-		else if(fip->field_type == TIFF_FLOAT)
-			fprintf(fd, "%f", ((float *)raw_data)[j]);
-		else if(fip->field_type == TIFF_DOUBLE)
-			fprintf(fd, "%f", ((double *) raw_data)[j]);
-		else if(fip->field_type == TIFF_ASCII) {
-			fprintf(fd, "%s", (char *) raw_data);
-			break;
-		}
-		else {
-			fprintf(fd, "<unsupported data type in TIFFPrint>");
-			break;
-		}
-
-		if(j < value_count - 1)
-			fprintf(fd, ",");
-	}
-
-	fprintf(fd, "\n");
-}
-
-static int
-_TIFFPrettyPrintField(TIFF* tif, const TIFFField *fip, FILE* fd, uint32 tag,
-		      uint32 value_count, void *raw_data)
-{
-        (void) tif;
-
-	/* do not try to pretty print auto-defined fields */
-	if (strncmp(fip->field_name,"Tag ", 4) == 0) {
-		return 0;
-	}
-        
-	switch (tag)
-	{
-		case TIFFTAG_INKSET:
-			if (value_count == 2 && fip->field_type == TIFF_SHORT) {
-				fprintf(fd, "  Ink Set: ");
-				switch (*((uint16*)raw_data)) {
-				case INKSET_CMYK:
-					fprintf(fd, "CMYK\n");
-					break;
-				default:
-					fprintf(fd, "%u (0x%x)\n",
-						*((uint16*)raw_data),
-						*((uint16*)raw_data));
-					break;
-				}
-				return 1;
-			}
-			return 0;
-
-		case TIFFTAG_DOTRANGE:
-			if (value_count == 2 && fip->field_type == TIFF_SHORT) {
-				fprintf(fd, "  Dot Range: %u-%u\n",
-					((uint16*)raw_data)[0], ((uint16*)raw_data)[1]);
-				return 1;
-			}
-			return 0;
-
-		case TIFFTAG_WHITEPOINT:
-			if (value_count == 2 && fip->field_type == TIFF_RATIONAL) {
-				fprintf(fd, "  White Point: %g-%g\n",
-					((float *)raw_data)[0], ((float *)raw_data)[1]);
-				return 1;
-			} 
-			return 0;
-
-		case TIFFTAG_XMLPACKET:
-		{
-			uint32 i;
-
-			fprintf(fd, "  XMLPacket (XMP Metadata):\n" );
-			for(i = 0; i < value_count; i++)
-				fputc(((char *)raw_data)[i], fd);
-			fprintf( fd, "\n" );
-			return 1;
-		}
-		case TIFFTAG_RICHTIFFIPTC:
-			/*
-			 * XXX: for some weird reason RichTIFFIPTC tag
-			 * defined as array of LONG values.
-			 */
-			fprintf(fd,
-			    "  RichTIFFIPTC Data: <present>, %lu bytes\n",
-			    (unsigned long) value_count * 4);
-			return 1;
-
-		case TIFFTAG_PHOTOSHOP:
-			fprintf(fd, "  Photoshop Data: <present>, %lu bytes\n",
-			    (unsigned long) value_count);
-			return 1;
-
-		case TIFFTAG_ICCPROFILE:
-			fprintf(fd, "  ICC Profile: <present>, %lu bytes\n",
-			    (unsigned long) value_count);
-			return 1;
-
-		case TIFFTAG_STONITS:
-			if (value_count == 1 && fip->field_type == TIFF_DOUBLE) { 
-				fprintf(fd,
-					"  Sample to Nits conversion factor: %.4e\n",
-					*((double*)raw_data));
-				return 1;
-			}
-			return 0;
-	}
-
-	return 0;
-}
-
-/*
- * Print the contents of the current directory
- * to the specified stdio file stream.
- */
-void
-TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-	char *sep;
-	uint16 i;
-	long l, n;
-
-#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
-	fprintf(fd, "TIFF Directory at offset 0x%I64x (%I64u)\n",
-		(unsigned __int64) tif->tif_diroff,
-		(unsigned __int64) tif->tif_diroff);
-#else
-	fprintf(fd, "TIFF Directory at offset 0x%llx (%llu)\n",
-		(unsigned long long) tif->tif_diroff,
-		(unsigned long long) tif->tif_diroff);
-#endif
-	if (TIFFFieldSet(tif,FIELD_SUBFILETYPE)) {
-		fprintf(fd, "  Subfile Type:");
-		sep = " ";
-		if (td->td_subfiletype & FILETYPE_REDUCEDIMAGE) {
-			fprintf(fd, "%sreduced-resolution image", sep);
-			sep = "/";
-		}
-		if (td->td_subfiletype & FILETYPE_PAGE) {
-			fprintf(fd, "%smulti-page document", sep);
-			sep = "/";
-		}
-		if (td->td_subfiletype & FILETYPE_MASK)
-			fprintf(fd, "%stransparency mask", sep);
-		fprintf(fd, " (%lu = 0x%lx)\n",
-		    (long) td->td_subfiletype, (long) td->td_subfiletype);
-	}
-	if (TIFFFieldSet(tif,FIELD_IMAGEDIMENSIONS)) {
-		fprintf(fd, "  Image Width: %lu Image Length: %lu",
-		    (unsigned long) td->td_imagewidth, (unsigned long) td->td_imagelength);
-		if (TIFFFieldSet(tif,FIELD_IMAGEDEPTH))
-			fprintf(fd, " Image Depth: %lu",
-			    (unsigned long) td->td_imagedepth);
-		fprintf(fd, "\n");
-	}
-	if (TIFFFieldSet(tif,FIELD_TILEDIMENSIONS)) {
-		fprintf(fd, "  Tile Width: %lu Tile Length: %lu",
-		    (unsigned long) td->td_tilewidth, (unsigned long) td->td_tilelength);
-		if (TIFFFieldSet(tif,FIELD_TILEDEPTH))
-			fprintf(fd, " Tile Depth: %lu",
-			    (unsigned long) td->td_tiledepth);
-		fprintf(fd, "\n");
-	}
-	if (TIFFFieldSet(tif,FIELD_RESOLUTION)) {
-		fprintf(fd, "  Resolution: %g, %g",
-		    td->td_xresolution, td->td_yresolution);
-		if (TIFFFieldSet(tif,FIELD_RESOLUTIONUNIT)) {
-			switch (td->td_resolutionunit) {
-			case RESUNIT_NONE:
-				fprintf(fd, " (unitless)");
-				break;
-			case RESUNIT_INCH:
-				fprintf(fd, " pixels/inch");
-				break;
-			case RESUNIT_CENTIMETER:
-				fprintf(fd, " pixels/cm");
-				break;
-			default:
-				fprintf(fd, " (unit %u = 0x%x)",
-				    td->td_resolutionunit,
-				    td->td_resolutionunit);
-				break;
-			}
-		}
-		fprintf(fd, "\n");
-	}
-	if (TIFFFieldSet(tif,FIELD_POSITION))
-		fprintf(fd, "  Position: %g, %g\n",
-		    td->td_xposition, td->td_yposition);
-	if (TIFFFieldSet(tif,FIELD_BITSPERSAMPLE))
-		fprintf(fd, "  Bits/Sample: %u\n", td->td_bitspersample);
-	if (TIFFFieldSet(tif,FIELD_SAMPLEFORMAT)) {
-		fprintf(fd, "  Sample Format: ");
-		switch (td->td_sampleformat) {
-		case SAMPLEFORMAT_VOID:
-			fprintf(fd, "void\n");
-			break;
-		case SAMPLEFORMAT_INT:
-			fprintf(fd, "signed integer\n");
-			break;
-		case SAMPLEFORMAT_UINT:
-			fprintf(fd, "unsigned integer\n");
-			break;
-		case SAMPLEFORMAT_IEEEFP:
-			fprintf(fd, "IEEE floating point\n");
-			break;
-		case SAMPLEFORMAT_COMPLEXINT:
-			fprintf(fd, "complex signed integer\n");
-			break;
-		case SAMPLEFORMAT_COMPLEXIEEEFP:
-			fprintf(fd, "complex IEEE floating point\n");
-			break;
-		default:
-			fprintf(fd, "%u (0x%x)\n",
-			    td->td_sampleformat, td->td_sampleformat);
-			break;
-		}
-	}
-	if (TIFFFieldSet(tif,FIELD_COMPRESSION)) {
-		const TIFFCodec* c = TIFFFindCODEC(td->td_compression);
-		fprintf(fd, "  Compression Scheme: ");
-		if (c)
-			fprintf(fd, "%s\n", c->name);
-		else
-			fprintf(fd, "%u (0x%x)\n",
-			    td->td_compression, td->td_compression);
-	}
-	if (TIFFFieldSet(tif,FIELD_PHOTOMETRIC)) {
-		fprintf(fd, "  Photometric Interpretation: ");
-		if (td->td_photometric < NPHOTONAMES)
-			fprintf(fd, "%s\n", photoNames[td->td_photometric]);
-		else {
-			switch (td->td_photometric) {
-			case PHOTOMETRIC_LOGL:
-				fprintf(fd, "CIE Log2(L)\n");
-				break;
-			case PHOTOMETRIC_LOGLUV:
-				fprintf(fd, "CIE Log2(L) (u',v')\n");
-				break;
-			default:
-				fprintf(fd, "%u (0x%x)\n",
-				    td->td_photometric, td->td_photometric);
-				break;
-			}
-		}
-	}
-	if (TIFFFieldSet(tif,FIELD_EXTRASAMPLES) && td->td_extrasamples) {
-		fprintf(fd, "  Extra Samples: %u<", td->td_extrasamples);
-		sep = "";
-		for (i = 0; i < td->td_extrasamples; i++) {
-			switch (td->td_sampleinfo[i]) {
-			case EXTRASAMPLE_UNSPECIFIED:
-				fprintf(fd, "%sunspecified", sep);
-				break;
-			case EXTRASAMPLE_ASSOCALPHA:
-				fprintf(fd, "%sassoc-alpha", sep);
-				break;
-			case EXTRASAMPLE_UNASSALPHA:
-				fprintf(fd, "%sunassoc-alpha", sep);
-				break;
-			default:
-				fprintf(fd, "%s%u (0x%x)", sep,
-				    td->td_sampleinfo[i], td->td_sampleinfo[i]);
-				break;
-			}
-			sep = ", ";
-		}
-		fprintf(fd, ">\n");
-	}
-	if (TIFFFieldSet(tif,FIELD_INKNAMES)) {
-		char* cp;
-		fprintf(fd, "  Ink Names: ");
-		i = td->td_samplesperpixel;
-		sep = "";
-		for (cp = td->td_inknames; 
-		     i > 0 && cp < td->td_inknames + td->td_inknameslen; 
-		     cp = strchr(cp,'\0')+1, i--) {
-			int max_chars = 
-				td->td_inknameslen - (cp - td->td_inknames);
-			fputs(sep, fd);
-			_TIFFprintAsciiBounded(fd, cp, max_chars);
-			sep = ", ";
-		}
-                fputs("\n", fd);
-	}
-	if (TIFFFieldSet(tif,FIELD_THRESHHOLDING)) {
-		fprintf(fd, "  Thresholding: ");
-		switch (td->td_threshholding) {
-		case THRESHHOLD_BILEVEL:
-			fprintf(fd, "bilevel art scan\n");
-			break;
-		case THRESHHOLD_HALFTONE:
-			fprintf(fd, "halftone or dithered scan\n");
-			break;
-		case THRESHHOLD_ERRORDIFFUSE:
-			fprintf(fd, "error diffused\n");
-			break;
-		default:
-			fprintf(fd, "%u (0x%x)\n",
-			    td->td_threshholding, td->td_threshholding);
-			break;
-		}
-	}
-	if (TIFFFieldSet(tif,FIELD_FILLORDER)) {
-		fprintf(fd, "  FillOrder: ");
-		switch (td->td_fillorder) {
-		case FILLORDER_MSB2LSB:
-			fprintf(fd, "msb-to-lsb\n");
-			break;
-		case FILLORDER_LSB2MSB:
-			fprintf(fd, "lsb-to-msb\n");
-			break;
-		default:
-			fprintf(fd, "%u (0x%x)\n",
-			    td->td_fillorder, td->td_fillorder);
-			break;
-		}
-	}
-	if (TIFFFieldSet(tif,FIELD_YCBCRSUBSAMPLING))
-        {
-		fprintf(fd, "  YCbCr Subsampling: %u, %u\n",
-			td->td_ycbcrsubsampling[0], td->td_ycbcrsubsampling[1] );
-	}
-	if (TIFFFieldSet(tif,FIELD_YCBCRPOSITIONING)) {
-		fprintf(fd, "  YCbCr Positioning: ");
-		switch (td->td_ycbcrpositioning) {
-		case YCBCRPOSITION_CENTERED:
-			fprintf(fd, "centered\n");
-			break;
-		case YCBCRPOSITION_COSITED:
-			fprintf(fd, "cosited\n");
-			break;
-		default:
-			fprintf(fd, "%u (0x%x)\n",
-			    td->td_ycbcrpositioning, td->td_ycbcrpositioning);
-			break;
-		}
-	}
-	if (TIFFFieldSet(tif,FIELD_HALFTONEHINTS))
-		fprintf(fd, "  Halftone Hints: light %u dark %u\n",
-		    td->td_halftonehints[0], td->td_halftonehints[1]);
-	if (TIFFFieldSet(tif,FIELD_ORIENTATION)) {
-		fprintf(fd, "  Orientation: ");
-		if (td->td_orientation < NORIENTNAMES)
-			fprintf(fd, "%s\n", orientNames[td->td_orientation]);
-		else
-			fprintf(fd, "%u (0x%x)\n",
-			    td->td_orientation, td->td_orientation);
-	}
-	if (TIFFFieldSet(tif,FIELD_SAMPLESPERPIXEL))
-		fprintf(fd, "  Samples/Pixel: %u\n", td->td_samplesperpixel);
-	if (TIFFFieldSet(tif,FIELD_ROWSPERSTRIP)) {
-		fprintf(fd, "  Rows/Strip: ");
-		if (td->td_rowsperstrip == (uint32) -1)
-			fprintf(fd, "(infinite)\n");
-		else
-			fprintf(fd, "%lu\n", (unsigned long) td->td_rowsperstrip);
-	}
-	if (TIFFFieldSet(tif,FIELD_MINSAMPLEVALUE))
-		fprintf(fd, "  Min Sample Value: %u\n", td->td_minsamplevalue);
-	if (TIFFFieldSet(tif,FIELD_MAXSAMPLEVALUE))
-		fprintf(fd, "  Max Sample Value: %u\n", td->td_maxsamplevalue);
-	if (TIFFFieldSet(tif,FIELD_SMINSAMPLEVALUE)) {
-		int count = (tif->tif_flags & TIFF_PERSAMPLE) ? td->td_samplesperpixel : 1;
-		fprintf(fd, "  SMin Sample Value:");
-		for (i = 0; i < count; ++i)
-			fprintf(fd, " %g", td->td_sminsamplevalue[i]);
-		fprintf(fd, "\n");
-	}
-	if (TIFFFieldSet(tif,FIELD_SMAXSAMPLEVALUE)) {
-		int count = (tif->tif_flags & TIFF_PERSAMPLE) ? td->td_samplesperpixel : 1;
-		fprintf(fd, "  SMax Sample Value:");
-		for (i = 0; i < count; ++i)
-			fprintf(fd, " %g", td->td_smaxsamplevalue[i]);
-		fprintf(fd, "\n");
-	}
-	if (TIFFFieldSet(tif,FIELD_PLANARCONFIG)) {
-		fprintf(fd, "  Planar Configuration: ");
-		switch (td->td_planarconfig) {
-		case PLANARCONFIG_CONTIG:
-			fprintf(fd, "single image plane\n");
-			break;
-		case PLANARCONFIG_SEPARATE:
-			fprintf(fd, "separate image planes\n");
-			break;
-		default:
-			fprintf(fd, "%u (0x%x)\n",
-			    td->td_planarconfig, td->td_planarconfig);
-			break;
-		}
-	}
-	if (TIFFFieldSet(tif,FIELD_PAGENUMBER))
-		fprintf(fd, "  Page Number: %u-%u\n",
-		    td->td_pagenumber[0], td->td_pagenumber[1]);
-	if (TIFFFieldSet(tif,FIELD_COLORMAP)) {
-		fprintf(fd, "  Color Map: ");
-		if (flags & TIFFPRINT_COLORMAP) {
-			fprintf(fd, "\n");
-			n = 1L<<td->td_bitspersample;
-			for (l = 0; l < n; l++)
-				fprintf(fd, "   %5lu: %5u %5u %5u\n",
-				    l,
-				    td->td_colormap[0][l],
-				    td->td_colormap[1][l],
-				    td->td_colormap[2][l]);
-		} else
-			fprintf(fd, "(present)\n");
-	}
-	if (TIFFFieldSet(tif,FIELD_REFBLACKWHITE)) {
-		fprintf(fd, "  Reference Black/White:\n");
-		for (i = 0; i < 3; i++)
-		fprintf(fd, "    %2d: %5g %5g\n", i,
-			td->td_refblackwhite[2*i+0],
-			td->td_refblackwhite[2*i+1]);
-	}
-	if (TIFFFieldSet(tif,FIELD_TRANSFERFUNCTION)) {
-		fprintf(fd, "  Transfer Function: ");
-		if (flags & TIFFPRINT_CURVES) {
-			fprintf(fd, "\n");
-			n = 1L<<td->td_bitspersample;
-			for (l = 0; l < n; l++) {
-				fprintf(fd, "    %2lu: %5u",
-				    l, td->td_transferfunction[0][l]);
-				for (i = 1; i < td->td_samplesperpixel; i++)
-					fprintf(fd, " %5u",
-					    td->td_transferfunction[i][l]);
-				fputc('\n', fd);
-			}
-		} else
-			fprintf(fd, "(present)\n");
-	}
-	if (TIFFFieldSet(tif, FIELD_SUBIFD) && (td->td_subifd)) {
-		fprintf(fd, "  SubIFD Offsets:");
-		for (i = 0; i < td->td_nsubifd; i++)
-#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
-			fprintf(fd, " %5I64u",
-				(unsigned __int64) td->td_subifd[i]);
-#else
-			fprintf(fd, " %5llu",
-				(unsigned long long) td->td_subifd[i]);
-#endif
-		fputc('\n', fd);
-	}
-
-	/*
-	** Custom tag support.
-	*/
-	{
-		int  i;
-		short count;
-
-		count = (short) TIFFGetTagListCount(tif);
-		for(i = 0; i < count; i++) {
-			uint32 tag = TIFFGetTagListEntry(tif, i);
-			const TIFFField *fip;
-			uint32 value_count;
-			int mem_alloc = 0;
-			void *raw_data;
-
-			fip = TIFFFieldWithTag(tif, tag);
-			if(fip == NULL)
-				continue;
-
-			if(fip->field_passcount) {
-				if (fip->field_readcount == TIFF_VARIABLE ) {
-					if(TIFFGetField(tif, tag, &value_count, &raw_data) != 1)
-						continue;
-				} else if (fip->field_readcount == TIFF_VARIABLE2 ) {
-					uint16 small_value_count;
-					if(TIFFGetField(tif, tag, &small_value_count, &raw_data) != 1)
-						continue;
-					value_count = small_value_count;
-				} else {
-					assert (fip->field_readcount == TIFF_VARIABLE
-						|| fip->field_readcount == TIFF_VARIABLE2);
-					continue;
-				} 
-			} else {
-				if (fip->field_readcount == TIFF_VARIABLE
-				    || fip->field_readcount == TIFF_VARIABLE2)
-					value_count = 1;
-				else if (fip->field_readcount == TIFF_SPP)
-					value_count = td->td_samplesperpixel;
-				else
-					value_count = fip->field_readcount;
-				if (fip->field_tag == TIFFTAG_DOTRANGE
-				    && strcmp(fip->field_name,"DotRange") == 0) {
-					/* TODO: This is an evil exception and should not have been
-					   handled this way ... likely best if we move it into
-					   the directory structure with an explicit field in 
-					   libtiff 4.1 and assign it a FIELD_ value */
-					static uint16 dotrange[2];
-					raw_data = dotrange;
-					TIFFGetField(tif, tag, dotrange+0, dotrange+1);
-				} else if (fip->field_type == TIFF_ASCII
-					   || fip->field_readcount == TIFF_VARIABLE
-					   || fip->field_readcount == TIFF_VARIABLE2
-					   || fip->field_readcount == TIFF_SPP
-					   || value_count > 1) {
-					if(TIFFGetField(tif, tag, &raw_data) != 1)
-						continue;
-				} else {
-					raw_data = _TIFFmalloc(
-					    _TIFFDataSize(fip->field_type)
-					    * value_count);
-					mem_alloc = 1;
-					if(TIFFGetField(tif, tag, raw_data) != 1) {
-						_TIFFfree(raw_data);
-						continue;
-					}
-				}
-			}
-
-			/*
-			 * Catch the tags which needs to be specially handled
-			 * and pretty print them. If tag not handled in
-			 * _TIFFPrettyPrintField() fall down and print it as
-			 * any other tag.
-			 */
-			if (!_TIFFPrettyPrintField(tif, fip, fd, tag, value_count, raw_data))
-				_TIFFPrintField(fd, fip, value_count, raw_data);
-
-			if(mem_alloc)
-				_TIFFfree(raw_data);
-		}
-	}
-        
-	if (tif->tif_tagmethods.printdir)
-		(*tif->tif_tagmethods.printdir)(tif, fd, flags);
-
-        _TIFFFillStriles( tif );
-        
-	if ((flags & TIFFPRINT_STRIPS) &&
-	    TIFFFieldSet(tif,FIELD_STRIPOFFSETS)) {
-		uint32 s;
-
-		fprintf(fd, "  %lu %s:\n",
-		    (long) td->td_nstrips,
-		    isTiled(tif) ? "Tiles" : "Strips");
-		for (s = 0; s < td->td_nstrips; s++)
-#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
-			fprintf(fd, "    %3lu: [%8I64u, %8I64u]\n",
-			    (unsigned long) s,
-			    (unsigned __int64) td->td_stripoffset[s],
-			    (unsigned __int64) td->td_stripbytecount[s]);
-#else
-			fprintf(fd, "    %3lu: [%8llu, %8llu]\n",
-			    (unsigned long) s,
-			    (unsigned long long) td->td_stripoffset[s],
-			    (unsigned long long) td->td_stripbytecount[s]);
-#endif
-	}
-}
-
-void
-_TIFFprintAscii(FILE* fd, const char* cp)
-{
-	_TIFFprintAsciiBounded( fd, cp, strlen(cp));
-}
-
-static void
-_TIFFprintAsciiBounded(FILE* fd, const char* cp, int max_chars)
-{
-	for (; max_chars > 0 && *cp != '\0'; cp++, max_chars--) {
-		const char* tp;
-
-		if (isprint((int)*cp)) {
-			fputc(*cp, fd);
-			continue;
-		}
-		for (tp = "\tt\bb\rr\nn\vv"; *tp; tp++)
-			if (*tp++ == *cp)
-				break;
-		if (*tp)
-			fprintf(fd, "\\%c", *tp);
-		else
-			fprintf(fd, "\\%03o", *cp & 0xff);
-	}
-}
-
-void
-_TIFFprintAsciiTag(FILE* fd, const char* name, const char* value)
-{
-	fprintf(fd, "  %s: \"", name);
-	_TIFFprintAscii(fd, value);
-	fprintf(fd, "\"\n");
-}
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Id: tif_print.c,v 1.11 2015/02/19 22:39:59 drolon Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and 
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
+ * 
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Directory Printing Support
+ */
+#include "tiffiop.h"
+#include <stdio.h>
+
+#include <ctype.h>
+
+static void
+_TIFFprintAsciiBounded(FILE* fd, const char* cp, int max_chars);
+
+static const char *photoNames[] = {
+    "min-is-white",				/* PHOTOMETRIC_MINISWHITE */
+    "min-is-black",				/* PHOTOMETRIC_MINISBLACK */
+    "RGB color",				/* PHOTOMETRIC_RGB */
+    "palette color (RGB from colormap)",	/* PHOTOMETRIC_PALETTE */
+    "transparency mask",			/* PHOTOMETRIC_MASK */
+    "separated",				/* PHOTOMETRIC_SEPARATED */
+    "YCbCr",					/* PHOTOMETRIC_YCBCR */
+    "7 (0x7)",
+    "CIE L*a*b*",				/* PHOTOMETRIC_CIELAB */
+    "ICC L*a*b*",				/* PHOTOMETRIC_ICCLAB */
+    "ITU L*a*b*" 				/* PHOTOMETRIC_ITULAB */
+};
+#define	NPHOTONAMES	(sizeof (photoNames) / sizeof (photoNames[0]))
+
+static const char *orientNames[] = {
+    "0 (0x0)",
+    "row 0 top, col 0 lhs",			/* ORIENTATION_TOPLEFT */
+    "row 0 top, col 0 rhs",			/* ORIENTATION_TOPRIGHT */
+    "row 0 bottom, col 0 rhs",			/* ORIENTATION_BOTRIGHT */
+    "row 0 bottom, col 0 lhs",			/* ORIENTATION_BOTLEFT */
+    "row 0 lhs, col 0 top",			/* ORIENTATION_LEFTTOP */
+    "row 0 rhs, col 0 top",			/* ORIENTATION_RIGHTTOP */
+    "row 0 rhs, col 0 bottom",			/* ORIENTATION_RIGHTBOT */
+    "row 0 lhs, col 0 bottom",			/* ORIENTATION_LEFTBOT */
+};
+#define	NORIENTNAMES	(sizeof (orientNames) / sizeof (orientNames[0]))
+
+static void
+_TIFFPrintField(FILE* fd, const TIFFField *fip,
+		uint32 value_count, void *raw_data)
+{
+	uint32 j;
+		
+	fprintf(fd, "  %s: ", fip->field_name);
+
+	for(j = 0; j < value_count; j++) {
+		if(fip->field_type == TIFF_BYTE)
+			fprintf(fd, "%u", ((uint8 *) raw_data)[j]);
+		else if(fip->field_type == TIFF_UNDEFINED)
+			fprintf(fd, "0x%x",
+			    (unsigned int) ((unsigned char *) raw_data)[j]);
+		else if(fip->field_type == TIFF_SBYTE)
+			fprintf(fd, "%d", ((int8 *) raw_data)[j]);
+		else if(fip->field_type == TIFF_SHORT)
+			fprintf(fd, "%u", ((uint16 *) raw_data)[j]);
+		else if(fip->field_type == TIFF_SSHORT)
+			fprintf(fd, "%d", ((int16 *) raw_data)[j]);
+		else if(fip->field_type == TIFF_LONG)
+			fprintf(fd, "%lu",
+			    (unsigned long)((uint32 *) raw_data)[j]);
+		else if(fip->field_type == TIFF_SLONG)
+			fprintf(fd, "%ld", (long)((int32 *) raw_data)[j]);
+		else if(fip->field_type == TIFF_IFD)
+			fprintf(fd, "0x%lx",
+				(unsigned long)((uint32 *) raw_data)[j]);
+		else if(fip->field_type == TIFF_RATIONAL
+			|| fip->field_type == TIFF_SRATIONAL
+			|| fip->field_type == TIFF_FLOAT)
+			fprintf(fd, "%f", ((float *) raw_data)[j]);
+		else if(fip->field_type == TIFF_LONG8)
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+			fprintf(fd, "%I64u",
+			    (unsigned __int64)((uint64 *) raw_data)[j]);
+#else
+			fprintf(fd, "%llu",
+			    (unsigned long long)((uint64 *) raw_data)[j]);
+#endif
+		else if(fip->field_type == TIFF_SLONG8)
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+			fprintf(fd, "%I64d", (__int64)((int64 *) raw_data)[j]);
+#else
+			fprintf(fd, "%lld", (long long)((int64 *) raw_data)[j]);
+#endif
+		else if(fip->field_type == TIFF_IFD8)
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+			fprintf(fd, "0x%I64x",
+				(unsigned __int64)((uint64 *) raw_data)[j]);
+#else
+			fprintf(fd, "0x%llx",
+				(unsigned long long)((uint64 *) raw_data)[j]);
+#endif
+		else if(fip->field_type == TIFF_FLOAT)
+			fprintf(fd, "%f", ((float *)raw_data)[j]);
+		else if(fip->field_type == TIFF_DOUBLE)
+			fprintf(fd, "%f", ((double *) raw_data)[j]);
+		else if(fip->field_type == TIFF_ASCII) {
+			fprintf(fd, "%s", (char *) raw_data);
+			break;
+		}
+		else {
+			fprintf(fd, "<unsupported data type in TIFFPrint>");
+			break;
+		}
+
+		if(j < value_count - 1)
+			fprintf(fd, ",");
+	}
+
+	fprintf(fd, "\n");
+}
+
+static int
+_TIFFPrettyPrintField(TIFF* tif, const TIFFField *fip, FILE* fd, uint32 tag,
+		      uint32 value_count, void *raw_data)
+{
+        (void) tif;
+
+	/* do not try to pretty print auto-defined fields */
+	if (strncmp(fip->field_name,"Tag ", 4) == 0) {
+		return 0;
+	}
+        
+	switch (tag)
+	{
+		case TIFFTAG_INKSET:
+			if (value_count == 2 && fip->field_type == TIFF_SHORT) {
+				fprintf(fd, "  Ink Set: ");
+				switch (*((uint16*)raw_data)) {
+				case INKSET_CMYK:
+					fprintf(fd, "CMYK\n");
+					break;
+				default:
+					fprintf(fd, "%u (0x%x)\n",
+						*((uint16*)raw_data),
+						*((uint16*)raw_data));
+					break;
+				}
+				return 1;
+			}
+			return 0;
+
+		case TIFFTAG_DOTRANGE:
+			if (value_count == 2 && fip->field_type == TIFF_SHORT) {
+				fprintf(fd, "  Dot Range: %u-%u\n",
+					((uint16*)raw_data)[0], ((uint16*)raw_data)[1]);
+				return 1;
+			}
+			return 0;
+
+		case TIFFTAG_WHITEPOINT:
+			if (value_count == 2 && fip->field_type == TIFF_RATIONAL) {
+				fprintf(fd, "  White Point: %g-%g\n",
+					((float *)raw_data)[0], ((float *)raw_data)[1]);
+				return 1;
+			} 
+			return 0;
+
+		case TIFFTAG_XMLPACKET:
+		{
+			uint32 i;
+
+			fprintf(fd, "  XMLPacket (XMP Metadata):\n" );
+			for(i = 0; i < value_count; i++)
+				fputc(((char *)raw_data)[i], fd);
+			fprintf( fd, "\n" );
+			return 1;
+		}
+		case TIFFTAG_RICHTIFFIPTC:
+			/*
+			 * XXX: for some weird reason RichTIFFIPTC tag
+			 * defined as array of LONG values.
+			 */
+			fprintf(fd,
+			    "  RichTIFFIPTC Data: <present>, %lu bytes\n",
+			    (unsigned long) value_count * 4);
+			return 1;
+
+		case TIFFTAG_PHOTOSHOP:
+			fprintf(fd, "  Photoshop Data: <present>, %lu bytes\n",
+			    (unsigned long) value_count);
+			return 1;
+
+		case TIFFTAG_ICCPROFILE:
+			fprintf(fd, "  ICC Profile: <present>, %lu bytes\n",
+			    (unsigned long) value_count);
+			return 1;
+
+		case TIFFTAG_STONITS:
+			if (value_count == 1 && fip->field_type == TIFF_DOUBLE) { 
+				fprintf(fd,
+					"  Sample to Nits conversion factor: %.4e\n",
+					*((double*)raw_data));
+				return 1;
+			}
+			return 0;
+	}
+
+	return 0;
+}
+
+/*
+ * Print the contents of the current directory
+ * to the specified stdio file stream.
+ */
+void
+TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
+{
+	TIFFDirectory *td = &tif->tif_dir;
+	char *sep;
+	uint16 i;
+	long l, n;
+
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+	fprintf(fd, "TIFF Directory at offset 0x%I64x (%I64u)\n",
+		(unsigned __int64) tif->tif_diroff,
+		(unsigned __int64) tif->tif_diroff);
+#else
+	fprintf(fd, "TIFF Directory at offset 0x%llx (%llu)\n",
+		(unsigned long long) tif->tif_diroff,
+		(unsigned long long) tif->tif_diroff);
+#endif
+	if (TIFFFieldSet(tif,FIELD_SUBFILETYPE)) {
+		fprintf(fd, "  Subfile Type:");
+		sep = " ";
+		if (td->td_subfiletype & FILETYPE_REDUCEDIMAGE) {
+			fprintf(fd, "%sreduced-resolution image", sep);
+			sep = "/";
+		}
+		if (td->td_subfiletype & FILETYPE_PAGE) {
+			fprintf(fd, "%smulti-page document", sep);
+			sep = "/";
+		}
+		if (td->td_subfiletype & FILETYPE_MASK)
+			fprintf(fd, "%stransparency mask", sep);
+		fprintf(fd, " (%lu = 0x%lx)\n",
+		    (long) td->td_subfiletype, (long) td->td_subfiletype);
+	}
+	if (TIFFFieldSet(tif,FIELD_IMAGEDIMENSIONS)) {
+		fprintf(fd, "  Image Width: %lu Image Length: %lu",
+		    (unsigned long) td->td_imagewidth, (unsigned long) td->td_imagelength);
+		if (TIFFFieldSet(tif,FIELD_IMAGEDEPTH))
+			fprintf(fd, " Image Depth: %lu",
+			    (unsigned long) td->td_imagedepth);
+		fprintf(fd, "\n");
+	}
+	if (TIFFFieldSet(tif,FIELD_TILEDIMENSIONS)) {
+		fprintf(fd, "  Tile Width: %lu Tile Length: %lu",
+		    (unsigned long) td->td_tilewidth, (unsigned long) td->td_tilelength);
+		if (TIFFFieldSet(tif,FIELD_TILEDEPTH))
+			fprintf(fd, " Tile Depth: %lu",
+			    (unsigned long) td->td_tiledepth);
+		fprintf(fd, "\n");
+	}
+	if (TIFFFieldSet(tif,FIELD_RESOLUTION)) {
+		fprintf(fd, "  Resolution: %g, %g",
+		    td->td_xresolution, td->td_yresolution);
+		if (TIFFFieldSet(tif,FIELD_RESOLUTIONUNIT)) {
+			switch (td->td_resolutionunit) {
+			case RESUNIT_NONE:
+				fprintf(fd, " (unitless)");
+				break;
+			case RESUNIT_INCH:
+				fprintf(fd, " pixels/inch");
+				break;
+			case RESUNIT_CENTIMETER:
+				fprintf(fd, " pixels/cm");
+				break;
+			default:
+				fprintf(fd, " (unit %u = 0x%x)",
+				    td->td_resolutionunit,
+				    td->td_resolutionunit);
+				break;
+			}
+		}
+		fprintf(fd, "\n");
+	}
+	if (TIFFFieldSet(tif,FIELD_POSITION))
+		fprintf(fd, "  Position: %g, %g\n",
+		    td->td_xposition, td->td_yposition);
+	if (TIFFFieldSet(tif,FIELD_BITSPERSAMPLE))
+		fprintf(fd, "  Bits/Sample: %u\n", td->td_bitspersample);
+	if (TIFFFieldSet(tif,FIELD_SAMPLEFORMAT)) {
+		fprintf(fd, "  Sample Format: ");
+		switch (td->td_sampleformat) {
+		case SAMPLEFORMAT_VOID:
+			fprintf(fd, "void\n");
+			break;
+		case SAMPLEFORMAT_INT:
+			fprintf(fd, "signed integer\n");
+			break;
+		case SAMPLEFORMAT_UINT:
+			fprintf(fd, "unsigned integer\n");
+			break;
+		case SAMPLEFORMAT_IEEEFP:
+			fprintf(fd, "IEEE floating point\n");
+			break;
+		case SAMPLEFORMAT_COMPLEXINT:
+			fprintf(fd, "complex signed integer\n");
+			break;
+		case SAMPLEFORMAT_COMPLEXIEEEFP:
+			fprintf(fd, "complex IEEE floating point\n");
+			break;
+		default:
+			fprintf(fd, "%u (0x%x)\n",
+			    td->td_sampleformat, td->td_sampleformat);
+			break;
+		}
+	}
+	if (TIFFFieldSet(tif,FIELD_COMPRESSION)) {
+		const TIFFCodec* c = TIFFFindCODEC(td->td_compression);
+		fprintf(fd, "  Compression Scheme: ");
+		if (c)
+			fprintf(fd, "%s\n", c->name);
+		else
+			fprintf(fd, "%u (0x%x)\n",
+			    td->td_compression, td->td_compression);
+	}
+	if (TIFFFieldSet(tif,FIELD_PHOTOMETRIC)) {
+		fprintf(fd, "  Photometric Interpretation: ");
+		if (td->td_photometric < NPHOTONAMES)
+			fprintf(fd, "%s\n", photoNames[td->td_photometric]);
+		else {
+			switch (td->td_photometric) {
+			case PHOTOMETRIC_LOGL:
+				fprintf(fd, "CIE Log2(L)\n");
+				break;
+			case PHOTOMETRIC_LOGLUV:
+				fprintf(fd, "CIE Log2(L) (u',v')\n");
+				break;
+			default:
+				fprintf(fd, "%u (0x%x)\n",
+				    td->td_photometric, td->td_photometric);
+				break;
+			}
+		}
+	}
+	if (TIFFFieldSet(tif,FIELD_EXTRASAMPLES) && td->td_extrasamples) {
+		fprintf(fd, "  Extra Samples: %u<", td->td_extrasamples);
+		sep = "";
+		for (i = 0; i < td->td_extrasamples; i++) {
+			switch (td->td_sampleinfo[i]) {
+			case EXTRASAMPLE_UNSPECIFIED:
+				fprintf(fd, "%sunspecified", sep);
+				break;
+			case EXTRASAMPLE_ASSOCALPHA:
+				fprintf(fd, "%sassoc-alpha", sep);
+				break;
+			case EXTRASAMPLE_UNASSALPHA:
+				fprintf(fd, "%sunassoc-alpha", sep);
+				break;
+			default:
+				fprintf(fd, "%s%u (0x%x)", sep,
+				    td->td_sampleinfo[i], td->td_sampleinfo[i]);
+				break;
+			}
+			sep = ", ";
+		}
+		fprintf(fd, ">\n");
+	}
+	if (TIFFFieldSet(tif,FIELD_INKNAMES)) {
+		char* cp;
+		fprintf(fd, "  Ink Names: ");
+		i = td->td_samplesperpixel;
+		sep = "";
+		for (cp = td->td_inknames; 
+		     i > 0 && cp < td->td_inknames + td->td_inknameslen; 
+		     cp = strchr(cp,'\0')+1, i--) {
+			int max_chars = 
+				td->td_inknameslen - (cp - td->td_inknames);
+			fputs(sep, fd);
+			_TIFFprintAsciiBounded(fd, cp, max_chars);
+			sep = ", ";
+		}
+                fputs("\n", fd);
+	}
+	if (TIFFFieldSet(tif,FIELD_THRESHHOLDING)) {
+		fprintf(fd, "  Thresholding: ");
+		switch (td->td_threshholding) {
+		case THRESHHOLD_BILEVEL:
+			fprintf(fd, "bilevel art scan\n");
+			break;
+		case THRESHHOLD_HALFTONE:
+			fprintf(fd, "halftone or dithered scan\n");
+			break;
+		case THRESHHOLD_ERRORDIFFUSE:
+			fprintf(fd, "error diffused\n");
+			break;
+		default:
+			fprintf(fd, "%u (0x%x)\n",
+			    td->td_threshholding, td->td_threshholding);
+			break;
+		}
+	}
+	if (TIFFFieldSet(tif,FIELD_FILLORDER)) {
+		fprintf(fd, "  FillOrder: ");
+		switch (td->td_fillorder) {
+		case FILLORDER_MSB2LSB:
+			fprintf(fd, "msb-to-lsb\n");
+			break;
+		case FILLORDER_LSB2MSB:
+			fprintf(fd, "lsb-to-msb\n");
+			break;
+		default:
+			fprintf(fd, "%u (0x%x)\n",
+			    td->td_fillorder, td->td_fillorder);
+			break;
+		}
+	}
+	if (TIFFFieldSet(tif,FIELD_YCBCRSUBSAMPLING))
+        {
+		fprintf(fd, "  YCbCr Subsampling: %u, %u\n",
+			td->td_ycbcrsubsampling[0], td->td_ycbcrsubsampling[1] );
+	}
+	if (TIFFFieldSet(tif,FIELD_YCBCRPOSITIONING)) {
+		fprintf(fd, "  YCbCr Positioning: ");
+		switch (td->td_ycbcrpositioning) {
+		case YCBCRPOSITION_CENTERED:
+			fprintf(fd, "centered\n");
+			break;
+		case YCBCRPOSITION_COSITED:
+			fprintf(fd, "cosited\n");
+			break;
+		default:
+			fprintf(fd, "%u (0x%x)\n",
+			    td->td_ycbcrpositioning, td->td_ycbcrpositioning);
+			break;
+		}
+	}
+	if (TIFFFieldSet(tif,FIELD_HALFTONEHINTS))
+		fprintf(fd, "  Halftone Hints: light %u dark %u\n",
+		    td->td_halftonehints[0], td->td_halftonehints[1]);
+	if (TIFFFieldSet(tif,FIELD_ORIENTATION)) {
+		fprintf(fd, "  Orientation: ");
+		if (td->td_orientation < NORIENTNAMES)
+			fprintf(fd, "%s\n", orientNames[td->td_orientation]);
+		else
+			fprintf(fd, "%u (0x%x)\n",
+			    td->td_orientation, td->td_orientation);
+	}
+	if (TIFFFieldSet(tif,FIELD_SAMPLESPERPIXEL))
+		fprintf(fd, "  Samples/Pixel: %u\n", td->td_samplesperpixel);
+	if (TIFFFieldSet(tif,FIELD_ROWSPERSTRIP)) {
+		fprintf(fd, "  Rows/Strip: ");
+		if (td->td_rowsperstrip == (uint32) -1)
+			fprintf(fd, "(infinite)\n");
+		else
+			fprintf(fd, "%lu\n", (unsigned long) td->td_rowsperstrip);
+	}
+	if (TIFFFieldSet(tif,FIELD_MINSAMPLEVALUE))
+		fprintf(fd, "  Min Sample Value: %u\n", td->td_minsamplevalue);
+	if (TIFFFieldSet(tif,FIELD_MAXSAMPLEVALUE))
+		fprintf(fd, "  Max Sample Value: %u\n", td->td_maxsamplevalue);
+	if (TIFFFieldSet(tif,FIELD_SMINSAMPLEVALUE)) {
+		int count = (tif->tif_flags & TIFF_PERSAMPLE) ? td->td_samplesperpixel : 1;
+		fprintf(fd, "  SMin Sample Value:");
+		for (i = 0; i < count; ++i)
+			fprintf(fd, " %g", td->td_sminsamplevalue[i]);
+		fprintf(fd, "\n");
+	}
+	if (TIFFFieldSet(tif,FIELD_SMAXSAMPLEVALUE)) {
+		int count = (tif->tif_flags & TIFF_PERSAMPLE) ? td->td_samplesperpixel : 1;
+		fprintf(fd, "  SMax Sample Value:");
+		for (i = 0; i < count; ++i)
+			fprintf(fd, " %g", td->td_smaxsamplevalue[i]);
+		fprintf(fd, "\n");
+	}
+	if (TIFFFieldSet(tif,FIELD_PLANARCONFIG)) {
+		fprintf(fd, "  Planar Configuration: ");
+		switch (td->td_planarconfig) {
+		case PLANARCONFIG_CONTIG:
+			fprintf(fd, "single image plane\n");
+			break;
+		case PLANARCONFIG_SEPARATE:
+			fprintf(fd, "separate image planes\n");
+			break;
+		default:
+			fprintf(fd, "%u (0x%x)\n",
+			    td->td_planarconfig, td->td_planarconfig);
+			break;
+		}
+	}
+	if (TIFFFieldSet(tif,FIELD_PAGENUMBER))
+		fprintf(fd, "  Page Number: %u-%u\n",
+		    td->td_pagenumber[0], td->td_pagenumber[1]);
+	if (TIFFFieldSet(tif,FIELD_COLORMAP)) {
+		fprintf(fd, "  Color Map: ");
+		if (flags & TIFFPRINT_COLORMAP) {
+			fprintf(fd, "\n");
+			n = 1L<<td->td_bitspersample;
+			for (l = 0; l < n; l++)
+				fprintf(fd, "   %5lu: %5u %5u %5u\n",
+				    l,
+				    td->td_colormap[0][l],
+				    td->td_colormap[1][l],
+				    td->td_colormap[2][l]);
+		} else
+			fprintf(fd, "(present)\n");
+	}
+	if (TIFFFieldSet(tif,FIELD_REFBLACKWHITE)) {
+		fprintf(fd, "  Reference Black/White:\n");
+		for (i = 0; i < 3; i++)
+		fprintf(fd, "    %2d: %5g %5g\n", i,
+			td->td_refblackwhite[2*i+0],
+			td->td_refblackwhite[2*i+1]);
+	}
+	if (TIFFFieldSet(tif,FIELD_TRANSFERFUNCTION)) {
+		fprintf(fd, "  Transfer Function: ");
+		if (flags & TIFFPRINT_CURVES) {
+			fprintf(fd, "\n");
+			n = 1L<<td->td_bitspersample;
+			for (l = 0; l < n; l++) {
+				fprintf(fd, "    %2lu: %5u",
+				    l, td->td_transferfunction[0][l]);
+				for (i = 1; i < td->td_samplesperpixel; i++)
+					fprintf(fd, " %5u",
+					    td->td_transferfunction[i][l]);
+				fputc('\n', fd);
+			}
+		} else
+			fprintf(fd, "(present)\n");
+	}
+	if (TIFFFieldSet(tif, FIELD_SUBIFD) && (td->td_subifd)) {
+		fprintf(fd, "  SubIFD Offsets:");
+		for (i = 0; i < td->td_nsubifd; i++)
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+			fprintf(fd, " %5I64u",
+				(unsigned __int64) td->td_subifd[i]);
+#else
+			fprintf(fd, " %5llu",
+				(unsigned long long) td->td_subifd[i]);
+#endif
+		fputc('\n', fd);
+	}
+
+	/*
+	** Custom tag support.
+	*/
+	{
+		int  i;
+		short count;
+
+		count = (short) TIFFGetTagListCount(tif);
+		for(i = 0; i < count; i++) {
+			uint32 tag = TIFFGetTagListEntry(tif, i);
+			const TIFFField *fip;
+			uint32 value_count;
+			int mem_alloc = 0;
+			void *raw_data;
+
+			fip = TIFFFieldWithTag(tif, tag);
+			if(fip == NULL)
+				continue;
+
+			if(fip->field_passcount) {
+				if (fip->field_readcount == TIFF_VARIABLE2 ) {
+					if(TIFFGetField(tif, tag, &value_count, &raw_data) != 1)
+						continue;
+				} else if (fip->field_readcount == TIFF_VARIABLE ) {
+					uint16 small_value_count;
+					if(TIFFGetField(tif, tag, &small_value_count, &raw_data) != 1)
+						continue;
+					value_count = small_value_count;
+				} else {
+					assert (fip->field_readcount == TIFF_VARIABLE
+						|| fip->field_readcount == TIFF_VARIABLE2);
+					continue;
+				} 
+			} else {
+				if (fip->field_readcount == TIFF_VARIABLE
+				    || fip->field_readcount == TIFF_VARIABLE2)
+					value_count = 1;
+				else if (fip->field_readcount == TIFF_SPP)
+					value_count = td->td_samplesperpixel;
+				else
+					value_count = fip->field_readcount;
+				if (fip->field_tag == TIFFTAG_DOTRANGE
+				    && strcmp(fip->field_name,"DotRange") == 0) {
+					/* TODO: This is an evil exception and should not have been
+					   handled this way ... likely best if we move it into
+					   the directory structure with an explicit field in 
+					   libtiff 4.1 and assign it a FIELD_ value */
+					static uint16 dotrange[2];
+					raw_data = dotrange;
+					TIFFGetField(tif, tag, dotrange+0, dotrange+1);
+				} else if (fip->field_type == TIFF_ASCII
+					   || fip->field_readcount == TIFF_VARIABLE
+					   || fip->field_readcount == TIFF_VARIABLE2
+					   || fip->field_readcount == TIFF_SPP
+					   || value_count > 1) {
+					if(TIFFGetField(tif, tag, &raw_data) != 1)
+						continue;
+				} else {
+					raw_data = _TIFFmalloc(
+					    _TIFFDataSize(fip->field_type)
+					    * value_count);
+					mem_alloc = 1;
+					if(TIFFGetField(tif, tag, raw_data) != 1) {
+						_TIFFfree(raw_data);
+						continue;
+					}
+				}
+			}
+
+			/*
+			 * Catch the tags which needs to be specially handled
+			 * and pretty print them. If tag not handled in
+			 * _TIFFPrettyPrintField() fall down and print it as
+			 * any other tag.
+			 */
+			if (!_TIFFPrettyPrintField(tif, fip, fd, tag, value_count, raw_data))
+				_TIFFPrintField(fd, fip, value_count, raw_data);
+
+			if(mem_alloc)
+				_TIFFfree(raw_data);
+		}
+	}
+        
+	if (tif->tif_tagmethods.printdir)
+		(*tif->tif_tagmethods.printdir)(tif, fd, flags);
+
+        _TIFFFillStriles( tif );
+        
+	if ((flags & TIFFPRINT_STRIPS) &&
+	    TIFFFieldSet(tif,FIELD_STRIPOFFSETS)) {
+		uint32 s;
+
+		fprintf(fd, "  %lu %s:\n",
+		    (long) td->td_nstrips,
+		    isTiled(tif) ? "Tiles" : "Strips");
+		for (s = 0; s < td->td_nstrips; s++)
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+			fprintf(fd, "    %3lu: [%8I64u, %8I64u]\n",
+			    (unsigned long) s,
+			    (unsigned __int64) td->td_stripoffset[s],
+			    (unsigned __int64) td->td_stripbytecount[s]);
+#else
+			fprintf(fd, "    %3lu: [%8llu, %8llu]\n",
+			    (unsigned long) s,
+			    (unsigned long long) td->td_stripoffset[s],
+			    (unsigned long long) td->td_stripbytecount[s]);
+#endif
+	}
+}
+
+void
+_TIFFprintAscii(FILE* fd, const char* cp)
+{
+	_TIFFprintAsciiBounded( fd, cp, strlen(cp));
+}
+
+static void
+_TIFFprintAsciiBounded(FILE* fd, const char* cp, int max_chars)
+{
+	for (; max_chars > 0 && *cp != '\0'; cp++, max_chars--) {
+		const char* tp;
+
+		if (isprint((int)*cp)) {
+			fputc(*cp, fd);
+			continue;
+		}
+		for (tp = "\tt\bb\rr\nn\vv"; *tp; tp++)
+			if (*tp++ == *cp)
+				break;
+		if (*tp)
+			fprintf(fd, "\\%c", *tp);
+		else
+			fprintf(fd, "\\%03o", *cp & 0xff);
+	}
+}
+
+void
+_TIFFprintAsciiTag(FILE* fd, const char* name, const char* value)
+{
+	fprintf(fd, "  %s: \"", name);
+	_TIFFprintAscii(fd, value);
+	fprintf(fd, "\"\n");
+}
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tif_read.c b/Source/LibTIFF4/tif_read.c
index 4198a22..dea5b9c 100644
--- a/Source/LibTIFF4/tif_read.c
+++ b/Source/LibTIFF4/tif_read.c
@@ -1,1083 +1,1086 @@
-/* $Id: tif_read.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library.
- * Scanline-oriented Read Support
- */
-#include "tiffiop.h"
-#include <stdio.h>
-
-int TIFFFillStrip(TIFF* tif, uint32 strip);
-int TIFFFillTile(TIFF* tif, uint32 tile);
-static int TIFFStartStrip(TIFF* tif, uint32 strip);
-static int TIFFStartTile(TIFF* tif, uint32 tile);
-static int TIFFCheckRead(TIFF*, int);
-static tmsize_t
-TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size,const char* module);
-
-#define NOSTRIP ((uint32)(-1))       /* undefined state */
-#define NOTILE ((uint32)(-1))         /* undefined state */
-
-static int
-TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart )
-{
-	static const char module[] = "TIFFFillStripPartial";
-	register TIFFDirectory *td = &tif->tif_dir;
-        uint64 unused_data;
-        uint64 read_offset;
-        tmsize_t cc, to_read;
-        /* tmsize_t bytecountm; */
-        
-        if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
-            return 0;
-        
-        /*
-         * Expand raw data buffer, if needed, to hold data
-         * strip coming from file (perhaps should set upper
-         * bound on the size of a buffer we'll use?).
-         */
-
-        /* bytecountm=(tmsize_t) td->td_stripbytecount[strip]; */
-        if (read_ahead*2 > tif->tif_rawdatasize) {
-                assert( restart );
-                
-                tif->tif_curstrip = NOSTRIP;
-                if ((tif->tif_flags & TIFF_MYBUFFER) == 0) {
-                        TIFFErrorExt(tif->tif_clientdata, module,
-                                     "Data buffer too small to hold part of strip %lu",
-                                     (unsigned long) strip);
-                        return (0);
-                }
-                if (!TIFFReadBufferSetup(tif, 0, read_ahead*2))
-                        return (0);
-        }
-
-        if( restart )
-        {
-                tif->tif_rawdataloaded = 0;
-                tif->tif_rawdataoff = 0;
-        }
-
-        /*
-        ** If we are reading more data, move any unused data to the
-        ** start of the buffer.
-        */
-        if( tif->tif_rawdataloaded > 0 )
-                unused_data = tif->tif_rawdataloaded - (tif->tif_rawcp - tif->tif_rawdata);
-        else
-                unused_data = 0;
-        
-        if( unused_data > 0 )
-        {
-		assert((tif->tif_flags&TIFF_BUFFERMMAP)==0);
-                memmove( tif->tif_rawdata, tif->tif_rawcp, unused_data );
-        }
-
-        /*
-        ** Seek to the point in the file where more data should be read.
-        */
-        read_offset = td->td_stripoffset[strip]
-                + tif->tif_rawdataoff + tif->tif_rawdataloaded;
-
-        if (!SeekOK(tif, read_offset)) {
-                TIFFErrorExt(tif->tif_clientdata, module,
-                             "Seek error at scanline %lu, strip %lu",
-                             (unsigned long) tif->tif_row, (unsigned long) strip);
-                return 0;
-        }
-
-        /*
-        ** How much do we want to read?
-        */
-        to_read = tif->tif_rawdatasize - unused_data;
-        if( (uint64) to_read > td->td_stripbytecount[strip] 
-            - tif->tif_rawdataoff - tif->tif_rawdataloaded )
-        {
-                to_read = td->td_stripbytecount[strip]
-                        - tif->tif_rawdataoff - tif->tif_rawdataloaded;
-        }
-
-	assert((tif->tif_flags&TIFF_BUFFERMMAP)==0);
-        cc = TIFFReadFile(tif, tif->tif_rawdata + unused_data, to_read);
-
-        if (cc != to_read) {
-#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
-                TIFFErrorExt(tif->tif_clientdata, module,
-                             "Read error at scanline %lu; got %I64u bytes, expected %I64u",
-                             (unsigned long) tif->tif_row,
-                             (unsigned __int64) cc,
-                             (unsigned __int64) to_read);
-#else
-                TIFFErrorExt(tif->tif_clientdata, module,
-                             "Read error at scanline %lu; got %llu bytes, expected %llu",
-                             (unsigned long) tif->tif_row,
-                             (unsigned long long) cc,
-                             (unsigned long long) to_read);
-#endif
-                return 0;
-        }
-        
-        tif->tif_rawdataoff = tif->tif_rawdataoff + tif->tif_rawdataloaded - unused_data ;
-        tif->tif_rawdataloaded = unused_data + to_read;
-
-        tif->tif_rawcp = tif->tif_rawdata;
-                        
-        if (!isFillOrder(tif, td->td_fillorder) &&
-            (tif->tif_flags & TIFF_NOBITREV) == 0) {
-		assert((tif->tif_flags&TIFF_BUFFERMMAP)==0);
-                TIFFReverseBits(tif->tif_rawdata + unused_data, to_read );
-	}
-
-        /*
-        ** When starting a strip from the beginning we need to
-        ** restart the decoder.
-        */
-        if( restart )
-                return TIFFStartStrip(tif, strip);
-        else
-                return 1;
-}
-
-/*
- * Seek to a random row+sample in a file.
- *
- * Only used by TIFFReadScanline, and is only used on
- * strip organized files.  We do some tricky stuff to try
- * and avoid reading the whole compressed raw data for big
- * strips.
- */
-static int
-TIFFSeek(TIFF* tif, uint32 row, uint16 sample )
-{
-	register TIFFDirectory *td = &tif->tif_dir;
-	uint32 strip;
-        int    whole_strip;
-	tmsize_t read_ahead = 0;
-
-        /*
-        ** Establish what strip we are working from.
-        */
-	if (row >= td->td_imagelength) {	/* out of range */
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-		    "%lu: Row out of range, max %lu",
-		    (unsigned long) row,
-		    (unsigned long) td->td_imagelength);
-		return (0);
-	}
-	if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
-		if (sample >= td->td_samplesperpixel) {
-			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			    "%lu: Sample out of range, max %lu",
-			    (unsigned long) sample, (unsigned long) td->td_samplesperpixel);
-			return (0);
-		}
-		strip = (uint32)sample*td->td_stripsperimage + row/td->td_rowsperstrip;
-	} else
-		strip = row / td->td_rowsperstrip;
-
-        /*
-         * Do we want to treat this strip as one whole chunk or
-         * read it a few lines at a time?
-         */
-#if defined(CHUNKY_STRIP_READ_SUPPORT)
-        if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
-            return 0;
-        whole_strip = tif->tif_dir.td_stripbytecount[strip] < 10
-                || isMapped(tif);
-#else
-        whole_strip = 1;
-#endif
-        
-        if( !whole_strip )
-        {
-                read_ahead = tif->tif_scanlinesize * 16 + 5000;
-        }
-
-        /*
-         * If we haven't loaded this strip, do so now, possibly
-         * only reading the first part.
-         */
-	if (strip != tif->tif_curstrip) {	/* different strip, refill */
-                
-                if( whole_strip )
-                {
-                        if (!TIFFFillStrip(tif, strip))
-                                return (0);
-                }
-                else
-                {
-                        if( !TIFFFillStripPartial(tif,strip,read_ahead,1) )
-                                return 0;
-                }
-	}
-
-        /*
-        ** If we already have some data loaded, do we need to read some more?
-        */
-        else if( !whole_strip )
-        {
-                if( ((tif->tif_rawdata + tif->tif_rawdataloaded) - tif->tif_rawcp) < read_ahead 
-                    && (uint64) tif->tif_rawdataoff+tif->tif_rawdataloaded < td->td_stripbytecount[strip] )
-                {
-                        if( !TIFFFillStripPartial(tif,strip,read_ahead,0) )
-                                return 0;
-                }
-        }
-
-        if (row < tif->tif_row) {
-		/*
-		 * Moving backwards within the same strip: backup
-		 * to the start and then decode forward (below).
-		 *
-		 * NB: If you're planning on lots of random access within a
-		 * strip, it's better to just read and decode the entire
-		 * strip, and then access the decoded data in a random fashion.
-		 */
-
-                if( tif->tif_rawdataoff != 0 )
-                {
-                        if( !TIFFFillStripPartial(tif,strip,read_ahead,1) )
-                                return 0;
-                }
-                else
-                {
-                        if (!TIFFStartStrip(tif, strip))
-                                return (0);
-                }
-	}
-        
-	if (row != tif->tif_row) {
-		/*
-		 * Seek forward to the desired row.
-		 */
-
-                /* TODO: Will this really work with partial buffers? */
-                
-		if (!(*tif->tif_seek)(tif, row - tif->tif_row))
-			return (0);
-		tif->tif_row = row;
-	}
-
-	return (1);
-}
-
-int
-TIFFReadScanline(TIFF* tif, void* buf, uint32 row, uint16 sample)
-{
-	int e;
-
-	if (!TIFFCheckRead(tif, 0))
-		return (-1);
-	if( (e = TIFFSeek(tif, row, sample)) != 0) {
-		/*
-		 * Decompress desired row into user buffer.
-		 */
-		e = (*tif->tif_decoderow)
-		    (tif, (uint8*) buf, tif->tif_scanlinesize, sample);  
-
-		/* we are now poised at the beginning of the next row */
-		tif->tif_row = row + 1;
-
-		if (e)
-			(*tif->tif_postdecode)(tif, (uint8*) buf,
-			    tif->tif_scanlinesize);  
-	}
-	return (e > 0 ? 1 : -1);
-}
-
-/*
- * Read a strip of data and decompress the specified
- * amount into the user-supplied buffer.
- */
-tmsize_t
-TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size)
-{
-	static const char module[] = "TIFFReadEncodedStrip";
-	TIFFDirectory *td = &tif->tif_dir;
-	uint32 rowsperstrip;
-	uint32 stripsperplane;
-	uint32 stripinplane;
-	uint16 plane;
-	uint32 rows;
-	tmsize_t stripsize;
-	if (!TIFFCheckRead(tif,0))
-		return((tmsize_t)(-1));
-	if (strip>=td->td_nstrips)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,
-		    "%lu: Strip out of range, max %lu",(unsigned long)strip,
-		    (unsigned long)td->td_nstrips);
-		return((tmsize_t)(-1));
-	}
-	/*
-	 * Calculate the strip size according to the number of
-	 * rows in the strip (check for truncated last strip on any
-	 * of the separations).
-	 */
-	rowsperstrip=td->td_rowsperstrip;
-	if (rowsperstrip>td->td_imagelength)
-		rowsperstrip=td->td_imagelength;
-	stripsperplane=((td->td_imagelength+rowsperstrip-1)/rowsperstrip);
-	stripinplane=(strip%stripsperplane);
-	plane=(strip/stripsperplane);
-	rows=td->td_imagelength-stripinplane*rowsperstrip;
-	if (rows>rowsperstrip)
-		rows=rowsperstrip;
-	stripsize=TIFFVStripSize(tif,rows);
-	if (stripsize==0)
-		return((tmsize_t)(-1));
-	if ((size!=(tmsize_t)(-1))&&(size<stripsize))
-		stripsize=size;
-	if (!TIFFFillStrip(tif,strip))
-		return((tmsize_t)(-1));
-	if ((*tif->tif_decodestrip)(tif,buf,stripsize,plane)<=0)
-		return((tmsize_t)(-1));
-	(*tif->tif_postdecode)(tif,buf,stripsize);
-	return(stripsize);
-}
-
-static tmsize_t
-TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size,
-    const char* module)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-
-    if (!_TIFFFillStriles( tif ))
-        return ((tmsize_t)(-1));
-        
-	assert((tif->tif_flags&TIFF_NOREADRAW)==0);
-	if (!isMapped(tif)) {
-		tmsize_t cc;
-
-		if (!SeekOK(tif, td->td_stripoffset[strip])) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-			    "Seek error at scanline %lu, strip %lu",
-			    (unsigned long) tif->tif_row, (unsigned long) strip);
-			return ((tmsize_t)(-1));
-		}
-		cc = TIFFReadFile(tif, buf, size);
-		if (cc != size) {
-#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
-			TIFFErrorExt(tif->tif_clientdata, module,
-		"Read error at scanline %lu; got %I64u bytes, expected %I64u",
-				     (unsigned long) tif->tif_row,
-				     (unsigned __int64) cc,
-				     (unsigned __int64) size);
-#else
-			TIFFErrorExt(tif->tif_clientdata, module,
-		"Read error at scanline %lu; got %llu bytes, expected %llu",
-				     (unsigned long) tif->tif_row,
-				     (unsigned long long) cc,
-				     (unsigned long long) size);
-#endif
-			return ((tmsize_t)(-1));
-		}
-	} else {
-		tmsize_t ma,mb;
-		tmsize_t n;
-		ma=(tmsize_t)td->td_stripoffset[strip];
-		mb=ma+size;
-		if (((uint64)ma!=td->td_stripoffset[strip])||(ma>tif->tif_size))
-			n=0;
-		else if ((mb<ma)||(mb<size)||(mb>tif->tif_size))
-			n=tif->tif_size-ma;
-		else
-			n=size;
-		if (n!=size) {
-#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
-			TIFFErrorExt(tif->tif_clientdata, module,
-	"Read error at scanline %lu, strip %lu; got %I64u bytes, expected %I64u",
-				     (unsigned long) tif->tif_row,
-				     (unsigned long) strip,
-				     (unsigned __int64) n,
-				     (unsigned __int64) size);
-#else
-			TIFFErrorExt(tif->tif_clientdata, module,
-	"Read error at scanline %lu, strip %lu; got %llu bytes, expected %llu",
-				     (unsigned long) tif->tif_row,
-				     (unsigned long) strip,
-				     (unsigned long long) n,
-				     (unsigned long long) size);
-#endif
-			return ((tmsize_t)(-1));
-		}
-		_TIFFmemcpy(buf, tif->tif_base + ma,
-			    size);
-	}
-	return (size);
-}
-
-/*
- * Read a strip of data from the file.
- */
-tmsize_t
-TIFFReadRawStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size)
-{
-	static const char module[] = "TIFFReadRawStrip";
-	TIFFDirectory *td = &tif->tif_dir;
-	uint64 bytecount;
-	tmsize_t bytecountm;
-
-	if (!TIFFCheckRead(tif, 0))
-		return ((tmsize_t)(-1));
-	if (strip >= td->td_nstrips) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-		     "%lu: Strip out of range, max %lu",
-		     (unsigned long) strip,
-		     (unsigned long) td->td_nstrips);
-		return ((tmsize_t)(-1));
-	}
-	if (tif->tif_flags&TIFF_NOREADRAW)
-	{
-		TIFFErrorExt(tif->tif_clientdata, module,
-		    "Compression scheme does not support access to raw uncompressed data");
-		return ((tmsize_t)(-1));
-	}
-	bytecount = td->td_stripbytecount[strip];
-	if (bytecount <= 0) {
-#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
-		TIFFErrorExt(tif->tif_clientdata, module,
-			     "%I64u: Invalid strip byte count, strip %lu",
-			     (unsigned __int64) bytecount,
-			     (unsigned long) strip);
-#else
-		TIFFErrorExt(tif->tif_clientdata, module,
-			     "%llu: Invalid strip byte count, strip %lu",
-			     (unsigned long long) bytecount,
-			     (unsigned long) strip);
-#endif
-		return ((tmsize_t)(-1));
-	}
-	bytecountm = (tmsize_t)bytecount;
-	if ((uint64)bytecountm!=bytecount) {
-		TIFFErrorExt(tif->tif_clientdata, module, "Integer overflow");
-		return ((tmsize_t)(-1));
-	}
-	if (size != (tmsize_t)(-1) && size < bytecountm)
-		bytecountm = size;
-	return (TIFFReadRawStrip1(tif, strip, buf, bytecountm, module));
-}
-
-/*
- * Read the specified strip and setup for decoding. The data buffer is
- * expanded, as necessary, to hold the strip's data.
- */
-int
-TIFFFillStrip(TIFF* tif, uint32 strip)
-{
-	static const char module[] = "TIFFFillStrip";
-	TIFFDirectory *td = &tif->tif_dir;
-
-    if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
-        return 0;
-        
-	if ((tif->tif_flags&TIFF_NOREADRAW)==0)
-	{
-		uint64 bytecount = td->td_stripbytecount[strip];
-		if (bytecount <= 0) {
-#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
-			TIFFErrorExt(tif->tif_clientdata, module,
-				"Invalid strip byte count %I64u, strip %lu",
-				     (unsigned __int64) bytecount,
-				     (unsigned long) strip);
-#else
-			TIFFErrorExt(tif->tif_clientdata, module,
-				"Invalid strip byte count %llu, strip %lu",
-				     (unsigned long long) bytecount,
-				     (unsigned long) strip);
-#endif
-			return (0);
-		}
-		if (isMapped(tif) &&
-		    (isFillOrder(tif, td->td_fillorder)
-		    || (tif->tif_flags & TIFF_NOBITREV))) {
-			/*
-			 * The image is mapped into memory and we either don't
-			 * need to flip bits or the compression routine is
-			 * going to handle this operation itself.  In this
-			 * case, avoid copying the raw data and instead just
-			 * reference the data from the memory mapped file
-			 * image.  This assumes that the decompression
-			 * routines do not modify the contents of the raw data
-			 * buffer (if they try to, the application will get a
-			 * fault since the file is mapped read-only).
-			 */
-			if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
-				_TIFFfree(tif->tif_rawdata);
-				tif->tif_rawdata = NULL;
-				tif->tif_rawdatasize = 0;
-			}
-			tif->tif_flags &= ~TIFF_MYBUFFER;
-			/*
-			 * We must check for overflow, potentially causing
-			 * an OOB read. Instead of simple
-			 *
-			 *  td->td_stripoffset[strip]+bytecount > tif->tif_size
-			 *
-			 * comparison (which can overflow) we do the following
-			 * two comparisons:
-			 */
-			if (bytecount > (uint64)tif->tif_size ||
-			    td->td_stripoffset[strip] > (uint64)tif->tif_size - bytecount) {
-				/*
-				 * This error message might seem strange, but
-				 * it's what would happen if a read were done
-				 * instead.
-				 */
-#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
-				TIFFErrorExt(tif->tif_clientdata, module,
-
-					"Read error on strip %lu; "
-					"got %I64u bytes, expected %I64u",
-					(unsigned long) strip,
-					(unsigned __int64) tif->tif_size - td->td_stripoffset[strip],
-					(unsigned __int64) bytecount);
-#else
-				TIFFErrorExt(tif->tif_clientdata, module,
-
-					"Read error on strip %lu; "
-					"got %llu bytes, expected %llu",
-					(unsigned long) strip,
-					(unsigned long long) tif->tif_size - td->td_stripoffset[strip],
-					(unsigned long long) bytecount);
-#endif
-				tif->tif_curstrip = NOSTRIP;
-				return (0);
-			}
-			tif->tif_rawdatasize = (tmsize_t)bytecount;
-			tif->tif_rawdata = tif->tif_base + (tmsize_t)td->td_stripoffset[strip];
-                        tif->tif_rawdataoff = 0;
-                        tif->tif_rawdataloaded = (tmsize_t) bytecount;
-
-			/* 
-			 * When we have tif_rawdata reference directly into the memory mapped file
-			 * we need to be pretty careful about how we use the rawdata.  It is not
-			 * a general purpose working buffer as it normally otherwise is.  So we
-			 * keep track of this fact to avoid using it improperly.
-			 */
-			tif->tif_flags |= TIFF_BUFFERMMAP;
-		} else {
-			/*
-			 * Expand raw data buffer, if needed, to hold data
-			 * strip coming from file (perhaps should set upper
-			 * bound on the size of a buffer we'll use?).
-			 */
-			tmsize_t bytecountm;
-			bytecountm=(tmsize_t)bytecount;
-			if ((uint64)bytecountm!=bytecount)
-			{
-				TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
-				return(0);
-			}
-			if (bytecountm > tif->tif_rawdatasize) {
-				tif->tif_curstrip = NOSTRIP;
-				if ((tif->tif_flags & TIFF_MYBUFFER) == 0) {
-					TIFFErrorExt(tif->tif_clientdata, module,
-					    "Data buffer too small to hold strip %lu",
-					    (unsigned long) strip);
-					return (0);
-				}
-				if (!TIFFReadBufferSetup(tif, 0, bytecountm))
-					return (0);
-			}
-			if (tif->tif_flags&TIFF_BUFFERMMAP) {
-				tif->tif_curstrip = NOSTRIP;
-				if (!TIFFReadBufferSetup(tif, 0, bytecountm))
-					return (0);
-			}
-			if (TIFFReadRawStrip1(tif, strip, tif->tif_rawdata,
-				bytecountm, module) != bytecountm)
-				return (0);
-
-                        tif->tif_rawdataoff = 0;
-                        tif->tif_rawdataloaded = bytecountm;
-                        
-			if (!isFillOrder(tif, td->td_fillorder) &&
-			    (tif->tif_flags & TIFF_NOBITREV) == 0)
-				TIFFReverseBits(tif->tif_rawdata, bytecountm);
-                }
-	}
-	return (TIFFStartStrip(tif, strip));
-}
-
-/*
- * Tile-oriented Read Support
- * Contributed by Nancy Cam (Silicon Graphics).
- */
-
-/*
- * Read and decompress a tile of data.  The
- * tile is selected by the (x,y,z,s) coordinates.
- */
-tmsize_t
-TIFFReadTile(TIFF* tif, void* buf, uint32 x, uint32 y, uint32 z, uint16 s)
-{
-	if (!TIFFCheckRead(tif, 1) || !TIFFCheckTile(tif, x, y, z, s))
-		return ((tmsize_t)(-1));
-	return (TIFFReadEncodedTile(tif,
-	    TIFFComputeTile(tif, x, y, z, s), buf, (tmsize_t)(-1)));
-}
-
-/*
- * Read a tile of data and decompress the specified
- * amount into the user-supplied buffer.
- */
-tmsize_t
-TIFFReadEncodedTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size)
-{
-	static const char module[] = "TIFFReadEncodedTile";
-	TIFFDirectory *td = &tif->tif_dir;
-	tmsize_t tilesize = tif->tif_tilesize;
-
-	if (!TIFFCheckRead(tif, 1))
-		return ((tmsize_t)(-1));
-	if (tile >= td->td_nstrips) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-		    "%lu: Tile out of range, max %lu",
-		    (unsigned long) tile, (unsigned long) td->td_nstrips);
-		return ((tmsize_t)(-1));
-	}
-	if (size == (tmsize_t)(-1))
-		size = tilesize;
-	else if (size > tilesize)
-		size = tilesize;
-	if (TIFFFillTile(tif, tile) && (*tif->tif_decodetile)(tif,
-	    (uint8*) buf, size, (uint16)(tile/td->td_stripsperimage))) {
-		(*tif->tif_postdecode)(tif, (uint8*) buf, size);
-		return (size);
-	} else
-		return ((tmsize_t)(-1));
-}
-
-static tmsize_t
-TIFFReadRawTile1(TIFF* tif, uint32 tile, void* buf, tmsize_t size, const char* module)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-
-    if (!_TIFFFillStriles( tif ))
-        return ((tmsize_t)(-1));
-
-	assert((tif->tif_flags&TIFF_NOREADRAW)==0);
-	if (!isMapped(tif)) {
-		tmsize_t cc;
-
-		if (!SeekOK(tif, td->td_stripoffset[tile])) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-			    "Seek error at row %lu, col %lu, tile %lu",
-			    (unsigned long) tif->tif_row,
-			    (unsigned long) tif->tif_col,
-			    (unsigned long) tile);
-			return ((tmsize_t)(-1));
-		}
-		cc = TIFFReadFile(tif, buf, size);
-		if (cc != size) {
-#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
-			TIFFErrorExt(tif->tif_clientdata, module,
-	"Read error at row %lu, col %lu; got %I64u bytes, expected %I64u",
-				     (unsigned long) tif->tif_row,
-				     (unsigned long) tif->tif_col,
-				     (unsigned __int64) cc,
-				     (unsigned __int64) size);
-#else
-			TIFFErrorExt(tif->tif_clientdata, module,
-	"Read error at row %lu, col %lu; got %llu bytes, expected %llu",
-				     (unsigned long) tif->tif_row,
-				     (unsigned long) tif->tif_col,
-				     (unsigned long long) cc,
-				     (unsigned long long) size);
-#endif
-			return ((tmsize_t)(-1));
-		}
-	} else {
-		tmsize_t ma,mb;
-		tmsize_t n;
-		ma=(tmsize_t)td->td_stripoffset[tile];
-		mb=ma+size;
-		if (((uint64)ma!=td->td_stripoffset[tile])||(ma>tif->tif_size))
-			n=0;
-		else if ((mb<ma)||(mb<size)||(mb>tif->tif_size))
-			n=tif->tif_size-ma;
-		else
-			n=size;
-		if (n!=size) {
-#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
-			TIFFErrorExt(tif->tif_clientdata, module,
-"Read error at row %lu, col %lu, tile %lu; got %I64u bytes, expected %I64u",
-				     (unsigned long) tif->tif_row,
-				     (unsigned long) tif->tif_col,
-				     (unsigned long) tile,
-				     (unsigned __int64) n,
-				     (unsigned __int64) size);
-#else
-			TIFFErrorExt(tif->tif_clientdata, module,
-"Read error at row %lu, col %lu, tile %lu; got %llu bytes, expected %llu",
-				     (unsigned long) tif->tif_row,
-				     (unsigned long) tif->tif_col,
-				     (unsigned long) tile,
-				     (unsigned long long) n,
-				     (unsigned long long) size);
-#endif
-			return ((tmsize_t)(-1));
-		}
-		_TIFFmemcpy(buf, tif->tif_base + ma, size);
-	}
-	return (size);
-}
-
-/*
- * Read a tile of data from the file.
- */
-tmsize_t
-TIFFReadRawTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size)
-{
-	static const char module[] = "TIFFReadRawTile";
-	TIFFDirectory *td = &tif->tif_dir;
-	uint64 bytecount64;
-	tmsize_t bytecountm;
-
-	if (!TIFFCheckRead(tif, 1))
-		return ((tmsize_t)(-1));
-	if (tile >= td->td_nstrips) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-		    "%lu: Tile out of range, max %lu",
-		    (unsigned long) tile, (unsigned long) td->td_nstrips);
-		return ((tmsize_t)(-1));
-	}
-	if (tif->tif_flags&TIFF_NOREADRAW)
-	{
-		TIFFErrorExt(tif->tif_clientdata, module,
-		"Compression scheme does not support access to raw uncompressed data");
-		return ((tmsize_t)(-1));
-	}
-	bytecount64 = td->td_stripbytecount[tile];
-	if (size != (tmsize_t)(-1) && (uint64)size < bytecount64)
-		bytecount64 = (uint64)size;
-	bytecountm = (tmsize_t)bytecount64;
-	if ((uint64)bytecountm!=bytecount64)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
-		return ((tmsize_t)(-1));
-	}
-	return (TIFFReadRawTile1(tif, tile, buf, bytecountm, module));
-}
-
-/*
- * Read the specified tile and setup for decoding. The data buffer is
- * expanded, as necessary, to hold the tile's data.
- */
-int
-TIFFFillTile(TIFF* tif, uint32 tile)
-{
-	static const char module[] = "TIFFFillTile";
-	TIFFDirectory *td = &tif->tif_dir;
-
-    if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
-        return 0;
-        
-	if ((tif->tif_flags&TIFF_NOREADRAW)==0)
-	{
-		uint64 bytecount = td->td_stripbytecount[tile];
-		if (bytecount <= 0) {
-#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
-			TIFFErrorExt(tif->tif_clientdata, module,
-				"%I64u: Invalid tile byte count, tile %lu",
-				     (unsigned __int64) bytecount,
-				     (unsigned long) tile);
-#else
-			TIFFErrorExt(tif->tif_clientdata, module,
-				"%llu: Invalid tile byte count, tile %lu",
-				     (unsigned long long) bytecount,
-				     (unsigned long) tile);
-#endif
-			return (0);
-		}
-		if (isMapped(tif) &&
-		    (isFillOrder(tif, td->td_fillorder)
-		     || (tif->tif_flags & TIFF_NOBITREV))) {
-			/*
-			 * The image is mapped into memory and we either don't
-			 * need to flip bits or the compression routine is
-			 * going to handle this operation itself.  In this
-			 * case, avoid copying the raw data and instead just
-			 * reference the data from the memory mapped file
-			 * image.  This assumes that the decompression
-			 * routines do not modify the contents of the raw data
-			 * buffer (if they try to, the application will get a
-			 * fault since the file is mapped read-only).
-			 */
-			if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
-				_TIFFfree(tif->tif_rawdata);
-				tif->tif_rawdata = NULL;
-				tif->tif_rawdatasize = 0;
-			}
-			tif->tif_flags &= ~TIFF_MYBUFFER;
-			/*
-			 * We must check for overflow, potentially causing
-			 * an OOB read. Instead of simple
-			 *
-			 *  td->td_stripoffset[tile]+bytecount > tif->tif_size
-			 *
-			 * comparison (which can overflow) we do the following
-			 * two comparisons:
-			 */
-			if (bytecount > (uint64)tif->tif_size ||
-			    td->td_stripoffset[tile] > (uint64)tif->tif_size - bytecount) {
-				tif->tif_curtile = NOTILE;
-				return (0);
-			}
-			tif->tif_rawdatasize = (tmsize_t)bytecount;
-			tif->tif_rawdata =
-				tif->tif_base + (tmsize_t)td->td_stripoffset[tile];
-                        tif->tif_rawdataoff = 0;
-                        tif->tif_rawdataloaded = (tmsize_t) bytecount;
-			tif->tif_flags |= TIFF_BUFFERMMAP;
-		} else {
-			/*
-			 * Expand raw data buffer, if needed, to hold data
-			 * tile coming from file (perhaps should set upper
-			 * bound on the size of a buffer we'll use?).
-			 */
-			tmsize_t bytecountm;
-			bytecountm=(tmsize_t)bytecount;
-			if ((uint64)bytecountm!=bytecount)
-			{
-				TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
-				return(0);
-			}
-			if (bytecountm > tif->tif_rawdatasize) {
-				tif->tif_curtile = NOTILE;
-				if ((tif->tif_flags & TIFF_MYBUFFER) == 0) {
-					TIFFErrorExt(tif->tif_clientdata, module,
-					    "Data buffer too small to hold tile %lu",
-					    (unsigned long) tile);
-					return (0);
-				}
-				if (!TIFFReadBufferSetup(tif, 0, bytecountm))
-					return (0);
-			}
-			if (tif->tif_flags&TIFF_BUFFERMMAP) {
-				tif->tif_curtile = NOTILE;
-				if (!TIFFReadBufferSetup(tif, 0, bytecountm))
-					return (0);
-			}
-
-			if (TIFFReadRawTile1(tif, tile, tif->tif_rawdata,
-			    bytecountm, module) != bytecountm)
-				return (0);
-
-                        tif->tif_rawdataoff = 0;
-                        tif->tif_rawdataloaded = bytecountm;
-                        
-			if (!isFillOrder(tif, td->td_fillorder) &&
-			    (tif->tif_flags & TIFF_NOBITREV) == 0)
-				TIFFReverseBits(tif->tif_rawdata,
-                                                tif->tif_rawdataloaded);
-		}
-	}
-	return (TIFFStartTile(tif, tile));
-}
-
-/*
- * Setup the raw data buffer in preparation for
- * reading a strip of raw data.  If the buffer
- * is specified as zero, then a buffer of appropriate
- * size is allocated by the library.  Otherwise,
- * the client must guarantee that the buffer is
- * large enough to hold any individual strip of
- * raw data.
- */
-int
-TIFFReadBufferSetup(TIFF* tif, void* bp, tmsize_t size)
-{
-	static const char module[] = "TIFFReadBufferSetup";
-
-	assert((tif->tif_flags&TIFF_NOREADRAW)==0);
-	tif->tif_flags &= ~TIFF_BUFFERMMAP;
-
-	if (tif->tif_rawdata) {
-		if (tif->tif_flags & TIFF_MYBUFFER)
-			_TIFFfree(tif->tif_rawdata);
-		tif->tif_rawdata = NULL;
-		tif->tif_rawdatasize = 0;
-	}
-	if (bp) {
-		tif->tif_rawdatasize = size;
-		tif->tif_rawdata = (uint8*) bp;
-		tif->tif_flags &= ~TIFF_MYBUFFER;
-	} else {
-		tif->tif_rawdatasize = (tmsize_t)TIFFroundup_64((uint64)size, 1024);
-		if (tif->tif_rawdatasize==0)
-			tif->tif_rawdatasize=(tmsize_t)(-1);
-		tif->tif_rawdata = (uint8*) _TIFFmalloc(tif->tif_rawdatasize);
-		tif->tif_flags |= TIFF_MYBUFFER;
-	}
-	if (tif->tif_rawdata == NULL) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-		    "No space for data buffer at scanline %lu",
-		    (unsigned long) tif->tif_row);
-		tif->tif_rawdatasize = 0;
-		return (0);
-	}
-	return (1);
-}
-
-/*
- * Set state to appear as if a
- * strip has just been read in.
- */
-static int
-TIFFStartStrip(TIFF* tif, uint32 strip)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-
-    if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
-        return 0;
-
-	if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
-		if (!(*tif->tif_setupdecode)(tif))
-			return (0);
-		tif->tif_flags |= TIFF_CODERSETUP;
-	}
-	tif->tif_curstrip = strip;
-	tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
-        tif->tif_flags &= ~TIFF_BUF4WRITE;
-
-	if (tif->tif_flags&TIFF_NOREADRAW)
-	{
-		tif->tif_rawcp = NULL;
-		tif->tif_rawcc = 0;  
-	}
-	else
-	{
-		tif->tif_rawcp = tif->tif_rawdata;
-		tif->tif_rawcc = (tmsize_t)td->td_stripbytecount[strip];
-	}
-	return ((*tif->tif_predecode)(tif,
-			(uint16)(strip / td->td_stripsperimage)));
-}
-
-/*
- * Set state to appear as if a
- * tile has just been read in.
- */
-static int
-TIFFStartTile(TIFF* tif, uint32 tile)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-
-    if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
-        return 0;
-
-	if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
-		if (!(*tif->tif_setupdecode)(tif))
-			return (0);
-		tif->tif_flags |= TIFF_CODERSETUP;
-	}
-	tif->tif_curtile = tile;
-	tif->tif_row =
-	    (tile % TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth)) *
-		td->td_tilelength;
-	tif->tif_col =
-	    (tile % TIFFhowmany_32(td->td_imagelength, td->td_tilelength)) *
-		td->td_tilewidth;
-        tif->tif_flags &= ~TIFF_BUF4WRITE;
-	if (tif->tif_flags&TIFF_NOREADRAW)
-	{
-		tif->tif_rawcp = NULL;
-		tif->tif_rawcc = 0;
-	}
-	else
-	{
-		tif->tif_rawcp = tif->tif_rawdata;
-		tif->tif_rawcc = (tmsize_t)td->td_stripbytecount[tile];
-	}
-	return ((*tif->tif_predecode)(tif,
-			(uint16)(tile/td->td_stripsperimage)));
-}
-
-static int
-TIFFCheckRead(TIFF* tif, int tiles)
-{
-	if (tif->tif_mode == O_WRONLY) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "File not open for reading");
-		return (0);
-	}
-	if (tiles ^ isTiled(tif)) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name, tiles ?
-		    "Can not read tiles from a stripped image" :
-		    "Can not read scanlines from a tiled image");
-		return (0);
-	}
-	return (1);
-}
-
-void
-_TIFFNoPostDecode(TIFF* tif, uint8* buf, tmsize_t cc)
-{
-    (void) tif; (void) buf; (void) cc;
-}
-
-void
-_TIFFSwab16BitData(TIFF* tif, uint8* buf, tmsize_t cc)
-{
-    (void) tif;
-    assert((cc & 1) == 0);
-    TIFFSwabArrayOfShort((uint16*) buf, cc/2);
-}
-
-void
-_TIFFSwab24BitData(TIFF* tif, uint8* buf, tmsize_t cc)
-{
-    (void) tif;
-    assert((cc % 3) == 0);
-    TIFFSwabArrayOfTriples((uint8*) buf, cc/3);
-}
-
-void
-_TIFFSwab32BitData(TIFF* tif, uint8* buf, tmsize_t cc)
-{
-    (void) tif;
-    assert((cc & 3) == 0);
-    TIFFSwabArrayOfLong((uint32*) buf, cc/4);
-}
-
-void
-_TIFFSwab64BitData(TIFF* tif, uint8* buf, tmsize_t cc)
-{
-    (void) tif;
-    assert((cc & 7) == 0);
-    TIFFSwabArrayOfDouble((double*) buf, cc/8);
-}
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Id: tif_read.c,v 1.11 2015/02/19 22:39:59 drolon Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and 
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
+ * 
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ * Scanline-oriented Read Support
+ */
+#include "tiffiop.h"
+#include <stdio.h>
+
+int TIFFFillStrip(TIFF* tif, uint32 strip);
+int TIFFFillTile(TIFF* tif, uint32 tile);
+static int TIFFStartStrip(TIFF* tif, uint32 strip);
+static int TIFFStartTile(TIFF* tif, uint32 tile);
+static int TIFFCheckRead(TIFF*, int);
+static tmsize_t
+TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size,const char* module);
+
+#define NOSTRIP ((uint32)(-1))       /* undefined state */
+#define NOTILE ((uint32)(-1))         /* undefined state */
+
+static int
+TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart )
+{
+	static const char module[] = "TIFFFillStripPartial";
+	register TIFFDirectory *td = &tif->tif_dir;
+        tmsize_t unused_data;
+        uint64 read_offset;
+        tmsize_t cc, to_read;
+        /* tmsize_t bytecountm; */
+        
+        if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
+            return 0;
+        
+        /*
+         * Expand raw data buffer, if needed, to hold data
+         * strip coming from file (perhaps should set upper
+         * bound on the size of a buffer we'll use?).
+         */
+
+        /* bytecountm=(tmsize_t) td->td_stripbytecount[strip]; */
+        if (read_ahead*2 > tif->tif_rawdatasize) {
+                assert( restart );
+                
+                tif->tif_curstrip = NOSTRIP;
+                if ((tif->tif_flags & TIFF_MYBUFFER) == 0) {
+                        TIFFErrorExt(tif->tif_clientdata, module,
+                                     "Data buffer too small to hold part of strip %lu",
+                                     (unsigned long) strip);
+                        return (0);
+                }
+                if (!TIFFReadBufferSetup(tif, 0, read_ahead*2))
+                        return (0);
+        }
+
+        if( restart )
+        {
+                tif->tif_rawdataloaded = 0;
+                tif->tif_rawdataoff = 0;
+        }
+
+        /*
+        ** If we are reading more data, move any unused data to the
+        ** start of the buffer.
+        */
+        if( tif->tif_rawdataloaded > 0 )
+                unused_data = tif->tif_rawdataloaded - (tif->tif_rawcp - tif->tif_rawdata);
+        else
+                unused_data = 0;
+        
+        if( unused_data > 0 )
+        {
+		assert((tif->tif_flags&TIFF_BUFFERMMAP)==0);
+                memmove( tif->tif_rawdata, tif->tif_rawcp, unused_data );
+        }
+
+        /*
+        ** Seek to the point in the file where more data should be read.
+        */
+        read_offset = td->td_stripoffset[strip]
+                + tif->tif_rawdataoff + tif->tif_rawdataloaded;
+
+        if (!SeekOK(tif, read_offset)) {
+                TIFFErrorExt(tif->tif_clientdata, module,
+                             "Seek error at scanline %lu, strip %lu",
+                             (unsigned long) tif->tif_row, (unsigned long) strip);
+                return 0;
+        }
+
+        /*
+        ** How much do we want to read?
+        */
+        to_read = tif->tif_rawdatasize - unused_data;
+        if( (uint64) to_read > td->td_stripbytecount[strip] 
+            - tif->tif_rawdataoff - tif->tif_rawdataloaded )
+        {
+                to_read = (tmsize_t) td->td_stripbytecount[strip]
+                        - tif->tif_rawdataoff - tif->tif_rawdataloaded;
+        }
+
+	assert((tif->tif_flags&TIFF_BUFFERMMAP)==0);
+        cc = TIFFReadFile(tif, tif->tif_rawdata + unused_data, to_read);
+
+        if (cc != to_read) {
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+                TIFFErrorExt(tif->tif_clientdata, module,
+                             "Read error at scanline %lu; got %I64u bytes, expected %I64u",
+                             (unsigned long) tif->tif_row,
+                             (unsigned __int64) cc,
+                             (unsigned __int64) to_read);
+#else
+                TIFFErrorExt(tif->tif_clientdata, module,
+                             "Read error at scanline %lu; got %llu bytes, expected %llu",
+                             (unsigned long) tif->tif_row,
+                             (unsigned long long) cc,
+                             (unsigned long long) to_read);
+#endif
+                return 0;
+        }
+        
+        tif->tif_rawdataoff = tif->tif_rawdataoff + tif->tif_rawdataloaded - unused_data ;
+        tif->tif_rawdataloaded = unused_data + to_read;
+
+        tif->tif_rawcp = tif->tif_rawdata;
+                        
+        if (!isFillOrder(tif, td->td_fillorder) &&
+            (tif->tif_flags & TIFF_NOBITREV) == 0) {
+		assert((tif->tif_flags&TIFF_BUFFERMMAP)==0);
+                TIFFReverseBits(tif->tif_rawdata + unused_data, to_read );
+	}
+
+        /*
+        ** When starting a strip from the beginning we need to
+        ** restart the decoder.
+        */
+        if( restart )
+                return TIFFStartStrip(tif, strip);
+        else
+                return 1;
+}
+
+/*
+ * Seek to a random row+sample in a file.
+ *
+ * Only used by TIFFReadScanline, and is only used on
+ * strip organized files.  We do some tricky stuff to try
+ * and avoid reading the whole compressed raw data for big
+ * strips.
+ */
+static int
+TIFFSeek(TIFF* tif, uint32 row, uint16 sample )
+{
+	register TIFFDirectory *td = &tif->tif_dir;
+	uint32 strip;
+        int    whole_strip;
+	tmsize_t read_ahead = 0;
+
+        /*
+        ** Establish what strip we are working from.
+        */
+	if (row >= td->td_imagelength) {	/* out of range */
+		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+		    "%lu: Row out of range, max %lu",
+		    (unsigned long) row,
+		    (unsigned long) td->td_imagelength);
+		return (0);
+	}
+	if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
+		if (sample >= td->td_samplesperpixel) {
+			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+			    "%lu: Sample out of range, max %lu",
+			    (unsigned long) sample, (unsigned long) td->td_samplesperpixel);
+			return (0);
+		}
+		strip = (uint32)sample*td->td_stripsperimage + row/td->td_rowsperstrip;
+	} else
+		strip = row / td->td_rowsperstrip;
+
+        /*
+         * Do we want to treat this strip as one whole chunk or
+         * read it a few lines at a time?
+         */
+#if defined(CHUNKY_STRIP_READ_SUPPORT)
+        if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
+            return 0;
+        whole_strip = tif->tif_dir.td_stripbytecount[strip] < 10
+                || isMapped(tif);
+#else
+        whole_strip = 1;
+#endif
+        
+        if( !whole_strip )
+        {
+                read_ahead = tif->tif_scanlinesize * 16 + 5000;
+        }
+
+        /*
+         * If we haven't loaded this strip, do so now, possibly
+         * only reading the first part.
+         */
+	if (strip != tif->tif_curstrip) {	/* different strip, refill */
+                
+                if( whole_strip )
+                {
+                        if (!TIFFFillStrip(tif, strip))
+                                return (0);
+                }
+                else
+                {
+                        if( !TIFFFillStripPartial(tif,strip,read_ahead,1) )
+                                return 0;
+                }
+	}
+
+        /*
+        ** If we already have some data loaded, do we need to read some more?
+        */
+        else if( !whole_strip )
+        {
+                if( ((tif->tif_rawdata + tif->tif_rawdataloaded) - tif->tif_rawcp) < read_ahead 
+                    && (uint64) tif->tif_rawdataoff+tif->tif_rawdataloaded < td->td_stripbytecount[strip] )
+                {
+                        if( !TIFFFillStripPartial(tif,strip,read_ahead,0) )
+                                return 0;
+                }
+        }
+
+        if (row < tif->tif_row) {
+		/*
+		 * Moving backwards within the same strip: backup
+		 * to the start and then decode forward (below).
+		 *
+		 * NB: If you're planning on lots of random access within a
+		 * strip, it's better to just read and decode the entire
+		 * strip, and then access the decoded data in a random fashion.
+		 */
+
+                if( tif->tif_rawdataoff != 0 )
+                {
+                        if( !TIFFFillStripPartial(tif,strip,read_ahead,1) )
+                                return 0;
+                }
+                else
+                {
+                        if (!TIFFStartStrip(tif, strip))
+                                return (0);
+                }
+	}
+        
+	if (row != tif->tif_row) {
+		/*
+		 * Seek forward to the desired row.
+		 */
+
+                /* TODO: Will this really work with partial buffers? */
+                
+		if (!(*tif->tif_seek)(tif, row - tif->tif_row))
+			return (0);
+		tif->tif_row = row;
+	}
+
+	return (1);
+}
+
+int
+TIFFReadScanline(TIFF* tif, void* buf, uint32 row, uint16 sample)
+{
+	int e;
+
+	if (!TIFFCheckRead(tif, 0))
+		return (-1);
+	if( (e = TIFFSeek(tif, row, sample)) != 0) {
+		/*
+		 * Decompress desired row into user buffer.
+		 */
+		e = (*tif->tif_decoderow)
+		    (tif, (uint8*) buf, tif->tif_scanlinesize, sample);  
+
+		/* we are now poised at the beginning of the next row */
+		tif->tif_row = row + 1;
+
+		if (e)
+			(*tif->tif_postdecode)(tif, (uint8*) buf,
+			    tif->tif_scanlinesize);  
+	}
+	return (e > 0 ? 1 : -1);
+}
+
+/*
+ * Read a strip of data and decompress the specified
+ * amount into the user-supplied buffer.
+ */
+tmsize_t
+TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size)
+{
+	static const char module[] = "TIFFReadEncodedStrip";
+	TIFFDirectory *td = &tif->tif_dir;
+	uint32 rowsperstrip;
+	uint32 stripsperplane;
+	uint32 stripinplane;
+	uint16 plane;
+	uint32 rows;
+	tmsize_t stripsize;
+	if (!TIFFCheckRead(tif,0))
+		return((tmsize_t)(-1));
+	if (strip>=td->td_nstrips)
+	{
+		TIFFErrorExt(tif->tif_clientdata,module,
+		    "%lu: Strip out of range, max %lu",(unsigned long)strip,
+		    (unsigned long)td->td_nstrips);
+		return((tmsize_t)(-1));
+	}
+	/*
+	 * Calculate the strip size according to the number of
+	 * rows in the strip (check for truncated last strip on any
+	 * of the separations).
+	 */
+	rowsperstrip=td->td_rowsperstrip;
+	if (rowsperstrip>td->td_imagelength)
+		rowsperstrip=td->td_imagelength;
+	stripsperplane=((td->td_imagelength+rowsperstrip-1)/rowsperstrip);
+	stripinplane=(strip%stripsperplane);
+	plane=(strip/stripsperplane);
+	rows=td->td_imagelength-stripinplane*rowsperstrip;
+	if (rows>rowsperstrip)
+		rows=rowsperstrip;
+	stripsize=TIFFVStripSize(tif,rows);
+	if (stripsize==0)
+		return((tmsize_t)(-1));
+	if ((size!=(tmsize_t)(-1))&&(size<stripsize))
+		stripsize=size;
+	if (!TIFFFillStrip(tif,strip))
+		return((tmsize_t)(-1));
+	if ((*tif->tif_decodestrip)(tif,buf,stripsize,plane)<=0)
+		return((tmsize_t)(-1));
+	(*tif->tif_postdecode)(tif,buf,stripsize);
+	return(stripsize);
+}
+
+static tmsize_t
+TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size,
+    const char* module)
+{
+	TIFFDirectory *td = &tif->tif_dir;
+
+    if (!_TIFFFillStriles( tif ))
+        return ((tmsize_t)(-1));
+        
+	assert((tif->tif_flags&TIFF_NOREADRAW)==0);
+	if (!isMapped(tif)) {
+		tmsize_t cc;
+
+		if (!SeekOK(tif, td->td_stripoffset[strip])) {
+			TIFFErrorExt(tif->tif_clientdata, module,
+			    "Seek error at scanline %lu, strip %lu",
+			    (unsigned long) tif->tif_row, (unsigned long) strip);
+			return ((tmsize_t)(-1));
+		}
+		cc = TIFFReadFile(tif, buf, size);
+		if (cc != size) {
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+			TIFFErrorExt(tif->tif_clientdata, module,
+		"Read error at scanline %lu; got %I64u bytes, expected %I64u",
+				     (unsigned long) tif->tif_row,
+				     (unsigned __int64) cc,
+				     (unsigned __int64) size);
+#else
+			TIFFErrorExt(tif->tif_clientdata, module,
+		"Read error at scanline %lu; got %llu bytes, expected %llu",
+				     (unsigned long) tif->tif_row,
+				     (unsigned long long) cc,
+				     (unsigned long long) size);
+#endif
+			return ((tmsize_t)(-1));
+		}
+	} else {
+		tmsize_t ma,mb;
+		tmsize_t n;
+		ma=(tmsize_t)td->td_stripoffset[strip];
+		mb=ma+size;
+		if (((uint64)ma!=td->td_stripoffset[strip])||(ma>tif->tif_size))
+			n=0;
+		else if ((mb<ma)||(mb<size)||(mb>tif->tif_size))
+			n=tif->tif_size-ma;
+		else
+			n=size;
+		if (n!=size) {
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+			TIFFErrorExt(tif->tif_clientdata, module,
+	"Read error at scanline %lu, strip %lu; got %I64u bytes, expected %I64u",
+				     (unsigned long) tif->tif_row,
+				     (unsigned long) strip,
+				     (unsigned __int64) n,
+				     (unsigned __int64) size);
+#else
+			TIFFErrorExt(tif->tif_clientdata, module,
+	"Read error at scanline %lu, strip %lu; got %llu bytes, expected %llu",
+				     (unsigned long) tif->tif_row,
+				     (unsigned long) strip,
+				     (unsigned long long) n,
+				     (unsigned long long) size);
+#endif
+			return ((tmsize_t)(-1));
+		}
+		_TIFFmemcpy(buf, tif->tif_base + ma,
+			    size);
+	}
+	return (size);
+}
+
+/*
+ * Read a strip of data from the file.
+ */
+tmsize_t
+TIFFReadRawStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size)
+{
+	static const char module[] = "TIFFReadRawStrip";
+	TIFFDirectory *td = &tif->tif_dir;
+	uint64 bytecount;
+	tmsize_t bytecountm;
+
+	if (!TIFFCheckRead(tif, 0))
+		return ((tmsize_t)(-1));
+	if (strip >= td->td_nstrips) {
+		TIFFErrorExt(tif->tif_clientdata, module,
+		     "%lu: Strip out of range, max %lu",
+		     (unsigned long) strip,
+		     (unsigned long) td->td_nstrips);
+		return ((tmsize_t)(-1));
+	}
+	if (tif->tif_flags&TIFF_NOREADRAW)
+	{
+		TIFFErrorExt(tif->tif_clientdata, module,
+		    "Compression scheme does not support access to raw uncompressed data");
+		return ((tmsize_t)(-1));
+	}
+	bytecount = td->td_stripbytecount[strip];
+	if ((int64)bytecount <= 0) {
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+		TIFFErrorExt(tif->tif_clientdata, module,
+			     "%I64u: Invalid strip byte count, strip %lu",
+			     (unsigned __int64) bytecount,
+			     (unsigned long) strip);
+#else
+		TIFFErrorExt(tif->tif_clientdata, module,
+			     "%llu: Invalid strip byte count, strip %lu",
+			     (unsigned long long) bytecount,
+			     (unsigned long) strip);
+#endif
+		return ((tmsize_t)(-1));
+	}
+	bytecountm = (tmsize_t)bytecount;
+	if ((uint64)bytecountm!=bytecount) {
+		TIFFErrorExt(tif->tif_clientdata, module, "Integer overflow");
+		return ((tmsize_t)(-1));
+	}
+	if (size != (tmsize_t)(-1) && size < bytecountm)
+		bytecountm = size;
+	return (TIFFReadRawStrip1(tif, strip, buf, bytecountm, module));
+}
+
+/*
+ * Read the specified strip and setup for decoding. The data buffer is
+ * expanded, as necessary, to hold the strip's data.
+ */
+int
+TIFFFillStrip(TIFF* tif, uint32 strip)
+{
+	static const char module[] = "TIFFFillStrip";
+	TIFFDirectory *td = &tif->tif_dir;
+
+    if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
+        return 0;
+        
+	if ((tif->tif_flags&TIFF_NOREADRAW)==0)
+	{
+		uint64 bytecount = td->td_stripbytecount[strip];
+		if ((int64)bytecount <= 0) {
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+			TIFFErrorExt(tif->tif_clientdata, module,
+				"Invalid strip byte count %I64u, strip %lu",
+				     (unsigned __int64) bytecount,
+				     (unsigned long) strip);
+#else
+			TIFFErrorExt(tif->tif_clientdata, module,
+				"Invalid strip byte count %llu, strip %lu",
+				     (unsigned long long) bytecount,
+				     (unsigned long) strip);
+#endif
+			return (0);
+		}
+		if (isMapped(tif) &&
+		    (isFillOrder(tif, td->td_fillorder)
+		    || (tif->tif_flags & TIFF_NOBITREV))) {
+			/*
+			 * The image is mapped into memory and we either don't
+			 * need to flip bits or the compression routine is
+			 * going to handle this operation itself.  In this
+			 * case, avoid copying the raw data and instead just
+			 * reference the data from the memory mapped file
+			 * image.  This assumes that the decompression
+			 * routines do not modify the contents of the raw data
+			 * buffer (if they try to, the application will get a
+			 * fault since the file is mapped read-only).
+			 */
+			if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
+				_TIFFfree(tif->tif_rawdata);
+				tif->tif_rawdata = NULL;
+				tif->tif_rawdatasize = 0;
+			}
+			tif->tif_flags &= ~TIFF_MYBUFFER;
+			/*
+			 * We must check for overflow, potentially causing
+			 * an OOB read. Instead of simple
+			 *
+			 *  td->td_stripoffset[strip]+bytecount > tif->tif_size
+			 *
+			 * comparison (which can overflow) we do the following
+			 * two comparisons:
+			 */
+			if (bytecount > (uint64)tif->tif_size ||
+			    td->td_stripoffset[strip] > (uint64)tif->tif_size - bytecount) {
+				/*
+				 * This error message might seem strange, but
+				 * it's what would happen if a read were done
+				 * instead.
+				 */
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+				TIFFErrorExt(tif->tif_clientdata, module,
+
+					"Read error on strip %lu; "
+					"got %I64u bytes, expected %I64u",
+					(unsigned long) strip,
+					(unsigned __int64) tif->tif_size - td->td_stripoffset[strip],
+					(unsigned __int64) bytecount);
+#else
+				TIFFErrorExt(tif->tif_clientdata, module,
+
+					"Read error on strip %lu; "
+					"got %llu bytes, expected %llu",
+					(unsigned long) strip,
+					(unsigned long long) tif->tif_size - td->td_stripoffset[strip],
+					(unsigned long long) bytecount);
+#endif
+				tif->tif_curstrip = NOSTRIP;
+				return (0);
+			}
+			tif->tif_rawdatasize = (tmsize_t)bytecount;
+			tif->tif_rawdata = tif->tif_base + (tmsize_t)td->td_stripoffset[strip];
+                        tif->tif_rawdataoff = 0;
+                        tif->tif_rawdataloaded = (tmsize_t) bytecount;
+
+			/* 
+			 * When we have tif_rawdata reference directly into the memory mapped file
+			 * we need to be pretty careful about how we use the rawdata.  It is not
+			 * a general purpose working buffer as it normally otherwise is.  So we
+			 * keep track of this fact to avoid using it improperly.
+			 */
+			tif->tif_flags |= TIFF_BUFFERMMAP;
+		} else {
+			/*
+			 * Expand raw data buffer, if needed, to hold data
+			 * strip coming from file (perhaps should set upper
+			 * bound on the size of a buffer we'll use?).
+			 */
+			tmsize_t bytecountm;
+			bytecountm=(tmsize_t)bytecount;
+			if ((uint64)bytecountm!=bytecount)
+			{
+				TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
+				return(0);
+			}
+			if (bytecountm > tif->tif_rawdatasize) {
+				tif->tif_curstrip = NOSTRIP;
+				if ((tif->tif_flags & TIFF_MYBUFFER) == 0) {
+					TIFFErrorExt(tif->tif_clientdata, module,
+					    "Data buffer too small to hold strip %lu",
+					    (unsigned long) strip);
+					return (0);
+				}
+				if (!TIFFReadBufferSetup(tif, 0, bytecountm))
+					return (0);
+			}
+			if (tif->tif_flags&TIFF_BUFFERMMAP) {
+				tif->tif_curstrip = NOSTRIP;
+				if (!TIFFReadBufferSetup(tif, 0, bytecountm))
+					return (0);
+			}
+			if (TIFFReadRawStrip1(tif, strip, tif->tif_rawdata,
+				bytecountm, module) != bytecountm)
+				return (0);
+
+                        tif->tif_rawdataoff = 0;
+                        tif->tif_rawdataloaded = bytecountm;
+                        
+			if (!isFillOrder(tif, td->td_fillorder) &&
+			    (tif->tif_flags & TIFF_NOBITREV) == 0)
+				TIFFReverseBits(tif->tif_rawdata, bytecountm);
+                }
+	}
+	return (TIFFStartStrip(tif, strip));
+}
+
+/*
+ * Tile-oriented Read Support
+ * Contributed by Nancy Cam (Silicon Graphics).
+ */
+
+/*
+ * Read and decompress a tile of data.  The
+ * tile is selected by the (x,y,z,s) coordinates.
+ */
+tmsize_t
+TIFFReadTile(TIFF* tif, void* buf, uint32 x, uint32 y, uint32 z, uint16 s)
+{
+	if (!TIFFCheckRead(tif, 1) || !TIFFCheckTile(tif, x, y, z, s))
+		return ((tmsize_t)(-1));
+	return (TIFFReadEncodedTile(tif,
+	    TIFFComputeTile(tif, x, y, z, s), buf, (tmsize_t)(-1)));
+}
+
+/*
+ * Read a tile of data and decompress the specified
+ * amount into the user-supplied buffer.
+ */
+tmsize_t
+TIFFReadEncodedTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size)
+{
+	static const char module[] = "TIFFReadEncodedTile";
+	TIFFDirectory *td = &tif->tif_dir;
+	tmsize_t tilesize = tif->tif_tilesize;
+
+	if (!TIFFCheckRead(tif, 1))
+		return ((tmsize_t)(-1));
+	if (tile >= td->td_nstrips) {
+		TIFFErrorExt(tif->tif_clientdata, module,
+		    "%lu: Tile out of range, max %lu",
+		    (unsigned long) tile, (unsigned long) td->td_nstrips);
+		return ((tmsize_t)(-1));
+	}
+	if (size == (tmsize_t)(-1))
+		size = tilesize;
+	else if (size > tilesize)
+		size = tilesize;
+	if (TIFFFillTile(tif, tile) && (*tif->tif_decodetile)(tif,
+	    (uint8*) buf, size, (uint16)(tile/td->td_stripsperimage))) {
+		(*tif->tif_postdecode)(tif, (uint8*) buf, size);
+		return (size);
+	} else
+		return ((tmsize_t)(-1));
+}
+
+static tmsize_t
+TIFFReadRawTile1(TIFF* tif, uint32 tile, void* buf, tmsize_t size, const char* module)
+{
+	TIFFDirectory *td = &tif->tif_dir;
+
+    if (!_TIFFFillStriles( tif ))
+        return ((tmsize_t)(-1));
+
+	assert((tif->tif_flags&TIFF_NOREADRAW)==0);
+	if (!isMapped(tif)) {
+		tmsize_t cc;
+
+		if (!SeekOK(tif, td->td_stripoffset[tile])) {
+			TIFFErrorExt(tif->tif_clientdata, module,
+			    "Seek error at row %lu, col %lu, tile %lu",
+			    (unsigned long) tif->tif_row,
+			    (unsigned long) tif->tif_col,
+			    (unsigned long) tile);
+			return ((tmsize_t)(-1));
+		}
+		cc = TIFFReadFile(tif, buf, size);
+		if (cc != size) {
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+			TIFFErrorExt(tif->tif_clientdata, module,
+	"Read error at row %lu, col %lu; got %I64u bytes, expected %I64u",
+				     (unsigned long) tif->tif_row,
+				     (unsigned long) tif->tif_col,
+				     (unsigned __int64) cc,
+				     (unsigned __int64) size);
+#else
+			TIFFErrorExt(tif->tif_clientdata, module,
+	"Read error at row %lu, col %lu; got %llu bytes, expected %llu",
+				     (unsigned long) tif->tif_row,
+				     (unsigned long) tif->tif_col,
+				     (unsigned long long) cc,
+				     (unsigned long long) size);
+#endif
+			return ((tmsize_t)(-1));
+		}
+	} else {
+		tmsize_t ma,mb;
+		tmsize_t n;
+		ma=(tmsize_t)td->td_stripoffset[tile];
+		mb=ma+size;
+		if (((uint64)ma!=td->td_stripoffset[tile])||(ma>tif->tif_size))
+			n=0;
+		else if ((mb<ma)||(mb<size)||(mb>tif->tif_size))
+			n=tif->tif_size-ma;
+		else
+			n=size;
+		if (n!=size) {
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+			TIFFErrorExt(tif->tif_clientdata, module,
+"Read error at row %lu, col %lu, tile %lu; got %I64u bytes, expected %I64u",
+				     (unsigned long) tif->tif_row,
+				     (unsigned long) tif->tif_col,
+				     (unsigned long) tile,
+				     (unsigned __int64) n,
+				     (unsigned __int64) size);
+#else
+			TIFFErrorExt(tif->tif_clientdata, module,
+"Read error at row %lu, col %lu, tile %lu; got %llu bytes, expected %llu",
+				     (unsigned long) tif->tif_row,
+				     (unsigned long) tif->tif_col,
+				     (unsigned long) tile,
+				     (unsigned long long) n,
+				     (unsigned long long) size);
+#endif
+			return ((tmsize_t)(-1));
+		}
+		_TIFFmemcpy(buf, tif->tif_base + ma, size);
+	}
+	return (size);
+}
+
+/*
+ * Read a tile of data from the file.
+ */
+tmsize_t
+TIFFReadRawTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size)
+{
+	static const char module[] = "TIFFReadRawTile";
+	TIFFDirectory *td = &tif->tif_dir;
+	uint64 bytecount64;
+	tmsize_t bytecountm;
+
+	if (!TIFFCheckRead(tif, 1))
+		return ((tmsize_t)(-1));
+	if (tile >= td->td_nstrips) {
+		TIFFErrorExt(tif->tif_clientdata, module,
+		    "%lu: Tile out of range, max %lu",
+		    (unsigned long) tile, (unsigned long) td->td_nstrips);
+		return ((tmsize_t)(-1));
+	}
+	if (tif->tif_flags&TIFF_NOREADRAW)
+	{
+		TIFFErrorExt(tif->tif_clientdata, module,
+		"Compression scheme does not support access to raw uncompressed data");
+		return ((tmsize_t)(-1));
+	}
+	bytecount64 = td->td_stripbytecount[tile];
+	if (size != (tmsize_t)(-1) && (uint64)size < bytecount64)
+		bytecount64 = (uint64)size;
+	bytecountm = (tmsize_t)bytecount64;
+	if ((uint64)bytecountm!=bytecount64)
+	{
+		TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
+		return ((tmsize_t)(-1));
+	}
+	return (TIFFReadRawTile1(tif, tile, buf, bytecountm, module));
+}
+
+/*
+ * Read the specified tile and setup for decoding. The data buffer is
+ * expanded, as necessary, to hold the tile's data.
+ */
+int
+TIFFFillTile(TIFF* tif, uint32 tile)
+{
+	static const char module[] = "TIFFFillTile";
+	TIFFDirectory *td = &tif->tif_dir;
+
+    if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
+        return 0;
+        
+	if ((tif->tif_flags&TIFF_NOREADRAW)==0)
+	{
+		uint64 bytecount = td->td_stripbytecount[tile];
+		if ((int64)bytecount <= 0) {
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+			TIFFErrorExt(tif->tif_clientdata, module,
+				"%I64u: Invalid tile byte count, tile %lu",
+				     (unsigned __int64) bytecount,
+				     (unsigned long) tile);
+#else
+			TIFFErrorExt(tif->tif_clientdata, module,
+				"%llu: Invalid tile byte count, tile %lu",
+				     (unsigned long long) bytecount,
+				     (unsigned long) tile);
+#endif
+			return (0);
+		}
+		if (isMapped(tif) &&
+		    (isFillOrder(tif, td->td_fillorder)
+		     || (tif->tif_flags & TIFF_NOBITREV))) {
+			/*
+			 * The image is mapped into memory and we either don't
+			 * need to flip bits or the compression routine is
+			 * going to handle this operation itself.  In this
+			 * case, avoid copying the raw data and instead just
+			 * reference the data from the memory mapped file
+			 * image.  This assumes that the decompression
+			 * routines do not modify the contents of the raw data
+			 * buffer (if they try to, the application will get a
+			 * fault since the file is mapped read-only).
+			 */
+			if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
+				_TIFFfree(tif->tif_rawdata);
+				tif->tif_rawdata = NULL;
+				tif->tif_rawdatasize = 0;
+			}
+			tif->tif_flags &= ~TIFF_MYBUFFER;
+			/*
+			 * We must check for overflow, potentially causing
+			 * an OOB read. Instead of simple
+			 *
+			 *  td->td_stripoffset[tile]+bytecount > tif->tif_size
+			 *
+			 * comparison (which can overflow) we do the following
+			 * two comparisons:
+			 */
+			if (bytecount > (uint64)tif->tif_size ||
+			    td->td_stripoffset[tile] > (uint64)tif->tif_size - bytecount) {
+				tif->tif_curtile = NOTILE;
+				return (0);
+			}
+			tif->tif_rawdatasize = (tmsize_t)bytecount;
+			tif->tif_rawdata =
+				tif->tif_base + (tmsize_t)td->td_stripoffset[tile];
+                        tif->tif_rawdataoff = 0;
+                        tif->tif_rawdataloaded = (tmsize_t) bytecount;
+			tif->tif_flags |= TIFF_BUFFERMMAP;
+		} else {
+			/*
+			 * Expand raw data buffer, if needed, to hold data
+			 * tile coming from file (perhaps should set upper
+			 * bound on the size of a buffer we'll use?).
+			 */
+			tmsize_t bytecountm;
+			bytecountm=(tmsize_t)bytecount;
+			if ((uint64)bytecountm!=bytecount)
+			{
+				TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
+				return(0);
+			}
+			if (bytecountm > tif->tif_rawdatasize) {
+				tif->tif_curtile = NOTILE;
+				if ((tif->tif_flags & TIFF_MYBUFFER) == 0) {
+					TIFFErrorExt(tif->tif_clientdata, module,
+					    "Data buffer too small to hold tile %lu",
+					    (unsigned long) tile);
+					return (0);
+				}
+				if (!TIFFReadBufferSetup(tif, 0, bytecountm))
+					return (0);
+			}
+			if (tif->tif_flags&TIFF_BUFFERMMAP) {
+				tif->tif_curtile = NOTILE;
+				if (!TIFFReadBufferSetup(tif, 0, bytecountm))
+					return (0);
+			}
+
+			if (TIFFReadRawTile1(tif, tile, tif->tif_rawdata,
+			    bytecountm, module) != bytecountm)
+				return (0);
+
+                        tif->tif_rawdataoff = 0;
+                        tif->tif_rawdataloaded = bytecountm;
+                        
+			if (!isFillOrder(tif, td->td_fillorder) &&
+			    (tif->tif_flags & TIFF_NOBITREV) == 0)
+				TIFFReverseBits(tif->tif_rawdata,
+                                                tif->tif_rawdataloaded);
+		}
+	}
+	return (TIFFStartTile(tif, tile));
+}
+
+/*
+ * Setup the raw data buffer in preparation for
+ * reading a strip of raw data.  If the buffer
+ * is specified as zero, then a buffer of appropriate
+ * size is allocated by the library.  Otherwise,
+ * the client must guarantee that the buffer is
+ * large enough to hold any individual strip of
+ * raw data.
+ */
+int
+TIFFReadBufferSetup(TIFF* tif, void* bp, tmsize_t size)
+{
+	static const char module[] = "TIFFReadBufferSetup";
+
+	assert((tif->tif_flags&TIFF_NOREADRAW)==0);
+	tif->tif_flags &= ~TIFF_BUFFERMMAP;
+
+	if (tif->tif_rawdata) {
+		if (tif->tif_flags & TIFF_MYBUFFER)
+			_TIFFfree(tif->tif_rawdata);
+		tif->tif_rawdata = NULL;
+		tif->tif_rawdatasize = 0;
+	}
+	if (bp) {
+		tif->tif_rawdatasize = size;
+		tif->tif_rawdata = (uint8*) bp;
+		tif->tif_flags &= ~TIFF_MYBUFFER;
+	} else {
+		tif->tif_rawdatasize = (tmsize_t)TIFFroundup_64((uint64)size, 1024);
+		if (tif->tif_rawdatasize==0) {
+		    TIFFErrorExt(tif->tif_clientdata, module,
+				 "Invalid buffer size");
+		    return (0);
+		}
+		tif->tif_rawdata = (uint8*) _TIFFmalloc(tif->tif_rawdatasize);
+		tif->tif_flags |= TIFF_MYBUFFER;
+	}
+	if (tif->tif_rawdata == NULL) {
+		TIFFErrorExt(tif->tif_clientdata, module,
+		    "No space for data buffer at scanline %lu",
+		    (unsigned long) tif->tif_row);
+		tif->tif_rawdatasize = 0;
+		return (0);
+	}
+	return (1);
+}
+
+/*
+ * Set state to appear as if a
+ * strip has just been read in.
+ */
+static int
+TIFFStartStrip(TIFF* tif, uint32 strip)
+{
+	TIFFDirectory *td = &tif->tif_dir;
+
+    if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
+        return 0;
+
+	if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
+		if (!(*tif->tif_setupdecode)(tif))
+			return (0);
+		tif->tif_flags |= TIFF_CODERSETUP;
+	}
+	tif->tif_curstrip = strip;
+	tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
+        tif->tif_flags &= ~TIFF_BUF4WRITE;
+
+	if (tif->tif_flags&TIFF_NOREADRAW)
+	{
+		tif->tif_rawcp = NULL;
+		tif->tif_rawcc = 0;  
+	}
+	else
+	{
+		tif->tif_rawcp = tif->tif_rawdata;
+		tif->tif_rawcc = (tmsize_t)td->td_stripbytecount[strip];
+	}
+	return ((*tif->tif_predecode)(tif,
+			(uint16)(strip / td->td_stripsperimage)));
+}
+
+/*
+ * Set state to appear as if a
+ * tile has just been read in.
+ */
+static int
+TIFFStartTile(TIFF* tif, uint32 tile)
+{
+	TIFFDirectory *td = &tif->tif_dir;
+
+    if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
+        return 0;
+
+	if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
+		if (!(*tif->tif_setupdecode)(tif))
+			return (0);
+		tif->tif_flags |= TIFF_CODERSETUP;
+	}
+	tif->tif_curtile = tile;
+	tif->tif_row =
+	    (tile % TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth)) *
+		td->td_tilelength;
+	tif->tif_col =
+	    (tile % TIFFhowmany_32(td->td_imagelength, td->td_tilelength)) *
+		td->td_tilewidth;
+        tif->tif_flags &= ~TIFF_BUF4WRITE;
+	if (tif->tif_flags&TIFF_NOREADRAW)
+	{
+		tif->tif_rawcp = NULL;
+		tif->tif_rawcc = 0;
+	}
+	else
+	{
+		tif->tif_rawcp = tif->tif_rawdata;
+		tif->tif_rawcc = (tmsize_t)td->td_stripbytecount[tile];
+	}
+	return ((*tif->tif_predecode)(tif,
+			(uint16)(tile/td->td_stripsperimage)));
+}
+
+static int
+TIFFCheckRead(TIFF* tif, int tiles)
+{
+	if (tif->tif_mode == O_WRONLY) {
+		TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "File not open for reading");
+		return (0);
+	}
+	if (tiles ^ isTiled(tif)) {
+		TIFFErrorExt(tif->tif_clientdata, tif->tif_name, tiles ?
+		    "Can not read tiles from a stripped image" :
+		    "Can not read scanlines from a tiled image");
+		return (0);
+	}
+	return (1);
+}
+
+void
+_TIFFNoPostDecode(TIFF* tif, uint8* buf, tmsize_t cc)
+{
+    (void) tif; (void) buf; (void) cc;
+}
+
+void
+_TIFFSwab16BitData(TIFF* tif, uint8* buf, tmsize_t cc)
+{
+    (void) tif;
+    assert((cc & 1) == 0);
+    TIFFSwabArrayOfShort((uint16*) buf, cc/2);
+}
+
+void
+_TIFFSwab24BitData(TIFF* tif, uint8* buf, tmsize_t cc)
+{
+    (void) tif;
+    assert((cc % 3) == 0);
+    TIFFSwabArrayOfTriples((uint8*) buf, cc/3);
+}
+
+void
+_TIFFSwab32BitData(TIFF* tif, uint8* buf, tmsize_t cc)
+{
+    (void) tif;
+    assert((cc & 3) == 0);
+    TIFFSwabArrayOfLong((uint32*) buf, cc/4);
+}
+
+void
+_TIFFSwab64BitData(TIFF* tif, uint8* buf, tmsize_t cc)
+{
+    (void) tif;
+    assert((cc & 7) == 0);
+    TIFFSwabArrayOfDouble((double*) buf, cc/8);
+}
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tif_stream.cxx b/Source/LibTIFF4/tif_stream.cxx
index 20d47d7..42f25d6 100644
--- a/Source/LibTIFF4/tif_stream.cxx
+++ b/Source/LibTIFF4/tif_stream.cxx
@@ -1,4 +1,4 @@
-/* $Id: tif_stream.cxx,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
+/* $Id: tif_stream.cxx,v 1.11 2015/02/19 22:39:59 drolon Exp $ */
 
 /*
  * Copyright (c) 1988-1996 Sam Leffler
@@ -340,12 +340,16 @@ _tiffisCloseProc(thandle_t fd)
 static int
 _tiffDummyMapProc(thandle_t , void** base, toff_t* size )
 {
+	(void) base;
+	(void) size;
 	return (0);
 }
 
 static void
 _tiffDummyUnmapProc(thandle_t , void* base, toff_t size )
 {
+	(void) base;
+	(void) size;
 }
 
 /*
diff --git a/Source/LibTIFF4/tif_strip.c b/Source/LibTIFF4/tif_strip.c
index e214d79..9309f5b 100644
--- a/Source/LibTIFF4/tif_strip.c
+++ b/Source/LibTIFF4/tif_strip.c
@@ -1,383 +1,383 @@
-/* $Id: tif_strip.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * Copyright (c) 1991-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library.
- *
- * Strip-organized Image Support Routines.
- */
-#include "tiffiop.h"
-
-/*
- * Compute which strip a (row,sample) value is in.
- */
-uint32
-TIFFComputeStrip(TIFF* tif, uint32 row, uint16 sample)
-{
-	static const char module[] = "TIFFComputeStrip";
-	TIFFDirectory *td = &tif->tif_dir;
-	uint32 strip;
-
-	strip = row / td->td_rowsperstrip;
-	if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
-		if (sample >= td->td_samplesperpixel) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-			    "%lu: Sample out of range, max %lu",
-			    (unsigned long) sample, (unsigned long) td->td_samplesperpixel);
-			return (0);
-		}
-		strip += (uint32)sample*td->td_stripsperimage;
-	}
-	return (strip);
-}
-
-/*
- * Compute how many strips are in an image.
- */
-uint32
-TIFFNumberOfStrips(TIFF* tif)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-	uint32 nstrips;
-
-	nstrips = (td->td_rowsperstrip == (uint32) -1 ? 1 :
-	     TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip));
-	if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
-		nstrips = _TIFFMultiply32(tif, nstrips, (uint32)td->td_samplesperpixel,
-		    "TIFFNumberOfStrips");
-	return (nstrips);
-}
-
-/*
- * Compute the # bytes in a variable height, row-aligned strip.
- */
-uint64
-TIFFVStripSize64(TIFF* tif, uint32 nrows)
-{
-	static const char module[] = "TIFFVStripSize64";
-	TIFFDirectory *td = &tif->tif_dir;
-	if (nrows==(uint32)(-1))
-		nrows=td->td_imagelength;
-	if ((td->td_planarconfig==PLANARCONFIG_CONTIG)&&
-	    (td->td_photometric == PHOTOMETRIC_YCBCR)&&
-	    (!isUpSampled(tif)))
-	{
-		/*
-		 * Packed YCbCr data contain one Cb+Cr for every
-		 * HorizontalSampling*VerticalSampling Y values.
-		 * Must also roundup width and height when calculating
-		 * since images that are not a multiple of the
-		 * horizontal/vertical subsampling area include
-		 * YCbCr data for the extended image.
-		 */
-		uint16 ycbcrsubsampling[2];
-		uint16 samplingblock_samples;
-		uint32 samplingblocks_hor;
-		uint32 samplingblocks_ver;
-		uint64 samplingrow_samples;
-		uint64 samplingrow_size;
-		if(td->td_samplesperpixel!=3)
-		{
-			TIFFErrorExt(tif->tif_clientdata,module,
-			    "Invalid td_samplesperpixel value");
-			return 0;
-		}
-		TIFFGetFieldDefaulted(tif,TIFFTAG_YCBCRSUBSAMPLING,ycbcrsubsampling+0,
-		    ycbcrsubsampling+1);
-		if ((ycbcrsubsampling[0] != 1 && ycbcrsubsampling[0] != 2 && ycbcrsubsampling[0] != 4)
-		    ||(ycbcrsubsampling[1] != 1 && ycbcrsubsampling[1] != 2 && ycbcrsubsampling[1] != 4))
-		{
-			TIFFErrorExt(tif->tif_clientdata,module,
-				     "Invalid YCbCr subsampling (%dx%d)", 
-				     ycbcrsubsampling[0], 
-				     ycbcrsubsampling[1] );
-			return 0;
-		}
-		samplingblock_samples=ycbcrsubsampling[0]*ycbcrsubsampling[1]+2;
-		samplingblocks_hor=TIFFhowmany_32(td->td_imagewidth,ycbcrsubsampling[0]);
-		samplingblocks_ver=TIFFhowmany_32(nrows,ycbcrsubsampling[1]);
-		samplingrow_samples=_TIFFMultiply64(tif,samplingblocks_hor,samplingblock_samples,module);
-		samplingrow_size=TIFFhowmany8_64(_TIFFMultiply64(tif,samplingrow_samples,td->td_bitspersample,module));
-		return(_TIFFMultiply64(tif,samplingrow_size,samplingblocks_ver,module));
-	}
-	else
-		return(_TIFFMultiply64(tif,nrows,TIFFScanlineSize64(tif),module));
-}
-tmsize_t
-TIFFVStripSize(TIFF* tif, uint32 nrows)
-{
-	static const char module[] = "TIFFVStripSize";
-	uint64 m;
-	tmsize_t n;
-	m=TIFFVStripSize64(tif,nrows);
-	n=(tmsize_t)m;
-	if ((uint64)n!=m)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
-		n=0;
-	}
-	return(n);
-}
-
-/*
- * Compute the # bytes in a raw strip.
- */
-uint64
-TIFFRawStripSize64(TIFF* tif, uint32 strip)
-{
-	static const char module[] = "TIFFRawStripSize64";
-	TIFFDirectory* td = &tif->tif_dir;
-	uint64 bytecount = td->td_stripbytecount[strip];
-
-	if (bytecount == 0)
-	{
-#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
-		TIFFErrorExt(tif->tif_clientdata, module,
-			     "%I64u: Invalid strip byte count, strip %lu",
-			     (unsigned __int64) bytecount,
-			     (unsigned long) strip);
-#else
-		TIFFErrorExt(tif->tif_clientdata, module,
-			     "%llu: Invalid strip byte count, strip %lu",
-			     (unsigned long long) bytecount,
-			     (unsigned long) strip);
-#endif
-		bytecount = (uint64) -1;
-	}
-
-	return bytecount;
-}
-tmsize_t
-TIFFRawStripSize(TIFF* tif, uint32 strip)
-{
-	static const char module[] = "TIFFRawStripSize";
-	uint64 m;
-	tmsize_t n;
-	m=TIFFRawStripSize64(tif,strip);
-	if (m==(uint64)(-1))
-		n=(tmsize_t)(-1);
-	else
-	{
-		n=(tmsize_t)m;
-		if ((uint64)n!=m)
-		{
-			TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
-			n=0;
-		}
-	}
-	return(n);
-}
-
-/*
- * Compute the # bytes in a (row-aligned) strip.
- *
- * Note that if RowsPerStrip is larger than the
- * recorded ImageLength, then the strip size is
- * truncated to reflect the actual space required
- * to hold the strip.
- */
-uint64
-TIFFStripSize64(TIFF* tif)
-{
-	TIFFDirectory* td = &tif->tif_dir;
-	uint32 rps = td->td_rowsperstrip;
-	if (rps > td->td_imagelength)
-		rps = td->td_imagelength;
-	return (TIFFVStripSize64(tif, rps));
-}
-tmsize_t
-TIFFStripSize(TIFF* tif)
-{
-	static const char module[] = "TIFFStripSize";
-	uint64 m;
-	tmsize_t n;
-	m=TIFFStripSize64(tif);
-	n=(tmsize_t)m;
-	if ((uint64)n!=m)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
-		n=0;
-	}
-	return(n);
-}
-
-/*
- * Compute a default strip size based on the image
- * characteristics and a requested value.  If the
- * request is <1 then we choose a strip size according
- * to certain heuristics.
- */
-uint32
-TIFFDefaultStripSize(TIFF* tif, uint32 request)
-{
-	return (*tif->tif_defstripsize)(tif, request);
-}
-
-uint32
-_TIFFDefaultStripSize(TIFF* tif, uint32 s)
-{
-	if ((int32) s < 1) {
-		/*
-		 * If RowsPerStrip is unspecified, try to break the
-		 * image up into strips that are approximately
-		 * STRIP_SIZE_DEFAULT bytes long.
-		 */
-		uint64 scanlinesize;
-		uint64 rows;
-		scanlinesize=TIFFScanlineSize64(tif);
-		if (scanlinesize==0)
-			scanlinesize=1;
-		rows=(uint64)STRIP_SIZE_DEFAULT/scanlinesize;
-		if (rows==0)
-			rows=1;
-		else if (rows>0xFFFFFFFF)
-			rows=0xFFFFFFFF;
-		s=(uint32)rows;
-	}
-	return (s);
-}
-
-/*
- * Return the number of bytes to read/write in a call to
- * one of the scanline-oriented i/o routines.  Note that
- * this number may be 1/samples-per-pixel if data is
- * stored as separate planes.
- * The ScanlineSize in case of YCbCrSubsampling is defined as the
- * strip size divided by the strip height, i.e. the size of a pack of vertical
- * subsampling lines divided by vertical subsampling. It should thus make
- * sense when multiplied by a multiple of vertical subsampling.
- */
-uint64
-TIFFScanlineSize64(TIFF* tif)
-{
-	static const char module[] = "TIFFScanlineSize64";
-	TIFFDirectory *td = &tif->tif_dir;
-	uint64 scanline_size;
-	if (td->td_planarconfig==PLANARCONFIG_CONTIG)
-	{
-		if ((td->td_photometric==PHOTOMETRIC_YCBCR)&&
-		    (td->td_samplesperpixel==3)&&
-		    (!isUpSampled(tif)))
-		{
-			uint16 ycbcrsubsampling[2];
-			uint16 samplingblock_samples;
-			uint32 samplingblocks_hor;
-			uint64 samplingrow_samples;
-			uint64 samplingrow_size;
-			if(td->td_samplesperpixel!=3)
-			{
-                            TIFFErrorExt(tif->tif_clientdata,module,
-                                         "Invalid td_samplesperpixel value");
-                            return 0;
-			}
-			TIFFGetFieldDefaulted(tif,TIFFTAG_YCBCRSUBSAMPLING,
-                                              ycbcrsubsampling+0,
-                                              ycbcrsubsampling+1);
-			if (((ycbcrsubsampling[0]!=1)&&(ycbcrsubsampling[0]!=2)&&(ycbcrsubsampling[0]!=4)) ||
-			    ((ycbcrsubsampling[1]!=1)&&(ycbcrsubsampling[1]!=2)&&(ycbcrsubsampling[1]!=4)))
-			{
-                            TIFFErrorExt(tif->tif_clientdata,module,
-                                         "Invalid YCbCr subsampling");
-                            return 0;
-			}
-			samplingblock_samples = ycbcrsubsampling[0]*ycbcrsubsampling[1]+2;
-			samplingblocks_hor = TIFFhowmany_32(td->td_imagewidth,ycbcrsubsampling[0]);
-			samplingrow_samples = _TIFFMultiply64(tif,samplingblocks_hor,samplingblock_samples,module);
-			samplingrow_size = TIFFhowmany_64(_TIFFMultiply64(tif,samplingrow_samples,td->td_bitspersample,module),8);
-			scanline_size = (samplingrow_size/ycbcrsubsampling[1]);
-		}
-		else
-		{
-			uint64 scanline_samples;
-			scanline_samples=_TIFFMultiply64(tif,td->td_imagewidth,td->td_samplesperpixel,module);
-			scanline_size=TIFFhowmany_64(_TIFFMultiply64(tif,scanline_samples,td->td_bitspersample,module),8);
-		}
-	}
-	else
-		scanline_size=TIFFhowmany_64(_TIFFMultiply64(tif,td->td_imagewidth,td->td_bitspersample,module),8);
-	return(scanline_size);
-}
-tmsize_t
-TIFFScanlineSize(TIFF* tif)
-{
-	static const char module[] = "TIFFScanlineSize";
-	uint64 m;
-	tmsize_t n;
-	m=TIFFScanlineSize64(tif);
-	n=(tmsize_t)m;
-	if ((uint64)n!=m)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Integer arithmetic overflow");
-		n=0;
-	}
-	return(n);
-}
-
-/*
- * Return the number of bytes required to store a complete
- * decoded and packed raster scanline (as opposed to the
- * I/O size returned by TIFFScanlineSize which may be less
- * if data is store as separate planes).
- */
-uint64
-TIFFRasterScanlineSize64(TIFF* tif)
-{
-	static const char module[] = "TIFFRasterScanlineSize64";
-	TIFFDirectory *td = &tif->tif_dir;
-	uint64 scanline;
-
-	scanline = _TIFFMultiply64(tif, td->td_bitspersample, td->td_imagewidth, module);
-	if (td->td_planarconfig == PLANARCONFIG_CONTIG) {
-		scanline = _TIFFMultiply64(tif, scanline, td->td_samplesperpixel, module);
-		return (TIFFhowmany8_64(scanline));
-	} else
-		return (_TIFFMultiply64(tif, TIFFhowmany8_64(scanline),
-		    td->td_samplesperpixel, module));
-}
-tmsize_t
-TIFFRasterScanlineSize(TIFF* tif)
-{
-	static const char module[] = "TIFFRasterScanlineSize";
-	uint64 m;
-	tmsize_t n;
-	m=TIFFRasterScanlineSize64(tif);
-	n=(tmsize_t)m;
-	if ((uint64)n!=m)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Integer arithmetic overflow");
-		n=0;
-	}
-	return(n);
-}
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Id: tif_strip.c,v 1.11 2015/02/19 22:39:59 drolon Exp $ */
+
+/*
+ * Copyright (c) 1991-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and 
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
+ * 
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Strip-organized Image Support Routines.
+ */
+#include "tiffiop.h"
+
+/*
+ * Compute which strip a (row,sample) value is in.
+ */
+uint32
+TIFFComputeStrip(TIFF* tif, uint32 row, uint16 sample)
+{
+	static const char module[] = "TIFFComputeStrip";
+	TIFFDirectory *td = &tif->tif_dir;
+	uint32 strip;
+
+	strip = row / td->td_rowsperstrip;
+	if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
+		if (sample >= td->td_samplesperpixel) {
+			TIFFErrorExt(tif->tif_clientdata, module,
+			    "%lu: Sample out of range, max %lu",
+			    (unsigned long) sample, (unsigned long) td->td_samplesperpixel);
+			return (0);
+		}
+		strip += (uint32)sample*td->td_stripsperimage;
+	}
+	return (strip);
+}
+
+/*
+ * Compute how many strips are in an image.
+ */
+uint32
+TIFFNumberOfStrips(TIFF* tif)
+{
+	TIFFDirectory *td = &tif->tif_dir;
+	uint32 nstrips;
+
+	nstrips = (td->td_rowsperstrip == (uint32) -1 ? 1 :
+	     TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip));
+	if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
+		nstrips = _TIFFMultiply32(tif, nstrips, (uint32)td->td_samplesperpixel,
+		    "TIFFNumberOfStrips");
+	return (nstrips);
+}
+
+/*
+ * Compute the # bytes in a variable height, row-aligned strip.
+ */
+uint64
+TIFFVStripSize64(TIFF* tif, uint32 nrows)
+{
+	static const char module[] = "TIFFVStripSize64";
+	TIFFDirectory *td = &tif->tif_dir;
+	if (nrows==(uint32)(-1))
+		nrows=td->td_imagelength;
+	if ((td->td_planarconfig==PLANARCONFIG_CONTIG)&&
+	    (td->td_photometric == PHOTOMETRIC_YCBCR)&&
+	    (!isUpSampled(tif)))
+	{
+		/*
+		 * Packed YCbCr data contain one Cb+Cr for every
+		 * HorizontalSampling*VerticalSampling Y values.
+		 * Must also roundup width and height when calculating
+		 * since images that are not a multiple of the
+		 * horizontal/vertical subsampling area include
+		 * YCbCr data for the extended image.
+		 */
+		uint16 ycbcrsubsampling[2];
+		uint16 samplingblock_samples;
+		uint32 samplingblocks_hor;
+		uint32 samplingblocks_ver;
+		uint64 samplingrow_samples;
+		uint64 samplingrow_size;
+		if(td->td_samplesperpixel!=3)
+		{
+			TIFFErrorExt(tif->tif_clientdata,module,
+			    "Invalid td_samplesperpixel value");
+			return 0;
+		}
+		TIFFGetFieldDefaulted(tif,TIFFTAG_YCBCRSUBSAMPLING,ycbcrsubsampling+0,
+		    ycbcrsubsampling+1);
+		if ((ycbcrsubsampling[0] != 1 && ycbcrsubsampling[0] != 2 && ycbcrsubsampling[0] != 4)
+		    ||(ycbcrsubsampling[1] != 1 && ycbcrsubsampling[1] != 2 && ycbcrsubsampling[1] != 4))
+		{
+			TIFFErrorExt(tif->tif_clientdata,module,
+				     "Invalid YCbCr subsampling (%dx%d)", 
+				     ycbcrsubsampling[0], 
+				     ycbcrsubsampling[1] );
+			return 0;
+		}
+		samplingblock_samples=ycbcrsubsampling[0]*ycbcrsubsampling[1]+2;
+		samplingblocks_hor=TIFFhowmany_32(td->td_imagewidth,ycbcrsubsampling[0]);
+		samplingblocks_ver=TIFFhowmany_32(nrows,ycbcrsubsampling[1]);
+		samplingrow_samples=_TIFFMultiply64(tif,samplingblocks_hor,samplingblock_samples,module);
+		samplingrow_size=TIFFhowmany8_64(_TIFFMultiply64(tif,samplingrow_samples,td->td_bitspersample,module));
+		return(_TIFFMultiply64(tif,samplingrow_size,samplingblocks_ver,module));
+	}
+	else
+		return(_TIFFMultiply64(tif,nrows,TIFFScanlineSize64(tif),module));
+}
+tmsize_t
+TIFFVStripSize(TIFF* tif, uint32 nrows)
+{
+	static const char module[] = "TIFFVStripSize";
+	uint64 m;
+	tmsize_t n;
+	m=TIFFVStripSize64(tif,nrows);
+	n=(tmsize_t)m;
+	if ((uint64)n!=m)
+	{
+		TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
+		n=0;
+	}
+	return(n);
+}
+
+/*
+ * Compute the # bytes in a raw strip.
+ */
+uint64
+TIFFRawStripSize64(TIFF* tif, uint32 strip)
+{
+	static const char module[] = "TIFFRawStripSize64";
+	TIFFDirectory* td = &tif->tif_dir;
+	uint64 bytecount = td->td_stripbytecount[strip];
+
+	if (bytecount == 0)
+	{
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+		TIFFErrorExt(tif->tif_clientdata, module,
+			     "%I64u: Invalid strip byte count, strip %lu",
+			     (unsigned __int64) bytecount,
+			     (unsigned long) strip);
+#else
+		TIFFErrorExt(tif->tif_clientdata, module,
+			     "%llu: Invalid strip byte count, strip %lu",
+			     (unsigned long long) bytecount,
+			     (unsigned long) strip);
+#endif
+		bytecount = (uint64) -1;
+	}
+
+	return bytecount;
+}
+tmsize_t
+TIFFRawStripSize(TIFF* tif, uint32 strip)
+{
+	static const char module[] = "TIFFRawStripSize";
+	uint64 m;
+	tmsize_t n;
+	m=TIFFRawStripSize64(tif,strip);
+	if (m==(uint64)(-1))
+		n=(tmsize_t)(-1);
+	else
+	{
+		n=(tmsize_t)m;
+		if ((uint64)n!=m)
+		{
+			TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
+			n=0;
+		}
+	}
+	return(n);
+}
+
+/*
+ * Compute the # bytes in a (row-aligned) strip.
+ *
+ * Note that if RowsPerStrip is larger than the
+ * recorded ImageLength, then the strip size is
+ * truncated to reflect the actual space required
+ * to hold the strip.
+ */
+uint64
+TIFFStripSize64(TIFF* tif)
+{
+	TIFFDirectory* td = &tif->tif_dir;
+	uint32 rps = td->td_rowsperstrip;
+	if (rps > td->td_imagelength)
+		rps = td->td_imagelength;
+	return (TIFFVStripSize64(tif, rps));
+}
+tmsize_t
+TIFFStripSize(TIFF* tif)
+{
+	static const char module[] = "TIFFStripSize";
+	uint64 m;
+	tmsize_t n;
+	m=TIFFStripSize64(tif);
+	n=(tmsize_t)m;
+	if ((uint64)n!=m)
+	{
+		TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
+		n=0;
+	}
+	return(n);
+}
+
+/*
+ * Compute a default strip size based on the image
+ * characteristics and a requested value.  If the
+ * request is <1 then we choose a strip size according
+ * to certain heuristics.
+ */
+uint32
+TIFFDefaultStripSize(TIFF* tif, uint32 request)
+{
+	return (*tif->tif_defstripsize)(tif, request);
+}
+
+uint32
+_TIFFDefaultStripSize(TIFF* tif, uint32 s)
+{
+	if ((int32) s < 1) {
+		/*
+		 * If RowsPerStrip is unspecified, try to break the
+		 * image up into strips that are approximately
+		 * STRIP_SIZE_DEFAULT bytes long.
+		 */
+		uint64 scanlinesize;
+		uint64 rows;
+		scanlinesize=TIFFScanlineSize64(tif);
+		if (scanlinesize==0)
+			scanlinesize=1;
+		rows=(uint64)STRIP_SIZE_DEFAULT/scanlinesize;
+		if (rows==0)
+			rows=1;
+		else if (rows>0xFFFFFFFF)
+			rows=0xFFFFFFFF;
+		s=(uint32)rows;
+	}
+	return (s);
+}
+
+/*
+ * Return the number of bytes to read/write in a call to
+ * one of the scanline-oriented i/o routines.  Note that
+ * this number may be 1/samples-per-pixel if data is
+ * stored as separate planes.
+ * The ScanlineSize in case of YCbCrSubsampling is defined as the
+ * strip size divided by the strip height, i.e. the size of a pack of vertical
+ * subsampling lines divided by vertical subsampling. It should thus make
+ * sense when multiplied by a multiple of vertical subsampling.
+ */
+uint64
+TIFFScanlineSize64(TIFF* tif)
+{
+	static const char module[] = "TIFFScanlineSize64";
+	TIFFDirectory *td = &tif->tif_dir;
+	uint64 scanline_size;
+	if (td->td_planarconfig==PLANARCONFIG_CONTIG)
+	{
+		if ((td->td_photometric==PHOTOMETRIC_YCBCR)&&
+		    (td->td_samplesperpixel==3)&&
+		    (!isUpSampled(tif)))
+		{
+			uint16 ycbcrsubsampling[2];
+			uint16 samplingblock_samples;
+			uint32 samplingblocks_hor;
+			uint64 samplingrow_samples;
+			uint64 samplingrow_size;
+			if(td->td_samplesperpixel!=3)
+			{
+                            TIFFErrorExt(tif->tif_clientdata,module,
+                                         "Invalid td_samplesperpixel value");
+                            return 0;
+			}
+			TIFFGetFieldDefaulted(tif,TIFFTAG_YCBCRSUBSAMPLING,
+                                              ycbcrsubsampling+0,
+                                              ycbcrsubsampling+1);
+			if (((ycbcrsubsampling[0]!=1)&&(ycbcrsubsampling[0]!=2)&&(ycbcrsubsampling[0]!=4)) ||
+			    ((ycbcrsubsampling[1]!=1)&&(ycbcrsubsampling[1]!=2)&&(ycbcrsubsampling[1]!=4)))
+			{
+                            TIFFErrorExt(tif->tif_clientdata,module,
+                                         "Invalid YCbCr subsampling");
+                            return 0;
+			}
+			samplingblock_samples = ycbcrsubsampling[0]*ycbcrsubsampling[1]+2;
+			samplingblocks_hor = TIFFhowmany_32(td->td_imagewidth,ycbcrsubsampling[0]);
+			samplingrow_samples = _TIFFMultiply64(tif,samplingblocks_hor,samplingblock_samples,module);
+			samplingrow_size = TIFFhowmany_64(_TIFFMultiply64(tif,samplingrow_samples,td->td_bitspersample,module),8);
+			scanline_size = (samplingrow_size/ycbcrsubsampling[1]);
+		}
+		else
+		{
+			uint64 scanline_samples;
+			scanline_samples=_TIFFMultiply64(tif,td->td_imagewidth,td->td_samplesperpixel,module);
+			scanline_size=TIFFhowmany_64(_TIFFMultiply64(tif,scanline_samples,td->td_bitspersample,module),8);
+		}
+	}
+	else
+		scanline_size=TIFFhowmany_64(_TIFFMultiply64(tif,td->td_imagewidth,td->td_bitspersample,module),8);
+	return(scanline_size);
+}
+tmsize_t
+TIFFScanlineSize(TIFF* tif)
+{
+	static const char module[] = "TIFFScanlineSize";
+	uint64 m;
+	tmsize_t n;
+	m=TIFFScanlineSize64(tif);
+	n=(tmsize_t)m;
+	if ((uint64)n!=m)
+	{
+		TIFFErrorExt(tif->tif_clientdata,module,"Integer arithmetic overflow");
+		n=0;
+	}
+	return(n);
+}
+
+/*
+ * Return the number of bytes required to store a complete
+ * decoded and packed raster scanline (as opposed to the
+ * I/O size returned by TIFFScanlineSize which may be less
+ * if data is store as separate planes).
+ */
+uint64
+TIFFRasterScanlineSize64(TIFF* tif)
+{
+	static const char module[] = "TIFFRasterScanlineSize64";
+	TIFFDirectory *td = &tif->tif_dir;
+	uint64 scanline;
+
+	scanline = _TIFFMultiply64(tif, td->td_bitspersample, td->td_imagewidth, module);
+	if (td->td_planarconfig == PLANARCONFIG_CONTIG) {
+		scanline = _TIFFMultiply64(tif, scanline, td->td_samplesperpixel, module);
+		return (TIFFhowmany8_64(scanline));
+	} else
+		return (_TIFFMultiply64(tif, TIFFhowmany8_64(scanline),
+		    td->td_samplesperpixel, module));
+}
+tmsize_t
+TIFFRasterScanlineSize(TIFF* tif)
+{
+	static const char module[] = "TIFFRasterScanlineSize";
+	uint64 m;
+	tmsize_t n;
+	m=TIFFRasterScanlineSize64(tif);
+	n=(tmsize_t)m;
+	if ((uint64)n!=m)
+	{
+		TIFFErrorExt(tif->tif_clientdata,module,"Integer arithmetic overflow");
+		n=0;
+	}
+	return(n);
+}
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tif_swab.c b/Source/LibTIFF4/tif_swab.c
index 29125f1..844e0a1 100644
--- a/Source/LibTIFF4/tif_swab.c
+++ b/Source/LibTIFF4/tif_swab.c
@@ -1,310 +1,310 @@
-/* $Id: tif_swab.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library Bit & Byte Swapping Support.
- *
- * XXX We assume short = 16-bits and long = 32-bits XXX
- */
-#include "tiffiop.h"
-
-#ifndef TIFFSwabShort
-void
-TIFFSwabShort(uint16* wp)
-{
-	register unsigned char* cp = (unsigned char*) wp;
-	unsigned char t;
-	assert(sizeof(uint16)==2);
-	t = cp[1]; cp[1] = cp[0]; cp[0] = t;
-}
-#endif
-
-#ifndef TIFFSwabLong
-void
-TIFFSwabLong(uint32* lp)
-{
-	register unsigned char* cp = (unsigned char*) lp;
-	unsigned char t;
-	assert(sizeof(uint32)==4);
-	t = cp[3]; cp[3] = cp[0]; cp[0] = t;
-	t = cp[2]; cp[2] = cp[1]; cp[1] = t;
-}
-#endif
-
-#ifndef TIFFSwabLong8
-void
-TIFFSwabLong8(uint64* lp)
-{
-	register unsigned char* cp = (unsigned char*) lp;
-	unsigned char t;
-	assert(sizeof(uint64)==8);
-	t = cp[7]; cp[7] = cp[0]; cp[0] = t;
-	t = cp[6]; cp[6] = cp[1]; cp[1] = t;
-	t = cp[5]; cp[5] = cp[2]; cp[2] = t;
-	t = cp[4]; cp[4] = cp[3]; cp[3] = t;
-}
-#endif
-
-#ifndef TIFFSwabArrayOfShort
-void
-TIFFSwabArrayOfShort(register uint16* wp, tmsize_t n)
-{
-	register unsigned char* cp;
-	register unsigned char t;
-	assert(sizeof(uint16)==2);
-	/* XXX unroll loop some */
-	while (n-- > 0) {
-		cp = (unsigned char*) wp;
-		t = cp[1]; cp[1] = cp[0]; cp[0] = t;
-		wp++;
-	}
-}
-#endif
-
-#ifndef TIFFSwabArrayOfTriples
-void
-TIFFSwabArrayOfTriples(register uint8* tp, tmsize_t n)
-{
-	unsigned char* cp;
-	unsigned char t;
-
-	/* XXX unroll loop some */
-	while (n-- > 0) {
-		cp = (unsigned char*) tp;
-		t = cp[2]; cp[2] = cp[0]; cp[0] = t;
-		tp += 3;
-	}
-}
-#endif
-
-#ifndef TIFFSwabArrayOfLong
-void
-TIFFSwabArrayOfLong(register uint32* lp, tmsize_t n)
-{
-	register unsigned char *cp;
-	register unsigned char t;
-	assert(sizeof(uint32)==4);
-	/* XXX unroll loop some */
-	while (n-- > 0) {
-		cp = (unsigned char *)lp;
-		t = cp[3]; cp[3] = cp[0]; cp[0] = t;
-		t = cp[2]; cp[2] = cp[1]; cp[1] = t;
-		lp++;
-	}
-}
-#endif
-
-#ifndef TIFFSwabArrayOfLong8
-void
-TIFFSwabArrayOfLong8(register uint64* lp, tmsize_t n)
-{
-	register unsigned char *cp;
-	register unsigned char t;
-	assert(sizeof(uint64)==8);
-	/* XXX unroll loop some */
-	while (n-- > 0) {
-		cp = (unsigned char *)lp;
-		t = cp[7]; cp[7] = cp[0]; cp[0] = t;
-		t = cp[6]; cp[6] = cp[1]; cp[1] = t;
-		t = cp[5]; cp[5] = cp[2]; cp[2] = t;
-		t = cp[4]; cp[4] = cp[3]; cp[3] = t;
-		lp++;
-	}
-}
-#endif
-
-#ifndef TIFFSwabFloat
-void
-TIFFSwabFloat(float* fp)
-{
-	register unsigned char* cp = (unsigned char*) fp;
-	unsigned char t;
-	assert(sizeof(float)==4);
-	t = cp[3]; cp[3] = cp[0]; cp[0] = t;
-	t = cp[2]; cp[2] = cp[1]; cp[1] = t;
-}
-#endif
-
-#ifndef TIFFSwabArrayOfFloat
-void
-TIFFSwabArrayOfFloat(register float* fp, tmsize_t n)
-{
-	register unsigned char *cp;
-	register unsigned char t;
-	assert(sizeof(float)==4);
-	/* XXX unroll loop some */
-	while (n-- > 0) {
-		cp = (unsigned char *)fp;
-		t = cp[3]; cp[3] = cp[0]; cp[0] = t;
-		t = cp[2]; cp[2] = cp[1]; cp[1] = t;
-		fp++;
-	}
-}
-#endif
-
-#ifndef TIFFSwabDouble
-void
-TIFFSwabDouble(double *dp)
-{
-	register unsigned char* cp = (unsigned char*) dp;
-	unsigned char t;
-	assert(sizeof(double)==8);
-	t = cp[7]; cp[7] = cp[0]; cp[0] = t;
-	t = cp[6]; cp[6] = cp[1]; cp[1] = t;
-	t = cp[5]; cp[5] = cp[2]; cp[2] = t;
-	t = cp[4]; cp[4] = cp[3]; cp[3] = t;
-}
-#endif
-
-#ifndef TIFFSwabArrayOfDouble
-void
-TIFFSwabArrayOfDouble(double* dp, tmsize_t n)
-{
-	register unsigned char *cp;
-	register unsigned char t;
-	assert(sizeof(double)==8);
-	/* XXX unroll loop some */
-	while (n-- > 0) {
-		cp = (unsigned char *)dp;
-		t = cp[7]; cp[7] = cp[0]; cp[0] = t;
-		t = cp[6]; cp[6] = cp[1]; cp[1] = t;
-		t = cp[5]; cp[5] = cp[2]; cp[2] = t;
-		t = cp[4]; cp[4] = cp[3]; cp[3] = t;
-		dp++;
-	}
-}
-#endif
-
-/*
- * Bit reversal tables.  TIFFBitRevTable[<byte>] gives
- * the bit reversed value of <byte>.  Used in various
- * places in the library when the FillOrder requires
- * bit reversal of byte values (e.g. CCITT Fax 3
- * encoding/decoding).  TIFFNoBitRevTable is provided
- * for algorithms that want an equivalent table that
- * do not reverse bit values.
- */
-static const unsigned char TIFFBitRevTable[256] = {
-    0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
-    0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
-    0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
-    0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
-    0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
-    0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
-    0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
-    0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
-    0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
-    0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
-    0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
-    0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
-    0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
-    0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
-    0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
-    0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
-    0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
-    0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
-    0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
-    0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
-    0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
-    0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
-    0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
-    0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
-    0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
-    0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
-    0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
-    0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
-    0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
-    0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
-    0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
-    0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
-};
-static const unsigned char TIFFNoBitRevTable[256] = {
-    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
-    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 
-    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 
-    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 
-    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 
-    0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 
-    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 
-    0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 
-    0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 
-    0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 
-    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 
-    0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 
-    0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 
-    0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 
-    0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 
-    0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 
-    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 
-    0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 
-    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 
-    0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 
-    0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 
-    0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 
-    0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 
-    0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 
-    0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 
-    0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 
-    0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 
-    0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 
-    0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 
-    0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 
-    0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 
-    0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, 
-};
-
-const unsigned char*
-TIFFGetBitRevTable(int reversed)
-{
-	return (reversed ? TIFFBitRevTable : TIFFNoBitRevTable);
-}
-
-void
-TIFFReverseBits(uint8* cp, tmsize_t n)  
-{
-	for (; n > 8; n -= 8) {
-		cp[0] = TIFFBitRevTable[cp[0]];
-		cp[1] = TIFFBitRevTable[cp[1]];
-		cp[2] = TIFFBitRevTable[cp[2]];
-		cp[3] = TIFFBitRevTable[cp[3]];
-		cp[4] = TIFFBitRevTable[cp[4]];
-		cp[5] = TIFFBitRevTable[cp[5]];
-		cp[6] = TIFFBitRevTable[cp[6]];
-		cp[7] = TIFFBitRevTable[cp[7]];
-		cp += 8;
-	}
-	while (n-- > 0)
-		*cp = TIFFBitRevTable[*cp], cp++;
-}
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Id: tif_swab.c,v 1.11 2015/02/19 22:39:59 drolon Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and 
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
+ * 
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library Bit & Byte Swapping Support.
+ *
+ * XXX We assume short = 16-bits and long = 32-bits XXX
+ */
+#include "tiffiop.h"
+
+#ifndef TIFFSwabShort
+void
+TIFFSwabShort(uint16* wp)
+{
+	register unsigned char* cp = (unsigned char*) wp;
+	unsigned char t;
+	assert(sizeof(uint16)==2);
+	t = cp[1]; cp[1] = cp[0]; cp[0] = t;
+}
+#endif
+
+#ifndef TIFFSwabLong
+void
+TIFFSwabLong(uint32* lp)
+{
+	register unsigned char* cp = (unsigned char*) lp;
+	unsigned char t;
+	assert(sizeof(uint32)==4);
+	t = cp[3]; cp[3] = cp[0]; cp[0] = t;
+	t = cp[2]; cp[2] = cp[1]; cp[1] = t;
+}
+#endif
+
+#ifndef TIFFSwabLong8
+void
+TIFFSwabLong8(uint64* lp)
+{
+	register unsigned char* cp = (unsigned char*) lp;
+	unsigned char t;
+	assert(sizeof(uint64)==8);
+	t = cp[7]; cp[7] = cp[0]; cp[0] = t;
+	t = cp[6]; cp[6] = cp[1]; cp[1] = t;
+	t = cp[5]; cp[5] = cp[2]; cp[2] = t;
+	t = cp[4]; cp[4] = cp[3]; cp[3] = t;
+}
+#endif
+
+#ifndef TIFFSwabArrayOfShort
+void
+TIFFSwabArrayOfShort(register uint16* wp, tmsize_t n)
+{
+	register unsigned char* cp;
+	register unsigned char t;
+	assert(sizeof(uint16)==2);
+	/* XXX unroll loop some */
+	while (n-- > 0) {
+		cp = (unsigned char*) wp;
+		t = cp[1]; cp[1] = cp[0]; cp[0] = t;
+		wp++;
+	}
+}
+#endif
+
+#ifndef TIFFSwabArrayOfTriples
+void
+TIFFSwabArrayOfTriples(register uint8* tp, tmsize_t n)
+{
+	unsigned char* cp;
+	unsigned char t;
+
+	/* XXX unroll loop some */
+	while (n-- > 0) {
+		cp = (unsigned char*) tp;
+		t = cp[2]; cp[2] = cp[0]; cp[0] = t;
+		tp += 3;
+	}
+}
+#endif
+
+#ifndef TIFFSwabArrayOfLong
+void
+TIFFSwabArrayOfLong(register uint32* lp, tmsize_t n)
+{
+	register unsigned char *cp;
+	register unsigned char t;
+	assert(sizeof(uint32)==4);
+	/* XXX unroll loop some */
+	while (n-- > 0) {
+		cp = (unsigned char *)lp;
+		t = cp[3]; cp[3] = cp[0]; cp[0] = t;
+		t = cp[2]; cp[2] = cp[1]; cp[1] = t;
+		lp++;
+	}
+}
+#endif
+
+#ifndef TIFFSwabArrayOfLong8
+void
+TIFFSwabArrayOfLong8(register uint64* lp, tmsize_t n)
+{
+	register unsigned char *cp;
+	register unsigned char t;
+	assert(sizeof(uint64)==8);
+	/* XXX unroll loop some */
+	while (n-- > 0) {
+		cp = (unsigned char *)lp;
+		t = cp[7]; cp[7] = cp[0]; cp[0] = t;
+		t = cp[6]; cp[6] = cp[1]; cp[1] = t;
+		t = cp[5]; cp[5] = cp[2]; cp[2] = t;
+		t = cp[4]; cp[4] = cp[3]; cp[3] = t;
+		lp++;
+	}
+}
+#endif
+
+#ifndef TIFFSwabFloat
+void
+TIFFSwabFloat(float* fp)
+{
+	register unsigned char* cp = (unsigned char*) fp;
+	unsigned char t;
+	assert(sizeof(float)==4);
+	t = cp[3]; cp[3] = cp[0]; cp[0] = t;
+	t = cp[2]; cp[2] = cp[1]; cp[1] = t;
+}
+#endif
+
+#ifndef TIFFSwabArrayOfFloat
+void
+TIFFSwabArrayOfFloat(register float* fp, tmsize_t n)
+{
+	register unsigned char *cp;
+	register unsigned char t;
+	assert(sizeof(float)==4);
+	/* XXX unroll loop some */
+	while (n-- > 0) {
+		cp = (unsigned char *)fp;
+		t = cp[3]; cp[3] = cp[0]; cp[0] = t;
+		t = cp[2]; cp[2] = cp[1]; cp[1] = t;
+		fp++;
+	}
+}
+#endif
+
+#ifndef TIFFSwabDouble
+void
+TIFFSwabDouble(double *dp)
+{
+	register unsigned char* cp = (unsigned char*) dp;
+	unsigned char t;
+	assert(sizeof(double)==8);
+	t = cp[7]; cp[7] = cp[0]; cp[0] = t;
+	t = cp[6]; cp[6] = cp[1]; cp[1] = t;
+	t = cp[5]; cp[5] = cp[2]; cp[2] = t;
+	t = cp[4]; cp[4] = cp[3]; cp[3] = t;
+}
+#endif
+
+#ifndef TIFFSwabArrayOfDouble
+void
+TIFFSwabArrayOfDouble(double* dp, tmsize_t n)
+{
+	register unsigned char *cp;
+	register unsigned char t;
+	assert(sizeof(double)==8);
+	/* XXX unroll loop some */
+	while (n-- > 0) {
+		cp = (unsigned char *)dp;
+		t = cp[7]; cp[7] = cp[0]; cp[0] = t;
+		t = cp[6]; cp[6] = cp[1]; cp[1] = t;
+		t = cp[5]; cp[5] = cp[2]; cp[2] = t;
+		t = cp[4]; cp[4] = cp[3]; cp[3] = t;
+		dp++;
+	}
+}
+#endif
+
+/*
+ * Bit reversal tables.  TIFFBitRevTable[<byte>] gives
+ * the bit reversed value of <byte>.  Used in various
+ * places in the library when the FillOrder requires
+ * bit reversal of byte values (e.g. CCITT Fax 3
+ * encoding/decoding).  TIFFNoBitRevTable is provided
+ * for algorithms that want an equivalent table that
+ * do not reverse bit values.
+ */
+static const unsigned char TIFFBitRevTable[256] = {
+    0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
+    0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
+    0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
+    0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
+    0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
+    0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
+    0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
+    0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
+    0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
+    0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
+    0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
+    0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
+    0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
+    0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
+    0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
+    0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
+    0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
+    0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
+    0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
+    0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
+    0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
+    0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
+    0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
+    0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
+    0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
+    0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
+    0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
+    0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
+    0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
+    0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
+    0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
+    0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
+};
+static const unsigned char TIFFNoBitRevTable[256] = {
+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
+    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 
+    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 
+    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 
+    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 
+    0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 
+    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 
+    0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 
+    0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 
+    0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 
+    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 
+    0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 
+    0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 
+    0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 
+    0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 
+    0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 
+    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 
+    0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 
+    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 
+    0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 
+    0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 
+    0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 
+    0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 
+    0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 
+    0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 
+    0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 
+    0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 
+    0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 
+    0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 
+    0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 
+    0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 
+    0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, 
+};
+
+const unsigned char*
+TIFFGetBitRevTable(int reversed)
+{
+	return (reversed ? TIFFBitRevTable : TIFFNoBitRevTable);
+}
+
+void
+TIFFReverseBits(uint8* cp, tmsize_t n)  
+{
+	for (; n > 8; n -= 8) {
+		cp[0] = TIFFBitRevTable[cp[0]];
+		cp[1] = TIFFBitRevTable[cp[1]];
+		cp[2] = TIFFBitRevTable[cp[2]];
+		cp[3] = TIFFBitRevTable[cp[3]];
+		cp[4] = TIFFBitRevTable[cp[4]];
+		cp[5] = TIFFBitRevTable[cp[5]];
+		cp[6] = TIFFBitRevTable[cp[6]];
+		cp[7] = TIFFBitRevTable[cp[7]];
+		cp += 8;
+	}
+	while (n-- > 0)
+		*cp = TIFFBitRevTable[*cp], cp++;
+}
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tif_thunder.c b/Source/LibTIFF4/tif_thunder.c
index 3d0d6f9..4ee5269 100644
--- a/Source/LibTIFF4/tif_thunder.c
+++ b/Source/LibTIFF4/tif_thunder.c
@@ -1,207 +1,207 @@
-/* $Id: tif_thunder.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-#include "tiffiop.h"
-#include <assert.h>
-#ifdef THUNDER_SUPPORT
-/*
- * TIFF Library.
- *
- * ThunderScan 4-bit Compression Algorithm Support
- */
-
-/*
- * ThunderScan uses an encoding scheme designed for
- * 4-bit pixel values.  Data is encoded in bytes, with
- * each byte split into a 2-bit code word and a 6-bit
- * data value.  The encoding gives raw data, runs of
- * pixels, or pixel values encoded as a delta from the
- * previous pixel value.  For the latter, either 2-bit
- * or 3-bit delta values are used, with the deltas packed
- * into a single byte.
- */
-#define	THUNDER_DATA		0x3f	/* mask for 6-bit data */
-#define	THUNDER_CODE		0xc0	/* mask for 2-bit code word */
-/* code values */
-#define	THUNDER_RUN		0x00	/* run of pixels w/ encoded count */
-#define	THUNDER_2BITDELTAS	0x40	/* 3 pixels w/ encoded 2-bit deltas */
-#define	    DELTA2_SKIP		2	/* skip code for 2-bit deltas */
-#define	THUNDER_3BITDELTAS	0x80	/* 2 pixels w/ encoded 3-bit deltas */
-#define	    DELTA3_SKIP		4	/* skip code for 3-bit deltas */
-#define	THUNDER_RAW		0xc0	/* raw data encoded */
-
-static const int twobitdeltas[4] = { 0, 1, 0, -1 };
-static const int threebitdeltas[8] = { 0, 1, 2, 3, 0, -3, -2, -1 };
-
-#define	SETPIXEL(op, v) {                     \
-	lastpixel = (v) & 0xf;                \
-        if ( npixels < maxpixels )         \
-        {                                     \
-	  if (npixels++ & 1)                  \
-	    *op++ |= lastpixel;               \
-	  else                                \
-	    op[0] = (uint8) (lastpixel << 4); \
-        }                                     \
-}
-
-static int
-ThunderSetupDecode(TIFF* tif)
-{
-	static const char module[] = "ThunderSetupDecode";
-
-        if( tif->tif_dir.td_bitspersample != 4 )
-        {
-                TIFFErrorExt(tif->tif_clientdata, module,
-                             "Wrong bitspersample value (%d), Thunder decoder only supports 4bits per sample.",
-                             (int) tif->tif_dir.td_bitspersample );
-                return 0;
-        }
-        
-
-	return (1);
-}
-
-static int
-ThunderDecode(TIFF* tif, uint8* op, tmsize_t maxpixels)
-{
-	static const char module[] = "ThunderDecode";
-	register unsigned char *bp;
-	register tmsize_t cc;
-	unsigned int lastpixel;
-	tmsize_t npixels;
-
-	bp = (unsigned char *)tif->tif_rawcp;
-	cc = tif->tif_rawcc;
-	lastpixel = 0;
-	npixels = 0;
-	while (cc > 0 && npixels < maxpixels) {
-		int n, delta;
-
-		n = *bp++, cc--;
-		switch (n & THUNDER_CODE) {
-		case THUNDER_RUN:		/* pixel run */
-			/*
-			 * Replicate the last pixel n times,
-			 * where n is the lower-order 6 bits.
-			 */
-			if (npixels & 1) {
-				op[0] |= lastpixel;
-				lastpixel = *op++; npixels++; n--;
-			} else
-				lastpixel |= lastpixel << 4;
-			npixels += n;
-			if (npixels < maxpixels) {
-				for (; n > 0; n -= 2)
-					*op++ = (uint8) lastpixel;
-			}
-			if (n == -1)
-				*--op &= 0xf0;
-			lastpixel &= 0xf;
-			break;
-		case THUNDER_2BITDELTAS:	/* 2-bit deltas */
-			if ((delta = ((n >> 4) & 3)) != DELTA2_SKIP)
-				SETPIXEL(op, lastpixel + twobitdeltas[delta]);
-			if ((delta = ((n >> 2) & 3)) != DELTA2_SKIP)
-				SETPIXEL(op, lastpixel + twobitdeltas[delta]);
-			if ((delta = (n & 3)) != DELTA2_SKIP)
-				SETPIXEL(op, lastpixel + twobitdeltas[delta]);
-			break;
-		case THUNDER_3BITDELTAS:	/* 3-bit deltas */
-			if ((delta = ((n >> 3) & 7)) != DELTA3_SKIP)
-				SETPIXEL(op, lastpixel + threebitdeltas[delta]);
-			if ((delta = (n & 7)) != DELTA3_SKIP)
-				SETPIXEL(op, lastpixel + threebitdeltas[delta]);
-			break;
-		case THUNDER_RAW:		/* raw data */
-			SETPIXEL(op, n);
-			break;
-		}
-	}
-	tif->tif_rawcp = (uint8*) bp;
-	tif->tif_rawcc = cc;
-	if (npixels != maxpixels) {
-#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
-		TIFFErrorExt(tif->tif_clientdata, module,
-			     "%s data at scanline %lu (%I64u != %I64u)",
-			     npixels < maxpixels ? "Not enough" : "Too much",
-			     (unsigned long) tif->tif_row,
-			     (unsigned __int64) npixels,
-			     (unsigned __int64) maxpixels);
-#else
-		TIFFErrorExt(tif->tif_clientdata, module,
-			     "%s data at scanline %lu (%llu != %llu)",
-			     npixels < maxpixels ? "Not enough" : "Too much",
-			     (unsigned long) tif->tif_row,
-			     (unsigned long long) npixels,
-			     (unsigned long long) maxpixels);
-#endif
-		return (0);
-	}
-
-        return (1);
-}
-
-static int
-ThunderDecodeRow(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s)
-{
-	static const char module[] = "ThunderDecodeRow";
-	uint8* row = buf;
-	
-	(void) s;
-	if (occ % tif->tif_scanlinesize)
-	{
-		TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read");
-		return (0);
-	}
-	while (occ > 0) {
-		if (!ThunderDecode(tif, row, tif->tif_dir.td_imagewidth))
-			return (0);
-		occ -= tif->tif_scanlinesize;
-		row += tif->tif_scanlinesize;
-	}
-	return (1);
-}
-
-int
-TIFFInitThunderScan(TIFF* tif, int scheme)
-{
-	(void) scheme;
-
-        tif->tif_setupdecode = ThunderSetupDecode;
-	tif->tif_decoderow = ThunderDecodeRow;
-	tif->tif_decodestrip = ThunderDecodeRow; 
-	return (1);
-}
-#endif /* THUNDER_SUPPORT */
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Id: tif_thunder.c,v 1.11 2015/02/19 22:39:59 drolon Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and 
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
+ * 
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
+ * OF THIS SOFTWARE.
+ */
+
+#include "tiffiop.h"
+#include <assert.h>
+#ifdef THUNDER_SUPPORT
+/*
+ * TIFF Library.
+ *
+ * ThunderScan 4-bit Compression Algorithm Support
+ */
+
+/*
+ * ThunderScan uses an encoding scheme designed for
+ * 4-bit pixel values.  Data is encoded in bytes, with
+ * each byte split into a 2-bit code word and a 6-bit
+ * data value.  The encoding gives raw data, runs of
+ * pixels, or pixel values encoded as a delta from the
+ * previous pixel value.  For the latter, either 2-bit
+ * or 3-bit delta values are used, with the deltas packed
+ * into a single byte.
+ */
+#define	THUNDER_DATA		0x3f	/* mask for 6-bit data */
+#define	THUNDER_CODE		0xc0	/* mask for 2-bit code word */
+/* code values */
+#define	THUNDER_RUN		0x00	/* run of pixels w/ encoded count */
+#define	THUNDER_2BITDELTAS	0x40	/* 3 pixels w/ encoded 2-bit deltas */
+#define	    DELTA2_SKIP		2	/* skip code for 2-bit deltas */
+#define	THUNDER_3BITDELTAS	0x80	/* 2 pixels w/ encoded 3-bit deltas */
+#define	    DELTA3_SKIP		4	/* skip code for 3-bit deltas */
+#define	THUNDER_RAW		0xc0	/* raw data encoded */
+
+static const int twobitdeltas[4] = { 0, 1, 0, -1 };
+static const int threebitdeltas[8] = { 0, 1, 2, 3, 0, -3, -2, -1 };
+
+#define	SETPIXEL(op, v) {                     \
+	lastpixel = (v) & 0xf;                \
+        if ( npixels < maxpixels )         \
+        {                                     \
+	  if (npixels++ & 1)                  \
+	    *op++ |= lastpixel;               \
+	  else                                \
+	    op[0] = (uint8) (lastpixel << 4); \
+        }                                     \
+}
+
+static int
+ThunderSetupDecode(TIFF* tif)
+{
+	static const char module[] = "ThunderSetupDecode";
+
+        if( tif->tif_dir.td_bitspersample != 4 )
+        {
+                TIFFErrorExt(tif->tif_clientdata, module,
+                             "Wrong bitspersample value (%d), Thunder decoder only supports 4bits per sample.",
+                             (int) tif->tif_dir.td_bitspersample );
+                return 0;
+        }
+        
+
+	return (1);
+}
+
+static int
+ThunderDecode(TIFF* tif, uint8* op, tmsize_t maxpixels)
+{
+	static const char module[] = "ThunderDecode";
+	register unsigned char *bp;
+	register tmsize_t cc;
+	unsigned int lastpixel;
+	tmsize_t npixels;
+
+	bp = (unsigned char *)tif->tif_rawcp;
+	cc = tif->tif_rawcc;
+	lastpixel = 0;
+	npixels = 0;
+	while (cc > 0 && npixels < maxpixels) {
+		int n, delta;
+
+		n = *bp++, cc--;
+		switch (n & THUNDER_CODE) {
+		case THUNDER_RUN:		/* pixel run */
+			/*
+			 * Replicate the last pixel n times,
+			 * where n is the lower-order 6 bits.
+			 */
+			if (npixels & 1) {
+				op[0] |= lastpixel;
+				lastpixel = *op++; npixels++; n--;
+			} else
+				lastpixel |= lastpixel << 4;
+			npixels += n;
+			if (npixels < maxpixels) {
+				for (; n > 0; n -= 2)
+					*op++ = (uint8) lastpixel;
+			}
+			if (n == -1)
+				*--op &= 0xf0;
+			lastpixel &= 0xf;
+			break;
+		case THUNDER_2BITDELTAS:	/* 2-bit deltas */
+			if ((delta = ((n >> 4) & 3)) != DELTA2_SKIP)
+				SETPIXEL(op, lastpixel + twobitdeltas[delta]);
+			if ((delta = ((n >> 2) & 3)) != DELTA2_SKIP)
+				SETPIXEL(op, lastpixel + twobitdeltas[delta]);
+			if ((delta = (n & 3)) != DELTA2_SKIP)
+				SETPIXEL(op, lastpixel + twobitdeltas[delta]);
+			break;
+		case THUNDER_3BITDELTAS:	/* 3-bit deltas */
+			if ((delta = ((n >> 3) & 7)) != DELTA3_SKIP)
+				SETPIXEL(op, lastpixel + threebitdeltas[delta]);
+			if ((delta = (n & 7)) != DELTA3_SKIP)
+				SETPIXEL(op, lastpixel + threebitdeltas[delta]);
+			break;
+		case THUNDER_RAW:		/* raw data */
+			SETPIXEL(op, n);
+			break;
+		}
+	}
+	tif->tif_rawcp = (uint8*) bp;
+	tif->tif_rawcc = cc;
+	if (npixels != maxpixels) {
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+		TIFFErrorExt(tif->tif_clientdata, module,
+			     "%s data at scanline %lu (%I64u != %I64u)",
+			     npixels < maxpixels ? "Not enough" : "Too much",
+			     (unsigned long) tif->tif_row,
+			     (unsigned __int64) npixels,
+			     (unsigned __int64) maxpixels);
+#else
+		TIFFErrorExt(tif->tif_clientdata, module,
+			     "%s data at scanline %lu (%llu != %llu)",
+			     npixels < maxpixels ? "Not enough" : "Too much",
+			     (unsigned long) tif->tif_row,
+			     (unsigned long long) npixels,
+			     (unsigned long long) maxpixels);
+#endif
+		return (0);
+	}
+
+        return (1);
+}
+
+static int
+ThunderDecodeRow(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s)
+{
+	static const char module[] = "ThunderDecodeRow";
+	uint8* row = buf;
+	
+	(void) s;
+	if (occ % tif->tif_scanlinesize)
+	{
+		TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read");
+		return (0);
+	}
+	while (occ > 0) {
+		if (!ThunderDecode(tif, row, tif->tif_dir.td_imagewidth))
+			return (0);
+		occ -= tif->tif_scanlinesize;
+		row += tif->tif_scanlinesize;
+	}
+	return (1);
+}
+
+int
+TIFFInitThunderScan(TIFF* tif, int scheme)
+{
+	(void) scheme;
+
+        tif->tif_setupdecode = ThunderSetupDecode;
+	tif->tif_decoderow = ThunderDecodeRow;
+	tif->tif_decodestrip = ThunderDecodeRow; 
+	return (1);
+}
+#endif /* THUNDER_SUPPORT */
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tif_tile.c b/Source/LibTIFF4/tif_tile.c
index 18f0a71..2739ea3 100644
--- a/Source/LibTIFF4/tif_tile.c
+++ b/Source/LibTIFF4/tif_tile.c
@@ -1,299 +1,299 @@
-/* $Id: tif_tile.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * Copyright (c) 1991-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library.
- *
- * Tiled Image Support Routines.
- */
-#include "tiffiop.h"
-
-/*
- * Compute which tile an (x,y,z,s) value is in.
- */
-uint32
-TIFFComputeTile(TIFF* tif, uint32 x, uint32 y, uint32 z, uint16 s)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-	uint32 dx = td->td_tilewidth;
-	uint32 dy = td->td_tilelength;
-	uint32 dz = td->td_tiledepth;
-	uint32 tile = 1;
-
-	if (td->td_imagedepth == 1)
-		z = 0;
-	if (dx == (uint32) -1)
-		dx = td->td_imagewidth;
-	if (dy == (uint32) -1)
-		dy = td->td_imagelength;
-	if (dz == (uint32) -1)
-		dz = td->td_imagedepth;
-	if (dx != 0 && dy != 0 && dz != 0) {
-		uint32 xpt = TIFFhowmany_32(td->td_imagewidth, dx);
-		uint32 ypt = TIFFhowmany_32(td->td_imagelength, dy);
-		uint32 zpt = TIFFhowmany_32(td->td_imagedepth, dz);
-
-		if (td->td_planarconfig == PLANARCONFIG_SEPARATE) 
-			tile = (xpt*ypt*zpt)*s +
-			     (xpt*ypt)*(z/dz) +
-			     xpt*(y/dy) +
-			     x/dx;
-		else
-			tile = (xpt*ypt)*(z/dz) + xpt*(y/dy) + x/dx;
-	}
-	return (tile);
-}
-
-/*
- * Check an (x,y,z,s) coordinate
- * against the image bounds.
- */
-int
-TIFFCheckTile(TIFF* tif, uint32 x, uint32 y, uint32 z, uint16 s)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-
-	if (x >= td->td_imagewidth) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			     "%lu: Col out of range, max %lu",
-			     (unsigned long) x,
-			     (unsigned long) (td->td_imagewidth - 1));
-		return (0);
-	}
-	if (y >= td->td_imagelength) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			     "%lu: Row out of range, max %lu",
-			     (unsigned long) y,
-			     (unsigned long) (td->td_imagelength - 1));
-		return (0);
-	}
-	if (z >= td->td_imagedepth) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			     "%lu: Depth out of range, max %lu",
-			     (unsigned long) z,
-			     (unsigned long) (td->td_imagedepth - 1));
-		return (0);
-	}
-	if (td->td_planarconfig == PLANARCONFIG_SEPARATE &&
-	    s >= td->td_samplesperpixel) {
-		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-			     "%lu: Sample out of range, max %lu",
-			     (unsigned long) s,
-			     (unsigned long) (td->td_samplesperpixel - 1));
-		return (0);
-	}
-	return (1);
-}
-
-/*
- * Compute how many tiles are in an image.
- */
-uint32
-TIFFNumberOfTiles(TIFF* tif)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-	uint32 dx = td->td_tilewidth;
-	uint32 dy = td->td_tilelength;
-	uint32 dz = td->td_tiledepth;
-	uint32 ntiles;
-
-	if (dx == (uint32) -1)
-		dx = td->td_imagewidth;
-	if (dy == (uint32) -1)
-		dy = td->td_imagelength;
-	if (dz == (uint32) -1)
-		dz = td->td_imagedepth;
-	ntiles = (dx == 0 || dy == 0 || dz == 0) ? 0 :
-	    _TIFFMultiply32(tif, _TIFFMultiply32(tif, TIFFhowmany_32(td->td_imagewidth, dx),
-	    TIFFhowmany_32(td->td_imagelength, dy),
-	    "TIFFNumberOfTiles"),
-	    TIFFhowmany_32(td->td_imagedepth, dz), "TIFFNumberOfTiles");
-	if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
-		ntiles = _TIFFMultiply32(tif, ntiles, td->td_samplesperpixel,
-		    "TIFFNumberOfTiles");
-	return (ntiles);
-}
-
-/*
- * Compute the # bytes in each row of a tile.
- */
-uint64
-TIFFTileRowSize64(TIFF* tif)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-	uint64 rowsize;
-
-	if (td->td_tilelength == 0 || td->td_tilewidth == 0)
-		return (0);
-	rowsize = _TIFFMultiply64(tif, td->td_bitspersample, td->td_tilewidth,
-	    "TIFFTileRowSize");
-	if (td->td_planarconfig == PLANARCONFIG_CONTIG)
-		rowsize = _TIFFMultiply64(tif, rowsize, td->td_samplesperpixel,
-		    "TIFFTileRowSize");
-	return (TIFFhowmany8_64(rowsize));
-}
-tmsize_t
-TIFFTileRowSize(TIFF* tif)
-{
-	static const char module[] = "TIFFTileRowSize";
-	uint64 m;
-	tmsize_t n;
-	m=TIFFTileRowSize64(tif);
-	n=(tmsize_t)m;
-	if ((uint64)n!=m)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
-		n=0;
-	}
-	return(n);
-}
-
-/*
- * Compute the # bytes in a variable length, row-aligned tile.
- */
-uint64
-TIFFVTileSize64(TIFF* tif, uint32 nrows)
-{
-	static const char module[] = "TIFFVTileSize64";
-	TIFFDirectory *td = &tif->tif_dir;
-	if (td->td_tilelength == 0 || td->td_tilewidth == 0 ||
-	    td->td_tiledepth == 0)
-		return (0);
-	if ((td->td_planarconfig==PLANARCONFIG_CONTIG)&&
-	    (td->td_photometric==PHOTOMETRIC_YCBCR)&&
-	    (td->td_samplesperpixel==3)&&
-	    (!isUpSampled(tif)))
-	{
-		/*
-		 * Packed YCbCr data contain one Cb+Cr for every
-		 * HorizontalSampling*VerticalSampling Y values.
-		 * Must also roundup width and height when calculating
-		 * since images that are not a multiple of the
-		 * horizontal/vertical subsampling area include
-		 * YCbCr data for the extended image.
-		 */
-		uint16 ycbcrsubsampling[2];
-		uint16 samplingblock_samples;
-		uint32 samplingblocks_hor;
-		uint32 samplingblocks_ver;
-		uint64 samplingrow_samples;
-		uint64 samplingrow_size;
-		TIFFGetFieldDefaulted(tif,TIFFTAG_YCBCRSUBSAMPLING,ycbcrsubsampling+0,
-		    ycbcrsubsampling+1);
-		if ((ycbcrsubsampling[0] != 1 && ycbcrsubsampling[0] != 2 && ycbcrsubsampling[0] != 4)
-		    ||(ycbcrsubsampling[1] != 1 && ycbcrsubsampling[1] != 2 && ycbcrsubsampling[1] != 4))
-		{
-			TIFFErrorExt(tif->tif_clientdata,module,
-				     "Invalid YCbCr subsampling (%dx%d)", 
-				     ycbcrsubsampling[0], 
-				     ycbcrsubsampling[1] );
-			return 0;
-		}
-		samplingblock_samples=ycbcrsubsampling[0]*ycbcrsubsampling[1]+2;
-		samplingblocks_hor=TIFFhowmany_32(td->td_tilewidth,ycbcrsubsampling[0]);
-		samplingblocks_ver=TIFFhowmany_32(nrows,ycbcrsubsampling[1]);
-		samplingrow_samples=_TIFFMultiply64(tif,samplingblocks_hor,samplingblock_samples,module);
-		samplingrow_size=TIFFhowmany8_64(_TIFFMultiply64(tif,samplingrow_samples,td->td_bitspersample,module));
-		return(_TIFFMultiply64(tif,samplingrow_size,samplingblocks_ver,module));
-	}
-	else
-		return(_TIFFMultiply64(tif,nrows,TIFFTileRowSize64(tif),module));
-}
-tmsize_t
-TIFFVTileSize(TIFF* tif, uint32 nrows)
-{
-	static const char module[] = "TIFFVTileSize";
-	uint64 m;
-	tmsize_t n;
-	m=TIFFVTileSize64(tif,nrows);
-	n=(tmsize_t)m;
-	if ((uint64)n!=m)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
-		n=0;
-	}
-	return(n);
-}
-
-/*
- * Compute the # bytes in a row-aligned tile.
- */
-uint64
-TIFFTileSize64(TIFF* tif)
-{
-	return (TIFFVTileSize64(tif, tif->tif_dir.td_tilelength));
-}
-tmsize_t
-TIFFTileSize(TIFF* tif)
-{
-	static const char module[] = "TIFFTileSize";
-	uint64 m;
-	tmsize_t n;
-	m=TIFFTileSize64(tif);
-	n=(tmsize_t)m;
-	if ((uint64)n!=m)
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
-		n=0;
-	}
-	return(n);
-}
-
-/*
- * Compute a default tile size based on the image
- * characteristics and a requested value.  If a
- * request is <1 then we choose a size according
- * to certain heuristics.
- */
-void
-TIFFDefaultTileSize(TIFF* tif, uint32* tw, uint32* th)
-{
-	(*tif->tif_deftilesize)(tif, tw, th);
-}
-
-void
-_TIFFDefaultTileSize(TIFF* tif, uint32* tw, uint32* th)
-{
-	(void) tif;
-	if (*(int32*) tw < 1)
-		*tw = 256;
-	if (*(int32*) th < 1)
-		*th = 256;
-	/* roundup to a multiple of 16 per the spec */
-	if (*tw & 0xf)
-		*tw = TIFFroundup_32(*tw, 16);
-	if (*th & 0xf)
-		*th = TIFFroundup_32(*th, 16);
-}
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Id: tif_tile.c,v 1.11 2015/02/19 22:39:59 drolon Exp $ */
+
+/*
+ * Copyright (c) 1991-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and 
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
+ * 
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Tiled Image Support Routines.
+ */
+#include "tiffiop.h"
+
+/*
+ * Compute which tile an (x,y,z,s) value is in.
+ */
+uint32
+TIFFComputeTile(TIFF* tif, uint32 x, uint32 y, uint32 z, uint16 s)
+{
+	TIFFDirectory *td = &tif->tif_dir;
+	uint32 dx = td->td_tilewidth;
+	uint32 dy = td->td_tilelength;
+	uint32 dz = td->td_tiledepth;
+	uint32 tile = 1;
+
+	if (td->td_imagedepth == 1)
+		z = 0;
+	if (dx == (uint32) -1)
+		dx = td->td_imagewidth;
+	if (dy == (uint32) -1)
+		dy = td->td_imagelength;
+	if (dz == (uint32) -1)
+		dz = td->td_imagedepth;
+	if (dx != 0 && dy != 0 && dz != 0) {
+		uint32 xpt = TIFFhowmany_32(td->td_imagewidth, dx);
+		uint32 ypt = TIFFhowmany_32(td->td_imagelength, dy);
+		uint32 zpt = TIFFhowmany_32(td->td_imagedepth, dz);
+
+		if (td->td_planarconfig == PLANARCONFIG_SEPARATE) 
+			tile = (xpt*ypt*zpt)*s +
+			     (xpt*ypt)*(z/dz) +
+			     xpt*(y/dy) +
+			     x/dx;
+		else
+			tile = (xpt*ypt)*(z/dz) + xpt*(y/dy) + x/dx;
+	}
+	return (tile);
+}
+
+/*
+ * Check an (x,y,z,s) coordinate
+ * against the image bounds.
+ */
+int
+TIFFCheckTile(TIFF* tif, uint32 x, uint32 y, uint32 z, uint16 s)
+{
+	TIFFDirectory *td = &tif->tif_dir;
+
+	if (x >= td->td_imagewidth) {
+		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+			     "%lu: Col out of range, max %lu",
+			     (unsigned long) x,
+			     (unsigned long) (td->td_imagewidth - 1));
+		return (0);
+	}
+	if (y >= td->td_imagelength) {
+		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+			     "%lu: Row out of range, max %lu",
+			     (unsigned long) y,
+			     (unsigned long) (td->td_imagelength - 1));
+		return (0);
+	}
+	if (z >= td->td_imagedepth) {
+		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+			     "%lu: Depth out of range, max %lu",
+			     (unsigned long) z,
+			     (unsigned long) (td->td_imagedepth - 1));
+		return (0);
+	}
+	if (td->td_planarconfig == PLANARCONFIG_SEPARATE &&
+	    s >= td->td_samplesperpixel) {
+		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+			     "%lu: Sample out of range, max %lu",
+			     (unsigned long) s,
+			     (unsigned long) (td->td_samplesperpixel - 1));
+		return (0);
+	}
+	return (1);
+}
+
+/*
+ * Compute how many tiles are in an image.
+ */
+uint32
+TIFFNumberOfTiles(TIFF* tif)
+{
+	TIFFDirectory *td = &tif->tif_dir;
+	uint32 dx = td->td_tilewidth;
+	uint32 dy = td->td_tilelength;
+	uint32 dz = td->td_tiledepth;
+	uint32 ntiles;
+
+	if (dx == (uint32) -1)
+		dx = td->td_imagewidth;
+	if (dy == (uint32) -1)
+		dy = td->td_imagelength;
+	if (dz == (uint32) -1)
+		dz = td->td_imagedepth;
+	ntiles = (dx == 0 || dy == 0 || dz == 0) ? 0 :
+	    _TIFFMultiply32(tif, _TIFFMultiply32(tif, TIFFhowmany_32(td->td_imagewidth, dx),
+	    TIFFhowmany_32(td->td_imagelength, dy),
+	    "TIFFNumberOfTiles"),
+	    TIFFhowmany_32(td->td_imagedepth, dz), "TIFFNumberOfTiles");
+	if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
+		ntiles = _TIFFMultiply32(tif, ntiles, td->td_samplesperpixel,
+		    "TIFFNumberOfTiles");
+	return (ntiles);
+}
+
+/*
+ * Compute the # bytes in each row of a tile.
+ */
+uint64
+TIFFTileRowSize64(TIFF* tif)
+{
+	TIFFDirectory *td = &tif->tif_dir;
+	uint64 rowsize;
+
+	if (td->td_tilelength == 0 || td->td_tilewidth == 0)
+		return (0);
+	rowsize = _TIFFMultiply64(tif, td->td_bitspersample, td->td_tilewidth,
+	    "TIFFTileRowSize");
+	if (td->td_planarconfig == PLANARCONFIG_CONTIG)
+		rowsize = _TIFFMultiply64(tif, rowsize, td->td_samplesperpixel,
+		    "TIFFTileRowSize");
+	return (TIFFhowmany8_64(rowsize));
+}
+tmsize_t
+TIFFTileRowSize(TIFF* tif)
+{
+	static const char module[] = "TIFFTileRowSize";
+	uint64 m;
+	tmsize_t n;
+	m=TIFFTileRowSize64(tif);
+	n=(tmsize_t)m;
+	if ((uint64)n!=m)
+	{
+		TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
+		n=0;
+	}
+	return(n);
+}
+
+/*
+ * Compute the # bytes in a variable length, row-aligned tile.
+ */
+uint64
+TIFFVTileSize64(TIFF* tif, uint32 nrows)
+{
+	static const char module[] = "TIFFVTileSize64";
+	TIFFDirectory *td = &tif->tif_dir;
+	if (td->td_tilelength == 0 || td->td_tilewidth == 0 ||
+	    td->td_tiledepth == 0)
+		return (0);
+	if ((td->td_planarconfig==PLANARCONFIG_CONTIG)&&
+	    (td->td_photometric==PHOTOMETRIC_YCBCR)&&
+	    (td->td_samplesperpixel==3)&&
+	    (!isUpSampled(tif)))
+	{
+		/*
+		 * Packed YCbCr data contain one Cb+Cr for every
+		 * HorizontalSampling*VerticalSampling Y values.
+		 * Must also roundup width and height when calculating
+		 * since images that are not a multiple of the
+		 * horizontal/vertical subsampling area include
+		 * YCbCr data for the extended image.
+		 */
+		uint16 ycbcrsubsampling[2];
+		uint16 samplingblock_samples;
+		uint32 samplingblocks_hor;
+		uint32 samplingblocks_ver;
+		uint64 samplingrow_samples;
+		uint64 samplingrow_size;
+		TIFFGetFieldDefaulted(tif,TIFFTAG_YCBCRSUBSAMPLING,ycbcrsubsampling+0,
+		    ycbcrsubsampling+1);
+		if ((ycbcrsubsampling[0] != 1 && ycbcrsubsampling[0] != 2 && ycbcrsubsampling[0] != 4)
+		    ||(ycbcrsubsampling[1] != 1 && ycbcrsubsampling[1] != 2 && ycbcrsubsampling[1] != 4))
+		{
+			TIFFErrorExt(tif->tif_clientdata,module,
+				     "Invalid YCbCr subsampling (%dx%d)", 
+				     ycbcrsubsampling[0], 
+				     ycbcrsubsampling[1] );
+			return 0;
+		}
+		samplingblock_samples=ycbcrsubsampling[0]*ycbcrsubsampling[1]+2;
+		samplingblocks_hor=TIFFhowmany_32(td->td_tilewidth,ycbcrsubsampling[0]);
+		samplingblocks_ver=TIFFhowmany_32(nrows,ycbcrsubsampling[1]);
+		samplingrow_samples=_TIFFMultiply64(tif,samplingblocks_hor,samplingblock_samples,module);
+		samplingrow_size=TIFFhowmany8_64(_TIFFMultiply64(tif,samplingrow_samples,td->td_bitspersample,module));
+		return(_TIFFMultiply64(tif,samplingrow_size,samplingblocks_ver,module));
+	}
+	else
+		return(_TIFFMultiply64(tif,nrows,TIFFTileRowSize64(tif),module));
+}
+tmsize_t
+TIFFVTileSize(TIFF* tif, uint32 nrows)
+{
+	static const char module[] = "TIFFVTileSize";
+	uint64 m;
+	tmsize_t n;
+	m=TIFFVTileSize64(tif,nrows);
+	n=(tmsize_t)m;
+	if ((uint64)n!=m)
+	{
+		TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
+		n=0;
+	}
+	return(n);
+}
+
+/*
+ * Compute the # bytes in a row-aligned tile.
+ */
+uint64
+TIFFTileSize64(TIFF* tif)
+{
+	return (TIFFVTileSize64(tif, tif->tif_dir.td_tilelength));
+}
+tmsize_t
+TIFFTileSize(TIFF* tif)
+{
+	static const char module[] = "TIFFTileSize";
+	uint64 m;
+	tmsize_t n;
+	m=TIFFTileSize64(tif);
+	n=(tmsize_t)m;
+	if ((uint64)n!=m)
+	{
+		TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
+		n=0;
+	}
+	return(n);
+}
+
+/*
+ * Compute a default tile size based on the image
+ * characteristics and a requested value.  If a
+ * request is <1 then we choose a size according
+ * to certain heuristics.
+ */
+void
+TIFFDefaultTileSize(TIFF* tif, uint32* tw, uint32* th)
+{
+	(*tif->tif_deftilesize)(tif, tw, th);
+}
+
+void
+_TIFFDefaultTileSize(TIFF* tif, uint32* tw, uint32* th)
+{
+	(void) tif;
+	if (*(int32*) tw < 1)
+		*tw = 256;
+	if (*(int32*) th < 1)
+		*th = 256;
+	/* roundup to a multiple of 16 per the spec */
+	if (*tw & 0xf)
+		*tw = TIFFroundup_32(*tw, 16);
+	if (*th & 0xf)
+		*th = TIFFroundup_32(*th, 16);
+}
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tif_unix.c b/Source/LibTIFF4/tif_unix.c
index ffe99e2..a3d8496 100644
--- a/Source/LibTIFF4/tif_unix.c
+++ b/Source/LibTIFF4/tif_unix.c
@@ -1,4 +1,4 @@
-/* $Id: tif_unix.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
+/* $Id: tif_unix.c,v 1.11 2015/02/19 22:39:59 drolon Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
@@ -257,6 +257,9 @@ TIFFOpenW(const wchar_t* name, const char* mode)
 void*
 _TIFFmalloc(tmsize_t s)
 {
+        if (s == 0)
+                return ((void *) NULL);
+
 	return (malloc((size_t) s));
 }
 
diff --git a/Source/LibTIFF4/tif_version.c b/Source/LibTIFF4/tif_version.c
index 1019e1a..f56d705 100644
--- a/Source/LibTIFF4/tif_version.c
+++ b/Source/LibTIFF4/tif_version.c
@@ -1,40 +1,40 @@
-/* $Header: /cvsroot/freeimage/FreeImage/Source/LibTIFF4/tif_version.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-/*
- * Copyright (c) 1992-1997 Sam Leffler
- * Copyright (c) 1992-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-#include "tiffiop.h"
-
-static const char TIFFVersion[] = TIFFLIB_VERSION_STR;
-
-const char*
-TIFFGetVersion(void)
-{
-	return (TIFFVersion);
-}
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Header: /cvsroot/freeimage/FreeImage/Source/LibTIFF4/tif_version.c,v 1.11 2015/02/19 22:39:59 drolon Exp $ */
+/*
+ * Copyright (c) 1992-1997 Sam Leffler
+ * Copyright (c) 1992-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and 
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
+ * 
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
+ * OF THIS SOFTWARE.
+ */
+#include "tiffiop.h"
+
+static const char TIFFVersion[] = TIFFLIB_VERSION_STR;
+
+const char*
+TIFFGetVersion(void)
+{
+	return (TIFFVersion);
+}
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tif_vms.c b/Source/LibTIFF4/tif_vms.c
index 30a1345..baaaae1 100644
--- a/Source/LibTIFF4/tif_vms.c
+++ b/Source/LibTIFF4/tif_vms.c
@@ -1,4 +1,4 @@
-/* $Id: tif_vms.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
+/* $Id: tif_vms.c,v 1.11 2015/02/19 22:39:59 drolon Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
@@ -264,6 +264,9 @@ TIFFOpen(const char* name, const char* mode)
 tdata_t
 _TIFFmalloc(tsize_t s)
 {
+        if (s == 0)
+                return ((void *) NULL);
+
 	return (malloc((size_t) s));
 }
 
diff --git a/Source/LibTIFF4/tif_warning.c b/Source/LibTIFF4/tif_warning.c
index 1dd09a6..e2784db 100644
--- a/Source/LibTIFF4/tif_warning.c
+++ b/Source/LibTIFF4/tif_warning.c
@@ -1,81 +1,81 @@
-/* $Header: /cvsroot/freeimage/FreeImage/Source/LibTIFF4/tif_warning.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library.
- */
-#include "tiffiop.h"
-
-TIFFErrorHandlerExt _TIFFwarningHandlerExt = NULL;
-
-TIFFErrorHandler
-TIFFSetWarningHandler(TIFFErrorHandler handler)
-{
-	TIFFErrorHandler prev = _TIFFwarningHandler;
-	_TIFFwarningHandler = handler;
-	return (prev);
-}
-
-TIFFErrorHandlerExt
-TIFFSetWarningHandlerExt(TIFFErrorHandlerExt handler)
-{
-	TIFFErrorHandlerExt prev = _TIFFwarningHandlerExt;
-	_TIFFwarningHandlerExt = handler;
-	return (prev);
-}
-
-void
-TIFFWarning(const char* module, const char* fmt, ...)
-{
-	va_list ap;
-	va_start(ap, fmt);
-	if (_TIFFwarningHandler)
-		(*_TIFFwarningHandler)(module, fmt, ap);
-	if (_TIFFwarningHandlerExt)
-		(*_TIFFwarningHandlerExt)(0, module, fmt, ap);
-	va_end(ap);
-}
-
-void
-TIFFWarningExt(thandle_t fd, const char* module, const char* fmt, ...)
-{
-	va_list ap;
-	va_start(ap, fmt);
-	if (_TIFFwarningHandler)
-		(*_TIFFwarningHandler)(module, fmt, ap);
-	if (_TIFFwarningHandlerExt)
-		(*_TIFFwarningHandlerExt)(fd, module, fmt, ap);
-	va_end(ap);
-}
-
-
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Header: /cvsroot/freeimage/FreeImage/Source/LibTIFF4/tif_warning.c,v 1.11 2015/02/19 22:39:59 drolon Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and 
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
+ * 
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ */
+#include "tiffiop.h"
+
+TIFFErrorHandlerExt _TIFFwarningHandlerExt = NULL;
+
+TIFFErrorHandler
+TIFFSetWarningHandler(TIFFErrorHandler handler)
+{
+	TIFFErrorHandler prev = _TIFFwarningHandler;
+	_TIFFwarningHandler = handler;
+	return (prev);
+}
+
+TIFFErrorHandlerExt
+TIFFSetWarningHandlerExt(TIFFErrorHandlerExt handler)
+{
+	TIFFErrorHandlerExt prev = _TIFFwarningHandlerExt;
+	_TIFFwarningHandlerExt = handler;
+	return (prev);
+}
+
+void
+TIFFWarning(const char* module, const char* fmt, ...)
+{
+	va_list ap;
+	va_start(ap, fmt);
+	if (_TIFFwarningHandler)
+		(*_TIFFwarningHandler)(module, fmt, ap);
+	if (_TIFFwarningHandlerExt)
+		(*_TIFFwarningHandlerExt)(0, module, fmt, ap);
+	va_end(ap);
+}
+
+void
+TIFFWarningExt(thandle_t fd, const char* module, const char* fmt, ...)
+{
+	va_list ap;
+	va_start(ap, fmt);
+	if (_TIFFwarningHandler)
+		(*_TIFFwarningHandler)(module, fmt, ap);
+	if (_TIFFwarningHandlerExt)
+		(*_TIFFwarningHandlerExt)(fd, module, fmt, ap);
+	va_end(ap);
+}
+
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tif_win32.c b/Source/LibTIFF4/tif_win32.c
index 010596f..9fbecd0 100644
--- a/Source/LibTIFF4/tif_win32.c
+++ b/Source/LibTIFF4/tif_win32.c
@@ -1,4 +1,4 @@
-/* $Id: tif_win32.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
+/* $Id: tif_win32.c,v 1.11 2015/02/19 22:39:59 drolon Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
@@ -329,6 +329,9 @@ TIFFOpenW(const wchar_t* name, const char* mode)
 void*
 _TIFFmalloc(tmsize_t s)
 {
+        if (s == 0)
+                return ((void *) NULL);
+
 	return (malloc((size_t) s));
 }
 
diff --git a/Source/LibTIFF4/tif_wince.c b/Source/LibTIFF4/tif_wince.c
index aeb1170..ff0c489 100644
--- a/Source/LibTIFF4/tif_wince.c
+++ b/Source/LibTIFF4/tif_wince.c
@@ -1,4 +1,4 @@
-/* $Id: tif_wince.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
+/* $Id: tif_wince.c,v 1.11 2015/02/19 22:39:59 drolon Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
diff --git a/Source/LibTIFF4/tif_write.c b/Source/LibTIFF4/tif_write.c
index 87341ff..a8be0d6 100644
--- a/Source/LibTIFF4/tif_write.c
+++ b/Source/LibTIFF4/tif_write.c
@@ -1,771 +1,771 @@
-/* $Id: tif_write.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- */
-
-/*
- * TIFF Library.
- *
- * Scanline-oriented Write Support
- */
-#include "tiffiop.h"
-#include <stdio.h>
-
-#define STRIPINCR	20		/* expansion factor on strip array */
-
-#define WRITECHECKSTRIPS(tif, module)				\
-	(((tif)->tif_flags&TIFF_BEENWRITING) || TIFFWriteCheck((tif),0,module))
-#define WRITECHECKTILES(tif, module)				\
-	(((tif)->tif_flags&TIFF_BEENWRITING) || TIFFWriteCheck((tif),1,module))
-#define BUFFERCHECK(tif)					\
-	((((tif)->tif_flags & TIFF_BUFFERSETUP) && tif->tif_rawdata) ||	\
-	    TIFFWriteBufferSetup((tif), NULL, (tmsize_t) -1))
-
-static int TIFFGrowStrips(TIFF* tif, uint32 delta, const char* module);
-static int TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t cc);
-
-int
-TIFFWriteScanline(TIFF* tif, void* buf, uint32 row, uint16 sample)
-{
-	static const char module[] = "TIFFWriteScanline";
-	register TIFFDirectory *td;
-	int status, imagegrew = 0;
-	uint32 strip;
-
-	if (!WRITECHECKSTRIPS(tif, module))
-		return (-1);
-	/*
-	 * Handle delayed allocation of data buffer.  This
-	 * permits it to be sized more intelligently (using
-	 * directory information).
-	 */
-	if (!BUFFERCHECK(tif))
-		return (-1);
-        tif->tif_flags |= TIFF_BUF4WRITE; /* not strictly sure this is right*/
-
-	td = &tif->tif_dir;
-	/*
-	 * Extend image length if needed
-	 * (but only for PlanarConfig=1).
-	 */
-	if (row >= td->td_imagelength) {	/* extend image */
-		if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-			    "Can not change \"ImageLength\" when using separate planes");
-			return (-1);
-		}
-		td->td_imagelength = row+1;
-		imagegrew = 1;
-	}
-	/*
-	 * Calculate strip and check for crossings.
-	 */
-	if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
-		if (sample >= td->td_samplesperpixel) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-			    "%lu: Sample out of range, max %lu",
-			    (unsigned long) sample, (unsigned long) td->td_samplesperpixel);
-			return (-1);
-		}
-		strip = sample*td->td_stripsperimage + row/td->td_rowsperstrip;
-	} else
-		strip = row / td->td_rowsperstrip;
-	/*
-	 * Check strip array to make sure there's space. We don't support
-	 * dynamically growing files that have data organized in separate
-	 * bitplanes because it's too painful.  In that case we require that
-	 * the imagelength be set properly before the first write (so that the
-	 * strips array will be fully allocated above).
-	 */
-	if (strip >= td->td_nstrips && !TIFFGrowStrips(tif, 1, module))
-		return (-1);
-	if (strip != tif->tif_curstrip) {
-		/*
-		 * Changing strips -- flush any data present.
-		 */
-		if (!TIFFFlushData(tif))
-			return (-1);
-		tif->tif_curstrip = strip;
-		/*
-		 * Watch out for a growing image.  The value of strips/image
-		 * will initially be 1 (since it can't be deduced until the
-		 * imagelength is known).
-		 */
-		if (strip >= td->td_stripsperimage && imagegrew)
-			td->td_stripsperimage =
-			    TIFFhowmany_32(td->td_imagelength,td->td_rowsperstrip);
-		tif->tif_row =
-		    (strip % td->td_stripsperimage) * td->td_rowsperstrip;
-		if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
-			if (!(*tif->tif_setupencode)(tif))
-				return (-1);
-			tif->tif_flags |= TIFF_CODERSETUP;
-		}
-        
-		tif->tif_rawcc = 0;
-		tif->tif_rawcp = tif->tif_rawdata;
-
-		if( td->td_stripbytecount[strip] > 0 )
-		{
-			/* if we are writing over existing tiles, zero length */
-			td->td_stripbytecount[strip] = 0;
-
-			/* this forces TIFFAppendToStrip() to do a seek */
-			tif->tif_curoff = 0;
-		}
-
-		if (!(*tif->tif_preencode)(tif, sample))
-			return (-1);
-		tif->tif_flags |= TIFF_POSTENCODE;
-	}
-	/*
-	 * Ensure the write is either sequential or at the
-	 * beginning of a strip (or that we can randomly
-	 * access the data -- i.e. no encoding).
-	 */
-	if (row != tif->tif_row) {
-		if (row < tif->tif_row) {
-			/*
-			 * Moving backwards within the same strip:
-			 * backup to the start and then decode
-			 * forward (below).
-			 */
-			tif->tif_row = (strip % td->td_stripsperimage) *
-			    td->td_rowsperstrip;
-			tif->tif_rawcp = tif->tif_rawdata;
-		}
-		/*
-		 * Seek forward to the desired row.
-		 */
-		if (!(*tif->tif_seek)(tif, row - tif->tif_row))
-			return (-1);
-		tif->tif_row = row;
-	}
-
-	/* swab if needed - note that source buffer will be altered */
-	tif->tif_postdecode( tif, (uint8*) buf, tif->tif_scanlinesize );
-
-	status = (*tif->tif_encoderow)(tif, (uint8*) buf,
-	    tif->tif_scanlinesize, sample);
-
-        /* we are now poised at the beginning of the next row */
-	tif->tif_row = row + 1;
-	return (status);
-}
-
-/*
- * Encode the supplied data and write it to the
- * specified strip.
- *
- * NB: Image length must be setup before writing.
- */
-tmsize_t
-TIFFWriteEncodedStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc)
-{
-	static const char module[] = "TIFFWriteEncodedStrip";
-	TIFFDirectory *td = &tif->tif_dir;
-	uint16 sample;
-
-	if (!WRITECHECKSTRIPS(tif, module))
-		return ((tmsize_t) -1);
-	/*
-	 * Check strip array to make sure there's space.
-	 * We don't support dynamically growing files that
-	 * have data organized in separate bitplanes because
-	 * it's too painful.  In that case we require that
-	 * the imagelength be set properly before the first
-	 * write (so that the strips array will be fully
-	 * allocated above).
-	 */
-	if (strip >= td->td_nstrips) {
-		if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-			    "Can not grow image by strips when using separate planes");
-			return ((tmsize_t) -1);
-		}
-		if (!TIFFGrowStrips(tif, 1, module))
-			return ((tmsize_t) -1);
-		td->td_stripsperimage =
-		    TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip);  
-	}
-	/*
-	 * Handle delayed allocation of data buffer.  This
-	 * permits it to be sized according to the directory
-	 * info.
-	 */
-	if (!BUFFERCHECK(tif))
-		return ((tmsize_t) -1);
-
-        tif->tif_flags |= TIFF_BUF4WRITE;
-	tif->tif_curstrip = strip;
-
-	tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
-	if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
-		if (!(*tif->tif_setupencode)(tif))
-			return ((tmsize_t) -1);
-		tif->tif_flags |= TIFF_CODERSETUP;
-	}
-
-	if( td->td_stripbytecount[strip] > 0 )
-        {
-            /* Make sure that at the first attempt of rewriting the tile, we will have */
-            /* more bytes available in the output buffer than the previous byte count, */
-            /* so that TIFFAppendToStrip() will detect the overflow when it is called the first */
-            /* time if the new compressed tile is bigger than the older one. (GDAL #4771) */
-            if( tif->tif_rawdatasize <= td->td_stripbytecount[strip] )
-            {
-                if( !(TIFFWriteBufferSetup(tif, NULL,
-                    (tmsize_t)TIFFroundup_64((uint64)(td->td_stripbytecount[strip] + 1), 1024))) )
-                    return ((tmsize_t)(-1));
-            }
-
-	    /* Force TIFFAppendToStrip() to consider placing data at end
-               of file. */
-            tif->tif_curoff = 0;
-        }
-
-    tif->tif_rawcc = 0;
-    tif->tif_rawcp = tif->tif_rawdata;
-
-	tif->tif_flags &= ~TIFF_POSTENCODE;
-	sample = (uint16)(strip / td->td_stripsperimage);
-	if (!(*tif->tif_preencode)(tif, sample))
-		return ((tmsize_t) -1);
-
-        /* swab if needed - note that source buffer will be altered */
-	tif->tif_postdecode( tif, (uint8*) data, cc );
-
-	if (!(*tif->tif_encodestrip)(tif, (uint8*) data, cc, sample))
-		return (0);
-	if (!(*tif->tif_postencode)(tif))
-		return ((tmsize_t) -1);
-	if (!isFillOrder(tif, td->td_fillorder) &&
-	    (tif->tif_flags & TIFF_NOBITREV) == 0)
-		TIFFReverseBits(tif->tif_rawdata, tif->tif_rawcc);
-	if (tif->tif_rawcc > 0 &&
-	    !TIFFAppendToStrip(tif, strip, tif->tif_rawdata, tif->tif_rawcc))
-		return ((tmsize_t) -1);
-	tif->tif_rawcc = 0;
-	tif->tif_rawcp = tif->tif_rawdata;
-	return (cc);
-}
-
-/*
- * Write the supplied data to the specified strip.
- *
- * NB: Image length must be setup before writing.
- */
-tmsize_t
-TIFFWriteRawStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc)
-{
-	static const char module[] = "TIFFWriteRawStrip";
-	TIFFDirectory *td = &tif->tif_dir;
-
-	if (!WRITECHECKSTRIPS(tif, module))
-		return ((tmsize_t) -1);
-	/*
-	 * Check strip array to make sure there's space.
-	 * We don't support dynamically growing files that
-	 * have data organized in separate bitplanes because
-	 * it's too painful.  In that case we require that
-	 * the imagelength be set properly before the first
-	 * write (so that the strips array will be fully
-	 * allocated above).
-	 */
-	if (strip >= td->td_nstrips) {
-		if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-			    "Can not grow image by strips when using separate planes");
-			return ((tmsize_t) -1);
-		}
-		/*
-		 * Watch out for a growing image.  The value of
-		 * strips/image will initially be 1 (since it
-		 * can't be deduced until the imagelength is known).
-		 */
-		if (strip >= td->td_stripsperimage)
-			td->td_stripsperimage =
-			    TIFFhowmany_32(td->td_imagelength,td->td_rowsperstrip);
-		if (!TIFFGrowStrips(tif, 1, module))
-			return ((tmsize_t) -1);
-	}
-	tif->tif_curstrip = strip;
-	tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
-	return (TIFFAppendToStrip(tif, strip, (uint8*) data, cc) ?
-	    cc : (tmsize_t) -1);
-}
-
-/*
- * Write and compress a tile of data.  The
- * tile is selected by the (x,y,z,s) coordinates.
- */
-tmsize_t
-TIFFWriteTile(TIFF* tif, void* buf, uint32 x, uint32 y, uint32 z, uint16 s)
-{
-	if (!TIFFCheckTile(tif, x, y, z, s))
-		return ((tmsize_t)(-1));
-	/*
-	 * NB: A tile size of -1 is used instead of tif_tilesize knowing
-	 *     that TIFFWriteEncodedTile will clamp this to the tile size.
-	 *     This is done because the tile size may not be defined until
-	 *     after the output buffer is setup in TIFFWriteBufferSetup.
-	 */
-	return (TIFFWriteEncodedTile(tif,
-	    TIFFComputeTile(tif, x, y, z, s), buf, (tmsize_t)(-1)));
-}
-
-/*
- * Encode the supplied data and write it to the
- * specified tile.  There must be space for the
- * data.  The function clamps individual writes
- * to a tile to the tile size, but does not (and
- * can not) check that multiple writes to the same
- * tile do not write more than tile size data.
- *
- * NB: Image length must be setup before writing; this
- *     interface does not support automatically growing
- *     the image on each write (as TIFFWriteScanline does).
- */
-tmsize_t
-TIFFWriteEncodedTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc)
-{
-	static const char module[] = "TIFFWriteEncodedTile";
-	TIFFDirectory *td;
-	uint16 sample;
-
-	if (!WRITECHECKTILES(tif, module))
-		return ((tmsize_t)(-1));
-	td = &tif->tif_dir;
-	if (tile >= td->td_nstrips) {
-		TIFFErrorExt(tif->tif_clientdata, module, "Tile %lu out of range, max %lu",
-		    (unsigned long) tile, (unsigned long) td->td_nstrips);
-		return ((tmsize_t)(-1));
-	}
-	/*
-	 * Handle delayed allocation of data buffer.  This
-	 * permits it to be sized more intelligently (using
-	 * directory information).
-	 */
-	if (!BUFFERCHECK(tif))
-		return ((tmsize_t)(-1));
-
-        tif->tif_flags |= TIFF_BUF4WRITE;
-	tif->tif_curtile = tile;
-
-	if( td->td_stripbytecount[tile] > 0 )
-        {
-            /* Make sure that at the first attempt of rewriting the tile, we will have */
-            /* more bytes available in the output buffer than the previous byte count, */
-            /* so that TIFFAppendToStrip() will detect the overflow when it is called the first */
-            /* time if the new compressed tile is bigger than the older one. (GDAL #4771) */
-            if( tif->tif_rawdatasize <= td->td_stripbytecount[tile] )
-            {
-                if( !(TIFFWriteBufferSetup(tif, NULL,
-                    (tmsize_t)TIFFroundup_64((uint64)(td->td_stripbytecount[tile] + 1), 1024))) )
-                    return ((tmsize_t)(-1));
-            }
-
-	    /* Force TIFFAppendToStrip() to consider placing data at end
-               of file. */
-            tif->tif_curoff = 0;
-        }
-
-    tif->tif_rawcc = 0;
-    tif->tif_rawcp = tif->tif_rawdata;
-
-	/* 
-	 * Compute tiles per row & per column to compute
-	 * current row and column
-	 */
-	tif->tif_row = (tile % TIFFhowmany_32(td->td_imagelength, td->td_tilelength))
-		* td->td_tilelength;
-	tif->tif_col = (tile % TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth))
-		* td->td_tilewidth;
-
-	if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
-		if (!(*tif->tif_setupencode)(tif))
-			return ((tmsize_t)(-1));
-		tif->tif_flags |= TIFF_CODERSETUP;
-	}
-	tif->tif_flags &= ~TIFF_POSTENCODE;
-	sample = (uint16)(tile/td->td_stripsperimage);
-	if (!(*tif->tif_preencode)(tif, sample))
-		return ((tmsize_t)(-1));
-	/*
-	 * Clamp write amount to the tile size.  This is mostly
-	 * done so that callers can pass in some large number
-	 * (e.g. -1) and have the tile size used instead.
-	 */
-	if ( cc < 1 || cc > tif->tif_tilesize)
-		cc = tif->tif_tilesize;
-
-        /* swab if needed - note that source buffer will be altered */
-	tif->tif_postdecode( tif, (uint8*) data, cc );
-
-	if (!(*tif->tif_encodetile)(tif, (uint8*) data, cc, sample))
-		return (0);
-	if (!(*tif->tif_postencode)(tif))
-		return ((tmsize_t)(-1));
-	if (!isFillOrder(tif, td->td_fillorder) &&
-	    (tif->tif_flags & TIFF_NOBITREV) == 0)
-		TIFFReverseBits((uint8*)tif->tif_rawdata, tif->tif_rawcc);
-	if (tif->tif_rawcc > 0 && !TIFFAppendToStrip(tif, tile,
-	    tif->tif_rawdata, tif->tif_rawcc))
-		return ((tmsize_t)(-1));
-	tif->tif_rawcc = 0;
-	tif->tif_rawcp = tif->tif_rawdata;
-	return (cc);
-}
-
-/*
- * Write the supplied data to the specified strip.
- * There must be space for the data; we don't check
- * if strips overlap!
- *
- * NB: Image length must be setup before writing; this
- *     interface does not support automatically growing
- *     the image on each write (as TIFFWriteScanline does).
- */
-tmsize_t
-TIFFWriteRawTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc)
-{
-	static const char module[] = "TIFFWriteRawTile";
-
-	if (!WRITECHECKTILES(tif, module))
-		return ((tmsize_t)(-1));
-	if (tile >= tif->tif_dir.td_nstrips) {
-		TIFFErrorExt(tif->tif_clientdata, module, "Tile %lu out of range, max %lu",
-		    (unsigned long) tile,
-		    (unsigned long) tif->tif_dir.td_nstrips);
-		return ((tmsize_t)(-1));
-	}
-	return (TIFFAppendToStrip(tif, tile, (uint8*) data, cc) ?
-	    cc : (tmsize_t)(-1));
-}
-
-#define	isUnspecified(tif, f) \
-    (TIFFFieldSet(tif,f) && (tif)->tif_dir.td_imagelength == 0)
-
-int
-TIFFSetupStrips(TIFF* tif)
-{
-	TIFFDirectory* td = &tif->tif_dir;
-
-	if (isTiled(tif))
-		td->td_stripsperimage =
-		    isUnspecified(tif, FIELD_TILEDIMENSIONS) ?
-			td->td_samplesperpixel : TIFFNumberOfTiles(tif);
-	else
-		td->td_stripsperimage =
-		    isUnspecified(tif, FIELD_ROWSPERSTRIP) ?
-			td->td_samplesperpixel : TIFFNumberOfStrips(tif);
-	td->td_nstrips = td->td_stripsperimage;
-	if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
-		td->td_stripsperimage /= td->td_samplesperpixel;
-	td->td_stripoffset = (uint64 *)
-	    _TIFFmalloc(td->td_nstrips * sizeof (uint64));
-	td->td_stripbytecount = (uint64 *)
-	    _TIFFmalloc(td->td_nstrips * sizeof (uint64));
-	if (td->td_stripoffset == NULL || td->td_stripbytecount == NULL)
-		return (0);
-	/*
-	 * Place data at the end-of-file
-	 * (by setting offsets to zero).
-	 */
-	_TIFFmemset(td->td_stripoffset, 0, td->td_nstrips*sizeof (uint64));
-	_TIFFmemset(td->td_stripbytecount, 0, td->td_nstrips*sizeof (uint64));
-	TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
-	TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
-	return (1);
-}
-#undef isUnspecified
-
-/*
- * Verify file is writable and that the directory
- * information is setup properly.  In doing the latter
- * we also "freeze" the state of the directory so
- * that important information is not changed.
- */
-int
-TIFFWriteCheck(TIFF* tif, int tiles, const char* module)
-{
-	if (tif->tif_mode == O_RDONLY) {
-		TIFFErrorExt(tif->tif_clientdata, module, "File not open for writing");
-		return (0);
-	}
-	if (tiles ^ isTiled(tif)) {
-		TIFFErrorExt(tif->tif_clientdata, module, tiles ?
-		    "Can not write tiles to a stripped image" :
-		    "Can not write scanlines to a tiled image");
-		return (0);
-	}
-
-        _TIFFFillStriles( tif );
-        
-	/*
-	 * On the first write verify all the required information
-	 * has been setup and initialize any data structures that
-	 * had to wait until directory information was set.
-	 * Note that a lot of our work is assumed to remain valid
-	 * because we disallow any of the important parameters
-	 * from changing after we start writing (i.e. once
-	 * TIFF_BEENWRITING is set, TIFFSetField will only allow
-	 * the image's length to be changed).
-	 */
-	if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS)) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-		    "Must set \"ImageWidth\" before writing data");
-		return (0);
-	}
-	if (tif->tif_dir.td_samplesperpixel == 1) {
-		/* 
-		 * Planarconfiguration is irrelevant in case of single band
-		 * images and need not be included. We will set it anyway,
-		 * because this field is used in other parts of library even
-		 * in the single band case.
-		 */
-		if (!TIFFFieldSet(tif, FIELD_PLANARCONFIG))
-                    tif->tif_dir.td_planarconfig = PLANARCONFIG_CONTIG;
-	} else {
-		if (!TIFFFieldSet(tif, FIELD_PLANARCONFIG)) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-			    "Must set \"PlanarConfiguration\" before writing data");
-			return (0);
-		}
-	}
-	if (tif->tif_dir.td_stripoffset == NULL && !TIFFSetupStrips(tif)) {
-		tif->tif_dir.td_nstrips = 0;
-		TIFFErrorExt(tif->tif_clientdata, module, "No space for %s arrays",
-		    isTiled(tif) ? "tile" : "strip");
-		return (0);
-	}
-	if (isTiled(tif))
-	{
-		tif->tif_tilesize = TIFFTileSize(tif);
-		if (tif->tif_tilesize == 0)
-			return (0);
-	}
-	else
-		tif->tif_tilesize = (tmsize_t)(-1);
-	tif->tif_scanlinesize = TIFFScanlineSize(tif);
-	if (tif->tif_scanlinesize == 0)
-		return (0);
-	tif->tif_flags |= TIFF_BEENWRITING;
-	return (1);
-}
-
-/*
- * Setup the raw data buffer used for encoding.
- */
-int
-TIFFWriteBufferSetup(TIFF* tif, void* bp, tmsize_t size)
-{
-	static const char module[] = "TIFFWriteBufferSetup";
-
-	if (tif->tif_rawdata) {
-		if (tif->tif_flags & TIFF_MYBUFFER) {
-			_TIFFfree(tif->tif_rawdata);
-			tif->tif_flags &= ~TIFF_MYBUFFER;
-		}
-		tif->tif_rawdata = NULL;
-	}
-	if (size == (tmsize_t)(-1)) {
-		size = (isTiled(tif) ?
-		    tif->tif_tilesize : TIFFStripSize(tif));
-		/*
-		 * Make raw data buffer at least 8K
-		 */
-		if (size < 8*1024)
-			size = 8*1024;
-		bp = NULL;			/* NB: force malloc */
-	}
-	if (bp == NULL) {
-		bp = _TIFFmalloc(size);
-		if (bp == NULL) {
-			TIFFErrorExt(tif->tif_clientdata, module, "No space for output buffer");
-			return (0);
-		}
-		tif->tif_flags |= TIFF_MYBUFFER;
-	} else
-		tif->tif_flags &= ~TIFF_MYBUFFER;
-	tif->tif_rawdata = (uint8*) bp;
-	tif->tif_rawdatasize = size;
-	tif->tif_rawcc = 0;
-	tif->tif_rawcp = tif->tif_rawdata;
-	tif->tif_flags |= TIFF_BUFFERSETUP;
-	return (1);
-}
-
-/*
- * Grow the strip data structures by delta strips.
- */
-static int
-TIFFGrowStrips(TIFF* tif, uint32 delta, const char* module)
-{
-	TIFFDirectory *td = &tif->tif_dir;
-	uint64* new_stripoffset;
-	uint64* new_stripbytecount;
-
-	assert(td->td_planarconfig == PLANARCONFIG_CONTIG);
-	new_stripoffset = (uint64*)_TIFFrealloc(td->td_stripoffset,
-		(td->td_nstrips + delta) * sizeof (uint64));
-	new_stripbytecount = (uint64*)_TIFFrealloc(td->td_stripbytecount,
-		(td->td_nstrips + delta) * sizeof (uint64));
-	if (new_stripoffset == NULL || new_stripbytecount == NULL) {
-		if (new_stripoffset)
-			_TIFFfree(new_stripoffset);
-		if (new_stripbytecount)
-			_TIFFfree(new_stripbytecount);
-		td->td_nstrips = 0;
-		TIFFErrorExt(tif->tif_clientdata, module, "No space to expand strip arrays");
-		return (0);
-	}
-	td->td_stripoffset = new_stripoffset;
-	td->td_stripbytecount = new_stripbytecount;
-	_TIFFmemset(td->td_stripoffset + td->td_nstrips,
-		    0, delta*sizeof (uint64));
-	_TIFFmemset(td->td_stripbytecount + td->td_nstrips,
-		    0, delta*sizeof (uint64));
-	td->td_nstrips += delta;
-        tif->tif_flags |= TIFF_DIRTYDIRECT;
-
-	return (1);
-}
-
-/*
- * Append the data to the specified strip.
- */
-static int
-TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t cc)
-{
-	static const char module[] = "TIFFAppendToStrip";
-	TIFFDirectory *td = &tif->tif_dir;
-	uint64 m;
-        int64 old_byte_count = -1;
-
-	if (td->td_stripoffset[strip] == 0 || tif->tif_curoff == 0) {
-            assert(td->td_nstrips > 0);
-
-            if( td->td_stripbytecount[strip] != 0 
-                && td->td_stripoffset[strip] != 0 
-                && td->td_stripbytecount[strip] >= (uint64) cc )
-            {
-                /* 
-                 * There is already tile data on disk, and the new tile
-                 * data we have will fit in the same space.  The only 
-                 * aspect of this that is risky is that there could be
-                 * more data to append to this strip before we are done
-                 * depending on how we are getting called.
-                 */
-                if (!SeekOK(tif, td->td_stripoffset[strip])) {
-                    TIFFErrorExt(tif->tif_clientdata, module,
-                                 "Seek error at scanline %lu",
-                                 (unsigned long)tif->tif_row);
-                    return (0);
-                }
-            }
-            else
-            {
-                /* 
-                 * Seek to end of file, and set that as our location to 
-                 * write this strip.
-                 */
-                td->td_stripoffset[strip] = TIFFSeekFile(tif, 0, SEEK_END);
-                tif->tif_flags |= TIFF_DIRTYSTRIP;
-            }
-
-            tif->tif_curoff = td->td_stripoffset[strip];
-
-            /*
-             * We are starting a fresh strip/tile, so set the size to zero.
-             */
-            old_byte_count = td->td_stripbytecount[strip];
-            td->td_stripbytecount[strip] = 0;
-	}
-
-	m = tif->tif_curoff+cc;
-	if (!(tif->tif_flags&TIFF_BIGTIFF))
-		m = (uint32)m;
-	if ((m<tif->tif_curoff)||(m<(uint64)cc))
-	{
-		TIFFErrorExt(tif->tif_clientdata, module, "Maximum TIFF file size exceeded");
-		return (0);
-	}
-	if (!WriteOK(tif, data, cc)) {
-		TIFFErrorExt(tif->tif_clientdata, module, "Write error at scanline %lu",
-		    (unsigned long) tif->tif_row);
-		    return (0);
-	}
-	tif->tif_curoff = m;
-	td->td_stripbytecount[strip] += cc;
-
-        if( (int64) td->td_stripbytecount[strip] != old_byte_count )
-            tif->tif_flags |= TIFF_DIRTYSTRIP;
-            
-	return (1);
-}
-
-/*
- * Internal version of TIFFFlushData that can be
- * called by ``encodestrip routines'' w/o concern
- * for infinite recursion.
- */
-int
-TIFFFlushData1(TIFF* tif)
-{
-	if (tif->tif_rawcc > 0 && tif->tif_flags & TIFF_BUF4WRITE ) {
-		if (!isFillOrder(tif, tif->tif_dir.td_fillorder) &&
-		    (tif->tif_flags & TIFF_NOBITREV) == 0)
-			TIFFReverseBits((uint8*)tif->tif_rawdata,
-			    tif->tif_rawcc);
-		if (!TIFFAppendToStrip(tif,
-		    isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip,
-		    tif->tif_rawdata, tif->tif_rawcc))
-			return (0);
-		tif->tif_rawcc = 0;
-		tif->tif_rawcp = tif->tif_rawdata;
-	}
-	return (1);
-}
-
-/*
- * Set the current write offset.  This should only be
- * used to set the offset to a known previous location
- * (very carefully), or to 0 so that the next write gets
- * appended to the end of the file.
- */
-void
-TIFFSetWriteOffset(TIFF* tif, toff_t off)
-{
-	tif->tif_curoff = off;
-}
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Id: tif_write.c,v 1.11 2015/02/19 22:39:59 drolon Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Scanline-oriented Write Support
+ */
+#include "tiffiop.h"
+#include <stdio.h>
+
+#define STRIPINCR	20		/* expansion factor on strip array */
+
+#define WRITECHECKSTRIPS(tif, module)				\
+	(((tif)->tif_flags&TIFF_BEENWRITING) || TIFFWriteCheck((tif),0,module))
+#define WRITECHECKTILES(tif, module)				\
+	(((tif)->tif_flags&TIFF_BEENWRITING) || TIFFWriteCheck((tif),1,module))
+#define BUFFERCHECK(tif)					\
+	((((tif)->tif_flags & TIFF_BUFFERSETUP) && tif->tif_rawdata) ||	\
+	    TIFFWriteBufferSetup((tif), NULL, (tmsize_t) -1))
+
+static int TIFFGrowStrips(TIFF* tif, uint32 delta, const char* module);
+static int TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t cc);
+
+int
+TIFFWriteScanline(TIFF* tif, void* buf, uint32 row, uint16 sample)
+{
+	static const char module[] = "TIFFWriteScanline";
+	register TIFFDirectory *td;
+	int status, imagegrew = 0;
+	uint32 strip;
+
+	if (!WRITECHECKSTRIPS(tif, module))
+		return (-1);
+	/*
+	 * Handle delayed allocation of data buffer.  This
+	 * permits it to be sized more intelligently (using
+	 * directory information).
+	 */
+	if (!BUFFERCHECK(tif))
+		return (-1);
+        tif->tif_flags |= TIFF_BUF4WRITE; /* not strictly sure this is right*/
+
+	td = &tif->tif_dir;
+	/*
+	 * Extend image length if needed
+	 * (but only for PlanarConfig=1).
+	 */
+	if (row >= td->td_imagelength) {	/* extend image */
+		if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
+			TIFFErrorExt(tif->tif_clientdata, module,
+			    "Can not change \"ImageLength\" when using separate planes");
+			return (-1);
+		}
+		td->td_imagelength = row+1;
+		imagegrew = 1;
+	}
+	/*
+	 * Calculate strip and check for crossings.
+	 */
+	if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
+		if (sample >= td->td_samplesperpixel) {
+			TIFFErrorExt(tif->tif_clientdata, module,
+			    "%lu: Sample out of range, max %lu",
+			    (unsigned long) sample, (unsigned long) td->td_samplesperpixel);
+			return (-1);
+		}
+		strip = sample*td->td_stripsperimage + row/td->td_rowsperstrip;
+	} else
+		strip = row / td->td_rowsperstrip;
+	/*
+	 * Check strip array to make sure there's space. We don't support
+	 * dynamically growing files that have data organized in separate
+	 * bitplanes because it's too painful.  In that case we require that
+	 * the imagelength be set properly before the first write (so that the
+	 * strips array will be fully allocated above).
+	 */
+	if (strip >= td->td_nstrips && !TIFFGrowStrips(tif, 1, module))
+		return (-1);
+	if (strip != tif->tif_curstrip) {
+		/*
+		 * Changing strips -- flush any data present.
+		 */
+		if (!TIFFFlushData(tif))
+			return (-1);
+		tif->tif_curstrip = strip;
+		/*
+		 * Watch out for a growing image.  The value of strips/image
+		 * will initially be 1 (since it can't be deduced until the
+		 * imagelength is known).
+		 */
+		if (strip >= td->td_stripsperimage && imagegrew)
+			td->td_stripsperimage =
+			    TIFFhowmany_32(td->td_imagelength,td->td_rowsperstrip);
+		tif->tif_row =
+		    (strip % td->td_stripsperimage) * td->td_rowsperstrip;
+		if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
+			if (!(*tif->tif_setupencode)(tif))
+				return (-1);
+			tif->tif_flags |= TIFF_CODERSETUP;
+		}
+        
+		tif->tif_rawcc = 0;
+		tif->tif_rawcp = tif->tif_rawdata;
+
+		if( td->td_stripbytecount[strip] > 0 )
+		{
+			/* if we are writing over existing tiles, zero length */
+			td->td_stripbytecount[strip] = 0;
+
+			/* this forces TIFFAppendToStrip() to do a seek */
+			tif->tif_curoff = 0;
+		}
+
+		if (!(*tif->tif_preencode)(tif, sample))
+			return (-1);
+		tif->tif_flags |= TIFF_POSTENCODE;
+	}
+	/*
+	 * Ensure the write is either sequential or at the
+	 * beginning of a strip (or that we can randomly
+	 * access the data -- i.e. no encoding).
+	 */
+	if (row != tif->tif_row) {
+		if (row < tif->tif_row) {
+			/*
+			 * Moving backwards within the same strip:
+			 * backup to the start and then decode
+			 * forward (below).
+			 */
+			tif->tif_row = (strip % td->td_stripsperimage) *
+			    td->td_rowsperstrip;
+			tif->tif_rawcp = tif->tif_rawdata;
+		}
+		/*
+		 * Seek forward to the desired row.
+		 */
+		if (!(*tif->tif_seek)(tif, row - tif->tif_row))
+			return (-1);
+		tif->tif_row = row;
+	}
+
+	/* swab if needed - note that source buffer will be altered */
+	tif->tif_postdecode( tif, (uint8*) buf, tif->tif_scanlinesize );
+
+	status = (*tif->tif_encoderow)(tif, (uint8*) buf,
+	    tif->tif_scanlinesize, sample);
+
+        /* we are now poised at the beginning of the next row */
+	tif->tif_row = row + 1;
+	return (status);
+}
+
+/*
+ * Encode the supplied data and write it to the
+ * specified strip.
+ *
+ * NB: Image length must be setup before writing.
+ */
+tmsize_t
+TIFFWriteEncodedStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc)
+{
+	static const char module[] = "TIFFWriteEncodedStrip";
+	TIFFDirectory *td = &tif->tif_dir;
+	uint16 sample;
+
+	if (!WRITECHECKSTRIPS(tif, module))
+		return ((tmsize_t) -1);
+	/*
+	 * Check strip array to make sure there's space.
+	 * We don't support dynamically growing files that
+	 * have data organized in separate bitplanes because
+	 * it's too painful.  In that case we require that
+	 * the imagelength be set properly before the first
+	 * write (so that the strips array will be fully
+	 * allocated above).
+	 */
+	if (strip >= td->td_nstrips) {
+		if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
+			TIFFErrorExt(tif->tif_clientdata, module,
+			    "Can not grow image by strips when using separate planes");
+			return ((tmsize_t) -1);
+		}
+		if (!TIFFGrowStrips(tif, 1, module))
+			return ((tmsize_t) -1);
+		td->td_stripsperimage =
+		    TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip);  
+	}
+	/*
+	 * Handle delayed allocation of data buffer.  This
+	 * permits it to be sized according to the directory
+	 * info.
+	 */
+	if (!BUFFERCHECK(tif))
+		return ((tmsize_t) -1);
+
+        tif->tif_flags |= TIFF_BUF4WRITE;
+	tif->tif_curstrip = strip;
+
+	tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
+	if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
+		if (!(*tif->tif_setupencode)(tif))
+			return ((tmsize_t) -1);
+		tif->tif_flags |= TIFF_CODERSETUP;
+	}
+
+	if( td->td_stripbytecount[strip] > 0 )
+        {
+            /* Make sure that at the first attempt of rewriting the tile, we will have */
+            /* more bytes available in the output buffer than the previous byte count, */
+            /* so that TIFFAppendToStrip() will detect the overflow when it is called the first */
+            /* time if the new compressed tile is bigger than the older one. (GDAL #4771) */
+            if( tif->tif_rawdatasize <= (tmsize_t)td->td_stripbytecount[strip] )
+            {
+                if( !(TIFFWriteBufferSetup(tif, NULL,
+                    (tmsize_t)TIFFroundup_64((uint64)(td->td_stripbytecount[strip] + 1), 1024))) )
+                    return ((tmsize_t)(-1));
+            }
+
+	    /* Force TIFFAppendToStrip() to consider placing data at end
+               of file. */
+            tif->tif_curoff = 0;
+        }
+
+    tif->tif_rawcc = 0;
+    tif->tif_rawcp = tif->tif_rawdata;
+
+	tif->tif_flags &= ~TIFF_POSTENCODE;
+	sample = (uint16)(strip / td->td_stripsperimage);
+	if (!(*tif->tif_preencode)(tif, sample))
+		return ((tmsize_t) -1);
+
+        /* swab if needed - note that source buffer will be altered */
+	tif->tif_postdecode( tif, (uint8*) data, cc );
+
+	if (!(*tif->tif_encodestrip)(tif, (uint8*) data, cc, sample))
+		return (0);
+	if (!(*tif->tif_postencode)(tif))
+		return ((tmsize_t) -1);
+	if (!isFillOrder(tif, td->td_fillorder) &&
+	    (tif->tif_flags & TIFF_NOBITREV) == 0)
+		TIFFReverseBits(tif->tif_rawdata, tif->tif_rawcc);
+	if (tif->tif_rawcc > 0 &&
+	    !TIFFAppendToStrip(tif, strip, tif->tif_rawdata, tif->tif_rawcc))
+		return ((tmsize_t) -1);
+	tif->tif_rawcc = 0;
+	tif->tif_rawcp = tif->tif_rawdata;
+	return (cc);
+}
+
+/*
+ * Write the supplied data to the specified strip.
+ *
+ * NB: Image length must be setup before writing.
+ */
+tmsize_t
+TIFFWriteRawStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc)
+{
+	static const char module[] = "TIFFWriteRawStrip";
+	TIFFDirectory *td = &tif->tif_dir;
+
+	if (!WRITECHECKSTRIPS(tif, module))
+		return ((tmsize_t) -1);
+	/*
+	 * Check strip array to make sure there's space.
+	 * We don't support dynamically growing files that
+	 * have data organized in separate bitplanes because
+	 * it's too painful.  In that case we require that
+	 * the imagelength be set properly before the first
+	 * write (so that the strips array will be fully
+	 * allocated above).
+	 */
+	if (strip >= td->td_nstrips) {
+		if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
+			TIFFErrorExt(tif->tif_clientdata, module,
+			    "Can not grow image by strips when using separate planes");
+			return ((tmsize_t) -1);
+		}
+		/*
+		 * Watch out for a growing image.  The value of
+		 * strips/image will initially be 1 (since it
+		 * can't be deduced until the imagelength is known).
+		 */
+		if (strip >= td->td_stripsperimage)
+			td->td_stripsperimage =
+			    TIFFhowmany_32(td->td_imagelength,td->td_rowsperstrip);
+		if (!TIFFGrowStrips(tif, 1, module))
+			return ((tmsize_t) -1);
+	}
+	tif->tif_curstrip = strip;
+	tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
+	return (TIFFAppendToStrip(tif, strip, (uint8*) data, cc) ?
+	    cc : (tmsize_t) -1);
+}
+
+/*
+ * Write and compress a tile of data.  The
+ * tile is selected by the (x,y,z,s) coordinates.
+ */
+tmsize_t
+TIFFWriteTile(TIFF* tif, void* buf, uint32 x, uint32 y, uint32 z, uint16 s)
+{
+	if (!TIFFCheckTile(tif, x, y, z, s))
+		return ((tmsize_t)(-1));
+	/*
+	 * NB: A tile size of -1 is used instead of tif_tilesize knowing
+	 *     that TIFFWriteEncodedTile will clamp this to the tile size.
+	 *     This is done because the tile size may not be defined until
+	 *     after the output buffer is setup in TIFFWriteBufferSetup.
+	 */
+	return (TIFFWriteEncodedTile(tif,
+	    TIFFComputeTile(tif, x, y, z, s), buf, (tmsize_t)(-1)));
+}
+
+/*
+ * Encode the supplied data and write it to the
+ * specified tile.  There must be space for the
+ * data.  The function clamps individual writes
+ * to a tile to the tile size, but does not (and
+ * can not) check that multiple writes to the same
+ * tile do not write more than tile size data.
+ *
+ * NB: Image length must be setup before writing; this
+ *     interface does not support automatically growing
+ *     the image on each write (as TIFFWriteScanline does).
+ */
+tmsize_t
+TIFFWriteEncodedTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc)
+{
+	static const char module[] = "TIFFWriteEncodedTile";
+	TIFFDirectory *td;
+	uint16 sample;
+
+	if (!WRITECHECKTILES(tif, module))
+		return ((tmsize_t)(-1));
+	td = &tif->tif_dir;
+	if (tile >= td->td_nstrips) {
+		TIFFErrorExt(tif->tif_clientdata, module, "Tile %lu out of range, max %lu",
+		    (unsigned long) tile, (unsigned long) td->td_nstrips);
+		return ((tmsize_t)(-1));
+	}
+	/*
+	 * Handle delayed allocation of data buffer.  This
+	 * permits it to be sized more intelligently (using
+	 * directory information).
+	 */
+	if (!BUFFERCHECK(tif))
+		return ((tmsize_t)(-1));
+
+        tif->tif_flags |= TIFF_BUF4WRITE;
+	tif->tif_curtile = tile;
+
+	if( td->td_stripbytecount[tile] > 0 )
+        {
+            /* Make sure that at the first attempt of rewriting the tile, we will have */
+            /* more bytes available in the output buffer than the previous byte count, */
+            /* so that TIFFAppendToStrip() will detect the overflow when it is called the first */
+            /* time if the new compressed tile is bigger than the older one. (GDAL #4771) */
+            if( tif->tif_rawdatasize <= (tmsize_t) td->td_stripbytecount[tile] )
+            {
+                if( !(TIFFWriteBufferSetup(tif, NULL,
+                    (tmsize_t)TIFFroundup_64((uint64)(td->td_stripbytecount[tile] + 1), 1024))) )
+                    return ((tmsize_t)(-1));
+            }
+
+	    /* Force TIFFAppendToStrip() to consider placing data at end
+               of file. */
+            tif->tif_curoff = 0;
+        }
+
+	tif->tif_rawcc = 0;
+	tif->tif_rawcp = tif->tif_rawdata;
+
+	/* 
+	 * Compute tiles per row & per column to compute
+	 * current row and column
+	 */
+	tif->tif_row = (tile % TIFFhowmany_32(td->td_imagelength, td->td_tilelength))
+		* td->td_tilelength;
+	tif->tif_col = (tile % TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth))
+		* td->td_tilewidth;
+
+	if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
+		if (!(*tif->tif_setupencode)(tif))
+			return ((tmsize_t)(-1));
+		tif->tif_flags |= TIFF_CODERSETUP;
+	}
+	tif->tif_flags &= ~TIFF_POSTENCODE;
+	sample = (uint16)(tile/td->td_stripsperimage);
+	if (!(*tif->tif_preencode)(tif, sample))
+		return ((tmsize_t)(-1));
+	/*
+	 * Clamp write amount to the tile size.  This is mostly
+	 * done so that callers can pass in some large number
+	 * (e.g. -1) and have the tile size used instead.
+	 */
+	if ( cc < 1 || cc > tif->tif_tilesize)
+		cc = tif->tif_tilesize;
+
+        /* swab if needed - note that source buffer will be altered */
+	tif->tif_postdecode( tif, (uint8*) data, cc );
+
+	if (!(*tif->tif_encodetile)(tif, (uint8*) data, cc, sample))
+		return (0);
+	if (!(*tif->tif_postencode)(tif))
+		return ((tmsize_t)(-1));
+	if (!isFillOrder(tif, td->td_fillorder) &&
+	    (tif->tif_flags & TIFF_NOBITREV) == 0)
+		TIFFReverseBits((uint8*)tif->tif_rawdata, tif->tif_rawcc);
+	if (tif->tif_rawcc > 0 && !TIFFAppendToStrip(tif, tile,
+	    tif->tif_rawdata, tif->tif_rawcc))
+		return ((tmsize_t)(-1));
+	tif->tif_rawcc = 0;
+	tif->tif_rawcp = tif->tif_rawdata;
+	return (cc);
+}
+
+/*
+ * Write the supplied data to the specified strip.
+ * There must be space for the data; we don't check
+ * if strips overlap!
+ *
+ * NB: Image length must be setup before writing; this
+ *     interface does not support automatically growing
+ *     the image on each write (as TIFFWriteScanline does).
+ */
+tmsize_t
+TIFFWriteRawTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc)
+{
+	static const char module[] = "TIFFWriteRawTile";
+
+	if (!WRITECHECKTILES(tif, module))
+		return ((tmsize_t)(-1));
+	if (tile >= tif->tif_dir.td_nstrips) {
+		TIFFErrorExt(tif->tif_clientdata, module, "Tile %lu out of range, max %lu",
+		    (unsigned long) tile,
+		    (unsigned long) tif->tif_dir.td_nstrips);
+		return ((tmsize_t)(-1));
+	}
+	return (TIFFAppendToStrip(tif, tile, (uint8*) data, cc) ?
+	    cc : (tmsize_t)(-1));
+}
+
+#define	isUnspecified(tif, f) \
+    (TIFFFieldSet(tif,f) && (tif)->tif_dir.td_imagelength == 0)
+
+int
+TIFFSetupStrips(TIFF* tif)
+{
+	TIFFDirectory* td = &tif->tif_dir;
+
+	if (isTiled(tif))
+		td->td_stripsperimage =
+		    isUnspecified(tif, FIELD_TILEDIMENSIONS) ?
+			td->td_samplesperpixel : TIFFNumberOfTiles(tif);
+	else
+		td->td_stripsperimage =
+		    isUnspecified(tif, FIELD_ROWSPERSTRIP) ?
+			td->td_samplesperpixel : TIFFNumberOfStrips(tif);
+	td->td_nstrips = td->td_stripsperimage;
+	if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
+		td->td_stripsperimage /= td->td_samplesperpixel;
+	td->td_stripoffset = (uint64 *)
+	    _TIFFmalloc(td->td_nstrips * sizeof (uint64));
+	td->td_stripbytecount = (uint64 *)
+	    _TIFFmalloc(td->td_nstrips * sizeof (uint64));
+	if (td->td_stripoffset == NULL || td->td_stripbytecount == NULL)
+		return (0);
+	/*
+	 * Place data at the end-of-file
+	 * (by setting offsets to zero).
+	 */
+	_TIFFmemset(td->td_stripoffset, 0, td->td_nstrips*sizeof (uint64));
+	_TIFFmemset(td->td_stripbytecount, 0, td->td_nstrips*sizeof (uint64));
+	TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
+	TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
+	return (1);
+}
+#undef isUnspecified
+
+/*
+ * Verify file is writable and that the directory
+ * information is setup properly.  In doing the latter
+ * we also "freeze" the state of the directory so
+ * that important information is not changed.
+ */
+int
+TIFFWriteCheck(TIFF* tif, int tiles, const char* module)
+{
+	if (tif->tif_mode == O_RDONLY) {
+		TIFFErrorExt(tif->tif_clientdata, module, "File not open for writing");
+		return (0);
+	}
+	if (tiles ^ isTiled(tif)) {
+		TIFFErrorExt(tif->tif_clientdata, module, tiles ?
+		    "Can not write tiles to a stripped image" :
+		    "Can not write scanlines to a tiled image");
+		return (0);
+	}
+
+        _TIFFFillStriles( tif );
+        
+	/*
+	 * On the first write verify all the required information
+	 * has been setup and initialize any data structures that
+	 * had to wait until directory information was set.
+	 * Note that a lot of our work is assumed to remain valid
+	 * because we disallow any of the important parameters
+	 * from changing after we start writing (i.e. once
+	 * TIFF_BEENWRITING is set, TIFFSetField will only allow
+	 * the image's length to be changed).
+	 */
+	if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS)) {
+		TIFFErrorExt(tif->tif_clientdata, module,
+		    "Must set \"ImageWidth\" before writing data");
+		return (0);
+	}
+	if (tif->tif_dir.td_samplesperpixel == 1) {
+		/* 
+		 * Planarconfiguration is irrelevant in case of single band
+		 * images and need not be included. We will set it anyway,
+		 * because this field is used in other parts of library even
+		 * in the single band case.
+		 */
+		if (!TIFFFieldSet(tif, FIELD_PLANARCONFIG))
+                    tif->tif_dir.td_planarconfig = PLANARCONFIG_CONTIG;
+	} else {
+		if (!TIFFFieldSet(tif, FIELD_PLANARCONFIG)) {
+			TIFFErrorExt(tif->tif_clientdata, module,
+			    "Must set \"PlanarConfiguration\" before writing data");
+			return (0);
+		}
+	}
+	if (tif->tif_dir.td_stripoffset == NULL && !TIFFSetupStrips(tif)) {
+		tif->tif_dir.td_nstrips = 0;
+		TIFFErrorExt(tif->tif_clientdata, module, "No space for %s arrays",
+		    isTiled(tif) ? "tile" : "strip");
+		return (0);
+	}
+	if (isTiled(tif))
+	{
+		tif->tif_tilesize = TIFFTileSize(tif);
+		if (tif->tif_tilesize == 0)
+			return (0);
+	}
+	else
+		tif->tif_tilesize = (tmsize_t)(-1);
+	tif->tif_scanlinesize = TIFFScanlineSize(tif);
+	if (tif->tif_scanlinesize == 0)
+		return (0);
+	tif->tif_flags |= TIFF_BEENWRITING;
+	return (1);
+}
+
+/*
+ * Setup the raw data buffer used for encoding.
+ */
+int
+TIFFWriteBufferSetup(TIFF* tif, void* bp, tmsize_t size)
+{
+	static const char module[] = "TIFFWriteBufferSetup";
+
+	if (tif->tif_rawdata) {
+		if (tif->tif_flags & TIFF_MYBUFFER) {
+			_TIFFfree(tif->tif_rawdata);
+			tif->tif_flags &= ~TIFF_MYBUFFER;
+		}
+		tif->tif_rawdata = NULL;
+	}
+	if (size == (tmsize_t)(-1)) {
+		size = (isTiled(tif) ?
+		    tif->tif_tilesize : TIFFStripSize(tif));
+		/*
+		 * Make raw data buffer at least 8K
+		 */
+		if (size < 8*1024)
+			size = 8*1024;
+		bp = NULL;			/* NB: force malloc */
+	}
+	if (bp == NULL) {
+		bp = _TIFFmalloc(size);
+		if (bp == NULL) {
+			TIFFErrorExt(tif->tif_clientdata, module, "No space for output buffer");
+			return (0);
+		}
+		tif->tif_flags |= TIFF_MYBUFFER;
+	} else
+		tif->tif_flags &= ~TIFF_MYBUFFER;
+	tif->tif_rawdata = (uint8*) bp;
+	tif->tif_rawdatasize = size;
+	tif->tif_rawcc = 0;
+	tif->tif_rawcp = tif->tif_rawdata;
+	tif->tif_flags |= TIFF_BUFFERSETUP;
+	return (1);
+}
+
+/*
+ * Grow the strip data structures by delta strips.
+ */
+static int
+TIFFGrowStrips(TIFF* tif, uint32 delta, const char* module)
+{
+	TIFFDirectory *td = &tif->tif_dir;
+	uint64* new_stripoffset;
+	uint64* new_stripbytecount;
+
+	assert(td->td_planarconfig == PLANARCONFIG_CONTIG);
+	new_stripoffset = (uint64*)_TIFFrealloc(td->td_stripoffset,
+		(td->td_nstrips + delta) * sizeof (uint64));
+	new_stripbytecount = (uint64*)_TIFFrealloc(td->td_stripbytecount,
+		(td->td_nstrips + delta) * sizeof (uint64));
+	if (new_stripoffset == NULL || new_stripbytecount == NULL) {
+		if (new_stripoffset)
+			_TIFFfree(new_stripoffset);
+		if (new_stripbytecount)
+			_TIFFfree(new_stripbytecount);
+		td->td_nstrips = 0;
+		TIFFErrorExt(tif->tif_clientdata, module, "No space to expand strip arrays");
+		return (0);
+	}
+	td->td_stripoffset = new_stripoffset;
+	td->td_stripbytecount = new_stripbytecount;
+	_TIFFmemset(td->td_stripoffset + td->td_nstrips,
+		    0, delta*sizeof (uint64));
+	_TIFFmemset(td->td_stripbytecount + td->td_nstrips,
+		    0, delta*sizeof (uint64));
+	td->td_nstrips += delta;
+        tif->tif_flags |= TIFF_DIRTYDIRECT;
+
+	return (1);
+}
+
+/*
+ * Append the data to the specified strip.
+ */
+static int
+TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t cc)
+{
+	static const char module[] = "TIFFAppendToStrip";
+	TIFFDirectory *td = &tif->tif_dir;
+	uint64 m;
+        int64 old_byte_count = -1;
+
+	if (td->td_stripoffset[strip] == 0 || tif->tif_curoff == 0) {
+            assert(td->td_nstrips > 0);
+
+            if( td->td_stripbytecount[strip] != 0 
+                && td->td_stripoffset[strip] != 0 
+                && td->td_stripbytecount[strip] >= (uint64) cc )
+            {
+                /* 
+                 * There is already tile data on disk, and the new tile
+                 * data we have will fit in the same space.  The only 
+                 * aspect of this that is risky is that there could be
+                 * more data to append to this strip before we are done
+                 * depending on how we are getting called.
+                 */
+                if (!SeekOK(tif, td->td_stripoffset[strip])) {
+                    TIFFErrorExt(tif->tif_clientdata, module,
+                                 "Seek error at scanline %lu",
+                                 (unsigned long)tif->tif_row);
+                    return (0);
+                }
+            }
+            else
+            {
+                /* 
+                 * Seek to end of file, and set that as our location to 
+                 * write this strip.
+                 */
+                td->td_stripoffset[strip] = TIFFSeekFile(tif, 0, SEEK_END);
+                tif->tif_flags |= TIFF_DIRTYSTRIP;
+            }
+
+            tif->tif_curoff = td->td_stripoffset[strip];
+
+            /*
+             * We are starting a fresh strip/tile, so set the size to zero.
+             */
+            old_byte_count = td->td_stripbytecount[strip];
+            td->td_stripbytecount[strip] = 0;
+	}
+
+	m = tif->tif_curoff+cc;
+	if (!(tif->tif_flags&TIFF_BIGTIFF))
+		m = (uint32)m;
+	if ((m<tif->tif_curoff)||(m<(uint64)cc))
+	{
+		TIFFErrorExt(tif->tif_clientdata, module, "Maximum TIFF file size exceeded");
+		return (0);
+	}
+	if (!WriteOK(tif, data, cc)) {
+		TIFFErrorExt(tif->tif_clientdata, module, "Write error at scanline %lu",
+		    (unsigned long) tif->tif_row);
+		    return (0);
+	}
+	tif->tif_curoff = m;
+	td->td_stripbytecount[strip] += cc;
+
+        if( (int64) td->td_stripbytecount[strip] != old_byte_count )
+            tif->tif_flags |= TIFF_DIRTYSTRIP;
+            
+	return (1);
+}
+
+/*
+ * Internal version of TIFFFlushData that can be
+ * called by ``encodestrip routines'' w/o concern
+ * for infinite recursion.
+ */
+int
+TIFFFlushData1(TIFF* tif)
+{
+	if (tif->tif_rawcc > 0 && tif->tif_flags & TIFF_BUF4WRITE ) {
+		if (!isFillOrder(tif, tif->tif_dir.td_fillorder) &&
+		    (tif->tif_flags & TIFF_NOBITREV) == 0)
+			TIFFReverseBits((uint8*)tif->tif_rawdata,
+			    tif->tif_rawcc);
+		if (!TIFFAppendToStrip(tif,
+		    isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip,
+		    tif->tif_rawdata, tif->tif_rawcc))
+			return (0);
+		tif->tif_rawcc = 0;
+		tif->tif_rawcp = tif->tif_rawdata;
+	}
+	return (1);
+}
+
+/*
+ * Set the current write offset.  This should only be
+ * used to set the offset to a known previous location
+ * (very carefully), or to 0 so that the next write gets
+ * appended to the end of the file.
+ */
+void
+TIFFSetWriteOffset(TIFF* tif, toff_t off)
+{
+	tif->tif_curoff = off;
+}
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tif_zip.c b/Source/LibTIFF4/tif_zip.c
index a975d2c..fc560bf 100644
--- a/Source/LibTIFF4/tif_zip.c
+++ b/Source/LibTIFF4/tif_zip.c
@@ -1,469 +1,472 @@
-/* $Id: tif_zip.c,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * Copyright (c) 1995-1997 Sam Leffler
- * Copyright (c) 1995-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-#include "tiffiop.h"
-#ifdef ZIP_SUPPORT
-/*
- * TIFF Library.
- *
- * ZIP (aka Deflate) Compression Support
- *
- * This file is simply an interface to the zlib library written by
- * Jean-loup Gailly and Mark Adler.  You must use version 1.0 or later
- * of the library: this code assumes the 1.0 API and also depends on
- * the ability to write the zlib header multiple times (one per strip)
- * which was not possible with versions prior to 0.95.  Note also that
- * older versions of this codec avoided this bug by supressing the header
- * entirely.  This means that files written with the old library cannot
- * be read; they should be converted to a different compression scheme
- * and then reconverted.
- *
- * The data format used by the zlib library is described in the files
- * zlib-3.1.doc, deflate-1.1.doc and gzip-4.1.doc, available in the
- * directory ftp://ftp.uu.net/pub/archiving/zip/doc.  The library was
- * last found at ftp://ftp.uu.net/pub/archiving/zip/zlib/zlib-0.99.tar.gz.
- */
-#include "tif_predict.h"
-#include "../ZLib/zlib.h"
-
-#include <stdio.h>
-
-/*
- * Sigh, ZLIB_VERSION is defined as a string so there's no
- * way to do a proper check here.  Instead we guess based
- * on the presence of #defines that were added between the
- * 0.95 and 1.0 distributions.
- */
-#if !defined(Z_NO_COMPRESSION) || !defined(Z_DEFLATED)
-#error "Antiquated ZLIB software; you must use version 1.0 or later"
-#endif
-
-/*
- * State block for each open TIFF
- * file using ZIP compression/decompression.
- */
-typedef struct {
-	TIFFPredictorState predict;
-        z_stream        stream;
-	int             zipquality;            /* compression level */
-	int             state;                 /* state flags */
-#define ZSTATE_INIT_DECODE 0x01
-#define ZSTATE_INIT_ENCODE 0x02
-
-	TIFFVGetMethod  vgetparent;            /* super-class method */
-	TIFFVSetMethod  vsetparent;            /* super-class method */
-} ZIPState;
-
-#define ZState(tif)             ((ZIPState*) (tif)->tif_data)
-#define DecoderState(tif)       ZState(tif)
-#define EncoderState(tif)       ZState(tif)
-
-static int ZIPEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s);
-static int ZIPDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s);
-
-static int
-ZIPFixupTags(TIFF* tif)
-{
-	(void) tif;
-	return (1);
-}
-
-static int
-ZIPSetupDecode(TIFF* tif)
-{
-	static const char module[] = "ZIPSetupDecode";
-	ZIPState* sp = DecoderState(tif);
-
-	assert(sp != NULL);
-        
-        /* if we were last encoding, terminate this mode */
-	if (sp->state & ZSTATE_INIT_ENCODE) {
-	    deflateEnd(&sp->stream);
-	    sp->state = 0;
-	}
-
-	if (inflateInit(&sp->stream) != Z_OK) {
-		TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg);
-		return (0);
-	} else {
-		sp->state |= ZSTATE_INIT_DECODE;
-		return (1);
-	}
-}
-
-/*
- * Setup state for decoding a strip.
- */
-static int
-ZIPPreDecode(TIFF* tif, uint16 s)
-{
-	static const char module[] = "ZIPPreDecode";
-	ZIPState* sp = DecoderState(tif);
-
-	(void) s;
-	assert(sp != NULL);
-
-	if( (sp->state & ZSTATE_INIT_DECODE) == 0 )
-            tif->tif_setupdecode( tif );
-
-	sp->stream.next_in = tif->tif_rawdata;
-	assert(sizeof(sp->stream.avail_in)==4);  /* if this assert gets raised,
-	    we need to simplify this code to reflect a ZLib that is likely updated
-	    to deal with 8byte memory sizes, though this code will respond
-	    apropriately even before we simplify it */
-	sp->stream.avail_in = (uInt) tif->tif_rawcc;
-	if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc)
-	{
-		TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
-		return (0);
-	}
-	return (inflateReset(&sp->stream) == Z_OK);
-}
-
-static int
-ZIPDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
-{
-	static const char module[] = "ZIPDecode";
-	ZIPState* sp = DecoderState(tif);
-
-	(void) s;
-	assert(sp != NULL);
-	assert(sp->state == ZSTATE_INIT_DECODE);
-
-        sp->stream.next_in = tif->tif_rawcp;
-	sp->stream.avail_in = (uInt) tif->tif_rawcc;
-        
-	sp->stream.next_out = op;
-	assert(sizeof(sp->stream.avail_out)==4);  /* if this assert gets raised,
-	    we need to simplify this code to reflect a ZLib that is likely updated
-	    to deal with 8byte memory sizes, though this code will respond
-	    apropriately even before we simplify it */
-	sp->stream.avail_out = (uInt) occ;
-	if ((tmsize_t)sp->stream.avail_out != occ)
-	{
-		TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
-		return (0);
-	}
-	do {
-		int state = inflate(&sp->stream, Z_PARTIAL_FLUSH);
-		if (state == Z_STREAM_END)
-			break;
-		if (state == Z_DATA_ERROR) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-			    "Decoding error at scanline %lu, %s",
-			    (unsigned long) tif->tif_row, sp->stream.msg);
-			if (inflateSync(&sp->stream) != Z_OK)
-				return (0);
-			continue;
-		}
-		if (state != Z_OK) {
-			TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s",
-			    sp->stream.msg);
-			return (0);
-		}
-	} while (sp->stream.avail_out > 0);
-	if (sp->stream.avail_out != 0) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-		    "Not enough data at scanline %lu (short " TIFF_UINT64_FORMAT " bytes)",
-		    (unsigned long) tif->tif_row, (TIFF_UINT64_T) sp->stream.avail_out);
-		return (0);
-	}
-
-        tif->tif_rawcp = sp->stream.next_in;
-        tif->tif_rawcc = sp->stream.avail_in;
-
-	return (1);
-}
-
-static int
-ZIPSetupEncode(TIFF* tif)
-{
-	static const char module[] = "ZIPSetupEncode";
-	ZIPState* sp = EncoderState(tif);
-
-	assert(sp != NULL);
-	if (sp->state & ZSTATE_INIT_DECODE) {
-		inflateEnd(&sp->stream);
-		sp->state = 0;
-	}
-
-	if (deflateInit(&sp->stream, sp->zipquality) != Z_OK) {
-		TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg);
-		return (0);
-	} else {
-		sp->state |= ZSTATE_INIT_ENCODE;
-		return (1);
-	}
-}
-
-/*
- * Reset encoding state at the start of a strip.
- */
-static int
-ZIPPreEncode(TIFF* tif, uint16 s)
-{
-	static const char module[] = "ZIPPreEncode";
-	ZIPState *sp = EncoderState(tif);
-
-	(void) s;
-	assert(sp != NULL);
-	if( sp->state != ZSTATE_INIT_ENCODE )
-            tif->tif_setupencode( tif );
-
-	sp->stream.next_out = tif->tif_rawdata;
-	assert(sizeof(sp->stream.avail_out)==4);  /* if this assert gets raised,
-	    we need to simplify this code to reflect a ZLib that is likely updated
-	    to deal with 8byte memory sizes, though this code will respond
-	    apropriately even before we simplify it */
-	sp->stream.avail_out = tif->tif_rawdatasize;
-	if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize)
-	{
-		TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
-		return (0);
-	}
-	return (deflateReset(&sp->stream) == Z_OK);
-}
-
-/*
- * Encode a chunk of pixels.
- */
-static int
-ZIPEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
-{
-	static const char module[] = "ZIPEncode";
-	ZIPState *sp = EncoderState(tif);
-
-	assert(sp != NULL);
-	assert(sp->state == ZSTATE_INIT_ENCODE);
-
-	(void) s;
-	sp->stream.next_in = bp;
-	assert(sizeof(sp->stream.avail_in)==4);  /* if this assert gets raised,
-	    we need to simplify this code to reflect a ZLib that is likely updated
-	    to deal with 8byte memory sizes, though this code will respond
-	    apropriately even before we simplify it */
-	sp->stream.avail_in = (uInt) cc;
-	if ((tmsize_t)sp->stream.avail_in != cc)
-	{
-		TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
-		return (0);
-	}
-	do {
-		if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) {
-			TIFFErrorExt(tif->tif_clientdata, module, "Encoder error: %s",
-			    sp->stream.msg);
-			return (0);
-		}
-		if (sp->stream.avail_out == 0) {
-			tif->tif_rawcc = tif->tif_rawdatasize;
-			TIFFFlushData1(tif);
-			sp->stream.next_out = tif->tif_rawdata;
-			sp->stream.avail_out = (uInt) tif->tif_rawdatasize;  /* this is a safe typecast, as check is made already in ZIPPreEncode */
-		}
-	} while (sp->stream.avail_in > 0);
-	return (1);
-}
-
-/*
- * Finish off an encoded strip by flushing the last
- * string and tacking on an End Of Information code.
- */
-static int
-ZIPPostEncode(TIFF* tif)
-{
-	static const char module[] = "ZIPPostEncode";
-	ZIPState *sp = EncoderState(tif);
-	int state;
-
-	sp->stream.avail_in = 0;
-	do {
-		state = deflate(&sp->stream, Z_FINISH);
-		switch (state) {
-		case Z_STREAM_END:
-		case Z_OK:
-			if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize)
-			{
-				tif->tif_rawcc =  tif->tif_rawdatasize - sp->stream.avail_out;
-				TIFFFlushData1(tif);
-				sp->stream.next_out = tif->tif_rawdata;
-				sp->stream.avail_out = (uInt) tif->tif_rawdatasize;  /* this is a safe typecast, as check is made already in ZIPPreEncode */
-			}
-			break;
-		default:
-			TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s",
-			    sp->stream.msg);
-			return (0);
-		}
-	} while (state != Z_STREAM_END);
-	return (1);
-}
-
-static void
-ZIPCleanup(TIFF* tif)
-{
-	ZIPState* sp = ZState(tif);
-
-	assert(sp != 0);
-
-	(void)TIFFPredictorCleanup(tif);
-
-	tif->tif_tagmethods.vgetfield = sp->vgetparent;
-	tif->tif_tagmethods.vsetfield = sp->vsetparent;
-
-	if (sp->state & ZSTATE_INIT_ENCODE) {
-		deflateEnd(&sp->stream);
-		sp->state = 0;
-	} else if( sp->state & ZSTATE_INIT_DECODE) {
-		inflateEnd(&sp->stream);
-		sp->state = 0;
-	}
-	_TIFFfree(sp);
-	tif->tif_data = NULL;
-
-	_TIFFSetDefaultCompressionState(tif);
-}
-
-static int
-ZIPVSetField(TIFF* tif, uint32 tag, va_list ap)
-{
-	static const char module[] = "ZIPVSetField";
-	ZIPState* sp = ZState(tif);
-
-	switch (tag) {
-	case TIFFTAG_ZIPQUALITY:
-		sp->zipquality = (int) va_arg(ap, int);
-		if ( sp->state&ZSTATE_INIT_ENCODE ) {
-			if (deflateParams(&sp->stream,
-			    sp->zipquality, Z_DEFAULT_STRATEGY) != Z_OK) {
-				TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s",
-				    sp->stream.msg);
-				return (0);
-			}
-		}
-		return (1);
-	default:
-		return (*sp->vsetparent)(tif, tag, ap);
-	}
-	/*NOTREACHED*/
-}
-
-static int
-ZIPVGetField(TIFF* tif, uint32 tag, va_list ap)
-{
-	ZIPState* sp = ZState(tif);
-
-	switch (tag) {
-	case TIFFTAG_ZIPQUALITY:
-		*va_arg(ap, int*) = sp->zipquality;
-		break;
-	default:
-		return (*sp->vgetparent)(tif, tag, ap);
-	}
-	return (1);
-}
-
-static const TIFFField zipFields[] = {
-    { TIFFTAG_ZIPQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL },
-};
-
-int
-TIFFInitZIP(TIFF* tif, int scheme)
-{
-	static const char module[] = "TIFFInitZIP";
-	ZIPState* sp;
-
-	assert( (scheme == COMPRESSION_DEFLATE)
-		|| (scheme == COMPRESSION_ADOBE_DEFLATE));
-
-	/*
-	 * Merge codec-specific tag information.
-	 */
-	if (!_TIFFMergeFields(tif, zipFields, TIFFArrayCount(zipFields))) {
-		TIFFErrorExt(tif->tif_clientdata, module,
-			     "Merging Deflate codec-specific tags failed");
-		return 0;
-	}
-
-	/*
-	 * Allocate state block so tag methods have storage to record values.
-	 */
-	tif->tif_data = (uint8*) _TIFFmalloc(sizeof (ZIPState));
-	if (tif->tif_data == NULL)
-		goto bad;
-	sp = ZState(tif);
-	sp->stream.zalloc = NULL;
-	sp->stream.zfree = NULL;
-	sp->stream.opaque = NULL;
-	sp->stream.data_type = Z_BINARY;
-
-	/*
-	 * Override parent get/set field methods.
-	 */
-	sp->vgetparent = tif->tif_tagmethods.vgetfield;
-	tif->tif_tagmethods.vgetfield = ZIPVGetField; /* hook for codec tags */
-	sp->vsetparent = tif->tif_tagmethods.vsetfield;
-	tif->tif_tagmethods.vsetfield = ZIPVSetField; /* hook for codec tags */
-
-	/* Default values for codec-specific fields */
-	sp->zipquality = Z_DEFAULT_COMPRESSION;	/* default comp. level */
-	sp->state = 0;
-
-	/*
-	 * Install codec methods.
-	 */
-	tif->tif_fixuptags = ZIPFixupTags; 
-	tif->tif_setupdecode = ZIPSetupDecode;
-	tif->tif_predecode = ZIPPreDecode;
-	tif->tif_decoderow = ZIPDecode;
-	tif->tif_decodestrip = ZIPDecode;
-	tif->tif_decodetile = ZIPDecode;  
-	tif->tif_setupencode = ZIPSetupEncode;
-	tif->tif_preencode = ZIPPreEncode;
-	tif->tif_postencode = ZIPPostEncode;
-	tif->tif_encoderow = ZIPEncode;
-	tif->tif_encodestrip = ZIPEncode;
-	tif->tif_encodetile = ZIPEncode;
-	tif->tif_cleanup = ZIPCleanup;
-	/*
-	 * Setup predictor setup.
-	 */
-	(void) TIFFPredictorInit(tif);
-	return (1);
-bad:
-	TIFFErrorExt(tif->tif_clientdata, module,
-		     "No space for ZIP state block");
-	return (0);
-}
-#endif /* ZIP_SUPORT */
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Id: tif_zip.c,v 1.11 2015/02/19 22:39:59 drolon Exp $ */
+
+/*
+ * Copyright (c) 1995-1997 Sam Leffler
+ * Copyright (c) 1995-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and 
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
+ * 
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
+ * OF THIS SOFTWARE.
+ */
+
+#include "tiffiop.h"
+#ifdef ZIP_SUPPORT
+/*
+ * TIFF Library.
+ *
+ * ZIP (aka Deflate) Compression Support
+ *
+ * This file is simply an interface to the zlib library written by
+ * Jean-loup Gailly and Mark Adler.  You must use version 1.0 or later
+ * of the library: this code assumes the 1.0 API and also depends on
+ * the ability to write the zlib header multiple times (one per strip)
+ * which was not possible with versions prior to 0.95.  Note also that
+ * older versions of this codec avoided this bug by suppressing the header
+ * entirely.  This means that files written with the old library cannot
+ * be read; they should be converted to a different compression scheme
+ * and then reconverted.
+ *
+ * The data format used by the zlib library is described in the files
+ * zlib-3.1.doc, deflate-1.1.doc and gzip-4.1.doc, available in the
+ * directory ftp://ftp.uu.net/pub/archiving/zip/doc.  The library was
+ * last found at ftp://ftp.uu.net/pub/archiving/zip/zlib/zlib-0.99.tar.gz.
+ */
+#include "tif_predict.h"
+#include "../ZLib/zlib.h"
+
+#include <stdio.h>
+
+/*
+ * Sigh, ZLIB_VERSION is defined as a string so there's no
+ * way to do a proper check here.  Instead we guess based
+ * on the presence of #defines that were added between the
+ * 0.95 and 1.0 distributions.
+ */
+#if !defined(Z_NO_COMPRESSION) || !defined(Z_DEFLATED)
+#error "Antiquated ZLIB software; you must use version 1.0 or later"
+#endif
+
+#define SAFE_MSG(sp)   ((sp)->stream.msg == NULL ? "" : (sp)->stream.msg)
+
+/*
+ * State block for each open TIFF
+ * file using ZIP compression/decompression.
+ */
+typedef struct {
+	TIFFPredictorState predict;
+        z_stream        stream;
+	int             zipquality;            /* compression level */
+	int             state;                 /* state flags */
+#define ZSTATE_INIT_DECODE 0x01
+#define ZSTATE_INIT_ENCODE 0x02
+
+	TIFFVGetMethod  vgetparent;            /* super-class method */
+	TIFFVSetMethod  vsetparent;            /* super-class method */
+} ZIPState;
+
+#define ZState(tif)             ((ZIPState*) (tif)->tif_data)
+#define DecoderState(tif)       ZState(tif)
+#define EncoderState(tif)       ZState(tif)
+
+static int ZIPEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s);
+static int ZIPDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s);
+
+static int
+ZIPFixupTags(TIFF* tif)
+{
+	(void) tif;
+	return (1);
+}
+
+static int
+ZIPSetupDecode(TIFF* tif)
+{
+	static const char module[] = "ZIPSetupDecode";
+	ZIPState* sp = DecoderState(tif);
+
+	assert(sp != NULL);
+        
+        /* if we were last encoding, terminate this mode */
+	if (sp->state & ZSTATE_INIT_ENCODE) {
+	    deflateEnd(&sp->stream);
+	    sp->state = 0;
+	}
+
+	if (inflateInit(&sp->stream) != Z_OK) {
+		TIFFErrorExt(tif->tif_clientdata, module, "%s", SAFE_MSG(sp));
+		return (0);
+	} else {
+		sp->state |= ZSTATE_INIT_DECODE;
+		return (1);
+	}
+}
+
+/*
+ * Setup state for decoding a strip.
+ */
+static int
+ZIPPreDecode(TIFF* tif, uint16 s)
+{
+	static const char module[] = "ZIPPreDecode";
+	ZIPState* sp = DecoderState(tif);
+
+	(void) s;
+	assert(sp != NULL);
+
+	if( (sp->state & ZSTATE_INIT_DECODE) == 0 )
+            tif->tif_setupdecode( tif );
+
+	sp->stream.next_in = tif->tif_rawdata;
+	assert(sizeof(sp->stream.avail_in)==4);  /* if this assert gets raised,
+	    we need to simplify this code to reflect a ZLib that is likely updated
+	    to deal with 8byte memory sizes, though this code will respond
+	    apropriately even before we simplify it */
+	sp->stream.avail_in = (uInt) tif->tif_rawcc;
+	if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc)
+	{
+		TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
+		return (0);
+	}
+	return (inflateReset(&sp->stream) == Z_OK);
+}
+
+static int
+ZIPDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
+{
+	static const char module[] = "ZIPDecode";
+	ZIPState* sp = DecoderState(tif);
+
+	(void) s;
+	assert(sp != NULL);
+	assert(sp->state == ZSTATE_INIT_DECODE);
+
+        sp->stream.next_in = tif->tif_rawcp;
+	sp->stream.avail_in = (uInt) tif->tif_rawcc;
+        
+	sp->stream.next_out = op;
+	assert(sizeof(sp->stream.avail_out)==4);  /* if this assert gets raised,
+	    we need to simplify this code to reflect a ZLib that is likely updated
+	    to deal with 8byte memory sizes, though this code will respond
+	    apropriately even before we simplify it */
+	sp->stream.avail_out = (uInt) occ;
+	if ((tmsize_t)sp->stream.avail_out != occ)
+	{
+		TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
+		return (0);
+	}
+	do {
+		int state = inflate(&sp->stream, Z_PARTIAL_FLUSH);
+		if (state == Z_STREAM_END)
+			break;
+		if (state == Z_DATA_ERROR) {
+			TIFFErrorExt(tif->tif_clientdata, module,
+			    "Decoding error at scanline %lu, %s",
+			     (unsigned long) tif->tif_row, SAFE_MSG(sp));
+			if (inflateSync(&sp->stream) != Z_OK)
+				return (0);
+			continue;
+		}
+		if (state != Z_OK) {
+			TIFFErrorExt(tif->tif_clientdata, module, 
+				     "ZLib error: %s", SAFE_MSG(sp));
+			return (0);
+		}
+	} while (sp->stream.avail_out > 0);
+	if (sp->stream.avail_out != 0) {
+		TIFFErrorExt(tif->tif_clientdata, module,
+		    "Not enough data at scanline %lu (short " TIFF_UINT64_FORMAT " bytes)",
+		    (unsigned long) tif->tif_row, (TIFF_UINT64_T) sp->stream.avail_out);
+		return (0);
+	}
+
+        tif->tif_rawcp = sp->stream.next_in;
+        tif->tif_rawcc = sp->stream.avail_in;
+
+	return (1);
+}
+
+static int
+ZIPSetupEncode(TIFF* tif)
+{
+	static const char module[] = "ZIPSetupEncode";
+	ZIPState* sp = EncoderState(tif);
+
+	assert(sp != NULL);
+	if (sp->state & ZSTATE_INIT_DECODE) {
+		inflateEnd(&sp->stream);
+		sp->state = 0;
+	}
+
+	if (deflateInit(&sp->stream, sp->zipquality) != Z_OK) {
+		TIFFErrorExt(tif->tif_clientdata, module, "%s", SAFE_MSG(sp));
+		return (0);
+	} else {
+		sp->state |= ZSTATE_INIT_ENCODE;
+		return (1);
+	}
+}
+
+/*
+ * Reset encoding state at the start of a strip.
+ */
+static int
+ZIPPreEncode(TIFF* tif, uint16 s)
+{
+	static const char module[] = "ZIPPreEncode";
+	ZIPState *sp = EncoderState(tif);
+
+	(void) s;
+	assert(sp != NULL);
+	if( sp->state != ZSTATE_INIT_ENCODE )
+            tif->tif_setupencode( tif );
+
+	sp->stream.next_out = tif->tif_rawdata;
+	assert(sizeof(sp->stream.avail_out)==4);  /* if this assert gets raised,
+	    we need to simplify this code to reflect a ZLib that is likely updated
+	    to deal with 8byte memory sizes, though this code will respond
+	    apropriately even before we simplify it */
+	sp->stream.avail_out = tif->tif_rawdatasize;
+	if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize)
+	{
+		TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
+		return (0);
+	}
+	return (deflateReset(&sp->stream) == Z_OK);
+}
+
+/*
+ * Encode a chunk of pixels.
+ */
+static int
+ZIPEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
+{
+	static const char module[] = "ZIPEncode";
+	ZIPState *sp = EncoderState(tif);
+
+	assert(sp != NULL);
+	assert(sp->state == ZSTATE_INIT_ENCODE);
+
+	(void) s;
+	sp->stream.next_in = bp;
+	assert(sizeof(sp->stream.avail_in)==4);  /* if this assert gets raised,
+	    we need to simplify this code to reflect a ZLib that is likely updated
+	    to deal with 8byte memory sizes, though this code will respond
+	    apropriately even before we simplify it */
+	sp->stream.avail_in = (uInt) cc;
+	if ((tmsize_t)sp->stream.avail_in != cc)
+	{
+		TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
+		return (0);
+	}
+	do {
+		if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) {
+			TIFFErrorExt(tif->tif_clientdata, module, 
+				     "Encoder error: %s",
+				     SAFE_MSG(sp));
+			return (0);
+		}
+		if (sp->stream.avail_out == 0) {
+			tif->tif_rawcc = tif->tif_rawdatasize;
+			TIFFFlushData1(tif);
+			sp->stream.next_out = tif->tif_rawdata;
+			sp->stream.avail_out = (uInt) tif->tif_rawdatasize;  /* this is a safe typecast, as check is made already in ZIPPreEncode */
+		}
+	} while (sp->stream.avail_in > 0);
+	return (1);
+}
+
+/*
+ * Finish off an encoded strip by flushing the last
+ * string and tacking on an End Of Information code.
+ */
+static int
+ZIPPostEncode(TIFF* tif)
+{
+	static const char module[] = "ZIPPostEncode";
+	ZIPState *sp = EncoderState(tif);
+	int state;
+
+	sp->stream.avail_in = 0;
+	do {
+		state = deflate(&sp->stream, Z_FINISH);
+		switch (state) {
+		case Z_STREAM_END:
+		case Z_OK:
+			if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize)
+			{
+				tif->tif_rawcc =  tif->tif_rawdatasize - sp->stream.avail_out;
+				TIFFFlushData1(tif);
+				sp->stream.next_out = tif->tif_rawdata;
+				sp->stream.avail_out = (uInt) tif->tif_rawdatasize;  /* this is a safe typecast, as check is made already in ZIPPreEncode */
+			}
+			break;
+		default:
+			TIFFErrorExt(tif->tif_clientdata, module, 
+				     "ZLib error: %s", SAFE_MSG(sp));
+			return (0);
+		}
+	} while (state != Z_STREAM_END);
+	return (1);
+}
+
+static void
+ZIPCleanup(TIFF* tif)
+{
+	ZIPState* sp = ZState(tif);
+
+	assert(sp != 0);
+
+	(void)TIFFPredictorCleanup(tif);
+
+	tif->tif_tagmethods.vgetfield = sp->vgetparent;
+	tif->tif_tagmethods.vsetfield = sp->vsetparent;
+
+	if (sp->state & ZSTATE_INIT_ENCODE) {
+		deflateEnd(&sp->stream);
+		sp->state = 0;
+	} else if( sp->state & ZSTATE_INIT_DECODE) {
+		inflateEnd(&sp->stream);
+		sp->state = 0;
+	}
+	_TIFFfree(sp);
+	tif->tif_data = NULL;
+
+	_TIFFSetDefaultCompressionState(tif);
+}
+
+static int
+ZIPVSetField(TIFF* tif, uint32 tag, va_list ap)
+{
+	static const char module[] = "ZIPVSetField";
+	ZIPState* sp = ZState(tif);
+
+	switch (tag) {
+	case TIFFTAG_ZIPQUALITY:
+		sp->zipquality = (int) va_arg(ap, int);
+		if ( sp->state&ZSTATE_INIT_ENCODE ) {
+			if (deflateParams(&sp->stream,
+			    sp->zipquality, Z_DEFAULT_STRATEGY) != Z_OK) {
+				TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s",
+					     SAFE_MSG(sp));
+				return (0);
+			}
+		}
+		return (1);
+	default:
+		return (*sp->vsetparent)(tif, tag, ap);
+	}
+	/*NOTREACHED*/
+}
+
+static int
+ZIPVGetField(TIFF* tif, uint32 tag, va_list ap)
+{
+	ZIPState* sp = ZState(tif);
+
+	switch (tag) {
+	case TIFFTAG_ZIPQUALITY:
+		*va_arg(ap, int*) = sp->zipquality;
+		break;
+	default:
+		return (*sp->vgetparent)(tif, tag, ap);
+	}
+	return (1);
+}
+
+static const TIFFField zipFields[] = {
+    { TIFFTAG_ZIPQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL },
+};
+
+int
+TIFFInitZIP(TIFF* tif, int scheme)
+{
+	static const char module[] = "TIFFInitZIP";
+	ZIPState* sp;
+
+	assert( (scheme == COMPRESSION_DEFLATE)
+		|| (scheme == COMPRESSION_ADOBE_DEFLATE));
+
+	/*
+	 * Merge codec-specific tag information.
+	 */
+	if (!_TIFFMergeFields(tif, zipFields, TIFFArrayCount(zipFields))) {
+		TIFFErrorExt(tif->tif_clientdata, module,
+			     "Merging Deflate codec-specific tags failed");
+		return 0;
+	}
+
+	/*
+	 * Allocate state block so tag methods have storage to record values.
+	 */
+	tif->tif_data = (uint8*) _TIFFmalloc(sizeof (ZIPState));
+	if (tif->tif_data == NULL)
+		goto bad;
+	sp = ZState(tif);
+	sp->stream.zalloc = NULL;
+	sp->stream.zfree = NULL;
+	sp->stream.opaque = NULL;
+	sp->stream.data_type = Z_BINARY;
+
+	/*
+	 * Override parent get/set field methods.
+	 */
+	sp->vgetparent = tif->tif_tagmethods.vgetfield;
+	tif->tif_tagmethods.vgetfield = ZIPVGetField; /* hook for codec tags */
+	sp->vsetparent = tif->tif_tagmethods.vsetfield;
+	tif->tif_tagmethods.vsetfield = ZIPVSetField; /* hook for codec tags */
+
+	/* Default values for codec-specific fields */
+	sp->zipquality = Z_DEFAULT_COMPRESSION;	/* default comp. level */
+	sp->state = 0;
+
+	/*
+	 * Install codec methods.
+	 */
+	tif->tif_fixuptags = ZIPFixupTags; 
+	tif->tif_setupdecode = ZIPSetupDecode;
+	tif->tif_predecode = ZIPPreDecode;
+	tif->tif_decoderow = ZIPDecode;
+	tif->tif_decodestrip = ZIPDecode;
+	tif->tif_decodetile = ZIPDecode;  
+	tif->tif_setupencode = ZIPSetupEncode;
+	tif->tif_preencode = ZIPPreEncode;
+	tif->tif_postencode = ZIPPostEncode;
+	tif->tif_encoderow = ZIPEncode;
+	tif->tif_encodestrip = ZIPEncode;
+	tif->tif_encodetile = ZIPEncode;
+	tif->tif_cleanup = ZIPCleanup;
+	/*
+	 * Setup predictor setup.
+	 */
+	(void) TIFFPredictorInit(tif);
+	return (1);
+bad:
+	TIFFErrorExt(tif->tif_clientdata, module,
+		     "No space for ZIP state block");
+	return (0);
+}
+#endif /* ZIP_SUPORT */
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tiff.h b/Source/LibTIFF4/tiff.h
index f5317ed..9059e8a 100644
--- a/Source/LibTIFF4/tiff.h
+++ b/Source/LibTIFF4/tiff.h
@@ -1,678 +1,681 @@
-/* $Id: tiff.h,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-#ifndef _TIFF_
-#define	_TIFF_
-
-#include "tiffconf.h"
-
-/*
- * Tag Image File Format (TIFF)
- *
- * Based on Rev 6.0 from:
- *    Developer's Desk
- *    Aldus Corporation
- *    411 First Ave. South
- *    Suite 200
- *    Seattle, WA  98104
- *    206-622-5500
- *
- *    (http://partners.adobe.com/asn/developer/PDFS/TN/TIFF6.pdf)
- *
- * For BigTIFF design notes see the following links
- *    http://www.remotesensing.org/libtiff/bigtiffdesign.html
- *    http://www.awaresystems.be/imaging/tiff/bigtiff.html
- */
-
-#define TIFF_VERSION_CLASSIC 42
-#define TIFF_VERSION_BIG 43
-
-#define TIFF_BIGENDIAN      0x4d4d
-#define TIFF_LITTLEENDIAN   0x4949
-#define MDI_LITTLEENDIAN    0x5045
-#define MDI_BIGENDIAN       0x4550
-
-/*
- * Intrinsic data types required by the file format:
- *
- * 8-bit quantities     int8/uint8
- * 16-bit quantities    int16/uint16
- * 32-bit quantities    int32/uint32
- * 64-bit quantities    int64/uint64
- * strings              unsigned char*
- */
-
-typedef TIFF_INT8_T   int8;
-typedef TIFF_UINT8_T  uint8;
-
-typedef TIFF_INT16_T  int16;
-typedef TIFF_UINT16_T uint16;
-
-typedef TIFF_INT32_T  int32;
-typedef TIFF_UINT32_T uint32;
-
-typedef TIFF_INT64_T  int64;
-typedef TIFF_UINT64_T uint64;
-
-/*
- * Some types as promoted in a variable argument list
- * We use uint16_vap rather then directly using int, because this way
- * we document the type we actually want to pass through, conceptually,
- * rather then confusing the issue by merely stating the type it gets
- * promoted to
- */
-
-typedef int uint16_vap;
-
-/*
- * TIFF header.
- */
-typedef struct {
-	uint16 tiff_magic;      /* magic number (defines byte order) */
-	uint16 tiff_version;    /* TIFF version number */
-} TIFFHeaderCommon;
-typedef struct {
-	uint16 tiff_magic;      /* magic number (defines byte order) */
-	uint16 tiff_version;    /* TIFF version number */
-	uint32 tiff_diroff;     /* byte offset to first directory */
-} TIFFHeaderClassic;
-typedef struct {
-	uint16 tiff_magic;      /* magic number (defines byte order) */
-	uint16 tiff_version;    /* TIFF version number */
-	uint16 tiff_offsetsize; /* size of offsets, should be 8 */
-	uint16 tiff_unused;     /* unused word, should be 0 */
-	uint64 tiff_diroff;     /* byte offset to first directory */
-} TIFFHeaderBig;
-
-
-/*
- * NB: In the comments below,
- *  - items marked with a + are obsoleted by revision 5.0,
- *  - items marked with a ! are introduced in revision 6.0.
- *  - items marked with a % are introduced post revision 6.0.
- *  - items marked with a $ are obsoleted by revision 6.0.
- *  - items marked with a & are introduced by Adobe DNG specification.
- */
-
-/*
- * Tag data type information.
- *
- * Note: RATIONALs are the ratio of two 32-bit integer values.
- */
-typedef enum {
-	TIFF_NOTYPE = 0,      /* placeholder */
-	TIFF_BYTE = 1,        /* 8-bit unsigned integer */
-	TIFF_ASCII = 2,       /* 8-bit bytes w/ last byte null */
-	TIFF_SHORT = 3,       /* 16-bit unsigned integer */
-	TIFF_LONG = 4,        /* 32-bit unsigned integer */
-	TIFF_RATIONAL = 5,    /* 64-bit unsigned fraction */
-	TIFF_SBYTE = 6,       /* !8-bit signed integer */
-	TIFF_UNDEFINED = 7,   /* !8-bit untyped data */
-	TIFF_SSHORT = 8,      /* !16-bit signed integer */
-	TIFF_SLONG = 9,       /* !32-bit signed integer */
-	TIFF_SRATIONAL = 10,  /* !64-bit signed fraction */
-	TIFF_FLOAT = 11,      /* !32-bit IEEE floating point */
-	TIFF_DOUBLE = 12,     /* !64-bit IEEE floating point */
-	TIFF_IFD = 13,        /* %32-bit unsigned integer (offset) */
-	TIFF_LONG8 = 16,      /* BigTIFF 64-bit unsigned integer */
-	TIFF_SLONG8 = 17,     /* BigTIFF 64-bit signed integer */
-	TIFF_IFD8 = 18        /* BigTIFF 64-bit unsigned integer (offset) */
-} TIFFDataType;
-
-/*
- * TIFF Tag Definitions.
- */
-#define	TIFFTAG_SUBFILETYPE		254	/* subfile data descriptor */
-#define	    FILETYPE_REDUCEDIMAGE	0x1	/* reduced resolution version */
-#define	    FILETYPE_PAGE		0x2	/* one page of many */
-#define	    FILETYPE_MASK		0x4	/* transparency mask */
-#define	TIFFTAG_OSUBFILETYPE		255	/* +kind of data in subfile */
-#define	    OFILETYPE_IMAGE		1	/* full resolution image data */
-#define	    OFILETYPE_REDUCEDIMAGE	2	/* reduced size image data */
-#define	    OFILETYPE_PAGE		3	/* one page of many */
-#define	TIFFTAG_IMAGEWIDTH		256	/* image width in pixels */
-#define	TIFFTAG_IMAGELENGTH		257	/* image height in pixels */
-#define	TIFFTAG_BITSPERSAMPLE		258	/* bits per channel (sample) */
-#define	TIFFTAG_COMPRESSION		259	/* data compression technique */
-#define	    COMPRESSION_NONE		1	/* dump mode */
-#define	    COMPRESSION_CCITTRLE	2	/* CCITT modified Huffman RLE */
-#define	    COMPRESSION_CCITTFAX3	3	/* CCITT Group 3 fax encoding */
-#define     COMPRESSION_CCITT_T4        3       /* CCITT T.4 (TIFF 6 name) */
-#define	    COMPRESSION_CCITTFAX4	4	/* CCITT Group 4 fax encoding */
-#define     COMPRESSION_CCITT_T6        4       /* CCITT T.6 (TIFF 6 name) */
-#define	    COMPRESSION_LZW		5       /* Lempel-Ziv  & Welch */
-#define	    COMPRESSION_OJPEG		6	/* !6.0 JPEG */
-#define	    COMPRESSION_JPEG		7	/* %JPEG DCT compression */
-#define     COMPRESSION_T85			9	/* !TIFF/FX T.85 JBIG compression */
-#define     COMPRESSION_T43			10	/* !TIFF/FX T.43 colour by layered JBIG compression */
-#define	    COMPRESSION_NEXT		32766	/* NeXT 2-bit RLE */
-#define	    COMPRESSION_CCITTRLEW	32771	/* #1 w/ word alignment */
-#define	    COMPRESSION_PACKBITS	32773	/* Macintosh RLE */
-#define	    COMPRESSION_THUNDERSCAN	32809	/* ThunderScan RLE */
-/* codes 32895-32898 are reserved for ANSI IT8 TIFF/IT <dkelly at apago.com) */
-#define	    COMPRESSION_IT8CTPAD	32895   /* IT8 CT w/padding */
-#define	    COMPRESSION_IT8LW		32896   /* IT8 Linework RLE */
-#define	    COMPRESSION_IT8MP		32897   /* IT8 Monochrome picture */
-#define	    COMPRESSION_IT8BL		32898   /* IT8 Binary line art */
-/* compression codes 32908-32911 are reserved for Pixar */
-#define     COMPRESSION_PIXARFILM	32908   /* Pixar companded 10bit LZW */
-#define	    COMPRESSION_PIXARLOG	32909   /* Pixar companded 11bit ZIP */
-#define	    COMPRESSION_DEFLATE		32946	/* Deflate compression */
-#define     COMPRESSION_ADOBE_DEFLATE   8       /* Deflate compression,
-						   as recognized by Adobe */
-/* compression code 32947 is reserved for Oceana Matrix <dev at oceana.com> */
-#define     COMPRESSION_DCS             32947   /* Kodak DCS encoding */
-#define	    COMPRESSION_JBIG		34661	/* ISO JBIG */
-#define     COMPRESSION_SGILOG		34676	/* SGI Log Luminance RLE */
-#define     COMPRESSION_SGILOG24	34677	/* SGI Log 24-bit packed */
-#define     COMPRESSION_JP2000          34712   /* Leadtools JPEG2000 */
-#define	    COMPRESSION_LZMA		34925	/* LZMA2 */
-#define	TIFFTAG_PHOTOMETRIC		262	/* photometric interpretation */
-#define	    PHOTOMETRIC_MINISWHITE	0	/* min value is white */
-#define	    PHOTOMETRIC_MINISBLACK	1	/* min value is black */
-#define	    PHOTOMETRIC_RGB		2	/* RGB color model */
-#define	    PHOTOMETRIC_PALETTE		3	/* color map indexed */
-#define	    PHOTOMETRIC_MASK		4	/* $holdout mask */
-#define	    PHOTOMETRIC_SEPARATED	5	/* !color separations */
-#define	    PHOTOMETRIC_YCBCR		6	/* !CCIR 601 */
-#define	    PHOTOMETRIC_CIELAB		8	/* !1976 CIE L*a*b* */
-#define	    PHOTOMETRIC_ICCLAB		9	/* ICC L*a*b* [Adobe TIFF Technote 4] */
-#define	    PHOTOMETRIC_ITULAB		10	/* ITU L*a*b* */
-#define     PHOTOMETRIC_LOGL		32844	/* CIE Log2(L) */
-#define     PHOTOMETRIC_LOGLUV		32845	/* CIE Log2(L) (u',v') */
-#define	TIFFTAG_THRESHHOLDING		263	/* +thresholding used on data */
-#define	    THRESHHOLD_BILEVEL		1	/* b&w art scan */
-#define	    THRESHHOLD_HALFTONE		2	/* or dithered scan */
-#define	    THRESHHOLD_ERRORDIFFUSE	3	/* usually floyd-steinberg */
-#define	TIFFTAG_CELLWIDTH		264	/* +dithering matrix width */
-#define	TIFFTAG_CELLLENGTH		265	/* +dithering matrix height */
-#define	TIFFTAG_FILLORDER		266	/* data order within a byte */
-#define	    FILLORDER_MSB2LSB		1	/* most significant -> least */
-#define	    FILLORDER_LSB2MSB		2	/* least significant -> most */
-#define	TIFFTAG_DOCUMENTNAME		269	/* name of doc. image is from */
-#define	TIFFTAG_IMAGEDESCRIPTION	270	/* info about image */
-#define	TIFFTAG_MAKE			271	/* scanner manufacturer name */
-#define	TIFFTAG_MODEL			272	/* scanner model name/number */
-#define	TIFFTAG_STRIPOFFSETS		273	/* offsets to data strips */
-#define	TIFFTAG_ORIENTATION		274	/* +image orientation */
-#define	    ORIENTATION_TOPLEFT		1	/* row 0 top, col 0 lhs */
-#define	    ORIENTATION_TOPRIGHT	2	/* row 0 top, col 0 rhs */
-#define	    ORIENTATION_BOTRIGHT	3	/* row 0 bottom, col 0 rhs */
-#define	    ORIENTATION_BOTLEFT		4	/* row 0 bottom, col 0 lhs */
-#define	    ORIENTATION_LEFTTOP		5	/* row 0 lhs, col 0 top */
-#define	    ORIENTATION_RIGHTTOP	6	/* row 0 rhs, col 0 top */
-#define	    ORIENTATION_RIGHTBOT	7	/* row 0 rhs, col 0 bottom */
-#define	    ORIENTATION_LEFTBOT		8	/* row 0 lhs, col 0 bottom */
-#define	TIFFTAG_SAMPLESPERPIXEL		277	/* samples per pixel */
-#define	TIFFTAG_ROWSPERSTRIP		278	/* rows per strip of data */
-#define	TIFFTAG_STRIPBYTECOUNTS		279	/* bytes counts for strips */
-#define	TIFFTAG_MINSAMPLEVALUE		280	/* +minimum sample value */
-#define	TIFFTAG_MAXSAMPLEVALUE		281	/* +maximum sample value */
-#define	TIFFTAG_XRESOLUTION		282	/* pixels/resolution in x */
-#define	TIFFTAG_YRESOLUTION		283	/* pixels/resolution in y */
-#define	TIFFTAG_PLANARCONFIG		284	/* storage organization */
-#define	    PLANARCONFIG_CONTIG		1	/* single image plane */
-#define	    PLANARCONFIG_SEPARATE	2	/* separate planes of data */
-#define	TIFFTAG_PAGENAME		285	/* page name image is from */
-#define	TIFFTAG_XPOSITION		286	/* x page offset of image lhs */
-#define	TIFFTAG_YPOSITION		287	/* y page offset of image lhs */
-#define	TIFFTAG_FREEOFFSETS		288	/* +byte offset to free block */
-#define	TIFFTAG_FREEBYTECOUNTS		289	/* +sizes of free blocks */
-#define	TIFFTAG_GRAYRESPONSEUNIT	290	/* $gray scale curve accuracy */
-#define	    GRAYRESPONSEUNIT_10S	1	/* tenths of a unit */
-#define	    GRAYRESPONSEUNIT_100S	2	/* hundredths of a unit */
-#define	    GRAYRESPONSEUNIT_1000S	3	/* thousandths of a unit */
-#define	    GRAYRESPONSEUNIT_10000S	4	/* ten-thousandths of a unit */
-#define	    GRAYRESPONSEUNIT_100000S	5	/* hundred-thousandths */
-#define	TIFFTAG_GRAYRESPONSECURVE	291	/* $gray scale response curve */
-#define	TIFFTAG_GROUP3OPTIONS		292	/* 32 flag bits */
-#define	TIFFTAG_T4OPTIONS		292	/* TIFF 6.0 proper name alias */
-#define	    GROUP3OPT_2DENCODING	0x1	/* 2-dimensional coding */
-#define	    GROUP3OPT_UNCOMPRESSED	0x2	/* data not compressed */
-#define	    GROUP3OPT_FILLBITS		0x4	/* fill to byte boundary */
-#define	TIFFTAG_GROUP4OPTIONS		293	/* 32 flag bits */
-#define TIFFTAG_T6OPTIONS               293     /* TIFF 6.0 proper name */
-#define	    GROUP4OPT_UNCOMPRESSED	0x2	/* data not compressed */
-#define	TIFFTAG_RESOLUTIONUNIT		296	/* units of resolutions */
-#define	    RESUNIT_NONE		1	/* no meaningful units */
-#define	    RESUNIT_INCH		2	/* english */
-#define	    RESUNIT_CENTIMETER		3	/* metric */
-#define	TIFFTAG_PAGENUMBER		297	/* page numbers of multi-page */
-#define	TIFFTAG_COLORRESPONSEUNIT	300	/* $color curve accuracy */
-#define	    COLORRESPONSEUNIT_10S	1	/* tenths of a unit */
-#define	    COLORRESPONSEUNIT_100S	2	/* hundredths of a unit */
-#define	    COLORRESPONSEUNIT_1000S	3	/* thousandths of a unit */
-#define	    COLORRESPONSEUNIT_10000S	4	/* ten-thousandths of a unit */
-#define	    COLORRESPONSEUNIT_100000S	5	/* hundred-thousandths */
-#define	TIFFTAG_TRANSFERFUNCTION	301	/* !colorimetry info */
-#define	TIFFTAG_SOFTWARE		305	/* name & release */
-#define	TIFFTAG_DATETIME		306	/* creation date and time */
-#define	TIFFTAG_ARTIST			315	/* creator of image */
-#define	TIFFTAG_HOSTCOMPUTER		316	/* machine where created */
-#define	TIFFTAG_PREDICTOR		317	/* prediction scheme w/ LZW */
-#define     PREDICTOR_NONE		1	/* no prediction scheme used */
-#define     PREDICTOR_HORIZONTAL	2	/* horizontal differencing */
-#define     PREDICTOR_FLOATINGPOINT	3	/* floating point predictor */
-#define	TIFFTAG_WHITEPOINT		318	/* image white point */
-#define	TIFFTAG_PRIMARYCHROMATICITIES	319	/* !primary chromaticities */
-#define	TIFFTAG_COLORMAP		320	/* RGB map for pallette image */
-#define	TIFFTAG_HALFTONEHINTS		321	/* !highlight+shadow info */
-#define	TIFFTAG_TILEWIDTH		322	/* !tile width in pixels */
-#define	TIFFTAG_TILELENGTH		323	/* !tile height in pixels */
-#define TIFFTAG_TILEOFFSETS		324	/* !offsets to data tiles */
-#define TIFFTAG_TILEBYTECOUNTS		325	/* !byte counts for tiles */
-#define	TIFFTAG_BADFAXLINES		326	/* lines w/ wrong pixel count */
-#define	TIFFTAG_CLEANFAXDATA		327	/* regenerated line info */
-#define	    CLEANFAXDATA_CLEAN		0	/* no errors detected */
-#define	    CLEANFAXDATA_REGENERATED	1	/* receiver regenerated lines */
-#define	    CLEANFAXDATA_UNCLEAN	2	/* uncorrected errors exist */
-#define	TIFFTAG_CONSECUTIVEBADFAXLINES	328	/* max consecutive bad lines */
-#define	TIFFTAG_SUBIFD			330	/* subimage descriptors */
-#define	TIFFTAG_INKSET			332	/* !inks in separated image */
-#define	    INKSET_CMYK			1	/* !cyan-magenta-yellow-black color */
-#define	    INKSET_MULTIINK		2	/* !multi-ink or hi-fi color */
-#define	TIFFTAG_INKNAMES		333	/* !ascii names of inks */
-#define	TIFFTAG_NUMBEROFINKS		334	/* !number of inks */
-#define	TIFFTAG_DOTRANGE		336	/* !0% and 100% dot codes */
-#define	TIFFTAG_TARGETPRINTER		337	/* !separation target */
-#define	TIFFTAG_EXTRASAMPLES		338	/* !info about extra samples */
-#define	    EXTRASAMPLE_UNSPECIFIED	0	/* !unspecified data */
-#define	    EXTRASAMPLE_ASSOCALPHA	1	/* !associated alpha data */
-#define	    EXTRASAMPLE_UNASSALPHA	2	/* !unassociated alpha data */
-#define	TIFFTAG_SAMPLEFORMAT		339	/* !data sample format */
-#define	    SAMPLEFORMAT_UINT		1	/* !unsigned integer data */
-#define	    SAMPLEFORMAT_INT		2	/* !signed integer data */
-#define	    SAMPLEFORMAT_IEEEFP		3	/* !IEEE floating point data */
-#define	    SAMPLEFORMAT_VOID		4	/* !untyped data */
-#define	    SAMPLEFORMAT_COMPLEXINT	5	/* !complex signed int */
-#define	    SAMPLEFORMAT_COMPLEXIEEEFP	6	/* !complex ieee floating */
-#define	TIFFTAG_SMINSAMPLEVALUE		340	/* !variable MinSampleValue */
-#define	TIFFTAG_SMAXSAMPLEVALUE		341	/* !variable MaxSampleValue */
-#define	TIFFTAG_CLIPPATH		343	/* %ClipPath
-						   [Adobe TIFF technote 2] */
-#define	TIFFTAG_XCLIPPATHUNITS		344	/* %XClipPathUnits
-						   [Adobe TIFF technote 2] */
-#define	TIFFTAG_YCLIPPATHUNITS		345	/* %YClipPathUnits
-						   [Adobe TIFF technote 2] */
-#define	TIFFTAG_INDEXED			346	/* %Indexed
-						   [Adobe TIFF Technote 3] */
-#define	TIFFTAG_JPEGTABLES		347	/* %JPEG table stream */
-#define	TIFFTAG_OPIPROXY		351	/* %OPI Proxy [Adobe TIFF technote] */
-/* Tags 400-435 are from the TIFF/FX spec */
-#define TIFFTAG_GLOBALPARAMETERSIFD	400	/* ! */
-#define TIFFTAG_PROFILETYPE			401	/* ! */
-#define     PROFILETYPE_UNSPECIFIED	0	/* ! */
-#define     PROFILETYPE_G3_FAX		1	/* ! */
-#define TIFFTAG_FAXPROFILE			402	/* ! */
-#define     FAXPROFILE_S			1	/* !TIFF/FX FAX profile S */
-#define     FAXPROFILE_F			2	/* !TIFF/FX FAX profile F */
-#define     FAXPROFILE_J			3	/* !TIFF/FX FAX profile J */
-#define     FAXPROFILE_C			4	/* !TIFF/FX FAX profile C */
-#define     FAXPROFILE_L			5	/* !TIFF/FX FAX profile L */
-#define     FAXPROFILE_M			6	/* !TIFF/FX FAX profile LM */
-#define TIFFTAG_CODINGMETHODS		403	/* !TIFF/FX coding methods */
-#define     CODINGMETHODS_T4_1D		(1 << 1)	/* !T.4 1D */
-#define     CODINGMETHODS_T4_2D		(1 << 2)	/* !T.4 2D */
-#define     CODINGMETHODS_T6		(1 << 3)	/* !T.6 */
-#define     CODINGMETHODS_T85 		(1 << 4)	/* !T.85 JBIG */
-#define     CODINGMETHODS_T42 		(1 << 5)	/* !T.42 JPEG */
-#define     CODINGMETHODS_T43		(1 << 6)	/* !T.43 colour by layered JBIG */
-#define TIFFTAG_VERSIONYEAR			404	/* !TIFF/FX version year */
-#define TIFFTAG_MODENUMBER			405	/* !TIFF/FX mode number */
-#define TIFFTAG_DECODE				433	/* !TIFF/FX decode */
-#define TIFFTAG_IMAGEBASECOLOR		434	/* !TIFF/FX image base colour */
-#define TIFFTAG_T82OPTIONS			435	/* !TIFF/FX T.82 options */
-/*
- * Tags 512-521 are obsoleted by Technical Note #2 which specifies a
- * revised JPEG-in-TIFF scheme.
- */
-#define	TIFFTAG_JPEGPROC		512	/* !JPEG processing algorithm */
-#define	    JPEGPROC_BASELINE		1	/* !baseline sequential */
-#define	    JPEGPROC_LOSSLESS		14	/* !Huffman coded lossless */
-#define	TIFFTAG_JPEGIFOFFSET		513	/* !pointer to SOI marker */
-#define	TIFFTAG_JPEGIFBYTECOUNT		514	/* !JFIF stream length */
-#define	TIFFTAG_JPEGRESTARTINTERVAL	515	/* !restart interval length */
-#define	TIFFTAG_JPEGLOSSLESSPREDICTORS	517	/* !lossless proc predictor */
-#define	TIFFTAG_JPEGPOINTTRANSFORM	518	/* !lossless point transform */
-#define	TIFFTAG_JPEGQTABLES		519	/* !Q matrice offsets */
-#define	TIFFTAG_JPEGDCTABLES		520	/* !DCT table offsets */
-#define	TIFFTAG_JPEGACTABLES		521	/* !AC coefficient offsets */
-#define	TIFFTAG_YCBCRCOEFFICIENTS	529	/* !RGB -> YCbCr transform */
-#define	TIFFTAG_YCBCRSUBSAMPLING	530	/* !YCbCr subsampling factors */
-#define	TIFFTAG_YCBCRPOSITIONING	531	/* !subsample positioning */
-#define	    YCBCRPOSITION_CENTERED	1	/* !as in PostScript Level 2 */
-#define	    YCBCRPOSITION_COSITED	2	/* !as in CCIR 601-1 */
-#define	TIFFTAG_REFERENCEBLACKWHITE	532	/* !colorimetry info */
-#define TIFFTAG_STRIPROWCOUNTS		559 /* !TIFF/FX strip row counts */
-#define	TIFFTAG_XMLPACKET		700	/* %XML packet
-						   [Adobe XMP Specification,
-						   January 2004 */
-#define TIFFTAG_OPIIMAGEID		32781	/* %OPI ImageID
-						   [Adobe TIFF technote] */
-/* tags 32952-32956 are private tags registered to Island Graphics */
-#define TIFFTAG_REFPTS			32953	/* image reference points */
-#define TIFFTAG_REGIONTACKPOINT		32954	/* region-xform tack point */
-#define TIFFTAG_REGIONWARPCORNERS	32955	/* warp quadrilateral */
-#define TIFFTAG_REGIONAFFINE		32956	/* affine transformation mat */
-/* tags 32995-32999 are private tags registered to SGI */
-#define	TIFFTAG_MATTEING		32995	/* $use ExtraSamples */
-#define	TIFFTAG_DATATYPE		32996	/* $use SampleFormat */
-#define	TIFFTAG_IMAGEDEPTH		32997	/* z depth of image */
-#define	TIFFTAG_TILEDEPTH		32998	/* z depth/data tile */
-/* tags 33300-33309 are private tags registered to Pixar */
-/*
- * TIFFTAG_PIXAR_IMAGEFULLWIDTH and TIFFTAG_PIXAR_IMAGEFULLLENGTH
- * are set when an image has been cropped out of a larger image.  
- * They reflect the size of the original uncropped image.
- * The TIFFTAG_XPOSITION and TIFFTAG_YPOSITION can be used
- * to determine the position of the smaller image in the larger one.
- */
-#define TIFFTAG_PIXAR_IMAGEFULLWIDTH    33300   /* full image size in x */
-#define TIFFTAG_PIXAR_IMAGEFULLLENGTH   33301   /* full image size in y */
- /* Tags 33302-33306 are used to identify special image modes and data
-  * used by Pixar's texture formats.
-  */
-#define TIFFTAG_PIXAR_TEXTUREFORMAT	33302	/* texture map format */
-#define TIFFTAG_PIXAR_WRAPMODES		33303	/* s & t wrap modes */
-#define TIFFTAG_PIXAR_FOVCOT		33304	/* cotan(fov) for env. maps */
-#define TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN 33305
-#define TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA 33306
-/* tag 33405 is a private tag registered to Eastman Kodak */
-#define TIFFTAG_WRITERSERIALNUMBER      33405   /* device serial number */
-/* tag 33432 is listed in the 6.0 spec w/ unknown ownership */
-#define	TIFFTAG_COPYRIGHT		33432	/* copyright string */
-/* IPTC TAG from RichTIFF specifications */
-#define TIFFTAG_RICHTIFFIPTC		33723
-/* 34016-34029 are reserved for ANSI IT8 TIFF/IT <dkelly at apago.com) */
-#define TIFFTAG_IT8SITE			34016	/* site name */
-#define TIFFTAG_IT8COLORSEQUENCE	34017	/* color seq. [RGB,CMYK,etc] */
-#define TIFFTAG_IT8HEADER		34018	/* DDES Header */
-#define TIFFTAG_IT8RASTERPADDING	34019	/* raster scanline padding */
-#define TIFFTAG_IT8BITSPERRUNLENGTH	34020	/* # of bits in short run */
-#define TIFFTAG_IT8BITSPEREXTENDEDRUNLENGTH 34021/* # of bits in long run */
-#define TIFFTAG_IT8COLORTABLE		34022	/* LW colortable */
-#define TIFFTAG_IT8IMAGECOLORINDICATOR	34023	/* BP/BL image color switch */
-#define TIFFTAG_IT8BKGCOLORINDICATOR	34024	/* BP/BL bg color switch */
-#define TIFFTAG_IT8IMAGECOLORVALUE	34025	/* BP/BL image color value */
-#define TIFFTAG_IT8BKGCOLORVALUE	34026	/* BP/BL bg color value */
-#define TIFFTAG_IT8PIXELINTENSITYRANGE	34027	/* MP pixel intensity value */
-#define TIFFTAG_IT8TRANSPARENCYINDICATOR 34028	/* HC transparency switch */
-#define TIFFTAG_IT8COLORCHARACTERIZATION 34029	/* color character. table */
-#define TIFFTAG_IT8HCUSAGE		34030	/* HC usage indicator */
-#define TIFFTAG_IT8TRAPINDICATOR	34031	/* Trapping indicator
-						   (untrapped=0, trapped=1) */
-#define TIFFTAG_IT8CMYKEQUIVALENT	34032	/* CMYK color equivalents */
-/* tags 34232-34236 are private tags registered to Texas Instruments */
-#define TIFFTAG_FRAMECOUNT              34232   /* Sequence Frame Count */
-/* tag 34377 is private tag registered to Adobe for PhotoShop */
-#define TIFFTAG_PHOTOSHOP		34377 
-/* tags 34665, 34853 and 40965 are documented in EXIF specification */
-#define TIFFTAG_EXIFIFD			34665	/* Pointer to EXIF private directory */
-/* tag 34750 is a private tag registered to Adobe? */
-#define TIFFTAG_ICCPROFILE		34675	/* ICC profile data */
-#define TIFFTAG_IMAGELAYER		34732	/* !TIFF/FX image layer information */
-/* tag 34750 is a private tag registered to Pixel Magic */
-#define	TIFFTAG_JBIGOPTIONS		34750	/* JBIG options */
-#define TIFFTAG_GPSIFD			34853	/* Pointer to GPS private directory */
-/* tags 34908-34914 are private tags registered to SGI */
-#define	TIFFTAG_FAXRECVPARAMS		34908	/* encoded Class 2 ses. parms */
-#define	TIFFTAG_FAXSUBADDRESS		34909	/* received SubAddr string */
-#define	TIFFTAG_FAXRECVTIME		34910	/* receive time (secs) */
-#define	TIFFTAG_FAXDCS			34911	/* encoded fax ses. params, Table 2/T.30 */
-/* tags 37439-37443 are registered to SGI <gregl at sgi.com> */
-#define TIFFTAG_STONITS			37439	/* Sample value to Nits */
-/* tag 34929 is a private tag registered to FedEx */
-#define	TIFFTAG_FEDEX_EDR		34929	/* unknown use */
-#define TIFFTAG_INTEROPERABILITYIFD	40965	/* Pointer to Interoperability private directory */
-/* Adobe Digital Negative (DNG) format tags */
-#define TIFFTAG_DNGVERSION		50706	/* &DNG version number */
-#define TIFFTAG_DNGBACKWARDVERSION	50707	/* &DNG compatibility version */
-#define TIFFTAG_UNIQUECAMERAMODEL	50708	/* &name for the camera model */
-#define TIFFTAG_LOCALIZEDCAMERAMODEL	50709	/* &localized camera model
-						   name */
-#define TIFFTAG_CFAPLANECOLOR		50710	/* &CFAPattern->LinearRaw space
-						   mapping */
-#define TIFFTAG_CFALAYOUT		50711	/* &spatial layout of the CFA */
-#define TIFFTAG_LINEARIZATIONTABLE	50712	/* &lookup table description */
-#define TIFFTAG_BLACKLEVELREPEATDIM	50713	/* &repeat pattern size for
-						   the BlackLevel tag */
-#define TIFFTAG_BLACKLEVEL		50714	/* &zero light encoding level */
-#define TIFFTAG_BLACKLEVELDELTAH	50715	/* &zero light encoding level
-						   differences (columns) */
-#define TIFFTAG_BLACKLEVELDELTAV	50716	/* &zero light encoding level
-						   differences (rows) */
-#define TIFFTAG_WHITELEVEL		50717	/* &fully saturated encoding
-						   level */
-#define TIFFTAG_DEFAULTSCALE		50718	/* &default scale factors */
-#define TIFFTAG_DEFAULTCROPORIGIN	50719	/* &origin of the final image
-						   area */
-#define TIFFTAG_DEFAULTCROPSIZE		50720	/* &size of the final image 
-						   area */
-#define TIFFTAG_COLORMATRIX1		50721	/* &XYZ->reference color space
-						   transformation matrix 1 */
-#define TIFFTAG_COLORMATRIX2		50722	/* &XYZ->reference color space
-						   transformation matrix 2 */
-#define TIFFTAG_CAMERACALIBRATION1	50723	/* &calibration matrix 1 */
-#define TIFFTAG_CAMERACALIBRATION2	50724	/* &calibration matrix 2 */
-#define TIFFTAG_REDUCTIONMATRIX1	50725	/* &dimensionality reduction
-						   matrix 1 */
-#define TIFFTAG_REDUCTIONMATRIX2	50726	/* &dimensionality reduction
-						   matrix 2 */
-#define TIFFTAG_ANALOGBALANCE		50727	/* &gain applied the stored raw
-						   values*/
-#define TIFFTAG_ASSHOTNEUTRAL		50728	/* &selected white balance in
-						   linear reference space */
-#define TIFFTAG_ASSHOTWHITEXY		50729	/* &selected white balance in
-						   x-y chromaticity
-						   coordinates */
-#define TIFFTAG_BASELINEEXPOSURE	50730	/* &how much to move the zero
-						   point */
-#define TIFFTAG_BASELINENOISE		50731	/* &relative noise level */
-#define TIFFTAG_BASELINESHARPNESS	50732	/* &relative amount of
-						   sharpening */
-#define TIFFTAG_BAYERGREENSPLIT		50733	/* &how closely the values of
-						   the green pixels in the
-						   blue/green rows track the
-						   values of the green pixels
-						   in the red/green rows */
-#define TIFFTAG_LINEARRESPONSELIMIT	50734	/* &non-linear encoding range */
-#define TIFFTAG_CAMERASERIALNUMBER	50735	/* &camera's serial number */
-#define TIFFTAG_LENSINFO		50736	/* info about the lens */
-#define TIFFTAG_CHROMABLURRADIUS	50737	/* &chroma blur radius */
-#define TIFFTAG_ANTIALIASSTRENGTH	50738	/* &relative strength of the
-						   camera's anti-alias filter */
-#define TIFFTAG_SHADOWSCALE		50739	/* &used by Adobe Camera Raw */
-#define TIFFTAG_DNGPRIVATEDATA		50740	/* &manufacturer's private data */
-#define TIFFTAG_MAKERNOTESAFETY		50741	/* &whether the EXIF MakerNote
-						   tag is safe to preserve
-						   along with the rest of the
-						   EXIF data */
-#define	TIFFTAG_CALIBRATIONILLUMINANT1	50778	/* &illuminant 1 */
-#define TIFFTAG_CALIBRATIONILLUMINANT2	50779	/* &illuminant 2 */
-#define TIFFTAG_BESTQUALITYSCALE	50780	/* &best quality multiplier */
-#define TIFFTAG_RAWDATAUNIQUEID		50781	/* &unique identifier for
-						   the raw image data */
-#define TIFFTAG_ORIGINALRAWFILENAME	50827	/* &file name of the original
-						   raw file */
-#define TIFFTAG_ORIGINALRAWFILEDATA	50828	/* &contents of the original
-						   raw file */
-#define TIFFTAG_ACTIVEAREA		50829	/* &active (non-masked) pixels
-						   of the sensor */
-#define TIFFTAG_MASKEDAREAS		50830	/* &list of coordinates
-						   of fully masked pixels */
-#define TIFFTAG_ASSHOTICCPROFILE	50831	/* &these two tags used to */
-#define TIFFTAG_ASSHOTPREPROFILEMATRIX	50832	/* map cameras's color space
-						   into ICC profile space */
-#define TIFFTAG_CURRENTICCPROFILE	50833	/* & */
-#define TIFFTAG_CURRENTPREPROFILEMATRIX	50834	/* & */
-/* tag 65535 is an undefined tag used by Eastman Kodak */
-#define TIFFTAG_DCSHUESHIFTVALUES       65535   /* hue shift correction data */
-
-/*
- * The following are ``pseudo tags'' that can be used to control
- * codec-specific functionality.  These tags are not written to file.
- * Note that these values start at 0xffff+1 so that they'll never
- * collide with Aldus-assigned tags.
- *
- * If you want your private pseudo tags ``registered'' (i.e. added to
- * this file), please post a bug report via the tracking system at
- * http://www.remotesensing.org/libtiff/bugs.html with the appropriate
- * C definitions to add.
- */
-#define	TIFFTAG_FAXMODE			65536	/* Group 3/4 format control */
-#define	    FAXMODE_CLASSIC	0x0000		/* default, include RTC */
-#define	    FAXMODE_NORTC	0x0001		/* no RTC at end of data */
-#define	    FAXMODE_NOEOL	0x0002		/* no EOL code at end of row */
-#define	    FAXMODE_BYTEALIGN	0x0004		/* byte align row */
-#define	    FAXMODE_WORDALIGN	0x0008		/* word align row */
-#define	    FAXMODE_CLASSF	FAXMODE_NORTC	/* TIFF Class F */
-#define	TIFFTAG_JPEGQUALITY		65537	/* Compression quality level */
-/* Note: quality level is on the IJG 0-100 scale.  Default value is 75 */
-#define	TIFFTAG_JPEGCOLORMODE		65538	/* Auto RGB<=>YCbCr convert? */
-#define	    JPEGCOLORMODE_RAW	0x0000		/* no conversion (default) */
-#define	    JPEGCOLORMODE_RGB	0x0001		/* do auto conversion */
-#define	TIFFTAG_JPEGTABLESMODE		65539	/* What to put in JPEGTables */
-#define	    JPEGTABLESMODE_QUANT 0x0001		/* include quantization tbls */
-#define	    JPEGTABLESMODE_HUFF	0x0002		/* include Huffman tbls */
-/* Note: default is JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF */
-#define	TIFFTAG_FAXFILLFUNC		65540	/* G3/G4 fill function */
-#define	TIFFTAG_PIXARLOGDATAFMT		65549	/* PixarLogCodec I/O data sz */
-#define	    PIXARLOGDATAFMT_8BIT	0	/* regular u_char samples */
-#define	    PIXARLOGDATAFMT_8BITABGR	1	/* ABGR-order u_chars */
-#define	    PIXARLOGDATAFMT_11BITLOG	2	/* 11-bit log-encoded (raw) */
-#define	    PIXARLOGDATAFMT_12BITPICIO	3	/* as per PICIO (1.0==2048) */
-#define	    PIXARLOGDATAFMT_16BIT	4	/* signed short samples */
-#define	    PIXARLOGDATAFMT_FLOAT	5	/* IEEE float samples */
-/* 65550-65556 are allocated to Oceana Matrix <dev at oceana.com> */
-#define TIFFTAG_DCSIMAGERTYPE           65550   /* imager model & filter */
-#define     DCSIMAGERMODEL_M3           0       /* M3 chip (1280 x 1024) */
-#define     DCSIMAGERMODEL_M5           1       /* M5 chip (1536 x 1024) */
-#define     DCSIMAGERMODEL_M6           2       /* M6 chip (3072 x 2048) */
-#define     DCSIMAGERFILTER_IR          0       /* infrared filter */
-#define     DCSIMAGERFILTER_MONO        1       /* monochrome filter */
-#define     DCSIMAGERFILTER_CFA         2       /* color filter array */
-#define     DCSIMAGERFILTER_OTHER       3       /* other filter */
-#define TIFFTAG_DCSINTERPMODE           65551   /* interpolation mode */
-#define     DCSINTERPMODE_NORMAL        0x0     /* whole image, default */
-#define     DCSINTERPMODE_PREVIEW       0x1     /* preview of image (384x256) */
-#define TIFFTAG_DCSBALANCEARRAY         65552   /* color balance values */
-#define TIFFTAG_DCSCORRECTMATRIX        65553   /* color correction values */
-#define TIFFTAG_DCSGAMMA                65554   /* gamma value */
-#define TIFFTAG_DCSTOESHOULDERPTS       65555   /* toe & shoulder points */
-#define TIFFTAG_DCSCALIBRATIONFD        65556   /* calibration file desc */
-/* Note: quality level is on the ZLIB 1-9 scale. Default value is -1 */
-#define	TIFFTAG_ZIPQUALITY		65557	/* compression quality level */
-#define	TIFFTAG_PIXARLOGQUALITY		65558	/* PixarLog uses same scale */
-/* 65559 is allocated to Oceana Matrix <dev at oceana.com> */
-#define TIFFTAG_DCSCLIPRECTANGLE	65559	/* area of image to acquire */
-#define TIFFTAG_SGILOGDATAFMT		65560	/* SGILog user data format */
-#define     SGILOGDATAFMT_FLOAT		0	/* IEEE float samples */
-#define     SGILOGDATAFMT_16BIT		1	/* 16-bit samples */
-#define     SGILOGDATAFMT_RAW		2	/* uninterpreted data */
-#define     SGILOGDATAFMT_8BIT		3	/* 8-bit RGB monitor values */
-#define TIFFTAG_SGILOGENCODE		65561 /* SGILog data encoding control*/
-#define     SGILOGENCODE_NODITHER	0     /* do not dither encoded values*/
-#define     SGILOGENCODE_RANDITHER	1     /* randomly dither encd values */
-#define	TIFFTAG_LZMAPRESET		65562	/* LZMA2 preset (compression level) */
-#define TIFFTAG_PERSAMPLE       65563	/* interface for per sample tags */
-#define     PERSAMPLE_MERGED        0	/* present as a single value */
-#define     PERSAMPLE_MULTI         1	/* present as multiple values */
-
-/*
- * EXIF tags
- */
-#define EXIFTAG_EXPOSURETIME		33434	/* Exposure time */
-#define EXIFTAG_FNUMBER			33437	/* F number */
-#define EXIFTAG_EXPOSUREPROGRAM		34850	/* Exposure program */
-#define EXIFTAG_SPECTRALSENSITIVITY	34852	/* Spectral sensitivity */
-#define EXIFTAG_ISOSPEEDRATINGS		34855	/* ISO speed rating */
-#define EXIFTAG_OECF			34856	/* Optoelectric conversion
-						   factor */
-#define EXIFTAG_EXIFVERSION		36864	/* Exif version */
-#define EXIFTAG_DATETIMEORIGINAL	36867	/* Date and time of original
-						   data generation */
-#define EXIFTAG_DATETIMEDIGITIZED	36868	/* Date and time of digital
-						   data generation */
-#define EXIFTAG_COMPONENTSCONFIGURATION	37121	/* Meaning of each component */
-#define EXIFTAG_COMPRESSEDBITSPERPIXEL	37122	/* Image compression mode */
-#define EXIFTAG_SHUTTERSPEEDVALUE	37377	/* Shutter speed */
-#define EXIFTAG_APERTUREVALUE		37378	/* Aperture */
-#define EXIFTAG_BRIGHTNESSVALUE		37379	/* Brightness */
-#define EXIFTAG_EXPOSUREBIASVALUE	37380	/* Exposure bias */
-#define EXIFTAG_MAXAPERTUREVALUE	37381	/* Maximum lens aperture */
-#define EXIFTAG_SUBJECTDISTANCE		37382	/* Subject distance */
-#define EXIFTAG_METERINGMODE		37383	/* Metering mode */
-#define EXIFTAG_LIGHTSOURCE		37384	/* Light source */
-#define EXIFTAG_FLASH			37385	/* Flash */
-#define EXIFTAG_FOCALLENGTH		37386	/* Lens focal length */
-#define EXIFTAG_SUBJECTAREA		37396	/* Subject area */
-#define EXIFTAG_MAKERNOTE		37500	/* Manufacturer notes */
-#define EXIFTAG_USERCOMMENT		37510	/* User comments */
-#define EXIFTAG_SUBSECTIME		37520	/* DateTime subseconds */
-#define EXIFTAG_SUBSECTIMEORIGINAL	37521	/* DateTimeOriginal subseconds */
-#define EXIFTAG_SUBSECTIMEDIGITIZED	37522	/* DateTimeDigitized subseconds */
-#define EXIFTAG_FLASHPIXVERSION		40960	/* Supported Flashpix version */
-#define EXIFTAG_COLORSPACE		40961	/* Color space information */
-#define EXIFTAG_PIXELXDIMENSION		40962	/* Valid image width */
-#define EXIFTAG_PIXELYDIMENSION		40963	/* Valid image height */
-#define EXIFTAG_RELATEDSOUNDFILE	40964	/* Related audio file */
-#define EXIFTAG_FLASHENERGY		41483	/* Flash energy */
-#define EXIFTAG_SPATIALFREQUENCYRESPONSE 41484	/* Spatial frequency response */
-#define EXIFTAG_FOCALPLANEXRESOLUTION	41486	/* Focal plane X resolution */
-#define EXIFTAG_FOCALPLANEYRESOLUTION	41487	/* Focal plane Y resolution */
-#define EXIFTAG_FOCALPLANERESOLUTIONUNIT 41488	/* Focal plane resolution unit */
-#define EXIFTAG_SUBJECTLOCATION		41492	/* Subject location */
-#define EXIFTAG_EXPOSUREINDEX		41493	/* Exposure index */
-#define EXIFTAG_SENSINGMETHOD		41495	/* Sensing method */
-#define EXIFTAG_FILESOURCE		41728	/* File source */
-#define EXIFTAG_SCENETYPE		41729	/* Scene type */
-#define EXIFTAG_CFAPATTERN		41730	/* CFA pattern */
-#define EXIFTAG_CUSTOMRENDERED		41985	/* Custom image processing */
-#define EXIFTAG_EXPOSUREMODE		41986	/* Exposure mode */
-#define EXIFTAG_WHITEBALANCE		41987	/* White balance */
-#define EXIFTAG_DIGITALZOOMRATIO	41988	/* Digital zoom ratio */
-#define EXIFTAG_FOCALLENGTHIN35MMFILM	41989	/* Focal length in 35 mm film */
-#define EXIFTAG_SCENECAPTURETYPE	41990	/* Scene capture type */
-#define EXIFTAG_GAINCONTROL		41991	/* Gain control */
-#define EXIFTAG_CONTRAST		41992	/* Contrast */
-#define EXIFTAG_SATURATION		41993	/* Saturation */
-#define EXIFTAG_SHARPNESS		41994	/* Sharpness */
-#define EXIFTAG_DEVICESETTINGDESCRIPTION 41995	/* Device settings description */
-#define EXIFTAG_SUBJECTDISTANCERANGE	41996	/* Subject distance range */
-#define EXIFTAG_GAINCONTROL		41991	/* Gain control */
-#define EXIFTAG_GAINCONTROL		41991	/* Gain control */
-#define EXIFTAG_IMAGEUNIQUEID		42016	/* Unique image ID */
-
-#endif /* _TIFF_ */
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Id: tiff.h,v 1.11 2015/02/19 22:39:59 drolon Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and 
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
+ * 
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef _TIFF_
+#define	_TIFF_
+
+#include "tiffconf.h"
+
+/*
+ * Tag Image File Format (TIFF)
+ *
+ * Based on Rev 6.0 from:
+ *    Developer's Desk
+ *    Aldus Corporation
+ *    411 First Ave. South
+ *    Suite 200
+ *    Seattle, WA  98104
+ *    206-622-5500
+ *
+ *    (http://partners.adobe.com/asn/developer/PDFS/TN/TIFF6.pdf)
+ *
+ * For BigTIFF design notes see the following links
+ *    http://www.remotesensing.org/libtiff/bigtiffdesign.html
+ *    http://www.awaresystems.be/imaging/tiff/bigtiff.html
+ */
+
+#define TIFF_VERSION_CLASSIC 42
+#define TIFF_VERSION_BIG 43
+
+#define TIFF_BIGENDIAN      0x4d4d
+#define TIFF_LITTLEENDIAN   0x4949
+#define MDI_LITTLEENDIAN    0x5045
+#define MDI_BIGENDIAN       0x4550
+
+/*
+ * Intrinsic data types required by the file format:
+ *
+ * 8-bit quantities     int8/uint8
+ * 16-bit quantities    int16/uint16
+ * 32-bit quantities    int32/uint32
+ * 64-bit quantities    int64/uint64
+ * strings              unsigned char*
+ */
+
+typedef TIFF_INT8_T   int8;
+typedef TIFF_UINT8_T  uint8;
+
+typedef TIFF_INT16_T  int16;
+typedef TIFF_UINT16_T uint16;
+
+typedef TIFF_INT32_T  int32;
+typedef TIFF_UINT32_T uint32;
+
+typedef TIFF_INT64_T  int64;
+typedef TIFF_UINT64_T uint64;
+
+/*
+ * Some types as promoted in a variable argument list
+ * We use uint16_vap rather then directly using int, because this way
+ * we document the type we actually want to pass through, conceptually,
+ * rather then confusing the issue by merely stating the type it gets
+ * promoted to
+ */
+
+typedef int uint16_vap;
+
+/*
+ * TIFF header.
+ */
+typedef struct {
+	uint16 tiff_magic;      /* magic number (defines byte order) */
+	uint16 tiff_version;    /* TIFF version number */
+} TIFFHeaderCommon;
+typedef struct {
+	uint16 tiff_magic;      /* magic number (defines byte order) */
+	uint16 tiff_version;    /* TIFF version number */
+	uint32 tiff_diroff;     /* byte offset to first directory */
+} TIFFHeaderClassic;
+typedef struct {
+	uint16 tiff_magic;      /* magic number (defines byte order) */
+	uint16 tiff_version;    /* TIFF version number */
+	uint16 tiff_offsetsize; /* size of offsets, should be 8 */
+	uint16 tiff_unused;     /* unused word, should be 0 */
+	uint64 tiff_diroff;     /* byte offset to first directory */
+} TIFFHeaderBig;
+
+
+/*
+ * NB: In the comments below,
+ *  - items marked with a + are obsoleted by revision 5.0,
+ *  - items marked with a ! are introduced in revision 6.0.
+ *  - items marked with a % are introduced post revision 6.0.
+ *  - items marked with a $ are obsoleted by revision 6.0.
+ *  - items marked with a & are introduced by Adobe DNG specification.
+ */
+
+/*
+ * Tag data type information.
+ *
+ * Note: RATIONALs are the ratio of two 32-bit integer values.
+ */
+typedef enum {
+	TIFF_NOTYPE = 0,      /* placeholder */
+	TIFF_BYTE = 1,        /* 8-bit unsigned integer */
+	TIFF_ASCII = 2,       /* 8-bit bytes w/ last byte null */
+	TIFF_SHORT = 3,       /* 16-bit unsigned integer */
+	TIFF_LONG = 4,        /* 32-bit unsigned integer */
+	TIFF_RATIONAL = 5,    /* 64-bit unsigned fraction */
+	TIFF_SBYTE = 6,       /* !8-bit signed integer */
+	TIFF_UNDEFINED = 7,   /* !8-bit untyped data */
+	TIFF_SSHORT = 8,      /* !16-bit signed integer */
+	TIFF_SLONG = 9,       /* !32-bit signed integer */
+	TIFF_SRATIONAL = 10,  /* !64-bit signed fraction */
+	TIFF_FLOAT = 11,      /* !32-bit IEEE floating point */
+	TIFF_DOUBLE = 12,     /* !64-bit IEEE floating point */
+	TIFF_IFD = 13,        /* %32-bit unsigned integer (offset) */
+	TIFF_LONG8 = 16,      /* BigTIFF 64-bit unsigned integer */
+	TIFF_SLONG8 = 17,     /* BigTIFF 64-bit signed integer */
+	TIFF_IFD8 = 18        /* BigTIFF 64-bit unsigned integer (offset) */
+} TIFFDataType;
+
+/*
+ * TIFF Tag Definitions.
+ */
+#define	TIFFTAG_SUBFILETYPE		254	/* subfile data descriptor */
+#define	    FILETYPE_REDUCEDIMAGE	0x1	/* reduced resolution version */
+#define	    FILETYPE_PAGE		0x2	/* one page of many */
+#define	    FILETYPE_MASK		0x4	/* transparency mask */
+#define	TIFFTAG_OSUBFILETYPE		255	/* +kind of data in subfile */
+#define	    OFILETYPE_IMAGE		1	/* full resolution image data */
+#define	    OFILETYPE_REDUCEDIMAGE	2	/* reduced size image data */
+#define	    OFILETYPE_PAGE		3	/* one page of many */
+#define	TIFFTAG_IMAGEWIDTH		256	/* image width in pixels */
+#define	TIFFTAG_IMAGELENGTH		257	/* image height in pixels */
+#define	TIFFTAG_BITSPERSAMPLE		258	/* bits per channel (sample) */
+#define	TIFFTAG_COMPRESSION		259	/* data compression technique */
+#define	    COMPRESSION_NONE		1	/* dump mode */
+#define	    COMPRESSION_CCITTRLE	2	/* CCITT modified Huffman RLE */
+#define	    COMPRESSION_CCITTFAX3	3	/* CCITT Group 3 fax encoding */
+#define     COMPRESSION_CCITT_T4        3       /* CCITT T.4 (TIFF 6 name) */
+#define	    COMPRESSION_CCITTFAX4	4	/* CCITT Group 4 fax encoding */
+#define     COMPRESSION_CCITT_T6        4       /* CCITT T.6 (TIFF 6 name) */
+#define	    COMPRESSION_LZW		5       /* Lempel-Ziv  & Welch */
+#define	    COMPRESSION_OJPEG		6	/* !6.0 JPEG */
+#define	    COMPRESSION_JPEG		7	/* %JPEG DCT compression */
+#define     COMPRESSION_T85			9	/* !TIFF/FX T.85 JBIG compression */
+#define     COMPRESSION_T43			10	/* !TIFF/FX T.43 colour by layered JBIG compression */
+#define	    COMPRESSION_NEXT		32766	/* NeXT 2-bit RLE */
+#define	    COMPRESSION_CCITTRLEW	32771	/* #1 w/ word alignment */
+#define	    COMPRESSION_PACKBITS	32773	/* Macintosh RLE */
+#define	    COMPRESSION_THUNDERSCAN	32809	/* ThunderScan RLE */
+/* codes 32895-32898 are reserved for ANSI IT8 TIFF/IT <dkelly at apago.com) */
+#define	    COMPRESSION_IT8CTPAD	32895   /* IT8 CT w/padding */
+#define	    COMPRESSION_IT8LW		32896   /* IT8 Linework RLE */
+#define	    COMPRESSION_IT8MP		32897   /* IT8 Monochrome picture */
+#define	    COMPRESSION_IT8BL		32898   /* IT8 Binary line art */
+/* compression codes 32908-32911 are reserved for Pixar */
+#define     COMPRESSION_PIXARFILM	32908   /* Pixar companded 10bit LZW */
+#define	    COMPRESSION_PIXARLOG	32909   /* Pixar companded 11bit ZIP */
+#define	    COMPRESSION_DEFLATE		32946	/* Deflate compression */
+#define     COMPRESSION_ADOBE_DEFLATE   8       /* Deflate compression,
+						   as recognized by Adobe */
+/* compression code 32947 is reserved for Oceana Matrix <dev at oceana.com> */
+#define     COMPRESSION_DCS             32947   /* Kodak DCS encoding */
+#define	    COMPRESSION_JBIG		34661	/* ISO JBIG */
+#define     COMPRESSION_SGILOG		34676	/* SGI Log Luminance RLE */
+#define     COMPRESSION_SGILOG24	34677	/* SGI Log 24-bit packed */
+#define     COMPRESSION_JP2000          34712   /* Leadtools JPEG2000 */
+#define	    COMPRESSION_LZMA		34925	/* LZMA2 */
+#define	TIFFTAG_PHOTOMETRIC		262	/* photometric interpretation */
+#define	    PHOTOMETRIC_MINISWHITE	0	/* min value is white */
+#define	    PHOTOMETRIC_MINISBLACK	1	/* min value is black */
+#define	    PHOTOMETRIC_RGB		2	/* RGB color model */
+#define	    PHOTOMETRIC_PALETTE		3	/* color map indexed */
+#define	    PHOTOMETRIC_MASK		4	/* $holdout mask */
+#define	    PHOTOMETRIC_SEPARATED	5	/* !color separations */
+#define	    PHOTOMETRIC_YCBCR		6	/* !CCIR 601 */
+#define	    PHOTOMETRIC_CIELAB		8	/* !1976 CIE L*a*b* */
+#define	    PHOTOMETRIC_ICCLAB		9	/* ICC L*a*b* [Adobe TIFF Technote 4] */
+#define	    PHOTOMETRIC_ITULAB		10	/* ITU L*a*b* */
+#define	    PHOTOMETRIC_CFA		32803	/* color filter array */
+#define     PHOTOMETRIC_LOGL		32844	/* CIE Log2(L) */
+#define     PHOTOMETRIC_LOGLUV		32845	/* CIE Log2(L) (u',v') */
+#define	TIFFTAG_THRESHHOLDING		263	/* +thresholding used on data */
+#define	    THRESHHOLD_BILEVEL		1	/* b&w art scan */
+#define	    THRESHHOLD_HALFTONE		2	/* or dithered scan */
+#define	    THRESHHOLD_ERRORDIFFUSE	3	/* usually floyd-steinberg */
+#define	TIFFTAG_CELLWIDTH		264	/* +dithering matrix width */
+#define	TIFFTAG_CELLLENGTH		265	/* +dithering matrix height */
+#define	TIFFTAG_FILLORDER		266	/* data order within a byte */
+#define	    FILLORDER_MSB2LSB		1	/* most significant -> least */
+#define	    FILLORDER_LSB2MSB		2	/* least significant -> most */
+#define	TIFFTAG_DOCUMENTNAME		269	/* name of doc. image is from */
+#define	TIFFTAG_IMAGEDESCRIPTION	270	/* info about image */
+#define	TIFFTAG_MAKE			271	/* scanner manufacturer name */
+#define	TIFFTAG_MODEL			272	/* scanner model name/number */
+#define	TIFFTAG_STRIPOFFSETS		273	/* offsets to data strips */
+#define	TIFFTAG_ORIENTATION		274	/* +image orientation */
+#define	    ORIENTATION_TOPLEFT		1	/* row 0 top, col 0 lhs */
+#define	    ORIENTATION_TOPRIGHT	2	/* row 0 top, col 0 rhs */
+#define	    ORIENTATION_BOTRIGHT	3	/* row 0 bottom, col 0 rhs */
+#define	    ORIENTATION_BOTLEFT		4	/* row 0 bottom, col 0 lhs */
+#define	    ORIENTATION_LEFTTOP		5	/* row 0 lhs, col 0 top */
+#define	    ORIENTATION_RIGHTTOP	6	/* row 0 rhs, col 0 top */
+#define	    ORIENTATION_RIGHTBOT	7	/* row 0 rhs, col 0 bottom */
+#define	    ORIENTATION_LEFTBOT		8	/* row 0 lhs, col 0 bottom */
+#define	TIFFTAG_SAMPLESPERPIXEL		277	/* samples per pixel */
+#define	TIFFTAG_ROWSPERSTRIP		278	/* rows per strip of data */
+#define	TIFFTAG_STRIPBYTECOUNTS		279	/* bytes counts for strips */
+#define	TIFFTAG_MINSAMPLEVALUE		280	/* +minimum sample value */
+#define	TIFFTAG_MAXSAMPLEVALUE		281	/* +maximum sample value */
+#define	TIFFTAG_XRESOLUTION		282	/* pixels/resolution in x */
+#define	TIFFTAG_YRESOLUTION		283	/* pixels/resolution in y */
+#define	TIFFTAG_PLANARCONFIG		284	/* storage organization */
+#define	    PLANARCONFIG_CONTIG		1	/* single image plane */
+#define	    PLANARCONFIG_SEPARATE	2	/* separate planes of data */
+#define	TIFFTAG_PAGENAME		285	/* page name image is from */
+#define	TIFFTAG_XPOSITION		286	/* x page offset of image lhs */
+#define	TIFFTAG_YPOSITION		287	/* y page offset of image lhs */
+#define	TIFFTAG_FREEOFFSETS		288	/* +byte offset to free block */
+#define	TIFFTAG_FREEBYTECOUNTS		289	/* +sizes of free blocks */
+#define	TIFFTAG_GRAYRESPONSEUNIT	290	/* $gray scale curve accuracy */
+#define	    GRAYRESPONSEUNIT_10S	1	/* tenths of a unit */
+#define	    GRAYRESPONSEUNIT_100S	2	/* hundredths of a unit */
+#define	    GRAYRESPONSEUNIT_1000S	3	/* thousandths of a unit */
+#define	    GRAYRESPONSEUNIT_10000S	4	/* ten-thousandths of a unit */
+#define	    GRAYRESPONSEUNIT_100000S	5	/* hundred-thousandths */
+#define	TIFFTAG_GRAYRESPONSECURVE	291	/* $gray scale response curve */
+#define	TIFFTAG_GROUP3OPTIONS		292	/* 32 flag bits */
+#define	TIFFTAG_T4OPTIONS		292	/* TIFF 6.0 proper name alias */
+#define	    GROUP3OPT_2DENCODING	0x1	/* 2-dimensional coding */
+#define	    GROUP3OPT_UNCOMPRESSED	0x2	/* data not compressed */
+#define	    GROUP3OPT_FILLBITS		0x4	/* fill to byte boundary */
+#define	TIFFTAG_GROUP4OPTIONS		293	/* 32 flag bits */
+#define TIFFTAG_T6OPTIONS               293     /* TIFF 6.0 proper name */
+#define	    GROUP4OPT_UNCOMPRESSED	0x2	/* data not compressed */
+#define	TIFFTAG_RESOLUTIONUNIT		296	/* units of resolutions */
+#define	    RESUNIT_NONE		1	/* no meaningful units */
+#define	    RESUNIT_INCH		2	/* english */
+#define	    RESUNIT_CENTIMETER		3	/* metric */
+#define	TIFFTAG_PAGENUMBER		297	/* page numbers of multi-page */
+#define	TIFFTAG_COLORRESPONSEUNIT	300	/* $color curve accuracy */
+#define	    COLORRESPONSEUNIT_10S	1	/* tenths of a unit */
+#define	    COLORRESPONSEUNIT_100S	2	/* hundredths of a unit */
+#define	    COLORRESPONSEUNIT_1000S	3	/* thousandths of a unit */
+#define	    COLORRESPONSEUNIT_10000S	4	/* ten-thousandths of a unit */
+#define	    COLORRESPONSEUNIT_100000S	5	/* hundred-thousandths */
+#define	TIFFTAG_TRANSFERFUNCTION	301	/* !colorimetry info */
+#define	TIFFTAG_SOFTWARE		305	/* name & release */
+#define	TIFFTAG_DATETIME		306	/* creation date and time */
+#define	TIFFTAG_ARTIST			315	/* creator of image */
+#define	TIFFTAG_HOSTCOMPUTER		316	/* machine where created */
+#define	TIFFTAG_PREDICTOR		317	/* prediction scheme w/ LZW */
+#define     PREDICTOR_NONE		1	/* no prediction scheme used */
+#define     PREDICTOR_HORIZONTAL	2	/* horizontal differencing */
+#define     PREDICTOR_FLOATINGPOINT	3	/* floating point predictor */
+#define	TIFFTAG_WHITEPOINT		318	/* image white point */
+#define	TIFFTAG_PRIMARYCHROMATICITIES	319	/* !primary chromaticities */
+#define	TIFFTAG_COLORMAP		320	/* RGB map for pallette image */
+#define	TIFFTAG_HALFTONEHINTS		321	/* !highlight+shadow info */
+#define	TIFFTAG_TILEWIDTH		322	/* !tile width in pixels */
+#define	TIFFTAG_TILELENGTH		323	/* !tile height in pixels */
+#define TIFFTAG_TILEOFFSETS		324	/* !offsets to data tiles */
+#define TIFFTAG_TILEBYTECOUNTS		325	/* !byte counts for tiles */
+#define	TIFFTAG_BADFAXLINES		326	/* lines w/ wrong pixel count */
+#define	TIFFTAG_CLEANFAXDATA		327	/* regenerated line info */
+#define	    CLEANFAXDATA_CLEAN		0	/* no errors detected */
+#define	    CLEANFAXDATA_REGENERATED	1	/* receiver regenerated lines */
+#define	    CLEANFAXDATA_UNCLEAN	2	/* uncorrected errors exist */
+#define	TIFFTAG_CONSECUTIVEBADFAXLINES	328	/* max consecutive bad lines */
+#define	TIFFTAG_SUBIFD			330	/* subimage descriptors */
+#define	TIFFTAG_INKSET			332	/* !inks in separated image */
+#define	    INKSET_CMYK			1	/* !cyan-magenta-yellow-black color */
+#define	    INKSET_MULTIINK		2	/* !multi-ink or hi-fi color */
+#define	TIFFTAG_INKNAMES		333	/* !ascii names of inks */
+#define	TIFFTAG_NUMBEROFINKS		334	/* !number of inks */
+#define	TIFFTAG_DOTRANGE		336	/* !0% and 100% dot codes */
+#define	TIFFTAG_TARGETPRINTER		337	/* !separation target */
+#define	TIFFTAG_EXTRASAMPLES		338	/* !info about extra samples */
+#define	    EXTRASAMPLE_UNSPECIFIED	0	/* !unspecified data */
+#define	    EXTRASAMPLE_ASSOCALPHA	1	/* !associated alpha data */
+#define	    EXTRASAMPLE_UNASSALPHA	2	/* !unassociated alpha data */
+#define	TIFFTAG_SAMPLEFORMAT		339	/* !data sample format */
+#define	    SAMPLEFORMAT_UINT		1	/* !unsigned integer data */
+#define	    SAMPLEFORMAT_INT		2	/* !signed integer data */
+#define	    SAMPLEFORMAT_IEEEFP		3	/* !IEEE floating point data */
+#define	    SAMPLEFORMAT_VOID		4	/* !untyped data */
+#define	    SAMPLEFORMAT_COMPLEXINT	5	/* !complex signed int */
+#define	    SAMPLEFORMAT_COMPLEXIEEEFP	6	/* !complex ieee floating */
+#define	TIFFTAG_SMINSAMPLEVALUE		340	/* !variable MinSampleValue */
+#define	TIFFTAG_SMAXSAMPLEVALUE		341	/* !variable MaxSampleValue */
+#define	TIFFTAG_CLIPPATH		343	/* %ClipPath
+						   [Adobe TIFF technote 2] */
+#define	TIFFTAG_XCLIPPATHUNITS		344	/* %XClipPathUnits
+						   [Adobe TIFF technote 2] */
+#define	TIFFTAG_YCLIPPATHUNITS		345	/* %YClipPathUnits
+						   [Adobe TIFF technote 2] */
+#define	TIFFTAG_INDEXED			346	/* %Indexed
+						   [Adobe TIFF Technote 3] */
+#define	TIFFTAG_JPEGTABLES		347	/* %JPEG table stream */
+#define	TIFFTAG_OPIPROXY		351	/* %OPI Proxy [Adobe TIFF technote] */
+/* Tags 400-435 are from the TIFF/FX spec */
+#define TIFFTAG_GLOBALPARAMETERSIFD	400	/* ! */
+#define TIFFTAG_PROFILETYPE			401	/* ! */
+#define     PROFILETYPE_UNSPECIFIED	0	/* ! */
+#define     PROFILETYPE_G3_FAX		1	/* ! */
+#define TIFFTAG_FAXPROFILE			402	/* ! */
+#define     FAXPROFILE_S			1	/* !TIFF/FX FAX profile S */
+#define     FAXPROFILE_F			2	/* !TIFF/FX FAX profile F */
+#define     FAXPROFILE_J			3	/* !TIFF/FX FAX profile J */
+#define     FAXPROFILE_C			4	/* !TIFF/FX FAX profile C */
+#define     FAXPROFILE_L			5	/* !TIFF/FX FAX profile L */
+#define     FAXPROFILE_M			6	/* !TIFF/FX FAX profile LM */
+#define TIFFTAG_CODINGMETHODS		403	/* !TIFF/FX coding methods */
+#define     CODINGMETHODS_T4_1D		(1 << 1)	/* !T.4 1D */
+#define     CODINGMETHODS_T4_2D		(1 << 2)	/* !T.4 2D */
+#define     CODINGMETHODS_T6		(1 << 3)	/* !T.6 */
+#define     CODINGMETHODS_T85 		(1 << 4)	/* !T.85 JBIG */
+#define     CODINGMETHODS_T42 		(1 << 5)	/* !T.42 JPEG */
+#define     CODINGMETHODS_T43		(1 << 6)	/* !T.43 colour by layered JBIG */
+#define TIFFTAG_VERSIONYEAR			404	/* !TIFF/FX version year */
+#define TIFFTAG_MODENUMBER			405	/* !TIFF/FX mode number */
+#define TIFFTAG_DECODE				433	/* !TIFF/FX decode */
+#define TIFFTAG_IMAGEBASECOLOR		434	/* !TIFF/FX image base colour */
+#define TIFFTAG_T82OPTIONS			435	/* !TIFF/FX T.82 options */
+/*
+ * Tags 512-521 are obsoleted by Technical Note #2 which specifies a
+ * revised JPEG-in-TIFF scheme.
+ */
+#define	TIFFTAG_JPEGPROC		512	/* !JPEG processing algorithm */
+#define	    JPEGPROC_BASELINE		1	/* !baseline sequential */
+#define	    JPEGPROC_LOSSLESS		14	/* !Huffman coded lossless */
+#define	TIFFTAG_JPEGIFOFFSET		513	/* !pointer to SOI marker */
+#define	TIFFTAG_JPEGIFBYTECOUNT		514	/* !JFIF stream length */
+#define	TIFFTAG_JPEGRESTARTINTERVAL	515	/* !restart interval length */
+#define	TIFFTAG_JPEGLOSSLESSPREDICTORS	517	/* !lossless proc predictor */
+#define	TIFFTAG_JPEGPOINTTRANSFORM	518	/* !lossless point transform */
+#define	TIFFTAG_JPEGQTABLES		519	/* !Q matrice offsets */
+#define	TIFFTAG_JPEGDCTABLES		520	/* !DCT table offsets */
+#define	TIFFTAG_JPEGACTABLES		521	/* !AC coefficient offsets */
+#define	TIFFTAG_YCBCRCOEFFICIENTS	529	/* !RGB -> YCbCr transform */
+#define	TIFFTAG_YCBCRSUBSAMPLING	530	/* !YCbCr subsampling factors */
+#define	TIFFTAG_YCBCRPOSITIONING	531	/* !subsample positioning */
+#define	    YCBCRPOSITION_CENTERED	1	/* !as in PostScript Level 2 */
+#define	    YCBCRPOSITION_COSITED	2	/* !as in CCIR 601-1 */
+#define	TIFFTAG_REFERENCEBLACKWHITE	532	/* !colorimetry info */
+#define TIFFTAG_STRIPROWCOUNTS		559 /* !TIFF/FX strip row counts */
+#define	TIFFTAG_XMLPACKET		700	/* %XML packet
+						   [Adobe XMP Specification,
+						   January 2004 */
+#define TIFFTAG_OPIIMAGEID		32781	/* %OPI ImageID
+						   [Adobe TIFF technote] */
+/* tags 32952-32956 are private tags registered to Island Graphics */
+#define TIFFTAG_REFPTS			32953	/* image reference points */
+#define TIFFTAG_REGIONTACKPOINT		32954	/* region-xform tack point */
+#define TIFFTAG_REGIONWARPCORNERS	32955	/* warp quadrilateral */
+#define TIFFTAG_REGIONAFFINE		32956	/* affine transformation mat */
+/* tags 32995-32999 are private tags registered to SGI */
+#define	TIFFTAG_MATTEING		32995	/* $use ExtraSamples */
+#define	TIFFTAG_DATATYPE		32996	/* $use SampleFormat */
+#define	TIFFTAG_IMAGEDEPTH		32997	/* z depth of image */
+#define	TIFFTAG_TILEDEPTH		32998	/* z depth/data tile */
+/* tags 33300-33309 are private tags registered to Pixar */
+/*
+ * TIFFTAG_PIXAR_IMAGEFULLWIDTH and TIFFTAG_PIXAR_IMAGEFULLLENGTH
+ * are set when an image has been cropped out of a larger image.  
+ * They reflect the size of the original uncropped image.
+ * The TIFFTAG_XPOSITION and TIFFTAG_YPOSITION can be used
+ * to determine the position of the smaller image in the larger one.
+ */
+#define TIFFTAG_PIXAR_IMAGEFULLWIDTH    33300   /* full image size in x */
+#define TIFFTAG_PIXAR_IMAGEFULLLENGTH   33301   /* full image size in y */
+ /* Tags 33302-33306 are used to identify special image modes and data
+  * used by Pixar's texture formats.
+  */
+#define TIFFTAG_PIXAR_TEXTUREFORMAT	33302	/* texture map format */
+#define TIFFTAG_PIXAR_WRAPMODES		33303	/* s & t wrap modes */
+#define TIFFTAG_PIXAR_FOVCOT		33304	/* cotan(fov) for env. maps */
+#define TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN 33305
+#define TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA 33306
+/* tag 33405 is a private tag registered to Eastman Kodak */
+#define TIFFTAG_WRITERSERIALNUMBER      33405   /* device serial number */
+#define TIFFTAG_CFAREPEATPATTERNDIM	33421	/* dimensions of CFA pattern */
+#define TIFFTAG_CFAPATTERN		33422	/* color filter array pattern */
+/* tag 33432 is listed in the 6.0 spec w/ unknown ownership */
+#define	TIFFTAG_COPYRIGHT		33432	/* copyright string */
+/* IPTC TAG from RichTIFF specifications */
+#define TIFFTAG_RICHTIFFIPTC		33723
+/* 34016-34029 are reserved for ANSI IT8 TIFF/IT <dkelly at apago.com) */
+#define TIFFTAG_IT8SITE			34016	/* site name */
+#define TIFFTAG_IT8COLORSEQUENCE	34017	/* color seq. [RGB,CMYK,etc] */
+#define TIFFTAG_IT8HEADER		34018	/* DDES Header */
+#define TIFFTAG_IT8RASTERPADDING	34019	/* raster scanline padding */
+#define TIFFTAG_IT8BITSPERRUNLENGTH	34020	/* # of bits in short run */
+#define TIFFTAG_IT8BITSPEREXTENDEDRUNLENGTH 34021/* # of bits in long run */
+#define TIFFTAG_IT8COLORTABLE		34022	/* LW colortable */
+#define TIFFTAG_IT8IMAGECOLORINDICATOR	34023	/* BP/BL image color switch */
+#define TIFFTAG_IT8BKGCOLORINDICATOR	34024	/* BP/BL bg color switch */
+#define TIFFTAG_IT8IMAGECOLORVALUE	34025	/* BP/BL image color value */
+#define TIFFTAG_IT8BKGCOLORVALUE	34026	/* BP/BL bg color value */
+#define TIFFTAG_IT8PIXELINTENSITYRANGE	34027	/* MP pixel intensity value */
+#define TIFFTAG_IT8TRANSPARENCYINDICATOR 34028	/* HC transparency switch */
+#define TIFFTAG_IT8COLORCHARACTERIZATION 34029	/* color character. table */
+#define TIFFTAG_IT8HCUSAGE		34030	/* HC usage indicator */
+#define TIFFTAG_IT8TRAPINDICATOR	34031	/* Trapping indicator
+						   (untrapped=0, trapped=1) */
+#define TIFFTAG_IT8CMYKEQUIVALENT	34032	/* CMYK color equivalents */
+/* tags 34232-34236 are private tags registered to Texas Instruments */
+#define TIFFTAG_FRAMECOUNT              34232   /* Sequence Frame Count */
+/* tag 34377 is private tag registered to Adobe for PhotoShop */
+#define TIFFTAG_PHOTOSHOP		34377 
+/* tags 34665, 34853 and 40965 are documented in EXIF specification */
+#define TIFFTAG_EXIFIFD			34665	/* Pointer to EXIF private directory */
+/* tag 34750 is a private tag registered to Adobe? */
+#define TIFFTAG_ICCPROFILE		34675	/* ICC profile data */
+#define TIFFTAG_IMAGELAYER		34732	/* !TIFF/FX image layer information */
+/* tag 34750 is a private tag registered to Pixel Magic */
+#define	TIFFTAG_JBIGOPTIONS		34750	/* JBIG options */
+#define TIFFTAG_GPSIFD			34853	/* Pointer to GPS private directory */
+/* tags 34908-34914 are private tags registered to SGI */
+#define	TIFFTAG_FAXRECVPARAMS		34908	/* encoded Class 2 ses. parms */
+#define	TIFFTAG_FAXSUBADDRESS		34909	/* received SubAddr string */
+#define	TIFFTAG_FAXRECVTIME		34910	/* receive time (secs) */
+#define	TIFFTAG_FAXDCS			34911	/* encoded fax ses. params, Table 2/T.30 */
+/* tags 37439-37443 are registered to SGI <gregl at sgi.com> */
+#define TIFFTAG_STONITS			37439	/* Sample value to Nits */
+/* tag 34929 is a private tag registered to FedEx */
+#define	TIFFTAG_FEDEX_EDR		34929	/* unknown use */
+#define TIFFTAG_INTEROPERABILITYIFD	40965	/* Pointer to Interoperability private directory */
+/* Adobe Digital Negative (DNG) format tags */
+#define TIFFTAG_DNGVERSION		50706	/* &DNG version number */
+#define TIFFTAG_DNGBACKWARDVERSION	50707	/* &DNG compatibility version */
+#define TIFFTAG_UNIQUECAMERAMODEL	50708	/* &name for the camera model */
+#define TIFFTAG_LOCALIZEDCAMERAMODEL	50709	/* &localized camera model
+						   name */
+#define TIFFTAG_CFAPLANECOLOR		50710	/* &CFAPattern->LinearRaw space
+						   mapping */
+#define TIFFTAG_CFALAYOUT		50711	/* &spatial layout of the CFA */
+#define TIFFTAG_LINEARIZATIONTABLE	50712	/* &lookup table description */
+#define TIFFTAG_BLACKLEVELREPEATDIM	50713	/* &repeat pattern size for
+						   the BlackLevel tag */
+#define TIFFTAG_BLACKLEVEL		50714	/* &zero light encoding level */
+#define TIFFTAG_BLACKLEVELDELTAH	50715	/* &zero light encoding level
+						   differences (columns) */
+#define TIFFTAG_BLACKLEVELDELTAV	50716	/* &zero light encoding level
+						   differences (rows) */
+#define TIFFTAG_WHITELEVEL		50717	/* &fully saturated encoding
+						   level */
+#define TIFFTAG_DEFAULTSCALE		50718	/* &default scale factors */
+#define TIFFTAG_DEFAULTCROPORIGIN	50719	/* &origin of the final image
+						   area */
+#define TIFFTAG_DEFAULTCROPSIZE		50720	/* &size of the final image 
+						   area */
+#define TIFFTAG_COLORMATRIX1		50721	/* &XYZ->reference color space
+						   transformation matrix 1 */
+#define TIFFTAG_COLORMATRIX2		50722	/* &XYZ->reference color space
+						   transformation matrix 2 */
+#define TIFFTAG_CAMERACALIBRATION1	50723	/* &calibration matrix 1 */
+#define TIFFTAG_CAMERACALIBRATION2	50724	/* &calibration matrix 2 */
+#define TIFFTAG_REDUCTIONMATRIX1	50725	/* &dimensionality reduction
+						   matrix 1 */
+#define TIFFTAG_REDUCTIONMATRIX2	50726	/* &dimensionality reduction
+						   matrix 2 */
+#define TIFFTAG_ANALOGBALANCE		50727	/* &gain applied the stored raw
+						   values*/
+#define TIFFTAG_ASSHOTNEUTRAL		50728	/* &selected white balance in
+						   linear reference space */
+#define TIFFTAG_ASSHOTWHITEXY		50729	/* &selected white balance in
+						   x-y chromaticity
+						   coordinates */
+#define TIFFTAG_BASELINEEXPOSURE	50730	/* &how much to move the zero
+						   point */
+#define TIFFTAG_BASELINENOISE		50731	/* &relative noise level */
+#define TIFFTAG_BASELINESHARPNESS	50732	/* &relative amount of
+						   sharpening */
+#define TIFFTAG_BAYERGREENSPLIT		50733	/* &how closely the values of
+						   the green pixels in the
+						   blue/green rows track the
+						   values of the green pixels
+						   in the red/green rows */
+#define TIFFTAG_LINEARRESPONSELIMIT	50734	/* &non-linear encoding range */
+#define TIFFTAG_CAMERASERIALNUMBER	50735	/* &camera's serial number */
+#define TIFFTAG_LENSINFO		50736	/* info about the lens */
+#define TIFFTAG_CHROMABLURRADIUS	50737	/* &chroma blur radius */
+#define TIFFTAG_ANTIALIASSTRENGTH	50738	/* &relative strength of the
+						   camera's anti-alias filter */
+#define TIFFTAG_SHADOWSCALE		50739	/* &used by Adobe Camera Raw */
+#define TIFFTAG_DNGPRIVATEDATA		50740	/* &manufacturer's private data */
+#define TIFFTAG_MAKERNOTESAFETY		50741	/* &whether the EXIF MakerNote
+						   tag is safe to preserve
+						   along with the rest of the
+						   EXIF data */
+#define	TIFFTAG_CALIBRATIONILLUMINANT1	50778	/* &illuminant 1 */
+#define TIFFTAG_CALIBRATIONILLUMINANT2	50779	/* &illuminant 2 */
+#define TIFFTAG_BESTQUALITYSCALE	50780	/* &best quality multiplier */
+#define TIFFTAG_RAWDATAUNIQUEID		50781	/* &unique identifier for
+						   the raw image data */
+#define TIFFTAG_ORIGINALRAWFILENAME	50827	/* &file name of the original
+						   raw file */
+#define TIFFTAG_ORIGINALRAWFILEDATA	50828	/* &contents of the original
+						   raw file */
+#define TIFFTAG_ACTIVEAREA		50829	/* &active (non-masked) pixels
+						   of the sensor */
+#define TIFFTAG_MASKEDAREAS		50830	/* &list of coordinates
+						   of fully masked pixels */
+#define TIFFTAG_ASSHOTICCPROFILE	50831	/* &these two tags used to */
+#define TIFFTAG_ASSHOTPREPROFILEMATRIX	50832	/* map cameras's color space
+						   into ICC profile space */
+#define TIFFTAG_CURRENTICCPROFILE	50833	/* & */
+#define TIFFTAG_CURRENTPREPROFILEMATRIX	50834	/* & */
+/* tag 65535 is an undefined tag used by Eastman Kodak */
+#define TIFFTAG_DCSHUESHIFTVALUES       65535   /* hue shift correction data */
+
+/*
+ * The following are ``pseudo tags'' that can be used to control
+ * codec-specific functionality.  These tags are not written to file.
+ * Note that these values start at 0xffff+1 so that they'll never
+ * collide with Aldus-assigned tags.
+ *
+ * If you want your private pseudo tags ``registered'' (i.e. added to
+ * this file), please post a bug report via the tracking system at
+ * http://www.remotesensing.org/libtiff/bugs.html with the appropriate
+ * C definitions to add.
+ */
+#define	TIFFTAG_FAXMODE			65536	/* Group 3/4 format control */
+#define	    FAXMODE_CLASSIC	0x0000		/* default, include RTC */
+#define	    FAXMODE_NORTC	0x0001		/* no RTC at end of data */
+#define	    FAXMODE_NOEOL	0x0002		/* no EOL code at end of row */
+#define	    FAXMODE_BYTEALIGN	0x0004		/* byte align row */
+#define	    FAXMODE_WORDALIGN	0x0008		/* word align row */
+#define	    FAXMODE_CLASSF	FAXMODE_NORTC	/* TIFF Class F */
+#define	TIFFTAG_JPEGQUALITY		65537	/* Compression quality level */
+/* Note: quality level is on the IJG 0-100 scale.  Default value is 75 */
+#define	TIFFTAG_JPEGCOLORMODE		65538	/* Auto RGB<=>YCbCr convert? */
+#define	    JPEGCOLORMODE_RAW	0x0000		/* no conversion (default) */
+#define	    JPEGCOLORMODE_RGB	0x0001		/* do auto conversion */
+#define	TIFFTAG_JPEGTABLESMODE		65539	/* What to put in JPEGTables */
+#define	    JPEGTABLESMODE_QUANT 0x0001		/* include quantization tbls */
+#define	    JPEGTABLESMODE_HUFF	0x0002		/* include Huffman tbls */
+/* Note: default is JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF */
+#define	TIFFTAG_FAXFILLFUNC		65540	/* G3/G4 fill function */
+#define	TIFFTAG_PIXARLOGDATAFMT		65549	/* PixarLogCodec I/O data sz */
+#define	    PIXARLOGDATAFMT_8BIT	0	/* regular u_char samples */
+#define	    PIXARLOGDATAFMT_8BITABGR	1	/* ABGR-order u_chars */
+#define	    PIXARLOGDATAFMT_11BITLOG	2	/* 11-bit log-encoded (raw) */
+#define	    PIXARLOGDATAFMT_12BITPICIO	3	/* as per PICIO (1.0==2048) */
+#define	    PIXARLOGDATAFMT_16BIT	4	/* signed short samples */
+#define	    PIXARLOGDATAFMT_FLOAT	5	/* IEEE float samples */
+/* 65550-65556 are allocated to Oceana Matrix <dev at oceana.com> */
+#define TIFFTAG_DCSIMAGERTYPE           65550   /* imager model & filter */
+#define     DCSIMAGERMODEL_M3           0       /* M3 chip (1280 x 1024) */
+#define     DCSIMAGERMODEL_M5           1       /* M5 chip (1536 x 1024) */
+#define     DCSIMAGERMODEL_M6           2       /* M6 chip (3072 x 2048) */
+#define     DCSIMAGERFILTER_IR          0       /* infrared filter */
+#define     DCSIMAGERFILTER_MONO        1       /* monochrome filter */
+#define     DCSIMAGERFILTER_CFA         2       /* color filter array */
+#define     DCSIMAGERFILTER_OTHER       3       /* other filter */
+#define TIFFTAG_DCSINTERPMODE           65551   /* interpolation mode */
+#define     DCSINTERPMODE_NORMAL        0x0     /* whole image, default */
+#define     DCSINTERPMODE_PREVIEW       0x1     /* preview of image (384x256) */
+#define TIFFTAG_DCSBALANCEARRAY         65552   /* color balance values */
+#define TIFFTAG_DCSCORRECTMATRIX        65553   /* color correction values */
+#define TIFFTAG_DCSGAMMA                65554   /* gamma value */
+#define TIFFTAG_DCSTOESHOULDERPTS       65555   /* toe & shoulder points */
+#define TIFFTAG_DCSCALIBRATIONFD        65556   /* calibration file desc */
+/* Note: quality level is on the ZLIB 1-9 scale. Default value is -1 */
+#define	TIFFTAG_ZIPQUALITY		65557	/* compression quality level */
+#define	TIFFTAG_PIXARLOGQUALITY		65558	/* PixarLog uses same scale */
+/* 65559 is allocated to Oceana Matrix <dev at oceana.com> */
+#define TIFFTAG_DCSCLIPRECTANGLE	65559	/* area of image to acquire */
+#define TIFFTAG_SGILOGDATAFMT		65560	/* SGILog user data format */
+#define     SGILOGDATAFMT_FLOAT		0	/* IEEE float samples */
+#define     SGILOGDATAFMT_16BIT		1	/* 16-bit samples */
+#define     SGILOGDATAFMT_RAW		2	/* uninterpreted data */
+#define     SGILOGDATAFMT_8BIT		3	/* 8-bit RGB monitor values */
+#define TIFFTAG_SGILOGENCODE		65561 /* SGILog data encoding control*/
+#define     SGILOGENCODE_NODITHER	0     /* do not dither encoded values*/
+#define     SGILOGENCODE_RANDITHER	1     /* randomly dither encd values */
+#define	TIFFTAG_LZMAPRESET		65562	/* LZMA2 preset (compression level) */
+#define TIFFTAG_PERSAMPLE       65563	/* interface for per sample tags */
+#define     PERSAMPLE_MERGED        0	/* present as a single value */
+#define     PERSAMPLE_MULTI         1	/* present as multiple values */
+
+/*
+ * EXIF tags
+ */
+#define EXIFTAG_EXPOSURETIME		33434	/* Exposure time */
+#define EXIFTAG_FNUMBER			33437	/* F number */
+#define EXIFTAG_EXPOSUREPROGRAM		34850	/* Exposure program */
+#define EXIFTAG_SPECTRALSENSITIVITY	34852	/* Spectral sensitivity */
+#define EXIFTAG_ISOSPEEDRATINGS		34855	/* ISO speed rating */
+#define EXIFTAG_OECF			34856	/* Optoelectric conversion
+						   factor */
+#define EXIFTAG_EXIFVERSION		36864	/* Exif version */
+#define EXIFTAG_DATETIMEORIGINAL	36867	/* Date and time of original
+						   data generation */
+#define EXIFTAG_DATETIMEDIGITIZED	36868	/* Date and time of digital
+						   data generation */
+#define EXIFTAG_COMPONENTSCONFIGURATION	37121	/* Meaning of each component */
+#define EXIFTAG_COMPRESSEDBITSPERPIXEL	37122	/* Image compression mode */
+#define EXIFTAG_SHUTTERSPEEDVALUE	37377	/* Shutter speed */
+#define EXIFTAG_APERTUREVALUE		37378	/* Aperture */
+#define EXIFTAG_BRIGHTNESSVALUE		37379	/* Brightness */
+#define EXIFTAG_EXPOSUREBIASVALUE	37380	/* Exposure bias */
+#define EXIFTAG_MAXAPERTUREVALUE	37381	/* Maximum lens aperture */
+#define EXIFTAG_SUBJECTDISTANCE		37382	/* Subject distance */
+#define EXIFTAG_METERINGMODE		37383	/* Metering mode */
+#define EXIFTAG_LIGHTSOURCE		37384	/* Light source */
+#define EXIFTAG_FLASH			37385	/* Flash */
+#define EXIFTAG_FOCALLENGTH		37386	/* Lens focal length */
+#define EXIFTAG_SUBJECTAREA		37396	/* Subject area */
+#define EXIFTAG_MAKERNOTE		37500	/* Manufacturer notes */
+#define EXIFTAG_USERCOMMENT		37510	/* User comments */
+#define EXIFTAG_SUBSECTIME		37520	/* DateTime subseconds */
+#define EXIFTAG_SUBSECTIMEORIGINAL	37521	/* DateTimeOriginal subseconds */
+#define EXIFTAG_SUBSECTIMEDIGITIZED	37522	/* DateTimeDigitized subseconds */
+#define EXIFTAG_FLASHPIXVERSION		40960	/* Supported Flashpix version */
+#define EXIFTAG_COLORSPACE		40961	/* Color space information */
+#define EXIFTAG_PIXELXDIMENSION		40962	/* Valid image width */
+#define EXIFTAG_PIXELYDIMENSION		40963	/* Valid image height */
+#define EXIFTAG_RELATEDSOUNDFILE	40964	/* Related audio file */
+#define EXIFTAG_FLASHENERGY		41483	/* Flash energy */
+#define EXIFTAG_SPATIALFREQUENCYRESPONSE 41484	/* Spatial frequency response */
+#define EXIFTAG_FOCALPLANEXRESOLUTION	41486	/* Focal plane X resolution */
+#define EXIFTAG_FOCALPLANEYRESOLUTION	41487	/* Focal plane Y resolution */
+#define EXIFTAG_FOCALPLANERESOLUTIONUNIT 41488	/* Focal plane resolution unit */
+#define EXIFTAG_SUBJECTLOCATION		41492	/* Subject location */
+#define EXIFTAG_EXPOSUREINDEX		41493	/* Exposure index */
+#define EXIFTAG_SENSINGMETHOD		41495	/* Sensing method */
+#define EXIFTAG_FILESOURCE		41728	/* File source */
+#define EXIFTAG_SCENETYPE		41729	/* Scene type */
+#define EXIFTAG_CFAPATTERN		41730	/* CFA pattern */
+#define EXIFTAG_CUSTOMRENDERED		41985	/* Custom image processing */
+#define EXIFTAG_EXPOSUREMODE		41986	/* Exposure mode */
+#define EXIFTAG_WHITEBALANCE		41987	/* White balance */
+#define EXIFTAG_DIGITALZOOMRATIO	41988	/* Digital zoom ratio */
+#define EXIFTAG_FOCALLENGTHIN35MMFILM	41989	/* Focal length in 35 mm film */
+#define EXIFTAG_SCENECAPTURETYPE	41990	/* Scene capture type */
+#define EXIFTAG_GAINCONTROL		41991	/* Gain control */
+#define EXIFTAG_CONTRAST		41992	/* Contrast */
+#define EXIFTAG_SATURATION		41993	/* Saturation */
+#define EXIFTAG_SHARPNESS		41994	/* Sharpness */
+#define EXIFTAG_DEVICESETTINGDESCRIPTION 41995	/* Device settings description */
+#define EXIFTAG_SUBJECTDISTANCERANGE	41996	/* Subject distance range */
+#define EXIFTAG_GAINCONTROL		41991	/* Gain control */
+#define EXIFTAG_GAINCONTROL		41991	/* Gain control */
+#define EXIFTAG_IMAGEUNIQUEID		42016	/* Unique image ID */
+
+#endif /* _TIFF_ */
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tiffconf.h b/Source/LibTIFF4/tiffconf.h
index 39b38a5..e2b7375 100644
--- a/Source/LibTIFF4/tiffconf.h
+++ b/Source/LibTIFF4/tiffconf.h
@@ -1,174 +1,170 @@
-/*
-  Configuration defines for installed libtiff.
-  This file maintained for backward compatibility. Do not use definitions
-  from this file in your programs.
-*/
-
-#ifndef _TIFFCONF_
-#define _TIFFCONF_
-
-/* The size of a `int', as computed by sizeof. */
-#define SIZEOF_INT 4
-
-/* The size of a `long', as computed by sizeof. */
-#include <limits.h>
-#if (LONG_MAX == +9223372036854775807L)
-#define SIZEOF_LONG 8
-#define SIZEOF_UNSIGNED_LONG 8
-#elif (LONG_MAX == +2147483647)
-#define SIZEOF_LONG 4
-#define SIZEOF_UNSIGNED_LONG 4
-#else
-#error "Cannot detect SIZEOF_LONG"
-#endif
-
-/* Signed 8-bit type */
-#define TIFF_INT8_T signed char
-
-/* Unsigned 8-bit type */
-#define TIFF_UINT8_T unsigned char
-
-/* Signed 16-bit type */
-#define TIFF_INT16_T signed short
-
-/* Unsigned 16-bit type */
-#define TIFF_UINT16_T unsigned short
-
-/* Signed 32-bit type */
-#define TIFF_INT32_T signed int
-
-/* Unsigned 32-bit type */
-#define TIFF_UINT32_T unsigned int
-
-/* Signed 64-bit type */
-#ifdef _MSC_VER
-#define TIFF_INT64_T signed __int64
-#else
-#define TIFF_INT64_T signed long
-#endif // _MSC_VER
-
-/* Unsigned 64-bit type */
-#ifdef _MSC_VER
-#define TIFF_UINT64_T unsigned __int64
-#else
-#define TIFF_UINT64_T unsigned long
-#endif // _MSC_VER
-
-/* Signed 64-bit type */
-#if defined(_WIN64)
-#define TIFF_SSIZE_T signed __int64
-#else
-#define TIFF_SSIZE_T signed long
-#endif
-
-/* Pointer difference type */
-#define TIFF_PTRDIFF_T ptrdiff_t
-
-/* Compatibility stuff. */
-
-/* Define as 0 or 1 according to the floating point format suported by the
-   machine */
-#define HAVE_IEEEFP 1
-
-/* 
------------------------------------------------------------------------
-Byte order
------------------------------------------------------------------------
-*/
-
-/*
-Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
-significant byte first (like Motorola and SPARC, unlike Intel).
-Some versions of gcc may have BYTE_ORDER or __BYTE_ORDER defined
-If your big endian system isn't being detected, add an OS specific check
-*/
-#if (defined(BYTE_ORDER) && BYTE_ORDER==BIG_ENDIAN) || \
-	(defined(__BYTE_ORDER) && __BYTE_ORDER==__BIG_ENDIAN) || \
-	defined(__BIG_ENDIAN__)
-/* Set the native cpu bit order (FILLORDER_LSB2MSB or FILLORDER_MSB2LSB) */
-#define HOST_FILLORDER FILLORDER_MSB2LSB
-/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian (Intel) */
-#define WORDS_BIGENDIAN 1
-/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian (Intel) */
-#define HOST_BIGENDIAN 1
-#else
-/* Set the native cpu bit order (FILLORDER_LSB2MSB or FILLORDER_MSB2LSB) */
-#define HOST_FILLORDER FILLORDER_LSB2MSB
-/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian (Intel) */
-#undef WORDS_BIGENDIAN
-/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian (Intel) */
-#undef HOST_BIGENDIAN
-#endif // BYTE_ORDER
-
-/* Support CCITT Group 3 & 4 algorithms */
-#define CCITT_SUPPORT 1
-
-/* Support JPEG compression (requires IJG JPEG library) */
-#define JPEG_SUPPORT 1
-
-/* Support JBIG compression (requires JBIG-KIT library) */
-/* #undef JBIG_SUPPORT */
-
-/* Support LogLuv high dynamic range encoding */
-#define LOGLUV_SUPPORT 1
-
-/* Support LZW algorithm */
-#define LZW_SUPPORT 1
-
-/* Support NeXT 2-bit RLE algorithm */
-#define NEXT_SUPPORT 1
-
-/* Support Old JPEG compresson (read contrib/ojpeg/README first! Compilation
-   fails with unpatched IJG JPEG library) */
-#define OJPEG_SUPPORT 1
-
-/* Support Macintosh PackBits algorithm */
-#define PACKBITS_SUPPORT 1
-
-/* Support Pixar log-format algorithm (requires Zlib) */
-#define PIXARLOG_SUPPORT 1
-
-/* Support ThunderScan 4-bit RLE algorithm */
-#define THUNDER_SUPPORT 1
-
-/* Support Deflate compression */
-#define ZIP_SUPPORT 1
-
-/* Support LZMA2 compression */
-#undef LZMA_SUPPORT
-
-/* Support Microsoft Document Imaging format */
-#undef MDI_SUPPORT
-
-/* Support strip chopping (whether or not to convert single-strip uncompressed
-   images to mutiple strips of ~8Kb to reduce memory usage) */
-#define STRIPCHOP_DEFAULT TIFF_STRIPCHOP
-
-/* Enable SubIFD tag (330) support */
-#define SUBIFD_SUPPORT 1
-
-/* Treat extra sample as alpha (default enabled). The RGBA interface will
-   treat a fourth sample with no EXTRASAMPLE_ value as being ASSOCALPHA. Many
-   packages produce RGBA files but don't mark the alpha properly. */
-#define DEFAULT_EXTRASAMPLE_AS_ALPHA 1
-
-/* Pick up YCbCr subsampling info from the JPEG data stream to support files
-   lacking the tag (default enabled). */
-#define CHECK_JPEG_YCBCR_SUBSAMPLING 1
-
-/* Support MS MDI magic number files as TIFF */
-/* #undef MDI_SUPPORT */
-
-/*
- * Feature support definitions.
- * XXX: These macros are obsoleted. Don't use them in your apps!
- * Macros stays here for backward compatibility and should be always defined.
- */
-#define COLORIMETRY_SUPPORT
-#define YCBCR_SUPPORT
-#define CMYK_SUPPORT
-#define ICC_SUPPORT
-#define PHOTOSHOP_SUPPORT
-#define IPTC_SUPPORT
-
-#endif /* _TIFFCONF_ */
+/*
+  Configuration defines for installed libtiff.
+  This file maintained for backward compatibility. Do not use definitions
+  from this file in your programs.
+*/
+
+#ifndef _TIFFCONF_
+#define _TIFFCONF_
+
+/* The size of a `int', as computed by sizeof. */
+#define SIZEOF_INT 4
+
+/* The size of a `long', as computed by sizeof. */
+#include <limits.h>
+#if (LONG_MAX == +9223372036854775807L)
+#define SIZEOF_LONG 8
+#define SIZEOF_UNSIGNED_LONG 8
+#elif (LONG_MAX == +2147483647)
+#define SIZEOF_LONG 4
+#define SIZEOF_UNSIGNED_LONG 4
+#else
+#error "Cannot detect SIZEOF_LONG"
+#endif
+
+/* Signed 8-bit type */
+#define TIFF_INT8_T signed char
+
+/* Unsigned 8-bit type */
+#define TIFF_UINT8_T unsigned char
+
+/* Signed 16-bit type */
+#define TIFF_INT16_T signed short
+
+/* Unsigned 16-bit type */
+#define TIFF_UINT16_T unsigned short
+
+/* Signed 32-bit type */
+#define TIFF_INT32_T signed int
+
+/* Unsigned 32-bit type */
+#define TIFF_UINT32_T unsigned int
+
+/* Signed / Unsigned 64-bit type */
+#ifdef _MSC_VER
+#define TIFF_INT64_T signed __int64
+#define TIFF_UINT64_T unsigned __int64
+#else
+#include <inttypes.h>
+#define TIFF_INT64_T int64_t
+#define TIFF_UINT64_T uint64_t
+#endif // _MSC_VER
+
+/* Signed 64-bit type */
+#if defined(_WIN64)
+#define TIFF_SSIZE_T signed __int64
+#else
+#define TIFF_SSIZE_T signed long
+#endif
+
+/* Pointer difference type */
+#define TIFF_PTRDIFF_T ptrdiff_t
+
+/* Compatibility stuff. */
+
+/* Define as 0 or 1 according to the floating point format suported by the
+   machine */
+#define HAVE_IEEEFP 1
+
+/* 
+-----------------------------------------------------------------------
+Byte order
+-----------------------------------------------------------------------
+*/
+
+/*
+Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+significant byte first (like Motorola and SPARC, unlike Intel).
+Some versions of gcc may have BYTE_ORDER or __BYTE_ORDER defined
+If your big endian system isn't being detected, add an OS specific check
+*/
+#if (defined(BYTE_ORDER) && BYTE_ORDER==BIG_ENDIAN) || \
+	(defined(__BYTE_ORDER) && __BYTE_ORDER==__BIG_ENDIAN) || \
+	defined(__BIG_ENDIAN__)
+/* Set the native cpu bit order (FILLORDER_LSB2MSB or FILLORDER_MSB2LSB) */
+#define HOST_FILLORDER FILLORDER_MSB2LSB
+/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian (Intel) */
+#define WORDS_BIGENDIAN 1
+/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian (Intel) */
+#define HOST_BIGENDIAN 1
+#else
+/* Set the native cpu bit order (FILLORDER_LSB2MSB or FILLORDER_MSB2LSB) */
+#define HOST_FILLORDER FILLORDER_LSB2MSB
+/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian (Intel) */
+#undef WORDS_BIGENDIAN
+/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian (Intel) */
+#undef HOST_BIGENDIAN
+#endif // BYTE_ORDER
+
+/* Support CCITT Group 3 & 4 algorithms */
+#define CCITT_SUPPORT 1
+
+/* Support JPEG compression (requires IJG JPEG library) */
+#define JPEG_SUPPORT 1
+
+/* Support JBIG compression (requires JBIG-KIT library) */
+/* #undef JBIG_SUPPORT */
+
+/* Support LogLuv high dynamic range encoding */
+#define LOGLUV_SUPPORT 1
+
+/* Support LZW algorithm */
+#define LZW_SUPPORT 1
+
+/* Support NeXT 2-bit RLE algorithm */
+#define NEXT_SUPPORT 1
+
+/* Support Old JPEG compresson (read contrib/ojpeg/README first! Compilation
+   fails with unpatched IJG JPEG library) */
+#define OJPEG_SUPPORT 1
+
+/* Support Macintosh PackBits algorithm */
+#define PACKBITS_SUPPORT 1
+
+/* Support Pixar log-format algorithm (requires Zlib) */
+#define PIXARLOG_SUPPORT 1
+
+/* Support ThunderScan 4-bit RLE algorithm */
+#define THUNDER_SUPPORT 1
+
+/* Support Deflate compression */
+#define ZIP_SUPPORT 1
+
+/* Support LZMA2 compression */
+#undef LZMA_SUPPORT
+
+/* Support Microsoft Document Imaging format */
+#undef MDI_SUPPORT
+
+/* Support strip chopping (whether or not to convert single-strip uncompressed
+   images to mutiple strips of ~8Kb to reduce memory usage) */
+#define STRIPCHOP_DEFAULT TIFF_STRIPCHOP
+
+/* Enable SubIFD tag (330) support */
+#define SUBIFD_SUPPORT 1
+
+/* Treat extra sample as alpha (default enabled). The RGBA interface will
+   treat a fourth sample with no EXTRASAMPLE_ value as being ASSOCALPHA. Many
+   packages produce RGBA files but don't mark the alpha properly. */
+#define DEFAULT_EXTRASAMPLE_AS_ALPHA 1
+
+/* Pick up YCbCr subsampling info from the JPEG data stream to support files
+   lacking the tag (default enabled). */
+#define CHECK_JPEG_YCBCR_SUBSAMPLING 1
+
+/* Support MS MDI magic number files as TIFF */
+/* #undef MDI_SUPPORT */
+
+/*
+ * Feature support definitions.
+ * XXX: These macros are obsoleted. Don't use them in your apps!
+ * Macros stays here for backward compatibility and should be always defined.
+ */
+#define COLORIMETRY_SUPPORT
+#define YCBCR_SUPPORT
+#define CMYK_SUPPORT
+#define ICC_SUPPORT
+#define PHOTOSHOP_SUPPORT
+#define IPTC_SUPPORT
+
+#endif /* _TIFFCONF_ */
diff --git a/Source/LibTIFF4/tiffconf.vc.h b/Source/LibTIFF4/tiffconf.vc.h
index 0584b59..680f839 100644
--- a/Source/LibTIFF4/tiffconf.vc.h
+++ b/Source/LibTIFF4/tiffconf.vc.h
@@ -1,160 +1,160 @@
-/*
-  Configuration defines for installed libtiff.
-  This file maintained for backward compatibility. Do not use definitions
-  from this file in your programs.
-*/
-
-#ifndef _TIFFCONF_
-#define _TIFFCONF_
-
-/* Define to 1 if the system has the type `int16'. */
-/* #undef HAVE_INT16 */
-
-/* Define to 1 if the system has the type `int32'. */
-/* #undef HAVE_INT32 */
-
-/* Define to 1 if the system has the type `int8'. */
-/* #undef HAVE_INT8 */
-
-/* The size of a `int', as computed by sizeof. */
-#define SIZEOF_INT 4
-
-/* Signed 8-bit type */
-#define TIFF_INT8_T signed char
-
-/* Unsigned 8-bit type */
-#define TIFF_UINT8_T unsigned char
-
-/* Signed 16-bit type */
-#define TIFF_INT16_T signed short
-
-/* Unsigned 16-bit type */
-#define TIFF_UINT16_T unsigned short
-
-/* Signed 32-bit type formatter */
-#define TIFF_INT32_FORMAT "%d"
-
-/* Signed 32-bit type */
-#define TIFF_INT32_T signed int
-
-/* Unsigned 32-bit type formatter */
-#define TIFF_UINT32_FORMAT "%u"
-
-/* Unsigned 32-bit type */
-#define TIFF_UINT32_T unsigned int
-
-/* Signed 64-bit type formatter */
-#define TIFF_INT64_FORMAT "%I64d"
-
-/* Signed 64-bit type */
-#define TIFF_INT64_T signed __int64
-
-/* Unsigned 64-bit type formatter */
-#define TIFF_UINT64_FORMAT "%I64u"
-
-/* Unsigned 64-bit type */
-#define TIFF_UINT64_T unsigned __int64
-
-/* Signed size type */
-#if defined(_WIN64)
-#define TIFF_SSIZE_T signed __int64
-#else
-#define TIFF_SSIZE_T signed int
-#endif
-
-/* Signed size type formatter */
-#if defined(_WIN64)
-#define TIFF_SSIZE_FORMAT "%I64d"
-#else
-#define TIFF_SSIZE_FORMAT "%ld"
-#endif
-
-/* Pointer difference type */
-#define TIFF_PTRDIFF_T long
-
-/* Compatibility stuff. */
-
-/* Define as 0 or 1 according to the floating point format suported by the
-   machine */
-#define HAVE_IEEEFP 1
-
-/* Set the native cpu bit order (FILLORDER_LSB2MSB or FILLORDER_MSB2LSB) */
-#define HOST_FILLORDER FILLORDER_LSB2MSB
-
-/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian
-   (Intel) */
-#define HOST_BIGENDIAN 0
-
-/* Support CCITT Group 3 & 4 algorithms */
-#define CCITT_SUPPORT 1
-
-/* Support JPEG compression (requires IJG JPEG library) */
-/* #undef JPEG_SUPPORT */
-
-/* Support JBIG compression (requires JBIG-KIT library) */
-/* #undef JBIG_SUPPORT */
-
-/* Support LogLuv high dynamic range encoding */
-#define LOGLUV_SUPPORT 1
-
-/* Support LZW algorithm */
-#define LZW_SUPPORT 1
-
-/* Support NeXT 2-bit RLE algorithm */
-#define NEXT_SUPPORT 1
-
-/* Support Old JPEG compresson (read contrib/ojpeg/README first! Compilation
-   fails with unpatched IJG JPEG library) */
-/* #undef OJPEG_SUPPORT */
-
-/* Support Macintosh PackBits algorithm */
-#define PACKBITS_SUPPORT 1
-
-/* Support Pixar log-format algorithm (requires Zlib) */
-/* #undef PIXARLOG_SUPPORT */
-
-/* Support ThunderScan 4-bit RLE algorithm */
-#define THUNDER_SUPPORT 1
-
-/* Support Deflate compression */
-/* #undef ZIP_SUPPORT */
-
-/* Support strip chopping (whether or not to convert single-strip uncompressed
-   images to mutiple strips of ~8Kb to reduce memory usage) */
-#define STRIPCHOP_DEFAULT TIFF_STRIPCHOP
-
-/* Enable SubIFD tag (330) support */
-#define SUBIFD_SUPPORT 1
-
-/* Treat extra sample as alpha (default enabled). The RGBA interface will
-   treat a fourth sample with no EXTRASAMPLE_ value as being ASSOCALPHA. Many
-   packages produce RGBA files but don't mark the alpha properly. */
-#define DEFAULT_EXTRASAMPLE_AS_ALPHA 1
-
-/* Pick up YCbCr subsampling info from the JPEG data stream to support files
-   lacking the tag (default enabled). */
-#define CHECK_JPEG_YCBCR_SUBSAMPLING 1
-
-/* Support MS MDI magic number files as TIFF */
-/* #undef MDI_SUPPORT */
-
-/*
- * Feature support definitions.
- * XXX: These macros are obsoleted. Don't use them in your apps!
- * Macros stays here for backward compatibility and should be always defined.
- */
-#define COLORIMETRY_SUPPORT
-#define YCBCR_SUPPORT
-#define CMYK_SUPPORT
-#define ICC_SUPPORT
-#define PHOTOSHOP_SUPPORT
-#define IPTC_SUPPORT
-
-#endif /* _TIFFCONF_ */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/*
+  Configuration defines for installed libtiff.
+  This file maintained for backward compatibility. Do not use definitions
+  from this file in your programs.
+*/
+
+#ifndef _TIFFCONF_
+#define _TIFFCONF_
+
+/* Define to 1 if the system has the type `int16'. */
+/* #undef HAVE_INT16 */
+
+/* Define to 1 if the system has the type `int32'. */
+/* #undef HAVE_INT32 */
+
+/* Define to 1 if the system has the type `int8'. */
+/* #undef HAVE_INT8 */
+
+/* The size of a `int', as computed by sizeof. */
+#define SIZEOF_INT 4
+
+/* Signed 8-bit type */
+#define TIFF_INT8_T signed char
+
+/* Unsigned 8-bit type */
+#define TIFF_UINT8_T unsigned char
+
+/* Signed 16-bit type */
+#define TIFF_INT16_T signed short
+
+/* Unsigned 16-bit type */
+#define TIFF_UINT16_T unsigned short
+
+/* Signed 32-bit type formatter */
+#define TIFF_INT32_FORMAT "%d"
+
+/* Signed 32-bit type */
+#define TIFF_INT32_T signed int
+
+/* Unsigned 32-bit type formatter */
+#define TIFF_UINT32_FORMAT "%u"
+
+/* Unsigned 32-bit type */
+#define TIFF_UINT32_T unsigned int
+
+/* Signed 64-bit type formatter */
+#define TIFF_INT64_FORMAT "%I64d"
+
+/* Signed 64-bit type */
+#define TIFF_INT64_T signed __int64
+
+/* Unsigned 64-bit type formatter */
+#define TIFF_UINT64_FORMAT "%I64u"
+
+/* Unsigned 64-bit type */
+#define TIFF_UINT64_T unsigned __int64
+
+/* Signed size type */
+#if defined(_WIN64)
+#define TIFF_SSIZE_T signed __int64
+#else
+#define TIFF_SSIZE_T signed int
+#endif
+
+/* Signed size type formatter */
+#if defined(_WIN64)
+#define TIFF_SSIZE_FORMAT "%I64d"
+#else
+#define TIFF_SSIZE_FORMAT "%ld"
+#endif
+
+/* Pointer difference type */
+#define TIFF_PTRDIFF_T long
+
+/* Compatibility stuff. */
+
+/* Define as 0 or 1 according to the floating point format suported by the
+   machine */
+#define HAVE_IEEEFP 1
+
+/* Set the native cpu bit order (FILLORDER_LSB2MSB or FILLORDER_MSB2LSB) */
+#define HOST_FILLORDER FILLORDER_LSB2MSB
+
+/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian
+   (Intel) */
+#define HOST_BIGENDIAN 0
+
+/* Support CCITT Group 3 & 4 algorithms */
+#define CCITT_SUPPORT 1
+
+/* Support JPEG compression (requires IJG JPEG library) */
+/* #undef JPEG_SUPPORT */
+
+/* Support JBIG compression (requires JBIG-KIT library) */
+/* #undef JBIG_SUPPORT */
+
+/* Support LogLuv high dynamic range encoding */
+#define LOGLUV_SUPPORT 1
+
+/* Support LZW algorithm */
+#define LZW_SUPPORT 1
+
+/* Support NeXT 2-bit RLE algorithm */
+#define NEXT_SUPPORT 1
+
+/* Support Old JPEG compresson (read contrib/ojpeg/README first! Compilation
+   fails with unpatched IJG JPEG library) */
+/* #undef OJPEG_SUPPORT */
+
+/* Support Macintosh PackBits algorithm */
+#define PACKBITS_SUPPORT 1
+
+/* Support Pixar log-format algorithm (requires Zlib) */
+/* #undef PIXARLOG_SUPPORT */
+
+/* Support ThunderScan 4-bit RLE algorithm */
+#define THUNDER_SUPPORT 1
+
+/* Support Deflate compression */
+/* #undef ZIP_SUPPORT */
+
+/* Support strip chopping (whether or not to convert single-strip uncompressed
+   images to mutiple strips of ~8Kb to reduce memory usage) */
+#define STRIPCHOP_DEFAULT TIFF_STRIPCHOP
+
+/* Enable SubIFD tag (330) support */
+#define SUBIFD_SUPPORT 1
+
+/* Treat extra sample as alpha (default enabled). The RGBA interface will
+   treat a fourth sample with no EXTRASAMPLE_ value as being ASSOCALPHA. Many
+   packages produce RGBA files but don't mark the alpha properly. */
+#define DEFAULT_EXTRASAMPLE_AS_ALPHA 1
+
+/* Pick up YCbCr subsampling info from the JPEG data stream to support files
+   lacking the tag (default enabled). */
+#define CHECK_JPEG_YCBCR_SUBSAMPLING 1
+
+/* Support MS MDI magic number files as TIFF */
+/* #undef MDI_SUPPORT */
+
+/*
+ * Feature support definitions.
+ * XXX: These macros are obsoleted. Don't use them in your apps!
+ * Macros stays here for backward compatibility and should be always defined.
+ */
+#define COLORIMETRY_SUPPORT
+#define YCBCR_SUPPORT
+#define CMYK_SUPPORT
+#define ICC_SUPPORT
+#define PHOTOSHOP_SUPPORT
+#define IPTC_SUPPORT
+
+#endif /* _TIFFCONF_ */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tiffconf.wince.h b/Source/LibTIFF4/tiffconf.wince.h
index b832751..e98239d 100644
--- a/Source/LibTIFF4/tiffconf.wince.h
+++ b/Source/LibTIFF4/tiffconf.wince.h
@@ -1,121 +1,121 @@
-/* $Id: tiffconf.wince.h,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * Windows CE platform tiffconf.wince.h
- * Created by Mateusz Loskot (mateusz at loskot.net)
- *
- * NOTE: Requires WCELIBCEX library with wceex_* functions,
- * It's an extension to C library on Windows CE platform.
- * For example, HAVE_STDIO_H definition indicates there are
- * following files available:
- * stdio.h - from Windows CE / Windows Mobile SDK 
- * wce_stdio.h - from WCELIBCEX library
- */
-
-
-/*
-  Configuration defines for installed libtiff.
-  This file maintained for backward compatibility. Do not use definitions
-  from this file in your programs.
-*/
-
-#ifndef _WIN32_WCE
-# error This version of tif_config.h header is dedicated for Windows CE platform!
-#endif
-
-
-#ifndef _TIFFCONF_
-#define _TIFFCONF_
-
-/* Define to 1 if the system has the type `int16'. */
-/* #undef HAVE_INT16 */
-
-/* Define to 1 if the system has the type `int32'. */
-/* #undef HAVE_INT32 */
-
-/* Define to 1 if the system has the type `int8'. */
-/* #undef HAVE_INT8 */
-
-/* The size of a `int', as computed by sizeof. */
-#define SIZEOF_INT 4
-
-/* Compatibility stuff. */
-
-/* Define as 0 or 1 according to the floating point format suported by the
-   machine */
-#define HAVE_IEEEFP 1
-
-/* Set the native cpu bit order (FILLORDER_LSB2MSB or FILLORDER_MSB2LSB) */
-#define HOST_FILLORDER FILLORDER_LSB2MSB
-
-/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian
-   (Intel) */
-#define HOST_BIGENDIAN 0
-
-/* Support CCITT Group 3 & 4 algorithms */
-#define CCITT_SUPPORT 1
-
-/* Support JPEG compression (requires IJG JPEG library) */
-/* #undef JPEG_SUPPORT */
-
-/* Support LogLuv high dynamic range encoding */
-#define LOGLUV_SUPPORT 1
-
-/* Support LZW algorithm */
-#define LZW_SUPPORT 1
-
-/* Support NeXT 2-bit RLE algorithm */
-#define NEXT_SUPPORT 1
-
-/* Support Old JPEG compresson (read contrib/ojpeg/README first! Compilation
-   fails with unpatched IJG JPEG library) */
-/* #undef OJPEG_SUPPORT */
-
-/* Support Macintosh PackBits algorithm */
-#define PACKBITS_SUPPORT 1
-
-/* Support Pixar log-format algorithm (requires Zlib) */
-/* #undef PIXARLOG_SUPPORT */
-
-/* Support ThunderScan 4-bit RLE algorithm */
-#define THUNDER_SUPPORT 1
-
-/* Support Deflate compression */
-/* #undef ZIP_SUPPORT */
-
-/* Support strip chopping (whether or not to convert single-strip uncompressed
-   images to mutiple strips of ~8Kb to reduce memory usage) */
-#define STRIPCHOP_DEFAULT TIFF_STRIPCHOP
-
-/* Enable SubIFD tag (330) support */
-#define SUBIFD_SUPPORT 1
-
-/* Treat extra sample as alpha (default enabled). The RGBA interface will
-   treat a fourth sample with no EXTRASAMPLE_ value as being ASSOCALPHA. Many
-   packages produce RGBA files but don't mark the alpha properly. */
-#define DEFAULT_EXTRASAMPLE_AS_ALPHA 1
-
-/* Pick up YCbCr subsampling info from the JPEG data stream to support files
-   lacking the tag (default enabled). */
-#define CHECK_JPEG_YCBCR_SUBSAMPLING 1
-
-/*
- * Feature support definitions.
- * XXX: These macros are obsoleted. Don't use them in your apps!
- * Macros stays here for backward compatibility and should be always defined.
- */
-#define COLORIMETRY_SUPPORT
-#define YCBCR_SUPPORT
-#define CMYK_SUPPORT
-#define ICC_SUPPORT
-#define PHOTOSHOP_SUPPORT
-#define IPTC_SUPPORT
-
-#endif /* _TIFFCONF_ */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Id: tiffconf.wince.h,v 1.11 2015/02/19 22:39:59 drolon Exp $ */
+
+/*
+ * Windows CE platform tiffconf.wince.h
+ * Created by Mateusz Loskot (mateusz at loskot.net)
+ *
+ * NOTE: Requires WCELIBCEX library with wceex_* functions,
+ * It's an extension to C library on Windows CE platform.
+ * For example, HAVE_STDIO_H definition indicates there are
+ * following files available:
+ * stdio.h - from Windows CE / Windows Mobile SDK 
+ * wce_stdio.h - from WCELIBCEX library
+ */
+
+
+/*
+  Configuration defines for installed libtiff.
+  This file maintained for backward compatibility. Do not use definitions
+  from this file in your programs.
+*/
+
+#ifndef _WIN32_WCE
+# error This version of tif_config.h header is dedicated for Windows CE platform!
+#endif
+
+
+#ifndef _TIFFCONF_
+#define _TIFFCONF_
+
+/* Define to 1 if the system has the type `int16'. */
+/* #undef HAVE_INT16 */
+
+/* Define to 1 if the system has the type `int32'. */
+/* #undef HAVE_INT32 */
+
+/* Define to 1 if the system has the type `int8'. */
+/* #undef HAVE_INT8 */
+
+/* The size of a `int', as computed by sizeof. */
+#define SIZEOF_INT 4
+
+/* Compatibility stuff. */
+
+/* Define as 0 or 1 according to the floating point format suported by the
+   machine */
+#define HAVE_IEEEFP 1
+
+/* Set the native cpu bit order (FILLORDER_LSB2MSB or FILLORDER_MSB2LSB) */
+#define HOST_FILLORDER FILLORDER_LSB2MSB
+
+/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian
+   (Intel) */
+#define HOST_BIGENDIAN 0
+
+/* Support CCITT Group 3 & 4 algorithms */
+#define CCITT_SUPPORT 1
+
+/* Support JPEG compression (requires IJG JPEG library) */
+/* #undef JPEG_SUPPORT */
+
+/* Support LogLuv high dynamic range encoding */
+#define LOGLUV_SUPPORT 1
+
+/* Support LZW algorithm */
+#define LZW_SUPPORT 1
+
+/* Support NeXT 2-bit RLE algorithm */
+#define NEXT_SUPPORT 1
+
+/* Support Old JPEG compresson (read contrib/ojpeg/README first! Compilation
+   fails with unpatched IJG JPEG library) */
+/* #undef OJPEG_SUPPORT */
+
+/* Support Macintosh PackBits algorithm */
+#define PACKBITS_SUPPORT 1
+
+/* Support Pixar log-format algorithm (requires Zlib) */
+/* #undef PIXARLOG_SUPPORT */
+
+/* Support ThunderScan 4-bit RLE algorithm */
+#define THUNDER_SUPPORT 1
+
+/* Support Deflate compression */
+/* #undef ZIP_SUPPORT */
+
+/* Support strip chopping (whether or not to convert single-strip uncompressed
+   images to mutiple strips of ~8Kb to reduce memory usage) */
+#define STRIPCHOP_DEFAULT TIFF_STRIPCHOP
+
+/* Enable SubIFD tag (330) support */
+#define SUBIFD_SUPPORT 1
+
+/* Treat extra sample as alpha (default enabled). The RGBA interface will
+   treat a fourth sample with no EXTRASAMPLE_ value as being ASSOCALPHA. Many
+   packages produce RGBA files but don't mark the alpha properly. */
+#define DEFAULT_EXTRASAMPLE_AS_ALPHA 1
+
+/* Pick up YCbCr subsampling info from the JPEG data stream to support files
+   lacking the tag (default enabled). */
+#define CHECK_JPEG_YCBCR_SUBSAMPLING 1
+
+/*
+ * Feature support definitions.
+ * XXX: These macros are obsoleted. Don't use them in your apps!
+ * Macros stays here for backward compatibility and should be always defined.
+ */
+#define COLORIMETRY_SUPPORT
+#define YCBCR_SUPPORT
+#define CMYK_SUPPORT
+#define ICC_SUPPORT
+#define PHOTOSHOP_SUPPORT
+#define IPTC_SUPPORT
+
+#endif /* _TIFFCONF_ */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tiffio.h b/Source/LibTIFF4/tiffio.h
index 482574a..a777410 100644
--- a/Source/LibTIFF4/tiffio.h
+++ b/Source/LibTIFF4/tiffio.h
@@ -1,557 +1,557 @@
-/* $Id: tiffio.h,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- */
-
-#ifndef _TIFFIO_
-#define	_TIFFIO_
-
-/*
- * TIFF I/O Library Definitions.
- */
-#include "tiff.h"
-#include "tiffvers.h"
-
-/*
- * TIFF is defined as an incomplete type to hide the
- * library's internal data structures from clients.
- */
-typedef struct tiff TIFF;
-
-/*
- * The following typedefs define the intrinsic size of
- * data types used in the *exported* interfaces.  These
- * definitions depend on the proper definition of types
- * in tiff.h.  Note also that the varargs interface used
- * to pass tag types and values uses the types defined in
- * tiff.h directly.
- *
- * NB: ttag_t is unsigned int and not unsigned short because
- *     ANSI C requires that the type before the ellipsis be a
- *     promoted type (i.e. one of int, unsigned int, pointer,
- *     or double) and because we defined pseudo-tags that are
- *     outside the range of legal Aldus-assigned tags.
- * NB: tsize_t is int32 and not uint32 because some functions
- *     return -1.
- * NB: toff_t is not off_t for many reasons; TIFFs max out at
- *     32-bit file offsets, and BigTIFF maxes out at 64-bit
- *     offsets being the most important, and to ensure use of
- *     a consistently unsigned type across architectures.
- *     Prior to libtiff 4.0, this was an unsigned 32 bit type.
- */
-/*
- * this is the machine addressing size type, only it's signed, so make it
- * int32 on 32bit machines, int64 on 64bit machines
- */
-typedef TIFF_SSIZE_T tmsize_t;
-typedef uint64 toff_t;          /* file offset */
-/* the following are deprecated and should be replaced by their defining
-   counterparts */
-typedef uint32 ttag_t;          /* directory tag */
-typedef uint16 tdir_t;          /* directory index */
-typedef uint16 tsample_t;       /* sample number */
-typedef uint32 tstrile_t;       /* strip or tile number */
-typedef tstrile_t tstrip_t;     /* strip number */
-typedef tstrile_t ttile_t;      /* tile number */
-typedef tmsize_t tsize_t;       /* i/o size in bytes */
-typedef void* tdata_t;          /* image data ref */
-
-#if !defined(__WIN32__) && (defined(_WIN32) || defined(WIN32))
-#define __WIN32__
-#endif
-
-/*
- * On windows you should define USE_WIN32_FILEIO if you are using tif_win32.c
- * or AVOID_WIN32_FILEIO if you are using something else (like tif_unix.c).
- *
- * By default tif_unix.c is assumed.
- */
-
-#if defined(_WINDOWS) || defined(__WIN32__) || defined(_Windows)
-#  if !defined(__CYGWIN) && !defined(AVOID_WIN32_FILEIO) && !defined(USE_WIN32_FILEIO)
-#    define AVOID_WIN32_FILEIO
-#  endif
-#endif
-
-#if defined(USE_WIN32_FILEIO)
-# define VC_EXTRALEAN
-# include <windows.h>
-# ifdef __WIN32__
-DECLARE_HANDLE(thandle_t);     /* Win32 file handle */
-# else
-typedef HFILE thandle_t;       /* client data handle */
-# endif /* __WIN32__ */
-#else
-typedef void* thandle_t;       /* client data handle */
-#endif /* USE_WIN32_FILEIO */
-
-/*
- * Flags to pass to TIFFPrintDirectory to control
- * printing of data structures that are potentially
- * very large.   Bit-or these flags to enable printing
- * multiple items.
- */
-#define TIFFPRINT_NONE	       0x0    /* no extra info */
-#define TIFFPRINT_STRIPS       0x1    /* strips/tiles info */
-#define TIFFPRINT_CURVES       0x2    /* color/gray response curves */
-#define TIFFPRINT_COLORMAP     0x4    /* colormap */
-#define TIFFPRINT_JPEGQTABLES  0x100  /* JPEG Q matrices */
-#define TIFFPRINT_JPEGACTABLES 0x200  /* JPEG AC tables */
-#define TIFFPRINT_JPEGDCTABLES 0x200  /* JPEG DC tables */
-
-/* 
- * Colour conversion stuff
- */
-
-/* reference white */
-#define D65_X0 (95.0470F)
-#define D65_Y0 (100.0F)
-#define D65_Z0 (108.8827F)
-
-#define D50_X0 (96.4250F)
-#define D50_Y0 (100.0F)
-#define D50_Z0 (82.4680F)
-
-/* Structure for holding information about a display device. */
-
-typedef unsigned char TIFFRGBValue;               /* 8-bit samples */
-
-typedef struct {
-	float d_mat[3][3];                        /* XYZ -> luminance matrix */
-	float d_YCR;                              /* Light o/p for reference white */
-	float d_YCG;
-	float d_YCB;
-	uint32 d_Vrwr;                            /* Pixel values for ref. white */
-	uint32 d_Vrwg;
-	uint32 d_Vrwb;
-	float d_Y0R;                              /* Residual light for black pixel */
-	float d_Y0G;
-	float d_Y0B;
-	float d_gammaR;                           /* Gamma values for the three guns */
-	float d_gammaG;
-	float d_gammaB;
-} TIFFDisplay;
-
-typedef struct {                                  /* YCbCr->RGB support */
-	TIFFRGBValue* clamptab;                   /* range clamping table */
-	int* Cr_r_tab;
-	int* Cb_b_tab;
-	int32* Cr_g_tab;
-	int32* Cb_g_tab;
-	int32* Y_tab;
-} TIFFYCbCrToRGB;
-
-typedef struct {                                  /* CIE Lab 1976->RGB support */
-	int range;                                /* Size of conversion table */
-#define CIELABTORGB_TABLE_RANGE 1500
-	float rstep, gstep, bstep;
-	float X0, Y0, Z0;                         /* Reference white point */
-	TIFFDisplay display;
-	float Yr2r[CIELABTORGB_TABLE_RANGE + 1];  /* Conversion of Yr to r */
-	float Yg2g[CIELABTORGB_TABLE_RANGE + 1];  /* Conversion of Yg to g */
-	float Yb2b[CIELABTORGB_TABLE_RANGE + 1];  /* Conversion of Yb to b */
-} TIFFCIELabToRGB;
-
-/*
- * RGBA-style image support.
- */
-typedef struct _TIFFRGBAImage TIFFRGBAImage;
-/*
- * The image reading and conversion routines invoke
- * ``put routines'' to copy/image/whatever tiles of
- * raw image data.  A default set of routines are 
- * provided to convert/copy raw image data to 8-bit
- * packed ABGR format rasters.  Applications can supply
- * alternate routines that unpack the data into a
- * different format or, for example, unpack the data
- * and draw the unpacked raster on the display.
- */
-typedef void (*tileContigRoutine)
-    (TIFFRGBAImage*, uint32*, uint32, uint32, uint32, uint32, int32, int32,
-	unsigned char*);
-typedef void (*tileSeparateRoutine)
-    (TIFFRGBAImage*, uint32*, uint32, uint32, uint32, uint32, int32, int32,
-	unsigned char*, unsigned char*, unsigned char*, unsigned char*);
-/*
- * RGBA-reader state.
- */
-struct _TIFFRGBAImage {
-	TIFF* tif;                              /* image handle */
-	int stoponerr;                          /* stop on read error */
-	int isContig;                           /* data is packed/separate */
-	int alpha;                              /* type of alpha data present */
-	uint32 width;                           /* image width */
-	uint32 height;                          /* image height */
-	uint16 bitspersample;                   /* image bits/sample */
-	uint16 samplesperpixel;                 /* image samples/pixel */
-	uint16 orientation;                     /* image orientation */
-	uint16 req_orientation;                 /* requested orientation */
-	uint16 photometric;                     /* image photometric interp */
-	uint16* redcmap;                        /* colormap pallete */
-	uint16* greencmap;
-	uint16* bluecmap;
-	/* get image data routine */
-	int (*get)(TIFFRGBAImage*, uint32*, uint32, uint32);
-	/* put decoded strip/tile */
-	union {
-	    void (*any)(TIFFRGBAImage*);
-	    tileContigRoutine contig;
-	    tileSeparateRoutine separate;
-	} put;
-	TIFFRGBValue* Map;                      /* sample mapping array */
-	uint32** BWmap;                         /* black&white map */
-	uint32** PALmap;                        /* palette image map */
-	TIFFYCbCrToRGB* ycbcr;                  /* YCbCr conversion state */
-	TIFFCIELabToRGB* cielab;                /* CIE L*a*b conversion state */
-
-	uint8* UaToAa;                          /* Unassociated alpha to associated alpha convertion LUT */
-	uint8* Bitdepth16To8;                   /* LUT for conversion from 16bit to 8bit values */
-
-	int row_offset;
-	int col_offset;
-};
-
-/*
- * Macros for extracting components from the
- * packed ABGR form returned by TIFFReadRGBAImage.
- */
-#define TIFFGetR(abgr) ((abgr) & 0xff)
-#define TIFFGetG(abgr) (((abgr) >> 8) & 0xff)
-#define TIFFGetB(abgr) (((abgr) >> 16) & 0xff)
-#define TIFFGetA(abgr) (((abgr) >> 24) & 0xff)
-
-/*
- * A CODEC is a software package that implements decoding,
- * encoding, or decoding+encoding of a compression algorithm.
- * The library provides a collection of builtin codecs.
- * More codecs may be registered through calls to the library
- * and/or the builtin implementations may be overridden.
- */
-typedef int (*TIFFInitMethod)(TIFF*, int);
-typedef struct {
-	char* name;
-	uint16 scheme;
-	TIFFInitMethod init;
-} TIFFCodec;
-
-#include <stdio.h>
-#include <stdarg.h>
-
-/* share internal LogLuv conversion routines? */
-#ifndef LOGLUV_PUBLIC
-#define LOGLUV_PUBLIC 1
-#endif
-
-#if !defined(__GNUC__) && !defined(__attribute__)
-#  define __attribute__(x) /*nothing*/
-#endif
-
-#if defined(c_plusplus) || defined(__cplusplus)
-extern "C" {
-#endif
-typedef void (*TIFFErrorHandler)(const char*, const char*, va_list);
-typedef void (*TIFFErrorHandlerExt)(thandle_t, const char*, const char*, va_list);
-typedef tmsize_t (*TIFFReadWriteProc)(thandle_t, void*, tmsize_t);
-typedef toff_t (*TIFFSeekProc)(thandle_t, toff_t, int);
-typedef int (*TIFFCloseProc)(thandle_t);
-typedef toff_t (*TIFFSizeProc)(thandle_t);
-typedef int (*TIFFMapFileProc)(thandle_t, void** base, toff_t* size);
-typedef void (*TIFFUnmapFileProc)(thandle_t, void* base, toff_t size);
-typedef void (*TIFFExtendProc)(TIFF*);
-
-extern const char* TIFFGetVersion(void);
-
-extern const TIFFCodec* TIFFFindCODEC(uint16);
-extern TIFFCodec* TIFFRegisterCODEC(uint16, const char*, TIFFInitMethod);
-extern void TIFFUnRegisterCODEC(TIFFCodec*);
-extern int TIFFIsCODECConfigured(uint16);
-extern TIFFCodec* TIFFGetConfiguredCODECs(void);
-
-/*
- * Auxiliary functions.
- */
-
-extern void* _TIFFmalloc(tmsize_t s);
-extern void* _TIFFrealloc(void* p, tmsize_t s);
-extern void _TIFFmemset(void* p, int v, tmsize_t c);
-extern void _TIFFmemcpy(void* d, const void* s, tmsize_t c);
-extern int _TIFFmemcmp(const void* p1, const void* p2, tmsize_t c);
-extern void _TIFFfree(void* p);
-
-/*
-** Stuff, related to tag handling and creating custom tags.
-*/
-extern int TIFFGetTagListCount( TIFF * );
-extern uint32 TIFFGetTagListEntry( TIFF *, int tag_index );
-    
-#define TIFF_ANY       TIFF_NOTYPE     /* for field descriptor searching */
-#define TIFF_VARIABLE  -1              /* marker for variable length tags */
-#define TIFF_SPP       -2              /* marker for SamplesPerPixel tags */
-#define TIFF_VARIABLE2 -3              /* marker for uint32 var-length tags */
-
-#define FIELD_CUSTOM    65
-
-typedef struct _TIFFField TIFFField;
-typedef struct _TIFFFieldArray TIFFFieldArray;
-
-extern const TIFFField* TIFFFindField(TIFF *, uint32, TIFFDataType);
-extern const TIFFField* TIFFFieldWithTag(TIFF*, uint32);
-extern const TIFFField* TIFFFieldWithName(TIFF*, const char *);
-
-extern uint32 TIFFFieldTag(const TIFFField*);
-extern const char* TIFFFieldName(const TIFFField*);
-extern TIFFDataType TIFFFieldDataType(const TIFFField*);
-extern int TIFFFieldPassCount(const TIFFField*);
-extern int TIFFFieldReadCount(const TIFFField*);
-extern int TIFFFieldWriteCount(const TIFFField*);
-
-typedef int (*TIFFVSetMethod)(TIFF*, uint32, va_list);
-typedef int (*TIFFVGetMethod)(TIFF*, uint32, va_list);
-typedef void (*TIFFPrintMethod)(TIFF*, FILE*, long);
-
-typedef struct {
-    TIFFVSetMethod vsetfield; /* tag set routine */
-    TIFFVGetMethod vgetfield; /* tag get routine */
-    TIFFPrintMethod printdir; /* directory print routine */
-} TIFFTagMethods;
-
-extern  TIFFTagMethods *TIFFAccessTagMethods(TIFF *);
-extern  void *TIFFGetClientInfo(TIFF *, const char *);
-extern  void TIFFSetClientInfo(TIFF *, void *, const char *);
-
-extern void TIFFCleanup(TIFF* tif);
-extern void TIFFClose(TIFF* tif);
-extern int TIFFFlush(TIFF* tif);
-extern int TIFFFlushData(TIFF* tif);
-extern int TIFFGetField(TIFF* tif, uint32 tag, ...);
-extern int TIFFVGetField(TIFF* tif, uint32 tag, va_list ap);
-extern int TIFFGetFieldDefaulted(TIFF* tif, uint32 tag, ...);
-extern int TIFFVGetFieldDefaulted(TIFF* tif, uint32 tag, va_list ap);
-extern int TIFFReadDirectory(TIFF* tif);
-extern int TIFFReadCustomDirectory(TIFF* tif, toff_t diroff, const TIFFFieldArray* infoarray);
-extern int TIFFReadEXIFDirectory(TIFF* tif, toff_t diroff);
-extern uint64 TIFFScanlineSize64(TIFF* tif);
-extern tmsize_t TIFFScanlineSize(TIFF* tif);
-extern uint64 TIFFRasterScanlineSize64(TIFF* tif);
-extern tmsize_t TIFFRasterScanlineSize(TIFF* tif);
-extern uint64 TIFFStripSize64(TIFF* tif);
-extern tmsize_t TIFFStripSize(TIFF* tif);
-extern uint64 TIFFRawStripSize64(TIFF* tif, uint32 strip);
-extern tmsize_t TIFFRawStripSize(TIFF* tif, uint32 strip);
-extern uint64 TIFFVStripSize64(TIFF* tif, uint32 nrows);
-extern tmsize_t TIFFVStripSize(TIFF* tif, uint32 nrows);
-extern uint64 TIFFTileRowSize64(TIFF* tif);
-extern tmsize_t TIFFTileRowSize(TIFF* tif);
-extern uint64 TIFFTileSize64(TIFF* tif);
-extern tmsize_t TIFFTileSize(TIFF* tif);
-extern uint64 TIFFVTileSize64(TIFF* tif, uint32 nrows);
-extern tmsize_t TIFFVTileSize(TIFF* tif, uint32 nrows);
-extern uint32 TIFFDefaultStripSize(TIFF* tif, uint32 request);
-extern void TIFFDefaultTileSize(TIFF*, uint32*, uint32*);
-extern int TIFFFileno(TIFF*);
-extern int TIFFSetFileno(TIFF*, int);
-extern thandle_t TIFFClientdata(TIFF*);
-extern thandle_t TIFFSetClientdata(TIFF*, thandle_t);
-extern int TIFFGetMode(TIFF*);
-extern int TIFFSetMode(TIFF*, int);
-extern int TIFFIsTiled(TIFF*);
-extern int TIFFIsByteSwapped(TIFF*);
-extern int TIFFIsUpSampled(TIFF*);
-extern int TIFFIsMSB2LSB(TIFF*);
-extern int TIFFIsBigEndian(TIFF*);
-extern TIFFReadWriteProc TIFFGetReadProc(TIFF*);
-extern TIFFReadWriteProc TIFFGetWriteProc(TIFF*);
-extern TIFFSeekProc TIFFGetSeekProc(TIFF*);                                                          
-extern TIFFCloseProc TIFFGetCloseProc(TIFF*);
-extern TIFFSizeProc TIFFGetSizeProc(TIFF*);
-extern TIFFMapFileProc TIFFGetMapFileProc(TIFF*);
-extern TIFFUnmapFileProc TIFFGetUnmapFileProc(TIFF*);
-extern uint32 TIFFCurrentRow(TIFF*);
-extern uint16 TIFFCurrentDirectory(TIFF*);
-extern uint16 TIFFNumberOfDirectories(TIFF*);
-extern uint64 TIFFCurrentDirOffset(TIFF*);
-extern uint32 TIFFCurrentStrip(TIFF*);
-extern uint32 TIFFCurrentTile(TIFF* tif);
-extern int TIFFReadBufferSetup(TIFF* tif, void* bp, tmsize_t size);
-extern int TIFFWriteBufferSetup(TIFF* tif, void* bp, tmsize_t size);  
-extern int TIFFSetupStrips(TIFF *);
-extern int TIFFWriteCheck(TIFF*, int, const char *);
-extern void TIFFFreeDirectory(TIFF*);
-extern int TIFFCreateDirectory(TIFF*);
-extern int TIFFCreateCustomDirectory(TIFF*,const TIFFFieldArray*);
-extern int TIFFCreateEXIFDirectory(TIFF*);
-extern int TIFFLastDirectory(TIFF*);
-extern int TIFFSetDirectory(TIFF*, uint16);
-extern int TIFFSetSubDirectory(TIFF*, uint64);
-extern int TIFFUnlinkDirectory(TIFF*, uint16);
-extern int TIFFSetField(TIFF*, uint32, ...);
-extern int TIFFVSetField(TIFF*, uint32, va_list);
-extern int TIFFUnsetField(TIFF*, uint32);
-extern int TIFFWriteDirectory(TIFF *);
-extern int TIFFWriteCustomDirectory(TIFF *, uint64 *);
-extern int TIFFCheckpointDirectory(TIFF *);
-extern int TIFFRewriteDirectory(TIFF *);
-
-#if defined(c_plusplus) || defined(__cplusplus)
-extern void TIFFPrintDirectory(TIFF*, FILE*, long = 0);
-extern int TIFFReadScanline(TIFF* tif, void* buf, uint32 row, uint16 sample = 0);
-extern int TIFFWriteScanline(TIFF* tif, void* buf, uint32 row, uint16 sample = 0);
-extern int TIFFReadRGBAImage(TIFF*, uint32, uint32, uint32*, int = 0);
-extern int TIFFReadRGBAImageOriented(TIFF*, uint32, uint32, uint32*,
-    int = ORIENTATION_BOTLEFT, int = 0);
-#else
-extern void TIFFPrintDirectory(TIFF*, FILE*, long);
-extern int TIFFReadScanline(TIFF* tif, void* buf, uint32 row, uint16 sample);
-extern int TIFFWriteScanline(TIFF* tif, void* buf, uint32 row, uint16 sample);
-extern int TIFFReadRGBAImage(TIFF*, uint32, uint32, uint32*, int);
-extern int TIFFReadRGBAImageOriented(TIFF*, uint32, uint32, uint32*, int, int);
-#endif
-
-extern int TIFFReadRGBAStrip(TIFF*, uint32, uint32 * );
-extern int TIFFReadRGBATile(TIFF*, uint32, uint32, uint32 * );
-extern int TIFFRGBAImageOK(TIFF*, char [1024]);
-extern int TIFFRGBAImageBegin(TIFFRGBAImage*, TIFF*, int, char [1024]);
-extern int TIFFRGBAImageGet(TIFFRGBAImage*, uint32*, uint32, uint32);
-extern void TIFFRGBAImageEnd(TIFFRGBAImage*);
-extern TIFF* TIFFOpen(const char*, const char*);
-# ifdef __WIN32__
-extern TIFF* TIFFOpenW(const wchar_t*, const char*);
-# endif /* __WIN32__ */
-extern TIFF* TIFFFdOpen(int, const char*, const char*);
-extern TIFF* TIFFClientOpen(const char*, const char*,
-	    thandle_t,
-	    TIFFReadWriteProc, TIFFReadWriteProc,
-	    TIFFSeekProc, TIFFCloseProc,
-	    TIFFSizeProc,
-	    TIFFMapFileProc, TIFFUnmapFileProc);
-extern const char* TIFFFileName(TIFF*);
-extern const char* TIFFSetFileName(TIFF*, const char *);
-extern void TIFFError(const char*, const char*, ...) __attribute__((__format__ (__printf__,2,3)));
-extern void TIFFErrorExt(thandle_t, const char*, const char*, ...) __attribute__((__format__ (__printf__,3,4)));
-extern void TIFFWarning(const char*, const char*, ...) __attribute__((__format__ (__printf__,2,3)));
-extern void TIFFWarningExt(thandle_t, const char*, const char*, ...) __attribute__((__format__ (__printf__,3,4)));
-extern TIFFErrorHandler TIFFSetErrorHandler(TIFFErrorHandler);
-extern TIFFErrorHandlerExt TIFFSetErrorHandlerExt(TIFFErrorHandlerExt);
-extern TIFFErrorHandler TIFFSetWarningHandler(TIFFErrorHandler);
-extern TIFFErrorHandlerExt TIFFSetWarningHandlerExt(TIFFErrorHandlerExt);
-extern TIFFExtendProc TIFFSetTagExtender(TIFFExtendProc);
-extern uint32 TIFFComputeTile(TIFF* tif, uint32 x, uint32 y, uint32 z, uint16 s);
-extern int TIFFCheckTile(TIFF* tif, uint32 x, uint32 y, uint32 z, uint16 s);
-extern uint32 TIFFNumberOfTiles(TIFF*);
-extern tmsize_t TIFFReadTile(TIFF* tif, void* buf, uint32 x, uint32 y, uint32 z, uint16 s);  
-extern tmsize_t TIFFWriteTile(TIFF* tif, void* buf, uint32 x, uint32 y, uint32 z, uint16 s);
-extern uint32 TIFFComputeStrip(TIFF*, uint32, uint16);
-extern uint32 TIFFNumberOfStrips(TIFF*);
-extern tmsize_t TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size);
-extern tmsize_t TIFFReadRawStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size);  
-extern tmsize_t TIFFReadEncodedTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size);  
-extern tmsize_t TIFFReadRawTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size);  
-extern tmsize_t TIFFWriteEncodedStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc);
-extern tmsize_t TIFFWriteRawStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc);  
-extern tmsize_t TIFFWriteEncodedTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc);  
-extern tmsize_t TIFFWriteRawTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc);  
-extern int TIFFDataWidth(TIFFDataType);    /* table of tag datatype widths */
-extern void TIFFSetWriteOffset(TIFF* tif, toff_t off);
-extern void TIFFSwabShort(uint16*);
-extern void TIFFSwabLong(uint32*);
-extern void TIFFSwabLong8(uint64*);
-extern void TIFFSwabFloat(float*);
-extern void TIFFSwabDouble(double*);
-extern void TIFFSwabArrayOfShort(uint16* wp, tmsize_t n);
-extern void TIFFSwabArrayOfTriples(uint8* tp, tmsize_t n);
-extern void TIFFSwabArrayOfLong(uint32* lp, tmsize_t n);
-extern void TIFFSwabArrayOfLong8(uint64* lp, tmsize_t n);
-extern void TIFFSwabArrayOfFloat(float* fp, tmsize_t n);
-extern void TIFFSwabArrayOfDouble(double* dp, tmsize_t n);
-extern void TIFFReverseBits(uint8* cp, tmsize_t n);
-extern const unsigned char* TIFFGetBitRevTable(int);
-
-#ifdef LOGLUV_PUBLIC
-#define U_NEU		0.210526316
-#define V_NEU		0.473684211
-#define UVSCALE		410.
-extern double LogL16toY(int);
-extern double LogL10toY(int);
-extern void XYZtoRGB24(float*, uint8*);
-extern int uv_decode(double*, double*, int);
-extern void LogLuv24toXYZ(uint32, float*);
-extern void LogLuv32toXYZ(uint32, float*);
-#if defined(c_plusplus) || defined(__cplusplus)
-extern int LogL16fromY(double, int = SGILOGENCODE_NODITHER);
-extern int LogL10fromY(double, int = SGILOGENCODE_NODITHER);
-extern int uv_encode(double, double, int = SGILOGENCODE_NODITHER);
-extern uint32 LogLuv24fromXYZ(float*, int = SGILOGENCODE_NODITHER);
-extern uint32 LogLuv32fromXYZ(float*, int = SGILOGENCODE_NODITHER);
-#else
-extern int LogL16fromY(double, int);
-extern int LogL10fromY(double, int);
-extern int uv_encode(double, double, int);
-extern uint32 LogLuv24fromXYZ(float*, int);
-extern uint32 LogLuv32fromXYZ(float*, int);
-#endif
-#endif /* LOGLUV_PUBLIC */
-
-extern int TIFFCIELabToRGBInit(TIFFCIELabToRGB*, const TIFFDisplay *, float*);
-extern void TIFFCIELabToXYZ(TIFFCIELabToRGB *, uint32, int32, int32,
-    float *, float *, float *);
-extern void TIFFXYZToRGB(TIFFCIELabToRGB *, float, float, float,
-    uint32 *, uint32 *, uint32 *);
-
-extern int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB*, float*, float*);
-extern void TIFFYCbCrtoRGB(TIFFYCbCrToRGB *, uint32, int32, int32,
-    uint32 *, uint32 *, uint32 *);
-
-/****************************************************************************
- *               O B S O L E T E D    I N T E R F A C E S
- *
- * Don't use this stuff in your applications, it may be removed in the future
- * libtiff versions.
- ****************************************************************************/
-typedef	struct {
-	ttag_t	field_tag;		/* field's tag */
-	short	field_readcount;	/* read count/TIFF_VARIABLE/TIFF_SPP */
-	short	field_writecount;	/* write count/TIFF_VARIABLE */
-	TIFFDataType field_type;	/* type of associated data */
-        unsigned short field_bit;	/* bit in fieldsset bit vector */
-	unsigned char field_oktochange;	/* if true, can change while writing */
-	unsigned char field_passcount;	/* if true, pass dir count on set */
-	char	*field_name;		/* ASCII name */
-} TIFFFieldInfo;
-
-extern int TIFFMergeFieldInfo(TIFF*, const TIFFFieldInfo[], uint32);
-        
-#if defined(c_plusplus) || defined(__cplusplus)
-}
-#endif
-
-#endif /* _TIFFIO_ */
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Id: tiffio.h,v 1.11 2015/02/19 22:39:59 drolon Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef _TIFFIO_
+#define	_TIFFIO_
+
+/*
+ * TIFF I/O Library Definitions.
+ */
+#include "tiff.h"
+#include "tiffvers.h"
+
+/*
+ * TIFF is defined as an incomplete type to hide the
+ * library's internal data structures from clients.
+ */
+typedef struct tiff TIFF;
+
+/*
+ * The following typedefs define the intrinsic size of
+ * data types used in the *exported* interfaces.  These
+ * definitions depend on the proper definition of types
+ * in tiff.h.  Note also that the varargs interface used
+ * to pass tag types and values uses the types defined in
+ * tiff.h directly.
+ *
+ * NB: ttag_t is unsigned int and not unsigned short because
+ *     ANSI C requires that the type before the ellipsis be a
+ *     promoted type (i.e. one of int, unsigned int, pointer,
+ *     or double) and because we defined pseudo-tags that are
+ *     outside the range of legal Aldus-assigned tags.
+ * NB: tsize_t is int32 and not uint32 because some functions
+ *     return -1.
+ * NB: toff_t is not off_t for many reasons; TIFFs max out at
+ *     32-bit file offsets, and BigTIFF maxes out at 64-bit
+ *     offsets being the most important, and to ensure use of
+ *     a consistently unsigned type across architectures.
+ *     Prior to libtiff 4.0, this was an unsigned 32 bit type.
+ */
+/*
+ * this is the machine addressing size type, only it's signed, so make it
+ * int32 on 32bit machines, int64 on 64bit machines
+ */
+typedef TIFF_SSIZE_T tmsize_t;
+typedef uint64 toff_t;          /* file offset */
+/* the following are deprecated and should be replaced by their defining
+   counterparts */
+typedef uint32 ttag_t;          /* directory tag */
+typedef uint16 tdir_t;          /* directory index */
+typedef uint16 tsample_t;       /* sample number */
+typedef uint32 tstrile_t;       /* strip or tile number */
+typedef tstrile_t tstrip_t;     /* strip number */
+typedef tstrile_t ttile_t;      /* tile number */
+typedef tmsize_t tsize_t;       /* i/o size in bytes */
+typedef void* tdata_t;          /* image data ref */
+
+#if !defined(__WIN32__) && (defined(_WIN32) || defined(WIN32))
+#define __WIN32__
+#endif
+
+/*
+ * On windows you should define USE_WIN32_FILEIO if you are using tif_win32.c
+ * or AVOID_WIN32_FILEIO if you are using something else (like tif_unix.c).
+ *
+ * By default tif_unix.c is assumed.
+ */
+
+#if defined(_WINDOWS) || defined(__WIN32__) || defined(_Windows)
+#  if !defined(__CYGWIN) && !defined(AVOID_WIN32_FILEIO) && !defined(USE_WIN32_FILEIO)
+#    define AVOID_WIN32_FILEIO
+#  endif
+#endif
+
+#if defined(USE_WIN32_FILEIO)
+# define VC_EXTRALEAN
+# include <windows.h>
+# ifdef __WIN32__
+DECLARE_HANDLE(thandle_t);     /* Win32 file handle */
+# else
+typedef HFILE thandle_t;       /* client data handle */
+# endif /* __WIN32__ */
+#else
+typedef void* thandle_t;       /* client data handle */
+#endif /* USE_WIN32_FILEIO */
+
+/*
+ * Flags to pass to TIFFPrintDirectory to control
+ * printing of data structures that are potentially
+ * very large.   Bit-or these flags to enable printing
+ * multiple items.
+ */
+#define TIFFPRINT_NONE	       0x0    /* no extra info */
+#define TIFFPRINT_STRIPS       0x1    /* strips/tiles info */
+#define TIFFPRINT_CURVES       0x2    /* color/gray response curves */
+#define TIFFPRINT_COLORMAP     0x4    /* colormap */
+#define TIFFPRINT_JPEGQTABLES  0x100  /* JPEG Q matrices */
+#define TIFFPRINT_JPEGACTABLES 0x200  /* JPEG AC tables */
+#define TIFFPRINT_JPEGDCTABLES 0x200  /* JPEG DC tables */
+
+/* 
+ * Colour conversion stuff
+ */
+
+/* reference white */
+#define D65_X0 (95.0470F)
+#define D65_Y0 (100.0F)
+#define D65_Z0 (108.8827F)
+
+#define D50_X0 (96.4250F)
+#define D50_Y0 (100.0F)
+#define D50_Z0 (82.4680F)
+
+/* Structure for holding information about a display device. */
+
+typedef unsigned char TIFFRGBValue;               /* 8-bit samples */
+
+typedef struct {
+	float d_mat[3][3];                        /* XYZ -> luminance matrix */
+	float d_YCR;                              /* Light o/p for reference white */
+	float d_YCG;
+	float d_YCB;
+	uint32 d_Vrwr;                            /* Pixel values for ref. white */
+	uint32 d_Vrwg;
+	uint32 d_Vrwb;
+	float d_Y0R;                              /* Residual light for black pixel */
+	float d_Y0G;
+	float d_Y0B;
+	float d_gammaR;                           /* Gamma values for the three guns */
+	float d_gammaG;
+	float d_gammaB;
+} TIFFDisplay;
+
+typedef struct {                                  /* YCbCr->RGB support */
+	TIFFRGBValue* clamptab;                   /* range clamping table */
+	int* Cr_r_tab;
+	int* Cb_b_tab;
+	int32* Cr_g_tab;
+	int32* Cb_g_tab;
+	int32* Y_tab;
+} TIFFYCbCrToRGB;
+
+typedef struct {                                  /* CIE Lab 1976->RGB support */
+	int range;                                /* Size of conversion table */
+#define CIELABTORGB_TABLE_RANGE 1500
+	float rstep, gstep, bstep;
+	float X0, Y0, Z0;                         /* Reference white point */
+	TIFFDisplay display;
+	float Yr2r[CIELABTORGB_TABLE_RANGE + 1];  /* Conversion of Yr to r */
+	float Yg2g[CIELABTORGB_TABLE_RANGE + 1];  /* Conversion of Yg to g */
+	float Yb2b[CIELABTORGB_TABLE_RANGE + 1];  /* Conversion of Yb to b */
+} TIFFCIELabToRGB;
+
+/*
+ * RGBA-style image support.
+ */
+typedef struct _TIFFRGBAImage TIFFRGBAImage;
+/*
+ * The image reading and conversion routines invoke
+ * ``put routines'' to copy/image/whatever tiles of
+ * raw image data.  A default set of routines are 
+ * provided to convert/copy raw image data to 8-bit
+ * packed ABGR format rasters.  Applications can supply
+ * alternate routines that unpack the data into a
+ * different format or, for example, unpack the data
+ * and draw the unpacked raster on the display.
+ */
+typedef void (*tileContigRoutine)
+    (TIFFRGBAImage*, uint32*, uint32, uint32, uint32, uint32, int32, int32,
+	unsigned char*);
+typedef void (*tileSeparateRoutine)
+    (TIFFRGBAImage*, uint32*, uint32, uint32, uint32, uint32, int32, int32,
+	unsigned char*, unsigned char*, unsigned char*, unsigned char*);
+/*
+ * RGBA-reader state.
+ */
+struct _TIFFRGBAImage {
+	TIFF* tif;                              /* image handle */
+	int stoponerr;                          /* stop on read error */
+	int isContig;                           /* data is packed/separate */
+	int alpha;                              /* type of alpha data present */
+	uint32 width;                           /* image width */
+	uint32 height;                          /* image height */
+	uint16 bitspersample;                   /* image bits/sample */
+	uint16 samplesperpixel;                 /* image samples/pixel */
+	uint16 orientation;                     /* image orientation */
+	uint16 req_orientation;                 /* requested orientation */
+	uint16 photometric;                     /* image photometric interp */
+	uint16* redcmap;                        /* colormap pallete */
+	uint16* greencmap;
+	uint16* bluecmap;
+	/* get image data routine */
+	int (*get)(TIFFRGBAImage*, uint32*, uint32, uint32);
+	/* put decoded strip/tile */
+	union {
+	    void (*any)(TIFFRGBAImage*);
+	    tileContigRoutine contig;
+	    tileSeparateRoutine separate;
+	} put;
+	TIFFRGBValue* Map;                      /* sample mapping array */
+	uint32** BWmap;                         /* black&white map */
+	uint32** PALmap;                        /* palette image map */
+	TIFFYCbCrToRGB* ycbcr;                  /* YCbCr conversion state */
+	TIFFCIELabToRGB* cielab;                /* CIE L*a*b conversion state */
+
+	uint8* UaToAa;                          /* Unassociated alpha to associated alpha convertion LUT */
+	uint8* Bitdepth16To8;                   /* LUT for conversion from 16bit to 8bit values */
+
+	int row_offset;
+	int col_offset;
+};
+
+/*
+ * Macros for extracting components from the
+ * packed ABGR form returned by TIFFReadRGBAImage.
+ */
+#define TIFFGetR(abgr) ((abgr) & 0xff)
+#define TIFFGetG(abgr) (((abgr) >> 8) & 0xff)
+#define TIFFGetB(abgr) (((abgr) >> 16) & 0xff)
+#define TIFFGetA(abgr) (((abgr) >> 24) & 0xff)
+
+/*
+ * A CODEC is a software package that implements decoding,
+ * encoding, or decoding+encoding of a compression algorithm.
+ * The library provides a collection of builtin codecs.
+ * More codecs may be registered through calls to the library
+ * and/or the builtin implementations may be overridden.
+ */
+typedef int (*TIFFInitMethod)(TIFF*, int);
+typedef struct {
+	char* name;
+	uint16 scheme;
+	TIFFInitMethod init;
+} TIFFCodec;
+
+#include <stdio.h>
+#include <stdarg.h>
+
+/* share internal LogLuv conversion routines? */
+#ifndef LOGLUV_PUBLIC
+#define LOGLUV_PUBLIC 1
+#endif
+
+#if !defined(__GNUC__) && !defined(__attribute__)
+#  define __attribute__(x) /*nothing*/
+#endif
+
+#if defined(c_plusplus) || defined(__cplusplus)
+extern "C" {
+#endif
+typedef void (*TIFFErrorHandler)(const char*, const char*, va_list);
+typedef void (*TIFFErrorHandlerExt)(thandle_t, const char*, const char*, va_list);
+typedef tmsize_t (*TIFFReadWriteProc)(thandle_t, void*, tmsize_t);
+typedef toff_t (*TIFFSeekProc)(thandle_t, toff_t, int);
+typedef int (*TIFFCloseProc)(thandle_t);
+typedef toff_t (*TIFFSizeProc)(thandle_t);
+typedef int (*TIFFMapFileProc)(thandle_t, void** base, toff_t* size);
+typedef void (*TIFFUnmapFileProc)(thandle_t, void* base, toff_t size);
+typedef void (*TIFFExtendProc)(TIFF*);
+
+extern const char* TIFFGetVersion(void);
+
+extern const TIFFCodec* TIFFFindCODEC(uint16);
+extern TIFFCodec* TIFFRegisterCODEC(uint16, const char*, TIFFInitMethod);
+extern void TIFFUnRegisterCODEC(TIFFCodec*);
+extern int TIFFIsCODECConfigured(uint16);
+extern TIFFCodec* TIFFGetConfiguredCODECs(void);
+
+/*
+ * Auxiliary functions.
+ */
+
+extern void* _TIFFmalloc(tmsize_t s);
+extern void* _TIFFrealloc(void* p, tmsize_t s);
+extern void _TIFFmemset(void* p, int v, tmsize_t c);
+extern void _TIFFmemcpy(void* d, const void* s, tmsize_t c);
+extern int _TIFFmemcmp(const void* p1, const void* p2, tmsize_t c);
+extern void _TIFFfree(void* p);
+
+/*
+** Stuff, related to tag handling and creating custom tags.
+*/
+extern int TIFFGetTagListCount( TIFF * );
+extern uint32 TIFFGetTagListEntry( TIFF *, int tag_index );
+    
+#define TIFF_ANY       TIFF_NOTYPE     /* for field descriptor searching */
+#define TIFF_VARIABLE  -1              /* marker for variable length tags */
+#define TIFF_SPP       -2              /* marker for SamplesPerPixel tags */
+#define TIFF_VARIABLE2 -3              /* marker for uint32 var-length tags */
+
+#define FIELD_CUSTOM    65
+
+typedef struct _TIFFField TIFFField;
+typedef struct _TIFFFieldArray TIFFFieldArray;
+
+extern const TIFFField* TIFFFindField(TIFF *, uint32, TIFFDataType);
+extern const TIFFField* TIFFFieldWithTag(TIFF*, uint32);
+extern const TIFFField* TIFFFieldWithName(TIFF*, const char *);
+
+extern uint32 TIFFFieldTag(const TIFFField*);
+extern const char* TIFFFieldName(const TIFFField*);
+extern TIFFDataType TIFFFieldDataType(const TIFFField*);
+extern int TIFFFieldPassCount(const TIFFField*);
+extern int TIFFFieldReadCount(const TIFFField*);
+extern int TIFFFieldWriteCount(const TIFFField*);
+
+typedef int (*TIFFVSetMethod)(TIFF*, uint32, va_list);
+typedef int (*TIFFVGetMethod)(TIFF*, uint32, va_list);
+typedef void (*TIFFPrintMethod)(TIFF*, FILE*, long);
+
+typedef struct {
+    TIFFVSetMethod vsetfield; /* tag set routine */
+    TIFFVGetMethod vgetfield; /* tag get routine */
+    TIFFPrintMethod printdir; /* directory print routine */
+} TIFFTagMethods;
+
+extern  TIFFTagMethods *TIFFAccessTagMethods(TIFF *);
+extern  void *TIFFGetClientInfo(TIFF *, const char *);
+extern  void TIFFSetClientInfo(TIFF *, void *, const char *);
+
+extern void TIFFCleanup(TIFF* tif);
+extern void TIFFClose(TIFF* tif);
+extern int TIFFFlush(TIFF* tif);
+extern int TIFFFlushData(TIFF* tif);
+extern int TIFFGetField(TIFF* tif, uint32 tag, ...);
+extern int TIFFVGetField(TIFF* tif, uint32 tag, va_list ap);
+extern int TIFFGetFieldDefaulted(TIFF* tif, uint32 tag, ...);
+extern int TIFFVGetFieldDefaulted(TIFF* tif, uint32 tag, va_list ap);
+extern int TIFFReadDirectory(TIFF* tif);
+extern int TIFFReadCustomDirectory(TIFF* tif, toff_t diroff, const TIFFFieldArray* infoarray);
+extern int TIFFReadEXIFDirectory(TIFF* tif, toff_t diroff);
+extern uint64 TIFFScanlineSize64(TIFF* tif);
+extern tmsize_t TIFFScanlineSize(TIFF* tif);
+extern uint64 TIFFRasterScanlineSize64(TIFF* tif);
+extern tmsize_t TIFFRasterScanlineSize(TIFF* tif);
+extern uint64 TIFFStripSize64(TIFF* tif);
+extern tmsize_t TIFFStripSize(TIFF* tif);
+extern uint64 TIFFRawStripSize64(TIFF* tif, uint32 strip);
+extern tmsize_t TIFFRawStripSize(TIFF* tif, uint32 strip);
+extern uint64 TIFFVStripSize64(TIFF* tif, uint32 nrows);
+extern tmsize_t TIFFVStripSize(TIFF* tif, uint32 nrows);
+extern uint64 TIFFTileRowSize64(TIFF* tif);
+extern tmsize_t TIFFTileRowSize(TIFF* tif);
+extern uint64 TIFFTileSize64(TIFF* tif);
+extern tmsize_t TIFFTileSize(TIFF* tif);
+extern uint64 TIFFVTileSize64(TIFF* tif, uint32 nrows);
+extern tmsize_t TIFFVTileSize(TIFF* tif, uint32 nrows);
+extern uint32 TIFFDefaultStripSize(TIFF* tif, uint32 request);
+extern void TIFFDefaultTileSize(TIFF*, uint32*, uint32*);
+extern int TIFFFileno(TIFF*);
+extern int TIFFSetFileno(TIFF*, int);
+extern thandle_t TIFFClientdata(TIFF*);
+extern thandle_t TIFFSetClientdata(TIFF*, thandle_t);
+extern int TIFFGetMode(TIFF*);
+extern int TIFFSetMode(TIFF*, int);
+extern int TIFFIsTiled(TIFF*);
+extern int TIFFIsByteSwapped(TIFF*);
+extern int TIFFIsUpSampled(TIFF*);
+extern int TIFFIsMSB2LSB(TIFF*);
+extern int TIFFIsBigEndian(TIFF*);
+extern TIFFReadWriteProc TIFFGetReadProc(TIFF*);
+extern TIFFReadWriteProc TIFFGetWriteProc(TIFF*);
+extern TIFFSeekProc TIFFGetSeekProc(TIFF*);                                                          
+extern TIFFCloseProc TIFFGetCloseProc(TIFF*);
+extern TIFFSizeProc TIFFGetSizeProc(TIFF*);
+extern TIFFMapFileProc TIFFGetMapFileProc(TIFF*);
+extern TIFFUnmapFileProc TIFFGetUnmapFileProc(TIFF*);
+extern uint32 TIFFCurrentRow(TIFF*);
+extern uint16 TIFFCurrentDirectory(TIFF*);
+extern uint16 TIFFNumberOfDirectories(TIFF*);
+extern uint64 TIFFCurrentDirOffset(TIFF*);
+extern uint32 TIFFCurrentStrip(TIFF*);
+extern uint32 TIFFCurrentTile(TIFF* tif);
+extern int TIFFReadBufferSetup(TIFF* tif, void* bp, tmsize_t size);
+extern int TIFFWriteBufferSetup(TIFF* tif, void* bp, tmsize_t size);  
+extern int TIFFSetupStrips(TIFF *);
+extern int TIFFWriteCheck(TIFF*, int, const char *);
+extern void TIFFFreeDirectory(TIFF*);
+extern int TIFFCreateDirectory(TIFF*);
+extern int TIFFCreateCustomDirectory(TIFF*,const TIFFFieldArray*);
+extern int TIFFCreateEXIFDirectory(TIFF*);
+extern int TIFFLastDirectory(TIFF*);
+extern int TIFFSetDirectory(TIFF*, uint16);
+extern int TIFFSetSubDirectory(TIFF*, uint64);
+extern int TIFFUnlinkDirectory(TIFF*, uint16);
+extern int TIFFSetField(TIFF*, uint32, ...);
+extern int TIFFVSetField(TIFF*, uint32, va_list);
+extern int TIFFUnsetField(TIFF*, uint32);
+extern int TIFFWriteDirectory(TIFF *);
+extern int TIFFWriteCustomDirectory(TIFF *, uint64 *);
+extern int TIFFCheckpointDirectory(TIFF *);
+extern int TIFFRewriteDirectory(TIFF *);
+
+#if defined(c_plusplus) || defined(__cplusplus)
+extern void TIFFPrintDirectory(TIFF*, FILE*, long = 0);
+extern int TIFFReadScanline(TIFF* tif, void* buf, uint32 row, uint16 sample = 0);
+extern int TIFFWriteScanline(TIFF* tif, void* buf, uint32 row, uint16 sample = 0);
+extern int TIFFReadRGBAImage(TIFF*, uint32, uint32, uint32*, int = 0);
+extern int TIFFReadRGBAImageOriented(TIFF*, uint32, uint32, uint32*,
+    int = ORIENTATION_BOTLEFT, int = 0);
+#else
+extern void TIFFPrintDirectory(TIFF*, FILE*, long);
+extern int TIFFReadScanline(TIFF* tif, void* buf, uint32 row, uint16 sample);
+extern int TIFFWriteScanline(TIFF* tif, void* buf, uint32 row, uint16 sample);
+extern int TIFFReadRGBAImage(TIFF*, uint32, uint32, uint32*, int);
+extern int TIFFReadRGBAImageOriented(TIFF*, uint32, uint32, uint32*, int, int);
+#endif
+
+extern int TIFFReadRGBAStrip(TIFF*, uint32, uint32 * );
+extern int TIFFReadRGBATile(TIFF*, uint32, uint32, uint32 * );
+extern int TIFFRGBAImageOK(TIFF*, char [1024]);
+extern int TIFFRGBAImageBegin(TIFFRGBAImage*, TIFF*, int, char [1024]);
+extern int TIFFRGBAImageGet(TIFFRGBAImage*, uint32*, uint32, uint32);
+extern void TIFFRGBAImageEnd(TIFFRGBAImage*);
+extern TIFF* TIFFOpen(const char*, const char*);
+# ifdef __WIN32__
+extern TIFF* TIFFOpenW(const wchar_t*, const char*);
+# endif /* __WIN32__ */
+extern TIFF* TIFFFdOpen(int, const char*, const char*);
+extern TIFF* TIFFClientOpen(const char*, const char*,
+	    thandle_t,
+	    TIFFReadWriteProc, TIFFReadWriteProc,
+	    TIFFSeekProc, TIFFCloseProc,
+	    TIFFSizeProc,
+	    TIFFMapFileProc, TIFFUnmapFileProc);
+extern const char* TIFFFileName(TIFF*);
+extern const char* TIFFSetFileName(TIFF*, const char *);
+extern void TIFFError(const char*, const char*, ...) __attribute__((__format__ (__printf__,2,3)));
+extern void TIFFErrorExt(thandle_t, const char*, const char*, ...) __attribute__((__format__ (__printf__,3,4)));
+extern void TIFFWarning(const char*, const char*, ...) __attribute__((__format__ (__printf__,2,3)));
+extern void TIFFWarningExt(thandle_t, const char*, const char*, ...) __attribute__((__format__ (__printf__,3,4)));
+extern TIFFErrorHandler TIFFSetErrorHandler(TIFFErrorHandler);
+extern TIFFErrorHandlerExt TIFFSetErrorHandlerExt(TIFFErrorHandlerExt);
+extern TIFFErrorHandler TIFFSetWarningHandler(TIFFErrorHandler);
+extern TIFFErrorHandlerExt TIFFSetWarningHandlerExt(TIFFErrorHandlerExt);
+extern TIFFExtendProc TIFFSetTagExtender(TIFFExtendProc);
+extern uint32 TIFFComputeTile(TIFF* tif, uint32 x, uint32 y, uint32 z, uint16 s);
+extern int TIFFCheckTile(TIFF* tif, uint32 x, uint32 y, uint32 z, uint16 s);
+extern uint32 TIFFNumberOfTiles(TIFF*);
+extern tmsize_t TIFFReadTile(TIFF* tif, void* buf, uint32 x, uint32 y, uint32 z, uint16 s);  
+extern tmsize_t TIFFWriteTile(TIFF* tif, void* buf, uint32 x, uint32 y, uint32 z, uint16 s);
+extern uint32 TIFFComputeStrip(TIFF*, uint32, uint16);
+extern uint32 TIFFNumberOfStrips(TIFF*);
+extern tmsize_t TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size);
+extern tmsize_t TIFFReadRawStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size);  
+extern tmsize_t TIFFReadEncodedTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size);  
+extern tmsize_t TIFFReadRawTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size);  
+extern tmsize_t TIFFWriteEncodedStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc);
+extern tmsize_t TIFFWriteRawStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc);  
+extern tmsize_t TIFFWriteEncodedTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc);  
+extern tmsize_t TIFFWriteRawTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc);  
+extern int TIFFDataWidth(TIFFDataType);    /* table of tag datatype widths */
+extern void TIFFSetWriteOffset(TIFF* tif, toff_t off);
+extern void TIFFSwabShort(uint16*);
+extern void TIFFSwabLong(uint32*);
+extern void TIFFSwabLong8(uint64*);
+extern void TIFFSwabFloat(float*);
+extern void TIFFSwabDouble(double*);
+extern void TIFFSwabArrayOfShort(uint16* wp, tmsize_t n);
+extern void TIFFSwabArrayOfTriples(uint8* tp, tmsize_t n);
+extern void TIFFSwabArrayOfLong(uint32* lp, tmsize_t n);
+extern void TIFFSwabArrayOfLong8(uint64* lp, tmsize_t n);
+extern void TIFFSwabArrayOfFloat(float* fp, tmsize_t n);
+extern void TIFFSwabArrayOfDouble(double* dp, tmsize_t n);
+extern void TIFFReverseBits(uint8* cp, tmsize_t n);
+extern const unsigned char* TIFFGetBitRevTable(int);
+
+#ifdef LOGLUV_PUBLIC
+#define U_NEU		0.210526316
+#define V_NEU		0.473684211
+#define UVSCALE		410.
+extern double LogL16toY(int);
+extern double LogL10toY(int);
+extern void XYZtoRGB24(float*, uint8*);
+extern int uv_decode(double*, double*, int);
+extern void LogLuv24toXYZ(uint32, float*);
+extern void LogLuv32toXYZ(uint32, float*);
+#if defined(c_plusplus) || defined(__cplusplus)
+extern int LogL16fromY(double, int = SGILOGENCODE_NODITHER);
+extern int LogL10fromY(double, int = SGILOGENCODE_NODITHER);
+extern int uv_encode(double, double, int = SGILOGENCODE_NODITHER);
+extern uint32 LogLuv24fromXYZ(float*, int = SGILOGENCODE_NODITHER);
+extern uint32 LogLuv32fromXYZ(float*, int = SGILOGENCODE_NODITHER);
+#else
+extern int LogL16fromY(double, int);
+extern int LogL10fromY(double, int);
+extern int uv_encode(double, double, int);
+extern uint32 LogLuv24fromXYZ(float*, int);
+extern uint32 LogLuv32fromXYZ(float*, int);
+#endif
+#endif /* LOGLUV_PUBLIC */
+
+extern int TIFFCIELabToRGBInit(TIFFCIELabToRGB*, const TIFFDisplay *, float*);
+extern void TIFFCIELabToXYZ(TIFFCIELabToRGB *, uint32, int32, int32,
+    float *, float *, float *);
+extern void TIFFXYZToRGB(TIFFCIELabToRGB *, float, float, float,
+    uint32 *, uint32 *, uint32 *);
+
+extern int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB*, float*, float*);
+extern void TIFFYCbCrtoRGB(TIFFYCbCrToRGB *, uint32, int32, int32,
+    uint32 *, uint32 *, uint32 *);
+
+/****************************************************************************
+ *               O B S O L E T E D    I N T E R F A C E S
+ *
+ * Don't use this stuff in your applications, it may be removed in the future
+ * libtiff versions.
+ ****************************************************************************/
+typedef	struct {
+	ttag_t	field_tag;		/* field's tag */
+	short	field_readcount;	/* read count/TIFF_VARIABLE/TIFF_SPP */
+	short	field_writecount;	/* write count/TIFF_VARIABLE */
+	TIFFDataType field_type;	/* type of associated data */
+        unsigned short field_bit;	/* bit in fieldsset bit vector */
+	unsigned char field_oktochange;	/* if true, can change while writing */
+	unsigned char field_passcount;	/* if true, pass dir count on set */
+	char	*field_name;		/* ASCII name */
+} TIFFFieldInfo;
+
+extern int TIFFMergeFieldInfo(TIFF*, const TIFFFieldInfo[], uint32);
+        
+#if defined(c_plusplus) || defined(__cplusplus)
+}
+#endif
+
+#endif /* _TIFFIO_ */
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tiffio.hxx b/Source/LibTIFF4/tiffio.hxx
index 7bf2cd1..7c332c1 100644
--- a/Source/LibTIFF4/tiffio.hxx
+++ b/Source/LibTIFF4/tiffio.hxx
@@ -1,4 +1,4 @@
-/* $Id: tiffio.hxx,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
+/* $Id: tiffio.hxx,v 1.11 2015/02/19 22:39:59 drolon Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
diff --git a/Source/LibTIFF4/tiffiop.h b/Source/LibTIFF4/tiffiop.h
index 35174e6..2dce3e5 100644
--- a/Source/LibTIFF4/tiffiop.h
+++ b/Source/LibTIFF4/tiffiop.h
@@ -1,367 +1,367 @@
-/* $Id: tiffiop.h,v 1.4 2012/10/07 15:54:03 drolon Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and 
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- * 
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
- * 
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
- * OF THIS SOFTWARE.
- */
-
-#ifndef _TIFFIOP_
-#define	_TIFFIOP_
-/*
- * ``Library-private'' definitions.
- */
-
-#include "tif_config.h"
-
-#ifdef HAVE_FCNTL_H
-# include <fcntl.h>
-#endif
-
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-
-#ifdef HAVE_STRING_H
-# include <string.h>
-#endif
-
-#ifdef HAVE_ASSERT_H
-# include <assert.h>
-#else
-# define assert(x) 
-#endif
-
-#ifdef HAVE_SEARCH_H
-# include <search.h>
-#else
-extern void *lfind(const void *, const void *, size_t *, size_t,
-		   int (*)(const void *, const void *));
-#endif
-
-#include "tiffio.h"
-
-#include "tif_dir.h"
-
-#ifndef STRIP_SIZE_DEFAULT
-# define STRIP_SIZE_DEFAULT 8192
-#endif
-
-#define    streq(a,b)      (strcmp(a,b) == 0)
-
-#ifndef TRUE
-#define	TRUE	1
-#define	FALSE	0
-#endif
-
-typedef struct client_info {
-    struct client_info *next;
-    void *data;
-    char *name;
-} TIFFClientInfoLink;
-
-/*
- * Typedefs for ``method pointers'' used internally.
- * these are depriciated and provided only for backwards compatibility
- */
-typedef unsigned char tidataval_t;    /* internal image data value type */
-typedef tidataval_t* tidata_t;        /* reference to internal image data */
-
-typedef void (*TIFFVoidMethod)(TIFF*);
-typedef int (*TIFFBoolMethod)(TIFF*);
-typedef int (*TIFFPreMethod)(TIFF*, uint16);
-typedef int (*TIFFCodeMethod)(TIFF* tif, uint8* buf, tmsize_t size, uint16 sample);
-typedef int (*TIFFSeekMethod)(TIFF*, uint32);
-typedef void (*TIFFPostMethod)(TIFF* tif, uint8* buf, tmsize_t size);
-typedef uint32 (*TIFFStripMethod)(TIFF*, uint32);
-typedef void (*TIFFTileMethod)(TIFF*, uint32*, uint32*);
-
-struct tiff {
-	char*                tif_name;         /* name of open file */
-	int                  tif_fd;           /* open file descriptor */
-	int                  tif_mode;         /* open mode (O_*) */
-	uint32               tif_flags;
-	#define TIFF_FILLORDER   0x00003 /* natural bit fill order for machine */
-	#define TIFF_DIRTYHEADER 0x00004 /* header must be written on close */
-	#define TIFF_DIRTYDIRECT 0x00008 /* current directory must be written */
-	#define TIFF_BUFFERSETUP 0x00010 /* data buffers setup */
-	#define TIFF_CODERSETUP  0x00020 /* encoder/decoder setup done */
-	#define TIFF_BEENWRITING 0x00040 /* written 1+ scanlines to file */
-	#define TIFF_SWAB        0x00080 /* byte swap file information */
-	#define TIFF_NOBITREV    0x00100 /* inhibit bit reversal logic */
-	#define TIFF_MYBUFFER    0x00200 /* my raw data buffer; free on close */
-	#define TIFF_ISTILED     0x00400 /* file is tile, not strip- based */
-	#define TIFF_MAPPED      0x00800 /* file is mapped into memory */
-	#define TIFF_POSTENCODE  0x01000 /* need call to postencode routine */
-	#define TIFF_INSUBIFD    0x02000 /* currently writing a subifd */
-	#define TIFF_UPSAMPLED   0x04000 /* library is doing data up-sampling */
-	#define TIFF_STRIPCHOP   0x08000 /* enable strip chopping support */
-	#define TIFF_HEADERONLY  0x10000 /* read header only, do not process the first directory */
-	#define TIFF_NOREADRAW   0x20000 /* skip reading of raw uncompressed image data */
-	#define TIFF_INCUSTOMIFD 0x40000 /* currently writing a custom IFD */
-	#define TIFF_BIGTIFF     0x80000 /* read/write bigtiff */
-        #define TIFF_BUF4WRITE  0x100000 /* rawcc bytes are for writing */
-        #define TIFF_DIRTYSTRIP 0x200000 /* stripoffsets/stripbytecount dirty*/
-        #define TIFF_PERSAMPLE  0x400000 /* get/set per sample tags as arrays */
-        #define TIFF_BUFFERMMAP 0x800000 /* read buffer (tif_rawdata) points into mmap() memory */
-	uint64               tif_diroff;       /* file offset of current directory */
-	uint64               tif_nextdiroff;   /* file offset of following directory */
-	uint64*              tif_dirlist;      /* list of offsets to already seen directories to prevent IFD looping */
-	uint16               tif_dirlistsize;  /* number of entires in offset list */
-	uint16               tif_dirnumber;    /* number of already seen directories */
-	TIFFDirectory        tif_dir;          /* internal rep of current directory */
-	TIFFDirectory        tif_customdir;    /* custom IFDs are separated from the main ones */
-	union {
-		TIFFHeaderCommon common;
-		TIFFHeaderClassic classic;
-		TIFFHeaderBig big;
-	} tif_header;
-	uint16               tif_header_size;  /* file's header block and its length */
-	uint32               tif_row;          /* current scanline */
-	uint16               tif_curdir;       /* current directory (index) */
-	uint32               tif_curstrip;     /* current strip for read/write */
-	uint64               tif_curoff;       /* current offset for read/write */
-	uint64               tif_dataoff;      /* current offset for writing dir */
-	/* SubIFD support */
-	uint16               tif_nsubifd;      /* remaining subifds to write */
-	uint64               tif_subifdoff;    /* offset for patching SubIFD link */
-	/* tiling support */
-	uint32               tif_col;          /* current column (offset by row too) */
-	uint32               tif_curtile;      /* current tile for read/write */
-	tmsize_t             tif_tilesize;     /* # of bytes in a tile */
-	/* compression scheme hooks */
-	int                  tif_decodestatus;
-	TIFFBoolMethod       tif_fixuptags;    /* called in TIFFReadDirectory */
-	TIFFBoolMethod       tif_setupdecode;  /* called once before predecode */
-	TIFFPreMethod        tif_predecode;    /* pre- row/strip/tile decoding */
-	TIFFBoolMethod       tif_setupencode;  /* called once before preencode */
-	int                  tif_encodestatus;
-	TIFFPreMethod        tif_preencode;    /* pre- row/strip/tile encoding */
-	TIFFBoolMethod       tif_postencode;   /* post- row/strip/tile encoding */
-	TIFFCodeMethod       tif_decoderow;    /* scanline decoding routine */
-	TIFFCodeMethod       tif_encoderow;    /* scanline encoding routine */
-	TIFFCodeMethod       tif_decodestrip;  /* strip decoding routine */
-	TIFFCodeMethod       tif_encodestrip;  /* strip encoding routine */
-	TIFFCodeMethod       tif_decodetile;   /* tile decoding routine */
-	TIFFCodeMethod       tif_encodetile;   /* tile encoding routine */
-	TIFFVoidMethod       tif_close;        /* cleanup-on-close routine */
-	TIFFSeekMethod       tif_seek;         /* position within a strip routine */
-	TIFFVoidMethod       tif_cleanup;      /* cleanup state routine */
-	TIFFStripMethod      tif_defstripsize; /* calculate/constrain strip size */
-	TIFFTileMethod       tif_deftilesize;  /* calculate/constrain tile size */
-	uint8*               tif_data;         /* compression scheme private data */
-	/* input/output buffering */
-	tmsize_t             tif_scanlinesize; /* # of bytes in a scanline */
-	tmsize_t             tif_scanlineskew; /* scanline skew for reading strips */
-	uint8*               tif_rawdata;      /* raw data buffer */
-	tmsize_t             tif_rawdatasize;  /* # of bytes in raw data buffer */
-        tmsize_t             tif_rawdataoff;   /* rawdata offset within strip */
-        tmsize_t             tif_rawdataloaded;/* amount of data in rawdata */
-	uint8*               tif_rawcp;        /* current spot in raw buffer */
-	tmsize_t             tif_rawcc;        /* bytes unread from raw buffer */
-	/* memory-mapped file support */
-	uint8*               tif_base;         /* base of mapped file */
-	tmsize_t             tif_size;         /* size of mapped file region (bytes, thus tmsize_t) */
-	TIFFMapFileProc      tif_mapproc;      /* map file method */
-	TIFFUnmapFileProc    tif_unmapproc;    /* unmap file method */
-	/* input/output callback methods */
-	thandle_t            tif_clientdata;   /* callback parameter */
-	TIFFReadWriteProc    tif_readproc;     /* read method */
-	TIFFReadWriteProc    tif_writeproc;    /* write method */
-	TIFFSeekProc         tif_seekproc;     /* lseek method */
-	TIFFCloseProc        tif_closeproc;    /* close method */
-	TIFFSizeProc         tif_sizeproc;     /* filesize method */
-	/* post-decoding support */
-	TIFFPostMethod       tif_postdecode;   /* post decoding routine */
-	/* tag support */
-	TIFFField**          tif_fields;       /* sorted table of registered tags */
-	size_t               tif_nfields;      /* # entries in registered tag table */
-	const TIFFField*     tif_foundfield;   /* cached pointer to already found tag */
-	TIFFTagMethods       tif_tagmethods;   /* tag get/set/print routines */
-	TIFFClientInfoLink*  tif_clientinfo;   /* extra client information. */
-	/* Backward compatibility stuff. We need these two fields for
-	 * setting up an old tag extension scheme. */
-	TIFFFieldArray*      tif_fieldscompat;
-	size_t               tif_nfieldscompat;
-};
-
-#define isPseudoTag(t) (t > 0xffff)            /* is tag value normal or pseudo */
-
-#define isTiled(tif) (((tif)->tif_flags & TIFF_ISTILED) != 0)
-#define isMapped(tif) (((tif)->tif_flags & TIFF_MAPPED) != 0)
-#define isFillOrder(tif, o) (((tif)->tif_flags & (o)) != 0)
-#define isUpSampled(tif) (((tif)->tif_flags & TIFF_UPSAMPLED) != 0)
-#define TIFFReadFile(tif, buf, size) \
-	((*(tif)->tif_readproc)((tif)->tif_clientdata,(buf),(size)))
-#define TIFFWriteFile(tif, buf, size) \
-	((*(tif)->tif_writeproc)((tif)->tif_clientdata,(buf),(size)))
-#define TIFFSeekFile(tif, off, whence) \
-	((*(tif)->tif_seekproc)((tif)->tif_clientdata,(off),(whence)))
-#define TIFFCloseFile(tif) \
-	((*(tif)->tif_closeproc)((tif)->tif_clientdata))
-#define TIFFGetFileSize(tif) \
-	((*(tif)->tif_sizeproc)((tif)->tif_clientdata))
-#define TIFFMapFileContents(tif, paddr, psize) \
-	((*(tif)->tif_mapproc)((tif)->tif_clientdata,(paddr),(psize)))
-#define TIFFUnmapFileContents(tif, addr, size) \
-	((*(tif)->tif_unmapproc)((tif)->tif_clientdata,(addr),(size)))
-
-/*
- * Default Read/Seek/Write definitions.
- */
-#ifndef ReadOK
-#define ReadOK(tif, buf, size) \
-	(TIFFReadFile((tif),(buf),(size))==(size))
-#endif
-#ifndef SeekOK
-#define SeekOK(tif, off) \
-	(TIFFSeekFile((tif),(off),SEEK_SET)==(off))
-#endif
-#ifndef WriteOK
-#define WriteOK(tif, buf, size) \
-	(TIFFWriteFile((tif),(buf),(size))==(size))
-#endif
-
-/* NB: the uint32 casts are to silence certain ANSI-C compilers */
-#define TIFFhowmany_32(x, y) (((uint32)x < (0xffffffff - (uint32)(y-1))) ? \
-			   ((((uint32)(x))+(((uint32)(y))-1))/((uint32)(y))) : \
-			   0U)
-#define TIFFhowmany8_32(x) (((x)&0x07)?((uint32)(x)>>3)+1:(uint32)(x)>>3)
-#define TIFFroundup_32(x, y) (TIFFhowmany_32(x,y)*(y))
-#define TIFFhowmany_64(x, y) ((((uint64)(x))+(((uint64)(y))-1))/((uint64)(y)))
-#define TIFFhowmany8_64(x) (((x)&0x07)?((uint64)(x)>>3)+1:(uint64)(x)>>3)
-#define TIFFroundup_64(x, y) (TIFFhowmany_64(x,y)*(y))
-
-/* Safe multiply which returns zero if there is an integer overflow */
-#define TIFFSafeMultiply(t,v,m) ((((t)(m) != (t)0) && (((t)(((v)*(m))/(m))) == (t)(v))) ? (t)((v)*(m)) : (t)0)
-
-#define TIFFmax(A,B) ((A)>(B)?(A):(B))
-#define TIFFmin(A,B) ((A)<(B)?(A):(B))
-
-#define TIFFArrayCount(a) (sizeof (a) / sizeof ((a)[0]))
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-extern int _TIFFgetMode(const char* mode, const char* module);
-extern int _TIFFNoRowEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s);
-extern int _TIFFNoStripEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s);
-extern int _TIFFNoTileEncode(TIFF*, uint8* pp, tmsize_t cc, uint16 s);
-extern int _TIFFNoRowDecode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s);
-extern int _TIFFNoStripDecode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s);
-extern int _TIFFNoTileDecode(TIFF*, uint8* pp, tmsize_t cc, uint16 s);
-extern void _TIFFNoPostDecode(TIFF* tif, uint8* buf, tmsize_t cc);
-extern int _TIFFNoPreCode(TIFF* tif, uint16 s);
-extern int _TIFFNoSeek(TIFF* tif, uint32 off);
-extern void _TIFFSwab16BitData(TIFF* tif, uint8* buf, tmsize_t cc);
-extern void _TIFFSwab24BitData(TIFF* tif, uint8* buf, tmsize_t cc);
-extern void _TIFFSwab32BitData(TIFF* tif, uint8* buf, tmsize_t cc);
-extern void _TIFFSwab64BitData(TIFF* tif, uint8* buf, tmsize_t cc);
-extern int TIFFFlushData1(TIFF* tif);
-extern int TIFFDefaultDirectory(TIFF* tif);
-extern void _TIFFSetDefaultCompressionState(TIFF* tif);
-extern int _TIFFRewriteField(TIFF *, uint16, TIFFDataType, tmsize_t, void *);
-extern int TIFFSetCompressionScheme(TIFF* tif, int scheme);
-extern int TIFFSetDefaultCompressionState(TIFF* tif);
-extern uint32 _TIFFDefaultStripSize(TIFF* tif, uint32 s);
-extern void _TIFFDefaultTileSize(TIFF* tif, uint32* tw, uint32* th);
-extern int _TIFFDataSize(TIFFDataType type);
-
-extern void _TIFFsetByteArray(void**, void*, uint32);
-extern void _TIFFsetString(char**, char*);
-extern void _TIFFsetShortArray(uint16**, uint16*, uint32);
-extern void _TIFFsetLongArray(uint32**, uint32*, uint32);
-extern void _TIFFsetFloatArray(float**, float*, uint32);
-extern void _TIFFsetDoubleArray(double**, double*, uint32);
-
-extern void _TIFFprintAscii(FILE*, const char*);
-extern void _TIFFprintAsciiTag(FILE*, const char*, const char*);
-
-extern TIFFErrorHandler _TIFFwarningHandler;
-extern TIFFErrorHandler _TIFFerrorHandler;
-extern TIFFErrorHandlerExt _TIFFwarningHandlerExt;
-extern TIFFErrorHandlerExt _TIFFerrorHandlerExt;
-
-extern uint32 _TIFFMultiply32(TIFF*, uint32, uint32, const char*);
-extern uint64 _TIFFMultiply64(TIFF*, uint64, uint64, const char*);
-extern void* _TIFFCheckMalloc(TIFF*, tmsize_t, tmsize_t, const char*);
-extern void* _TIFFCheckRealloc(TIFF*, void*, tmsize_t, tmsize_t, const char*);
-
-extern double _TIFFUInt64ToDouble(uint64);
-extern float _TIFFUInt64ToFloat(uint64);
-
-extern int TIFFInitDumpMode(TIFF*, int);
-#ifdef PACKBITS_SUPPORT
-extern int TIFFInitPackBits(TIFF*, int);
-#endif
-#ifdef CCITT_SUPPORT
-extern int TIFFInitCCITTRLE(TIFF*, int), TIFFInitCCITTRLEW(TIFF*, int);
-extern int TIFFInitCCITTFax3(TIFF*, int), TIFFInitCCITTFax4(TIFF*, int);
-#endif
-#ifdef THUNDER_SUPPORT
-extern int TIFFInitThunderScan(TIFF*, int);
-#endif
-#ifdef NEXT_SUPPORT
-extern int TIFFInitNeXT(TIFF*, int);
-#endif
-#ifdef LZW_SUPPORT
-extern int TIFFInitLZW(TIFF*, int);
-#endif
-#ifdef OJPEG_SUPPORT
-extern int TIFFInitOJPEG(TIFF*, int);
-#endif
-#ifdef JPEG_SUPPORT
-extern int TIFFInitJPEG(TIFF*, int);
-#endif
-#ifdef JBIG_SUPPORT
-extern int TIFFInitJBIG(TIFF*, int);
-#endif
-#ifdef ZIP_SUPPORT
-extern int TIFFInitZIP(TIFF*, int);
-#endif
-#ifdef PIXARLOG_SUPPORT
-extern int TIFFInitPixarLog(TIFF*, int);
-#endif
-#ifdef LOGLUV_SUPPORT
-extern int TIFFInitSGILog(TIFF*, int);
-#endif
-#ifdef LZMA_SUPPORT
-extern int TIFFInitLZMA(TIFF*, int);
-#endif
-#ifdef VMS
-extern const TIFFCodec _TIFFBuiltinCODECS[];
-#else
-extern TIFFCodec _TIFFBuiltinCODECS[];
-#endif
-
-#if defined(__cplusplus)
-}
-#endif
-#endif /* _TIFFIOP_ */
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* $Id: tiffiop.h,v 1.11 2015/02/19 22:39:59 drolon Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and 
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
+ * 
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef _TIFFIOP_
+#define	_TIFFIOP_
+/*
+ * ``Library-private'' definitions.
+ */
+
+#include "tif_config.h"
+
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif
+
+#ifdef HAVE_ASSERT_H
+# include <assert.h>
+#else
+# define assert(x) 
+#endif
+
+#ifdef HAVE_SEARCH_H
+# include <search.h>
+#else
+extern void *lfind(const void *, const void *, size_t *, size_t,
+		   int (*)(const void *, const void *));
+#endif
+
+#include "tiffio.h"
+
+#include "tif_dir.h"
+
+#ifndef STRIP_SIZE_DEFAULT
+# define STRIP_SIZE_DEFAULT 8192
+#endif
+
+#define    streq(a,b)      (strcmp(a,b) == 0)
+
+#ifndef TRUE
+#define	TRUE	1
+#define	FALSE	0
+#endif
+
+typedef struct client_info {
+    struct client_info *next;
+    void *data;
+    char *name;
+} TIFFClientInfoLink;
+
+/*
+ * Typedefs for ``method pointers'' used internally.
+ * these are depriciated and provided only for backwards compatibility
+ */
+typedef unsigned char tidataval_t;    /* internal image data value type */
+typedef tidataval_t* tidata_t;        /* reference to internal image data */
+
+typedef void (*TIFFVoidMethod)(TIFF*);
+typedef int (*TIFFBoolMethod)(TIFF*);
+typedef int (*TIFFPreMethod)(TIFF*, uint16);
+typedef int (*TIFFCodeMethod)(TIFF* tif, uint8* buf, tmsize_t size, uint16 sample);
+typedef int (*TIFFSeekMethod)(TIFF*, uint32);
+typedef void (*TIFFPostMethod)(TIFF* tif, uint8* buf, tmsize_t size);
+typedef uint32 (*TIFFStripMethod)(TIFF*, uint32);
+typedef void (*TIFFTileMethod)(TIFF*, uint32*, uint32*);
+
+struct tiff {
+	char*                tif_name;         /* name of open file */
+	int                  tif_fd;           /* open file descriptor */
+	int                  tif_mode;         /* open mode (O_*) */
+	uint32               tif_flags;
+	#define TIFF_FILLORDER   0x00003 /* natural bit fill order for machine */
+	#define TIFF_DIRTYHEADER 0x00004 /* header must be written on close */
+	#define TIFF_DIRTYDIRECT 0x00008 /* current directory must be written */
+	#define TIFF_BUFFERSETUP 0x00010 /* data buffers setup */
+	#define TIFF_CODERSETUP  0x00020 /* encoder/decoder setup done */
+	#define TIFF_BEENWRITING 0x00040 /* written 1+ scanlines to file */
+	#define TIFF_SWAB        0x00080 /* byte swap file information */
+	#define TIFF_NOBITREV    0x00100 /* inhibit bit reversal logic */
+	#define TIFF_MYBUFFER    0x00200 /* my raw data buffer; free on close */
+	#define TIFF_ISTILED     0x00400 /* file is tile, not strip- based */
+	#define TIFF_MAPPED      0x00800 /* file is mapped into memory */
+	#define TIFF_POSTENCODE  0x01000 /* need call to postencode routine */
+	#define TIFF_INSUBIFD    0x02000 /* currently writing a subifd */
+	#define TIFF_UPSAMPLED   0x04000 /* library is doing data up-sampling */
+	#define TIFF_STRIPCHOP   0x08000 /* enable strip chopping support */
+	#define TIFF_HEADERONLY  0x10000 /* read header only, do not process the first directory */
+	#define TIFF_NOREADRAW   0x20000 /* skip reading of raw uncompressed image data */
+	#define TIFF_INCUSTOMIFD 0x40000 /* currently writing a custom IFD */
+	#define TIFF_BIGTIFF     0x80000 /* read/write bigtiff */
+        #define TIFF_BUF4WRITE  0x100000 /* rawcc bytes are for writing */
+        #define TIFF_DIRTYSTRIP 0x200000 /* stripoffsets/stripbytecount dirty*/
+        #define TIFF_PERSAMPLE  0x400000 /* get/set per sample tags as arrays */
+        #define TIFF_BUFFERMMAP 0x800000 /* read buffer (tif_rawdata) points into mmap() memory */
+	uint64               tif_diroff;       /* file offset of current directory */
+	uint64               tif_nextdiroff;   /* file offset of following directory */
+	uint64*              tif_dirlist;      /* list of offsets to already seen directories to prevent IFD looping */
+	uint16               tif_dirlistsize;  /* number of entires in offset list */
+	uint16               tif_dirnumber;    /* number of already seen directories */
+	TIFFDirectory        tif_dir;          /* internal rep of current directory */
+	TIFFDirectory        tif_customdir;    /* custom IFDs are separated from the main ones */
+	union {
+		TIFFHeaderCommon common;
+		TIFFHeaderClassic classic;
+		TIFFHeaderBig big;
+	} tif_header;
+	uint16               tif_header_size;  /* file's header block and its length */
+	uint32               tif_row;          /* current scanline */
+	uint16               tif_curdir;       /* current directory (index) */
+	uint32               tif_curstrip;     /* current strip for read/write */
+	uint64               tif_curoff;       /* current offset for read/write */
+	uint64               tif_dataoff;      /* current offset for writing dir */
+	/* SubIFD support */
+	uint16               tif_nsubifd;      /* remaining subifds to write */
+	uint64               tif_subifdoff;    /* offset for patching SubIFD link */
+	/* tiling support */
+	uint32               tif_col;          /* current column (offset by row too) */
+	uint32               tif_curtile;      /* current tile for read/write */
+	tmsize_t             tif_tilesize;     /* # of bytes in a tile */
+	/* compression scheme hooks */
+	int                  tif_decodestatus;
+	TIFFBoolMethod       tif_fixuptags;    /* called in TIFFReadDirectory */
+	TIFFBoolMethod       tif_setupdecode;  /* called once before predecode */
+	TIFFPreMethod        tif_predecode;    /* pre- row/strip/tile decoding */
+	TIFFBoolMethod       tif_setupencode;  /* called once before preencode */
+	int                  tif_encodestatus;
+	TIFFPreMethod        tif_preencode;    /* pre- row/strip/tile encoding */
+	TIFFBoolMethod       tif_postencode;   /* post- row/strip/tile encoding */
+	TIFFCodeMethod       tif_decoderow;    /* scanline decoding routine */
+	TIFFCodeMethod       tif_encoderow;    /* scanline encoding routine */
+	TIFFCodeMethod       tif_decodestrip;  /* strip decoding routine */
+	TIFFCodeMethod       tif_encodestrip;  /* strip encoding routine */
+	TIFFCodeMethod       tif_decodetile;   /* tile decoding routine */
+	TIFFCodeMethod       tif_encodetile;   /* tile encoding routine */
+	TIFFVoidMethod       tif_close;        /* cleanup-on-close routine */
+	TIFFSeekMethod       tif_seek;         /* position within a strip routine */
+	TIFFVoidMethod       tif_cleanup;      /* cleanup state routine */
+	TIFFStripMethod      tif_defstripsize; /* calculate/constrain strip size */
+	TIFFTileMethod       tif_deftilesize;  /* calculate/constrain tile size */
+	uint8*               tif_data;         /* compression scheme private data */
+	/* input/output buffering */
+	tmsize_t             tif_scanlinesize; /* # of bytes in a scanline */
+	tmsize_t             tif_scanlineskew; /* scanline skew for reading strips */
+	uint8*               tif_rawdata;      /* raw data buffer */
+	tmsize_t             tif_rawdatasize;  /* # of bytes in raw data buffer */
+        tmsize_t             tif_rawdataoff;   /* rawdata offset within strip */
+        tmsize_t             tif_rawdataloaded;/* amount of data in rawdata */
+	uint8*               tif_rawcp;        /* current spot in raw buffer */
+	tmsize_t             tif_rawcc;        /* bytes unread from raw buffer */
+	/* memory-mapped file support */
+	uint8*               tif_base;         /* base of mapped file */
+	tmsize_t             tif_size;         /* size of mapped file region (bytes, thus tmsize_t) */
+	TIFFMapFileProc      tif_mapproc;      /* map file method */
+	TIFFUnmapFileProc    tif_unmapproc;    /* unmap file method */
+	/* input/output callback methods */
+	thandle_t            tif_clientdata;   /* callback parameter */
+	TIFFReadWriteProc    tif_readproc;     /* read method */
+	TIFFReadWriteProc    tif_writeproc;    /* write method */
+	TIFFSeekProc         tif_seekproc;     /* lseek method */
+	TIFFCloseProc        tif_closeproc;    /* close method */
+	TIFFSizeProc         tif_sizeproc;     /* filesize method */
+	/* post-decoding support */
+	TIFFPostMethod       tif_postdecode;   /* post decoding routine */
+	/* tag support */
+	TIFFField**          tif_fields;       /* sorted table of registered tags */
+	size_t               tif_nfields;      /* # entries in registered tag table */
+	const TIFFField*     tif_foundfield;   /* cached pointer to already found tag */
+	TIFFTagMethods       tif_tagmethods;   /* tag get/set/print routines */
+	TIFFClientInfoLink*  tif_clientinfo;   /* extra client information. */
+	/* Backward compatibility stuff. We need these two fields for
+	 * setting up an old tag extension scheme. */
+	TIFFFieldArray*      tif_fieldscompat;
+	size_t               tif_nfieldscompat;
+};
+
+#define isPseudoTag(t) (t > 0xffff)            /* is tag value normal or pseudo */
+
+#define isTiled(tif) (((tif)->tif_flags & TIFF_ISTILED) != 0)
+#define isMapped(tif) (((tif)->tif_flags & TIFF_MAPPED) != 0)
+#define isFillOrder(tif, o) (((tif)->tif_flags & (o)) != 0)
+#define isUpSampled(tif) (((tif)->tif_flags & TIFF_UPSAMPLED) != 0)
+#define TIFFReadFile(tif, buf, size) \
+	((*(tif)->tif_readproc)((tif)->tif_clientdata,(buf),(size)))
+#define TIFFWriteFile(tif, buf, size) \
+	((*(tif)->tif_writeproc)((tif)->tif_clientdata,(buf),(size)))
+#define TIFFSeekFile(tif, off, whence) \
+	((*(tif)->tif_seekproc)((tif)->tif_clientdata,(off),(whence)))
+#define TIFFCloseFile(tif) \
+	((*(tif)->tif_closeproc)((tif)->tif_clientdata))
+#define TIFFGetFileSize(tif) \
+	((*(tif)->tif_sizeproc)((tif)->tif_clientdata))
+#define TIFFMapFileContents(tif, paddr, psize) \
+	((*(tif)->tif_mapproc)((tif)->tif_clientdata,(paddr),(psize)))
+#define TIFFUnmapFileContents(tif, addr, size) \
+	((*(tif)->tif_unmapproc)((tif)->tif_clientdata,(addr),(size)))
+
+/*
+ * Default Read/Seek/Write definitions.
+ */
+#ifndef ReadOK
+#define ReadOK(tif, buf, size) \
+	(TIFFReadFile((tif),(buf),(size))==(size))
+#endif
+#ifndef SeekOK
+#define SeekOK(tif, off) \
+	(TIFFSeekFile((tif),(off),SEEK_SET)==(off))
+#endif
+#ifndef WriteOK
+#define WriteOK(tif, buf, size) \
+	(TIFFWriteFile((tif),(buf),(size))==(size))
+#endif
+
+/* NB: the uint32 casts are to silence certain ANSI-C compilers */
+#define TIFFhowmany_32(x, y) (((uint32)x < (0xffffffff - (uint32)(y-1))) ? \
+			   ((((uint32)(x))+(((uint32)(y))-1))/((uint32)(y))) : \
+			   0U)
+#define TIFFhowmany8_32(x) (((x)&0x07)?((uint32)(x)>>3)+1:(uint32)(x)>>3)
+#define TIFFroundup_32(x, y) (TIFFhowmany_32(x,y)*(y))
+#define TIFFhowmany_64(x, y) ((((uint64)(x))+(((uint64)(y))-1))/((uint64)(y)))
+#define TIFFhowmany8_64(x) (((x)&0x07)?((uint64)(x)>>3)+1:(uint64)(x)>>3)
+#define TIFFroundup_64(x, y) (TIFFhowmany_64(x,y)*(y))
+
+/* Safe multiply which returns zero if there is an integer overflow */
+#define TIFFSafeMultiply(t,v,m) ((((t)(m) != (t)0) && (((t)(((v)*(m))/(m))) == (t)(v))) ? (t)((v)*(m)) : (t)0)
+
+#define TIFFmax(A,B) ((A)>(B)?(A):(B))
+#define TIFFmin(A,B) ((A)<(B)?(A):(B))
+
+#define TIFFArrayCount(a) (sizeof (a) / sizeof ((a)[0]))
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+extern int _TIFFgetMode(const char* mode, const char* module);
+extern int _TIFFNoRowEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s);
+extern int _TIFFNoStripEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s);
+extern int _TIFFNoTileEncode(TIFF*, uint8* pp, tmsize_t cc, uint16 s);
+extern int _TIFFNoRowDecode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s);
+extern int _TIFFNoStripDecode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s);
+extern int _TIFFNoTileDecode(TIFF*, uint8* pp, tmsize_t cc, uint16 s);
+extern void _TIFFNoPostDecode(TIFF* tif, uint8* buf, tmsize_t cc);
+extern int _TIFFNoPreCode(TIFF* tif, uint16 s);
+extern int _TIFFNoSeek(TIFF* tif, uint32 off);
+extern void _TIFFSwab16BitData(TIFF* tif, uint8* buf, tmsize_t cc);
+extern void _TIFFSwab24BitData(TIFF* tif, uint8* buf, tmsize_t cc);
+extern void _TIFFSwab32BitData(TIFF* tif, uint8* buf, tmsize_t cc);
+extern void _TIFFSwab64BitData(TIFF* tif, uint8* buf, tmsize_t cc);
+extern int TIFFFlushData1(TIFF* tif);
+extern int TIFFDefaultDirectory(TIFF* tif);
+extern void _TIFFSetDefaultCompressionState(TIFF* tif);
+extern int _TIFFRewriteField(TIFF *, uint16, TIFFDataType, tmsize_t, void *);
+extern int TIFFSetCompressionScheme(TIFF* tif, int scheme);
+extern int TIFFSetDefaultCompressionState(TIFF* tif);
+extern uint32 _TIFFDefaultStripSize(TIFF* tif, uint32 s);
+extern void _TIFFDefaultTileSize(TIFF* tif, uint32* tw, uint32* th);
+extern int _TIFFDataSize(TIFFDataType type);
+
+extern void _TIFFsetByteArray(void**, void*, uint32);
+extern void _TIFFsetString(char**, char*);
+extern void _TIFFsetShortArray(uint16**, uint16*, uint32);
+extern void _TIFFsetLongArray(uint32**, uint32*, uint32);
+extern void _TIFFsetFloatArray(float**, float*, uint32);
+extern void _TIFFsetDoubleArray(double**, double*, uint32);
+
+extern void _TIFFprintAscii(FILE*, const char*);
+extern void _TIFFprintAsciiTag(FILE*, const char*, const char*);
+
+extern TIFFErrorHandler _TIFFwarningHandler;
+extern TIFFErrorHandler _TIFFerrorHandler;
+extern TIFFErrorHandlerExt _TIFFwarningHandlerExt;
+extern TIFFErrorHandlerExt _TIFFerrorHandlerExt;
+
+extern uint32 _TIFFMultiply32(TIFF*, uint32, uint32, const char*);
+extern uint64 _TIFFMultiply64(TIFF*, uint64, uint64, const char*);
+extern void* _TIFFCheckMalloc(TIFF*, tmsize_t, tmsize_t, const char*);
+extern void* _TIFFCheckRealloc(TIFF*, void*, tmsize_t, tmsize_t, const char*);
+
+extern double _TIFFUInt64ToDouble(uint64);
+extern float _TIFFUInt64ToFloat(uint64);
+
+extern int TIFFInitDumpMode(TIFF*, int);
+#ifdef PACKBITS_SUPPORT
+extern int TIFFInitPackBits(TIFF*, int);
+#endif
+#ifdef CCITT_SUPPORT
+extern int TIFFInitCCITTRLE(TIFF*, int), TIFFInitCCITTRLEW(TIFF*, int);
+extern int TIFFInitCCITTFax3(TIFF*, int), TIFFInitCCITTFax4(TIFF*, int);
+#endif
+#ifdef THUNDER_SUPPORT
+extern int TIFFInitThunderScan(TIFF*, int);
+#endif
+#ifdef NEXT_SUPPORT
+extern int TIFFInitNeXT(TIFF*, int);
+#endif
+#ifdef LZW_SUPPORT
+extern int TIFFInitLZW(TIFF*, int);
+#endif
+#ifdef OJPEG_SUPPORT
+extern int TIFFInitOJPEG(TIFF*, int);
+#endif
+#ifdef JPEG_SUPPORT
+extern int TIFFInitJPEG(TIFF*, int);
+#endif
+#ifdef JBIG_SUPPORT
+extern int TIFFInitJBIG(TIFF*, int);
+#endif
+#ifdef ZIP_SUPPORT
+extern int TIFFInitZIP(TIFF*, int);
+#endif
+#ifdef PIXARLOG_SUPPORT
+extern int TIFFInitPixarLog(TIFF*, int);
+#endif
+#ifdef LOGLUV_SUPPORT
+extern int TIFFInitSGILog(TIFF*, int);
+#endif
+#ifdef LZMA_SUPPORT
+extern int TIFFInitLZMA(TIFF*, int);
+#endif
+#ifdef VMS
+extern const TIFFCodec _TIFFBuiltinCODECS[];
+#else
+extern TIFFCodec _TIFFBuiltinCODECS[];
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* _TIFFIOP_ */
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibTIFF4/tiffvers.h b/Source/LibTIFF4/tiffvers.h
index 5e0ff31..74f769c 100644
--- a/Source/LibTIFF4/tiffvers.h
+++ b/Source/LibTIFF4/tiffvers.h
@@ -1,9 +1,9 @@
-#define TIFFLIB_VERSION_STR "LIBTIFF, Version 4.0.3\nCopyright (c) 1988-1996 Sam Leffler\nCopyright (c) 1991-1996 Silicon Graphics, Inc."
-/*
- * This define can be used in code that requires
- * compilation-related definitions specific to a
- * version or versions of the library.  Runtime
- * version checking should be done based on the
- * string returned by TIFFGetVersion.
- */
-#define TIFFLIB_VERSION 20120922
+#define TIFFLIB_VERSION_STR "LIBTIFF, Version 4.0.4beta\nCopyright (c) 1988-1996 Sam Leffler\nCopyright (c) 1991-1996 Silicon Graphics, Inc."
+/*
+ * This define can be used in code that requires
+ * compilation-related definitions specific to a
+ * version or versions of the library.  Runtime
+ * version checking should be done based on the
+ * string returned by TIFFGetVersion.
+ */
+#define TIFFLIB_VERSION 20150126
diff --git a/Source/LibTIFF4/uvcode.h b/Source/LibTIFF4/uvcode.h
index 8f22325..50f11d7 100644
--- a/Source/LibTIFF4/uvcode.h
+++ b/Source/LibTIFF4/uvcode.h
@@ -1,180 +1,180 @@
-/* Version 1.0 generated April 7, 1997 by Greg Ward Larson, SGI */
-#define UV_SQSIZ	(float)0.003500
-#define UV_NDIVS	16289
-#define UV_VSTART	(float)0.016940
-#define UV_NVS		163
-static struct {
-	float	ustart;
-	short	nus, ncum;
-}	uv_row[UV_NVS] = {
-	{ (float)0.247663,	4,	0 },
-	{ (float)0.243779,	6,	4 },
-	{ (float)0.241684,	7,	10 },
-	{ (float)0.237874,	9,	17 },
-	{ (float)0.235906,	10,	26 },
-	{ (float)0.232153,	12,	36 },
-	{ (float)0.228352,	14,	48 },
-	{ (float)0.226259,	15,	62 },
-	{ (float)0.222371,	17,	77 },
-	{ (float)0.220410,	18,	94 },
-	{ (float)0.214710,	21,	112 },
-	{ (float)0.212714,	22,	133 },
-	{ (float)0.210721,	23,	155 },
-	{ (float)0.204976,	26,	178 },
-	{ (float)0.202986,	27,	204 },
-	{ (float)0.199245,	29,	231 },
-	{ (float)0.195525,	31,	260 },
-	{ (float)0.193560,	32,	291 },
-	{ (float)0.189878,	34,	323 },
-	{ (float)0.186216,	36,	357 },
-	{ (float)0.186216,	36,	393 },
-	{ (float)0.182592,	38,	429 },
-	{ (float)0.179003,	40,	467 },
-	{ (float)0.175466,	42,	507 },
-	{ (float)0.172001,	44,	549 },
-	{ (float)0.172001,	44,	593 },
-	{ (float)0.168612,	46,	637 },
-	{ (float)0.168612,	46,	683 },
-	{ (float)0.163575,	49,	729 },
-	{ (float)0.158642,	52,	778 },
-	{ (float)0.158642,	52,	830 },
-	{ (float)0.158642,	52,	882 },
-	{ (float)0.153815,	55,	934 },
-	{ (float)0.153815,	55,	989 },
-	{ (float)0.149097,	58,	1044 },
-	{ (float)0.149097,	58,	1102 },
-	{ (float)0.142746,	62,	1160 },
-	{ (float)0.142746,	62,	1222 },
-	{ (float)0.142746,	62,	1284 },
-	{ (float)0.138270,	65,	1346 },
-	{ (float)0.138270,	65,	1411 },
-	{ (float)0.138270,	65,	1476 },
-	{ (float)0.132166,	69,	1541 },
-	{ (float)0.132166,	69,	1610 },
-	{ (float)0.126204,	73,	1679 },
-	{ (float)0.126204,	73,	1752 },
-	{ (float)0.126204,	73,	1825 },
-	{ (float)0.120381,	77,	1898 },
-	{ (float)0.120381,	77,	1975 },
-	{ (float)0.120381,	77,	2052 },
-	{ (float)0.120381,	77,	2129 },
-	{ (float)0.112962,	82,	2206 },
-	{ (float)0.112962,	82,	2288 },
-	{ (float)0.112962,	82,	2370 },
-	{ (float)0.107450,	86,	2452 },
-	{ (float)0.107450,	86,	2538 },
-	{ (float)0.107450,	86,	2624 },
-	{ (float)0.107450,	86,	2710 },
-	{ (float)0.100343,	91,	2796 },
-	{ (float)0.100343,	91,	2887 },
-	{ (float)0.100343,	91,	2978 },
-	{ (float)0.095126,	95,	3069 },
-	{ (float)0.095126,	95,	3164 },
-	{ (float)0.095126,	95,	3259 },
-	{ (float)0.095126,	95,	3354 },
-	{ (float)0.088276,	100,	3449 },
-	{ (float)0.088276,	100,	3549 },
-	{ (float)0.088276,	100,	3649 },
-	{ (float)0.088276,	100,	3749 },
-	{ (float)0.081523,	105,	3849 },
-	{ (float)0.081523,	105,	3954 },
-	{ (float)0.081523,	105,	4059 },
-	{ (float)0.081523,	105,	4164 },
-	{ (float)0.074861,	110,	4269 },
-	{ (float)0.074861,	110,	4379 },
-	{ (float)0.074861,	110,	4489 },
-	{ (float)0.074861,	110,	4599 },
-	{ (float)0.068290,	115,	4709 },
-	{ (float)0.068290,	115,	4824 },
-	{ (float)0.068290,	115,	4939 },
-	{ (float)0.068290,	115,	5054 },
-	{ (float)0.063573,	119,	5169 },
-	{ (float)0.063573,	119,	5288 },
-	{ (float)0.063573,	119,	5407 },
-	{ (float)0.063573,	119,	5526 },
-	{ (float)0.057219,	124,	5645 },
-	{ (float)0.057219,	124,	5769 },
-	{ (float)0.057219,	124,	5893 },
-	{ (float)0.057219,	124,	6017 },
-	{ (float)0.050985,	129,	6141 },
-	{ (float)0.050985,	129,	6270 },
-	{ (float)0.050985,	129,	6399 },
-	{ (float)0.050985,	129,	6528 },
-	{ (float)0.050985,	129,	6657 },
-	{ (float)0.044859,	134,	6786 },
-	{ (float)0.044859,	134,	6920 },
-	{ (float)0.044859,	134,	7054 },
-	{ (float)0.044859,	134,	7188 },
-	{ (float)0.040571,	138,	7322 },
-	{ (float)0.040571,	138,	7460 },
-	{ (float)0.040571,	138,	7598 },
-	{ (float)0.040571,	138,	7736 },
-	{ (float)0.036339,	142,	7874 },
-	{ (float)0.036339,	142,	8016 },
-	{ (float)0.036339,	142,	8158 },
-	{ (float)0.036339,	142,	8300 },
-	{ (float)0.032139,	146,	8442 },
-	{ (float)0.032139,	146,	8588 },
-	{ (float)0.032139,	146,	8734 },
-	{ (float)0.032139,	146,	8880 },
-	{ (float)0.027947,	150,	9026 },
-	{ (float)0.027947,	150,	9176 },
-	{ (float)0.027947,	150,	9326 },
-	{ (float)0.023739,	154,	9476 },
-	{ (float)0.023739,	154,	9630 },
-	{ (float)0.023739,	154,	9784 },
-	{ (float)0.023739,	154,	9938 },
-	{ (float)0.019504,	158,	10092 },
-	{ (float)0.019504,	158,	10250 },
-	{ (float)0.019504,	158,	10408 },
-	{ (float)0.016976,	161,	10566 },
-	{ (float)0.016976,	161,	10727 },
-	{ (float)0.016976,	161,	10888 },
-	{ (float)0.016976,	161,	11049 },
-	{ (float)0.012639,	165,	11210 },
-	{ (float)0.012639,	165,	11375 },
-	{ (float)0.012639,	165,	11540 },
-	{ (float)0.009991,	168,	11705 },
-	{ (float)0.009991,	168,	11873 },
-	{ (float)0.009991,	168,	12041 },
-	{ (float)0.009016,	170,	12209 },
-	{ (float)0.009016,	170,	12379 },
-	{ (float)0.009016,	170,	12549 },
-	{ (float)0.006217,	173,	12719 },
-	{ (float)0.006217,	173,	12892 },
-	{ (float)0.005097,	175,	13065 },
-	{ (float)0.005097,	175,	13240 },
-	{ (float)0.005097,	175,	13415 },
-	{ (float)0.003909,	177,	13590 },
-	{ (float)0.003909,	177,	13767 },
-	{ (float)0.002340,	177,	13944 },
-	{ (float)0.002389,	170,	14121 },
-	{ (float)0.001068,	164,	14291 },
-	{ (float)0.001653,	157,	14455 },
-	{ (float)0.000717,	150,	14612 },
-	{ (float)0.001614,	143,	14762 },
-	{ (float)0.000270,	136,	14905 },
-	{ (float)0.000484,	129,	15041 },
-	{ (float)0.001103,	123,	15170 },
-	{ (float)0.001242,	115,	15293 },
-	{ (float)0.001188,	109,	15408 },
-	{ (float)0.001011,	103,	15517 },
-	{ (float)0.000709,	97,	15620 },
-	{ (float)0.000301,	89,	15717 },
-	{ (float)0.002416,	82,	15806 },
-	{ (float)0.003251,	76,	15888 },
-	{ (float)0.003246,	69,	15964 },
-	{ (float)0.004141,	62,	16033 },
-	{ (float)0.005963,	55,	16095 },
-	{ (float)0.008839,	47,	16150 },
-	{ (float)0.010490,	40,	16197 },
-	{ (float)0.016994,	31,	16237 },
-	{ (float)0.023659,	21,	16268 },
-};
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
+/* Version 1.0 generated April 7, 1997 by Greg Ward Larson, SGI */
+#define UV_SQSIZ	(float)0.003500
+#define UV_NDIVS	16289
+#define UV_VSTART	(float)0.016940
+#define UV_NVS		163
+static struct {
+	float	ustart;
+	short	nus, ncum;
+}	uv_row[UV_NVS] = {
+	{ (float)0.247663,	4,	0 },
+	{ (float)0.243779,	6,	4 },
+	{ (float)0.241684,	7,	10 },
+	{ (float)0.237874,	9,	17 },
+	{ (float)0.235906,	10,	26 },
+	{ (float)0.232153,	12,	36 },
+	{ (float)0.228352,	14,	48 },
+	{ (float)0.226259,	15,	62 },
+	{ (float)0.222371,	17,	77 },
+	{ (float)0.220410,	18,	94 },
+	{ (float)0.214710,	21,	112 },
+	{ (float)0.212714,	22,	133 },
+	{ (float)0.210721,	23,	155 },
+	{ (float)0.204976,	26,	178 },
+	{ (float)0.202986,	27,	204 },
+	{ (float)0.199245,	29,	231 },
+	{ (float)0.195525,	31,	260 },
+	{ (float)0.193560,	32,	291 },
+	{ (float)0.189878,	34,	323 },
+	{ (float)0.186216,	36,	357 },
+	{ (float)0.186216,	36,	393 },
+	{ (float)0.182592,	38,	429 },
+	{ (float)0.179003,	40,	467 },
+	{ (float)0.175466,	42,	507 },
+	{ (float)0.172001,	44,	549 },
+	{ (float)0.172001,	44,	593 },
+	{ (float)0.168612,	46,	637 },
+	{ (float)0.168612,	46,	683 },
+	{ (float)0.163575,	49,	729 },
+	{ (float)0.158642,	52,	778 },
+	{ (float)0.158642,	52,	830 },
+	{ (float)0.158642,	52,	882 },
+	{ (float)0.153815,	55,	934 },
+	{ (float)0.153815,	55,	989 },
+	{ (float)0.149097,	58,	1044 },
+	{ (float)0.149097,	58,	1102 },
+	{ (float)0.142746,	62,	1160 },
+	{ (float)0.142746,	62,	1222 },
+	{ (float)0.142746,	62,	1284 },
+	{ (float)0.138270,	65,	1346 },
+	{ (float)0.138270,	65,	1411 },
+	{ (float)0.138270,	65,	1476 },
+	{ (float)0.132166,	69,	1541 },
+	{ (float)0.132166,	69,	1610 },
+	{ (float)0.126204,	73,	1679 },
+	{ (float)0.126204,	73,	1752 },
+	{ (float)0.126204,	73,	1825 },
+	{ (float)0.120381,	77,	1898 },
+	{ (float)0.120381,	77,	1975 },
+	{ (float)0.120381,	77,	2052 },
+	{ (float)0.120381,	77,	2129 },
+	{ (float)0.112962,	82,	2206 },
+	{ (float)0.112962,	82,	2288 },
+	{ (float)0.112962,	82,	2370 },
+	{ (float)0.107450,	86,	2452 },
+	{ (float)0.107450,	86,	2538 },
+	{ (float)0.107450,	86,	2624 },
+	{ (float)0.107450,	86,	2710 },
+	{ (float)0.100343,	91,	2796 },
+	{ (float)0.100343,	91,	2887 },
+	{ (float)0.100343,	91,	2978 },
+	{ (float)0.095126,	95,	3069 },
+	{ (float)0.095126,	95,	3164 },
+	{ (float)0.095126,	95,	3259 },
+	{ (float)0.095126,	95,	3354 },
+	{ (float)0.088276,	100,	3449 },
+	{ (float)0.088276,	100,	3549 },
+	{ (float)0.088276,	100,	3649 },
+	{ (float)0.088276,	100,	3749 },
+	{ (float)0.081523,	105,	3849 },
+	{ (float)0.081523,	105,	3954 },
+	{ (float)0.081523,	105,	4059 },
+	{ (float)0.081523,	105,	4164 },
+	{ (float)0.074861,	110,	4269 },
+	{ (float)0.074861,	110,	4379 },
+	{ (float)0.074861,	110,	4489 },
+	{ (float)0.074861,	110,	4599 },
+	{ (float)0.068290,	115,	4709 },
+	{ (float)0.068290,	115,	4824 },
+	{ (float)0.068290,	115,	4939 },
+	{ (float)0.068290,	115,	5054 },
+	{ (float)0.063573,	119,	5169 },
+	{ (float)0.063573,	119,	5288 },
+	{ (float)0.063573,	119,	5407 },
+	{ (float)0.063573,	119,	5526 },
+	{ (float)0.057219,	124,	5645 },
+	{ (float)0.057219,	124,	5769 },
+	{ (float)0.057219,	124,	5893 },
+	{ (float)0.057219,	124,	6017 },
+	{ (float)0.050985,	129,	6141 },
+	{ (float)0.050985,	129,	6270 },
+	{ (float)0.050985,	129,	6399 },
+	{ (float)0.050985,	129,	6528 },
+	{ (float)0.050985,	129,	6657 },
+	{ (float)0.044859,	134,	6786 },
+	{ (float)0.044859,	134,	6920 },
+	{ (float)0.044859,	134,	7054 },
+	{ (float)0.044859,	134,	7188 },
+	{ (float)0.040571,	138,	7322 },
+	{ (float)0.040571,	138,	7460 },
+	{ (float)0.040571,	138,	7598 },
+	{ (float)0.040571,	138,	7736 },
+	{ (float)0.036339,	142,	7874 },
+	{ (float)0.036339,	142,	8016 },
+	{ (float)0.036339,	142,	8158 },
+	{ (float)0.036339,	142,	8300 },
+	{ (float)0.032139,	146,	8442 },
+	{ (float)0.032139,	146,	8588 },
+	{ (float)0.032139,	146,	8734 },
+	{ (float)0.032139,	146,	8880 },
+	{ (float)0.027947,	150,	9026 },
+	{ (float)0.027947,	150,	9176 },
+	{ (float)0.027947,	150,	9326 },
+	{ (float)0.023739,	154,	9476 },
+	{ (float)0.023739,	154,	9630 },
+	{ (float)0.023739,	154,	9784 },
+	{ (float)0.023739,	154,	9938 },
+	{ (float)0.019504,	158,	10092 },
+	{ (float)0.019504,	158,	10250 },
+	{ (float)0.019504,	158,	10408 },
+	{ (float)0.016976,	161,	10566 },
+	{ (float)0.016976,	161,	10727 },
+	{ (float)0.016976,	161,	10888 },
+	{ (float)0.016976,	161,	11049 },
+	{ (float)0.012639,	165,	11210 },
+	{ (float)0.012639,	165,	11375 },
+	{ (float)0.012639,	165,	11540 },
+	{ (float)0.009991,	168,	11705 },
+	{ (float)0.009991,	168,	11873 },
+	{ (float)0.009991,	168,	12041 },
+	{ (float)0.009016,	170,	12209 },
+	{ (float)0.009016,	170,	12379 },
+	{ (float)0.009016,	170,	12549 },
+	{ (float)0.006217,	173,	12719 },
+	{ (float)0.006217,	173,	12892 },
+	{ (float)0.005097,	175,	13065 },
+	{ (float)0.005097,	175,	13240 },
+	{ (float)0.005097,	175,	13415 },
+	{ (float)0.003909,	177,	13590 },
+	{ (float)0.003909,	177,	13767 },
+	{ (float)0.002340,	177,	13944 },
+	{ (float)0.002389,	170,	14121 },
+	{ (float)0.001068,	164,	14291 },
+	{ (float)0.001653,	157,	14455 },
+	{ (float)0.000717,	150,	14612 },
+	{ (float)0.001614,	143,	14762 },
+	{ (float)0.000270,	136,	14905 },
+	{ (float)0.000484,	129,	15041 },
+	{ (float)0.001103,	123,	15170 },
+	{ (float)0.001242,	115,	15293 },
+	{ (float)0.001188,	109,	15408 },
+	{ (float)0.001011,	103,	15517 },
+	{ (float)0.000709,	97,	15620 },
+	{ (float)0.000301,	89,	15717 },
+	{ (float)0.002416,	82,	15806 },
+	{ (float)0.003251,	76,	15888 },
+	{ (float)0.003246,	69,	15964 },
+	{ (float)0.004141,	62,	16033 },
+	{ (float)0.005963,	55,	16095 },
+	{ (float)0.008839,	47,	16150 },
+	{ (float)0.010490,	40,	16197 },
+	{ (float)0.016994,	31,	16237 },
+	{ (float)0.023659,	21,	16268 },
+};
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/Source/LibWebP/AUTHORS b/Source/LibWebP/AUTHORS
new file mode 100644
index 0000000..c971d4f
--- /dev/null
+++ b/Source/LibWebP/AUTHORS
@@ -0,0 +1,24 @@
+Contributors:
+- Charles Munger (clm at google dot com)
+- Christian Duvivier (cduvivier at google dot com)
+- Djordje Pesut (djordje dot pesut at imgtec dot com)
+- James Zern (jzern at google dot com)
+- Jan Engelhardt (jengelh at medozas dot de)
+- Johann (johann dot koenig at duck dot com)
+- Jovan Zelincevic (jovan dot zelincevic at imgtec dot com)
+- Jyrki Alakuijala (jyrki at google dot com)
+- levytamar82 (tamar dot levy at intel dot com)
+- Lou Quillio (louquillio at google dot com)
+- Mans Rullgard (mans at mansr dot com)
+- Martin Olsson (mnemo at minimum dot se)
+- Mikołaj Zalewski (mikolajz at google dot com)
+- Noel Chromium (noel at chromium dot org)
+- Pascal Massimino (pascal dot massimino at gmail dot com)
+- Paweł Hajdan, Jr (phajdan dot jr at chromium dot org)
+- Pierre Joye (pierre dot php at gmail dot com)
+- Scott LaVarnway (slavarnway at google dot com)
+- Scott Talbot (s at chikachow dot org)
+- Slobodan Prijic (slobodan dot prijic at imgtec dot com)
+- Somnath Banerjee (somnath dot banerjee at gmail dot com)
+- Urvang Joshi (urvang at google dot com)
+- Vikas Arora (vikasa at google dot com)
diff --git a/Source/LibWebP/COPYING b/Source/LibWebP/COPYING
new file mode 100644
index 0000000..947fb3e
--- /dev/null
+++ b/Source/LibWebP/COPYING
@@ -0,0 +1,30 @@
+Copyright (c) 2010, Google Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+  * Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+
+  * Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in
+    the documentation and/or other materials provided with the
+    distribution.
+
+  * Neither the name of Google nor the names of its contributors may
+    be used to endorse or promote products derived from this software
+    without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/Source/LibWebP/ChangeLog b/Source/LibWebP/ChangeLog
new file mode 100644
index 0000000..1e3e29b
--- /dev/null
+++ b/Source/LibWebP/ChangeLog
@@ -0,0 +1,2144 @@
+f59c0b4 iosbuild.sh: specify optimization flags
+8d34ea3 update ChangeLog (tag: v0.4.1-rc1)
+dbc3da6 makefile.unix: add vwebp.1 to the dist target
+89a7c83 update ChangeLog
+ffe67ee Merge "update NEWS for the next release" into 0.4.1
+2def1fe gif2webp: dust up the help message
+fb668d7 remove -noalphadither option from README/vwebp.1
+e49f693 update NEWS for the next release
+cd01358 Merge "update AUTHORS" into 0.4.1
+268d01e update AUTHORS
+85213b9 bump version to 0.4.1
+695f80a Merge "restore mux API compatibility" into 0.4.1
+862d296 restore mux API compatibility
+8f6f8c5 remove the !WEBP_REFERENCE_IMPLEMENTATION tweak in Put8x8uv
+d713a69 Merge changes If4debc15,I437a5d5f into 0.4.1
+c2fc52e restore encode API compatibility
+793368e restore decode API compatibility
+b8984f3 gif2webp: fix compile with giflib 5.1.0
+222f9b1 gif2webp: simplify giflib version checking
+d2cc61b Extend MakeARGB32() to accept Alpha channel.
+4595b62 Merge "use explicit size of kErrorMessages[] arrays"
+157de01 Merge "Actuate memory stats for PRINT_MEMORY_INFO"
+fbda2f4 JPEG decoder: delay conversion to YUV to WebPEncode() call
+0b747b1 use explicit size of kErrorMessages[] arrays
+3398d81 Actuate memory stats for PRINT_MEMORY_INFO
+6f3202b Merge "move WebPPictureInit to picture.c"
+6c347bb move WebPPictureInit to picture.c
+fb3acf1 fix configure message for multi-thread
+40b086f configure: check for _beginthreadex
+1549d62 reorder the YUVA->ARGB and ARGB->YUVA functions correctly
+c6461bf Merge "extract colorspace code from picture.c into picture_csp.c"
+736f2a1 extract colorspace code from picture.c into picture_csp.c
+645daa0 Merge "configure: check for -Wformat-security"
+abafed8 configure: check for -Wformat-security
+fbadb48 split monolithic picture.c into picture_{tools,psnr,rescale}.c
+c76f07e dec_neon/TransformAC3: initialize vector w/vcreate
+bb4fc05 gif2webp: Allow single-frame animations
+46fd44c thread: remove harmless race on status_ in End()
+5a1a726 Merge "configure: check for __builtin_bswapXX()"
+6781423 configure: check for __builtin_bswapXX()
+6450c48 configure: fix iOS builds
+6422e68 VP8LFillBitWindow: enable fast path for 32-bit builds
+4f7f52b VP8LFillBitWindow: respect WEBP_FORCE_ALIGNED
+e458bad endian_inl.h: implement htoleXX with BSwapXX
+f2664d1 endian_inl.h: add BSwap16
+6fbf534 Merge "configure: add --enable-aligned"
+dc0f479 configure: add --enable-aligned
+9cc69e2 Merge "configure: support WIC + OpenGL under mingw64"
+257adfb remove experimental YUV444 YUV422 and YUV400 code
+10f4257 configure: support WIC + OpenGL under mingw64
+380cca4 configure.ac: add AC_C_BIGENDIAN
+ee70a90 endian_inl.h: add BSwap64
+47779d4 endian_inl.h: add BSwap32
+d5104b1 utils: add endian_inl.h
+58ab622 Merge "make alpha-detection loop in IsKeyFrame() in good x/y order"
+9d56290 make alpha-detection loop in IsKeyFrame() in good x/y order
+516971b lossless: Remove unaligned read warning
+b8b596f Merge "configure.ac: add an autoconf version prerequisite"
+34b02f8 configure.ac: add an autoconf version prerequisite
+e59f536 neon: normalize vdup_n_* usage
+6ee7160 Merge changes I0da7b3d3,Idad2f278,I4accc305
+abc02f2 Merge "fix (uncompiled) typo"
+bc03670 neon: add INIT_VECTOR4
+6c1c632 neon: add INIT_VECTOR3
+dc7687e neon: add INIT_VECTOR2
+4536e7c add WebPMuxSetCanvasSize() to the mux API
+824eab1 fix (uncompiled) typo
+1f3e5f1 remove unused 'shift' argument and QFIX2 define
+8e86705 Merge "VP8LoadNewBytes: use __builtin_bswap32 if available"
+1b6a263 Merge "Fix handling of weird GIF with canvas dimension 0x0"
+1da3d46 VP8LoadNewBytes: use __builtin_bswap32 if available
+1582e40 Fix handling of weird GIF with canvas dimension 0x0
+b8811da Merge "rename interface -> winterface"
+db8b8b5 Fix logic in the GIF LOOP-detection parsing
+25aaddc rename interface -> winterface
+5584d9d make WebPSetWorkerInterface() check its arguments
+a9ef7ef Merge "cosmetics: update thread.h comments"
+c6af999 Merge "dust up the help message"
+0a8b886 dust up the help message
+a9cf319 cosmetics: update thread.h comments
+27bfeee QuantizeBlock SSE2 Optimization:
+2bc0dc3 Merge "webpmux: warn when odd frame offsets are used"
+3114ebe Merge changes Id8edd3c1,Id418eb96,Ide05e3be
+c072663 webpmux: warn when odd frame offsets are used
+c5c6b40 Merge "add alpha dithering for lossy"
+d514678 examples/Android.mk: add cwebp
+ca0fa7c Android.mk: move dwebp to examples/Android.mk
+73d8fca Android.mk: add ENABLE_SHARED flag
+6e93317 muxread: fix out of bounds read
+8b0f6a4 Makefile.vc: fix CFLAGS assignment w/HAVE_AVX2=1
+bbe32df add alpha dithering for lossy
+7902076 Merge "make error-code reporting consistent upon malloc failure"
+77bf441 make error-code reporting consistent upon malloc failure
+7a93c00 **/Makefile.am: remove unused AM_CPPFLAGS
+24e3080 Add an interface abstraction to the WebP worker thread implementation
+d6cd635 Merge "fix orig_rect==NULL case"
+2bfd1ff fix orig_rect==NULL case
+059e21c Merge "configure: move config.h to src/webp/config.h"
+f05fe00 properly report back encoding error code in WebPFrameCacheAddFrame()
+32b3137 configure: move config.h to src/webp/config.h
+90090d9 Merge changes I7c675e51,I84f7d785
+ae7661b makefiles: define WEBP_HAVE_AVX2 when appropriate
+69fce2e remove the special casing for res->first in VP8SetResidualCoeffs
+6e61a3a configure: test for -msse2
+b9d2efc rename upsampling_mips32.c to yuv_mips32.c
+bdfeeba dsp/yuv: move sse2 functions to yuv_sse2.c
+46b32e8 Merge "configure: set WEBP_HAVE_AVX2 when available"
+88305db Merge "VP8RandomBits2: prevent signed int overflow"
+73fee88 VP8RandomBits2: prevent signed int overflow
+db4860b enc_sse2: prevent signed int overflow
+3fdaf4d Merge "real fix for longjmp warning"
+385e334 real fix for longjmp warning
+230a055 configure: set WEBP_HAVE_AVX2 when available
+a2ac8a4 restore original value_/range_ field order
+5e2ee56 Merge "remove libwebpdspdecode dep on libwebpdsp_avx2"
+61362db remove libwebpdspdecode dep on libwebpdsp_avx2
+42c447a Merge "lossy bit-reader clean-up:"
+479ffd8 Merge "remove unused #include's"
+9754d39 Merge "strong filtering speed-up (~2-3% x86, ~1-2% for NEON)"
+158aff9 remove unused #include's
+09545ee lossy bit-reader clean-up:
+ea8b0a1 strong filtering speed-up (~2-3% x86, ~1-2% for NEON)
+6679f89 Optimize VP8SetResidualCoeffs.
+ac591cf fix for gcc-4.9 warnings about longjmp + local variables
+4dfa86b dsp/cpu: NaCl has no support for xgetbv
+4c39869 Merge "cwebp: fallback to native webp decode in WIC builds"
+33aa497 Merge "cwebp: add some missing newlines in longhelp output"
+c9b340a fix missing WebPInitAlphaProcessing call for premultiplied colorspace output
+57897ba Merge "lossless_neon: use vcreate_*() where appropriate"
+6aa4777 Merge "(enc|dec)_neon: use vcreate_*() where appropriate"
+0d346e4 Always reinit VP8TransformWHT instead of hard-coding
+7d039fc cwebp: fallback to native webp decode in WIC builds
+d471f42 cwebp: add some missing newlines in longhelp output
+bf0e003 lossless_neon: use vcreate_*() where appropriate
+9251c2f (enc|dec)_neon: use vcreate_*() where appropriate
+399b916 lossy decoding: correct alpha-rescaling for YUVA format
+78c12ed Merge "Makefile.vc: add rudimentary avx2 support"
+dc5b122 try to remove the spurious warning for static analysis
+ddfefd6 Makefile.vc: add rudimentary avx2 support
+a891164 Merge "simplify VP8LInitBitReader()"
+fdbcd44 simplify VP8LInitBitReader()
+7c00428 makefile.unix: add rudimentary avx2 support
+515e35c Merge "add stub dsp/enc_avx2.c"
+a05dc14 SSE2: yuv->rgb speed-up for point-sampling
+178e9a6 add stub dsp/enc_avx2.c
+1b99c09 Merge "configure: add a test for -mavx2"
+fe72807 configure: add a test for -mavx2
+e46a247 cpu: fix check for __cpuidex availability
+176fda2 fix the bit-writer for lossless in 32bit mode
+541784c dsp.h: add a check for AVX2 / define WEBP_USE_AVX2
+bdb151e dsp/cpu: add AVX2 detection
+ab9f2f8 Merge "revamp the point-sampling functions by processing a full plane"
+a2f8b28 revamp the point-sampling functions by processing a full plane
+ef07602 use decoder's DSP functions for autofilter
+2b5cb32 Merge "dsp/cpu: add AVX detection"
+df08e67 dsp/cpu: add AVX detection
+e2f405c Merge "clean-up and slight speed-up in-loop filtering SSE2"
+f60957b clean-up and slight speed-up in-loop filtering SSE2
+9fc3ae4 .gitattributes: treat .ppm as binary
+3da924b Merge "dsp/WEBP_USE_NEON: test for __aarch64__"
+c716449 Android.mk: always include *_neon.c in the build
+a577b23 dsp/WEBP_USE_NEON: test for __aarch64__
+54bfffc move RemapBitReader() from idec.c to bit_reader code
+34168ec Merge "remove all unused layer code"
+f1e7717 remove all unused layer code
+b0757db Code cleanup for VP8LGetHistoImageSymbols.
+5fe628d make the token page size be variable instead of fixed 8192
+f948d08 memory debug: allow setting pre-defined malloc failure points
+ca3d746 use block-based allocation for backward refs storage, and free-lists
+1ba61b0 enable NEON intrinsics in aarch64 builds
+b9d2bb6 dsp/neon.h: coalesce intrinsics-related defines
+b5c7525 iosbuild: add support for iOSv7/aarch64
+9383afd Reduce number of memory allocations while decoding lossless.
+888e63e Merge "dsp/lossless: prevent signed int overflow in left shift ops"
+8137f3e Merge "instrument memory allocation routines for debugging"
+2aa1873 instrument memory allocation routines for debugging
+d3bcf72 Don't allocate VP8LHashChain, but treat like automatic object
+bd6b861 dsp/lossless: prevent signed int overflow in left shift ops
+b7f19b8 Merge "dec/vp8l: prevent signed int overflow in left shift ops"
+29059d5 Merge "remove some uint64_t casts and use."
+e69a1df dec/vp8l: prevent signed int overflow in left shift ops
+cf5eb8a remove some uint64_t casts and use.
+38e2db3 MIPS: MIPS32r1: Added optimization for HistogramAdd.
+e0609ad dwebp: fix exit code on webp load failure
+bbd358a Merge "example_util.h: avoid forward declaring enums"
+8955da2 example_util.h: avoid forward declaring enums
+6d6865f Added SSE2 variants for Average2/3/4
+b3a616b make HistogramAdd() a pointer in dsp
+c8bbb63 dec_neon: relocate some inline-asm defines
+4e393bb dec_neon: enable intrinsics-only functions
+ba99a92 dec_neon: use positive tests for USE_INTRINSICS
+69058ff Merge "example_util: add ExUtilDecodeWebPIncremental"
+a7828e8 dec_neon: make WORK_AROUND_GCC conditional on version
+3f3d717 Merge "enc_neon: enable intrinsics-only functions"
+de3cb6c Merge "move LOCAL_GCC_VERSION def to dsp.h"
+1b2fe14 example_util: add ExUtilDecodeWebPIncremental
+ca49e7a Merge "enc_neon: move Transpose4x4 to dsp/neon.h"
+ad900ab Merge "fix warning about size_t -> int conversion"
+4825b43 fix warning about size_t -> int conversion
+42b35e0 enc_neon: enable intrinsics-only functions
+f937e01 move LOCAL_GCC_VERSION def to dsp.h
+5e1a17e enc_neon: move Transpose4x4 to dsp/neon.h
+c7b92a5 dec_neon: (WORK_AROUND_GCC) delete unused Load4x8
+8e5f90b Merge "make ExUtilLoadWebP() accept NULL bitstream param."
+05d4c1b Merge "cwebp: add webpdec"
+ddeb6ac cwebp: add webpdec
+35d7d09 Merge "Reduce memory footprint for encoding WebP lossless."
+0b89610 Reduce memory footprint for encoding WebP lossless.
+f0b65c9 make ExUtilLoadWebP() accept NULL bitstream param.
+9c0a60c Merge "dwebp: move webp decoding to example_util"
+1d62acf MIPS: MIPS32r1: Added optimization for HuffmanCost functions.
+4a0e739 dwebp: move webp decoding to example_util
+c022046 Merge "Bugfix: Incremental decode of lossy-alpha"
+8c7cd72 Bugfix: Incremental decode of lossy-alpha
+7955152 MIPS: fix error with number of registers.
+b1dabe3 Merge "Move the HuffmanCost() function to dsp lib"
+75b1200 Move the HuffmanCost() function to dsp lib
+2772b8b MIPS: fix assembler error revealed by clang's debug build
+6653b60 enc_mips32: fix unused symbol warning in debug
+8dec120 enc_mips32: disable ITransform(One) in debug builds
+98519dd enc_neon: convert Disto4x4 to intrinsics
+fe9317c cosmetics:
+953b074 enc_neon: cosmetics
+a9fc697 Merge "WIP: extract the float-calculation of HuffmanCost from loop"
+3f84b52 Merge "replace some mult-long (vmull_u8) with mult-long-accumulate (vmlal_u8)"
+4ae0533 MIPS: MIPS32r1: Added optimizations for ExtraCost functions.
+b30a04c WIP: extract the float-calculation of HuffmanCost from loop
+a8fe8ce Merge "NEON intrinsics version of CollectHistogram"
+95203d2 NEON intrinsics version of CollectHistogram
+7ca2e74 replace some mult-long (vmull_u8) with mult-long-accumulate (vmlal_u8)
+41c6efb fix lossless_neon.c
+8ff96a0 NEON intrinsics version of FTransform
+0214f4a Merge "MIPS: MIPS32r1: Added optimizations for FastLog2"
+baabf1e MIPS: MIPS32r1: Added optimizations for FastLog2
+3d49871 NEON functions for lossless coding
+3fe0291 MIPS: MIPS32r1: Added optimizations for SSE functions.
+c503b48 Merge "fix the gcc-4.6.0 bug by implementing alternative method"
+abe6f48 fix the gcc-4.6.0 bug by implementing alternative method
+5598bde enc_mips32.c: fix file mode
+2b1b4d5 MIPS: MIPS32r1: Add optimization for GetResidualCost
+f0a1f3c Merge "MIPS: MIPS32r1: Added optimization for FTransform"
+7231f61 MIPS: MIPS32r1: Added optimization for FTransform
+869eaf6  ~30% encoding speedup: use NEON for QuantizeBlock()
+f758af6 enc_neon: convert FTransformWHT to intrinsics
+7dad095 MIPS: MIPS32r1: Added optimization for Disto4x4 (TTransform)
+2298d5f MIPS: MIPS32r1: Added optimization for QuantizeBlock
+e88150c Merge "MIPS: MIPS32r1: Add optimization for ITransform"
+de693f2 lossless_neon: disable VP8LConvert* functions
+4143332 NEON intrinsics for encoding
+0ca2914 MIPS: MIPS32r1: Add optimization for ITransform
+71bca5e dec_neon: use vst_lane instead of vget_lane
+bf06105 Intrinsics NEON version of TransformOne
+19c6f1b Merge "dec_neon: use vld?_lane instead of vset?_lane"
+7a94c0c upsampling_neon: drop NEON suffix from local functions
+d14669c upsampling_sse2: drop SSE2 suffix from local functions
+2ca42a4 enc_sse2: drop SSE2 suffix from local functions
+d038e61 dec_sse2: drop SSE2 suffix from local functions
+fa52d75 dec_neon: use vld?_lane instead of vset?_lane
+c520e77 cosmetic: fix long line
+4b0f2da Merge "add intrinsics NEON code for chroma strong-filtering"
+e351ec0 add intrinsics NEON code for chroma strong-filtering
+aaf734b Merge "Add SSE2 version of forward cross-color transform"
+c90a902 Add SSE2 version of forward cross-color transform
+bc374ff Use histogram_bits to initalize transform_bits.
+2132992 Merge "Add strong filtering intrinsics (inner and outer edges)"
+5fbff3a Add strong filtering intrinsics (inner and outer edges)
+d4813f0 Add SSE2 function for Inverse Cross-color Transform
+2602956 dec_neon: add strong loopfilter intrinsics
+cca7d7e Merge "add intrinsics version of SimpleHFilter16NEON()"
+1a05dfa windows: fix dll builds
+d6c50d8 Merge "add some colorspace conversion functions in NEON"
+4fd7c82 SSE2 variants of Subtract-Green: Rectify loop condition
+97e5fac add some colorspace conversion functions in NEON
+b9a7a45 add intrinsics version of SimpleHFilter16NEON()
+daccbf4 add light filtering NEON intrinsics
+af44460 fix typo in STORE_WHT
+6af6b8e Tune HistogramCombineBin for large images.
+af93bdd use WebPSafe[CM]alloc/WebPSafeFree instead of [cm]alloc/free
+51f406a lossless_sse2: relocate VP8LDspInitSSE2 proto
+0f4f721 separate SSE2 lossless functions into its own file
+514fc25 VP8LConvertFromBGRA: use conversion function pointers
+6d2f352 dsp/dec: TransformDCUV: use VP8TransformDC
+defc8e1 Merge "fix out-of-bound read during alpha-plane decoding"
+fbed364 Merge "dsp: reuse wht transform from dec in encoder"
+d846708 Merge "Add SSE2 version of ARGB -> BGR/RGB/... conversion functions"
+207d03b fix out-of-bound read during alpha-plane decoding
+d1b33ad 2-5% faster trellis with clang/MacOS (and ~2-3% on ARM)
+369c26d Add SSE2 version of ARGB -> BGR/RGB/... conversion functions
+df230f2 dsp: reuse wht transform from dec in encoder
+80e218d Android.mk: fix build with APP_ABI=armeabi-v7a-hard
+59daf08 Merge "cosmetics:"
+5362200 cosmetics:
+3e7f34a AssignSegments: quiet array-bounds warning
+3c2ebf5 Merge "UpdateHistogramCost: avoid implicit double->float"
+cf821c8 UpdateHistogramCost: avoid implicit double->float
+312e638 Extend the search space for GetBestGreenRedToBlue
+1c58526 Fix few nits
+fef2270 Optimize and re-structure VP8LGetHistoImageSymbols
+068b14a Optimize lossless decoding.
+5f0cfa8 Do a binary search to get the optimum cache bits.
+24ca367 Merge "allow 'cwebp -o -' to emit output to stdout"
+e12f874 allow 'cwebp -o -' to emit output to stdout
+2bcad89 allow some more stdin/stout I/O
+84ed4b3 fix cwebp.1 typos after patch #69199
+65b99f1 add a -z option to cwebp, and WebPConfigLosslessPreset() function
+3017661 4-5% faster trellis by removing some unneeded calculations.
+687a58e histogram.c: reindent after b33e8a0
+06d456f Merge "~3-4% faster lossless encoding"
+c60de26 ~3-4% faster lossless encoding
+42eb06f Merge "few cosmetics after patch #69079"
+82af826 few cosmetics after patch #69079
+b33e8a0 Refactor code for HistogramCombine.
+ca1bfff Merge "5-10% encoding speedup with faster trellis (-m 6)"
+5aeeb08 5-10% encoding speedup with faster trellis (-m 6)
+82ae1bf cosmetics: normalize VP8GetCPUInfo checks
+e3dd924 Merge "Refactor GetBestPredictorForTile for future tuning."
+206cc1b Refactor GetBestPredictorForTile for future tuning.
+3cb8406 Merge "speed-up trellis quant (~5-10% overall speed-up)"
+b66f222 Merge "lossy encoding: ~3% speed-up"
+4287d0d speed-up trellis quant (~5-10% overall speed-up)
+390c8b3 lossy encoding: ~3% speed-up
+9a463c4 Merge "dec_neon: convert TransformWHT to intrinsics"
+e8605e9 Merge "dec_neon: add ConvertU8ToS16"
+4aa3e41 MIPS: MIPS32r1: rescaler bugfix
+c16cd99 Speed up lossless encoder.
+9d6b5ff dec_neon: convert TransformWHT to intrinsics
+2ff0aae dec_neon: add ConvertU8ToS16
+77a8f91 fix compilation with USE_YUVj flag
+4acbec1 Merge changes I3b240ffb,Ia9370283,Ia2d28728
+2719bb7 dec_neon: TransformAC3: work on packed vectors
+b7b60ca dec_neon: add SaturateAndStore4x4
+b7685d7 Rescale: let ImportRow / ExportRow be pointer-to-function
+e02f16e dec_neon.c: convert TransformDC to intrinsics
+9cba963 add missing file
+8992ddb use static clipping tables
+0235d5e 1-2% faster quantization in SSE2
+b2fbc36 fix VC12-x64 warning
+6e37cb9 Merge "cosmetics: backward_references.c: reindent after a7d2ee3"
+a42ea97 cosmetics: backward_references.c: reindent after a7d2ee3
+6c32744 Merge "fix missing __BIG_ENDIAN__ definition on some platform"
+a8b6aad fix missing __BIG_ENDIAN__ definition on some platform
+fde2904 Increase initial buffer size for VP8L Bit Writer.
+a7d2ee3 Optimize cache estimate logic.
+7fb6095 Merge "dec_neon.c: add TransformAC3"
+bf182e8 VP8LBitWriter: use a bit-accumulator
+3f40b4a Merge "MIPS: MIPS32r1: clang macro warning resolved"
+1684f4e WebP Decoder: Mark some truncated bitstreams as invalid
+acbedac MIPS: MIPS32r1: clang macro warning resolved
+228e487 dec_neon.c: add TransformAC3
+393f89b Android.mk: avoid gcc-specific flags with clang
+32aeaf1 revamp VP8LColorSpaceTransform() a bit
+0c7cc4c Merge "Don't dereference NULL, ensure HashChain fully initialized"
+391316f Don't dereference NULL, ensure HashChain fully initialized
+926ff40 WEBP_SWAP_16BIT_CSP: remove code dup
+1d1cd3b Fix decode bug for rgbA_4444/RGBA_4444 color-modes.
+939e70e update AUTHORS file
+8934a62 cosmetics: *_mips32.c
+dd438c9 MIPS: MIPS32r1: Optimization of some simple point-sampling functions. PATCH [6/6]
+5352091 Added support for calling sampling functions via pointers.
+d16c697 MIPS: MIPS32r1: Optimization of filter functions. PATCH [5/6]
+04336fc MIPS: MIPS32r1: Optimization of function TransformOne. PATCH [4/6]
+92d8fc7 MIPS: MIPS32r1: Optimization of function WebPRescalerImportRow. PATCH [3/6]
+bbc23ff parse one row of intra modes altogether
+a2f608f Merge "MIPS: MIPS32r1: Optimization of function WebPRescalerExportRow. [2/6]"
+8823085 MIPS: MIPS32r1: Optimization of function WebPRescalerExportRow. [2/6]
+c5a5b02 decode mt+incremental: fix segfault in debug builds
+9882b2f always use fast-analysis for all methods.
+000adac Merge "autoconf: update ax_pthread.m4"
+2d2fc37 update .gitignore
+5bf4255 Merge "Make it possible to avoid automagic dependencies"
+c1cb193 disable NEON for arm64 platform
+73a304e Make it possible to avoid automagic dependencies
+4d493f8 MIPS: MIPS32r1: Decoder bit reader function optimized. PATCH [1/6]
+c741183 make WebPCleanupTransparentArea work with argb picture
+5da1855 add a decoding option to flip image vertically
+00c3c4e Merge "add man/vwebp.1"
+2c6bb42 add man/vwebp.1
+ea59a8e Merge "Merge tag 'v0.4.0'"
+7574bed fix comments related to array sizes
+0b5a90f dwebp.1: fix option formatting
+effcb0f Merge tag 'v0.4.0'
+7c76255 autoconf: update ax_pthread.m4
+fff2a11 make -short work with -print_ssim, -print_psnr, etc.
+68e7901 update ChangeLog (tag: v0.4.0-rc1, tag: v0.4.0, origin/0.4.0, 0.4.0)
+256e433 update NEWS description with new general features
+2962534 Merge "gif2webp: don't use C99 %zu" into 0.4.0
+3b9f9dd gif2webp: don't use C99 %zu
+b5b2e3c cwebp: fix metadata output w/lossy+alpha
+ad26df1 makefile.unix: clean up libgif2webp_util.a
+c3b4557 update Changelog
+ca84112 Merge "bump version to 0.4.0" into 0.4.0
+8c524db bump version to 0.4.0
+eec2398 update AUTHORS & .mailmap
+b9bbf6a update NEWS for 0.4.0
+c72e081 Merge "dec/webp.c: don't wait for data before reporting w/h"
+5ad6531 dec/frame.c: fix formatting
+f7fc4bc dec/webp.c: don't wait for data before reporting w/h
+66a32af Merge "NEON speed up"
+26d842e NEON speed up
+f307f98 Merge "webpmux: let -- stop parameter parsing"
+fe051da Merge "README: add a section on gif2webp"
+6fd2bd6 Merge "manpage pedantry"
+4af1900 README: add a section on gif2webp
+6f36ade manpage pedantry
+f9016cb README: update dwebp options
+b4fa0a4 webpmux: let -- stop parameter parsing
+a9a20ac gif2webp: Add a multi-threaded encode option
+495bef4 fix bug in TrellisQuantize
+605a712 simplify __cplusplus ifdef
+33109f9 Merge "drop: ifdef __cplusplus checks from C files"
+7f9de0b Merge changes I994a5587,I8467bb71,I13b50688,I1e2c9c7b
+5459030 gif2webp: let -- stop parameter parsing
+a4b0aa0 vwebp: let -- stop parameter parsing
+98af68f cwebp: let -- stop parameter parsing
+a33831e dwebp: let -- stop parameter parsing
+3630124 add some checks on error paths
+ce4c713 Merge "autoconf: add --disable-wic"
+5227d99 drop: ifdef __cplusplus checks from C files
+f645355 dwebp.1: fix typo
+f91034f Merge "cwebp: print metadata stats when no output file is given"
+d493455 gif2webp: Backward compatibility for giflib version <= 4.1.3
+4c617d3 gif2webp: Disable output of ICC profile by default
+73b731f introduce a special quantization function for WHT
+41c0cc4 Make Forward WHT transform use 32bit fixed-point calculation
+a3359f5 Only compute quantization params once
+7049043 cwebp: print metadata stats when no output file is given
+d513bb6 * fix off-by-one zthresh calculation * remove the sharpening for non luma-AC coeffs * adjust the bias a little bit to compensate for this
+ad9dec0 Merge "cosmetics: dwebp: fix local function name format"
+f737f03 Merge "dwebp: remove a dead store"
+3c3a70d Merge "makefile.unix: install binaries in $(DESTDIR)/bin/"
+150b655 Merge "Android.mk: add some release compile flags"
+dbebd33 cosmetics: dwebp: fix local function name format
+2774995 dwebp: remove a dead store
+a01e04f autoconf: add --disable-wic
+5009b22 makefile.unix: install binaries in $(DESTDIR)/bin/
+bab30fc Merge "fix -print_psnr / ssim options"
+ebef7fb fix -print_psnr / ssim options
+cb63785 Merge "fix bug due to overzealous check in WebPPictureYUVAToARGB()"
+8189885 Merge "EstimateBestFilter: use an int to iterate WEBP_FILTER_TYPE"
+4ad7d33 Android.mk: add some release compile flags
+c12e236 cosmetics: fix a few typos
+6f10403 fix bug due to overzealous check in WebPPictureYUVAToARGB()
+3f6c35c EstimateBestFilter: use an int to iterate WEBP_FILTER_TYPE
+cc55790 Merge changes I8bb7a4dc,I2c180051,I021a014f,I8a224a62
+c536afb Merge "cosmetics: fix some typos"
+cbdd3e6 add a -dither dithering option to the decoder
+e812401 Updated iosbuild.sh for XCode 5.x
+4931c32 cosmetics: fix some typos
+05aacf7 mux: add some missing casts
+617d934 enc/vp8l: add a missing cast
+46db286 idec: add some missing casts
+b524e33 ErrorStatusLossless: correct return type
+cb261f7 fix a descaling bug for vertical/horizontal U/V interpolation
+bcb3955 Merge changes I48968468,I181bc736
+73f5213 gif2webp: Add a mixed compression mode
+6198715 demux: split chunk parsing from ParseVP8X
+d2e3f4e demux: add a tail pointer for chunks
+87cffcc demux: cosmetics: s/has_frames/is_animation/
+e18e667 demux: strictly enforce the animation flag
+c4f39f4 demux: cosmetics: remove a useless break
+61cb884 demux: (non-exp) fail if the fragmented flag is set
+ff379db few % speedup of lossless encoding
+df3649a remove all disabled code related to P-frames
+6d0cb3d Merge "gif2webp: kmin = 0 should suppress key-frame addition."
+3655598 gif2webp: kmin = 0 should suppress key-frame addition.
+7708e60 Merge "detect flatness in blocks and favor DC prediction"
+06b1503 Merge "add comment about the kLevelsFromDelta[][] LUT generation"
+5935259 add comment about the kLevelsFromDelta[][] LUT generation
+e3312ea detect flatness in blocks and favor DC prediction
+ebc9b1e Merge "VPLBitReader bugfix: Catch error if bit_pos > LBITS too."
+96ad0e0 VPLBitReader bugfix: Catch error if bit_pos > LBITS too.
+a014e9c tune quantization biases toward higher precision
+1e89861 add helpful PrintBlockInfo() function
+596a6d7 make use of 'extern' consistent in function declarations
+c8d48c6 Merge "extract random utils to their own file util/random.[ch]"
+98aa33c extract random utils to their own file util/random.[ch]
+432a723 Merge "swig: add basic go bindings"
+fab618b Merge "rename libwebp.i -> libwebp.swig"
+e4e7fcd swig: add basic go bindings
+d340872 Merge "fast auto-determined filtering strength"
+f8bfd5c fast auto-determined filtering strength
+ac0bf95 small clean-up in ExpandMatrix()
+1939607 rename libwebp.i -> libwebp.swig
+43148b6 filtering: precompute ilimit and hev_threshold
+18f992e simplify f_inner calculation a little
+241d11f add missing const
+86c0031 add a 'format' field to WebPBitstreamFeatures
+dde91fd Demux: Correct the extended format validation
+5d6c5bd add entry for '-resize' option in cwebp's man
+7c098d1 Use some gamma-curve range compression when computing U/V average
+0b2b050 Use deterministic random-dithering during RGB->YUV conversion
+8a2fa09 Add a second multi-thread method
+7d6f2da Merge "up to 20% faster multi-threaded decoding"
+266f63e Merge "libwebp.jar: build w/Java 1.6 for Android compat"
+0532149 up to 20% faster multi-threaded decoding
+38efdc2 Simplify the gif2webp tool: move the optimization details to util
+de89951 libwebp.jar: build w/Java 1.6 for Android compat
+cb22155 Decode a full row of bitstream before reconstructing
+dca8a4d Merge "NEON/simple loopfilter: avoid q4-q7 registers"
+9e84d90 Merge "NEON/TransformWHT: avoid q4-q7 registers"
+fc10249 NEON/simple loopfilter: avoid q4-q7 registers
+2f09d63 NEON/TransformWHT: avoid q4-q7 registers
+77585a2 Merge "use a macrofunc for setting NzCoeffs bits"
+d155507 Merge "use HINT_GRAPH as image_hint for gif source"
+9c56164 Merge "only print GIF_DISPOSE_WARNING once"
+0587986 use HINT_GRAPH as image_hint for gif source
+0b28d7a use a macrofunc for setting NzCoeffs bits
+f9bbc2a Special-case sparse transform
+0012519 gif2webp: detect and flatten uniformly similar blocks
+0deaf0f only print GIF_DISPOSE_WARNING once
+6a8c0eb Merge "small optimization in segment-smoothing loop"
+f7146bc small optimization in segment-smoothing loop
+5a7533c small gif2webp fix
+4df0c89 Merge changes Ic697660c,I27285521
+5b2e6bd Android.mk: add a dwebp target
+f910a84 Android.mk: update build flags
+63f9aba special-case WHT transform when there's only DC
+80911ae Merge "7-8% faster decoding by rewriting GetCoeffs()"
+606c430 gif2webp: Improved compression for lossy animated WebP
+fb887f7 gif2webp: Different kmin/kmax defaults for lossy and lossless
+2a98136 7-8% faster decoding by rewriting GetCoeffs()
+92d47e4 improve VP8L signature detection by checking the version bits too
+5cd43e4 Add -incremental option to dwebp
+54b8e3f webpmux: DisplayInfo(): remove unnecessary error checks.
+40ae352 fix memleak in WebPIDelete()
+d966265 mux.h doc: WebPMuxGetFrame() can return WEBP_MUX_MEMORY_ERROR too.
+0e6747f webpmux -info: display dimensions and has_alpha per frame
+d78a82c Sanity check for underflow
+8498f4b Merge "remove -Wshadow warnings"
+e89c6fc Avoid a potential memleak
+3ebe175 Merge "break down the proba 4D-array into some handy structs"
+6a44550 break down the proba 4D-array into some handy structs
+2f5e893 remove -Wshadow warnings
+bf3a29b Merge "add proper WEBP_HAVE_GIF and WEBP_HAVE_GL flags"
+2b0a759 Merge "fix some warnings from static analysis"
+22dd07c mux.h: Some doc corrections
+79ff034 add proper WEBP_HAVE_GIF and WEBP_HAVE_GL flags
+d51f45f fix some warnings from static analysis
+d134307 fix conversion warning on MSVC
+d538cea gif2webp: Support a 'min' and 'max'  key frame interval
+80b54e1 allow search with token buffer loop and fix PARTITION0 problem
+b7d4e04 add VP8EstimateTokenSize()
+10fddf5 enc/quant.c: silence a warning
+399cd45 Merge "fix compile error on ARM/gcc"
+9f24519 encoder: misc rate-related fixes
+c663bb2 Merge "simplify VP8IteratorSaveBoundary() arg passing"
+fa46b31 Demux.h: Correct a method name reference
+f8398c9 fix compile error on ARM/gcc
+f691f0e simplify VP8IteratorSaveBoundary() arg passing
+42542be up to 6% faster encoding with clang compiler
+93402f0 multi-threaded segment analysis
+7e2d659 Merge "remove the PACK() bit-packing tricks"
+c13fecf remove the PACK() bit-packing tricks
+2fd091c Merge "use NULL for lf_stats_ testing, not bool"
+b11c9d6 dwebp: use default dct_method
+4bb8465 Merge "(de)mux.h: wrap pseudo-code in /* */"
+cfb56b1 make -pass option work with token buffers
+5416aab (de)mux.h: wrap pseudo-code in /* */
+35dba33 use NULL for lf_stats_ testing, not bool
+733a7fa enc->Iterator memory cleanup
+e81fac8 Add support for "no blend" in webpmux binary
+3b80bc4 gif2webp: Separate out each step into a method
+bef7e9c Add doc precision about demux object keeping pointers to data.
+61405a1 dwebp: enable stdout output with WIC
+6eabb88 Merge "Animated WebP: add "do no blend" option to spec"
+be20dec fix compilation for BITS 24
+e58cc13 Merge "dwebp: s/unsigned char/uint8_t/"
+72501d4 dwebp: s/unsigned char/uint8_t/
+2c9633e Merge "gif2webp: Insert independent frames at regular intervals."
+f0d6a14 gif2webp: Insert independent frames at regular intervals.
+b25a6fb yuv.h: fix indent
+ede3602 Merge "cosmetics: fix indent"
+3a65122 dwebp: fix stdout related output
+388a724 cosmetics: fix indent
+4c7322c Merge "dsp: msvc compatibility"
+d50c7e3 Merge "5-7% faster SSE2 versions of YUV->RGB conversion functions"
+b8ab784 Merge "simplify upsampler calls: only allow 'bottom' to be NULL"
+df6cebf 5-7% faster SSE2 versions of YUV->RGB conversion functions
+ad6ac32 simplify upsampler calls: only allow 'bottom' to be NULL
+a5e8afa output to stdout if file name is "-"
+f358450 dsp: msvc compatibility
+43a7c8e Merge "cosmetics"
+4c5f19c Merge "bit_reader.h: cosmetics"
+f72fab7 cosmetics
+14dd5e7 fix const-ness
+b20aec4 Merge "Support for 'do not blend' option in vwebp"
+dcf6522 Support for 'do not blend' option in vwebp
+d5bad03 Animated WebP: add "do no blend" option to spec
+a2f5f73 Merge "Support for "Do not blend" in mux and demux libraries"
+e081f2f Pack code & extra_bits to Struct (VP8LPrefixCode).
+6284854 Support for "Do not blend" in mux and demux libraries
+f486aaa Merge "slightly faster ParseIntraMode"
+d171863 slightly faster ParseIntraMode
+3ceca8a bit_reader.h: cosmetics
+69257f7 Create LUT for PrefixEncode.
+988b708 add WebPWorkerExecute() for convenient bypass
+06e2498 Merge "VP8EncIterator clean-up"
+de4d4ad VP8EncIterator clean-up
+7bbe952 Merge "cosmetics: thread.c: drop a redundant comment"
+da41148 cosmetics: thread.c: drop a redundant comment
+feb4b6e thread.h: #ifdef when checking WEBP_USE_THREAD
+8924a3a thread.c: drop WebPWorker prefix from static funcs
+1aed8f2 Merge "fix indent"
+4038ed1 fix indent
+1693fd9 Demux: A new state WEBP_DEMUX_PARSE_ERROR
+8dcae8b fix rescaling-with-alpha inaccuracy
+11249ab Merge changes I9b4dc36c,I4e0eef4d
+52508a1 Mux: support parsing unknown chunks within a frame/fragment.
+05db057 WebPMuxSetChunk: remove unused variable
+8ba1bf6 Stricter check for presence of alpha when writing lossless images
+a03c351 Demux: WebPIterator now also denotes if the frame has alpha.
+6df743a Decoder: handle fragments case correctly too.
+faa4b07 Support for unknown chunks in mux library
+7d60bbc Speed up HashChainFindCopy function.
+6674014 Speedup Alpha plane encoding.
+b7346a1 0.1 % speedup to decoding
+c606182 webp-container-spec: Tighten language added by last
+a34a502 pngdec: output error messages from libpng
+e84c625 Merge "Detect canvas and image size mismatch in decoder."
+f626fe2 Detect canvas and image size mismatch in decoder.
+f5fbdee demux: stricter image bounds check
+30c8158 add extra assert in Huffman decode code
+8967b9f SSE2 for lossless decoding (critical) functions.
+699d80e Jump-lookup for Huffman coding
+c34307a fix some VS9 warnings about type conversion
+eeada35 pngdec: add missing include
+54b6510 gif2webp: If aligning to even offsets, extra pixels should be transparent
+0bcf5ce Merge "remove a malloc() in case we're using only FILTER_NONE for alpha"
+2c07143 remove a malloc() in case we're using only FILTER_NONE for alpha
+a4d5f59 Faster lossless decoding
+fd53bb7 Merge "alternate LUT-base reverse-bits code"
+d1c166e Merge "Container spec: a clarification on background color."
+fdb9177 Rename a method
+5e96753 Container spec: a clarification on background color.
+30e77d0 Merge branch '0.3.0'
+1b631e2 alternate LUT-base reverse-bits code
+24cc307 ~20% faster lossless decoding
+313d853 Speedup for decoding lossless WebP photographs:
+24ee098 change the bytes_per_pixels_ field into more evocative use_8b_decode
+2a04b03 update ChangeLog (tag: v0.3.1-rc2, tag: v0.3.1)
+7288950 Regression fix for alpha channels using color cache:
+2e377b5 wicdec: silence a format warning
+ad9e42a muxedit: silence some uninitialized warnings
+3307c16 Don't set alpha-channel to 0xff for alpha->green uplift
+5130770 Merge "wicdec: silence a format warning"
+a37eff4 Regression fix for alpha channels using color cache:
+241cf99 Merge "muxedit: silence some uninitialized warnings"
+c8f9c84 Regression fix for alpha unfiltering:
+14cd5c6 muxedit: silence some uninitialized warnings
+a368db8 dec/vp8l: quiet vs9 x64 type conversion warning
+ffae9f3 wicdec: silence a format warning
+8cf0701 Alpha encoding: never filter in case of NO_COMPRESSION
+825e73b update ChangeLog (tag: v0.3.1-rc1)
+abf6f69 update NEWS
+5a92c1a bump version to 0.3.1
+86daf77 store top Y/U/V samples in packed fashion
+67bc353 Revert "add WebPBlendAlpha() function to blend colors against background"
+068db59 Intertwined decoding of alpha and RGB
+38cc011 Simplify forward-WHT + SSE2 version
+3fa595a Support decoding upto given row in DECODE_DATA_FUNC
+520f005 DequantizeLevels(): Add 'row' and 'num_rows' args
+47374b8 Alpha unfilter for given set of rows
+f32097e probe input file and quick-check for WebP format.
+a2aed1d configure: improve gl/glut library test
+c7e89cb update copyright text
+a00380d configure: remove use of AS_VAR_APPEND
+a94a88d fix EXIF parsing in PNG
+a71e5d8 add doc precision for WebPPictureCopy() and WebPPictureView()
+8287012 remove datatype qualifier for vmnv
+e190843 fix a memory leak in gif2webp
+0b18b9e fix two minor memory leaks in webpmux
+db5095d remove some cruft from swig/libwebp.jar
+850e956 README: update swig notes
+bddd9b0 swig/python: add minimal documentation
+d573a8d swig: add python encode support
+6b93187 swig/java: reduce wrapper function code duplication
+6fe536f swig/java: rework uint8_t typemap
+a2ea464 Fix the bug in ApplyPalette.
+7bb28d2 webp/lossless: fix big endian BGRA output
+f036d4b Speed up ApplyPalette for ARGB pixels.
+8112c8c remove some warnings:
+cc128e0 Further reduce memory to decode lossy+alpha images
+07db70d fix for big-endian
+eda8a7d gif2webp: Fix signed/unsigned comparison mismatch
+31f346f Makefile.vc: fix libwebpdemux dll variable typo
+6c76d28 swig: add python (decode) support
+b4f5bb6 swig: cosmetics
+498d4dd WebP-Lossless encoding improvements.
+26e7244 swig: ifdef some Java specific code
+8ecec68 configure: add warning related flags
+e676b04 configure: add GLUT detection; build vwebp
+b0ffc43 Alpha decoding: significantly reduce memory usage
+20aa7a8 configure: add --enable-everything
+b8307cc configure.ac: add some helper macros
+980e7ae Remove the gcc compilation comments
+7f25ff9 gif2webp: Fix ICC and XMP support
+d8e5321 Add missing name to AUTHORS
+11edf5e Demux: Fix a potential memleak
+c7b9218 don't forward declare enums
+7a650c6 prevent signed int overflow in left shift ops
+31bea32 add precision about dynamic output reallocation with IDecoder
+c22877f Add incremental support for extended format files
+5051245 Makefile.vc: have 'all' target build everything
+8191dec Makefile.vc: flags cleanup
+b9d7473 Makefile.vc: drop /FD flag
+5568dbc update gitignore
+f4c7b65 WebPEncode: An additional check. Start VP8EncLoop/VP8EncTokenLoop only if VP8EncStartAlpha succeeded.
+1fb04be pngdec: Avoid a double-free.
+dcbb1ca add WebPBlendAlpha() function to blend colors against background
+bc9f5fb configure.ac: add AM_PROG_AR for automake >= 1.12
+bf867bf Tuned cross_color parameter (step) for lower qual
+90e2ec5 Merge "probe input file and quick-check for WebP format."
+7180d7f Merge "update copyright text"
+830f72b probe input file and quick-check for WebP format.
+2ccf58d configure: improve gl/glut library test
+d640614 update copyright text
+c2113ad Merge "configure: remove use of AS_VAR_APPEND"
+9326a56 configure: remove use of AS_VAR_APPEND
+ea63d61 fix a type warning on VS9 x86
+bec1109 fix EXIF parsing in PNG
+b6e65f3 Merge "fix warnings for vs9 x64"
+438946d fix warnings for vs9 x64
+f4710e3 collect macroblock reconstruction data in VP8MBData struct
+23d28e2 add doc precision for WebPPictureCopy() and WebPPictureView()
+518f2cd cosmetics: gif2webp: fix indent
+af358e6 Merge "remove datatype qualifier for vmnv"
+3fe9163 remove datatype qualifier for vmnv
+764fdff fix a memory leak in gif2webp
+3e59a74 fix two minor memory leaks in webpmux
+47b9862 Merge "README: update swig notes"
+325d15f remove some cruft from swig/libwebp.jar
+4a7627c README: update swig notes
+5da81e3 Merge "swig/python: add minimal documentation"
+f39e08f Merge "swig: add python encode support"
+6ca4a3e Merge "swig/java: reduce wrapper function code duplication"
+8f8702b Merge "swig/java: rework uint8_t typemap"
+91413be reduce memory for VP8MB and remove bitfields use
+7413394 Fix the memory leak in ApplyFilters.
+2053c2c simplify the alpha-filter testing loop
+825b64d swig/python: add minimal documentation
+14677e1 swig: add python encode support
+a5c297c swig/java: reduce wrapper function code duplication
+ad4a367 swig/java: rework uint8_t typemap
+0d25876 use uint8_t for inv_palette[]
+afa3450 Fix the bug in ApplyPalette.
+2d6ac42 Merge "webp/lossless: fix big endian BGRA output"
+2ca8396 webp/lossless: fix big endian BGRA output
+742110c Speed up ApplyPalette for ARGB pixels.
+2451e47 misc code cleanup
+83db404 Merge "swig: add python (decode) support"
+eeeea8b Merge "swig: cosmetics"
+d5f9b8f Merge "libwebp: fix vp8 encoder mem alloc offsetting"
+d8edd83 libwebp: fix vp8 encoder mem alloc offsetting
+8983b83 remove use of bit-fields in VP8FInfo
+87a4fca remove some warnings:
+ba8f74e Merge "fix for big-endian"
+a65067f Merge "Further reduce memory to decode lossy+alpha images"
+64c8448 Further reduce memory to decode lossy+alpha images
+332130b Mux: make a few methods static
+4437061 fix for big-endian
+5199eab Merge "add uncompressed TIFF output support"
+a3aede9 add uncompressed TIFF output support
+f975b67 Merge "gif2webp: Fix signed/unsigned comparison mismatch"
+5fbc734 Merge "GetFeatures: Detect invalid VP8X/VP8/VP8L data"
+d5060c8 Merge "mux.h: A comment fix + some consistency fixes"
+352d0de GetFeatures: Detect invalid VP8X/VP8/VP8L data
+3ef79fe Cosmetic: "width * height"
+043e1ae gif2webp: Fix signed/unsigned comparison mismatch
+5818cff mux.h: A comment fix + some consistency fixes
+1153f88 Merge "swig: ifdef some Java specific code"
+3eeedae Makefile.vc: fix libwebpdemux dll variable typo
+f980faf swig: add python (decode) support
+7f5f42b swig: cosmetics
+8eae188 WebP-Lossless encoding improvements.
+c7247c4 swig: ifdef some Java specific code
+4cb234d Merge "Mux: make ValidateForSingleImage() method static"
+ed6f530 Merge "Add GetCanvasSize() method to mux"
+1d530c9 Mux: make ValidateForSingleImage() method static
+bba4c2b configure: add warning related flags
+fffefd1 Add GetCanvasSize() method to mux
+732da8d Merge "configure: add GLUT detection; build vwebp"
+0e513f7 configure: add GLUT detection; build vwebp
+55d1c15 Merge "Alpha decoding: significantly reduce memory usage"
+13d99fb Merge "configure: add --enable-everything"
+2bf698f Merge "configure.ac: add some helper macros"
+edccd19 Alpha decoding: significantly reduce memory usage
+3cafcc9 configure: add --enable-everything
+4ef1447 configure.ac: add some helper macros
+a4e1cdb Remove the gcc compilation comments
+6393fe4 Cosmetic fixes
+9c4ce97 Simplify forward-WHT + SSE2 version
+878b9da fix missed optim
+0004617 VP8GetInfo(): Check for zero width or height.
+9bf3129 align VP8Encoder::nz_ allocation
+5da165c fix CheckMode() signature
+0ece07d Merge "explicitly pad bitfields to 32-bits"
+9dbc9d1 explicitly pad bitfields to 32-bits
+5369a80 Merge "prevent signed int overflow in left shift ops"
+70e3971 Merge "cosmetics: remove unnecessary ';'s"
+d3136ce Merge "don't forward declare enums"
+b26e5ad gif2webp: Fix ICC and XMP support
+46089b2 Add missing name to AUTHORS
+94328d6 Demux: Fix a potential memleak
+96e948d don't forward declare enums
+f4f9088 prevent signed int overflow in left shift ops
+0261545 cosmetics: remove unnecessary ';'s
+7ebdf11 Merge "Fix few missing comparisons to NULL"
+1579989 Fix few missing comparisons to NULL
+ea1b21c Cleaned up VP8GetHeaders() so that it parses only frame header
+b66caee dwebp: add support for BMP output
+ff885bf add precision about dynamic output reallocation with IDecoder
+79241d5 Merge "Makefile.vc: have 'all' target build everything"
+ac1c729 Merge "Makefile.vc: flags cleanup"
+118a055 Merge "Makefile.vc: drop /FD flag"
+ecad010 Merge "update gitignore"
+a681b4f Rename PRE_VP8 state to WEBP_HEADER
+ead4d47 Add incremental support for extended format files
+69d0f92 Makefile.vc: have 'all' target build everything
+5296749 Makefile.vc: flags cleanup
+c61baf0 Makefile.vc: drop /FD flag
+3a15125 update gitignore
+5167ca4 Merge "WebPEncode: An additional check. Start VP8EncLoop/VP8EncTokenLoop only if VP8EncStartAlpha succeeded."
+67708d6 WebPEncode: An additional check. Start VP8EncLoop/VP8EncTokenLoop only if VP8EncStartAlpha succeeded.
+b68912a pngdec: Avoid a double-free.
+82abbe1 Merge "configure.ac: add AM_PROG_AR for automake >= 1.12"
+e7d9548 add WebPBlendAlpha() function to blend colors against background
+ed4dc71 configure.ac: add AM_PROG_AR for automake >= 1.12
+df4a406 Merge branch '0.3.0'
+1e0d4b8 Update ChangeLog (tag: v0.3.0-rc7, tag: v0.3.0)
+d52b405 Cosmetic fixes
+6cb4a61 misc style fix
+68111ab add missing YUVA->ARGB automatic conversion in WebPEncode()
+e9a7990 Cosmetic fixes
+403bfe8 Container spec: Clarify frame disposal
+2aaa423 Merge "add missing YUVA->ARGB automatic conversion in WebPEncode()"
+07d87bd add missing YUVA->ARGB automatic conversion in WebPEncode()
+142c462 misc style fix
+3e7a13a Merge "Container spec: clarify the background color field" into 0.3.0
+14af774 container doc: add a note about the 'ANMF' payload
+cc635ef Container spec: clarify the background color field
+e3e3394 container doc: move RIFF description to own section
+4299f39 libwebp/mux: fix double free
+33f9a69 Merge "demux: keep a frame tail pointer; used in AddFrame" into 0.3.0
+a2a7b95 use WebPDataCopy() instead of re-coding it.
+6f18f12 demux: keep a frame tail pointer; used in AddFrame
+e5af49e add doc precision about WebPParseHeaders() return codes
+db46daa Merge "Makefile.vc: fix dynamic builds" into 0.3.0
+53c77af Merge "gif2webp: Bgcolor fix for a special case" into 0.3.0
+a5ebd14 gif2webp: Bgcolor fix for a special case
+6378f23 Merge "vwebp/animation: fix background dispose" into 0.3.0
+3c8eb9a fix bad saturation order in QuantizeBlock
+04c7a2e vwebp/animation: fix background dispose
+81a5069 Makefile.vc: fix dynamic builds
+5f25c39 update ChangeLog (tag: v0.3.0-rc6)
+14d42af examples: don't use C99 %zu
+5ccf1fe update ChangeLog
+2560c24 update NEWS
+f43bafc Merge changes Iecccb09c,If5ee9fd2,I3e181ce4 into 0.3.0
+a788644 dwebp: warn when decoding animated webp's
+302efcd Decode: return more meaningful error for animation
+ad45273 WebPBitstreamFeatures: add has_animation field
+783dfa4 disable FRGM decoding for good in libwebpmux
+4b956be Update ChangeLog
+ad8b86d update NEWS
+3e084f6 Merge "demux cosmetics: comments/rename internal function" into 0.3.0
+d3f8c62 Merge "move WebPFeatureFlags declaration" into 0.3.0
+7386fe5 Merge "libwebp{demux,mux}: install mux_types.h" into 0.3.0
+d6cd4e9 Merge "bump decode abi" into 0.3.0
+17f8da5 bump decode abi
+97684ae Merge "add doc precision about WebPDemuxPartial()" into 0.3.0
+f933fd2 move WebPFeatureFlags declaration
+289bc47 libwebp{demux,mux}: install mux_types.h
+224e8d4 add doc precision about WebPDemuxPartial()
+4c18e80 demux cosmetics: comments/rename internal function
+7cfd1bf update AUTHORS
+401f7b8 Merge "speed-up lossless (~3%) with ad-hoc histogram cost evaluation" into 0.3.0
+1fc8ffc Merge "makefile.unix: dist related changes" into 0.3.0
+8a89c6e Merge changes I466c377f,Ib761ebd3,I694857fc into 0.3.0
+f4ffb2d speed-up lossless (~3%) with ad-hoc histogram cost evaluation
+723847d gif2webp: only write error messages to stderr
+701b9e2 makefile.unix: dist related changes
+bb85b43 Merge "update NEWS" into 0.3.0
+59423a2 gif2webp: fix crash on open failure with libgif5
+9acb17d gif2webp: silence a unused param warning
+7d9fdc2 Merge "README updates" into 0.3.0
+5621934 Merge "build: fix install race on shared headers" into 0.3.0
+70809d8 Merge "bump version to 0.3.0" into 0.3.0
+d851cd1 demux: make the parse a bit more strict
+28bb410 update NEWS
+cef9388 bump version to 0.3.0
+9048494 build: fix install race on shared headers
+1e67e8e README updates
+42b611a Merge "configure: drop experimental from mux/demux" into 0.3.0
+096a8e3 Merge "vwebp: add color profile support" into 0.3.0
+ddfee5d vwebp: add color profile support
+0d6927d Merge "Mark fragment options as experimental in webpmux" into 0.3.0
+5dbd403 Mark fragment options as experimental in webpmux
+a0a6648 configure: drop experimental from mux/demux
+ee65bad Merge "add support for BITS > 32" into 0.3.0
+744930d add support for BITS > 32
+7dd288f cwebp: fix build
+19a8dd0 Merge "Makefile.vc: add vwebp.exe target" into 0.3.0
+50eedda Merge "examples: normalize icc related program arguments" into 0.3.0
+757f637 Merge "Makefile.vc: add libwebpdecoder target" into 0.3.0
+b65c4b7 Makefile.vc: add libwebpdecoder target
+f8db7b4 Merge "vwebp: replace doubles w/floats where appropriate" into 0.3.0
+d99aa56 Makefile.vc: add vwebp.exe target
+013023e vwebp: replace doubles w/floats where appropriate
+9b3db89 README.mux: add version reference
+7b6a26c Merge "cwebp: output metadata statistics" into 0.3.0
+d8dc72a examples: normalize icc related program arguments
+7bfc905 Merge "make alpha unfilter work in-place" into 0.3.0
+0037b2d Merge "add LUT-free reference code for YUV->RGB conversion." into 0.3.0
+166bf74 Merge "demux: disable fragment parsing" into 0.3.0
+126974b add LUT-free reference code for YUV->RGB conversion.
+0aef3eb make alpha unfilter work in-place
+14ef500 Merge "Remove 'status: experimental' from container spec" into 0.3.0
+d40c98e Merge "webpmux binary: tiny style fix" into 0.3.0
+0bc4268 cwebp: output metadata statistics
+bc03980 Merge "autoconf: normalize experimental define" into 0.3.0
+d1e21b1 Remove 'status: experimental' from container spec
+7681bb9 webpmux binary: tiny style fix
+a3dd3d0 avoid installing example_util.h
+252320e demux: disable fragment parsing
+537bde0 autoconf: normalize experimental define
+5e338e0 Merge changes I33e8a613,I8e8a7b44 into 0.3.0
+d9d0ea1 Merge changes If21e3ec7,I991fc30b into 0.3.0
+627f5ca automake: add reference to libwebp for mux/demux
+eef73d0 don't consolidate proba stats too often
+05ec4cc libwebp{,decoder}.pc: add pthread flags
+1bfcf5b add libwebpmux.pc
+26ca843 add libwebpdemux.pc
+69e2590 Merge "Tune Lossless compression for lower qualities."
+0478b5d Tune Lossless compression for lower qualities.
+39f7586 add a mention of parallel alpha encoding in the NEWS
+5a21d96 Merge "1.5x-2x faster encoding for method 3 and up"
+9bfbdd1 1.5x-2x faster encoding for method 3 and up
+27dc741 Correct frame options order in README.mux
+be2fd17 Mux: fix a scenario with bad ANMF/FRGM size
+19eb012 Merge "Demux: Add option to get frame count using GetI()"
+7368b8c Merge "WebPGetFeatures() out of if condition for clarity."
+f604c9a Merge "fix windows build"
+153f94e fix windows build
+847b492 Merge "vwebp: use magenta for 'i'nfo display"
+25ea46b Merge "vwebp: add keyboard shortcuts to help output"
+bea7cca vwebp: use magenta for 'i'nfo display
+8fab161 webpmux: correct -frame param order in help output
+03cc23d vwebp: add keyboard shortcuts to help output
+068eba8 Demux: Add option to get frame count using GetI()
+988b8f5 WebPGetFeatures() out of if condition for clarity.
+6933d91 Merge "gif2webp: Be lenient about background color index."
+4d0f7c5 Merge "WebPGetFeatures() behavior change:"
+fdeeb01 gif2webp: Be lenient about background color index.
+ad25032 Merge "multi-threaded alpha encoding for lossy"
+4e32d3e Merge "fix compilation of token.c"
+f817930 multi-threaded alpha encoding for lossy
+8805035 fix compilation of token.c
+fc81621 code using the actual values for num_parts_, not the ones from config
+7265535 Merge "move the config check from .c to .h"
+dd9e76f move the config check from .c to .h
+956b217 WebPGetFeatures() behavior change:
+df02e4c WebPDemuxGetI behavior change:
+633c004 Merge "rebalance method tools (-m) for methods [0..4]"
+58ca6f6 rebalance method tools (-m) for methods [0..4]
+7648c3c Merge "describe rd-opt levels introduce VP8RDLevel enum"
+67fb100 Merge "autoconf: enable silent-rules by default"
+a5042a3 GetVersion() methods for mux and demux
+5189957 describe rd-opt levels introduce VP8RDLevel enum
+4e094ac autoconf: enable silent-rules by default
+b7eaa85 inline VP8LFastLog2() and VP8LFastSLog2 for small values
+5cf7792 split quant_levels.c into decoder and encoder version
+e5d3ffe Merge "Update code example in README.mux"
+ac5a915 Update code example in README.mux
+38a91e9 Add example code snippet for demux API
+5f557f3 README.mux: add info about Demux API and vwebp
+c0ba090 backward_references: avoid signed integer overflow
+943386d disable SSE2 for now
+9479fb7 lossless encoding speedup
+ec2030a merge two lines together
+b67956c Merge "Remove ReadOneBit() and ReadSymbolUnsafe()"
+1667bde Remove ReadOneBit() and ReadSymbolUnsafe()
+3151669 wicdec + dwebp cosmetics: normalize formatting
+92668da change default filtering parameters:   * type is now 'strong'   * strength is now '60'
+b7490f8 introduce WEBP_REFERENCE_IMPLEMENTATION compile option
+3383885 faster decoding (3%-6%)
+5c3e381 Merge "add a -jpeg_like option"
+c231104 remove unused declaration of VP8Zigzag
+3615295 Merge "wicdec: add alpha support for paletted formats"
+c9f1649 wicdec: add alpha support for paletted formats
+1262f81 Merge "wicdec: silence some warnings"
+e7ea61e wicdec: silence some warnings
+23c0f35 fix missing intptr_t->int cast for MSVC
+e895059 add a -jpeg_like option
+1f803f6 Merge "Tune alpha quality mapping to more reasonable values."
+1267d49 Tune alpha quality mapping to more reasonable values.
+043076e Merge "speed-up lossless in BackwardTrace"
+f3a44dc remove one malloc from TraceBackwards()
+0fc1a3a speed-up lossless in BackwardTrace
+7c732e5 cwebp: centralize WebPCleanupTransparentArea()
+7381254 Merge "wicdec: add ICC profile extraction"
+e83ff7d wicdec: add ICC profile extraction
+146c6e3 Merge "cosmetics: pngdec: normalize default label location"
+a8f549d Merge "manpages: italicize option parameters"
+e118db8 Merge "encode.h: note the need to free() WebPMemoryWriter"
+1dfee6d cosmetics: pngdec: normalize default label location
+14c3820 manpages: italicize option parameters
+7defbfa encode.h: note the need to free() WebPMemoryWriter
+88d382a cwebp: cleanup after memory_writer
+12d6cec fix extra space in dwebp.1 man
+b01681a Fix for demuxer frame iteration:
+56c12aa Demuxer creation fix:
+66c810b add a -yuv option to dwebp (very similar to -pgm)
+841a3ba Merge "Remove -Wshadow warnings."
+8fd0252 Merge "upsampling_neon.c: fix build"
+6efed26 Remove -Wshadow warnings.
+60904aa Merge "allow WebPINewRGB/YUVA to be passed a NULL output buffer."
+b7adf37 allow WebPINewRGB/YUVA to be passed a NULL output buffer.
+27f8f74 upsampling_neon.c: fix build
+06b9cdf gitignore: add IOS related directories
+f112221 Merge "Fix more comments for iobuild.sh"
+fe4d25d Fix more comments for iobuild.sh
+1de3e25 Merge "NEON optimised yuv to rgb conversion"
+090b708 NEON optimised yuv to rgb conversion
+daa0647 Merge "Add ios build script for building iOS library."
+79fe39e Add ios build script for building iOS library.
+126c035 remove some more -Wshadow warnings
+522e9d6 Merge "cwebp: enable '-metadata'"
+76ec5fa cwebp: enable '-metadata'
+aeb91a9 Merge "cosmetics: break a few long lines"
+be7c96b cosmetics: break a few long lines
+cff8ddb Merge "add libwebpdecoder.pc"
+93148ab Merge "libwebp.pc.in: detab"
+6477f95 Merge "Makefile.vc: normalize path separator"
+bed1ed7 add libwebpdecoder.pc
+46168b2 libwebp.pc.in: detab
+a941a34 Fixed few nits in the build files.
+dd7a49b Makefile.vc: normalize path separator
+9161be8 Merge "cwebp: extract WIC decoding to its own module"
+08e7c58 Merge "Provide an option to build decoder library."
+0aeba52 Provide an option to build decoder library.
+757ebcb catch malloc(0)/calloc(0) with an assert
+152ec3d Merge "handle malloc(0) and calloc(0) uniformly on all platforms"
+a452a55 cwebp: extract WIC decoding to its own module
+2b252a5 Merge "Provide option to swap bytes for 16 bit colormodes"
+94a48b4 Provide option to swap bytes for 16 bit colormodes
+42f8f93 handle malloc(0) and calloc(0) uniformly on all platforms
+8b2152c Merge "add an extra assert to check memory bounds"
+0d19fbf remove some -Wshadow warnings
+cd22f65 add an extra assert to check memory bounds
+8189fed Merge "Add details and reference about the YUV->RGB conversion"
+1d2702b Merge "Formatting fixes in lossless bitstream spec"
+8425aae Formatting fixes in lossless bitstream spec
+a556cb1 Add details and reference about the YUV->RGB conversion
+d8f21e0 add link to SSIM description on Wikipedia
+18e9167 Merge "WebP-lossless spec clarifications:"
+98e25b9 Merge "cwebp: add -metadata option"
+f01c2a5 WebP-lossless spec clarifications:
+f4a9797 Merge "Disto4x4 and Disto16x16 in NEON"
+47b7b0b Disto4x4 and Disto16x16 in NEON
+7eaee9f cwebp: add -metadata option
+36c52c2 tiffdec: use toff_t for exif ifd offset
+7c8111e Merge "cwebp/tiffdec: add TIFF metadata extraction"
+e6409ad Remove redundant include from dsp/lossless code.
+1ab5b3a Merge "configure: fix --with-gifincludedir"
+03c749e configure: fix --with-gifincludedir
+8b65063 multiple libgif versions support for gif2webp
+476e293 gif2webp: Use DGifOpenFileName()
+b50f277 tiffdec: correct format string
+2b9048e Merge "tiffdec: check error returns for width/height"
+a1b5a9a Merge "cwebp/tiff: use the first image directory"
+079423f tiffdec: check error returns for width/height
+d62824a Merge "cwebp/jpegdec: add JPEG metadata extraction"
+03afaca Merge "cwebp: add PNG metadata extraction"
+2c72496 cwebp/jpegdec: add JPEG metadata extraction
+dba64d9 cwebp: add PNG metadata extraction
+1f075f8 Lossless spec corrections/rewording/clarifications
+2914ecf cwebp/tiffdec: add TIFF metadata extraction
+d82a3e3 More corrections/clarifications in lossless spec:
+bd00255 cwebp/tiff: use the first image directory
+df7aa07 Merge "Cleanup around jpegdec"
+0f57dcc decoding speed-up (~1%)
+bcec339 Lossless bitstream clarification:
+6bf2087 add examples/metadata.c
+207f89c Merge "configure: add libwebpdemux status to summary"
+1bd287a Cleanup around jpegdec
+9145567 Merge "cosmetics: use '== 0' in size checks"
+d6b88b7 cosmetics: use '== 0' in size checks
+d3dace2 cosmetics: jpegdec
+2f69af7 configure: add libwebpdemux status to summary
+1c1c564 cwebp: extract tiff decoding to its own module
+6a871d6 cwebp: extract jpeg decoding to its own module
+2ee228f cwebp: extract png decoding to its own module
+4679db0 Merge "cwebp: add metadata framework"
+63aba3a cwebp: add metadata framework
+931bd51 lossless bitstream: block size bits correction
+e4fc4c1 lossless bitstream: block size bits correction
+d65ec67 fix build, move token.c to src/enc/
+657f5c9 move token buffer to its own file (token.c)
+c34a375 introduce GetLargeValue() to slim-fast GetCoeffs().
+d5838cd faster non-transposing SSE2 4x4 FTransform
+f76191f speed up GetResidualCost()
+ba2aa0f Add support for BITS=24 case
+2e7f6e8 makefile.unix: Dependency on libraries
+dca8421 Merge "Separate out mux and demux code and libraries:"
+23782f9 Separate out mux and demux code and libraries:
+bd56a01 configure: add summary output
+90e5e31 dwebp manual: point to webpmux, gif2webp.
+540790c gif2webp.c: add a note about prerequisites
+d1edf69 cwebp man page: meaning of '-q' for lossy/lossless
+79efa1d Add man page for gif2webp utility
+2243e40 Merge "gif2webp build support with autoconf tools"
+c40efca gif2webp build support with autoconf tools
+6523e2d WebP Container:
+4da788d Merge "simplify the fwd transform"
+42c3b55 simplify the fwd transform
+41a6ced user GLfloat instead of float
+b542611 fix indentation
+68f282f * handle offset in anim viewer 'vwebp' * fix gif2webp to handle disposal method and odd offset correctly
+118cb31 Merge "add SSE2 version of Sum of Square error for 16x16, 16x8 and 8x8 case"
+8a7c3cc Merge "Change the order of -frame argument to be more natural"
+99e0a70 Merge "Simplify the texture evaluation Disto4x4()"
+0f923c3 make the bundling work in a tmp buffer
+e5c3b3f Simplify the texture evaluation Disto4x4()
+4860008 Change the order of -frame argument to be more natural
+35bfd4c add SSE2 version of Sum of Square error for 16x16, 16x8 and 8x8 case
+a7305c2 Clarification for unknown chunks
+4c4398e Refine WebP Container Spec wrt unknown chunks.
+2ca642e Rectify WebPMuxGetFeatures:
+7caab1d Some cosmetic/comment fixes.
+60b2651 Merge "Write a GIF to WebP converter based on libgif."
+c7127a4 Merge "Add NEON version of FTransformWHT"
+11b2721 Write a GIF to WebP converter based on libgif.
+e9a15a3 ExUtilWriteFile() to write memory segment to file
+74356eb Add a simple cleanup step in mux assembly:
+51bb1e5 mux.h: correct WebPDemuxSelectFragment() prototype
+22a0fd9 Add NEON version of FTransformWHT
+fa30c86 Update mux code to match the spec wrt animation
+d9c5fbe by-pass Analysis pass in case segments=1
+d2ad445 Merge changes Ibeccffc3,Id1585b16
+5c8be25 Merge "Chunk fourCCs for XMP/EXIF"
+a00a3da Use 'frgm' instead of 'tile' in webpmux parameters
+81b8a74 Design change in ANMF and FRGM chunks:
+f903cba Chunk fourCCs for XMP/EXIF
+812933d Tune performance of HistogramCombine
+52ad197 Animation specification in container spec
+001b930 Image fragment specification in container spec
+391f9db Ordering of description of bits in container spec
+d573577 Metadata specification in container spec
+1c4609b Merge commit 'v0.2.1'
+0ca584c Merge "Color profile specification in container spec"
+e8b41ad add NEON asm version for WHT inverse transform
+af6f0db Color profile specification in container spec
+a61a824 Merge "Add NULL check in chunk APIs"
+0e8b7ee fix WebPPictureView() unassigned strides
+75e5f17 ARM/NEON: 30% encoding speed-up
+02b4356 Add NULL check in chunk APIs
+a077072 mux struct naming
+6c66dde Merge "Tune Lossless encoder"
+ab5ea21 Tune Lossless encoder
+74fefc8 Update ChangeLog (tag: v0.2.1, origin/0.2.0, 0.2.0)
+92f8059 Rename some chunks:
+3bb4bbe Merge "Mux API change:"
+d0c79f0 Mux API change:
+abc0604 Merge "update NEWS" into 0.2.0
+57cf313 update NEWS
+25f585c bump version to 0.2.1
+fed7c04 libwebp: validate chunk size in ParseOptionalChunks
+552cd9b cwebp (windows): fix alpha image import on XP
+b14fea9 autoconf/libwebp: enable dll builds for mingw
+4a8fb27 [cd]webp: always output windows errors
+d662158 fix double to float conversion warning
+72b96a6 cwebp: fix jpg encodes on XP
+734f762 VP8LAllocateHistogramSet: fix overflow in size calculation
+f9cb58f GetHistoBits: fix integer overflow
+b30add2 EncodeImageInternal: fix uninitialized free
+3de58d7 fix the -g/O3 discrepancy for 32bit compile
+77aa7d5 fix the BITS=8 case
+e5970bd Make *InitSSE2() functions be empty on non-SSE2 platform
+ef5cc47 make *InitSSE2() functions be empty on non-SSE2 platform
+c4ea259 make VP8DspInitNEON() public
+8344ead Merge "libwebp: validate chunk size in ParseOptionalChunks"
+4828bb9 Merge "cwebp (windows): fix alpha image import on XP"
+3076333 libwebp: validate chunk size in ParseOptionalChunks
+7048189 AccumulateLSIM: fix double -> float warnings
+eda8ee4 cwebp (windows): fix alpha image import on XP
+c6e9865 Merge "add EXPERIMENTAL code for YUV-JPEG colorspace"
+f0360b4 add EXPERIMENTAL code for YUV-JPEG colorspace
+f86e6ab add LSIM metric to WebPPictureDistortion()
+c3aa215 Speed up HistogramCombine for lower qualities.
+1765cb1 Merge "autoconf/libwebp: enable dll builds for mingw"
+a13562e autoconf/libwebp: enable dll builds for mingw
+9f469b5 typo: no_fancy -> no_fancy_upsampling
+1a27f2f Merge "fix double to float conversion warning"
+cf1e90d Merge "cwebp: fix jpg encodes on XP"
+f2b5d19 [cd]webp: always output windows errors
+e855208 fix double to float conversion warning
+ecd66f7 cwebp: fix jpg encodes on XP
+7b3eb37 Tune lossless compression to get better gains.
+ce8bff4 Merge "VP8LAllocateHistogramSet: fix overflow in size calculation"
+ab5b67a Merge "EncodeImageInternal: fix uninitialized free"
+7fee5d1 Merge "GetHistoBits: fix integer overflow"
+a6ae04d VP8LAllocateHistogramSet: fix overflow in size calculation
+80237c4 GetHistoBits: fix integer overflow
+8a99723 EncodeImageInternal: fix uninitialized free
+0b9e682 minor cosmetics
+a792b91 fix the -g/O3 discrepancy for 32bit compile
+73ba435 Merge "detect and merge similar segments"
+fee6627 detect and merge similar segments
+0c44f41 src/webp/*.h: don't forward declare enums in C++
+d7a5ac8 vwebp: use demux interface
+931e0ea Merge "replace 'typedef struct {} X;" by "typedef struct X X; struct X {};""
+8f216f7 remove cases of equal comparison for qsort()
+28d25c8 replace 'typedef struct {} X;" by "typedef struct X X; struct X {};"
+2afee60 speed up for ARM using 8bit for boolean decoder
+5725cab new segmentation algorithm
+2cf1f81 Merge "fix the BITS=8 case"
+12f78ae fix the BITS=8 case
+6920c71 fix MSVC warnings regarding implicit uint64 to uint32 conversions
+f6c096a webpmux binary: Rename 'xmp' option to 'meta'
+ddfe871 webpmux help correction
+b7c5544 Merge "Make *InitSSE2() functions be empty on non-SSE2 platform"
+1c04a0d Common APIs for chunks metadata and color profile.
+2a3117a Merge "Create WebPMuxFrameInfo struct for Mux APIs"
+5c3a723 Make *InitSSE2() functions be empty on non-SSE2 platform
+7c6e60f make *InitSSE2() functions be empty on non-SSE2 platform
+c7eb457 make VP8DspInitNEON() public
+ab3234a Create WebPMuxFrameInfo struct for Mux APIs
+e3990fd Alignment fixes
+e55fbd6 Merge branch '0.2.0'
+4238bc0 Update ChangeLog (tag: v0.2.0)
+c655380 dec/io.c: cosmetics
+fe1958f RGBA4444: harmonize lossless/lossy alpha values
+681cb30 fix RGBA4444 output w/fancy upsampling
+f06c1d8 Merge "Alignment fix" into 0.2.0
+f56e98f Alignment fix
+6fe843b avoid rgb-premultiply if there's only trivial alpha values
+528a11a fix the ARGB4444 premultiply arithmetic
+a0a4885 Lossless decoder fix for a special transform order
+62dd9bb Update encoding heuristic w.r.t palette colors.
+6f4272b remove unused ApplyInverseTransform()
+93bf0fa Update ChangeLog (tag: v0.2.0-rc1)
+5934fc5 update AUTHORS
+014a711 update NEWS
+43b0d61 add support for ARGB -> YUVA conversion for lossless decoder
+33705ca bump version to 0.2.0
+c40d7ef fix alpha-plane check + add extra checks
+a06f802 MODE_YUVA: set alpha to opaque if the image has none
+52a87dd Merge "silence one more warning" into 0.2.0
+3b02309 silence one more warning
+f94b04f move some RGB->YUV functions to yuv.h
+4b71ba0 README: sync [cd]webp help output
+c9ae57f man/dwebp.1: add links to output file format details
+292ec5c quiet a few 'uninitialized' warnings
+4af3f6c fix indentation
+9b261bf remove the last NOT_HAVE_LOG2 instances
+323dc4d remove use of log2(). Use VP8LFastLog2() instead.
+8c515d5 Merge "harness some malloc/calloc to use WebPSafeMalloc and WebPSafeCalloc" into 0.2.0
+d4b4bb0 Merge changes I46090628,I1a41b2ce into 0.2.0
+bff34ac harness some malloc/calloc to use WebPSafeMalloc and WebPSafeCalloc
+a3c063c Merge "extra size check for security" into 0.2.0
+5e79630 Merge "WebPEncode: clear stats at the start of encode" into 0.2.0
+f1edf62 Merge "rationalize use of color-cache" into 0.2.0
+c193331 extra size check for security
+906be65 rationalize use of color-cache
+dd1c387 Add image-hint for low-color images.
+4eb7aa6 Merge "WebPCheckMalloc() and WebPCheckCalloc():" into 0.2.0
+80cc730 WebPCheckMalloc() and WebPCheckCalloc():
+183cba8 check VP8LBitWriterInit return
+cbfa9ee lossless: fix crash on user abort
+256afef cwebp: exit immediately on version mismatch
+475d87d WebPEncode: clear stats at the start of encode
+a7cc729 fix type and conversion warnings
+7d853d7 add stats for lossless
+d39177b make QuantizeLevels() store the sum of squared error
+5955cf5 replace x*155/100 by x*101581>>16
+7d732f9 make QuantizeLevels() store the sum of squared error
+e45a446 replace x*155/100 by x*101581>>16
+159b75d cwebp output size consistency:
+cbee59e Merge commit 'v0.1.99'
+1889e9b dwebp: report -alpha option
+3bc3f7c Merge "dwebp: add PAM output support" into 0.2.0
+d919ed0 dwebp: add PAM output support
+85e215d README/manpages/configure: update website link
+c3a207b Update ChangeLog (tag: v0.1.99)
+d1fd782 Merge "add extra precision about default values and behaviour" into 0.2.0
+efc826e add extra precision about default values and behaviour
+9f29635 header/doc clean up
+ff9fd1b Makefile.vc: fix webpmux.exe *-dynamic builds
+8aacc7b remove INAM, ICOP, ... chunks from the test webp file.
+2fc1301 harmonize authors as "Name (mail at address)"
+4a9f37b Merge "update NEWS" into 0.2.0
+7415ae1 makefile.unix: provide examples/webpmux target
+ce82ced update NEWS
+641e28e Merge "man/cwebp.1: wording, change the date" into 0.2.0
+c37c23e README: cosmetics
+3976dcd man/cwebp.1: wording, change the date
+3e5bbe1 Merge "rename 'use_argb_input' to 'use_argb'" into 0.2.0
+ce90847 Merge "add some padding bytes areas for later use" into 0.2.0
+2390dab Merge "fixing the findings by Frederic Kayser to the bitstream spec" into 0.2.0
+0275159 add a very crude progress report for lossless
+a4b9b1c Remove some unused enum values.
+dd10817 rename 'use_argb_input' to 'use_argb'
+90516ae add some padding bytes areas for later use
+d03b250 fixing the findings by Frederic Kayser to the bitstream spec
+ce156af add missing ABI compatibility checks
+9d45416 Merge "Doc: container spec text tweaks" into 0.2.0
+4e2e0a8 Doc: container spec text tweaks
+f7f16a2 add ABI compatibility check
+2a77557 Merge "swig: add WebPEncodeLossless* wrappers" into 0.2.0
+a3ec622 mux.h: remove '* const' from function parameters
+31426eb encode.h: remove '* const' from function parameters
+9838e5d decode.h: remove '* const' from function parameters
+4972302 swig: add WebPEncodeLossless* wrappers
+9ff00ca bump encoder/decoder versions
+c2416c9 add lossless quick encoding functions to the public API
+4c1f5d6 Merge "NEWS: mention decode_vp8.h is no longer installed" into 0.2.0
+6cb2277 NEWS: mention decode_vp8.h is no longer installed
+d5e5ad6 move decode_vp8.h from webp/ to dec/
+8d3b04a Merge "header clean-up" into 0.2.0
+02201c3 Merge "remove one malloc() by making color_cache non dynamic" into 0.2.0
+d708ec1 Merge "move MIN/MAX_HISTO_BITS to format_constants.h" into 0.2.0
+ab2da3e Merge "add a malloc() check" into 0.2.0
+2d571bd add a malloc() check
+7f0c178 remove one malloc() by making color_cache non dynamic
+6569cd7 Merge "VP8LFillBitWindow: use 64-bit path for msvc x64 builds" into 0.2.0
+23d34f3 header clean-up
+2a3ab6f move MIN/MAX_HISTO_BITS to format_constants.h
+985d3da Merge "shuffle variables in HashChainFindCopy" into 0.2.0
+cdf885c shuffle variables in HashChainFindCopy
+c3b014d Android.mk: add missing lossless files
+8c1cc6b makefile.unix dist: explicitly name installed includes
+7f4647e Merge "clarify the colorspace naming and byte ordering of decoded samples" into 0.2.0
+cbf6972 clarify the colorspace naming and byte ordering of decoded samples
+857650c Mux: Add WebPDataInit() and remove WebPImageInfo
+ff771e7 don't install webp/decode_vp8.h
+596dff7 VP8LFillBitWindow: use 64-bit path for msvc x64 builds
+3ca7ce9 Merge "doc: remove non-finalized chunk references" into 0.2.0
+1efaa5a Merge "bump versions" into 0.2.0
+51fa13e Merge "README: update cwebp help output" into 0.2.0
+12f9aed README: update cwebp help output
+f0b5def bump versions
+4c42a61 update AUTHORS
+6431a1c doc: remove non-finalized chunk references
+8130c4c Merge "build: remove libwebpmux from default targets/config"
+23b4443 Merge "configure: broaden test for libpng-config"
+85bff2c Merge "doc: correct lossless prefix coding table & code"
+05108f6 Merge "More spec/code matching in mux:"
+6808e69 More spec/code matching in mux:
+bd2b46f Merge "doc/webp-container-spec: light cosmetics"
+20ead32 doc/webp-container-spec: light cosmetics
+1d40a8b configure: add pthread detection
+b5e9067 fix some int <-> size_t mix for buffer sizes
+e41a759 build: remove libwebpmux from default targets/config
+0fc2baa configure: broaden test for libpng-config
+45b8272 Merge "restore authorship to lossless bitstream doc"
+06ba059 restore authorship to lossless bitstream doc
+44a09a3 add missing description of the alpha filtering methods
+63db87d Merge "vwebp: add checkboard background for alpha display"
+a73b897 vwebp: add checkboard background for alpha display
+939158c Merge "vwebp: fix info display"
+b35c07d vwebp: fix info display
+48b39eb fix underflow for very short bitstreams
+7e62298 cosmetics: param alignment, manpage wording
+1bd7dd5 Merge changes I7b0afb0d,I7ecc9708
+ac69e63 Merge "Updated cwebp man's help for Alpha & Lossless."
+c0e8859 Get rid of image_info_ from WebPChunk struct.
+135ca69 WebP Container Spec:
+eb6f9b8 Updated cwebp man's help for Alpha & Lossless.
+0fa844f cosmetic fixes on assert and 'const' where applicable
+7f22bd2 check limit of width * height is 32 bits
+16c46e8 autoconf/make: cosmetics: break long lines
+ab22a07 configure: add helper macro to define --with-*
+c17699b configure: add libtiff test
+0e09732 Merge "cwebp: fix crash with yuv input + lossless"
+88a510f Merge "fix big-endian VP8LWriteBits"
+da99e3b Merge "Makefile.vc: split mux into separate lib"
+7bda392 cwebp: fix crash with yuv input + lossless
+f56a369 fix big-endian VP8LWriteBits
+54169d6 Merge "cwebp: name InputFileFormat members consistently"
+e2feefa Makefile.vc: split mux into separate lib
+27caa5a Merge "cwebp: add basic TIFF support"
+d8921dd cwebp: name InputFileFormat members consistently
+6f76d24 cwebp: add basic TIFF support
+4691407 Merge changes If39ab7f5,I3658b5ae
+cca7c7b Fixed nit: 10 -> 10.f
+5d09a24 WebPMuxCreate() error handling:
+777341c Fix a memleak in WebPMuxCreate()
+61c9d16 doc: correct lossless prefix coding table & code
+4c39757 Merge "mark VP8{,L}{GetInfo,CheckSignature} as WEBP_EXTERN"
+e4e36cc Merge "Mux: Allow only some frames/tiles to have alpha."
+ad2aad3 Merge "WebP Decoding error handling:"
+97649c8 Mux: Allow only some frames/tiles to have alpha.
+f864be3 Lower the quality settings for Alpha encoding.
+3ba81bb WebP Decoding error handling:
+fcc6992 add automatic YUVA/ARGB conversion during WebPEncode()
+802e012 fix compilation in non-FANCY_UPSAMPLING mode
+e012dfd make width/height coding match the spec
+228d96a mark VP8{,L}{GetInfo,CheckSignature} as WEBP_EXTERN
+637a314 remove the now unused *KeepA variants
+d11f6fc webpmux returns error strings rather than numbers
+fcec059 makefile.unix: cwebp: fix OSX link
+6b811f1 Merge "doc: remove lossless pdf"
+c963482 doc: remove lossless pdf
+b9ae4f0 cosmetics after mux changes b74ed6e, b494ad5
+b494ad5 Mux: only allow adding frame/tiles at the end.
+2c341b0 Merge "Added image characteristic hint for the codec."
+d373076 Added image characteristic hint for the codec.
+2ed2adb Merge "msvc: add intrinsic based BitsLog2Floor"
+e595e7c Merge "add demux.c to the makefiles"
+da47b5b Merge "demux: add {Next,Prev}Chunk"
+e5f4674 add demux.c to the makefiles
+4708393 demux: add {Next,Prev}Chunk
+e8a0a82 demux: quiet msvc warnings
+7f8472a Update the WebP Container Spec.
+31b68fe cleanup WebPPicture struct and API
+9144a18 add overflow check before calling malloc()
+81720c9 consistency cosmetics
+2ebe839 Merge "Add kramdown version information to README"
+7144308 enc/vp8l.c: fix build
+b7ac19f Add kramdown version information to README
+efdcb66 Merge "Edit for consistency, usage and grammar."
+0822010 Enable alpha in vvwebp
+8de9a08 Merge "Mux API change:"
+b74ed6e Mux API change:
+233a589 take picture->argb_stride into account for lossless coding
+04e33f1 Edit for consistency, usage and grammar.
+a575b4b Merge "cosmetics: add missing const"
+8d99b0f Merge "cosmetics: remove unimplemented function proto"
+69d0221 cosmetics: add missing const
+5b08318 cosmetics: remove unimplemented function proto
+b7fb0ed Log warning for unsupported options for lossless.
+e1f769f msvc: add intrinsic based BitsLog2Floor
+8a69c7d Bug-fix: Clamp backward dist to 1.
+b5b6ac9 Merge "Bring the special writer 'WebPMemoryWriter' to public API"
+a6a1909 Merge "Fix floating point exception with cwebp -progress"
+f2cee06 Fix floating point exception with cwebp -progress
+91b7a8c Bring the special writer 'WebPMemoryWriter' to public API
+310e297 support resize and crop for RGBA input
+a89835d Merge changes Ice662960,Ie8d7aa90,I2d996d5e,I01c04772
+ce614c0 Merge "dec/vp8: avoid setting decoder status twice"
+900285d dec/vp8: avoid setting decoder status twice
+8227adc Merge changes I6f02b0d0,I5cbc9c0a,I9dd9d4ed,Id684d2a1
+dcda59c Merge "demux: rename SetTile to SelectTile"
+622ef12 demux: rename SetTile to SelectTile
+81ebd37 Merge "demux: add {Next,Prev}Frame"
+02dd37a demux: add {Next,Prev}Frame
+4b79fa5 Merge "Limit the maximum size of huffman Image to 16MB."
+9aa34b3 Manually number "chapters," as chapter numbers are used in the narrative.
+2a4c6c2 Re-wrap at <= 72 columns
+a45adc1 Apply inline emphasis and monospacing, per gdoc / PDF
+9101120 Incorporate gdoc changes through 2012-06-08
+7a18248 Removed CodeRay syntax declarations ...
+b3ec18c Provide for code-block syntax highlighting.
+709d770 Replace high ASCII artifacts (curly quotes, etc.).
+930e8ab Lossless WebP doc largely ported to markdown text.
+18cae37 msvc: silence some build warnings
+b392308 Limit the maximum size of huffman Image to 16MB.
+f180df2 Merge "libwebp/demux: add Frame/Chunk iteration"
+2bbe1c9 Merge "Enable lossless encoder code"
+d0601b0 Merge changes I1d97a633,I81c59093
+78f3e34 Enable lossless encoder code
+d974a9c Merge "libwebp/demux: add simple format parsing"
+26bf223 Merge "libwebp: add WebPDemux stub functions"
+2f66668 Merge "modify WebPParseHeaders to allow reuse by GetFeatures"
+b402b1f libwebp/demux: add Frame/Chunk iteration
+ad9ada3 libwebp/demux: add WebPDemuxGetI
+2f2d4d5 libwebp/demux: add extended format parsing
+962dcef libwebp/demux: add simple format parsing
+f8f9408 libwebp: add WebPDemux stub functions
+fb47bb5 Merge "NumNamedElements() should take an enum param."
+7c68980 Fix asserts in Palette and BackwardReference code.
+fbdcb7e NumNamedElements() should take an enum param.
+fb4943b modify WebPParseHeaders to allow reuse by GetFeatures
+3697b5c write an ad-hoc EncodeImageInternal variant
+eaee9e7 Bug-Fix: Decode small (less than 32 bytes) images.
+0bceae4 Merge "cwebp: fix alpha reporting in stats output"
+0424b1e Rebase default encoding settings.
+c71ff9e cwebp: fix alpha reporting in stats output
+e2ffe44 Merge "Stop indefinite recursion for Huffman Image."
+70eb2bd Stop indefinite recursion for Huffman Image.
+f3bab8e Update vwebp
+6d5c797 Remove support for partial files in Mux.
+f1df558 WebPMuxAssemble() returns WebPData*.
+814a063 Rename 'Add' APIs to 'Set'.
+bbb0218 Update Mux psuedo-code examples.
+4fc4a47 Use WebPData in MUX set APIs
+c67bc97 Merge "add WebPPictureImportRGBX() and WebPPictureImportBGRX()"
+27519bc add WebPPictureImportRGBX() and WebPPictureImportBGRX()
+f80cd27 factorize code in Import()
+9b71502 histogram: add log2 wrapper
+8c34378 Merge "fix some implicit type conversion warnings"
+42f6df9 fix some implicit type conversion warnings
+250c16e Merge "doc: update lossless pdf"
+9d9daba Merge "add a PDF of the lossless spec"
+8fbb918 prefer webp/types.h over stdint.h
+0ca170c doc: update lossless pdf
+0862ac6 add a PDF of the lossless spec
+437999f introduce a generic WebPPictureHasTransparency() function
+d2b6c6c cosmetic fixes after Idaba281a
+b4e6645 Merge "add colorspace for premultiplied alpha"
+48f8275 add colorspace for premultiplied alpha
+069f903 Change in lossless bit-stream.
+5f7bb3f Merge "WebPReportProgress: use non-encoder specific params"
+f18281f WebPReportProgress: use non-encoder specific params
+9ef3228 Add support for raw lossless bitstream in decoder.
+7cbee29 Fix bug: InitIo reseting fancy_upsampling flag.
+880fd98 vwebp: fix exit w/freeglut
+1875d92 trap two unchecked error conditions
+87b4a90 no need to have mux.h as noinst clause in enc/
+88f41ec doc: fix bit alignment in VP8X chunk
+52f5a4e Merge "fix bug with lossy-alpha output stride"
+3bde22d fix bug with lossy-alpha output stride
+42d61b6 update the spec for the lossy-alpha compression methods.
+e75dc80 Move some more defines to format_constants.h
+c13f663 Move consts to internal header format_constants.h
+7f2dfc9 use a bit-set transforms_seen_ instead of looping
+18da1f5 modulate alpha-compression effort according to config.method
+f5f2fff Merge "Alpha flag fix for lossless."
+c975c44 Alpha flag fix for lossless.
+4f067fb Merge "Android: only build dec_neon with NEON support"
+255c66b Android: only build dec_neon with NEON support
+8f9117a cosmetics: signature fixes
+39bf5d6 use header-less lossless bitstream for alpha channel
+75d7f3b Merge "make input data be 'const' for VP8LInverseTransform()"
+9a721c6 make input data be 'const' for VP8LInverseTransform()
+9fc64ed Disallow re-use of same transformation.
+98ec717  use a function pointer for ProcessRows()
+f7ae5e3 cosmetics: join line
+140b89a factor out buffer alloc in AllocateARGBBuffers()
+a107dfa Rectify WebPParseOptionalChunks().
+237eab6 Add two more color-spaces for lossless decoding.
+27f417a fix orthographic typo
+489ec33 add VP8LEncodeStream() to compress lossless image stream
+fa8bc3d make WebPEncodingSetError() take a const picture
+638528c bitstream update for lossy alpha compression
+d73e63a add DequantizeLevels() placeholder
+ec122e0 remove arch-dependent rand()
+d40e765 fix alignment
+1dd6a8b Merge "remove tcoder, switch alpha-plane compression to lossless"
+3e863dd remove tcoder, switch alpha-plane compression to lossless
+8d77dc2 Add support for lossless in mux:
+831bd13 Make tile size a function of encoding method.
+778c522 Merge "remove some variable shadowing"
+817c9dc Few more HuffmanTreeToken conversions.
+37a77a6 remove some variable shadowing
+89c07c9 Merge "normalize example header includes"
+4aff411 Merge "add example_util.[hc]"
+00b29e2 normalize example header includes
+061263a add example_util.[hc]
+c6882c4 merge all tree processing into a single VP8LProcessTree()
+9c7a3cf fix VP8LHistogramNumCodes to handle the case palette_code_bits == 0
+b5551d2 Merge "Added HuffmanTreeCode Struct for tree codes."
+8b85d01 Added HuffmanTreeCode Struct for tree codes.
+093f76d Merge "Allocate single memory in GetHuffBitLengthsAndCodes."
+41d8049 Allocate single memory in GetHuffBitLengthsAndCodes.
+1b04f6d Correct size in VP8L header.
+2924a5a Makefile.vc: split object lists based on directory
+c8f2416 Merge "add assert(tokens)"
+4323994 add assert(tokens)
+9f54745 Catch an error in DecodeImageData().
+ac8e5e4 minor typo and style fix
+9f566d1 clean-up around Huffman-encode
+c579a71 Introduce CHUNK_SIZE_BYTES in muxi.h.
+14757f8 Make sure huffman trees always have valid symbols
+4105061 makefile.unix: add support for building vwebp
+48b3772 Merge "fixed signed/unsigned comparison warning"
+57f696d Merge "EncodeImageInternal: fix potential leak"
+d972cdf EncodeImageInternal: fix potential leak
+5cd12c3 fixed signed/unsigned comparison warning
+cdca30d Merge "cosmetics: shorten long line"
+e025fb5 cosmetics: shorten long line
+22671ed Merge "enc/vp8l: fix double free on error"
+e1b9b05 Merge "cosmetics: VP8LCreateHuffmanTree: fix indent"
+a8e725f enc/vp8l: fix double free on error
+27541fb cosmetics: VP8LCreateHuffmanTree: fix indent
+1d38b25 cwebp/windows: use MAKE_REFGUID where appropriate
+817ef6e Merge "cwebp: fix WIC/Microsoft SDK compatibility issue"
+902d3e3 cwebp: fix WIC/Microsoft SDK compatibility issue
+89d803c Merge "Fix a crash due to wrong pointer-integer arithmetic."
+cb1bd74 Merge "Fix a crash in lossless decoder."
+de2fe20 Merge "Some cleanup in VP8LCreateHuffmanTree() (and related functions CompareHuffmanTrees() and SetBitDepths()): - Move 'tree_size' initialization and malloc for 'tree + tree_pool'   outside the loop. - Some renames/tweaks for readability."
+ce69177 Fix a crash due to wrong pointer-integer arithmetic.
+e40a368 Fix a crash in lossless decoder.
+3927ff3 remove unneeded error condition for WebPMuxNumNamedElements()
+2c140e1 Some cleanup in VP8LCreateHuffmanTree() (and related functions CompareHuffmanTrees() and SetBitDepths()): - Move 'tree_size' initialization and malloc for 'tree + tree_pool'   outside the loop. - Some renames/tweaks for readability.
+861a5b7 add support for animation
+eb5c16c Merge "Set correct encode size in encoder's stats."
+4abe04a fix the return value and handle missing input file case.
+2fafb85 Set correct encode size in encoder's stats.
+e7167a2 Provide one entry point for backward references.
+c4ccab6 Print relevant lossless encoding stats in cwebp.
+e3302cf GetHuffBitLengthsAndCodes: reduce level of indirection
+b5f2a9e enc/vp8l: fix uninitialized variable warning
+7885f8b makefile.unix: add lossless encoder files
+1261a4c Merge "cosmetics"
+3926b5b Merge "dsp/cpu.c: Android: fix crash on non-neon arm builds"
+834f937 dsp/cpu.c: Android: fix crash on non-neon arm builds
+126e160 cosmetics
+e38602d Merge branch 'lossless_encoder'
+e8d3d6a split StoreHuffmanCode() into smaller functions
+d0d8899 more consolidation: introduce VP8LHistogramSet
+1a210ef big code clean-up and refactoring and optimization
+41b5c8f Some cosmetics in histogram.c
+ada6ff7 Approximate FastLog between value range [256, 8192]
+ec123ca Forgot to update out_bit_costs to symbol_bit_costs at one instance.
+cf33ccd Evaluate output cluster's bit_costs once in HistogramRefine.
+781c01f Simple Huffman code changes.
+a2849bc Lossless decoder: remove an unneeded param in ReadHuffmanCodeLengths().
+b39e748 Reducing emerging palette size from 11 to 9 bits.
+bfc73db Move GetHistImageSymbols to histogram.c
+889a578 Improve predict vs no-predict heuristic.
+01f5066 code-moving and clean-up
+31035f3 reduce memory usage by allocating only one histo
+fbb501b Restrict histo_bits to ensure histo_image size is under 32MB
+8415ddf further simplification for the meta-Huffman coding
+e491729 A quick pass of cleanup in backward reference code
+83332b3 Make transform bits a function of encode method (-m).
+72920ca introduce -lossless option, protected by USE_LOSSLESS_ENCODER
+c6ac4df Run TraceBackwards for higher qualities.
+412222c Make histo_bits and transform_bits function of quality.
+149b509 Update lossless encoder strategy:
+0e6fa06 cache_bits passed to EncodeImageInternal()
+e38b40a Factorize code for clearing HtreeGroup.
+6f4a16e Removing the indirection of meta-huffman tables.
+3d33ecd Some renaming/comments related to palette in lossless encoder.
+4d02d58 Lossless encoder: correction in Palette storage
+4a63623 fix a memleak in EncodeImageInternal()
+0993a61 Full and final fix for prediction transform
+afd2102 Fix cross-color transform in lossless encoder
+b96d874 Need to write a '0' bit at the end of transforms.
+54dad7e Color cache size should be counted as 0 when cache bits = 0
+4f0c5ca Fix prediction transform in lossless encoder.
+36dabda Fix memory leak in method EncodeImageInternal for histogram_image.
+352a4f4 Get rid of PackLiteralBitLengths()
+d673b6b Change the predictor function to pass left pixel
+b2f9946 Fix CopyTileWithPrediction()
+84547f5 Add EncodeImageInternal() method.
+6b38378 Guard the lossless encoder (in flux) under a flag
+09f7532 Fix few nits (const qualifiers)
+648be39 Added implementation for various lossless functions
+32714ce Add VP8L prefix to backward ref & histogram methods.
+fcba7be Fixed header file tag (WEBP_UTILS_HUFFMAN_ENCODE_H_)
+bc70374 Add backward_ref, histogram & huffman encode modules from lossless.
+fdccaad Fixing nits
+227110c libwebp interface changes for lossless encoding.
+50679ac minor style fixes
+b38dfcc remove unneeded reference to NUM_LITERAL_CODES
+8979675 harmonize header description
+c04eb7b tcoder.c: define NOT_HAVE_LOG2 for MSVC builds
+9a214fa Merge "VP8[L]GetInfo: check input pointers"
+5c5be8b VP8[L]GetInfo: check input pointers
+0c188fe Merge changes I431acdfe,I713659b7
+b3515c6 mux: drop 'chunk' from ChunkInfo member names
+aea7923 muxi.h: remove some unused defines
+0142249 update NEWS file for next release
+29e3f7e Merge "dec: remove deprecated WebPINew()"
+4718e44 Merge "muxedit: a few more size_t changes"
+82654f9 Merge "muxedit: remove a few redundant NULL checks"
+02f27fb dec: remove deprecated WebPINew()
+ccddb3f muxedit: remove a few redundant NULL checks
+a6cdf71 muxedit: a few more size_t changes
+a384689 Merge "mux: remove unused LIST_ID"
+11ae46a alpha.c: quiet some size_t -> int conversion warnings
+dee4669 mux: remove unused LIST_ID
+03f1f49 mux: add version checked entry points
+6a0abda Merge "doc: tile/alpha corrections"
+c8139fb Merge "few cosmetics"
+6833873 Merge "lossless: remove some size_t -> int conversions"
+5249e94 doc: tile/alpha corrections
+d96e722 huffman: quiet int64 -> int conversion warning
+532020f lossless: remove some size_t -> int conversions
+23be6ed few cosmetics
+1349eda Merge "configure: AC_ARG_* use AS_HELP_STRING"
+bfbcc60 configure: AC_ARG_* use AS_HELP_STRING
+1427ca8 Merge "Makefile.am: header file maintenance"
+087332e Merge "remove unused parameter 'round' from CalcProba()"
+9630e16 remove unused parameter 'round' from CalcProba()
+92092ea Merge "bit_reader.h: correct include"
+a87fc3f Merge "mux: ensure # images = # tiles"
+53af99b Merge "mux: use size_t consistently"
+39a57da Makefile.am: header file maintenance
+1bd0bd0 bit_reader.h: correct include
+326a3c6 mux: ensure # images = # tiles
+95667b8 mux: use size_t consistently
+231ec1f Removing the indirection of meta-huffman tables.
+15ebcba check return pointer from MuxImageGetListFromId
+b0d6c4a Merge "configure: remove test for zlib.h"
+8cccac5 Merge "dsp/lossless: silence some build warnings"
+b08819a dsp/lossless: silence some build warnings
+7ae2252 Android.mk: SSE2 & NEON updates
+0a49e3f Merge "makefile.unix add missing header files"
+2e75a9a Merge "decode.h: use size_t consistently"
+fa13035 configure: remove test for zlib.h
+d3adc81 makefile.unix add missing header files
+262fe01 Merge "makefile.unix & Android.mk: cosmetics"
+4cce137 Merge "enc_sse2 add missing stdlib.h include"
+80256b8 enc_sse2 add missing stdlib.h include
+9b3d1f3 decode.h: use size_t consistently
+64083d3 Merge "Makefile.am: cosmetics"
+dceb8b4 Merge changes If1331d3c,I86fe3847
+0e33d7b Merge "webp/decode.h: fix prototypes"
+fac0f12 rename BitReader to VP8LBitReader
+fbd82b5 types.h: centralize use of stddef.h
+2154835 Makefile.am: cosmetics
+1c92bd3 vp8io: use size_t for buffer size
+90ead71 fix some more uint32_t -> size_t typing
+cbe705c webp/decode.h: fix prototypes
+3f8ec1c makefile.unix & Android.mk: cosmetics
+217ec7f Remove tabs in configure.ac
+b3d35fc Merge "Android.mk & Makefile.vc: add new files"
+0df04b9 Android.mk & Makefile.vc: add new files
+e4f20c5 Merge "automake: replace 'silent-rules' w/AM_SILENT_RULES"
+8d254a0 cosmetics
+6860c2e fix some uint32_t -> size_t typing
+4af1858 Fix a crash due to max symbol in a tree >= alphabet size
+6f01b83 split the VP8 and VP8L decoding properly
+f2623db enable lossless decoder
+b96efd7 add dec/vp8i.h changes from experimental
+19f6398 add dec/vp8l{i.h,.c} from experimental
+c4ae53c add utils/bit_reader.[hc] changes from experimental
+514d008 add dsp/lossless.[hc] from experimental
+9c67291 add utils/huffman.[hc] from experimental
+337914a add utils/color_cache.[hc] from experimental
+b3bf8fe the read-overflow code-path wasn't reporting as an error
+1db888b take colorspace into account when cropping
+61c2d51 move the rescaling code into its own file and make enc/ and dec/ use it.
+efc2016 Make rescaler methods generic
+3eacee8 Move rescaler methods out of io.c.
+a69b893 automake: replace 'silent-rules' w/AM_SILENT_RULES
+6f7bf64 issue 111: fix little-endian problem in bit-reader
+ed278e2 Removed unnecessary lookup
+cd8c3ba fix some warnings: down-cast and possibly-uninitialized variable
+0a7102b ~1% improvement of alpha compression
+3bc1b14 Merge "Reformat container doc"
+dc17abd mux: cosmetics
+cb5810d Merge "WebPMuxGetImage: allow image param to be NULL"
+506a4af mux: cosmetics
+135e8b1 WebPMuxGetImage: allow image param to be NULL
+de556b6 Merge "README.mux: reword some descriptions"
+0ee2aeb Makefile.vc: use batch mode rules
+d9acddc msvc: move {i,p}db creation to object directory
+237c9aa Merge "expose WebPFree function for DLL builds"
+b3e4054 silence msvc debug build warning
+45feb55 expose WebPFree function for DLL builds
+11316d8 README.mux: reword some descriptions
+4be52f4 factorize WebPMuxValidate
+14f6b9f mux: light cleanup
+5e96a5d add more param checks to WebPPictureDistortion()
+8abaf82 Merge "silence some type size related warnings"
+1601a39 silence some type size related warnings
+f3abe52 Merge "idec: simplify buffer size calculation"
+a9c5cd4 idec: simplify buffer size calculation
+7b06bd7 Merge "configure/automake: add silent-rules option"
+e9a7d14 Reformat container doc
+d4e5c7f configure/automake: add silent-rules option
+5081db7 configure/automake: no -version-info for convenience libs
+85b6ff6 Merge "idec: fix WebPIUpdate failure"
+7bb6a9c idec: fix internal state corruption
+89cd1bb idec: fix WebPIUpdate failure
+01b6380 4-5% faster decoding, optimized byte loads in arithmetic decoder.
+631117e Merge "cosmetics & warnings"
+a0b2736 cosmetics & warnings
+f73947f use 32bit for storing dequant coeffs, instead of 16b.
+b960030 Merge "store prediction mode array as uint8_t[16], not int[16]."
+7b67881 store prediction mode array as uint8_t[16], not int[16].
+cab8d4d Merge "NEON TransformOne"
+ba503fd NEON TransformOne
+9f740e3 Merge "gcc warning fix: remove the 'const' qualifier."
+f76d358 gcc warning fix: remove the 'const' qualifier.
+e78478d Merge "webpmux: make more use of WebPData"
+f85bba3 Merge "manpages: add BUGS section"
+48a43bb Merge "makefile.unix: variable cosmetics"
+c274dc9 makefile.unix: variable cosmetics
+1f7b859 re-organize the error-handling in the main loop a bit
+1336fa7 Only recompute level_cost_[] when needed
+771ee44 manpages: add BUGS section
+0f7820e webpmux: make more use of WebPData
+974aaff examples: logging updates
+6c14aad Merge "better token buffer code"
+f405425 better token buffer code
+18d959f Merge "mux: add WebPData type"
+eec4b87 mux: add WebPData type
+0de3096 use 16bit counters for recording proba counts
+7f23678 fix for LevelCost + little speed-up
+7107d54 further speed-up/cleanup of RecordCoeffs() and GetResidualCost()
+fd22104 Introduce Token buffer (unused for now)
+5fa148f Merge "speed-up GetResidualCost()"
+28a9d9b speed-up GetResidualCost()
+11e7dad Merge "misc cosmetics"
+378086b misc cosmetics
+d61479f add -print_psnr and -print_ssim options to cwebp.
+2e3e8b2 add a WebPCleanupTransparentArea() method
+552c121 Merge "mux: plug some memory leaks on error"
+a2a81f7 Merge "fix Mach-O shared library build"
+b3482c4 Merge "fix gcc-4.0 apple 32-bit build"
+e4e3ec1 fix gcc-4.0 apple 32-bit build
+b0d2fec mux: plug some memory leaks on error
+f0d2c7a pass of cosmetics
+b309a6f fix Mach-O shared library build
+241ddd3 doc: delete mux container pdf
+8b1ba27 doc: update VP8 decode guide link
+7e4371c WebPMuxCreate: fix unchecked malloc
+eb42558 Merge "have makefile.unix clean up src/webp/*~ too"
+a85c363 Merge "correct EncodeAlpha documentation"
+a33842f Merge "Update webp container spec with alpha filter options."
+8d6490d Incremental support for some of the mux APIs.
+b8375ab have makefile.unix clean up src/webp/*~ too
+b5855fc correct EncodeAlpha documentation
+dba37fe Update webp container spec with alpha filter options.
+2e74ec8 fix compile under MINGW
+716d1d7 fix suboptimal MAX_LEN cut-off limit
+57cab7b Harmonize the alpha-filter predictions at boundary
+3a98953 Merge "Fix bug for Alpha in RGBA_4444 color-mode."
+8ca2076 Introduce a 'fast' alpha mode
+221a06b Fix bug for Alpha in RGBA_4444 color-mode.
+ad1e163 cosmetics: normalize copyright headers
+c77424d cosmetics: light include cleanup
+9d0e17c fix msvc build breakage after 252028a
+7c4c177 Some readability fixes for mux library
+d8a47e6 Merge "Add predictive filtering option for Alpha."
+252028a Add predictive filtering option for Alpha.
+9b69be1 Merge "Simplify mux library code"
+a056170 Simplify mux library code
+992187a improve log2 test
+e852f83 update Android.mk file list
+a90cb2b reduce number of copies and mallocs in alpha plane enc/dec
+b1662b0 fix some more type conversion warnings w/MSVC
+223d8c6 fix some uint64_t -> int conversion warnings with MSC
+c1a0437 Merge "simplify checks for enabling SSE2 code"
+f06817a simplify checks for enabling SSE2 code
+948d4fe silence a msvc build warning
+9117954 vwebp: msvc build tweaks
+7937b40 simple WebP viewer, based on OpenGL
+6aac1df add a bunch of missing 'extern "C"'
+421eb99 Merge "Remove assigned-but-not-used variable "br""
+91e27f4 better fitting names for upsampling functions
+a5d7ed5 Remove assigned-but-not-used variable "br"
+f62d2c9 remove unused 'has_alpha' from VP8GetInfo() signature
+08e8658 trap alpha-decoding error
+b361eca add cut-off to arith coder probability update.
+8666a93 Some bug-fixes for images with alpha.
+273a12a fix off-by-1 diff in case cropping and simple filtering
+2f741d1 webpmux: ReadImage: fix ptr free in error case
+721f3f4 fix alpha decode
+60942c8 fix the has_alpha_ order
+30971c9 Implement progress report (and user abort)
+eda520a cosmetics after 9523f2a
+38bd5bb Merge "Better alpha support in webpmux binary"
+ccbaebf Merge "Updated the includes to relative paths."
+d71fbdc fix small typo in error message array
+cdf97aa Better alpha support in webpmux binary
+885f25b Updated the includes to relative paths.
+a0ec9aa Update WebP encoder (cwebp) to support Alpha.
+667b769 Fixed the include for types.h within mux.h
+9523f2a Add Alpha Encode support from WebPEncode.
+16612dd Merge "Add Alpha Decode support from WebPDecode."
+d117a94 Add Alpha Decode support from WebPDecode.
+6722873 cosmetics after e1947a9
+e1947a9 Add Alpha encode/decode code.
+afc4c5d simplify code by introducing a CopyPlane() helper func
+113b312 Merge "MUX API Updates"
+c398f59 MUX API Updates
+5acf04e remove orphan source file
+059f03e Merge "dec: validate colorspace before using as array index"
+70a0398 Merge "factorize some code"
+9b243b3 factorize some code
+372e2b4 Correct a bug in ReadPNG() with GRAY_ALPHA images
+469d6eb Merge "Makefile.am: remove redundant noinst_HEADERS"
+9fe3372 dec: validate colorspace before using as array index
+8962030 remove orphan source file
+ced3e3f Makefile.am: remove redundant noinst_HEADERS
+964387e use WEBP_INLINE for inline function declarations
+90880a1 Merge "manpages: break long lines"
+b591089 Merge "manpages: minor formatting updates"
+4c451e4 Merge "Rectify the Chunk parsing logic."
+04e84cf examples: slight cleanup
+099717c manpages: break long lines
+1daf39b manpages: minor formatting updates
+abd030b fix missing "(void)" in function signature
+f6a7d75 remove useless test
+f07b213 Rectify the Chunk parsing logic.
+b8634f7 webpmux: fix lib link order
+42c2e68 Fix missing coma (on uncompiled code)
+d8329d4 Android.mk: add missing source files
+13a54df Merge "More aggressive copy-edit; add TODO; validate HTML5"
+868b96a More aggressive copy-edit; add TODO; validate HTML5
+767afea configure: check for a symbol contained in libpng
+408b891 Merge "Linewrap at 72 cols. Casual copy-edit."
+3ae318c Merge "Restore (most) emphasis; add emphasis to normative RFC 2119 terms (MUST, etc.)"
+918eb2d Merge "Basic container doc source clean-up; fix lists and pseudocode blocks."
+03bec9e Linewrap at 72 cols. Casual copy-edit.
+2678d81 Restore (most) emphasis; add emphasis to normative RFC 2119 terms (MUST, etc.)
+428674d Basic container doc source clean-up; fix lists and pseudocode blocks.
+6a77d92 Merge "Makefile.vc: cosmetics"
+28c38e8 Merge "Makefile.vc: condense directory creation rules"
+55be2cf Initial import of container spec document, from pdftotext transform.
+a82a788 Makefile.vc: cosmetics
+c8f41ce Makefile.vc: condense directory creation rules
+2b877cd Some fixes to Makefile.vc to support the src\mux directory.
+3eb969b Merge "Add Makefile.vc for Mux library & binary."
+e78e971 Add Makefile.vc for Mux library & binary.
+6aedde5 Add manual for WebPMux tool.
+8a360d0 Merge "Added WebPMux Binary."
+a4f32ca Added WebPMux Binary.
+f3bf4c7 Added Mux Container Spec & README for MUX-API.
+9f761cf Changed function signature for WebPMuxCreate
+5f31b5e Merge "Add Mux library for manipulating WebP container."
+2315785 Add Mux library for manipulating WebP container.
+7e198ab update ChangeLog (tag: v0.1.3)
+dfc9c1e Harmonize the dates
+28ad70c Fix PNG decoding bug
+846e93c Update AUTHORS & add .mailmap
+563e52d cosmetics after '76036f5 Refactor decoder library'
+76036f5 Refactor decoder library
+377ef43 configure.ac: update AC_INIT params
+7a8d876 use a user-visible MACRO for max width/height.
+d4e9f55 NEON decode support in WebP
+0ee683b update libtool version-info
+fdbe02c windows: match _cond_destroy logic w/return variable name
+206b686 README: correct advanced decode api pseudo-code
+6a32a0f make VP8BitReader a typedef, for better re-use
+b112e83 create a libwebputils under src/utils
+ee697d9 harmonize the include guards and #endif comments
+a1ec07a Fixing compiler error in non x86 arch.
+dcfa509 Fixed recursive inclusion of bit_writer.h and vp8enci.h.
+e06ac08 create a separate libwebpdsp under src/dsp
+ebeb412 use unsigned int for bitfields
+341cc56 make kNewRange a static array
+227a91e README: minor wording update
+05bd8e6 add man pages to dist
+812dfa1 bump up versions in preparations for 0.1.3
+a5b78c8 wrap alpha-related options under WEBP_EXPERIMENTAL_FEATURES flag
+34dc790 regen ChangeLog for 0.1.3-rc2
+7c43663 Silence some (more) Visual Studio warnings.
+60306e8 add top-level gitattributes
+2aa6b80 Slience some Visual Studio warnings.
+4cbbb29 Merge "bump up version for next freeze"
+a329167 bump up version for next freeze
+c7e86ab cosmetics: fix comment line lengths
+c9e037a makefile.unix: add simple dist target
+87d58ce makefile.unix: rule maintenance
+d477de7 mend
+fac15ec Update NEWS & README for next release V0.1.3
+6215595 Merge "add a -partition_limit option to limit the number of bits used by intra4x4"
+3814b76 Merge "reorganize chunk-parsing code"
+900286e add a -partition_limit option to limit the number of bits used by intra4x4
+cd12b4b add the missing cost for I4/I16 mode selection
+dfcc213 reorganize chunk-parsing code
+3cf2030 initialize pointers to function within VP8DspInit()
+d21b479 Merge "windows: add decode threading support"
+473ae95 fix hang on thread creation failure
+fccca42 windows: add decode threading support
+a31f843 Use the exact PNG_INCLUDES/PNG_LIBS when testing for -lpng
+ad9b45f Merge "Makefile.vc: rule maintenance"
+565a2ca Makefile.vc: rule maintenance
+2d0da68 makefile.unix: disable Wvla by default
+fc7815d multi-thread decoding: ~25-30% faster
+acd8ba4 io->teardown() was not always called upon error
+c85527b Merge "Makefile.vc: add DLL configs"
+e1e9be3 cosmetics: spelling/grammar in README and lib headers
+b4d0ef8 Makefile.vc: add DLL configs
+998754a remove unused nb_i4_ and nb_i16_ fields.
+9f01ce3 rename WebPDecBuffer::memory -> private_memory
+fb5d659 fix an overflow bug in LUT calculation
+d646d5c swig: add WebPDecodeARGB
+78aeed4 add missing WebPDecodeARGBInto() and switch ARGB4444 to RGBA4444 as was intended
+cd7c529 explicitly mark library functions as extern
+19db59f add support for RGB565, ARGB4444 and ARGB colorspace (decoder)
+c915fb2 encoder speed-up: hardcode special level values
+c558bda Rename and improve the API to retrieve decoded area
+bf599d7 Merge "makefile.unix: disable -Wvla by default"
+c9ea03d SSE2 version of strong filtering
+993af3e makefile.unix: disable -Wvla by default
+3827e1b Merge "examples: (windows/WIC) add alpha support"
+e291fae SSE2 functions for the fancy upsampler.
+a06bbe2 add WebPISetIOHooks() to set some custom hooks on the incremental decoder object.
+7643a6f Merge "makefile.unix: use uname to detect OSX environment"
+5142a0b export alpha channel (if present) when dumping to PGM format
+14d5731 makefile.unix: use uname to detect OSX environment
+0805706 examples: quiet warnings
+3cfe088 examples: (windows/WIC) add alpha support
+13ed94b add compile warning for variable-length-array
+5a18eb1 Merge "add Advanced Decoding Interface"
+5c4f27f add missing \n
+f4c4e41 80 cols fix
+d260310 add Advanced Decoding Interface
+bd2f65f sse2 version of the complex filter
+96ed9ce perform two idct transforms at a time when possible
+01af7b6 use aligned stored
+0e1d1fd Merge "Makefile.vc: add experimental target"
+2a1292a Makefile.vc: add experimental target
+23bf351 Enable decode SSE2 for Visual Studio
+131a4b7 dec/dsp_sse2: fix visual studio compile
+00d9d68 swig: file reorganization
+7fc7e0d Merge "swig/java: basic encode support"
+3be57b1 fix MSVC compile for WEBP_EXPERIMENTAL_FEATURES
+40a7e34 dec/dsp: disable sse2 for Visual Studio builds
+e4d540c add SSE2 code for transform
+54f2170 swig/java: basic encode support
+c5d4584 call function pointers instead of C-version
+ea43f04 Merge "configure: mingw32 targets: test for WIC support"
+a11009d SSE2 version of simple in-loop filtering
+42548da shave one unneeded filter-cache line
+31f9dc6 configure: mingw32 targets: test for WIC support
+1955969 Merge "split expression in two."
+415dbe4 split expression in two.
+e29072a configure: test for zlib only w/--enable-experimental
+b2b0090 Simplify Visual Studio ifdefs
+ca7a2fd Add error reporting from encoding failures.
+6c9405d Merge "Makefile.vc: require CFG with clean target"
+0424ecd Makefile.vc: require CFG with clean target
+003417c Enable SSE2 for Visual Studio builds
+af10db4 little speed up for VP8BitUpdate()
+e71418f more MSVC files to ignore
+46d9036 cosmetics
+edf59ab typo fix
+72229f5 Add support for x64 and SSE2 builds under Windows.
+92e5c6e VP8GetInfo() + WebPResetDecParams()
+416b7a6 raise the fixed-point precision for the rescaler
+aa87e4e fix alignment
+eb66670 disable WEBP_EXPERIMENTAL_FEATURES
+c5ae7f6 typo fix: USE_ => WEBP_
+d041efa swig: add libwebp.jar/libwebp_java_wrap.c
+f6fb387 add swig interface
+e927390 align buffer for double too
+842c009 fix -strong option
+d0a7038 Merge "cosmetics"
+fc0a02e fix the dichotomy loop
+38369c0 cosmetics
+8dfc4c6 factorize and unify GetAlpha() between the C and SSE2 version
+6d0e66c prepare experimentation with yuv444 / 422
+79cc49f add a --enable-experimental option to './configure'
+d757523 sse2 version of CollectHistogram()
+c1c728d add an extra #ifdef WEBP_EXPERIMENTAL_FEATURES to avoid 'unused variable' warning
+60c61d2 always call VP*EncDeleteAlpha() unconditionnally, for simplicity
+0f8c638 simply don't call WriteExtensions() if WEBP_EXPERIMENTAL_FEATURES is not defined
+47c661d rename swap -> swap_rb
+10d55bb move chunk[] declaration out of the for() loop
+517cec2 fix indentation
+f7d9e26 fix merge problems
+8fd42b3 add a stride 'a_stride' for the alpha plane
+b8dcbf2 fix alpha-plane copy and crop methods
+cdef89d fix some 'unused variable' warning
+fb29c26 SSE2 version of the fwd transform and the squared sum metric
+2ab4b72 EXPERIMENTAL: add support for alpha channel
+cfbf88a add SSE2 functions. ~2x faster encoding on average.
+e7ff3f9 merge two ITransforms together when applicable and change the TTransform to return the sum directly.
+ca55413 fix WebPIDecGetRGB() to accept any RGB(A) mode, not just MODE_RGB
+8aa50ef fix some 'man' typos
+d3f3bdd update ChangeLog (tag: v0.1.2)
+d7e9a69 update contributor list
+261abb8 add a 'superclean' section
+276ae82 Remove files not mean to be in git, and update .gitignore
+2486845 build: prepare libwebp.pc
+14ceb6e add "-version" description to man pages
+b247a3b Create the m4 directory, and also place .gitignore in there for libtool.
+cdd734c Resolve automake warnings
+c5fa726 build: add pkgconfig files
+b20aaca build: just use autoreconf, avoid calling tools manually
+4b0b0d6 cwebp: use modern functions
+efbc6c4 update Android.mk
+7777570 better version of ChangeLog
+fa70d2b update version number in the DOC
+f8db5d5 more C89-fixes
+0de013b fix typos
+650ffa3 add version getters for decoder and encoder
+be4867d doc for incremental decoding
+56732a1 add idec.obj in MSVC makefile
+208afb5 add c++ guards
+8bf76fe add incremental decoding
+1f28832 'inline' isn't defined in strict ansi c89
+8b77c63 move the quantization function to dsp.c
+b2c3575 add a 'last_y' field to WebPDecParams
+2654c3d correctly pass along the exact same status returned from ParsePartitions
+4704146 add missing precision in the man
+6d978a6 add error messages
+6463e6a add some install instructions, and fix intel-mac flags
+05fb7bf Merge ".gitignore: initial version"
+c33f019 .gitignore: initial version
+e532b9a Makefile: allow out of tree builds
+4c0da7a enable sparse dc/ac transforms
+07dbb8d clarify the return logic
+5c69e1b fix bigger-by-1 array
+7c5267e fix a (harmless) typo: non_zero_ -> non_zero_ac_
+bc75213 fix missing free()
+af3e2aa remove trailing spaces
+13e50da make the bitreader preload at least 8bits, instead of post-load them (this makes initialization easier and will be helpful for incremental decoding). Modify ParsePartitions() to accommodate for truncated input.
+f4888f7 emit 9 - nb_bits trailing zeros instead of 8
+3db6525 separate block-parsing into a visible VP8DecodeMB()
+a871de0 add missing extern "C"
+b3ce8c5 remove a gcc warning about type pun by using a proper union'd type
+e186371 update after addition of webpi.h
+3e856e2 Extract some useful functions around decoding buffer WebPDecParams.
+d5bc05a make the filtering process match libvpx and ffvp8
+dd60138 add man pages for cwebp(1) and dwebp(1)
+c4fa364 fix header
+5b70b37 * add an option to bypass_filtering in VP8Io.
+b97a400 simplify QuantizeBlock code a bit
+84b58eb add more checks around picture allocation
+b65a3e1     remove absolute_delta_ field and syntax code
+0744e84 Dont' open output file until we're sure the input file is valid
+d5bd54c fix typo and buggy line
+f7a9549 Add a simple top-level makefile.unix for quick & easy build.
+5f36b94 update the doc for the -f option
+f61d14a a WebP encoder converts PNG & JPEG to WebP
+81c9662 oops: forgotten call to Initialize() + move the error message to a more useful place
+87ffa00 typo: fix a missing 'R', was confusing.
+b04b857 * add decoding measurement using stopwatch.h (use -v option) * support PNG output through WIC on Win32
+746a482 * make (*put)() hook return a bool for abort request. * add an enum for VP8Status() to make things clearer
+73c973e * strengthen riff/chunk size checks * don't consider odd-sized chunks being an error
+1dc4611 add support for PNG output (default) regularize include guards
+860641d fix a typo: sizeof(kYModeProbaInter0) => sizeof(kUVModeProbaInter0)
+3254fc5 fix some petty constness fix the ./configure file too
+504d339 fix eof_ mis-initialization
+2bc0778 leftover Makefile.* from previous commit
+d2cf04e move Makefile.am one level below, to src/dec fix typos here and there dwebp is now an installed program
+ade92de typo: vp8.h -> decode_vp8.h
+d724124 forgot to declare types.h to be installed
+6421a7a move the decoder sourcetree to a sub-location src/dec to make room for future libs sources
+a9b3eab correct layout name is IMC4.
+2330522 handle corner case of zero-dimensions
+280c365 make VP8Init() handle short buffers (< 2 bytes) correctly
+b1c9e8b handle error cases more robustly
+0e94935 Merge "table-less version of clip_8b()"
+1e0a2d2 table-less version of clip_8b()
+e12109e dwebp: change -yuv option to -raw change the layout to IMC2
+d72180a speed-up fancy upscaler
+9145f3b reset eof_ at construction time
+a7ee055 simplify the logic of GetCoeffs()
+f67b593 lot of cosmetics
+ea27d7c fix endian problem on PowerPC
+beb0a1b fix signature of VP8StoreBlock
+b128c5e Merge "fancy chroma upscaling"
+6a37a2a fancy chroma upscaling
+ff565ed fix two numeric typos
+5a936a0 use uintptr_t for casting pointers to ints
+e14a030 for cross_compiling=yes to prevent executing any binary
+83b545e add vc9+ makefile
+296f691 fix output loop for small height
+cbfbb5c convert to plain-C
+f09f96e Fix declaration after statement warning
+5981ee5 Fix UV plane ac/dc quantizer transposition
+c8d15ef convert to ANSI-C
+c3f41cb Initial commit
diff --git a/Source/LibWebP/LibWebP.2005.vcproj b/Source/LibWebP/LibWebP.2005.vcproj
new file mode 100644
index 0000000..1424064
--- /dev/null
+++ b/Source/LibWebP/LibWebP.2005.vcproj
@@ -0,0 +1,735 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8,00"
+	Name="LibWebP"
+	ProjectGUID="{097D9F6C-FD0E-4CBC-9676-009012AAECA8}"
+	RootNamespace="LibWebP"
+	Keyword="Win32Proj"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="4"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				InlineFunctionExpansion="0"
+				PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG;_LIB"
+				StringPooling="false"
+				MinimalRebuild="false"
+				ExceptionHandling="0"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
+				BufferSecurityCheck="true"
+				EnableFunctionLevelLinking="false"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="false"
+				DebugInformationFormat="3"
+				CallingConvention="0"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile=".\Debug\LibWebP.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="4"
+			CharacterSet="2"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				EnableIntrinsicFunctions="true"
+				PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
+				StringPooling="false"
+				MinimalRebuild="false"
+				ExceptionHandling="0"
+				RuntimeLibrary="0"
+				BufferSecurityCheck="true"
+				EnableFunctionLevelLinking="false"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+				CompileAs="1"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile=".\Release\LibWebP.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<Filter
+				Name="dec"
+				>
+				<File
+					RelativePath=".\src\dec\dec.alpha.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dec\dec.buffer.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dec\dec.frame.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dec\dec.idec.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dec\dec.io.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dec\dec.quant.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dec\dec.tree.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dec\dec.vp8.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dec\dec.vp8l.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dec\dec.webp.c"
+					>
+				</File>
+			</Filter>
+			<Filter
+				Name="dsp"
+				>
+				<File
+					RelativePath=".\src\dsp\dsp.alpha_processing.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.alpha_processing_mips_dsp_r2.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.alpha_processing_sse2.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.argb.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.argb_mips_dsp_r2.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.argb_sse2.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.cost.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.cost_mips32.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.cost_mips_dsp_r2.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.cost_sse2.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.cpu.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.dec.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.dec_clip_tables.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.dec_mips32.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.dec_mips_dsp_r2.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.dec_neon.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.dec_sse2.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.enc.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.enc_avx2.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.enc_mips32.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.enc_mips_dsp_r2.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.enc_neon.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.enc_sse2.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.filters.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.filters_mips_dsp_r2.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.filters_sse2.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.lossless.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.lossless_mips32.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.lossless_mips_dsp_r2.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.lossless_neon.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.lossless_sse2.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.rescaler.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.rescaler_mips32.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.rescaler_mips_dsp_r2.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.upsampling.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.upsampling_mips_dsp_r2.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.upsampling_neon.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.upsampling_sse2.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.yuv.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.yuv_mips32.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.yuv_mips_dsp_r2.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.yuv_sse2.c"
+					>
+				</File>
+			</Filter>
+			<Filter
+				Name="enc"
+				>
+				<File
+					RelativePath=".\src\enc\enc.alpha.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\enc.analysis.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\enc.backward_references.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\enc.config.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\enc.cost.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\enc.filter.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\enc.frame.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\enc.histogram.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\enc.iterator.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\enc.near_lossless.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\enc.picture.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\enc.picture_csp.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\enc.picture_psnr.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\enc.picture_rescale.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\enc.picture_tools.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\enc.quant.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\enc.syntax.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\enc.token.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\enc.tree.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\enc.vp8l.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\enc.webpenc.c"
+					>
+				</File>
+			</Filter>
+			<Filter
+				Name="utils"
+				>
+				<File
+					RelativePath=".\src\utils\utils.bit_reader.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\utils.bit_writer.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\utils.color_cache.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\utils.filters.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\utils.huffman.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\utils.huffman_encode.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\utils.quant_levels.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\utils.quant_levels_dec.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\utils.random.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\utils.rescaler.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\utils.thread.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\utils.utils.c"
+					>
+				</File>
+			</Filter>
+			<Filter
+				Name="mux"
+				>
+				<File
+					RelativePath=".\src\mux\mux.anim_encode.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\mux\mux.muxedit.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\mux\mux.muxinternal.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\mux\mux.muxread.c"
+					>
+				</File>
+			</Filter>
+			<Filter
+				Name="demux"
+				>
+				<File
+					RelativePath=".\src\demux\demux.demux.c"
+					>
+				</File>
+			</Filter>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+			<Filter
+				Name="dec"
+				>
+				<File
+					RelativePath=".\src\dec\alphai.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dec\decode_vp8.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dec\vp8i.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dec\vp8li.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dec\webpi.h"
+					>
+				</File>
+			</Filter>
+			<Filter
+				Name="dsp"
+				>
+				<File
+					RelativePath=".\src\dsp\dsp.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\lossless.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\mips_macro.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\neon.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\yuv.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\yuv_tables_sse2.h"
+					>
+				</File>
+			</Filter>
+			<Filter
+				Name="enc"
+				>
+				<File
+					RelativePath=".\src\enc\backward_references.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\cost.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\histogram.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\vp8enci.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\vp8li.h"
+					>
+				</File>
+			</Filter>
+			<Filter
+				Name="webp"
+				>
+				<File
+					RelativePath=".\src\webp\decode.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\webp\demux.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\webp\encode.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\webp\format_constants.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\webp\mux.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\webp\mux_types.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\webp\types.h"
+					>
+				</File>
+			</Filter>
+			<Filter
+				Name="utils"
+				>
+				<File
+					RelativePath=".\src\utils\bit_reader.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\bit_reader_inl.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\bit_writer.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\color_cache.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\endian_inl.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\filters.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\huffman.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\huffman_encode.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\quant_levels.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\quant_levels_dec.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\random.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\rescaler.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\thread.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\utils.h"
+					>
+				</File>
+			</Filter>
+			<Filter
+				Name="mux"
+				>
+				<File
+					RelativePath=".\src\mux\muxi.h"
+					>
+				</File>
+			</Filter>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/Source/LibWebP/LibWebP.2008.vcproj b/Source/LibWebP/LibWebP.2008.vcproj
new file mode 100644
index 0000000..f8024b9
--- /dev/null
+++ b/Source/LibWebP/LibWebP.2008.vcproj
@@ -0,0 +1,883 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9,00"
+	Name="LibWebP"
+	ProjectGUID="{097D9F6C-FD0E-4CBC-9676-009012AAECA8}"
+	RootNamespace="LibWebP"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="4"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				UseUnicodeResponseFiles="false"
+				Optimization="0"
+				InlineFunctionExpansion="0"
+				AdditionalIncludeDirectories="./src"
+				PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG;_LIB;WIN32_LEAN_AND_MEAN"
+				StringPooling="false"
+				MinimalRebuild="false"
+				ExceptionHandling="0"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
+				BufferSecurityCheck="true"
+				EnableFunctionLevelLinking="false"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="false"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				LinkLibraryDependencies="true"
+				OutputFile=".\Debug\LibWebP.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+			ConfigurationType="4"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				UseUnicodeResponseFiles="false"
+				Optimization="0"
+				InlineFunctionExpansion="0"
+				AdditionalIncludeDirectories="./src"
+				PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG;_LIB;WIN32_LEAN_AND_MEAN"
+				StringPooling="false"
+				MinimalRebuild="false"
+				ExceptionHandling="0"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
+				BufferSecurityCheck="true"
+				EnableFunctionLevelLinking="false"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="false"
+				DebugInformationFormat="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				LinkLibraryDependencies="true"
+				OutputFile=".\Debug\LibWebP.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="4"
+			CharacterSet="2"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				EnableIntrinsicFunctions="true"
+				PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
+				StringPooling="false"
+				MinimalRebuild="false"
+				ExceptionHandling="0"
+				RuntimeLibrary="0"
+				BufferSecurityCheck="true"
+				EnableFunctionLevelLinking="false"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+				CompileAs="1"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile=".\Release\LibWebP.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+			ConfigurationType="4"
+			CharacterSet="2"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				EnableIntrinsicFunctions="true"
+				PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
+				StringPooling="false"
+				MinimalRebuild="false"
+				ExceptionHandling="0"
+				RuntimeLibrary="0"
+				BufferSecurityCheck="true"
+				EnableFunctionLevelLinking="false"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+				CompileAs="1"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile=".\Release\LibWebP.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<Filter
+				Name="dec"
+				>
+				<File
+					RelativePath=".\src\dec\dec.alpha.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dec\dec.buffer.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dec\dec.frame.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dec\dec.idec.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dec\dec.io.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dec\dec.quant.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dec\dec.tree.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dec\dec.vp8.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dec\dec.vp8l.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dec\dec.webp.c"
+					>
+				</File>
+			</Filter>
+			<Filter
+				Name="dsp"
+				>
+				<File
+					RelativePath=".\src\dsp\dsp.alpha_processing.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.alpha_processing_mips_dsp_r2.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.alpha_processing_sse2.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.argb.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.argb_mips_dsp_r2.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.argb_sse2.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.cost.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.cost_mips32.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.cost_mips_dsp_r2.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.cost_sse2.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.cpu.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.dec.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.dec_clip_tables.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.dec_mips32.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.dec_mips_dsp_r2.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.dec_neon.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.dec_sse2.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.enc.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.enc_avx2.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.enc_mips32.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.enc_mips_dsp_r2.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.enc_neon.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.enc_sse2.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.filters.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.filters_mips_dsp_r2.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.filters_sse2.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.lossless.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.lossless_mips32.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.lossless_mips_dsp_r2.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.lossless_neon.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.lossless_sse2.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.rescaler.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.rescaler_mips32.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.rescaler_mips_dsp_r2.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.upsampling.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.upsampling_mips_dsp_r2.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.upsampling_neon.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.upsampling_sse2.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.yuv.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.yuv_mips32.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.yuv_mips_dsp_r2.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\dsp.yuv_sse2.c"
+					>
+				</File>
+			</Filter>
+			<Filter
+				Name="enc"
+				>
+				<File
+					RelativePath=".\src\enc\enc.alpha.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\enc.analysis.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\enc.backward_references.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\enc.config.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\enc.cost.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\enc.filter.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\enc.frame.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\enc.histogram.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\enc.iterator.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\enc.near_lossless.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\enc.picture.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\enc.picture_csp.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\enc.picture_psnr.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\enc.picture_rescale.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\enc.picture_tools.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\enc.quant.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\enc.syntax.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\enc.token.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\enc.tree.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\enc.vp8l.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\enc.webpenc.c"
+					>
+				</File>
+			</Filter>
+			<Filter
+				Name="utils"
+				>
+				<File
+					RelativePath=".\src\utils\utils.bit_reader.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\utils.bit_writer.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\utils.color_cache.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\utils.filters.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\utils.huffman.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\utils.huffman_encode.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\utils.quant_levels.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\utils.quant_levels_dec.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\utils.random.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\utils.rescaler.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\utils.thread.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\utils.utils.c"
+					>
+				</File>
+			</Filter>
+			<Filter
+				Name="mux"
+				>
+				<File
+					RelativePath=".\src\mux\mux.anim_encode.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\mux\mux.muxedit.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\mux\mux.muxinternal.c"
+					>
+				</File>
+				<File
+					RelativePath=".\src\mux\mux.muxread.c"
+					>
+				</File>
+			</Filter>
+			<Filter
+				Name="demux"
+				>
+				<File
+					RelativePath=".\src\demux\demux.demux.c"
+					>
+				</File>
+			</Filter>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+			<Filter
+				Name="dec"
+				>
+				<File
+					RelativePath=".\src\dec\alphai.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dec\decode_vp8.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dec\vp8i.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dec\vp8li.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dec\webpi.h"
+					>
+				</File>
+			</Filter>
+			<Filter
+				Name="dsp"
+				>
+				<File
+					RelativePath=".\src\dsp\dsp.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\lossless.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\mips_macro.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\neon.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\yuv.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\dsp\yuv_tables_sse2.h"
+					>
+				</File>
+			</Filter>
+			<Filter
+				Name="enc"
+				>
+				<File
+					RelativePath=".\src\enc\backward_references.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\cost.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\histogram.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\vp8enci.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\enc\vp8li.h"
+					>
+				</File>
+			</Filter>
+			<Filter
+				Name="webp"
+				>
+				<File
+					RelativePath=".\src\webp\decode.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\webp\demux.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\webp\encode.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\webp\format_constants.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\webp\mux.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\webp\mux_types.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\webp\types.h"
+					>
+				</File>
+			</Filter>
+			<Filter
+				Name="utils"
+				>
+				<File
+					RelativePath=".\src\utils\bit_reader.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\bit_reader_inl.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\bit_writer.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\color_cache.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\endian_inl.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\filters.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\huffman.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\huffman_encode.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\quant_levels.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\quant_levels_dec.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\random.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\rescaler.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\thread.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\utils\utils.h"
+					>
+				</File>
+			</Filter>
+			<Filter
+				Name="mux"
+				>
+				<File
+					RelativePath=".\src\mux\muxi.h"
+					>
+				</File>
+			</Filter>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/Source/LibWebP/LibWebP.2013.vcxproj b/Source/LibWebP/LibWebP.2013.vcxproj
new file mode 100644
index 0000000..b5df115
--- /dev/null
+++ b/Source/LibWebP/LibWebP.2013.vcxproj
@@ -0,0 +1,314 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectName>LibWebP</ProjectName>
+    <ProjectGuid>{097D9F6C-FD0E-4CBC-9676-009012AAECA8}</ProjectGuid>
+    <RootNamespace>LibWebP</RootNamespace>
+    <Keyword>Win32Proj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>12.0.21005.1</_ProjectFileVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+      <AdditionalIncludeDirectories>./src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;_LIB;WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>false</StringPooling>
+      <MinimalRebuild>false</MinimalRebuild>
+      <ExceptionHandling />
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <BufferSecurityCheck>true</BufferSecurityCheck>
+      <FunctionLevelLinking>false</FunctionLevelLinking>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <CompileAs>Default</CompileAs>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+    </ClCompile>
+    <ProjectReference>
+      <LinkLibraryDependencies>true</LinkLibraryDependencies>
+    </ProjectReference>
+    <Lib />
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+      <AdditionalIncludeDirectories>./src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;_LIB;WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>false</StringPooling>
+      <MinimalRebuild>false</MinimalRebuild>
+      <ExceptionHandling />
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <BufferSecurityCheck>true</BufferSecurityCheck>
+      <FunctionLevelLinking>false</FunctionLevelLinking>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <CompileAs>Default</CompileAs>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+    </ClCompile>
+    <ProjectReference>
+      <LinkLibraryDependencies>true</LinkLibraryDependencies>
+    </ProjectReference>
+    <Lib />
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <Optimization>Full</Optimization>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>false</StringPooling>
+      <MinimalRebuild>false</MinimalRebuild>
+      <ExceptionHandling />
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>true</BufferSecurityCheck>
+      <FunctionLevelLinking>false</FunctionLevelLinking>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>None</DebugInformationFormat>
+      <CompileAs>CompileAsC</CompileAs>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+    </ClCompile>
+    <Lib />
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>Full</Optimization>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>false</StringPooling>
+      <MinimalRebuild>false</MinimalRebuild>
+      <ExceptionHandling />
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>true</BufferSecurityCheck>
+      <FunctionLevelLinking>false</FunctionLevelLinking>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>None</DebugInformationFormat>
+      <CompileAs>CompileAsC</CompileAs>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+    </ClCompile>
+    <Lib />
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClInclude Include="src\dec\alphai.h" />
+    <ClInclude Include="src\dec\decode_vp8.h" />
+    <ClInclude Include="src\dec\vp8i.h" />
+    <ClInclude Include="src\dec\vp8li.h" />
+    <ClInclude Include="src\dec\webpi.h" />
+    <ClInclude Include="src\dsp\dsp.h" />
+    <ClInclude Include="src\dsp\lossless.h" />
+    <ClInclude Include="src\dsp\mips_macro.h" />
+    <ClInclude Include="src\dsp\neon.h" />
+    <ClInclude Include="src\dsp\yuv.h" />
+    <ClInclude Include="src\dsp\yuv_tables_sse2.h" />
+    <ClInclude Include="src\enc\backward_references.h" />
+    <ClInclude Include="src\enc\cost.h" />
+    <ClInclude Include="src\enc\histogram.h" />
+    <ClInclude Include="src\enc\vp8enci.h" />
+    <ClInclude Include="src\enc\vp8li.h" />
+    <ClInclude Include="src\webp\decode.h" />
+    <ClInclude Include="src\webp\demux.h" />
+    <ClInclude Include="src\webp\encode.h" />
+    <ClInclude Include="src\webp\format_constants.h" />
+    <ClInclude Include="src\webp\mux.h" />
+    <ClInclude Include="src\webp\mux_types.h" />
+    <ClInclude Include="src\webp\types.h" />
+    <ClInclude Include="src\utils\bit_reader.h" />
+    <ClInclude Include="src\utils\bit_reader_inl.h" />
+    <ClInclude Include="src\utils\bit_writer.h" />
+    <ClInclude Include="src\utils\color_cache.h" />
+    <ClInclude Include="src\utils\endian_inl.h" />
+    <ClInclude Include="src\utils\filters.h" />
+    <ClInclude Include="src\utils\huffman.h" />
+    <ClInclude Include="src\utils\huffman_encode.h" />
+    <ClInclude Include="src\utils\quant_levels.h" />
+    <ClInclude Include="src\utils\quant_levels_dec.h" />
+    <ClInclude Include="src\utils\random.h" />
+    <ClInclude Include="src\utils\rescaler.h" />
+    <ClInclude Include="src\utils\thread.h" />
+    <ClInclude Include="src\utils\utils.h" />
+    <ClInclude Include="src\mux\muxi.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="src\dec\dec.alpha.c" />
+    <ClCompile Include="src\dec\dec.buffer.c" />
+    <ClCompile Include="src\dec\dec.frame.c" />
+    <ClCompile Include="src\dec\dec.idec.c" />
+    <ClCompile Include="src\dec\dec.io.c" />
+    <ClCompile Include="src\dec\dec.quant.c" />
+    <ClCompile Include="src\dec\dec.tree.c" />
+    <ClCompile Include="src\dec\dec.vp8.c" />
+    <ClCompile Include="src\dec\dec.vp8l.c" />
+    <ClCompile Include="src\dec\dec.webp.c" />
+    <ClCompile Include="src\demux\demux.demux.c" />
+    <ClCompile Include="src\dsp\dsp.alpha_processing.c" />
+    <ClCompile Include="src\dsp\dsp.alpha_processing_mips_dsp_r2.c" />
+    <ClCompile Include="src\dsp\dsp.alpha_processing_sse2.c" />
+    <ClCompile Include="src\dsp\dsp.argb.c" />
+    <ClCompile Include="src\dsp\dsp.argb_mips_dsp_r2.c" />
+    <ClCompile Include="src\dsp\dsp.argb_sse2.c" />
+    <ClCompile Include="src\dsp\dsp.cost.c" />
+    <ClCompile Include="src\dsp\dsp.cost_mips32.c" />
+    <ClCompile Include="src\dsp\dsp.cost_mips_dsp_r2.c" />
+    <ClCompile Include="src\dsp\dsp.cost_sse2.c" />
+    <ClCompile Include="src\dsp\dsp.cpu.c" />
+    <ClCompile Include="src\dsp\dsp.dec.c" />
+    <ClCompile Include="src\dsp\dsp.dec_clip_tables.c" />
+    <ClCompile Include="src\dsp\dsp.dec_mips32.c" />
+    <ClCompile Include="src\dsp\dsp.dec_mips_dsp_r2.c" />
+    <ClCompile Include="src\dsp\dsp.dec_neon.c" />
+    <ClCompile Include="src\dsp\dsp.dec_sse2.c" />
+    <ClCompile Include="src\dsp\dsp.enc.c" />
+    <ClCompile Include="src\dsp\dsp.enc_avx2.c" />
+    <ClCompile Include="src\dsp\dsp.enc_mips32.c" />
+    <ClCompile Include="src\dsp\dsp.enc_mips_dsp_r2.c" />
+    <ClCompile Include="src\dsp\dsp.enc_neon.c" />
+    <ClCompile Include="src\dsp\dsp.enc_sse2.c" />
+    <ClCompile Include="src\dsp\dsp.filters.c" />
+    <ClCompile Include="src\dsp\dsp.filters_mips_dsp_r2.c" />
+    <ClCompile Include="src\dsp\dsp.filters_sse2.c" />
+    <ClCompile Include="src\dsp\dsp.lossless.c" />
+    <ClCompile Include="src\dsp\dsp.lossless_mips32.c" />
+    <ClCompile Include="src\dsp\dsp.lossless_mips_dsp_r2.c" />
+    <ClCompile Include="src\dsp\dsp.lossless_neon.c" />
+    <ClCompile Include="src\dsp\dsp.lossless_sse2.c" />
+    <ClCompile Include="src\dsp\dsp.rescaler.c" />
+    <ClCompile Include="src\dsp\dsp.rescaler_mips32.c" />
+    <ClCompile Include="src\dsp\dsp.rescaler_mips_dsp_r2.c" />
+    <ClCompile Include="src\dsp\dsp.upsampling.c" />
+    <ClCompile Include="src\dsp\dsp.upsampling_mips_dsp_r2.c" />
+    <ClCompile Include="src\dsp\dsp.upsampling_neon.c" />
+    <ClCompile Include="src\dsp\dsp.upsampling_sse2.c" />
+    <ClCompile Include="src\dsp\dsp.yuv.c" />
+    <ClCompile Include="src\dsp\dsp.yuv_mips32.c" />
+    <ClCompile Include="src\dsp\dsp.yuv_mips_dsp_r2.c" />
+    <ClCompile Include="src\dsp\dsp.yuv_sse2.c" />
+    <ClCompile Include="src\enc\enc.alpha.c" />
+    <ClCompile Include="src\enc\enc.analysis.c" />
+    <ClCompile Include="src\enc\enc.backward_references.c" />
+    <ClCompile Include="src\enc\enc.config.c" />
+    <ClCompile Include="src\enc\enc.cost.c" />
+    <ClCompile Include="src\enc\enc.filter.c" />
+    <ClCompile Include="src\enc\enc.frame.c" />
+    <ClCompile Include="src\enc\enc.histogram.c" />
+    <ClCompile Include="src\enc\enc.iterator.c" />
+    <ClCompile Include="src\enc\enc.near_lossless.c" />
+    <ClCompile Include="src\enc\enc.picture.c" />
+    <ClCompile Include="src\enc\enc.picture_csp.c" />
+    <ClCompile Include="src\enc\enc.picture_psnr.c" />
+    <ClCompile Include="src\enc\enc.picture_rescale.c" />
+    <ClCompile Include="src\enc\enc.picture_tools.c" />
+    <ClCompile Include="src\enc\enc.quant.c" />
+    <ClCompile Include="src\enc\enc.syntax.c" />
+    <ClCompile Include="src\enc\enc.token.c" />
+    <ClCompile Include="src\enc\enc.tree.c" />
+    <ClCompile Include="src\enc\enc.vp8l.c" />
+    <ClCompile Include="src\enc\enc.webpenc.c" />
+    <ClCompile Include="src\mux\mux.anim_encode.c" />
+    <ClCompile Include="src\mux\mux.muxedit.c" />
+    <ClCompile Include="src\mux\mux.muxinternal.c" />
+    <ClCompile Include="src\mux\mux.muxread.c" />
+    <ClCompile Include="src\utils\utils.bit_reader.c" />
+    <ClCompile Include="src\utils\utils.bit_writer.c" />
+    <ClCompile Include="src\utils\utils.color_cache.c" />
+    <ClCompile Include="src\utils\utils.filters.c" />
+    <ClCompile Include="src\utils\utils.huffman.c" />
+    <ClCompile Include="src\utils\utils.huffman_encode.c" />
+    <ClCompile Include="src\utils\utils.quant_levels.c" />
+    <ClCompile Include="src\utils\utils.quant_levels_dec.c" />
+    <ClCompile Include="src\utils\utils.random.c" />
+    <ClCompile Include="src\utils\utils.rescaler.c" />
+    <ClCompile Include="src\utils\utils.thread.c" />
+    <ClCompile Include="src\utils\utils.utils.c" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/Source/LibWebP/LibWebP.2013.vcxproj.filters b/Source/LibWebP/LibWebP.2013.vcxproj.filters
new file mode 100644
index 0000000..fb0eb4e
--- /dev/null
+++ b/Source/LibWebP/LibWebP.2013.vcxproj.filters
@@ -0,0 +1,437 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="Source Files\dec">
+      <UniqueIdentifier>{898f62af-7401-4f82-9452-2b72677517d7}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\dsp">
+      <UniqueIdentifier>{3e44808f-e2b1-4d2b-b50f-8b8d56f209ac}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\enc">
+      <UniqueIdentifier>{40bf922d-3f05-4278-a848-9a8f9c1d9474}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\utils">
+      <UniqueIdentifier>{d906e31e-f602-4b1f-ba68-b1abb5ff9738}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\mux">
+      <UniqueIdentifier>{4eeaa0c9-dead-4997-bff0-6c9a5af48cdd}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\demux">
+      <UniqueIdentifier>{c7c9cc92-92ca-4844-b506-87ba16fe9d1d}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+    </Filter>
+    <Filter Include="Header Files\dec">
+      <UniqueIdentifier>{dff32b80-f0b7-49d7-b771-b92f85ee9848}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\dsp">
+      <UniqueIdentifier>{88e77c9d-2044-4a31-920e-ee5f93256344}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\enc">
+      <UniqueIdentifier>{a9d95275-6425-4ea0-841b-40c54d451735}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\webp">
+      <UniqueIdentifier>{f8ab3946-dc90-46c3-856a-5b56f14bce33}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\utils">
+      <UniqueIdentifier>{fb7ba256-3298-47b1-8382-c5a3e8d62004}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\mux">
+      <UniqueIdentifier>{d494e420-63fe-4350-80fa-44e7c4786e1a}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="src\dec\alphai.h">
+      <Filter>Header Files\dec</Filter>
+    </ClInclude>
+    <ClInclude Include="src\dec\decode_vp8.h">
+      <Filter>Header Files\dec</Filter>
+    </ClInclude>
+    <ClInclude Include="src\dec\vp8i.h">
+      <Filter>Header Files\dec</Filter>
+    </ClInclude>
+    <ClInclude Include="src\dec\vp8li.h">
+      <Filter>Header Files\dec</Filter>
+    </ClInclude>
+    <ClInclude Include="src\dec\webpi.h">
+      <Filter>Header Files\dec</Filter>
+    </ClInclude>
+    <ClInclude Include="src\dsp\dsp.h">
+      <Filter>Header Files\dsp</Filter>
+    </ClInclude>
+    <ClInclude Include="src\dsp\lossless.h">
+      <Filter>Header Files\dsp</Filter>
+    </ClInclude>
+    <ClInclude Include="src\dsp\neon.h">
+      <Filter>Header Files\dsp</Filter>
+    </ClInclude>
+    <ClInclude Include="src\dsp\yuv.h">
+      <Filter>Header Files\dsp</Filter>
+    </ClInclude>
+    <ClInclude Include="src\dsp\yuv_tables_sse2.h">
+      <Filter>Header Files\dsp</Filter>
+    </ClInclude>
+    <ClInclude Include="src\enc\backward_references.h">
+      <Filter>Header Files\enc</Filter>
+    </ClInclude>
+    <ClInclude Include="src\enc\cost.h">
+      <Filter>Header Files\enc</Filter>
+    </ClInclude>
+    <ClInclude Include="src\enc\histogram.h">
+      <Filter>Header Files\enc</Filter>
+    </ClInclude>
+    <ClInclude Include="src\enc\vp8enci.h">
+      <Filter>Header Files\enc</Filter>
+    </ClInclude>
+    <ClInclude Include="src\enc\vp8li.h">
+      <Filter>Header Files\enc</Filter>
+    </ClInclude>
+    <ClInclude Include="src\webp\decode.h">
+      <Filter>Header Files\webp</Filter>
+    </ClInclude>
+    <ClInclude Include="src\webp\demux.h">
+      <Filter>Header Files\webp</Filter>
+    </ClInclude>
+    <ClInclude Include="src\webp\encode.h">
+      <Filter>Header Files\webp</Filter>
+    </ClInclude>
+    <ClInclude Include="src\webp\format_constants.h">
+      <Filter>Header Files\webp</Filter>
+    </ClInclude>
+    <ClInclude Include="src\webp\mux.h">
+      <Filter>Header Files\webp</Filter>
+    </ClInclude>
+    <ClInclude Include="src\webp\mux_types.h">
+      <Filter>Header Files\webp</Filter>
+    </ClInclude>
+    <ClInclude Include="src\webp\types.h">
+      <Filter>Header Files\webp</Filter>
+    </ClInclude>
+    <ClInclude Include="src\utils\bit_reader.h">
+      <Filter>Header Files\utils</Filter>
+    </ClInclude>
+    <ClInclude Include="src\utils\bit_reader_inl.h">
+      <Filter>Header Files\utils</Filter>
+    </ClInclude>
+    <ClInclude Include="src\utils\bit_writer.h">
+      <Filter>Header Files\utils</Filter>
+    </ClInclude>
+    <ClInclude Include="src\utils\color_cache.h">
+      <Filter>Header Files\utils</Filter>
+    </ClInclude>
+    <ClInclude Include="src\utils\endian_inl.h">
+      <Filter>Header Files\utils</Filter>
+    </ClInclude>
+    <ClInclude Include="src\utils\filters.h">
+      <Filter>Header Files\utils</Filter>
+    </ClInclude>
+    <ClInclude Include="src\utils\huffman.h">
+      <Filter>Header Files\utils</Filter>
+    </ClInclude>
+    <ClInclude Include="src\utils\huffman_encode.h">
+      <Filter>Header Files\utils</Filter>
+    </ClInclude>
+    <ClInclude Include="src\utils\quant_levels.h">
+      <Filter>Header Files\utils</Filter>
+    </ClInclude>
+    <ClInclude Include="src\utils\quant_levels_dec.h">
+      <Filter>Header Files\utils</Filter>
+    </ClInclude>
+    <ClInclude Include="src\utils\random.h">
+      <Filter>Header Files\utils</Filter>
+    </ClInclude>
+    <ClInclude Include="src\utils\rescaler.h">
+      <Filter>Header Files\utils</Filter>
+    </ClInclude>
+    <ClInclude Include="src\utils\thread.h">
+      <Filter>Header Files\utils</Filter>
+    </ClInclude>
+    <ClInclude Include="src\utils\utils.h">
+      <Filter>Header Files\utils</Filter>
+    </ClInclude>
+    <ClInclude Include="src\mux\muxi.h">
+      <Filter>Header Files\mux</Filter>
+    </ClInclude>
+    <ClInclude Include="src\dsp\mips_macro.h">
+      <Filter>Header Files\dsp</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="src\dec\dec.alpha.c">
+      <Filter>Source Files\dec</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dec\dec.buffer.c">
+      <Filter>Source Files\dec</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dec\dec.frame.c">
+      <Filter>Source Files\dec</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dec\dec.idec.c">
+      <Filter>Source Files\dec</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dec\dec.io.c">
+      <Filter>Source Files\dec</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dec\dec.quant.c">
+      <Filter>Source Files\dec</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dec\dec.tree.c">
+      <Filter>Source Files\dec</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dec\dec.vp8.c">
+      <Filter>Source Files\dec</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dec\dec.vp8l.c">
+      <Filter>Source Files\dec</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dec\dec.webp.c">
+      <Filter>Source Files\dec</Filter>
+    </ClCompile>
+    <ClCompile Include="src\demux\demux.demux.c">
+      <Filter>Source Files\demux</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.alpha_processing.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.alpha_processing_mips_dsp_r2.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.alpha_processing_sse2.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.argb.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.argb_mips_dsp_r2.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.argb_sse2.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.cost.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.cost_mips_dsp_r2.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.cost_mips32.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.cost_sse2.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.cpu.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.dec.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.dec_clip_tables.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.dec_mips_dsp_r2.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.dec_mips32.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.dec_neon.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.dec_sse2.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.enc.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.enc_avx2.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.enc_mips_dsp_r2.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.enc_mips32.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.enc_neon.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.enc_sse2.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.filters.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.filters_mips_dsp_r2.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.filters_sse2.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.lossless.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.lossless_mips_dsp_r2.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.lossless_mips32.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.lossless_neon.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.lossless_sse2.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.rescaler.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.rescaler_mips_dsp_r2.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.rescaler_mips32.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.upsampling.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.upsampling_mips_dsp_r2.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.upsampling_neon.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.upsampling_sse2.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.yuv.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.yuv_mips_dsp_r2.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.yuv_mips32.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\dsp\dsp.yuv_sse2.c">
+      <Filter>Source Files\dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="src\enc\enc.alpha.c">
+      <Filter>Source Files\enc</Filter>
+    </ClCompile>
+    <ClCompile Include="src\enc\enc.analysis.c">
+      <Filter>Source Files\enc</Filter>
+    </ClCompile>
+    <ClCompile Include="src\enc\enc.backward_references.c">
+      <Filter>Source Files\enc</Filter>
+    </ClCompile>
+    <ClCompile Include="src\enc\enc.config.c">
+      <Filter>Source Files\enc</Filter>
+    </ClCompile>
+    <ClCompile Include="src\enc\enc.cost.c">
+      <Filter>Source Files\enc</Filter>
+    </ClCompile>
+    <ClCompile Include="src\enc\enc.filter.c">
+      <Filter>Source Files\enc</Filter>
+    </ClCompile>
+    <ClCompile Include="src\enc\enc.frame.c">
+      <Filter>Source Files\enc</Filter>
+    </ClCompile>
+    <ClCompile Include="src\enc\enc.histogram.c">
+      <Filter>Source Files\enc</Filter>
+    </ClCompile>
+    <ClCompile Include="src\enc\enc.iterator.c">
+      <Filter>Source Files\enc</Filter>
+    </ClCompile>
+    <ClCompile Include="src\enc\enc.near_lossless.c">
+      <Filter>Source Files\enc</Filter>
+    </ClCompile>
+    <ClCompile Include="src\enc\enc.picture.c">
+      <Filter>Source Files\enc</Filter>
+    </ClCompile>
+    <ClCompile Include="src\enc\enc.picture_csp.c">
+      <Filter>Source Files\enc</Filter>
+    </ClCompile>
+    <ClCompile Include="src\enc\enc.picture_psnr.c">
+      <Filter>Source Files\enc</Filter>
+    </ClCompile>
+    <ClCompile Include="src\enc\enc.picture_rescale.c">
+      <Filter>Source Files\enc</Filter>
+    </ClCompile>
+    <ClCompile Include="src\enc\enc.picture_tools.c">
+      <Filter>Source Files\enc</Filter>
+    </ClCompile>
+    <ClCompile Include="src\enc\enc.quant.c">
+      <Filter>Source Files\enc</Filter>
+    </ClCompile>
+    <ClCompile Include="src\enc\enc.syntax.c">
+      <Filter>Source Files\enc</Filter>
+    </ClCompile>
+    <ClCompile Include="src\enc\enc.token.c">
+      <Filter>Source Files\enc</Filter>
+    </ClCompile>
+    <ClCompile Include="src\enc\enc.tree.c">
+      <Filter>Source Files\enc</Filter>
+    </ClCompile>
+    <ClCompile Include="src\enc\enc.vp8l.c">
+      <Filter>Source Files\enc</Filter>
+    </ClCompile>
+    <ClCompile Include="src\enc\enc.webpenc.c">
+      <Filter>Source Files\enc</Filter>
+    </ClCompile>
+    <ClCompile Include="src\mux\mux.anim_encode.c">
+      <Filter>Source Files\mux</Filter>
+    </ClCompile>
+    <ClCompile Include="src\mux\mux.muxedit.c">
+      <Filter>Source Files\mux</Filter>
+    </ClCompile>
+    <ClCompile Include="src\mux\mux.muxinternal.c">
+      <Filter>Source Files\mux</Filter>
+    </ClCompile>
+    <ClCompile Include="src\mux\mux.muxread.c">
+      <Filter>Source Files\mux</Filter>
+    </ClCompile>
+    <ClCompile Include="src\utils\utils.bit_reader.c">
+      <Filter>Source Files\utils</Filter>
+    </ClCompile>
+    <ClCompile Include="src\utils\utils.bit_writer.c">
+      <Filter>Source Files\utils</Filter>
+    </ClCompile>
+    <ClCompile Include="src\utils\utils.color_cache.c">
+      <Filter>Source Files\utils</Filter>
+    </ClCompile>
+    <ClCompile Include="src\utils\utils.filters.c">
+      <Filter>Source Files\utils</Filter>
+    </ClCompile>
+    <ClCompile Include="src\utils\utils.huffman.c">
+      <Filter>Source Files\utils</Filter>
+    </ClCompile>
+    <ClCompile Include="src\utils\utils.huffman_encode.c">
+      <Filter>Source Files\utils</Filter>
+    </ClCompile>
+    <ClCompile Include="src\utils\utils.quant_levels.c">
+      <Filter>Source Files\utils</Filter>
+    </ClCompile>
+    <ClCompile Include="src\utils\utils.quant_levels_dec.c">
+      <Filter>Source Files\utils</Filter>
+    </ClCompile>
+    <ClCompile Include="src\utils\utils.random.c">
+      <Filter>Source Files\utils</Filter>
+    </ClCompile>
+    <ClCompile Include="src\utils\utils.rescaler.c">
+      <Filter>Source Files\utils</Filter>
+    </ClCompile>
+    <ClCompile Include="src\utils\utils.thread.c">
+      <Filter>Source Files\utils</Filter>
+    </ClCompile>
+    <ClCompile Include="src\utils\utils.utils.c">
+      <Filter>Source Files\utils</Filter>
+    </ClCompile>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/Source/LibWebP/NEWS b/Source/LibWebP/NEWS
new file mode 100644
index 0000000..0e2e535
--- /dev/null
+++ b/Source/LibWebP/NEWS
@@ -0,0 +1,96 @@
+- 10/13/14: version 0.4.2
+  This is a binary compatible release.
+  * Android / gcc build fixes
+  * (Windows) fix reading from stdin and writing to stdout
+  * gif2webp: miscellaneous fixes
+  * fix 'alpha-leak' with lossy compression (issue #220)
+  * the lossless bitstream spec has been amended to reflect the current code
+
+- 7/24/14: version 0.4.1
+  This is a binary compatible release.
+  * AArch64 (arm64) & MIPS support/optimizations
+  * NEON assembly additions:
+    - ~25% faster lossy decode / encode (-m 4)
+    - ~10% faster lossless decode
+    - ~5-10% faster lossless encode (-m 3/4)
+  * dwebp/vwebp can read from stdin
+  * cwebp/gif2webp can write to stdout
+  * cwebp can read webp files; useful if storing sources as webp lossless
+
+- 12/19/13: version 0.4.0
+  * improved gif2webp tool
+  * numerous fixes, compression improvement and speed-up
+  * dither option added to decoder (dwebp -dither 50 ...)
+  * improved multi-threaded modes (-mt option)
+  * improved filtering strength determination
+  * New function: WebPMuxGetCanvasSize
+  * BMP and TIFF format output added to 'dwebp'
+  * Significant memory reduction for decoding lossy images with alpha.
+  * Intertwined decoding of RGB and alpha for a shorter
+    time-to-first-decoded-pixel.
+  * WebPIterator has a new member 'has_alpha' denoting whether the frame
+    contains transparency.
+  * Container spec amended with new 'blending method' for animation.
+
+- 6/13/13: version 0.3.1
+  This is a binary compatible release.
+  * Add incremental decoding support for images containing ALPH and ICCP chunks.
+  * Python bindings via swig for the simple encode/decode interfaces similar to
+    Java.
+
+- 3/20/13: version 0.3.0
+  This is a binary compatible release.
+  * WebPINewRGB/WebPINewYUVA accept being passed a NULL output buffer
+    and will perform auto-allocation.
+  * default filter option is now '-strong -f 60'
+  * encoding speed-up for lossy methods 3 to 6
+  * alpha encoding can be done in parallel to lossy using 'cwebp -mt ...'
+  * color profile, metadata (XMP/EXIF) and animation support finalized in the
+    container.
+  * various NEON assembly additions
+  Tool updates / additions:
+    * gif2webp added
+    * vwebp given color profile & animation support
+    * cwebp can preserve color profile / metadata with '-metadata'
+
+- 10/30/12: version 0.2.1
+  * Various security related fixes
+  * cwebp.exe: fix import errors on Windows XP
+  * enable DLL builds for mingw targets
+
+- 8/3/12: version 0.2.0
+  * Add support for ARGB -> YUVA conversion for lossless decoder
+    New functions: WebPINewYUVA, WebPIDecGetYUVA
+  * Add stats for lossless and alpha encoding
+  * Security related hardening: allocation and size checks
+  * Add PAM output support to dwebp
+
+- 7/19/12: version 0.1.99
+  * This is a pre-release of 0.2.0, not an rc to allow for further
+    incompatible changes based on user feedback.
+  * Alpha channel encode/decode support.
+  * Lossless encoder/decoder.
+  * Add TIFF input support to cwebp.
+  Incompatible changes:
+    * The encode ABI has been modified to support alpha encoding.
+    * Deprecated function WebPINew() has been removed.
+    * Decode function signatures have changed to consistently use size_t over
+      int/uint32_t.
+    * decode_vp8.h is no longer installed system-wide.
+    * cwebp will encode the alpha channel if present.
+
+- 9/19/11: version 0.1.3
+  * Advanced decoding APIs.
+  * On-the-fly cropping and rescaling of images.
+  * SSE2 instructions for decoding performance optimizations on x86 based platforms.
+  * Support Multi-threaded decoding.
+  * 40% improvement in Decoding performance.
+  * Add support for RGB565, RGBA4444 & ARGB image colorspace.
+  * Better handling of large picture encoding.
+
+- 3/25/11: version 0.1.2
+  * Incremental decoding: picture can be decoded byte-by-byte if needs be.
+  * lot of bug-fixes, consolidation and stabilization
+
+- 2/23/11: initial release of version 0.1, with the new encoder
+- 9/30/10: initial release version with only the lightweight decoder
diff --git a/Source/LibWebP/PATENTS b/Source/LibWebP/PATENTS
new file mode 100644
index 0000000..b530e98
--- /dev/null
+++ b/Source/LibWebP/PATENTS
@@ -0,0 +1,23 @@
+Additional IP Rights Grant (Patents)
+------------------------------------
+
+"These implementations" means the copyrightable works that implement the WebM
+codecs distributed by Google as part of the WebM Project.
+
+Google hereby grants to you a perpetual, worldwide, non-exclusive, no-charge,
+royalty-free, irrevocable (except as stated in this section) patent license to
+make, have made, use, offer to sell, sell, import, transfer, and otherwise
+run, modify and propagate the contents of these implementations of WebM, where
+such license applies only to those patent claims, both currently owned by
+Google and acquired in the future, licensable by Google that are necessarily
+infringed by these implementations of WebM. This grant does not include claims
+that would be infringed only as a consequence of further modification of these
+implementations. If you or your agent or exclusive licensee institute or order
+or agree to the institution of patent litigation or any other patent
+enforcement activity against any entity (including a cross-claim or
+counterclaim in a lawsuit) alleging that any of these implementations of WebM
+or any code incorporated within any of these implementations of WebM
+constitutes direct or contributory patent infringement, or inducement of
+patent infringement, then any patent rights granted to you under this License
+for these implementations of WebM shall terminate as of the date such
+litigation is filed.
diff --git a/Source/LibWebP/README b/Source/LibWebP/README
new file mode 100644
index 0000000..f23f853
--- /dev/null
+++ b/Source/LibWebP/README
@@ -0,0 +1,612 @@
+          __   __  ____  ____  ____
+         /  \\/  \/  _ \/  _ )/  _ \
+         \       /   __/  _  \   __/
+          \__\__/\____/\_____/__/ ____  ___
+                / _/ /    \    \ /  _ \/ _/
+               /  \_/   / /   \ \   __/  \__
+               \____/____/\_____/_____/____/v0.4.2
+
+Description:
+============
+
+WebP codec: library to encode and decode images in WebP format. This package
+contains the library that can be used in other programs to add WebP support,
+as well as the command line tools 'cwebp' and 'dwebp'.
+
+See http://developers.google.com/speed/webp
+
+Latest sources are available from http://www.webmproject.org/code/
+
+It is released under the same license as the WebM project.
+See http://www.webmproject.org/license/software/ or the
+file "COPYING" file for details. An additional intellectual
+property rights grant can be found in the file PATENTS.
+
+Building:
+=========
+
+Windows build:
+--------------
+
+By running:
+
+  nmake /f Makefile.vc CFG=release-static RTLIBCFG=static OBJDIR=output
+
+the directory output\release-static\(x64|x86)\bin will contain the tools
+cwebp.exe and dwebp.exe. The directory output\release-static\(x64|x86)\lib will
+contain the libwebp static library.
+The target architecture (x86/x64) is detected by Makefile.vc from the Visual
+Studio compiler (cl.exe) available in the system path.
+
+Unix build using makefile.unix:
+-------------------------------
+
+On platforms with GNU tools installed (gcc and make), running
+
+  make -f makefile.unix
+
+will build the binaries examples/cwebp and examples/dwebp, along
+with the static library src/libwebp.a. No system-wide installation
+is supplied, as this is a simple alternative to the full installation
+system based on the autoconf tools (see below).
+Please refer to makefile.unix for additional details and customizations.
+
+Using autoconf tools:
+---------------------
+When building from git sources, you will need to run autogen.sh to generate the
+configure script.
+
+./configure
+make
+make install
+
+should be all you need to have the following files
+
+/usr/local/include/webp/decode.h
+/usr/local/include/webp/encode.h
+/usr/local/include/webp/types.h
+/usr/local/lib/libwebp.*
+/usr/local/bin/cwebp
+/usr/local/bin/dwebp
+
+installed.
+
+Note: A decode-only library, libwebpdecoder, is available using the
+'--enable-libwebpdecoder' flag. The encode library is built separately and can
+be installed independently using a minor modification in the corresponding
+Makefile.am configure files (see comments there). See './configure --help' for
+more options.
+
+SWIG bindings:
+--------------
+
+To generate language bindings from swig/libwebp.swig at least swig-1.3
+(http://www.swig.org) is required.
+
+Currently the following functions are mapped:
+Decode:
+  WebPGetDecoderVersion
+  WebPGetInfo
+  WebPDecodeRGBA
+  WebPDecodeARGB
+  WebPDecodeBGRA
+  WebPDecodeBGR
+  WebPDecodeRGB
+
+Encode:
+  WebPGetEncoderVersion
+  WebPEncodeRGBA
+  WebPEncodeBGRA
+  WebPEncodeRGB
+  WebPEncodeBGR
+  WebPEncodeLosslessRGBA
+  WebPEncodeLosslessBGRA
+  WebPEncodeLosslessRGB
+  WebPEncodeLosslessBGR
+
+See swig/README for more detailed build instructions.
+
+Java bindings:
+
+To build the swig-generated JNI wrapper code at least JDK-1.5 (or equivalent)
+is necessary for enum support. The output is intended to be a shared object /
+DLL that can be loaded via System.loadLibrary("webp_jni").
+
+Python bindings:
+
+To build the swig-generated Python extension code at least Python 2.6 is
+required. Python < 2.6 may build with some minor changes to libwebp.swig or the
+generated code, but is untested.
+
+Encoding tool:
+==============
+
+The examples/ directory contains tools for encoding (cwebp) and
+decoding (dwebp) images.
+
+The easiest use should look like:
+  cwebp input.png -q 80 -o output.webp
+which will convert the input file to a WebP file using a quality factor of 80
+on a 0->100 scale (0 being the lowest quality, 100 being the best. Default
+value is 75).
+You might want to try the -lossless flag too, which will compress the source
+(in RGBA format) without any loss. The -q quality parameter will in this case
+control the amount of processing time spent trying to make the output file as
+small as possible.
+
+A longer list of options is available using the -longhelp command line flag:
+
+> cwebp -longhelp
+Usage:
+ cwebp [-preset <...>] [options] in_file [-o out_file]
+
+If input size (-s) for an image is not specified, it is
+assumed to be a PNG, JPEG, TIFF or WebP file.
+
+Options:
+  -h / -help  ............ short help
+  -H / -longhelp  ........ long help
+  -q <float> ............. quality factor (0:small..100:big)
+  -alpha_q <int> ......... transparency-compression quality (0..100)
+  -preset <string> ....... preset setting, one of:
+                            default, photo, picture,
+                            drawing, icon, text
+     -preset must come first, as it overwrites other parameters
+  -z <int> ............... activates lossless preset with given
+                           level in [0:fast, ..., 9:slowest]
+
+  -m <int> ............... compression method (0=fast, 6=slowest)
+  -segments <int> ........ number of segments to use (1..4)
+  -size <int> ............ target size (in bytes)
+  -psnr <float> .......... target PSNR (in dB. typically: 42)
+
+  -s <int> <int> ......... input size (width x height) for YUV
+  -sns <int> ............. spatial noise shaping (0:off, 100:max)
+  -f <int> ............... filter strength (0=off..100)
+  -sharpness <int> ....... filter sharpness (0:most .. 7:least sharp)
+  -strong ................ use strong filter instead of simple (default)
+  -nostrong .............. use simple filter instead of strong
+  -partition_limit <int> . limit quality to fit the 512k limit on
+                           the first partition (0=no degradation ... 100=full)
+  -pass <int> ............ analysis pass number (1..10)
+  -crop <x> <y> <w> <h> .. crop picture with the given rectangle
+  -resize <w> <h> ........ resize picture (after any cropping)
+  -mt .................... use multi-threading if available
+  -low_memory ............ reduce memory usage (slower encoding)
+  -map <int> ............. print map of extra info
+  -print_psnr ............ prints averaged PSNR distortion
+  -print_ssim ............ prints averaged SSIM distortion
+  -print_lsim ............ prints local-similarity distortion
+  -d <file.pgm> .......... dump the compressed output (PGM file)
+  -alpha_method <int> .... transparency-compression method (0..1)
+  -alpha_filter <string> . predictive filtering for alpha plane,
+                           one of: none, fast (default) or best
+  -alpha_cleanup ......... clean RGB values in transparent area
+  -blend_alpha <hex> ..... blend colors against background color
+                           expressed as RGB values written in
+                           hexadecimal, e.g. 0xc0e0d0 for red=0xc0
+                           green=0xe0 and blue=0xd0
+  -noalpha ............... discard any transparency information
+  -lossless .............. encode image losslessly
+  -hint <string> ......... specify image characteristics hint,
+                           one of: photo, picture or graph
+
+  -metadata <string> ..... comma separated list of metadata to
+                           copy from the input to the output if present.
+                           Valid values: all, none (default), exif, icc, xmp
+
+  -short ................. condense printed message
+  -quiet ................. don't print anything
+  -version ............... print version number and exit
+  -noasm ................. disable all assembly optimizations
+  -v ..................... verbose, e.g. print encoding/decoding times
+  -progress .............. report encoding progress
+
+Experimental Options:
+  -jpeg_like ............. roughly match expected JPEG size
+  -af .................... auto-adjust filter strength
+  -pre <int> ............. pre-processing filter
+
+The main options you might want to try in order to further tune the
+visual quality are:
+ -preset
+ -sns
+ -f
+ -m
+
+Namely:
+  * 'preset' will set up a default encoding configuration targeting a
+     particular type of input. It should appear first in the list of options,
+     so that subsequent options can take effect on top of this preset.
+     Default value is 'default'.
+  * 'sns' will progressively turn on (when going from 0 to 100) some additional
+     visual optimizations (like: segmentation map re-enforcement). This option
+     will balance the bit allocation differently. It tries to take bits from the
+     "easy" parts of the picture and use them in the "difficult" ones instead.
+     Usually, raising the sns value (at fixed -q value) leads to larger files,
+     but with better quality.
+     Typical value is around '75'.
+  * 'f' option directly links to the filtering strength used by the codec's
+     in-loop processing. The higher the value, the smoother the
+     highly-compressed area will look. This is particularly useful when aiming
+     at very small files. Typical values are around 20-30. Note that using the
+     option -strong/-nostrong will change the type of filtering. Use "-f 0" to
+     turn filtering off.
+  * 'm' controls the trade-off between encoding speed and quality. Default is 4.
+     You can try -m 5 or -m 6 to explore more (time-consuming) encoding
+     possibilities. A lower value will result in faster encoding at the expense
+     of quality.
+
+Decoding tool:
+==============
+
+There is a decoding sample in examples/dwebp.c which will take
+a .webp file and decode it to a PNG image file (amongst other formats).
+This is simply to demonstrate the use of the API. You can verify the
+file test.webp decodes to exactly the same as test_ref.ppm by using:
+
+ cd examples
+ ./dwebp test.webp -ppm -o test.ppm
+ diff test.ppm test_ref.ppm
+
+The full list of options is available using -h:
+
+> dwebp -h
+Usage: dwebp in_file [options] [-o out_file]
+
+Decodes the WebP image file to PNG format [Default]
+Use following options to convert into alternate image formats:
+  -pam ......... save the raw RGBA samples as a color PAM
+  -ppm ......... save the raw RGB samples as a color PPM
+  -bmp ......... save as uncompressed BMP format
+  -tiff ........ save as uncompressed TIFF format
+  -pgm ......... save the raw YUV samples as a grayscale PGM
+                 file with IMC4 layout
+  -yuv ......... save the raw YUV samples in flat layout
+
+ Other options are:
+  -version  .... print version number and exit
+  -nofancy ..... don't use the fancy YUV420 upscaler
+  -nofilter .... disable in-loop filtering
+  -nodither .... disable dithering
+  -dither <d> .. dithering strength (in 0..100)
+  -alpha_dither  use alpha-plane dithering if needed
+  -mt .......... use multi-threading
+  -crop <x> <y> <w> <h> ... crop output with the given rectangle
+  -scale <w> <h> .......... scale the output (*after* any cropping)
+  -flip ........ flip the output vertically
+  -alpha ....... only save the alpha plane
+  -incremental . use incremental decoding (useful for tests)
+  -h     ....... this help message
+  -v     ....... verbose (e.g. print encoding/decoding times)
+  -noasm ....... disable all assembly optimizations
+
+Visualization tool:
+===================
+
+There's a little self-serve visualization tool called 'vwebp' under the
+examples/ directory. It uses OpenGL to open a simple drawing window and show
+a decoded WebP file. It's not yet integrated in the automake build system, but
+you can try to manually compile it using the recommendations below.
+
+Usage: vwebp in_file [options]
+
+Decodes the WebP image file and visualize it using OpenGL
+Options are:
+  -version  .... print version number and exit
+  -noicc ....... don't use the icc profile if present
+  -nofancy ..... don't use the fancy YUV420 upscaler
+  -nofilter .... disable in-loop filtering
+  -dither <int>  dithering strength (0..100), default=50
+  -noalphadither disable alpha plane dithering
+  -mt .......... use multi-threading
+  -info ........ print info
+  -h     ....... this help message
+
+Keyboard shortcuts:
+  'c' ................ toggle use of color profile
+  'i' ................ overlay file information
+  'q' / 'Q' / ESC .... quit
+
+Building:
+---------
+
+Prerequisites:
+1) OpenGL & OpenGL Utility Toolkit (GLUT)
+  Linux:
+    $ sudo apt-get install freeglut3-dev mesa-common-dev
+  Mac + XCode:
+    - These libraries should be available in the OpenGL / GLUT frameworks.
+  Windows:
+    http://freeglut.sourceforge.net/index.php#download
+
+2) (Optional) qcms (Quick Color Management System)
+  i. Download qcms from Mozilla / Chromium:
+    http://hg.mozilla.org/mozilla-central/file/0e7639e3bdfb/gfx/qcms
+    http://src.chromium.org/viewvc/chrome/trunk/src/third_party/qcms
+  ii. Build and archive the source files as libqcms.a / qcms.lib
+  iii. Update makefile.unix / Makefile.vc
+    a) Define WEBP_HAVE_QCMS
+    b) Update include / library paths to reference the qcms directory.
+
+Build using makefile.unix / Makefile.vc:
+$ make -f makefile.unix examples/vwebp
+> nmake /f Makefile.vc CFG=release-static \
+    ../obj/x64/release-static/bin/vwebp.exe
+
+Animated GIF conversion:
+========================
+Animated GIF files can be converted to WebP files with animation using the
+gif2webp utility available under examples/. The files can then be viewed using
+vwebp.
+
+Usage:
+ gif2webp [options] gif_file -o webp_file
+Options:
+  -h / -help  ............ this help
+  -lossy ................. encode image using lossy compression
+  -mixed ................. for each frame in the image, pick lossy
+                           or lossless compression heuristically
+  -q <float> ............. quality factor (0:small..100:big)
+  -m <int> ............... compression method (0=fast, 6=slowest)
+  -kmin <int> ............ min distance between key frames
+  -kmax <int> ............ max distance between key frames
+  -f <int> ............... filter strength (0=off..100)
+  -metadata <string> ..... comma separated list of metadata to
+                           copy from the input to the output if present
+                           Valid values: all, none, icc, xmp (default)
+  -mt .................... use multi-threading if available
+
+  -version ............... print version number and exit
+  -v ..................... verbose
+  -quiet ................. don't print anything
+
+Building:
+---------
+With the libgif development files installed, gif2webp can be built using
+makefile.unix:
+$ make -f makefile.unix examples/gif2webp
+
+or using autoconf:
+$ ./configure --enable-everything
+$ make
+
+Encoding API:
+=============
+
+The main encoding functions are available in the header src/webp/encode.h
+The ready-to-use ones are:
+size_t WebPEncodeRGB(const uint8_t* rgb, int width, int height, int stride,
+                     float quality_factor, uint8_t** output);
+size_t WebPEncodeBGR(const uint8_t* bgr, int width, int height, int stride,
+                     float quality_factor, uint8_t** output);
+size_t WebPEncodeRGBA(const uint8_t* rgba, int width, int height, int stride,
+                      float quality_factor, uint8_t** output);
+size_t WebPEncodeBGRA(const uint8_t* bgra, int width, int height, int stride,
+                      float quality_factor, uint8_t** output);
+
+They will convert raw RGB samples to a WebP data. The only control supplied
+is the quality factor.
+
+There are some variants for using the lossless format:
+
+size_t WebPEncodeLosslessRGB(const uint8_t* rgb, int width, int height,
+                             int stride, uint8_t** output);
+size_t WebPEncodeLosslessBGR(const uint8_t* bgr, int width, int height,
+                             int stride, uint8_t** output);
+size_t WebPEncodeLosslessRGBA(const uint8_t* rgba, int width, int height,
+                              int stride, uint8_t** output);
+size_t WebPEncodeLosslessBGRA(const uint8_t* bgra, int width, int height,
+                              int stride, uint8_t** output);
+
+Of course in this case, no quality factor is needed since the compression
+occurs without loss of the input values, at the expense of larger output sizes.
+
+Advanced encoding API:
+----------------------
+
+A more advanced API is based on the WebPConfig and WebPPicture structures.
+
+WebPConfig contains the encoding settings and is not tied to a particular
+picture.
+WebPPicture contains input data, on which some WebPConfig will be used for
+compression.
+The encoding flow looks like:
+
+-------------------------------------- BEGIN PSEUDO EXAMPLE
+
+#include <webp/encode.h>
+
+  // Setup a config, starting form a preset and tuning some additional
+  // parameters
+  WebPConfig config;
+  if (!WebPConfigPreset(&config, WEBP_PRESET_PHOTO, quality_factor))
+    return 0;   // version error
+  }
+  // ... additional tuning
+  config.sns_strength = 90;
+  config.filter_sharpness = 6;
+  config_error = WebPValidateConfig(&config);  // not mandatory, but useful
+
+  // Setup the input data
+  WebPPicture pic;
+  if (!WebPPictureInit(&pic)) {
+    return 0;  // version error
+  }
+  pic.width = width;
+  pic.height = height;
+  // allocated picture of dimension width x height
+  if (!WebPPictureAllocate(&pic)) {
+    return 0;   // memory error
+  }
+  // at this point, 'pic' has been initialized as a container,
+  // and can receive the Y/U/V samples.
+  // Alternatively, one could use ready-made import functions like
+  // WebPPictureImportRGB(), which will take care of memory allocation.
+  // In any case, past this point, one will have to call
+  // WebPPictureFree(&pic) to reclaim memory.
+
+  // Set up a byte-output write method. WebPMemoryWriter, for instance.
+  WebPMemoryWriter wrt;
+  WebPMemoryWriterInit(&wrt);     // initialize 'wrt'
+
+  pic.writer = MyFileWriter;
+  pic.custom_ptr = my_opaque_structure_to_make_MyFileWriter_work;
+
+  // Compress!
+  int ok = WebPEncode(&config, &pic);   // ok = 0 => error occurred!
+  WebPPictureFree(&pic);  // must be called independently of the 'ok' result.
+
+  // output data should have been handled by the writer at that point.
+  // -> compressed data is the memory buffer described by wrt.mem / wrt.size
+
+  // deallocate the memory used by compressed data
+  WebPMemoryWriterClear(&wrt);
+
+-------------------------------------- END PSEUDO EXAMPLE
+
+Decoding API:
+=============
+
+This is mainly just one function to call:
+
+#include "webp/decode.h"
+uint8_t* WebPDecodeRGB(const uint8_t* data, size_t data_size,
+                       int* width, int* height);
+
+Please have a look at the file src/webp/decode.h for the details.
+There are variants for decoding in BGR/RGBA/ARGB/BGRA order, along with
+decoding to raw Y'CbCr samples. One can also decode the image directly into a
+pre-allocated buffer.
+
+To detect a WebP file and gather the picture's dimensions, the function:
+  int WebPGetInfo(const uint8_t* data, size_t data_size,
+                  int* width, int* height);
+is supplied. No decoding is involved when using it.
+
+Incremental decoding API:
+=========================
+
+In the case when data is being progressively transmitted, pictures can still
+be incrementally decoded using a slightly more complicated API. Decoder state
+is stored into an instance of the WebPIDecoder object. This object can be
+created with the purpose of decoding either RGB or Y'CbCr samples.
+For instance:
+
+  WebPDecBuffer buffer;
+  WebPInitDecBuffer(&buffer);
+  buffer.colorspace = MODE_BGR;
+  ...
+  WebPIDecoder* idec = WebPINewDecoder(&buffer);
+
+As data is made progressively available, this incremental-decoder object
+can be used to decode the picture further. There are two (mutually exclusive)
+ways to pass freshly arrived data:
+
+either by appending the fresh bytes:
+
+  WebPIAppend(idec, fresh_data, size_of_fresh_data);
+
+or by just mentioning the new size of the transmitted data:
+
+  WebPIUpdate(idec, buffer, size_of_transmitted_buffer);
+
+Note that 'buffer' can be modified between each call to WebPIUpdate, in
+particular when the buffer is resized to accommodate larger data.
+
+These functions will return the decoding status: either VP8_STATUS_SUSPENDED if
+decoding is not finished yet or VP8_STATUS_OK when decoding is done. Any other
+status is an error condition.
+
+The 'idec' object must always be released (even upon an error condition) by
+calling: WebPDelete(idec).
+
+To retrieve partially decoded picture samples, one must use the corresponding
+method: WebPIDecGetRGB or WebPIDecGetYUVA.
+It will return the last displayable pixel row.
+
+Lastly, note that decoding can also be performed into a pre-allocated pixel
+buffer. This buffer must be passed when creating a WebPIDecoder, calling
+WebPINewRGB() or WebPINewYUVA().
+
+Please have a look at the src/webp/decode.h header for further details.
+
+Advanced Decoding API:
+======================
+
+WebP decoding supports an advanced API which provides on-the-fly cropping and
+rescaling, something of great usefulness on memory-constrained environments like
+mobile phones. Basically, the memory usage will scale with the output's size,
+not the input's, when one only needs a quick preview or a zoomed in portion of
+an otherwise too-large picture. Some CPU can be saved too, incidentally.
+
+-------------------------------------- BEGIN PSEUDO EXAMPLE
+     // A) Init a configuration object
+     WebPDecoderConfig config;
+     CHECK(WebPInitDecoderConfig(&config));
+
+     // B) optional: retrieve the bitstream's features.
+     CHECK(WebPGetFeatures(data, data_size, &config.input) == VP8_STATUS_OK);
+
+     // C) Adjust 'config' options, if needed
+     config.options.no_fancy_upsampling = 1;
+     config.options.use_scaling = 1;
+     config.options.scaled_width = scaledWidth();
+     config.options.scaled_height = scaledHeight();
+     // etc.
+
+     // D) Specify 'config' output options for specifying output colorspace.
+     // Optionally the external image decode buffer can also be specified.
+     config.output.colorspace = MODE_BGRA;
+     // Optionally, the config.output can be pointed to an external buffer as
+     // well for decoding the image. This externally supplied memory buffer
+     // should be big enough to store the decoded picture.
+     config.output.u.RGBA.rgba = (uint8_t*) memory_buffer;
+     config.output.u.RGBA.stride = scanline_stride;
+     config.output.u.RGBA.size = total_size_of_the_memory_buffer;
+     config.output.is_external_memory = 1;
+
+     // E) Decode the WebP image. There are two variants w.r.t decoding image.
+     // The first one (E.1) decodes the full image and the second one (E.2) is
+     // used to incrementally decode the image using small input buffers.
+     // Any one of these steps can be used to decode the WebP image.
+
+     // E.1) Decode full image.
+     CHECK(WebPDecode(data, data_size, &config) == VP8_STATUS_OK);
+
+     // E.2) Decode image incrementally.
+     WebPIDecoder* const idec = WebPIDecode(NULL, NULL, &config);
+     CHECK(idec != NULL);
+     while (bytes_remaining > 0) {
+       VP8StatusCode status = WebPIAppend(idec, input, bytes_read);
+       if (status == VP8_STATUS_OK || status == VP8_STATUS_SUSPENDED) {
+         bytes_remaining -= bytes_read;
+       } else {
+         break;
+       }
+     }
+     WebPIDelete(idec);
+
+     // F) Decoded image is now in config.output (and config.output.u.RGBA).
+     // It can be saved, displayed or otherwise processed.
+
+     // G) Reclaim memory allocated in config's object. It's safe to call
+     // this function even if the memory is external and wasn't allocated
+     // by WebPDecode().
+     WebPFreeDecBuffer(&config.output);
+
+-------------------------------------- END PSEUDO EXAMPLE
+
+Bugs:
+=====
+
+Please report all bugs to our issue tracker:
+    http://code.google.com/p/webp/issues
+Patches welcome! See this page to get started:
+    http://www.webmproject.org/code/contribute/submitting-patches/
+
+Discuss:
+========
+
+Email: webp-discuss at webmproject.org
+Web: http://groups.google.com/a/webmproject.org/group/webp-discuss
diff --git a/Source/LibWebP/README.mux b/Source/LibWebP/README.mux
new file mode 100644
index 0000000..f5a972d
--- /dev/null
+++ b/Source/LibWebP/README.mux
@@ -0,0 +1,210 @@
+          __   __  ____  ____  ____  __ __  _     __ __
+         /  \\/  \/  _ \/  _ \/  _ \/  \  \/ \___/_ / _\
+         \       /   __/  _  \   __/      /  /  (_/  /__
+          \__\__/\_____/_____/__/  \__//_/\_____/__/___/v0.2.2
+
+
+Description:
+============
+
+WebPMux: set of two libraries 'Mux' and 'Demux' for creation, extraction and
+manipulation of an extended format WebP file, which can have features like
+color profile, metadata and animation. Reference command-line tools 'webpmux'
+and 'vwebp' as well as the WebP container specification
+'doc/webp-container-spec.txt' are also provided in this package.
+
+WebP Mux tool:
+==============
+
+The examples/ directory contains a tool (webpmux) for manipulating WebP
+files. The webpmux tool can be used to create an extended format WebP file and
+also to extract or strip relevant data from such a file.
+
+A list of options is available using the -help command line flag:
+
+> webpmux -help
+Usage: webpmux -get GET_OPTIONS INPUT -o OUTPUT
+       webpmux -set SET_OPTIONS INPUT -o OUTPUT
+       webpmux -strip STRIP_OPTIONS INPUT -o OUTPUT
+       webpmux -frame FRAME_OPTIONS [-frame...] [-loop LOOP_COUNT]
+               [-bgcolor BACKGROUND_COLOR] -o OUTPUT
+       webpmux -info INPUT
+       webpmux [-h|-help]
+       webpmux -version
+
+GET_OPTIONS:
+ Extract relevant data:
+   icc       get ICC profile
+   exif      get EXIF metadata
+   xmp       get XMP metadata
+   frame n   get nth frame
+
+SET_OPTIONS:
+ Set color profile/metadata:
+   icc  file.icc     set ICC profile
+   exif file.exif    set EXIF metadata
+   xmp  file.xmp     set XMP metadata
+   where:    'file.icc' contains the ICC profile to be set,
+             'file.exif' contains the EXIF metadata to be set
+             'file.xmp' contains the XMP metadata to be set
+
+STRIP_OPTIONS:
+ Strip color profile/metadata:
+   icc       strip ICC profile
+   exif      strip EXIF metadata
+   xmp       strip XMP metadata
+
+FRAME_OPTIONS(i):
+ Create animation:
+   file_i +di+[xi+yi[+mi[bi]]]
+   where:    'file_i' is the i'th animation frame (WebP format),
+             'di' is the pause duration before next frame,
+             'xi','yi' specify the image offset for this frame,
+             'mi' is the dispose method for this frame (0 or 1),
+             'bi' is the blending method for this frame (+b or -b)
+
+LOOP_COUNT:
+ Number of times to repeat the animation.
+ Valid range is 0 to 65535 [Default: 0 (infinite)].
+
+BACKGROUND_COLOR:
+ Background color of the canvas.
+  A,R,G,B
+  where:    'A', 'R', 'G' and 'B' are integers in the range 0 to 255 specifying
+            the Alpha, Red, Green and Blue component values respectively
+            [Default: 255,255,255,255]
+
+INPUT & OUTPUT are in WebP format.
+
+Note: The nature of EXIF, XMP and ICC data is not checked and is assumed to be
+valid.
+
+Visualization tool:
+===================
+
+The examples/ directory also contains a tool (vwebp) for viewing WebP files.
+It decodes the image and visualizes it using OpenGL. See the libwebp README
+for details on building and running this program.
+
+Mux API:
+========
+The Mux API contains methods for adding data to and reading data from WebP
+files. This API currently supports XMP/EXIF metadata, ICC profile and animation.
+Other features may be added in subsequent releases.
+
+Example#1 (pseudo code): Creating a WebPMux object with image data, color
+profile and XMP metadata.
+
+  int copy_data = 0;
+  WebPMux* mux = WebPMuxNew();
+  // ... (Prepare image data).
+  WebPMuxSetImage(mux, &image, copy_data);
+  // ... (Prepare ICC profile data).
+  WebPMuxSetChunk(mux, "ICCP", &icc_profile, copy_data);
+  // ... (Prepare XMP metadata).
+  WebPMuxSetChunk(mux, "XMP ", &xmp, copy_data);
+  // Get data from mux in WebP RIFF format.
+  WebPMuxAssemble(mux, &output_data);
+  WebPMuxDelete(mux);
+  // ... (Consume output_data; e.g. write output_data.bytes to file).
+  WebPDataClear(&output_data);
+
+
+Example#2 (pseudo code): Get image and color profile data from a WebP file.
+
+  int copy_data = 0;
+  // ... (Read data from file).
+  WebPMux* mux = WebPMuxCreate(&data, copy_data);
+  WebPMuxGetFrame(mux, 1, &image);
+  // ... (Consume image; e.g. call WebPDecode() to decode the data).
+  WebPMuxGetChunk(mux, "ICCP", &icc_profile);
+  // ... (Consume icc_profile).
+  WebPMuxDelete(mux);
+  free(data);
+
+
+For a detailed Mux API reference, please refer to the header file
+(src/webp/mux.h).
+
+Demux API:
+==========
+The Demux API enables extraction of images and extended format data from
+WebP files. This API currently supports reading of XMP/EXIF metadata, ICC
+profile and animated images. Other features may be added in subsequent
+releases.
+
+Code example: Demuxing WebP data to extract all the frames, ICC profile
+and EXIF/XMP metadata.
+
+  WebPDemuxer* demux = WebPDemux(&webp_data);
+  uint32_t width = WebPDemuxGetI(demux, WEBP_FF_CANVAS_WIDTH);
+  uint32_t height = WebPDemuxGetI(demux, WEBP_FF_CANVAS_HEIGHT);
+  // ... (Get information about the features present in the WebP file).
+  uint32_t flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS);
+
+  // ... (Iterate over all frames).
+  WebPIterator iter;
+  if (WebPDemuxGetFrame(demux, 1, &iter)) {
+    do {
+      // ... (Consume 'iter'; e.g. Decode 'iter.fragment' with WebPDecode(),
+      // ... and get other frame properties like width, height, offsets etc.
+      // ... see 'struct WebPIterator' below for more info).
+    } while (WebPDemuxNextFrame(&iter));
+    WebPDemuxReleaseIterator(&iter);
+  }
+
+  // ... (Extract metadata).
+  WebPChunkIterator chunk_iter;
+  if (flags & ICCP_FLAG) WebPDemuxGetChunk(demux, "ICCP", 1, &chunk_iter);
+  // ... (Consume the ICC profile in 'chunk_iter.chunk').
+  WebPDemuxReleaseChunkIterator(&chunk_iter);
+  if (flags & EXIF_FLAG) WebPDemuxGetChunk(demux, "EXIF", 1, &chunk_iter);
+  // ... (Consume the EXIF metadata in 'chunk_iter.chunk').
+  WebPDemuxReleaseChunkIterator(&chunk_iter);
+  if (flags & XMP_FLAG) WebPDemuxGetChunk(demux, "XMP ", 1, &chunk_iter);
+  // ... (Consume the XMP metadata in 'chunk_iter.chunk').
+  WebPDemuxReleaseChunkIterator(&chunk_iter);
+  WebPDemuxDelete(demux);
+
+
+For a detailed Demux API reference, please refer to the header file
+(src/webp/demux.h).
+
+AnimEncoder API:
+================
+The AnimEncoder API can be used to create animated WebP images.
+
+Code example:
+
+  WebPAnimEncoderOptions enc_options;
+  WebPAnimEncoderOptionsInit(&enc_options);
+  // ... (Tune 'enc_options' as needed).
+  WebPAnimEncoder* enc = WebPAnimEncoderNew(width, height, &enc_options);
+  while(<there are more frames>) {
+    WebPConfig config;
+    WebPConfigInit(&config);
+    // ... (Tune 'config' as needed).
+    WebPAnimEncoderAdd(enc, frame, duration, &config);
+  }
+  WebPAnimEncoderAssemble(enc, webp_data);
+  WebPAnimEncoderDelete(enc);
+  // ... (Write the 'webp_data' to a file, or re-mux it further).
+
+
+For a detailed AnimEncoder API reference, please refer to the header file
+(src/webp/mux.h).
+
+
+Bugs:
+=====
+
+Please report all bugs to our issue tracker:
+    http://code.google.com/p/webp/issues
+Patches welcome! See this page to get started:
+    http://www.webmproject.org/code/contribute/submitting-patches/
+
+Discuss:
+========
+
+Email: webp-discuss at webmproject.org
+Web: http://groups.google.com/a/webmproject.org/group/webp-discuss
diff --git a/Source/LibWebP/src/dec/alphai.h b/Source/LibWebP/src/dec/alphai.h
new file mode 100644
index 0000000..16a9322
--- /dev/null
+++ b/Source/LibWebP/src/dec/alphai.h
@@ -0,0 +1,55 @@
+// Copyright 2013 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Alpha decoder: internal header.
+//
+// Author: Urvang (urvang at google.com)
+
+#ifndef WEBP_DEC_ALPHAI_H_
+#define WEBP_DEC_ALPHAI_H_
+
+#include "./webpi.h"
+#include "../utils/filters.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct VP8LDecoder;  // Defined in dec/vp8li.h.
+
+typedef struct ALPHDecoder ALPHDecoder;
+struct ALPHDecoder {
+  int width_;
+  int height_;
+  int method_;
+  WEBP_FILTER_TYPE filter_;
+  int pre_processing_;
+  struct VP8LDecoder* vp8l_dec_;
+  VP8Io io_;
+  int use_8b_decode;  // Although alpha channel requires only 1 byte per
+                      // pixel, sometimes VP8LDecoder may need to allocate
+                      // 4 bytes per pixel internally during decode.
+};
+
+//------------------------------------------------------------------------------
+// internal functions. Not public.
+
+// Allocates a new alpha decoder instance.
+ALPHDecoder* ALPHNew(void);
+
+// Clears and deallocates an alpha decoder instance.
+void ALPHDelete(ALPHDecoder* const dec);
+
+//------------------------------------------------------------------------------
+
+#ifdef __cplusplus
+}    // extern "C"
+#endif
+
+#endif  /* WEBP_DEC_ALPHAI_H_ */
diff --git a/Source/LibWebP/src/dec/dec.alpha.c b/Source/LibWebP/src/dec/dec.alpha.c
new file mode 100644
index 0000000..2b6756e
--- /dev/null
+++ b/Source/LibWebP/src/dec/dec.alpha.c
@@ -0,0 +1,167 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Alpha-plane decompression.
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include <stdlib.h>
+#include "./alphai.h"
+#include "./vp8i.h"
+#include "./vp8li.h"
+#include "../dsp/dsp.h"
+#include "../utils/quant_levels_dec.h"
+#include "../utils/utils.h"
+#include "../webp/format_constants.h"
+
+//------------------------------------------------------------------------------
+// ALPHDecoder object.
+
+ALPHDecoder* ALPHNew(void) {
+  ALPHDecoder* const dec = (ALPHDecoder*)WebPSafeCalloc(1ULL, sizeof(*dec));
+  return dec;
+}
+
+void ALPHDelete(ALPHDecoder* const dec) {
+  if (dec != NULL) {
+    VP8LDelete(dec->vp8l_dec_);
+    dec->vp8l_dec_ = NULL;
+    WebPSafeFree(dec);
+  }
+}
+
+//------------------------------------------------------------------------------
+// Decoding.
+
+// Initialize alpha decoding by parsing the alpha header and decoding the image
+// header for alpha data stored using lossless compression.
+// Returns false in case of error in alpha header (data too short, invalid
+// compression method or filter, error in lossless header data etc).
+static int ALPHInit(ALPHDecoder* const dec, const uint8_t* data,
+                    size_t data_size, int width, int height, uint8_t* output) {
+  int ok = 0;
+  const uint8_t* const alpha_data = data + ALPHA_HEADER_LEN;
+  const size_t alpha_data_size = data_size - ALPHA_HEADER_LEN;
+  int rsrv;
+
+  assert(width > 0 && height > 0);
+  assert(data != NULL && output != NULL);
+
+  dec->width_ = width;
+  dec->height_ = height;
+
+  if (data_size <= ALPHA_HEADER_LEN) {
+    return 0;
+  }
+
+  dec->method_ = (data[0] >> 0) & 0x03;
+  dec->filter_ = (data[0] >> 2) & 0x03;
+  dec->pre_processing_ = (data[0] >> 4) & 0x03;
+  rsrv = (data[0] >> 6) & 0x03;
+  if (dec->method_ < ALPHA_NO_COMPRESSION ||
+      dec->method_ > ALPHA_LOSSLESS_COMPRESSION ||
+      dec->filter_ >= WEBP_FILTER_LAST ||
+      dec->pre_processing_ > ALPHA_PREPROCESSED_LEVELS ||
+      rsrv != 0) {
+    return 0;
+  }
+
+  if (dec->method_ == ALPHA_NO_COMPRESSION) {
+    const size_t alpha_decoded_size = dec->width_ * dec->height_;
+    ok = (alpha_data_size >= alpha_decoded_size);
+  } else {
+    assert(dec->method_ == ALPHA_LOSSLESS_COMPRESSION);
+    ok = VP8LDecodeAlphaHeader(dec, alpha_data, alpha_data_size, output);
+  }
+  VP8FiltersInit();
+  return ok;
+}
+
+// Decodes, unfilters and dequantizes *at least* 'num_rows' rows of alpha
+// starting from row number 'row'. It assumes that rows up to (row - 1) have
+// already been decoded.
+// Returns false in case of bitstream error.
+static int ALPHDecode(VP8Decoder* const dec, int row, int num_rows) {
+  ALPHDecoder* const alph_dec = dec->alph_dec_;
+  const int width = alph_dec->width_;
+  const int height = alph_dec->height_;
+  WebPUnfilterFunc unfilter_func = WebPUnfilters[alph_dec->filter_];
+  uint8_t* const output = dec->alpha_plane_;
+  if (alph_dec->method_ == ALPHA_NO_COMPRESSION) {
+    const size_t offset = row * width;
+    const size_t num_pixels = num_rows * width;
+    assert(dec->alpha_data_size_ >= ALPHA_HEADER_LEN + offset + num_pixels);
+    memcpy(dec->alpha_plane_ + offset,
+           dec->alpha_data_ + ALPHA_HEADER_LEN + offset, num_pixels);
+  } else {  // alph_dec->method_ == ALPHA_LOSSLESS_COMPRESSION
+    assert(alph_dec->vp8l_dec_ != NULL);
+    if (!VP8LDecodeAlphaImageStream(alph_dec, row + num_rows)) {
+      return 0;
+    }
+  }
+
+  if (unfilter_func != NULL) {
+    unfilter_func(width, height, width, row, num_rows, output);
+  }
+
+  if (row + num_rows == dec->pic_hdr_.height_) {
+    dec->is_alpha_decoded_ = 1;
+  }
+  return 1;
+}
+
+//------------------------------------------------------------------------------
+// Main entry point.
+
+const uint8_t* VP8DecompressAlphaRows(VP8Decoder* const dec,
+                                      int row, int num_rows) {
+  const int width = dec->pic_hdr_.width_;
+  const int height = dec->pic_hdr_.height_;
+
+  if (row < 0 || num_rows <= 0 || row + num_rows > height) {
+    return NULL;    // sanity check.
+  }
+
+  if (row == 0) {
+    // Initialize decoding.
+    assert(dec->alpha_plane_ != NULL);
+    dec->alph_dec_ = ALPHNew();
+    if (dec->alph_dec_ == NULL) return NULL;
+    if (!ALPHInit(dec->alph_dec_, dec->alpha_data_, dec->alpha_data_size_,
+                  width, height, dec->alpha_plane_)) {
+      ALPHDelete(dec->alph_dec_);
+      dec->alph_dec_ = NULL;
+      return NULL;
+    }
+    // if we allowed use of alpha dithering, check whether it's needed at all
+    if (dec->alph_dec_->pre_processing_ != ALPHA_PREPROCESSED_LEVELS) {
+      dec->alpha_dithering_ = 0;  // disable dithering
+    } else {
+      num_rows = height;          // decode everything in one pass
+    }
+  }
+
+  if (!dec->is_alpha_decoded_) {
+    int ok = 0;
+    assert(dec->alph_dec_ != NULL);
+    ok = ALPHDecode(dec, row, num_rows);
+    if (ok && dec->alpha_dithering_ > 0) {
+      ok = WebPDequantizeLevels(dec->alpha_plane_, width, height,
+                                dec->alpha_dithering_);
+    }
+    if (!ok || dec->is_alpha_decoded_) {
+      ALPHDelete(dec->alph_dec_);
+      dec->alph_dec_ = NULL;
+    }
+    if (!ok) return NULL;  // Error.
+  }
+
+  // Return a pointer to the current decoded row.
+  return dec->alpha_plane_ + row * width;
+}
diff --git a/Source/LibWebP/src/dec/dec.buffer.c b/Source/LibWebP/src/dec/dec.buffer.c
new file mode 100644
index 0000000..dbbc5f2
--- /dev/null
+++ b/Source/LibWebP/src/dec/dec.buffer.c
@@ -0,0 +1,249 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Everything about WebPDecBuffer
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include <stdlib.h>
+
+#include "./vp8i.h"
+#include "./webpi.h"
+#include "../utils/utils.h"
+
+//------------------------------------------------------------------------------
+// WebPDecBuffer
+
+// Number of bytes per pixel for the different color-spaces.
+static const int kModeBpp[MODE_LAST] = {
+  3, 4, 3, 4, 4, 2, 2,
+  4, 4, 4, 2,    // pre-multiplied modes
+  1, 1 };
+
+// Check that webp_csp_mode is within the bounds of WEBP_CSP_MODE.
+// Convert to an integer to handle both the unsigned/signed enum cases
+// without the need for casting to remove type limit warnings.
+static int IsValidColorspace(int webp_csp_mode) {
+  return (webp_csp_mode >= MODE_RGB && webp_csp_mode < MODE_LAST);
+}
+
+static VP8StatusCode CheckDecBuffer(const WebPDecBuffer* const buffer) {
+  int ok = 1;
+  const WEBP_CSP_MODE mode = buffer->colorspace;
+  const int width = buffer->width;
+  const int height = buffer->height;
+  if (!IsValidColorspace(mode)) {
+    ok = 0;
+  } else if (!WebPIsRGBMode(mode)) {   // YUV checks
+    const WebPYUVABuffer* const buf = &buffer->u.YUVA;
+    const int y_stride = abs(buf->y_stride);
+    const int u_stride = abs(buf->u_stride);
+    const int v_stride = abs(buf->v_stride);
+    const int a_stride = abs(buf->a_stride);
+    const uint64_t y_size = (uint64_t)y_stride * height;
+    const uint64_t u_size = (uint64_t)u_stride * ((height + 1) / 2);
+    const uint64_t v_size = (uint64_t)v_stride * ((height + 1) / 2);
+    const uint64_t a_size = (uint64_t)a_stride * height;
+    ok &= (y_size <= buf->y_size);
+    ok &= (u_size <= buf->u_size);
+    ok &= (v_size <= buf->v_size);
+    ok &= (y_stride >= width);
+    ok &= (u_stride >= (width + 1) / 2);
+    ok &= (v_stride >= (width + 1) / 2);
+    ok &= (buf->y != NULL);
+    ok &= (buf->u != NULL);
+    ok &= (buf->v != NULL);
+    if (mode == MODE_YUVA) {
+      ok &= (a_stride >= width);
+      ok &= (a_size <= buf->a_size);
+      ok &= (buf->a != NULL);
+    }
+  } else {    // RGB checks
+    const WebPRGBABuffer* const buf = &buffer->u.RGBA;
+    const int stride = abs(buf->stride);
+    const uint64_t size = (uint64_t)stride * height;
+    ok &= (size <= buf->size);
+    ok &= (stride >= width * kModeBpp[mode]);
+    ok &= (buf->rgba != NULL);
+  }
+  return ok ? VP8_STATUS_OK : VP8_STATUS_INVALID_PARAM;
+}
+
+static VP8StatusCode AllocateBuffer(WebPDecBuffer* const buffer) {
+  const int w = buffer->width;
+  const int h = buffer->height;
+  const WEBP_CSP_MODE mode = buffer->colorspace;
+
+  if (w <= 0 || h <= 0 || !IsValidColorspace(mode)) {
+    return VP8_STATUS_INVALID_PARAM;
+  }
+
+  if (!buffer->is_external_memory && buffer->private_memory == NULL) {
+    uint8_t* output;
+    int uv_stride = 0, a_stride = 0;
+    uint64_t uv_size = 0, a_size = 0, total_size;
+    // We need memory and it hasn't been allocated yet.
+    // => initialize output buffer, now that dimensions are known.
+    const int stride = w * kModeBpp[mode];
+    const uint64_t size = (uint64_t)stride * h;
+
+    if (!WebPIsRGBMode(mode)) {
+      uv_stride = (w + 1) / 2;
+      uv_size = (uint64_t)uv_stride * ((h + 1) / 2);
+      if (mode == MODE_YUVA) {
+        a_stride = w;
+        a_size = (uint64_t)a_stride * h;
+      }
+    }
+    total_size = size + 2 * uv_size + a_size;
+
+    // Security/sanity checks
+    output = (uint8_t*)WebPSafeMalloc(total_size, sizeof(*output));
+    if (output == NULL) {
+      return VP8_STATUS_OUT_OF_MEMORY;
+    }
+    buffer->private_memory = output;
+
+    if (!WebPIsRGBMode(mode)) {   // YUVA initialization
+      WebPYUVABuffer* const buf = &buffer->u.YUVA;
+      buf->y = output;
+      buf->y_stride = stride;
+      buf->y_size = (size_t)size;
+      buf->u = output + size;
+      buf->u_stride = uv_stride;
+      buf->u_size = (size_t)uv_size;
+      buf->v = output + size + uv_size;
+      buf->v_stride = uv_stride;
+      buf->v_size = (size_t)uv_size;
+      if (mode == MODE_YUVA) {
+        buf->a = output + size + 2 * uv_size;
+      }
+      buf->a_size = (size_t)a_size;
+      buf->a_stride = a_stride;
+    } else {  // RGBA initialization
+      WebPRGBABuffer* const buf = &buffer->u.RGBA;
+      buf->rgba = output;
+      buf->stride = stride;
+      buf->size = (size_t)size;
+    }
+  }
+  return CheckDecBuffer(buffer);
+}
+
+VP8StatusCode WebPFlipBuffer(WebPDecBuffer* const buffer) {
+  if (buffer == NULL) {
+    return VP8_STATUS_INVALID_PARAM;
+  }
+  if (WebPIsRGBMode(buffer->colorspace)) {
+    WebPRGBABuffer* const buf = &buffer->u.RGBA;
+    buf->rgba += (buffer->height - 1) * buf->stride;
+    buf->stride = -buf->stride;
+  } else {
+    WebPYUVABuffer* const buf = &buffer->u.YUVA;
+    const int H = buffer->height;
+    buf->y += (H - 1) * buf->y_stride;
+    buf->y_stride = -buf->y_stride;
+    buf->u += ((H - 1) >> 1) * buf->u_stride;
+    buf->u_stride = -buf->u_stride;
+    buf->v += ((H - 1) >> 1) * buf->v_stride;
+    buf->v_stride = -buf->v_stride;
+    if (buf->a != NULL) {
+      buf->a += (H - 1) * buf->a_stride;
+      buf->a_stride = -buf->a_stride;
+    }
+  }
+  return VP8_STATUS_OK;
+}
+
+VP8StatusCode WebPAllocateDecBuffer(int w, int h,
+                                    const WebPDecoderOptions* const options,
+                                    WebPDecBuffer* const out) {
+  VP8StatusCode status;
+  if (out == NULL || w <= 0 || h <= 0) {
+    return VP8_STATUS_INVALID_PARAM;
+  }
+  if (options != NULL) {    // First, apply options if there is any.
+    if (options->use_cropping) {
+      const int cw = options->crop_width;
+      const int ch = options->crop_height;
+      const int x = options->crop_left & ~1;
+      const int y = options->crop_top & ~1;
+      if (x < 0 || y < 0 || cw <= 0 || ch <= 0 || x + cw > w || y + ch > h) {
+        return VP8_STATUS_INVALID_PARAM;   // out of frame boundary.
+      }
+      w = cw;
+      h = ch;
+    }
+    if (options->use_scaling) {
+      if (options->scaled_width <= 0 || options->scaled_height <= 0) {
+        return VP8_STATUS_INVALID_PARAM;
+      }
+      w = options->scaled_width;
+      h = options->scaled_height;
+    }
+  }
+  out->width = w;
+  out->height = h;
+
+  // Then, allocate buffer for real.
+  status = AllocateBuffer(out);
+  if (status != VP8_STATUS_OK) return status;
+
+  // Use the stride trick if vertical flip is needed.
+  if (options != NULL && options->flip) {
+    status = WebPFlipBuffer(out);
+  }
+  return status;
+}
+
+//------------------------------------------------------------------------------
+// constructors / destructors
+
+int WebPInitDecBufferInternal(WebPDecBuffer* buffer, int version) {
+  if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_DECODER_ABI_VERSION)) {
+    return 0;  // version mismatch
+  }
+  if (buffer == NULL) return 0;
+  memset(buffer, 0, sizeof(*buffer));
+  return 1;
+}
+
+void WebPFreeDecBuffer(WebPDecBuffer* buffer) {
+  if (buffer != NULL) {
+    if (!buffer->is_external_memory) {
+      WebPSafeFree(buffer->private_memory);
+    }
+    buffer->private_memory = NULL;
+  }
+}
+
+void WebPCopyDecBuffer(const WebPDecBuffer* const src,
+                       WebPDecBuffer* const dst) {
+  if (src != NULL && dst != NULL) {
+    *dst = *src;
+    if (src->private_memory != NULL) {
+      dst->is_external_memory = 1;   // dst buffer doesn't own the memory.
+      dst->private_memory = NULL;
+    }
+  }
+}
+
+// Copy and transfer ownership from src to dst (beware of parameter order!)
+void WebPGrabDecBuffer(WebPDecBuffer* const src, WebPDecBuffer* const dst) {
+  if (src != NULL && dst != NULL) {
+    *dst = *src;
+    if (src->private_memory != NULL) {
+      src->is_external_memory = 1;   // src relinquishes ownership
+      src->private_memory = NULL;
+    }
+  }
+}
+
+//------------------------------------------------------------------------------
+
diff --git a/Source/LibWebP/src/dec/dec.frame.c b/Source/LibWebP/src/dec/dec.frame.c
new file mode 100644
index 0000000..87750fb
--- /dev/null
+++ b/Source/LibWebP/src/dec/dec.frame.c
@@ -0,0 +1,827 @@
+// Copyright 2010 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Frame-reconstruction function. Memory allocation.
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include <stdlib.h>
+#include "./vp8i.h"
+#include "../utils/utils.h"
+
+#define ALIGN_CST (32 - 1)
+#define DO_ALIGN(PTR) ((uintptr_t)((PTR) + ALIGN_CST) & ~ALIGN_CST)
+
+static void ReconstructRow(const VP8Decoder* const dec,
+                           const VP8ThreadContext* ctx);  // TODO(skal): remove
+
+//------------------------------------------------------------------------------
+// Filtering
+
+// kFilterExtraRows[] = How many extra lines are needed on the MB boundary
+// for caching, given a filtering level.
+// Simple filter:  up to 2 luma samples are read and 1 is written.
+// Complex filter: up to 4 luma samples are read and 3 are written. Same for
+//                 U/V, so it's 8 samples total (because of the 2x upsampling).
+static const uint8_t kFilterExtraRows[3] = { 0, 2, 8 };
+
+static void DoFilter(const VP8Decoder* const dec, int mb_x, int mb_y) {
+  const VP8ThreadContext* const ctx = &dec->thread_ctx_;
+  const int cache_id = ctx->id_;
+  const int y_bps = dec->cache_y_stride_;
+  const VP8FInfo* const f_info = ctx->f_info_ + mb_x;
+  uint8_t* const y_dst = dec->cache_y_ + cache_id * 16 * y_bps + mb_x * 16;
+  const int ilevel = f_info->f_ilevel_;
+  const int limit = f_info->f_limit_;
+  if (limit == 0) {
+    return;
+  }
+  assert(limit >= 3);
+  if (dec->filter_type_ == 1) {   // simple
+    if (mb_x > 0) {
+      VP8SimpleHFilter16(y_dst, y_bps, limit + 4);
+    }
+    if (f_info->f_inner_) {
+      VP8SimpleHFilter16i(y_dst, y_bps, limit);
+    }
+    if (mb_y > 0) {
+      VP8SimpleVFilter16(y_dst, y_bps, limit + 4);
+    }
+    if (f_info->f_inner_) {
+      VP8SimpleVFilter16i(y_dst, y_bps, limit);
+    }
+  } else {    // complex
+    const int uv_bps = dec->cache_uv_stride_;
+    uint8_t* const u_dst = dec->cache_u_ + cache_id * 8 * uv_bps + mb_x * 8;
+    uint8_t* const v_dst = dec->cache_v_ + cache_id * 8 * uv_bps + mb_x * 8;
+    const int hev_thresh = f_info->hev_thresh_;
+    if (mb_x > 0) {
+      VP8HFilter16(y_dst, y_bps, limit + 4, ilevel, hev_thresh);
+      VP8HFilter8(u_dst, v_dst, uv_bps, limit + 4, ilevel, hev_thresh);
+    }
+    if (f_info->f_inner_) {
+      VP8HFilter16i(y_dst, y_bps, limit, ilevel, hev_thresh);
+      VP8HFilter8i(u_dst, v_dst, uv_bps, limit, ilevel, hev_thresh);
+    }
+    if (mb_y > 0) {
+      VP8VFilter16(y_dst, y_bps, limit + 4, ilevel, hev_thresh);
+      VP8VFilter8(u_dst, v_dst, uv_bps, limit + 4, ilevel, hev_thresh);
+    }
+    if (f_info->f_inner_) {
+      VP8VFilter16i(y_dst, y_bps, limit, ilevel, hev_thresh);
+      VP8VFilter8i(u_dst, v_dst, uv_bps, limit, ilevel, hev_thresh);
+    }
+  }
+}
+
+// Filter the decoded macroblock row (if needed)
+static void FilterRow(const VP8Decoder* const dec) {
+  int mb_x;
+  const int mb_y = dec->thread_ctx_.mb_y_;
+  assert(dec->thread_ctx_.filter_row_);
+  for (mb_x = dec->tl_mb_x_; mb_x < dec->br_mb_x_; ++mb_x) {
+    DoFilter(dec, mb_x, mb_y);
+  }
+}
+
+//------------------------------------------------------------------------------
+// Precompute the filtering strength for each segment and each i4x4/i16x16 mode.
+
+static void PrecomputeFilterStrengths(VP8Decoder* const dec) {
+  if (dec->filter_type_ > 0) {
+    int s;
+    const VP8FilterHeader* const hdr = &dec->filter_hdr_;
+    for (s = 0; s < NUM_MB_SEGMENTS; ++s) {
+      int i4x4;
+      // First, compute the initial level
+      int base_level;
+      if (dec->segment_hdr_.use_segment_) {
+        base_level = dec->segment_hdr_.filter_strength_[s];
+        if (!dec->segment_hdr_.absolute_delta_) {
+          base_level += hdr->level_;
+        }
+      } else {
+        base_level = hdr->level_;
+      }
+      for (i4x4 = 0; i4x4 <= 1; ++i4x4) {
+        VP8FInfo* const info = &dec->fstrengths_[s][i4x4];
+        int level = base_level;
+        if (hdr->use_lf_delta_) {
+          // TODO(skal): only CURRENT is handled for now.
+          level += hdr->ref_lf_delta_[0];
+          if (i4x4) {
+            level += hdr->mode_lf_delta_[0];
+          }
+        }
+        level = (level < 0) ? 0 : (level > 63) ? 63 : level;
+        if (level > 0) {
+          int ilevel = level;
+          if (hdr->sharpness_ > 0) {
+            if (hdr->sharpness_ > 4) {
+              ilevel >>= 2;
+            } else {
+              ilevel >>= 1;
+            }
+            if (ilevel > 9 - hdr->sharpness_) {
+              ilevel = 9 - hdr->sharpness_;
+            }
+          }
+          if (ilevel < 1) ilevel = 1;
+          info->f_ilevel_ = ilevel;
+          info->f_limit_ = 2 * level + ilevel;
+          info->hev_thresh_ = (level >= 40) ? 2 : (level >= 15) ? 1 : 0;
+        } else {
+          info->f_limit_ = 0;  // no filtering
+        }
+        info->f_inner_ = i4x4;
+      }
+    }
+  }
+}
+
+//------------------------------------------------------------------------------
+// Dithering
+
+#define DITHER_AMP_TAB_SIZE 12
+static const int kQuantToDitherAmp[DITHER_AMP_TAB_SIZE] = {
+  // roughly, it's dqm->uv_mat_[1]
+  8, 7, 6, 4, 4, 2, 2, 2, 1, 1, 1, 1
+};
+
+void VP8InitDithering(const WebPDecoderOptions* const options,
+                      VP8Decoder* const dec) {
+  assert(dec != NULL);
+  if (options != NULL) {
+    const int d = options->dithering_strength;
+    const int max_amp = (1 << VP8_RANDOM_DITHER_FIX) - 1;
+    const int f = (d < 0) ? 0 : (d > 100) ? max_amp : (d * max_amp / 100);
+    if (f > 0) {
+      int s;
+      int all_amp = 0;
+      for (s = 0; s < NUM_MB_SEGMENTS; ++s) {
+        VP8QuantMatrix* const dqm = &dec->dqm_[s];
+        if (dqm->uv_quant_ < DITHER_AMP_TAB_SIZE) {
+          // TODO(skal): should we specially dither more for uv_quant_ < 0?
+          const int idx = (dqm->uv_quant_ < 0) ? 0 : dqm->uv_quant_;
+          dqm->dither_ = (f * kQuantToDitherAmp[idx]) >> 3;
+        }
+        all_amp |= dqm->dither_;
+      }
+      if (all_amp != 0) {
+        VP8InitRandom(&dec->dithering_rg_, 1.0f);
+        dec->dither_ = 1;
+      }
+    }
+    // potentially allow alpha dithering
+    dec->alpha_dithering_ = options->alpha_dithering_strength;
+    if (dec->alpha_dithering_ > 100) {
+      dec->alpha_dithering_ = 100;
+    } else if (dec->alpha_dithering_ < 0) {
+      dec->alpha_dithering_ = 0;
+    }
+  }
+}
+
+// minimal amp that will provide a non-zero dithering effect
+#define MIN_DITHER_AMP 4
+#define DITHER_DESCALE 4
+#define DITHER_DESCALE_ROUNDER (1 << (DITHER_DESCALE - 1))
+#define DITHER_AMP_BITS 8
+#define DITHER_AMP_CENTER (1 << DITHER_AMP_BITS)
+
+static void Dither8x8(VP8Random* const rg, uint8_t* dst, int bps, int amp) {
+  int i, j;
+  for (j = 0; j < 8; ++j) {
+    for (i = 0; i < 8; ++i) {
+      // TODO: could be made faster with SSE2
+      const int bits =
+          VP8RandomBits2(rg, DITHER_AMP_BITS + 1, amp) - DITHER_AMP_CENTER;
+      // Convert to range: [-2,2] for dither=50, [-4,4] for dither=100
+      const int delta = (bits + DITHER_DESCALE_ROUNDER) >> DITHER_DESCALE;
+      const int v = (int)dst[i] + delta;
+      dst[i] = (v < 0) ? 0 : (v > 255) ? 255u : (uint8_t)v;
+    }
+    dst += bps;
+  }
+}
+
+static void DitherRow(VP8Decoder* const dec) {
+  int mb_x;
+  assert(dec->dither_);
+  for (mb_x = dec->tl_mb_x_; mb_x < dec->br_mb_x_; ++mb_x) {
+    const VP8ThreadContext* const ctx = &dec->thread_ctx_;
+    const VP8MBData* const data = ctx->mb_data_ + mb_x;
+    const int cache_id = ctx->id_;
+    const int uv_bps = dec->cache_uv_stride_;
+    if (data->dither_ >= MIN_DITHER_AMP) {
+      uint8_t* const u_dst = dec->cache_u_ + cache_id * 8 * uv_bps + mb_x * 8;
+      uint8_t* const v_dst = dec->cache_v_ + cache_id * 8 * uv_bps + mb_x * 8;
+      Dither8x8(&dec->dithering_rg_, u_dst, uv_bps, data->dither_);
+      Dither8x8(&dec->dithering_rg_, v_dst, uv_bps, data->dither_);
+    }
+  }
+}
+
+//------------------------------------------------------------------------------
+// This function is called after a row of macroblocks is finished decoding.
+// It also takes into account the following restrictions:
+//  * In case of in-loop filtering, we must hold off sending some of the bottom
+//    pixels as they are yet unfiltered. They will be when the next macroblock
+//    row is decoded. Meanwhile, we must preserve them by rotating them in the
+//    cache area. This doesn't hold for the very bottom row of the uncropped
+//    picture of course.
+//  * we must clip the remaining pixels against the cropping area. The VP8Io
+//    struct must have the following fields set correctly before calling put():
+
+#define MACROBLOCK_VPOS(mb_y)  ((mb_y) * 16)    // vertical position of a MB
+
+// Finalize and transmit a complete row. Return false in case of user-abort.
+static int FinishRow(VP8Decoder* const dec, VP8Io* const io) {
+  int ok = 1;
+  const VP8ThreadContext* const ctx = &dec->thread_ctx_;
+  const int cache_id = ctx->id_;
+  const int extra_y_rows = kFilterExtraRows[dec->filter_type_];
+  const int ysize = extra_y_rows * dec->cache_y_stride_;
+  const int uvsize = (extra_y_rows / 2) * dec->cache_uv_stride_;
+  const int y_offset = cache_id * 16 * dec->cache_y_stride_;
+  const int uv_offset = cache_id * 8 * dec->cache_uv_stride_;
+  uint8_t* const ydst = dec->cache_y_ - ysize + y_offset;
+  uint8_t* const udst = dec->cache_u_ - uvsize + uv_offset;
+  uint8_t* const vdst = dec->cache_v_ - uvsize + uv_offset;
+  const int mb_y = ctx->mb_y_;
+  const int is_first_row = (mb_y == 0);
+  const int is_last_row = (mb_y >= dec->br_mb_y_ - 1);
+
+  if (dec->mt_method_ == 2) {
+    ReconstructRow(dec, ctx);
+  }
+
+  if (ctx->filter_row_) {
+    FilterRow(dec);
+  }
+
+  if (dec->dither_) {
+    DitherRow(dec);
+  }
+
+  if (io->put != NULL) {
+    int y_start = MACROBLOCK_VPOS(mb_y);
+    int y_end = MACROBLOCK_VPOS(mb_y + 1);
+    if (!is_first_row) {
+      y_start -= extra_y_rows;
+      io->y = ydst;
+      io->u = udst;
+      io->v = vdst;
+    } else {
+      io->y = dec->cache_y_ + y_offset;
+      io->u = dec->cache_u_ + uv_offset;
+      io->v = dec->cache_v_ + uv_offset;
+    }
+
+    if (!is_last_row) {
+      y_end -= extra_y_rows;
+    }
+    if (y_end > io->crop_bottom) {
+      y_end = io->crop_bottom;    // make sure we don't overflow on last row.
+    }
+    io->a = NULL;
+    if (dec->alpha_data_ != NULL && y_start < y_end) {
+      // TODO(skal): testing presence of alpha with dec->alpha_data_ is not a
+      // good idea.
+      io->a = VP8DecompressAlphaRows(dec, y_start, y_end - y_start);
+      if (io->a == NULL) {
+        return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR,
+                           "Could not decode alpha data.");
+      }
+    }
+    if (y_start < io->crop_top) {
+      const int delta_y = io->crop_top - y_start;
+      y_start = io->crop_top;
+      assert(!(delta_y & 1));
+      io->y += dec->cache_y_stride_ * delta_y;
+      io->u += dec->cache_uv_stride_ * (delta_y >> 1);
+      io->v += dec->cache_uv_stride_ * (delta_y >> 1);
+      if (io->a != NULL) {
+        io->a += io->width * delta_y;
+      }
+    }
+    if (y_start < y_end) {
+      io->y += io->crop_left;
+      io->u += io->crop_left >> 1;
+      io->v += io->crop_left >> 1;
+      if (io->a != NULL) {
+        io->a += io->crop_left;
+      }
+      io->mb_y = y_start - io->crop_top;
+      io->mb_w = io->crop_right - io->crop_left;
+      io->mb_h = y_end - y_start;
+      ok = io->put(io);
+    }
+  }
+  // rotate top samples if needed
+  if (cache_id + 1 == dec->num_caches_) {
+    if (!is_last_row) {
+      memcpy(dec->cache_y_ - ysize, ydst + 16 * dec->cache_y_stride_, ysize);
+      memcpy(dec->cache_u_ - uvsize, udst + 8 * dec->cache_uv_stride_, uvsize);
+      memcpy(dec->cache_v_ - uvsize, vdst + 8 * dec->cache_uv_stride_, uvsize);
+    }
+  }
+
+  return ok;
+}
+
+#undef MACROBLOCK_VPOS
+
+//------------------------------------------------------------------------------
+
+int VP8ProcessRow(VP8Decoder* const dec, VP8Io* const io) {
+  int ok = 1;
+  VP8ThreadContext* const ctx = &dec->thread_ctx_;
+  const int filter_row =
+      (dec->filter_type_ > 0) &&
+      (dec->mb_y_ >= dec->tl_mb_y_) && (dec->mb_y_ <= dec->br_mb_y_);
+  if (dec->mt_method_ == 0) {
+    // ctx->id_ and ctx->f_info_ are already set
+    ctx->mb_y_ = dec->mb_y_;
+    ctx->filter_row_ = filter_row;
+    ReconstructRow(dec, ctx);
+    ok = FinishRow(dec, io);
+  } else {
+    WebPWorker* const worker = &dec->worker_;
+    // Finish previous job *before* updating context
+    ok &= WebPGetWorkerInterface()->Sync(worker);
+    assert(worker->status_ == OK);
+    if (ok) {   // spawn a new deblocking/output job
+      ctx->io_ = *io;
+      ctx->id_ = dec->cache_id_;
+      ctx->mb_y_ = dec->mb_y_;
+      ctx->filter_row_ = filter_row;
+      if (dec->mt_method_ == 2) {  // swap macroblock data
+        VP8MBData* const tmp = ctx->mb_data_;
+        ctx->mb_data_ = dec->mb_data_;
+        dec->mb_data_ = tmp;
+      } else {
+        // perform reconstruction directly in main thread
+        ReconstructRow(dec, ctx);
+      }
+      if (filter_row) {            // swap filter info
+        VP8FInfo* const tmp = ctx->f_info_;
+        ctx->f_info_ = dec->f_info_;
+        dec->f_info_ = tmp;
+      }
+      // (reconstruct)+filter in parallel
+      WebPGetWorkerInterface()->Launch(worker);
+      if (++dec->cache_id_ == dec->num_caches_) {
+        dec->cache_id_ = 0;
+      }
+    }
+  }
+  return ok;
+}
+
+//------------------------------------------------------------------------------
+// Finish setting up the decoding parameter once user's setup() is called.
+
+VP8StatusCode VP8EnterCritical(VP8Decoder* const dec, VP8Io* const io) {
+  // Call setup() first. This may trigger additional decoding features on 'io'.
+  // Note: Afterward, we must call teardown() no matter what.
+  if (io->setup != NULL && !io->setup(io)) {
+    VP8SetError(dec, VP8_STATUS_USER_ABORT, "Frame setup failed");
+    return dec->status_;
+  }
+
+  // Disable filtering per user request
+  if (io->bypass_filtering) {
+    dec->filter_type_ = 0;
+  }
+  // TODO(skal): filter type / strength / sharpness forcing
+
+  // Define the area where we can skip in-loop filtering, in case of cropping.
+  //
+  // 'Simple' filter reads two luma samples outside of the macroblock
+  // and filters one. It doesn't filter the chroma samples. Hence, we can
+  // avoid doing the in-loop filtering before crop_top/crop_left position.
+  // For the 'Complex' filter, 3 samples are read and up to 3 are filtered.
+  // Means: there's a dependency chain that goes all the way up to the
+  // top-left corner of the picture (MB #0). We must filter all the previous
+  // macroblocks.
+  // TODO(skal): add an 'approximate_decoding' option, that won't produce
+  // a 1:1 bit-exactness for complex filtering?
+  {
+    const int extra_pixels = kFilterExtraRows[dec->filter_type_];
+    if (dec->filter_type_ == 2) {
+      // For complex filter, we need to preserve the dependency chain.
+      dec->tl_mb_x_ = 0;
+      dec->tl_mb_y_ = 0;
+    } else {
+      // For simple filter, we can filter only the cropped region.
+      // We include 'extra_pixels' on the other side of the boundary, since
+      // vertical or horizontal filtering of the previous macroblock can
+      // modify some abutting pixels.
+      dec->tl_mb_x_ = (io->crop_left - extra_pixels) >> 4;
+      dec->tl_mb_y_ = (io->crop_top - extra_pixels) >> 4;
+      if (dec->tl_mb_x_ < 0) dec->tl_mb_x_ = 0;
+      if (dec->tl_mb_y_ < 0) dec->tl_mb_y_ = 0;
+    }
+    // We need some 'extra' pixels on the right/bottom.
+    dec->br_mb_y_ = (io->crop_bottom + 15 + extra_pixels) >> 4;
+    dec->br_mb_x_ = (io->crop_right + 15 + extra_pixels) >> 4;
+    if (dec->br_mb_x_ > dec->mb_w_) {
+      dec->br_mb_x_ = dec->mb_w_;
+    }
+    if (dec->br_mb_y_ > dec->mb_h_) {
+      dec->br_mb_y_ = dec->mb_h_;
+    }
+  }
+  PrecomputeFilterStrengths(dec);
+  return VP8_STATUS_OK;
+}
+
+int VP8ExitCritical(VP8Decoder* const dec, VP8Io* const io) {
+  int ok = 1;
+  if (dec->mt_method_ > 0) {
+    ok = WebPGetWorkerInterface()->Sync(&dec->worker_);
+  }
+
+  if (io->teardown != NULL) {
+    io->teardown(io);
+  }
+  return ok;
+}
+
+//------------------------------------------------------------------------------
+// For multi-threaded decoding we need to use 3 rows of 16 pixels as delay line.
+//
+// Reason is: the deblocking filter cannot deblock the bottom horizontal edges
+// immediately, and needs to wait for first few rows of the next macroblock to
+// be decoded. Hence, deblocking is lagging behind by 4 or 8 pixels (depending
+// on strength).
+// With two threads, the vertical positions of the rows being decoded are:
+// Decode:  [ 0..15][16..31][32..47][48..63][64..79][...
+// Deblock:         [ 0..11][12..27][28..43][44..59][...
+// If we use two threads and two caches of 16 pixels, the sequence would be:
+// Decode:  [ 0..15][16..31][ 0..15!!][16..31][ 0..15][...
+// Deblock:         [ 0..11][12..27!!][-4..11][12..27][...
+// The problem occurs during row [12..15!!] that both the decoding and
+// deblocking threads are writing simultaneously.
+// With 3 cache lines, one get a safe write pattern:
+// Decode:  [ 0..15][16..31][32..47][ 0..15][16..31][32..47][0..
+// Deblock:         [ 0..11][12..27][28..43][-4..11][12..27][28...
+// Note that multi-threaded output _without_ deblocking can make use of two
+// cache lines of 16 pixels only, since there's no lagging behind. The decoding
+// and output process have non-concurrent writing:
+// Decode:  [ 0..15][16..31][ 0..15][16..31][...
+// io->put:         [ 0..15][16..31][ 0..15][...
+
+#define MT_CACHE_LINES 3
+#define ST_CACHE_LINES 1   // 1 cache row only for single-threaded case
+
+// Initialize multi/single-thread worker
+static int InitThreadContext(VP8Decoder* const dec) {
+  dec->cache_id_ = 0;
+  if (dec->mt_method_ > 0) {
+    WebPWorker* const worker = &dec->worker_;
+    if (!WebPGetWorkerInterface()->Reset(worker)) {
+      return VP8SetError(dec, VP8_STATUS_OUT_OF_MEMORY,
+                         "thread initialization failed.");
+    }
+    worker->data1 = dec;
+    worker->data2 = (void*)&dec->thread_ctx_.io_;
+    worker->hook = (WebPWorkerHook)FinishRow;
+    dec->num_caches_ =
+      (dec->filter_type_ > 0) ? MT_CACHE_LINES : MT_CACHE_LINES - 1;
+  } else {
+    dec->num_caches_ = ST_CACHE_LINES;
+  }
+  return 1;
+}
+
+int VP8GetThreadMethod(const WebPDecoderOptions* const options,
+                       const WebPHeaderStructure* const headers,
+                       int width, int height) {
+  if (options == NULL || options->use_threads == 0) {
+    return 0;
+  }
+  (void)headers;
+  (void)width;
+  (void)height;
+  assert(headers == NULL || !headers->is_lossless);
+#if defined(WEBP_USE_THREAD)
+  if (width < MIN_WIDTH_FOR_THREADS) return 0;
+  // TODO(skal): tune the heuristic further
+#if 0
+  if (height < 2 * width) return 2;
+#endif
+  return 2;
+#else   // !WEBP_USE_THREAD
+  return 0;
+#endif
+}
+
+#undef MT_CACHE_LINES
+#undef ST_CACHE_LINES
+
+//------------------------------------------------------------------------------
+// Memory setup
+
+static int AllocateMemory(VP8Decoder* const dec) {
+  const int num_caches = dec->num_caches_;
+  const int mb_w = dec->mb_w_;
+  // Note: we use 'size_t' when there's no overflow risk, uint64_t otherwise.
+  const size_t intra_pred_mode_size = 4 * mb_w * sizeof(uint8_t);
+  const size_t top_size = sizeof(VP8TopSamples) * mb_w;
+  const size_t mb_info_size = (mb_w + 1) * sizeof(VP8MB);
+  const size_t f_info_size =
+      (dec->filter_type_ > 0) ?
+          mb_w * (dec->mt_method_ > 0 ? 2 : 1) * sizeof(VP8FInfo)
+        : 0;
+  const size_t yuv_size = YUV_SIZE * sizeof(*dec->yuv_b_);
+  const size_t mb_data_size =
+      (dec->mt_method_ == 2 ? 2 : 1) * mb_w * sizeof(*dec->mb_data_);
+  const size_t cache_height = (16 * num_caches
+                            + kFilterExtraRows[dec->filter_type_]) * 3 / 2;
+  const size_t cache_size = top_size * cache_height;
+  // alpha_size is the only one that scales as width x height.
+  const uint64_t alpha_size = (dec->alpha_data_ != NULL) ?
+      (uint64_t)dec->pic_hdr_.width_ * dec->pic_hdr_.height_ : 0ULL;
+  const uint64_t needed = (uint64_t)intra_pred_mode_size
+                        + top_size + mb_info_size + f_info_size
+                        + yuv_size + mb_data_size
+                        + cache_size + alpha_size + ALIGN_CST;
+  uint8_t* mem;
+
+  if (needed != (size_t)needed) return 0;  // check for overflow
+  if (needed > dec->mem_size_) {
+    WebPSafeFree(dec->mem_);
+    dec->mem_size_ = 0;
+    dec->mem_ = WebPSafeMalloc(needed, sizeof(uint8_t));
+    if (dec->mem_ == NULL) {
+      return VP8SetError(dec, VP8_STATUS_OUT_OF_MEMORY,
+                         "no memory during frame initialization.");
+    }
+    // down-cast is ok, thanks to WebPSafeAlloc() above.
+    dec->mem_size_ = (size_t)needed;
+  }
+
+  mem = (uint8_t*)dec->mem_;
+  dec->intra_t_ = (uint8_t*)mem;
+  mem += intra_pred_mode_size;
+
+  dec->yuv_t_ = (VP8TopSamples*)mem;
+  mem += top_size;
+
+  dec->mb_info_ = ((VP8MB*)mem) + 1;
+  mem += mb_info_size;
+
+  dec->f_info_ = f_info_size ? (VP8FInfo*)mem : NULL;
+  mem += f_info_size;
+  dec->thread_ctx_.id_ = 0;
+  dec->thread_ctx_.f_info_ = dec->f_info_;
+  if (dec->mt_method_ > 0) {
+    // secondary cache line. The deblocking process need to make use of the
+    // filtering strength from previous macroblock row, while the new ones
+    // are being decoded in parallel. We'll just swap the pointers.
+    dec->thread_ctx_.f_info_ += mb_w;
+  }
+
+  mem = (uint8_t*)DO_ALIGN(mem);
+  assert((yuv_size & ALIGN_CST) == 0);
+  dec->yuv_b_ = (uint8_t*)mem;
+  mem += yuv_size;
+
+  dec->mb_data_ = (VP8MBData*)mem;
+  dec->thread_ctx_.mb_data_ = (VP8MBData*)mem;
+  if (dec->mt_method_ == 2) {
+    dec->thread_ctx_.mb_data_ += mb_w;
+  }
+  mem += mb_data_size;
+
+  dec->cache_y_stride_ = 16 * mb_w;
+  dec->cache_uv_stride_ = 8 * mb_w;
+  {
+    const int extra_rows = kFilterExtraRows[dec->filter_type_];
+    const int extra_y = extra_rows * dec->cache_y_stride_;
+    const int extra_uv = (extra_rows / 2) * dec->cache_uv_stride_;
+    dec->cache_y_ = ((uint8_t*)mem) + extra_y;
+    dec->cache_u_ = dec->cache_y_
+                  + 16 * num_caches * dec->cache_y_stride_ + extra_uv;
+    dec->cache_v_ = dec->cache_u_
+                  + 8 * num_caches * dec->cache_uv_stride_ + extra_uv;
+    dec->cache_id_ = 0;
+  }
+  mem += cache_size;
+
+  // alpha plane
+  dec->alpha_plane_ = alpha_size ? (uint8_t*)mem : NULL;
+  mem += alpha_size;
+  assert(mem <= (uint8_t*)dec->mem_ + dec->mem_size_);
+
+  // note: left/top-info is initialized once for all.
+  memset(dec->mb_info_ - 1, 0, mb_info_size);
+  VP8InitScanline(dec);   // initialize left too.
+
+  // initialize top
+  memset(dec->intra_t_, B_DC_PRED, intra_pred_mode_size);
+
+  return 1;
+}
+
+static void InitIo(VP8Decoder* const dec, VP8Io* io) {
+  // prepare 'io'
+  io->mb_y = 0;
+  io->y = dec->cache_y_;
+  io->u = dec->cache_u_;
+  io->v = dec->cache_v_;
+  io->y_stride = dec->cache_y_stride_;
+  io->uv_stride = dec->cache_uv_stride_;
+  io->a = NULL;
+}
+
+int VP8InitFrame(VP8Decoder* const dec, VP8Io* io) {
+  if (!InitThreadContext(dec)) return 0;  // call first. Sets dec->num_caches_.
+  if (!AllocateMemory(dec)) return 0;
+  InitIo(dec, io);
+  VP8DspInit();  // Init critical function pointers and look-up tables.
+  return 1;
+}
+
+//------------------------------------------------------------------------------
+// Main reconstruction function.
+
+static const int kScan[16] = {
+  0 +  0 * BPS,  4 +  0 * BPS, 8 +  0 * BPS, 12 +  0 * BPS,
+  0 +  4 * BPS,  4 +  4 * BPS, 8 +  4 * BPS, 12 +  4 * BPS,
+  0 +  8 * BPS,  4 +  8 * BPS, 8 +  8 * BPS, 12 +  8 * BPS,
+  0 + 12 * BPS,  4 + 12 * BPS, 8 + 12 * BPS, 12 + 12 * BPS
+};
+
+static int CheckMode(int mb_x, int mb_y, int mode) {
+  if (mode == B_DC_PRED) {
+    if (mb_x == 0) {
+      return (mb_y == 0) ? B_DC_PRED_NOTOPLEFT : B_DC_PRED_NOLEFT;
+    } else {
+      return (mb_y == 0) ? B_DC_PRED_NOTOP : B_DC_PRED;
+    }
+  }
+  return mode;
+}
+
+static void Copy32b(uint8_t* dst, uint8_t* src) {
+  memcpy(dst, src, 4);
+}
+
+static WEBP_INLINE void DoTransform(uint32_t bits, const int16_t* const src,
+                                    uint8_t* const dst) {
+  switch (bits >> 30) {
+    case 3:
+      VP8Transform(src, dst, 0);
+      break;
+    case 2:
+      VP8TransformAC3(src, dst);
+      break;
+    case 1:
+      VP8TransformDC(src, dst);
+      break;
+    default:
+      break;
+  }
+}
+
+static void DoUVTransform(uint32_t bits, const int16_t* const src,
+                          uint8_t* const dst) {
+  if (bits & 0xff) {    // any non-zero coeff at all?
+    if (bits & 0xaa) {  // any non-zero AC coefficient?
+      VP8TransformUV(src, dst);   // note we don't use the AC3 variant for U/V
+    } else {
+      VP8TransformDCUV(src, dst);
+    }
+  }
+}
+
+static void ReconstructRow(const VP8Decoder* const dec,
+                           const VP8ThreadContext* ctx) {
+  int j;
+  int mb_x;
+  const int mb_y = ctx->mb_y_;
+  const int cache_id = ctx->id_;
+  uint8_t* const y_dst = dec->yuv_b_ + Y_OFF;
+  uint8_t* const u_dst = dec->yuv_b_ + U_OFF;
+  uint8_t* const v_dst = dec->yuv_b_ + V_OFF;
+  for (mb_x = 0; mb_x < dec->mb_w_; ++mb_x) {
+    const VP8MBData* const block = ctx->mb_data_ + mb_x;
+
+    // Rotate in the left samples from previously decoded block. We move four
+    // pixels at a time for alignment reason, and because of in-loop filter.
+    if (mb_x > 0) {
+      for (j = -1; j < 16; ++j) {
+        Copy32b(&y_dst[j * BPS - 4], &y_dst[j * BPS + 12]);
+      }
+      for (j = -1; j < 8; ++j) {
+        Copy32b(&u_dst[j * BPS - 4], &u_dst[j * BPS + 4]);
+        Copy32b(&v_dst[j * BPS - 4], &v_dst[j * BPS + 4]);
+      }
+    } else {
+      for (j = 0; j < 16; ++j) {
+        y_dst[j * BPS - 1] = 129;
+      }
+      for (j = 0; j < 8; ++j) {
+        u_dst[j * BPS - 1] = 129;
+        v_dst[j * BPS - 1] = 129;
+      }
+      // Init top-left sample on left column too
+      if (mb_y > 0) {
+        y_dst[-1 - BPS] = u_dst[-1 - BPS] = v_dst[-1 - BPS] = 129;
+      }
+    }
+    {
+      // bring top samples into the cache
+      VP8TopSamples* const top_yuv = dec->yuv_t_ + mb_x;
+      const int16_t* const coeffs = block->coeffs_;
+      uint32_t bits = block->non_zero_y_;
+      int n;
+
+      if (mb_y > 0) {
+        memcpy(y_dst - BPS, top_yuv[0].y, 16);
+        memcpy(u_dst - BPS, top_yuv[0].u, 8);
+        memcpy(v_dst - BPS, top_yuv[0].v, 8);
+      } else if (mb_x == 0) {
+        // we only need to do this init once at block (0,0).
+        // Afterward, it remains valid for the whole topmost row.
+        memset(y_dst - BPS - 1, 127, 16 + 4 + 1);
+        memset(u_dst - BPS - 1, 127, 8 + 1);
+        memset(v_dst - BPS - 1, 127, 8 + 1);
+      }
+
+      // predict and add residuals
+      if (block->is_i4x4_) {   // 4x4
+        uint32_t* const top_right = (uint32_t*)(y_dst - BPS + 16);
+
+        if (mb_y > 0) {
+          if (mb_x >= dec->mb_w_ - 1) {    // on rightmost border
+            memset(top_right, top_yuv[0].y[15], sizeof(*top_right));
+          } else {
+            memcpy(top_right, top_yuv[1].y, sizeof(*top_right));
+          }
+        }
+        // replicate the top-right pixels below
+        top_right[BPS] = top_right[2 * BPS] = top_right[3 * BPS] = top_right[0];
+
+        // predict and add residuals for all 4x4 blocks in turn.
+        for (n = 0; n < 16; ++n, bits <<= 2) {
+          uint8_t* const dst = y_dst + kScan[n];
+          VP8PredLuma4[block->imodes_[n]](dst);
+          DoTransform(bits, coeffs + n * 16, dst);
+        }
+      } else {    // 16x16
+        const int pred_func = CheckMode(mb_x, mb_y,
+                                        block->imodes_[0]);
+        VP8PredLuma16[pred_func](y_dst);
+        if (bits != 0) {
+          for (n = 0; n < 16; ++n, bits <<= 2) {
+            DoTransform(bits, coeffs + n * 16, y_dst + kScan[n]);
+          }
+        }
+      }
+      {
+        // Chroma
+        const uint32_t bits_uv = block->non_zero_uv_;
+        const int pred_func = CheckMode(mb_x, mb_y, block->uvmode_);
+        VP8PredChroma8[pred_func](u_dst);
+        VP8PredChroma8[pred_func](v_dst);
+        DoUVTransform(bits_uv >> 0, coeffs + 16 * 16, u_dst);
+        DoUVTransform(bits_uv >> 8, coeffs + 20 * 16, v_dst);
+      }
+
+      // stash away top samples for next block
+      if (mb_y < dec->mb_h_ - 1) {
+        memcpy(top_yuv[0].y, y_dst + 15 * BPS, 16);
+        memcpy(top_yuv[0].u, u_dst +  7 * BPS,  8);
+        memcpy(top_yuv[0].v, v_dst +  7 * BPS,  8);
+      }
+    }
+    // Transfer reconstructed samples from yuv_b_ cache to final destination.
+    {
+      const int y_offset = cache_id * 16 * dec->cache_y_stride_;
+      const int uv_offset = cache_id * 8 * dec->cache_uv_stride_;
+      uint8_t* const y_out = dec->cache_y_ + mb_x * 16 + y_offset;
+      uint8_t* const u_out = dec->cache_u_ + mb_x * 8 + uv_offset;
+      uint8_t* const v_out = dec->cache_v_ + mb_x * 8 + uv_offset;
+      for (j = 0; j < 16; ++j) {
+        memcpy(y_out + j * dec->cache_y_stride_, y_dst + j * BPS, 16);
+      }
+      for (j = 0; j < 8; ++j) {
+        memcpy(u_out + j * dec->cache_uv_stride_, u_dst + j * BPS, 8);
+        memcpy(v_out + j * dec->cache_uv_stride_, v_dst + j * BPS, 8);
+      }
+    }
+  }
+}
+
+//------------------------------------------------------------------------------
+
diff --git a/Source/LibWebP/src/dec/dec.idec.c b/Source/LibWebP/src/dec/dec.idec.c
new file mode 100644
index 0000000..08e8a81
--- /dev/null
+++ b/Source/LibWebP/src/dec/dec.idec.c
@@ -0,0 +1,857 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Incremental decoding
+//
+// Author: somnath at google.com (Somnath Banerjee)
+
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "./alphai.h"
+#include "./webpi.h"
+#include "./vp8i.h"
+#include "../utils/utils.h"
+
+// In append mode, buffer allocations increase as multiples of this value.
+// Needs to be a power of 2.
+#define CHUNK_SIZE 4096
+#define MAX_MB_SIZE 4096
+
+//------------------------------------------------------------------------------
+// Data structures for memory and states
+
+// Decoding states. State normally flows as:
+// WEBP_HEADER->VP8_HEADER->VP8_PARTS0->VP8_DATA->DONE for a lossy image, and
+// WEBP_HEADER->VP8L_HEADER->VP8L_DATA->DONE for a lossless image.
+// If there is any error the decoder goes into state ERROR.
+typedef enum {
+  STATE_WEBP_HEADER,  // All the data before that of the VP8/VP8L chunk.
+  STATE_VP8_HEADER,   // The VP8 Frame header (within the VP8 chunk).
+  STATE_VP8_PARTS0,
+  STATE_VP8_DATA,
+  STATE_VP8L_HEADER,
+  STATE_VP8L_DATA,
+  STATE_DONE,
+  STATE_ERROR
+} DecState;
+
+// Operating state for the MemBuffer
+typedef enum {
+  MEM_MODE_NONE = 0,
+  MEM_MODE_APPEND,
+  MEM_MODE_MAP
+} MemBufferMode;
+
+// storage for partition #0 and partial data (in a rolling fashion)
+typedef struct {
+  MemBufferMode mode_;  // Operation mode
+  size_t start_;        // start location of the data to be decoded
+  size_t end_;          // end location
+  size_t buf_size_;     // size of the allocated buffer
+  uint8_t* buf_;        // We don't own this buffer in case WebPIUpdate()
+
+  size_t part0_size_;         // size of partition #0
+  const uint8_t* part0_buf_;  // buffer to store partition #0
+} MemBuffer;
+
+struct WebPIDecoder {
+  DecState state_;         // current decoding state
+  WebPDecParams params_;   // Params to store output info
+  int is_lossless_;        // for down-casting 'dec_'.
+  void* dec_;              // either a VP8Decoder or a VP8LDecoder instance
+  VP8Io io_;
+
+  MemBuffer mem_;          // input memory buffer.
+  WebPDecBuffer output_;   // output buffer (when no external one is supplied)
+  size_t chunk_size_;      // Compressed VP8/VP8L size extracted from Header.
+
+  int last_mb_y_;          // last row reached for intra-mode decoding
+};
+
+// MB context to restore in case VP8DecodeMB() fails
+typedef struct {
+  VP8MB left_;
+  VP8MB info_;
+  VP8BitReader token_br_;
+} MBContext;
+
+//------------------------------------------------------------------------------
+// MemBuffer: incoming data handling
+
+static WEBP_INLINE size_t MemDataSize(const MemBuffer* mem) {
+  return (mem->end_ - mem->start_);
+}
+
+// Check if we need to preserve the compressed alpha data, as it may not have
+// been decoded yet.
+static int NeedCompressedAlpha(const WebPIDecoder* const idec) {
+  if (idec->state_ == STATE_WEBP_HEADER) {
+    // We haven't parsed the headers yet, so we don't know whether the image is
+    // lossy or lossless. This also means that we haven't parsed the ALPH chunk.
+    return 0;
+  }
+  if (idec->is_lossless_) {
+    return 0;  // ALPH chunk is not present for lossless images.
+  } else {
+    const VP8Decoder* const dec = (VP8Decoder*)idec->dec_;
+    assert(dec != NULL);  // Must be true as idec->state_ != STATE_WEBP_HEADER.
+    return (dec->alpha_data_ != NULL) && !dec->is_alpha_decoded_;
+  }
+}
+
+static void DoRemap(WebPIDecoder* const idec, ptrdiff_t offset) {
+  MemBuffer* const mem = &idec->mem_;
+  const uint8_t* const new_base = mem->buf_ + mem->start_;
+  // note: for VP8, setting up idec->io_ is only really needed at the beginning
+  // of the decoding, till partition #0 is complete.
+  idec->io_.data = new_base;
+  idec->io_.data_size = MemDataSize(mem);
+
+  if (idec->dec_ != NULL) {
+    if (!idec->is_lossless_) {
+      VP8Decoder* const dec = (VP8Decoder*)idec->dec_;
+      const int last_part = dec->num_parts_ - 1;
+      if (offset != 0) {
+        int p;
+        for (p = 0; p <= last_part; ++p) {
+          VP8RemapBitReader(dec->parts_ + p, offset);
+        }
+        // Remap partition #0 data pointer to new offset, but only in MAP
+        // mode (in APPEND mode, partition #0 is copied into a fixed memory).
+        if (mem->mode_ == MEM_MODE_MAP) {
+          VP8RemapBitReader(&dec->br_, offset);
+        }
+      }
+      assert(last_part >= 0);
+      dec->parts_[last_part].buf_end_ = mem->buf_ + mem->end_;
+      if (NeedCompressedAlpha(idec)) {
+        ALPHDecoder* const alph_dec = dec->alph_dec_;
+        dec->alpha_data_ += offset;
+        if (alph_dec != NULL) {
+          if (alph_dec->method_ == ALPHA_LOSSLESS_COMPRESSION) {
+            VP8LDecoder* const alph_vp8l_dec = alph_dec->vp8l_dec_;
+            assert(alph_vp8l_dec != NULL);
+            assert(dec->alpha_data_size_ >= ALPHA_HEADER_LEN);
+            VP8LBitReaderSetBuffer(&alph_vp8l_dec->br_,
+                                   dec->alpha_data_ + ALPHA_HEADER_LEN,
+                                   dec->alpha_data_size_ - ALPHA_HEADER_LEN);
+          } else {  // alph_dec->method_ == ALPHA_NO_COMPRESSION
+            // Nothing special to do in this case.
+          }
+        }
+      }
+    } else {    // Resize lossless bitreader
+      VP8LDecoder* const dec = (VP8LDecoder*)idec->dec_;
+      VP8LBitReaderSetBuffer(&dec->br_, new_base, MemDataSize(mem));
+    }
+  }
+}
+
+// Appends data to the end of MemBuffer->buf_. It expands the allocated memory
+// size if required and also updates VP8BitReader's if new memory is allocated.
+static int AppendToMemBuffer(WebPIDecoder* const idec,
+                             const uint8_t* const data, size_t data_size) {
+  VP8Decoder* const dec = (VP8Decoder*)idec->dec_;
+  MemBuffer* const mem = &idec->mem_;
+  const int need_compressed_alpha = NeedCompressedAlpha(idec);
+  const uint8_t* const old_start = mem->buf_ + mem->start_;
+  const uint8_t* const old_base =
+      need_compressed_alpha ? dec->alpha_data_ : old_start;
+  assert(mem->mode_ == MEM_MODE_APPEND);
+  if (data_size > MAX_CHUNK_PAYLOAD) {
+    // security safeguard: trying to allocate more than what the format
+    // allows for a chunk should be considered a smoke smell.
+    return 0;
+  }
+
+  if (mem->end_ + data_size > mem->buf_size_) {  // Need some free memory
+    const size_t new_mem_start = old_start - old_base;
+    const size_t current_size = MemDataSize(mem) + new_mem_start;
+    const uint64_t new_size = (uint64_t)current_size + data_size;
+    const uint64_t extra_size = (new_size + CHUNK_SIZE - 1) & ~(CHUNK_SIZE - 1);
+    uint8_t* const new_buf =
+        (uint8_t*)WebPSafeMalloc(extra_size, sizeof(*new_buf));
+    if (new_buf == NULL) return 0;
+    memcpy(new_buf, old_base, current_size);
+    WebPSafeFree(mem->buf_);
+    mem->buf_ = new_buf;
+    mem->buf_size_ = (size_t)extra_size;
+    mem->start_ = new_mem_start;
+    mem->end_ = current_size;
+  }
+
+  memcpy(mem->buf_ + mem->end_, data, data_size);
+  mem->end_ += data_size;
+  assert(mem->end_ <= mem->buf_size_);
+
+  DoRemap(idec, mem->buf_ + mem->start_ - old_start);
+  return 1;
+}
+
+static int RemapMemBuffer(WebPIDecoder* const idec,
+                          const uint8_t* const data, size_t data_size) {
+  MemBuffer* const mem = &idec->mem_;
+  const uint8_t* const old_buf = mem->buf_;
+  const uint8_t* const old_start = old_buf + mem->start_;
+  assert(mem->mode_ == MEM_MODE_MAP);
+
+  if (data_size < mem->buf_size_) return 0;  // can't remap to a shorter buffer!
+
+  mem->buf_ = (uint8_t*)data;
+  mem->end_ = mem->buf_size_ = data_size;
+
+  DoRemap(idec, mem->buf_ + mem->start_ - old_start);
+  return 1;
+}
+
+static void InitMemBuffer(MemBuffer* const mem) {
+  mem->mode_       = MEM_MODE_NONE;
+  mem->buf_        = NULL;
+  mem->buf_size_   = 0;
+  mem->part0_buf_  = NULL;
+  mem->part0_size_ = 0;
+}
+
+static void ClearMemBuffer(MemBuffer* const mem) {
+  assert(mem);
+  if (mem->mode_ == MEM_MODE_APPEND) {
+    WebPSafeFree(mem->buf_);
+    WebPSafeFree((void*)mem->part0_buf_);
+  }
+}
+
+static int CheckMemBufferMode(MemBuffer* const mem, MemBufferMode expected) {
+  if (mem->mode_ == MEM_MODE_NONE) {
+    mem->mode_ = expected;    // switch to the expected mode
+  } else if (mem->mode_ != expected) {
+    return 0;         // we mixed the modes => error
+  }
+  assert(mem->mode_ == expected);   // mode is ok
+  return 1;
+}
+
+// To be called last.
+static VP8StatusCode FinishDecoding(WebPIDecoder* const idec) {
+  const WebPDecoderOptions* const options = idec->params_.options;
+  WebPDecBuffer* const output = idec->params_.output;
+
+  idec->state_ = STATE_DONE;
+  if (options != NULL && options->flip) {
+    return WebPFlipBuffer(output);
+  } else {
+    return VP8_STATUS_OK;
+  }
+}
+
+//------------------------------------------------------------------------------
+// Macroblock-decoding contexts
+
+static void SaveContext(const VP8Decoder* dec, const VP8BitReader* token_br,
+                        MBContext* const context) {
+  context->left_ = dec->mb_info_[-1];
+  context->info_ = dec->mb_info_[dec->mb_x_];
+  context->token_br_ = *token_br;
+}
+
+static void RestoreContext(const MBContext* context, VP8Decoder* const dec,
+                           VP8BitReader* const token_br) {
+  dec->mb_info_[-1] = context->left_;
+  dec->mb_info_[dec->mb_x_] = context->info_;
+  *token_br = context->token_br_;
+}
+
+//------------------------------------------------------------------------------
+
+static VP8StatusCode IDecError(WebPIDecoder* const idec, VP8StatusCode error) {
+  if (idec->state_ == STATE_VP8_DATA) {
+    VP8Io* const io = &idec->io_;
+    if (io->teardown != NULL) {
+      io->teardown(io);
+    }
+  }
+  idec->state_ = STATE_ERROR;
+  return error;
+}
+
+static void ChangeState(WebPIDecoder* const idec, DecState new_state,
+                        size_t consumed_bytes) {
+  MemBuffer* const mem = &idec->mem_;
+  idec->state_ = new_state;
+  mem->start_ += consumed_bytes;
+  assert(mem->start_ <= mem->end_);
+  idec->io_.data = mem->buf_ + mem->start_;
+  idec->io_.data_size = MemDataSize(mem);
+}
+
+// Headers
+static VP8StatusCode DecodeWebPHeaders(WebPIDecoder* const idec) {
+  MemBuffer* const mem = &idec->mem_;
+  const uint8_t* data = mem->buf_ + mem->start_;
+  size_t curr_size = MemDataSize(mem);
+  VP8StatusCode status;
+  WebPHeaderStructure headers;
+
+  headers.data = data;
+  headers.data_size = curr_size;
+  headers.have_all_data = 0;
+  status = WebPParseHeaders(&headers);
+  if (status == VP8_STATUS_NOT_ENOUGH_DATA) {
+    return VP8_STATUS_SUSPENDED;  // We haven't found a VP8 chunk yet.
+  } else if (status != VP8_STATUS_OK) {
+    return IDecError(idec, status);
+  }
+
+  idec->chunk_size_ = headers.compressed_size;
+  idec->is_lossless_ = headers.is_lossless;
+  if (!idec->is_lossless_) {
+    VP8Decoder* const dec = VP8New();
+    if (dec == NULL) {
+      return VP8_STATUS_OUT_OF_MEMORY;
+    }
+    idec->dec_ = dec;
+    dec->alpha_data_ = headers.alpha_data;
+    dec->alpha_data_size_ = headers.alpha_data_size;
+    ChangeState(idec, STATE_VP8_HEADER, headers.offset);
+  } else {
+    VP8LDecoder* const dec = VP8LNew();
+    if (dec == NULL) {
+      return VP8_STATUS_OUT_OF_MEMORY;
+    }
+    idec->dec_ = dec;
+    ChangeState(idec, STATE_VP8L_HEADER, headers.offset);
+  }
+  return VP8_STATUS_OK;
+}
+
+static VP8StatusCode DecodeVP8FrameHeader(WebPIDecoder* const idec) {
+  const uint8_t* data = idec->mem_.buf_ + idec->mem_.start_;
+  const size_t curr_size = MemDataSize(&idec->mem_);
+  int width, height;
+  uint32_t bits;
+
+  if (curr_size < VP8_FRAME_HEADER_SIZE) {
+    // Not enough data bytes to extract VP8 Frame Header.
+    return VP8_STATUS_SUSPENDED;
+  }
+  if (!VP8GetInfo(data, curr_size, idec->chunk_size_, &width, &height)) {
+    return IDecError(idec, VP8_STATUS_BITSTREAM_ERROR);
+  }
+
+  bits = data[0] | (data[1] << 8) | (data[2] << 16);
+  idec->mem_.part0_size_ = (bits >> 5) + VP8_FRAME_HEADER_SIZE;
+
+  idec->io_.data = data;
+  idec->io_.data_size = curr_size;
+  idec->state_ = STATE_VP8_PARTS0;
+  return VP8_STATUS_OK;
+}
+
+// Partition #0
+static VP8StatusCode CopyParts0Data(WebPIDecoder* const idec) {
+  VP8Decoder* const dec = (VP8Decoder*)idec->dec_;
+  VP8BitReader* const br = &dec->br_;
+  const size_t part_size = br->buf_end_ - br->buf_;
+  MemBuffer* const mem = &idec->mem_;
+  assert(!idec->is_lossless_);
+  assert(mem->part0_buf_ == NULL);
+  // the following is a format limitation, no need for runtime check:
+  assert(part_size <= mem->part0_size_);
+  if (part_size == 0) {   // can't have zero-size partition #0
+    return VP8_STATUS_BITSTREAM_ERROR;
+  }
+  if (mem->mode_ == MEM_MODE_APPEND) {
+    // We copy and grab ownership of the partition #0 data.
+    uint8_t* const part0_buf = (uint8_t*)WebPSafeMalloc(1ULL, part_size);
+    if (part0_buf == NULL) {
+      return VP8_STATUS_OUT_OF_MEMORY;
+    }
+    memcpy(part0_buf, br->buf_, part_size);
+    mem->part0_buf_ = part0_buf;
+    br->buf_ = part0_buf;
+    br->buf_end_ = part0_buf + part_size;
+  } else {
+    // Else: just keep pointers to the partition #0's data in dec_->br_.
+  }
+  mem->start_ += part_size;
+  return VP8_STATUS_OK;
+}
+
+static VP8StatusCode DecodePartition0(WebPIDecoder* const idec) {
+  VP8Decoder* const dec = (VP8Decoder*)idec->dec_;
+  VP8Io* const io = &idec->io_;
+  const WebPDecParams* const params = &idec->params_;
+  WebPDecBuffer* const output = params->output;
+
+  // Wait till we have enough data for the whole partition #0
+  if (MemDataSize(&idec->mem_) < idec->mem_.part0_size_) {
+    return VP8_STATUS_SUSPENDED;
+  }
+
+  if (!VP8GetHeaders(dec, io)) {
+    const VP8StatusCode status = dec->status_;
+    if (status == VP8_STATUS_SUSPENDED ||
+        status == VP8_STATUS_NOT_ENOUGH_DATA) {
+      // treating NOT_ENOUGH_DATA as SUSPENDED state
+      return VP8_STATUS_SUSPENDED;
+    }
+    return IDecError(idec, status);
+  }
+
+  // Allocate/Verify output buffer now
+  dec->status_ = WebPAllocateDecBuffer(io->width, io->height, params->options,
+                                       output);
+  if (dec->status_ != VP8_STATUS_OK) {
+    return IDecError(idec, dec->status_);
+  }
+  // This change must be done before calling VP8InitFrame()
+  dec->mt_method_ = VP8GetThreadMethod(params->options, NULL,
+                                       io->width, io->height);
+  VP8InitDithering(params->options, dec);
+
+  dec->status_ = CopyParts0Data(idec);
+  if (dec->status_ != VP8_STATUS_OK) {
+    return IDecError(idec, dec->status_);
+  }
+
+  // Finish setting up the decoding parameters. Will call io->setup().
+  if (VP8EnterCritical(dec, io) != VP8_STATUS_OK) {
+    return IDecError(idec, dec->status_);
+  }
+
+  // Note: past this point, teardown() must always be called
+  // in case of error.
+  idec->state_ = STATE_VP8_DATA;
+  // Allocate memory and prepare everything.
+  if (!VP8InitFrame(dec, io)) {
+    return IDecError(idec, dec->status_);
+  }
+  return VP8_STATUS_OK;
+}
+
+// Remaining partitions
+static VP8StatusCode DecodeRemaining(WebPIDecoder* const idec) {
+  VP8Decoder* const dec = (VP8Decoder*)idec->dec_;
+  VP8Io* const io = &idec->io_;
+
+  assert(dec->ready_);
+  for (; dec->mb_y_ < dec->mb_h_; ++dec->mb_y_) {
+    if (idec->last_mb_y_ != dec->mb_y_) {
+      if (!VP8ParseIntraModeRow(&dec->br_, dec)) {
+        // note: normally, error shouldn't occur since we already have the whole
+        // partition0 available here in DecodeRemaining(). Reaching EOF while
+        // reading intra modes really means a BITSTREAM_ERROR.
+        return IDecError(idec, VP8_STATUS_BITSTREAM_ERROR);
+      }
+      idec->last_mb_y_ = dec->mb_y_;
+    }
+    for (; dec->mb_x_ < dec->mb_w_; ++dec->mb_x_) {
+      VP8BitReader* const token_br =
+          &dec->parts_[dec->mb_y_ & (dec->num_parts_ - 1)];
+      MBContext context;
+      SaveContext(dec, token_br, &context);
+      if (!VP8DecodeMB(dec, token_br)) {
+        // We shouldn't fail when MAX_MB data was available
+        if (dec->num_parts_ == 1 && MemDataSize(&idec->mem_) > MAX_MB_SIZE) {
+          return IDecError(idec, VP8_STATUS_BITSTREAM_ERROR);
+        }
+        RestoreContext(&context, dec, token_br);
+        return VP8_STATUS_SUSPENDED;
+      }
+      // Release buffer only if there is only one partition
+      if (dec->num_parts_ == 1) {
+        idec->mem_.start_ = token_br->buf_ - idec->mem_.buf_;
+        assert(idec->mem_.start_ <= idec->mem_.end_);
+      }
+    }
+    VP8InitScanline(dec);   // Prepare for next scanline
+
+    // Reconstruct, filter and emit the row.
+    if (!VP8ProcessRow(dec, io)) {
+      return IDecError(idec, VP8_STATUS_USER_ABORT);
+    }
+  }
+  // Synchronize the thread and check for errors.
+  if (!VP8ExitCritical(dec, io)) {
+    return IDecError(idec, VP8_STATUS_USER_ABORT);
+  }
+  dec->ready_ = 0;
+  return FinishDecoding(idec);
+}
+
+static VP8StatusCode ErrorStatusLossless(WebPIDecoder* const idec,
+                                         VP8StatusCode status) {
+  if (status == VP8_STATUS_SUSPENDED || status == VP8_STATUS_NOT_ENOUGH_DATA) {
+    return VP8_STATUS_SUSPENDED;
+  }
+  return IDecError(idec, status);
+}
+
+static VP8StatusCode DecodeVP8LHeader(WebPIDecoder* const idec) {
+  VP8Io* const io = &idec->io_;
+  VP8LDecoder* const dec = (VP8LDecoder*)idec->dec_;
+  const WebPDecParams* const params = &idec->params_;
+  WebPDecBuffer* const output = params->output;
+  size_t curr_size = MemDataSize(&idec->mem_);
+  assert(idec->is_lossless_);
+
+  // Wait until there's enough data for decoding header.
+  if (curr_size < (idec->chunk_size_ >> 3)) {
+    dec->status_ = VP8_STATUS_SUSPENDED;
+    return ErrorStatusLossless(idec, dec->status_);
+  }
+
+  if (!VP8LDecodeHeader(dec, io)) {
+    if (dec->status_ == VP8_STATUS_BITSTREAM_ERROR &&
+        curr_size < idec->chunk_size_) {
+      dec->status_ = VP8_STATUS_SUSPENDED;
+    }
+    return ErrorStatusLossless(idec, dec->status_);
+  }
+  // Allocate/verify output buffer now.
+  dec->status_ = WebPAllocateDecBuffer(io->width, io->height, params->options,
+                                       output);
+  if (dec->status_ != VP8_STATUS_OK) {
+    return IDecError(idec, dec->status_);
+  }
+
+  idec->state_ = STATE_VP8L_DATA;
+  return VP8_STATUS_OK;
+}
+
+static VP8StatusCode DecodeVP8LData(WebPIDecoder* const idec) {
+  VP8LDecoder* const dec = (VP8LDecoder*)idec->dec_;
+  const size_t curr_size = MemDataSize(&idec->mem_);
+  assert(idec->is_lossless_);
+
+  // Switch to incremental decoding if we don't have all the bytes available.
+  dec->incremental_ = (curr_size < idec->chunk_size_);
+
+  if (!VP8LDecodeImage(dec)) {
+    return ErrorStatusLossless(idec, dec->status_);
+  }
+  assert(dec->status_ == VP8_STATUS_OK || dec->status_ == VP8_STATUS_SUSPENDED);
+  return (dec->status_ == VP8_STATUS_SUSPENDED) ? dec->status_
+                                                : FinishDecoding(idec);
+}
+
+  // Main decoding loop
+static VP8StatusCode IDecode(WebPIDecoder* idec) {
+  VP8StatusCode status = VP8_STATUS_SUSPENDED;
+
+  if (idec->state_ == STATE_WEBP_HEADER) {
+    status = DecodeWebPHeaders(idec);
+  } else {
+    if (idec->dec_ == NULL) {
+      return VP8_STATUS_SUSPENDED;    // can't continue if we have no decoder.
+    }
+  }
+  if (idec->state_ == STATE_VP8_HEADER) {
+    status = DecodeVP8FrameHeader(idec);
+  }
+  if (idec->state_ == STATE_VP8_PARTS0) {
+    status = DecodePartition0(idec);
+  }
+  if (idec->state_ == STATE_VP8_DATA) {
+    status = DecodeRemaining(idec);
+  }
+  if (idec->state_ == STATE_VP8L_HEADER) {
+    status = DecodeVP8LHeader(idec);
+  }
+  if (idec->state_ == STATE_VP8L_DATA) {
+    status = DecodeVP8LData(idec);
+  }
+  return status;
+}
+
+//------------------------------------------------------------------------------
+// Public functions
+
+WebPIDecoder* WebPINewDecoder(WebPDecBuffer* output_buffer) {
+  WebPIDecoder* idec = (WebPIDecoder*)WebPSafeCalloc(1ULL, sizeof(*idec));
+  if (idec == NULL) {
+    return NULL;
+  }
+
+  idec->state_ = STATE_WEBP_HEADER;
+  idec->chunk_size_ = 0;
+
+  idec->last_mb_y_ = -1;
+
+  InitMemBuffer(&idec->mem_);
+  WebPInitDecBuffer(&idec->output_);
+  VP8InitIo(&idec->io_);
+
+  WebPResetDecParams(&idec->params_);
+  idec->params_.output = (output_buffer != NULL) ? output_buffer
+                                                 : &idec->output_;
+  WebPInitCustomIo(&idec->params_, &idec->io_);  // Plug the I/O functions.
+
+  return idec;
+}
+
+WebPIDecoder* WebPIDecode(const uint8_t* data, size_t data_size,
+                          WebPDecoderConfig* config) {
+  WebPIDecoder* idec;
+
+  // Parse the bitstream's features, if requested:
+  if (data != NULL && data_size > 0 && config != NULL) {
+    if (WebPGetFeatures(data, data_size, &config->input) != VP8_STATUS_OK) {
+      return NULL;
+    }
+  }
+  // Create an instance of the incremental decoder
+  idec = WebPINewDecoder(config ? &config->output : NULL);
+  if (idec == NULL) {
+    return NULL;
+  }
+  // Finish initialization
+  if (config != NULL) {
+    idec->params_.options = &config->options;
+  }
+  return idec;
+}
+
+void WebPIDelete(WebPIDecoder* idec) {
+  if (idec == NULL) return;
+  if (idec->dec_ != NULL) {
+    if (!idec->is_lossless_) {
+      if (idec->state_ == STATE_VP8_DATA) {
+        // Synchronize the thread, clean-up and check for errors.
+        VP8ExitCritical((VP8Decoder*)idec->dec_, &idec->io_);
+      }
+      VP8Delete((VP8Decoder*)idec->dec_);
+    } else {
+      VP8LDelete((VP8LDecoder*)idec->dec_);
+    }
+  }
+  ClearMemBuffer(&idec->mem_);
+  WebPFreeDecBuffer(&idec->output_);
+  WebPSafeFree(idec);
+}
+
+//------------------------------------------------------------------------------
+// Wrapper toward WebPINewDecoder
+
+WebPIDecoder* WebPINewRGB(WEBP_CSP_MODE mode, uint8_t* output_buffer,
+                          size_t output_buffer_size, int output_stride) {
+  const int is_external_memory = (output_buffer != NULL);
+  WebPIDecoder* idec;
+
+  if (mode >= MODE_YUV) return NULL;
+  if (!is_external_memory) {    // Overwrite parameters to sane values.
+    output_buffer_size = 0;
+    output_stride = 0;
+  } else {  // A buffer was passed. Validate the other params.
+    if (output_stride == 0 || output_buffer_size == 0) {
+      return NULL;   // invalid parameter.
+    }
+  }
+  idec = WebPINewDecoder(NULL);
+  if (idec == NULL) return NULL;
+  idec->output_.colorspace = mode;
+  idec->output_.is_external_memory = is_external_memory;
+  idec->output_.u.RGBA.rgba = output_buffer;
+  idec->output_.u.RGBA.stride = output_stride;
+  idec->output_.u.RGBA.size = output_buffer_size;
+  return idec;
+}
+
+WebPIDecoder* WebPINewYUVA(uint8_t* luma, size_t luma_size, int luma_stride,
+                           uint8_t* u, size_t u_size, int u_stride,
+                           uint8_t* v, size_t v_size, int v_stride,
+                           uint8_t* a, size_t a_size, int a_stride) {
+  const int is_external_memory = (luma != NULL);
+  WebPIDecoder* idec;
+  WEBP_CSP_MODE colorspace;
+
+  if (!is_external_memory) {    // Overwrite parameters to sane values.
+    luma_size = u_size = v_size = a_size = 0;
+    luma_stride = u_stride = v_stride = a_stride = 0;
+    u = v = a = NULL;
+    colorspace = MODE_YUVA;
+  } else {  // A luma buffer was passed. Validate the other parameters.
+    if (u == NULL || v == NULL) return NULL;
+    if (luma_size == 0 || u_size == 0 || v_size == 0) return NULL;
+    if (luma_stride == 0 || u_stride == 0 || v_stride == 0) return NULL;
+    if (a != NULL) {
+      if (a_size == 0 || a_stride == 0) return NULL;
+    }
+    colorspace = (a == NULL) ? MODE_YUV : MODE_YUVA;
+  }
+
+  idec = WebPINewDecoder(NULL);
+  if (idec == NULL) return NULL;
+
+  idec->output_.colorspace = colorspace;
+  idec->output_.is_external_memory = is_external_memory;
+  idec->output_.u.YUVA.y = luma;
+  idec->output_.u.YUVA.y_stride = luma_stride;
+  idec->output_.u.YUVA.y_size = luma_size;
+  idec->output_.u.YUVA.u = u;
+  idec->output_.u.YUVA.u_stride = u_stride;
+  idec->output_.u.YUVA.u_size = u_size;
+  idec->output_.u.YUVA.v = v;
+  idec->output_.u.YUVA.v_stride = v_stride;
+  idec->output_.u.YUVA.v_size = v_size;
+  idec->output_.u.YUVA.a = a;
+  idec->output_.u.YUVA.a_stride = a_stride;
+  idec->output_.u.YUVA.a_size = a_size;
+  return idec;
+}
+
+WebPIDecoder* WebPINewYUV(uint8_t* luma, size_t luma_size, int luma_stride,
+                          uint8_t* u, size_t u_size, int u_stride,
+                          uint8_t* v, size_t v_size, int v_stride) {
+  return WebPINewYUVA(luma, luma_size, luma_stride,
+                      u, u_size, u_stride,
+                      v, v_size, v_stride,
+                      NULL, 0, 0);
+}
+
+//------------------------------------------------------------------------------
+
+static VP8StatusCode IDecCheckStatus(const WebPIDecoder* const idec) {
+  assert(idec);
+  if (idec->state_ == STATE_ERROR) {
+    return VP8_STATUS_BITSTREAM_ERROR;
+  }
+  if (idec->state_ == STATE_DONE) {
+    return VP8_STATUS_OK;
+  }
+  return VP8_STATUS_SUSPENDED;
+}
+
+VP8StatusCode WebPIAppend(WebPIDecoder* idec,
+                          const uint8_t* data, size_t data_size) {
+  VP8StatusCode status;
+  if (idec == NULL || data == NULL) {
+    return VP8_STATUS_INVALID_PARAM;
+  }
+  status = IDecCheckStatus(idec);
+  if (status != VP8_STATUS_SUSPENDED) {
+    return status;
+  }
+  // Check mixed calls between RemapMemBuffer and AppendToMemBuffer.
+  if (!CheckMemBufferMode(&idec->mem_, MEM_MODE_APPEND)) {
+    return VP8_STATUS_INVALID_PARAM;
+  }
+  // Append data to memory buffer
+  if (!AppendToMemBuffer(idec, data, data_size)) {
+    return VP8_STATUS_OUT_OF_MEMORY;
+  }
+  return IDecode(idec);
+}
+
+VP8StatusCode WebPIUpdate(WebPIDecoder* idec,
+                          const uint8_t* data, size_t data_size) {
+  VP8StatusCode status;
+  if (idec == NULL || data == NULL) {
+    return VP8_STATUS_INVALID_PARAM;
+  }
+  status = IDecCheckStatus(idec);
+  if (status != VP8_STATUS_SUSPENDED) {
+    return status;
+  }
+  // Check mixed calls between RemapMemBuffer and AppendToMemBuffer.
+  if (!CheckMemBufferMode(&idec->mem_, MEM_MODE_MAP)) {
+    return VP8_STATUS_INVALID_PARAM;
+  }
+  // Make the memory buffer point to the new buffer
+  if (!RemapMemBuffer(idec, data, data_size)) {
+    return VP8_STATUS_INVALID_PARAM;
+  }
+  return IDecode(idec);
+}
+
+//------------------------------------------------------------------------------
+
+static const WebPDecBuffer* GetOutputBuffer(const WebPIDecoder* const idec) {
+  if (idec == NULL || idec->dec_ == NULL) {
+    return NULL;
+  }
+  if (idec->state_ <= STATE_VP8_PARTS0) {
+    return NULL;
+  }
+  return idec->params_.output;
+}
+
+const WebPDecBuffer* WebPIDecodedArea(const WebPIDecoder* idec,
+                                      int* left, int* top,
+                                      int* width, int* height) {
+  const WebPDecBuffer* const src = GetOutputBuffer(idec);
+  if (left != NULL) *left = 0;
+  if (top != NULL) *top = 0;
+  // TODO(skal): later include handling of rotations.
+  if (src) {
+    if (width != NULL) *width = src->width;
+    if (height != NULL) *height = idec->params_.last_y;
+  } else {
+    if (width != NULL) *width = 0;
+    if (height != NULL) *height = 0;
+  }
+  return src;
+}
+
+uint8_t* WebPIDecGetRGB(const WebPIDecoder* idec, int* last_y,
+                        int* width, int* height, int* stride) {
+  const WebPDecBuffer* const src = GetOutputBuffer(idec);
+  if (src == NULL) return NULL;
+  if (src->colorspace >= MODE_YUV) {
+    return NULL;
+  }
+
+  if (last_y != NULL) *last_y = idec->params_.last_y;
+  if (width != NULL) *width = src->width;
+  if (height != NULL) *height = src->height;
+  if (stride != NULL) *stride = src->u.RGBA.stride;
+
+  return src->u.RGBA.rgba;
+}
+
+uint8_t* WebPIDecGetYUVA(const WebPIDecoder* idec, int* last_y,
+                         uint8_t** u, uint8_t** v, uint8_t** a,
+                         int* width, int* height,
+                         int* stride, int* uv_stride, int* a_stride) {
+  const WebPDecBuffer* const src = GetOutputBuffer(idec);
+  if (src == NULL) return NULL;
+  if (src->colorspace < MODE_YUV) {
+    return NULL;
+  }
+
+  if (last_y != NULL) *last_y = idec->params_.last_y;
+  if (u != NULL) *u = src->u.YUVA.u;
+  if (v != NULL) *v = src->u.YUVA.v;
+  if (a != NULL) *a = src->u.YUVA.a;
+  if (width != NULL) *width = src->width;
+  if (height != NULL) *height = src->height;
+  if (stride != NULL) *stride = src->u.YUVA.y_stride;
+  if (uv_stride != NULL) *uv_stride = src->u.YUVA.u_stride;
+  if (a_stride != NULL) *a_stride = src->u.YUVA.a_stride;
+
+  return src->u.YUVA.y;
+}
+
+int WebPISetIOHooks(WebPIDecoder* const idec,
+                    VP8IoPutHook put,
+                    VP8IoSetupHook setup,
+                    VP8IoTeardownHook teardown,
+                    void* user_data) {
+  if (idec == NULL || idec->state_ > STATE_WEBP_HEADER) {
+    return 0;
+  }
+
+  idec->io_.put = put;
+  idec->io_.setup = setup;
+  idec->io_.teardown = teardown;
+  idec->io_.opaque = user_data;
+
+  return 1;
+}
diff --git a/Source/LibWebP/src/dec/dec.io.c b/Source/LibWebP/src/dec/dec.io.c
new file mode 100644
index 0000000..bc6a147
--- /dev/null
+++ b/Source/LibWebP/src/dec/dec.io.c
@@ -0,0 +1,640 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// functions for sample output.
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include <assert.h>
+#include <stdlib.h>
+#include "../dec/vp8i.h"
+#include "./webpi.h"
+#include "../dsp/dsp.h"
+#include "../dsp/yuv.h"
+#include "../utils/utils.h"
+
+//------------------------------------------------------------------------------
+// Main YUV<->RGB conversion functions
+
+static int EmitYUV(const VP8Io* const io, WebPDecParams* const p) {
+  WebPDecBuffer* output = p->output;
+  const WebPYUVABuffer* const buf = &output->u.YUVA;
+  uint8_t* const y_dst = buf->y + io->mb_y * buf->y_stride;
+  uint8_t* const u_dst = buf->u + (io->mb_y >> 1) * buf->u_stride;
+  uint8_t* const v_dst = buf->v + (io->mb_y >> 1) * buf->v_stride;
+  const int mb_w = io->mb_w;
+  const int mb_h = io->mb_h;
+  const int uv_w = (mb_w + 1) / 2;
+  const int uv_h = (mb_h + 1) / 2;
+  int j;
+  for (j = 0; j < mb_h; ++j) {
+    memcpy(y_dst + j * buf->y_stride, io->y + j * io->y_stride, mb_w);
+  }
+  for (j = 0; j < uv_h; ++j) {
+    memcpy(u_dst + j * buf->u_stride, io->u + j * io->uv_stride, uv_w);
+    memcpy(v_dst + j * buf->v_stride, io->v + j * io->uv_stride, uv_w);
+  }
+  return io->mb_h;
+}
+
+// Point-sampling U/V sampler.
+static int EmitSampledRGB(const VP8Io* const io, WebPDecParams* const p) {
+  WebPDecBuffer* const output = p->output;
+  WebPRGBABuffer* const buf = &output->u.RGBA;
+  uint8_t* const dst = buf->rgba + io->mb_y * buf->stride;
+  WebPSamplerProcessPlane(io->y, io->y_stride,
+                          io->u, io->v, io->uv_stride,
+                          dst, buf->stride, io->mb_w, io->mb_h,
+                          WebPSamplers[output->colorspace]);
+  return io->mb_h;
+}
+
+//------------------------------------------------------------------------------
+// YUV444 -> RGB conversion
+
+#if 0   // TODO(skal): this is for future rescaling.
+static int EmitRGB(const VP8Io* const io, WebPDecParams* const p) {
+  WebPDecBuffer* output = p->output;
+  const WebPRGBABuffer* const buf = &output->u.RGBA;
+  uint8_t* dst = buf->rgba + io->mb_y * buf->stride;
+  const uint8_t* y_src = io->y;
+  const uint8_t* u_src = io->u;
+  const uint8_t* v_src = io->v;
+  const WebPYUV444Converter convert = WebPYUV444Converters[output->colorspace];
+  const int mb_w = io->mb_w;
+  const int last = io->mb_h;
+  int j;
+  for (j = 0; j < last; ++j) {
+    convert(y_src, u_src, v_src, dst, mb_w);
+    y_src += io->y_stride;
+    u_src += io->uv_stride;
+    v_src += io->uv_stride;
+    dst += buf->stride;
+  }
+  return io->mb_h;
+}
+#endif
+
+//------------------------------------------------------------------------------
+// Fancy upsampling
+
+#ifdef FANCY_UPSAMPLING
+static int EmitFancyRGB(const VP8Io* const io, WebPDecParams* const p) {
+  int num_lines_out = io->mb_h;   // a priori guess
+  const WebPRGBABuffer* const buf = &p->output->u.RGBA;
+  uint8_t* dst = buf->rgba + io->mb_y * buf->stride;
+  WebPUpsampleLinePairFunc upsample = WebPUpsamplers[p->output->colorspace];
+  const uint8_t* cur_y = io->y;
+  const uint8_t* cur_u = io->u;
+  const uint8_t* cur_v = io->v;
+  const uint8_t* top_u = p->tmp_u;
+  const uint8_t* top_v = p->tmp_v;
+  int y = io->mb_y;
+  const int y_end = io->mb_y + io->mb_h;
+  const int mb_w = io->mb_w;
+  const int uv_w = (mb_w + 1) / 2;
+
+  if (y == 0) {
+    // First line is special cased. We mirror the u/v samples at boundary.
+    upsample(cur_y, NULL, cur_u, cur_v, cur_u, cur_v, dst, NULL, mb_w);
+  } else {
+    // We can finish the left-over line from previous call.
+    upsample(p->tmp_y, cur_y, top_u, top_v, cur_u, cur_v,
+             dst - buf->stride, dst, mb_w);
+    ++num_lines_out;
+  }
+  // Loop over each output pairs of row.
+  for (; y + 2 < y_end; y += 2) {
+    top_u = cur_u;
+    top_v = cur_v;
+    cur_u += io->uv_stride;
+    cur_v += io->uv_stride;
+    dst += 2 * buf->stride;
+    cur_y += 2 * io->y_stride;
+    upsample(cur_y - io->y_stride, cur_y,
+             top_u, top_v, cur_u, cur_v,
+             dst - buf->stride, dst, mb_w);
+  }
+  // move to last row
+  cur_y += io->y_stride;
+  if (io->crop_top + y_end < io->crop_bottom) {
+    // Save the unfinished samples for next call (as we're not done yet).
+    memcpy(p->tmp_y, cur_y, mb_w * sizeof(*p->tmp_y));
+    memcpy(p->tmp_u, cur_u, uv_w * sizeof(*p->tmp_u));
+    memcpy(p->tmp_v, cur_v, uv_w * sizeof(*p->tmp_v));
+    // The fancy upsampler leaves a row unfinished behind
+    // (except for the very last row)
+    num_lines_out--;
+  } else {
+    // Process the very last row of even-sized picture
+    if (!(y_end & 1)) {
+      upsample(cur_y, NULL, cur_u, cur_v, cur_u, cur_v,
+               dst + buf->stride, NULL, mb_w);
+    }
+  }
+  return num_lines_out;
+}
+
+#endif    /* FANCY_UPSAMPLING */
+
+//------------------------------------------------------------------------------
+
+static int EmitAlphaYUV(const VP8Io* const io, WebPDecParams* const p) {
+  const uint8_t* alpha = io->a;
+  const WebPYUVABuffer* const buf = &p->output->u.YUVA;
+  const int mb_w = io->mb_w;
+  const int mb_h = io->mb_h;
+  uint8_t* dst = buf->a + io->mb_y * buf->a_stride;
+  int j;
+
+  if (alpha != NULL) {
+    for (j = 0; j < mb_h; ++j) {
+      memcpy(dst, alpha, mb_w * sizeof(*dst));
+      alpha += io->width;
+      dst += buf->a_stride;
+    }
+  } else if (buf->a != NULL) {
+    // the user requested alpha, but there is none, set it to opaque.
+    for (j = 0; j < mb_h; ++j) {
+      memset(dst, 0xff, mb_w * sizeof(*dst));
+      dst += buf->a_stride;
+    }
+  }
+  return 0;
+}
+
+static int GetAlphaSourceRow(const VP8Io* const io,
+                             const uint8_t** alpha, int* const num_rows) {
+  int start_y = io->mb_y;
+  *num_rows = io->mb_h;
+
+  // Compensate for the 1-line delay of the fancy upscaler.
+  // This is similar to EmitFancyRGB().
+  if (io->fancy_upsampling) {
+    if (start_y == 0) {
+      // We don't process the last row yet. It'll be done during the next call.
+      --*num_rows;
+    } else {
+      --start_y;
+      // Fortunately, *alpha data is persistent, so we can go back
+      // one row and finish alpha blending, now that the fancy upscaler
+      // completed the YUV->RGB interpolation.
+      *alpha -= io->width;
+    }
+    if (io->crop_top + io->mb_y + io->mb_h == io->crop_bottom) {
+      // If it's the very last call, we process all the remaining rows!
+      *num_rows = io->crop_bottom - io->crop_top - start_y;
+    }
+  }
+  return start_y;
+}
+
+static int EmitAlphaRGB(const VP8Io* const io, WebPDecParams* const p) {
+  const uint8_t* alpha = io->a;
+  if (alpha != NULL) {
+    const int mb_w = io->mb_w;
+    const WEBP_CSP_MODE colorspace = p->output->colorspace;
+    const int alpha_first =
+        (colorspace == MODE_ARGB || colorspace == MODE_Argb);
+    const WebPRGBABuffer* const buf = &p->output->u.RGBA;
+    int num_rows;
+    const int start_y = GetAlphaSourceRow(io, &alpha, &num_rows);
+    uint8_t* const base_rgba = buf->rgba + start_y * buf->stride;
+    uint8_t* const dst = base_rgba + (alpha_first ? 0 : 3);
+    const int has_alpha = WebPDispatchAlpha(alpha, io->width, mb_w,
+                                            num_rows, dst, buf->stride);
+
+    // has_alpha is true if there's non-trivial alpha to premultiply with.
+    if (has_alpha && WebPIsPremultipliedMode(colorspace)) {
+      WebPApplyAlphaMultiply(base_rgba, alpha_first,
+                             mb_w, num_rows, buf->stride);
+    }
+  }
+  return 0;
+}
+
+static int EmitAlphaRGBA4444(const VP8Io* const io, WebPDecParams* const p) {
+  const uint8_t* alpha = io->a;
+  if (alpha != NULL) {
+    const int mb_w = io->mb_w;
+    const WEBP_CSP_MODE colorspace = p->output->colorspace;
+    const WebPRGBABuffer* const buf = &p->output->u.RGBA;
+    int num_rows;
+    const int start_y = GetAlphaSourceRow(io, &alpha, &num_rows);
+    uint8_t* const base_rgba = buf->rgba + start_y * buf->stride;
+#ifdef WEBP_SWAP_16BIT_CSP
+    uint8_t* alpha_dst = base_rgba;
+#else
+    uint8_t* alpha_dst = base_rgba + 1;
+#endif
+    uint32_t alpha_mask = 0x0f;
+    int i, j;
+
+    for (j = 0; j < num_rows; ++j) {
+      for (i = 0; i < mb_w; ++i) {
+        // Fill in the alpha value (converted to 4 bits).
+        const uint32_t alpha_value = alpha[i] >> 4;
+        alpha_dst[2 * i] = (alpha_dst[2 * i] & 0xf0) | alpha_value;
+        alpha_mask &= alpha_value;
+      }
+      alpha += io->width;
+      alpha_dst += buf->stride;
+    }
+    if (alpha_mask != 0x0f && WebPIsPremultipliedMode(colorspace)) {
+      WebPApplyAlphaMultiply4444(base_rgba, mb_w, num_rows, buf->stride);
+    }
+  }
+  return 0;
+}
+
+//------------------------------------------------------------------------------
+// YUV rescaling (no final RGB conversion needed)
+
+static int Rescale(const uint8_t* src, int src_stride,
+                   int new_lines, WebPRescaler* const wrk) {
+  int num_lines_out = 0;
+  while (new_lines > 0) {    // import new contributions of source rows.
+    const int lines_in = WebPRescalerImport(wrk, new_lines, src, src_stride);
+    src += lines_in * src_stride;
+    new_lines -= lines_in;
+    num_lines_out += WebPRescalerExport(wrk);    // emit output row(s)
+  }
+  return num_lines_out;
+}
+
+static int EmitRescaledYUV(const VP8Io* const io, WebPDecParams* const p) {
+  const int mb_h = io->mb_h;
+  const int uv_mb_h = (mb_h + 1) >> 1;
+  WebPRescaler* const scaler = &p->scaler_y;
+  int num_lines_out = 0;
+  if (WebPIsAlphaMode(p->output->colorspace) && io->a != NULL) {
+    // Before rescaling, we premultiply the luma directly into the io->y
+    // internal buffer. This is OK since these samples are not used for
+    // intra-prediction (the top samples are saved in cache_y_/u_/v_).
+    // But we need to cast the const away, though.
+    WebPMultRows((uint8_t*)io->y, io->y_stride,
+                 io->a, io->width, io->mb_w, mb_h, 0);
+  }
+  num_lines_out = Rescale(io->y, io->y_stride, mb_h, scaler);
+  Rescale(io->u, io->uv_stride, uv_mb_h, &p->scaler_u);
+  Rescale(io->v, io->uv_stride, uv_mb_h, &p->scaler_v);
+  return num_lines_out;
+}
+
+static int EmitRescaledAlphaYUV(const VP8Io* const io, WebPDecParams* const p) {
+  if (io->a != NULL) {
+    const WebPYUVABuffer* const buf = &p->output->u.YUVA;
+    uint8_t* dst_y = buf->y + p->last_y * buf->y_stride;
+    const uint8_t* src_a = buf->a + p->last_y * buf->a_stride;
+    const int num_lines_out = Rescale(io->a, io->width, io->mb_h, &p->scaler_a);
+    if (num_lines_out > 0) {   // unmultiply the Y
+      WebPMultRows(dst_y, buf->y_stride, src_a, buf->a_stride,
+                   p->scaler_a.dst_width, num_lines_out, 1);
+    }
+  }
+  return 0;
+}
+
+static int InitYUVRescaler(const VP8Io* const io, WebPDecParams* const p) {
+  const int has_alpha = WebPIsAlphaMode(p->output->colorspace);
+  const WebPYUVABuffer* const buf = &p->output->u.YUVA;
+  const int out_width  = io->scaled_width;
+  const int out_height = io->scaled_height;
+  const int uv_out_width  = (out_width + 1) >> 1;
+  const int uv_out_height = (out_height + 1) >> 1;
+  const int uv_in_width  = (io->mb_w + 1) >> 1;
+  const int uv_in_height = (io->mb_h + 1) >> 1;
+  const size_t work_size = 2 * out_width;   // scratch memory for luma rescaler
+  const size_t uv_work_size = 2 * uv_out_width;  // and for each u/v ones
+  size_t tmp_size;
+  int32_t* work;
+
+  tmp_size = (work_size + 2 * uv_work_size) * sizeof(*work);
+  if (has_alpha) {
+    tmp_size += work_size * sizeof(*work);
+  }
+  p->memory = WebPSafeCalloc(1ULL, tmp_size);
+  if (p->memory == NULL) {
+    return 0;   // memory error
+  }
+  work = (int32_t*)p->memory;
+  WebPRescalerInit(&p->scaler_y, io->mb_w, io->mb_h,
+                   buf->y, out_width, out_height, buf->y_stride, 1,
+                   io->mb_w, out_width, io->mb_h, out_height,
+                   work);
+  WebPRescalerInit(&p->scaler_u, uv_in_width, uv_in_height,
+                   buf->u, uv_out_width, uv_out_height, buf->u_stride, 1,
+                   uv_in_width, uv_out_width,
+                   uv_in_height, uv_out_height,
+                   work + work_size);
+  WebPRescalerInit(&p->scaler_v, uv_in_width, uv_in_height,
+                   buf->v, uv_out_width, uv_out_height, buf->v_stride, 1,
+                   uv_in_width, uv_out_width,
+                   uv_in_height, uv_out_height,
+                   work + work_size + uv_work_size);
+  p->emit = EmitRescaledYUV;
+
+  if (has_alpha) {
+    WebPRescalerInit(&p->scaler_a, io->mb_w, io->mb_h,
+                     buf->a, out_width, out_height, buf->a_stride, 1,
+                     io->mb_w, out_width, io->mb_h, out_height,
+                     work + work_size + 2 * uv_work_size);
+    p->emit_alpha = EmitRescaledAlphaYUV;
+    WebPInitAlphaProcessing();
+  }
+  return 1;
+}
+
+//------------------------------------------------------------------------------
+// RGBA rescaling
+
+static int ExportRGB(WebPDecParams* const p, int y_pos) {
+  const WebPYUV444Converter convert =
+      WebPYUV444Converters[p->output->colorspace];
+  const WebPRGBABuffer* const buf = &p->output->u.RGBA;
+  uint8_t* dst = buf->rgba + (p->last_y + y_pos) * buf->stride;
+  int num_lines_out = 0;
+  // For RGB rescaling, because of the YUV420, current scan position
+  // U/V can be +1/-1 line from the Y one.  Hence the double test.
+  while (WebPRescalerHasPendingOutput(&p->scaler_y) &&
+         WebPRescalerHasPendingOutput(&p->scaler_u)) {
+    assert(p->last_y + y_pos + num_lines_out < p->output->height);
+    assert(p->scaler_u.y_accum == p->scaler_v.y_accum);
+    WebPRescalerExportRow(&p->scaler_y, 0);
+    WebPRescalerExportRow(&p->scaler_u, 0);
+    WebPRescalerExportRow(&p->scaler_v, 0);
+    convert(p->scaler_y.dst, p->scaler_u.dst, p->scaler_v.dst,
+            dst, p->scaler_y.dst_width);
+    dst += buf->stride;
+    ++num_lines_out;
+  }
+  return num_lines_out;
+}
+
+static int EmitRescaledRGB(const VP8Io* const io, WebPDecParams* const p) {
+  const int mb_h = io->mb_h;
+  const int uv_mb_h = (mb_h + 1) >> 1;
+  int j = 0, uv_j = 0;
+  int num_lines_out = 0;
+  while (j < mb_h) {
+    const int y_lines_in =
+        WebPRescalerImport(&p->scaler_y, mb_h - j,
+                           io->y + j * io->y_stride, io->y_stride);
+    const int u_lines_in =
+        WebPRescalerImport(&p->scaler_u, uv_mb_h - uv_j,
+                           io->u + uv_j * io->uv_stride, io->uv_stride);
+    const int v_lines_in =
+        WebPRescalerImport(&p->scaler_v, uv_mb_h - uv_j,
+                           io->v + uv_j * io->uv_stride, io->uv_stride);
+    (void)v_lines_in;   // remove a gcc warning
+    assert(u_lines_in == v_lines_in);
+    j += y_lines_in;
+    uv_j += u_lines_in;
+    num_lines_out += ExportRGB(p, num_lines_out);
+  }
+  return num_lines_out;
+}
+
+static int ExportAlpha(WebPDecParams* const p, int y_pos) {
+  const WebPRGBABuffer* const buf = &p->output->u.RGBA;
+  uint8_t* const base_rgba = buf->rgba + (p->last_y + y_pos) * buf->stride;
+  const WEBP_CSP_MODE colorspace = p->output->colorspace;
+  const int alpha_first =
+      (colorspace == MODE_ARGB || colorspace == MODE_Argb);
+  uint8_t* dst = base_rgba + (alpha_first ? 0 : 3);
+  int num_lines_out = 0;
+  const int is_premult_alpha = WebPIsPremultipliedMode(colorspace);
+  uint32_t alpha_mask = 0xff;
+  const int width = p->scaler_a.dst_width;
+
+  while (WebPRescalerHasPendingOutput(&p->scaler_a)) {
+    int i;
+    assert(p->last_y + y_pos + num_lines_out < p->output->height);
+    WebPRescalerExportRow(&p->scaler_a, 0);
+    for (i = 0; i < width; ++i) {
+      const uint32_t alpha_value = p->scaler_a.dst[i];
+      dst[4 * i] = alpha_value;
+      alpha_mask &= alpha_value;
+    }
+    dst += buf->stride;
+    ++num_lines_out;
+  }
+  if (is_premult_alpha && alpha_mask != 0xff) {
+    WebPApplyAlphaMultiply(base_rgba, alpha_first,
+                           width, num_lines_out, buf->stride);
+  }
+  return num_lines_out;
+}
+
+static int ExportAlphaRGBA4444(WebPDecParams* const p, int y_pos) {
+  const WebPRGBABuffer* const buf = &p->output->u.RGBA;
+  uint8_t* const base_rgba = buf->rgba + (p->last_y + y_pos) * buf->stride;
+#ifdef WEBP_SWAP_16BIT_CSP
+  uint8_t* alpha_dst = base_rgba;
+#else
+  uint8_t* alpha_dst = base_rgba + 1;
+#endif
+  int num_lines_out = 0;
+  const WEBP_CSP_MODE colorspace = p->output->colorspace;
+  const int width = p->scaler_a.dst_width;
+  const int is_premult_alpha = WebPIsPremultipliedMode(colorspace);
+  uint32_t alpha_mask = 0x0f;
+
+  while (WebPRescalerHasPendingOutput(&p->scaler_a)) {
+    int i;
+    assert(p->last_y + y_pos + num_lines_out < p->output->height);
+    WebPRescalerExportRow(&p->scaler_a, 0);
+    for (i = 0; i < width; ++i) {
+      // Fill in the alpha value (converted to 4 bits).
+      const uint32_t alpha_value = p->scaler_a.dst[i] >> 4;
+      alpha_dst[2 * i] = (alpha_dst[2 * i] & 0xf0) | alpha_value;
+      alpha_mask &= alpha_value;
+    }
+    alpha_dst += buf->stride;
+    ++num_lines_out;
+  }
+  if (is_premult_alpha && alpha_mask != 0x0f) {
+    WebPApplyAlphaMultiply4444(base_rgba, width, num_lines_out, buf->stride);
+  }
+  return num_lines_out;
+}
+
+static int EmitRescaledAlphaRGB(const VP8Io* const io, WebPDecParams* const p) {
+  if (io->a != NULL) {
+    WebPRescaler* const scaler = &p->scaler_a;
+    int j = 0;
+    int pos = 0;
+    while (j < io->mb_h) {
+      j += WebPRescalerImport(scaler, io->mb_h - j,
+                              io->a + j * io->width, io->width);
+      pos += p->emit_alpha_row(p, pos);
+    }
+  }
+  return 0;
+}
+
+static int InitRGBRescaler(const VP8Io* const io, WebPDecParams* const p) {
+  const int has_alpha = WebPIsAlphaMode(p->output->colorspace);
+  const int out_width  = io->scaled_width;
+  const int out_height = io->scaled_height;
+  const int uv_in_width  = (io->mb_w + 1) >> 1;
+  const int uv_in_height = (io->mb_h + 1) >> 1;
+  const size_t work_size = 2 * out_width;   // scratch memory for one rescaler
+  int32_t* work;  // rescalers work area
+  uint8_t* tmp;   // tmp storage for scaled YUV444 samples before RGB conversion
+  size_t tmp_size1, tmp_size2, total_size;
+
+  tmp_size1 = 3 * work_size;
+  tmp_size2 = 3 * out_width;
+  if (has_alpha) {
+    tmp_size1 += work_size;
+    tmp_size2 += out_width;
+  }
+  total_size = tmp_size1 * sizeof(*work) + tmp_size2 * sizeof(*tmp);
+  p->memory = WebPSafeCalloc(1ULL, total_size);
+  if (p->memory == NULL) {
+    return 0;   // memory error
+  }
+  work = (int32_t*)p->memory;
+  tmp = (uint8_t*)(work + tmp_size1);
+  WebPRescalerInit(&p->scaler_y, io->mb_w, io->mb_h,
+                   tmp + 0 * out_width, out_width, out_height, 0, 1,
+                   io->mb_w, out_width, io->mb_h, out_height,
+                   work + 0 * work_size);
+  WebPRescalerInit(&p->scaler_u, uv_in_width, uv_in_height,
+                   tmp + 1 * out_width, out_width, out_height, 0, 1,
+                   io->mb_w, 2 * out_width, io->mb_h, 2 * out_height,
+                   work + 1 * work_size);
+  WebPRescalerInit(&p->scaler_v, uv_in_width, uv_in_height,
+                   tmp + 2 * out_width, out_width, out_height, 0, 1,
+                   io->mb_w, 2 * out_width, io->mb_h, 2 * out_height,
+                   work + 2 * work_size);
+  p->emit = EmitRescaledRGB;
+  WebPInitYUV444Converters();
+
+  if (has_alpha) {
+    WebPRescalerInit(&p->scaler_a, io->mb_w, io->mb_h,
+                     tmp + 3 * out_width, out_width, out_height, 0, 1,
+                     io->mb_w, out_width, io->mb_h, out_height,
+                     work + 3 * work_size);
+    p->emit_alpha = EmitRescaledAlphaRGB;
+    if (p->output->colorspace == MODE_RGBA_4444 ||
+        p->output->colorspace == MODE_rgbA_4444) {
+      p->emit_alpha_row = ExportAlphaRGBA4444;
+    } else {
+      p->emit_alpha_row = ExportAlpha;
+    }
+    WebPInitAlphaProcessing();
+  }
+  return 1;
+}
+
+//------------------------------------------------------------------------------
+// Default custom functions
+
+static int CustomSetup(VP8Io* io) {
+  WebPDecParams* const p = (WebPDecParams*)io->opaque;
+  const WEBP_CSP_MODE colorspace = p->output->colorspace;
+  const int is_rgb = WebPIsRGBMode(colorspace);
+  const int is_alpha = WebPIsAlphaMode(colorspace);
+
+  p->memory = NULL;
+  p->emit = NULL;
+  p->emit_alpha = NULL;
+  p->emit_alpha_row = NULL;
+  if (!WebPIoInitFromOptions(p->options, io, is_alpha ? MODE_YUV : MODE_YUVA)) {
+    return 0;
+  }
+  if (is_alpha && WebPIsPremultipliedMode(colorspace)) {
+    WebPInitUpsamplers();
+  }
+  if (io->use_scaling) {
+    const int ok = is_rgb ? InitRGBRescaler(io, p) : InitYUVRescaler(io, p);
+    if (!ok) {
+      return 0;    // memory error
+    }
+  } else {
+    if (is_rgb) {
+      p->emit = EmitSampledRGB;   // default
+      if (io->fancy_upsampling) {
+#ifdef FANCY_UPSAMPLING
+        const int uv_width = (io->mb_w + 1) >> 1;
+        p->memory = WebPSafeMalloc(1ULL, (size_t)(io->mb_w + 2 * uv_width));
+        if (p->memory == NULL) {
+          return 0;   // memory error.
+        }
+        p->tmp_y = (uint8_t*)p->memory;
+        p->tmp_u = p->tmp_y + io->mb_w;
+        p->tmp_v = p->tmp_u + uv_width;
+        p->emit = EmitFancyRGB;
+        WebPInitUpsamplers();
+#endif
+      } else {
+        WebPInitSamplers();
+      }
+    } else {
+      p->emit = EmitYUV;
+    }
+    if (is_alpha) {  // need transparency output
+      p->emit_alpha =
+          (colorspace == MODE_RGBA_4444 || colorspace == MODE_rgbA_4444) ?
+              EmitAlphaRGBA4444
+          : is_rgb ? EmitAlphaRGB
+          : EmitAlphaYUV;
+      if (is_rgb) {
+        WebPInitAlphaProcessing();
+      }
+    }
+  }
+
+  if (is_rgb) {
+    VP8YUVInit();
+  }
+  return 1;
+}
+
+//------------------------------------------------------------------------------
+
+static int CustomPut(const VP8Io* io) {
+  WebPDecParams* const p = (WebPDecParams*)io->opaque;
+  const int mb_w = io->mb_w;
+  const int mb_h = io->mb_h;
+  int num_lines_out;
+  assert(!(io->mb_y & 1));
+
+  if (mb_w <= 0 || mb_h <= 0) {
+    return 0;
+  }
+  num_lines_out = p->emit(io, p);
+  if (p->emit_alpha != NULL) {
+    p->emit_alpha(io, p);
+  }
+  p->last_y += num_lines_out;
+  return 1;
+}
+
+//------------------------------------------------------------------------------
+
+static void CustomTeardown(const VP8Io* io) {
+  WebPDecParams* const p = (WebPDecParams*)io->opaque;
+  WebPSafeFree(p->memory);
+  p->memory = NULL;
+}
+
+//------------------------------------------------------------------------------
+// Main entry point
+
+void WebPInitCustomIo(WebPDecParams* const params, VP8Io* const io) {
+  io->put      = CustomPut;
+  io->setup    = CustomSetup;
+  io->teardown = CustomTeardown;
+  io->opaque   = params;
+}
+
+//------------------------------------------------------------------------------
diff --git a/Source/LibWebP/src/dec/dec.quant.c b/Source/LibWebP/src/dec/dec.quant.c
new file mode 100644
index 0000000..701d4df
--- /dev/null
+++ b/Source/LibWebP/src/dec/dec.quant.c
@@ -0,0 +1,110 @@
+// Copyright 2010 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Quantizer initialization
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include "./vp8i.h"
+
+static WEBP_INLINE int clip(int v, int M) {
+  return v < 0 ? 0 : v > M ? M : v;
+}
+
+// Paragraph 14.1
+static const uint8_t kDcTable[128] = {
+  4,     5,   6,   7,   8,   9,  10,  10,
+  11,   12,  13,  14,  15,  16,  17,  17,
+  18,   19,  20,  20,  21,  21,  22,  22,
+  23,   23,  24,  25,  25,  26,  27,  28,
+  29,   30,  31,  32,  33,  34,  35,  36,
+  37,   37,  38,  39,  40,  41,  42,  43,
+  44,   45,  46,  46,  47,  48,  49,  50,
+  51,   52,  53,  54,  55,  56,  57,  58,
+  59,   60,  61,  62,  63,  64,  65,  66,
+  67,   68,  69,  70,  71,  72,  73,  74,
+  75,   76,  76,  77,  78,  79,  80,  81,
+  82,   83,  84,  85,  86,  87,  88,  89,
+  91,   93,  95,  96,  98, 100, 101, 102,
+  104, 106, 108, 110, 112, 114, 116, 118,
+  122, 124, 126, 128, 130, 132, 134, 136,
+  138, 140, 143, 145, 148, 151, 154, 157
+};
+
+static const uint16_t kAcTable[128] = {
+  4,     5,   6,   7,   8,   9,  10,  11,
+  12,   13,  14,  15,  16,  17,  18,  19,
+  20,   21,  22,  23,  24,  25,  26,  27,
+  28,   29,  30,  31,  32,  33,  34,  35,
+  36,   37,  38,  39,  40,  41,  42,  43,
+  44,   45,  46,  47,  48,  49,  50,  51,
+  52,   53,  54,  55,  56,  57,  58,  60,
+  62,   64,  66,  68,  70,  72,  74,  76,
+  78,   80,  82,  84,  86,  88,  90,  92,
+  94,   96,  98, 100, 102, 104, 106, 108,
+  110, 112, 114, 116, 119, 122, 125, 128,
+  131, 134, 137, 140, 143, 146, 149, 152,
+  155, 158, 161, 164, 167, 170, 173, 177,
+  181, 185, 189, 193, 197, 201, 205, 209,
+  213, 217, 221, 225, 229, 234, 239, 245,
+  249, 254, 259, 264, 269, 274, 279, 284
+};
+
+//------------------------------------------------------------------------------
+// Paragraph 9.6
+
+void VP8ParseQuant(VP8Decoder* const dec) {
+  VP8BitReader* const br = &dec->br_;
+  const int base_q0 = VP8GetValue(br, 7);
+  const int dqy1_dc = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0;
+  const int dqy2_dc = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0;
+  const int dqy2_ac = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0;
+  const int dquv_dc = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0;
+  const int dquv_ac = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0;
+
+  const VP8SegmentHeader* const hdr = &dec->segment_hdr_;
+  int i;
+
+  for (i = 0; i < NUM_MB_SEGMENTS; ++i) {
+    int q;
+    if (hdr->use_segment_) {
+      q = hdr->quantizer_[i];
+      if (!hdr->absolute_delta_) {
+        q += base_q0;
+      }
+    } else {
+      if (i > 0) {
+        dec->dqm_[i] = dec->dqm_[0];
+        continue;
+      } else {
+        q = base_q0;
+      }
+    }
+    {
+      VP8QuantMatrix* const m = &dec->dqm_[i];
+      m->y1_mat_[0] = kDcTable[clip(q + dqy1_dc, 127)];
+      m->y1_mat_[1] = kAcTable[clip(q + 0,       127)];
+
+      m->y2_mat_[0] = kDcTable[clip(q + dqy2_dc, 127)] * 2;
+      // For all x in [0..284], x*155/100 is bitwise equal to (x*101581) >> 16.
+      // The smallest precision for that is '(x*6349) >> 12' but 16 is a good
+      // word size.
+      m->y2_mat_[1] = (kAcTable[clip(q + dqy2_ac, 127)] * 101581) >> 16;
+      if (m->y2_mat_[1] < 8) m->y2_mat_[1] = 8;
+
+      m->uv_mat_[0] = kDcTable[clip(q + dquv_dc, 117)];
+      m->uv_mat_[1] = kAcTable[clip(q + dquv_ac, 127)];
+
+      m->uv_quant_ = q + dquv_ac;   // for dithering strength evaluation
+    }
+  }
+}
+
+//------------------------------------------------------------------------------
+
diff --git a/Source/LibWebP/src/dec/dec.tree.c b/Source/LibWebP/src/dec/dec.tree.c
new file mode 100644
index 0000000..b2f6310
--- /dev/null
+++ b/Source/LibWebP/src/dec/dec.tree.c
@@ -0,0 +1,525 @@
+// Copyright 2010 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Coding trees and probas
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include "./vp8i.h"
+#include "../utils/bit_reader_inl.h"
+
+#define USE_GENERIC_TREE
+
+#ifdef USE_GENERIC_TREE
+static const int8_t kYModesIntra4[18] = {
+  -B_DC_PRED, 1,
+    -B_TM_PRED, 2,
+      -B_VE_PRED, 3,
+        4, 6,
+          -B_HE_PRED, 5,
+            -B_RD_PRED, -B_VR_PRED,
+        -B_LD_PRED, 7,
+          -B_VL_PRED, 8,
+            -B_HD_PRED, -B_HU_PRED
+};
+#endif
+
+//------------------------------------------------------------------------------
+// Default probabilities
+
+// Paragraph 13.5
+static const uint8_t
+  CoeffsProba0[NUM_TYPES][NUM_BANDS][NUM_CTX][NUM_PROBAS] = {
+  { { { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
+      { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
+      { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 }
+    },
+    { { 253, 136, 254, 255, 228, 219, 128, 128, 128, 128, 128 },
+      { 189, 129, 242, 255, 227, 213, 255, 219, 128, 128, 128 },
+      { 106, 126, 227, 252, 214, 209, 255, 255, 128, 128, 128 }
+    },
+    { { 1, 98, 248, 255, 236, 226, 255, 255, 128, 128, 128 },
+      { 181, 133, 238, 254, 221, 234, 255, 154, 128, 128, 128 },
+      { 78, 134, 202, 247, 198, 180, 255, 219, 128, 128, 128 },
+    },
+    { { 1, 185, 249, 255, 243, 255, 128, 128, 128, 128, 128 },
+      { 184, 150, 247, 255, 236, 224, 128, 128, 128, 128, 128 },
+      { 77, 110, 216, 255, 236, 230, 128, 128, 128, 128, 128 },
+    },
+    { { 1, 101, 251, 255, 241, 255, 128, 128, 128, 128, 128 },
+      { 170, 139, 241, 252, 236, 209, 255, 255, 128, 128, 128 },
+      { 37, 116, 196, 243, 228, 255, 255, 255, 128, 128, 128 }
+    },
+    { { 1, 204, 254, 255, 245, 255, 128, 128, 128, 128, 128 },
+      { 207, 160, 250, 255, 238, 128, 128, 128, 128, 128, 128 },
+      { 102, 103, 231, 255, 211, 171, 128, 128, 128, 128, 128 }
+    },
+    { { 1, 152, 252, 255, 240, 255, 128, 128, 128, 128, 128 },
+      { 177, 135, 243, 255, 234, 225, 128, 128, 128, 128, 128 },
+      { 80, 129, 211, 255, 194, 224, 128, 128, 128, 128, 128 }
+    },
+    { { 1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
+      { 246, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
+      { 255, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 }
+    }
+  },
+  { { { 198, 35, 237, 223, 193, 187, 162, 160, 145, 155, 62 },
+      { 131, 45, 198, 221, 172, 176, 220, 157, 252, 221, 1 },
+      { 68, 47, 146, 208, 149, 167, 221, 162, 255, 223, 128 }
+    },
+    { { 1, 149, 241, 255, 221, 224, 255, 255, 128, 128, 128 },
+      { 184, 141, 234, 253, 222, 220, 255, 199, 128, 128, 128 },
+      { 81, 99, 181, 242, 176, 190, 249, 202, 255, 255, 128 }
+    },
+    { { 1, 129, 232, 253, 214, 197, 242, 196, 255, 255, 128 },
+      { 99, 121, 210, 250, 201, 198, 255, 202, 128, 128, 128 },
+      { 23, 91, 163, 242, 170, 187, 247, 210, 255, 255, 128 }
+    },
+    { { 1, 200, 246, 255, 234, 255, 128, 128, 128, 128, 128 },
+      { 109, 178, 241, 255, 231, 245, 255, 255, 128, 128, 128 },
+      { 44, 130, 201, 253, 205, 192, 255, 255, 128, 128, 128 }
+    },
+    { { 1, 132, 239, 251, 219, 209, 255, 165, 128, 128, 128 },
+      { 94, 136, 225, 251, 218, 190, 255, 255, 128, 128, 128 },
+      { 22, 100, 174, 245, 186, 161, 255, 199, 128, 128, 128 }
+    },
+    { { 1, 182, 249, 255, 232, 235, 128, 128, 128, 128, 128 },
+      { 124, 143, 241, 255, 227, 234, 128, 128, 128, 128, 128 },
+      { 35, 77, 181, 251, 193, 211, 255, 205, 128, 128, 128 }
+    },
+    { { 1, 157, 247, 255, 236, 231, 255, 255, 128, 128, 128 },
+      { 121, 141, 235, 255, 225, 227, 255, 255, 128, 128, 128 },
+      { 45, 99, 188, 251, 195, 217, 255, 224, 128, 128, 128 }
+    },
+    { { 1, 1, 251, 255, 213, 255, 128, 128, 128, 128, 128 },
+      { 203, 1, 248, 255, 255, 128, 128, 128, 128, 128, 128 },
+      { 137, 1, 177, 255, 224, 255, 128, 128, 128, 128, 128 }
+    }
+  },
+  { { { 253, 9, 248, 251, 207, 208, 255, 192, 128, 128, 128 },
+      { 175, 13, 224, 243, 193, 185, 249, 198, 255, 255, 128 },
+      { 73, 17, 171, 221, 161, 179, 236, 167, 255, 234, 128 }
+    },
+    { { 1, 95, 247, 253, 212, 183, 255, 255, 128, 128, 128 },
+      { 239, 90, 244, 250, 211, 209, 255, 255, 128, 128, 128 },
+      { 155, 77, 195, 248, 188, 195, 255, 255, 128, 128, 128 }
+    },
+    { { 1, 24, 239, 251, 218, 219, 255, 205, 128, 128, 128 },
+      { 201, 51, 219, 255, 196, 186, 128, 128, 128, 128, 128 },
+      { 69, 46, 190, 239, 201, 218, 255, 228, 128, 128, 128 }
+    },
+    { { 1, 191, 251, 255, 255, 128, 128, 128, 128, 128, 128 },
+      { 223, 165, 249, 255, 213, 255, 128, 128, 128, 128, 128 },
+      { 141, 124, 248, 255, 255, 128, 128, 128, 128, 128, 128 }
+    },
+    { { 1, 16, 248, 255, 255, 128, 128, 128, 128, 128, 128 },
+      { 190, 36, 230, 255, 236, 255, 128, 128, 128, 128, 128 },
+      { 149, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 }
+    },
+    { { 1, 226, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
+      { 247, 192, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
+      { 240, 128, 255, 128, 128, 128, 128, 128, 128, 128, 128 }
+    },
+    { { 1, 134, 252, 255, 255, 128, 128, 128, 128, 128, 128 },
+      { 213, 62, 250, 255, 255, 128, 128, 128, 128, 128, 128 },
+      { 55, 93, 255, 128, 128, 128, 128, 128, 128, 128, 128 }
+    },
+    { { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
+      { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
+      { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 }
+    }
+  },
+  { { { 202, 24, 213, 235, 186, 191, 220, 160, 240, 175, 255 },
+      { 126, 38, 182, 232, 169, 184, 228, 174, 255, 187, 128 },
+      { 61, 46, 138, 219, 151, 178, 240, 170, 255, 216, 128 }
+    },
+    { { 1, 112, 230, 250, 199, 191, 247, 159, 255, 255, 128 },
+      { 166, 109, 228, 252, 211, 215, 255, 174, 128, 128, 128 },
+      { 39, 77, 162, 232, 172, 180, 245, 178, 255, 255, 128 }
+    },
+    { { 1, 52, 220, 246, 198, 199, 249, 220, 255, 255, 128 },
+      { 124, 74, 191, 243, 183, 193, 250, 221, 255, 255, 128 },
+      { 24, 71, 130, 219, 154, 170, 243, 182, 255, 255, 128 }
+    },
+    { { 1, 182, 225, 249, 219, 240, 255, 224, 128, 128, 128 },
+      { 149, 150, 226, 252, 216, 205, 255, 171, 128, 128, 128 },
+      { 28, 108, 170, 242, 183, 194, 254, 223, 255, 255, 128 }
+    },
+    { { 1, 81, 230, 252, 204, 203, 255, 192, 128, 128, 128 },
+      { 123, 102, 209, 247, 188, 196, 255, 233, 128, 128, 128 },
+      { 20, 95, 153, 243, 164, 173, 255, 203, 128, 128, 128 }
+    },
+    { { 1, 222, 248, 255, 216, 213, 128, 128, 128, 128, 128 },
+      { 168, 175, 246, 252, 235, 205, 255, 255, 128, 128, 128 },
+      { 47, 116, 215, 255, 211, 212, 255, 255, 128, 128, 128 }
+    },
+    { { 1, 121, 236, 253, 212, 214, 255, 255, 128, 128, 128 },
+      { 141, 84, 213, 252, 201, 202, 255, 219, 128, 128, 128 },
+      { 42, 80, 160, 240, 162, 185, 255, 205, 128, 128, 128 }
+    },
+    { { 1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
+      { 244, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
+      { 238, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 }
+    }
+  }
+};
+
+// Paragraph 11.5
+static const uint8_t kBModesProba[NUM_BMODES][NUM_BMODES][NUM_BMODES - 1] = {
+  { { 231, 120, 48, 89, 115, 113, 120, 152, 112 },
+    { 152, 179, 64, 126, 170, 118, 46, 70, 95 },
+    { 175, 69, 143, 80, 85, 82, 72, 155, 103 },
+    { 56, 58, 10, 171, 218, 189, 17, 13, 152 },
+    { 114, 26, 17, 163, 44, 195, 21, 10, 173 },
+    { 121, 24, 80, 195, 26, 62, 44, 64, 85 },
+    { 144, 71, 10, 38, 171, 213, 144, 34, 26 },
+    { 170, 46, 55, 19, 136, 160, 33, 206, 71 },
+    { 63, 20, 8, 114, 114, 208, 12, 9, 226 },
+    { 81, 40, 11, 96, 182, 84, 29, 16, 36 } },
+  { { 134, 183, 89, 137, 98, 101, 106, 165, 148 },
+    { 72, 187, 100, 130, 157, 111, 32, 75, 80 },
+    { 66, 102, 167, 99, 74, 62, 40, 234, 128 },
+    { 41, 53, 9, 178, 241, 141, 26, 8, 107 },
+    { 74, 43, 26, 146, 73, 166, 49, 23, 157 },
+    { 65, 38, 105, 160, 51, 52, 31, 115, 128 },
+    { 104, 79, 12, 27, 217, 255, 87, 17, 7 },
+    { 87, 68, 71, 44, 114, 51, 15, 186, 23 },
+    { 47, 41, 14, 110, 182, 183, 21, 17, 194 },
+    { 66, 45, 25, 102, 197, 189, 23, 18, 22 } },
+  { { 88, 88, 147, 150, 42, 46, 45, 196, 205 },
+    { 43, 97, 183, 117, 85, 38, 35, 179, 61 },
+    { 39, 53, 200, 87, 26, 21, 43, 232, 171 },
+    { 56, 34, 51, 104, 114, 102, 29, 93, 77 },
+    { 39, 28, 85, 171, 58, 165, 90, 98, 64 },
+    { 34, 22, 116, 206, 23, 34, 43, 166, 73 },
+    { 107, 54, 32, 26, 51, 1, 81, 43, 31 },
+    { 68, 25, 106, 22, 64, 171, 36, 225, 114 },
+    { 34, 19, 21, 102, 132, 188, 16, 76, 124 },
+    { 62, 18, 78, 95, 85, 57, 50, 48, 51 } },
+  { { 193, 101, 35, 159, 215, 111, 89, 46, 111 },
+    { 60, 148, 31, 172, 219, 228, 21, 18, 111 },
+    { 112, 113, 77, 85, 179, 255, 38, 120, 114 },
+    { 40, 42, 1, 196, 245, 209, 10, 25, 109 },
+    { 88, 43, 29, 140, 166, 213, 37, 43, 154 },
+    { 61, 63, 30, 155, 67, 45, 68, 1, 209 },
+    { 100, 80, 8, 43, 154, 1, 51, 26, 71 },
+    { 142, 78, 78, 16, 255, 128, 34, 197, 171 },
+    { 41, 40, 5, 102, 211, 183, 4, 1, 221 },
+    { 51, 50, 17, 168, 209, 192, 23, 25, 82 } },
+  { { 138, 31, 36, 171, 27, 166, 38, 44, 229 },
+    { 67, 87, 58, 169, 82, 115, 26, 59, 179 },
+    { 63, 59, 90, 180, 59, 166, 93, 73, 154 },
+    { 40, 40, 21, 116, 143, 209, 34, 39, 175 },
+    { 47, 15, 16, 183, 34, 223, 49, 45, 183 },
+    { 46, 17, 33, 183, 6, 98, 15, 32, 183 },
+    { 57, 46, 22, 24, 128, 1, 54, 17, 37 },
+    { 65, 32, 73, 115, 28, 128, 23, 128, 205 },
+    { 40, 3, 9, 115, 51, 192, 18, 6, 223 },
+    { 87, 37, 9, 115, 59, 77, 64, 21, 47 } },
+  { { 104, 55, 44, 218, 9, 54, 53, 130, 226 },
+    { 64, 90, 70, 205, 40, 41, 23, 26, 57 },
+    { 54, 57, 112, 184, 5, 41, 38, 166, 213 },
+    { 30, 34, 26, 133, 152, 116, 10, 32, 134 },
+    { 39, 19, 53, 221, 26, 114, 32, 73, 255 },
+    { 31, 9, 65, 234, 2, 15, 1, 118, 73 },
+    { 75, 32, 12, 51, 192, 255, 160, 43, 51 },
+    { 88, 31, 35, 67, 102, 85, 55, 186, 85 },
+    { 56, 21, 23, 111, 59, 205, 45, 37, 192 },
+    { 55, 38, 70, 124, 73, 102, 1, 34, 98 } },
+  { { 125, 98, 42, 88, 104, 85, 117, 175, 82 },
+    { 95, 84, 53, 89, 128, 100, 113, 101, 45 },
+    { 75, 79, 123, 47, 51, 128, 81, 171, 1 },
+    { 57, 17, 5, 71, 102, 57, 53, 41, 49 },
+    { 38, 33, 13, 121, 57, 73, 26, 1, 85 },
+    { 41, 10, 67, 138, 77, 110, 90, 47, 114 },
+    { 115, 21, 2, 10, 102, 255, 166, 23, 6 },
+    { 101, 29, 16, 10, 85, 128, 101, 196, 26 },
+    { 57, 18, 10, 102, 102, 213, 34, 20, 43 },
+    { 117, 20, 15, 36, 163, 128, 68, 1, 26 } },
+  { { 102, 61, 71, 37, 34, 53, 31, 243, 192 },
+    { 69, 60, 71, 38, 73, 119, 28, 222, 37 },
+    { 68, 45, 128, 34, 1, 47, 11, 245, 171 },
+    { 62, 17, 19, 70, 146, 85, 55, 62, 70 },
+    { 37, 43, 37, 154, 100, 163, 85, 160, 1 },
+    { 63, 9, 92, 136, 28, 64, 32, 201, 85 },
+    { 75, 15, 9, 9, 64, 255, 184, 119, 16 },
+    { 86, 6, 28, 5, 64, 255, 25, 248, 1 },
+    { 56, 8, 17, 132, 137, 255, 55, 116, 128 },
+    { 58, 15, 20, 82, 135, 57, 26, 121, 40 } },
+  { { 164, 50, 31, 137, 154, 133, 25, 35, 218 },
+    { 51, 103, 44, 131, 131, 123, 31, 6, 158 },
+    { 86, 40, 64, 135, 148, 224, 45, 183, 128 },
+    { 22, 26, 17, 131, 240, 154, 14, 1, 209 },
+    { 45, 16, 21, 91, 64, 222, 7, 1, 197 },
+    { 56, 21, 39, 155, 60, 138, 23, 102, 213 },
+    { 83, 12, 13, 54, 192, 255, 68, 47, 28 },
+    { 85, 26, 85, 85, 128, 128, 32, 146, 171 },
+    { 18, 11, 7, 63, 144, 171, 4, 4, 246 },
+    { 35, 27, 10, 146, 174, 171, 12, 26, 128 } },
+  { { 190, 80, 35, 99, 180, 80, 126, 54, 45 },
+    { 85, 126, 47, 87, 176, 51, 41, 20, 32 },
+    { 101, 75, 128, 139, 118, 146, 116, 128, 85 },
+    { 56, 41, 15, 176, 236, 85, 37, 9, 62 },
+    { 71, 30, 17, 119, 118, 255, 17, 18, 138 },
+    { 101, 38, 60, 138, 55, 70, 43, 26, 142 },
+    { 146, 36, 19, 30, 171, 255, 97, 27, 20 },
+    { 138, 45, 61, 62, 219, 1, 81, 188, 64 },
+    { 32, 41, 20, 117, 151, 142, 20, 21, 163 },
+    { 112, 19, 12, 61, 195, 128, 48, 4, 24 } }
+};
+
+void VP8ResetProba(VP8Proba* const proba) {
+  memset(proba->segments_, 255u, sizeof(proba->segments_));
+  // proba->bands_[][] is initialized later
+}
+
+static void ParseIntraMode(VP8BitReader* const br,
+                           VP8Decoder* const dec, int mb_x) {
+  uint8_t* const top = dec->intra_t_ + 4 * mb_x;
+  uint8_t* const left = dec->intra_l_;
+  VP8MBData* const block = dec->mb_data_ + mb_x;
+
+  // Note: we don't save segment map (yet), as we don't expect
+  // to decode more than 1 keyframe.
+  if (dec->segment_hdr_.update_map_) {
+    // Hardcoded tree parsing
+    block->segment_ = !VP8GetBit(br, dec->proba_.segments_[0])
+                    ? VP8GetBit(br, dec->proba_.segments_[1])
+                    : 2 + VP8GetBit(br, dec->proba_.segments_[2]);
+  } else {
+    block->segment_ = 0;  // default for intra
+  }
+  if (dec->use_skip_proba_) block->skip_ = VP8GetBit(br, dec->skip_p_);
+
+  block->is_i4x4_ = !VP8GetBit(br, 145);   // decide for B_PRED first
+  if (!block->is_i4x4_) {
+    // Hardcoded 16x16 intra-mode decision tree.
+    const int ymode =
+        VP8GetBit(br, 156) ? (VP8GetBit(br, 128) ? TM_PRED : H_PRED)
+                           : (VP8GetBit(br, 163) ? V_PRED : DC_PRED);
+    block->imodes_[0] = ymode;
+    memset(top, ymode, 4 * sizeof(*top));
+    memset(left, ymode, 4 * sizeof(*left));
+  } else {
+    uint8_t* modes = block->imodes_;
+    int y;
+    for (y = 0; y < 4; ++y) {
+      int ymode = left[y];
+      int x;
+      for (x = 0; x < 4; ++x) {
+        const uint8_t* const prob = kBModesProba[top[x]][ymode];
+#ifdef USE_GENERIC_TREE
+        // Generic tree-parsing
+        int i = kYModesIntra4[VP8GetBit(br, prob[0])];
+        while (i > 0) {
+          i = kYModesIntra4[2 * i + VP8GetBit(br, prob[i])];
+        }
+        ymode = -i;
+#else
+        // Hardcoded tree parsing
+        ymode = !VP8GetBit(br, prob[0]) ? B_DC_PRED :
+                  !VP8GetBit(br, prob[1]) ? B_TM_PRED :
+                    !VP8GetBit(br, prob[2]) ? B_VE_PRED :
+                      !VP8GetBit(br, prob[3]) ?
+                        (!VP8GetBit(br, prob[4]) ? B_HE_PRED :
+                          (!VP8GetBit(br, prob[5]) ? B_RD_PRED : B_VR_PRED)) :
+                        (!VP8GetBit(br, prob[6]) ? B_LD_PRED :
+                          (!VP8GetBit(br, prob[7]) ? B_VL_PRED :
+                            (!VP8GetBit(br, prob[8]) ? B_HD_PRED : B_HU_PRED)));
+#endif    // USE_GENERIC_TREE
+        top[x] = ymode;
+      }
+      memcpy(modes, top, 4 * sizeof(*top));
+      modes += 4;
+      left[y] = ymode;
+    }
+  }
+  // Hardcoded UVMode decision tree
+  block->uvmode_ = !VP8GetBit(br, 142) ? DC_PRED
+                 : !VP8GetBit(br, 114) ? V_PRED
+                 : VP8GetBit(br, 183) ? TM_PRED : H_PRED;
+}
+
+int VP8ParseIntraModeRow(VP8BitReader* const br, VP8Decoder* const dec) {
+  int mb_x;
+  for (mb_x = 0; mb_x < dec->mb_w_; ++mb_x) {
+    ParseIntraMode(br, dec, mb_x);
+  }
+  return !dec->br_.eof_;
+}
+
+//------------------------------------------------------------------------------
+// Paragraph 13
+
+static const uint8_t
+    CoeffsUpdateProba[NUM_TYPES][NUM_BANDS][NUM_CTX][NUM_PROBAS] = {
+  { { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 176, 246, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 223, 241, 252, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 249, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 244, 252, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 234, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 246, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 239, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 251, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 251, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 254, 253, 255, 254, 255, 255, 255, 255, 255, 255 },
+      { 250, 255, 254, 255, 254, 255, 255, 255, 255, 255, 255 },
+      { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    }
+  },
+  { { { 217, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 225, 252, 241, 253, 255, 255, 254, 255, 255, 255, 255 },
+      { 234, 250, 241, 250, 253, 255, 253, 254, 255, 255, 255 }
+    },
+    { { 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 223, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 238, 253, 254, 254, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 249, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 247, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    }
+  },
+  { { { 186, 251, 250, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 234, 251, 244, 254, 255, 255, 255, 255, 255, 255, 255 },
+      { 251, 251, 243, 253, 254, 255, 254, 255, 255, 255, 255 }
+    },
+    { { 255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 236, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 251, 253, 253, 254, 254, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    }
+  },
+  { { { 248, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 250, 254, 252, 254, 255, 255, 255, 255, 255, 255, 255 },
+      { 248, 254, 249, 253, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 246, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 252, 254, 251, 254, 254, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 254, 252, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 248, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 253, 255, 254, 254, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 245, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 253, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 251, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 252, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 249, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 255, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    }
+  }
+};
+
+// Paragraph 9.9
+
+static const int kBands[16 + 1] = {
+  0, 1, 2, 3, 6, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7,
+  0  // extra entry as sentinel
+};
+
+void VP8ParseProba(VP8BitReader* const br, VP8Decoder* const dec) {
+  VP8Proba* const proba = &dec->proba_;
+  int t, b, c, p;
+  for (t = 0; t < NUM_TYPES; ++t) {
+    for (b = 0; b < NUM_BANDS; ++b) {
+      for (c = 0; c < NUM_CTX; ++c) {
+        for (p = 0; p < NUM_PROBAS; ++p) {
+          const int v = VP8GetBit(br, CoeffsUpdateProba[t][b][c][p]) ?
+                        VP8GetValue(br, 8) : CoeffsProba0[t][b][c][p];
+          proba->bands_[t][b].probas_[c][p] = v;
+        }
+      }
+    }
+    for (b = 0; b < 16 + 1; ++b) {
+      proba->bands_ptr_[t][b] = &proba->bands_[t][kBands[b]];
+    }
+  }
+  dec->use_skip_proba_ = VP8Get(br);
+  if (dec->use_skip_proba_) {
+    dec->skip_p_ = VP8GetValue(br, 8);
+  }
+}
+
diff --git a/Source/LibWebP/src/dec/dec.vp8.c b/Source/LibWebP/src/dec/dec.vp8.c
new file mode 100644
index 0000000..ffececc
--- /dev/null
+++ b/Source/LibWebP/src/dec/dec.vp8.c
@@ -0,0 +1,663 @@
+// Copyright 2010 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// main entry for the decoder
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include <stdlib.h>
+
+#include "./alphai.h"
+#include "./vp8i.h"
+#include "./vp8li.h"
+#include "./webpi.h"
+#include "../utils/bit_reader_inl.h"
+#include "../utils/utils.h"
+
+//------------------------------------------------------------------------------
+
+int WebPGetDecoderVersion(void) {
+  return (DEC_MAJ_VERSION << 16) | (DEC_MIN_VERSION << 8) | DEC_REV_VERSION;
+}
+
+//------------------------------------------------------------------------------
+// VP8Decoder
+
+static void SetOk(VP8Decoder* const dec) {
+  dec->status_ = VP8_STATUS_OK;
+  dec->error_msg_ = "OK";
+}
+
+int VP8InitIoInternal(VP8Io* const io, int version) {
+  if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_DECODER_ABI_VERSION)) {
+    return 0;  // mismatch error
+  }
+  if (io != NULL) {
+    memset(io, 0, sizeof(*io));
+  }
+  return 1;
+}
+
+VP8Decoder* VP8New(void) {
+  VP8Decoder* const dec = (VP8Decoder*)WebPSafeCalloc(1ULL, sizeof(*dec));
+  if (dec != NULL) {
+    SetOk(dec);
+    WebPGetWorkerInterface()->Init(&dec->worker_);
+    dec->ready_ = 0;
+    dec->num_parts_ = 1;
+  }
+  return dec;
+}
+
+VP8StatusCode VP8Status(VP8Decoder* const dec) {
+  if (!dec) return VP8_STATUS_INVALID_PARAM;
+  return dec->status_;
+}
+
+const char* VP8StatusMessage(VP8Decoder* const dec) {
+  if (dec == NULL) return "no object";
+  if (!dec->error_msg_) return "OK";
+  return dec->error_msg_;
+}
+
+void VP8Delete(VP8Decoder* const dec) {
+  if (dec != NULL) {
+    VP8Clear(dec);
+    WebPSafeFree(dec);
+  }
+}
+
+int VP8SetError(VP8Decoder* const dec,
+                VP8StatusCode error, const char* const msg) {
+  // TODO This check would be unnecessary if alpha decompression was separated
+  // from VP8ProcessRow/FinishRow. This avoids setting 'dec->status_' to
+  // something other than VP8_STATUS_BITSTREAM_ERROR on alpha decompression
+  // failure.
+  if (dec->status_ == VP8_STATUS_OK) {
+    dec->status_ = error;
+    dec->error_msg_ = msg;
+    dec->ready_ = 0;
+  }
+  return 0;
+}
+
+//------------------------------------------------------------------------------
+
+int VP8CheckSignature(const uint8_t* const data, size_t data_size) {
+  return (data_size >= 3 &&
+          data[0] == 0x9d && data[1] == 0x01 && data[2] == 0x2a);
+}
+
+int VP8GetInfo(const uint8_t* data, size_t data_size, size_t chunk_size,
+               int* const width, int* const height) {
+  if (data == NULL || data_size < VP8_FRAME_HEADER_SIZE) {
+    return 0;         // not enough data
+  }
+  // check signature
+  if (!VP8CheckSignature(data + 3, data_size - 3)) {
+    return 0;         // Wrong signature.
+  } else {
+    const uint32_t bits = data[0] | (data[1] << 8) | (data[2] << 16);
+    const int key_frame = !(bits & 1);
+    const int w = ((data[7] << 8) | data[6]) & 0x3fff;
+    const int h = ((data[9] << 8) | data[8]) & 0x3fff;
+
+    if (!key_frame) {   // Not a keyframe.
+      return 0;
+    }
+
+    if (((bits >> 1) & 7) > 3) {
+      return 0;         // unknown profile
+    }
+    if (!((bits >> 4) & 1)) {
+      return 0;         // first frame is invisible!
+    }
+    if (((bits >> 5)) >= chunk_size) {  // partition_length
+      return 0;         // inconsistent size information.
+    }
+    if (w == 0 || h == 0) {
+      return 0;         // We don't support both width and height to be zero.
+    }
+
+    if (width) {
+      *width = w;
+    }
+    if (height) {
+      *height = h;
+    }
+
+    return 1;
+  }
+}
+
+//------------------------------------------------------------------------------
+// Header parsing
+
+static void ResetSegmentHeader(VP8SegmentHeader* const hdr) {
+  assert(hdr != NULL);
+  hdr->use_segment_ = 0;
+  hdr->update_map_ = 0;
+  hdr->absolute_delta_ = 1;
+  memset(hdr->quantizer_, 0, sizeof(hdr->quantizer_));
+  memset(hdr->filter_strength_, 0, sizeof(hdr->filter_strength_));
+}
+
+// Paragraph 9.3
+static int ParseSegmentHeader(VP8BitReader* br,
+                              VP8SegmentHeader* hdr, VP8Proba* proba) {
+  assert(br != NULL);
+  assert(hdr != NULL);
+  hdr->use_segment_ = VP8Get(br);
+  if (hdr->use_segment_) {
+    hdr->update_map_ = VP8Get(br);
+    if (VP8Get(br)) {   // update data
+      int s;
+      hdr->absolute_delta_ = VP8Get(br);
+      for (s = 0; s < NUM_MB_SEGMENTS; ++s) {
+        hdr->quantizer_[s] = VP8Get(br) ? VP8GetSignedValue(br, 7) : 0;
+      }
+      for (s = 0; s < NUM_MB_SEGMENTS; ++s) {
+        hdr->filter_strength_[s] = VP8Get(br) ? VP8GetSignedValue(br, 6) : 0;
+      }
+    }
+    if (hdr->update_map_) {
+      int s;
+      for (s = 0; s < MB_FEATURE_TREE_PROBS; ++s) {
+        proba->segments_[s] = VP8Get(br) ? VP8GetValue(br, 8) : 255u;
+      }
+    }
+  } else {
+    hdr->update_map_ = 0;
+  }
+  return !br->eof_;
+}
+
+// Paragraph 9.5
+// This function returns VP8_STATUS_SUSPENDED if we don't have all the
+// necessary data in 'buf'.
+// This case is not necessarily an error (for incremental decoding).
+// Still, no bitreader is ever initialized to make it possible to read
+// unavailable memory.
+// If we don't even have the partitions' sizes, than VP8_STATUS_NOT_ENOUGH_DATA
+// is returned, and this is an unrecoverable error.
+// If the partitions were positioned ok, VP8_STATUS_OK is returned.
+static VP8StatusCode ParsePartitions(VP8Decoder* const dec,
+                                     const uint8_t* buf, size_t size) {
+  VP8BitReader* const br = &dec->br_;
+  const uint8_t* sz = buf;
+  const uint8_t* buf_end = buf + size;
+  const uint8_t* part_start;
+  int last_part;
+  int p;
+
+  dec->num_parts_ = 1 << VP8GetValue(br, 2);
+  last_part = dec->num_parts_ - 1;
+  part_start = buf + last_part * 3;
+  if (buf_end < part_start) {
+    // we can't even read the sizes with sz[]! That's a failure.
+    return VP8_STATUS_NOT_ENOUGH_DATA;
+  }
+  for (p = 0; p < last_part; ++p) {
+    const uint32_t psize = sz[0] | (sz[1] << 8) | (sz[2] << 16);
+    const uint8_t* part_end = part_start + psize;
+    if (part_end > buf_end) part_end = buf_end;
+    VP8InitBitReader(dec->parts_ + p, part_start, part_end);
+    part_start = part_end;
+    sz += 3;
+  }
+  VP8InitBitReader(dec->parts_ + last_part, part_start, buf_end);
+  return (part_start < buf_end) ? VP8_STATUS_OK :
+           VP8_STATUS_SUSPENDED;   // Init is ok, but there's not enough data
+}
+
+// Paragraph 9.4
+static int ParseFilterHeader(VP8BitReader* br, VP8Decoder* const dec) {
+  VP8FilterHeader* const hdr = &dec->filter_hdr_;
+  hdr->simple_    = VP8Get(br);
+  hdr->level_     = VP8GetValue(br, 6);
+  hdr->sharpness_ = VP8GetValue(br, 3);
+  hdr->use_lf_delta_ = VP8Get(br);
+  if (hdr->use_lf_delta_) {
+    if (VP8Get(br)) {   // update lf-delta?
+      int i;
+      for (i = 0; i < NUM_REF_LF_DELTAS; ++i) {
+        if (VP8Get(br)) {
+          hdr->ref_lf_delta_[i] = VP8GetSignedValue(br, 6);
+        }
+      }
+      for (i = 0; i < NUM_MODE_LF_DELTAS; ++i) {
+        if (VP8Get(br)) {
+          hdr->mode_lf_delta_[i] = VP8GetSignedValue(br, 6);
+        }
+      }
+    }
+  }
+  dec->filter_type_ = (hdr->level_ == 0) ? 0 : hdr->simple_ ? 1 : 2;
+  return !br->eof_;
+}
+
+// Topmost call
+int VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io) {
+  const uint8_t* buf;
+  size_t buf_size;
+  VP8FrameHeader* frm_hdr;
+  VP8PictureHeader* pic_hdr;
+  VP8BitReader* br;
+  VP8StatusCode status;
+
+  if (dec == NULL) {
+    return 0;
+  }
+  SetOk(dec);
+  if (io == NULL) {
+    return VP8SetError(dec, VP8_STATUS_INVALID_PARAM,
+                       "null VP8Io passed to VP8GetHeaders()");
+  }
+  buf = io->data;
+  buf_size = io->data_size;
+  if (buf_size < 4) {
+    return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA,
+                       "Truncated header.");
+  }
+
+  // Paragraph 9.1
+  {
+    const uint32_t bits = buf[0] | (buf[1] << 8) | (buf[2] << 16);
+    frm_hdr = &dec->frm_hdr_;
+    frm_hdr->key_frame_ = !(bits & 1);
+    frm_hdr->profile_ = (bits >> 1) & 7;
+    frm_hdr->show_ = (bits >> 4) & 1;
+    frm_hdr->partition_length_ = (bits >> 5);
+    if (frm_hdr->profile_ > 3)
+      return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR,
+                         "Incorrect keyframe parameters.");
+    if (!frm_hdr->show_)
+      return VP8SetError(dec, VP8_STATUS_UNSUPPORTED_FEATURE,
+                         "Frame not displayable.");
+    buf += 3;
+    buf_size -= 3;
+  }
+
+  pic_hdr = &dec->pic_hdr_;
+  if (frm_hdr->key_frame_) {
+    // Paragraph 9.2
+    if (buf_size < 7) {
+      return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA,
+                         "cannot parse picture header");
+    }
+    if (!VP8CheckSignature(buf, buf_size)) {
+      return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR,
+                         "Bad code word");
+    }
+    pic_hdr->width_ = ((buf[4] << 8) | buf[3]) & 0x3fff;
+    pic_hdr->xscale_ = buf[4] >> 6;   // ratio: 1, 5/4 5/3 or 2
+    pic_hdr->height_ = ((buf[6] << 8) | buf[5]) & 0x3fff;
+    pic_hdr->yscale_ = buf[6] >> 6;
+    buf += 7;
+    buf_size -= 7;
+
+    dec->mb_w_ = (pic_hdr->width_ + 15) >> 4;
+    dec->mb_h_ = (pic_hdr->height_ + 15) >> 4;
+    // Setup default output area (can be later modified during io->setup())
+    io->width = pic_hdr->width_;
+    io->height = pic_hdr->height_;
+    io->use_scaling  = 0;
+    io->use_cropping = 0;
+    io->crop_top  = 0;
+    io->crop_left = 0;
+    io->crop_right  = io->width;
+    io->crop_bottom = io->height;
+    io->mb_w = io->width;   // sanity check
+    io->mb_h = io->height;  // ditto
+
+    VP8ResetProba(&dec->proba_);
+    ResetSegmentHeader(&dec->segment_hdr_);
+  }
+
+  // Check if we have all the partition #0 available, and initialize dec->br_
+  // to read this partition (and this partition only).
+  if (frm_hdr->partition_length_ > buf_size) {
+    return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA,
+                       "bad partition length");
+  }
+
+  br = &dec->br_;
+  VP8InitBitReader(br, buf, buf + frm_hdr->partition_length_);
+  buf += frm_hdr->partition_length_;
+  buf_size -= frm_hdr->partition_length_;
+
+  if (frm_hdr->key_frame_) {
+    pic_hdr->colorspace_ = VP8Get(br);
+    pic_hdr->clamp_type_ = VP8Get(br);
+  }
+  if (!ParseSegmentHeader(br, &dec->segment_hdr_, &dec->proba_)) {
+    return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR,
+                       "cannot parse segment header");
+  }
+  // Filter specs
+  if (!ParseFilterHeader(br, dec)) {
+    return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR,
+                       "cannot parse filter header");
+  }
+  status = ParsePartitions(dec, buf, buf_size);
+  if (status != VP8_STATUS_OK) {
+    return VP8SetError(dec, status, "cannot parse partitions");
+  }
+
+  // quantizer change
+  VP8ParseQuant(dec);
+
+  // Frame buffer marking
+  if (!frm_hdr->key_frame_) {
+    return VP8SetError(dec, VP8_STATUS_UNSUPPORTED_FEATURE,
+                       "Not a key frame.");
+  }
+
+  VP8Get(br);   // ignore the value of update_proba_
+
+  VP8ParseProba(br, dec);
+
+  // sanitized state
+  dec->ready_ = 1;
+  return 1;
+}
+
+//------------------------------------------------------------------------------
+// Residual decoding (Paragraph 13.2 / 13.3)
+
+static const uint8_t kCat3[] = { 173, 148, 140, 0 };
+static const uint8_t kCat4[] = { 176, 155, 140, 135, 0 };
+static const uint8_t kCat5[] = { 180, 157, 141, 134, 130, 0 };
+static const uint8_t kCat6[] =
+  { 254, 254, 243, 230, 196, 177, 153, 140, 133, 130, 129, 0 };
+static const uint8_t* const kCat3456[] = { kCat3, kCat4, kCat5, kCat6 };
+static const uint8_t kZigzag[16] = {
+  0, 1, 4, 8,  5, 2, 3, 6,  9, 12, 13, 10,  7, 11, 14, 15
+};
+
+// See section 13-2: http://tools.ietf.org/html/rfc6386#section-13.2
+static int GetLargeValue(VP8BitReader* const br, const uint8_t* const p) {
+  int v;
+  if (!VP8GetBit(br, p[3])) {
+    if (!VP8GetBit(br, p[4])) {
+      v = 2;
+    } else {
+      v = 3 + VP8GetBit(br, p[5]);
+    }
+  } else {
+    if (!VP8GetBit(br, p[6])) {
+      if (!VP8GetBit(br, p[7])) {
+        v = 5 + VP8GetBit(br, 159);
+      } else {
+        v = 7 + 2 * VP8GetBit(br, 165);
+        v += VP8GetBit(br, 145);
+      }
+    } else {
+      const uint8_t* tab;
+      const int bit1 = VP8GetBit(br, p[8]);
+      const int bit0 = VP8GetBit(br, p[9 + bit1]);
+      const int cat = 2 * bit1 + bit0;
+      v = 0;
+      for (tab = kCat3456[cat]; *tab; ++tab) {
+        v += v + VP8GetBit(br, *tab);
+      }
+      v += 3 + (8 << cat);
+    }
+  }
+  return v;
+}
+
+// Returns the position of the last non-zero coeff plus one
+static int GetCoeffs(VP8BitReader* const br, const VP8BandProbas* const prob[],
+                     int ctx, const quant_t dq, int n, int16_t* out) {
+  const uint8_t* p = prob[n]->probas_[ctx];
+  for (; n < 16; ++n) {
+    if (!VP8GetBit(br, p[0])) {
+      return n;  // previous coeff was last non-zero coeff
+    }
+    while (!VP8GetBit(br, p[1])) {       // sequence of zero coeffs
+      p = prob[++n]->probas_[0];
+      if (n == 16) return 16;
+    }
+    {        // non zero coeff
+      const VP8ProbaArray* const p_ctx = &prob[n + 1]->probas_[0];
+      int v;
+      if (!VP8GetBit(br, p[2])) {
+        v = 1;
+        p = p_ctx[1];
+      } else {
+        v = GetLargeValue(br, p);
+        p = p_ctx[2];
+      }
+      out[kZigzag[n]] = VP8GetSigned(br, v) * dq[n > 0];
+    }
+  }
+  return 16;
+}
+
+static WEBP_INLINE uint32_t NzCodeBits(uint32_t nz_coeffs, int nz, int dc_nz) {
+  nz_coeffs <<= 2;
+  nz_coeffs |= (nz > 3) ? 3 : (nz > 1) ? 2 : dc_nz;
+  return nz_coeffs;
+}
+
+static int ParseResiduals(VP8Decoder* const dec,
+                          VP8MB* const mb, VP8BitReader* const token_br) {
+  const VP8BandProbas* (* const bands)[16 + 1] = dec->proba_.bands_ptr_;
+  const VP8BandProbas* const * ac_proba;
+  VP8MBData* const block = dec->mb_data_ + dec->mb_x_;
+  const VP8QuantMatrix* const q = &dec->dqm_[block->segment_];
+  int16_t* dst = block->coeffs_;
+  VP8MB* const left_mb = dec->mb_info_ - 1;
+  uint8_t tnz, lnz;
+  uint32_t non_zero_y = 0;
+  uint32_t non_zero_uv = 0;
+  int x, y, ch;
+  uint32_t out_t_nz, out_l_nz;
+  int first;
+
+  memset(dst, 0, 384 * sizeof(*dst));
+  if (!block->is_i4x4_) {    // parse DC
+    int16_t dc[16] = { 0 };
+    const int ctx = mb->nz_dc_ + left_mb->nz_dc_;
+    const int nz = GetCoeffs(token_br, bands[1], ctx, q->y2_mat_, 0, dc);
+    mb->nz_dc_ = left_mb->nz_dc_ = (nz > 0);
+    if (nz > 1) {   // more than just the DC -> perform the full transform
+      VP8TransformWHT(dc, dst);
+    } else {        // only DC is non-zero -> inlined simplified transform
+      int i;
+      const int dc0 = (dc[0] + 3) >> 3;
+      for (i = 0; i < 16 * 16; i += 16) dst[i] = dc0;
+    }
+    first = 1;
+    ac_proba = bands[0];
+  } else {
+    first = 0;
+    ac_proba = bands[3];
+  }
+
+  tnz = mb->nz_ & 0x0f;
+  lnz = left_mb->nz_ & 0x0f;
+  for (y = 0; y < 4; ++y) {
+    int l = lnz & 1;
+    uint32_t nz_coeffs = 0;
+    for (x = 0; x < 4; ++x) {
+      const int ctx = l + (tnz & 1);
+      const int nz = GetCoeffs(token_br, ac_proba, ctx, q->y1_mat_, first, dst);
+      l = (nz > first);
+      tnz = (tnz >> 1) | (l << 7);
+      nz_coeffs = NzCodeBits(nz_coeffs, nz, dst[0] != 0);
+      dst += 16;
+    }
+    tnz >>= 4;
+    lnz = (lnz >> 1) | (l << 7);
+    non_zero_y = (non_zero_y << 8) | nz_coeffs;
+  }
+  out_t_nz = tnz;
+  out_l_nz = lnz >> 4;
+
+  for (ch = 0; ch < 4; ch += 2) {
+    uint32_t nz_coeffs = 0;
+    tnz = mb->nz_ >> (4 + ch);
+    lnz = left_mb->nz_ >> (4 + ch);
+    for (y = 0; y < 2; ++y) {
+      int l = lnz & 1;
+      for (x = 0; x < 2; ++x) {
+        const int ctx = l + (tnz & 1);
+        const int nz = GetCoeffs(token_br, bands[2], ctx, q->uv_mat_, 0, dst);
+        l = (nz > 0);
+        tnz = (tnz >> 1) | (l << 3);
+        nz_coeffs = NzCodeBits(nz_coeffs, nz, dst[0] != 0);
+        dst += 16;
+      }
+      tnz >>= 2;
+      lnz = (lnz >> 1) | (l << 5);
+    }
+    // Note: we don't really need the per-4x4 details for U/V blocks.
+    non_zero_uv |= nz_coeffs << (4 * ch);
+    out_t_nz |= (tnz << 4) << ch;
+    out_l_nz |= (lnz & 0xf0) << ch;
+  }
+  mb->nz_ = out_t_nz;
+  left_mb->nz_ = out_l_nz;
+
+  block->non_zero_y_ = non_zero_y;
+  block->non_zero_uv_ = non_zero_uv;
+
+  // We look at the mode-code of each block and check if some blocks have less
+  // than three non-zero coeffs (code < 2). This is to avoid dithering flat and
+  // empty blocks.
+  block->dither_ = (non_zero_uv & 0xaaaa) ? 0 : q->dither_;
+
+  return !(non_zero_y | non_zero_uv);  // will be used for further optimization
+}
+
+//------------------------------------------------------------------------------
+// Main loop
+
+int VP8DecodeMB(VP8Decoder* const dec, VP8BitReader* const token_br) {
+  VP8MB* const left = dec->mb_info_ - 1;
+  VP8MB* const mb = dec->mb_info_ + dec->mb_x_;
+  VP8MBData* const block = dec->mb_data_ + dec->mb_x_;
+  int skip = dec->use_skip_proba_ ? block->skip_ : 0;
+
+  if (!skip) {
+    skip = ParseResiduals(dec, mb, token_br);
+  } else {
+    left->nz_ = mb->nz_ = 0;
+    if (!block->is_i4x4_) {
+      left->nz_dc_ = mb->nz_dc_ = 0;
+    }
+    block->non_zero_y_ = 0;
+    block->non_zero_uv_ = 0;
+    block->dither_ = 0;
+  }
+
+  if (dec->filter_type_ > 0) {  // store filter info
+    VP8FInfo* const finfo = dec->f_info_ + dec->mb_x_;
+    *finfo = dec->fstrengths_[block->segment_][block->is_i4x4_];
+    finfo->f_inner_ |= !skip;
+  }
+
+  return !token_br->eof_;
+}
+
+void VP8InitScanline(VP8Decoder* const dec) {
+  VP8MB* const left = dec->mb_info_ - 1;
+  left->nz_ = 0;
+  left->nz_dc_ = 0;
+  memset(dec->intra_l_, B_DC_PRED, sizeof(dec->intra_l_));
+  dec->mb_x_ = 0;
+}
+
+static int ParseFrame(VP8Decoder* const dec, VP8Io* io) {
+  for (dec->mb_y_ = 0; dec->mb_y_ < dec->br_mb_y_; ++dec->mb_y_) {
+    // Parse bitstream for this row.
+    VP8BitReader* const token_br =
+        &dec->parts_[dec->mb_y_ & (dec->num_parts_ - 1)];
+    if (!VP8ParseIntraModeRow(&dec->br_, dec)) {
+      return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA,
+                         "Premature end-of-partition0 encountered.");
+    }
+    for (; dec->mb_x_ < dec->mb_w_; ++dec->mb_x_) {
+      if (!VP8DecodeMB(dec, token_br)) {
+        return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA,
+                           "Premature end-of-file encountered.");
+      }
+    }
+    VP8InitScanline(dec);   // Prepare for next scanline
+
+    // Reconstruct, filter and emit the row.
+    if (!VP8ProcessRow(dec, io)) {
+      return VP8SetError(dec, VP8_STATUS_USER_ABORT, "Output aborted.");
+    }
+  }
+  if (dec->mt_method_ > 0) {
+    if (!WebPGetWorkerInterface()->Sync(&dec->worker_)) return 0;
+  }
+
+  return 1;
+}
+
+// Main entry point
+int VP8Decode(VP8Decoder* const dec, VP8Io* const io) {
+  int ok = 0;
+  if (dec == NULL) {
+    return 0;
+  }
+  if (io == NULL) {
+    return VP8SetError(dec, VP8_STATUS_INVALID_PARAM,
+                       "NULL VP8Io parameter in VP8Decode().");
+  }
+
+  if (!dec->ready_) {
+    if (!VP8GetHeaders(dec, io)) {
+      return 0;
+    }
+  }
+  assert(dec->ready_);
+
+  // Finish setting up the decoding parameter. Will call io->setup().
+  ok = (VP8EnterCritical(dec, io) == VP8_STATUS_OK);
+  if (ok) {   // good to go.
+    // Will allocate memory and prepare everything.
+    if (ok) ok = VP8InitFrame(dec, io);
+
+    // Main decoding loop
+    if (ok) ok = ParseFrame(dec, io);
+
+    // Exit.
+    ok &= VP8ExitCritical(dec, io);
+  }
+
+  if (!ok) {
+    VP8Clear(dec);
+    return 0;
+  }
+
+  dec->ready_ = 0;
+  return ok;
+}
+
+void VP8Clear(VP8Decoder* const dec) {
+  if (dec == NULL) {
+    return;
+  }
+  WebPGetWorkerInterface()->End(&dec->worker_);
+  ALPHDelete(dec->alph_dec_);
+  dec->alph_dec_ = NULL;
+  WebPSafeFree(dec->mem_);
+  dec->mem_ = NULL;
+  dec->mem_size_ = 0;
+  memset(&dec->br_, 0, sizeof(dec->br_));
+  dec->ready_ = 0;
+}
+
+//------------------------------------------------------------------------------
+
diff --git a/Source/LibWebP/src/dec/dec.vp8l.c b/Source/LibWebP/src/dec/dec.vp8l.c
new file mode 100644
index 0000000..7abeb72
--- /dev/null
+++ b/Source/LibWebP/src/dec/dec.vp8l.c
@@ -0,0 +1,1584 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// main entry for the decoder
+//
+// Authors: Vikas Arora (vikaas.arora at gmail.com)
+//          Jyrki Alakuijala (jyrki at google.com)
+
+#include <stdlib.h>
+
+#include "./alphai.h"
+#include "./vp8li.h"
+#include "../dsp/dsp.h"
+#include "../dsp/lossless.h"
+#include "../dsp/yuv.h"
+#include "../utils/huffman.h"
+#include "../utils/utils.h"
+
+#define NUM_ARGB_CACHE_ROWS          16
+
+static const int kCodeLengthLiterals = 16;
+static const int kCodeLengthRepeatCode = 16;
+static const int kCodeLengthExtraBits[3] = { 2, 3, 7 };
+static const int kCodeLengthRepeatOffsets[3] = { 3, 3, 11 };
+
+// -----------------------------------------------------------------------------
+//  Five Huffman codes are used at each meta code:
+//  1. green + length prefix codes + color cache codes,
+//  2. alpha,
+//  3. red,
+//  4. blue, and,
+//  5. distance prefix codes.
+typedef enum {
+  GREEN = 0,
+  RED   = 1,
+  BLUE  = 2,
+  ALPHA = 3,
+  DIST  = 4
+} HuffIndex;
+
+static const uint16_t kAlphabetSize[HUFFMAN_CODES_PER_META_CODE] = {
+  NUM_LITERAL_CODES + NUM_LENGTH_CODES,
+  NUM_LITERAL_CODES, NUM_LITERAL_CODES, NUM_LITERAL_CODES,
+  NUM_DISTANCE_CODES
+};
+
+static const uint8_t kLiteralMap[HUFFMAN_CODES_PER_META_CODE] = {
+  0, 1, 1, 1, 0
+};
+
+#define NUM_CODE_LENGTH_CODES       19
+static const uint8_t kCodeLengthCodeOrder[NUM_CODE_LENGTH_CODES] = {
+  17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
+};
+
+#define CODE_TO_PLANE_CODES        120
+static const uint8_t kCodeToPlane[CODE_TO_PLANE_CODES] = {
+  0x18, 0x07, 0x17, 0x19, 0x28, 0x06, 0x27, 0x29, 0x16, 0x1a,
+  0x26, 0x2a, 0x38, 0x05, 0x37, 0x39, 0x15, 0x1b, 0x36, 0x3a,
+  0x25, 0x2b, 0x48, 0x04, 0x47, 0x49, 0x14, 0x1c, 0x35, 0x3b,
+  0x46, 0x4a, 0x24, 0x2c, 0x58, 0x45, 0x4b, 0x34, 0x3c, 0x03,
+  0x57, 0x59, 0x13, 0x1d, 0x56, 0x5a, 0x23, 0x2d, 0x44, 0x4c,
+  0x55, 0x5b, 0x33, 0x3d, 0x68, 0x02, 0x67, 0x69, 0x12, 0x1e,
+  0x66, 0x6a, 0x22, 0x2e, 0x54, 0x5c, 0x43, 0x4d, 0x65, 0x6b,
+  0x32, 0x3e, 0x78, 0x01, 0x77, 0x79, 0x53, 0x5d, 0x11, 0x1f,
+  0x64, 0x6c, 0x42, 0x4e, 0x76, 0x7a, 0x21, 0x2f, 0x75, 0x7b,
+  0x31, 0x3f, 0x63, 0x6d, 0x52, 0x5e, 0x00, 0x74, 0x7c, 0x41,
+  0x4f, 0x10, 0x20, 0x62, 0x6e, 0x30, 0x73, 0x7d, 0x51, 0x5f,
+  0x40, 0x72, 0x7e, 0x61, 0x6f, 0x50, 0x71, 0x7f, 0x60, 0x70
+};
+
+// Memory needed for lookup tables of one Huffman tree group. Red, blue, alpha
+// and distance alphabets are constant (256 for red, blue and alpha, 40 for
+// distance) and lookup table sizes for them in worst case are 630 and 410
+// respectively. Size of green alphabet depends on color cache size and is equal
+// to 256 (green component values) + 24 (length prefix values)
+// + color_cache_size (between 0 and 2048).
+// All values computed for 8-bit first level lookup with Mark Adler's tool:
+// http://www.hdfgroup.org/ftp/lib-external/zlib/zlib-1.2.5/examples/enough.c
+#define FIXED_TABLE_SIZE (630 * 3 + 410)
+static const int kTableSize[12] = {
+  FIXED_TABLE_SIZE + 654,
+  FIXED_TABLE_SIZE + 656,
+  FIXED_TABLE_SIZE + 658,
+  FIXED_TABLE_SIZE + 662,
+  FIXED_TABLE_SIZE + 670,
+  FIXED_TABLE_SIZE + 686,
+  FIXED_TABLE_SIZE + 718,
+  FIXED_TABLE_SIZE + 782,
+  FIXED_TABLE_SIZE + 912,
+  FIXED_TABLE_SIZE + 1168,
+  FIXED_TABLE_SIZE + 1680,
+  FIXED_TABLE_SIZE + 2704
+};
+
+static int DecodeImageStream(int xsize, int ysize,
+                             int is_level0,
+                             VP8LDecoder* const dec,
+                             uint32_t** const decoded_data);
+
+//------------------------------------------------------------------------------
+
+int VP8LCheckSignature(const uint8_t* const data, size_t size) {
+  return (size >= VP8L_FRAME_HEADER_SIZE &&
+          data[0] == VP8L_MAGIC_BYTE &&
+          (data[4] >> 5) == 0);  // version
+}
+
+static int ReadImageInfo(VP8LBitReader* const br,
+                         int* const width, int* const height,
+                         int* const has_alpha) {
+  if (VP8LReadBits(br, 8) != VP8L_MAGIC_BYTE) return 0;
+  *width = VP8LReadBits(br, VP8L_IMAGE_SIZE_BITS) + 1;
+  *height = VP8LReadBits(br, VP8L_IMAGE_SIZE_BITS) + 1;
+  *has_alpha = VP8LReadBits(br, 1);
+  if (VP8LReadBits(br, VP8L_VERSION_BITS) != 0) return 0;
+  return !br->eos_;
+}
+
+int VP8LGetInfo(const uint8_t* data, size_t data_size,
+                int* const width, int* const height, int* const has_alpha) {
+  if (data == NULL || data_size < VP8L_FRAME_HEADER_SIZE) {
+    return 0;         // not enough data
+  } else if (!VP8LCheckSignature(data, data_size)) {
+    return 0;         // bad signature
+  } else {
+    int w, h, a;
+    VP8LBitReader br;
+    VP8LInitBitReader(&br, data, data_size);
+    if (!ReadImageInfo(&br, &w, &h, &a)) {
+      return 0;
+    }
+    if (width != NULL) *width = w;
+    if (height != NULL) *height = h;
+    if (has_alpha != NULL) *has_alpha = a;
+    return 1;
+  }
+}
+
+//------------------------------------------------------------------------------
+
+static WEBP_INLINE int GetCopyDistance(int distance_symbol,
+                                       VP8LBitReader* const br) {
+  int extra_bits, offset;
+  if (distance_symbol < 4) {
+    return distance_symbol + 1;
+  }
+  extra_bits = (distance_symbol - 2) >> 1;
+  offset = (2 + (distance_symbol & 1)) << extra_bits;
+  return offset + VP8LReadBits(br, extra_bits) + 1;
+}
+
+static WEBP_INLINE int GetCopyLength(int length_symbol,
+                                     VP8LBitReader* const br) {
+  // Length and distance prefixes are encoded the same way.
+  return GetCopyDistance(length_symbol, br);
+}
+
+static WEBP_INLINE int PlaneCodeToDistance(int xsize, int plane_code) {
+  if (plane_code > CODE_TO_PLANE_CODES) {
+    return plane_code - CODE_TO_PLANE_CODES;
+  } else {
+    const int dist_code = kCodeToPlane[plane_code - 1];
+    const int yoffset = dist_code >> 4;
+    const int xoffset = 8 - (dist_code & 0xf);
+    const int dist = yoffset * xsize + xoffset;
+    return (dist >= 1) ? dist : 1;  // dist<1 can happen if xsize is very small
+  }
+}
+
+//------------------------------------------------------------------------------
+// Decodes the next Huffman code from bit-stream.
+// FillBitWindow(br) needs to be called at minimum every second call
+// to ReadSymbol, in order to pre-fetch enough bits.
+static WEBP_INLINE int ReadSymbol(const HuffmanCode* table,
+                                  VP8LBitReader* const br) {
+  int nbits;
+  uint32_t val = VP8LPrefetchBits(br);
+  table += val & HUFFMAN_TABLE_MASK;
+  nbits = table->bits - HUFFMAN_TABLE_BITS;
+  if (nbits > 0) {
+    VP8LSetBitPos(br, br->bit_pos_ + HUFFMAN_TABLE_BITS);
+    val = VP8LPrefetchBits(br);
+    table += table->value;
+    table += val & ((1 << nbits) - 1);
+  }
+  VP8LSetBitPos(br, br->bit_pos_ + table->bits);
+  return table->value;
+}
+
+static int ReadHuffmanCodeLengths(
+    VP8LDecoder* const dec, const int* const code_length_code_lengths,
+    int num_symbols, int* const code_lengths) {
+  int ok = 0;
+  VP8LBitReader* const br = &dec->br_;
+  int symbol;
+  int max_symbol;
+  int prev_code_len = DEFAULT_CODE_LENGTH;
+  HuffmanCode table[1 << LENGTHS_TABLE_BITS];
+
+  if (!VP8LBuildHuffmanTable(table, LENGTHS_TABLE_BITS,
+                             code_length_code_lengths,
+                             NUM_CODE_LENGTH_CODES)) {
+    goto End;
+  }
+
+  if (VP8LReadBits(br, 1)) {    // use length
+    const int length_nbits = 2 + 2 * VP8LReadBits(br, 3);
+    max_symbol = 2 + VP8LReadBits(br, length_nbits);
+    if (max_symbol > num_symbols) {
+      goto End;
+    }
+  } else {
+    max_symbol = num_symbols;
+  }
+
+  symbol = 0;
+  while (symbol < num_symbols) {
+    const HuffmanCode* p;
+    int code_len;
+    if (max_symbol-- == 0) break;
+    VP8LFillBitWindow(br);
+    p = &table[VP8LPrefetchBits(br) & LENGTHS_TABLE_MASK];
+    VP8LSetBitPos(br, br->bit_pos_ + p->bits);
+    code_len = p->value;
+    if (code_len < kCodeLengthLiterals) {
+      code_lengths[symbol++] = code_len;
+      if (code_len != 0) prev_code_len = code_len;
+    } else {
+      const int use_prev = (code_len == kCodeLengthRepeatCode);
+      const int slot = code_len - kCodeLengthLiterals;
+      const int extra_bits = kCodeLengthExtraBits[slot];
+      const int repeat_offset = kCodeLengthRepeatOffsets[slot];
+      int repeat = VP8LReadBits(br, extra_bits) + repeat_offset;
+      if (symbol + repeat > num_symbols) {
+        goto End;
+      } else {
+        const int length = use_prev ? prev_code_len : 0;
+        while (repeat-- > 0) code_lengths[symbol++] = length;
+      }
+    }
+  }
+  ok = 1;
+
+ End:
+  if (!ok) dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
+  return ok;
+}
+
+// 'code_lengths' is pre-allocated temporary buffer, used for creating Huffman
+// tree.
+static int ReadHuffmanCode(int alphabet_size, VP8LDecoder* const dec,
+                           int* const code_lengths, HuffmanCode* const table) {
+  int ok = 0;
+  int size = 0;
+  VP8LBitReader* const br = &dec->br_;
+  const int simple_code = VP8LReadBits(br, 1);
+
+  memset(code_lengths, 0, alphabet_size * sizeof(*code_lengths));
+
+  if (simple_code) {  // Read symbols, codes & code lengths directly.
+    const int num_symbols = VP8LReadBits(br, 1) + 1;
+    const int first_symbol_len_code = VP8LReadBits(br, 1);
+    // The first code is either 1 bit or 8 bit code.
+    int symbol = VP8LReadBits(br, (first_symbol_len_code == 0) ? 1 : 8);
+    code_lengths[symbol] = 1;
+    // The second code (if present), is always 8 bit long.
+    if (num_symbols == 2) {
+      symbol = VP8LReadBits(br, 8);
+      code_lengths[symbol] = 1;
+    }
+    ok = 1;
+  } else {  // Decode Huffman-coded code lengths.
+    int i;
+    int code_length_code_lengths[NUM_CODE_LENGTH_CODES] = { 0 };
+    const int num_codes = VP8LReadBits(br, 4) + 4;
+    if (num_codes > NUM_CODE_LENGTH_CODES) {
+      dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
+      return 0;
+    }
+
+    for (i = 0; i < num_codes; ++i) {
+      code_length_code_lengths[kCodeLengthCodeOrder[i]] = VP8LReadBits(br, 3);
+    }
+    ok = ReadHuffmanCodeLengths(dec, code_length_code_lengths, alphabet_size,
+                                code_lengths);
+  }
+
+  ok = ok && !br->eos_;
+  if (ok) {
+    size = VP8LBuildHuffmanTable(table, HUFFMAN_TABLE_BITS,
+                                 code_lengths, alphabet_size);
+  }
+  if (!ok || size == 0) {
+    dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
+    return 0;
+  }
+  return size;
+}
+
+static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
+                            int color_cache_bits, int allow_recursion) {
+  int i, j;
+  VP8LBitReader* const br = &dec->br_;
+  VP8LMetadata* const hdr = &dec->hdr_;
+  uint32_t* huffman_image = NULL;
+  HTreeGroup* htree_groups = NULL;
+  HuffmanCode* huffman_tables = NULL;
+  HuffmanCode* next = NULL;
+  int num_htree_groups = 1;
+  int max_alphabet_size = 0;
+  int* code_lengths = NULL;
+  const int table_size = kTableSize[color_cache_bits];
+
+  if (allow_recursion && VP8LReadBits(br, 1)) {
+    // use meta Huffman codes.
+    const int huffman_precision = VP8LReadBits(br, 3) + 2;
+    const int huffman_xsize = VP8LSubSampleSize(xsize, huffman_precision);
+    const int huffman_ysize = VP8LSubSampleSize(ysize, huffman_precision);
+    const int huffman_pixs = huffman_xsize * huffman_ysize;
+    if (!DecodeImageStream(huffman_xsize, huffman_ysize, 0, dec,
+                           &huffman_image)) {
+      goto Error;
+    }
+    hdr->huffman_subsample_bits_ = huffman_precision;
+    for (i = 0; i < huffman_pixs; ++i) {
+      // The huffman data is stored in red and green bytes.
+      const int group = (huffman_image[i] >> 8) & 0xffff;
+      huffman_image[i] = group;
+      if (group >= num_htree_groups) {
+        num_htree_groups = group + 1;
+      }
+    }
+  }
+
+  if (br->eos_) goto Error;
+
+  // Find maximum alphabet size for the htree group.
+  for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) {
+    int alphabet_size = kAlphabetSize[j];
+    if (j == 0 && color_cache_bits > 0) {
+      alphabet_size += 1 << color_cache_bits;
+    }
+    if (max_alphabet_size < alphabet_size) {
+      max_alphabet_size = alphabet_size;
+    }
+  }
+
+  huffman_tables = (HuffmanCode*)WebPSafeMalloc(num_htree_groups * table_size,
+                                                sizeof(*huffman_tables));
+  htree_groups = VP8LHtreeGroupsNew(num_htree_groups);
+  code_lengths = (int*)WebPSafeCalloc((uint64_t)max_alphabet_size,
+                                      sizeof(*code_lengths));
+
+  if (htree_groups == NULL || code_lengths == NULL || huffman_tables == NULL) {
+    dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
+    goto Error;
+  }
+
+  next = huffman_tables;
+  for (i = 0; i < num_htree_groups; ++i) {
+    HTreeGroup* const htree_group = &htree_groups[i];
+    HuffmanCode** const htrees = htree_group->htrees;
+    int size;
+    int is_trivial_literal = 1;
+    for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) {
+      int alphabet_size = kAlphabetSize[j];
+      htrees[j] = next;
+      if (j == 0 && color_cache_bits > 0) {
+        alphabet_size += 1 << color_cache_bits;
+      }
+      size = ReadHuffmanCode(alphabet_size, dec, code_lengths, next);
+      if (is_trivial_literal && kLiteralMap[j] == 1) {
+        is_trivial_literal = (next->bits == 0);
+      }
+      next += size;
+      if (size == 0) {
+        goto Error;
+      }
+    }
+    htree_group->is_trivial_literal = is_trivial_literal;
+    if (is_trivial_literal) {
+      const int red = htrees[RED][0].value;
+      const int blue = htrees[BLUE][0].value;
+      const int alpha = htrees[ALPHA][0].value;
+      htree_group->literal_arb =
+          ((uint32_t)alpha << 24) | (red << 16) | blue;
+    }
+  }
+  WebPSafeFree(code_lengths);
+
+  // All OK. Finalize pointers and return.
+  hdr->huffman_image_ = huffman_image;
+  hdr->num_htree_groups_ = num_htree_groups;
+  hdr->htree_groups_ = htree_groups;
+  hdr->huffman_tables_ = huffman_tables;
+  return 1;
+
+ Error:
+  WebPSafeFree(code_lengths);
+  WebPSafeFree(huffman_image);
+  WebPSafeFree(huffman_tables);
+  VP8LHtreeGroupsFree(htree_groups);
+  return 0;
+}
+
+//------------------------------------------------------------------------------
+// Scaling.
+
+static int AllocateAndInitRescaler(VP8LDecoder* const dec, VP8Io* const io) {
+  const int num_channels = 4;
+  const int in_width = io->mb_w;
+  const int out_width = io->scaled_width;
+  const int in_height = io->mb_h;
+  const int out_height = io->scaled_height;
+  const uint64_t work_size = 2 * num_channels * (uint64_t)out_width;
+  int32_t* work;        // Rescaler work area.
+  const uint64_t scaled_data_size = num_channels * (uint64_t)out_width;
+  uint32_t* scaled_data;  // Temporary storage for scaled BGRA data.
+  const uint64_t memory_size = sizeof(*dec->rescaler) +
+                               work_size * sizeof(*work) +
+                               scaled_data_size * sizeof(*scaled_data);
+  uint8_t* memory = (uint8_t*)WebPSafeCalloc(memory_size, sizeof(*memory));
+  if (memory == NULL) {
+    dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
+    return 0;
+  }
+  assert(dec->rescaler_memory == NULL);
+  dec->rescaler_memory = memory;
+
+  dec->rescaler = (WebPRescaler*)memory;
+  memory += sizeof(*dec->rescaler);
+  work = (int32_t*)memory;
+  memory += work_size * sizeof(*work);
+  scaled_data = (uint32_t*)memory;
+
+  WebPRescalerInit(dec->rescaler, in_width, in_height, (uint8_t*)scaled_data,
+                   out_width, out_height, 0, num_channels,
+                   in_width, out_width, in_height, out_height, work);
+  return 1;
+}
+
+//------------------------------------------------------------------------------
+// Export to ARGB
+
+// We have special "export" function since we need to convert from BGRA
+static int Export(WebPRescaler* const rescaler, WEBP_CSP_MODE colorspace,
+                  int rgba_stride, uint8_t* const rgba) {
+  uint32_t* const src = (uint32_t*)rescaler->dst;
+  const int dst_width = rescaler->dst_width;
+  int num_lines_out = 0;
+  while (WebPRescalerHasPendingOutput(rescaler)) {
+    uint8_t* const dst = rgba + num_lines_out * rgba_stride;
+    WebPRescalerExportRow(rescaler, 0);
+    WebPMultARGBRow(src, dst_width, 1);
+    VP8LConvertFromBGRA(src, dst_width, colorspace, dst);
+    ++num_lines_out;
+  }
+  return num_lines_out;
+}
+
+// Emit scaled rows.
+static int EmitRescaledRowsRGBA(const VP8LDecoder* const dec,
+                                uint8_t* in, int in_stride, int mb_h,
+                                uint8_t* const out, int out_stride) {
+  const WEBP_CSP_MODE colorspace = dec->output_->colorspace;
+  int num_lines_in = 0;
+  int num_lines_out = 0;
+  while (num_lines_in < mb_h) {
+    uint8_t* const row_in = in + num_lines_in * in_stride;
+    uint8_t* const row_out = out + num_lines_out * out_stride;
+    const int lines_left = mb_h - num_lines_in;
+    const int needed_lines = WebPRescaleNeededLines(dec->rescaler, lines_left);
+    assert(needed_lines > 0 && needed_lines <= lines_left);
+    WebPMultARGBRows(row_in, in_stride,
+                     dec->rescaler->src_width, needed_lines, 0);
+    WebPRescalerImport(dec->rescaler, lines_left, row_in, in_stride);
+    num_lines_in += needed_lines;
+    num_lines_out += Export(dec->rescaler, colorspace, out_stride, row_out);
+  }
+  return num_lines_out;
+}
+
+// Emit rows without any scaling.
+static int EmitRows(WEBP_CSP_MODE colorspace,
+                    const uint8_t* row_in, int in_stride,
+                    int mb_w, int mb_h,
+                    uint8_t* const out, int out_stride) {
+  int lines = mb_h;
+  uint8_t* row_out = out;
+  while (lines-- > 0) {
+    VP8LConvertFromBGRA((const uint32_t*)row_in, mb_w, colorspace, row_out);
+    row_in += in_stride;
+    row_out += out_stride;
+  }
+  return mb_h;  // Num rows out == num rows in.
+}
+
+//------------------------------------------------------------------------------
+// Export to YUVA
+
+// TODO(skal): should be in yuv.c
+static void ConvertToYUVA(const uint32_t* const src, int width, int y_pos,
+                          const WebPDecBuffer* const output) {
+  const WebPYUVABuffer* const buf = &output->u.YUVA;
+  // first, the luma plane
+  {
+    int i;
+    uint8_t* const y = buf->y + y_pos * buf->y_stride;
+    for (i = 0; i < width; ++i) {
+      const uint32_t p = src[i];
+      y[i] = VP8RGBToY((p >> 16) & 0xff, (p >> 8) & 0xff, (p >> 0) & 0xff,
+                       YUV_HALF);
+    }
+  }
+
+  // then U/V planes
+  {
+    uint8_t* const u = buf->u + (y_pos >> 1) * buf->u_stride;
+    uint8_t* const v = buf->v + (y_pos >> 1) * buf->v_stride;
+    const int uv_width = width >> 1;
+    int i;
+    for (i = 0; i < uv_width; ++i) {
+      const uint32_t v0 = src[2 * i + 0];
+      const uint32_t v1 = src[2 * i + 1];
+      // VP8RGBToU/V expects four accumulated pixels. Hence we need to
+      // scale r/g/b value by a factor 2. We just shift v0/v1 one bit less.
+      const int r = ((v0 >> 15) & 0x1fe) + ((v1 >> 15) & 0x1fe);
+      const int g = ((v0 >>  7) & 0x1fe) + ((v1 >>  7) & 0x1fe);
+      const int b = ((v0 <<  1) & 0x1fe) + ((v1 <<  1) & 0x1fe);
+      if (!(y_pos & 1)) {  // even lines: store values
+        u[i] = VP8RGBToU(r, g, b, YUV_HALF << 2);
+        v[i] = VP8RGBToV(r, g, b, YUV_HALF << 2);
+      } else {             // odd lines: average with previous values
+        const int tmp_u = VP8RGBToU(r, g, b, YUV_HALF << 2);
+        const int tmp_v = VP8RGBToV(r, g, b, YUV_HALF << 2);
+        // Approximated average-of-four. But it's an acceptable diff.
+        u[i] = (u[i] + tmp_u + 1) >> 1;
+        v[i] = (v[i] + tmp_v + 1) >> 1;
+      }
+    }
+    if (width & 1) {       // last pixel
+      const uint32_t v0 = src[2 * i + 0];
+      const int r = (v0 >> 14) & 0x3fc;
+      const int g = (v0 >>  6) & 0x3fc;
+      const int b = (v0 <<  2) & 0x3fc;
+      if (!(y_pos & 1)) {  // even lines
+        u[i] = VP8RGBToU(r, g, b, YUV_HALF << 2);
+        v[i] = VP8RGBToV(r, g, b, YUV_HALF << 2);
+      } else {             // odd lines (note: we could just skip this)
+        const int tmp_u = VP8RGBToU(r, g, b, YUV_HALF << 2);
+        const int tmp_v = VP8RGBToV(r, g, b, YUV_HALF << 2);
+        u[i] = (u[i] + tmp_u + 1) >> 1;
+        v[i] = (v[i] + tmp_v + 1) >> 1;
+      }
+    }
+  }
+  // Lastly, store alpha if needed.
+  if (buf->a != NULL) {
+    int i;
+    uint8_t* const a = buf->a + y_pos * buf->a_stride;
+    for (i = 0; i < width; ++i) a[i] = (src[i] >> 24);
+  }
+}
+
+static int ExportYUVA(const VP8LDecoder* const dec, int y_pos) {
+  WebPRescaler* const rescaler = dec->rescaler;
+  uint32_t* const src = (uint32_t*)rescaler->dst;
+  const int dst_width = rescaler->dst_width;
+  int num_lines_out = 0;
+  while (WebPRescalerHasPendingOutput(rescaler)) {
+    WebPRescalerExportRow(rescaler, 0);
+    WebPMultARGBRow(src, dst_width, 1);
+    ConvertToYUVA(src, dst_width, y_pos, dec->output_);
+    ++y_pos;
+    ++num_lines_out;
+  }
+  return num_lines_out;
+}
+
+static int EmitRescaledRowsYUVA(const VP8LDecoder* const dec,
+                                uint8_t* in, int in_stride, int mb_h) {
+  int num_lines_in = 0;
+  int y_pos = dec->last_out_row_;
+  while (num_lines_in < mb_h) {
+    const int lines_left = mb_h - num_lines_in;
+    const int needed_lines = WebPRescaleNeededLines(dec->rescaler, lines_left);
+    WebPMultARGBRows(in, in_stride, dec->rescaler->src_width, needed_lines, 0);
+    WebPRescalerImport(dec->rescaler, lines_left, in, in_stride);
+    num_lines_in += needed_lines;
+    in += needed_lines * in_stride;
+    y_pos += ExportYUVA(dec, y_pos);
+  }
+  return y_pos;
+}
+
+static int EmitRowsYUVA(const VP8LDecoder* const dec,
+                        const uint8_t* in, int in_stride,
+                        int mb_w, int num_rows) {
+  int y_pos = dec->last_out_row_;
+  while (num_rows-- > 0) {
+    ConvertToYUVA((const uint32_t*)in, mb_w, y_pos, dec->output_);
+    in += in_stride;
+    ++y_pos;
+  }
+  return y_pos;
+}
+
+//------------------------------------------------------------------------------
+// Cropping.
+
+// Sets io->mb_y, io->mb_h & io->mb_w according to start row, end row and
+// crop options. Also updates the input data pointer, so that it points to the
+// start of the cropped window. Note that pixels are in ARGB format even if
+// 'in_data' is uint8_t*.
+// Returns true if the crop window is not empty.
+static int SetCropWindow(VP8Io* const io, int y_start, int y_end,
+                         uint8_t** const in_data, int pixel_stride) {
+  assert(y_start < y_end);
+  assert(io->crop_left < io->crop_right);
+  if (y_end > io->crop_bottom) {
+    y_end = io->crop_bottom;  // make sure we don't overflow on last row.
+  }
+  if (y_start < io->crop_top) {
+    const int delta = io->crop_top - y_start;
+    y_start = io->crop_top;
+    *in_data += delta * pixel_stride;
+  }
+  if (y_start >= y_end) return 0;  // Crop window is empty.
+
+  *in_data += io->crop_left * sizeof(uint32_t);
+
+  io->mb_y = y_start - io->crop_top;
+  io->mb_w = io->crop_right - io->crop_left;
+  io->mb_h = y_end - y_start;
+  return 1;  // Non-empty crop window.
+}
+
+//------------------------------------------------------------------------------
+
+static WEBP_INLINE int GetMetaIndex(
+    const uint32_t* const image, int xsize, int bits, int x, int y) {
+  if (bits == 0) return 0;
+  return image[xsize * (y >> bits) + (x >> bits)];
+}
+
+static WEBP_INLINE HTreeGroup* GetHtreeGroupForPos(VP8LMetadata* const hdr,
+                                                   int x, int y) {
+  const int meta_index = GetMetaIndex(hdr->huffman_image_, hdr->huffman_xsize_,
+                                      hdr->huffman_subsample_bits_, x, y);
+  assert(meta_index < hdr->num_htree_groups_);
+  return hdr->htree_groups_ + meta_index;
+}
+
+//------------------------------------------------------------------------------
+// Main loop, with custom row-processing function
+
+typedef void (*ProcessRowsFunc)(VP8LDecoder* const dec, int row);
+
+static void ApplyInverseTransforms(VP8LDecoder* const dec, int num_rows,
+                                   const uint32_t* const rows) {
+  int n = dec->next_transform_;
+  const int cache_pixs = dec->width_ * num_rows;
+  const int start_row = dec->last_row_;
+  const int end_row = start_row + num_rows;
+  const uint32_t* rows_in = rows;
+  uint32_t* const rows_out = dec->argb_cache_;
+
+  // Inverse transforms.
+  // TODO: most transforms only need to operate on the cropped region only.
+  memcpy(rows_out, rows_in, cache_pixs * sizeof(*rows_out));
+  while (n-- > 0) {
+    VP8LTransform* const transform = &dec->transforms_[n];
+    VP8LInverseTransform(transform, start_row, end_row, rows_in, rows_out);
+    rows_in = rows_out;
+  }
+}
+
+// Special method for paletted alpha data.
+static void ApplyInverseTransformsAlpha(VP8LDecoder* const dec, int num_rows,
+                                        const uint8_t* const rows) {
+  const int start_row = dec->last_row_;
+  const int end_row = start_row + num_rows;
+  const uint8_t* rows_in = rows;
+  uint8_t* rows_out = (uint8_t*)dec->io_->opaque + dec->io_->width * start_row;
+  VP8LTransform* const transform = &dec->transforms_[0];
+  assert(dec->next_transform_ == 1);
+  assert(transform->type_ == COLOR_INDEXING_TRANSFORM);
+  VP8LColorIndexInverseTransformAlpha(transform, start_row, end_row, rows_in,
+                                      rows_out);
+}
+
+// Processes (transforms, scales & color-converts) the rows decoded after the
+// last call.
+static void ProcessRows(VP8LDecoder* const dec, int row) {
+  const uint32_t* const rows = dec->pixels_ + dec->width_ * dec->last_row_;
+  const int num_rows = row - dec->last_row_;
+
+  if (num_rows <= 0) return;  // Nothing to be done.
+  ApplyInverseTransforms(dec, num_rows, rows);
+
+  // Emit output.
+  {
+    VP8Io* const io = dec->io_;
+    uint8_t* rows_data = (uint8_t*)dec->argb_cache_;
+    const int in_stride = io->width * sizeof(uint32_t);  // in unit of RGBA
+    if (!SetCropWindow(io, dec->last_row_, row, &rows_data, in_stride)) {
+      // Nothing to output (this time).
+    } else {
+      const WebPDecBuffer* const output = dec->output_;
+      if (output->colorspace < MODE_YUV) {  // convert to RGBA
+        const WebPRGBABuffer* const buf = &output->u.RGBA;
+        uint8_t* const rgba = buf->rgba + dec->last_out_row_ * buf->stride;
+        const int num_rows_out = io->use_scaling ?
+            EmitRescaledRowsRGBA(dec, rows_data, in_stride, io->mb_h,
+                                 rgba, buf->stride) :
+            EmitRows(output->colorspace, rows_data, in_stride,
+                     io->mb_w, io->mb_h, rgba, buf->stride);
+        // Update 'last_out_row_'.
+        dec->last_out_row_ += num_rows_out;
+      } else {                              // convert to YUVA
+        dec->last_out_row_ = io->use_scaling ?
+            EmitRescaledRowsYUVA(dec, rows_data, in_stride, io->mb_h) :
+            EmitRowsYUVA(dec, rows_data, in_stride, io->mb_w, io->mb_h);
+      }
+      assert(dec->last_out_row_ <= output->height);
+    }
+  }
+
+  // Update 'last_row_'.
+  dec->last_row_ = row;
+  assert(dec->last_row_ <= dec->height_);
+}
+
+// Row-processing for the special case when alpha data contains only one
+// transform (color indexing), and trivial non-green literals.
+static int Is8bOptimizable(const VP8LMetadata* const hdr) {
+  int i;
+  if (hdr->color_cache_size_ > 0) return 0;
+  // When the Huffman tree contains only one symbol, we can skip the
+  // call to ReadSymbol() for red/blue/alpha channels.
+  for (i = 0; i < hdr->num_htree_groups_; ++i) {
+    HuffmanCode** const htrees = hdr->htree_groups_[i].htrees;
+    if (htrees[RED][0].bits > 0) return 0;
+    if (htrees[BLUE][0].bits > 0) return 0;
+    if (htrees[ALPHA][0].bits > 0) return 0;
+  }
+  return 1;
+}
+
+static void ExtractPalettedAlphaRows(VP8LDecoder* const dec, int row) {
+  const int num_rows = row - dec->last_row_;
+  const uint8_t* const in =
+      (uint8_t*)dec->pixels_ + dec->width_ * dec->last_row_;
+  if (num_rows > 0) {
+    ApplyInverseTransformsAlpha(dec, num_rows, in);
+  }
+  dec->last_row_ = dec->last_out_row_ = row;
+}
+
+//------------------------------------------------------------------------------
+// Helper functions for fast pattern copy (8b and 32b)
+
+// cyclic rotation of pattern word
+static WEBP_INLINE uint32_t Rotate8b(uint32_t V) {
+#if defined(WORDS_BIGENDIAN)
+  return ((V & 0xff000000u) >> 24) | (V << 8);
+#else
+  return ((V & 0xffu) << 24) | (V >> 8);
+#endif
+}
+
+// copy 1, 2 or 4-bytes pattern
+static WEBP_INLINE void CopySmallPattern8b(const uint8_t* src, uint8_t* dst,
+                                           int length, uint32_t pattern) {
+  int i;
+  // align 'dst' to 4-bytes boundary. Adjust the pattern along the way.
+  while ((uintptr_t)dst & 3) {
+    *dst++ = *src++;
+    pattern = Rotate8b(pattern);
+    --length;
+  }
+  // Copy the pattern 4 bytes at a time.
+  for (i = 0; i < (length >> 2); ++i) {
+    ((uint32_t*)dst)[i] = pattern;
+  }
+  // Finish with left-overs. 'pattern' is still correctly positioned,
+  // so no Rotate8b() call is needed.
+  for (i <<= 2; i < length; ++i) {
+    dst[i] = src[i];
+  }
+}
+
+static WEBP_INLINE void CopyBlock8b(uint8_t* const dst, int dist, int length) {
+  const uint8_t* src = dst - dist;
+  if (length >= 8) {
+    uint32_t pattern = 0;
+    switch (dist) {
+      case 1:
+        pattern = src[0];
+#if defined(__arm__) || defined(_M_ARM)   // arm doesn't like multiply that much
+        pattern |= pattern << 8;
+        pattern |= pattern << 16;
+#elif defined(WEBP_USE_MIPS_DSP_R2)
+        __asm__ volatile ("replv.qb %0, %0" : "+r"(pattern));
+#else
+        pattern = 0x01010101u * pattern;
+#endif
+        break;
+      case 2:
+        memcpy(&pattern, src, sizeof(uint16_t));
+#if defined(__arm__) || defined(_M_ARM)
+        pattern |= pattern << 16;
+#elif defined(WEBP_USE_MIPS_DSP_R2)
+        __asm__ volatile ("replv.ph %0, %0" : "+r"(pattern));
+#else
+        pattern = 0x00010001u * pattern;
+#endif
+        break;
+      case 4:
+        memcpy(&pattern, src, sizeof(uint32_t));
+        break;
+      default:
+        goto Copy;
+        break;
+    }
+    CopySmallPattern8b(src, dst, length, pattern);
+    return;
+  }
+ Copy:
+  if (dist >= length) {  // no overlap -> use memcpy()
+    memcpy(dst, src, length * sizeof(*dst));
+  } else {
+    int i;
+    for (i = 0; i < length; ++i) dst[i] = src[i];
+  }
+}
+
+// copy pattern of 1 or 2 uint32_t's
+static WEBP_INLINE void CopySmallPattern32b(const uint32_t* src,
+                                            uint32_t* dst,
+                                            int length, uint64_t pattern) {
+  int i;
+  if ((uintptr_t)dst & 4) {           // Align 'dst' to 8-bytes boundary.
+    *dst++ = *src++;
+    pattern = (pattern >> 32) | (pattern << 32);
+    --length;
+  }
+  assert(0 == ((uintptr_t)dst & 7));
+  for (i = 0; i < (length >> 1); ++i) {
+    ((uint64_t*)dst)[i] = pattern;    // Copy the pattern 8 bytes at a time.
+  }
+  if (length & 1) {                   // Finish with left-over.
+    dst[i << 1] = src[i << 1];
+  }
+}
+
+static WEBP_INLINE void CopyBlock32b(uint32_t* const dst,
+                                     int dist, int length) {
+  const uint32_t* const src = dst - dist;
+  if (dist <= 2 && length >= 4 && ((uintptr_t)dst & 3) == 0) {
+    uint64_t pattern;
+    if (dist == 1) {
+      pattern = (uint64_t)src[0];
+      pattern |= pattern << 32;
+    } else {
+      memcpy(&pattern, src, sizeof(pattern));
+    }
+    CopySmallPattern32b(src, dst, length, pattern);
+  } else if (dist >= length) {  // no overlap
+    memcpy(dst, src, length * sizeof(*dst));
+  } else {
+    int i;
+    for (i = 0; i < length; ++i) dst[i] = src[i];
+  }
+}
+
+//------------------------------------------------------------------------------
+
+static int DecodeAlphaData(VP8LDecoder* const dec, uint8_t* const data,
+                           int width, int height, int last_row) {
+  int ok = 1;
+  int row = dec->last_pixel_ / width;
+  int col = dec->last_pixel_ % width;
+  VP8LBitReader* const br = &dec->br_;
+  VP8LMetadata* const hdr = &dec->hdr_;
+  const HTreeGroup* htree_group = GetHtreeGroupForPos(hdr, col, row);
+  int pos = dec->last_pixel_;         // current position
+  const int end = width * height;     // End of data
+  const int last = width * last_row;  // Last pixel to decode
+  const int len_code_limit = NUM_LITERAL_CODES + NUM_LENGTH_CODES;
+  const int mask = hdr->huffman_mask_;
+  assert(htree_group != NULL);
+  assert(pos < end);
+  assert(last_row <= height);
+  assert(Is8bOptimizable(hdr));
+
+  while (!br->eos_ && pos < last) {
+    int code;
+    // Only update when changing tile.
+    if ((col & mask) == 0) {
+      htree_group = GetHtreeGroupForPos(hdr, col, row);
+    }
+    VP8LFillBitWindow(br);
+    code = ReadSymbol(htree_group->htrees[GREEN], br);
+    if (code < NUM_LITERAL_CODES) {  // Literal
+      data[pos] = code;
+      ++pos;
+      ++col;
+      if (col >= width) {
+        col = 0;
+        ++row;
+        if (row % NUM_ARGB_CACHE_ROWS == 0) {
+          ExtractPalettedAlphaRows(dec, row);
+        }
+      }
+    } else if (code < len_code_limit) {  // Backward reference
+      int dist_code, dist;
+      const int length_sym = code - NUM_LITERAL_CODES;
+      const int length = GetCopyLength(length_sym, br);
+      const int dist_symbol = ReadSymbol(htree_group->htrees[DIST], br);
+      VP8LFillBitWindow(br);
+      dist_code = GetCopyDistance(dist_symbol, br);
+      dist = PlaneCodeToDistance(width, dist_code);
+      if (pos >= dist && end - pos >= length) {
+        CopyBlock8b(data + pos, dist, length);
+      } else {
+        ok = 0;
+        goto End;
+      }
+      pos += length;
+      col += length;
+      while (col >= width) {
+        col -= width;
+        ++row;
+        if (row % NUM_ARGB_CACHE_ROWS == 0) {
+          ExtractPalettedAlphaRows(dec, row);
+        }
+      }
+      if (pos < last && (col & mask)) {
+        htree_group = GetHtreeGroupForPos(hdr, col, row);
+      }
+    } else {  // Not reached
+      ok = 0;
+      goto End;
+    }
+    assert(br->eos_ == VP8LIsEndOfStream(br));
+  }
+  // Process the remaining rows corresponding to last row-block.
+  ExtractPalettedAlphaRows(dec, row);
+
+ End:
+  if (!ok || (br->eos_ && pos < end)) {
+    ok = 0;
+    dec->status_ = br->eos_ ? VP8_STATUS_SUSPENDED
+                            : VP8_STATUS_BITSTREAM_ERROR;
+  } else {
+    dec->last_pixel_ = (int)pos;
+  }
+  return ok;
+}
+
+static void SaveState(VP8LDecoder* const dec, int last_pixel) {
+  assert(dec->incremental_);
+  dec->saved_br_ = dec->br_;
+  dec->saved_last_pixel_ = last_pixel;
+  if (dec->hdr_.color_cache_size_ > 0) {
+    VP8LColorCacheCopy(&dec->hdr_.color_cache_, &dec->hdr_.saved_color_cache_);
+  }
+}
+
+static void RestoreState(VP8LDecoder* const dec) {
+  assert(dec->br_.eos_);
+  dec->status_ = VP8_STATUS_SUSPENDED;
+  dec->br_ = dec->saved_br_;
+  dec->last_pixel_ = dec->saved_last_pixel_;
+  if (dec->hdr_.color_cache_size_ > 0) {
+    VP8LColorCacheCopy(&dec->hdr_.saved_color_cache_, &dec->hdr_.color_cache_);
+  }
+}
+
+#define SYNC_EVERY_N_ROWS 8  // minimum number of rows between check-points
+static int DecodeImageData(VP8LDecoder* const dec, uint32_t* const data,
+                           int width, int height, int last_row,
+                           ProcessRowsFunc process_func) {
+  int row = dec->last_pixel_ / width;
+  int col = dec->last_pixel_ % width;
+  VP8LBitReader* const br = &dec->br_;
+  VP8LMetadata* const hdr = &dec->hdr_;
+  HTreeGroup* htree_group = GetHtreeGroupForPos(hdr, col, row);
+  uint32_t* src = data + dec->last_pixel_;
+  uint32_t* last_cached = src;
+  uint32_t* const src_end = data + width * height;     // End of data
+  uint32_t* const src_last = data + width * last_row;  // Last pixel to decode
+  const int len_code_limit = NUM_LITERAL_CODES + NUM_LENGTH_CODES;
+  const int color_cache_limit = len_code_limit + hdr->color_cache_size_;
+  int next_sync_row = dec->incremental_ ? row : 1 << 24;
+  VP8LColorCache* const color_cache =
+      (hdr->color_cache_size_ > 0) ? &hdr->color_cache_ : NULL;
+  const int mask = hdr->huffman_mask_;
+  assert(htree_group != NULL);
+  assert(src < src_end);
+  assert(src_last <= src_end);
+
+  while (src < src_last) {
+    int code;
+    if (row >= next_sync_row) {
+      SaveState(dec, (int)(src - data));
+      next_sync_row = row + SYNC_EVERY_N_ROWS;
+    }
+    // Only update when changing tile. Note we could use this test:
+    // if "((((prev_col ^ col) | prev_row ^ row)) > mask)" -> tile changed
+    // but that's actually slower and needs storing the previous col/row.
+    if ((col & mask) == 0) {
+      htree_group = GetHtreeGroupForPos(hdr, col, row);
+    }
+    VP8LFillBitWindow(br);
+    code = ReadSymbol(htree_group->htrees[GREEN], br);
+    if (br->eos_) break;  // early out
+    if (code < NUM_LITERAL_CODES) {  // Literal
+      if (htree_group->is_trivial_literal) {
+        *src = htree_group->literal_arb | (code << 8);
+      } else {
+        int red, blue, alpha;
+        red = ReadSymbol(htree_group->htrees[RED], br);
+        VP8LFillBitWindow(br);
+        blue = ReadSymbol(htree_group->htrees[BLUE], br);
+        alpha = ReadSymbol(htree_group->htrees[ALPHA], br);
+        if (br->eos_) break;
+        *src = ((uint32_t)alpha << 24) | (red << 16) | (code << 8) | blue;
+      }
+    AdvanceByOne:
+      ++src;
+      ++col;
+      if (col >= width) {
+        col = 0;
+        ++row;
+        if ((row % NUM_ARGB_CACHE_ROWS == 0) && (process_func != NULL)) {
+          process_func(dec, row);
+        }
+        if (color_cache != NULL) {
+          while (last_cached < src) {
+            VP8LColorCacheInsert(color_cache, *last_cached++);
+          }
+        }
+      }
+    } else if (code < len_code_limit) {  // Backward reference
+      int dist_code, dist;
+      const int length_sym = code - NUM_LITERAL_CODES;
+      const int length = GetCopyLength(length_sym, br);
+      const int dist_symbol = ReadSymbol(htree_group->htrees[DIST], br);
+      VP8LFillBitWindow(br);
+      dist_code = GetCopyDistance(dist_symbol, br);
+      dist = PlaneCodeToDistance(width, dist_code);
+      if (br->eos_) break;
+      if (src - data < (ptrdiff_t)dist || src_end - src < (ptrdiff_t)length) {
+        goto Error;
+      } else {
+        CopyBlock32b(src, dist, length);
+      }
+      src += length;
+      col += length;
+      while (col >= width) {
+        col -= width;
+        ++row;
+        if ((row % NUM_ARGB_CACHE_ROWS == 0) && (process_func != NULL)) {
+          process_func(dec, row);
+        }
+      }
+      // Because of the check done above (before 'src' was incremented by
+      // 'length'), the following holds true.
+      assert(src <= src_end);
+      if (col & mask) htree_group = GetHtreeGroupForPos(hdr, col, row);
+      if (color_cache != NULL) {
+        while (last_cached < src) {
+          VP8LColorCacheInsert(color_cache, *last_cached++);
+        }
+      }
+    } else if (code < color_cache_limit) {  // Color cache
+      const int key = code - len_code_limit;
+      assert(color_cache != NULL);
+      while (last_cached < src) {
+        VP8LColorCacheInsert(color_cache, *last_cached++);
+      }
+      *src = VP8LColorCacheLookup(color_cache, key);
+      goto AdvanceByOne;
+    } else {  // Not reached
+      goto Error;
+    }
+    assert(br->eos_ == VP8LIsEndOfStream(br));
+  }
+
+  if (dec->incremental_ && br->eos_ && src < src_end) {
+    RestoreState(dec);
+  } else if (!br->eos_) {
+    // Process the remaining rows corresponding to last row-block.
+    if (process_func != NULL) {
+      process_func(dec, row);
+    }
+    dec->status_ = VP8_STATUS_OK;
+    dec->last_pixel_ = (int)(src - data);  // end-of-scan marker
+  } else {
+    // if not incremental, and we are past the end of buffer (eos_=1), then this
+    // is a real bitstream error.
+    goto Error;
+  }
+  return 1;
+
+ Error:
+  dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
+  return 0;
+}
+
+// -----------------------------------------------------------------------------
+// VP8LTransform
+
+static void ClearTransform(VP8LTransform* const transform) {
+  WebPSafeFree(transform->data_);
+  transform->data_ = NULL;
+}
+
+// For security reason, we need to remap the color map to span
+// the total possible bundled values, and not just the num_colors.
+static int ExpandColorMap(int num_colors, VP8LTransform* const transform) {
+  int i;
+  const int final_num_colors = 1 << (8 >> transform->bits_);
+  uint32_t* const new_color_map =
+      (uint32_t*)WebPSafeMalloc((uint64_t)final_num_colors,
+                                sizeof(*new_color_map));
+  if (new_color_map == NULL) {
+    return 0;
+  } else {
+    uint8_t* const data = (uint8_t*)transform->data_;
+    uint8_t* const new_data = (uint8_t*)new_color_map;
+    new_color_map[0] = transform->data_[0];
+    for (i = 4; i < 4 * num_colors; ++i) {
+      // Equivalent to AddPixelEq(), on a byte-basis.
+      new_data[i] = (data[i] + new_data[i - 4]) & 0xff;
+    }
+    for (; i < 4 * final_num_colors; ++i)
+      new_data[i] = 0;  // black tail.
+    WebPSafeFree(transform->data_);
+    transform->data_ = new_color_map;
+  }
+  return 1;
+}
+
+static int ReadTransform(int* const xsize, int const* ysize,
+                         VP8LDecoder* const dec) {
+  int ok = 1;
+  VP8LBitReader* const br = &dec->br_;
+  VP8LTransform* transform = &dec->transforms_[dec->next_transform_];
+  const VP8LImageTransformType type =
+      (VP8LImageTransformType)VP8LReadBits(br, 2);
+
+  // Each transform type can only be present once in the stream.
+  if (dec->transforms_seen_ & (1U << type)) {
+    return 0;  // Already there, let's not accept the second same transform.
+  }
+  dec->transforms_seen_ |= (1U << type);
+
+  transform->type_ = type;
+  transform->xsize_ = *xsize;
+  transform->ysize_ = *ysize;
+  transform->data_ = NULL;
+  ++dec->next_transform_;
+  assert(dec->next_transform_ <= NUM_TRANSFORMS);
+
+  switch (type) {
+    case PREDICTOR_TRANSFORM:
+    case CROSS_COLOR_TRANSFORM:
+      transform->bits_ = VP8LReadBits(br, 3) + 2;
+      ok = DecodeImageStream(VP8LSubSampleSize(transform->xsize_,
+                                               transform->bits_),
+                             VP8LSubSampleSize(transform->ysize_,
+                                               transform->bits_),
+                             0, dec, &transform->data_);
+      break;
+    case COLOR_INDEXING_TRANSFORM: {
+       const int num_colors = VP8LReadBits(br, 8) + 1;
+       const int bits = (num_colors > 16) ? 0
+                      : (num_colors > 4) ? 1
+                      : (num_colors > 2) ? 2
+                      : 3;
+       *xsize = VP8LSubSampleSize(transform->xsize_, bits);
+       transform->bits_ = bits;
+       ok = DecodeImageStream(num_colors, 1, 0, dec, &transform->data_);
+       ok = ok && ExpandColorMap(num_colors, transform);
+      break;
+    }
+    case SUBTRACT_GREEN:
+      break;
+    default:
+      assert(0);    // can't happen
+      break;
+  }
+
+  return ok;
+}
+
+// -----------------------------------------------------------------------------
+// VP8LMetadata
+
+static void InitMetadata(VP8LMetadata* const hdr) {
+  assert(hdr != NULL);
+  memset(hdr, 0, sizeof(*hdr));
+}
+
+static void ClearMetadata(VP8LMetadata* const hdr) {
+  assert(hdr != NULL);
+
+  WebPSafeFree(hdr->huffman_image_);
+  WebPSafeFree(hdr->huffman_tables_);
+  VP8LHtreeGroupsFree(hdr->htree_groups_);
+  VP8LColorCacheClear(&hdr->color_cache_);
+  VP8LColorCacheClear(&hdr->saved_color_cache_);
+  InitMetadata(hdr);
+}
+
+// -----------------------------------------------------------------------------
+// VP8LDecoder
+
+VP8LDecoder* VP8LNew(void) {
+  VP8LDecoder* const dec = (VP8LDecoder*)WebPSafeCalloc(1ULL, sizeof(*dec));
+  if (dec == NULL) return NULL;
+  dec->status_ = VP8_STATUS_OK;
+  dec->state_ = READ_DIM;
+
+  VP8LDspInit();  // Init critical function pointers.
+
+  return dec;
+}
+
+void VP8LClear(VP8LDecoder* const dec) {
+  int i;
+  if (dec == NULL) return;
+  ClearMetadata(&dec->hdr_);
+
+  WebPSafeFree(dec->pixels_);
+  dec->pixels_ = NULL;
+  for (i = 0; i < dec->next_transform_; ++i) {
+    ClearTransform(&dec->transforms_[i]);
+  }
+  dec->next_transform_ = 0;
+  dec->transforms_seen_ = 0;
+
+  WebPSafeFree(dec->rescaler_memory);
+  dec->rescaler_memory = NULL;
+
+  dec->output_ = NULL;   // leave no trace behind
+}
+
+void VP8LDelete(VP8LDecoder* const dec) {
+  if (dec != NULL) {
+    VP8LClear(dec);
+    WebPSafeFree(dec);
+  }
+}
+
+static void UpdateDecoder(VP8LDecoder* const dec, int width, int height) {
+  VP8LMetadata* const hdr = &dec->hdr_;
+  const int num_bits = hdr->huffman_subsample_bits_;
+  dec->width_ = width;
+  dec->height_ = height;
+
+  hdr->huffman_xsize_ = VP8LSubSampleSize(width, num_bits);
+  hdr->huffman_mask_ = (num_bits == 0) ? ~0 : (1 << num_bits) - 1;
+}
+
+static int DecodeImageStream(int xsize, int ysize,
+                             int is_level0,
+                             VP8LDecoder* const dec,
+                             uint32_t** const decoded_data) {
+  int ok = 1;
+  int transform_xsize = xsize;
+  int transform_ysize = ysize;
+  VP8LBitReader* const br = &dec->br_;
+  VP8LMetadata* const hdr = &dec->hdr_;
+  uint32_t* data = NULL;
+  int color_cache_bits = 0;
+
+  // Read the transforms (may recurse).
+  if (is_level0) {
+    while (ok && VP8LReadBits(br, 1)) {
+      ok = ReadTransform(&transform_xsize, &transform_ysize, dec);
+    }
+  }
+
+  // Color cache
+  if (ok && VP8LReadBits(br, 1)) {
+    color_cache_bits = VP8LReadBits(br, 4);
+    ok = (color_cache_bits >= 1 && color_cache_bits <= MAX_CACHE_BITS);
+    if (!ok) {
+      dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
+      goto End;
+    }
+  }
+
+  // Read the Huffman codes (may recurse).
+  ok = ok && ReadHuffmanCodes(dec, transform_xsize, transform_ysize,
+                              color_cache_bits, is_level0);
+  if (!ok) {
+    dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
+    goto End;
+  }
+
+  // Finish setting up the color-cache
+  if (color_cache_bits > 0) {
+    hdr->color_cache_size_ = 1 << color_cache_bits;
+    if (!VP8LColorCacheInit(&hdr->color_cache_, color_cache_bits)) {
+      dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
+      ok = 0;
+      goto End;
+    }
+  } else {
+    hdr->color_cache_size_ = 0;
+  }
+  UpdateDecoder(dec, transform_xsize, transform_ysize);
+
+  if (is_level0) {   // level 0 complete
+    dec->state_ = READ_HDR;
+    goto End;
+  }
+
+  {
+    const uint64_t total_size = (uint64_t)transform_xsize * transform_ysize;
+    data = (uint32_t*)WebPSafeMalloc(total_size, sizeof(*data));
+    if (data == NULL) {
+      dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
+      ok = 0;
+      goto End;
+    }
+  }
+
+  // Use the Huffman trees to decode the LZ77 encoded data.
+  ok = DecodeImageData(dec, data, transform_xsize, transform_ysize,
+                       transform_ysize, NULL);
+  ok = ok && !br->eos_;
+
+ End:
+  if (!ok) {
+    WebPSafeFree(data);
+    ClearMetadata(hdr);
+  } else {
+    if (decoded_data != NULL) {
+      *decoded_data = data;
+    } else {
+      // We allocate image data in this function only for transforms. At level 0
+      // (that is: not the transforms), we shouldn't have allocated anything.
+      assert(data == NULL);
+      assert(is_level0);
+    }
+    dec->last_pixel_ = 0;  // Reset for future DECODE_DATA_FUNC() calls.
+    if (!is_level0) ClearMetadata(hdr);  // Clean up temporary data behind.
+  }
+  return ok;
+}
+
+//------------------------------------------------------------------------------
+// Allocate internal buffers dec->pixels_ and dec->argb_cache_.
+static int AllocateInternalBuffers32b(VP8LDecoder* const dec, int final_width) {
+  const uint64_t num_pixels = (uint64_t)dec->width_ * dec->height_;
+  // Scratch buffer corresponding to top-prediction row for transforming the
+  // first row in the row-blocks. Not needed for paletted alpha.
+  const uint64_t cache_top_pixels = (uint16_t)final_width;
+  // Scratch buffer for temporary BGRA storage. Not needed for paletted alpha.
+  const uint64_t cache_pixels = (uint64_t)final_width * NUM_ARGB_CACHE_ROWS;
+  const uint64_t total_num_pixels =
+      num_pixels + cache_top_pixels + cache_pixels;
+
+  assert(dec->width_ <= final_width);
+  dec->pixels_ = (uint32_t*)WebPSafeMalloc(total_num_pixels, sizeof(uint32_t));
+  if (dec->pixels_ == NULL) {
+    dec->argb_cache_ = NULL;    // for sanity check
+    dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
+    return 0;
+  }
+  dec->argb_cache_ = dec->pixels_ + num_pixels + cache_top_pixels;
+  return 1;
+}
+
+static int AllocateInternalBuffers8b(VP8LDecoder* const dec) {
+  const uint64_t total_num_pixels = (uint64_t)dec->width_ * dec->height_;
+  dec->argb_cache_ = NULL;    // for sanity check
+  dec->pixels_ = (uint32_t*)WebPSafeMalloc(total_num_pixels, sizeof(uint8_t));
+  if (dec->pixels_ == NULL) {
+    dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
+    return 0;
+  }
+  return 1;
+}
+
+//------------------------------------------------------------------------------
+
+// Special row-processing that only stores the alpha data.
+static void ExtractAlphaRows(VP8LDecoder* const dec, int row) {
+  const int num_rows = row - dec->last_row_;
+  const uint32_t* const in = dec->pixels_ + dec->width_ * dec->last_row_;
+
+  if (num_rows <= 0) return;  // Nothing to be done.
+  ApplyInverseTransforms(dec, num_rows, in);
+
+  // Extract alpha (which is stored in the green plane).
+  {
+    const int width = dec->io_->width;      // the final width (!= dec->width_)
+    const int cache_pixs = width * num_rows;
+    uint8_t* const dst = (uint8_t*)dec->io_->opaque + width * dec->last_row_;
+    const uint32_t* const src = dec->argb_cache_;
+    int i;
+    for (i = 0; i < cache_pixs; ++i) dst[i] = (src[i] >> 8) & 0xff;
+  }
+  dec->last_row_ = dec->last_out_row_ = row;
+}
+
+int VP8LDecodeAlphaHeader(ALPHDecoder* const alph_dec,
+                          const uint8_t* const data, size_t data_size,
+                          uint8_t* const output) {
+  int ok = 0;
+  VP8LDecoder* dec;
+  VP8Io* io;
+  assert(alph_dec != NULL);
+  alph_dec->vp8l_dec_ = VP8LNew();
+  if (alph_dec->vp8l_dec_ == NULL) return 0;
+  dec = alph_dec->vp8l_dec_;
+
+  dec->width_ = alph_dec->width_;
+  dec->height_ = alph_dec->height_;
+  dec->io_ = &alph_dec->io_;
+  io = dec->io_;
+
+  VP8InitIo(io);
+  WebPInitCustomIo(NULL, io);  // Just a sanity Init. io won't be used.
+  io->opaque = output;
+  io->width = alph_dec->width_;
+  io->height = alph_dec->height_;
+
+  dec->status_ = VP8_STATUS_OK;
+  VP8LInitBitReader(&dec->br_, data, data_size);
+
+  if (!DecodeImageStream(alph_dec->width_, alph_dec->height_, 1, dec, NULL)) {
+    goto Err;
+  }
+
+  // Special case: if alpha data uses only the color indexing transform and
+  // doesn't use color cache (a frequent case), we will use DecodeAlphaData()
+  // method that only needs allocation of 1 byte per pixel (alpha channel).
+  if (dec->next_transform_ == 1 &&
+      dec->transforms_[0].type_ == COLOR_INDEXING_TRANSFORM &&
+      Is8bOptimizable(&dec->hdr_)) {
+    alph_dec->use_8b_decode = 1;
+    ok = AllocateInternalBuffers8b(dec);
+  } else {
+    // Allocate internal buffers (note that dec->width_ may have changed here).
+    alph_dec->use_8b_decode = 0;
+    ok = AllocateInternalBuffers32b(dec, alph_dec->width_);
+  }
+
+  if (!ok) goto Err;
+
+  return 1;
+
+ Err:
+  VP8LDelete(alph_dec->vp8l_dec_);
+  alph_dec->vp8l_dec_ = NULL;
+  return 0;
+}
+
+int VP8LDecodeAlphaImageStream(ALPHDecoder* const alph_dec, int last_row) {
+  VP8LDecoder* const dec = alph_dec->vp8l_dec_;
+  assert(dec != NULL);
+  assert(last_row <= dec->height_);
+
+  if (dec->last_pixel_ == dec->width_ * dec->height_) {
+    return 1;  // done
+  }
+
+  // Decode (with special row processing).
+  return alph_dec->use_8b_decode ?
+      DecodeAlphaData(dec, (uint8_t*)dec->pixels_, dec->width_, dec->height_,
+                      last_row) :
+      DecodeImageData(dec, dec->pixels_, dec->width_, dec->height_,
+                      last_row, ExtractAlphaRows);
+}
+
+//------------------------------------------------------------------------------
+
+int VP8LDecodeHeader(VP8LDecoder* const dec, VP8Io* const io) {
+  int width, height, has_alpha;
+
+  if (dec == NULL) return 0;
+  if (io == NULL) {
+    dec->status_ = VP8_STATUS_INVALID_PARAM;
+    return 0;
+  }
+
+  dec->io_ = io;
+  dec->status_ = VP8_STATUS_OK;
+  VP8LInitBitReader(&dec->br_, io->data, io->data_size);
+  if (!ReadImageInfo(&dec->br_, &width, &height, &has_alpha)) {
+    dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
+    goto Error;
+  }
+  dec->state_ = READ_DIM;
+  io->width = width;
+  io->height = height;
+
+  if (!DecodeImageStream(width, height, 1, dec, NULL)) goto Error;
+  return 1;
+
+ Error:
+  VP8LClear(dec);
+  assert(dec->status_ != VP8_STATUS_OK);
+  return 0;
+}
+
+int VP8LDecodeImage(VP8LDecoder* const dec) {
+  VP8Io* io = NULL;
+  WebPDecParams* params = NULL;
+
+  // Sanity checks.
+  if (dec == NULL) return 0;
+
+  assert(dec->hdr_.huffman_tables_ != NULL);
+  assert(dec->hdr_.htree_groups_ != NULL);
+  assert(dec->hdr_.num_htree_groups_ > 0);
+
+  io = dec->io_;
+  assert(io != NULL);
+  params = (WebPDecParams*)io->opaque;
+  assert(params != NULL);
+
+  // Initialization.
+  if (dec->state_ != READ_DATA) {
+    dec->output_ = params->output;
+    assert(dec->output_ != NULL);
+
+    if (!WebPIoInitFromOptions(params->options, io, MODE_BGRA)) {
+      dec->status_ = VP8_STATUS_INVALID_PARAM;
+      goto Err;
+    }
+
+    if (!AllocateInternalBuffers32b(dec, io->width)) goto Err;
+
+    if (io->use_scaling && !AllocateAndInitRescaler(dec, io)) goto Err;
+
+    if (io->use_scaling || WebPIsPremultipliedMode(dec->output_->colorspace)) {
+      // need the alpha-multiply functions for premultiplied output or rescaling
+      WebPInitAlphaProcessing();
+    }
+    if (dec->incremental_) {
+      if (dec->hdr_.color_cache_size_ > 0 &&
+          dec->hdr_.saved_color_cache_.colors_ == NULL) {
+        if (!VP8LColorCacheInit(&dec->hdr_.saved_color_cache_,
+                                dec->hdr_.color_cache_.hash_bits_)) {
+          dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
+          goto Err;
+        }
+      }
+    }
+    dec->state_ = READ_DATA;
+  }
+
+  // Decode.
+  if (!DecodeImageData(dec, dec->pixels_, dec->width_, dec->height_,
+                       dec->height_, ProcessRows)) {
+    goto Err;
+  }
+
+  params->last_y = dec->last_out_row_;
+  return 1;
+
+ Err:
+  VP8LClear(dec);
+  assert(dec->status_ != VP8_STATUS_OK);
+  return 0;
+}
+
+//------------------------------------------------------------------------------
diff --git a/Source/LibWebP/src/dec/dec.webp.c b/Source/LibWebP/src/dec/dec.webp.c
new file mode 100644
index 0000000..f078e68
--- /dev/null
+++ b/Source/LibWebP/src/dec/dec.webp.c
@@ -0,0 +1,834 @@
+// Copyright 2010 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Main decoding functions for WEBP images.
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include <stdlib.h>
+
+#include "./vp8i.h"
+#include "./vp8li.h"
+#include "./webpi.h"
+#include "../webp/mux_types.h"  // ALPHA_FLAG
+
+//------------------------------------------------------------------------------
+// RIFF layout is:
+//   Offset  tag
+//   0...3   "RIFF" 4-byte tag
+//   4...7   size of image data (including metadata) starting at offset 8
+//   8...11  "WEBP"   our form-type signature
+// The RIFF container (12 bytes) is followed by appropriate chunks:
+//   12..15  "VP8 ": 4-bytes tags, signaling the use of VP8 video format
+//   16..19  size of the raw VP8 image data, starting at offset 20
+//   20....  the VP8 bytes
+// Or,
+//   12..15  "VP8L": 4-bytes tags, signaling the use of VP8L lossless format
+//   16..19  size of the raw VP8L image data, starting at offset 20
+//   20....  the VP8L bytes
+// Or,
+//   12..15  "VP8X": 4-bytes tags, describing the extended-VP8 chunk.
+//   16..19  size of the VP8X chunk starting at offset 20.
+//   20..23  VP8X flags bit-map corresponding to the chunk-types present.
+//   24..26  Width of the Canvas Image.
+//   27..29  Height of the Canvas Image.
+// There can be extra chunks after the "VP8X" chunk (ICCP, FRGM, ANMF, VP8,
+// VP8L, XMP, EXIF  ...)
+// All sizes are in little-endian order.
+// Note: chunk data size must be padded to multiple of 2 when written.
+
+static WEBP_INLINE uint32_t get_le24(const uint8_t* const data) {
+  return data[0] | (data[1] << 8) | (data[2] << 16);
+}
+
+static WEBP_INLINE uint32_t get_le32(const uint8_t* const data) {
+  return (uint32_t)get_le24(data) | (data[3] << 24);
+}
+
+// Validates the RIFF container (if detected) and skips over it.
+// If a RIFF container is detected, returns:
+//     VP8_STATUS_BITSTREAM_ERROR for invalid header,
+//     VP8_STATUS_NOT_ENOUGH_DATA for truncated data if have_all_data is true,
+// and VP8_STATUS_OK otherwise.
+// In case there are not enough bytes (partial RIFF container), return 0 for
+// *riff_size. Else return the RIFF size extracted from the header.
+static VP8StatusCode ParseRIFF(const uint8_t** const data,
+                               size_t* const data_size, int have_all_data,
+                               size_t* const riff_size) {
+  assert(data != NULL);
+  assert(data_size != NULL);
+  assert(riff_size != NULL);
+
+  *riff_size = 0;  // Default: no RIFF present.
+  if (*data_size >= RIFF_HEADER_SIZE && !memcmp(*data, "RIFF", TAG_SIZE)) {
+    if (memcmp(*data + 8, "WEBP", TAG_SIZE)) {
+      return VP8_STATUS_BITSTREAM_ERROR;  // Wrong image file signature.
+    } else {
+      const uint32_t size = get_le32(*data + TAG_SIZE);
+      // Check that we have at least one chunk (i.e "WEBP" + "VP8?nnnn").
+      if (size < TAG_SIZE + CHUNK_HEADER_SIZE) {
+        return VP8_STATUS_BITSTREAM_ERROR;
+      }
+      if (size > MAX_CHUNK_PAYLOAD) {
+        return VP8_STATUS_BITSTREAM_ERROR;
+      }
+      if (have_all_data && (size > *data_size - CHUNK_HEADER_SIZE)) {
+        return VP8_STATUS_NOT_ENOUGH_DATA;  // Truncated bitstream.
+      }
+      // We have a RIFF container. Skip it.
+      *riff_size = size;
+      *data += RIFF_HEADER_SIZE;
+      *data_size -= RIFF_HEADER_SIZE;
+    }
+  }
+  return VP8_STATUS_OK;
+}
+
+// Validates the VP8X header and skips over it.
+// Returns VP8_STATUS_BITSTREAM_ERROR for invalid VP8X header,
+//         VP8_STATUS_NOT_ENOUGH_DATA in case of insufficient data, and
+//         VP8_STATUS_OK otherwise.
+// If a VP8X chunk is found, found_vp8x is set to true and *width_ptr,
+// *height_ptr and *flags_ptr are set to the corresponding values extracted
+// from the VP8X chunk.
+static VP8StatusCode ParseVP8X(const uint8_t** const data,
+                               size_t* const data_size,
+                               int* const found_vp8x,
+                               int* const width_ptr, int* const height_ptr,
+                               uint32_t* const flags_ptr) {
+  const uint32_t vp8x_size = CHUNK_HEADER_SIZE + VP8X_CHUNK_SIZE;
+  assert(data != NULL);
+  assert(data_size != NULL);
+  assert(found_vp8x != NULL);
+
+  *found_vp8x = 0;
+
+  if (*data_size < CHUNK_HEADER_SIZE) {
+    return VP8_STATUS_NOT_ENOUGH_DATA;  // Insufficient data.
+  }
+
+  if (!memcmp(*data, "VP8X", TAG_SIZE)) {
+    int width, height;
+    uint32_t flags;
+    const uint32_t chunk_size = get_le32(*data + TAG_SIZE);
+    if (chunk_size != VP8X_CHUNK_SIZE) {
+      return VP8_STATUS_BITSTREAM_ERROR;  // Wrong chunk size.
+    }
+
+    // Verify if enough data is available to validate the VP8X chunk.
+    if (*data_size < vp8x_size) {
+      return VP8_STATUS_NOT_ENOUGH_DATA;  // Insufficient data.
+    }
+    flags = get_le32(*data + 8);
+    width = 1 + get_le24(*data + 12);
+    height = 1 + get_le24(*data + 15);
+    if (width * (uint64_t)height >= MAX_IMAGE_AREA) {
+      return VP8_STATUS_BITSTREAM_ERROR;  // image is too large
+    }
+
+    if (flags_ptr != NULL) *flags_ptr = flags;
+    if (width_ptr != NULL) *width_ptr = width;
+    if (height_ptr != NULL) *height_ptr = height;
+    // Skip over VP8X header bytes.
+    *data += vp8x_size;
+    *data_size -= vp8x_size;
+    *found_vp8x = 1;
+  }
+  return VP8_STATUS_OK;
+}
+
+// Skips to the next VP8/VP8L chunk header in the data given the size of the
+// RIFF chunk 'riff_size'.
+// Returns VP8_STATUS_BITSTREAM_ERROR if any invalid chunk size is encountered,
+//         VP8_STATUS_NOT_ENOUGH_DATA in case of insufficient data, and
+//         VP8_STATUS_OK otherwise.
+// If an alpha chunk is found, *alpha_data and *alpha_size are set
+// appropriately.
+static VP8StatusCode ParseOptionalChunks(const uint8_t** const data,
+                                         size_t* const data_size,
+                                         size_t const riff_size,
+                                         const uint8_t** const alpha_data,
+                                         size_t* const alpha_size) {
+  const uint8_t* buf;
+  size_t buf_size;
+  uint32_t total_size = TAG_SIZE +           // "WEBP".
+                        CHUNK_HEADER_SIZE +  // "VP8Xnnnn".
+                        VP8X_CHUNK_SIZE;     // data.
+  assert(data != NULL);
+  assert(data_size != NULL);
+  buf = *data;
+  buf_size = *data_size;
+
+  assert(alpha_data != NULL);
+  assert(alpha_size != NULL);
+  *alpha_data = NULL;
+  *alpha_size = 0;
+
+  while (1) {
+    uint32_t chunk_size;
+    uint32_t disk_chunk_size;   // chunk_size with padding
+
+    *data = buf;
+    *data_size = buf_size;
+
+    if (buf_size < CHUNK_HEADER_SIZE) {  // Insufficient data.
+      return VP8_STATUS_NOT_ENOUGH_DATA;
+    }
+
+    chunk_size = get_le32(buf + TAG_SIZE);
+    if (chunk_size > MAX_CHUNK_PAYLOAD) {
+      return VP8_STATUS_BITSTREAM_ERROR;          // Not a valid chunk size.
+    }
+    // For odd-sized chunk-payload, there's one byte padding at the end.
+    disk_chunk_size = (CHUNK_HEADER_SIZE + chunk_size + 1) & ~1;
+    total_size += disk_chunk_size;
+
+    // Check that total bytes skipped so far does not exceed riff_size.
+    if (riff_size > 0 && (total_size > riff_size)) {
+      return VP8_STATUS_BITSTREAM_ERROR;          // Not a valid chunk size.
+    }
+
+    // Start of a (possibly incomplete) VP8/VP8L chunk implies that we have
+    // parsed all the optional chunks.
+    // Note: This check must occur before the check 'buf_size < disk_chunk_size'
+    // below to allow incomplete VP8/VP8L chunks.
+    if (!memcmp(buf, "VP8 ", TAG_SIZE) ||
+        !memcmp(buf, "VP8L", TAG_SIZE)) {
+      return VP8_STATUS_OK;
+    }
+
+    if (buf_size < disk_chunk_size) {             // Insufficient data.
+      return VP8_STATUS_NOT_ENOUGH_DATA;
+    }
+
+    if (!memcmp(buf, "ALPH", TAG_SIZE)) {         // A valid ALPH header.
+      *alpha_data = buf + CHUNK_HEADER_SIZE;
+      *alpha_size = chunk_size;
+    }
+
+    // We have a full and valid chunk; skip it.
+    buf += disk_chunk_size;
+    buf_size -= disk_chunk_size;
+  }
+}
+
+// Validates the VP8/VP8L Header ("VP8 nnnn" or "VP8L nnnn") and skips over it.
+// Returns VP8_STATUS_BITSTREAM_ERROR for invalid (chunk larger than
+//         riff_size) VP8/VP8L header,
+//         VP8_STATUS_NOT_ENOUGH_DATA in case of insufficient data, and
+//         VP8_STATUS_OK otherwise.
+// If a VP8/VP8L chunk is found, *chunk_size is set to the total number of bytes
+// extracted from the VP8/VP8L chunk header.
+// The flag '*is_lossless' is set to 1 in case of VP8L chunk / raw VP8L data.
+static VP8StatusCode ParseVP8Header(const uint8_t** const data_ptr,
+                                    size_t* const data_size, int have_all_data,
+                                    size_t riff_size, size_t* const chunk_size,
+                                    int* const is_lossless) {
+  const uint8_t* const data = *data_ptr;
+  const int is_vp8 = !memcmp(data, "VP8 ", TAG_SIZE);
+  const int is_vp8l = !memcmp(data, "VP8L", TAG_SIZE);
+  const uint32_t minimal_size =
+      TAG_SIZE + CHUNK_HEADER_SIZE;  // "WEBP" + "VP8 nnnn" OR
+                                     // "WEBP" + "VP8Lnnnn"
+  assert(data != NULL);
+  assert(data_size != NULL);
+  assert(chunk_size != NULL);
+  assert(is_lossless != NULL);
+
+  if (*data_size < CHUNK_HEADER_SIZE) {
+    return VP8_STATUS_NOT_ENOUGH_DATA;  // Insufficient data.
+  }
+
+  if (is_vp8 || is_vp8l) {
+    // Bitstream contains VP8/VP8L header.
+    const uint32_t size = get_le32(data + TAG_SIZE);
+    if ((riff_size >= minimal_size) && (size > riff_size - minimal_size)) {
+      return VP8_STATUS_BITSTREAM_ERROR;  // Inconsistent size information.
+    }
+    if (have_all_data && (size > *data_size - CHUNK_HEADER_SIZE)) {
+      return VP8_STATUS_NOT_ENOUGH_DATA;  // Truncated bitstream.
+    }
+    // Skip over CHUNK_HEADER_SIZE bytes from VP8/VP8L Header.
+    *chunk_size = size;
+    *data_ptr += CHUNK_HEADER_SIZE;
+    *data_size -= CHUNK_HEADER_SIZE;
+    *is_lossless = is_vp8l;
+  } else {
+    // Raw VP8/VP8L bitstream (no header).
+    *is_lossless = VP8LCheckSignature(data, *data_size);
+    *chunk_size = *data_size;
+  }
+
+  return VP8_STATUS_OK;
+}
+
+//------------------------------------------------------------------------------
+
+// Fetch '*width', '*height', '*has_alpha' and fill out 'headers' based on
+// 'data'. All the output parameters may be NULL. If 'headers' is NULL only the
+// minimal amount will be read to fetch the remaining parameters.
+// If 'headers' is non-NULL this function will attempt to locate both alpha
+// data (with or without a VP8X chunk) and the bitstream chunk (VP8/VP8L).
+// Note: The following chunk sequences (before the raw VP8/VP8L data) are
+// considered valid by this function:
+// RIFF + VP8(L)
+// RIFF + VP8X + (optional chunks) + VP8(L)
+// ALPH + VP8 <-- Not a valid WebP format: only allowed for internal purpose.
+// VP8(L)     <-- Not a valid WebP format: only allowed for internal purpose.
+static VP8StatusCode ParseHeadersInternal(const uint8_t* data,
+                                          size_t data_size,
+                                          int* const width,
+                                          int* const height,
+                                          int* const has_alpha,
+                                          int* const has_animation,
+                                          int* const format,
+                                          WebPHeaderStructure* const headers) {
+  int canvas_width = 0;
+  int canvas_height = 0;
+  int image_width = 0;
+  int image_height = 0;
+  int found_riff = 0;
+  int found_vp8x = 0;
+  int animation_present = 0;
+  int fragments_present = 0;
+  const int have_all_data = (headers != NULL) ? headers->have_all_data : 0;
+
+  VP8StatusCode status;
+  WebPHeaderStructure hdrs;
+
+  if (data == NULL || data_size < RIFF_HEADER_SIZE) {
+    return VP8_STATUS_NOT_ENOUGH_DATA;
+  }
+  memset(&hdrs, 0, sizeof(hdrs));
+  hdrs.data = data;
+  hdrs.data_size = data_size;
+
+  // Skip over RIFF header.
+  status = ParseRIFF(&data, &data_size, have_all_data, &hdrs.riff_size);
+  if (status != VP8_STATUS_OK) {
+    return status;   // Wrong RIFF header / insufficient data.
+  }
+  found_riff = (hdrs.riff_size > 0);
+
+  // Skip over VP8X.
+  {
+    uint32_t flags = 0;
+    status = ParseVP8X(&data, &data_size, &found_vp8x,
+                       &canvas_width, &canvas_height, &flags);
+    if (status != VP8_STATUS_OK) {
+      return status;  // Wrong VP8X / insufficient data.
+    }
+    animation_present = !!(flags & ANIMATION_FLAG);
+    fragments_present = !!(flags & FRAGMENTS_FLAG);
+    if (!found_riff && found_vp8x) {
+      // Note: This restriction may be removed in the future, if it becomes
+      // necessary to send VP8X chunk to the decoder.
+      return VP8_STATUS_BITSTREAM_ERROR;
+    }
+    if (has_alpha != NULL) *has_alpha = !!(flags & ALPHA_FLAG);
+    if (has_animation != NULL) *has_animation = animation_present;
+    if (format != NULL) *format = 0;   // default = undefined
+
+    image_width = canvas_width;
+    image_height = canvas_height;
+    if (found_vp8x && (animation_present || fragments_present) &&
+        headers == NULL) {
+      status = VP8_STATUS_OK;
+      goto ReturnWidthHeight;  // Just return features from VP8X header.
+    }
+  }
+
+  if (data_size < TAG_SIZE) {
+    status = VP8_STATUS_NOT_ENOUGH_DATA;
+    goto ReturnWidthHeight;
+  }
+
+  // Skip over optional chunks if data started with "RIFF + VP8X" or "ALPH".
+  if ((found_riff && found_vp8x) ||
+      (!found_riff && !found_vp8x && !memcmp(data, "ALPH", TAG_SIZE))) {
+    status = ParseOptionalChunks(&data, &data_size, hdrs.riff_size,
+                                 &hdrs.alpha_data, &hdrs.alpha_data_size);
+    if (status != VP8_STATUS_OK) {
+      goto ReturnWidthHeight;  // Invalid chunk size / insufficient data.
+    }
+  }
+
+  // Skip over VP8/VP8L header.
+  status = ParseVP8Header(&data, &data_size, have_all_data, hdrs.riff_size,
+                          &hdrs.compressed_size, &hdrs.is_lossless);
+  if (status != VP8_STATUS_OK) {
+    goto ReturnWidthHeight;  // Wrong VP8/VP8L chunk-header / insufficient data.
+  }
+  if (hdrs.compressed_size > MAX_CHUNK_PAYLOAD) {
+    return VP8_STATUS_BITSTREAM_ERROR;
+  }
+
+  if (format != NULL && !(animation_present || fragments_present)) {
+    *format = hdrs.is_lossless ? 2 : 1;
+  }
+
+  if (!hdrs.is_lossless) {
+    if (data_size < VP8_FRAME_HEADER_SIZE) {
+      status = VP8_STATUS_NOT_ENOUGH_DATA;
+      goto ReturnWidthHeight;
+    }
+    // Validates raw VP8 data.
+    if (!VP8GetInfo(data, data_size, (uint32_t)hdrs.compressed_size,
+                    &image_width, &image_height)) {
+      return VP8_STATUS_BITSTREAM_ERROR;
+    }
+  } else {
+    if (data_size < VP8L_FRAME_HEADER_SIZE) {
+      status = VP8_STATUS_NOT_ENOUGH_DATA;
+      goto ReturnWidthHeight;
+    }
+    // Validates raw VP8L data.
+    if (!VP8LGetInfo(data, data_size, &image_width, &image_height, has_alpha)) {
+      return VP8_STATUS_BITSTREAM_ERROR;
+    }
+  }
+  // Validates image size coherency.
+  if (found_vp8x) {
+    if (canvas_width != image_width || canvas_height != image_height) {
+      return VP8_STATUS_BITSTREAM_ERROR;
+    }
+  }
+  if (headers != NULL) {
+    *headers = hdrs;
+    headers->offset = data - headers->data;
+    assert((uint64_t)(data - headers->data) < MAX_CHUNK_PAYLOAD);
+    assert(headers->offset == headers->data_size - data_size);
+  }
+ ReturnWidthHeight:
+  if (status == VP8_STATUS_OK ||
+      (status == VP8_STATUS_NOT_ENOUGH_DATA && found_vp8x && headers == NULL)) {
+    if (has_alpha != NULL) {
+      // If the data did not contain a VP8X/VP8L chunk the only definitive way
+      // to set this is by looking for alpha data (from an ALPH chunk).
+      *has_alpha |= (hdrs.alpha_data != NULL);
+    }
+    if (width != NULL) *width = image_width;
+    if (height != NULL) *height = image_height;
+    return VP8_STATUS_OK;
+  } else {
+    return status;
+  }
+}
+
+VP8StatusCode WebPParseHeaders(WebPHeaderStructure* const headers) {
+  VP8StatusCode status;
+  int has_animation = 0;
+  assert(headers != NULL);
+  // fill out headers, ignore width/height/has_alpha.
+  status = ParseHeadersInternal(headers->data, headers->data_size,
+                                NULL, NULL, NULL, &has_animation,
+                                NULL, headers);
+  if (status == VP8_STATUS_OK || status == VP8_STATUS_NOT_ENOUGH_DATA) {
+    // TODO(jzern): full support of animation frames will require API additions.
+    if (has_animation) {
+      status = VP8_STATUS_UNSUPPORTED_FEATURE;
+    }
+  }
+  return status;
+}
+
+//------------------------------------------------------------------------------
+// WebPDecParams
+
+void WebPResetDecParams(WebPDecParams* const params) {
+  if (params != NULL) {
+    memset(params, 0, sizeof(*params));
+  }
+}
+
+//------------------------------------------------------------------------------
+// "Into" decoding variants
+
+// Main flow
+static VP8StatusCode DecodeInto(const uint8_t* const data, size_t data_size,
+                                WebPDecParams* const params) {
+  VP8StatusCode status;
+  VP8Io io;
+  WebPHeaderStructure headers;
+
+  headers.data = data;
+  headers.data_size = data_size;
+  headers.have_all_data = 1;
+  status = WebPParseHeaders(&headers);   // Process Pre-VP8 chunks.
+  if (status != VP8_STATUS_OK) {
+    return status;
+  }
+
+  assert(params != NULL);
+  VP8InitIo(&io);
+  io.data = headers.data + headers.offset;
+  io.data_size = headers.data_size - headers.offset;
+  WebPInitCustomIo(params, &io);  // Plug the I/O functions.
+
+  if (!headers.is_lossless) {
+    VP8Decoder* const dec = VP8New();
+    if (dec == NULL) {
+      return VP8_STATUS_OUT_OF_MEMORY;
+    }
+    dec->alpha_data_ = headers.alpha_data;
+    dec->alpha_data_size_ = headers.alpha_data_size;
+
+    // Decode bitstream header, update io->width/io->height.
+    if (!VP8GetHeaders(dec, &io)) {
+      status = dec->status_;   // An error occurred. Grab error status.
+    } else {
+      // Allocate/check output buffers.
+      status = WebPAllocateDecBuffer(io.width, io.height, params->options,
+                                     params->output);
+      if (status == VP8_STATUS_OK) {  // Decode
+        // This change must be done before calling VP8Decode()
+        dec->mt_method_ = VP8GetThreadMethod(params->options, &headers,
+                                             io.width, io.height);
+        VP8InitDithering(params->options, dec);
+        if (!VP8Decode(dec, &io)) {
+          status = dec->status_;
+        }
+      }
+    }
+    VP8Delete(dec);
+  } else {
+    VP8LDecoder* const dec = VP8LNew();
+    if (dec == NULL) {
+      return VP8_STATUS_OUT_OF_MEMORY;
+    }
+    if (!VP8LDecodeHeader(dec, &io)) {
+      status = dec->status_;   // An error occurred. Grab error status.
+    } else {
+      // Allocate/check output buffers.
+      status = WebPAllocateDecBuffer(io.width, io.height, params->options,
+                                     params->output);
+      if (status == VP8_STATUS_OK) {  // Decode
+        if (!VP8LDecodeImage(dec)) {
+          status = dec->status_;
+        }
+      }
+    }
+    VP8LDelete(dec);
+  }
+
+  if (status != VP8_STATUS_OK) {
+    WebPFreeDecBuffer(params->output);
+  }
+
+  if (params->options != NULL && params->options->flip) {
+    status = WebPFlipBuffer(params->output);
+  }
+  return status;
+}
+
+// Helpers
+static uint8_t* DecodeIntoRGBABuffer(WEBP_CSP_MODE colorspace,
+                                     const uint8_t* const data,
+                                     size_t data_size,
+                                     uint8_t* const rgba,
+                                     int stride, size_t size) {
+  WebPDecParams params;
+  WebPDecBuffer buf;
+  if (rgba == NULL) {
+    return NULL;
+  }
+  WebPInitDecBuffer(&buf);
+  WebPResetDecParams(&params);
+  params.output = &buf;
+  buf.colorspace    = colorspace;
+  buf.u.RGBA.rgba   = rgba;
+  buf.u.RGBA.stride = stride;
+  buf.u.RGBA.size   = size;
+  buf.is_external_memory = 1;
+  if (DecodeInto(data, data_size, &params) != VP8_STATUS_OK) {
+    return NULL;
+  }
+  return rgba;
+}
+
+uint8_t* WebPDecodeRGBInto(const uint8_t* data, size_t data_size,
+                           uint8_t* output, size_t size, int stride) {
+  return DecodeIntoRGBABuffer(MODE_RGB, data, data_size, output, stride, size);
+}
+
+uint8_t* WebPDecodeRGBAInto(const uint8_t* data, size_t data_size,
+                            uint8_t* output, size_t size, int stride) {
+  return DecodeIntoRGBABuffer(MODE_RGBA, data, data_size, output, stride, size);
+}
+
+uint8_t* WebPDecodeARGBInto(const uint8_t* data, size_t data_size,
+                            uint8_t* output, size_t size, int stride) {
+  return DecodeIntoRGBABuffer(MODE_ARGB, data, data_size, output, stride, size);
+}
+
+uint8_t* WebPDecodeBGRInto(const uint8_t* data, size_t data_size,
+                           uint8_t* output, size_t size, int stride) {
+  return DecodeIntoRGBABuffer(MODE_BGR, data, data_size, output, stride, size);
+}
+
+uint8_t* WebPDecodeBGRAInto(const uint8_t* data, size_t data_size,
+                            uint8_t* output, size_t size, int stride) {
+  return DecodeIntoRGBABuffer(MODE_BGRA, data, data_size, output, stride, size);
+}
+
+uint8_t* WebPDecodeYUVInto(const uint8_t* data, size_t data_size,
+                           uint8_t* luma, size_t luma_size, int luma_stride,
+                           uint8_t* u, size_t u_size, int u_stride,
+                           uint8_t* v, size_t v_size, int v_stride) {
+  WebPDecParams params;
+  WebPDecBuffer output;
+  if (luma == NULL) return NULL;
+  WebPInitDecBuffer(&output);
+  WebPResetDecParams(&params);
+  params.output = &output;
+  output.colorspace      = MODE_YUV;
+  output.u.YUVA.y        = luma;
+  output.u.YUVA.y_stride = luma_stride;
+  output.u.YUVA.y_size   = luma_size;
+  output.u.YUVA.u        = u;
+  output.u.YUVA.u_stride = u_stride;
+  output.u.YUVA.u_size   = u_size;
+  output.u.YUVA.v        = v;
+  output.u.YUVA.v_stride = v_stride;
+  output.u.YUVA.v_size   = v_size;
+  output.is_external_memory = 1;
+  if (DecodeInto(data, data_size, &params) != VP8_STATUS_OK) {
+    return NULL;
+  }
+  return luma;
+}
+
+//------------------------------------------------------------------------------
+
+static uint8_t* Decode(WEBP_CSP_MODE mode, const uint8_t* const data,
+                       size_t data_size, int* const width, int* const height,
+                       WebPDecBuffer* const keep_info) {
+  WebPDecParams params;
+  WebPDecBuffer output;
+
+  WebPInitDecBuffer(&output);
+  WebPResetDecParams(&params);
+  params.output = &output;
+  output.colorspace = mode;
+
+  // Retrieve (and report back) the required dimensions from bitstream.
+  if (!WebPGetInfo(data, data_size, &output.width, &output.height)) {
+    return NULL;
+  }
+  if (width != NULL) *width = output.width;
+  if (height != NULL) *height = output.height;
+
+  // Decode
+  if (DecodeInto(data, data_size, &params) != VP8_STATUS_OK) {
+    return NULL;
+  }
+  if (keep_info != NULL) {    // keep track of the side-info
+    WebPCopyDecBuffer(&output, keep_info);
+  }
+  // return decoded samples (don't clear 'output'!)
+  return WebPIsRGBMode(mode) ? output.u.RGBA.rgba : output.u.YUVA.y;
+}
+
+uint8_t* WebPDecodeRGB(const uint8_t* data, size_t data_size,
+                       int* width, int* height) {
+  return Decode(MODE_RGB, data, data_size, width, height, NULL);
+}
+
+uint8_t* WebPDecodeRGBA(const uint8_t* data, size_t data_size,
+                        int* width, int* height) {
+  return Decode(MODE_RGBA, data, data_size, width, height, NULL);
+}
+
+uint8_t* WebPDecodeARGB(const uint8_t* data, size_t data_size,
+                        int* width, int* height) {
+  return Decode(MODE_ARGB, data, data_size, width, height, NULL);
+}
+
+uint8_t* WebPDecodeBGR(const uint8_t* data, size_t data_size,
+                       int* width, int* height) {
+  return Decode(MODE_BGR, data, data_size, width, height, NULL);
+}
+
+uint8_t* WebPDecodeBGRA(const uint8_t* data, size_t data_size,
+                        int* width, int* height) {
+  return Decode(MODE_BGRA, data, data_size, width, height, NULL);
+}
+
+uint8_t* WebPDecodeYUV(const uint8_t* data, size_t data_size,
+                       int* width, int* height, uint8_t** u, uint8_t** v,
+                       int* stride, int* uv_stride) {
+  WebPDecBuffer output;   // only to preserve the side-infos
+  uint8_t* const out = Decode(MODE_YUV, data, data_size,
+                              width, height, &output);
+
+  if (out != NULL) {
+    const WebPYUVABuffer* const buf = &output.u.YUVA;
+    *u = buf->u;
+    *v = buf->v;
+    *stride = buf->y_stride;
+    *uv_stride = buf->u_stride;
+    assert(buf->u_stride == buf->v_stride);
+  }
+  return out;
+}
+
+static void DefaultFeatures(WebPBitstreamFeatures* const features) {
+  assert(features != NULL);
+  memset(features, 0, sizeof(*features));
+}
+
+static VP8StatusCode GetFeatures(const uint8_t* const data, size_t data_size,
+                                 WebPBitstreamFeatures* const features) {
+  if (features == NULL || data == NULL) {
+    return VP8_STATUS_INVALID_PARAM;
+  }
+  DefaultFeatures(features);
+
+  // Only parse enough of the data to retrieve the features.
+  return ParseHeadersInternal(data, data_size,
+                              &features->width, &features->height,
+                              &features->has_alpha, &features->has_animation,
+                              &features->format, NULL);
+}
+
+//------------------------------------------------------------------------------
+// WebPGetInfo()
+
+int WebPGetInfo(const uint8_t* data, size_t data_size,
+                int* width, int* height) {
+  WebPBitstreamFeatures features;
+
+  if (GetFeatures(data, data_size, &features) != VP8_STATUS_OK) {
+    return 0;
+  }
+
+  if (width != NULL) {
+    *width  = features.width;
+  }
+  if (height != NULL) {
+    *height = features.height;
+  }
+
+  return 1;
+}
+
+//------------------------------------------------------------------------------
+// Advance decoding API
+
+int WebPInitDecoderConfigInternal(WebPDecoderConfig* config,
+                                  int version) {
+  if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_DECODER_ABI_VERSION)) {
+    return 0;   // version mismatch
+  }
+  if (config == NULL) {
+    return 0;
+  }
+  memset(config, 0, sizeof(*config));
+  DefaultFeatures(&config->input);
+  WebPInitDecBuffer(&config->output);
+  return 1;
+}
+
+VP8StatusCode WebPGetFeaturesInternal(const uint8_t* data, size_t data_size,
+                                      WebPBitstreamFeatures* features,
+                                      int version) {
+  if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_DECODER_ABI_VERSION)) {
+    return VP8_STATUS_INVALID_PARAM;   // version mismatch
+  }
+  if (features == NULL) {
+    return VP8_STATUS_INVALID_PARAM;
+  }
+  return GetFeatures(data, data_size, features);
+}
+
+VP8StatusCode WebPDecode(const uint8_t* data, size_t data_size,
+                         WebPDecoderConfig* config) {
+  WebPDecParams params;
+  VP8StatusCode status;
+
+  if (config == NULL) {
+    return VP8_STATUS_INVALID_PARAM;
+  }
+
+  status = GetFeatures(data, data_size, &config->input);
+  if (status != VP8_STATUS_OK) {
+    if (status == VP8_STATUS_NOT_ENOUGH_DATA) {
+      return VP8_STATUS_BITSTREAM_ERROR;  // Not-enough-data treated as error.
+    }
+    return status;
+  }
+
+  WebPResetDecParams(&params);
+  params.output = &config->output;
+  params.options = &config->options;
+  status = DecodeInto(data, data_size, &params);
+
+  return status;
+}
+
+//------------------------------------------------------------------------------
+// Cropping and rescaling.
+
+int WebPIoInitFromOptions(const WebPDecoderOptions* const options,
+                          VP8Io* const io, WEBP_CSP_MODE src_colorspace) {
+  const int W = io->width;
+  const int H = io->height;
+  int x = 0, y = 0, w = W, h = H;
+
+  // Cropping
+  io->use_cropping = (options != NULL) && (options->use_cropping > 0);
+  if (io->use_cropping) {
+    w = options->crop_width;
+    h = options->crop_height;
+    x = options->crop_left;
+    y = options->crop_top;
+    if (!WebPIsRGBMode(src_colorspace)) {   // only snap for YUV420
+      x &= ~1;
+      y &= ~1;
+    }
+    if (x < 0 || y < 0 || w <= 0 || h <= 0 || x + w > W || y + h > H) {
+      return 0;  // out of frame boundary error
+    }
+  }
+  io->crop_left   = x;
+  io->crop_top    = y;
+  io->crop_right  = x + w;
+  io->crop_bottom = y + h;
+  io->mb_w = w;
+  io->mb_h = h;
+
+  // Scaling
+  io->use_scaling = (options != NULL) && (options->use_scaling > 0);
+  if (io->use_scaling) {
+    if (options->scaled_width <= 0 || options->scaled_height <= 0) {
+      return 0;
+    }
+    io->scaled_width = options->scaled_width;
+    io->scaled_height = options->scaled_height;
+  }
+
+  // Filter
+  io->bypass_filtering = options && options->bypass_filtering;
+
+  // Fancy upsampler
+#ifdef FANCY_UPSAMPLING
+  io->fancy_upsampling = (options == NULL) || (!options->no_fancy_upsampling);
+#endif
+
+  if (io->use_scaling) {
+    // disable filter (only for large downscaling ratio).
+    io->bypass_filtering = (io->scaled_width < W * 3 / 4) &&
+                           (io->scaled_height < H * 3 / 4);
+    io->fancy_upsampling = 0;
+  }
+  return 1;
+}
+
+//------------------------------------------------------------------------------
+
diff --git a/Source/LibWebP/src/dec/decode_vp8.h b/Source/LibWebP/src/dec/decode_vp8.h
new file mode 100644
index 0000000..282b0f5
--- /dev/null
+++ b/Source/LibWebP/src/dec/decode_vp8.h
@@ -0,0 +1,185 @@
+// Copyright 2010 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+//  Low-level API for VP8 decoder
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#ifndef WEBP_WEBP_DECODE_VP8_H_
+#define WEBP_WEBP_DECODE_VP8_H_
+
+#include "../webp/decode.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//------------------------------------------------------------------------------
+// Lower-level API
+//
+// These functions provide fine-grained control of the decoding process.
+// The call flow should resemble:
+//
+//   VP8Io io;
+//   VP8InitIo(&io);
+//   io.data = data;
+//   io.data_size = size;
+//   /* customize io's functions (setup()/put()/teardown()) if needed. */
+//
+//   VP8Decoder* dec = VP8New();
+//   bool ok = VP8Decode(dec);
+//   if (!ok) printf("Error: %s\n", VP8StatusMessage(dec));
+//   VP8Delete(dec);
+//   return ok;
+
+// Input / Output
+typedef struct VP8Io VP8Io;
+typedef int (*VP8IoPutHook)(const VP8Io* io);
+typedef int (*VP8IoSetupHook)(VP8Io* io);
+typedef void (*VP8IoTeardownHook)(const VP8Io* io);
+
+struct VP8Io {
+  // set by VP8GetHeaders()
+  int width, height;         // picture dimensions, in pixels (invariable).
+                             // These are the original, uncropped dimensions.
+                             // The actual area passed to put() is stored
+                             // in mb_w / mb_h fields.
+
+  // set before calling put()
+  int mb_y;                  // position of the current rows (in pixels)
+  int mb_w;                  // number of columns in the sample
+  int mb_h;                  // number of rows in the sample
+  const uint8_t* y, *u, *v;  // rows to copy (in yuv420 format)
+  int y_stride;              // row stride for luma
+  int uv_stride;             // row stride for chroma
+
+  void* opaque;              // user data
+
+  // called when fresh samples are available. Currently, samples are in
+  // YUV420 format, and can be up to width x 24 in size (depending on the
+  // in-loop filtering level, e.g.). Should return false in case of error
+  // or abort request. The actual size of the area to update is mb_w x mb_h
+  // in size, taking cropping into account.
+  VP8IoPutHook put;
+
+  // called just before starting to decode the blocks.
+  // Must return false in case of setup error, true otherwise. If false is
+  // returned, teardown() will NOT be called. But if the setup succeeded
+  // and true is returned, then teardown() will always be called afterward.
+  VP8IoSetupHook setup;
+
+  // Called just after block decoding is finished (or when an error occurred
+  // during put()). Is NOT called if setup() failed.
+  VP8IoTeardownHook teardown;
+
+  // this is a recommendation for the user-side yuv->rgb converter. This flag
+  // is set when calling setup() hook and can be overwritten by it. It then
+  // can be taken into consideration during the put() method.
+  int fancy_upsampling;
+
+  // Input buffer.
+  size_t data_size;
+  const uint8_t* data;
+
+  // If true, in-loop filtering will not be performed even if present in the
+  // bitstream. Switching off filtering may speed up decoding at the expense
+  // of more visible blocking. Note that output will also be non-compliant
+  // with the VP8 specifications.
+  int bypass_filtering;
+
+  // Cropping parameters.
+  int use_cropping;
+  int crop_left, crop_right, crop_top, crop_bottom;
+
+  // Scaling parameters.
+  int use_scaling;
+  int scaled_width, scaled_height;
+
+  // If non NULL, pointer to the alpha data (if present) corresponding to the
+  // start of the current row (That is: it is pre-offset by mb_y and takes
+  // cropping into account).
+  const uint8_t* a;
+};
+
+// Internal, version-checked, entry point
+int VP8InitIoInternal(VP8Io* const, int);
+
+// Set the custom IO function pointers and user-data. The setter for IO hooks
+// should be called before initiating incremental decoding. Returns true if
+// WebPIDecoder object is successfully modified, false otherwise.
+int WebPISetIOHooks(WebPIDecoder* const idec,
+                    VP8IoPutHook put,
+                    VP8IoSetupHook setup,
+                    VP8IoTeardownHook teardown,
+                    void* user_data);
+
+// Main decoding object. This is an opaque structure.
+typedef struct VP8Decoder VP8Decoder;
+
+// Create a new decoder object.
+VP8Decoder* VP8New(void);
+
+// Must be called to make sure 'io' is initialized properly.
+// Returns false in case of version mismatch. Upon such failure, no other
+// decoding function should be called (VP8Decode, VP8GetHeaders, ...)
+static WEBP_INLINE int VP8InitIo(VP8Io* const io) {
+  return VP8InitIoInternal(io, WEBP_DECODER_ABI_VERSION);
+}
+
+// Decode the VP8 frame header. Returns true if ok.
+// Note: 'io->data' must be pointing to the start of the VP8 frame header.
+int VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io);
+
+// Decode a picture. Will call VP8GetHeaders() if it wasn't done already.
+// Returns false in case of error.
+int VP8Decode(VP8Decoder* const dec, VP8Io* const io);
+
+// Return current status of the decoder:
+VP8StatusCode VP8Status(VP8Decoder* const dec);
+
+// return readable string corresponding to the last status.
+const char* VP8StatusMessage(VP8Decoder* const dec);
+
+// Resets the decoder in its initial state, reclaiming memory.
+// Not a mandatory call between calls to VP8Decode().
+void VP8Clear(VP8Decoder* const dec);
+
+// Destroy the decoder object.
+void VP8Delete(VP8Decoder* const dec);
+
+//------------------------------------------------------------------------------
+// Miscellaneous VP8/VP8L bitstream probing functions.
+
+// Returns true if the next 3 bytes in data contain the VP8 signature.
+WEBP_EXTERN(int) VP8CheckSignature(const uint8_t* const data, size_t data_size);
+
+// Validates the VP8 data-header and retrieves basic header information viz
+// width and height. Returns 0 in case of formatting error. *width/*height
+// can be passed NULL.
+WEBP_EXTERN(int) VP8GetInfo(
+    const uint8_t* data,
+    size_t data_size,    // data available so far
+    size_t chunk_size,   // total data size expected in the chunk
+    int* const width, int* const height);
+
+// Returns true if the next byte(s) in data is a VP8L signature.
+WEBP_EXTERN(int) VP8LCheckSignature(const uint8_t* const data, size_t size);
+
+// Validates the VP8L data-header and retrieves basic header information viz
+// width, height and alpha. Returns 0 in case of formatting error.
+// width/height/has_alpha can be passed NULL.
+WEBP_EXTERN(int) VP8LGetInfo(
+    const uint8_t* data, size_t data_size,  // data available so far
+    int* const width, int* const height, int* const has_alpha);
+
+#ifdef __cplusplus
+}    // extern "C"
+#endif
+
+#endif  /* WEBP_WEBP_DECODE_VP8_H_ */
diff --git a/Source/LibWebP/src/dec/vp8i.h b/Source/LibWebP/src/dec/vp8i.h
new file mode 100644
index 0000000..6280aea
--- /dev/null
+++ b/Source/LibWebP/src/dec/vp8i.h
@@ -0,0 +1,353 @@
+// Copyright 2010 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// VP8 decoder: internal header.
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#ifndef WEBP_DEC_VP8I_H_
+#define WEBP_DEC_VP8I_H_
+
+#include <string.h>     // for memcpy()
+#include "./vp8li.h"
+#include "../utils/bit_reader.h"
+#include "../utils/random.h"
+#include "../utils/thread.h"
+#include "../dsp/dsp.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//------------------------------------------------------------------------------
+// Various defines and enums
+
+// version numbers
+#define DEC_MAJ_VERSION 0
+#define DEC_MIN_VERSION 4
+#define DEC_REV_VERSION 2
+
+// intra prediction modes
+enum { B_DC_PRED = 0,   // 4x4 modes
+       B_TM_PRED,
+       B_VE_PRED,
+       B_HE_PRED,
+       B_RD_PRED,
+       B_VR_PRED,
+       B_LD_PRED,
+       B_VL_PRED,
+       B_HD_PRED,
+       B_HU_PRED,
+       NUM_BMODES = B_HU_PRED + 1 - B_DC_PRED,  // = 10
+
+       // Luma16 or UV modes
+       DC_PRED = B_DC_PRED, V_PRED = B_VE_PRED,
+       H_PRED = B_HE_PRED, TM_PRED = B_TM_PRED,
+       B_PRED = NUM_BMODES,   // refined I4x4 mode
+
+       // special modes
+       B_DC_PRED_NOTOP = 4,
+       B_DC_PRED_NOLEFT = 5,
+       B_DC_PRED_NOTOPLEFT = 6,
+       NUM_B_DC_MODES = 7 };
+
+enum { MB_FEATURE_TREE_PROBS = 3,
+       NUM_MB_SEGMENTS = 4,
+       NUM_REF_LF_DELTAS = 4,
+       NUM_MODE_LF_DELTAS = 4,    // I4x4, ZERO, *, SPLIT
+       MAX_NUM_PARTITIONS = 8,
+       // Probabilities
+       NUM_TYPES = 4,
+       NUM_BANDS = 8,
+       NUM_CTX = 3,
+       NUM_PROBAS = 11,
+       NUM_MV_PROBAS = 19 };
+
+// YUV-cache parameters. Cache is 32-bytes wide (= one cacheline).
+// Constraints are: We need to store one 16x16 block of luma samples (y),
+// and two 8x8 chroma blocks (u/v). These are better be 16-bytes aligned,
+// in order to be SIMD-friendly. We also need to store the top, left and
+// top-left samples (from previously decoded blocks), along with four
+// extra top-right samples for luma (intra4x4 prediction only).
+// One possible layout is, using 32 * (17 + 9) bytes:
+//
+//   .+------   <- only 1 pixel high
+//   .|yyyyt.
+//   .|yyyyt.
+//   .|yyyyt.
+//   .|yyyy..
+//   .+--.+--   <- only 1 pixel high
+//   .|uu.|vv
+//   .|uu.|vv
+//
+// Every character is a 4x4 block, with legend:
+//  '.' = unused
+//  'y' = y-samples   'u' = u-samples     'v' = u-samples
+//  '|' = left sample,   '-' = top sample,    '+' = top-left sample
+//  't' = extra top-right sample for 4x4 modes
+#define YUV_SIZE (BPS * 17 + BPS * 9)
+#define Y_SIZE   (BPS * 17)
+#define Y_OFF    (BPS * 1 + 8)
+#define U_OFF    (Y_OFF + BPS * 16 + BPS)
+#define V_OFF    (U_OFF + 16)
+
+// minimal width under which lossy multi-threading is always disabled
+#define MIN_WIDTH_FOR_THREADS 512
+
+//------------------------------------------------------------------------------
+// Headers
+
+typedef struct {
+  uint8_t key_frame_;
+  uint8_t profile_;
+  uint8_t show_;
+  uint32_t partition_length_;
+} VP8FrameHeader;
+
+typedef struct {
+  uint16_t width_;
+  uint16_t height_;
+  uint8_t xscale_;
+  uint8_t yscale_;
+  uint8_t colorspace_;   // 0 = YCbCr
+  uint8_t clamp_type_;
+} VP8PictureHeader;
+
+// segment features
+typedef struct {
+  int use_segment_;
+  int update_map_;        // whether to update the segment map or not
+  int absolute_delta_;    // absolute or delta values for quantizer and filter
+  int8_t quantizer_[NUM_MB_SEGMENTS];        // quantization changes
+  int8_t filter_strength_[NUM_MB_SEGMENTS];  // filter strength for segments
+} VP8SegmentHeader;
+
+
+// probas associated to one of the contexts
+typedef uint8_t VP8ProbaArray[NUM_PROBAS];
+
+typedef struct {   // all the probas associated to one band
+  VP8ProbaArray probas_[NUM_CTX];
+} VP8BandProbas;
+
+// Struct collecting all frame-persistent probabilities.
+typedef struct {
+  uint8_t segments_[MB_FEATURE_TREE_PROBS];
+  // Type: 0:Intra16-AC  1:Intra16-DC   2:Chroma   3:Intra4
+  VP8BandProbas bands_[NUM_TYPES][NUM_BANDS];
+  const VP8BandProbas* bands_ptr_[NUM_TYPES][16 + 1];
+} VP8Proba;
+
+// Filter parameters
+typedef struct {
+  int simple_;                  // 0=complex, 1=simple
+  int level_;                   // [0..63]
+  int sharpness_;               // [0..7]
+  int use_lf_delta_;
+  int ref_lf_delta_[NUM_REF_LF_DELTAS];
+  int mode_lf_delta_[NUM_MODE_LF_DELTAS];
+} VP8FilterHeader;
+
+//------------------------------------------------------------------------------
+// Informations about the macroblocks.
+
+typedef struct {  // filter specs
+  uint8_t f_limit_;      // filter limit in [3..189], or 0 if no filtering
+  uint8_t f_ilevel_;     // inner limit in [1..63]
+  uint8_t f_inner_;      // do inner filtering?
+  uint8_t hev_thresh_;   // high edge variance threshold in [0..2]
+} VP8FInfo;
+
+typedef struct {  // Top/Left Contexts used for syntax-parsing
+  uint8_t nz_;        // non-zero AC/DC coeffs (4bit for luma + 4bit for chroma)
+  uint8_t nz_dc_;     // non-zero DC coeff (1bit)
+} VP8MB;
+
+// Dequantization matrices
+typedef int quant_t[2];      // [DC / AC].  Can be 'uint16_t[2]' too (~slower).
+typedef struct {
+  quant_t y1_mat_, y2_mat_, uv_mat_;
+
+  int uv_quant_;   // U/V quantizer value
+  int dither_;     // dithering amplitude (0 = off, max=255)
+} VP8QuantMatrix;
+
+// Data needed to reconstruct a macroblock
+typedef struct {
+  int16_t coeffs_[384];   // 384 coeffs = (16+4+4) * 4*4
+  uint8_t is_i4x4_;       // true if intra4x4
+  uint8_t imodes_[16];    // one 16x16 mode (#0) or sixteen 4x4 modes
+  uint8_t uvmode_;        // chroma prediction mode
+  // bit-wise info about the content of each sub-4x4 blocks (in decoding order).
+  // Each of the 4x4 blocks for y/u/v is associated with a 2b code according to:
+  //   code=0 -> no coefficient
+  //   code=1 -> only DC
+  //   code=2 -> first three coefficients are non-zero
+  //   code=3 -> more than three coefficients are non-zero
+  // This allows to call specialized transform functions.
+  uint32_t non_zero_y_;
+  uint32_t non_zero_uv_;
+  uint8_t dither_;      // local dithering strength (deduced from non_zero_*)
+  uint8_t skip_;
+  uint8_t segment_;
+} VP8MBData;
+
+// Persistent information needed by the parallel processing
+typedef struct {
+  int id_;              // cache row to process (in [0..2])
+  int mb_y_;            // macroblock position of the row
+  int filter_row_;      // true if row-filtering is needed
+  VP8FInfo* f_info_;    // filter strengths (swapped with dec->f_info_)
+  VP8MBData* mb_data_;  // reconstruction data (swapped with dec->mb_data_)
+  VP8Io io_;            // copy of the VP8Io to pass to put()
+} VP8ThreadContext;
+
+// Saved top samples, per macroblock. Fits into a cache-line.
+typedef struct {
+  uint8_t y[16], u[8], v[8];
+} VP8TopSamples;
+
+//------------------------------------------------------------------------------
+// VP8Decoder: the main opaque structure handed over to user
+
+struct VP8Decoder {
+  VP8StatusCode status_;
+  int ready_;     // true if ready to decode a picture with VP8Decode()
+  const char* error_msg_;  // set when status_ is not OK.
+
+  // Main data source
+  VP8BitReader br_;
+
+  // headers
+  VP8FrameHeader   frm_hdr_;
+  VP8PictureHeader pic_hdr_;
+  VP8FilterHeader  filter_hdr_;
+  VP8SegmentHeader segment_hdr_;
+
+  // Worker
+  WebPWorker worker_;
+  int mt_method_;      // multi-thread method: 0=off, 1=[parse+recon][filter]
+                       // 2=[parse][recon+filter]
+  int cache_id_;       // current cache row
+  int num_caches_;     // number of cached rows of 16 pixels (1, 2 or 3)
+  VP8ThreadContext thread_ctx_;  // Thread context
+
+  // dimension, in macroblock units.
+  int mb_w_, mb_h_;
+
+  // Macroblock to process/filter, depending on cropping and filter_type.
+  int tl_mb_x_, tl_mb_y_;  // top-left MB that must be in-loop filtered
+  int br_mb_x_, br_mb_y_;  // last bottom-right MB that must be decoded
+
+  // number of partitions.
+  int num_parts_;
+  // per-partition boolean decoders.
+  VP8BitReader parts_[MAX_NUM_PARTITIONS];
+
+  // Dithering strength, deduced from decoding options
+  int dither_;                // whether to use dithering or not
+  VP8Random dithering_rg_;    // random generator for dithering
+
+  // dequantization (one set of DC/AC dequant factor per segment)
+  VP8QuantMatrix dqm_[NUM_MB_SEGMENTS];
+
+  // probabilities
+  VP8Proba proba_;
+  int use_skip_proba_;
+  uint8_t skip_p_;
+
+  // Boundary data cache and persistent buffers.
+  uint8_t* intra_t_;      // top intra modes values: 4 * mb_w_
+  uint8_t  intra_l_[4];   // left intra modes values
+
+  VP8TopSamples* yuv_t_;  // top y/u/v samples
+
+  VP8MB* mb_info_;        // contextual macroblock info (mb_w_ + 1)
+  VP8FInfo* f_info_;      // filter strength info
+  uint8_t* yuv_b_;        // main block for Y/U/V (size = YUV_SIZE)
+
+  uint8_t* cache_y_;      // macroblock row for storing unfiltered samples
+  uint8_t* cache_u_;
+  uint8_t* cache_v_;
+  int cache_y_stride_;
+  int cache_uv_stride_;
+
+  // main memory chunk for the above data. Persistent.
+  void* mem_;
+  size_t mem_size_;
+
+  // Per macroblock non-persistent infos.
+  int mb_x_, mb_y_;       // current position, in macroblock units
+  VP8MBData* mb_data_;    // parsed reconstruction data
+
+  // Filtering side-info
+  int filter_type_;                          // 0=off, 1=simple, 2=complex
+  VP8FInfo fstrengths_[NUM_MB_SEGMENTS][2];  // precalculated per-segment/type
+
+  // Alpha
+  struct ALPHDecoder* alph_dec_;  // alpha-plane decoder object
+  const uint8_t* alpha_data_;     // compressed alpha data (if present)
+  size_t alpha_data_size_;
+  int is_alpha_decoded_;  // true if alpha_data_ is decoded in alpha_plane_
+  uint8_t* alpha_plane_;  // output. Persistent, contains the whole data.
+  int alpha_dithering_;   // derived from decoding options (0=off, 100=full).
+};
+
+//------------------------------------------------------------------------------
+// internal functions. Not public.
+
+// in vp8.c
+int VP8SetError(VP8Decoder* const dec,
+                VP8StatusCode error, const char* const msg);
+
+// in tree.c
+void VP8ResetProba(VP8Proba* const proba);
+void VP8ParseProba(VP8BitReader* const br, VP8Decoder* const dec);
+// parses one row of intra mode data in partition 0, returns !eof
+int VP8ParseIntraModeRow(VP8BitReader* const br, VP8Decoder* const dec);
+
+// in quant.c
+void VP8ParseQuant(VP8Decoder* const dec);
+
+// in frame.c
+int VP8InitFrame(VP8Decoder* const dec, VP8Io* io);
+// Call io->setup() and finish setting up scan parameters.
+// After this call returns, one must always call VP8ExitCritical() with the
+// same parameters. Both functions should be used in pair. Returns VP8_STATUS_OK
+// if ok, otherwise sets and returns the error status on *dec.
+VP8StatusCode VP8EnterCritical(VP8Decoder* const dec, VP8Io* const io);
+// Must always be called in pair with VP8EnterCritical().
+// Returns false in case of error.
+int VP8ExitCritical(VP8Decoder* const dec, VP8Io* const io);
+// Return the multi-threading method to use (0=off), depending
+// on options and bitstream size. Only for lossy decoding.
+int VP8GetThreadMethod(const WebPDecoderOptions* const options,
+                       const WebPHeaderStructure* const headers,
+                       int width, int height);
+// Initialize dithering post-process if needed.
+void VP8InitDithering(const WebPDecoderOptions* const options,
+                      VP8Decoder* const dec);
+// Process the last decoded row (filtering + output).
+int VP8ProcessRow(VP8Decoder* const dec, VP8Io* const io);
+// To be called at the start of a new scanline, to initialize predictors.
+void VP8InitScanline(VP8Decoder* const dec);
+// Decode one macroblock. Returns false if there is not enough data.
+int VP8DecodeMB(VP8Decoder* const dec, VP8BitReader* const token_br);
+
+// in alpha.c
+const uint8_t* VP8DecompressAlphaRows(VP8Decoder* const dec,
+                                      int row, int num_rows);
+
+//------------------------------------------------------------------------------
+
+#ifdef __cplusplus
+}    // extern "C"
+#endif
+
+#endif  /* WEBP_DEC_VP8I_H_ */
diff --git a/Source/LibWebP/src/dec/vp8li.h b/Source/LibWebP/src/dec/vp8li.h
new file mode 100644
index 0000000..5ccb002
--- /dev/null
+++ b/Source/LibWebP/src/dec/vp8li.h
@@ -0,0 +1,136 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Lossless decoder: internal header.
+//
+// Author: Skal (pascal.massimino at gmail.com)
+//         Vikas Arora(vikaas.arora at gmail.com)
+
+#ifndef WEBP_DEC_VP8LI_H_
+#define WEBP_DEC_VP8LI_H_
+
+#include <string.h>     // for memcpy()
+#include "./webpi.h"
+#include "../utils/bit_reader.h"
+#include "../utils/color_cache.h"
+#include "../utils/huffman.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+  READ_DATA = 0,
+  READ_HDR = 1,
+  READ_DIM = 2
+} VP8LDecodeState;
+
+typedef struct VP8LTransform VP8LTransform;
+struct VP8LTransform {
+  VP8LImageTransformType type_;   // transform type.
+  int                    bits_;   // subsampling bits defining transform window.
+  int                    xsize_;  // transform window X index.
+  int                    ysize_;  // transform window Y index.
+  uint32_t              *data_;   // transform data.
+};
+
+typedef struct {
+  int             color_cache_size_;
+  VP8LColorCache  color_cache_;
+  VP8LColorCache  saved_color_cache_;  // for incremental
+
+  int             huffman_mask_;
+  int             huffman_subsample_bits_;
+  int             huffman_xsize_;
+  uint32_t       *huffman_image_;
+  int             num_htree_groups_;
+  HTreeGroup     *htree_groups_;
+  HuffmanCode    *huffman_tables_;
+} VP8LMetadata;
+
+typedef struct VP8LDecoder VP8LDecoder;
+struct VP8LDecoder {
+  VP8StatusCode    status_;
+  VP8LDecodeState  state_;
+  VP8Io           *io_;
+
+  const WebPDecBuffer *output_;    // shortcut to io->opaque->output
+
+  uint32_t        *pixels_;        // Internal data: either uint8_t* for alpha
+                                   // or uint32_t* for BGRA.
+  uint32_t        *argb_cache_;    // Scratch buffer for temporary BGRA storage.
+
+  VP8LBitReader    br_;
+  int              incremental_;   // if true, incremental decoding is expected
+  VP8LBitReader    saved_br_;      // note: could be local variables too
+  int              saved_last_pixel_;
+
+  int              width_;
+  int              height_;
+  int              last_row_;      // last input row decoded so far.
+  int              last_pixel_;    // last pixel decoded so far. However, it may
+                                   // not be transformed, scaled and
+                                   // color-converted yet.
+  int              last_out_row_;  // last row output so far.
+
+  VP8LMetadata     hdr_;
+
+  int              next_transform_;
+  VP8LTransform    transforms_[NUM_TRANSFORMS];
+  // or'd bitset storing the transforms types.
+  uint32_t         transforms_seen_;
+
+  uint8_t         *rescaler_memory;  // Working memory for rescaling work.
+  WebPRescaler    *rescaler;         // Common rescaler for all channels.
+};
+
+//------------------------------------------------------------------------------
+// internal functions. Not public.
+
+struct ALPHDecoder;  // Defined in dec/alphai.h.
+
+// in vp8l.c
+
+// Decodes image header for alpha data stored using lossless compression.
+// Returns false in case of error.
+int VP8LDecodeAlphaHeader(struct ALPHDecoder* const alph_dec,
+                          const uint8_t* const data, size_t data_size,
+                          uint8_t* const output);
+
+// Decodes *at least* 'last_row' rows of alpha. If some of the initial rows are
+// already decoded in previous call(s), it will resume decoding from where it
+// was paused.
+// Returns false in case of bitstream error.
+int VP8LDecodeAlphaImageStream(struct ALPHDecoder* const alph_dec,
+                               int last_row);
+
+// Allocates and initialize a new lossless decoder instance.
+VP8LDecoder* VP8LNew(void);
+
+// Decodes the image header. Returns false in case of error.
+int VP8LDecodeHeader(VP8LDecoder* const dec, VP8Io* const io);
+
+// Decodes an image. It's required to decode the lossless header before calling
+// this function. Returns false in case of error, with updated dec->status_.
+int VP8LDecodeImage(VP8LDecoder* const dec);
+
+// Resets the decoder in its initial state, reclaiming memory.
+// Preserves the dec->status_ value.
+void VP8LClear(VP8LDecoder* const dec);
+
+// Clears and deallocate a lossless decoder instance.
+void VP8LDelete(VP8LDecoder* const dec);
+
+//------------------------------------------------------------------------------
+
+#ifdef __cplusplus
+}    // extern "C"
+#endif
+
+#endif  /* WEBP_DEC_VP8LI_H_ */
diff --git a/Source/LibWebP/src/dec/webpi.h b/Source/LibWebP/src/dec/webpi.h
new file mode 100644
index 0000000..aeb66a2
--- /dev/null
+++ b/Source/LibWebP/src/dec/webpi.h
@@ -0,0 +1,120 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Internal header: WebP decoding parameters and custom IO on buffer
+//
+// Author: somnath at google.com (Somnath Banerjee)
+
+#ifndef WEBP_DEC_WEBPI_H_
+#define WEBP_DEC_WEBPI_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "../utils/rescaler.h"
+#include "./decode_vp8.h"
+
+//------------------------------------------------------------------------------
+// WebPDecParams: Decoding output parameters. Transient internal object.
+
+typedef struct WebPDecParams WebPDecParams;
+typedef int (*OutputFunc)(const VP8Io* const io, WebPDecParams* const p);
+typedef int (*OutputRowFunc)(WebPDecParams* const p, int y_pos);
+
+struct WebPDecParams {
+  WebPDecBuffer* output;             // output buffer.
+  uint8_t* tmp_y, *tmp_u, *tmp_v;    // cache for the fancy upsampler
+                                     // or used for tmp rescaling
+
+  int last_y;                 // coordinate of the line that was last output
+  const WebPDecoderOptions* options;  // if not NULL, use alt decoding features
+  // rescalers
+  WebPRescaler scaler_y, scaler_u, scaler_v, scaler_a;
+  void* memory;                  // overall scratch memory for the output work.
+
+  OutputFunc emit;               // output RGB or YUV samples
+  OutputFunc emit_alpha;         // output alpha channel
+  OutputRowFunc emit_alpha_row;  // output one line of rescaled alpha values
+};
+
+// Should be called first, before any use of the WebPDecParams object.
+void WebPResetDecParams(WebPDecParams* const params);
+
+//------------------------------------------------------------------------------
+// Header parsing helpers
+
+// Structure storing a description of the RIFF headers.
+typedef struct {
+  const uint8_t* data;         // input buffer
+  size_t data_size;            // input buffer size
+  int have_all_data;           // true if all data is known to be available
+  size_t offset;               // offset to main data chunk (VP8 or VP8L)
+  const uint8_t* alpha_data;   // points to alpha chunk (if present)
+  size_t alpha_data_size;      // alpha chunk size
+  size_t compressed_size;      // VP8/VP8L compressed data size
+  size_t riff_size;            // size of the riff payload (or 0 if absent)
+  int is_lossless;             // true if a VP8L chunk is present
+} WebPHeaderStructure;
+
+// Skips over all valid chunks prior to the first VP8/VP8L frame header.
+// Returns: VP8_STATUS_OK, VP8_STATUS_BITSTREAM_ERROR (invalid header/chunk),
+// VP8_STATUS_NOT_ENOUGH_DATA (partial input) or VP8_STATUS_UNSUPPORTED_FEATURE
+// in the case of non-decodable features (animation for instance).
+// In 'headers', compressed_size, offset, alpha_data, alpha_size, and lossless
+// fields are updated appropriately upon success.
+VP8StatusCode WebPParseHeaders(WebPHeaderStructure* const headers);
+
+//------------------------------------------------------------------------------
+// Misc utils
+
+// Initializes VP8Io with custom setup, io and teardown functions. The default
+// hooks will use the supplied 'params' as io->opaque handle.
+void WebPInitCustomIo(WebPDecParams* const params, VP8Io* const io);
+
+// Setup crop_xxx fields, mb_w and mb_h in io. 'src_colorspace' refers
+// to the *compressed* format, not the output one.
+int WebPIoInitFromOptions(const WebPDecoderOptions* const options,
+                          VP8Io* const io, WEBP_CSP_MODE src_colorspace);
+
+//------------------------------------------------------------------------------
+// Internal functions regarding WebPDecBuffer memory (in buffer.c).
+// Don't really need to be externally visible for now.
+
+// Prepare 'buffer' with the requested initial dimensions width/height.
+// If no external storage is supplied, initializes buffer by allocating output
+// memory and setting up the stride information. Validate the parameters. Return
+// an error code in case of problem (no memory, or invalid stride / size /
+// dimension / etc.). If *options is not NULL, also verify that the options'
+// parameters are valid and apply them to the width/height dimensions of the
+// output buffer. This takes cropping / scaling / rotation into account.
+// Also incorporates the options->flip flag to flip the buffer parameters if
+// needed.
+VP8StatusCode WebPAllocateDecBuffer(int width, int height,
+                                    const WebPDecoderOptions* const options,
+                                    WebPDecBuffer* const buffer);
+
+// Flip buffer vertically by negating the various strides.
+VP8StatusCode WebPFlipBuffer(WebPDecBuffer* const buffer);
+
+// Copy 'src' into 'dst' buffer, making sure 'dst' is not marked as owner of the
+// memory (still held by 'src').
+void WebPCopyDecBuffer(const WebPDecBuffer* const src,
+                       WebPDecBuffer* const dst);
+
+// Copy and transfer ownership from src to dst (beware of parameter order!)
+void WebPGrabDecBuffer(WebPDecBuffer* const src, WebPDecBuffer* const dst);
+
+//------------------------------------------------------------------------------
+
+#ifdef __cplusplus
+}    // extern "C"
+#endif
+
+#endif  /* WEBP_DEC_WEBPI_H_ */
diff --git a/Source/LibWebP/src/demux/demux.demux.c b/Source/LibWebP/src/demux/demux.demux.c
new file mode 100644
index 0000000..49b5565
--- /dev/null
+++ b/Source/LibWebP/src/demux/demux.demux.c
@@ -0,0 +1,957 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+//  WebP container demux.
+//
+
+#ifdef HAVE_CONFIG_H
+#include "../webp/config.h"
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../utils/utils.h"
+#include "../webp/decode.h"     // WebPGetFeatures
+#include "../webp/demux.h"
+#include "../webp/format_constants.h"
+
+#define DMUX_MAJ_VERSION 0
+#define DMUX_MIN_VERSION 2
+#define DMUX_REV_VERSION 2
+
+typedef struct {
+  size_t start_;        // start location of the data
+  size_t end_;          // end location
+  size_t riff_end_;     // riff chunk end location, can be > end_.
+  size_t buf_size_;     // size of the buffer
+  const uint8_t* buf_;
+} MemBuffer;
+
+typedef struct {
+  size_t offset_;
+  size_t size_;
+} ChunkData;
+
+typedef struct Frame {
+  int x_offset_, y_offset_;
+  int width_, height_;
+  int has_alpha_;
+  int duration_;
+  WebPMuxAnimDispose dispose_method_;
+  WebPMuxAnimBlend blend_method_;
+  int is_fragment_;  // this is a frame fragment (and not a full frame).
+  int frame_num_;  // the referent frame number for use in assembling fragments.
+  int complete_;   // img_components_ contains a full image.
+  ChunkData img_components_[2];  // 0=VP8{,L} 1=ALPH
+  struct Frame* next_;
+} Frame;
+
+typedef struct Chunk {
+  ChunkData data_;
+  struct Chunk* next_;
+} Chunk;
+
+struct WebPDemuxer {
+  MemBuffer mem_;
+  WebPDemuxState state_;
+  int is_ext_format_;
+  uint32_t feature_flags_;
+  int canvas_width_, canvas_height_;
+  int loop_count_;
+  uint32_t bgcolor_;
+  int num_frames_;
+  Frame* frames_;
+  Frame** frames_tail_;
+  Chunk* chunks_;  // non-image chunks
+  Chunk** chunks_tail_;
+};
+
+typedef enum {
+  PARSE_OK,
+  PARSE_NEED_MORE_DATA,
+  PARSE_ERROR
+} ParseStatus;
+
+typedef struct ChunkParser {
+  uint8_t id[4];
+  ParseStatus (*parse)(WebPDemuxer* const dmux);
+  int (*valid)(const WebPDemuxer* const dmux);
+} ChunkParser;
+
+static ParseStatus ParseSingleImage(WebPDemuxer* const dmux);
+static ParseStatus ParseVP8X(WebPDemuxer* const dmux);
+static int IsValidSimpleFormat(const WebPDemuxer* const dmux);
+static int IsValidExtendedFormat(const WebPDemuxer* const dmux);
+
+static const ChunkParser kMasterChunks[] = {
+  { { 'V', 'P', '8', ' ' }, ParseSingleImage, IsValidSimpleFormat },
+  { { 'V', 'P', '8', 'L' }, ParseSingleImage, IsValidSimpleFormat },
+  { { 'V', 'P', '8', 'X' }, ParseVP8X,        IsValidExtendedFormat },
+  { { '0', '0', '0', '0' }, NULL,             NULL },
+};
+
+//------------------------------------------------------------------------------
+
+int WebPGetDemuxVersion(void) {
+  return (DMUX_MAJ_VERSION << 16) | (DMUX_MIN_VERSION << 8) | DMUX_REV_VERSION;
+}
+
+// -----------------------------------------------------------------------------
+// MemBuffer
+
+static int RemapMemBuffer(MemBuffer* const mem,
+                          const uint8_t* data, size_t size) {
+  if (size < mem->buf_size_) return 0;  // can't remap to a shorter buffer!
+
+  mem->buf_ = data;
+  mem->end_ = mem->buf_size_ = size;
+  return 1;
+}
+
+static int InitMemBuffer(MemBuffer* const mem,
+                         const uint8_t* data, size_t size) {
+  memset(mem, 0, sizeof(*mem));
+  return RemapMemBuffer(mem, data, size);
+}
+
+// Return the remaining data size available in 'mem'.
+static WEBP_INLINE size_t MemDataSize(const MemBuffer* const mem) {
+  return (mem->end_ - mem->start_);
+}
+
+// Return true if 'size' exceeds the end of the RIFF chunk.
+static WEBP_INLINE int SizeIsInvalid(const MemBuffer* const mem, size_t size) {
+  return (size > mem->riff_end_ - mem->start_);
+}
+
+static WEBP_INLINE void Skip(MemBuffer* const mem, size_t size) {
+  mem->start_ += size;
+}
+
+static WEBP_INLINE void Rewind(MemBuffer* const mem, size_t size) {
+  mem->start_ -= size;
+}
+
+static WEBP_INLINE const uint8_t* GetBuffer(MemBuffer* const mem) {
+  return mem->buf_ + mem->start_;
+}
+
+// Read from 'mem' and skip the read bytes.
+static WEBP_INLINE uint8_t ReadByte(MemBuffer* const mem) {
+  const uint8_t byte = mem->buf_[mem->start_];
+  Skip(mem, 1);
+  return byte;
+}
+
+static WEBP_INLINE int ReadLE16s(MemBuffer* const mem) {
+  const uint8_t* const data = mem->buf_ + mem->start_;
+  const int val = GetLE16(data);
+  Skip(mem, 2);
+  return val;
+}
+
+static WEBP_INLINE int ReadLE24s(MemBuffer* const mem) {
+  const uint8_t* const data = mem->buf_ + mem->start_;
+  const int val = GetLE24(data);
+  Skip(mem, 3);
+  return val;
+}
+
+static WEBP_INLINE uint32_t ReadLE32(MemBuffer* const mem) {
+  const uint8_t* const data = mem->buf_ + mem->start_;
+  const uint32_t val = GetLE32(data);
+  Skip(mem, 4);
+  return val;
+}
+
+// -----------------------------------------------------------------------------
+// Secondary chunk parsing
+
+static void AddChunk(WebPDemuxer* const dmux, Chunk* const chunk) {
+  *dmux->chunks_tail_ = chunk;
+  chunk->next_ = NULL;
+  dmux->chunks_tail_ = &chunk->next_;
+}
+
+// Add a frame to the end of the list, ensuring the last frame is complete.
+// Returns true on success, false otherwise.
+static int AddFrame(WebPDemuxer* const dmux, Frame* const frame) {
+  const Frame* const last_frame = *dmux->frames_tail_;
+  if (last_frame != NULL && !last_frame->complete_) return 0;
+
+  *dmux->frames_tail_ = frame;
+  frame->next_ = NULL;
+  dmux->frames_tail_ = &frame->next_;
+  return 1;
+}
+
+// Store image bearing chunks to 'frame'.
+static ParseStatus StoreFrame(int frame_num, uint32_t min_size,
+                              MemBuffer* const mem, Frame* const frame) {
+  int alpha_chunks = 0;
+  int image_chunks = 0;
+  int done = (MemDataSize(mem) < min_size);
+  ParseStatus status = PARSE_OK;
+
+  if (done) return PARSE_NEED_MORE_DATA;
+
+  do {
+    const size_t chunk_start_offset = mem->start_;
+    const uint32_t fourcc = ReadLE32(mem);
+    const uint32_t payload_size = ReadLE32(mem);
+    const uint32_t payload_size_padded = payload_size + (payload_size & 1);
+    const size_t payload_available = (payload_size_padded > MemDataSize(mem))
+                                   ? MemDataSize(mem) : payload_size_padded;
+    const size_t chunk_size = CHUNK_HEADER_SIZE + payload_available;
+
+    if (payload_size > MAX_CHUNK_PAYLOAD) return PARSE_ERROR;
+    if (SizeIsInvalid(mem, payload_size_padded)) return PARSE_ERROR;
+    if (payload_size_padded > MemDataSize(mem)) status = PARSE_NEED_MORE_DATA;
+
+    switch (fourcc) {
+      case MKFOURCC('A', 'L', 'P', 'H'):
+        if (alpha_chunks == 0) {
+          ++alpha_chunks;
+          frame->img_components_[1].offset_ = chunk_start_offset;
+          frame->img_components_[1].size_ = chunk_size;
+          frame->has_alpha_ = 1;
+          frame->frame_num_ = frame_num;
+          Skip(mem, payload_available);
+        } else {
+          goto Done;
+        }
+        break;
+      case MKFOURCC('V', 'P', '8', 'L'):
+        if (alpha_chunks > 0) return PARSE_ERROR;  // VP8L has its own alpha
+        // fall through
+      case MKFOURCC('V', 'P', '8', ' '):
+        if (image_chunks == 0) {
+          // Extract the bitstream features, tolerating failures when the data
+          // is incomplete.
+          WebPBitstreamFeatures features;
+          const VP8StatusCode vp8_status =
+              WebPGetFeatures(mem->buf_ + chunk_start_offset, chunk_size,
+                              &features);
+          if (status == PARSE_NEED_MORE_DATA &&
+              vp8_status == VP8_STATUS_NOT_ENOUGH_DATA) {
+            return PARSE_NEED_MORE_DATA;
+          } else if (vp8_status != VP8_STATUS_OK) {
+            // We have enough data, and yet WebPGetFeatures() failed.
+            return PARSE_ERROR;
+          }
+          ++image_chunks;
+          frame->img_components_[0].offset_ = chunk_start_offset;
+          frame->img_components_[0].size_ = chunk_size;
+          frame->width_ = features.width;
+          frame->height_ = features.height;
+          frame->has_alpha_ |= features.has_alpha;
+          frame->frame_num_ = frame_num;
+          frame->complete_ = (status == PARSE_OK);
+          Skip(mem, payload_available);
+        } else {
+          goto Done;
+        }
+        break;
+ Done:
+      default:
+        // Restore fourcc/size when moving up one level in parsing.
+        Rewind(mem, CHUNK_HEADER_SIZE);
+        done = 1;
+        break;
+    }
+
+    if (mem->start_ == mem->riff_end_) {
+      done = 1;
+    } else if (MemDataSize(mem) < CHUNK_HEADER_SIZE) {
+      status = PARSE_NEED_MORE_DATA;
+    }
+  } while (!done && status == PARSE_OK);
+
+  return status;
+}
+
+// Creates a new Frame if 'actual_size' is within bounds and 'mem' contains
+// enough data ('min_size') to parse the payload.
+// Returns PARSE_OK on success with *frame pointing to the new Frame.
+// Returns PARSE_NEED_MORE_DATA with insufficient data, PARSE_ERROR otherwise.
+static ParseStatus NewFrame(const MemBuffer* const mem,
+                            uint32_t min_size, uint32_t actual_size,
+                            Frame** frame) {
+  if (SizeIsInvalid(mem, min_size)) return PARSE_ERROR;
+  if (actual_size < min_size) return PARSE_ERROR;
+  if (MemDataSize(mem) < min_size)  return PARSE_NEED_MORE_DATA;
+
+  *frame = (Frame*)WebPSafeCalloc(1ULL, sizeof(**frame));
+  return (*frame == NULL) ? PARSE_ERROR : PARSE_OK;
+}
+
+// Parse a 'ANMF' chunk and any image bearing chunks that immediately follow.
+// 'frame_chunk_size' is the previously validated, padded chunk size.
+static ParseStatus ParseAnimationFrame(
+    WebPDemuxer* const dmux, uint32_t frame_chunk_size) {
+  const int is_animation = !!(dmux->feature_flags_ & ANIMATION_FLAG);
+  const uint32_t anmf_payload_size = frame_chunk_size - ANMF_CHUNK_SIZE;
+  int added_frame = 0;
+  int bits;
+  MemBuffer* const mem = &dmux->mem_;
+  Frame* frame;
+  ParseStatus status =
+      NewFrame(mem, ANMF_CHUNK_SIZE, frame_chunk_size, &frame);
+  if (status != PARSE_OK) return status;
+
+  frame->x_offset_       = 2 * ReadLE24s(mem);
+  frame->y_offset_       = 2 * ReadLE24s(mem);
+  frame->width_          = 1 + ReadLE24s(mem);
+  frame->height_         = 1 + ReadLE24s(mem);
+  frame->duration_       = ReadLE24s(mem);
+  bits = ReadByte(mem);
+  frame->dispose_method_ =
+      (bits & 1) ? WEBP_MUX_DISPOSE_BACKGROUND : WEBP_MUX_DISPOSE_NONE;
+  frame->blend_method_ = (bits & 2) ? WEBP_MUX_NO_BLEND : WEBP_MUX_BLEND;
+  if (frame->width_ * (uint64_t)frame->height_ >= MAX_IMAGE_AREA) {
+    WebPSafeFree(frame);
+    return PARSE_ERROR;
+  }
+
+  // Store a frame only if the animation flag is set there is some data for
+  // this frame is available.
+  status = StoreFrame(dmux->num_frames_ + 1, anmf_payload_size, mem, frame);
+  if (status != PARSE_ERROR && is_animation && frame->frame_num_ > 0) {
+    added_frame = AddFrame(dmux, frame);
+    if (added_frame) {
+      ++dmux->num_frames_;
+    } else {
+      status = PARSE_ERROR;
+    }
+  }
+
+  if (!added_frame) WebPSafeFree(frame);
+  return status;
+}
+
+// General chunk storage, starting with the header at 'start_offset', allowing
+// the user to request the payload via a fourcc string. 'size' includes the
+// header and the unpadded payload size.
+// Returns true on success, false otherwise.
+static int StoreChunk(WebPDemuxer* const dmux,
+                      size_t start_offset, uint32_t size) {
+  Chunk* const chunk = (Chunk*)WebPSafeCalloc(1ULL, sizeof(*chunk));
+  if (chunk == NULL) return 0;
+
+  chunk->data_.offset_ = start_offset;
+  chunk->data_.size_ = size;
+  AddChunk(dmux, chunk);
+  return 1;
+}
+
+// -----------------------------------------------------------------------------
+// Primary chunk parsing
+
+static ParseStatus ReadHeader(MemBuffer* const mem) {
+  const size_t min_size = RIFF_HEADER_SIZE + CHUNK_HEADER_SIZE;
+  uint32_t riff_size;
+
+  // Basic file level validation.
+  if (MemDataSize(mem) < min_size) return PARSE_NEED_MORE_DATA;
+  if (memcmp(GetBuffer(mem), "RIFF", CHUNK_SIZE_BYTES) ||
+      memcmp(GetBuffer(mem) + CHUNK_HEADER_SIZE, "WEBP", CHUNK_SIZE_BYTES)) {
+    return PARSE_ERROR;
+  }
+
+  riff_size = GetLE32(GetBuffer(mem) + TAG_SIZE);
+  if (riff_size < CHUNK_HEADER_SIZE) return PARSE_ERROR;
+  if (riff_size > MAX_CHUNK_PAYLOAD) return PARSE_ERROR;
+
+  // There's no point in reading past the end of the RIFF chunk
+  mem->riff_end_ = riff_size + CHUNK_HEADER_SIZE;
+  if (mem->buf_size_ > mem->riff_end_) {
+    mem->buf_size_ = mem->end_ = mem->riff_end_;
+  }
+
+  Skip(mem, RIFF_HEADER_SIZE);
+  return PARSE_OK;
+}
+
+static ParseStatus ParseSingleImage(WebPDemuxer* const dmux) {
+  const size_t min_size = CHUNK_HEADER_SIZE;
+  MemBuffer* const mem = &dmux->mem_;
+  Frame* frame;
+  ParseStatus status;
+  int image_added = 0;
+
+  if (dmux->frames_ != NULL) return PARSE_ERROR;
+  if (SizeIsInvalid(mem, min_size)) return PARSE_ERROR;
+  if (MemDataSize(mem) < min_size) return PARSE_NEED_MORE_DATA;
+
+  frame = (Frame*)WebPSafeCalloc(1ULL, sizeof(*frame));
+  if (frame == NULL) return PARSE_ERROR;
+
+  // For the single image case we allow parsing of a partial frame, but we need
+  // at least CHUNK_HEADER_SIZE for parsing.
+  status = StoreFrame(1, CHUNK_HEADER_SIZE, &dmux->mem_, frame);
+  if (status != PARSE_ERROR) {
+    const int has_alpha = !!(dmux->feature_flags_ & ALPHA_FLAG);
+    // Clear any alpha when the alpha flag is missing.
+    if (!has_alpha && frame->img_components_[1].size_ > 0) {
+      frame->img_components_[1].offset_ = 0;
+      frame->img_components_[1].size_ = 0;
+      frame->has_alpha_ = 0;
+    }
+
+    // Use the frame width/height as the canvas values for non-vp8x files.
+    // Also, set ALPHA_FLAG if this is a lossless image with alpha.
+    if (!dmux->is_ext_format_ && frame->width_ > 0 && frame->height_ > 0) {
+      dmux->state_ = WEBP_DEMUX_PARSED_HEADER;
+      dmux->canvas_width_ = frame->width_;
+      dmux->canvas_height_ = frame->height_;
+      dmux->feature_flags_ |= frame->has_alpha_ ? ALPHA_FLAG : 0;
+    }
+    if (!AddFrame(dmux, frame)) {
+      status = PARSE_ERROR;  // last frame was left incomplete
+    } else {
+      image_added = 1;
+      dmux->num_frames_ = 1;
+    }
+  }
+
+  if (!image_added) WebPSafeFree(frame);
+  return status;
+}
+
+static ParseStatus ParseVP8XChunks(WebPDemuxer* const dmux) {
+  const int is_animation = !!(dmux->feature_flags_ & ANIMATION_FLAG);
+  MemBuffer* const mem = &dmux->mem_;
+  int anim_chunks = 0;
+  ParseStatus status = PARSE_OK;
+
+  do {
+    int store_chunk = 1;
+    const size_t chunk_start_offset = mem->start_;
+    const uint32_t fourcc = ReadLE32(mem);
+    const uint32_t chunk_size = ReadLE32(mem);
+    const uint32_t chunk_size_padded = chunk_size + (chunk_size & 1);
+
+    if (chunk_size > MAX_CHUNK_PAYLOAD) return PARSE_ERROR;
+    if (SizeIsInvalid(mem, chunk_size_padded)) return PARSE_ERROR;
+
+    switch (fourcc) {
+      case MKFOURCC('V', 'P', '8', 'X'): {
+        return PARSE_ERROR;
+      }
+      case MKFOURCC('A', 'L', 'P', 'H'):
+      case MKFOURCC('V', 'P', '8', ' '):
+      case MKFOURCC('V', 'P', '8', 'L'): {
+        // check that this isn't an animation (all frames should be in an ANMF).
+        if (anim_chunks > 0 || is_animation) return PARSE_ERROR;
+
+        Rewind(mem, CHUNK_HEADER_SIZE);
+        status = ParseSingleImage(dmux);
+        break;
+      }
+      case MKFOURCC('A', 'N', 'I', 'M'): {
+        if (chunk_size_padded < ANIM_CHUNK_SIZE) return PARSE_ERROR;
+
+        if (MemDataSize(mem) < chunk_size_padded) {
+          status = PARSE_NEED_MORE_DATA;
+        } else if (anim_chunks == 0) {
+          ++anim_chunks;
+          dmux->bgcolor_ = ReadLE32(mem);
+          dmux->loop_count_ = ReadLE16s(mem);
+          Skip(mem, chunk_size_padded - ANIM_CHUNK_SIZE);
+        } else {
+          store_chunk = 0;
+          goto Skip;
+        }
+        break;
+      }
+      case MKFOURCC('A', 'N', 'M', 'F'): {
+        if (anim_chunks == 0) return PARSE_ERROR;  // 'ANIM' precedes frames.
+        status = ParseAnimationFrame(dmux, chunk_size_padded);
+        break;
+      }
+      case MKFOURCC('I', 'C', 'C', 'P'): {
+        store_chunk = !!(dmux->feature_flags_ & ICCP_FLAG);
+        goto Skip;
+      }
+      case MKFOURCC('E', 'X', 'I', 'F'): {
+        store_chunk = !!(dmux->feature_flags_ & EXIF_FLAG);
+        goto Skip;
+      }
+      case MKFOURCC('X', 'M', 'P', ' '): {
+        store_chunk = !!(dmux->feature_flags_ & XMP_FLAG);
+        goto Skip;
+      }
+ Skip:
+      default: {
+        if (chunk_size_padded <= MemDataSize(mem)) {
+          if (store_chunk) {
+            // Store only the chunk header and unpadded size as only the payload
+            // will be returned to the user.
+            if (!StoreChunk(dmux, chunk_start_offset,
+                            CHUNK_HEADER_SIZE + chunk_size)) {
+              return PARSE_ERROR;
+            }
+          }
+          Skip(mem, chunk_size_padded);
+        } else {
+          status = PARSE_NEED_MORE_DATA;
+        }
+      }
+    }
+
+    if (mem->start_ == mem->riff_end_) {
+      break;
+    } else if (MemDataSize(mem) < CHUNK_HEADER_SIZE) {
+      status = PARSE_NEED_MORE_DATA;
+    }
+  } while (status == PARSE_OK);
+
+  return status;
+}
+
+static ParseStatus ParseVP8X(WebPDemuxer* const dmux) {
+  MemBuffer* const mem = &dmux->mem_;
+  uint32_t vp8x_size;
+
+  if (MemDataSize(mem) < CHUNK_HEADER_SIZE) return PARSE_NEED_MORE_DATA;
+
+  dmux->is_ext_format_ = 1;
+  Skip(mem, TAG_SIZE);  // VP8X
+  vp8x_size = ReadLE32(mem);
+  if (vp8x_size > MAX_CHUNK_PAYLOAD) return PARSE_ERROR;
+  if (vp8x_size < VP8X_CHUNK_SIZE) return PARSE_ERROR;
+  vp8x_size += vp8x_size & 1;
+  if (SizeIsInvalid(mem, vp8x_size)) return PARSE_ERROR;
+  if (MemDataSize(mem) < vp8x_size) return PARSE_NEED_MORE_DATA;
+
+  dmux->feature_flags_ = ReadByte(mem);
+  Skip(mem, 3);  // Reserved.
+  dmux->canvas_width_  = 1 + ReadLE24s(mem);
+  dmux->canvas_height_ = 1 + ReadLE24s(mem);
+  if (dmux->canvas_width_ * (uint64_t)dmux->canvas_height_ >= MAX_IMAGE_AREA) {
+    return PARSE_ERROR;  // image final dimension is too large
+  }
+  Skip(mem, vp8x_size - VP8X_CHUNK_SIZE);  // skip any trailing data.
+  dmux->state_ = WEBP_DEMUX_PARSED_HEADER;
+
+  if (SizeIsInvalid(mem, CHUNK_HEADER_SIZE)) return PARSE_ERROR;
+  if (MemDataSize(mem) < CHUNK_HEADER_SIZE) return PARSE_NEED_MORE_DATA;
+
+  return ParseVP8XChunks(dmux);
+}
+
+// -----------------------------------------------------------------------------
+// Format validation
+
+static int IsValidSimpleFormat(const WebPDemuxer* const dmux) {
+  const Frame* const frame = dmux->frames_;
+  if (dmux->state_ == WEBP_DEMUX_PARSING_HEADER) return 1;
+
+  if (dmux->canvas_width_ <= 0 || dmux->canvas_height_ <= 0) return 0;
+  if (dmux->state_ == WEBP_DEMUX_DONE && frame == NULL) return 0;
+
+  if (frame->width_ <= 0 || frame->height_ <= 0) return 0;
+  return 1;
+}
+
+// If 'exact' is true, check that the image resolution matches the canvas.
+// If 'exact' is false, check that the x/y offsets do not exceed the canvas.
+// TODO(jzern): this is insufficient in the fragmented image case if the
+// expectation is that the fragments completely cover the canvas.
+static int CheckFrameBounds(const Frame* const frame, int exact,
+                            int canvas_width, int canvas_height) {
+  if (exact) {
+    if (frame->x_offset_ != 0 || frame->y_offset_ != 0) {
+      return 0;
+    }
+    if (frame->width_ != canvas_width || frame->height_ != canvas_height) {
+      return 0;
+    }
+  } else {
+    if (frame->x_offset_ < 0 || frame->y_offset_ < 0) return 0;
+    if (frame->width_ + frame->x_offset_ > canvas_width) return 0;
+    if (frame->height_ + frame->y_offset_ > canvas_height) return 0;
+  }
+  return 1;
+}
+
+static int IsValidExtendedFormat(const WebPDemuxer* const dmux) {
+  const int is_animation = !!(dmux->feature_flags_ & ANIMATION_FLAG);
+  const int is_fragmented = !!(dmux->feature_flags_ & FRAGMENTS_FLAG);
+  const Frame* f = dmux->frames_;
+
+  if (dmux->state_ == WEBP_DEMUX_PARSING_HEADER) return 1;
+
+  if (dmux->canvas_width_ <= 0 || dmux->canvas_height_ <= 0) return 0;
+  if (dmux->loop_count_ < 0) return 0;
+  if (dmux->state_ == WEBP_DEMUX_DONE && dmux->frames_ == NULL) return 0;
+  if (is_fragmented) return 0;
+
+  while (f != NULL) {
+    const int cur_frame_set = f->frame_num_;
+    int frame_count = 0, fragment_count = 0;
+
+    // Check frame properties and if the image is composed of fragments that
+    // each fragment came from a fragment.
+    for (; f != NULL && f->frame_num_ == cur_frame_set; f = f->next_) {
+      const ChunkData* const image = f->img_components_;
+      const ChunkData* const alpha = f->img_components_ + 1;
+
+      if (is_fragmented && !f->is_fragment_) return 0;
+      if (!is_fragmented && f->is_fragment_) return 0;
+      if (!is_animation && f->frame_num_ > 1) return 0;
+
+      if (f->complete_) {
+        if (alpha->size_ == 0 && image->size_ == 0) return 0;
+        // Ensure alpha precedes image bitstream.
+        if (alpha->size_ > 0 && alpha->offset_ > image->offset_) {
+          return 0;
+        }
+
+        if (f->width_ <= 0 || f->height_ <= 0) return 0;
+      } else {
+        // There shouldn't be a partial frame in a complete file.
+        if (dmux->state_ == WEBP_DEMUX_DONE) return 0;
+
+        // Ensure alpha precedes image bitstream.
+        if (alpha->size_ > 0 && image->size_ > 0 &&
+            alpha->offset_ > image->offset_) {
+          return 0;
+        }
+        // There shouldn't be any frames after an incomplete one.
+        if (f->next_ != NULL) return 0;
+      }
+
+      if (f->width_ > 0 && f->height_ > 0 &&
+          !CheckFrameBounds(f, !(is_animation || is_fragmented),
+                            dmux->canvas_width_, dmux->canvas_height_)) {
+        return 0;
+      }
+
+      fragment_count += f->is_fragment_;
+      ++frame_count;
+    }
+    if (!is_fragmented && frame_count > 1) return 0;
+    if (fragment_count > 0 && frame_count != fragment_count) return 0;
+  }
+  return 1;
+}
+
+// -----------------------------------------------------------------------------
+// WebPDemuxer object
+
+static void InitDemux(WebPDemuxer* const dmux, const MemBuffer* const mem) {
+  dmux->state_ = WEBP_DEMUX_PARSING_HEADER;
+  dmux->loop_count_ = 1;
+  dmux->bgcolor_ = 0xFFFFFFFF;  // White background by default.
+  dmux->canvas_width_ = -1;
+  dmux->canvas_height_ = -1;
+  dmux->frames_tail_ = &dmux->frames_;
+  dmux->chunks_tail_ = &dmux->chunks_;
+  dmux->mem_ = *mem;
+}
+
+WebPDemuxer* WebPDemuxInternal(const WebPData* data, int allow_partial,
+                               WebPDemuxState* state, int version) {
+  const ChunkParser* parser;
+  int partial;
+  ParseStatus status = PARSE_ERROR;
+  MemBuffer mem;
+  WebPDemuxer* dmux;
+
+  if (state != NULL) *state = WEBP_DEMUX_PARSE_ERROR;
+
+  if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_DEMUX_ABI_VERSION)) return NULL;
+  if (data == NULL || data->bytes == NULL || data->size == 0) return NULL;
+
+  if (!InitMemBuffer(&mem, data->bytes, data->size)) return NULL;
+  status = ReadHeader(&mem);
+  if (status != PARSE_OK) {
+    if (state != NULL) {
+      *state = (status == PARSE_NEED_MORE_DATA) ? WEBP_DEMUX_PARSING_HEADER
+                                                : WEBP_DEMUX_PARSE_ERROR;
+    }
+    return NULL;
+  }
+
+  partial = (mem.buf_size_ < mem.riff_end_);
+  if (!allow_partial && partial) return NULL;
+
+  dmux = (WebPDemuxer*)WebPSafeCalloc(1ULL, sizeof(*dmux));
+  if (dmux == NULL) return NULL;
+  InitDemux(dmux, &mem);
+
+  status = PARSE_ERROR;
+  for (parser = kMasterChunks; parser->parse != NULL; ++parser) {
+    if (!memcmp(parser->id, GetBuffer(&dmux->mem_), TAG_SIZE)) {
+      status = parser->parse(dmux);
+      if (status == PARSE_OK) dmux->state_ = WEBP_DEMUX_DONE;
+      if (status == PARSE_NEED_MORE_DATA && !partial) status = PARSE_ERROR;
+      if (status != PARSE_ERROR && !parser->valid(dmux)) status = PARSE_ERROR;
+      if (status == PARSE_ERROR) dmux->state_ = WEBP_DEMUX_PARSE_ERROR;
+      break;
+    }
+  }
+  if (state != NULL) *state = dmux->state_;
+
+  if (status == PARSE_ERROR) {
+    WebPDemuxDelete(dmux);
+    return NULL;
+  }
+  return dmux;
+}
+
+void WebPDemuxDelete(WebPDemuxer* dmux) {
+  Chunk* c;
+  Frame* f;
+  if (dmux == NULL) return;
+
+  for (f = dmux->frames_; f != NULL;) {
+    Frame* const cur_frame = f;
+    f = f->next_;
+    WebPSafeFree(cur_frame);
+  }
+  for (c = dmux->chunks_; c != NULL;) {
+    Chunk* const cur_chunk = c;
+    c = c->next_;
+    WebPSafeFree(cur_chunk);
+  }
+  WebPSafeFree(dmux);
+}
+
+// -----------------------------------------------------------------------------
+
+uint32_t WebPDemuxGetI(const WebPDemuxer* dmux, WebPFormatFeature feature) {
+  if (dmux == NULL) return 0;
+
+  switch (feature) {
+    case WEBP_FF_FORMAT_FLAGS:     return dmux->feature_flags_;
+    case WEBP_FF_CANVAS_WIDTH:     return (uint32_t)dmux->canvas_width_;
+    case WEBP_FF_CANVAS_HEIGHT:    return (uint32_t)dmux->canvas_height_;
+    case WEBP_FF_LOOP_COUNT:       return (uint32_t)dmux->loop_count_;
+    case WEBP_FF_BACKGROUND_COLOR: return dmux->bgcolor_;
+    case WEBP_FF_FRAME_COUNT:      return (uint32_t)dmux->num_frames_;
+  }
+  return 0;
+}
+
+// -----------------------------------------------------------------------------
+// Frame iteration
+
+// Find the first 'frame_num' frame. There may be multiple such frames in a
+// fragmented frame.
+static const Frame* GetFrame(const WebPDemuxer* const dmux, int frame_num) {
+  const Frame* f;
+  for (f = dmux->frames_; f != NULL; f = f->next_) {
+    if (frame_num == f->frame_num_) break;
+  }
+  return f;
+}
+
+// Returns fragment 'fragment_num' and the total count.
+static const Frame* GetFragment(
+    const Frame* const frame_set, int fragment_num, int* const count) {
+  const int this_frame = frame_set->frame_num_;
+  const Frame* f = frame_set;
+  const Frame* fragment = NULL;
+  int total;
+
+  for (total = 0; f != NULL && f->frame_num_ == this_frame; f = f->next_) {
+    if (++total == fragment_num) fragment = f;
+  }
+  *count = total;
+  return fragment;
+}
+
+static const uint8_t* GetFramePayload(const uint8_t* const mem_buf,
+                                      const Frame* const frame,
+                                      size_t* const data_size) {
+  *data_size = 0;
+  if (frame != NULL) {
+    const ChunkData* const image = frame->img_components_;
+    const ChunkData* const alpha = frame->img_components_ + 1;
+    size_t start_offset = image->offset_;
+    *data_size = image->size_;
+
+    // if alpha exists it precedes image, update the size allowing for
+    // intervening chunks.
+    if (alpha->size_ > 0) {
+      const size_t inter_size = (image->offset_ > 0)
+                              ? image->offset_ - (alpha->offset_ + alpha->size_)
+                              : 0;
+      start_offset = alpha->offset_;
+      *data_size  += alpha->size_ + inter_size;
+    }
+    return mem_buf + start_offset;
+  }
+  return NULL;
+}
+
+// Create a whole 'frame' from VP8 (+ alpha) or lossless.
+static int SynthesizeFrame(const WebPDemuxer* const dmux,
+                           const Frame* const first_frame,
+                           int fragment_num, WebPIterator* const iter) {
+  const uint8_t* const mem_buf = dmux->mem_.buf_;
+  int num_fragments;
+  size_t payload_size = 0;
+  const Frame* const fragment =
+      GetFragment(first_frame, fragment_num, &num_fragments);
+  const uint8_t* const payload =
+      GetFramePayload(mem_buf, fragment, &payload_size);
+  if (payload == NULL) return 0;
+  assert(first_frame != NULL);
+
+  iter->frame_num      = first_frame->frame_num_;
+  iter->num_frames     = dmux->num_frames_;
+  iter->fragment_num   = fragment_num;
+  iter->num_fragments  = num_fragments;
+  iter->x_offset       = fragment->x_offset_;
+  iter->y_offset       = fragment->y_offset_;
+  iter->width          = fragment->width_;
+  iter->height         = fragment->height_;
+  iter->has_alpha      = fragment->has_alpha_;
+  iter->duration       = fragment->duration_;
+  iter->dispose_method = fragment->dispose_method_;
+  iter->blend_method   = fragment->blend_method_;
+  iter->complete       = fragment->complete_;
+  iter->fragment.bytes = payload;
+  iter->fragment.size  = payload_size;
+  return 1;
+}
+
+static int SetFrame(int frame_num, WebPIterator* const iter) {
+  const Frame* frame;
+  const WebPDemuxer* const dmux = (WebPDemuxer*)iter->private_;
+  if (dmux == NULL || frame_num < 0) return 0;
+  if (frame_num > dmux->num_frames_) return 0;
+  if (frame_num == 0) frame_num = dmux->num_frames_;
+
+  frame = GetFrame(dmux, frame_num);
+  if (frame == NULL) return 0;
+
+  return SynthesizeFrame(dmux, frame, 1, iter);
+}
+
+int WebPDemuxGetFrame(const WebPDemuxer* dmux, int frame, WebPIterator* iter) {
+  if (iter == NULL) return 0;
+
+  memset(iter, 0, sizeof(*iter));
+  iter->private_ = (void*)dmux;
+  return SetFrame(frame, iter);
+}
+
+int WebPDemuxNextFrame(WebPIterator* iter) {
+  if (iter == NULL) return 0;
+  return SetFrame(iter->frame_num + 1, iter);
+}
+
+int WebPDemuxPrevFrame(WebPIterator* iter) {
+  if (iter == NULL) return 0;
+  if (iter->frame_num <= 1) return 0;
+  return SetFrame(iter->frame_num - 1, iter);
+}
+
+int WebPDemuxSelectFragment(WebPIterator* iter, int fragment_num) {
+  if (iter != NULL && iter->private_ != NULL && fragment_num > 0) {
+    const WebPDemuxer* const dmux = (WebPDemuxer*)iter->private_;
+    const Frame* const frame = GetFrame(dmux, iter->frame_num);
+    if (frame == NULL) return 0;
+
+    return SynthesizeFrame(dmux, frame, fragment_num, iter);
+  }
+  return 0;
+}
+
+void WebPDemuxReleaseIterator(WebPIterator* iter) {
+  (void)iter;
+}
+
+// -----------------------------------------------------------------------------
+// Chunk iteration
+
+static int ChunkCount(const WebPDemuxer* const dmux, const char fourcc[4]) {
+  const uint8_t* const mem_buf = dmux->mem_.buf_;
+  const Chunk* c;
+  int count = 0;
+  for (c = dmux->chunks_; c != NULL; c = c->next_) {
+    const uint8_t* const header = mem_buf + c->data_.offset_;
+    if (!memcmp(header, fourcc, TAG_SIZE)) ++count;
+  }
+  return count;
+}
+
+static const Chunk* GetChunk(const WebPDemuxer* const dmux,
+                             const char fourcc[4], int chunk_num) {
+  const uint8_t* const mem_buf = dmux->mem_.buf_;
+  const Chunk* c;
+  int count = 0;
+  for (c = dmux->chunks_; c != NULL; c = c->next_) {
+    const uint8_t* const header = mem_buf + c->data_.offset_;
+    if (!memcmp(header, fourcc, TAG_SIZE)) ++count;
+    if (count == chunk_num) break;
+  }
+  return c;
+}
+
+static int SetChunk(const char fourcc[4], int chunk_num,
+                    WebPChunkIterator* const iter) {
+  const WebPDemuxer* const dmux = (WebPDemuxer*)iter->private_;
+  int count;
+
+  if (dmux == NULL || fourcc == NULL || chunk_num < 0) return 0;
+  count = ChunkCount(dmux, fourcc);
+  if (count == 0) return 0;
+  if (chunk_num == 0) chunk_num = count;
+
+  if (chunk_num <= count) {
+    const uint8_t* const mem_buf = dmux->mem_.buf_;
+    const Chunk* const chunk = GetChunk(dmux, fourcc, chunk_num);
+    iter->chunk.bytes = mem_buf + chunk->data_.offset_ + CHUNK_HEADER_SIZE;
+    iter->chunk.size  = chunk->data_.size_ - CHUNK_HEADER_SIZE;
+    iter->num_chunks  = count;
+    iter->chunk_num   = chunk_num;
+    return 1;
+  }
+  return 0;
+}
+
+int WebPDemuxGetChunk(const WebPDemuxer* dmux,
+                      const char fourcc[4], int chunk_num,
+                      WebPChunkIterator* iter) {
+  if (iter == NULL) return 0;
+
+  memset(iter, 0, sizeof(*iter));
+  iter->private_ = (void*)dmux;
+  return SetChunk(fourcc, chunk_num, iter);
+}
+
+int WebPDemuxNextChunk(WebPChunkIterator* iter) {
+  if (iter != NULL) {
+    const char* const fourcc =
+        (const char*)iter->chunk.bytes - CHUNK_HEADER_SIZE;
+    return SetChunk(fourcc, iter->chunk_num + 1, iter);
+  }
+  return 0;
+}
+
+int WebPDemuxPrevChunk(WebPChunkIterator* iter) {
+  if (iter != NULL && iter->chunk_num > 1) {
+    const char* const fourcc =
+        (const char*)iter->chunk.bytes - CHUNK_HEADER_SIZE;
+    return SetChunk(fourcc, iter->chunk_num - 1, iter);
+  }
+  return 0;
+}
+
+void WebPDemuxReleaseChunkIterator(WebPChunkIterator* iter) {
+  (void)iter;
+}
+
diff --git a/Source/LibWebP/src/dsp/dsp.alpha_processing.c b/Source/LibWebP/src/dsp/dsp.alpha_processing.c
new file mode 100644
index 0000000..874f8fa
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.alpha_processing.c
@@ -0,0 +1,377 @@
+// Copyright 2013 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Utilities for processing transparent channel.
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include <assert.h>
+#include "./dsp.h"
+
+// Tables can be faster on some platform but incur some extra binary size (~2k).
+// #define USE_TABLES_FOR_ALPHA_MULT
+
+// -----------------------------------------------------------------------------
+
+#define MFIX 24    // 24bit fixed-point arithmetic
+#define HALF ((1u << MFIX) >> 1)
+#define KINV_255 ((1u << MFIX) / 255u)
+
+static uint32_t Mult(uint8_t x, uint32_t mult) {
+  const uint32_t v = (x * mult + HALF) >> MFIX;
+  assert(v <= 255);  // <- 24bit precision is enough to ensure that.
+  return v;
+}
+
+#ifdef USE_TABLES_FOR_ALPHA_MULT
+
+static const uint32_t kMultTables[2][256] = {
+  {    // (255u << MFIX) / alpha
+    0x00000000, 0xff000000, 0x7f800000, 0x55000000, 0x3fc00000, 0x33000000,
+    0x2a800000, 0x246db6db, 0x1fe00000, 0x1c555555, 0x19800000, 0x172e8ba2,
+    0x15400000, 0x139d89d8, 0x1236db6d, 0x11000000, 0x0ff00000, 0x0f000000,
+    0x0e2aaaaa, 0x0d6bca1a, 0x0cc00000, 0x0c249249, 0x0b9745d1, 0x0b1642c8,
+    0x0aa00000, 0x0a333333, 0x09cec4ec, 0x0971c71c, 0x091b6db6, 0x08cb08d3,
+    0x08800000, 0x0839ce73, 0x07f80000, 0x07ba2e8b, 0x07800000, 0x07492492,
+    0x07155555, 0x06e45306, 0x06b5e50d, 0x0689d89d, 0x06600000, 0x063831f3,
+    0x06124924, 0x05ee23b8, 0x05cba2e8, 0x05aaaaaa, 0x058b2164, 0x056cefa8,
+    0x05500000, 0x05343eb1, 0x05199999, 0x05000000, 0x04e76276, 0x04cfb2b7,
+    0x04b8e38e, 0x04a2e8ba, 0x048db6db, 0x0479435e, 0x04658469, 0x045270d0,
+    0x04400000, 0x042e29f7, 0x041ce739, 0x040c30c3, 0x03fc0000, 0x03ec4ec4,
+    0x03dd1745, 0x03ce540f, 0x03c00000, 0x03b21642, 0x03a49249, 0x03976fc6,
+    0x038aaaaa, 0x037e3f1f, 0x03722983, 0x03666666, 0x035af286, 0x034fcace,
+    0x0344ec4e, 0x033a5440, 0x03300000, 0x0325ed09, 0x031c18f9, 0x0312818a,
+    0x03092492, 0x03000000, 0x02f711dc, 0x02ee5846, 0x02e5d174, 0x02dd7baf,
+    0x02d55555, 0x02cd5cd5, 0x02c590b2, 0x02bdef7b, 0x02b677d4, 0x02af286b,
+    0x02a80000, 0x02a0fd5c, 0x029a1f58, 0x029364d9, 0x028ccccc, 0x0286562d,
+    0x02800000, 0x0279c952, 0x0273b13b, 0x026db6db, 0x0267d95b, 0x026217ec,
+    0x025c71c7, 0x0256e62a, 0x0251745d, 0x024c1bac, 0x0246db6d, 0x0241b2f9,
+    0x023ca1af, 0x0237a6f4, 0x0232c234, 0x022df2df, 0x02293868, 0x02249249,
+    0x02200000, 0x021b810e, 0x021714fb, 0x0212bb51, 0x020e739c, 0x020a3d70,
+    0x02061861, 0x02020408, 0x01fe0000, 0x01fa0be8, 0x01f62762, 0x01f25213,
+    0x01ee8ba2, 0x01ead3ba, 0x01e72a07, 0x01e38e38, 0x01e00000, 0x01dc7f10,
+    0x01d90b21, 0x01d5a3e9, 0x01d24924, 0x01cefa8d, 0x01cbb7e3, 0x01c880e5,
+    0x01c55555, 0x01c234f7, 0x01bf1f8f, 0x01bc14e5, 0x01b914c1, 0x01b61eed,
+    0x01b33333, 0x01b05160, 0x01ad7943, 0x01aaaaaa, 0x01a7e567, 0x01a5294a,
+    0x01a27627, 0x019fcbd2, 0x019d2a20, 0x019a90e7, 0x01980000, 0x01957741,
+    0x0192f684, 0x01907da4, 0x018e0c7c, 0x018ba2e8, 0x018940c5, 0x0186e5f0,
+    0x01849249, 0x018245ae, 0x01800000, 0x017dc11f, 0x017b88ee, 0x0179574e,
+    0x01772c23, 0x01750750, 0x0172e8ba, 0x0170d045, 0x016ebdd7, 0x016cb157,
+    0x016aaaaa, 0x0168a9b9, 0x0166ae6a, 0x0164b8a7, 0x0162c859, 0x0160dd67,
+    0x015ef7bd, 0x015d1745, 0x015b3bea, 0x01596596, 0x01579435, 0x0155c7b4,
+    0x01540000, 0x01523d03, 0x01507eae, 0x014ec4ec, 0x014d0fac, 0x014b5edc,
+    0x0149b26c, 0x01480a4a, 0x01466666, 0x0144c6af, 0x01432b16, 0x0141938b,
+    0x01400000, 0x013e7063, 0x013ce4a9, 0x013b5cc0, 0x0139d89d, 0x01385830,
+    0x0136db6d, 0x01356246, 0x0133ecad, 0x01327a97, 0x01310bf6, 0x012fa0be,
+    0x012e38e3, 0x012cd459, 0x012b7315, 0x012a150a, 0x0128ba2e, 0x01276276,
+    0x01260dd6, 0x0124bc44, 0x01236db6, 0x01222222, 0x0120d97c, 0x011f93bc,
+    0x011e50d7, 0x011d10c4, 0x011bd37a, 0x011a98ef, 0x0119611a, 0x01182bf2,
+    0x0116f96f, 0x0115c988, 0x01149c34, 0x0113716a, 0x01124924, 0x01112358,
+    0x01100000, 0x010edf12, 0x010dc087, 0x010ca458, 0x010b8a7d, 0x010a72f0,
+    0x01095da8, 0x01084a9f, 0x010739ce, 0x01062b2e, 0x01051eb8, 0x01041465,
+    0x01030c30, 0x01020612, 0x01010204, 0x01000000 },
+  {   // alpha * KINV_255
+    0x00000000, 0x00010101, 0x00020202, 0x00030303, 0x00040404, 0x00050505,
+    0x00060606, 0x00070707, 0x00080808, 0x00090909, 0x000a0a0a, 0x000b0b0b,
+    0x000c0c0c, 0x000d0d0d, 0x000e0e0e, 0x000f0f0f, 0x00101010, 0x00111111,
+    0x00121212, 0x00131313, 0x00141414, 0x00151515, 0x00161616, 0x00171717,
+    0x00181818, 0x00191919, 0x001a1a1a, 0x001b1b1b, 0x001c1c1c, 0x001d1d1d,
+    0x001e1e1e, 0x001f1f1f, 0x00202020, 0x00212121, 0x00222222, 0x00232323,
+    0x00242424, 0x00252525, 0x00262626, 0x00272727, 0x00282828, 0x00292929,
+    0x002a2a2a, 0x002b2b2b, 0x002c2c2c, 0x002d2d2d, 0x002e2e2e, 0x002f2f2f,
+    0x00303030, 0x00313131, 0x00323232, 0x00333333, 0x00343434, 0x00353535,
+    0x00363636, 0x00373737, 0x00383838, 0x00393939, 0x003a3a3a, 0x003b3b3b,
+    0x003c3c3c, 0x003d3d3d, 0x003e3e3e, 0x003f3f3f, 0x00404040, 0x00414141,
+    0x00424242, 0x00434343, 0x00444444, 0x00454545, 0x00464646, 0x00474747,
+    0x00484848, 0x00494949, 0x004a4a4a, 0x004b4b4b, 0x004c4c4c, 0x004d4d4d,
+    0x004e4e4e, 0x004f4f4f, 0x00505050, 0x00515151, 0x00525252, 0x00535353,
+    0x00545454, 0x00555555, 0x00565656, 0x00575757, 0x00585858, 0x00595959,
+    0x005a5a5a, 0x005b5b5b, 0x005c5c5c, 0x005d5d5d, 0x005e5e5e, 0x005f5f5f,
+    0x00606060, 0x00616161, 0x00626262, 0x00636363, 0x00646464, 0x00656565,
+    0x00666666, 0x00676767, 0x00686868, 0x00696969, 0x006a6a6a, 0x006b6b6b,
+    0x006c6c6c, 0x006d6d6d, 0x006e6e6e, 0x006f6f6f, 0x00707070, 0x00717171,
+    0x00727272, 0x00737373, 0x00747474, 0x00757575, 0x00767676, 0x00777777,
+    0x00787878, 0x00797979, 0x007a7a7a, 0x007b7b7b, 0x007c7c7c, 0x007d7d7d,
+    0x007e7e7e, 0x007f7f7f, 0x00808080, 0x00818181, 0x00828282, 0x00838383,
+    0x00848484, 0x00858585, 0x00868686, 0x00878787, 0x00888888, 0x00898989,
+    0x008a8a8a, 0x008b8b8b, 0x008c8c8c, 0x008d8d8d, 0x008e8e8e, 0x008f8f8f,
+    0x00909090, 0x00919191, 0x00929292, 0x00939393, 0x00949494, 0x00959595,
+    0x00969696, 0x00979797, 0x00989898, 0x00999999, 0x009a9a9a, 0x009b9b9b,
+    0x009c9c9c, 0x009d9d9d, 0x009e9e9e, 0x009f9f9f, 0x00a0a0a0, 0x00a1a1a1,
+    0x00a2a2a2, 0x00a3a3a3, 0x00a4a4a4, 0x00a5a5a5, 0x00a6a6a6, 0x00a7a7a7,
+    0x00a8a8a8, 0x00a9a9a9, 0x00aaaaaa, 0x00ababab, 0x00acacac, 0x00adadad,
+    0x00aeaeae, 0x00afafaf, 0x00b0b0b0, 0x00b1b1b1, 0x00b2b2b2, 0x00b3b3b3,
+    0x00b4b4b4, 0x00b5b5b5, 0x00b6b6b6, 0x00b7b7b7, 0x00b8b8b8, 0x00b9b9b9,
+    0x00bababa, 0x00bbbbbb, 0x00bcbcbc, 0x00bdbdbd, 0x00bebebe, 0x00bfbfbf,
+    0x00c0c0c0, 0x00c1c1c1, 0x00c2c2c2, 0x00c3c3c3, 0x00c4c4c4, 0x00c5c5c5,
+    0x00c6c6c6, 0x00c7c7c7, 0x00c8c8c8, 0x00c9c9c9, 0x00cacaca, 0x00cbcbcb,
+    0x00cccccc, 0x00cdcdcd, 0x00cecece, 0x00cfcfcf, 0x00d0d0d0, 0x00d1d1d1,
+    0x00d2d2d2, 0x00d3d3d3, 0x00d4d4d4, 0x00d5d5d5, 0x00d6d6d6, 0x00d7d7d7,
+    0x00d8d8d8, 0x00d9d9d9, 0x00dadada, 0x00dbdbdb, 0x00dcdcdc, 0x00dddddd,
+    0x00dedede, 0x00dfdfdf, 0x00e0e0e0, 0x00e1e1e1, 0x00e2e2e2, 0x00e3e3e3,
+    0x00e4e4e4, 0x00e5e5e5, 0x00e6e6e6, 0x00e7e7e7, 0x00e8e8e8, 0x00e9e9e9,
+    0x00eaeaea, 0x00ebebeb, 0x00ececec, 0x00ededed, 0x00eeeeee, 0x00efefef,
+    0x00f0f0f0, 0x00f1f1f1, 0x00f2f2f2, 0x00f3f3f3, 0x00f4f4f4, 0x00f5f5f5,
+    0x00f6f6f6, 0x00f7f7f7, 0x00f8f8f8, 0x00f9f9f9, 0x00fafafa, 0x00fbfbfb,
+    0x00fcfcfc, 0x00fdfdfd, 0x00fefefe, 0x00ffffff }
+};
+
+static WEBP_INLINE uint32_t GetScale(uint32_t a, int inverse) {
+  return kMultTables[!inverse][a];
+}
+
+#else
+
+static WEBP_INLINE uint32_t GetScale(uint32_t a, int inverse) {
+  return inverse ? (255u << MFIX) / a : a * KINV_255;
+}
+
+#endif    // USE_TABLES_FOR_ALPHA_MULT
+
+void WebPMultARGBRowC(uint32_t* const ptr, int width, int inverse) {
+  int x;
+  for (x = 0; x < width; ++x) {
+    const uint32_t argb = ptr[x];
+    if (argb < 0xff000000u) {      // alpha < 255
+      if (argb <= 0x00ffffffu) {   // alpha == 0
+        ptr[x] = 0;
+      } else {
+        const uint32_t alpha = (argb >> 24) & 0xff;
+        const uint32_t scale = GetScale(alpha, inverse);
+        uint32_t out = argb & 0xff000000u;
+        out |= Mult(argb >>  0, scale) <<  0;
+        out |= Mult(argb >>  8, scale) <<  8;
+        out |= Mult(argb >> 16, scale) << 16;
+        ptr[x] = out;
+      }
+    }
+  }
+}
+
+void WebPMultRowC(uint8_t* const ptr, const uint8_t* const alpha,
+                  int width, int inverse) {
+  int x;
+  for (x = 0; x < width; ++x) {
+    const uint32_t a = alpha[x];
+    if (a != 255) {
+      if (a == 0) {
+        ptr[x] = 0;
+      } else {
+        const uint32_t scale = GetScale(a, inverse);
+        ptr[x] = Mult(ptr[x], scale);
+      }
+    }
+  }
+}
+
+#undef KINV_255
+#undef HALF
+#undef MFIX
+
+void (*WebPMultARGBRow)(uint32_t* const ptr, int width, int inverse);
+void (*WebPMultRow)(uint8_t* const ptr, const uint8_t* const alpha,
+                    int width, int inverse);
+
+//------------------------------------------------------------------------------
+// Generic per-plane calls
+
+void WebPMultARGBRows(uint8_t* ptr, int stride, int width, int num_rows,
+                      int inverse) {
+  int n;
+  for (n = 0; n < num_rows; ++n) {
+    WebPMultARGBRow((uint32_t*)ptr, width, inverse);
+    ptr += stride;
+  }
+}
+
+void WebPMultRows(uint8_t* ptr, int stride,
+                  const uint8_t* alpha, int alpha_stride,
+                  int width, int num_rows, int inverse) {
+  int n;
+  for (n = 0; n < num_rows; ++n) {
+    WebPMultRow(ptr, alpha, width, inverse);
+    ptr += stride;
+    alpha += alpha_stride;
+  }
+}
+
+//------------------------------------------------------------------------------
+// Premultiplied modes
+
+// non dithered-modes
+
+// (x * a * 32897) >> 23 is bit-wise equivalent to (int)(x * a / 255.)
+// for all 8bit x or a. For bit-wise equivalence to (int)(x * a / 255. + .5),
+// one can use instead: (x * a * 65793 + (1 << 23)) >> 24
+#if 1     // (int)(x * a / 255.)
+#define MULTIPLIER(a)   ((a) * 32897U)
+#define PREMULTIPLY(x, m) (((x) * (m)) >> 23)
+#else     // (int)(x * a / 255. + .5)
+#define MULTIPLIER(a) ((a) * 65793U)
+#define PREMULTIPLY(x, m) (((x) * (m) + (1U << 23)) >> 24)
+#endif
+
+static void ApplyAlphaMultiply(uint8_t* rgba, int alpha_first,
+                               int w, int h, int stride) {
+  while (h-- > 0) {
+    uint8_t* const rgb = rgba + (alpha_first ? 1 : 0);
+    const uint8_t* const alpha = rgba + (alpha_first ? 0 : 3);
+    int i;
+    for (i = 0; i < w; ++i) {
+      const uint32_t a = alpha[4 * i];
+      if (a != 0xff) {
+        const uint32_t mult = MULTIPLIER(a);
+        rgb[4 * i + 0] = PREMULTIPLY(rgb[4 * i + 0], mult);
+        rgb[4 * i + 1] = PREMULTIPLY(rgb[4 * i + 1], mult);
+        rgb[4 * i + 2] = PREMULTIPLY(rgb[4 * i + 2], mult);
+      }
+    }
+    rgba += stride;
+  }
+}
+#undef MULTIPLIER
+#undef PREMULTIPLY
+
+// rgbA4444
+
+#define MULTIPLIER(a)  ((a) * 0x1111)    // 0x1111 ~= (1 << 16) / 15
+
+static WEBP_INLINE uint8_t dither_hi(uint8_t x) {
+  return (x & 0xf0) | (x >> 4);
+}
+
+static WEBP_INLINE uint8_t dither_lo(uint8_t x) {
+  return (x & 0x0f) | (x << 4);
+}
+
+static WEBP_INLINE uint8_t multiply(uint8_t x, uint32_t m) {
+  return (x * m) >> 16;
+}
+
+static WEBP_INLINE void ApplyAlphaMultiply4444(uint8_t* rgba4444,
+                                               int w, int h, int stride,
+                                               int rg_byte_pos /* 0 or 1 */) {
+  while (h-- > 0) {
+    int i;
+    for (i = 0; i < w; ++i) {
+      const uint32_t rg = rgba4444[2 * i + rg_byte_pos];
+      const uint32_t ba = rgba4444[2 * i + (rg_byte_pos ^ 1)];
+      const uint8_t a = ba & 0x0f;
+      const uint32_t mult = MULTIPLIER(a);
+      const uint8_t r = multiply(dither_hi(rg), mult);
+      const uint8_t g = multiply(dither_lo(rg), mult);
+      const uint8_t b = multiply(dither_hi(ba), mult);
+      rgba4444[2 * i + rg_byte_pos] = (r & 0xf0) | ((g >> 4) & 0x0f);
+      rgba4444[2 * i + (rg_byte_pos ^ 1)] = (b & 0xf0) | a;
+    }
+    rgba4444 += stride;
+  }
+}
+#undef MULTIPLIER
+
+static void ApplyAlphaMultiply_16b(uint8_t* rgba4444,
+                                   int w, int h, int stride) {
+#ifdef WEBP_SWAP_16BIT_CSP
+  ApplyAlphaMultiply4444(rgba4444, w, h, stride, 1);
+#else
+  ApplyAlphaMultiply4444(rgba4444, w, h, stride, 0);
+#endif
+}
+
+static int DispatchAlpha(const uint8_t* alpha, int alpha_stride,
+                         int width, int height,
+                         uint8_t* dst, int dst_stride) {
+  uint32_t alpha_mask = 0xff;
+  int i, j;
+
+  for (j = 0; j < height; ++j) {
+    for (i = 0; i < width; ++i) {
+      const uint32_t alpha_value = alpha[i];
+      dst[4 * i] = alpha_value;
+      alpha_mask &= alpha_value;
+    }
+    alpha += alpha_stride;
+    dst += dst_stride;
+  }
+
+  return (alpha_mask != 0xff);
+}
+
+static void DispatchAlphaToGreen(const uint8_t* alpha, int alpha_stride,
+                                 int width, int height,
+                                 uint32_t* dst, int dst_stride) {
+  int i, j;
+  for (j = 0; j < height; ++j) {
+    for (i = 0; i < width; ++i) {
+      dst[i] = alpha[i] << 8;  // leave A/R/B channels zero'd.
+    }
+    alpha += alpha_stride;
+    dst += dst_stride;
+  }
+}
+
+static int ExtractAlpha(const uint8_t* argb, int argb_stride,
+                        int width, int height,
+                        uint8_t* alpha, int alpha_stride) {
+  uint8_t alpha_mask = 0xff;
+  int i, j;
+
+  for (j = 0; j < height; ++j) {
+    for (i = 0; i < width; ++i) {
+      const uint8_t alpha_value = argb[4 * i];
+      alpha[i] = alpha_value;
+      alpha_mask &= alpha_value;
+    }
+    argb += argb_stride;
+    alpha += alpha_stride;
+  }
+  return (alpha_mask == 0xff);
+}
+
+void (*WebPApplyAlphaMultiply)(uint8_t*, int, int, int, int);
+void (*WebPApplyAlphaMultiply4444)(uint8_t*, int, int, int);
+int (*WebPDispatchAlpha)(const uint8_t*, int, int, int, uint8_t*, int);
+void (*WebPDispatchAlphaToGreen)(const uint8_t*, int, int, int, uint32_t*, int);
+int (*WebPExtractAlpha)(const uint8_t*, int, int, int, uint8_t*, int);
+
+//------------------------------------------------------------------------------
+// Init function
+
+extern void WebPInitAlphaProcessingMIPSdspR2(void);
+extern void WebPInitAlphaProcessingSSE2(void);
+
+static volatile VP8CPUInfo alpha_processing_last_cpuinfo_used =
+    (VP8CPUInfo)&alpha_processing_last_cpuinfo_used;
+
+WEBP_TSAN_IGNORE_FUNCTION void WebPInitAlphaProcessing(void) {
+  if (alpha_processing_last_cpuinfo_used == VP8GetCPUInfo) return;
+
+  WebPMultARGBRow = WebPMultARGBRowC;
+  WebPMultRow = WebPMultRowC;
+  WebPApplyAlphaMultiply = ApplyAlphaMultiply;
+  WebPApplyAlphaMultiply4444 = ApplyAlphaMultiply_16b;
+  WebPDispatchAlpha = DispatchAlpha;
+  WebPDispatchAlphaToGreen = DispatchAlphaToGreen;
+  WebPExtractAlpha = ExtractAlpha;
+
+  // If defined, use CPUInfo() to overwrite some pointers with faster versions.
+  if (VP8GetCPUInfo != NULL) {
+#if defined(WEBP_USE_SSE2)
+    if (VP8GetCPUInfo(kSSE2)) {
+      WebPInitAlphaProcessingSSE2();
+    }
+#endif
+#if defined(WEBP_USE_MIPS_DSP_R2)
+    if (VP8GetCPUInfo(kMIPSdspR2)) {
+      WebPInitAlphaProcessingMIPSdspR2();
+    }
+#endif
+  }
+  alpha_processing_last_cpuinfo_used = VP8GetCPUInfo;
+}
diff --git a/Source/LibWebP/src/dsp/dsp.alpha_processing_mips_dsp_r2.c b/Source/LibWebP/src/dsp/dsp.alpha_processing_mips_dsp_r2.c
new file mode 100644
index 0000000..e14a577
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.alpha_processing_mips_dsp_r2.c
@@ -0,0 +1,139 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Utilities for processing transparent channel.
+//
+// Author(s): Branimir Vasic (branimir.vasic at imgtec.com)
+//            Djordje Pesut  (djordje.pesut at imgtec.com)
+
+#include "./dsp.h"
+
+#if defined(WEBP_USE_MIPS_DSP_R2)
+
+static int DispatchAlpha(const uint8_t* alpha, int alpha_stride,
+                         int width, int height,
+                         uint8_t* dst, int dst_stride) {
+  uint32_t alpha_mask = 0xffffffff;
+  int i, j, temp0;
+
+  for (j = 0; j < height; ++j) {
+    uint8_t* pdst = dst;
+    const uint8_t* palpha = alpha;
+    for (i = 0; i < (width >> 2); ++i) {
+      int temp1, temp2, temp3;
+
+      __asm__ volatile (
+        "ulw    %[temp0],      0(%[palpha])                \n\t"
+        "addiu  %[palpha],     %[palpha],     4            \n\t"
+        "addiu  %[pdst],       %[pdst],       16           \n\t"
+        "srl    %[temp1],      %[temp0],      8            \n\t"
+        "srl    %[temp2],      %[temp0],      16           \n\t"
+        "srl    %[temp3],      %[temp0],      24           \n\t"
+        "and    %[alpha_mask], %[alpha_mask], %[temp0]     \n\t"
+        "sb     %[temp0],      -16(%[pdst])                \n\t"
+        "sb     %[temp1],      -12(%[pdst])                \n\t"
+        "sb     %[temp2],      -8(%[pdst])                 \n\t"
+        "sb     %[temp3],      -4(%[pdst])                 \n\t"
+        : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+          [temp3]"=&r"(temp3), [palpha]"+r"(palpha), [pdst]"+r"(pdst),
+          [alpha_mask]"+r"(alpha_mask)
+        :
+        : "memory"
+      );
+    }
+
+    for (i = 0; i < (width & 3); ++i) {
+      __asm__ volatile (
+        "lbu    %[temp0],      0(%[palpha])                \n\t"
+        "addiu  %[palpha],     %[palpha],     1            \n\t"
+        "sb     %[temp0],      0(%[pdst])                  \n\t"
+        "and    %[alpha_mask], %[alpha_mask], %[temp0]     \n\t"
+        "addiu  %[pdst],       %[pdst],       4            \n\t"
+        : [temp0]"=&r"(temp0), [palpha]"+r"(palpha), [pdst]"+r"(pdst),
+          [alpha_mask]"+r"(alpha_mask)
+        :
+        : "memory"
+      );
+    }
+    alpha += alpha_stride;
+    dst += dst_stride;
+  }
+
+  __asm__ volatile (
+    "ext    %[temp0],      %[alpha_mask], 0, 16            \n\t"
+    "srl    %[alpha_mask], %[alpha_mask], 16               \n\t"
+    "and    %[alpha_mask], %[alpha_mask], %[temp0]         \n\t"
+    "ext    %[temp0],      %[alpha_mask], 0, 8             \n\t"
+    "srl    %[alpha_mask], %[alpha_mask], 8                \n\t"
+    "and    %[alpha_mask], %[alpha_mask], %[temp0]         \n\t"
+    : [temp0]"=&r"(temp0), [alpha_mask]"+r"(alpha_mask)
+    :
+  );
+
+  return (alpha_mask != 0xff);
+}
+
+static void MultARGBRow(uint32_t* const ptr, int width, int inverse) {
+  int x;
+  const uint32_t c_00ffffff = 0x00ffffffu;
+  const uint32_t c_ff000000 = 0xff000000u;
+  const uint32_t c_8000000  = 0x00800000u;
+  const uint32_t c_8000080  = 0x00800080u;
+  for (x = 0; x < width; ++x) {
+    const uint32_t argb = ptr[x];
+    if (argb < 0xff000000u) {      // alpha < 255
+      if (argb <= 0x00ffffffu) {   // alpha == 0
+        ptr[x] = 0;
+      } else {
+        int temp0, temp1, temp2, temp3, alpha;
+        __asm__ volatile (
+          "srl          %[alpha],   %[argb],       24                \n\t"
+          "replv.qb     %[temp0],   %[alpha]                         \n\t"
+          "and          %[temp0],   %[temp0],      %[c_00ffffff]     \n\t"
+          "beqz         %[inverse], 0f                               \n\t"
+          "divu         $zero,      %[c_ff000000], %[alpha]          \n\t"
+          "mflo         %[temp0]                                     \n\t"
+        "0:                                                          \n\t"
+          "andi         %[temp1],   %[argb],       0xff              \n\t"
+          "ext          %[temp2],   %[argb],       8,             8  \n\t"
+          "ext          %[temp3],   %[argb],       16,            8  \n\t"
+          "mul          %[temp1],   %[temp1],      %[temp0]          \n\t"
+          "mul          %[temp2],   %[temp2],      %[temp0]          \n\t"
+          "mul          %[temp3],   %[temp3],      %[temp0]          \n\t"
+          "precrq.ph.w  %[temp1],   %[temp2],      %[temp1]          \n\t"
+          "addu         %[temp3],   %[temp3],      %[c_8000000]      \n\t"
+          "addu         %[temp1],   %[temp1],      %[c_8000080]      \n\t"
+          "precrq.ph.w  %[temp3],   %[argb],       %[temp3]          \n\t"
+          "precrq.qb.ph %[temp1],   %[temp3],      %[temp1]          \n\t"
+          : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+            [temp3]"=&r"(temp3), [alpha]"=&r"(alpha)
+          : [inverse]"r"(inverse), [c_00ffffff]"r"(c_00ffffff),
+            [c_8000000]"r"(c_8000000), [c_8000080]"r"(c_8000080),
+            [c_ff000000]"r"(c_ff000000), [argb]"r"(argb)
+          : "memory", "hi", "lo"
+        );
+        ptr[x] = temp1;
+      }
+    }
+  }
+}
+
+#endif  // WEBP_USE_MIPS_DSP_R2
+
+//------------------------------------------------------------------------------
+// Init function
+
+extern void WebPInitAlphaProcessingMIPSdspR2(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void WebPInitAlphaProcessingMIPSdspR2(void) {
+#if defined(WEBP_USE_MIPS_DSP_R2)
+  WebPDispatchAlpha = DispatchAlpha;
+  WebPMultARGBRow = MultARGBRow;
+#endif
+}
diff --git a/Source/LibWebP/src/dsp/dsp.alpha_processing_sse2.c b/Source/LibWebP/src/dsp/dsp.alpha_processing_sse2.c
new file mode 100644
index 0000000..7ad467b
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.alpha_processing_sse2.c
@@ -0,0 +1,296 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Utilities for processing transparent channel.
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include "./dsp.h"
+
+#if defined(WEBP_USE_SSE2)
+#include <emmintrin.h>
+
+//------------------------------------------------------------------------------
+
+static int DispatchAlpha(const uint8_t* alpha, int alpha_stride,
+                         int width, int height,
+                         uint8_t* dst, int dst_stride) {
+  // alpha_and stores an 'and' operation of all the alpha[] values. The final
+  // value is not 0xff if any of the alpha[] is not equal to 0xff.
+  uint32_t alpha_and = 0xff;
+  int i, j;
+  const __m128i zero = _mm_setzero_si128();
+  const __m128i rgb_mask = _mm_set1_epi32(0xffffff00u);  // to preserve RGB
+  const __m128i all_0xff = _mm_set_epi32(0, 0, ~0u, ~0u);
+  __m128i all_alphas = all_0xff;
+
+  // We must be able to access 3 extra bytes after the last written byte
+  // 'dst[4 * width - 4]', because we don't know if alpha is the first or the
+  // last byte of the quadruplet.
+  const int limit = (width - 1) & ~7;
+
+  for (j = 0; j < height; ++j) {
+    __m128i* out = (__m128i*)dst;
+    for (i = 0; i < limit; i += 8) {
+      // load 8 alpha bytes
+      const __m128i a0 = _mm_loadl_epi64((const __m128i*)&alpha[i]);
+      const __m128i a1 = _mm_unpacklo_epi8(a0, zero);
+      const __m128i a2_lo = _mm_unpacklo_epi16(a1, zero);
+      const __m128i a2_hi = _mm_unpackhi_epi16(a1, zero);
+      // load 8 dst pixels (32 bytes)
+      const __m128i b0_lo = _mm_loadu_si128(out + 0);
+      const __m128i b0_hi = _mm_loadu_si128(out + 1);
+      // mask dst alpha values
+      const __m128i b1_lo = _mm_and_si128(b0_lo, rgb_mask);
+      const __m128i b1_hi = _mm_and_si128(b0_hi, rgb_mask);
+      // combine
+      const __m128i b2_lo = _mm_or_si128(b1_lo, a2_lo);
+      const __m128i b2_hi = _mm_or_si128(b1_hi, a2_hi);
+      // store
+      _mm_storeu_si128(out + 0, b2_lo);
+      _mm_storeu_si128(out + 1, b2_hi);
+      // accumulate eight alpha 'and' in parallel
+      all_alphas = _mm_and_si128(all_alphas, a0);
+      out += 2;
+    }
+    for (; i < width; ++i) {
+      const uint32_t alpha_value = alpha[i];
+      dst[4 * i] = alpha_value;
+      alpha_and &= alpha_value;
+    }
+    alpha += alpha_stride;
+    dst += dst_stride;
+  }
+  // Combine the eight alpha 'and' into a 8-bit mask.
+  alpha_and &= _mm_movemask_epi8(_mm_cmpeq_epi8(all_alphas, all_0xff));
+  return (alpha_and != 0xff);
+}
+
+static void DispatchAlphaToGreen(const uint8_t* alpha, int alpha_stride,
+                                 int width, int height,
+                                 uint32_t* dst, int dst_stride) {
+  int i, j;
+  const __m128i zero = _mm_setzero_si128();
+  const int limit = width & ~15;
+  for (j = 0; j < height; ++j) {
+    for (i = 0; i < limit; i += 16) {   // process 16 alpha bytes
+      const __m128i a0 = _mm_loadu_si128((const __m128i*)&alpha[i]);
+      const __m128i a1 = _mm_unpacklo_epi8(zero, a0);  // note the 'zero' first!
+      const __m128i b1 = _mm_unpackhi_epi8(zero, a0);
+      const __m128i a2_lo = _mm_unpacklo_epi16(a1, zero);
+      const __m128i b2_lo = _mm_unpacklo_epi16(b1, zero);
+      const __m128i a2_hi = _mm_unpackhi_epi16(a1, zero);
+      const __m128i b2_hi = _mm_unpackhi_epi16(b1, zero);
+      _mm_storeu_si128((__m128i*)&dst[i +  0], a2_lo);
+      _mm_storeu_si128((__m128i*)&dst[i +  4], a2_hi);
+      _mm_storeu_si128((__m128i*)&dst[i +  8], b2_lo);
+      _mm_storeu_si128((__m128i*)&dst[i + 12], b2_hi);
+    }
+    for (; i < width; ++i) dst[i] = alpha[i] << 8;
+    alpha += alpha_stride;
+    dst += dst_stride;
+  }
+}
+
+static int ExtractAlpha(const uint8_t* argb, int argb_stride,
+                        int width, int height,
+                        uint8_t* alpha, int alpha_stride) {
+  // alpha_and stores an 'and' operation of all the alpha[] values. The final
+  // value is not 0xff if any of the alpha[] is not equal to 0xff.
+  uint32_t alpha_and = 0xff;
+  int i, j;
+  const __m128i a_mask = _mm_set1_epi32(0xffu);  // to preserve alpha
+  const __m128i all_0xff = _mm_set_epi32(0, 0, ~0u, ~0u);
+  __m128i all_alphas = all_0xff;
+
+  // We must be able to access 3 extra bytes after the last written byte
+  // 'src[4 * width - 4]', because we don't know if alpha is the first or the
+  // last byte of the quadruplet.
+  const int limit = (width - 1) & ~7;
+
+  for (j = 0; j < height; ++j) {
+    const __m128i* src = (const __m128i*)argb;
+    for (i = 0; i < limit; i += 8) {
+      // load 32 argb bytes
+      const __m128i a0 = _mm_loadu_si128(src + 0);
+      const __m128i a1 = _mm_loadu_si128(src + 1);
+      const __m128i b0 = _mm_and_si128(a0, a_mask);
+      const __m128i b1 = _mm_and_si128(a1, a_mask);
+      const __m128i c0 = _mm_packs_epi32(b0, b1);
+      const __m128i d0 = _mm_packus_epi16(c0, c0);
+      // store
+      _mm_storel_epi64((__m128i*)&alpha[i], d0);
+      // accumulate eight alpha 'and' in parallel
+      all_alphas = _mm_and_si128(all_alphas, d0);
+      src += 2;
+    }
+    for (; i < width; ++i) {
+      const uint32_t alpha_value = argb[4 * i];
+      alpha[i] = alpha_value;
+      alpha_and &= alpha_value;
+    }
+    argb += argb_stride;
+    alpha += alpha_stride;
+  }
+  // Combine the eight alpha 'and' into a 8-bit mask.
+  alpha_and &= _mm_movemask_epi8(_mm_cmpeq_epi8(all_alphas, all_0xff));
+  return (alpha_and == 0xff);
+}
+
+//------------------------------------------------------------------------------
+// Non-dither premultiplied modes
+
+#define MULTIPLIER(a)   ((a) * 0x8081)
+#define PREMULTIPLY(x, m) (((x) * (m)) >> 23)
+
+// We can't use a 'const int' for the SHUFFLE value, because it has to be an
+// immediate in the _mm_shufflexx_epi16() instruction. We really a macro here.
+#define APPLY_ALPHA(RGBX, SHUFFLE, MASK, MULT) do {             \
+  const __m128i argb0 = _mm_loadl_epi64((__m128i*)&(RGBX));     \
+  const __m128i argb1 = _mm_unpacklo_epi8(argb0, zero);         \
+  const __m128i alpha0 = _mm_and_si128(argb1, MASK);            \
+  const __m128i alpha1 = _mm_shufflelo_epi16(alpha0, SHUFFLE);  \
+  const __m128i alpha2 = _mm_shufflehi_epi16(alpha1, SHUFFLE);  \
+  /* alpha2 = [0 a0 a0 a0][0 a1 a1 a1] */                       \
+  const __m128i scale0 = _mm_mullo_epi16(alpha2, MULT);         \
+  const __m128i scale1 = _mm_mulhi_epu16(alpha2, MULT);         \
+  const __m128i argb2 = _mm_mulhi_epu16(argb1, scale0);         \
+  const __m128i argb3 = _mm_mullo_epi16(argb1, scale1);         \
+  const __m128i argb4 = _mm_adds_epu16(argb2, argb3);           \
+  const __m128i argb5 = _mm_srli_epi16(argb4, 7);               \
+  const __m128i argb6 = _mm_or_si128(argb5, alpha0);            \
+  const __m128i argb7 = _mm_packus_epi16(argb6, zero);          \
+  _mm_storel_epi64((__m128i*)&(RGBX), argb7);                   \
+} while (0)
+
+static void ApplyAlphaMultiply(uint8_t* rgba, int alpha_first,
+                               int w, int h, int stride) {
+  const __m128i zero = _mm_setzero_si128();
+  const int kSpan = 2;
+  const int w2 = w & ~(kSpan - 1);
+  while (h-- > 0) {
+    uint32_t* const rgbx = (uint32_t*)rgba;
+    int i;
+    if (!alpha_first) {
+      const __m128i kMask = _mm_set_epi16(0xff, 0, 0, 0, 0xff, 0, 0, 0);
+      const __m128i kMult =
+          _mm_set_epi16(0, 0x8081, 0x8081, 0x8081, 0, 0x8081, 0x8081, 0x8081);
+      for (i = 0; i < w2; i += kSpan) {
+        APPLY_ALPHA(rgbx[i], _MM_SHUFFLE(0, 3, 3, 3), kMask, kMult);
+      }
+    } else {
+      const __m128i kMask = _mm_set_epi16(0, 0, 0, 0xff, 0, 0, 0, 0xff);
+      const __m128i kMult =
+          _mm_set_epi16(0x8081, 0x8081, 0x8081, 0, 0x8081, 0x8081, 0x8081, 0);
+      for (i = 0; i < w2; i += kSpan) {
+        APPLY_ALPHA(rgbx[i], _MM_SHUFFLE(0, 0, 0, 3), kMask, kMult);
+      }
+    }
+    // Finish with left-overs.
+    for (; i < w; ++i) {
+      uint8_t* const rgb = rgba + (alpha_first ? 1 : 0);
+      const uint8_t* const alpha = rgba + (alpha_first ? 0 : 3);
+      const uint32_t a = alpha[4 * i];
+      if (a != 0xff) {
+        const uint32_t mult = MULTIPLIER(a);
+        rgb[4 * i + 0] = PREMULTIPLY(rgb[4 * i + 0], mult);
+        rgb[4 * i + 1] = PREMULTIPLY(rgb[4 * i + 1], mult);
+        rgb[4 * i + 2] = PREMULTIPLY(rgb[4 * i + 2], mult);
+      }
+    }
+    rgba += stride;
+  }
+}
+#undef MULTIPLIER
+#undef PREMULTIPLY
+
+// -----------------------------------------------------------------------------
+// Apply alpha value to rows
+
+// We use: kINV255 = (1 << 24) / 255 = 0x010101
+// So: a * kINV255 = (a << 16) | [(a << 8) | a]
+// -> _mm_mulhi_epu16() takes care of the (a<<16) part,
+// and _mm_mullo_epu16(a * 0x0101,...) takes care of the "(a << 8) | a" one.
+
+static void MultARGBRow(uint32_t* const ptr, int width, int inverse) {
+  int x = 0;
+  if (!inverse) {
+    const int kSpan = 2;
+    const __m128i zero = _mm_setzero_si128();
+    const __m128i kRound =
+        _mm_set_epi16(0, 1 << 7, 1 << 7, 1 << 7, 0, 1 << 7, 1 << 7, 1 << 7);
+    const __m128i kMult =
+        _mm_set_epi16(0, 0x0101, 0x0101, 0x0101, 0, 0x0101, 0x0101, 0x0101);
+    const __m128i kOne64 = _mm_set_epi16(1u << 8, 0, 0, 0, 1u << 8, 0, 0, 0);
+    const int w2 = width & ~(kSpan - 1);
+    for (x = 0; x < w2; x += kSpan) {
+      const __m128i argb0 = _mm_loadl_epi64((__m128i*)&ptr[x]);
+      const __m128i argb1 = _mm_unpacklo_epi8(argb0, zero);
+      const __m128i tmp0 = _mm_shufflelo_epi16(argb1, _MM_SHUFFLE(3, 3, 3, 3));
+      const __m128i tmp1 = _mm_shufflehi_epi16(tmp0, _MM_SHUFFLE(3, 3, 3, 3));
+      const __m128i tmp2 = _mm_srli_epi64(tmp1, 16);
+      const __m128i scale0 = _mm_mullo_epi16(tmp1, kMult);
+      const __m128i scale1 = _mm_or_si128(tmp2, kOne64);
+      const __m128i argb2 = _mm_mulhi_epu16(argb1, scale0);
+      const __m128i argb3 = _mm_mullo_epi16(argb1, scale1);
+      const __m128i argb4 = _mm_adds_epu16(argb2, argb3);
+      const __m128i argb5 = _mm_adds_epu16(argb4, kRound);
+      const __m128i argb6 = _mm_srli_epi16(argb5, 8);
+      const __m128i argb7 = _mm_packus_epi16(argb6, zero);
+      _mm_storel_epi64((__m128i*)&ptr[x], argb7);
+    }
+  }
+  width -= x;
+  if (width > 0) WebPMultARGBRowC(ptr + x, width, inverse);
+}
+
+static void MultRow(uint8_t* const ptr, const uint8_t* const alpha,
+                    int width, int inverse) {
+  int x = 0;
+  if (!inverse) {
+    const int kSpan = 8;
+    const __m128i zero = _mm_setzero_si128();
+    const __m128i kRound = _mm_set1_epi16(1 << 7);
+    const int w2 = width & ~(kSpan - 1);
+    for (x = 0; x < w2; x += kSpan) {
+      const __m128i v0 = _mm_loadl_epi64((__m128i*)&ptr[x]);
+      const __m128i v1 = _mm_unpacklo_epi8(v0, zero);
+      const __m128i alpha0 = _mm_loadl_epi64((const __m128i*)&alpha[x]);
+      const __m128i alpha1 = _mm_unpacklo_epi8(alpha0, zero);
+      const __m128i alpha2 = _mm_unpacklo_epi8(alpha0, alpha0);
+      const __m128i v2 = _mm_mulhi_epu16(v1, alpha2);
+      const __m128i v3 = _mm_mullo_epi16(v1, alpha1);
+      const __m128i v4 = _mm_adds_epu16(v2, v3);
+      const __m128i v5 = _mm_adds_epu16(v4, kRound);
+      const __m128i v6 = _mm_srli_epi16(v5, 8);
+      const __m128i v7 = _mm_packus_epi16(v6, zero);
+      _mm_storel_epi64((__m128i*)&ptr[x], v7);
+    }
+  }
+  width -= x;
+  if (width > 0) WebPMultRowC(ptr + x, alpha + x, width, inverse);
+}
+
+#endif   // WEBP_USE_SSE2
+
+//------------------------------------------------------------------------------
+// Init function
+
+extern void WebPInitAlphaProcessingSSE2(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void WebPInitAlphaProcessingSSE2(void) {
+#if defined(WEBP_USE_SSE2)
+  WebPMultARGBRow = MultARGBRow;
+  WebPMultRow = MultRow;
+  WebPApplyAlphaMultiply = ApplyAlphaMultiply;
+  WebPDispatchAlpha = DispatchAlpha;
+  WebPDispatchAlphaToGreen = DispatchAlphaToGreen;
+  WebPExtractAlpha = ExtractAlpha;
+#endif
+}
diff --git a/Source/LibWebP/src/dsp/dsp.argb.c b/Source/LibWebP/src/dsp/dsp.argb.c
new file mode 100644
index 0000000..dbfa08b
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.argb.c
@@ -0,0 +1,68 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+//   ARGB making functions.
+//
+// Author: Djordje Pesut (djordje.pesut at imgtec.com)
+
+#include "./dsp.h"
+
+static WEBP_INLINE uint32_t MakeARGB32(int a, int r, int g, int b) {
+  return (((uint32_t)a << 24) | (r << 16) | (g << 8) | b);
+}
+
+static void PackARGB(const uint8_t* a, const uint8_t* r, const uint8_t* g,
+                     const uint8_t* b, int len, uint32_t* out) {
+  int i;
+  for (i = 0; i < len; ++i) {
+    out[i] = MakeARGB32(a[4 * i], r[4 * i], g[4 * i], b[4 * i]);
+  }
+}
+
+static void PackRGB(const uint8_t* r, const uint8_t* g, const uint8_t* b,
+                    int len, int step, uint32_t* out) {
+  int i, offset = 0;
+  for (i = 0; i < len; ++i) {
+    out[i] = MakeARGB32(0xff, r[offset], g[offset], b[offset]);
+    offset += step;
+  }
+}
+
+void (*VP8PackARGB)(const uint8_t*, const uint8_t*, const uint8_t*,
+                    const uint8_t*, int, uint32_t*);
+void (*VP8PackRGB)(const uint8_t*, const uint8_t*, const uint8_t*,
+                   int, int, uint32_t*);
+
+extern void VP8EncDspARGBInitMIPSdspR2(void);
+extern void VP8EncDspARGBInitSSE2(void);
+
+static volatile VP8CPUInfo argb_last_cpuinfo_used =
+    (VP8CPUInfo)&argb_last_cpuinfo_used;
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspARGBInit(void) {
+  if (argb_last_cpuinfo_used == VP8GetCPUInfo) return;
+
+  VP8PackARGB = PackARGB;
+  VP8PackRGB = PackRGB;
+
+  // If defined, use CPUInfo() to overwrite some pointers with faster versions.
+  if (VP8GetCPUInfo != NULL) {
+#if defined(WEBP_USE_SSE2)
+    if (VP8GetCPUInfo(kSSE2)) {
+      VP8EncDspARGBInitSSE2();
+    }
+#endif
+#if defined(WEBP_USE_MIPS_DSP_R2)
+    if (VP8GetCPUInfo(kMIPSdspR2)) {
+      VP8EncDspARGBInitMIPSdspR2();
+    }
+#endif
+  }
+  argb_last_cpuinfo_used = VP8GetCPUInfo;
+}
diff --git a/Source/LibWebP/src/dsp/dsp.argb_mips_dsp_r2.c b/Source/LibWebP/src/dsp/dsp.argb_mips_dsp_r2.c
new file mode 100644
index 0000000..6166c20
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.argb_mips_dsp_r2.c
@@ -0,0 +1,108 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+//   ARGB making functions (mips version).
+//
+// Author: Djordje Pesut (djordje.pesut at imgtec.com)
+
+#include "./dsp.h"
+
+#if defined(WEBP_USE_MIPS_DSP_R2)
+
+static void PackARGB(const uint8_t* a, const uint8_t* r, const uint8_t* g,
+                     const uint8_t* b, int len, uint32_t* out) {
+  int temp0, temp1, temp2, temp3, offset;
+  const int rest = len & 1;
+  const uint32_t* const loop_end = out + len - rest;
+  const int step = 4;
+  __asm__ volatile (
+    "xor          %[offset],   %[offset], %[offset]    \n\t"
+    "beq          %[loop_end], %[out],    0f           \n\t"
+  "2:                                                  \n\t"
+    "lbux         %[temp0],    %[offset](%[a])         \n\t"
+    "lbux         %[temp1],    %[offset](%[r])         \n\t"
+    "lbux         %[temp2],    %[offset](%[g])         \n\t"
+    "lbux         %[temp3],    %[offset](%[b])         \n\t"
+    "ins          %[temp1],    %[temp0],  16,     16   \n\t"
+    "ins          %[temp3],    %[temp2],  16,     16   \n\t"
+    "addiu        %[out],      %[out],    4            \n\t"
+    "precr.qb.ph  %[temp0],    %[temp1],  %[temp3]     \n\t"
+    "sw           %[temp0],    -4(%[out])              \n\t"
+    "addu         %[offset],   %[offset], %[step]      \n\t"
+    "bne          %[loop_end], %[out],    2b           \n\t"
+  "0:                                                  \n\t"
+    "beq          %[rest],     $zero,     1f           \n\t"
+    "lbux         %[temp0],    %[offset](%[a])         \n\t"
+    "lbux         %[temp1],    %[offset](%[r])         \n\t"
+    "lbux         %[temp2],    %[offset](%[g])         \n\t"
+    "lbux         %[temp3],    %[offset](%[b])         \n\t"
+    "ins          %[temp1],    %[temp0],  16,     16   \n\t"
+    "ins          %[temp3],    %[temp2],  16,     16   \n\t"
+    "precr.qb.ph  %[temp0],    %[temp1],  %[temp3]     \n\t"
+    "sw           %[temp0],    0(%[out])               \n\t"
+  "1:                                                  \n\t"
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [temp3]"=&r"(temp3), [offset]"=&r"(offset), [out]"+&r"(out)
+    : [a]"r"(a), [r]"r"(r), [g]"r"(g), [b]"r"(b), [step]"r"(step),
+      [loop_end]"r"(loop_end), [rest]"r"(rest)
+    : "memory"
+  );
+}
+
+static void PackRGB(const uint8_t* r, const uint8_t* g, const uint8_t* b,
+                    int len, int step, uint32_t* out) {
+  int temp0, temp1, temp2, offset;
+  const int rest = len & 1;
+  const int a = 0xff;
+  const uint32_t* const loop_end = out + len - rest;
+  __asm__ volatile (
+    "xor          %[offset],   %[offset], %[offset]    \n\t"
+    "beq          %[loop_end], %[out],    0f           \n\t"
+  "2:                                                  \n\t"
+    "lbux         %[temp0],    %[offset](%[r])         \n\t"
+    "lbux         %[temp1],    %[offset](%[g])         \n\t"
+    "lbux         %[temp2],    %[offset](%[b])         \n\t"
+    "ins          %[temp0],    %[a],      16,     16   \n\t"
+    "ins          %[temp2],    %[temp1],  16,     16   \n\t"
+    "addiu        %[out],      %[out],    4            \n\t"
+    "precr.qb.ph  %[temp0],    %[temp0],  %[temp2]     \n\t"
+    "sw           %[temp0],    -4(%[out])              \n\t"
+    "addu         %[offset],   %[offset], %[step]      \n\t"
+    "bne          %[loop_end], %[out],    2b           \n\t"
+  "0:                                                  \n\t"
+    "beq          %[rest],     $zero,     1f           \n\t"
+    "lbux         %[temp0],    %[offset](%[r])         \n\t"
+    "lbux         %[temp1],    %[offset](%[g])         \n\t"
+    "lbux         %[temp2],    %[offset](%[b])         \n\t"
+    "ins          %[temp0],    %[a],      16,     16   \n\t"
+    "ins          %[temp2],    %[temp1],  16,     16   \n\t"
+    "precr.qb.ph  %[temp0],    %[temp0],  %[temp2]     \n\t"
+    "sw           %[temp0],    0(%[out])               \n\t"
+  "1:                                                  \n\t"
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [offset]"=&r"(offset), [out]"+&r"(out)
+    : [a]"r"(a), [r]"r"(r), [g]"r"(g), [b]"r"(b), [step]"r"(step),
+      [loop_end]"r"(loop_end), [rest]"r"(rest)
+    : "memory"
+  );
+}
+
+#endif  // WEBP_USE_MIPS_DSP_R2
+
+//------------------------------------------------------------------------------
+// Entry point
+
+extern void VP8EncDspARGBInitMIPSdspR2(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspARGBInitMIPSdspR2(void) {
+#if defined(WEBP_USE_MIPS_DSP_R2)
+  VP8PackARGB = PackARGB;
+  VP8PackRGB = PackRGB;
+#endif  // WEBP_USE_MIPS_DSP_R2
+}
diff --git a/Source/LibWebP/src/dsp/dsp.argb_sse2.c b/Source/LibWebP/src/dsp/dsp.argb_sse2.c
new file mode 100644
index 0000000..3aa738f
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.argb_sse2.c
@@ -0,0 +1,62 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+//   ARGB making functions (SSE2 version).
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include "./dsp.h"
+
+#if defined(WEBP_USE_SSE2)
+
+#include <assert.h>
+#include <emmintrin.h>
+#include <string.h>
+
+static WEBP_INLINE uint32_t MakeARGB32(int a, int r, int g, int b) {
+  return (((uint32_t)a << 24) | (r << 16) | (g << 8) | b);
+}
+
+static void PackARGB(const uint8_t* a, const uint8_t* r, const uint8_t* g,
+                     const uint8_t* b, int len, uint32_t* out) {
+  if (g == r + 1) {  // RGBA input order. Need to swap R and B.
+    int i = 0;
+    const int len_max = len & ~3;  // max length processed in main loop
+    const __m128i red_blue_mask = _mm_set1_epi32(0x00ff00ffu);
+    assert(b == r + 2);
+    assert(a == r + 3);
+    for (; i < len_max; i += 4) {
+      const __m128i A = _mm_loadu_si128((const __m128i*)(r + 4 * i));
+      const __m128i B = _mm_and_si128(A, red_blue_mask);     // R 0 B 0
+      const __m128i C = _mm_andnot_si128(red_blue_mask, A);  // 0 G 0 A
+      const __m128i D = _mm_shufflelo_epi16(B, _MM_SHUFFLE(2, 3, 0, 1));
+      const __m128i E = _mm_shufflehi_epi16(D, _MM_SHUFFLE(2, 3, 0, 1));
+      const __m128i F = _mm_or_si128(E, C);
+      _mm_storeu_si128((__m128i*)(out + i), F);
+    }
+    for (; i < len; ++i) {
+      out[i] = MakeARGB32(a[4 * i], r[4 * i], g[4 * i], b[4 * i]);
+    }
+  } else {
+    assert(g == b + 1);
+    assert(r == b + 2);
+    assert(a == b + 3);
+    memcpy(out, b, len * 4);
+  }
+}
+
+#endif    // WEBP_USE_SSE2
+
+extern void VP8EncDspARGBInitSSE2(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspARGBInitSSE2(void) {
+#if defined(WEBP_USE_SSE2)
+  VP8PackARGB = PackARGB;
+#endif
+}
diff --git a/Source/LibWebP/src/dsp/dsp.cost.c b/Source/LibWebP/src/dsp/dsp.cost.c
new file mode 100644
index 0000000..4fda42a
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.cost.c
@@ -0,0 +1,412 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include "./dsp.h"
+#include "../enc/cost.h"
+
+//------------------------------------------------------------------------------
+// Boolean-cost cost table
+
+const uint16_t VP8EntropyCost[256] = {
+  1792, 1792, 1792, 1536, 1536, 1408, 1366, 1280, 1280, 1216,
+  1178, 1152, 1110, 1076, 1061, 1024, 1024,  992,  968,  951,
+   939,  911,  896,  878,  871,  854,  838,  820,  811,  794,
+   786,  768,  768,  752,  740,  732,  720,  709,  704,  690,
+   683,  672,  666,  655,  647,  640,  631,  622,  615,  607,
+   598,  592,  586,  576,  572,  564,  559,  555,  547,  541,
+   534,  528,  522,  512,  512,  504,  500,  494,  488,  483,
+   477,  473,  467,  461,  458,  452,  448,  443,  438,  434,
+   427,  424,  419,  415,  410,  406,  403,  399,  394,  390,
+   384,  384,  377,  374,  370,  366,  362,  359,  355,  351,
+   347,  342,  342,  336,  333,  330,  326,  323,  320,  316,
+   312,  308,  305,  302,  299,  296,  293,  288,  287,  283,
+   280,  277,  274,  272,  268,  266,  262,  256,  256,  256,
+   251,  248,  245,  242,  240,  237,  234,  232,  228,  226,
+   223,  221,  218,  216,  214,  211,  208,  205,  203,  201,
+   198,  196,  192,  191,  188,  187,  183,  181,  179,  176,
+   175,  171,  171,  168,  165,  163,  160,  159,  156,  154,
+   152,  150,  148,  146,  144,  142,  139,  138,  135,  133,
+   131,  128,  128,  125,  123,  121,  119,  117,  115,  113,
+   111,  110,  107,  105,  103,  102,  100,   98,   96,   94,
+    92,   91,   89,   86,   86,   83,   82,   80,   77,   76,
+    74,   73,   71,   69,   67,   66,   64,   63,   61,   59,
+    57,   55,   54,   52,   51,   49,   47,   46,   44,   43,
+    41,   40,   38,   36,   35,   33,   32,   30,   29,   27,
+    25,   24,   22,   21,   19,   18,   16,   15,   13,   12,
+    10,    9,    7,    6,    4,    3
+};
+
+//------------------------------------------------------------------------------
+// Level cost tables
+
+// fixed costs for coding levels, deduce from the coding tree.
+// This is only the part that doesn't depend on the probability state.
+const uint16_t VP8LevelFixedCosts[MAX_LEVEL + 1] = {
+     0,  256,  256,  256,  256,  432,  618,  630,
+   731,  640,  640,  828,  901,  948, 1021, 1101,
+  1174, 1221, 1294, 1042, 1085, 1115, 1158, 1202,
+  1245, 1275, 1318, 1337, 1380, 1410, 1453, 1497,
+  1540, 1570, 1613, 1280, 1295, 1317, 1332, 1358,
+  1373, 1395, 1410, 1454, 1469, 1491, 1506, 1532,
+  1547, 1569, 1584, 1601, 1616, 1638, 1653, 1679,
+  1694, 1716, 1731, 1775, 1790, 1812, 1827, 1853,
+  1868, 1890, 1905, 1727, 1733, 1742, 1748, 1759,
+  1765, 1774, 1780, 1800, 1806, 1815, 1821, 1832,
+  1838, 1847, 1853, 1878, 1884, 1893, 1899, 1910,
+  1916, 1925, 1931, 1951, 1957, 1966, 1972, 1983,
+  1989, 1998, 2004, 2027, 2033, 2042, 2048, 2059,
+  2065, 2074, 2080, 2100, 2106, 2115, 2121, 2132,
+  2138, 2147, 2153, 2178, 2184, 2193, 2199, 2210,
+  2216, 2225, 2231, 2251, 2257, 2266, 2272, 2283,
+  2289, 2298, 2304, 2168, 2174, 2183, 2189, 2200,
+  2206, 2215, 2221, 2241, 2247, 2256, 2262, 2273,
+  2279, 2288, 2294, 2319, 2325, 2334, 2340, 2351,
+  2357, 2366, 2372, 2392, 2398, 2407, 2413, 2424,
+  2430, 2439, 2445, 2468, 2474, 2483, 2489, 2500,
+  2506, 2515, 2521, 2541, 2547, 2556, 2562, 2573,
+  2579, 2588, 2594, 2619, 2625, 2634, 2640, 2651,
+  2657, 2666, 2672, 2692, 2698, 2707, 2713, 2724,
+  2730, 2739, 2745, 2540, 2546, 2555, 2561, 2572,
+  2578, 2587, 2593, 2613, 2619, 2628, 2634, 2645,
+  2651, 2660, 2666, 2691, 2697, 2706, 2712, 2723,
+  2729, 2738, 2744, 2764, 2770, 2779, 2785, 2796,
+  2802, 2811, 2817, 2840, 2846, 2855, 2861, 2872,
+  2878, 2887, 2893, 2913, 2919, 2928, 2934, 2945,
+  2951, 2960, 2966, 2991, 2997, 3006, 3012, 3023,
+  3029, 3038, 3044, 3064, 3070, 3079, 3085, 3096,
+  3102, 3111, 3117, 2981, 2987, 2996, 3002, 3013,
+  3019, 3028, 3034, 3054, 3060, 3069, 3075, 3086,
+  3092, 3101, 3107, 3132, 3138, 3147, 3153, 3164,
+  3170, 3179, 3185, 3205, 3211, 3220, 3226, 3237,
+  3243, 3252, 3258, 3281, 3287, 3296, 3302, 3313,
+  3319, 3328, 3334, 3354, 3360, 3369, 3375, 3386,
+  3392, 3401, 3407, 3432, 3438, 3447, 3453, 3464,
+  3470, 3479, 3485, 3505, 3511, 3520, 3526, 3537,
+  3543, 3552, 3558, 2816, 2822, 2831, 2837, 2848,
+  2854, 2863, 2869, 2889, 2895, 2904, 2910, 2921,
+  2927, 2936, 2942, 2967, 2973, 2982, 2988, 2999,
+  3005, 3014, 3020, 3040, 3046, 3055, 3061, 3072,
+  3078, 3087, 3093, 3116, 3122, 3131, 3137, 3148,
+  3154, 3163, 3169, 3189, 3195, 3204, 3210, 3221,
+  3227, 3236, 3242, 3267, 3273, 3282, 3288, 3299,
+  3305, 3314, 3320, 3340, 3346, 3355, 3361, 3372,
+  3378, 3387, 3393, 3257, 3263, 3272, 3278, 3289,
+  3295, 3304, 3310, 3330, 3336, 3345, 3351, 3362,
+  3368, 3377, 3383, 3408, 3414, 3423, 3429, 3440,
+  3446, 3455, 3461, 3481, 3487, 3496, 3502, 3513,
+  3519, 3528, 3534, 3557, 3563, 3572, 3578, 3589,
+  3595, 3604, 3610, 3630, 3636, 3645, 3651, 3662,
+  3668, 3677, 3683, 3708, 3714, 3723, 3729, 3740,
+  3746, 3755, 3761, 3781, 3787, 3796, 3802, 3813,
+  3819, 3828, 3834, 3629, 3635, 3644, 3650, 3661,
+  3667, 3676, 3682, 3702, 3708, 3717, 3723, 3734,
+  3740, 3749, 3755, 3780, 3786, 3795, 3801, 3812,
+  3818, 3827, 3833, 3853, 3859, 3868, 3874, 3885,
+  3891, 3900, 3906, 3929, 3935, 3944, 3950, 3961,
+  3967, 3976, 3982, 4002, 4008, 4017, 4023, 4034,
+  4040, 4049, 4055, 4080, 4086, 4095, 4101, 4112,
+  4118, 4127, 4133, 4153, 4159, 4168, 4174, 4185,
+  4191, 4200, 4206, 4070, 4076, 4085, 4091, 4102,
+  4108, 4117, 4123, 4143, 4149, 4158, 4164, 4175,
+  4181, 4190, 4196, 4221, 4227, 4236, 4242, 4253,
+  4259, 4268, 4274, 4294, 4300, 4309, 4315, 4326,
+  4332, 4341, 4347, 4370, 4376, 4385, 4391, 4402,
+  4408, 4417, 4423, 4443, 4449, 4458, 4464, 4475,
+  4481, 4490, 4496, 4521, 4527, 4536, 4542, 4553,
+  4559, 4568, 4574, 4594, 4600, 4609, 4615, 4626,
+  4632, 4641, 4647, 3515, 3521, 3530, 3536, 3547,
+  3553, 3562, 3568, 3588, 3594, 3603, 3609, 3620,
+  3626, 3635, 3641, 3666, 3672, 3681, 3687, 3698,
+  3704, 3713, 3719, 3739, 3745, 3754, 3760, 3771,
+  3777, 3786, 3792, 3815, 3821, 3830, 3836, 3847,
+  3853, 3862, 3868, 3888, 3894, 3903, 3909, 3920,
+  3926, 3935, 3941, 3966, 3972, 3981, 3987, 3998,
+  4004, 4013, 4019, 4039, 4045, 4054, 4060, 4071,
+  4077, 4086, 4092, 3956, 3962, 3971, 3977, 3988,
+  3994, 4003, 4009, 4029, 4035, 4044, 4050, 4061,
+  4067, 4076, 4082, 4107, 4113, 4122, 4128, 4139,
+  4145, 4154, 4160, 4180, 4186, 4195, 4201, 4212,
+  4218, 4227, 4233, 4256, 4262, 4271, 4277, 4288,
+  4294, 4303, 4309, 4329, 4335, 4344, 4350, 4361,
+  4367, 4376, 4382, 4407, 4413, 4422, 4428, 4439,
+  4445, 4454, 4460, 4480, 4486, 4495, 4501, 4512,
+  4518, 4527, 4533, 4328, 4334, 4343, 4349, 4360,
+  4366, 4375, 4381, 4401, 4407, 4416, 4422, 4433,
+  4439, 4448, 4454, 4479, 4485, 4494, 4500, 4511,
+  4517, 4526, 4532, 4552, 4558, 4567, 4573, 4584,
+  4590, 4599, 4605, 4628, 4634, 4643, 4649, 4660,
+  4666, 4675, 4681, 4701, 4707, 4716, 4722, 4733,
+  4739, 4748, 4754, 4779, 4785, 4794, 4800, 4811,
+  4817, 4826, 4832, 4852, 4858, 4867, 4873, 4884,
+  4890, 4899, 4905, 4769, 4775, 4784, 4790, 4801,
+  4807, 4816, 4822, 4842, 4848, 4857, 4863, 4874,
+  4880, 4889, 4895, 4920, 4926, 4935, 4941, 4952,
+  4958, 4967, 4973, 4993, 4999, 5008, 5014, 5025,
+  5031, 5040, 5046, 5069, 5075, 5084, 5090, 5101,
+  5107, 5116, 5122, 5142, 5148, 5157, 5163, 5174,
+  5180, 5189, 5195, 5220, 5226, 5235, 5241, 5252,
+  5258, 5267, 5273, 5293, 5299, 5308, 5314, 5325,
+  5331, 5340, 5346, 4604, 4610, 4619, 4625, 4636,
+  4642, 4651, 4657, 4677, 4683, 4692, 4698, 4709,
+  4715, 4724, 4730, 4755, 4761, 4770, 4776, 4787,
+  4793, 4802, 4808, 4828, 4834, 4843, 4849, 4860,
+  4866, 4875, 4881, 4904, 4910, 4919, 4925, 4936,
+  4942, 4951, 4957, 4977, 4983, 4992, 4998, 5009,
+  5015, 5024, 5030, 5055, 5061, 5070, 5076, 5087,
+  5093, 5102, 5108, 5128, 5134, 5143, 5149, 5160,
+  5166, 5175, 5181, 5045, 5051, 5060, 5066, 5077,
+  5083, 5092, 5098, 5118, 5124, 5133, 5139, 5150,
+  5156, 5165, 5171, 5196, 5202, 5211, 5217, 5228,
+  5234, 5243, 5249, 5269, 5275, 5284, 5290, 5301,
+  5307, 5316, 5322, 5345, 5351, 5360, 5366, 5377,
+  5383, 5392, 5398, 5418, 5424, 5433, 5439, 5450,
+  5456, 5465, 5471, 5496, 5502, 5511, 5517, 5528,
+  5534, 5543, 5549, 5569, 5575, 5584, 5590, 5601,
+  5607, 5616, 5622, 5417, 5423, 5432, 5438, 5449,
+  5455, 5464, 5470, 5490, 5496, 5505, 5511, 5522,
+  5528, 5537, 5543, 5568, 5574, 5583, 5589, 5600,
+  5606, 5615, 5621, 5641, 5647, 5656, 5662, 5673,
+  5679, 5688, 5694, 5717, 5723, 5732, 5738, 5749,
+  5755, 5764, 5770, 5790, 5796, 5805, 5811, 5822,
+  5828, 5837, 5843, 5868, 5874, 5883, 5889, 5900,
+  5906, 5915, 5921, 5941, 5947, 5956, 5962, 5973,
+  5979, 5988, 5994, 5858, 5864, 5873, 5879, 5890,
+  5896, 5905, 5911, 5931, 5937, 5946, 5952, 5963,
+  5969, 5978, 5984, 6009, 6015, 6024, 6030, 6041,
+  6047, 6056, 6062, 6082, 6088, 6097, 6103, 6114,
+  6120, 6129, 6135, 6158, 6164, 6173, 6179, 6190,
+  6196, 6205, 6211, 6231, 6237, 6246, 6252, 6263,
+  6269, 6278, 6284, 6309, 6315, 6324, 6330, 6341,
+  6347, 6356, 6362, 6382, 6388, 6397, 6403, 6414,
+  6420, 6429, 6435, 3515, 3521, 3530, 3536, 3547,
+  3553, 3562, 3568, 3588, 3594, 3603, 3609, 3620,
+  3626, 3635, 3641, 3666, 3672, 3681, 3687, 3698,
+  3704, 3713, 3719, 3739, 3745, 3754, 3760, 3771,
+  3777, 3786, 3792, 3815, 3821, 3830, 3836, 3847,
+  3853, 3862, 3868, 3888, 3894, 3903, 3909, 3920,
+  3926, 3935, 3941, 3966, 3972, 3981, 3987, 3998,
+  4004, 4013, 4019, 4039, 4045, 4054, 4060, 4071,
+  4077, 4086, 4092, 3956, 3962, 3971, 3977, 3988,
+  3994, 4003, 4009, 4029, 4035, 4044, 4050, 4061,
+  4067, 4076, 4082, 4107, 4113, 4122, 4128, 4139,
+  4145, 4154, 4160, 4180, 4186, 4195, 4201, 4212,
+  4218, 4227, 4233, 4256, 4262, 4271, 4277, 4288,
+  4294, 4303, 4309, 4329, 4335, 4344, 4350, 4361,
+  4367, 4376, 4382, 4407, 4413, 4422, 4428, 4439,
+  4445, 4454, 4460, 4480, 4486, 4495, 4501, 4512,
+  4518, 4527, 4533, 4328, 4334, 4343, 4349, 4360,
+  4366, 4375, 4381, 4401, 4407, 4416, 4422, 4433,
+  4439, 4448, 4454, 4479, 4485, 4494, 4500, 4511,
+  4517, 4526, 4532, 4552, 4558, 4567, 4573, 4584,
+  4590, 4599, 4605, 4628, 4634, 4643, 4649, 4660,
+  4666, 4675, 4681, 4701, 4707, 4716, 4722, 4733,
+  4739, 4748, 4754, 4779, 4785, 4794, 4800, 4811,
+  4817, 4826, 4832, 4852, 4858, 4867, 4873, 4884,
+  4890, 4899, 4905, 4769, 4775, 4784, 4790, 4801,
+  4807, 4816, 4822, 4842, 4848, 4857, 4863, 4874,
+  4880, 4889, 4895, 4920, 4926, 4935, 4941, 4952,
+  4958, 4967, 4973, 4993, 4999, 5008, 5014, 5025,
+  5031, 5040, 5046, 5069, 5075, 5084, 5090, 5101,
+  5107, 5116, 5122, 5142, 5148, 5157, 5163, 5174,
+  5180, 5189, 5195, 5220, 5226, 5235, 5241, 5252,
+  5258, 5267, 5273, 5293, 5299, 5308, 5314, 5325,
+  5331, 5340, 5346, 4604, 4610, 4619, 4625, 4636,
+  4642, 4651, 4657, 4677, 4683, 4692, 4698, 4709,
+  4715, 4724, 4730, 4755, 4761, 4770, 4776, 4787,
+  4793, 4802, 4808, 4828, 4834, 4843, 4849, 4860,
+  4866, 4875, 4881, 4904, 4910, 4919, 4925, 4936,
+  4942, 4951, 4957, 4977, 4983, 4992, 4998, 5009,
+  5015, 5024, 5030, 5055, 5061, 5070, 5076, 5087,
+  5093, 5102, 5108, 5128, 5134, 5143, 5149, 5160,
+  5166, 5175, 5181, 5045, 5051, 5060, 5066, 5077,
+  5083, 5092, 5098, 5118, 5124, 5133, 5139, 5150,
+  5156, 5165, 5171, 5196, 5202, 5211, 5217, 5228,
+  5234, 5243, 5249, 5269, 5275, 5284, 5290, 5301,
+  5307, 5316, 5322, 5345, 5351, 5360, 5366, 5377,
+  5383, 5392, 5398, 5418, 5424, 5433, 5439, 5450,
+  5456, 5465, 5471, 5496, 5502, 5511, 5517, 5528,
+  5534, 5543, 5549, 5569, 5575, 5584, 5590, 5601,
+  5607, 5616, 5622, 5417, 5423, 5432, 5438, 5449,
+  5455, 5464, 5470, 5490, 5496, 5505, 5511, 5522,
+  5528, 5537, 5543, 5568, 5574, 5583, 5589, 5600,
+  5606, 5615, 5621, 5641, 5647, 5656, 5662, 5673,
+  5679, 5688, 5694, 5717, 5723, 5732, 5738, 5749,
+  5755, 5764, 5770, 5790, 5796, 5805, 5811, 5822,
+  5828, 5837, 5843, 5868, 5874, 5883, 5889, 5900,
+  5906, 5915, 5921, 5941, 5947, 5956, 5962, 5973,
+  5979, 5988, 5994, 5858, 5864, 5873, 5879, 5890,
+  5896, 5905, 5911, 5931, 5937, 5946, 5952, 5963,
+  5969, 5978, 5984, 6009, 6015, 6024, 6030, 6041,
+  6047, 6056, 6062, 6082, 6088, 6097, 6103, 6114,
+  6120, 6129, 6135, 6158, 6164, 6173, 6179, 6190,
+  6196, 6205, 6211, 6231, 6237, 6246, 6252, 6263,
+  6269, 6278, 6284, 6309, 6315, 6324, 6330, 6341,
+  6347, 6356, 6362, 6382, 6388, 6397, 6403, 6414,
+  6420, 6429, 6435, 5303, 5309, 5318, 5324, 5335,
+  5341, 5350, 5356, 5376, 5382, 5391, 5397, 5408,
+  5414, 5423, 5429, 5454, 5460, 5469, 5475, 5486,
+  5492, 5501, 5507, 5527, 5533, 5542, 5548, 5559,
+  5565, 5574, 5580, 5603, 5609, 5618, 5624, 5635,
+  5641, 5650, 5656, 5676, 5682, 5691, 5697, 5708,
+  5714, 5723, 5729, 5754, 5760, 5769, 5775, 5786,
+  5792, 5801, 5807, 5827, 5833, 5842, 5848, 5859,
+  5865, 5874, 5880, 5744, 5750, 5759, 5765, 5776,
+  5782, 5791, 5797, 5817, 5823, 5832, 5838, 5849,
+  5855, 5864, 5870, 5895, 5901, 5910, 5916, 5927,
+  5933, 5942, 5948, 5968, 5974, 5983, 5989, 6000,
+  6006, 6015, 6021, 6044, 6050, 6059, 6065, 6076,
+  6082, 6091, 6097, 6117, 6123, 6132, 6138, 6149,
+  6155, 6164, 6170, 6195, 6201, 6210, 6216, 6227,
+  6233, 6242, 6248, 6268, 6274, 6283, 6289, 6300,
+  6306, 6315, 6321, 6116, 6122, 6131, 6137, 6148,
+  6154, 6163, 6169, 6189, 6195, 6204, 6210, 6221,
+  6227, 6236, 6242, 6267, 6273, 6282, 6288, 6299,
+  6305, 6314, 6320, 6340, 6346, 6355, 6361, 6372,
+  6378, 6387, 6393, 6416, 6422, 6431, 6437, 6448,
+  6454, 6463, 6469, 6489, 6495, 6504, 6510, 6521,
+  6527, 6536, 6542, 6567, 6573, 6582, 6588, 6599,
+  6605, 6614, 6620, 6640, 6646, 6655, 6661, 6672,
+  6678, 6687, 6693, 6557, 6563, 6572, 6578, 6589,
+  6595, 6604, 6610, 6630, 6636, 6645, 6651, 6662,
+  6668, 6677, 6683, 6708, 6714, 6723, 6729, 6740,
+  6746, 6755, 6761, 6781, 6787, 6796, 6802, 6813,
+  6819, 6828, 6834, 6857, 6863, 6872, 6878, 6889,
+  6895, 6904, 6910, 6930, 6936, 6945, 6951, 6962,
+  6968, 6977, 6983, 7008, 7014, 7023, 7029, 7040,
+  7046, 7055, 7061, 7081, 7087, 7096, 7102, 7113,
+  7119, 7128, 7134, 6392, 6398, 6407, 6413, 6424,
+  6430, 6439, 6445, 6465, 6471, 6480, 6486, 6497,
+  6503, 6512, 6518, 6543, 6549, 6558, 6564, 6575,
+  6581, 6590, 6596, 6616, 6622, 6631, 6637, 6648,
+  6654, 6663, 6669, 6692, 6698, 6707, 6713, 6724,
+  6730, 6739, 6745, 6765, 6771, 6780, 6786, 6797,
+  6803, 6812, 6818, 6843, 6849, 6858, 6864, 6875,
+  6881, 6890, 6896, 6916, 6922, 6931, 6937, 6948,
+  6954, 6963, 6969, 6833, 6839, 6848, 6854, 6865,
+  6871, 6880, 6886, 6906, 6912, 6921, 6927, 6938,
+  6944, 6953, 6959, 6984, 6990, 6999, 7005, 7016,
+  7022, 7031, 7037, 7057, 7063, 7072, 7078, 7089,
+  7095, 7104, 7110, 7133, 7139, 7148, 7154, 7165,
+  7171, 7180, 7186, 7206, 7212, 7221, 7227, 7238,
+  7244, 7253, 7259, 7284, 7290, 7299, 7305, 7316,
+  7322, 7331, 7337, 7357, 7363, 7372, 7378, 7389,
+  7395, 7404, 7410, 7205, 7211, 7220, 7226, 7237,
+  7243, 7252, 7258, 7278, 7284, 7293, 7299, 7310,
+  7316, 7325, 7331, 7356, 7362, 7371, 7377, 7388,
+  7394, 7403, 7409, 7429, 7435, 7444, 7450, 7461,
+  7467, 7476, 7482, 7505, 7511, 7520, 7526, 7537,
+  7543, 7552, 7558, 7578, 7584, 7593, 7599, 7610,
+  7616, 7625, 7631, 7656, 7662, 7671, 7677, 7688,
+  7694, 7703, 7709, 7729, 7735, 7744, 7750, 7761
+};
+
+//------------------------------------------------------------------------------
+// Tables for level coding
+
+const uint8_t VP8EncBands[16 + 1] = {
+  0, 1, 2, 3, 6, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7,
+  0  // sentinel
+};
+
+//------------------------------------------------------------------------------
+// Mode costs
+
+static int GetResidualCost(int ctx0, const VP8Residual* const res) {
+  int n = res->first;
+  // should be prob[VP8EncBands[n]], but it's equivalent for n=0 or 1
+  const int p0 = res->prob[n][ctx0][0];
+  CostArrayPtr const costs = res->costs;
+  const uint16_t* t = costs[n][ctx0];
+  // bit_cost(1, p0) is already incorporated in t[] tables, but only if ctx != 0
+  // (as required by the syntax). For ctx0 == 0, we need to add it here or it'll
+  // be missing during the loop.
+  int cost = (ctx0 == 0) ? VP8BitCost(1, p0) : 0;
+
+  if (res->last < 0) {
+    return VP8BitCost(0, p0);
+  }
+  for (; n < res->last; ++n) {
+    const int v = abs(res->coeffs[n]);
+    const int ctx = (v >= 2) ? 2 : v;
+    cost += VP8LevelCost(t, v);
+    t = costs[n + 1][ctx];
+  }
+  // Last coefficient is always non-zero
+  {
+    const int v = abs(res->coeffs[n]);
+    assert(v != 0);
+    cost += VP8LevelCost(t, v);
+    if (n < 15) {
+      const int b = VP8EncBands[n + 1];
+      const int ctx = (v == 1) ? 1 : 2;
+      const int last_p0 = res->prob[b][ctx][0];
+      cost += VP8BitCost(0, last_p0);
+    }
+  }
+  return cost;
+}
+
+static void SetResidualCoeffs(const int16_t* const coeffs,
+                              VP8Residual* const res) {
+  int n;
+  res->last = -1;
+  assert(res->first == 0 || coeffs[0] == 0);
+  for (n = 15; n >= 0; --n) {
+    if (coeffs[n]) {
+      res->last = n;
+      break;
+    }
+  }
+  res->coeffs = coeffs;
+}
+
+//------------------------------------------------------------------------------
+// init function
+
+VP8GetResidualCostFunc VP8GetResidualCost;
+VP8SetResidualCoeffsFunc VP8SetResidualCoeffs;
+
+extern void VP8EncDspCostInitMIPS32(void);
+extern void VP8EncDspCostInitMIPSdspR2(void);
+extern void VP8EncDspCostInitSSE2(void);
+
+static volatile VP8CPUInfo cost_last_cpuinfo_used =
+    (VP8CPUInfo)&cost_last_cpuinfo_used;
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspCostInit(void) {
+  if (cost_last_cpuinfo_used == VP8GetCPUInfo) return;
+
+  VP8GetResidualCost = GetResidualCost;
+  VP8SetResidualCoeffs = SetResidualCoeffs;
+
+  // If defined, use CPUInfo() to overwrite some pointers with faster versions.
+  if (VP8GetCPUInfo != NULL) {
+#if defined(WEBP_USE_MIPS32)
+    if (VP8GetCPUInfo(kMIPS32)) {
+      VP8EncDspCostInitMIPS32();
+    }
+#endif
+#if defined(WEBP_USE_MIPS_DSP_R2)
+    if (VP8GetCPUInfo(kMIPSdspR2)) {
+      VP8EncDspCostInitMIPSdspR2();
+    }
+#endif
+#if defined(WEBP_USE_SSE2)
+    if (VP8GetCPUInfo(kSSE2)) {
+      VP8EncDspCostInitSSE2();
+    }
+#endif
+  }
+
+  cost_last_cpuinfo_used = VP8GetCPUInfo;
+}
+
+//------------------------------------------------------------------------------
diff --git a/Source/LibWebP/src/dsp/dsp.cost_mips32.c b/Source/LibWebP/src/dsp/dsp.cost_mips32.c
new file mode 100644
index 0000000..bddfe6c
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.cost_mips32.c
@@ -0,0 +1,154 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Author: Djordje Pesut (djordje.pesut at imgtec.com)
+
+#include "./dsp.h"
+
+#if defined(WEBP_USE_MIPS32)
+
+#include "../enc/cost.h"
+
+static int GetResidualCost(int ctx0, const VP8Residual* const res) {
+  int temp0, temp1;
+  int v_reg, ctx_reg;
+  int n = res->first;
+  // should be prob[VP8EncBands[n]], but it's equivalent for n=0 or 1
+  int p0 = res->prob[n][ctx0][0];
+  CostArrayPtr const costs = res->costs;
+  const uint16_t* t = costs[n][ctx0];
+  // bit_cost(1, p0) is already incorporated in t[] tables, but only if ctx != 0
+  // (as required by the syntax). For ctx0 == 0, we need to add it here or it'll
+  // be missing during the loop.
+  int cost = (ctx0 == 0) ? VP8BitCost(1, p0) : 0;
+  const int16_t* res_coeffs = res->coeffs;
+  const int res_last = res->last;
+  const int const_max_level = MAX_VARIABLE_LEVEL;
+  const int const_2 = 2;
+  const uint16_t** p_costs = &costs[n][0];
+  const size_t inc_p_costs = NUM_CTX * sizeof(*p_costs);
+
+  if (res->last < 0) {
+    return VP8BitCost(0, p0);
+  }
+
+  __asm__ volatile (
+    ".set      push                                                        \n\t"
+    ".set      noreorder                                                   \n\t"
+    "subu      %[temp1],        %[res_last],        %[n]                   \n\t"
+    "sll       %[temp0],        %[n],               1                      \n\t"
+    "blez      %[temp1],        2f                                         \n\t"
+    " addu     %[res_coeffs],   %[res_coeffs],      %[temp0]               \n\t"
+  "1:                                                                      \n\t"
+    "lh        %[v_reg],        0(%[res_coeffs])                           \n\t"
+    "addiu     %[n],            %[n],               1                      \n\t"
+    "negu      %[temp0],        %[v_reg]                                   \n\t"
+    "slti      %[temp1],        %[v_reg],           0                      \n\t"
+    "movn      %[v_reg],        %[temp0],           %[temp1]               \n\t"
+    "sltiu     %[temp0],        %[v_reg],           2                      \n\t"
+    "move      %[ctx_reg],      %[v_reg]                                   \n\t"
+    "movz      %[ctx_reg],      %[const_2],         %[temp0]               \n\t"
+    "sll       %[temp1],        %[v_reg],           1                      \n\t"
+    "addu      %[temp1],        %[temp1],           %[VP8LevelFixedCosts]  \n\t"
+    "lhu       %[temp1],        0(%[temp1])                                \n\t"
+    "slt       %[temp0],        %[v_reg],           %[const_max_level]     \n\t"
+    "movz      %[v_reg],        %[const_max_level], %[temp0]               \n\t"
+    "addu      %[cost],         %[cost],            %[temp1]               \n\t"
+    "sll       %[v_reg],        %[v_reg],           1                      \n\t"
+    "sll       %[ctx_reg],      %[ctx_reg],         2                      \n\t"
+    "addu      %[v_reg],        %[v_reg],           %[t]                   \n\t"
+    "lhu       %[temp0],        0(%[v_reg])                                \n\t"
+    "addu      %[p_costs],      %[p_costs],         %[inc_p_costs]         \n\t"
+    "addu      %[t],            %[p_costs],         %[ctx_reg]             \n\t"
+    "addu      %[cost],         %[cost],            %[temp0]               \n\t"
+    "addiu     %[res_coeffs],   %[res_coeffs],      2                      \n\t"
+    "bne       %[n],            %[res_last],        1b                     \n\t"
+    " lw       %[t],            0(%[t])                                    \n\t"
+  "2:                                                                      \n\t"
+    ".set      pop                                                         \n\t"
+    : [cost]"+&r"(cost), [t]"+&r"(t), [n]"+&r"(n), [v_reg]"=&r"(v_reg),
+      [ctx_reg]"=&r"(ctx_reg), [p_costs]"+&r"(p_costs), [temp0]"=&r"(temp0),
+      [temp1]"=&r"(temp1), [res_coeffs]"+&r"(res_coeffs)
+    : [const_2]"r"(const_2), [const_max_level]"r"(const_max_level),
+      [VP8LevelFixedCosts]"r"(VP8LevelFixedCosts), [res_last]"r"(res_last),
+      [inc_p_costs]"r"(inc_p_costs)
+    : "memory"
+  );
+
+  // Last coefficient is always non-zero
+  {
+    const int v = abs(res->coeffs[n]);
+    assert(v != 0);
+    cost += VP8LevelCost(t, v);
+    if (n < 15) {
+      const int b = VP8EncBands[n + 1];
+      const int ctx = (v == 1) ? 1 : 2;
+      const int last_p0 = res->prob[b][ctx][0];
+      cost += VP8BitCost(0, last_p0);
+    }
+  }
+  return cost;
+}
+
+static void SetResidualCoeffs(const int16_t* const coeffs,
+                              VP8Residual* const res) {
+  const int16_t* p_coeffs = (int16_t*)coeffs;
+  int temp0, temp1, temp2, n, n1;
+  assert(res->first == 0 || coeffs[0] == 0);
+
+  __asm__ volatile (
+    ".set     push                                      \n\t"
+    ".set     noreorder                                 \n\t"
+    "addiu    %[p_coeffs],   %[p_coeffs],    28         \n\t"
+    "li       %[n],          15                         \n\t"
+    "li       %[temp2],      -1                         \n\t"
+  "0:                                                   \n\t"
+    "ulw      %[temp0],      0(%[p_coeffs])             \n\t"
+    "beqz     %[temp0],      1f                         \n\t"
+#if defined(WORDS_BIGENDIAN)
+    " sll     %[temp1],      %[temp0],       16         \n\t"
+#else
+    " srl     %[temp1],      %[temp0],       16         \n\t"
+#endif
+    "addiu    %[n1],         %[n],           -1         \n\t"
+    "movz     %[temp0],      %[n1],          %[temp1]   \n\t"
+    "movn     %[temp0],      %[n],           %[temp1]   \n\t"
+    "j        2f                                        \n\t"
+    " addiu   %[temp2],      %[temp0],       0          \n\t"
+  "1:                                                   \n\t"
+    "addiu    %[n],          %[n],           -2         \n\t"
+    "bgtz     %[n],          0b                         \n\t"
+    " addiu   %[p_coeffs],   %[p_coeffs],    -4         \n\t"
+  "2:                                                   \n\t"
+    ".set     pop                                       \n\t"
+    : [p_coeffs]"+&r"(p_coeffs), [temp0]"=&r"(temp0),
+      [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [n]"=&r"(n), [n1]"=&r"(n1)
+    :
+    : "memory"
+  );
+  res->last = temp2;
+  res->coeffs = coeffs;
+}
+
+#endif  // WEBP_USE_MIPS32
+
+//------------------------------------------------------------------------------
+// Entry point
+
+extern void VP8EncDspCostInitMIPS32(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspCostInitMIPS32(void) {
+#if defined(WEBP_USE_MIPS32)
+  VP8GetResidualCost = GetResidualCost;
+  VP8SetResidualCoeffs = SetResidualCoeffs;
+#endif  // WEBP_USE_MIPS32
+}
+
+//------------------------------------------------------------------------------
diff --git a/Source/LibWebP/src/dsp/dsp.cost_mips_dsp_r2.c b/Source/LibWebP/src/dsp/dsp.cost_mips_dsp_r2.c
new file mode 100644
index 0000000..57383f2
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.cost_mips_dsp_r2.c
@@ -0,0 +1,107 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Author: Djordje Pesut (djordje.pesut at imgtec.com)
+
+#include "./dsp.h"
+
+#if defined(WEBP_USE_MIPS_DSP_R2)
+
+#include "../enc/cost.h"
+
+static int GetResidualCost(int ctx0, const VP8Residual* const res) {
+  int temp0, temp1;
+  int v_reg, ctx_reg;
+  int n = res->first;
+  // should be prob[VP8EncBands[n]], but it's equivalent for n=0 or 1
+  int p0 = res->prob[n][ctx0][0];
+  CostArrayPtr const costs = res->costs;
+  const uint16_t* t = costs[n][ctx0];
+  // bit_cost(1, p0) is already incorporated in t[] tables, but only if ctx != 0
+  // (as required by the syntax). For ctx0 == 0, we need to add it here or it'll
+  // be missing during the loop.
+  int cost = (ctx0 == 0) ? VP8BitCost(1, p0) : 0;
+  const int16_t* res_coeffs = res->coeffs;
+  const int res_last = res->last;
+  const int const_max_level = MAX_VARIABLE_LEVEL;
+  const int const_2 = 2;
+  const uint16_t** p_costs = &costs[n][0];
+  const size_t inc_p_costs = NUM_CTX * sizeof(*p_costs);
+
+  if (res->last < 0) {
+    return VP8BitCost(0, p0);
+  }
+
+  __asm__ volatile (
+    ".set      push                                                     \n\t"
+    ".set      noreorder                                                \n\t"
+    "subu      %[temp1],        %[res_last],        %[n]                \n\t"
+    "blez      %[temp1],        2f                                      \n\t"
+    " nop                                                               \n\t"
+  "1:                                                                   \n\t"
+    "sll       %[temp0],        %[n],               1                   \n\t"
+    "lhx       %[v_reg],        %[temp0](%[res_coeffs])                 \n\t"
+    "addiu     %[n],            %[n],               1                   \n\t"
+    "absq_s.w  %[v_reg],        %[v_reg]                                \n\t"
+    "sltiu     %[temp0],        %[v_reg],           2                   \n\t"
+    "move      %[ctx_reg],      %[v_reg]                                \n\t"
+    "movz      %[ctx_reg],      %[const_2],         %[temp0]            \n\t"
+    "sll       %[temp1],        %[v_reg],           1                   \n\t"
+    "lhx       %[temp1],        %[temp1](%[VP8LevelFixedCosts])         \n\t"
+    "slt       %[temp0],        %[v_reg],           %[const_max_level]  \n\t"
+    "movz      %[v_reg],        %[const_max_level], %[temp0]            \n\t"
+    "addu      %[cost],         %[cost],            %[temp1]            \n\t"
+    "sll       %[v_reg],        %[v_reg],           1                   \n\t"
+    "sll       %[ctx_reg],      %[ctx_reg],         2                   \n\t"
+    "lhx       %[temp0],        %[v_reg](%[t])                          \n\t"
+    "addu      %[p_costs],      %[p_costs],         %[inc_p_costs]      \n\t"
+    "addu      %[t],            %[p_costs],         %[ctx_reg]          \n\t"
+    "addu      %[cost],         %[cost],            %[temp0]            \n\t"
+    "bne       %[n],            %[res_last],        1b                  \n\t"
+    " lw       %[t],            0(%[t])                                 \n\t"
+  "2:                                                                   \n\t"
+    ".set      pop                                                      \n\t"
+    : [cost]"+&r"(cost), [t]"+&r"(t), [n]"+&r"(n), [v_reg]"=&r"(v_reg),
+      [ctx_reg]"=&r"(ctx_reg), [p_costs]"+&r"(p_costs), [temp0]"=&r"(temp0),
+      [temp1]"=&r"(temp1)
+    : [const_2]"r"(const_2), [const_max_level]"r"(const_max_level),
+      [VP8LevelFixedCosts]"r"(VP8LevelFixedCosts), [res_last]"r"(res_last),
+      [res_coeffs]"r"(res_coeffs), [inc_p_costs]"r"(inc_p_costs)
+    : "memory"
+  );
+
+  // Last coefficient is always non-zero
+  {
+    const int v = abs(res->coeffs[n]);
+    assert(v != 0);
+    cost += VP8LevelCost(t, v);
+    if (n < 15) {
+      const int b = VP8EncBands[n + 1];
+      const int ctx = (v == 1) ? 1 : 2;
+      const int last_p0 = res->prob[b][ctx][0];
+      cost += VP8BitCost(0, last_p0);
+    }
+  }
+  return cost;
+}
+
+#endif  // WEBP_USE_MIPS_DSP_R2
+
+//------------------------------------------------------------------------------
+// Entry point
+
+extern void VP8EncDspCostInitMIPSdspR2(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspCostInitMIPSdspR2(void) {
+#if defined(WEBP_USE_MIPS_DSP_R2)
+  VP8GetResidualCost = GetResidualCost;
+#endif  // WEBP_USE_MIPS_DSP_R2
+}
+
+//------------------------------------------------------------------------------
diff --git a/Source/LibWebP/src/dsp/dsp.cost_sse2.c b/Source/LibWebP/src/dsp/dsp.cost_sse2.c
new file mode 100644
index 0000000..909d196
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.cost_sse2.c
@@ -0,0 +1,121 @@
+// Copyright 2015 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// SSE2 version of cost functions
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include "./dsp.h"
+
+#if defined(WEBP_USE_SSE2)
+#include <emmintrin.h>
+
+#include "../enc/cost.h"
+#include "../enc/vp8enci.h"
+#include "../utils/utils.h"
+
+//------------------------------------------------------------------------------
+
+static void SetResidualCoeffsSSE2(const int16_t* const coeffs,
+                                  VP8Residual* const res) {
+  const __m128i c0 = _mm_loadu_si128((const __m128i*)coeffs);
+  const __m128i c1 = _mm_loadu_si128((const __m128i*)(coeffs + 8));
+  // Use SSE to compare 8 values with a single instruction.
+  const __m128i zero = _mm_setzero_si128();
+  const __m128i m0 = _mm_cmpeq_epi16(c0, zero);
+  const __m128i m1 = _mm_cmpeq_epi16(c1, zero);
+  // Get the comparison results as a bitmask, consisting of two times 16 bits:
+  // two identical bits for each result. Concatenate both bitmasks to get a
+  // single 32 bit value. Negate the mask to get the position of entries that
+  // are not equal to zero. We don't need to mask out least significant bits
+  // according to res->first, since coeffs[0] is 0 if res->first > 0
+  const uint32_t mask =
+      ~(((uint32_t)_mm_movemask_epi8(m1) << 16) | _mm_movemask_epi8(m0));
+  // The position of the most significant non-zero bit indicates the position of
+  // the last non-zero value. Divide the result by two because __movemask_epi8
+  // operates on 8 bit values instead of 16 bit values.
+  assert(res->first == 0 || coeffs[0] == 0);
+  res->last = mask ? (BitsLog2Floor(mask) >> 1) : -1;
+  res->coeffs = coeffs;
+}
+
+static int GetResidualCostSSE2(int ctx0, const VP8Residual* const res) {
+  uint8_t levels[16], ctxs[16];
+  uint16_t abs_levels[16];
+  int n = res->first;
+  // should be prob[VP8EncBands[n]], but it's equivalent for n=0 or 1
+  const int p0 = res->prob[n][ctx0][0];
+  CostArrayPtr const costs = res->costs;
+  const uint16_t* t = costs[n][ctx0];
+  // bit_cost(1, p0) is already incorporated in t[] tables, but only if ctx != 0
+  // (as required by the syntax). For ctx0 == 0, we need to add it here or it'll
+  // be missing during the loop.
+  int cost = (ctx0 == 0) ? VP8BitCost(1, p0) : 0;
+
+  if (res->last < 0) {
+    return VP8BitCost(0, p0);
+  }
+
+  {   // precompute clamped levels and contexts, packed to 8b.
+    const __m128i zero = _mm_setzero_si128();
+    const __m128i kCst2 = _mm_set1_epi8(2);
+    const __m128i kCst67 = _mm_set1_epi8(MAX_VARIABLE_LEVEL);
+    const __m128i c0 = _mm_loadu_si128((const __m128i*)&res->coeffs[0]);
+    const __m128i c1 = _mm_loadu_si128((const __m128i*)&res->coeffs[8]);
+    const __m128i D0_m = _mm_min_epi16(c0, zero);
+    const __m128i D0_p = _mm_max_epi16(c0, zero);
+    const __m128i D1_m = _mm_min_epi16(c1, zero);
+    const __m128i D1_p = _mm_max_epi16(c1, zero);
+    const __m128i E0 = _mm_sub_epi16(D0_p, D0_m);   // abs(v), 16b
+    const __m128i E1 = _mm_sub_epi16(D1_p, D1_m);
+    const __m128i F = _mm_packs_epi16(E0, E1);
+    const __m128i G = _mm_min_epu8(F, kCst2);    // context = 0,1,2
+    const __m128i H = _mm_min_epu8(F, kCst67);   // clamp_level in [0..67]
+
+    _mm_storeu_si128((__m128i*)&ctxs[0], G);
+    _mm_storeu_si128((__m128i*)&levels[0], H);
+
+    _mm_storeu_si128((__m128i*)&abs_levels[0], E0);
+    _mm_storeu_si128((__m128i*)&abs_levels[8], E1);
+  }
+  for (; n < res->last; ++n) {
+    const int ctx = ctxs[n];
+    const int level = levels[n];
+    const int flevel = abs_levels[n];   // full level
+    cost += VP8LevelFixedCosts[flevel] + t[level];  // simplified VP8LevelCost()
+    t = costs[n + 1][ctx];
+  }
+  // Last coefficient is always non-zero
+  {
+    const int level = levels[n];
+    const int flevel = abs_levels[n];
+    assert(flevel != 0);
+    cost += VP8LevelFixedCosts[flevel] + t[level];
+    if (n < 15) {
+      const int b = VP8EncBands[n + 1];
+      const int ctx = ctxs[n];
+      const int last_p0 = res->prob[b][ctx][0];
+      cost += VP8BitCost(0, last_p0);
+    }
+  }
+  return cost;
+}
+#endif   // WEBP_USE_SSE2
+
+//------------------------------------------------------------------------------
+// Entry point
+
+extern void VP8EncDspCostInitSSE2(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspCostInitSSE2(void) {
+#if defined(WEBP_USE_SSE2)
+  VP8SetResidualCoeffs = SetResidualCoeffsSSE2;
+  VP8GetResidualCost = GetResidualCostSSE2;
+#endif   // WEBP_USE_SSE2
+}
diff --git a/Source/LibWebP/src/dsp/dsp.cpu.c b/Source/LibWebP/src/dsp/dsp.cpu.c
new file mode 100644
index 0000000..4991d84
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.cpu.c
@@ -0,0 +1,138 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// CPU detection
+//
+// Author: Christian Duvivier (cduvivier at google.com)
+
+#include "./dsp.h"
+
+#if defined(__ANDROID__)
+#include <cpu-features.h>
+#endif
+
+//------------------------------------------------------------------------------
+// SSE2 detection.
+//
+
+// apple/darwin gcc-4.0.1 defines __PIC__, but not __pic__ with -fPIC.
+#if (defined(__pic__) || defined(__PIC__)) && defined(__i386__)
+static WEBP_INLINE void GetCPUInfo(int cpu_info[4], int info_type) {
+  __asm__ volatile (
+    "mov %%ebx, %%edi\n"
+    "cpuid\n"
+    "xchg %%edi, %%ebx\n"
+    : "=a"(cpu_info[0]), "=D"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3])
+    : "a"(info_type), "c"(0));
+}
+#elif defined(__i386__) || defined(__x86_64__)
+static WEBP_INLINE void GetCPUInfo(int cpu_info[4], int info_type) {
+  __asm__ volatile (
+    "cpuid\n"
+    : "=a"(cpu_info[0]), "=b"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3])
+    : "a"(info_type), "c"(0));
+}
+#elif (defined(_M_X64) || defined(_M_IX86)) && \
+      defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 150030729  // >= VS2008 SP1
+#include <intrin.h>
+#define GetCPUInfo(info, type) __cpuidex(info, type, 0)  // set ecx=0
+#elif defined(WEBP_MSC_SSE2)
+#define GetCPUInfo __cpuid
+#endif
+
+// NaCl has no support for xgetbv or the raw opcode.
+#if !defined(__native_client__) && (defined(__i386__) || defined(__x86_64__))
+static WEBP_INLINE uint64_t xgetbv(void) {
+  const uint32_t ecx = 0;
+  uint32_t eax, edx;
+  // Use the raw opcode for xgetbv for compatibility with older toolchains.
+  __asm__ volatile (
+    ".byte 0x0f, 0x01, 0xd0\n"
+    : "=a"(eax), "=d"(edx) : "c" (ecx));
+  return ((uint64_t)edx << 32) | eax;
+}
+#elif (defined(_M_X64) || defined(_M_IX86)) && \
+      defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 160040219  // >= VS2010 SP1
+#include <immintrin.h>
+#define xgetbv() _xgetbv(0)
+#elif defined(_MSC_VER) && defined(_M_IX86)
+static WEBP_INLINE uint64_t xgetbv(void) {
+  uint32_t eax_, edx_;
+  __asm {
+    xor ecx, ecx  // ecx = 0
+    // Use the raw opcode for xgetbv for compatibility with older toolchains.
+    __asm _emit 0x0f __asm _emit 0x01 __asm _emit 0xd0
+    mov eax_, eax
+    mov edx_, edx
+  }
+  return ((uint64_t)edx_ << 32) | eax_;
+}
+#else
+#define xgetbv() 0U  // no AVX for older x64 or unrecognized toolchains.
+#endif
+
+#if defined(__i386__) || defined(__x86_64__) || defined(WEBP_MSC_SSE2)
+static int x86CPUInfo(CPUFeature feature) {
+  int cpu_info[4];
+  GetCPUInfo(cpu_info, 1);
+  if (feature == kSSE2) {
+    return 0 != (cpu_info[3] & 0x04000000);
+  }
+  if (feature == kSSE3) {
+    return 0 != (cpu_info[2] & 0x00000001);
+  }
+  if (feature == kAVX) {
+    // bits 27 (OSXSAVE) & 28 (256-bit AVX)
+    if ((cpu_info[2] & 0x18000000) == 0x18000000) {
+      // XMM state and YMM state enabled by the OS.
+      return (xgetbv() & 0x6) == 0x6;
+    }
+  }
+  if (feature == kAVX2) {
+    if (x86CPUInfo(kAVX)) {
+      GetCPUInfo(cpu_info, 7);
+      return ((cpu_info[1] & 0x00000020) == 0x00000020);
+    }
+  }
+  return 0;
+}
+VP8CPUInfo VP8GetCPUInfo = x86CPUInfo;
+#elif defined(WEBP_ANDROID_NEON)  // NB: needs to be before generic NEON test.
+static int AndroidCPUInfo(CPUFeature feature) {
+  const AndroidCpuFamily cpu_family = android_getCpuFamily();
+  const uint64_t cpu_features = android_getCpuFeatures();
+  if (feature == kNEON) {
+    return (cpu_family == ANDROID_CPU_FAMILY_ARM &&
+            0 != (cpu_features & ANDROID_CPU_ARM_FEATURE_NEON));
+  }
+  return 0;
+}
+VP8CPUInfo VP8GetCPUInfo = AndroidCPUInfo;
+#elif defined(WEBP_USE_NEON)
+// define a dummy function to enable turning off NEON at runtime by setting
+// VP8DecGetCPUInfo = NULL
+static int armCPUInfo(CPUFeature feature) {
+  (void)feature;
+  return 1;
+}
+VP8CPUInfo VP8GetCPUInfo = armCPUInfo;
+#elif defined(WEBP_USE_MIPS32) || defined(WEBP_USE_MIPS_DSP_R2)
+static int mipsCPUInfo(CPUFeature feature) {
+  if ((feature == kMIPS32) || (feature == kMIPSdspR2)) {
+    return 1;
+  } else {
+    return 0;
+  }
+
+}
+VP8CPUInfo VP8GetCPUInfo = mipsCPUInfo;
+#else
+VP8CPUInfo VP8GetCPUInfo = NULL;
+#endif
+
diff --git a/Source/LibWebP/src/dsp/dsp.dec.c b/Source/LibWebP/src/dsp/dsp.dec.c
new file mode 100644
index 0000000..7986a64
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.dec.c
@@ -0,0 +1,760 @@
+// Copyright 2010 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Speed-critical decoding functions, default plain-C implementations.
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include "./dsp.h"
+#include "../dec/vp8i.h"
+
+//------------------------------------------------------------------------------
+
+static WEBP_INLINE uint8_t clip_8b(int v) {
+  return (!(v & ~0xff)) ? v : (v < 0) ? 0 : 255;
+}
+
+//------------------------------------------------------------------------------
+// Transforms (Paragraph 14.4)
+
+#define STORE(x, y, v) \
+  dst[x + y * BPS] = clip_8b(dst[x + y * BPS] + ((v) >> 3))
+
+#define STORE2(y, dc, d, c) do {    \
+  const int DC = (dc);              \
+  STORE(0, y, DC + (d));            \
+  STORE(1, y, DC + (c));            \
+  STORE(2, y, DC - (c));            \
+  STORE(3, y, DC - (d));            \
+} while (0)
+
+static const int kC1 = 20091 + (1 << 16);
+static const int kC2 = 35468;
+#define MUL(a, b) (((a) * (b)) >> 16)
+
+static void TransformOne(const int16_t* in, uint8_t* dst) {
+  int C[4 * 4], *tmp;
+  int i;
+  tmp = C;
+  for (i = 0; i < 4; ++i) {    // vertical pass
+    const int a = in[0] + in[8];    // [-4096, 4094]
+    const int b = in[0] - in[8];    // [-4095, 4095]
+    const int c = MUL(in[4], kC2) - MUL(in[12], kC1);   // [-3783, 3783]
+    const int d = MUL(in[4], kC1) + MUL(in[12], kC2);   // [-3785, 3781]
+    tmp[0] = a + d;   // [-7881, 7875]
+    tmp[1] = b + c;   // [-7878, 7878]
+    tmp[2] = b - c;   // [-7878, 7878]
+    tmp[3] = a - d;   // [-7877, 7879]
+    tmp += 4;
+    in++;
+  }
+  // Each pass is expanding the dynamic range by ~3.85 (upper bound).
+  // The exact value is (2. + (kC1 + kC2) / 65536).
+  // After the second pass, maximum interval is [-3794, 3794], assuming
+  // an input in [-2048, 2047] interval. We then need to add a dst value
+  // in the [0, 255] range.
+  // In the worst case scenario, the input to clip_8b() can be as large as
+  // [-60713, 60968].
+  tmp = C;
+  for (i = 0; i < 4; ++i) {    // horizontal pass
+    const int dc = tmp[0] + 4;
+    const int a =  dc +  tmp[8];
+    const int b =  dc -  tmp[8];
+    const int c = MUL(tmp[4], kC2) - MUL(tmp[12], kC1);
+    const int d = MUL(tmp[4], kC1) + MUL(tmp[12], kC2);
+    STORE(0, 0, a + d);
+    STORE(1, 0, b + c);
+    STORE(2, 0, b - c);
+    STORE(3, 0, a - d);
+    tmp++;
+    dst += BPS;
+  }
+}
+
+// Simplified transform when only in[0], in[1] and in[4] are non-zero
+static void TransformAC3(const int16_t* in, uint8_t* dst) {
+  const int a = in[0] + 4;
+  const int c4 = MUL(in[4], kC2);
+  const int d4 = MUL(in[4], kC1);
+  const int c1 = MUL(in[1], kC2);
+  const int d1 = MUL(in[1], kC1);
+  STORE2(0, a + d4, d1, c1);
+  STORE2(1, a + c4, d1, c1);
+  STORE2(2, a - c4, d1, c1);
+  STORE2(3, a - d4, d1, c1);
+}
+#undef MUL
+#undef STORE2
+
+static void TransformTwo(const int16_t* in, uint8_t* dst, int do_two) {
+  TransformOne(in, dst);
+  if (do_two) {
+    TransformOne(in + 16, dst + 4);
+  }
+}
+
+static void TransformUV(const int16_t* in, uint8_t* dst) {
+  VP8Transform(in + 0 * 16, dst, 1);
+  VP8Transform(in + 2 * 16, dst + 4 * BPS, 1);
+}
+
+static void TransformDC(const int16_t* in, uint8_t* dst) {
+  const int DC = in[0] + 4;
+  int i, j;
+  for (j = 0; j < 4; ++j) {
+    for (i = 0; i < 4; ++i) {
+      STORE(i, j, DC);
+    }
+  }
+}
+
+static void TransformDCUV(const int16_t* in, uint8_t* dst) {
+  if (in[0 * 16]) VP8TransformDC(in + 0 * 16, dst);
+  if (in[1 * 16]) VP8TransformDC(in + 1 * 16, dst + 4);
+  if (in[2 * 16]) VP8TransformDC(in + 2 * 16, dst + 4 * BPS);
+  if (in[3 * 16]) VP8TransformDC(in + 3 * 16, dst + 4 * BPS + 4);
+}
+
+#undef STORE
+
+//------------------------------------------------------------------------------
+// Paragraph 14.3
+
+static void TransformWHT(const int16_t* in, int16_t* out) {
+  int tmp[16];
+  int i;
+  for (i = 0; i < 4; ++i) {
+    const int a0 = in[0 + i] + in[12 + i];
+    const int a1 = in[4 + i] + in[ 8 + i];
+    const int a2 = in[4 + i] - in[ 8 + i];
+    const int a3 = in[0 + i] - in[12 + i];
+    tmp[0  + i] = a0 + a1;
+    tmp[8  + i] = a0 - a1;
+    tmp[4  + i] = a3 + a2;
+    tmp[12 + i] = a3 - a2;
+  }
+  for (i = 0; i < 4; ++i) {
+    const int dc = tmp[0 + i * 4] + 3;    // w/ rounder
+    const int a0 = dc             + tmp[3 + i * 4];
+    const int a1 = tmp[1 + i * 4] + tmp[2 + i * 4];
+    const int a2 = tmp[1 + i * 4] - tmp[2 + i * 4];
+    const int a3 = dc             - tmp[3 + i * 4];
+    out[ 0] = (a0 + a1) >> 3;
+    out[16] = (a3 + a2) >> 3;
+    out[32] = (a0 - a1) >> 3;
+    out[48] = (a3 - a2) >> 3;
+    out += 64;
+  }
+}
+
+void (*VP8TransformWHT)(const int16_t* in, int16_t* out);
+
+//------------------------------------------------------------------------------
+// Intra predictions
+
+#define DST(x, y) dst[(x) + (y) * BPS]
+
+static WEBP_INLINE void TrueMotion(uint8_t* dst, int size) {
+  const uint8_t* top = dst - BPS;
+  const uint8_t* const clip0 = VP8kclip1 - top[-1];
+  int y;
+  for (y = 0; y < size; ++y) {
+    const uint8_t* const clip = clip0 + dst[-1];
+    int x;
+    for (x = 0; x < size; ++x) {
+      dst[x] = clip[top[x]];
+    }
+    dst += BPS;
+  }
+}
+static void TM4(uint8_t* dst)   { TrueMotion(dst, 4); }
+static void TM8uv(uint8_t* dst) { TrueMotion(dst, 8); }
+static void TM16(uint8_t* dst)  { TrueMotion(dst, 16); }
+
+//------------------------------------------------------------------------------
+// 16x16
+
+static void VE16(uint8_t* dst) {     // vertical
+  int j;
+  for (j = 0; j < 16; ++j) {
+    memcpy(dst + j * BPS, dst - BPS, 16);
+  }
+}
+
+static void HE16(uint8_t* dst) {     // horizontal
+  int j;
+  for (j = 16; j > 0; --j) {
+    memset(dst, dst[-1], 16);
+    dst += BPS;
+  }
+}
+
+static WEBP_INLINE void Put16(int v, uint8_t* dst) {
+  int j;
+  for (j = 0; j < 16; ++j) {
+    memset(dst + j * BPS, v, 16);
+  }
+}
+
+static void DC16(uint8_t* dst) {    // DC
+  int DC = 16;
+  int j;
+  for (j = 0; j < 16; ++j) {
+    DC += dst[-1 + j * BPS] + dst[j - BPS];
+  }
+  Put16(DC >> 5, dst);
+}
+
+static void DC16NoTop(uint8_t* dst) {   // DC with top samples not available
+  int DC = 8;
+  int j;
+  for (j = 0; j < 16; ++j) {
+    DC += dst[-1 + j * BPS];
+  }
+  Put16(DC >> 4, dst);
+}
+
+static void DC16NoLeft(uint8_t* dst) {  // DC with left samples not available
+  int DC = 8;
+  int i;
+  for (i = 0; i < 16; ++i) {
+    DC += dst[i - BPS];
+  }
+  Put16(DC >> 4, dst);
+}
+
+static void DC16NoTopLeft(uint8_t* dst) {  // DC with no top and left samples
+  Put16(0x80, dst);
+}
+
+VP8PredFunc VP8PredLuma16[NUM_B_DC_MODES];
+
+//------------------------------------------------------------------------------
+// 4x4
+
+#define AVG3(a, b, c) (((a) + 2 * (b) + (c) + 2) >> 2)
+#define AVG2(a, b) (((a) + (b) + 1) >> 1)
+
+static void VE4(uint8_t* dst) {    // vertical
+  const uint8_t* top = dst - BPS;
+  const uint8_t vals[4] = {
+    AVG3(top[-1], top[0], top[1]),
+    AVG3(top[ 0], top[1], top[2]),
+    AVG3(top[ 1], top[2], top[3]),
+    AVG3(top[ 2], top[3], top[4])
+  };
+  int i;
+  for (i = 0; i < 4; ++i) {
+    memcpy(dst + i * BPS, vals, sizeof(vals));
+  }
+}
+
+static void HE4(uint8_t* dst) {    // horizontal
+  const int A = dst[-1 - BPS];
+  const int B = dst[-1];
+  const int C = dst[-1 + BPS];
+  const int D = dst[-1 + 2 * BPS];
+  const int E = dst[-1 + 3 * BPS];
+  *(uint32_t*)(dst + 0 * BPS) = 0x01010101U * AVG3(A, B, C);
+  *(uint32_t*)(dst + 1 * BPS) = 0x01010101U * AVG3(B, C, D);
+  *(uint32_t*)(dst + 2 * BPS) = 0x01010101U * AVG3(C, D, E);
+  *(uint32_t*)(dst + 3 * BPS) = 0x01010101U * AVG3(D, E, E);
+}
+
+static void DC4(uint8_t* dst) {   // DC
+  uint32_t dc = 4;
+  int i;
+  for (i = 0; i < 4; ++i) dc += dst[i - BPS] + dst[-1 + i * BPS];
+  dc >>= 3;
+  for (i = 0; i < 4; ++i) memset(dst + i * BPS, dc, 4);
+}
+
+static void RD4(uint8_t* dst) {   // Down-right
+  const int I = dst[-1 + 0 * BPS];
+  const int J = dst[-1 + 1 * BPS];
+  const int K = dst[-1 + 2 * BPS];
+  const int L = dst[-1 + 3 * BPS];
+  const int X = dst[-1 - BPS];
+  const int A = dst[0 - BPS];
+  const int B = dst[1 - BPS];
+  const int C = dst[2 - BPS];
+  const int D = dst[3 - BPS];
+  DST(0, 3)                                     = AVG3(J, K, L);
+  DST(1, 3) = DST(0, 2)                         = AVG3(I, J, K);
+  DST(2, 3) = DST(1, 2) = DST(0, 1)             = AVG3(X, I, J);
+  DST(3, 3) = DST(2, 2) = DST(1, 1) = DST(0, 0) = AVG3(A, X, I);
+              DST(3, 2) = DST(2, 1) = DST(1, 0) = AVG3(B, A, X);
+                          DST(3, 1) = DST(2, 0) = AVG3(C, B, A);
+                                      DST(3, 0) = AVG3(D, C, B);
+}
+
+static void LD4(uint8_t* dst) {   // Down-Left
+  const int A = dst[0 - BPS];
+  const int B = dst[1 - BPS];
+  const int C = dst[2 - BPS];
+  const int D = dst[3 - BPS];
+  const int E = dst[4 - BPS];
+  const int F = dst[5 - BPS];
+  const int G = dst[6 - BPS];
+  const int H = dst[7 - BPS];
+  DST(0, 0)                                     = AVG3(A, B, C);
+  DST(1, 0) = DST(0, 1)                         = AVG3(B, C, D);
+  DST(2, 0) = DST(1, 1) = DST(0, 2)             = AVG3(C, D, E);
+  DST(3, 0) = DST(2, 1) = DST(1, 2) = DST(0, 3) = AVG3(D, E, F);
+              DST(3, 1) = DST(2, 2) = DST(1, 3) = AVG3(E, F, G);
+                          DST(3, 2) = DST(2, 3) = AVG3(F, G, H);
+                                      DST(3, 3) = AVG3(G, H, H);
+}
+
+static void VR4(uint8_t* dst) {   // Vertical-Right
+  const int I = dst[-1 + 0 * BPS];
+  const int J = dst[-1 + 1 * BPS];
+  const int K = dst[-1 + 2 * BPS];
+  const int X = dst[-1 - BPS];
+  const int A = dst[0 - BPS];
+  const int B = dst[1 - BPS];
+  const int C = dst[2 - BPS];
+  const int D = dst[3 - BPS];
+  DST(0, 0) = DST(1, 2) = AVG2(X, A);
+  DST(1, 0) = DST(2, 2) = AVG2(A, B);
+  DST(2, 0) = DST(3, 2) = AVG2(B, C);
+  DST(3, 0)             = AVG2(C, D);
+
+  DST(0, 3) =             AVG3(K, J, I);
+  DST(0, 2) =             AVG3(J, I, X);
+  DST(0, 1) = DST(1, 3) = AVG3(I, X, A);
+  DST(1, 1) = DST(2, 3) = AVG3(X, A, B);
+  DST(2, 1) = DST(3, 3) = AVG3(A, B, C);
+  DST(3, 1) =             AVG3(B, C, D);
+}
+
+static void VL4(uint8_t* dst) {   // Vertical-Left
+  const int A = dst[0 - BPS];
+  const int B = dst[1 - BPS];
+  const int C = dst[2 - BPS];
+  const int D = dst[3 - BPS];
+  const int E = dst[4 - BPS];
+  const int F = dst[5 - BPS];
+  const int G = dst[6 - BPS];
+  const int H = dst[7 - BPS];
+  DST(0, 0) =             AVG2(A, B);
+  DST(1, 0) = DST(0, 2) = AVG2(B, C);
+  DST(2, 0) = DST(1, 2) = AVG2(C, D);
+  DST(3, 0) = DST(2, 2) = AVG2(D, E);
+
+  DST(0, 1) =             AVG3(A, B, C);
+  DST(1, 1) = DST(0, 3) = AVG3(B, C, D);
+  DST(2, 1) = DST(1, 3) = AVG3(C, D, E);
+  DST(3, 1) = DST(2, 3) = AVG3(D, E, F);
+              DST(3, 2) = AVG3(E, F, G);
+              DST(3, 3) = AVG3(F, G, H);
+}
+
+static void HU4(uint8_t* dst) {   // Horizontal-Up
+  const int I = dst[-1 + 0 * BPS];
+  const int J = dst[-1 + 1 * BPS];
+  const int K = dst[-1 + 2 * BPS];
+  const int L = dst[-1 + 3 * BPS];
+  DST(0, 0) =             AVG2(I, J);
+  DST(2, 0) = DST(0, 1) = AVG2(J, K);
+  DST(2, 1) = DST(0, 2) = AVG2(K, L);
+  DST(1, 0) =             AVG3(I, J, K);
+  DST(3, 0) = DST(1, 1) = AVG3(J, K, L);
+  DST(3, 1) = DST(1, 2) = AVG3(K, L, L);
+  DST(3, 2) = DST(2, 2) =
+    DST(0, 3) = DST(1, 3) = DST(2, 3) = DST(3, 3) = L;
+}
+
+static void HD4(uint8_t* dst) {  // Horizontal-Down
+  const int I = dst[-1 + 0 * BPS];
+  const int J = dst[-1 + 1 * BPS];
+  const int K = dst[-1 + 2 * BPS];
+  const int L = dst[-1 + 3 * BPS];
+  const int X = dst[-1 - BPS];
+  const int A = dst[0 - BPS];
+  const int B = dst[1 - BPS];
+  const int C = dst[2 - BPS];
+
+  DST(0, 0) = DST(2, 1) = AVG2(I, X);
+  DST(0, 1) = DST(2, 2) = AVG2(J, I);
+  DST(0, 2) = DST(2, 3) = AVG2(K, J);
+  DST(0, 3)             = AVG2(L, K);
+
+  DST(3, 0)             = AVG3(A, B, C);
+  DST(2, 0)             = AVG3(X, A, B);
+  DST(1, 0) = DST(3, 1) = AVG3(I, X, A);
+  DST(1, 1) = DST(3, 2) = AVG3(J, I, X);
+  DST(1, 2) = DST(3, 3) = AVG3(K, J, I);
+  DST(1, 3)             = AVG3(L, K, J);
+}
+
+#undef DST
+#undef AVG3
+#undef AVG2
+
+VP8PredFunc VP8PredLuma4[NUM_BMODES];
+
+//------------------------------------------------------------------------------
+// Chroma
+
+static void VE8uv(uint8_t* dst) {    // vertical
+  int j;
+  for (j = 0; j < 8; ++j) {
+    memcpy(dst + j * BPS, dst - BPS, 8);
+  }
+}
+
+static void HE8uv(uint8_t* dst) {    // horizontal
+  int j;
+  for (j = 0; j < 8; ++j) {
+    memset(dst, dst[-1], 8);
+    dst += BPS;
+  }
+}
+
+// helper for chroma-DC predictions
+static WEBP_INLINE void Put8x8uv(uint8_t value, uint8_t* dst) {
+  int j;
+  for (j = 0; j < 8; ++j) {
+    memset(dst + j * BPS, value, 8);
+  }
+}
+
+static void DC8uv(uint8_t* dst) {     // DC
+  int dc0 = 8;
+  int i;
+  for (i = 0; i < 8; ++i) {
+    dc0 += dst[i - BPS] + dst[-1 + i * BPS];
+  }
+  Put8x8uv(dc0 >> 4, dst);
+}
+
+static void DC8uvNoLeft(uint8_t* dst) {   // DC with no left samples
+  int dc0 = 4;
+  int i;
+  for (i = 0; i < 8; ++i) {
+    dc0 += dst[i - BPS];
+  }
+  Put8x8uv(dc0 >> 3, dst);
+}
+
+static void DC8uvNoTop(uint8_t* dst) {  // DC with no top samples
+  int dc0 = 4;
+  int i;
+  for (i = 0; i < 8; ++i) {
+    dc0 += dst[-1 + i * BPS];
+  }
+  Put8x8uv(dc0 >> 3, dst);
+}
+
+static void DC8uvNoTopLeft(uint8_t* dst) {    // DC with nothing
+  Put8x8uv(0x80, dst);
+}
+
+VP8PredFunc VP8PredChroma8[NUM_B_DC_MODES];
+
+//------------------------------------------------------------------------------
+// Edge filtering functions
+
+// 4 pixels in, 2 pixels out
+static WEBP_INLINE void do_filter2(uint8_t* p, int step) {
+  const int p1 = p[-2*step], p0 = p[-step], q0 = p[0], q1 = p[step];
+  const int a = 3 * (q0 - p0) + VP8ksclip1[p1 - q1];  // in [-893,892]
+  const int a1 = VP8ksclip2[(a + 4) >> 3];            // in [-16,15]
+  const int a2 = VP8ksclip2[(a + 3) >> 3];
+  p[-step] = VP8kclip1[p0 + a2];
+  p[    0] = VP8kclip1[q0 - a1];
+}
+
+// 4 pixels in, 4 pixels out
+static WEBP_INLINE void do_filter4(uint8_t* p, int step) {
+  const int p1 = p[-2*step], p0 = p[-step], q0 = p[0], q1 = p[step];
+  const int a = 3 * (q0 - p0);
+  const int a1 = VP8ksclip2[(a + 4) >> 3];
+  const int a2 = VP8ksclip2[(a + 3) >> 3];
+  const int a3 = (a1 + 1) >> 1;
+  p[-2*step] = VP8kclip1[p1 + a3];
+  p[-  step] = VP8kclip1[p0 + a2];
+  p[      0] = VP8kclip1[q0 - a1];
+  p[   step] = VP8kclip1[q1 - a3];
+}
+
+// 6 pixels in, 6 pixels out
+static WEBP_INLINE void do_filter6(uint8_t* p, int step) {
+  const int p2 = p[-3*step], p1 = p[-2*step], p0 = p[-step];
+  const int q0 = p[0], q1 = p[step], q2 = p[2*step];
+  const int a = VP8ksclip1[3 * (q0 - p0) + VP8ksclip1[p1 - q1]];
+  // a is in [-128,127], a1 in [-27,27], a2 in [-18,18] and a3 in [-9,9]
+  const int a1 = (27 * a + 63) >> 7;  // eq. to ((3 * a + 7) * 9) >> 7
+  const int a2 = (18 * a + 63) >> 7;  // eq. to ((2 * a + 7) * 9) >> 7
+  const int a3 = (9  * a + 63) >> 7;  // eq. to ((1 * a + 7) * 9) >> 7
+  p[-3*step] = VP8kclip1[p2 + a3];
+  p[-2*step] = VP8kclip1[p1 + a2];
+  p[-  step] = VP8kclip1[p0 + a1];
+  p[      0] = VP8kclip1[q0 - a1];
+  p[   step] = VP8kclip1[q1 - a2];
+  p[ 2*step] = VP8kclip1[q2 - a3];
+}
+
+static WEBP_INLINE int hev(const uint8_t* p, int step, int thresh) {
+  const int p1 = p[-2*step], p0 = p[-step], q0 = p[0], q1 = p[step];
+  return (VP8kabs0[p1 - p0] > thresh) || (VP8kabs0[q1 - q0] > thresh);
+}
+
+static WEBP_INLINE int needs_filter(const uint8_t* p, int step, int t) {
+  const int p1 = p[-2 * step], p0 = p[-step], q0 = p[0], q1 = p[step];
+  return ((4 * VP8kabs0[p0 - q0] + VP8kabs0[p1 - q1]) <= t);
+}
+
+static WEBP_INLINE int needs_filter2(const uint8_t* p,
+                                     int step, int t, int it) {
+  const int p3 = p[-4 * step], p2 = p[-3 * step], p1 = p[-2 * step];
+  const int p0 = p[-step], q0 = p[0];
+  const int q1 = p[step], q2 = p[2 * step], q3 = p[3 * step];
+  if ((4 * VP8kabs0[p0 - q0] + VP8kabs0[p1 - q1]) > t) return 0;
+  return VP8kabs0[p3 - p2] <= it && VP8kabs0[p2 - p1] <= it &&
+         VP8kabs0[p1 - p0] <= it && VP8kabs0[q3 - q2] <= it &&
+         VP8kabs0[q2 - q1] <= it && VP8kabs0[q1 - q0] <= it;
+}
+
+//------------------------------------------------------------------------------
+// Simple In-loop filtering (Paragraph 15.2)
+
+static void SimpleVFilter16(uint8_t* p, int stride, int thresh) {
+  int i;
+  const int thresh2 = 2 * thresh + 1;
+  for (i = 0; i < 16; ++i) {
+    if (needs_filter(p + i, stride, thresh2)) {
+      do_filter2(p + i, stride);
+    }
+  }
+}
+
+static void SimpleHFilter16(uint8_t* p, int stride, int thresh) {
+  int i;
+  const int thresh2 = 2 * thresh + 1;
+  for (i = 0; i < 16; ++i) {
+    if (needs_filter(p + i * stride, 1, thresh2)) {
+      do_filter2(p + i * stride, 1);
+    }
+  }
+}
+
+static void SimpleVFilter16i(uint8_t* p, int stride, int thresh) {
+  int k;
+  for (k = 3; k > 0; --k) {
+    p += 4 * stride;
+    SimpleVFilter16(p, stride, thresh);
+  }
+}
+
+static void SimpleHFilter16i(uint8_t* p, int stride, int thresh) {
+  int k;
+  for (k = 3; k > 0; --k) {
+    p += 4;
+    SimpleHFilter16(p, stride, thresh);
+  }
+}
+
+//------------------------------------------------------------------------------
+// Complex In-loop filtering (Paragraph 15.3)
+
+static WEBP_INLINE void FilterLoop26(uint8_t* p,
+                                     int hstride, int vstride, int size,
+                                     int thresh, int ithresh, int hev_thresh) {
+  const int thresh2 = 2 * thresh + 1;
+  while (size-- > 0) {
+    if (needs_filter2(p, hstride, thresh2, ithresh)) {
+      if (hev(p, hstride, hev_thresh)) {
+        do_filter2(p, hstride);
+      } else {
+        do_filter6(p, hstride);
+      }
+    }
+    p += vstride;
+  }
+}
+
+static WEBP_INLINE void FilterLoop24(uint8_t* p,
+                                     int hstride, int vstride, int size,
+                                     int thresh, int ithresh, int hev_thresh) {
+  const int thresh2 = 2 * thresh + 1;
+  while (size-- > 0) {
+    if (needs_filter2(p, hstride, thresh2, ithresh)) {
+      if (hev(p, hstride, hev_thresh)) {
+        do_filter2(p, hstride);
+      } else {
+        do_filter4(p, hstride);
+      }
+    }
+    p += vstride;
+  }
+}
+
+// on macroblock edges
+static void VFilter16(uint8_t* p, int stride,
+                      int thresh, int ithresh, int hev_thresh) {
+  FilterLoop26(p, stride, 1, 16, thresh, ithresh, hev_thresh);
+}
+
+static void HFilter16(uint8_t* p, int stride,
+                      int thresh, int ithresh, int hev_thresh) {
+  FilterLoop26(p, 1, stride, 16, thresh, ithresh, hev_thresh);
+}
+
+// on three inner edges
+static void VFilter16i(uint8_t* p, int stride,
+                       int thresh, int ithresh, int hev_thresh) {
+  int k;
+  for (k = 3; k > 0; --k) {
+    p += 4 * stride;
+    FilterLoop24(p, stride, 1, 16, thresh, ithresh, hev_thresh);
+  }
+}
+
+static void HFilter16i(uint8_t* p, int stride,
+                       int thresh, int ithresh, int hev_thresh) {
+  int k;
+  for (k = 3; k > 0; --k) {
+    p += 4;
+    FilterLoop24(p, 1, stride, 16, thresh, ithresh, hev_thresh);
+  }
+}
+
+// 8-pixels wide variant, for chroma filtering
+static void VFilter8(uint8_t* u, uint8_t* v, int stride,
+                     int thresh, int ithresh, int hev_thresh) {
+  FilterLoop26(u, stride, 1, 8, thresh, ithresh, hev_thresh);
+  FilterLoop26(v, stride, 1, 8, thresh, ithresh, hev_thresh);
+}
+
+static void HFilter8(uint8_t* u, uint8_t* v, int stride,
+                     int thresh, int ithresh, int hev_thresh) {
+  FilterLoop26(u, 1, stride, 8, thresh, ithresh, hev_thresh);
+  FilterLoop26(v, 1, stride, 8, thresh, ithresh, hev_thresh);
+}
+
+static void VFilter8i(uint8_t* u, uint8_t* v, int stride,
+                      int thresh, int ithresh, int hev_thresh) {
+  FilterLoop24(u + 4 * stride, stride, 1, 8, thresh, ithresh, hev_thresh);
+  FilterLoop24(v + 4 * stride, stride, 1, 8, thresh, ithresh, hev_thresh);
+}
+
+static void HFilter8i(uint8_t* u, uint8_t* v, int stride,
+                      int thresh, int ithresh, int hev_thresh) {
+  FilterLoop24(u + 4, 1, stride, 8, thresh, ithresh, hev_thresh);
+  FilterLoop24(v + 4, 1, stride, 8, thresh, ithresh, hev_thresh);
+}
+
+//------------------------------------------------------------------------------
+
+VP8DecIdct2 VP8Transform;
+VP8DecIdct VP8TransformAC3;
+VP8DecIdct VP8TransformUV;
+VP8DecIdct VP8TransformDC;
+VP8DecIdct VP8TransformDCUV;
+
+VP8LumaFilterFunc VP8VFilter16;
+VP8LumaFilterFunc VP8HFilter16;
+VP8ChromaFilterFunc VP8VFilter8;
+VP8ChromaFilterFunc VP8HFilter8;
+VP8LumaFilterFunc VP8VFilter16i;
+VP8LumaFilterFunc VP8HFilter16i;
+VP8ChromaFilterFunc VP8VFilter8i;
+VP8ChromaFilterFunc VP8HFilter8i;
+VP8SimpleFilterFunc VP8SimpleVFilter16;
+VP8SimpleFilterFunc VP8SimpleHFilter16;
+VP8SimpleFilterFunc VP8SimpleVFilter16i;
+VP8SimpleFilterFunc VP8SimpleHFilter16i;
+
+extern void VP8DspInitSSE2(void);
+extern void VP8DspInitNEON(void);
+extern void VP8DspInitMIPS32(void);
+extern void VP8DspInitMIPSdspR2(void);
+
+static volatile VP8CPUInfo dec_last_cpuinfo_used =
+    (VP8CPUInfo)&dec_last_cpuinfo_used;
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8DspInit(void) {
+  if (dec_last_cpuinfo_used == VP8GetCPUInfo) return;
+
+  VP8InitClipTables();
+
+  VP8TransformWHT = TransformWHT;
+  VP8Transform = TransformTwo;
+  VP8TransformUV = TransformUV;
+  VP8TransformDC = TransformDC;
+  VP8TransformDCUV = TransformDCUV;
+  VP8TransformAC3 = TransformAC3;
+
+  VP8VFilter16 = VFilter16;
+  VP8HFilter16 = HFilter16;
+  VP8VFilter8 = VFilter8;
+  VP8HFilter8 = HFilter8;
+  VP8VFilter16i = VFilter16i;
+  VP8HFilter16i = HFilter16i;
+  VP8VFilter8i = VFilter8i;
+  VP8HFilter8i = HFilter8i;
+  VP8SimpleVFilter16 = SimpleVFilter16;
+  VP8SimpleHFilter16 = SimpleHFilter16;
+  VP8SimpleVFilter16i = SimpleVFilter16i;
+  VP8SimpleHFilter16i = SimpleHFilter16i;
+
+  VP8PredLuma4[0] = DC4;
+  VP8PredLuma4[1] = TM4;
+  VP8PredLuma4[2] = VE4;
+  VP8PredLuma4[3] = HE4;
+  VP8PredLuma4[4] = RD4;
+  VP8PredLuma4[5] = VR4;
+  VP8PredLuma4[6] = LD4;
+  VP8PredLuma4[7] = VL4;
+  VP8PredLuma4[8] = HD4;
+  VP8PredLuma4[9] = HU4;
+
+  VP8PredLuma16[0] = DC16;
+  VP8PredLuma16[1] = TM16;
+  VP8PredLuma16[2] = VE16;
+  VP8PredLuma16[3] = HE16;
+  VP8PredLuma16[4] = DC16NoTop;
+  VP8PredLuma16[5] = DC16NoLeft;
+  VP8PredLuma16[6] = DC16NoTopLeft;
+
+  VP8PredChroma8[0] = DC8uv;
+  VP8PredChroma8[1] = TM8uv;
+  VP8PredChroma8[2] = VE8uv;
+  VP8PredChroma8[3] = HE8uv;
+  VP8PredChroma8[4] = DC8uvNoTop;
+  VP8PredChroma8[5] = DC8uvNoLeft;
+  VP8PredChroma8[6] = DC8uvNoTopLeft;
+
+  // If defined, use CPUInfo() to overwrite some pointers with faster versions.
+  if (VP8GetCPUInfo != NULL) {
+#if defined(WEBP_USE_SSE2)
+    if (VP8GetCPUInfo(kSSE2)) {
+      VP8DspInitSSE2();
+    }
+#endif
+#if defined(WEBP_USE_NEON)
+    if (VP8GetCPUInfo(kNEON)) {
+      VP8DspInitNEON();
+    }
+#endif
+#if defined(WEBP_USE_MIPS32)
+    if (VP8GetCPUInfo(kMIPS32)) {
+      VP8DspInitMIPS32();
+    }
+#endif
+#if defined(WEBP_USE_MIPS_DSP_R2)
+    if (VP8GetCPUInfo(kMIPSdspR2)) {
+      VP8DspInitMIPSdspR2();
+    }
+#endif
+  }
+  dec_last_cpuinfo_used = VP8GetCPUInfo;
+}
diff --git a/Source/LibWebP/src/dsp/dsp.dec_clip_tables.c b/Source/LibWebP/src/dsp/dsp.dec_clip_tables.c
new file mode 100644
index 0000000..281d7fb
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.dec_clip_tables.c
@@ -0,0 +1,366 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Clipping tables for filtering
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include "./dsp.h"
+
+#define USE_STATIC_TABLES     // undefine to have run-time table initialization
+
+#ifdef USE_STATIC_TABLES
+
+static const uint8_t abs0[255 + 255 + 1] = {
+  0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4,
+  0xf3, 0xf2, 0xf1, 0xf0, 0xef, 0xee, 0xed, 0xec, 0xeb, 0xea, 0xe9, 0xe8,
+  0xe7, 0xe6, 0xe5, 0xe4, 0xe3, 0xe2, 0xe1, 0xe0, 0xdf, 0xde, 0xdd, 0xdc,
+  0xdb, 0xda, 0xd9, 0xd8, 0xd7, 0xd6, 0xd5, 0xd4, 0xd3, 0xd2, 0xd1, 0xd0,
+  0xcf, 0xce, 0xcd, 0xcc, 0xcb, 0xca, 0xc9, 0xc8, 0xc7, 0xc6, 0xc5, 0xc4,
+  0xc3, 0xc2, 0xc1, 0xc0, 0xbf, 0xbe, 0xbd, 0xbc, 0xbb, 0xba, 0xb9, 0xb8,
+  0xb7, 0xb6, 0xb5, 0xb4, 0xb3, 0xb2, 0xb1, 0xb0, 0xaf, 0xae, 0xad, 0xac,
+  0xab, 0xaa, 0xa9, 0xa8, 0xa7, 0xa6, 0xa5, 0xa4, 0xa3, 0xa2, 0xa1, 0xa0,
+  0x9f, 0x9e, 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, 0x97, 0x96, 0x95, 0x94,
+  0x93, 0x92, 0x91, 0x90, 0x8f, 0x8e, 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88,
+  0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81, 0x80, 0x7f, 0x7e, 0x7d, 0x7c,
+  0x7b, 0x7a, 0x79, 0x78, 0x77, 0x76, 0x75, 0x74, 0x73, 0x72, 0x71, 0x70,
+  0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x69, 0x68, 0x67, 0x66, 0x65, 0x64,
+  0x63, 0x62, 0x61, 0x60, 0x5f, 0x5e, 0x5d, 0x5c, 0x5b, 0x5a, 0x59, 0x58,
+  0x57, 0x56, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50, 0x4f, 0x4e, 0x4d, 0x4c,
+  0x4b, 0x4a, 0x49, 0x48, 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 0x40,
+  0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, 0x37, 0x36, 0x35, 0x34,
+  0x33, 0x32, 0x31, 0x30, 0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28,
+  0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e, 0x1d, 0x1c,
+  0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
+  0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04,
+  0x03, 0x02, 0x01, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+  0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
+  0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
+  0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c,
+  0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
+  0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44,
+  0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
+  0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c,
+  0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
+  0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74,
+  0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80,
+  0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c,
+  0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
+  0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4,
+  0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0,
+  0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc,
+  0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8,
+  0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4,
+  0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0,
+  0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec,
+  0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
+  0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
+};
+
+static const int8_t sclip1[1020 + 1020 + 1] = {
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+  0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93,
+  0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+  0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab,
+  0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+  0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3,
+  0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+  0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb,
+  0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+  0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3,
+  0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
+  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
+  0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+  0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
+  0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+  0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
+  0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+  0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53,
+  0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+  0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
+  0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+  0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f
+};
+
+static const int8_t sclip2[112 + 112 + 1] = {
+  0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
+  0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
+  0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
+  0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
+  0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
+  0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
+  0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
+  0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
+  0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb,
+  0xfc, 0xfd, 0xfe, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+  0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+  0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+  0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+  0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+  0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+  0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+  0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+  0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f
+};
+
+static const uint8_t clip1[255 + 511 + 1] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+  0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
+  0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
+  0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c,
+  0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
+  0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44,
+  0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
+  0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c,
+  0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
+  0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74,
+  0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80,
+  0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c,
+  0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
+  0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4,
+  0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0,
+  0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc,
+  0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8,
+  0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4,
+  0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0,
+  0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec,
+  0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
+  0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+};
+
+#else
+
+// uninitialized tables
+static uint8_t abs0[255 + 255 + 1];
+static int8_t sclip1[1020 + 1020 + 1];
+static int8_t sclip2[112 + 112 + 1];
+static uint8_t clip1[255 + 511 + 1];
+
+// We declare this variable 'volatile' to prevent instruction reordering
+// and make sure it's set to true _last_ (so as to be thread-safe)
+static volatile int tables_ok = 0;
+
+#endif
+
+const int8_t* const VP8ksclip1 = &sclip1[1020];
+const int8_t* const VP8ksclip2 = &sclip2[112];
+const uint8_t* const VP8kclip1 = &clip1[255];
+const uint8_t* const VP8kabs0 = &abs0[255];
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8InitClipTables(void) {
+#if !defined(USE_STATIC_TABLES)
+  int i;
+  if (!tables_ok) {
+    for (i = -255; i <= 255; ++i) {
+      abs0[255 + i] = (i < 0) ? -i : i;
+    }
+    for (i = -1020; i <= 1020; ++i) {
+      sclip1[1020 + i] = (i < -128) ? -128 : (i > 127) ? 127 : i;
+    }
+    for (i = -112; i <= 112; ++i) {
+      sclip2[112 + i] = (i < -16) ? -16 : (i > 15) ? 15 : i;
+    }
+    for (i = -255; i <= 255 + 255; ++i) {
+      clip1[255 + i] = (i < 0) ? 0 : (i > 255) ? 255 : i;
+    }
+    tables_ok = 1;
+  }
+#endif    // USE_STATIC_TABLES
+}
diff --git a/Source/LibWebP/src/dsp/dsp.dec_mips32.c b/Source/LibWebP/src/dsp/dsp.dec_mips32.c
new file mode 100644
index 0000000..f611bdc
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.dec_mips32.c
@@ -0,0 +1,585 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// MIPS version of dsp functions
+//
+// Author(s):  Djordje Pesut    (djordje.pesut at imgtec.com)
+//             Jovan Zelincevic (jovan.zelincevic at imgtec.com)
+
+#include "./dsp.h"
+
+#if defined(WEBP_USE_MIPS32)
+
+#include "./mips_macro.h"
+
+static const int kC1 = 20091 + (1 << 16);
+static const int kC2 = 35468;
+
+static WEBP_INLINE int abs_mips32(int x) {
+  const int sign = x >> 31;
+  return (x ^ sign) - sign;
+}
+
+// 4 pixels in, 2 pixels out
+static WEBP_INLINE void do_filter2(uint8_t* p, int step) {
+  const int p1 = p[-2 * step], p0 = p[-step], q0 = p[0], q1 = p[step];
+  const int a = 3 * (q0 - p0) + VP8ksclip1[p1 - q1];
+  const int a1 = VP8ksclip2[(a + 4) >> 3];
+  const int a2 = VP8ksclip2[(a + 3) >> 3];
+  p[-step] = VP8kclip1[p0 + a2];
+  p[    0] = VP8kclip1[q0 - a1];
+}
+
+// 4 pixels in, 4 pixels out
+static WEBP_INLINE void do_filter4(uint8_t* p, int step) {
+  const int p1 = p[-2 * step], p0 = p[-step], q0 = p[0], q1 = p[step];
+  const int a = 3 * (q0 - p0);
+  const int a1 = VP8ksclip2[(a + 4) >> 3];
+  const int a2 = VP8ksclip2[(a + 3) >> 3];
+  const int a3 = (a1 + 1) >> 1;
+  p[-2 * step] = VP8kclip1[p1 + a3];
+  p[-    step] = VP8kclip1[p0 + a2];
+  p[        0] = VP8kclip1[q0 - a1];
+  p[     step] = VP8kclip1[q1 - a3];
+}
+
+// 6 pixels in, 6 pixels out
+static WEBP_INLINE void do_filter6(uint8_t* p, int step) {
+  const int p2 = p[-3 * step], p1 = p[-2 * step], p0 = p[-step];
+  const int q0 = p[0], q1 = p[step], q2 = p[2 * step];
+  const int a = VP8ksclip1[3 * (q0 - p0) + VP8ksclip1[p1 - q1]];
+  // a is in [-128,127], a1 in [-27,27], a2 in [-18,18] and a3 in [-9,9]
+  const int a1 = (27 * a + 63) >> 7;  // eq. to ((3 * a + 7) * 9) >> 7
+  const int a2 = (18 * a + 63) >> 7;  // eq. to ((2 * a + 7) * 9) >> 7
+  const int a3 = (9  * a + 63) >> 7;  // eq. to ((1 * a + 7) * 9) >> 7
+  p[-3 * step] = VP8kclip1[p2 + a3];
+  p[-2 * step] = VP8kclip1[p1 + a2];
+  p[-    step] = VP8kclip1[p0 + a1];
+  p[        0] = VP8kclip1[q0 - a1];
+  p[     step] = VP8kclip1[q1 - a2];
+  p[ 2 * step] = VP8kclip1[q2 - a3];
+}
+
+static WEBP_INLINE int hev(const uint8_t* p, int step, int thresh) {
+  const int p1 = p[-2 * step], p0 = p[-step], q0 = p[0], q1 = p[step];
+  return (abs_mips32(p1 - p0) > thresh) || (abs_mips32(q1 - q0) > thresh);
+}
+
+static WEBP_INLINE int needs_filter(const uint8_t* p, int step, int t) {
+  const int p1 = p[-2 * step], p0 = p[-step], q0 = p[0], q1 = p[step];
+  return ((4 * abs_mips32(p0 - q0) + abs_mips32(p1 - q1)) <= t);
+}
+
+static WEBP_INLINE int needs_filter2(const uint8_t* p,
+                                     int step, int t, int it) {
+  const int p3 = p[-4 * step], p2 = p[-3 * step];
+  const int p1 = p[-2 * step], p0 = p[-step];
+  const int q0 = p[0], q1 = p[step], q2 = p[2 * step], q3 = p[3 * step];
+  if ((4 * abs_mips32(p0 - q0) + abs_mips32(p1 - q1)) > t) {
+    return 0;
+  }
+  return abs_mips32(p3 - p2) <= it && abs_mips32(p2 - p1) <= it &&
+         abs_mips32(p1 - p0) <= it && abs_mips32(q3 - q2) <= it &&
+         abs_mips32(q2 - q1) <= it && abs_mips32(q1 - q0) <= it;
+}
+
+static WEBP_INLINE void FilterLoop26(uint8_t* p,
+                                     int hstride, int vstride, int size,
+                                     int thresh, int ithresh, int hev_thresh) {
+  const int thresh2 = 2 * thresh + 1;
+  while (size-- > 0) {
+    if (needs_filter2(p, hstride, thresh2, ithresh)) {
+      if (hev(p, hstride, hev_thresh)) {
+        do_filter2(p, hstride);
+      } else {
+        do_filter6(p, hstride);
+      }
+    }
+    p += vstride;
+  }
+}
+
+static WEBP_INLINE void FilterLoop24(uint8_t* p,
+                                     int hstride, int vstride, int size,
+                                     int thresh, int ithresh, int hev_thresh) {
+  const int thresh2 = 2 * thresh + 1;
+  while (size-- > 0) {
+    if (needs_filter2(p, hstride, thresh2, ithresh)) {
+      if (hev(p, hstride, hev_thresh)) {
+        do_filter2(p, hstride);
+      } else {
+        do_filter4(p, hstride);
+      }
+    }
+    p += vstride;
+  }
+}
+
+// on macroblock edges
+static void VFilter16(uint8_t* p, int stride,
+                      int thresh, int ithresh, int hev_thresh) {
+  FilterLoop26(p, stride, 1, 16, thresh, ithresh, hev_thresh);
+}
+
+static void HFilter16(uint8_t* p, int stride,
+                      int thresh, int ithresh, int hev_thresh) {
+  FilterLoop26(p, 1, stride, 16, thresh, ithresh, hev_thresh);
+}
+
+// 8-pixels wide variant, for chroma filtering
+static void VFilter8(uint8_t* u, uint8_t* v, int stride,
+                     int thresh, int ithresh, int hev_thresh) {
+  FilterLoop26(u, stride, 1, 8, thresh, ithresh, hev_thresh);
+  FilterLoop26(v, stride, 1, 8, thresh, ithresh, hev_thresh);
+}
+
+static void HFilter8(uint8_t* u, uint8_t* v, int stride,
+                     int thresh, int ithresh, int hev_thresh) {
+  FilterLoop26(u, 1, stride, 8, thresh, ithresh, hev_thresh);
+  FilterLoop26(v, 1, stride, 8, thresh, ithresh, hev_thresh);
+}
+
+static void VFilter8i(uint8_t* u, uint8_t* v, int stride,
+                      int thresh, int ithresh, int hev_thresh) {
+  FilterLoop24(u + 4 * stride, stride, 1, 8, thresh, ithresh, hev_thresh);
+  FilterLoop24(v + 4 * stride, stride, 1, 8, thresh, ithresh, hev_thresh);
+}
+
+static void HFilter8i(uint8_t* u, uint8_t* v, int stride,
+                      int thresh, int ithresh, int hev_thresh) {
+  FilterLoop24(u + 4, 1, stride, 8, thresh, ithresh, hev_thresh);
+  FilterLoop24(v + 4, 1, stride, 8, thresh, ithresh, hev_thresh);
+}
+
+// on three inner edges
+static void VFilter16i(uint8_t* p, int stride,
+                       int thresh, int ithresh, int hev_thresh) {
+  int k;
+  for (k = 3; k > 0; --k) {
+    p += 4 * stride;
+    FilterLoop24(p, stride, 1, 16, thresh, ithresh, hev_thresh);
+  }
+}
+
+static void HFilter16i(uint8_t* p, int stride,
+                       int thresh, int ithresh, int hev_thresh) {
+  int k;
+  for (k = 3; k > 0; --k) {
+    p += 4;
+    FilterLoop24(p, 1, stride, 16, thresh, ithresh, hev_thresh);
+  }
+}
+
+//------------------------------------------------------------------------------
+// Simple In-loop filtering (Paragraph 15.2)
+
+static void SimpleVFilter16(uint8_t* p, int stride, int thresh) {
+  int i;
+  const int thresh2 = 2 * thresh + 1;
+  for (i = 0; i < 16; ++i) {
+    if (needs_filter(p + i, stride, thresh2)) {
+      do_filter2(p + i, stride);
+    }
+  }
+}
+
+static void SimpleHFilter16(uint8_t* p, int stride, int thresh) {
+  int i;
+  const int thresh2 = 2 * thresh + 1;
+  for (i = 0; i < 16; ++i) {
+    if (needs_filter(p + i * stride, 1, thresh2)) {
+      do_filter2(p + i * stride, 1);
+    }
+  }
+}
+
+static void SimpleVFilter16i(uint8_t* p, int stride, int thresh) {
+  int k;
+  for (k = 3; k > 0; --k) {
+    p += 4 * stride;
+    SimpleVFilter16(p, stride, thresh);
+  }
+}
+
+static void SimpleHFilter16i(uint8_t* p, int stride, int thresh) {
+  int k;
+  for (k = 3; k > 0; --k) {
+    p += 4;
+    SimpleHFilter16(p, stride, thresh);
+  }
+}
+
+static void TransformOne(const int16_t* in, uint8_t* dst) {
+  int temp0, temp1, temp2, temp3, temp4;
+  int temp5, temp6, temp7, temp8, temp9;
+  int temp10, temp11, temp12, temp13, temp14;
+  int temp15, temp16, temp17, temp18;
+  int16_t* p_in = (int16_t*)in;
+
+  // loops unrolled and merged to avoid usage of tmp buffer
+  // and to reduce number of stalls. MUL macro is written
+  // in assembler and inlined
+  __asm__ volatile(
+    "lh       %[temp0],  0(%[in])                      \n\t"
+    "lh       %[temp8],  16(%[in])                     \n\t"
+    "lh       %[temp4],  8(%[in])                      \n\t"
+    "lh       %[temp12], 24(%[in])                     \n\t"
+    "addu     %[temp16], %[temp0],  %[temp8]           \n\t"
+    "subu     %[temp0],  %[temp0],  %[temp8]           \n\t"
+    "mul      %[temp8],  %[temp4],  %[kC2]             \n\t"
+    "mul      %[temp17], %[temp12], %[kC1]             \n\t"
+    "mul      %[temp4],  %[temp4],  %[kC1]             \n\t"
+    "mul      %[temp12], %[temp12], %[kC2]             \n\t"
+    "lh       %[temp1],  2(%[in])                      \n\t"
+    "lh       %[temp5],  10(%[in])                     \n\t"
+    "lh       %[temp9],  18(%[in])                     \n\t"
+    "lh       %[temp13], 26(%[in])                     \n\t"
+    "sra      %[temp8],  %[temp8],  16                 \n\t"
+    "sra      %[temp17], %[temp17], 16                 \n\t"
+    "sra      %[temp4],  %[temp4],  16                 \n\t"
+    "sra      %[temp12], %[temp12], 16                 \n\t"
+    "lh       %[temp2],  4(%[in])                      \n\t"
+    "lh       %[temp6],  12(%[in])                     \n\t"
+    "lh       %[temp10], 20(%[in])                     \n\t"
+    "lh       %[temp14], 28(%[in])                     \n\t"
+    "subu     %[temp17], %[temp8],  %[temp17]          \n\t"
+    "addu     %[temp4],  %[temp4],  %[temp12]          \n\t"
+    "addu     %[temp8],  %[temp16], %[temp4]           \n\t"
+    "subu     %[temp4],  %[temp16], %[temp4]           \n\t"
+    "addu     %[temp16], %[temp1],  %[temp9]           \n\t"
+    "subu     %[temp1],  %[temp1],  %[temp9]           \n\t"
+    "lh       %[temp3],  6(%[in])                      \n\t"
+    "lh       %[temp7],  14(%[in])                     \n\t"
+    "lh       %[temp11], 22(%[in])                     \n\t"
+    "lh       %[temp15], 30(%[in])                     \n\t"
+    "addu     %[temp12], %[temp0],  %[temp17]          \n\t"
+    "subu     %[temp0],  %[temp0],  %[temp17]          \n\t"
+    "mul      %[temp9],  %[temp5],  %[kC2]             \n\t"
+    "mul      %[temp17], %[temp13], %[kC1]             \n\t"
+    "mul      %[temp5],  %[temp5],  %[kC1]             \n\t"
+    "mul      %[temp13], %[temp13], %[kC2]             \n\t"
+    "sra      %[temp9],  %[temp9],  16                 \n\t"
+    "sra      %[temp17], %[temp17], 16                 \n\t"
+    "subu     %[temp17], %[temp9],  %[temp17]          \n\t"
+    "sra      %[temp5],  %[temp5],  16                 \n\t"
+    "sra      %[temp13], %[temp13], 16                 \n\t"
+    "addu     %[temp5],  %[temp5],  %[temp13]          \n\t"
+    "addu     %[temp13], %[temp1],  %[temp17]          \n\t"
+    "subu     %[temp1],  %[temp1],  %[temp17]          \n\t"
+    "mul      %[temp17], %[temp14], %[kC1]             \n\t"
+    "mul      %[temp14], %[temp14], %[kC2]             \n\t"
+    "addu     %[temp9],  %[temp16], %[temp5]           \n\t"
+    "subu     %[temp5],  %[temp16], %[temp5]           \n\t"
+    "addu     %[temp16], %[temp2],  %[temp10]          \n\t"
+    "subu     %[temp2],  %[temp2],  %[temp10]          \n\t"
+    "mul      %[temp10], %[temp6],  %[kC2]             \n\t"
+    "mul      %[temp6],  %[temp6],  %[kC1]             \n\t"
+    "sra      %[temp17], %[temp17], 16                 \n\t"
+    "sra      %[temp14], %[temp14], 16                 \n\t"
+    "sra      %[temp10], %[temp10], 16                 \n\t"
+    "sra      %[temp6],  %[temp6],  16                 \n\t"
+    "subu     %[temp17], %[temp10], %[temp17]          \n\t"
+    "addu     %[temp6],  %[temp6],  %[temp14]          \n\t"
+    "addu     %[temp10], %[temp16], %[temp6]           \n\t"
+    "subu     %[temp6],  %[temp16], %[temp6]           \n\t"
+    "addu     %[temp14], %[temp2],  %[temp17]          \n\t"
+    "subu     %[temp2],  %[temp2],  %[temp17]          \n\t"
+    "mul      %[temp17], %[temp15], %[kC1]             \n\t"
+    "mul      %[temp15], %[temp15], %[kC2]             \n\t"
+    "addu     %[temp16], %[temp3],  %[temp11]          \n\t"
+    "subu     %[temp3],  %[temp3],  %[temp11]          \n\t"
+    "mul      %[temp11], %[temp7],  %[kC2]             \n\t"
+    "mul      %[temp7],  %[temp7],  %[kC1]             \n\t"
+    "addiu    %[temp8],  %[temp8],  4                  \n\t"
+    "addiu    %[temp12], %[temp12], 4                  \n\t"
+    "addiu    %[temp0],  %[temp0],  4                  \n\t"
+    "addiu    %[temp4],  %[temp4],  4                  \n\t"
+    "sra      %[temp17], %[temp17], 16                 \n\t"
+    "sra      %[temp15], %[temp15], 16                 \n\t"
+    "sra      %[temp11], %[temp11], 16                 \n\t"
+    "sra      %[temp7],  %[temp7],  16                 \n\t"
+    "subu     %[temp17], %[temp11], %[temp17]          \n\t"
+    "addu     %[temp7],  %[temp7],  %[temp15]          \n\t"
+    "addu     %[temp15], %[temp3],  %[temp17]          \n\t"
+    "subu     %[temp3],  %[temp3],  %[temp17]          \n\t"
+    "addu     %[temp11], %[temp16], %[temp7]           \n\t"
+    "subu     %[temp7],  %[temp16], %[temp7]           \n\t"
+    "addu     %[temp16], %[temp8],  %[temp10]          \n\t"
+    "subu     %[temp8],  %[temp8],  %[temp10]          \n\t"
+    "mul      %[temp10], %[temp9],  %[kC2]             \n\t"
+    "mul      %[temp17], %[temp11], %[kC1]             \n\t"
+    "mul      %[temp9],  %[temp9],  %[kC1]             \n\t"
+    "mul      %[temp11], %[temp11], %[kC2]             \n\t"
+    "sra      %[temp10], %[temp10], 16                 \n\t"
+    "sra      %[temp17], %[temp17], 16                 \n\t"
+    "sra      %[temp9],  %[temp9],  16                 \n\t"
+    "sra      %[temp11], %[temp11], 16                 \n\t"
+    "subu     %[temp17], %[temp10], %[temp17]          \n\t"
+    "addu     %[temp11], %[temp9],  %[temp11]          \n\t"
+    "addu     %[temp10], %[temp12], %[temp14]          \n\t"
+    "subu     %[temp12], %[temp12], %[temp14]          \n\t"
+    "mul      %[temp14], %[temp13], %[kC2]             \n\t"
+    "mul      %[temp9],  %[temp15], %[kC1]             \n\t"
+    "mul      %[temp13], %[temp13], %[kC1]             \n\t"
+    "mul      %[temp15], %[temp15], %[kC2]             \n\t"
+    "sra      %[temp14], %[temp14], 16                 \n\t"
+    "sra      %[temp9],  %[temp9],  16                 \n\t"
+    "sra      %[temp13], %[temp13], 16                 \n\t"
+    "sra      %[temp15], %[temp15], 16                 \n\t"
+    "subu     %[temp9],  %[temp14], %[temp9]           \n\t"
+    "addu     %[temp15], %[temp13], %[temp15]          \n\t"
+    "addu     %[temp14], %[temp0],  %[temp2]           \n\t"
+    "subu     %[temp0],  %[temp0],  %[temp2]           \n\t"
+    "mul      %[temp2],  %[temp1],  %[kC2]             \n\t"
+    "mul      %[temp13], %[temp3],  %[kC1]             \n\t"
+    "mul      %[temp1],  %[temp1],  %[kC1]             \n\t"
+    "mul      %[temp3],  %[temp3],  %[kC2]             \n\t"
+    "sra      %[temp2],  %[temp2],  16                 \n\t"
+    "sra      %[temp13], %[temp13], 16                 \n\t"
+    "sra      %[temp1],  %[temp1],  16                 \n\t"
+    "sra      %[temp3],  %[temp3],  16                 \n\t"
+    "subu     %[temp13], %[temp2],  %[temp13]          \n\t"
+    "addu     %[temp3],  %[temp1],  %[temp3]           \n\t"
+    "addu     %[temp2],  %[temp4],  %[temp6]           \n\t"
+    "subu     %[temp4],  %[temp4],  %[temp6]           \n\t"
+    "mul      %[temp6],  %[temp5],  %[kC2]             \n\t"
+    "mul      %[temp1],  %[temp7],  %[kC1]             \n\t"
+    "mul      %[temp5],  %[temp5],  %[kC1]             \n\t"
+    "mul      %[temp7],  %[temp7],  %[kC2]             \n\t"
+    "sra      %[temp6],  %[temp6],  16                 \n\t"
+    "sra      %[temp1],  %[temp1],  16                 \n\t"
+    "sra      %[temp5],  %[temp5],  16                 \n\t"
+    "sra      %[temp7],  %[temp7],  16                 \n\t"
+    "subu     %[temp1],  %[temp6],  %[temp1]           \n\t"
+    "addu     %[temp7],  %[temp5],  %[temp7]           \n\t"
+    "addu     %[temp5],  %[temp16], %[temp11]          \n\t"
+    "subu     %[temp16], %[temp16], %[temp11]          \n\t"
+    "addu     %[temp11], %[temp8],  %[temp17]          \n\t"
+    "subu     %[temp8],  %[temp8],  %[temp17]          \n\t"
+    "sra      %[temp5],  %[temp5],  3                  \n\t"
+    "sra      %[temp16], %[temp16], 3                  \n\t"
+    "sra      %[temp11], %[temp11], 3                  \n\t"
+    "sra      %[temp8],  %[temp8],  3                  \n\t"
+    "addu     %[temp17], %[temp10], %[temp15]          \n\t"
+    "subu     %[temp10], %[temp10], %[temp15]          \n\t"
+    "addu     %[temp15], %[temp12], %[temp9]           \n\t"
+    "subu     %[temp12], %[temp12], %[temp9]           \n\t"
+    "sra      %[temp17], %[temp17], 3                  \n\t"
+    "sra      %[temp10], %[temp10], 3                  \n\t"
+    "sra      %[temp15], %[temp15], 3                  \n\t"
+    "sra      %[temp12], %[temp12], 3                  \n\t"
+    "addu     %[temp9],  %[temp14], %[temp3]           \n\t"
+    "subu     %[temp14], %[temp14], %[temp3]           \n\t"
+    "addu     %[temp3],  %[temp0],  %[temp13]          \n\t"
+    "subu     %[temp0],  %[temp0],  %[temp13]          \n\t"
+    "sra      %[temp9],  %[temp9],  3                  \n\t"
+    "sra      %[temp14], %[temp14], 3                  \n\t"
+    "sra      %[temp3],  %[temp3],  3                  \n\t"
+    "sra      %[temp0],  %[temp0],  3                  \n\t"
+    "addu     %[temp13], %[temp2],  %[temp7]           \n\t"
+    "subu     %[temp2],  %[temp2],  %[temp7]           \n\t"
+    "addu     %[temp7],  %[temp4],  %[temp1]           \n\t"
+    "subu     %[temp4],  %[temp4],  %[temp1]           \n\t"
+    "sra      %[temp13], %[temp13], 3                  \n\t"
+    "sra      %[temp2],  %[temp2],  3                  \n\t"
+    "sra      %[temp7],  %[temp7],  3                  \n\t"
+    "sra      %[temp4],  %[temp4],  3                  \n\t"
+    "addiu    %[temp6],  $zero,     255                \n\t"
+    "lbu      %[temp1],  0+0*"XSTR(BPS)"(%[dst])       \n\t"
+    "addu     %[temp1],  %[temp1],  %[temp5]           \n\t"
+    "sra      %[temp5],  %[temp1],  8                  \n\t"
+    "sra      %[temp18], %[temp1],  31                 \n\t"
+    "beqz     %[temp5],  1f                            \n\t"
+    "xor      %[temp1],  %[temp1],  %[temp1]           \n\t"
+    "movz     %[temp1],  %[temp6],  %[temp18]          \n\t"
+  "1:                                                  \n\t"
+    "lbu      %[temp18], 1+0*"XSTR(BPS)"(%[dst])       \n\t"
+    "sb       %[temp1],  0+0*"XSTR(BPS)"(%[dst])       \n\t"
+    "addu     %[temp18], %[temp18], %[temp11]          \n\t"
+    "sra      %[temp11], %[temp18], 8                  \n\t"
+    "sra      %[temp1],  %[temp18], 31                 \n\t"
+    "beqz     %[temp11], 2f                            \n\t"
+    "xor      %[temp18], %[temp18], %[temp18]          \n\t"
+    "movz     %[temp18], %[temp6],  %[temp1]           \n\t"
+  "2:                                                  \n\t"
+    "lbu      %[temp1],  2+0*"XSTR(BPS)"(%[dst])       \n\t"
+    "sb       %[temp18], 1+0*"XSTR(BPS)"(%[dst])       \n\t"
+    "addu     %[temp1],  %[temp1],  %[temp8]           \n\t"
+    "sra      %[temp8],  %[temp1],  8                  \n\t"
+    "sra      %[temp18], %[temp1],  31                 \n\t"
+    "beqz     %[temp8],  3f                            \n\t"
+    "xor      %[temp1],  %[temp1],  %[temp1]           \n\t"
+    "movz     %[temp1],  %[temp6],  %[temp18]          \n\t"
+  "3:                                                  \n\t"
+    "lbu      %[temp18], 3+0*"XSTR(BPS)"(%[dst])       \n\t"
+    "sb       %[temp1],  2+0*"XSTR(BPS)"(%[dst])       \n\t"
+    "addu     %[temp18], %[temp18], %[temp16]          \n\t"
+    "sra      %[temp16], %[temp18], 8                  \n\t"
+    "sra      %[temp1],  %[temp18], 31                 \n\t"
+    "beqz     %[temp16], 4f                            \n\t"
+    "xor      %[temp18], %[temp18], %[temp18]          \n\t"
+    "movz     %[temp18], %[temp6],  %[temp1]           \n\t"
+  "4:                                                  \n\t"
+    "sb       %[temp18], 3+0*"XSTR(BPS)"(%[dst])       \n\t"
+    "lbu      %[temp5],  0+1*"XSTR(BPS)"(%[dst])       \n\t"
+    "lbu      %[temp8],  1+1*"XSTR(BPS)"(%[dst])       \n\t"
+    "lbu      %[temp11], 2+1*"XSTR(BPS)"(%[dst])       \n\t"
+    "lbu      %[temp16], 3+1*"XSTR(BPS)"(%[dst])       \n\t"
+    "addu     %[temp5],  %[temp5],  %[temp17]          \n\t"
+    "addu     %[temp8],  %[temp8],  %[temp15]          \n\t"
+    "addu     %[temp11], %[temp11], %[temp12]          \n\t"
+    "addu     %[temp16], %[temp16], %[temp10]          \n\t"
+    "sra      %[temp18], %[temp5],  8                  \n\t"
+    "sra      %[temp1],  %[temp5],  31                 \n\t"
+    "beqz     %[temp18], 5f                            \n\t"
+    "xor      %[temp5],  %[temp5],  %[temp5]           \n\t"
+    "movz     %[temp5],  %[temp6],  %[temp1]           \n\t"
+  "5:                                                  \n\t"
+    "sra      %[temp18], %[temp8],  8                  \n\t"
+    "sra      %[temp1],  %[temp8],  31                 \n\t"
+    "beqz     %[temp18], 6f                            \n\t"
+    "xor      %[temp8],  %[temp8],  %[temp8]           \n\t"
+    "movz     %[temp8],  %[temp6],  %[temp1]           \n\t"
+  "6:                                                  \n\t"
+    "sra      %[temp18], %[temp11], 8                  \n\t"
+    "sra      %[temp1],  %[temp11], 31                 \n\t"
+    "sra      %[temp17], %[temp16], 8                  \n\t"
+    "sra      %[temp15], %[temp16], 31                 \n\t"
+    "beqz     %[temp18], 7f                            \n\t"
+    "xor      %[temp11], %[temp11], %[temp11]          \n\t"
+    "movz     %[temp11], %[temp6],  %[temp1]           \n\t"
+  "7:                                                  \n\t"
+    "beqz     %[temp17], 8f                            \n\t"
+    "xor      %[temp16], %[temp16], %[temp16]          \n\t"
+    "movz     %[temp16], %[temp6],  %[temp15]          \n\t"
+  "8:                                                  \n\t"
+    "sb       %[temp5],  0+1*"XSTR(BPS)"(%[dst])       \n\t"
+    "sb       %[temp8],  1+1*"XSTR(BPS)"(%[dst])       \n\t"
+    "sb       %[temp11], 2+1*"XSTR(BPS)"(%[dst])       \n\t"
+    "sb       %[temp16], 3+1*"XSTR(BPS)"(%[dst])       \n\t"
+    "lbu      %[temp5],  0+2*"XSTR(BPS)"(%[dst])       \n\t"
+    "lbu      %[temp8],  1+2*"XSTR(BPS)"(%[dst])       \n\t"
+    "lbu      %[temp11], 2+2*"XSTR(BPS)"(%[dst])       \n\t"
+    "lbu      %[temp16], 3+2*"XSTR(BPS)"(%[dst])       \n\t"
+    "addu     %[temp5],  %[temp5],  %[temp9]           \n\t"
+    "addu     %[temp8],  %[temp8],  %[temp3]           \n\t"
+    "addu     %[temp11], %[temp11], %[temp0]           \n\t"
+    "addu     %[temp16], %[temp16], %[temp14]          \n\t"
+    "sra      %[temp18], %[temp5],  8                  \n\t"
+    "sra      %[temp1],  %[temp5],  31                 \n\t"
+    "sra      %[temp17], %[temp8],  8                  \n\t"
+    "sra      %[temp15], %[temp8],  31                 \n\t"
+    "sra      %[temp12], %[temp11], 8                  \n\t"
+    "sra      %[temp10], %[temp11], 31                 \n\t"
+    "sra      %[temp9],  %[temp16], 8                  \n\t"
+    "sra      %[temp3],  %[temp16], 31                 \n\t"
+    "beqz     %[temp18], 9f                            \n\t"
+    "xor      %[temp5],  %[temp5],  %[temp5]           \n\t"
+    "movz     %[temp5],  %[temp6],  %[temp1]           \n\t"
+  "9:                                                  \n\t"
+    "beqz     %[temp17], 10f                           \n\t"
+    "xor      %[temp8],  %[temp8],  %[temp8]           \n\t"
+    "movz     %[temp8],  %[temp6],  %[temp15]          \n\t"
+  "10:                                                 \n\t"
+    "beqz     %[temp12], 11f                           \n\t"
+    "xor      %[temp11], %[temp11], %[temp11]          \n\t"
+    "movz     %[temp11], %[temp6],  %[temp10]          \n\t"
+  "11:                                                 \n\t"
+    "beqz     %[temp9],  12f                           \n\t"
+    "xor      %[temp16], %[temp16], %[temp16]          \n\t"
+    "movz     %[temp16], %[temp6],  %[temp3]           \n\t"
+  "12:                                                 \n\t"
+    "sb       %[temp5],  0+2*"XSTR(BPS)"(%[dst])       \n\t"
+    "sb       %[temp8],  1+2*"XSTR(BPS)"(%[dst])       \n\t"
+    "sb       %[temp11], 2+2*"XSTR(BPS)"(%[dst])       \n\t"
+    "sb       %[temp16], 3+2*"XSTR(BPS)"(%[dst])       \n\t"
+    "lbu      %[temp5],  0+3*"XSTR(BPS)"(%[dst])       \n\t"
+    "lbu      %[temp8],  1+3*"XSTR(BPS)"(%[dst])       \n\t"
+    "lbu      %[temp11], 2+3*"XSTR(BPS)"(%[dst])       \n\t"
+    "lbu      %[temp16], 3+3*"XSTR(BPS)"(%[dst])       \n\t"
+    "addu     %[temp5],  %[temp5],  %[temp13]          \n\t"
+    "addu     %[temp8],  %[temp8],  %[temp7]           \n\t"
+    "addu     %[temp11], %[temp11], %[temp4]           \n\t"
+    "addu     %[temp16], %[temp16], %[temp2]           \n\t"
+    "sra      %[temp18], %[temp5],  8                  \n\t"
+    "sra      %[temp1],  %[temp5],  31                 \n\t"
+    "sra      %[temp17], %[temp8],  8                  \n\t"
+    "sra      %[temp15], %[temp8],  31                 \n\t"
+    "sra      %[temp12], %[temp11], 8                  \n\t"
+    "sra      %[temp10], %[temp11], 31                 \n\t"
+    "sra      %[temp9],  %[temp16], 8                  \n\t"
+    "sra      %[temp3],  %[temp16], 31                 \n\t"
+    "beqz     %[temp18], 13f                           \n\t"
+    "xor      %[temp5],  %[temp5],  %[temp5]           \n\t"
+    "movz     %[temp5],  %[temp6],  %[temp1]           \n\t"
+  "13:                                                 \n\t"
+    "beqz     %[temp17], 14f                           \n\t"
+    "xor      %[temp8],  %[temp8],  %[temp8]           \n\t"
+    "movz     %[temp8],  %[temp6],  %[temp15]          \n\t"
+  "14:                                                 \n\t"
+    "beqz     %[temp12], 15f                           \n\t"
+    "xor      %[temp11], %[temp11], %[temp11]          \n\t"
+    "movz     %[temp11], %[temp6],  %[temp10]          \n\t"
+  "15:                                                 \n\t"
+    "beqz     %[temp9],  16f                           \n\t"
+    "xor      %[temp16], %[temp16], %[temp16]          \n\t"
+    "movz     %[temp16], %[temp6],  %[temp3]           \n\t"
+  "16:                                                 \n\t"
+    "sb       %[temp5],  0+3*"XSTR(BPS)"(%[dst])       \n\t"
+    "sb       %[temp8],  1+3*"XSTR(BPS)"(%[dst])       \n\t"
+    "sb       %[temp11], 2+3*"XSTR(BPS)"(%[dst])       \n\t"
+    "sb       %[temp16], 3+3*"XSTR(BPS)"(%[dst])       \n\t"
+
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+      [temp6]"=&r"(temp6), [temp7]"=&r"(temp7), [temp8]"=&r"(temp8),
+      [temp9]"=&r"(temp9), [temp10]"=&r"(temp10), [temp11]"=&r"(temp11),
+      [temp12]"=&r"(temp12), [temp13]"=&r"(temp13), [temp14]"=&r"(temp14),
+      [temp15]"=&r"(temp15), [temp16]"=&r"(temp16), [temp17]"=&r"(temp17),
+      [temp18]"=&r"(temp18)
+    : [in]"r"(p_in), [kC1]"r"(kC1), [kC2]"r"(kC2), [dst]"r"(dst)
+    : "memory", "hi", "lo"
+  );
+}
+
+static void TransformTwo(const int16_t* in, uint8_t* dst, int do_two) {
+  TransformOne(in, dst);
+  if (do_two) {
+    TransformOne(in + 16, dst + 4);
+  }
+}
+
+#endif  // WEBP_USE_MIPS32
+
+//------------------------------------------------------------------------------
+// Entry point
+
+extern void VP8DspInitMIPS32(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8DspInitMIPS32(void) {
+#if defined(WEBP_USE_MIPS32)
+  VP8InitClipTables();
+
+  VP8Transform = TransformTwo;
+
+  VP8VFilter16 = VFilter16;
+  VP8HFilter16 = HFilter16;
+  VP8VFilter8 = VFilter8;
+  VP8HFilter8 = HFilter8;
+  VP8VFilter16i = VFilter16i;
+  VP8HFilter16i = HFilter16i;
+  VP8VFilter8i = VFilter8i;
+  VP8HFilter8i = HFilter8i;
+
+  VP8SimpleVFilter16 = SimpleVFilter16;
+  VP8SimpleHFilter16 = SimpleHFilter16;
+  VP8SimpleVFilter16i = SimpleVFilter16i;
+  VP8SimpleHFilter16i = SimpleHFilter16i;
+#endif  // WEBP_USE_MIPS32
+}
diff --git a/Source/LibWebP/src/dsp/dsp.dec_mips_dsp_r2.c b/Source/LibWebP/src/dsp/dsp.dec_mips_dsp_r2.c
new file mode 100644
index 0000000..dac2c93
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.dec_mips_dsp_r2.c
@@ -0,0 +1,992 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// MIPS version of dsp functions
+//
+// Author(s):  Djordje Pesut    (djordje.pesut at imgtec.com)
+//             Jovan Zelincevic (jovan.zelincevic at imgtec.com)
+
+#include "./dsp.h"
+
+#if defined(WEBP_USE_MIPS_DSP_R2)
+
+#include "./mips_macro.h"
+
+static const int kC1 = 20091 + (1 << 16);
+static const int kC2 = 35468;
+
+#define MUL(a, b) (((a) * (b)) >> 16)
+
+static void TransformDC(const int16_t* in, uint8_t* dst) {
+  int temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8, temp9, temp10;
+
+  __asm__ volatile (
+    LOAD_WITH_OFFSET_X4(temp1, temp2, temp3, temp4, dst,
+                        0, 0, 0, 0,
+                        0, 1, 2, 3,
+                        BPS)
+    "lh               %[temp5],  0(%[in])               \n\t"
+    "addiu            %[temp5],  %[temp5],  4           \n\t"
+    "ins              %[temp5],  %[temp5],  16, 16      \n\t"
+    "shra.ph          %[temp5],  %[temp5],  3           \n\t"
+    CONVERT_2_BYTES_TO_HALF(temp6, temp7, temp8, temp9, temp10, temp1, temp2,
+                            temp3, temp1, temp2, temp3, temp4)
+    STORE_SAT_SUM_X2(temp6, temp7, temp8, temp9, temp10, temp1, temp2, temp3,
+                     temp5, temp5, temp5, temp5, temp5, temp5, temp5, temp5,
+                     dst, 0, 1, 2, 3, BPS)
+
+    OUTPUT_EARLY_CLOBBER_REGS_10()
+    : [in]"r"(in), [dst]"r"(dst)
+    : "memory"
+  );
+}
+
+static void TransformAC3(const int16_t* in, uint8_t* dst) {
+  const int a = in[0] + 4;
+  int c4 = MUL(in[4], kC2);
+  const int d4 = MUL(in[4], kC1);
+  const int c1 = MUL(in[1], kC2);
+  const int d1 = MUL(in[1], kC1);
+  int temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8, temp9;
+  int temp10, temp11, temp12, temp13, temp14, temp15, temp16, temp17, temp18;
+
+  __asm__ volatile (
+    "ins              %[c4],      %[d4],     16,       16    \n\t"
+    "replv.ph         %[temp1],   %[a]                       \n\t"
+    "replv.ph         %[temp4],   %[d1]                      \n\t"
+    ADD_SUB_HALVES(temp2, temp3, temp1, c4)
+    "replv.ph         %[temp5],   %[c1]                      \n\t"
+    SHIFT_R_SUM_X2(temp1, temp6, temp7, temp8, temp2, temp9, temp10, temp4,
+                   temp2, temp2, temp3, temp3, temp4, temp5, temp4, temp5)
+    LOAD_WITH_OFFSET_X4(temp3, temp5, temp11, temp12, dst,
+                        0, 0, 0, 0,
+                        0, 1, 2, 3,
+                        BPS)
+    CONVERT_2_BYTES_TO_HALF(temp13, temp14, temp3, temp15, temp5, temp16,
+                            temp11, temp17, temp3, temp5, temp11, temp12)
+    PACK_2_HALVES_TO_WORD(temp12, temp18, temp7, temp6, temp1, temp8, temp2,
+                          temp4, temp7, temp6, temp10, temp9)
+    STORE_SAT_SUM_X2(temp13, temp14, temp3, temp15, temp5, temp16, temp11,
+                     temp17, temp12, temp18, temp1, temp8, temp2, temp4,
+                     temp7, temp6, dst, 0, 1, 2, 3, BPS)
+
+    OUTPUT_EARLY_CLOBBER_REGS_18(),
+      [c4]"+&r"(c4)
+    : [dst]"r"(dst), [a]"r"(a), [d1]"r"(d1), [d4]"r"(d4), [c1]"r"(c1)
+    : "memory"
+  );
+}
+
+static void TransformOne(const int16_t* in, uint8_t* dst) {
+  int temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8, temp9;
+  int temp10, temp11, temp12, temp13, temp14, temp15, temp16, temp17, temp18;
+
+  __asm__ volatile (
+    "ulw              %[temp1],   0(%[in])                 \n\t"
+    "ulw              %[temp2],   16(%[in])                \n\t"
+    LOAD_IN_X2(temp5, temp6, 24, 26)
+    ADD_SUB_HALVES(temp3, temp4, temp1, temp2)
+    LOAD_IN_X2(temp1, temp2, 8, 10)
+    MUL_SHIFT_SUM(temp7, temp8, temp9, temp10, temp11, temp12, temp13, temp14,
+                  temp10, temp8, temp9, temp7, temp1, temp2, temp5, temp6,
+                  temp13, temp11, temp14, temp12)
+    INSERT_HALF_X2(temp8, temp7, temp10, temp9)
+    "ulw              %[temp17],  4(%[in])                 \n\t"
+    "ulw              %[temp18],  20(%[in])                \n\t"
+    ADD_SUB_HALVES(temp1, temp2, temp3, temp8)
+    ADD_SUB_HALVES(temp5, temp6, temp4, temp7)
+    ADD_SUB_HALVES(temp7, temp8, temp17, temp18)
+    LOAD_IN_X2(temp17, temp18, 12, 14)
+    LOAD_IN_X2(temp9, temp10, 28, 30)
+    MUL_SHIFT_SUM(temp11, temp12, temp13, temp14, temp15, temp16, temp4, temp17,
+                  temp12, temp14, temp11, temp13, temp17, temp18, temp9, temp10,
+                  temp15, temp4, temp16, temp17)
+    INSERT_HALF_X2(temp11, temp12, temp13, temp14)
+    ADD_SUB_HALVES(temp17, temp8, temp8, temp11)
+    ADD_SUB_HALVES(temp3, temp4, temp7, temp12)
+
+    // horizontal
+    SRA_16(temp9, temp10, temp11, temp12, temp1, temp2, temp5, temp6)
+    INSERT_HALF_X2(temp1, temp6, temp5, temp2)
+    SRA_16(temp13, temp14, temp15, temp16, temp3, temp4, temp17, temp8)
+    "repl.ph          %[temp2],   0x4                      \n\t"
+    INSERT_HALF_X2(temp3, temp8, temp17, temp4)
+    "addq.ph          %[temp1],   %[temp1],  %[temp2]      \n\t"
+    "addq.ph          %[temp6],   %[temp6],  %[temp2]      \n\t"
+    ADD_SUB_HALVES(temp2, temp4, temp1, temp3)
+    ADD_SUB_HALVES(temp5, temp7, temp6, temp8)
+    MUL_SHIFT_SUM(temp1, temp3, temp6, temp8, temp9, temp13, temp17, temp18,
+                  temp3, temp13, temp1, temp9, temp9, temp13, temp11, temp15,
+                  temp6, temp17, temp8, temp18)
+    MUL_SHIFT_SUM(temp6, temp8, temp18, temp17, temp11, temp15, temp12, temp16,
+                  temp8, temp15, temp6, temp11, temp12, temp16, temp10, temp14,
+                  temp18, temp12, temp17, temp16)
+    INSERT_HALF_X2(temp1, temp3, temp9, temp13)
+    INSERT_HALF_X2(temp6, temp8, temp11, temp15)
+    SHIFT_R_SUM_X2(temp9, temp10, temp11, temp12, temp13, temp14, temp15,
+                   temp16, temp2, temp4, temp5, temp7, temp3, temp1, temp8,
+                   temp6)
+    PACK_2_HALVES_TO_WORD(temp1, temp2, temp3, temp4, temp9, temp12, temp13,
+                          temp16, temp11, temp10, temp15, temp14)
+    LOAD_WITH_OFFSET_X4(temp10, temp11, temp14, temp15, dst,
+                        0, 0, 0, 0,
+                        0, 1, 2, 3,
+                        BPS)
+    CONVERT_2_BYTES_TO_HALF(temp5, temp6, temp7, temp8, temp17, temp18, temp10,
+                            temp11, temp10, temp11, temp14, temp15)
+    STORE_SAT_SUM_X2(temp5, temp6, temp7, temp8, temp17, temp18, temp10, temp11,
+                     temp9, temp12, temp1, temp2, temp13, temp16, temp3, temp4,
+                     dst, 0, 1, 2, 3, BPS)
+
+    OUTPUT_EARLY_CLOBBER_REGS_18()
+    : [dst]"r"(dst), [in]"r"(in), [kC1]"r"(kC1), [kC2]"r"(kC2)
+    : "memory", "hi", "lo"
+  );
+}
+
+static void TransformTwo(const int16_t* in, uint8_t* dst, int do_two) {
+  TransformOne(in, dst);
+  if (do_two) {
+    TransformOne(in + 16, dst + 4);
+  }
+}
+
+static WEBP_INLINE void FilterLoop26(uint8_t* p,
+                                     int hstride, int vstride, int size,
+                                     int thresh, int ithresh, int hev_thresh) {
+  const int thresh2 = 2 * thresh + 1;
+  int temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8, temp9;
+  int temp10, temp11, temp12, temp13, temp14, temp15;
+
+  __asm__ volatile (
+    ".set      push                                      \n\t"
+    ".set      noreorder                                 \n\t"
+  "1:                                                    \n\t"
+    "negu      %[temp1],  %[hstride]                     \n\t"
+    "addiu     %[size],   %[size],        -1             \n\t"
+    "sll       %[temp2],  %[hstride],     1              \n\t"
+    "sll       %[temp3],  %[temp1],       1              \n\t"
+    "addu      %[temp4],  %[temp2],       %[hstride]     \n\t"
+    "addu      %[temp5],  %[temp3],       %[temp1]       \n\t"
+    "lbu       %[temp7],  0(%[p])                        \n\t"
+    "sll       %[temp6],  %[temp3],       1              \n\t"
+    "lbux      %[temp8],  %[temp5](%[p])                 \n\t"
+    "lbux      %[temp9],  %[temp3](%[p])                 \n\t"
+    "lbux      %[temp10], %[temp1](%[p])                 \n\t"
+    "lbux      %[temp11], %[temp6](%[p])                 \n\t"
+    "lbux      %[temp12], %[hstride](%[p])               \n\t"
+    "lbux      %[temp13], %[temp2](%[p])                 \n\t"
+    "lbux      %[temp14], %[temp4](%[p])                 \n\t"
+    "subu      %[temp1],  %[temp10],      %[temp7]       \n\t"
+    "subu      %[temp2],  %[temp9],       %[temp12]      \n\t"
+    "absq_s.w  %[temp3],  %[temp1]                       \n\t"
+    "absq_s.w  %[temp4],  %[temp2]                       \n\t"
+    "negu      %[temp1],  %[temp1]                       \n\t"
+    "sll       %[temp3],  %[temp3],       2              \n\t"
+    "addu      %[temp15], %[temp3],       %[temp4]       \n\t"
+    "subu      %[temp3],  %[temp15],      %[thresh2]     \n\t"
+    "sll       %[temp6],  %[temp1],       1              \n\t"
+    "bgtz      %[temp3],  3f                             \n\t"
+    " subu     %[temp4],  %[temp11],      %[temp8]       \n\t"
+    "absq_s.w  %[temp4],  %[temp4]                       \n\t"
+    "shll_s.w  %[temp2],  %[temp2],       24             \n\t"
+    "subu      %[temp4],  %[temp4],       %[ithresh]     \n\t"
+    "bgtz      %[temp4],  3f                             \n\t"
+    " subu     %[temp3],  %[temp8],       %[temp9]       \n\t"
+    "absq_s.w  %[temp3],  %[temp3]                       \n\t"
+    "subu      %[temp3],  %[temp3],       %[ithresh]     \n\t"
+    "bgtz      %[temp3],  3f                             \n\t"
+    " subu     %[temp5],  %[temp9],       %[temp10]      \n\t"
+    "absq_s.w  %[temp3],  %[temp5]                       \n\t"
+    "absq_s.w  %[temp5],  %[temp5]                       \n\t"
+    "subu      %[temp3],  %[temp3],       %[ithresh]     \n\t"
+    "bgtz      %[temp3],  3f                             \n\t"
+    " subu     %[temp3],  %[temp14],      %[temp13]      \n\t"
+    "absq_s.w  %[temp3],  %[temp3]                       \n\t"
+    "slt       %[temp5],  %[hev_thresh],  %[temp5]       \n\t"
+    "subu      %[temp3],  %[temp3],       %[ithresh]     \n\t"
+    "bgtz      %[temp3],  3f                             \n\t"
+    " subu     %[temp3],  %[temp13],      %[temp12]      \n\t"
+    "absq_s.w  %[temp3],  %[temp3]                       \n\t"
+    "sra       %[temp4],  %[temp2],       24             \n\t"
+    "subu      %[temp3],  %[temp3],       %[ithresh]     \n\t"
+    "bgtz      %[temp3],  3f                             \n\t"
+    " subu     %[temp15], %[temp12],      %[temp7]       \n\t"
+    "absq_s.w  %[temp3],  %[temp15]                      \n\t"
+    "absq_s.w  %[temp15], %[temp15]                      \n\t"
+    "subu      %[temp3],  %[temp3],       %[ithresh]     \n\t"
+    "bgtz      %[temp3],  3f                             \n\t"
+    " slt      %[temp15], %[hev_thresh],  %[temp15]      \n\t"
+    "addu      %[temp3],  %[temp6],       %[temp1]       \n\t"
+    "or        %[temp2],  %[temp5],       %[temp15]      \n\t"
+    "addu      %[temp5],  %[temp4],       %[temp3]       \n\t"
+    "beqz      %[temp2],  4f                             \n\t"
+    " shra_r.w %[temp1],  %[temp5],       3              \n\t"
+    "addiu     %[temp2],  %[temp5],       3              \n\t"
+    "sra       %[temp2],  %[temp2],       3              \n\t"
+    "shll_s.w  %[temp1],  %[temp1],       27             \n\t"
+    "shll_s.w  %[temp2],  %[temp2],       27             \n\t"
+    "subu      %[temp3],  %[p],           %[hstride]     \n\t"
+    "sra       %[temp1],  %[temp1],       27             \n\t"
+    "sra       %[temp2],  %[temp2],       27             \n\t"
+    "subu      %[temp1],  %[temp7],       %[temp1]       \n\t"
+    "addu      %[temp2],  %[temp10],      %[temp2]       \n\t"
+    "lbux      %[temp2],  %[temp2](%[VP8kclip1])         \n\t"
+    "lbux      %[temp1],  %[temp1](%[VP8kclip1])         \n\t"
+    "sb        %[temp2],  0(%[temp3])                    \n\t"
+    "j         3f                                        \n\t"
+    " sb       %[temp1],  0(%[p])                        \n\t"
+  "4:                                                    \n\t"
+    "shll_s.w  %[temp5],  %[temp5],       24             \n\t"
+    "subu      %[temp14], %[p],           %[hstride]     \n\t"
+    "subu      %[temp11], %[temp14],      %[hstride]     \n\t"
+    "sra       %[temp6],  %[temp5],       24             \n\t"
+    "sll       %[temp1],  %[temp6],       3              \n\t"
+    "subu      %[temp15], %[temp11],      %[hstride]     \n\t"
+    "addu      %[temp2],  %[temp6],       %[temp1]       \n\t"
+    "sll       %[temp3],  %[temp2],       1              \n\t"
+    "addu      %[temp4],  %[temp3],       %[temp2]       \n\t"
+    "addiu     %[temp2],  %[temp2],       63             \n\t"
+    "addiu     %[temp3],  %[temp3],       63             \n\t"
+    "addiu     %[temp4],  %[temp4],       63             \n\t"
+    "sra       %[temp2],  %[temp2],       7              \n\t"
+    "sra       %[temp3],  %[temp3],       7              \n\t"
+    "sra       %[temp4],  %[temp4],       7              \n\t"
+    "addu      %[temp1],  %[temp8],       %[temp2]       \n\t"
+    "addu      %[temp5],  %[temp9],       %[temp3]       \n\t"
+    "addu      %[temp6],  %[temp10],      %[temp4]       \n\t"
+    "subu      %[temp8],  %[temp7],       %[temp4]       \n\t"
+    "subu      %[temp7],  %[temp12],      %[temp3]       \n\t"
+    "addu      %[temp10], %[p],           %[hstride]     \n\t"
+    "subu      %[temp9],  %[temp13],      %[temp2]       \n\t"
+    "addu      %[temp12], %[temp10],      %[hstride]     \n\t"
+    "lbux      %[temp2],  %[temp1](%[VP8kclip1])         \n\t"
+    "lbux      %[temp3],  %[temp5](%[VP8kclip1])         \n\t"
+    "lbux      %[temp4],  %[temp6](%[VP8kclip1])         \n\t"
+    "lbux      %[temp5],  %[temp8](%[VP8kclip1])         \n\t"
+    "lbux      %[temp6],  %[temp7](%[VP8kclip1])         \n\t"
+    "lbux      %[temp8],  %[temp9](%[VP8kclip1])         \n\t"
+    "sb        %[temp2],  0(%[temp15])                   \n\t"
+    "sb        %[temp3],  0(%[temp11])                   \n\t"
+    "sb        %[temp4],  0(%[temp14])                   \n\t"
+    "sb        %[temp5],  0(%[p])                        \n\t"
+    "sb        %[temp6],  0(%[temp10])                   \n\t"
+    "sb        %[temp8],  0(%[temp12])                   \n\t"
+  "3:                                                    \n\t"
+    "bgtz      %[size],   1b                             \n\t"
+    " addu     %[p],      %[p],           %[vstride]     \n\t"
+    ".set      pop                                       \n\t"
+    : [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),[temp3]"=&r"(temp3),
+      [temp4]"=&r"(temp4), [temp5]"=&r"(temp5), [temp6]"=&r"(temp6),
+      [temp7]"=&r"(temp7),[temp8]"=&r"(temp8),[temp9]"=&r"(temp9),
+      [temp10]"=&r"(temp10),[temp11]"=&r"(temp11),[temp12]"=&r"(temp12),
+      [temp13]"=&r"(temp13),[temp14]"=&r"(temp14),[temp15]"=&r"(temp15),
+      [size]"+&r"(size), [p]"+&r"(p)
+    : [hstride]"r"(hstride), [thresh2]"r"(thresh2),
+      [ithresh]"r"(ithresh),[vstride]"r"(vstride), [hev_thresh]"r"(hev_thresh),
+      [VP8kclip1]"r"(VP8kclip1)
+    : "memory"
+  );
+}
+
+static WEBP_INLINE void FilterLoop24(uint8_t* p,
+                                     int hstride, int vstride, int size,
+                                     int thresh, int ithresh, int hev_thresh) {
+  int p0, q0, p1, q1, p2, q2, p3, q3;
+  int step1, step2, temp1, temp2, temp3, temp4;
+  uint8_t* pTemp0;
+  uint8_t* pTemp1;
+  const int thresh2 = 2 * thresh + 1;
+
+  __asm__ volatile (
+    ".set      push                                   \n\t"
+    ".set      noreorder                              \n\t"
+    "bltz      %[size],    3f                         \n\t"
+    " nop                                             \n\t"
+  "2:                                                 \n\t"
+    "negu      %[step1],   %[hstride]                 \n\t"
+    "lbu       %[q0],      0(%[p])                    \n\t"
+    "lbux      %[p0],      %[step1](%[p])             \n\t"
+    "subu      %[step1],   %[step1],      %[hstride]  \n\t"
+    "lbux      %[q1],      %[hstride](%[p])           \n\t"
+    "subu      %[temp1],   %[p0],         %[q0]       \n\t"
+    "lbux      %[p1],      %[step1](%[p])             \n\t"
+    "addu      %[step2],   %[hstride],    %[hstride]  \n\t"
+    "absq_s.w  %[temp2],   %[temp1]                   \n\t"
+    "subu      %[temp3],   %[p1],         %[q1]       \n\t"
+    "absq_s.w  %[temp4],   %[temp3]                   \n\t"
+    "sll       %[temp2],   %[temp2],      2           \n\t"
+    "addu      %[temp2],   %[temp2],      %[temp4]    \n\t"
+    "subu      %[temp4],   %[temp2],      %[thresh2]  \n\t"
+    "subu      %[step1],   %[step1],      %[hstride]  \n\t"
+    "bgtz      %[temp4],   0f                         \n\t"
+    " lbux     %[p2],      %[step1](%[p])             \n\t"
+    "subu      %[step1],   %[step1],      %[hstride]  \n\t"
+    "lbux      %[q2],      %[step2](%[p])             \n\t"
+    "lbux      %[p3],      %[step1](%[p])             \n\t"
+    "subu      %[temp4],   %[p2],         %[p1]       \n\t"
+    "addu      %[step2],   %[step2],      %[hstride]  \n\t"
+    "subu      %[temp2],   %[p3],         %[p2]       \n\t"
+    "absq_s.w  %[temp4],   %[temp4]                   \n\t"
+    "absq_s.w  %[temp2],   %[temp2]                   \n\t"
+    "lbux      %[q3],      %[step2](%[p])             \n\t"
+    "subu      %[temp4],   %[temp4],      %[ithresh]  \n\t"
+    "negu      %[temp1],   %[temp1]                   \n\t"
+    "bgtz      %[temp4],   0f                         \n\t"
+    " subu     %[temp2],   %[temp2],      %[ithresh]  \n\t"
+    "subu      %[p3],      %[p1],         %[p0]       \n\t"
+    "bgtz      %[temp2],   0f                         \n\t"
+    " absq_s.w %[p3],      %[p3]                      \n\t"
+    "subu      %[temp4],   %[q3],         %[q2]       \n\t"
+    "subu      %[pTemp0],  %[p],          %[hstride]  \n\t"
+    "absq_s.w  %[temp4],   %[temp4]                   \n\t"
+    "subu      %[temp2],   %[p3],         %[ithresh]  \n\t"
+    "sll       %[step1],   %[temp1],      1           \n\t"
+    "bgtz      %[temp2],   0f                         \n\t"
+    " subu     %[temp4],   %[temp4],      %[ithresh]  \n\t"
+    "subu      %[temp2],   %[q2],         %[q1]       \n\t"
+    "bgtz      %[temp4],   0f                         \n\t"
+    " absq_s.w %[temp2],   %[temp2]                   \n\t"
+    "subu      %[q3],      %[q1],         %[q0]       \n\t"
+    "absq_s.w  %[q3],      %[q3]                      \n\t"
+    "subu      %[temp2],   %[temp2],      %[ithresh]  \n\t"
+    "addu      %[temp1],   %[temp1],      %[step1]    \n\t"
+    "bgtz      %[temp2],   0f                         \n\t"
+    " subu     %[temp4],   %[q3],         %[ithresh]  \n\t"
+    "slt       %[p3],      %[hev_thresh], %[p3]       \n\t"
+    "bgtz      %[temp4],   0f                         \n\t"
+    " slt      %[q3],      %[hev_thresh], %[q3]       \n\t"
+    "or        %[q3],      %[q3],         %[p3]       \n\t"
+    "bgtz      %[q3],      1f                         \n\t"
+    " shra_r.w %[temp2],   %[temp1],      3           \n\t"
+    "addiu     %[temp1],   %[temp1],      3           \n\t"
+    "sra       %[temp1],   %[temp1],      3           \n\t"
+    "shll_s.w  %[temp2],   %[temp2],      27          \n\t"
+    "shll_s.w  %[temp1],   %[temp1],      27          \n\t"
+    "addu      %[pTemp1],  %[p],          %[hstride]  \n\t"
+    "sra       %[temp2],   %[temp2],      27          \n\t"
+    "sra       %[temp1],   %[temp1],      27          \n\t"
+    "addiu     %[step1],   %[temp2],      1           \n\t"
+    "sra       %[step1],   %[step1],      1           \n\t"
+    "addu      %[p0],      %[p0],         %[temp1]    \n\t"
+    "addu      %[p1],      %[p1],         %[step1]    \n\t"
+    "subu      %[q0],      %[q0],         %[temp2]    \n\t"
+    "subu      %[q1],      %[q1],         %[step1]    \n\t"
+    "lbux      %[temp2],   %[p0](%[VP8kclip1])        \n\t"
+    "lbux      %[temp3],   %[q0](%[VP8kclip1])        \n\t"
+    "lbux      %[temp4],   %[q1](%[VP8kclip1])        \n\t"
+    "sb        %[temp2],   0(%[pTemp0])               \n\t"
+    "lbux      %[temp1],   %[p1](%[VP8kclip1])        \n\t"
+    "subu      %[pTemp0],  %[pTemp0],    %[hstride]   \n\t"
+    "sb        %[temp3],   0(%[p])                    \n\t"
+    "sb        %[temp4],   0(%[pTemp1])               \n\t"
+    "j         0f                                     \n\t"
+    " sb       %[temp1],   0(%[pTemp0])               \n\t"
+  "1:                                                 \n\t"
+    "shll_s.w  %[temp3],   %[temp3],      24          \n\t"
+    "sra       %[temp3],   %[temp3],      24          \n\t"
+    "addu      %[temp1],   %[temp1],      %[temp3]    \n\t"
+    "shra_r.w  %[temp2],   %[temp1],      3           \n\t"
+    "addiu     %[temp1],   %[temp1],      3           \n\t"
+    "shll_s.w  %[temp2],   %[temp2],      27          \n\t"
+    "sra       %[temp1],   %[temp1],      3           \n\t"
+    "shll_s.w  %[temp1],   %[temp1],      27          \n\t"
+    "sra       %[temp2],   %[temp2],      27          \n\t"
+    "sra       %[temp1],   %[temp1],      27          \n\t"
+    "addu      %[p0],      %[p0],         %[temp1]    \n\t"
+    "subu      %[q0],      %[q0],         %[temp2]    \n\t"
+    "lbux      %[temp1],   %[p0](%[VP8kclip1])        \n\t"
+    "lbux      %[temp2],   %[q0](%[VP8kclip1])        \n\t"
+    "sb        %[temp2],   0(%[p])                    \n\t"
+    "sb        %[temp1],   0(%[pTemp0])               \n\t"
+  "0:                                                 \n\t"
+    "subu      %[size],    %[size],       1           \n\t"
+    "bgtz      %[size],    2b                         \n\t"
+    " addu     %[p],       %[p],          %[vstride]  \n\t"
+  "3:                                                 \n\t"
+    ".set      pop                                    \n\t"
+    : [p0]"=&r"(p0), [q0]"=&r"(q0), [p1]"=&r"(p1), [q1]"=&r"(q1),
+      [p2]"=&r"(p2), [q2]"=&r"(q2), [p3]"=&r"(p3), [q3]"=&r"(q3),
+      [step2]"=&r"(step2), [step1]"=&r"(step1), [temp1]"=&r"(temp1),
+      [temp2]"=&r"(temp2), [temp3]"=&r"(temp3), [temp4]"=&r"(temp4),
+      [pTemp0]"=&r"(pTemp0), [pTemp1]"=&r"(pTemp1), [p]"+&r"(p),
+      [size]"+&r"(size)
+    : [vstride]"r"(vstride), [ithresh]"r"(ithresh),
+      [hev_thresh]"r"(hev_thresh), [hstride]"r"(hstride),
+      [VP8kclip1]"r"(VP8kclip1), [thresh2]"r"(thresh2)
+    : "memory"
+  );
+}
+
+// on macroblock edges
+static void VFilter16(uint8_t* p, int stride,
+                      int thresh, int ithresh, int hev_thresh) {
+  FilterLoop26(p, stride, 1, 16, thresh, ithresh, hev_thresh);
+}
+
+static void HFilter16(uint8_t* p, int stride,
+                      int thresh, int ithresh, int hev_thresh) {
+  FilterLoop26(p, 1, stride, 16, thresh, ithresh, hev_thresh);
+}
+
+// 8-pixels wide variant, for chroma filtering
+static void VFilter8(uint8_t* u, uint8_t* v, int stride,
+                     int thresh, int ithresh, int hev_thresh) {
+  FilterLoop26(u, stride, 1, 8, thresh, ithresh, hev_thresh);
+  FilterLoop26(v, stride, 1, 8, thresh, ithresh, hev_thresh);
+}
+
+static void HFilter8(uint8_t* u, uint8_t* v, int stride,
+                     int thresh, int ithresh, int hev_thresh) {
+  FilterLoop26(u, 1, stride, 8, thresh, ithresh, hev_thresh);
+  FilterLoop26(v, 1, stride, 8, thresh, ithresh, hev_thresh);
+}
+
+// on three inner edges
+static void VFilter16i(uint8_t* p, int stride,
+                       int thresh, int ithresh, int hev_thresh) {
+  int k;
+  for (k = 3; k > 0; --k) {
+    p += 4 * stride;
+    FilterLoop24(p, stride, 1, 16, thresh, ithresh, hev_thresh);
+  }
+}
+
+static void HFilter16i(uint8_t* p, int stride,
+                       int thresh, int ithresh, int hev_thresh) {
+  int k;
+  for (k = 3; k > 0; --k) {
+    p += 4;
+    FilterLoop24(p, 1, stride, 16, thresh, ithresh, hev_thresh);
+  }
+}
+
+static void VFilter8i(uint8_t* u, uint8_t* v, int stride,
+                      int thresh, int ithresh, int hev_thresh) {
+  FilterLoop24(u + 4 * stride, stride, 1, 8, thresh, ithresh, hev_thresh);
+  FilterLoop24(v + 4 * stride, stride, 1, 8, thresh, ithresh, hev_thresh);
+}
+
+static void HFilter8i(uint8_t* u, uint8_t* v, int stride,
+                      int thresh, int ithresh, int hev_thresh) {
+  FilterLoop24(u + 4, 1, stride, 8, thresh, ithresh, hev_thresh);
+  FilterLoop24(v + 4, 1, stride, 8, thresh, ithresh, hev_thresh);
+}
+
+#undef MUL
+
+//------------------------------------------------------------------------------
+// Simple In-loop filtering (Paragraph 15.2)
+
+static void SimpleVFilter16(uint8_t* p, int stride, int thresh) {
+  int i;
+  const int thresh2 = 2 * thresh + 1;
+  int temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8;
+  uint8_t* p1 = p - stride;
+  __asm__ volatile (
+    ".set      push                                      \n\t"
+    ".set      noreorder                                 \n\t"
+    "li        %[i],        16                           \n\t"
+  "0:                                                    \n\t"
+    "negu      %[temp4],    %[stride]                    \n\t"
+    "sll       %[temp5],    %[temp4],       1            \n\t"
+    "lbu       %[temp2],    0(%[p])                      \n\t"
+    "lbux      %[temp3],    %[stride](%[p])              \n\t"
+    "lbux      %[temp1],    %[temp4](%[p])               \n\t"
+    "lbux      %[temp0],    %[temp5](%[p])               \n\t"
+    "subu      %[temp7],    %[temp1],       %[temp2]     \n\t"
+    "subu      %[temp6],    %[temp0],       %[temp3]     \n\t"
+    "absq_s.w  %[temp4],    %[temp7]                     \n\t"
+    "absq_s.w  %[temp5],    %[temp6]                     \n\t"
+    "sll       %[temp4],    %[temp4],       2            \n\t"
+    "subu      %[temp5],    %[temp5],       %[thresh2]   \n\t"
+    "addu      %[temp5],    %[temp4],       %[temp5]     \n\t"
+    "negu      %[temp8],    %[temp7]                     \n\t"
+    "bgtz      %[temp5],    1f                           \n\t"
+    " addiu    %[i],        %[i],           -1           \n\t"
+    "sll       %[temp4],    %[temp8],       1            \n\t"
+    "shll_s.w  %[temp5],    %[temp6],       24           \n\t"
+    "addu      %[temp3],    %[temp4],       %[temp8]     \n\t"
+    "sra       %[temp5],    %[temp5],       24           \n\t"
+    "addu      %[temp3],    %[temp3],       %[temp5]     \n\t"
+    "addiu     %[temp7],    %[temp3],       3            \n\t"
+    "sra       %[temp7],    %[temp7],       3            \n\t"
+    "shra_r.w  %[temp8],    %[temp3],       3            \n\t"
+    "shll_s.w  %[temp0],    %[temp7],       27           \n\t"
+    "shll_s.w  %[temp4],    %[temp8],       27           \n\t"
+    "sra       %[temp0],    %[temp0],       27           \n\t"
+    "sra       %[temp4],    %[temp4],       27           \n\t"
+    "addu      %[temp7],    %[temp1],       %[temp0]     \n\t"
+    "subu      %[temp2],    %[temp2],       %[temp4]     \n\t"
+    "lbux      %[temp3],    %[temp7](%[VP8kclip1])       \n\t"
+    "lbux      %[temp4],    %[temp2](%[VP8kclip1])       \n\t"
+    "sb        %[temp3],    0(%[p1])                     \n\t"
+    "sb        %[temp4],    0(%[p])                      \n\t"
+  "1:                                                    \n\t"
+    "addiu     %[p1],       %[p1],          1            \n\t"
+    "bgtz      %[i],        0b                           \n\t"
+    " addiu    %[p],        %[p],           1            \n\t"
+    " .set     pop                                       \n\t"
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+      [temp6]"=&r"(temp6), [temp7]"=&r"(temp7), [temp8]"=&r"(temp8),
+      [p]"+&r"(p), [i]"=&r"(i), [p1]"+&r"(p1)
+    : [stride]"r"(stride), [VP8kclip1]"r"(VP8kclip1), [thresh2]"r"(thresh2)
+    : "memory"
+  );
+}
+
+// TEMP0 = SRC[A + A1 * BPS]
+// TEMP1 = SRC[B + B1 * BPS]
+// TEMP2 = SRC[C + C1 * BPS]
+// TEMP3 = SRC[D + D1 * BPS]
+#define LOAD_4_BYTES(TEMP0, TEMP1, TEMP2, TEMP3,                               \
+                     A, A1, B, B1, C, C1, D, D1, SRC)                          \
+  "lbu          %["#TEMP0"],   "#A"+"#A1"*"XSTR(BPS)"(%["#SRC"])     \n\t"     \
+  "lbu          %["#TEMP1"],   "#B"+"#B1"*"XSTR(BPS)"(%["#SRC"])     \n\t"     \
+  "lbu          %["#TEMP2"],   "#C"+"#C1"*"XSTR(BPS)"(%["#SRC"])     \n\t"     \
+  "lbu          %["#TEMP3"],   "#D"+"#D1"*"XSTR(BPS)"(%["#SRC"])     \n\t"     \
+
+static void SimpleHFilter16(uint8_t* p, int stride, int thresh) {
+  int i;
+  const int thresh2 = 2 * thresh + 1;
+  int temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8;
+  __asm__ volatile (
+    ".set      push                                     \n\t"
+    ".set      noreorder                                \n\t"
+    "li        %[i],       16                           \n\t"
+  "0:                                                   \n\t"
+    LOAD_4_BYTES(temp0, temp1, temp2, temp3, -2, 0, -1, 0, 0, 0, 1, 0, p)
+    "subu      %[temp7],    %[temp1],       %[temp2]    \n\t"
+    "subu      %[temp6],    %[temp0],       %[temp3]    \n\t"
+    "absq_s.w  %[temp4],    %[temp7]                    \n\t"
+    "absq_s.w  %[temp5],    %[temp6]                    \n\t"
+    "sll       %[temp4],    %[temp4],       2           \n\t"
+    "addu      %[temp5],    %[temp4],       %[temp5]    \n\t"
+    "subu      %[temp5],    %[temp5],       %[thresh2]  \n\t"
+    "negu      %[temp8],    %[temp7]                    \n\t"
+    "bgtz      %[temp5],    1f                          \n\t"
+    " addiu    %[i],        %[i],           -1          \n\t"
+    "sll       %[temp4],    %[temp8],       1           \n\t"
+    "shll_s.w  %[temp5],    %[temp6],       24          \n\t"
+    "addu      %[temp3],    %[temp4],       %[temp8]    \n\t"
+    "sra       %[temp5],    %[temp5],       24          \n\t"
+    "addu      %[temp3],    %[temp3],       %[temp5]    \n\t"
+    "addiu     %[temp7],    %[temp3],       3           \n\t"
+    "sra       %[temp7],    %[temp7],       3           \n\t"
+    "shra_r.w  %[temp8],    %[temp3],       3           \n\t"
+    "shll_s.w  %[temp0],    %[temp7],       27          \n\t"
+    "shll_s.w  %[temp4],    %[temp8],       27          \n\t"
+    "sra       %[temp0],    %[temp0],       27          \n\t"
+    "sra       %[temp4],    %[temp4],       27          \n\t"
+    "addu      %[temp7],    %[temp1],       %[temp0]    \n\t"
+    "subu      %[temp2],    %[temp2],       %[temp4]    \n\t"
+    "lbux      %[temp3],    %[temp7](%[VP8kclip1])      \n\t"
+    "lbux      %[temp4],    %[temp2](%[VP8kclip1])      \n\t"
+    "sb        %[temp3],    -1(%[p])                    \n\t"
+    "sb        %[temp4],    0(%[p])                     \n\t"
+  "1:                                                   \n\t"
+    "bgtz      %[i],        0b                          \n\t"
+    " addu     %[p],        %[p],           %[stride]   \n\t"
+    ".set      pop                                      \n\t"
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+      [temp6]"=&r"(temp6), [temp7]"=&r"(temp7), [temp8]"=&r"(temp8),
+      [p]"+&r"(p), [i]"=&r"(i)
+    : [stride]"r"(stride), [VP8kclip1]"r"(VP8kclip1), [thresh2]"r"(thresh2)
+    : "memory"
+  );
+}
+
+static void SimpleVFilter16i(uint8_t* p, int stride, int thresh) {
+  int k;
+  for (k = 3; k > 0; --k) {
+    p += 4 * stride;
+    SimpleVFilter16(p, stride, thresh);
+  }
+}
+
+static void SimpleHFilter16i(uint8_t* p, int stride, int thresh) {
+  int k;
+  for (k = 3; k > 0; --k) {
+    p += 4;
+    SimpleHFilter16(p, stride, thresh);
+  }
+}
+
+// DST[A * BPS]     = TEMP0
+// DST[B + C * BPS] = TEMP1
+#define STORE_8_BYTES(TEMP0, TEMP1, A, B, C, DST)                              \
+  "usw          %["#TEMP0"],   "#A"*"XSTR(BPS)"(%["#DST"])         \n\t"       \
+  "usw          %["#TEMP1"],   "#B"+"#C"*"XSTR(BPS)"(%["#DST"])    \n\t"
+
+static void VE4(uint8_t* dst) {    // vertical
+  const uint8_t* top = dst - BPS;
+  int temp0, temp1, temp2, temp3, temp4, temp5, temp6;
+  __asm__ volatile (
+    "ulw             %[temp0],   -1(%[top])              \n\t"
+    "ulh             %[temp1],   3(%[top])               \n\t"
+    "preceu.ph.qbr   %[temp2],   %[temp0]                \n\t"
+    "preceu.ph.qbl   %[temp3],   %[temp0]                \n\t"
+    "preceu.ph.qbr   %[temp4],   %[temp1]                \n\t"
+    "packrl.ph       %[temp5],   %[temp3],    %[temp2]   \n\t"
+    "packrl.ph       %[temp6],   %[temp4],    %[temp3]   \n\t"
+    "shll.ph         %[temp5],   %[temp5],    1          \n\t"
+    "shll.ph         %[temp6],   %[temp6],    1          \n\t"
+    "addq.ph         %[temp2],   %[temp5],    %[temp2]   \n\t"
+    "addq.ph         %[temp6],   %[temp6],    %[temp4]   \n\t"
+    "addq.ph         %[temp2],   %[temp2],    %[temp3]   \n\t"
+    "addq.ph         %[temp6],   %[temp6],    %[temp3]   \n\t"
+    "shra_r.ph       %[temp2],   %[temp2],    2          \n\t"
+    "shra_r.ph       %[temp6],   %[temp6],    2          \n\t"
+    "precr.qb.ph     %[temp4],   %[temp6],    %[temp2]   \n\t"
+    STORE_8_BYTES(temp4, temp4, 0, 0, 1, dst)
+    STORE_8_BYTES(temp4, temp4, 2, 0, 3, dst)
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+      [temp6]"=&r"(temp6)
+    : [top]"r"(top), [dst]"r"(dst)
+    : "memory"
+  );
+}
+
+static void DC4(uint8_t* dst) {   // DC
+  int temp0, temp1, temp2, temp3, temp4;
+  __asm__ volatile (
+    "ulw          %[temp0],   -1*"XSTR(BPS)"(%[dst])   \n\t"
+    LOAD_4_BYTES(temp1, temp2, temp3, temp4, -1, 0, -1, 1, -1, 2, -1, 3, dst)
+    "ins          %[temp1],   %[temp2],    8,     8    \n\t"
+    "ins          %[temp1],   %[temp3],    16,    8    \n\t"
+    "ins          %[temp1],   %[temp4],    24,    8    \n\t"
+    "raddu.w.qb   %[temp0],   %[temp0]                 \n\t"
+    "raddu.w.qb   %[temp1],   %[temp1]                 \n\t"
+    "addu         %[temp0],   %[temp0],    %[temp1]    \n\t"
+    "shra_r.w     %[temp0],   %[temp0],    3           \n\t"
+    "replv.qb     %[temp0],   %[temp0]                 \n\t"
+    STORE_8_BYTES(temp0, temp0, 0, 0, 1, dst)
+    STORE_8_BYTES(temp0, temp0, 2, 0, 3, dst)
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [temp3]"=&r"(temp3), [temp4]"=&r"(temp4)
+    : [dst]"r"(dst)
+    : "memory"
+  );
+}
+
+static void RD4(uint8_t* dst) {   // Down-right
+  int temp0, temp1, temp2, temp3, temp4;
+  int temp5, temp6, temp7, temp8;
+  __asm__ volatile (
+    LOAD_4_BYTES(temp0, temp1, temp2, temp3, -1, 0, -1, 1, -1, 2, -1, 3, dst)
+    "ulw            %[temp7],   -1-"XSTR(BPS)"(%[dst])         \n\t"
+    "ins            %[temp1],   %[temp0], 16, 16               \n\t"
+    "preceu.ph.qbr  %[temp5],   %[temp7]                       \n\t"
+    "ins            %[temp2],   %[temp1], 16, 16               \n\t"
+    "preceu.ph.qbl  %[temp4],   %[temp7]                       \n\t"
+    "ins            %[temp3],   %[temp2], 16, 16               \n\t"
+    "shll.ph        %[temp2],   %[temp2], 1                    \n\t"
+    "addq.ph        %[temp3],   %[temp3], %[temp1]             \n\t"
+    "packrl.ph      %[temp6],   %[temp5], %[temp1]             \n\t"
+    "addq.ph        %[temp3],   %[temp3], %[temp2]             \n\t"
+    "addq.ph        %[temp1],   %[temp1], %[temp5]             \n\t"
+    "shll.ph        %[temp6],   %[temp6], 1                    \n\t"
+    "addq.ph        %[temp1],   %[temp1], %[temp6]             \n\t"
+    "packrl.ph      %[temp0],   %[temp4], %[temp5]             \n\t"
+    "addq.ph        %[temp8],   %[temp5], %[temp4]             \n\t"
+    "shra_r.ph      %[temp3],   %[temp3], 2                    \n\t"
+    "shll.ph        %[temp0],   %[temp0], 1                    \n\t"
+    "shra_r.ph      %[temp1],   %[temp1], 2                    \n\t"
+    "addq.ph        %[temp8],   %[temp0], %[temp8]             \n\t"
+    "lbu            %[temp5],   3-"XSTR(BPS)"(%[dst])          \n\t"
+    "precrq.ph.w    %[temp7],   %[temp7], %[temp7]             \n\t"
+    "shra_r.ph      %[temp8],   %[temp8], 2                    \n\t"
+    "ins            %[temp7],   %[temp5], 0,  8                \n\t"
+    "precr.qb.ph    %[temp2],   %[temp1], %[temp3]             \n\t"
+    "raddu.w.qb     %[temp4],   %[temp7]                       \n\t"
+    "precr.qb.ph    %[temp6],   %[temp8], %[temp1]             \n\t"
+    "shra_r.w       %[temp4],   %[temp4], 2                    \n\t"
+    STORE_8_BYTES(temp2, temp6, 3, 0, 1, dst)
+    "prepend        %[temp2],   %[temp8], 8                    \n\t"
+    "prepend        %[temp6],   %[temp4], 8                    \n\t"
+    STORE_8_BYTES(temp2, temp6, 2, 0, 0, dst)
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+      [temp6]"=&r"(temp6), [temp7]"=&r"(temp7), [temp8]"=&r"(temp8)
+    : [dst]"r"(dst)
+    : "memory"
+  );
+}
+
+// TEMP0 = SRC[A * BPS]
+// TEMP1 = SRC[B + C * BPS]
+#define LOAD_8_BYTES(TEMP0, TEMP1, A, B, C, SRC)                               \
+  "ulw          %["#TEMP0"],   "#A"*"XSTR(BPS)"(%["#SRC"])         \n\t"       \
+  "ulw          %["#TEMP1"],   "#B"+"#C"*"XSTR(BPS)"(%["#SRC"])    \n\t"
+
+static void LD4(uint8_t* dst) {   // Down-Left
+  int temp0, temp1, temp2, temp3, temp4;
+  int temp5, temp6, temp7, temp8, temp9;
+  __asm__ volatile (
+    LOAD_8_BYTES(temp0, temp1, -1, 4, -1, dst)
+    "preceu.ph.qbl   %[temp2],    %[temp0]                     \n\t"
+    "preceu.ph.qbr   %[temp3],    %[temp0]                     \n\t"
+    "preceu.ph.qbr   %[temp4],    %[temp1]                     \n\t"
+    "preceu.ph.qbl   %[temp5],    %[temp1]                     \n\t"
+    "packrl.ph       %[temp6],    %[temp2],    %[temp3]        \n\t"
+    "packrl.ph       %[temp7],    %[temp4],    %[temp2]        \n\t"
+    "packrl.ph       %[temp8],    %[temp5],    %[temp4]        \n\t"
+    "shll.ph         %[temp6],    %[temp6],    1               \n\t"
+    "addq.ph         %[temp9],    %[temp2],    %[temp6]        \n\t"
+    "shll.ph         %[temp7],    %[temp7],    1               \n\t"
+    "addq.ph         %[temp9],    %[temp9],    %[temp3]        \n\t"
+    "shll.ph         %[temp8],    %[temp8],    1               \n\t"
+    "shra_r.ph       %[temp9],    %[temp9],    2               \n\t"
+    "addq.ph         %[temp3],    %[temp4],    %[temp7]        \n\t"
+    "addq.ph         %[temp0],    %[temp5],    %[temp8]        \n\t"
+    "addq.ph         %[temp3],    %[temp3],    %[temp2]        \n\t"
+    "addq.ph         %[temp0],    %[temp0],    %[temp4]        \n\t"
+    "shra_r.ph       %[temp3],    %[temp3],    2               \n\t"
+    "shra_r.ph       %[temp0],    %[temp0],    2               \n\t"
+    "srl             %[temp1],    %[temp1],    24              \n\t"
+    "sll             %[temp1],    %[temp1],    1               \n\t"
+    "raddu.w.qb      %[temp5],    %[temp5]                     \n\t"
+    "precr.qb.ph     %[temp9],    %[temp3],    %[temp9]        \n\t"
+    "precr.qb.ph     %[temp3],    %[temp0],    %[temp3]        \n\t"
+    "addu            %[temp1],    %[temp1],    %[temp5]        \n\t"
+    "shra_r.w        %[temp1],    %[temp1],    2               \n\t"
+    STORE_8_BYTES(temp9, temp3, 0, 0, 2, dst)
+    "prepend         %[temp9],    %[temp0],    8               \n\t"
+    "prepend         %[temp3],    %[temp1],    8               \n\t"
+    STORE_8_BYTES(temp9, temp3, 1, 0, 3, dst)
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+      [temp6]"=&r"(temp6), [temp7]"=&r"(temp7), [temp8]"=&r"(temp8),
+      [temp9]"=&r"(temp9)
+    : [dst]"r"(dst)
+    : "memory"
+  );
+}
+
+//------------------------------------------------------------------------------
+// Chroma
+
+static void DC8uv(uint8_t* dst) {     // DC
+  int temp0, temp1, temp2, temp3, temp4;
+  int temp5, temp6, temp7, temp8, temp9;
+  __asm__ volatile (
+    LOAD_8_BYTES(temp0, temp1, -1, 4, -1, dst)
+    LOAD_4_BYTES(temp2, temp3, temp4, temp5, -1, 0, -1, 1, -1, 2, -1, 3, dst)
+    LOAD_4_BYTES(temp6, temp7, temp8, temp9, -1, 4, -1, 5, -1, 6, -1, 7, dst)
+    "raddu.w.qb   %[temp0],   %[temp0]                   \n\t"
+    "raddu.w.qb   %[temp1],   %[temp1]                   \n\t"
+    "addu         %[temp2],   %[temp2],    %[temp3]      \n\t"
+    "addu         %[temp4],   %[temp4],    %[temp5]      \n\t"
+    "addu         %[temp6],   %[temp6],    %[temp7]      \n\t"
+    "addu         %[temp8],   %[temp8],    %[temp9]      \n\t"
+    "addu         %[temp0],   %[temp0],    %[temp1]      \n\t"
+    "addu         %[temp2],   %[temp2],    %[temp4]      \n\t"
+    "addu         %[temp6],   %[temp6],    %[temp8]      \n\t"
+    "addu         %[temp0],   %[temp0],    %[temp2]      \n\t"
+    "addu         %[temp0],   %[temp0],    %[temp6]      \n\t"
+    "shra_r.w     %[temp0],   %[temp0],    4             \n\t"
+    "replv.qb     %[temp0],   %[temp0]                   \n\t"
+    STORE_8_BYTES(temp0, temp0, 0, 4, 0, dst)
+    STORE_8_BYTES(temp0, temp0, 1, 4, 1, dst)
+    STORE_8_BYTES(temp0, temp0, 2, 4, 2, dst)
+    STORE_8_BYTES(temp0, temp0, 3, 4, 3, dst)
+    STORE_8_BYTES(temp0, temp0, 4, 4, 4, dst)
+    STORE_8_BYTES(temp0, temp0, 5, 4, 5, dst)
+    STORE_8_BYTES(temp0, temp0, 6, 4, 6, dst)
+    STORE_8_BYTES(temp0, temp0, 7, 4, 7, dst)
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+      [temp6]"=&r"(temp6), [temp7]"=&r"(temp7), [temp8]"=&r"(temp8),
+      [temp9]"=&r"(temp9)
+    : [dst]"r"(dst)
+    : "memory"
+  );
+}
+
+static void DC8uvNoLeft(uint8_t* dst) {   // DC with no left samples
+  int temp0, temp1;
+  __asm__ volatile (
+    LOAD_8_BYTES(temp0, temp1, -1, 4, -1, dst)
+    "raddu.w.qb   %[temp0],   %[temp0]                   \n\t"
+    "raddu.w.qb   %[temp1],   %[temp1]                   \n\t"
+    "addu         %[temp0],   %[temp0],    %[temp1]      \n\t"
+    "shra_r.w     %[temp0],   %[temp0],    3             \n\t"
+    "replv.qb     %[temp0],   %[temp0]                   \n\t"
+    STORE_8_BYTES(temp0, temp0, 0, 4, 0, dst)
+    STORE_8_BYTES(temp0, temp0, 1, 4, 1, dst)
+    STORE_8_BYTES(temp0, temp0, 2, 4, 2, dst)
+    STORE_8_BYTES(temp0, temp0, 3, 4, 3, dst)
+    STORE_8_BYTES(temp0, temp0, 4, 4, 4, dst)
+    STORE_8_BYTES(temp0, temp0, 5, 4, 5, dst)
+    STORE_8_BYTES(temp0, temp0, 6, 4, 6, dst)
+    STORE_8_BYTES(temp0, temp0, 7, 4, 7, dst)
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1)
+    : [dst]"r"(dst)
+    : "memory"
+  );
+}
+
+static void DC8uvNoTop(uint8_t* dst) {  // DC with no top samples
+  int temp0, temp1, temp2, temp3, temp4;
+  int temp5, temp6, temp7, temp8;
+  __asm__ volatile (
+    LOAD_4_BYTES(temp2, temp3, temp4, temp5, -1, 0, -1, 1, -1, 2, -1, 3, dst)
+    LOAD_4_BYTES(temp6, temp7, temp8, temp1, -1, 4, -1, 5, -1, 6, -1, 7, dst)
+    "addu         %[temp2],   %[temp2],    %[temp3]      \n\t"
+    "addu         %[temp4],   %[temp4],    %[temp5]      \n\t"
+    "addu         %[temp6],   %[temp6],    %[temp7]      \n\t"
+    "addu         %[temp8],   %[temp8],    %[temp1]      \n\t"
+    "addu         %[temp2],   %[temp2],    %[temp4]      \n\t"
+    "addu         %[temp6],   %[temp6],    %[temp8]      \n\t"
+    "addu         %[temp0],   %[temp6],    %[temp2]      \n\t"
+    "shra_r.w     %[temp0],   %[temp0],    3             \n\t"
+    "replv.qb     %[temp0],   %[temp0]                   \n\t"
+    STORE_8_BYTES(temp0, temp0, 0, 4, 0, dst)
+    STORE_8_BYTES(temp0, temp0, 1, 4, 1, dst)
+    STORE_8_BYTES(temp0, temp0, 2, 4, 2, dst)
+    STORE_8_BYTES(temp0, temp0, 3, 4, 3, dst)
+    STORE_8_BYTES(temp0, temp0, 4, 4, 4, dst)
+    STORE_8_BYTES(temp0, temp0, 5, 4, 5, dst)
+    STORE_8_BYTES(temp0, temp0, 6, 4, 6, dst)
+    STORE_8_BYTES(temp0, temp0, 7, 4, 7, dst)
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+      [temp6]"=&r"(temp6), [temp7]"=&r"(temp7), [temp8]"=&r"(temp8)
+    : [dst]"r"(dst)
+    : "memory"
+  );
+}
+
+#undef LOAD_8_BYTES
+#undef STORE_8_BYTES
+#undef LOAD_4_BYTES
+
+#define CLIPPING(SIZE)                                                         \
+  "preceu.ph.qbl   %[temp2],   %[temp0]                  \n\t"                 \
+  "preceu.ph.qbr   %[temp0],   %[temp0]                  \n\t"                 \
+".if "#SIZE" == 8                                        \n\t"                 \
+  "preceu.ph.qbl   %[temp3],   %[temp1]                  \n\t"                 \
+  "preceu.ph.qbr   %[temp1],   %[temp1]                  \n\t"                 \
+".endif                                                  \n\t"                 \
+  "addu.ph         %[temp2],   %[temp2],   %[dst_1]      \n\t"                 \
+  "addu.ph         %[temp0],   %[temp0],   %[dst_1]      \n\t"                 \
+".if "#SIZE" == 8                                        \n\t"                 \
+  "addu.ph         %[temp3],   %[temp3],   %[dst_1]      \n\t"                 \
+  "addu.ph         %[temp1],   %[temp1],   %[dst_1]      \n\t"                 \
+".endif                                                  \n\t"                 \
+  "shll_s.ph       %[temp2],   %[temp2],   7             \n\t"                 \
+  "shll_s.ph       %[temp0],   %[temp0],   7             \n\t"                 \
+".if "#SIZE" == 8                                        \n\t"                 \
+  "shll_s.ph       %[temp3],   %[temp3],   7             \n\t"                 \
+  "shll_s.ph       %[temp1],   %[temp1],   7             \n\t"                 \
+".endif                                                  \n\t"                 \
+  "precrqu_s.qb.ph %[temp0],   %[temp2],   %[temp0]      \n\t"                 \
+".if "#SIZE" == 8                                        \n\t"                 \
+  "precrqu_s.qb.ph %[temp1],   %[temp3],   %[temp1]      \n\t"                 \
+".endif                                                  \n\t"
+
+
+#define CLIP_8B_TO_DST(DST, TOP, SIZE) do {                                    \
+  int dst_1 = ((int)(DST)[-1] << 16) + (DST)[-1];                              \
+  int temp0, temp1, temp2, temp3;                                              \
+  __asm__ volatile (                                                           \
+  ".if "#SIZE" < 8                                       \n\t"                 \
+    "ulw             %[temp0],   0(%[top])               \n\t"                 \
+    "subu.ph         %[dst_1],   %[dst_1],    %[top_1]   \n\t"                 \
+    CLIPPING(4)                                                                \
+    "usw             %[temp0],   0(%[dst])               \n\t"                 \
+  ".else                                                 \n\t"                 \
+    "ulw             %[temp0],   0(%[top])               \n\t"                 \
+    "ulw             %[temp1],   4(%[top])               \n\t"                 \
+    "subu.ph         %[dst_1],   %[dst_1],    %[top_1]   \n\t"                 \
+    CLIPPING(8)                                                                \
+    "usw             %[temp0],   0(%[dst])               \n\t"                 \
+    "usw             %[temp1],   4(%[dst])               \n\t"                 \
+  ".if "#SIZE" == 16                                     \n\t"                 \
+    "ulw             %[temp0],   8(%[top])               \n\t"                 \
+    "ulw             %[temp1],   12(%[top])              \n\t"                 \
+    CLIPPING(8)                                                                \
+    "usw             %[temp0],   8(%[dst])               \n\t"                 \
+    "usw             %[temp1],   12(%[dst])              \n\t"                 \
+  ".endif                                                \n\t"                 \
+  ".endif                                                \n\t"                 \
+    : [dst_1]"+&r"(dst_1), [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),           \
+      [temp2]"=&r"(temp2), [temp3]"=&r"(temp3)                                 \
+    : [top_1]"r"(top_1), [top]"r"((TOP)), [dst]"r"((DST))                      \
+    : "memory"                                                                 \
+  );                                                                           \
+} while (0)
+
+#define CLIP_TO_DST(DST, SIZE) do {                                            \
+  int y;                                                                       \
+  const uint8_t* top = (DST) - BPS;                                            \
+  const int top_1 = ((int)top[-1] << 16) + top[-1];                            \
+  for (y = 0; y < (SIZE); ++y) {                                               \
+    CLIP_8B_TO_DST((DST), top, (SIZE));                                        \
+    (DST) += BPS;                                                              \
+  }                                                                            \
+} while (0)
+
+#define TRUE_MOTION(DST, SIZE)                                                 \
+static void TrueMotion##SIZE(uint8_t* (DST)) {                                 \
+  CLIP_TO_DST((DST), (SIZE));                                                  \
+}
+
+TRUE_MOTION(dst, 4)
+TRUE_MOTION(dst, 8)
+TRUE_MOTION(dst, 16)
+
+#undef TRUE_MOTION
+#undef CLIP_TO_DST
+#undef CLIP_8B_TO_DST
+#undef CLIPPING
+
+#endif  // WEBP_USE_MIPS_DSP_R2
+
+//------------------------------------------------------------------------------
+// Entry point
+
+extern void VP8DspInitMIPSdspR2(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8DspInitMIPSdspR2(void) {
+#if defined(WEBP_USE_MIPS_DSP_R2)
+  VP8TransformDC = TransformDC;
+  VP8TransformAC3 = TransformAC3;
+  VP8Transform = TransformTwo;
+
+  VP8VFilter16 = VFilter16;
+  VP8HFilter16 = HFilter16;
+  VP8VFilter8 = VFilter8;
+  VP8HFilter8 = HFilter8;
+  VP8VFilter16i = VFilter16i;
+  VP8HFilter16i = HFilter16i;
+  VP8VFilter8i = VFilter8i;
+  VP8HFilter8i = HFilter8i;
+  VP8SimpleVFilter16 = SimpleVFilter16;
+  VP8SimpleHFilter16 = SimpleHFilter16;
+  VP8SimpleVFilter16i = SimpleVFilter16i;
+  VP8SimpleHFilter16i = SimpleHFilter16i;
+
+  VP8PredLuma4[0] = DC4;
+  VP8PredLuma4[1] = TrueMotion4;
+  VP8PredLuma4[2] = VE4;
+  VP8PredLuma4[4] = RD4;
+  VP8PredLuma4[6] = LD4;
+
+  VP8PredChroma8[0] = DC8uv;
+  VP8PredChroma8[1] = TrueMotion8;
+  VP8PredChroma8[4] = DC8uvNoTop;
+  VP8PredChroma8[5] = DC8uvNoLeft;
+
+  VP8PredLuma16[1] = TrueMotion16;
+#endif
+}
diff --git a/Source/LibWebP/src/dsp/dsp.dec_neon.c b/Source/LibWebP/src/dsp/dsp.dec_neon.c
new file mode 100644
index 0000000..fb3f9f2
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.dec_neon.c
@@ -0,0 +1,1489 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// ARM NEON version of dsp functions and loop filtering.
+//
+// Authors: Somnath Banerjee (somnath at google.com)
+//          Johann Koenig (johannkoenig at google.com)
+
+#include "./dsp.h"
+
+#if defined(WEBP_USE_NEON)
+
+#include "./neon.h"
+#include "../dec/vp8i.h"
+
+//------------------------------------------------------------------------------
+// NxM Loading functions
+
+// Load/Store vertical edge
+#define LOAD8x4(c1, c2, c3, c4, b1, b2, stride)                                \
+  "vld4.8   {" #c1"[0], " #c2"[0], " #c3"[0], " #c4"[0]}," #b1 "," #stride"\n" \
+  "vld4.8   {" #c1"[1], " #c2"[1], " #c3"[1], " #c4"[1]}," #b2 "," #stride"\n" \
+  "vld4.8   {" #c1"[2], " #c2"[2], " #c3"[2], " #c4"[2]}," #b1 "," #stride"\n" \
+  "vld4.8   {" #c1"[3], " #c2"[3], " #c3"[3], " #c4"[3]}," #b2 "," #stride"\n" \
+  "vld4.8   {" #c1"[4], " #c2"[4], " #c3"[4], " #c4"[4]}," #b1 "," #stride"\n" \
+  "vld4.8   {" #c1"[5], " #c2"[5], " #c3"[5], " #c4"[5]}," #b2 "," #stride"\n" \
+  "vld4.8   {" #c1"[6], " #c2"[6], " #c3"[6], " #c4"[6]}," #b1 "," #stride"\n" \
+  "vld4.8   {" #c1"[7], " #c2"[7], " #c3"[7], " #c4"[7]}," #b2 "," #stride"\n"
+
+#define STORE8x2(c1, c2, p, stride)                                            \
+  "vst2.8   {" #c1"[0], " #c2"[0]}," #p "," #stride " \n"                      \
+  "vst2.8   {" #c1"[1], " #c2"[1]}," #p "," #stride " \n"                      \
+  "vst2.8   {" #c1"[2], " #c2"[2]}," #p "," #stride " \n"                      \
+  "vst2.8   {" #c1"[3], " #c2"[3]}," #p "," #stride " \n"                      \
+  "vst2.8   {" #c1"[4], " #c2"[4]}," #p "," #stride " \n"                      \
+  "vst2.8   {" #c1"[5], " #c2"[5]}," #p "," #stride " \n"                      \
+  "vst2.8   {" #c1"[6], " #c2"[6]}," #p "," #stride " \n"                      \
+  "vst2.8   {" #c1"[7], " #c2"[7]}," #p "," #stride " \n"
+
+#if !defined(WORK_AROUND_GCC)
+
+// This intrinsics version makes gcc-4.6.3 crash during Load4x??() compilation
+// (register alloc, probably). The variants somewhat mitigate the problem, but
+// not quite. HFilter16i() remains problematic.
+static WEBP_INLINE uint8x8x4_t Load4x8(const uint8_t* const src, int stride) {
+  const uint8x8_t zero = vdup_n_u8(0);
+  uint8x8x4_t out;
+  INIT_VECTOR4(out, zero, zero, zero, zero);
+  out = vld4_lane_u8(src + 0 * stride, out, 0);
+  out = vld4_lane_u8(src + 1 * stride, out, 1);
+  out = vld4_lane_u8(src + 2 * stride, out, 2);
+  out = vld4_lane_u8(src + 3 * stride, out, 3);
+  out = vld4_lane_u8(src + 4 * stride, out, 4);
+  out = vld4_lane_u8(src + 5 * stride, out, 5);
+  out = vld4_lane_u8(src + 6 * stride, out, 6);
+  out = vld4_lane_u8(src + 7 * stride, out, 7);
+  return out;
+}
+
+static WEBP_INLINE void Load4x16(const uint8_t* const src, int stride,
+                                 uint8x16_t* const p1, uint8x16_t* const p0,
+                                 uint8x16_t* const q0, uint8x16_t* const q1) {
+  // row0 = p1[0..7]|p0[0..7]|q0[0..7]|q1[0..7]
+  // row8 = p1[8..15]|p0[8..15]|q0[8..15]|q1[8..15]
+  const uint8x8x4_t row0 = Load4x8(src - 2 + 0 * stride, stride);
+  const uint8x8x4_t row8 = Load4x8(src - 2 + 8 * stride, stride);
+  *p1 = vcombine_u8(row0.val[0], row8.val[0]);
+  *p0 = vcombine_u8(row0.val[1], row8.val[1]);
+  *q0 = vcombine_u8(row0.val[2], row8.val[2]);
+  *q1 = vcombine_u8(row0.val[3], row8.val[3]);
+}
+
+#else  // WORK_AROUND_GCC
+
+#define LOADQ_LANE_32b(VALUE, LANE) do {                             \
+  (VALUE) = vld1q_lane_u32((const uint32_t*)src, (VALUE), (LANE));   \
+  src += stride;                                                     \
+} while (0)
+
+static WEBP_INLINE void Load4x16(const uint8_t* src, int stride,
+                                 uint8x16_t* const p1, uint8x16_t* const p0,
+                                 uint8x16_t* const q0, uint8x16_t* const q1) {
+  const uint32x4_t zero = vdupq_n_u32(0);
+  uint32x4x4_t in;
+  INIT_VECTOR4(in, zero, zero, zero, zero);
+  src -= 2;
+  LOADQ_LANE_32b(in.val[0], 0);
+  LOADQ_LANE_32b(in.val[1], 0);
+  LOADQ_LANE_32b(in.val[2], 0);
+  LOADQ_LANE_32b(in.val[3], 0);
+  LOADQ_LANE_32b(in.val[0], 1);
+  LOADQ_LANE_32b(in.val[1], 1);
+  LOADQ_LANE_32b(in.val[2], 1);
+  LOADQ_LANE_32b(in.val[3], 1);
+  LOADQ_LANE_32b(in.val[0], 2);
+  LOADQ_LANE_32b(in.val[1], 2);
+  LOADQ_LANE_32b(in.val[2], 2);
+  LOADQ_LANE_32b(in.val[3], 2);
+  LOADQ_LANE_32b(in.val[0], 3);
+  LOADQ_LANE_32b(in.val[1], 3);
+  LOADQ_LANE_32b(in.val[2], 3);
+  LOADQ_LANE_32b(in.val[3], 3);
+  // Transpose four 4x4 parts:
+  {
+    const uint8x16x2_t row01 = vtrnq_u8(vreinterpretq_u8_u32(in.val[0]),
+                                        vreinterpretq_u8_u32(in.val[1]));
+    const uint8x16x2_t row23 = vtrnq_u8(vreinterpretq_u8_u32(in.val[2]),
+                                        vreinterpretq_u8_u32(in.val[3]));
+    const uint16x8x2_t row02 = vtrnq_u16(vreinterpretq_u16_u8(row01.val[0]),
+                                         vreinterpretq_u16_u8(row23.val[0]));
+    const uint16x8x2_t row13 = vtrnq_u16(vreinterpretq_u16_u8(row01.val[1]),
+                                         vreinterpretq_u16_u8(row23.val[1]));
+    *p1 = vreinterpretq_u8_u16(row02.val[0]);
+    *p0 = vreinterpretq_u8_u16(row13.val[0]);
+    *q0 = vreinterpretq_u8_u16(row02.val[1]);
+    *q1 = vreinterpretq_u8_u16(row13.val[1]);
+  }
+}
+#undef LOADQ_LANE_32b
+
+#endif  // !WORK_AROUND_GCC
+
+static WEBP_INLINE void Load8x16(const uint8_t* const src, int stride,
+                                 uint8x16_t* const p3, uint8x16_t* const p2,
+                                 uint8x16_t* const p1, uint8x16_t* const p0,
+                                 uint8x16_t* const q0, uint8x16_t* const q1,
+                                 uint8x16_t* const q2, uint8x16_t* const q3) {
+  Load4x16(src - 2, stride, p3, p2, p1, p0);
+  Load4x16(src + 2, stride, q0, q1, q2, q3);
+}
+
+static WEBP_INLINE void Load16x4(const uint8_t* const src, int stride,
+                                 uint8x16_t* const p1, uint8x16_t* const p0,
+                                 uint8x16_t* const q0, uint8x16_t* const q1) {
+  *p1 = vld1q_u8(src - 2 * stride);
+  *p0 = vld1q_u8(src - 1 * stride);
+  *q0 = vld1q_u8(src + 0 * stride);
+  *q1 = vld1q_u8(src + 1 * stride);
+}
+
+static WEBP_INLINE void Load16x8(const uint8_t* const src, int stride,
+                                 uint8x16_t* const p3, uint8x16_t* const p2,
+                                 uint8x16_t* const p1, uint8x16_t* const p0,
+                                 uint8x16_t* const q0, uint8x16_t* const q1,
+                                 uint8x16_t* const q2, uint8x16_t* const q3) {
+  Load16x4(src - 2  * stride, stride, p3, p2, p1, p0);
+  Load16x4(src + 2  * stride, stride, q0, q1, q2, q3);
+}
+
+static WEBP_INLINE void Load8x8x2(const uint8_t* const u,
+                                  const uint8_t* const v,
+                                  int stride,
+                                  uint8x16_t* const p3, uint8x16_t* const p2,
+                                  uint8x16_t* const p1, uint8x16_t* const p0,
+                                  uint8x16_t* const q0, uint8x16_t* const q1,
+                                  uint8x16_t* const q2, uint8x16_t* const q3) {
+  // We pack the 8x8 u-samples in the lower half of the uint8x16_t destination
+  // and the v-samples on the higher half.
+  *p3 = vcombine_u8(vld1_u8(u - 4 * stride), vld1_u8(v - 4 * stride));
+  *p2 = vcombine_u8(vld1_u8(u - 3 * stride), vld1_u8(v - 3 * stride));
+  *p1 = vcombine_u8(vld1_u8(u - 2 * stride), vld1_u8(v - 2 * stride));
+  *p0 = vcombine_u8(vld1_u8(u - 1 * stride), vld1_u8(v - 1 * stride));
+  *q0 = vcombine_u8(vld1_u8(u + 0 * stride), vld1_u8(v + 0 * stride));
+  *q1 = vcombine_u8(vld1_u8(u + 1 * stride), vld1_u8(v + 1 * stride));
+  *q2 = vcombine_u8(vld1_u8(u + 2 * stride), vld1_u8(v + 2 * stride));
+  *q3 = vcombine_u8(vld1_u8(u + 3 * stride), vld1_u8(v + 3 * stride));
+}
+
+#if !defined(WORK_AROUND_GCC)
+
+#define LOAD_UV_8(ROW) \
+  vcombine_u8(vld1_u8(u - 4 + (ROW) * stride), vld1_u8(v - 4 + (ROW) * stride))
+
+static WEBP_INLINE void Load8x8x2T(const uint8_t* const u,
+                                   const uint8_t* const v,
+                                   int stride,
+                                   uint8x16_t* const p3, uint8x16_t* const p2,
+                                   uint8x16_t* const p1, uint8x16_t* const p0,
+                                   uint8x16_t* const q0, uint8x16_t* const q1,
+                                   uint8x16_t* const q2, uint8x16_t* const q3) {
+  // We pack the 8x8 u-samples in the lower half of the uint8x16_t destination
+  // and the v-samples on the higher half.
+  const uint8x16_t row0 = LOAD_UV_8(0);
+  const uint8x16_t row1 = LOAD_UV_8(1);
+  const uint8x16_t row2 = LOAD_UV_8(2);
+  const uint8x16_t row3 = LOAD_UV_8(3);
+  const uint8x16_t row4 = LOAD_UV_8(4);
+  const uint8x16_t row5 = LOAD_UV_8(5);
+  const uint8x16_t row6 = LOAD_UV_8(6);
+  const uint8x16_t row7 = LOAD_UV_8(7);
+  // Perform two side-by-side 8x8 transposes
+  // u00 u01 u02 u03 u04 u05 u06 u07 | v00 v01 v02 v03 v04 v05 v06 v07
+  // u10 u11 u12 u13 u14 u15 u16 u17 | v10 v11 v12 ...
+  // u20 u21 u22 u23 u24 u25 u26 u27 | v20 v21 ...
+  // u30 u31 u32 u33 u34 u35 u36 u37 | ...
+  // u40 u41 u42 u43 u44 u45 u46 u47 | ...
+  // u50 u51 u52 u53 u54 u55 u56 u57 | ...
+  // u60 u61 u62 u63 u64 u65 u66 u67 | v60 ...
+  // u70 u71 u72 u73 u74 u75 u76 u77 | v70 v71 v72 ...
+  const uint8x16x2_t row01 = vtrnq_u8(row0, row1);  // u00 u10 u02 u12 ...
+                                                    // u01 u11 u03 u13 ...
+  const uint8x16x2_t row23 = vtrnq_u8(row2, row3);  // u20 u30 u22 u32 ...
+                                                    // u21 u31 u23 u33 ...
+  const uint8x16x2_t row45 = vtrnq_u8(row4, row5);  // ...
+  const uint8x16x2_t row67 = vtrnq_u8(row6, row7);  // ...
+  const uint16x8x2_t row02 = vtrnq_u16(vreinterpretq_u16_u8(row01.val[0]),
+                                       vreinterpretq_u16_u8(row23.val[0]));
+  const uint16x8x2_t row13 = vtrnq_u16(vreinterpretq_u16_u8(row01.val[1]),
+                                       vreinterpretq_u16_u8(row23.val[1]));
+  const uint16x8x2_t row46 = vtrnq_u16(vreinterpretq_u16_u8(row45.val[0]),
+                                       vreinterpretq_u16_u8(row67.val[0]));
+  const uint16x8x2_t row57 = vtrnq_u16(vreinterpretq_u16_u8(row45.val[1]),
+                                       vreinterpretq_u16_u8(row67.val[1]));
+  const uint32x4x2_t row04 = vtrnq_u32(vreinterpretq_u32_u16(row02.val[0]),
+                                       vreinterpretq_u32_u16(row46.val[0]));
+  const uint32x4x2_t row26 = vtrnq_u32(vreinterpretq_u32_u16(row02.val[1]),
+                                       vreinterpretq_u32_u16(row46.val[1]));
+  const uint32x4x2_t row15 = vtrnq_u32(vreinterpretq_u32_u16(row13.val[0]),
+                                       vreinterpretq_u32_u16(row57.val[0]));
+  const uint32x4x2_t row37 = vtrnq_u32(vreinterpretq_u32_u16(row13.val[1]),
+                                       vreinterpretq_u32_u16(row57.val[1]));
+  *p3 = vreinterpretq_u8_u32(row04.val[0]);
+  *p2 = vreinterpretq_u8_u32(row15.val[0]);
+  *p1 = vreinterpretq_u8_u32(row26.val[0]);
+  *p0 = vreinterpretq_u8_u32(row37.val[0]);
+  *q0 = vreinterpretq_u8_u32(row04.val[1]);
+  *q1 = vreinterpretq_u8_u32(row15.val[1]);
+  *q2 = vreinterpretq_u8_u32(row26.val[1]);
+  *q3 = vreinterpretq_u8_u32(row37.val[1]);
+}
+#undef LOAD_UV_8
+
+#endif  // !WORK_AROUND_GCC
+
+static WEBP_INLINE void Store2x8(const uint8x8x2_t v,
+                                 uint8_t* const dst, int stride) {
+  vst2_lane_u8(dst + 0 * stride, v, 0);
+  vst2_lane_u8(dst + 1 * stride, v, 1);
+  vst2_lane_u8(dst + 2 * stride, v, 2);
+  vst2_lane_u8(dst + 3 * stride, v, 3);
+  vst2_lane_u8(dst + 4 * stride, v, 4);
+  vst2_lane_u8(dst + 5 * stride, v, 5);
+  vst2_lane_u8(dst + 6 * stride, v, 6);
+  vst2_lane_u8(dst + 7 * stride, v, 7);
+}
+
+static WEBP_INLINE void Store2x16(const uint8x16_t p0, const uint8x16_t q0,
+                                  uint8_t* const dst, int stride) {
+  uint8x8x2_t lo, hi;
+  lo.val[0] = vget_low_u8(p0);
+  lo.val[1] = vget_low_u8(q0);
+  hi.val[0] = vget_high_u8(p0);
+  hi.val[1] = vget_high_u8(q0);
+  Store2x8(lo, dst - 1 + 0 * stride, stride);
+  Store2x8(hi, dst - 1 + 8 * stride, stride);
+}
+
+#if !defined(WORK_AROUND_GCC)
+static WEBP_INLINE void Store4x8(const uint8x8x4_t v,
+                                 uint8_t* const dst, int stride) {
+  vst4_lane_u8(dst + 0 * stride, v, 0);
+  vst4_lane_u8(dst + 1 * stride, v, 1);
+  vst4_lane_u8(dst + 2 * stride, v, 2);
+  vst4_lane_u8(dst + 3 * stride, v, 3);
+  vst4_lane_u8(dst + 4 * stride, v, 4);
+  vst4_lane_u8(dst + 5 * stride, v, 5);
+  vst4_lane_u8(dst + 6 * stride, v, 6);
+  vst4_lane_u8(dst + 7 * stride, v, 7);
+}
+
+static WEBP_INLINE void Store4x16(const uint8x16_t p1, const uint8x16_t p0,
+                                  const uint8x16_t q0, const uint8x16_t q1,
+                                  uint8_t* const dst, int stride) {
+  uint8x8x4_t lo, hi;
+  INIT_VECTOR4(lo,
+               vget_low_u8(p1), vget_low_u8(p0),
+               vget_low_u8(q0), vget_low_u8(q1));
+  INIT_VECTOR4(hi,
+               vget_high_u8(p1), vget_high_u8(p0),
+               vget_high_u8(q0), vget_high_u8(q1));
+  Store4x8(lo, dst - 2 + 0 * stride, stride);
+  Store4x8(hi, dst - 2 + 8 * stride, stride);
+}
+#endif  // !WORK_AROUND_GCC
+
+static WEBP_INLINE void Store16x2(const uint8x16_t p0, const uint8x16_t q0,
+                                  uint8_t* const dst, int stride) {
+  vst1q_u8(dst - stride, p0);
+  vst1q_u8(dst, q0);
+}
+
+static WEBP_INLINE void Store16x4(const uint8x16_t p1, const uint8x16_t p0,
+                                  const uint8x16_t q0, const uint8x16_t q1,
+                                  uint8_t* const dst, int stride) {
+  Store16x2(p1, p0, dst - stride, stride);
+  Store16x2(q0, q1, dst + stride, stride);
+}
+
+static WEBP_INLINE void Store8x2x2(const uint8x16_t p0, const uint8x16_t q0,
+                                   uint8_t* const u, uint8_t* const v,
+                                   int stride) {
+  // p0 and q0 contain the u+v samples packed in low/high halves.
+  vst1_u8(u - stride, vget_low_u8(p0));
+  vst1_u8(u,          vget_low_u8(q0));
+  vst1_u8(v - stride, vget_high_u8(p0));
+  vst1_u8(v,          vget_high_u8(q0));
+}
+
+static WEBP_INLINE void Store8x4x2(const uint8x16_t p1, const uint8x16_t p0,
+                                   const uint8x16_t q0, const uint8x16_t q1,
+                                   uint8_t* const u, uint8_t* const v,
+                                   int stride) {
+  // The p1...q1 registers contain the u+v samples packed in low/high halves.
+  Store8x2x2(p1, p0, u - stride, v - stride, stride);
+  Store8x2x2(q0, q1, u + stride, v + stride, stride);
+}
+
+#if !defined(WORK_AROUND_GCC)
+
+#define STORE6_LANE(DST, VAL0, VAL1, LANE) do {   \
+  vst3_lane_u8((DST) - 3, (VAL0), (LANE));        \
+  vst3_lane_u8((DST) + 0, (VAL1), (LANE));        \
+  (DST) += stride;                                \
+} while (0)
+
+static WEBP_INLINE void Store6x8x2(const uint8x16_t p2, const uint8x16_t p1,
+                                   const uint8x16_t p0, const uint8x16_t q0,
+                                   const uint8x16_t q1, const uint8x16_t q2,
+                                   uint8_t* u, uint8_t* v,
+                                   int stride) {
+  uint8x8x3_t u0, u1, v0, v1;
+  INIT_VECTOR3(u0, vget_low_u8(p2), vget_low_u8(p1), vget_low_u8(p0));
+  INIT_VECTOR3(u1, vget_low_u8(q0), vget_low_u8(q1), vget_low_u8(q2));
+  INIT_VECTOR3(v0, vget_high_u8(p2), vget_high_u8(p1), vget_high_u8(p0));
+  INIT_VECTOR3(v1, vget_high_u8(q0), vget_high_u8(q1), vget_high_u8(q2));
+  STORE6_LANE(u, u0, u1, 0);
+  STORE6_LANE(u, u0, u1, 1);
+  STORE6_LANE(u, u0, u1, 2);
+  STORE6_LANE(u, u0, u1, 3);
+  STORE6_LANE(u, u0, u1, 4);
+  STORE6_LANE(u, u0, u1, 5);
+  STORE6_LANE(u, u0, u1, 6);
+  STORE6_LANE(u, u0, u1, 7);
+  STORE6_LANE(v, v0, v1, 0);
+  STORE6_LANE(v, v0, v1, 1);
+  STORE6_LANE(v, v0, v1, 2);
+  STORE6_LANE(v, v0, v1, 3);
+  STORE6_LANE(v, v0, v1, 4);
+  STORE6_LANE(v, v0, v1, 5);
+  STORE6_LANE(v, v0, v1, 6);
+  STORE6_LANE(v, v0, v1, 7);
+}
+#undef STORE6_LANE
+
+static WEBP_INLINE void Store4x8x2(const uint8x16_t p1, const uint8x16_t p0,
+                                   const uint8x16_t q0, const uint8x16_t q1,
+                                   uint8_t* const u, uint8_t* const v,
+                                   int stride) {
+  uint8x8x4_t u0, v0;
+  INIT_VECTOR4(u0,
+               vget_low_u8(p1), vget_low_u8(p0),
+               vget_low_u8(q0), vget_low_u8(q1));
+  INIT_VECTOR4(v0,
+               vget_high_u8(p1), vget_high_u8(p0),
+               vget_high_u8(q0), vget_high_u8(q1));
+  vst4_lane_u8(u - 2 + 0 * stride, u0, 0);
+  vst4_lane_u8(u - 2 + 1 * stride, u0, 1);
+  vst4_lane_u8(u - 2 + 2 * stride, u0, 2);
+  vst4_lane_u8(u - 2 + 3 * stride, u0, 3);
+  vst4_lane_u8(u - 2 + 4 * stride, u0, 4);
+  vst4_lane_u8(u - 2 + 5 * stride, u0, 5);
+  vst4_lane_u8(u - 2 + 6 * stride, u0, 6);
+  vst4_lane_u8(u - 2 + 7 * stride, u0, 7);
+  vst4_lane_u8(v - 2 + 0 * stride, v0, 0);
+  vst4_lane_u8(v - 2 + 1 * stride, v0, 1);
+  vst4_lane_u8(v - 2 + 2 * stride, v0, 2);
+  vst4_lane_u8(v - 2 + 3 * stride, v0, 3);
+  vst4_lane_u8(v - 2 + 4 * stride, v0, 4);
+  vst4_lane_u8(v - 2 + 5 * stride, v0, 5);
+  vst4_lane_u8(v - 2 + 6 * stride, v0, 6);
+  vst4_lane_u8(v - 2 + 7 * stride, v0, 7);
+}
+
+#endif  // !WORK_AROUND_GCC
+
+// Zero extend 'v' to an int16x8_t.
+static WEBP_INLINE int16x8_t ConvertU8ToS16(uint8x8_t v) {
+  return vreinterpretq_s16_u16(vmovl_u8(v));
+}
+
+// Performs unsigned 8b saturation on 'dst01' and 'dst23' storing the result
+// to the corresponding rows of 'dst'.
+static WEBP_INLINE void SaturateAndStore4x4(uint8_t* const dst,
+                                            const int16x8_t dst01,
+                                            const int16x8_t dst23) {
+  // Unsigned saturate to 8b.
+  const uint8x8_t dst01_u8 = vqmovun_s16(dst01);
+  const uint8x8_t dst23_u8 = vqmovun_s16(dst23);
+
+  // Store the results.
+  vst1_lane_u32((uint32_t*)(dst + 0 * BPS), vreinterpret_u32_u8(dst01_u8), 0);
+  vst1_lane_u32((uint32_t*)(dst + 1 * BPS), vreinterpret_u32_u8(dst01_u8), 1);
+  vst1_lane_u32((uint32_t*)(dst + 2 * BPS), vreinterpret_u32_u8(dst23_u8), 0);
+  vst1_lane_u32((uint32_t*)(dst + 3 * BPS), vreinterpret_u32_u8(dst23_u8), 1);
+}
+
+static WEBP_INLINE void Add4x4(const int16x8_t row01, const int16x8_t row23,
+                               uint8_t* const dst) {
+  uint32x2_t dst01 = vdup_n_u32(0);
+  uint32x2_t dst23 = vdup_n_u32(0);
+
+  // Load the source pixels.
+  dst01 = vld1_lane_u32((uint32_t*)(dst + 0 * BPS), dst01, 0);
+  dst23 = vld1_lane_u32((uint32_t*)(dst + 2 * BPS), dst23, 0);
+  dst01 = vld1_lane_u32((uint32_t*)(dst + 1 * BPS), dst01, 1);
+  dst23 = vld1_lane_u32((uint32_t*)(dst + 3 * BPS), dst23, 1);
+
+  {
+    // Convert to 16b.
+    const int16x8_t dst01_s16 = ConvertU8ToS16(vreinterpret_u8_u32(dst01));
+    const int16x8_t dst23_s16 = ConvertU8ToS16(vreinterpret_u8_u32(dst23));
+
+    // Descale with rounding.
+    const int16x8_t out01 = vrsraq_n_s16(dst01_s16, row01, 3);
+    const int16x8_t out23 = vrsraq_n_s16(dst23_s16, row23, 3);
+    // Add the inverse transform.
+    SaturateAndStore4x4(dst, out01, out23);
+  }
+}
+
+//-----------------------------------------------------------------------------
+// Simple In-loop filtering (Paragraph 15.2)
+
+static uint8x16_t NeedsFilter(const uint8x16_t p1, const uint8x16_t p0,
+                              const uint8x16_t q0, const uint8x16_t q1,
+                              int thresh) {
+  const uint8x16_t thresh_v = vdupq_n_u8((uint8_t)thresh);
+  const uint8x16_t a_p0_q0 = vabdq_u8(p0, q0);               // abs(p0-q0)
+  const uint8x16_t a_p1_q1 = vabdq_u8(p1, q1);               // abs(p1-q1)
+  const uint8x16_t a_p0_q0_2 = vqaddq_u8(a_p0_q0, a_p0_q0);  // 2 * abs(p0-q0)
+  const uint8x16_t a_p1_q1_2 = vshrq_n_u8(a_p1_q1, 1);       // abs(p1-q1) / 2
+  const uint8x16_t sum = vqaddq_u8(a_p0_q0_2, a_p1_q1_2);
+  const uint8x16_t mask = vcgeq_u8(thresh_v, sum);
+  return mask;
+}
+
+static int8x16_t FlipSign(const uint8x16_t v) {
+  const uint8x16_t sign_bit = vdupq_n_u8(0x80);
+  return vreinterpretq_s8_u8(veorq_u8(v, sign_bit));
+}
+
+static uint8x16_t FlipSignBack(const int8x16_t v) {
+  const int8x16_t sign_bit = vdupq_n_s8(0x80);
+  return vreinterpretq_u8_s8(veorq_s8(v, sign_bit));
+}
+
+static int8x16_t GetBaseDelta(const int8x16_t p1, const int8x16_t p0,
+                              const int8x16_t q0, const int8x16_t q1) {
+  const int8x16_t q0_p0 = vqsubq_s8(q0, p0);      // (q0-p0)
+  const int8x16_t p1_q1 = vqsubq_s8(p1, q1);      // (p1-q1)
+  const int8x16_t s1 = vqaddq_s8(p1_q1, q0_p0);   // (p1-q1) + 1 * (q0 - p0)
+  const int8x16_t s2 = vqaddq_s8(q0_p0, s1);      // (p1-q1) + 2 * (q0 - p0)
+  const int8x16_t s3 = vqaddq_s8(q0_p0, s2);      // (p1-q1) + 3 * (q0 - p0)
+  return s3;
+}
+
+static int8x16_t GetBaseDelta0(const int8x16_t p0, const int8x16_t q0) {
+  const int8x16_t q0_p0 = vqsubq_s8(q0, p0);      // (q0-p0)
+  const int8x16_t s1 = vqaddq_s8(q0_p0, q0_p0);   // 2 * (q0 - p0)
+  const int8x16_t s2 = vqaddq_s8(q0_p0, s1);      // 3 * (q0 - p0)
+  return s2;
+}
+
+//------------------------------------------------------------------------------
+
+static void ApplyFilter2(const int8x16_t p0s, const int8x16_t q0s,
+                         const int8x16_t delta,
+                         uint8x16_t* const op0, uint8x16_t* const oq0) {
+  const int8x16_t kCst3 = vdupq_n_s8(0x03);
+  const int8x16_t kCst4 = vdupq_n_s8(0x04);
+  const int8x16_t delta_p3 = vqaddq_s8(delta, kCst3);
+  const int8x16_t delta_p4 = vqaddq_s8(delta, kCst4);
+  const int8x16_t delta3 = vshrq_n_s8(delta_p3, 3);
+  const int8x16_t delta4 = vshrq_n_s8(delta_p4, 3);
+  const int8x16_t sp0 = vqaddq_s8(p0s, delta3);
+  const int8x16_t sq0 = vqsubq_s8(q0s, delta4);
+  *op0 = FlipSignBack(sp0);
+  *oq0 = FlipSignBack(sq0);
+}
+
+#if defined(WEBP_USE_INTRINSICS)
+
+static void DoFilter2(const uint8x16_t p1, const uint8x16_t p0,
+                      const uint8x16_t q0, const uint8x16_t q1,
+                      const uint8x16_t mask,
+                      uint8x16_t* const op0, uint8x16_t* const oq0) {
+  const int8x16_t p1s = FlipSign(p1);
+  const int8x16_t p0s = FlipSign(p0);
+  const int8x16_t q0s = FlipSign(q0);
+  const int8x16_t q1s = FlipSign(q1);
+  const int8x16_t delta0 = GetBaseDelta(p1s, p0s, q0s, q1s);
+  const int8x16_t delta1 = vandq_s8(delta0, vreinterpretq_s8_u8(mask));
+  ApplyFilter2(p0s, q0s, delta1, op0, oq0);
+}
+
+static void SimpleVFilter16(uint8_t* p, int stride, int thresh) {
+  uint8x16_t p1, p0, q0, q1, op0, oq0;
+  Load16x4(p, stride, &p1, &p0, &q0, &q1);
+  {
+    const uint8x16_t mask = NeedsFilter(p1, p0, q0, q1, thresh);
+    DoFilter2(p1, p0, q0, q1, mask, &op0, &oq0);
+  }
+  Store16x2(op0, oq0, p, stride);
+}
+
+static void SimpleHFilter16(uint8_t* p, int stride, int thresh) {
+  uint8x16_t p1, p0, q0, q1, oq0, op0;
+  Load4x16(p, stride, &p1, &p0, &q0, &q1);
+  {
+    const uint8x16_t mask = NeedsFilter(p1, p0, q0, q1, thresh);
+    DoFilter2(p1, p0, q0, q1, mask, &op0, &oq0);
+  }
+  Store2x16(op0, oq0, p, stride);
+}
+
+#else
+
+#define QRegs "q0", "q1", "q2", "q3",                                          \
+              "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"
+
+#define FLIP_SIGN_BIT2(a, b, s)                                                \
+  "veor     " #a "," #a "," #s "               \n"                             \
+  "veor     " #b "," #b "," #s "               \n"                             \
+
+#define FLIP_SIGN_BIT4(a, b, c, d, s)                                          \
+  FLIP_SIGN_BIT2(a, b, s)                                                      \
+  FLIP_SIGN_BIT2(c, d, s)                                                      \
+
+#define NEEDS_FILTER(p1, p0, q0, q1, thresh, mask)                             \
+  "vabd.u8    q15," #p0 "," #q0 "         \n"  /* abs(p0 - q0) */              \
+  "vabd.u8    q14," #p1 "," #q1 "         \n"  /* abs(p1 - q1) */              \
+  "vqadd.u8   q15, q15, q15               \n"  /* abs(p0 - q0) * 2 */          \
+  "vshr.u8    q14, q14, #1                \n"  /* abs(p1 - q1) / 2 */          \
+  "vqadd.u8   q15, q15, q14     \n"  /* abs(p0 - q0) * 2 + abs(p1 - q1) / 2 */ \
+  "vdup.8     q14, " #thresh "            \n"                                  \
+  "vcge.u8   " #mask ", q14, q15          \n"  /* mask <= thresh */
+
+#define GET_BASE_DELTA(p1, p0, q0, q1, o)                                      \
+  "vqsub.s8   q15," #q0 "," #p0 "         \n"  /* (q0 - p0) */                 \
+  "vqsub.s8  " #o "," #p1 "," #q1 "       \n"  /* (p1 - q1) */                 \
+  "vqadd.s8  " #o "," #o ", q15           \n"  /* (p1 - q1) + 1 * (p0 - q0) */ \
+  "vqadd.s8  " #o "," #o ", q15           \n"  /* (p1 - q1) + 2 * (p0 - q0) */ \
+  "vqadd.s8  " #o "," #o ", q15           \n"  /* (p1 - q1) + 3 * (p0 - q0) */
+
+#define DO_SIMPLE_FILTER(p0, q0, fl)                                           \
+  "vmov.i8    q15, #0x03                  \n"                                  \
+  "vqadd.s8   q15, q15, " #fl "           \n"  /* filter1 = filter + 3 */      \
+  "vshr.s8    q15, q15, #3                \n"  /* filter1 >> 3 */              \
+  "vqadd.s8  " #p0 "," #p0 ", q15         \n"  /* p0 += filter1 */             \
+                                                                               \
+  "vmov.i8    q15, #0x04                  \n"                                  \
+  "vqadd.s8   q15, q15, " #fl "           \n"  /* filter1 = filter + 4 */      \
+  "vshr.s8    q15, q15, #3                \n"  /* filter2 >> 3 */              \
+  "vqsub.s8  " #q0 "," #q0 ", q15         \n"  /* q0 -= filter2 */
+
+// Applies filter on 2 pixels (p0 and q0)
+#define DO_FILTER2(p1, p0, q0, q1, thresh)                                     \
+  NEEDS_FILTER(p1, p0, q0, q1, thresh, q9)     /* filter mask in q9 */         \
+  "vmov.i8    q10, #0x80                  \n"  /* sign bit */                  \
+  FLIP_SIGN_BIT4(p1, p0, q0, q1, q10)          /* convert to signed value */   \
+  GET_BASE_DELTA(p1, p0, q0, q1, q11)          /* get filter level  */         \
+  "vand       q9, q9, q11                 \n"  /* apply filter mask */         \
+  DO_SIMPLE_FILTER(p0, q0, q9)                 /* apply filter */              \
+  FLIP_SIGN_BIT2(p0, q0, q10)
+
+static void SimpleVFilter16(uint8_t* p, int stride, int thresh) {
+  __asm__ volatile (
+    "sub        %[p], %[p], %[stride], lsl #1  \n"  // p -= 2 * stride
+
+    "vld1.u8    {q1}, [%[p]], %[stride]        \n"  // p1
+    "vld1.u8    {q2}, [%[p]], %[stride]        \n"  // p0
+    "vld1.u8    {q3}, [%[p]], %[stride]        \n"  // q0
+    "vld1.u8    {q12}, [%[p]]                  \n"  // q1
+
+    DO_FILTER2(q1, q2, q3, q12, %[thresh])
+
+    "sub        %[p], %[p], %[stride], lsl #1  \n"  // p -= 2 * stride
+
+    "vst1.u8    {q2}, [%[p]], %[stride]        \n"  // store op0
+    "vst1.u8    {q3}, [%[p]]                   \n"  // store oq0
+    : [p] "+r"(p)
+    : [stride] "r"(stride), [thresh] "r"(thresh)
+    : "memory", QRegs
+  );
+}
+
+static void SimpleHFilter16(uint8_t* p, int stride, int thresh) {
+  __asm__ volatile (
+    "sub        r4, %[p], #2                   \n"  // base1 = p - 2
+    "lsl        r6, %[stride], #1              \n"  // r6 = 2 * stride
+    "add        r5, r4, %[stride]              \n"  // base2 = base1 + stride
+
+    LOAD8x4(d2, d3, d4, d5, [r4], [r5], r6)
+    LOAD8x4(d24, d25, d26, d27, [r4], [r5], r6)
+    "vswp       d3, d24                        \n"  // p1:q1 p0:q3
+    "vswp       d5, d26                        \n"  // q0:q2 q1:q4
+    "vswp       q2, q12                        \n"  // p1:q1 p0:q2 q0:q3 q1:q4
+
+    DO_FILTER2(q1, q2, q12, q13, %[thresh])
+
+    "sub        %[p], %[p], #1                 \n"  // p - 1
+
+    "vswp        d5, d24                       \n"
+    STORE8x2(d4, d5, [%[p]], %[stride])
+    STORE8x2(d24, d25, [%[p]], %[stride])
+
+    : [p] "+r"(p)
+    : [stride] "r"(stride), [thresh] "r"(thresh)
+    : "memory", "r4", "r5", "r6", QRegs
+  );
+}
+
+#endif    // WEBP_USE_INTRINSICS
+
+static void SimpleVFilter16i(uint8_t* p, int stride, int thresh) {
+  uint32_t k;
+  for (k = 3; k != 0; --k) {
+    p += 4 * stride;
+    SimpleVFilter16(p, stride, thresh);
+  }
+}
+
+static void SimpleHFilter16i(uint8_t* p, int stride, int thresh) {
+  uint32_t k;
+  for (k = 3; k != 0; --k) {
+    p += 4;
+    SimpleHFilter16(p, stride, thresh);
+  }
+}
+
+//------------------------------------------------------------------------------
+// Complex In-loop filtering (Paragraph 15.3)
+
+static uint8x16_t NeedsHev(const uint8x16_t p1, const uint8x16_t p0,
+                           const uint8x16_t q0, const uint8x16_t q1,
+                           int hev_thresh) {
+  const uint8x16_t hev_thresh_v = vdupq_n_u8((uint8_t)hev_thresh);
+  const uint8x16_t a_p1_p0 = vabdq_u8(p1, p0);  // abs(p1 - p0)
+  const uint8x16_t a_q1_q0 = vabdq_u8(q1, q0);  // abs(q1 - q0)
+  const uint8x16_t mask1 = vcgtq_u8(a_p1_p0, hev_thresh_v);
+  const uint8x16_t mask2 = vcgtq_u8(a_q1_q0, hev_thresh_v);
+  const uint8x16_t mask = vorrq_u8(mask1, mask2);
+  return mask;
+}
+
+static uint8x16_t NeedsFilter2(const uint8x16_t p3, const uint8x16_t p2,
+                               const uint8x16_t p1, const uint8x16_t p0,
+                               const uint8x16_t q0, const uint8x16_t q1,
+                               const uint8x16_t q2, const uint8x16_t q3,
+                               int ithresh, int thresh) {
+  const uint8x16_t ithresh_v = vdupq_n_u8((uint8_t)ithresh);
+  const uint8x16_t a_p3_p2 = vabdq_u8(p3, p2);  // abs(p3 - p2)
+  const uint8x16_t a_p2_p1 = vabdq_u8(p2, p1);  // abs(p2 - p1)
+  const uint8x16_t a_p1_p0 = vabdq_u8(p1, p0);  // abs(p1 - p0)
+  const uint8x16_t a_q3_q2 = vabdq_u8(q3, q2);  // abs(q3 - q2)
+  const uint8x16_t a_q2_q1 = vabdq_u8(q2, q1);  // abs(q2 - q1)
+  const uint8x16_t a_q1_q0 = vabdq_u8(q1, q0);  // abs(q1 - q0)
+  const uint8x16_t max1 = vmaxq_u8(a_p3_p2, a_p2_p1);
+  const uint8x16_t max2 = vmaxq_u8(a_p1_p0, a_q3_q2);
+  const uint8x16_t max3 = vmaxq_u8(a_q2_q1, a_q1_q0);
+  const uint8x16_t max12 = vmaxq_u8(max1, max2);
+  const uint8x16_t max123 = vmaxq_u8(max12, max3);
+  const uint8x16_t mask2 = vcgeq_u8(ithresh_v, max123);
+  const uint8x16_t mask1 = NeedsFilter(p1, p0, q0, q1, thresh);
+  const uint8x16_t mask = vandq_u8(mask1, mask2);
+  return mask;
+}
+
+//  4-points filter
+
+static void ApplyFilter4(
+    const int8x16_t p1, const int8x16_t p0,
+    const int8x16_t q0, const int8x16_t q1,
+    const int8x16_t delta0,
+    uint8x16_t* const op1, uint8x16_t* const op0,
+    uint8x16_t* const oq0, uint8x16_t* const oq1) {
+  const int8x16_t kCst3 = vdupq_n_s8(0x03);
+  const int8x16_t kCst4 = vdupq_n_s8(0x04);
+  const int8x16_t delta1 = vqaddq_s8(delta0, kCst4);
+  const int8x16_t delta2 = vqaddq_s8(delta0, kCst3);
+  const int8x16_t a1 = vshrq_n_s8(delta1, 3);
+  const int8x16_t a2 = vshrq_n_s8(delta2, 3);
+  const int8x16_t a3 = vrshrq_n_s8(a1, 1);   // a3 = (a1 + 1) >> 1
+  *op0 = FlipSignBack(vqaddq_s8(p0, a2));  // clip(p0 + a2)
+  *oq0 = FlipSignBack(vqsubq_s8(q0, a1));  // clip(q0 - a1)
+  *op1 = FlipSignBack(vqaddq_s8(p1, a3));  // clip(p1 + a3)
+  *oq1 = FlipSignBack(vqsubq_s8(q1, a3));  // clip(q1 - a3)
+}
+
+static void DoFilter4(
+    const uint8x16_t p1, const uint8x16_t p0,
+    const uint8x16_t q0, const uint8x16_t q1,
+    const uint8x16_t mask, const uint8x16_t hev_mask,
+    uint8x16_t* const op1, uint8x16_t* const op0,
+    uint8x16_t* const oq0, uint8x16_t* const oq1) {
+  // This is a fused version of DoFilter2() calling ApplyFilter2 directly
+  const int8x16_t p1s = FlipSign(p1);
+  int8x16_t p0s = FlipSign(p0);
+  int8x16_t q0s = FlipSign(q0);
+  const int8x16_t q1s = FlipSign(q1);
+  const uint8x16_t simple_lf_mask = vandq_u8(mask, hev_mask);
+
+  // do_filter2 part (simple loopfilter on pixels with hev)
+  {
+    const int8x16_t delta = GetBaseDelta(p1s, p0s, q0s, q1s);
+    const int8x16_t simple_lf_delta =
+        vandq_s8(delta, vreinterpretq_s8_u8(simple_lf_mask));
+    uint8x16_t tmp_p0, tmp_q0;
+    ApplyFilter2(p0s, q0s, simple_lf_delta, &tmp_p0, &tmp_q0);
+    // TODO(skal): avoid the double FlipSign() in ApplyFilter2() and here
+    p0s = FlipSign(tmp_p0);
+    q0s = FlipSign(tmp_q0);
+  }
+
+  // do_filter4 part (complex loopfilter on pixels without hev)
+  {
+    const int8x16_t delta0 = GetBaseDelta0(p0s, q0s);
+    // we use: (mask & hev_mask) ^ mask = mask & !hev_mask
+    const uint8x16_t complex_lf_mask = veorq_u8(simple_lf_mask, mask);
+    const int8x16_t complex_lf_delta =
+        vandq_s8(delta0, vreinterpretq_s8_u8(complex_lf_mask));
+    ApplyFilter4(p1s, p0s, q0s, q1s, complex_lf_delta, op1, op0, oq0, oq1);
+  }
+}
+
+//  6-points filter
+
+static void ApplyFilter6(
+    const int8x16_t p2, const int8x16_t p1, const int8x16_t p0,
+    const int8x16_t q0, const int8x16_t q1, const int8x16_t q2,
+    const int8x16_t delta,
+    uint8x16_t* const op2, uint8x16_t* const op1, uint8x16_t* const op0,
+    uint8x16_t* const oq0, uint8x16_t* const oq1, uint8x16_t* const oq2) {
+  const int16x8_t kCst63 = vdupq_n_s16(63);
+  const int8x8_t kCst27 = vdup_n_s8(27);
+  const int8x8_t kCst18 = vdup_n_s8(18);
+  const int8x8_t kCst9 = vdup_n_s8(9);
+  const int8x8_t delta_lo = vget_low_s8(delta);
+  const int8x8_t delta_hi = vget_high_s8(delta);
+  const int16x8_t s1_lo = vmlal_s8(kCst63, kCst27, delta_lo);  // 63 + 27 * a
+  const int16x8_t s1_hi = vmlal_s8(kCst63, kCst27, delta_hi);  // 63 + 27 * a
+  const int16x8_t s2_lo = vmlal_s8(kCst63, kCst18, delta_lo);  // 63 + 18 * a
+  const int16x8_t s2_hi = vmlal_s8(kCst63, kCst18, delta_hi);  // 63 + 18 * a
+  const int16x8_t s3_lo = vmlal_s8(kCst63, kCst9, delta_lo);   // 63 + 9 * a
+  const int16x8_t s3_hi = vmlal_s8(kCst63, kCst9, delta_hi);   // 63 + 9 * a
+  const int8x8_t a1_lo = vqshrn_n_s16(s1_lo, 7);
+  const int8x8_t a1_hi = vqshrn_n_s16(s1_hi, 7);
+  const int8x8_t a2_lo = vqshrn_n_s16(s2_lo, 7);
+  const int8x8_t a2_hi = vqshrn_n_s16(s2_hi, 7);
+  const int8x8_t a3_lo = vqshrn_n_s16(s3_lo, 7);
+  const int8x8_t a3_hi = vqshrn_n_s16(s3_hi, 7);
+  const int8x16_t a1 = vcombine_s8(a1_lo, a1_hi);
+  const int8x16_t a2 = vcombine_s8(a2_lo, a2_hi);
+  const int8x16_t a3 = vcombine_s8(a3_lo, a3_hi);
+
+  *op0 = FlipSignBack(vqaddq_s8(p0, a1));  // clip(p0 + a1)
+  *oq0 = FlipSignBack(vqsubq_s8(q0, a1));  // clip(q0 - q1)
+  *oq1 = FlipSignBack(vqsubq_s8(q1, a2));  // clip(q1 - a2)
+  *op1 = FlipSignBack(vqaddq_s8(p1, a2));  // clip(p1 + a2)
+  *oq2 = FlipSignBack(vqsubq_s8(q2, a3));  // clip(q2 - a3)
+  *op2 = FlipSignBack(vqaddq_s8(p2, a3));  // clip(p2 + a3)
+}
+
+static void DoFilter6(
+    const uint8x16_t p2, const uint8x16_t p1, const uint8x16_t p0,
+    const uint8x16_t q0, const uint8x16_t q1, const uint8x16_t q2,
+    const uint8x16_t mask, const uint8x16_t hev_mask,
+    uint8x16_t* const op2, uint8x16_t* const op1, uint8x16_t* const op0,
+    uint8x16_t* const oq0, uint8x16_t* const oq1, uint8x16_t* const oq2) {
+  // This is a fused version of DoFilter2() calling ApplyFilter2 directly
+  const int8x16_t p2s = FlipSign(p2);
+  const int8x16_t p1s = FlipSign(p1);
+  int8x16_t p0s = FlipSign(p0);
+  int8x16_t q0s = FlipSign(q0);
+  const int8x16_t q1s = FlipSign(q1);
+  const int8x16_t q2s = FlipSign(q2);
+  const uint8x16_t simple_lf_mask = vandq_u8(mask, hev_mask);
+  const int8x16_t delta0 = GetBaseDelta(p1s, p0s, q0s, q1s);
+
+  // do_filter2 part (simple loopfilter on pixels with hev)
+  {
+    const int8x16_t simple_lf_delta =
+        vandq_s8(delta0, vreinterpretq_s8_u8(simple_lf_mask));
+    uint8x16_t tmp_p0, tmp_q0;
+    ApplyFilter2(p0s, q0s, simple_lf_delta, &tmp_p0, &tmp_q0);
+    // TODO(skal): avoid the double FlipSign() in ApplyFilter2() and here
+    p0s = FlipSign(tmp_p0);
+    q0s = FlipSign(tmp_q0);
+  }
+
+  // do_filter6 part (complex loopfilter on pixels without hev)
+  {
+    // we use: (mask & hev_mask) ^ mask = mask & !hev_mask
+    const uint8x16_t complex_lf_mask = veorq_u8(simple_lf_mask, mask);
+    const int8x16_t complex_lf_delta =
+        vandq_s8(delta0, vreinterpretq_s8_u8(complex_lf_mask));
+    ApplyFilter6(p2s, p1s, p0s, q0s, q1s, q2s, complex_lf_delta,
+                 op2, op1, op0, oq0, oq1, oq2);
+  }
+}
+
+// on macroblock edges
+
+static void VFilter16(uint8_t* p, int stride,
+                      int thresh, int ithresh, int hev_thresh) {
+  uint8x16_t p3, p2, p1, p0, q0, q1, q2, q3;
+  Load16x8(p, stride, &p3, &p2, &p1, &p0, &q0, &q1, &q2, &q3);
+  {
+    const uint8x16_t mask = NeedsFilter2(p3, p2, p1, p0, q0, q1, q2, q3,
+                                         ithresh, thresh);
+    const uint8x16_t hev_mask = NeedsHev(p1, p0, q0, q1, hev_thresh);
+    uint8x16_t op2, op1, op0, oq0, oq1, oq2;
+    DoFilter6(p2, p1, p0, q0, q1, q2, mask, hev_mask,
+              &op2, &op1, &op0, &oq0, &oq1, &oq2);
+    Store16x2(op2, op1, p - 2 * stride, stride);
+    Store16x2(op0, oq0, p + 0 * stride, stride);
+    Store16x2(oq1, oq2, p + 2 * stride, stride);
+  }
+}
+
+static void HFilter16(uint8_t* p, int stride,
+                      int thresh, int ithresh, int hev_thresh) {
+  uint8x16_t p3, p2, p1, p0, q0, q1, q2, q3;
+  Load8x16(p, stride, &p3, &p2, &p1, &p0, &q0, &q1, &q2, &q3);
+  {
+    const uint8x16_t mask = NeedsFilter2(p3, p2, p1, p0, q0, q1, q2, q3,
+                                         ithresh, thresh);
+    const uint8x16_t hev_mask = NeedsHev(p1, p0, q0, q1, hev_thresh);
+    uint8x16_t op2, op1, op0, oq0, oq1, oq2;
+    DoFilter6(p2, p1, p0, q0, q1, q2, mask, hev_mask,
+              &op2, &op1, &op0, &oq0, &oq1, &oq2);
+    Store2x16(op2, op1, p - 2, stride);
+    Store2x16(op0, oq0, p + 0, stride);
+    Store2x16(oq1, oq2, p + 2, stride);
+  }
+}
+
+// on three inner edges
+static void VFilter16i(uint8_t* p, int stride,
+                       int thresh, int ithresh, int hev_thresh) {
+  uint32_t k;
+  uint8x16_t p3, p2, p1, p0;
+  Load16x4(p + 2  * stride, stride, &p3, &p2, &p1, &p0);
+  for (k = 3; k != 0; --k) {
+    uint8x16_t q0, q1, q2, q3;
+    p += 4 * stride;
+    Load16x4(p + 2  * stride, stride, &q0, &q1, &q2, &q3);
+    {
+      const uint8x16_t mask =
+          NeedsFilter2(p3, p2, p1, p0, q0, q1, q2, q3, ithresh, thresh);
+      const uint8x16_t hev_mask = NeedsHev(p1, p0, q0, q1, hev_thresh);
+      // p3 and p2 are not just temporary variables here: they will be
+      // re-used for next span. And q2/q3 will become p1/p0 accordingly.
+      DoFilter4(p1, p0, q0, q1, mask, hev_mask, &p1, &p0, &p3, &p2);
+      Store16x4(p1, p0, p3, p2, p, stride);
+      p1 = q2;
+      p0 = q3;
+    }
+  }
+}
+
+#if !defined(WORK_AROUND_GCC)
+static void HFilter16i(uint8_t* p, int stride,
+                       int thresh, int ithresh, int hev_thresh) {
+  uint32_t k;
+  uint8x16_t p3, p2, p1, p0;
+  Load4x16(p + 2, stride, &p3, &p2, &p1, &p0);
+  for (k = 3; k != 0; --k) {
+    uint8x16_t q0, q1, q2, q3;
+    p += 4;
+    Load4x16(p + 2, stride, &q0, &q1, &q2, &q3);
+    {
+      const uint8x16_t mask =
+          NeedsFilter2(p3, p2, p1, p0, q0, q1, q2, q3, ithresh, thresh);
+      const uint8x16_t hev_mask = NeedsHev(p1, p0, q0, q1, hev_thresh);
+      DoFilter4(p1, p0, q0, q1, mask, hev_mask, &p1, &p0, &p3, &p2);
+      Store4x16(p1, p0, p3, p2, p, stride);
+      p1 = q2;
+      p0 = q3;
+    }
+  }
+}
+#endif  // !WORK_AROUND_GCC
+
+// 8-pixels wide variant, for chroma filtering
+static void VFilter8(uint8_t* u, uint8_t* v, int stride,
+                     int thresh, int ithresh, int hev_thresh) {
+  uint8x16_t p3, p2, p1, p0, q0, q1, q2, q3;
+  Load8x8x2(u, v, stride, &p3, &p2, &p1, &p0, &q0, &q1, &q2, &q3);
+  {
+    const uint8x16_t mask = NeedsFilter2(p3, p2, p1, p0, q0, q1, q2, q3,
+                                         ithresh, thresh);
+    const uint8x16_t hev_mask = NeedsHev(p1, p0, q0, q1, hev_thresh);
+    uint8x16_t op2, op1, op0, oq0, oq1, oq2;
+    DoFilter6(p2, p1, p0, q0, q1, q2, mask, hev_mask,
+              &op2, &op1, &op0, &oq0, &oq1, &oq2);
+    Store8x2x2(op2, op1, u - 2 * stride, v - 2 * stride, stride);
+    Store8x2x2(op0, oq0, u + 0 * stride, v + 0 * stride, stride);
+    Store8x2x2(oq1, oq2, u + 2 * stride, v + 2 * stride, stride);
+  }
+}
+static void VFilter8i(uint8_t* u, uint8_t* v, int stride,
+                      int thresh, int ithresh, int hev_thresh) {
+  uint8x16_t p3, p2, p1, p0, q0, q1, q2, q3;
+  u += 4 * stride;
+  v += 4 * stride;
+  Load8x8x2(u, v, stride, &p3, &p2, &p1, &p0, &q0, &q1, &q2, &q3);
+  {
+    const uint8x16_t mask = NeedsFilter2(p3, p2, p1, p0, q0, q1, q2, q3,
+                                         ithresh, thresh);
+    const uint8x16_t hev_mask = NeedsHev(p1, p0, q0, q1, hev_thresh);
+    uint8x16_t op1, op0, oq0, oq1;
+    DoFilter4(p1, p0, q0, q1, mask, hev_mask, &op1, &op0, &oq0, &oq1);
+    Store8x4x2(op1, op0, oq0, oq1, u, v, stride);
+  }
+}
+
+#if !defined(WORK_AROUND_GCC)
+static void HFilter8(uint8_t* u, uint8_t* v, int stride,
+                     int thresh, int ithresh, int hev_thresh) {
+  uint8x16_t p3, p2, p1, p0, q0, q1, q2, q3;
+  Load8x8x2T(u, v, stride, &p3, &p2, &p1, &p0, &q0, &q1, &q2, &q3);
+  {
+    const uint8x16_t mask = NeedsFilter2(p3, p2, p1, p0, q0, q1, q2, q3,
+                                         ithresh, thresh);
+    const uint8x16_t hev_mask = NeedsHev(p1, p0, q0, q1, hev_thresh);
+    uint8x16_t op2, op1, op0, oq0, oq1, oq2;
+    DoFilter6(p2, p1, p0, q0, q1, q2, mask, hev_mask,
+              &op2, &op1, &op0, &oq0, &oq1, &oq2);
+    Store6x8x2(op2, op1, op0, oq0, oq1, oq2, u, v, stride);
+  }
+}
+
+static void HFilter8i(uint8_t* u, uint8_t* v, int stride,
+                      int thresh, int ithresh, int hev_thresh) {
+  uint8x16_t p3, p2, p1, p0, q0, q1, q2, q3;
+  u += 4;
+  v += 4;
+  Load8x8x2T(u, v, stride, &p3, &p2, &p1, &p0, &q0, &q1, &q2, &q3);
+  {
+    const uint8x16_t mask = NeedsFilter2(p3, p2, p1, p0, q0, q1, q2, q3,
+                                         ithresh, thresh);
+    const uint8x16_t hev_mask = NeedsHev(p1, p0, q0, q1, hev_thresh);
+    uint8x16_t op1, op0, oq0, oq1;
+    DoFilter4(p1, p0, q0, q1, mask, hev_mask, &op1, &op0, &oq0, &oq1);
+    Store4x8x2(op1, op0, oq0, oq1, u, v, stride);
+  }
+}
+#endif  // !WORK_AROUND_GCC
+
+//-----------------------------------------------------------------------------
+// Inverse transforms (Paragraph 14.4)
+
+// Technically these are unsigned but vqdmulh is only available in signed.
+// vqdmulh returns high half (effectively >> 16) but also doubles the value,
+// changing the >> 16 to >> 15 and requiring an additional >> 1.
+// We use this to our advantage with kC2. The canonical value is 35468.
+// However, the high bit is set so treating it as signed will give incorrect
+// results. We avoid this by down shifting by 1 here to clear the highest bit.
+// Combined with the doubling effect of vqdmulh we get >> 16.
+// This can not be applied to kC1 because the lowest bit is set. Down shifting
+// the constant would reduce precision.
+
+// libwebp uses a trick to avoid some extra addition that libvpx does.
+// Instead of:
+// temp2 = ip[12] + ((ip[12] * cospi8sqrt2minus1) >> 16);
+// libwebp adds 1 << 16 to cospi8sqrt2minus1 (kC1). However, this causes the
+// same issue with kC1 and vqdmulh that we work around by down shifting kC2
+
+static const int16_t kC1 = 20091;
+static const int16_t kC2 = 17734;  // half of kC2, actually. See comment above.
+
+#if defined(WEBP_USE_INTRINSICS)
+static WEBP_INLINE void Transpose8x2(const int16x8_t in0, const int16x8_t in1,
+                                     int16x8x2_t* const out) {
+  // a0 a1 a2 a3 | b0 b1 b2 b3   => a0 b0 c0 d0 | a1 b1 c1 d1
+  // c0 c1 c2 c3 | d0 d1 d2 d3      a2 b2 c2 d2 | a3 b3 c3 d3
+  const int16x8x2_t tmp0 = vzipq_s16(in0, in1);   // a0 c0 a1 c1 a2 c2 ...
+                                                  // b0 d0 b1 d1 b2 d2 ...
+  *out = vzipq_s16(tmp0.val[0], tmp0.val[1]);
+}
+
+static WEBP_INLINE void TransformPass(int16x8x2_t* const rows) {
+  // {rows} = in0 | in4
+  //          in8 | in12
+  // B1 = in4 | in12
+  const int16x8_t B1 =
+      vcombine_s16(vget_high_s16(rows->val[0]), vget_high_s16(rows->val[1]));
+  // C0 = kC1 * in4 | kC1 * in12
+  // C1 = kC2 * in4 | kC2 * in12
+  const int16x8_t C0 = vsraq_n_s16(B1, vqdmulhq_n_s16(B1, kC1), 1);
+  const int16x8_t C1 = vqdmulhq_n_s16(B1, kC2);
+  const int16x4_t a = vqadd_s16(vget_low_s16(rows->val[0]),
+                                vget_low_s16(rows->val[1]));   // in0 + in8
+  const int16x4_t b = vqsub_s16(vget_low_s16(rows->val[0]),
+                                vget_low_s16(rows->val[1]));   // in0 - in8
+  // c = kC2 * in4 - kC1 * in12
+  // d = kC1 * in4 + kC2 * in12
+  const int16x4_t c = vqsub_s16(vget_low_s16(C1), vget_high_s16(C0));
+  const int16x4_t d = vqadd_s16(vget_low_s16(C0), vget_high_s16(C1));
+  const int16x8_t D0 = vcombine_s16(a, b);      // D0 = a | b
+  const int16x8_t D1 = vcombine_s16(d, c);      // D1 = d | c
+  const int16x8_t E0 = vqaddq_s16(D0, D1);      // a+d | b+c
+  const int16x8_t E_tmp = vqsubq_s16(D0, D1);   // a-d | b-c
+  const int16x8_t E1 = vcombine_s16(vget_high_s16(E_tmp), vget_low_s16(E_tmp));
+  Transpose8x2(E0, E1, rows);
+}
+
+static void TransformOne(const int16_t* in, uint8_t* dst) {
+  int16x8x2_t rows;
+  INIT_VECTOR2(rows, vld1q_s16(in + 0), vld1q_s16(in + 8));
+  TransformPass(&rows);
+  TransformPass(&rows);
+  Add4x4(rows.val[0], rows.val[1], dst);
+}
+
+#else
+
+static void TransformOne(const int16_t* in, uint8_t* dst) {
+  const int kBPS = BPS;
+  // kC1, kC2. Padded because vld1.16 loads 8 bytes
+  const int16_t constants[4] = { kC1, kC2, 0, 0 };
+  /* Adapted from libvpx: vp8/common/arm/neon/shortidct4x4llm_neon.asm */
+  __asm__ volatile (
+    "vld1.16         {q1, q2}, [%[in]]           \n"
+    "vld1.16         {d0}, [%[constants]]        \n"
+
+    /* d2: in[0]
+     * d3: in[8]
+     * d4: in[4]
+     * d5: in[12]
+     */
+    "vswp            d3, d4                      \n"
+
+    /* q8 = {in[4], in[12]} * kC1 * 2 >> 16
+     * q9 = {in[4], in[12]} * kC2 >> 16
+     */
+    "vqdmulh.s16     q8, q2, d0[0]               \n"
+    "vqdmulh.s16     q9, q2, d0[1]               \n"
+
+    /* d22 = a = in[0] + in[8]
+     * d23 = b = in[0] - in[8]
+     */
+    "vqadd.s16       d22, d2, d3                 \n"
+    "vqsub.s16       d23, d2, d3                 \n"
+
+    /* The multiplication should be x * kC1 >> 16
+     * However, with vqdmulh we get x * kC1 * 2 >> 16
+     * (multiply, double, return high half)
+     * We avoided this in kC2 by pre-shifting the constant.
+     * q8 = in[4]/[12] * kC1 >> 16
+     */
+    "vshr.s16        q8, q8, #1                  \n"
+
+    /* Add {in[4], in[12]} back after the multiplication. This is handled by
+     * adding 1 << 16 to kC1 in the libwebp C code.
+     */
+    "vqadd.s16       q8, q2, q8                  \n"
+
+    /* d20 = c = in[4]*kC2 - in[12]*kC1
+     * d21 = d = in[4]*kC1 + in[12]*kC2
+     */
+    "vqsub.s16       d20, d18, d17               \n"
+    "vqadd.s16       d21, d19, d16               \n"
+
+    /* d2 = tmp[0] = a + d
+     * d3 = tmp[1] = b + c
+     * d4 = tmp[2] = b - c
+     * d5 = tmp[3] = a - d
+     */
+    "vqadd.s16       d2, d22, d21                \n"
+    "vqadd.s16       d3, d23, d20                \n"
+    "vqsub.s16       d4, d23, d20                \n"
+    "vqsub.s16       d5, d22, d21                \n"
+
+    "vzip.16         q1, q2                      \n"
+    "vzip.16         q1, q2                      \n"
+
+    "vswp            d3, d4                      \n"
+
+    /* q8 = {tmp[4], tmp[12]} * kC1 * 2 >> 16
+     * q9 = {tmp[4], tmp[12]} * kC2 >> 16
+     */
+    "vqdmulh.s16     q8, q2, d0[0]               \n"
+    "vqdmulh.s16     q9, q2, d0[1]               \n"
+
+    /* d22 = a = tmp[0] + tmp[8]
+     * d23 = b = tmp[0] - tmp[8]
+     */
+    "vqadd.s16       d22, d2, d3                 \n"
+    "vqsub.s16       d23, d2, d3                 \n"
+
+    /* See long winded explanations prior */
+    "vshr.s16        q8, q8, #1                  \n"
+    "vqadd.s16       q8, q2, q8                  \n"
+
+    /* d20 = c = in[4]*kC2 - in[12]*kC1
+     * d21 = d = in[4]*kC1 + in[12]*kC2
+     */
+    "vqsub.s16       d20, d18, d17               \n"
+    "vqadd.s16       d21, d19, d16               \n"
+
+    /* d2 = tmp[0] = a + d
+     * d3 = tmp[1] = b + c
+     * d4 = tmp[2] = b - c
+     * d5 = tmp[3] = a - d
+     */
+    "vqadd.s16       d2, d22, d21                \n"
+    "vqadd.s16       d3, d23, d20                \n"
+    "vqsub.s16       d4, d23, d20                \n"
+    "vqsub.s16       d5, d22, d21                \n"
+
+    "vld1.32         d6[0], [%[dst]], %[kBPS]    \n"
+    "vld1.32         d6[1], [%[dst]], %[kBPS]    \n"
+    "vld1.32         d7[0], [%[dst]], %[kBPS]    \n"
+    "vld1.32         d7[1], [%[dst]], %[kBPS]    \n"
+
+    "sub         %[dst], %[dst], %[kBPS], lsl #2 \n"
+
+    /* (val) + 4 >> 3 */
+    "vrshr.s16       d2, d2, #3                  \n"
+    "vrshr.s16       d3, d3, #3                  \n"
+    "vrshr.s16       d4, d4, #3                  \n"
+    "vrshr.s16       d5, d5, #3                  \n"
+
+    "vzip.16         q1, q2                      \n"
+    "vzip.16         q1, q2                      \n"
+
+    /* Must accumulate before saturating */
+    "vmovl.u8        q8, d6                      \n"
+    "vmovl.u8        q9, d7                      \n"
+
+    "vqadd.s16       q1, q1, q8                  \n"
+    "vqadd.s16       q2, q2, q9                  \n"
+
+    "vqmovun.s16     d0, q1                      \n"
+    "vqmovun.s16     d1, q2                      \n"
+
+    "vst1.32         d0[0], [%[dst]], %[kBPS]    \n"
+    "vst1.32         d0[1], [%[dst]], %[kBPS]    \n"
+    "vst1.32         d1[0], [%[dst]], %[kBPS]    \n"
+    "vst1.32         d1[1], [%[dst]]             \n"
+
+    : [in] "+r"(in), [dst] "+r"(dst)  /* modified registers */
+    : [kBPS] "r"(kBPS), [constants] "r"(constants)  /* constants */
+    : "memory", "q0", "q1", "q2", "q8", "q9", "q10", "q11"  /* clobbered */
+  );
+}
+
+#endif    // WEBP_USE_INTRINSICS
+
+static void TransformTwo(const int16_t* in, uint8_t* dst, int do_two) {
+  TransformOne(in, dst);
+  if (do_two) {
+    TransformOne(in + 16, dst + 4);
+  }
+}
+
+static void TransformDC(const int16_t* in, uint8_t* dst) {
+  const int16x8_t DC = vdupq_n_s16(in[0]);
+  Add4x4(DC, DC, dst);
+}
+
+//------------------------------------------------------------------------------
+
+#define STORE_WHT(dst, col, rows) do {                  \
+  *dst = vgetq_lane_s32(rows.val[0], col); (dst) += 16; \
+  *dst = vgetq_lane_s32(rows.val[1], col); (dst) += 16; \
+  *dst = vgetq_lane_s32(rows.val[2], col); (dst) += 16; \
+  *dst = vgetq_lane_s32(rows.val[3], col); (dst) += 16; \
+} while (0)
+
+static void TransformWHT(const int16_t* in, int16_t* out) {
+  int32x4x4_t tmp;
+
+  {
+    // Load the source.
+    const int16x4_t in00_03 = vld1_s16(in + 0);
+    const int16x4_t in04_07 = vld1_s16(in + 4);
+    const int16x4_t in08_11 = vld1_s16(in + 8);
+    const int16x4_t in12_15 = vld1_s16(in + 12);
+    const int32x4_t a0 = vaddl_s16(in00_03, in12_15);  // in[0..3] + in[12..15]
+    const int32x4_t a1 = vaddl_s16(in04_07, in08_11);  // in[4..7] + in[8..11]
+    const int32x4_t a2 = vsubl_s16(in04_07, in08_11);  // in[4..7] - in[8..11]
+    const int32x4_t a3 = vsubl_s16(in00_03, in12_15);  // in[0..3] - in[12..15]
+    tmp.val[0] = vaddq_s32(a0, a1);
+    tmp.val[1] = vaddq_s32(a3, a2);
+    tmp.val[2] = vsubq_s32(a0, a1);
+    tmp.val[3] = vsubq_s32(a3, a2);
+    // Arrange the temporary results column-wise.
+    tmp = Transpose4x4(tmp);
+  }
+
+  {
+    const int32x4_t kCst3 = vdupq_n_s32(3);
+    const int32x4_t dc = vaddq_s32(tmp.val[0], kCst3);  // add rounder
+    const int32x4_t a0 = vaddq_s32(dc, tmp.val[3]);
+    const int32x4_t a1 = vaddq_s32(tmp.val[1], tmp.val[2]);
+    const int32x4_t a2 = vsubq_s32(tmp.val[1], tmp.val[2]);
+    const int32x4_t a3 = vsubq_s32(dc, tmp.val[3]);
+
+    tmp.val[0] = vaddq_s32(a0, a1);
+    tmp.val[1] = vaddq_s32(a3, a2);
+    tmp.val[2] = vsubq_s32(a0, a1);
+    tmp.val[3] = vsubq_s32(a3, a2);
+
+    // right shift the results by 3.
+    tmp.val[0] = vshrq_n_s32(tmp.val[0], 3);
+    tmp.val[1] = vshrq_n_s32(tmp.val[1], 3);
+    tmp.val[2] = vshrq_n_s32(tmp.val[2], 3);
+    tmp.val[3] = vshrq_n_s32(tmp.val[3], 3);
+
+    STORE_WHT(out, 0, tmp);
+    STORE_WHT(out, 1, tmp);
+    STORE_WHT(out, 2, tmp);
+    STORE_WHT(out, 3, tmp);
+  }
+}
+
+#undef STORE_WHT
+
+//------------------------------------------------------------------------------
+
+#define MUL(a, b) (((a) * (b)) >> 16)
+static void TransformAC3(const int16_t* in, uint8_t* dst) {
+  static const int kC1_full = 20091 + (1 << 16);
+  static const int kC2_full = 35468;
+  const int16x4_t A = vdup_n_s16(in[0]);
+  const int16x4_t c4 = vdup_n_s16(MUL(in[4], kC2_full));
+  const int16x4_t d4 = vdup_n_s16(MUL(in[4], kC1_full));
+  const int c1 = MUL(in[1], kC2_full);
+  const int d1 = MUL(in[1], kC1_full);
+  const uint64_t cd = (uint64_t)( d1 & 0xffff) <<  0 |
+                      (uint64_t)( c1 & 0xffff) << 16 |
+                      (uint64_t)(-c1 & 0xffff) << 32 |
+                      (uint64_t)(-d1 & 0xffff) << 48;
+  const int16x4_t CD = vcreate_s16(cd);
+  const int16x4_t B = vqadd_s16(A, CD);
+  const int16x8_t m0_m1 = vcombine_s16(vqadd_s16(B, d4), vqadd_s16(B, c4));
+  const int16x8_t m2_m3 = vcombine_s16(vqsub_s16(B, c4), vqsub_s16(B, d4));
+  Add4x4(m0_m1, m2_m3, dst);
+}
+#undef MUL
+
+//------------------------------------------------------------------------------
+// 4x4
+
+static void DC4(uint8_t* dst) {    // DC
+  const uint8x8_t A = vld1_u8(dst - BPS);  // top row
+  const uint16x4_t p0 = vpaddl_u8(A);  // cascading summation of the top
+  const uint16x4_t p1 = vpadd_u16(p0, p0);
+  const uint16x8_t L0 = vmovl_u8(vld1_u8(dst + 0 * BPS - 1));
+  const uint16x8_t L1 = vmovl_u8(vld1_u8(dst + 1 * BPS - 1));
+  const uint16x8_t L2 = vmovl_u8(vld1_u8(dst + 2 * BPS - 1));
+  const uint16x8_t L3 = vmovl_u8(vld1_u8(dst + 3 * BPS - 1));
+  const uint16x8_t s0 = vaddq_u16(L0, L1);
+  const uint16x8_t s1 = vaddq_u16(L2, L3);
+  const uint16x8_t s01 = vaddq_u16(s0, s1);
+  const uint16x8_t sum = vaddq_u16(s01, vcombine_u16(p1, p1));
+  const uint8x8_t dc0 = vrshrn_n_u16(sum, 3);  // (sum + 4) >> 3
+  const uint8x8_t dc = vdup_lane_u8(dc0, 0);
+  int i;
+  for (i = 0; i < 4; ++i) {
+    vst1_lane_u32((uint32_t*)(dst + i * BPS), vreinterpret_u32_u8(dc), 0);
+  }
+}
+
+// TrueMotion (4x4 + 8x8)
+static WEBP_INLINE void TrueMotion(uint8_t* dst, int size) {
+  const uint8x8_t TL = vdup_n_u8(dst[-BPS - 1]);  // top-left pixel 'A[-1]'
+  const uint8x8_t T = vld1_u8(dst - BPS);  // top row 'A[0..3]'
+  const int16x8_t d = vreinterpretq_s16_u16(vsubl_u8(T, TL));  // A[c] - A[-1]
+  int y;
+  for (y = 0; y < size; y += 4) {
+    // left edge
+    const int16x8_t l0 = ConvertU8ToS16(vld1_u8(dst + 0 * BPS - 1));
+    const int16x8_t l1 = ConvertU8ToS16(vld1_u8(dst + 1 * BPS - 1));
+    const int16x8_t l2 = ConvertU8ToS16(vld1_u8(dst + 2 * BPS - 1));
+    const int16x8_t l3 = ConvertU8ToS16(vld1_u8(dst + 3 * BPS - 1));
+    const int16x8_t L0 = vdupq_lane_s16(vget_low_s16(l0), 0);
+    const int16x8_t L1 = vdupq_lane_s16(vget_low_s16(l1), 0);
+    const int16x8_t L2 = vdupq_lane_s16(vget_low_s16(l2), 0);
+    const int16x8_t L3 = vdupq_lane_s16(vget_low_s16(l3), 0);
+    const int16x8_t r0 = vaddq_s16(L0, d);  // L[r] + A[c] - A[-1]
+    const int16x8_t r1 = vaddq_s16(L1, d);
+    const int16x8_t r2 = vaddq_s16(L2, d);
+    const int16x8_t r3 = vaddq_s16(L3, d);
+    // Saturate and store the result.
+    const uint32x2_t r0_u32 = vreinterpret_u32_u8(vqmovun_s16(r0));
+    const uint32x2_t r1_u32 = vreinterpret_u32_u8(vqmovun_s16(r1));
+    const uint32x2_t r2_u32 = vreinterpret_u32_u8(vqmovun_s16(r2));
+    const uint32x2_t r3_u32 = vreinterpret_u32_u8(vqmovun_s16(r3));
+    if (size == 4) {
+      vst1_lane_u32((uint32_t*)(dst + 0 * BPS), r0_u32, 0);
+      vst1_lane_u32((uint32_t*)(dst + 1 * BPS), r1_u32, 0);
+      vst1_lane_u32((uint32_t*)(dst + 2 * BPS), r2_u32, 0);
+      vst1_lane_u32((uint32_t*)(dst + 3 * BPS), r3_u32, 0);
+    } else {
+      vst1_u32((uint32_t*)(dst + 0 * BPS), r0_u32);
+      vst1_u32((uint32_t*)(dst + 1 * BPS), r1_u32);
+      vst1_u32((uint32_t*)(dst + 2 * BPS), r2_u32);
+      vst1_u32((uint32_t*)(dst + 3 * BPS), r3_u32);
+    }
+    dst += 4 * BPS;
+  }
+}
+
+static void TM4(uint8_t* dst) { TrueMotion(dst, 4); }
+
+static void VE4(uint8_t* dst) {    // vertical
+  // NB: avoid vld1_u64 here as an alignment hint may be added -> SIGBUS.
+  const uint64x1_t A0 = vreinterpret_u64_u8(vld1_u8(dst - BPS - 1));  // top row
+  const uint64x1_t A1 = vshr_n_u64(A0, 8);
+  const uint64x1_t A2 = vshr_n_u64(A0, 16);
+  const uint8x8_t ABCDEFGH = vreinterpret_u8_u64(A0);
+  const uint8x8_t BCDEFGH0 = vreinterpret_u8_u64(A1);
+  const uint8x8_t CDEFGH00 = vreinterpret_u8_u64(A2);
+  const uint8x8_t b = vhadd_u8(ABCDEFGH, CDEFGH00);
+  const uint8x8_t avg = vrhadd_u8(b, BCDEFGH0);
+  int i;
+  for (i = 0; i < 4; ++i) {
+    vst1_lane_u32((uint32_t*)(dst + i * BPS), vreinterpret_u32_u8(avg), 0);
+  }
+}
+
+static void RD4(uint8_t* dst) {   // Down-right
+  const uint8x8_t XABCD_u8 = vld1_u8(dst - BPS - 1);
+  const uint64x1_t XABCD = vreinterpret_u64_u8(XABCD_u8);
+  const uint64x1_t ____XABC = vshl_n_u64(XABCD, 32);
+  const uint32_t I = dst[-1 + 0 * BPS];
+  const uint32_t J = dst[-1 + 1 * BPS];
+  const uint32_t K = dst[-1 + 2 * BPS];
+  const uint32_t L = dst[-1 + 3 * BPS];
+  const uint64x1_t LKJI____ = vcreate_u64(L | (K << 8) | (J << 16) | (I << 24));
+  const uint64x1_t LKJIXABC = vorr_u64(LKJI____, ____XABC);
+  const uint8x8_t KJIXABC_ = vreinterpret_u8_u64(vshr_n_u64(LKJIXABC, 8));
+  const uint8x8_t JIXABC__ = vreinterpret_u8_u64(vshr_n_u64(LKJIXABC, 16));
+  const uint8_t D = vget_lane_u8(XABCD_u8, 4);
+  const uint8x8_t JIXABCD_ = vset_lane_u8(D, JIXABC__, 6);
+  const uint8x8_t LKJIXABC_u8 = vreinterpret_u8_u64(LKJIXABC);
+  const uint8x8_t avg1 = vhadd_u8(JIXABCD_, LKJIXABC_u8);
+  const uint8x8_t avg2 = vrhadd_u8(avg1, KJIXABC_);
+  const uint64x1_t avg2_u64 = vreinterpret_u64_u8(avg2);
+  const uint32x2_t r3 = vreinterpret_u32_u8(avg2);
+  const uint32x2_t r2 = vreinterpret_u32_u64(vshr_n_u64(avg2_u64, 8));
+  const uint32x2_t r1 = vreinterpret_u32_u64(vshr_n_u64(avg2_u64, 16));
+  const uint32x2_t r0 = vreinterpret_u32_u64(vshr_n_u64(avg2_u64, 24));
+  vst1_lane_u32((uint32_t*)(dst + 0 * BPS), r0, 0);
+  vst1_lane_u32((uint32_t*)(dst + 1 * BPS), r1, 0);
+  vst1_lane_u32((uint32_t*)(dst + 2 * BPS), r2, 0);
+  vst1_lane_u32((uint32_t*)(dst + 3 * BPS), r3, 0);
+}
+
+static void LD4(uint8_t* dst) {    // Down-left
+  // Note using the same shift trick as VE4() is slower here.
+  const uint8x8_t ABCDEFGH = vld1_u8(dst - BPS + 0);
+  const uint8x8_t BCDEFGH0 = vld1_u8(dst - BPS + 1);
+  const uint8x8_t CDEFGH00 = vld1_u8(dst - BPS + 2);
+  const uint8x8_t CDEFGHH0 = vset_lane_u8(dst[-BPS + 7], CDEFGH00, 6);
+  const uint8x8_t avg1 = vhadd_u8(ABCDEFGH, CDEFGHH0);
+  const uint8x8_t avg2 = vrhadd_u8(avg1, BCDEFGH0);
+  const uint64x1_t avg2_u64 = vreinterpret_u64_u8(avg2);
+  const uint32x2_t r0 = vreinterpret_u32_u8(avg2);
+  const uint32x2_t r1 = vreinterpret_u32_u64(vshr_n_u64(avg2_u64, 8));
+  const uint32x2_t r2 = vreinterpret_u32_u64(vshr_n_u64(avg2_u64, 16));
+  const uint32x2_t r3 = vreinterpret_u32_u64(vshr_n_u64(avg2_u64, 24));
+  vst1_lane_u32((uint32_t*)(dst + 0 * BPS), r0, 0);
+  vst1_lane_u32((uint32_t*)(dst + 1 * BPS), r1, 0);
+  vst1_lane_u32((uint32_t*)(dst + 2 * BPS), r2, 0);
+  vst1_lane_u32((uint32_t*)(dst + 3 * BPS), r3, 0);
+}
+
+//------------------------------------------------------------------------------
+// Chroma
+
+static WEBP_INLINE void DC8(uint8_t* dst, int do_top, int do_left) {
+  uint16x8_t sum_top;
+  uint16x8_t sum_left;
+  uint8x8_t dc0;
+
+  if (do_top) {
+    const uint8x8_t A = vld1_u8(dst - BPS);  // top row
+    const uint16x4_t p0 = vpaddl_u8(A);  // cascading summation of the top
+    const uint16x4_t p1 = vpadd_u16(p0, p0);
+    const uint16x4_t p2 = vpadd_u16(p1, p1);
+    sum_top = vcombine_u16(p2, p2);
+  }
+
+  if (do_left) {
+    const uint16x8_t L0 = vmovl_u8(vld1_u8(dst + 0 * BPS - 1));
+    const uint16x8_t L1 = vmovl_u8(vld1_u8(dst + 1 * BPS - 1));
+    const uint16x8_t L2 = vmovl_u8(vld1_u8(dst + 2 * BPS - 1));
+    const uint16x8_t L3 = vmovl_u8(vld1_u8(dst + 3 * BPS - 1));
+    const uint16x8_t L4 = vmovl_u8(vld1_u8(dst + 4 * BPS - 1));
+    const uint16x8_t L5 = vmovl_u8(vld1_u8(dst + 5 * BPS - 1));
+    const uint16x8_t L6 = vmovl_u8(vld1_u8(dst + 6 * BPS - 1));
+    const uint16x8_t L7 = vmovl_u8(vld1_u8(dst + 7 * BPS - 1));
+    const uint16x8_t s0 = vaddq_u16(L0, L1);
+    const uint16x8_t s1 = vaddq_u16(L2, L3);
+    const uint16x8_t s2 = vaddq_u16(L4, L5);
+    const uint16x8_t s3 = vaddq_u16(L6, L7);
+    const uint16x8_t s01 = vaddq_u16(s0, s1);
+    const uint16x8_t s23 = vaddq_u16(s2, s3);
+    sum_left = vaddq_u16(s01, s23);
+  }
+
+  if (do_top && do_left) {
+    const uint16x8_t sum = vaddq_u16(sum_left, sum_top);
+    dc0 = vrshrn_n_u16(sum, 4);
+  } else if (do_top) {
+    dc0 = vrshrn_n_u16(sum_top, 3);
+  } else {
+    dc0 = vrshrn_n_u16(sum_left, 3);
+  }
+
+  {
+    const uint8x8_t dc = vdup_lane_u8(dc0, 0);
+    int i;
+    for (i = 0; i < 8; ++i) {
+      vst1_u32((uint32_t*)(dst + i * BPS), vreinterpret_u32_u8(dc));
+    }
+  }
+}
+
+static void DC8uv(uint8_t* dst) { DC8(dst, 1, 1); }
+static void DC8uvNoTop(uint8_t* dst) { DC8(dst, 0, 1); }
+static void DC8uvNoLeft(uint8_t* dst) { DC8(dst, 1, 0); }
+
+static void TM8uv(uint8_t* dst) { TrueMotion(dst, 8); }
+
+#endif   // WEBP_USE_NEON
+
+//------------------------------------------------------------------------------
+// Entry point
+
+extern void VP8DspInitNEON(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8DspInitNEON(void) {
+#if defined(WEBP_USE_NEON)
+  VP8Transform = TransformTwo;
+  VP8TransformAC3 = TransformAC3;
+  VP8TransformDC = TransformDC;
+  VP8TransformWHT = TransformWHT;
+
+  VP8VFilter16 = VFilter16;
+  VP8VFilter16i = VFilter16i;
+  VP8HFilter16 = HFilter16;
+#if !defined(WORK_AROUND_GCC)
+  VP8HFilter16i = HFilter16i;
+#endif
+  VP8VFilter8 = VFilter8;
+  VP8VFilter8i = VFilter8i;
+#if !defined(WORK_AROUND_GCC)
+  VP8HFilter8 = HFilter8;
+  VP8HFilter8i = HFilter8i;
+#endif
+  VP8SimpleVFilter16 = SimpleVFilter16;
+  VP8SimpleHFilter16 = SimpleHFilter16;
+  VP8SimpleVFilter16i = SimpleVFilter16i;
+  VP8SimpleHFilter16i = SimpleHFilter16i;
+
+  VP8PredLuma4[0] = DC4;
+  VP8PredLuma4[1] = TM4;
+  VP8PredLuma4[2] = VE4;
+  VP8PredLuma4[4] = RD4;
+  VP8PredLuma4[6] = LD4;
+
+  VP8PredChroma8[0] = DC8uv;
+  VP8PredChroma8[1] = TM8uv;
+  VP8PredChroma8[4] = DC8uvNoTop;
+  VP8PredChroma8[5] = DC8uvNoLeft;
+#endif   // WEBP_USE_NEON
+}
diff --git a/Source/LibWebP/src/dsp/dsp.dec_sse2.c b/Source/LibWebP/src/dsp/dsp.dec_sse2.c
new file mode 100644
index 0000000..fca36c9
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.dec_sse2.c
@@ -0,0 +1,1284 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// SSE2 version of some decoding functions (idct, loop filtering).
+//
+// Author: somnath at google.com (Somnath Banerjee)
+//         cduvivier at google.com (Christian Duvivier)
+
+#include "./dsp.h"
+
+#if defined(WEBP_USE_SSE2)
+
+// The 3-coeff sparse transform in SSE2 is not really faster than the plain-C
+// one it seems => disable it by default. Uncomment the following to enable:
+// #define USE_TRANSFORM_AC3
+
+#include <emmintrin.h>
+#include "../dec/vp8i.h"
+
+//------------------------------------------------------------------------------
+// Transforms (Paragraph 14.4)
+
+static void Transform(const int16_t* in, uint8_t* dst, int do_two) {
+  // This implementation makes use of 16-bit fixed point versions of two
+  // multiply constants:
+  //    K1 = sqrt(2) * cos (pi/8) ~= 85627 / 2^16
+  //    K2 = sqrt(2) * sin (pi/8) ~= 35468 / 2^16
+  //
+  // To be able to use signed 16-bit integers, we use the following trick to
+  // have constants within range:
+  // - Associated constants are obtained by subtracting the 16-bit fixed point
+  //   version of one:
+  //      k = K - (1 << 16)  =>  K = k + (1 << 16)
+  //      K1 = 85267  =>  k1 =  20091
+  //      K2 = 35468  =>  k2 = -30068
+  // - The multiplication of a variable by a constant become the sum of the
+  //   variable and the multiplication of that variable by the associated
+  //   constant:
+  //      (x * K) >> 16 = (x * (k + (1 << 16))) >> 16 = ((x * k ) >> 16) + x
+  const __m128i k1 = _mm_set1_epi16(20091);
+  const __m128i k2 = _mm_set1_epi16(-30068);
+  __m128i T0, T1, T2, T3;
+
+  // Load and concatenate the transform coefficients (we'll do two transforms
+  // in parallel). In the case of only one transform, the second half of the
+  // vectors will just contain random value we'll never use nor store.
+  __m128i in0, in1, in2, in3;
+  {
+    in0 = _mm_loadl_epi64((const __m128i*)&in[0]);
+    in1 = _mm_loadl_epi64((const __m128i*)&in[4]);
+    in2 = _mm_loadl_epi64((const __m128i*)&in[8]);
+    in3 = _mm_loadl_epi64((const __m128i*)&in[12]);
+    // a00 a10 a20 a30   x x x x
+    // a01 a11 a21 a31   x x x x
+    // a02 a12 a22 a32   x x x x
+    // a03 a13 a23 a33   x x x x
+    if (do_two) {
+      const __m128i inB0 = _mm_loadl_epi64((const __m128i*)&in[16]);
+      const __m128i inB1 = _mm_loadl_epi64((const __m128i*)&in[20]);
+      const __m128i inB2 = _mm_loadl_epi64((const __m128i*)&in[24]);
+      const __m128i inB3 = _mm_loadl_epi64((const __m128i*)&in[28]);
+      in0 = _mm_unpacklo_epi64(in0, inB0);
+      in1 = _mm_unpacklo_epi64(in1, inB1);
+      in2 = _mm_unpacklo_epi64(in2, inB2);
+      in3 = _mm_unpacklo_epi64(in3, inB3);
+      // a00 a10 a20 a30   b00 b10 b20 b30
+      // a01 a11 a21 a31   b01 b11 b21 b31
+      // a02 a12 a22 a32   b02 b12 b22 b32
+      // a03 a13 a23 a33   b03 b13 b23 b33
+    }
+  }
+
+  // Vertical pass and subsequent transpose.
+  {
+    // First pass, c and d calculations are longer because of the "trick"
+    // multiplications.
+    const __m128i a = _mm_add_epi16(in0, in2);
+    const __m128i b = _mm_sub_epi16(in0, in2);
+    // c = MUL(in1, K2) - MUL(in3, K1) = MUL(in1, k2) - MUL(in3, k1) + in1 - in3
+    const __m128i c1 = _mm_mulhi_epi16(in1, k2);
+    const __m128i c2 = _mm_mulhi_epi16(in3, k1);
+    const __m128i c3 = _mm_sub_epi16(in1, in3);
+    const __m128i c4 = _mm_sub_epi16(c1, c2);
+    const __m128i c = _mm_add_epi16(c3, c4);
+    // d = MUL(in1, K1) + MUL(in3, K2) = MUL(in1, k1) + MUL(in3, k2) + in1 + in3
+    const __m128i d1 = _mm_mulhi_epi16(in1, k1);
+    const __m128i d2 = _mm_mulhi_epi16(in3, k2);
+    const __m128i d3 = _mm_add_epi16(in1, in3);
+    const __m128i d4 = _mm_add_epi16(d1, d2);
+    const __m128i d = _mm_add_epi16(d3, d4);
+
+    // Second pass.
+    const __m128i tmp0 = _mm_add_epi16(a, d);
+    const __m128i tmp1 = _mm_add_epi16(b, c);
+    const __m128i tmp2 = _mm_sub_epi16(b, c);
+    const __m128i tmp3 = _mm_sub_epi16(a, d);
+
+    // Transpose the two 4x4.
+    // a00 a01 a02 a03   b00 b01 b02 b03
+    // a10 a11 a12 a13   b10 b11 b12 b13
+    // a20 a21 a22 a23   b20 b21 b22 b23
+    // a30 a31 a32 a33   b30 b31 b32 b33
+    const __m128i transpose0_0 = _mm_unpacklo_epi16(tmp0, tmp1);
+    const __m128i transpose0_1 = _mm_unpacklo_epi16(tmp2, tmp3);
+    const __m128i transpose0_2 = _mm_unpackhi_epi16(tmp0, tmp1);
+    const __m128i transpose0_3 = _mm_unpackhi_epi16(tmp2, tmp3);
+    // a00 a10 a01 a11   a02 a12 a03 a13
+    // a20 a30 a21 a31   a22 a32 a23 a33
+    // b00 b10 b01 b11   b02 b12 b03 b13
+    // b20 b30 b21 b31   b22 b32 b23 b33
+    const __m128i transpose1_0 = _mm_unpacklo_epi32(transpose0_0, transpose0_1);
+    const __m128i transpose1_1 = _mm_unpacklo_epi32(transpose0_2, transpose0_3);
+    const __m128i transpose1_2 = _mm_unpackhi_epi32(transpose0_0, transpose0_1);
+    const __m128i transpose1_3 = _mm_unpackhi_epi32(transpose0_2, transpose0_3);
+    // a00 a10 a20 a30 a01 a11 a21 a31
+    // b00 b10 b20 b30 b01 b11 b21 b31
+    // a02 a12 a22 a32 a03 a13 a23 a33
+    // b02 b12 a22 b32 b03 b13 b23 b33
+    T0 = _mm_unpacklo_epi64(transpose1_0, transpose1_1);
+    T1 = _mm_unpackhi_epi64(transpose1_0, transpose1_1);
+    T2 = _mm_unpacklo_epi64(transpose1_2, transpose1_3);
+    T3 = _mm_unpackhi_epi64(transpose1_2, transpose1_3);
+    // a00 a10 a20 a30   b00 b10 b20 b30
+    // a01 a11 a21 a31   b01 b11 b21 b31
+    // a02 a12 a22 a32   b02 b12 b22 b32
+    // a03 a13 a23 a33   b03 b13 b23 b33
+  }
+
+  // Horizontal pass and subsequent transpose.
+  {
+    // First pass, c and d calculations are longer because of the "trick"
+    // multiplications.
+    const __m128i four = _mm_set1_epi16(4);
+    const __m128i dc = _mm_add_epi16(T0, four);
+    const __m128i a =  _mm_add_epi16(dc, T2);
+    const __m128i b =  _mm_sub_epi16(dc, T2);
+    // c = MUL(T1, K2) - MUL(T3, K1) = MUL(T1, k2) - MUL(T3, k1) + T1 - T3
+    const __m128i c1 = _mm_mulhi_epi16(T1, k2);
+    const __m128i c2 = _mm_mulhi_epi16(T3, k1);
+    const __m128i c3 = _mm_sub_epi16(T1, T3);
+    const __m128i c4 = _mm_sub_epi16(c1, c2);
+    const __m128i c = _mm_add_epi16(c3, c4);
+    // d = MUL(T1, K1) + MUL(T3, K2) = MUL(T1, k1) + MUL(T3, k2) + T1 + T3
+    const __m128i d1 = _mm_mulhi_epi16(T1, k1);
+    const __m128i d2 = _mm_mulhi_epi16(T3, k2);
+    const __m128i d3 = _mm_add_epi16(T1, T3);
+    const __m128i d4 = _mm_add_epi16(d1, d2);
+    const __m128i d = _mm_add_epi16(d3, d4);
+
+    // Second pass.
+    const __m128i tmp0 = _mm_add_epi16(a, d);
+    const __m128i tmp1 = _mm_add_epi16(b, c);
+    const __m128i tmp2 = _mm_sub_epi16(b, c);
+    const __m128i tmp3 = _mm_sub_epi16(a, d);
+    const __m128i shifted0 = _mm_srai_epi16(tmp0, 3);
+    const __m128i shifted1 = _mm_srai_epi16(tmp1, 3);
+    const __m128i shifted2 = _mm_srai_epi16(tmp2, 3);
+    const __m128i shifted3 = _mm_srai_epi16(tmp3, 3);
+
+    // Transpose the two 4x4.
+    // a00 a01 a02 a03   b00 b01 b02 b03
+    // a10 a11 a12 a13   b10 b11 b12 b13
+    // a20 a21 a22 a23   b20 b21 b22 b23
+    // a30 a31 a32 a33   b30 b31 b32 b33
+    const __m128i transpose0_0 = _mm_unpacklo_epi16(shifted0, shifted1);
+    const __m128i transpose0_1 = _mm_unpacklo_epi16(shifted2, shifted3);
+    const __m128i transpose0_2 = _mm_unpackhi_epi16(shifted0, shifted1);
+    const __m128i transpose0_3 = _mm_unpackhi_epi16(shifted2, shifted3);
+    // a00 a10 a01 a11   a02 a12 a03 a13
+    // a20 a30 a21 a31   a22 a32 a23 a33
+    // b00 b10 b01 b11   b02 b12 b03 b13
+    // b20 b30 b21 b31   b22 b32 b23 b33
+    const __m128i transpose1_0 = _mm_unpacklo_epi32(transpose0_0, transpose0_1);
+    const __m128i transpose1_1 = _mm_unpacklo_epi32(transpose0_2, transpose0_3);
+    const __m128i transpose1_2 = _mm_unpackhi_epi32(transpose0_0, transpose0_1);
+    const __m128i transpose1_3 = _mm_unpackhi_epi32(transpose0_2, transpose0_3);
+    // a00 a10 a20 a30 a01 a11 a21 a31
+    // b00 b10 b20 b30 b01 b11 b21 b31
+    // a02 a12 a22 a32 a03 a13 a23 a33
+    // b02 b12 a22 b32 b03 b13 b23 b33
+    T0 = _mm_unpacklo_epi64(transpose1_0, transpose1_1);
+    T1 = _mm_unpackhi_epi64(transpose1_0, transpose1_1);
+    T2 = _mm_unpacklo_epi64(transpose1_2, transpose1_3);
+    T3 = _mm_unpackhi_epi64(transpose1_2, transpose1_3);
+    // a00 a10 a20 a30   b00 b10 b20 b30
+    // a01 a11 a21 a31   b01 b11 b21 b31
+    // a02 a12 a22 a32   b02 b12 b22 b32
+    // a03 a13 a23 a33   b03 b13 b23 b33
+  }
+
+  // Add inverse transform to 'dst' and store.
+  {
+    const __m128i zero = _mm_setzero_si128();
+    // Load the reference(s).
+    __m128i dst0, dst1, dst2, dst3;
+    if (do_two) {
+      // Load eight bytes/pixels per line.
+      dst0 = _mm_loadl_epi64((__m128i*)(dst + 0 * BPS));
+      dst1 = _mm_loadl_epi64((__m128i*)(dst + 1 * BPS));
+      dst2 = _mm_loadl_epi64((__m128i*)(dst + 2 * BPS));
+      dst3 = _mm_loadl_epi64((__m128i*)(dst + 3 * BPS));
+    } else {
+      // Load four bytes/pixels per line.
+      dst0 = _mm_cvtsi32_si128(*(int*)(dst + 0 * BPS));
+      dst1 = _mm_cvtsi32_si128(*(int*)(dst + 1 * BPS));
+      dst2 = _mm_cvtsi32_si128(*(int*)(dst + 2 * BPS));
+      dst3 = _mm_cvtsi32_si128(*(int*)(dst + 3 * BPS));
+    }
+    // Convert to 16b.
+    dst0 = _mm_unpacklo_epi8(dst0, zero);
+    dst1 = _mm_unpacklo_epi8(dst1, zero);
+    dst2 = _mm_unpacklo_epi8(dst2, zero);
+    dst3 = _mm_unpacklo_epi8(dst3, zero);
+    // Add the inverse transform(s).
+    dst0 = _mm_add_epi16(dst0, T0);
+    dst1 = _mm_add_epi16(dst1, T1);
+    dst2 = _mm_add_epi16(dst2, T2);
+    dst3 = _mm_add_epi16(dst3, T3);
+    // Unsigned saturate to 8b.
+    dst0 = _mm_packus_epi16(dst0, dst0);
+    dst1 = _mm_packus_epi16(dst1, dst1);
+    dst2 = _mm_packus_epi16(dst2, dst2);
+    dst3 = _mm_packus_epi16(dst3, dst3);
+    // Store the results.
+    if (do_two) {
+      // Store eight bytes/pixels per line.
+      _mm_storel_epi64((__m128i*)(dst + 0 * BPS), dst0);
+      _mm_storel_epi64((__m128i*)(dst + 1 * BPS), dst1);
+      _mm_storel_epi64((__m128i*)(dst + 2 * BPS), dst2);
+      _mm_storel_epi64((__m128i*)(dst + 3 * BPS), dst3);
+    } else {
+      // Store four bytes/pixels per line.
+      *(int*)(dst + 0 * BPS) = _mm_cvtsi128_si32(dst0);
+      *(int*)(dst + 1 * BPS) = _mm_cvtsi128_si32(dst1);
+      *(int*)(dst + 2 * BPS) = _mm_cvtsi128_si32(dst2);
+      *(int*)(dst + 3 * BPS) = _mm_cvtsi128_si32(dst3);
+    }
+  }
+}
+
+#if defined(USE_TRANSFORM_AC3)
+#define MUL(a, b) (((a) * (b)) >> 16)
+static void TransformAC3(const int16_t* in, uint8_t* dst) {
+  static const int kC1 = 20091 + (1 << 16);
+  static const int kC2 = 35468;
+  const __m128i A = _mm_set1_epi16(in[0] + 4);
+  const __m128i c4 = _mm_set1_epi16(MUL(in[4], kC2));
+  const __m128i d4 = _mm_set1_epi16(MUL(in[4], kC1));
+  const int c1 = MUL(in[1], kC2);
+  const int d1 = MUL(in[1], kC1);
+  const __m128i CD = _mm_set_epi16(0, 0, 0, 0, -d1, -c1, c1, d1);
+  const __m128i B = _mm_adds_epi16(A, CD);
+  const __m128i m0 = _mm_adds_epi16(B, d4);
+  const __m128i m1 = _mm_adds_epi16(B, c4);
+  const __m128i m2 = _mm_subs_epi16(B, c4);
+  const __m128i m3 = _mm_subs_epi16(B, d4);
+  const __m128i zero = _mm_setzero_si128();
+  // Load the source pixels.
+  __m128i dst0 = _mm_cvtsi32_si128(*(int*)(dst + 0 * BPS));
+  __m128i dst1 = _mm_cvtsi32_si128(*(int*)(dst + 1 * BPS));
+  __m128i dst2 = _mm_cvtsi32_si128(*(int*)(dst + 2 * BPS));
+  __m128i dst3 = _mm_cvtsi32_si128(*(int*)(dst + 3 * BPS));
+  // Convert to 16b.
+  dst0 = _mm_unpacklo_epi8(dst0, zero);
+  dst1 = _mm_unpacklo_epi8(dst1, zero);
+  dst2 = _mm_unpacklo_epi8(dst2, zero);
+  dst3 = _mm_unpacklo_epi8(dst3, zero);
+  // Add the inverse transform.
+  dst0 = _mm_adds_epi16(dst0, _mm_srai_epi16(m0, 3));
+  dst1 = _mm_adds_epi16(dst1, _mm_srai_epi16(m1, 3));
+  dst2 = _mm_adds_epi16(dst2, _mm_srai_epi16(m2, 3));
+  dst3 = _mm_adds_epi16(dst3, _mm_srai_epi16(m3, 3));
+  // Unsigned saturate to 8b.
+  dst0 = _mm_packus_epi16(dst0, dst0);
+  dst1 = _mm_packus_epi16(dst1, dst1);
+  dst2 = _mm_packus_epi16(dst2, dst2);
+  dst3 = _mm_packus_epi16(dst3, dst3);
+  // Store the results.
+  *(int*)(dst + 0 * BPS) = _mm_cvtsi128_si32(dst0);
+  *(int*)(dst + 1 * BPS) = _mm_cvtsi128_si32(dst1);
+  *(int*)(dst + 2 * BPS) = _mm_cvtsi128_si32(dst2);
+  *(int*)(dst + 3 * BPS) = _mm_cvtsi128_si32(dst3);
+}
+#undef MUL
+#endif   // USE_TRANSFORM_AC3
+
+//------------------------------------------------------------------------------
+// Loop Filter (Paragraph 15)
+
+// Compute abs(p - q) = subs(p - q) OR subs(q - p)
+#define MM_ABS(p, q)  _mm_or_si128(                                            \
+    _mm_subs_epu8((q), (p)),                                                   \
+    _mm_subs_epu8((p), (q)))
+
+// Shift each byte of "x" by 3 bits while preserving by the sign bit.
+static WEBP_INLINE void SignedShift8b(__m128i* const x) {
+  const __m128i zero = _mm_setzero_si128();
+  const __m128i signs = _mm_cmpgt_epi8(zero, *x);
+  const __m128i lo_0 = _mm_unpacklo_epi8(*x, signs);  // s8 -> s16 sign extend
+  const __m128i hi_0 = _mm_unpackhi_epi8(*x, signs);
+  const __m128i lo_1 = _mm_srai_epi16(lo_0, 3);
+  const __m128i hi_1 = _mm_srai_epi16(hi_0, 3);
+  *x = _mm_packs_epi16(lo_1, hi_1);
+}
+
+#define FLIP_SIGN_BIT2(a, b) {                                                 \
+  a = _mm_xor_si128(a, sign_bit);                                              \
+  b = _mm_xor_si128(b, sign_bit);                                              \
+}
+
+#define FLIP_SIGN_BIT4(a, b, c, d) {                                           \
+  FLIP_SIGN_BIT2(a, b);                                                        \
+  FLIP_SIGN_BIT2(c, d);                                                        \
+}
+
+// input/output is uint8_t
+static WEBP_INLINE void GetNotHEV(const __m128i* const p1,
+                                  const __m128i* const p0,
+                                  const __m128i* const q0,
+                                  const __m128i* const q1,
+                                  int hev_thresh, __m128i* const not_hev) {
+  const __m128i zero = _mm_setzero_si128();
+  const __m128i t_1 = MM_ABS(*p1, *p0);
+  const __m128i t_2 = MM_ABS(*q1, *q0);
+
+  const __m128i h = _mm_set1_epi8(hev_thresh);
+  const __m128i t_3 = _mm_subs_epu8(t_1, h);  // abs(p1 - p0) - hev_tresh
+  const __m128i t_4 = _mm_subs_epu8(t_2, h);  // abs(q1 - q0) - hev_tresh
+
+  *not_hev = _mm_or_si128(t_3, t_4);
+  *not_hev = _mm_cmpeq_epi8(*not_hev, zero);  // not_hev <= t1 && not_hev <= t2
+}
+
+// input pixels are int8_t
+static WEBP_INLINE void GetBaseDelta(const __m128i* const p1,
+                                     const __m128i* const p0,
+                                     const __m128i* const q0,
+                                     const __m128i* const q1,
+                                     __m128i* const delta) {
+  // beware of addition order, for saturation!
+  const __m128i p1_q1 = _mm_subs_epi8(*p1, *q1);   // p1 - q1
+  const __m128i q0_p0 = _mm_subs_epi8(*q0, *p0);   // q0 - p0
+  const __m128i s1 = _mm_adds_epi8(p1_q1, q0_p0);  // p1 - q1 + 1 * (q0 - p0)
+  const __m128i s2 = _mm_adds_epi8(q0_p0, s1);     // p1 - q1 + 2 * (q0 - p0)
+  const __m128i s3 = _mm_adds_epi8(q0_p0, s2);     // p1 - q1 + 3 * (q0 - p0)
+  *delta = s3;
+}
+
+// input and output are int8_t
+static WEBP_INLINE void DoSimpleFilter(__m128i* const p0, __m128i* const q0,
+                                       const __m128i* const fl) {
+  const __m128i k3 = _mm_set1_epi8(3);
+  const __m128i k4 = _mm_set1_epi8(4);
+  __m128i v3 = _mm_adds_epi8(*fl, k3);
+  __m128i v4 = _mm_adds_epi8(*fl, k4);
+
+  SignedShift8b(&v4);                  // v4 >> 3
+  SignedShift8b(&v3);                  // v3 >> 3
+  *q0 = _mm_subs_epi8(*q0, v4);        // q0 -= v4
+  *p0 = _mm_adds_epi8(*p0, v3);        // p0 += v3
+}
+
+// Updates values of 2 pixels at MB edge during complex filtering.
+// Update operations:
+// q = q - delta and p = p + delta; where delta = [(a_hi >> 7), (a_lo >> 7)]
+// Pixels 'pi' and 'qi' are int8_t on input, uint8_t on output (sign flip).
+static WEBP_INLINE void Update2Pixels(__m128i* const pi, __m128i* const qi,
+                                      const __m128i* const a0_lo,
+                                      const __m128i* const a0_hi) {
+  const __m128i a1_lo = _mm_srai_epi16(*a0_lo, 7);
+  const __m128i a1_hi = _mm_srai_epi16(*a0_hi, 7);
+  const __m128i delta = _mm_packs_epi16(a1_lo, a1_hi);
+  const __m128i sign_bit = _mm_set1_epi8(0x80);
+  *pi = _mm_adds_epi8(*pi, delta);
+  *qi = _mm_subs_epi8(*qi, delta);
+  FLIP_SIGN_BIT2(*pi, *qi);
+}
+
+// input pixels are uint8_t
+static WEBP_INLINE void NeedsFilter(const __m128i* const p1,
+                                    const __m128i* const p0,
+                                    const __m128i* const q0,
+                                    const __m128i* const q1,
+                                    int thresh, __m128i* const mask) {
+  const __m128i m_thresh = _mm_set1_epi8(thresh);
+  const __m128i t1 = MM_ABS(*p1, *q1);        // abs(p1 - q1)
+  const __m128i kFE = _mm_set1_epi8(0xFE);
+  const __m128i t2 = _mm_and_si128(t1, kFE);  // set lsb of each byte to zero
+  const __m128i t3 = _mm_srli_epi16(t2, 1);   // abs(p1 - q1) / 2
+
+  const __m128i t4 = MM_ABS(*p0, *q0);        // abs(p0 - q0)
+  const __m128i t5 = _mm_adds_epu8(t4, t4);   // abs(p0 - q0) * 2
+  const __m128i t6 = _mm_adds_epu8(t5, t3);   // abs(p0-q0)*2 + abs(p1-q1)/2
+
+  const __m128i t7 = _mm_subs_epu8(t6, m_thresh);  // mask <= m_thresh
+  *mask = _mm_cmpeq_epi8(t7, _mm_setzero_si128());
+}
+
+//------------------------------------------------------------------------------
+// Edge filtering functions
+
+// Applies filter on 2 pixels (p0 and q0)
+static WEBP_INLINE void DoFilter2(__m128i* const p1, __m128i* const p0,
+                                  __m128i* const q0, __m128i* const q1,
+                                  int thresh) {
+  __m128i a, mask;
+  const __m128i sign_bit = _mm_set1_epi8(0x80);
+  // convert p1/q1 to int8_t (for GetBaseDelta)
+  const __m128i p1s = _mm_xor_si128(*p1, sign_bit);
+  const __m128i q1s = _mm_xor_si128(*q1, sign_bit);
+
+  NeedsFilter(p1, p0, q0, q1, thresh, &mask);
+
+  FLIP_SIGN_BIT2(*p0, *q0);
+  GetBaseDelta(&p1s, p0, q0, &q1s, &a);
+  a = _mm_and_si128(a, mask);     // mask filter values we don't care about
+  DoSimpleFilter(p0, q0, &a);
+  FLIP_SIGN_BIT2(*p0, *q0);
+}
+
+// Applies filter on 4 pixels (p1, p0, q0 and q1)
+static WEBP_INLINE void DoFilter4(__m128i* const p1, __m128i* const p0,
+                                  __m128i* const q0, __m128i* const q1,
+                                  const __m128i* const mask, int hev_thresh) {
+  const __m128i sign_bit = _mm_set1_epi8(0x80);
+  const __m128i k64 = _mm_set1_epi8(0x40);
+  const __m128i zero = _mm_setzero_si128();
+  __m128i not_hev;
+  __m128i t1, t2, t3;
+
+  // compute hev mask
+  GetNotHEV(p1, p0, q0, q1, hev_thresh, &not_hev);
+
+  // convert to signed values
+  FLIP_SIGN_BIT4(*p1, *p0, *q0, *q1);
+
+  t1 = _mm_subs_epi8(*p1, *q1);        // p1 - q1
+  t1 = _mm_andnot_si128(not_hev, t1);  // hev(p1 - q1)
+  t2 = _mm_subs_epi8(*q0, *p0);        // q0 - p0
+  t1 = _mm_adds_epi8(t1, t2);          // hev(p1 - q1) + 1 * (q0 - p0)
+  t1 = _mm_adds_epi8(t1, t2);          // hev(p1 - q1) + 2 * (q0 - p0)
+  t1 = _mm_adds_epi8(t1, t2);          // hev(p1 - q1) + 3 * (q0 - p0)
+  t1 = _mm_and_si128(t1, *mask);       // mask filter values we don't care about
+
+  t2 = _mm_set1_epi8(3);
+  t3 = _mm_set1_epi8(4);
+  t2 = _mm_adds_epi8(t1, t2);        // 3 * (q0 - p0) + (p1 - q1) + 3
+  t3 = _mm_adds_epi8(t1, t3);        // 3 * (q0 - p0) + (p1 - q1) + 4
+  SignedShift8b(&t2);                // (3 * (q0 - p0) + hev(p1 - q1) + 3) >> 3
+  SignedShift8b(&t3);                // (3 * (q0 - p0) + hev(p1 - q1) + 4) >> 3
+  *p0 = _mm_adds_epi8(*p0, t2);      // p0 += t2
+  *q0 = _mm_subs_epi8(*q0, t3);      // q0 -= t3
+  FLIP_SIGN_BIT2(*p0, *q0);
+
+  // this is equivalent to signed (a + 1) >> 1 calculation
+  t2 = _mm_add_epi8(t3, sign_bit);
+  t3 = _mm_avg_epu8(t2, zero);
+  t3 = _mm_sub_epi8(t3, k64);
+
+  t3 = _mm_and_si128(not_hev, t3);   // if !hev
+  *q1 = _mm_subs_epi8(*q1, t3);      // q1 -= t3
+  *p1 = _mm_adds_epi8(*p1, t3);      // p1 += t3
+  FLIP_SIGN_BIT2(*p1, *q1);
+}
+
+// Applies filter on 6 pixels (p2, p1, p0, q0, q1 and q2)
+static WEBP_INLINE void DoFilter6(__m128i* const p2, __m128i* const p1,
+                                  __m128i* const p0, __m128i* const q0,
+                                  __m128i* const q1, __m128i* const q2,
+                                  const __m128i* const mask, int hev_thresh) {
+  const __m128i zero = _mm_setzero_si128();
+  const __m128i sign_bit = _mm_set1_epi8(0x80);
+  __m128i a, not_hev;
+
+  // compute hev mask
+  GetNotHEV(p1, p0, q0, q1, hev_thresh, &not_hev);
+
+  FLIP_SIGN_BIT4(*p1, *p0, *q0, *q1);
+  FLIP_SIGN_BIT2(*p2, *q2);
+  GetBaseDelta(p1, p0, q0, q1, &a);
+
+  { // do simple filter on pixels with hev
+    const __m128i m = _mm_andnot_si128(not_hev, *mask);
+    const __m128i f = _mm_and_si128(a, m);
+    DoSimpleFilter(p0, q0, &f);
+  }
+
+  { // do strong filter on pixels with not hev
+    const __m128i k9 = _mm_set1_epi16(0x0900);
+    const __m128i k63 = _mm_set1_epi16(63);
+
+    const __m128i m = _mm_and_si128(not_hev, *mask);
+    const __m128i f = _mm_and_si128(a, m);
+
+    const __m128i f_lo = _mm_unpacklo_epi8(zero, f);
+    const __m128i f_hi = _mm_unpackhi_epi8(zero, f);
+
+    const __m128i f9_lo = _mm_mulhi_epi16(f_lo, k9);    // Filter (lo) * 9
+    const __m128i f9_hi = _mm_mulhi_epi16(f_hi, k9);    // Filter (hi) * 9
+
+    const __m128i a2_lo = _mm_add_epi16(f9_lo, k63);    // Filter * 9 + 63
+    const __m128i a2_hi = _mm_add_epi16(f9_hi, k63);    // Filter * 9 + 63
+
+    const __m128i a1_lo = _mm_add_epi16(a2_lo, f9_lo);  // Filter * 18 + 63
+    const __m128i a1_hi = _mm_add_epi16(a2_hi, f9_hi);  // Filter * 18 + 63
+
+    const __m128i a0_lo = _mm_add_epi16(a1_lo, f9_lo);  // Filter * 27 + 63
+    const __m128i a0_hi = _mm_add_epi16(a1_hi, f9_hi);  // Filter * 27 + 63
+
+    Update2Pixels(p2, q2, &a2_lo, &a2_hi);
+    Update2Pixels(p1, q1, &a1_lo, &a1_hi);
+    Update2Pixels(p0, q0, &a0_lo, &a0_hi);
+  }
+}
+
+// reads 8 rows across a vertical edge.
+//
+// TODO(somnath): Investigate _mm_shuffle* also see if it can be broken into
+// two Load4x4() to avoid code duplication.
+static WEBP_INLINE void Load8x4(const uint8_t* const b, int stride,
+                                __m128i* const p, __m128i* const q) {
+  __m128i t1, t2;
+
+  // Load 0th, 1st, 4th and 5th rows
+  __m128i r0 =  _mm_cvtsi32_si128(*(const int*)&b[0 * stride]);  // 03 02 01 00
+  __m128i r1 =  _mm_cvtsi32_si128(*(const int*)&b[1 * stride]);  // 13 12 11 10
+  __m128i r4 =  _mm_cvtsi32_si128(*(const int*)&b[4 * stride]);  // 43 42 41 40
+  __m128i r5 =  _mm_cvtsi32_si128(*(const int*)&b[5 * stride]);  // 53 52 51 50
+
+  r0 = _mm_unpacklo_epi32(r0, r4);               // 43 42 41 40 03 02 01 00
+  r1 = _mm_unpacklo_epi32(r1, r5);               // 53 52 51 50 13 12 11 10
+
+  // t1 = 53 43 52 42 51 41 50 40 13 03 12 02 11 01 10 00
+  t1 = _mm_unpacklo_epi8(r0, r1);
+
+  // Load 2nd, 3rd, 6th and 7th rows
+  r0 =  _mm_cvtsi32_si128(*(const int*)&b[2 * stride]);          // 23 22 21 22
+  r1 =  _mm_cvtsi32_si128(*(const int*)&b[3 * stride]);          // 33 32 31 30
+  r4 =  _mm_cvtsi32_si128(*(const int*)&b[6 * stride]);          // 63 62 61 60
+  r5 =  _mm_cvtsi32_si128(*(const int*)&b[7 * stride]);          // 73 72 71 70
+
+  r0 = _mm_unpacklo_epi32(r0, r4);               // 63 62 61 60 23 22 21 20
+  r1 = _mm_unpacklo_epi32(r1, r5);               // 73 72 71 70 33 32 31 30
+
+  // t2 = 73 63 72 62 71 61 70 60 33 23 32 22 31 21 30 20
+  t2 = _mm_unpacklo_epi8(r0, r1);
+
+  // t1 = 33 23 13 03 32 22 12 02 31 21 11 01 30 20 10 00
+  // t2 = 73 63 53 43 72 62 52 42 71 61 51 41 70 60 50 40
+  r0 = t1;
+  t1 = _mm_unpacklo_epi16(t1, t2);
+  t2 = _mm_unpackhi_epi16(r0, t2);
+
+  // *p = 71 61 51 41 31 21 11 01 70 60 50 40 30 20 10 00
+  // *q = 73 63 53 43 33 23 13 03 72 62 52 42 32 22 12 02
+  *p = _mm_unpacklo_epi32(t1, t2);
+  *q = _mm_unpackhi_epi32(t1, t2);
+}
+
+static WEBP_INLINE void Load16x4(const uint8_t* const r0,
+                                 const uint8_t* const r8,
+                                 int stride,
+                                 __m128i* const p1, __m128i* const p0,
+                                 __m128i* const q0, __m128i* const q1) {
+  __m128i t1, t2;
+  // Assume the pixels around the edge (|) are numbered as follows
+  //                00 01 | 02 03
+  //                10 11 | 12 13
+  //                 ...  |  ...
+  //                e0 e1 | e2 e3
+  //                f0 f1 | f2 f3
+  //
+  // r0 is pointing to the 0th row (00)
+  // r8 is pointing to the 8th row (80)
+
+  // Load
+  // p1 = 71 61 51 41 31 21 11 01 70 60 50 40 30 20 10 00
+  // q0 = 73 63 53 43 33 23 13 03 72 62 52 42 32 22 12 02
+  // p0 = f1 e1 d1 c1 b1 a1 91 81 f0 e0 d0 c0 b0 a0 90 80
+  // q1 = f3 e3 d3 c3 b3 a3 93 83 f2 e2 d2 c2 b2 a2 92 82
+  Load8x4(r0, stride, p1, q0);
+  Load8x4(r8, stride, p0, q1);
+
+  t1 = *p1;
+  t2 = *q0;
+  // p1 = f0 e0 d0 c0 b0 a0 90 80 70 60 50 40 30 20 10 00
+  // p0 = f1 e1 d1 c1 b1 a1 91 81 71 61 51 41 31 21 11 01
+  // q0 = f2 e2 d2 c2 b2 a2 92 82 72 62 52 42 32 22 12 02
+  // q1 = f3 e3 d3 c3 b3 a3 93 83 73 63 53 43 33 23 13 03
+  *p1 = _mm_unpacklo_epi64(t1, *p0);
+  *p0 = _mm_unpackhi_epi64(t1, *p0);
+  *q0 = _mm_unpacklo_epi64(t2, *q1);
+  *q1 = _mm_unpackhi_epi64(t2, *q1);
+}
+
+static WEBP_INLINE void Store4x4(__m128i* const x, uint8_t* dst, int stride) {
+  int i;
+  for (i = 0; i < 4; ++i, dst += stride) {
+    *((int32_t*)dst) = _mm_cvtsi128_si32(*x);
+    *x = _mm_srli_si128(*x, 4);
+  }
+}
+
+// Transpose back and store
+static WEBP_INLINE void Store16x4(const __m128i* const p1,
+                                  const __m128i* const p0,
+                                  const __m128i* const q0,
+                                  const __m128i* const q1,
+                                  uint8_t* r0, uint8_t* r8,
+                                  int stride) {
+  __m128i t1, p1_s, p0_s, q0_s, q1_s;
+
+  // p0 = 71 70 61 60 51 50 41 40 31 30 21 20 11 10 01 00
+  // p1 = f1 f0 e1 e0 d1 d0 c1 c0 b1 b0 a1 a0 91 90 81 80
+  t1 = *p0;
+  p0_s = _mm_unpacklo_epi8(*p1, t1);
+  p1_s = _mm_unpackhi_epi8(*p1, t1);
+
+  // q0 = 73 72 63 62 53 52 43 42 33 32 23 22 13 12 03 02
+  // q1 = f3 f2 e3 e2 d3 d2 c3 c2 b3 b2 a3 a2 93 92 83 82
+  t1 = *q0;
+  q0_s = _mm_unpacklo_epi8(t1, *q1);
+  q1_s = _mm_unpackhi_epi8(t1, *q1);
+
+  // p0 = 33 32 31 30 23 22 21 20 13 12 11 10 03 02 01 00
+  // q0 = 73 72 71 70 63 62 61 60 53 52 51 50 43 42 41 40
+  t1 = p0_s;
+  p0_s = _mm_unpacklo_epi16(t1, q0_s);
+  q0_s = _mm_unpackhi_epi16(t1, q0_s);
+
+  // p1 = b3 b2 b1 b0 a3 a2 a1 a0 93 92 91 90 83 82 81 80
+  // q1 = f3 f2 f1 f0 e3 e2 e1 e0 d3 d2 d1 d0 c3 c2 c1 c0
+  t1 = p1_s;
+  p1_s = _mm_unpacklo_epi16(t1, q1_s);
+  q1_s = _mm_unpackhi_epi16(t1, q1_s);
+
+  Store4x4(&p0_s, r0, stride);
+  r0 += 4 * stride;
+  Store4x4(&q0_s, r0, stride);
+
+  Store4x4(&p1_s, r8, stride);
+  r8 += 4 * stride;
+  Store4x4(&q1_s, r8, stride);
+}
+
+//------------------------------------------------------------------------------
+// Simple In-loop filtering (Paragraph 15.2)
+
+static void SimpleVFilter16(uint8_t* p, int stride, int thresh) {
+  // Load
+  __m128i p1 = _mm_loadu_si128((__m128i*)&p[-2 * stride]);
+  __m128i p0 = _mm_loadu_si128((__m128i*)&p[-stride]);
+  __m128i q0 = _mm_loadu_si128((__m128i*)&p[0]);
+  __m128i q1 = _mm_loadu_si128((__m128i*)&p[stride]);
+
+  DoFilter2(&p1, &p0, &q0, &q1, thresh);
+
+  // Store
+  _mm_storeu_si128((__m128i*)&p[-stride], p0);
+  _mm_storeu_si128((__m128i*)&p[0], q0);
+}
+
+static void SimpleHFilter16(uint8_t* p, int stride, int thresh) {
+  __m128i p1, p0, q0, q1;
+
+  p -= 2;  // beginning of p1
+
+  Load16x4(p, p + 8 * stride, stride, &p1, &p0, &q0, &q1);
+  DoFilter2(&p1, &p0, &q0, &q1, thresh);
+  Store16x4(&p1, &p0, &q0, &q1, p, p + 8 * stride, stride);
+}
+
+static void SimpleVFilter16i(uint8_t* p, int stride, int thresh) {
+  int k;
+  for (k = 3; k > 0; --k) {
+    p += 4 * stride;
+    SimpleVFilter16(p, stride, thresh);
+  }
+}
+
+static void SimpleHFilter16i(uint8_t* p, int stride, int thresh) {
+  int k;
+  for (k = 3; k > 0; --k) {
+    p += 4;
+    SimpleHFilter16(p, stride, thresh);
+  }
+}
+
+//------------------------------------------------------------------------------
+// Complex In-loop filtering (Paragraph 15.3)
+
+#define MAX_DIFF1(p3, p2, p1, p0, m) do {                                      \
+  m = MM_ABS(p1, p0);                                                          \
+  m = _mm_max_epu8(m, MM_ABS(p3, p2));                                         \
+  m = _mm_max_epu8(m, MM_ABS(p2, p1));                                         \
+} while (0)
+
+#define MAX_DIFF2(p3, p2, p1, p0, m) do {                                      \
+  m = _mm_max_epu8(m, MM_ABS(p1, p0));                                         \
+  m = _mm_max_epu8(m, MM_ABS(p3, p2));                                         \
+  m = _mm_max_epu8(m, MM_ABS(p2, p1));                                         \
+} while (0)
+
+#define LOAD_H_EDGES4(p, stride, e1, e2, e3, e4) {                             \
+  e1 = _mm_loadu_si128((__m128i*)&(p)[0 * stride]);                            \
+  e2 = _mm_loadu_si128((__m128i*)&(p)[1 * stride]);                            \
+  e3 = _mm_loadu_si128((__m128i*)&(p)[2 * stride]);                            \
+  e4 = _mm_loadu_si128((__m128i*)&(p)[3 * stride]);                            \
+}
+
+#define LOADUV_H_EDGE(p, u, v, stride) do {                                    \
+  const __m128i U = _mm_loadl_epi64((__m128i*)&(u)[(stride)]);                 \
+  const __m128i V = _mm_loadl_epi64((__m128i*)&(v)[(stride)]);                 \
+  p = _mm_unpacklo_epi64(U, V);                                                \
+} while (0)
+
+#define LOADUV_H_EDGES4(u, v, stride, e1, e2, e3, e4) {                        \
+  LOADUV_H_EDGE(e1, u, v, 0 * stride);                                         \
+  LOADUV_H_EDGE(e2, u, v, 1 * stride);                                         \
+  LOADUV_H_EDGE(e3, u, v, 2 * stride);                                         \
+  LOADUV_H_EDGE(e4, u, v, 3 * stride);                                         \
+}
+
+#define STOREUV(p, u, v, stride) {                                             \
+  _mm_storel_epi64((__m128i*)&u[(stride)], p);                                 \
+  p = _mm_srli_si128(p, 8);                                                    \
+  _mm_storel_epi64((__m128i*)&v[(stride)], p);                                 \
+}
+
+static WEBP_INLINE void ComplexMask(const __m128i* const p1,
+                                    const __m128i* const p0,
+                                    const __m128i* const q0,
+                                    const __m128i* const q1,
+                                    int thresh, int ithresh,
+                                    __m128i* const mask) {
+  const __m128i it = _mm_set1_epi8(ithresh);
+  const __m128i diff = _mm_subs_epu8(*mask, it);
+  const __m128i thresh_mask = _mm_cmpeq_epi8(diff, _mm_setzero_si128());
+  __m128i filter_mask;
+  NeedsFilter(p1, p0, q0, q1, thresh, &filter_mask);
+  *mask = _mm_and_si128(thresh_mask, filter_mask);
+}
+
+// on macroblock edges
+static void VFilter16(uint8_t* p, int stride,
+                      int thresh, int ithresh, int hev_thresh) {
+  __m128i t1;
+  __m128i mask;
+  __m128i p2, p1, p0, q0, q1, q2;
+
+  // Load p3, p2, p1, p0
+  LOAD_H_EDGES4(p - 4 * stride, stride, t1, p2, p1, p0);
+  MAX_DIFF1(t1, p2, p1, p0, mask);
+
+  // Load q0, q1, q2, q3
+  LOAD_H_EDGES4(p, stride, q0, q1, q2, t1);
+  MAX_DIFF2(t1, q2, q1, q0, mask);
+
+  ComplexMask(&p1, &p0, &q0, &q1, thresh, ithresh, &mask);
+  DoFilter6(&p2, &p1, &p0, &q0, &q1, &q2, &mask, hev_thresh);
+
+  // Store
+  _mm_storeu_si128((__m128i*)&p[-3 * stride], p2);
+  _mm_storeu_si128((__m128i*)&p[-2 * stride], p1);
+  _mm_storeu_si128((__m128i*)&p[-1 * stride], p0);
+  _mm_storeu_si128((__m128i*)&p[+0 * stride], q0);
+  _mm_storeu_si128((__m128i*)&p[+1 * stride], q1);
+  _mm_storeu_si128((__m128i*)&p[+2 * stride], q2);
+}
+
+static void HFilter16(uint8_t* p, int stride,
+                      int thresh, int ithresh, int hev_thresh) {
+  __m128i mask;
+  __m128i p3, p2, p1, p0, q0, q1, q2, q3;
+
+  uint8_t* const b = p - 4;
+  Load16x4(b, b + 8 * stride, stride, &p3, &p2, &p1, &p0);  // p3, p2, p1, p0
+  MAX_DIFF1(p3, p2, p1, p0, mask);
+
+  Load16x4(p, p + 8 * stride, stride, &q0, &q1, &q2, &q3);  // q0, q1, q2, q3
+  MAX_DIFF2(q3, q2, q1, q0, mask);
+
+  ComplexMask(&p1, &p0, &q0, &q1, thresh, ithresh, &mask);
+  DoFilter6(&p2, &p1, &p0, &q0, &q1, &q2, &mask, hev_thresh);
+
+  Store16x4(&p3, &p2, &p1, &p0, b, b + 8 * stride, stride);
+  Store16x4(&q0, &q1, &q2, &q3, p, p + 8 * stride, stride);
+}
+
+// on three inner edges
+static void VFilter16i(uint8_t* p, int stride,
+                       int thresh, int ithresh, int hev_thresh) {
+  int k;
+  __m128i p3, p2, p1, p0;   // loop invariants
+
+  LOAD_H_EDGES4(p, stride, p3, p2, p1, p0);  // prologue
+
+  for (k = 3; k > 0; --k) {
+    __m128i mask, tmp1, tmp2;
+    uint8_t* const b = p + 2 * stride;   // beginning of p1
+    p += 4 * stride;
+
+    MAX_DIFF1(p3, p2, p1, p0, mask);   // compute partial mask
+    LOAD_H_EDGES4(p, stride, p3, p2, tmp1, tmp2);
+    MAX_DIFF2(p3, p2, tmp1, tmp2, mask);
+
+    // p3 and p2 are not just temporary variables here: they will be
+    // re-used for next span. And q2/q3 will become p1/p0 accordingly.
+    ComplexMask(&p1, &p0, &p3, &p2, thresh, ithresh, &mask);
+    DoFilter4(&p1, &p0, &p3, &p2, &mask, hev_thresh);
+
+    // Store
+    _mm_storeu_si128((__m128i*)&b[0 * stride], p1);
+    _mm_storeu_si128((__m128i*)&b[1 * stride], p0);
+    _mm_storeu_si128((__m128i*)&b[2 * stride], p3);
+    _mm_storeu_si128((__m128i*)&b[3 * stride], p2);
+
+    // rotate samples
+    p1 = tmp1;
+    p0 = tmp2;
+  }
+}
+
+static void HFilter16i(uint8_t* p, int stride,
+                       int thresh, int ithresh, int hev_thresh) {
+  int k;
+  __m128i p3, p2, p1, p0;   // loop invariants
+
+  Load16x4(p, p + 8 * stride, stride, &p3, &p2, &p1, &p0);  // prologue
+
+  for (k = 3; k > 0; --k) {
+    __m128i mask, tmp1, tmp2;
+    uint8_t* const b = p + 2;   // beginning of p1
+
+    p += 4;  // beginning of q0 (and next span)
+
+    MAX_DIFF1(p3, p2, p1, p0, mask);   // compute partial mask
+    Load16x4(p, p + 8 * stride, stride, &p3, &p2, &tmp1, &tmp2);
+    MAX_DIFF2(p3, p2, tmp1, tmp2, mask);
+
+    ComplexMask(&p1, &p0, &p3, &p2, thresh, ithresh, &mask);
+    DoFilter4(&p1, &p0, &p3, &p2, &mask, hev_thresh);
+
+    Store16x4(&p1, &p0, &p3, &p2, b, b + 8 * stride, stride);
+
+    // rotate samples
+    p1 = tmp1;
+    p0 = tmp2;
+  }
+}
+
+// 8-pixels wide variant, for chroma filtering
+static void VFilter8(uint8_t* u, uint8_t* v, int stride,
+                     int thresh, int ithresh, int hev_thresh) {
+  __m128i mask;
+  __m128i t1, p2, p1, p0, q0, q1, q2;
+
+  // Load p3, p2, p1, p0
+  LOADUV_H_EDGES4(u - 4 * stride, v - 4 * stride, stride, t1, p2, p1, p0);
+  MAX_DIFF1(t1, p2, p1, p0, mask);
+
+  // Load q0, q1, q2, q3
+  LOADUV_H_EDGES4(u, v, stride, q0, q1, q2, t1);
+  MAX_DIFF2(t1, q2, q1, q0, mask);
+
+  ComplexMask(&p1, &p0, &q0, &q1, thresh, ithresh, &mask);
+  DoFilter6(&p2, &p1, &p0, &q0, &q1, &q2, &mask, hev_thresh);
+
+  // Store
+  STOREUV(p2, u, v, -3 * stride);
+  STOREUV(p1, u, v, -2 * stride);
+  STOREUV(p0, u, v, -1 * stride);
+  STOREUV(q0, u, v, 0 * stride);
+  STOREUV(q1, u, v, 1 * stride);
+  STOREUV(q2, u, v, 2 * stride);
+}
+
+static void HFilter8(uint8_t* u, uint8_t* v, int stride,
+                     int thresh, int ithresh, int hev_thresh) {
+  __m128i mask;
+  __m128i p3, p2, p1, p0, q0, q1, q2, q3;
+
+  uint8_t* const tu = u - 4;
+  uint8_t* const tv = v - 4;
+  Load16x4(tu, tv, stride, &p3, &p2, &p1, &p0);  // p3, p2, p1, p0
+  MAX_DIFF1(p3, p2, p1, p0, mask);
+
+  Load16x4(u, v, stride, &q0, &q1, &q2, &q3);    // q0, q1, q2, q3
+  MAX_DIFF2(q3, q2, q1, q0, mask);
+
+  ComplexMask(&p1, &p0, &q0, &q1, thresh, ithresh, &mask);
+  DoFilter6(&p2, &p1, &p0, &q0, &q1, &q2, &mask, hev_thresh);
+
+  Store16x4(&p3, &p2, &p1, &p0, tu, tv, stride);
+  Store16x4(&q0, &q1, &q2, &q3, u, v, stride);
+}
+
+static void VFilter8i(uint8_t* u, uint8_t* v, int stride,
+                      int thresh, int ithresh, int hev_thresh) {
+  __m128i mask;
+  __m128i t1, t2, p1, p0, q0, q1;
+
+  // Load p3, p2, p1, p0
+  LOADUV_H_EDGES4(u, v, stride, t2, t1, p1, p0);
+  MAX_DIFF1(t2, t1, p1, p0, mask);
+
+  u += 4 * stride;
+  v += 4 * stride;
+
+  // Load q0, q1, q2, q3
+  LOADUV_H_EDGES4(u, v, stride, q0, q1, t1, t2);
+  MAX_DIFF2(t2, t1, q1, q0, mask);
+
+  ComplexMask(&p1, &p0, &q0, &q1, thresh, ithresh, &mask);
+  DoFilter4(&p1, &p0, &q0, &q1, &mask, hev_thresh);
+
+  // Store
+  STOREUV(p1, u, v, -2 * stride);
+  STOREUV(p0, u, v, -1 * stride);
+  STOREUV(q0, u, v, 0 * stride);
+  STOREUV(q1, u, v, 1 * stride);
+}
+
+static void HFilter8i(uint8_t* u, uint8_t* v, int stride,
+                      int thresh, int ithresh, int hev_thresh) {
+  __m128i mask;
+  __m128i t1, t2, p1, p0, q0, q1;
+  Load16x4(u, v, stride, &t2, &t1, &p1, &p0);   // p3, p2, p1, p0
+  MAX_DIFF1(t2, t1, p1, p0, mask);
+
+  u += 4;  // beginning of q0
+  v += 4;
+  Load16x4(u, v, stride, &q0, &q1, &t1, &t2);  // q0, q1, q2, q3
+  MAX_DIFF2(t2, t1, q1, q0, mask);
+
+  ComplexMask(&p1, &p0, &q0, &q1, thresh, ithresh, &mask);
+  DoFilter4(&p1, &p0, &q0, &q1, &mask, hev_thresh);
+
+  u -= 2;  // beginning of p1
+  v -= 2;
+  Store16x4(&p1, &p0, &q0, &q1, u, v, stride);
+}
+
+//------------------------------------------------------------------------------
+// 4x4 predictions
+
+#define DST(x, y) dst[(x) + (y) * BPS]
+#define AVG3(a, b, c) (((a) + 2 * (b) + (c) + 2) >> 2)
+
+// We use the following 8b-arithmetic tricks:
+//     (a + 2 * b + c + 2) >> 2 = (AC + b + 1) >> 1
+//   where: AC = (a + c) >> 1 = [(a + c + 1) >> 1] - [(a^c) & 1]
+// and:
+//     (a + 2 * b + c + 2) >> 2 = (AB + BC + 1) >> 1 - (ab|bc)&lsb
+//   where: AC = (a + b + 1) >> 1,   BC = (b + c + 1) >> 1
+//   and ab = a ^ b, bc = b ^ c, lsb = (AC^BC)&1
+
+static void VE4(uint8_t* dst) {    // vertical
+  const __m128i one = _mm_set1_epi8(1);
+  const __m128i ABCDEFGH = _mm_loadl_epi64((__m128i*)(dst - BPS - 1));
+  const __m128i BCDEFGH0 = _mm_srli_si128(ABCDEFGH, 1);
+  const __m128i CDEFGH00 = _mm_srli_si128(ABCDEFGH, 2);
+  const __m128i a = _mm_avg_epu8(ABCDEFGH, CDEFGH00);
+  const __m128i lsb = _mm_and_si128(_mm_xor_si128(ABCDEFGH, CDEFGH00), one);
+  const __m128i b = _mm_subs_epu8(a, lsb);
+  const __m128i avg = _mm_avg_epu8(b, BCDEFGH0);
+  const uint32_t vals = _mm_cvtsi128_si32(avg);
+  int i;
+  for (i = 0; i < 4; ++i) {
+    *(uint32_t*)(dst + i * BPS) = vals;
+  }
+}
+
+static void LD4(uint8_t* dst) {   // Down-Left
+  const __m128i one = _mm_set1_epi8(1);
+  const __m128i ABCDEFGH = _mm_loadl_epi64((__m128i*)(dst - BPS));
+  const __m128i BCDEFGH0 = _mm_srli_si128(ABCDEFGH, 1);
+  const __m128i CDEFGH00 = _mm_srli_si128(ABCDEFGH, 2);
+  const __m128i CDEFGHH0 = _mm_insert_epi16(CDEFGH00, dst[-BPS + 7], 3);
+  const __m128i avg1 = _mm_avg_epu8(ABCDEFGH, CDEFGHH0);
+  const __m128i lsb = _mm_and_si128(_mm_xor_si128(ABCDEFGH, CDEFGHH0), one);
+  const __m128i avg2 = _mm_subs_epu8(avg1, lsb);
+  const __m128i abcdefg = _mm_avg_epu8(avg2, BCDEFGH0);
+  *(uint32_t*)(dst + 0 * BPS) = _mm_cvtsi128_si32(               abcdefg    );
+  *(uint32_t*)(dst + 1 * BPS) = _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1));
+  *(uint32_t*)(dst + 2 * BPS) = _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2));
+  *(uint32_t*)(dst + 3 * BPS) = _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3));
+}
+
+static void VR4(uint8_t* dst) {   // Vertical-Right
+  const __m128i one = _mm_set1_epi8(1);
+  const int I = dst[-1 + 0 * BPS];
+  const int J = dst[-1 + 1 * BPS];
+  const int K = dst[-1 + 2 * BPS];
+  const int X = dst[-1 - BPS];
+  const __m128i XABCD = _mm_loadl_epi64((__m128i*)(dst - BPS - 1));
+  const __m128i ABCD0 = _mm_srli_si128(XABCD, 1);
+  const __m128i abcd = _mm_avg_epu8(XABCD, ABCD0);
+  const __m128i _XABCD = _mm_slli_si128(XABCD, 1);
+  const __m128i IXABCD = _mm_insert_epi16(_XABCD, I | (X << 8), 0);
+  const __m128i avg1 = _mm_avg_epu8(IXABCD, ABCD0);
+  const __m128i lsb = _mm_and_si128(_mm_xor_si128(IXABCD, ABCD0), one);
+  const __m128i avg2 = _mm_subs_epu8(avg1, lsb);
+  const __m128i efgh = _mm_avg_epu8(avg2, XABCD);
+  *(uint32_t*)(dst + 0 * BPS) = _mm_cvtsi128_si32(               abcd    );
+  *(uint32_t*)(dst + 1 * BPS) = _mm_cvtsi128_si32(               efgh    );
+  *(uint32_t*)(dst + 2 * BPS) = _mm_cvtsi128_si32(_mm_slli_si128(abcd, 1));
+  *(uint32_t*)(dst + 3 * BPS) = _mm_cvtsi128_si32(_mm_slli_si128(efgh, 1));
+
+  // these two are hard to implement in SSE2, so we keep the C-version:
+  DST(0, 2) = AVG3(J, I, X);
+  DST(0, 3) = AVG3(K, J, I);
+}
+
+static void VL4(uint8_t* dst) {   // Vertical-Left
+  const __m128i one = _mm_set1_epi8(1);
+  const __m128i ABCDEFGH = _mm_loadl_epi64((__m128i*)(dst - BPS));
+  const __m128i BCDEFGH_ = _mm_srli_si128(ABCDEFGH, 1);
+  const __m128i CDEFGH__ = _mm_srli_si128(ABCDEFGH, 2);
+  const __m128i avg1 = _mm_avg_epu8(ABCDEFGH, BCDEFGH_);
+  const __m128i avg2 = _mm_avg_epu8(CDEFGH__, BCDEFGH_);
+  const __m128i avg3 = _mm_avg_epu8(avg1, avg2);
+  const __m128i lsb1 = _mm_and_si128(_mm_xor_si128(avg1, avg2), one);
+  const __m128i ab = _mm_xor_si128(ABCDEFGH, BCDEFGH_);
+  const __m128i bc = _mm_xor_si128(CDEFGH__, BCDEFGH_);
+  const __m128i abbc = _mm_or_si128(ab, bc);
+  const __m128i lsb2 = _mm_and_si128(abbc, lsb1);
+  const __m128i avg4 = _mm_subs_epu8(avg3, lsb2);
+  const uint32_t extra_out = _mm_cvtsi128_si32(_mm_srli_si128(avg4, 4));
+  *(uint32_t*)(dst + 0 * BPS) = _mm_cvtsi128_si32(               avg1    );
+  *(uint32_t*)(dst + 1 * BPS) = _mm_cvtsi128_si32(               avg4    );
+  *(uint32_t*)(dst + 2 * BPS) = _mm_cvtsi128_si32(_mm_srli_si128(avg1, 1));
+  *(uint32_t*)(dst + 3 * BPS) = _mm_cvtsi128_si32(_mm_srli_si128(avg4, 1));
+
+  // these two are hard to get and irregular
+  DST(3, 2) = (extra_out >> 0) & 0xff;
+  DST(3, 3) = (extra_out >> 8) & 0xff;
+}
+
+static void RD4(uint8_t* dst) {   // Down-right
+  const __m128i one = _mm_set1_epi8(1);
+  const __m128i XABCD = _mm_loadl_epi64((__m128i*)(dst - BPS - 1));
+  const __m128i ____XABCD = _mm_slli_si128(XABCD, 4);
+  const uint32_t I = dst[-1 + 0 * BPS];
+  const uint32_t J = dst[-1 + 1 * BPS];
+  const uint32_t K = dst[-1 + 2 * BPS];
+  const uint32_t L = dst[-1 + 3 * BPS];
+  const __m128i LKJI_____ =
+      _mm_cvtsi32_si128(L | (K << 8) | (J << 16) | (I << 24));
+  const __m128i LKJIXABCD = _mm_or_si128(LKJI_____, ____XABCD);
+  const __m128i KJIXABCD_ = _mm_srli_si128(LKJIXABCD, 1);
+  const __m128i JIXABCD__ = _mm_srli_si128(LKJIXABCD, 2);
+  const __m128i avg1 = _mm_avg_epu8(JIXABCD__, LKJIXABCD);
+  const __m128i lsb = _mm_and_si128(_mm_xor_si128(JIXABCD__, LKJIXABCD), one);
+  const __m128i avg2 = _mm_subs_epu8(avg1, lsb);
+  const __m128i abcdefg = _mm_avg_epu8(avg2, KJIXABCD_);
+  *(uint32_t*)(dst + 3 * BPS) = _mm_cvtsi128_si32(               abcdefg    );
+  *(uint32_t*)(dst + 2 * BPS) = _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1));
+  *(uint32_t*)(dst + 1 * BPS) = _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2));
+  *(uint32_t*)(dst + 0 * BPS) = _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3));
+}
+
+#undef DST
+#undef AVG3
+
+//------------------------------------------------------------------------------
+// Luma 16x16
+
+static WEBP_INLINE void TrueMotion(uint8_t* dst, int size) {
+  const uint8_t* top = dst - BPS;
+  const __m128i zero = _mm_setzero_si128();
+  int y;
+  if (size == 4) {
+    const __m128i top_values = _mm_cvtsi32_si128(*(const int*)top);
+    const __m128i top_base = _mm_unpacklo_epi8(top_values, zero);
+    for (y = 0; y < 4; ++y, dst += BPS) {
+      const int val = dst[-1] - top[-1];
+      const __m128i base = _mm_set1_epi16(val);
+      const __m128i out = _mm_packus_epi16(_mm_add_epi16(base, top_base), zero);
+      *(int*)dst = _mm_cvtsi128_si32(out);
+    }
+  } else if (size == 8) {
+    const __m128i top_values = _mm_loadl_epi64((const __m128i*)top);
+    const __m128i top_base = _mm_unpacklo_epi8(top_values, zero);
+    for (y = 0; y < 8; ++y, dst += BPS) {
+      const int val = dst[-1] - top[-1];
+      const __m128i base = _mm_set1_epi16(val);
+      const __m128i out = _mm_packus_epi16(_mm_add_epi16(base, top_base), zero);
+      _mm_storel_epi64((__m128i*)dst, out);
+    }
+  } else {
+    const __m128i top_values = _mm_loadu_si128((const __m128i*)top);
+    const __m128i top_base_0 = _mm_unpacklo_epi8(top_values, zero);
+    const __m128i top_base_1 = _mm_unpackhi_epi8(top_values, zero);
+    for (y = 0; y < 16; ++y, dst += BPS) {
+      const int val = dst[-1] - top[-1];
+      const __m128i base = _mm_set1_epi16(val);
+      const __m128i out_0 = _mm_add_epi16(base, top_base_0);
+      const __m128i out_1 = _mm_add_epi16(base, top_base_1);
+      const __m128i out = _mm_packus_epi16(out_0, out_1);
+      _mm_storeu_si128((__m128i*)dst, out);
+    }
+  }
+}
+
+static void TM4(uint8_t* dst)   { TrueMotion(dst, 4); }
+static void TM8uv(uint8_t* dst) { TrueMotion(dst, 8); }
+static void TM16(uint8_t* dst)  { TrueMotion(dst, 16); }
+
+static void VE16(uint8_t* dst) {
+  const __m128i top = _mm_loadu_si128((const __m128i*)(dst - BPS));
+  int j;
+  for (j = 0; j < 16; ++j) {
+    _mm_storeu_si128((__m128i*)(dst + j * BPS), top);
+  }
+}
+
+static void HE16(uint8_t* dst) {     // horizontal
+  int j;
+  for (j = 16; j > 0; --j) {
+    const __m128i values = _mm_set1_epi8(dst[-1]);
+    _mm_storeu_si128((__m128i*)dst, values);
+    dst += BPS;
+  }
+}
+
+static WEBP_INLINE void Put16(uint8_t v, uint8_t* dst) {
+  int j;
+  const __m128i values = _mm_set1_epi8(v);
+  for (j = 0; j < 16; ++j) {
+    _mm_storeu_si128((__m128i*)(dst + j * BPS), values);
+  }
+}
+
+static void DC16(uint8_t* dst) {    // DC
+  int DC = 16;
+  int j;
+  for (j = 0; j < 16; ++j) {
+    DC += dst[-1 + j * BPS] + dst[j - BPS];
+  }
+  Put16(DC >> 5, dst);
+}
+
+static void DC16NoTop(uint8_t* dst) {   // DC with top samples not available
+  int DC = 8;
+  int j;
+  for (j = 0; j < 16; ++j) {
+    DC += dst[-1 + j * BPS];
+  }
+  Put16(DC >> 4, dst);
+}
+
+static void DC16NoLeft(uint8_t* dst) {  // DC with left samples not available
+  int DC = 8;
+  int i;
+  for (i = 0; i < 16; ++i) {
+    DC += dst[i - BPS];
+  }
+  Put16(DC >> 4, dst);
+}
+
+static void DC16NoTopLeft(uint8_t* dst) {  // DC with no top and left samples
+  Put16(0x80, dst);
+}
+
+//------------------------------------------------------------------------------
+// Chroma
+
+static void VE8uv(uint8_t* dst) {    // vertical
+  int j;
+  const __m128i top = _mm_loadl_epi64((const __m128i*)(dst - BPS));
+  for (j = 0; j < 8; ++j) {
+    _mm_storel_epi64((__m128i*)(dst + j * BPS), top);
+  }
+}
+
+static void HE8uv(uint8_t* dst) {    // horizontal
+  int j;
+  for (j = 0; j < 8; ++j) {
+    const __m128i values = _mm_set1_epi8(dst[-1]);
+    _mm_storel_epi64((__m128i*)dst, values);
+    dst += BPS;
+  }
+}
+
+// helper for chroma-DC predictions
+static WEBP_INLINE void Put8x8uv(uint8_t v, uint8_t* dst) {
+  int j;
+  const __m128i values = _mm_set1_epi8(v);
+  for (j = 0; j < 8; ++j) {
+    _mm_storel_epi64((__m128i*)(dst + j * BPS), values);
+  }
+}
+
+static void DC8uv(uint8_t* dst) {     // DC
+  int dc0 = 8;
+  int i;
+  for (i = 0; i < 8; ++i) {
+    dc0 += dst[i - BPS] + dst[-1 + i * BPS];
+  }
+  Put8x8uv(dc0 >> 4, dst);
+}
+
+static void DC8uvNoLeft(uint8_t* dst) {   // DC with no left samples
+  int dc0 = 4;
+  int i;
+  for (i = 0; i < 8; ++i) {
+    dc0 += dst[i - BPS];
+  }
+  Put8x8uv(dc0 >> 3, dst);
+}
+
+static void DC8uvNoTop(uint8_t* dst) {  // DC with no top samples
+  int dc0 = 4;
+  int i;
+  for (i = 0; i < 8; ++i) {
+    dc0 += dst[-1 + i * BPS];
+  }
+  Put8x8uv(dc0 >> 3, dst);
+}
+
+static void DC8uvNoTopLeft(uint8_t* dst) {    // DC with nothing
+  Put8x8uv(0x80, dst);
+}
+
+#endif   // WEBP_USE_SSE2
+
+//------------------------------------------------------------------------------
+// Entry point
+
+extern void VP8DspInitSSE2(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8DspInitSSE2(void) {
+#if defined(WEBP_USE_SSE2)
+  VP8Transform = Transform;
+#if defined(USE_TRANSFORM_AC3)
+  VP8TransformAC3 = TransformAC3;
+#endif
+
+  VP8VFilter16 = VFilter16;
+  VP8HFilter16 = HFilter16;
+  VP8VFilter8 = VFilter8;
+  VP8HFilter8 = HFilter8;
+  VP8VFilter16i = VFilter16i;
+  VP8HFilter16i = HFilter16i;
+  VP8VFilter8i = VFilter8i;
+  VP8HFilter8i = HFilter8i;
+
+  VP8SimpleVFilter16 = SimpleVFilter16;
+  VP8SimpleHFilter16 = SimpleHFilter16;
+  VP8SimpleVFilter16i = SimpleVFilter16i;
+  VP8SimpleHFilter16i = SimpleHFilter16i;
+
+  VP8PredLuma4[1] = TM4;
+  VP8PredLuma4[2] = VE4;
+  VP8PredLuma4[4] = RD4;
+  VP8PredLuma4[5] = VR4;
+  VP8PredLuma4[6] = LD4;
+  VP8PredLuma4[7] = VL4;
+
+  VP8PredLuma16[0] = DC16;
+  VP8PredLuma16[1] = TM16;
+  VP8PredLuma16[2] = VE16;
+  VP8PredLuma16[3] = HE16;
+  VP8PredLuma16[4] = DC16NoTop;
+  VP8PredLuma16[5] = DC16NoLeft;
+  VP8PredLuma16[6] = DC16NoTopLeft;
+
+  VP8PredChroma8[0] = DC8uv;
+  VP8PredChroma8[1] = TM8uv;
+  VP8PredChroma8[2] = VE8uv;
+  VP8PredChroma8[3] = HE8uv;
+  VP8PredChroma8[4] = DC8uvNoTop;
+  VP8PredChroma8[5] = DC8uvNoLeft;
+  VP8PredChroma8[6] = DC8uvNoTopLeft;
+
+#endif   // WEBP_USE_SSE2
+}
diff --git a/Source/LibWebP/src/dsp/dsp.enc.c b/Source/LibWebP/src/dsp/dsp.enc.c
new file mode 100644
index 0000000..4c22d98
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.enc.c
@@ -0,0 +1,788 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Speed-critical encoding functions.
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include <assert.h>
+#include <stdlib.h>  // for abs()
+
+#include "./dsp.h"
+#include "../enc/vp8enci.h"
+
+static WEBP_INLINE uint8_t clip_8b(int v) {
+  return (!(v & ~0xff)) ? v : (v < 0) ? 0 : 255;
+}
+
+static WEBP_INLINE int clip_max(int v, int max) {
+  return (v > max) ? max : v;
+}
+
+//------------------------------------------------------------------------------
+// Compute susceptibility based on DCT-coeff histograms:
+// the higher, the "easier" the macroblock is to compress.
+
+const int VP8DspScan[16 + 4 + 4] = {
+  // Luma
+  0 +  0 * BPS,  4 +  0 * BPS, 8 +  0 * BPS, 12 +  0 * BPS,
+  0 +  4 * BPS,  4 +  4 * BPS, 8 +  4 * BPS, 12 +  4 * BPS,
+  0 +  8 * BPS,  4 +  8 * BPS, 8 +  8 * BPS, 12 +  8 * BPS,
+  0 + 12 * BPS,  4 + 12 * BPS, 8 + 12 * BPS, 12 + 12 * BPS,
+
+  0 + 0 * BPS,   4 + 0 * BPS, 0 + 4 * BPS,  4 + 4 * BPS,    // U
+  8 + 0 * BPS,  12 + 0 * BPS, 8 + 4 * BPS, 12 + 4 * BPS     // V
+};
+
+// general-purpose util function
+void VP8LSetHistogramData(const int distribution[MAX_COEFF_THRESH + 1],
+                          VP8Histogram* const histo) {
+  int max_value = 0, last_non_zero = 1;
+  int k;
+  for (k = 0; k <= MAX_COEFF_THRESH; ++k) {
+    const int value = distribution[k];
+    if (value > 0) {
+      if (value > max_value) max_value = value;
+      last_non_zero = k;
+    }
+  }
+  histo->max_value = max_value;
+  histo->last_non_zero = last_non_zero;
+}
+
+static void CollectHistogram(const uint8_t* ref, const uint8_t* pred,
+                             int start_block, int end_block,
+                             VP8Histogram* const histo) {
+  int j;
+  int distribution[MAX_COEFF_THRESH + 1] = { 0 };
+  for (j = start_block; j < end_block; ++j) {
+    int k;
+    int16_t out[16];
+
+    VP8FTransform(ref + VP8DspScan[j], pred + VP8DspScan[j], out);
+
+    // Convert coefficients to bin.
+    for (k = 0; k < 16; ++k) {
+      const int v = abs(out[k]) >> 3;  // TODO(skal): add rounding?
+      const int clipped_value = clip_max(v, MAX_COEFF_THRESH);
+      ++distribution[clipped_value];
+    }
+  }
+  VP8LSetHistogramData(distribution, histo);
+}
+
+//------------------------------------------------------------------------------
+// run-time tables (~4k)
+
+static uint8_t clip1[255 + 510 + 1];    // clips [-255,510] to [0,255]
+
+// We declare this variable 'volatile' to prevent instruction reordering
+// and make sure it's set to true _last_ (so as to be thread-safe)
+static volatile int tables_ok = 0;
+
+static WEBP_TSAN_IGNORE_FUNCTION void InitTables(void) {
+  if (!tables_ok) {
+    int i;
+    for (i = -255; i <= 255 + 255; ++i) {
+      clip1[255 + i] = clip_8b(i);
+    }
+    tables_ok = 1;
+  }
+}
+
+
+//------------------------------------------------------------------------------
+// Transforms (Paragraph 14.4)
+
+#define STORE(x, y, v) \
+  dst[(x) + (y) * BPS] = clip_8b(ref[(x) + (y) * BPS] + ((v) >> 3))
+
+static const int kC1 = 20091 + (1 << 16);
+static const int kC2 = 35468;
+#define MUL(a, b) (((a) * (b)) >> 16)
+
+static WEBP_INLINE void ITransformOne(const uint8_t* ref, const int16_t* in,
+                                      uint8_t* dst) {
+  int C[4 * 4], *tmp;
+  int i;
+  tmp = C;
+  for (i = 0; i < 4; ++i) {    // vertical pass
+    const int a = in[0] + in[8];
+    const int b = in[0] - in[8];
+    const int c = MUL(in[4], kC2) - MUL(in[12], kC1);
+    const int d = MUL(in[4], kC1) + MUL(in[12], kC2);
+    tmp[0] = a + d;
+    tmp[1] = b + c;
+    tmp[2] = b - c;
+    tmp[3] = a - d;
+    tmp += 4;
+    in++;
+  }
+
+  tmp = C;
+  for (i = 0; i < 4; ++i) {    // horizontal pass
+    const int dc = tmp[0] + 4;
+    const int a =  dc +  tmp[8];
+    const int b =  dc -  tmp[8];
+    const int c = MUL(tmp[4], kC2) - MUL(tmp[12], kC1);
+    const int d = MUL(tmp[4], kC1) + MUL(tmp[12], kC2);
+    STORE(0, i, a + d);
+    STORE(1, i, b + c);
+    STORE(2, i, b - c);
+    STORE(3, i, a - d);
+    tmp++;
+  }
+}
+
+static void ITransform(const uint8_t* ref, const int16_t* in, uint8_t* dst,
+                       int do_two) {
+  ITransformOne(ref, in, dst);
+  if (do_two) {
+    ITransformOne(ref + 4, in + 16, dst + 4);
+  }
+}
+
+static void FTransform(const uint8_t* src, const uint8_t* ref, int16_t* out) {
+  int i;
+  int tmp[16];
+  for (i = 0; i < 4; ++i, src += BPS, ref += BPS) {
+    const int d0 = src[0] - ref[0];   // 9bit dynamic range ([-255,255])
+    const int d1 = src[1] - ref[1];
+    const int d2 = src[2] - ref[2];
+    const int d3 = src[3] - ref[3];
+    const int a0 = (d0 + d3);         // 10b                      [-510,510]
+    const int a1 = (d1 + d2);
+    const int a2 = (d1 - d2);
+    const int a3 = (d0 - d3);
+    tmp[0 + i * 4] = (a0 + a1) * 8;   // 14b                      [-8160,8160]
+    tmp[1 + i * 4] = (a2 * 2217 + a3 * 5352 + 1812) >> 9;      // [-7536,7542]
+    tmp[2 + i * 4] = (a0 - a1) * 8;
+    tmp[3 + i * 4] = (a3 * 2217 - a2 * 5352 +  937) >> 9;
+  }
+  for (i = 0; i < 4; ++i) {
+    const int a0 = (tmp[0 + i] + tmp[12 + i]);  // 15b
+    const int a1 = (tmp[4 + i] + tmp[ 8 + i]);
+    const int a2 = (tmp[4 + i] - tmp[ 8 + i]);
+    const int a3 = (tmp[0 + i] - tmp[12 + i]);
+    out[0 + i] = (a0 + a1 + 7) >> 4;            // 12b
+    out[4 + i] = ((a2 * 2217 + a3 * 5352 + 12000) >> 16) + (a3 != 0);
+    out[8 + i] = (a0 - a1 + 7) >> 4;
+    out[12+ i] = ((a3 * 2217 - a2 * 5352 + 51000) >> 16);
+  }
+}
+
+static void FTransformWHT(const int16_t* in, int16_t* out) {
+  // input is 12b signed
+  int32_t tmp[16];
+  int i;
+  for (i = 0; i < 4; ++i, in += 64) {
+    const int a0 = (in[0 * 16] + in[2 * 16]);  // 13b
+    const int a1 = (in[1 * 16] + in[3 * 16]);
+    const int a2 = (in[1 * 16] - in[3 * 16]);
+    const int a3 = (in[0 * 16] - in[2 * 16]);
+    tmp[0 + i * 4] = a0 + a1;   // 14b
+    tmp[1 + i * 4] = a3 + a2;
+    tmp[2 + i * 4] = a3 - a2;
+    tmp[3 + i * 4] = a0 - a1;
+  }
+  for (i = 0; i < 4; ++i) {
+    const int a0 = (tmp[0 + i] + tmp[8 + i]);  // 15b
+    const int a1 = (tmp[4 + i] + tmp[12+ i]);
+    const int a2 = (tmp[4 + i] - tmp[12+ i]);
+    const int a3 = (tmp[0 + i] - tmp[8 + i]);
+    const int b0 = a0 + a1;    // 16b
+    const int b1 = a3 + a2;
+    const int b2 = a3 - a2;
+    const int b3 = a0 - a1;
+    out[ 0 + i] = b0 >> 1;     // 15b
+    out[ 4 + i] = b1 >> 1;
+    out[ 8 + i] = b2 >> 1;
+    out[12 + i] = b3 >> 1;
+  }
+}
+
+#undef MUL
+#undef STORE
+
+//------------------------------------------------------------------------------
+// Intra predictions
+
+#define DST(x, y) dst[(x) + (y) * BPS]
+
+static WEBP_INLINE void Fill(uint8_t* dst, int value, int size) {
+  int j;
+  for (j = 0; j < size; ++j) {
+    memset(dst + j * BPS, value, size);
+  }
+}
+
+static WEBP_INLINE void VerticalPred(uint8_t* dst,
+                                     const uint8_t* top, int size) {
+  int j;
+  if (top != NULL) {
+    for (j = 0; j < size; ++j) memcpy(dst + j * BPS, top, size);
+  } else {
+    Fill(dst, 127, size);
+  }
+}
+
+static WEBP_INLINE void HorizontalPred(uint8_t* dst,
+                                       const uint8_t* left, int size) {
+  if (left != NULL) {
+    int j;
+    for (j = 0; j < size; ++j) {
+      memset(dst + j * BPS, left[j], size);
+    }
+  } else {
+    Fill(dst, 129, size);
+  }
+}
+
+static WEBP_INLINE void TrueMotion(uint8_t* dst, const uint8_t* left,
+                                   const uint8_t* top, int size) {
+  int y;
+  if (left != NULL) {
+    if (top != NULL) {
+      const uint8_t* const clip = clip1 + 255 - left[-1];
+      for (y = 0; y < size; ++y) {
+        const uint8_t* const clip_table = clip + left[y];
+        int x;
+        for (x = 0; x < size; ++x) {
+          dst[x] = clip_table[top[x]];
+        }
+        dst += BPS;
+      }
+    } else {
+      HorizontalPred(dst, left, size);
+    }
+  } else {
+    // true motion without left samples (hence: with default 129 value)
+    // is equivalent to VE prediction where you just copy the top samples.
+    // Note that if top samples are not available, the default value is
+    // then 129, and not 127 as in the VerticalPred case.
+    if (top != NULL) {
+      VerticalPred(dst, top, size);
+    } else {
+      Fill(dst, 129, size);
+    }
+  }
+}
+
+static WEBP_INLINE void DCMode(uint8_t* dst, const uint8_t* left,
+                               const uint8_t* top,
+                               int size, int round, int shift) {
+  int DC = 0;
+  int j;
+  if (top != NULL) {
+    for (j = 0; j < size; ++j) DC += top[j];
+    if (left != NULL) {   // top and left present
+      for (j = 0; j < size; ++j) DC += left[j];
+    } else {      // top, but no left
+      DC += DC;
+    }
+    DC = (DC + round) >> shift;
+  } else if (left != NULL) {   // left but no top
+    for (j = 0; j < size; ++j) DC += left[j];
+    DC += DC;
+    DC = (DC + round) >> shift;
+  } else {   // no top, no left, nothing.
+    DC = 0x80;
+  }
+  Fill(dst, DC, size);
+}
+
+//------------------------------------------------------------------------------
+// Chroma 8x8 prediction (paragraph 12.2)
+
+static void IntraChromaPreds(uint8_t* dst, const uint8_t* left,
+                             const uint8_t* top) {
+  // U block
+  DCMode(C8DC8 + dst, left, top, 8, 8, 4);
+  VerticalPred(C8VE8 + dst, top, 8);
+  HorizontalPred(C8HE8 + dst, left, 8);
+  TrueMotion(C8TM8 + dst, left, top, 8);
+  // V block
+  dst += 8;
+  if (top != NULL) top += 8;
+  if (left != NULL) left += 16;
+  DCMode(C8DC8 + dst, left, top, 8, 8, 4);
+  VerticalPred(C8VE8 + dst, top, 8);
+  HorizontalPred(C8HE8 + dst, left, 8);
+  TrueMotion(C8TM8 + dst, left, top, 8);
+}
+
+//------------------------------------------------------------------------------
+// luma 16x16 prediction (paragraph 12.3)
+
+static void Intra16Preds(uint8_t* dst,
+                         const uint8_t* left, const uint8_t* top) {
+  DCMode(I16DC16 + dst, left, top, 16, 16, 5);
+  VerticalPred(I16VE16 + dst, top, 16);
+  HorizontalPred(I16HE16 + dst, left, 16);
+  TrueMotion(I16TM16 + dst, left, top, 16);
+}
+
+//------------------------------------------------------------------------------
+// luma 4x4 prediction
+
+#define AVG3(a, b, c) (((a) + 2 * (b) + (c) + 2) >> 2)
+#define AVG2(a, b) (((a) + (b) + 1) >> 1)
+
+static void VE4(uint8_t* dst, const uint8_t* top) {    // vertical
+  const uint8_t vals[4] = {
+    AVG3(top[-1], top[0], top[1]),
+    AVG3(top[ 0], top[1], top[2]),
+    AVG3(top[ 1], top[2], top[3]),
+    AVG3(top[ 2], top[3], top[4])
+  };
+  int i;
+  for (i = 0; i < 4; ++i) {
+    memcpy(dst + i * BPS, vals, 4);
+  }
+}
+
+static void HE4(uint8_t* dst, const uint8_t* top) {    // horizontal
+  const int X = top[-1];
+  const int I = top[-2];
+  const int J = top[-3];
+  const int K = top[-4];
+  const int L = top[-5];
+  *(uint32_t*)(dst + 0 * BPS) = 0x01010101U * AVG3(X, I, J);
+  *(uint32_t*)(dst + 1 * BPS) = 0x01010101U * AVG3(I, J, K);
+  *(uint32_t*)(dst + 2 * BPS) = 0x01010101U * AVG3(J, K, L);
+  *(uint32_t*)(dst + 3 * BPS) = 0x01010101U * AVG3(K, L, L);
+}
+
+static void DC4(uint8_t* dst, const uint8_t* top) {
+  uint32_t dc = 4;
+  int i;
+  for (i = 0; i < 4; ++i) dc += top[i] + top[-5 + i];
+  Fill(dst, dc >> 3, 4);
+}
+
+static void RD4(uint8_t* dst, const uint8_t* top) {
+  const int X = top[-1];
+  const int I = top[-2];
+  const int J = top[-3];
+  const int K = top[-4];
+  const int L = top[-5];
+  const int A = top[0];
+  const int B = top[1];
+  const int C = top[2];
+  const int D = top[3];
+  DST(0, 3)                                     = AVG3(J, K, L);
+  DST(0, 2) = DST(1, 3)                         = AVG3(I, J, K);
+  DST(0, 1) = DST(1, 2) = DST(2, 3)             = AVG3(X, I, J);
+  DST(0, 0) = DST(1, 1) = DST(2, 2) = DST(3, 3) = AVG3(A, X, I);
+  DST(1, 0) = DST(2, 1) = DST(3, 2)             = AVG3(B, A, X);
+  DST(2, 0) = DST(3, 1)                         = AVG3(C, B, A);
+  DST(3, 0)                                     = AVG3(D, C, B);
+}
+
+static void LD4(uint8_t* dst, const uint8_t* top) {
+  const int A = top[0];
+  const int B = top[1];
+  const int C = top[2];
+  const int D = top[3];
+  const int E = top[4];
+  const int F = top[5];
+  const int G = top[6];
+  const int H = top[7];
+  DST(0, 0)                                     = AVG3(A, B, C);
+  DST(1, 0) = DST(0, 1)                         = AVG3(B, C, D);
+  DST(2, 0) = DST(1, 1) = DST(0, 2)             = AVG3(C, D, E);
+  DST(3, 0) = DST(2, 1) = DST(1, 2) = DST(0, 3) = AVG3(D, E, F);
+  DST(3, 1) = DST(2, 2) = DST(1, 3)             = AVG3(E, F, G);
+  DST(3, 2) = DST(2, 3)                         = AVG3(F, G, H);
+  DST(3, 3)                                     = AVG3(G, H, H);
+}
+
+static void VR4(uint8_t* dst, const uint8_t* top) {
+  const int X = top[-1];
+  const int I = top[-2];
+  const int J = top[-3];
+  const int K = top[-4];
+  const int A = top[0];
+  const int B = top[1];
+  const int C = top[2];
+  const int D = top[3];
+  DST(0, 0) = DST(1, 2) = AVG2(X, A);
+  DST(1, 0) = DST(2, 2) = AVG2(A, B);
+  DST(2, 0) = DST(3, 2) = AVG2(B, C);
+  DST(3, 0)             = AVG2(C, D);
+
+  DST(0, 3) =             AVG3(K, J, I);
+  DST(0, 2) =             AVG3(J, I, X);
+  DST(0, 1) = DST(1, 3) = AVG3(I, X, A);
+  DST(1, 1) = DST(2, 3) = AVG3(X, A, B);
+  DST(2, 1) = DST(3, 3) = AVG3(A, B, C);
+  DST(3, 1) =             AVG3(B, C, D);
+}
+
+static void VL4(uint8_t* dst, const uint8_t* top) {
+  const int A = top[0];
+  const int B = top[1];
+  const int C = top[2];
+  const int D = top[3];
+  const int E = top[4];
+  const int F = top[5];
+  const int G = top[6];
+  const int H = top[7];
+  DST(0, 0) =             AVG2(A, B);
+  DST(1, 0) = DST(0, 2) = AVG2(B, C);
+  DST(2, 0) = DST(1, 2) = AVG2(C, D);
+  DST(3, 0) = DST(2, 2) = AVG2(D, E);
+
+  DST(0, 1) =             AVG3(A, B, C);
+  DST(1, 1) = DST(0, 3) = AVG3(B, C, D);
+  DST(2, 1) = DST(1, 3) = AVG3(C, D, E);
+  DST(3, 1) = DST(2, 3) = AVG3(D, E, F);
+              DST(3, 2) = AVG3(E, F, G);
+              DST(3, 3) = AVG3(F, G, H);
+}
+
+static void HU4(uint8_t* dst, const uint8_t* top) {
+  const int I = top[-2];
+  const int J = top[-3];
+  const int K = top[-4];
+  const int L = top[-5];
+  DST(0, 0) =             AVG2(I, J);
+  DST(2, 0) = DST(0, 1) = AVG2(J, K);
+  DST(2, 1) = DST(0, 2) = AVG2(K, L);
+  DST(1, 0) =             AVG3(I, J, K);
+  DST(3, 0) = DST(1, 1) = AVG3(J, K, L);
+  DST(3, 1) = DST(1, 2) = AVG3(K, L, L);
+  DST(3, 2) = DST(2, 2) =
+  DST(0, 3) = DST(1, 3) = DST(2, 3) = DST(3, 3) = L;
+}
+
+static void HD4(uint8_t* dst, const uint8_t* top) {
+  const int X = top[-1];
+  const int I = top[-2];
+  const int J = top[-3];
+  const int K = top[-4];
+  const int L = top[-5];
+  const int A = top[0];
+  const int B = top[1];
+  const int C = top[2];
+
+  DST(0, 0) = DST(2, 1) = AVG2(I, X);
+  DST(0, 1) = DST(2, 2) = AVG2(J, I);
+  DST(0, 2) = DST(2, 3) = AVG2(K, J);
+  DST(0, 3)             = AVG2(L, K);
+
+  DST(3, 0)             = AVG3(A, B, C);
+  DST(2, 0)             = AVG3(X, A, B);
+  DST(1, 0) = DST(3, 1) = AVG3(I, X, A);
+  DST(1, 1) = DST(3, 2) = AVG3(J, I, X);
+  DST(1, 2) = DST(3, 3) = AVG3(K, J, I);
+  DST(1, 3)             = AVG3(L, K, J);
+}
+
+static void TM4(uint8_t* dst, const uint8_t* top) {
+  int x, y;
+  const uint8_t* const clip = clip1 + 255 - top[-1];
+  for (y = 0; y < 4; ++y) {
+    const uint8_t* const clip_table = clip + top[-2 - y];
+    for (x = 0; x < 4; ++x) {
+      dst[x] = clip_table[top[x]];
+    }
+    dst += BPS;
+  }
+}
+
+#undef DST
+#undef AVG3
+#undef AVG2
+
+// Left samples are top[-5 .. -2], top_left is top[-1], top are
+// located at top[0..3], and top right is top[4..7]
+static void Intra4Preds(uint8_t* dst, const uint8_t* top) {
+  DC4(I4DC4 + dst, top);
+  TM4(I4TM4 + dst, top);
+  VE4(I4VE4 + dst, top);
+  HE4(I4HE4 + dst, top);
+  RD4(I4RD4 + dst, top);
+  VR4(I4VR4 + dst, top);
+  LD4(I4LD4 + dst, top);
+  VL4(I4VL4 + dst, top);
+  HD4(I4HD4 + dst, top);
+  HU4(I4HU4 + dst, top);
+}
+
+//------------------------------------------------------------------------------
+// Metric
+
+static WEBP_INLINE int GetSSE(const uint8_t* a, const uint8_t* b,
+                              int w, int h) {
+  int count = 0;
+  int y, x;
+  for (y = 0; y < h; ++y) {
+    for (x = 0; x < w; ++x) {
+      const int diff = (int)a[x] - b[x];
+      count += diff * diff;
+    }
+    a += BPS;
+    b += BPS;
+  }
+  return count;
+}
+
+static int SSE16x16(const uint8_t* a, const uint8_t* b) {
+  return GetSSE(a, b, 16, 16);
+}
+static int SSE16x8(const uint8_t* a, const uint8_t* b) {
+  return GetSSE(a, b, 16, 8);
+}
+static int SSE8x8(const uint8_t* a, const uint8_t* b) {
+  return GetSSE(a, b, 8, 8);
+}
+static int SSE4x4(const uint8_t* a, const uint8_t* b) {
+  return GetSSE(a, b, 4, 4);
+}
+
+//------------------------------------------------------------------------------
+// Texture distortion
+//
+// We try to match the spectral content (weighted) between source and
+// reconstructed samples.
+
+// Hadamard transform
+// Returns the weighted sum of the absolute value of transformed coefficients.
+static int TTransform(const uint8_t* in, const uint16_t* w) {
+  int sum = 0;
+  int tmp[16];
+  int i;
+  // horizontal pass
+  for (i = 0; i < 4; ++i, in += BPS) {
+    const int a0 = in[0] + in[2];
+    const int a1 = in[1] + in[3];
+    const int a2 = in[1] - in[3];
+    const int a3 = in[0] - in[2];
+    tmp[0 + i * 4] = a0 + a1;
+    tmp[1 + i * 4] = a3 + a2;
+    tmp[2 + i * 4] = a3 - a2;
+    tmp[3 + i * 4] = a0 - a1;
+  }
+  // vertical pass
+  for (i = 0; i < 4; ++i, ++w) {
+    const int a0 = tmp[0 + i] + tmp[8 + i];
+    const int a1 = tmp[4 + i] + tmp[12+ i];
+    const int a2 = tmp[4 + i] - tmp[12+ i];
+    const int a3 = tmp[0 + i] - tmp[8 + i];
+    const int b0 = a0 + a1;
+    const int b1 = a3 + a2;
+    const int b2 = a3 - a2;
+    const int b3 = a0 - a1;
+
+    sum += w[ 0] * abs(b0);
+    sum += w[ 4] * abs(b1);
+    sum += w[ 8] * abs(b2);
+    sum += w[12] * abs(b3);
+  }
+  return sum;
+}
+
+static int Disto4x4(const uint8_t* const a, const uint8_t* const b,
+                    const uint16_t* const w) {
+  const int sum1 = TTransform(a, w);
+  const int sum2 = TTransform(b, w);
+  return abs(sum2 - sum1) >> 5;
+}
+
+static int Disto16x16(const uint8_t* const a, const uint8_t* const b,
+                      const uint16_t* const w) {
+  int D = 0;
+  int x, y;
+  for (y = 0; y < 16 * BPS; y += 4 * BPS) {
+    for (x = 0; x < 16; x += 4) {
+      D += Disto4x4(a + x + y, b + x + y, w);
+    }
+  }
+  return D;
+}
+
+//------------------------------------------------------------------------------
+// Quantization
+//
+
+static const uint8_t kZigzag[16] = {
+  0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15
+};
+
+// Simple quantization
+static int QuantizeBlock(int16_t in[16], int16_t out[16],
+                         const VP8Matrix* const mtx) {
+  int last = -1;
+  int n;
+  for (n = 0; n < 16; ++n) {
+    const int j = kZigzag[n];
+    const int sign = (in[j] < 0);
+    const uint32_t coeff = (sign ? -in[j] : in[j]) + mtx->sharpen_[j];
+    if (coeff > mtx->zthresh_[j]) {
+      const uint32_t Q = mtx->q_[j];
+      const uint32_t iQ = mtx->iq_[j];
+      const uint32_t B = mtx->bias_[j];
+      int level = QUANTDIV(coeff, iQ, B);
+      if (level > MAX_LEVEL) level = MAX_LEVEL;
+      if (sign) level = -level;
+      in[j] = level * Q;
+      out[n] = level;
+      if (level) last = n;
+    } else {
+      out[n] = 0;
+      in[j] = 0;
+    }
+  }
+  return (last >= 0);
+}
+
+static int Quantize2Blocks(int16_t in[32], int16_t out[32],
+                           const VP8Matrix* const mtx) {
+  int nz;
+  nz  = VP8EncQuantizeBlock(in + 0 * 16, out + 0 * 16, mtx) << 0;
+  nz |= VP8EncQuantizeBlock(in + 1 * 16, out + 1 * 16, mtx) << 1;
+  return nz;
+}
+
+static int QuantizeBlockWHT(int16_t in[16], int16_t out[16],
+                            const VP8Matrix* const mtx) {
+  int n, last = -1;
+  for (n = 0; n < 16; ++n) {
+    const int j = kZigzag[n];
+    const int sign = (in[j] < 0);
+    const uint32_t coeff = sign ? -in[j] : in[j];
+    assert(mtx->sharpen_[j] == 0);
+    if (coeff > mtx->zthresh_[j]) {
+      const uint32_t Q = mtx->q_[j];
+      const uint32_t iQ = mtx->iq_[j];
+      const uint32_t B = mtx->bias_[j];
+      int level = QUANTDIV(coeff, iQ, B);
+      if (level > MAX_LEVEL) level = MAX_LEVEL;
+      if (sign) level = -level;
+      in[j] = level * Q;
+      out[n] = level;
+      if (level) last = n;
+    } else {
+      out[n] = 0;
+      in[j] = 0;
+    }
+  }
+  return (last >= 0);
+}
+
+//------------------------------------------------------------------------------
+// Block copy
+
+static WEBP_INLINE void Copy(const uint8_t* src, uint8_t* dst, int w, int h) {
+  int y;
+  for (y = 0; y < h; ++y) {
+    memcpy(dst, src, w);
+    src += BPS;
+    dst += BPS;
+  }
+}
+
+static void Copy4x4(const uint8_t* src, uint8_t* dst) {
+  Copy(src, dst, 4, 4);
+}
+
+static void Copy16x8(const uint8_t* src, uint8_t* dst) {
+  Copy(src, dst, 16, 8);
+}
+
+//------------------------------------------------------------------------------
+// Initialization
+
+// Speed-critical function pointers. We have to initialize them to the default
+// implementations within VP8EncDspInit().
+VP8CHisto VP8CollectHistogram;
+VP8Idct VP8ITransform;
+VP8Fdct VP8FTransform;
+VP8WHT VP8FTransformWHT;
+VP8Intra4Preds VP8EncPredLuma4;
+VP8IntraPreds VP8EncPredLuma16;
+VP8IntraPreds VP8EncPredChroma8;
+VP8Metric VP8SSE16x16;
+VP8Metric VP8SSE8x8;
+VP8Metric VP8SSE16x8;
+VP8Metric VP8SSE4x4;
+VP8WMetric VP8TDisto4x4;
+VP8WMetric VP8TDisto16x16;
+VP8QuantizeBlock VP8EncQuantizeBlock;
+VP8Quantize2Blocks VP8EncQuantize2Blocks;
+VP8QuantizeBlockWHT VP8EncQuantizeBlockWHT;
+VP8BlockCopy VP8Copy4x4;
+VP8BlockCopy VP8Copy16x8;
+
+extern void VP8EncDspInitSSE2(void);
+extern void VP8EncDspInitAVX2(void);
+extern void VP8EncDspInitNEON(void);
+extern void VP8EncDspInitMIPS32(void);
+extern void VP8EncDspInitMIPSdspR2(void);
+
+static volatile VP8CPUInfo enc_last_cpuinfo_used =
+    (VP8CPUInfo)&enc_last_cpuinfo_used;
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspInit(void) {
+  if (enc_last_cpuinfo_used == VP8GetCPUInfo) return;
+
+  VP8DspInit();  // common inverse transforms
+  InitTables();
+
+  // default C implementations
+  VP8CollectHistogram = CollectHistogram;
+  VP8ITransform = ITransform;
+  VP8FTransform = FTransform;
+  VP8FTransformWHT = FTransformWHT;
+  VP8EncPredLuma4 = Intra4Preds;
+  VP8EncPredLuma16 = Intra16Preds;
+  VP8EncPredChroma8 = IntraChromaPreds;
+  VP8SSE16x16 = SSE16x16;
+  VP8SSE8x8 = SSE8x8;
+  VP8SSE16x8 = SSE16x8;
+  VP8SSE4x4 = SSE4x4;
+  VP8TDisto4x4 = Disto4x4;
+  VP8TDisto16x16 = Disto16x16;
+  VP8EncQuantizeBlock = QuantizeBlock;
+  VP8EncQuantize2Blocks = Quantize2Blocks;
+  VP8EncQuantizeBlockWHT = QuantizeBlockWHT;
+  VP8Copy4x4 = Copy4x4;
+  VP8Copy16x8 = Copy16x8;
+
+  // If defined, use CPUInfo() to overwrite some pointers with faster versions.
+  if (VP8GetCPUInfo != NULL) {
+#if defined(WEBP_USE_SSE2)
+    if (VP8GetCPUInfo(kSSE2)) {
+      VP8EncDspInitSSE2();
+    }
+#endif
+#if defined(WEBP_USE_AVX2)
+    if (VP8GetCPUInfo(kAVX2)) {
+      VP8EncDspInitAVX2();
+    }
+#endif
+#if defined(WEBP_USE_NEON)
+    if (VP8GetCPUInfo(kNEON)) {
+      VP8EncDspInitNEON();
+    }
+#endif
+#if defined(WEBP_USE_MIPS32)
+    if (VP8GetCPUInfo(kMIPS32)) {
+      VP8EncDspInitMIPS32();
+    }
+#endif
+#if defined(WEBP_USE_MIPS_DSP_R2)
+    if (VP8GetCPUInfo(kMIPSdspR2)) {
+      VP8EncDspInitMIPSdspR2();
+    }
+#endif
+  }
+  enc_last_cpuinfo_used = VP8GetCPUInfo;
+}
diff --git a/Source/LibWebP/src/dsp/dsp.enc_avx2.c b/Source/LibWebP/src/dsp/dsp.enc_avx2.c
new file mode 100644
index 0000000..07d08fa
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.enc_avx2.c
@@ -0,0 +1,24 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// AVX2 version of speed-critical encoding functions.
+
+#include "./dsp.h"
+
+#if defined(WEBP_USE_AVX2)
+
+#endif  // WEBP_USE_AVX2
+
+//------------------------------------------------------------------------------
+// Entry point
+
+extern void VP8EncDspInitAVX2(void);
+
+void VP8EncDspInitAVX2(void) {
+}
diff --git a/Source/LibWebP/src/dsp/dsp.enc_mips32.c b/Source/LibWebP/src/dsp/dsp.enc_mips32.c
new file mode 100644
index 0000000..545aa3a
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.enc_mips32.c
@@ -0,0 +1,670 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// MIPS version of speed-critical encoding functions.
+//
+// Author(s): Djordje Pesut    (djordje.pesut at imgtec.com)
+//            Jovan Zelincevic (jovan.zelincevic at imgtec.com)
+//            Slobodan Prijic  (slobodan.prijic at imgtec.com)
+
+#include "./dsp.h"
+
+#if defined(WEBP_USE_MIPS32)
+
+#include "./mips_macro.h"
+#include "../enc/vp8enci.h"
+#include "../enc/cost.h"
+
+static const int kC1 = 20091 + (1 << 16);
+static const int kC2 = 35468;
+
+// macro for one vertical pass in ITransformOne
+// MUL macro inlined
+// temp0..temp15 holds tmp[0]..tmp[15]
+// A..D - offsets in bytes to load from in buffer
+// TEMP0..TEMP3 - registers for corresponding tmp elements
+// TEMP4..TEMP5 - temporary registers
+#define VERTICAL_PASS(A, B, C, D, TEMP4, TEMP0, TEMP1, TEMP2, TEMP3)        \
+  "lh      %[temp16],      "#A"(%[temp20])                 \n\t"            \
+  "lh      %[temp18],      "#B"(%[temp20])                 \n\t"            \
+  "lh      %[temp17],      "#C"(%[temp20])                 \n\t"            \
+  "lh      %[temp19],      "#D"(%[temp20])                 \n\t"            \
+  "addu    %["#TEMP4"],    %[temp16],      %[temp18]       \n\t"            \
+  "subu    %[temp16],      %[temp16],      %[temp18]       \n\t"            \
+  "mul     %["#TEMP0"],    %[temp17],      %[kC2]          \n\t"            \
+  "mul     %[temp18],      %[temp19],      %[kC1]          \n\t"            \
+  "mul     %[temp17],      %[temp17],      %[kC1]          \n\t"            \
+  "mul     %[temp19],      %[temp19],      %[kC2]          \n\t"            \
+  "sra     %["#TEMP0"],    %["#TEMP0"],    16              \n\n"            \
+  "sra     %[temp18],      %[temp18],      16              \n\n"            \
+  "sra     %[temp17],      %[temp17],      16              \n\n"            \
+  "sra     %[temp19],      %[temp19],      16              \n\n"            \
+  "subu    %["#TEMP2"],    %["#TEMP0"],    %[temp18]       \n\t"            \
+  "addu    %["#TEMP3"],    %[temp17],      %[temp19]       \n\t"            \
+  "addu    %["#TEMP0"],    %["#TEMP4"],    %["#TEMP3"]     \n\t"            \
+  "addu    %["#TEMP1"],    %[temp16],      %["#TEMP2"]     \n\t"            \
+  "subu    %["#TEMP2"],    %[temp16],      %["#TEMP2"]     \n\t"            \
+  "subu    %["#TEMP3"],    %["#TEMP4"],    %["#TEMP3"]     \n\t"
+
+// macro for one horizontal pass in ITransformOne
+// MUL and STORE macros inlined
+// a = clip_8b(a) is replaced with: a = max(a, 0); a = min(a, 255)
+// temp0..temp15 holds tmp[0]..tmp[15]
+// A - offset in bytes to load from ref and store to dst buffer
+// TEMP0, TEMP4, TEMP8 and TEMP12 - registers for corresponding tmp elements
+#define HORIZONTAL_PASS(A, TEMP0, TEMP4, TEMP8, TEMP12)                     \
+  "addiu   %["#TEMP0"],    %["#TEMP0"],    4               \n\t"            \
+  "addu    %[temp16],      %["#TEMP0"],    %["#TEMP8"]     \n\t"            \
+  "subu    %[temp17],      %["#TEMP0"],    %["#TEMP8"]     \n\t"            \
+  "mul     %["#TEMP0"],    %["#TEMP4"],    %[kC2]          \n\t"            \
+  "mul     %["#TEMP8"],    %["#TEMP12"],   %[kC1]          \n\t"            \
+  "mul     %["#TEMP4"],    %["#TEMP4"],    %[kC1]          \n\t"            \
+  "mul     %["#TEMP12"],   %["#TEMP12"],   %[kC2]          \n\t"            \
+  "sra     %["#TEMP0"],    %["#TEMP0"],    16              \n\t"            \
+  "sra     %["#TEMP8"],    %["#TEMP8"],    16              \n\t"            \
+  "sra     %["#TEMP4"],    %["#TEMP4"],    16              \n\t"            \
+  "sra     %["#TEMP12"],   %["#TEMP12"],   16              \n\t"            \
+  "subu    %[temp18],      %["#TEMP0"],    %["#TEMP8"]     \n\t"            \
+  "addu    %[temp19],      %["#TEMP4"],    %["#TEMP12"]    \n\t"            \
+  "addu    %["#TEMP0"],    %[temp16],      %[temp19]       \n\t"            \
+  "addu    %["#TEMP4"],    %[temp17],      %[temp18]       \n\t"            \
+  "subu    %["#TEMP8"],    %[temp17],      %[temp18]       \n\t"            \
+  "subu    %["#TEMP12"],   %[temp16],      %[temp19]       \n\t"            \
+  "lw      %[temp20],      0(%[args])                      \n\t"            \
+  "sra     %["#TEMP0"],    %["#TEMP0"],    3               \n\t"            \
+  "sra     %["#TEMP4"],    %["#TEMP4"],    3               \n\t"            \
+  "sra     %["#TEMP8"],    %["#TEMP8"],    3               \n\t"            \
+  "sra     %["#TEMP12"],   %["#TEMP12"],   3               \n\t"            \
+  "lbu     %[temp16],      0+"XSTR(BPS)"*"#A"(%[temp20])   \n\t"            \
+  "lbu     %[temp17],      1+"XSTR(BPS)"*"#A"(%[temp20])   \n\t"            \
+  "lbu     %[temp18],      2+"XSTR(BPS)"*"#A"(%[temp20])   \n\t"            \
+  "lbu     %[temp19],      3+"XSTR(BPS)"*"#A"(%[temp20])   \n\t"            \
+  "addu    %["#TEMP0"],    %[temp16],      %["#TEMP0"]     \n\t"            \
+  "addu    %["#TEMP4"],    %[temp17],      %["#TEMP4"]     \n\t"            \
+  "addu    %["#TEMP8"],    %[temp18],      %["#TEMP8"]     \n\t"            \
+  "addu    %["#TEMP12"],   %[temp19],      %["#TEMP12"]    \n\t"            \
+  "slt     %[temp16],      %["#TEMP0"],    $zero           \n\t"            \
+  "slt     %[temp17],      %["#TEMP4"],    $zero           \n\t"            \
+  "slt     %[temp18],      %["#TEMP8"],    $zero           \n\t"            \
+  "slt     %[temp19],      %["#TEMP12"],   $zero           \n\t"            \
+  "movn    %["#TEMP0"],    $zero,          %[temp16]       \n\t"            \
+  "movn    %["#TEMP4"],    $zero,          %[temp17]       \n\t"            \
+  "movn    %["#TEMP8"],    $zero,          %[temp18]       \n\t"            \
+  "movn    %["#TEMP12"],   $zero,          %[temp19]       \n\t"            \
+  "addiu   %[temp20],      $zero,          255             \n\t"            \
+  "slt     %[temp16],      %["#TEMP0"],    %[temp20]       \n\t"            \
+  "slt     %[temp17],      %["#TEMP4"],    %[temp20]       \n\t"            \
+  "slt     %[temp18],      %["#TEMP8"],    %[temp20]       \n\t"            \
+  "slt     %[temp19],      %["#TEMP12"],   %[temp20]       \n\t"            \
+  "movz    %["#TEMP0"],    %[temp20],      %[temp16]       \n\t"            \
+  "movz    %["#TEMP4"],    %[temp20],      %[temp17]       \n\t"            \
+  "lw      %[temp16],      8(%[args])                      \n\t"            \
+  "movz    %["#TEMP8"],    %[temp20],      %[temp18]       \n\t"            \
+  "movz    %["#TEMP12"],   %[temp20],      %[temp19]       \n\t"            \
+  "sb      %["#TEMP0"],    0+"XSTR(BPS)"*"#A"(%[temp16])   \n\t"            \
+  "sb      %["#TEMP4"],    1+"XSTR(BPS)"*"#A"(%[temp16])   \n\t"            \
+  "sb      %["#TEMP8"],    2+"XSTR(BPS)"*"#A"(%[temp16])   \n\t"            \
+  "sb      %["#TEMP12"],   3+"XSTR(BPS)"*"#A"(%[temp16])   \n\t"
+
+// Does one or two inverse transforms.
+static WEBP_INLINE void ITransformOne(const uint8_t* ref, const int16_t* in,
+                                      uint8_t* dst) {
+  int temp0, temp1, temp2, temp3, temp4, temp5, temp6;
+  int temp7, temp8, temp9, temp10, temp11, temp12, temp13;
+  int temp14, temp15, temp16, temp17, temp18, temp19, temp20;
+  const int* args[3] = {(const int*)ref, (const int*)in, (const int*)dst};
+
+  __asm__ volatile(
+    "lw      %[temp20],      4(%[args])                      \n\t"
+    VERTICAL_PASS(0, 16,  8, 24, temp4,  temp0,  temp1,  temp2,  temp3)
+    VERTICAL_PASS(2, 18, 10, 26, temp8,  temp4,  temp5,  temp6,  temp7)
+    VERTICAL_PASS(4, 20, 12, 28, temp12, temp8,  temp9,  temp10, temp11)
+    VERTICAL_PASS(6, 22, 14, 30, temp20, temp12, temp13, temp14, temp15)
+
+    HORIZONTAL_PASS(0, temp0, temp4, temp8,  temp12)
+    HORIZONTAL_PASS(1, temp1, temp5, temp9,  temp13)
+    HORIZONTAL_PASS(2, temp2, temp6, temp10, temp14)
+    HORIZONTAL_PASS(3, temp3, temp7, temp11, temp15)
+
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+      [temp6]"=&r"(temp6), [temp7]"=&r"(temp7), [temp8]"=&r"(temp8),
+      [temp9]"=&r"(temp9), [temp10]"=&r"(temp10), [temp11]"=&r"(temp11),
+      [temp12]"=&r"(temp12), [temp13]"=&r"(temp13), [temp14]"=&r"(temp14),
+      [temp15]"=&r"(temp15), [temp16]"=&r"(temp16), [temp17]"=&r"(temp17),
+      [temp18]"=&r"(temp18), [temp19]"=&r"(temp19), [temp20]"=&r"(temp20)
+    : [args]"r"(args), [kC1]"r"(kC1), [kC2]"r"(kC2)
+    : "memory", "hi", "lo"
+  );
+}
+
+static void ITransform(const uint8_t* ref, const int16_t* in,
+                       uint8_t* dst, int do_two) {
+  ITransformOne(ref, in, dst);
+  if (do_two) {
+    ITransformOne(ref + 4, in + 16, dst + 4);
+  }
+}
+
+#undef VERTICAL_PASS
+#undef HORIZONTAL_PASS
+
+// macro for one pass through for loop in QuantizeBlock
+// QUANTDIV macro inlined
+// J - offset in bytes (kZigzag[n] * 2)
+// K - offset in bytes (kZigzag[n] * 4)
+// N - offset in bytes (n * 2)
+#define QUANTIZE_ONE(J, K, N)                                               \
+  "lh           %[temp0],       "#J"(%[ppin])                       \n\t"   \
+  "lhu          %[temp1],       "#J"(%[ppsharpen])                  \n\t"   \
+  "lw           %[temp2],       "#K"(%[ppzthresh])                  \n\t"   \
+  "sra          %[sign],        %[temp0],           15              \n\t"   \
+  "xor          %[coeff],       %[temp0],           %[sign]         \n\t"   \
+  "subu         %[coeff],       %[coeff],           %[sign]         \n\t"   \
+  "addu         %[coeff],       %[coeff],           %[temp1]        \n\t"   \
+  "slt          %[temp4],       %[temp2],           %[coeff]        \n\t"   \
+  "addiu        %[temp5],       $zero,              0               \n\t"   \
+  "addiu        %[level],       $zero,              0               \n\t"   \
+  "beqz         %[temp4],       2f                                  \n\t"   \
+  "lhu          %[temp1],       "#J"(%[ppiq])                       \n\t"   \
+  "lw           %[temp2],       "#K"(%[ppbias])                     \n\t"   \
+  "lhu          %[temp3],       "#J"(%[ppq])                        \n\t"   \
+  "mul          %[level],       %[coeff],           %[temp1]        \n\t"   \
+  "addu         %[level],       %[level],           %[temp2]        \n\t"   \
+  "sra          %[level],       %[level],           17              \n\t"   \
+  "slt          %[temp4],       %[max_level],       %[level]        \n\t"   \
+  "movn         %[level],       %[max_level],       %[temp4]        \n\t"   \
+  "xor          %[level],       %[level],           %[sign]         \n\t"   \
+  "subu         %[level],       %[level],           %[sign]         \n\t"   \
+  "mul          %[temp5],       %[level],           %[temp3]        \n\t"   \
+"2:                                                                 \n\t"   \
+  "sh           %[temp5],       "#J"(%[ppin])                       \n\t"   \
+  "sh           %[level],       "#N"(%[pout])                       \n\t"
+
+static int QuantizeBlock(int16_t in[16], int16_t out[16],
+                         const VP8Matrix* const mtx) {
+  int temp0, temp1, temp2, temp3, temp4, temp5;
+  int sign, coeff, level, i;
+  int max_level = MAX_LEVEL;
+
+  int16_t* ppin             = &in[0];
+  int16_t* pout             = &out[0];
+  const uint16_t* ppsharpen = &mtx->sharpen_[0];
+  const uint32_t* ppzthresh = &mtx->zthresh_[0];
+  const uint16_t* ppq       = &mtx->q_[0];
+  const uint16_t* ppiq      = &mtx->iq_[0];
+  const uint32_t* ppbias    = &mtx->bias_[0];
+
+  __asm__ volatile(
+    QUANTIZE_ONE( 0,  0,  0)
+    QUANTIZE_ONE( 2,  4,  2)
+    QUANTIZE_ONE( 8, 16,  4)
+    QUANTIZE_ONE(16, 32,  6)
+    QUANTIZE_ONE(10, 20,  8)
+    QUANTIZE_ONE( 4,  8, 10)
+    QUANTIZE_ONE( 6, 12, 12)
+    QUANTIZE_ONE(12, 24, 14)
+    QUANTIZE_ONE(18, 36, 16)
+    QUANTIZE_ONE(24, 48, 18)
+    QUANTIZE_ONE(26, 52, 20)
+    QUANTIZE_ONE(20, 40, 22)
+    QUANTIZE_ONE(14, 28, 24)
+    QUANTIZE_ONE(22, 44, 26)
+    QUANTIZE_ONE(28, 56, 28)
+    QUANTIZE_ONE(30, 60, 30)
+
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),
+      [temp2]"=&r"(temp2), [temp3]"=&r"(temp3),
+      [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+      [sign]"=&r"(sign), [coeff]"=&r"(coeff),
+      [level]"=&r"(level)
+    : [pout]"r"(pout), [ppin]"r"(ppin),
+      [ppiq]"r"(ppiq), [max_level]"r"(max_level),
+      [ppbias]"r"(ppbias), [ppzthresh]"r"(ppzthresh),
+      [ppsharpen]"r"(ppsharpen), [ppq]"r"(ppq)
+    : "memory", "hi", "lo"
+  );
+
+  // moved out from macro to increase possibility for earlier breaking
+  for (i = 15; i >= 0; i--) {
+    if (out[i]) return 1;
+  }
+  return 0;
+}
+
+static int Quantize2Blocks(int16_t in[32], int16_t out[32],
+                           const VP8Matrix* const mtx) {
+  int nz;
+  nz  = QuantizeBlock(in + 0 * 16, out + 0 * 16, mtx) << 0;
+  nz |= QuantizeBlock(in + 1 * 16, out + 1 * 16, mtx) << 1;
+  return nz;
+}
+
+#undef QUANTIZE_ONE
+
+// macro for one horizontal pass in Disto4x4 (TTransform)
+// two calls of function TTransform are merged into single one
+// A - offset in bytes to load from a and b buffers
+// E..H - offsets in bytes to store first results to tmp buffer
+// E1..H1 - offsets in bytes to store second results to tmp buffer
+#define HORIZONTAL_PASS(A, E, F, G, H, E1, F1, G1, H1)              \
+  "lbu    %[temp0],  0+"XSTR(BPS)"*"#A"(%[a])  \n\t"                \
+  "lbu    %[temp1],  1+"XSTR(BPS)"*"#A"(%[a])  \n\t"                \
+  "lbu    %[temp2],  2+"XSTR(BPS)"*"#A"(%[a])  \n\t"                \
+  "lbu    %[temp3],  3+"XSTR(BPS)"*"#A"(%[a])  \n\t"                \
+  "lbu    %[temp4],  0+"XSTR(BPS)"*"#A"(%[b])  \n\t"                \
+  "lbu    %[temp5],  1+"XSTR(BPS)"*"#A"(%[b])  \n\t"                \
+  "lbu    %[temp6],  2+"XSTR(BPS)"*"#A"(%[b])  \n\t"                \
+  "lbu    %[temp7],  3+"XSTR(BPS)"*"#A"(%[b])  \n\t"                \
+  "addu   %[temp8],  %[temp0],    %[temp2]     \n\t"                \
+  "subu   %[temp0],  %[temp0],    %[temp2]     \n\t"                \
+  "addu   %[temp2],  %[temp1],    %[temp3]     \n\t"                \
+  "subu   %[temp1],  %[temp1],    %[temp3]     \n\t"                \
+  "addu   %[temp3],  %[temp4],    %[temp6]     \n\t"                \
+  "subu   %[temp4],  %[temp4],    %[temp6]     \n\t"                \
+  "addu   %[temp6],  %[temp5],    %[temp7]     \n\t"                \
+  "subu   %[temp5],  %[temp5],    %[temp7]     \n\t"                \
+  "addu   %[temp7],  %[temp8],    %[temp2]     \n\t"                \
+  "subu   %[temp2],  %[temp8],    %[temp2]     \n\t"                \
+  "addu   %[temp8],  %[temp0],    %[temp1]     \n\t"                \
+  "subu   %[temp0],  %[temp0],    %[temp1]     \n\t"                \
+  "addu   %[temp1],  %[temp3],    %[temp6]     \n\t"                \
+  "subu   %[temp3],  %[temp3],    %[temp6]     \n\t"                \
+  "addu   %[temp6],  %[temp4],    %[temp5]     \n\t"                \
+  "subu   %[temp4],  %[temp4],    %[temp5]     \n\t"                \
+  "sw     %[temp7],  "#E"(%[tmp])              \n\t"                \
+  "sw     %[temp2],  "#H"(%[tmp])              \n\t"                \
+  "sw     %[temp8],  "#F"(%[tmp])              \n\t"                \
+  "sw     %[temp0],  "#G"(%[tmp])              \n\t"                \
+  "sw     %[temp1],  "#E1"(%[tmp])             \n\t"                \
+  "sw     %[temp3],  "#H1"(%[tmp])             \n\t"                \
+  "sw     %[temp6],  "#F1"(%[tmp])             \n\t"                \
+  "sw     %[temp4],  "#G1"(%[tmp])             \n\t"
+
+// macro for one vertical pass in Disto4x4 (TTransform)
+// two calls of function TTransform are merged into single one
+// since only one accu is available in mips32r1 instruction set
+//   first is done second call of function TTransform and after
+//   that first one.
+//   const int sum1 = TTransform(a, w);
+//   const int sum2 = TTransform(b, w);
+//   return abs(sum2 - sum1) >> 5;
+//   (sum2 - sum1) is calculated with madds (sub2) and msubs (sub1)
+// A..D - offsets in bytes to load first results from tmp buffer
+// A1..D1 - offsets in bytes to load second results from tmp buffer
+// E..H - offsets in bytes to load from w buffer
+#define VERTICAL_PASS(A, B, C, D, A1, B1, C1, D1, E, F, G, H)     \
+  "lw     %[temp0],  "#A1"(%[tmp])           \n\t"                \
+  "lw     %[temp1],  "#C1"(%[tmp])           \n\t"                \
+  "lw     %[temp2],  "#B1"(%[tmp])           \n\t"                \
+  "lw     %[temp3],  "#D1"(%[tmp])           \n\t"                \
+  "addu   %[temp8],  %[temp0],    %[temp1]   \n\t"                \
+  "subu   %[temp0],  %[temp0],    %[temp1]   \n\t"                \
+  "addu   %[temp1],  %[temp2],    %[temp3]   \n\t"                \
+  "subu   %[temp2],  %[temp2],    %[temp3]   \n\t"                \
+  "addu   %[temp3],  %[temp8],    %[temp1]   \n\t"                \
+  "subu   %[temp8],  %[temp8],    %[temp1]   \n\t"                \
+  "addu   %[temp1],  %[temp0],    %[temp2]   \n\t"                \
+  "subu   %[temp0],  %[temp0],    %[temp2]   \n\t"                \
+  "sra    %[temp4],  %[temp3],    31         \n\t"                \
+  "sra    %[temp5],  %[temp1],    31         \n\t"                \
+  "sra    %[temp6],  %[temp0],    31         \n\t"                \
+  "sra    %[temp7],  %[temp8],    31         \n\t"                \
+  "xor    %[temp3],  %[temp3],    %[temp4]   \n\t"                \
+  "xor    %[temp1],  %[temp1],    %[temp5]   \n\t"                \
+  "xor    %[temp0],  %[temp0],    %[temp6]   \n\t"                \
+  "xor    %[temp8],  %[temp8],    %[temp7]   \n\t"                \
+  "subu   %[temp3],  %[temp3],    %[temp4]   \n\t"                \
+  "subu   %[temp1],  %[temp1],    %[temp5]   \n\t"                \
+  "subu   %[temp0],  %[temp0],    %[temp6]   \n\t"                \
+  "subu   %[temp8],  %[temp8],    %[temp7]   \n\t"                \
+  "lhu    %[temp4],  "#E"(%[w])              \n\t"                \
+  "lhu    %[temp5],  "#F"(%[w])              \n\t"                \
+  "lhu    %[temp6],  "#G"(%[w])              \n\t"                \
+  "lhu    %[temp7],  "#H"(%[w])              \n\t"                \
+  "madd   %[temp4],  %[temp3]                \n\t"                \
+  "madd   %[temp5],  %[temp1]                \n\t"                \
+  "madd   %[temp6],  %[temp0]                \n\t"                \
+  "madd   %[temp7],  %[temp8]                \n\t"                \
+  "lw     %[temp0],  "#A"(%[tmp])            \n\t"                \
+  "lw     %[temp1],  "#C"(%[tmp])            \n\t"                \
+  "lw     %[temp2],  "#B"(%[tmp])            \n\t"                \
+  "lw     %[temp3],  "#D"(%[tmp])            \n\t"                \
+  "addu   %[temp8],  %[temp0],    %[temp1]   \n\t"                \
+  "subu   %[temp0],  %[temp0],    %[temp1]   \n\t"                \
+  "addu   %[temp1],  %[temp2],    %[temp3]   \n\t"                \
+  "subu   %[temp2],  %[temp2],    %[temp3]   \n\t"                \
+  "addu   %[temp3],  %[temp8],    %[temp1]   \n\t"                \
+  "subu   %[temp1],  %[temp8],    %[temp1]   \n\t"                \
+  "addu   %[temp8],  %[temp0],    %[temp2]   \n\t"                \
+  "subu   %[temp0],  %[temp0],    %[temp2]   \n\t"                \
+  "sra    %[temp2],  %[temp3],    31         \n\t"                \
+  "xor    %[temp3],  %[temp3],    %[temp2]   \n\t"                \
+  "subu   %[temp3],  %[temp3],    %[temp2]   \n\t"                \
+  "msub   %[temp4],  %[temp3]                \n\t"                \
+  "sra    %[temp2],  %[temp8],    31         \n\t"                \
+  "sra    %[temp3],  %[temp0],    31         \n\t"                \
+  "sra    %[temp4],  %[temp1],    31         \n\t"                \
+  "xor    %[temp8],  %[temp8],    %[temp2]   \n\t"                \
+  "xor    %[temp0],  %[temp0],    %[temp3]   \n\t"                \
+  "xor    %[temp1],  %[temp1],    %[temp4]   \n\t"                \
+  "subu   %[temp8],  %[temp8],    %[temp2]   \n\t"                \
+  "subu   %[temp0],  %[temp0],    %[temp3]   \n\t"                \
+  "subu   %[temp1],  %[temp1],    %[temp4]   \n\t"                \
+  "msub   %[temp5],  %[temp8]                \n\t"                \
+  "msub   %[temp6],  %[temp0]                \n\t"                \
+  "msub   %[temp7],  %[temp1]                \n\t"
+
+static int Disto4x4(const uint8_t* const a, const uint8_t* const b,
+                    const uint16_t* const w) {
+  int tmp[32];
+  int temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8;
+
+  __asm__ volatile(
+    HORIZONTAL_PASS(0,   0,  4,  8, 12,    64,  68,  72,  76)
+    HORIZONTAL_PASS(1,  16, 20, 24, 28,    80,  84,  88,  92)
+    HORIZONTAL_PASS(2,  32, 36, 40, 44,    96, 100, 104, 108)
+    HORIZONTAL_PASS(3,  48, 52, 56, 60,   112, 116, 120, 124)
+    "mthi   $zero                             \n\t"
+    "mtlo   $zero                             \n\t"
+    VERTICAL_PASS( 0, 16, 32, 48,     64, 80,  96, 112,   0,  8, 16, 24)
+    VERTICAL_PASS( 4, 20, 36, 52,     68, 84, 100, 116,   2, 10, 18, 26)
+    VERTICAL_PASS( 8, 24, 40, 56,     72, 88, 104, 120,   4, 12, 20, 28)
+    VERTICAL_PASS(12, 28, 44, 60,     76, 92, 108, 124,   6, 14, 22, 30)
+    "mflo   %[temp0]                          \n\t"
+    "sra    %[temp1],  %[temp0],  31          \n\t"
+    "xor    %[temp0],  %[temp0],  %[temp1]    \n\t"
+    "subu   %[temp0],  %[temp0],  %[temp1]    \n\t"
+    "sra    %[temp0],  %[temp0],  5           \n\t"
+
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+      [temp6]"=&r"(temp6), [temp7]"=&r"(temp7), [temp8]"=&r"(temp8)
+    : [a]"r"(a), [b]"r"(b), [w]"r"(w), [tmp]"r"(tmp)
+    : "memory", "hi", "lo"
+  );
+
+  return temp0;
+}
+
+#undef VERTICAL_PASS
+#undef HORIZONTAL_PASS
+
+static int Disto16x16(const uint8_t* const a, const uint8_t* const b,
+                      const uint16_t* const w) {
+  int D = 0;
+  int x, y;
+  for (y = 0; y < 16 * BPS; y += 4 * BPS) {
+    for (x = 0; x < 16; x += 4) {
+      D += Disto4x4(a + x + y, b + x + y, w);
+    }
+  }
+  return D;
+}
+
+// macro for one horizontal pass in FTransform
+// temp0..temp15 holds tmp[0]..tmp[15]
+// A - offset in bytes to load from src and ref buffers
+// TEMP0..TEMP3 - registers for corresponding tmp elements
+#define HORIZONTAL_PASS(A, TEMP0, TEMP1, TEMP2, TEMP3)            \
+  "lw     %["#TEMP1"],  0(%[args])                       \n\t"    \
+  "lw     %["#TEMP2"],  4(%[args])                       \n\t"    \
+  "lbu    %[temp16],    0+"XSTR(BPS)"*"#A"(%["#TEMP1"])  \n\t"    \
+  "lbu    %[temp17],    0+"XSTR(BPS)"*"#A"(%["#TEMP2"])  \n\t"    \
+  "lbu    %[temp18],    1+"XSTR(BPS)"*"#A"(%["#TEMP1"])  \n\t"    \
+  "lbu    %[temp19],    1+"XSTR(BPS)"*"#A"(%["#TEMP2"])  \n\t"    \
+  "subu   %[temp20],    %[temp16],    %[temp17]          \n\t"    \
+  "lbu    %[temp16],    2+"XSTR(BPS)"*"#A"(%["#TEMP1"])  \n\t"    \
+  "lbu    %[temp17],    2+"XSTR(BPS)"*"#A"(%["#TEMP2"])  \n\t"    \
+  "subu   %["#TEMP0"],  %[temp18],    %[temp19]          \n\t"    \
+  "lbu    %[temp18],    3+"XSTR(BPS)"*"#A"(%["#TEMP1"])  \n\t"    \
+  "lbu    %[temp19],    3+"XSTR(BPS)"*"#A"(%["#TEMP2"])  \n\t"    \
+  "subu   %["#TEMP1"],  %[temp16],    %[temp17]          \n\t"    \
+  "subu   %["#TEMP2"],  %[temp18],    %[temp19]          \n\t"    \
+  "addu   %["#TEMP3"],  %[temp20],    %["#TEMP2"]        \n\t"    \
+  "subu   %["#TEMP2"],  %[temp20],    %["#TEMP2"]        \n\t"    \
+  "addu   %[temp20],    %["#TEMP0"],  %["#TEMP1"]        \n\t"    \
+  "subu   %["#TEMP0"],  %["#TEMP0"],  %["#TEMP1"]        \n\t"    \
+  "mul    %[temp16],    %["#TEMP2"],  %[c5352]           \n\t"    \
+  "mul    %[temp17],    %["#TEMP2"],  %[c2217]           \n\t"    \
+  "mul    %[temp18],    %["#TEMP0"],  %[c5352]           \n\t"    \
+  "mul    %[temp19],    %["#TEMP0"],  %[c2217]           \n\t"    \
+  "addu   %["#TEMP1"],  %["#TEMP3"],  %[temp20]          \n\t"    \
+  "subu   %[temp20],    %["#TEMP3"],  %[temp20]          \n\t"    \
+  "sll    %["#TEMP0"],  %["#TEMP1"],  3                  \n\t"    \
+  "sll    %["#TEMP2"],  %[temp20],    3                  \n\t"    \
+  "addiu  %[temp16],    %[temp16],    1812               \n\t"    \
+  "addiu  %[temp17],    %[temp17],    937                \n\t"    \
+  "addu   %[temp16],    %[temp16],    %[temp19]          \n\t"    \
+  "subu   %[temp17],    %[temp17],    %[temp18]          \n\t"    \
+  "sra    %["#TEMP1"],  %[temp16],    9                  \n\t"    \
+  "sra    %["#TEMP3"],  %[temp17],    9                  \n\t"
+
+// macro for one vertical pass in FTransform
+// temp0..temp15 holds tmp[0]..tmp[15]
+// A..D - offsets in bytes to store to out buffer
+// TEMP0, TEMP4, TEMP8 and TEMP12 - registers for corresponding tmp elements
+#define VERTICAL_PASS(A, B, C, D, TEMP0, TEMP4, TEMP8, TEMP12)  \
+  "addu   %[temp16],    %["#TEMP0"],  %["#TEMP12"]     \n\t"    \
+  "subu   %[temp19],    %["#TEMP0"],  %["#TEMP12"]     \n\t"    \
+  "addu   %[temp17],    %["#TEMP4"],  %["#TEMP8"]      \n\t"    \
+  "subu   %[temp18],    %["#TEMP4"],  %["#TEMP8"]      \n\t"    \
+  "mul    %["#TEMP8"],  %[temp19],    %[c2217]         \n\t"    \
+  "mul    %["#TEMP12"], %[temp18],    %[c2217]         \n\t"    \
+  "mul    %["#TEMP4"],  %[temp19],    %[c5352]         \n\t"    \
+  "mul    %[temp18],    %[temp18],    %[c5352]         \n\t"    \
+  "addiu  %[temp16],    %[temp16],    7                \n\t"    \
+  "addu   %["#TEMP0"],  %[temp16],    %[temp17]        \n\t"    \
+  "sra    %["#TEMP0"],  %["#TEMP0"],  4                \n\t"    \
+  "addu   %["#TEMP12"], %["#TEMP12"], %["#TEMP4"]      \n\t"    \
+  "subu   %["#TEMP4"],  %[temp16],    %[temp17]        \n\t"    \
+  "sra    %["#TEMP4"],  %["#TEMP4"],  4                \n\t"    \
+  "addiu  %["#TEMP8"],  %["#TEMP8"],  30000            \n\t"    \
+  "addiu  %["#TEMP12"], %["#TEMP12"], 12000            \n\t"    \
+  "addiu  %["#TEMP8"],  %["#TEMP8"],  21000            \n\t"    \
+  "subu   %["#TEMP8"],  %["#TEMP8"],  %[temp18]        \n\t"    \
+  "sra    %["#TEMP12"], %["#TEMP12"], 16               \n\t"    \
+  "sra    %["#TEMP8"],  %["#TEMP8"],  16               \n\t"    \
+  "addiu  %[temp16],    %["#TEMP12"], 1                \n\t"    \
+  "movn   %["#TEMP12"], %[temp16],    %[temp19]        \n\t"    \
+  "sh     %["#TEMP0"],  "#A"(%[temp20])                \n\t"    \
+  "sh     %["#TEMP4"],  "#C"(%[temp20])                \n\t"    \
+  "sh     %["#TEMP8"],  "#D"(%[temp20])                \n\t"    \
+  "sh     %["#TEMP12"], "#B"(%[temp20])                \n\t"
+
+static void FTransform(const uint8_t* src, const uint8_t* ref, int16_t* out) {
+  int temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8;
+  int temp9, temp10, temp11, temp12, temp13, temp14, temp15, temp16;
+  int temp17, temp18, temp19, temp20;
+  const int c2217 = 2217;
+  const int c5352 = 5352;
+  const int* const args[3] =
+      { (const int*)src, (const int*)ref, (const int*)out };
+
+  __asm__ volatile(
+    HORIZONTAL_PASS(0, temp0,  temp1,  temp2,  temp3)
+    HORIZONTAL_PASS(1, temp4,  temp5,  temp6,  temp7)
+    HORIZONTAL_PASS(2, temp8,  temp9,  temp10, temp11)
+    HORIZONTAL_PASS(3, temp12, temp13, temp14, temp15)
+    "lw   %[temp20],    8(%[args])                     \n\t"
+    VERTICAL_PASS(0,  8, 16, 24, temp0, temp4, temp8,  temp12)
+    VERTICAL_PASS(2, 10, 18, 26, temp1, temp5, temp9,  temp13)
+    VERTICAL_PASS(4, 12, 20, 28, temp2, temp6, temp10, temp14)
+    VERTICAL_PASS(6, 14, 22, 30, temp3, temp7, temp11, temp15)
+
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+      [temp6]"=&r"(temp6), [temp7]"=&r"(temp7), [temp8]"=&r"(temp8),
+      [temp9]"=&r"(temp9), [temp10]"=&r"(temp10), [temp11]"=&r"(temp11),
+      [temp12]"=&r"(temp12), [temp13]"=&r"(temp13), [temp14]"=&r"(temp14),
+      [temp15]"=&r"(temp15), [temp16]"=&r"(temp16), [temp17]"=&r"(temp17),
+      [temp18]"=&r"(temp18), [temp19]"=&r"(temp19), [temp20]"=&r"(temp20)
+    : [args]"r"(args), [c2217]"r"(c2217), [c5352]"r"(c5352)
+    : "memory", "hi", "lo"
+  );
+}
+
+#undef VERTICAL_PASS
+#undef HORIZONTAL_PASS
+
+#if !defined(WORK_AROUND_GCC)
+
+#define GET_SSE_INNER(A, B, C, D)                               \
+  "lbu     %[temp0],    "#A"(%[a])                   \n\t"      \
+  "lbu     %[temp1],    "#A"(%[b])                   \n\t"      \
+  "lbu     %[temp2],    "#B"(%[a])                   \n\t"      \
+  "lbu     %[temp3],    "#B"(%[b])                   \n\t"      \
+  "lbu     %[temp4],    "#C"(%[a])                   \n\t"      \
+  "lbu     %[temp5],    "#C"(%[b])                   \n\t"      \
+  "lbu     %[temp6],    "#D"(%[a])                   \n\t"      \
+  "lbu     %[temp7],    "#D"(%[b])                   \n\t"      \
+  "subu    %[temp0],    %[temp0],     %[temp1]       \n\t"      \
+  "subu    %[temp2],    %[temp2],     %[temp3]       \n\t"      \
+  "subu    %[temp4],    %[temp4],     %[temp5]       \n\t"      \
+  "subu    %[temp6],    %[temp6],     %[temp7]       \n\t"      \
+  "madd    %[temp0],    %[temp0]                     \n\t"      \
+  "madd    %[temp2],    %[temp2]                     \n\t"      \
+  "madd    %[temp4],    %[temp4]                     \n\t"      \
+  "madd    %[temp6],    %[temp6]                     \n\t"
+
+#define GET_SSE(A, B, C, D)               \
+  GET_SSE_INNER(A, A + 1, A + 2, A + 3)   \
+  GET_SSE_INNER(B, B + 1, B + 2, B + 3)   \
+  GET_SSE_INNER(C, C + 1, C + 2, C + 3)   \
+  GET_SSE_INNER(D, D + 1, D + 2, D + 3)
+
+static int SSE16x16(const uint8_t* a, const uint8_t* b) {
+  int count;
+  int temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
+
+  __asm__ volatile(
+     "mult   $zero,    $zero                            \n\t"
+
+     GET_SSE( 0 * BPS, 4 +  0 * BPS, 8 +  0 * BPS, 12 +  0 * BPS)
+     GET_SSE( 1 * BPS, 4 +  1 * BPS, 8 +  1 * BPS, 12 +  1 * BPS)
+     GET_SSE( 2 * BPS, 4 +  2 * BPS, 8 +  2 * BPS, 12 +  2 * BPS)
+     GET_SSE( 3 * BPS, 4 +  3 * BPS, 8 +  3 * BPS, 12 +  3 * BPS)
+     GET_SSE( 4 * BPS, 4 +  4 * BPS, 8 +  4 * BPS, 12 +  4 * BPS)
+     GET_SSE( 5 * BPS, 4 +  5 * BPS, 8 +  5 * BPS, 12 +  5 * BPS)
+     GET_SSE( 6 * BPS, 4 +  6 * BPS, 8 +  6 * BPS, 12 +  6 * BPS)
+     GET_SSE( 7 * BPS, 4 +  7 * BPS, 8 +  7 * BPS, 12 +  7 * BPS)
+     GET_SSE( 8 * BPS, 4 +  8 * BPS, 8 +  8 * BPS, 12 +  8 * BPS)
+     GET_SSE( 9 * BPS, 4 +  9 * BPS, 8 +  9 * BPS, 12 +  9 * BPS)
+     GET_SSE(10 * BPS, 4 + 10 * BPS, 8 + 10 * BPS, 12 + 10 * BPS)
+     GET_SSE(11 * BPS, 4 + 11 * BPS, 8 + 11 * BPS, 12 + 11 * BPS)
+     GET_SSE(12 * BPS, 4 + 12 * BPS, 8 + 12 * BPS, 12 + 12 * BPS)
+     GET_SSE(13 * BPS, 4 + 13 * BPS, 8 + 13 * BPS, 12 + 13 * BPS)
+     GET_SSE(14 * BPS, 4 + 14 * BPS, 8 + 14 * BPS, 12 + 14 * BPS)
+     GET_SSE(15 * BPS, 4 + 15 * BPS, 8 + 15 * BPS, 12 + 15 * BPS)
+
+    "mflo    %[count]                                   \n\t"
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+      [temp6]"=&r"(temp6), [temp7]"=&r"(temp7), [count]"=&r"(count)
+    : [a]"r"(a), [b]"r"(b)
+    : "memory", "hi", "lo"
+  );
+  return count;
+}
+
+static int SSE16x8(const uint8_t* a, const uint8_t* b) {
+  int count;
+  int temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
+
+  __asm__ volatile(
+     "mult   $zero,    $zero                            \n\t"
+
+     GET_SSE( 0 * BPS, 4 +  0 * BPS, 8 +  0 * BPS, 12 +  0 * BPS)
+     GET_SSE( 1 * BPS, 4 +  1 * BPS, 8 +  1 * BPS, 12 +  1 * BPS)
+     GET_SSE( 2 * BPS, 4 +  2 * BPS, 8 +  2 * BPS, 12 +  2 * BPS)
+     GET_SSE( 3 * BPS, 4 +  3 * BPS, 8 +  3 * BPS, 12 +  3 * BPS)
+     GET_SSE( 4 * BPS, 4 +  4 * BPS, 8 +  4 * BPS, 12 +  4 * BPS)
+     GET_SSE( 5 * BPS, 4 +  5 * BPS, 8 +  5 * BPS, 12 +  5 * BPS)
+     GET_SSE( 6 * BPS, 4 +  6 * BPS, 8 +  6 * BPS, 12 +  6 * BPS)
+     GET_SSE( 7 * BPS, 4 +  7 * BPS, 8 +  7 * BPS, 12 +  7 * BPS)
+
+    "mflo    %[count]                                   \n\t"
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+      [temp6]"=&r"(temp6), [temp7]"=&r"(temp7), [count]"=&r"(count)
+    : [a]"r"(a), [b]"r"(b)
+    : "memory", "hi", "lo"
+  );
+  return count;
+}
+
+static int SSE8x8(const uint8_t* a, const uint8_t* b) {
+  int count;
+  int temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
+
+  __asm__ volatile(
+     "mult   $zero,    $zero                            \n\t"
+
+     GET_SSE(0 * BPS, 4 + 0 * BPS, 1 * BPS, 4 + 1 * BPS)
+     GET_SSE(2 * BPS, 4 + 2 * BPS, 3 * BPS, 4 + 3 * BPS)
+     GET_SSE(4 * BPS, 4 + 4 * BPS, 5 * BPS, 4 + 5 * BPS)
+     GET_SSE(6 * BPS, 4 + 6 * BPS, 7 * BPS, 4 + 7 * BPS)
+
+    "mflo    %[count]                                   \n\t"
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+      [temp6]"=&r"(temp6), [temp7]"=&r"(temp7), [count]"=&r"(count)
+    : [a]"r"(a), [b]"r"(b)
+    : "memory", "hi", "lo"
+  );
+  return count;
+}
+
+static int SSE4x4(const uint8_t* a, const uint8_t* b) {
+  int count;
+  int temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
+
+  __asm__ volatile(
+     "mult   $zero,    $zero                            \n\t"
+
+     GET_SSE(0 * BPS, 1 * BPS, 2 * BPS, 3 * BPS)
+
+    "mflo    %[count]                                   \n\t"
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+      [temp6]"=&r"(temp6), [temp7]"=&r"(temp7), [count]"=&r"(count)
+    : [a]"r"(a), [b]"r"(b)
+    : "memory", "hi", "lo"
+  );
+  return count;
+}
+
+#undef GET_SSE
+#undef GET_SSE_INNER
+
+#endif  // !WORK_AROUND_GCC
+
+#endif  // WEBP_USE_MIPS32
+
+//------------------------------------------------------------------------------
+// Entry point
+
+extern void VP8EncDspInitMIPS32(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspInitMIPS32(void) {
+#if defined(WEBP_USE_MIPS32)
+  VP8ITransform = ITransform;
+  VP8FTransform = FTransform;
+  VP8EncQuantizeBlock = QuantizeBlock;
+  VP8EncQuantize2Blocks = Quantize2Blocks;
+  VP8TDisto4x4 = Disto4x4;
+  VP8TDisto16x16 = Disto16x16;
+#if !defined(WORK_AROUND_GCC)
+  VP8SSE16x16 = SSE16x16;
+  VP8SSE8x8 = SSE8x8;
+  VP8SSE16x8 = SSE16x8;
+  VP8SSE4x4 = SSE4x4;
+#endif
+#endif  // WEBP_USE_MIPS32
+}
diff --git a/Source/LibWebP/src/dsp/dsp.enc_mips_dsp_r2.c b/Source/LibWebP/src/dsp/dsp.enc_mips_dsp_r2.c
new file mode 100644
index 0000000..ec58efe
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.enc_mips_dsp_r2.c
@@ -0,0 +1,1510 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// MIPS version of speed-critical encoding functions.
+//
+// Author(s): Darko Laus (darko.laus at imgtec.com)
+//            Mirko Raus (mirko.raus at imgtec.com)
+
+#include "./dsp.h"
+
+#if defined(WEBP_USE_MIPS_DSP_R2)
+
+#include "./mips_macro.h"
+#include "../enc/cost.h"
+#include "../enc/vp8enci.h"
+
+static const int kC1 = 20091 + (1 << 16);
+static const int kC2 = 35468;
+
+// O - output
+// I - input (macro doesn't change it)
+#define ADD_SUB_HALVES_X4(O0, O1, O2, O3, O4, O5, O6, O7,                      \
+                          I0, I1, I2, I3, I4, I5, I6, I7)                      \
+  "addq.ph          %["#O0"],   %["#I0"],  %["#I1"]           \n\t"            \
+  "subq.ph          %["#O1"],   %["#I0"],  %["#I1"]           \n\t"            \
+  "addq.ph          %["#O2"],   %["#I2"],  %["#I3"]           \n\t"            \
+  "subq.ph          %["#O3"],   %["#I2"],  %["#I3"]           \n\t"            \
+  "addq.ph          %["#O4"],   %["#I4"],  %["#I5"]           \n\t"            \
+  "subq.ph          %["#O5"],   %["#I4"],  %["#I5"]           \n\t"            \
+  "addq.ph          %["#O6"],   %["#I6"],  %["#I7"]           \n\t"            \
+  "subq.ph          %["#O7"],   %["#I6"],  %["#I7"]           \n\t"
+
+// IO - input/output
+#define ABS_X8(IO0, IO1, IO2, IO3, IO4, IO5, IO6, IO7)                         \
+  "absq_s.ph        %["#IO0"],   %["#IO0"]                    \n\t"            \
+  "absq_s.ph        %["#IO1"],   %["#IO1"]                    \n\t"            \
+  "absq_s.ph        %["#IO2"],   %["#IO2"]                    \n\t"            \
+  "absq_s.ph        %["#IO3"],   %["#IO3"]                    \n\t"            \
+  "absq_s.ph        %["#IO4"],   %["#IO4"]                    \n\t"            \
+  "absq_s.ph        %["#IO5"],   %["#IO5"]                    \n\t"            \
+  "absq_s.ph        %["#IO6"],   %["#IO6"]                    \n\t"            \
+  "absq_s.ph        %["#IO7"],   %["#IO7"]                    \n\t"
+
+// dpa.w.ph $ac0 temp0 ,temp1
+//  $ac += temp0[31..16] * temp1[31..16] + temp0[15..0] * temp1[15..0]
+// dpax.w.ph $ac0 temp0 ,temp1
+//  $ac += temp0[31..16] * temp1[15..0] + temp0[15..0] * temp1[31..16]
+// O - output
+// I - input (macro doesn't change it)
+#define MUL_HALF(O0, I0, I1, I2, I3, I4, I5, I6, I7,                           \
+                 I8, I9, I10, I11, I12, I13, I14, I15)                         \
+    "mult            $ac0,      $zero,     $zero              \n\t"            \
+    "dpa.w.ph        $ac0,      %["#I2"],  %["#I0"]           \n\t"            \
+    "dpax.w.ph       $ac0,      %["#I5"],  %["#I6"]           \n\t"            \
+    "dpa.w.ph        $ac0,      %["#I8"],  %["#I9"]           \n\t"            \
+    "dpax.w.ph       $ac0,      %["#I11"], %["#I4"]           \n\t"            \
+    "dpa.w.ph        $ac0,      %["#I12"], %["#I7"]           \n\t"            \
+    "dpax.w.ph       $ac0,      %["#I13"], %["#I1"]           \n\t"            \
+    "dpa.w.ph        $ac0,      %["#I14"], %["#I3"]           \n\t"            \
+    "dpax.w.ph       $ac0,      %["#I15"], %["#I10"]          \n\t"            \
+    "mflo            %["#O0"],  $ac0                          \n\t"
+
+#define OUTPUT_EARLY_CLOBBER_REGS_17()                                         \
+  OUTPUT_EARLY_CLOBBER_REGS_10(),                                              \
+  [temp11]"=&r"(temp11), [temp12]"=&r"(temp12), [temp13]"=&r"(temp13),         \
+  [temp14]"=&r"(temp14), [temp15]"=&r"(temp15), [temp16]"=&r"(temp16),         \
+  [temp17]"=&r"(temp17)
+
+// macro for one horizontal pass in FTransform
+// temp0..temp15 holds tmp[0]..tmp[15]
+// A - offset in bytes to load from src and ref buffers
+// TEMP0..TEMP3 - registers for corresponding tmp elements
+#define HORIZONTAL_PASS(A, TEMP0, TEMP1, TEMP2, TEMP3)                         \
+  "lw              %["#TEMP0"],   0(%[args])                        \n\t"      \
+  "lw              %["#TEMP1"],   4(%[args])                        \n\t"      \
+  "lw              %["#TEMP2"],   "XSTR(BPS)"*"#A"(%["#TEMP0"])     \n\t"      \
+  "lw              %["#TEMP3"],   "XSTR(BPS)"*"#A"(%["#TEMP1"])     \n\t"      \
+  "preceu.ph.qbl   %["#TEMP0"],   %["#TEMP2"]                       \n\t"      \
+  "preceu.ph.qbl   %["#TEMP1"],   %["#TEMP3"]                       \n\t"      \
+  "preceu.ph.qbr   %["#TEMP2"],   %["#TEMP2"]                       \n\t"      \
+  "preceu.ph.qbr   %["#TEMP3"],   %["#TEMP3"]                       \n\t"      \
+  "subq.ph         %["#TEMP0"],   %["#TEMP0"],   %["#TEMP1"]        \n\t"      \
+  "subq.ph         %["#TEMP2"],   %["#TEMP2"],   %["#TEMP3"]        \n\t"      \
+  "rotr            %["#TEMP0"],   %["#TEMP0"],   16                 \n\t"      \
+  "addq.ph         %["#TEMP1"],   %["#TEMP2"],   %["#TEMP0"]        \n\t"      \
+  "subq.ph         %["#TEMP3"],   %["#TEMP2"],   %["#TEMP0"]        \n\t"      \
+  "seh             %["#TEMP0"],   %["#TEMP1"]                       \n\t"      \
+  "sra             %[temp16],     %["#TEMP1"],   16                 \n\t"      \
+  "seh             %[temp19],     %["#TEMP3"]                       \n\t"      \
+  "sra             %["#TEMP3"],   %["#TEMP3"],   16                 \n\t"      \
+  "subu            %["#TEMP2"],   %["#TEMP0"],   %[temp16]          \n\t"      \
+  "addu            %["#TEMP0"],   %["#TEMP0"],   %[temp16]          \n\t"      \
+  "mul             %[temp17],     %[temp19],     %[c2217]           \n\t"      \
+  "mul             %[temp18],     %["#TEMP3"],   %[c5352]           \n\t"      \
+  "mul             %["#TEMP1"],   %[temp19],     %[c5352]           \n\t"      \
+  "mul             %[temp16],     %["#TEMP3"],   %[c2217]           \n\t"      \
+  "sll             %["#TEMP2"],   %["#TEMP2"],   3                  \n\t"      \
+  "sll             %["#TEMP0"],   %["#TEMP0"],   3                  \n\t"      \
+  "subu            %["#TEMP3"],   %[temp17],     %[temp18]          \n\t"      \
+  "addu            %["#TEMP1"],   %[temp16],     %["#TEMP1"]        \n\t"      \
+  "addiu           %["#TEMP3"],   %["#TEMP3"],   937                \n\t"      \
+  "addiu           %["#TEMP1"],   %["#TEMP1"],   1812               \n\t"      \
+  "sra             %["#TEMP3"],   %["#TEMP3"],   9                  \n\t"      \
+  "sra             %["#TEMP1"],   %["#TEMP1"],   9                  \n\t"
+
+// macro for one vertical pass in FTransform
+// temp0..temp15 holds tmp[0]..tmp[15]
+// A..D - offsets in bytes to store to out buffer
+// TEMP0, TEMP4, TEMP8 and TEMP12 - registers for corresponding tmp elements
+#define VERTICAL_PASS(A, B, C, D, TEMP0, TEMP4, TEMP8, TEMP12)                 \
+  "addu            %[temp16],     %["#TEMP0"],   %["#TEMP12"] \n\t"            \
+  "subu            %[temp19],     %["#TEMP0"],   %["#TEMP12"] \n\t"            \
+  "addu            %[temp17],     %["#TEMP4"],   %["#TEMP8"]  \n\t"            \
+  "subu            %[temp18],     %["#TEMP4"],   %["#TEMP8"]  \n\t"            \
+  "mul             %["#TEMP8"],   %[temp19],     %[c2217]     \n\t"            \
+  "mul             %["#TEMP12"],  %[temp18],     %[c2217]     \n\t"            \
+  "mul             %["#TEMP4"],   %[temp19],     %[c5352]     \n\t"            \
+  "mul             %[temp18],     %[temp18],     %[c5352]     \n\t"            \
+  "addiu           %[temp16],     %[temp16],     7            \n\t"            \
+  "addu            %["#TEMP0"],   %[temp16],     %[temp17]    \n\t"            \
+  "sra             %["#TEMP0"],   %["#TEMP0"],   4            \n\t"            \
+  "addu            %["#TEMP12"],  %["#TEMP12"],  %["#TEMP4"]  \n\t"            \
+  "subu            %["#TEMP4"],   %[temp16],     %[temp17]    \n\t"            \
+  "sra             %["#TEMP4"],   %["#TEMP4"],   4            \n\t"            \
+  "addiu           %["#TEMP8"],   %["#TEMP8"],   30000        \n\t"            \
+  "addiu           %["#TEMP12"],  %["#TEMP12"],  12000        \n\t"            \
+  "addiu           %["#TEMP8"],   %["#TEMP8"],   21000        \n\t"            \
+  "subu            %["#TEMP8"],   %["#TEMP8"],   %[temp18]    \n\t"            \
+  "sra             %["#TEMP12"],  %["#TEMP12"],  16           \n\t"            \
+  "sra             %["#TEMP8"],   %["#TEMP8"],   16           \n\t"            \
+  "addiu           %[temp16],     %["#TEMP12"],  1            \n\t"            \
+  "movn            %["#TEMP12"],  %[temp16],     %[temp19]    \n\t"            \
+  "sh              %["#TEMP0"],   "#A"(%[temp20])             \n\t"            \
+  "sh              %["#TEMP4"],   "#C"(%[temp20])             \n\t"            \
+  "sh              %["#TEMP8"],   "#D"(%[temp20])             \n\t"            \
+  "sh              %["#TEMP12"],  "#B"(%[temp20])             \n\t"
+
+static void FTransform(const uint8_t* src, const uint8_t* ref, int16_t* out) {
+  const int c2217 = 2217;
+  const int c5352 = 5352;
+  int temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8;
+  int temp9, temp10, temp11, temp12, temp13, temp14, temp15, temp16;
+  int temp17, temp18, temp19, temp20;
+  const int* const args[3] =
+      { (const int*)src, (const int*)ref, (const int*)out };
+
+  __asm__ volatile (
+    HORIZONTAL_PASS(0, temp0,  temp1,  temp2,  temp3)
+    HORIZONTAL_PASS(1, temp4,  temp5,  temp6,  temp7)
+    HORIZONTAL_PASS(2, temp8,  temp9,  temp10, temp11)
+    HORIZONTAL_PASS(3, temp12, temp13, temp14, temp15)
+    "lw            %[temp20],     8(%[args])                  \n\t"
+    VERTICAL_PASS(0,  8, 16, 24, temp0, temp4, temp8,  temp12)
+    VERTICAL_PASS(2, 10, 18, 26, temp1, temp5, temp9,  temp13)
+    VERTICAL_PASS(4, 12, 20, 28, temp2, temp6, temp10, temp14)
+    VERTICAL_PASS(6, 14, 22, 30, temp3, temp7, temp11, temp15)
+    OUTPUT_EARLY_CLOBBER_REGS_18(),
+      [temp0]"=&r"(temp0), [temp19]"=&r"(temp19), [temp20]"=&r"(temp20)
+    : [args]"r"(args), [c2217]"r"(c2217), [c5352]"r"(c5352)
+    : "memory", "hi", "lo"
+  );
+}
+
+#undef VERTICAL_PASS
+#undef HORIZONTAL_PASS
+
+static WEBP_INLINE void ITransformOne(const uint8_t* ref, const int16_t* in,
+                                      uint8_t* dst) {
+  int temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8, temp9;
+  int temp10, temp11, temp12, temp13, temp14, temp15, temp16, temp17, temp18;
+
+  __asm__ volatile (
+    "ulw              %[temp1],   0(%[in])                 \n\t"
+    "ulw              %[temp2],   16(%[in])                \n\t"
+    LOAD_IN_X2(temp5, temp6, 24, 26)
+    ADD_SUB_HALVES(temp3, temp4, temp1, temp2)
+    LOAD_IN_X2(temp1, temp2, 8, 10)
+    MUL_SHIFT_SUM(temp7, temp8, temp9, temp10, temp11, temp12, temp13, temp14,
+                  temp10, temp8, temp9, temp7, temp1, temp2, temp5, temp6,
+                  temp13, temp11, temp14, temp12)
+    INSERT_HALF_X2(temp8, temp7, temp10, temp9)
+    "ulw              %[temp17],  4(%[in])                 \n\t"
+    "ulw              %[temp18],  20(%[in])                \n\t"
+    ADD_SUB_HALVES(temp1, temp2, temp3, temp8)
+    ADD_SUB_HALVES(temp5, temp6, temp4, temp7)
+    ADD_SUB_HALVES(temp7, temp8, temp17, temp18)
+    LOAD_IN_X2(temp17, temp18, 12, 14)
+    LOAD_IN_X2(temp9, temp10, 28, 30)
+    MUL_SHIFT_SUM(temp11, temp12, temp13, temp14, temp15, temp16, temp4, temp17,
+                  temp12, temp14, temp11, temp13, temp17, temp18, temp9, temp10,
+                  temp15, temp4, temp16, temp17)
+    INSERT_HALF_X2(temp11, temp12, temp13, temp14)
+    ADD_SUB_HALVES(temp17, temp8, temp8, temp11)
+    ADD_SUB_HALVES(temp3, temp4, temp7, temp12)
+
+    // horizontal
+    SRA_16(temp9, temp10, temp11, temp12, temp1, temp2, temp5, temp6)
+    INSERT_HALF_X2(temp1, temp6, temp5, temp2)
+    SRA_16(temp13, temp14, temp15, temp16, temp3, temp4, temp17, temp8)
+    "repl.ph          %[temp2],   0x4                      \n\t"
+    INSERT_HALF_X2(temp3, temp8, temp17, temp4)
+    "addq.ph          %[temp1],   %[temp1],  %[temp2]      \n\t"
+    "addq.ph          %[temp6],   %[temp6],  %[temp2]      \n\t"
+    ADD_SUB_HALVES(temp2, temp4, temp1, temp3)
+    ADD_SUB_HALVES(temp5, temp7, temp6, temp8)
+    MUL_SHIFT_SUM(temp1, temp3, temp6, temp8, temp9, temp13, temp17, temp18,
+                  temp3, temp13, temp1, temp9, temp9, temp13, temp11, temp15,
+                  temp6, temp17, temp8, temp18)
+    MUL_SHIFT_SUM(temp6, temp8, temp18, temp17, temp11, temp15, temp12, temp16,
+                  temp8, temp15, temp6, temp11, temp12, temp16, temp10, temp14,
+                  temp18, temp12, temp17, temp16)
+    INSERT_HALF_X2(temp1, temp3, temp9, temp13)
+    INSERT_HALF_X2(temp6, temp8, temp11, temp15)
+    SHIFT_R_SUM_X2(temp9, temp10, temp11, temp12, temp13, temp14, temp15,
+                   temp16, temp2, temp4, temp5, temp7, temp3, temp1, temp8,
+                   temp6)
+    PACK_2_HALVES_TO_WORD(temp1, temp2, temp3, temp4, temp9, temp12, temp13,
+                          temp16, temp11, temp10, temp15, temp14)
+    LOAD_WITH_OFFSET_X4(temp10, temp11, temp14, temp15, ref,
+                        0, 0, 0, 0,
+                        0, 1, 2, 3,
+                        BPS)
+    CONVERT_2_BYTES_TO_HALF(temp5, temp6, temp7, temp8, temp17, temp18, temp10,
+                            temp11, temp10, temp11, temp14, temp15)
+    STORE_SAT_SUM_X2(temp5, temp6, temp7, temp8, temp17, temp18, temp10, temp11,
+                     temp9, temp12, temp1, temp2, temp13, temp16, temp3, temp4,
+                     dst, 0, 1, 2, 3, BPS)
+
+    OUTPUT_EARLY_CLOBBER_REGS_18()
+    : [dst]"r"(dst), [in]"r"(in), [kC1]"r"(kC1), [kC2]"r"(kC2), [ref]"r"(ref)
+    : "memory", "hi", "lo"
+  );
+}
+
+static void ITransform(const uint8_t* ref, const int16_t* in, uint8_t* dst,
+                       int do_two) {
+  ITransformOne(ref, in, dst);
+  if (do_two) {
+    ITransformOne(ref + 4, in + 16, dst + 4);
+  }
+}
+
+static int Disto4x4(const uint8_t* const a, const uint8_t* const b,
+                    const uint16_t* const w) {
+  int temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8, temp9;
+  int temp10, temp11, temp12, temp13, temp14, temp15, temp16, temp17;
+
+  __asm__ volatile (
+    LOAD_WITH_OFFSET_X4(temp1, temp2, temp3, temp4, a,
+                        0, 0, 0, 0,
+                        0, 1, 2, 3,
+                        BPS)
+    CONVERT_2_BYTES_TO_HALF(temp5, temp6, temp7, temp8, temp9,temp10, temp11,
+                            temp12, temp1, temp2, temp3, temp4)
+    ADD_SUB_HALVES_X4(temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8,
+                      temp5, temp6, temp7, temp8, temp9, temp10, temp11, temp12)
+    PACK_2_HALVES_TO_WORD(temp9, temp10, temp11, temp12, temp1, temp3, temp5,
+                          temp7, temp2, temp4, temp6, temp8)
+    ADD_SUB_HALVES_X4(temp2, temp4, temp6, temp8, temp9, temp1, temp3, temp10,
+                      temp1, temp9, temp3, temp10, temp5, temp11, temp7, temp12)
+    ADD_SUB_HALVES_X4(temp5, temp11, temp7, temp2, temp9, temp3, temp6, temp12,
+                      temp2, temp9, temp6, temp3, temp4, temp1, temp8, temp10)
+    ADD_SUB_HALVES_X4(temp1, temp4, temp10, temp8, temp7, temp11, temp5, temp2,
+                      temp5, temp7, temp11, temp2, temp9, temp6, temp3, temp12)
+    ABS_X8(temp1, temp4, temp10, temp8, temp7, temp11, temp5, temp2)
+    LOAD_WITH_OFFSET_X4(temp3, temp6, temp9, temp12, w,
+                        0, 4, 8, 12,
+                        0, 0, 0, 0,
+                        0)
+    LOAD_WITH_OFFSET_X4(temp13, temp14, temp15, temp16, w,
+                        0, 4, 8, 12,
+                        1, 1, 1, 1,
+                        16)
+    MUL_HALF(temp17, temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8,
+             temp9, temp10, temp11, temp12, temp13, temp14, temp15, temp16)
+    LOAD_WITH_OFFSET_X4(temp1, temp2, temp3, temp4, b,
+                        0, 0, 0, 0,
+                        0, 1, 2, 3,
+                        BPS)
+    CONVERT_2_BYTES_TO_HALF(temp5,temp6, temp7, temp8, temp9,temp10, temp11,
+                            temp12, temp1, temp2, temp3, temp4)
+    ADD_SUB_HALVES_X4(temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8,
+                      temp5, temp6, temp7, temp8, temp9, temp10, temp11, temp12)
+    PACK_2_HALVES_TO_WORD(temp9, temp10, temp11, temp12, temp1, temp3, temp5,
+                          temp7, temp2, temp4, temp6, temp8)
+    ADD_SUB_HALVES_X4(temp2, temp4, temp6, temp8, temp9, temp1, temp3, temp10,
+                      temp1, temp9, temp3, temp10, temp5, temp11, temp7, temp12)
+    ADD_SUB_HALVES_X4(temp5, temp11, temp7, temp2, temp9, temp3, temp6, temp12,
+                      temp2, temp9, temp6, temp3, temp4, temp1, temp8, temp10)
+    ADD_SUB_HALVES_X4(temp1, temp4, temp10, temp8, temp7, temp11, temp5, temp2,
+                      temp5, temp7, temp11, temp2, temp9, temp6, temp3, temp12)
+    ABS_X8(temp1, temp4, temp10, temp8, temp7, temp11, temp5, temp2)
+    LOAD_WITH_OFFSET_X4(temp3, temp6, temp9, temp12, w,
+                        0, 4, 8, 12,
+                        0, 0, 0, 0,
+                        0)
+    LOAD_WITH_OFFSET_X4(temp13, temp14, temp15, temp16, w,
+                        0, 4, 8, 12,
+                        1, 1, 1, 1,
+                        16)
+    MUL_HALF(temp3, temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8,
+             temp9, temp10, temp11, temp12, temp13, temp14, temp15, temp16)
+    OUTPUT_EARLY_CLOBBER_REGS_17()
+    : [a]"r"(a), [b]"r"(b), [w]"r"(w)
+    : "memory", "hi", "lo"
+  );
+  return abs(temp3 - temp17) >> 5;
+}
+
+static int Disto16x16(const uint8_t* const a, const uint8_t* const b,
+                      const uint16_t* const w) {
+  int D = 0;
+  int x, y;
+  for (y = 0; y < 16 * BPS; y += 4 * BPS) {
+    for (x = 0; x < 16; x += 4) {
+      D += Disto4x4(a + x + y, b + x + y, w);
+    }
+  }
+  return D;
+}
+
+//------------------------------------------------------------------------------
+// Intra predictions
+
+#define FILL_PART(J, SIZE)                                          \
+    "usw        %[value],  0+"#J"*"XSTR(BPS)"(%[dst])    \n\t"      \
+    "usw        %[value],  4+"#J"*"XSTR(BPS)"(%[dst])    \n\t"      \
+  ".if "#SIZE" == 16                                     \n\t"      \
+    "usw        %[value],  8+"#J"*"XSTR(BPS)"(%[dst])    \n\t"      \
+    "usw        %[value], 12+"#J"*"XSTR(BPS)"(%[dst])    \n\t"      \
+  ".endif                                                \n\t"
+
+#define FILL_8_OR_16(DST, VALUE, SIZE) do {                         \
+  int value = (VALUE);                                              \
+  __asm__ volatile (                                                \
+    "replv.qb   %[value],  %[value]                      \n\t"      \
+    FILL_PART( 0, SIZE)                                             \
+    FILL_PART( 1, SIZE)                                             \
+    FILL_PART( 2, SIZE)                                             \
+    FILL_PART( 3, SIZE)                                             \
+    FILL_PART( 4, SIZE)                                             \
+    FILL_PART( 5, SIZE)                                             \
+    FILL_PART( 6, SIZE)                                             \
+    FILL_PART( 7, SIZE)                                             \
+  ".if "#SIZE" == 16                                     \n\t"      \
+    FILL_PART( 8, 16)                                               \
+    FILL_PART( 9, 16)                                               \
+    FILL_PART(10, 16)                                               \
+    FILL_PART(11, 16)                                               \
+    FILL_PART(12, 16)                                               \
+    FILL_PART(13, 16)                                               \
+    FILL_PART(14, 16)                                               \
+    FILL_PART(15, 16)                                               \
+  ".endif                                                \n\t"      \
+    : [value]"+&r"(value)                                           \
+    : [dst]"r"((DST))                                               \
+    : "memory"                                                      \
+  );                                                                \
+} while (0)
+
+#define VERTICAL_PRED(DST, TOP, SIZE)                                          \
+static WEBP_INLINE void VerticalPred##SIZE(uint8_t* (DST),                     \
+                                           const uint8_t* (TOP)) {             \
+  int j;                                                                       \
+  if ((TOP)) {                                                                 \
+    for (j = 0; j < (SIZE); ++j) memcpy((DST) + j * BPS, (TOP), (SIZE));       \
+  } else {                                                                     \
+    FILL_8_OR_16((DST), 127, (SIZE));                                          \
+  }                                                                            \
+}
+
+VERTICAL_PRED(dst, top, 8)
+VERTICAL_PRED(dst, top, 16)
+
+#undef VERTICAL_PRED
+
+#define HORIZONTAL_PRED(DST, LEFT, SIZE)                                       \
+static WEBP_INLINE void HorizontalPred##SIZE(uint8_t* (DST),                   \
+                                             const uint8_t* (LEFT)) {          \
+  if (LEFT) {                                                                  \
+    int j;                                                                     \
+    for (j = 0; j < (SIZE); ++j) {                                             \
+      memset((DST) + j * BPS, (LEFT)[j], (SIZE));                              \
+    }                                                                          \
+  } else {                                                                     \
+    FILL_8_OR_16((DST), 129, (SIZE));                                          \
+  }                                                                            \
+}
+
+HORIZONTAL_PRED(dst, left, 8)
+HORIZONTAL_PRED(dst, left, 16)
+
+#undef HORIZONTAL_PRED
+
+#define CLIPPING()                                                             \
+  "preceu.ph.qbl   %[temp2],   %[temp0]                  \n\t"                 \
+  "preceu.ph.qbr   %[temp0],   %[temp0]                  \n\t"                 \
+  "preceu.ph.qbl   %[temp3],   %[temp1]                  \n\t"                 \
+  "preceu.ph.qbr   %[temp1],   %[temp1]                  \n\t"                 \
+  "addu.ph         %[temp2],   %[temp2],   %[leftY_1]    \n\t"                 \
+  "addu.ph         %[temp0],   %[temp0],   %[leftY_1]    \n\t"                 \
+  "addu.ph         %[temp3],   %[temp3],   %[leftY_1]    \n\t"                 \
+  "addu.ph         %[temp1],   %[temp1],   %[leftY_1]    \n\t"                 \
+  "shll_s.ph       %[temp2],   %[temp2],   7             \n\t"                 \
+  "shll_s.ph       %[temp0],   %[temp0],   7             \n\t"                 \
+  "shll_s.ph       %[temp3],   %[temp3],   7             \n\t"                 \
+  "shll_s.ph       %[temp1],   %[temp1],   7             \n\t"                 \
+  "precrqu_s.qb.ph %[temp0],   %[temp2],   %[temp0]      \n\t"                 \
+  "precrqu_s.qb.ph %[temp1],   %[temp3],   %[temp1]      \n\t"
+
+#define CLIP_8B_TO_DST(DST, LEFT, TOP, SIZE) do {                              \
+  int leftY_1 = ((int)(LEFT)[y] << 16) + (LEFT)[y];                            \
+  int temp0, temp1, temp2, temp3;                                              \
+  __asm__ volatile (                                                           \
+    "replv.ph        %[leftY_1], %[leftY_1]              \n\t"                 \
+    "ulw             %[temp0],   0(%[top])               \n\t"                 \
+    "ulw             %[temp1],   4(%[top])               \n\t"                 \
+    "subu.ph         %[leftY_1], %[leftY_1], %[left_1]   \n\t"                 \
+    CLIPPING()                                                                 \
+    "usw             %[temp0],   0(%[dst])               \n\t"                 \
+    "usw             %[temp1],   4(%[dst])               \n\t"                 \
+  ".if "#SIZE" == 16                                     \n\t"                 \
+    "ulw             %[temp0],   8(%[top])               \n\t"                 \
+    "ulw             %[temp1],   12(%[top])              \n\t"                 \
+    CLIPPING()                                                                 \
+    "usw             %[temp0],   8(%[dst])               \n\t"                 \
+    "usw             %[temp1],   12(%[dst])              \n\t"                 \
+  ".endif                                                \n\t"                 \
+    : [leftY_1]"+&r"(leftY_1), [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),       \
+      [temp2]"=&r"(temp2), [temp3]"=&r"(temp3)                                 \
+    : [left_1]"r"(left_1), [top]"r"((TOP)), [dst]"r"((DST))                    \
+    : "memory"                                                                 \
+  );                                                                           \
+} while (0)
+
+#define CLIP_TO_DST(DST, LEFT, TOP, SIZE) do {                                 \
+  int y;                                                                       \
+  const int left_1 = ((int)(LEFT)[-1] << 16) + (LEFT)[-1];                     \
+  for (y = 0; y < (SIZE); ++y) {                                               \
+    CLIP_8B_TO_DST((DST), (LEFT), (TOP), (SIZE));                              \
+    (DST) += BPS;                                                              \
+  }                                                                            \
+} while (0)
+
+#define TRUE_MOTION(DST, LEFT, TOP, SIZE)                                      \
+static WEBP_INLINE void TrueMotion##SIZE(uint8_t* (DST), const uint8_t* (LEFT),\
+                                         const uint8_t* (TOP)) {               \
+  if ((LEFT) != NULL) {                                                        \
+    if ((TOP) != NULL) {                                                       \
+      CLIP_TO_DST((DST), (LEFT), (TOP), (SIZE));                               \
+    } else {                                                                   \
+      HorizontalPred##SIZE((DST), (LEFT));                                     \
+    }                                                                          \
+  } else {                                                                     \
+    /* true motion without left samples (hence: with default 129 value)    */  \
+    /* is equivalent to VE prediction where you just copy the top samples. */  \
+    /* Note that if top samples are not available, the default value is    */  \
+    /* then 129, and not 127 as in the VerticalPred case.                  */  \
+    if ((TOP) != NULL) {                                                       \
+      VerticalPred##SIZE((DST), (TOP));                                        \
+    } else {                                                                   \
+      FILL_8_OR_16((DST), 129, (SIZE));                                        \
+    }                                                                          \
+  }                                                                            \
+}
+
+TRUE_MOTION(dst, left, top, 8)
+TRUE_MOTION(dst, left, top, 16)
+
+#undef TRUE_MOTION
+#undef CLIP_TO_DST
+#undef CLIP_8B_TO_DST
+#undef CLIPPING
+
+static WEBP_INLINE void DCMode16(uint8_t* dst, const uint8_t* left,
+                                 const uint8_t* top) {
+  int DC, DC1;
+  int temp0, temp1, temp2, temp3;
+
+  __asm__ volatile(
+    "beqz        %[top],   2f                  \n\t"
+    LOAD_WITH_OFFSET_X4(temp0, temp1, temp2, temp3, top,
+                        0, 4, 8, 12,
+                        0, 0, 0, 0,
+                        0)
+    "raddu.w.qb  %[temp0], %[temp0]            \n\t"
+    "raddu.w.qb  %[temp1], %[temp1]            \n\t"
+    "raddu.w.qb  %[temp2], %[temp2]            \n\t"
+    "raddu.w.qb  %[temp3], %[temp3]            \n\t"
+    "addu        %[temp0], %[temp0], %[temp1]  \n\t"
+    "addu        %[temp2], %[temp2], %[temp3]  \n\t"
+    "addu        %[DC],    %[temp0], %[temp2]  \n\t"
+    "move        %[DC1],   %[DC]               \n\t"
+    "beqz        %[left],  1f                  \n\t"
+    LOAD_WITH_OFFSET_X4(temp0, temp1, temp2, temp3, left,
+                        0, 4, 8, 12,
+                        0, 0, 0, 0,
+                        0)
+    "raddu.w.qb  %[temp0], %[temp0]            \n\t"
+    "raddu.w.qb  %[temp1], %[temp1]            \n\t"
+    "raddu.w.qb  %[temp2], %[temp2]            \n\t"
+    "raddu.w.qb  %[temp3], %[temp3]            \n\t"
+    "addu        %[temp0], %[temp0], %[temp1]  \n\t"
+    "addu        %[temp2], %[temp2], %[temp3]  \n\t"
+    "addu        %[DC1],   %[temp0], %[temp2]  \n\t"
+  "1:                                          \n\t"
+    "addu        %[DC],   %[DC],     %[DC1]    \n\t"
+    "j           3f                            \n\t"
+  "2:                                          \n\t"
+    "beqz        %[left],  4f                  \n\t"
+    LOAD_WITH_OFFSET_X4(temp0, temp1, temp2, temp3, left,
+                        0, 4, 8, 12,
+                        0, 0, 0, 0,
+                        0)
+    "raddu.w.qb  %[temp0], %[temp0]            \n\t"
+    "raddu.w.qb  %[temp1], %[temp1]            \n\t"
+    "raddu.w.qb  %[temp2], %[temp2]            \n\t"
+    "raddu.w.qb  %[temp3], %[temp3]            \n\t"
+    "addu        %[temp0], %[temp0], %[temp1]  \n\t"
+    "addu        %[temp2], %[temp2], %[temp3]  \n\t"
+    "addu        %[DC],    %[temp0], %[temp2]  \n\t"
+    "addu        %[DC],    %[DC],    %[DC]     \n\t"
+  "3:                                          \n\t"
+    "shra_r.w    %[DC],    %[DC],    5         \n\t"
+    "j           5f                            \n\t"
+  "4:                                          \n\t"
+    "li          %[DC],    0x80                \n\t"
+  "5:                                          \n\t"
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [DC]"=&r"(DC),
+      [temp2]"=&r"(temp2), [temp3]"=&r"(temp3), [DC1]"=&r"(DC1)
+    : [left]"r"(left), [top]"r"(top)
+    : "memory"
+  );
+
+  FILL_8_OR_16(dst, DC, 16);
+}
+
+static WEBP_INLINE void DCMode8(uint8_t* dst, const uint8_t* left,
+                                const uint8_t* top) {
+  int DC, DC1;
+  int temp0, temp1, temp2, temp3;
+
+  __asm__ volatile(
+    "beqz        %[top],   2f                  \n\t"
+    "ulw         %[temp0], 0(%[top])           \n\t"
+    "ulw         %[temp1], 4(%[top])           \n\t"
+    "raddu.w.qb  %[temp0], %[temp0]            \n\t"
+    "raddu.w.qb  %[temp1], %[temp1]            \n\t"
+    "addu        %[DC],    %[temp0], %[temp1]  \n\t"
+    "move        %[DC1],   %[DC]               \n\t"
+    "beqz        %[left],  1f                  \n\t"
+    "ulw         %[temp2], 0(%[left])          \n\t"
+    "ulw         %[temp3], 4(%[left])          \n\t"
+    "raddu.w.qb  %[temp2], %[temp2]            \n\t"
+    "raddu.w.qb  %[temp3], %[temp3]            \n\t"
+    "addu        %[DC1],   %[temp2], %[temp3]  \n\t"
+  "1:                                          \n\t"
+    "addu        %[DC],    %[DC],    %[DC1]    \n\t"
+    "j           3f                            \n\t"
+  "2:                                          \n\t"
+    "beqz        %[left],  4f                  \n\t"
+    "ulw         %[temp2], 0(%[left])          \n\t"
+    "ulw         %[temp3], 4(%[left])          \n\t"
+    "raddu.w.qb  %[temp2], %[temp2]            \n\t"
+    "raddu.w.qb  %[temp3], %[temp3]            \n\t"
+    "addu        %[DC],    %[temp2], %[temp3]  \n\t"
+    "addu        %[DC],    %[DC],    %[DC]     \n\t"
+  "3:                                          \n\t"
+    "shra_r.w    %[DC], %[DC], 4               \n\t"
+    "j           5f                            \n\t"
+  "4:                                          \n\t"
+    "li          %[DC], 0x80                   \n\t"
+  "5:                                          \n\t"
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [DC]"=&r"(DC),
+      [temp2]"=&r"(temp2), [temp3]"=&r"(temp3), [DC1]"=&r"(DC1)
+    : [left]"r"(left), [top]"r"(top)
+    : "memory"
+  );
+
+  FILL_8_OR_16(dst, DC, 8);
+}
+
+static void DC4(uint8_t* dst, const uint8_t* top) {
+  int temp0, temp1;
+  __asm__ volatile(
+    "ulw          %[temp0],   0(%[top])               \n\t"
+    "ulw          %[temp1],   -5(%[top])              \n\t"
+    "raddu.w.qb   %[temp0],   %[temp0]                \n\t"
+    "raddu.w.qb   %[temp1],   %[temp1]                \n\t"
+    "addu         %[temp0],   %[temp0],    %[temp1]   \n\t"
+    "addiu        %[temp0],   %[temp0],    4          \n\t"
+    "srl          %[temp0],   %[temp0],    3          \n\t"
+    "replv.qb     %[temp0],   %[temp0]                \n\t"
+    "usw          %[temp0],   0*"XSTR(BPS)"(%[dst])   \n\t"
+    "usw          %[temp0],   1*"XSTR(BPS)"(%[dst])   \n\t"
+    "usw          %[temp0],   2*"XSTR(BPS)"(%[dst])   \n\t"
+    "usw          %[temp0],   3*"XSTR(BPS)"(%[dst])   \n\t"
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1)
+    : [top]"r"(top), [dst]"r"(dst)
+    : "memory"
+  );
+}
+
+static void TM4(uint8_t* dst, const uint8_t* top) {
+  int a10, a32, temp0, temp1, temp2, temp3, temp4, temp5;
+  const int c35 = 0xff00ff;
+  __asm__ volatile (
+    "lbu              %[temp1],  0(%[top])                     \n\t"
+    "lbu              %[a10],    1(%[top])                     \n\t"
+    "lbu              %[temp2],  2(%[top])                     \n\t"
+    "lbu              %[a32],    3(%[top])                     \n\t"
+    "ulw              %[temp0],  -5(%[top])                    \n\t"
+    "lbu              %[temp4],  -1(%[top])                    \n\t"
+    "append           %[a10],    %[temp1],   16                \n\t"
+    "append           %[a32],    %[temp2],   16                \n\t"
+    "replv.ph         %[temp4],  %[temp4]                      \n\t"
+    "shrl.ph          %[temp1],  %[temp0],   8                 \n\t"
+    "and              %[temp0],  %[temp0],   %[c35]            \n\t"
+    "subu.ph          %[temp1],  %[temp1],   %[temp4]          \n\t"
+    "subu.ph          %[temp0],  %[temp0],   %[temp4]          \n\t"
+    "srl              %[temp2],  %[temp1],   16                \n\t"
+    "srl              %[temp3],  %[temp0],   16                \n\t"
+    "replv.ph         %[temp2],  %[temp2]                      \n\t"
+    "replv.ph         %[temp3],  %[temp3]                      \n\t"
+    "replv.ph         %[temp4],  %[temp1]                      \n\t"
+    "replv.ph         %[temp5],  %[temp0]                      \n\t"
+    "addu.ph          %[temp0],  %[temp3],   %[a10]            \n\t"
+    "addu.ph          %[temp1],  %[temp3],   %[a32]            \n\t"
+    "addu.ph          %[temp3],  %[temp2],   %[a10]            \n\t"
+    "addu.ph          %[temp2],  %[temp2],   %[a32]            \n\t"
+    "shll_s.ph        %[temp0],  %[temp0],   7                 \n\t"
+    "shll_s.ph        %[temp1],  %[temp1],   7                 \n\t"
+    "shll_s.ph        %[temp3],  %[temp3],   7                 \n\t"
+    "shll_s.ph        %[temp2],  %[temp2],   7                 \n\t"
+    "precrqu_s.qb.ph  %[temp0],  %[temp1],   %[temp0]          \n\t"
+    "precrqu_s.qb.ph  %[temp1],  %[temp2],   %[temp3]          \n\t"
+    "addu.ph          %[temp2],  %[temp5],   %[a10]            \n\t"
+    "addu.ph          %[temp3],  %[temp5],   %[a32]            \n\t"
+    "addu.ph          %[temp5],  %[temp4],   %[a10]            \n\t"
+    "addu.ph          %[temp4],  %[temp4],   %[a32]            \n\t"
+    "shll_s.ph        %[temp2],  %[temp2],   7                 \n\t"
+    "shll_s.ph        %[temp3],  %[temp3],   7                 \n\t"
+    "shll_s.ph        %[temp4],  %[temp4],   7                 \n\t"
+    "shll_s.ph        %[temp5],  %[temp5],   7                 \n\t"
+    "precrqu_s.qb.ph  %[temp2],  %[temp3],   %[temp2]          \n\t"
+    "precrqu_s.qb.ph  %[temp3],  %[temp4],   %[temp5]          \n\t"
+    "usw              %[temp1],  0*"XSTR(BPS)"(%[dst])         \n\t"
+    "usw              %[temp0],  1*"XSTR(BPS)"(%[dst])         \n\t"
+    "usw              %[temp3],  2*"XSTR(BPS)"(%[dst])         \n\t"
+    "usw              %[temp2],  3*"XSTR(BPS)"(%[dst])         \n\t"
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+      [a10]"=&r"(a10), [a32]"=&r"(a32)
+    : [c35]"r"(c35), [top]"r"(top), [dst]"r"(dst)
+    : "memory"
+  );
+}
+
+static void VE4(uint8_t* dst, const uint8_t* top) {
+  int temp0, temp1, temp2, temp3, temp4, temp5, temp6;
+  __asm__ volatile(
+    "ulw             %[temp0],   -1(%[top])              \n\t"
+    "ulh             %[temp1],   3(%[top])               \n\t"
+    "preceu.ph.qbr   %[temp2],   %[temp0]                \n\t"
+    "preceu.ph.qbl   %[temp3],   %[temp0]                \n\t"
+    "preceu.ph.qbr   %[temp4],   %[temp1]                \n\t"
+    "packrl.ph       %[temp5],   %[temp3],    %[temp2]   \n\t"
+    "packrl.ph       %[temp6],   %[temp4],    %[temp3]   \n\t"
+    "shll.ph         %[temp5],   %[temp5],    1          \n\t"
+    "shll.ph         %[temp6],   %[temp6],    1          \n\t"
+    "addq.ph         %[temp2],   %[temp5],    %[temp2]   \n\t"
+    "addq.ph         %[temp6],   %[temp6],    %[temp4]   \n\t"
+    "addq.ph         %[temp2],   %[temp2],    %[temp3]   \n\t"
+    "addq.ph         %[temp6],   %[temp6],    %[temp3]   \n\t"
+    "shra_r.ph       %[temp2],   %[temp2],    2          \n\t"
+    "shra_r.ph       %[temp6],   %[temp6],    2          \n\t"
+    "precr.qb.ph     %[temp4],   %[temp6],    %[temp2]   \n\t"
+    "usw             %[temp4],   0*"XSTR(BPS)"(%[dst])   \n\t"
+    "usw             %[temp4],   1*"XSTR(BPS)"(%[dst])   \n\t"
+    "usw             %[temp4],   2*"XSTR(BPS)"(%[dst])   \n\t"
+    "usw             %[temp4],   3*"XSTR(BPS)"(%[dst])   \n\t"
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+      [temp6]"=&r"(temp6)
+    : [top]"r"(top), [dst]"r"(dst)
+    : "memory"
+  );
+}
+
+static void HE4(uint8_t* dst, const uint8_t* top) {
+  int temp0, temp1, temp2, temp3, temp4, temp5, temp6;
+  __asm__ volatile(
+    "ulw             %[temp0],   -4(%[top])              \n\t"
+    "lbu             %[temp1],   -5(%[top])              \n\t"
+    "preceu.ph.qbr   %[temp2],   %[temp0]                \n\t"
+    "preceu.ph.qbl   %[temp3],   %[temp0]                \n\t"
+    "replv.ph        %[temp4],   %[temp1]                \n\t"
+    "packrl.ph       %[temp5],   %[temp3],    %[temp2]   \n\t"
+    "packrl.ph       %[temp6],   %[temp2],    %[temp4]   \n\t"
+    "shll.ph         %[temp5],   %[temp5],    1          \n\t"
+    "shll.ph         %[temp6],   %[temp6],    1          \n\t"
+    "addq.ph         %[temp3],   %[temp3],    %[temp5]   \n\t"
+    "addq.ph         %[temp3],   %[temp3],    %[temp2]   \n\t"
+    "addq.ph         %[temp2],   %[temp2],    %[temp6]   \n\t"
+    "addq.ph         %[temp2],   %[temp2],    %[temp4]   \n\t"
+    "shra_r.ph       %[temp3],   %[temp3],    2          \n\t"
+    "shra_r.ph       %[temp2],   %[temp2],    2          \n\t"
+    "replv.qb        %[temp0],   %[temp3]                \n\t"
+    "replv.qb        %[temp1],   %[temp2]                \n\t"
+    "srl             %[temp3],   %[temp3],    16         \n\t"
+    "srl             %[temp2],   %[temp2],    16         \n\t"
+    "replv.qb        %[temp3],   %[temp3]                \n\t"
+    "replv.qb        %[temp2],   %[temp2]                \n\t"
+    "usw             %[temp3],   0*"XSTR(BPS)"(%[dst])   \n\t"
+    "usw             %[temp0],   1*"XSTR(BPS)"(%[dst])   \n\t"
+    "usw             %[temp2],   2*"XSTR(BPS)"(%[dst])   \n\t"
+    "usw             %[temp1],   3*"XSTR(BPS)"(%[dst])   \n\t"
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+      [temp6]"=&r"(temp6)
+    : [top]"r"(top), [dst]"r"(dst)
+    : "memory"
+  );
+}
+
+static void RD4(uint8_t* dst, const uint8_t* top) {
+  int temp0, temp1, temp2, temp3, temp4, temp5;
+  int temp6, temp7, temp8, temp9, temp10, temp11;
+  __asm__ volatile(
+    "ulw             %[temp0],    -5(%[top])               \n\t"
+    "ulw             %[temp1],    -1(%[top])               \n\t"
+    "preceu.ph.qbl   %[temp2],    %[temp0]                 \n\t"
+    "preceu.ph.qbr   %[temp3],    %[temp0]                 \n\t"
+    "preceu.ph.qbr   %[temp4],    %[temp1]                 \n\t"
+    "preceu.ph.qbl   %[temp5],    %[temp1]                 \n\t"
+    "packrl.ph       %[temp6],    %[temp2],    %[temp3]    \n\t"
+    "packrl.ph       %[temp7],    %[temp4],    %[temp2]    \n\t"
+    "packrl.ph       %[temp8],    %[temp5],    %[temp4]    \n\t"
+    "shll.ph         %[temp6],    %[temp6],    1           \n\t"
+    "addq.ph         %[temp9],    %[temp2],    %[temp6]    \n\t"
+    "shll.ph         %[temp7],    %[temp7],    1           \n\t"
+    "addq.ph         %[temp9],    %[temp9],    %[temp3]    \n\t"
+    "shll.ph         %[temp8],    %[temp8],    1           \n\t"
+    "shra_r.ph       %[temp9],    %[temp9],    2           \n\t"
+    "addq.ph         %[temp10],   %[temp4],    %[temp7]    \n\t"
+    "addq.ph         %[temp11],   %[temp5],    %[temp8]    \n\t"
+    "addq.ph         %[temp10],   %[temp10],   %[temp2]    \n\t"
+    "addq.ph         %[temp11],   %[temp11],   %[temp4]    \n\t"
+    "shra_r.ph       %[temp10],   %[temp10],   2           \n\t"
+    "shra_r.ph       %[temp11],   %[temp11],   2           \n\t"
+    "lbu             %[temp0],    3(%[top])                \n\t"
+    "lbu             %[temp1],    2(%[top])                \n\t"
+    "lbu             %[temp2],    1(%[top])                \n\t"
+    "sll             %[temp1],    %[temp1],    1           \n\t"
+    "addu            %[temp0],    %[temp0],    %[temp1]    \n\t"
+    "addu            %[temp0],    %[temp0],    %[temp2]    \n\t"
+    "precr.qb.ph     %[temp9],    %[temp10],   %[temp9]    \n\t"
+    "shra_r.w        %[temp0],    %[temp0],    2           \n\t"
+    "precr.qb.ph     %[temp10],   %[temp11],   %[temp10]   \n\t"
+    "usw             %[temp9],    3*"XSTR(BPS)"(%[dst])    \n\t"
+    "usw             %[temp10],   1*"XSTR(BPS)"(%[dst])    \n\t"
+    "prepend         %[temp9],    %[temp11],   8           \n\t"
+    "prepend         %[temp10],   %[temp0],    8           \n\t"
+    "usw             %[temp9],    2*"XSTR(BPS)"(%[dst])    \n\t"
+    "usw             %[temp10],   0*"XSTR(BPS)"(%[dst])    \n\t"
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+      [temp6]"=&r"(temp6), [temp7]"=&r"(temp7), [temp8]"=&r"(temp8),
+      [temp9]"=&r"(temp9), [temp10]"=&r"(temp10), [temp11]"=&r"(temp11)
+    : [top]"r"(top), [dst]"r"(dst)
+    : "memory"
+  );
+}
+
+static void VR4(uint8_t* dst, const uint8_t* top) {
+  int temp0, temp1, temp2, temp3, temp4;
+  int temp5, temp6, temp7, temp8, temp9;
+  __asm__ volatile (
+    "ulw              %[temp0],   -4(%[top])              \n\t"
+    "ulw              %[temp1],   0(%[top])               \n\t"
+    "preceu.ph.qbl    %[temp2],   %[temp0]                \n\t"
+    "preceu.ph.qbr    %[temp0],   %[temp0]                \n\t"
+    "preceu.ph.qbla   %[temp3],   %[temp1]                \n\t"
+    "preceu.ph.qbra   %[temp1],   %[temp1]                \n\t"
+    "packrl.ph        %[temp7],   %[temp3],    %[temp2]   \n\t"
+    "addqh_r.ph       %[temp4],   %[temp1],    %[temp3]   \n\t"
+    "move             %[temp6],   %[temp1]                \n\t"
+    "append           %[temp1],   %[temp2],    16         \n\t"
+    "shll.ph          %[temp9],   %[temp6],    1          \n\t"
+    "addqh_r.ph       %[temp5],   %[temp7],    %[temp6]   \n\t"
+    "shll.ph          %[temp8],   %[temp7],    1          \n\t"
+    "addu.ph          %[temp3],   %[temp7],    %[temp3]   \n\t"
+    "addu.ph          %[temp1],   %[temp1],    %[temp6]   \n\t"
+    "packrl.ph        %[temp7],   %[temp2],    %[temp0]   \n\t"
+    "addu.ph          %[temp6],   %[temp0],    %[temp2]   \n\t"
+    "addu.ph          %[temp3],   %[temp3],    %[temp9]   \n\t"
+    "addu.ph          %[temp1],   %[temp1],    %[temp8]   \n\t"
+    "shll.ph          %[temp7],   %[temp7],    1          \n\t"
+    "shra_r.ph        %[temp3],   %[temp3],    2          \n\t"
+    "shra_r.ph        %[temp1],   %[temp1],    2          \n\t"
+    "addu.ph          %[temp6],   %[temp6],    %[temp7]   \n\t"
+    "shra_r.ph        %[temp6],   %[temp6],    2          \n\t"
+    "precrq.ph.w      %[temp8],   %[temp4],    %[temp5]   \n\t"
+    "append           %[temp4],   %[temp5],    16         \n\t"
+    "precrq.ph.w      %[temp2],   %[temp3],    %[temp1]   \n\t"
+    "append           %[temp3],   %[temp1],    16         \n\t"
+    "precr.qb.ph      %[temp8],   %[temp8],    %[temp4]   \n\t"
+    "precr.qb.ph      %[temp3],   %[temp2],    %[temp3]   \n\t"
+    "usw              %[temp8],   0*"XSTR(BPS)"(%[dst])   \n\t"
+    "usw              %[temp3],   1*"XSTR(BPS)"(%[dst])   \n\t"
+    "append           %[temp3],   %[temp6],    8          \n\t"
+    "srl              %[temp6],   %[temp6],    16         \n\t"
+    "append           %[temp8],   %[temp6],    8          \n\t"
+    "usw              %[temp3],   3*"XSTR(BPS)"(%[dst])   \n\t"
+    "usw              %[temp8],   2*"XSTR(BPS)"(%[dst])   \n\t"
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+      [temp6]"=&r"(temp6), [temp7]"=&r"(temp7), [temp8]"=&r"(temp8),
+      [temp9]"=&r"(temp9)
+    : [top]"r"(top), [dst]"r"(dst)
+    : "memory"
+  );
+}
+
+static void LD4(uint8_t* dst, const uint8_t* top) {
+  int temp0, temp1, temp2, temp3, temp4, temp5;
+  int temp6, temp7, temp8, temp9, temp10, temp11;
+  __asm__ volatile(
+    "ulw             %[temp0],    0(%[top])               \n\t"
+    "ulw             %[temp1],    4(%[top])               \n\t"
+    "preceu.ph.qbl   %[temp2],    %[temp0]                \n\t"
+    "preceu.ph.qbr   %[temp3],    %[temp0]                \n\t"
+    "preceu.ph.qbr   %[temp4],    %[temp1]                \n\t"
+    "preceu.ph.qbl   %[temp5],    %[temp1]                \n\t"
+    "packrl.ph       %[temp6],    %[temp2],    %[temp3]   \n\t"
+    "packrl.ph       %[temp7],    %[temp4],    %[temp2]   \n\t"
+    "packrl.ph       %[temp8],    %[temp5],    %[temp4]   \n\t"
+    "shll.ph         %[temp6],    %[temp6],    1          \n\t"
+    "addq.ph         %[temp9],    %[temp2],    %[temp6]   \n\t"
+    "shll.ph         %[temp7],    %[temp7],    1          \n\t"
+    "addq.ph         %[temp9],    %[temp9],    %[temp3]   \n\t"
+    "shll.ph         %[temp8],    %[temp8],    1          \n\t"
+    "shra_r.ph       %[temp9],    %[temp9],    2          \n\t"
+    "addq.ph         %[temp10],   %[temp4],    %[temp7]   \n\t"
+    "addq.ph         %[temp11],   %[temp5],    %[temp8]   \n\t"
+    "addq.ph         %[temp10],   %[temp10],   %[temp2]   \n\t"
+    "addq.ph         %[temp11],   %[temp11],   %[temp4]   \n\t"
+    "shra_r.ph       %[temp10],   %[temp10],   2          \n\t"
+    "shra_r.ph       %[temp11],   %[temp11],   2          \n\t"
+    "srl             %[temp1],    %[temp1],    24         \n\t"
+    "sll             %[temp1],    %[temp1],    1          \n\t"
+    "raddu.w.qb      %[temp5],    %[temp5]                \n\t"
+    "precr.qb.ph     %[temp9],    %[temp10],   %[temp9]   \n\t"
+    "precr.qb.ph     %[temp10],   %[temp11],   %[temp10]  \n\t"
+    "addu            %[temp1],    %[temp1],    %[temp5]   \n\t"
+    "shra_r.w        %[temp1],    %[temp1],    2          \n\t"
+    "usw             %[temp9],    0*"XSTR(BPS)"(%[dst])   \n\t"
+    "usw             %[temp10],   2*"XSTR(BPS)"(%[dst])   \n\t"
+    "prepend         %[temp9],    %[temp11],   8          \n\t"
+    "prepend         %[temp10],   %[temp1],    8          \n\t"
+    "usw             %[temp9],    1*"XSTR(BPS)"(%[dst])   \n\t"
+    "usw             %[temp10],   3*"XSTR(BPS)"(%[dst])   \n\t"
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+      [temp6]"=&r"(temp6), [temp7]"=&r"(temp7), [temp8]"=&r"(temp8),
+      [temp9]"=&r"(temp9), [temp10]"=&r"(temp10), [temp11]"=&r"(temp11)
+    : [top]"r"(top), [dst]"r"(dst)
+    : "memory"
+  );
+}
+
+static void VL4(uint8_t* dst, const uint8_t* top) {
+  int temp0, temp1, temp2, temp3, temp4;
+  int temp5, temp6, temp7, temp8, temp9;
+  __asm__ volatile (
+    "ulw              %[temp0],   0(%[top])               \n\t"
+    "ulw              %[temp1],   4(%[top])               \n\t"
+    "preceu.ph.qbla   %[temp2],   %[temp0]                \n\t"
+    "preceu.ph.qbra   %[temp0],   %[temp0]                \n\t"
+    "preceu.ph.qbl    %[temp3],   %[temp1]                \n\t"
+    "preceu.ph.qbr    %[temp1],   %[temp1]                \n\t"
+    "addqh_r.ph       %[temp4],   %[temp0],    %[temp2]   \n\t"
+    "packrl.ph        %[temp7],   %[temp1],    %[temp0]   \n\t"
+    "precrq.ph.w      %[temp6],   %[temp1],    %[temp2]   \n\t"
+    "shll.ph          %[temp9],   %[temp2],    1          \n\t"
+    "addqh_r.ph       %[temp5],   %[temp7],    %[temp2]   \n\t"
+    "shll.ph          %[temp8],   %[temp7],    1          \n\t"
+    "addu.ph          %[temp2],   %[temp2],    %[temp6]   \n\t"
+    "addu.ph          %[temp0],   %[temp0],    %[temp7]   \n\t"
+    "packrl.ph        %[temp7],   %[temp3],    %[temp1]   \n\t"
+    "addu.ph          %[temp6],   %[temp1],    %[temp3]   \n\t"
+    "addu.ph          %[temp2],   %[temp2],    %[temp8]   \n\t"
+    "addu.ph          %[temp0],   %[temp0],    %[temp9]   \n\t"
+    "shll.ph          %[temp7],   %[temp7],    1          \n\t"
+    "shra_r.ph        %[temp2],   %[temp2],    2          \n\t"
+    "shra_r.ph        %[temp0],   %[temp0],    2          \n\t"
+    "addu.ph          %[temp6],   %[temp6],    %[temp7]   \n\t"
+    "shra_r.ph        %[temp6],   %[temp6],    2          \n\t"
+    "precrq.ph.w      %[temp8],   %[temp5],    %[temp4]   \n\t"
+    "append           %[temp5],   %[temp4],    16         \n\t"
+    "precrq.ph.w      %[temp3],   %[temp2],    %[temp0]   \n\t"
+    "append           %[temp2],   %[temp0],    16         \n\t"
+    "precr.qb.ph      %[temp8],   %[temp8],    %[temp5]   \n\t"
+    "precr.qb.ph      %[temp3],   %[temp3],    %[temp2]   \n\t"
+    "usw              %[temp8],   0*"XSTR(BPS)"(%[dst])   \n\t"
+    "prepend          %[temp8],   %[temp6],    8          \n\t"
+    "usw              %[temp3],   1*"XSTR(BPS)"(%[dst])   \n\t"
+    "srl              %[temp6],   %[temp6],    16         \n\t"
+    "prepend          %[temp3],   %[temp6],    8          \n\t"
+    "usw              %[temp8],   2*"XSTR(BPS)"(%[dst])   \n\t"
+    "usw              %[temp3],   3*"XSTR(BPS)"(%[dst])   \n\t"
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+      [temp6]"=&r"(temp6), [temp7]"=&r"(temp7), [temp8]"=&r"(temp8),
+      [temp9]"=&r"(temp9)
+    : [top]"r"(top), [dst]"r"(dst)
+    : "memory"
+  );
+}
+
+static void HD4(uint8_t* dst, const uint8_t* top) {
+  int temp0, temp1, temp2, temp3, temp4;
+  int temp5, temp6, temp7, temp8, temp9;
+  __asm__ volatile (
+    "ulw              %[temp0],   -5(%[top])              \n\t"
+    "ulw              %[temp1],   -1(%[top])              \n\t"
+    "preceu.ph.qbla   %[temp2],   %[temp0]                \n\t"
+    "preceu.ph.qbra   %[temp0],   %[temp0]                \n\t"
+    "preceu.ph.qbl    %[temp3],   %[temp1]                \n\t"
+    "preceu.ph.qbr    %[temp1],   %[temp1]                \n\t"
+    "addqh_r.ph       %[temp4],   %[temp0],    %[temp2]   \n\t"
+    "packrl.ph        %[temp7],   %[temp1],    %[temp0]   \n\t"
+    "precrq.ph.w      %[temp6],   %[temp1],    %[temp2]   \n\t"
+    "shll.ph          %[temp9],   %[temp2],    1          \n\t"
+    "addqh_r.ph       %[temp5],   %[temp7],    %[temp2]   \n\t"
+    "shll.ph          %[temp8],   %[temp7],    1          \n\t"
+    "addu.ph          %[temp2],   %[temp2],    %[temp6]   \n\t"
+    "addu.ph          %[temp0],   %[temp0],    %[temp7]   \n\t"
+    "packrl.ph        %[temp7],   %[temp3],    %[temp1]   \n\t"
+    "addu.ph          %[temp6],   %[temp1],    %[temp3]   \n\t"
+    "addu.ph          %[temp2],   %[temp2],    %[temp8]   \n\t"
+    "addu.ph          %[temp0],   %[temp0],    %[temp9]   \n\t"
+    "shll.ph          %[temp7],   %[temp7],    1          \n\t"
+    "shra_r.ph        %[temp2],   %[temp2],    2          \n\t"
+    "shra_r.ph        %[temp0],   %[temp0],    2          \n\t"
+    "addu.ph          %[temp6],   %[temp6],    %[temp7]   \n\t"
+    "shra_r.ph        %[temp6],   %[temp6],    2          \n\t"
+    "precrq.ph.w      %[temp1],   %[temp2],    %[temp5]   \n\t"
+    "precrq.ph.w      %[temp3],   %[temp0],    %[temp4]   \n\t"
+    "precr.qb.ph      %[temp7],   %[temp6],    %[temp1]   \n\t"
+    "precr.qb.ph      %[temp6],   %[temp1],    %[temp3]   \n\t"
+    "usw              %[temp7],   0*"XSTR(BPS)"(%[dst])   \n\t"
+    "usw              %[temp6],   1*"XSTR(BPS)"(%[dst])   \n\t"
+    "append           %[temp2],   %[temp5],    16         \n\t"
+    "append           %[temp0],   %[temp4],    16         \n\t"
+    "precr.qb.ph      %[temp5],   %[temp3],    %[temp2]   \n\t"
+    "precr.qb.ph      %[temp4],   %[temp2],    %[temp0]   \n\t"
+    "usw              %[temp5],   2*"XSTR(BPS)"(%[dst])   \n\t"
+    "usw              %[temp4],   3*"XSTR(BPS)"(%[dst])   \n\t"
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+      [temp6]"=&r"(temp6), [temp7]"=&r"(temp7), [temp8]"=&r"(temp8),
+      [temp9]"=&r"(temp9)
+    : [top]"r"(top), [dst]"r"(dst)
+    : "memory"
+  );
+}
+
+static void HU4(uint8_t* dst, const uint8_t* top) {
+  int temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
+  __asm__ volatile (
+    "ulw             %[temp0],   -5(%[top])              \n\t"
+    "preceu.ph.qbl   %[temp1],   %[temp0]                \n\t"
+    "preceu.ph.qbr   %[temp2],   %[temp0]                \n\t"
+    "packrl.ph       %[temp3],   %[temp1],    %[temp2]   \n\t"
+    "replv.qb        %[temp7],   %[temp2]                \n\t"
+    "addqh_r.ph      %[temp4],   %[temp1],    %[temp3]   \n\t"
+    "addqh_r.ph      %[temp5],   %[temp3],    %[temp2]   \n\t"
+    "shll.ph         %[temp6],   %[temp3],    1          \n\t"
+    "addu.ph         %[temp3],   %[temp2],    %[temp3]   \n\t"
+    "addu.ph         %[temp6],   %[temp1],    %[temp6]   \n\t"
+    "shll.ph         %[temp0],   %[temp2],    1          \n\t"
+    "addu.ph         %[temp6],   %[temp6],    %[temp2]   \n\t"
+    "addu.ph         %[temp0],   %[temp3],    %[temp0]   \n\t"
+    "shra_r.ph       %[temp6],   %[temp6],    2          \n\t"
+    "shra_r.ph       %[temp0],   %[temp0],    2          \n\t"
+    "packrl.ph       %[temp3],   %[temp6],    %[temp5]   \n\t"
+    "precrq.ph.w     %[temp2],   %[temp6],    %[temp4]   \n\t"
+    "append          %[temp0],   %[temp5],    16         \n\t"
+    "precr.qb.ph     %[temp3],   %[temp3],    %[temp2]   \n\t"
+    "usw             %[temp3],   0*"XSTR(BPS)"(%[dst])   \n\t"
+    "precr.qb.ph     %[temp1],   %[temp7],    %[temp0]   \n\t"
+    "usw             %[temp7],   3*"XSTR(BPS)"(%[dst])   \n\t"
+    "packrl.ph       %[temp2],   %[temp1],    %[temp3]   \n\t"
+    "usw             %[temp1],   2*"XSTR(BPS)"(%[dst])   \n\t"
+    "usw             %[temp2],   1*"XSTR(BPS)"(%[dst])   \n\t"
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+      [temp6]"=&r"(temp6), [temp7]"=&r"(temp7)
+    : [top]"r"(top), [dst]"r"(dst)
+    : "memory"
+  );
+}
+
+//------------------------------------------------------------------------------
+// Chroma 8x8 prediction (paragraph 12.2)
+
+static void IntraChromaPreds(uint8_t* dst, const uint8_t* left,
+                             const uint8_t* top) {
+  // U block
+  DCMode8(C8DC8 + dst, left, top);
+  VerticalPred8(C8VE8 + dst, top);
+  HorizontalPred8(C8HE8 + dst, left);
+  TrueMotion8(C8TM8 + dst, left, top);
+  // V block
+  dst += 8;
+  if (top) top += 8;
+  if (left) left += 16;
+  DCMode8(C8DC8 + dst, left, top);
+  VerticalPred8(C8VE8 + dst, top);
+  HorizontalPred8(C8HE8 + dst, left);
+  TrueMotion8(C8TM8 + dst, left, top);
+}
+
+//------------------------------------------------------------------------------
+// luma 16x16 prediction (paragraph 12.3)
+
+static void Intra16Preds(uint8_t* dst,
+                         const uint8_t* left, const uint8_t* top) {
+  DCMode16(I16DC16 + dst, left, top);
+  VerticalPred16(I16VE16 + dst, top);
+  HorizontalPred16(I16HE16 + dst, left);
+  TrueMotion16(I16TM16 + dst, left, top);
+}
+
+// Left samples are top[-5 .. -2], top_left is top[-1], top are
+// located at top[0..3], and top right is top[4..7]
+static void Intra4Preds(uint8_t* dst, const uint8_t* top) {
+  DC4(I4DC4 + dst, top);
+  TM4(I4TM4 + dst, top);
+  VE4(I4VE4 + dst, top);
+  HE4(I4HE4 + dst, top);
+  RD4(I4RD4 + dst, top);
+  VR4(I4VR4 + dst, top);
+  LD4(I4LD4 + dst, top);
+  VL4(I4VL4 + dst, top);
+  HD4(I4HD4 + dst, top);
+  HU4(I4HU4 + dst, top);
+}
+
+//------------------------------------------------------------------------------
+// Metric
+
+#if !defined(WORK_AROUND_GCC)
+
+#define GET_SSE_INNER(A)                                                  \
+  "lw               %[temp0],    "#A"(%[a])                    \n\t"      \
+  "lw               %[temp1],    "#A"(%[b])                    \n\t"      \
+  "preceu.ph.qbr    %[temp2],    %[temp0]                      \n\t"      \
+  "preceu.ph.qbl    %[temp0],    %[temp0]                      \n\t"      \
+  "preceu.ph.qbr    %[temp3],    %[temp1]                      \n\t"      \
+  "preceu.ph.qbl    %[temp1],    %[temp1]                      \n\t"      \
+  "subq.ph          %[temp2],    %[temp2],    %[temp3]         \n\t"      \
+  "subq.ph          %[temp0],    %[temp0],    %[temp1]         \n\t"      \
+  "dpa.w.ph         $ac0,        %[temp2],    %[temp2]         \n\t"      \
+  "dpa.w.ph         $ac0,        %[temp0],    %[temp0]         \n\t"
+
+#define GET_SSE(A, B, C, D)               \
+  GET_SSE_INNER(A)                        \
+  GET_SSE_INNER(B)                        \
+  GET_SSE_INNER(C)                        \
+  GET_SSE_INNER(D)
+
+static int SSE16x16(const uint8_t* a, const uint8_t* b) {
+  int count;
+  int temp0, temp1, temp2, temp3;
+  __asm__ volatile (
+    "mult   $zero,    $zero                            \n\t"
+    GET_SSE( 0 * BPS, 4 +  0 * BPS, 8 +  0 * BPS, 12 +  0 * BPS)
+    GET_SSE( 1 * BPS, 4 +  1 * BPS, 8 +  1 * BPS, 12 +  1 * BPS)
+    GET_SSE( 2 * BPS, 4 +  2 * BPS, 8 +  2 * BPS, 12 +  2 * BPS)
+    GET_SSE( 3 * BPS, 4 +  3 * BPS, 8 +  3 * BPS, 12 +  3 * BPS)
+    GET_SSE( 4 * BPS, 4 +  4 * BPS, 8 +  4 * BPS, 12 +  4 * BPS)
+    GET_SSE( 5 * BPS, 4 +  5 * BPS, 8 +  5 * BPS, 12 +  5 * BPS)
+    GET_SSE( 6 * BPS, 4 +  6 * BPS, 8 +  6 * BPS, 12 +  6 * BPS)
+    GET_SSE( 7 * BPS, 4 +  7 * BPS, 8 +  7 * BPS, 12 +  7 * BPS)
+    GET_SSE( 8 * BPS, 4 +  8 * BPS, 8 +  8 * BPS, 12 +  8 * BPS)
+    GET_SSE( 9 * BPS, 4 +  9 * BPS, 8 +  9 * BPS, 12 +  9 * BPS)
+    GET_SSE(10 * BPS, 4 + 10 * BPS, 8 + 10 * BPS, 12 + 10 * BPS)
+    GET_SSE(11 * BPS, 4 + 11 * BPS, 8 + 11 * BPS, 12 + 11 * BPS)
+    GET_SSE(12 * BPS, 4 + 12 * BPS, 8 + 12 * BPS, 12 + 12 * BPS)
+    GET_SSE(13 * BPS, 4 + 13 * BPS, 8 + 13 * BPS, 12 + 13 * BPS)
+    GET_SSE(14 * BPS, 4 + 14 * BPS, 8 + 14 * BPS, 12 + 14 * BPS)
+    GET_SSE(15 * BPS, 4 + 15 * BPS, 8 + 15 * BPS, 12 + 15 * BPS)
+    "mflo   %[count]                                   \n\t"
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [temp3]"=&r"(temp3), [count]"=&r"(count)
+    : [a]"r"(a), [b]"r"(b)
+    : "memory", "hi", "lo"
+  );
+  return count;
+}
+
+static int SSE16x8(const uint8_t* a, const uint8_t* b) {
+  int count;
+  int temp0, temp1, temp2, temp3;
+  __asm__ volatile (
+    "mult   $zero,    $zero                            \n\t"
+    GET_SSE( 0 * BPS, 4 +  0 * BPS, 8 +  0 * BPS, 12 +  0 * BPS)
+    GET_SSE( 1 * BPS, 4 +  1 * BPS, 8 +  1 * BPS, 12 +  1 * BPS)
+    GET_SSE( 2 * BPS, 4 +  2 * BPS, 8 +  2 * BPS, 12 +  2 * BPS)
+    GET_SSE( 3 * BPS, 4 +  3 * BPS, 8 +  3 * BPS, 12 +  3 * BPS)
+    GET_SSE( 4 * BPS, 4 +  4 * BPS, 8 +  4 * BPS, 12 +  4 * BPS)
+    GET_SSE( 5 * BPS, 4 +  5 * BPS, 8 +  5 * BPS, 12 +  5 * BPS)
+    GET_SSE( 6 * BPS, 4 +  6 * BPS, 8 +  6 * BPS, 12 +  6 * BPS)
+    GET_SSE( 7 * BPS, 4 +  7 * BPS, 8 +  7 * BPS, 12 +  7 * BPS)
+    "mflo   %[count]                                   \n\t"
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [temp3]"=&r"(temp3), [count]"=&r"(count)
+    : [a]"r"(a), [b]"r"(b)
+    : "memory", "hi", "lo"
+  );
+  return count;
+}
+
+static int SSE8x8(const uint8_t* a, const uint8_t* b) {
+  int count;
+  int temp0, temp1, temp2, temp3;
+  __asm__ volatile (
+    "mult   $zero,    $zero                            \n\t"
+    GET_SSE(0 * BPS, 4 + 0 * BPS, 1 * BPS, 4 + 1 * BPS)
+    GET_SSE(2 * BPS, 4 + 2 * BPS, 3 * BPS, 4 + 3 * BPS)
+    GET_SSE(4 * BPS, 4 + 4 * BPS, 5 * BPS, 4 + 5 * BPS)
+    GET_SSE(6 * BPS, 4 + 6 * BPS, 7 * BPS, 4 + 7 * BPS)
+    "mflo   %[count]                                   \n\t"
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [temp3]"=&r"(temp3), [count]"=&r"(count)
+    : [a]"r"(a), [b]"r"(b)
+    : "memory", "hi", "lo"
+  );
+  return count;
+}
+
+static int SSE4x4(const uint8_t* a, const uint8_t* b) {
+  int count;
+  int temp0, temp1, temp2, temp3;
+  __asm__ volatile (
+    "mult   $zero,    $zero                            \n\t"
+    GET_SSE(0 * BPS, 1 * BPS, 2 * BPS, 3 * BPS)
+    "mflo   %[count]                                   \n\t"
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [temp3]"=&r"(temp3), [count]"=&r"(count)
+    : [a]"r"(a), [b]"r"(b)
+    : "memory", "hi", "lo"
+  );
+  return count;
+}
+
+#undef GET_SSE
+#undef GET_SSE_INNER
+
+#endif  // !WORK_AROUND_GCC
+
+#undef FILL_8_OR_16
+#undef FILL_PART
+#undef OUTPUT_EARLY_CLOBBER_REGS_17
+#undef MUL_HALF
+#undef ABS_X8
+#undef ADD_SUB_HALVES_X4
+
+//------------------------------------------------------------------------------
+// Quantization
+//
+
+// macro for one pass through for loop in QuantizeBlock reading 2 values at time
+// QUANTDIV macro inlined
+// J - offset in bytes (kZigzag[n] * 2)
+// K - offset in bytes (kZigzag[n] * 4)
+// N - offset in bytes (n * 2)
+// N1 - offset in bytes ((n + 1) * 2)
+#define QUANTIZE_ONE(J, K, N, N1)                                         \
+  "ulw         %[temp1],     "#J"(%[ppin])                   \n\t"        \
+  "ulw         %[temp2],     "#J"(%[ppsharpen])              \n\t"        \
+  "lhu         %[temp3],     "#K"(%[ppzthresh])              \n\t"        \
+  "lhu         %[temp6],     "#K"+4(%[ppzthresh])            \n\t"        \
+  "absq_s.ph   %[temp4],     %[temp1]                        \n\t"        \
+  "ins         %[temp3],     %[temp6],         16,       16  \n\t"        \
+  "addu.ph     %[coeff],     %[temp4],         %[temp2]      \n\t"        \
+  "shra.ph     %[sign],      %[temp1],         15            \n\t"        \
+  "li          %[level],     0x10001                         \n\t"        \
+  "cmp.lt.ph   %[temp3],     %[coeff]                        \n\t"        \
+  "lhu         %[temp1],     "#J"(%[ppiq])                   \n\t"        \
+  "pick.ph     %[temp5],     %[level],         $0            \n\t"        \
+  "lw          %[temp2],     "#K"(%[ppbias])                 \n\t"        \
+  "beqz        %[temp5],     0f                              \n\t"        \
+  "lhu         %[temp3],     "#J"(%[ppq])                    \n\t"        \
+  "beq         %[temp5],     %[level],         1f            \n\t"        \
+  "andi        %[temp5],     %[temp5],         0x1           \n\t"        \
+  "andi        %[temp4],     %[coeff],         0xffff        \n\t"        \
+  "beqz        %[temp5],     2f                              \n\t"        \
+  "mul         %[level],     %[temp4],         %[temp1]      \n\t"        \
+  "sh          $0,           "#J"+2(%[ppin])                 \n\t"        \
+  "sh          $0,           "#N1"(%[pout])                  \n\t"        \
+  "addu        %[level],     %[level],         %[temp2]      \n\t"        \
+  "sra         %[level],     %[level],         17            \n\t"        \
+  "slt         %[temp4],     %[max_level],     %[level]      \n\t"        \
+  "movn        %[level],     %[max_level],     %[temp4]      \n\t"        \
+  "andi        %[temp6],     %[sign],          0xffff        \n\t"        \
+  "xor         %[level],     %[level],         %[temp6]      \n\t"        \
+  "subu        %[level],     %[level],         %[temp6]      \n\t"        \
+  "mul         %[temp5],     %[level],         %[temp3]      \n\t"        \
+  "or          %[ret],       %[ret],           %[level]      \n\t"        \
+  "sh          %[level],     "#N"(%[pout])                   \n\t"        \
+  "sh          %[temp5],     "#J"(%[ppin])                   \n\t"        \
+  "j           3f                                            \n\t"        \
+"2:                                                          \n\t"        \
+  "lhu         %[temp1],     "#J"+2(%[ppiq])                 \n\t"        \
+  "srl         %[temp5],     %[coeff],         16            \n\t"        \
+  "mul         %[level],     %[temp5],         %[temp1]      \n\t"        \
+  "lw          %[temp2],     "#K"+4(%[ppbias])               \n\t"        \
+  "lhu         %[temp3],     "#J"+2(%[ppq])                  \n\t"        \
+  "addu        %[level],     %[level],         %[temp2]      \n\t"        \
+  "sra         %[level],     %[level],         17            \n\t"        \
+  "srl         %[temp6],     %[sign],          16            \n\t"        \
+  "slt         %[temp4],     %[max_level],     %[level]      \n\t"        \
+  "movn        %[level],     %[max_level],     %[temp4]      \n\t"        \
+  "xor         %[level],     %[level],         %[temp6]      \n\t"        \
+  "subu        %[level],     %[level],         %[temp6]      \n\t"        \
+  "mul         %[temp5],     %[level],         %[temp3]      \n\t"        \
+  "sh          $0,           "#J"(%[ppin])                   \n\t"        \
+  "sh          $0,           "#N"(%[pout])                   \n\t"        \
+  "or          %[ret],       %[ret],           %[level]      \n\t"        \
+  "sh          %[temp5],     "#J"+2(%[ppin])                 \n\t"        \
+  "sh          %[level],     "#N1"(%[pout])                  \n\t"        \
+  "j           3f                                            \n\t"        \
+"1:                                                          \n\t"        \
+  "lhu         %[temp1],     "#J"(%[ppiq])                   \n\t"        \
+  "lw          %[temp2],     "#K"(%[ppbias])                 \n\t"        \
+  "ulw         %[temp3],     "#J"(%[ppq])                    \n\t"        \
+  "andi        %[temp5],     %[coeff],         0xffff        \n\t"        \
+  "srl         %[temp0],     %[coeff],         16            \n\t"        \
+  "lhu         %[temp6],     "#J"+2(%[ppiq])                 \n\t"        \
+  "lw          %[coeff],     "#K"+4(%[ppbias])               \n\t"        \
+  "mul         %[level],     %[temp5],         %[temp1]      \n\t"        \
+  "mul         %[temp4],     %[temp0],         %[temp6]      \n\t"        \
+  "addu        %[level],     %[level],         %[temp2]      \n\t"        \
+  "addu        %[temp4],     %[temp4],         %[coeff]      \n\t"        \
+  "precrq.ph.w %[level],     %[temp4],         %[level]      \n\t"        \
+  "shra.ph     %[level],     %[level],         1             \n\t"        \
+  "cmp.lt.ph   %[max_level1],%[level]                        \n\t"        \
+  "pick.ph     %[level],     %[max_level],     %[level]      \n\t"        \
+  "xor         %[level],     %[level],         %[sign]       \n\t"        \
+  "subu.ph     %[level],     %[level],         %[sign]       \n\t"        \
+  "mul.ph      %[temp3],     %[level],         %[temp3]      \n\t"        \
+  "or          %[ret],       %[ret],           %[level]      \n\t"        \
+  "sh          %[level],     "#N"(%[pout])                   \n\t"        \
+  "srl         %[level],     %[level],         16            \n\t"        \
+  "sh          %[level],     "#N1"(%[pout])                  \n\t"        \
+  "usw         %[temp3],     "#J"(%[ppin])                   \n\t"        \
+  "j           3f                                            \n\t"        \
+"0:                                                          \n\t"        \
+  "sh          $0,           "#N"(%[pout])                   \n\t"        \
+  "sh          $0,           "#N1"(%[pout])                  \n\t"        \
+  "usw         $0,           "#J"(%[ppin])                   \n\t"        \
+"3:                                                          \n\t"
+
+static int QuantizeBlock(int16_t in[16], int16_t out[16],
+                         const VP8Matrix* const mtx) {
+  int temp0, temp1, temp2, temp3, temp4, temp5,temp6;
+  int sign, coeff, level;
+  int max_level = MAX_LEVEL;
+  int max_level1 = max_level << 16 | max_level;
+  int ret = 0;
+
+  int16_t* ppin             = &in[0];
+  int16_t* pout             = &out[0];
+  const uint16_t* ppsharpen = &mtx->sharpen_[0];
+  const uint32_t* ppzthresh = &mtx->zthresh_[0];
+  const uint16_t* ppq       = &mtx->q_[0];
+  const uint16_t* ppiq      = &mtx->iq_[0];
+  const uint32_t* ppbias    = &mtx->bias_[0];
+
+  __asm__ volatile (
+    QUANTIZE_ONE( 0,  0,  0,  2)
+    QUANTIZE_ONE( 4,  8, 10, 12)
+    QUANTIZE_ONE( 8, 16,  4,  8)
+    QUANTIZE_ONE(12, 24, 14, 24)
+    QUANTIZE_ONE(16, 32,  6, 16)
+    QUANTIZE_ONE(20, 40, 22, 26)
+    QUANTIZE_ONE(24, 48, 18, 20)
+    QUANTIZE_ONE(28, 56, 28, 30)
+
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),
+      [temp2]"=&r"(temp2), [temp3]"=&r"(temp3),
+      [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+      [sign]"=&r"(sign), [coeff]"=&r"(coeff),
+      [level]"=&r"(level), [temp6]"=&r"(temp6), [ret]"+&r"(ret)
+    : [ppin]"r"(ppin), [pout]"r"(pout), [max_level1]"r"(max_level1),
+      [ppiq]"r"(ppiq), [max_level]"r"(max_level),
+      [ppbias]"r"(ppbias), [ppzthresh]"r"(ppzthresh),
+      [ppsharpen]"r"(ppsharpen), [ppq]"r"(ppq)
+    : "memory", "hi", "lo"
+  );
+
+  return (ret != 0);
+}
+
+static int Quantize2Blocks(int16_t in[32], int16_t out[32],
+                           const VP8Matrix* const mtx) {
+  int nz;
+  nz  = QuantizeBlock(in + 0 * 16, out + 0 * 16, mtx) << 0;
+  nz |= QuantizeBlock(in + 1 * 16, out + 1 * 16, mtx) << 1;
+  return nz;
+}
+
+#undef QUANTIZE_ONE
+
+// macro for one horizontal pass in FTransformWHT
+// temp0..temp7 holds tmp[0]..tmp[15]
+// A, B, C, D - offset in bytes to load from in buffer
+// TEMP0, TEMP1 - registers for corresponding tmp elements
+#define HORIZONTAL_PASS_WHT(A, B, C, D, TEMP0, TEMP1)                          \
+  "lh              %["#TEMP0"],  "#A"(%[in])                \n\t"              \
+  "lh              %["#TEMP1"],  "#B"(%[in])                \n\t"              \
+  "lh              %[temp8],     "#C"(%[in])                \n\t"              \
+  "lh              %[temp9],     "#D"(%[in])                \n\t"              \
+  "ins             %["#TEMP1"],  %["#TEMP0"],  16,  16      \n\t"              \
+  "ins             %[temp9],     %[temp8],     16,  16      \n\t"              \
+  "subq.ph         %[temp8],     %["#TEMP1"],  %[temp9]     \n\t"              \
+  "addq.ph         %[temp9],     %["#TEMP1"],  %[temp9]     \n\t"              \
+  "precrq.ph.w     %["#TEMP0"],  %[temp8],     %[temp9]     \n\t"              \
+  "append          %[temp8],     %[temp9],     16           \n\t"              \
+  "subq.ph         %["#TEMP1"],  %["#TEMP0"],  %[temp8]     \n\t"              \
+  "addq.ph         %["#TEMP0"],  %["#TEMP0"],  %[temp8]     \n\t"              \
+  "rotr            %["#TEMP1"],  %["#TEMP1"],  16           \n\t"
+
+// macro for one vertical pass in FTransformWHT
+// temp0..temp7 holds tmp[0]..tmp[15]
+// A, B, C, D - offsets in bytes to store to out buffer
+// TEMP0, TEMP2, TEMP4 and TEMP6 - registers for corresponding tmp elements
+#define VERTICAL_PASS_WHT(A, B, C, D, TEMP0, TEMP2, TEMP4, TEMP6)              \
+  "addq.ph         %[temp8],     %["#TEMP0"],  %["#TEMP4"]  \n\t"              \
+  "addq.ph         %[temp9],     %["#TEMP2"],  %["#TEMP6"]  \n\t"              \
+  "subq.ph         %["#TEMP2"],  %["#TEMP2"],  %["#TEMP6"]  \n\t"              \
+  "subq.ph         %["#TEMP6"],  %["#TEMP0"],  %["#TEMP4"]  \n\t"              \
+  "addqh.ph        %["#TEMP0"],  %[temp8],     %[temp9]     \n\t"              \
+  "subqh.ph        %["#TEMP4"],  %["#TEMP6"],  %["#TEMP2"]  \n\t"              \
+  "addqh.ph        %["#TEMP2"],  %["#TEMP2"],  %["#TEMP6"]  \n\t"              \
+  "subqh.ph        %["#TEMP6"],  %[temp8],     %[temp9]     \n\t"              \
+  "usw             %["#TEMP0"],  "#A"(%[out])               \n\t"              \
+  "usw             %["#TEMP2"],  "#B"(%[out])               \n\t"              \
+  "usw             %["#TEMP4"],  "#C"(%[out])               \n\t"              \
+  "usw             %["#TEMP6"],  "#D"(%[out])               \n\t"
+
+static void FTransformWHT(const int16_t* in, int16_t* out) {
+  int temp0, temp1, temp2, temp3, temp4;
+  int temp5, temp6, temp7, temp8, temp9;
+
+  __asm__ volatile (
+    HORIZONTAL_PASS_WHT(  0,  32,  64,  96, temp0, temp1)
+    HORIZONTAL_PASS_WHT(128, 160, 192, 224, temp2, temp3)
+    HORIZONTAL_PASS_WHT(256, 288, 320, 352, temp4, temp5)
+    HORIZONTAL_PASS_WHT(384, 416, 448, 480, temp6, temp7)
+    VERTICAL_PASS_WHT(0,  8, 16, 24, temp0, temp2, temp4, temp6)
+    VERTICAL_PASS_WHT(4, 12, 20, 28, temp1, temp3, temp5, temp7)
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+      [temp6]"=&r"(temp6), [temp7]"=&r"(temp7), [temp8]"=&r"(temp8),
+      [temp9]"=&r"(temp9)
+    : [in]"r"(in), [out]"r"(out)
+    : "memory"
+  );
+}
+
+#undef VERTICAL_PASS_WHT
+#undef HORIZONTAL_PASS_WHT
+
+// macro for converting coefficients to bin
+// convert 8 coeffs at time
+// A, B, C, D - offsets in bytes to load from out buffer
+#define CONVERT_COEFFS_TO_BIN(A, B, C, D)                                      \
+  "ulw        %[temp0],  "#A"(%[out])                  \n\t"                   \
+  "ulw        %[temp1],  "#B"(%[out])                  \n\t"                   \
+  "ulw        %[temp2],  "#C"(%[out])                  \n\t"                   \
+  "ulw        %[temp3],  "#D"(%[out])                  \n\t"                   \
+  "absq_s.ph  %[temp0],  %[temp0]                      \n\t"                   \
+  "absq_s.ph  %[temp1],  %[temp1]                      \n\t"                   \
+  "absq_s.ph  %[temp2],  %[temp2]                      \n\t"                   \
+  "absq_s.ph  %[temp3],  %[temp3]                      \n\t"                   \
+  /* TODO(skal): add rounding ? shra_r.ph : shra.ph */                         \
+  /*             for following 4 instructions       */                         \
+  "shra.ph    %[temp0],  %[temp0],    3                \n\t"                   \
+  "shra.ph    %[temp1],  %[temp1],    3                \n\t"                   \
+  "shra.ph    %[temp2],  %[temp2],    3                \n\t"                   \
+  "shra.ph    %[temp3],  %[temp3],    3                \n\t"                   \
+  "shll_s.ph  %[temp0],  %[temp0],    10               \n\t"                   \
+  "shll_s.ph  %[temp1],  %[temp1],    10               \n\t"                   \
+  "shll_s.ph  %[temp2],  %[temp2],    10               \n\t"                   \
+  "shll_s.ph  %[temp3],  %[temp3],    10               \n\t"                   \
+  "shrl.ph    %[temp0],  %[temp0],    10               \n\t"                   \
+  "shrl.ph    %[temp1],  %[temp1],    10               \n\t"                   \
+  "shrl.ph    %[temp2],  %[temp2],    10               \n\t"                   \
+  "shrl.ph    %[temp3],  %[temp3],    10               \n\t"                   \
+  "shll.ph    %[temp0],  %[temp0],    2                \n\t"                   \
+  "shll.ph    %[temp1],  %[temp1],    2                \n\t"                   \
+  "shll.ph    %[temp2],  %[temp2],    2                \n\t"                   \
+  "shll.ph    %[temp3],  %[temp3],    2                \n\t"                   \
+  "ext        %[temp4],  %[temp0],    0,       16      \n\t"                   \
+  "ext        %[temp0],  %[temp0],    16,      16      \n\t"                   \
+  "addu       %[temp4],  %[temp4],    %[dist]          \n\t"                   \
+  "addu       %[temp0],  %[temp0],    %[dist]          \n\t"                   \
+  "ext        %[temp5],  %[temp1],    0,       16      \n\t"                   \
+  "lw         %[temp8],  0(%[temp4])                   \n\t"                   \
+  "ext        %[temp1],  %[temp1],    16,      16      \n\t"                   \
+  "addu       %[temp5],  %[temp5],    %[dist]          \n\t"                   \
+  "addiu      %[temp8],  %[temp8],    1                \n\t"                   \
+  "sw         %[temp8],  0(%[temp4])                   \n\t"                   \
+  "lw         %[temp8],  0(%[temp0])                   \n\t"                   \
+  "addu       %[temp1],  %[temp1],    %[dist]          \n\t"                   \
+  "ext        %[temp6],  %[temp2],    0,       16      \n\t"                   \
+  "addiu      %[temp8],  %[temp8],    1                \n\t"                   \
+  "sw         %[temp8],  0(%[temp0])                   \n\t"                   \
+  "lw         %[temp8],  0(%[temp5])                   \n\t"                   \
+  "ext        %[temp2],  %[temp2],    16,      16      \n\t"                   \
+  "addu       %[temp6],  %[temp6],    %[dist]          \n\t"                   \
+  "addiu      %[temp8],  %[temp8],    1                \n\t"                   \
+  "sw         %[temp8],  0(%[temp5])                   \n\t"                   \
+  "lw         %[temp8],  0(%[temp1])                   \n\t"                   \
+  "addu       %[temp2],  %[temp2],    %[dist]          \n\t"                   \
+  "ext        %[temp7],  %[temp3],    0,       16      \n\t"                   \
+  "addiu      %[temp8],  %[temp8],    1                \n\t"                   \
+  "sw         %[temp8],  0(%[temp1])                   \n\t"                   \
+  "lw         %[temp8],  0(%[temp6])                   \n\t"                   \
+  "ext        %[temp3],  %[temp3],    16,      16      \n\t"                   \
+  "addu       %[temp7],  %[temp7],    %[dist]          \n\t"                   \
+  "addiu      %[temp8],  %[temp8],    1                \n\t"                   \
+  "sw         %[temp8],  0(%[temp6])                   \n\t"                   \
+  "lw         %[temp8],  0(%[temp2])                   \n\t"                   \
+  "addu       %[temp3],  %[temp3],    %[dist]          \n\t"                   \
+  "addiu      %[temp8],  %[temp8],    1                \n\t"                   \
+  "sw         %[temp8],  0(%[temp2])                   \n\t"                   \
+  "lw         %[temp8],  0(%[temp7])                   \n\t"                   \
+  "addiu      %[temp8],  %[temp8],    1                \n\t"                   \
+  "sw         %[temp8],  0(%[temp7])                   \n\t"                   \
+  "lw         %[temp8],  0(%[temp3])                   \n\t"                   \
+  "addiu      %[temp8],  %[temp8],    1                \n\t"                   \
+  "sw         %[temp8],  0(%[temp3])                   \n\t"
+
+static void CollectHistogram(const uint8_t* ref, const uint8_t* pred,
+                             int start_block, int end_block,
+                             VP8Histogram* const histo) {
+  int j;
+  int distribution[MAX_COEFF_THRESH + 1] = { 0 };
+  const int max_coeff = (MAX_COEFF_THRESH << 16) + MAX_COEFF_THRESH;
+  for (j = start_block; j < end_block; ++j) {
+    int16_t out[16];
+    int temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8;
+
+    VP8FTransform(ref + VP8DspScan[j], pred + VP8DspScan[j], out);
+
+    // Convert coefficients to bin.
+    __asm__ volatile (
+      CONVERT_COEFFS_TO_BIN( 0,  4,  8, 12)
+      CONVERT_COEFFS_TO_BIN(16, 20, 24, 28)
+      : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+        [temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+        [temp6]"=&r"(temp6), [temp7]"=&r"(temp7), [temp8]"=&r"(temp8)
+      : [dist]"r"(distribution), [out]"r"(out), [max_coeff]"r"(max_coeff)
+      : "memory"
+    );
+  }
+  VP8LSetHistogramData(distribution, histo);
+}
+
+#undef CONVERT_COEFFS_TO_BIN
+
+#endif  // WEBP_USE_MIPS_DSP_R2
+
+//------------------------------------------------------------------------------
+// Entry point
+
+extern void VP8EncDspInitMIPSdspR2(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspInitMIPSdspR2(void) {
+#if defined(WEBP_USE_MIPS_DSP_R2)
+  VP8FTransform = FTransform;
+  VP8ITransform = ITransform;
+  VP8TDisto4x4 = Disto4x4;
+  VP8TDisto16x16 = Disto16x16;
+  VP8EncPredLuma16 = Intra16Preds;
+  VP8EncPredChroma8 = IntraChromaPreds;
+  VP8EncPredLuma4 = Intra4Preds;
+#if !defined(WORK_AROUND_GCC)
+  VP8SSE16x16 = SSE16x16;
+  VP8SSE8x8 = SSE8x8;
+  VP8SSE16x8 = SSE16x8;
+  VP8SSE4x4 = SSE4x4;
+#endif
+  VP8EncQuantizeBlock = QuantizeBlock;
+  VP8EncQuantize2Blocks = Quantize2Blocks;
+  VP8FTransformWHT = FTransformWHT;
+  VP8CollectHistogram = CollectHistogram;
+#endif  // WEBP_USE_MIPS_DSP_R2
+}
diff --git a/Source/LibWebP/src/dsp/dsp.enc_neon.c b/Source/LibWebP/src/dsp/dsp.enc_neon.c
new file mode 100644
index 0000000..1e64b57
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.enc_neon.c
@@ -0,0 +1,932 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// ARM NEON version of speed-critical encoding functions.
+//
+// adapted from libvpx (http://www.webmproject.org/code/)
+
+#include "./dsp.h"
+
+#if defined(WEBP_USE_NEON)
+
+#include <assert.h>
+
+#include "./neon.h"
+#include "../enc/vp8enci.h"
+
+//------------------------------------------------------------------------------
+// Transforms (Paragraph 14.4)
+
+// Inverse transform.
+// This code is pretty much the same as TransformOne in the dec_neon.c, except
+// for subtraction to *ref. See the comments there for algorithmic explanations.
+
+static const int16_t kC1 = 20091;
+static const int16_t kC2 = 17734;  // half of kC2, actually. See comment above.
+
+// This code works but is *slower* than the inlined-asm version below
+// (with gcc-4.6). So we disable it for now. Later, it'll be conditional to
+// WEBP_USE_INTRINSICS define.
+// With gcc-4.8, it's a little faster speed than inlined-assembly.
+#if defined(WEBP_USE_INTRINSICS)
+
+// Treats 'v' as an uint8x8_t and zero extends to an int16x8_t.
+static WEBP_INLINE int16x8_t ConvertU8ToS16(uint32x2_t v) {
+  return vreinterpretq_s16_u16(vmovl_u8(vreinterpret_u8_u32(v)));
+}
+
+// Performs unsigned 8b saturation on 'dst01' and 'dst23' storing the result
+// to the corresponding rows of 'dst'.
+static WEBP_INLINE void SaturateAndStore4x4(uint8_t* const dst,
+                                            const int16x8_t dst01,
+                                            const int16x8_t dst23) {
+  // Unsigned saturate to 8b.
+  const uint8x8_t dst01_u8 = vqmovun_s16(dst01);
+  const uint8x8_t dst23_u8 = vqmovun_s16(dst23);
+
+  // Store the results.
+  vst1_lane_u32((uint32_t*)(dst + 0 * BPS), vreinterpret_u32_u8(dst01_u8), 0);
+  vst1_lane_u32((uint32_t*)(dst + 1 * BPS), vreinterpret_u32_u8(dst01_u8), 1);
+  vst1_lane_u32((uint32_t*)(dst + 2 * BPS), vreinterpret_u32_u8(dst23_u8), 0);
+  vst1_lane_u32((uint32_t*)(dst + 3 * BPS), vreinterpret_u32_u8(dst23_u8), 1);
+}
+
+static WEBP_INLINE void Add4x4(const int16x8_t row01, const int16x8_t row23,
+                               const uint8_t* const ref, uint8_t* const dst) {
+  uint32x2_t dst01 = vdup_n_u32(0);
+  uint32x2_t dst23 = vdup_n_u32(0);
+
+  // Load the source pixels.
+  dst01 = vld1_lane_u32((uint32_t*)(ref + 0 * BPS), dst01, 0);
+  dst23 = vld1_lane_u32((uint32_t*)(ref + 2 * BPS), dst23, 0);
+  dst01 = vld1_lane_u32((uint32_t*)(ref + 1 * BPS), dst01, 1);
+  dst23 = vld1_lane_u32((uint32_t*)(ref + 3 * BPS), dst23, 1);
+
+  {
+    // Convert to 16b.
+    const int16x8_t dst01_s16 = ConvertU8ToS16(dst01);
+    const int16x8_t dst23_s16 = ConvertU8ToS16(dst23);
+
+    // Descale with rounding.
+    const int16x8_t out01 = vrsraq_n_s16(dst01_s16, row01, 3);
+    const int16x8_t out23 = vrsraq_n_s16(dst23_s16, row23, 3);
+    // Add the inverse transform.
+    SaturateAndStore4x4(dst, out01, out23);
+  }
+}
+
+static WEBP_INLINE void Transpose8x2(const int16x8_t in0, const int16x8_t in1,
+                                     int16x8x2_t* const out) {
+  // a0 a1 a2 a3 | b0 b1 b2 b3   => a0 b0 c0 d0 | a1 b1 c1 d1
+  // c0 c1 c2 c3 | d0 d1 d2 d3      a2 b2 c2 d2 | a3 b3 c3 d3
+  const int16x8x2_t tmp0 = vzipq_s16(in0, in1);   // a0 c0 a1 c1 a2 c2 ...
+                                                  // b0 d0 b1 d1 b2 d2 ...
+  *out = vzipq_s16(tmp0.val[0], tmp0.val[1]);
+}
+
+static WEBP_INLINE void TransformPass(int16x8x2_t* const rows) {
+  // {rows} = in0 | in4
+  //          in8 | in12
+  // B1 = in4 | in12
+  const int16x8_t B1 =
+      vcombine_s16(vget_high_s16(rows->val[0]), vget_high_s16(rows->val[1]));
+  // C0 = kC1 * in4 | kC1 * in12
+  // C1 = kC2 * in4 | kC2 * in12
+  const int16x8_t C0 = vsraq_n_s16(B1, vqdmulhq_n_s16(B1, kC1), 1);
+  const int16x8_t C1 = vqdmulhq_n_s16(B1, kC2);
+  const int16x4_t a = vqadd_s16(vget_low_s16(rows->val[0]),
+                                vget_low_s16(rows->val[1]));   // in0 + in8
+  const int16x4_t b = vqsub_s16(vget_low_s16(rows->val[0]),
+                                vget_low_s16(rows->val[1]));   // in0 - in8
+  // c = kC2 * in4 - kC1 * in12
+  // d = kC1 * in4 + kC2 * in12
+  const int16x4_t c = vqsub_s16(vget_low_s16(C1), vget_high_s16(C0));
+  const int16x4_t d = vqadd_s16(vget_low_s16(C0), vget_high_s16(C1));
+  const int16x8_t D0 = vcombine_s16(a, b);      // D0 = a | b
+  const int16x8_t D1 = vcombine_s16(d, c);      // D1 = d | c
+  const int16x8_t E0 = vqaddq_s16(D0, D1);      // a+d | b+c
+  const int16x8_t E_tmp = vqsubq_s16(D0, D1);   // a-d | b-c
+  const int16x8_t E1 = vcombine_s16(vget_high_s16(E_tmp), vget_low_s16(E_tmp));
+  Transpose8x2(E0, E1, rows);
+}
+
+static void ITransformOne(const uint8_t* ref,
+                          const int16_t* in, uint8_t* dst) {
+  int16x8x2_t rows;
+  INIT_VECTOR2(rows, vld1q_s16(in + 0), vld1q_s16(in + 8));
+  TransformPass(&rows);
+  TransformPass(&rows);
+  Add4x4(rows.val[0], rows.val[1], ref, dst);
+}
+
+#else
+
+static void ITransformOne(const uint8_t* ref,
+                          const int16_t* in, uint8_t* dst) {
+  const int kBPS = BPS;
+  const int16_t kC1C2[] = { kC1, kC2, 0, 0 };
+
+  __asm__ volatile (
+    "vld1.16         {q1, q2}, [%[in]]           \n"
+    "vld1.16         {d0}, [%[kC1C2]]            \n"
+
+    // d2: in[0]
+    // d3: in[8]
+    // d4: in[4]
+    // d5: in[12]
+    "vswp            d3, d4                      \n"
+
+    // q8 = {in[4], in[12]} * kC1 * 2 >> 16
+    // q9 = {in[4], in[12]} * kC2 >> 16
+    "vqdmulh.s16     q8, q2, d0[0]               \n"
+    "vqdmulh.s16     q9, q2, d0[1]               \n"
+
+    // d22 = a = in[0] + in[8]
+    // d23 = b = in[0] - in[8]
+    "vqadd.s16       d22, d2, d3                 \n"
+    "vqsub.s16       d23, d2, d3                 \n"
+
+    //  q8 = in[4]/[12] * kC1 >> 16
+    "vshr.s16        q8, q8, #1                  \n"
+
+    // Add {in[4], in[12]} back after the multiplication.
+    "vqadd.s16       q8, q2, q8                  \n"
+
+    // d20 = c = in[4]*kC2 - in[12]*kC1
+    // d21 = d = in[4]*kC1 + in[12]*kC2
+    "vqsub.s16       d20, d18, d17               \n"
+    "vqadd.s16       d21, d19, d16               \n"
+
+    // d2 = tmp[0] = a + d
+    // d3 = tmp[1] = b + c
+    // d4 = tmp[2] = b - c
+    // d5 = tmp[3] = a - d
+    "vqadd.s16       d2, d22, d21                \n"
+    "vqadd.s16       d3, d23, d20                \n"
+    "vqsub.s16       d4, d23, d20                \n"
+    "vqsub.s16       d5, d22, d21                \n"
+
+    "vzip.16         q1, q2                      \n"
+    "vzip.16         q1, q2                      \n"
+
+    "vswp            d3, d4                      \n"
+
+    // q8 = {tmp[4], tmp[12]} * kC1 * 2 >> 16
+    // q9 = {tmp[4], tmp[12]} * kC2 >> 16
+    "vqdmulh.s16     q8, q2, d0[0]               \n"
+    "vqdmulh.s16     q9, q2, d0[1]               \n"
+
+    // d22 = a = tmp[0] + tmp[8]
+    // d23 = b = tmp[0] - tmp[8]
+    "vqadd.s16       d22, d2, d3                 \n"
+    "vqsub.s16       d23, d2, d3                 \n"
+
+    "vshr.s16        q8, q8, #1                  \n"
+    "vqadd.s16       q8, q2, q8                  \n"
+
+    // d20 = c = in[4]*kC2 - in[12]*kC1
+    // d21 = d = in[4]*kC1 + in[12]*kC2
+    "vqsub.s16       d20, d18, d17               \n"
+    "vqadd.s16       d21, d19, d16               \n"
+
+    // d2 = tmp[0] = a + d
+    // d3 = tmp[1] = b + c
+    // d4 = tmp[2] = b - c
+    // d5 = tmp[3] = a - d
+    "vqadd.s16       d2, d22, d21                \n"
+    "vqadd.s16       d3, d23, d20                \n"
+    "vqsub.s16       d4, d23, d20                \n"
+    "vqsub.s16       d5, d22, d21                \n"
+
+    "vld1.32         d6[0], [%[ref]], %[kBPS]    \n"
+    "vld1.32         d6[1], [%[ref]], %[kBPS]    \n"
+    "vld1.32         d7[0], [%[ref]], %[kBPS]    \n"
+    "vld1.32         d7[1], [%[ref]], %[kBPS]    \n"
+
+    "sub         %[ref], %[ref], %[kBPS], lsl #2 \n"
+
+    // (val) + 4 >> 3
+    "vrshr.s16       d2, d2, #3                  \n"
+    "vrshr.s16       d3, d3, #3                  \n"
+    "vrshr.s16       d4, d4, #3                  \n"
+    "vrshr.s16       d5, d5, #3                  \n"
+
+    "vzip.16         q1, q2                      \n"
+    "vzip.16         q1, q2                      \n"
+
+    // Must accumulate before saturating
+    "vmovl.u8        q8, d6                      \n"
+    "vmovl.u8        q9, d7                      \n"
+
+    "vqadd.s16       q1, q1, q8                  \n"
+    "vqadd.s16       q2, q2, q9                  \n"
+
+    "vqmovun.s16     d0, q1                      \n"
+    "vqmovun.s16     d1, q2                      \n"
+
+    "vst1.32         d0[0], [%[dst]], %[kBPS]    \n"
+    "vst1.32         d0[1], [%[dst]], %[kBPS]    \n"
+    "vst1.32         d1[0], [%[dst]], %[kBPS]    \n"
+    "vst1.32         d1[1], [%[dst]]             \n"
+
+    : [in] "+r"(in), [dst] "+r"(dst)               // modified registers
+    : [kBPS] "r"(kBPS), [kC1C2] "r"(kC1C2), [ref] "r"(ref)  // constants
+    : "memory", "q0", "q1", "q2", "q8", "q9", "q10", "q11"  // clobbered
+  );
+}
+
+#endif    // WEBP_USE_INTRINSICS
+
+static void ITransform(const uint8_t* ref,
+                       const int16_t* in, uint8_t* dst, int do_two) {
+  ITransformOne(ref, in, dst);
+  if (do_two) {
+    ITransformOne(ref + 4, in + 16, dst + 4);
+  }
+}
+
+// Load all 4x4 pixels into a single uint8x16_t variable.
+static uint8x16_t Load4x4(const uint8_t* src) {
+  uint32x4_t out = vdupq_n_u32(0);
+  out = vld1q_lane_u32((const uint32_t*)(src + 0 * BPS), out, 0);
+  out = vld1q_lane_u32((const uint32_t*)(src + 1 * BPS), out, 1);
+  out = vld1q_lane_u32((const uint32_t*)(src + 2 * BPS), out, 2);
+  out = vld1q_lane_u32((const uint32_t*)(src + 3 * BPS), out, 3);
+  return vreinterpretq_u8_u32(out);
+}
+
+// Forward transform.
+
+#if defined(WEBP_USE_INTRINSICS)
+
+static WEBP_INLINE void Transpose4x4_S16(const int16x4_t A, const int16x4_t B,
+                                         const int16x4_t C, const int16x4_t D,
+                                         int16x8_t* const out01,
+                                         int16x8_t* const out32) {
+  const int16x4x2_t AB = vtrn_s16(A, B);
+  const int16x4x2_t CD = vtrn_s16(C, D);
+  const int32x2x2_t tmp02 = vtrn_s32(vreinterpret_s32_s16(AB.val[0]),
+                                     vreinterpret_s32_s16(CD.val[0]));
+  const int32x2x2_t tmp13 = vtrn_s32(vreinterpret_s32_s16(AB.val[1]),
+                                     vreinterpret_s32_s16(CD.val[1]));
+  *out01 = vreinterpretq_s16_s64(
+      vcombine_s64(vreinterpret_s64_s32(tmp02.val[0]),
+                   vreinterpret_s64_s32(tmp13.val[0])));
+  *out32 = vreinterpretq_s16_s64(
+      vcombine_s64(vreinterpret_s64_s32(tmp13.val[1]),
+                   vreinterpret_s64_s32(tmp02.val[1])));
+}
+
+static WEBP_INLINE int16x8_t DiffU8ToS16(const uint8x8_t a,
+                                         const uint8x8_t b) {
+  return vreinterpretq_s16_u16(vsubl_u8(a, b));
+}
+
+static void FTransform(const uint8_t* src, const uint8_t* ref,
+                       int16_t* out) {
+  int16x8_t d0d1, d3d2;   // working 4x4 int16 variables
+  {
+    const uint8x16_t S0 = Load4x4(src);
+    const uint8x16_t R0 = Load4x4(ref);
+    const int16x8_t D0D1 = DiffU8ToS16(vget_low_u8(S0), vget_low_u8(R0));
+    const int16x8_t D2D3 = DiffU8ToS16(vget_high_u8(S0), vget_high_u8(R0));
+    const int16x4_t D0 = vget_low_s16(D0D1);
+    const int16x4_t D1 = vget_high_s16(D0D1);
+    const int16x4_t D2 = vget_low_s16(D2D3);
+    const int16x4_t D3 = vget_high_s16(D2D3);
+    Transpose4x4_S16(D0, D1, D2, D3, &d0d1, &d3d2);
+  }
+  {    // 1rst pass
+    const int32x4_t kCst937 = vdupq_n_s32(937);
+    const int32x4_t kCst1812 = vdupq_n_s32(1812);
+    const int16x8_t a0a1 = vaddq_s16(d0d1, d3d2);   // d0+d3 | d1+d2   (=a0|a1)
+    const int16x8_t a3a2 = vsubq_s16(d0d1, d3d2);   // d0-d3 | d1-d2   (=a3|a2)
+    const int16x8_t a0a1_2 = vshlq_n_s16(a0a1, 3);
+    const int16x4_t tmp0 = vadd_s16(vget_low_s16(a0a1_2),
+                                    vget_high_s16(a0a1_2));
+    const int16x4_t tmp2 = vsub_s16(vget_low_s16(a0a1_2),
+                                    vget_high_s16(a0a1_2));
+    const int32x4_t a3_2217 = vmull_n_s16(vget_low_s16(a3a2), 2217);
+    const int32x4_t a2_2217 = vmull_n_s16(vget_high_s16(a3a2), 2217);
+    const int32x4_t a2_p_a3 = vmlal_n_s16(a2_2217, vget_low_s16(a3a2), 5352);
+    const int32x4_t a3_m_a2 = vmlsl_n_s16(a3_2217, vget_high_s16(a3a2), 5352);
+    const int16x4_t tmp1 = vshrn_n_s32(vaddq_s32(a2_p_a3, kCst1812), 9);
+    const int16x4_t tmp3 = vshrn_n_s32(vaddq_s32(a3_m_a2, kCst937), 9);
+    Transpose4x4_S16(tmp0, tmp1, tmp2, tmp3, &d0d1, &d3d2);
+  }
+  {    // 2nd pass
+    // the (1<<16) addition is for the replacement: a3!=0  <-> 1-(a3==0)
+    const int32x4_t kCst12000 = vdupq_n_s32(12000 + (1 << 16));
+    const int32x4_t kCst51000 = vdupq_n_s32(51000);
+    const int16x8_t a0a1 = vaddq_s16(d0d1, d3d2);   // d0+d3 | d1+d2   (=a0|a1)
+    const int16x8_t a3a2 = vsubq_s16(d0d1, d3d2);   // d0-d3 | d1-d2   (=a3|a2)
+    const int16x4_t a0_k7 = vadd_s16(vget_low_s16(a0a1), vdup_n_s16(7));
+    const int16x4_t out0 = vshr_n_s16(vadd_s16(a0_k7, vget_high_s16(a0a1)), 4);
+    const int16x4_t out2 = vshr_n_s16(vsub_s16(a0_k7, vget_high_s16(a0a1)), 4);
+    const int32x4_t a3_2217 = vmull_n_s16(vget_low_s16(a3a2), 2217);
+    const int32x4_t a2_2217 = vmull_n_s16(vget_high_s16(a3a2), 2217);
+    const int32x4_t a2_p_a3 = vmlal_n_s16(a2_2217, vget_low_s16(a3a2), 5352);
+    const int32x4_t a3_m_a2 = vmlsl_n_s16(a3_2217, vget_high_s16(a3a2), 5352);
+    const int16x4_t tmp1 = vaddhn_s32(a2_p_a3, kCst12000);
+    const int16x4_t out3 = vaddhn_s32(a3_m_a2, kCst51000);
+    const int16x4_t a3_eq_0 =
+        vreinterpret_s16_u16(vceq_s16(vget_low_s16(a3a2), vdup_n_s16(0)));
+    const int16x4_t out1 = vadd_s16(tmp1, a3_eq_0);
+    vst1_s16(out +  0, out0);
+    vst1_s16(out +  4, out1);
+    vst1_s16(out +  8, out2);
+    vst1_s16(out + 12, out3);
+  }
+}
+
+#else
+
+// adapted from vp8/encoder/arm/neon/shortfdct_neon.asm
+static const int16_t kCoeff16[] = {
+  5352,  5352,  5352, 5352, 2217,  2217,  2217, 2217
+};
+static const int32_t kCoeff32[] = {
+   1812,  1812,  1812,  1812,
+    937,   937,   937,   937,
+  12000, 12000, 12000, 12000,
+  51000, 51000, 51000, 51000
+};
+
+static void FTransform(const uint8_t* src, const uint8_t* ref,
+                       int16_t* out) {
+  const int kBPS = BPS;
+  const uint8_t* src_ptr = src;
+  const uint8_t* ref_ptr = ref;
+  const int16_t* coeff16 = kCoeff16;
+  const int32_t* coeff32 = kCoeff32;
+
+  __asm__ volatile (
+    // load src into q4, q5 in high half
+    "vld1.8 {d8},  [%[src_ptr]], %[kBPS]      \n"
+    "vld1.8 {d10}, [%[src_ptr]], %[kBPS]      \n"
+    "vld1.8 {d9},  [%[src_ptr]], %[kBPS]      \n"
+    "vld1.8 {d11}, [%[src_ptr]]               \n"
+
+    // load ref into q6, q7 in high half
+    "vld1.8 {d12}, [%[ref_ptr]], %[kBPS]      \n"
+    "vld1.8 {d14}, [%[ref_ptr]], %[kBPS]      \n"
+    "vld1.8 {d13}, [%[ref_ptr]], %[kBPS]      \n"
+    "vld1.8 {d15}, [%[ref_ptr]]               \n"
+
+    // Pack the high values in to q4 and q6
+    "vtrn.32     q4, q5                       \n"
+    "vtrn.32     q6, q7                       \n"
+
+    // d[0-3] = src - ref
+    "vsubl.u8    q0, d8, d12                  \n"
+    "vsubl.u8    q1, d9, d13                  \n"
+
+    // load coeff16 into q8(d16=5352, d17=2217)
+    "vld1.16     {q8}, [%[coeff16]]           \n"
+
+    // load coeff32 high half into q9 = 1812, q10 = 937
+    "vld1.32     {q9, q10}, [%[coeff32]]!     \n"
+
+    // load coeff32 low half into q11=12000, q12=51000
+    "vld1.32     {q11,q12}, [%[coeff32]]      \n"
+
+    // part 1
+    // Transpose. Register dN is the same as dN in C
+    "vtrn.32         d0, d2                   \n"
+    "vtrn.32         d1, d3                   \n"
+    "vtrn.16         d0, d1                   \n"
+    "vtrn.16         d2, d3                   \n"
+
+    "vadd.s16        d4, d0, d3               \n" // a0 = d0 + d3
+    "vadd.s16        d5, d1, d2               \n" // a1 = d1 + d2
+    "vsub.s16        d6, d1, d2               \n" // a2 = d1 - d2
+    "vsub.s16        d7, d0, d3               \n" // a3 = d0 - d3
+
+    "vadd.s16        d0, d4, d5               \n" // a0 + a1
+    "vshl.s16        d0, d0, #3               \n" // temp[0+i*4] = (a0+a1) << 3
+    "vsub.s16        d2, d4, d5               \n" // a0 - a1
+    "vshl.s16        d2, d2, #3               \n" // (temp[2+i*4] = (a0-a1) << 3
+
+    "vmlal.s16       q9, d7, d16              \n" // a3*5352 + 1812
+    "vmlal.s16       q10, d7, d17             \n" // a3*2217 + 937
+    "vmlal.s16       q9, d6, d17              \n" // a2*2217 + a3*5352 + 1812
+    "vmlsl.s16       q10, d6, d16             \n" // a3*2217 + 937 - a2*5352
+
+    // temp[1+i*4] = (d2*2217 + d3*5352 + 1812) >> 9
+    // temp[3+i*4] = (d3*2217 + 937 - d2*5352) >> 9
+    "vshrn.s32       d1, q9, #9               \n"
+    "vshrn.s32       d3, q10, #9              \n"
+
+    // part 2
+    // transpose d0=ip[0], d1=ip[4], d2=ip[8], d3=ip[12]
+    "vtrn.32         d0, d2                   \n"
+    "vtrn.32         d1, d3                   \n"
+    "vtrn.16         d0, d1                   \n"
+    "vtrn.16         d2, d3                   \n"
+
+    "vmov.s16        d26, #7                  \n"
+
+    "vadd.s16        d4, d0, d3               \n" // a1 = ip[0] + ip[12]
+    "vadd.s16        d5, d1, d2               \n" // b1 = ip[4] + ip[8]
+    "vsub.s16        d6, d1, d2               \n" // c1 = ip[4] - ip[8]
+    "vadd.s16        d4, d4, d26              \n" // a1 + 7
+    "vsub.s16        d7, d0, d3               \n" // d1 = ip[0] - ip[12]
+
+    "vadd.s16        d0, d4, d5               \n" // op[0] = a1 + b1 + 7
+    "vsub.s16        d2, d4, d5               \n" // op[8] = a1 - b1 + 7
+
+    "vmlal.s16       q11, d7, d16             \n" // d1*5352 + 12000
+    "vmlal.s16       q12, d7, d17             \n" // d1*2217 + 51000
+
+    "vceq.s16        d4, d7, #0               \n"
+
+    "vshr.s16        d0, d0, #4               \n"
+    "vshr.s16        d2, d2, #4               \n"
+
+    "vmlal.s16       q11, d6, d17             \n" // c1*2217 + d1*5352 + 12000
+    "vmlsl.s16       q12, d6, d16             \n" // d1*2217 - c1*5352 + 51000
+
+    "vmvn            d4, d4                   \n" // !(d1 == 0)
+    // op[4] = (c1*2217 + d1*5352 + 12000)>>16
+    "vshrn.s32       d1, q11, #16             \n"
+    // op[4] += (d1!=0)
+    "vsub.s16        d1, d1, d4               \n"
+    // op[12]= (d1*2217 - c1*5352 + 51000)>>16
+    "vshrn.s32       d3, q12, #16             \n"
+
+    // set result to out array
+    "vst1.16         {q0, q1}, [%[out]]   \n"
+    : [src_ptr] "+r"(src_ptr), [ref_ptr] "+r"(ref_ptr),
+      [coeff32] "+r"(coeff32)          // modified registers
+    : [kBPS] "r"(kBPS), [coeff16] "r"(coeff16),
+      [out] "r"(out)                   // constants
+    : "memory", "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9",
+      "q10", "q11", "q12", "q13"       // clobbered
+  );
+}
+
+#endif
+
+#define LOAD_LANE_16b(VALUE, LANE) do {             \
+  (VALUE) = vld1_lane_s16(src, (VALUE), (LANE));    \
+  src += stride;                                    \
+} while (0)
+
+static void FTransformWHT(const int16_t* src, int16_t* out) {
+  const int stride = 16;
+  const int16x4_t zero = vdup_n_s16(0);
+  int32x4x4_t tmp0;
+  int16x4x4_t in;
+  INIT_VECTOR4(in, zero, zero, zero, zero);
+  LOAD_LANE_16b(in.val[0], 0);
+  LOAD_LANE_16b(in.val[1], 0);
+  LOAD_LANE_16b(in.val[2], 0);
+  LOAD_LANE_16b(in.val[3], 0);
+  LOAD_LANE_16b(in.val[0], 1);
+  LOAD_LANE_16b(in.val[1], 1);
+  LOAD_LANE_16b(in.val[2], 1);
+  LOAD_LANE_16b(in.val[3], 1);
+  LOAD_LANE_16b(in.val[0], 2);
+  LOAD_LANE_16b(in.val[1], 2);
+  LOAD_LANE_16b(in.val[2], 2);
+  LOAD_LANE_16b(in.val[3], 2);
+  LOAD_LANE_16b(in.val[0], 3);
+  LOAD_LANE_16b(in.val[1], 3);
+  LOAD_LANE_16b(in.val[2], 3);
+  LOAD_LANE_16b(in.val[3], 3);
+
+  {
+    // a0 = in[0 * 16] + in[2 * 16]
+    // a1 = in[1 * 16] + in[3 * 16]
+    // a2 = in[1 * 16] - in[3 * 16]
+    // a3 = in[0 * 16] - in[2 * 16]
+    const int32x4_t a0 = vaddl_s16(in.val[0], in.val[2]);
+    const int32x4_t a1 = vaddl_s16(in.val[1], in.val[3]);
+    const int32x4_t a2 = vsubl_s16(in.val[1], in.val[3]);
+    const int32x4_t a3 = vsubl_s16(in.val[0], in.val[2]);
+    tmp0.val[0] = vaddq_s32(a0, a1);
+    tmp0.val[1] = vaddq_s32(a3, a2);
+    tmp0.val[2] = vsubq_s32(a3, a2);
+    tmp0.val[3] = vsubq_s32(a0, a1);
+  }
+  {
+    const int32x4x4_t tmp1 = Transpose4x4(tmp0);
+    // a0 = tmp[0 + i] + tmp[ 8 + i]
+    // a1 = tmp[4 + i] + tmp[12 + i]
+    // a2 = tmp[4 + i] - tmp[12 + i]
+    // a3 = tmp[0 + i] - tmp[ 8 + i]
+    const int32x4_t a0 = vaddq_s32(tmp1.val[0], tmp1.val[2]);
+    const int32x4_t a1 = vaddq_s32(tmp1.val[1], tmp1.val[3]);
+    const int32x4_t a2 = vsubq_s32(tmp1.val[1], tmp1.val[3]);
+    const int32x4_t a3 = vsubq_s32(tmp1.val[0], tmp1.val[2]);
+    const int32x4_t b0 = vhaddq_s32(a0, a1);  // (a0 + a1) >> 1
+    const int32x4_t b1 = vhaddq_s32(a3, a2);  // (a3 + a2) >> 1
+    const int32x4_t b2 = vhsubq_s32(a3, a2);  // (a3 - a2) >> 1
+    const int32x4_t b3 = vhsubq_s32(a0, a1);  // (a0 - a1) >> 1
+    const int16x4_t out0 = vmovn_s32(b0);
+    const int16x4_t out1 = vmovn_s32(b1);
+    const int16x4_t out2 = vmovn_s32(b2);
+    const int16x4_t out3 = vmovn_s32(b3);
+
+    vst1_s16(out +  0, out0);
+    vst1_s16(out +  4, out1);
+    vst1_s16(out +  8, out2);
+    vst1_s16(out + 12, out3);
+  }
+}
+#undef LOAD_LANE_16b
+
+//------------------------------------------------------------------------------
+// Texture distortion
+//
+// We try to match the spectral content (weighted) between source and
+// reconstructed samples.
+
+// a 0123, b 0123
+// a 4567, b 4567
+// a 89ab, b 89ab
+// a cdef, b cdef
+//
+// transpose
+//
+// a 048c, b 048c
+// a 159d, b 159d
+// a 26ae, b 26ae
+// a 37bf, b 37bf
+//
+static WEBP_INLINE uint8x8x4_t DistoTranspose4x4U8(uint8x8x4_t d4_in) {
+  const uint8x8x2_t d2_tmp0 = vtrn_u8(d4_in.val[0], d4_in.val[1]);
+  const uint8x8x2_t d2_tmp1 = vtrn_u8(d4_in.val[2], d4_in.val[3]);
+  const uint16x4x2_t d2_tmp2 = vtrn_u16(vreinterpret_u16_u8(d2_tmp0.val[0]),
+                                        vreinterpret_u16_u8(d2_tmp1.val[0]));
+  const uint16x4x2_t d2_tmp3 = vtrn_u16(vreinterpret_u16_u8(d2_tmp0.val[1]),
+                                        vreinterpret_u16_u8(d2_tmp1.val[1]));
+
+  d4_in.val[0] = vreinterpret_u8_u16(d2_tmp2.val[0]);
+  d4_in.val[2] = vreinterpret_u8_u16(d2_tmp2.val[1]);
+  d4_in.val[1] = vreinterpret_u8_u16(d2_tmp3.val[0]);
+  d4_in.val[3] = vreinterpret_u8_u16(d2_tmp3.val[1]);
+  return d4_in;
+}
+
+static WEBP_INLINE int16x8x4_t DistoTranspose4x4S16(int16x8x4_t q4_in) {
+  const int16x8x2_t q2_tmp0 = vtrnq_s16(q4_in.val[0], q4_in.val[1]);
+  const int16x8x2_t q2_tmp1 = vtrnq_s16(q4_in.val[2], q4_in.val[3]);
+  const int32x4x2_t q2_tmp2 = vtrnq_s32(vreinterpretq_s32_s16(q2_tmp0.val[0]),
+                                        vreinterpretq_s32_s16(q2_tmp1.val[0]));
+  const int32x4x2_t q2_tmp3 = vtrnq_s32(vreinterpretq_s32_s16(q2_tmp0.val[1]),
+                                        vreinterpretq_s32_s16(q2_tmp1.val[1]));
+  q4_in.val[0] = vreinterpretq_s16_s32(q2_tmp2.val[0]);
+  q4_in.val[2] = vreinterpretq_s16_s32(q2_tmp2.val[1]);
+  q4_in.val[1] = vreinterpretq_s16_s32(q2_tmp3.val[0]);
+  q4_in.val[3] = vreinterpretq_s16_s32(q2_tmp3.val[1]);
+  return q4_in;
+}
+
+static WEBP_INLINE int16x8x4_t DistoHorizontalPass(const uint8x8x4_t d4_in) {
+  // {a0, a1} = {in[0] + in[2], in[1] + in[3]}
+  // {a3, a2} = {in[0] - in[2], in[1] - in[3]}
+  const int16x8_t q_a0 = vreinterpretq_s16_u16(vaddl_u8(d4_in.val[0],
+                                                        d4_in.val[2]));
+  const int16x8_t q_a1 = vreinterpretq_s16_u16(vaddl_u8(d4_in.val[1],
+                                                        d4_in.val[3]));
+  const int16x8_t q_a3 = vreinterpretq_s16_u16(vsubl_u8(d4_in.val[0],
+                                                        d4_in.val[2]));
+  const int16x8_t q_a2 = vreinterpretq_s16_u16(vsubl_u8(d4_in.val[1],
+                                                        d4_in.val[3]));
+  int16x8x4_t q4_out;
+  // tmp[0] = a0 + a1
+  // tmp[1] = a3 + a2
+  // tmp[2] = a3 - a2
+  // tmp[3] = a0 - a1
+  INIT_VECTOR4(q4_out,
+               vaddq_s16(q_a0, q_a1), vaddq_s16(q_a3, q_a2),
+               vsubq_s16(q_a3, q_a2), vsubq_s16(q_a0, q_a1));
+  return q4_out;
+}
+
+static WEBP_INLINE int16x8x4_t DistoVerticalPass(int16x8x4_t q4_in) {
+  const int16x8_t q_a0 = vaddq_s16(q4_in.val[0], q4_in.val[2]);
+  const int16x8_t q_a1 = vaddq_s16(q4_in.val[1], q4_in.val[3]);
+  const int16x8_t q_a2 = vsubq_s16(q4_in.val[1], q4_in.val[3]);
+  const int16x8_t q_a3 = vsubq_s16(q4_in.val[0], q4_in.val[2]);
+
+  q4_in.val[0] = vaddq_s16(q_a0, q_a1);
+  q4_in.val[1] = vaddq_s16(q_a3, q_a2);
+  q4_in.val[2] = vabdq_s16(q_a3, q_a2);
+  q4_in.val[3] = vabdq_s16(q_a0, q_a1);
+  q4_in.val[0] = vabsq_s16(q4_in.val[0]);
+  q4_in.val[1] = vabsq_s16(q4_in.val[1]);
+  return q4_in;
+}
+
+static WEBP_INLINE int16x4x4_t DistoLoadW(const uint16_t* w) {
+  const uint16x8_t q_w07 = vld1q_u16(&w[0]);
+  const uint16x8_t q_w8f = vld1q_u16(&w[8]);
+  int16x4x4_t d4_w;
+  INIT_VECTOR4(d4_w,
+               vget_low_s16(vreinterpretq_s16_u16(q_w07)),
+               vget_high_s16(vreinterpretq_s16_u16(q_w07)),
+               vget_low_s16(vreinterpretq_s16_u16(q_w8f)),
+               vget_high_s16(vreinterpretq_s16_u16(q_w8f)));
+  return d4_w;
+}
+
+static WEBP_INLINE int32x2_t DistoSum(const int16x8x4_t q4_in,
+                                      const int16x4x4_t d4_w) {
+  int32x2_t d_sum;
+  // sum += w[ 0] * abs(b0);
+  // sum += w[ 4] * abs(b1);
+  // sum += w[ 8] * abs(b2);
+  // sum += w[12] * abs(b3);
+  int32x4_t q_sum0 = vmull_s16(d4_w.val[0], vget_low_s16(q4_in.val[0]));
+  int32x4_t q_sum1 = vmull_s16(d4_w.val[1], vget_low_s16(q4_in.val[1]));
+  int32x4_t q_sum2 = vmull_s16(d4_w.val[2], vget_low_s16(q4_in.val[2]));
+  int32x4_t q_sum3 = vmull_s16(d4_w.val[3], vget_low_s16(q4_in.val[3]));
+  q_sum0 = vmlsl_s16(q_sum0, d4_w.val[0], vget_high_s16(q4_in.val[0]));
+  q_sum1 = vmlsl_s16(q_sum1, d4_w.val[1], vget_high_s16(q4_in.val[1]));
+  q_sum2 = vmlsl_s16(q_sum2, d4_w.val[2], vget_high_s16(q4_in.val[2]));
+  q_sum3 = vmlsl_s16(q_sum3, d4_w.val[3], vget_high_s16(q4_in.val[3]));
+
+  q_sum0 = vaddq_s32(q_sum0, q_sum1);
+  q_sum2 = vaddq_s32(q_sum2, q_sum3);
+  q_sum2 = vaddq_s32(q_sum0, q_sum2);
+  d_sum = vpadd_s32(vget_low_s32(q_sum2), vget_high_s32(q_sum2));
+  d_sum = vpadd_s32(d_sum, d_sum);
+  return d_sum;
+}
+
+#define LOAD_LANE_32b(src, VALUE, LANE) \
+    (VALUE) = vld1_lane_u32((const uint32_t*)(src), (VALUE), (LANE))
+
+// Hadamard transform
+// Returns the weighted sum of the absolute value of transformed coefficients.
+static int Disto4x4(const uint8_t* const a, const uint8_t* const b,
+                    const uint16_t* const w) {
+  uint32x2_t d_in_ab_0123 = vdup_n_u32(0);
+  uint32x2_t d_in_ab_4567 = vdup_n_u32(0);
+  uint32x2_t d_in_ab_89ab = vdup_n_u32(0);
+  uint32x2_t d_in_ab_cdef = vdup_n_u32(0);
+  uint8x8x4_t d4_in;
+
+  // load data a, b
+  LOAD_LANE_32b(a + 0 * BPS, d_in_ab_0123, 0);
+  LOAD_LANE_32b(a + 1 * BPS, d_in_ab_4567, 0);
+  LOAD_LANE_32b(a + 2 * BPS, d_in_ab_89ab, 0);
+  LOAD_LANE_32b(a + 3 * BPS, d_in_ab_cdef, 0);
+  LOAD_LANE_32b(b + 0 * BPS, d_in_ab_0123, 1);
+  LOAD_LANE_32b(b + 1 * BPS, d_in_ab_4567, 1);
+  LOAD_LANE_32b(b + 2 * BPS, d_in_ab_89ab, 1);
+  LOAD_LANE_32b(b + 3 * BPS, d_in_ab_cdef, 1);
+  INIT_VECTOR4(d4_in,
+               vreinterpret_u8_u32(d_in_ab_0123),
+               vreinterpret_u8_u32(d_in_ab_4567),
+               vreinterpret_u8_u32(d_in_ab_89ab),
+               vreinterpret_u8_u32(d_in_ab_cdef));
+
+  {
+    // horizontal pass
+    const uint8x8x4_t d4_t = DistoTranspose4x4U8(d4_in);
+    const int16x8x4_t q4_h = DistoHorizontalPass(d4_t);
+    const int16x4x4_t d4_w = DistoLoadW(w);
+    // vertical pass
+    const int16x8x4_t q4_t = DistoTranspose4x4S16(q4_h);
+    const int16x8x4_t q4_v = DistoVerticalPass(q4_t);
+    int32x2_t d_sum = DistoSum(q4_v, d4_w);
+
+    // abs(sum2 - sum1) >> 5
+    d_sum = vabs_s32(d_sum);
+    d_sum  = vshr_n_s32(d_sum, 5);
+    return vget_lane_s32(d_sum, 0);
+  }
+}
+#undef LOAD_LANE_32b
+
+static int Disto16x16(const uint8_t* const a, const uint8_t* const b,
+                      const uint16_t* const w) {
+  int D = 0;
+  int x, y;
+  for (y = 0; y < 16 * BPS; y += 4 * BPS) {
+    for (x = 0; x < 16; x += 4) {
+      D += Disto4x4(a + x + y, b + x + y, w);
+    }
+  }
+  return D;
+}
+
+//------------------------------------------------------------------------------
+
+static void CollectHistogram(const uint8_t* ref, const uint8_t* pred,
+                             int start_block, int end_block,
+                             VP8Histogram* const histo) {
+  const uint16x8_t max_coeff_thresh = vdupq_n_u16(MAX_COEFF_THRESH);
+  int j;
+  int distribution[MAX_COEFF_THRESH + 1] = { 0 };
+  for (j = start_block; j < end_block; ++j) {
+    int16_t out[16];
+    FTransform(ref + VP8DspScan[j], pred + VP8DspScan[j], out);
+    {
+      int k;
+      const int16x8_t a0 = vld1q_s16(out + 0);
+      const int16x8_t b0 = vld1q_s16(out + 8);
+      const uint16x8_t a1 = vreinterpretq_u16_s16(vabsq_s16(a0));
+      const uint16x8_t b1 = vreinterpretq_u16_s16(vabsq_s16(b0));
+      const uint16x8_t a2 = vshrq_n_u16(a1, 3);
+      const uint16x8_t b2 = vshrq_n_u16(b1, 3);
+      const uint16x8_t a3 = vminq_u16(a2, max_coeff_thresh);
+      const uint16x8_t b3 = vminq_u16(b2, max_coeff_thresh);
+      vst1q_s16(out + 0, vreinterpretq_s16_u16(a3));
+      vst1q_s16(out + 8, vreinterpretq_s16_u16(b3));
+      // Convert coefficients to bin.
+      for (k = 0; k < 16; ++k) {
+        ++distribution[out[k]];
+      }
+    }
+  }
+  VP8LSetHistogramData(distribution, histo);
+}
+
+//------------------------------------------------------------------------------
+
+static WEBP_INLINE void AccumulateSSE16(const uint8_t* const a,
+                                        const uint8_t* const b,
+                                        uint32x4_t* const sum) {
+  const uint8x16_t a0 = vld1q_u8(a);
+  const uint8x16_t b0 = vld1q_u8(b);
+  const uint8x16_t abs_diff = vabdq_u8(a0, b0);
+  uint16x8_t prod = vmull_u8(vget_low_u8(abs_diff), vget_low_u8(abs_diff));
+  prod = vmlal_u8(prod, vget_high_u8(abs_diff), vget_high_u8(abs_diff));
+  *sum = vpadalq_u16(*sum, prod);      // pair-wise add and accumulate
+}
+
+// Horizontal sum of all four uint32_t values in 'sum'.
+static int SumToInt(uint32x4_t sum) {
+  const uint64x2_t sum2 = vpaddlq_u32(sum);
+  const uint64_t sum3 = vgetq_lane_u64(sum2, 0) + vgetq_lane_u64(sum2, 1);
+  return (int)sum3;
+}
+
+static int SSE16x16(const uint8_t* a, const uint8_t* b) {
+  uint32x4_t sum = vdupq_n_u32(0);
+  int y;
+  for (y = 0; y < 16; ++y) {
+    AccumulateSSE16(a + y * BPS, b + y * BPS, &sum);
+  }
+  return SumToInt(sum);
+}
+
+static int SSE16x8(const uint8_t* a, const uint8_t* b) {
+  uint32x4_t sum = vdupq_n_u32(0);
+  int y;
+  for (y = 0; y < 8; ++y) {
+    AccumulateSSE16(a + y * BPS, b + y * BPS, &sum);
+  }
+  return SumToInt(sum);
+}
+
+static int SSE8x8(const uint8_t* a, const uint8_t* b) {
+  uint32x4_t sum = vdupq_n_u32(0);
+  int y;
+  for (y = 0; y < 8; ++y) {
+    const uint8x8_t a0 = vld1_u8(a + y * BPS);
+    const uint8x8_t b0 = vld1_u8(b + y * BPS);
+    const uint8x8_t abs_diff = vabd_u8(a0, b0);
+    const uint16x8_t prod = vmull_u8(abs_diff, abs_diff);
+    sum = vpadalq_u16(sum, prod);
+  }
+  return SumToInt(sum);
+}
+
+static int SSE4x4(const uint8_t* a, const uint8_t* b) {
+  const uint8x16_t a0 = Load4x4(a);
+  const uint8x16_t b0 = Load4x4(b);
+  const uint8x16_t abs_diff = vabdq_u8(a0, b0);
+  uint16x8_t prod = vmull_u8(vget_low_u8(abs_diff), vget_low_u8(abs_diff));
+  prod = vmlal_u8(prod, vget_high_u8(abs_diff), vget_high_u8(abs_diff));
+  return SumToInt(vpaddlq_u16(prod));
+}
+
+//------------------------------------------------------------------------------
+
+// Compilation with gcc-4.6.x is problematic for now.
+#if !defined(WORK_AROUND_GCC)
+
+static int16x8_t Quantize(int16_t* const in,
+                          const VP8Matrix* const mtx, int offset) {
+  const uint16x8_t sharp = vld1q_u16(&mtx->sharpen_[offset]);
+  const uint16x8_t q = vld1q_u16(&mtx->q_[offset]);
+  const uint16x8_t iq = vld1q_u16(&mtx->iq_[offset]);
+  const uint32x4_t bias0 = vld1q_u32(&mtx->bias_[offset + 0]);
+  const uint32x4_t bias1 = vld1q_u32(&mtx->bias_[offset + 4]);
+
+  const int16x8_t a = vld1q_s16(in + offset);                // in
+  const uint16x8_t b = vreinterpretq_u16_s16(vabsq_s16(a));  // coeff = abs(in)
+  const int16x8_t sign = vshrq_n_s16(a, 15);                 // sign
+  const uint16x8_t c = vaddq_u16(b, sharp);                  // + sharpen
+  const uint32x4_t m0 = vmull_u16(vget_low_u16(c), vget_low_u16(iq));
+  const uint32x4_t m1 = vmull_u16(vget_high_u16(c), vget_high_u16(iq));
+  const uint32x4_t m2 = vhaddq_u32(m0, bias0);
+  const uint32x4_t m3 = vhaddq_u32(m1, bias1);     // (coeff * iQ + bias) >> 1
+  const uint16x8_t c0 = vcombine_u16(vshrn_n_u32(m2, 16),
+                                     vshrn_n_u32(m3, 16));   // QFIX=17 = 16+1
+  const uint16x8_t c1 = vminq_u16(c0, vdupq_n_u16(MAX_LEVEL));
+  const int16x8_t c2 = veorq_s16(vreinterpretq_s16_u16(c1), sign);
+  const int16x8_t c3 = vsubq_s16(c2, sign);                  // restore sign
+  const int16x8_t c4 = vmulq_s16(c3, vreinterpretq_s16_u16(q));
+  vst1q_s16(in + offset, c4);
+  assert(QFIX == 17);  // this function can't work as is if QFIX != 16+1
+  return c3;
+}
+
+static const uint8_t kShuffles[4][8] = {
+  { 0,   1,  2,  3,  8,  9, 16, 17 },
+  { 10, 11,  4,  5,  6,  7, 12, 13 },
+  { 18, 19, 24, 25, 26, 27, 20, 21 },
+  { 14, 15, 22, 23, 28, 29, 30, 31 }
+};
+
+static int QuantizeBlock(int16_t in[16], int16_t out[16],
+                         const VP8Matrix* const mtx) {
+  const int16x8_t out0 = Quantize(in, mtx, 0);
+  const int16x8_t out1 = Quantize(in, mtx, 8);
+  uint8x8x4_t shuffles;
+  // vtbl?_u8 are marked unavailable for iOS arm64 with Xcode < 6.3, use
+  // non-standard versions there.
+#if defined(__APPLE__) && defined(__aarch64__) && \
+    defined(__apple_build_version__) && (__apple_build_version__< 6020037)
+  uint8x16x2_t all_out;
+  INIT_VECTOR2(all_out, vreinterpretq_u8_s16(out0), vreinterpretq_u8_s16(out1));
+  INIT_VECTOR4(shuffles,
+               vtbl2q_u8(all_out, vld1_u8(kShuffles[0])),
+               vtbl2q_u8(all_out, vld1_u8(kShuffles[1])),
+               vtbl2q_u8(all_out, vld1_u8(kShuffles[2])),
+               vtbl2q_u8(all_out, vld1_u8(kShuffles[3])));
+#else
+  uint8x8x4_t all_out;
+  INIT_VECTOR4(all_out,
+               vreinterpret_u8_s16(vget_low_s16(out0)),
+               vreinterpret_u8_s16(vget_high_s16(out0)),
+               vreinterpret_u8_s16(vget_low_s16(out1)),
+               vreinterpret_u8_s16(vget_high_s16(out1)));
+  INIT_VECTOR4(shuffles,
+               vtbl4_u8(all_out, vld1_u8(kShuffles[0])),
+               vtbl4_u8(all_out, vld1_u8(kShuffles[1])),
+               vtbl4_u8(all_out, vld1_u8(kShuffles[2])),
+               vtbl4_u8(all_out, vld1_u8(kShuffles[3])));
+#endif
+  // Zigzag reordering
+  vst1_u8((uint8_t*)(out +  0), shuffles.val[0]);
+  vst1_u8((uint8_t*)(out +  4), shuffles.val[1]);
+  vst1_u8((uint8_t*)(out +  8), shuffles.val[2]);
+  vst1_u8((uint8_t*)(out + 12), shuffles.val[3]);
+  // test zeros
+  if (*(uint64_t*)(out +  0) != 0) return 1;
+  if (*(uint64_t*)(out +  4) != 0) return 1;
+  if (*(uint64_t*)(out +  8) != 0) return 1;
+  if (*(uint64_t*)(out + 12) != 0) return 1;
+  return 0;
+}
+
+static int Quantize2Blocks(int16_t in[32], int16_t out[32],
+                           const VP8Matrix* const mtx) {
+  int nz;
+  nz  = QuantizeBlock(in + 0 * 16, out + 0 * 16, mtx) << 0;
+  nz |= QuantizeBlock(in + 1 * 16, out + 1 * 16, mtx) << 1;
+  return nz;
+}
+
+#endif   // !WORK_AROUND_GCC
+
+#endif   // WEBP_USE_NEON
+
+//------------------------------------------------------------------------------
+// Entry point
+
+extern void VP8EncDspInitNEON(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspInitNEON(void) {
+#if defined(WEBP_USE_NEON)
+  VP8ITransform = ITransform;
+  VP8FTransform = FTransform;
+
+  VP8FTransformWHT = FTransformWHT;
+
+  VP8TDisto4x4 = Disto4x4;
+  VP8TDisto16x16 = Disto16x16;
+  VP8CollectHistogram = CollectHistogram;
+  VP8SSE16x16 = SSE16x16;
+  VP8SSE16x8 = SSE16x8;
+  VP8SSE8x8 = SSE8x8;
+  VP8SSE4x4 = SSE4x4;
+#if !defined(WORK_AROUND_GCC)
+  VP8EncQuantizeBlock = QuantizeBlock;
+  VP8EncQuantize2Blocks = Quantize2Blocks;
+#endif
+#endif   // WEBP_USE_NEON
+}
diff --git a/Source/LibWebP/src/dsp/dsp.enc_sse2.c b/Source/LibWebP/src/dsp/dsp.enc_sse2.c
new file mode 100644
index 0000000..18dccad
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.enc_sse2.c
@@ -0,0 +1,940 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// SSE2 version of speed-critical encoding functions.
+//
+// Author: Christian Duvivier (cduvivier at google.com)
+
+#include "./dsp.h"
+
+#if defined(WEBP_USE_SSE2)
+#include <stdlib.h>  // for abs()
+#include <emmintrin.h>
+
+#include "../enc/cost.h"
+#include "../enc/vp8enci.h"
+#include "../utils/utils.h"
+
+//------------------------------------------------------------------------------
+// Quite useful macro for debugging. Left here for convenience.
+
+#if 0
+#include <stdio.h>
+static void PrintReg(const __m128i r, const char* const name, int size) {
+  int n;
+  union {
+    __m128i r;
+    uint8_t i8[16];
+    uint16_t i16[8];
+    uint32_t i32[4];
+    uint64_t i64[2];
+  } tmp;
+  tmp.r = r;
+  fprintf(stderr, "%s\t: ", name);
+  if (size == 8) {
+    for (n = 0; n < 16; ++n) fprintf(stderr, "%.2x ", tmp.i8[n]);
+  } else if (size == 16) {
+    for (n = 0; n < 8; ++n) fprintf(stderr, "%.4x ", tmp.i16[n]);
+  } else if (size == 32) {
+    for (n = 0; n < 4; ++n) fprintf(stderr, "%.8x ", tmp.i32[n]);
+  } else {
+    for (n = 0; n < 2; ++n) fprintf(stderr, "%.16lx ", tmp.i64[n]);
+  }
+  fprintf(stderr, "\n");
+}
+#endif
+
+//------------------------------------------------------------------------------
+// Compute susceptibility based on DCT-coeff histograms:
+// the higher, the "easier" the macroblock is to compress.
+
+static void CollectHistogram(const uint8_t* ref, const uint8_t* pred,
+                             int start_block, int end_block,
+                             VP8Histogram* const histo) {
+  const __m128i max_coeff_thresh = _mm_set1_epi16(MAX_COEFF_THRESH);
+  int j;
+  int distribution[MAX_COEFF_THRESH + 1] = { 0 };
+  for (j = start_block; j < end_block; ++j) {
+    int16_t out[16];
+    int k;
+
+    VP8FTransform(ref + VP8DspScan[j], pred + VP8DspScan[j], out);
+
+    // Convert coefficients to bin (within out[]).
+    {
+      // Load.
+      const __m128i out0 = _mm_loadu_si128((__m128i*)&out[0]);
+      const __m128i out1 = _mm_loadu_si128((__m128i*)&out[8]);
+      // sign(out) = out >> 15  (0x0000 if positive, 0xffff if negative)
+      const __m128i sign0 = _mm_srai_epi16(out0, 15);
+      const __m128i sign1 = _mm_srai_epi16(out1, 15);
+      // abs(out) = (out ^ sign) - sign
+      const __m128i xor0 = _mm_xor_si128(out0, sign0);
+      const __m128i xor1 = _mm_xor_si128(out1, sign1);
+      const __m128i abs0 = _mm_sub_epi16(xor0, sign0);
+      const __m128i abs1 = _mm_sub_epi16(xor1, sign1);
+      // v = abs(out) >> 3
+      const __m128i v0 = _mm_srai_epi16(abs0, 3);
+      const __m128i v1 = _mm_srai_epi16(abs1, 3);
+      // bin = min(v, MAX_COEFF_THRESH)
+      const __m128i bin0 = _mm_min_epi16(v0, max_coeff_thresh);
+      const __m128i bin1 = _mm_min_epi16(v1, max_coeff_thresh);
+      // Store.
+      _mm_storeu_si128((__m128i*)&out[0], bin0);
+      _mm_storeu_si128((__m128i*)&out[8], bin1);
+    }
+
+    // Convert coefficients to bin.
+    for (k = 0; k < 16; ++k) {
+      ++distribution[out[k]];
+    }
+  }
+  VP8LSetHistogramData(distribution, histo);
+}
+
+//------------------------------------------------------------------------------
+// Transforms (Paragraph 14.4)
+
+// Does one or two inverse transforms.
+static void ITransform(const uint8_t* ref, const int16_t* in, uint8_t* dst,
+                       int do_two) {
+  // This implementation makes use of 16-bit fixed point versions of two
+  // multiply constants:
+  //    K1 = sqrt(2) * cos (pi/8) ~= 85627 / 2^16
+  //    K2 = sqrt(2) * sin (pi/8) ~= 35468 / 2^16
+  //
+  // To be able to use signed 16-bit integers, we use the following trick to
+  // have constants within range:
+  // - Associated constants are obtained by subtracting the 16-bit fixed point
+  //   version of one:
+  //      k = K - (1 << 16)  =>  K = k + (1 << 16)
+  //      K1 = 85267  =>  k1 =  20091
+  //      K2 = 35468  =>  k2 = -30068
+  // - The multiplication of a variable by a constant become the sum of the
+  //   variable and the multiplication of that variable by the associated
+  //   constant:
+  //      (x * K) >> 16 = (x * (k + (1 << 16))) >> 16 = ((x * k ) >> 16) + x
+  const __m128i k1 = _mm_set1_epi16(20091);
+  const __m128i k2 = _mm_set1_epi16(-30068);
+  __m128i T0, T1, T2, T3;
+
+  // Load and concatenate the transform coefficients (we'll do two inverse
+  // transforms in parallel). In the case of only one inverse transform, the
+  // second half of the vectors will just contain random value we'll never
+  // use nor store.
+  __m128i in0, in1, in2, in3;
+  {
+    in0 = _mm_loadl_epi64((const __m128i*)&in[0]);
+    in1 = _mm_loadl_epi64((const __m128i*)&in[4]);
+    in2 = _mm_loadl_epi64((const __m128i*)&in[8]);
+    in3 = _mm_loadl_epi64((const __m128i*)&in[12]);
+    // a00 a10 a20 a30   x x x x
+    // a01 a11 a21 a31   x x x x
+    // a02 a12 a22 a32   x x x x
+    // a03 a13 a23 a33   x x x x
+    if (do_two) {
+      const __m128i inB0 = _mm_loadl_epi64((const __m128i*)&in[16]);
+      const __m128i inB1 = _mm_loadl_epi64((const __m128i*)&in[20]);
+      const __m128i inB2 = _mm_loadl_epi64((const __m128i*)&in[24]);
+      const __m128i inB3 = _mm_loadl_epi64((const __m128i*)&in[28]);
+      in0 = _mm_unpacklo_epi64(in0, inB0);
+      in1 = _mm_unpacklo_epi64(in1, inB1);
+      in2 = _mm_unpacklo_epi64(in2, inB2);
+      in3 = _mm_unpacklo_epi64(in3, inB3);
+      // a00 a10 a20 a30   b00 b10 b20 b30
+      // a01 a11 a21 a31   b01 b11 b21 b31
+      // a02 a12 a22 a32   b02 b12 b22 b32
+      // a03 a13 a23 a33   b03 b13 b23 b33
+    }
+  }
+
+  // Vertical pass and subsequent transpose.
+  {
+    // First pass, c and d calculations are longer because of the "trick"
+    // multiplications.
+    const __m128i a = _mm_add_epi16(in0, in2);
+    const __m128i b = _mm_sub_epi16(in0, in2);
+    // c = MUL(in1, K2) - MUL(in3, K1) = MUL(in1, k2) - MUL(in3, k1) + in1 - in3
+    const __m128i c1 = _mm_mulhi_epi16(in1, k2);
+    const __m128i c2 = _mm_mulhi_epi16(in3, k1);
+    const __m128i c3 = _mm_sub_epi16(in1, in3);
+    const __m128i c4 = _mm_sub_epi16(c1, c2);
+    const __m128i c = _mm_add_epi16(c3, c4);
+    // d = MUL(in1, K1) + MUL(in3, K2) = MUL(in1, k1) + MUL(in3, k2) + in1 + in3
+    const __m128i d1 = _mm_mulhi_epi16(in1, k1);
+    const __m128i d2 = _mm_mulhi_epi16(in3, k2);
+    const __m128i d3 = _mm_add_epi16(in1, in3);
+    const __m128i d4 = _mm_add_epi16(d1, d2);
+    const __m128i d = _mm_add_epi16(d3, d4);
+
+    // Second pass.
+    const __m128i tmp0 = _mm_add_epi16(a, d);
+    const __m128i tmp1 = _mm_add_epi16(b, c);
+    const __m128i tmp2 = _mm_sub_epi16(b, c);
+    const __m128i tmp3 = _mm_sub_epi16(a, d);
+
+    // Transpose the two 4x4.
+    // a00 a01 a02 a03   b00 b01 b02 b03
+    // a10 a11 a12 a13   b10 b11 b12 b13
+    // a20 a21 a22 a23   b20 b21 b22 b23
+    // a30 a31 a32 a33   b30 b31 b32 b33
+    const __m128i transpose0_0 = _mm_unpacklo_epi16(tmp0, tmp1);
+    const __m128i transpose0_1 = _mm_unpacklo_epi16(tmp2, tmp3);
+    const __m128i transpose0_2 = _mm_unpackhi_epi16(tmp0, tmp1);
+    const __m128i transpose0_3 = _mm_unpackhi_epi16(tmp2, tmp3);
+    // a00 a10 a01 a11   a02 a12 a03 a13
+    // a20 a30 a21 a31   a22 a32 a23 a33
+    // b00 b10 b01 b11   b02 b12 b03 b13
+    // b20 b30 b21 b31   b22 b32 b23 b33
+    const __m128i transpose1_0 = _mm_unpacklo_epi32(transpose0_0, transpose0_1);
+    const __m128i transpose1_1 = _mm_unpacklo_epi32(transpose0_2, transpose0_3);
+    const __m128i transpose1_2 = _mm_unpackhi_epi32(transpose0_0, transpose0_1);
+    const __m128i transpose1_3 = _mm_unpackhi_epi32(transpose0_2, transpose0_3);
+    // a00 a10 a20 a30 a01 a11 a21 a31
+    // b00 b10 b20 b30 b01 b11 b21 b31
+    // a02 a12 a22 a32 a03 a13 a23 a33
+    // b02 b12 a22 b32 b03 b13 b23 b33
+    T0 = _mm_unpacklo_epi64(transpose1_0, transpose1_1);
+    T1 = _mm_unpackhi_epi64(transpose1_0, transpose1_1);
+    T2 = _mm_unpacklo_epi64(transpose1_2, transpose1_3);
+    T3 = _mm_unpackhi_epi64(transpose1_2, transpose1_3);
+    // a00 a10 a20 a30   b00 b10 b20 b30
+    // a01 a11 a21 a31   b01 b11 b21 b31
+    // a02 a12 a22 a32   b02 b12 b22 b32
+    // a03 a13 a23 a33   b03 b13 b23 b33
+  }
+
+  // Horizontal pass and subsequent transpose.
+  {
+    // First pass, c and d calculations are longer because of the "trick"
+    // multiplications.
+    const __m128i four = _mm_set1_epi16(4);
+    const __m128i dc = _mm_add_epi16(T0, four);
+    const __m128i a =  _mm_add_epi16(dc, T2);
+    const __m128i b =  _mm_sub_epi16(dc, T2);
+    // c = MUL(T1, K2) - MUL(T3, K1) = MUL(T1, k2) - MUL(T3, k1) + T1 - T3
+    const __m128i c1 = _mm_mulhi_epi16(T1, k2);
+    const __m128i c2 = _mm_mulhi_epi16(T3, k1);
+    const __m128i c3 = _mm_sub_epi16(T1, T3);
+    const __m128i c4 = _mm_sub_epi16(c1, c2);
+    const __m128i c = _mm_add_epi16(c3, c4);
+    // d = MUL(T1, K1) + MUL(T3, K2) = MUL(T1, k1) + MUL(T3, k2) + T1 + T3
+    const __m128i d1 = _mm_mulhi_epi16(T1, k1);
+    const __m128i d2 = _mm_mulhi_epi16(T3, k2);
+    const __m128i d3 = _mm_add_epi16(T1, T3);
+    const __m128i d4 = _mm_add_epi16(d1, d2);
+    const __m128i d = _mm_add_epi16(d3, d4);
+
+    // Second pass.
+    const __m128i tmp0 = _mm_add_epi16(a, d);
+    const __m128i tmp1 = _mm_add_epi16(b, c);
+    const __m128i tmp2 = _mm_sub_epi16(b, c);
+    const __m128i tmp3 = _mm_sub_epi16(a, d);
+    const __m128i shifted0 = _mm_srai_epi16(tmp0, 3);
+    const __m128i shifted1 = _mm_srai_epi16(tmp1, 3);
+    const __m128i shifted2 = _mm_srai_epi16(tmp2, 3);
+    const __m128i shifted3 = _mm_srai_epi16(tmp3, 3);
+
+    // Transpose the two 4x4.
+    // a00 a01 a02 a03   b00 b01 b02 b03
+    // a10 a11 a12 a13   b10 b11 b12 b13
+    // a20 a21 a22 a23   b20 b21 b22 b23
+    // a30 a31 a32 a33   b30 b31 b32 b33
+    const __m128i transpose0_0 = _mm_unpacklo_epi16(shifted0, shifted1);
+    const __m128i transpose0_1 = _mm_unpacklo_epi16(shifted2, shifted3);
+    const __m128i transpose0_2 = _mm_unpackhi_epi16(shifted0, shifted1);
+    const __m128i transpose0_3 = _mm_unpackhi_epi16(shifted2, shifted3);
+    // a00 a10 a01 a11   a02 a12 a03 a13
+    // a20 a30 a21 a31   a22 a32 a23 a33
+    // b00 b10 b01 b11   b02 b12 b03 b13
+    // b20 b30 b21 b31   b22 b32 b23 b33
+    const __m128i transpose1_0 = _mm_unpacklo_epi32(transpose0_0, transpose0_1);
+    const __m128i transpose1_1 = _mm_unpacklo_epi32(transpose0_2, transpose0_3);
+    const __m128i transpose1_2 = _mm_unpackhi_epi32(transpose0_0, transpose0_1);
+    const __m128i transpose1_3 = _mm_unpackhi_epi32(transpose0_2, transpose0_3);
+    // a00 a10 a20 a30 a01 a11 a21 a31
+    // b00 b10 b20 b30 b01 b11 b21 b31
+    // a02 a12 a22 a32 a03 a13 a23 a33
+    // b02 b12 a22 b32 b03 b13 b23 b33
+    T0 = _mm_unpacklo_epi64(transpose1_0, transpose1_1);
+    T1 = _mm_unpackhi_epi64(transpose1_0, transpose1_1);
+    T2 = _mm_unpacklo_epi64(transpose1_2, transpose1_3);
+    T3 = _mm_unpackhi_epi64(transpose1_2, transpose1_3);
+    // a00 a10 a20 a30   b00 b10 b20 b30
+    // a01 a11 a21 a31   b01 b11 b21 b31
+    // a02 a12 a22 a32   b02 b12 b22 b32
+    // a03 a13 a23 a33   b03 b13 b23 b33
+  }
+
+  // Add inverse transform to 'ref' and store.
+  {
+    const __m128i zero = _mm_setzero_si128();
+    // Load the reference(s).
+    __m128i ref0, ref1, ref2, ref3;
+    if (do_two) {
+      // Load eight bytes/pixels per line.
+      ref0 = _mm_loadl_epi64((const __m128i*)&ref[0 * BPS]);
+      ref1 = _mm_loadl_epi64((const __m128i*)&ref[1 * BPS]);
+      ref2 = _mm_loadl_epi64((const __m128i*)&ref[2 * BPS]);
+      ref3 = _mm_loadl_epi64((const __m128i*)&ref[3 * BPS]);
+    } else {
+      // Load four bytes/pixels per line.
+      ref0 = _mm_cvtsi32_si128(*(const int*)&ref[0 * BPS]);
+      ref1 = _mm_cvtsi32_si128(*(const int*)&ref[1 * BPS]);
+      ref2 = _mm_cvtsi32_si128(*(const int*)&ref[2 * BPS]);
+      ref3 = _mm_cvtsi32_si128(*(const int*)&ref[3 * BPS]);
+    }
+    // Convert to 16b.
+    ref0 = _mm_unpacklo_epi8(ref0, zero);
+    ref1 = _mm_unpacklo_epi8(ref1, zero);
+    ref2 = _mm_unpacklo_epi8(ref2, zero);
+    ref3 = _mm_unpacklo_epi8(ref3, zero);
+    // Add the inverse transform(s).
+    ref0 = _mm_add_epi16(ref0, T0);
+    ref1 = _mm_add_epi16(ref1, T1);
+    ref2 = _mm_add_epi16(ref2, T2);
+    ref3 = _mm_add_epi16(ref3, T3);
+    // Unsigned saturate to 8b.
+    ref0 = _mm_packus_epi16(ref0, ref0);
+    ref1 = _mm_packus_epi16(ref1, ref1);
+    ref2 = _mm_packus_epi16(ref2, ref2);
+    ref3 = _mm_packus_epi16(ref3, ref3);
+    // Store the results.
+    if (do_two) {
+      // Store eight bytes/pixels per line.
+      _mm_storel_epi64((__m128i*)&dst[0 * BPS], ref0);
+      _mm_storel_epi64((__m128i*)&dst[1 * BPS], ref1);
+      _mm_storel_epi64((__m128i*)&dst[2 * BPS], ref2);
+      _mm_storel_epi64((__m128i*)&dst[3 * BPS], ref3);
+    } else {
+      // Store four bytes/pixels per line.
+      *((int32_t *)&dst[0 * BPS]) = _mm_cvtsi128_si32(ref0);
+      *((int32_t *)&dst[1 * BPS]) = _mm_cvtsi128_si32(ref1);
+      *((int32_t *)&dst[2 * BPS]) = _mm_cvtsi128_si32(ref2);
+      *((int32_t *)&dst[3 * BPS]) = _mm_cvtsi128_si32(ref3);
+    }
+  }
+}
+
+static void FTransform(const uint8_t* src, const uint8_t* ref, int16_t* out) {
+  const __m128i zero = _mm_setzero_si128();
+  const __m128i seven = _mm_set1_epi16(7);
+  const __m128i k937 = _mm_set1_epi32(937);
+  const __m128i k1812 = _mm_set1_epi32(1812);
+  const __m128i k51000 = _mm_set1_epi32(51000);
+  const __m128i k12000_plus_one = _mm_set1_epi32(12000 + (1 << 16));
+  const __m128i k5352_2217 = _mm_set_epi16(5352,  2217, 5352,  2217,
+                                           5352,  2217, 5352,  2217);
+  const __m128i k2217_5352 = _mm_set_epi16(2217, -5352, 2217, -5352,
+                                           2217, -5352, 2217, -5352);
+  const __m128i k88p = _mm_set_epi16(8, 8, 8, 8, 8, 8, 8, 8);
+  const __m128i k88m = _mm_set_epi16(-8, 8, -8, 8, -8, 8, -8, 8);
+  const __m128i k5352_2217p = _mm_set_epi16(2217, 5352, 2217, 5352,
+                                            2217, 5352, 2217, 5352);
+  const __m128i k5352_2217m = _mm_set_epi16(-5352, 2217, -5352, 2217,
+                                            -5352, 2217, -5352, 2217);
+  __m128i v01, v32;
+
+
+  // Difference between src and ref and initial transpose.
+  {
+    // Load src and convert to 16b.
+    const __m128i src0 = _mm_loadl_epi64((const __m128i*)&src[0 * BPS]);
+    const __m128i src1 = _mm_loadl_epi64((const __m128i*)&src[1 * BPS]);
+    const __m128i src2 = _mm_loadl_epi64((const __m128i*)&src[2 * BPS]);
+    const __m128i src3 = _mm_loadl_epi64((const __m128i*)&src[3 * BPS]);
+    const __m128i src_0 = _mm_unpacklo_epi8(src0, zero);
+    const __m128i src_1 = _mm_unpacklo_epi8(src1, zero);
+    const __m128i src_2 = _mm_unpacklo_epi8(src2, zero);
+    const __m128i src_3 = _mm_unpacklo_epi8(src3, zero);
+    // Load ref and convert to 16b.
+    const __m128i ref0 = _mm_loadl_epi64((const __m128i*)&ref[0 * BPS]);
+    const __m128i ref1 = _mm_loadl_epi64((const __m128i*)&ref[1 * BPS]);
+    const __m128i ref2 = _mm_loadl_epi64((const __m128i*)&ref[2 * BPS]);
+    const __m128i ref3 = _mm_loadl_epi64((const __m128i*)&ref[3 * BPS]);
+    const __m128i ref_0 = _mm_unpacklo_epi8(ref0, zero);
+    const __m128i ref_1 = _mm_unpacklo_epi8(ref1, zero);
+    const __m128i ref_2 = _mm_unpacklo_epi8(ref2, zero);
+    const __m128i ref_3 = _mm_unpacklo_epi8(ref3, zero);
+    // Compute difference. -> 00 01 02 03 00 00 00 00
+    const __m128i diff0 = _mm_sub_epi16(src_0, ref_0);
+    const __m128i diff1 = _mm_sub_epi16(src_1, ref_1);
+    const __m128i diff2 = _mm_sub_epi16(src_2, ref_2);
+    const __m128i diff3 = _mm_sub_epi16(src_3, ref_3);
+
+
+    // Unpack and shuffle
+    // 00 01 02 03   0 0 0 0
+    // 10 11 12 13   0 0 0 0
+    // 20 21 22 23   0 0 0 0
+    // 30 31 32 33   0 0 0 0
+    const __m128i shuf01 = _mm_unpacklo_epi32(diff0, diff1);
+    const __m128i shuf23 = _mm_unpacklo_epi32(diff2, diff3);
+    // 00 01 10 11 02 03 12 13
+    // 20 21 30 31 22 23 32 33
+    const __m128i shuf01_p =
+        _mm_shufflehi_epi16(shuf01, _MM_SHUFFLE(2, 3, 0, 1));
+    const __m128i shuf23_p =
+        _mm_shufflehi_epi16(shuf23, _MM_SHUFFLE(2, 3, 0, 1));
+    // 00 01 10 11 03 02 13 12
+    // 20 21 30 31 23 22 33 32
+    const __m128i s01 = _mm_unpacklo_epi64(shuf01_p, shuf23_p);
+    const __m128i s32 = _mm_unpackhi_epi64(shuf01_p, shuf23_p);
+    // 00 01 10 11 20 21 30 31
+    // 03 02 13 12 23 22 33 32
+    const __m128i a01 = _mm_add_epi16(s01, s32);
+    const __m128i a32 = _mm_sub_epi16(s01, s32);
+    // [d0 + d3 | d1 + d2 | ...] = [a0 a1 | a0' a1' | ... ]
+    // [d0 - d3 | d1 - d2 | ...] = [a3 a2 | a3' a2' | ... ]
+
+    const __m128i tmp0 = _mm_madd_epi16(a01, k88p);  // [ (a0 + a1) << 3, ... ]
+    const __m128i tmp2 = _mm_madd_epi16(a01, k88m);  // [ (a0 - a1) << 3, ... ]
+    const __m128i tmp1_1 = _mm_madd_epi16(a32, k5352_2217p);
+    const __m128i tmp3_1 = _mm_madd_epi16(a32, k5352_2217m);
+    const __m128i tmp1_2 = _mm_add_epi32(tmp1_1, k1812);
+    const __m128i tmp3_2 = _mm_add_epi32(tmp3_1, k937);
+    const __m128i tmp1   = _mm_srai_epi32(tmp1_2, 9);
+    const __m128i tmp3   = _mm_srai_epi32(tmp3_2, 9);
+    const __m128i s03 = _mm_packs_epi32(tmp0, tmp2);
+    const __m128i s12 = _mm_packs_epi32(tmp1, tmp3);
+    const __m128i s_lo = _mm_unpacklo_epi16(s03, s12);   // 0 1 0 1 0 1...
+    const __m128i s_hi = _mm_unpackhi_epi16(s03, s12);   // 2 3 2 3 2 3
+    const __m128i v23 = _mm_unpackhi_epi32(s_lo, s_hi);
+    v01 = _mm_unpacklo_epi32(s_lo, s_hi);
+    v32 = _mm_shuffle_epi32(v23, _MM_SHUFFLE(1, 0, 3, 2));  // 3 2 3 2 3 2..
+  }
+
+  // Second pass
+  {
+    // Same operations are done on the (0,3) and (1,2) pairs.
+    // a0 = v0 + v3
+    // a1 = v1 + v2
+    // a3 = v0 - v3
+    // a2 = v1 - v2
+    const __m128i a01 = _mm_add_epi16(v01, v32);
+    const __m128i a32 = _mm_sub_epi16(v01, v32);
+    const __m128i a11 = _mm_unpackhi_epi64(a01, a01);
+    const __m128i a22 = _mm_unpackhi_epi64(a32, a32);
+    const __m128i a01_plus_7 = _mm_add_epi16(a01, seven);
+
+    // d0 = (a0 + a1 + 7) >> 4;
+    // d2 = (a0 - a1 + 7) >> 4;
+    const __m128i c0 = _mm_add_epi16(a01_plus_7, a11);
+    const __m128i c2 = _mm_sub_epi16(a01_plus_7, a11);
+    const __m128i d0 = _mm_srai_epi16(c0, 4);
+    const __m128i d2 = _mm_srai_epi16(c2, 4);
+
+    // f1 = ((b3 * 5352 + b2 * 2217 + 12000) >> 16)
+    // f3 = ((b3 * 2217 - b2 * 5352 + 51000) >> 16)
+    const __m128i b23 = _mm_unpacklo_epi16(a22, a32);
+    const __m128i c1 = _mm_madd_epi16(b23, k5352_2217);
+    const __m128i c3 = _mm_madd_epi16(b23, k2217_5352);
+    const __m128i d1 = _mm_add_epi32(c1, k12000_plus_one);
+    const __m128i d3 = _mm_add_epi32(c3, k51000);
+    const __m128i e1 = _mm_srai_epi32(d1, 16);
+    const __m128i e3 = _mm_srai_epi32(d3, 16);
+    const __m128i f1 = _mm_packs_epi32(e1, e1);
+    const __m128i f3 = _mm_packs_epi32(e3, e3);
+    // f1 = f1 + (a3 != 0);
+    // The compare will return (0xffff, 0) for (==0, !=0). To turn that into the
+    // desired (0, 1), we add one earlier through k12000_plus_one.
+    // -> f1 = f1 + 1 - (a3 == 0)
+    const __m128i g1 = _mm_add_epi16(f1, _mm_cmpeq_epi16(a32, zero));
+
+    const __m128i d0_g1 = _mm_unpacklo_epi64(d0, g1);
+    const __m128i d2_f3 = _mm_unpacklo_epi64(d2, f3);
+    _mm_storeu_si128((__m128i*)&out[0], d0_g1);
+    _mm_storeu_si128((__m128i*)&out[8], d2_f3);
+  }
+}
+
+static void FTransformWHT(const int16_t* in, int16_t* out) {
+  int32_t tmp[16];
+  int i;
+  for (i = 0; i < 4; ++i, in += 64) {
+    const int a0 = (in[0 * 16] + in[2 * 16]);
+    const int a1 = (in[1 * 16] + in[3 * 16]);
+    const int a2 = (in[1 * 16] - in[3 * 16]);
+    const int a3 = (in[0 * 16] - in[2 * 16]);
+    tmp[0 + i * 4] = a0 + a1;
+    tmp[1 + i * 4] = a3 + a2;
+    tmp[2 + i * 4] = a3 - a2;
+    tmp[3 + i * 4] = a0 - a1;
+  }
+  {
+    const __m128i src0 = _mm_loadu_si128((__m128i*)&tmp[0]);
+    const __m128i src1 = _mm_loadu_si128((__m128i*)&tmp[4]);
+    const __m128i src2 = _mm_loadu_si128((__m128i*)&tmp[8]);
+    const __m128i src3 = _mm_loadu_si128((__m128i*)&tmp[12]);
+    const __m128i a0 = _mm_add_epi32(src0, src2);
+    const __m128i a1 = _mm_add_epi32(src1, src3);
+    const __m128i a2 = _mm_sub_epi32(src1, src3);
+    const __m128i a3 = _mm_sub_epi32(src0, src2);
+    const __m128i b0 = _mm_srai_epi32(_mm_add_epi32(a0, a1), 1);
+    const __m128i b1 = _mm_srai_epi32(_mm_add_epi32(a3, a2), 1);
+    const __m128i b2 = _mm_srai_epi32(_mm_sub_epi32(a3, a2), 1);
+    const __m128i b3 = _mm_srai_epi32(_mm_sub_epi32(a0, a1), 1);
+    const __m128i out0 = _mm_packs_epi32(b0, b1);
+    const __m128i out1 = _mm_packs_epi32(b2, b3);
+    _mm_storeu_si128((__m128i*)&out[0], out0);
+    _mm_storeu_si128((__m128i*)&out[8], out1);
+  }
+}
+
+//------------------------------------------------------------------------------
+// Metric
+
+static WEBP_INLINE __m128i SubtractAndAccumulate(const __m128i a,
+                                                 const __m128i b) {
+  const __m128i zero = _mm_setzero_si128();
+  // convert to 16b
+  const __m128i A0 = _mm_unpacklo_epi8(a, zero);
+  const __m128i B0 = _mm_unpacklo_epi8(b, zero);
+  const __m128i A1 = _mm_unpackhi_epi8(a, zero);
+  const __m128i B1 = _mm_unpackhi_epi8(b, zero);
+  // subtract
+  const __m128i C0 = _mm_subs_epi16(A0, B0);
+  const __m128i C1 = _mm_subs_epi16(A1, B1);
+  // multiply with self
+  const __m128i D0 = _mm_madd_epi16(C0, C0);
+  const __m128i D1 = _mm_madd_epi16(C1, C1);
+  // accumulate
+  const __m128i sum = _mm_add_epi32(D0, D1);
+  return sum;
+}
+
+static int SSE_16xN(const uint8_t* a, const uint8_t* b, int num_pairs) {
+  __m128i sum = _mm_setzero_si128();
+  int32_t tmp[4];
+
+  while (num_pairs-- > 0) {
+    const __m128i a0 = _mm_loadu_si128((const __m128i*)&a[BPS * 0]);
+    const __m128i a1 = _mm_loadu_si128((const __m128i*)&a[BPS * 1]);
+    const __m128i b0 = _mm_loadu_si128((const __m128i*)&b[BPS * 0]);
+    const __m128i b1 = _mm_loadu_si128((const __m128i*)&b[BPS * 1]);
+    const __m128i sum1 = SubtractAndAccumulate(a0, b0);
+    const __m128i sum2 = SubtractAndAccumulate(a1, b1);
+    const __m128i sum12 = _mm_add_epi32(sum1, sum2);
+    sum = _mm_add_epi32(sum, sum12);
+    a += 2 * BPS;
+    b += 2 * BPS;
+  }
+  _mm_storeu_si128((__m128i*)tmp, sum);
+  return (tmp[3] + tmp[2] + tmp[1] + tmp[0]);
+}
+
+static int SSE16x16(const uint8_t* a, const uint8_t* b) {
+  return SSE_16xN(a, b, 8);
+}
+
+static int SSE16x8(const uint8_t* a, const uint8_t* b) {
+  return SSE_16xN(a, b, 4);
+}
+
+#define LOAD_8x16b(ptr) \
+  _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i*)(ptr)), zero)
+
+static int SSE8x8(const uint8_t* a, const uint8_t* b) {
+  const __m128i zero = _mm_setzero_si128();
+  int num_pairs = 4;
+  __m128i sum = zero;
+  int32_t tmp[4];
+  while (num_pairs-- > 0) {
+    const __m128i a0 = LOAD_8x16b(&a[BPS * 0]);
+    const __m128i a1 = LOAD_8x16b(&a[BPS * 1]);
+    const __m128i b0 = LOAD_8x16b(&b[BPS * 0]);
+    const __m128i b1 = LOAD_8x16b(&b[BPS * 1]);
+    // subtract
+    const __m128i c0 = _mm_subs_epi16(a0, b0);
+    const __m128i c1 = _mm_subs_epi16(a1, b1);
+    // multiply/accumulate with self
+    const __m128i d0 = _mm_madd_epi16(c0, c0);
+    const __m128i d1 = _mm_madd_epi16(c1, c1);
+    // collect
+    const __m128i sum01 = _mm_add_epi32(d0, d1);
+    sum = _mm_add_epi32(sum, sum01);
+    a += 2 * BPS;
+    b += 2 * BPS;
+  }
+  _mm_storeu_si128((__m128i*)tmp, sum);
+  return (tmp[3] + tmp[2] + tmp[1] + tmp[0]);
+}
+#undef LOAD_8x16b
+
+static int SSE4x4(const uint8_t* a, const uint8_t* b) {
+  const __m128i zero = _mm_setzero_si128();
+
+  // Load values. Note that we read 8 pixels instead of 4,
+  // but the a/b buffers are over-allocated to that effect.
+  const __m128i a0 = _mm_loadl_epi64((const __m128i*)&a[BPS * 0]);
+  const __m128i a1 = _mm_loadl_epi64((const __m128i*)&a[BPS * 1]);
+  const __m128i a2 = _mm_loadl_epi64((const __m128i*)&a[BPS * 2]);
+  const __m128i a3 = _mm_loadl_epi64((const __m128i*)&a[BPS * 3]);
+  const __m128i b0 = _mm_loadl_epi64((const __m128i*)&b[BPS * 0]);
+  const __m128i b1 = _mm_loadl_epi64((const __m128i*)&b[BPS * 1]);
+  const __m128i b2 = _mm_loadl_epi64((const __m128i*)&b[BPS * 2]);
+  const __m128i b3 = _mm_loadl_epi64((const __m128i*)&b[BPS * 3]);
+  // Combine pair of lines.
+  const __m128i a01 = _mm_unpacklo_epi32(a0, a1);
+  const __m128i a23 = _mm_unpacklo_epi32(a2, a3);
+  const __m128i b01 = _mm_unpacklo_epi32(b0, b1);
+  const __m128i b23 = _mm_unpacklo_epi32(b2, b3);
+  // Convert to 16b.
+  const __m128i a01s = _mm_unpacklo_epi8(a01, zero);
+  const __m128i a23s = _mm_unpacklo_epi8(a23, zero);
+  const __m128i b01s = _mm_unpacklo_epi8(b01, zero);
+  const __m128i b23s = _mm_unpacklo_epi8(b23, zero);
+  // subtract, square and accumulate
+  const __m128i d0 = _mm_subs_epi16(a01s, b01s);
+  const __m128i d1 = _mm_subs_epi16(a23s, b23s);
+  const __m128i e0 = _mm_madd_epi16(d0, d0);
+  const __m128i e1 = _mm_madd_epi16(d1, d1);
+  const __m128i sum = _mm_add_epi32(e0, e1);
+
+  int32_t tmp[4];
+  _mm_storeu_si128((__m128i*)tmp, sum);
+  return (tmp[3] + tmp[2] + tmp[1] + tmp[0]);
+}
+
+//------------------------------------------------------------------------------
+// Texture distortion
+//
+// We try to match the spectral content (weighted) between source and
+// reconstructed samples.
+
+// Hadamard transform
+// Returns the difference between the weighted sum of the absolute value of
+// transformed coefficients.
+static int TTransform(const uint8_t* inA, const uint8_t* inB,
+                      const uint16_t* const w) {
+  int32_t sum[4];
+  __m128i tmp_0, tmp_1, tmp_2, tmp_3;
+  const __m128i zero = _mm_setzero_si128();
+
+  // Load, combine and transpose inputs.
+  {
+    const __m128i inA_0 = _mm_loadl_epi64((const __m128i*)&inA[BPS * 0]);
+    const __m128i inA_1 = _mm_loadl_epi64((const __m128i*)&inA[BPS * 1]);
+    const __m128i inA_2 = _mm_loadl_epi64((const __m128i*)&inA[BPS * 2]);
+    const __m128i inA_3 = _mm_loadl_epi64((const __m128i*)&inA[BPS * 3]);
+    const __m128i inB_0 = _mm_loadl_epi64((const __m128i*)&inB[BPS * 0]);
+    const __m128i inB_1 = _mm_loadl_epi64((const __m128i*)&inB[BPS * 1]);
+    const __m128i inB_2 = _mm_loadl_epi64((const __m128i*)&inB[BPS * 2]);
+    const __m128i inB_3 = _mm_loadl_epi64((const __m128i*)&inB[BPS * 3]);
+
+    // Combine inA and inB (we'll do two transforms in parallel).
+    const __m128i inAB_0 = _mm_unpacklo_epi8(inA_0, inB_0);
+    const __m128i inAB_1 = _mm_unpacklo_epi8(inA_1, inB_1);
+    const __m128i inAB_2 = _mm_unpacklo_epi8(inA_2, inB_2);
+    const __m128i inAB_3 = _mm_unpacklo_epi8(inA_3, inB_3);
+    // a00 b00 a01 b01 a02 b03 a03 b03   0 0 0 0 0 0 0 0
+    // a10 b10 a11 b11 a12 b12 a13 b13   0 0 0 0 0 0 0 0
+    // a20 b20 a21 b21 a22 b22 a23 b23   0 0 0 0 0 0 0 0
+    // a30 b30 a31 b31 a32 b32 a33 b33   0 0 0 0 0 0 0 0
+
+    // Transpose the two 4x4, discarding the filling zeroes.
+    const __m128i transpose0_0 = _mm_unpacklo_epi8(inAB_0, inAB_2);
+    const __m128i transpose0_1 = _mm_unpacklo_epi8(inAB_1, inAB_3);
+    // a00 a20  b00 b20  a01 a21  b01 b21  a02 a22  b02 b22  a03 a23  b03 b23
+    // a10 a30  b10 b30  a11 a31  b11 b31  a12 a32  b12 b32  a13 a33  b13 b33
+    const __m128i transpose1_0 = _mm_unpacklo_epi8(transpose0_0, transpose0_1);
+    const __m128i transpose1_1 = _mm_unpackhi_epi8(transpose0_0, transpose0_1);
+    // a00 a10 a20 a30  b00 b10 b20 b30  a01 a11 a21 a31  b01 b11 b21 b31
+    // a02 a12 a22 a32  b02 b12 b22 b32  a03 a13 a23 a33  b03 b13 b23 b33
+
+    // Convert to 16b.
+    tmp_0 = _mm_unpacklo_epi8(transpose1_0, zero);
+    tmp_1 = _mm_unpackhi_epi8(transpose1_0, zero);
+    tmp_2 = _mm_unpacklo_epi8(transpose1_1, zero);
+    tmp_3 = _mm_unpackhi_epi8(transpose1_1, zero);
+    // a00 a10 a20 a30   b00 b10 b20 b30
+    // a01 a11 a21 a31   b01 b11 b21 b31
+    // a02 a12 a22 a32   b02 b12 b22 b32
+    // a03 a13 a23 a33   b03 b13 b23 b33
+  }
+
+  // Horizontal pass and subsequent transpose.
+  {
+    // Calculate a and b (two 4x4 at once).
+    const __m128i a0 = _mm_add_epi16(tmp_0, tmp_2);
+    const __m128i a1 = _mm_add_epi16(tmp_1, tmp_3);
+    const __m128i a2 = _mm_sub_epi16(tmp_1, tmp_3);
+    const __m128i a3 = _mm_sub_epi16(tmp_0, tmp_2);
+    const __m128i b0 = _mm_add_epi16(a0, a1);
+    const __m128i b1 = _mm_add_epi16(a3, a2);
+    const __m128i b2 = _mm_sub_epi16(a3, a2);
+    const __m128i b3 = _mm_sub_epi16(a0, a1);
+    // a00 a01 a02 a03   b00 b01 b02 b03
+    // a10 a11 a12 a13   b10 b11 b12 b13
+    // a20 a21 a22 a23   b20 b21 b22 b23
+    // a30 a31 a32 a33   b30 b31 b32 b33
+
+    // Transpose the two 4x4.
+    const __m128i transpose0_0 = _mm_unpacklo_epi16(b0, b1);
+    const __m128i transpose0_1 = _mm_unpacklo_epi16(b2, b3);
+    const __m128i transpose0_2 = _mm_unpackhi_epi16(b0, b1);
+    const __m128i transpose0_3 = _mm_unpackhi_epi16(b2, b3);
+    // a00 a10 a01 a11   a02 a12 a03 a13
+    // a20 a30 a21 a31   a22 a32 a23 a33
+    // b00 b10 b01 b11   b02 b12 b03 b13
+    // b20 b30 b21 b31   b22 b32 b23 b33
+    const __m128i transpose1_0 = _mm_unpacklo_epi32(transpose0_0, transpose0_1);
+    const __m128i transpose1_1 = _mm_unpacklo_epi32(transpose0_2, transpose0_3);
+    const __m128i transpose1_2 = _mm_unpackhi_epi32(transpose0_0, transpose0_1);
+    const __m128i transpose1_3 = _mm_unpackhi_epi32(transpose0_2, transpose0_3);
+    // a00 a10 a20 a30 a01 a11 a21 a31
+    // b00 b10 b20 b30 b01 b11 b21 b31
+    // a02 a12 a22 a32 a03 a13 a23 a33
+    // b02 b12 a22 b32 b03 b13 b23 b33
+    tmp_0 = _mm_unpacklo_epi64(transpose1_0, transpose1_1);
+    tmp_1 = _mm_unpackhi_epi64(transpose1_0, transpose1_1);
+    tmp_2 = _mm_unpacklo_epi64(transpose1_2, transpose1_3);
+    tmp_3 = _mm_unpackhi_epi64(transpose1_2, transpose1_3);
+    // a00 a10 a20 a30   b00 b10 b20 b30
+    // a01 a11 a21 a31   b01 b11 b21 b31
+    // a02 a12 a22 a32   b02 b12 b22 b32
+    // a03 a13 a23 a33   b03 b13 b23 b33
+  }
+
+  // Vertical pass and difference of weighted sums.
+  {
+    // Load all inputs.
+    // TODO(cduvivier): Make variable declarations and allocations aligned so
+    //                  we can use _mm_load_si128 instead of _mm_loadu_si128.
+    const __m128i w_0 = _mm_loadu_si128((const __m128i*)&w[0]);
+    const __m128i w_8 = _mm_loadu_si128((const __m128i*)&w[8]);
+
+    // Calculate a and b (two 4x4 at once).
+    const __m128i a0 = _mm_add_epi16(tmp_0, tmp_2);
+    const __m128i a1 = _mm_add_epi16(tmp_1, tmp_3);
+    const __m128i a2 = _mm_sub_epi16(tmp_1, tmp_3);
+    const __m128i a3 = _mm_sub_epi16(tmp_0, tmp_2);
+    const __m128i b0 = _mm_add_epi16(a0, a1);
+    const __m128i b1 = _mm_add_epi16(a3, a2);
+    const __m128i b2 = _mm_sub_epi16(a3, a2);
+    const __m128i b3 = _mm_sub_epi16(a0, a1);
+
+    // Separate the transforms of inA and inB.
+    __m128i A_b0 = _mm_unpacklo_epi64(b0, b1);
+    __m128i A_b2 = _mm_unpacklo_epi64(b2, b3);
+    __m128i B_b0 = _mm_unpackhi_epi64(b0, b1);
+    __m128i B_b2 = _mm_unpackhi_epi64(b2, b3);
+
+    {
+      // sign(b) = b >> 15  (0x0000 if positive, 0xffff if negative)
+      const __m128i sign_A_b0 = _mm_srai_epi16(A_b0, 15);
+      const __m128i sign_A_b2 = _mm_srai_epi16(A_b2, 15);
+      const __m128i sign_B_b0 = _mm_srai_epi16(B_b0, 15);
+      const __m128i sign_B_b2 = _mm_srai_epi16(B_b2, 15);
+
+      // b = abs(b) = (b ^ sign) - sign
+      A_b0 = _mm_xor_si128(A_b0, sign_A_b0);
+      A_b2 = _mm_xor_si128(A_b2, sign_A_b2);
+      B_b0 = _mm_xor_si128(B_b0, sign_B_b0);
+      B_b2 = _mm_xor_si128(B_b2, sign_B_b2);
+      A_b0 = _mm_sub_epi16(A_b0, sign_A_b0);
+      A_b2 = _mm_sub_epi16(A_b2, sign_A_b2);
+      B_b0 = _mm_sub_epi16(B_b0, sign_B_b0);
+      B_b2 = _mm_sub_epi16(B_b2, sign_B_b2);
+    }
+
+    // weighted sums
+    A_b0 = _mm_madd_epi16(A_b0, w_0);
+    A_b2 = _mm_madd_epi16(A_b2, w_8);
+    B_b0 = _mm_madd_epi16(B_b0, w_0);
+    B_b2 = _mm_madd_epi16(B_b2, w_8);
+    A_b0 = _mm_add_epi32(A_b0, A_b2);
+    B_b0 = _mm_add_epi32(B_b0, B_b2);
+
+    // difference of weighted sums
+    A_b0 = _mm_sub_epi32(A_b0, B_b0);
+    _mm_storeu_si128((__m128i*)&sum[0], A_b0);
+  }
+  return sum[0] + sum[1] + sum[2] + sum[3];
+}
+
+static int Disto4x4(const uint8_t* const a, const uint8_t* const b,
+                    const uint16_t* const w) {
+  const int diff_sum = TTransform(a, b, w);
+  return abs(diff_sum) >> 5;
+}
+
+static int Disto16x16(const uint8_t* const a, const uint8_t* const b,
+                      const uint16_t* const w) {
+  int D = 0;
+  int x, y;
+  for (y = 0; y < 16 * BPS; y += 4 * BPS) {
+    for (x = 0; x < 16; x += 4) {
+      D += Disto4x4(a + x + y, b + x + y, w);
+    }
+  }
+  return D;
+}
+
+//------------------------------------------------------------------------------
+// Quantization
+//
+
+static WEBP_INLINE int DoQuantizeBlock(int16_t in[16], int16_t out[16],
+                                       const uint16_t* const sharpen,
+                                       const VP8Matrix* const mtx) {
+  const __m128i max_coeff_2047 = _mm_set1_epi16(MAX_LEVEL);
+  const __m128i zero = _mm_setzero_si128();
+  __m128i coeff0, coeff8;
+  __m128i out0, out8;
+  __m128i packed_out;
+
+  // Load all inputs.
+  // TODO(cduvivier): Make variable declarations and allocations aligned so that
+  //                  we can use _mm_load_si128 instead of _mm_loadu_si128.
+  __m128i in0 = _mm_loadu_si128((__m128i*)&in[0]);
+  __m128i in8 = _mm_loadu_si128((__m128i*)&in[8]);
+  const __m128i iq0 = _mm_loadu_si128((const __m128i*)&mtx->iq_[0]);
+  const __m128i iq8 = _mm_loadu_si128((const __m128i*)&mtx->iq_[8]);
+  const __m128i q0 = _mm_loadu_si128((const __m128i*)&mtx->q_[0]);
+  const __m128i q8 = _mm_loadu_si128((const __m128i*)&mtx->q_[8]);
+
+  // extract sign(in)  (0x0000 if positive, 0xffff if negative)
+  const __m128i sign0 = _mm_cmpgt_epi16(zero, in0);
+  const __m128i sign8 = _mm_cmpgt_epi16(zero, in8);
+
+  // coeff = abs(in) = (in ^ sign) - sign
+  coeff0 = _mm_xor_si128(in0, sign0);
+  coeff8 = _mm_xor_si128(in8, sign8);
+  coeff0 = _mm_sub_epi16(coeff0, sign0);
+  coeff8 = _mm_sub_epi16(coeff8, sign8);
+
+  // coeff = abs(in) + sharpen
+  if (sharpen != NULL) {
+    const __m128i sharpen0 = _mm_loadu_si128((const __m128i*)&sharpen[0]);
+    const __m128i sharpen8 = _mm_loadu_si128((const __m128i*)&sharpen[8]);
+    coeff0 = _mm_add_epi16(coeff0, sharpen0);
+    coeff8 = _mm_add_epi16(coeff8, sharpen8);
+  }
+
+  // out = (coeff * iQ + B) >> QFIX
+  {
+    // doing calculations with 32b precision (QFIX=17)
+    // out = (coeff * iQ)
+    const __m128i coeff_iQ0H = _mm_mulhi_epu16(coeff0, iq0);
+    const __m128i coeff_iQ0L = _mm_mullo_epi16(coeff0, iq0);
+    const __m128i coeff_iQ8H = _mm_mulhi_epu16(coeff8, iq8);
+    const __m128i coeff_iQ8L = _mm_mullo_epi16(coeff8, iq8);
+    __m128i out_00 = _mm_unpacklo_epi16(coeff_iQ0L, coeff_iQ0H);
+    __m128i out_04 = _mm_unpackhi_epi16(coeff_iQ0L, coeff_iQ0H);
+    __m128i out_08 = _mm_unpacklo_epi16(coeff_iQ8L, coeff_iQ8H);
+    __m128i out_12 = _mm_unpackhi_epi16(coeff_iQ8L, coeff_iQ8H);
+    // out = (coeff * iQ + B)
+    const __m128i bias_00 = _mm_loadu_si128((const __m128i*)&mtx->bias_[0]);
+    const __m128i bias_04 = _mm_loadu_si128((const __m128i*)&mtx->bias_[4]);
+    const __m128i bias_08 = _mm_loadu_si128((const __m128i*)&mtx->bias_[8]);
+    const __m128i bias_12 = _mm_loadu_si128((const __m128i*)&mtx->bias_[12]);
+    out_00 = _mm_add_epi32(out_00, bias_00);
+    out_04 = _mm_add_epi32(out_04, bias_04);
+    out_08 = _mm_add_epi32(out_08, bias_08);
+    out_12 = _mm_add_epi32(out_12, bias_12);
+    // out = QUANTDIV(coeff, iQ, B, QFIX)
+    out_00 = _mm_srai_epi32(out_00, QFIX);
+    out_04 = _mm_srai_epi32(out_04, QFIX);
+    out_08 = _mm_srai_epi32(out_08, QFIX);
+    out_12 = _mm_srai_epi32(out_12, QFIX);
+
+    // pack result as 16b
+    out0 = _mm_packs_epi32(out_00, out_04);
+    out8 = _mm_packs_epi32(out_08, out_12);
+
+    // if (coeff > 2047) coeff = 2047
+    out0 = _mm_min_epi16(out0, max_coeff_2047);
+    out8 = _mm_min_epi16(out8, max_coeff_2047);
+  }
+
+  // get sign back (if (sign[j]) out_n = -out_n)
+  out0 = _mm_xor_si128(out0, sign0);
+  out8 = _mm_xor_si128(out8, sign8);
+  out0 = _mm_sub_epi16(out0, sign0);
+  out8 = _mm_sub_epi16(out8, sign8);
+
+  // in = out * Q
+  in0 = _mm_mullo_epi16(out0, q0);
+  in8 = _mm_mullo_epi16(out8, q8);
+
+  _mm_storeu_si128((__m128i*)&in[0], in0);
+  _mm_storeu_si128((__m128i*)&in[8], in8);
+
+  // zigzag the output before storing it.
+  //
+  // The zigzag pattern can almost be reproduced with a small sequence of
+  // shuffles. After it, we only need to swap the 7th (ending up in third
+  // position instead of twelfth) and 8th values.
+  {
+    __m128i outZ0, outZ8;
+    outZ0 = _mm_shufflehi_epi16(out0,  _MM_SHUFFLE(2, 1, 3, 0));
+    outZ0 = _mm_shuffle_epi32  (outZ0, _MM_SHUFFLE(3, 1, 2, 0));
+    outZ0 = _mm_shufflehi_epi16(outZ0, _MM_SHUFFLE(3, 1, 0, 2));
+    outZ8 = _mm_shufflelo_epi16(out8,  _MM_SHUFFLE(3, 0, 2, 1));
+    outZ8 = _mm_shuffle_epi32  (outZ8, _MM_SHUFFLE(3, 1, 2, 0));
+    outZ8 = _mm_shufflelo_epi16(outZ8, _MM_SHUFFLE(1, 3, 2, 0));
+    _mm_storeu_si128((__m128i*)&out[0], outZ0);
+    _mm_storeu_si128((__m128i*)&out[8], outZ8);
+    packed_out = _mm_packs_epi16(outZ0, outZ8);
+  }
+  {
+    const int16_t outZ_12 = out[12];
+    const int16_t outZ_3 = out[3];
+    out[3] = outZ_12;
+    out[12] = outZ_3;
+  }
+
+  // detect if all 'out' values are zeroes or not
+  return (_mm_movemask_epi8(_mm_cmpeq_epi8(packed_out, zero)) != 0xffff);
+}
+
+static int QuantizeBlock(int16_t in[16], int16_t out[16],
+                         const VP8Matrix* const mtx) {
+  return DoQuantizeBlock(in, out, &mtx->sharpen_[0], mtx);
+}
+
+static int QuantizeBlockWHT(int16_t in[16], int16_t out[16],
+                            const VP8Matrix* const mtx) {
+  return DoQuantizeBlock(in, out, NULL, mtx);
+}
+
+static int Quantize2Blocks(int16_t in[32], int16_t out[32],
+                           const VP8Matrix* const mtx) {
+  int nz;
+  const uint16_t* const sharpen = &mtx->sharpen_[0];
+  nz  = DoQuantizeBlock(in + 0 * 16, out + 0 * 16, sharpen, mtx) << 0;
+  nz |= DoQuantizeBlock(in + 1 * 16, out + 1 * 16, sharpen, mtx) << 1;
+  return nz;
+}
+
+#endif   // WEBP_USE_SSE2
+
+//------------------------------------------------------------------------------
+// Entry point
+
+extern void VP8EncDspInitSSE2(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspInitSSE2(void) {
+#if defined(WEBP_USE_SSE2)
+  VP8CollectHistogram = CollectHistogram;
+  VP8EncQuantizeBlock = QuantizeBlock;
+  VP8EncQuantize2Blocks = Quantize2Blocks;
+  VP8EncQuantizeBlockWHT = QuantizeBlockWHT;
+  VP8ITransform = ITransform;
+  VP8FTransform = FTransform;
+  VP8FTransformWHT = FTransformWHT;
+  VP8SSE16x16 = SSE16x16;
+  VP8SSE16x8 = SSE16x8;
+  VP8SSE8x8 = SSE8x8;
+  VP8SSE4x4 = SSE4x4;
+  VP8TDisto4x4 = Disto4x4;
+  VP8TDisto16x16 = Disto16x16;
+#endif   // WEBP_USE_SSE2
+}
diff --git a/Source/LibWebP/src/dsp/dsp.filters.c b/Source/LibWebP/src/dsp/dsp.filters.c
new file mode 100644
index 0000000..11ead57
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.filters.c
@@ -0,0 +1,240 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Spatial prediction using various filters
+//
+// Author: Urvang (urvang at google.com)
+
+#include "./dsp.h"
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+//------------------------------------------------------------------------------
+// Helpful macro.
+
+# define SANITY_CHECK(in, out)                                                 \
+  assert(in != NULL);                                                          \
+  assert(out != NULL);                                                         \
+  assert(width > 0);                                                           \
+  assert(height > 0);                                                          \
+  assert(stride >= width);                                                     \
+  assert(row >= 0 && num_rows > 0 && row + num_rows <= height);                \
+  (void)height;  // Silence unused warning.
+
+static WEBP_INLINE void PredictLine(const uint8_t* src, const uint8_t* pred,
+                                    uint8_t* dst, int length, int inverse) {
+  int i;
+  if (inverse) {
+    for (i = 0; i < length; ++i) dst[i] = src[i] + pred[i];
+  } else {
+    for (i = 0; i < length; ++i) dst[i] = src[i] - pred[i];
+  }
+}
+
+//------------------------------------------------------------------------------
+// Horizontal filter.
+
+static WEBP_INLINE void DoHorizontalFilter(const uint8_t* in,
+                                           int width, int height, int stride,
+                                           int row, int num_rows,
+                                           int inverse, uint8_t* out) {
+  const uint8_t* preds;
+  const size_t start_offset = row * stride;
+  const int last_row = row + num_rows;
+  SANITY_CHECK(in, out);
+  in += start_offset;
+  out += start_offset;
+  preds = inverse ? out : in;
+
+  if (row == 0) {
+    // Leftmost pixel is the same as input for topmost scanline.
+    out[0] = in[0];
+    PredictLine(in + 1, preds, out + 1, width - 1, inverse);
+    row = 1;
+    preds += stride;
+    in += stride;
+    out += stride;
+  }
+
+  // Filter line-by-line.
+  while (row < last_row) {
+    // Leftmost pixel is predicted from above.
+    PredictLine(in, preds - stride, out, 1, inverse);
+    PredictLine(in + 1, preds, out + 1, width - 1, inverse);
+    ++row;
+    preds += stride;
+    in += stride;
+    out += stride;
+  }
+}
+
+//------------------------------------------------------------------------------
+// Vertical filter.
+
+static WEBP_INLINE void DoVerticalFilter(const uint8_t* in,
+                                         int width, int height, int stride,
+                                         int row, int num_rows,
+                                         int inverse, uint8_t* out) {
+  const uint8_t* preds;
+  const size_t start_offset = row * stride;
+  const int last_row = row + num_rows;
+  SANITY_CHECK(in, out);
+  in += start_offset;
+  out += start_offset;
+  preds = inverse ? out : in;
+
+  if (row == 0) {
+    // Very first top-left pixel is copied.
+    out[0] = in[0];
+    // Rest of top scan-line is left-predicted.
+    PredictLine(in + 1, preds, out + 1, width - 1, inverse);
+    row = 1;
+    in += stride;
+    out += stride;
+  } else {
+    // We are starting from in-between. Make sure 'preds' points to prev row.
+    preds -= stride;
+  }
+
+  // Filter line-by-line.
+  while (row < last_row) {
+    PredictLine(in, preds, out, width, inverse);
+    ++row;
+    preds += stride;
+    in += stride;
+    out += stride;
+  }
+}
+
+//------------------------------------------------------------------------------
+// Gradient filter.
+
+static WEBP_INLINE int GradientPredictor(uint8_t a, uint8_t b, uint8_t c) {
+  const int g = a + b - c;
+  return ((g & ~0xff) == 0) ? g : (g < 0) ? 0 : 255;  // clip to 8bit
+}
+
+static WEBP_INLINE void DoGradientFilter(const uint8_t* in,
+                                         int width, int height, int stride,
+                                         int row, int num_rows,
+                                         int inverse, uint8_t* out) {
+  const uint8_t* preds;
+  const size_t start_offset = row * stride;
+  const int last_row = row + num_rows;
+  SANITY_CHECK(in, out);
+  in += start_offset;
+  out += start_offset;
+  preds = inverse ? out : in;
+
+  // left prediction for top scan-line
+  if (row == 0) {
+    out[0] = in[0];
+    PredictLine(in + 1, preds, out + 1, width - 1, inverse);
+    row = 1;
+    preds += stride;
+    in += stride;
+    out += stride;
+  }
+
+  // Filter line-by-line.
+  while (row < last_row) {
+    int w;
+    // leftmost pixel: predict from above.
+    PredictLine(in, preds - stride, out, 1, inverse);
+    for (w = 1; w < width; ++w) {
+      const int pred = GradientPredictor(preds[w - 1],
+                                         preds[w - stride],
+                                         preds[w - stride - 1]);
+      out[w] = in[w] + (inverse ? pred : -pred);
+    }
+    ++row;
+    preds += stride;
+    in += stride;
+    out += stride;
+  }
+}
+
+#undef SANITY_CHECK
+
+//------------------------------------------------------------------------------
+
+static void HorizontalFilter(const uint8_t* data, int width, int height,
+                             int stride, uint8_t* filtered_data) {
+  DoHorizontalFilter(data, width, height, stride, 0, height, 0, filtered_data);
+}
+
+static void VerticalFilter(const uint8_t* data, int width, int height,
+                           int stride, uint8_t* filtered_data) {
+  DoVerticalFilter(data, width, height, stride, 0, height, 0, filtered_data);
+}
+
+
+static void GradientFilter(const uint8_t* data, int width, int height,
+                           int stride, uint8_t* filtered_data) {
+  DoGradientFilter(data, width, height, stride, 0, height, 0, filtered_data);
+}
+
+
+//------------------------------------------------------------------------------
+
+static void VerticalUnfilter(int width, int height, int stride, int row,
+                             int num_rows, uint8_t* data) {
+  DoVerticalFilter(data, width, height, stride, row, num_rows, 1, data);
+}
+
+static void HorizontalUnfilter(int width, int height, int stride, int row,
+                               int num_rows, uint8_t* data) {
+  DoHorizontalFilter(data, width, height, stride, row, num_rows, 1, data);
+}
+
+static void GradientUnfilter(int width, int height, int stride, int row,
+                             int num_rows, uint8_t* data) {
+  DoGradientFilter(data, width, height, stride, row, num_rows, 1, data);
+}
+
+//------------------------------------------------------------------------------
+// Init function
+
+WebPFilterFunc WebPFilters[WEBP_FILTER_LAST];
+WebPUnfilterFunc WebPUnfilters[WEBP_FILTER_LAST];
+
+extern void VP8FiltersInitMIPSdspR2(void);
+extern void VP8FiltersInitSSE2(void);
+
+static volatile VP8CPUInfo filters_last_cpuinfo_used =
+    (VP8CPUInfo)&filters_last_cpuinfo_used;
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8FiltersInit(void) {
+  if (filters_last_cpuinfo_used == VP8GetCPUInfo) return;
+
+  WebPUnfilters[WEBP_FILTER_NONE] = NULL;
+  WebPUnfilters[WEBP_FILTER_HORIZONTAL] = HorizontalUnfilter;
+  WebPUnfilters[WEBP_FILTER_VERTICAL] = VerticalUnfilter;
+  WebPUnfilters[WEBP_FILTER_GRADIENT] = GradientUnfilter;
+
+  WebPFilters[WEBP_FILTER_NONE] = NULL;
+  WebPFilters[WEBP_FILTER_HORIZONTAL] = HorizontalFilter;
+  WebPFilters[WEBP_FILTER_VERTICAL] = VerticalFilter;
+  WebPFilters[WEBP_FILTER_GRADIENT] = GradientFilter;
+
+  if (VP8GetCPUInfo != NULL) {
+#if defined(WEBP_USE_SSE2)
+    if (VP8GetCPUInfo(kSSE2)) {
+      VP8FiltersInitSSE2();
+    }
+#endif
+#if defined(WEBP_USE_MIPS_DSP_R2)
+    if (VP8GetCPUInfo(kMIPSdspR2)) {
+      VP8FiltersInitMIPSdspR2();
+    }
+#endif
+  }
+  filters_last_cpuinfo_used = VP8GetCPUInfo;
+}
diff --git a/Source/LibWebP/src/dsp/dsp.filters_mips_dsp_r2.c b/Source/LibWebP/src/dsp/dsp.filters_mips_dsp_r2.c
new file mode 100644
index 0000000..6c34efb
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.filters_mips_dsp_r2.c
@@ -0,0 +1,404 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Spatial prediction using various filters
+//
+// Author(s): Branimir Vasic (branimir.vasic at imgtec.com)
+//            Djordje Pesut (djordje.pesut at imgtec.com)
+
+#include "./dsp.h"
+
+#if defined(WEBP_USE_MIPS_DSP_R2)
+
+#include "../dsp/dsp.h"
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+//------------------------------------------------------------------------------
+// Helpful macro.
+
+# define SANITY_CHECK(in, out)                                                 \
+  assert(in != NULL);                                                          \
+  assert(out != NULL);                                                         \
+  assert(width > 0);                                                           \
+  assert(height > 0);                                                          \
+  assert(stride >= width);                                                     \
+  assert(row >= 0 && num_rows > 0 && row + num_rows <= height);                \
+  (void)height;  // Silence unused warning.
+
+// if INVERSE
+//   preds == &dst[-1] == &src[-1]
+// else
+//   preds == &src[-1] != &dst[-1]
+#define DO_PREDICT_LINE(SRC, DST, LENGTH, INVERSE) do {                        \
+    const uint8_t* psrc = (uint8_t*)(SRC);                                     \
+    uint8_t* pdst = (uint8_t*)(DST);                                           \
+    const int ilength = (int)(LENGTH);                                         \
+    int temp0, temp1, temp2, temp3, temp4, temp5, temp6;                       \
+    __asm__ volatile (                                                         \
+      ".set      push                                   \n\t"                  \
+      ".set      noreorder                              \n\t"                  \
+      "srl       %[temp0],    %[length],    0x2         \n\t"                  \
+      "beqz      %[temp0],    4f                        \n\t"                  \
+      " andi     %[temp6],    %[length],    0x3         \n\t"                  \
+    ".if "#INVERSE"                                     \n\t"                  \
+      "lbu       %[temp1],    -1(%[src])                \n\t"                  \
+    "1:                                                 \n\t"                  \
+      "lbu       %[temp2],    0(%[src])                 \n\t"                  \
+      "lbu       %[temp3],    1(%[src])                 \n\t"                  \
+      "lbu       %[temp4],    2(%[src])                 \n\t"                  \
+      "lbu       %[temp5],    3(%[src])                 \n\t"                  \
+      "addiu     %[src],      %[src],       4           \n\t"                  \
+      "addiu     %[temp0],    %[temp0],     -1          \n\t"                  \
+      "addu      %[temp2],    %[temp2],     %[temp1]    \n\t"                  \
+      "addu      %[temp3],    %[temp3],     %[temp2]    \n\t"                  \
+      "addu      %[temp4],    %[temp4],     %[temp3]    \n\t"                  \
+      "addu      %[temp1],    %[temp5],     %[temp4]    \n\t"                  \
+      "sb        %[temp2],    -4(%[src])                \n\t"                  \
+      "sb        %[temp3],    -3(%[src])                \n\t"                  \
+      "sb        %[temp4],    -2(%[src])                \n\t"                  \
+      "bnez      %[temp0],    1b                        \n\t"                  \
+      " sb       %[temp1],    -1(%[src])                \n\t"                  \
+    ".else                                              \n\t"                  \
+    "1:                                                 \n\t"                  \
+      "ulw       %[temp1],    -1(%[src])                \n\t"                  \
+      "ulw       %[temp2],    0(%[src])                 \n\t"                  \
+      "addiu     %[src],      %[src],       4           \n\t"                  \
+      "addiu     %[temp0],    %[temp0],     -1          \n\t"                  \
+      "subu.qb   %[temp3],    %[temp2],     %[temp1]    \n\t"                  \
+      "usw       %[temp3],    0(%[dst])                 \n\t"                  \
+      "bnez      %[temp0],    1b                        \n\t"                  \
+      " addiu    %[dst],      %[dst],       4           \n\t"                  \
+    ".endif                                             \n\t"                  \
+    "4:                                                 \n\t"                  \
+      "beqz      %[temp6],    3f                        \n\t"                  \
+      " nop                                             \n\t"                  \
+    "2:                                                 \n\t"                  \
+      "lbu       %[temp1],    -1(%[src])                \n\t"                  \
+      "lbu       %[temp2],    0(%[src])                 \n\t"                  \
+      "addiu     %[src],      %[src],       1           \n\t"                  \
+    ".if "#INVERSE"                                     \n\t"                  \
+      "addu      %[temp3],    %[temp1],     %[temp2]    \n\t"                  \
+      "sb        %[temp3],    -1(%[src])                \n\t"                  \
+    ".else                                              \n\t"                  \
+      "subu      %[temp3],    %[temp1],     %[temp2]    \n\t"                  \
+      "sb        %[temp3],    0(%[dst])                 \n\t"                  \
+    ".endif                                             \n\t"                  \
+      "addiu     %[temp6],    %[temp6],     -1          \n\t"                  \
+      "bnez      %[temp6],    2b                        \n\t"                  \
+      " addiu    %[dst],      %[dst],       1           \n\t"                  \
+    "3:                                                 \n\t"                  \
+      ".set      pop                                    \n\t"                  \
+      : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),         \
+        [temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),         \
+        [temp6]"=&r"(temp6), [dst]"+&r"(pdst), [src]"+&r"(psrc)                \
+      : [length]"r"(ilength)                                                   \
+      : "memory"                                                               \
+    );                                                                         \
+  } while (0)
+
+static WEBP_INLINE void PredictLine(const uint8_t* src, uint8_t* dst,
+                                    int length, int inverse) {
+  if (inverse) {
+    DO_PREDICT_LINE(src, dst, length, 1);
+  } else {
+    DO_PREDICT_LINE(src, dst, length, 0);
+  }
+}
+
+#define DO_PREDICT_LINE_VERTICAL(SRC, PRED, DST, LENGTH, INVERSE) do {         \
+    const uint8_t* psrc = (uint8_t*)(SRC);                                     \
+    const uint8_t* ppred = (uint8_t*)(PRED);                                   \
+    uint8_t* pdst = (uint8_t*)(DST);                                           \
+    const int ilength = (int)(LENGTH);                                         \
+    int temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;                \
+    __asm__ volatile (                                                         \
+      ".set      push                                   \n\t"                  \
+      ".set      noreorder                              \n\t"                  \
+      "srl       %[temp0],    %[length],    0x3         \n\t"                  \
+      "beqz      %[temp0],    4f                        \n\t"                  \
+      " andi     %[temp7],    %[length],    0x7         \n\t"                  \
+    "1:                                                 \n\t"                  \
+      "ulw       %[temp1],    0(%[src])                 \n\t"                  \
+      "ulw       %[temp2],    0(%[pred])                \n\t"                  \
+      "ulw       %[temp3],    4(%[src])                 \n\t"                  \
+      "ulw       %[temp4],    4(%[pred])                \n\t"                  \
+      "addiu     %[src],      %[src],       8           \n\t"                  \
+    ".if "#INVERSE"                                     \n\t"                  \
+      "addu.qb   %[temp5],    %[temp1],     %[temp2]    \n\t"                  \
+      "addu.qb   %[temp6],    %[temp3],     %[temp4]    \n\t"                  \
+    ".else                                              \n\t"                  \
+      "subu.qb   %[temp5],    %[temp1],     %[temp2]    \n\t"                  \
+      "subu.qb   %[temp6],    %[temp3],     %[temp4]    \n\t"                  \
+    ".endif                                             \n\t"                  \
+      "addiu     %[pred],     %[pred],      8           \n\t"                  \
+      "usw       %[temp5],    0(%[dst])                 \n\t"                  \
+      "usw       %[temp6],    4(%[dst])                 \n\t"                  \
+      "addiu     %[temp0],    %[temp0],     -1          \n\t"                  \
+      "bnez      %[temp0],    1b                        \n\t"                  \
+      " addiu    %[dst],      %[dst],       8           \n\t"                  \
+    "4:                                                 \n\t"                  \
+      "beqz      %[temp7],    3f                        \n\t"                  \
+      " nop                                             \n\t"                  \
+    "2:                                                 \n\t"                  \
+      "lbu       %[temp1],    0(%[src])                 \n\t"                  \
+      "lbu       %[temp2],    0(%[pred])                \n\t"                  \
+      "addiu     %[src],      %[src],       1           \n\t"                  \
+      "addiu     %[pred],     %[pred],      1           \n\t"                  \
+    ".if "#INVERSE"                                     \n\t"                  \
+      "addu      %[temp3],    %[temp1],     %[temp2]    \n\t"                  \
+    ".else                                              \n\t"                  \
+      "subu      %[temp3],    %[temp1],     %[temp2]    \n\t"                  \
+    ".endif                                             \n\t"                  \
+      "sb        %[temp3],    0(%[dst])                 \n\t"                  \
+      "addiu     %[temp7],    %[temp7],     -1          \n\t"                  \
+      "bnez      %[temp7],    2b                        \n\t"                  \
+      " addiu    %[dst],      %[dst],       1           \n\t"                  \
+    "3:                                                 \n\t"                  \
+      ".set      pop                                    \n\t"                  \
+      : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),         \
+        [temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),         \
+        [temp6]"=&r"(temp6), [temp7]"=&r"(temp7), [pred]"+&r"(ppred),          \
+        [dst]"+&r"(pdst), [src]"+&r"(psrc)                                     \
+      : [length]"r"(ilength)                                                   \
+      : "memory"                                                               \
+    );                                                                         \
+  } while (0)
+
+#define PREDICT_LINE_ONE_PASS(SRC, PRED, DST, INVERSE) do {                    \
+    int temp1, temp2, temp3;                                                   \
+    __asm__ volatile (                                                         \
+      "lbu       %[temp1],   0(%[src])               \n\t"                     \
+      "lbu       %[temp2],   0(%[pred])              \n\t"                     \
+    ".if "#INVERSE"                                  \n\t"                     \
+      "addu      %[temp3],   %[temp1],   %[temp2]    \n\t"                     \
+    ".else                                           \n\t"                     \
+      "subu      %[temp3],   %[temp1],   %[temp2]    \n\t"                     \
+    ".endif                                          \n\t"                     \
+      "sb        %[temp3],   0(%[dst])               \n\t"                     \
+      : [temp1]"=&r"(temp1), [temp2]"=&r"(temp2), [temp3]"=&r"(temp3)          \
+      : [pred]"r"((PRED)), [dst]"r"((DST)), [src]"r"((SRC))                    \
+      : "memory"                                                               \
+    );                                                                         \
+  } while (0)
+
+//------------------------------------------------------------------------------
+// Horizontal filter.
+
+#define FILTER_LINE_BY_LINE(INVERSE) do {                                      \
+    while (row < last_row) {                                                   \
+      PREDICT_LINE_ONE_PASS(in, preds - stride, out, INVERSE);                 \
+      DO_PREDICT_LINE(in + 1, out + 1, width - 1, INVERSE);                    \
+      ++row;                                                                   \
+      preds += stride;                                                         \
+      in += stride;                                                            \
+      out += stride;                                                           \
+    }                                                                          \
+  } while (0)
+
+static WEBP_INLINE void DoHorizontalFilter(const uint8_t* in,
+                                           int width, int height, int stride,
+                                           int row, int num_rows,
+                                           int inverse, uint8_t* out) {
+  const uint8_t* preds;
+  const size_t start_offset = row * stride;
+  const int last_row = row + num_rows;
+  SANITY_CHECK(in, out);
+  in += start_offset;
+  out += start_offset;
+  preds = inverse ? out : in;
+
+  if (row == 0) {
+    // Leftmost pixel is the same as input for topmost scanline.
+    out[0] = in[0];
+    PredictLine(in + 1, out + 1, width - 1, inverse);
+    row = 1;
+    preds += stride;
+    in += stride;
+    out += stride;
+  }
+
+  // Filter line-by-line.
+  if (inverse) {
+    FILTER_LINE_BY_LINE(1);
+  } else {
+    FILTER_LINE_BY_LINE(0);
+  }
+}
+
+#undef FILTER_LINE_BY_LINE
+
+static void HorizontalFilter(const uint8_t* data, int width, int height,
+                             int stride, uint8_t* filtered_data) {
+  DoHorizontalFilter(data, width, height, stride, 0, height, 0, filtered_data);
+}
+
+static void HorizontalUnfilter(int width, int height, int stride, int row,
+                               int num_rows, uint8_t* data) {
+  DoHorizontalFilter(data, width, height, stride, row, num_rows, 1, data);
+}
+
+//------------------------------------------------------------------------------
+// Vertical filter.
+
+#define FILTER_LINE_BY_LINE(INVERSE) do {                                      \
+    while (row < last_row) {                                                   \
+      DO_PREDICT_LINE_VERTICAL(in, preds, out, width, INVERSE);                \
+      ++row;                                                                   \
+      preds += stride;                                                         \
+      in += stride;                                                            \
+      out += stride;                                                           \
+    }                                                                          \
+  } while (0)
+
+static WEBP_INLINE void DoVerticalFilter(const uint8_t* in,
+                                         int width, int height, int stride,
+                                         int row, int num_rows,
+                                         int inverse, uint8_t* out) {
+  const uint8_t* preds;
+  const size_t start_offset = row * stride;
+  const int last_row = row + num_rows;
+  SANITY_CHECK(in, out);
+  in += start_offset;
+  out += start_offset;
+  preds = inverse ? out : in;
+
+  if (row == 0) {
+    // Very first top-left pixel is copied.
+    out[0] = in[0];
+    // Rest of top scan-line is left-predicted.
+    PredictLine(in + 1, out + 1, width - 1, inverse);
+    row = 1;
+    in += stride;
+    out += stride;
+  } else {
+    // We are starting from in-between. Make sure 'preds' points to prev row.
+    preds -= stride;
+  }
+
+  // Filter line-by-line.
+  if (inverse) {
+    FILTER_LINE_BY_LINE(1);
+  } else {
+    FILTER_LINE_BY_LINE(0);
+  }
+}
+
+#undef FILTER_LINE_BY_LINE
+#undef DO_PREDICT_LINE_VERTICAL
+
+static void VerticalFilter(const uint8_t* data, int width, int height,
+                           int stride, uint8_t* filtered_data) {
+  DoVerticalFilter(data, width, height, stride, 0, height, 0, filtered_data);
+}
+
+static void VerticalUnfilter(int width, int height, int stride, int row,
+                             int num_rows, uint8_t* data) {
+  DoVerticalFilter(data, width, height, stride, row, num_rows, 1, data);
+}
+
+//------------------------------------------------------------------------------
+// Gradient filter.
+
+static WEBP_INLINE int GradientPredictor(uint8_t a, uint8_t b, uint8_t c) {
+  int temp0;
+  __asm__ volatile (
+    "addu             %[temp0],   %[a],       %[b]        \n\t"
+    "subu             %[temp0],   %[temp0],   %[c]        \n\t"
+    "shll_s.w         %[temp0],   %[temp0],   23          \n\t"
+    "precrqu_s.qb.ph  %[temp0],   %[temp0],   $zero       \n\t"
+    "srl              %[temp0],   %[temp0],   24          \n\t"
+    : [temp0]"=&r"(temp0)
+    : [a]"r"(a),[b]"r"(b),[c]"r"(c)
+  );
+  return temp0;
+}
+
+#define FILTER_LINE_BY_LINE(INVERSE, PREDS, OPERATION) do {                    \
+    while (row < last_row) {                                                   \
+      int w;                                                                   \
+      PREDICT_LINE_ONE_PASS(in, PREDS - stride, out, INVERSE);                 \
+      for (w = 1; w < width; ++w) {                                            \
+        const int pred = GradientPredictor(PREDS[w - 1],                       \
+                                           PREDS[w - stride],                  \
+                                           PREDS[w - stride - 1]);             \
+        out[w] = in[w] OPERATION pred;                                         \
+      }                                                                        \
+      ++row;                                                                   \
+      in += stride;                                                            \
+      out += stride;                                                           \
+    }                                                                          \
+  } while (0)
+
+static WEBP_INLINE void DoGradientFilter(const uint8_t* in,
+                                         int width, int height, int stride,
+                                         int row, int num_rows,
+                                         int inverse, uint8_t* out) {
+  const uint8_t* preds;
+  const size_t start_offset = row * stride;
+  const int last_row = row + num_rows;
+  SANITY_CHECK(in, out);
+  in += start_offset;
+  out += start_offset;
+  preds = inverse ? out : in;
+
+  // left prediction for top scan-line
+  if (row == 0) {
+    out[0] = in[0];
+    PredictLine(in + 1, out + 1, width - 1, inverse);
+    row = 1;
+    preds += stride;
+    in += stride;
+    out += stride;
+  }
+
+  // Filter line-by-line.
+  if (inverse) {
+    FILTER_LINE_BY_LINE(1, out, +);
+  } else {
+    FILTER_LINE_BY_LINE(0, in, -);
+  }
+}
+
+#undef FILTER_LINE_BY_LINE
+
+static void GradientFilter(const uint8_t* data, int width, int height,
+                           int stride, uint8_t* filtered_data) {
+  DoGradientFilter(data, width, height, stride, 0, height, 0, filtered_data);
+}
+
+static void GradientUnfilter(int width, int height, int stride, int row,
+                             int num_rows, uint8_t* data) {
+  DoGradientFilter(data, width, height, stride, row, num_rows, 1, data);
+}
+
+#undef PREDICT_LINE_ONE_PASS
+#undef DO_PREDICT_LINE
+#undef SANITY_CHECK
+
+#endif  // WEBP_USE_MIPS_DSP_R2
+
+//------------------------------------------------------------------------------
+
+extern void VP8FiltersInitMIPSdspR2(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8FiltersInitMIPSdspR2(void) {
+#if defined(WEBP_USE_MIPS_DSP_R2)
+  WebPFilters[WEBP_FILTER_HORIZONTAL] = HorizontalFilter;
+  WebPFilters[WEBP_FILTER_VERTICAL] = VerticalFilter;
+  WebPFilters[WEBP_FILTER_GRADIENT] = GradientFilter;
+
+  WebPUnfilters[WEBP_FILTER_HORIZONTAL] = HorizontalUnfilter;
+  WebPUnfilters[WEBP_FILTER_VERTICAL] = VerticalUnfilter;
+  WebPUnfilters[WEBP_FILTER_GRADIENT] = GradientUnfilter;
+#endif  // WEBP_USE_MIPS_DSP_R2
+}
+
+//------------------------------------------------------------------------------
diff --git a/Source/LibWebP/src/dsp/dsp.filters_sse2.c b/Source/LibWebP/src/dsp/dsp.filters_sse2.c
new file mode 100644
index 0000000..c2792ee
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.filters_sse2.c
@@ -0,0 +1,349 @@
+// Copyright 2015 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// SSE2 variant of alpha filters
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include "./dsp.h"
+
+#if defined(WEBP_USE_SSE2)
+
+#include <assert.h>
+#include <emmintrin.h>
+#include <stdlib.h>
+#include <string.h>
+
+//------------------------------------------------------------------------------
+// Helpful macro.
+
+# define SANITY_CHECK(in, out)                                                 \
+  assert(in != NULL);                                                          \
+  assert(out != NULL);                                                         \
+  assert(width > 0);                                                           \
+  assert(height > 0);                                                          \
+  assert(stride >= width);                                                     \
+  assert(row >= 0 && num_rows > 0 && row + num_rows <= height);                \
+  (void)height;  // Silence unused warning.
+
+static void PredictLineTop(const uint8_t* src, const uint8_t* pred,
+                           uint8_t* dst, int length, int inverse) {
+  int i;
+  const int max_pos = length & ~31;
+  assert(length >= 0);
+  if (inverse) {
+    for (i = 0; i < max_pos; i += 32) {
+      const __m128i A0 = _mm_loadu_si128((const __m128i*)&src[i +  0]);
+      const __m128i A1 = _mm_loadu_si128((const __m128i*)&src[i + 16]);
+      const __m128i B0 = _mm_loadu_si128((const __m128i*)&pred[i +  0]);
+      const __m128i B1 = _mm_loadu_si128((const __m128i*)&pred[i + 16]);
+      const __m128i C0 = _mm_add_epi8(A0, B0);
+      const __m128i C1 = _mm_add_epi8(A1, B1);
+      _mm_storeu_si128((__m128i*)&dst[i +  0], C0);
+      _mm_storeu_si128((__m128i*)&dst[i + 16], C1);
+    }
+    for (; i < length; ++i) dst[i] = src[i] + pred[i];
+  } else {
+    for (i = 0; i < max_pos; i += 32) {
+      const __m128i A0 = _mm_loadu_si128((const __m128i*)&src[i +  0]);
+      const __m128i A1 = _mm_loadu_si128((const __m128i*)&src[i + 16]);
+      const __m128i B0 = _mm_loadu_si128((const __m128i*)&pred[i +  0]);
+      const __m128i B1 = _mm_loadu_si128((const __m128i*)&pred[i + 16]);
+      const __m128i C0 = _mm_sub_epi8(A0, B0);
+      const __m128i C1 = _mm_sub_epi8(A1, B1);
+      _mm_storeu_si128((__m128i*)&dst[i +  0], C0);
+      _mm_storeu_si128((__m128i*)&dst[i + 16], C1);
+    }
+    for (; i < length; ++i) dst[i] = src[i] - pred[i];
+  }
+}
+
+// Special case for left-based prediction (when preds==dst-1 or preds==src-1).
+static void PredictLineLeft(const uint8_t* src, uint8_t* dst, int length,
+                            int inverse) {
+  int i;
+  if (length <= 0) return;
+  if (inverse) {
+    const int max_pos = length & ~7;
+    __m128i last = _mm_set_epi32(0, 0, 0, dst[-1]);
+    for (i = 0; i < max_pos; i += 8) {
+      const __m128i A0 = _mm_loadl_epi64((const __m128i*)(src + i));
+      const __m128i A1 = _mm_add_epi8(A0, last);
+      const __m128i A2 = _mm_slli_si128(A1, 1);
+      const __m128i A3 = _mm_add_epi8(A1, A2);
+      const __m128i A4 = _mm_slli_si128(A3, 2);
+      const __m128i A5 = _mm_add_epi8(A3, A4);
+      const __m128i A6 = _mm_slli_si128(A5, 4);
+      const __m128i A7 = _mm_add_epi8(A5, A6);
+      _mm_storel_epi64((__m128i*)(dst + i), A7);
+      last = _mm_srli_epi64(A7, 56);
+    }
+    for (; i < length; ++i) dst[i] = src[i] + dst[i - 1];
+  } else {
+    const int max_pos = length & ~31;
+    for (i = 0; i < max_pos; i += 32) {
+      const __m128i A0 = _mm_loadu_si128((const __m128i*)(src + i +  0    ));
+      const __m128i B0 = _mm_loadu_si128((const __m128i*)(src + i +  0 - 1));
+      const __m128i A1 = _mm_loadu_si128((const __m128i*)(src + i + 16    ));
+      const __m128i B1 = _mm_loadu_si128((const __m128i*)(src + i + 16 - 1));
+      const __m128i C0 = _mm_sub_epi8(A0, B0);
+      const __m128i C1 = _mm_sub_epi8(A1, B1);
+      _mm_storeu_si128((__m128i*)(dst + i +  0), C0);
+      _mm_storeu_si128((__m128i*)(dst + i + 16), C1);
+    }
+    for (; i < length; ++i) dst[i] = src[i] - src[i - 1];
+  }
+}
+
+static void PredictLineC(const uint8_t* src, const uint8_t* pred,
+                         uint8_t* dst, int length, int inverse) {
+  int i;
+  if (inverse) {
+    for (i = 0; i < length; ++i) dst[i] = src[i] + pred[i];
+  } else {
+    for (i = 0; i < length; ++i) dst[i] = src[i] - pred[i];
+  }
+}
+
+//------------------------------------------------------------------------------
+// Horizontal filter.
+
+static WEBP_INLINE void DoHorizontalFilter(const uint8_t* in,
+                                           int width, int height, int stride,
+                                           int row, int num_rows,
+                                           int inverse, uint8_t* out) {
+  const uint8_t* preds;
+  const size_t start_offset = row * stride;
+  const int last_row = row + num_rows;
+  SANITY_CHECK(in, out);
+  in += start_offset;
+  out += start_offset;
+  preds = inverse ? out : in;
+
+  if (row == 0) {
+    // Leftmost pixel is the same as input for topmost scanline.
+    out[0] = in[0];
+    PredictLineLeft(in + 1, out + 1, width - 1, inverse);
+    row = 1;
+    preds += stride;
+    in += stride;
+    out += stride;
+  }
+
+  // Filter line-by-line.
+  while (row < last_row) {
+    // Leftmost pixel is predicted from above.
+    PredictLineC(in, preds - stride, out, 1, inverse);
+    PredictLineLeft(in + 1, out + 1, width - 1, inverse);
+    ++row;
+    preds += stride;
+    in += stride;
+    out += stride;
+  }
+}
+
+//------------------------------------------------------------------------------
+// Vertical filter.
+
+static WEBP_INLINE void DoVerticalFilter(const uint8_t* in,
+                                         int width, int height, int stride,
+                                         int row, int num_rows,
+                                         int inverse, uint8_t* out) {
+  const uint8_t* preds;
+  const size_t start_offset = row * stride;
+  const int last_row = row + num_rows;
+  SANITY_CHECK(in, out);
+  in += start_offset;
+  out += start_offset;
+  preds = inverse ? out : in;
+
+  if (row == 0) {
+    // Very first top-left pixel is copied.
+    out[0] = in[0];
+    // Rest of top scan-line is left-predicted.
+    PredictLineLeft(in + 1, out + 1, width - 1, inverse);
+    row = 1;
+    in += stride;
+    out += stride;
+  } else {
+    // We are starting from in-between. Make sure 'preds' points to prev row.
+    preds -= stride;
+  }
+
+  // Filter line-by-line.
+  while (row < last_row) {
+    PredictLineTop(in, preds, out, width, inverse);
+    ++row;
+    preds += stride;
+    in += stride;
+    out += stride;
+  }
+}
+
+//------------------------------------------------------------------------------
+// Gradient filter.
+
+static WEBP_INLINE int GradientPredictorC(uint8_t a, uint8_t b, uint8_t c) {
+  const int g = a + b - c;
+  return ((g & ~0xff) == 0) ? g : (g < 0) ? 0 : 255;  // clip to 8bit
+}
+
+static void GradientPredictDirect(const uint8_t* const row,
+                                  const uint8_t* const top,
+                                  uint8_t* const out, int length) {
+  const int max_pos = length & ~7;
+  int i;
+  const __m128i zero = _mm_setzero_si128();
+  for (i = 0; i < max_pos; i += 8) {
+    const __m128i A0 = _mm_loadl_epi64((const __m128i*)&row[i - 1]);
+    const __m128i B0 = _mm_loadl_epi64((const __m128i*)&top[i]);
+    const __m128i C0 = _mm_loadl_epi64((const __m128i*)&top[i - 1]);
+    const __m128i D = _mm_loadl_epi64((const __m128i*)&row[i]);
+    const __m128i A1 = _mm_unpacklo_epi8(A0, zero);
+    const __m128i B1 = _mm_unpacklo_epi8(B0, zero);
+    const __m128i C1 = _mm_unpacklo_epi8(C0, zero);
+    const __m128i E = _mm_add_epi16(A1, B1);
+    const __m128i F = _mm_sub_epi16(E, C1);
+    const __m128i G = _mm_packus_epi16(F, zero);
+    const __m128i H = _mm_sub_epi8(D, G);
+    _mm_storel_epi64((__m128i*)(out + i), H);
+  }
+  for (; i < length; ++i) {
+    out[i] = row[i] - GradientPredictorC(row[i - 1], top[i], top[i - 1]);
+  }
+}
+
+static void GradientPredictInverse(const uint8_t* const in,
+                                   const uint8_t* const top,
+                                   uint8_t* const row, int length) {
+  if (length > 0) {
+    int i;
+    const int max_pos = length & ~7;
+    const __m128i zero = _mm_setzero_si128();
+    __m128i A = _mm_set_epi32(0, 0, 0, row[-1]);   // left sample
+    for (i = 0; i < max_pos; i += 8) {
+      const __m128i tmp0 = _mm_loadl_epi64((const __m128i*)&top[i]);
+      const __m128i tmp1 = _mm_loadl_epi64((const __m128i*)&top[i - 1]);
+      const __m128i B = _mm_unpacklo_epi8(tmp0, zero);
+      const __m128i C = _mm_unpacklo_epi8(tmp1, zero);
+      const __m128i tmp2 = _mm_loadl_epi64((const __m128i*)&in[i]);
+      const __m128i D = _mm_unpacklo_epi8(tmp2, zero);   // base input
+      const __m128i E = _mm_sub_epi16(B, C);  // unclipped gradient basis B - C
+      __m128i out = zero;                     // accumulator for output
+      __m128i mask_hi = _mm_set_epi32(0, 0, 0, 0xff);
+      int k = 8;
+      while (1) {
+        const __m128i tmp3 = _mm_add_epi16(A, E);        // delta = A + B - C
+        const __m128i tmp4 = _mm_min_epi16(tmp3, mask_hi);
+        const __m128i tmp5 = _mm_max_epi16(tmp4, zero);  // clipped delta
+        const __m128i tmp6 = _mm_add_epi16(tmp5, D);     // add to in[] values
+        A = _mm_and_si128(tmp6, mask_hi);                // 1-complement clip
+        out = _mm_or_si128(out, A);                      // accumulate output
+        if (--k == 0) break;
+        A = _mm_slli_si128(A, 2);                        // rotate left sample
+        mask_hi = _mm_slli_si128(mask_hi, 2);            // rotate mask
+      }
+      A = _mm_srli_si128(A, 14);       // prepare left sample for next iteration
+      _mm_storel_epi64((__m128i*)&row[i], _mm_packus_epi16(out, zero));
+    }
+    for (; i < length; ++i) {
+      row[i] = in[i] + GradientPredictorC(row[i - 1], top[i], top[i - 1]);
+    }
+  }
+}
+
+static WEBP_INLINE void DoGradientFilter(const uint8_t* in,
+                                         int width, int height, int stride,
+                                         int row, int num_rows,
+                                         int inverse, uint8_t* out) {
+  const size_t start_offset = row * stride;
+  const int last_row = row + num_rows;
+  SANITY_CHECK(in, out);
+  in += start_offset;
+  out += start_offset;
+
+  // left prediction for top scan-line
+  if (row == 0) {
+    out[0] = in[0];
+    PredictLineLeft(in + 1, out + 1, width - 1, inverse);
+    row = 1;
+    in += stride;
+    out += stride;
+  }
+
+  // Filter line-by-line.
+  while (row < last_row) {
+    if (inverse) {
+      PredictLineC(in, out - stride, out, 1, inverse);  // predict from above
+      GradientPredictInverse(in + 1, out + 1 - stride, out + 1, width - 1);
+    } else {
+      PredictLineC(in, in - stride, out, 1, inverse);
+      GradientPredictDirect(in + 1, in + 1 - stride, out + 1, width - 1);
+    }
+    ++row;
+    in += stride;
+    out += stride;
+  }
+}
+
+#undef SANITY_CHECK
+
+//------------------------------------------------------------------------------
+
+static void HorizontalFilter(const uint8_t* data, int width, int height,
+                             int stride, uint8_t* filtered_data) {
+  DoHorizontalFilter(data, width, height, stride, 0, height, 0, filtered_data);
+}
+
+static void VerticalFilter(const uint8_t* data, int width, int height,
+                           int stride, uint8_t* filtered_data) {
+  DoVerticalFilter(data, width, height, stride, 0, height, 0, filtered_data);
+}
+
+
+static void GradientFilter(const uint8_t* data, int width, int height,
+                           int stride, uint8_t* filtered_data) {
+  DoGradientFilter(data, width, height, stride, 0, height, 0, filtered_data);
+}
+
+
+//------------------------------------------------------------------------------
+
+static void VerticalUnfilter(int width, int height, int stride, int row,
+                             int num_rows, uint8_t* data) {
+  DoVerticalFilter(data, width, height, stride, row, num_rows, 1, data);
+}
+
+static void HorizontalUnfilter(int width, int height, int stride, int row,
+                               int num_rows, uint8_t* data) {
+  DoHorizontalFilter(data, width, height, stride, row, num_rows, 1, data);
+}
+
+static void GradientUnfilter(int width, int height, int stride, int row,
+                             int num_rows, uint8_t* data) {
+  DoGradientFilter(data, width, height, stride, row, num_rows, 1, data);
+}
+
+//------------------------------------------------------------------------------
+
+#endif    // WEBP_USE_SSE2
+
+extern void VP8FiltersInitSSE2(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8FiltersInitSSE2(void) {
+#if defined(WEBP_USE_SSE2)
+  WebPUnfilters[WEBP_FILTER_HORIZONTAL] = HorizontalUnfilter;
+  WebPUnfilters[WEBP_FILTER_VERTICAL] = VerticalUnfilter;
+  WebPUnfilters[WEBP_FILTER_GRADIENT] = GradientUnfilter;
+
+  WebPFilters[WEBP_FILTER_HORIZONTAL] = HorizontalFilter;
+  WebPFilters[WEBP_FILTER_VERTICAL] = VerticalFilter;
+  WebPFilters[WEBP_FILTER_GRADIENT] = GradientFilter;
+#endif
+}
diff --git a/Source/LibWebP/src/dsp/dsp.h b/Source/LibWebP/src/dsp/dsp.h
new file mode 100644
index 0000000..98952a8
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.h
@@ -0,0 +1,434 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+//   Speed-critical functions.
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#ifndef WEBP_DSP_DSP_H_
+#define WEBP_DSP_DSP_H_
+
+#ifdef HAVE_CONFIG_H
+#include "../webp/config.h"
+#endif
+
+#include "../webp/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define BPS 32   // this is the common stride for enc/dec
+
+//------------------------------------------------------------------------------
+// CPU detection
+
+#if defined(__GNUC__)
+# define LOCAL_GCC_VERSION ((__GNUC__ << 8) | __GNUC_MINOR__)
+# define LOCAL_GCC_PREREQ(maj, min) \
+    (LOCAL_GCC_VERSION >= (((maj) << 8) | (min)))
+#else
+# define LOCAL_GCC_VERSION 0
+# define LOCAL_GCC_PREREQ(maj, min) 0
+#endif
+
+#ifdef __clang__
+# define LOCAL_CLANG_VERSION ((__clang_major__ << 8) | __clang_minor__)
+# define LOCAL_CLANG_PREREQ(maj, min) \
+    (LOCAL_CLANG_VERSION >= (((maj) << 8) | (min)))
+#else
+# define LOCAL_CLANG_VERSION 0
+# define LOCAL_CLANG_PREREQ(maj, min) 0
+#endif  // __clang__
+
+#if defined(_MSC_VER) && _MSC_VER > 1310 && \
+    (defined(_M_X64) || defined(_M_IX86))
+#define WEBP_MSC_SSE2  // Visual C++ SSE2 targets
+#endif
+
+// WEBP_HAVE_* are used to indicate the presence of the instruction set in dsp
+// files without intrinsics, allowing the corresponding Init() to be called.
+// Files containing intrinsics will need to be built targeting the instruction
+// set so should succeed on one of the earlier tests.
+#if defined(__SSE2__) || defined(WEBP_MSC_SSE2) || defined(WEBP_HAVE_SSE2)
+#define WEBP_USE_SSE2
+#endif
+
+#if defined(__AVX2__) || defined(WEBP_HAVE_AVX2)
+#define WEBP_USE_AVX2
+#endif
+
+#if defined(__ANDROID__) && defined(__ARM_ARCH_7A__)
+#define WEBP_ANDROID_NEON  // Android targets that might support NEON
+#endif
+
+#if defined(__ARM_NEON__) || defined(WEBP_ANDROID_NEON) || defined(__aarch64__)
+#define WEBP_USE_NEON
+#endif
+
+#if defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_M_ARM)
+#define WEBP_USE_NEON
+#define WEBP_USE_INTRINSICS
+#endif
+
+#if defined(__mips__) && !defined(__mips64) && (__mips_isa_rev < 6)
+#define WEBP_USE_MIPS32
+#if (__mips_isa_rev >= 2)
+#define WEBP_USE_MIPS32_R2
+#if defined(__mips_dspr2) || (__mips_dsp_rev >= 2)
+#define WEBP_USE_MIPS_DSP_R2
+#endif
+#endif
+#endif
+
+// This macro prevents thread_sanitizer from reporting known concurrent writes.
+#define WEBP_TSAN_IGNORE_FUNCTION
+#if defined(__has_feature)
+#if __has_feature(thread_sanitizer)
+#undef WEBP_TSAN_IGNORE_FUNCTION
+#define WEBP_TSAN_IGNORE_FUNCTION __attribute__((no_sanitize_thread))
+#endif
+#endif
+
+typedef enum {
+  kSSE2,
+  kSSE3,
+  kAVX,
+  kAVX2,
+  kNEON,
+  kMIPS32,
+  kMIPSdspR2
+} CPUFeature;
+// returns true if the CPU supports the feature.
+typedef int (*VP8CPUInfo)(CPUFeature feature);
+WEBP_EXTERN(VP8CPUInfo) VP8GetCPUInfo;
+
+//------------------------------------------------------------------------------
+// Encoding
+
+// Transforms
+// VP8Idct: Does one of two inverse transforms. If do_two is set, the transforms
+//          will be done for (ref, in, dst) and (ref + 4, in + 16, dst + 4).
+typedef void (*VP8Idct)(const uint8_t* ref, const int16_t* in, uint8_t* dst,
+                        int do_two);
+typedef void (*VP8Fdct)(const uint8_t* src, const uint8_t* ref, int16_t* out);
+typedef void (*VP8WHT)(const int16_t* in, int16_t* out);
+extern VP8Idct VP8ITransform;
+extern VP8Fdct VP8FTransform;
+extern VP8WHT VP8FTransformWHT;
+// Predictions
+// *dst is the destination block. *top and *left can be NULL.
+typedef void (*VP8IntraPreds)(uint8_t *dst, const uint8_t* left,
+                              const uint8_t* top);
+typedef void (*VP8Intra4Preds)(uint8_t *dst, const uint8_t* top);
+extern VP8Intra4Preds VP8EncPredLuma4;
+extern VP8IntraPreds VP8EncPredLuma16;
+extern VP8IntraPreds VP8EncPredChroma8;
+
+typedef int (*VP8Metric)(const uint8_t* pix, const uint8_t* ref);
+extern VP8Metric VP8SSE16x16, VP8SSE16x8, VP8SSE8x8, VP8SSE4x4;
+typedef int (*VP8WMetric)(const uint8_t* pix, const uint8_t* ref,
+                          const uint16_t* const weights);
+extern VP8WMetric VP8TDisto4x4, VP8TDisto16x16;
+
+typedef void (*VP8BlockCopy)(const uint8_t* src, uint8_t* dst);
+extern VP8BlockCopy VP8Copy4x4;
+extern VP8BlockCopy VP8Copy16x8;
+// Quantization
+struct VP8Matrix;   // forward declaration
+typedef int (*VP8QuantizeBlock)(int16_t in[16], int16_t out[16],
+                                const struct VP8Matrix* const mtx);
+// Same as VP8QuantizeBlock, but quantizes two consecutive blocks.
+typedef int (*VP8Quantize2Blocks)(int16_t in[32], int16_t out[32],
+                                  const struct VP8Matrix* const mtx);
+
+extern VP8QuantizeBlock VP8EncQuantizeBlock;
+extern VP8Quantize2Blocks VP8EncQuantize2Blocks;
+
+// specific to 2nd transform:
+typedef int (*VP8QuantizeBlockWHT)(int16_t in[16], int16_t out[16],
+                                   const struct VP8Matrix* const mtx);
+extern VP8QuantizeBlockWHT VP8EncQuantizeBlockWHT;
+
+extern const int VP8DspScan[16 + 4 + 4];
+
+// Collect histogram for susceptibility calculation.
+#define MAX_COEFF_THRESH   31   // size of histogram used by CollectHistogram.
+typedef struct {
+  // We only need to store max_value and last_non_zero, not the distribution.
+  int max_value;
+  int last_non_zero;
+} VP8Histogram;
+typedef void (*VP8CHisto)(const uint8_t* ref, const uint8_t* pred,
+                          int start_block, int end_block,
+                          VP8Histogram* const histo);
+extern VP8CHisto VP8CollectHistogram;
+// General-purpose util function to help VP8CollectHistogram().
+void VP8LSetHistogramData(const int distribution[MAX_COEFF_THRESH + 1],
+                          VP8Histogram* const histo);
+
+// must be called before using any of the above
+void VP8EncDspInit(void);
+
+//------------------------------------------------------------------------------
+// cost functions (encoding)
+
+extern const uint16_t VP8EntropyCost[256];        // 8bit fixed-point log(p)
+// approximate cost per level:
+extern const uint16_t VP8LevelFixedCosts[2047 /*MAX_LEVEL*/ + 1];
+extern const uint8_t VP8EncBands[16 + 1];
+
+struct VP8Residual;
+typedef void (*VP8SetResidualCoeffsFunc)(const int16_t* const coeffs,
+                                         struct VP8Residual* const res);
+extern VP8SetResidualCoeffsFunc VP8SetResidualCoeffs;
+
+// Cost calculation function.
+typedef int (*VP8GetResidualCostFunc)(int ctx0,
+                                      const struct VP8Residual* const res);
+extern VP8GetResidualCostFunc VP8GetResidualCost;
+
+// must be called before anything using the above
+void VP8EncDspCostInit(void);
+
+//------------------------------------------------------------------------------
+// Decoding
+
+typedef void (*VP8DecIdct)(const int16_t* coeffs, uint8_t* dst);
+// when doing two transforms, coeffs is actually int16_t[2][16].
+typedef void (*VP8DecIdct2)(const int16_t* coeffs, uint8_t* dst, int do_two);
+extern VP8DecIdct2 VP8Transform;
+extern VP8DecIdct VP8TransformAC3;
+extern VP8DecIdct VP8TransformUV;
+extern VP8DecIdct VP8TransformDC;
+extern VP8DecIdct VP8TransformDCUV;
+extern VP8WHT VP8TransformWHT;
+
+// *dst is the destination block, with stride BPS. Boundary samples are
+// assumed accessible when needed.
+typedef void (*VP8PredFunc)(uint8_t* dst);
+extern VP8PredFunc VP8PredLuma16[/* NUM_B_DC_MODES */];
+extern VP8PredFunc VP8PredChroma8[/* NUM_B_DC_MODES */];
+extern VP8PredFunc VP8PredLuma4[/* NUM_BMODES */];
+
+// clipping tables (for filtering)
+extern const int8_t* const VP8ksclip1;  // clips [-1020, 1020] to [-128, 127]
+extern const int8_t* const VP8ksclip2;  // clips [-112, 112] to [-16, 15]
+extern const uint8_t* const VP8kclip1;  // clips [-255,511] to [0,255]
+extern const uint8_t* const VP8kabs0;   // abs(x) for x in [-255,255]
+// must be called first
+void VP8InitClipTables(void);
+
+// simple filter (only for luma)
+typedef void (*VP8SimpleFilterFunc)(uint8_t* p, int stride, int thresh);
+extern VP8SimpleFilterFunc VP8SimpleVFilter16;
+extern VP8SimpleFilterFunc VP8SimpleHFilter16;
+extern VP8SimpleFilterFunc VP8SimpleVFilter16i;  // filter 3 inner edges
+extern VP8SimpleFilterFunc VP8SimpleHFilter16i;
+
+// regular filter (on both macroblock edges and inner edges)
+typedef void (*VP8LumaFilterFunc)(uint8_t* luma, int stride,
+                                  int thresh, int ithresh, int hev_t);
+typedef void (*VP8ChromaFilterFunc)(uint8_t* u, uint8_t* v, int stride,
+                                    int thresh, int ithresh, int hev_t);
+// on outer edge
+extern VP8LumaFilterFunc VP8VFilter16;
+extern VP8LumaFilterFunc VP8HFilter16;
+extern VP8ChromaFilterFunc VP8VFilter8;
+extern VP8ChromaFilterFunc VP8HFilter8;
+
+// on inner edge
+extern VP8LumaFilterFunc VP8VFilter16i;   // filtering 3 inner edges altogether
+extern VP8LumaFilterFunc VP8HFilter16i;
+extern VP8ChromaFilterFunc VP8VFilter8i;  // filtering u and v altogether
+extern VP8ChromaFilterFunc VP8HFilter8i;
+
+// must be called before anything using the above
+void VP8DspInit(void);
+
+//------------------------------------------------------------------------------
+// WebP I/O
+
+#define FANCY_UPSAMPLING   // undefined to remove fancy upsampling support
+
+// Convert a pair of y/u/v lines together to the output rgb/a colorspace.
+// bottom_y can be NULL if only one line of output is needed (at top/bottom).
+typedef void (*WebPUpsampleLinePairFunc)(
+    const uint8_t* top_y, const uint8_t* bottom_y,
+    const uint8_t* top_u, const uint8_t* top_v,
+    const uint8_t* cur_u, const uint8_t* cur_v,
+    uint8_t* top_dst, uint8_t* bottom_dst, int len);
+
+#ifdef FANCY_UPSAMPLING
+
+// Fancy upsampling functions to convert YUV to RGB(A) modes
+extern WebPUpsampleLinePairFunc WebPUpsamplers[/* MODE_LAST */];
+
+#endif    // FANCY_UPSAMPLING
+
+// Per-row point-sampling methods.
+typedef void (*WebPSamplerRowFunc)(const uint8_t* y,
+                                   const uint8_t* u, const uint8_t* v,
+                                   uint8_t* dst, int len);
+// Generic function to apply 'WebPSamplerRowFunc' to the whole plane:
+void WebPSamplerProcessPlane(const uint8_t* y, int y_stride,
+                             const uint8_t* u, const uint8_t* v, int uv_stride,
+                             uint8_t* dst, int dst_stride,
+                             int width, int height, WebPSamplerRowFunc func);
+
+// Sampling functions to convert rows of YUV to RGB(A)
+extern WebPSamplerRowFunc WebPSamplers[/* MODE_LAST */];
+
+// General function for converting two lines of ARGB or RGBA.
+// 'alpha_is_last' should be true if 0xff000000 is stored in memory as
+// as 0x00, 0x00, 0x00, 0xff (little endian).
+WebPUpsampleLinePairFunc WebPGetLinePairConverter(int alpha_is_last);
+
+// YUV444->RGB converters
+typedef void (*WebPYUV444Converter)(const uint8_t* y,
+                                    const uint8_t* u, const uint8_t* v,
+                                    uint8_t* dst, int len);
+
+extern WebPYUV444Converter WebPYUV444Converters[/* MODE_LAST */];
+
+// Must be called before using the WebPUpsamplers[] (and for premultiplied
+// colorspaces like rgbA, rgbA4444, etc)
+void WebPInitUpsamplers(void);
+// Must be called before using WebPSamplers[]
+void WebPInitSamplers(void);
+// Must be called before using WebPYUV444Converters[]
+void WebPInitYUV444Converters(void);
+
+//------------------------------------------------------------------------------
+// Rescaler
+
+struct WebPRescaler;
+
+// Import a row of data and save its contribution in the rescaler.
+// 'channel' denotes the channel number to be imported.
+extern void (*WebPRescalerImportRow)(struct WebPRescaler* const wrk,
+                                     const uint8_t* const src, int channel);
+
+// Export one row (starting at x_out position) from rescaler.
+extern void (*WebPRescalerExportRow)(struct WebPRescaler* const wrk, int x_out);
+
+// Plain-C implementation, as fall-back.
+extern void WebPRescalerExportRowC(struct WebPRescaler* const wrk, int x_out);
+
+// Must be called first before using the above.
+void WebPRescalerDspInit(void);
+
+//------------------------------------------------------------------------------
+// Utilities for processing transparent channel.
+
+// Apply alpha pre-multiply on an rgba, bgra or argb plane of size w * h.
+// alpha_first should be 0 for argb, 1 for rgba or bgra (where alpha is last).
+extern void (*WebPApplyAlphaMultiply)(
+    uint8_t* rgba, int alpha_first, int w, int h, int stride);
+
+// Same, buf specifically for RGBA4444 format
+extern void (*WebPApplyAlphaMultiply4444)(
+    uint8_t* rgba4444, int w, int h, int stride);
+
+// Dispatch the values from alpha[] plane to the ARGB destination 'dst'.
+// Returns true if alpha[] plane has non-trivial values different from 0xff.
+extern int (*WebPDispatchAlpha)(const uint8_t* alpha, int alpha_stride,
+                                int width, int height,
+                                uint8_t* dst, int dst_stride);
+
+// Transfer packed 8b alpha[] values to green channel in dst[], zero'ing the
+// A/R/B values. 'dst_stride' is the stride for dst[] in uint32_t units.
+extern void (*WebPDispatchAlphaToGreen)(const uint8_t* alpha, int alpha_stride,
+                                        int width, int height,
+                                        uint32_t* dst, int dst_stride);
+
+// Extract the alpha values from 32b values in argb[] and pack them into alpha[]
+// (this is the opposite of WebPDispatchAlpha).
+// Returns true if there's only trivial 0xff alpha values.
+extern int (*WebPExtractAlpha)(const uint8_t* argb, int argb_stride,
+                               int width, int height,
+                               uint8_t* alpha, int alpha_stride);
+
+// Pre-Multiply operation transforms x into x * A / 255  (where x=Y,R,G or B).
+// Un-Multiply operation transforms x into x * 255 / A.
+
+// Pre-Multiply or Un-Multiply (if 'inverse' is true) argb values in a row.
+extern void (*WebPMultARGBRow)(uint32_t* const ptr, int width, int inverse);
+
+// Same a WebPMultARGBRow(), but for several rows.
+void WebPMultARGBRows(uint8_t* ptr, int stride, int width, int num_rows,
+                      int inverse);
+
+// Same for a row of single values, with side alpha values.
+extern void (*WebPMultRow)(uint8_t* const ptr, const uint8_t* const alpha,
+                           int width, int inverse);
+
+// Same a WebPMultRow(), but for several 'num_rows' rows.
+void WebPMultRows(uint8_t* ptr, int stride,
+                  const uint8_t* alpha, int alpha_stride,
+                  int width, int num_rows, int inverse);
+
+// Plain-C versions, used as fallback by some implementations.
+void WebPMultRowC(uint8_t* const ptr, const uint8_t* const alpha,
+                  int width, int inverse);
+void WebPMultARGBRowC(uint32_t* const ptr, int width, int inverse);
+
+// To be called first before using the above.
+void WebPInitAlphaProcessing(void);
+
+// ARGB packing function: a/r/g/b input is rgba or bgra order.
+extern void (*VP8PackARGB)(const uint8_t* a, const uint8_t* r,
+                           const uint8_t* g, const uint8_t* b, int len,
+                           uint32_t* out);
+
+// RGB packing function. 'step' can be 3 or 4. r/g/b input is rgb or bgr order.
+extern void (*VP8PackRGB)(const uint8_t* r, const uint8_t* g, const uint8_t* b,
+                          int len, int step, uint32_t* out);
+
+// To be called first before using the above.
+void VP8EncDspARGBInit(void);
+
+//------------------------------------------------------------------------------
+// Filter functions
+
+typedef enum {     // Filter types.
+  WEBP_FILTER_NONE = 0,
+  WEBP_FILTER_HORIZONTAL,
+  WEBP_FILTER_VERTICAL,
+  WEBP_FILTER_GRADIENT,
+  WEBP_FILTER_LAST = WEBP_FILTER_GRADIENT + 1,  // end marker
+  WEBP_FILTER_BEST,    // meta-types
+  WEBP_FILTER_FAST
+} WEBP_FILTER_TYPE;
+
+typedef void (*WebPFilterFunc)(const uint8_t* in, int width, int height,
+                               int stride, uint8_t* out);
+typedef void (*WebPUnfilterFunc)(int width, int height, int stride,
+                                 int row, int num_rows, uint8_t* data);
+
+// Filter the given data using the given predictor.
+// 'in' corresponds to a 2-dimensional pixel array of size (stride * height)
+// in raster order.
+// 'stride' is number of bytes per scan line (with possible padding).
+// 'out' should be pre-allocated.
+extern WebPFilterFunc WebPFilters[WEBP_FILTER_LAST];
+
+// In-place reconstruct the original data from the given filtered data.
+// The reconstruction will be done for 'num_rows' rows starting from 'row'
+// (assuming rows upto 'row - 1' are already reconstructed).
+extern WebPUnfilterFunc WebPUnfilters[WEBP_FILTER_LAST];
+
+// To be called first before using the above.
+void VP8FiltersInit(void);
+
+#ifdef __cplusplus
+}    // extern "C"
+#endif
+
+#endif  /* WEBP_DSP_DSP_H_ */
diff --git a/Source/LibWebP/src/dsp/dsp.lossless.c b/Source/LibWebP/src/dsp/dsp.lossless.c
new file mode 100644
index 0000000..6322a97
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.lossless.c
@@ -0,0 +1,1838 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Image transforms and color space conversion methods for lossless decoder.
+//
+// Authors: Vikas Arora (vikaas.arora at gmail.com)
+//          Jyrki Alakuijala (jyrki at google.com)
+//          Urvang Joshi (urvang at google.com)
+
+#include "./dsp.h"
+
+#include <math.h>
+#include <stdlib.h>
+#include "../dec/vp8li.h"
+#include "../utils/endian_inl.h"
+#include "./lossless.h"
+#include "./yuv.h"
+
+#define MAX_DIFF_COST (1e30f)
+
+// lookup table for small values of log2(int)
+const float kLog2Table[LOG_LOOKUP_IDX_MAX] = {
+  0.0000000000000000f, 0.0000000000000000f,
+  1.0000000000000000f, 1.5849625007211560f,
+  2.0000000000000000f, 2.3219280948873621f,
+  2.5849625007211560f, 2.8073549220576041f,
+  3.0000000000000000f, 3.1699250014423121f,
+  3.3219280948873621f, 3.4594316186372973f,
+  3.5849625007211560f, 3.7004397181410921f,
+  3.8073549220576041f, 3.9068905956085187f,
+  4.0000000000000000f, 4.0874628412503390f,
+  4.1699250014423121f, 4.2479275134435852f,
+  4.3219280948873626f, 4.3923174227787606f,
+  4.4594316186372973f, 4.5235619560570130f,
+  4.5849625007211560f, 4.6438561897747243f,
+  4.7004397181410917f, 4.7548875021634682f,
+  4.8073549220576037f, 4.8579809951275718f,
+  4.9068905956085187f, 4.9541963103868749f,
+  5.0000000000000000f, 5.0443941193584533f,
+  5.0874628412503390f, 5.1292830169449663f,
+  5.1699250014423121f, 5.2094533656289501f,
+  5.2479275134435852f, 5.2854022188622487f,
+  5.3219280948873626f, 5.3575520046180837f,
+  5.3923174227787606f, 5.4262647547020979f,
+  5.4594316186372973f, 5.4918530963296747f,
+  5.5235619560570130f, 5.5545888516776376f,
+  5.5849625007211560f, 5.6147098441152083f,
+  5.6438561897747243f, 5.6724253419714951f,
+  5.7004397181410917f, 5.7279204545631987f,
+  5.7548875021634682f, 5.7813597135246599f,
+  5.8073549220576037f, 5.8328900141647412f,
+  5.8579809951275718f, 5.8826430493618415f,
+  5.9068905956085187f, 5.9307373375628866f,
+  5.9541963103868749f, 5.9772799234999167f,
+  6.0000000000000000f, 6.0223678130284543f,
+  6.0443941193584533f, 6.0660891904577720f,
+  6.0874628412503390f, 6.1085244567781691f,
+  6.1292830169449663f, 6.1497471195046822f,
+  6.1699250014423121f, 6.1898245588800175f,
+  6.2094533656289501f, 6.2288186904958804f,
+  6.2479275134435852f, 6.2667865406949010f,
+  6.2854022188622487f, 6.3037807481771030f,
+  6.3219280948873626f, 6.3398500028846243f,
+  6.3575520046180837f, 6.3750394313469245f,
+  6.3923174227787606f, 6.4093909361377017f,
+  6.4262647547020979f, 6.4429434958487279f,
+  6.4594316186372973f, 6.4757334309663976f,
+  6.4918530963296747f, 6.5077946401986963f,
+  6.5235619560570130f, 6.5391588111080309f,
+  6.5545888516776376f, 6.5698556083309478f,
+  6.5849625007211560f, 6.5999128421871278f,
+  6.6147098441152083f, 6.6293566200796094f,
+  6.6438561897747243f, 6.6582114827517946f,
+  6.6724253419714951f, 6.6865005271832185f,
+  6.7004397181410917f, 6.7142455176661224f,
+  6.7279204545631987f, 6.7414669864011464f,
+  6.7548875021634682f, 6.7681843247769259f,
+  6.7813597135246599f, 6.7944158663501061f,
+  6.8073549220576037f, 6.8201789624151878f,
+  6.8328900141647412f, 6.8454900509443747f,
+  6.8579809951275718f, 6.8703647195834047f,
+  6.8826430493618415f, 6.8948177633079437f,
+  6.9068905956085187f, 6.9188632372745946f,
+  6.9307373375628866f, 6.9425145053392398f,
+  6.9541963103868749f, 6.9657842846620869f,
+  6.9772799234999167f, 6.9886846867721654f,
+  7.0000000000000000f, 7.0112272554232539f,
+  7.0223678130284543f, 7.0334230015374501f,
+  7.0443941193584533f, 7.0552824355011898f,
+  7.0660891904577720f, 7.0768155970508308f,
+  7.0874628412503390f, 7.0980320829605263f,
+  7.1085244567781691f, 7.1189410727235076f,
+  7.1292830169449663f, 7.1395513523987936f,
+  7.1497471195046822f, 7.1598713367783890f,
+  7.1699250014423121f, 7.1799090900149344f,
+  7.1898245588800175f, 7.1996723448363644f,
+  7.2094533656289501f, 7.2191685204621611f,
+  7.2288186904958804f, 7.2384047393250785f,
+  7.2479275134435852f, 7.2573878426926521f,
+  7.2667865406949010f, 7.2761244052742375f,
+  7.2854022188622487f, 7.2946207488916270f,
+  7.3037807481771030f, 7.3128829552843557f,
+  7.3219280948873626f, 7.3309168781146167f,
+  7.3398500028846243f, 7.3487281542310771f,
+  7.3575520046180837f, 7.3663222142458160f,
+  7.3750394313469245f, 7.3837042924740519f,
+  7.3923174227787606f, 7.4008794362821843f,
+  7.4093909361377017f, 7.4178525148858982f,
+  7.4262647547020979f, 7.4346282276367245f,
+  7.4429434958487279f, 7.4512111118323289f,
+  7.4594316186372973f, 7.4676055500829976f,
+  7.4757334309663976f, 7.4838157772642563f,
+  7.4918530963296747f, 7.4998458870832056f,
+  7.5077946401986963f, 7.5156998382840427f,
+  7.5235619560570130f, 7.5313814605163118f,
+  7.5391588111080309f, 7.5468944598876364f,
+  7.5545888516776376f, 7.5622424242210728f,
+  7.5698556083309478f, 7.5774288280357486f,
+  7.5849625007211560f, 7.5924570372680806f,
+  7.5999128421871278f, 7.6073303137496104f,
+  7.6147098441152083f, 7.6220518194563764f,
+  7.6293566200796094f, 7.6366246205436487f,
+  7.6438561897747243f, 7.6510516911789281f,
+  7.6582114827517946f, 7.6653359171851764f,
+  7.6724253419714951f, 7.6794800995054464f,
+  7.6865005271832185f, 7.6934869574993252f,
+  7.7004397181410917f, 7.7073591320808825f,
+  7.7142455176661224f, 7.7210991887071855f,
+  7.7279204545631987f, 7.7347096202258383f,
+  7.7414669864011464f, 7.7481928495894605f,
+  7.7548875021634682f, 7.7615512324444795f,
+  7.7681843247769259f, 7.7747870596011736f,
+  7.7813597135246599f, 7.7879025593914317f,
+  7.7944158663501061f, 7.8008998999203047f,
+  7.8073549220576037f, 7.8137811912170374f,
+  7.8201789624151878f, 7.8265484872909150f,
+  7.8328900141647412f, 7.8392037880969436f,
+  7.8454900509443747f, 7.8517490414160571f,
+  7.8579809951275718f, 7.8641861446542797f,
+  7.8703647195834047f, 7.8765169465649993f,
+  7.8826430493618415f, 7.8887432488982591f,
+  7.8948177633079437f, 7.9008668079807486f,
+  7.9068905956085187f, 7.9128893362299619f,
+  7.9188632372745946f, 7.9248125036057812f,
+  7.9307373375628866f, 7.9366379390025709f,
+  7.9425145053392398f, 7.9483672315846778f,
+  7.9541963103868749f, 7.9600019320680805f,
+  7.9657842846620869f, 7.9715435539507719f,
+  7.9772799234999167f, 7.9829935746943103f,
+  7.9886846867721654f, 7.9943534368588577f
+};
+
+const float kSLog2Table[LOG_LOOKUP_IDX_MAX] = {
+  0.00000000f,    0.00000000f,  2.00000000f,   4.75488750f,
+  8.00000000f,   11.60964047f,  15.50977500f,  19.65148445f,
+  24.00000000f,  28.52932501f,  33.21928095f,  38.05374781f,
+  43.01955001f,  48.10571634f,  53.30296891f,  58.60335893f,
+  64.00000000f,  69.48686830f,  75.05865003f,  80.71062276f,
+  86.43856190f,  92.23866588f,  98.10749561f,  104.04192499f,
+  110.03910002f, 116.09640474f, 122.21143267f, 128.38196256f,
+  134.60593782f, 140.88144886f, 147.20671787f, 153.58008562f,
+  160.00000000f, 166.46500594f, 172.97373660f, 179.52490559f,
+  186.11730005f, 192.74977453f, 199.42124551f, 206.13068654f,
+  212.87712380f, 219.65963219f, 226.47733176f, 233.32938445f,
+  240.21499122f, 247.13338933f, 254.08384998f, 261.06567603f,
+  268.07820003f, 275.12078236f, 282.19280949f, 289.29369244f,
+  296.42286534f, 303.57978409f, 310.76392512f, 317.97478424f,
+  325.21187564f, 332.47473081f, 339.76289772f, 347.07593991f,
+  354.41343574f, 361.77497759f, 369.16017124f, 376.56863518f,
+  384.00000000f, 391.45390785f, 398.93001188f, 406.42797576f,
+  413.94747321f, 421.48818752f, 429.04981119f, 436.63204548f,
+  444.23460010f, 451.85719280f, 459.49954906f, 467.16140179f,
+  474.84249102f, 482.54256363f, 490.26137307f, 497.99867911f,
+  505.75424759f, 513.52785023f, 521.31926438f, 529.12827280f,
+  536.95466351f, 544.79822957f, 552.65876890f, 560.53608414f,
+  568.42998244f, 576.34027536f, 584.26677867f, 592.20931226f,
+  600.16769996f, 608.14176943f, 616.13135206f, 624.13628279f,
+  632.15640007f, 640.19154569f, 648.24156472f, 656.30630539f,
+  664.38561898f, 672.47935976f, 680.58738488f, 688.70955430f,
+  696.84573069f, 704.99577935f, 713.15956818f, 721.33696754f,
+  729.52785023f, 737.73209140f, 745.94956849f, 754.18016116f,
+  762.42375127f, 770.68022275f, 778.94946161f, 787.23135586f,
+  795.52579543f, 803.83267219f, 812.15187982f, 820.48331383f,
+  828.82687147f, 837.18245171f, 845.54995518f, 853.92928416f,
+  862.32034249f, 870.72303558f, 879.13727036f, 887.56295522f,
+  896.00000000f, 904.44831595f, 912.90781569f, 921.37841320f,
+  929.86002376f, 938.35256392f, 946.85595152f, 955.37010560f,
+  963.89494641f, 972.43039537f, 980.97637504f, 989.53280911f,
+  998.09962237f, 1006.67674069f, 1015.26409097f, 1023.86160116f,
+  1032.46920021f, 1041.08681805f, 1049.71438560f, 1058.35183469f,
+  1066.99909811f, 1075.65610955f, 1084.32280357f, 1092.99911564f,
+  1101.68498204f, 1110.38033993f, 1119.08512727f, 1127.79928282f,
+  1136.52274614f, 1145.25545758f, 1153.99735821f, 1162.74838989f,
+  1171.50849518f, 1180.27761738f, 1189.05570047f, 1197.84268914f,
+  1206.63852876f, 1215.44316535f, 1224.25654560f, 1233.07861684f,
+  1241.90932703f, 1250.74862473f, 1259.59645914f, 1268.45278005f,
+  1277.31753781f, 1286.19068338f, 1295.07216828f, 1303.96194457f,
+  1312.85996488f, 1321.76618236f, 1330.68055071f, 1339.60302413f,
+  1348.53355734f, 1357.47210556f, 1366.41862452f, 1375.37307041f,
+  1384.33539991f, 1393.30557020f, 1402.28353887f, 1411.26926400f,
+  1420.26270412f, 1429.26381818f, 1438.27256558f, 1447.28890615f,
+  1456.31280014f, 1465.34420819f, 1474.38309138f, 1483.42941118f,
+  1492.48312945f, 1501.54420843f, 1510.61261078f, 1519.68829949f,
+  1528.77123795f, 1537.86138993f, 1546.95871952f, 1556.06319119f,
+  1565.17476976f, 1574.29342040f, 1583.41910860f, 1592.55180020f,
+  1601.69146137f, 1610.83805860f, 1619.99155871f, 1629.15192882f,
+  1638.31913637f, 1647.49314911f, 1656.67393509f, 1665.86146266f,
+  1675.05570047f, 1684.25661744f, 1693.46418280f, 1702.67836605f,
+  1711.89913698f, 1721.12646563f, 1730.36032233f, 1739.60067768f,
+  1748.84750254f, 1758.10076802f, 1767.36044551f, 1776.62650662f,
+  1785.89892323f, 1795.17766747f, 1804.46271172f, 1813.75402857f,
+  1823.05159087f, 1832.35537170f, 1841.66534438f, 1850.98148244f,
+  1860.30375965f, 1869.63214999f, 1878.96662767f, 1888.30716711f,
+  1897.65374295f, 1907.00633003f, 1916.36490342f, 1925.72943838f,
+  1935.09991037f, 1944.47629506f, 1953.85856831f, 1963.24670620f,
+  1972.64068498f, 1982.04048108f, 1991.44607117f, 2000.85743204f,
+  2010.27454072f, 2019.69737440f, 2029.12591044f, 2038.56012640f
+};
+
+const VP8LPrefixCode kPrefixEncodeCode[PREFIX_LOOKUP_IDX_MAX] = {
+  { 0, 0}, { 0, 0}, { 1, 0}, { 2, 0}, { 3, 0}, { 4, 1}, { 4, 1}, { 5, 1},
+  { 5, 1}, { 6, 2}, { 6, 2}, { 6, 2}, { 6, 2}, { 7, 2}, { 7, 2}, { 7, 2},
+  { 7, 2}, { 8, 3}, { 8, 3}, { 8, 3}, { 8, 3}, { 8, 3}, { 8, 3}, { 8, 3},
+  { 8, 3}, { 9, 3}, { 9, 3}, { 9, 3}, { 9, 3}, { 9, 3}, { 9, 3}, { 9, 3},
+  { 9, 3}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4},
+  {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4},
+  {10, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4},
+  {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4},
+  {11, 4}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5},
+  {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5},
+  {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5},
+  {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5},
+  {12, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5},
+  {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5},
+  {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5},
+  {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5},
+  {13, 5}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6},
+  {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6},
+  {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6},
+  {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6},
+  {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6},
+  {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6},
+  {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6},
+  {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6},
+  {14, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6},
+  {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6},
+  {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6},
+  {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6},
+  {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6},
+  {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6},
+  {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6},
+  {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6},
+  {15, 6}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
+  {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
+  {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
+  {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
+  {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
+  {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
+  {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
+  {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
+  {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
+  {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
+  {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
+  {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
+  {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
+  {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
+  {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
+  {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
+  {16, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
+  {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
+  {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
+  {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
+  {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
+  {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
+  {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
+  {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
+  {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
+  {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
+  {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
+  {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
+  {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
+  {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
+  {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
+  {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
+};
+
+const uint8_t kPrefixEncodeExtraBitsValue[PREFIX_LOOKUP_IDX_MAX] = {
+   0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  2,  3,  0,  1,  2,  3,
+   0,  1,  2,  3,  4,  5,  6,  7,  0,  1,  2,  3,  4,  5,  6,  7,
+   0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
+   0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
+   0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
+  16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+   0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
+  16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+   0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
+  16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+  32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+  48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+   0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
+  16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+  32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+  48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+   0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
+  16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+  32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+  48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+  64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+  80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+  96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+  112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
+  127,
+   0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
+  16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+  32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+  48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+  64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+  80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+  96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+  112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126
+};
+
+// The threshold till approximate version of log_2 can be used.
+// Practically, we can get rid of the call to log() as the two values match to
+// very high degree (the ratio of these two is 0.99999x).
+// Keeping a high threshold for now.
+#define APPROX_LOG_WITH_CORRECTION_MAX  65536
+#define APPROX_LOG_MAX                   4096
+#define LOG_2_RECIPROCAL 1.44269504088896338700465094007086
+static float FastSLog2Slow(uint32_t v) {
+  assert(v >= LOG_LOOKUP_IDX_MAX);
+  if (v < APPROX_LOG_WITH_CORRECTION_MAX) {
+    int log_cnt = 0;
+    uint32_t y = 1;
+    int correction = 0;
+    const float v_f = (float)v;
+    const uint32_t orig_v = v;
+    do {
+      ++log_cnt;
+      v = v >> 1;
+      y = y << 1;
+    } while (v >= LOG_LOOKUP_IDX_MAX);
+    // vf = (2^log_cnt) * Xf; where y = 2^log_cnt and Xf < 256
+    // Xf = floor(Xf) * (1 + (v % y) / v)
+    // log2(Xf) = log2(floor(Xf)) + log2(1 + (v % y) / v)
+    // The correction factor: log(1 + d) ~ d; for very small d values, so
+    // log2(1 + (v % y) / v) ~ LOG_2_RECIPROCAL * (v % y)/v
+    // LOG_2_RECIPROCAL ~ 23/16
+    correction = (23 * (orig_v & (y - 1))) >> 4;
+    return v_f * (kLog2Table[v] + log_cnt) + correction;
+  } else {
+    return (float)(LOG_2_RECIPROCAL * v * log((double)v));
+  }
+}
+
+static float FastLog2Slow(uint32_t v) {
+  assert(v >= LOG_LOOKUP_IDX_MAX);
+  if (v < APPROX_LOG_WITH_CORRECTION_MAX) {
+    int log_cnt = 0;
+    uint32_t y = 1;
+    const uint32_t orig_v = v;
+    double log_2;
+    do {
+      ++log_cnt;
+      v = v >> 1;
+      y = y << 1;
+    } while (v >= LOG_LOOKUP_IDX_MAX);
+    log_2 = kLog2Table[v] + log_cnt;
+    if (orig_v >= APPROX_LOG_MAX) {
+      // Since the division is still expensive, add this correction factor only
+      // for large values of 'v'.
+      const int correction = (23 * (orig_v & (y - 1))) >> 4;
+      log_2 += (double)correction / orig_v;
+    }
+    return (float)log_2;
+  } else {
+    return (float)(LOG_2_RECIPROCAL * log((double)v));
+  }
+}
+
+//------------------------------------------------------------------------------
+// Image transforms.
+
+// Mostly used to reduce code size + readability
+static WEBP_INLINE int GetMin(int a, int b) { return (a > b) ? b : a; }
+
+// In-place sum of each component with mod 256.
+static WEBP_INLINE void AddPixelsEq(uint32_t* a, uint32_t b) {
+  const uint32_t alpha_and_green = (*a & 0xff00ff00u) + (b & 0xff00ff00u);
+  const uint32_t red_and_blue = (*a & 0x00ff00ffu) + (b & 0x00ff00ffu);
+  *a = (alpha_and_green & 0xff00ff00u) | (red_and_blue & 0x00ff00ffu);
+}
+
+static WEBP_INLINE uint32_t Average2(uint32_t a0, uint32_t a1) {
+  return (((a0 ^ a1) & 0xfefefefeL) >> 1) + (a0 & a1);
+}
+
+static WEBP_INLINE uint32_t Average3(uint32_t a0, uint32_t a1, uint32_t a2) {
+  return Average2(Average2(a0, a2), a1);
+}
+
+static WEBP_INLINE uint32_t Average4(uint32_t a0, uint32_t a1,
+                                     uint32_t a2, uint32_t a3) {
+  return Average2(Average2(a0, a1), Average2(a2, a3));
+}
+
+static WEBP_INLINE uint32_t Clip255(uint32_t a) {
+  if (a < 256) {
+    return a;
+  }
+  // return 0, when a is a negative integer.
+  // return 255, when a is positive.
+  return ~a >> 24;
+}
+
+static WEBP_INLINE int AddSubtractComponentFull(int a, int b, int c) {
+  return Clip255(a + b - c);
+}
+
+static WEBP_INLINE uint32_t ClampedAddSubtractFull(uint32_t c0, uint32_t c1,
+                                                   uint32_t c2) {
+  const int a = AddSubtractComponentFull(c0 >> 24, c1 >> 24, c2 >> 24);
+  const int r = AddSubtractComponentFull((c0 >> 16) & 0xff,
+                                         (c1 >> 16) & 0xff,
+                                         (c2 >> 16) & 0xff);
+  const int g = AddSubtractComponentFull((c0 >> 8) & 0xff,
+                                         (c1 >> 8) & 0xff,
+                                         (c2 >> 8) & 0xff);
+  const int b = AddSubtractComponentFull(c0 & 0xff, c1 & 0xff, c2 & 0xff);
+  return ((uint32_t)a << 24) | (r << 16) | (g << 8) | b;
+}
+
+static WEBP_INLINE int AddSubtractComponentHalf(int a, int b) {
+  return Clip255(a + (a - b) / 2);
+}
+
+static WEBP_INLINE uint32_t ClampedAddSubtractHalf(uint32_t c0, uint32_t c1,
+                                                   uint32_t c2) {
+  const uint32_t ave = Average2(c0, c1);
+  const int a = AddSubtractComponentHalf(ave >> 24, c2 >> 24);
+  const int r = AddSubtractComponentHalf((ave >> 16) & 0xff, (c2 >> 16) & 0xff);
+  const int g = AddSubtractComponentHalf((ave >> 8) & 0xff, (c2 >> 8) & 0xff);
+  const int b = AddSubtractComponentHalf((ave >> 0) & 0xff, (c2 >> 0) & 0xff);
+  return ((uint32_t)a << 24) | (r << 16) | (g << 8) | b;
+}
+
+// gcc-4.9 on ARM generates incorrect code in Select() when Sub3() is inlined.
+#if defined(__arm__) && LOCAL_GCC_VERSION == 0x409
+# define LOCAL_INLINE __attribute__ ((noinline))
+#else
+# define LOCAL_INLINE WEBP_INLINE
+#endif
+
+static LOCAL_INLINE int Sub3(int a, int b, int c) {
+  const int pb = b - c;
+  const int pa = a - c;
+  return abs(pb) - abs(pa);
+}
+
+#undef LOCAL_INLINE
+
+static WEBP_INLINE uint32_t Select(uint32_t a, uint32_t b, uint32_t c) {
+  const int pa_minus_pb =
+      Sub3((a >> 24)       , (b >> 24)       , (c >> 24)       ) +
+      Sub3((a >> 16) & 0xff, (b >> 16) & 0xff, (c >> 16) & 0xff) +
+      Sub3((a >>  8) & 0xff, (b >>  8) & 0xff, (c >>  8) & 0xff) +
+      Sub3((a      ) & 0xff, (b      ) & 0xff, (c      ) & 0xff);
+  return (pa_minus_pb <= 0) ? a : b;
+}
+
+//------------------------------------------------------------------------------
+// Predictors
+
+static uint32_t Predictor0(uint32_t left, const uint32_t* const top) {
+  (void)top;
+  (void)left;
+  return ARGB_BLACK;
+}
+static uint32_t Predictor1(uint32_t left, const uint32_t* const top) {
+  (void)top;
+  return left;
+}
+static uint32_t Predictor2(uint32_t left, const uint32_t* const top) {
+  (void)left;
+  return top[0];
+}
+static uint32_t Predictor3(uint32_t left, const uint32_t* const top) {
+  (void)left;
+  return top[1];
+}
+static uint32_t Predictor4(uint32_t left, const uint32_t* const top) {
+  (void)left;
+  return top[-1];
+}
+static uint32_t Predictor5(uint32_t left, const uint32_t* const top) {
+  const uint32_t pred = Average3(left, top[0], top[1]);
+  return pred;
+}
+static uint32_t Predictor6(uint32_t left, const uint32_t* const top) {
+  const uint32_t pred = Average2(left, top[-1]);
+  return pred;
+}
+static uint32_t Predictor7(uint32_t left, const uint32_t* const top) {
+  const uint32_t pred = Average2(left, top[0]);
+  return pred;
+}
+static uint32_t Predictor8(uint32_t left, const uint32_t* const top) {
+  const uint32_t pred = Average2(top[-1], top[0]);
+  (void)left;
+  return pred;
+}
+static uint32_t Predictor9(uint32_t left, const uint32_t* const top) {
+  const uint32_t pred = Average2(top[0], top[1]);
+  (void)left;
+  return pred;
+}
+static uint32_t Predictor10(uint32_t left, const uint32_t* const top) {
+  const uint32_t pred = Average4(left, top[-1], top[0], top[1]);
+  return pred;
+}
+static uint32_t Predictor11(uint32_t left, const uint32_t* const top) {
+  const uint32_t pred = Select(top[0], left, top[-1]);
+  return pred;
+}
+static uint32_t Predictor12(uint32_t left, const uint32_t* const top) {
+  const uint32_t pred = ClampedAddSubtractFull(left, top[0], top[-1]);
+  return pred;
+}
+static uint32_t Predictor13(uint32_t left, const uint32_t* const top) {
+  const uint32_t pred = ClampedAddSubtractHalf(left, top[0], top[-1]);
+  return pred;
+}
+
+//------------------------------------------------------------------------------
+// Methods to calculate Entropy (Shannon).
+
+static float PredictionCostSpatial(const int counts[256], int weight_0,
+                                   double exp_val) {
+  const int significant_symbols = 256 >> 4;
+  const double exp_decay_factor = 0.6;
+  double bits = weight_0 * counts[0];
+  int i;
+  for (i = 1; i < significant_symbols; ++i) {
+    bits += exp_val * (counts[i] + counts[256 - i]);
+    exp_val *= exp_decay_factor;
+  }
+  return (float)(-0.1 * bits);
+}
+
+// Compute the combined Shanon's entropy for distribution {X} and {X+Y}
+static float CombinedShannonEntropy(const int X[256], const int Y[256]) {
+  int i;
+  double retval = 0.;
+  int sumX = 0, sumXY = 0;
+  for (i = 0; i < 256; ++i) {
+    const int x = X[i];
+    const int xy = x + Y[i];
+    if (x != 0) {
+      sumX += x;
+      retval -= VP8LFastSLog2(x);
+      sumXY += xy;
+      retval -= VP8LFastSLog2(xy);
+    } else if (xy != 0) {
+      sumXY += xy;
+      retval -= VP8LFastSLog2(xy);
+    }
+  }
+  retval += VP8LFastSLog2(sumX) + VP8LFastSLog2(sumXY);
+  return (float)retval;
+}
+
+static float PredictionCostSpatialHistogram(const int accumulated[4][256],
+                                            const int tile[4][256]) {
+  int i;
+  double retval = 0;
+  for (i = 0; i < 4; ++i) {
+    const double kExpValue = 0.94;
+    retval += PredictionCostSpatial(tile[i], 1, kExpValue);
+    retval += CombinedShannonEntropy(tile[i], accumulated[i]);
+  }
+  return (float)retval;
+}
+
+static WEBP_INLINE double BitsEntropyRefine(int nonzeros, int sum, int max_val,
+                                            double retval) {
+  double mix;
+  if (nonzeros < 5) {
+    if (nonzeros <= 1) {
+      return 0;
+    }
+    // Two symbols, they will be 0 and 1 in a Huffman code.
+    // Let's mix in a bit of entropy to favor good clustering when
+    // distributions of these are combined.
+    if (nonzeros == 2) {
+      return 0.99 * sum + 0.01 * retval;
+    }
+    // No matter what the entropy says, we cannot be better than min_limit
+    // with Huffman coding. I am mixing a bit of entropy into the
+    // min_limit since it produces much better (~0.5 %) compression results
+    // perhaps because of better entropy clustering.
+    if (nonzeros == 3) {
+      mix = 0.95;
+    } else {
+      mix = 0.7;  // nonzeros == 4.
+    }
+  } else {
+    mix = 0.627;
+  }
+
+  {
+    double min_limit = 2 * sum - max_val;
+    min_limit = mix * min_limit + (1.0 - mix) * retval;
+    return (retval < min_limit) ? min_limit : retval;
+  }
+}
+
+// Returns the entropy for the symbols in the input array.
+// Also sets trivial_symbol to the code value, if the array has only one code
+// value. Otherwise, set it to VP8L_NON_TRIVIAL_SYM.
+static double BitsEntropy(const uint32_t* const array, int n,
+                          uint32_t* const trivial_symbol) {
+  double retval = 0.;
+  uint32_t sum = 0;
+  uint32_t nonzero_code = VP8L_NON_TRIVIAL_SYM;
+  int nonzeros = 0;
+  uint32_t max_val = 0;
+  int i;
+  for (i = 0; i < n; ++i) {
+    if (array[i] != 0) {
+      sum += array[i];
+      nonzero_code = i;
+      ++nonzeros;
+      retval -= VP8LFastSLog2(array[i]);
+      if (max_val < array[i]) {
+        max_val = array[i];
+      }
+    }
+  }
+  retval += VP8LFastSLog2(sum);
+  if (trivial_symbol != NULL) {
+    *trivial_symbol = (nonzeros == 1) ? nonzero_code : VP8L_NON_TRIVIAL_SYM;
+  }
+  return BitsEntropyRefine(nonzeros, sum, max_val, retval);
+}
+
+static double BitsEntropyCombined(const uint32_t* const X,
+                                  const uint32_t* const Y, int n) {
+  double retval = 0.;
+  int sum = 0;
+  int nonzeros = 0;
+  int max_val = 0;
+  int i;
+  for (i = 0; i < n; ++i) {
+    const int xy = X[i] + Y[i];
+    if (xy != 0) {
+      sum += xy;
+      ++nonzeros;
+      retval -= VP8LFastSLog2(xy);
+      if (max_val < xy) {
+        max_val = xy;
+      }
+    }
+  }
+  retval += VP8LFastSLog2(sum);
+  return BitsEntropyRefine(nonzeros, sum, max_val, retval);
+}
+
+static double InitialHuffmanCost(void) {
+  // Small bias because Huffman code length is typically not stored in
+  // full length.
+  static const int kHuffmanCodeOfHuffmanCodeSize = CODE_LENGTH_CODES * 3;
+  static const double kSmallBias = 9.1;
+  return kHuffmanCodeOfHuffmanCodeSize - kSmallBias;
+}
+
+// Finalize the Huffman cost based on streak numbers and length type (<3 or >=3)
+static double FinalHuffmanCost(const VP8LStreaks* const stats) {
+  double retval = InitialHuffmanCost();
+  retval += stats->counts[0] * 1.5625 + 0.234375 * stats->streaks[0][1];
+  retval += stats->counts[1] * 2.578125 + 0.703125 * stats->streaks[1][1];
+  retval += 1.796875 * stats->streaks[0][0];
+  retval += 3.28125 * stats->streaks[1][0];
+  return retval;
+}
+
+// Trampolines
+static double HuffmanCost(const uint32_t* const population, int length) {
+  const VP8LStreaks stats = VP8LHuffmanCostCount(population, length);
+  return FinalHuffmanCost(&stats);
+}
+
+static double HuffmanCostCombined(const uint32_t* const X,
+                                  const uint32_t* const Y, int length) {
+  const VP8LStreaks stats = VP8LHuffmanCostCombinedCount(X, Y, length);
+  return FinalHuffmanCost(&stats);
+}
+
+// Aggregated costs
+double VP8LPopulationCost(const uint32_t* const population, int length,
+                          uint32_t* const trivial_sym) {
+  return
+      BitsEntropy(population, length, trivial_sym) +
+      HuffmanCost(population, length);
+}
+
+double VP8LGetCombinedEntropy(const uint32_t* const X,
+                              const uint32_t* const Y, int length) {
+  return BitsEntropyCombined(X, Y, length) + HuffmanCostCombined(X, Y, length);
+}
+
+// Estimates the Entropy + Huffman + other block overhead size cost.
+double VP8LHistogramEstimateBits(const VP8LHistogram* const p) {
+  return
+      VP8LPopulationCost(
+          p->literal_, VP8LHistogramNumCodes(p->palette_code_bits_), NULL)
+      + VP8LPopulationCost(p->red_, NUM_LITERAL_CODES, NULL)
+      + VP8LPopulationCost(p->blue_, NUM_LITERAL_CODES, NULL)
+      + VP8LPopulationCost(p->alpha_, NUM_LITERAL_CODES, NULL)
+      + VP8LPopulationCost(p->distance_, NUM_DISTANCE_CODES, NULL)
+      + VP8LExtraCost(p->literal_ + NUM_LITERAL_CODES, NUM_LENGTH_CODES)
+      + VP8LExtraCost(p->distance_, NUM_DISTANCE_CODES);
+}
+
+double VP8LHistogramEstimateBitsBulk(const VP8LHistogram* const p) {
+  return
+      BitsEntropy(p->literal_, VP8LHistogramNumCodes(p->palette_code_bits_),
+                  NULL)
+      + BitsEntropy(p->red_, NUM_LITERAL_CODES, NULL)
+      + BitsEntropy(p->blue_, NUM_LITERAL_CODES, NULL)
+      + BitsEntropy(p->alpha_, NUM_LITERAL_CODES, NULL)
+      + BitsEntropy(p->distance_, NUM_DISTANCE_CODES, NULL)
+      + VP8LExtraCost(p->literal_ + NUM_LITERAL_CODES, NUM_LENGTH_CODES)
+      + VP8LExtraCost(p->distance_, NUM_DISTANCE_CODES);
+}
+
+static WEBP_INLINE void UpdateHisto(int histo_argb[4][256], uint32_t argb) {
+  ++histo_argb[0][argb >> 24];
+  ++histo_argb[1][(argb >> 16) & 0xff];
+  ++histo_argb[2][(argb >> 8) & 0xff];
+  ++histo_argb[3][argb & 0xff];
+}
+
+//------------------------------------------------------------------------------
+
+static int GetBestPredictorForTile(int width, int height,
+                                   int tile_x, int tile_y, int bits,
+                                   const int accumulated[4][256],
+                                   const uint32_t* const argb_scratch) {
+  const int kNumPredModes = 14;
+  const int col_start = tile_x << bits;
+  const int row_start = tile_y << bits;
+  const int tile_size = 1 << bits;
+  const int max_y = GetMin(tile_size, height - row_start);
+  const int max_x = GetMin(tile_size, width - col_start);
+  float best_diff = MAX_DIFF_COST;
+  int best_mode = 0;
+  int mode;
+  for (mode = 0; mode < kNumPredModes; ++mode) {
+    const uint32_t* current_row = argb_scratch;
+    const VP8LPredictorFunc pred_func = VP8LPredictors[mode];
+    float cur_diff;
+    int y;
+    int histo_argb[4][256];
+    memset(histo_argb, 0, sizeof(histo_argb));
+    for (y = 0; y < max_y; ++y) {
+      int x;
+      const int row = row_start + y;
+      const uint32_t* const upper_row = current_row;
+      current_row = upper_row + width;
+      for (x = 0; x < max_x; ++x) {
+        const int col = col_start + x;
+        uint32_t predict;
+        if (row == 0) {
+          predict = (col == 0) ? ARGB_BLACK : current_row[col - 1];  // Left.
+        } else if (col == 0) {
+          predict = upper_row[col];  // Top.
+        } else {
+          predict = pred_func(current_row[col - 1], upper_row + col);
+        }
+        UpdateHisto(histo_argb, VP8LSubPixels(current_row[col], predict));
+      }
+    }
+    cur_diff = PredictionCostSpatialHistogram(
+        accumulated, (const int (*)[256])histo_argb);
+    if (cur_diff < best_diff) {
+      best_diff = cur_diff;
+      best_mode = mode;
+    }
+  }
+
+  return best_mode;
+}
+
+static void CopyTileWithPrediction(int width, int height,
+                                   int tile_x, int tile_y, int bits, int mode,
+                                   const uint32_t* const argb_scratch,
+                                   uint32_t* const argb) {
+  const int col_start = tile_x << bits;
+  const int row_start = tile_y << bits;
+  const int tile_size = 1 << bits;
+  const int max_y = GetMin(tile_size, height - row_start);
+  const int max_x = GetMin(tile_size, width - col_start);
+  const VP8LPredictorFunc pred_func = VP8LPredictors[mode];
+  const uint32_t* current_row = argb_scratch;
+
+  int y;
+  for (y = 0; y < max_y; ++y) {
+    int x;
+    const int row = row_start + y;
+    const uint32_t* const upper_row = current_row;
+    current_row = upper_row + width;
+    for (x = 0; x < max_x; ++x) {
+      const int col = col_start + x;
+      const int pix = row * width + col;
+      uint32_t predict;
+      if (row == 0) {
+        predict = (col == 0) ? ARGB_BLACK : current_row[col - 1];  // Left.
+      } else if (col == 0) {
+        predict = upper_row[col];  // Top.
+      } else {
+        predict = pred_func(current_row[col - 1], upper_row + col);
+      }
+      argb[pix] = VP8LSubPixels(current_row[col], predict);
+    }
+  }
+}
+
+void VP8LResidualImage(int width, int height, int bits, int low_effort,
+                       uint32_t* const argb, uint32_t* const argb_scratch,
+                       uint32_t* const image) {
+  const int max_tile_size = 1 << bits;
+  const int tiles_per_row = VP8LSubSampleSize(width, bits);
+  const int tiles_per_col = VP8LSubSampleSize(height, bits);
+  const int kPredLowEffort = 11;
+  uint32_t* const upper_row = argb_scratch;
+  uint32_t* const current_tile_rows = argb_scratch + width;
+  int tile_y;
+  int histo[4][256];
+  memset(histo, 0, sizeof(histo));
+  for (tile_y = 0; tile_y < tiles_per_col; ++tile_y) {
+    const int tile_y_offset = tile_y * max_tile_size;
+    const int this_tile_height =
+        (tile_y < tiles_per_col - 1) ? max_tile_size : height - tile_y_offset;
+    int tile_x;
+    if (tile_y > 0) {
+      memcpy(upper_row, current_tile_rows + (max_tile_size - 1) * width,
+             width * sizeof(*upper_row));
+    }
+    memcpy(current_tile_rows, &argb[tile_y_offset * width],
+           this_tile_height * width * sizeof(*current_tile_rows));
+    for (tile_x = 0; tile_x < tiles_per_row; ++tile_x) {
+      int pred;
+      int y;
+      const int tile_x_offset = tile_x * max_tile_size;
+      int all_x_max = tile_x_offset + max_tile_size;
+      if (all_x_max > width) {
+        all_x_max = width;
+      }
+      pred = low_effort ? kPredLowEffort :
+                          GetBestPredictorForTile(width, height, tile_x,
+                                                  tile_y, bits,
+                                                  (const int (*)[256])histo,
+                                                  argb_scratch);
+      image[tile_y * tiles_per_row + tile_x] = 0xff000000u | (pred << 8);
+      CopyTileWithPrediction(width, height, tile_x, tile_y, bits, pred,
+                             argb_scratch, argb);
+      for (y = 0; y < max_tile_size; ++y) {
+        int all_x;
+        int all_y = tile_y_offset + y;
+        if (all_y >= height) {
+          break;
+        }
+        for (all_x = tile_x_offset; all_x < all_x_max; ++all_x) {
+          UpdateHisto(histo, argb[all_y * width + all_x]);
+        }
+      }
+    }
+  }
+}
+
+// Inverse prediction.
+static void PredictorInverseTransform(const VP8LTransform* const transform,
+                                      int y_start, int y_end, uint32_t* data) {
+  const int width = transform->xsize_;
+  if (y_start == 0) {  // First Row follows the L (mode=1) mode.
+    int x;
+    const uint32_t pred0 = Predictor0(data[-1], NULL);
+    AddPixelsEq(data, pred0);
+    for (x = 1; x < width; ++x) {
+      const uint32_t pred1 = Predictor1(data[x - 1], NULL);
+      AddPixelsEq(data + x, pred1);
+    }
+    data += width;
+    ++y_start;
+  }
+
+  {
+    int y = y_start;
+    const int tile_width = 1 << transform->bits_;
+    const int mask = tile_width - 1;
+    const int safe_width = width & ~mask;
+    const int tiles_per_row = VP8LSubSampleSize(width, transform->bits_);
+    const uint32_t* pred_mode_base =
+        transform->data_ + (y >> transform->bits_) * tiles_per_row;
+
+    while (y < y_end) {
+      const uint32_t pred2 = Predictor2(data[-1], data - width);
+      const uint32_t* pred_mode_src = pred_mode_base;
+      VP8LPredictorFunc pred_func;
+      int x = 1;
+      int t = 1;
+      // First pixel follows the T (mode=2) mode.
+      AddPixelsEq(data, pred2);
+      // .. the rest:
+      while (x < safe_width) {
+        pred_func = VP8LPredictors[((*pred_mode_src++) >> 8) & 0xf];
+        for (; t < tile_width; ++t, ++x) {
+          const uint32_t pred = pred_func(data[x - 1], data + x - width);
+          AddPixelsEq(data + x, pred);
+        }
+        t = 0;
+      }
+      if (x < width) {
+        pred_func = VP8LPredictors[((*pred_mode_src++) >> 8) & 0xf];
+        for (; x < width; ++x) {
+          const uint32_t pred = pred_func(data[x - 1], data + x - width);
+          AddPixelsEq(data + x, pred);
+        }
+      }
+      data += width;
+      ++y;
+      if ((y & mask) == 0) {   // Use the same mask, since tiles are squares.
+        pred_mode_base += tiles_per_row;
+      }
+    }
+  }
+}
+
+void VP8LSubtractGreenFromBlueAndRed_C(uint32_t* argb_data, int num_pixels) {
+  int i;
+  for (i = 0; i < num_pixels; ++i) {
+    const uint32_t argb = argb_data[i];
+    const uint32_t green = (argb >> 8) & 0xff;
+    const uint32_t new_r = (((argb >> 16) & 0xff) - green) & 0xff;
+    const uint32_t new_b = ((argb & 0xff) - green) & 0xff;
+    argb_data[i] = (argb & 0xff00ff00) | (new_r << 16) | new_b;
+  }
+}
+
+// Add green to blue and red channels (i.e. perform the inverse transform of
+// 'subtract green').
+void VP8LAddGreenToBlueAndRed_C(uint32_t* data, int num_pixels) {
+  int i;
+  for (i = 0; i < num_pixels; ++i) {
+    const uint32_t argb = data[i];
+    const uint32_t green = ((argb >> 8) & 0xff);
+    uint32_t red_blue = (argb & 0x00ff00ffu);
+    red_blue += (green << 16) | green;
+    red_blue &= 0x00ff00ffu;
+    data[i] = (argb & 0xff00ff00u) | red_blue;
+  }
+}
+
+static WEBP_INLINE void MultipliersClear(VP8LMultipliers* const m) {
+  m->green_to_red_ = 0;
+  m->green_to_blue_ = 0;
+  m->red_to_blue_ = 0;
+}
+
+static WEBP_INLINE uint32_t ColorTransformDelta(int8_t color_pred,
+                                                int8_t color) {
+  return (uint32_t)((int)(color_pred) * color) >> 5;
+}
+
+static WEBP_INLINE void ColorCodeToMultipliers(uint32_t color_code,
+                                               VP8LMultipliers* const m) {
+  m->green_to_red_  = (color_code >>  0) & 0xff;
+  m->green_to_blue_ = (color_code >>  8) & 0xff;
+  m->red_to_blue_   = (color_code >> 16) & 0xff;
+}
+
+static WEBP_INLINE uint32_t MultipliersToColorCode(
+    const VP8LMultipliers* const m) {
+  return 0xff000000u |
+         ((uint32_t)(m->red_to_blue_) << 16) |
+         ((uint32_t)(m->green_to_blue_) << 8) |
+         m->green_to_red_;
+}
+
+void VP8LTransformColor_C(const VP8LMultipliers* const m, uint32_t* data,
+                          int num_pixels) {
+  int i;
+  for (i = 0; i < num_pixels; ++i) {
+    const uint32_t argb = data[i];
+    const uint32_t green = argb >> 8;
+    const uint32_t red = argb >> 16;
+    uint32_t new_red = red;
+    uint32_t new_blue = argb;
+    new_red -= ColorTransformDelta(m->green_to_red_, green);
+    new_red &= 0xff;
+    new_blue -= ColorTransformDelta(m->green_to_blue_, green);
+    new_blue -= ColorTransformDelta(m->red_to_blue_, red);
+    new_blue &= 0xff;
+    data[i] = (argb & 0xff00ff00u) | (new_red << 16) | (new_blue);
+  }
+}
+
+void VP8LTransformColorInverse_C(const VP8LMultipliers* const m, uint32_t* data,
+                                 int num_pixels) {
+  int i;
+  for (i = 0; i < num_pixels; ++i) {
+    const uint32_t argb = data[i];
+    const uint32_t green = argb >> 8;
+    const uint32_t red = argb >> 16;
+    uint32_t new_red = red;
+    uint32_t new_blue = argb;
+    new_red += ColorTransformDelta(m->green_to_red_, green);
+    new_red &= 0xff;
+    new_blue += ColorTransformDelta(m->green_to_blue_, green);
+    new_blue += ColorTransformDelta(m->red_to_blue_, new_red);
+    new_blue &= 0xff;
+    data[i] = (argb & 0xff00ff00u) | (new_red << 16) | (new_blue);
+  }
+}
+
+static WEBP_INLINE uint8_t TransformColorRed(uint8_t green_to_red,
+                                             uint32_t argb) {
+  const uint32_t green = argb >> 8;
+  uint32_t new_red = argb >> 16;
+  new_red -= ColorTransformDelta(green_to_red, green);
+  return (new_red & 0xff);
+}
+
+static WEBP_INLINE uint8_t TransformColorBlue(uint8_t green_to_blue,
+                                              uint8_t red_to_blue,
+                                              uint32_t argb) {
+  const uint32_t green = argb >> 8;
+  const uint32_t red = argb >> 16;
+  uint8_t new_blue = argb;
+  new_blue -= ColorTransformDelta(green_to_blue, green);
+  new_blue -= ColorTransformDelta(red_to_blue, red);
+  return (new_blue & 0xff);
+}
+
+static float PredictionCostCrossColor(const int accumulated[256],
+                                      const int counts[256]) {
+  // Favor low entropy, locally and globally.
+  // Favor small absolute values for PredictionCostSpatial
+  static const double kExpValue = 2.4;
+  return CombinedShannonEntropy(counts, accumulated) +
+         PredictionCostSpatial(counts, 3, kExpValue);
+}
+
+static void CollectColorRedTransforms(const uint32_t* argb, int stride,
+                                      int tile_width, int tile_height,
+                                      int green_to_red, int histo[]) {
+  while (tile_height-- > 0) {
+    int x;
+    for (x = 0; x < tile_width; ++x) {
+      ++histo[TransformColorRed(green_to_red, argb[x])];
+    }
+    argb += stride;
+  }
+}
+
+static float GetPredictionCostCrossColorRed(
+    const uint32_t* argb, int stride, int tile_width, int tile_height,
+    VP8LMultipliers prev_x, VP8LMultipliers prev_y, int green_to_red,
+    const int accumulated_red_histo[256]) {
+  int histo[256] = { 0 };
+  float cur_diff;
+
+  VP8LCollectColorRedTransforms(argb, stride, tile_width, tile_height,
+                                green_to_red, histo);
+
+  cur_diff = PredictionCostCrossColor(accumulated_red_histo, histo);
+  if ((uint8_t)green_to_red == prev_x.green_to_red_) {
+    cur_diff -= 3;  // favor keeping the areas locally similar
+  }
+  if ((uint8_t)green_to_red == prev_y.green_to_red_) {
+    cur_diff -= 3;  // favor keeping the areas locally similar
+  }
+  if (green_to_red == 0) {
+    cur_diff -= 3;
+  }
+  return cur_diff;
+}
+
+static void GetBestGreenToRed(
+    const uint32_t* argb, int stride, int tile_width, int tile_height,
+    VP8LMultipliers prev_x, VP8LMultipliers prev_y,
+    const int accumulated_red_histo[256], VP8LMultipliers* const best_tx) {
+  int min_green_to_red = -64;
+  int max_green_to_red = 64;
+  int green_to_red = 0;
+  int eval_min = 1;
+  int eval_max = 1;
+  float cur_diff_min = MAX_DIFF_COST;
+  float cur_diff_max = MAX_DIFF_COST;
+  // Do a binary search to find the optimal green_to_red color transform.
+  while (max_green_to_red - min_green_to_red > 2) {
+    if (eval_min) {
+      cur_diff_min = GetPredictionCostCrossColorRed(
+          argb, stride, tile_width, tile_height,
+          prev_x, prev_y, min_green_to_red, accumulated_red_histo);
+      eval_min = 0;
+    }
+    if (eval_max) {
+      cur_diff_max = GetPredictionCostCrossColorRed(
+          argb, stride, tile_width, tile_height,
+          prev_x, prev_y, max_green_to_red, accumulated_red_histo);
+      eval_max = 0;
+    }
+    if (cur_diff_min < cur_diff_max) {
+      green_to_red = min_green_to_red;
+      max_green_to_red = (max_green_to_red + min_green_to_red) / 2;
+      eval_max = 1;
+    } else {
+      green_to_red = max_green_to_red;
+      min_green_to_red = (max_green_to_red + min_green_to_red) / 2;
+      eval_min = 1;
+    }
+  }
+  best_tx->green_to_red_ = green_to_red;
+}
+
+static void CollectColorBlueTransforms(const uint32_t* argb, int stride,
+                                       int tile_width, int tile_height,
+                                       int green_to_blue, int red_to_blue,
+                                       int histo[]) {
+  while (tile_height-- > 0) {
+    int x;
+    for (x = 0; x < tile_width; ++x) {
+      ++histo[TransformColorBlue(green_to_blue, red_to_blue, argb[x])];
+    }
+    argb += stride;
+  }
+}
+
+static float GetPredictionCostCrossColorBlue(
+    const uint32_t* argb, int stride, int tile_width, int tile_height,
+    VP8LMultipliers prev_x, VP8LMultipliers prev_y,
+    int green_to_blue, int red_to_blue, const int accumulated_blue_histo[256]) {
+  int histo[256] = { 0 };
+  float cur_diff;
+
+  VP8LCollectColorBlueTransforms(argb, stride, tile_width, tile_height,
+                                 green_to_blue, red_to_blue, histo);
+
+  cur_diff = PredictionCostCrossColor(accumulated_blue_histo, histo);
+  if ((uint8_t)green_to_blue == prev_x.green_to_blue_) {
+    cur_diff -= 3;  // favor keeping the areas locally similar
+  }
+  if ((uint8_t)green_to_blue == prev_y.green_to_blue_) {
+    cur_diff -= 3;  // favor keeping the areas locally similar
+  }
+  if ((uint8_t)red_to_blue == prev_x.red_to_blue_) {
+    cur_diff -= 3;  // favor keeping the areas locally similar
+  }
+  if ((uint8_t)red_to_blue == prev_y.red_to_blue_) {
+    cur_diff -= 3;  // favor keeping the areas locally similar
+  }
+  if (green_to_blue == 0) {
+    cur_diff -= 3;
+  }
+  if (red_to_blue == 0) {
+    cur_diff -= 3;
+  }
+  return cur_diff;
+}
+
+static void GetBestGreenRedToBlue(
+    const uint32_t* argb, int stride, int tile_width, int tile_height,
+    VP8LMultipliers prev_x, VP8LMultipliers prev_y, int quality,
+    const int accumulated_blue_histo[256],
+    VP8LMultipliers* const best_tx) {
+  float best_diff = MAX_DIFF_COST;
+  float cur_diff;
+  const int step = (quality < 25) ? 32 : (quality > 50) ? 8 : 16;
+  const int min_green_to_blue = -32;
+  const int max_green_to_blue = 32;
+  const int min_red_to_blue = -32;
+  const int max_red_to_blue = 32;
+  const int num_iters =
+      (1 + (max_green_to_blue - min_green_to_blue) / step) *
+      (1 + (max_red_to_blue - min_red_to_blue) / step);
+  // Number of tries to get optimal green_to_blue & red_to_blue color transforms
+  // after finding a local minima.
+  const int max_tries_after_min = 4 + (num_iters >> 2);
+  int num_tries_after_min = 0;
+  int green_to_blue;
+  for (green_to_blue = min_green_to_blue;
+       green_to_blue <= max_green_to_blue &&
+       num_tries_after_min < max_tries_after_min;
+       green_to_blue += step) {
+    int red_to_blue;
+    for (red_to_blue = min_red_to_blue;
+         red_to_blue <= max_red_to_blue &&
+         num_tries_after_min < max_tries_after_min;
+         red_to_blue += step) {
+      cur_diff = GetPredictionCostCrossColorBlue(
+          argb, stride, tile_width, tile_height, prev_x, prev_y,
+          green_to_blue, red_to_blue, accumulated_blue_histo);
+      if (cur_diff < best_diff) {
+        best_diff = cur_diff;
+        best_tx->green_to_blue_ = green_to_blue;
+        best_tx->red_to_blue_ = red_to_blue;
+        num_tries_after_min = 0;
+      } else {
+        ++num_tries_after_min;
+      }
+    }
+  }
+}
+
+static VP8LMultipliers GetBestColorTransformForTile(
+    int tile_x, int tile_y, int bits,
+    VP8LMultipliers prev_x,
+    VP8LMultipliers prev_y,
+    int quality, int xsize, int ysize,
+    const int accumulated_red_histo[256],
+    const int accumulated_blue_histo[256],
+    const uint32_t* const argb) {
+  const int max_tile_size = 1 << bits;
+  const int tile_y_offset = tile_y * max_tile_size;
+  const int tile_x_offset = tile_x * max_tile_size;
+  const int all_x_max = GetMin(tile_x_offset + max_tile_size, xsize);
+  const int all_y_max = GetMin(tile_y_offset + max_tile_size, ysize);
+  const int tile_width = all_x_max - tile_x_offset;
+  const int tile_height = all_y_max - tile_y_offset;
+  const uint32_t* const tile_argb = argb + tile_y_offset * xsize
+                                  + tile_x_offset;
+  VP8LMultipliers best_tx;
+  MultipliersClear(&best_tx);
+
+  GetBestGreenToRed(tile_argb, xsize, tile_width, tile_height,
+                    prev_x, prev_y, accumulated_red_histo, &best_tx);
+  GetBestGreenRedToBlue(tile_argb, xsize, tile_width, tile_height,
+                        prev_x, prev_y, quality, accumulated_blue_histo,
+                        &best_tx);
+  return best_tx;
+}
+
+static void CopyTileWithColorTransform(int xsize, int ysize,
+                                       int tile_x, int tile_y,
+                                       int max_tile_size,
+                                       VP8LMultipliers color_transform,
+                                       uint32_t* argb) {
+  const int xscan = GetMin(max_tile_size, xsize - tile_x);
+  int yscan = GetMin(max_tile_size, ysize - tile_y);
+  argb += tile_y * xsize + tile_x;
+  while (yscan-- > 0) {
+    VP8LTransformColor(&color_transform, argb, xscan);
+    argb += xsize;
+  }
+}
+
+void VP8LColorSpaceTransform(int width, int height, int bits, int quality,
+                             uint32_t* const argb, uint32_t* image) {
+  const int max_tile_size = 1 << bits;
+  const int tile_xsize = VP8LSubSampleSize(width, bits);
+  const int tile_ysize = VP8LSubSampleSize(height, bits);
+  int accumulated_red_histo[256] = { 0 };
+  int accumulated_blue_histo[256] = { 0 };
+  int tile_x, tile_y;
+  VP8LMultipliers prev_x, prev_y;
+  MultipliersClear(&prev_y);
+  MultipliersClear(&prev_x);
+  for (tile_y = 0; tile_y < tile_ysize; ++tile_y) {
+    for (tile_x = 0; tile_x < tile_xsize; ++tile_x) {
+      int y;
+      const int tile_x_offset = tile_x * max_tile_size;
+      const int tile_y_offset = tile_y * max_tile_size;
+      const int all_x_max = GetMin(tile_x_offset + max_tile_size, width);
+      const int all_y_max = GetMin(tile_y_offset + max_tile_size, height);
+      const int offset = tile_y * tile_xsize + tile_x;
+      if (tile_y != 0) {
+        ColorCodeToMultipliers(image[offset - tile_xsize], &prev_y);
+      }
+      prev_x = GetBestColorTransformForTile(tile_x, tile_y, bits,
+                                            prev_x, prev_y,
+                                            quality, width, height,
+                                            accumulated_red_histo,
+                                            accumulated_blue_histo,
+                                            argb);
+      image[offset] = MultipliersToColorCode(&prev_x);
+      CopyTileWithColorTransform(width, height, tile_x_offset, tile_y_offset,
+                                 max_tile_size, prev_x, argb);
+
+      // Gather accumulated histogram data.
+      for (y = tile_y_offset; y < all_y_max; ++y) {
+        int ix = y * width + tile_x_offset;
+        const int ix_end = ix + all_x_max - tile_x_offset;
+        for (; ix < ix_end; ++ix) {
+          const uint32_t pix = argb[ix];
+          if (ix >= 2 &&
+              pix == argb[ix - 2] &&
+              pix == argb[ix - 1]) {
+            continue;  // repeated pixels are handled by backward references
+          }
+          if (ix >= width + 2 &&
+              argb[ix - 2] == argb[ix - width - 2] &&
+              argb[ix - 1] == argb[ix - width - 1] &&
+              pix == argb[ix - width]) {
+            continue;  // repeated pixels are handled by backward references
+          }
+          ++accumulated_red_histo[(pix >> 16) & 0xff];
+          ++accumulated_blue_histo[(pix >> 0) & 0xff];
+        }
+      }
+    }
+  }
+}
+
+// Color space inverse transform.
+static void ColorSpaceInverseTransform(const VP8LTransform* const transform,
+                                       int y_start, int y_end, uint32_t* data) {
+  const int width = transform->xsize_;
+  const int tile_width = 1 << transform->bits_;
+  const int mask = tile_width - 1;
+  const int safe_width = width & ~mask;
+  const int remaining_width = width - safe_width;
+  const int tiles_per_row = VP8LSubSampleSize(width, transform->bits_);
+  int y = y_start;
+  const uint32_t* pred_row =
+      transform->data_ + (y >> transform->bits_) * tiles_per_row;
+
+  while (y < y_end) {
+    const uint32_t* pred = pred_row;
+    VP8LMultipliers m = { 0, 0, 0 };
+    const uint32_t* const data_safe_end = data + safe_width;
+    const uint32_t* const data_end = data + width;
+    while (data < data_safe_end) {
+      ColorCodeToMultipliers(*pred++, &m);
+      VP8LTransformColorInverse(&m, data, tile_width);
+      data += tile_width;
+    }
+    if (data < data_end) {  // Left-overs using C-version.
+      ColorCodeToMultipliers(*pred++, &m);
+      VP8LTransformColorInverse(&m, data, remaining_width);
+      data += remaining_width;
+    }
+    ++y;
+    if ((y & mask) == 0) pred_row += tiles_per_row;
+  }
+}
+
+// Separate out pixels packed together using pixel-bundling.
+// We define two methods for ARGB data (uint32_t) and alpha-only data (uint8_t).
+#define COLOR_INDEX_INVERSE(FUNC_NAME, F_NAME, STATIC_DECL, TYPE, BIT_SUFFIX,  \
+                            GET_INDEX, GET_VALUE)                              \
+static void F_NAME(const TYPE* src, const uint32_t* const color_map,           \
+                   TYPE* dst, int y_start, int y_end, int width) {             \
+  int y;                                                                       \
+  for (y = y_start; y < y_end; ++y) {                                          \
+    int x;                                                                     \
+    for (x = 0; x < width; ++x) {                                              \
+      *dst++ = GET_VALUE(color_map[GET_INDEX(*src++)]);                        \
+    }                                                                          \
+  }                                                                            \
+}                                                                              \
+STATIC_DECL void FUNC_NAME(const VP8LTransform* const transform,               \
+                           int y_start, int y_end, const TYPE* src,            \
+                           TYPE* dst) {                                        \
+  int y;                                                                       \
+  const int bits_per_pixel = 8 >> transform->bits_;                            \
+  const int width = transform->xsize_;                                         \
+  const uint32_t* const color_map = transform->data_;                          \
+  if (bits_per_pixel < 8) {                                                    \
+    const int pixels_per_byte = 1 << transform->bits_;                         \
+    const int count_mask = pixels_per_byte - 1;                                \
+    const uint32_t bit_mask = (1 << bits_per_pixel) - 1;                       \
+    for (y = y_start; y < y_end; ++y) {                                        \
+      uint32_t packed_pixels = 0;                                              \
+      int x;                                                                   \
+      for (x = 0; x < width; ++x) {                                            \
+        /* We need to load fresh 'packed_pixels' once every                */  \
+        /* 'pixels_per_byte' increments of x. Fortunately, pixels_per_byte */  \
+        /* is a power of 2, so can just use a mask for that, instead of    */  \
+        /* decrementing a counter.                                         */  \
+        if ((x & count_mask) == 0) packed_pixels = GET_INDEX(*src++);          \
+        *dst++ = GET_VALUE(color_map[packed_pixels & bit_mask]);               \
+        packed_pixels >>= bits_per_pixel;                                      \
+      }                                                                        \
+    }                                                                          \
+  } else {                                                                     \
+    VP8LMapColor##BIT_SUFFIX(src, color_map, dst, y_start, y_end, width);      \
+  }                                                                            \
+}
+
+COLOR_INDEX_INVERSE(ColorIndexInverseTransform, MapARGB, static, uint32_t, 32b,
+                    VP8GetARGBIndex, VP8GetARGBValue)
+COLOR_INDEX_INVERSE(VP8LColorIndexInverseTransformAlpha, MapAlpha, , uint8_t,
+                    8b, VP8GetAlphaIndex, VP8GetAlphaValue)
+
+#undef COLOR_INDEX_INVERSE
+
+void VP8LInverseTransform(const VP8LTransform* const transform,
+                          int row_start, int row_end,
+                          const uint32_t* const in, uint32_t* const out) {
+  const int width = transform->xsize_;
+  assert(row_start < row_end);
+  assert(row_end <= transform->ysize_);
+  switch (transform->type_) {
+    case SUBTRACT_GREEN:
+      VP8LAddGreenToBlueAndRed(out, (row_end - row_start) * width);
+      break;
+    case PREDICTOR_TRANSFORM:
+      PredictorInverseTransform(transform, row_start, row_end, out);
+      if (row_end != transform->ysize_) {
+        // The last predicted row in this iteration will be the top-pred row
+        // for the first row in next iteration.
+        memcpy(out - width, out + (row_end - row_start - 1) * width,
+               width * sizeof(*out));
+      }
+      break;
+    case CROSS_COLOR_TRANSFORM:
+      ColorSpaceInverseTransform(transform, row_start, row_end, out);
+      break;
+    case COLOR_INDEXING_TRANSFORM:
+      if (in == out && transform->bits_ > 0) {
+        // Move packed pixels to the end of unpacked region, so that unpacking
+        // can occur seamlessly.
+        // Also, note that this is the only transform that applies on
+        // the effective width of VP8LSubSampleSize(xsize_, bits_). All other
+        // transforms work on effective width of xsize_.
+        const int out_stride = (row_end - row_start) * width;
+        const int in_stride = (row_end - row_start) *
+            VP8LSubSampleSize(transform->xsize_, transform->bits_);
+        uint32_t* const src = out + out_stride - in_stride;
+        memmove(src, out, in_stride * sizeof(*src));
+        ColorIndexInverseTransform(transform, row_start, row_end, src, out);
+      } else {
+        ColorIndexInverseTransform(transform, row_start, row_end, in, out);
+      }
+      break;
+  }
+}
+
+//------------------------------------------------------------------------------
+// Color space conversion.
+
+static int is_big_endian(void) {
+  static const union {
+    uint16_t w;
+    uint8_t b[2];
+  } tmp = { 1 };
+  return (tmp.b[0] != 1);
+}
+
+void VP8LConvertBGRAToRGB_C(const uint32_t* src,
+                            int num_pixels, uint8_t* dst) {
+  const uint32_t* const src_end = src + num_pixels;
+  while (src < src_end) {
+    const uint32_t argb = *src++;
+    *dst++ = (argb >> 16) & 0xff;
+    *dst++ = (argb >>  8) & 0xff;
+    *dst++ = (argb >>  0) & 0xff;
+  }
+}
+
+void VP8LConvertBGRAToRGBA_C(const uint32_t* src,
+                             int num_pixels, uint8_t* dst) {
+  const uint32_t* const src_end = src + num_pixels;
+  while (src < src_end) {
+    const uint32_t argb = *src++;
+    *dst++ = (argb >> 16) & 0xff;
+    *dst++ = (argb >>  8) & 0xff;
+    *dst++ = (argb >>  0) & 0xff;
+    *dst++ = (argb >> 24) & 0xff;
+  }
+}
+
+void VP8LConvertBGRAToRGBA4444_C(const uint32_t* src,
+                                 int num_pixels, uint8_t* dst) {
+  const uint32_t* const src_end = src + num_pixels;
+  while (src < src_end) {
+    const uint32_t argb = *src++;
+    const uint8_t rg = ((argb >> 16) & 0xf0) | ((argb >> 12) & 0xf);
+    const uint8_t ba = ((argb >>  0) & 0xf0) | ((argb >> 28) & 0xf);
+#ifdef WEBP_SWAP_16BIT_CSP
+    *dst++ = ba;
+    *dst++ = rg;
+#else
+    *dst++ = rg;
+    *dst++ = ba;
+#endif
+  }
+}
+
+void VP8LConvertBGRAToRGB565_C(const uint32_t* src,
+                               int num_pixels, uint8_t* dst) {
+  const uint32_t* const src_end = src + num_pixels;
+  while (src < src_end) {
+    const uint32_t argb = *src++;
+    const uint8_t rg = ((argb >> 16) & 0xf8) | ((argb >> 13) & 0x7);
+    const uint8_t gb = ((argb >>  5) & 0xe0) | ((argb >>  3) & 0x1f);
+#ifdef WEBP_SWAP_16BIT_CSP
+    *dst++ = gb;
+    *dst++ = rg;
+#else
+    *dst++ = rg;
+    *dst++ = gb;
+#endif
+  }
+}
+
+void VP8LConvertBGRAToBGR_C(const uint32_t* src,
+                            int num_pixels, uint8_t* dst) {
+  const uint32_t* const src_end = src + num_pixels;
+  while (src < src_end) {
+    const uint32_t argb = *src++;
+    *dst++ = (argb >>  0) & 0xff;
+    *dst++ = (argb >>  8) & 0xff;
+    *dst++ = (argb >> 16) & 0xff;
+  }
+}
+
+static void CopyOrSwap(const uint32_t* src, int num_pixels, uint8_t* dst,
+                       int swap_on_big_endian) {
+  if (is_big_endian() == swap_on_big_endian) {
+    const uint32_t* const src_end = src + num_pixels;
+    while (src < src_end) {
+      const uint32_t argb = *src++;
+
+#if !defined(WORDS_BIGENDIAN)
+#if !defined(WEBP_REFERENCE_IMPLEMENTATION)
+      *(uint32_t*)dst = BSwap32(argb);
+#else  // WEBP_REFERENCE_IMPLEMENTATION
+      dst[0] = (argb >> 24) & 0xff;
+      dst[1] = (argb >> 16) & 0xff;
+      dst[2] = (argb >>  8) & 0xff;
+      dst[3] = (argb >>  0) & 0xff;
+#endif
+#else  // WORDS_BIGENDIAN
+      dst[0] = (argb >>  0) & 0xff;
+      dst[1] = (argb >>  8) & 0xff;
+      dst[2] = (argb >> 16) & 0xff;
+      dst[3] = (argb >> 24) & 0xff;
+#endif
+      dst += sizeof(argb);
+    }
+  } else {
+    memcpy(dst, src, num_pixels * sizeof(*src));
+  }
+}
+
+void VP8LConvertFromBGRA(const uint32_t* const in_data, int num_pixels,
+                         WEBP_CSP_MODE out_colorspace, uint8_t* const rgba) {
+  switch (out_colorspace) {
+    case MODE_RGB:
+      VP8LConvertBGRAToRGB(in_data, num_pixels, rgba);
+      break;
+    case MODE_RGBA:
+      VP8LConvertBGRAToRGBA(in_data, num_pixels, rgba);
+      break;
+    case MODE_rgbA:
+      VP8LConvertBGRAToRGBA(in_data, num_pixels, rgba);
+      WebPApplyAlphaMultiply(rgba, 0, num_pixels, 1, 0);
+      break;
+    case MODE_BGR:
+      VP8LConvertBGRAToBGR(in_data, num_pixels, rgba);
+      break;
+    case MODE_BGRA:
+      CopyOrSwap(in_data, num_pixels, rgba, 1);
+      break;
+    case MODE_bgrA:
+      CopyOrSwap(in_data, num_pixels, rgba, 1);
+      WebPApplyAlphaMultiply(rgba, 0, num_pixels, 1, 0);
+      break;
+    case MODE_ARGB:
+      CopyOrSwap(in_data, num_pixels, rgba, 0);
+      break;
+    case MODE_Argb:
+      CopyOrSwap(in_data, num_pixels, rgba, 0);
+      WebPApplyAlphaMultiply(rgba, 1, num_pixels, 1, 0);
+      break;
+    case MODE_RGBA_4444:
+      VP8LConvertBGRAToRGBA4444(in_data, num_pixels, rgba);
+      break;
+    case MODE_rgbA_4444:
+      VP8LConvertBGRAToRGBA4444(in_data, num_pixels, rgba);
+      WebPApplyAlphaMultiply4444(rgba, num_pixels, 1, 0);
+      break;
+    case MODE_RGB_565:
+      VP8LConvertBGRAToRGB565(in_data, num_pixels, rgba);
+      break;
+    default:
+      assert(0);          // Code flow should not reach here.
+  }
+}
+
+//------------------------------------------------------------------------------
+// Bundles multiple (1, 2, 4 or 8) pixels into a single pixel.
+void VP8LBundleColorMap(const uint8_t* const row, int width,
+                        int xbits, uint32_t* const dst) {
+  int x;
+  if (xbits > 0) {
+    const int bit_depth = 1 << (3 - xbits);
+    const int mask = (1 << xbits) - 1;
+    uint32_t code = 0xff000000;
+    for (x = 0; x < width; ++x) {
+      const int xsub = x & mask;
+      if (xsub == 0) {
+        code = 0xff000000;
+      }
+      code |= row[x] << (8 + bit_depth * xsub);
+      dst[x >> xbits] = code;
+    }
+  } else {
+    for (x = 0; x < width; ++x) dst[x] = 0xff000000 | (row[x] << 8);
+  }
+}
+
+//------------------------------------------------------------------------------
+
+static double ExtraCost(const uint32_t* population, int length) {
+  int i;
+  double cost = 0.;
+  for (i = 2; i < length - 2; ++i) cost += (i >> 1) * population[i + 2];
+  return cost;
+}
+
+static double ExtraCostCombined(const uint32_t* X, const uint32_t* Y,
+                                int length) {
+  int i;
+  double cost = 0.;
+  for (i = 2; i < length - 2; ++i) {
+    const int xy = X[i + 2] + Y[i + 2];
+    cost += (i >> 1) * xy;
+  }
+  return cost;
+}
+
+// Returns the various RLE counts
+static VP8LStreaks HuffmanCostCount(const uint32_t* population, int length) {
+  int i;
+  int streak = 0;
+  VP8LStreaks stats;
+  memset(&stats, 0, sizeof(stats));
+  for (i = 0; i < length - 1; ++i) {
+    ++streak;
+    if (population[i] == population[i + 1]) {
+      continue;
+    }
+    stats.counts[population[i] != 0] += (streak > 3);
+    stats.streaks[population[i] != 0][(streak > 3)] += streak;
+    streak = 0;
+  }
+  ++streak;
+  stats.counts[population[i] != 0] += (streak > 3);
+  stats.streaks[population[i] != 0][(streak > 3)] += streak;
+  return stats;
+}
+
+static VP8LStreaks HuffmanCostCombinedCount(const uint32_t* X,
+                                            const uint32_t* Y, int length) {
+  int i;
+  int streak = 0;
+  VP8LStreaks stats;
+  memset(&stats, 0, sizeof(stats));
+  for (i = 0; i < length - 1; ++i) {
+    const int xy = X[i] + Y[i];
+    const int xy_next = X[i + 1] + Y[i + 1];
+    ++streak;
+    if (xy == xy_next) {
+      continue;
+    }
+    stats.counts[xy != 0] += (streak > 3);
+    stats.streaks[xy != 0][(streak > 3)] += streak;
+    streak = 0;
+  }
+  {
+    const int xy = X[i] + Y[i];
+    ++streak;
+    stats.counts[xy != 0] += (streak > 3);
+    stats.streaks[xy != 0][(streak > 3)] += streak;
+  }
+  return stats;
+}
+
+//------------------------------------------------------------------------------
+
+static void HistogramAdd(const VP8LHistogram* const a,
+                         const VP8LHistogram* const b,
+                         VP8LHistogram* const out) {
+  int i;
+  const int literal_size = VP8LHistogramNumCodes(a->palette_code_bits_);
+  assert(a->palette_code_bits_ == b->palette_code_bits_);
+  if (b != out) {
+    for (i = 0; i < literal_size; ++i) {
+      out->literal_[i] = a->literal_[i] + b->literal_[i];
+    }
+    for (i = 0; i < NUM_DISTANCE_CODES; ++i) {
+      out->distance_[i] = a->distance_[i] + b->distance_[i];
+    }
+    for (i = 0; i < NUM_LITERAL_CODES; ++i) {
+      out->red_[i] = a->red_[i] + b->red_[i];
+      out->blue_[i] = a->blue_[i] + b->blue_[i];
+      out->alpha_[i] = a->alpha_[i] + b->alpha_[i];
+    }
+  } else {
+    for (i = 0; i < literal_size; ++i) {
+      out->literal_[i] += a->literal_[i];
+    }
+    for (i = 0; i < NUM_DISTANCE_CODES; ++i) {
+      out->distance_[i] += a->distance_[i];
+    }
+    for (i = 0; i < NUM_LITERAL_CODES; ++i) {
+      out->red_[i] += a->red_[i];
+      out->blue_[i] += a->blue_[i];
+      out->alpha_[i] += a->alpha_[i];
+    }
+  }
+}
+
+//------------------------------------------------------------------------------
+
+VP8LProcessBlueAndRedFunc VP8LSubtractGreenFromBlueAndRed;
+VP8LProcessBlueAndRedFunc VP8LAddGreenToBlueAndRed;
+VP8LPredictorFunc VP8LPredictors[16];
+
+VP8LTransformColorFunc VP8LTransformColor;
+VP8LTransformColorFunc VP8LTransformColorInverse;
+
+VP8LConvertFunc VP8LConvertBGRAToRGB;
+VP8LConvertFunc VP8LConvertBGRAToRGBA;
+VP8LConvertFunc VP8LConvertBGRAToRGBA4444;
+VP8LConvertFunc VP8LConvertBGRAToRGB565;
+VP8LConvertFunc VP8LConvertBGRAToBGR;
+
+VP8LCollectColorBlueTransformsFunc VP8LCollectColorBlueTransforms;
+VP8LCollectColorRedTransformsFunc VP8LCollectColorRedTransforms;
+
+VP8LFastLog2SlowFunc VP8LFastLog2Slow;
+VP8LFastLog2SlowFunc VP8LFastSLog2Slow;
+
+VP8LCostFunc VP8LExtraCost;
+VP8LCostCombinedFunc VP8LExtraCostCombined;
+
+VP8LCostCountFunc VP8LHuffmanCostCount;
+VP8LCostCombinedCountFunc VP8LHuffmanCostCombinedCount;
+
+VP8LHistogramAddFunc VP8LHistogramAdd;
+
+VP8LMapARGBFunc VP8LMapColor32b;
+VP8LMapAlphaFunc VP8LMapColor8b;
+
+extern void VP8LDspInitSSE2(void);
+extern void VP8LDspInitNEON(void);
+extern void VP8LDspInitMIPS32(void);
+extern void VP8LDspInitMIPSdspR2(void);
+
+static volatile VP8CPUInfo lossless_last_cpuinfo_used =
+    (VP8CPUInfo)&lossless_last_cpuinfo_used;
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8LDspInit(void) {
+  if (lossless_last_cpuinfo_used == VP8GetCPUInfo) return;
+
+  VP8LPredictors[0] = Predictor0;
+  VP8LPredictors[1] = Predictor1;
+  VP8LPredictors[2] = Predictor2;
+  VP8LPredictors[3] = Predictor3;
+  VP8LPredictors[4] = Predictor4;
+  VP8LPredictors[5] = Predictor5;
+  VP8LPredictors[6] = Predictor6;
+  VP8LPredictors[7] = Predictor7;
+  VP8LPredictors[8] = Predictor8;
+  VP8LPredictors[9] = Predictor9;
+  VP8LPredictors[10] = Predictor10;
+  VP8LPredictors[11] = Predictor11;
+  VP8LPredictors[12] = Predictor12;
+  VP8LPredictors[13] = Predictor13;
+  VP8LPredictors[14] = Predictor0;     // <- padding security sentinels
+  VP8LPredictors[15] = Predictor0;
+
+  VP8LSubtractGreenFromBlueAndRed = VP8LSubtractGreenFromBlueAndRed_C;
+  VP8LAddGreenToBlueAndRed = VP8LAddGreenToBlueAndRed_C;
+
+  VP8LTransformColor = VP8LTransformColor_C;
+  VP8LTransformColorInverse = VP8LTransformColorInverse_C;
+
+  VP8LConvertBGRAToRGB = VP8LConvertBGRAToRGB_C;
+  VP8LConvertBGRAToRGBA = VP8LConvertBGRAToRGBA_C;
+  VP8LConvertBGRAToRGBA4444 = VP8LConvertBGRAToRGBA4444_C;
+  VP8LConvertBGRAToRGB565 = VP8LConvertBGRAToRGB565_C;
+  VP8LConvertBGRAToBGR = VP8LConvertBGRAToBGR_C;
+
+  VP8LCollectColorBlueTransforms = CollectColorBlueTransforms;
+  VP8LCollectColorRedTransforms = CollectColorRedTransforms;
+
+  VP8LFastLog2Slow = FastLog2Slow;
+  VP8LFastSLog2Slow = FastSLog2Slow;
+
+  VP8LExtraCost = ExtraCost;
+  VP8LExtraCostCombined = ExtraCostCombined;
+
+  VP8LHuffmanCostCount = HuffmanCostCount;
+  VP8LHuffmanCostCombinedCount = HuffmanCostCombinedCount;
+
+  VP8LHistogramAdd = HistogramAdd;
+
+  VP8LMapColor32b = MapARGB;
+  VP8LMapColor8b = MapAlpha;
+
+  // If defined, use CPUInfo() to overwrite some pointers with faster versions.
+  if (VP8GetCPUInfo != NULL) {
+#if defined(WEBP_USE_SSE2)
+    if (VP8GetCPUInfo(kSSE2)) {
+      VP8LDspInitSSE2();
+    }
+#endif
+#if defined(WEBP_USE_NEON)
+    if (VP8GetCPUInfo(kNEON)) {
+      VP8LDspInitNEON();
+    }
+#endif
+#if defined(WEBP_USE_MIPS32)
+    if (VP8GetCPUInfo(kMIPS32)) {
+      VP8LDspInitMIPS32();
+    }
+#endif
+#if defined(WEBP_USE_MIPS_DSP_R2)
+    if (VP8GetCPUInfo(kMIPSdspR2)) {
+      VP8LDspInitMIPSdspR2();
+    }
+#endif
+  }
+  lossless_last_cpuinfo_used = VP8GetCPUInfo;
+}
+
+//------------------------------------------------------------------------------
diff --git a/Source/LibWebP/src/dsp/dsp.lossless_mips32.c b/Source/LibWebP/src/dsp/dsp.lossless_mips32.c
new file mode 100644
index 0000000..68fbe85
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.lossless_mips32.c
@@ -0,0 +1,416 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// MIPS version of lossless functions
+//
+// Author(s):  Djordje Pesut    (djordje.pesut at imgtec.com)
+//             Jovan Zelincevic (jovan.zelincevic at imgtec.com)
+
+#include "./dsp.h"
+#include "./lossless.h"
+
+#if defined(WEBP_USE_MIPS32)
+
+#include <assert.h>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define APPROX_LOG_WITH_CORRECTION_MAX  65536
+#define APPROX_LOG_MAX                   4096
+#define LOG_2_RECIPROCAL 1.44269504088896338700465094007086
+
+static float FastSLog2Slow(uint32_t v) {
+  assert(v >= LOG_LOOKUP_IDX_MAX);
+  if (v < APPROX_LOG_WITH_CORRECTION_MAX) {
+    uint32_t log_cnt, y, correction;
+    const int c24 = 24;
+    const float v_f = (float)v;
+    uint32_t temp;
+
+    // Xf = 256 = 2^8
+    // log_cnt is index of leading one in upper 24 bits
+    __asm__ volatile(
+      "clz      %[log_cnt], %[v]                      \n\t"
+      "addiu    %[y],       $zero,        1           \n\t"
+      "subu     %[log_cnt], %[c24],       %[log_cnt]  \n\t"
+      "sllv     %[y],       %[y],         %[log_cnt]  \n\t"
+      "srlv     %[temp],    %[v],         %[log_cnt]  \n\t"
+      : [log_cnt]"=&r"(log_cnt), [y]"=&r"(y),
+        [temp]"=r"(temp)
+      : [c24]"r"(c24), [v]"r"(v)
+    );
+
+    // vf = (2^log_cnt) * Xf; where y = 2^log_cnt and Xf < 256
+    // Xf = floor(Xf) * (1 + (v % y) / v)
+    // log2(Xf) = log2(floor(Xf)) + log2(1 + (v % y) / v)
+    // The correction factor: log(1 + d) ~ d; for very small d values, so
+    // log2(1 + (v % y) / v) ~ LOG_2_RECIPROCAL * (v % y)/v
+    // LOG_2_RECIPROCAL ~ 23/16
+
+    // (v % y) = (v % 2^log_cnt) = v & (2^log_cnt - 1)
+    correction = (23 * (v & (y - 1))) >> 4;
+    return v_f * (kLog2Table[temp] + log_cnt) + correction;
+  } else {
+    return (float)(LOG_2_RECIPROCAL * v * log((double)v));
+  }
+}
+
+static float FastLog2Slow(uint32_t v) {
+  assert(v >= LOG_LOOKUP_IDX_MAX);
+  if (v < APPROX_LOG_WITH_CORRECTION_MAX) {
+    uint32_t log_cnt, y;
+    const int c24 = 24;
+    double log_2;
+    uint32_t temp;
+
+    __asm__ volatile(
+      "clz      %[log_cnt], %[v]                      \n\t"
+      "addiu    %[y],       $zero,        1           \n\t"
+      "subu     %[log_cnt], %[c24],       %[log_cnt]  \n\t"
+      "sllv     %[y],       %[y],         %[log_cnt]  \n\t"
+      "srlv     %[temp],    %[v],         %[log_cnt]  \n\t"
+      : [log_cnt]"=&r"(log_cnt), [y]"=&r"(y),
+        [temp]"=r"(temp)
+      : [c24]"r"(c24), [v]"r"(v)
+    );
+
+    log_2 = kLog2Table[temp] + log_cnt;
+    if (v >= APPROX_LOG_MAX) {
+      // Since the division is still expensive, add this correction factor only
+      // for large values of 'v'.
+
+      const uint32_t correction = (23 * (v & (y - 1))) >> 4;
+      log_2 += (double)correction / v;
+    }
+    return (float)log_2;
+  } else {
+    return (float)(LOG_2_RECIPROCAL * log((double)v));
+  }
+}
+
+// C version of this function:
+//   int i = 0;
+//   int64_t cost = 0;
+//   const uint32_t* pop = &population[4];
+//   const uint32_t* LoopEnd = &population[length];
+//   while (pop != LoopEnd) {
+//     ++i;
+//     cost += i * *pop;
+//     cost += i * *(pop + 1);
+//     pop += 2;
+//   }
+//   return (double)cost;
+static double ExtraCost(const uint32_t* const population, int length) {
+  int i, temp0, temp1;
+  const uint32_t* pop = &population[4];
+  const uint32_t* const LoopEnd = &population[length];
+
+  __asm__ volatile(
+    "mult   $zero,    $zero                  \n\t"
+    "xor    %[i],     %[i],       %[i]       \n\t"
+    "beq    %[pop],   %[LoopEnd], 2f         \n\t"
+  "1:                                        \n\t"
+    "lw     %[temp0], 0(%[pop])              \n\t"
+    "lw     %[temp1], 4(%[pop])              \n\t"
+    "addiu  %[i],     %[i],       1          \n\t"
+    "addiu  %[pop],   %[pop],     8          \n\t"
+    "madd   %[i],     %[temp0]               \n\t"
+    "madd   %[i],     %[temp1]               \n\t"
+    "bne    %[pop],   %[LoopEnd], 1b         \n\t"
+  "2:                                        \n\t"
+    "mfhi   %[temp0]                         \n\t"
+    "mflo   %[temp1]                         \n\t"
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),
+      [i]"=&r"(i), [pop]"+r"(pop)
+    : [LoopEnd]"r"(LoopEnd)
+    : "memory", "hi", "lo"
+  );
+
+  return (double)((int64_t)temp0 << 32 | temp1);
+}
+
+// C version of this function:
+//   int i = 0;
+//   int64_t cost = 0;
+//   const uint32_t* pX = &X[4];
+//   const uint32_t* pY = &Y[4];
+//   const uint32_t* LoopEnd = &X[length];
+//   while (pX != LoopEnd) {
+//     const uint32_t xy0 = *pX + *pY;
+//     const uint32_t xy1 = *(pX + 1) + *(pY + 1);
+//     ++i;
+//     cost += i * xy0;
+//     cost += i * xy1;
+//     pX += 2;
+//     pY += 2;
+//   }
+//   return (double)cost;
+static double ExtraCostCombined(const uint32_t* const X,
+                                const uint32_t* const Y, int length) {
+  int i, temp0, temp1, temp2, temp3;
+  const uint32_t* pX = &X[4];
+  const uint32_t* pY = &Y[4];
+  const uint32_t* const LoopEnd = &X[length];
+
+  __asm__ volatile(
+    "mult   $zero,    $zero                  \n\t"
+    "xor    %[i],     %[i],       %[i]       \n\t"
+    "beq    %[pX],    %[LoopEnd], 2f         \n\t"
+  "1:                                        \n\t"
+    "lw     %[temp0], 0(%[pX])               \n\t"
+    "lw     %[temp1], 0(%[pY])               \n\t"
+    "lw     %[temp2], 4(%[pX])               \n\t"
+    "lw     %[temp3], 4(%[pY])               \n\t"
+    "addiu  %[i],     %[i],       1          \n\t"
+    "addu   %[temp0], %[temp0],   %[temp1]   \n\t"
+    "addu   %[temp2], %[temp2],   %[temp3]   \n\t"
+    "addiu  %[pX],    %[pX],      8          \n\t"
+    "addiu  %[pY],    %[pY],      8          \n\t"
+    "madd   %[i],     %[temp0]               \n\t"
+    "madd   %[i],     %[temp2]               \n\t"
+    "bne    %[pX],    %[LoopEnd], 1b         \n\t"
+  "2:                                        \n\t"
+    "mfhi   %[temp0]                         \n\t"
+    "mflo   %[temp1]                         \n\t"
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),
+      [temp2]"=&r"(temp2), [temp3]"=&r"(temp3),
+      [i]"=&r"(i), [pX]"+r"(pX), [pY]"+r"(pY)
+    : [LoopEnd]"r"(LoopEnd)
+    : "memory", "hi", "lo"
+  );
+
+  return (double)((int64_t)temp0 << 32 | temp1);
+}
+
+#define HUFFMAN_COST_PASS                                 \
+  __asm__ volatile(                                       \
+    "sll   %[temp1],  %[temp0],    3           \n\t"      \
+    "addiu %[temp3],  %[streak],   -3          \n\t"      \
+    "addu  %[temp2],  %[pstreaks], %[temp1]    \n\t"      \
+    "blez  %[temp3],  1f                       \n\t"      \
+    "srl   %[temp1],  %[temp1],    1           \n\t"      \
+    "addu  %[temp3],  %[pcnts],    %[temp1]    \n\t"      \
+    "lw    %[temp0],  4(%[temp2])              \n\t"      \
+    "lw    %[temp1],  0(%[temp3])              \n\t"      \
+    "addu  %[temp0],  %[temp0],    %[streak]   \n\t"      \
+    "addiu %[temp1],  %[temp1],    1           \n\t"      \
+    "sw    %[temp0],  4(%[temp2])              \n\t"      \
+    "sw    %[temp1],  0(%[temp3])              \n\t"      \
+    "b     2f                                  \n\t"      \
+  "1:                                          \n\t"      \
+    "lw    %[temp0],  0(%[temp2])              \n\t"      \
+    "addu  %[temp0],  %[temp0],    %[streak]   \n\t"      \
+    "sw    %[temp0],  0(%[temp2])              \n\t"      \
+  "2:                                          \n\t"      \
+    : [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),           \
+      [temp3]"=&r"(temp3), [temp0]"+r"(temp0)             \
+    : [pstreaks]"r"(pstreaks), [pcnts]"r"(pcnts),         \
+      [streak]"r"(streak)                                 \
+    : "memory"                                            \
+  );
+
+// Returns the various RLE counts
+static VP8LStreaks HuffmanCostCount(const uint32_t* population, int length) {
+  int i;
+  int streak = 0;
+  VP8LStreaks stats;
+  int* const pstreaks = &stats.streaks[0][0];
+  int* const pcnts = &stats.counts[0];
+  int temp0, temp1, temp2, temp3;
+  memset(&stats, 0, sizeof(stats));
+  for (i = 0; i < length - 1; ++i) {
+    ++streak;
+    if (population[i] == population[i + 1]) {
+      continue;
+    }
+    temp0 = (population[i] != 0);
+    HUFFMAN_COST_PASS
+    streak = 0;
+  }
+  ++streak;
+  temp0 = (population[i] != 0);
+  HUFFMAN_COST_PASS
+
+  return stats;
+}
+
+static VP8LStreaks HuffmanCostCombinedCount(const uint32_t* X,
+                                            const uint32_t* Y, int length) {
+  int i;
+  int streak = 0;
+  VP8LStreaks stats;
+  int* const pstreaks = &stats.streaks[0][0];
+  int* const pcnts = &stats.counts[0];
+  int temp0, temp1, temp2, temp3;
+  memset(&stats, 0, sizeof(stats));
+  for (i = 0; i < length - 1; ++i) {
+    const uint32_t xy = X[i] + Y[i];
+    const uint32_t xy_next = X[i + 1] + Y[i + 1];
+    ++streak;
+    if (xy == xy_next) {
+      continue;
+    }
+    temp0 = (xy != 0);
+    HUFFMAN_COST_PASS
+    streak = 0;
+  }
+  {
+    const uint32_t xy = X[i] + Y[i];
+    ++streak;
+    temp0 = (xy != 0);
+    HUFFMAN_COST_PASS
+  }
+
+  return stats;
+}
+
+#define ASM_START                                       \
+  __asm__ volatile(                                     \
+    ".set   push                            \n\t"       \
+    ".set   at                              \n\t"       \
+    ".set   macro                           \n\t"       \
+  "1:                                       \n\t"
+
+// P2 = P0 + P1
+// A..D - offsets
+// E - temp variable to tell macro
+//     if pointer should be incremented
+// literal_ and successive histograms could be unaligned
+// so we must use ulw and usw
+#define ADD_TO_OUT(A, B, C, D, E, P0, P1, P2)           \
+    "ulw    %[temp0], "#A"(%["#P0"])        \n\t"       \
+    "ulw    %[temp1], "#B"(%["#P0"])        \n\t"       \
+    "ulw    %[temp2], "#C"(%["#P0"])        \n\t"       \
+    "ulw    %[temp3], "#D"(%["#P0"])        \n\t"       \
+    "ulw    %[temp4], "#A"(%["#P1"])        \n\t"       \
+    "ulw    %[temp5], "#B"(%["#P1"])        \n\t"       \
+    "ulw    %[temp6], "#C"(%["#P1"])        \n\t"       \
+    "ulw    %[temp7], "#D"(%["#P1"])        \n\t"       \
+    "addu   %[temp4], %[temp4],   %[temp0]  \n\t"       \
+    "addu   %[temp5], %[temp5],   %[temp1]  \n\t"       \
+    "addu   %[temp6], %[temp6],   %[temp2]  \n\t"       \
+    "addu   %[temp7], %[temp7],   %[temp3]  \n\t"       \
+    "addiu  %["#P0"],  %["#P0"],  16        \n\t"       \
+  ".if "#E" == 1                            \n\t"       \
+    "addiu  %["#P1"],  %["#P1"],  16        \n\t"       \
+  ".endif                                   \n\t"       \
+    "usw    %[temp4], "#A"(%["#P2"])        \n\t"       \
+    "usw    %[temp5], "#B"(%["#P2"])        \n\t"       \
+    "usw    %[temp6], "#C"(%["#P2"])        \n\t"       \
+    "usw    %[temp7], "#D"(%["#P2"])        \n\t"       \
+    "addiu  %["#P2"], %["#P2"],   16        \n\t"       \
+    "bne    %["#P0"], %[LoopEnd], 1b        \n\t"       \
+    ".set   pop                             \n\t"       \
+
+#define ASM_END_COMMON_0                                \
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),         \
+      [temp2]"=&r"(temp2), [temp3]"=&r"(temp3),         \
+      [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),         \
+      [temp6]"=&r"(temp6), [temp7]"=&r"(temp7),         \
+      [pa]"+r"(pa), [pout]"+r"(pout)
+
+#define ASM_END_COMMON_1                                \
+    : [LoopEnd]"r"(LoopEnd)                             \
+    : "memory", "at"                                    \
+  );
+
+#define ASM_END_0                                       \
+    ASM_END_COMMON_0                                    \
+      , [pb]"+r"(pb)                                    \
+    ASM_END_COMMON_1
+
+#define ASM_END_1                                       \
+    ASM_END_COMMON_0                                    \
+    ASM_END_COMMON_1
+
+#define ADD_VECTOR(A, B, OUT, SIZE, EXTRA_SIZE)  do {   \
+  const uint32_t* pa = (const uint32_t*)(A);            \
+  const uint32_t* pb = (const uint32_t*)(B);            \
+  uint32_t* pout = (uint32_t*)(OUT);                    \
+  const uint32_t* const LoopEnd = pa + (SIZE);          \
+  assert((SIZE) % 4 == 0);                              \
+  ASM_START                                             \
+  ADD_TO_OUT(0, 4, 8, 12, 1, pa, pb, pout)              \
+  ASM_END_0                                             \
+  if ((EXTRA_SIZE) > 0) {                               \
+    const int last = (EXTRA_SIZE);                      \
+    int i;                                              \
+    for (i = 0; i < last; ++i) pout[i] = pa[i] + pb[i]; \
+  }                                                     \
+} while (0)
+
+#define ADD_VECTOR_EQ(A, OUT, SIZE, EXTRA_SIZE)  do {   \
+  const uint32_t* pa = (const uint32_t*)(A);            \
+  uint32_t* pout = (uint32_t*)(OUT);                    \
+  const uint32_t* const LoopEnd = pa + (SIZE);          \
+  assert((SIZE) % 4 == 0);                              \
+  ASM_START                                             \
+  ADD_TO_OUT(0, 4, 8, 12, 0, pa, pout, pout)            \
+  ASM_END_1                                             \
+  if ((EXTRA_SIZE) > 0) {                               \
+    const int last = (EXTRA_SIZE);                      \
+    int i;                                              \
+    for (i = 0; i < last; ++i) pout[i] += pa[i];        \
+  }                                                     \
+} while (0)
+
+static void HistogramAdd(const VP8LHistogram* const a,
+                         const VP8LHistogram* const b,
+                         VP8LHistogram* const out) {
+  uint32_t temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
+  const int extra_cache_size = VP8LHistogramNumCodes(a->palette_code_bits_)
+                             - (NUM_LITERAL_CODES + NUM_LENGTH_CODES);
+  assert(a->palette_code_bits_ == b->palette_code_bits_);
+
+  if (b != out) {
+    ADD_VECTOR(a->literal_, b->literal_, out->literal_,
+               NUM_LITERAL_CODES + NUM_LENGTH_CODES, extra_cache_size);
+    ADD_VECTOR(a->distance_, b->distance_, out->distance_,
+               NUM_DISTANCE_CODES, 0);
+    ADD_VECTOR(a->red_, b->red_, out->red_, NUM_LITERAL_CODES, 0);
+    ADD_VECTOR(a->blue_, b->blue_, out->blue_, NUM_LITERAL_CODES, 0);
+    ADD_VECTOR(a->alpha_, b->alpha_, out->alpha_, NUM_LITERAL_CODES, 0);
+  } else {
+    ADD_VECTOR_EQ(a->literal_, out->literal_,
+                  NUM_LITERAL_CODES + NUM_LENGTH_CODES, extra_cache_size);
+    ADD_VECTOR_EQ(a->distance_, out->distance_, NUM_DISTANCE_CODES, 0);
+    ADD_VECTOR_EQ(a->red_, out->red_, NUM_LITERAL_CODES, 0);
+    ADD_VECTOR_EQ(a->blue_, out->blue_, NUM_LITERAL_CODES, 0);
+    ADD_VECTOR_EQ(a->alpha_, out->alpha_, NUM_LITERAL_CODES, 0);
+  }
+}
+
+#undef ADD_VECTOR_EQ
+#undef ADD_VECTOR
+#undef ASM_END_1
+#undef ASM_END_0
+#undef ASM_END_COMMON_1
+#undef ASM_END_COMMON_0
+#undef ADD_TO_OUT
+#undef ASM_START
+
+#endif  // WEBP_USE_MIPS32
+
+//------------------------------------------------------------------------------
+// Entry point
+
+extern void VP8LDspInitMIPS32(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8LDspInitMIPS32(void) {
+#if defined(WEBP_USE_MIPS32)
+  VP8LFastSLog2Slow = FastSLog2Slow;
+  VP8LFastLog2Slow = FastLog2Slow;
+  VP8LExtraCost = ExtraCost;
+  VP8LExtraCostCombined = ExtraCostCombined;
+  VP8LHuffmanCostCount = HuffmanCostCount;
+  VP8LHuffmanCostCombinedCount = HuffmanCostCombinedCount;
+  VP8LHistogramAdd = HistogramAdd;
+#endif  // WEBP_USE_MIPS32
+}
diff --git a/Source/LibWebP/src/dsp/dsp.lossless_mips_dsp_r2.c b/Source/LibWebP/src/dsp/dsp.lossless_mips_dsp_r2.c
new file mode 100644
index 0000000..821cda9
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.lossless_mips_dsp_r2.c
@@ -0,0 +1,921 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Image transforms and color space conversion methods for lossless decoder.
+//
+// Author(s):  Djordje Pesut    (djordje.pesut at imgtec.com)
+//             Jovan Zelincevic (jovan.zelincevic at imgtec.com)
+
+#include "./dsp.h"
+
+#if defined(WEBP_USE_MIPS_DSP_R2)
+
+#include "./lossless.h"
+
+#define MAP_COLOR_FUNCS(FUNC_NAME, TYPE, GET_INDEX, GET_VALUE)                 \
+static void FUNC_NAME(const TYPE* src,                                         \
+                      const uint32_t* const color_map,                         \
+                      TYPE* dst, int y_start, int y_end,                       \
+                      int width) {                                             \
+  int y;                                                                       \
+  for (y = y_start; y < y_end; ++y) {                                          \
+    int x;                                                                     \
+    for (x = 0; x < (width >> 2); ++x) {                                       \
+      int tmp1, tmp2, tmp3, tmp4;                                              \
+      __asm__ volatile (                                                       \
+      ".ifc        "#TYPE",  uint8_t                    \n\t"                  \
+        "lbu       %[tmp1],  0(%[src])                  \n\t"                  \
+        "lbu       %[tmp2],  1(%[src])                  \n\t"                  \
+        "lbu       %[tmp3],  2(%[src])                  \n\t"                  \
+        "lbu       %[tmp4],  3(%[src])                  \n\t"                  \
+        "addiu     %[src],   %[src],      4             \n\t"                  \
+      ".endif                                           \n\t"                  \
+      ".ifc        "#TYPE",  uint32_t                   \n\t"                  \
+        "lw        %[tmp1],  0(%[src])                  \n\t"                  \
+        "lw        %[tmp2],  4(%[src])                  \n\t"                  \
+        "lw        %[tmp3],  8(%[src])                  \n\t"                  \
+        "lw        %[tmp4],  12(%[src])                 \n\t"                  \
+        "ext       %[tmp1],  %[tmp1],     8,        8   \n\t"                  \
+        "ext       %[tmp2],  %[tmp2],     8,        8   \n\t"                  \
+        "ext       %[tmp3],  %[tmp3],     8,        8   \n\t"                  \
+        "ext       %[tmp4],  %[tmp4],     8,        8   \n\t"                  \
+        "addiu     %[src],   %[src],      16            \n\t"                  \
+      ".endif                                           \n\t"                  \
+        "sll       %[tmp1],  %[tmp1],     2             \n\t"                  \
+        "sll       %[tmp2],  %[tmp2],     2             \n\t"                  \
+        "sll       %[tmp3],  %[tmp3],     2             \n\t"                  \
+        "sll       %[tmp4],  %[tmp4],     2             \n\t"                  \
+        "lwx       %[tmp1],  %[tmp1](%[color_map])      \n\t"                  \
+        "lwx       %[tmp2],  %[tmp2](%[color_map])      \n\t"                  \
+        "lwx       %[tmp3],  %[tmp3](%[color_map])      \n\t"                  \
+        "lwx       %[tmp4],  %[tmp4](%[color_map])      \n\t"                  \
+      ".ifc        "#TYPE",  uint8_t                    \n\t"                  \
+        "ext       %[tmp1],  %[tmp1],     8,        8   \n\t"                  \
+        "ext       %[tmp2],  %[tmp2],     8,        8   \n\t"                  \
+        "ext       %[tmp3],  %[tmp3],     8,        8   \n\t"                  \
+        "ext       %[tmp4],  %[tmp4],     8,        8   \n\t"                  \
+        "sb        %[tmp1],  0(%[dst])                  \n\t"                  \
+        "sb        %[tmp2],  1(%[dst])                  \n\t"                  \
+        "sb        %[tmp3],  2(%[dst])                  \n\t"                  \
+        "sb        %[tmp4],  3(%[dst])                  \n\t"                  \
+        "addiu     %[dst],   %[dst],      4             \n\t"                  \
+      ".endif                                           \n\t"                  \
+      ".ifc        "#TYPE",  uint32_t                   \n\t"                  \
+        "sw        %[tmp1],  0(%[dst])                  \n\t"                  \
+        "sw        %[tmp2],  4(%[dst])                  \n\t"                  \
+        "sw        %[tmp3],  8(%[dst])                  \n\t"                  \
+        "sw        %[tmp4],  12(%[dst])                 \n\t"                  \
+        "addiu     %[dst],   %[dst],      16            \n\t"                  \
+      ".endif                                           \n\t"                  \
+        : [tmp1]"=&r"(tmp1), [tmp2]"=&r"(tmp2), [tmp3]"=&r"(tmp3),             \
+          [tmp4]"=&r"(tmp4), [src]"+&r"(src), [dst]"+r"(dst)                   \
+        : [color_map]"r"(color_map)                                            \
+        : "memory"                                                             \
+      );                                                                       \
+    }                                                                          \
+    for (x = 0; x < (width & 3); ++x) {                                        \
+      *dst++ = GET_VALUE(color_map[GET_INDEX(*src++)]);                        \
+    }                                                                          \
+  }                                                                            \
+}
+
+MAP_COLOR_FUNCS(MapARGB, uint32_t, VP8GetARGBIndex, VP8GetARGBValue)
+MAP_COLOR_FUNCS(MapAlpha, uint8_t, VP8GetAlphaIndex, VP8GetAlphaValue)
+
+#undef MAP_COLOR_FUNCS
+
+static WEBP_INLINE uint32_t ClampedAddSubtractFull(uint32_t c0, uint32_t c1,
+                                                   uint32_t c2) {
+  int temp0, temp1, temp2, temp3, temp4, temp5;
+  __asm__ volatile (
+    "preceu.ph.qbr   %[temp1],   %[c0]                 \n\t"
+    "preceu.ph.qbl   %[temp2],   %[c0]                 \n\t"
+    "preceu.ph.qbr   %[temp3],   %[c1]                 \n\t"
+    "preceu.ph.qbl   %[temp4],   %[c1]                 \n\t"
+    "preceu.ph.qbr   %[temp5],   %[c2]                 \n\t"
+    "preceu.ph.qbl   %[temp0],   %[c2]                 \n\t"
+    "subq.ph         %[temp3],   %[temp3],   %[temp5]  \n\t"
+    "subq.ph         %[temp4],   %[temp4],   %[temp0]  \n\t"
+    "addq.ph         %[temp1],   %[temp1],   %[temp3]  \n\t"
+    "addq.ph         %[temp2],   %[temp2],   %[temp4]  \n\t"
+    "shll_s.ph       %[temp1],   %[temp1],   7         \n\t"
+    "shll_s.ph       %[temp2],   %[temp2],   7         \n\t"
+    "precrqu_s.qb.ph %[temp2],   %[temp2],   %[temp1]  \n\t"
+    : [temp0]"=r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5)
+    : [c0]"r"(c0), [c1]"r"(c1), [c2]"r"(c2)
+    : "memory"
+  );
+  return temp2;
+}
+
+static WEBP_INLINE uint32_t ClampedAddSubtractHalf(uint32_t c0, uint32_t c1,
+                                                   uint32_t c2) {
+  int temp0, temp1, temp2, temp3, temp4, temp5;
+  __asm__ volatile (
+    "adduh.qb         %[temp5],   %[c0],      %[c1]       \n\t"
+    "preceu.ph.qbr    %[temp3],   %[c2]                   \n\t"
+    "preceu.ph.qbr    %[temp1],   %[temp5]                \n\t"
+    "preceu.ph.qbl    %[temp2],   %[temp5]                \n\t"
+    "preceu.ph.qbl    %[temp4],   %[c2]                   \n\t"
+    "subq.ph          %[temp3],   %[temp1],   %[temp3]    \n\t"
+    "subq.ph          %[temp4],   %[temp2],   %[temp4]    \n\t"
+    "shrl.ph          %[temp5],   %[temp3],   15          \n\t"
+    "shrl.ph          %[temp0],   %[temp4],   15          \n\t"
+    "addq.ph          %[temp3],   %[temp3],   %[temp5]    \n\t"
+    "addq.ph          %[temp4],   %[temp0],   %[temp4]    \n\t"
+    "shra.ph          %[temp3],   %[temp3],   1           \n\t"
+    "shra.ph          %[temp4],   %[temp4],   1           \n\t"
+    "addq.ph          %[temp1],   %[temp1],   %[temp3]    \n\t"
+    "addq.ph          %[temp2],   %[temp2],   %[temp4]    \n\t"
+    "shll_s.ph        %[temp1],   %[temp1],   7           \n\t"
+    "shll_s.ph        %[temp2],   %[temp2],   7           \n\t"
+    "precrqu_s.qb.ph  %[temp1],   %[temp2],   %[temp1]    \n\t"
+    : [temp0]"=r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [temp3]"=&r"(temp3), [temp4]"=r"(temp4), [temp5]"=&r"(temp5)
+    : [c0]"r"(c0), [c1]"r"(c1), [c2]"r"(c2)
+    : "memory"
+  );
+  return temp1;
+}
+
+static void SubtractGreenFromBlueAndRed(uint32_t* argb_data,
+                                        int num_pixels) {
+  uint32_t temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
+  uint32_t* const p_loop1_end = argb_data + (num_pixels & ~3);
+  uint32_t* const p_loop2_end = p_loop1_end + (num_pixels & 3);
+  __asm__ volatile (
+    ".set       push                                          \n\t"
+    ".set       noreorder                                     \n\t"
+    "beq        %[argb_data],    %[p_loop1_end],     3f       \n\t"
+    " nop                                                     \n\t"
+  "0:                                                         \n\t"
+    "lw         %[temp0],        0(%[argb_data])              \n\t"
+    "lw         %[temp1],        4(%[argb_data])              \n\t"
+    "lw         %[temp2],        8(%[argb_data])              \n\t"
+    "lw         %[temp3],        12(%[argb_data])             \n\t"
+    "ext        %[temp4],        %[temp0],           8,    8  \n\t"
+    "ext        %[temp5],        %[temp1],           8,    8  \n\t"
+    "ext        %[temp6],        %[temp2],           8,    8  \n\t"
+    "ext        %[temp7],        %[temp3],           8,    8  \n\t"
+    "addiu      %[argb_data],    %[argb_data],       16       \n\t"
+    "replv.ph   %[temp4],        %[temp4]                     \n\t"
+    "replv.ph   %[temp5],        %[temp5]                     \n\t"
+    "replv.ph   %[temp6],        %[temp6]                     \n\t"
+    "replv.ph   %[temp7],        %[temp7]                     \n\t"
+    "subu.qb    %[temp0],        %[temp0],           %[temp4] \n\t"
+    "subu.qb    %[temp1],        %[temp1],           %[temp5] \n\t"
+    "subu.qb    %[temp2],        %[temp2],           %[temp6] \n\t"
+    "subu.qb    %[temp3],        %[temp3],           %[temp7] \n\t"
+    "sw         %[temp0],        -16(%[argb_data])            \n\t"
+    "sw         %[temp1],        -12(%[argb_data])            \n\t"
+    "sw         %[temp2],        -8(%[argb_data])             \n\t"
+    "bne        %[argb_data],    %[p_loop1_end],     0b       \n\t"
+    " sw        %[temp3],        -4(%[argb_data])             \n\t"
+  "3:                                                         \n\t"
+    "beq        %[argb_data],    %[p_loop2_end],     2f       \n\t"
+    " nop                                                     \n\t"
+  "1:                                                         \n\t"
+    "lw         %[temp0],        0(%[argb_data])              \n\t"
+    "addiu      %[argb_data],    %[argb_data],       4        \n\t"
+    "ext        %[temp4],        %[temp0],           8,    8  \n\t"
+    "replv.ph   %[temp4],        %[temp4]                     \n\t"
+    "subu.qb    %[temp0],        %[temp0],           %[temp4] \n\t"
+    "bne        %[argb_data],    %[p_loop2_end],     1b       \n\t"
+    " sw        %[temp0],        -4(%[argb_data])             \n\t"
+  "2:                                                         \n\t"
+    ".set       pop                                           \n\t"
+    : [argb_data]"+&r"(argb_data), [temp0]"=&r"(temp0),
+      [temp1]"=&r"(temp1), [temp2]"=&r"(temp2), [temp3]"=&r"(temp3),
+      [temp4]"=&r"(temp4), [temp5]"=&r"(temp5), [temp6]"=&r"(temp6),
+      [temp7]"=&r"(temp7)
+    : [p_loop1_end]"r"(p_loop1_end), [p_loop2_end]"r"(p_loop2_end)
+    : "memory"
+  );
+}
+
+static WEBP_INLINE uint32_t Select(uint32_t a, uint32_t b, uint32_t c) {
+  int temp0, temp1, temp2, temp3, temp4, temp5;
+  __asm__ volatile (
+    "cmpgdu.lt.qb %[temp1], %[c],     %[b]             \n\t"
+    "pick.qb      %[temp1], %[b],     %[c]             \n\t"
+    "pick.qb      %[temp2], %[c],     %[b]             \n\t"
+    "cmpgdu.lt.qb %[temp4], %[c],     %[a]             \n\t"
+    "pick.qb      %[temp4], %[a],     %[c]             \n\t"
+    "pick.qb      %[temp5], %[c],     %[a]             \n\t"
+    "subu.qb      %[temp3], %[temp1], %[temp2]         \n\t"
+    "subu.qb      %[temp0], %[temp4], %[temp5]         \n\t"
+    "raddu.w.qb   %[temp3], %[temp3]                   \n\t"
+    "raddu.w.qb   %[temp0], %[temp0]                   \n\t"
+    "subu         %[temp3], %[temp3], %[temp0]         \n\t"
+    "slti         %[temp0], %[temp3], 0x1              \n\t"
+    "movz         %[a],     %[b],     %[temp0]         \n\t"
+    : [temp1]"=&r"(temp1), [temp2]"=&r"(temp2), [temp3]"=&r"(temp3),
+      [temp4]"=&r"(temp4), [temp5]"=&r"(temp5), [temp0]"=&r"(temp0),
+      [a]"+&r"(a)
+    : [b]"r"(b), [c]"r"(c)
+  );
+  return a;
+}
+
+static WEBP_INLINE uint32_t Average2(uint32_t a0, uint32_t a1) {
+  __asm__ volatile (
+    "adduh.qb    %[a0], %[a0], %[a1]       \n\t"
+    : [a0]"+r"(a0)
+    : [a1]"r"(a1)
+  );
+  return a0;
+}
+
+static WEBP_INLINE uint32_t Average3(uint32_t a0, uint32_t a1, uint32_t a2) {
+  return Average2(Average2(a0, a2), a1);
+}
+
+static WEBP_INLINE uint32_t Average4(uint32_t a0, uint32_t a1,
+                                     uint32_t a2, uint32_t a3) {
+  return Average2(Average2(a0, a1), Average2(a2, a3));
+}
+
+static uint32_t Predictor5(uint32_t left, const uint32_t* const top) {
+  return Average3(left, top[0], top[1]);
+}
+
+static uint32_t Predictor6(uint32_t left, const uint32_t* const top) {
+  return Average2(left, top[-1]);
+}
+
+static uint32_t Predictor7(uint32_t left, const uint32_t* const top) {
+  return Average2(left, top[0]);
+}
+
+static uint32_t Predictor8(uint32_t left, const uint32_t* const top) {
+  (void)left;
+  return Average2(top[-1], top[0]);
+}
+
+static uint32_t Predictor9(uint32_t left, const uint32_t* const top) {
+  (void)left;
+  return Average2(top[0], top[1]);
+}
+
+static uint32_t Predictor10(uint32_t left, const uint32_t* const top) {
+  return Average4(left, top[-1], top[0], top[1]);
+}
+
+static uint32_t Predictor11(uint32_t left, const uint32_t* const top) {
+  return Select(top[0], left, top[-1]);
+}
+
+static uint32_t Predictor12(uint32_t left, const uint32_t* const top) {
+  return ClampedAddSubtractFull(left, top[0], top[-1]);
+}
+
+static uint32_t Predictor13(uint32_t left, const uint32_t* const top) {
+  return ClampedAddSubtractHalf(left, top[0], top[-1]);
+}
+
+static WEBP_INLINE uint32_t ColorTransformDelta(int8_t color_pred,
+                                                int8_t color) {
+  return (uint32_t)((int)(color_pred) * color) >> 5;
+}
+
+static void TransformColor(const VP8LMultipliers* const m, uint32_t* data,
+                           int num_pixels) {
+  int temp0, temp1, temp2, temp3, temp4, temp5;
+  uint32_t argb, argb1, new_red, new_red1;
+  const uint32_t G_to_R = m->green_to_red_;
+  const uint32_t G_to_B = m->green_to_blue_;
+  const uint32_t R_to_B = m->red_to_blue_;
+  uint32_t* const p_loop_end = data + (num_pixels & ~1);
+  __asm__ volatile (
+    ".set            push                                    \n\t"
+    ".set            noreorder                               \n\t"
+    "beq             %[data],      %[p_loop_end],  1f        \n\t"
+    " nop                                                    \n\t"
+    "replv.ph        %[temp0],     %[G_to_R]                 \n\t"
+    "replv.ph        %[temp1],     %[G_to_B]                 \n\t"
+    "replv.ph        %[temp2],     %[R_to_B]                 \n\t"
+    "shll.ph         %[temp0],     %[temp0],       8         \n\t"
+    "shll.ph         %[temp1],     %[temp1],       8         \n\t"
+    "shll.ph         %[temp2],     %[temp2],       8         \n\t"
+    "shra.ph         %[temp0],     %[temp0],       8         \n\t"
+    "shra.ph         %[temp1],     %[temp1],       8         \n\t"
+    "shra.ph         %[temp2],     %[temp2],       8         \n\t"
+  "0:                                                        \n\t"
+    "lw              %[argb],      0(%[data])                \n\t"
+    "lw              %[argb1],     4(%[data])                \n\t"
+    "lhu             %[new_red],   2(%[data])                \n\t"
+    "lhu             %[new_red1],  6(%[data])                \n\t"
+    "precrq.qb.ph    %[temp3],     %[argb],        %[argb1]  \n\t"
+    "precr.qb.ph     %[temp4],     %[argb],        %[argb1]  \n\t"
+    "preceu.ph.qbra  %[temp3],     %[temp3]                  \n\t"
+    "preceu.ph.qbla  %[temp4],     %[temp4]                  \n\t"
+    "shll.ph         %[temp3],     %[temp3],       8         \n\t"
+    "shll.ph         %[temp4],     %[temp4],       8         \n\t"
+    "shra.ph         %[temp3],     %[temp3],       8         \n\t"
+    "shra.ph         %[temp4],     %[temp4],       8         \n\t"
+    "mul.ph          %[temp5],     %[temp3],       %[temp0]  \n\t"
+    "mul.ph          %[temp3],     %[temp3],       %[temp1]  \n\t"
+    "mul.ph          %[temp4],     %[temp4],       %[temp2]  \n\t"
+    "addiu           %[data],      %[data],        8         \n\t"
+    "ins             %[new_red1],  %[new_red],     16,   16  \n\t"
+    "ins             %[argb1],     %[argb],        16,   16  \n\t"
+    "shra.ph         %[temp5],     %[temp5],       5         \n\t"
+    "shra.ph         %[temp3],     %[temp3],       5         \n\t"
+    "shra.ph         %[temp4],     %[temp4],       5         \n\t"
+    "subu.ph         %[new_red1],  %[new_red1],    %[temp5]  \n\t"
+    "subu.ph         %[argb1],     %[argb1],       %[temp3]  \n\t"
+    "preceu.ph.qbra  %[temp5],     %[new_red1]               \n\t"
+    "subu.ph         %[argb1],     %[argb1],       %[temp4]  \n\t"
+    "preceu.ph.qbra  %[temp3],     %[argb1]                  \n\t"
+    "sb              %[temp5],     -2(%[data])               \n\t"
+    "sb              %[temp3],     -4(%[data])               \n\t"
+    "sra             %[temp5],     %[temp5],       16        \n\t"
+    "sra             %[temp3],     %[temp3],       16        \n\t"
+    "sb              %[temp5],     -6(%[data])               \n\t"
+    "bne             %[data],      %[p_loop_end],  0b        \n\t"
+    " sb             %[temp3],     -8(%[data])               \n\t"
+  "1:                                                        \n\t"
+    ".set            pop                                     \n\t"
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+      [new_red1]"=&r"(new_red1), [new_red]"=&r"(new_red),
+      [argb]"=&r"(argb), [argb1]"=&r"(argb1), [data]"+&r"(data)
+    : [G_to_R]"r"(G_to_R), [R_to_B]"r"(R_to_B),
+      [G_to_B]"r"(G_to_B), [p_loop_end]"r"(p_loop_end)
+    : "memory", "hi", "lo"
+  );
+
+  if (num_pixels & 1) {
+    const uint32_t argb_ = data[0];
+    const uint32_t green = argb_ >> 8;
+    const uint32_t red = argb_ >> 16;
+    uint32_t new_blue = argb_;
+    new_red = red;
+    new_red -= ColorTransformDelta(m->green_to_red_, green);
+    new_red &= 0xff;
+    new_blue -= ColorTransformDelta(m->green_to_blue_, green);
+    new_blue -= ColorTransformDelta(m->red_to_blue_, red);
+    new_blue &= 0xff;
+    data[0] = (argb_ & 0xff00ff00u) | (new_red << 16) | (new_blue);
+  }
+}
+
+static WEBP_INLINE uint8_t TransformColorBlue(uint8_t green_to_blue,
+                                              uint8_t red_to_blue,
+                                              uint32_t argb) {
+  const uint32_t green = argb >> 8;
+  const uint32_t red = argb >> 16;
+  uint8_t new_blue = argb;
+  new_blue -= ColorTransformDelta(green_to_blue, green);
+  new_blue -= ColorTransformDelta(red_to_blue, red);
+  return (new_blue & 0xff);
+}
+
+static void CollectColorBlueTransforms(const uint32_t* argb, int stride,
+                                       int tile_width, int tile_height,
+                                       int green_to_blue, int red_to_blue,
+                                       int histo[]) {
+  const int rtb = (red_to_blue << 16) | (red_to_blue & 0xffff);
+  const int gtb = (green_to_blue << 16) | (green_to_blue & 0xffff);
+  const uint32_t mask = 0xff00ffu;
+  while (tile_height-- > 0) {
+    int x;
+    const uint32_t* p_argb = argb;
+    argb += stride;
+    for (x = 0; x < (tile_width >> 1); ++x) {
+      int temp0, temp1, temp2, temp3, temp4, temp5, temp6;
+      __asm__ volatile (
+        "lw           %[temp0],  0(%[p_argb])             \n\t"
+        "lw           %[temp1],  4(%[p_argb])             \n\t"
+        "precr.qb.ph  %[temp2],  %[temp0],  %[temp1]      \n\t"
+        "ins          %[temp1],  %[temp0],  16,    16     \n\t"
+        "shra.ph      %[temp2],  %[temp2],  8             \n\t"
+        "shra.ph      %[temp3],  %[temp1],  8             \n\t"
+        "mul.ph       %[temp5],  %[temp2],  %[rtb]        \n\t"
+        "mul.ph       %[temp6],  %[temp3],  %[gtb]        \n\t"
+        "and          %[temp4],  %[temp1],  %[mask]       \n\t"
+        "addiu        %[p_argb], %[p_argb], 8             \n\t"
+        "shra.ph      %[temp5],  %[temp5],  5             \n\t"
+        "shra.ph      %[temp6],  %[temp6],  5             \n\t"
+        "subu.qb      %[temp2],  %[temp4],  %[temp5]      \n\t"
+        "subu.qb      %[temp2],  %[temp2],  %[temp6]      \n\t"
+        : [p_argb]"+&r"(p_argb), [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),
+          [temp2]"=&r"(temp2), [temp3]"=&r"(temp3), [temp4]"=&r"(temp4),
+          [temp5]"=&r"(temp5), [temp6]"=&r"(temp6)
+        : [rtb]"r"(rtb), [gtb]"r"(gtb), [mask]"r"(mask)
+        : "memory", "hi", "lo"
+      );
+      ++histo[(uint8_t)(temp2 >> 16)];
+      ++histo[(uint8_t)temp2];
+    }
+    if (tile_width & 1) {
+      ++histo[TransformColorBlue(green_to_blue, red_to_blue, *p_argb)];
+    }
+  }
+}
+
+static WEBP_INLINE uint8_t TransformColorRed(uint8_t green_to_red,
+                                             uint32_t argb) {
+  const uint32_t green = argb >> 8;
+  uint32_t new_red = argb >> 16;
+  new_red -= ColorTransformDelta(green_to_red, green);
+  return (new_red & 0xff);
+}
+
+static void CollectColorRedTransforms(const uint32_t* argb, int stride,
+                                      int tile_width, int tile_height,
+                                      int green_to_red, int histo[]) {
+  const int gtr = (green_to_red << 16) | (green_to_red & 0xffff);
+  while (tile_height-- > 0) {
+    int x;
+    const uint32_t* p_argb = argb;
+    argb += stride;
+    for (x = 0; x < (tile_width >> 1); ++x) {
+      int temp0, temp1, temp2, temp3, temp4;
+      __asm__ volatile (
+        "lw           %[temp0],  0(%[p_argb])             \n\t"
+        "lw           %[temp1],  4(%[p_argb])             \n\t"
+        "precrq.ph.w  %[temp4],  %[temp0],  %[temp1]      \n\t"
+        "ins          %[temp1],  %[temp0],  16,    16     \n\t"
+        "shra.ph      %[temp3],  %[temp1],  8             \n\t"
+        "mul.ph       %[temp2],  %[temp3],  %[gtr]        \n\t"
+        "addiu        %[p_argb], %[p_argb], 8             \n\t"
+        "shra.ph      %[temp2],  %[temp2],  5             \n\t"
+        "subu.qb      %[temp2],  %[temp4],  %[temp2]      \n\t"
+        : [p_argb]"+&r"(p_argb), [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),
+          [temp2]"=&r"(temp2), [temp3]"=&r"(temp3), [temp4]"=&r"(temp4)
+        : [gtr]"r"(gtr)
+        : "memory", "hi", "lo"
+      );
+      ++histo[(uint8_t)(temp2 >> 16)];
+      ++histo[(uint8_t)temp2];
+    }
+    if (tile_width & 1) {
+      ++histo[TransformColorRed(green_to_red, *p_argb)];
+    }
+  }
+}
+
+// Add green to blue and red channels (i.e. perform the inverse transform of
+// 'subtract green').
+static void AddGreenToBlueAndRed(uint32_t* data, int num_pixels) {
+  uint32_t temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
+  uint32_t* const p_loop1_end = data + (num_pixels & ~3);
+  uint32_t* const p_loop2_end = data + num_pixels;
+  __asm__ volatile (
+    ".set       push                                          \n\t"
+    ".set       noreorder                                     \n\t"
+    "beq        %[data],         %[p_loop1_end],     3f       \n\t"
+    " nop                                                     \n\t"
+  "0:                                                         \n\t"
+    "lw         %[temp0],        0(%[data])                   \n\t"
+    "lw         %[temp1],        4(%[data])                   \n\t"
+    "lw         %[temp2],        8(%[data])                   \n\t"
+    "lw         %[temp3],        12(%[data])                  \n\t"
+    "ext        %[temp4],        %[temp0],           8,    8  \n\t"
+    "ext        %[temp5],        %[temp1],           8,    8  \n\t"
+    "ext        %[temp6],        %[temp2],           8,    8  \n\t"
+    "ext        %[temp7],        %[temp3],           8,    8  \n\t"
+    "addiu      %[data],         %[data],            16       \n\t"
+    "replv.ph   %[temp4],        %[temp4]                     \n\t"
+    "replv.ph   %[temp5],        %[temp5]                     \n\t"
+    "replv.ph   %[temp6],        %[temp6]                     \n\t"
+    "replv.ph   %[temp7],        %[temp7]                     \n\t"
+    "addu.qb    %[temp0],        %[temp0],           %[temp4] \n\t"
+    "addu.qb    %[temp1],        %[temp1],           %[temp5] \n\t"
+    "addu.qb    %[temp2],        %[temp2],           %[temp6] \n\t"
+    "addu.qb    %[temp3],        %[temp3],           %[temp7] \n\t"
+    "sw         %[temp0],        -16(%[data])                 \n\t"
+    "sw         %[temp1],        -12(%[data])                 \n\t"
+    "sw         %[temp2],        -8(%[data])                  \n\t"
+    "bne        %[data],         %[p_loop1_end],     0b       \n\t"
+    " sw        %[temp3],        -4(%[data])                  \n\t"
+  "3:                                                         \n\t"
+    "beq        %[data],         %[p_loop2_end],     2f       \n\t"
+    " nop                                                     \n\t"
+  "1:                                                         \n\t"
+    "lw         %[temp0],        0(%[data])                   \n\t"
+    "addiu      %[data],         %[data],            4        \n\t"
+    "ext        %[temp4],        %[temp0],           8,    8  \n\t"
+    "replv.ph   %[temp4],        %[temp4]                     \n\t"
+    "addu.qb    %[temp0],        %[temp0],           %[temp4] \n\t"
+    "bne        %[data],         %[p_loop2_end],     1b       \n\t"
+    " sw        %[temp0],        -4(%[data])                  \n\t"
+  "2:                                                         \n\t"
+    ".set       pop                                           \n\t"
+    : [data]"+&r"(data), [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),
+      [temp2]"=&r"(temp2), [temp3]"=&r"(temp3), [temp4]"=&r"(temp4),
+      [temp5]"=&r"(temp5), [temp6]"=&r"(temp6), [temp7]"=&r"(temp7)
+    : [p_loop1_end]"r"(p_loop1_end), [p_loop2_end]"r"(p_loop2_end)
+    : "memory"
+  );
+}
+
+static void TransformColorInverse(const VP8LMultipliers* const m,
+                                  uint32_t* data, int num_pixels) {
+  int temp0, temp1, temp2, temp3, temp4, temp5;
+  uint32_t argb, argb1, new_red;
+  const uint32_t G_to_R = m->green_to_red_;
+  const uint32_t G_to_B = m->green_to_blue_;
+  const uint32_t R_to_B = m->red_to_blue_;
+  uint32_t* const p_loop_end = data + (num_pixels & ~1);
+  __asm__ volatile (
+    ".set            push                                    \n\t"
+    ".set            noreorder                               \n\t"
+    "beq             %[data],      %[p_loop_end],  1f        \n\t"
+    " nop                                                    \n\t"
+    "replv.ph        %[temp0],     %[G_to_R]                 \n\t"
+    "replv.ph        %[temp1],     %[G_to_B]                 \n\t"
+    "replv.ph        %[temp2],     %[R_to_B]                 \n\t"
+    "shll.ph         %[temp0],     %[temp0],       8         \n\t"
+    "shll.ph         %[temp1],     %[temp1],       8         \n\t"
+    "shll.ph         %[temp2],     %[temp2],       8         \n\t"
+    "shra.ph         %[temp0],     %[temp0],       8         \n\t"
+    "shra.ph         %[temp1],     %[temp1],       8         \n\t"
+    "shra.ph         %[temp2],     %[temp2],       8         \n\t"
+  "0:                                                        \n\t"
+    "lw              %[argb],      0(%[data])                \n\t"
+    "lw              %[argb1],     4(%[data])                \n\t"
+    "addiu           %[data],      %[data],        8         \n\t"
+    "precrq.qb.ph    %[temp3],     %[argb],        %[argb1]  \n\t"
+    "preceu.ph.qbra  %[temp3],     %[temp3]                  \n\t"
+    "shll.ph         %[temp3],     %[temp3],       8         \n\t"
+    "shra.ph         %[temp3],     %[temp3],       8         \n\t"
+    "mul.ph          %[temp5],     %[temp3],       %[temp0]  \n\t"
+    "mul.ph          %[temp3],     %[temp3],       %[temp1]  \n\t"
+    "precrq.ph.w     %[new_red],   %[argb],        %[argb1]  \n\t"
+    "ins             %[argb1],     %[argb],        16,   16  \n\t"
+    "shra.ph         %[temp5],     %[temp5],       5         \n\t"
+    "shra.ph         %[temp3],     %[temp3],       5         \n\t"
+    "addu.ph         %[new_red],   %[new_red],     %[temp5]  \n\t"
+    "addu.ph         %[argb1],     %[argb1],       %[temp3]  \n\t"
+    "preceu.ph.qbra  %[temp5],     %[new_red]                \n\t"
+    "shll.ph         %[temp4],     %[temp5],       8         \n\t"
+    "shra.ph         %[temp4],     %[temp4],       8         \n\t"
+    "mul.ph          %[temp4],     %[temp4],       %[temp2]  \n\t"
+    "sb              %[temp5],     -2(%[data])               \n\t"
+    "sra             %[temp5],     %[temp5],       16        \n\t"
+    "shra.ph         %[temp4],     %[temp4],       5         \n\t"
+    "addu.ph         %[argb1],     %[argb1],       %[temp4]  \n\t"
+    "preceu.ph.qbra  %[temp3],     %[argb1]                  \n\t"
+    "sb              %[temp5],     -6(%[data])               \n\t"
+    "sb              %[temp3],     -4(%[data])               \n\t"
+    "sra             %[temp3],     %[temp3],       16        \n\t"
+    "bne             %[data],      %[p_loop_end],  0b        \n\t"
+    " sb             %[temp3],     -8(%[data])               \n\t"
+  "1:                                                        \n\t"
+    ".set            pop                                     \n\t"
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+      [new_red]"=&r"(new_red), [argb]"=&r"(argb),
+      [argb1]"=&r"(argb1), [data]"+&r"(data)
+    : [G_to_R]"r"(G_to_R), [R_to_B]"r"(R_to_B),
+      [G_to_B]"r"(G_to_B), [p_loop_end]"r"(p_loop_end)
+    : "memory", "hi", "lo"
+  );
+
+  // Fall-back to C-version for left-overs.
+  if (num_pixels & 1) VP8LTransformColorInverse_C(m, data, 1);
+}
+
+static void ConvertBGRAToRGB(const uint32_t* src,
+                             int num_pixels, uint8_t* dst) {
+  int temp0, temp1, temp2, temp3;
+  const uint32_t* const p_loop1_end = src + (num_pixels & ~3);
+  const uint32_t* const p_loop2_end = src + num_pixels;
+  __asm__ volatile (
+    ".set       push                                       \n\t"
+    ".set       noreorder                                  \n\t"
+    "beq        %[src],      %[p_loop1_end],    3f         \n\t"
+    " nop                                                  \n\t"
+  "0:                                                      \n\t"
+    "lw         %[temp3],    12(%[src])                    \n\t"
+    "lw         %[temp2],    8(%[src])                     \n\t"
+    "lw         %[temp1],    4(%[src])                     \n\t"
+    "lw         %[temp0],    0(%[src])                     \n\t"
+    "ins        %[temp3],    %[temp2],          24,   8    \n\t"
+    "sll        %[temp2],    %[temp2],          8          \n\t"
+    "rotr       %[temp3],    %[temp3],          16         \n\t"
+    "ins        %[temp2],    %[temp1],          0,    16   \n\t"
+    "sll        %[temp1],    %[temp1],          8          \n\t"
+    "wsbh       %[temp3],    %[temp3]                      \n\t"
+    "balign     %[temp0],    %[temp1],          1          \n\t"
+    "wsbh       %[temp2],    %[temp2]                      \n\t"
+    "wsbh       %[temp0],    %[temp0]                      \n\t"
+    "usw        %[temp3],    8(%[dst])                     \n\t"
+    "rotr       %[temp0],    %[temp0],          16         \n\t"
+    "usw        %[temp2],    4(%[dst])                     \n\t"
+    "addiu      %[src],      %[src],            16         \n\t"
+    "usw        %[temp0],    0(%[dst])                     \n\t"
+    "bne        %[src],      %[p_loop1_end],    0b         \n\t"
+    " addiu     %[dst],      %[dst],            12         \n\t"
+  "3:                                                      \n\t"
+    "beq        %[src],      %[p_loop2_end],    2f         \n\t"
+    " nop                                                  \n\t"
+  "1:                                                      \n\t"
+    "lw         %[temp0],    0(%[src])                     \n\t"
+    "addiu      %[src],      %[src],            4          \n\t"
+    "wsbh       %[temp1],    %[temp0]                      \n\t"
+    "addiu      %[dst],      %[dst],            3          \n\t"
+    "ush        %[temp1],    -2(%[dst])                    \n\t"
+    "sra        %[temp0],    %[temp0],          16         \n\t"
+    "bne        %[src],      %[p_loop2_end],    1b         \n\t"
+    " sb        %[temp0],    -3(%[dst])                    \n\t"
+  "2:                                                      \n\t"
+    ".set       pop                                        \n\t"
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [temp3]"=&r"(temp3), [dst]"+&r"(dst), [src]"+&r"(src)
+    : [p_loop1_end]"r"(p_loop1_end), [p_loop2_end]"r"(p_loop2_end)
+    : "memory"
+  );
+}
+
+static void ConvertBGRAToRGBA(const uint32_t* src,
+                              int num_pixels, uint8_t* dst) {
+  int temp0, temp1, temp2, temp3;
+  const uint32_t* const p_loop1_end = src + (num_pixels & ~3);
+  const uint32_t* const p_loop2_end = src + num_pixels;
+  __asm__ volatile (
+    ".set       push                                       \n\t"
+    ".set       noreorder                                  \n\t"
+    "beq        %[src],      %[p_loop1_end],    3f         \n\t"
+    " nop                                                  \n\t"
+  "0:                                                      \n\t"
+    "lw         %[temp0],    0(%[src])                     \n\t"
+    "lw         %[temp1],    4(%[src])                     \n\t"
+    "lw         %[temp2],    8(%[src])                     \n\t"
+    "lw         %[temp3],    12(%[src])                    \n\t"
+    "wsbh       %[temp0],    %[temp0]                      \n\t"
+    "wsbh       %[temp1],    %[temp1]                      \n\t"
+    "wsbh       %[temp2],    %[temp2]                      \n\t"
+    "wsbh       %[temp3],    %[temp3]                      \n\t"
+    "addiu      %[src],      %[src],            16         \n\t"
+    "balign     %[temp0],    %[temp0],          1          \n\t"
+    "balign     %[temp1],    %[temp1],          1          \n\t"
+    "balign     %[temp2],    %[temp2],          1          \n\t"
+    "balign     %[temp3],    %[temp3],          1          \n\t"
+    "usw        %[temp0],    0(%[dst])                     \n\t"
+    "usw        %[temp1],    4(%[dst])                     \n\t"
+    "usw        %[temp2],    8(%[dst])                     \n\t"
+    "usw        %[temp3],    12(%[dst])                    \n\t"
+    "bne        %[src],      %[p_loop1_end],    0b         \n\t"
+    " addiu     %[dst],      %[dst],            16         \n\t"
+  "3:                                                      \n\t"
+    "beq        %[src],      %[p_loop2_end],    2f         \n\t"
+    " nop                                                  \n\t"
+  "1:                                                      \n\t"
+    "lw         %[temp0],    0(%[src])                     \n\t"
+    "wsbh       %[temp0],    %[temp0]                      \n\t"
+    "addiu      %[src],      %[src],            4          \n\t"
+    "balign     %[temp0],    %[temp0],          1          \n\t"
+    "usw        %[temp0],    0(%[dst])                     \n\t"
+    "bne        %[src],      %[p_loop2_end],    1b         \n\t"
+    " addiu     %[dst],      %[dst],            4          \n\t"
+  "2:                                                      \n\t"
+    ".set       pop                                        \n\t"
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [temp3]"=&r"(temp3), [dst]"+&r"(dst), [src]"+&r"(src)
+    : [p_loop1_end]"r"(p_loop1_end), [p_loop2_end]"r"(p_loop2_end)
+    : "memory"
+  );
+}
+
+static void ConvertBGRAToRGBA4444(const uint32_t* src,
+                                  int num_pixels, uint8_t* dst) {
+  int temp0, temp1, temp2, temp3, temp4, temp5;
+  const uint32_t* const p_loop1_end = src + (num_pixels & ~3);
+  const uint32_t* const p_loop2_end = src + num_pixels;
+  __asm__ volatile (
+    ".set           push                                       \n\t"
+    ".set           noreorder                                  \n\t"
+    "beq            %[src],      %[p_loop1_end],    3f         \n\t"
+    " nop                                                      \n\t"
+  "0:                                                          \n\t"
+    "lw             %[temp0],    0(%[src])                     \n\t"
+    "lw             %[temp1],    4(%[src])                     \n\t"
+    "lw             %[temp2],    8(%[src])                     \n\t"
+    "lw             %[temp3],    12(%[src])                    \n\t"
+    "ext            %[temp4],    %[temp0],          28,   4    \n\t"
+    "ext            %[temp5],    %[temp0],          12,   4    \n\t"
+    "ins            %[temp0],    %[temp4],          0,    4    \n\t"
+    "ext            %[temp4],    %[temp1],          28,   4    \n\t"
+    "ins            %[temp0],    %[temp5],          16,   4    \n\t"
+    "ext            %[temp5],    %[temp1],          12,   4    \n\t"
+    "ins            %[temp1],    %[temp4],          0,    4    \n\t"
+    "ext            %[temp4],    %[temp2],          28,   4    \n\t"
+    "ins            %[temp1],    %[temp5],          16,   4    \n\t"
+    "ext            %[temp5],    %[temp2],          12,   4    \n\t"
+    "ins            %[temp2],    %[temp4],          0,    4    \n\t"
+    "ext            %[temp4],    %[temp3],          28,   4    \n\t"
+    "ins            %[temp2],    %[temp5],          16,   4    \n\t"
+    "ext            %[temp5],    %[temp3],          12,   4    \n\t"
+    "ins            %[temp3],    %[temp4],          0,    4    \n\t"
+    "precr.qb.ph    %[temp1],    %[temp1],          %[temp0]   \n\t"
+    "ins            %[temp3],    %[temp5],          16,   4    \n\t"
+    "addiu          %[src],      %[src],            16         \n\t"
+    "precr.qb.ph    %[temp3],    %[temp3],          %[temp2]   \n\t"
+#ifdef WEBP_SWAP_16BIT_CSP
+    "usw            %[temp1],    0(%[dst])                     \n\t"
+    "usw            %[temp3],    4(%[dst])                     \n\t"
+#else
+    "wsbh           %[temp1],    %[temp1]                      \n\t"
+    "wsbh           %[temp3],    %[temp3]                      \n\t"
+    "usw            %[temp1],    0(%[dst])                     \n\t"
+    "usw            %[temp3],    4(%[dst])                     \n\t"
+#endif
+    "bne            %[src],      %[p_loop1_end],    0b         \n\t"
+    " addiu         %[dst],      %[dst],            8          \n\t"
+  "3:                                                          \n\t"
+    "beq            %[src],      %[p_loop2_end],    2f         \n\t"
+    " nop                                                      \n\t"
+  "1:                                                          \n\t"
+    "lw             %[temp0],    0(%[src])                     \n\t"
+    "ext            %[temp4],    %[temp0],          28,   4    \n\t"
+    "ext            %[temp5],    %[temp0],          12,   4    \n\t"
+    "ins            %[temp0],    %[temp4],          0,    4    \n\t"
+    "ins            %[temp0],    %[temp5],          16,   4    \n\t"
+    "addiu          %[src],      %[src],            4          \n\t"
+    "precr.qb.ph    %[temp0],    %[temp0],          %[temp0]   \n\t"
+#ifdef WEBP_SWAP_16BIT_CSP
+    "ush            %[temp0],    0(%[dst])                     \n\t"
+#else
+    "wsbh           %[temp0],    %[temp0]                      \n\t"
+    "ush            %[temp0],    0(%[dst])                     \n\t"
+#endif
+    "bne            %[src],      %[p_loop2_end],    1b         \n\t"
+    " addiu         %[dst],      %[dst],            2          \n\t"
+  "2:                                                          \n\t"
+    ".set           pop                                        \n\t"
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+      [dst]"+&r"(dst), [src]"+&r"(src)
+    : [p_loop1_end]"r"(p_loop1_end), [p_loop2_end]"r"(p_loop2_end)
+    : "memory"
+  );
+}
+
+static void ConvertBGRAToRGB565(const uint32_t* src,
+                                int num_pixels, uint8_t* dst) {
+  int temp0, temp1, temp2, temp3, temp4, temp5;
+  const uint32_t* const p_loop1_end = src + (num_pixels & ~3);
+  const uint32_t* const p_loop2_end = src + num_pixels;
+  __asm__ volatile (
+    ".set           push                                       \n\t"
+    ".set           noreorder                                  \n\t"
+    "beq            %[src],      %[p_loop1_end],    3f         \n\t"
+    " nop                                                      \n\t"
+  "0:                                                          \n\t"
+    "lw             %[temp0],    0(%[src])                     \n\t"
+    "lw             %[temp1],    4(%[src])                     \n\t"
+    "lw             %[temp2],    8(%[src])                     \n\t"
+    "lw             %[temp3],    12(%[src])                    \n\t"
+    "ext            %[temp4],    %[temp0],          8,    16   \n\t"
+    "ext            %[temp5],    %[temp0],          5,    11   \n\t"
+    "ext            %[temp0],    %[temp0],          3,    5    \n\t"
+    "ins            %[temp4],    %[temp5],          0,    11   \n\t"
+    "ext            %[temp5],    %[temp1],          5,    11   \n\t"
+    "ins            %[temp4],    %[temp0],          0,    5    \n\t"
+    "ext            %[temp0],    %[temp1],          8,    16   \n\t"
+    "ext            %[temp1],    %[temp1],          3,    5    \n\t"
+    "ins            %[temp0],    %[temp5],          0,    11   \n\t"
+    "ext            %[temp5],    %[temp2],          5,    11   \n\t"
+    "ins            %[temp0],    %[temp1],          0,    5    \n\t"
+    "ext            %[temp1],    %[temp2],          8,    16   \n\t"
+    "ext            %[temp2],    %[temp2],          3,    5    \n\t"
+    "ins            %[temp1],    %[temp5],          0,    11   \n\t"
+    "ext            %[temp5],    %[temp3],          5,    11   \n\t"
+    "ins            %[temp1],    %[temp2],          0,    5    \n\t"
+    "ext            %[temp2],    %[temp3],          8,    16   \n\t"
+    "ext            %[temp3],    %[temp3],          3,    5    \n\t"
+    "ins            %[temp2],    %[temp5],          0,    11   \n\t"
+    "append         %[temp0],    %[temp4],          16         \n\t"
+    "ins            %[temp2],    %[temp3],          0,    5    \n\t"
+    "addiu          %[src],      %[src],            16         \n\t"
+    "append         %[temp2],    %[temp1],          16         \n\t"
+#ifdef WEBP_SWAP_16BIT_CSP
+    "usw            %[temp0],    0(%[dst])                     \n\t"
+    "usw            %[temp2],    4(%[dst])                     \n\t"
+#else
+    "wsbh           %[temp0],    %[temp0]                      \n\t"
+    "wsbh           %[temp2],    %[temp2]                      \n\t"
+    "usw            %[temp0],    0(%[dst])                     \n\t"
+    "usw            %[temp2],    4(%[dst])                     \n\t"
+#endif
+    "bne            %[src],      %[p_loop1_end],    0b         \n\t"
+    " addiu         %[dst],      %[dst],            8          \n\t"
+  "3:                                                          \n\t"
+    "beq            %[src],      %[p_loop2_end],    2f         \n\t"
+    " nop                                                      \n\t"
+  "1:                                                          \n\t"
+    "lw             %[temp0],    0(%[src])                     \n\t"
+    "ext            %[temp4],    %[temp0],          8,    16   \n\t"
+    "ext            %[temp5],    %[temp0],          5,    11   \n\t"
+    "ext            %[temp0],    %[temp0],          3,    5    \n\t"
+    "ins            %[temp4],    %[temp5],          0,    11   \n\t"
+    "addiu          %[src],      %[src],            4          \n\t"
+    "ins            %[temp4],    %[temp0],          0,    5    \n\t"
+#ifdef WEBP_SWAP_16BIT_CSP
+    "ush            %[temp4],    0(%[dst])                     \n\t"
+#else
+    "wsbh           %[temp4],    %[temp4]                      \n\t"
+    "ush            %[temp4],    0(%[dst])                     \n\t"
+#endif
+    "bne            %[src],      %[p_loop2_end],    1b         \n\t"
+    " addiu         %[dst],      %[dst],            2          \n\t"
+  "2:                                                          \n\t"
+    ".set           pop                                        \n\t"
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
+      [dst]"+&r"(dst), [src]"+&r"(src)
+    : [p_loop1_end]"r"(p_loop1_end), [p_loop2_end]"r"(p_loop2_end)
+    : "memory"
+  );
+}
+
+static void ConvertBGRAToBGR(const uint32_t* src,
+                             int num_pixels, uint8_t* dst) {
+  int temp0, temp1, temp2, temp3;
+  const uint32_t* const p_loop1_end = src + (num_pixels & ~3);
+  const uint32_t* const p_loop2_end = src + num_pixels;
+  __asm__ volatile (
+    ".set       push                                         \n\t"
+    ".set       noreorder                                    \n\t"
+    "beq        %[src],      %[p_loop1_end],    3f           \n\t"
+    " nop                                                    \n\t"
+  "0:                                                        \n\t"
+    "lw         %[temp0],    0(%[src])                       \n\t"
+    "lw         %[temp1],    4(%[src])                       \n\t"
+    "lw         %[temp2],    8(%[src])                       \n\t"
+    "lw         %[temp3],    12(%[src])                      \n\t"
+    "ins        %[temp0],    %[temp1],          24,    8     \n\t"
+    "sra        %[temp1],    %[temp1],          8            \n\t"
+    "ins        %[temp1],    %[temp2],          16,    16    \n\t"
+    "sll        %[temp2],    %[temp2],          8            \n\t"
+    "balign     %[temp3],    %[temp2],          1            \n\t"
+    "addiu      %[src],      %[src],            16           \n\t"
+    "usw        %[temp0],    0(%[dst])                       \n\t"
+    "usw        %[temp1],    4(%[dst])                       \n\t"
+    "usw        %[temp3],    8(%[dst])                       \n\t"
+    "bne        %[src],      %[p_loop1_end],    0b           \n\t"
+    " addiu     %[dst],      %[dst],            12           \n\t"
+  "3:                                                        \n\t"
+    "beq        %[src],      %[p_loop2_end],    2f           \n\t"
+    " nop                                                    \n\t"
+  "1:                                                        \n\t"
+    "lw         %[temp0],    0(%[src])                       \n\t"
+    "addiu      %[src],      %[src],            4            \n\t"
+    "addiu      %[dst],      %[dst],            3            \n\t"
+    "ush        %[temp0],    -3(%[dst])                      \n\t"
+    "sra        %[temp0],    %[temp0],          16           \n\t"
+    "bne        %[src],      %[p_loop2_end],    1b           \n\t"
+    " sb        %[temp0],    -1(%[dst])                      \n\t"
+  "2:                                                        \n\t"
+    ".set       pop                                          \n\t"
+    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
+      [temp3]"=&r"(temp3), [dst]"+&r"(dst), [src]"+&r"(src)
+    : [p_loop1_end]"r"(p_loop1_end), [p_loop2_end]"r"(p_loop2_end)
+    : "memory"
+  );
+}
+
+#endif  // WEBP_USE_MIPS_DSP_R2
+
+//------------------------------------------------------------------------------
+
+extern void VP8LDspInitMIPSdspR2(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8LDspInitMIPSdspR2(void) {
+#if defined(WEBP_USE_MIPS_DSP_R2)
+  VP8LMapColor32b = MapARGB;
+  VP8LMapColor8b = MapAlpha;
+  VP8LPredictors[5] = Predictor5;
+  VP8LPredictors[6] = Predictor6;
+  VP8LPredictors[7] = Predictor7;
+  VP8LPredictors[8] = Predictor8;
+  VP8LPredictors[9] = Predictor9;
+  VP8LPredictors[10] = Predictor10;
+  VP8LPredictors[11] = Predictor11;
+  VP8LPredictors[12] = Predictor12;
+  VP8LPredictors[13] = Predictor13;
+  VP8LSubtractGreenFromBlueAndRed = SubtractGreenFromBlueAndRed;
+  VP8LTransformColor = TransformColor;
+  VP8LCollectColorBlueTransforms = CollectColorBlueTransforms;
+  VP8LCollectColorRedTransforms = CollectColorRedTransforms;
+  VP8LAddGreenToBlueAndRed = AddGreenToBlueAndRed;
+  VP8LTransformColorInverse = TransformColorInverse;
+  VP8LConvertBGRAToRGB = ConvertBGRAToRGB;
+  VP8LConvertBGRAToRGBA = ConvertBGRAToRGBA;
+  VP8LConvertBGRAToRGBA4444 = ConvertBGRAToRGBA4444;
+  VP8LConvertBGRAToRGB565 = ConvertBGRAToRGB565;
+  VP8LConvertBGRAToBGR = ConvertBGRAToBGR;
+#endif  // WEBP_USE_MIPS_DSP_R2
+}
+
+//------------------------------------------------------------------------------
diff --git a/Source/LibWebP/src/dsp/dsp.lossless_neon.c b/Source/LibWebP/src/dsp/dsp.lossless_neon.c
new file mode 100644
index 0000000..298cd43
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.lossless_neon.c
@@ -0,0 +1,357 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// NEON variant of methods for lossless decoder
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include "./dsp.h"
+
+#if defined(WEBP_USE_NEON)
+
+#include <arm_neon.h>
+
+#include "./lossless.h"
+#include "./neon.h"
+
+//------------------------------------------------------------------------------
+// Colorspace conversion functions
+
+#if !defined(WORK_AROUND_GCC)
+// gcc 4.6.0 had some trouble (NDK-r9) with this code. We only use it for
+// gcc-4.8.x at least.
+static void ConvertBGRAToRGBA(const uint32_t* src,
+                              int num_pixels, uint8_t* dst) {
+  const uint32_t* const end = src + (num_pixels & ~15);
+  for (; src < end; src += 16) {
+    uint8x16x4_t pixel = vld4q_u8((uint8_t*)src);
+    // swap B and R. (VSWP d0,d2 has no intrinsics equivalent!)
+    const uint8x16_t tmp = pixel.val[0];
+    pixel.val[0] = pixel.val[2];
+    pixel.val[2] = tmp;
+    vst4q_u8(dst, pixel);
+    dst += 64;
+  }
+  VP8LConvertBGRAToRGBA_C(src, num_pixels & 15, dst);  // left-overs
+}
+
+static void ConvertBGRAToBGR(const uint32_t* src,
+                             int num_pixels, uint8_t* dst) {
+  const uint32_t* const end = src + (num_pixels & ~15);
+  for (; src < end; src += 16) {
+    const uint8x16x4_t pixel = vld4q_u8((uint8_t*)src);
+    const uint8x16x3_t tmp = { { pixel.val[0], pixel.val[1], pixel.val[2] } };
+    vst3q_u8(dst, tmp);
+    dst += 48;
+  }
+  VP8LConvertBGRAToBGR_C(src, num_pixels & 15, dst);  // left-overs
+}
+
+static void ConvertBGRAToRGB(const uint32_t* src,
+                             int num_pixels, uint8_t* dst) {
+  const uint32_t* const end = src + (num_pixels & ~15);
+  for (; src < end; src += 16) {
+    const uint8x16x4_t pixel = vld4q_u8((uint8_t*)src);
+    const uint8x16x3_t tmp = { { pixel.val[2], pixel.val[1], pixel.val[0] } };
+    vst3q_u8(dst, tmp);
+    dst += 48;
+  }
+  VP8LConvertBGRAToRGB_C(src, num_pixels & 15, dst);  // left-overs
+}
+
+#else  // WORK_AROUND_GCC
+
+// gcc-4.6.0 fallback
+
+static const uint8_t kRGBAShuffle[8] = { 2, 1, 0, 3, 6, 5, 4, 7 };
+
+static void ConvertBGRAToRGBA(const uint32_t* src,
+                              int num_pixels, uint8_t* dst) {
+  const uint32_t* const end = src + (num_pixels & ~1);
+  const uint8x8_t shuffle = vld1_u8(kRGBAShuffle);
+  for (; src < end; src += 2) {
+    const uint8x8_t pixels = vld1_u8((uint8_t*)src);
+    vst1_u8(dst, vtbl1_u8(pixels, shuffle));
+    dst += 8;
+  }
+  VP8LConvertBGRAToRGBA_C(src, num_pixels & 1, dst);  // left-overs
+}
+
+static const uint8_t kBGRShuffle[3][8] = {
+  {  0,  1,  2,  4,  5,  6,  8,  9 },
+  { 10, 12, 13, 14, 16, 17, 18, 20 },
+  { 21, 22, 24, 25, 26, 28, 29, 30 }
+};
+
+static void ConvertBGRAToBGR(const uint32_t* src,
+                             int num_pixels, uint8_t* dst) {
+  const uint32_t* const end = src + (num_pixels & ~7);
+  const uint8x8_t shuffle0 = vld1_u8(kBGRShuffle[0]);
+  const uint8x8_t shuffle1 = vld1_u8(kBGRShuffle[1]);
+  const uint8x8_t shuffle2 = vld1_u8(kBGRShuffle[2]);
+  for (; src < end; src += 8) {
+    uint8x8x4_t pixels;
+    INIT_VECTOR4(pixels,
+                 vld1_u8((const uint8_t*)(src + 0)),
+                 vld1_u8((const uint8_t*)(src + 2)),
+                 vld1_u8((const uint8_t*)(src + 4)),
+                 vld1_u8((const uint8_t*)(src + 6)));
+    vst1_u8(dst +  0, vtbl4_u8(pixels, shuffle0));
+    vst1_u8(dst +  8, vtbl4_u8(pixels, shuffle1));
+    vst1_u8(dst + 16, vtbl4_u8(pixels, shuffle2));
+    dst += 8 * 3;
+  }
+  VP8LConvertBGRAToBGR_C(src, num_pixels & 7, dst);  // left-overs
+}
+
+static const uint8_t kRGBShuffle[3][8] = {
+  {  2,  1,  0,  6,  5,  4, 10,  9 },
+  {  8, 14, 13, 12, 18, 17, 16, 22 },
+  { 21, 20, 26, 25, 24, 30, 29, 28 }
+};
+
+static void ConvertBGRAToRGB(const uint32_t* src,
+                             int num_pixels, uint8_t* dst) {
+  const uint32_t* const end = src + (num_pixels & ~7);
+  const uint8x8_t shuffle0 = vld1_u8(kRGBShuffle[0]);
+  const uint8x8_t shuffle1 = vld1_u8(kRGBShuffle[1]);
+  const uint8x8_t shuffle2 = vld1_u8(kRGBShuffle[2]);
+  for (; src < end; src += 8) {
+    uint8x8x4_t pixels;
+    INIT_VECTOR4(pixels,
+                 vld1_u8((const uint8_t*)(src + 0)),
+                 vld1_u8((const uint8_t*)(src + 2)),
+                 vld1_u8((const uint8_t*)(src + 4)),
+                 vld1_u8((const uint8_t*)(src + 6)));
+    vst1_u8(dst +  0, vtbl4_u8(pixels, shuffle0));
+    vst1_u8(dst +  8, vtbl4_u8(pixels, shuffle1));
+    vst1_u8(dst + 16, vtbl4_u8(pixels, shuffle2));
+    dst += 8 * 3;
+  }
+  VP8LConvertBGRAToRGB_C(src, num_pixels & 7, dst);  // left-overs
+}
+
+#endif   // !WORK_AROUND_GCC
+
+//------------------------------------------------------------------------------
+
+#ifdef WEBP_USE_INTRINSICS
+
+static WEBP_INLINE uint32_t Average2(const uint32_t* const a,
+                                     const uint32_t* const b) {
+  const uint8x8_t a0 = vreinterpret_u8_u64(vcreate_u64(*a));
+  const uint8x8_t b0 = vreinterpret_u8_u64(vcreate_u64(*b));
+  const uint8x8_t avg = vhadd_u8(a0, b0);
+  return vget_lane_u32(vreinterpret_u32_u8(avg), 0);
+}
+
+static WEBP_INLINE uint32_t Average3(const uint32_t* const a,
+                                     const uint32_t* const b,
+                                     const uint32_t* const c) {
+  const uint8x8_t a0 = vreinterpret_u8_u64(vcreate_u64(*a));
+  const uint8x8_t b0 = vreinterpret_u8_u64(vcreate_u64(*b));
+  const uint8x8_t c0 = vreinterpret_u8_u64(vcreate_u64(*c));
+  const uint8x8_t avg1 = vhadd_u8(a0, c0);
+  const uint8x8_t avg2 = vhadd_u8(avg1, b0);
+  return vget_lane_u32(vreinterpret_u32_u8(avg2), 0);
+}
+
+static WEBP_INLINE uint32_t Average4(const uint32_t* const a,
+                                     const uint32_t* const b,
+                                     const uint32_t* const c,
+                                     const uint32_t* const d) {
+  const uint8x8_t a0 = vreinterpret_u8_u64(vcreate_u64(*a));
+  const uint8x8_t b0 = vreinterpret_u8_u64(vcreate_u64(*b));
+  const uint8x8_t c0 = vreinterpret_u8_u64(vcreate_u64(*c));
+  const uint8x8_t d0 = vreinterpret_u8_u64(vcreate_u64(*d));
+  const uint8x8_t avg1 = vhadd_u8(a0, b0);
+  const uint8x8_t avg2 = vhadd_u8(c0, d0);
+  const uint8x8_t avg3 = vhadd_u8(avg1, avg2);
+  return vget_lane_u32(vreinterpret_u32_u8(avg3), 0);
+}
+
+static uint32_t Predictor5(uint32_t left, const uint32_t* const top) {
+  return Average3(&left, top + 0, top + 1);
+}
+
+static uint32_t Predictor6(uint32_t left, const uint32_t* const top) {
+  return Average2(&left, top - 1);
+}
+
+static uint32_t Predictor7(uint32_t left, const uint32_t* const top) {
+  return Average2(&left, top + 0);
+}
+
+static uint32_t Predictor8(uint32_t left, const uint32_t* const top) {
+  (void)left;
+  return Average2(top - 1, top + 0);
+}
+
+static uint32_t Predictor9(uint32_t left, const uint32_t* const top) {
+  (void)left;
+  return Average2(top + 0, top + 1);
+}
+
+static uint32_t Predictor10(uint32_t left, const uint32_t* const top) {
+  return Average4(&left, top - 1, top + 0, top + 1);
+}
+
+//------------------------------------------------------------------------------
+
+static WEBP_INLINE uint32_t Select(const uint32_t* const c0,
+                                   const uint32_t* const c1,
+                                   const uint32_t* const c2) {
+  const uint8x8_t p0 = vreinterpret_u8_u64(vcreate_u64(*c0));
+  const uint8x8_t p1 = vreinterpret_u8_u64(vcreate_u64(*c1));
+  const uint8x8_t p2 = vreinterpret_u8_u64(vcreate_u64(*c2));
+  const uint8x8_t bc = vabd_u8(p1, p2);   // |b-c|
+  const uint8x8_t ac = vabd_u8(p0, p2);   // |a-c|
+  const int16x4_t sum_bc = vreinterpret_s16_u16(vpaddl_u8(bc));
+  const int16x4_t sum_ac = vreinterpret_s16_u16(vpaddl_u8(ac));
+  const int32x2_t diff = vpaddl_s16(vsub_s16(sum_bc, sum_ac));
+  const int32_t pa_minus_pb = vget_lane_s32(diff, 0);
+  return (pa_minus_pb <= 0) ? *c0 : *c1;
+}
+
+static uint32_t Predictor11(uint32_t left, const uint32_t* const top) {
+  return Select(top + 0, &left, top - 1);
+}
+
+static WEBP_INLINE uint32_t ClampedAddSubtractFull(const uint32_t* const c0,
+                                                   const uint32_t* const c1,
+                                                   const uint32_t* const c2) {
+  const uint8x8_t p0 = vreinterpret_u8_u64(vcreate_u64(*c0));
+  const uint8x8_t p1 = vreinterpret_u8_u64(vcreate_u64(*c1));
+  const uint8x8_t p2 = vreinterpret_u8_u64(vcreate_u64(*c2));
+  const uint16x8_t sum0 = vaddl_u8(p0, p1);                // add and widen
+  const uint16x8_t sum1 = vqsubq_u16(sum0, vmovl_u8(p2));  // widen and subtract
+  const uint8x8_t out = vqmovn_u16(sum1);                  // narrow and clamp
+  return vget_lane_u32(vreinterpret_u32_u8(out), 0);
+}
+
+static uint32_t Predictor12(uint32_t left, const uint32_t* const top) {
+  return ClampedAddSubtractFull(&left, top + 0, top - 1);
+}
+
+static WEBP_INLINE uint32_t ClampedAddSubtractHalf(const uint32_t* const c0,
+                                                   const uint32_t* const c1,
+                                                   const uint32_t* const c2) {
+  const uint8x8_t p0 = vreinterpret_u8_u64(vcreate_u64(*c0));
+  const uint8x8_t p1 = vreinterpret_u8_u64(vcreate_u64(*c1));
+  const uint8x8_t p2 = vreinterpret_u8_u64(vcreate_u64(*c2));
+  const uint8x8_t avg = vhadd_u8(p0, p1);                  // Average(c0,c1)
+  const uint8x8_t ab = vshr_n_u8(vqsub_u8(avg, p2), 1);    // (a-b)>>1 saturated
+  const uint8x8_t ba = vshr_n_u8(vqsub_u8(p2, avg), 1);    // (b-a)>>1 saturated
+  const uint8x8_t out = vqsub_u8(vqadd_u8(avg, ab), ba);
+  return vget_lane_u32(vreinterpret_u32_u8(out), 0);
+}
+
+static uint32_t Predictor13(uint32_t left, const uint32_t* const top) {
+  return ClampedAddSubtractHalf(&left, top + 0, top - 1);
+}
+
+//------------------------------------------------------------------------------
+// Subtract-Green Transform
+
+// vtbl?_u8 are marked unavailable for iOS arm64 with Xcode < 6.3, use
+// non-standard versions there.
+#if defined(__APPLE__) && defined(__aarch64__) && \
+    defined(__apple_build_version__) && (__apple_build_version__< 6020037)
+#define USE_VTBLQ
+#endif
+
+#ifdef USE_VTBLQ
+// 255 = byte will be zeroed
+static const uint8_t kGreenShuffle[16] = {
+  1, 255, 1, 255, 5, 255, 5, 255, 9, 255, 9, 255, 13, 255, 13, 255
+};
+
+static WEBP_INLINE uint8x16_t DoGreenShuffle(const uint8x16_t argb,
+                                             const uint8x16_t shuffle) {
+  return vcombine_u8(vtbl1q_u8(argb, vget_low_u8(shuffle)),
+                     vtbl1q_u8(argb, vget_high_u8(shuffle)));
+}
+#else  // !USE_VTBLQ
+// 255 = byte will be zeroed
+static const uint8_t kGreenShuffle[8] = { 1, 255, 1, 255, 5, 255, 5, 255  };
+
+static WEBP_INLINE uint8x16_t DoGreenShuffle(const uint8x16_t argb,
+                                             const uint8x8_t shuffle) {
+  return vcombine_u8(vtbl1_u8(vget_low_u8(argb), shuffle),
+                     vtbl1_u8(vget_high_u8(argb), shuffle));
+}
+#endif  // USE_VTBLQ
+
+static void SubtractGreenFromBlueAndRed(uint32_t* argb_data, int num_pixels) {
+  const uint32_t* const end = argb_data + (num_pixels & ~3);
+#ifdef USE_VTBLQ
+  const uint8x16_t shuffle = vld1q_u8(kGreenShuffle);
+#else
+  const uint8x8_t shuffle = vld1_u8(kGreenShuffle);
+#endif
+  for (; argb_data < end; argb_data += 4) {
+    const uint8x16_t argb = vld1q_u8((uint8_t*)argb_data);
+    const uint8x16_t greens = DoGreenShuffle(argb, shuffle);
+    vst1q_u8((uint8_t*)argb_data, vsubq_u8(argb, greens));
+  }
+  // fallthrough and finish off with plain-C
+  VP8LSubtractGreenFromBlueAndRed_C(argb_data, num_pixels & 3);
+}
+
+static void AddGreenToBlueAndRed(uint32_t* argb_data, int num_pixels) {
+  const uint32_t* const end = argb_data + (num_pixels & ~3);
+#ifdef USE_VTBLQ
+  const uint8x16_t shuffle = vld1q_u8(kGreenShuffle);
+#else
+  const uint8x8_t shuffle = vld1_u8(kGreenShuffle);
+#endif
+  for (; argb_data < end; argb_data += 4) {
+    const uint8x16_t argb = vld1q_u8((uint8_t*)argb_data);
+    const uint8x16_t greens = DoGreenShuffle(argb, shuffle);
+    vst1q_u8((uint8_t*)argb_data, vaddq_u8(argb, greens));
+  }
+  // fallthrough and finish off with plain-C
+  VP8LAddGreenToBlueAndRed_C(argb_data, num_pixels & 3);
+}
+
+#undef USE_VTBLQ
+
+#endif   // WEBP_USE_INTRINSICS
+
+#endif   // WEBP_USE_NEON
+
+//------------------------------------------------------------------------------
+
+extern void VP8LDspInitNEON(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8LDspInitNEON(void) {
+#if defined(WEBP_USE_NEON)
+  VP8LConvertBGRAToRGBA = ConvertBGRAToRGBA;
+  VP8LConvertBGRAToBGR = ConvertBGRAToBGR;
+  VP8LConvertBGRAToRGB = ConvertBGRAToRGB;
+
+#ifdef WEBP_USE_INTRINSICS
+  VP8LPredictors[5] = Predictor5;
+  VP8LPredictors[6] = Predictor6;
+  VP8LPredictors[7] = Predictor7;
+  VP8LPredictors[8] = Predictor8;
+  VP8LPredictors[9] = Predictor9;
+  VP8LPredictors[10] = Predictor10;
+  VP8LPredictors[11] = Predictor11;
+  VP8LPredictors[12] = Predictor12;
+  VP8LPredictors[13] = Predictor13;
+
+  VP8LSubtractGreenFromBlueAndRed = SubtractGreenFromBlueAndRed;
+  VP8LAddGreenToBlueAndRed = AddGreenToBlueAndRed;
+#endif
+
+#endif   // WEBP_USE_NEON
+}
+
+//------------------------------------------------------------------------------
diff --git a/Source/LibWebP/src/dsp/dsp.lossless_sse2.c b/Source/LibWebP/src/dsp/dsp.lossless_sse2.c
new file mode 100644
index 0000000..5e265e2
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.lossless_sse2.c
@@ -0,0 +1,535 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// SSE2 variant of methods for lossless decoder
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include "./dsp.h"
+
+#include <assert.h>
+
+#if defined(WEBP_USE_SSE2)
+#include <emmintrin.h>
+#include "./lossless.h"
+
+//------------------------------------------------------------------------------
+// Predictor Transform
+
+static WEBP_INLINE uint32_t ClampedAddSubtractFull(uint32_t c0, uint32_t c1,
+                                                   uint32_t c2) {
+  const __m128i zero = _mm_setzero_si128();
+  const __m128i C0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(c0), zero);
+  const __m128i C1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(c1), zero);
+  const __m128i C2 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(c2), zero);
+  const __m128i V1 = _mm_add_epi16(C0, C1);
+  const __m128i V2 = _mm_sub_epi16(V1, C2);
+  const __m128i b = _mm_packus_epi16(V2, V2);
+  const uint32_t output = _mm_cvtsi128_si32(b);
+  return output;
+}
+
+static WEBP_INLINE uint32_t ClampedAddSubtractHalf(uint32_t c0, uint32_t c1,
+                                                   uint32_t c2) {
+  const __m128i zero = _mm_setzero_si128();
+  const __m128i C0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(c0), zero);
+  const __m128i C1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(c1), zero);
+  const __m128i B0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(c2), zero);
+  const __m128i avg = _mm_add_epi16(C1, C0);
+  const __m128i A0 = _mm_srli_epi16(avg, 1);
+  const __m128i A1 = _mm_sub_epi16(A0, B0);
+  const __m128i BgtA = _mm_cmpgt_epi16(B0, A0);
+  const __m128i A2 = _mm_sub_epi16(A1, BgtA);
+  const __m128i A3 = _mm_srai_epi16(A2, 1);
+  const __m128i A4 = _mm_add_epi16(A0, A3);
+  const __m128i A5 = _mm_packus_epi16(A4, A4);
+  const uint32_t output = _mm_cvtsi128_si32(A5);
+  return output;
+}
+
+static WEBP_INLINE uint32_t Select(uint32_t a, uint32_t b, uint32_t c) {
+  int pa_minus_pb;
+  const __m128i zero = _mm_setzero_si128();
+  const __m128i A0 = _mm_cvtsi32_si128(a);
+  const __m128i B0 = _mm_cvtsi32_si128(b);
+  const __m128i C0 = _mm_cvtsi32_si128(c);
+  const __m128i AC0 = _mm_subs_epu8(A0, C0);
+  const __m128i CA0 = _mm_subs_epu8(C0, A0);
+  const __m128i BC0 = _mm_subs_epu8(B0, C0);
+  const __m128i CB0 = _mm_subs_epu8(C0, B0);
+  const __m128i AC = _mm_or_si128(AC0, CA0);
+  const __m128i BC = _mm_or_si128(BC0, CB0);
+  const __m128i pa = _mm_unpacklo_epi8(AC, zero);  // |a - c|
+  const __m128i pb = _mm_unpacklo_epi8(BC, zero);  // |b - c|
+  const __m128i diff = _mm_sub_epi16(pb, pa);
+  {
+    int16_t out[8];
+    _mm_storeu_si128((__m128i*)out, diff);
+    pa_minus_pb = out[0] + out[1] + out[2] + out[3];
+  }
+  return (pa_minus_pb <= 0) ? a : b;
+}
+
+static WEBP_INLINE __m128i Average2_128i(uint32_t a0, uint32_t a1) {
+  const __m128i zero = _mm_setzero_si128();
+  const __m128i A0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(a0), zero);
+  const __m128i A1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(a1), zero);
+  const __m128i sum = _mm_add_epi16(A1, A0);
+  const __m128i avg = _mm_srli_epi16(sum, 1);
+  return avg;
+}
+
+static WEBP_INLINE uint32_t Average2(uint32_t a0, uint32_t a1) {
+  const __m128i avg = Average2_128i(a0, a1);
+  const __m128i A2 = _mm_packus_epi16(avg, avg);
+  const uint32_t output = _mm_cvtsi128_si32(A2);
+  return output;
+}
+
+static WEBP_INLINE uint32_t Average3(uint32_t a0, uint32_t a1, uint32_t a2) {
+  const __m128i zero = _mm_setzero_si128();
+  const __m128i avg1 = Average2_128i(a0, a2);
+  const __m128i A1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(a1), zero);
+  const __m128i sum = _mm_add_epi16(avg1, A1);
+  const __m128i avg2 = _mm_srli_epi16(sum, 1);
+  const __m128i A2 = _mm_packus_epi16(avg2, avg2);
+  const uint32_t output = _mm_cvtsi128_si32(A2);
+  return output;
+}
+
+static WEBP_INLINE uint32_t Average4(uint32_t a0, uint32_t a1,
+                                     uint32_t a2, uint32_t a3) {
+  const __m128i avg1 = Average2_128i(a0, a1);
+  const __m128i avg2 = Average2_128i(a2, a3);
+  const __m128i sum = _mm_add_epi16(avg2, avg1);
+  const __m128i avg3 = _mm_srli_epi16(sum, 1);
+  const __m128i A0 = _mm_packus_epi16(avg3, avg3);
+  const uint32_t output = _mm_cvtsi128_si32(A0);
+  return output;
+}
+
+static uint32_t Predictor5(uint32_t left, const uint32_t* const top) {
+  const uint32_t pred = Average3(left, top[0], top[1]);
+  return pred;
+}
+static uint32_t Predictor6(uint32_t left, const uint32_t* const top) {
+  const uint32_t pred = Average2(left, top[-1]);
+  return pred;
+}
+static uint32_t Predictor7(uint32_t left, const uint32_t* const top) {
+  const uint32_t pred = Average2(left, top[0]);
+  return pred;
+}
+static uint32_t Predictor8(uint32_t left, const uint32_t* const top) {
+  const uint32_t pred = Average2(top[-1], top[0]);
+  (void)left;
+  return pred;
+}
+static uint32_t Predictor9(uint32_t left, const uint32_t* const top) {
+  const uint32_t pred = Average2(top[0], top[1]);
+  (void)left;
+  return pred;
+}
+static uint32_t Predictor10(uint32_t left, const uint32_t* const top) {
+  const uint32_t pred = Average4(left, top[-1], top[0], top[1]);
+  return pred;
+}
+static uint32_t Predictor11(uint32_t left, const uint32_t* const top) {
+  const uint32_t pred = Select(top[0], left, top[-1]);
+  return pred;
+}
+static uint32_t Predictor12(uint32_t left, const uint32_t* const top) {
+  const uint32_t pred = ClampedAddSubtractFull(left, top[0], top[-1]);
+  return pred;
+}
+static uint32_t Predictor13(uint32_t left, const uint32_t* const top) {
+  const uint32_t pred = ClampedAddSubtractHalf(left, top[0], top[-1]);
+  return pred;
+}
+
+//------------------------------------------------------------------------------
+// Subtract-Green Transform
+
+static void SubtractGreenFromBlueAndRed(uint32_t* argb_data, int num_pixels) {
+  const __m128i mask = _mm_set1_epi32(0x0000ff00);
+  int i;
+  for (i = 0; i + 4 <= num_pixels; i += 4) {
+    const __m128i in = _mm_loadu_si128((__m128i*)&argb_data[i]);
+    const __m128i in_00g0 = _mm_and_si128(in, mask);     // 00g0|00g0|...
+    const __m128i in_0g00 = _mm_slli_epi32(in_00g0, 8);  // 0g00|0g00|...
+    const __m128i in_000g = _mm_srli_epi32(in_00g0, 8);  // 000g|000g|...
+    const __m128i in_0g0g = _mm_or_si128(in_0g00, in_000g);
+    const __m128i out = _mm_sub_epi8(in, in_0g0g);
+    _mm_storeu_si128((__m128i*)&argb_data[i], out);
+  }
+  // fallthrough and finish off with plain-C
+  VP8LSubtractGreenFromBlueAndRed_C(argb_data + i, num_pixels - i);
+}
+
+static void AddGreenToBlueAndRed(uint32_t* argb_data, int num_pixels) {
+  const __m128i mask = _mm_set1_epi32(0x0000ff00);
+  int i;
+  for (i = 0; i + 4 <= num_pixels; i += 4) {
+    const __m128i in = _mm_loadu_si128((__m128i*)&argb_data[i]);
+    const __m128i in_00g0 = _mm_and_si128(in, mask);     // 00g0|00g0|...
+    const __m128i in_0g00 = _mm_slli_epi32(in_00g0, 8);  // 0g00|0g00|...
+    const __m128i in_000g = _mm_srli_epi32(in_00g0, 8);  // 000g|000g|...
+    const __m128i in_0g0g = _mm_or_si128(in_0g00, in_000g);
+    const __m128i out = _mm_add_epi8(in, in_0g0g);
+    _mm_storeu_si128((__m128i*)&argb_data[i], out);
+  }
+  // fallthrough and finish off with plain-C
+  VP8LAddGreenToBlueAndRed_C(argb_data + i, num_pixels - i);
+}
+
+//------------------------------------------------------------------------------
+// Color Transform
+
+static WEBP_INLINE __m128i ColorTransformDelta(__m128i color_pred,
+                                               __m128i color) {
+  // We simulate signed 8-bit multiplication as:
+  // * Left shift the two (8-bit) numbers by 8 bits,
+  // * Perform a 16-bit signed multiplication and retain the higher 16-bits.
+  const __m128i color_pred_shifted = _mm_slli_epi32(color_pred, 8);
+  const __m128i color_shifted = _mm_slli_epi32(color, 8);
+  // Note: This performs multiplication on 8 packed 16-bit numbers, 4 of which
+  // happen to be zeroes.
+  const __m128i signed_mult =
+      _mm_mulhi_epi16(color_pred_shifted, color_shifted);
+  return _mm_srli_epi32(signed_mult, 5);
+}
+
+static WEBP_INLINE void TransformColor(const VP8LMultipliers* const m,
+                                       uint32_t* argb_data,
+                                       int num_pixels) {
+  const __m128i g_to_r = _mm_set1_epi32(m->green_to_red_);       // multipliers
+  const __m128i g_to_b = _mm_set1_epi32(m->green_to_blue_);
+  const __m128i r_to_b = _mm_set1_epi32(m->red_to_blue_);
+
+  int i;
+
+  for (i = 0; i + 4 <= num_pixels; i += 4) {
+    const __m128i in = _mm_loadu_si128((__m128i*)&argb_data[i]);
+    const __m128i alpha_green_mask = _mm_set1_epi32(0xff00ff00);  // masks
+    const __m128i red_mask = _mm_set1_epi32(0x00ff0000);
+    const __m128i green_mask = _mm_set1_epi32(0x0000ff00);
+    const __m128i lower_8bit_mask  = _mm_set1_epi32(0x000000ff);
+    const __m128i ag = _mm_and_si128(in, alpha_green_mask);      // alpha, green
+    const __m128i r = _mm_srli_epi32(_mm_and_si128(in, red_mask), 16);
+    const __m128i g = _mm_srli_epi32(_mm_and_si128(in, green_mask), 8);
+    const __m128i b = in;
+
+    const __m128i r_delta = ColorTransformDelta(g_to_r, g);      // red
+    const __m128i r_new =
+        _mm_and_si128(_mm_sub_epi32(r, r_delta), lower_8bit_mask);
+    const __m128i r_new_shifted = _mm_slli_epi32(r_new, 16);
+
+    const __m128i b_delta_1 = ColorTransformDelta(g_to_b, g);    // blue
+    const __m128i b_delta_2 = ColorTransformDelta(r_to_b, r);
+    const __m128i b_delta = _mm_add_epi32(b_delta_1, b_delta_2);
+    const __m128i b_new =
+        _mm_and_si128(_mm_sub_epi32(b, b_delta), lower_8bit_mask);
+
+    const __m128i out = _mm_or_si128(_mm_or_si128(ag, r_new_shifted), b_new);
+    _mm_storeu_si128((__m128i*)&argb_data[i], out);
+  }
+
+  // Fall-back to C-version for left-overs.
+  VP8LTransformColor_C(m, argb_data + i, num_pixels - i);
+}
+
+static WEBP_INLINE void TransformColorInverse(const VP8LMultipliers* const m,
+                                              uint32_t* argb_data,
+                                              int num_pixels) {
+  const __m128i g_to_r = _mm_set1_epi32(m->green_to_red_);       // multipliers
+  const __m128i g_to_b = _mm_set1_epi32(m->green_to_blue_);
+  const __m128i r_to_b = _mm_set1_epi32(m->red_to_blue_);
+
+  int i;
+
+  for (i = 0; i + 4 <= num_pixels; i += 4) {
+    const __m128i in = _mm_loadu_si128((__m128i*)&argb_data[i]);
+    const __m128i alpha_green_mask = _mm_set1_epi32(0xff00ff00);  // masks
+    const __m128i red_mask = _mm_set1_epi32(0x00ff0000);
+    const __m128i green_mask = _mm_set1_epi32(0x0000ff00);
+    const __m128i lower_8bit_mask  = _mm_set1_epi32(0x000000ff);
+    const __m128i ag = _mm_and_si128(in, alpha_green_mask);      // alpha, green
+    const __m128i r = _mm_srli_epi32(_mm_and_si128(in, red_mask), 16);
+    const __m128i g = _mm_srli_epi32(_mm_and_si128(in, green_mask), 8);
+    const __m128i b = in;
+
+    const __m128i r_delta = ColorTransformDelta(g_to_r, g);      // red
+    const __m128i r_new =
+        _mm_and_si128(_mm_add_epi32(r, r_delta), lower_8bit_mask);
+    const __m128i r_new_shifted = _mm_slli_epi32(r_new, 16);
+
+    const __m128i b_delta_1 = ColorTransformDelta(g_to_b, g);    // blue
+    const __m128i b_delta_2 = ColorTransformDelta(r_to_b, r_new);
+    const __m128i b_delta = _mm_add_epi32(b_delta_1, b_delta_2);
+    const __m128i b_new =
+        _mm_and_si128(_mm_add_epi32(b, b_delta), lower_8bit_mask);
+
+    const __m128i out = _mm_or_si128(_mm_or_si128(ag, r_new_shifted), b_new);
+    _mm_storeu_si128((__m128i*)&argb_data[i], out);
+  }
+
+  // Fall-back to C-version for left-overs.
+  VP8LTransformColorInverse_C(m, argb_data + i, num_pixels - i);
+}
+
+//------------------------------------------------------------------------------
+// Color-space conversion functions
+
+static void ConvertBGRAToRGBA(const uint32_t* src,
+                              int num_pixels, uint8_t* dst) {
+  const __m128i* in = (const __m128i*)src;
+  __m128i* out = (__m128i*)dst;
+  while (num_pixels >= 8) {
+    const __m128i bgra0 = _mm_loadu_si128(in++);     // bgra0|bgra1|bgra2|bgra3
+    const __m128i bgra4 = _mm_loadu_si128(in++);     // bgra4|bgra5|bgra6|bgra7
+    const __m128i v0l = _mm_unpacklo_epi8(bgra0, bgra4);  // b0b4g0g4r0r4a0a4...
+    const __m128i v0h = _mm_unpackhi_epi8(bgra0, bgra4);  // b2b6g2g6r2r6a2a6...
+    const __m128i v1l = _mm_unpacklo_epi8(v0l, v0h);   // b0b2b4b6g0g2g4g6...
+    const __m128i v1h = _mm_unpackhi_epi8(v0l, v0h);   // b1b3b5b7g1g3g5g7...
+    const __m128i v2l = _mm_unpacklo_epi8(v1l, v1h);   // b0...b7 | g0...g7
+    const __m128i v2h = _mm_unpackhi_epi8(v1l, v1h);   // r0...r7 | a0...a7
+    const __m128i ga0 = _mm_unpackhi_epi64(v2l, v2h);  // g0...g7 | a0...a7
+    const __m128i rb0 = _mm_unpacklo_epi64(v2h, v2l);  // r0...r7 | b0...b7
+    const __m128i rg0 = _mm_unpacklo_epi8(rb0, ga0);   // r0g0r1g1 ... r6g6r7g7
+    const __m128i ba0 = _mm_unpackhi_epi8(rb0, ga0);   // b0a0b1a1 ... b6a6b7a7
+    const __m128i rgba0 = _mm_unpacklo_epi16(rg0, ba0);  // rgba0|rgba1...
+    const __m128i rgba4 = _mm_unpackhi_epi16(rg0, ba0);  // rgba4|rgba5...
+    _mm_storeu_si128(out++, rgba0);
+    _mm_storeu_si128(out++, rgba4);
+    num_pixels -= 8;
+  }
+  // left-overs
+  VP8LConvertBGRAToRGBA_C((const uint32_t*)in, num_pixels, (uint8_t*)out);
+}
+
+static void ConvertBGRAToRGBA4444(const uint32_t* src,
+                                  int num_pixels, uint8_t* dst) {
+  const __m128i mask_0x0f = _mm_set1_epi8(0x0f);
+  const __m128i mask_0xf0 = _mm_set1_epi8(0xf0);
+  const __m128i* in = (const __m128i*)src;
+  __m128i* out = (__m128i*)dst;
+  while (num_pixels >= 8) {
+    const __m128i bgra0 = _mm_loadu_si128(in++);     // bgra0|bgra1|bgra2|bgra3
+    const __m128i bgra4 = _mm_loadu_si128(in++);     // bgra4|bgra5|bgra6|bgra7
+    const __m128i v0l = _mm_unpacklo_epi8(bgra0, bgra4);  // b0b4g0g4r0r4a0a4...
+    const __m128i v0h = _mm_unpackhi_epi8(bgra0, bgra4);  // b2b6g2g6r2r6a2a6...
+    const __m128i v1l = _mm_unpacklo_epi8(v0l, v0h);    // b0b2b4b6g0g2g4g6...
+    const __m128i v1h = _mm_unpackhi_epi8(v0l, v0h);    // b1b3b5b7g1g3g5g7...
+    const __m128i v2l = _mm_unpacklo_epi8(v1l, v1h);    // b0...b7 | g0...g7
+    const __m128i v2h = _mm_unpackhi_epi8(v1l, v1h);    // r0...r7 | a0...a7
+    const __m128i ga0 = _mm_unpackhi_epi64(v2l, v2h);   // g0...g7 | a0...a7
+    const __m128i rb0 = _mm_unpacklo_epi64(v2h, v2l);   // r0...r7 | b0...b7
+    const __m128i ga1 = _mm_srli_epi16(ga0, 4);         // g0-|g1-|...|a6-|a7-
+    const __m128i rb1 = _mm_and_si128(rb0, mask_0xf0);  // -r0|-r1|...|-b6|-a7
+    const __m128i ga2 = _mm_and_si128(ga1, mask_0x0f);  // g0-|g1-|...|a6-|a7-
+    const __m128i rgba0 = _mm_or_si128(ga2, rb1);       // rg0..rg7 | ba0..ba7
+    const __m128i rgba1 = _mm_srli_si128(rgba0, 8);     // ba0..ba7 | 0
+#ifdef WEBP_SWAP_16BIT_CSP
+    const __m128i rgba = _mm_unpacklo_epi8(rgba1, rgba0);  // barg0...barg7
+#else
+    const __m128i rgba = _mm_unpacklo_epi8(rgba0, rgba1);  // rgba0...rgba7
+#endif
+    _mm_storeu_si128(out++, rgba);
+    num_pixels -= 8;
+  }
+  // left-overs
+  VP8LConvertBGRAToRGBA4444_C((const uint32_t*)in, num_pixels, (uint8_t*)out);
+}
+
+static void ConvertBGRAToRGB565(const uint32_t* src,
+                                int num_pixels, uint8_t* dst) {
+  const __m128i mask_0xe0 = _mm_set1_epi8(0xe0);
+  const __m128i mask_0xf8 = _mm_set1_epi8(0xf8);
+  const __m128i mask_0x07 = _mm_set1_epi8(0x07);
+  const __m128i* in = (const __m128i*)src;
+  __m128i* out = (__m128i*)dst;
+  while (num_pixels >= 8) {
+    const __m128i bgra0 = _mm_loadu_si128(in++);     // bgra0|bgra1|bgra2|bgra3
+    const __m128i bgra4 = _mm_loadu_si128(in++);     // bgra4|bgra5|bgra6|bgra7
+    const __m128i v0l = _mm_unpacklo_epi8(bgra0, bgra4);  // b0b4g0g4r0r4a0a4...
+    const __m128i v0h = _mm_unpackhi_epi8(bgra0, bgra4);  // b2b6g2g6r2r6a2a6...
+    const __m128i v1l = _mm_unpacklo_epi8(v0l, v0h);      // b0b2b4b6g0g2g4g6...
+    const __m128i v1h = _mm_unpackhi_epi8(v0l, v0h);      // b1b3b5b7g1g3g5g7...
+    const __m128i v2l = _mm_unpacklo_epi8(v1l, v1h);      // b0...b7 | g0...g7
+    const __m128i v2h = _mm_unpackhi_epi8(v1l, v1h);      // r0...r7 | a0...a7
+    const __m128i ga0 = _mm_unpackhi_epi64(v2l, v2h);     // g0...g7 | a0...a7
+    const __m128i rb0 = _mm_unpacklo_epi64(v2h, v2l);     // r0...r7 | b0...b7
+    const __m128i rb1 = _mm_and_si128(rb0, mask_0xf8);    // -r0..-r7|-b0..-b7
+    const __m128i g_lo1 = _mm_srli_epi16(ga0, 5);
+    const __m128i g_lo2 = _mm_and_si128(g_lo1, mask_0x07);  // g0-...g7-|xx (3b)
+    const __m128i g_hi1 = _mm_slli_epi16(ga0, 3);
+    const __m128i g_hi2 = _mm_and_si128(g_hi1, mask_0xe0);  // -g0...-g7|xx (3b)
+    const __m128i b0 = _mm_srli_si128(rb1, 8);              // -b0...-b7|0
+    const __m128i rg1 = _mm_or_si128(rb1, g_lo2);           // gr0...gr7|xx
+    const __m128i b1 = _mm_srli_epi16(b0, 3);
+    const __m128i gb1 = _mm_or_si128(b1, g_hi2);            // bg0...bg7|xx
+#ifdef WEBP_SWAP_16BIT_CSP
+    const __m128i rgba = _mm_unpacklo_epi8(gb1, rg1);     // rggb0...rggb7
+#else
+    const __m128i rgba = _mm_unpacklo_epi8(rg1, gb1);     // bgrb0...bgrb7
+#endif
+    _mm_storeu_si128(out++, rgba);
+    num_pixels -= 8;
+  }
+  // left-overs
+  VP8LConvertBGRAToRGB565_C((const uint32_t*)in, num_pixels, (uint8_t*)out);
+}
+
+static void ConvertBGRAToBGR(const uint32_t* src,
+                             int num_pixels, uint8_t* dst) {
+  const __m128i mask_l = _mm_set_epi32(0, 0x00ffffff, 0, 0x00ffffff);
+  const __m128i mask_h = _mm_set_epi32(0x00ffffff, 0, 0x00ffffff, 0);
+  const __m128i* in = (const __m128i*)src;
+  const uint8_t* const end = dst + num_pixels * 3;
+  // the last storel_epi64 below writes 8 bytes starting at offset 18
+  while (dst + 26 <= end) {
+    const __m128i bgra0 = _mm_loadu_si128(in++);     // bgra0|bgra1|bgra2|bgra3
+    const __m128i bgra4 = _mm_loadu_si128(in++);     // bgra4|bgra5|bgra6|bgra7
+    const __m128i a0l = _mm_and_si128(bgra0, mask_l);   // bgr0|0|bgr0|0
+    const __m128i a4l = _mm_and_si128(bgra4, mask_l);   // bgr0|0|bgr0|0
+    const __m128i a0h = _mm_and_si128(bgra0, mask_h);   // 0|bgr0|0|bgr0
+    const __m128i a4h = _mm_and_si128(bgra4, mask_h);   // 0|bgr0|0|bgr0
+    const __m128i b0h = _mm_srli_epi64(a0h, 8);         // 000b|gr00|000b|gr00
+    const __m128i b4h = _mm_srli_epi64(a4h, 8);         // 000b|gr00|000b|gr00
+    const __m128i c0 = _mm_or_si128(a0l, b0h);          // rgbrgb00|rgbrgb00
+    const __m128i c4 = _mm_or_si128(a4l, b4h);          // rgbrgb00|rgbrgb00
+    const __m128i c2 = _mm_srli_si128(c0, 8);
+    const __m128i c6 = _mm_srli_si128(c4, 8);
+    _mm_storel_epi64((__m128i*)(dst +   0), c0);
+    _mm_storel_epi64((__m128i*)(dst +   6), c2);
+    _mm_storel_epi64((__m128i*)(dst +  12), c4);
+    _mm_storel_epi64((__m128i*)(dst +  18), c6);
+    dst += 24;
+    num_pixels -= 8;
+  }
+  // left-overs
+  VP8LConvertBGRAToBGR_C((const uint32_t*)in, num_pixels, dst);
+}
+
+//------------------------------------------------------------------------------
+
+#define LINE_SIZE 16    // 8 or 16
+static void AddVector(const uint32_t* a, const uint32_t* b, uint32_t* out,
+                      int size) {
+  int i;
+  assert(size % LINE_SIZE == 0);
+  for (i = 0; i < size; i += LINE_SIZE) {
+    const __m128i a0 = _mm_loadu_si128((const __m128i*)&a[i +  0]);
+    const __m128i a1 = _mm_loadu_si128((const __m128i*)&a[i +  4]);
+#if (LINE_SIZE == 16)
+    const __m128i a2 = _mm_loadu_si128((const __m128i*)&a[i +  8]);
+    const __m128i a3 = _mm_loadu_si128((const __m128i*)&a[i + 12]);
+#endif
+    const __m128i b0 = _mm_loadu_si128((const __m128i*)&b[i +  0]);
+    const __m128i b1 = _mm_loadu_si128((const __m128i*)&b[i +  4]);
+#if (LINE_SIZE == 16)
+    const __m128i b2 = _mm_loadu_si128((const __m128i*)&b[i +  8]);
+    const __m128i b3 = _mm_loadu_si128((const __m128i*)&b[i + 12]);
+#endif
+    _mm_storeu_si128((__m128i*)&out[i +  0], _mm_add_epi32(a0, b0));
+    _mm_storeu_si128((__m128i*)&out[i +  4], _mm_add_epi32(a1, b1));
+#if (LINE_SIZE == 16)
+    _mm_storeu_si128((__m128i*)&out[i +  8], _mm_add_epi32(a2, b2));
+    _mm_storeu_si128((__m128i*)&out[i + 12], _mm_add_epi32(a3, b3));
+#endif
+  }
+}
+
+static void AddVectorEq(const uint32_t* a, uint32_t* out, int size) {
+  int i;
+  assert(size % LINE_SIZE == 0);
+  for (i = 0; i < size; i += LINE_SIZE) {
+    const __m128i a0 = _mm_loadu_si128((const __m128i*)&a[i +  0]);
+    const __m128i a1 = _mm_loadu_si128((const __m128i*)&a[i +  4]);
+#if (LINE_SIZE == 16)
+    const __m128i a2 = _mm_loadu_si128((const __m128i*)&a[i +  8]);
+    const __m128i a3 = _mm_loadu_si128((const __m128i*)&a[i + 12]);
+#endif
+    const __m128i b0 = _mm_loadu_si128((const __m128i*)&out[i +  0]);
+    const __m128i b1 = _mm_loadu_si128((const __m128i*)&out[i +  4]);
+#if (LINE_SIZE == 16)
+    const __m128i b2 = _mm_loadu_si128((const __m128i*)&out[i +  8]);
+    const __m128i b3 = _mm_loadu_si128((const __m128i*)&out[i + 12]);
+#endif
+    _mm_storeu_si128((__m128i*)&out[i +  0], _mm_add_epi32(a0, b0));
+    _mm_storeu_si128((__m128i*)&out[i +  4], _mm_add_epi32(a1, b1));
+#if (LINE_SIZE == 16)
+    _mm_storeu_si128((__m128i*)&out[i +  8], _mm_add_epi32(a2, b2));
+    _mm_storeu_si128((__m128i*)&out[i + 12], _mm_add_epi32(a3, b3));
+#endif
+  }
+}
+#undef LINE_SIZE
+
+// Note we are adding uint32_t's as *signed* int32's (using _mm_add_epi32). But
+// that's ok since the histogram values are less than 1<<28 (max picture size).
+static void HistogramAdd(const VP8LHistogram* const a,
+                         const VP8LHistogram* const b,
+                         VP8LHistogram* const out) {
+  int i;
+  const int literal_size = VP8LHistogramNumCodes(a->palette_code_bits_);
+  assert(a->palette_code_bits_ == b->palette_code_bits_);
+  if (b != out) {
+    AddVector(a->literal_, b->literal_, out->literal_, NUM_LITERAL_CODES);
+    AddVector(a->red_, b->red_, out->red_, NUM_LITERAL_CODES);
+    AddVector(a->blue_, b->blue_, out->blue_, NUM_LITERAL_CODES);
+    AddVector(a->alpha_, b->alpha_, out->alpha_, NUM_LITERAL_CODES);
+  } else {
+    AddVectorEq(a->literal_, out->literal_, NUM_LITERAL_CODES);
+    AddVectorEq(a->red_, out->red_, NUM_LITERAL_CODES);
+    AddVectorEq(a->blue_, out->blue_, NUM_LITERAL_CODES);
+    AddVectorEq(a->alpha_, out->alpha_, NUM_LITERAL_CODES);
+  }
+  for (i = NUM_LITERAL_CODES; i < literal_size; ++i) {
+    out->literal_[i] = a->literal_[i] + b->literal_[i];
+  }
+  for (i = 0; i < NUM_DISTANCE_CODES; ++i) {
+    out->distance_[i] = a->distance_[i] + b->distance_[i];
+  }
+}
+
+#endif   // WEBP_USE_SSE2
+
+//------------------------------------------------------------------------------
+
+extern void VP8LDspInitSSE2(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8LDspInitSSE2(void) {
+#if defined(WEBP_USE_SSE2)
+  VP8LPredictors[5] = Predictor5;
+  VP8LPredictors[6] = Predictor6;
+  VP8LPredictors[7] = Predictor7;
+  VP8LPredictors[8] = Predictor8;
+  VP8LPredictors[9] = Predictor9;
+  VP8LPredictors[10] = Predictor10;
+  VP8LPredictors[11] = Predictor11;
+  VP8LPredictors[12] = Predictor12;
+  VP8LPredictors[13] = Predictor13;
+
+  VP8LSubtractGreenFromBlueAndRed = SubtractGreenFromBlueAndRed;
+  VP8LAddGreenToBlueAndRed = AddGreenToBlueAndRed;
+
+  VP8LTransformColor = TransformColor;
+  VP8LTransformColorInverse = TransformColorInverse;
+
+  VP8LConvertBGRAToRGBA = ConvertBGRAToRGBA;
+  VP8LConvertBGRAToRGBA4444 = ConvertBGRAToRGBA4444;
+  VP8LConvertBGRAToRGB565 = ConvertBGRAToRGB565;
+  VP8LConvertBGRAToBGR = ConvertBGRAToBGR;
+
+  VP8LHistogramAdd = HistogramAdd;
+#endif   // WEBP_USE_SSE2
+}
+
+//------------------------------------------------------------------------------
diff --git a/Source/LibWebP/src/dsp/dsp.rescaler.c b/Source/LibWebP/src/dsp/dsp.rescaler.c
new file mode 100644
index 0000000..852d44c
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.rescaler.c
@@ -0,0 +1,115 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Rescaling functions
+
+#include "./dsp.h"
+#include "../utils/rescaler.h"
+
+//------------------------------------------------------------------------------
+// Implementations of critical functions ImportRow / ExportRow
+
+#define ROUNDER (1 << (WEBP_RESCALER_RFIX - 1))
+#define MULT_FIX(x, y) (((int64_t)(x) * (y) + ROUNDER) >> WEBP_RESCALER_RFIX)
+
+static void RescalerImportRowC(WebPRescaler* const wrk,
+                               const uint8_t* const src, int channel) {
+  const int x_stride = wrk->num_channels;
+  const int x_out_max = wrk->dst_width * wrk->num_channels;
+  int x_in = channel;
+  int x_out;
+  int accum = 0;
+  if (!wrk->x_expand) {
+    int sum = 0;
+    for (x_out = channel; x_out < x_out_max; x_out += x_stride) {
+      accum += wrk->x_add;
+      for (; accum > 0; accum -= wrk->x_sub) {
+        sum += src[x_in];
+        x_in += x_stride;
+      }
+      {        // Emit next horizontal pixel.
+        const int32_t base = src[x_in];
+        const int32_t frac = base * (-accum);
+        x_in += x_stride;
+        wrk->frow[x_out] = (sum + base) * wrk->x_sub - frac;
+        // fresh fractional start for next pixel
+        sum = (int)MULT_FIX(frac, wrk->fx_scale);
+      }
+    }
+  } else {        // simple bilinear interpolation
+    int left = src[channel], right = src[channel];
+    for (x_out = channel; x_out < x_out_max; x_out += x_stride) {
+      if (accum < 0) {
+        left = right;
+        x_in += x_stride;
+        right = src[x_in];
+        accum += wrk->x_add;
+      }
+      wrk->frow[x_out] = right * wrk->x_add + (left - right) * accum;
+      accum -= wrk->x_sub;
+    }
+  }
+  // Accumulate the contribution of the new row.
+  for (x_out = channel; x_out < x_out_max; x_out += x_stride) {
+    wrk->irow[x_out] += wrk->frow[x_out];
+  }
+}
+
+void WebPRescalerExportRowC(WebPRescaler* const wrk, int x_out) {
+  if (wrk->y_accum <= 0) {
+    uint8_t* const dst = wrk->dst;
+    int32_t* const irow = wrk->irow;
+    const int32_t* const frow = wrk->frow;
+    const int yscale = wrk->fy_scale * (-wrk->y_accum);
+    const int x_out_max = wrk->dst_width * wrk->num_channels;
+    for (; x_out < x_out_max; ++x_out) {
+      const int frac = (int)MULT_FIX(frow[x_out], yscale);
+      const int v = (int)MULT_FIX(irow[x_out] - frac, wrk->fxy_scale);
+      dst[x_out] = (!(v & ~0xff)) ? v : (v < 0) ? 0 : 255;
+      irow[x_out] = frac;   // new fractional start
+    }
+    wrk->y_accum += wrk->y_add;
+    wrk->dst += wrk->dst_stride;
+  }
+}
+
+#undef MULT_FIX
+#undef ROUNDER
+
+//------------------------------------------------------------------------------
+
+void (*WebPRescalerImportRow)(struct WebPRescaler* const wrk,
+                              const uint8_t* const src, int channel);
+void (*WebPRescalerExportRow)(struct WebPRescaler* const wrk, int x_out);
+
+extern void WebPRescalerDspInitMIPS32(void);
+extern void WebPRescalerDspInitMIPSdspR2(void);
+
+static volatile VP8CPUInfo rescaler_last_cpuinfo_used =
+    (VP8CPUInfo)&rescaler_last_cpuinfo_used;
+
+WEBP_TSAN_IGNORE_FUNCTION void WebPRescalerDspInit(void) {
+  if (rescaler_last_cpuinfo_used == VP8GetCPUInfo) return;
+
+  WebPRescalerImportRow = RescalerImportRowC;
+  WebPRescalerExportRow = WebPRescalerExportRowC;
+  if (VP8GetCPUInfo != NULL) {
+#if defined(WEBP_USE_MIPS32)
+    if (VP8GetCPUInfo(kMIPS32)) {
+      WebPRescalerDspInitMIPS32();
+    }
+#endif
+#if defined(WEBP_USE_MIPS_DSP_R2)
+    if (VP8GetCPUInfo(kMIPSdspR2)) {
+      WebPRescalerDspInitMIPSdspR2();
+    }
+#endif
+  }
+  rescaler_last_cpuinfo_used = VP8GetCPUInfo;
+}
diff --git a/Source/LibWebP/src/dsp/dsp.rescaler_mips32.c b/Source/LibWebP/src/dsp/dsp.rescaler_mips32.c
new file mode 100644
index 0000000..a5b155b
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.rescaler_mips32.c
@@ -0,0 +1,192 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// MIPS version of rescaling functions
+//
+// Author(s): Djordje Pesut (djordje.pesut at imgtec.com)
+
+#include "./dsp.h"
+
+#if defined(WEBP_USE_MIPS32)
+
+#include "../utils/rescaler.h"
+
+static void ImportRow(WebPRescaler* const wrk,
+                      const uint8_t* const src, int channel) {
+  const int x_stride = wrk->num_channels;
+  const int x_out_max = wrk->dst_width * wrk->num_channels;
+  const int fx_scale = wrk->fx_scale;
+  const int x_add = wrk->x_add;
+  const int x_sub = wrk->x_sub;
+  int* frow = wrk->frow + channel;
+  int* irow = wrk->irow + channel;
+  const uint8_t* src1 = src + channel;
+  int temp1, temp2, temp3;
+  int base, frac, sum;
+  int accum, accum1;
+  const int x_stride1 = x_stride << 2;
+  int loop_c = x_out_max - channel;
+
+  if (!wrk->x_expand) {
+    __asm__ volatile (
+      "li     %[temp1],   0x8000                    \n\t"
+      "li     %[temp2],   0x10000                   \n\t"
+      "li     %[sum],     0                         \n\t"
+      "li     %[accum],   0                         \n\t"
+    "1:                                             \n\t"
+      "addu   %[accum],   %[accum],   %[x_add]      \n\t"
+      "blez   %[accum],   3f                        \n\t"
+    "2:                                             \n\t"
+      "lbu    %[temp3],   0(%[src1])                \n\t"
+      "subu   %[accum],   %[accum],   %[x_sub]      \n\t"
+      "addu   %[src1],    %[src1],    %[x_stride]   \n\t"
+      "addu   %[sum],     %[sum],     %[temp3]      \n\t"
+      "bgtz   %[accum],   2b                        \n\t"
+    "3:                                             \n\t"
+      "lbu    %[base],    0(%[src1])                \n\t"
+      "addu   %[src1],    %[src1],    %[x_stride]   \n\t"
+      "negu   %[accum1],  %[accum]                  \n\t"
+      "mul    %[frac],    %[base],    %[accum1]     \n\t"
+      "addu   %[temp3],   %[sum],     %[base]       \n\t"
+      "mul    %[temp3],   %[temp3],   %[x_sub]      \n\t"
+      "lw     %[base],    0(%[irow])                \n\t"
+      "subu   %[loop_c],  %[loop_c],  %[x_stride]   \n\t"
+      "sll    %[accum1],  %[frac],    2             \n\t"
+      "mult   %[temp1],   %[temp2]                  \n\t"
+      "madd   %[accum1],  %[fx_scale]               \n\t"
+      "mfhi   %[sum]                                \n\t"
+      "subu   %[temp3],   %[temp3],   %[frac]       \n\t"
+      "sw     %[temp3],   0(%[frow])                \n\t"
+      "add    %[base],    %[base],    %[temp3]      \n\t"
+      "sw     %[base],    0(%[irow])                \n\t"
+      "addu   %[irow],    %[irow],    %[x_stride1]  \n\t"
+      "addu   %[frow],    %[frow],    %[x_stride1]  \n\t"
+      "bgtz   %[loop_c],  1b                        \n\t"
+
+      : [accum] "=&r" (accum), [src1] "+r" (src1), [temp3] "=&r" (temp3),
+        [sum] "=&r" (sum), [base] "=&r" (base), [frac] "=&r" (frac),
+        [frow] "+r" (frow), [irow] "+r" (irow), [accum1] "=&r" (accum1),
+        [temp2] "=&r" (temp2), [temp1] "=&r" (temp1)
+      : [x_stride] "r" (x_stride), [fx_scale] "r" (fx_scale),
+        [x_sub] "r" (x_sub), [x_add] "r" (x_add),
+        [loop_c] "r" (loop_c), [x_stride1] "r" (x_stride1)
+      : "memory", "hi", "lo"
+    );
+  } else {
+    __asm__ volatile (
+      "lbu    %[temp1],   0(%[src1])                \n\t"
+      "move   %[temp2],   %[temp1]                  \n\t"
+      "li     %[accum],   0                         \n\t"
+    "1:                                             \n\t"
+      "bgez   %[accum],   2f                        \n\t"
+      "move   %[temp2],   %[temp1]                  \n\t"
+      "addu   %[src1],    %[x_stride]               \n\t"
+      "lbu    %[temp1],   0(%[src1])                \n\t"
+      "addu   %[accum],   %[x_add]                  \n\t"
+    "2:                                             \n\t"
+      "subu   %[temp3],   %[temp2],   %[temp1]      \n\t"
+      "mul    %[temp3],   %[temp3],   %[accum]      \n\t"
+      "mul    %[base],    %[temp1],   %[x_add]      \n\t"
+      "subu   %[accum],   %[accum],   %[x_sub]      \n\t"
+      "lw     %[frac],    0(%[irow])                \n\t"
+      "subu   %[loop_c],  %[loop_c],  %[x_stride]   \n\t"
+      "addu   %[temp3],   %[base],    %[temp3]      \n\t"
+      "sw     %[temp3],   0(%[frow])                \n\t"
+      "addu   %[frow],    %[x_stride1]              \n\t"
+      "addu   %[frac],    %[temp3]                  \n\t"
+      "sw     %[frac],    0(%[irow])                \n\t"
+      "addu   %[irow],    %[x_stride1]              \n\t"
+      "bgtz   %[loop_c],  1b                        \n\t"
+
+      : [src1] "+r" (src1), [accum] "=&r" (accum), [temp1] "=&r" (temp1),
+        [temp2] "=&r" (temp2), [temp3] "=&r" (temp3), [base] "=&r" (base),
+        [frac] "=&r" (frac), [frow] "+r" (frow), [irow] "+r" (irow)
+      : [x_stride] "r" (x_stride), [x_add] "r" (x_add), [x_sub] "r" (x_sub),
+        [x_stride1] "r" (x_stride1), [loop_c] "r" (loop_c)
+      : "memory", "hi", "lo"
+    );
+  }
+}
+
+static void ExportRow(WebPRescaler* const wrk, int x_out) {
+  if (wrk->y_accum <= 0) {
+    uint8_t* const dst = wrk->dst;
+    int32_t* const irow = wrk->irow;
+    const int32_t* const frow = wrk->frow;
+    const int yscale = wrk->fy_scale * (-wrk->y_accum);
+    const int x_out_max = wrk->dst_width * wrk->num_channels;
+    // if wrk->fxy_scale can fit into 32 bits use optimized code,
+    // otherwise use C code
+    if ((wrk->fxy_scale >> 32) == 0) {
+      int temp0, temp1, temp3, temp4, temp5, temp6, temp7, loop_end;
+      const int temp2 = (int)(wrk->fxy_scale);
+      const int temp8 = x_out_max << 2;
+      uint8_t* dst_t = (uint8_t*)dst;
+      int32_t* irow_t = (int32_t*)irow;
+      const int32_t* frow_t = (const int32_t*)frow;
+
+      __asm__ volatile(
+        "addiu    %[temp6],    $zero,       -256          \n\t"
+        "addiu    %[temp7],    $zero,       255           \n\t"
+        "li       %[temp3],    0x10000                    \n\t"
+        "li       %[temp4],    0x8000                     \n\t"
+        "addu     %[loop_end], %[frow_t],   %[temp8]      \n\t"
+      "1:                                                 \n\t"
+        "lw       %[temp0],    0(%[frow_t])               \n\t"
+        "mult     %[temp3],    %[temp4]                   \n\t"
+        "addiu    %[frow_t],   %[frow_t],   4             \n\t"
+        "sll      %[temp0],    %[temp0],    2             \n\t"
+        "madd     %[temp0],    %[yscale]                  \n\t"
+        "mfhi     %[temp1]                                \n\t"
+        "lw       %[temp0],    0(%[irow_t])               \n\t"
+        "addiu    %[dst_t],    %[dst_t],    1             \n\t"
+        "addiu    %[irow_t],   %[irow_t],   4             \n\t"
+        "subu     %[temp0],    %[temp0],    %[temp1]      \n\t"
+        "mult     %[temp3],    %[temp4]                   \n\t"
+        "sll      %[temp0],    %[temp0],    2             \n\t"
+        "madd     %[temp0],    %[temp2]                   \n\t"
+        "mfhi     %[temp5]                                \n\t"
+        "sw       %[temp1],    -4(%[irow_t])              \n\t"
+        "and      %[temp0],    %[temp5],    %[temp6]      \n\t"
+        "slti     %[temp1],    %[temp5],    0             \n\t"
+        "beqz     %[temp0],    2f                         \n\t"
+        "xor      %[temp5],    %[temp5],    %[temp5]      \n\t"
+        "movz     %[temp5],    %[temp7],    %[temp1]      \n\t"
+      "2:                                                 \n\t"
+        "sb       %[temp5],    -1(%[dst_t])               \n\t"
+        "bne      %[frow_t],   %[loop_end], 1b            \n\t"
+
+        : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp3]"=&r"(temp3),
+          [temp4]"=&r"(temp4), [temp5]"=&r"(temp5), [temp6]"=&r"(temp6),
+          [temp7]"=&r"(temp7), [frow_t]"+r"(frow_t), [irow_t]"+r"(irow_t),
+          [dst_t]"+r"(dst_t), [loop_end]"=&r"(loop_end)
+        : [temp2]"r"(temp2), [yscale]"r"(yscale), [temp8]"r"(temp8)
+        : "memory", "hi", "lo"
+      );
+      wrk->y_accum += wrk->y_add;
+      wrk->dst += wrk->dst_stride;
+    } else {
+      WebPRescalerExportRowC(wrk, x_out);
+    }
+  }
+}
+
+#endif  // WEBP_USE_MIPS32
+
+//------------------------------------------------------------------------------
+// Entry point
+
+extern void WebPRescalerDspInitMIPS32(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void WebPRescalerDspInitMIPS32(void) {
+#if defined(WEBP_USE_MIPS32)
+  WebPRescalerImportRow = ImportRow;
+  WebPRescalerExportRow = ExportRow;
+#endif  // WEBP_USE_MIPS32
+}
diff --git a/Source/LibWebP/src/dsp/dsp.rescaler_mips_dsp_r2.c b/Source/LibWebP/src/dsp/dsp.rescaler_mips_dsp_r2.c
new file mode 100644
index 0000000..2252f44
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.rescaler_mips_dsp_r2.c
@@ -0,0 +1,210 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// MIPS version of rescaling functions
+//
+// Author(s): Djordje Pesut (djordje.pesut at imgtec.com)
+
+#include "./dsp.h"
+
+#if defined(WEBP_USE_MIPS_DSP_R2)
+
+#include "../utils/rescaler.h"
+
+static void ImportRow(WebPRescaler* const wrk,
+                      const uint8_t* const src, int channel) {
+  const int x_stride = wrk->num_channels;
+  const int x_out_max = wrk->dst_width * wrk->num_channels;
+  const int fx_scale = wrk->fx_scale;
+  const int x_add = wrk->x_add;
+  const int x_sub = wrk->x_sub;
+  int* frow = wrk->frow + channel;
+  int* irow = wrk->irow + channel;
+  const uint8_t* src1 = src + channel;
+  int temp1, temp2, temp3;
+  int base, frac, sum;
+  int accum, accum1;
+  const int x_stride1 = x_stride << 2;
+  int loop_c = x_out_max - channel;
+
+  if (!wrk->x_expand) {
+    __asm__ volatile (
+      "li         %[sum],     0                         \n\t"
+      "li         %[accum],   0                         \n\t"
+    "1:                                                 \n\t"
+      "addu       %[accum],   %[accum],   %[x_add]      \n\t"
+      "blez       %[accum],   3f                        \n\t"
+    "2:                                                 \n\t"
+      "lbu        %[temp3],   0(%[src1])                \n\t"
+      "subu       %[accum],   %[accum],   %[x_sub]      \n\t"
+      "addu       %[src1],    %[src1],    %[x_stride]   \n\t"
+      "addu       %[sum],     %[sum],     %[temp3]      \n\t"
+      "bgtz       %[accum],   2b                        \n\t"
+    "3:                                                 \n\t"
+      "lbu        %[base],    0(%[src1])                \n\t"
+      "addu       %[src1],    %[src1],    %[x_stride]   \n\t"
+      "negu       %[accum1],  %[accum]                  \n\t"
+      "mul        %[frac],    %[base],    %[accum1]     \n\t"
+      "addu       %[temp3],   %[sum],     %[base]       \n\t"
+      "mul        %[temp3],   %[temp3],   %[x_sub]      \n\t"
+      "lw         %[base],    0(%[irow])                \n\t"
+      "sll        %[accum1],  %[frac],    1             \n\t"
+      "subu       %[loop_c],  %[loop_c],  %[x_stride]   \n\t"
+      "mulq_rs.w  %[sum],     %[accum1],  %[fx_scale]   \n\t"
+      "subu       %[temp3],   %[temp3],   %[frac]       \n\t"
+      "sw         %[temp3],   0(%[frow])                \n\t"
+      "add        %[base],    %[base],    %[temp3]      \n\t"
+      "sw         %[base],    0(%[irow])                \n\t"
+      "addu       %[irow],    %[irow],    %[x_stride1]  \n\t"
+      "addu       %[frow],    %[frow],    %[x_stride1]  \n\t"
+      "bgtz       %[loop_c],  1b                        \n\t"
+
+      : [accum]"=&r"(accum), [src1]"+&r"(src1), [temp3]"=&r"(temp3),
+        [sum]"=&r"(sum), [base]"=&r"(base), [frac]"=&r"(frac),
+        [frow]"+&r"(frow), [irow]"+&r"(irow), [accum1]"=&r"(accum1),
+        [loop_c]"+&r"(loop_c)
+      : [x_stride]"r"(x_stride), [fx_scale]"r"(fx_scale), [x_sub]"r"(x_sub),
+        [x_add] "r" (x_add), [x_stride1] "r" (x_stride1)
+      : "memory", "hi", "lo"
+    );
+  } else {
+    __asm__ volatile (
+      "lbu    %[temp1],   0(%[src1])                \n\t"
+      "move   %[temp2],   %[temp1]                  \n\t"
+      "li     %[accum],   0                         \n\t"
+    "1:                                             \n\t"
+      "bgez   %[accum],   2f                        \n\t"
+      "move   %[temp2],   %[temp1]                  \n\t"
+      "addu   %[src1],    %[x_stride]               \n\t"
+      "lbu    %[temp1],   0(%[src1])                \n\t"
+      "addu   %[accum],   %[x_add]                  \n\t"
+    "2:                                             \n\t"
+      "subu   %[temp3],   %[temp2],   %[temp1]      \n\t"
+      "mul    %[temp3],   %[temp3],   %[accum]      \n\t"
+      "mul    %[base],    %[temp1],   %[x_add]      \n\t"
+      "subu   %[accum],   %[accum],   %[x_sub]      \n\t"
+      "lw     %[frac],    0(%[irow])                \n\t"
+      "subu   %[loop_c],  %[loop_c],  %[x_stride]   \n\t"
+      "addu   %[temp3],   %[base],    %[temp3]      \n\t"
+      "sw     %[temp3],   0(%[frow])                \n\t"
+      "addu   %[frow],    %[x_stride1]              \n\t"
+      "addu   %[frac],    %[temp3]                  \n\t"
+      "sw     %[frac],    0(%[irow])                \n\t"
+      "addu   %[irow],    %[x_stride1]              \n\t"
+      "bgtz   %[loop_c],  1b                        \n\t"
+
+      : [src1]"+&r"(src1), [accum]"=&r"(accum), [temp1]"=&r"(temp1),
+        [temp2]"=&r"(temp2), [temp3]"=&r"(temp3), [base]"=&r"(base),
+        [frac]"=&r"(frac), [frow]"+&r"(frow), [irow]"+&r"(irow),
+        [loop_c]"+&r"(loop_c)
+      : [x_stride]"r"(x_stride), [x_add]"r"(x_add), [x_sub]"r"(x_sub),
+        [x_stride1]"r"(x_stride1)
+      : "memory", "hi", "lo"
+    );
+  }
+}
+
+static void ExportRow(WebPRescaler* const wrk, int x_out) {
+  if (wrk->y_accum <= 0) {
+    // if wrk->fxy_scale can fit into 32 bits use optimized code,
+    // otherwise use C code
+    if ((wrk->fxy_scale >> 32) == 0) {
+      uint8_t* dst = wrk->dst;
+      int32_t* irow = wrk->irow;
+      const int32_t* frow = wrk->frow;
+      const int yscale = wrk->fy_scale * (-wrk->y_accum);
+      const int x_out_max = wrk->dst_width * wrk->num_channels;
+      int temp0, temp1, temp3, temp4, temp5, temp6, temp7;
+      const int temp2 = (int)wrk->fxy_scale;
+      const int rest = (x_out_max - x_out) & 1;
+      const int32_t* const loop_end = frow + (x_out_max - x_out) - rest;
+
+      __asm__ volatile (
+        ".set             push                                    \n\t"
+        ".set             noreorder                               \n\t"
+        "beq              %[frow],   %[loop_end],   1f            \n\t"
+        " nop                                                     \n\t"
+      "0:                                                         \n\t"
+        "lw               %[temp0],    0(%[frow])                 \n\t"
+        "lw               %[temp1],    0(%[irow])                 \n\t"
+        "lw               %[temp3],    4(%[frow])                 \n\t"
+        "lw               %[temp4],    4(%[irow])                 \n\t"
+        "sll              %[temp0],    %[temp0],      1           \n\t"
+        "sll              %[temp3],    %[temp3],      1           \n\t"
+        "mulq_rs.w        %[temp5],    %[temp0],      %[yscale]   \n\t"
+        "mulq_rs.w        %[temp6],    %[temp3],      %[yscale]   \n\t"
+        "addiu            %[frow],     %[frow],       8           \n\t"
+        "addiu            %[dst],      %[dst],        2           \n\t"
+        "addiu            %[irow],     %[irow],       8           \n\t"
+        "subu             %[temp1],    %[temp1],      %[temp5]    \n\t"
+        "subu             %[temp4],    %[temp4],      %[temp6]    \n\t"
+        "sll              %[temp1],    %[temp1],      1           \n\t"
+        "sll              %[temp4],    %[temp4],      1           \n\t"
+        "mulq_rs.w        %[temp0],    %[temp1],      %[temp2]    \n\t"
+        "mulq_rs.w        %[temp3],    %[temp4],      %[temp2]    \n\t"
+        "sw               %[temp5],    -8(%[irow])                \n\t"
+        "sw               %[temp6],    -4(%[irow])                \n\t"
+        "shll_s.ph        %[temp0],    %[temp0],      7           \n\t"
+        "shll_s.ph        %[temp3],    %[temp3],      7           \n\t"
+        "precrqu_s.qb.ph  %[temp0],    %[temp0],      %[temp3]    \n\t"
+        "sb               %[temp0],    -1(%[dst])                 \n\t"
+        "srl              %[temp0],    %[temp0],      16          \n\t"
+        "bne              %[frow],     %[loop_end],   0b          \n\t"
+        " sb              %[temp0],    -2(%[dst])                 \n\t"
+      "1:                                                         \n\t"
+        "beqz             %[rest],     3f                         \n\t"
+        " nop                                                     \n\t"
+        "addiu            %[temp6],    $zero,         -256        \n\t"
+        "addiu            %[temp7],    $zero,         255         \n\t"
+        "lw               %[temp0],    0(%[frow])                 \n\t"
+        "sll              %[temp0],    %[temp0],      1           \n\t"
+        "mulq_rs.w        %[temp1],    %[temp0],      %[yscale]   \n\t"
+        "lw               %[temp0],    0(%[irow])                 \n\t"
+        "subu             %[temp0],    %[temp0],      %[temp1]    \n\t"
+        "sll              %[temp0],    %[temp0],      1           \n\t"
+        "mulq_rs.w        %[temp5],    %[temp0],      %[temp2]    \n\t"
+        "sw               %[temp1],    0(%[irow])                 \n\t"
+        "and              %[temp0],    %[temp5],      %[temp6]    \n\t"
+        "beqz             %[temp0],    2f                         \n\t"
+        " slti            %[temp1],    %[temp5],      0           \n\t"
+        "xor              %[temp5],    %[temp5],      %[temp5]    \n\t"
+        "movz             %[temp5],    %[temp7],      %[temp1]    \n\t"
+      "2:                                                         \n\t"
+        "sb               %[temp5],    0(%[dst])                  \n\t"
+      "3:                                                         \n\t"
+        ".set             pop                                     \n\t"
+        : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp3]"=&r"(temp3),
+          [temp4]"=&r"(temp4), [temp5]"=&r"(temp5), [temp6]"=&r"(temp6),
+          [temp7]"=&r"(temp7), [frow]"+&r"(frow), [irow]"+&r"(irow),
+          [dst]"+&r"(dst)
+        : [temp2]"r"(temp2), [yscale]"r"(yscale), [loop_end]"r"(loop_end),
+          [rest]"r"(rest)
+        : "memory", "hi", "lo"
+      );
+      wrk->y_accum += wrk->y_add;
+      wrk->dst += wrk->dst_stride;
+    } else {
+      WebPRescalerExportRowC(wrk, x_out);
+    }
+  }
+}
+
+#endif  // WEBP_USE_MIPS_DSP_R2
+
+//------------------------------------------------------------------------------
+// Entry point
+
+extern void WebPRescalerDspInitMIPSdspR2(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void WebPRescalerDspInitMIPSdspR2(void) {
+#if defined(WEBP_USE_MIPS_DSP_R2)
+  WebPRescalerImportRow = ImportRow;
+  WebPRescalerExportRow = ExportRow;
+#endif  // WEBP_USE_MIPS_DSP_R2
+}
diff --git a/Source/LibWebP/src/dsp/dsp.upsampling.c b/Source/LibWebP/src/dsp/dsp.upsampling.c
new file mode 100644
index 0000000..6271bde
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.upsampling.c
@@ -0,0 +1,252 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// YUV to RGB upsampling functions.
+//
+// Author: somnath at google.com (Somnath Banerjee)
+
+#include "./dsp.h"
+#include "./yuv.h"
+
+#include <assert.h>
+
+//------------------------------------------------------------------------------
+// Fancy upsampler
+
+#ifdef FANCY_UPSAMPLING
+
+// Fancy upsampling functions to convert YUV to RGB
+WebPUpsampleLinePairFunc WebPUpsamplers[MODE_LAST];
+
+// Given samples laid out in a square as:
+//  [a b]
+//  [c d]
+// we interpolate u/v as:
+//  ([9*a + 3*b + 3*c +   d    3*a + 9*b + 3*c +   d] + [8 8]) / 16
+//  ([3*a +   b + 9*c + 3*d      a + 3*b + 3*c + 9*d]   [8 8]) / 16
+
+// We process u and v together stashed into 32bit (16bit each).
+#define LOAD_UV(u, v) ((u) | ((v) << 16))
+
+#define UPSAMPLE_FUNC(FUNC_NAME, FUNC, XSTEP)                                  \
+static void FUNC_NAME(const uint8_t* top_y, const uint8_t* bottom_y,           \
+                      const uint8_t* top_u, const uint8_t* top_v,              \
+                      const uint8_t* cur_u, const uint8_t* cur_v,              \
+                      uint8_t* top_dst, uint8_t* bottom_dst, int len) {        \
+  int x;                                                                       \
+  const int last_pixel_pair = (len - 1) >> 1;                                  \
+  uint32_t tl_uv = LOAD_UV(top_u[0], top_v[0]);   /* top-left sample */        \
+  uint32_t l_uv  = LOAD_UV(cur_u[0], cur_v[0]);   /* left-sample */            \
+  assert(top_y != NULL);                                                       \
+  {                                                                            \
+    const uint32_t uv0 = (3 * tl_uv + l_uv + 0x00020002u) >> 2;                \
+    FUNC(top_y[0], uv0 & 0xff, (uv0 >> 16), top_dst);                          \
+  }                                                                            \
+  if (bottom_y != NULL) {                                                      \
+    const uint32_t uv0 = (3 * l_uv + tl_uv + 0x00020002u) >> 2;                \
+    FUNC(bottom_y[0], uv0 & 0xff, (uv0 >> 16), bottom_dst);                    \
+  }                                                                            \
+  for (x = 1; x <= last_pixel_pair; ++x) {                                     \
+    const uint32_t t_uv = LOAD_UV(top_u[x], top_v[x]);  /* top sample */       \
+    const uint32_t uv   = LOAD_UV(cur_u[x], cur_v[x]);  /* sample */           \
+    /* precompute invariant values associated with first and second diagonals*/\
+    const uint32_t avg = tl_uv + t_uv + l_uv + uv + 0x00080008u;               \
+    const uint32_t diag_12 = (avg + 2 * (t_uv + l_uv)) >> 3;                   \
+    const uint32_t diag_03 = (avg + 2 * (tl_uv + uv)) >> 3;                    \
+    {                                                                          \
+      const uint32_t uv0 = (diag_12 + tl_uv) >> 1;                             \
+      const uint32_t uv1 = (diag_03 + t_uv) >> 1;                              \
+      FUNC(top_y[2 * x - 1], uv0 & 0xff, (uv0 >> 16),                          \
+           top_dst + (2 * x - 1) * XSTEP);                                     \
+      FUNC(top_y[2 * x - 0], uv1 & 0xff, (uv1 >> 16),                          \
+           top_dst + (2 * x - 0) * XSTEP);                                     \
+    }                                                                          \
+    if (bottom_y != NULL) {                                                    \
+      const uint32_t uv0 = (diag_03 + l_uv) >> 1;                              \
+      const uint32_t uv1 = (diag_12 + uv) >> 1;                                \
+      FUNC(bottom_y[2 * x - 1], uv0 & 0xff, (uv0 >> 16),                       \
+           bottom_dst + (2 * x - 1) * XSTEP);                                  \
+      FUNC(bottom_y[2 * x + 0], uv1 & 0xff, (uv1 >> 16),                       \
+           bottom_dst + (2 * x + 0) * XSTEP);                                  \
+    }                                                                          \
+    tl_uv = t_uv;                                                              \
+    l_uv = uv;                                                                 \
+  }                                                                            \
+  if (!(len & 1)) {                                                            \
+    {                                                                          \
+      const uint32_t uv0 = (3 * tl_uv + l_uv + 0x00020002u) >> 2;              \
+      FUNC(top_y[len - 1], uv0 & 0xff, (uv0 >> 16),                            \
+           top_dst + (len - 1) * XSTEP);                                       \
+    }                                                                          \
+    if (bottom_y != NULL) {                                                    \
+      const uint32_t uv0 = (3 * l_uv + tl_uv + 0x00020002u) >> 2;              \
+      FUNC(bottom_y[len - 1], uv0 & 0xff, (uv0 >> 16),                         \
+           bottom_dst + (len - 1) * XSTEP);                                    \
+    }                                                                          \
+  }                                                                            \
+}
+
+// All variants implemented.
+UPSAMPLE_FUNC(UpsampleRgbLinePair,  VP8YuvToRgb,  3)
+UPSAMPLE_FUNC(UpsampleBgrLinePair,  VP8YuvToBgr,  3)
+UPSAMPLE_FUNC(UpsampleRgbaLinePair, VP8YuvToRgba, 4)
+UPSAMPLE_FUNC(UpsampleBgraLinePair, VP8YuvToBgra, 4)
+UPSAMPLE_FUNC(UpsampleArgbLinePair, VP8YuvToArgb, 4)
+UPSAMPLE_FUNC(UpsampleRgba4444LinePair, VP8YuvToRgba4444, 2)
+UPSAMPLE_FUNC(UpsampleRgb565LinePair,  VP8YuvToRgb565,  2)
+
+#undef LOAD_UV
+#undef UPSAMPLE_FUNC
+
+#endif  // FANCY_UPSAMPLING
+
+//------------------------------------------------------------------------------
+
+#if !defined(FANCY_UPSAMPLING)
+#define DUAL_SAMPLE_FUNC(FUNC_NAME, FUNC)                                      \
+static void FUNC_NAME(const uint8_t* top_y, const uint8_t* bot_y,              \
+                      const uint8_t* top_u, const uint8_t* top_v,              \
+                      const uint8_t* bot_u, const uint8_t* bot_v,              \
+                      uint8_t* top_dst, uint8_t* bot_dst, int len) {           \
+  const int half_len = len >> 1;                                               \
+  int x;                                                                       \
+  assert(top_dst != NULL);                                                     \
+  {                                                                            \
+    for (x = 0; x < half_len; ++x) {                                           \
+      FUNC(top_y[2 * x + 0], top_u[x], top_v[x], top_dst + 8 * x + 0);         \
+      FUNC(top_y[2 * x + 1], top_u[x], top_v[x], top_dst + 8 * x + 4);         \
+    }                                                                          \
+    if (len & 1) FUNC(top_y[2 * x + 0], top_u[x], top_v[x], top_dst + 8 * x);  \
+  }                                                                            \
+  if (bot_dst != NULL) {                                                       \
+    for (x = 0; x < half_len; ++x) {                                           \
+      FUNC(bot_y[2 * x + 0], bot_u[x], bot_v[x], bot_dst + 8 * x + 0);         \
+      FUNC(bot_y[2 * x + 1], bot_u[x], bot_v[x], bot_dst + 8 * x + 4);         \
+    }                                                                          \
+    if (len & 1) FUNC(bot_y[2 * x + 0], bot_u[x], bot_v[x], bot_dst + 8 * x);  \
+  }                                                                            \
+}
+
+DUAL_SAMPLE_FUNC(DualLineSamplerBGRA, VP8YuvToBgra)
+DUAL_SAMPLE_FUNC(DualLineSamplerARGB, VP8YuvToArgb)
+#undef DUAL_SAMPLE_FUNC
+
+#endif  // !FANCY_UPSAMPLING
+
+WebPUpsampleLinePairFunc WebPGetLinePairConverter(int alpha_is_last) {
+  WebPInitUpsamplers();
+  VP8YUVInit();
+#ifdef FANCY_UPSAMPLING
+  return WebPUpsamplers[alpha_is_last ? MODE_BGRA : MODE_ARGB];
+#else
+  return (alpha_is_last ? DualLineSamplerBGRA : DualLineSamplerARGB);
+#endif
+}
+
+//------------------------------------------------------------------------------
+// YUV444 converter
+
+#define YUV444_FUNC(FUNC_NAME, FUNC, XSTEP)                                    \
+static void FUNC_NAME(const uint8_t* y, const uint8_t* u, const uint8_t* v,    \
+                      uint8_t* dst, int len) {                                 \
+  int i;                                                                       \
+  for (i = 0; i < len; ++i) FUNC(y[i], u[i], v[i], &dst[i * XSTEP]);           \
+}
+
+YUV444_FUNC(Yuv444ToRgb,      VP8YuvToRgb,  3)
+YUV444_FUNC(Yuv444ToBgr,      VP8YuvToBgr,  3)
+YUV444_FUNC(Yuv444ToRgba,     VP8YuvToRgba, 4)
+YUV444_FUNC(Yuv444ToBgra,     VP8YuvToBgra, 4)
+YUV444_FUNC(Yuv444ToArgb,     VP8YuvToArgb, 4)
+YUV444_FUNC(Yuv444ToRgba4444, VP8YuvToRgba4444, 2)
+YUV444_FUNC(Yuv444ToRgb565,   VP8YuvToRgb565, 2)
+
+#undef YUV444_FUNC
+
+WebPYUV444Converter WebPYUV444Converters[MODE_LAST];
+
+extern void WebPInitYUV444ConvertersMIPSdspR2(void);
+
+static volatile VP8CPUInfo upsampling_last_cpuinfo_used1 =
+    (VP8CPUInfo)&upsampling_last_cpuinfo_used1;
+
+WEBP_TSAN_IGNORE_FUNCTION void WebPInitYUV444Converters(void) {
+  if (upsampling_last_cpuinfo_used1 == VP8GetCPUInfo) return;
+
+  WebPYUV444Converters[MODE_RGB]       = Yuv444ToRgb;
+  WebPYUV444Converters[MODE_RGBA]      = Yuv444ToRgba;
+  WebPYUV444Converters[MODE_BGR]       = Yuv444ToBgr;
+  WebPYUV444Converters[MODE_BGRA]      = Yuv444ToBgra;
+  WebPYUV444Converters[MODE_ARGB]      = Yuv444ToArgb;
+  WebPYUV444Converters[MODE_RGBA_4444] = Yuv444ToRgba4444;
+  WebPYUV444Converters[MODE_RGB_565]   = Yuv444ToRgb565;
+  WebPYUV444Converters[MODE_rgbA]      = Yuv444ToRgba;
+  WebPYUV444Converters[MODE_bgrA]      = Yuv444ToBgra;
+  WebPYUV444Converters[MODE_Argb]      = Yuv444ToArgb;
+  WebPYUV444Converters[MODE_rgbA_4444] = Yuv444ToRgba4444;
+
+  if (VP8GetCPUInfo != NULL) {
+#if defined(WEBP_USE_MIPS_DSP_R2)
+    if (VP8GetCPUInfo(kMIPSdspR2)) {
+      WebPInitYUV444ConvertersMIPSdspR2();
+    }
+#endif
+  }
+  upsampling_last_cpuinfo_used1 = VP8GetCPUInfo;
+}
+
+//------------------------------------------------------------------------------
+// Main calls
+
+extern void WebPInitUpsamplersSSE2(void);
+extern void WebPInitUpsamplersNEON(void);
+extern void WebPInitUpsamplersMIPSdspR2(void);
+
+static volatile VP8CPUInfo upsampling_last_cpuinfo_used2 =
+    (VP8CPUInfo)&upsampling_last_cpuinfo_used2;
+
+WEBP_TSAN_IGNORE_FUNCTION void WebPInitUpsamplers(void) {
+  if (upsampling_last_cpuinfo_used2 == VP8GetCPUInfo) return;
+
+#ifdef FANCY_UPSAMPLING
+  WebPUpsamplers[MODE_RGB]       = UpsampleRgbLinePair;
+  WebPUpsamplers[MODE_RGBA]      = UpsampleRgbaLinePair;
+  WebPUpsamplers[MODE_BGR]       = UpsampleBgrLinePair;
+  WebPUpsamplers[MODE_BGRA]      = UpsampleBgraLinePair;
+  WebPUpsamplers[MODE_ARGB]      = UpsampleArgbLinePair;
+  WebPUpsamplers[MODE_RGBA_4444] = UpsampleRgba4444LinePair;
+  WebPUpsamplers[MODE_RGB_565]   = UpsampleRgb565LinePair;
+  WebPUpsamplers[MODE_rgbA]      = UpsampleRgbaLinePair;
+  WebPUpsamplers[MODE_bgrA]      = UpsampleBgraLinePair;
+  WebPUpsamplers[MODE_Argb]      = UpsampleArgbLinePair;
+  WebPUpsamplers[MODE_rgbA_4444] = UpsampleRgba4444LinePair;
+
+  // If defined, use CPUInfo() to overwrite some pointers with faster versions.
+  if (VP8GetCPUInfo != NULL) {
+#if defined(WEBP_USE_SSE2)
+    if (VP8GetCPUInfo(kSSE2)) {
+      WebPInitUpsamplersSSE2();
+    }
+#endif
+#if defined(WEBP_USE_NEON)
+    if (VP8GetCPUInfo(kNEON)) {
+      WebPInitUpsamplersNEON();
+    }
+#endif
+#if defined(WEBP_USE_MIPS_DSP_R2)
+    if (VP8GetCPUInfo(kMIPSdspR2)) {
+      WebPInitUpsamplersMIPSdspR2();
+    }
+#endif
+  }
+#endif  // FANCY_UPSAMPLING
+  upsampling_last_cpuinfo_used2 = VP8GetCPUInfo;
+}
+
+//------------------------------------------------------------------------------
diff --git a/Source/LibWebP/src/dsp/dsp.upsampling_mips_dsp_r2.c b/Source/LibWebP/src/dsp/dsp.upsampling_mips_dsp_r2.c
new file mode 100644
index 0000000..a7864a0
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.upsampling_mips_dsp_r2.c
@@ -0,0 +1,280 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// YUV to RGB upsampling functions.
+//
+// Author(s): Branimir Vasic (branimir.vasic at imgtec.com)
+//            Djordje Pesut  (djordje.pesut at imgtec.com)
+
+#include "./dsp.h"
+
+#if defined(WEBP_USE_MIPS_DSP_R2)
+
+#include "./yuv.h"
+#include <assert.h>
+
+#if !defined(WEBP_YUV_USE_TABLE)
+
+#define YUV_TO_RGB(Y, U, V, R, G, B) do {                                      \
+    const int t1 = kYScale * Y;                                                \
+    const int t2 = kVToG * V;                                                  \
+    R = kVToR * V;                                                             \
+    G = kUToG * U;                                                             \
+    B = kUToB * U;                                                             \
+    R = t1 + R;                                                                \
+    G = t1 - G;                                                                \
+    B = t1 + B;                                                                \
+    R = R + kRCst;                                                             \
+    G = G - t2 + kGCst;                                                        \
+    B = B + kBCst;                                                             \
+    __asm__ volatile (                                                         \
+      "shll_s.w         %["#R"],      %["#R"],        9              \n\t"     \
+      "shll_s.w         %["#G"],      %["#G"],        9              \n\t"     \
+      "shll_s.w         %["#B"],      %["#B"],        9              \n\t"     \
+      "precrqu_s.qb.ph  %["#R"],      %["#R"],        $zero          \n\t"     \
+      "precrqu_s.qb.ph  %["#G"],      %["#G"],        $zero          \n\t"     \
+      "precrqu_s.qb.ph  %["#B"],      %["#B"],        $zero          \n\t"     \
+      "srl              %["#R"],      %["#R"],        24             \n\t"     \
+      "srl              %["#G"],      %["#G"],        24             \n\t"     \
+      "srl              %["#B"],      %["#B"],        24             \n\t"     \
+      : [R]"+r"(R), [G]"+r"(G), [B]"+r"(B)                                     \
+      :                                                                        \
+    );                                                                         \
+  } while (0)
+
+static WEBP_INLINE void YuvToRgb(int y, int u, int v, uint8_t* const rgb) {
+  int r, g, b;
+  YUV_TO_RGB(y, u, v, r, g, b);
+  rgb[0] = r;
+  rgb[1] = g;
+  rgb[2] = b;
+}
+static WEBP_INLINE void YuvToBgr(int y, int u, int v, uint8_t* const bgr) {
+  int r, g, b;
+  YUV_TO_RGB(y, u, v, r, g, b);
+  bgr[0] = b;
+  bgr[1] = g;
+  bgr[2] = r;
+}
+static WEBP_INLINE void YuvToRgb565(int y, int u, int v, uint8_t* const rgb) {
+  int r, g, b;
+  YUV_TO_RGB(y, u, v, r, g, b);
+  {
+    const int rg = (r & 0xf8) | (g >> 5);
+    const int gb = ((g << 3) & 0xe0) | (b >> 3);
+#ifdef WEBP_SWAP_16BIT_CSP
+    rgb[0] = gb;
+    rgb[1] = rg;
+#else
+    rgb[0] = rg;
+    rgb[1] = gb;
+#endif
+  }
+}
+static WEBP_INLINE void YuvToRgba4444(int y, int u, int v,
+                                      uint8_t* const argb) {
+  int r, g, b;
+  YUV_TO_RGB(y, u, v, r, g, b);
+  {
+    const int rg = (r & 0xf0) | (g >> 4);
+    const int ba = (b & 0xf0) | 0x0f;     // overwrite the lower 4 bits
+#ifdef WEBP_SWAP_16BIT_CSP
+    argb[0] = ba;
+    argb[1] = rg;
+#else
+    argb[0] = rg;
+    argb[1] = ba;
+#endif
+   }
+}
+#endif  // WEBP_YUV_USE_TABLE
+
+//-----------------------------------------------------------------------------
+// Alpha handling variants
+
+static WEBP_INLINE void YuvToArgb(uint8_t y, uint8_t u, uint8_t v,
+                                  uint8_t* const argb) {
+  int r, g, b;
+  YUV_TO_RGB(y, u, v, r, g, b);
+  argb[0] = 0xff;
+  argb[1] = r;
+  argb[2] = g;
+  argb[3] = b;
+}
+static WEBP_INLINE void YuvToBgra(uint8_t y, uint8_t u, uint8_t v,
+                                  uint8_t* const bgra) {
+  int r, g, b;
+  YUV_TO_RGB(y, u, v, r, g, b);
+  bgra[0] = b;
+  bgra[1] = g;
+  bgra[2] = r;
+  bgra[3] = 0xff;
+}
+static WEBP_INLINE void YuvToRgba(uint8_t y, uint8_t u, uint8_t v,
+                                  uint8_t* const rgba) {
+  int r, g, b;
+  YUV_TO_RGB(y, u, v, r, g, b);
+  rgba[0] = r;
+  rgba[1] = g;
+  rgba[2] = b;
+  rgba[3] = 0xff;
+}
+
+//------------------------------------------------------------------------------
+// Fancy upsampler
+
+#ifdef FANCY_UPSAMPLING
+
+// Given samples laid out in a square as:
+//  [a b]
+//  [c d]
+// we interpolate u/v as:
+//  ([9*a + 3*b + 3*c +   d    3*a + 9*b + 3*c +   d] + [8 8]) / 16
+//  ([3*a +   b + 9*c + 3*d      a + 3*b + 3*c + 9*d]   [8 8]) / 16
+
+// We process u and v together stashed into 32bit (16bit each).
+#define LOAD_UV(u, v) ((u) | ((v) << 16))
+
+#define UPSAMPLE_FUNC(FUNC_NAME, FUNC, XSTEP)                                  \
+static void FUNC_NAME(const uint8_t* top_y, const uint8_t* bottom_y,           \
+                      const uint8_t* top_u, const uint8_t* top_v,              \
+                      const uint8_t* cur_u, const uint8_t* cur_v,              \
+                      uint8_t* top_dst, uint8_t* bottom_dst, int len) {        \
+  int x;                                                                       \
+  const int last_pixel_pair = (len - 1) >> 1;                                  \
+  uint32_t tl_uv = LOAD_UV(top_u[0], top_v[0]);   /* top-left sample */        \
+  uint32_t l_uv  = LOAD_UV(cur_u[0], cur_v[0]);   /* left-sample */            \
+  assert(top_y != NULL);                                                       \
+  {                                                                            \
+    const uint32_t uv0 = (3 * tl_uv + l_uv + 0x00020002u) >> 2;                \
+    FUNC(top_y[0], uv0 & 0xff, (uv0 >> 16), top_dst);                          \
+  }                                                                            \
+  if (bottom_y != NULL) {                                                      \
+    const uint32_t uv0 = (3 * l_uv + tl_uv + 0x00020002u) >> 2;                \
+    FUNC(bottom_y[0], uv0 & 0xff, (uv0 >> 16), bottom_dst);                    \
+  }                                                                            \
+  for (x = 1; x <= last_pixel_pair; ++x) {                                     \
+    const uint32_t t_uv = LOAD_UV(top_u[x], top_v[x]);  /* top sample */       \
+    const uint32_t uv   = LOAD_UV(cur_u[x], cur_v[x]);  /* sample */           \
+    /* precompute invariant values associated with first and second diagonals*/\
+    const uint32_t avg = tl_uv + t_uv + l_uv + uv + 0x00080008u;               \
+    const uint32_t diag_12 = (avg + 2 * (t_uv + l_uv)) >> 3;                   \
+    const uint32_t diag_03 = (avg + 2 * (tl_uv + uv)) >> 3;                    \
+    {                                                                          \
+      const uint32_t uv0 = (diag_12 + tl_uv) >> 1;                             \
+      const uint32_t uv1 = (diag_03 + t_uv) >> 1;                              \
+      FUNC(top_y[2 * x - 1], uv0 & 0xff, (uv0 >> 16),                          \
+           top_dst + (2 * x - 1) * XSTEP);                                     \
+      FUNC(top_y[2 * x - 0], uv1 & 0xff, (uv1 >> 16),                          \
+           top_dst + (2 * x - 0) * XSTEP);                                     \
+    }                                                                          \
+    if (bottom_y != NULL) {                                                    \
+      const uint32_t uv0 = (diag_03 + l_uv) >> 1;                              \
+      const uint32_t uv1 = (diag_12 + uv) >> 1;                                \
+      FUNC(bottom_y[2 * x - 1], uv0 & 0xff, (uv0 >> 16),                       \
+           bottom_dst + (2 * x - 1) * XSTEP);                                  \
+      FUNC(bottom_y[2 * x + 0], uv1 & 0xff, (uv1 >> 16),                       \
+           bottom_dst + (2 * x + 0) * XSTEP);                                  \
+    }                                                                          \
+    tl_uv = t_uv;                                                              \
+    l_uv = uv;                                                                 \
+  }                                                                            \
+  if (!(len & 1)) {                                                            \
+    {                                                                          \
+      const uint32_t uv0 = (3 * tl_uv + l_uv + 0x00020002u) >> 2;              \
+      FUNC(top_y[len - 1], uv0 & 0xff, (uv0 >> 16),                            \
+           top_dst + (len - 1) * XSTEP);                                       \
+    }                                                                          \
+    if (bottom_y != NULL) {                                                    \
+      const uint32_t uv0 = (3 * l_uv + tl_uv + 0x00020002u) >> 2;              \
+      FUNC(bottom_y[len - 1], uv0 & 0xff, (uv0 >> 16),                         \
+           bottom_dst + (len - 1) * XSTEP);                                    \
+    }                                                                          \
+  }                                                                            \
+}
+
+// All variants implemented.
+UPSAMPLE_FUNC(UpsampleRgbLinePair,      YuvToRgb,      3)
+UPSAMPLE_FUNC(UpsampleBgrLinePair,      YuvToBgr,      3)
+UPSAMPLE_FUNC(UpsampleRgbaLinePair,     YuvToRgba,     4)
+UPSAMPLE_FUNC(UpsampleBgraLinePair,     YuvToBgra,     4)
+UPSAMPLE_FUNC(UpsampleArgbLinePair,     YuvToArgb,     4)
+UPSAMPLE_FUNC(UpsampleRgba4444LinePair, YuvToRgba4444, 2)
+UPSAMPLE_FUNC(UpsampleRgb565LinePair,   YuvToRgb565,   2)
+
+#undef LOAD_UV
+#undef UPSAMPLE_FUNC
+
+#endif  // FANCY_UPSAMPLING
+
+#endif  // WEBP_USE_MIPS_DSP_R2
+
+extern void WebPInitUpsamplersMIPSdspR2(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void WebPInitUpsamplersMIPSdspR2(void) {
+#if defined(WEBP_USE_MIPS_DSP_R2)
+#ifdef FANCY_UPSAMPLING
+  WebPUpsamplers[MODE_RGB]       = UpsampleRgbLinePair;
+  WebPUpsamplers[MODE_RGBA]      = UpsampleRgbaLinePair;
+  WebPUpsamplers[MODE_BGR]       = UpsampleBgrLinePair;
+  WebPUpsamplers[MODE_BGRA]      = UpsampleBgraLinePair;
+  WebPUpsamplers[MODE_ARGB]      = UpsampleArgbLinePair;
+  WebPUpsamplers[MODE_RGBA_4444] = UpsampleRgba4444LinePair;
+  WebPUpsamplers[MODE_RGB_565]   = UpsampleRgb565LinePair;
+  WebPUpsamplers[MODE_rgbA]      = UpsampleRgbaLinePair;
+  WebPUpsamplers[MODE_bgrA]      = UpsampleBgraLinePair;
+  WebPUpsamplers[MODE_Argb]      = UpsampleArgbLinePair;
+  WebPUpsamplers[MODE_rgbA_4444] = UpsampleRgba4444LinePair;
+#endif  // FANCY_UPSAMPLING
+#endif  // WEBP_USE_MIPS_DSP_R2
+}
+
+//------------------------------------------------------------------------------
+// YUV444 converter
+
+#if defined(WEBP_USE_MIPS_DSP_R2)
+
+#define YUV444_FUNC(FUNC_NAME, FUNC, XSTEP)                                    \
+static void FUNC_NAME(const uint8_t* y, const uint8_t* u, const uint8_t* v,    \
+                      uint8_t* dst, int len) {                                 \
+  int i;                                                                       \
+  for (i = 0; i < len; ++i) FUNC(y[i], u[i], v[i], &dst[i * XSTEP]);           \
+}
+
+YUV444_FUNC(Yuv444ToRgb,      YuvToRgb,      3)
+YUV444_FUNC(Yuv444ToBgr,      YuvToBgr,      3)
+YUV444_FUNC(Yuv444ToRgba,     YuvToRgba,     4)
+YUV444_FUNC(Yuv444ToBgra,     YuvToBgra,     4)
+YUV444_FUNC(Yuv444ToArgb,     YuvToArgb,     4)
+YUV444_FUNC(Yuv444ToRgba4444, YuvToRgba4444, 2)
+YUV444_FUNC(Yuv444ToRgb565,   YuvToRgb565,   2)
+
+#undef YUV444_FUNC
+
+#endif  // WEBP_USE_MIPS_DSP_R2
+
+extern void WebPInitYUV444ConvertersMIPSdspR2(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void WebPInitYUV444ConvertersMIPSdspR2(void) {
+#if defined(WEBP_USE_MIPS_DSP_R2)
+  WebPYUV444Converters[MODE_RGB]       = Yuv444ToRgb;
+  WebPYUV444Converters[MODE_RGBA]      = Yuv444ToRgba;
+  WebPYUV444Converters[MODE_BGR]       = Yuv444ToBgr;
+  WebPYUV444Converters[MODE_BGRA]      = Yuv444ToBgra;
+  WebPYUV444Converters[MODE_ARGB]      = Yuv444ToArgb;
+  WebPYUV444Converters[MODE_RGBA_4444] = Yuv444ToRgba4444;
+  WebPYUV444Converters[MODE_RGB_565]   = Yuv444ToRgb565;
+  WebPYUV444Converters[MODE_rgbA]      = Yuv444ToRgba;
+  WebPYUV444Converters[MODE_bgrA]      = Yuv444ToBgra;
+  WebPYUV444Converters[MODE_Argb]      = Yuv444ToArgb;
+  WebPYUV444Converters[MODE_rgbA_4444] = Yuv444ToRgba4444;
+#endif  // WEBP_USE_MIPS_DSP_R2
+}
+
+//------------------------------------------------------------------------------
diff --git a/Source/LibWebP/src/dsp/dsp.upsampling_neon.c b/Source/LibWebP/src/dsp/dsp.upsampling_neon.c
new file mode 100644
index 0000000..f41d44c
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.upsampling_neon.c
@@ -0,0 +1,267 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// NEON version of YUV to RGB upsampling functions.
+//
+// Author: mans at mansr.com (Mans Rullgard)
+// Based on SSE code by: somnath at google.com (Somnath Banerjee)
+
+#include "./dsp.h"
+
+#if defined(WEBP_USE_NEON)
+
+#include <assert.h>
+#include <arm_neon.h>
+#include <string.h>
+#include "./neon.h"
+#include "./yuv.h"
+
+#ifdef FANCY_UPSAMPLING
+
+//-----------------------------------------------------------------------------
+// U/V upsampling
+
+// Loads 9 pixels each from rows r1 and r2 and generates 16 pixels.
+#define UPSAMPLE_16PIXELS(r1, r2, out) {                                \
+  uint8x8_t a = vld1_u8(r1);                                            \
+  uint8x8_t b = vld1_u8(r1 + 1);                                        \
+  uint8x8_t c = vld1_u8(r2);                                            \
+  uint8x8_t d = vld1_u8(r2 + 1);                                        \
+                                                                        \
+  uint16x8_t al = vshll_n_u8(a, 1);                                     \
+  uint16x8_t bl = vshll_n_u8(b, 1);                                     \
+  uint16x8_t cl = vshll_n_u8(c, 1);                                     \
+  uint16x8_t dl = vshll_n_u8(d, 1);                                     \
+                                                                        \
+  uint8x8_t diag1, diag2;                                               \
+  uint16x8_t sl;                                                        \
+                                                                        \
+  /* a + b + c + d */                                                   \
+  sl = vaddl_u8(a,  b);                                                 \
+  sl = vaddw_u8(sl, c);                                                 \
+  sl = vaddw_u8(sl, d);                                                 \
+                                                                        \
+  al = vaddq_u16(sl, al); /* 3a +  b +  c +  d */                       \
+  bl = vaddq_u16(sl, bl); /*  a + 3b +  c +  d */                       \
+                                                                        \
+  al = vaddq_u16(al, dl); /* 3a +  b +  c + 3d */                       \
+  bl = vaddq_u16(bl, cl); /*  a + 3b + 3c +  d */                       \
+                                                                        \
+  diag2 = vshrn_n_u16(al, 3);                                           \
+  diag1 = vshrn_n_u16(bl, 3);                                           \
+                                                                        \
+  a = vrhadd_u8(a, diag1);                                              \
+  b = vrhadd_u8(b, diag2);                                              \
+  c = vrhadd_u8(c, diag2);                                              \
+  d = vrhadd_u8(d, diag1);                                              \
+                                                                        \
+  {                                                                     \
+    uint8x8x2_t a_b, c_d;                                               \
+    INIT_VECTOR2(a_b, a, b);                                            \
+    INIT_VECTOR2(c_d, c, d);                                            \
+    vst2_u8(out,      a_b);                                             \
+    vst2_u8(out + 32, c_d);                                             \
+  }                                                                     \
+}
+
+// Turn the macro into a function for reducing code-size when non-critical
+static void Upsample16Pixels(const uint8_t *r1, const uint8_t *r2,
+                             uint8_t *out) {
+  UPSAMPLE_16PIXELS(r1, r2, out);
+}
+
+#define UPSAMPLE_LAST_BLOCK(tb, bb, num_pixels, out) {                  \
+  uint8_t r1[9], r2[9];                                                 \
+  memcpy(r1, (tb), (num_pixels));                                       \
+  memcpy(r2, (bb), (num_pixels));                                       \
+  /* replicate last byte */                                             \
+  memset(r1 + (num_pixels), r1[(num_pixels) - 1], 9 - (num_pixels));    \
+  memset(r2 + (num_pixels), r2[(num_pixels) - 1], 9 - (num_pixels));    \
+  Upsample16Pixels(r1, r2, out);                                        \
+}
+
+//-----------------------------------------------------------------------------
+// YUV->RGB conversion
+
+static const int16_t kCoeffs[4] = { kYScale, kVToR, kUToG, kVToG };
+
+#define v255 vdup_n_u8(255)
+
+#define STORE_Rgb(out, r, g, b) do {                                    \
+  uint8x8x3_t r_g_b;                                                    \
+  INIT_VECTOR3(r_g_b, r, g, b);                                         \
+  vst3_u8(out, r_g_b);                                                  \
+} while (0)
+
+#define STORE_Bgr(out, r, g, b) do {                                    \
+  uint8x8x3_t b_g_r;                                                    \
+  INIT_VECTOR3(b_g_r, b, g, r);                                         \
+  vst3_u8(out, b_g_r);                                                  \
+} while (0)
+
+#define STORE_Rgba(out, r, g, b) do {                                   \
+  uint8x8x4_t r_g_b_v255;                                               \
+  INIT_VECTOR4(r_g_b_v255, r, g, b, v255);                              \
+  vst4_u8(out, r_g_b_v255);                                             \
+} while (0)
+
+#define STORE_Bgra(out, r, g, b) do {                                   \
+  uint8x8x4_t b_g_r_v255;                                               \
+  INIT_VECTOR4(b_g_r_v255, b, g, r, v255);                              \
+  vst4_u8(out, b_g_r_v255);                                             \
+} while (0)
+
+#define CONVERT8(FMT, XSTEP, N, src_y, src_uv, out, cur_x) {            \
+  int i;                                                                \
+  for (i = 0; i < N; i += 8) {                                          \
+    const int off = ((cur_x) + i) * XSTEP;                              \
+    uint8x8_t y  = vld1_u8((src_y) + (cur_x)  + i);                     \
+    uint8x8_t u  = vld1_u8((src_uv) + i);                               \
+    uint8x8_t v  = vld1_u8((src_uv) + i + 16);                          \
+    const int16x8_t yy = vreinterpretq_s16_u16(vsubl_u8(y, u16));       \
+    const int16x8_t uu = vreinterpretq_s16_u16(vsubl_u8(u, u128));      \
+    const int16x8_t vv = vreinterpretq_s16_u16(vsubl_u8(v, u128));      \
+    int32x4_t yl = vmull_lane_s16(vget_low_s16(yy),  cf16, 0);          \
+    int32x4_t yh = vmull_lane_s16(vget_high_s16(yy), cf16, 0);          \
+    const int32x4_t rl = vmlal_lane_s16(yl, vget_low_s16(vv),  cf16, 1);\
+    const int32x4_t rh = vmlal_lane_s16(yh, vget_high_s16(vv), cf16, 1);\
+    int32x4_t gl = vmlsl_lane_s16(yl, vget_low_s16(uu),  cf16, 2);      \
+    int32x4_t gh = vmlsl_lane_s16(yh, vget_high_s16(uu), cf16, 2);      \
+    const int32x4_t bl = vmovl_s16(vget_low_s16(uu));                   \
+    const int32x4_t bh = vmovl_s16(vget_high_s16(uu));                  \
+    gl = vmlsl_lane_s16(gl, vget_low_s16(vv),  cf16, 3);                \
+    gh = vmlsl_lane_s16(gh, vget_high_s16(vv), cf16, 3);                \
+    yl = vmlaq_lane_s32(yl, bl, cf32, 0);                               \
+    yh = vmlaq_lane_s32(yh, bh, cf32, 0);                               \
+    /* vrshrn_n_s32() already incorporates the rounding constant */     \
+    y = vqmovun_s16(vcombine_s16(vrshrn_n_s32(rl, YUV_FIX2),            \
+                                 vrshrn_n_s32(rh, YUV_FIX2)));          \
+    u = vqmovun_s16(vcombine_s16(vrshrn_n_s32(gl, YUV_FIX2),            \
+                                 vrshrn_n_s32(gh, YUV_FIX2)));          \
+    v = vqmovun_s16(vcombine_s16(vrshrn_n_s32(yl, YUV_FIX2),            \
+                                 vrshrn_n_s32(yh, YUV_FIX2)));          \
+    STORE_ ## FMT(out + off, y, u, v);                                  \
+  }                                                                     \
+}
+
+#define CONVERT1(FUNC, XSTEP, N, src_y, src_uv, rgb, cur_x) {           \
+  int i;                                                                \
+  for (i = 0; i < N; i++) {                                             \
+    const int off = ((cur_x) + i) * XSTEP;                              \
+    const int y = src_y[(cur_x) + i];                                   \
+    const int u = (src_uv)[i];                                          \
+    const int v = (src_uv)[i + 16];                                     \
+    FUNC(y, u, v, rgb + off);                                           \
+  }                                                                     \
+}
+
+#define CONVERT2RGB_8(FMT, XSTEP, top_y, bottom_y, uv,                  \
+                      top_dst, bottom_dst, cur_x, len) {                \
+  CONVERT8(FMT, XSTEP, len, top_y, uv, top_dst, cur_x)                  \
+  if (bottom_y != NULL) {                                               \
+    CONVERT8(FMT, XSTEP, len, bottom_y, (uv) + 32, bottom_dst, cur_x)   \
+  }                                                                     \
+}
+
+#define CONVERT2RGB_1(FUNC, XSTEP, top_y, bottom_y, uv,                 \
+                      top_dst, bottom_dst, cur_x, len) {                \
+  CONVERT1(FUNC, XSTEP, len, top_y, uv, top_dst, cur_x);                \
+  if (bottom_y != NULL) {                                               \
+    CONVERT1(FUNC, XSTEP, len, bottom_y, (uv) + 32, bottom_dst, cur_x); \
+  }                                                                     \
+}
+
+#define NEON_UPSAMPLE_FUNC(FUNC_NAME, FMT, XSTEP)                       \
+static void FUNC_NAME(const uint8_t *top_y, const uint8_t *bottom_y,    \
+                      const uint8_t *top_u, const uint8_t *top_v,       \
+                      const uint8_t *cur_u, const uint8_t *cur_v,       \
+                      uint8_t *top_dst, uint8_t *bottom_dst, int len) { \
+  int block;                                                            \
+  /* 16 byte aligned array to cache reconstructed u and v */            \
+  uint8_t uv_buf[2 * 32 + 15];                                          \
+  uint8_t *const r_uv = (uint8_t*)((uintptr_t)(uv_buf + 15) & ~15);     \
+  const int uv_len = (len + 1) >> 1;                                    \
+  /* 9 pixels must be read-able for each block */                       \
+  const int num_blocks = (uv_len - 1) >> 3;                             \
+  const int leftover = uv_len - num_blocks * 8;                         \
+  const int last_pos = 1 + 16 * num_blocks;                             \
+                                                                        \
+  const int u_diag = ((top_u[0] + cur_u[0]) >> 1) + 1;                  \
+  const int v_diag = ((top_v[0] + cur_v[0]) >> 1) + 1;                  \
+                                                                        \
+  const int16x4_t cf16 = vld1_s16(kCoeffs);                             \
+  const int32x2_t cf32 = vdup_n_s32(kUToB);                             \
+  const uint8x8_t u16  = vdup_n_u8(16);                                 \
+  const uint8x8_t u128 = vdup_n_u8(128);                                \
+                                                                        \
+  /* Treat the first pixel in regular way */                            \
+  assert(top_y != NULL);                                                \
+  {                                                                     \
+    const int u0 = (top_u[0] + u_diag) >> 1;                            \
+    const int v0 = (top_v[0] + v_diag) >> 1;                            \
+    VP8YuvTo ## FMT(top_y[0], u0, v0, top_dst);                         \
+  }                                                                     \
+  if (bottom_y != NULL) {                                               \
+    const int u0 = (cur_u[0] + u_diag) >> 1;                            \
+    const int v0 = (cur_v[0] + v_diag) >> 1;                            \
+    VP8YuvTo ## FMT(bottom_y[0], u0, v0, bottom_dst);                   \
+  }                                                                     \
+                                                                        \
+  for (block = 0; block < num_blocks; ++block) {                        \
+    UPSAMPLE_16PIXELS(top_u, cur_u, r_uv);                              \
+    UPSAMPLE_16PIXELS(top_v, cur_v, r_uv + 16);                         \
+    CONVERT2RGB_8(FMT, XSTEP, top_y, bottom_y, r_uv,                    \
+                  top_dst, bottom_dst, 16 * block + 1, 16);             \
+    top_u += 8;                                                         \
+    cur_u += 8;                                                         \
+    top_v += 8;                                                         \
+    cur_v += 8;                                                         \
+  }                                                                     \
+                                                                        \
+  UPSAMPLE_LAST_BLOCK(top_u, cur_u, leftover, r_uv);                    \
+  UPSAMPLE_LAST_BLOCK(top_v, cur_v, leftover, r_uv + 16);               \
+  CONVERT2RGB_1(VP8YuvTo ## FMT, XSTEP, top_y, bottom_y, r_uv,          \
+                top_dst, bottom_dst, last_pos, len - last_pos);         \
+}
+
+// NEON variants of the fancy upsampler.
+NEON_UPSAMPLE_FUNC(UpsampleRgbLinePair,  Rgb,  3)
+NEON_UPSAMPLE_FUNC(UpsampleBgrLinePair,  Bgr,  3)
+NEON_UPSAMPLE_FUNC(UpsampleRgbaLinePair, Rgba, 4)
+NEON_UPSAMPLE_FUNC(UpsampleBgraLinePair, Bgra, 4)
+
+#endif  // FANCY_UPSAMPLING
+
+#endif   // WEBP_USE_NEON
+
+//------------------------------------------------------------------------------
+
+extern void WebPInitUpsamplersNEON(void);
+
+#ifdef FANCY_UPSAMPLING
+
+extern WebPUpsampleLinePairFunc WebPUpsamplers[/* MODE_LAST */];
+
+WEBP_TSAN_IGNORE_FUNCTION void WebPInitUpsamplersNEON(void) {
+#if defined(WEBP_USE_NEON)
+  WebPUpsamplers[MODE_RGB]  = UpsampleRgbLinePair;
+  WebPUpsamplers[MODE_RGBA] = UpsampleRgbaLinePair;
+  WebPUpsamplers[MODE_BGR]  = UpsampleBgrLinePair;
+  WebPUpsamplers[MODE_BGRA] = UpsampleBgraLinePair;
+  WebPUpsamplers[MODE_rgbA] = UpsampleRgbaLinePair;
+  WebPUpsamplers[MODE_bgrA] = UpsampleBgraLinePair;
+#endif   // WEBP_USE_NEON
+}
+
+#else
+
+// this empty function is to avoid an empty .o
+WEBP_TSAN_IGNORE_FUNCTION void WebPInitUpsamplersNEON(void) {}
+
+#endif  // FANCY_UPSAMPLING
diff --git a/Source/LibWebP/src/dsp/dsp.upsampling_sse2.c b/Source/LibWebP/src/dsp/dsp.upsampling_sse2.c
new file mode 100644
index 0000000..d1b3314
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.upsampling_sse2.c
@@ -0,0 +1,214 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// SSE2 version of YUV to RGB upsampling functions.
+//
+// Author: somnath at google.com (Somnath Banerjee)
+
+#include "./dsp.h"
+
+#if defined(WEBP_USE_SSE2)
+
+#include <assert.h>
+#include <emmintrin.h>
+#include <string.h>
+#include "./yuv.h"
+
+#ifdef FANCY_UPSAMPLING
+
+// We compute (9*a + 3*b + 3*c + d + 8) / 16 as follows
+// u = (9*a + 3*b + 3*c + d + 8) / 16
+//   = (a + (a + 3*b + 3*c + d) / 8 + 1) / 2
+//   = (a + m + 1) / 2
+// where m = (a + 3*b + 3*c + d) / 8
+//         = ((a + b + c + d) / 2 + b + c) / 4
+//
+// Let's say  k = (a + b + c + d) / 4.
+// We can compute k as
+// k = (s + t + 1) / 2 - ((a^d) | (b^c) | (s^t)) & 1
+// where s = (a + d + 1) / 2 and t = (b + c + 1) / 2
+//
+// Then m can be written as
+// m = (k + t + 1) / 2 - (((b^c) & (s^t)) | (k^t)) & 1
+
+// Computes out = (k + in + 1) / 2 - ((ij & (s^t)) | (k^in)) & 1
+#define GET_M(ij, in, out) do {                                                \
+  const __m128i tmp0 = _mm_avg_epu8(k, (in));     /* (k + in + 1) / 2 */       \
+  const __m128i tmp1 = _mm_and_si128((ij), st);   /* (ij) & (s^t) */           \
+  const __m128i tmp2 = _mm_xor_si128(k, (in));    /* (k^in) */                 \
+  const __m128i tmp3 = _mm_or_si128(tmp1, tmp2);  /* ((ij) & (s^t)) | (k^in) */\
+  const __m128i tmp4 = _mm_and_si128(tmp3, one);  /* & 1 -> lsb_correction */  \
+  (out) = _mm_sub_epi8(tmp0, tmp4);    /* (k + in + 1) / 2 - lsb_correction */ \
+} while (0)
+
+// pack and store two alternating pixel rows
+#define PACK_AND_STORE(a, b, da, db, out) do {                                 \
+  const __m128i t_a = _mm_avg_epu8(a, da);  /* (9a + 3b + 3c +  d + 8) / 16 */ \
+  const __m128i t_b = _mm_avg_epu8(b, db);  /* (3a + 9b +  c + 3d + 8) / 16 */ \
+  const __m128i t_1 = _mm_unpacklo_epi8(t_a, t_b);                             \
+  const __m128i t_2 = _mm_unpackhi_epi8(t_a, t_b);                             \
+  _mm_store_si128(((__m128i*)(out)) + 0, t_1);                                 \
+  _mm_store_si128(((__m128i*)(out)) + 1, t_2);                                 \
+} while (0)
+
+// Loads 17 pixels each from rows r1 and r2 and generates 32 pixels.
+#define UPSAMPLE_32PIXELS(r1, r2, out) {                                       \
+  const __m128i one = _mm_set1_epi8(1);                                        \
+  const __m128i a = _mm_loadu_si128((const __m128i*)&(r1)[0]);                 \
+  const __m128i b = _mm_loadu_si128((const __m128i*)&(r1)[1]);                 \
+  const __m128i c = _mm_loadu_si128((const __m128i*)&(r2)[0]);                 \
+  const __m128i d = _mm_loadu_si128((const __m128i*)&(r2)[1]);                 \
+                                                                               \
+  const __m128i s = _mm_avg_epu8(a, d);        /* s = (a + d + 1) / 2 */       \
+  const __m128i t = _mm_avg_epu8(b, c);        /* t = (b + c + 1) / 2 */       \
+  const __m128i st = _mm_xor_si128(s, t);      /* st = s^t */                  \
+                                                                               \
+  const __m128i ad = _mm_xor_si128(a, d);      /* ad = a^d */                  \
+  const __m128i bc = _mm_xor_si128(b, c);      /* bc = b^c */                  \
+                                                                               \
+  const __m128i t1 = _mm_or_si128(ad, bc);     /* (a^d) | (b^c) */             \
+  const __m128i t2 = _mm_or_si128(t1, st);     /* (a^d) | (b^c) | (s^t) */     \
+  const __m128i t3 = _mm_and_si128(t2, one);   /* (a^d) | (b^c) | (s^t) & 1 */ \
+  const __m128i t4 = _mm_avg_epu8(s, t);                                       \
+  const __m128i k = _mm_sub_epi8(t4, t3);      /* k = (a + b + c + d) / 4 */   \
+  __m128i diag1, diag2;                                                        \
+                                                                               \
+  GET_M(bc, t, diag1);                  /* diag1 = (a + 3b + 3c + d) / 8 */    \
+  GET_M(ad, s, diag2);                  /* diag2 = (3a + b + c + 3d) / 8 */    \
+                                                                               \
+  /* pack the alternate pixels */                                              \
+  PACK_AND_STORE(a, b, diag1, diag2, out +      0);  /* store top */           \
+  PACK_AND_STORE(c, d, diag2, diag1, out + 2 * 32);  /* store bottom */        \
+}
+
+// Turn the macro into a function for reducing code-size when non-critical
+static void Upsample32Pixels(const uint8_t r1[], const uint8_t r2[],
+                             uint8_t* const out) {
+  UPSAMPLE_32PIXELS(r1, r2, out);
+}
+
+#define UPSAMPLE_LAST_BLOCK(tb, bb, num_pixels, out) {                         \
+  uint8_t r1[17], r2[17];                                                      \
+  memcpy(r1, (tb), (num_pixels));                                              \
+  memcpy(r2, (bb), (num_pixels));                                              \
+  /* replicate last byte */                                                    \
+  memset(r1 + (num_pixels), r1[(num_pixels) - 1], 17 - (num_pixels));          \
+  memset(r2 + (num_pixels), r2[(num_pixels) - 1], 17 - (num_pixels));          \
+  /* using the shared function instead of the macro saves ~3k code size */     \
+  Upsample32Pixels(r1, r2, out);                                               \
+}
+
+#define CONVERT2RGB(FUNC, XSTEP, top_y, bottom_y,                              \
+                    top_dst, bottom_dst, cur_x, num_pixels) {                  \
+  int n;                                                                       \
+  for (n = 0; n < (num_pixels); ++n) {                                         \
+    FUNC(top_y[(cur_x) + n], r_u[n], r_v[n],                                   \
+         top_dst + ((cur_x) + n) * XSTEP);                                     \
+  }                                                                            \
+  if (bottom_y != NULL) {                                                      \
+    for (n = 0; n < (num_pixels); ++n) {                                       \
+      FUNC(bottom_y[(cur_x) + n], r_u[64 + n], r_v[64 + n],                    \
+           bottom_dst + ((cur_x) + n) * XSTEP);                                \
+    }                                                                          \
+  }                                                                            \
+}
+
+#define CONVERT2RGB_32(FUNC, XSTEP, top_y, bottom_y,                           \
+                       top_dst, bottom_dst, cur_x) do {                        \
+  FUNC##32(top_y + (cur_x), r_u, r_v, top_dst + (cur_x) * XSTEP);              \
+  if (bottom_y != NULL) {                                                      \
+    FUNC##32(bottom_y + (cur_x), r_u + 64, r_v + 64,                           \
+             bottom_dst + (cur_x) * XSTEP);                                    \
+  }                                                                            \
+} while (0)
+
+#define SSE2_UPSAMPLE_FUNC(FUNC_NAME, FUNC, XSTEP)                             \
+static void FUNC_NAME(const uint8_t* top_y, const uint8_t* bottom_y,           \
+                      const uint8_t* top_u, const uint8_t* top_v,              \
+                      const uint8_t* cur_u, const uint8_t* cur_v,              \
+                      uint8_t* top_dst, uint8_t* bottom_dst, int len) {        \
+  int uv_pos, pos;                                                             \
+  /* 16byte-aligned array to cache reconstructed u and v */                    \
+  uint8_t uv_buf[4 * 32 + 15];                                                 \
+  uint8_t* const r_u = (uint8_t*)((uintptr_t)(uv_buf + 15) & ~15);             \
+  uint8_t* const r_v = r_u + 32;                                               \
+                                                                               \
+  assert(top_y != NULL);                                                       \
+  {   /* Treat the first pixel in regular way */                               \
+    const int u_diag = ((top_u[0] + cur_u[0]) >> 1) + 1;                       \
+    const int v_diag = ((top_v[0] + cur_v[0]) >> 1) + 1;                       \
+    const int u0_t = (top_u[0] + u_diag) >> 1;                                 \
+    const int v0_t = (top_v[0] + v_diag) >> 1;                                 \
+    FUNC(top_y[0], u0_t, v0_t, top_dst);                                       \
+    if (bottom_y != NULL) {                                                    \
+      const int u0_b = (cur_u[0] + u_diag) >> 1;                               \
+      const int v0_b = (cur_v[0] + v_diag) >> 1;                               \
+      FUNC(bottom_y[0], u0_b, v0_b, bottom_dst);                               \
+    }                                                                          \
+  }                                                                            \
+  /* For UPSAMPLE_32PIXELS, 17 u/v values must be read-able for each block */  \
+  for (pos = 1, uv_pos = 0; pos + 32 + 1 <= len; pos += 32, uv_pos += 16) {    \
+    UPSAMPLE_32PIXELS(top_u + uv_pos, cur_u + uv_pos, r_u);                    \
+    UPSAMPLE_32PIXELS(top_v + uv_pos, cur_v + uv_pos, r_v);                    \
+    CONVERT2RGB_32(FUNC, XSTEP, top_y, bottom_y, top_dst, bottom_dst, pos);    \
+  }                                                                            \
+  if (len > 1) {                                                               \
+    const int left_over = ((len + 1) >> 1) - (pos >> 1);                       \
+    assert(left_over > 0);                                                     \
+    UPSAMPLE_LAST_BLOCK(top_u + uv_pos, cur_u + uv_pos, left_over, r_u);       \
+    UPSAMPLE_LAST_BLOCK(top_v + uv_pos, cur_v + uv_pos, left_over, r_v);       \
+    CONVERT2RGB(FUNC, XSTEP, top_y, bottom_y, top_dst, bottom_dst,             \
+                pos, len - pos);                                               \
+  }                                                                            \
+}
+
+// SSE2 variants of the fancy upsampler.
+SSE2_UPSAMPLE_FUNC(UpsampleRgbLinePair,  VP8YuvToRgb,  3)
+SSE2_UPSAMPLE_FUNC(UpsampleBgrLinePair,  VP8YuvToBgr,  3)
+SSE2_UPSAMPLE_FUNC(UpsampleRgbaLinePair, VP8YuvToRgba, 4)
+SSE2_UPSAMPLE_FUNC(UpsampleBgraLinePair, VP8YuvToBgra, 4)
+
+#undef GET_M
+#undef PACK_AND_STORE
+#undef UPSAMPLE_32PIXELS
+#undef UPSAMPLE_LAST_BLOCK
+#undef CONVERT2RGB
+#undef CONVERT2RGB_32
+#undef SSE2_UPSAMPLE_FUNC
+
+#endif  // FANCY_UPSAMPLING
+
+#endif   // WEBP_USE_SSE2
+
+//------------------------------------------------------------------------------
+
+extern void WebPInitUpsamplersSSE2(void);
+
+#ifdef FANCY_UPSAMPLING
+
+extern WebPUpsampleLinePairFunc WebPUpsamplers[/* MODE_LAST */];
+
+WEBP_TSAN_IGNORE_FUNCTION void WebPInitUpsamplersSSE2(void) {
+#if defined(WEBP_USE_SSE2)
+  VP8YUVInitSSE2();
+  WebPUpsamplers[MODE_RGB]  = UpsampleRgbLinePair;
+  WebPUpsamplers[MODE_RGBA] = UpsampleRgbaLinePair;
+  WebPUpsamplers[MODE_BGR]  = UpsampleBgrLinePair;
+  WebPUpsamplers[MODE_BGRA] = UpsampleBgraLinePair;
+  WebPUpsamplers[MODE_rgbA] = UpsampleRgbaLinePair;
+  WebPUpsamplers[MODE_bgrA] = UpsampleBgraLinePair;
+#endif   // WEBP_USE_SSE2
+}
+
+#else
+
+// this empty function is to avoid an empty .o
+WEBP_TSAN_IGNORE_FUNCTION void WebPInitUpsamplersSSE2(void) {}
+
+#endif  // FANCY_UPSAMPLING
diff --git a/Source/LibWebP/src/dsp/dsp.yuv.c b/Source/LibWebP/src/dsp/dsp.yuv.c
new file mode 100644
index 0000000..8a907ae
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.yuv.c
@@ -0,0 +1,166 @@
+// Copyright 2010 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// YUV->RGB conversion functions
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include "./yuv.h"
+
+#if defined(WEBP_YUV_USE_TABLE)
+
+static int done = 0;
+
+static WEBP_INLINE uint8_t clip(int v, int max_value) {
+  return v < 0 ? 0 : v > max_value ? max_value : v;
+}
+
+int16_t VP8kVToR[256], VP8kUToB[256];
+int32_t VP8kVToG[256], VP8kUToG[256];
+uint8_t VP8kClip[YUV_RANGE_MAX - YUV_RANGE_MIN];
+uint8_t VP8kClip4Bits[YUV_RANGE_MAX - YUV_RANGE_MIN];
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8YUVInit(void) {
+  int i;
+  if (done) {
+    return;
+  }
+#ifndef USE_YUVj
+  for (i = 0; i < 256; ++i) {
+    VP8kVToR[i] = (89858 * (i - 128) + YUV_HALF) >> YUV_FIX;
+    VP8kUToG[i] = -22014 * (i - 128) + YUV_HALF;
+    VP8kVToG[i] = -45773 * (i - 128);
+    VP8kUToB[i] = (113618 * (i - 128) + YUV_HALF) >> YUV_FIX;
+  }
+  for (i = YUV_RANGE_MIN; i < YUV_RANGE_MAX; ++i) {
+    const int k = ((i - 16) * 76283 + YUV_HALF) >> YUV_FIX;
+    VP8kClip[i - YUV_RANGE_MIN] = clip(k, 255);
+    VP8kClip4Bits[i - YUV_RANGE_MIN] = clip((k + 8) >> 4, 15);
+  }
+#else
+  for (i = 0; i < 256; ++i) {
+    VP8kVToR[i] = (91881 * (i - 128) + YUV_HALF) >> YUV_FIX;
+    VP8kUToG[i] = -22554 * (i - 128) + YUV_HALF;
+    VP8kVToG[i] = -46802 * (i - 128);
+    VP8kUToB[i] = (116130 * (i - 128) + YUV_HALF) >> YUV_FIX;
+  }
+  for (i = YUV_RANGE_MIN; i < YUV_RANGE_MAX; ++i) {
+    const int k = i;
+    VP8kClip[i - YUV_RANGE_MIN] = clip(k, 255);
+    VP8kClip4Bits[i - YUV_RANGE_MIN] = clip((k + 8) >> 4, 15);
+  }
+#endif
+
+  done = 1;
+}
+
+#else
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8YUVInit(void) {}
+
+#endif  // WEBP_YUV_USE_TABLE
+
+//-----------------------------------------------------------------------------
+// Plain-C version
+
+#define ROW_FUNC(FUNC_NAME, FUNC, XSTEP)                                       \
+static void FUNC_NAME(const uint8_t* y,                                        \
+                      const uint8_t* u, const uint8_t* v,                      \
+                      uint8_t* dst, int len) {                                 \
+  const uint8_t* const end = dst + (len & ~1) * XSTEP;                         \
+  while (dst != end) {                                                         \
+    FUNC(y[0], u[0], v[0], dst);                                               \
+    FUNC(y[1], u[0], v[0], dst + XSTEP);                                       \
+    y += 2;                                                                    \
+    ++u;                                                                       \
+    ++v;                                                                       \
+    dst += 2 * XSTEP;                                                          \
+  }                                                                            \
+  if (len & 1) {                                                               \
+    FUNC(y[0], u[0], v[0], dst);                                               \
+  }                                                                            \
+}                                                                              \
+
+// All variants implemented.
+ROW_FUNC(YuvToRgbRow,      VP8YuvToRgb,  3)
+ROW_FUNC(YuvToBgrRow,      VP8YuvToBgr,  3)
+ROW_FUNC(YuvToRgbaRow,     VP8YuvToRgba, 4)
+ROW_FUNC(YuvToBgraRow,     VP8YuvToBgra, 4)
+ROW_FUNC(YuvToArgbRow,     VP8YuvToArgb, 4)
+ROW_FUNC(YuvToRgba4444Row, VP8YuvToRgba4444, 2)
+ROW_FUNC(YuvToRgb565Row,   VP8YuvToRgb565, 2)
+
+#undef ROW_FUNC
+
+// Main call for processing a plane with a WebPSamplerRowFunc function:
+void WebPSamplerProcessPlane(const uint8_t* y, int y_stride,
+                             const uint8_t* u, const uint8_t* v, int uv_stride,
+                             uint8_t* dst, int dst_stride,
+                             int width, int height, WebPSamplerRowFunc func) {
+  int j;
+  for (j = 0; j < height; ++j) {
+    func(y, u, v, dst, width);
+    y += y_stride;
+    if (j & 1) {
+      u += uv_stride;
+      v += uv_stride;
+    }
+    dst += dst_stride;
+  }
+}
+
+//-----------------------------------------------------------------------------
+// Main call
+
+WebPSamplerRowFunc WebPSamplers[MODE_LAST];
+
+extern void WebPInitSamplersSSE2(void);
+extern void WebPInitSamplersMIPS32(void);
+extern void WebPInitSamplersMIPSdspR2(void);
+
+static volatile VP8CPUInfo yuv_last_cpuinfo_used =
+    (VP8CPUInfo)&yuv_last_cpuinfo_used;
+
+WEBP_TSAN_IGNORE_FUNCTION void WebPInitSamplers(void) {
+  if (yuv_last_cpuinfo_used == VP8GetCPUInfo) return;
+
+  WebPSamplers[MODE_RGB]       = YuvToRgbRow;
+  WebPSamplers[MODE_RGBA]      = YuvToRgbaRow;
+  WebPSamplers[MODE_BGR]       = YuvToBgrRow;
+  WebPSamplers[MODE_BGRA]      = YuvToBgraRow;
+  WebPSamplers[MODE_ARGB]      = YuvToArgbRow;
+  WebPSamplers[MODE_RGBA_4444] = YuvToRgba4444Row;
+  WebPSamplers[MODE_RGB_565]   = YuvToRgb565Row;
+  WebPSamplers[MODE_rgbA]      = YuvToRgbaRow;
+  WebPSamplers[MODE_bgrA]      = YuvToBgraRow;
+  WebPSamplers[MODE_Argb]      = YuvToArgbRow;
+  WebPSamplers[MODE_rgbA_4444] = YuvToRgba4444Row;
+
+  // If defined, use CPUInfo() to overwrite some pointers with faster versions.
+  if (VP8GetCPUInfo != NULL) {
+#if defined(WEBP_USE_SSE2)
+    if (VP8GetCPUInfo(kSSE2)) {
+      WebPInitSamplersSSE2();
+    }
+#endif  // WEBP_USE_SSE2
+#if defined(WEBP_USE_MIPS32)
+    if (VP8GetCPUInfo(kMIPS32)) {
+      WebPInitSamplersMIPS32();
+    }
+#endif  // WEBP_USE_MIPS32
+#if defined(WEBP_USE_MIPS_DSP_R2)
+    if (VP8GetCPUInfo(kMIPSdspR2)) {
+      WebPInitSamplersMIPSdspR2();
+    }
+#endif  // WEBP_USE_MIPS_DSP_R2
+  }
+  yuv_last_cpuinfo_used = VP8GetCPUInfo;
+}
+
+//-----------------------------------------------------------------------------
diff --git a/Source/LibWebP/src/dsp/dsp.yuv_mips32.c b/Source/LibWebP/src/dsp/dsp.yuv_mips32.c
new file mode 100644
index 0000000..6110034
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.yuv_mips32.c
@@ -0,0 +1,100 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// MIPS version of YUV to RGB upsampling functions.
+//
+// Author(s):  Djordje Pesut    (djordje.pesut at imgtec.com)
+//             Jovan Zelincevic (jovan.zelincevic at imgtec.com)
+
+#include "./dsp.h"
+
+#if defined(WEBP_USE_MIPS32)
+
+#include "./yuv.h"
+
+//------------------------------------------------------------------------------
+// simple point-sampling
+
+#define ROW_FUNC(FUNC_NAME, XSTEP, R, G, B, A)                                 \
+static void FUNC_NAME(const uint8_t* y,                                        \
+                      const uint8_t* u, const uint8_t* v,                      \
+                      uint8_t* dst, int len) {                                 \
+  int i, r, g, b;                                                              \
+  int temp0, temp1, temp2, temp3, temp4;                                       \
+  for (i = 0; i < (len >> 1); i++) {                                           \
+    temp1 = kVToR * v[0];                                                      \
+    temp3 = kVToG * v[0];                                                      \
+    temp2 = kUToG * u[0];                                                      \
+    temp4 = kUToB * u[0];                                                      \
+    temp0 = kYScale * y[0];                                                    \
+    temp1 += kRCst;                                                            \
+    temp3 -= kGCst;                                                            \
+    temp2 += temp3;                                                            \
+    temp4 += kBCst;                                                            \
+    r = VP8Clip8(temp0 + temp1);                                               \
+    g = VP8Clip8(temp0 - temp2);                                               \
+    b = VP8Clip8(temp0 + temp4);                                               \
+    temp0 = kYScale * y[1];                                                    \
+    dst[R] = r;                                                                \
+    dst[G] = g;                                                                \
+    dst[B] = b;                                                                \
+    if (A) dst[A] = 0xff;                                                      \
+    r = VP8Clip8(temp0 + temp1);                                               \
+    g = VP8Clip8(temp0 - temp2);                                               \
+    b = VP8Clip8(temp0 + temp4);                                               \
+    dst[R + XSTEP] = r;                                                        \
+    dst[G + XSTEP] = g;                                                        \
+    dst[B + XSTEP] = b;                                                        \
+    if (A) dst[A + XSTEP] = 0xff;                                              \
+    y += 2;                                                                    \
+    ++u;                                                                       \
+    ++v;                                                                       \
+    dst += 2 * XSTEP;                                                          \
+  }                                                                            \
+  if (len & 1) {                                                               \
+    temp1 = kVToR * v[0];                                                      \
+    temp3 = kVToG * v[0];                                                      \
+    temp2 = kUToG * u[0];                                                      \
+    temp4 = kUToB * u[0];                                                      \
+    temp0 = kYScale * y[0];                                                    \
+    temp1 += kRCst;                                                            \
+    temp3 -= kGCst;                                                            \
+    temp2 += temp3;                                                            \
+    temp4 += kBCst;                                                            \
+    r = VP8Clip8(temp0 + temp1);                                               \
+    g = VP8Clip8(temp0 - temp2);                                               \
+    b = VP8Clip8(temp0 + temp4);                                               \
+    dst[R] = r;                                                                \
+    dst[G] = g;                                                                \
+    dst[B] = b;                                                                \
+    if (A) dst[A] = 0xff;                                                      \
+  }                                                                            \
+}
+
+ROW_FUNC(YuvToRgbRow,      3, 0, 1, 2, 0)
+ROW_FUNC(YuvToRgbaRow,     4, 0, 1, 2, 3)
+ROW_FUNC(YuvToBgrRow,      3, 2, 1, 0, 0)
+ROW_FUNC(YuvToBgraRow,     4, 2, 1, 0, 3)
+
+#undef ROW_FUNC
+
+#endif   // WEBP_USE_MIPS32
+
+//------------------------------------------------------------------------------
+
+extern void WebPInitSamplersMIPS32(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void WebPInitSamplersMIPS32(void) {
+#if defined(WEBP_USE_MIPS32)
+  WebPSamplers[MODE_RGB]  = YuvToRgbRow;
+  WebPSamplers[MODE_RGBA] = YuvToRgbaRow;
+  WebPSamplers[MODE_BGR]  = YuvToBgrRow;
+  WebPSamplers[MODE_BGRA] = YuvToBgraRow;
+#endif  // WEBP_USE_MIPS32
+}
diff --git a/Source/LibWebP/src/dsp/dsp.yuv_mips_dsp_r2.c b/Source/LibWebP/src/dsp/dsp.yuv_mips_dsp_r2.c
new file mode 100644
index 0000000..66adde5
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.yuv_mips_dsp_r2.c
@@ -0,0 +1,131 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// MIPS DSPr2 version of YUV to RGB upsampling functions.
+//
+// Author(s):  Branimir Vasic (branimir.vasic at imgtec.com)
+//             Djordje Pesut  (djordje.pesut at imgtec.com)
+
+#include "./dsp.h"
+
+#if defined(WEBP_USE_MIPS_DSP_R2)
+
+#include "./yuv.h"
+
+//------------------------------------------------------------------------------
+// simple point-sampling
+
+#define ROW_FUNC_PART_1()                                                      \
+  "lbu              %[temp3],   0(%[v])                         \n\t"          \
+  "lbu              %[temp4],   0(%[u])                         \n\t"          \
+  "lbu              %[temp0],   0(%[y])                         \n\t"          \
+  "mul              %[temp1],   %[t_con_1],     %[temp3]        \n\t"          \
+  "mul              %[temp3],   %[t_con_2],     %[temp3]        \n\t"          \
+  "mul              %[temp2],   %[t_con_3],     %[temp4]        \n\t"          \
+  "mul              %[temp4],   %[t_con_4],     %[temp4]        \n\t"          \
+  "mul              %[temp0],   %[t_con_5],     %[temp0]        \n\t"          \
+  "addu             %[temp1],   %[temp1],       %[t_con_6]      \n\t"          \
+  "subu             %[temp3],   %[temp3],       %[t_con_7]      \n\t"          \
+  "addu             %[temp2],   %[temp2],       %[temp3]        \n\t"          \
+  "addu             %[temp4],   %[temp4],       %[t_con_8]      \n\t"          \
+
+#define ROW_FUNC_PART_2(R, G, B, K)                                            \
+  "addu             %[temp5],   %[temp0],       %[temp1]        \n\t"          \
+  "subu             %[temp6],   %[temp0],       %[temp2]        \n\t"          \
+  "addu             %[temp7],   %[temp0],       %[temp4]        \n\t"          \
+".if "#K"                                                       \n\t"          \
+  "lbu              %[temp0],   1(%[y])                         \n\t"          \
+".endif                                                         \n\t"          \
+  "shll_s.w         %[temp5],   %[temp5],       9               \n\t"          \
+  "shll_s.w         %[temp6],   %[temp6],       9               \n\t"          \
+".if "#K"                                                       \n\t"          \
+  "mul              %[temp0],   %[t_con_5],     %[temp0]        \n\t"          \
+".endif                                                         \n\t"          \
+  "shll_s.w         %[temp7],   %[temp7],       9               \n\t"          \
+  "precrqu_s.qb.ph  %[temp5],   %[temp5],       $zero           \n\t"          \
+  "precrqu_s.qb.ph  %[temp6],   %[temp6],       $zero           \n\t"          \
+  "precrqu_s.qb.ph  %[temp7],   %[temp7],       $zero           \n\t"          \
+  "srl              %[temp5],   %[temp5],       24              \n\t"          \
+  "srl              %[temp6],   %[temp6],       24              \n\t"          \
+  "srl              %[temp7],   %[temp7],       24              \n\t"          \
+  "sb               %[temp5],   "#R"(%[dst])                    \n\t"          \
+  "sb               %[temp6],   "#G"(%[dst])                    \n\t"          \
+  "sb               %[temp7],   "#B"(%[dst])                    \n\t"          \
+
+#define ASM_CLOBBER_LIST()                                                     \
+  : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),             \
+    [temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),             \
+    [temp6]"=&r"(temp6), [temp7]"=&r"(temp7)                                   \
+  : [t_con_1]"r"(t_con_1), [t_con_2]"r"(t_con_2), [t_con_3]"r"(t_con_3),       \
+    [t_con_4]"r"(t_con_4), [t_con_5]"r"(t_con_5), [t_con_6]"r"(t_con_6),       \
+    [u]"r"(u), [v]"r"(v), [y]"r"(y), [dst]"r"(dst),                            \
+    [t_con_7]"r"(t_con_7), [t_con_8]"r"(t_con_8)                               \
+  : "memory", "hi", "lo"                                                       \
+
+#define ROW_FUNC(FUNC_NAME, XSTEP, R, G, B, A)                                 \
+static void FUNC_NAME(const uint8_t* y,                                        \
+                      const uint8_t* u, const uint8_t* v,                      \
+                      uint8_t* dst, int len) {                                 \
+  int i;                                                                       \
+  uint32_t temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;             \
+  const int t_con_1 = kVToR;                                                   \
+  const int t_con_2 = kVToG;                                                   \
+  const int t_con_3 = kUToG;                                                   \
+  const int t_con_4 = kUToB;                                                   \
+  const int t_con_5 = kYScale;                                                 \
+  const int t_con_6 = kRCst;                                                   \
+  const int t_con_7 = kGCst;                                                   \
+  const int t_con_8 = kBCst;                                                   \
+  for (i = 0; i < (len >> 1); i++) {                                           \
+    __asm__ volatile (                                                         \
+      ROW_FUNC_PART_1()                                                        \
+      ROW_FUNC_PART_2(R, G, B, 1)                                              \
+      ROW_FUNC_PART_2(R + XSTEP, G + XSTEP, B + XSTEP, 0)                      \
+      ASM_CLOBBER_LIST()                                                       \
+    );                                                                         \
+    if (A) dst[A] = dst[A + XSTEP] = 0xff;                                     \
+    y += 2;                                                                    \
+    ++u;                                                                       \
+    ++v;                                                                       \
+    dst += 2 * XSTEP;                                                          \
+  }                                                                            \
+  if (len & 1) {                                                               \
+    __asm__ volatile (                                                         \
+      ROW_FUNC_PART_1()                                                        \
+      ROW_FUNC_PART_2(R, G, B, 0)                                              \
+      ASM_CLOBBER_LIST()                                                       \
+    );                                                                         \
+    if (A) dst[A] = 0xff;                                                      \
+  }                                                                            \
+}
+
+ROW_FUNC(YuvToRgbRow,      3, 0, 1, 2, 0)
+ROW_FUNC(YuvToRgbaRow,     4, 0, 1, 2, 3)
+ROW_FUNC(YuvToBgrRow,      3, 2, 1, 0, 0)
+ROW_FUNC(YuvToBgraRow,     4, 2, 1, 0, 3)
+
+#undef ROW_FUNC
+#undef ASM_CLOBBER_LIST
+#undef ROW_FUNC_PART_2
+#undef ROW_FUNC_PART_1
+
+#endif  // WEBP_USE_MIPS_DSP_R2
+
+//------------------------------------------------------------------------------
+
+extern void WebPInitSamplersMIPSdspR2(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void WebPInitSamplersMIPSdspR2(void) {
+#if defined(WEBP_USE_MIPS_DSP_R2)
+  WebPSamplers[MODE_RGB]  = YuvToRgbRow;
+  WebPSamplers[MODE_RGBA] = YuvToRgbaRow;
+  WebPSamplers[MODE_BGR]  = YuvToBgrRow;
+  WebPSamplers[MODE_BGRA] = YuvToBgraRow;
+#endif  // WEBP_USE_MIPS_DSP_R2
+}
diff --git a/Source/LibWebP/src/dsp/dsp.yuv_sse2.c b/Source/LibWebP/src/dsp/dsp.yuv_sse2.c
new file mode 100644
index 0000000..ef52381
--- /dev/null
+++ b/Source/LibWebP/src/dsp/dsp.yuv_sse2.c
@@ -0,0 +1,322 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// YUV->RGB conversion functions
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include "./yuv.h"
+
+#if defined(WEBP_USE_SSE2)
+
+#include <emmintrin.h>
+#include <string.h>   // for memcpy
+
+typedef union {   // handy struct for converting SSE2 registers
+  int32_t i32[4];
+  uint8_t u8[16];
+  __m128i m;
+} VP8kCstSSE2;
+
+#if defined(WEBP_YUV_USE_SSE2_TABLES)
+
+#include "./yuv_tables_sse2.h"
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8YUVInitSSE2(void) {}
+
+#else
+
+static int done_sse2 = 0;
+static VP8kCstSSE2 VP8kUtoRGBA[256], VP8kVtoRGBA[256], VP8kYtoRGBA[256];
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8YUVInitSSE2(void) {
+  if (!done_sse2) {
+    int i;
+    for (i = 0; i < 256; ++i) {
+      VP8kYtoRGBA[i].i32[0] =
+        VP8kYtoRGBA[i].i32[1] =
+        VP8kYtoRGBA[i].i32[2] = (i - 16) * kYScale + YUV_HALF2;
+      VP8kYtoRGBA[i].i32[3] = 0xff << YUV_FIX2;
+
+      VP8kUtoRGBA[i].i32[0] = 0;
+      VP8kUtoRGBA[i].i32[1] = -kUToG * (i - 128);
+      VP8kUtoRGBA[i].i32[2] =  kUToB * (i - 128);
+      VP8kUtoRGBA[i].i32[3] = 0;
+
+      VP8kVtoRGBA[i].i32[0] =  kVToR * (i - 128);
+      VP8kVtoRGBA[i].i32[1] = -kVToG * (i - 128);
+      VP8kVtoRGBA[i].i32[2] = 0;
+      VP8kVtoRGBA[i].i32[3] = 0;
+    }
+    done_sse2 = 1;
+
+#if 0   // code used to generate 'yuv_tables_sse2.h'
+    printf("static const VP8kCstSSE2 VP8kYtoRGBA[256] = {\n");
+    for (i = 0; i < 256; ++i) {
+      printf("  {{0x%.8x, 0x%.8x, 0x%.8x, 0x%.8x}},\n",
+             VP8kYtoRGBA[i].i32[0], VP8kYtoRGBA[i].i32[1],
+             VP8kYtoRGBA[i].i32[2], VP8kYtoRGBA[i].i32[3]);
+    }
+    printf("};\n\n");
+    printf("static const VP8kCstSSE2 VP8kUtoRGBA[256] = {\n");
+    for (i = 0; i < 256; ++i) {
+      printf("  {{0, 0x%.8x, 0x%.8x, 0}},\n",
+             VP8kUtoRGBA[i].i32[1], VP8kUtoRGBA[i].i32[2]);
+    }
+    printf("};\n\n");
+    printf("static VP8kCstSSE2 VP8kVtoRGBA[256] = {\n");
+    for (i = 0; i < 256; ++i) {
+      printf("  {{0x%.8x, 0x%.8x, 0, 0}},\n",
+             VP8kVtoRGBA[i].i32[0], VP8kVtoRGBA[i].i32[1]);
+    }
+    printf("};\n\n");
+#endif
+  }
+}
+
+#endif  // WEBP_YUV_USE_SSE2_TABLES
+
+//-----------------------------------------------------------------------------
+
+static WEBP_INLINE __m128i LoadUVPart(int u, int v) {
+  const __m128i u_part = _mm_loadu_si128(&VP8kUtoRGBA[u].m);
+  const __m128i v_part = _mm_loadu_si128(&VP8kVtoRGBA[v].m);
+  const __m128i uv_part = _mm_add_epi32(u_part, v_part);
+  return uv_part;
+}
+
+static WEBP_INLINE __m128i GetRGBA32bWithUV(int y, const __m128i uv_part) {
+  const __m128i y_part = _mm_loadu_si128(&VP8kYtoRGBA[y].m);
+  const __m128i rgba1 = _mm_add_epi32(y_part, uv_part);
+  const __m128i rgba2 = _mm_srai_epi32(rgba1, YUV_FIX2);
+  return rgba2;
+}
+
+static WEBP_INLINE __m128i GetRGBA32b(int y, int u, int v) {
+  const __m128i uv_part = LoadUVPart(u, v);
+  return GetRGBA32bWithUV(y, uv_part);
+}
+
+static WEBP_INLINE void YuvToRgbSSE2(uint8_t y, uint8_t u, uint8_t v,
+                                     uint8_t* const rgb) {
+  const __m128i tmp0 = GetRGBA32b(y, u, v);
+  const __m128i tmp1 = _mm_packs_epi32(tmp0, tmp0);
+  const __m128i tmp2 = _mm_packus_epi16(tmp1, tmp1);
+  // Note: we store 8 bytes at a time, not 3 bytes! -> memory stomp
+  _mm_storel_epi64((__m128i*)rgb, tmp2);
+}
+
+static WEBP_INLINE void YuvToBgrSSE2(uint8_t y, uint8_t u, uint8_t v,
+                                     uint8_t* const bgr) {
+  const __m128i tmp0 = GetRGBA32b(y, u, v);
+  const __m128i tmp1 = _mm_shuffle_epi32(tmp0, _MM_SHUFFLE(3, 0, 1, 2));
+  const __m128i tmp2 = _mm_packs_epi32(tmp1, tmp1);
+  const __m128i tmp3 = _mm_packus_epi16(tmp2, tmp2);
+  // Note: we store 8 bytes at a time, not 3 bytes! -> memory stomp
+  _mm_storel_epi64((__m128i*)bgr, tmp3);
+}
+
+//-----------------------------------------------------------------------------
+// Convert spans of 32 pixels to various RGB formats for the fancy upsampler.
+
+#ifdef FANCY_UPSAMPLING
+
+void VP8YuvToRgba32(const uint8_t* y, const uint8_t* u, const uint8_t* v,
+                    uint8_t* dst) {
+  int n;
+  for (n = 0; n < 32; n += 4) {
+    const __m128i tmp0_1 = GetRGBA32b(y[n + 0], u[n + 0], v[n + 0]);
+    const __m128i tmp0_2 = GetRGBA32b(y[n + 1], u[n + 1], v[n + 1]);
+    const __m128i tmp0_3 = GetRGBA32b(y[n + 2], u[n + 2], v[n + 2]);
+    const __m128i tmp0_4 = GetRGBA32b(y[n + 3], u[n + 3], v[n + 3]);
+    const __m128i tmp1_1 = _mm_packs_epi32(tmp0_1, tmp0_2);
+    const __m128i tmp1_2 = _mm_packs_epi32(tmp0_3, tmp0_4);
+    const __m128i tmp2 = _mm_packus_epi16(tmp1_1, tmp1_2);
+    _mm_storeu_si128((__m128i*)dst, tmp2);
+    dst += 4 * 4;
+  }
+}
+
+void VP8YuvToBgra32(const uint8_t* y, const uint8_t* u, const uint8_t* v,
+                    uint8_t* dst) {
+  int n;
+  for (n = 0; n < 32; n += 2) {
+    const __m128i tmp0_1 = GetRGBA32b(y[n + 0], u[n + 0], v[n + 0]);
+    const __m128i tmp0_2 = GetRGBA32b(y[n + 1], u[n + 1], v[n + 1]);
+    const __m128i tmp1_1 = _mm_shuffle_epi32(tmp0_1, _MM_SHUFFLE(3, 0, 1, 2));
+    const __m128i tmp1_2 = _mm_shuffle_epi32(tmp0_2, _MM_SHUFFLE(3, 0, 1, 2));
+    const __m128i tmp2_1 = _mm_packs_epi32(tmp1_1, tmp1_2);
+    const __m128i tmp3 = _mm_packus_epi16(tmp2_1, tmp2_1);
+    _mm_storel_epi64((__m128i*)dst, tmp3);
+    dst += 4 * 2;
+  }
+}
+
+void VP8YuvToRgb32(const uint8_t* y, const uint8_t* u, const uint8_t* v,
+                   uint8_t* dst) {
+  int n;
+  uint8_t tmp0[2 * 3 + 5 + 15];
+  uint8_t* const tmp = (uint8_t*)((uintptr_t)(tmp0 + 15) & ~15);  // align
+  for (n = 0; n < 30; ++n) {   // we directly stomp the *dst memory
+    YuvToRgbSSE2(y[n], u[n], v[n], dst + n * 3);
+  }
+  // Last two pixels are special: we write in a tmp buffer before sending
+  // to dst.
+  YuvToRgbSSE2(y[n + 0], u[n + 0], v[n + 0], tmp + 0);
+  YuvToRgbSSE2(y[n + 1], u[n + 1], v[n + 1], tmp + 3);
+  memcpy(dst + n * 3, tmp, 2 * 3);
+}
+
+void VP8YuvToBgr32(const uint8_t* y, const uint8_t* u, const uint8_t* v,
+                   uint8_t* dst) {
+  int n;
+  uint8_t tmp0[2 * 3 + 5 + 15];
+  uint8_t* const tmp = (uint8_t*)((uintptr_t)(tmp0 + 15) & ~15);  // align
+  for (n = 0; n < 30; ++n) {
+    YuvToBgrSSE2(y[n], u[n], v[n], dst + n * 3);
+  }
+  YuvToBgrSSE2(y[n + 0], u[n + 0], v[n + 0], tmp + 0);
+  YuvToBgrSSE2(y[n + 1], u[n + 1], v[n + 1], tmp + 3);
+  memcpy(dst + n * 3, tmp, 2 * 3);
+}
+
+#endif  // FANCY_UPSAMPLING
+
+//-----------------------------------------------------------------------------
+// Arbitrary-length row conversion functions
+
+static void YuvToRgbaRowSSE2(const uint8_t* y,
+                             const uint8_t* u, const uint8_t* v,
+                             uint8_t* dst, int len) {
+  int n;
+  for (n = 0; n + 4 <= len; n += 4) {
+    const __m128i uv_0 = LoadUVPart(u[0], v[0]);
+    const __m128i uv_1 = LoadUVPart(u[1], v[1]);
+    const __m128i tmp0_1 = GetRGBA32bWithUV(y[0], uv_0);
+    const __m128i tmp0_2 = GetRGBA32bWithUV(y[1], uv_0);
+    const __m128i tmp0_3 = GetRGBA32bWithUV(y[2], uv_1);
+    const __m128i tmp0_4 = GetRGBA32bWithUV(y[3], uv_1);
+    const __m128i tmp1_1 = _mm_packs_epi32(tmp0_1, tmp0_2);
+    const __m128i tmp1_2 = _mm_packs_epi32(tmp0_3, tmp0_4);
+    const __m128i tmp2 = _mm_packus_epi16(tmp1_1, tmp1_2);
+    _mm_storeu_si128((__m128i*)dst, tmp2);
+    dst += 4 * 4;
+    y += 4;
+    u += 2;
+    v += 2;
+  }
+  // Finish off
+  while (n < len) {
+    VP8YuvToRgba(y[0], u[0], v[0], dst);
+    dst += 4;
+    ++y;
+    u += (n & 1);
+    v += (n & 1);
+    ++n;
+  }
+}
+
+static void YuvToBgraRowSSE2(const uint8_t* y,
+                             const uint8_t* u, const uint8_t* v,
+                             uint8_t* dst, int len) {
+  int n;
+  for (n = 0; n + 2 <= len; n += 2) {
+    const __m128i uv_0 = LoadUVPart(u[0], v[0]);
+    const __m128i tmp0_1 = GetRGBA32bWithUV(y[0], uv_0);
+    const __m128i tmp0_2 = GetRGBA32bWithUV(y[1], uv_0);
+    const __m128i tmp1_1 = _mm_shuffle_epi32(tmp0_1, _MM_SHUFFLE(3, 0, 1, 2));
+    const __m128i tmp1_2 = _mm_shuffle_epi32(tmp0_2, _MM_SHUFFLE(3, 0, 1, 2));
+    const __m128i tmp2_1 = _mm_packs_epi32(tmp1_1, tmp1_2);
+    const __m128i tmp3 = _mm_packus_epi16(tmp2_1, tmp2_1);
+    _mm_storel_epi64((__m128i*)dst, tmp3);
+    dst += 4 * 2;
+    y += 2;
+    ++u;
+    ++v;
+  }
+  // Finish off
+  if (len & 1) {
+    VP8YuvToBgra(y[0], u[0], v[0], dst);
+  }
+}
+
+static void YuvToArgbRowSSE2(const uint8_t* y,
+                             const uint8_t* u, const uint8_t* v,
+                             uint8_t* dst, int len) {
+  int n;
+  for (n = 0; n + 2 <= len; n += 2) {
+    const __m128i uv_0 = LoadUVPart(u[0], v[0]);
+    const __m128i tmp0_1 = GetRGBA32bWithUV(y[0], uv_0);
+    const __m128i tmp0_2 = GetRGBA32bWithUV(y[1], uv_0);
+    const __m128i tmp1_1 = _mm_shuffle_epi32(tmp0_1, _MM_SHUFFLE(2, 1, 0, 3));
+    const __m128i tmp1_2 = _mm_shuffle_epi32(tmp0_2, _MM_SHUFFLE(2, 1, 0, 3));
+    const __m128i tmp2_1 = _mm_packs_epi32(tmp1_1, tmp1_2);
+    const __m128i tmp3 = _mm_packus_epi16(tmp2_1, tmp2_1);
+    _mm_storel_epi64((__m128i*)dst, tmp3);
+    dst += 4 * 2;
+    y += 2;
+    ++u;
+    ++v;
+  }
+  // Finish off
+  if (len & 1) {
+    VP8YuvToArgb(y[0], u[0], v[0], dst);
+  }
+}
+
+static void YuvToRgbRowSSE2(const uint8_t* y,
+                            const uint8_t* u, const uint8_t* v,
+                            uint8_t* dst, int len) {
+  int n;
+  for (n = 0; n + 2 < len; ++n) {   // we directly stomp the *dst memory
+    YuvToRgbSSE2(y[0], u[0], v[0], dst);  // stomps 8 bytes
+    dst += 3;
+    ++y;
+    u += (n & 1);
+    v += (n & 1);
+  }
+  VP8YuvToRgb(y[0], u[0], v[0], dst);
+  if (len > 1) {
+    VP8YuvToRgb(y[1], u[n & 1], v[n & 1], dst + 3);
+  }
+}
+
+static void YuvToBgrRowSSE2(const uint8_t* y,
+                            const uint8_t* u, const uint8_t* v,
+                            uint8_t* dst, int len) {
+  int n;
+  for (n = 0; n + 2 < len; ++n) {   // we directly stomp the *dst memory
+    YuvToBgrSSE2(y[0], u[0], v[0], dst);  // stomps 8 bytes
+    dst += 3;
+    ++y;
+    u += (n & 1);
+    v += (n & 1);
+  }
+  VP8YuvToBgr(y[0], u[0], v[0], dst + 0);
+  if (len > 1) {
+    VP8YuvToBgr(y[1], u[n & 1], v[n & 1], dst + 3);
+  }
+}
+
+#endif  // WEBP_USE_SSE2
+
+//------------------------------------------------------------------------------
+// Entry point
+
+extern void WebPInitSamplersSSE2(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void WebPInitSamplersSSE2(void) {
+#if defined(WEBP_USE_SSE2)
+  WebPSamplers[MODE_RGB]  = YuvToRgbRowSSE2;
+  WebPSamplers[MODE_RGBA] = YuvToRgbaRowSSE2;
+  WebPSamplers[MODE_BGR]  = YuvToBgrRowSSE2;
+  WebPSamplers[MODE_BGRA] = YuvToBgraRowSSE2;
+  WebPSamplers[MODE_ARGB] = YuvToArgbRowSSE2;
+#endif  // WEBP_USE_SSE2
+}
diff --git a/Source/LibWebP/src/dsp/lossless.h b/Source/LibWebP/src/dsp/lossless.h
new file mode 100644
index 0000000..f702903
--- /dev/null
+++ b/Source/LibWebP/src/dsp/lossless.h
@@ -0,0 +1,313 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Image transforms and color space conversion methods for lossless decoder.
+//
+// Authors: Vikas Arora (vikaas.arora at gmail.com)
+//          Jyrki Alakuijala (jyrki at google.com)
+
+#ifndef WEBP_DSP_LOSSLESS_H_
+#define WEBP_DSP_LOSSLESS_H_
+
+#include "../webp/types.h"
+#include "../webp/decode.h"
+
+#include "../enc/histogram.h"
+#include "../utils/utils.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+// Not a trivial literal symbol.
+#define VP8L_NON_TRIVIAL_SYM (0xffffffff)
+
+//------------------------------------------------------------------------------
+// Signatures and generic function-pointers
+
+typedef uint32_t (*VP8LPredictorFunc)(uint32_t left, const uint32_t* const top);
+extern VP8LPredictorFunc VP8LPredictors[16];
+
+typedef void (*VP8LProcessBlueAndRedFunc)(uint32_t* argb_data, int num_pixels);
+extern VP8LProcessBlueAndRedFunc VP8LSubtractGreenFromBlueAndRed;
+extern VP8LProcessBlueAndRedFunc VP8LAddGreenToBlueAndRed;
+
+typedef struct {
+  // Note: the members are uint8_t, so that any negative values are
+  // automatically converted to "mod 256" values.
+  uint8_t green_to_red_;
+  uint8_t green_to_blue_;
+  uint8_t red_to_blue_;
+} VP8LMultipliers;
+typedef void (*VP8LTransformColorFunc)(const VP8LMultipliers* const m,
+                                       uint32_t* argb_data, int num_pixels);
+extern VP8LTransformColorFunc VP8LTransformColor;
+extern VP8LTransformColorFunc VP8LTransformColorInverse;
+
+typedef void (*VP8LConvertFunc)(const uint32_t* src, int num_pixels,
+                                uint8_t* dst);
+extern VP8LConvertFunc VP8LConvertBGRAToRGB;
+extern VP8LConvertFunc VP8LConvertBGRAToRGBA;
+extern VP8LConvertFunc VP8LConvertBGRAToRGBA4444;
+extern VP8LConvertFunc VP8LConvertBGRAToRGB565;
+extern VP8LConvertFunc VP8LConvertBGRAToBGR;
+
+typedef void (*VP8LCollectColorBlueTransformsFunc)(
+    const uint32_t* argb, int stride,
+    int tile_width, int tile_height,
+    int green_to_blue, int red_to_blue, int histo[]);
+extern VP8LCollectColorBlueTransformsFunc VP8LCollectColorBlueTransforms;
+
+typedef void (*VP8LCollectColorRedTransformsFunc)(
+    const uint32_t* argb, int stride,
+    int tile_width, int tile_height,
+    int green_to_red, int histo[]);
+extern VP8LCollectColorRedTransformsFunc VP8LCollectColorRedTransforms;
+
+// Expose some C-only fallback functions
+void VP8LTransformColor_C(const VP8LMultipliers* const m,
+                          uint32_t* data, int num_pixels);
+void VP8LTransformColorInverse_C(const VP8LMultipliers* const m,
+                                 uint32_t* data, int num_pixels);
+
+void VP8LConvertBGRAToRGB_C(const uint32_t* src, int num_pixels, uint8_t* dst);
+void VP8LConvertBGRAToRGBA_C(const uint32_t* src, int num_pixels, uint8_t* dst);
+void VP8LConvertBGRAToRGBA4444_C(const uint32_t* src,
+                                 int num_pixels, uint8_t* dst);
+void VP8LConvertBGRAToRGB565_C(const uint32_t* src,
+                               int num_pixels, uint8_t* dst);
+void VP8LConvertBGRAToBGR_C(const uint32_t* src, int num_pixels, uint8_t* dst);
+void VP8LSubtractGreenFromBlueAndRed_C(uint32_t* argb_data, int num_pixels);
+void VP8LAddGreenToBlueAndRed_C(uint32_t* data, int num_pixels);
+
+// Must be called before calling any of the above methods.
+void VP8LDspInit(void);
+
+//------------------------------------------------------------------------------
+// Image transforms.
+
+struct VP8LTransform;  // Defined in dec/vp8li.h.
+
+// Performs inverse transform of data given transform information, start and end
+// rows. Transform will be applied to rows [row_start, row_end[.
+// The *in and *out pointers refer to source and destination data respectively
+// corresponding to the intermediate row (row_start).
+void VP8LInverseTransform(const struct VP8LTransform* const transform,
+                          int row_start, int row_end,
+                          const uint32_t* const in, uint32_t* const out);
+
+// Similar to the static method ColorIndexInverseTransform() that is part of
+// lossless.c, but used only for alpha decoding. It takes uint8_t (rather than
+// uint32_t) arguments for 'src' and 'dst'.
+void VP8LColorIndexInverseTransformAlpha(
+    const struct VP8LTransform* const transform, int y_start, int y_end,
+    const uint8_t* src, uint8_t* dst);
+
+void VP8LResidualImage(int width, int height, int bits, int low_effort,
+                       uint32_t* const argb, uint32_t* const argb_scratch,
+                       uint32_t* const image);
+
+void VP8LColorSpaceTransform(int width, int height, int bits, int quality,
+                             uint32_t* const argb, uint32_t* image);
+
+//------------------------------------------------------------------------------
+// Color space conversion.
+
+// Converts from BGRA to other color spaces.
+void VP8LConvertFromBGRA(const uint32_t* const in_data, int num_pixels,
+                         WEBP_CSP_MODE out_colorspace, uint8_t* const rgba);
+
+//------------------------------------------------------------------------------
+// Misc methods.
+
+// Computes sampled size of 'size' when sampling using 'sampling bits'.
+static WEBP_INLINE uint32_t VP8LSubSampleSize(uint32_t size,
+                                              uint32_t sampling_bits) {
+  return (size + (1 << sampling_bits) - 1) >> sampling_bits;
+}
+
+// -----------------------------------------------------------------------------
+// Faster logarithm for integers. Small values use a look-up table.
+#define LOG_LOOKUP_IDX_MAX 256
+extern const float kLog2Table[LOG_LOOKUP_IDX_MAX];
+extern const float kSLog2Table[LOG_LOOKUP_IDX_MAX];
+typedef float (*VP8LFastLog2SlowFunc)(uint32_t v);
+
+extern VP8LFastLog2SlowFunc VP8LFastLog2Slow;
+extern VP8LFastLog2SlowFunc VP8LFastSLog2Slow;
+
+static WEBP_INLINE float VP8LFastLog2(uint32_t v) {
+  return (v < LOG_LOOKUP_IDX_MAX) ? kLog2Table[v] : VP8LFastLog2Slow(v);
+}
+// Fast calculation of v * log2(v) for integer input.
+static WEBP_INLINE float VP8LFastSLog2(uint32_t v) {
+  return (v < LOG_LOOKUP_IDX_MAX) ? kSLog2Table[v] : VP8LFastSLog2Slow(v);
+}
+
+// -----------------------------------------------------------------------------
+// Huffman-cost related functions.
+
+typedef double (*VP8LCostFunc)(const uint32_t* population, int length);
+typedef double (*VP8LCostCombinedFunc)(const uint32_t* X, const uint32_t* Y,
+                                       int length);
+
+extern VP8LCostFunc VP8LExtraCost;
+extern VP8LCostCombinedFunc VP8LExtraCostCombined;
+
+typedef struct {        // small struct to hold counters
+  int counts[2];        // index: 0=zero steak, 1=non-zero streak
+  int streaks[2][2];    // [zero/non-zero][streak<3 / streak>=3]
+} VP8LStreaks;
+
+typedef VP8LStreaks (*VP8LCostCountFunc)(const uint32_t* population,
+                                         int length);
+typedef VP8LStreaks (*VP8LCostCombinedCountFunc)(const uint32_t* X,
+                                                 const uint32_t* Y, int length);
+
+extern VP8LCostCountFunc VP8LHuffmanCostCount;
+extern VP8LCostCombinedCountFunc VP8LHuffmanCostCombinedCount;
+
+// Get the symbol entropy for the distribution 'population'.
+// Set 'trivial_sym', if there's only one symbol present in the distribution.
+double VP8LPopulationCost(const uint32_t* const population, int length,
+                          uint32_t* const trivial_sym);
+
+// Get the combined symbol entropy for the distributions 'X' and 'Y'.
+double VP8LGetCombinedEntropy(const uint32_t* const X,
+                              const uint32_t* const Y, int length);
+
+// Estimate how many bits the combined entropy of literals and distance
+// approximately maps to.
+double VP8LHistogramEstimateBits(const VP8LHistogram* const p);
+
+// This function estimates the cost in bits excluding the bits needed to
+// represent the entropy code itself.
+double VP8LHistogramEstimateBitsBulk(const VP8LHistogram* const p);
+
+typedef void (*VP8LHistogramAddFunc)(const VP8LHistogram* const a,
+                                     const VP8LHistogram* const b,
+                                     VP8LHistogram* const out);
+extern VP8LHistogramAddFunc VP8LHistogramAdd;
+
+// -----------------------------------------------------------------------------
+// color mapping related functions.
+
+static WEBP_INLINE uint32_t VP8GetARGBIndex(uint32_t idx) {
+  return (idx >> 8) & 0xff;
+}
+
+static WEBP_INLINE uint8_t VP8GetAlphaIndex(uint8_t idx) {
+  return idx;
+}
+
+static WEBP_INLINE uint32_t VP8GetARGBValue(uint32_t val) {
+  return val;
+}
+
+static WEBP_INLINE uint8_t VP8GetAlphaValue(uint32_t val) {
+  return (val >> 8) & 0xff;
+}
+
+typedef void (*VP8LMapARGBFunc)(const uint32_t* src,
+                                const uint32_t* const color_map,
+                                uint32_t* dst, int y_start,
+                                int y_end, int width);
+typedef void (*VP8LMapAlphaFunc)(const uint8_t* src,
+                                 const uint32_t* const color_map,
+                                 uint8_t* dst, int y_start,
+                                 int y_end, int width);
+
+extern VP8LMapARGBFunc VP8LMapColor32b;
+extern VP8LMapAlphaFunc VP8LMapColor8b;
+
+// -----------------------------------------------------------------------------
+// PrefixEncode()
+
+static WEBP_INLINE int VP8LBitsLog2Ceiling(uint32_t n) {
+  const int log_floor = BitsLog2Floor(n);
+  if (n == (n & ~(n - 1)))  // zero or a power of two.
+    return log_floor;
+  else
+    return log_floor + 1;
+}
+
+// Splitting of distance and length codes into prefixes and
+// extra bits. The prefixes are encoded with an entropy code
+// while the extra bits are stored just as normal bits.
+static WEBP_INLINE void VP8LPrefixEncodeBitsNoLUT(int distance, int* const code,
+                                                  int* const extra_bits) {
+  const int highest_bit = BitsLog2Floor(--distance);
+  const int second_highest_bit = (distance >> (highest_bit - 1)) & 1;
+  *extra_bits = highest_bit - 1;
+  *code = 2 * highest_bit + second_highest_bit;
+}
+
+static WEBP_INLINE void VP8LPrefixEncodeNoLUT(int distance, int* const code,
+                                              int* const extra_bits,
+                                              int* const extra_bits_value) {
+  const int highest_bit = BitsLog2Floor(--distance);
+  const int second_highest_bit = (distance >> (highest_bit - 1)) & 1;
+  *extra_bits = highest_bit - 1;
+  *extra_bits_value = distance & ((1 << *extra_bits) - 1);
+  *code = 2 * highest_bit + second_highest_bit;
+}
+
+#define PREFIX_LOOKUP_IDX_MAX   512
+typedef struct {
+  int8_t code_;
+  int8_t extra_bits_;
+} VP8LPrefixCode;
+
+// These tables are derived using VP8LPrefixEncodeNoLUT.
+extern const VP8LPrefixCode kPrefixEncodeCode[PREFIX_LOOKUP_IDX_MAX];
+extern const uint8_t kPrefixEncodeExtraBitsValue[PREFIX_LOOKUP_IDX_MAX];
+static WEBP_INLINE void VP8LPrefixEncodeBits(int distance, int* const code,
+                                             int* const extra_bits) {
+  if (distance < PREFIX_LOOKUP_IDX_MAX) {
+    const VP8LPrefixCode prefix_code = kPrefixEncodeCode[distance];
+    *code = prefix_code.code_;
+    *extra_bits = prefix_code.extra_bits_;
+  } else {
+    VP8LPrefixEncodeBitsNoLUT(distance, code, extra_bits);
+  }
+}
+
+static WEBP_INLINE void VP8LPrefixEncode(int distance, int* const code,
+                                         int* const extra_bits,
+                                         int* const extra_bits_value) {
+  if (distance < PREFIX_LOOKUP_IDX_MAX) {
+    const VP8LPrefixCode prefix_code = kPrefixEncodeCode[distance];
+    *code = prefix_code.code_;
+    *extra_bits = prefix_code.extra_bits_;
+    *extra_bits_value = kPrefixEncodeExtraBitsValue[distance];
+  } else {
+    VP8LPrefixEncodeNoLUT(distance, code, extra_bits, extra_bits_value);
+  }
+}
+
+// In-place difference of each component with mod 256.
+static WEBP_INLINE uint32_t VP8LSubPixels(uint32_t a, uint32_t b) {
+  const uint32_t alpha_and_green =
+      0x00ff00ffu + (a & 0xff00ff00u) - (b & 0xff00ff00u);
+  const uint32_t red_and_blue =
+      0xff00ff00u + (a & 0x00ff00ffu) - (b & 0x00ff00ffu);
+  return (alpha_and_green & 0xff00ff00u) | (red_and_blue & 0x00ff00ffu);
+}
+
+void VP8LBundleColorMap(const uint8_t* const row, int width,
+                        int xbits, uint32_t* const dst);
+
+//------------------------------------------------------------------------------
+
+#ifdef __cplusplus
+}    // extern "C"
+#endif
+
+#endif  // WEBP_DSP_LOSSLESS_H_
diff --git a/Source/LibWebP/src/dsp/mips_macro.h b/Source/LibWebP/src/dsp/mips_macro.h
new file mode 100644
index 0000000..baff21d
--- /dev/null
+++ b/Source/LibWebP/src/dsp/mips_macro.h
@@ -0,0 +1,200 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// MIPS common macros
+
+#ifndef WEBP_DSP_MIPS_MACRO_H_
+#define WEBP_DSP_MIPS_MACRO_H_
+
+#if defined(__GNUC__) && defined(__ANDROID__) && LOCAL_GCC_VERSION == 0x409
+#define WORK_AROUND_GCC
+#endif
+
+#define STR(s) #s
+#define XSTR(s) STR(s)
+
+// O0[31..16 | 15..0] = I0[31..16 | 15..0] + I1[31..16 | 15..0]
+// O1[31..16 | 15..0] = I0[31..16 | 15..0] - I1[31..16 | 15..0]
+// O - output
+// I - input (macro doesn't change it)
+#define ADD_SUB_HALVES(O0, O1,                                                 \
+                       I0, I1)                                                 \
+  "addq.ph          %["#O0"],   %["#I0"],  %["#I1"]           \n\t"            \
+  "subq.ph          %["#O1"],   %["#I0"],  %["#I1"]           \n\t"
+
+// O - output
+// I - input (macro doesn't change it)
+// I[0/1] - offset in bytes
+#define LOAD_IN_X2(O0, O1,                                                     \
+                   I0, I1)                                                     \
+  "lh               %["#O0"],   "#I0"(%[in])                  \n\t"            \
+  "lh               %["#O1"],   "#I1"(%[in])                  \n\t"
+
+// I0 - location
+// I1..I9 - offsets in bytes
+#define LOAD_WITH_OFFSET_X4(O0, O1, O2, O3,                                    \
+                            I0, I1, I2, I3, I4, I5, I6, I7, I8, I9)            \
+  "ulw    %["#O0"],    "#I1"+"XSTR(I9)"*"#I5"(%["#I0"])       \n\t"            \
+  "ulw    %["#O1"],    "#I2"+"XSTR(I9)"*"#I6"(%["#I0"])       \n\t"            \
+  "ulw    %["#O2"],    "#I3"+"XSTR(I9)"*"#I7"(%["#I0"])       \n\t"            \
+  "ulw    %["#O3"],    "#I4"+"XSTR(I9)"*"#I8"(%["#I0"])       \n\t"
+
+// O - output
+// IO - input/output
+// I - input (macro doesn't change it)
+#define MUL_SHIFT_SUM(O0, O1, O2, O3, O4, O5, O6, O7,                          \
+                      IO0, IO1, IO2, IO3,                                      \
+                      I0, I1, I2, I3, I4, I5, I6, I7)                          \
+  "mul              %["#O0"],   %["#I0"],   %[kC2]            \n\t"            \
+  "mul              %["#O1"],   %["#I0"],   %[kC1]            \n\t"            \
+  "mul              %["#O2"],   %["#I1"],   %[kC2]            \n\t"            \
+  "mul              %["#O3"],   %["#I1"],   %[kC1]            \n\t"            \
+  "mul              %["#O4"],   %["#I2"],   %[kC2]            \n\t"            \
+  "mul              %["#O5"],   %["#I2"],   %[kC1]            \n\t"            \
+  "mul              %["#O6"],   %["#I3"],   %[kC2]            \n\t"            \
+  "mul              %["#O7"],   %["#I3"],   %[kC1]            \n\t"            \
+  "sra              %["#O0"],   %["#O0"],   16                \n\t"            \
+  "sra              %["#O1"],   %["#O1"],   16                \n\t"            \
+  "sra              %["#O2"],   %["#O2"],   16                \n\t"            \
+  "sra              %["#O3"],   %["#O3"],   16                \n\t"            \
+  "sra              %["#O4"],   %["#O4"],   16                \n\t"            \
+  "sra              %["#O5"],   %["#O5"],   16                \n\t"            \
+  "sra              %["#O6"],   %["#O6"],   16                \n\t"            \
+  "sra              %["#O7"],   %["#O7"],   16                \n\t"            \
+  "addu             %["#IO0"],  %["#IO0"],  %["#I4"]          \n\t"            \
+  "addu             %["#IO1"],  %["#IO1"],  %["#I5"]          \n\t"            \
+  "subu             %["#IO2"],  %["#IO2"],  %["#I6"]          \n\t"            \
+  "subu             %["#IO3"],  %["#IO3"],  %["#I7"]          \n\t"
+
+// O - output
+// I - input (macro doesn't change it)
+#define INSERT_HALF_X2(O0, O1,                                                 \
+                       I0, I1)                                                 \
+  "ins              %["#O0"],   %["#I0"], 16,    16           \n\t"            \
+  "ins              %["#O1"],   %["#I1"], 16,    16           \n\t"
+
+// O - output
+// I - input (macro doesn't change it)
+#define SRA_16(O0, O1, O2, O3,                                                 \
+               I0, I1, I2, I3)                                                 \
+  "sra              %["#O0"],  %["#I0"],  16                  \n\t"            \
+  "sra              %["#O1"],  %["#I1"],  16                  \n\t"            \
+  "sra              %["#O2"],  %["#I2"],  16                  \n\t"            \
+  "sra              %["#O3"],  %["#I3"],  16                  \n\t"
+
+// temp0[31..16 | 15..0] = temp8[31..16 | 15..0] + temp12[31..16 | 15..0]
+// temp1[31..16 | 15..0] = temp8[31..16 | 15..0] - temp12[31..16 | 15..0]
+// temp0[31..16 | 15..0] = temp0[31..16 >> 3 | 15..0 >> 3]
+// temp1[31..16 | 15..0] = temp1[31..16 >> 3 | 15..0 >> 3]
+// O - output
+// I - input (macro doesn't change it)
+#define SHIFT_R_SUM_X2(O0, O1, O2, O3, O4, O5, O6, O7,                         \
+                       I0, I1, I2, I3, I4, I5, I6, I7)                         \
+  "addq.ph          %["#O0"],   %["#I0"],   %["#I4"]          \n\t"            \
+  "subq.ph          %["#O1"],   %["#I0"],   %["#I4"]          \n\t"            \
+  "addq.ph          %["#O2"],   %["#I1"],   %["#I5"]          \n\t"            \
+  "subq.ph          %["#O3"],   %["#I1"],   %["#I5"]          \n\t"            \
+  "addq.ph          %["#O4"],   %["#I2"],   %["#I6"]          \n\t"            \
+  "subq.ph          %["#O5"],   %["#I2"],   %["#I6"]          \n\t"            \
+  "addq.ph          %["#O6"],   %["#I3"],   %["#I7"]          \n\t"            \
+  "subq.ph          %["#O7"],   %["#I3"],   %["#I7"]          \n\t"            \
+  "shra.ph          %["#O0"],   %["#O0"],   3                 \n\t"            \
+  "shra.ph          %["#O1"],   %["#O1"],   3                 \n\t"            \
+  "shra.ph          %["#O2"],   %["#O2"],   3                 \n\t"            \
+  "shra.ph          %["#O3"],   %["#O3"],   3                 \n\t"            \
+  "shra.ph          %["#O4"],   %["#O4"],   3                 \n\t"            \
+  "shra.ph          %["#O5"],   %["#O5"],   3                 \n\t"            \
+  "shra.ph          %["#O6"],   %["#O6"],   3                 \n\t"            \
+  "shra.ph          %["#O7"],   %["#O7"],   3                 \n\t"
+
+// precrq.ph.w temp0, temp8, temp2
+//   temp0 = temp8[31..16] | temp2[31..16]
+// ins temp2, temp8, 16, 16
+//   temp2 = temp8[31..16] | temp2[15..0]
+// O - output
+// IO - input/output
+// I - input (macro doesn't change it)
+#define PACK_2_HALVES_TO_WORD(O0, O1, O2, O3,                                  \
+                              IO0, IO1, IO2, IO3,                              \
+                              I0, I1, I2, I3)                                  \
+  "precrq.ph.w      %["#O0"],    %["#I0"],  %["#IO0"]         \n\t"            \
+  "precrq.ph.w      %["#O1"],    %["#I1"],  %["#IO1"]         \n\t"            \
+  "ins              %["#IO0"],   %["#I0"],  16,    16         \n\t"            \
+  "ins              %["#IO1"],   %["#I1"],  16,    16         \n\t"            \
+  "precrq.ph.w      %["#O2"],    %["#I2"],  %["#IO2"]         \n\t"            \
+  "precrq.ph.w      %["#O3"],    %["#I3"],  %["#IO3"]         \n\t"            \
+  "ins              %["#IO2"],   %["#I2"],  16,    16         \n\t"            \
+  "ins              %["#IO3"],   %["#I3"],  16,    16         \n\t"
+
+// preceu.ph.qbr temp0, temp8
+//   temp0 = 0 | 0 | temp8[23..16] | temp8[7..0]
+// preceu.ph.qbl temp1, temp8
+//   temp1 = temp8[23..16] | temp8[7..0] | 0 | 0
+// O - output
+// I - input (macro doesn't change it)
+#define CONVERT_2_BYTES_TO_HALF(O0, O1, O2, O3, O4, O5, O6, O7,                \
+                                I0, I1, I2, I3)                                \
+  "preceu.ph.qbr    %["#O0"],   %["#I0"]                      \n\t"            \
+  "preceu.ph.qbl    %["#O1"],   %["#I0"]                      \n\t"            \
+  "preceu.ph.qbr    %["#O2"],   %["#I1"]                      \n\t"            \
+  "preceu.ph.qbl    %["#O3"],   %["#I1"]                      \n\t"            \
+  "preceu.ph.qbr    %["#O4"],   %["#I2"]                      \n\t"            \
+  "preceu.ph.qbl    %["#O5"],   %["#I2"]                      \n\t"            \
+  "preceu.ph.qbr    %["#O6"],   %["#I3"]                      \n\t"            \
+  "preceu.ph.qbl    %["#O7"],   %["#I3"]                      \n\t"
+
+// temp0[31..16 | 15..0] = temp0[31..16 | 15..0] + temp8[31..16 | 15..0]
+// temp0[31..16 | 15..0] = temp0[31..16 <<(s) 7 | 15..0 <<(s) 7]
+// temp1..temp7 same as temp0
+// precrqu_s.qb.ph temp0, temp1, temp0:
+//   temp0 = temp1[31..24] | temp1[15..8] | temp0[31..24] | temp0[15..8]
+// store temp0 to dst
+// IO - input/output
+// I - input (macro doesn't change it)
+#define STORE_SAT_SUM_X2(IO0, IO1, IO2, IO3, IO4, IO5, IO6, IO7,               \
+                         I0, I1, I2, I3, I4, I5, I6, I7,                       \
+                         I8, I9, I10, I11, I12, I13)                           \
+  "addq.ph          %["#IO0"],  %["#IO0"],  %["#I0"]          \n\t"            \
+  "addq.ph          %["#IO1"],  %["#IO1"],  %["#I1"]          \n\t"            \
+  "addq.ph          %["#IO2"],  %["#IO2"],  %["#I2"]          \n\t"            \
+  "addq.ph          %["#IO3"],  %["#IO3"],  %["#I3"]          \n\t"            \
+  "addq.ph          %["#IO4"],  %["#IO4"],  %["#I4"]          \n\t"            \
+  "addq.ph          %["#IO5"],  %["#IO5"],  %["#I5"]          \n\t"            \
+  "addq.ph          %["#IO6"],  %["#IO6"],  %["#I6"]          \n\t"            \
+  "addq.ph          %["#IO7"],  %["#IO7"],  %["#I7"]          \n\t"            \
+  "shll_s.ph        %["#IO0"],  %["#IO0"],  7                 \n\t"            \
+  "shll_s.ph        %["#IO1"],  %["#IO1"],  7                 \n\t"            \
+  "shll_s.ph        %["#IO2"],  %["#IO2"],  7                 \n\t"            \
+  "shll_s.ph        %["#IO3"],  %["#IO3"],  7                 \n\t"            \
+  "shll_s.ph        %["#IO4"],  %["#IO4"],  7                 \n\t"            \
+  "shll_s.ph        %["#IO5"],  %["#IO5"],  7                 \n\t"            \
+  "shll_s.ph        %["#IO6"],  %["#IO6"],  7                 \n\t"            \
+  "shll_s.ph        %["#IO7"],  %["#IO7"],  7                 \n\t"            \
+  "precrqu_s.qb.ph  %["#IO0"],  %["#IO1"],  %["#IO0"]         \n\t"            \
+  "precrqu_s.qb.ph  %["#IO2"],  %["#IO3"],  %["#IO2"]         \n\t"            \
+  "precrqu_s.qb.ph  %["#IO4"],  %["#IO5"],  %["#IO4"]         \n\t"            \
+  "precrqu_s.qb.ph  %["#IO6"],  %["#IO7"],  %["#IO6"]         \n\t"            \
+  "usw              %["#IO0"],  "XSTR(I13)"*"#I9"(%["#I8"])   \n\t"            \
+  "usw              %["#IO2"],  "XSTR(I13)"*"#I10"(%["#I8"])  \n\t"            \
+  "usw              %["#IO4"],  "XSTR(I13)"*"#I11"(%["#I8"])  \n\t"            \
+  "usw              %["#IO6"],  "XSTR(I13)"*"#I12"(%["#I8"])  \n\t"
+
+#define OUTPUT_EARLY_CLOBBER_REGS_10()                                         \
+  : [temp1]"=&r"(temp1), [temp2]"=&r"(temp2), [temp3]"=&r"(temp3),             \
+    [temp4]"=&r"(temp4), [temp5]"=&r"(temp5), [temp6]"=&r"(temp6),             \
+    [temp7]"=&r"(temp7), [temp8]"=&r"(temp8), [temp9]"=&r"(temp9),             \
+    [temp10]"=&r"(temp10)
+
+#define OUTPUT_EARLY_CLOBBER_REGS_18()                                         \
+  OUTPUT_EARLY_CLOBBER_REGS_10(),                                              \
+  [temp11]"=&r"(temp11), [temp12]"=&r"(temp12), [temp13]"=&r"(temp13),         \
+  [temp14]"=&r"(temp14), [temp15]"=&r"(temp15), [temp16]"=&r"(temp16),         \
+  [temp17]"=&r"(temp17), [temp18]"=&r"(temp18)
+
+#endif  // WEBP_DSP_MIPS_MACRO_H_
diff --git a/Source/LibWebP/src/dsp/neon.h b/Source/LibWebP/src/dsp/neon.h
new file mode 100644
index 0000000..79a936f
--- /dev/null
+++ b/Source/LibWebP/src/dsp/neon.h
@@ -0,0 +1,82 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+//  NEON common code.
+
+#ifndef WEBP_DSP_NEON_H_
+#define WEBP_DSP_NEON_H_
+
+#include <arm_neon.h>
+
+#include "./dsp.h"
+
+// Right now, some intrinsics functions seem slower, so we disable them
+// everywhere except aarch64 where the inline assembly is incompatible.
+#if defined(__aarch64__)
+#define WEBP_USE_INTRINSICS   // use intrinsics when possible
+#endif
+
+#define INIT_VECTOR2(v, a, b) do {  \
+  v.val[0] = a;                     \
+  v.val[1] = b;                     \
+} while (0)
+
+#define INIT_VECTOR3(v, a, b, c) do {  \
+  v.val[0] = a;                        \
+  v.val[1] = b;                        \
+  v.val[2] = c;                        \
+} while (0)
+
+#define INIT_VECTOR4(v, a, b, c, d) do {  \
+  v.val[0] = a;                           \
+  v.val[1] = b;                           \
+  v.val[2] = c;                           \
+  v.val[3] = d;                           \
+} while (0)
+
+// if using intrinsics, this flag avoids some functions that make gcc-4.6.3
+// crash ("internal compiler error: in immed_double_const, at emit-rtl.").
+// (probably similar to gcc.gnu.org/bugzilla/show_bug.cgi?id=48183)
+#if !(LOCAL_GCC_PREREQ(4,8) || defined(__aarch64__))
+#define WORK_AROUND_GCC
+#endif
+
+static WEBP_INLINE int32x4x4_t Transpose4x4(const int32x4x4_t rows) {
+  uint64x2x2_t row01, row23;
+
+  row01.val[0] = vreinterpretq_u64_s32(rows.val[0]);
+  row01.val[1] = vreinterpretq_u64_s32(rows.val[1]);
+  row23.val[0] = vreinterpretq_u64_s32(rows.val[2]);
+  row23.val[1] = vreinterpretq_u64_s32(rows.val[3]);
+  // Transpose 64-bit values (there's no vswp equivalent)
+  {
+    const uint64x1_t row0h = vget_high_u64(row01.val[0]);
+    const uint64x1_t row2l = vget_low_u64(row23.val[0]);
+    const uint64x1_t row1h = vget_high_u64(row01.val[1]);
+    const uint64x1_t row3l = vget_low_u64(row23.val[1]);
+    row01.val[0] = vcombine_u64(vget_low_u64(row01.val[0]), row2l);
+    row23.val[0] = vcombine_u64(row0h, vget_high_u64(row23.val[0]));
+    row01.val[1] = vcombine_u64(vget_low_u64(row01.val[1]), row3l);
+    row23.val[1] = vcombine_u64(row1h, vget_high_u64(row23.val[1]));
+  }
+  {
+    const int32x4x2_t out01 = vtrnq_s32(vreinterpretq_s32_u64(row01.val[0]),
+                                        vreinterpretq_s32_u64(row01.val[1]));
+    const int32x4x2_t out23 = vtrnq_s32(vreinterpretq_s32_u64(row23.val[0]),
+                                        vreinterpretq_s32_u64(row23.val[1]));
+    int32x4x4_t out;
+    out.val[0] = out01.val[0];
+    out.val[1] = out01.val[1];
+    out.val[2] = out23.val[0];
+    out.val[3] = out23.val[1];
+    return out;
+  }
+}
+
+#endif  // WEBP_DSP_NEON_H_
diff --git a/Source/LibWebP/src/dsp/yuv.h b/Source/LibWebP/src/dsp/yuv.h
new file mode 100644
index 0000000..0c5ec42
--- /dev/null
+++ b/Source/LibWebP/src/dsp/yuv.h
@@ -0,0 +1,321 @@
+// Copyright 2010 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// inline YUV<->RGB conversion function
+//
+// The exact naming is Y'CbCr, following the ITU-R BT.601 standard.
+// More information at: http://en.wikipedia.org/wiki/YCbCr
+// Y = 0.2569 * R + 0.5044 * G + 0.0979 * B + 16
+// U = -0.1483 * R - 0.2911 * G + 0.4394 * B + 128
+// V = 0.4394 * R - 0.3679 * G - 0.0715 * B + 128
+// We use 16bit fixed point operations for RGB->YUV conversion (YUV_FIX).
+//
+// For the Y'CbCr to RGB conversion, the BT.601 specification reads:
+//   R = 1.164 * (Y-16) + 1.596 * (V-128)
+//   G = 1.164 * (Y-16) - 0.813 * (V-128) - 0.391 * (U-128)
+//   B = 1.164 * (Y-16)                   + 2.018 * (U-128)
+// where Y is in the [16,235] range, and U/V in the [16,240] range.
+// In the table-lookup version (WEBP_YUV_USE_TABLE), the common factor
+// "1.164 * (Y-16)" can be handled as an offset in the VP8kClip[] table.
+// So in this case the formulae should read:
+//   R = 1.164 * [Y + 1.371 * (V-128)                  ] - 18.624
+//   G = 1.164 * [Y - 0.698 * (V-128) - 0.336 * (U-128)] - 18.624
+//   B = 1.164 * [Y                   + 1.733 * (U-128)] - 18.624
+// once factorized.
+// For YUV->RGB conversion, only 14bit fixed precision is used (YUV_FIX2).
+// That's the maximum possible for a convenient ARM implementation.
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#ifndef WEBP_DSP_YUV_H_
+#define WEBP_DSP_YUV_H_
+
+#include "./dsp.h"
+#include "../dec/decode_vp8.h"
+
+// Define the following to use the LUT-based code:
+// #define WEBP_YUV_USE_TABLE
+
+#if defined(WEBP_EXPERIMENTAL_FEATURES)
+// Do NOT activate this feature for real compression. This is only experimental!
+// This flag is for comparison purpose against JPEG's "YUVj" natural colorspace.
+// This colorspace is close to Rec.601's Y'CbCr model with the notable
+// difference of allowing larger range for luma/chroma.
+// See http://en.wikipedia.org/wiki/YCbCr#JPEG_conversion paragraph, and its
+// difference with http://en.wikipedia.org/wiki/YCbCr#ITU-R_BT.601_conversion
+// #define USE_YUVj
+#endif
+
+//------------------------------------------------------------------------------
+// YUV -> RGB conversion
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum {
+  YUV_FIX = 16,                    // fixed-point precision for RGB->YUV
+  YUV_HALF = 1 << (YUV_FIX - 1),
+  YUV_MASK = (256 << YUV_FIX) - 1,
+  YUV_RANGE_MIN = -227,            // min value of r/g/b output
+  YUV_RANGE_MAX = 256 + 226,       // max value of r/g/b output
+
+  YUV_FIX2 = 14,                   // fixed-point precision for YUV->RGB
+  YUV_HALF2 = 1 << (YUV_FIX2 - 1),
+  YUV_MASK2 = (256 << YUV_FIX2) - 1
+};
+
+// These constants are 14b fixed-point version of ITU-R BT.601 constants.
+#define kYScale 19077    // 1.164 = 255 / 219
+#define kVToR   26149    // 1.596 = 255 / 112 * 0.701
+#define kUToG   6419     // 0.391 = 255 / 112 * 0.886 * 0.114 / 0.587
+#define kVToG   13320    // 0.813 = 255 / 112 * 0.701 * 0.299 / 0.587
+#define kUToB   33050    // 2.018 = 255 / 112 * 0.886
+#define kRCst (-kYScale * 16 - kVToR * 128 + YUV_HALF2)
+#define kGCst (-kYScale * 16 + kUToG * 128 + kVToG * 128 + YUV_HALF2)
+#define kBCst (-kYScale * 16 - kUToB * 128 + YUV_HALF2)
+
+//------------------------------------------------------------------------------
+
+#if !defined(WEBP_YUV_USE_TABLE)
+
+// slower on x86 by ~7-8%, but bit-exact with the SSE2 version
+
+static WEBP_INLINE int VP8Clip8(int v) {
+  return ((v & ~YUV_MASK2) == 0) ? (v >> YUV_FIX2) : (v < 0) ? 0 : 255;
+}
+
+static WEBP_INLINE int VP8YUVToR(int y, int v) {
+  return VP8Clip8(kYScale * y + kVToR * v + kRCst);
+}
+
+static WEBP_INLINE int VP8YUVToG(int y, int u, int v) {
+  return VP8Clip8(kYScale * y - kUToG * u - kVToG * v + kGCst);
+}
+
+static WEBP_INLINE int VP8YUVToB(int y, int u) {
+  return VP8Clip8(kYScale * y + kUToB * u + kBCst);
+}
+
+static WEBP_INLINE void VP8YuvToRgb(int y, int u, int v,
+                                    uint8_t* const rgb) {
+  rgb[0] = VP8YUVToR(y, v);
+  rgb[1] = VP8YUVToG(y, u, v);
+  rgb[2] = VP8YUVToB(y, u);
+}
+
+static WEBP_INLINE void VP8YuvToBgr(int y, int u, int v,
+                                    uint8_t* const bgr) {
+  bgr[0] = VP8YUVToB(y, u);
+  bgr[1] = VP8YUVToG(y, u, v);
+  bgr[2] = VP8YUVToR(y, v);
+}
+
+static WEBP_INLINE void VP8YuvToRgb565(int y, int u, int v,
+                                       uint8_t* const rgb) {
+  const int r = VP8YUVToR(y, v);      // 5 usable bits
+  const int g = VP8YUVToG(y, u, v);   // 6 usable bits
+  const int b = VP8YUVToB(y, u);      // 5 usable bits
+  const int rg = (r & 0xf8) | (g >> 5);
+  const int gb = ((g << 3) & 0xe0) | (b >> 3);
+#ifdef WEBP_SWAP_16BIT_CSP
+  rgb[0] = gb;
+  rgb[1] = rg;
+#else
+  rgb[0] = rg;
+  rgb[1] = gb;
+#endif
+}
+
+static WEBP_INLINE void VP8YuvToRgba4444(int y, int u, int v,
+                                         uint8_t* const argb) {
+  const int r = VP8YUVToR(y, v);        // 4 usable bits
+  const int g = VP8YUVToG(y, u, v);     // 4 usable bits
+  const int b = VP8YUVToB(y, u);        // 4 usable bits
+  const int rg = (r & 0xf0) | (g >> 4);
+  const int ba = (b & 0xf0) | 0x0f;     // overwrite the lower 4 bits
+#ifdef WEBP_SWAP_16BIT_CSP
+  argb[0] = ba;
+  argb[1] = rg;
+#else
+  argb[0] = rg;
+  argb[1] = ba;
+#endif
+}
+
+#else
+
+// Table-based version, not totally equivalent to the SSE2 version.
+// Rounding diff is only +/-1 though.
+
+extern int16_t VP8kVToR[256], VP8kUToB[256];
+extern int32_t VP8kVToG[256], VP8kUToG[256];
+extern uint8_t VP8kClip[YUV_RANGE_MAX - YUV_RANGE_MIN];
+extern uint8_t VP8kClip4Bits[YUV_RANGE_MAX - YUV_RANGE_MIN];
+
+static WEBP_INLINE void VP8YuvToRgb(int y, int u, int v,
+                                    uint8_t* const rgb) {
+  const int r_off = VP8kVToR[v];
+  const int g_off = (VP8kVToG[v] + VP8kUToG[u]) >> YUV_FIX;
+  const int b_off = VP8kUToB[u];
+  rgb[0] = VP8kClip[y + r_off - YUV_RANGE_MIN];
+  rgb[1] = VP8kClip[y + g_off - YUV_RANGE_MIN];
+  rgb[2] = VP8kClip[y + b_off - YUV_RANGE_MIN];
+}
+
+static WEBP_INLINE void VP8YuvToBgr(int y, int u, int v,
+                                    uint8_t* const bgr) {
+  const int r_off = VP8kVToR[v];
+  const int g_off = (VP8kVToG[v] + VP8kUToG[u]) >> YUV_FIX;
+  const int b_off = VP8kUToB[u];
+  bgr[0] = VP8kClip[y + b_off - YUV_RANGE_MIN];
+  bgr[1] = VP8kClip[y + g_off - YUV_RANGE_MIN];
+  bgr[2] = VP8kClip[y + r_off - YUV_RANGE_MIN];
+}
+
+static WEBP_INLINE void VP8YuvToRgb565(int y, int u, int v,
+                                       uint8_t* const rgb) {
+  const int r_off = VP8kVToR[v];
+  const int g_off = (VP8kVToG[v] + VP8kUToG[u]) >> YUV_FIX;
+  const int b_off = VP8kUToB[u];
+  const int rg = ((VP8kClip[y + r_off - YUV_RANGE_MIN] & 0xf8) |
+                  (VP8kClip[y + g_off - YUV_RANGE_MIN] >> 5));
+  const int gb = (((VP8kClip[y + g_off - YUV_RANGE_MIN] << 3) & 0xe0) |
+                   (VP8kClip[y + b_off - YUV_RANGE_MIN] >> 3));
+#ifdef WEBP_SWAP_16BIT_CSP
+  rgb[0] = gb;
+  rgb[1] = rg;
+#else
+  rgb[0] = rg;
+  rgb[1] = gb;
+#endif
+}
+
+static WEBP_INLINE void VP8YuvToRgba4444(int y, int u, int v,
+                                         uint8_t* const argb) {
+  const int r_off = VP8kVToR[v];
+  const int g_off = (VP8kVToG[v] + VP8kUToG[u]) >> YUV_FIX;
+  const int b_off = VP8kUToB[u];
+  const int rg = ((VP8kClip4Bits[y + r_off - YUV_RANGE_MIN] << 4) |
+                   VP8kClip4Bits[y + g_off - YUV_RANGE_MIN]);
+  const int ba = (VP8kClip4Bits[y + b_off - YUV_RANGE_MIN] << 4) | 0x0f;
+#ifdef WEBP_SWAP_16BIT_CSP
+  argb[0] = ba;
+  argb[1] = rg;
+#else
+  argb[0] = rg;
+  argb[1] = ba;
+#endif
+}
+
+#endif  // WEBP_YUV_USE_TABLE
+
+//-----------------------------------------------------------------------------
+// Alpha handling variants
+
+static WEBP_INLINE void VP8YuvToArgb(uint8_t y, uint8_t u, uint8_t v,
+                                     uint8_t* const argb) {
+  argb[0] = 0xff;
+  VP8YuvToRgb(y, u, v, argb + 1);
+}
+
+static WEBP_INLINE void VP8YuvToBgra(uint8_t y, uint8_t u, uint8_t v,
+                                     uint8_t* const bgra) {
+  VP8YuvToBgr(y, u, v, bgra);
+  bgra[3] = 0xff;
+}
+
+static WEBP_INLINE void VP8YuvToRgba(uint8_t y, uint8_t u, uint8_t v,
+                                     uint8_t* const rgba) {
+  VP8YuvToRgb(y, u, v, rgba);
+  rgba[3] = 0xff;
+}
+
+// Must be called before everything, to initialize the tables.
+void VP8YUVInit(void);
+
+//-----------------------------------------------------------------------------
+// SSE2 extra functions (mostly for upsampling_sse2.c)
+
+#if defined(WEBP_USE_SSE2)
+
+// When the following is defined, tables are initialized statically, adding ~12k
+// to the binary size. Otherwise, they are initialized at run-time (small cost).
+#define WEBP_YUV_USE_SSE2_TABLES
+
+#if defined(FANCY_UPSAMPLING)
+// Process 32 pixels and store the result (24b or 32b per pixel) in *dst.
+void VP8YuvToRgba32(const uint8_t* y, const uint8_t* u, const uint8_t* v,
+                    uint8_t* dst);
+void VP8YuvToRgb32(const uint8_t* y, const uint8_t* u, const uint8_t* v,
+                   uint8_t* dst);
+void VP8YuvToBgra32(const uint8_t* y, const uint8_t* u, const uint8_t* v,
+                    uint8_t* dst);
+void VP8YuvToBgr32(const uint8_t* y, const uint8_t* u, const uint8_t* v,
+                   uint8_t* dst);
+#endif  // FANCY_UPSAMPLING
+
+// Must be called to initialize tables before using the functions.
+void VP8YUVInitSSE2(void);
+
+#endif    // WEBP_USE_SSE2
+
+//------------------------------------------------------------------------------
+// RGB -> YUV conversion
+
+// Stub functions that can be called with various rounding values:
+static WEBP_INLINE int VP8ClipUV(int uv, int rounding) {
+  uv = (uv + rounding + (128 << (YUV_FIX + 2))) >> (YUV_FIX + 2);
+  return ((uv & ~0xff) == 0) ? uv : (uv < 0) ? 0 : 255;
+}
+
+#ifndef USE_YUVj
+
+static WEBP_INLINE int VP8RGBToY(int r, int g, int b, int rounding) {
+  const int luma = 16839 * r + 33059 * g + 6420 * b;
+  return (luma + rounding + (16 << YUV_FIX)) >> YUV_FIX;  // no need to clip
+}
+
+static WEBP_INLINE int VP8RGBToU(int r, int g, int b, int rounding) {
+  const int u = -9719 * r - 19081 * g + 28800 * b;
+  return VP8ClipUV(u, rounding);
+}
+
+static WEBP_INLINE int VP8RGBToV(int r, int g, int b, int rounding) {
+  const int v = +28800 * r - 24116 * g - 4684 * b;
+  return VP8ClipUV(v, rounding);
+}
+
+#else
+
+// This JPEG-YUV colorspace, only for comparison!
+// These are also 16bit precision coefficients from Rec.601, but with full
+// [0..255] output range.
+static WEBP_INLINE int VP8RGBToY(int r, int g, int b, int rounding) {
+  const int luma = 19595 * r + 38470 * g + 7471 * b;
+  return (luma + rounding) >> YUV_FIX;  // no need to clip
+}
+
+static WEBP_INLINE int VP8RGBToU(int r, int g, int b, int rounding) {
+  const int u = -11058 * r - 21710 * g + 32768 * b;
+  return VP8ClipUV(u, rounding);
+}
+
+static WEBP_INLINE int VP8RGBToV(int r, int g, int b, int rounding) {
+  const int v = 32768 * r - 27439 * g - 5329 * b;
+  return VP8ClipUV(v, rounding);
+}
+
+#endif    // USE_YUVj
+
+#ifdef __cplusplus
+}    // extern "C"
+#endif
+
+#endif  /* WEBP_DSP_YUV_H_ */
diff --git a/Source/LibWebP/src/dsp/yuv_tables_sse2.h b/Source/LibWebP/src/dsp/yuv_tables_sse2.h
new file mode 100644
index 0000000..6b1f4c3
--- /dev/null
+++ b/Source/LibWebP/src/dsp/yuv_tables_sse2.h
@@ -0,0 +1,536 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// SSE2 tables for YUV->RGB conversion (12kB overall)
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+// This file is not compiled, but #include'd directly from yuv.c
+// Only used if WEBP_YUV_USE_SSE2_TABLES is defined.
+
+static const VP8kCstSSE2 VP8kYtoRGBA[256] = {
+  {{0xfffb77b0, 0xfffb77b0, 0xfffb77b0, 0x003fc000}},
+  {{0xfffbc235, 0xfffbc235, 0xfffbc235, 0x003fc000}},
+  {{0xfffc0cba, 0xfffc0cba, 0xfffc0cba, 0x003fc000}},
+  {{0xfffc573f, 0xfffc573f, 0xfffc573f, 0x003fc000}},
+  {{0xfffca1c4, 0xfffca1c4, 0xfffca1c4, 0x003fc000}},
+  {{0xfffcec49, 0xfffcec49, 0xfffcec49, 0x003fc000}},
+  {{0xfffd36ce, 0xfffd36ce, 0xfffd36ce, 0x003fc000}},
+  {{0xfffd8153, 0xfffd8153, 0xfffd8153, 0x003fc000}},
+  {{0xfffdcbd8, 0xfffdcbd8, 0xfffdcbd8, 0x003fc000}},
+  {{0xfffe165d, 0xfffe165d, 0xfffe165d, 0x003fc000}},
+  {{0xfffe60e2, 0xfffe60e2, 0xfffe60e2, 0x003fc000}},
+  {{0xfffeab67, 0xfffeab67, 0xfffeab67, 0x003fc000}},
+  {{0xfffef5ec, 0xfffef5ec, 0xfffef5ec, 0x003fc000}},
+  {{0xffff4071, 0xffff4071, 0xffff4071, 0x003fc000}},
+  {{0xffff8af6, 0xffff8af6, 0xffff8af6, 0x003fc000}},
+  {{0xffffd57b, 0xffffd57b, 0xffffd57b, 0x003fc000}},
+  {{0x00002000, 0x00002000, 0x00002000, 0x003fc000}},
+  {{0x00006a85, 0x00006a85, 0x00006a85, 0x003fc000}},
+  {{0x0000b50a, 0x0000b50a, 0x0000b50a, 0x003fc000}},
+  {{0x0000ff8f, 0x0000ff8f, 0x0000ff8f, 0x003fc000}},
+  {{0x00014a14, 0x00014a14, 0x00014a14, 0x003fc000}},
+  {{0x00019499, 0x00019499, 0x00019499, 0x003fc000}},
+  {{0x0001df1e, 0x0001df1e, 0x0001df1e, 0x003fc000}},
+  {{0x000229a3, 0x000229a3, 0x000229a3, 0x003fc000}},
+  {{0x00027428, 0x00027428, 0x00027428, 0x003fc000}},
+  {{0x0002bead, 0x0002bead, 0x0002bead, 0x003fc000}},
+  {{0x00030932, 0x00030932, 0x00030932, 0x003fc000}},
+  {{0x000353b7, 0x000353b7, 0x000353b7, 0x003fc000}},
+  {{0x00039e3c, 0x00039e3c, 0x00039e3c, 0x003fc000}},
+  {{0x0003e8c1, 0x0003e8c1, 0x0003e8c1, 0x003fc000}},
+  {{0x00043346, 0x00043346, 0x00043346, 0x003fc000}},
+  {{0x00047dcb, 0x00047dcb, 0x00047dcb, 0x003fc000}},
+  {{0x0004c850, 0x0004c850, 0x0004c850, 0x003fc000}},
+  {{0x000512d5, 0x000512d5, 0x000512d5, 0x003fc000}},
+  {{0x00055d5a, 0x00055d5a, 0x00055d5a, 0x003fc000}},
+  {{0x0005a7df, 0x0005a7df, 0x0005a7df, 0x003fc000}},
+  {{0x0005f264, 0x0005f264, 0x0005f264, 0x003fc000}},
+  {{0x00063ce9, 0x00063ce9, 0x00063ce9, 0x003fc000}},
+  {{0x0006876e, 0x0006876e, 0x0006876e, 0x003fc000}},
+  {{0x0006d1f3, 0x0006d1f3, 0x0006d1f3, 0x003fc000}},
+  {{0x00071c78, 0x00071c78, 0x00071c78, 0x003fc000}},
+  {{0x000766fd, 0x000766fd, 0x000766fd, 0x003fc000}},
+  {{0x0007b182, 0x0007b182, 0x0007b182, 0x003fc000}},
+  {{0x0007fc07, 0x0007fc07, 0x0007fc07, 0x003fc000}},
+  {{0x0008468c, 0x0008468c, 0x0008468c, 0x003fc000}},
+  {{0x00089111, 0x00089111, 0x00089111, 0x003fc000}},
+  {{0x0008db96, 0x0008db96, 0x0008db96, 0x003fc000}},
+  {{0x0009261b, 0x0009261b, 0x0009261b, 0x003fc000}},
+  {{0x000970a0, 0x000970a0, 0x000970a0, 0x003fc000}},
+  {{0x0009bb25, 0x0009bb25, 0x0009bb25, 0x003fc000}},
+  {{0x000a05aa, 0x000a05aa, 0x000a05aa, 0x003fc000}},
+  {{0x000a502f, 0x000a502f, 0x000a502f, 0x003fc000}},
+  {{0x000a9ab4, 0x000a9ab4, 0x000a9ab4, 0x003fc000}},
+  {{0x000ae539, 0x000ae539, 0x000ae539, 0x003fc000}},
+  {{0x000b2fbe, 0x000b2fbe, 0x000b2fbe, 0x003fc000}},
+  {{0x000b7a43, 0x000b7a43, 0x000b7a43, 0x003fc000}},
+  {{0x000bc4c8, 0x000bc4c8, 0x000bc4c8, 0x003fc000}},
+  {{0x000c0f4d, 0x000c0f4d, 0x000c0f4d, 0x003fc000}},
+  {{0x000c59d2, 0x000c59d2, 0x000c59d2, 0x003fc000}},
+  {{0x000ca457, 0x000ca457, 0x000ca457, 0x003fc000}},
+  {{0x000ceedc, 0x000ceedc, 0x000ceedc, 0x003fc000}},
+  {{0x000d3961, 0x000d3961, 0x000d3961, 0x003fc000}},
+  {{0x000d83e6, 0x000d83e6, 0x000d83e6, 0x003fc000}},
+  {{0x000dce6b, 0x000dce6b, 0x000dce6b, 0x003fc000}},
+  {{0x000e18f0, 0x000e18f0, 0x000e18f0, 0x003fc000}},
+  {{0x000e6375, 0x000e6375, 0x000e6375, 0x003fc000}},
+  {{0x000eadfa, 0x000eadfa, 0x000eadfa, 0x003fc000}},
+  {{0x000ef87f, 0x000ef87f, 0x000ef87f, 0x003fc000}},
+  {{0x000f4304, 0x000f4304, 0x000f4304, 0x003fc000}},
+  {{0x000f8d89, 0x000f8d89, 0x000f8d89, 0x003fc000}},
+  {{0x000fd80e, 0x000fd80e, 0x000fd80e, 0x003fc000}},
+  {{0x00102293, 0x00102293, 0x00102293, 0x003fc000}},
+  {{0x00106d18, 0x00106d18, 0x00106d18, 0x003fc000}},
+  {{0x0010b79d, 0x0010b79d, 0x0010b79d, 0x003fc000}},
+  {{0x00110222, 0x00110222, 0x00110222, 0x003fc000}},
+  {{0x00114ca7, 0x00114ca7, 0x00114ca7, 0x003fc000}},
+  {{0x0011972c, 0x0011972c, 0x0011972c, 0x003fc000}},
+  {{0x0011e1b1, 0x0011e1b1, 0x0011e1b1, 0x003fc000}},
+  {{0x00122c36, 0x00122c36, 0x00122c36, 0x003fc000}},
+  {{0x001276bb, 0x001276bb, 0x001276bb, 0x003fc000}},
+  {{0x0012c140, 0x0012c140, 0x0012c140, 0x003fc000}},
+  {{0x00130bc5, 0x00130bc5, 0x00130bc5, 0x003fc000}},
+  {{0x0013564a, 0x0013564a, 0x0013564a, 0x003fc000}},
+  {{0x0013a0cf, 0x0013a0cf, 0x0013a0cf, 0x003fc000}},
+  {{0x0013eb54, 0x0013eb54, 0x0013eb54, 0x003fc000}},
+  {{0x001435d9, 0x001435d9, 0x001435d9, 0x003fc000}},
+  {{0x0014805e, 0x0014805e, 0x0014805e, 0x003fc000}},
+  {{0x0014cae3, 0x0014cae3, 0x0014cae3, 0x003fc000}},
+  {{0x00151568, 0x00151568, 0x00151568, 0x003fc000}},
+  {{0x00155fed, 0x00155fed, 0x00155fed, 0x003fc000}},
+  {{0x0015aa72, 0x0015aa72, 0x0015aa72, 0x003fc000}},
+  {{0x0015f4f7, 0x0015f4f7, 0x0015f4f7, 0x003fc000}},
+  {{0x00163f7c, 0x00163f7c, 0x00163f7c, 0x003fc000}},
+  {{0x00168a01, 0x00168a01, 0x00168a01, 0x003fc000}},
+  {{0x0016d486, 0x0016d486, 0x0016d486, 0x003fc000}},
+  {{0x00171f0b, 0x00171f0b, 0x00171f0b, 0x003fc000}},
+  {{0x00176990, 0x00176990, 0x00176990, 0x003fc000}},
+  {{0x0017b415, 0x0017b415, 0x0017b415, 0x003fc000}},
+  {{0x0017fe9a, 0x0017fe9a, 0x0017fe9a, 0x003fc000}},
+  {{0x0018491f, 0x0018491f, 0x0018491f, 0x003fc000}},
+  {{0x001893a4, 0x001893a4, 0x001893a4, 0x003fc000}},
+  {{0x0018de29, 0x0018de29, 0x0018de29, 0x003fc000}},
+  {{0x001928ae, 0x001928ae, 0x001928ae, 0x003fc000}},
+  {{0x00197333, 0x00197333, 0x00197333, 0x003fc000}},
+  {{0x0019bdb8, 0x0019bdb8, 0x0019bdb8, 0x003fc000}},
+  {{0x001a083d, 0x001a083d, 0x001a083d, 0x003fc000}},
+  {{0x001a52c2, 0x001a52c2, 0x001a52c2, 0x003fc000}},
+  {{0x001a9d47, 0x001a9d47, 0x001a9d47, 0x003fc000}},
+  {{0x001ae7cc, 0x001ae7cc, 0x001ae7cc, 0x003fc000}},
+  {{0x001b3251, 0x001b3251, 0x001b3251, 0x003fc000}},
+  {{0x001b7cd6, 0x001b7cd6, 0x001b7cd6, 0x003fc000}},
+  {{0x001bc75b, 0x001bc75b, 0x001bc75b, 0x003fc000}},
+  {{0x001c11e0, 0x001c11e0, 0x001c11e0, 0x003fc000}},
+  {{0x001c5c65, 0x001c5c65, 0x001c5c65, 0x003fc000}},
+  {{0x001ca6ea, 0x001ca6ea, 0x001ca6ea, 0x003fc000}},
+  {{0x001cf16f, 0x001cf16f, 0x001cf16f, 0x003fc000}},
+  {{0x001d3bf4, 0x001d3bf4, 0x001d3bf4, 0x003fc000}},
+  {{0x001d8679, 0x001d8679, 0x001d8679, 0x003fc000}},
+  {{0x001dd0fe, 0x001dd0fe, 0x001dd0fe, 0x003fc000}},
+  {{0x001e1b83, 0x001e1b83, 0x001e1b83, 0x003fc000}},
+  {{0x001e6608, 0x001e6608, 0x001e6608, 0x003fc000}},
+  {{0x001eb08d, 0x001eb08d, 0x001eb08d, 0x003fc000}},
+  {{0x001efb12, 0x001efb12, 0x001efb12, 0x003fc000}},
+  {{0x001f4597, 0x001f4597, 0x001f4597, 0x003fc000}},
+  {{0x001f901c, 0x001f901c, 0x001f901c, 0x003fc000}},
+  {{0x001fdaa1, 0x001fdaa1, 0x001fdaa1, 0x003fc000}},
+  {{0x00202526, 0x00202526, 0x00202526, 0x003fc000}},
+  {{0x00206fab, 0x00206fab, 0x00206fab, 0x003fc000}},
+  {{0x0020ba30, 0x0020ba30, 0x0020ba30, 0x003fc000}},
+  {{0x002104b5, 0x002104b5, 0x002104b5, 0x003fc000}},
+  {{0x00214f3a, 0x00214f3a, 0x00214f3a, 0x003fc000}},
+  {{0x002199bf, 0x002199bf, 0x002199bf, 0x003fc000}},
+  {{0x0021e444, 0x0021e444, 0x0021e444, 0x003fc000}},
+  {{0x00222ec9, 0x00222ec9, 0x00222ec9, 0x003fc000}},
+  {{0x0022794e, 0x0022794e, 0x0022794e, 0x003fc000}},
+  {{0x0022c3d3, 0x0022c3d3, 0x0022c3d3, 0x003fc000}},
+  {{0x00230e58, 0x00230e58, 0x00230e58, 0x003fc000}},
+  {{0x002358dd, 0x002358dd, 0x002358dd, 0x003fc000}},
+  {{0x0023a362, 0x0023a362, 0x0023a362, 0x003fc000}},
+  {{0x0023ede7, 0x0023ede7, 0x0023ede7, 0x003fc000}},
+  {{0x0024386c, 0x0024386c, 0x0024386c, 0x003fc000}},
+  {{0x002482f1, 0x002482f1, 0x002482f1, 0x003fc000}},
+  {{0x0024cd76, 0x0024cd76, 0x0024cd76, 0x003fc000}},
+  {{0x002517fb, 0x002517fb, 0x002517fb, 0x003fc000}},
+  {{0x00256280, 0x00256280, 0x00256280, 0x003fc000}},
+  {{0x0025ad05, 0x0025ad05, 0x0025ad05, 0x003fc000}},
+  {{0x0025f78a, 0x0025f78a, 0x0025f78a, 0x003fc000}},
+  {{0x0026420f, 0x0026420f, 0x0026420f, 0x003fc000}},
+  {{0x00268c94, 0x00268c94, 0x00268c94, 0x003fc000}},
+  {{0x0026d719, 0x0026d719, 0x0026d719, 0x003fc000}},
+  {{0x0027219e, 0x0027219e, 0x0027219e, 0x003fc000}},
+  {{0x00276c23, 0x00276c23, 0x00276c23, 0x003fc000}},
+  {{0x0027b6a8, 0x0027b6a8, 0x0027b6a8, 0x003fc000}},
+  {{0x0028012d, 0x0028012d, 0x0028012d, 0x003fc000}},
+  {{0x00284bb2, 0x00284bb2, 0x00284bb2, 0x003fc000}},
+  {{0x00289637, 0x00289637, 0x00289637, 0x003fc000}},
+  {{0x0028e0bc, 0x0028e0bc, 0x0028e0bc, 0x003fc000}},
+  {{0x00292b41, 0x00292b41, 0x00292b41, 0x003fc000}},
+  {{0x002975c6, 0x002975c6, 0x002975c6, 0x003fc000}},
+  {{0x0029c04b, 0x0029c04b, 0x0029c04b, 0x003fc000}},
+  {{0x002a0ad0, 0x002a0ad0, 0x002a0ad0, 0x003fc000}},
+  {{0x002a5555, 0x002a5555, 0x002a5555, 0x003fc000}},
+  {{0x002a9fda, 0x002a9fda, 0x002a9fda, 0x003fc000}},
+  {{0x002aea5f, 0x002aea5f, 0x002aea5f, 0x003fc000}},
+  {{0x002b34e4, 0x002b34e4, 0x002b34e4, 0x003fc000}},
+  {{0x002b7f69, 0x002b7f69, 0x002b7f69, 0x003fc000}},
+  {{0x002bc9ee, 0x002bc9ee, 0x002bc9ee, 0x003fc000}},
+  {{0x002c1473, 0x002c1473, 0x002c1473, 0x003fc000}},
+  {{0x002c5ef8, 0x002c5ef8, 0x002c5ef8, 0x003fc000}},
+  {{0x002ca97d, 0x002ca97d, 0x002ca97d, 0x003fc000}},
+  {{0x002cf402, 0x002cf402, 0x002cf402, 0x003fc000}},
+  {{0x002d3e87, 0x002d3e87, 0x002d3e87, 0x003fc000}},
+  {{0x002d890c, 0x002d890c, 0x002d890c, 0x003fc000}},
+  {{0x002dd391, 0x002dd391, 0x002dd391, 0x003fc000}},
+  {{0x002e1e16, 0x002e1e16, 0x002e1e16, 0x003fc000}},
+  {{0x002e689b, 0x002e689b, 0x002e689b, 0x003fc000}},
+  {{0x002eb320, 0x002eb320, 0x002eb320, 0x003fc000}},
+  {{0x002efda5, 0x002efda5, 0x002efda5, 0x003fc000}},
+  {{0x002f482a, 0x002f482a, 0x002f482a, 0x003fc000}},
+  {{0x002f92af, 0x002f92af, 0x002f92af, 0x003fc000}},
+  {{0x002fdd34, 0x002fdd34, 0x002fdd34, 0x003fc000}},
+  {{0x003027b9, 0x003027b9, 0x003027b9, 0x003fc000}},
+  {{0x0030723e, 0x0030723e, 0x0030723e, 0x003fc000}},
+  {{0x0030bcc3, 0x0030bcc3, 0x0030bcc3, 0x003fc000}},
+  {{0x00310748, 0x00310748, 0x00310748, 0x003fc000}},
+  {{0x003151cd, 0x003151cd, 0x003151cd, 0x003fc000}},
+  {{0x00319c52, 0x00319c52, 0x00319c52, 0x003fc000}},
+  {{0x0031e6d7, 0x0031e6d7, 0x0031e6d7, 0x003fc000}},
+  {{0x0032315c, 0x0032315c, 0x0032315c, 0x003fc000}},
+  {{0x00327be1, 0x00327be1, 0x00327be1, 0x003fc000}},
+  {{0x0032c666, 0x0032c666, 0x0032c666, 0x003fc000}},
+  {{0x003310eb, 0x003310eb, 0x003310eb, 0x003fc000}},
+  {{0x00335b70, 0x00335b70, 0x00335b70, 0x003fc000}},
+  {{0x0033a5f5, 0x0033a5f5, 0x0033a5f5, 0x003fc000}},
+  {{0x0033f07a, 0x0033f07a, 0x0033f07a, 0x003fc000}},
+  {{0x00343aff, 0x00343aff, 0x00343aff, 0x003fc000}},
+  {{0x00348584, 0x00348584, 0x00348584, 0x003fc000}},
+  {{0x0034d009, 0x0034d009, 0x0034d009, 0x003fc000}},
+  {{0x00351a8e, 0x00351a8e, 0x00351a8e, 0x003fc000}},
+  {{0x00356513, 0x00356513, 0x00356513, 0x003fc000}},
+  {{0x0035af98, 0x0035af98, 0x0035af98, 0x003fc000}},
+  {{0x0035fa1d, 0x0035fa1d, 0x0035fa1d, 0x003fc000}},
+  {{0x003644a2, 0x003644a2, 0x003644a2, 0x003fc000}},
+  {{0x00368f27, 0x00368f27, 0x00368f27, 0x003fc000}},
+  {{0x0036d9ac, 0x0036d9ac, 0x0036d9ac, 0x003fc000}},
+  {{0x00372431, 0x00372431, 0x00372431, 0x003fc000}},
+  {{0x00376eb6, 0x00376eb6, 0x00376eb6, 0x003fc000}},
+  {{0x0037b93b, 0x0037b93b, 0x0037b93b, 0x003fc000}},
+  {{0x003803c0, 0x003803c0, 0x003803c0, 0x003fc000}},
+  {{0x00384e45, 0x00384e45, 0x00384e45, 0x003fc000}},
+  {{0x003898ca, 0x003898ca, 0x003898ca, 0x003fc000}},
+  {{0x0038e34f, 0x0038e34f, 0x0038e34f, 0x003fc000}},
+  {{0x00392dd4, 0x00392dd4, 0x00392dd4, 0x003fc000}},
+  {{0x00397859, 0x00397859, 0x00397859, 0x003fc000}},
+  {{0x0039c2de, 0x0039c2de, 0x0039c2de, 0x003fc000}},
+  {{0x003a0d63, 0x003a0d63, 0x003a0d63, 0x003fc000}},
+  {{0x003a57e8, 0x003a57e8, 0x003a57e8, 0x003fc000}},
+  {{0x003aa26d, 0x003aa26d, 0x003aa26d, 0x003fc000}},
+  {{0x003aecf2, 0x003aecf2, 0x003aecf2, 0x003fc000}},
+  {{0x003b3777, 0x003b3777, 0x003b3777, 0x003fc000}},
+  {{0x003b81fc, 0x003b81fc, 0x003b81fc, 0x003fc000}},
+  {{0x003bcc81, 0x003bcc81, 0x003bcc81, 0x003fc000}},
+  {{0x003c1706, 0x003c1706, 0x003c1706, 0x003fc000}},
+  {{0x003c618b, 0x003c618b, 0x003c618b, 0x003fc000}},
+  {{0x003cac10, 0x003cac10, 0x003cac10, 0x003fc000}},
+  {{0x003cf695, 0x003cf695, 0x003cf695, 0x003fc000}},
+  {{0x003d411a, 0x003d411a, 0x003d411a, 0x003fc000}},
+  {{0x003d8b9f, 0x003d8b9f, 0x003d8b9f, 0x003fc000}},
+  {{0x003dd624, 0x003dd624, 0x003dd624, 0x003fc000}},
+  {{0x003e20a9, 0x003e20a9, 0x003e20a9, 0x003fc000}},
+  {{0x003e6b2e, 0x003e6b2e, 0x003e6b2e, 0x003fc000}},
+  {{0x003eb5b3, 0x003eb5b3, 0x003eb5b3, 0x003fc000}},
+  {{0x003f0038, 0x003f0038, 0x003f0038, 0x003fc000}},
+  {{0x003f4abd, 0x003f4abd, 0x003f4abd, 0x003fc000}},
+  {{0x003f9542, 0x003f9542, 0x003f9542, 0x003fc000}},
+  {{0x003fdfc7, 0x003fdfc7, 0x003fdfc7, 0x003fc000}},
+  {{0x00402a4c, 0x00402a4c, 0x00402a4c, 0x003fc000}},
+  {{0x004074d1, 0x004074d1, 0x004074d1, 0x003fc000}},
+  {{0x0040bf56, 0x0040bf56, 0x0040bf56, 0x003fc000}},
+  {{0x004109db, 0x004109db, 0x004109db, 0x003fc000}},
+  {{0x00415460, 0x00415460, 0x00415460, 0x003fc000}},
+  {{0x00419ee5, 0x00419ee5, 0x00419ee5, 0x003fc000}},
+  {{0x0041e96a, 0x0041e96a, 0x0041e96a, 0x003fc000}},
+  {{0x004233ef, 0x004233ef, 0x004233ef, 0x003fc000}},
+  {{0x00427e74, 0x00427e74, 0x00427e74, 0x003fc000}},
+  {{0x0042c8f9, 0x0042c8f9, 0x0042c8f9, 0x003fc000}},
+  {{0x0043137e, 0x0043137e, 0x0043137e, 0x003fc000}},
+  {{0x00435e03, 0x00435e03, 0x00435e03, 0x003fc000}},
+  {{0x0043a888, 0x0043a888, 0x0043a888, 0x003fc000}},
+  {{0x0043f30d, 0x0043f30d, 0x0043f30d, 0x003fc000}},
+  {{0x00443d92, 0x00443d92, 0x00443d92, 0x003fc000}},
+  {{0x00448817, 0x00448817, 0x00448817, 0x003fc000}},
+  {{0x0044d29c, 0x0044d29c, 0x0044d29c, 0x003fc000}},
+  {{0x00451d21, 0x00451d21, 0x00451d21, 0x003fc000}},
+  {{0x004567a6, 0x004567a6, 0x004567a6, 0x003fc000}},
+  {{0x0045b22b, 0x0045b22b, 0x0045b22b, 0x003fc000}}
+};
+
+static const VP8kCstSSE2 VP8kUtoRGBA[256] = {
+  {{0, 0x000c8980, 0xffbf7300, 0}}, {{0, 0x000c706d, 0xffbff41a, 0}},
+  {{0, 0x000c575a, 0xffc07534, 0}}, {{0, 0x000c3e47, 0xffc0f64e, 0}},
+  {{0, 0x000c2534, 0xffc17768, 0}}, {{0, 0x000c0c21, 0xffc1f882, 0}},
+  {{0, 0x000bf30e, 0xffc2799c, 0}}, {{0, 0x000bd9fb, 0xffc2fab6, 0}},
+  {{0, 0x000bc0e8, 0xffc37bd0, 0}}, {{0, 0x000ba7d5, 0xffc3fcea, 0}},
+  {{0, 0x000b8ec2, 0xffc47e04, 0}}, {{0, 0x000b75af, 0xffc4ff1e, 0}},
+  {{0, 0x000b5c9c, 0xffc58038, 0}}, {{0, 0x000b4389, 0xffc60152, 0}},
+  {{0, 0x000b2a76, 0xffc6826c, 0}}, {{0, 0x000b1163, 0xffc70386, 0}},
+  {{0, 0x000af850, 0xffc784a0, 0}}, {{0, 0x000adf3d, 0xffc805ba, 0}},
+  {{0, 0x000ac62a, 0xffc886d4, 0}}, {{0, 0x000aad17, 0xffc907ee, 0}},
+  {{0, 0x000a9404, 0xffc98908, 0}}, {{0, 0x000a7af1, 0xffca0a22, 0}},
+  {{0, 0x000a61de, 0xffca8b3c, 0}}, {{0, 0x000a48cb, 0xffcb0c56, 0}},
+  {{0, 0x000a2fb8, 0xffcb8d70, 0}}, {{0, 0x000a16a5, 0xffcc0e8a, 0}},
+  {{0, 0x0009fd92, 0xffcc8fa4, 0}}, {{0, 0x0009e47f, 0xffcd10be, 0}},
+  {{0, 0x0009cb6c, 0xffcd91d8, 0}}, {{0, 0x0009b259, 0xffce12f2, 0}},
+  {{0, 0x00099946, 0xffce940c, 0}}, {{0, 0x00098033, 0xffcf1526, 0}},
+  {{0, 0x00096720, 0xffcf9640, 0}}, {{0, 0x00094e0d, 0xffd0175a, 0}},
+  {{0, 0x000934fa, 0xffd09874, 0}}, {{0, 0x00091be7, 0xffd1198e, 0}},
+  {{0, 0x000902d4, 0xffd19aa8, 0}}, {{0, 0x0008e9c1, 0xffd21bc2, 0}},
+  {{0, 0x0008d0ae, 0xffd29cdc, 0}}, {{0, 0x0008b79b, 0xffd31df6, 0}},
+  {{0, 0x00089e88, 0xffd39f10, 0}}, {{0, 0x00088575, 0xffd4202a, 0}},
+  {{0, 0x00086c62, 0xffd4a144, 0}}, {{0, 0x0008534f, 0xffd5225e, 0}},
+  {{0, 0x00083a3c, 0xffd5a378, 0}}, {{0, 0x00082129, 0xffd62492, 0}},
+  {{0, 0x00080816, 0xffd6a5ac, 0}}, {{0, 0x0007ef03, 0xffd726c6, 0}},
+  {{0, 0x0007d5f0, 0xffd7a7e0, 0}}, {{0, 0x0007bcdd, 0xffd828fa, 0}},
+  {{0, 0x0007a3ca, 0xffd8aa14, 0}}, {{0, 0x00078ab7, 0xffd92b2e, 0}},
+  {{0, 0x000771a4, 0xffd9ac48, 0}}, {{0, 0x00075891, 0xffda2d62, 0}},
+  {{0, 0x00073f7e, 0xffdaae7c, 0}}, {{0, 0x0007266b, 0xffdb2f96, 0}},
+  {{0, 0x00070d58, 0xffdbb0b0, 0}}, {{0, 0x0006f445, 0xffdc31ca, 0}},
+  {{0, 0x0006db32, 0xffdcb2e4, 0}}, {{0, 0x0006c21f, 0xffdd33fe, 0}},
+  {{0, 0x0006a90c, 0xffddb518, 0}}, {{0, 0x00068ff9, 0xffde3632, 0}},
+  {{0, 0x000676e6, 0xffdeb74c, 0}}, {{0, 0x00065dd3, 0xffdf3866, 0}},
+  {{0, 0x000644c0, 0xffdfb980, 0}}, {{0, 0x00062bad, 0xffe03a9a, 0}},
+  {{0, 0x0006129a, 0xffe0bbb4, 0}}, {{0, 0x0005f987, 0xffe13cce, 0}},
+  {{0, 0x0005e074, 0xffe1bde8, 0}}, {{0, 0x0005c761, 0xffe23f02, 0}},
+  {{0, 0x0005ae4e, 0xffe2c01c, 0}}, {{0, 0x0005953b, 0xffe34136, 0}},
+  {{0, 0x00057c28, 0xffe3c250, 0}}, {{0, 0x00056315, 0xffe4436a, 0}},
+  {{0, 0x00054a02, 0xffe4c484, 0}}, {{0, 0x000530ef, 0xffe5459e, 0}},
+  {{0, 0x000517dc, 0xffe5c6b8, 0}}, {{0, 0x0004fec9, 0xffe647d2, 0}},
+  {{0, 0x0004e5b6, 0xffe6c8ec, 0}}, {{0, 0x0004cca3, 0xffe74a06, 0}},
+  {{0, 0x0004b390, 0xffe7cb20, 0}}, {{0, 0x00049a7d, 0xffe84c3a, 0}},
+  {{0, 0x0004816a, 0xffe8cd54, 0}}, {{0, 0x00046857, 0xffe94e6e, 0}},
+  {{0, 0x00044f44, 0xffe9cf88, 0}}, {{0, 0x00043631, 0xffea50a2, 0}},
+  {{0, 0x00041d1e, 0xffead1bc, 0}}, {{0, 0x0004040b, 0xffeb52d6, 0}},
+  {{0, 0x0003eaf8, 0xffebd3f0, 0}}, {{0, 0x0003d1e5, 0xffec550a, 0}},
+  {{0, 0x0003b8d2, 0xffecd624, 0}}, {{0, 0x00039fbf, 0xffed573e, 0}},
+  {{0, 0x000386ac, 0xffedd858, 0}}, {{0, 0x00036d99, 0xffee5972, 0}},
+  {{0, 0x00035486, 0xffeeda8c, 0}}, {{0, 0x00033b73, 0xffef5ba6, 0}},
+  {{0, 0x00032260, 0xffefdcc0, 0}}, {{0, 0x0003094d, 0xfff05dda, 0}},
+  {{0, 0x0002f03a, 0xfff0def4, 0}}, {{0, 0x0002d727, 0xfff1600e, 0}},
+  {{0, 0x0002be14, 0xfff1e128, 0}}, {{0, 0x0002a501, 0xfff26242, 0}},
+  {{0, 0x00028bee, 0xfff2e35c, 0}}, {{0, 0x000272db, 0xfff36476, 0}},
+  {{0, 0x000259c8, 0xfff3e590, 0}}, {{0, 0x000240b5, 0xfff466aa, 0}},
+  {{0, 0x000227a2, 0xfff4e7c4, 0}}, {{0, 0x00020e8f, 0xfff568de, 0}},
+  {{0, 0x0001f57c, 0xfff5e9f8, 0}}, {{0, 0x0001dc69, 0xfff66b12, 0}},
+  {{0, 0x0001c356, 0xfff6ec2c, 0}}, {{0, 0x0001aa43, 0xfff76d46, 0}},
+  {{0, 0x00019130, 0xfff7ee60, 0}}, {{0, 0x0001781d, 0xfff86f7a, 0}},
+  {{0, 0x00015f0a, 0xfff8f094, 0}}, {{0, 0x000145f7, 0xfff971ae, 0}},
+  {{0, 0x00012ce4, 0xfff9f2c8, 0}}, {{0, 0x000113d1, 0xfffa73e2, 0}},
+  {{0, 0x0000fabe, 0xfffaf4fc, 0}}, {{0, 0x0000e1ab, 0xfffb7616, 0}},
+  {{0, 0x0000c898, 0xfffbf730, 0}}, {{0, 0x0000af85, 0xfffc784a, 0}},
+  {{0, 0x00009672, 0xfffcf964, 0}}, {{0, 0x00007d5f, 0xfffd7a7e, 0}},
+  {{0, 0x0000644c, 0xfffdfb98, 0}}, {{0, 0x00004b39, 0xfffe7cb2, 0}},
+  {{0, 0x00003226, 0xfffefdcc, 0}}, {{0, 0x00001913, 0xffff7ee6, 0}},
+  {{0, 0x00000000, 0x00000000, 0}}, {{0, 0xffffe6ed, 0x0000811a, 0}},
+  {{0, 0xffffcdda, 0x00010234, 0}}, {{0, 0xffffb4c7, 0x0001834e, 0}},
+  {{0, 0xffff9bb4, 0x00020468, 0}}, {{0, 0xffff82a1, 0x00028582, 0}},
+  {{0, 0xffff698e, 0x0003069c, 0}}, {{0, 0xffff507b, 0x000387b6, 0}},
+  {{0, 0xffff3768, 0x000408d0, 0}}, {{0, 0xffff1e55, 0x000489ea, 0}},
+  {{0, 0xffff0542, 0x00050b04, 0}}, {{0, 0xfffeec2f, 0x00058c1e, 0}},
+  {{0, 0xfffed31c, 0x00060d38, 0}}, {{0, 0xfffeba09, 0x00068e52, 0}},
+  {{0, 0xfffea0f6, 0x00070f6c, 0}}, {{0, 0xfffe87e3, 0x00079086, 0}},
+  {{0, 0xfffe6ed0, 0x000811a0, 0}}, {{0, 0xfffe55bd, 0x000892ba, 0}},
+  {{0, 0xfffe3caa, 0x000913d4, 0}}, {{0, 0xfffe2397, 0x000994ee, 0}},
+  {{0, 0xfffe0a84, 0x000a1608, 0}}, {{0, 0xfffdf171, 0x000a9722, 0}},
+  {{0, 0xfffdd85e, 0x000b183c, 0}}, {{0, 0xfffdbf4b, 0x000b9956, 0}},
+  {{0, 0xfffda638, 0x000c1a70, 0}}, {{0, 0xfffd8d25, 0x000c9b8a, 0}},
+  {{0, 0xfffd7412, 0x000d1ca4, 0}}, {{0, 0xfffd5aff, 0x000d9dbe, 0}},
+  {{0, 0xfffd41ec, 0x000e1ed8, 0}}, {{0, 0xfffd28d9, 0x000e9ff2, 0}},
+  {{0, 0xfffd0fc6, 0x000f210c, 0}}, {{0, 0xfffcf6b3, 0x000fa226, 0}},
+  {{0, 0xfffcdda0, 0x00102340, 0}}, {{0, 0xfffcc48d, 0x0010a45a, 0}},
+  {{0, 0xfffcab7a, 0x00112574, 0}}, {{0, 0xfffc9267, 0x0011a68e, 0}},
+  {{0, 0xfffc7954, 0x001227a8, 0}}, {{0, 0xfffc6041, 0x0012a8c2, 0}},
+  {{0, 0xfffc472e, 0x001329dc, 0}}, {{0, 0xfffc2e1b, 0x0013aaf6, 0}},
+  {{0, 0xfffc1508, 0x00142c10, 0}}, {{0, 0xfffbfbf5, 0x0014ad2a, 0}},
+  {{0, 0xfffbe2e2, 0x00152e44, 0}}, {{0, 0xfffbc9cf, 0x0015af5e, 0}},
+  {{0, 0xfffbb0bc, 0x00163078, 0}}, {{0, 0xfffb97a9, 0x0016b192, 0}},
+  {{0, 0xfffb7e96, 0x001732ac, 0}}, {{0, 0xfffb6583, 0x0017b3c6, 0}},
+  {{0, 0xfffb4c70, 0x001834e0, 0}}, {{0, 0xfffb335d, 0x0018b5fa, 0}},
+  {{0, 0xfffb1a4a, 0x00193714, 0}}, {{0, 0xfffb0137, 0x0019b82e, 0}},
+  {{0, 0xfffae824, 0x001a3948, 0}}, {{0, 0xfffacf11, 0x001aba62, 0}},
+  {{0, 0xfffab5fe, 0x001b3b7c, 0}}, {{0, 0xfffa9ceb, 0x001bbc96, 0}},
+  {{0, 0xfffa83d8, 0x001c3db0, 0}}, {{0, 0xfffa6ac5, 0x001cbeca, 0}},
+  {{0, 0xfffa51b2, 0x001d3fe4, 0}}, {{0, 0xfffa389f, 0x001dc0fe, 0}},
+  {{0, 0xfffa1f8c, 0x001e4218, 0}}, {{0, 0xfffa0679, 0x001ec332, 0}},
+  {{0, 0xfff9ed66, 0x001f444c, 0}}, {{0, 0xfff9d453, 0x001fc566, 0}},
+  {{0, 0xfff9bb40, 0x00204680, 0}}, {{0, 0xfff9a22d, 0x0020c79a, 0}},
+  {{0, 0xfff9891a, 0x002148b4, 0}}, {{0, 0xfff97007, 0x0021c9ce, 0}},
+  {{0, 0xfff956f4, 0x00224ae8, 0}}, {{0, 0xfff93de1, 0x0022cc02, 0}},
+  {{0, 0xfff924ce, 0x00234d1c, 0}}, {{0, 0xfff90bbb, 0x0023ce36, 0}},
+  {{0, 0xfff8f2a8, 0x00244f50, 0}}, {{0, 0xfff8d995, 0x0024d06a, 0}},
+  {{0, 0xfff8c082, 0x00255184, 0}}, {{0, 0xfff8a76f, 0x0025d29e, 0}},
+  {{0, 0xfff88e5c, 0x002653b8, 0}}, {{0, 0xfff87549, 0x0026d4d2, 0}},
+  {{0, 0xfff85c36, 0x002755ec, 0}}, {{0, 0xfff84323, 0x0027d706, 0}},
+  {{0, 0xfff82a10, 0x00285820, 0}}, {{0, 0xfff810fd, 0x0028d93a, 0}},
+  {{0, 0xfff7f7ea, 0x00295a54, 0}}, {{0, 0xfff7ded7, 0x0029db6e, 0}},
+  {{0, 0xfff7c5c4, 0x002a5c88, 0}}, {{0, 0xfff7acb1, 0x002adda2, 0}},
+  {{0, 0xfff7939e, 0x002b5ebc, 0}}, {{0, 0xfff77a8b, 0x002bdfd6, 0}},
+  {{0, 0xfff76178, 0x002c60f0, 0}}, {{0, 0xfff74865, 0x002ce20a, 0}},
+  {{0, 0xfff72f52, 0x002d6324, 0}}, {{0, 0xfff7163f, 0x002de43e, 0}},
+  {{0, 0xfff6fd2c, 0x002e6558, 0}}, {{0, 0xfff6e419, 0x002ee672, 0}},
+  {{0, 0xfff6cb06, 0x002f678c, 0}}, {{0, 0xfff6b1f3, 0x002fe8a6, 0}},
+  {{0, 0xfff698e0, 0x003069c0, 0}}, {{0, 0xfff67fcd, 0x0030eada, 0}},
+  {{0, 0xfff666ba, 0x00316bf4, 0}}, {{0, 0xfff64da7, 0x0031ed0e, 0}},
+  {{0, 0xfff63494, 0x00326e28, 0}}, {{0, 0xfff61b81, 0x0032ef42, 0}},
+  {{0, 0xfff6026e, 0x0033705c, 0}}, {{0, 0xfff5e95b, 0x0033f176, 0}},
+  {{0, 0xfff5d048, 0x00347290, 0}}, {{0, 0xfff5b735, 0x0034f3aa, 0}},
+  {{0, 0xfff59e22, 0x003574c4, 0}}, {{0, 0xfff5850f, 0x0035f5de, 0}},
+  {{0, 0xfff56bfc, 0x003676f8, 0}}, {{0, 0xfff552e9, 0x0036f812, 0}},
+  {{0, 0xfff539d6, 0x0037792c, 0}}, {{0, 0xfff520c3, 0x0037fa46, 0}},
+  {{0, 0xfff507b0, 0x00387b60, 0}}, {{0, 0xfff4ee9d, 0x0038fc7a, 0}},
+  {{0, 0xfff4d58a, 0x00397d94, 0}}, {{0, 0xfff4bc77, 0x0039feae, 0}},
+  {{0, 0xfff4a364, 0x003a7fc8, 0}}, {{0, 0xfff48a51, 0x003b00e2, 0}},
+  {{0, 0xfff4713e, 0x003b81fc, 0}}, {{0, 0xfff4582b, 0x003c0316, 0}},
+  {{0, 0xfff43f18, 0x003c8430, 0}}, {{0, 0xfff42605, 0x003d054a, 0}},
+  {{0, 0xfff40cf2, 0x003d8664, 0}}, {{0, 0xfff3f3df, 0x003e077e, 0}},
+  {{0, 0xfff3dacc, 0x003e8898, 0}}, {{0, 0xfff3c1b9, 0x003f09b2, 0}},
+  {{0, 0xfff3a8a6, 0x003f8acc, 0}}, {{0, 0xfff38f93, 0x00400be6, 0}}
+};
+
+static VP8kCstSSE2 VP8kVtoRGBA[256] = {
+  {{0xffcced80, 0x001a0400, 0, 0}}, {{0xffcd53a5, 0x0019cff8, 0, 0}},
+  {{0xffcdb9ca, 0x00199bf0, 0, 0}}, {{0xffce1fef, 0x001967e8, 0, 0}},
+  {{0xffce8614, 0x001933e0, 0, 0}}, {{0xffceec39, 0x0018ffd8, 0, 0}},
+  {{0xffcf525e, 0x0018cbd0, 0, 0}}, {{0xffcfb883, 0x001897c8, 0, 0}},
+  {{0xffd01ea8, 0x001863c0, 0, 0}}, {{0xffd084cd, 0x00182fb8, 0, 0}},
+  {{0xffd0eaf2, 0x0017fbb0, 0, 0}}, {{0xffd15117, 0x0017c7a8, 0, 0}},
+  {{0xffd1b73c, 0x001793a0, 0, 0}}, {{0xffd21d61, 0x00175f98, 0, 0}},
+  {{0xffd28386, 0x00172b90, 0, 0}}, {{0xffd2e9ab, 0x0016f788, 0, 0}},
+  {{0xffd34fd0, 0x0016c380, 0, 0}}, {{0xffd3b5f5, 0x00168f78, 0, 0}},
+  {{0xffd41c1a, 0x00165b70, 0, 0}}, {{0xffd4823f, 0x00162768, 0, 0}},
+  {{0xffd4e864, 0x0015f360, 0, 0}}, {{0xffd54e89, 0x0015bf58, 0, 0}},
+  {{0xffd5b4ae, 0x00158b50, 0, 0}}, {{0xffd61ad3, 0x00155748, 0, 0}},
+  {{0xffd680f8, 0x00152340, 0, 0}}, {{0xffd6e71d, 0x0014ef38, 0, 0}},
+  {{0xffd74d42, 0x0014bb30, 0, 0}}, {{0xffd7b367, 0x00148728, 0, 0}},
+  {{0xffd8198c, 0x00145320, 0, 0}}, {{0xffd87fb1, 0x00141f18, 0, 0}},
+  {{0xffd8e5d6, 0x0013eb10, 0, 0}}, {{0xffd94bfb, 0x0013b708, 0, 0}},
+  {{0xffd9b220, 0x00138300, 0, 0}}, {{0xffda1845, 0x00134ef8, 0, 0}},
+  {{0xffda7e6a, 0x00131af0, 0, 0}}, {{0xffdae48f, 0x0012e6e8, 0, 0}},
+  {{0xffdb4ab4, 0x0012b2e0, 0, 0}}, {{0xffdbb0d9, 0x00127ed8, 0, 0}},
+  {{0xffdc16fe, 0x00124ad0, 0, 0}}, {{0xffdc7d23, 0x001216c8, 0, 0}},
+  {{0xffdce348, 0x0011e2c0, 0, 0}}, {{0xffdd496d, 0x0011aeb8, 0, 0}},
+  {{0xffddaf92, 0x00117ab0, 0, 0}}, {{0xffde15b7, 0x001146a8, 0, 0}},
+  {{0xffde7bdc, 0x001112a0, 0, 0}}, {{0xffdee201, 0x0010de98, 0, 0}},
+  {{0xffdf4826, 0x0010aa90, 0, 0}}, {{0xffdfae4b, 0x00107688, 0, 0}},
+  {{0xffe01470, 0x00104280, 0, 0}}, {{0xffe07a95, 0x00100e78, 0, 0}},
+  {{0xffe0e0ba, 0x000fda70, 0, 0}}, {{0xffe146df, 0x000fa668, 0, 0}},
+  {{0xffe1ad04, 0x000f7260, 0, 0}}, {{0xffe21329, 0x000f3e58, 0, 0}},
+  {{0xffe2794e, 0x000f0a50, 0, 0}}, {{0xffe2df73, 0x000ed648, 0, 0}},
+  {{0xffe34598, 0x000ea240, 0, 0}}, {{0xffe3abbd, 0x000e6e38, 0, 0}},
+  {{0xffe411e2, 0x000e3a30, 0, 0}}, {{0xffe47807, 0x000e0628, 0, 0}},
+  {{0xffe4de2c, 0x000dd220, 0, 0}}, {{0xffe54451, 0x000d9e18, 0, 0}},
+  {{0xffe5aa76, 0x000d6a10, 0, 0}}, {{0xffe6109b, 0x000d3608, 0, 0}},
+  {{0xffe676c0, 0x000d0200, 0, 0}}, {{0xffe6dce5, 0x000ccdf8, 0, 0}},
+  {{0xffe7430a, 0x000c99f0, 0, 0}}, {{0xffe7a92f, 0x000c65e8, 0, 0}},
+  {{0xffe80f54, 0x000c31e0, 0, 0}}, {{0xffe87579, 0x000bfdd8, 0, 0}},
+  {{0xffe8db9e, 0x000bc9d0, 0, 0}}, {{0xffe941c3, 0x000b95c8, 0, 0}},
+  {{0xffe9a7e8, 0x000b61c0, 0, 0}}, {{0xffea0e0d, 0x000b2db8, 0, 0}},
+  {{0xffea7432, 0x000af9b0, 0, 0}}, {{0xffeada57, 0x000ac5a8, 0, 0}},
+  {{0xffeb407c, 0x000a91a0, 0, 0}}, {{0xffeba6a1, 0x000a5d98, 0, 0}},
+  {{0xffec0cc6, 0x000a2990, 0, 0}}, {{0xffec72eb, 0x0009f588, 0, 0}},
+  {{0xffecd910, 0x0009c180, 0, 0}}, {{0xffed3f35, 0x00098d78, 0, 0}},
+  {{0xffeda55a, 0x00095970, 0, 0}}, {{0xffee0b7f, 0x00092568, 0, 0}},
+  {{0xffee71a4, 0x0008f160, 0, 0}}, {{0xffeed7c9, 0x0008bd58, 0, 0}},
+  {{0xffef3dee, 0x00088950, 0, 0}}, {{0xffefa413, 0x00085548, 0, 0}},
+  {{0xfff00a38, 0x00082140, 0, 0}}, {{0xfff0705d, 0x0007ed38, 0, 0}},
+  {{0xfff0d682, 0x0007b930, 0, 0}}, {{0xfff13ca7, 0x00078528, 0, 0}},
+  {{0xfff1a2cc, 0x00075120, 0, 0}}, {{0xfff208f1, 0x00071d18, 0, 0}},
+  {{0xfff26f16, 0x0006e910, 0, 0}}, {{0xfff2d53b, 0x0006b508, 0, 0}},
+  {{0xfff33b60, 0x00068100, 0, 0}}, {{0xfff3a185, 0x00064cf8, 0, 0}},
+  {{0xfff407aa, 0x000618f0, 0, 0}}, {{0xfff46dcf, 0x0005e4e8, 0, 0}},
+  {{0xfff4d3f4, 0x0005b0e0, 0, 0}}, {{0xfff53a19, 0x00057cd8, 0, 0}},
+  {{0xfff5a03e, 0x000548d0, 0, 0}}, {{0xfff60663, 0x000514c8, 0, 0}},
+  {{0xfff66c88, 0x0004e0c0, 0, 0}}, {{0xfff6d2ad, 0x0004acb8, 0, 0}},
+  {{0xfff738d2, 0x000478b0, 0, 0}}, {{0xfff79ef7, 0x000444a8, 0, 0}},
+  {{0xfff8051c, 0x000410a0, 0, 0}}, {{0xfff86b41, 0x0003dc98, 0, 0}},
+  {{0xfff8d166, 0x0003a890, 0, 0}}, {{0xfff9378b, 0x00037488, 0, 0}},
+  {{0xfff99db0, 0x00034080, 0, 0}}, {{0xfffa03d5, 0x00030c78, 0, 0}},
+  {{0xfffa69fa, 0x0002d870, 0, 0}}, {{0xfffad01f, 0x0002a468, 0, 0}},
+  {{0xfffb3644, 0x00027060, 0, 0}}, {{0xfffb9c69, 0x00023c58, 0, 0}},
+  {{0xfffc028e, 0x00020850, 0, 0}}, {{0xfffc68b3, 0x0001d448, 0, 0}},
+  {{0xfffcced8, 0x0001a040, 0, 0}}, {{0xfffd34fd, 0x00016c38, 0, 0}},
+  {{0xfffd9b22, 0x00013830, 0, 0}}, {{0xfffe0147, 0x00010428, 0, 0}},
+  {{0xfffe676c, 0x0000d020, 0, 0}}, {{0xfffecd91, 0x00009c18, 0, 0}},
+  {{0xffff33b6, 0x00006810, 0, 0}}, {{0xffff99db, 0x00003408, 0, 0}},
+  {{0x00000000, 0x00000000, 0, 0}}, {{0x00006625, 0xffffcbf8, 0, 0}},
+  {{0x0000cc4a, 0xffff97f0, 0, 0}}, {{0x0001326f, 0xffff63e8, 0, 0}},
+  {{0x00019894, 0xffff2fe0, 0, 0}}, {{0x0001feb9, 0xfffefbd8, 0, 0}},
+  {{0x000264de, 0xfffec7d0, 0, 0}}, {{0x0002cb03, 0xfffe93c8, 0, 0}},
+  {{0x00033128, 0xfffe5fc0, 0, 0}}, {{0x0003974d, 0xfffe2bb8, 0, 0}},
+  {{0x0003fd72, 0xfffdf7b0, 0, 0}}, {{0x00046397, 0xfffdc3a8, 0, 0}},
+  {{0x0004c9bc, 0xfffd8fa0, 0, 0}}, {{0x00052fe1, 0xfffd5b98, 0, 0}},
+  {{0x00059606, 0xfffd2790, 0, 0}}, {{0x0005fc2b, 0xfffcf388, 0, 0}},
+  {{0x00066250, 0xfffcbf80, 0, 0}}, {{0x0006c875, 0xfffc8b78, 0, 0}},
+  {{0x00072e9a, 0xfffc5770, 0, 0}}, {{0x000794bf, 0xfffc2368, 0, 0}},
+  {{0x0007fae4, 0xfffbef60, 0, 0}}, {{0x00086109, 0xfffbbb58, 0, 0}},
+  {{0x0008c72e, 0xfffb8750, 0, 0}}, {{0x00092d53, 0xfffb5348, 0, 0}},
+  {{0x00099378, 0xfffb1f40, 0, 0}}, {{0x0009f99d, 0xfffaeb38, 0, 0}},
+  {{0x000a5fc2, 0xfffab730, 0, 0}}, {{0x000ac5e7, 0xfffa8328, 0, 0}},
+  {{0x000b2c0c, 0xfffa4f20, 0, 0}}, {{0x000b9231, 0xfffa1b18, 0, 0}},
+  {{0x000bf856, 0xfff9e710, 0, 0}}, {{0x000c5e7b, 0xfff9b308, 0, 0}},
+  {{0x000cc4a0, 0xfff97f00, 0, 0}}, {{0x000d2ac5, 0xfff94af8, 0, 0}},
+  {{0x000d90ea, 0xfff916f0, 0, 0}}, {{0x000df70f, 0xfff8e2e8, 0, 0}},
+  {{0x000e5d34, 0xfff8aee0, 0, 0}}, {{0x000ec359, 0xfff87ad8, 0, 0}},
+  {{0x000f297e, 0xfff846d0, 0, 0}}, {{0x000f8fa3, 0xfff812c8, 0, 0}},
+  {{0x000ff5c8, 0xfff7dec0, 0, 0}}, {{0x00105bed, 0xfff7aab8, 0, 0}},
+  {{0x0010c212, 0xfff776b0, 0, 0}}, {{0x00112837, 0xfff742a8, 0, 0}},
+  {{0x00118e5c, 0xfff70ea0, 0, 0}}, {{0x0011f481, 0xfff6da98, 0, 0}},
+  {{0x00125aa6, 0xfff6a690, 0, 0}}, {{0x0012c0cb, 0xfff67288, 0, 0}},
+  {{0x001326f0, 0xfff63e80, 0, 0}}, {{0x00138d15, 0xfff60a78, 0, 0}},
+  {{0x0013f33a, 0xfff5d670, 0, 0}}, {{0x0014595f, 0xfff5a268, 0, 0}},
+  {{0x0014bf84, 0xfff56e60, 0, 0}}, {{0x001525a9, 0xfff53a58, 0, 0}},
+  {{0x00158bce, 0xfff50650, 0, 0}}, {{0x0015f1f3, 0xfff4d248, 0, 0}},
+  {{0x00165818, 0xfff49e40, 0, 0}}, {{0x0016be3d, 0xfff46a38, 0, 0}},
+  {{0x00172462, 0xfff43630, 0, 0}}, {{0x00178a87, 0xfff40228, 0, 0}},
+  {{0x0017f0ac, 0xfff3ce20, 0, 0}}, {{0x001856d1, 0xfff39a18, 0, 0}},
+  {{0x0018bcf6, 0xfff36610, 0, 0}}, {{0x0019231b, 0xfff33208, 0, 0}},
+  {{0x00198940, 0xfff2fe00, 0, 0}}, {{0x0019ef65, 0xfff2c9f8, 0, 0}},
+  {{0x001a558a, 0xfff295f0, 0, 0}}, {{0x001abbaf, 0xfff261e8, 0, 0}},
+  {{0x001b21d4, 0xfff22de0, 0, 0}}, {{0x001b87f9, 0xfff1f9d8, 0, 0}},
+  {{0x001bee1e, 0xfff1c5d0, 0, 0}}, {{0x001c5443, 0xfff191c8, 0, 0}},
+  {{0x001cba68, 0xfff15dc0, 0, 0}}, {{0x001d208d, 0xfff129b8, 0, 0}},
+  {{0x001d86b2, 0xfff0f5b0, 0, 0}}, {{0x001decd7, 0xfff0c1a8, 0, 0}},
+  {{0x001e52fc, 0xfff08da0, 0, 0}}, {{0x001eb921, 0xfff05998, 0, 0}},
+  {{0x001f1f46, 0xfff02590, 0, 0}}, {{0x001f856b, 0xffeff188, 0, 0}},
+  {{0x001feb90, 0xffefbd80, 0, 0}}, {{0x002051b5, 0xffef8978, 0, 0}},
+  {{0x0020b7da, 0xffef5570, 0, 0}}, {{0x00211dff, 0xffef2168, 0, 0}},
+  {{0x00218424, 0xffeeed60, 0, 0}}, {{0x0021ea49, 0xffeeb958, 0, 0}},
+  {{0x0022506e, 0xffee8550, 0, 0}}, {{0x0022b693, 0xffee5148, 0, 0}},
+  {{0x00231cb8, 0xffee1d40, 0, 0}}, {{0x002382dd, 0xffede938, 0, 0}},
+  {{0x0023e902, 0xffedb530, 0, 0}}, {{0x00244f27, 0xffed8128, 0, 0}},
+  {{0x0024b54c, 0xffed4d20, 0, 0}}, {{0x00251b71, 0xffed1918, 0, 0}},
+  {{0x00258196, 0xffece510, 0, 0}}, {{0x0025e7bb, 0xffecb108, 0, 0}},
+  {{0x00264de0, 0xffec7d00, 0, 0}}, {{0x0026b405, 0xffec48f8, 0, 0}},
+  {{0x00271a2a, 0xffec14f0, 0, 0}}, {{0x0027804f, 0xffebe0e8, 0, 0}},
+  {{0x0027e674, 0xffebace0, 0, 0}}, {{0x00284c99, 0xffeb78d8, 0, 0}},
+  {{0x0028b2be, 0xffeb44d0, 0, 0}}, {{0x002918e3, 0xffeb10c8, 0, 0}},
+  {{0x00297f08, 0xffeadcc0, 0, 0}}, {{0x0029e52d, 0xffeaa8b8, 0, 0}},
+  {{0x002a4b52, 0xffea74b0, 0, 0}}, {{0x002ab177, 0xffea40a8, 0, 0}},
+  {{0x002b179c, 0xffea0ca0, 0, 0}}, {{0x002b7dc1, 0xffe9d898, 0, 0}},
+  {{0x002be3e6, 0xffe9a490, 0, 0}}, {{0x002c4a0b, 0xffe97088, 0, 0}},
+  {{0x002cb030, 0xffe93c80, 0, 0}}, {{0x002d1655, 0xffe90878, 0, 0}},
+  {{0x002d7c7a, 0xffe8d470, 0, 0}}, {{0x002de29f, 0xffe8a068, 0, 0}},
+  {{0x002e48c4, 0xffe86c60, 0, 0}}, {{0x002eaee9, 0xffe83858, 0, 0}},
+  {{0x002f150e, 0xffe80450, 0, 0}}, {{0x002f7b33, 0xffe7d048, 0, 0}},
+  {{0x002fe158, 0xffe79c40, 0, 0}}, {{0x0030477d, 0xffe76838, 0, 0}},
+  {{0x0030ada2, 0xffe73430, 0, 0}}, {{0x003113c7, 0xffe70028, 0, 0}},
+  {{0x003179ec, 0xffe6cc20, 0, 0}}, {{0x0031e011, 0xffe69818, 0, 0}},
+  {{0x00324636, 0xffe66410, 0, 0}}, {{0x0032ac5b, 0xffe63008, 0, 0}}
+};
diff --git a/Source/LibWebP/src/enc/backward_references.h b/Source/LibWebP/src/enc/backward_references.h
new file mode 100644
index 0000000..6869e57
--- /dev/null
+++ b/Source/LibWebP/src/enc/backward_references.h
@@ -0,0 +1,202 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Author: Jyrki Alakuijala (jyrki at google.com)
+//
+
+#ifndef WEBP_ENC_BACKWARD_REFERENCES_H_
+#define WEBP_ENC_BACKWARD_REFERENCES_H_
+
+#include <assert.h>
+#include <stdlib.h>
+#include "../webp/types.h"
+#include "../webp/format_constants.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// The maximum allowed limit is 11.
+#define MAX_COLOR_CACHE_BITS 10
+
+// -----------------------------------------------------------------------------
+// PixOrCopy
+
+enum Mode {
+  kLiteral,
+  kCacheIdx,
+  kCopy,
+  kNone
+};
+
+typedef struct {
+  // mode as uint8_t to make the memory layout to be exactly 8 bytes.
+  uint8_t mode;
+  uint16_t len;
+  uint32_t argb_or_distance;
+} PixOrCopy;
+
+static WEBP_INLINE PixOrCopy PixOrCopyCreateCopy(uint32_t distance,
+                                                 uint16_t len) {
+  PixOrCopy retval;
+  retval.mode = kCopy;
+  retval.argb_or_distance = distance;
+  retval.len = len;
+  return retval;
+}
+
+static WEBP_INLINE PixOrCopy PixOrCopyCreateCacheIdx(int idx) {
+  PixOrCopy retval;
+  assert(idx >= 0);
+  assert(idx < (1 << MAX_COLOR_CACHE_BITS));
+  retval.mode = kCacheIdx;
+  retval.argb_or_distance = idx;
+  retval.len = 1;
+  return retval;
+}
+
+static WEBP_INLINE PixOrCopy PixOrCopyCreateLiteral(uint32_t argb) {
+  PixOrCopy retval;
+  retval.mode = kLiteral;
+  retval.argb_or_distance = argb;
+  retval.len = 1;
+  return retval;
+}
+
+static WEBP_INLINE int PixOrCopyIsLiteral(const PixOrCopy* const p) {
+  return (p->mode == kLiteral);
+}
+
+static WEBP_INLINE int PixOrCopyIsCacheIdx(const PixOrCopy* const p) {
+  return (p->mode == kCacheIdx);
+}
+
+static WEBP_INLINE int PixOrCopyIsCopy(const PixOrCopy* const p) {
+  return (p->mode == kCopy);
+}
+
+static WEBP_INLINE uint32_t PixOrCopyLiteral(const PixOrCopy* const p,
+                                             int component) {
+  assert(p->mode == kLiteral);
+  return (p->argb_or_distance >> (component * 8)) & 0xff;
+}
+
+static WEBP_INLINE uint32_t PixOrCopyLength(const PixOrCopy* const p) {
+  return p->len;
+}
+
+static WEBP_INLINE uint32_t PixOrCopyArgb(const PixOrCopy* const p) {
+  assert(p->mode == kLiteral);
+  return p->argb_or_distance;
+}
+
+static WEBP_INLINE uint32_t PixOrCopyCacheIdx(const PixOrCopy* const p) {
+  assert(p->mode == kCacheIdx);
+  assert(p->argb_or_distance < (1U << MAX_COLOR_CACHE_BITS));
+  return p->argb_or_distance;
+}
+
+static WEBP_INLINE uint32_t PixOrCopyDistance(const PixOrCopy* const p) {
+  assert(p->mode == kCopy);
+  return p->argb_or_distance;
+}
+
+// -----------------------------------------------------------------------------
+// VP8LHashChain
+
+#define HASH_BITS 18
+#define HASH_SIZE (1 << HASH_BITS)
+
+typedef struct VP8LHashChain VP8LHashChain;
+struct VP8LHashChain {
+  // Stores the most recently added position with the given hash value.
+  int32_t hash_to_first_index_[HASH_SIZE];
+  // chain_[pos] stores the previous position with the same hash value
+  // for every pixel in the image.
+  int32_t* chain_;
+  // This is the maximum size of the hash_chain that can be constructed.
+  // Typically this is the pixel count (width x height) for a given image.
+  int size_;
+};
+
+// Must be called first, to set size.
+int VP8LHashChainInit(VP8LHashChain* const p, int size);
+void VP8LHashChainClear(VP8LHashChain* const p);  // release memory
+
+// -----------------------------------------------------------------------------
+// VP8LBackwardRefs (block-based backward-references storage)
+
+// maximum number of reference blocks the image will be segmented into
+#define MAX_REFS_BLOCK_PER_IMAGE 16
+
+typedef struct PixOrCopyBlock PixOrCopyBlock;   // forward declaration
+typedef struct VP8LBackwardRefs VP8LBackwardRefs;
+
+// Container for blocks chain
+struct VP8LBackwardRefs {
+  int block_size_;               // common block-size
+  int error_;                    // set to true if some memory error occurred
+  PixOrCopyBlock* refs_;         // list of currently used blocks
+  PixOrCopyBlock** tail_;        // for list recycling
+  PixOrCopyBlock* free_blocks_;  // free-list
+  PixOrCopyBlock* last_block_;   // used for adding new refs (internal)
+};
+
+// Initialize the object. 'block_size' is the common block size to store
+// references (typically, width * height / MAX_REFS_BLOCK_PER_IMAGE).
+void VP8LBackwardRefsInit(VP8LBackwardRefs* const refs, int block_size);
+// Release memory for backward references.
+void VP8LBackwardRefsClear(VP8LBackwardRefs* const refs);
+// Copies the 'src' backward refs to the 'dst'. Returns 0 in case of error.
+int VP8LBackwardRefsCopy(const VP8LBackwardRefs* const src,
+                         VP8LBackwardRefs* const dst);
+
+// Cursor for iterating on references content
+typedef struct {
+  // public:
+  PixOrCopy* cur_pos;           // current position
+  // private:
+  PixOrCopyBlock* cur_block_;   // current block in the refs list
+  const PixOrCopy* last_pos_;   // sentinel for switching to next block
+} VP8LRefsCursor;
+
+// Returns a cursor positioned at the beginning of the references list.
+VP8LRefsCursor VP8LRefsCursorInit(const VP8LBackwardRefs* const refs);
+// Returns true if cursor is pointing at a valid position.
+static WEBP_INLINE int VP8LRefsCursorOk(const VP8LRefsCursor* const c) {
+  return (c->cur_pos != NULL);
+}
+// Move to next block of references. Internal, not to be called directly.
+void VP8LRefsCursorNextBlock(VP8LRefsCursor* const c);
+// Move to next position, or NULL. Should not be called if !VP8LRefsCursorOk().
+static WEBP_INLINE void VP8LRefsCursorNext(VP8LRefsCursor* const c) {
+  assert(c != NULL);
+  assert(VP8LRefsCursorOk(c));
+  if (++c->cur_pos == c->last_pos_) VP8LRefsCursorNextBlock(c);
+}
+
+// -----------------------------------------------------------------------------
+// Main entry points
+
+// Evaluates best possible backward references for specified quality.
+// The input cache_bits to 'VP8LGetBackwardReferences' sets the maximum cache
+// bits to use (passing 0 implies disabling the local color cache).
+// The optimal cache bits is evaluated and set for the *cache_bits parameter.
+// The return value is the pointer to the best of the two backward refs viz,
+// refs[0] or refs[1].
+VP8LBackwardRefs* VP8LGetBackwardReferences(
+    int width, int height, const uint32_t* const argb, int quality,
+    int low_effort, int* const cache_bits, VP8LHashChain* const hash_chain,
+    VP8LBackwardRefs refs[2]);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // WEBP_ENC_BACKWARD_REFERENCES_H_
diff --git a/Source/LibWebP/src/enc/cost.h b/Source/LibWebP/src/enc/cost.h
new file mode 100644
index 0000000..7979b79
--- /dev/null
+++ b/Source/LibWebP/src/enc/cost.h
@@ -0,0 +1,69 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Cost tables for level and modes.
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#ifndef WEBP_ENC_COST_H_
+#define WEBP_ENC_COST_H_
+
+#include <assert.h>
+#include <stdlib.h>
+#include "./vp8enci.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// On-the-fly info about the current set of residuals. Handy to avoid
+// passing zillions of params.
+typedef struct VP8Residual VP8Residual;
+struct VP8Residual {
+  int first;
+  int last;
+  const int16_t* coeffs;
+
+  int coeff_type;
+  ProbaArray*   prob;
+  StatsArray*   stats;
+  CostArray*    cost;    // TODO(skal): remove in favor of *costs
+  CostArrayPtr  costs;
+};
+
+void VP8InitResidual(int first, int coeff_type,
+                     VP8Encoder* const enc, VP8Residual* const res);
+
+int VP8RecordCoeffs(int ctx, const VP8Residual* const res);
+
+// Cost of coding one event with probability 'proba'.
+static WEBP_INLINE int VP8BitCost(int bit, uint8_t proba) {
+  return !bit ? VP8EntropyCost[proba] : VP8EntropyCost[255 - proba];
+}
+
+// Level cost calculations
+extern const uint16_t VP8LevelCodes[MAX_VARIABLE_LEVEL][2];
+void VP8CalculateLevelCosts(VP8Proba* const proba);
+static WEBP_INLINE int VP8LevelCost(const uint16_t* const table, int level) {
+  return VP8LevelFixedCosts[level]
+       + table[(level > MAX_VARIABLE_LEVEL) ? MAX_VARIABLE_LEVEL : level];
+}
+
+// Mode costs
+extern const uint16_t VP8FixedCostsUV[4];
+extern const uint16_t VP8FixedCostsI16[4];
+extern const uint16_t VP8FixedCostsI4[NUM_BMODES][NUM_BMODES][NUM_BMODES];
+
+//------------------------------------------------------------------------------
+
+#ifdef __cplusplus
+}    // extern "C"
+#endif
+
+#endif  /* WEBP_ENC_COST_H_ */
diff --git a/Source/LibWebP/src/enc/enc.alpha.c b/Source/LibWebP/src/enc/enc.alpha.c
new file mode 100644
index 0000000..c324499
--- /dev/null
+++ b/Source/LibWebP/src/enc/enc.alpha.c
@@ -0,0 +1,440 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Alpha-plane compression.
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include "./vp8enci.h"
+#include "../dsp/dsp.h"
+#include "../utils/filters.h"
+#include "../utils/quant_levels.h"
+#include "../utils/utils.h"
+#include "../webp/format_constants.h"
+
+// -----------------------------------------------------------------------------
+// Encodes the given alpha data via specified compression method 'method'.
+// The pre-processing (quantization) is performed if 'quality' is less than 100.
+// For such cases, the encoding is lossy. The valid range is [0, 100] for
+// 'quality' and [0, 1] for 'method':
+//   'method = 0' - No compression;
+//   'method = 1' - Use lossless coder on the alpha plane only
+// 'filter' values [0, 4] correspond to prediction modes none, horizontal,
+// vertical & gradient filters. The prediction mode 4 will try all the
+// prediction modes 0 to 3 and pick the best one.
+// 'effort_level': specifies how much effort must be spent to try and reduce
+//  the compressed output size. In range 0 (quick) to 6 (slow).
+//
+// 'output' corresponds to the buffer containing compressed alpha data.
+//          This buffer is allocated by this method and caller should call
+//          WebPSafeFree(*output) when done.
+// 'output_size' corresponds to size of this compressed alpha buffer.
+//
+// Returns 1 on successfully encoding the alpha and
+//         0 if either:
+//           invalid quality or method, or
+//           memory allocation for the compressed data fails.
+
+#include "../enc/vp8li.h"
+
+static int EncodeLossless(const uint8_t* const data, int width, int height,
+                          int effort_level,  // in [0..6] range
+                          VP8LBitWriter* const bw,
+                          WebPAuxStats* const stats) {
+  int ok = 0;
+  WebPConfig config;
+  WebPPicture picture;
+
+  WebPPictureInit(&picture);
+  picture.width = width;
+  picture.height = height;
+  picture.use_argb = 1;
+  picture.stats = stats;
+  if (!WebPPictureAlloc(&picture)) return 0;
+
+  // Transfer the alpha values to the green channel.
+  WebPDispatchAlphaToGreen(data, width, picture.width, picture.height,
+                           picture.argb, picture.argb_stride);
+
+  WebPConfigInit(&config);
+  config.lossless = 1;
+  config.method = effort_level;  // impact is very small
+  // Set a low default quality for encoding alpha. Ensure that Alpha quality at
+  // lower methods (3 and below) is less than the threshold for triggering
+  // costly 'BackwardReferencesTraceBackwards'.
+  config.quality = 8.f * effort_level;
+  assert(config.quality >= 0 && config.quality <= 100.f);
+
+  // TODO(urvang): Temporary fix to avoid generating images that trigger
+  // a decoder bug related to alpha with color cache.
+  // See: https://code.google.com/p/webp/issues/detail?id=239
+  // Need to re-enable this later.
+  ok = (VP8LEncodeStream(&config, &picture, bw, 0 /*use_cache*/) == VP8_ENC_OK);
+  WebPPictureFree(&picture);
+  ok = ok && !bw->error_;
+  if (!ok) {
+    VP8LBitWriterWipeOut(bw);
+    return 0;
+  }
+  return 1;
+
+}
+
+// -----------------------------------------------------------------------------
+
+// Small struct to hold the result of a filter mode compression attempt.
+typedef struct {
+  size_t score;
+  VP8BitWriter bw;
+  WebPAuxStats stats;
+} FilterTrial;
+
+// This function always returns an initialized 'bw' object, even upon error.
+static int EncodeAlphaInternal(const uint8_t* const data, int width, int height,
+                               int method, int filter, int reduce_levels,
+                               int effort_level,  // in [0..6] range
+                               uint8_t* const tmp_alpha,
+                               FilterTrial* result) {
+  int ok = 0;
+  const uint8_t* alpha_src;
+  WebPFilterFunc filter_func;
+  uint8_t header;
+  const size_t data_size = width * height;
+  const uint8_t* output = NULL;
+  size_t output_size = 0;
+  VP8LBitWriter tmp_bw;
+
+  assert((uint64_t)data_size == (uint64_t)width * height);  // as per spec
+  assert(filter >= 0 && filter < WEBP_FILTER_LAST);
+  assert(method >= ALPHA_NO_COMPRESSION);
+  assert(method <= ALPHA_LOSSLESS_COMPRESSION);
+  assert(sizeof(header) == ALPHA_HEADER_LEN);
+  // TODO(skal): have a common function and #define's to validate alpha params.
+
+  filter_func = WebPFilters[filter];
+  if (filter_func != NULL) {
+    filter_func(data, width, height, width, tmp_alpha);
+    alpha_src = tmp_alpha;
+  }  else {
+    alpha_src = data;
+  }
+
+  if (method != ALPHA_NO_COMPRESSION) {
+    ok = VP8LBitWriterInit(&tmp_bw, data_size >> 3);
+    ok = ok && EncodeLossless(alpha_src, width, height, effort_level,
+                              &tmp_bw, &result->stats);
+    if (ok) {
+      output = VP8LBitWriterFinish(&tmp_bw);
+      output_size = VP8LBitWriterNumBytes(&tmp_bw);
+      if (output_size > data_size) {
+        // compressed size is larger than source! Revert to uncompressed mode.
+        method = ALPHA_NO_COMPRESSION;
+        VP8LBitWriterWipeOut(&tmp_bw);
+      }
+    } else {
+      VP8LBitWriterWipeOut(&tmp_bw);
+      return 0;
+    }
+  }
+
+  if (method == ALPHA_NO_COMPRESSION) {
+    output = alpha_src;
+    output_size = data_size;
+    ok = 1;
+  }
+
+  // Emit final result.
+  header = method | (filter << 2);
+  if (reduce_levels) header |= ALPHA_PREPROCESSED_LEVELS << 4;
+
+  VP8BitWriterInit(&result->bw, ALPHA_HEADER_LEN + output_size);
+  ok = ok && VP8BitWriterAppend(&result->bw, &header, ALPHA_HEADER_LEN);
+  ok = ok && VP8BitWriterAppend(&result->bw, output, output_size);
+
+  if (method != ALPHA_NO_COMPRESSION) {
+    VP8LBitWriterWipeOut(&tmp_bw);
+  }
+  ok = ok && !result->bw.error_;
+  result->score = VP8BitWriterSize(&result->bw);
+  return ok;
+}
+
+// -----------------------------------------------------------------------------
+
+// TODO(skal): move to dsp/ ?
+static void CopyPlane(const uint8_t* src, int src_stride,
+                      uint8_t* dst, int dst_stride, int width, int height) {
+  while (height-- > 0) {
+    memcpy(dst, src, width);
+    src += src_stride;
+    dst += dst_stride;
+  }
+}
+
+static int GetNumColors(const uint8_t* data, int width, int height,
+                        int stride) {
+  int j;
+  int colors = 0;
+  uint8_t color[256] = { 0 };
+
+  for (j = 0; j < height; ++j) {
+    int i;
+    const uint8_t* const p = data + j * stride;
+    for (i = 0; i < width; ++i) {
+      color[p[i]] = 1;
+    }
+  }
+  for (j = 0; j < 256; ++j) {
+    if (color[j] > 0) ++colors;
+  }
+  return colors;
+}
+
+#define FILTER_TRY_NONE (1 << WEBP_FILTER_NONE)
+#define FILTER_TRY_ALL ((1 << WEBP_FILTER_LAST) - 1)
+
+// Given the input 'filter' option, return an OR'd bit-set of filters to try.
+static uint32_t GetFilterMap(const uint8_t* alpha, int width, int height,
+                             int filter, int effort_level) {
+  uint32_t bit_map = 0U;
+  if (filter == WEBP_FILTER_FAST) {
+    // Quick estimate of the best candidate.
+    int try_filter_none = (effort_level > 3);
+    const int kMinColorsForFilterNone = 16;
+    const int kMaxColorsForFilterNone = 192;
+    const int num_colors = GetNumColors(alpha, width, height, width);
+    // For low number of colors, NONE yields better compression.
+    filter = (num_colors <= kMinColorsForFilterNone)
+        ? WEBP_FILTER_NONE
+        : WebPEstimateBestFilter(alpha, width, height, width);
+    bit_map |= 1 << filter;
+    // For large number of colors, try FILTER_NONE in addition to the best
+    // filter as well.
+    if (try_filter_none || num_colors > kMaxColorsForFilterNone) {
+      bit_map |= FILTER_TRY_NONE;
+    }
+  } else if (filter == WEBP_FILTER_NONE) {
+    bit_map = FILTER_TRY_NONE;
+  } else {  // WEBP_FILTER_BEST -> try all
+    bit_map = FILTER_TRY_ALL;
+  }
+  return bit_map;
+}
+
+static void InitFilterTrial(FilterTrial* const score) {
+  score->score = (size_t)~0U;
+  VP8BitWriterInit(&score->bw, 0);
+}
+
+static int ApplyFiltersAndEncode(const uint8_t* alpha, int width, int height,
+                                 size_t data_size, int method, int filter,
+                                 int reduce_levels, int effort_level,
+                                 uint8_t** const output,
+                                 size_t* const output_size,
+                                 WebPAuxStats* const stats) {
+  int ok = 1;
+  FilterTrial best;
+  uint32_t try_map =
+      GetFilterMap(alpha, width, height, filter, effort_level);
+  InitFilterTrial(&best);
+
+  if (try_map != FILTER_TRY_NONE) {
+    uint8_t* filtered_alpha =  (uint8_t*)WebPSafeMalloc(1ULL, data_size);
+    if (filtered_alpha == NULL) return 0;
+
+    for (filter = WEBP_FILTER_NONE; ok && try_map; ++filter, try_map >>= 1) {
+      if (try_map & 1) {
+        FilterTrial trial;
+        ok = EncodeAlphaInternal(alpha, width, height, method, filter,
+                                 reduce_levels, effort_level, filtered_alpha,
+                                 &trial);
+        if (ok && trial.score < best.score) {
+          VP8BitWriterWipeOut(&best.bw);
+          best = trial;
+        } else {
+          VP8BitWriterWipeOut(&trial.bw);
+        }
+      }
+    }
+    WebPSafeFree(filtered_alpha);
+  } else {
+    ok = EncodeAlphaInternal(alpha, width, height, method, WEBP_FILTER_NONE,
+                             reduce_levels, effort_level, NULL, &best);
+  }
+  if (ok) {
+    if (stats != NULL) {
+      stats->lossless_features = best.stats.lossless_features;
+      stats->histogram_bits = best.stats.histogram_bits;
+      stats->transform_bits = best.stats.transform_bits;
+      stats->cache_bits = best.stats.cache_bits;
+      stats->palette_size = best.stats.palette_size;
+      stats->lossless_size = best.stats.lossless_size;
+      stats->lossless_hdr_size = best.stats.lossless_hdr_size;
+      stats->lossless_data_size = best.stats.lossless_data_size;
+    }
+    *output_size = VP8BitWriterSize(&best.bw);
+    *output = VP8BitWriterBuf(&best.bw);
+  } else {
+    VP8BitWriterWipeOut(&best.bw);
+  }
+  return ok;
+}
+
+static int EncodeAlpha(VP8Encoder* const enc,
+                       int quality, int method, int filter,
+                       int effort_level,
+                       uint8_t** const output, size_t* const output_size) {
+  const WebPPicture* const pic = enc->pic_;
+  const int width = pic->width;
+  const int height = pic->height;
+
+  uint8_t* quant_alpha = NULL;
+  const size_t data_size = width * height;
+  uint64_t sse = 0;
+  int ok = 1;
+  const int reduce_levels = (quality < 100);
+
+  // quick sanity checks
+  assert((uint64_t)data_size == (uint64_t)width * height);  // as per spec
+  assert(enc != NULL && pic != NULL && pic->a != NULL);
+  assert(output != NULL && output_size != NULL);
+  assert(width > 0 && height > 0);
+  assert(pic->a_stride >= width);
+  assert(filter >= WEBP_FILTER_NONE && filter <= WEBP_FILTER_FAST);
+
+  if (quality < 0 || quality > 100) {
+    return 0;
+  }
+
+  if (method < ALPHA_NO_COMPRESSION || method > ALPHA_LOSSLESS_COMPRESSION) {
+    return 0;
+  }
+
+  if (method == ALPHA_NO_COMPRESSION) {
+    // Don't filter, as filtering will make no impact on compressed size.
+    filter = WEBP_FILTER_NONE;
+  }
+
+  quant_alpha = (uint8_t*)WebPSafeMalloc(1ULL, data_size);
+  if (quant_alpha == NULL) {
+    return 0;
+  }
+
+  // Extract alpha data (width x height) from raw_data (stride x height).
+  CopyPlane(pic->a, pic->a_stride, quant_alpha, width, width, height);
+
+  if (reduce_levels) {  // No Quantization required for 'quality = 100'.
+    // 16 alpha levels gives quite a low MSE w.r.t original alpha plane hence
+    // mapped to moderate quality 70. Hence Quality:[0, 70] -> Levels:[2, 16]
+    // and Quality:]70, 100] -> Levels:]16, 256].
+    const int alpha_levels = (quality <= 70) ? (2 + quality / 5)
+                                             : (16 + (quality - 70) * 8);
+    ok = QuantizeLevels(quant_alpha, width, height, alpha_levels, &sse);
+  }
+
+  if (ok) {
+    VP8FiltersInit();
+    ok = ApplyFiltersAndEncode(quant_alpha, width, height, data_size, method,
+                               filter, reduce_levels, effort_level, output,
+                               output_size, pic->stats);
+    if (pic->stats != NULL) {  // need stats?
+      pic->stats->coded_size += (int)(*output_size);
+      enc->sse_[3] = sse;
+    }
+  }
+
+  WebPSafeFree(quant_alpha);
+  return ok;
+}
+
+//------------------------------------------------------------------------------
+// Main calls
+
+static int CompressAlphaJob(VP8Encoder* const enc, void* dummy) {
+  const WebPConfig* config = enc->config_;
+  uint8_t* alpha_data = NULL;
+  size_t alpha_size = 0;
+  const int effort_level = config->method;  // maps to [0..6]
+  const WEBP_FILTER_TYPE filter =
+      (config->alpha_filtering == 0) ? WEBP_FILTER_NONE :
+      (config->alpha_filtering == 1) ? WEBP_FILTER_FAST :
+                                       WEBP_FILTER_BEST;
+  if (!EncodeAlpha(enc, config->alpha_quality, config->alpha_compression,
+                   filter, effort_level, &alpha_data, &alpha_size)) {
+    return 0;
+  }
+  if (alpha_size != (uint32_t)alpha_size) {  // Sanity check.
+    WebPSafeFree(alpha_data);
+    return 0;
+  }
+  enc->alpha_data_size_ = (uint32_t)alpha_size;
+  enc->alpha_data_ = alpha_data;
+  (void)dummy;
+  return 1;
+}
+
+void VP8EncInitAlpha(VP8Encoder* const enc) {
+  WebPInitAlphaProcessing();
+  enc->has_alpha_ = WebPPictureHasTransparency(enc->pic_);
+  enc->alpha_data_ = NULL;
+  enc->alpha_data_size_ = 0;
+  if (enc->thread_level_ > 0) {
+    WebPWorker* const worker = &enc->alpha_worker_;
+    WebPGetWorkerInterface()->Init(worker);
+    worker->data1 = enc;
+    worker->data2 = NULL;
+    worker->hook = (WebPWorkerHook)CompressAlphaJob;
+  }
+}
+
+int VP8EncStartAlpha(VP8Encoder* const enc) {
+  if (enc->has_alpha_) {
+    if (enc->thread_level_ > 0) {
+      WebPWorker* const worker = &enc->alpha_worker_;
+      // Makes sure worker is good to go.
+      if (!WebPGetWorkerInterface()->Reset(worker)) {
+        return 0;
+      }
+      WebPGetWorkerInterface()->Launch(worker);
+      return 1;
+    } else {
+      return CompressAlphaJob(enc, NULL);   // just do the job right away
+    }
+  }
+  return 1;
+}
+
+int VP8EncFinishAlpha(VP8Encoder* const enc) {
+  if (enc->has_alpha_) {
+    if (enc->thread_level_ > 0) {
+      WebPWorker* const worker = &enc->alpha_worker_;
+      if (!WebPGetWorkerInterface()->Sync(worker)) return 0;  // error
+    }
+  }
+  return WebPReportProgress(enc->pic_, enc->percent_ + 20, &enc->percent_);
+}
+
+int VP8EncDeleteAlpha(VP8Encoder* const enc) {
+  int ok = 1;
+  if (enc->thread_level_ > 0) {
+    WebPWorker* const worker = &enc->alpha_worker_;
+    // finish anything left in flight
+    ok = WebPGetWorkerInterface()->Sync(worker);
+    // still need to end the worker, even if !ok
+    WebPGetWorkerInterface()->End(worker);
+  }
+  WebPSafeFree(enc->alpha_data_);
+  enc->alpha_data_ = NULL;
+  enc->alpha_data_size_ = 0;
+  enc->has_alpha_ = 0;
+  return ok;
+}
diff --git a/Source/LibWebP/src/enc/enc.analysis.c b/Source/LibWebP/src/enc/enc.analysis.c
new file mode 100644
index 0000000..e17c815
--- /dev/null
+++ b/Source/LibWebP/src/enc/enc.analysis.c
@@ -0,0 +1,501 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Macroblock analysis
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "./vp8enci.h"
+#include "./cost.h"
+#include "../utils/utils.h"
+
+#define MAX_ITERS_K_MEANS  6
+
+//------------------------------------------------------------------------------
+// Smooth the segment map by replacing isolated block by the majority of its
+// neighbours.
+
+static void SmoothSegmentMap(VP8Encoder* const enc) {
+  int n, x, y;
+  const int w = enc->mb_w_;
+  const int h = enc->mb_h_;
+  const int majority_cnt_3_x_3_grid = 5;
+  uint8_t* const tmp = (uint8_t*)WebPSafeMalloc(w * h, sizeof(*tmp));
+  assert((uint64_t)(w * h) == (uint64_t)w * h);   // no overflow, as per spec
+
+  if (tmp == NULL) return;
+  for (y = 1; y < h - 1; ++y) {
+    for (x = 1; x < w - 1; ++x) {
+      int cnt[NUM_MB_SEGMENTS] = { 0 };
+      const VP8MBInfo* const mb = &enc->mb_info_[x + w * y];
+      int majority_seg = mb->segment_;
+      // Check the 8 neighbouring segment values.
+      cnt[mb[-w - 1].segment_]++;  // top-left
+      cnt[mb[-w + 0].segment_]++;  // top
+      cnt[mb[-w + 1].segment_]++;  // top-right
+      cnt[mb[   - 1].segment_]++;  // left
+      cnt[mb[   + 1].segment_]++;  // right
+      cnt[mb[ w - 1].segment_]++;  // bottom-left
+      cnt[mb[ w + 0].segment_]++;  // bottom
+      cnt[mb[ w + 1].segment_]++;  // bottom-right
+      for (n = 0; n < NUM_MB_SEGMENTS; ++n) {
+        if (cnt[n] >= majority_cnt_3_x_3_grid) {
+          majority_seg = n;
+          break;
+        }
+      }
+      tmp[x + y * w] = majority_seg;
+    }
+  }
+  for (y = 1; y < h - 1; ++y) {
+    for (x = 1; x < w - 1; ++x) {
+      VP8MBInfo* const mb = &enc->mb_info_[x + w * y];
+      mb->segment_ = tmp[x + y * w];
+    }
+  }
+  WebPSafeFree(tmp);
+}
+
+//------------------------------------------------------------------------------
+// set segment susceptibility alpha_ / beta_
+
+static WEBP_INLINE int clip(int v, int m, int M) {
+  return (v < m) ? m : (v > M) ? M : v;
+}
+
+static void SetSegmentAlphas(VP8Encoder* const enc,
+                             const int centers[NUM_MB_SEGMENTS],
+                             int mid) {
+  const int nb = enc->segment_hdr_.num_segments_;
+  int min = centers[0], max = centers[0];
+  int n;
+
+  if (nb > 1) {
+    for (n = 0; n < nb; ++n) {
+      if (min > centers[n]) min = centers[n];
+      if (max < centers[n]) max = centers[n];
+    }
+  }
+  if (max == min) max = min + 1;
+  assert(mid <= max && mid >= min);
+  for (n = 0; n < nb; ++n) {
+    const int alpha = 255 * (centers[n] - mid) / (max - min);
+    const int beta = 255 * (centers[n] - min) / (max - min);
+    enc->dqm_[n].alpha_ = clip(alpha, -127, 127);
+    enc->dqm_[n].beta_ = clip(beta, 0, 255);
+  }
+}
+
+//------------------------------------------------------------------------------
+// Compute susceptibility based on DCT-coeff histograms:
+// the higher, the "easier" the macroblock is to compress.
+
+#define MAX_ALPHA 255                // 8b of precision for susceptibilities.
+#define ALPHA_SCALE (2 * MAX_ALPHA)  // scaling factor for alpha.
+#define DEFAULT_ALPHA (-1)
+#define IS_BETTER_ALPHA(alpha, best_alpha) ((alpha) > (best_alpha))
+
+static int FinalAlphaValue(int alpha) {
+  alpha = MAX_ALPHA - alpha;
+  return clip(alpha, 0, MAX_ALPHA);
+}
+
+static int GetAlpha(const VP8Histogram* const histo) {
+  // 'alpha' will later be clipped to [0..MAX_ALPHA] range, clamping outer
+  // values which happen to be mostly noise. This leaves the maximum precision
+  // for handling the useful small values which contribute most.
+  const int max_value = histo->max_value;
+  const int last_non_zero = histo->last_non_zero;
+  const int alpha =
+      (max_value > 1) ? ALPHA_SCALE * last_non_zero / max_value : 0;
+  return alpha;
+}
+
+static void InitHistogram(VP8Histogram* const histo) {
+  histo->max_value = 0;
+  histo->last_non_zero = 1;
+}
+
+static void MergeHistograms(const VP8Histogram* const in,
+                            VP8Histogram* const out) {
+  if (in->max_value > out->max_value) {
+    out->max_value = in->max_value;
+  }
+  if (in->last_non_zero > out->last_non_zero) {
+    out->last_non_zero = in->last_non_zero;
+  }
+}
+
+//------------------------------------------------------------------------------
+// Simplified k-Means, to assign Nb segments based on alpha-histogram
+
+static void AssignSegments(VP8Encoder* const enc,
+                           const int alphas[MAX_ALPHA + 1]) {
+  // 'num_segments_' is previously validated and <= NUM_MB_SEGMENTS, but an
+  // explicit check is needed to avoid spurious warning about 'n + 1' exceeding
+  // array bounds of 'centers' with some compilers (noticed with gcc-4.9).
+  const int nb = (enc->segment_hdr_.num_segments_ < NUM_MB_SEGMENTS) ?
+                 enc->segment_hdr_.num_segments_ : NUM_MB_SEGMENTS;
+  int centers[NUM_MB_SEGMENTS];
+  int weighted_average = 0;
+  int map[MAX_ALPHA + 1];
+  int a, n, k;
+  int min_a = 0, max_a = MAX_ALPHA, range_a;
+  // 'int' type is ok for histo, and won't overflow
+  int accum[NUM_MB_SEGMENTS], dist_accum[NUM_MB_SEGMENTS];
+
+  assert(nb >= 1);
+  assert(nb <= NUM_MB_SEGMENTS);
+
+  // bracket the input
+  for (n = 0; n <= MAX_ALPHA && alphas[n] == 0; ++n) {}
+  min_a = n;
+  for (n = MAX_ALPHA; n > min_a && alphas[n] == 0; --n) {}
+  max_a = n;
+  range_a = max_a - min_a;
+
+  // Spread initial centers evenly
+  for (k = 0, n = 1; k < nb; ++k, n += 2) {
+    assert(n < 2 * nb);
+    centers[k] = min_a + (n * range_a) / (2 * nb);
+  }
+
+  for (k = 0; k < MAX_ITERS_K_MEANS; ++k) {     // few iters are enough
+    int total_weight;
+    int displaced;
+    // Reset stats
+    for (n = 0; n < nb; ++n) {
+      accum[n] = 0;
+      dist_accum[n] = 0;
+    }
+    // Assign nearest center for each 'a'
+    n = 0;    // track the nearest center for current 'a'
+    for (a = min_a; a <= max_a; ++a) {
+      if (alphas[a]) {
+        while (n + 1 < nb && abs(a - centers[n + 1]) < abs(a - centers[n])) {
+          n++;
+        }
+        map[a] = n;
+        // accumulate contribution into best centroid
+        dist_accum[n] += a * alphas[a];
+        accum[n] += alphas[a];
+      }
+    }
+    // All point are classified. Move the centroids to the
+    // center of their respective cloud.
+    displaced = 0;
+    weighted_average = 0;
+    total_weight = 0;
+    for (n = 0; n < nb; ++n) {
+      if (accum[n]) {
+        const int new_center = (dist_accum[n] + accum[n] / 2) / accum[n];
+        displaced += abs(centers[n] - new_center);
+        centers[n] = new_center;
+        weighted_average += new_center * accum[n];
+        total_weight += accum[n];
+      }
+    }
+    weighted_average = (weighted_average + total_weight / 2) / total_weight;
+    if (displaced < 5) break;   // no need to keep on looping...
+  }
+
+  // Map each original value to the closest centroid
+  for (n = 0; n < enc->mb_w_ * enc->mb_h_; ++n) {
+    VP8MBInfo* const mb = &enc->mb_info_[n];
+    const int alpha = mb->alpha_;
+    mb->segment_ = map[alpha];
+    mb->alpha_ = centers[map[alpha]];  // for the record.
+  }
+
+  if (nb > 1) {
+    const int smooth = (enc->config_->preprocessing & 1);
+    if (smooth) SmoothSegmentMap(enc);
+  }
+
+  SetSegmentAlphas(enc, centers, weighted_average);  // pick some alphas.
+}
+
+//------------------------------------------------------------------------------
+// Macroblock analysis: collect histogram for each mode, deduce the maximal
+// susceptibility and set best modes for this macroblock.
+// Segment assignment is done later.
+
+// Number of modes to inspect for alpha_ evaluation. We don't need to test all
+// the possible modes during the analysis phase: we risk falling into a local
+// optimum, or be subject to boundary effect
+#define MAX_INTRA16_MODE 2
+#define MAX_INTRA4_MODE  2
+#define MAX_UV_MODE      2
+
+static int MBAnalyzeBestIntra16Mode(VP8EncIterator* const it) {
+  const int max_mode = MAX_INTRA16_MODE;
+  int mode;
+  int best_alpha = DEFAULT_ALPHA;
+  int best_mode = 0;
+
+  VP8MakeLuma16Preds(it);
+  for (mode = 0; mode < max_mode; ++mode) {
+    VP8Histogram histo;
+    int alpha;
+
+    InitHistogram(&histo);
+    VP8CollectHistogram(it->yuv_in_ + Y_OFF,
+                        it->yuv_p_ + VP8I16ModeOffsets[mode],
+                        0, 16, &histo);
+    alpha = GetAlpha(&histo);
+    if (IS_BETTER_ALPHA(alpha, best_alpha)) {
+      best_alpha = alpha;
+      best_mode = mode;
+    }
+  }
+  VP8SetIntra16Mode(it, best_mode);
+  return best_alpha;
+}
+
+static int MBAnalyzeBestIntra4Mode(VP8EncIterator* const it,
+                                   int best_alpha) {
+  uint8_t modes[16];
+  const int max_mode = MAX_INTRA4_MODE;
+  int i4_alpha;
+  VP8Histogram total_histo;
+  int cur_histo = 0;
+  InitHistogram(&total_histo);
+
+  VP8IteratorStartI4(it);
+  do {
+    int mode;
+    int best_mode_alpha = DEFAULT_ALPHA;
+    VP8Histogram histos[2];
+    const uint8_t* const src = it->yuv_in_ + Y_OFF + VP8Scan[it->i4_];
+
+    VP8MakeIntra4Preds(it);
+    for (mode = 0; mode < max_mode; ++mode) {
+      int alpha;
+
+      InitHistogram(&histos[cur_histo]);
+      VP8CollectHistogram(src, it->yuv_p_ + VP8I4ModeOffsets[mode],
+                          0, 1, &histos[cur_histo]);
+      alpha = GetAlpha(&histos[cur_histo]);
+      if (IS_BETTER_ALPHA(alpha, best_mode_alpha)) {
+        best_mode_alpha = alpha;
+        modes[it->i4_] = mode;
+        cur_histo ^= 1;   // keep track of best histo so far.
+      }
+    }
+    // accumulate best histogram
+    MergeHistograms(&histos[cur_histo ^ 1], &total_histo);
+    // Note: we reuse the original samples for predictors
+  } while (VP8IteratorRotateI4(it, it->yuv_in_ + Y_OFF));
+
+  i4_alpha = GetAlpha(&total_histo);
+  if (IS_BETTER_ALPHA(i4_alpha, best_alpha)) {
+    VP8SetIntra4Mode(it, modes);
+    best_alpha = i4_alpha;
+  }
+  return best_alpha;
+}
+
+static int MBAnalyzeBestUVMode(VP8EncIterator* const it) {
+  int best_alpha = DEFAULT_ALPHA;
+  int best_mode = 0;
+  const int max_mode = MAX_UV_MODE;
+  int mode;
+
+  VP8MakeChroma8Preds(it);
+  for (mode = 0; mode < max_mode; ++mode) {
+    VP8Histogram histo;
+    int alpha;
+    InitHistogram(&histo);
+    VP8CollectHistogram(it->yuv_in_ + U_OFF,
+                        it->yuv_p_ + VP8UVModeOffsets[mode],
+                        16, 16 + 4 + 4, &histo);
+    alpha = GetAlpha(&histo);
+    if (IS_BETTER_ALPHA(alpha, best_alpha)) {
+      best_alpha = alpha;
+      best_mode = mode;
+    }
+  }
+  VP8SetIntraUVMode(it, best_mode);
+  return best_alpha;
+}
+
+static void MBAnalyze(VP8EncIterator* const it,
+                      int alphas[MAX_ALPHA + 1],
+                      int* const alpha, int* const uv_alpha) {
+  const VP8Encoder* const enc = it->enc_;
+  int best_alpha, best_uv_alpha;
+
+  VP8SetIntra16Mode(it, 0);  // default: Intra16, DC_PRED
+  VP8SetSkip(it, 0);         // not skipped
+  VP8SetSegment(it, 0);      // default segment, spec-wise.
+
+  best_alpha = MBAnalyzeBestIntra16Mode(it);
+  if (enc->method_ >= 5) {
+    // We go and make a fast decision for intra4/intra16.
+    // It's usually not a good and definitive pick, but helps seeding the stats
+    // about level bit-cost.
+    // TODO(skal): improve criterion.
+    best_alpha = MBAnalyzeBestIntra4Mode(it, best_alpha);
+  }
+  best_uv_alpha = MBAnalyzeBestUVMode(it);
+
+  // Final susceptibility mix
+  best_alpha = (3 * best_alpha + best_uv_alpha + 2) >> 2;
+  best_alpha = FinalAlphaValue(best_alpha);
+  alphas[best_alpha]++;
+  it->mb_->alpha_ = best_alpha;   // for later remapping.
+
+  // Accumulate for later complexity analysis.
+  *alpha += best_alpha;   // mixed susceptibility (not just luma)
+  *uv_alpha += best_uv_alpha;
+}
+
+static void DefaultMBInfo(VP8MBInfo* const mb) {
+  mb->type_ = 1;     // I16x16
+  mb->uv_mode_ = 0;
+  mb->skip_ = 0;     // not skipped
+  mb->segment_ = 0;  // default segment
+  mb->alpha_ = 0;
+}
+
+//------------------------------------------------------------------------------
+// Main analysis loop:
+// Collect all susceptibilities for each macroblock and record their
+// distribution in alphas[]. Segments is assigned a-posteriori, based on
+// this histogram.
+// We also pick an intra16 prediction mode, which shouldn't be considered
+// final except for fast-encode settings. We can also pick some intra4 modes
+// and decide intra4/intra16, but that's usually almost always a bad choice at
+// this stage.
+
+static void ResetAllMBInfo(VP8Encoder* const enc) {
+  int n;
+  for (n = 0; n < enc->mb_w_ * enc->mb_h_; ++n) {
+    DefaultMBInfo(&enc->mb_info_[n]);
+  }
+  // Default susceptibilities.
+  enc->dqm_[0].alpha_ = 0;
+  enc->dqm_[0].beta_ = 0;
+  // Note: we can't compute this alpha_ / uv_alpha_ -> set to default value.
+  enc->alpha_ = 0;
+  enc->uv_alpha_ = 0;
+  WebPReportProgress(enc->pic_, enc->percent_ + 20, &enc->percent_);
+}
+
+// struct used to collect job result
+typedef struct {
+  WebPWorker worker;
+  int alphas[MAX_ALPHA + 1];
+  int alpha, uv_alpha;
+  VP8EncIterator it;
+  int delta_progress;
+} SegmentJob;
+
+// main work call
+static int DoSegmentsJob(SegmentJob* const job, VP8EncIterator* const it) {
+  int ok = 1;
+  if (!VP8IteratorIsDone(it)) {
+    uint8_t tmp[32 + ALIGN_CST];
+    uint8_t* const scratch = (uint8_t*)DO_ALIGN(tmp);
+    do {
+      // Let's pretend we have perfect lossless reconstruction.
+      VP8IteratorImport(it, scratch);
+      MBAnalyze(it, job->alphas, &job->alpha, &job->uv_alpha);
+      ok = VP8IteratorProgress(it, job->delta_progress);
+    } while (ok && VP8IteratorNext(it));
+  }
+  return ok;
+}
+
+static void MergeJobs(const SegmentJob* const src, SegmentJob* const dst) {
+  int i;
+  for (i = 0; i <= MAX_ALPHA; ++i) dst->alphas[i] += src->alphas[i];
+  dst->alpha += src->alpha;
+  dst->uv_alpha += src->uv_alpha;
+}
+
+// initialize the job struct with some TODOs
+static void InitSegmentJob(VP8Encoder* const enc, SegmentJob* const job,
+                           int start_row, int end_row) {
+  WebPGetWorkerInterface()->Init(&job->worker);
+  job->worker.data1 = job;
+  job->worker.data2 = &job->it;
+  job->worker.hook = (WebPWorkerHook)DoSegmentsJob;
+  VP8IteratorInit(enc, &job->it);
+  VP8IteratorSetRow(&job->it, start_row);
+  VP8IteratorSetCountDown(&job->it, (end_row - start_row) * enc->mb_w_);
+  memset(job->alphas, 0, sizeof(job->alphas));
+  job->alpha = 0;
+  job->uv_alpha = 0;
+  // only one of both jobs can record the progress, since we don't
+  // expect the user's hook to be multi-thread safe
+  job->delta_progress = (start_row == 0) ? 20 : 0;
+}
+
+// main entry point
+int VP8EncAnalyze(VP8Encoder* const enc) {
+  int ok = 1;
+  const int do_segments =
+      enc->config_->emulate_jpeg_size ||   // We need the complexity evaluation.
+      (enc->segment_hdr_.num_segments_ > 1) ||
+      (enc->method_ == 0);  // for method 0, we need preds_[] to be filled.
+  if (do_segments) {
+    const int last_row = enc->mb_h_;
+    // We give a little more than a half work to the main thread.
+    const int split_row = (9 * last_row + 15) >> 4;
+    const int total_mb = last_row * enc->mb_w_;
+#ifdef WEBP_USE_THREAD
+    const int kMinSplitRow = 2;  // minimal rows needed for mt to be worth it
+    const int do_mt = (enc->thread_level_ > 0) && (split_row >= kMinSplitRow);
+#else
+    const int do_mt = 0;
+#endif
+    const WebPWorkerInterface* const worker_interface =
+        WebPGetWorkerInterface();
+    SegmentJob main_job;
+    if (do_mt) {
+      SegmentJob side_job;
+      // Note the use of '&' instead of '&&' because we must call the functions
+      // no matter what.
+      InitSegmentJob(enc, &main_job, 0, split_row);
+      InitSegmentJob(enc, &side_job, split_row, last_row);
+      // we don't need to call Reset() on main_job.worker, since we're calling
+      // WebPWorkerExecute() on it
+      ok &= worker_interface->Reset(&side_job.worker);
+      // launch the two jobs in parallel
+      if (ok) {
+        worker_interface->Launch(&side_job.worker);
+        worker_interface->Execute(&main_job.worker);
+        ok &= worker_interface->Sync(&side_job.worker);
+        ok &= worker_interface->Sync(&main_job.worker);
+      }
+      worker_interface->End(&side_job.worker);
+      if (ok) MergeJobs(&side_job, &main_job);  // merge results together
+    } else {
+      // Even for single-thread case, we use the generic Worker tools.
+      InitSegmentJob(enc, &main_job, 0, last_row);
+      worker_interface->Execute(&main_job.worker);
+      ok &= worker_interface->Sync(&main_job.worker);
+    }
+    worker_interface->End(&main_job.worker);
+    if (ok) {
+      enc->alpha_ = main_job.alpha / total_mb;
+      enc->uv_alpha_ = main_job.uv_alpha / total_mb;
+      AssignSegments(enc, main_job.alphas);
+    }
+  } else {   // Use only one default segment.
+    ResetAllMBInfo(enc);
+  }
+  return ok;
+}
+
diff --git a/Source/LibWebP/src/enc/enc.backward_references.c b/Source/LibWebP/src/enc/enc.backward_references.c
new file mode 100644
index 0000000..dcce9e9
--- /dev/null
+++ b/Source/LibWebP/src/enc/enc.backward_references.c
@@ -0,0 +1,1076 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Author: Jyrki Alakuijala (jyrki at google.com)
+//
+
+#include <assert.h>
+#include <math.h>
+
+#include "./backward_references.h"
+#include "./histogram.h"
+#include "../dsp/lossless.h"
+#include "../utils/color_cache.h"
+#include "../utils/utils.h"
+
+#define VALUES_IN_BYTE 256
+
+#define HASH_MULTIPLIER (0xc6a4a7935bd1e995ULL)
+
+#define MIN_BLOCK_SIZE 256  // minimum block size for backward references
+
+#define MAX_ENTROPY    (1e30f)
+
+// 1M window (4M bytes) minus 120 special codes for short distances.
+#define WINDOW_SIZE ((1 << 20) - 120)
+
+// Bounds for the match length.
+#define MIN_LENGTH 2
+#define MAX_LENGTH 4096
+
+// -----------------------------------------------------------------------------
+
+static const uint8_t plane_to_code_lut[128] = {
+ 96,   73,  55,  39,  23,  13,   5,  1,  255, 255, 255, 255, 255, 255, 255, 255,
+ 101,  78,  58,  42,  26,  16,   8,  2,    0,   3,  9,   17,  27,  43,  59,  79,
+ 102,  86,  62,  46,  32,  20,  10,  6,    4,   7,  11,  21,  33,  47,  63,  87,
+ 105,  90,  70,  52,  37,  28,  18,  14,  12,  15,  19,  29,  38,  53,  71,  91,
+ 110,  99,  82,  66,  48,  35,  30,  24,  22,  25,  31,  36,  49,  67,  83, 100,
+ 115, 108,  94,  76,  64,  50,  44,  40,  34,  41,  45,  51,  65,  77,  95, 109,
+ 118, 113, 103,  92,  80,  68,  60,  56,  54,  57,  61,  69,  81,  93, 104, 114,
+ 119, 116, 111, 106,  97,  88,  84,  74,  72,  75,  85,  89,  98, 107, 112, 117
+};
+
+static int DistanceToPlaneCode(int xsize, int dist) {
+  const int yoffset = dist / xsize;
+  const int xoffset = dist - yoffset * xsize;
+  if (xoffset <= 8 && yoffset < 8) {
+    return plane_to_code_lut[yoffset * 16 + 8 - xoffset] + 1;
+  } else if (xoffset > xsize - 8 && yoffset < 7) {
+    return plane_to_code_lut[(yoffset + 1) * 16 + 8 + (xsize - xoffset)] + 1;
+  }
+  return dist + 120;
+}
+
+// TODO(vikasa): Evaluate loading (and comparing) 32/64 bits for the inner while
+// loop.
+static WEBP_INLINE int FindMatchLength(const uint32_t* const array1,
+                                       const uint32_t* const array2,
+                                       int best_len_match,
+                                       int max_limit) {
+  int match_len = 0;
+  // Before 'expensive' linear match, check if the two arrays match at the
+  // current best length index.
+  if (array1[best_len_match] != array2[best_len_match]) return 0;
+  while (match_len < max_limit && array1[match_len] == array2[match_len]) {
+    ++match_len;
+  }
+  return match_len;
+}
+
+// -----------------------------------------------------------------------------
+//  VP8LBackwardRefs
+
+struct PixOrCopyBlock {
+  PixOrCopyBlock* next_;   // next block (or NULL)
+  PixOrCopy* start_;       // data start
+  int size_;               // currently used size
+};
+
+static void ClearBackwardRefs(VP8LBackwardRefs* const refs) {
+  assert(refs != NULL);
+  if (refs->tail_ != NULL) {
+    *refs->tail_ = refs->free_blocks_;  // recycle all blocks at once
+  }
+  refs->free_blocks_ = refs->refs_;
+  refs->tail_ = &refs->refs_;
+  refs->last_block_ = NULL;
+  refs->refs_ = NULL;
+}
+
+void VP8LBackwardRefsClear(VP8LBackwardRefs* const refs) {
+  assert(refs != NULL);
+  ClearBackwardRefs(refs);
+  while (refs->free_blocks_ != NULL) {
+    PixOrCopyBlock* const next = refs->free_blocks_->next_;
+    WebPSafeFree(refs->free_blocks_);
+    refs->free_blocks_ = next;
+  }
+}
+
+void VP8LBackwardRefsInit(VP8LBackwardRefs* const refs, int block_size) {
+  assert(refs != NULL);
+  memset(refs, 0, sizeof(*refs));
+  refs->tail_ = &refs->refs_;
+  refs->block_size_ =
+      (block_size < MIN_BLOCK_SIZE) ? MIN_BLOCK_SIZE : block_size;
+}
+
+VP8LRefsCursor VP8LRefsCursorInit(const VP8LBackwardRefs* const refs) {
+  VP8LRefsCursor c;
+  c.cur_block_ = refs->refs_;
+  if (refs->refs_ != NULL) {
+    c.cur_pos = c.cur_block_->start_;
+    c.last_pos_ = c.cur_pos + c.cur_block_->size_;
+  } else {
+    c.cur_pos = NULL;
+    c.last_pos_ = NULL;
+  }
+  return c;
+}
+
+void VP8LRefsCursorNextBlock(VP8LRefsCursor* const c) {
+  PixOrCopyBlock* const b = c->cur_block_->next_;
+  c->cur_pos = (b == NULL) ? NULL : b->start_;
+  c->last_pos_ = (b == NULL) ? NULL : b->start_ + b->size_;
+  c->cur_block_ = b;
+}
+
+// Create a new block, either from the free list or allocated
+static PixOrCopyBlock* BackwardRefsNewBlock(VP8LBackwardRefs* const refs) {
+  PixOrCopyBlock* b = refs->free_blocks_;
+  if (b == NULL) {   // allocate new memory chunk
+    const size_t total_size =
+        sizeof(*b) + refs->block_size_ * sizeof(*b->start_);
+    b = (PixOrCopyBlock*)WebPSafeMalloc(1ULL, total_size);
+    if (b == NULL) {
+      refs->error_ |= 1;
+      return NULL;
+    }
+    b->start_ = (PixOrCopy*)((uint8_t*)b + sizeof(*b));  // not always aligned
+  } else {  // recycle from free-list
+    refs->free_blocks_ = b->next_;
+  }
+  *refs->tail_ = b;
+  refs->tail_ = &b->next_;
+  refs->last_block_ = b;
+  b->next_ = NULL;
+  b->size_ = 0;
+  return b;
+}
+
+static WEBP_INLINE void BackwardRefsCursorAdd(VP8LBackwardRefs* const refs,
+                                              const PixOrCopy v) {
+  PixOrCopyBlock* b = refs->last_block_;
+  if (b == NULL || b->size_ == refs->block_size_) {
+    b = BackwardRefsNewBlock(refs);
+    if (b == NULL) return;   // refs->error_ is set
+  }
+  b->start_[b->size_++] = v;
+}
+
+int VP8LBackwardRefsCopy(const VP8LBackwardRefs* const src,
+                         VP8LBackwardRefs* const dst) {
+  const PixOrCopyBlock* b = src->refs_;
+  ClearBackwardRefs(dst);
+  assert(src->block_size_ == dst->block_size_);
+  while (b != NULL) {
+    PixOrCopyBlock* const new_b = BackwardRefsNewBlock(dst);
+    if (new_b == NULL) return 0;   // dst->error_ is set
+    memcpy(new_b->start_, b->start_, b->size_ * sizeof(*b->start_));
+    new_b->size_ = b->size_;
+    b = b->next_;
+  }
+  return 1;
+}
+
+// -----------------------------------------------------------------------------
+// Hash chains
+
+// initialize as empty
+static void HashChainReset(VP8LHashChain* const p) {
+  int i;
+  assert(p != NULL);
+  for (i = 0; i < p->size_; ++i) {
+    p->chain_[i] = -1;
+  }
+  for (i = 0; i < HASH_SIZE; ++i) {
+    p->hash_to_first_index_[i] = -1;
+  }
+}
+
+int VP8LHashChainInit(VP8LHashChain* const p, int size) {
+  assert(p->size_ == 0);
+  assert(p->chain_ == NULL);
+  assert(size > 0);
+  p->chain_ = (int*)WebPSafeMalloc(size, sizeof(*p->chain_));
+  if (p->chain_ == NULL) return 0;
+  p->size_ = size;
+  HashChainReset(p);
+  return 1;
+}
+
+void VP8LHashChainClear(VP8LHashChain* const p) {
+  assert(p != NULL);
+  WebPSafeFree(p->chain_);
+  p->size_ = 0;
+  p->chain_ = NULL;
+}
+
+// -----------------------------------------------------------------------------
+
+static WEBP_INLINE uint64_t GetPixPairHash64(const uint32_t* const argb) {
+  uint64_t key = ((uint64_t)argb[1] << 32) | argb[0];
+  key = (key * HASH_MULTIPLIER) >> (64 - HASH_BITS);
+  return key;
+}
+
+// Insertion of two pixels at a time.
+static void HashChainInsert(VP8LHashChain* const p,
+                            const uint32_t* const argb, int pos) {
+  const uint64_t hash_code = GetPixPairHash64(argb);
+  p->chain_[pos] = p->hash_to_first_index_[hash_code];
+  p->hash_to_first_index_[hash_code] = pos;
+}
+
+static void GetParamsForHashChainFindCopy(
+    int quality, int low_effort, int* iter_max, int* len_for_unit_dist) {
+  *iter_max = 8 + (quality * quality) / 40;
+  *len_for_unit_dist = 32 + (96 * quality) / 100;
+  if (low_effort) {
+    *iter_max -= 2;
+    *len_for_unit_dist /= 4;
+  }
+}
+
+static int GetWindowSizeForHashChain(int quality, int xsize) {
+  const int max_window_size = (quality > 75) ? WINDOW_SIZE
+                            : (quality > 50) ? (xsize << 8)
+                            : (quality > 25) ? (xsize << 6)
+                            : (xsize << 4);
+  assert(xsize > 0);
+  return (max_window_size > WINDOW_SIZE) ? WINDOW_SIZE : max_window_size;
+}
+
+static WEBP_INLINE int MaxFindCopyLength(int len) {
+  return (len < MAX_LENGTH) ? len : MAX_LENGTH;
+}
+
+static void HashChainFindOffset(const VP8LHashChain* const p, int base_position,
+                                const uint32_t* const argb, int len,
+                                int window_size, int* const distance_ptr) {
+  const uint32_t* const argb_start = argb + base_position;
+  const int min_pos =
+      (base_position > window_size) ? base_position - window_size : 0;
+  int pos;
+  assert(len <= MAX_LENGTH);
+  for (pos = p->hash_to_first_index_[GetPixPairHash64(argb_start)];
+       pos >= min_pos;
+       pos = p->chain_[pos]) {
+    const int curr_length =
+        FindMatchLength(argb + pos, argb_start, len - 1, len);
+    if (curr_length == len) break;
+  }
+  *distance_ptr = base_position - pos;
+}
+
+static int HashChainFindCopy(const VP8LHashChain* const p,
+                             int base_position, int xsize,
+                             const uint32_t* const argb, int max_len,
+                             int window_size, int iter_max,
+                             int len_for_unit_dist,
+                             int* const distance_ptr,
+                             int* const length_ptr) {
+  const uint32_t* const argb_start = argb + base_position;
+  int iter = 0;
+  int best_length = 1;
+  const int length_max = 256;
+  int best_distance = 0;
+  const int min_pos =
+      (base_position > window_size) ? base_position - window_size : 0;
+  int pos;
+  assert(xsize > 0);
+  for (pos = p->hash_to_first_index_[GetPixPairHash64(argb_start)];
+       pos >= min_pos;
+       pos = p->chain_[pos]) {
+    int curr_length;
+    int distance;
+    if (iter > 8) {
+      if (iter > iter_max || best_length >= length_max) {
+        break;
+      }
+    }
+    ++iter;
+
+    curr_length = FindMatchLength(argb + pos, argb_start, best_length, max_len);
+    if (curr_length < best_length) continue;
+
+    distance = base_position - pos;
+    if (best_length < curr_length) {
+      best_length = curr_length;
+      best_distance = distance;
+      if (curr_length >= max_len) {
+        break;
+      }
+      if ((distance == 1 || distance == xsize) &&
+          best_length >= len_for_unit_dist) {
+        break;
+      }
+    }
+  }
+  *distance_ptr = best_distance;
+  *length_ptr = best_length;
+  return (best_length >= MIN_LENGTH);
+}
+
+static void AddSingleLiteral(uint32_t pixel, int use_color_cache,
+                             VP8LColorCache* const hashers,
+                             VP8LBackwardRefs* const refs) {
+  PixOrCopy v;
+  if (use_color_cache && VP8LColorCacheContains(hashers, pixel)) {
+    // push pixel as a PixOrCopyCreateCacheIdx pixel
+    const int ix = VP8LColorCacheGetIndex(hashers, pixel);
+    v = PixOrCopyCreateCacheIdx(ix);
+  } else {
+    if (use_color_cache) VP8LColorCacheInsert(hashers, pixel);
+    v = PixOrCopyCreateLiteral(pixel);
+  }
+  BackwardRefsCursorAdd(refs, v);
+}
+
+static WEBP_INLINE void PushBackCopy(VP8LBackwardRefs* const refs, int length) {
+  while (length >= MAX_LENGTH) {
+    BackwardRefsCursorAdd(refs, PixOrCopyCreateCopy(1, MAX_LENGTH));
+    length -= MAX_LENGTH;
+  }
+  if (length > 0) {
+    BackwardRefsCursorAdd(refs, PixOrCopyCreateCopy(1, length));
+  }
+}
+
+static int BackwardReferencesRle(int xsize, int ysize,
+                                 const uint32_t* const argb,
+                                 int cache_bits, VP8LBackwardRefs* const refs) {
+  const int pix_count = xsize * ysize;
+  int match_len = 0;
+  int i;
+  int cc_init = 0;
+  const int use_color_cache = (cache_bits > 0);
+  VP8LColorCache hashers;
+
+  if (use_color_cache) {
+    cc_init = VP8LColorCacheInit(&hashers, cache_bits);
+    if (!cc_init) return 0;
+  }
+  ClearBackwardRefs(refs);
+  // Add first pixel as literal.
+  AddSingleLiteral(argb[0], use_color_cache, &hashers, refs);
+  for (i = 1; i < pix_count; ++i) {
+    if (argb[i] == argb[i - 1]) {
+      ++match_len;
+    } else {
+      PushBackCopy(refs, match_len);
+      match_len = 0;
+      AddSingleLiteral(argb[i], use_color_cache, &hashers, refs);
+    }
+  }
+  PushBackCopy(refs, match_len);
+  if (cc_init) VP8LColorCacheClear(&hashers);
+  return !refs->error_;
+}
+
+static int BackwardReferencesLz77(int xsize, int ysize,
+                                  const uint32_t* const argb, int cache_bits,
+                                  int quality, int low_effort,
+                                  VP8LHashChain* const hash_chain,
+                                  VP8LBackwardRefs* const refs) {
+  int i;
+  int ok = 0;
+  int cc_init = 0;
+  const int use_color_cache = (cache_bits > 0);
+  const int pix_count = xsize * ysize;
+  VP8LColorCache hashers;
+  int iter_max, len_for_unit_dist;
+  const int window_size = GetWindowSizeForHashChain(quality, xsize);
+  GetParamsForHashChainFindCopy(quality, low_effort, &iter_max,
+                                &len_for_unit_dist);
+
+  if (use_color_cache) {
+    cc_init = VP8LColorCacheInit(&hashers, cache_bits);
+    if (!cc_init) goto Error;
+  }
+  ClearBackwardRefs(refs);
+  HashChainReset(hash_chain);
+  for (i = 0; i < pix_count - 2; ) {
+    // Alternative#1: Code the pixels starting at 'i' using backward reference.
+    int offset = 0;
+    int len = 0;
+    const int max_len = MaxFindCopyLength(pix_count - i);
+    HashChainFindCopy(hash_chain, i, xsize, argb, max_len, window_size,
+                      iter_max, len_for_unit_dist, &offset, &len);
+    if (len >= MIN_LENGTH) {
+      int offset2 = 0;
+      int len2 = 0;
+      int k;
+      HashChainInsert(hash_chain, &argb[i], i);
+      if ((len < (max_len >> 2)) && !low_effort) {
+        // Evaluate Alternative#2: Insert the pixel at 'i' as literal, and code
+        // the pixels starting at 'i + 1' using backward reference.
+        HashChainFindCopy(hash_chain, i + 1, xsize, argb, max_len - 1,
+                          window_size, iter_max, len_for_unit_dist, &offset2,
+                          &len2);
+        if (len2 > len + 1) {
+          AddSingleLiteral(argb[i], use_color_cache, &hashers, refs);
+          i++;  // Backward reference to be done for next pixel.
+          len = len2;
+          offset = offset2;
+        }
+      }
+      BackwardRefsCursorAdd(refs, PixOrCopyCreateCopy(offset, len));
+      if (use_color_cache) {
+        for (k = 0; k < len; ++k) {
+          VP8LColorCacheInsert(&hashers, argb[i + k]);
+        }
+      }
+      // Add to the hash_chain (but cannot add the last pixel).
+      {
+        const int last = (len < pix_count - 1 - i) ? len : pix_count - 1 - i;
+        for (k = 1; k < last; ++k) {
+          HashChainInsert(hash_chain, &argb[i + k], i + k);
+        }
+      }
+      i += len;
+    } else {
+      AddSingleLiteral(argb[i], use_color_cache, &hashers, refs);
+      HashChainInsert(hash_chain, &argb[i], i);
+      ++i;
+    }
+  }
+  while (i < pix_count) {
+    // Handle the last (two) pixel(s).
+    AddSingleLiteral(argb[i], use_color_cache, &hashers, refs);
+    if (i < (pix_count - 1)) HashChainInsert(hash_chain, &argb[i], i);
+    ++i;
+  }
+
+  ok = !refs->error_;
+ Error:
+  if (cc_init) VP8LColorCacheClear(&hashers);
+  return ok;
+}
+
+// -----------------------------------------------------------------------------
+
+typedef struct {
+  double alpha_[VALUES_IN_BYTE];
+  double red_[VALUES_IN_BYTE];
+  double blue_[VALUES_IN_BYTE];
+  double distance_[NUM_DISTANCE_CODES];
+  double* literal_;
+} CostModel;
+
+static int BackwardReferencesTraceBackwards(
+    int xsize, int ysize, const uint32_t* const argb, int quality,
+    int cache_bits, VP8LHashChain* const hash_chain,
+    VP8LBackwardRefs* const refs);
+
+static void ConvertPopulationCountTableToBitEstimates(
+    int num_symbols, const uint32_t population_counts[], double output[]) {
+  uint32_t sum = 0;
+  int nonzeros = 0;
+  int i;
+  for (i = 0; i < num_symbols; ++i) {
+    sum += population_counts[i];
+    if (population_counts[i] > 0) {
+      ++nonzeros;
+    }
+  }
+  if (nonzeros <= 1) {
+    memset(output, 0, num_symbols * sizeof(*output));
+  } else {
+    const double logsum = VP8LFastLog2(sum);
+    for (i = 0; i < num_symbols; ++i) {
+      output[i] = logsum - VP8LFastLog2(population_counts[i]);
+    }
+  }
+}
+
+static int CostModelBuild(CostModel* const m, int cache_bits,
+                          VP8LBackwardRefs* const refs) {
+  int ok = 0;
+  VP8LHistogram* const histo = VP8LAllocateHistogram(cache_bits);
+  if (histo == NULL) goto Error;
+
+  VP8LHistogramCreate(histo, refs, cache_bits);
+
+  ConvertPopulationCountTableToBitEstimates(
+      VP8LHistogramNumCodes(histo->palette_code_bits_),
+      histo->literal_, m->literal_);
+  ConvertPopulationCountTableToBitEstimates(
+      VALUES_IN_BYTE, histo->red_, m->red_);
+  ConvertPopulationCountTableToBitEstimates(
+      VALUES_IN_BYTE, histo->blue_, m->blue_);
+  ConvertPopulationCountTableToBitEstimates(
+      VALUES_IN_BYTE, histo->alpha_, m->alpha_);
+  ConvertPopulationCountTableToBitEstimates(
+      NUM_DISTANCE_CODES, histo->distance_, m->distance_);
+  ok = 1;
+
+ Error:
+  VP8LFreeHistogram(histo);
+  return ok;
+}
+
+static WEBP_INLINE double GetLiteralCost(const CostModel* const m, uint32_t v) {
+  return m->alpha_[v >> 24] +
+         m->red_[(v >> 16) & 0xff] +
+         m->literal_[(v >> 8) & 0xff] +
+         m->blue_[v & 0xff];
+}
+
+static WEBP_INLINE double GetCacheCost(const CostModel* const m, uint32_t idx) {
+  const int literal_idx = VALUES_IN_BYTE + NUM_LENGTH_CODES + idx;
+  return m->literal_[literal_idx];
+}
+
+static WEBP_INLINE double GetLengthCost(const CostModel* const m,
+                                        uint32_t length) {
+  int code, extra_bits;
+  VP8LPrefixEncodeBits(length, &code, &extra_bits);
+  return m->literal_[VALUES_IN_BYTE + code] + extra_bits;
+}
+
+static WEBP_INLINE double GetDistanceCost(const CostModel* const m,
+                                          uint32_t distance) {
+  int code, extra_bits;
+  VP8LPrefixEncodeBits(distance, &code, &extra_bits);
+  return m->distance_[code] + extra_bits;
+}
+
+static void AddSingleLiteralWithCostModel(
+    const uint32_t* const argb, VP8LHashChain* const hash_chain,
+    VP8LColorCache* const hashers, const CostModel* const cost_model, int idx,
+    int is_last, int use_color_cache, double prev_cost, float* const cost,
+    uint16_t* const dist_array) {
+  double cost_val = prev_cost;
+  const uint32_t color = argb[0];
+  if (!is_last) {
+    HashChainInsert(hash_chain, argb, idx);
+  }
+  if (use_color_cache && VP8LColorCacheContains(hashers, color)) {
+    const double mul0 = 0.68;
+    const int ix = VP8LColorCacheGetIndex(hashers, color);
+    cost_val += GetCacheCost(cost_model, ix) * mul0;
+  } else {
+    const double mul1 = 0.82;
+    if (use_color_cache) VP8LColorCacheInsert(hashers, color);
+    cost_val += GetLiteralCost(cost_model, color) * mul1;
+  }
+  if (cost[idx] > cost_val) {
+    cost[idx] = (float)cost_val;
+    dist_array[idx] = 1;  // only one is inserted.
+  }
+}
+
+static int BackwardReferencesHashChainDistanceOnly(
+    int xsize, int ysize, const uint32_t* const argb,
+    int quality, int cache_bits, VP8LHashChain* const hash_chain,
+    VP8LBackwardRefs* const refs, uint16_t* const dist_array) {
+  int i;
+  int ok = 0;
+  int cc_init = 0;
+  const int pix_count = xsize * ysize;
+  const int use_color_cache = (cache_bits > 0);
+  float* const cost =
+      (float*)WebPSafeMalloc(pix_count, sizeof(*cost));
+  const size_t literal_array_size = sizeof(double) *
+      (NUM_LITERAL_CODES + NUM_LENGTH_CODES +
+       ((cache_bits > 0) ? (1 << cache_bits) : 0));
+  const size_t cost_model_size = sizeof(CostModel) + literal_array_size;
+  CostModel* const cost_model =
+      (CostModel*)WebPSafeMalloc(1ULL, cost_model_size);
+  VP8LColorCache hashers;
+  const int min_distance_code = 2;
+  int iter_max, len_for_unit_dist;
+  const int window_size = GetWindowSizeForHashChain(quality, xsize);
+  GetParamsForHashChainFindCopy(quality, 0, &iter_max, &len_for_unit_dist);
+
+  if (cost == NULL || cost_model == NULL) goto Error;
+
+  cost_model->literal_ = (double*)(cost_model + 1);
+  if (use_color_cache) {
+    cc_init = VP8LColorCacheInit(&hashers, cache_bits);
+    if (!cc_init) goto Error;
+  }
+
+  if (!CostModelBuild(cost_model, cache_bits, refs)) {
+    goto Error;
+  }
+
+  for (i = 0; i < pix_count; ++i) cost[i] = 1e38f;
+
+  // We loop one pixel at a time, but store all currently best points to
+  // non-processed locations from this point.
+  dist_array[0] = 0;
+  HashChainReset(hash_chain);
+  // Add first pixel as literal.
+  AddSingleLiteralWithCostModel(argb + 0, hash_chain, &hashers, cost_model, 0,
+                                0, use_color_cache, 0.0, cost, dist_array);
+  for (i = 1; i < pix_count - 1; ++i) {
+    int offset = 0;
+    int len = 0;
+    double prev_cost = cost[i - 1];
+    const int max_len = MaxFindCopyLength(pix_count - i);
+    HashChainFindCopy(hash_chain, i, xsize, argb, max_len, window_size,
+                      iter_max, len_for_unit_dist, &offset, &len);
+    if (len >= MIN_LENGTH) {
+      const int code = DistanceToPlaneCode(xsize, offset);
+      const double distance_cost =
+          prev_cost + GetDistanceCost(cost_model, code);
+      int k;
+      for (k = 1; k < len; ++k) {
+        const double cost_val = distance_cost + GetLengthCost(cost_model, k);
+        if (cost[i + k] > cost_val) {
+          cost[i + k] = (float)cost_val;
+          dist_array[i + k] = k + 1;
+        }
+      }
+      // This if is for speedup only. It roughly doubles the speed, and
+      // makes compression worse by .1 %.
+      if (len >= len_for_unit_dist && code <= min_distance_code) {
+        // Long copy for short distances, let's skip the middle
+        // lookups for better copies.
+        // 1) insert the hashes.
+        if (use_color_cache) {
+          for (k = 0; k < len; ++k) {
+            VP8LColorCacheInsert(&hashers, argb[i + k]);
+          }
+        }
+        // 2) Add to the hash_chain (but cannot add the last pixel)
+        {
+          const int last = (len + i < pix_count - 1) ? len + i
+                                                     : pix_count - 1;
+          for (k = i; k < last; ++k) {
+            HashChainInsert(hash_chain, &argb[k], k);
+          }
+        }
+        // 3) jump.
+        i += len - 1;  // for loop does ++i, thus -1 here.
+        goto next_symbol;
+      }
+      if (len != MIN_LENGTH) {
+        int code_min_length;
+        double cost_total;
+        HashChainFindOffset(hash_chain, i, argb, MIN_LENGTH, window_size,
+                            &offset);
+        code_min_length = DistanceToPlaneCode(xsize, offset);
+        cost_total = prev_cost +
+            GetDistanceCost(cost_model, code_min_length) +
+            GetLengthCost(cost_model, 1);
+        if (cost[i + 1] > cost_total) {
+          cost[i + 1] = (float)cost_total;
+          dist_array[i + 1] = 2;
+        }
+      }
+    }
+    AddSingleLiteralWithCostModel(argb + i, hash_chain, &hashers, cost_model, i,
+                                  0, use_color_cache, prev_cost, cost,
+                                  dist_array);
+ next_symbol: ;
+  }
+  // Handle the last pixel.
+  if (i == (pix_count - 1)) {
+    AddSingleLiteralWithCostModel(argb + i, hash_chain, &hashers, cost_model, i,
+                                  1, use_color_cache, cost[pix_count - 2], cost,
+                                  dist_array);
+  }
+  ok = !refs->error_;
+ Error:
+  if (cc_init) VP8LColorCacheClear(&hashers);
+  WebPSafeFree(cost_model);
+  WebPSafeFree(cost);
+  return ok;
+}
+
+// We pack the path at the end of *dist_array and return
+// a pointer to this part of the array. Example:
+// dist_array = [1x2xx3x2] => packed [1x2x1232], chosen_path = [1232]
+static void TraceBackwards(uint16_t* const dist_array,
+                           int dist_array_size,
+                           uint16_t** const chosen_path,
+                           int* const chosen_path_size) {
+  uint16_t* path = dist_array + dist_array_size;
+  uint16_t* cur = dist_array + dist_array_size - 1;
+  while (cur >= dist_array) {
+    const int k = *cur;
+    --path;
+    *path = k;
+    cur -= k;
+  }
+  *chosen_path = path;
+  *chosen_path_size = (int)(dist_array + dist_array_size - path);
+}
+
+static int BackwardReferencesHashChainFollowChosenPath(
+    int xsize, int ysize, const uint32_t* const argb,
+    int quality, int cache_bits,
+    const uint16_t* const chosen_path, int chosen_path_size,
+    VP8LHashChain* const hash_chain,
+    VP8LBackwardRefs* const refs) {
+  const int pix_count = xsize * ysize;
+  const int use_color_cache = (cache_bits > 0);
+  int ix;
+  int i = 0;
+  int ok = 0;
+  int cc_init = 0;
+  const int window_size = GetWindowSizeForHashChain(quality, xsize);
+  VP8LColorCache hashers;
+
+  if (use_color_cache) {
+    cc_init = VP8LColorCacheInit(&hashers, cache_bits);
+    if (!cc_init) goto Error;
+  }
+
+  ClearBackwardRefs(refs);
+  HashChainReset(hash_chain);
+  for (ix = 0; ix < chosen_path_size; ++ix) {
+    int offset = 0;
+    const int len = chosen_path[ix];
+    if (len != 1) {
+      int k;
+      HashChainFindOffset(hash_chain, i, argb, len, window_size, &offset);
+      BackwardRefsCursorAdd(refs, PixOrCopyCreateCopy(offset, len));
+      if (use_color_cache) {
+        for (k = 0; k < len; ++k) {
+          VP8LColorCacheInsert(&hashers, argb[i + k]);
+        }
+      }
+      {
+        const int last = (len < pix_count - 1 - i) ? len : pix_count - 1 - i;
+        for (k = 0; k < last; ++k) {
+          HashChainInsert(hash_chain, &argb[i + k], i + k);
+        }
+      }
+      i += len;
+    } else {
+      PixOrCopy v;
+      if (use_color_cache && VP8LColorCacheContains(&hashers, argb[i])) {
+        // push pixel as a color cache index
+        const int idx = VP8LColorCacheGetIndex(&hashers, argb[i]);
+        v = PixOrCopyCreateCacheIdx(idx);
+      } else {
+        if (use_color_cache) VP8LColorCacheInsert(&hashers, argb[i]);
+        v = PixOrCopyCreateLiteral(argb[i]);
+      }
+      BackwardRefsCursorAdd(refs, v);
+      if (i + 1 < pix_count) {
+        HashChainInsert(hash_chain, &argb[i], i);
+      }
+      ++i;
+    }
+  }
+  ok = !refs->error_;
+ Error:
+  if (cc_init) VP8LColorCacheClear(&hashers);
+  return ok;
+}
+
+// Returns 1 on success.
+static int BackwardReferencesTraceBackwards(int xsize, int ysize,
+                                            const uint32_t* const argb,
+                                            int quality, int cache_bits,
+                                            VP8LHashChain* const hash_chain,
+                                            VP8LBackwardRefs* const refs) {
+  int ok = 0;
+  const int dist_array_size = xsize * ysize;
+  uint16_t* chosen_path = NULL;
+  int chosen_path_size = 0;
+  uint16_t* dist_array =
+      (uint16_t*)WebPSafeMalloc(dist_array_size, sizeof(*dist_array));
+
+  if (dist_array == NULL) goto Error;
+
+  if (!BackwardReferencesHashChainDistanceOnly(
+      xsize, ysize, argb, quality, cache_bits, hash_chain,
+      refs, dist_array)) {
+    goto Error;
+  }
+  TraceBackwards(dist_array, dist_array_size, &chosen_path, &chosen_path_size);
+  if (!BackwardReferencesHashChainFollowChosenPath(
+      xsize, ysize, argb, quality, cache_bits, chosen_path, chosen_path_size,
+      hash_chain, refs)) {
+    goto Error;
+  }
+  ok = 1;
+ Error:
+  WebPSafeFree(dist_array);
+  return ok;
+}
+
+static void BackwardReferences2DLocality(int xsize,
+                                         const VP8LBackwardRefs* const refs) {
+  VP8LRefsCursor c = VP8LRefsCursorInit(refs);
+  while (VP8LRefsCursorOk(&c)) {
+    if (PixOrCopyIsCopy(c.cur_pos)) {
+      const int dist = c.cur_pos->argb_or_distance;
+      const int transformed_dist = DistanceToPlaneCode(xsize, dist);
+      c.cur_pos->argb_or_distance = transformed_dist;
+    }
+    VP8LRefsCursorNext(&c);
+  }
+}
+
+// Returns entropy for the given cache bits.
+static double ComputeCacheEntropy(const uint32_t* const argb,
+                                  int xsize, int ysize,
+                                  const VP8LBackwardRefs* const refs,
+                                  int cache_bits) {
+  int pixel_index = 0;
+  uint32_t k;
+  const int use_color_cache = (cache_bits > 0);
+  int cc_init = 0;
+  double entropy = MAX_ENTROPY;
+  const double kSmallPenaltyForLargeCache = 4.0;
+  VP8LColorCache hashers;
+  VP8LRefsCursor c = VP8LRefsCursorInit(refs);
+  VP8LHistogram* histo = VP8LAllocateHistogram(cache_bits);
+  if (histo == NULL) goto Error;
+
+  if (use_color_cache) {
+    cc_init = VP8LColorCacheInit(&hashers, cache_bits);
+    if (!cc_init) goto Error;
+  }
+
+  while (VP8LRefsCursorOk(&c)) {
+    const PixOrCopy* const v = c.cur_pos;
+    if (PixOrCopyIsLiteral(v)) {
+      if (use_color_cache &&
+          VP8LColorCacheContains(&hashers, argb[pixel_index])) {
+        // push pixel as a cache index
+        const int ix = VP8LColorCacheGetIndex(&hashers, argb[pixel_index]);
+        const PixOrCopy token = PixOrCopyCreateCacheIdx(ix);
+        VP8LHistogramAddSinglePixOrCopy(histo, &token);
+      } else {
+        VP8LHistogramAddSinglePixOrCopy(histo, v);
+      }
+    } else {
+      VP8LHistogramAddSinglePixOrCopy(histo, v);
+    }
+    if (use_color_cache) {
+      for (k = 0; k < PixOrCopyLength(v); ++k) {
+        VP8LColorCacheInsert(&hashers, argb[pixel_index + k]);
+      }
+    }
+    pixel_index += PixOrCopyLength(v);
+    VP8LRefsCursorNext(&c);
+  }
+  assert(pixel_index == xsize * ysize);
+  (void)xsize;  // xsize is not used in non-debug compilations otherwise.
+  (void)ysize;  // ysize is not used in non-debug compilations otherwise.
+  entropy = VP8LHistogramEstimateBits(histo) +
+      kSmallPenaltyForLargeCache * cache_bits;
+ Error:
+  if (cc_init) VP8LColorCacheClear(&hashers);
+  VP8LFreeHistogram(histo);
+  return entropy;
+}
+
+// Evaluate optimal cache bits for the local color cache.
+// The input *best_cache_bits sets the maximum cache bits to use (passing 0
+// implies disabling the local color cache). The local color cache is also
+// disabled for the lower (<= 25) quality.
+// Returns 0 in case of memory error.
+static int CalculateBestCacheSize(const uint32_t* const argb,
+                                  int xsize, int ysize, int quality,
+                                  VP8LHashChain* const hash_chain,
+                                  VP8LBackwardRefs* const refs,
+                                  int* const lz77_computed,
+                                  int* const best_cache_bits) {
+  int eval_low = 1;
+  int eval_high = 1;
+  double entropy_low = MAX_ENTROPY;
+  double entropy_high = MAX_ENTROPY;
+  const double cost_mul = 5e-4;
+  int cache_bits_low = 0;
+  int cache_bits_high = (quality <= 25) ? 0 : *best_cache_bits;
+
+  assert(cache_bits_high <= MAX_COLOR_CACHE_BITS);
+
+  *lz77_computed = 0;
+  if (cache_bits_high == 0) {
+    *best_cache_bits = 0;
+    // Local color cache is disabled.
+    return 1;
+  }
+  if (!BackwardReferencesLz77(xsize, ysize, argb, cache_bits_low, quality, 0,
+                              hash_chain, refs)) {
+    return 0;
+  }
+  // Do a binary search to find the optimal entropy for cache_bits.
+  while (eval_low || eval_high) {
+    if (eval_low) {
+      entropy_low =
+          ComputeCacheEntropy(argb, xsize, ysize, refs, cache_bits_low);
+      entropy_low += entropy_low * cache_bits_low * cost_mul;
+      eval_low = 0;
+    }
+    if (eval_high) {
+      entropy_high =
+          ComputeCacheEntropy(argb, xsize, ysize, refs, cache_bits_high);
+      entropy_high += entropy_high * cache_bits_high * cost_mul;
+      eval_high = 0;
+    }
+    if (entropy_high < entropy_low) {
+      const int prev_cache_bits_low = cache_bits_low;
+      *best_cache_bits = cache_bits_high;
+      cache_bits_low = (cache_bits_low + cache_bits_high) / 2;
+      if (cache_bits_low != prev_cache_bits_low) eval_low = 1;
+    } else {
+      *best_cache_bits = cache_bits_low;
+      cache_bits_high = (cache_bits_low + cache_bits_high) / 2;
+      if (cache_bits_high != cache_bits_low) eval_high = 1;
+    }
+  }
+  *lz77_computed = 1;
+  return 1;
+}
+
+// Update (in-place) backward references for specified cache_bits.
+static int BackwardRefsWithLocalCache(const uint32_t* const argb,
+                                      int cache_bits,
+                                      VP8LBackwardRefs* const refs) {
+  int pixel_index = 0;
+  VP8LColorCache hashers;
+  VP8LRefsCursor c = VP8LRefsCursorInit(refs);
+  if (!VP8LColorCacheInit(&hashers, cache_bits)) return 0;
+
+  while (VP8LRefsCursorOk(&c)) {
+    PixOrCopy* const v = c.cur_pos;
+    if (PixOrCopyIsLiteral(v)) {
+      const uint32_t argb_literal = v->argb_or_distance;
+      if (VP8LColorCacheContains(&hashers, argb_literal)) {
+        const int ix = VP8LColorCacheGetIndex(&hashers, argb_literal);
+        *v = PixOrCopyCreateCacheIdx(ix);
+      } else {
+        VP8LColorCacheInsert(&hashers, argb_literal);
+      }
+      ++pixel_index;
+    } else {
+      // refs was created without local cache, so it can not have cache indexes.
+      int k;
+      assert(PixOrCopyIsCopy(v));
+      for (k = 0; k < v->len; ++k) {
+        VP8LColorCacheInsert(&hashers, argb[pixel_index++]);
+      }
+    }
+    VP8LRefsCursorNext(&c);
+  }
+  VP8LColorCacheClear(&hashers);
+  return 1;
+}
+
+static VP8LBackwardRefs* GetBackwardReferencesLowEffort(
+    int width, int height, const uint32_t* const argb, int quality,
+    int* const cache_bits, VP8LHashChain* const hash_chain,
+    VP8LBackwardRefs refs_array[2]) {
+  VP8LBackwardRefs* refs_lz77 = &refs_array[0];
+  *cache_bits = 0;
+  if (!BackwardReferencesLz77(width, height, argb, 0, quality,
+                              1 /* Low effort. */, hash_chain, refs_lz77)) {
+    return NULL;
+  }
+  BackwardReferences2DLocality(width, refs_lz77);
+  return refs_lz77;
+}
+
+static VP8LBackwardRefs* GetBackwardReferences(
+    int width, int height, const uint32_t* const argb, int quality,
+    int* const cache_bits, VP8LHashChain* const hash_chain,
+    VP8LBackwardRefs refs_array[2]) {
+  int lz77_is_useful;
+  int lz77_computed;
+  double bit_cost_lz77, bit_cost_rle;
+  VP8LBackwardRefs* best = NULL;
+  VP8LBackwardRefs* refs_lz77 = &refs_array[0];
+  VP8LBackwardRefs* refs_rle = &refs_array[1];
+  VP8LHistogram* histo = NULL;
+
+  if (!CalculateBestCacheSize(argb, width, height, quality, hash_chain,
+                              refs_lz77, &lz77_computed, cache_bits)) {
+    goto Error;
+  }
+
+  if (lz77_computed) {
+    // Transform refs_lz77 for the optimized cache_bits.
+    if (*cache_bits > 0) {
+      if (!BackwardRefsWithLocalCache(argb, *cache_bits, refs_lz77)) {
+        goto Error;
+      }
+    }
+  } else {
+    if (!BackwardReferencesLz77(width, height, argb, *cache_bits, quality,
+                                0 /* Low effort. */, hash_chain, refs_lz77)) {
+      goto Error;
+    }
+  }
+
+  if (!BackwardReferencesRle(width, height, argb, *cache_bits, refs_rle)) {
+    goto Error;
+  }
+
+  histo = VP8LAllocateHistogram(*cache_bits);
+  if (histo == NULL) goto Error;
+
+  {
+    // Evaluate LZ77 coding.
+    VP8LHistogramCreate(histo, refs_lz77, *cache_bits);
+    bit_cost_lz77 = VP8LHistogramEstimateBits(histo);
+    // Evaluate RLE coding.
+    VP8LHistogramCreate(histo, refs_rle, *cache_bits);
+    bit_cost_rle = VP8LHistogramEstimateBits(histo);
+    // Decide if LZ77 is useful.
+    lz77_is_useful = (bit_cost_lz77 < bit_cost_rle);
+  }
+
+  // Choose appropriate backward reference.
+  if (lz77_is_useful) {
+    // TraceBackwards is costly. Don't execute it at lower quality.
+    const int try_lz77_trace_backwards = (quality >= 25);
+    best = refs_lz77;   // default guess: lz77 is better
+    if (try_lz77_trace_backwards) {
+      VP8LBackwardRefs* const refs_trace = refs_rle;
+      if (!VP8LBackwardRefsCopy(refs_lz77, refs_trace)) {
+        best = NULL;
+        goto Error;
+      }
+      if (BackwardReferencesTraceBackwards(width, height, argb, quality,
+                                           *cache_bits, hash_chain,
+                                           refs_trace)) {
+        double bit_cost_trace;
+        // Evaluate LZ77 coding.
+        VP8LHistogramCreate(histo, refs_trace, *cache_bits);
+        bit_cost_trace = VP8LHistogramEstimateBits(histo);
+        if (bit_cost_trace < bit_cost_lz77) {
+          best = refs_trace;
+        }
+      }
+    }
+  } else {
+    best = refs_rle;
+  }
+
+  BackwardReferences2DLocality(width, best);
+
+ Error:
+  VP8LFreeHistogram(histo);
+  return best;
+}
+
+VP8LBackwardRefs* VP8LGetBackwardReferences(
+    int width, int height, const uint32_t* const argb, int quality,
+    int low_effort, int* const cache_bits, VP8LHashChain* const hash_chain,
+    VP8LBackwardRefs refs_array[2]) {
+  if (low_effort) {
+    return GetBackwardReferencesLowEffort(width, height, argb, quality,
+                                          cache_bits, hash_chain, refs_array);
+  } else {
+    return GetBackwardReferences(width, height, argb, quality, cache_bits,
+                                 hash_chain, refs_array);
+  }
+}
diff --git a/Source/LibWebP/src/enc/enc.config.c b/Source/LibWebP/src/enc/enc.config.c
new file mode 100644
index 0000000..e20edf2
--- /dev/null
+++ b/Source/LibWebP/src/enc/enc.config.c
@@ -0,0 +1,163 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Coding tools configuration
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include "../webp/encode.h"
+
+//------------------------------------------------------------------------------
+// WebPConfig
+//------------------------------------------------------------------------------
+
+int WebPConfigInitInternal(WebPConfig* config,
+                           WebPPreset preset, float quality, int version) {
+  if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_ENCODER_ABI_VERSION)) {
+    return 0;   // caller/system version mismatch!
+  }
+  if (config == NULL) return 0;
+
+  config->quality = quality;
+  config->target_size = 0;
+  config->target_PSNR = 0.;
+  config->method = 4;
+  config->sns_strength = 50;
+  config->filter_strength = 60;   // mid-filtering
+  config->filter_sharpness = 0;
+  config->filter_type = 1;        // default: strong (so U/V is filtered too)
+  config->partitions = 0;
+  config->segments = 4;
+  config->pass = 1;
+  config->show_compressed = 0;
+  config->preprocessing = 0;
+  config->autofilter = 0;
+  config->partition_limit = 0;
+  config->alpha_compression = 1;
+  config->alpha_filtering = 1;
+  config->alpha_quality = 100;
+  config->lossless = 0;
+  config->image_hint = WEBP_HINT_DEFAULT;
+  config->emulate_jpeg_size = 0;
+  config->thread_level = 0;
+  config->low_memory = 0;
+  config->near_lossless = 100;
+
+  // TODO(skal): tune.
+  switch (preset) {
+    case WEBP_PRESET_PICTURE:
+      config->sns_strength = 80;
+      config->filter_sharpness = 4;
+      config->filter_strength = 35;
+      config->preprocessing &= ~2;   // no dithering
+      break;
+    case WEBP_PRESET_PHOTO:
+      config->sns_strength = 80;
+      config->filter_sharpness = 3;
+      config->filter_strength = 30;
+      config->preprocessing |= 2;
+      break;
+    case WEBP_PRESET_DRAWING:
+      config->sns_strength = 25;
+      config->filter_sharpness = 6;
+      config->filter_strength = 10;
+      break;
+    case WEBP_PRESET_ICON:
+      config->sns_strength = 0;
+      config->filter_strength = 0;   // disable filtering to retain sharpness
+      config->preprocessing &= ~2;   // no dithering
+      break;
+    case WEBP_PRESET_TEXT:
+      config->sns_strength = 0;
+      config->filter_strength = 0;   // disable filtering to retain sharpness
+      config->preprocessing &= ~2;   // no dithering
+      config->segments = 2;
+      break;
+    case WEBP_PRESET_DEFAULT:
+    default:
+      break;
+  }
+  return WebPValidateConfig(config);
+}
+
+int WebPValidateConfig(const WebPConfig* config) {
+  if (config == NULL) return 0;
+  if (config->quality < 0 || config->quality > 100)
+    return 0;
+  if (config->target_size < 0)
+    return 0;
+  if (config->target_PSNR < 0)
+    return 0;
+  if (config->method < 0 || config->method > 6)
+    return 0;
+  if (config->segments < 1 || config->segments > 4)
+    return 0;
+  if (config->sns_strength < 0 || config->sns_strength > 100)
+    return 0;
+  if (config->filter_strength < 0 || config->filter_strength > 100)
+    return 0;
+  if (config->filter_sharpness < 0 || config->filter_sharpness > 7)
+    return 0;
+  if (config->filter_type < 0 || config->filter_type > 1)
+    return 0;
+  if (config->autofilter < 0 || config->autofilter > 1)
+    return 0;
+  if (config->pass < 1 || config->pass > 10)
+    return 0;
+  if (config->show_compressed < 0 || config->show_compressed > 1)
+    return 0;
+  if (config->preprocessing < 0 || config->preprocessing > 7)
+    return 0;
+  if (config->partitions < 0 || config->partitions > 3)
+    return 0;
+  if (config->partition_limit < 0 || config->partition_limit > 100)
+    return 0;
+  if (config->alpha_compression < 0)
+    return 0;
+  if (config->alpha_filtering < 0)
+    return 0;
+  if (config->alpha_quality < 0 || config->alpha_quality > 100)
+    return 0;
+  if (config->lossless < 0 || config->lossless > 1)
+    return 0;
+  if (config->near_lossless < 0 || config->near_lossless > 100)
+    return 0;
+  if (config->image_hint >= WEBP_HINT_LAST)
+    return 0;
+  if (config->emulate_jpeg_size < 0 || config->emulate_jpeg_size > 1)
+    return 0;
+  if (config->thread_level < 0 || config->thread_level > 1)
+    return 0;
+  if (config->low_memory < 0 || config->low_memory > 1)
+    return 0;
+  return 1;
+}
+
+//------------------------------------------------------------------------------
+
+#define MAX_LEVEL 9
+
+// Mapping between -z level and -m / -q parameter settings.
+static const struct {
+  uint8_t method_;
+  uint8_t quality_;
+} kLosslessPresets[MAX_LEVEL + 1] = {
+  { 0,  0 }, { 1, 20 }, { 2, 25 }, { 3, 30 }, { 3, 50 },
+  { 4, 50 }, { 4, 75 }, { 4, 90 }, { 5, 90 }, { 6, 100 }
+};
+
+int WebPConfigLosslessPreset(WebPConfig* config, int level) {
+  if (config == NULL || level < 0 || level > MAX_LEVEL) return 0;
+  config->lossless = 1;
+  config->method = kLosslessPresets[level].method_;
+  config->quality = kLosslessPresets[level].quality_;
+  return 1;
+}
+
+//------------------------------------------------------------------------------
diff --git a/Source/LibWebP/src/enc/enc.cost.c b/Source/LibWebP/src/enc/enc.cost.c
new file mode 100644
index 0000000..1b16543
--- /dev/null
+++ b/Source/LibWebP/src/enc/enc.cost.c
@@ -0,0 +1,355 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Cost tables for level and modes
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include "./cost.h"
+
+//------------------------------------------------------------------------------
+// Level cost tables
+
+// For each given level, the following table gives the pattern of contexts to
+// use for coding it (in [][0]) as well as the bit value to use for each
+// context (in [][1]).
+const uint16_t VP8LevelCodes[MAX_VARIABLE_LEVEL][2] = {
+                  {0x001, 0x000}, {0x007, 0x001}, {0x00f, 0x005},
+  {0x00f, 0x00d}, {0x033, 0x003}, {0x033, 0x003}, {0x033, 0x023},
+  {0x033, 0x023}, {0x033, 0x023}, {0x033, 0x023}, {0x0d3, 0x013},
+  {0x0d3, 0x013}, {0x0d3, 0x013}, {0x0d3, 0x013}, {0x0d3, 0x013},
+  {0x0d3, 0x013}, {0x0d3, 0x013}, {0x0d3, 0x013}, {0x0d3, 0x093},
+  {0x0d3, 0x093}, {0x0d3, 0x093}, {0x0d3, 0x093}, {0x0d3, 0x093},
+  {0x0d3, 0x093}, {0x0d3, 0x093}, {0x0d3, 0x093}, {0x0d3, 0x093},
+  {0x0d3, 0x093}, {0x0d3, 0x093}, {0x0d3, 0x093}, {0x0d3, 0x093},
+  {0x0d3, 0x093}, {0x0d3, 0x093}, {0x0d3, 0x093}, {0x153, 0x053},
+  {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053},
+  {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053},
+  {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053},
+  {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053},
+  {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053},
+  {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053},
+  {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053},
+  {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x153}
+};
+
+static int VariableLevelCost(int level, const uint8_t probas[NUM_PROBAS]) {
+  int pattern = VP8LevelCodes[level - 1][0];
+  int bits = VP8LevelCodes[level - 1][1];
+  int cost = 0;
+  int i;
+  for (i = 2; pattern; ++i) {
+    if (pattern & 1) {
+      cost += VP8BitCost(bits & 1, probas[i]);
+    }
+    bits >>= 1;
+    pattern >>= 1;
+  }
+  return cost;
+}
+
+//------------------------------------------------------------------------------
+// Pre-calc level costs once for all
+
+void VP8CalculateLevelCosts(VP8Proba* const proba) {
+  int ctype, band, ctx;
+
+  if (!proba->dirty_) return;  // nothing to do.
+
+  for (ctype = 0; ctype < NUM_TYPES; ++ctype) {
+    int n;
+    for (band = 0; band < NUM_BANDS; ++band) {
+      for (ctx = 0; ctx < NUM_CTX; ++ctx) {
+        const uint8_t* const p = proba->coeffs_[ctype][band][ctx];
+        uint16_t* const table = proba->level_cost_[ctype][band][ctx];
+        const int cost0 = (ctx > 0) ? VP8BitCost(1, p[0]) : 0;
+        const int cost_base = VP8BitCost(1, p[1]) + cost0;
+        int v;
+        table[0] = VP8BitCost(0, p[1]) + cost0;
+        for (v = 1; v <= MAX_VARIABLE_LEVEL; ++v) {
+          table[v] = cost_base + VariableLevelCost(v, p);
+        }
+        // Starting at level 67 and up, the variable part of the cost is
+        // actually constant.
+      }
+    }
+    for (n = 0; n < 16; ++n) {    // replicate bands. We don't need to sentinel.
+      for (ctx = 0; ctx < NUM_CTX; ++ctx) {
+        proba->remapped_costs_[ctype][n][ctx] =
+            proba->level_cost_[ctype][VP8EncBands[n]][ctx];
+      }
+    }
+  }
+  proba->dirty_ = 0;
+}
+
+//------------------------------------------------------------------------------
+// Mode cost tables.
+
+// These are the fixed probabilities (in the coding trees) turned into bit-cost
+// by calling VP8BitCost().
+const uint16_t VP8FixedCostsUV[4] = { 302, 984, 439, 642 };
+// note: these values include the fixed VP8BitCost(1, 145) mode selection cost.
+const uint16_t VP8FixedCostsI16[4] = { 663, 919, 872, 919 };
+const uint16_t VP8FixedCostsI4[NUM_BMODES][NUM_BMODES][NUM_BMODES] = {
+  { {   40, 1151, 1723, 1874, 2103, 2019, 1628, 1777, 2226, 2137 },
+    {  192,  469, 1296, 1308, 1849, 1794, 1781, 1703, 1713, 1522 },
+    {  142,  910,  762, 1684, 1849, 1576, 1460, 1305, 1801, 1657 },
+    {  559,  641, 1370,  421, 1182, 1569, 1612, 1725,  863, 1007 },
+    {  299, 1059, 1256, 1108,  636, 1068, 1581, 1883,  869, 1142 },
+    {  277, 1111,  707, 1362, 1089,  672, 1603, 1541, 1545, 1291 },
+    {  214,  781, 1609, 1303, 1632, 2229,  726, 1560, 1713,  918 },
+    {  152, 1037, 1046, 1759, 1983, 2174, 1358,  742, 1740, 1390 },
+    {  512, 1046, 1420,  753,  752, 1297, 1486, 1613,  460, 1207 },
+    {  424,  827, 1362,  719, 1462, 1202, 1199, 1476, 1199,  538 } },
+  { {  240,  402, 1134, 1491, 1659, 1505, 1517, 1555, 1979, 2099 },
+    {  467,  242,  960, 1232, 1714, 1620, 1834, 1570, 1676, 1391 },
+    {  500,  455,  463, 1507, 1699, 1282, 1564,  982, 2114, 2114 },
+    {  672,  643, 1372,  331, 1589, 1667, 1453, 1938,  996,  876 },
+    {  458,  783, 1037,  911,  738,  968, 1165, 1518,  859, 1033 },
+    {  504,  815,  504, 1139, 1219,  719, 1506, 1085, 1268, 1268 },
+    {  333,  630, 1445, 1239, 1883, 3672,  799, 1548, 1865,  598 },
+    {  399,  644,  746, 1342, 1856, 1350, 1493,  613, 1855, 1015 },
+    {  622,  749, 1205,  608, 1066, 1408, 1290, 1406,  546,  971 },
+    {  500,  753, 1041,  668, 1230, 1617, 1297, 1425, 1383,  523 } },
+  { {  394,  553,  523, 1502, 1536,  981, 1608, 1142, 1666, 2181 },
+    {  655,  430,  375, 1411, 1861, 1220, 1677, 1135, 1978, 1553 },
+    {  690,  640,  245, 1954, 2070, 1194, 1528,  982, 1972, 2232 },
+    {  559,  834,  741,  867, 1131,  980, 1225,  852, 1092,  784 },
+    {  690,  875,  516,  959,  673,  894, 1056, 1190, 1528, 1126 },
+    {  740,  951,  384, 1277, 1177,  492, 1579, 1155, 1846, 1513 },
+    {  323,  775, 1062, 1776, 3062, 1274,  813, 1188, 1372,  655 },
+    {  488,  971,  484, 1767, 1515, 1775, 1115,  503, 1539, 1461 },
+    {  740, 1006,  998,  709,  851, 1230, 1337,  788,  741,  721 },
+    {  522, 1073,  573, 1045, 1346,  887, 1046, 1146, 1203,  697 } },
+  { {  105,  864, 1442, 1009, 1934, 1840, 1519, 1920, 1673, 1579 },
+    {  534,  305, 1193,  683, 1388, 2164, 1802, 1894, 1264, 1170 },
+    {  305,  518,  877, 1108, 1426, 3215, 1425, 1064, 1320, 1242 },
+    {  683,  732, 1927,  257, 1493, 2048, 1858, 1552, 1055,  947 },
+    {  394,  814, 1024,  660,  959, 1556, 1282, 1289,  893, 1047 },
+    {  528,  615,  996,  940, 1201,  635, 1094, 2515,  803, 1358 },
+    {  347,  614, 1609, 1187, 3133, 1345, 1007, 1339, 1017,  667 },
+    {  218,  740,  878, 1605, 3650, 3650, 1345,  758, 1357, 1617 },
+    {  672,  750, 1541,  558, 1257, 1599, 1870, 2135,  402, 1087 },
+    {  592,  684, 1161,  430, 1092, 1497, 1475, 1489, 1095,  822 } },
+  { {  228, 1056, 1059, 1368,  752,  982, 1512, 1518,  987, 1782 },
+    {  494,  514,  818,  942,  965,  892, 1610, 1356, 1048, 1363 },
+    {  512,  648,  591, 1042,  761,  991, 1196, 1454, 1309, 1463 },
+    {  683,  749, 1043,  676,  841, 1396, 1133, 1138,  654,  939 },
+    {  622, 1101, 1126,  994,  361, 1077, 1203, 1318,  877, 1219 },
+    {  631, 1068,  857, 1650,  651,  477, 1650, 1419,  828, 1170 },
+    {  555,  727, 1068, 1335, 3127, 1339,  820, 1331, 1077,  429 },
+    {  504,  879,  624, 1398,  889,  889, 1392,  808,  891, 1406 },
+    {  683, 1602, 1289,  977,  578,  983, 1280, 1708,  406, 1122 },
+    {  399,  865, 1433, 1070, 1072,  764,  968, 1477, 1223,  678 } },
+  { {  333,  760,  935, 1638, 1010,  529, 1646, 1410, 1472, 2219 },
+    {  512,  494,  750, 1160, 1215,  610, 1870, 1868, 1628, 1169 },
+    {  572,  646,  492, 1934, 1208,  603, 1580, 1099, 1398, 1995 },
+    {  786,  789,  942,  581, 1018,  951, 1599, 1207,  731,  768 },
+    {  690, 1015,  672, 1078,  582,  504, 1693, 1438, 1108, 2897 },
+    {  768, 1267,  571, 2005, 1243,  244, 2881, 1380, 1786, 1453 },
+    {  452,  899, 1293,  903, 1311, 3100,  465, 1311, 1319,  813 },
+    {  394,  927,  942, 1103, 1358, 1104,  946,  593, 1363, 1109 },
+    {  559, 1005, 1007, 1016,  658, 1173, 1021, 1164,  623, 1028 },
+    {  564,  796,  632, 1005, 1014,  863, 2316, 1268,  938,  764 } },
+  { {  266,  606, 1098, 1228, 1497, 1243,  948, 1030, 1734, 1461 },
+    {  366,  585,  901, 1060, 1407, 1247,  876, 1134, 1620, 1054 },
+    {  452,  565,  542, 1729, 1479, 1479, 1016,  886, 2938, 1150 },
+    {  555, 1088, 1533,  950, 1354,  895,  834, 1019, 1021,  496 },
+    {  704,  815, 1193,  971,  973,  640, 1217, 2214,  832,  578 },
+    {  672, 1245,  579,  871,  875,  774,  872, 1273, 1027,  949 },
+    {  296, 1134, 2050, 1784, 1636, 3425,  442, 1550, 2076,  722 },
+    {  342,  982, 1259, 1846, 1848, 1848,  622,  568, 1847, 1052 },
+    {  555, 1064, 1304,  828,  746, 1343, 1075, 1329, 1078,  494 },
+    {  288, 1167, 1285, 1174, 1639, 1639,  833, 2254, 1304,  509 } },
+  { {  342,  719,  767, 1866, 1757, 1270, 1246,  550, 1746, 2151 },
+    {  483,  653,  694, 1509, 1459, 1410, 1218,  507, 1914, 1266 },
+    {  488,  757,  447, 2979, 1813, 1268, 1654,  539, 1849, 2109 },
+    {  522, 1097, 1085,  851, 1365, 1111,  851,  901,  961,  605 },
+    {  709,  716,  841,  728,  736,  945,  941,  862, 2845, 1057 },
+    {  512, 1323,  500, 1336, 1083,  681, 1342,  717, 1604, 1350 },
+    {  452, 1155, 1372, 1900, 1501, 3290,  311,  944, 1919,  922 },
+    {  403, 1520,  977, 2132, 1733, 3522, 1076,  276, 3335, 1547 },
+    {  559, 1374, 1101,  615,  673, 2462,  974,  795,  984,  984 },
+    {  547, 1122, 1062,  812, 1410,  951, 1140,  622, 1268,  651 } },
+  { {  165,  982, 1235,  938, 1334, 1366, 1659, 1578,  964, 1612 },
+    {  592,  422,  925,  847, 1139, 1112, 1387, 2036,  861, 1041 },
+    {  403,  837,  732,  770,  941, 1658, 1250,  809, 1407, 1407 },
+    {  896,  874, 1071,  381, 1568, 1722, 1437, 2192,  480, 1035 },
+    {  640, 1098, 1012, 1032,  684, 1382, 1581, 2106,  416,  865 },
+    {  559, 1005,  819,  914,  710,  770, 1418,  920,  838, 1435 },
+    {  415, 1258, 1245,  870, 1278, 3067,  770, 1021, 1287,  522 },
+    {  406,  990,  601, 1009, 1265, 1265, 1267,  759, 1017, 1277 },
+    {  968, 1182, 1329,  788, 1032, 1292, 1705, 1714,  203, 1403 },
+    {  732,  877, 1279,  471,  901, 1161, 1545, 1294,  755,  755 } },
+  { {  111,  931, 1378, 1185, 1933, 1648, 1148, 1714, 1873, 1307 },
+    {  406,  414, 1030, 1023, 1910, 1404, 1313, 1647, 1509,  793 },
+    {  342,  640,  575, 1088, 1241, 1349, 1161, 1350, 1756, 1502 },
+    {  559,  766, 1185,  357, 1682, 1428, 1329, 1897, 1219,  802 },
+    {  473,  909, 1164,  771,  719, 2508, 1427, 1432,  722,  782 },
+    {  342,  892,  785, 1145, 1150,  794, 1296, 1550,  973, 1057 },
+    {  208, 1036, 1326, 1343, 1606, 3395,  815, 1455, 1618,  712 },
+    {  228,  928,  890, 1046, 3499, 1711,  994,  829, 1720, 1318 },
+    {  768,  724, 1058,  636,  991, 1075, 1319, 1324,  616,  825 },
+    {  305, 1167, 1358,  899, 1587, 1587,  987, 1988, 1332,  501 } }
+};
+
+//------------------------------------------------------------------------------
+// helper functions for residuals struct VP8Residual.
+
+void VP8InitResidual(int first, int coeff_type,
+                     VP8Encoder* const enc, VP8Residual* const res) {
+  res->coeff_type = coeff_type;
+  res->prob  = enc->proba_.coeffs_[coeff_type];
+  res->stats = enc->proba_.stats_[coeff_type];
+  res->cost  = enc->proba_.level_cost_[coeff_type];
+  res->costs = enc->proba_.remapped_costs_[coeff_type];
+  res->first = first;
+}
+
+//------------------------------------------------------------------------------
+// Mode costs
+
+int VP8GetCostLuma4(VP8EncIterator* const it, const int16_t levels[16]) {
+  const int x = (it->i4_ & 3), y = (it->i4_ >> 2);
+  VP8Residual res;
+  VP8Encoder* const enc = it->enc_;
+  int R = 0;
+  int ctx;
+
+  VP8InitResidual(0, 3, enc, &res);
+  ctx = it->top_nz_[x] + it->left_nz_[y];
+  VP8SetResidualCoeffs(levels, &res);
+  R += VP8GetResidualCost(ctx, &res);
+  return R;
+}
+
+int VP8GetCostLuma16(VP8EncIterator* const it, const VP8ModeScore* const rd) {
+  VP8Residual res;
+  VP8Encoder* const enc = it->enc_;
+  int x, y;
+  int R = 0;
+
+  VP8IteratorNzToBytes(it);   // re-import the non-zero context
+
+  // DC
+  VP8InitResidual(0, 1, enc, &res);
+  VP8SetResidualCoeffs(rd->y_dc_levels, &res);
+  R += VP8GetResidualCost(it->top_nz_[8] + it->left_nz_[8], &res);
+
+  // AC
+  VP8InitResidual(1, 0, enc, &res);
+  for (y = 0; y < 4; ++y) {
+    for (x = 0; x < 4; ++x) {
+      const int ctx = it->top_nz_[x] + it->left_nz_[y];
+      VP8SetResidualCoeffs(rd->y_ac_levels[x + y * 4], &res);
+      R += VP8GetResidualCost(ctx, &res);
+      it->top_nz_[x] = it->left_nz_[y] = (res.last >= 0);
+    }
+  }
+  return R;
+}
+
+int VP8GetCostUV(VP8EncIterator* const it, const VP8ModeScore* const rd) {
+  VP8Residual res;
+  VP8Encoder* const enc = it->enc_;
+  int ch, x, y;
+  int R = 0;
+
+  VP8IteratorNzToBytes(it);  // re-import the non-zero context
+
+  VP8InitResidual(0, 2, enc, &res);
+  for (ch = 0; ch <= 2; ch += 2) {
+    for (y = 0; y < 2; ++y) {
+      for (x = 0; x < 2; ++x) {
+        const int ctx = it->top_nz_[4 + ch + x] + it->left_nz_[4 + ch + y];
+        VP8SetResidualCoeffs(rd->uv_levels[ch * 2 + x + y * 2], &res);
+        R += VP8GetResidualCost(ctx, &res);
+        it->top_nz_[4 + ch + x] = it->left_nz_[4 + ch + y] = (res.last >= 0);
+      }
+    }
+  }
+  return R;
+}
+
+
+//------------------------------------------------------------------------------
+// Recording of token probabilities.
+
+// Record proba context used
+static int Record(int bit, proba_t* const stats) {
+  proba_t p = *stats;
+  if (p >= 0xffff0000u) {               // an overflow is inbound.
+    p = ((p + 1u) >> 1) & 0x7fff7fffu;  // -> divide the stats by 2.
+  }
+  // record bit count (lower 16 bits) and increment total count (upper 16 bits).
+  p += 0x00010000u + bit;
+  *stats = p;
+  return bit;
+}
+
+// We keep the table-free variant around for reference, in case.
+#define USE_LEVEL_CODE_TABLE
+
+// Simulate block coding, but only record statistics.
+// Note: no need to record the fixed probas.
+int VP8RecordCoeffs(int ctx, const VP8Residual* const res) {
+  int n = res->first;
+  // should be stats[VP8EncBands[n]], but it's equivalent for n=0 or 1
+  proba_t* s = res->stats[n][ctx];
+  if (res->last  < 0) {
+    Record(0, s + 0);
+    return 0;
+  }
+  while (n <= res->last) {
+    int v;
+    Record(1, s + 0);  // order of record doesn't matter
+    while ((v = res->coeffs[n++]) == 0) {
+      Record(0, s + 1);
+      s = res->stats[VP8EncBands[n]][0];
+    }
+    Record(1, s + 1);
+    if (!Record(2u < (unsigned int)(v + 1), s + 2)) {  // v = -1 or 1
+      s = res->stats[VP8EncBands[n]][1];
+    } else {
+      v = abs(v);
+#if !defined(USE_LEVEL_CODE_TABLE)
+      if (!Record(v > 4, s + 3)) {
+        if (Record(v != 2, s + 4))
+          Record(v == 4, s + 5);
+      } else if (!Record(v > 10, s + 6)) {
+        Record(v > 6, s + 7);
+      } else if (!Record((v >= 3 + (8 << 2)), s + 8)) {
+        Record((v >= 3 + (8 << 1)), s + 9);
+      } else {
+        Record((v >= 3 + (8 << 3)), s + 10);
+      }
+#else
+      if (v > MAX_VARIABLE_LEVEL) {
+        v = MAX_VARIABLE_LEVEL;
+      }
+
+      {
+        const int bits = VP8LevelCodes[v - 1][1];
+        int pattern = VP8LevelCodes[v - 1][0];
+        int i;
+        for (i = 0; (pattern >>= 1) != 0; ++i) {
+          const int mask = 2 << i;
+          if (pattern & 1) Record(!!(bits & mask), s + 3 + i);
+        }
+      }
+#endif
+      s = res->stats[VP8EncBands[n]][2];
+    }
+  }
+  if (n < 16) Record(0, s + 0);
+  return 1;
+}
+
+//------------------------------------------------------------------------------
diff --git a/Source/LibWebP/src/enc/enc.filter.c b/Source/LibWebP/src/enc/enc.filter.c
new file mode 100644
index 0000000..d4885ff
--- /dev/null
+++ b/Source/LibWebP/src/enc/enc.filter.c
@@ -0,0 +1,296 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Selecting filter level
+//
+// Author: somnath at google.com (Somnath Banerjee)
+
+#include <assert.h>
+#include "./vp8enci.h"
+#include "../dsp/dsp.h"
+
+// This table gives, for a given sharpness, the filtering strength to be
+// used (at least) in order to filter a given edge step delta.
+// This is constructed by brute force inspection: for all delta, we iterate
+// over all possible filtering strength / thresh until needs_filter() returns
+// true.
+#define MAX_DELTA_SIZE 64
+static const uint8_t kLevelsFromDelta[8][MAX_DELTA_SIZE] = {
+  { 0,   1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
+    16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+    32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63 },
+  { 0,  1,  2,  3,  5,  6,  7,  8,  9, 11, 12, 13, 14, 15, 17, 18,
+    20, 21, 23, 24, 26, 27, 29, 30, 32, 33, 35, 36, 38, 39, 41, 42,
+    44, 45, 47, 48, 50, 51, 53, 54, 56, 57, 59, 60, 62, 63, 63, 63,
+    63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63 },
+  {  0,  1,  2,  3,  5,  6,  7,  8,  9, 11, 12, 13, 14, 16, 17, 19,
+    20, 22, 23, 25, 26, 28, 29, 31, 32, 34, 35, 37, 38, 40, 41, 43,
+    44, 46, 47, 49, 50, 52, 53, 55, 56, 58, 59, 61, 62, 63, 63, 63,
+    63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63 },
+  {  0,  1,  2,  3,  5,  6,  7,  8,  9, 11, 12, 13, 15, 16, 18, 19,
+    21, 22, 24, 25, 27, 28, 30, 31, 33, 34, 36, 37, 39, 40, 42, 43,
+    45, 46, 48, 49, 51, 52, 54, 55, 57, 58, 60, 61, 63, 63, 63, 63,
+    63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63 },
+  {  0,  1,  2,  3,  5,  6,  7,  8,  9, 11, 12, 14, 15, 17, 18, 20,
+    21, 23, 24, 26, 27, 29, 30, 32, 33, 35, 36, 38, 39, 41, 42, 44,
+    45, 47, 48, 50, 51, 53, 54, 56, 57, 59, 60, 62, 63, 63, 63, 63,
+    63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63 },
+  {  0,  1,  2,  4,  5,  7,  8,  9, 11, 12, 13, 15, 16, 17, 19, 20,
+    22, 23, 25, 26, 28, 29, 31, 32, 34, 35, 37, 38, 40, 41, 43, 44,
+    46, 47, 49, 50, 52, 53, 55, 56, 58, 59, 61, 62, 63, 63, 63, 63,
+    63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63 },
+  {  0,  1,  2,  4,  5,  7,  8,  9, 11, 12, 13, 15, 16, 18, 19, 21,
+    22, 24, 25, 27, 28, 30, 31, 33, 34, 36, 37, 39, 40, 42, 43, 45,
+    46, 48, 49, 51, 52, 54, 55, 57, 58, 60, 61, 63, 63, 63, 63, 63,
+    63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63 },
+  {  0,  1,  2,  4,  5,  7,  8,  9, 11, 12, 14, 15, 17, 18, 20, 21,
+    23, 24, 26, 27, 29, 30, 32, 33, 35, 36, 38, 39, 41, 42, 44, 45,
+    47, 48, 50, 51, 53, 54, 56, 57, 59, 60, 62, 63, 63, 63, 63, 63,
+    63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63 }
+};
+
+int VP8FilterStrengthFromDelta(int sharpness, int delta) {
+  const int pos = (delta < MAX_DELTA_SIZE) ? delta : MAX_DELTA_SIZE - 1;
+  assert(sharpness >= 0 && sharpness <= 7);
+  return kLevelsFromDelta[sharpness][pos];
+}
+
+//------------------------------------------------------------------------------
+// Paragraph 15.4: compute the inner-edge filtering strength
+
+static int GetILevel(int sharpness, int level) {
+  if (sharpness > 0) {
+    if (sharpness > 4) {
+      level >>= 2;
+    } else {
+      level >>= 1;
+    }
+    if (level > 9 - sharpness) {
+      level = 9 - sharpness;
+    }
+  }
+  if (level < 1) level = 1;
+  return level;
+}
+
+static void DoFilter(const VP8EncIterator* const it, int level) {
+  const VP8Encoder* const enc = it->enc_;
+  const int ilevel = GetILevel(enc->config_->filter_sharpness, level);
+  const int limit = 2 * level + ilevel;
+
+  uint8_t* const y_dst = it->yuv_out2_ + Y_OFF;
+  uint8_t* const u_dst = it->yuv_out2_ + U_OFF;
+  uint8_t* const v_dst = it->yuv_out2_ + V_OFF;
+
+  // copy current block to yuv_out2_
+  memcpy(y_dst, it->yuv_out_, YUV_SIZE * sizeof(uint8_t));
+
+  if (enc->filter_hdr_.simple_ == 1) {   // simple
+    VP8SimpleHFilter16i(y_dst, BPS, limit);
+    VP8SimpleVFilter16i(y_dst, BPS, limit);
+  } else {    // complex
+    const int hev_thresh = (level >= 40) ? 2 : (level >= 15) ? 1 : 0;
+    VP8HFilter16i(y_dst, BPS, limit, ilevel, hev_thresh);
+    VP8HFilter8i(u_dst, v_dst, BPS, limit, ilevel, hev_thresh);
+    VP8VFilter16i(y_dst, BPS, limit, ilevel, hev_thresh);
+    VP8VFilter8i(u_dst, v_dst, BPS, limit, ilevel, hev_thresh);
+  }
+}
+
+//------------------------------------------------------------------------------
+// SSIM metric
+
+enum { KERNEL = 3 };
+static const double kMinValue = 1.e-10;  // minimal threshold
+
+void VP8SSIMAddStats(const DistoStats* const src, DistoStats* const dst) {
+  dst->w   += src->w;
+  dst->xm  += src->xm;
+  dst->ym  += src->ym;
+  dst->xxm += src->xxm;
+  dst->xym += src->xym;
+  dst->yym += src->yym;
+}
+
+static void VP8SSIMAccumulate(const uint8_t* src1, int stride1,
+                              const uint8_t* src2, int stride2,
+                              int xo, int yo, int W, int H,
+                              DistoStats* const stats) {
+  const int ymin = (yo - KERNEL < 0) ? 0 : yo - KERNEL;
+  const int ymax = (yo + KERNEL > H - 1) ? H - 1 : yo + KERNEL;
+  const int xmin = (xo - KERNEL < 0) ? 0 : xo - KERNEL;
+  const int xmax = (xo + KERNEL > W - 1) ? W - 1 : xo + KERNEL;
+  int x, y;
+  src1 += ymin * stride1;
+  src2 += ymin * stride2;
+  for (y = ymin; y <= ymax; ++y, src1 += stride1, src2 += stride2) {
+    for (x = xmin; x <= xmax; ++x) {
+      const int s1 = src1[x];
+      const int s2 = src2[x];
+      stats->w   += 1;
+      stats->xm  += s1;
+      stats->ym  += s2;
+      stats->xxm += s1 * s1;
+      stats->xym += s1 * s2;
+      stats->yym += s2 * s2;
+    }
+  }
+}
+
+double VP8SSIMGet(const DistoStats* const stats) {
+  const double xmxm = stats->xm * stats->xm;
+  const double ymym = stats->ym * stats->ym;
+  const double xmym = stats->xm * stats->ym;
+  const double w2 = stats->w * stats->w;
+  double sxx = stats->xxm * stats->w - xmxm;
+  double syy = stats->yym * stats->w - ymym;
+  double sxy = stats->xym * stats->w - xmym;
+  double C1, C2;
+  double fnum;
+  double fden;
+  // small errors are possible, due to rounding. Clamp to zero.
+  if (sxx < 0.) sxx = 0.;
+  if (syy < 0.) syy = 0.;
+  C1 = 6.5025 * w2;
+  C2 = 58.5225 * w2;
+  fnum = (2 * xmym + C1) * (2 * sxy + C2);
+  fden = (xmxm + ymym + C1) * (sxx + syy + C2);
+  return (fden != 0.) ? fnum / fden : kMinValue;
+}
+
+double VP8SSIMGetSquaredError(const DistoStats* const s) {
+  if (s->w > 0.) {
+    const double iw2 = 1. / (s->w * s->w);
+    const double sxx = s->xxm * s->w - s->xm * s->xm;
+    const double syy = s->yym * s->w - s->ym * s->ym;
+    const double sxy = s->xym * s->w - s->xm * s->ym;
+    const double SSE = iw2 * (sxx + syy - 2. * sxy);
+    if (SSE > kMinValue) return SSE;
+  }
+  return kMinValue;
+}
+
+void VP8SSIMAccumulatePlane(const uint8_t* src1, int stride1,
+                            const uint8_t* src2, int stride2,
+                            int W, int H, DistoStats* const stats) {
+  int x, y;
+  for (y = 0; y < H; ++y) {
+    for (x = 0; x < W; ++x) {
+      VP8SSIMAccumulate(src1, stride1, src2, stride2, x, y, W, H, stats);
+    }
+  }
+}
+
+static double GetMBSSIM(const uint8_t* yuv1, const uint8_t* yuv2) {
+  int x, y;
+  DistoStats s = { .0, .0, .0, .0, .0, .0 };
+
+  // compute SSIM in a 10 x 10 window
+  for (x = 3; x < 13; x++) {
+    for (y = 3; y < 13; y++) {
+      VP8SSIMAccumulate(yuv1 + Y_OFF, BPS, yuv2 + Y_OFF, BPS, x, y, 16, 16, &s);
+    }
+  }
+  for (x = 1; x < 7; x++) {
+    for (y = 1; y < 7; y++) {
+      VP8SSIMAccumulate(yuv1 + U_OFF, BPS, yuv2 + U_OFF, BPS, x, y, 8, 8, &s);
+      VP8SSIMAccumulate(yuv1 + V_OFF, BPS, yuv2 + V_OFF, BPS, x, y, 8, 8, &s);
+    }
+  }
+  return VP8SSIMGet(&s);
+}
+
+//------------------------------------------------------------------------------
+// Exposed APIs: Encoder should call the following 3 functions to adjust
+// loop filter strength
+
+void VP8InitFilter(VP8EncIterator* const it) {
+  if (it->lf_stats_ != NULL) {
+    int s, i;
+    for (s = 0; s < NUM_MB_SEGMENTS; s++) {
+      for (i = 0; i < MAX_LF_LEVELS; i++) {
+        (*it->lf_stats_)[s][i] = 0;
+      }
+    }
+  }
+}
+
+void VP8StoreFilterStats(VP8EncIterator* const it) {
+  int d;
+  VP8Encoder* const enc = it->enc_;
+  const int s = it->mb_->segment_;
+  const int level0 = enc->dqm_[s].fstrength_;  // TODO: ref_lf_delta[]
+
+  // explore +/-quant range of values around level0
+  const int delta_min = -enc->dqm_[s].quant_;
+  const int delta_max = enc->dqm_[s].quant_;
+  const int step_size = (delta_max - delta_min >= 4) ? 4 : 1;
+
+  if (it->lf_stats_ == NULL) return;
+
+  // NOTE: Currently we are applying filter only across the sublock edges
+  // There are two reasons for that.
+  // 1. Applying filter on macro block edges will change the pixels in
+  // the left and top macro blocks. That will be hard to restore
+  // 2. Macro Blocks on the bottom and right are not yet compressed. So we
+  // cannot apply filter on the right and bottom macro block edges.
+  if (it->mb_->type_ == 1 && it->mb_->skip_) return;
+
+  // Always try filter level  zero
+  (*it->lf_stats_)[s][0] += GetMBSSIM(it->yuv_in_, it->yuv_out_);
+
+  for (d = delta_min; d <= delta_max; d += step_size) {
+    const int level = level0 + d;
+    if (level <= 0 || level >= MAX_LF_LEVELS) {
+      continue;
+    }
+    DoFilter(it, level);
+    (*it->lf_stats_)[s][level] += GetMBSSIM(it->yuv_in_, it->yuv_out2_);
+  }
+}
+
+void VP8AdjustFilterStrength(VP8EncIterator* const it) {
+  VP8Encoder* const enc = it->enc_;
+  if (it->lf_stats_ != NULL) {
+    int s;
+    for (s = 0; s < NUM_MB_SEGMENTS; s++) {
+      int i, best_level = 0;
+      // Improvement over filter level 0 should be at least 1e-5 (relatively)
+      double best_v = 1.00001 * (*it->lf_stats_)[s][0];
+      for (i = 1; i < MAX_LF_LEVELS; i++) {
+        const double v = (*it->lf_stats_)[s][i];
+        if (v > best_v) {
+          best_v = v;
+          best_level = i;
+        }
+      }
+      enc->dqm_[s].fstrength_ = best_level;
+    }
+  } else if (enc->config_->filter_strength > 0) {
+    int max_level = 0;
+    int s;
+    for (s = 0; s < NUM_MB_SEGMENTS; s++) {
+      VP8SegmentInfo* const dqm = &enc->dqm_[s];
+      // this '>> 3' accounts for some inverse WHT scaling
+      const int delta = (dqm->max_edge_ * dqm->y2_.q_[1]) >> 3;
+      const int level =
+          VP8FilterStrengthFromDelta(enc->filter_hdr_.sharpness_, delta);
+      if (level > dqm->fstrength_) {
+        dqm->fstrength_ = level;
+      }
+      if (max_level < dqm->fstrength_) {
+        max_level = dqm->fstrength_;
+      }
+    }
+    enc->filter_hdr_.level_ = max_level;
+  }
+}
+
+// -----------------------------------------------------------------------------
diff --git a/Source/LibWebP/src/enc/enc.frame.c b/Source/LibWebP/src/enc/enc.frame.c
new file mode 100644
index 0000000..686c768
--- /dev/null
+++ b/Source/LibWebP/src/enc/enc.frame.c
@@ -0,0 +1,850 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+//   frame coding and analysis
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include <string.h>
+#include <math.h>
+
+#include "./cost.h"
+#include "./vp8enci.h"
+#include "../dsp/dsp.h"
+#include "../webp/format_constants.h"  // RIFF constants
+
+#define SEGMENT_VISU 0
+#define DEBUG_SEARCH 0    // useful to track search convergence
+
+//------------------------------------------------------------------------------
+// multi-pass convergence
+
+#define HEADER_SIZE_ESTIMATE (RIFF_HEADER_SIZE + CHUNK_HEADER_SIZE +  \
+                              VP8_FRAME_HEADER_SIZE)
+#define DQ_LIMIT 0.4  // convergence is considered reached if dq < DQ_LIMIT
+// we allow 2k of extra head-room in PARTITION0 limit.
+#define PARTITION0_SIZE_LIMIT ((VP8_MAX_PARTITION0_SIZE - 2048ULL) << 11)
+
+typedef struct {  // struct for organizing convergence in either size or PSNR
+  int is_first;
+  float dq;
+  float q, last_q;
+  double value, last_value;   // PSNR or size
+  double target;
+  int do_size_search;
+} PassStats;
+
+static int InitPassStats(const VP8Encoder* const enc, PassStats* const s) {
+  const uint64_t target_size = (uint64_t)enc->config_->target_size;
+  const int do_size_search = (target_size != 0);
+  const float target_PSNR = enc->config_->target_PSNR;
+
+  s->is_first = 1;
+  s->dq = 10.f;
+  s->q = s->last_q = enc->config_->quality;
+  s->target = do_size_search ? (double)target_size
+            : (target_PSNR > 0.) ? target_PSNR
+            : 40.;   // default, just in case
+  s->value = s->last_value = 0.;
+  s->do_size_search = do_size_search;
+  return do_size_search;
+}
+
+static float Clamp(float v, float min, float max) {
+  return (v < min) ? min : (v > max) ? max : v;
+}
+
+static float ComputeNextQ(PassStats* const s) {
+  float dq;
+  if (s->is_first) {
+    dq = (s->value > s->target) ? -s->dq : s->dq;
+    s->is_first = 0;
+  } else if (s->value != s->last_value) {
+    const double slope = (s->target - s->value) / (s->last_value - s->value);
+    dq = (float)(slope * (s->last_q - s->q));
+  } else {
+    dq = 0.;  // we're done?!
+  }
+  // Limit variable to avoid large swings.
+  s->dq = Clamp(dq, -30.f, 30.f);
+  s->last_q = s->q;
+  s->last_value = s->value;
+  s->q = Clamp(s->q + s->dq, 0.f, 100.f);
+  return s->q;
+}
+
+//------------------------------------------------------------------------------
+// Tables for level coding
+
+const uint8_t VP8Cat3[] = { 173, 148, 140 };
+const uint8_t VP8Cat4[] = { 176, 155, 140, 135 };
+const uint8_t VP8Cat5[] = { 180, 157, 141, 134, 130 };
+const uint8_t VP8Cat6[] =
+    { 254, 254, 243, 230, 196, 177, 153, 140, 133, 130, 129 };
+
+//------------------------------------------------------------------------------
+// Reset the statistics about: number of skips, token proba, level cost,...
+
+static void ResetStats(VP8Encoder* const enc) {
+  VP8Proba* const proba = &enc->proba_;
+  VP8CalculateLevelCosts(proba);
+  proba->nb_skip_ = 0;
+}
+
+//------------------------------------------------------------------------------
+// Skip decision probability
+
+#define SKIP_PROBA_THRESHOLD 250  // value below which using skip_proba is OK.
+
+static int CalcSkipProba(uint64_t nb, uint64_t total) {
+  return (int)(total ? (total - nb) * 255 / total : 255);
+}
+
+// Returns the bit-cost for coding the skip probability.
+static int FinalizeSkipProba(VP8Encoder* const enc) {
+  VP8Proba* const proba = &enc->proba_;
+  const int nb_mbs = enc->mb_w_ * enc->mb_h_;
+  const int nb_events = proba->nb_skip_;
+  int size;
+  proba->skip_proba_ = CalcSkipProba(nb_events, nb_mbs);
+  proba->use_skip_proba_ = (proba->skip_proba_ < SKIP_PROBA_THRESHOLD);
+  size = 256;   // 'use_skip_proba' bit
+  if (proba->use_skip_proba_) {
+    size +=  nb_events * VP8BitCost(1, proba->skip_proba_)
+         + (nb_mbs - nb_events) * VP8BitCost(0, proba->skip_proba_);
+    size += 8 * 256;   // cost of signaling the skip_proba_ itself.
+  }
+  return size;
+}
+
+// Collect statistics and deduce probabilities for next coding pass.
+// Return the total bit-cost for coding the probability updates.
+static int CalcTokenProba(int nb, int total) {
+  assert(nb <= total);
+  return nb ? (255 - nb * 255 / total) : 255;
+}
+
+// Cost of coding 'nb' 1's and 'total-nb' 0's using 'proba' probability.
+static int BranchCost(int nb, int total, int proba) {
+  return nb * VP8BitCost(1, proba) + (total - nb) * VP8BitCost(0, proba);
+}
+
+static void ResetTokenStats(VP8Encoder* const enc) {
+  VP8Proba* const proba = &enc->proba_;
+  memset(proba->stats_, 0, sizeof(proba->stats_));
+}
+
+static int FinalizeTokenProbas(VP8Proba* const proba) {
+  int has_changed = 0;
+  int size = 0;
+  int t, b, c, p;
+  for (t = 0; t < NUM_TYPES; ++t) {
+    for (b = 0; b < NUM_BANDS; ++b) {
+      for (c = 0; c < NUM_CTX; ++c) {
+        for (p = 0; p < NUM_PROBAS; ++p) {
+          const proba_t stats = proba->stats_[t][b][c][p];
+          const int nb = (stats >> 0) & 0xffff;
+          const int total = (stats >> 16) & 0xffff;
+          const int update_proba = VP8CoeffsUpdateProba[t][b][c][p];
+          const int old_p = VP8CoeffsProba0[t][b][c][p];
+          const int new_p = CalcTokenProba(nb, total);
+          const int old_cost = BranchCost(nb, total, old_p)
+                             + VP8BitCost(0, update_proba);
+          const int new_cost = BranchCost(nb, total, new_p)
+                             + VP8BitCost(1, update_proba)
+                             + 8 * 256;
+          const int use_new_p = (old_cost > new_cost);
+          size += VP8BitCost(use_new_p, update_proba);
+          if (use_new_p) {  // only use proba that seem meaningful enough.
+            proba->coeffs_[t][b][c][p] = new_p;
+            has_changed |= (new_p != old_p);
+            size += 8 * 256;
+          } else {
+            proba->coeffs_[t][b][c][p] = old_p;
+          }
+        }
+      }
+    }
+  }
+  proba->dirty_ = has_changed;
+  return size;
+}
+
+//------------------------------------------------------------------------------
+// Finalize Segment probability based on the coding tree
+
+static int GetProba(int a, int b) {
+  const int total = a + b;
+  return (total == 0) ? 255     // that's the default probability.
+                      : (255 * a + total / 2) / total;  // rounded proba
+}
+
+static void SetSegmentProbas(VP8Encoder* const enc) {
+  int p[NUM_MB_SEGMENTS] = { 0 };
+  int n;
+
+  for (n = 0; n < enc->mb_w_ * enc->mb_h_; ++n) {
+    const VP8MBInfo* const mb = &enc->mb_info_[n];
+    p[mb->segment_]++;
+  }
+  if (enc->pic_->stats != NULL) {
+    for (n = 0; n < NUM_MB_SEGMENTS; ++n) {
+      enc->pic_->stats->segment_size[n] = p[n];
+    }
+  }
+  if (enc->segment_hdr_.num_segments_ > 1) {
+    uint8_t* const probas = enc->proba_.segments_;
+    probas[0] = GetProba(p[0] + p[1], p[2] + p[3]);
+    probas[1] = GetProba(p[0], p[1]);
+    probas[2] = GetProba(p[2], p[3]);
+
+    enc->segment_hdr_.update_map_ =
+        (probas[0] != 255) || (probas[1] != 255) || (probas[2] != 255);
+    enc->segment_hdr_.size_ =
+        p[0] * (VP8BitCost(0, probas[0]) + VP8BitCost(0, probas[1])) +
+        p[1] * (VP8BitCost(0, probas[0]) + VP8BitCost(1, probas[1])) +
+        p[2] * (VP8BitCost(1, probas[0]) + VP8BitCost(0, probas[2])) +
+        p[3] * (VP8BitCost(1, probas[0]) + VP8BitCost(1, probas[2]));
+  } else {
+    enc->segment_hdr_.update_map_ = 0;
+    enc->segment_hdr_.size_ = 0;
+  }
+}
+
+//------------------------------------------------------------------------------
+// Coefficient coding
+
+static int PutCoeffs(VP8BitWriter* const bw, int ctx, const VP8Residual* res) {
+  int n = res->first;
+  // should be prob[VP8EncBands[n]], but it's equivalent for n=0 or 1
+  const uint8_t* p = res->prob[n][ctx];
+  if (!VP8PutBit(bw, res->last >= 0, p[0])) {
+    return 0;
+  }
+
+  while (n < 16) {
+    const int c = res->coeffs[n++];
+    const int sign = c < 0;
+    int v = sign ? -c : c;
+    if (!VP8PutBit(bw, v != 0, p[1])) {
+      p = res->prob[VP8EncBands[n]][0];
+      continue;
+    }
+    if (!VP8PutBit(bw, v > 1, p[2])) {
+      p = res->prob[VP8EncBands[n]][1];
+    } else {
+      if (!VP8PutBit(bw, v > 4, p[3])) {
+        if (VP8PutBit(bw, v != 2, p[4]))
+          VP8PutBit(bw, v == 4, p[5]);
+      } else if (!VP8PutBit(bw, v > 10, p[6])) {
+        if (!VP8PutBit(bw, v > 6, p[7])) {
+          VP8PutBit(bw, v == 6, 159);
+        } else {
+          VP8PutBit(bw, v >= 9, 165);
+          VP8PutBit(bw, !(v & 1), 145);
+        }
+      } else {
+        int mask;
+        const uint8_t* tab;
+        if (v < 3 + (8 << 1)) {          // VP8Cat3  (3b)
+          VP8PutBit(bw, 0, p[8]);
+          VP8PutBit(bw, 0, p[9]);
+          v -= 3 + (8 << 0);
+          mask = 1 << 2;
+          tab = VP8Cat3;
+        } else if (v < 3 + (8 << 2)) {   // VP8Cat4  (4b)
+          VP8PutBit(bw, 0, p[8]);
+          VP8PutBit(bw, 1, p[9]);
+          v -= 3 + (8 << 1);
+          mask = 1 << 3;
+          tab = VP8Cat4;
+        } else if (v < 3 + (8 << 3)) {   // VP8Cat5  (5b)
+          VP8PutBit(bw, 1, p[8]);
+          VP8PutBit(bw, 0, p[10]);
+          v -= 3 + (8 << 2);
+          mask = 1 << 4;
+          tab = VP8Cat5;
+        } else {                         // VP8Cat6 (11b)
+          VP8PutBit(bw, 1, p[8]);
+          VP8PutBit(bw, 1, p[10]);
+          v -= 3 + (8 << 3);
+          mask = 1 << 10;
+          tab = VP8Cat6;
+        }
+        while (mask) {
+          VP8PutBit(bw, !!(v & mask), *tab++);
+          mask >>= 1;
+        }
+      }
+      p = res->prob[VP8EncBands[n]][2];
+    }
+    VP8PutBitUniform(bw, sign);
+    if (n == 16 || !VP8PutBit(bw, n <= res->last, p[0])) {
+      return 1;   // EOB
+    }
+  }
+  return 1;
+}
+
+static void CodeResiduals(VP8BitWriter* const bw, VP8EncIterator* const it,
+                          const VP8ModeScore* const rd) {
+  int x, y, ch;
+  VP8Residual res;
+  uint64_t pos1, pos2, pos3;
+  const int i16 = (it->mb_->type_ == 1);
+  const int segment = it->mb_->segment_;
+  VP8Encoder* const enc = it->enc_;
+
+  VP8IteratorNzToBytes(it);
+
+  pos1 = VP8BitWriterPos(bw);
+  if (i16) {
+    VP8InitResidual(0, 1, enc, &res);
+    VP8SetResidualCoeffs(rd->y_dc_levels, &res);
+    it->top_nz_[8] = it->left_nz_[8] =
+      PutCoeffs(bw, it->top_nz_[8] + it->left_nz_[8], &res);
+    VP8InitResidual(1, 0, enc, &res);
+  } else {
+    VP8InitResidual(0, 3, enc, &res);
+  }
+
+  // luma-AC
+  for (y = 0; y < 4; ++y) {
+    for (x = 0; x < 4; ++x) {
+      const int ctx = it->top_nz_[x] + it->left_nz_[y];
+      VP8SetResidualCoeffs(rd->y_ac_levels[x + y * 4], &res);
+      it->top_nz_[x] = it->left_nz_[y] = PutCoeffs(bw, ctx, &res);
+    }
+  }
+  pos2 = VP8BitWriterPos(bw);
+
+  // U/V
+  VP8InitResidual(0, 2, enc, &res);
+  for (ch = 0; ch <= 2; ch += 2) {
+    for (y = 0; y < 2; ++y) {
+      for (x = 0; x < 2; ++x) {
+        const int ctx = it->top_nz_[4 + ch + x] + it->left_nz_[4 + ch + y];
+        VP8SetResidualCoeffs(rd->uv_levels[ch * 2 + x + y * 2], &res);
+        it->top_nz_[4 + ch + x] = it->left_nz_[4 + ch + y] =
+            PutCoeffs(bw, ctx, &res);
+      }
+    }
+  }
+  pos3 = VP8BitWriterPos(bw);
+  it->luma_bits_ = pos2 - pos1;
+  it->uv_bits_ = pos3 - pos2;
+  it->bit_count_[segment][i16] += it->luma_bits_;
+  it->bit_count_[segment][2] += it->uv_bits_;
+  VP8IteratorBytesToNz(it);
+}
+
+// Same as CodeResiduals, but doesn't actually write anything.
+// Instead, it just records the event distribution.
+static void RecordResiduals(VP8EncIterator* const it,
+                            const VP8ModeScore* const rd) {
+  int x, y, ch;
+  VP8Residual res;
+  VP8Encoder* const enc = it->enc_;
+
+  VP8IteratorNzToBytes(it);
+
+  if (it->mb_->type_ == 1) {   // i16x16
+    VP8InitResidual(0, 1, enc, &res);
+    VP8SetResidualCoeffs(rd->y_dc_levels, &res);
+    it->top_nz_[8] = it->left_nz_[8] =
+      VP8RecordCoeffs(it->top_nz_[8] + it->left_nz_[8], &res);
+    VP8InitResidual(1, 0, enc, &res);
+  } else {
+    VP8InitResidual(0, 3, enc, &res);
+  }
+
+  // luma-AC
+  for (y = 0; y < 4; ++y) {
+    for (x = 0; x < 4; ++x) {
+      const int ctx = it->top_nz_[x] + it->left_nz_[y];
+      VP8SetResidualCoeffs(rd->y_ac_levels[x + y * 4], &res);
+      it->top_nz_[x] = it->left_nz_[y] = VP8RecordCoeffs(ctx, &res);
+    }
+  }
+
+  // U/V
+  VP8InitResidual(0, 2, enc, &res);
+  for (ch = 0; ch <= 2; ch += 2) {
+    for (y = 0; y < 2; ++y) {
+      for (x = 0; x < 2; ++x) {
+        const int ctx = it->top_nz_[4 + ch + x] + it->left_nz_[4 + ch + y];
+        VP8SetResidualCoeffs(rd->uv_levels[ch * 2 + x + y * 2], &res);
+        it->top_nz_[4 + ch + x] = it->left_nz_[4 + ch + y] =
+            VP8RecordCoeffs(ctx, &res);
+      }
+    }
+  }
+
+  VP8IteratorBytesToNz(it);
+}
+
+//------------------------------------------------------------------------------
+// Token buffer
+
+#if !defined(DISABLE_TOKEN_BUFFER)
+
+static int RecordTokens(VP8EncIterator* const it, const VP8ModeScore* const rd,
+                        VP8TBuffer* const tokens) {
+  int x, y, ch;
+  VP8Residual res;
+  VP8Encoder* const enc = it->enc_;
+
+  VP8IteratorNzToBytes(it);
+  if (it->mb_->type_ == 1) {   // i16x16
+    const int ctx = it->top_nz_[8] + it->left_nz_[8];
+    VP8InitResidual(0, 1, enc, &res);
+    VP8SetResidualCoeffs(rd->y_dc_levels, &res);
+    it->top_nz_[8] = it->left_nz_[8] =
+        VP8RecordCoeffTokens(ctx, 1,
+                             res.first, res.last, res.coeffs, tokens);
+    VP8RecordCoeffs(ctx, &res);
+    VP8InitResidual(1, 0, enc, &res);
+  } else {
+    VP8InitResidual(0, 3, enc, &res);
+  }
+
+  // luma-AC
+  for (y = 0; y < 4; ++y) {
+    for (x = 0; x < 4; ++x) {
+      const int ctx = it->top_nz_[x] + it->left_nz_[y];
+      VP8SetResidualCoeffs(rd->y_ac_levels[x + y * 4], &res);
+      it->top_nz_[x] = it->left_nz_[y] =
+          VP8RecordCoeffTokens(ctx, res.coeff_type,
+                               res.first, res.last, res.coeffs, tokens);
+      VP8RecordCoeffs(ctx, &res);
+    }
+  }
+
+  // U/V
+  VP8InitResidual(0, 2, enc, &res);
+  for (ch = 0; ch <= 2; ch += 2) {
+    for (y = 0; y < 2; ++y) {
+      for (x = 0; x < 2; ++x) {
+        const int ctx = it->top_nz_[4 + ch + x] + it->left_nz_[4 + ch + y];
+        VP8SetResidualCoeffs(rd->uv_levels[ch * 2 + x + y * 2], &res);
+        it->top_nz_[4 + ch + x] = it->left_nz_[4 + ch + y] =
+            VP8RecordCoeffTokens(ctx, 2,
+                                 res.first, res.last, res.coeffs, tokens);
+        VP8RecordCoeffs(ctx, &res);
+      }
+    }
+  }
+  VP8IteratorBytesToNz(it);
+  return !tokens->error_;
+}
+
+#endif    // !DISABLE_TOKEN_BUFFER
+
+//------------------------------------------------------------------------------
+// ExtraInfo map / Debug function
+
+#if SEGMENT_VISU
+static void SetBlock(uint8_t* p, int value, int size) {
+  int y;
+  for (y = 0; y < size; ++y) {
+    memset(p, value, size);
+    p += BPS;
+  }
+}
+#endif
+
+static void ResetSSE(VP8Encoder* const enc) {
+  enc->sse_[0] = 0;
+  enc->sse_[1] = 0;
+  enc->sse_[2] = 0;
+  // Note: enc->sse_[3] is managed by alpha.c
+  enc->sse_count_ = 0;
+}
+
+static void StoreSSE(const VP8EncIterator* const it) {
+  VP8Encoder* const enc = it->enc_;
+  const uint8_t* const in = it->yuv_in_;
+  const uint8_t* const out = it->yuv_out_;
+  // Note: not totally accurate at boundary. And doesn't include in-loop filter.
+  enc->sse_[0] += VP8SSE16x16(in + Y_OFF, out + Y_OFF);
+  enc->sse_[1] += VP8SSE8x8(in + U_OFF, out + U_OFF);
+  enc->sse_[2] += VP8SSE8x8(in + V_OFF, out + V_OFF);
+  enc->sse_count_ += 16 * 16;
+}
+
+static void StoreSideInfo(const VP8EncIterator* const it) {
+  VP8Encoder* const enc = it->enc_;
+  const VP8MBInfo* const mb = it->mb_;
+  WebPPicture* const pic = enc->pic_;
+
+  if (pic->stats != NULL) {
+    StoreSSE(it);
+    enc->block_count_[0] += (mb->type_ == 0);
+    enc->block_count_[1] += (mb->type_ == 1);
+    enc->block_count_[2] += (mb->skip_ != 0);
+  }
+
+  if (pic->extra_info != NULL) {
+    uint8_t* const info = &pic->extra_info[it->x_ + it->y_ * enc->mb_w_];
+    switch (pic->extra_info_type) {
+      case 1: *info = mb->type_; break;
+      case 2: *info = mb->segment_; break;
+      case 3: *info = enc->dqm_[mb->segment_].quant_; break;
+      case 4: *info = (mb->type_ == 1) ? it->preds_[0] : 0xff; break;
+      case 5: *info = mb->uv_mode_; break;
+      case 6: {
+        const int b = (int)((it->luma_bits_ + it->uv_bits_ + 7) >> 3);
+        *info = (b > 255) ? 255 : b; break;
+      }
+      case 7: *info = mb->alpha_; break;
+      default: *info = 0; break;
+    }
+  }
+#if SEGMENT_VISU  // visualize segments and prediction modes
+  SetBlock(it->yuv_out_ + Y_OFF, mb->segment_ * 64, 16);
+  SetBlock(it->yuv_out_ + U_OFF, it->preds_[0] * 64, 8);
+  SetBlock(it->yuv_out_ + V_OFF, mb->uv_mode_ * 64, 8);
+#endif
+}
+
+static double GetPSNR(uint64_t mse, uint64_t size) {
+  return (mse > 0 && size > 0) ? 10. * log10(255. * 255. * size / mse) : 99;
+}
+
+//------------------------------------------------------------------------------
+//  StatLoop(): only collect statistics (number of skips, token usage, ...).
+//  This is used for deciding optimal probabilities. It also modifies the
+//  quantizer value if some target (size, PSNR) was specified.
+
+static void SetLoopParams(VP8Encoder* const enc, float q) {
+  // Make sure the quality parameter is inside valid bounds
+  q = Clamp(q, 0.f, 100.f);
+
+  VP8SetSegmentParams(enc, q);      // setup segment quantizations and filters
+  SetSegmentProbas(enc);            // compute segment probabilities
+
+  ResetStats(enc);
+  ResetSSE(enc);
+}
+
+static uint64_t OneStatPass(VP8Encoder* const enc, VP8RDLevel rd_opt,
+                            int nb_mbs, int percent_delta,
+                            PassStats* const s) {
+  VP8EncIterator it;
+  uint64_t size = 0;
+  uint64_t size_p0 = 0;
+  uint64_t distortion = 0;
+  const uint64_t pixel_count = nb_mbs * 384;
+
+  VP8IteratorInit(enc, &it);
+  SetLoopParams(enc, s->q);
+  do {
+    VP8ModeScore info;
+    VP8IteratorImport(&it, NULL);
+    if (VP8Decimate(&it, &info, rd_opt)) {
+      // Just record the number of skips and act like skip_proba is not used.
+      enc->proba_.nb_skip_++;
+    }
+    RecordResiduals(&it, &info);
+    size += info.R + info.H;
+    size_p0 += info.H;
+    distortion += info.D;
+    if (percent_delta && !VP8IteratorProgress(&it, percent_delta))
+      return 0;
+    VP8IteratorSaveBoundary(&it);
+  } while (VP8IteratorNext(&it) && --nb_mbs > 0);
+
+  size_p0 += enc->segment_hdr_.size_;
+  if (s->do_size_search) {
+    size += FinalizeSkipProba(enc);
+    size += FinalizeTokenProbas(&enc->proba_);
+    size = ((size + size_p0 + 1024) >> 11) + HEADER_SIZE_ESTIMATE;
+    s->value = (double)size;
+  } else {
+    s->value = GetPSNR(distortion, pixel_count);
+  }
+  return size_p0;
+}
+
+static int StatLoop(VP8Encoder* const enc) {
+  const int method = enc->method_;
+  const int do_search = enc->do_search_;
+  const int fast_probe = ((method == 0 || method == 3) && !do_search);
+  int num_pass_left = enc->config_->pass;
+  const int task_percent = 20;
+  const int percent_per_pass =
+      (task_percent + num_pass_left / 2) / num_pass_left;
+  const int final_percent = enc->percent_ + task_percent;
+  const VP8RDLevel rd_opt =
+      (method >= 3 || do_search) ? RD_OPT_BASIC : RD_OPT_NONE;
+  int nb_mbs = enc->mb_w_ * enc->mb_h_;
+  PassStats stats;
+
+  InitPassStats(enc, &stats);
+  ResetTokenStats(enc);
+
+  // Fast mode: quick analysis pass over few mbs. Better than nothing.
+  if (fast_probe) {
+    if (method == 3) {  // we need more stats for method 3 to be reliable.
+      nb_mbs = (nb_mbs > 200) ? nb_mbs >> 1 : 100;
+    } else {
+      nb_mbs = (nb_mbs > 200) ? nb_mbs >> 2 : 50;
+    }
+  }
+
+  while (num_pass_left-- > 0) {
+    const int is_last_pass = (fabs(stats.dq) <= DQ_LIMIT) ||
+                             (num_pass_left == 0) ||
+                             (enc->max_i4_header_bits_ == 0);
+    const uint64_t size_p0 =
+        OneStatPass(enc, rd_opt, nb_mbs, percent_per_pass, &stats);
+    if (size_p0 == 0) return 0;
+#if (DEBUG_SEARCH > 0)
+    printf("#%d value:%.1lf -> %.1lf   q:%.2f -> %.2f\n",
+           num_pass_left, stats.last_value, stats.value, stats.last_q, stats.q);
+#endif
+    if (enc->max_i4_header_bits_ > 0 && size_p0 > PARTITION0_SIZE_LIMIT) {
+      ++num_pass_left;
+      enc->max_i4_header_bits_ >>= 1;  // strengthen header bit limitation...
+      continue;                        // ...and start over
+    }
+    if (is_last_pass) {
+      break;
+    }
+    // If no target size: just do several pass without changing 'q'
+    if (do_search) {
+      ComputeNextQ(&stats);
+      if (fabs(stats.dq) <= DQ_LIMIT) break;
+    }
+  }
+  if (!do_search || !stats.do_size_search) {
+    // Need to finalize probas now, since it wasn't done during the search.
+    FinalizeSkipProba(enc);
+    FinalizeTokenProbas(&enc->proba_);
+  }
+  VP8CalculateLevelCosts(&enc->proba_);  // finalize costs
+  return WebPReportProgress(enc->pic_, final_percent, &enc->percent_);
+}
+
+//------------------------------------------------------------------------------
+// Main loops
+//
+
+static const int kAverageBytesPerMB[8] = { 50, 24, 16, 9, 7, 5, 3, 2 };
+
+static int PreLoopInitialize(VP8Encoder* const enc) {
+  int p;
+  int ok = 1;
+  const int average_bytes_per_MB = kAverageBytesPerMB[enc->base_quant_ >> 4];
+  const int bytes_per_parts =
+      enc->mb_w_ * enc->mb_h_ * average_bytes_per_MB / enc->num_parts_;
+  // Initialize the bit-writers
+  for (p = 0; ok && p < enc->num_parts_; ++p) {
+    ok = VP8BitWriterInit(enc->parts_ + p, bytes_per_parts);
+  }
+  if (!ok) {
+    VP8EncFreeBitWriters(enc);  // malloc error occurred
+    WebPEncodingSetError(enc->pic_, VP8_ENC_ERROR_OUT_OF_MEMORY);
+  }
+  return ok;
+}
+
+static int PostLoopFinalize(VP8EncIterator* const it, int ok) {
+  VP8Encoder* const enc = it->enc_;
+  if (ok) {      // Finalize the partitions, check for extra errors.
+    int p;
+    for (p = 0; p < enc->num_parts_; ++p) {
+      VP8BitWriterFinish(enc->parts_ + p);
+      ok &= !enc->parts_[p].error_;
+    }
+  }
+
+  if (ok) {      // All good. Finish up.
+    if (enc->pic_->stats != NULL) {  // finalize byte counters...
+      int i, s;
+      for (i = 0; i <= 2; ++i) {
+        for (s = 0; s < NUM_MB_SEGMENTS; ++s) {
+          enc->residual_bytes_[i][s] = (int)((it->bit_count_[s][i] + 7) >> 3);
+        }
+      }
+    }
+    VP8AdjustFilterStrength(it);     // ...and store filter stats.
+  } else {
+    // Something bad happened -> need to do some memory cleanup.
+    VP8EncFreeBitWriters(enc);
+  }
+  return ok;
+}
+
+//------------------------------------------------------------------------------
+//  VP8EncLoop(): does the final bitstream coding.
+
+static void ResetAfterSkip(VP8EncIterator* const it) {
+  if (it->mb_->type_ == 1) {
+    *it->nz_ = 0;  // reset all predictors
+    it->left_nz_[8] = 0;
+  } else {
+    *it->nz_ &= (1 << 24);  // preserve the dc_nz bit
+  }
+}
+
+int VP8EncLoop(VP8Encoder* const enc) {
+  VP8EncIterator it;
+  int ok = PreLoopInitialize(enc);
+  if (!ok) return 0;
+
+  StatLoop(enc);  // stats-collection loop
+
+  VP8IteratorInit(enc, &it);
+  VP8InitFilter(&it);
+  do {
+    VP8ModeScore info;
+    const int dont_use_skip = !enc->proba_.use_skip_proba_;
+    const VP8RDLevel rd_opt = enc->rd_opt_level_;
+
+    VP8IteratorImport(&it, NULL);
+    // Warning! order is important: first call VP8Decimate() and
+    // *then* decide how to code the skip decision if there's one.
+    if (!VP8Decimate(&it, &info, rd_opt) || dont_use_skip) {
+      CodeResiduals(it.bw_, &it, &info);
+    } else {   // reset predictors after a skip
+      ResetAfterSkip(&it);
+    }
+    StoreSideInfo(&it);
+    VP8StoreFilterStats(&it);
+    VP8IteratorExport(&it);
+    ok = VP8IteratorProgress(&it, 20);
+    VP8IteratorSaveBoundary(&it);
+  } while (ok && VP8IteratorNext(&it));
+
+  return PostLoopFinalize(&it, ok);
+}
+
+//------------------------------------------------------------------------------
+// Single pass using Token Buffer.
+
+#if !defined(DISABLE_TOKEN_BUFFER)
+
+#define MIN_COUNT 96  // minimum number of macroblocks before updating stats
+
+int VP8EncTokenLoop(VP8Encoder* const enc) {
+  // Roughly refresh the proba eight times per pass
+  int max_count = (enc->mb_w_ * enc->mb_h_) >> 3;
+  int num_pass_left = enc->config_->pass;
+  const int do_search = enc->do_search_;
+  VP8EncIterator it;
+  VP8Proba* const proba = &enc->proba_;
+  const VP8RDLevel rd_opt = enc->rd_opt_level_;
+  const uint64_t pixel_count = enc->mb_w_ * enc->mb_h_ * 384;
+  PassStats stats;
+  int ok;
+
+  InitPassStats(enc, &stats);
+  ok = PreLoopInitialize(enc);
+  if (!ok) return 0;
+
+  if (max_count < MIN_COUNT) max_count = MIN_COUNT;
+
+  assert(enc->num_parts_ == 1);
+  assert(enc->use_tokens_);
+  assert(proba->use_skip_proba_ == 0);
+  assert(rd_opt >= RD_OPT_BASIC);   // otherwise, token-buffer won't be useful
+  assert(num_pass_left > 0);
+
+  while (ok && num_pass_left-- > 0) {
+    const int is_last_pass = (fabs(stats.dq) <= DQ_LIMIT) ||
+                             (num_pass_left == 0) ||
+                             (enc->max_i4_header_bits_ == 0);
+    uint64_t size_p0 = 0;
+    uint64_t distortion = 0;
+    int cnt = max_count;
+    VP8IteratorInit(enc, &it);
+    SetLoopParams(enc, stats.q);
+    if (is_last_pass) {
+      ResetTokenStats(enc);
+      VP8InitFilter(&it);  // don't collect stats until last pass (too costly)
+    }
+    VP8TBufferClear(&enc->tokens_);
+    do {
+      VP8ModeScore info;
+      VP8IteratorImport(&it, NULL);
+      if (--cnt < 0) {
+        FinalizeTokenProbas(proba);
+        VP8CalculateLevelCosts(proba);  // refresh cost tables for rd-opt
+        cnt = max_count;
+      }
+      VP8Decimate(&it, &info, rd_opt);
+      ok = RecordTokens(&it, &info, &enc->tokens_);
+      if (!ok) {
+        WebPEncodingSetError(enc->pic_, VP8_ENC_ERROR_OUT_OF_MEMORY);
+        break;
+      }
+      size_p0 += info.H;
+      distortion += info.D;
+      if (is_last_pass) {
+        StoreSideInfo(&it);
+        VP8StoreFilterStats(&it);
+        VP8IteratorExport(&it);
+        ok = VP8IteratorProgress(&it, 20);
+      }
+      VP8IteratorSaveBoundary(&it);
+    } while (ok && VP8IteratorNext(&it));
+    if (!ok) break;
+
+    size_p0 += enc->segment_hdr_.size_;
+    if (stats.do_size_search) {
+      uint64_t size = FinalizeTokenProbas(&enc->proba_);
+      size += VP8EstimateTokenSize(&enc->tokens_,
+                                   (const uint8_t*)proba->coeffs_);
+      size = (size + size_p0 + 1024) >> 11;  // -> size in bytes
+      size += HEADER_SIZE_ESTIMATE;
+      stats.value = (double)size;
+    } else {  // compute and store PSNR
+      stats.value = GetPSNR(distortion, pixel_count);
+    }
+
+#if (DEBUG_SEARCH > 0)
+    printf("#%2d metric:%.1lf -> %.1lf   last_q=%.2lf q=%.2lf dq=%.2lf\n",
+           num_pass_left, stats.last_value, stats.value,
+           stats.last_q, stats.q, stats.dq);
+#endif
+    if (size_p0 > PARTITION0_SIZE_LIMIT) {
+      ++num_pass_left;
+      enc->max_i4_header_bits_ >>= 1;  // strengthen header bit limitation...
+      continue;                        // ...and start over
+    }
+    if (is_last_pass) {
+      break;   // done
+    }
+    if (do_search) {
+      ComputeNextQ(&stats);  // Adjust q
+    }
+  }
+  if (ok) {
+    if (!stats.do_size_search) {
+      FinalizeTokenProbas(&enc->proba_);
+    }
+    ok = VP8EmitTokens(&enc->tokens_, enc->parts_ + 0,
+                       (const uint8_t*)proba->coeffs_, 1);
+  }
+  ok = ok && WebPReportProgress(enc->pic_, enc->percent_ + 20, &enc->percent_);
+  return PostLoopFinalize(&it, ok);
+}
+
+#else
+
+int VP8EncTokenLoop(VP8Encoder* const enc) {
+  (void)enc;
+  return 0;   // we shouldn't be here.
+}
+
+#endif    // DISABLE_TOKEN_BUFFER
+
+//------------------------------------------------------------------------------
+
diff --git a/Source/LibWebP/src/enc/enc.histogram.c b/Source/LibWebP/src/enc/enc.histogram.c
new file mode 100644
index 0000000..6259cc6
--- /dev/null
+++ b/Source/LibWebP/src/enc/enc.histogram.c
@@ -0,0 +1,897 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Author: Jyrki Alakuijala (jyrki at google.com)
+//
+#ifdef HAVE_CONFIG_H
+#include "../webp/config.h"
+#endif
+
+#include <math.h>
+
+#include "./backward_references.h"
+#include "./histogram.h"
+#include "../dsp/lossless.h"
+#include "../utils/utils.h"
+
+#define MAX_COST 1.e38
+
+// Number of partitions for the three dominant (literal, red and blue) symbol
+// costs.
+#define NUM_PARTITIONS 4
+// The size of the bin-hash corresponding to the three dominant costs.
+#define BIN_SIZE (NUM_PARTITIONS * NUM_PARTITIONS * NUM_PARTITIONS)
+// Maximum number of histograms allowed in greedy combining algorithm.
+#define MAX_HISTO_GREEDY 100
+
+static void HistogramClear(VP8LHistogram* const p) {
+  uint32_t* const literal = p->literal_;
+  const int cache_bits = p->palette_code_bits_;
+  const int histo_size = VP8LGetHistogramSize(cache_bits);
+  memset(p, 0, histo_size);
+  p->palette_code_bits_ = cache_bits;
+  p->literal_ = literal;
+}
+
+// Swap two histogram pointers.
+static void HistogramSwap(VP8LHistogram** const A, VP8LHistogram** const B) {
+  VP8LHistogram* const tmp = *A;
+  *A = *B;
+  *B = tmp;
+}
+
+static void HistogramCopy(const VP8LHistogram* const src,
+                          VP8LHistogram* const dst) {
+  uint32_t* const dst_literal = dst->literal_;
+  const int dst_cache_bits = dst->palette_code_bits_;
+  const int histo_size = VP8LGetHistogramSize(dst_cache_bits);
+  assert(src->palette_code_bits_ == dst_cache_bits);
+  memcpy(dst, src, histo_size);
+  dst->literal_ = dst_literal;
+}
+
+int VP8LGetHistogramSize(int cache_bits) {
+  const int literal_size = VP8LHistogramNumCodes(cache_bits);
+  const size_t total_size = sizeof(VP8LHistogram) + sizeof(int) * literal_size;
+  assert(total_size <= (size_t)0x7fffffff);
+  return (int)total_size;
+}
+
+void VP8LFreeHistogram(VP8LHistogram* const histo) {
+  WebPSafeFree(histo);
+}
+
+void VP8LFreeHistogramSet(VP8LHistogramSet* const histo) {
+  WebPSafeFree(histo);
+}
+
+void VP8LHistogramStoreRefs(const VP8LBackwardRefs* const refs,
+                            VP8LHistogram* const histo) {
+  VP8LRefsCursor c = VP8LRefsCursorInit(refs);
+  while (VP8LRefsCursorOk(&c)) {
+    VP8LHistogramAddSinglePixOrCopy(histo, c.cur_pos);
+    VP8LRefsCursorNext(&c);
+  }
+}
+
+void VP8LHistogramCreate(VP8LHistogram* const p,
+                         const VP8LBackwardRefs* const refs,
+                         int palette_code_bits) {
+  if (palette_code_bits >= 0) {
+    p->palette_code_bits_ = palette_code_bits;
+  }
+  HistogramClear(p);
+  VP8LHistogramStoreRefs(refs, p);
+}
+
+void VP8LHistogramInit(VP8LHistogram* const p, int palette_code_bits) {
+  p->palette_code_bits_ = palette_code_bits;
+  HistogramClear(p);
+}
+
+VP8LHistogram* VP8LAllocateHistogram(int cache_bits) {
+  VP8LHistogram* histo = NULL;
+  const int total_size = VP8LGetHistogramSize(cache_bits);
+  uint8_t* const memory = (uint8_t*)WebPSafeMalloc(total_size, sizeof(*memory));
+  if (memory == NULL) return NULL;
+  histo = (VP8LHistogram*)memory;
+  // literal_ won't necessary be aligned.
+  histo->literal_ = (uint32_t*)(memory + sizeof(VP8LHistogram));
+  VP8LHistogramInit(histo, cache_bits);
+  return histo;
+}
+
+VP8LHistogramSet* VP8LAllocateHistogramSet(int size, int cache_bits) {
+  int i;
+  VP8LHistogramSet* set;
+  const size_t total_size = sizeof(*set)
+                            + sizeof(*set->histograms) * size
+                            + (size_t)VP8LGetHistogramSize(cache_bits) * size;
+  uint8_t* memory = (uint8_t*)WebPSafeMalloc(total_size, sizeof(*memory));
+  if (memory == NULL) return NULL;
+
+  set = (VP8LHistogramSet*)memory;
+  memory += sizeof(*set);
+  set->histograms = (VP8LHistogram**)memory;
+  memory += size * sizeof(*set->histograms);
+  set->max_size = size;
+  set->size = size;
+  for (i = 0; i < size; ++i) {
+    set->histograms[i] = (VP8LHistogram*)memory;
+    // literal_ won't necessary be aligned.
+    set->histograms[i]->literal_ = (uint32_t*)(memory + sizeof(VP8LHistogram));
+    VP8LHistogramInit(set->histograms[i], cache_bits);
+    // There's no padding/alignment between successive histograms.
+    memory += VP8LGetHistogramSize(cache_bits);
+  }
+  return set;
+}
+
+// -----------------------------------------------------------------------------
+
+void VP8LHistogramAddSinglePixOrCopy(VP8LHistogram* const histo,
+                                     const PixOrCopy* const v) {
+  if (PixOrCopyIsLiteral(v)) {
+    ++histo->alpha_[PixOrCopyLiteral(v, 3)];
+    ++histo->red_[PixOrCopyLiteral(v, 2)];
+    ++histo->literal_[PixOrCopyLiteral(v, 1)];
+    ++histo->blue_[PixOrCopyLiteral(v, 0)];
+  } else if (PixOrCopyIsCacheIdx(v)) {
+    const int literal_ix =
+        NUM_LITERAL_CODES + NUM_LENGTH_CODES + PixOrCopyCacheIdx(v);
+    ++histo->literal_[literal_ix];
+  } else {
+    int code, extra_bits;
+    VP8LPrefixEncodeBits(PixOrCopyLength(v), &code, &extra_bits);
+    ++histo->literal_[NUM_LITERAL_CODES + code];
+    VP8LPrefixEncodeBits(PixOrCopyDistance(v), &code, &extra_bits);
+    ++histo->distance_[code];
+  }
+}
+
+// -----------------------------------------------------------------------------
+// Various histogram combine/cost-eval functions
+
+static int GetCombinedHistogramEntropy(const VP8LHistogram* const a,
+                                       const VP8LHistogram* const b,
+                                       double cost_threshold,
+                                       double* cost) {
+  const int palette_code_bits = a->palette_code_bits_;
+  assert(a->palette_code_bits_ == b->palette_code_bits_);
+  *cost += VP8LGetCombinedEntropy(a->literal_, b->literal_,
+                                  VP8LHistogramNumCodes(palette_code_bits));
+  *cost += VP8LExtraCostCombined(a->literal_ + NUM_LITERAL_CODES,
+                                 b->literal_ + NUM_LITERAL_CODES,
+                                 NUM_LENGTH_CODES);
+  if (*cost > cost_threshold) return 0;
+
+  *cost += VP8LGetCombinedEntropy(a->red_, b->red_, NUM_LITERAL_CODES);
+  if (*cost > cost_threshold) return 0;
+
+  *cost += VP8LGetCombinedEntropy(a->blue_, b->blue_, NUM_LITERAL_CODES);
+  if (*cost > cost_threshold) return 0;
+
+  *cost += VP8LGetCombinedEntropy(a->alpha_, b->alpha_, NUM_LITERAL_CODES);
+  if (*cost > cost_threshold) return 0;
+
+  *cost += VP8LGetCombinedEntropy(a->distance_, b->distance_,
+                                  NUM_DISTANCE_CODES);
+  *cost += VP8LExtraCostCombined(a->distance_, b->distance_,
+                                 NUM_DISTANCE_CODES);
+  if (*cost > cost_threshold) return 0;
+
+  return 1;
+}
+
+// Performs out = a + b, computing the cost C(a+b) - C(a) - C(b) while comparing
+// to the threshold value 'cost_threshold'. The score returned is
+//  Score = C(a+b) - C(a) - C(b), where C(a) + C(b) is known and fixed.
+// Since the previous score passed is 'cost_threshold', we only need to compare
+// the partial cost against 'cost_threshold + C(a) + C(b)' to possibly bail-out
+// early.
+static double HistogramAddEval(const VP8LHistogram* const a,
+                               const VP8LHistogram* const b,
+                               VP8LHistogram* const out,
+                               double cost_threshold) {
+  double cost = 0;
+  const double sum_cost = a->bit_cost_ + b->bit_cost_;
+  cost_threshold += sum_cost;
+
+  if (GetCombinedHistogramEntropy(a, b, cost_threshold, &cost)) {
+    VP8LHistogramAdd(a, b, out);
+    out->bit_cost_ = cost;
+    out->palette_code_bits_ = a->palette_code_bits_;
+    out->trivial_symbol_ = (a->trivial_symbol_ == b->trivial_symbol_) ?
+        a->trivial_symbol_ : VP8L_NON_TRIVIAL_SYM;
+  }
+
+  return cost - sum_cost;
+}
+
+// Same as HistogramAddEval(), except that the resulting histogram
+// is not stored. Only the cost C(a+b) - C(a) is evaluated. We omit
+// the term C(b) which is constant over all the evaluations.
+static double HistogramAddThresh(const VP8LHistogram* const a,
+                                 const VP8LHistogram* const b,
+                                 double cost_threshold) {
+  double cost = -a->bit_cost_;
+  GetCombinedHistogramEntropy(a, b, cost_threshold, &cost);
+  return cost;
+}
+
+// -----------------------------------------------------------------------------
+
+// The structure to keep track of cost range for the three dominant entropy
+// symbols.
+// TODO(skal): Evaluate if float can be used here instead of double for
+// representing the entropy costs.
+typedef struct {
+  double literal_max_;
+  double literal_min_;
+  double red_max_;
+  double red_min_;
+  double blue_max_;
+  double blue_min_;
+} DominantCostRange;
+
+static void DominantCostRangeInit(DominantCostRange* const c) {
+  c->literal_max_ = 0.;
+  c->literal_min_ = MAX_COST;
+  c->red_max_ = 0.;
+  c->red_min_ = MAX_COST;
+  c->blue_max_ = 0.;
+  c->blue_min_ = MAX_COST;
+}
+
+static void UpdateDominantCostRange(
+    const VP8LHistogram* const h, DominantCostRange* const c) {
+  if (c->literal_max_ < h->literal_cost_) c->literal_max_ = h->literal_cost_;
+  if (c->literal_min_ > h->literal_cost_) c->literal_min_ = h->literal_cost_;
+  if (c->red_max_ < h->red_cost_) c->red_max_ = h->red_cost_;
+  if (c->red_min_ > h->red_cost_) c->red_min_ = h->red_cost_;
+  if (c->blue_max_ < h->blue_cost_) c->blue_max_ = h->blue_cost_;
+  if (c->blue_min_ > h->blue_cost_) c->blue_min_ = h->blue_cost_;
+}
+
+static void UpdateHistogramCost(VP8LHistogram* const h) {
+  uint32_t alpha_sym, red_sym, blue_sym;
+  const double alpha_cost = VP8LPopulationCost(h->alpha_, NUM_LITERAL_CODES,
+                                               &alpha_sym);
+  const double distance_cost =
+      VP8LPopulationCost(h->distance_, NUM_DISTANCE_CODES, NULL) +
+      VP8LExtraCost(h->distance_, NUM_DISTANCE_CODES);
+  const int num_codes = VP8LHistogramNumCodes(h->palette_code_bits_);
+  h->literal_cost_ = VP8LPopulationCost(h->literal_, num_codes, NULL) +
+                     VP8LExtraCost(h->literal_ + NUM_LITERAL_CODES,
+                                   NUM_LENGTH_CODES);
+  h->red_cost_ = VP8LPopulationCost(h->red_, NUM_LITERAL_CODES, &red_sym);
+  h->blue_cost_ = VP8LPopulationCost(h->blue_, NUM_LITERAL_CODES, &blue_sym);
+  h->bit_cost_ = h->literal_cost_ + h->red_cost_ + h->blue_cost_ +
+                 alpha_cost + distance_cost;
+  if ((alpha_sym | red_sym | blue_sym) == VP8L_NON_TRIVIAL_SYM) {
+    h->trivial_symbol_ = VP8L_NON_TRIVIAL_SYM;
+  } else {
+    h->trivial_symbol_ =
+        ((uint32_t)alpha_sym << 24) | (red_sym << 16) | (blue_sym << 0);
+  }
+}
+
+static int GetBinIdForEntropy(double min, double max, double val) {
+  const double range = max - min + 1e-6;
+  const double delta = val - min;
+  return (int)(NUM_PARTITIONS * delta / range);
+}
+
+static int GetHistoBinIndexLowEffort(
+    const VP8LHistogram* const h, const DominantCostRange* const c) {
+  const int bin_id = GetBinIdForEntropy(c->literal_min_, c->literal_max_,
+                                        h->literal_cost_);
+  assert(bin_id < NUM_PARTITIONS);
+  return bin_id;
+}
+
+static int GetHistoBinIndex(
+    const VP8LHistogram* const h, const DominantCostRange* const c) {
+  const int bin_id =
+      GetBinIdForEntropy(c->blue_min_, c->blue_max_, h->blue_cost_) +
+      NUM_PARTITIONS * GetBinIdForEntropy(c->red_min_, c->red_max_,
+                                          h->red_cost_) +
+      NUM_PARTITIONS * NUM_PARTITIONS * GetBinIdForEntropy(c->literal_min_,
+                                                           c->literal_max_,
+                                                           h->literal_cost_);
+  assert(bin_id < BIN_SIZE);
+  return bin_id;
+}
+
+// Construct the histograms from backward references.
+static void HistogramBuild(
+    int xsize, int histo_bits, const VP8LBackwardRefs* const backward_refs,
+    VP8LHistogramSet* const image_histo) {
+  int x = 0, y = 0;
+  const int histo_xsize = VP8LSubSampleSize(xsize, histo_bits);
+  VP8LHistogram** const histograms = image_histo->histograms;
+  VP8LRefsCursor c = VP8LRefsCursorInit(backward_refs);
+  assert(histo_bits > 0);
+  while (VP8LRefsCursorOk(&c)) {
+    const PixOrCopy* const v = c.cur_pos;
+    const int ix = (y >> histo_bits) * histo_xsize + (x >> histo_bits);
+    VP8LHistogramAddSinglePixOrCopy(histograms[ix], v);
+    x += PixOrCopyLength(v);
+    while (x >= xsize) {
+      x -= xsize;
+      ++y;
+    }
+    VP8LRefsCursorNext(&c);
+  }
+}
+
+// Copies the histograms and computes its bit_cost.
+static void HistogramCopyAndAnalyze(
+    VP8LHistogramSet* const orig_histo, VP8LHistogramSet* const image_histo) {
+  int i;
+  const int histo_size = orig_histo->size;
+  VP8LHistogram** const orig_histograms = orig_histo->histograms;
+  VP8LHistogram** const histograms = image_histo->histograms;
+  for (i = 0; i < histo_size; ++i) {
+    VP8LHistogram* const histo = orig_histograms[i];
+    UpdateHistogramCost(histo);
+    // Copy histograms from orig_histo[] to image_histo[].
+    HistogramCopy(histo, histograms[i]);
+  }
+}
+
+// Partition histograms to different entropy bins for three dominant (literal,
+// red and blue) symbol costs and compute the histogram aggregate bit_cost.
+static void HistogramAnalyzeEntropyBin(VP8LHistogramSet* const image_histo,
+                                       int16_t* const bin_map, int low_effort) {
+  int i;
+  VP8LHistogram** const histograms = image_histo->histograms;
+  const int histo_size = image_histo->size;
+  const int bin_depth = histo_size + 1;
+  DominantCostRange cost_range;
+  DominantCostRangeInit(&cost_range);
+
+  // Analyze the dominant (literal, red and blue) entropy costs.
+  for (i = 0; i < histo_size; ++i) {
+    VP8LHistogram* const histo = histograms[i];
+    UpdateDominantCostRange(histo, &cost_range);
+  }
+
+  // bin-hash histograms on three of the dominant (literal, red and blue)
+  // symbol costs.
+  for (i = 0; i < histo_size; ++i) {
+    int num_histos;
+    VP8LHistogram* const histo = histograms[i];
+    const int16_t bin_id = low_effort ?
+        (int16_t)GetHistoBinIndexLowEffort(histo, &cost_range) :
+        (int16_t)GetHistoBinIndex(histo, &cost_range);
+    const int bin_offset = bin_id * bin_depth;
+    // bin_map[n][0] for every bin 'n' maintains the counter for the number of
+    // histograms in that bin.
+    // Get and increment the num_histos in that bin.
+    num_histos = ++bin_map[bin_offset];
+    assert(bin_offset + num_histos < bin_depth * BIN_SIZE);
+    // Add histogram i'th index at num_histos (last) position in the bin_map.
+    bin_map[bin_offset + num_histos] = i;
+  }
+}
+
+// Compact the histogram set by removing unused entries.
+static void HistogramCompactBins(VP8LHistogramSet* const image_histo) {
+  VP8LHistogram** const histograms = image_histo->histograms;
+  int i, j;
+
+  for (i = 0, j = 0; i < image_histo->size; ++i) {
+    if (histograms[i] != NULL && histograms[i]->bit_cost_ != 0.) {
+      if (j < i) {
+        histograms[j] = histograms[i];
+        histograms[i] = NULL;
+      }
+      ++j;
+    }
+  }
+  image_histo->size = j;
+}
+
+static VP8LHistogram* HistogramCombineEntropyBin(
+    VP8LHistogramSet* const image_histo,
+    VP8LHistogram* cur_combo,
+    int16_t* const bin_map, int bin_depth, int num_bins,
+    double combine_cost_factor, int low_effort) {
+  int bin_id;
+  VP8LHistogram** const histograms = image_histo->histograms;
+
+  for (bin_id = 0; bin_id < num_bins; ++bin_id) {
+    const int bin_offset = bin_id * bin_depth;
+    const int num_histos = bin_map[bin_offset];
+    const int idx1 = bin_map[bin_offset + 1];
+    int num_combine_failures = 0;
+    int n;
+    for (n = 2; n <= num_histos; ++n) {
+      const int idx2 = bin_map[bin_offset + n];
+      if (low_effort) {
+        // Merge all histograms with the same bin index, irrespective of cost of
+        // the merged histograms.
+        VP8LHistogramAdd(histograms[idx1], histograms[idx2], histograms[idx1]);
+        histograms[idx2]->bit_cost_ = 0.;
+      } else {
+        const double bit_cost_idx2 = histograms[idx2]->bit_cost_;
+        if (bit_cost_idx2 > 0.) {
+          const double bit_cost_thresh = -bit_cost_idx2 * combine_cost_factor;
+          const double curr_cost_diff =
+              HistogramAddEval(histograms[idx1], histograms[idx2],
+                               cur_combo, bit_cost_thresh);
+          if (curr_cost_diff < bit_cost_thresh) {
+            // Try to merge two histograms only if the combo is a trivial one or
+            // the two candidate histograms are already non-trivial.
+            // For some images, 'try_combine' turns out to be false for a lot of
+            // histogram pairs. In that case, we fallback to combining
+            // histograms as usual to avoid increasing the header size.
+            const int try_combine =
+                (cur_combo->trivial_symbol_ != VP8L_NON_TRIVIAL_SYM) ||
+                ((histograms[idx1]->trivial_symbol_ == VP8L_NON_TRIVIAL_SYM) &&
+                 (histograms[idx2]->trivial_symbol_ == VP8L_NON_TRIVIAL_SYM));
+            const int max_combine_failures = 32;
+            if (try_combine || (num_combine_failures >= max_combine_failures)) {
+              HistogramSwap(&cur_combo, &histograms[idx1]);
+              histograms[idx2]->bit_cost_ = 0.;
+            } else {
+              ++num_combine_failures;
+            }
+          }
+        }
+      }
+    }
+    if (low_effort) {
+      // Update the bit_cost for the merged histograms (per bin index).
+      UpdateHistogramCost(histograms[idx1]);
+    }
+  }
+  HistogramCompactBins(image_histo);
+  return cur_combo;
+}
+
+static uint32_t MyRand(uint32_t *seed) {
+  *seed *= 16807U;
+  if (*seed == 0) {
+    *seed = 1;
+  }
+  return *seed;
+}
+
+// -----------------------------------------------------------------------------
+// Histogram pairs priority queue
+
+// Pair of histograms. Negative idx1 value means that pair is out-of-date.
+typedef struct {
+  int idx1;
+  int idx2;
+  double cost_diff;
+  double cost_combo;
+} HistogramPair;
+
+typedef struct {
+  HistogramPair* heap;
+  int* positions;
+  int size;
+  int max_index;
+} HistoHeap;
+
+static int HistoHeapInit(HistoHeap* const histo_heap, const int max_index) {
+  histo_heap->size = 0;
+  histo_heap->max_index = max_index;
+  histo_heap->heap = WebPSafeMalloc(max_index * max_index,
+                                    sizeof(*histo_heap->heap));
+  histo_heap->positions = WebPSafeMalloc(max_index * max_index,
+                                         sizeof(*histo_heap->positions));
+  return histo_heap->heap != NULL && histo_heap->positions != NULL;
+}
+
+static void HistoHeapClear(HistoHeap* const histo_heap) {
+  assert(histo_heap != NULL);
+  WebPSafeFree(histo_heap->heap);
+  WebPSafeFree(histo_heap->positions);
+}
+
+static void SwapHistogramPairs(HistogramPair *p1,
+                               HistogramPair *p2) {
+  const HistogramPair tmp = *p1;
+  *p1 = *p2;
+  *p2 = tmp;
+}
+
+// Given a valid min-heap in range [0, heap_size-1) this function places value
+// heap[heap_size-1] into right location within heap and sets its position in
+// positions array.
+static void HeapPush(HistoHeap* const histo_heap) {
+  HistogramPair* const heap = histo_heap->heap - 1;
+  int* const positions = histo_heap->positions;
+  const int max_index = histo_heap->max_index;
+  int v;
+  ++histo_heap->size;
+  v = histo_heap->size;
+  while (v > 1 && heap[v].cost_diff < heap[v >> 1].cost_diff) {
+    SwapHistogramPairs(&heap[v], &heap[v >> 1]);
+    // Change position of moved pair in heap.
+    if (heap[v].idx1 >= 0) {
+      const int pos = heap[v].idx1 * max_index + heap[v].idx2;
+      assert(pos >= 0 && pos < max_index * max_index);
+      positions[pos] = v;
+    }
+    v >>= 1;
+  }
+  positions[heap[v].idx1 * max_index + heap[v].idx2] = v;
+}
+
+// Given a valid min-heap in range [0, heap_size) this function shortens heap
+// range by one and places element with the lowest value to (heap_size-1).
+static void HeapPop(HistoHeap* const histo_heap) {
+  HistogramPair* const heap = histo_heap->heap - 1;
+  int* const positions = histo_heap->positions;
+  const int heap_size = histo_heap->size;
+  const int max_index = histo_heap->max_index;
+  int v = 1;
+  if (heap[v].idx1 >= 0) {
+    positions[heap[v].idx1 * max_index + heap[v].idx2] = -1;
+  }
+  SwapHistogramPairs(&heap[v], &heap[heap_size]);
+  while ((v << 1) < heap_size) {
+    int son = (heap[v << 1].cost_diff < heap[v].cost_diff) ? (v << 1) : v;
+    if (((v << 1) + 1) < heap_size &&
+        heap[(v << 1) + 1].cost_diff < heap[son].cost_diff) {
+      son = (v << 1) + 1;
+    }
+    if (son == v) break;
+    SwapHistogramPairs(&heap[v], &heap[son]);
+    // Change position of moved pair in heap.
+    if (heap[v].idx1 >= 0) {
+      positions[heap[v].idx1 * max_index + heap[v].idx2] = v;
+    }
+    v = son;
+  }
+  if (heap[v].idx1 >= 0) {
+    positions[heap[v].idx1 * max_index + heap[v].idx2] = v;
+  }
+  --histo_heap->size;
+}
+
+// -----------------------------------------------------------------------------
+
+static void PreparePair(VP8LHistogram** histograms, int idx1, int idx2,
+                        HistogramPair* const pair,
+                        VP8LHistogram* const histos) {
+  if (idx1 > idx2) {
+    const int tmp = idx2;
+    idx2 = idx1;
+    idx1 = tmp;
+  }
+  pair->idx1 = idx1;
+  pair->idx2 = idx2;
+  pair->cost_diff =
+      HistogramAddEval(histograms[idx1], histograms[idx2], histos, 0);
+  pair->cost_combo = histos->bit_cost_;
+}
+
+#define POSITION_INVALID (-1)
+
+// Invalidates pairs intersecting (idx1, idx2) in heap.
+static void InvalidatePairs(int idx1, int idx2,
+                            const HistoHeap* const histo_heap) {
+  HistogramPair* const heap = histo_heap->heap - 1;
+  int* const positions = histo_heap->positions;
+  const int max_index = histo_heap->max_index;
+  int i;
+  for (i = 0; i < idx1; ++i) {
+    const int pos = positions[i * max_index + idx1];
+    if (pos >= 0) {
+      heap[pos].idx1 = POSITION_INVALID;
+    }
+  }
+  for (i = idx1 + 1; i < max_index; ++i) {
+    const int pos = positions[idx1 * max_index + i];
+    if (pos >= 0) {
+      heap[pos].idx1 = POSITION_INVALID;
+    }
+  }
+  for (i = 0; i < idx2; ++i) {
+    const int pos = positions[i * max_index + idx2];
+    if (pos >= 0) {
+      heap[pos].idx1 = POSITION_INVALID;
+    }
+  }
+  for (i = idx2 + 1; i < max_index; ++i) {
+    const int pos = positions[idx2 * max_index + i];
+    if (pos >= 0) {
+      heap[pos].idx1 = POSITION_INVALID;
+    }
+  }
+}
+
+// Combines histograms by continuously choosing the one with the highest cost
+// reduction.
+static int HistogramCombineGreedy(VP8LHistogramSet* const image_histo,
+                                  VP8LHistogram* const histos) {
+  int ok = 0;
+  int image_histo_size = image_histo->size;
+  int i, j;
+  VP8LHistogram** const histograms = image_histo->histograms;
+  // Indexes of remaining histograms.
+  int* const clusters = WebPSafeMalloc(image_histo_size, sizeof(*clusters));
+  // Heap of histogram pairs.
+  HistoHeap histo_heap;
+
+  if (!HistoHeapInit(&histo_heap, image_histo_size) || clusters == NULL) {
+    goto End;
+  }
+
+  for (i = 0; i < image_histo_size; ++i) {
+    // Initialize clusters indexes.
+    clusters[i] = i;
+    for (j = i + 1; j < image_histo_size; ++j) {
+      // Initialize positions array.
+      histo_heap.positions[i * histo_heap.max_index + j] = POSITION_INVALID;
+      PreparePair(histograms, i, j, &histo_heap.heap[histo_heap.size], histos);
+      if (histo_heap.heap[histo_heap.size].cost_diff < 0) {
+        HeapPush(&histo_heap);
+      }
+    }
+  }
+
+  while (image_histo_size > 1 && histo_heap.size > 0) {
+    const int idx1 = histo_heap.heap[0].idx1;
+    const int idx2 = histo_heap.heap[0].idx2;
+    VP8LHistogramAdd(histograms[idx2], histograms[idx1], histograms[idx1]);
+    histograms[idx1]->bit_cost_ = histo_heap.heap[0].cost_combo;
+    // Remove merged histogram.
+    for (i = 0; i + 1 < image_histo_size; ++i) {
+      if (clusters[i] >= idx2) {
+        clusters[i] = clusters[i + 1];
+      }
+    }
+    --image_histo_size;
+
+    // Invalidate pairs intersecting the just combined best pair.
+    InvalidatePairs(idx1, idx2, &histo_heap);
+
+    // Pop invalid pairs from the top of the heap.
+    while (histo_heap.size > 0 && histo_heap.heap[0].idx1 < 0) {
+      HeapPop(&histo_heap);
+    }
+
+    // Push new pairs formed with combined histogram to the heap.
+    for (i = 0; i < image_histo_size; ++i) {
+      if (clusters[i] != idx1) {
+        PreparePair(histograms, idx1, clusters[i],
+                    &histo_heap.heap[histo_heap.size], histos);
+        if (histo_heap.heap[histo_heap.size].cost_diff < 0) {
+          HeapPush(&histo_heap);
+        }
+      }
+    }
+  }
+  // Move remaining histograms to the beginning of the array.
+  for (i = 0; i < image_histo_size; ++i) {
+    if (i != clusters[i]) {  // swap the two histograms
+      HistogramSwap(&histograms[i], &histograms[clusters[i]]);
+    }
+  }
+
+  image_histo->size = image_histo_size;
+  ok = 1;
+
+ End:
+  WebPSafeFree(clusters);
+  HistoHeapClear(&histo_heap);
+  return ok;
+}
+
+static VP8LHistogram* HistogramCombineStochastic(
+    VP8LHistogramSet* const image_histo,
+    VP8LHistogram* tmp_histo,
+    VP8LHistogram* best_combo,
+    int quality, int min_cluster_size) {
+  int iter;
+  uint32_t seed = 0;
+  int tries_with_no_success = 0;
+  int image_histo_size = image_histo->size;
+  const int iter_mult = (quality < 25) ? 2 : 2 + (quality - 25) / 8;
+  const int outer_iters = image_histo_size * iter_mult;
+  const int num_pairs = image_histo_size / 2;
+  const int num_tries_no_success = outer_iters / 2;
+  VP8LHistogram** const histograms = image_histo->histograms;
+
+  // Collapse similar histograms in 'image_histo'.
+  ++min_cluster_size;
+  for (iter = 0;
+       iter < outer_iters && image_histo_size >= min_cluster_size;
+       ++iter) {
+    double best_cost_diff = 0.;
+    int best_idx1 = -1, best_idx2 = 1;
+    int j;
+    const int num_tries =
+        (num_pairs < image_histo_size) ? num_pairs : image_histo_size;
+    seed += iter;
+    for (j = 0; j < num_tries; ++j) {
+      double curr_cost_diff;
+      // Choose two histograms at random and try to combine them.
+      const uint32_t idx1 = MyRand(&seed) % image_histo_size;
+      const uint32_t tmp = (j & 7) + 1;
+      const uint32_t diff =
+          (tmp < 3) ? tmp : MyRand(&seed) % (image_histo_size - 1);
+      const uint32_t idx2 = (idx1 + diff + 1) % image_histo_size;
+      if (idx1 == idx2) {
+        continue;
+      }
+
+      // Calculate cost reduction on combining.
+      curr_cost_diff = HistogramAddEval(histograms[idx1], histograms[idx2],
+                                        tmp_histo, best_cost_diff);
+      if (curr_cost_diff < best_cost_diff) {    // found a better pair?
+        HistogramSwap(&best_combo, &tmp_histo);
+        best_cost_diff = curr_cost_diff;
+        best_idx1 = idx1;
+        best_idx2 = idx2;
+      }
+    }
+
+    if (best_idx1 >= 0) {
+      HistogramSwap(&best_combo, &histograms[best_idx1]);
+      // swap best_idx2 slot with last one (which is now unused)
+      --image_histo_size;
+      if (best_idx2 != image_histo_size) {
+        HistogramSwap(&histograms[image_histo_size], &histograms[best_idx2]);
+        histograms[image_histo_size] = NULL;
+      }
+      tries_with_no_success = 0;
+    }
+    if (++tries_with_no_success >= num_tries_no_success) {
+      break;
+    }
+  }
+  image_histo->size = image_histo_size;
+  return best_combo;
+}
+
+// -----------------------------------------------------------------------------
+// Histogram refinement
+
+// Find the best 'out' histogram for each of the 'in' histograms.
+// Note: we assume that out[]->bit_cost_ is already up-to-date.
+static void HistogramRemap(const VP8LHistogramSet* const orig_histo,
+                           const VP8LHistogramSet* const image_histo,
+                           uint16_t* const symbols) {
+  int i;
+  VP8LHistogram** const orig_histograms = orig_histo->histograms;
+  VP8LHistogram** const histograms = image_histo->histograms;
+  const int orig_histo_size = orig_histo->size;
+  const int image_histo_size = image_histo->size;
+  if (image_histo_size > 1) {
+    for (i = 0; i < orig_histo_size; ++i) {
+      int best_out = 0;
+      double best_bits =
+          HistogramAddThresh(histograms[0], orig_histograms[i], MAX_COST);
+      int k;
+      for (k = 1; k < image_histo_size; ++k) {
+        const double cur_bits =
+            HistogramAddThresh(histograms[k], orig_histograms[i], best_bits);
+        if (cur_bits < best_bits) {
+          best_bits = cur_bits;
+          best_out = k;
+        }
+      }
+      symbols[i] = best_out;
+    }
+  } else {
+    assert(image_histo_size == 1);
+    for (i = 0; i < orig_histo_size; ++i) {
+      symbols[i] = 0;
+    }
+  }
+
+  // Recompute each out based on raw and symbols.
+  for (i = 0; i < image_histo_size; ++i) {
+    HistogramClear(histograms[i]);
+  }
+
+  for (i = 0; i < orig_histo_size; ++i) {
+    const int idx = symbols[i];
+    VP8LHistogramAdd(orig_histograms[i], histograms[idx], histograms[idx]);
+  }
+}
+
+static double GetCombineCostFactor(int histo_size, int quality) {
+  double combine_cost_factor = 0.16;
+  if (quality < 90) {
+    if (histo_size > 256) combine_cost_factor /= 2.;
+    if (histo_size > 512) combine_cost_factor /= 2.;
+    if (histo_size > 1024) combine_cost_factor /= 2.;
+    if (quality <= 50) combine_cost_factor /= 2.;
+  }
+  return combine_cost_factor;
+}
+
+int VP8LGetHistoImageSymbols(int xsize, int ysize,
+                             const VP8LBackwardRefs* const refs,
+                             int quality, int low_effort,
+                             int histo_bits, int cache_bits,
+                             VP8LHistogramSet* const image_histo,
+                             VP8LHistogramSet* const tmp_histos,
+                             uint16_t* const histogram_symbols) {
+  int ok = 0;
+  const int histo_xsize = histo_bits ? VP8LSubSampleSize(xsize, histo_bits) : 1;
+  const int histo_ysize = histo_bits ? VP8LSubSampleSize(ysize, histo_bits) : 1;
+  const int image_histo_raw_size = histo_xsize * histo_ysize;
+  const int entropy_combine_num_bins = low_effort ? NUM_PARTITIONS : BIN_SIZE;
+
+  // The bin_map for every bin follows following semantics:
+  // bin_map[n][0] = num_histo; // The number of histograms in that bin.
+  // bin_map[n][1] = index of first histogram in that bin;
+  // bin_map[n][num_histo] = index of last histogram in that bin;
+  // bin_map[n][num_histo + 1] ... bin_map[n][bin_depth - 1] = unused indices.
+  const int bin_depth = image_histo_raw_size + 1;
+  int16_t* bin_map = NULL;
+  VP8LHistogramSet* const orig_histo =
+      VP8LAllocateHistogramSet(image_histo_raw_size, cache_bits);
+  VP8LHistogram* cur_combo;
+  const int entropy_combine =
+      (orig_histo->size > entropy_combine_num_bins * 2) && (quality < 100);
+
+  if (orig_histo == NULL) goto Error;
+
+  // Don't attempt linear bin-partition heuristic for:
+  // histograms of small sizes, as bin_map will be very sparse and;
+  // Maximum quality (q==100), to preserve the compression gains at that level.
+  if (entropy_combine) {
+    const int bin_map_size = bin_depth * entropy_combine_num_bins;
+    bin_map = (int16_t*)WebPSafeCalloc(bin_map_size, sizeof(*bin_map));
+    if (bin_map == NULL) goto Error;
+  }
+
+  // Construct the histograms from backward references.
+  HistogramBuild(xsize, histo_bits, refs, orig_histo);
+  // Copies the histograms and computes its bit_cost.
+  HistogramCopyAndAnalyze(orig_histo, image_histo);
+
+  cur_combo = tmp_histos->histograms[1];  // pick up working slot
+  if (entropy_combine) {
+    const double combine_cost_factor =
+        GetCombineCostFactor(image_histo_raw_size, quality);
+    HistogramAnalyzeEntropyBin(orig_histo, bin_map, low_effort);
+    // Collapse histograms with similar entropy.
+    cur_combo = HistogramCombineEntropyBin(image_histo, cur_combo, bin_map,
+                                           bin_depth, entropy_combine_num_bins,
+                                           combine_cost_factor, low_effort);
+  }
+
+  // Don't combine the histograms using stochastic and greedy heuristics for
+  // low-effort compression mode.
+  if (!low_effort || !entropy_combine) {
+    const float x = quality / 100.f;
+    // cubic ramp between 1 and MAX_HISTO_GREEDY:
+    const int threshold_size = (int)(1 + (x * x * x) * (MAX_HISTO_GREEDY - 1));
+    cur_combo = HistogramCombineStochastic(image_histo,
+                                           tmp_histos->histograms[0],
+                                           cur_combo, quality, threshold_size);
+    if ((image_histo->size <= threshold_size) &&
+        !HistogramCombineGreedy(image_histo, cur_combo)) {
+      goto Error;
+    }
+  }
+
+  // TODO(vikasa): Optimize HistogramRemap for low-effort compression mode also.
+  // Find the optimal map from original histograms to the final ones.
+  HistogramRemap(orig_histo, image_histo, histogram_symbols);
+
+  ok = 1;
+
+ Error:
+  WebPSafeFree(bin_map);
+  VP8LFreeHistogramSet(orig_histo);
+  return ok;
+}
diff --git a/Source/LibWebP/src/enc/enc.iterator.c b/Source/LibWebP/src/enc/enc.iterator.c
new file mode 100644
index 0000000..0b13834
--- /dev/null
+++ b/Source/LibWebP/src/enc/enc.iterator.c
@@ -0,0 +1,456 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// VP8Iterator: block iterator
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include <string.h>
+
+#include "./vp8enci.h"
+
+//------------------------------------------------------------------------------
+// VP8Iterator
+//------------------------------------------------------------------------------
+
+static void InitLeft(VP8EncIterator* const it) {
+  it->y_left_[-1] = it->u_left_[-1] = it->v_left_[-1] =
+      (it->y_ > 0) ? 129 : 127;
+  memset(it->y_left_, 129, 16);
+  memset(it->u_left_, 129, 8);
+  memset(it->v_left_, 129, 8);
+  it->left_nz_[8] = 0;
+}
+
+static void InitTop(VP8EncIterator* const it) {
+  const VP8Encoder* const enc = it->enc_;
+  const size_t top_size = enc->mb_w_ * 16;
+  memset(enc->y_top_, 127, 2 * top_size);
+  memset(enc->nz_, 0, enc->mb_w_ * sizeof(*enc->nz_));
+}
+
+void VP8IteratorSetRow(VP8EncIterator* const it, int y) {
+  VP8Encoder* const enc = it->enc_;
+  it->x_ = 0;
+  it->y_ = y;
+  it->bw_ = &enc->parts_[y & (enc->num_parts_ - 1)];
+  it->preds_ = enc->preds_ + y * 4 * enc->preds_w_;
+  it->nz_ = enc->nz_;
+  it->mb_ = enc->mb_info_ + y * enc->mb_w_;
+  it->y_top_ = enc->y_top_;
+  it->uv_top_ = enc->uv_top_;
+  InitLeft(it);
+}
+
+void VP8IteratorReset(VP8EncIterator* const it) {
+  VP8Encoder* const enc = it->enc_;
+  VP8IteratorSetRow(it, 0);
+  VP8IteratorSetCountDown(it, enc->mb_w_ * enc->mb_h_);  // default
+  InitTop(it);
+  InitLeft(it);
+  memset(it->bit_count_, 0, sizeof(it->bit_count_));
+  it->do_trellis_ = 0;
+}
+
+void VP8IteratorSetCountDown(VP8EncIterator* const it, int count_down) {
+  it->count_down_ = it->count_down0_ = count_down;
+}
+
+int VP8IteratorIsDone(const VP8EncIterator* const it) {
+  return (it->count_down_ <= 0);
+}
+
+void VP8IteratorInit(VP8Encoder* const enc, VP8EncIterator* const it) {
+  it->enc_ = enc;
+  it->y_stride_  = enc->pic_->y_stride;
+  it->uv_stride_ = enc->pic_->uv_stride;
+  it->yuv_in_   = (uint8_t*)DO_ALIGN(it->yuv_mem_);
+  it->yuv_out_  = it->yuv_in_ + YUV_SIZE;
+  it->yuv_out2_ = it->yuv_out_ + YUV_SIZE;
+  it->yuv_p_    = it->yuv_out2_ + YUV_SIZE;
+  it->lf_stats_ = enc->lf_stats_;
+  it->percent0_ = enc->percent_;
+  it->y_left_ = (uint8_t*)DO_ALIGN(it->yuv_left_mem_ + 1);
+  it->u_left_ = it->y_left_ + 16 + 16;
+  it->v_left_ = it->u_left_ + 16;
+  VP8IteratorReset(it);
+}
+
+int VP8IteratorProgress(const VP8EncIterator* const it, int delta) {
+  VP8Encoder* const enc = it->enc_;
+  if (delta && enc->pic_->progress_hook != NULL) {
+    const int done = it->count_down0_ - it->count_down_;
+    const int percent = (it->count_down0_ <= 0)
+                      ? it->percent0_
+                      : it->percent0_ + delta * done / it->count_down0_;
+    return WebPReportProgress(enc->pic_, percent, &enc->percent_);
+  }
+  return 1;
+}
+
+//------------------------------------------------------------------------------
+// Import the source samples into the cache. Takes care of replicating
+// boundary pixels if necessary.
+
+static WEBP_INLINE int MinSize(int a, int b) { return (a < b) ? a : b; }
+
+static void ImportBlock(const uint8_t* src, int src_stride,
+                        uint8_t* dst, int w, int h, int size) {
+  int i;
+  for (i = 0; i < h; ++i) {
+    memcpy(dst, src, w);
+    if (w < size) {
+      memset(dst + w, dst[w - 1], size - w);
+    }
+    dst += BPS;
+    src += src_stride;
+  }
+  for (i = h; i < size; ++i) {
+    memcpy(dst, dst - BPS, size);
+    dst += BPS;
+  }
+}
+
+static void ImportLine(const uint8_t* src, int src_stride,
+                       uint8_t* dst, int len, int total_len) {
+  int i;
+  for (i = 0; i < len; ++i, src += src_stride) dst[i] = *src;
+  for (; i < total_len; ++i) dst[i] = dst[len - 1];
+}
+
+void VP8IteratorImport(VP8EncIterator* const it, uint8_t* tmp_32) {
+  const VP8Encoder* const enc = it->enc_;
+  const int x = it->x_, y = it->y_;
+  const WebPPicture* const pic = enc->pic_;
+  const uint8_t* const ysrc = pic->y + (y * pic->y_stride  + x) * 16;
+  const uint8_t* const usrc = pic->u + (y * pic->uv_stride + x) * 8;
+  const uint8_t* const vsrc = pic->v + (y * pic->uv_stride + x) * 8;
+  const int w = MinSize(pic->width - x * 16, 16);
+  const int h = MinSize(pic->height - y * 16, 16);
+  const int uv_w = (w + 1) >> 1;
+  const int uv_h = (h + 1) >> 1;
+
+  ImportBlock(ysrc, pic->y_stride,  it->yuv_in_ + Y_OFF, w, h, 16);
+  ImportBlock(usrc, pic->uv_stride, it->yuv_in_ + U_OFF, uv_w, uv_h, 8);
+  ImportBlock(vsrc, pic->uv_stride, it->yuv_in_ + V_OFF, uv_w, uv_h, 8);
+
+  if (tmp_32 == NULL) return;
+
+  // Import source (uncompressed) samples into boundary.
+  if (x == 0) {
+    InitLeft(it);
+  } else {
+    if (y == 0) {
+      it->y_left_[-1] = it->u_left_[-1] = it->v_left_[-1] = 127;
+    } else {
+      it->y_left_[-1] = ysrc[- 1 - pic->y_stride];
+      it->u_left_[-1] = usrc[- 1 - pic->uv_stride];
+      it->v_left_[-1] = vsrc[- 1 - pic->uv_stride];
+    }
+    ImportLine(ysrc - 1, pic->y_stride,  it->y_left_, h,   16);
+    ImportLine(usrc - 1, pic->uv_stride, it->u_left_, uv_h, 8);
+    ImportLine(vsrc - 1, pic->uv_stride, it->v_left_, uv_h, 8);
+  }
+
+  it->y_top_  = tmp_32 + 0;
+  it->uv_top_ = tmp_32 + 16;
+  if (y == 0) {
+    memset(tmp_32, 127, 32 * sizeof(*tmp_32));
+  } else {
+    ImportLine(ysrc - pic->y_stride,  1, tmp_32,          w,   16);
+    ImportLine(usrc - pic->uv_stride, 1, tmp_32 + 16,     uv_w, 8);
+    ImportLine(vsrc - pic->uv_stride, 1, tmp_32 + 16 + 8, uv_w, 8);
+  }
+}
+
+//------------------------------------------------------------------------------
+// Copy back the compressed samples into user space if requested.
+
+static void ExportBlock(const uint8_t* src, uint8_t* dst, int dst_stride,
+                        int w, int h) {
+  while (h-- > 0) {
+    memcpy(dst, src, w);
+    dst += dst_stride;
+    src += BPS;
+  }
+}
+
+void VP8IteratorExport(const VP8EncIterator* const it) {
+  const VP8Encoder* const enc = it->enc_;
+  if (enc->config_->show_compressed) {
+    const int x = it->x_, y = it->y_;
+    const uint8_t* const ysrc = it->yuv_out_ + Y_OFF;
+    const uint8_t* const usrc = it->yuv_out_ + U_OFF;
+    const uint8_t* const vsrc = it->yuv_out_ + V_OFF;
+    const WebPPicture* const pic = enc->pic_;
+    uint8_t* const ydst = pic->y + (y * pic->y_stride + x) * 16;
+    uint8_t* const udst = pic->u + (y * pic->uv_stride + x) * 8;
+    uint8_t* const vdst = pic->v + (y * pic->uv_stride + x) * 8;
+    int w = (pic->width - x * 16);
+    int h = (pic->height - y * 16);
+
+    if (w > 16) w = 16;
+    if (h > 16) h = 16;
+
+    // Luma plane
+    ExportBlock(ysrc, ydst, pic->y_stride, w, h);
+
+    {   // U/V planes
+      const int uv_w = (w + 1) >> 1;
+      const int uv_h = (h + 1) >> 1;
+      ExportBlock(usrc, udst, pic->uv_stride, uv_w, uv_h);
+      ExportBlock(vsrc, vdst, pic->uv_stride, uv_w, uv_h);
+    }
+  }
+}
+
+//------------------------------------------------------------------------------
+// Non-zero contexts setup/teardown
+
+// Nz bits:
+//  0  1  2  3  Y
+//  4  5  6  7
+//  8  9 10 11
+// 12 13 14 15
+// 16 17        U
+// 18 19
+// 20 21        V
+// 22 23
+// 24           DC-intra16
+
+// Convert packed context to byte array
+#define BIT(nz, n) (!!((nz) & (1 << (n))))
+
+void VP8IteratorNzToBytes(VP8EncIterator* const it) {
+  const int tnz = it->nz_[0], lnz = it->nz_[-1];
+  int* const top_nz = it->top_nz_;
+  int* const left_nz = it->left_nz_;
+
+  // Top-Y
+  top_nz[0] = BIT(tnz, 12);
+  top_nz[1] = BIT(tnz, 13);
+  top_nz[2] = BIT(tnz, 14);
+  top_nz[3] = BIT(tnz, 15);
+  // Top-U
+  top_nz[4] = BIT(tnz, 18);
+  top_nz[5] = BIT(tnz, 19);
+  // Top-V
+  top_nz[6] = BIT(tnz, 22);
+  top_nz[7] = BIT(tnz, 23);
+  // DC
+  top_nz[8] = BIT(tnz, 24);
+
+  // left-Y
+  left_nz[0] = BIT(lnz,  3);
+  left_nz[1] = BIT(lnz,  7);
+  left_nz[2] = BIT(lnz, 11);
+  left_nz[3] = BIT(lnz, 15);
+  // left-U
+  left_nz[4] = BIT(lnz, 17);
+  left_nz[5] = BIT(lnz, 19);
+  // left-V
+  left_nz[6] = BIT(lnz, 21);
+  left_nz[7] = BIT(lnz, 23);
+  // left-DC is special, iterated separately
+}
+
+void VP8IteratorBytesToNz(VP8EncIterator* const it) {
+  uint32_t nz = 0;
+  const int* const top_nz = it->top_nz_;
+  const int* const left_nz = it->left_nz_;
+  // top
+  nz |= (top_nz[0] << 12) | (top_nz[1] << 13);
+  nz |= (top_nz[2] << 14) | (top_nz[3] << 15);
+  nz |= (top_nz[4] << 18) | (top_nz[5] << 19);
+  nz |= (top_nz[6] << 22) | (top_nz[7] << 23);
+  nz |= (top_nz[8] << 24);  // we propagate the _top_ bit, esp. for intra4
+  // left
+  nz |= (left_nz[0] << 3) | (left_nz[1] << 7);
+  nz |= (left_nz[2] << 11);
+  nz |= (left_nz[4] << 17) | (left_nz[6] << 21);
+
+  *it->nz_ = nz;
+}
+
+#undef BIT
+
+//------------------------------------------------------------------------------
+// Advance to the next position, doing the bookkeeping.
+
+void VP8IteratorSaveBoundary(VP8EncIterator* const it) {
+  VP8Encoder* const enc = it->enc_;
+  const int x = it->x_, y = it->y_;
+  const uint8_t* const ysrc = it->yuv_out_ + Y_OFF;
+  const uint8_t* const uvsrc = it->yuv_out_ + U_OFF;
+  if (x < enc->mb_w_ - 1) {   // left
+    int i;
+    for (i = 0; i < 16; ++i) {
+      it->y_left_[i] = ysrc[15 + i * BPS];
+    }
+    for (i = 0; i < 8; ++i) {
+      it->u_left_[i] = uvsrc[7 + i * BPS];
+      it->v_left_[i] = uvsrc[15 + i * BPS];
+    }
+    // top-left (before 'top'!)
+    it->y_left_[-1] = it->y_top_[15];
+    it->u_left_[-1] = it->uv_top_[0 + 7];
+    it->v_left_[-1] = it->uv_top_[8 + 7];
+  }
+  if (y < enc->mb_h_ - 1) {  // top
+    memcpy(it->y_top_, ysrc + 15 * BPS, 16);
+    memcpy(it->uv_top_, uvsrc + 7 * BPS, 8 + 8);
+  }
+}
+
+int VP8IteratorNext(VP8EncIterator* const it) {
+  it->preds_ += 4;
+  it->mb_ += 1;
+  it->nz_ += 1;
+  it->y_top_ += 16;
+  it->uv_top_ += 16;
+  it->x_ += 1;
+  if (it->x_ == it->enc_->mb_w_) {
+    VP8IteratorSetRow(it, ++it->y_);
+  }
+  return (0 < --it->count_down_);
+}
+
+//------------------------------------------------------------------------------
+// Helper function to set mode properties
+
+void VP8SetIntra16Mode(const VP8EncIterator* const it, int mode) {
+  uint8_t* preds = it->preds_;
+  int y;
+  for (y = 0; y < 4; ++y) {
+    memset(preds, mode, 4);
+    preds += it->enc_->preds_w_;
+  }
+  it->mb_->type_ = 1;
+}
+
+void VP8SetIntra4Mode(const VP8EncIterator* const it, const uint8_t* modes) {
+  uint8_t* preds = it->preds_;
+  int y;
+  for (y = 4; y > 0; --y) {
+    memcpy(preds, modes, 4 * sizeof(*modes));
+    preds += it->enc_->preds_w_;
+    modes += 4;
+  }
+  it->mb_->type_ = 0;
+}
+
+void VP8SetIntraUVMode(const VP8EncIterator* const it, int mode) {
+  it->mb_->uv_mode_ = mode;
+}
+
+void VP8SetSkip(const VP8EncIterator* const it, int skip) {
+  it->mb_->skip_ = skip;
+}
+
+void VP8SetSegment(const VP8EncIterator* const it, int segment) {
+  it->mb_->segment_ = segment;
+}
+
+//------------------------------------------------------------------------------
+// Intra4x4 sub-blocks iteration
+//
+//  We store and update the boundary samples into an array of 37 pixels. They
+//  are updated as we iterate and reconstructs each intra4x4 blocks in turn.
+//  The position of the samples has the following snake pattern:
+//
+// 16|17 18 19 20|21 22 23 24|25 26 27 28|29 30 31 32|33 34 35 36  <- Top-right
+// --+-----------+-----------+-----------+-----------+
+// 15|         19|         23|         27|         31|
+// 14|         18|         22|         26|         30|
+// 13|         17|         21|         25|         29|
+// 12|13 14 15 16|17 18 19 20|21 22 23 24|25 26 27 28|
+// --+-----------+-----------+-----------+-----------+
+// 11|         15|         19|         23|         27|
+// 10|         14|         18|         22|         26|
+//  9|         13|         17|         21|         25|
+//  8| 9 10 11 12|13 14 15 16|17 18 19 20|21 22 23 24|
+// --+-----------+-----------+-----------+-----------+
+//  7|         11|         15|         19|         23|
+//  6|         10|         14|         18|         22|
+//  5|          9|         13|         17|         21|
+//  4| 5  6  7  8| 9 10 11 12|13 14 15 16|17 18 19 20|
+// --+-----------+-----------+-----------+-----------+
+//  3|          7|         11|         15|         19|
+//  2|          6|         10|         14|         18|
+//  1|          5|          9|         13|         17|
+//  0| 1  2  3  4| 5  6  7  8| 9 10 11 12|13 14 15 16|
+// --+-----------+-----------+-----------+-----------+
+
+// Array to record the position of the top sample to pass to the prediction
+// functions in dsp.c.
+static const uint8_t VP8TopLeftI4[16] = {
+  17, 21, 25, 29,
+  13, 17, 21, 25,
+  9,  13, 17, 21,
+  5,   9, 13, 17
+};
+
+void VP8IteratorStartI4(VP8EncIterator* const it) {
+  const VP8Encoder* const enc = it->enc_;
+  int i;
+
+  it->i4_ = 0;    // first 4x4 sub-block
+  it->i4_top_ = it->i4_boundary_ + VP8TopLeftI4[0];
+
+  // Import the boundary samples
+  for (i = 0; i < 17; ++i) {    // left
+    it->i4_boundary_[i] = it->y_left_[15 - i];
+  }
+  for (i = 0; i < 16; ++i) {    // top
+    it->i4_boundary_[17 + i] = it->y_top_[i];
+  }
+  // top-right samples have a special case on the far right of the picture
+  if (it->x_ < enc->mb_w_ - 1) {
+    for (i = 16; i < 16 + 4; ++i) {
+      it->i4_boundary_[17 + i] = it->y_top_[i];
+    }
+  } else {    // else, replicate the last valid pixel four times
+    for (i = 16; i < 16 + 4; ++i) {
+      it->i4_boundary_[17 + i] = it->i4_boundary_[17 + 15];
+    }
+  }
+  VP8IteratorNzToBytes(it);  // import the non-zero context
+}
+
+int VP8IteratorRotateI4(VP8EncIterator* const it,
+                        const uint8_t* const yuv_out) {
+  const uint8_t* const blk = yuv_out + VP8Scan[it->i4_];
+  uint8_t* const top = it->i4_top_;
+  int i;
+
+  // Update the cache with 7 fresh samples
+  for (i = 0; i <= 3; ++i) {
+    top[-4 + i] = blk[i + 3 * BPS];   // store future top samples
+  }
+  if ((it->i4_ & 3) != 3) {  // if not on the right sub-blocks #3, #7, #11, #15
+    for (i = 0; i <= 2; ++i) {        // store future left samples
+      top[i] = blk[3 + (2 - i) * BPS];
+    }
+  } else {  // else replicate top-right samples, as says the specs.
+    for (i = 0; i <= 3; ++i) {
+      top[i] = top[i + 4];
+    }
+  }
+  // move pointers to next sub-block
+  ++it->i4_;
+  if (it->i4_ == 16) {    // we're done
+    return 0;
+  }
+
+  it->i4_top_ = it->i4_boundary_ + VP8TopLeftI4[it->i4_];
+  return 1;
+}
+
+//------------------------------------------------------------------------------
+
diff --git a/Source/LibWebP/src/enc/enc.near_lossless.c b/Source/LibWebP/src/enc/enc.near_lossless.c
new file mode 100644
index 0000000..52e8a61
--- /dev/null
+++ b/Source/LibWebP/src/enc/enc.near_lossless.c
@@ -0,0 +1,160 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Near-lossless image preprocessing adjusts pixel values to help
+// compressibility with a guarantee of maximum deviation between original and
+// resulting pixel values.
+//
+// Author: Jyrki Alakuijala (jyrki at google.com)
+// Converted to C by Aleksander Kramarz (akramarz at google.com)
+
+#include <stdlib.h>
+
+#include "../dsp/lossless.h"
+#include "../utils/utils.h"
+#include "./vp8enci.h"
+
+#define MIN_DIM_FOR_NEAR_LOSSLESS 64
+#define MAX_LIMIT_BITS             5
+
+// Computes quantized pixel value and distance from original value.
+static void GetValAndDistance(int a, int initial, int bits,
+                              int* const val, int* const distance) {
+  const int mask = ~((1 << bits) - 1);
+  *val = (initial & mask) | (initial >> (8 - bits));
+  *distance = 2 * abs(a - *val);
+}
+
+// Clamps the value to range [0, 255].
+static int Clamp8b(int val) {
+  const int min_val = 0;
+  const int max_val = 0xff;
+  return (val < min_val) ? min_val : (val > max_val) ? max_val : val;
+}
+
+// Quantizes values {a, a+(1<<bits), a-(1<<bits)} and returns the nearest one.
+static int FindClosestDiscretized(int a, int bits) {
+  int best_val = a, i;
+  int min_distance = 256;
+
+  for (i = -1; i <= 1; ++i) {
+    int candidate, distance;
+    const int val = Clamp8b(a + i * (1 << bits));
+    GetValAndDistance(a, val, bits, &candidate, &distance);
+    if (i != 0) {
+      ++distance;
+    }
+    // Smallest distance but favor i == 0 over i == -1 and i == 1
+    // since that keeps the overall intensity more constant in the
+    // images.
+    if (distance < min_distance) {
+      min_distance = distance;
+      best_val = candidate;
+    }
+  }
+  return best_val;
+}
+
+// Applies FindClosestDiscretized to all channels of pixel.
+static uint32_t ClosestDiscretizedArgb(uint32_t a, int bits) {
+  return
+      (FindClosestDiscretized(a >> 24, bits) << 24) |
+      (FindClosestDiscretized((a >> 16) & 0xff, bits) << 16) |
+      (FindClosestDiscretized((a >> 8) & 0xff, bits) << 8) |
+      (FindClosestDiscretized(a & 0xff, bits));
+}
+
+// Checks if distance between corresponding channel values of pixels a and b
+// is within the given limit.
+static int IsNear(uint32_t a, uint32_t b, int limit) {
+  int k;
+  for (k = 0; k < 4; ++k) {
+    const int delta =
+        (int)((a >> (k * 8)) & 0xff) - (int)((b >> (k * 8)) & 0xff);
+    if (delta >= limit || delta <= -limit) {
+      return 0;
+    }
+  }
+  return 1;
+}
+
+static int IsSmooth(const uint32_t* const prev_row,
+                    const uint32_t* const curr_row,
+                    const uint32_t* const next_row,
+                    int ix, int limit) {
+  // Check that all pixels in 4-connected neighborhood are smooth.
+  return (IsNear(curr_row[ix], curr_row[ix - 1], limit) &&
+          IsNear(curr_row[ix], curr_row[ix + 1], limit) &&
+          IsNear(curr_row[ix], prev_row[ix], limit) &&
+          IsNear(curr_row[ix], next_row[ix], limit));
+}
+
+// Adjusts pixel values of image with given maximum error.
+static void NearLossless(int xsize, int ysize, uint32_t* argb,
+                         int limit_bits, uint32_t* copy_buffer) {
+  int x, y;
+  const int limit = 1 << limit_bits;
+  uint32_t* prev_row = copy_buffer;
+  uint32_t* curr_row = prev_row + xsize;
+  uint32_t* next_row = curr_row + xsize;
+  memcpy(copy_buffer, argb, xsize * 2 * sizeof(argb[0]));
+
+  for (y = 1; y < ysize - 1; ++y) {
+    uint32_t* const curr_argb_row = argb + y * xsize;
+    uint32_t* const next_argb_row = curr_argb_row + xsize;
+    memcpy(next_row, next_argb_row, xsize * sizeof(argb[0]));
+    for (x = 1; x < xsize - 1; ++x) {
+      if (!IsSmooth(prev_row, curr_row, next_row, x, limit)) {
+        curr_argb_row[x] = ClosestDiscretizedArgb(curr_row[x], limit_bits);
+      }
+    }
+    {
+      // Three-way swap.
+      uint32_t* const temp = prev_row;
+      prev_row = curr_row;
+      curr_row = next_row;
+      next_row = temp;
+    }
+  }
+}
+
+static int QualityToLimitBits(int quality) {
+  // quality mapping:
+  //  0..19 -> 5
+  //  0..39 -> 4
+  //  0..59 -> 3
+  //  0..79 -> 2
+  //  0..99 -> 1
+  //  100   -> 0
+  return MAX_LIMIT_BITS - quality / 20;
+}
+
+int VP8ApplyNearLossless(int xsize, int ysize, uint32_t* argb, int quality) {
+  int i;
+  uint32_t* const copy_buffer =
+      (uint32_t*)WebPSafeMalloc(xsize * 3, sizeof(*copy_buffer));
+  const int limit_bits = QualityToLimitBits(quality);
+  assert(argb != NULL);
+  assert(limit_bits >= 0);
+  assert(limit_bits <= MAX_LIMIT_BITS);
+  if (copy_buffer == NULL) {
+    return 0;
+  }
+  // For small icon images, don't attempt to apply near-lossless compression.
+  if (xsize < MIN_DIM_FOR_NEAR_LOSSLESS && ysize < MIN_DIM_FOR_NEAR_LOSSLESS) {
+    WebPSafeFree(copy_buffer);
+    return 1;
+  }
+
+  for (i = limit_bits; i != 0; --i) {
+    NearLossless(xsize, ysize, argb, i, copy_buffer);
+  }
+  WebPSafeFree(copy_buffer);
+  return 1;
+}
diff --git a/Source/LibWebP/src/enc/enc.picture.c b/Source/LibWebP/src/enc/enc.picture.c
new file mode 100644
index 0000000..3ce0dc8
--- /dev/null
+++ b/Source/LibWebP/src/enc/enc.picture.c
@@ -0,0 +1,290 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// WebPPicture class basis
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include "./vp8enci.h"
+#include "../dsp/dsp.h"
+#include "../utils/utils.h"
+
+//------------------------------------------------------------------------------
+// WebPPicture
+//------------------------------------------------------------------------------
+
+static int DummyWriter(const uint8_t* data, size_t data_size,
+                       const WebPPicture* const picture) {
+  // The following are to prevent 'unused variable' error message.
+  (void)data;
+  (void)data_size;
+  (void)picture;
+  return 1;
+}
+
+int WebPPictureInitInternal(WebPPicture* picture, int version) {
+  if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_ENCODER_ABI_VERSION)) {
+    return 0;   // caller/system version mismatch!
+  }
+  if (picture != NULL) {
+    memset(picture, 0, sizeof(*picture));
+    picture->writer = DummyWriter;
+    WebPEncodingSetError(picture, VP8_ENC_OK);
+  }
+  return 1;
+}
+
+//------------------------------------------------------------------------------
+
+static void WebPPictureResetBufferARGB(WebPPicture* const picture) {
+  picture->memory_argb_ = NULL;
+  picture->argb = NULL;
+  picture->argb_stride = 0;
+}
+
+static void WebPPictureResetBufferYUVA(WebPPicture* const picture) {
+  picture->memory_ = NULL;
+  picture->y = picture->u = picture->v = picture->a = NULL;
+  picture->y_stride = picture->uv_stride = 0;
+  picture->a_stride = 0;
+}
+
+void WebPPictureResetBuffers(WebPPicture* const picture) {
+  WebPPictureResetBufferARGB(picture);
+  WebPPictureResetBufferYUVA(picture);
+}
+
+int WebPPictureAllocARGB(WebPPicture* const picture, int width, int height) {
+  void* memory;
+  const uint64_t argb_size = (uint64_t)width * height;
+
+  assert(picture != NULL);
+
+  WebPSafeFree(picture->memory_argb_);
+  WebPPictureResetBufferARGB(picture);
+
+  if (width <= 0 || height <= 0) {
+    return WebPEncodingSetError(picture, VP8_ENC_ERROR_BAD_DIMENSION);
+  }
+  // allocate a new buffer.
+  memory = WebPSafeMalloc(argb_size, sizeof(*picture->argb));
+  if (memory == NULL) {
+    return WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY);
+  }
+  // TODO(skal): align plane to cache line?
+  picture->memory_argb_ = memory;
+  picture->argb = (uint32_t*)memory;
+  picture->argb_stride = width;
+  return 1;
+}
+
+int WebPPictureAllocYUVA(WebPPicture* const picture, int width, int height) {
+  const WebPEncCSP uv_csp = picture->colorspace & WEBP_CSP_UV_MASK;
+  const int has_alpha = picture->colorspace & WEBP_CSP_ALPHA_BIT;
+  const int y_stride = width;
+  const int uv_width = (width + 1) >> 1;
+  const int uv_height = (height + 1) >> 1;
+  const int uv_stride = uv_width;
+  int a_width, a_stride;
+  uint64_t y_size, uv_size, a_size, total_size;
+  uint8_t* mem;
+
+  assert(picture != NULL);
+
+  WebPSafeFree(picture->memory_);
+  WebPPictureResetBufferYUVA(picture);
+
+  if (uv_csp != WEBP_YUV420) {
+    return WebPEncodingSetError(picture, VP8_ENC_ERROR_INVALID_CONFIGURATION);
+  }
+
+  // alpha
+  a_width = has_alpha ? width : 0;
+  a_stride = a_width;
+  y_size = (uint64_t)y_stride * height;
+  uv_size = (uint64_t)uv_stride * uv_height;
+  a_size =  (uint64_t)a_stride * height;
+
+  total_size = y_size + a_size + 2 * uv_size;
+
+  // Security and validation checks
+  if (width <= 0 || height <= 0 ||         // luma/alpha param error
+      uv_width < 0 || uv_height < 0) {     // u/v param error
+    return WebPEncodingSetError(picture, VP8_ENC_ERROR_BAD_DIMENSION);
+  }
+  // allocate a new buffer.
+  mem = (uint8_t*)WebPSafeMalloc(total_size, sizeof(*mem));
+  if (mem == NULL) {
+    return WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY);
+  }
+
+  // From now on, we're in the clear, we can no longer fail...
+  picture->memory_ = (void*)mem;
+  picture->y_stride  = y_stride;
+  picture->uv_stride = uv_stride;
+  picture->a_stride  = a_stride;
+
+  // TODO(skal): we could align the y/u/v planes and adjust stride.
+  picture->y = mem;
+  mem += y_size;
+
+  picture->u = mem;
+  mem += uv_size;
+  picture->v = mem;
+  mem += uv_size;
+
+  if (a_size > 0) {
+    picture->a = mem;
+    mem += a_size;
+  }
+  (void)mem;  // makes the static analyzer happy
+  return 1;
+}
+
+int WebPPictureAlloc(WebPPicture* picture) {
+  if (picture != NULL) {
+    const int width = picture->width;
+    const int height = picture->height;
+
+    WebPPictureFree(picture);   // erase previous buffer
+
+    if (!picture->use_argb) {
+      return WebPPictureAllocYUVA(picture, width, height);
+    } else {
+      return WebPPictureAllocARGB(picture, width, height);
+    }
+  }
+  return 1;
+}
+
+void WebPPictureFree(WebPPicture* picture) {
+  if (picture != NULL) {
+    WebPSafeFree(picture->memory_);
+    WebPSafeFree(picture->memory_argb_);
+    WebPPictureResetBuffers(picture);
+  }
+}
+
+//------------------------------------------------------------------------------
+// WebPMemoryWriter: Write-to-memory
+
+void WebPMemoryWriterInit(WebPMemoryWriter* writer) {
+  writer->mem = NULL;
+  writer->size = 0;
+  writer->max_size = 0;
+}
+
+int WebPMemoryWrite(const uint8_t* data, size_t data_size,
+                    const WebPPicture* picture) {
+  WebPMemoryWriter* const w = (WebPMemoryWriter*)picture->custom_ptr;
+  uint64_t next_size;
+  if (w == NULL) {
+    return 1;
+  }
+  next_size = (uint64_t)w->size + data_size;
+  if (next_size > w->max_size) {
+    uint8_t* new_mem;
+    uint64_t next_max_size = 2ULL * w->max_size;
+    if (next_max_size < next_size) next_max_size = next_size;
+    if (next_max_size < 8192ULL) next_max_size = 8192ULL;
+    new_mem = (uint8_t*)WebPSafeMalloc(next_max_size, 1);
+    if (new_mem == NULL) {
+      return 0;
+    }
+    if (w->size > 0) {
+      memcpy(new_mem, w->mem, w->size);
+    }
+    WebPSafeFree(w->mem);
+    w->mem = new_mem;
+    // down-cast is ok, thanks to WebPSafeMalloc
+    w->max_size = (size_t)next_max_size;
+  }
+  if (data_size > 0) {
+    memcpy(w->mem + w->size, data, data_size);
+    w->size += data_size;
+  }
+  return 1;
+}
+
+void WebPMemoryWriterClear(WebPMemoryWriter* writer) {
+  if (writer != NULL) {
+    WebPSafeFree(writer->mem);
+    writer->mem = NULL;
+    writer->size = 0;
+    writer->max_size = 0;
+  }
+}
+
+//------------------------------------------------------------------------------
+// Simplest high-level calls:
+
+typedef int (*Importer)(WebPPicture* const, const uint8_t* const, int);
+
+static size_t Encode(const uint8_t* rgba, int width, int height, int stride,
+                     Importer import, float quality_factor, int lossless,
+                     uint8_t** output) {
+  WebPPicture pic;
+  WebPConfig config;
+  WebPMemoryWriter wrt;
+  int ok;
+
+  if (!WebPConfigPreset(&config, WEBP_PRESET_DEFAULT, quality_factor) ||
+      !WebPPictureInit(&pic)) {
+    return 0;  // shouldn't happen, except if system installation is broken
+  }
+
+  config.lossless = !!lossless;
+  pic.use_argb = !!lossless;
+  pic.width = width;
+  pic.height = height;
+  pic.writer = WebPMemoryWrite;
+  pic.custom_ptr = &wrt;
+  WebPMemoryWriterInit(&wrt);
+
+  ok = import(&pic, rgba, stride) && WebPEncode(&config, &pic);
+  WebPPictureFree(&pic);
+  if (!ok) {
+    WebPMemoryWriterClear(&wrt);
+    *output = NULL;
+    return 0;
+  }
+  *output = wrt.mem;
+  return wrt.size;
+}
+
+#define ENCODE_FUNC(NAME, IMPORTER)                                     \
+size_t NAME(const uint8_t* in, int w, int h, int bps, float q,          \
+            uint8_t** out) {                                            \
+  return Encode(in, w, h, bps, IMPORTER, q, 0, out);                    \
+}
+
+ENCODE_FUNC(WebPEncodeRGB, WebPPictureImportRGB)
+ENCODE_FUNC(WebPEncodeBGR, WebPPictureImportBGR)
+ENCODE_FUNC(WebPEncodeRGBA, WebPPictureImportRGBA)
+ENCODE_FUNC(WebPEncodeBGRA, WebPPictureImportBGRA)
+
+#undef ENCODE_FUNC
+
+#define LOSSLESS_DEFAULT_QUALITY 70.
+#define LOSSLESS_ENCODE_FUNC(NAME, IMPORTER)                                 \
+size_t NAME(const uint8_t* in, int w, int h, int bps, uint8_t** out) {       \
+  return Encode(in, w, h, bps, IMPORTER, LOSSLESS_DEFAULT_QUALITY, 1, out);  \
+}
+
+LOSSLESS_ENCODE_FUNC(WebPEncodeLosslessRGB, WebPPictureImportRGB)
+LOSSLESS_ENCODE_FUNC(WebPEncodeLosslessBGR, WebPPictureImportBGR)
+LOSSLESS_ENCODE_FUNC(WebPEncodeLosslessRGBA, WebPPictureImportRGBA)
+LOSSLESS_ENCODE_FUNC(WebPEncodeLosslessBGRA, WebPPictureImportBGRA)
+
+#undef LOSSLESS_ENCODE_FUNC
+
+//------------------------------------------------------------------------------
diff --git a/Source/LibWebP/src/enc/enc.picture_csp.c b/Source/LibWebP/src/enc/enc.picture_csp.c
new file mode 100644
index 0000000..d70ce98
--- /dev/null
+++ b/Source/LibWebP/src/enc/enc.picture_csp.c
@@ -0,0 +1,1100 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// WebPPicture utils for colorspace conversion
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include <assert.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include "./vp8enci.h"
+#include "../utils/random.h"
+#include "../utils/utils.h"
+#include "../dsp/yuv.h"
+
+// Uncomment to disable gamma-compression during RGB->U/V averaging
+#define USE_GAMMA_COMPRESSION
+
+// If defined, use table to compute x / alpha.
+#define USE_INVERSE_ALPHA_TABLE
+
+static const union {
+  uint32_t argb;
+  uint8_t  bytes[4];
+} test_endian = { 0xff000000u };
+#define ALPHA_IS_LAST (test_endian.bytes[3] == 0xff)
+
+//------------------------------------------------------------------------------
+// Detection of non-trivial transparency
+
+// Returns true if alpha[] has non-0xff values.
+static int CheckNonOpaque(const uint8_t* alpha, int width, int height,
+                          int x_step, int y_step) {
+  if (alpha == NULL) return 0;
+  while (height-- > 0) {
+    int x;
+    for (x = 0; x < width * x_step; x += x_step) {
+      if (alpha[x] != 0xff) return 1;  // TODO(skal): check 4/8 bytes at a time.
+    }
+    alpha += y_step;
+  }
+  return 0;
+}
+
+// Checking for the presence of non-opaque alpha.
+int WebPPictureHasTransparency(const WebPPicture* picture) {
+  if (picture == NULL) return 0;
+  if (!picture->use_argb) {
+    return CheckNonOpaque(picture->a, picture->width, picture->height,
+                          1, picture->a_stride);
+  } else {
+    int x, y;
+    const uint32_t* argb = picture->argb;
+    if (argb == NULL) return 0;
+    for (y = 0; y < picture->height; ++y) {
+      for (x = 0; x < picture->width; ++x) {
+        if (argb[x] < 0xff000000u) return 1;   // test any alpha values != 0xff
+      }
+      argb += picture->argb_stride;
+    }
+  }
+  return 0;
+}
+
+//------------------------------------------------------------------------------
+// Code for gamma correction
+
+#if defined(USE_GAMMA_COMPRESSION)
+
+// gamma-compensates loss of resolution during chroma subsampling
+#define kGamma 0.80      // for now we use a different gamma value than kGammaF
+#define kGammaFix 12     // fixed-point precision for linear values
+#define kGammaScale ((1 << kGammaFix) - 1)
+#define kGammaTabFix 7   // fixed-point fractional bits precision
+#define kGammaTabScale (1 << kGammaTabFix)
+#define kGammaTabRounder (kGammaTabScale >> 1)
+#define kGammaTabSize (1 << (kGammaFix - kGammaTabFix))
+
+static int kLinearToGammaTab[kGammaTabSize + 1];
+static uint16_t kGammaToLinearTab[256];
+static volatile int kGammaTablesOk = 0;
+
+static WEBP_TSAN_IGNORE_FUNCTION void InitGammaTables(void) {
+  if (!kGammaTablesOk) {
+    int v;
+    const double scale = (double)(1 << kGammaTabFix) / kGammaScale;
+    const double norm = 1. / 255.;
+    for (v = 0; v <= 255; ++v) {
+      kGammaToLinearTab[v] =
+          (uint16_t)(pow(norm * v, kGamma) * kGammaScale + .5);
+    }
+    for (v = 0; v <= kGammaTabSize; ++v) {
+      kLinearToGammaTab[v] = (int)(255. * pow(scale * v, 1. / kGamma) + .5);
+    }
+    kGammaTablesOk = 1;
+  }
+}
+
+static WEBP_INLINE uint32_t GammaToLinear(uint8_t v) {
+  return kGammaToLinearTab[v];
+}
+
+static WEBP_INLINE int Interpolate(int v) {
+  const int tab_pos = v >> (kGammaTabFix + 2);    // integer part
+  const int x = v & ((kGammaTabScale << 2) - 1);  // fractional part
+  const int v0 = kLinearToGammaTab[tab_pos];
+  const int v1 = kLinearToGammaTab[tab_pos + 1];
+  const int y = v1 * x + v0 * ((kGammaTabScale << 2) - x);   // interpolate
+  assert(tab_pos + 1 < kGammaTabSize + 1);
+  return y;
+}
+
+// Convert a linear value 'v' to YUV_FIX+2 fixed-point precision
+// U/V value, suitable for RGBToU/V calls.
+static WEBP_INLINE int LinearToGamma(uint32_t base_value, int shift) {
+  const int y = Interpolate(base_value << shift);   // final uplifted value
+  return (y + kGammaTabRounder) >> kGammaTabFix;    // descale
+}
+
+#else
+
+static WEBP_TSAN_IGNORE_FUNCTION void InitGammaTables(void) {}
+static WEBP_INLINE uint32_t GammaToLinear(uint8_t v) { return v; }
+static WEBP_INLINE int LinearToGamma(uint32_t base_value, int shift) {
+  return (int)(base_value << shift);
+}
+
+#endif    // USE_GAMMA_COMPRESSION
+
+//------------------------------------------------------------------------------
+// RGB -> YUV conversion
+
+static int RGBToY(int r, int g, int b, VP8Random* const rg) {
+  return (rg == NULL) ? VP8RGBToY(r, g, b, YUV_HALF)
+                      : VP8RGBToY(r, g, b, VP8RandomBits(rg, YUV_FIX));
+}
+
+static int RGBToU(int r, int g, int b, VP8Random* const rg) {
+  return (rg == NULL) ? VP8RGBToU(r, g, b, YUV_HALF << 2)
+                      : VP8RGBToU(r, g, b, VP8RandomBits(rg, YUV_FIX + 2));
+}
+
+static int RGBToV(int r, int g, int b, VP8Random* const rg) {
+  return (rg == NULL) ? VP8RGBToV(r, g, b, YUV_HALF << 2)
+                      : VP8RGBToV(r, g, b, VP8RandomBits(rg, YUV_FIX + 2));
+}
+
+//------------------------------------------------------------------------------
+// Smart RGB->YUV conversion
+
+static const int kNumIterations = 6;
+static const int kMinDimensionIterativeConversion = 4;
+
+// We use a-priori a different precision for storing RGB and Y/W components
+// We could use YFIX=0 and only uint8_t for fixed_y_t, but it produces some
+// banding sometimes. Better use extra precision.
+// TODO(skal): cleanup once TFIX/YFIX values are fixed.
+
+typedef int16_t fixed_t;      // signed type with extra TFIX precision for UV
+typedef uint16_t fixed_y_t;   // unsigned type with extra YFIX precision for W
+#define TFIX 2   // fixed-point precision of RGB
+#define YFIX 2   // fixed point precision for Y/W
+
+#define THALF ((1 << TFIX) >> 1)
+#define MAX_Y_T ((256 << YFIX) - 1)
+#define TROUNDER (1 << (YUV_FIX + TFIX - 1))
+
+#if defined(USE_GAMMA_COMPRESSION)
+
+// float variant of gamma-correction
+// We use tables of different size and precision, along with a 'real-world'
+// Gamma value close to ~2.
+#define kGammaF 2.2
+static float kGammaToLinearTabF[MAX_Y_T + 1];   // size scales with Y_FIX
+static float kLinearToGammaTabF[kGammaTabSize + 2];
+static volatile int kGammaTablesFOk = 0;
+
+static WEBP_TSAN_IGNORE_FUNCTION void InitGammaTablesF(void) {
+  if (!kGammaTablesFOk) {
+    int v;
+    const double norm = 1. / MAX_Y_T;
+    const double scale = 1. / kGammaTabSize;
+    for (v = 0; v <= MAX_Y_T; ++v) {
+      kGammaToLinearTabF[v] = (float)pow(norm * v, kGammaF);
+    }
+    for (v = 0; v <= kGammaTabSize; ++v) {
+      kLinearToGammaTabF[v] = (float)(MAX_Y_T * pow(scale * v, 1. / kGammaF));
+    }
+    // to prevent small rounding errors to cause read-overflow:
+    kLinearToGammaTabF[kGammaTabSize + 1] = kLinearToGammaTabF[kGammaTabSize];
+    kGammaTablesFOk = 1;
+  }
+}
+
+static WEBP_INLINE float GammaToLinearF(int v) {
+  return kGammaToLinearTabF[v];
+}
+
+static WEBP_INLINE int LinearToGammaF(float value) {
+  const float v = value * kGammaTabSize;
+  const int tab_pos = (int)v;
+  const float x = v - (float)tab_pos;      // fractional part
+  const float v0 = kLinearToGammaTabF[tab_pos + 0];
+  const float v1 = kLinearToGammaTabF[tab_pos + 1];
+  const float y = v1 * x + v0 * (1.f - x);  // interpolate
+  return (int)(y + .5);
+}
+
+#else
+
+static WEBP_TSAN_IGNORE_FUNCTION void InitGammaTablesF(void) {}
+static WEBP_INLINE float GammaToLinearF(int v) {
+  const float norm = 1.f / MAX_Y_T;
+  return norm * v;
+}
+static WEBP_INLINE int LinearToGammaF(float value) {
+  return (int)(MAX_Y_T * value + .5);
+}
+
+#endif    // USE_GAMMA_COMPRESSION
+
+//------------------------------------------------------------------------------
+
+// precision: YFIX -> TFIX
+static WEBP_INLINE int FixedYToW(int v) { return v; }
+static WEBP_INLINE int FixedWToY(int v) { return v; }
+
+static uint8_t clip_8b(fixed_t v) {
+  return (!(v & ~0xff)) ? (uint8_t)v : (v < 0) ? 0u : 255u;
+}
+
+static fixed_y_t clip_y(int y) {
+  return (!(y & ~MAX_Y_T)) ? (fixed_y_t)y : (y < 0) ? 0 : MAX_Y_T;
+}
+
+// precision: TFIX -> YFIX
+static fixed_y_t clip_fixed_t(fixed_t v) {
+  const int y = FixedWToY(v);
+  const fixed_y_t w = clip_y(y);
+  return w;
+}
+
+//------------------------------------------------------------------------------
+
+static int RGBToGray(int r, int g, int b) {
+  const int luma = 19595 * r + 38470 * g + 7471 * b + YUV_HALF;
+  return (luma >> YUV_FIX);
+}
+
+static float RGBToGrayF(float r, float g, float b) {
+  return 0.299f * r + 0.587f * g + 0.114f * b;
+}
+
+static int ScaleDown(int a, int b, int c, int d) {
+  const float A = GammaToLinearF(a);
+  const float B = GammaToLinearF(b);
+  const float C = GammaToLinearF(c);
+  const float D = GammaToLinearF(d);
+  return LinearToGammaF(0.25f * (A + B + C + D));
+}
+
+static WEBP_INLINE void UpdateW(const fixed_y_t* src, fixed_y_t* dst, int len) {
+  while (len-- > 0) {
+    const float R = GammaToLinearF(src[0]);
+    const float G = GammaToLinearF(src[1]);
+    const float B = GammaToLinearF(src[2]);
+    const float Y = RGBToGrayF(R, G, B);
+    *dst++ = (fixed_y_t)LinearToGammaF(Y);
+    src += 3;
+  }
+}
+
+static WEBP_INLINE void UpdateChroma(const fixed_y_t* src1,
+                                     const fixed_y_t* src2,
+                                     fixed_t* dst, fixed_y_t* tmp, int len) {
+  while (len--> 0) {
+    const int r = ScaleDown(src1[0], src1[3], src2[0], src2[3]);
+    const int g = ScaleDown(src1[1], src1[4], src2[1], src2[4]);
+    const int b = ScaleDown(src1[2], src1[5], src2[2], src2[5]);
+    const int W = RGBToGray(r, g, b);
+    dst[0] = (fixed_t)FixedYToW(r - W);
+    dst[1] = (fixed_t)FixedYToW(g - W);
+    dst[2] = (fixed_t)FixedYToW(b - W);
+    dst += 3;
+    src1 += 6;
+    src2 += 6;
+    if (tmp != NULL) {
+      tmp[0] = tmp[1] = clip_y((int)(W + .5));
+      tmp += 2;
+    }
+  }
+}
+
+//------------------------------------------------------------------------------
+
+static WEBP_INLINE int Filter(const fixed_t* const A, const fixed_t* const B,
+                              int rightwise) {
+  int v;
+  if (!rightwise) {
+    v = (A[0] * 9 + A[-3] * 3 + B[0] * 3 + B[-3]);
+  } else {
+    v = (A[0] * 9 + A[+3] * 3 + B[0] * 3 + B[+3]);
+  }
+  return (v + 8) >> 4;
+}
+
+static WEBP_INLINE int Filter2(int A, int B) { return (A * 3 + B + 2) >> 2; }
+
+//------------------------------------------------------------------------------
+
+// 8bit -> YFIX
+static WEBP_INLINE fixed_y_t UpLift(uint8_t a) {
+  return ((fixed_y_t)a << YFIX) | (1 << (YFIX - 1));
+}
+
+static void ImportOneRow(const uint8_t* const r_ptr,
+                         const uint8_t* const g_ptr,
+                         const uint8_t* const b_ptr,
+                         int step,
+                         int pic_width,
+                         fixed_y_t* const dst) {
+  int i;
+  for (i = 0; i < pic_width; ++i) {
+    const int off = i * step;
+    dst[3 * i + 0] = UpLift(r_ptr[off]);
+    dst[3 * i + 1] = UpLift(g_ptr[off]);
+    dst[3 * i + 2] = UpLift(b_ptr[off]);
+  }
+  if (pic_width & 1) {  // replicate rightmost pixel
+    memcpy(dst + 3 * pic_width, dst + 3 * (pic_width - 1), 3 * sizeof(*dst));
+  }
+}
+
+static void InterpolateTwoRows(const fixed_y_t* const best_y,
+                               const fixed_t* const prev_uv,
+                               const fixed_t* const cur_uv,
+                               const fixed_t* const next_uv,
+                               int w,
+                               fixed_y_t* const out1,
+                               fixed_y_t* const out2) {
+  int i, k;
+  {  // special boundary case for i==0
+    const int W0 = FixedYToW(best_y[0]);
+    const int W1 = FixedYToW(best_y[w]);
+    for (k = 0; k <= 2; ++k) {
+      out1[k] = clip_fixed_t(Filter2(cur_uv[k], prev_uv[k]) + W0);
+      out2[k] = clip_fixed_t(Filter2(cur_uv[k], next_uv[k]) + W1);
+    }
+  }
+  for (i = 1; i < w - 1; ++i) {
+    const int W0 = FixedYToW(best_y[i + 0]);
+    const int W1 = FixedYToW(best_y[i + w]);
+    const int off = 3 * (i >> 1);
+    for (k = 0; k <= 2; ++k) {
+      const int tmp0 = Filter(cur_uv + off + k, prev_uv + off + k, i & 1);
+      const int tmp1 = Filter(cur_uv + off + k, next_uv + off + k, i & 1);
+      out1[3 * i + k] = clip_fixed_t(tmp0 + W0);
+      out2[3 * i + k] = clip_fixed_t(tmp1 + W1);
+    }
+  }
+  {  // special boundary case for i == w - 1
+    const int W0 = FixedYToW(best_y[i + 0]);
+    const int W1 = FixedYToW(best_y[i + w]);
+    const int off = 3 * (i >> 1);
+    for (k = 0; k <= 2; ++k) {
+      out1[3 * i + k] =
+          clip_fixed_t(Filter2(cur_uv[off + k], prev_uv[off + k]) + W0);
+      out2[3 * i + k] =
+          clip_fixed_t(Filter2(cur_uv[off + k], next_uv[off + k]) + W1);
+    }
+  }
+}
+
+static WEBP_INLINE uint8_t ConvertRGBToY(int r, int g, int b) {
+  const int luma = 16839 * r + 33059 * g + 6420 * b + TROUNDER;
+  return clip_8b(16 + (luma >> (YUV_FIX + TFIX)));
+}
+
+static WEBP_INLINE uint8_t ConvertRGBToU(int r, int g, int b) {
+  const int u =  -9719 * r - 19081 * g + 28800 * b + TROUNDER;
+  return clip_8b(128 + (u >> (YUV_FIX + TFIX)));
+}
+
+static WEBP_INLINE uint8_t ConvertRGBToV(int r, int g, int b) {
+  const int v = +28800 * r - 24116 * g -  4684 * b + TROUNDER;
+  return clip_8b(128 + (v >> (YUV_FIX + TFIX)));
+}
+
+static int ConvertWRGBToYUV(const fixed_y_t* const best_y,
+                            const fixed_t* const best_uv,
+                            WebPPicture* const picture) {
+  int i, j;
+  const int w = (picture->width + 1) & ~1;
+  const int h = (picture->height + 1) & ~1;
+  const int uv_w = w >> 1;
+  const int uv_h = h >> 1;
+  for (j = 0; j < picture->height; ++j) {
+    for (i = 0; i < picture->width; ++i) {
+      const int off = 3 * ((i >> 1) + (j >> 1) * uv_w);
+      const int off2 = i + j * picture->y_stride;
+      const int W = FixedYToW(best_y[i + j * w]);
+      const int r = best_uv[off + 0] + W;
+      const int g = best_uv[off + 1] + W;
+      const int b = best_uv[off + 2] + W;
+      picture->y[off2] = ConvertRGBToY(r, g, b);
+    }
+  }
+  for (j = 0; j < uv_h; ++j) {
+    uint8_t* const dst_u = picture->u + j * picture->uv_stride;
+    uint8_t* const dst_v = picture->v + j * picture->uv_stride;
+    for (i = 0; i < uv_w; ++i) {
+      const int off = 3 * (i + j * uv_w);
+      const int r = best_uv[off + 0];
+      const int g = best_uv[off + 1];
+      const int b = best_uv[off + 2];
+      dst_u[i] = ConvertRGBToU(r, g, b);
+      dst_v[i] = ConvertRGBToV(r, g, b);
+    }
+  }
+  return 1;
+}
+
+//------------------------------------------------------------------------------
+// Main function
+
+#define SAFE_ALLOC(W, H, T) ((T*)WebPSafeMalloc((W) * (H), sizeof(T)))
+
+static int PreprocessARGB(const uint8_t* const r_ptr,
+                          const uint8_t* const g_ptr,
+                          const uint8_t* const b_ptr,
+                          int step, int rgb_stride,
+                          WebPPicture* const picture) {
+  // we expand the right/bottom border if needed
+  const int w = (picture->width + 1) & ~1;
+  const int h = (picture->height + 1) & ~1;
+  const int uv_w = w >> 1;
+  const int uv_h = h >> 1;
+  int i, j, iter;
+
+  // TODO(skal): allocate one big memory chunk. But for now, it's easier
+  // for valgrind debugging to have several chunks.
+  fixed_y_t* const tmp_buffer = SAFE_ALLOC(w * 3, 2, fixed_y_t);   // scratch
+  fixed_y_t* const best_y = SAFE_ALLOC(w, h, fixed_y_t);
+  fixed_y_t* const target_y = SAFE_ALLOC(w, h, fixed_y_t);
+  fixed_y_t* const best_rgb_y = SAFE_ALLOC(w, 2, fixed_y_t);
+  fixed_t* const best_uv = SAFE_ALLOC(uv_w * 3, uv_h, fixed_t);
+  fixed_t* const target_uv = SAFE_ALLOC(uv_w * 3, uv_h, fixed_t);
+  fixed_t* const best_rgb_uv = SAFE_ALLOC(uv_w * 3, 1, fixed_t);
+  int ok;
+
+  if (best_y == NULL || best_uv == NULL ||
+      target_y == NULL || target_uv == NULL ||
+      best_rgb_y == NULL || best_rgb_uv == NULL ||
+      tmp_buffer == NULL) {
+    ok = WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY);
+    goto End;
+  }
+  assert(picture->width >= kMinDimensionIterativeConversion);
+  assert(picture->height >= kMinDimensionIterativeConversion);
+
+  // Import RGB samples to W/RGB representation.
+  for (j = 0; j < picture->height; j += 2) {
+    const int is_last_row = (j == picture->height - 1);
+    fixed_y_t* const src1 = tmp_buffer;
+    fixed_y_t* const src2 = tmp_buffer + 3 * w;
+    const int off1 = j * rgb_stride;
+    const int off2 = off1 + rgb_stride;
+    const int uv_off = (j >> 1) * 3 * uv_w;
+    fixed_y_t* const dst_y = best_y + j * w;
+
+    // prepare two rows of input
+    ImportOneRow(r_ptr + off1, g_ptr + off1, b_ptr + off1,
+                 step, picture->width, src1);
+    if (!is_last_row) {
+      ImportOneRow(r_ptr + off2, g_ptr + off2, b_ptr + off2,
+                   step, picture->width, src2);
+    } else {
+      memcpy(src2, src1, 3 * w * sizeof(*src2));
+    }
+    UpdateW(src1, target_y + (j + 0) * w, w);
+    UpdateW(src2, target_y + (j + 1) * w, w);
+    UpdateChroma(src1, src2, target_uv + uv_off, dst_y, uv_w);
+    memcpy(best_uv + uv_off, target_uv + uv_off, 3 * uv_w * sizeof(*best_uv));
+    memcpy(dst_y + w, dst_y, w * sizeof(*dst_y));
+  }
+
+  // Iterate and resolve clipping conflicts.
+  for (iter = 0; iter < kNumIterations; ++iter) {
+    int k;
+    const fixed_t* cur_uv = best_uv;
+    const fixed_t* prev_uv = best_uv;
+    for (j = 0; j < h; j += 2) {
+      fixed_y_t* const src1 = tmp_buffer;
+      fixed_y_t* const src2 = tmp_buffer + 3 * w;
+
+      {
+        const fixed_t* const next_uv = cur_uv + ((j < h - 2) ? 3 * uv_w : 0);
+        InterpolateTwoRows(best_y + j * w, prev_uv, cur_uv, next_uv,
+                           w, src1, src2);
+        prev_uv = cur_uv;
+        cur_uv = next_uv;
+      }
+
+      UpdateW(src1, best_rgb_y + 0 * w, w);
+      UpdateW(src2, best_rgb_y + 1 * w, w);
+      UpdateChroma(src1, src2, best_rgb_uv, NULL, uv_w);
+
+      // update two rows of Y and one row of RGB
+      for (i = 0; i < 2 * w; ++i) {
+        const int off = i + j * w;
+        const int diff_y = target_y[off] - best_rgb_y[i];
+        const int new_y = (int)best_y[off] + diff_y;
+        best_y[off] = clip_y(new_y);
+      }
+      for (i = 0; i < uv_w; ++i) {
+        const int off = 3 * (i + (j >> 1) * uv_w);
+        int W;
+        for (k = 0; k <= 2; ++k) {
+          const int diff_uv = (int)target_uv[off + k] - best_rgb_uv[3 * i + k];
+          best_uv[off + k] += diff_uv;
+        }
+        W = RGBToGray(best_uv[off + 0], best_uv[off + 1], best_uv[off + 2]);
+        for (k = 0; k <= 2; ++k) {
+          best_uv[off + k] -= W;
+        }
+      }
+    }
+    // TODO(skal): add early-termination criterion
+  }
+
+  // final reconstruction
+  ok = ConvertWRGBToYUV(best_y, best_uv, picture);
+
+ End:
+  WebPSafeFree(best_y);
+  WebPSafeFree(best_uv);
+  WebPSafeFree(target_y);
+  WebPSafeFree(target_uv);
+  WebPSafeFree(best_rgb_y);
+  WebPSafeFree(best_rgb_uv);
+  WebPSafeFree(tmp_buffer);
+  return ok;
+}
+#undef SAFE_ALLOC
+
+//------------------------------------------------------------------------------
+// "Fast" regular RGB->YUV
+
+#define SUM4(ptr, step) LinearToGamma(                     \
+    GammaToLinear((ptr)[0]) +                              \
+    GammaToLinear((ptr)[(step)]) +                         \
+    GammaToLinear((ptr)[rgb_stride]) +                     \
+    GammaToLinear((ptr)[rgb_stride + (step)]), 0)          \
+
+#define SUM2(ptr) \
+    LinearToGamma(GammaToLinear((ptr)[0]) + GammaToLinear((ptr)[rgb_stride]), 1)
+
+#define SUM2ALPHA(ptr) ((ptr)[0] + (ptr)[rgb_stride])
+#define SUM4ALPHA(ptr) (SUM2ALPHA(ptr) + SUM2ALPHA((ptr) + 4))
+
+#if defined(USE_INVERSE_ALPHA_TABLE)
+
+static const int kAlphaFix = 19;
+// Following table is (1 << kAlphaFix) / a. The (v * kInvAlpha[a]) >> kAlphaFix
+// formula is then equal to v / a in most (99.6%) cases. Note that this table
+// and constant are adjusted very tightly to fit 32b arithmetic.
+// In particular, they use the fact that the operands for 'v / a' are actually
+// derived as v = (a0.p0 + a1.p1 + a2.p2 + a3.p3) and a = a0 + a1 + a2 + a3
+// with ai in [0..255] and pi in [0..1<<kGammaFix). The constraint to avoid
+// overflow is: kGammaFix + kAlphaFix <= 31.
+static const uint32_t kInvAlpha[4 * 0xff + 1] = {
+  0,  /* alpha = 0 */
+  524288, 262144, 174762, 131072, 104857, 87381, 74898, 65536,
+  58254, 52428, 47662, 43690, 40329, 37449, 34952, 32768,
+  30840, 29127, 27594, 26214, 24966, 23831, 22795, 21845,
+  20971, 20164, 19418, 18724, 18078, 17476, 16912, 16384,
+  15887, 15420, 14979, 14563, 14169, 13797, 13443, 13107,
+  12787, 12483, 12192, 11915, 11650, 11397, 11155, 10922,
+  10699, 10485, 10280, 10082, 9892, 9709, 9532, 9362,
+  9198, 9039, 8886, 8738, 8594, 8456, 8322, 8192,
+  8065, 7943, 7825, 7710, 7598, 7489, 7384, 7281,
+  7182, 7084, 6990, 6898, 6808, 6721, 6636, 6553,
+  6472, 6393, 6316, 6241, 6168, 6096, 6026, 5957,
+  5890, 5825, 5761, 5698, 5637, 5577, 5518, 5461,
+  5405, 5349, 5295, 5242, 5190, 5140, 5090, 5041,
+  4993, 4946, 4899, 4854, 4809, 4766, 4723, 4681,
+  4639, 4599, 4559, 4519, 4481, 4443, 4405, 4369,
+  4332, 4297, 4262, 4228, 4194, 4161, 4128, 4096,
+  4064, 4032, 4002, 3971, 3942, 3912, 3883, 3855,
+  3826, 3799, 3771, 3744, 3718, 3692, 3666, 3640,
+  3615, 3591, 3566, 3542, 3518, 3495, 3472, 3449,
+  3426, 3404, 3382, 3360, 3339, 3318, 3297, 3276,
+  3256, 3236, 3216, 3196, 3177, 3158, 3139, 3120,
+  3102, 3084, 3066, 3048, 3030, 3013, 2995, 2978,
+  2962, 2945, 2928, 2912, 2896, 2880, 2864, 2849,
+  2833, 2818, 2803, 2788, 2774, 2759, 2744, 2730,
+  2716, 2702, 2688, 2674, 2661, 2647, 2634, 2621,
+  2608, 2595, 2582, 2570, 2557, 2545, 2532, 2520,
+  2508, 2496, 2484, 2473, 2461, 2449, 2438, 2427,
+  2416, 2404, 2394, 2383, 2372, 2361, 2351, 2340,
+  2330, 2319, 2309, 2299, 2289, 2279, 2269, 2259,
+  2250, 2240, 2231, 2221, 2212, 2202, 2193, 2184,
+  2175, 2166, 2157, 2148, 2139, 2131, 2122, 2114,
+  2105, 2097, 2088, 2080, 2072, 2064, 2056, 2048,
+  2040, 2032, 2024, 2016, 2008, 2001, 1993, 1985,
+  1978, 1971, 1963, 1956, 1949, 1941, 1934, 1927,
+  1920, 1913, 1906, 1899, 1892, 1885, 1879, 1872,
+  1865, 1859, 1852, 1846, 1839, 1833, 1826, 1820,
+  1814, 1807, 1801, 1795, 1789, 1783, 1777, 1771,
+  1765, 1759, 1753, 1747, 1741, 1736, 1730, 1724,
+  1718, 1713, 1707, 1702, 1696, 1691, 1685, 1680,
+  1675, 1669, 1664, 1659, 1653, 1648, 1643, 1638,
+  1633, 1628, 1623, 1618, 1613, 1608, 1603, 1598,
+  1593, 1588, 1583, 1579, 1574, 1569, 1565, 1560,
+  1555, 1551, 1546, 1542, 1537, 1533, 1528, 1524,
+  1519, 1515, 1510, 1506, 1502, 1497, 1493, 1489,
+  1485, 1481, 1476, 1472, 1468, 1464, 1460, 1456,
+  1452, 1448, 1444, 1440, 1436, 1432, 1428, 1424,
+  1420, 1416, 1413, 1409, 1405, 1401, 1398, 1394,
+  1390, 1387, 1383, 1379, 1376, 1372, 1368, 1365,
+  1361, 1358, 1354, 1351, 1347, 1344, 1340, 1337,
+  1334, 1330, 1327, 1323, 1320, 1317, 1314, 1310,
+  1307, 1304, 1300, 1297, 1294, 1291, 1288, 1285,
+  1281, 1278, 1275, 1272, 1269, 1266, 1263, 1260,
+  1257, 1254, 1251, 1248, 1245, 1242, 1239, 1236,
+  1233, 1230, 1227, 1224, 1222, 1219, 1216, 1213,
+  1210, 1208, 1205, 1202, 1199, 1197, 1194, 1191,
+  1188, 1186, 1183, 1180, 1178, 1175, 1172, 1170,
+  1167, 1165, 1162, 1159, 1157, 1154, 1152, 1149,
+  1147, 1144, 1142, 1139, 1137, 1134, 1132, 1129,
+  1127, 1125, 1122, 1120, 1117, 1115, 1113, 1110,
+  1108, 1106, 1103, 1101, 1099, 1096, 1094, 1092,
+  1089, 1087, 1085, 1083, 1081, 1078, 1076, 1074,
+  1072, 1069, 1067, 1065, 1063, 1061, 1059, 1057,
+  1054, 1052, 1050, 1048, 1046, 1044, 1042, 1040,
+  1038, 1036, 1034, 1032, 1030, 1028, 1026, 1024,
+  1022, 1020, 1018, 1016, 1014, 1012, 1010, 1008,
+  1006, 1004, 1002, 1000, 998, 996, 994, 992,
+  991, 989, 987, 985, 983, 981, 979, 978,
+  976, 974, 972, 970, 969, 967, 965, 963,
+  961, 960, 958, 956, 954, 953, 951, 949,
+  948, 946, 944, 942, 941, 939, 937, 936,
+  934, 932, 931, 929, 927, 926, 924, 923,
+  921, 919, 918, 916, 914, 913, 911, 910,
+  908, 907, 905, 903, 902, 900, 899, 897,
+  896, 894, 893, 891, 890, 888, 887, 885,
+  884, 882, 881, 879, 878, 876, 875, 873,
+  872, 870, 869, 868, 866, 865, 863, 862,
+  860, 859, 858, 856, 855, 853, 852, 851,
+  849, 848, 846, 845, 844, 842, 841, 840,
+  838, 837, 836, 834, 833, 832, 830, 829,
+  828, 826, 825, 824, 823, 821, 820, 819,
+  817, 816, 815, 814, 812, 811, 810, 809,
+  807, 806, 805, 804, 802, 801, 800, 799,
+  798, 796, 795, 794, 793, 791, 790, 789,
+  788, 787, 786, 784, 783, 782, 781, 780,
+  779, 777, 776, 775, 774, 773, 772, 771,
+  769, 768, 767, 766, 765, 764, 763, 762,
+  760, 759, 758, 757, 756, 755, 754, 753,
+  752, 751, 750, 748, 747, 746, 745, 744,
+  743, 742, 741, 740, 739, 738, 737, 736,
+  735, 734, 733, 732, 731, 730, 729, 728,
+  727, 726, 725, 724, 723, 722, 721, 720,
+  719, 718, 717, 716, 715, 714, 713, 712,
+  711, 710, 709, 708, 707, 706, 705, 704,
+  703, 702, 701, 700, 699, 699, 698, 697,
+  696, 695, 694, 693, 692, 691, 690, 689,
+  688, 688, 687, 686, 685, 684, 683, 682,
+  681, 680, 680, 679, 678, 677, 676, 675,
+  674, 673, 673, 672, 671, 670, 669, 668,
+  667, 667, 666, 665, 664, 663, 662, 661,
+  661, 660, 659, 658, 657, 657, 656, 655,
+  654, 653, 652, 652, 651, 650, 649, 648,
+  648, 647, 646, 645, 644, 644, 643, 642,
+  641, 640, 640, 639, 638, 637, 637, 636,
+  635, 634, 633, 633, 632, 631, 630, 630,
+  629, 628, 627, 627, 626, 625, 624, 624,
+  623, 622, 621, 621, 620, 619, 618, 618,
+  617, 616, 616, 615, 614, 613, 613, 612,
+  611, 611, 610, 609, 608, 608, 607, 606,
+  606, 605, 604, 604, 603, 602, 601, 601,
+  600, 599, 599, 598, 597, 597, 596, 595,
+  595, 594, 593, 593, 592, 591, 591, 590,
+  589, 589, 588, 587, 587, 586, 585, 585,
+  584, 583, 583, 582, 581, 581, 580, 579,
+  579, 578, 578, 577, 576, 576, 575, 574,
+  574, 573, 572, 572, 571, 571, 570, 569,
+  569, 568, 568, 567, 566, 566, 565, 564,
+  564, 563, 563, 562, 561, 561, 560, 560,
+  559, 558, 558, 557, 557, 556, 555, 555,
+  554, 554, 553, 553, 552, 551, 551, 550,
+  550, 549, 548, 548, 547, 547, 546, 546,
+  545, 544, 544, 543, 543, 542, 542, 541,
+  541, 540, 539, 539, 538, 538, 537, 537,
+  536, 536, 535, 534, 534, 533, 533, 532,
+  532, 531, 531, 530, 530, 529, 529, 528,
+  527, 527, 526, 526, 525, 525, 524, 524,
+  523, 523, 522, 522, 521, 521, 520, 520,
+  519, 519, 518, 518, 517, 517, 516, 516,
+  515, 515, 514, 514
+};
+
+// Note that LinearToGamma() expects the values to be premultiplied by 4,
+// so we incorporate this factor 4 inside the DIVIDE_BY_ALPHA macro directly.
+#define DIVIDE_BY_ALPHA(sum, a)  (((sum) * kInvAlpha[(a)]) >> (kAlphaFix - 2))
+
+#else
+
+#define DIVIDE_BY_ALPHA(sum, a) (4 * (sum) / (a))
+
+#endif  // USE_INVERSE_ALPHA_TABLE
+
+static WEBP_INLINE int LinearToGammaWeighted(const uint8_t* src,
+                                             const uint8_t* a_ptr,
+                                             uint32_t total_a, int step,
+                                             int rgb_stride) {
+  const uint32_t sum =
+      a_ptr[0] * GammaToLinear(src[0]) +
+      a_ptr[step] * GammaToLinear(src[step]) +
+      a_ptr[rgb_stride] * GammaToLinear(src[rgb_stride]) +
+      a_ptr[rgb_stride + step] * GammaToLinear(src[rgb_stride + step]);
+  assert(total_a > 0 && total_a <= 4 * 0xff);
+#if defined(USE_INVERSE_ALPHA_TABLE)
+  assert((uint64_t)sum * kInvAlpha[total_a] < ((uint64_t)1 << 32));
+#endif
+  return LinearToGamma(DIVIDE_BY_ALPHA(sum, total_a), 0);
+}
+
+static WEBP_INLINE void ConvertRowToY(const uint8_t* const r_ptr,
+                                      const uint8_t* const g_ptr,
+                                      const uint8_t* const b_ptr,
+                                      int step,
+                                      uint8_t* const dst_y,
+                                      int width,
+                                      VP8Random* const rg) {
+  int i, j;
+  for (i = 0, j = 0; i < width; ++i, j += step) {
+    dst_y[i] = RGBToY(r_ptr[j], g_ptr[j], b_ptr[j], rg);
+  }
+}
+
+static WEBP_INLINE void ConvertRowsToUVWithAlpha(const uint8_t* const r_ptr,
+                                                 const uint8_t* const g_ptr,
+                                                 const uint8_t* const b_ptr,
+                                                 const uint8_t* const a_ptr,
+                                                 int rgb_stride,
+                                                 uint8_t* const dst_u,
+                                                 uint8_t* const dst_v,
+                                                 int width,
+                                                 VP8Random* const rg) {
+  int i, j;
+  // we loop over 2x2 blocks and produce one U/V value for each.
+  for (i = 0, j = 0; i < (width >> 1); ++i, j += 2 * sizeof(uint32_t)) {
+    const uint32_t a = SUM4ALPHA(a_ptr + j);
+    int r, g, b;
+    if (a == 4 * 0xff || a == 0) {
+      r = SUM4(r_ptr + j, 4);
+      g = SUM4(g_ptr + j, 4);
+      b = SUM4(b_ptr + j, 4);
+    } else {
+      r = LinearToGammaWeighted(r_ptr + j, a_ptr + j, a, 4, rgb_stride);
+      g = LinearToGammaWeighted(g_ptr + j, a_ptr + j, a, 4, rgb_stride);
+      b = LinearToGammaWeighted(b_ptr + j, a_ptr + j, a, 4, rgb_stride);
+    }
+    dst_u[i] = RGBToU(r, g, b, rg);
+    dst_v[i] = RGBToV(r, g, b, rg);
+  }
+  if (width & 1) {
+    const uint32_t a = 2u * SUM2ALPHA(a_ptr + j);
+    int r, g, b;
+    if (a == 4 * 0xff || a == 0) {
+      r = SUM2(r_ptr + j);
+      g = SUM2(g_ptr + j);
+      b = SUM2(b_ptr + j);
+    } else {
+      r = LinearToGammaWeighted(r_ptr + j, a_ptr + j, a, 0, rgb_stride);
+      g = LinearToGammaWeighted(g_ptr + j, a_ptr + j, a, 0, rgb_stride);
+      b = LinearToGammaWeighted(b_ptr + j, a_ptr + j, a, 0, rgb_stride);
+    }
+    dst_u[i] = RGBToU(r, g, b, rg);
+    dst_v[i] = RGBToV(r, g, b, rg);
+  }
+}
+
+static WEBP_INLINE void ConvertRowsToUV(const uint8_t* const r_ptr,
+                                        const uint8_t* const g_ptr,
+                                        const uint8_t* const b_ptr,
+                                        int step, int rgb_stride,
+                                        uint8_t* const dst_u,
+                                        uint8_t* const dst_v,
+                                        int width,
+                                        VP8Random* const rg) {
+  int i, j;
+  for (i = 0, j = 0; i < (width >> 1); ++i, j += 2 * step) {
+    const int r = SUM4(r_ptr + j, step);
+    const int g = SUM4(g_ptr + j, step);
+    const int b = SUM4(b_ptr + j, step);
+    dst_u[i] = RGBToU(r, g, b, rg);
+    dst_v[i] = RGBToV(r, g, b, rg);
+  }
+  if (width & 1) {
+    const int r = SUM2(r_ptr + j);
+    const int g = SUM2(g_ptr + j);
+    const int b = SUM2(b_ptr + j);
+    dst_u[i] = RGBToU(r, g, b, rg);
+    dst_v[i] = RGBToV(r, g, b, rg);
+  }
+}
+
+static int ImportYUVAFromRGBA(const uint8_t* const r_ptr,
+                              const uint8_t* const g_ptr,
+                              const uint8_t* const b_ptr,
+                              const uint8_t* const a_ptr,
+                              int step,         // bytes per pixel
+                              int rgb_stride,   // bytes per scanline
+                              float dithering,
+                              int use_iterative_conversion,
+                              WebPPicture* const picture) {
+  int y;
+  const int width = picture->width;
+  const int height = picture->height;
+  const int has_alpha = CheckNonOpaque(a_ptr, width, height, step, rgb_stride);
+
+  picture->colorspace = has_alpha ? WEBP_YUV420A : WEBP_YUV420;
+  picture->use_argb = 0;
+
+  // disable smart conversion if source is too small (overkill).
+  if (width < kMinDimensionIterativeConversion ||
+      height < kMinDimensionIterativeConversion) {
+    use_iterative_conversion = 0;
+  }
+
+  if (!WebPPictureAllocYUVA(picture, width, height)) {
+    return 0;
+  }
+  if (has_alpha) {
+    WebPInitAlphaProcessing();
+    assert(step == 4);
+#if defined(USE_GAMMA_COMPRESSION) && defined(USE_INVERSE_ALPHA_TABLE)
+    assert(kAlphaFix + kGammaFix <= 31);
+#endif
+  }
+
+  if (use_iterative_conversion) {
+    InitGammaTablesF();
+    if (!PreprocessARGB(r_ptr, g_ptr, b_ptr, step, rgb_stride, picture)) {
+      return 0;
+    }
+    if (has_alpha) {
+      WebPExtractAlpha(a_ptr, rgb_stride, width, height,
+                       picture->a, picture->a_stride);
+    }
+  } else {
+    uint8_t* dst_y = picture->y;
+    uint8_t* dst_u = picture->u;
+    uint8_t* dst_v = picture->v;
+    uint8_t* dst_a = picture->a;
+
+    VP8Random base_rg;
+    VP8Random* rg = NULL;
+    if (dithering > 0.) {
+      VP8InitRandom(&base_rg, dithering);
+      rg = &base_rg;
+    }
+
+    InitGammaTables();
+
+    // Downsample Y/U/V planes, two rows at a time
+    for (y = 0; y < (height >> 1); ++y) {
+      int rows_have_alpha = has_alpha;
+      const int off1 = (2 * y + 0) * rgb_stride;
+      const int off2 = (2 * y + 1) * rgb_stride;
+      ConvertRowToY(r_ptr + off1, g_ptr + off1, b_ptr + off1, step,
+                    dst_y, width, rg);
+      ConvertRowToY(r_ptr + off2, g_ptr + off2, b_ptr + off2, step,
+                    dst_y + picture->y_stride, width, rg);
+      dst_y += 2 * picture->y_stride;
+      if (has_alpha) {
+        rows_have_alpha &= !WebPExtractAlpha(a_ptr + off1, rgb_stride,
+                                             width, 2,
+                                             dst_a, picture->a_stride);
+        dst_a += 2 * picture->a_stride;
+      }
+      if (!rows_have_alpha) {
+        ConvertRowsToUV(r_ptr + off1, g_ptr + off1, b_ptr + off1,
+                        step, rgb_stride, dst_u, dst_v, width, rg);
+      } else {
+        ConvertRowsToUVWithAlpha(r_ptr + off1, g_ptr + off1, b_ptr + off1,
+                                 a_ptr + off1, rgb_stride,
+                                 dst_u, dst_v, width, rg);
+      }
+      dst_u += picture->uv_stride;
+      dst_v += picture->uv_stride;
+    }
+    if (height & 1) {    // extra last row
+      const int off = 2 * y * rgb_stride;
+      int row_has_alpha = has_alpha;
+      ConvertRowToY(r_ptr + off, g_ptr + off, b_ptr + off, step,
+                    dst_y, width, rg);
+      if (row_has_alpha) {
+        row_has_alpha &= !WebPExtractAlpha(a_ptr + off, 0, width, 1, dst_a, 0);
+      }
+      if (!row_has_alpha) {
+        ConvertRowsToUV(r_ptr + off, g_ptr + off, b_ptr + off,
+                        step, 0, dst_u, dst_v, width, rg);
+      } else {
+        ConvertRowsToUVWithAlpha(r_ptr + off, g_ptr + off, b_ptr + off,
+                                 a_ptr + off, 0,
+                                 dst_u, dst_v, width, rg);
+      }
+    }
+  }
+  return 1;
+}
+
+#undef SUM4
+#undef SUM2
+#undef SUM4ALPHA
+#undef SUM2ALPHA
+
+//------------------------------------------------------------------------------
+// call for ARGB->YUVA conversion
+
+static int PictureARGBToYUVA(WebPPicture* picture, WebPEncCSP colorspace,
+                             float dithering, int use_iterative_conversion) {
+  if (picture == NULL) return 0;
+  if (picture->argb == NULL) {
+    return WebPEncodingSetError(picture, VP8_ENC_ERROR_NULL_PARAMETER);
+  } else if ((colorspace & WEBP_CSP_UV_MASK) != WEBP_YUV420) {
+    return WebPEncodingSetError(picture, VP8_ENC_ERROR_INVALID_CONFIGURATION);
+  } else {
+    const uint8_t* const argb = (const uint8_t*)picture->argb;
+    const uint8_t* const r = ALPHA_IS_LAST ? argb + 2 : argb + 1;
+    const uint8_t* const g = ALPHA_IS_LAST ? argb + 1 : argb + 2;
+    const uint8_t* const b = ALPHA_IS_LAST ? argb + 0 : argb + 3;
+    const uint8_t* const a = ALPHA_IS_LAST ? argb + 3 : argb + 0;
+
+    picture->colorspace = WEBP_YUV420;
+    return ImportYUVAFromRGBA(r, g, b, a, 4, 4 * picture->argb_stride,
+                              dithering, use_iterative_conversion, picture);
+  }
+}
+
+int WebPPictureARGBToYUVADithered(WebPPicture* picture, WebPEncCSP colorspace,
+                                  float dithering) {
+  return PictureARGBToYUVA(picture, colorspace, dithering, 0);
+}
+
+int WebPPictureARGBToYUVA(WebPPicture* picture, WebPEncCSP colorspace) {
+  return PictureARGBToYUVA(picture, colorspace, 0.f, 0);
+}
+
+int WebPPictureSmartARGBToYUVA(WebPPicture* picture) {
+  return PictureARGBToYUVA(picture, WEBP_YUV420, 0.f, 1);
+}
+
+//------------------------------------------------------------------------------
+// call for YUVA -> ARGB conversion
+
+int WebPPictureYUVAToARGB(WebPPicture* picture) {
+  if (picture == NULL) return 0;
+  if (picture->y == NULL || picture->u == NULL || picture->v == NULL) {
+    return WebPEncodingSetError(picture, VP8_ENC_ERROR_NULL_PARAMETER);
+  }
+  if ((picture->colorspace & WEBP_CSP_ALPHA_BIT) && picture->a == NULL) {
+    return WebPEncodingSetError(picture, VP8_ENC_ERROR_NULL_PARAMETER);
+  }
+  if ((picture->colorspace & WEBP_CSP_UV_MASK) != WEBP_YUV420) {
+    return WebPEncodingSetError(picture, VP8_ENC_ERROR_INVALID_CONFIGURATION);
+  }
+  // Allocate a new argb buffer (discarding the previous one).
+  if (!WebPPictureAllocARGB(picture, picture->width, picture->height)) return 0;
+  picture->use_argb = 1;
+
+  // Convert
+  {
+    int y;
+    const int width = picture->width;
+    const int height = picture->height;
+    const int argb_stride = 4 * picture->argb_stride;
+    uint8_t* dst = (uint8_t*)picture->argb;
+    const uint8_t *cur_u = picture->u, *cur_v = picture->v, *cur_y = picture->y;
+    WebPUpsampleLinePairFunc upsample = WebPGetLinePairConverter(ALPHA_IS_LAST);
+
+    // First row, with replicated top samples.
+    upsample(cur_y, NULL, cur_u, cur_v, cur_u, cur_v, dst, NULL, width);
+    cur_y += picture->y_stride;
+    dst += argb_stride;
+    // Center rows.
+    for (y = 1; y + 1 < height; y += 2) {
+      const uint8_t* const top_u = cur_u;
+      const uint8_t* const top_v = cur_v;
+      cur_u += picture->uv_stride;
+      cur_v += picture->uv_stride;
+      upsample(cur_y, cur_y + picture->y_stride, top_u, top_v, cur_u, cur_v,
+               dst, dst + argb_stride, width);
+      cur_y += 2 * picture->y_stride;
+      dst += 2 * argb_stride;
+    }
+    // Last row (if needed), with replicated bottom samples.
+    if (height > 1 && !(height & 1)) {
+      upsample(cur_y, NULL, cur_u, cur_v, cur_u, cur_v, dst, NULL, width);
+    }
+    // Insert alpha values if needed, in replacement for the default 0xff ones.
+    if (picture->colorspace & WEBP_CSP_ALPHA_BIT) {
+      for (y = 0; y < height; ++y) {
+        uint32_t* const argb_dst = picture->argb + y * picture->argb_stride;
+        const uint8_t* const src = picture->a + y * picture->a_stride;
+        int x;
+        for (x = 0; x < width; ++x) {
+          argb_dst[x] = (argb_dst[x] & 0x00ffffffu) | ((uint32_t)src[x] << 24);
+        }
+      }
+    }
+  }
+  return 1;
+}
+
+//------------------------------------------------------------------------------
+// automatic import / conversion
+
+static int Import(WebPPicture* const picture,
+                  const uint8_t* const rgb, int rgb_stride,
+                  int step, int swap_rb, int import_alpha) {
+  int y;
+  const uint8_t* const r_ptr = rgb + (swap_rb ? 2 : 0);
+  const uint8_t* const g_ptr = rgb + 1;
+  const uint8_t* const b_ptr = rgb + (swap_rb ? 0 : 2);
+  const uint8_t* const a_ptr = import_alpha ? rgb + 3 : NULL;
+  const int width = picture->width;
+  const int height = picture->height;
+
+  if (!picture->use_argb) {
+    return ImportYUVAFromRGBA(r_ptr, g_ptr, b_ptr, a_ptr, step, rgb_stride,
+                              0.f /* no dithering */, 0, picture);
+  }
+  if (!WebPPictureAlloc(picture)) return 0;
+
+  VP8EncDspARGBInit();
+
+  if (import_alpha) {
+    assert(step == 4);
+    for (y = 0; y < height; ++y) {
+      uint32_t* const dst = &picture->argb[y * picture->argb_stride];
+      const int offset = y * rgb_stride;
+      VP8PackARGB(a_ptr + offset, r_ptr + offset, g_ptr + offset,
+                  b_ptr + offset, width, dst);
+    }
+  } else {
+    assert(step >= 3);
+    for (y = 0; y < height; ++y) {
+      uint32_t* const dst = &picture->argb[y * picture->argb_stride];
+      const int offset = y * rgb_stride;
+      VP8PackRGB(r_ptr + offset, g_ptr + offset, b_ptr + offset,
+                 width, step, dst);
+    }
+  }
+  return 1;
+}
+
+// Public API
+
+int WebPPictureImportRGB(WebPPicture* picture,
+                         const uint8_t* rgb, int rgb_stride) {
+  return (picture != NULL) ? Import(picture, rgb, rgb_stride, 3, 0, 0) : 0;
+}
+
+int WebPPictureImportBGR(WebPPicture* picture,
+                         const uint8_t* rgb, int rgb_stride) {
+  return (picture != NULL) ? Import(picture, rgb, rgb_stride, 3, 1, 0) : 0;
+}
+
+int WebPPictureImportRGBA(WebPPicture* picture,
+                          const uint8_t* rgba, int rgba_stride) {
+  return (picture != NULL) ? Import(picture, rgba, rgba_stride, 4, 0, 1) : 0;
+}
+
+int WebPPictureImportBGRA(WebPPicture* picture,
+                          const uint8_t* rgba, int rgba_stride) {
+  return (picture != NULL) ? Import(picture, rgba, rgba_stride, 4, 1, 1) : 0;
+}
+
+int WebPPictureImportRGBX(WebPPicture* picture,
+                          const uint8_t* rgba, int rgba_stride) {
+  return (picture != NULL) ? Import(picture, rgba, rgba_stride, 4, 0, 0) : 0;
+}
+
+int WebPPictureImportBGRX(WebPPicture* picture,
+                          const uint8_t* rgba, int rgba_stride) {
+  return (picture != NULL) ? Import(picture, rgba, rgba_stride, 4, 1, 0) : 0;
+}
+
+//------------------------------------------------------------------------------
diff --git a/Source/LibWebP/src/enc/enc.picture_psnr.c b/Source/LibWebP/src/enc/enc.picture_psnr.c
new file mode 100644
index 0000000..1247452
--- /dev/null
+++ b/Source/LibWebP/src/enc/enc.picture_psnr.c
@@ -0,0 +1,150 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// WebPPicture tools for measuring distortion
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include <math.h>
+
+#include "./vp8enci.h"
+
+//------------------------------------------------------------------------------
+// local-min distortion
+//
+// For every pixel in the *reference* picture, we search for the local best
+// match in the compressed image. This is not a symmetrical measure.
+
+#define RADIUS 2  // search radius. Shouldn't be too large.
+
+static float AccumulateLSIM(const uint8_t* src, int src_stride,
+                            const uint8_t* ref, int ref_stride,
+                            int w, int h) {
+  int x, y;
+  double total_sse = 0.;
+  for (y = 0; y < h; ++y) {
+    const int y_0 = (y - RADIUS < 0) ? 0 : y - RADIUS;
+    const int y_1 = (y + RADIUS + 1 >= h) ? h : y + RADIUS + 1;
+    for (x = 0; x < w; ++x) {
+      const int x_0 = (x - RADIUS < 0) ? 0 : x - RADIUS;
+      const int x_1 = (x + RADIUS + 1 >= w) ? w : x + RADIUS + 1;
+      double best_sse = 255. * 255.;
+      const double value = (double)ref[y * ref_stride + x];
+      int i, j;
+      for (j = y_0; j < y_1; ++j) {
+        const uint8_t* s = src + j * src_stride;
+        for (i = x_0; i < x_1; ++i) {
+          const double sse = (double)(s[i] - value) * (s[i] - value);
+          if (sse < best_sse) best_sse = sse;
+        }
+      }
+      total_sse += best_sse;
+    }
+  }
+  return (float)total_sse;
+}
+#undef RADIUS
+
+//------------------------------------------------------------------------------
+// Distortion
+
+// Max value returned in case of exact similarity.
+static const double kMinDistortion_dB = 99.;
+static float GetPSNR(const double v) {
+  return (float)((v > 0.) ? -4.3429448 * log(v / (255 * 255.))
+                          : kMinDistortion_dB);
+}
+
+int WebPPictureDistortion(const WebPPicture* src, const WebPPicture* ref,
+                          int type, float result[5]) {
+  DistoStats stats[5];
+  int has_alpha;
+  int uv_w, uv_h;
+
+  if (src == NULL || ref == NULL ||
+      src->width != ref->width || src->height != ref->height ||
+      src->y == NULL || ref->y == NULL ||
+      src->u == NULL || ref->u == NULL ||
+      src->v == NULL || ref->v == NULL ||
+      result == NULL) {
+    return 0;
+  }
+  // TODO(skal): provide distortion for ARGB too.
+  if (src->use_argb == 1 || src->use_argb != ref->use_argb) {
+    return 0;
+  }
+
+  has_alpha = !!(src->colorspace & WEBP_CSP_ALPHA_BIT);
+  if (has_alpha != !!(ref->colorspace & WEBP_CSP_ALPHA_BIT) ||
+      (has_alpha && (src->a == NULL || ref->a == NULL))) {
+    return 0;
+  }
+
+  memset(stats, 0, sizeof(stats));
+
+  uv_w = (src->width + 1) >> 1;
+  uv_h = (src->height + 1) >> 1;
+  if (type >= 2) {
+    float sse[4];
+    sse[0] = AccumulateLSIM(src->y, src->y_stride,
+                            ref->y, ref->y_stride, src->width, src->height);
+    sse[1] = AccumulateLSIM(src->u, src->uv_stride,
+                            ref->u, ref->uv_stride, uv_w, uv_h);
+    sse[2] = AccumulateLSIM(src->v, src->uv_stride,
+                            ref->v, ref->uv_stride, uv_w, uv_h);
+    sse[3] = has_alpha ? AccumulateLSIM(src->a, src->a_stride,
+                                        ref->a, ref->a_stride,
+                                        src->width, src->height)
+                       : 0.f;
+    result[0] = GetPSNR(sse[0] / (src->width * src->height));
+    result[1] = GetPSNR(sse[1] / (uv_w * uv_h));
+    result[2] = GetPSNR(sse[2] / (uv_w * uv_h));
+    result[3] = GetPSNR(sse[3] / (src->width * src->height));
+    {
+      double total_sse = sse[0] + sse[1] + sse[2];
+      int total_pixels = src->width * src->height + 2 * uv_w * uv_h;
+      if (has_alpha) {
+        total_pixels += src->width * src->height;
+        total_sse += sse[3];
+      }
+      result[4] = GetPSNR(total_sse / total_pixels);
+    }
+  } else {
+    int c;
+    VP8SSIMAccumulatePlane(src->y, src->y_stride,
+                           ref->y, ref->y_stride,
+                           src->width, src->height, &stats[0]);
+    VP8SSIMAccumulatePlane(src->u, src->uv_stride,
+                           ref->u, ref->uv_stride,
+                           uv_w, uv_h, &stats[1]);
+    VP8SSIMAccumulatePlane(src->v, src->uv_stride,
+                           ref->v, ref->uv_stride,
+                           uv_w, uv_h, &stats[2]);
+    if (has_alpha) {
+      VP8SSIMAccumulatePlane(src->a, src->a_stride,
+                             ref->a, ref->a_stride,
+                             src->width, src->height, &stats[3]);
+    }
+    for (c = 0; c <= 4; ++c) {
+      if (type == 1) {
+        const double v = VP8SSIMGet(&stats[c]);
+        result[c] = (float)((v < 1.) ? -10.0 * log10(1. - v)
+                                     : kMinDistortion_dB);
+      } else {
+        const double v = VP8SSIMGetSquaredError(&stats[c]);
+        result[c] = GetPSNR(v);
+      }
+      // Accumulate forward
+      if (c < 4) VP8SSIMAddStats(&stats[c], &stats[4]);
+    }
+  }
+  return 1;
+}
+
+//------------------------------------------------------------------------------
diff --git a/Source/LibWebP/src/enc/enc.picture_rescale.c b/Source/LibWebP/src/enc/enc.picture_rescale.c
new file mode 100644
index 0000000..1de7b67
--- /dev/null
+++ b/Source/LibWebP/src/enc/enc.picture_rescale.c
@@ -0,0 +1,285 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// WebPPicture tools: copy, crop, rescaling and view.
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include "./vp8enci.h"
+#include "../utils/rescaler.h"
+#include "../utils/utils.h"
+
+#define HALVE(x) (((x) + 1) >> 1)
+
+// Grab the 'specs' (writer, *opaque, width, height...) from 'src' and copy them
+// into 'dst'. Mark 'dst' as not owning any memory.
+static void PictureGrabSpecs(const WebPPicture* const src,
+                             WebPPicture* const dst) {
+  assert(src != NULL && dst != NULL);
+  *dst = *src;
+  WebPPictureResetBuffers(dst);
+}
+
+//------------------------------------------------------------------------------
+// Picture copying
+
+static void CopyPlane(const uint8_t* src, int src_stride,
+                      uint8_t* dst, int dst_stride, int width, int height) {
+  while (height-- > 0) {
+    memcpy(dst, src, width);
+    src += src_stride;
+    dst += dst_stride;
+  }
+}
+
+// Adjust top-left corner to chroma sample position.
+static void SnapTopLeftPosition(const WebPPicture* const pic,
+                                int* const left, int* const top) {
+  if (!pic->use_argb) {
+    *left &= ~1;
+    *top &= ~1;
+  }
+}
+
+// Adjust top-left corner and verify that the sub-rectangle is valid.
+static int AdjustAndCheckRectangle(const WebPPicture* const pic,
+                                   int* const left, int* const top,
+                                   int width, int height) {
+  SnapTopLeftPosition(pic, left, top);
+  if ((*left) < 0 || (*top) < 0) return 0;
+  if (width <= 0 || height <= 0) return 0;
+  if ((*left) + width > pic->width) return 0;
+  if ((*top) + height > pic->height) return 0;
+  return 1;
+}
+
+int WebPPictureCopy(const WebPPicture* src, WebPPicture* dst) {
+  if (src == NULL || dst == NULL) return 0;
+  if (src == dst) return 1;
+
+  PictureGrabSpecs(src, dst);
+  if (!WebPPictureAlloc(dst)) return 0;
+
+  if (!src->use_argb) {
+    CopyPlane(src->y, src->y_stride,
+              dst->y, dst->y_stride, dst->width, dst->height);
+    CopyPlane(src->u, src->uv_stride,
+              dst->u, dst->uv_stride, HALVE(dst->width), HALVE(dst->height));
+    CopyPlane(src->v, src->uv_stride,
+              dst->v, dst->uv_stride, HALVE(dst->width), HALVE(dst->height));
+    if (dst->a != NULL)  {
+      CopyPlane(src->a, src->a_stride,
+                dst->a, dst->a_stride, dst->width, dst->height);
+    }
+  } else {
+    CopyPlane((const uint8_t*)src->argb, 4 * src->argb_stride,
+              (uint8_t*)dst->argb, 4 * dst->argb_stride,
+              4 * dst->width, dst->height);
+  }
+  return 1;
+}
+
+int WebPPictureIsView(const WebPPicture* picture) {
+  if (picture == NULL) return 0;
+  if (picture->use_argb) {
+    return (picture->memory_argb_ == NULL);
+  }
+  return (picture->memory_ == NULL);
+}
+
+int WebPPictureView(const WebPPicture* src,
+                    int left, int top, int width, int height,
+                    WebPPicture* dst) {
+  if (src == NULL || dst == NULL) return 0;
+
+  // verify rectangle position.
+  if (!AdjustAndCheckRectangle(src, &left, &top, width, height)) return 0;
+
+  if (src != dst) {  // beware of aliasing! We don't want to leak 'memory_'.
+    PictureGrabSpecs(src, dst);
+  }
+  dst->width = width;
+  dst->height = height;
+  if (!src->use_argb) {
+    dst->y = src->y + top * src->y_stride + left;
+    dst->u = src->u + (top >> 1) * src->uv_stride + (left >> 1);
+    dst->v = src->v + (top >> 1) * src->uv_stride + (left >> 1);
+    dst->y_stride = src->y_stride;
+    dst->uv_stride = src->uv_stride;
+    if (src->a != NULL) {
+      dst->a = src->a + top * src->a_stride + left;
+      dst->a_stride = src->a_stride;
+    }
+  } else {
+    dst->argb = src->argb + top * src->argb_stride + left;
+    dst->argb_stride = src->argb_stride;
+  }
+  return 1;
+}
+
+//------------------------------------------------------------------------------
+// Picture cropping
+
+int WebPPictureCrop(WebPPicture* pic,
+                    int left, int top, int width, int height) {
+  WebPPicture tmp;
+
+  if (pic == NULL) return 0;
+  if (!AdjustAndCheckRectangle(pic, &left, &top, width, height)) return 0;
+
+  PictureGrabSpecs(pic, &tmp);
+  tmp.width = width;
+  tmp.height = height;
+  if (!WebPPictureAlloc(&tmp)) return 0;
+
+  if (!pic->use_argb) {
+    const int y_offset = top * pic->y_stride + left;
+    const int uv_offset = (top / 2) * pic->uv_stride + left / 2;
+    CopyPlane(pic->y + y_offset, pic->y_stride,
+              tmp.y, tmp.y_stride, width, height);
+    CopyPlane(pic->u + uv_offset, pic->uv_stride,
+              tmp.u, tmp.uv_stride, HALVE(width), HALVE(height));
+    CopyPlane(pic->v + uv_offset, pic->uv_stride,
+              tmp.v, tmp.uv_stride, HALVE(width), HALVE(height));
+
+    if (tmp.a != NULL) {
+      const int a_offset = top * pic->a_stride + left;
+      CopyPlane(pic->a + a_offset, pic->a_stride,
+                tmp.a, tmp.a_stride, width, height);
+    }
+  } else {
+    const uint8_t* const src =
+        (const uint8_t*)(pic->argb + top * pic->argb_stride + left);
+    CopyPlane(src, pic->argb_stride * 4,
+              (uint8_t*)tmp.argb, tmp.argb_stride * 4,
+              width * 4, height);
+  }
+  WebPPictureFree(pic);
+  *pic = tmp;
+  return 1;
+}
+
+//------------------------------------------------------------------------------
+// Simple picture rescaler
+
+static void RescalePlane(const uint8_t* src,
+                         int src_width, int src_height, int src_stride,
+                         uint8_t* dst,
+                         int dst_width, int dst_height, int dst_stride,
+                         int32_t* const work,
+                         int num_channels) {
+  WebPRescaler rescaler;
+  int y = 0;
+  WebPRescalerInit(&rescaler, src_width, src_height,
+                   dst, dst_width, dst_height, dst_stride,
+                   num_channels,
+                   src_width, dst_width,
+                   src_height, dst_height,
+                   work);
+  memset(work, 0, 2 * dst_width * num_channels * sizeof(*work));
+  while (y < src_height) {
+    y += WebPRescalerImport(&rescaler, src_height - y,
+                            src + y * src_stride, src_stride);
+    WebPRescalerExport(&rescaler);
+  }
+}
+
+static void AlphaMultiplyARGB(WebPPicture* const pic, int inverse) {
+  assert(pic->argb != NULL);
+  WebPMultARGBRows((uint8_t*)pic->argb, pic->argb_stride * sizeof(*pic->argb),
+                   pic->width, pic->height, inverse);
+}
+
+static void AlphaMultiplyY(WebPPicture* const pic, int inverse) {
+  if (pic->a != NULL) {
+    WebPMultRows(pic->y, pic->y_stride, pic->a, pic->a_stride,
+                 pic->width, pic->height, inverse);
+  }
+}
+
+int WebPPictureRescale(WebPPicture* pic, int width, int height) {
+  WebPPicture tmp;
+  int prev_width, prev_height;
+  int32_t* work;
+
+  if (pic == NULL) return 0;
+  prev_width = pic->width;
+  prev_height = pic->height;
+  // if width is unspecified, scale original proportionally to height ratio.
+  if (width == 0) {
+    width = (prev_width * height + prev_height / 2) / prev_height;
+  }
+  // if height is unspecified, scale original proportionally to width ratio.
+  if (height == 0) {
+    height = (prev_height * width + prev_width / 2) / prev_width;
+  }
+  // Check if the overall dimensions still make sense.
+  if (width <= 0 || height <= 0) return 0;
+
+  PictureGrabSpecs(pic, &tmp);
+  tmp.width = width;
+  tmp.height = height;
+  if (!WebPPictureAlloc(&tmp)) return 0;
+
+  if (!pic->use_argb) {
+    work = (int32_t*)WebPSafeMalloc(2ULL * width, sizeof(*work));
+    if (work == NULL) {
+      WebPPictureFree(&tmp);
+      return 0;
+    }
+    // If present, we need to rescale alpha first (for AlphaMultiplyY).
+    if (pic->a != NULL) {
+      WebPInitAlphaProcessing();
+      RescalePlane(pic->a, prev_width, prev_height, pic->a_stride,
+                   tmp.a, width, height, tmp.a_stride, work, 1);
+    }
+
+    // We take transparency into account on the luma plane only. That's not
+    // totally exact blending, but still is a good approximation.
+    AlphaMultiplyY(pic, 0);
+    RescalePlane(pic->y, prev_width, prev_height, pic->y_stride,
+                 tmp.y, width, height, tmp.y_stride, work, 1);
+    AlphaMultiplyY(&tmp, 1);
+
+    RescalePlane(pic->u,
+                 HALVE(prev_width), HALVE(prev_height), pic->uv_stride,
+                 tmp.u,
+                 HALVE(width), HALVE(height), tmp.uv_stride, work, 1);
+    RescalePlane(pic->v,
+                 HALVE(prev_width), HALVE(prev_height), pic->uv_stride,
+                 tmp.v,
+                 HALVE(width), HALVE(height), tmp.uv_stride, work, 1);
+  } else {
+    work = (int32_t*)WebPSafeMalloc(2ULL * width * 4, sizeof(*work));
+    if (work == NULL) {
+      WebPPictureFree(&tmp);
+      return 0;
+    }
+    // In order to correctly interpolate colors, we need to apply the alpha
+    // weighting first (black-matting), scale the RGB values, and remove
+    // the premultiplication afterward (while preserving the alpha channel).
+    WebPInitAlphaProcessing();
+    AlphaMultiplyARGB(pic, 0);
+    RescalePlane((const uint8_t*)pic->argb, prev_width, prev_height,
+                 pic->argb_stride * 4,
+                 (uint8_t*)tmp.argb, width, height,
+                 tmp.argb_stride * 4,
+                 work, 4);
+    AlphaMultiplyARGB(&tmp, 1);
+  }
+  WebPPictureFree(pic);
+  WebPSafeFree(work);
+  *pic = tmp;
+  return 1;
+}
+
+//------------------------------------------------------------------------------
diff --git a/Source/LibWebP/src/enc/enc.picture_tools.c b/Source/LibWebP/src/enc/enc.picture_tools.c
new file mode 100644
index 0000000..5d5679b
--- /dev/null
+++ b/Source/LibWebP/src/enc/enc.picture_tools.c
@@ -0,0 +1,206 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// WebPPicture tools: alpha handling, etc.
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include "./vp8enci.h"
+#include "../dsp/yuv.h"
+
+static WEBP_INLINE uint32_t MakeARGB32(int r, int g, int b) {
+  return (0xff000000u | (r << 16) | (g << 8) | b);
+}
+
+//------------------------------------------------------------------------------
+// Helper: clean up fully transparent area to help compressibility.
+
+#define SIZE 8
+#define SIZE2 (SIZE / 2)
+static int is_transparent_area(const uint8_t* ptr, int stride, int size) {
+  int y, x;
+  for (y = 0; y < size; ++y) {
+    for (x = 0; x < size; ++x) {
+      if (ptr[x]) {
+        return 0;
+      }
+    }
+    ptr += stride;
+  }
+  return 1;
+}
+
+static int is_transparent_argb_area(const uint32_t* ptr, int stride, int size) {
+  int y, x;
+  for (y = 0; y < size; ++y) {
+    for (x = 0; x < size; ++x) {
+      if (ptr[x] & 0xff000000u) {
+        return 0;
+      }
+    }
+    ptr += stride;
+  }
+  return 1;
+}
+
+static void flatten(uint8_t* ptr, int v, int stride, int size) {
+  int y;
+  for (y = 0; y < size; ++y) {
+    memset(ptr, v, size);
+    ptr += stride;
+  }
+}
+
+static void flatten_argb(uint32_t* ptr, uint32_t v, int stride, int size) {
+  int x, y;
+  for (y = 0; y < size; ++y) {
+    for (x = 0; x < size; ++x) ptr[x] = v;
+    ptr += stride;
+  }
+}
+
+void WebPCleanupTransparentArea(WebPPicture* pic) {
+  int x, y, w, h;
+  if (pic == NULL) return;
+  w = pic->width / SIZE;
+  h = pic->height / SIZE;
+
+  // note: we ignore the left-overs on right/bottom
+  if (pic->use_argb) {
+    uint32_t argb_value = 0;
+    for (y = 0; y < h; ++y) {
+      int need_reset = 1;
+      for (x = 0; x < w; ++x) {
+        const int off = (y * pic->argb_stride + x) * SIZE;
+        if (is_transparent_argb_area(pic->argb + off, pic->argb_stride, SIZE)) {
+          if (need_reset) {
+            argb_value = pic->argb[off];
+            need_reset = 0;
+          }
+          flatten_argb(pic->argb + off, argb_value, pic->argb_stride, SIZE);
+        } else {
+          need_reset = 1;
+        }
+      }
+    }
+  } else {
+    const uint8_t* const a_ptr = pic->a;
+    int values[3] = { 0 };
+    if (a_ptr == NULL) return;    // nothing to do
+    for (y = 0; y < h; ++y) {
+      int need_reset = 1;
+      for (x = 0; x < w; ++x) {
+        const int off_a = (y * pic->a_stride + x) * SIZE;
+        const int off_y = (y * pic->y_stride + x) * SIZE;
+        const int off_uv = (y * pic->uv_stride + x) * SIZE2;
+        if (is_transparent_area(a_ptr + off_a, pic->a_stride, SIZE)) {
+          if (need_reset) {
+            values[0] = pic->y[off_y];
+            values[1] = pic->u[off_uv];
+            values[2] = pic->v[off_uv];
+            need_reset = 0;
+          }
+          flatten(pic->y + off_y, values[0], pic->y_stride, SIZE);
+          flatten(pic->u + off_uv, values[1], pic->uv_stride, SIZE2);
+          flatten(pic->v + off_uv, values[2], pic->uv_stride, SIZE2);
+        } else {
+          need_reset = 1;
+        }
+      }
+    }
+  }
+}
+
+#undef SIZE
+#undef SIZE2
+
+//------------------------------------------------------------------------------
+// Blend color and remove transparency info
+
+#define BLEND(V0, V1, ALPHA) \
+    ((((V0) * (255 - (ALPHA)) + (V1) * (ALPHA)) * 0x101) >> 16)
+#define BLEND_10BIT(V0, V1, ALPHA) \
+    ((((V0) * (1020 - (ALPHA)) + (V1) * (ALPHA)) * 0x101) >> 18)
+
+void WebPBlendAlpha(WebPPicture* pic, uint32_t background_rgb) {
+  const int red = (background_rgb >> 16) & 0xff;
+  const int green = (background_rgb >> 8) & 0xff;
+  const int blue = (background_rgb >> 0) & 0xff;
+  int x, y;
+  if (pic == NULL) return;
+  if (!pic->use_argb) {
+    const int uv_width = (pic->width >> 1);  // omit last pixel during u/v loop
+    const int Y0 = VP8RGBToY(red, green, blue, YUV_HALF);
+    // VP8RGBToU/V expects the u/v values summed over four pixels
+    const int U0 = VP8RGBToU(4 * red, 4 * green, 4 * blue, 4 * YUV_HALF);
+    const int V0 = VP8RGBToV(4 * red, 4 * green, 4 * blue, 4 * YUV_HALF);
+    const int has_alpha = pic->colorspace & WEBP_CSP_ALPHA_BIT;
+    if (!has_alpha || pic->a == NULL) return;    // nothing to do
+    for (y = 0; y < pic->height; ++y) {
+      // Luma blending
+      uint8_t* const y_ptr = pic->y + y * pic->y_stride;
+      uint8_t* const a_ptr = pic->a + y * pic->a_stride;
+      for (x = 0; x < pic->width; ++x) {
+        const int alpha = a_ptr[x];
+        if (alpha < 0xff) {
+          y_ptr[x] = BLEND(Y0, y_ptr[x], a_ptr[x]);
+        }
+      }
+      // Chroma blending every even line
+      if ((y & 1) == 0) {
+        uint8_t* const u = pic->u + (y >> 1) * pic->uv_stride;
+        uint8_t* const v = pic->v + (y >> 1) * pic->uv_stride;
+        uint8_t* const a_ptr2 =
+            (y + 1 == pic->height) ? a_ptr : a_ptr + pic->a_stride;
+        for (x = 0; x < uv_width; ++x) {
+          // Average four alpha values into a single blending weight.
+          // TODO(skal): might lead to visible contouring. Can we do better?
+          const int alpha =
+              a_ptr[2 * x + 0] + a_ptr[2 * x + 1] +
+              a_ptr2[2 * x + 0] + a_ptr2[2 * x + 1];
+          u[x] = BLEND_10BIT(U0, u[x], alpha);
+          v[x] = BLEND_10BIT(V0, v[x], alpha);
+        }
+        if (pic->width & 1) {   // rightmost pixel
+          const int alpha = 2 * (a_ptr[2 * x + 0] + a_ptr2[2 * x + 0]);
+          u[x] = BLEND_10BIT(U0, u[x], alpha);
+          v[x] = BLEND_10BIT(V0, v[x], alpha);
+        }
+      }
+      memset(a_ptr, 0xff, pic->width);
+    }
+  } else {
+    uint32_t* argb = pic->argb;
+    const uint32_t background = MakeARGB32(red, green, blue);
+    for (y = 0; y < pic->height; ++y) {
+      for (x = 0; x < pic->width; ++x) {
+        const int alpha = (argb[x] >> 24) & 0xff;
+        if (alpha != 0xff) {
+          if (alpha > 0) {
+            int r = (argb[x] >> 16) & 0xff;
+            int g = (argb[x] >>  8) & 0xff;
+            int b = (argb[x] >>  0) & 0xff;
+            r = BLEND(red, r, alpha);
+            g = BLEND(green, g, alpha);
+            b = BLEND(blue, b, alpha);
+            argb[x] = MakeARGB32(r, g, b);
+          } else {
+            argb[x] = background;
+          }
+        }
+      }
+      argb += pic->argb_stride;
+    }
+  }
+}
+
+#undef BLEND
+#undef BLEND_10BIT
+
+//------------------------------------------------------------------------------
diff --git a/Source/LibWebP/src/enc/enc.quant.c b/Source/LibWebP/src/enc/enc.quant.c
new file mode 100644
index 0000000..de4a94c
--- /dev/null
+++ b/Source/LibWebP/src/enc/enc.quant.c
@@ -0,0 +1,1191 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+//   Quantization
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include <assert.h>
+#include <math.h>
+#include <stdlib.h>  // for abs()
+
+#include "./vp8enci.h"
+#include "./cost.h"
+
+#define DO_TRELLIS_I4  1
+#define DO_TRELLIS_I16 1   // not a huge gain, but ok at low bitrate.
+#define DO_TRELLIS_UV  0   // disable trellis for UV. Risky. Not worth.
+#define USE_TDISTO 1
+
+#define MID_ALPHA 64      // neutral value for susceptibility
+#define MIN_ALPHA 30      // lowest usable value for susceptibility
+#define MAX_ALPHA 100     // higher meaningful value for susceptibility
+
+#define SNS_TO_DQ 0.9     // Scaling constant between the sns value and the QP
+                          // power-law modulation. Must be strictly less than 1.
+
+#define I4_PENALTY 4000   // Rate-penalty for quick i4/i16 decision
+
+// number of non-zero coeffs below which we consider the block very flat
+// (and apply a penalty to complex predictions)
+#define FLATNESS_LIMIT_I16 10      // I16 mode
+#define FLATNESS_LIMIT_I4  3       // I4 mode
+#define FLATNESS_LIMIT_UV  2       // UV mode
+#define FLATNESS_PENALTY   140     // roughly ~1bit per block
+
+#define MULT_8B(a, b) (((a) * (b) + 128) >> 8)
+
+// #define DEBUG_BLOCK
+
+//------------------------------------------------------------------------------
+
+#if defined(DEBUG_BLOCK)
+
+#include <stdio.h>
+#include <stdlib.h>
+
+static void PrintBlockInfo(const VP8EncIterator* const it,
+                           const VP8ModeScore* const rd) {
+  int i, j;
+  const int is_i16 = (it->mb_->type_ == 1);
+  printf("SOURCE / OUTPUT / ABS DELTA\n");
+  for (j = 0; j < 24; ++j) {
+    if (j == 16) printf("\n");   // newline before the U/V block
+    for (i = 0; i < 16; ++i) printf("%3d ", it->yuv_in_[i + j * BPS]);
+    printf("     ");
+    for (i = 0; i < 16; ++i) printf("%3d ", it->yuv_out_[i + j * BPS]);
+    printf("     ");
+    for (i = 0; i < 16; ++i) {
+      printf("%1d ", abs(it->yuv_out_[i + j * BPS] - it->yuv_in_[i + j * BPS]));
+    }
+    printf("\n");
+  }
+  printf("\nD:%d SD:%d R:%d H:%d nz:0x%x score:%d\n",
+    (int)rd->D, (int)rd->SD, (int)rd->R, (int)rd->H, (int)rd->nz,
+    (int)rd->score);
+  if (is_i16) {
+    printf("Mode: %d\n", rd->mode_i16);
+    printf("y_dc_levels:");
+    for (i = 0; i < 16; ++i) printf("%3d ", rd->y_dc_levels[i]);
+    printf("\n");
+  } else {
+    printf("Modes[16]: ");
+    for (i = 0; i < 16; ++i) printf("%d ", rd->modes_i4[i]);
+    printf("\n");
+  }
+  printf("y_ac_levels:\n");
+  for (j = 0; j < 16; ++j) {
+    for (i = is_i16 ? 1 : 0; i < 16; ++i) {
+      printf("%4d ", rd->y_ac_levels[j][i]);
+    }
+    printf("\n");
+  }
+  printf("\n");
+  printf("uv_levels (mode=%d):\n", rd->mode_uv);
+  for (j = 0; j < 8; ++j) {
+    for (i = 0; i < 16; ++i) {
+      printf("%4d ", rd->uv_levels[j][i]);
+    }
+    printf("\n");
+  }
+}
+
+#endif   // DEBUG_BLOCK
+
+//------------------------------------------------------------------------------
+
+static WEBP_INLINE int clip(int v, int m, int M) {
+  return v < m ? m : v > M ? M : v;
+}
+
+static const uint8_t kZigzag[16] = {
+  0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15
+};
+
+static const uint8_t kDcTable[128] = {
+  4,     5,   6,   7,   8,   9,  10,  10,
+  11,   12,  13,  14,  15,  16,  17,  17,
+  18,   19,  20,  20,  21,  21,  22,  22,
+  23,   23,  24,  25,  25,  26,  27,  28,
+  29,   30,  31,  32,  33,  34,  35,  36,
+  37,   37,  38,  39,  40,  41,  42,  43,
+  44,   45,  46,  46,  47,  48,  49,  50,
+  51,   52,  53,  54,  55,  56,  57,  58,
+  59,   60,  61,  62,  63,  64,  65,  66,
+  67,   68,  69,  70,  71,  72,  73,  74,
+  75,   76,  76,  77,  78,  79,  80,  81,
+  82,   83,  84,  85,  86,  87,  88,  89,
+  91,   93,  95,  96,  98, 100, 101, 102,
+  104, 106, 108, 110, 112, 114, 116, 118,
+  122, 124, 126, 128, 130, 132, 134, 136,
+  138, 140, 143, 145, 148, 151, 154, 157
+};
+
+static const uint16_t kAcTable[128] = {
+  4,     5,   6,   7,   8,   9,  10,  11,
+  12,   13,  14,  15,  16,  17,  18,  19,
+  20,   21,  22,  23,  24,  25,  26,  27,
+  28,   29,  30,  31,  32,  33,  34,  35,
+  36,   37,  38,  39,  40,  41,  42,  43,
+  44,   45,  46,  47,  48,  49,  50,  51,
+  52,   53,  54,  55,  56,  57,  58,  60,
+  62,   64,  66,  68,  70,  72,  74,  76,
+  78,   80,  82,  84,  86,  88,  90,  92,
+  94,   96,  98, 100, 102, 104, 106, 108,
+  110, 112, 114, 116, 119, 122, 125, 128,
+  131, 134, 137, 140, 143, 146, 149, 152,
+  155, 158, 161, 164, 167, 170, 173, 177,
+  181, 185, 189, 193, 197, 201, 205, 209,
+  213, 217, 221, 225, 229, 234, 239, 245,
+  249, 254, 259, 264, 269, 274, 279, 284
+};
+
+static const uint16_t kAcTable2[128] = {
+  8,     8,   9,  10,  12,  13,  15,  17,
+  18,   20,  21,  23,  24,  26,  27,  29,
+  31,   32,  34,  35,  37,  38,  40,  41,
+  43,   44,  46,  48,  49,  51,  52,  54,
+  55,   57,  58,  60,  62,  63,  65,  66,
+  68,   69,  71,  72,  74,  75,  77,  79,
+  80,   82,  83,  85,  86,  88,  89,  93,
+  96,   99, 102, 105, 108, 111, 114, 117,
+  120, 124, 127, 130, 133, 136, 139, 142,
+  145, 148, 151, 155, 158, 161, 164, 167,
+  170, 173, 176, 179, 184, 189, 193, 198,
+  203, 207, 212, 217, 221, 226, 230, 235,
+  240, 244, 249, 254, 258, 263, 268, 274,
+  280, 286, 292, 299, 305, 311, 317, 323,
+  330, 336, 342, 348, 354, 362, 370, 379,
+  385, 393, 401, 409, 416, 424, 432, 440
+};
+
+static const uint8_t kBiasMatrices[3][2] = {  // [luma-ac,luma-dc,chroma][dc,ac]
+  { 96, 110 }, { 96, 108 }, { 110, 115 }
+};
+
+// Sharpening by (slightly) raising the hi-frequency coeffs.
+// Hack-ish but helpful for mid-bitrate range. Use with care.
+#define SHARPEN_BITS 11  // number of descaling bits for sharpening bias
+static const uint8_t kFreqSharpening[16] = {
+  0,  30, 60, 90,
+  30, 60, 90, 90,
+  60, 90, 90, 90,
+  90, 90, 90, 90
+};
+
+//------------------------------------------------------------------------------
+// Initialize quantization parameters in VP8Matrix
+
+// Returns the average quantizer
+static int ExpandMatrix(VP8Matrix* const m, int type) {
+  int i, sum;
+  for (i = 0; i < 2; ++i) {
+    const int is_ac_coeff = (i > 0);
+    const int bias = kBiasMatrices[type][is_ac_coeff];
+    m->iq_[i] = (1 << QFIX) / m->q_[i];
+    m->bias_[i] = BIAS(bias);
+    // zthresh_ is the exact value such that QUANTDIV(coeff, iQ, B) is:
+    //   * zero if coeff <= zthresh
+    //   * non-zero if coeff > zthresh
+    m->zthresh_[i] = ((1 << QFIX) - 1 - m->bias_[i]) / m->iq_[i];
+  }
+  for (i = 2; i < 16; ++i) {
+    m->q_[i] = m->q_[1];
+    m->iq_[i] = m->iq_[1];
+    m->bias_[i] = m->bias_[1];
+    m->zthresh_[i] = m->zthresh_[1];
+  }
+  for (sum = 0, i = 0; i < 16; ++i) {
+    if (type == 0) {  // we only use sharpening for AC luma coeffs
+      m->sharpen_[i] = (kFreqSharpening[i] * m->q_[i]) >> SHARPEN_BITS;
+    } else {
+      m->sharpen_[i] = 0;
+    }
+    sum += m->q_[i];
+  }
+  return (sum + 8) >> 4;
+}
+
+static void SetupMatrices(VP8Encoder* enc) {
+  int i;
+  const int tlambda_scale =
+    (enc->method_ >= 4) ? enc->config_->sns_strength
+                        : 0;
+  const int num_segments = enc->segment_hdr_.num_segments_;
+  for (i = 0; i < num_segments; ++i) {
+    VP8SegmentInfo* const m = &enc->dqm_[i];
+    const int q = m->quant_;
+    int q4, q16, quv;
+    m->y1_.q_[0] = kDcTable[clip(q + enc->dq_y1_dc_, 0, 127)];
+    m->y1_.q_[1] = kAcTable[clip(q,                  0, 127)];
+
+    m->y2_.q_[0] = kDcTable[ clip(q + enc->dq_y2_dc_, 0, 127)] * 2;
+    m->y2_.q_[1] = kAcTable2[clip(q + enc->dq_y2_ac_, 0, 127)];
+
+    m->uv_.q_[0] = kDcTable[clip(q + enc->dq_uv_dc_, 0, 117)];
+    m->uv_.q_[1] = kAcTable[clip(q + enc->dq_uv_ac_, 0, 127)];
+
+    q4  = ExpandMatrix(&m->y1_, 0);
+    q16 = ExpandMatrix(&m->y2_, 1);
+    quv = ExpandMatrix(&m->uv_, 2);
+
+    m->lambda_i4_          = (3 * q4 * q4) >> 7;
+    m->lambda_i16_         = (3 * q16 * q16);
+    m->lambda_uv_          = (3 * quv * quv) >> 6;
+    m->lambda_mode_        = (1 * q4 * q4) >> 7;
+    m->lambda_trellis_i4_  = (7 * q4 * q4) >> 3;
+    m->lambda_trellis_i16_ = (q16 * q16) >> 2;
+    m->lambda_trellis_uv_  = (quv *quv) << 1;
+    m->tlambda_            = (tlambda_scale * q4) >> 5;
+
+    m->min_disto_ = 10 * m->y1_.q_[0];   // quantization-aware min disto
+    m->max_edge_  = 0;
+  }
+}
+
+//------------------------------------------------------------------------------
+// Initialize filtering parameters
+
+// Very small filter-strength values have close to no visual effect. So we can
+// save a little decoding-CPU by turning filtering off for these.
+#define FSTRENGTH_CUTOFF 2
+
+static void SetupFilterStrength(VP8Encoder* const enc) {
+  int i;
+  // level0 is in [0..500]. Using '-f 50' as filter_strength is mid-filtering.
+  const int level0 = 5 * enc->config_->filter_strength;
+  for (i = 0; i < NUM_MB_SEGMENTS; ++i) {
+    VP8SegmentInfo* const m = &enc->dqm_[i];
+    // We focus on the quantization of AC coeffs.
+    const int qstep = kAcTable[clip(m->quant_, 0, 127)] >> 2;
+    const int base_strength =
+        VP8FilterStrengthFromDelta(enc->filter_hdr_.sharpness_, qstep);
+    // Segments with lower complexity ('beta') will be less filtered.
+    const int f = base_strength * level0 / (256 + m->beta_);
+    m->fstrength_ = (f < FSTRENGTH_CUTOFF) ? 0 : (f > 63) ? 63 : f;
+  }
+  // We record the initial strength (mainly for the case of 1-segment only).
+  enc->filter_hdr_.level_ = enc->dqm_[0].fstrength_;
+  enc->filter_hdr_.simple_ = (enc->config_->filter_type == 0);
+  enc->filter_hdr_.sharpness_ = enc->config_->filter_sharpness;
+}
+
+//------------------------------------------------------------------------------
+
+// Note: if you change the values below, remember that the max range
+// allowed by the syntax for DQ_UV is [-16,16].
+#define MAX_DQ_UV (6)
+#define MIN_DQ_UV (-4)
+
+// We want to emulate jpeg-like behaviour where the expected "good" quality
+// is around q=75. Internally, our "good" middle is around c=50. So we
+// map accordingly using linear piece-wise function
+static double QualityToCompression(double c) {
+  const double linear_c = (c < 0.75) ? c * (2. / 3.) : 2. * c - 1.;
+  // The file size roughly scales as pow(quantizer, 3.). Actually, the
+  // exponent is somewhere between 2.8 and 3.2, but we're mostly interested
+  // in the mid-quant range. So we scale the compressibility inversely to
+  // this power-law: quant ~= compression ^ 1/3. This law holds well for
+  // low quant. Finer modeling for high-quant would make use of kAcTable[]
+  // more explicitly.
+  const double v = pow(linear_c, 1 / 3.);
+  return v;
+}
+
+static double QualityToJPEGCompression(double c, double alpha) {
+  // We map the complexity 'alpha' and quality setting 'c' to a compression
+  // exponent empirically matched to the compression curve of libjpeg6b.
+  // On average, the WebP output size will be roughly similar to that of a
+  // JPEG file compressed with same quality factor.
+  const double amin = 0.30;
+  const double amax = 0.85;
+  const double exp_min = 0.4;
+  const double exp_max = 0.9;
+  const double slope = (exp_min - exp_max) / (amax - amin);
+  // Linearly interpolate 'expn' from exp_min to exp_max
+  // in the [amin, amax] range.
+  const double expn = (alpha > amax) ? exp_min
+                    : (alpha < amin) ? exp_max
+                    : exp_max + slope * (alpha - amin);
+  const double v = pow(c, expn);
+  return v;
+}
+
+static int SegmentsAreEquivalent(const VP8SegmentInfo* const S1,
+                                 const VP8SegmentInfo* const S2) {
+  return (S1->quant_ == S2->quant_) && (S1->fstrength_ == S2->fstrength_);
+}
+
+static void SimplifySegments(VP8Encoder* const enc) {
+  int map[NUM_MB_SEGMENTS] = { 0, 1, 2, 3 };
+  const int num_segments = enc->segment_hdr_.num_segments_;
+  int num_final_segments = 1;
+  int s1, s2;
+  for (s1 = 1; s1 < num_segments; ++s1) {    // find similar segments
+    const VP8SegmentInfo* const S1 = &enc->dqm_[s1];
+    int found = 0;
+    // check if we already have similar segment
+    for (s2 = 0; s2 < num_final_segments; ++s2) {
+      const VP8SegmentInfo* const S2 = &enc->dqm_[s2];
+      if (SegmentsAreEquivalent(S1, S2)) {
+        found = 1;
+        break;
+      }
+    }
+    map[s1] = s2;
+    if (!found) {
+      if (num_final_segments != s1) {
+        enc->dqm_[num_final_segments] = enc->dqm_[s1];
+      }
+      ++num_final_segments;
+    }
+  }
+  if (num_final_segments < num_segments) {  // Remap
+    int i = enc->mb_w_ * enc->mb_h_;
+    while (i-- > 0) enc->mb_info_[i].segment_ = map[enc->mb_info_[i].segment_];
+    enc->segment_hdr_.num_segments_ = num_final_segments;
+    // Replicate the trailing segment infos (it's mostly cosmetics)
+    for (i = num_final_segments; i < num_segments; ++i) {
+      enc->dqm_[i] = enc->dqm_[num_final_segments - 1];
+    }
+  }
+}
+
+void VP8SetSegmentParams(VP8Encoder* const enc, float quality) {
+  int i;
+  int dq_uv_ac, dq_uv_dc;
+  const int num_segments = enc->segment_hdr_.num_segments_;
+  const double amp = SNS_TO_DQ * enc->config_->sns_strength / 100. / 128.;
+  const double Q = quality / 100.;
+  const double c_base = enc->config_->emulate_jpeg_size ?
+      QualityToJPEGCompression(Q, enc->alpha_ / 255.) :
+      QualityToCompression(Q);
+  for (i = 0; i < num_segments; ++i) {
+    // We modulate the base coefficient to accommodate for the quantization
+    // susceptibility and allow denser segments to be quantized more.
+    const double expn = 1. - amp * enc->dqm_[i].alpha_;
+    const double c = pow(c_base, expn);
+    const int q = (int)(127. * (1. - c));
+    assert(expn > 0.);
+    enc->dqm_[i].quant_ = clip(q, 0, 127);
+  }
+
+  // purely indicative in the bitstream (except for the 1-segment case)
+  enc->base_quant_ = enc->dqm_[0].quant_;
+
+  // fill-in values for the unused segments (required by the syntax)
+  for (i = num_segments; i < NUM_MB_SEGMENTS; ++i) {
+    enc->dqm_[i].quant_ = enc->base_quant_;
+  }
+
+  // uv_alpha_ is normally spread around ~60. The useful range is
+  // typically ~30 (quite bad) to ~100 (ok to decimate UV more).
+  // We map it to the safe maximal range of MAX/MIN_DQ_UV for dq_uv.
+  dq_uv_ac = (enc->uv_alpha_ - MID_ALPHA) * (MAX_DQ_UV - MIN_DQ_UV)
+                                          / (MAX_ALPHA - MIN_ALPHA);
+  // we rescale by the user-defined strength of adaptation
+  dq_uv_ac = dq_uv_ac * enc->config_->sns_strength / 100;
+  // and make it safe.
+  dq_uv_ac = clip(dq_uv_ac, MIN_DQ_UV, MAX_DQ_UV);
+  // We also boost the dc-uv-quant a little, based on sns-strength, since
+  // U/V channels are quite more reactive to high quants (flat DC-blocks
+  // tend to appear, and are unpleasant).
+  dq_uv_dc = -4 * enc->config_->sns_strength / 100;
+  dq_uv_dc = clip(dq_uv_dc, -15, 15);   // 4bit-signed max allowed
+
+  enc->dq_y1_dc_ = 0;       // TODO(skal): dq-lum
+  enc->dq_y2_dc_ = 0;
+  enc->dq_y2_ac_ = 0;
+  enc->dq_uv_dc_ = dq_uv_dc;
+  enc->dq_uv_ac_ = dq_uv_ac;
+
+  SetupFilterStrength(enc);   // initialize segments' filtering, eventually
+
+  if (num_segments > 1) SimplifySegments(enc);
+
+  SetupMatrices(enc);         // finalize quantization matrices
+}
+
+//------------------------------------------------------------------------------
+// Form the predictions in cache
+
+// Must be ordered using {DC_PRED, TM_PRED, V_PRED, H_PRED} as index
+const int VP8I16ModeOffsets[4] = { I16DC16, I16TM16, I16VE16, I16HE16 };
+const int VP8UVModeOffsets[4] = { C8DC8, C8TM8, C8VE8, C8HE8 };
+
+// Must be indexed using {B_DC_PRED -> B_HU_PRED} as index
+const int VP8I4ModeOffsets[NUM_BMODES] = {
+  I4DC4, I4TM4, I4VE4, I4HE4, I4RD4, I4VR4, I4LD4, I4VL4, I4HD4, I4HU4
+};
+
+void VP8MakeLuma16Preds(const VP8EncIterator* const it) {
+  const uint8_t* const left = it->x_ ? it->y_left_ : NULL;
+  const uint8_t* const top = it->y_ ? it->y_top_ : NULL;
+  VP8EncPredLuma16(it->yuv_p_, left, top);
+}
+
+void VP8MakeChroma8Preds(const VP8EncIterator* const it) {
+  const uint8_t* const left = it->x_ ? it->u_left_ : NULL;
+  const uint8_t* const top = it->y_ ? it->uv_top_ : NULL;
+  VP8EncPredChroma8(it->yuv_p_, left, top);
+}
+
+void VP8MakeIntra4Preds(const VP8EncIterator* const it) {
+  VP8EncPredLuma4(it->yuv_p_, it->i4_top_);
+}
+
+//------------------------------------------------------------------------------
+// Quantize
+
+// Layout:
+// +----+----+
+// |YYYY|UUVV| 0
+// |YYYY|UUVV| 4
+// |YYYY|....| 8
+// |YYYY|....| 12
+// +----+----+
+
+const int VP8Scan[16] = {  // Luma
+  0 +  0 * BPS,  4 +  0 * BPS, 8 +  0 * BPS, 12 +  0 * BPS,
+  0 +  4 * BPS,  4 +  4 * BPS, 8 +  4 * BPS, 12 +  4 * BPS,
+  0 +  8 * BPS,  4 +  8 * BPS, 8 +  8 * BPS, 12 +  8 * BPS,
+  0 + 12 * BPS,  4 + 12 * BPS, 8 + 12 * BPS, 12 + 12 * BPS,
+};
+
+static const int VP8ScanUV[4 + 4] = {
+  0 + 0 * BPS,   4 + 0 * BPS, 0 + 4 * BPS,  4 + 4 * BPS,    // U
+  8 + 0 * BPS,  12 + 0 * BPS, 8 + 4 * BPS, 12 + 4 * BPS     // V
+};
+
+//------------------------------------------------------------------------------
+// Distortion measurement
+
+static const uint16_t kWeightY[16] = {
+  38, 32, 20, 9, 32, 28, 17, 7, 20, 17, 10, 4, 9, 7, 4, 2
+};
+
+static const uint16_t kWeightTrellis[16] = {
+#if USE_TDISTO == 0
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
+#else
+  30, 27, 19, 11,
+  27, 24, 17, 10,
+  19, 17, 12,  8,
+  11, 10,  8,  6
+#endif
+};
+
+// Init/Copy the common fields in score.
+static void InitScore(VP8ModeScore* const rd) {
+  rd->D  = 0;
+  rd->SD = 0;
+  rd->R  = 0;
+  rd->H  = 0;
+  rd->nz = 0;
+  rd->score = MAX_COST;
+}
+
+static void CopyScore(VP8ModeScore* const dst, const VP8ModeScore* const src) {
+  dst->D  = src->D;
+  dst->SD = src->SD;
+  dst->R  = src->R;
+  dst->H  = src->H;
+  dst->nz = src->nz;      // note that nz is not accumulated, but just copied.
+  dst->score = src->score;
+}
+
+static void AddScore(VP8ModeScore* const dst, const VP8ModeScore* const src) {
+  dst->D  += src->D;
+  dst->SD += src->SD;
+  dst->R  += src->R;
+  dst->H  += src->H;
+  dst->nz |= src->nz;     // here, new nz bits are accumulated.
+  dst->score += src->score;
+}
+
+//------------------------------------------------------------------------------
+// Performs trellis-optimized quantization.
+
+// Trellis node
+typedef struct {
+  int8_t prev;            // best previous node
+  int8_t sign;            // sign of coeff_i
+  int16_t level;          // level
+} Node;
+
+// Score state
+typedef struct {
+  score_t score;          // partial RD score
+  const uint16_t* costs;  // shortcut to cost tables
+} ScoreState;
+
+// If a coefficient was quantized to a value Q (using a neutral bias),
+// we test all alternate possibilities between [Q-MIN_DELTA, Q+MAX_DELTA]
+// We don't test negative values though.
+#define MIN_DELTA 0   // how much lower level to try
+#define MAX_DELTA 1   // how much higher
+#define NUM_NODES (MIN_DELTA + 1 + MAX_DELTA)
+#define NODE(n, l) (nodes[(n)][(l) + MIN_DELTA])
+#define SCORE_STATE(n, l) (score_states[n][(l) + MIN_DELTA])
+
+static WEBP_INLINE void SetRDScore(int lambda, VP8ModeScore* const rd) {
+  // TODO: incorporate the "* 256" in the tables?
+  rd->score = (rd->R + rd->H) * lambda + 256 * (rd->D + rd->SD);
+}
+
+static WEBP_INLINE score_t RDScoreTrellis(int lambda, score_t rate,
+                                          score_t distortion) {
+  return rate * lambda + 256 * distortion;
+}
+
+static int TrellisQuantizeBlock(const VP8Encoder* const enc,
+                                int16_t in[16], int16_t out[16],
+                                int ctx0, int coeff_type,
+                                const VP8Matrix* const mtx,
+                                int lambda) {
+  const ProbaArray* const probas = enc->proba_.coeffs_[coeff_type];
+  CostArrayPtr const costs =
+      (CostArrayPtr)enc->proba_.remapped_costs_[coeff_type];
+  const int first = (coeff_type == 0) ? 1 : 0;
+  Node nodes[16][NUM_NODES];
+  ScoreState score_states[2][NUM_NODES];
+  ScoreState* ss_cur = &SCORE_STATE(0, MIN_DELTA);
+  ScoreState* ss_prev = &SCORE_STATE(1, MIN_DELTA);
+  int best_path[3] = {-1, -1, -1};   // store best-last/best-level/best-previous
+  score_t best_score;
+  int n, m, p, last;
+
+  {
+    score_t cost;
+    const int thresh = mtx->q_[1] * mtx->q_[1] / 4;
+    const int last_proba = probas[VP8EncBands[first]][ctx0][0];
+
+    // compute the position of the last interesting coefficient
+    last = first - 1;
+    for (n = 15; n >= first; --n) {
+      const int j = kZigzag[n];
+      const int err = in[j] * in[j];
+      if (err > thresh) {
+        last = n;
+        break;
+      }
+    }
+    // we don't need to go inspect up to n = 16 coeffs. We can just go up
+    // to last + 1 (inclusive) without losing much.
+    if (last < 15) ++last;
+
+    // compute 'skip' score. This is the max score one can do.
+    cost = VP8BitCost(0, last_proba);
+    best_score = RDScoreTrellis(lambda, cost, 0);
+
+    // initialize source node.
+    for (m = -MIN_DELTA; m <= MAX_DELTA; ++m) {
+      const score_t rate = (ctx0 == 0) ? VP8BitCost(1, last_proba) : 0;
+      ss_cur[m].score = RDScoreTrellis(lambda, rate, 0);
+      ss_cur[m].costs = costs[first][ctx0];
+    }
+  }
+
+  // traverse trellis.
+  for (n = first; n <= last; ++n) {
+    const int j = kZigzag[n];
+    const uint32_t Q  = mtx->q_[j];
+    const uint32_t iQ = mtx->iq_[j];
+    const uint32_t B = BIAS(0x00);     // neutral bias
+    // note: it's important to take sign of the _original_ coeff,
+    // so we don't have to consider level < 0 afterward.
+    const int sign = (in[j] < 0);
+    const uint32_t coeff0 = (sign ? -in[j] : in[j]) + mtx->sharpen_[j];
+    int level0 = QUANTDIV(coeff0, iQ, B);
+    if (level0 > MAX_LEVEL) level0 = MAX_LEVEL;
+
+    {   // Swap current and previous score states
+      ScoreState* const tmp = ss_cur;
+      ss_cur = ss_prev;
+      ss_prev = tmp;
+    }
+
+    // test all alternate level values around level0.
+    for (m = -MIN_DELTA; m <= MAX_DELTA; ++m) {
+      Node* const cur = &NODE(n, m);
+      int level = level0 + m;
+      const int ctx = (level > 2) ? 2 : level;
+      const int band = VP8EncBands[n + 1];
+      score_t base_score, last_pos_score;
+      score_t best_cur_score = MAX_COST;
+      int best_prev = 0;   // default, in case
+
+      ss_cur[m].score = MAX_COST;
+      ss_cur[m].costs = costs[n + 1][ctx];
+      if (level > MAX_LEVEL || level < 0) {   // node is dead?
+        continue;
+      }
+
+      // Compute extra rate cost if last coeff's position is < 15
+      {
+        const score_t last_pos_cost =
+            (n < 15) ? VP8BitCost(0, probas[band][ctx][0]) : 0;
+        last_pos_score = RDScoreTrellis(lambda, last_pos_cost, 0);
+      }
+
+      {
+        // Compute delta_error = how much coding this level will
+        // subtract to max_error as distortion.
+        // Here, distortion = sum of (|coeff_i| - level_i * Q_i)^2
+        const int new_error = coeff0 - level * Q;
+        const int delta_error =
+            kWeightTrellis[j] * (new_error * new_error - coeff0 * coeff0);
+        base_score = RDScoreTrellis(lambda, 0, delta_error);
+      }
+
+      // Inspect all possible non-dead predecessors. Retain only the best one.
+      for (p = -MIN_DELTA; p <= MAX_DELTA; ++p) {
+        // Dead nodes (with ss_prev[p].score >= MAX_COST) are automatically
+        // eliminated since their score can't be better than the current best.
+        const score_t cost = VP8LevelCost(ss_prev[p].costs, level);
+        // Examine node assuming it's a non-terminal one.
+        const score_t score =
+            base_score + ss_prev[p].score + RDScoreTrellis(lambda, cost, 0);
+        if (score < best_cur_score) {
+          best_cur_score = score;
+          best_prev = p;
+        }
+      }
+      // Store best finding in current node.
+      cur->sign = sign;
+      cur->level = level;
+      cur->prev = best_prev;
+      ss_cur[m].score = best_cur_score;
+
+      // Now, record best terminal node (and thus best entry in the graph).
+      if (level != 0) {
+        const score_t score = best_cur_score + last_pos_score;
+        if (score < best_score) {
+          best_score = score;
+          best_path[0] = n;                     // best eob position
+          best_path[1] = m;                     // best node index
+          best_path[2] = best_prev;             // best predecessor
+        }
+      }
+    }
+  }
+
+  // Fresh start
+  memset(in + first, 0, (16 - first) * sizeof(*in));
+  memset(out + first, 0, (16 - first) * sizeof(*out));
+  if (best_path[0] == -1) {
+    return 0;   // skip!
+  }
+
+  {
+    // Unwind the best path.
+    // Note: best-prev on terminal node is not necessarily equal to the
+    // best_prev for non-terminal. So we patch best_path[2] in.
+    int nz = 0;
+    int best_node = best_path[1];
+    n = best_path[0];
+    NODE(n, best_node).prev = best_path[2];   // force best-prev for terminal
+
+    for (; n >= first; --n) {
+      const Node* const node = &NODE(n, best_node);
+      const int j = kZigzag[n];
+      out[n] = node->sign ? -node->level : node->level;
+      nz |= node->level;
+      in[j] = out[n] * mtx->q_[j];
+      best_node = node->prev;
+    }
+    return (nz != 0);
+  }
+}
+
+#undef NODE
+
+//------------------------------------------------------------------------------
+// Performs: difference, transform, quantize, back-transform, add
+// all at once. Output is the reconstructed block in *yuv_out, and the
+// quantized levels in *levels.
+
+static int ReconstructIntra16(VP8EncIterator* const it,
+                              VP8ModeScore* const rd,
+                              uint8_t* const yuv_out,
+                              int mode) {
+  const VP8Encoder* const enc = it->enc_;
+  const uint8_t* const ref = it->yuv_p_ + VP8I16ModeOffsets[mode];
+  const uint8_t* const src = it->yuv_in_ + Y_OFF;
+  const VP8SegmentInfo* const dqm = &enc->dqm_[it->mb_->segment_];
+  int nz = 0;
+  int n;
+  int16_t tmp[16][16], dc_tmp[16];
+
+  for (n = 0; n < 16; ++n) {
+    VP8FTransform(src + VP8Scan[n], ref + VP8Scan[n], tmp[n]);
+  }
+  VP8FTransformWHT(tmp[0], dc_tmp);
+  nz |= VP8EncQuantizeBlockWHT(dc_tmp, rd->y_dc_levels, &dqm->y2_) << 24;
+
+  if (DO_TRELLIS_I16 && it->do_trellis_) {
+    int x, y;
+    VP8IteratorNzToBytes(it);
+    for (y = 0, n = 0; y < 4; ++y) {
+      for (x = 0; x < 4; ++x, ++n) {
+        const int ctx = it->top_nz_[x] + it->left_nz_[y];
+        const int non_zero =
+            TrellisQuantizeBlock(enc, tmp[n], rd->y_ac_levels[n], ctx, 0,
+                                 &dqm->y1_, dqm->lambda_trellis_i16_);
+        it->top_nz_[x] = it->left_nz_[y] = non_zero;
+        rd->y_ac_levels[n][0] = 0;
+        nz |= non_zero << n;
+      }
+    }
+  } else {
+    for (n = 0; n < 16; n += 2) {
+      // Zero-out the first coeff, so that: a) nz is correct below, and
+      // b) finding 'last' non-zero coeffs in SetResidualCoeffs() is simplified.
+      tmp[n][0] = tmp[n + 1][0] = 0;
+      nz |= VP8EncQuantize2Blocks(tmp[n], rd->y_ac_levels[n], &dqm->y1_) << n;
+      assert(rd->y_ac_levels[n + 0][0] == 0);
+      assert(rd->y_ac_levels[n + 1][0] == 0);
+    }
+  }
+
+  // Transform back
+  VP8TransformWHT(dc_tmp, tmp[0]);
+  for (n = 0; n < 16; n += 2) {
+    VP8ITransform(ref + VP8Scan[n], tmp[n], yuv_out + VP8Scan[n], 1);
+  }
+
+  return nz;
+}
+
+static int ReconstructIntra4(VP8EncIterator* const it,
+                             int16_t levels[16],
+                             const uint8_t* const src,
+                             uint8_t* const yuv_out,
+                             int mode) {
+  const VP8Encoder* const enc = it->enc_;
+  const uint8_t* const ref = it->yuv_p_ + VP8I4ModeOffsets[mode];
+  const VP8SegmentInfo* const dqm = &enc->dqm_[it->mb_->segment_];
+  int nz = 0;
+  int16_t tmp[16];
+
+  VP8FTransform(src, ref, tmp);
+  if (DO_TRELLIS_I4 && it->do_trellis_) {
+    const int x = it->i4_ & 3, y = it->i4_ >> 2;
+    const int ctx = it->top_nz_[x] + it->left_nz_[y];
+    nz = TrellisQuantizeBlock(enc, tmp, levels, ctx, 3, &dqm->y1_,
+                              dqm->lambda_trellis_i4_);
+  } else {
+    nz = VP8EncQuantizeBlock(tmp, levels, &dqm->y1_);
+  }
+  VP8ITransform(ref, tmp, yuv_out, 0);
+  return nz;
+}
+
+static int ReconstructUV(VP8EncIterator* const it, VP8ModeScore* const rd,
+                         uint8_t* const yuv_out, int mode) {
+  const VP8Encoder* const enc = it->enc_;
+  const uint8_t* const ref = it->yuv_p_ + VP8UVModeOffsets[mode];
+  const uint8_t* const src = it->yuv_in_ + U_OFF;
+  const VP8SegmentInfo* const dqm = &enc->dqm_[it->mb_->segment_];
+  int nz = 0;
+  int n;
+  int16_t tmp[8][16];
+
+  for (n = 0; n < 8; ++n) {
+    VP8FTransform(src + VP8ScanUV[n], ref + VP8ScanUV[n], tmp[n]);
+  }
+  if (DO_TRELLIS_UV && it->do_trellis_) {
+    int ch, x, y;
+    for (ch = 0, n = 0; ch <= 2; ch += 2) {
+      for (y = 0; y < 2; ++y) {
+        for (x = 0; x < 2; ++x, ++n) {
+          const int ctx = it->top_nz_[4 + ch + x] + it->left_nz_[4 + ch + y];
+          const int non_zero =
+              TrellisQuantizeBlock(enc, tmp[n], rd->uv_levels[n], ctx, 2,
+                                   &dqm->uv_, dqm->lambda_trellis_uv_);
+          it->top_nz_[4 + ch + x] = it->left_nz_[4 + ch + y] = non_zero;
+          nz |= non_zero << n;
+        }
+      }
+    }
+  } else {
+    for (n = 0; n < 8; n += 2) {
+      nz |= VP8EncQuantize2Blocks(tmp[n], rd->uv_levels[n], &dqm->uv_) << n;
+    }
+  }
+
+  for (n = 0; n < 8; n += 2) {
+    VP8ITransform(ref + VP8ScanUV[n], tmp[n], yuv_out + VP8ScanUV[n], 1);
+  }
+  return (nz << 16);
+}
+
+//------------------------------------------------------------------------------
+// RD-opt decision. Reconstruct each modes, evalue distortion and bit-cost.
+// Pick the mode is lower RD-cost = Rate + lambda * Distortion.
+
+static void StoreMaxDelta(VP8SegmentInfo* const dqm, const int16_t DCs[16]) {
+  // We look at the first three AC coefficients to determine what is the average
+  // delta between each sub-4x4 block.
+  const int v0 = abs(DCs[1]);
+  const int v1 = abs(DCs[4]);
+  const int v2 = abs(DCs[5]);
+  int max_v = (v0 > v1) ? v1 : v0;
+  max_v = (v2 > max_v) ? v2 : max_v;
+  if (max_v > dqm->max_edge_) dqm->max_edge_ = max_v;
+}
+
+static void SwapModeScore(VP8ModeScore** a, VP8ModeScore** b) {
+  VP8ModeScore* const tmp = *a;
+  *a = *b;
+  *b = tmp;
+}
+
+static void SwapPtr(uint8_t** a, uint8_t** b) {
+  uint8_t* const tmp = *a;
+  *a = *b;
+  *b = tmp;
+}
+
+static void SwapOut(VP8EncIterator* const it) {
+  SwapPtr(&it->yuv_out_, &it->yuv_out2_);
+}
+
+static score_t IsFlat(const int16_t* levels, int num_blocks, score_t thresh) {
+  score_t score = 0;
+  while (num_blocks-- > 0) {      // TODO(skal): refine positional scoring?
+    int i;
+    for (i = 1; i < 16; ++i) {    // omit DC, we're only interested in AC
+      score += (levels[i] != 0);
+      if (score > thresh) return 0;
+    }
+    levels += 16;
+  }
+  return 1;
+}
+
+static void PickBestIntra16(VP8EncIterator* const it, VP8ModeScore* rd) {
+  const int kNumBlocks = 16;
+  VP8SegmentInfo* const dqm = &it->enc_->dqm_[it->mb_->segment_];
+  const int lambda = dqm->lambda_i16_;
+  const int tlambda = dqm->tlambda_;
+  const uint8_t* const src = it->yuv_in_ + Y_OFF;
+  VP8ModeScore rd_tmp;
+  VP8ModeScore* rd_cur = &rd_tmp;
+  VP8ModeScore* rd_best = rd;
+  int mode;
+
+  rd->mode_i16 = -1;
+  for (mode = 0; mode < NUM_PRED_MODES; ++mode) {
+    uint8_t* const tmp_dst = it->yuv_out2_ + Y_OFF;  // scratch buffer
+    rd_cur->mode_i16 = mode;
+
+    // Reconstruct
+    rd_cur->nz = ReconstructIntra16(it, rd_cur, tmp_dst, mode);
+
+    // Measure RD-score
+    rd_cur->D = VP8SSE16x16(src, tmp_dst);
+    rd_cur->SD =
+        tlambda ? MULT_8B(tlambda, VP8TDisto16x16(src, tmp_dst, kWeightY)) : 0;
+    rd_cur->H = VP8FixedCostsI16[mode];
+    rd_cur->R = VP8GetCostLuma16(it, rd_cur);
+    if (mode > 0 &&
+        IsFlat(rd_cur->y_ac_levels[0], kNumBlocks, FLATNESS_LIMIT_I16)) {
+      // penalty to avoid flat area to be mispredicted by complex mode
+      rd_cur->R += FLATNESS_PENALTY * kNumBlocks;
+    }
+
+    // Since we always examine Intra16 first, we can overwrite *rd directly.
+    SetRDScore(lambda, rd_cur);
+    if (mode == 0 || rd_cur->score < rd_best->score) {
+      SwapModeScore(&rd_cur, &rd_best);
+      SwapOut(it);
+    }
+  }
+  if (rd_best != rd) {
+    memcpy(rd, rd_best, sizeof(*rd));
+  }
+  SetRDScore(dqm->lambda_mode_, rd);   // finalize score for mode decision.
+  VP8SetIntra16Mode(it, rd->mode_i16);
+
+  // we have a blocky macroblock (only DCs are non-zero) with fairly high
+  // distortion, record max delta so we can later adjust the minimal filtering
+  // strength needed to smooth these blocks out.
+  if ((rd->nz & 0xffff) == 0 && rd->D > dqm->min_disto_) {
+    StoreMaxDelta(dqm, rd->y_dc_levels);
+  }
+}
+
+//------------------------------------------------------------------------------
+
+// return the cost array corresponding to the surrounding prediction modes.
+static const uint16_t* GetCostModeI4(VP8EncIterator* const it,
+                                     const uint8_t modes[16]) {
+  const int preds_w = it->enc_->preds_w_;
+  const int x = (it->i4_ & 3), y = it->i4_ >> 2;
+  const int left = (x == 0) ? it->preds_[y * preds_w - 1] : modes[it->i4_ - 1];
+  const int top = (y == 0) ? it->preds_[-preds_w + x] : modes[it->i4_ - 4];
+  return VP8FixedCostsI4[top][left];
+}
+
+static int PickBestIntra4(VP8EncIterator* const it, VP8ModeScore* const rd) {
+  const VP8Encoder* const enc = it->enc_;
+  const VP8SegmentInfo* const dqm = &enc->dqm_[it->mb_->segment_];
+  const int lambda = dqm->lambda_i4_;
+  const int tlambda = dqm->tlambda_;
+  const uint8_t* const src0 = it->yuv_in_ + Y_OFF;
+  uint8_t* const best_blocks = it->yuv_out2_ + Y_OFF;
+  int total_header_bits = 0;
+  VP8ModeScore rd_best;
+
+  if (enc->max_i4_header_bits_ == 0) {
+    return 0;
+  }
+
+  InitScore(&rd_best);
+  rd_best.H = 211;  // '211' is the value of VP8BitCost(0, 145)
+  SetRDScore(dqm->lambda_mode_, &rd_best);
+  VP8IteratorStartI4(it);
+  do {
+    const int kNumBlocks = 1;
+    VP8ModeScore rd_i4;
+    int mode;
+    int best_mode = -1;
+    const uint8_t* const src = src0 + VP8Scan[it->i4_];
+    const uint16_t* const mode_costs = GetCostModeI4(it, rd->modes_i4);
+    uint8_t* best_block = best_blocks + VP8Scan[it->i4_];
+    uint8_t* tmp_dst = it->yuv_p_ + I4TMP;    // scratch buffer.
+
+    InitScore(&rd_i4);
+    VP8MakeIntra4Preds(it);
+    for (mode = 0; mode < NUM_BMODES; ++mode) {
+      VP8ModeScore rd_tmp;
+      int16_t tmp_levels[16];
+
+      // Reconstruct
+      rd_tmp.nz =
+          ReconstructIntra4(it, tmp_levels, src, tmp_dst, mode) << it->i4_;
+
+      // Compute RD-score
+      rd_tmp.D = VP8SSE4x4(src, tmp_dst);
+      rd_tmp.SD =
+          tlambda ? MULT_8B(tlambda, VP8TDisto4x4(src, tmp_dst, kWeightY))
+                  : 0;
+      rd_tmp.H = mode_costs[mode];
+
+      // Add flatness penalty
+      if (mode > 0 && IsFlat(tmp_levels, kNumBlocks, FLATNESS_LIMIT_I4)) {
+        rd_tmp.R = FLATNESS_PENALTY * kNumBlocks;
+      } else {
+        rd_tmp.R = 0;
+      }
+
+      // early-out check
+      SetRDScore(lambda, &rd_tmp);
+      if (best_mode >= 0 && rd_tmp.score >= rd_i4.score) continue;
+
+      // finish computing score
+      rd_tmp.R += VP8GetCostLuma4(it, tmp_levels);
+      SetRDScore(lambda, &rd_tmp);
+
+      if (best_mode < 0 || rd_tmp.score < rd_i4.score) {
+        CopyScore(&rd_i4, &rd_tmp);
+        best_mode = mode;
+        SwapPtr(&tmp_dst, &best_block);
+        memcpy(rd_best.y_ac_levels[it->i4_], tmp_levels,
+               sizeof(rd_best.y_ac_levels[it->i4_]));
+      }
+    }
+    SetRDScore(dqm->lambda_mode_, &rd_i4);
+    AddScore(&rd_best, &rd_i4);
+    if (rd_best.score >= rd->score) {
+      return 0;
+    }
+    total_header_bits += (int)rd_i4.H;   // <- equal to mode_costs[best_mode];
+    if (total_header_bits > enc->max_i4_header_bits_) {
+      return 0;
+    }
+    // Copy selected samples if not in the right place already.
+    if (best_block != best_blocks + VP8Scan[it->i4_]) {
+      VP8Copy4x4(best_block, best_blocks + VP8Scan[it->i4_]);
+    }
+    rd->modes_i4[it->i4_] = best_mode;
+    it->top_nz_[it->i4_ & 3] = it->left_nz_[it->i4_ >> 2] = (rd_i4.nz ? 1 : 0);
+  } while (VP8IteratorRotateI4(it, best_blocks));
+
+  // finalize state
+  CopyScore(rd, &rd_best);
+  VP8SetIntra4Mode(it, rd->modes_i4);
+  SwapOut(it);
+  memcpy(rd->y_ac_levels, rd_best.y_ac_levels, sizeof(rd->y_ac_levels));
+  return 1;   // select intra4x4 over intra16x16
+}
+
+//------------------------------------------------------------------------------
+
+static void PickBestUV(VP8EncIterator* const it, VP8ModeScore* const rd) {
+  const int kNumBlocks = 8;
+  const VP8SegmentInfo* const dqm = &it->enc_->dqm_[it->mb_->segment_];
+  const int lambda = dqm->lambda_uv_;
+  const uint8_t* const src = it->yuv_in_ + U_OFF;
+  uint8_t* tmp_dst = it->yuv_out2_ + U_OFF;  // scratch buffer
+  uint8_t* dst0 = it->yuv_out_ + U_OFF;
+  uint8_t* dst = dst0;
+  VP8ModeScore rd_best;
+  int mode;
+
+  rd->mode_uv = -1;
+  InitScore(&rd_best);
+  for (mode = 0; mode < NUM_PRED_MODES; ++mode) {
+    VP8ModeScore rd_uv;
+
+    // Reconstruct
+    rd_uv.nz = ReconstructUV(it, &rd_uv, tmp_dst, mode);
+
+    // Compute RD-score
+    rd_uv.D  = VP8SSE16x8(src, tmp_dst);
+    rd_uv.SD = 0;    // TODO: should we call TDisto? it tends to flatten areas.
+    rd_uv.H  = VP8FixedCostsUV[mode];
+    rd_uv.R  = VP8GetCostUV(it, &rd_uv);
+    if (mode > 0 && IsFlat(rd_uv.uv_levels[0], kNumBlocks, FLATNESS_LIMIT_UV)) {
+      rd_uv.R += FLATNESS_PENALTY * kNumBlocks;
+    }
+
+    SetRDScore(lambda, &rd_uv);
+    if (mode == 0 || rd_uv.score < rd_best.score) {
+      CopyScore(&rd_best, &rd_uv);
+      rd->mode_uv = mode;
+      memcpy(rd->uv_levels, rd_uv.uv_levels, sizeof(rd->uv_levels));
+      SwapPtr(&dst, &tmp_dst);
+    }
+  }
+  VP8SetIntraUVMode(it, rd->mode_uv);
+  AddScore(rd, &rd_best);
+  if (dst != dst0) {   // copy 16x8 block if needed
+    VP8Copy16x8(dst, dst0);
+  }
+}
+
+//------------------------------------------------------------------------------
+// Final reconstruction and quantization.
+
+static void SimpleQuantize(VP8EncIterator* const it, VP8ModeScore* const rd) {
+  const VP8Encoder* const enc = it->enc_;
+  const int is_i16 = (it->mb_->type_ == 1);
+  int nz = 0;
+
+  if (is_i16) {
+    nz = ReconstructIntra16(it, rd, it->yuv_out_ + Y_OFF, it->preds_[0]);
+  } else {
+    VP8IteratorStartI4(it);
+    do {
+      const int mode =
+          it->preds_[(it->i4_ & 3) + (it->i4_ >> 2) * enc->preds_w_];
+      const uint8_t* const src = it->yuv_in_ + Y_OFF + VP8Scan[it->i4_];
+      uint8_t* const dst = it->yuv_out_ + Y_OFF + VP8Scan[it->i4_];
+      VP8MakeIntra4Preds(it);
+      nz |= ReconstructIntra4(it, rd->y_ac_levels[it->i4_],
+                              src, dst, mode) << it->i4_;
+    } while (VP8IteratorRotateI4(it, it->yuv_out_ + Y_OFF));
+  }
+
+  nz |= ReconstructUV(it, rd, it->yuv_out_ + U_OFF, it->mb_->uv_mode_);
+  rd->nz = nz;
+}
+
+// Refine intra16/intra4 sub-modes based on distortion only (not rate).
+static void DistoRefine(VP8EncIterator* const it, int try_both_i4_i16) {
+  const int is_i16 = (it->mb_->type_ == 1);
+  score_t best_score = MAX_COST;
+
+  if (try_both_i4_i16 || is_i16) {
+    int mode;
+    int best_mode = -1;
+    for (mode = 0; mode < NUM_PRED_MODES; ++mode) {
+      const uint8_t* const ref = it->yuv_p_ + VP8I16ModeOffsets[mode];
+      const uint8_t* const src = it->yuv_in_ + Y_OFF;
+      const score_t score = VP8SSE16x16(src, ref);
+      if (score < best_score) {
+        best_mode = mode;
+        best_score = score;
+      }
+    }
+    VP8SetIntra16Mode(it, best_mode);
+  }
+  if (try_both_i4_i16 || !is_i16) {
+    uint8_t modes_i4[16];
+    // We don't evaluate the rate here, but just account for it through a
+    // constant penalty (i4 mode usually needs more bits compared to i16).
+    score_t score_i4 = (score_t)I4_PENALTY;
+
+    VP8IteratorStartI4(it);
+    do {
+      int mode;
+      int best_sub_mode = -1;
+      score_t best_sub_score = MAX_COST;
+      const uint8_t* const src = it->yuv_in_ + Y_OFF + VP8Scan[it->i4_];
+
+      // TODO(skal): we don't really need the prediction pixels here,
+      // but just the distortion against 'src'.
+      VP8MakeIntra4Preds(it);
+      for (mode = 0; mode < NUM_BMODES; ++mode) {
+        const uint8_t* const ref = it->yuv_p_ + VP8I4ModeOffsets[mode];
+        const score_t score = VP8SSE4x4(src, ref);
+        if (score < best_sub_score) {
+          best_sub_mode = mode;
+          best_sub_score = score;
+        }
+      }
+      modes_i4[it->i4_] = best_sub_mode;
+      score_i4 += best_sub_score;
+      if (score_i4 >= best_score) break;
+    } while (VP8IteratorRotateI4(it, it->yuv_in_ + Y_OFF));
+    if (score_i4 < best_score) {
+      VP8SetIntra4Mode(it, modes_i4);
+    }
+  }
+}
+
+//------------------------------------------------------------------------------
+// Entry point
+
+int VP8Decimate(VP8EncIterator* const it, VP8ModeScore* const rd,
+                VP8RDLevel rd_opt) {
+  int is_skipped;
+  const int method = it->enc_->method_;
+
+  InitScore(rd);
+
+  // We can perform predictions for Luma16x16 and Chroma8x8 already.
+  // Luma4x4 predictions needs to be done as-we-go.
+  VP8MakeLuma16Preds(it);
+  VP8MakeChroma8Preds(it);
+
+  if (rd_opt > RD_OPT_NONE) {
+    it->do_trellis_ = (rd_opt >= RD_OPT_TRELLIS_ALL);
+    PickBestIntra16(it, rd);
+    if (method >= 2) {
+      PickBestIntra4(it, rd);
+    }
+    PickBestUV(it, rd);
+    if (rd_opt == RD_OPT_TRELLIS) {   // finish off with trellis-optim now
+      it->do_trellis_ = 1;
+      SimpleQuantize(it, rd);
+    }
+  } else {
+    // For method == 2, pick the best intra4/intra16 based on SSE (~tad slower).
+    // For method <= 1, we refine intra4 or intra16 (but don't re-examine mode).
+    DistoRefine(it, (method >= 2));
+    SimpleQuantize(it, rd);
+  }
+  is_skipped = (rd->nz == 0);
+  VP8SetSkip(it, is_skipped);
+  return is_skipped;
+}
+
diff --git a/Source/LibWebP/src/enc/enc.syntax.c b/Source/LibWebP/src/enc/enc.syntax.c
new file mode 100644
index 0000000..2dfebcc
--- /dev/null
+++ b/Source/LibWebP/src/enc/enc.syntax.c
@@ -0,0 +1,383 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Header syntax writing
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include <assert.h>
+
+#include "../utils/utils.h"
+#include "../webp/format_constants.h"  // RIFF constants
+#include "../webp/mux_types.h"         // ALPHA_FLAG
+#include "./vp8enci.h"
+
+//------------------------------------------------------------------------------
+// Helper functions
+
+static int IsVP8XNeeded(const VP8Encoder* const enc) {
+  return !!enc->has_alpha_;  // Currently the only case when VP8X is needed.
+                             // This could change in the future.
+}
+
+static int PutPaddingByte(const WebPPicture* const pic) {
+  const uint8_t pad_byte[1] = { 0 };
+  return !!pic->writer(pad_byte, 1, pic);
+}
+
+//------------------------------------------------------------------------------
+// Writers for header's various pieces (in order of appearance)
+
+static WebPEncodingError PutRIFFHeader(const VP8Encoder* const enc,
+                                       size_t riff_size) {
+  const WebPPicture* const pic = enc->pic_;
+  uint8_t riff[RIFF_HEADER_SIZE] = {
+    'R', 'I', 'F', 'F', 0, 0, 0, 0, 'W', 'E', 'B', 'P'
+  };
+  assert(riff_size == (uint32_t)riff_size);
+  PutLE32(riff + TAG_SIZE, (uint32_t)riff_size);
+  if (!pic->writer(riff, sizeof(riff), pic)) {
+    return VP8_ENC_ERROR_BAD_WRITE;
+  }
+  return VP8_ENC_OK;
+}
+
+static WebPEncodingError PutVP8XHeader(const VP8Encoder* const enc) {
+  const WebPPicture* const pic = enc->pic_;
+  uint8_t vp8x[CHUNK_HEADER_SIZE + VP8X_CHUNK_SIZE] = {
+    'V', 'P', '8', 'X'
+  };
+  uint32_t flags = 0;
+
+  assert(IsVP8XNeeded(enc));
+  assert(pic->width >= 1 && pic->height >= 1);
+  assert(pic->width <= MAX_CANVAS_SIZE && pic->height <= MAX_CANVAS_SIZE);
+
+  if (enc->has_alpha_) {
+    flags |= ALPHA_FLAG;
+  }
+
+  PutLE32(vp8x + TAG_SIZE,              VP8X_CHUNK_SIZE);
+  PutLE32(vp8x + CHUNK_HEADER_SIZE,     flags);
+  PutLE24(vp8x + CHUNK_HEADER_SIZE + 4, pic->width - 1);
+  PutLE24(vp8x + CHUNK_HEADER_SIZE + 7, pic->height - 1);
+  if (!pic->writer(vp8x, sizeof(vp8x), pic)) {
+    return VP8_ENC_ERROR_BAD_WRITE;
+  }
+  return VP8_ENC_OK;
+}
+
+static WebPEncodingError PutAlphaChunk(const VP8Encoder* const enc) {
+  const WebPPicture* const pic = enc->pic_;
+  uint8_t alpha_chunk_hdr[CHUNK_HEADER_SIZE] = {
+    'A', 'L', 'P', 'H'
+  };
+
+  assert(enc->has_alpha_);
+
+  // Alpha chunk header.
+  PutLE32(alpha_chunk_hdr + TAG_SIZE, enc->alpha_data_size_);
+  if (!pic->writer(alpha_chunk_hdr, sizeof(alpha_chunk_hdr), pic)) {
+    return VP8_ENC_ERROR_BAD_WRITE;
+  }
+
+  // Alpha chunk data.
+  if (!pic->writer(enc->alpha_data_, enc->alpha_data_size_, pic)) {
+    return VP8_ENC_ERROR_BAD_WRITE;
+  }
+
+  // Padding.
+  if ((enc->alpha_data_size_ & 1) && !PutPaddingByte(pic)) {
+    return VP8_ENC_ERROR_BAD_WRITE;
+  }
+  return VP8_ENC_OK;
+}
+
+static WebPEncodingError PutVP8Header(const WebPPicture* const pic,
+                                      size_t vp8_size) {
+  uint8_t vp8_chunk_hdr[CHUNK_HEADER_SIZE] = {
+    'V', 'P', '8', ' '
+  };
+  assert(vp8_size == (uint32_t)vp8_size);
+  PutLE32(vp8_chunk_hdr + TAG_SIZE, (uint32_t)vp8_size);
+  if (!pic->writer(vp8_chunk_hdr, sizeof(vp8_chunk_hdr), pic)) {
+    return VP8_ENC_ERROR_BAD_WRITE;
+  }
+  return VP8_ENC_OK;
+}
+
+static WebPEncodingError PutVP8FrameHeader(const WebPPicture* const pic,
+                                           int profile, size_t size0) {
+  uint8_t vp8_frm_hdr[VP8_FRAME_HEADER_SIZE];
+  uint32_t bits;
+
+  if (size0 >= VP8_MAX_PARTITION0_SIZE) {  // partition #0 is too big to fit
+    return VP8_ENC_ERROR_PARTITION0_OVERFLOW;
+  }
+
+  // Paragraph 9.1.
+  bits = 0                         // keyframe (1b)
+       | (profile << 1)            // profile (3b)
+       | (1 << 4)                  // visible (1b)
+       | ((uint32_t)size0 << 5);   // partition length (19b)
+  vp8_frm_hdr[0] = (bits >>  0) & 0xff;
+  vp8_frm_hdr[1] = (bits >>  8) & 0xff;
+  vp8_frm_hdr[2] = (bits >> 16) & 0xff;
+  // signature
+  vp8_frm_hdr[3] = (VP8_SIGNATURE >> 16) & 0xff;
+  vp8_frm_hdr[4] = (VP8_SIGNATURE >>  8) & 0xff;
+  vp8_frm_hdr[5] = (VP8_SIGNATURE >>  0) & 0xff;
+  // dimensions
+  vp8_frm_hdr[6] = pic->width & 0xff;
+  vp8_frm_hdr[7] = pic->width >> 8;
+  vp8_frm_hdr[8] = pic->height & 0xff;
+  vp8_frm_hdr[9] = pic->height >> 8;
+
+  if (!pic->writer(vp8_frm_hdr, sizeof(vp8_frm_hdr), pic)) {
+    return VP8_ENC_ERROR_BAD_WRITE;
+  }
+  return VP8_ENC_OK;
+}
+
+// WebP Headers.
+static int PutWebPHeaders(const VP8Encoder* const enc, size_t size0,
+                          size_t vp8_size, size_t riff_size) {
+  WebPPicture* const pic = enc->pic_;
+  WebPEncodingError err = VP8_ENC_OK;
+
+  // RIFF header.
+  err = PutRIFFHeader(enc, riff_size);
+  if (err != VP8_ENC_OK) goto Error;
+
+  // VP8X.
+  if (IsVP8XNeeded(enc)) {
+    err = PutVP8XHeader(enc);
+    if (err != VP8_ENC_OK) goto Error;
+  }
+
+  // Alpha.
+  if (enc->has_alpha_) {
+    err = PutAlphaChunk(enc);
+    if (err != VP8_ENC_OK) goto Error;
+  }
+
+  // VP8 header.
+  err = PutVP8Header(pic, vp8_size);
+  if (err != VP8_ENC_OK) goto Error;
+
+  // VP8 frame header.
+  err = PutVP8FrameHeader(pic, enc->profile_, size0);
+  if (err != VP8_ENC_OK) goto Error;
+
+  // All OK.
+  return 1;
+
+  // Error.
+ Error:
+  return WebPEncodingSetError(pic, err);
+}
+
+// Segmentation header
+static void PutSegmentHeader(VP8BitWriter* const bw,
+                             const VP8Encoder* const enc) {
+  const VP8SegmentHeader* const hdr = &enc->segment_hdr_;
+  const VP8Proba* const proba = &enc->proba_;
+  if (VP8PutBitUniform(bw, (hdr->num_segments_ > 1))) {
+    // We always 'update' the quant and filter strength values
+    const int update_data = 1;
+    int s;
+    VP8PutBitUniform(bw, hdr->update_map_);
+    if (VP8PutBitUniform(bw, update_data)) {
+      // we always use absolute values, not relative ones
+      VP8PutBitUniform(bw, 1);   // (segment_feature_mode = 1. Paragraph 9.3.)
+      for (s = 0; s < NUM_MB_SEGMENTS; ++s) {
+        VP8PutSignedBits(bw, enc->dqm_[s].quant_, 7);
+      }
+      for (s = 0; s < NUM_MB_SEGMENTS; ++s) {
+        VP8PutSignedBits(bw, enc->dqm_[s].fstrength_, 6);
+      }
+    }
+    if (hdr->update_map_) {
+      for (s = 0; s < 3; ++s) {
+        if (VP8PutBitUniform(bw, (proba->segments_[s] != 255u))) {
+          VP8PutBits(bw, proba->segments_[s], 8);
+        }
+      }
+    }
+  }
+}
+
+// Filtering parameters header
+static void PutFilterHeader(VP8BitWriter* const bw,
+                            const VP8FilterHeader* const hdr) {
+  const int use_lf_delta = (hdr->i4x4_lf_delta_ != 0);
+  VP8PutBitUniform(bw, hdr->simple_);
+  VP8PutBits(bw, hdr->level_, 6);
+  VP8PutBits(bw, hdr->sharpness_, 3);
+  if (VP8PutBitUniform(bw, use_lf_delta)) {
+    // '0' is the default value for i4x4_lf_delta_ at frame #0.
+    const int need_update = (hdr->i4x4_lf_delta_ != 0);
+    if (VP8PutBitUniform(bw, need_update)) {
+      // we don't use ref_lf_delta => emit four 0 bits
+      VP8PutBits(bw, 0, 4);
+      // we use mode_lf_delta for i4x4
+      VP8PutSignedBits(bw, hdr->i4x4_lf_delta_, 6);
+      VP8PutBits(bw, 0, 3);    // all others unused
+    }
+  }
+}
+
+// Nominal quantization parameters
+static void PutQuant(VP8BitWriter* const bw,
+                     const VP8Encoder* const enc) {
+  VP8PutBits(bw, enc->base_quant_, 7);
+  VP8PutSignedBits(bw, enc->dq_y1_dc_, 4);
+  VP8PutSignedBits(bw, enc->dq_y2_dc_, 4);
+  VP8PutSignedBits(bw, enc->dq_y2_ac_, 4);
+  VP8PutSignedBits(bw, enc->dq_uv_dc_, 4);
+  VP8PutSignedBits(bw, enc->dq_uv_ac_, 4);
+}
+
+// Partition sizes
+static int EmitPartitionsSize(const VP8Encoder* const enc,
+                              WebPPicture* const pic) {
+  uint8_t buf[3 * (MAX_NUM_PARTITIONS - 1)];
+  int p;
+  for (p = 0; p < enc->num_parts_ - 1; ++p) {
+    const size_t part_size = VP8BitWriterSize(enc->parts_ + p);
+    if (part_size >= VP8_MAX_PARTITION_SIZE) {
+      return WebPEncodingSetError(pic, VP8_ENC_ERROR_PARTITION_OVERFLOW);
+    }
+    buf[3 * p + 0] = (part_size >>  0) & 0xff;
+    buf[3 * p + 1] = (part_size >>  8) & 0xff;
+    buf[3 * p + 2] = (part_size >> 16) & 0xff;
+  }
+  return p ? pic->writer(buf, 3 * p, pic) : 1;
+}
+
+//------------------------------------------------------------------------------
+
+static int GeneratePartition0(VP8Encoder* const enc) {
+  VP8BitWriter* const bw = &enc->bw_;
+  const int mb_size = enc->mb_w_ * enc->mb_h_;
+  uint64_t pos1, pos2, pos3;
+
+  pos1 = VP8BitWriterPos(bw);
+  if (!VP8BitWriterInit(bw, mb_size * 7 / 8)) {        // ~7 bits per macroblock
+    return WebPEncodingSetError(enc->pic_, VP8_ENC_ERROR_OUT_OF_MEMORY);
+  }
+  VP8PutBitUniform(bw, 0);   // colorspace
+  VP8PutBitUniform(bw, 0);   // clamp type
+
+  PutSegmentHeader(bw, enc);
+  PutFilterHeader(bw, &enc->filter_hdr_);
+  VP8PutBits(bw, enc->num_parts_ == 8 ? 3 :
+                 enc->num_parts_ == 4 ? 2 :
+                 enc->num_parts_ == 2 ? 1 : 0, 2);
+  PutQuant(bw, enc);
+  VP8PutBitUniform(bw, 0);   // no proba update
+  VP8WriteProbas(bw, &enc->proba_);
+  pos2 = VP8BitWriterPos(bw);
+  VP8CodeIntraModes(enc);
+  VP8BitWriterFinish(bw);
+
+  pos3 = VP8BitWriterPos(bw);
+
+  if (enc->pic_->stats) {
+    enc->pic_->stats->header_bytes[0] = (int)((pos2 - pos1 + 7) >> 3);
+    enc->pic_->stats->header_bytes[1] = (int)((pos3 - pos2 + 7) >> 3);
+    enc->pic_->stats->alpha_data_size = (int)enc->alpha_data_size_;
+  }
+  if (bw->error_) {
+    return WebPEncodingSetError(enc->pic_, VP8_ENC_ERROR_OUT_OF_MEMORY);
+  }
+  return 1;
+}
+
+void VP8EncFreeBitWriters(VP8Encoder* const enc) {
+  int p;
+  VP8BitWriterWipeOut(&enc->bw_);
+  for (p = 0; p < enc->num_parts_; ++p) {
+    VP8BitWriterWipeOut(enc->parts_ + p);
+  }
+}
+
+int VP8EncWrite(VP8Encoder* const enc) {
+  WebPPicture* const pic = enc->pic_;
+  VP8BitWriter* const bw = &enc->bw_;
+  const int task_percent = 19;
+  const int percent_per_part = task_percent / enc->num_parts_;
+  const int final_percent = enc->percent_ + task_percent;
+  int ok = 0;
+  size_t vp8_size, pad, riff_size;
+  int p;
+
+  // Partition #0 with header and partition sizes
+  ok = GeneratePartition0(enc);
+  if (!ok) return 0;
+
+  // Compute VP8 size
+  vp8_size = VP8_FRAME_HEADER_SIZE +
+             VP8BitWriterSize(bw) +
+             3 * (enc->num_parts_ - 1);
+  for (p = 0; p < enc->num_parts_; ++p) {
+    vp8_size += VP8BitWriterSize(enc->parts_ + p);
+  }
+  pad = vp8_size & 1;
+  vp8_size += pad;
+
+  // Compute RIFF size
+  // At the minimum it is: "WEBPVP8 nnnn" + VP8 data size.
+  riff_size = TAG_SIZE + CHUNK_HEADER_SIZE + vp8_size;
+  if (IsVP8XNeeded(enc)) {  // Add size for: VP8X header + data.
+    riff_size += CHUNK_HEADER_SIZE + VP8X_CHUNK_SIZE;
+  }
+  if (enc->has_alpha_) {  // Add size for: ALPH header + data.
+    const uint32_t padded_alpha_size = enc->alpha_data_size_ +
+                                       (enc->alpha_data_size_ & 1);
+    riff_size += CHUNK_HEADER_SIZE + padded_alpha_size;
+  }
+  // Sanity check.
+  if (riff_size > 0xfffffffeU) {
+    return WebPEncodingSetError(pic, VP8_ENC_ERROR_FILE_TOO_BIG);
+  }
+
+  // Emit headers and partition #0
+  {
+    const uint8_t* const part0 = VP8BitWriterBuf(bw);
+    const size_t size0 = VP8BitWriterSize(bw);
+    ok = ok && PutWebPHeaders(enc, size0, vp8_size, riff_size)
+            && pic->writer(part0, size0, pic)
+            && EmitPartitionsSize(enc, pic);
+    VP8BitWriterWipeOut(bw);    // will free the internal buffer.
+  }
+
+  // Token partitions
+  for (p = 0; p < enc->num_parts_; ++p) {
+    const uint8_t* const buf = VP8BitWriterBuf(enc->parts_ + p);
+    const size_t size = VP8BitWriterSize(enc->parts_ + p);
+    if (size)
+      ok = ok && pic->writer(buf, size, pic);
+    VP8BitWriterWipeOut(enc->parts_ + p);    // will free the internal buffer.
+    ok = ok && WebPReportProgress(pic, enc->percent_ + percent_per_part,
+                                  &enc->percent_);
+  }
+
+  // Padding byte
+  if (ok && pad) {
+    ok = PutPaddingByte(pic);
+  }
+
+  enc->coded_size_ = (int)(CHUNK_HEADER_SIZE + riff_size);
+  ok = ok && WebPReportProgress(pic, final_percent, &enc->percent_);
+  return ok;
+}
+
+//------------------------------------------------------------------------------
+
diff --git a/Source/LibWebP/src/enc/enc.token.c b/Source/LibWebP/src/enc/enc.token.c
new file mode 100644
index 0000000..637162c
--- /dev/null
+++ b/Source/LibWebP/src/enc/enc.token.c
@@ -0,0 +1,285 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Paginated token buffer
+//
+//  A 'token' is a bit value associated with a probability, either fixed
+// or a later-to-be-determined after statistics have been collected.
+// For dynamic probability, we just record the slot id (idx) for the probability
+// value in the final probability array (uint8_t* probas in VP8EmitTokens).
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "./cost.h"
+#include "./vp8enci.h"
+#include "../utils/utils.h"
+
+#if !defined(DISABLE_TOKEN_BUFFER)
+
+// we use pages to reduce the number of memcpy()
+#define MIN_PAGE_SIZE 8192          // minimum number of token per page
+#define FIXED_PROBA_BIT (1u << 14)
+
+typedef uint16_t token_t;  // bit #15: bit value
+                           // bit #14: flags for constant proba or idx
+                           // bits #0..13: slot or constant proba
+struct VP8Tokens {
+  VP8Tokens* next_;        // pointer to next page
+};
+// Token data is located in memory just after the next_ field.
+// This macro is used to return their address and hide the trick.
+#define TOKEN_DATA(p) ((const token_t*)&(p)[1])
+
+//------------------------------------------------------------------------------
+
+void VP8TBufferInit(VP8TBuffer* const b, int page_size) {
+  b->tokens_ = NULL;
+  b->pages_ = NULL;
+  b->last_page_ = &b->pages_;
+  b->left_ = 0;
+  b->page_size_ = (page_size < MIN_PAGE_SIZE) ? MIN_PAGE_SIZE : page_size;
+  b->error_ = 0;
+}
+
+void VP8TBufferClear(VP8TBuffer* const b) {
+  if (b != NULL) {
+    VP8Tokens* p = b->pages_;
+    while (p != NULL) {
+      VP8Tokens* const next = p->next_;
+      WebPSafeFree(p);
+      p = next;
+    }
+    VP8TBufferInit(b, b->page_size_);
+  }
+}
+
+static int TBufferNewPage(VP8TBuffer* const b) {
+  VP8Tokens* page = NULL;
+  if (!b->error_) {
+    const size_t size = sizeof(*page) + b->page_size_ * sizeof(token_t);
+    page = (VP8Tokens*)WebPSafeMalloc(1ULL, size);
+  }
+  if (page == NULL) {
+    b->error_ = 1;
+    return 0;
+  }
+  page->next_ = NULL;
+
+  *b->last_page_ = page;
+  b->last_page_ = &page->next_;
+  b->left_ = b->page_size_;
+  b->tokens_ = (token_t*)TOKEN_DATA(page);
+  return 1;
+}
+
+//------------------------------------------------------------------------------
+
+#define TOKEN_ID(t, b, ctx) \
+    (NUM_PROBAS * ((ctx) + NUM_CTX * ((b) + NUM_BANDS * (t))))
+
+static WEBP_INLINE uint32_t AddToken(VP8TBuffer* const b,
+                                     uint32_t bit, uint32_t proba_idx) {
+  assert(proba_idx < FIXED_PROBA_BIT);
+  assert(bit <= 1);
+  if (b->left_ > 0 || TBufferNewPage(b)) {
+    const int slot = --b->left_;
+    b->tokens_[slot] = (bit << 15) | proba_idx;
+  }
+  return bit;
+}
+
+static WEBP_INLINE void AddConstantToken(VP8TBuffer* const b,
+                                         uint32_t bit, uint32_t proba) {
+  assert(proba < 256);
+  assert(bit <= 1);
+  if (b->left_ > 0 || TBufferNewPage(b)) {
+    const int slot = --b->left_;
+    b->tokens_[slot] = (bit << 15) | FIXED_PROBA_BIT | proba;
+  }
+}
+
+int VP8RecordCoeffTokens(const int ctx, const int coeff_type,
+                         int first, int last,
+                         const int16_t* const coeffs,
+                         VP8TBuffer* const tokens) {
+  int n = first;
+  uint32_t base_id = TOKEN_ID(coeff_type, n, ctx);
+  if (!AddToken(tokens, last >= 0, base_id + 0)) {
+    return 0;
+  }
+
+  while (n < 16) {
+    const int c = coeffs[n++];
+    const int sign = c < 0;
+    const uint32_t v = sign ? -c : c;
+    if (!AddToken(tokens, v != 0, base_id + 1)) {
+      base_id = TOKEN_ID(coeff_type, VP8EncBands[n], 0);  // ctx=0
+      continue;
+    }
+    if (!AddToken(tokens, v > 1, base_id + 2)) {
+      base_id = TOKEN_ID(coeff_type, VP8EncBands[n], 1);  // ctx=1
+    } else {
+      if (!AddToken(tokens, v > 4, base_id + 3)) {
+        if (AddToken(tokens, v != 2, base_id + 4))
+          AddToken(tokens, v == 4, base_id + 5);
+      } else if (!AddToken(tokens, v > 10, base_id + 6)) {
+        if (!AddToken(tokens, v > 6, base_id + 7)) {
+          AddConstantToken(tokens, v == 6, 159);
+        } else {
+          AddConstantToken(tokens, v >= 9, 165);
+          AddConstantToken(tokens, !(v & 1), 145);
+        }
+      } else {
+        int mask;
+        const uint8_t* tab;
+        uint32_t residue = v - 3;
+        if (residue < (8 << 1)) {          // VP8Cat3  (3b)
+          AddToken(tokens, 0, base_id + 8);
+          AddToken(tokens, 0, base_id + 9);
+          residue -= (8 << 0);
+          mask = 1 << 2;
+          tab = VP8Cat3;
+        } else if (residue < (8 << 2)) {   // VP8Cat4  (4b)
+          AddToken(tokens, 0, base_id + 8);
+          AddToken(tokens, 1, base_id + 9);
+          residue -= (8 << 1);
+          mask = 1 << 3;
+          tab = VP8Cat4;
+        } else if (residue < (8 << 3)) {   // VP8Cat5  (5b)
+          AddToken(tokens, 1, base_id + 8);
+          AddToken(tokens, 0, base_id + 10);
+          residue -= (8 << 2);
+          mask = 1 << 4;
+          tab = VP8Cat5;
+        } else {                         // VP8Cat6 (11b)
+          AddToken(tokens, 1, base_id + 8);
+          AddToken(tokens, 1, base_id + 10);
+          residue -= (8 << 3);
+          mask = 1 << 10;
+          tab = VP8Cat6;
+        }
+        while (mask) {
+          AddConstantToken(tokens, !!(residue & mask), *tab++);
+          mask >>= 1;
+        }
+      }
+      base_id = TOKEN_ID(coeff_type, VP8EncBands[n], 2);  // ctx=2
+    }
+    AddConstantToken(tokens, sign, 128);
+    if (n == 16 || !AddToken(tokens, n <= last, base_id + 0)) {
+      return 1;   // EOB
+    }
+  }
+  return 1;
+}
+
+#undef TOKEN_ID
+
+//------------------------------------------------------------------------------
+// This function works, but isn't currently used. Saved for later.
+
+#if 0
+
+static void Record(int bit, proba_t* const stats) {
+  proba_t p = *stats;
+  if (p >= 0xffff0000u) {               // an overflow is inbound.
+    p = ((p + 1u) >> 1) & 0x7fff7fffu;  // -> divide the stats by 2.
+  }
+  // record bit count (lower 16 bits) and increment total count (upper 16 bits).
+  p += 0x00010000u + bit;
+  *stats = p;
+}
+
+void VP8TokenToStats(const VP8TBuffer* const b, proba_t* const stats) {
+  const VP8Tokens* p = b->pages_;
+  while (p != NULL) {
+    const int N = (p->next_ == NULL) ? b->left_ : 0;
+    int n = MAX_NUM_TOKEN;
+    const token_t* const tokens = TOKEN_DATA(p);
+    while (n-- > N) {
+      const token_t token = tokens[n];
+      if (!(token & FIXED_PROBA_BIT)) {
+        Record((token >> 15) & 1, stats + (token & 0x3fffu));
+      }
+    }
+    p = p->next_;
+  }
+}
+
+#endif   // 0
+
+//------------------------------------------------------------------------------
+// Final coding pass, with known probabilities
+
+int VP8EmitTokens(VP8TBuffer* const b, VP8BitWriter* const bw,
+                  const uint8_t* const probas, int final_pass) {
+  const VP8Tokens* p = b->pages_;
+  assert(!b->error_);
+  while (p != NULL) {
+    const VP8Tokens* const next = p->next_;
+    const int N = (next == NULL) ? b->left_ : 0;
+    int n = b->page_size_;
+    const token_t* const tokens = TOKEN_DATA(p);
+    while (n-- > N) {
+      const token_t token = tokens[n];
+      const int bit = (token >> 15) & 1;
+      if (token & FIXED_PROBA_BIT) {
+        VP8PutBit(bw, bit, token & 0xffu);  // constant proba
+      } else {
+        VP8PutBit(bw, bit, probas[token & 0x3fffu]);
+      }
+    }
+    if (final_pass) WebPSafeFree((void*)p);
+    p = next;
+  }
+  if (final_pass) b->pages_ = NULL;
+  return 1;
+}
+
+// Size estimation
+size_t VP8EstimateTokenSize(VP8TBuffer* const b, const uint8_t* const probas) {
+  size_t size = 0;
+  const VP8Tokens* p = b->pages_;
+  assert(!b->error_);
+  while (p != NULL) {
+    const VP8Tokens* const next = p->next_;
+    const int N = (next == NULL) ? b->left_ : 0;
+    int n = b->page_size_;
+    const token_t* const tokens = TOKEN_DATA(p);
+    while (n-- > N) {
+      const token_t token = tokens[n];
+      const int bit = token & (1 << 15);
+      if (token & FIXED_PROBA_BIT) {
+        size += VP8BitCost(bit, token & 0xffu);
+      } else {
+        size += VP8BitCost(bit, probas[token & 0x3fffu]);
+      }
+    }
+    p = next;
+  }
+  return size;
+}
+
+//------------------------------------------------------------------------------
+
+#else     // DISABLE_TOKEN_BUFFER
+
+void VP8TBufferInit(VP8TBuffer* const b) {
+  (void)b;
+}
+void VP8TBufferClear(VP8TBuffer* const b) {
+  (void)b;
+}
+
+#endif    // !DISABLE_TOKEN_BUFFER
+
diff --git a/Source/LibWebP/src/enc/enc.tree.c b/Source/LibWebP/src/enc/enc.tree.c
new file mode 100644
index 0000000..f8a06a9
--- /dev/null
+++ b/Source/LibWebP/src/enc/enc.tree.c
@@ -0,0 +1,504 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Coding of token probabilities, intra modes and segments.
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include "./vp8enci.h"
+
+//------------------------------------------------------------------------------
+// Default probabilities
+
+// Paragraph 13.5
+const uint8_t
+  VP8CoeffsProba0[NUM_TYPES][NUM_BANDS][NUM_CTX][NUM_PROBAS] = {
+  { { { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
+      { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
+      { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 }
+    },
+    { { 253, 136, 254, 255, 228, 219, 128, 128, 128, 128, 128 },
+      { 189, 129, 242, 255, 227, 213, 255, 219, 128, 128, 128 },
+      { 106, 126, 227, 252, 214, 209, 255, 255, 128, 128, 128 }
+    },
+    { { 1, 98, 248, 255, 236, 226, 255, 255, 128, 128, 128 },
+      { 181, 133, 238, 254, 221, 234, 255, 154, 128, 128, 128 },
+      { 78, 134, 202, 247, 198, 180, 255, 219, 128, 128, 128 },
+    },
+    { { 1, 185, 249, 255, 243, 255, 128, 128, 128, 128, 128 },
+      { 184, 150, 247, 255, 236, 224, 128, 128, 128, 128, 128 },
+      { 77, 110, 216, 255, 236, 230, 128, 128, 128, 128, 128 },
+    },
+    { { 1, 101, 251, 255, 241, 255, 128, 128, 128, 128, 128 },
+      { 170, 139, 241, 252, 236, 209, 255, 255, 128, 128, 128 },
+      { 37, 116, 196, 243, 228, 255, 255, 255, 128, 128, 128 }
+    },
+    { { 1, 204, 254, 255, 245, 255, 128, 128, 128, 128, 128 },
+      { 207, 160, 250, 255, 238, 128, 128, 128, 128, 128, 128 },
+      { 102, 103, 231, 255, 211, 171, 128, 128, 128, 128, 128 }
+    },
+    { { 1, 152, 252, 255, 240, 255, 128, 128, 128, 128, 128 },
+      { 177, 135, 243, 255, 234, 225, 128, 128, 128, 128, 128 },
+      { 80, 129, 211, 255, 194, 224, 128, 128, 128, 128, 128 }
+    },
+    { { 1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
+      { 246, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
+      { 255, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 }
+    }
+  },
+  { { { 198, 35, 237, 223, 193, 187, 162, 160, 145, 155, 62 },
+      { 131, 45, 198, 221, 172, 176, 220, 157, 252, 221, 1 },
+      { 68, 47, 146, 208, 149, 167, 221, 162, 255, 223, 128 }
+    },
+    { { 1, 149, 241, 255, 221, 224, 255, 255, 128, 128, 128 },
+      { 184, 141, 234, 253, 222, 220, 255, 199, 128, 128, 128 },
+      { 81, 99, 181, 242, 176, 190, 249, 202, 255, 255, 128 }
+    },
+    { { 1, 129, 232, 253, 214, 197, 242, 196, 255, 255, 128 },
+      { 99, 121, 210, 250, 201, 198, 255, 202, 128, 128, 128 },
+      { 23, 91, 163, 242, 170, 187, 247, 210, 255, 255, 128 }
+    },
+    { { 1, 200, 246, 255, 234, 255, 128, 128, 128, 128, 128 },
+      { 109, 178, 241, 255, 231, 245, 255, 255, 128, 128, 128 },
+      { 44, 130, 201, 253, 205, 192, 255, 255, 128, 128, 128 }
+    },
+    { { 1, 132, 239, 251, 219, 209, 255, 165, 128, 128, 128 },
+      { 94, 136, 225, 251, 218, 190, 255, 255, 128, 128, 128 },
+      { 22, 100, 174, 245, 186, 161, 255, 199, 128, 128, 128 }
+    },
+    { { 1, 182, 249, 255, 232, 235, 128, 128, 128, 128, 128 },
+      { 124, 143, 241, 255, 227, 234, 128, 128, 128, 128, 128 },
+      { 35, 77, 181, 251, 193, 211, 255, 205, 128, 128, 128 }
+    },
+    { { 1, 157, 247, 255, 236, 231, 255, 255, 128, 128, 128 },
+      { 121, 141, 235, 255, 225, 227, 255, 255, 128, 128, 128 },
+      { 45, 99, 188, 251, 195, 217, 255, 224, 128, 128, 128 }
+    },
+    { { 1, 1, 251, 255, 213, 255, 128, 128, 128, 128, 128 },
+      { 203, 1, 248, 255, 255, 128, 128, 128, 128, 128, 128 },
+      { 137, 1, 177, 255, 224, 255, 128, 128, 128, 128, 128 }
+    }
+  },
+  { { { 253, 9, 248, 251, 207, 208, 255, 192, 128, 128, 128 },
+      { 175, 13, 224, 243, 193, 185, 249, 198, 255, 255, 128 },
+      { 73, 17, 171, 221, 161, 179, 236, 167, 255, 234, 128 }
+    },
+    { { 1, 95, 247, 253, 212, 183, 255, 255, 128, 128, 128 },
+      { 239, 90, 244, 250, 211, 209, 255, 255, 128, 128, 128 },
+      { 155, 77, 195, 248, 188, 195, 255, 255, 128, 128, 128 }
+    },
+    { { 1, 24, 239, 251, 218, 219, 255, 205, 128, 128, 128 },
+      { 201, 51, 219, 255, 196, 186, 128, 128, 128, 128, 128 },
+      { 69, 46, 190, 239, 201, 218, 255, 228, 128, 128, 128 }
+    },
+    { { 1, 191, 251, 255, 255, 128, 128, 128, 128, 128, 128 },
+      { 223, 165, 249, 255, 213, 255, 128, 128, 128, 128, 128 },
+      { 141, 124, 248, 255, 255, 128, 128, 128, 128, 128, 128 }
+    },
+    { { 1, 16, 248, 255, 255, 128, 128, 128, 128, 128, 128 },
+      { 190, 36, 230, 255, 236, 255, 128, 128, 128, 128, 128 },
+      { 149, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 }
+    },
+    { { 1, 226, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
+      { 247, 192, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
+      { 240, 128, 255, 128, 128, 128, 128, 128, 128, 128, 128 }
+    },
+    { { 1, 134, 252, 255, 255, 128, 128, 128, 128, 128, 128 },
+      { 213, 62, 250, 255, 255, 128, 128, 128, 128, 128, 128 },
+      { 55, 93, 255, 128, 128, 128, 128, 128, 128, 128, 128 }
+    },
+    { { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
+      { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
+      { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 }
+    }
+  },
+  { { { 202, 24, 213, 235, 186, 191, 220, 160, 240, 175, 255 },
+      { 126, 38, 182, 232, 169, 184, 228, 174, 255, 187, 128 },
+      { 61, 46, 138, 219, 151, 178, 240, 170, 255, 216, 128 }
+    },
+    { { 1, 112, 230, 250, 199, 191, 247, 159, 255, 255, 128 },
+      { 166, 109, 228, 252, 211, 215, 255, 174, 128, 128, 128 },
+      { 39, 77, 162, 232, 172, 180, 245, 178, 255, 255, 128 }
+    },
+    { { 1, 52, 220, 246, 198, 199, 249, 220, 255, 255, 128 },
+      { 124, 74, 191, 243, 183, 193, 250, 221, 255, 255, 128 },
+      { 24, 71, 130, 219, 154, 170, 243, 182, 255, 255, 128 }
+    },
+    { { 1, 182, 225, 249, 219, 240, 255, 224, 128, 128, 128 },
+      { 149, 150, 226, 252, 216, 205, 255, 171, 128, 128, 128 },
+      { 28, 108, 170, 242, 183, 194, 254, 223, 255, 255, 128 }
+    },
+    { { 1, 81, 230, 252, 204, 203, 255, 192, 128, 128, 128 },
+      { 123, 102, 209, 247, 188, 196, 255, 233, 128, 128, 128 },
+      { 20, 95, 153, 243, 164, 173, 255, 203, 128, 128, 128 }
+    },
+    { { 1, 222, 248, 255, 216, 213, 128, 128, 128, 128, 128 },
+      { 168, 175, 246, 252, 235, 205, 255, 255, 128, 128, 128 },
+      { 47, 116, 215, 255, 211, 212, 255, 255, 128, 128, 128 }
+    },
+    { { 1, 121, 236, 253, 212, 214, 255, 255, 128, 128, 128 },
+      { 141, 84, 213, 252, 201, 202, 255, 219, 128, 128, 128 },
+      { 42, 80, 160, 240, 162, 185, 255, 205, 128, 128, 128 }
+    },
+    { { 1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
+      { 244, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
+      { 238, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 }
+    }
+  }
+};
+
+void VP8DefaultProbas(VP8Encoder* const enc) {
+  VP8Proba* const probas = &enc->proba_;
+  probas->use_skip_proba_ = 0;
+  memset(probas->segments_, 255u, sizeof(probas->segments_));
+  memcpy(probas->coeffs_, VP8CoeffsProba0, sizeof(VP8CoeffsProba0));
+  // Note: we could hard-code the level_costs_ corresponding to VP8CoeffsProba0,
+  // but that's ~11k of static data. Better call VP8CalculateLevelCosts() later.
+  probas->dirty_ = 1;
+}
+
+// Paragraph 11.5.  900bytes.
+static const uint8_t kBModesProba[NUM_BMODES][NUM_BMODES][NUM_BMODES - 1] = {
+  { { 231, 120, 48, 89, 115, 113, 120, 152, 112 },
+    { 152, 179, 64, 126, 170, 118, 46, 70, 95 },
+    { 175, 69, 143, 80, 85, 82, 72, 155, 103 },
+    { 56, 58, 10, 171, 218, 189, 17, 13, 152 },
+    { 114, 26, 17, 163, 44, 195, 21, 10, 173 },
+    { 121, 24, 80, 195, 26, 62, 44, 64, 85 },
+    { 144, 71, 10, 38, 171, 213, 144, 34, 26 },
+    { 170, 46, 55, 19, 136, 160, 33, 206, 71 },
+    { 63, 20, 8, 114, 114, 208, 12, 9, 226 },
+    { 81, 40, 11, 96, 182, 84, 29, 16, 36 } },
+  { { 134, 183, 89, 137, 98, 101, 106, 165, 148 },
+    { 72, 187, 100, 130, 157, 111, 32, 75, 80 },
+    { 66, 102, 167, 99, 74, 62, 40, 234, 128 },
+    { 41, 53, 9, 178, 241, 141, 26, 8, 107 },
+    { 74, 43, 26, 146, 73, 166, 49, 23, 157 },
+    { 65, 38, 105, 160, 51, 52, 31, 115, 128 },
+    { 104, 79, 12, 27, 217, 255, 87, 17, 7 },
+    { 87, 68, 71, 44, 114, 51, 15, 186, 23 },
+    { 47, 41, 14, 110, 182, 183, 21, 17, 194 },
+    { 66, 45, 25, 102, 197, 189, 23, 18, 22 } },
+  { { 88, 88, 147, 150, 42, 46, 45, 196, 205 },
+    { 43, 97, 183, 117, 85, 38, 35, 179, 61 },
+    { 39, 53, 200, 87, 26, 21, 43, 232, 171 },
+    { 56, 34, 51, 104, 114, 102, 29, 93, 77 },
+    { 39, 28, 85, 171, 58, 165, 90, 98, 64 },
+    { 34, 22, 116, 206, 23, 34, 43, 166, 73 },
+    { 107, 54, 32, 26, 51, 1, 81, 43, 31 },
+    { 68, 25, 106, 22, 64, 171, 36, 225, 114 },
+    { 34, 19, 21, 102, 132, 188, 16, 76, 124 },
+    { 62, 18, 78, 95, 85, 57, 50, 48, 51 } },
+  { { 193, 101, 35, 159, 215, 111, 89, 46, 111 },
+    { 60, 148, 31, 172, 219, 228, 21, 18, 111 },
+    { 112, 113, 77, 85, 179, 255, 38, 120, 114 },
+    { 40, 42, 1, 196, 245, 209, 10, 25, 109 },
+    { 88, 43, 29, 140, 166, 213, 37, 43, 154 },
+    { 61, 63, 30, 155, 67, 45, 68, 1, 209 },
+    { 100, 80, 8, 43, 154, 1, 51, 26, 71 },
+    { 142, 78, 78, 16, 255, 128, 34, 197, 171 },
+    { 41, 40, 5, 102, 211, 183, 4, 1, 221 },
+    { 51, 50, 17, 168, 209, 192, 23, 25, 82 } },
+  { { 138, 31, 36, 171, 27, 166, 38, 44, 229 },
+    { 67, 87, 58, 169, 82, 115, 26, 59, 179 },
+    { 63, 59, 90, 180, 59, 166, 93, 73, 154 },
+    { 40, 40, 21, 116, 143, 209, 34, 39, 175 },
+    { 47, 15, 16, 183, 34, 223, 49, 45, 183 },
+    { 46, 17, 33, 183, 6, 98, 15, 32, 183 },
+    { 57, 46, 22, 24, 128, 1, 54, 17, 37 },
+    { 65, 32, 73, 115, 28, 128, 23, 128, 205 },
+    { 40, 3, 9, 115, 51, 192, 18, 6, 223 },
+    { 87, 37, 9, 115, 59, 77, 64, 21, 47 } },
+  { { 104, 55, 44, 218, 9, 54, 53, 130, 226 },
+    { 64, 90, 70, 205, 40, 41, 23, 26, 57 },
+    { 54, 57, 112, 184, 5, 41, 38, 166, 213 },
+    { 30, 34, 26, 133, 152, 116, 10, 32, 134 },
+    { 39, 19, 53, 221, 26, 114, 32, 73, 255 },
+    { 31, 9, 65, 234, 2, 15, 1, 118, 73 },
+    { 75, 32, 12, 51, 192, 255, 160, 43, 51 },
+    { 88, 31, 35, 67, 102, 85, 55, 186, 85 },
+    { 56, 21, 23, 111, 59, 205, 45, 37, 192 },
+    { 55, 38, 70, 124, 73, 102, 1, 34, 98 } },
+  { { 125, 98, 42, 88, 104, 85, 117, 175, 82 },
+    { 95, 84, 53, 89, 128, 100, 113, 101, 45 },
+    { 75, 79, 123, 47, 51, 128, 81, 171, 1 },
+    { 57, 17, 5, 71, 102, 57, 53, 41, 49 },
+    { 38, 33, 13, 121, 57, 73, 26, 1, 85 },
+    { 41, 10, 67, 138, 77, 110, 90, 47, 114 },
+    { 115, 21, 2, 10, 102, 255, 166, 23, 6 },
+    { 101, 29, 16, 10, 85, 128, 101, 196, 26 },
+    { 57, 18, 10, 102, 102, 213, 34, 20, 43 },
+    { 117, 20, 15, 36, 163, 128, 68, 1, 26 } },
+  { { 102, 61, 71, 37, 34, 53, 31, 243, 192 },
+    { 69, 60, 71, 38, 73, 119, 28, 222, 37 },
+    { 68, 45, 128, 34, 1, 47, 11, 245, 171 },
+    { 62, 17, 19, 70, 146, 85, 55, 62, 70 },
+    { 37, 43, 37, 154, 100, 163, 85, 160, 1 },
+    { 63, 9, 92, 136, 28, 64, 32, 201, 85 },
+    { 75, 15, 9, 9, 64, 255, 184, 119, 16 },
+    { 86, 6, 28, 5, 64, 255, 25, 248, 1 },
+    { 56, 8, 17, 132, 137, 255, 55, 116, 128 },
+    { 58, 15, 20, 82, 135, 57, 26, 121, 40 } },
+  { { 164, 50, 31, 137, 154, 133, 25, 35, 218 },
+    { 51, 103, 44, 131, 131, 123, 31, 6, 158 },
+    { 86, 40, 64, 135, 148, 224, 45, 183, 128 },
+    { 22, 26, 17, 131, 240, 154, 14, 1, 209 },
+    { 45, 16, 21, 91, 64, 222, 7, 1, 197 },
+    { 56, 21, 39, 155, 60, 138, 23, 102, 213 },
+    { 83, 12, 13, 54, 192, 255, 68, 47, 28 },
+    { 85, 26, 85, 85, 128, 128, 32, 146, 171 },
+    { 18, 11, 7, 63, 144, 171, 4, 4, 246 },
+    { 35, 27, 10, 146, 174, 171, 12, 26, 128 } },
+  { { 190, 80, 35, 99, 180, 80, 126, 54, 45 },
+    { 85, 126, 47, 87, 176, 51, 41, 20, 32 },
+    { 101, 75, 128, 139, 118, 146, 116, 128, 85 },
+    { 56, 41, 15, 176, 236, 85, 37, 9, 62 },
+    { 71, 30, 17, 119, 118, 255, 17, 18, 138 },
+    { 101, 38, 60, 138, 55, 70, 43, 26, 142 },
+    { 146, 36, 19, 30, 171, 255, 97, 27, 20 },
+    { 138, 45, 61, 62, 219, 1, 81, 188, 64 },
+    { 32, 41, 20, 117, 151, 142, 20, 21, 163 },
+    { 112, 19, 12, 61, 195, 128, 48, 4, 24 } }
+};
+
+static int PutI4Mode(VP8BitWriter* const bw, int mode,
+                     const uint8_t* const prob) {
+  if (VP8PutBit(bw, mode != B_DC_PRED, prob[0])) {
+    if (VP8PutBit(bw, mode != B_TM_PRED, prob[1])) {
+      if (VP8PutBit(bw, mode != B_VE_PRED, prob[2])) {
+        if (!VP8PutBit(bw, mode >= B_LD_PRED, prob[3])) {
+          if (VP8PutBit(bw, mode != B_HE_PRED, prob[4])) {
+            VP8PutBit(bw, mode != B_RD_PRED, prob[5]);
+          }
+        } else {
+          if (VP8PutBit(bw, mode != B_LD_PRED, prob[6])) {
+            if (VP8PutBit(bw, mode != B_VL_PRED, prob[7])) {
+              VP8PutBit(bw, mode != B_HD_PRED, prob[8]);
+            }
+          }
+        }
+      }
+    }
+  }
+  return mode;
+}
+
+static void PutI16Mode(VP8BitWriter* const bw, int mode) {
+  if (VP8PutBit(bw, (mode == TM_PRED || mode == H_PRED), 156)) {
+    VP8PutBit(bw, mode == TM_PRED, 128);    // TM or HE
+  } else {
+    VP8PutBit(bw, mode == V_PRED, 163);     // VE or DC
+  }
+}
+
+static void PutUVMode(VP8BitWriter* const bw, int uv_mode) {
+  if (VP8PutBit(bw, uv_mode != DC_PRED, 142)) {
+    if (VP8PutBit(bw, uv_mode != V_PRED, 114)) {
+      VP8PutBit(bw, uv_mode != H_PRED, 183);    // else: TM_PRED
+    }
+  }
+}
+
+static void PutSegment(VP8BitWriter* const bw, int s, const uint8_t* p) {
+  if (VP8PutBit(bw, s >= 2, p[0])) p += 1;
+  VP8PutBit(bw, s & 1, p[1]);
+}
+
+void VP8CodeIntraModes(VP8Encoder* const enc) {
+  VP8BitWriter* const bw = &enc->bw_;
+  VP8EncIterator it;
+  VP8IteratorInit(enc, &it);
+  do {
+    const VP8MBInfo* const mb = it.mb_;
+    const uint8_t* preds = it.preds_;
+    if (enc->segment_hdr_.update_map_) {
+      PutSegment(bw, mb->segment_, enc->proba_.segments_);
+    }
+    if (enc->proba_.use_skip_proba_) {
+      VP8PutBit(bw, mb->skip_, enc->proba_.skip_proba_);
+    }
+    if (VP8PutBit(bw, (mb->type_ != 0), 145)) {  // i16x16
+      PutI16Mode(bw, preds[0]);
+    } else {
+      const int preds_w = enc->preds_w_;
+      const uint8_t* top_pred = preds - preds_w;
+      int x, y;
+      for (y = 0; y < 4; ++y) {
+        int left = preds[-1];
+        for (x = 0; x < 4; ++x) {
+          const uint8_t* const probas = kBModesProba[top_pred[x]][left];
+          left = PutI4Mode(bw, preds[x], probas);
+        }
+        top_pred = preds;
+        preds += preds_w;
+      }
+    }
+    PutUVMode(bw, mb->uv_mode_);
+  } while (VP8IteratorNext(&it));
+}
+
+//------------------------------------------------------------------------------
+// Paragraph 13
+
+const uint8_t
+    VP8CoeffsUpdateProba[NUM_TYPES][NUM_BANDS][NUM_CTX][NUM_PROBAS] = {
+  { { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 176, 246, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 223, 241, 252, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 249, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 244, 252, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 234, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 246, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 239, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 251, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 251, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 254, 253, 255, 254, 255, 255, 255, 255, 255, 255 },
+      { 250, 255, 254, 255, 254, 255, 255, 255, 255, 255, 255 },
+      { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    }
+  },
+  { { { 217, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 225, 252, 241, 253, 255, 255, 254, 255, 255, 255, 255 },
+      { 234, 250, 241, 250, 253, 255, 253, 254, 255, 255, 255 }
+    },
+    { { 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 223, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 238, 253, 254, 254, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 249, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 247, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    }
+  },
+  { { { 186, 251, 250, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 234, 251, 244, 254, 255, 255, 255, 255, 255, 255, 255 },
+      { 251, 251, 243, 253, 254, 255, 254, 255, 255, 255, 255 }
+    },
+    { { 255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 236, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 251, 253, 253, 254, 254, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    }
+  },
+  { { { 248, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 250, 254, 252, 254, 255, 255, 255, 255, 255, 255, 255 },
+      { 248, 254, 249, 253, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 246, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 252, 254, 251, 254, 254, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 254, 252, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 248, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 253, 255, 254, 254, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 245, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 253, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 251, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 252, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 249, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 255, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    }
+  }
+};
+
+void VP8WriteProbas(VP8BitWriter* const bw, const VP8Proba* const probas) {
+  int t, b, c, p;
+  for (t = 0; t < NUM_TYPES; ++t) {
+    for (b = 0; b < NUM_BANDS; ++b) {
+      for (c = 0; c < NUM_CTX; ++c) {
+        for (p = 0; p < NUM_PROBAS; ++p) {
+          const uint8_t p0 = probas->coeffs_[t][b][c][p];
+          const int update = (p0 != VP8CoeffsProba0[t][b][c][p]);
+          if (VP8PutBit(bw, update, VP8CoeffsUpdateProba[t][b][c][p])) {
+            VP8PutBits(bw, p0, 8);
+          }
+        }
+      }
+    }
+  }
+  if (VP8PutBitUniform(bw, probas->use_skip_proba_)) {
+    VP8PutBits(bw, probas->skip_proba_, 8);
+  }
+}
+
diff --git a/Source/LibWebP/src/enc/enc.vp8l.c b/Source/LibWebP/src/enc/enc.vp8l.c
new file mode 100644
index 0000000..032e224
--- /dev/null
+++ b/Source/LibWebP/src/enc/enc.vp8l.c
@@ -0,0 +1,1437 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// main entry for the lossless encoder.
+//
+// Author: Vikas Arora (vikaas.arora at gmail.com)
+//
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include "./backward_references.h"
+#include "./vp8enci.h"
+#include "./vp8li.h"
+#include "../dsp/lossless.h"
+#include "../utils/bit_writer.h"
+#include "../utils/huffman_encode.h"
+#include "../utils/utils.h"
+#include "../webp/format_constants.h"
+
+#define PALETTE_KEY_RIGHT_SHIFT   22  // Key for 1K buffer.
+// Maximum number of histogram images (sub-blocks).
+#define MAX_HUFF_IMAGE_SIZE       2600
+
+#define OPTIMIZE_MIN_NUM_COLORS 8
+
+// -----------------------------------------------------------------------------
+// Palette optimization
+
+static int CompareColors(const void* p1, const void* p2) {
+  const uint32_t a = *(const uint32_t*)p1;
+  const uint32_t b = *(const uint32_t*)p2;
+  assert(a != b);
+  return (a < b) ? -1 : 1;
+}
+static WEBP_INLINE int Distance(int a, int b) {
+  return abs(a - b);
+}
+
+static int ColorDistance(uint32_t col1, uint32_t col2) {
+  int score = 0;
+  // we favor grouping green channel in the palette
+  score += Distance((col1 >>  0) & 0xff, (col2 >>  0) & 0xff) * 5;
+  score += Distance((col1 >>  8) & 0xff, (col2 >>  8) & 0xff) * 8;
+  score += Distance((col1 >> 16) & 0xff, (col2 >> 16) & 0xff) * 5;
+  score += Distance((col1 >> 24) & 0xff, (col2 >> 24) & 0xff) * 1;
+  return score;
+}
+
+static void SwapColor(uint32_t* const col1, uint32_t* const col2) {
+  if (col1 != col2) {
+    const uint32_t tmp = *col1;
+    *col1 = *col2;
+    *col2 = tmp;
+  }
+}
+
+static int ShouldRestoreSortedPalette(int score_new, int score_orig) {
+  if ((score_orig > 200) && (score_new + 100 > score_orig)) {
+    return 1;  // improvement not big enough
+  }
+  // if drop is less 20%, it's not enough
+  if ((score_new + 100) > (score_orig + 100) * 80 / 100) {
+    return 1;
+  }
+  if (score_orig > 500) {  // if original palette was dispersed and...
+                           // improvement is not clear?
+    if (score_new > 300) return 1;
+  }
+  return 0;  // keep the new one
+}
+
+static void OptimizePalette(uint32_t palette[], int num_colors) {
+  uint32_t palette_orig[MAX_PALETTE_SIZE];
+  int score_orig = 0, score_new = 0;
+  int i;
+
+  // Compute original dispersion.
+  assert(num_colors > 1 && num_colors <= MAX_PALETTE_SIZE);
+  for (i = 1; i < num_colors; ++i) {
+    score_orig += ColorDistance(palette[i], palette[i - 1]);
+  }
+  score_orig /= (num_colors - 1);
+  // if score is already quite good, bail out at once.
+  if (score_orig < 100) return;
+
+  memcpy(palette_orig, palette, num_colors * sizeof(palette_orig[0]));
+
+  // palette[0] contains the lowest ordered color already. Keep it.
+  // Reorder subsequent palette colors by shortest distance to previous.
+  for (i = 1; i < num_colors; ++i) {
+    int j;
+    int best_col = -1;
+    int best_score = 0;
+    const uint32_t prev_color = palette[i - 1];
+    for (j = i; j < num_colors; ++j) {
+      const int score = ColorDistance(palette[j], prev_color);
+      if (best_col < 0 || score < best_score) {
+        best_col = j;
+        best_score = score;
+      }
+    }
+    score_new += best_score;
+    SwapColor(&palette[best_col], &palette[i]);
+  }
+  // dispersion is typically in range ~[100-1000]
+  score_new /= (num_colors - 1);
+
+  if (ShouldRestoreSortedPalette(score_new, score_orig)) {
+    memcpy(palette, palette_orig, num_colors * sizeof(palette[0]));
+  }
+}
+
+// -----------------------------------------------------------------------------
+// Palette
+
+// If number of colors in the image is less than or equal to MAX_PALETTE_SIZE,
+// creates a palette and returns true, else returns false.
+static int AnalyzeAndCreatePalette(const WebPPicture* const pic,
+                                   uint32_t palette[MAX_PALETTE_SIZE],
+                                   int* const palette_size) {
+  int i, x, y, key;
+  int num_colors = 0;
+  uint8_t in_use[MAX_PALETTE_SIZE * 4] = { 0 };
+  uint32_t colors[MAX_PALETTE_SIZE * 4];
+  static const uint32_t kHashMul = 0x1e35a7bd;
+  const uint32_t* argb = pic->argb;
+  const int width = pic->width;
+  const int height = pic->height;
+  uint32_t all_color_bits;
+  uint32_t last_pix = ~argb[0];   // so we're sure that last_pix != argb[0]
+
+  for (y = 0; y < height; ++y) {
+    for (x = 0; x < width; ++x) {
+      if (argb[x] == last_pix) {
+        continue;
+      }
+      last_pix = argb[x];
+      key = (kHashMul * last_pix) >> PALETTE_KEY_RIGHT_SHIFT;
+      while (1) {
+        if (!in_use[key]) {
+          colors[key] = last_pix;
+          in_use[key] = 1;
+          ++num_colors;
+          if (num_colors > MAX_PALETTE_SIZE) {
+            return 0;
+          }
+          break;
+        } else if (colors[key] == last_pix) {
+          // The color is already there.
+          break;
+        } else {
+          // Some other color sits there.
+          // Do linear conflict resolution.
+          ++key;
+          key &= (MAX_PALETTE_SIZE * 4 - 1);  // key mask for 1K buffer.
+        }
+      }
+    }
+    argb += pic->argb_stride;
+  }
+
+  // TODO(skal): could we reuse in_use[] to speed up EncodePalette()?
+  num_colors = 0;
+  all_color_bits = 0x00000000;
+  for (i = 0; i < (int)(sizeof(in_use) / sizeof(in_use[0])); ++i) {
+    if (in_use[i]) {
+      palette[num_colors] = colors[i];
+      all_color_bits |= colors[i];
+      ++num_colors;
+    }
+  }
+
+  *palette_size = num_colors;
+  qsort(palette, num_colors, sizeof(*palette), CompareColors);
+  // OptimizePalette() is not useful for single-channel (like alpha, e.g.).
+  if (num_colors > OPTIMIZE_MIN_NUM_COLORS &&
+      (all_color_bits & ~0x000000ffu) != 0 &&   // all red?
+      (all_color_bits & ~0x0000ff00u) != 0 &&   // all green/alpha?
+      (all_color_bits & ~0x00ff0000u) != 0) {   // all blue?
+    OptimizePalette(palette, num_colors);
+  }
+  return 1;
+}
+
+static int AnalyzeEntropy(const uint32_t* argb,
+                          int width, int height, int argb_stride,
+                          double* const nonpredicted_bits,
+                          double* const predicted_bits) {
+  // Allocate histogram set with cache_bits = 0.
+  VP8LHistogramSet* const histo_set = VP8LAllocateHistogramSet(2, 0);
+  assert(nonpredicted_bits != NULL);
+  assert(predicted_bits != NULL);
+
+  if (histo_set != NULL) {
+    int x, y;
+    const uint32_t* prev_row = argb;
+    const uint32_t* curr_row = argb + argb_stride;
+    VP8LHistogram* const histo_non_pred = histo_set->histograms[0];
+    VP8LHistogram* const histo_pred = histo_set->histograms[1];
+    for (y = 1; y < height; ++y) {
+      uint32_t prev_pix = curr_row[0];
+      for (x = 1; x < width; ++x) {
+        const uint32_t pix = curr_row[x];
+        const uint32_t pix_diff = VP8LSubPixels(pix, prev_pix);
+        if ((pix_diff == 0) || (pix == prev_row[x])) continue;
+        prev_pix = pix;
+        {
+          const PixOrCopy pix_token = PixOrCopyCreateLiteral(pix);
+          const PixOrCopy pix_diff_token = PixOrCopyCreateLiteral(pix_diff);
+          VP8LHistogramAddSinglePixOrCopy(histo_non_pred, &pix_token);
+          VP8LHistogramAddSinglePixOrCopy(histo_pred, &pix_diff_token);
+        }
+      }
+      prev_row = curr_row;
+      curr_row += argb_stride;
+    }
+    *nonpredicted_bits = VP8LHistogramEstimateBitsBulk(histo_non_pred);
+    *predicted_bits = VP8LHistogramEstimateBitsBulk(histo_pred);
+    VP8LFreeHistogramSet(histo_set);
+    return 1;
+  } else {
+    return 0;
+  }
+}
+
+// Check if it would be a good idea to subtract green from red and blue. We
+// only evaluate entropy in red/blue components, don't bother to look at others.
+static int AnalyzeSubtractGreen(const uint32_t* const argb,
+                                int width, int height,
+                                double* const entropy_change_ratio) {
+  // Allocate histogram set with cache_bits = 1.
+  VP8LHistogramSet* const histo_set = VP8LAllocateHistogramSet(2, 1);
+  assert(entropy_change_ratio != NULL);
+
+  if (histo_set != NULL) {
+    int i;
+    double bit_cost, bit_cost_subgreen;
+    VP8LHistogram* const histo = histo_set->histograms[0];
+    VP8LHistogram* const histo_subgreen = histo_set->histograms[1];
+    for (i = 0; i < width * height; ++i) {
+      const uint32_t c = argb[i];
+      const int green = (c >> 8) & 0xff;
+      const int red = (c >> 16) & 0xff;
+      const int blue = (c >> 0) & 0xff;
+      ++histo->red_[red];
+      ++histo->blue_[blue];
+      ++histo_subgreen->red_[(red - green) & 0xff];
+      ++histo_subgreen->blue_[(blue - green) & 0xff];
+    }
+    bit_cost= VP8LHistogramEstimateBits(histo);
+    bit_cost_subgreen = VP8LHistogramEstimateBits(histo_subgreen);
+    VP8LFreeHistogramSet(histo_set);
+    *entropy_change_ratio = bit_cost_subgreen / (bit_cost + 1e-6);
+    return 1;
+  } else {
+    return 0;
+  }
+}
+
+static int GetHistoBits(int method, int use_palette, int width, int height) {
+  // Make tile size a function of encoding method (Range: 0 to 6).
+  int histo_bits = (use_palette ? 9 : 7) - method;
+  while (1) {
+    const int huff_image_size = VP8LSubSampleSize(width, histo_bits) *
+                                VP8LSubSampleSize(height, histo_bits);
+    if (huff_image_size <= MAX_HUFF_IMAGE_SIZE) break;
+    ++histo_bits;
+  }
+  return (histo_bits < MIN_HUFFMAN_BITS) ? MIN_HUFFMAN_BITS :
+         (histo_bits > MAX_HUFFMAN_BITS) ? MAX_HUFFMAN_BITS : histo_bits;
+}
+
+static int GetTransformBits(int method, int histo_bits) {
+  const int max_transform_bits = (method < 4) ? 6 : (method > 4) ? 4 : 5;
+  return (histo_bits > max_transform_bits) ? max_transform_bits : histo_bits;
+}
+
+static int EvalSubtractGreenForPalette(int palette_size, float quality) {
+  // Evaluate non-palette encoding (subtract green, prediction transforms etc)
+  // for palette size in the mid-range (17-96) as for larger number of colors,
+  // the benefit from switching to non-palette is not much.
+  // Non-palette transforms are little CPU intensive, hence don't evaluate them
+  // for lower (<= 25) quality.
+  const int min_colors_non_palette = 17;
+  const int max_colors_non_palette = 96;
+  const float min_quality_non_palette = 26.f;
+  return (palette_size >= min_colors_non_palette) &&
+         (palette_size <= max_colors_non_palette) &&
+         (quality >= min_quality_non_palette);
+}
+
+static int AnalyzeAndInit(VP8LEncoder* const enc, WebPImageHint image_hint) {
+  const WebPPicture* const pic = enc->pic_;
+  const int width = pic->width;
+  const int height = pic->height;
+  const int pix_cnt = width * height;
+  const WebPConfig* const config = enc->config_;
+  const int method = config->method;
+  const int low_effort = (config->method == 0);
+  const float quality = config->quality;
+  double subtract_green_score = 10.0;
+  const double subtract_green_threshold_palette = 0.80;
+  const double subtract_green_threshold_non_palette = 1.0;
+  // we round the block size up, so we're guaranteed to have
+  // at max MAX_REFS_BLOCK_PER_IMAGE blocks used:
+  int refs_block_size = (pix_cnt - 1) / MAX_REFS_BLOCK_PER_IMAGE + 1;
+  assert(pic != NULL && pic->argb != NULL);
+
+  enc->use_palette_ =
+      AnalyzeAndCreatePalette(pic, enc->palette_, &enc->palette_size_);
+
+  if (!enc->use_palette_ ||
+      EvalSubtractGreenForPalette(enc->palette_size_, quality)) {
+    if (low_effort) {
+      // For low effort compression, avoid calling (costly) method
+      // AnalyzeSubtractGreen and enable the subtract-green transform
+      // for non-palette images.
+      subtract_green_score = subtract_green_threshold_non_palette * 0.99;
+    } else {
+      if (!AnalyzeSubtractGreen(pic->argb, width, height,
+                                &subtract_green_score)) {
+        return 0;
+      }
+    }
+  }
+
+  // Evaluate histogram bits based on the original value of use_palette flag.
+  enc->histo_bits_ = GetHistoBits(method, enc->use_palette_, pic->width,
+                                  pic->height);
+  enc->transform_bits_ = GetTransformBits(method, enc->histo_bits_);
+
+  enc->use_subtract_green_ = 0;
+  if (enc->use_palette_) {
+    // Check if other transforms (subtract green etc) are potentially better.
+    if (subtract_green_score < subtract_green_threshold_palette) {
+      enc->use_subtract_green_ = 1;
+      enc->use_palette_ = 0;
+    }
+  } else {
+    // Non-palette case, check if subtract-green optimizes the entropy.
+    if (subtract_green_score < subtract_green_threshold_non_palette) {
+      enc->use_subtract_green_ = 1;
+    }
+  }
+
+  if (!enc->use_palette_) {
+    if (image_hint == WEBP_HINT_PHOTO) {
+      enc->use_predict_ = 1;
+      enc->use_cross_color_ = !low_effort;
+    } else {
+      double non_pred_entropy, pred_entropy;
+      if (!AnalyzeEntropy(pic->argb, width, height, pic->argb_stride,
+                          &non_pred_entropy, &pred_entropy)) {
+        return 0;
+      }
+      if (pred_entropy < 0.95 * non_pred_entropy) {
+        enc->use_predict_ = 1;
+        enc->use_cross_color_ = !low_effort;
+      }
+    }
+  }
+  if (!VP8LHashChainInit(&enc->hash_chain_, pix_cnt)) return 0;
+
+  // palette-friendly input typically uses less literals
+  //  -> reduce block size a bit
+  if (enc->use_palette_) refs_block_size /= 2;
+  VP8LBackwardRefsInit(&enc->refs_[0], refs_block_size);
+  VP8LBackwardRefsInit(&enc->refs_[1], refs_block_size);
+
+  return 1;
+}
+
+// Returns false in case of memory error.
+static int GetHuffBitLengthsAndCodes(
+    const VP8LHistogramSet* const histogram_image,
+    HuffmanTreeCode* const huffman_codes) {
+  int i, k;
+  int ok = 0;
+  uint64_t total_length_size = 0;
+  uint8_t* mem_buf = NULL;
+  const int histogram_image_size = histogram_image->size;
+  int max_num_symbols = 0;
+  uint8_t* buf_rle = NULL;
+  HuffmanTree* huff_tree = NULL;
+
+  // Iterate over all histograms and get the aggregate number of codes used.
+  for (i = 0; i < histogram_image_size; ++i) {
+    const VP8LHistogram* const histo = histogram_image->histograms[i];
+    HuffmanTreeCode* const codes = &huffman_codes[5 * i];
+    for (k = 0; k < 5; ++k) {
+      const int num_symbols =
+          (k == 0) ? VP8LHistogramNumCodes(histo->palette_code_bits_) :
+          (k == 4) ? NUM_DISTANCE_CODES : 256;
+      codes[k].num_symbols = num_symbols;
+      total_length_size += num_symbols;
+    }
+  }
+
+  // Allocate and Set Huffman codes.
+  {
+    uint16_t* codes;
+    uint8_t* lengths;
+    mem_buf = (uint8_t*)WebPSafeCalloc(total_length_size,
+                                       sizeof(*lengths) + sizeof(*codes));
+    if (mem_buf == NULL) goto End;
+
+    codes = (uint16_t*)mem_buf;
+    lengths = (uint8_t*)&codes[total_length_size];
+    for (i = 0; i < 5 * histogram_image_size; ++i) {
+      const int bit_length = huffman_codes[i].num_symbols;
+      huffman_codes[i].codes = codes;
+      huffman_codes[i].code_lengths = lengths;
+      codes += bit_length;
+      lengths += bit_length;
+      if (max_num_symbols < bit_length) {
+        max_num_symbols = bit_length;
+      }
+    }
+  }
+
+  buf_rle = (uint8_t*)WebPSafeMalloc(1ULL, max_num_symbols);
+  huff_tree = (HuffmanTree*)WebPSafeMalloc(3ULL * max_num_symbols,
+                                           sizeof(*huff_tree));
+  if (buf_rle == NULL || huff_tree == NULL) goto End;
+
+  // Create Huffman trees.
+  for (i = 0; i < histogram_image_size; ++i) {
+    HuffmanTreeCode* const codes = &huffman_codes[5 * i];
+    VP8LHistogram* const histo = histogram_image->histograms[i];
+    VP8LCreateHuffmanTree(histo->literal_, 15, buf_rle, huff_tree, codes + 0);
+    VP8LCreateHuffmanTree(histo->red_, 15, buf_rle, huff_tree, codes + 1);
+    VP8LCreateHuffmanTree(histo->blue_, 15, buf_rle, huff_tree, codes + 2);
+    VP8LCreateHuffmanTree(histo->alpha_, 15, buf_rle, huff_tree, codes + 3);
+    VP8LCreateHuffmanTree(histo->distance_, 15, buf_rle, huff_tree, codes + 4);
+  }
+  ok = 1;
+ End:
+  WebPSafeFree(huff_tree);
+  WebPSafeFree(buf_rle);
+  if (!ok) {
+    WebPSafeFree(mem_buf);
+    memset(huffman_codes, 0, 5 * histogram_image_size * sizeof(*huffman_codes));
+  }
+  return ok;
+}
+
+static void StoreHuffmanTreeOfHuffmanTreeToBitMask(
+    VP8LBitWriter* const bw, const uint8_t* code_length_bitdepth) {
+  // RFC 1951 will calm you down if you are worried about this funny sequence.
+  // This sequence is tuned from that, but more weighted for lower symbol count,
+  // and more spiking histograms.
+  static const uint8_t kStorageOrder[CODE_LENGTH_CODES] = {
+    17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
+  };
+  int i;
+  // Throw away trailing zeros:
+  int codes_to_store = CODE_LENGTH_CODES;
+  for (; codes_to_store > 4; --codes_to_store) {
+    if (code_length_bitdepth[kStorageOrder[codes_to_store - 1]] != 0) {
+      break;
+    }
+  }
+  VP8LPutBits(bw, codes_to_store - 4, 4);
+  for (i = 0; i < codes_to_store; ++i) {
+    VP8LPutBits(bw, code_length_bitdepth[kStorageOrder[i]], 3);
+  }
+}
+
+static void ClearHuffmanTreeIfOnlyOneSymbol(
+    HuffmanTreeCode* const huffman_code) {
+  int k;
+  int count = 0;
+  for (k = 0; k < huffman_code->num_symbols; ++k) {
+    if (huffman_code->code_lengths[k] != 0) {
+      ++count;
+      if (count > 1) return;
+    }
+  }
+  for (k = 0; k < huffman_code->num_symbols; ++k) {
+    huffman_code->code_lengths[k] = 0;
+    huffman_code->codes[k] = 0;
+  }
+}
+
+static void StoreHuffmanTreeToBitMask(
+    VP8LBitWriter* const bw,
+    const HuffmanTreeToken* const tokens, const int num_tokens,
+    const HuffmanTreeCode* const huffman_code) {
+  int i;
+  for (i = 0; i < num_tokens; ++i) {
+    const int ix = tokens[i].code;
+    const int extra_bits = tokens[i].extra_bits;
+    VP8LPutBits(bw, huffman_code->codes[ix], huffman_code->code_lengths[ix]);
+    switch (ix) {
+      case 16:
+        VP8LPutBits(bw, extra_bits, 2);
+        break;
+      case 17:
+        VP8LPutBits(bw, extra_bits, 3);
+        break;
+      case 18:
+        VP8LPutBits(bw, extra_bits, 7);
+        break;
+    }
+  }
+}
+
+// 'huff_tree' and 'tokens' are pre-alloacted buffers.
+static void StoreFullHuffmanCode(VP8LBitWriter* const bw,
+                                 HuffmanTree* const huff_tree,
+                                 HuffmanTreeToken* const tokens,
+                                 const HuffmanTreeCode* const tree) {
+  uint8_t code_length_bitdepth[CODE_LENGTH_CODES] = { 0 };
+  uint16_t code_length_bitdepth_symbols[CODE_LENGTH_CODES] = { 0 };
+  const int max_tokens = tree->num_symbols;
+  int num_tokens;
+  HuffmanTreeCode huffman_code;
+  huffman_code.num_symbols = CODE_LENGTH_CODES;
+  huffman_code.code_lengths = code_length_bitdepth;
+  huffman_code.codes = code_length_bitdepth_symbols;
+
+  VP8LPutBits(bw, 0, 1);
+  num_tokens = VP8LCreateCompressedHuffmanTree(tree, tokens, max_tokens);
+  {
+    uint32_t histogram[CODE_LENGTH_CODES] = { 0 };
+    uint8_t buf_rle[CODE_LENGTH_CODES] = { 0 };
+    int i;
+    for (i = 0; i < num_tokens; ++i) {
+      ++histogram[tokens[i].code];
+    }
+
+    VP8LCreateHuffmanTree(histogram, 7, buf_rle, huff_tree, &huffman_code);
+  }
+
+  StoreHuffmanTreeOfHuffmanTreeToBitMask(bw, code_length_bitdepth);
+  ClearHuffmanTreeIfOnlyOneSymbol(&huffman_code);
+  {
+    int trailing_zero_bits = 0;
+    int trimmed_length = num_tokens;
+    int write_trimmed_length;
+    int length;
+    int i = num_tokens;
+    while (i-- > 0) {
+      const int ix = tokens[i].code;
+      if (ix == 0 || ix == 17 || ix == 18) {
+        --trimmed_length;   // discount trailing zeros
+        trailing_zero_bits += code_length_bitdepth[ix];
+        if (ix == 17) {
+          trailing_zero_bits += 3;
+        } else if (ix == 18) {
+          trailing_zero_bits += 7;
+        }
+      } else {
+        break;
+      }
+    }
+    write_trimmed_length = (trimmed_length > 1 && trailing_zero_bits > 12);
+    length = write_trimmed_length ? trimmed_length : num_tokens;
+    VP8LPutBits(bw, write_trimmed_length, 1);
+    if (write_trimmed_length) {
+      const int nbits = VP8LBitsLog2Ceiling(trimmed_length - 1);
+      const int nbitpairs = (nbits == 0) ? 1 : (nbits + 1) / 2;
+      VP8LPutBits(bw, nbitpairs - 1, 3);
+      assert(trimmed_length >= 2);
+      VP8LPutBits(bw, trimmed_length - 2, nbitpairs * 2);
+    }
+    StoreHuffmanTreeToBitMask(bw, tokens, length, &huffman_code);
+  }
+}
+
+// 'huff_tree' and 'tokens' are pre-alloacted buffers.
+static void StoreHuffmanCode(VP8LBitWriter* const bw,
+                             HuffmanTree* const huff_tree,
+                             HuffmanTreeToken* const tokens,
+                             const HuffmanTreeCode* const huffman_code) {
+  int i;
+  int count = 0;
+  int symbols[2] = { 0, 0 };
+  const int kMaxBits = 8;
+  const int kMaxSymbol = 1 << kMaxBits;
+
+  // Check whether it's a small tree.
+  for (i = 0; i < huffman_code->num_symbols && count < 3; ++i) {
+    if (huffman_code->code_lengths[i] != 0) {
+      if (count < 2) symbols[count] = i;
+      ++count;
+    }
+  }
+
+  if (count == 0) {   // emit minimal tree for empty cases
+    // bits: small tree marker: 1, count-1: 0, large 8-bit code: 0, code: 0
+    VP8LPutBits(bw, 0x01, 4);
+  } else if (count <= 2 && symbols[0] < kMaxSymbol && symbols[1] < kMaxSymbol) {
+    VP8LPutBits(bw, 1, 1);  // Small tree marker to encode 1 or 2 symbols.
+    VP8LPutBits(bw, count - 1, 1);
+    if (symbols[0] <= 1) {
+      VP8LPutBits(bw, 0, 1);  // Code bit for small (1 bit) symbol value.
+      VP8LPutBits(bw, symbols[0], 1);
+    } else {
+      VP8LPutBits(bw, 1, 1);
+      VP8LPutBits(bw, symbols[0], 8);
+    }
+    if (count == 2) {
+      VP8LPutBits(bw, symbols[1], 8);
+    }
+  } else {
+    StoreFullHuffmanCode(bw, huff_tree, tokens, huffman_code);
+  }
+}
+
+static void WriteHuffmanCode(VP8LBitWriter* const bw,
+                             const HuffmanTreeCode* const code,
+                             int code_index) {
+  const int depth = code->code_lengths[code_index];
+  const int symbol = code->codes[code_index];
+  VP8LPutBits(bw, symbol, depth);
+}
+
+static WebPEncodingError StoreImageToBitMask(
+    VP8LBitWriter* const bw, int width, int histo_bits,
+    VP8LBackwardRefs* const refs,
+    const uint16_t* histogram_symbols,
+    const HuffmanTreeCode* const huffman_codes) {
+  const int histo_xsize = histo_bits ? VP8LSubSampleSize(width, histo_bits) : 1;
+  const int tile_mask = (histo_bits == 0) ? 0 : -(1 << histo_bits);
+  // x and y trace the position in the image.
+  int x = 0;
+  int y = 0;
+  int tile_x = x & tile_mask;
+  int tile_y = y & tile_mask;
+  int histogram_ix = histogram_symbols[0];
+  const HuffmanTreeCode* codes = huffman_codes + 5 * histogram_ix;
+  VP8LRefsCursor c = VP8LRefsCursorInit(refs);
+  while (VP8LRefsCursorOk(&c)) {
+    const PixOrCopy* const v = c.cur_pos;
+    if ((tile_x != (x & tile_mask)) || (tile_y != (y & tile_mask))) {
+      tile_x = x & tile_mask;
+      tile_y = y & tile_mask;
+      histogram_ix = histogram_symbols[(y >> histo_bits) * histo_xsize +
+                                       (x >> histo_bits)];
+      codes = huffman_codes + 5 * histogram_ix;
+    }
+    if (PixOrCopyIsCacheIdx(v)) {
+      const int code = PixOrCopyCacheIdx(v);
+      const int literal_ix = 256 + NUM_LENGTH_CODES + code;
+      WriteHuffmanCode(bw, codes, literal_ix);
+    } else if (PixOrCopyIsLiteral(v)) {
+      static const int order[] = { 1, 2, 0, 3 };
+      int k;
+      for (k = 0; k < 4; ++k) {
+        const int code = PixOrCopyLiteral(v, order[k]);
+        WriteHuffmanCode(bw, codes + k, code);
+      }
+    } else {
+      int bits, n_bits;
+      int code, distance;
+
+      VP8LPrefixEncode(v->len, &code, &n_bits, &bits);
+      WriteHuffmanCode(bw, codes, 256 + code);
+      VP8LPutBits(bw, bits, n_bits);
+
+      distance = PixOrCopyDistance(v);
+      VP8LPrefixEncode(distance, &code, &n_bits, &bits);
+      WriteHuffmanCode(bw, codes + 4, code);
+      VP8LPutBits(bw, bits, n_bits);
+    }
+    x += PixOrCopyLength(v);
+    while (x >= width) {
+      x -= width;
+      ++y;
+    }
+    VP8LRefsCursorNext(&c);
+  }
+  return bw->error_ ? VP8_ENC_ERROR_OUT_OF_MEMORY : VP8_ENC_OK;
+}
+
+// Special case of EncodeImageInternal() for cache-bits=0, histo_bits=31
+static WebPEncodingError EncodeImageNoHuffman(VP8LBitWriter* const bw,
+                                              const uint32_t* const argb,
+                                              VP8LHashChain* const hash_chain,
+                                              VP8LBackwardRefs refs_array[2],
+                                              int width, int height,
+                                              int quality) {
+  int i;
+  int max_tokens = 0;
+  WebPEncodingError err = VP8_ENC_OK;
+  VP8LBackwardRefs* refs;
+  HuffmanTreeToken* tokens = NULL;
+  HuffmanTreeCode huffman_codes[5] = { { 0, NULL, NULL } };
+  const uint16_t histogram_symbols[1] = { 0 };    // only one tree, one symbol
+  int cache_bits = 0;
+  VP8LHistogramSet* histogram_image = NULL;
+  HuffmanTree* const huff_tree = (HuffmanTree*)WebPSafeMalloc(
+        3ULL * CODE_LENGTH_CODES, sizeof(*huff_tree));
+  if (huff_tree == NULL) {
+    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
+    goto Error;
+  }
+
+  // Calculate backward references from ARGB image.
+  refs = VP8LGetBackwardReferences(width, height, argb, quality, 0, &cache_bits,
+                                   hash_chain, refs_array);
+  if (refs == NULL) {
+    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
+    goto Error;
+  }
+  histogram_image = VP8LAllocateHistogramSet(1, cache_bits);
+  if (histogram_image == NULL) {
+    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
+    goto Error;
+  }
+
+  // Build histogram image and symbols from backward references.
+  VP8LHistogramStoreRefs(refs, histogram_image->histograms[0]);
+
+  // Create Huffman bit lengths and codes for each histogram image.
+  assert(histogram_image->size == 1);
+  if (!GetHuffBitLengthsAndCodes(histogram_image, huffman_codes)) {
+    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
+    goto Error;
+  }
+
+  // No color cache, no Huffman image.
+  VP8LPutBits(bw, 0, 1);
+
+  // Find maximum number of symbols for the huffman tree-set.
+  for (i = 0; i < 5; ++i) {
+    HuffmanTreeCode* const codes = &huffman_codes[i];
+    if (max_tokens < codes->num_symbols) {
+      max_tokens = codes->num_symbols;
+    }
+  }
+
+  tokens = (HuffmanTreeToken*)WebPSafeMalloc(max_tokens, sizeof(*tokens));
+  if (tokens == NULL) {
+    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
+    goto Error;
+  }
+
+  // Store Huffman codes.
+  for (i = 0; i < 5; ++i) {
+    HuffmanTreeCode* const codes = &huffman_codes[i];
+    StoreHuffmanCode(bw, huff_tree, tokens, codes);
+    ClearHuffmanTreeIfOnlyOneSymbol(codes);
+  }
+
+  // Store actual literals.
+  err = StoreImageToBitMask(bw, width, 0, refs, histogram_symbols,
+                            huffman_codes);
+
+ Error:
+  WebPSafeFree(tokens);
+  WebPSafeFree(huff_tree);
+  VP8LFreeHistogramSet(histogram_image);
+  WebPSafeFree(huffman_codes[0].codes);
+  return err;
+}
+
+static WebPEncodingError EncodeImageInternal(VP8LBitWriter* const bw,
+                                             const uint32_t* const argb,
+                                             VP8LHashChain* const hash_chain,
+                                             VP8LBackwardRefs refs_array[2],
+                                             int width, int height, int quality,
+                                             int low_effort,
+                                             int use_cache, int* cache_bits,
+                                             int histogram_bits,
+                                             size_t init_byte_position,
+                                             int* const hdr_size,
+                                             int* const data_size) {
+  WebPEncodingError err = VP8_ENC_OK;
+  const uint32_t histogram_image_xysize =
+      VP8LSubSampleSize(width, histogram_bits) *
+      VP8LSubSampleSize(height, histogram_bits);
+  VP8LHistogramSet* histogram_image = NULL;
+  VP8LHistogramSet* tmp_histos = NULL;
+  int histogram_image_size = 0;
+  size_t bit_array_size = 0;
+  HuffmanTree* huff_tree = NULL;
+  HuffmanTreeToken* tokens = NULL;
+  HuffmanTreeCode* huffman_codes = NULL;
+  VP8LBackwardRefs refs;
+  VP8LBackwardRefs* best_refs;
+  uint16_t* const histogram_symbols =
+      (uint16_t*)WebPSafeMalloc(histogram_image_xysize,
+                                sizeof(*histogram_symbols));
+  assert(histogram_bits >= MIN_HUFFMAN_BITS);
+  assert(histogram_bits <= MAX_HUFFMAN_BITS);
+  assert(hdr_size != NULL);
+  assert(data_size != NULL);
+
+  VP8LBackwardRefsInit(&refs, refs_array[0].block_size_);
+  if (histogram_symbols == NULL) {
+    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
+    goto Error;
+  }
+
+  *cache_bits = use_cache ? MAX_COLOR_CACHE_BITS : 0;
+  // 'best_refs' is the reference to the best backward refs and points to one
+  // of refs_array[0] or refs_array[1].
+  // Calculate backward references from ARGB image.
+  best_refs = VP8LGetBackwardReferences(width, height, argb, quality,
+                                        low_effort, cache_bits, hash_chain,
+                                        refs_array);
+  if (best_refs == NULL || !VP8LBackwardRefsCopy(best_refs, &refs)) {
+    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
+    goto Error;
+  }
+  histogram_image =
+      VP8LAllocateHistogramSet(histogram_image_xysize, *cache_bits);
+  tmp_histos = VP8LAllocateHistogramSet(2, *cache_bits);
+  if (histogram_image == NULL || tmp_histos == NULL) {
+    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
+    goto Error;
+  }
+
+  // Build histogram image and symbols from backward references.
+  if (!VP8LGetHistoImageSymbols(width, height, &refs, quality, low_effort,
+                                histogram_bits, *cache_bits, histogram_image,
+                                tmp_histos, histogram_symbols)) {
+    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
+    goto Error;
+  }
+  // Create Huffman bit lengths and codes for each histogram image.
+  histogram_image_size = histogram_image->size;
+  bit_array_size = 5 * histogram_image_size;
+  huffman_codes = (HuffmanTreeCode*)WebPSafeCalloc(bit_array_size,
+                                                   sizeof(*huffman_codes));
+  // Note: some histogram_image entries may point to tmp_histos[], so the latter
+  // need to outlive the following call to GetHuffBitLengthsAndCodes().
+  if (huffman_codes == NULL ||
+      !GetHuffBitLengthsAndCodes(histogram_image, huffman_codes)) {
+    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
+    goto Error;
+  }
+  // Free combined histograms.
+  VP8LFreeHistogramSet(histogram_image);
+  histogram_image = NULL;
+
+  // Free scratch histograms.
+  VP8LFreeHistogramSet(tmp_histos);
+  tmp_histos = NULL;
+
+  // Color Cache parameters.
+  if (*cache_bits > 0) {
+    VP8LPutBits(bw, 1, 1);
+    VP8LPutBits(bw, *cache_bits, 4);
+  } else {
+    VP8LPutBits(bw, 0, 1);
+  }
+
+  // Huffman image + meta huffman.
+  {
+    const int write_histogram_image = (histogram_image_size > 1);
+    VP8LPutBits(bw, write_histogram_image, 1);
+    if (write_histogram_image) {
+      uint32_t* const histogram_argb =
+          (uint32_t*)WebPSafeMalloc(histogram_image_xysize,
+                                    sizeof(*histogram_argb));
+      int max_index = 0;
+      uint32_t i;
+      if (histogram_argb == NULL) {
+        err = VP8_ENC_ERROR_OUT_OF_MEMORY;
+        goto Error;
+      }
+      for (i = 0; i < histogram_image_xysize; ++i) {
+        const int symbol_index = histogram_symbols[i] & 0xffff;
+        histogram_argb[i] = (symbol_index << 8);
+        if (symbol_index >= max_index) {
+          max_index = symbol_index + 1;
+        }
+      }
+      histogram_image_size = max_index;
+
+      VP8LPutBits(bw, histogram_bits - 2, 3);
+      err = EncodeImageNoHuffman(bw, histogram_argb, hash_chain, refs_array,
+                                 VP8LSubSampleSize(width, histogram_bits),
+                                 VP8LSubSampleSize(height, histogram_bits),
+                                 quality);
+      WebPSafeFree(histogram_argb);
+      if (err != VP8_ENC_OK) goto Error;
+    }
+  }
+
+  // Store Huffman codes.
+  {
+    int i;
+    int max_tokens = 0;
+    huff_tree = (HuffmanTree*)WebPSafeMalloc(3ULL * CODE_LENGTH_CODES,
+                                             sizeof(*huff_tree));
+    if (huff_tree == NULL) {
+      err = VP8_ENC_ERROR_OUT_OF_MEMORY;
+      goto Error;
+    }
+    // Find maximum number of symbols for the huffman tree-set.
+    for (i = 0; i < 5 * histogram_image_size; ++i) {
+      HuffmanTreeCode* const codes = &huffman_codes[i];
+      if (max_tokens < codes->num_symbols) {
+        max_tokens = codes->num_symbols;
+      }
+    }
+    tokens = (HuffmanTreeToken*)WebPSafeMalloc(max_tokens,
+                                               sizeof(*tokens));
+    if (tokens == NULL) {
+      err = VP8_ENC_ERROR_OUT_OF_MEMORY;
+      goto Error;
+    }
+    for (i = 0; i < 5 * histogram_image_size; ++i) {
+      HuffmanTreeCode* const codes = &huffman_codes[i];
+      StoreHuffmanCode(bw, huff_tree, tokens, codes);
+      ClearHuffmanTreeIfOnlyOneSymbol(codes);
+    }
+  }
+
+  *hdr_size = (int)(VP8LBitWriterNumBytes(bw) - init_byte_position);
+  // Store actual literals.
+  err = StoreImageToBitMask(bw, width, histogram_bits, &refs,
+                            histogram_symbols, huffman_codes);
+  *data_size =
+        (int)(VP8LBitWriterNumBytes(bw) - init_byte_position - *hdr_size);
+
+ Error:
+  WebPSafeFree(tokens);
+  WebPSafeFree(huff_tree);
+  VP8LFreeHistogramSet(histogram_image);
+  VP8LFreeHistogramSet(tmp_histos);
+  VP8LBackwardRefsClear(&refs);
+  if (huffman_codes != NULL) {
+    WebPSafeFree(huffman_codes->codes);
+    WebPSafeFree(huffman_codes);
+  }
+  WebPSafeFree(histogram_symbols);
+  return err;
+}
+
+// -----------------------------------------------------------------------------
+// Transforms
+
+static void ApplySubtractGreen(VP8LEncoder* const enc, int width, int height,
+                               VP8LBitWriter* const bw) {
+  VP8LPutBits(bw, TRANSFORM_PRESENT, 1);
+  VP8LPutBits(bw, SUBTRACT_GREEN, 2);
+  VP8LSubtractGreenFromBlueAndRed(enc->argb_, width * height);
+}
+
+static WebPEncodingError ApplyPredictFilter(const VP8LEncoder* const enc,
+                                            int width, int height,
+                                            int quality, int low_effort,
+                                            VP8LBitWriter* const bw) {
+  const int pred_bits = enc->transform_bits_;
+  const int transform_width = VP8LSubSampleSize(width, pred_bits);
+  const int transform_height = VP8LSubSampleSize(height, pred_bits);
+
+  VP8LResidualImage(width, height, pred_bits, low_effort, enc->argb_,
+                    enc->argb_scratch_, enc->transform_data_);
+  VP8LPutBits(bw, TRANSFORM_PRESENT, 1);
+  VP8LPutBits(bw, PREDICTOR_TRANSFORM, 2);
+  assert(pred_bits >= 2);
+  VP8LPutBits(bw, pred_bits - 2, 3);
+  return EncodeImageNoHuffman(bw, enc->transform_data_,
+                              (VP8LHashChain*)&enc->hash_chain_,
+                              (VP8LBackwardRefs*)enc->refs_,  // cast const away
+                              transform_width, transform_height,
+                              quality);
+}
+
+static WebPEncodingError ApplyCrossColorFilter(const VP8LEncoder* const enc,
+                                               int width, int height,
+                                               int quality,
+                                               VP8LBitWriter* const bw) {
+  const int ccolor_transform_bits = enc->transform_bits_;
+  const int transform_width = VP8LSubSampleSize(width, ccolor_transform_bits);
+  const int transform_height = VP8LSubSampleSize(height, ccolor_transform_bits);
+
+  VP8LColorSpaceTransform(width, height, ccolor_transform_bits, quality,
+                          enc->argb_, enc->transform_data_);
+  VP8LPutBits(bw, TRANSFORM_PRESENT, 1);
+  VP8LPutBits(bw, CROSS_COLOR_TRANSFORM, 2);
+  assert(ccolor_transform_bits >= 2);
+  VP8LPutBits(bw, ccolor_transform_bits - 2, 3);
+  return EncodeImageNoHuffman(bw, enc->transform_data_,
+                              (VP8LHashChain*)&enc->hash_chain_,
+                              (VP8LBackwardRefs*)enc->refs_,  // cast const away
+                              transform_width, transform_height,
+                              quality);
+}
+
+// -----------------------------------------------------------------------------
+
+static WebPEncodingError WriteRiffHeader(const WebPPicture* const pic,
+                                         size_t riff_size, size_t vp8l_size) {
+  uint8_t riff[RIFF_HEADER_SIZE + CHUNK_HEADER_SIZE + VP8L_SIGNATURE_SIZE] = {
+    'R', 'I', 'F', 'F', 0, 0, 0, 0, 'W', 'E', 'B', 'P',
+    'V', 'P', '8', 'L', 0, 0, 0, 0, VP8L_MAGIC_BYTE,
+  };
+  PutLE32(riff + TAG_SIZE, (uint32_t)riff_size);
+  PutLE32(riff + RIFF_HEADER_SIZE + TAG_SIZE, (uint32_t)vp8l_size);
+  if (!pic->writer(riff, sizeof(riff), pic)) {
+    return VP8_ENC_ERROR_BAD_WRITE;
+  }
+  return VP8_ENC_OK;
+}
+
+static int WriteImageSize(const WebPPicture* const pic,
+                          VP8LBitWriter* const bw) {
+  const int width = pic->width - 1;
+  const int height = pic->height - 1;
+  assert(width < WEBP_MAX_DIMENSION && height < WEBP_MAX_DIMENSION);
+
+  VP8LPutBits(bw, width, VP8L_IMAGE_SIZE_BITS);
+  VP8LPutBits(bw, height, VP8L_IMAGE_SIZE_BITS);
+  return !bw->error_;
+}
+
+static int WriteRealAlphaAndVersion(VP8LBitWriter* const bw, int has_alpha) {
+  VP8LPutBits(bw, has_alpha, 1);
+  VP8LPutBits(bw, VP8L_VERSION, VP8L_VERSION_BITS);
+  return !bw->error_;
+}
+
+static WebPEncodingError WriteImage(const WebPPicture* const pic,
+                                    VP8LBitWriter* const bw,
+                                    size_t* const coded_size) {
+  WebPEncodingError err = VP8_ENC_OK;
+  const uint8_t* const webpll_data = VP8LBitWriterFinish(bw);
+  const size_t webpll_size = VP8LBitWriterNumBytes(bw);
+  const size_t vp8l_size = VP8L_SIGNATURE_SIZE + webpll_size;
+  const size_t pad = vp8l_size & 1;
+  const size_t riff_size = TAG_SIZE + CHUNK_HEADER_SIZE + vp8l_size + pad;
+
+  err = WriteRiffHeader(pic, riff_size, vp8l_size);
+  if (err != VP8_ENC_OK) goto Error;
+
+  if (!pic->writer(webpll_data, webpll_size, pic)) {
+    err = VP8_ENC_ERROR_BAD_WRITE;
+    goto Error;
+  }
+
+  if (pad) {
+    const uint8_t pad_byte[1] = { 0 };
+    if (!pic->writer(pad_byte, 1, pic)) {
+      err = VP8_ENC_ERROR_BAD_WRITE;
+      goto Error;
+    }
+  }
+  *coded_size = CHUNK_HEADER_SIZE + riff_size;
+  return VP8_ENC_OK;
+
+ Error:
+  return err;
+}
+
+// -----------------------------------------------------------------------------
+
+// Allocates the memory for argb (W x H) buffer, 2 rows of context for
+// prediction and transform data.
+static WebPEncodingError AllocateTransformBuffer(VP8LEncoder* const enc,
+                                                 int width, int height) {
+  WebPEncodingError err = VP8_ENC_OK;
+  const int tile_size = 1 << enc->transform_bits_;
+  const uint64_t image_size = width * height;
+  const uint64_t argb_scratch_size = tile_size * width + width;
+  const int transform_data_size =
+      VP8LSubSampleSize(width, enc->transform_bits_) *
+      VP8LSubSampleSize(height, enc->transform_bits_);
+  const uint64_t total_size =
+      image_size + argb_scratch_size + (uint64_t)transform_data_size;
+  uint32_t* mem = (uint32_t*)WebPSafeMalloc(total_size, sizeof(*mem));
+  if (mem == NULL) {
+    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
+    goto Error;
+  }
+  enc->argb_ = mem;
+  mem += image_size;
+  enc->argb_scratch_ = mem;
+  mem += argb_scratch_size;
+  enc->transform_data_ = mem;
+  enc->current_width_ = width;
+
+ Error:
+  return err;
+}
+
+static void MapToPalette(const uint32_t palette[], int num_colors,
+                         uint32_t* const last_pix, int* const last_idx,
+                         const uint32_t* src, uint8_t* dst, int width) {
+  int x;
+  int prev_idx = *last_idx;
+  uint32_t prev_pix = *last_pix;
+  for (x = 0; x < width; ++x) {
+    const uint32_t pix = src[x];
+    if (pix != prev_pix) {
+      int i;
+      for (i = 0; i < num_colors; ++i) {
+        if (pix == palette[i]) {
+          prev_idx = i;
+          prev_pix = pix;
+          break;
+        }
+      }
+    }
+    dst[x] = prev_idx;
+  }
+  *last_idx = prev_idx;
+  *last_pix = prev_pix;
+}
+
+static void ApplyPalette(uint32_t* src, uint32_t* dst,
+                         uint32_t src_stride, uint32_t dst_stride,
+                         const uint32_t* palette, int palette_size,
+                         int width, int height, int xbits, uint8_t* row) {
+  int i, x, y;
+  int use_LUT = 1;
+  for (i = 0; i < palette_size; ++i) {
+    if ((palette[i] & 0xffff00ffu) != 0) {
+      use_LUT = 0;
+      break;
+    }
+  }
+
+  if (use_LUT) {
+    uint8_t inv_palette[MAX_PALETTE_SIZE] = { 0 };
+    for (i = 0; i < palette_size; ++i) {
+      const int color = (palette[i] >> 8) & 0xff;
+      inv_palette[color] = i;
+    }
+    for (y = 0; y < height; ++y) {
+      for (x = 0; x < width; ++x) {
+        const int color = (src[x] >> 8) & 0xff;
+        row[x] = inv_palette[color];
+      }
+      VP8LBundleColorMap(row, width, xbits, dst);
+      src += src_stride;
+      dst += dst_stride;
+    }
+  } else {
+    // Use 1 pixel cache for ARGB pixels.
+    uint32_t last_pix = palette[0];
+    int last_idx = 0;
+    for (y = 0; y < height; ++y) {
+      MapToPalette(palette, palette_size, &last_pix, &last_idx,
+                   src, row, width);
+      VP8LBundleColorMap(row, width, xbits, dst);
+      src += src_stride;
+      dst += dst_stride;
+    }
+  }
+}
+
+// Note: Expects "enc->palette_" to be set properly.
+// Also, "enc->palette_" will be modified after this call and should not be used
+// later.
+static WebPEncodingError EncodePalette(VP8LBitWriter* const bw,
+                                       VP8LEncoder* const enc) {
+  WebPEncodingError err = VP8_ENC_OK;
+  int i;
+  const WebPPicture* const pic = enc->pic_;
+  uint32_t* src = pic->argb;
+  uint32_t* dst;
+  const int width = pic->width;
+  const int height = pic->height;
+  uint32_t* const palette = enc->palette_;
+  const int palette_size = enc->palette_size_;
+  uint8_t* row = NULL;
+  int xbits;
+
+  // Replace each input pixel by corresponding palette index.
+  // This is done line by line.
+  if (palette_size <= 4) {
+    xbits = (palette_size <= 2) ? 3 : 2;
+  } else {
+    xbits = (palette_size <= 16) ? 1 : 0;
+  }
+
+  err = AllocateTransformBuffer(enc, VP8LSubSampleSize(width, xbits), height);
+  if (err != VP8_ENC_OK) goto Error;
+  dst = enc->argb_;
+
+  row = (uint8_t*)WebPSafeMalloc(width, sizeof(*row));
+  if (row == NULL) return VP8_ENC_ERROR_OUT_OF_MEMORY;
+
+  ApplyPalette(src, dst, pic->argb_stride, enc->current_width_,
+               palette, palette_size, width, height, xbits, row);
+
+  // Save palette to bitstream.
+  VP8LPutBits(bw, TRANSFORM_PRESENT, 1);
+  VP8LPutBits(bw, COLOR_INDEXING_TRANSFORM, 2);
+  assert(palette_size >= 1);
+  VP8LPutBits(bw, palette_size - 1, 8);
+  for (i = palette_size - 1; i >= 1; --i) {
+    palette[i] = VP8LSubPixels(palette[i], palette[i - 1]);
+  }
+  err = EncodeImageNoHuffman(bw, palette, &enc->hash_chain_, enc->refs_,
+                             palette_size, 1, 20 /* quality */);
+ Error:
+  WebPSafeFree(row);
+  return err;
+}
+
+// -----------------------------------------------------------------------------
+// VP8LEncoder
+
+static VP8LEncoder* VP8LEncoderNew(const WebPConfig* const config,
+                                   const WebPPicture* const picture) {
+  VP8LEncoder* const enc = (VP8LEncoder*)WebPSafeCalloc(1ULL, sizeof(*enc));
+  if (enc == NULL) {
+    WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY);
+    return NULL;
+  }
+  enc->config_ = config;
+  enc->pic_ = picture;
+
+  VP8LDspInit();
+
+  return enc;
+}
+
+static void VP8LEncoderDelete(VP8LEncoder* enc) {
+  if (enc != NULL) {
+    VP8LHashChainClear(&enc->hash_chain_);
+    VP8LBackwardRefsClear(&enc->refs_[0]);
+    VP8LBackwardRefsClear(&enc->refs_[1]);
+    WebPSafeFree(enc->argb_);
+    WebPSafeFree(enc);
+  }
+}
+
+// -----------------------------------------------------------------------------
+// Main call
+
+WebPEncodingError VP8LEncodeStream(const WebPConfig* const config,
+                                   const WebPPicture* const picture,
+                                   VP8LBitWriter* const bw, int use_cache) {
+  WebPEncodingError err = VP8_ENC_OK;
+  const int quality = (int)config->quality;
+  const int low_effort = (config->method == 0);
+  const int width = picture->width;
+  const int height = picture->height;
+  VP8LEncoder* const enc = VP8LEncoderNew(config, picture);
+  const size_t byte_position = VP8LBitWriterNumBytes(bw);
+  int use_near_lossless = 0;
+  int hdr_size = 0;
+  int data_size = 0;
+
+  if (enc == NULL) {
+    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
+    goto Error;
+  }
+
+  // ---------------------------------------------------------------------------
+  // Analyze image (entropy, num_palettes etc)
+
+  if (!AnalyzeAndInit(enc, config->image_hint)) {
+    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
+    goto Error;
+  }
+
+  // Apply near-lossless preprocessing.
+  use_near_lossless = !enc->use_palette_ && (config->near_lossless < 100);
+  if (use_near_lossless) {
+    if (!VP8ApplyNearLossless(width, height, picture->argb,
+                              config->near_lossless)) {
+      err = VP8_ENC_ERROR_OUT_OF_MEMORY;
+      goto Error;
+    }
+  }
+
+  if (enc->use_palette_) {
+    err = EncodePalette(bw, enc);
+    if (err != VP8_ENC_OK) goto Error;
+  }
+
+  // In case image is not packed.
+  if (enc->argb_ == NULL) {
+    int y;
+    err = AllocateTransformBuffer(enc, width, height);
+    if (err != VP8_ENC_OK) goto Error;
+    assert(enc->argb_ != NULL);
+    for (y = 0; y < height; ++y) {
+      memcpy(enc->argb_ + y * width,
+             picture->argb + y * picture->argb_stride,
+             width * sizeof(*enc->argb_));
+    }
+    enc->current_width_ = width;
+  }
+
+  // ---------------------------------------------------------------------------
+  // Apply transforms and write transform data.
+
+  if (enc->use_subtract_green_) {
+    ApplySubtractGreen(enc, enc->current_width_, height, bw);
+  }
+
+  if (enc->use_predict_) {
+    err = ApplyPredictFilter(enc, enc->current_width_, height, quality,
+                             low_effort, bw);
+    if (err != VP8_ENC_OK) goto Error;
+  }
+
+  if (enc->use_cross_color_) {
+    err = ApplyCrossColorFilter(enc, enc->current_width_, height, quality, bw);
+    if (err != VP8_ENC_OK) goto Error;
+  }
+
+  VP8LPutBits(bw, !TRANSFORM_PRESENT, 1);  // No more transforms.
+
+  // ---------------------------------------------------------------------------
+  // Encode and write the transformed image.
+  err = EncodeImageInternal(bw, enc->argb_, &enc->hash_chain_, enc->refs_,
+                            enc->current_width_, height, quality, low_effort,
+                            use_cache, &enc->cache_bits_, enc->histo_bits_,
+                            byte_position, &hdr_size, &data_size);
+  if (err != VP8_ENC_OK) goto Error;
+
+  if (picture->stats != NULL) {
+    WebPAuxStats* const stats = picture->stats;
+    stats->lossless_features = 0;
+    if (enc->use_predict_) stats->lossless_features |= 1;
+    if (enc->use_cross_color_) stats->lossless_features |= 2;
+    if (enc->use_subtract_green_) stats->lossless_features |= 4;
+    if (enc->use_palette_) stats->lossless_features |= 8;
+    stats->histogram_bits = enc->histo_bits_;
+    stats->transform_bits = enc->transform_bits_;
+    stats->cache_bits = enc->cache_bits_;
+    stats->palette_size = enc->palette_size_;
+    stats->lossless_size = (int)(VP8LBitWriterNumBytes(bw) - byte_position);
+    stats->lossless_hdr_size = hdr_size;
+    stats->lossless_data_size = data_size;
+  }
+
+ Error:
+  VP8LEncoderDelete(enc);
+  return err;
+}
+
+int VP8LEncodeImage(const WebPConfig* const config,
+                    const WebPPicture* const picture) {
+  int width, height;
+  int has_alpha;
+  size_t coded_size;
+  int percent = 0;
+  int initial_size;
+  WebPEncodingError err = VP8_ENC_OK;
+  VP8LBitWriter bw;
+
+  if (picture == NULL) return 0;
+
+  if (config == NULL || picture->argb == NULL) {
+    err = VP8_ENC_ERROR_NULL_PARAMETER;
+    WebPEncodingSetError(picture, err);
+    return 0;
+  }
+
+  width = picture->width;
+  height = picture->height;
+  // Initialize BitWriter with size corresponding to 16 bpp to photo images and
+  // 8 bpp for graphical images.
+  initial_size = (config->image_hint == WEBP_HINT_GRAPH) ?
+                 width * height : width * height * 2;
+  if (!VP8LBitWriterInit(&bw, initial_size)) {
+    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
+    goto Error;
+  }
+
+  if (!WebPReportProgress(picture, 1, &percent)) {
+ UserAbort:
+    err = VP8_ENC_ERROR_USER_ABORT;
+    goto Error;
+  }
+  // Reset stats (for pure lossless coding)
+  if (picture->stats != NULL) {
+    WebPAuxStats* const stats = picture->stats;
+    memset(stats, 0, sizeof(*stats));
+    stats->PSNR[0] = 99.f;
+    stats->PSNR[1] = 99.f;
+    stats->PSNR[2] = 99.f;
+    stats->PSNR[3] = 99.f;
+    stats->PSNR[4] = 99.f;
+  }
+
+  // Write image size.
+  if (!WriteImageSize(picture, &bw)) {
+    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
+    goto Error;
+  }
+
+  has_alpha = WebPPictureHasTransparency(picture);
+  // Write the non-trivial Alpha flag and lossless version.
+  if (!WriteRealAlphaAndVersion(&bw, has_alpha)) {
+    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
+    goto Error;
+  }
+
+  if (!WebPReportProgress(picture, 5, &percent)) goto UserAbort;
+
+  // Encode main image stream.
+  err = VP8LEncodeStream(config, picture, &bw, 1 /*use_cache*/);
+  if (err != VP8_ENC_OK) goto Error;
+
+  // TODO(skal): have a fine-grained progress report in VP8LEncodeStream().
+  if (!WebPReportProgress(picture, 90, &percent)) goto UserAbort;
+
+  // Finish the RIFF chunk.
+  err = WriteImage(picture, &bw, &coded_size);
+  if (err != VP8_ENC_OK) goto Error;
+
+  if (!WebPReportProgress(picture, 100, &percent)) goto UserAbort;
+
+  // Save size.
+  if (picture->stats != NULL) {
+    picture->stats->coded_size += (int)coded_size;
+    picture->stats->lossless_size = (int)coded_size;
+  }
+
+  if (picture->extra_info != NULL) {
+    const int mb_w = (width + 15) >> 4;
+    const int mb_h = (height + 15) >> 4;
+    memset(picture->extra_info, 0, mb_w * mb_h * sizeof(*picture->extra_info));
+  }
+
+ Error:
+  if (bw.error_) err = VP8_ENC_ERROR_OUT_OF_MEMORY;
+  VP8LBitWriterWipeOut(&bw);
+  if (err != VP8_ENC_OK) {
+    WebPEncodingSetError(picture, err);
+    return 0;
+  }
+  return 1;
+}
+
+//------------------------------------------------------------------------------
diff --git a/Source/LibWebP/src/enc/enc.webpenc.c b/Source/LibWebP/src/enc/enc.webpenc.c
new file mode 100644
index 0000000..312382a
--- /dev/null
+++ b/Source/LibWebP/src/enc/enc.webpenc.c
@@ -0,0 +1,379 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// WebP encoder: main entry point
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "./cost.h"
+#include "./vp8enci.h"
+#include "./vp8li.h"
+#include "../utils/utils.h"
+
+// #define PRINT_MEMORY_INFO
+
+#ifdef PRINT_MEMORY_INFO
+#include <stdio.h>
+#endif
+
+//------------------------------------------------------------------------------
+
+int WebPGetEncoderVersion(void) {
+  return (ENC_MAJ_VERSION << 16) | (ENC_MIN_VERSION << 8) | ENC_REV_VERSION;
+}
+
+//------------------------------------------------------------------------------
+// VP8Encoder
+//------------------------------------------------------------------------------
+
+static void ResetSegmentHeader(VP8Encoder* const enc) {
+  VP8SegmentHeader* const hdr = &enc->segment_hdr_;
+  hdr->num_segments_ = enc->config_->segments;
+  hdr->update_map_  = (hdr->num_segments_ > 1);
+  hdr->size_ = 0;
+}
+
+static void ResetFilterHeader(VP8Encoder* const enc) {
+  VP8FilterHeader* const hdr = &enc->filter_hdr_;
+  hdr->simple_ = 1;
+  hdr->level_ = 0;
+  hdr->sharpness_ = 0;
+  hdr->i4x4_lf_delta_ = 0;
+}
+
+static void ResetBoundaryPredictions(VP8Encoder* const enc) {
+  // init boundary values once for all
+  // Note: actually, initializing the preds_[] is only needed for intra4.
+  int i;
+  uint8_t* const top = enc->preds_ - enc->preds_w_;
+  uint8_t* const left = enc->preds_ - 1;
+  for (i = -1; i < 4 * enc->mb_w_; ++i) {
+    top[i] = B_DC_PRED;
+  }
+  for (i = 0; i < 4 * enc->mb_h_; ++i) {
+    left[i * enc->preds_w_] = B_DC_PRED;
+  }
+  enc->nz_[-1] = 0;   // constant
+}
+
+// Mapping from config->method_ to coding tools used.
+//-------------------+---+---+---+---+---+---+---+
+//   Method          | 0 | 1 | 2 | 3 |(4)| 5 | 6 |
+//-------------------+---+---+---+---+---+---+---+
+// fast probe        | x |   |   | x |   |   |   |
+//-------------------+---+---+---+---+---+---+---+
+// dynamic proba     | ~ | x | x | x | x | x | x |
+//-------------------+---+---+---+---+---+---+---+
+// fast mode analysis|   |   |   |   | x | x | x |
+//-------------------+---+---+---+---+---+---+---+
+// basic rd-opt      |   |   |   | x | x | x | x |
+//-------------------+---+---+---+---+---+---+---+
+// disto-score i4/16 |   |   | x |   |   |   |   |
+//-------------------+---+---+---+---+---+---+---+
+// rd-opt i4/16      |   |   | ~ | x | x | x | x |
+//-------------------+---+---+---+---+---+---+---+
+// token buffer (opt)|   |   |   | x | x | x | x |
+//-------------------+---+---+---+---+---+---+---+
+// Trellis           |   |   |   |   |   | x |Ful|
+//-------------------+---+---+---+---+---+---+---+
+// full-SNS          |   |   |   |   | x | x | x |
+//-------------------+---+---+---+---+---+---+---+
+
+static void MapConfigToTools(VP8Encoder* const enc) {
+  const WebPConfig* const config = enc->config_;
+  const int method = config->method;
+  const int limit = 100 - config->partition_limit;
+  enc->method_ = method;
+  enc->rd_opt_level_ = (method >= 6) ? RD_OPT_TRELLIS_ALL
+                     : (method >= 5) ? RD_OPT_TRELLIS
+                     : (method >= 3) ? RD_OPT_BASIC
+                     : RD_OPT_NONE;
+  enc->max_i4_header_bits_ =
+      256 * 16 * 16 *                 // upper bound: up to 16bit per 4x4 block
+      (limit * limit) / (100 * 100);  // ... modulated with a quadratic curve.
+
+  enc->thread_level_ = config->thread_level;
+
+  enc->do_search_ = (config->target_size > 0 || config->target_PSNR > 0);
+  if (!config->low_memory) {
+#if !defined(DISABLE_TOKEN_BUFFER)
+    enc->use_tokens_ = (enc->rd_opt_level_ >= RD_OPT_BASIC);  // need rd stats
+#endif
+    if (enc->use_tokens_) {
+      enc->num_parts_ = 1;   // doesn't work with multi-partition
+    }
+  }
+}
+
+// Memory scaling with dimensions:
+//  memory (bytes) ~= 2.25 * w + 0.0625 * w * h
+//
+// Typical memory footprint (614x440 picture)
+//              encoder: 22111
+//                 info: 4368
+//                preds: 17741
+//          top samples: 1263
+//             non-zero: 175
+//             lf-stats: 0
+//                total: 45658
+// Transient object sizes:
+//       VP8EncIterator: 3360
+//         VP8ModeScore: 872
+//       VP8SegmentInfo: 732
+//             VP8Proba: 18352
+//              LFStats: 2048
+// Picture size (yuv): 419328
+
+static VP8Encoder* InitVP8Encoder(const WebPConfig* const config,
+                                  WebPPicture* const picture) {
+  const int use_filter =
+      (config->filter_strength > 0) || (config->autofilter > 0);
+  const int mb_w = (picture->width + 15) >> 4;
+  const int mb_h = (picture->height + 15) >> 4;
+  const int preds_w = 4 * mb_w + 1;
+  const int preds_h = 4 * mb_h + 1;
+  const size_t preds_size = preds_w * preds_h * sizeof(uint8_t);
+  const int top_stride = mb_w * 16;
+  const size_t nz_size = (mb_w + 1) * sizeof(uint32_t) + ALIGN_CST;
+  const size_t info_size = mb_w * mb_h * sizeof(VP8MBInfo);
+  const size_t samples_size = 2 * top_stride * sizeof(uint8_t)  // top-luma/u/v
+                            + ALIGN_CST;                        // align all
+  const size_t lf_stats_size =
+      config->autofilter ? sizeof(LFStats) + ALIGN_CST : 0;
+  VP8Encoder* enc;
+  uint8_t* mem;
+  const uint64_t size = (uint64_t)sizeof(VP8Encoder)   // main struct
+                      + ALIGN_CST                      // cache alignment
+                      + info_size                      // modes info
+                      + preds_size                     // prediction modes
+                      + samples_size                   // top/left samples
+                      + nz_size                        // coeff context bits
+                      + lf_stats_size;                 // autofilter stats
+
+#ifdef PRINT_MEMORY_INFO
+  printf("===================================\n");
+  printf("Memory used:\n"
+         "             encoder: %ld\n"
+         "                info: %ld\n"
+         "               preds: %ld\n"
+         "         top samples: %ld\n"
+         "            non-zero: %ld\n"
+         "            lf-stats: %ld\n"
+         "               total: %ld\n",
+         sizeof(VP8Encoder) + ALIGN_CST, info_size,
+         preds_size, samples_size, nz_size, lf_stats_size, size);
+  printf("Transient object sizes:\n"
+         "      VP8EncIterator: %ld\n"
+         "        VP8ModeScore: %ld\n"
+         "      VP8SegmentInfo: %ld\n"
+         "            VP8Proba: %ld\n"
+         "             LFStats: %ld\n",
+         sizeof(VP8EncIterator), sizeof(VP8ModeScore),
+         sizeof(VP8SegmentInfo), sizeof(VP8Proba),
+         sizeof(LFStats));
+  printf("Picture size (yuv): %ld\n",
+         mb_w * mb_h * 384 * sizeof(uint8_t));
+  printf("===================================\n");
+#endif
+  mem = (uint8_t*)WebPSafeMalloc(size, sizeof(*mem));
+  if (mem == NULL) {
+    WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY);
+    return NULL;
+  }
+  enc = (VP8Encoder*)mem;
+  mem = (uint8_t*)DO_ALIGN(mem + sizeof(*enc));
+  memset(enc, 0, sizeof(*enc));
+  enc->num_parts_ = 1 << config->partitions;
+  enc->mb_w_ = mb_w;
+  enc->mb_h_ = mb_h;
+  enc->preds_w_ = preds_w;
+  enc->mb_info_ = (VP8MBInfo*)mem;
+  mem += info_size;
+  enc->preds_ = ((uint8_t*)mem) + 1 + enc->preds_w_;
+  mem += preds_w * preds_h * sizeof(uint8_t);
+  enc->nz_ = 1 + (uint32_t*)DO_ALIGN(mem);
+  mem += nz_size;
+  enc->lf_stats_ = lf_stats_size ? (LFStats*)DO_ALIGN(mem) : NULL;
+  mem += lf_stats_size;
+
+  // top samples (all 16-aligned)
+  mem = (uint8_t*)DO_ALIGN(mem);
+  enc->y_top_ = (uint8_t*)mem;
+  enc->uv_top_ = enc->y_top_ + top_stride;
+  mem += 2 * top_stride;
+  assert(mem <= (uint8_t*)enc + size);
+
+  enc->config_ = config;
+  enc->profile_ = use_filter ? ((config->filter_type == 1) ? 0 : 1) : 2;
+  enc->pic_ = picture;
+  enc->percent_ = 0;
+
+  MapConfigToTools(enc);
+  VP8EncDspInit();
+  VP8DefaultProbas(enc);
+  ResetSegmentHeader(enc);
+  ResetFilterHeader(enc);
+  ResetBoundaryPredictions(enc);
+  VP8EncDspCostInit();
+  VP8EncInitAlpha(enc);
+
+  // lower quality means smaller output -> we modulate a little the page
+  // size based on quality. This is just a crude 1rst-order prediction.
+  {
+    const float scale = 1.f + config->quality * 5.f / 100.f;  // in [1,6]
+    VP8TBufferInit(&enc->tokens_, (int)(mb_w * mb_h * 4 * scale));
+  }
+  return enc;
+}
+
+static int DeleteVP8Encoder(VP8Encoder* enc) {
+  int ok = 1;
+  if (enc != NULL) {
+    ok = VP8EncDeleteAlpha(enc);
+    VP8TBufferClear(&enc->tokens_);
+    WebPSafeFree(enc);
+  }
+  return ok;
+}
+
+//------------------------------------------------------------------------------
+
+static double GetPSNR(uint64_t err, uint64_t size) {
+  return (err > 0 && size > 0) ? 10. * log10(255. * 255. * size / err) : 99.;
+}
+
+static void FinalizePSNR(const VP8Encoder* const enc) {
+  WebPAuxStats* stats = enc->pic_->stats;
+  const uint64_t size = enc->sse_count_;
+  const uint64_t* const sse = enc->sse_;
+  stats->PSNR[0] = (float)GetPSNR(sse[0], size);
+  stats->PSNR[1] = (float)GetPSNR(sse[1], size / 4);
+  stats->PSNR[2] = (float)GetPSNR(sse[2], size / 4);
+  stats->PSNR[3] = (float)GetPSNR(sse[0] + sse[1] + sse[2], size * 3 / 2);
+  stats->PSNR[4] = (float)GetPSNR(sse[3], size);
+}
+
+static void StoreStats(VP8Encoder* const enc) {
+  WebPAuxStats* const stats = enc->pic_->stats;
+  if (stats != NULL) {
+    int i, s;
+    for (i = 0; i < NUM_MB_SEGMENTS; ++i) {
+      stats->segment_level[i] = enc->dqm_[i].fstrength_;
+      stats->segment_quant[i] = enc->dqm_[i].quant_;
+      for (s = 0; s <= 2; ++s) {
+        stats->residual_bytes[s][i] = enc->residual_bytes_[s][i];
+      }
+    }
+    FinalizePSNR(enc);
+    stats->coded_size = enc->coded_size_;
+    for (i = 0; i < 3; ++i) {
+      stats->block_count[i] = enc->block_count_[i];
+    }
+  }
+  WebPReportProgress(enc->pic_, 100, &enc->percent_);  // done!
+}
+
+int WebPEncodingSetError(const WebPPicture* const pic,
+                         WebPEncodingError error) {
+  assert((int)error < VP8_ENC_ERROR_LAST);
+  assert((int)error >= VP8_ENC_OK);
+  ((WebPPicture*)pic)->error_code = error;
+  return 0;
+}
+
+int WebPReportProgress(const WebPPicture* const pic,
+                       int percent, int* const percent_store) {
+  if (percent_store != NULL && percent != *percent_store) {
+    *percent_store = percent;
+    if (pic->progress_hook && !pic->progress_hook(percent, pic)) {
+      // user abort requested
+      WebPEncodingSetError(pic, VP8_ENC_ERROR_USER_ABORT);
+      return 0;
+    }
+  }
+  return 1;  // ok
+}
+//------------------------------------------------------------------------------
+
+int WebPEncode(const WebPConfig* config, WebPPicture* pic) {
+  int ok = 0;
+
+  if (pic == NULL)
+    return 0;
+  WebPEncodingSetError(pic, VP8_ENC_OK);  // all ok so far
+  if (config == NULL)  // bad params
+    return WebPEncodingSetError(pic, VP8_ENC_ERROR_NULL_PARAMETER);
+  if (!WebPValidateConfig(config))
+    return WebPEncodingSetError(pic, VP8_ENC_ERROR_INVALID_CONFIGURATION);
+  if (pic->width <= 0 || pic->height <= 0)
+    return WebPEncodingSetError(pic, VP8_ENC_ERROR_BAD_DIMENSION);
+  if (pic->width > WEBP_MAX_DIMENSION || pic->height > WEBP_MAX_DIMENSION)
+    return WebPEncodingSetError(pic, VP8_ENC_ERROR_BAD_DIMENSION);
+
+  if (pic->stats != NULL) memset(pic->stats, 0, sizeof(*pic->stats));
+
+  if (!config->lossless) {
+    VP8Encoder* enc = NULL;
+    if (pic->use_argb || pic->y == NULL || pic->u == NULL || pic->v == NULL) {
+      // Make sure we have YUVA samples.
+      if (config->preprocessing & 4) {
+        if (!WebPPictureSmartARGBToYUVA(pic)) {
+          return 0;
+        }
+      } else {
+        float dithering = 0.f;
+        if (config->preprocessing & 2) {
+          const float x = config->quality / 100.f;
+          const float x2 = x * x;
+          // slowly decreasing from max dithering at low quality (q->0)
+          // to 0.5 dithering amplitude at high quality (q->100)
+          dithering = 1.0f + (0.5f - 1.0f) * x2 * x2;
+        }
+        if (!WebPPictureARGBToYUVADithered(pic, WEBP_YUV420, dithering)) {
+          return 0;
+        }
+      }
+    }
+
+    enc = InitVP8Encoder(config, pic);
+    if (enc == NULL) return 0;  // pic->error is already set.
+    // Note: each of the tasks below account for 20% in the progress report.
+    ok = VP8EncAnalyze(enc);
+
+    // Analysis is done, proceed to actual coding.
+    ok = ok && VP8EncStartAlpha(enc);   // possibly done in parallel
+    if (!enc->use_tokens_) {
+      ok = ok && VP8EncLoop(enc);
+    } else {
+      ok = ok && VP8EncTokenLoop(enc);
+    }
+    ok = ok && VP8EncFinishAlpha(enc);
+
+    ok = ok && VP8EncWrite(enc);
+    StoreStats(enc);
+    if (!ok) {
+      VP8EncFreeBitWriters(enc);
+    }
+    ok &= DeleteVP8Encoder(enc);  // must always be called, even if !ok
+  } else {
+    // Make sure we have ARGB samples.
+    if (pic->argb == NULL && !WebPPictureYUVAToARGB(pic)) {
+      return 0;
+    }
+
+    ok = VP8LEncodeImage(config, pic);  // Sets pic->error in case of problem.
+  }
+
+  return ok;
+}
diff --git a/Source/LibWebP/src/enc/histogram.h b/Source/LibWebP/src/enc/histogram.h
new file mode 100644
index 0000000..2812656
--- /dev/null
+++ b/Source/LibWebP/src/enc/histogram.h
@@ -0,0 +1,114 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Author: Jyrki Alakuijala (jyrki at google.com)
+//
+// Models the histograms of literal and distance codes.
+
+#ifndef WEBP_ENC_HISTOGRAM_H_
+#define WEBP_ENC_HISTOGRAM_H_
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "./backward_references.h"
+#include "../webp/format_constants.h"
+#include "../webp/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// A simple container for histograms of data.
+typedef struct {
+  // literal_ contains green literal, palette-code and
+  // copy-length-prefix histogram
+  uint32_t* literal_;         // Pointer to the allocated buffer for literal.
+  uint32_t red_[NUM_LITERAL_CODES];
+  uint32_t blue_[NUM_LITERAL_CODES];
+  uint32_t alpha_[NUM_LITERAL_CODES];
+  // Backward reference prefix-code histogram.
+  uint32_t distance_[NUM_DISTANCE_CODES];
+  int palette_code_bits_;
+  uint32_t trivial_symbol_;  // True, if histograms for Red, Blue & Alpha
+                             // literal symbols are single valued.
+  double bit_cost_;          // cached value of bit cost.
+  double literal_cost_;      // Cached values of dominant entropy costs:
+  double red_cost_;          // literal, red & blue.
+  double blue_cost_;
+} VP8LHistogram;
+
+// Collection of histograms with fixed capacity, allocated as one
+// big memory chunk. Can be destroyed by calling WebPSafeFree().
+typedef struct {
+  int size;         // number of slots currently in use
+  int max_size;     // maximum capacity
+  VP8LHistogram** histograms;
+} VP8LHistogramSet;
+
+// Create the histogram.
+//
+// The input data is the PixOrCopy data, which models the literals, stop
+// codes and backward references (both distances and lengths).  Also: if
+// palette_code_bits is >= 0, initialize the histogram with this value.
+void VP8LHistogramCreate(VP8LHistogram* const p,
+                         const VP8LBackwardRefs* const refs,
+                         int palette_code_bits);
+
+// Return the size of the histogram for a given palette_code_bits.
+int VP8LGetHistogramSize(int palette_code_bits);
+
+// Set the palette_code_bits and reset the stats.
+void VP8LHistogramInit(VP8LHistogram* const p, int palette_code_bits);
+
+// Collect all the references into a histogram (without reset)
+void VP8LHistogramStoreRefs(const VP8LBackwardRefs* const refs,
+                            VP8LHistogram* const histo);
+
+// Free the memory allocated for the histogram.
+void VP8LFreeHistogram(VP8LHistogram* const histo);
+
+// Free the memory allocated for the histogram set.
+void VP8LFreeHistogramSet(VP8LHistogramSet* const histo);
+
+// Allocate an array of pointer to histograms, allocated and initialized
+// using 'cache_bits'. Return NULL in case of memory error.
+VP8LHistogramSet* VP8LAllocateHistogramSet(int size, int cache_bits);
+
+// Allocate and initialize histogram object with specified 'cache_bits'.
+// Returns NULL in case of memory error.
+// Special case of VP8LAllocateHistogramSet, with size equals 1.
+VP8LHistogram* VP8LAllocateHistogram(int cache_bits);
+
+// Accumulate a token 'v' into a histogram.
+void VP8LHistogramAddSinglePixOrCopy(VP8LHistogram* const histo,
+                                     const PixOrCopy* const v);
+
+static WEBP_INLINE int VP8LHistogramNumCodes(int palette_code_bits) {
+  return NUM_LITERAL_CODES + NUM_LENGTH_CODES +
+      ((palette_code_bits > 0) ? (1 << palette_code_bits) : 0);
+}
+
+// Builds the histogram image.
+int VP8LGetHistoImageSymbols(int xsize, int ysize,
+                             const VP8LBackwardRefs* const refs,
+                             int quality, int low_effort,
+                             int histogram_bits, int cache_bits,
+                             VP8LHistogramSet* const image_in,
+                             VP8LHistogramSet* const tmp_histos,
+                             uint16_t* const histogram_symbols);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // WEBP_ENC_HISTOGRAM_H_
diff --git a/Source/LibWebP/src/enc/vp8enci.h b/Source/LibWebP/src/enc/vp8enci.h
new file mode 100644
index 0000000..4e43e08
--- /dev/null
+++ b/Source/LibWebP/src/enc/vp8enci.h
@@ -0,0 +1,551 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+//   WebP encoder: internal header.
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#ifndef WEBP_ENC_VP8ENCI_H_
+#define WEBP_ENC_VP8ENCI_H_
+
+#include <string.h>     // for memcpy()
+#include "../webp/encode.h"
+#include "../dsp/dsp.h"
+#include "../utils/bit_writer.h"
+#include "../utils/thread.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//------------------------------------------------------------------------------
+// Various defines and enums
+
+// version numbers
+#define ENC_MAJ_VERSION 0
+#define ENC_MIN_VERSION 4
+#define ENC_REV_VERSION 2
+
+// intra prediction modes
+enum { B_DC_PRED = 0,   // 4x4 modes
+       B_TM_PRED = 1,
+       B_VE_PRED = 2,
+       B_HE_PRED = 3,
+       B_RD_PRED = 4,
+       B_VR_PRED = 5,
+       B_LD_PRED = 6,
+       B_VL_PRED = 7,
+       B_HD_PRED = 8,
+       B_HU_PRED = 9,
+       NUM_BMODES = B_HU_PRED + 1 - B_DC_PRED,  // = 10
+
+       // Luma16 or UV modes
+       DC_PRED = B_DC_PRED, V_PRED = B_VE_PRED,
+       H_PRED = B_HE_PRED, TM_PRED = B_TM_PRED,
+       NUM_PRED_MODES = 4
+     };
+
+enum { NUM_MB_SEGMENTS = 4,
+       MAX_NUM_PARTITIONS = 8,
+       NUM_TYPES = 4,   // 0: i16-AC,  1: i16-DC,  2:chroma-AC,  3:i4-AC
+       NUM_BANDS = 8,
+       NUM_CTX = 3,
+       NUM_PROBAS = 11,
+       MAX_LF_LEVELS = 64,       // Maximum loop filter level
+       MAX_VARIABLE_LEVEL = 67,  // last (inclusive) level with variable cost
+       MAX_LEVEL = 2047          // max level (note: max codable is 2047 + 67)
+     };
+
+typedef enum {   // Rate-distortion optimization levels
+  RD_OPT_NONE        = 0,  // no rd-opt
+  RD_OPT_BASIC       = 1,  // basic scoring (no trellis)
+  RD_OPT_TRELLIS     = 2,  // perform trellis-quant on the final decision only
+  RD_OPT_TRELLIS_ALL = 3   // trellis-quant for every scoring (much slower)
+} VP8RDLevel;
+
+// YUV-cache parameters. Cache is 32-bytes wide (= one cacheline).
+// The original or reconstructed samples can be accessed using VP8Scan[].
+// The predicted blocks can be accessed using offsets to yuv_p_ and
+// the arrays VP8*ModeOffsets[].
+// * YUV Samples area (yuv_in_/yuv_out_/yuv_out2_)
+//   (see VP8Scan[] for accessing the blocks, along with Y_OFF/U_OFF/V_OFF):
+//         +----+----+
+//  Y_OFF  |YYYY|UUVV|
+//  U_OFF  |YYYY|UUVV|
+//  V_OFF  |YYYY|....| <- 25% wasted U/V area
+//         |YYYY|....|
+//         +----+----+
+// * Prediction area ('yuv_p_', size = PRED_SIZE)
+//   Intra16 predictions (16x16 block each, two per row):
+//         |I16DC16|I16TM16|
+//         |I16VE16|I16HE16|
+//   Chroma U/V predictions (16x8 block each, two per row):
+//         |C8DC8|C8TM8|
+//         |C8VE8|C8HE8|
+//   Intra 4x4 predictions (4x4 block each)
+//         |I4DC4 I4TM4 I4VE4 I4HE4|I4RD4 I4VR4 I4LD4 I4VL4|
+//         |I4HD4 I4HU4 I4TMP .....|.......................| <- ~31% wasted
+#define YUV_SIZE (BPS * 16)
+#define PRED_SIZE (32 * BPS + 16 * BPS + 8 * BPS)   // I16+Chroma+I4 preds
+#define Y_OFF    (0)
+#define U_OFF    (16)
+#define V_OFF    (16 + 8)
+#define ALIGN_CST 15
+#define DO_ALIGN(PTR) ((uintptr_t)((PTR) + ALIGN_CST) & ~ALIGN_CST)
+
+extern const int VP8Scan[16];           // in quant.c
+extern const int VP8UVModeOffsets[4];   // in analyze.c
+extern const int VP8I16ModeOffsets[4];
+extern const int VP8I4ModeOffsets[NUM_BMODES];
+
+// Layout of prediction blocks
+// intra 16x16
+#define I16DC16 (0 * 16 * BPS)
+#define I16TM16 (I16DC16 + 16)
+#define I16VE16 (1 * 16 * BPS)
+#define I16HE16 (I16VE16 + 16)
+// chroma 8x8, two U/V blocks side by side (hence: 16x8 each)
+#define C8DC8 (2 * 16 * BPS)
+#define C8TM8 (C8DC8 + 1 * 16)
+#define C8VE8 (2 * 16 * BPS + 8 * BPS)
+#define C8HE8 (C8VE8 + 1 * 16)
+// intra 4x4
+#define I4DC4 (3 * 16 * BPS +  0)
+#define I4TM4 (I4DC4 +  4)
+#define I4VE4 (I4DC4 +  8)
+#define I4HE4 (I4DC4 + 12)
+#define I4RD4 (I4DC4 + 16)
+#define I4VR4 (I4DC4 + 20)
+#define I4LD4 (I4DC4 + 24)
+#define I4VL4 (I4DC4 + 28)
+#define I4HD4 (3 * 16 * BPS + 4 * BPS)
+#define I4HU4 (I4HD4 + 4)
+#define I4TMP (I4HD4 + 8)
+
+typedef int64_t score_t;     // type used for scores, rate, distortion
+// Note that MAX_COST is not the maximum allowed by sizeof(score_t),
+// in order to allow overflowing computations.
+#define MAX_COST ((score_t)0x7fffffffffffffLL)
+
+#define QFIX 17
+#define BIAS(b)  ((b) << (QFIX - 8))
+// Fun fact: this is the _only_ line where we're actually being lossy and
+// discarding bits.
+static WEBP_INLINE int QUANTDIV(uint32_t n, uint32_t iQ, uint32_t B) {
+  return (int)((n * iQ + B) >> QFIX);
+}
+
+// Uncomment the following to remove token-buffer code:
+// #define DISABLE_TOKEN_BUFFER
+
+//------------------------------------------------------------------------------
+// Headers
+
+typedef uint32_t proba_t;   // 16b + 16b
+typedef uint8_t ProbaArray[NUM_CTX][NUM_PROBAS];
+typedef proba_t StatsArray[NUM_CTX][NUM_PROBAS];
+typedef uint16_t CostArray[NUM_CTX][MAX_VARIABLE_LEVEL + 1];
+typedef const uint16_t* (*CostArrayPtr)[NUM_CTX];   // for easy casting
+typedef const uint16_t* CostArrayMap[16][NUM_CTX];
+typedef double LFStats[NUM_MB_SEGMENTS][MAX_LF_LEVELS];  // filter stats
+
+typedef struct VP8Encoder VP8Encoder;
+
+// segment features
+typedef struct {
+  int num_segments_;      // Actual number of segments. 1 segment only = unused.
+  int update_map_;        // whether to update the segment map or not.
+                          // must be 0 if there's only 1 segment.
+  int size_;              // bit-cost for transmitting the segment map
+} VP8SegmentHeader;
+
+// Struct collecting all frame-persistent probabilities.
+typedef struct {
+  uint8_t segments_[3];     // probabilities for segment tree
+  uint8_t skip_proba_;      // final probability of being skipped.
+  ProbaArray coeffs_[NUM_TYPES][NUM_BANDS];      // 1056 bytes
+  StatsArray stats_[NUM_TYPES][NUM_BANDS];       // 4224 bytes
+  CostArray level_cost_[NUM_TYPES][NUM_BANDS];   // 13056 bytes
+  CostArrayMap remapped_costs_[NUM_TYPES];       // 1536 bytes
+  int dirty_;               // if true, need to call VP8CalculateLevelCosts()
+  int use_skip_proba_;      // Note: we always use skip_proba for now.
+  int nb_skip_;             // number of skipped blocks
+} VP8Proba;
+
+// Filter parameters. Not actually used in the code (we don't perform
+// the in-loop filtering), but filled from user's config
+typedef struct {
+  int simple_;             // filtering type: 0=complex, 1=simple
+  int level_;              // base filter level [0..63]
+  int sharpness_;          // [0..7]
+  int i4x4_lf_delta_;      // delta filter level for i4x4 relative to i16x16
+} VP8FilterHeader;
+
+//------------------------------------------------------------------------------
+// Informations about the macroblocks.
+
+typedef struct {
+  // block type
+  unsigned int type_:2;     // 0=i4x4, 1=i16x16
+  unsigned int uv_mode_:2;
+  unsigned int skip_:1;
+  unsigned int segment_:2;
+  uint8_t alpha_;      // quantization-susceptibility
+} VP8MBInfo;
+
+typedef struct VP8Matrix {
+  uint16_t q_[16];        // quantizer steps
+  uint16_t iq_[16];       // reciprocals, fixed point.
+  uint32_t bias_[16];     // rounding bias
+  uint32_t zthresh_[16];  // value below which a coefficient is zeroed
+  uint16_t sharpen_[16];  // frequency boosters for slight sharpening
+} VP8Matrix;
+
+typedef struct {
+  VP8Matrix y1_, y2_, uv_;  // quantization matrices
+  int alpha_;      // quant-susceptibility, range [-127,127]. Zero is neutral.
+                   // Lower values indicate a lower risk of blurriness.
+  int beta_;       // filter-susceptibility, range [0,255].
+  int quant_;      // final segment quantizer.
+  int fstrength_;  // final in-loop filtering strength
+  int max_edge_;   // max edge delta (for filtering strength)
+  int min_disto_;  // minimum distortion required to trigger filtering record
+  // reactivities
+  int lambda_i16_, lambda_i4_, lambda_uv_;
+  int lambda_mode_, lambda_trellis_, tlambda_;
+  int lambda_trellis_i16_, lambda_trellis_i4_, lambda_trellis_uv_;
+} VP8SegmentInfo;
+
+// Handy transient struct to accumulate score and info during RD-optimization
+// and mode evaluation.
+typedef struct {
+  score_t D, SD;              // Distortion, spectral distortion
+  score_t H, R, score;        // header bits, rate, score.
+  int16_t y_dc_levels[16];    // Quantized levels for luma-DC, luma-AC, chroma.
+  int16_t y_ac_levels[16][16];
+  int16_t uv_levels[4 + 4][16];
+  int mode_i16;               // mode number for intra16 prediction
+  uint8_t modes_i4[16];       // mode numbers for intra4 predictions
+  int mode_uv;                // mode number of chroma prediction
+  uint32_t nz;                // non-zero blocks
+} VP8ModeScore;
+
+// Iterator structure to iterate through macroblocks, pointing to the
+// right neighbouring data (samples, predictions, contexts, ...)
+typedef struct {
+  int x_, y_;                      // current macroblock
+  int y_stride_, uv_stride_;       // respective strides
+  uint8_t*      yuv_in_;           // input samples
+  uint8_t*      yuv_out_;          // output samples
+  uint8_t*      yuv_out2_;         // secondary buffer swapped with yuv_out_.
+  uint8_t*      yuv_p_;            // scratch buffer for prediction
+  VP8Encoder*   enc_;              // back-pointer
+  VP8MBInfo*    mb_;               // current macroblock
+  VP8BitWriter* bw_;               // current bit-writer
+  uint8_t*      preds_;            // intra mode predictors (4x4 blocks)
+  uint32_t*     nz_;               // non-zero pattern
+  uint8_t       i4_boundary_[37];  // 32+5 boundary samples needed by intra4x4
+  uint8_t*      i4_top_;           // pointer to the current top boundary sample
+  int           i4_;               // current intra4x4 mode being tested
+  int           top_nz_[9];        // top-non-zero context.
+  int           left_nz_[9];       // left-non-zero. left_nz[8] is independent.
+  uint64_t      bit_count_[4][3];  // bit counters for coded levels.
+  uint64_t      luma_bits_;        // macroblock bit-cost for luma
+  uint64_t      uv_bits_;          // macroblock bit-cost for chroma
+  LFStats*      lf_stats_;         // filter stats (borrowed from enc_)
+  int           do_trellis_;       // if true, perform extra level optimisation
+  int           count_down_;       // number of mb still to be processed
+  int           count_down0_;      // starting counter value (for progress)
+  int           percent0_;         // saved initial progress percent
+
+  uint8_t* y_left_;    // left luma samples (addressable from index -1 to 15).
+  uint8_t* u_left_;    // left u samples (addressable from index -1 to 7)
+  uint8_t* v_left_;    // left v samples (addressable from index -1 to 7)
+
+  uint8_t* y_top_;     // top luma samples at position 'x_'
+  uint8_t* uv_top_;    // top u/v samples at position 'x_', packed as 16 bytes
+
+  // memory for storing y/u/v_left_ and yuv_in_/out_*
+  uint8_t yuv_left_mem_[17 + 16 + 16 + 8 + ALIGN_CST];     // memory for *_left_
+  uint8_t yuv_mem_[3 * YUV_SIZE + PRED_SIZE + ALIGN_CST];  // memory for yuv_*
+} VP8EncIterator;
+
+  // in iterator.c
+// must be called first
+void VP8IteratorInit(VP8Encoder* const enc, VP8EncIterator* const it);
+// restart a scan
+void VP8IteratorReset(VP8EncIterator* const it);
+// reset iterator position to row 'y'
+void VP8IteratorSetRow(VP8EncIterator* const it, int y);
+// set count down (=number of iterations to go)
+void VP8IteratorSetCountDown(VP8EncIterator* const it, int count_down);
+// return true if iteration is finished
+int VP8IteratorIsDone(const VP8EncIterator* const it);
+// Import uncompressed samples from source.
+// If tmp_32 is not NULL, import boundary samples too.
+// tmp_32 is a 32-bytes scratch buffer that must be aligned in memory.
+void VP8IteratorImport(VP8EncIterator* const it, uint8_t* tmp_32);
+// export decimated samples
+void VP8IteratorExport(const VP8EncIterator* const it);
+// go to next macroblock. Returns false if not finished.
+int VP8IteratorNext(VP8EncIterator* const it);
+// save the yuv_out_ boundary values to top_/left_ arrays for next iterations.
+void VP8IteratorSaveBoundary(VP8EncIterator* const it);
+// Report progression based on macroblock rows. Return 0 for user-abort request.
+int VP8IteratorProgress(const VP8EncIterator* const it,
+                        int final_delta_percent);
+// Intra4x4 iterations
+void VP8IteratorStartI4(VP8EncIterator* const it);
+// returns true if not done.
+int VP8IteratorRotateI4(VP8EncIterator* const it,
+                        const uint8_t* const yuv_out);
+
+// Non-zero context setup/teardown
+void VP8IteratorNzToBytes(VP8EncIterator* const it);
+void VP8IteratorBytesToNz(VP8EncIterator* const it);
+
+// Helper functions to set mode properties
+void VP8SetIntra16Mode(const VP8EncIterator* const it, int mode);
+void VP8SetIntra4Mode(const VP8EncIterator* const it, const uint8_t* modes);
+void VP8SetIntraUVMode(const VP8EncIterator* const it, int mode);
+void VP8SetSkip(const VP8EncIterator* const it, int skip);
+void VP8SetSegment(const VP8EncIterator* const it, int segment);
+
+//------------------------------------------------------------------------------
+// Paginated token buffer
+
+typedef struct VP8Tokens VP8Tokens;  // struct details in token.c
+
+typedef struct {
+#if !defined(DISABLE_TOKEN_BUFFER)
+  VP8Tokens* pages_;        // first page
+  VP8Tokens** last_page_;   // last page
+  uint16_t* tokens_;        // set to (*last_page_)->tokens_
+  int left_;                // how many free tokens left before the page is full
+  int page_size_;           // number of tokens per page
+#endif
+  int error_;         // true in case of malloc error
+} VP8TBuffer;
+
+// initialize an empty buffer
+void VP8TBufferInit(VP8TBuffer* const b, int page_size);
+void VP8TBufferClear(VP8TBuffer* const b);   // de-allocate pages memory
+
+#if !defined(DISABLE_TOKEN_BUFFER)
+
+// Finalizes bitstream when probabilities are known.
+// Deletes the allocated token memory if final_pass is true.
+int VP8EmitTokens(VP8TBuffer* const b, VP8BitWriter* const bw,
+                  const uint8_t* const probas, int final_pass);
+
+// record the coding of coefficients without knowing the probabilities yet
+int VP8RecordCoeffTokens(const int ctx, const int coeff_type,
+                         int first, int last,
+                         const int16_t* const coeffs,
+                         VP8TBuffer* const tokens);
+
+// Estimate the final coded size given a set of 'probas'.
+size_t VP8EstimateTokenSize(VP8TBuffer* const b, const uint8_t* const probas);
+
+// unused for now
+void VP8TokenToStats(const VP8TBuffer* const b, proba_t* const stats);
+
+#endif  // !DISABLE_TOKEN_BUFFER
+
+//------------------------------------------------------------------------------
+// VP8Encoder
+
+struct VP8Encoder {
+  const WebPConfig* config_;    // user configuration and parameters
+  WebPPicture* pic_;            // input / output picture
+
+  // headers
+  VP8FilterHeader   filter_hdr_;     // filtering information
+  VP8SegmentHeader  segment_hdr_;    // segment information
+
+  int profile_;                      // VP8's profile, deduced from Config.
+
+  // dimension, in macroblock units.
+  int mb_w_, mb_h_;
+  int preds_w_;   // stride of the *preds_ prediction plane (=4*mb_w + 1)
+
+  // number of partitions (1, 2, 4 or 8 = MAX_NUM_PARTITIONS)
+  int num_parts_;
+
+  // per-partition boolean decoders.
+  VP8BitWriter bw_;                         // part0
+  VP8BitWriter parts_[MAX_NUM_PARTITIONS];  // token partitions
+  VP8TBuffer tokens_;                       // token buffer
+
+  int percent_;                             // for progress
+
+  // transparency blob
+  int has_alpha_;
+  uint8_t* alpha_data_;       // non-NULL if transparency is present
+  uint32_t alpha_data_size_;
+  WebPWorker alpha_worker_;
+
+  // quantization info (one set of DC/AC dequant factor per segment)
+  VP8SegmentInfo dqm_[NUM_MB_SEGMENTS];
+  int base_quant_;                 // nominal quantizer value. Only used
+                                   // for relative coding of segments' quant.
+  int alpha_;                      // global susceptibility (<=> complexity)
+  int uv_alpha_;                   // U/V quantization susceptibility
+  // global offset of quantizers, shared by all segments
+  int dq_y1_dc_;
+  int dq_y2_dc_, dq_y2_ac_;
+  int dq_uv_dc_, dq_uv_ac_;
+
+  // probabilities and statistics
+  VP8Proba proba_;
+  uint64_t sse_[4];        // sum of Y/U/V/A squared errors for all macroblocks
+  uint64_t sse_count_;     // pixel count for the sse_[] stats
+  int      coded_size_;
+  int      residual_bytes_[3][4];
+  int      block_count_[3];
+
+  // quality/speed settings
+  int method_;               // 0=fastest, 6=best/slowest.
+  VP8RDLevel rd_opt_level_;  // Deduced from method_.
+  int max_i4_header_bits_;   // partition #0 safeness factor
+  int thread_level_;         // derived from config->thread_level
+  int do_search_;            // derived from config->target_XXX
+  int use_tokens_;           // if true, use token buffer
+
+  // Memory
+  VP8MBInfo* mb_info_;   // contextual macroblock infos (mb_w_ + 1)
+  uint8_t*   preds_;     // predictions modes: (4*mb_w+1) * (4*mb_h+1)
+  uint32_t*  nz_;        // non-zero bit context: mb_w+1
+  uint8_t*   y_top_;     // top luma samples.
+  uint8_t*   uv_top_;    // top u/v samples.
+                         // U and V are packed into 16 bytes (8 U + 8 V)
+  LFStats*   lf_stats_;  // autofilter stats (if NULL, autofilter is off)
+};
+
+//------------------------------------------------------------------------------
+// internal functions. Not public.
+
+  // in tree.c
+extern const uint8_t VP8CoeffsProba0[NUM_TYPES][NUM_BANDS][NUM_CTX][NUM_PROBAS];
+extern const uint8_t
+    VP8CoeffsUpdateProba[NUM_TYPES][NUM_BANDS][NUM_CTX][NUM_PROBAS];
+// Reset the token probabilities to their initial (default) values
+void VP8DefaultProbas(VP8Encoder* const enc);
+// Write the token probabilities
+void VP8WriteProbas(VP8BitWriter* const bw, const VP8Proba* const probas);
+// Writes the partition #0 modes (that is: all intra modes)
+void VP8CodeIntraModes(VP8Encoder* const enc);
+
+  // in syntax.c
+// Generates the final bitstream by coding the partition0 and headers,
+// and appending an assembly of all the pre-coded token partitions.
+// Return true if everything is ok.
+int VP8EncWrite(VP8Encoder* const enc);
+// Release memory allocated for bit-writing in VP8EncLoop & seq.
+void VP8EncFreeBitWriters(VP8Encoder* const enc);
+
+  // in frame.c
+extern const uint8_t VP8Cat3[];
+extern const uint8_t VP8Cat4[];
+extern const uint8_t VP8Cat5[];
+extern const uint8_t VP8Cat6[];
+
+// Form all the four Intra16x16 predictions in the yuv_p_ cache
+void VP8MakeLuma16Preds(const VP8EncIterator* const it);
+// Form all the four Chroma8x8 predictions in the yuv_p_ cache
+void VP8MakeChroma8Preds(const VP8EncIterator* const it);
+// Form all the ten Intra4x4 predictions in the yuv_p_ cache
+// for the 4x4 block it->i4_
+void VP8MakeIntra4Preds(const VP8EncIterator* const it);
+// Rate calculation
+int VP8GetCostLuma16(VP8EncIterator* const it, const VP8ModeScore* const rd);
+int VP8GetCostLuma4(VP8EncIterator* const it, const int16_t levels[16]);
+int VP8GetCostUV(VP8EncIterator* const it, const VP8ModeScore* const rd);
+// Main coding calls
+int VP8EncLoop(VP8Encoder* const enc);
+int VP8EncTokenLoop(VP8Encoder* const enc);
+
+  // in webpenc.c
+// Assign an error code to a picture. Return false for convenience.
+int WebPEncodingSetError(const WebPPicture* const pic, WebPEncodingError error);
+int WebPReportProgress(const WebPPicture* const pic,
+                       int percent, int* const percent_store);
+
+  // in analysis.c
+// Main analysis loop. Decides the segmentations and complexity.
+// Assigns a first guess for Intra16 and uvmode_ prediction modes.
+int VP8EncAnalyze(VP8Encoder* const enc);
+
+  // in quant.c
+// Sets up segment's quantization values, base_quant_ and filter strengths.
+void VP8SetSegmentParams(VP8Encoder* const enc, float quality);
+// Pick best modes and fills the levels. Returns true if skipped.
+int VP8Decimate(VP8EncIterator* const it, VP8ModeScore* const rd,
+                VP8RDLevel rd_opt);
+
+  // in alpha.c
+void VP8EncInitAlpha(VP8Encoder* const enc);    // initialize alpha compression
+int VP8EncStartAlpha(VP8Encoder* const enc);    // start alpha coding process
+int VP8EncFinishAlpha(VP8Encoder* const enc);   // finalize compressed data
+int VP8EncDeleteAlpha(VP8Encoder* const enc);   // delete compressed data
+
+  // in filter.c
+
+// SSIM utils
+typedef struct {
+  double w, xm, ym, xxm, xym, yym;
+} DistoStats;
+void VP8SSIMAddStats(const DistoStats* const src, DistoStats* const dst);
+void VP8SSIMAccumulatePlane(const uint8_t* src1, int stride1,
+                            const uint8_t* src2, int stride2,
+                            int W, int H, DistoStats* const stats);
+double VP8SSIMGet(const DistoStats* const stats);
+double VP8SSIMGetSquaredError(const DistoStats* const stats);
+
+// autofilter
+void VP8InitFilter(VP8EncIterator* const it);
+void VP8StoreFilterStats(VP8EncIterator* const it);
+void VP8AdjustFilterStrength(VP8EncIterator* const it);
+
+// returns the approximate filtering strength needed to smooth a edge
+// step of 'delta', given a sharpness parameter 'sharpness'.
+int VP8FilterStrengthFromDelta(int sharpness, int delta);
+
+  // misc utils for picture_*.c:
+
+// Remove reference to the ARGB/YUVA buffer (doesn't free anything).
+void WebPPictureResetBuffers(WebPPicture* const picture);
+
+// Allocates ARGB buffer of given dimension (previous one is always free'd).
+// Preserves the YUV(A) buffer. Returns false in case of error (invalid param,
+// out-of-memory).
+int WebPPictureAllocARGB(WebPPicture* const picture, int width, int height);
+
+// Allocates YUVA buffer of given dimension (previous one is always free'd).
+// Uses picture->csp to determine whether an alpha buffer is needed.
+// Preserves the ARGB buffer.
+// Returns false in case of error (invalid param, out-of-memory).
+int WebPPictureAllocYUVA(WebPPicture* const picture, int width, int height);
+
+  // in near_lossless.c
+// Near lossless preprocessing in RGB color-space.
+int VP8ApplyNearLossless(int xsize, int ysize, uint32_t* argb, int quality);
+// Near lossless adjustment for predictors.
+void VP8ApplyNearLosslessPredict(int xsize, int ysize, int pred_bits,
+                                 const uint32_t* argb_orig,
+                                 uint32_t* argb, uint32_t* argb_scratch,
+                                 const uint32_t* const transform_data,
+                                 int quality, int subtract_green);
+//------------------------------------------------------------------------------
+
+#ifdef __cplusplus
+}    // extern "C"
+#endif
+
+#endif  /* WEBP_ENC_VP8ENCI_H_ */
diff --git a/Source/LibWebP/src/enc/vp8li.h b/Source/LibWebP/src/enc/vp8li.h
new file mode 100644
index 0000000..5696f4b
--- /dev/null
+++ b/Source/LibWebP/src/enc/vp8li.h
@@ -0,0 +1,78 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Lossless encoder: internal header.
+//
+// Author: Vikas Arora (vikaas.arora at gmail.com)
+
+#ifndef WEBP_ENC_VP8LI_H_
+#define WEBP_ENC_VP8LI_H_
+
+#include "./backward_references.h"
+#include "./histogram.h"
+#include "../utils/bit_writer.h"
+#include "../webp/encode.h"
+#include "../webp/format_constants.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+  const WebPConfig* config_;    // user configuration and parameters
+  const WebPPicture* pic_;      // input picture.
+
+  uint32_t* argb_;              // Transformed argb image data.
+  uint32_t* argb_scratch_;      // Scratch memory for argb rows
+                                // (used for prediction).
+  uint32_t* transform_data_;    // Scratch memory for transform data.
+  int       current_width_;     // Corresponds to packed image width.
+
+  // Encoding parameters derived from quality parameter.
+  int histo_bits_;
+  int transform_bits_;
+  int cache_bits_;        // If equal to 0, don't use color cache.
+
+  // Encoding parameters derived from image characteristics.
+  int use_cross_color_;
+  int use_subtract_green_;
+  int use_predict_;
+  int use_palette_;
+  int palette_size_;
+  uint32_t palette_[MAX_PALETTE_SIZE];
+
+  // Some 'scratch' (potentially large) objects.
+  struct VP8LBackwardRefs refs_[2];  // Backward Refs array corresponding to
+                                     // LZ77 & RLE coding.
+  VP8LHashChain hash_chain_;         // HashChain data for constructing
+                                     // backward references.
+} VP8LEncoder;
+
+//------------------------------------------------------------------------------
+// internal functions. Not public.
+
+// Encodes the picture.
+// Returns 0 if config or picture is NULL or picture doesn't have valid argb
+// input.
+int VP8LEncodeImage(const WebPConfig* const config,
+                    const WebPPicture* const picture);
+
+// Encodes the main image stream using the supplied bit writer.
+// If 'use_cache' is false, disables the use of color cache.
+WebPEncodingError VP8LEncodeStream(const WebPConfig* const config,
+                                   const WebPPicture* const picture,
+                                   VP8LBitWriter* const bw, int use_cache);
+
+//------------------------------------------------------------------------------
+
+#ifdef __cplusplus
+}    // extern "C"
+#endif
+
+#endif  /* WEBP_ENC_VP8LI_H_ */
diff --git a/Source/LibWebP/src/file_rename.bat b/Source/LibWebP/src/file_rename.bat
new file mode 100644
index 0000000..10706c5
--- /dev/null
+++ b/Source/LibWebP/src/file_rename.bat
@@ -0,0 +1,75 @@
+: The following file renaming is needed if one want to compile all files 
+: using the same output directory, e.g. "Debug\" or "Release\". 
+:
+: Usage:
+: copy all src WebP files into src\, then, run this script to rename files
+:
+
+setlocal
+
+: dec\
+del /Q .\dec\dec.*.c
+pushd "dec\" && for /f "delims=" %%A in ('dir /a-d /b *.c') do (
+copy /Y "%%~fA" "%%~dpAdec.%%A"
+del /Q "%%~fA"
+)
+popd
+
+: demux\
+del /Q .\demux\demux.*.c
+pushd "demux\" && for /f "delims=" %%A in ('dir /a-d /b *.c') do (
+copy /Y "%%~fA" "%%~dpAdemux.%%A"
+del /Q "%%~fA"
+)
+popd
+
+: dsp\
+del /Q .\dsp\dsp.*.c
+pushd "dsp\" && for /f "delims=" %%A in ('dir /a-d /b *.c') do (
+copy /Y "%%~fA" "%%~dpAdsp.%%A"
+del /Q "%%~fA"
+)
+popd
+
+: enc\
+del /Q .\enc\enc.*.c
+pushd "enc\" && for /f "delims=" %%A in ('dir /a-d /b *.c') do (
+copy /Y "%%~fA" "%%~dpAenc.%%A"
+del /Q "%%~fA"
+)
+popd
+
+: mux\
+del /Q .\mux\mux.*.c
+pushd "mux\" && for /f "delims=" %%A in ('dir /a-d /b *.c') do (
+copy /Y "%%~fA" "%%~dpAmux.%%A"
+del /Q "%%~fA"
+)
+popd
+
+: utils\
+del /Q .\utils\utils.*.c
+pushd "utils\" && for /f "delims=" %%A in ('dir /a-d /b *.c') do (
+copy /Y "%%~fA" "%%~dpAutils.%%A"
+del /Q "%%~fA"
+)
+popd
+
+: webp\
+del /Q .\webp\webp.*.c
+pushd "webp\" && for /f "delims=" %%A in ('dir /a-d /b *.c') do (
+copy /Y "%%~fA" "%%~dpAwebp.%%A"
+del /Q "%%~fA"
+)
+popd
+
+endlocal
+
+: Makefiles
+
+del /S /Q Makefile.am
+del /S /Q *.pc.in
+
+pause -1
+
+
diff --git a/Source/LibWebP/src/mux/mux.anim_encode.c b/Source/LibWebP/src/mux/mux.anim_encode.c
new file mode 100644
index 0000000..e0689ce
--- /dev/null
+++ b/Source/LibWebP/src/mux/mux.anim_encode.c
@@ -0,0 +1,1241 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+//  AnimEncoder implementation.
+//
+
+#include <assert.h>
+#include <limits.h>
+#include <stdio.h>
+
+#include "../utils/utils.h"
+#include "../webp/decode.h"
+#include "../webp/format_constants.h"
+#include "../webp/mux.h"
+
+//------------------------------------------------------------------------------
+// Internal structs.
+
+// Stores frame rectangle dimensions.
+typedef struct {
+  int x_offset_, y_offset_, width_, height_;
+} FrameRect;
+
+// Used to store two candidates of encoded data for an animation frame. One of
+// the two will be chosen later.
+typedef struct {
+  WebPMuxFrameInfo sub_frame_;  // Encoded frame rectangle.
+  WebPMuxFrameInfo key_frame_;  // Encoded frame if it is a key-frame.
+  int is_key_frame_;            // True if 'key_frame' has been chosen.
+} EncodedFrame;
+
+struct WebPAnimEncoder {
+  const int canvas_width_;                  // Canvas width.
+  const int canvas_height_;                 // Canvas height.
+  const WebPAnimEncoderOptions options_;    // Global encoding options.
+
+  FrameRect prev_rect;                // Previous WebP frame rectangle.
+  WebPConfig last_config;             // Cached in case a re-encode is needed.
+  WebPConfig last_config2;            // 2nd cached config; only valid if
+                                      // 'options_.allow_mixed' is true.
+
+  WebPPicture* curr_canvas_;          // Only pointer; we don't own memory.
+
+  // Canvas buffers.
+  WebPPicture curr_canvas_copy_;      // Possibly modified current canvas.
+  int curr_canvas_copy_modified_;     // True if pixels in 'curr_canvas_copy_'
+                                      // differ from those in 'curr_canvas_'.
+
+  WebPPicture prev_canvas_;           // Previous canvas.
+  WebPPicture prev_canvas_disposed_;  // Previous canvas disposed to background.
+
+  // Encoded data.
+  EncodedFrame* encoded_frames_;      // Array of encoded frames.
+  size_t size_;             // Number of allocated frames.
+  size_t start_;            // Frame start index.
+  size_t count_;            // Number of valid frames.
+  size_t flush_count_;      // If >0, 'flush_count' frames starting from
+                            // 'start' are ready to be added to mux.
+
+  // key-frame related.
+  int64_t best_delta_;      // min(canvas size - frame size) over the frames.
+                            // Can be negative in certain cases due to
+                            // transparent pixels in a frame.
+  int keyframe_;            // Index of selected key-frame relative to 'start_'.
+  int count_since_key_frame_;     // Frames seen since the last key-frame.
+  int prev_candidate_undecided_;  // True if it's not yet decided if previous
+                                  // frame would be a sub-frame or a key-frame.
+
+  // Misc.
+  int is_first_frame_;  // True if first frame is yet to be added/being added.
+  size_t frame_count_;  // Number of frames added to mux so far.
+
+  WebPMux* mux_;        // Muxer to assemble the WebP bitstream.
+};
+
+// -----------------------------------------------------------------------------
+// Life of WebPAnimEncoder object.
+
+#define DELTA_INFINITY      (1ULL << 32)
+#define KEYFRAME_NONE       (-1)
+
+// Reset the counters in the WebPAnimEncoder.
+static void ResetCounters(WebPAnimEncoder* const enc) {
+  enc->start_ = 0;
+  enc->count_ = 0;
+  enc->flush_count_ = 0;
+  enc->best_delta_ = DELTA_INFINITY;
+  enc->keyframe_ = KEYFRAME_NONE;
+}
+
+static void DisableKeyframes(WebPAnimEncoderOptions* const enc_options) {
+  enc_options->kmax = INT_MAX;
+  enc_options->kmin = enc_options->kmax - 1;
+}
+
+#define MAX_CACHED_FRAMES 30
+
+static void SanitizeEncoderOptions(WebPAnimEncoderOptions* const enc_options) {
+  int print_warning = enc_options->verbose;
+
+  if (enc_options->minimize_size) {
+    DisableKeyframes(enc_options);
+  }
+
+  if (enc_options->kmin <= 0) {
+    DisableKeyframes(enc_options);
+    print_warning = 0;
+  }
+  if (enc_options->kmax <= 0) {  // All frames will be key-frames.
+    enc_options->kmin = 0;
+    enc_options->kmax = 0;
+    return;
+  }
+
+  if (enc_options->kmin >= enc_options->kmax) {
+    enc_options->kmin = enc_options->kmax - 1;
+    if (print_warning) {
+      fprintf(stderr, "WARNING: Setting kmin = %d, so that kmin < kmax.\n",
+              enc_options->kmin);
+    }
+  } else {
+    const int kmin_limit = enc_options->kmax / 2 + 1;
+    if (enc_options->kmin < kmin_limit && kmin_limit < enc_options->kmax) {
+      // This ensures that enc.keyframe + kmin >= kmax is always true. So, we
+      // can flush all the frames in the 'count_since_key_frame == kmax' case.
+      enc_options->kmin = kmin_limit;
+      if (print_warning) {
+        fprintf(stderr,
+                "WARNING: Setting kmin = %d, so that kmin >= kmax / 2 + 1.\n",
+                enc_options->kmin);
+      }
+    }
+  }
+  // Limit the max number of frames that are allocated.
+  if (enc_options->kmax - enc_options->kmin > MAX_CACHED_FRAMES) {
+    enc_options->kmin = enc_options->kmax - MAX_CACHED_FRAMES;
+    if (print_warning) {
+      fprintf(stderr,
+              "WARNING: Setting kmin = %d, so that kmax - kmin <= %d.\n",
+              enc_options->kmin, MAX_CACHED_FRAMES);
+    }
+  }
+  assert(enc_options->kmin < enc_options->kmax);
+}
+
+#undef MAX_CACHED_FRAMES
+
+static void DefaultEncoderOptions(WebPAnimEncoderOptions* const enc_options) {
+  enc_options->anim_params.loop_count = 0;
+  enc_options->anim_params.bgcolor = 0xffffffff;  // White.
+  enc_options->minimize_size = 0;
+  DisableKeyframes(enc_options);
+  enc_options->allow_mixed = 0;
+  enc_options->verbose = 0;
+}
+
+int WebPAnimEncoderOptionsInitInternal(WebPAnimEncoderOptions* enc_options,
+                                       int abi_version) {
+  if (enc_options == NULL ||
+      WEBP_ABI_IS_INCOMPATIBLE(abi_version, WEBP_MUX_ABI_VERSION)) {
+    return 0;
+  }
+  DefaultEncoderOptions(enc_options);
+  return 1;
+}
+
+#define TRANSPARENT_COLOR   0x00ffffff
+
+static void ClearRectangle(WebPPicture* const picture,
+                           int left, int top, int width, int height) {
+  int j;
+  for (j = top; j < top + height; ++j) {
+    uint32_t* const dst = picture->argb + j * picture->argb_stride;
+    int i;
+    for (i = left; i < left + width; ++i) {
+      dst[i] = TRANSPARENT_COLOR;
+    }
+  }
+}
+
+static void WebPUtilClearPic(WebPPicture* const picture,
+                             const FrameRect* const rect) {
+  if (rect != NULL) {
+    ClearRectangle(picture, rect->x_offset_, rect->y_offset_,
+                   rect->width_, rect->height_);
+  } else {
+    ClearRectangle(picture, 0, 0, picture->width, picture->height);
+  }
+}
+
+WebPAnimEncoder* WebPAnimEncoderNewInternal(
+    int width, int height, const WebPAnimEncoderOptions* enc_options,
+    int abi_version) {
+  WebPAnimEncoder* enc;
+
+  if (WEBP_ABI_IS_INCOMPATIBLE(abi_version, WEBP_MUX_ABI_VERSION)) {
+    return NULL;
+  }
+  if (width <= 0 || height <= 0 ||
+      (width * (uint64_t)height) >= MAX_IMAGE_AREA) {
+    return NULL;
+  }
+
+  enc = (WebPAnimEncoder*)WebPSafeCalloc(1, sizeof(*enc));
+  if (enc == NULL) return NULL;
+  // sanity inits, so we can call WebPAnimEncoderDelete():
+  enc->encoded_frames_ = NULL;
+  enc->mux_ = NULL;
+
+  // Dimensions and options.
+  *(int*)&enc->canvas_width_ = width;
+  *(int*)&enc->canvas_height_ = height;
+  if (enc_options != NULL) {
+    *(WebPAnimEncoderOptions*)&enc->options_ = *enc_options;
+    SanitizeEncoderOptions((WebPAnimEncoderOptions*)&enc->options_);
+  } else {
+    DefaultEncoderOptions((WebPAnimEncoderOptions*)&enc->options_);
+  }
+
+  // Canvas buffers.
+  if (!WebPPictureInit(&enc->curr_canvas_copy_) ||
+      !WebPPictureInit(&enc->prev_canvas_) ||
+      !WebPPictureInit(&enc->prev_canvas_disposed_)) {
+    return NULL;
+  }
+  enc->curr_canvas_copy_.width = width;
+  enc->curr_canvas_copy_.height = height;
+  enc->curr_canvas_copy_.use_argb = 1;
+  if (!WebPPictureAlloc(&enc->curr_canvas_copy_) ||
+      !WebPPictureCopy(&enc->curr_canvas_copy_, &enc->prev_canvas_) ||
+      !WebPPictureCopy(&enc->curr_canvas_copy_, &enc->prev_canvas_disposed_)) {
+    goto Err;
+  }
+  WebPUtilClearPic(&enc->prev_canvas_, NULL);
+  enc->curr_canvas_copy_modified_ = 1;
+
+  // Encoded frames.
+  ResetCounters(enc);
+  // Note: one extra storage is for the previous frame.
+  enc->size_ = enc->options_.kmax - enc->options_.kmin + 1;
+  // We need space for at least 2 frames. But when kmin, kmax are both zero,
+  // enc->size_ will be 1. So we handle that special case below.
+  if (enc->size_ < 2) enc->size_ = 2;
+  enc->encoded_frames_ =
+      (EncodedFrame*)WebPSafeCalloc(enc->size_, sizeof(*enc->encoded_frames_));
+  if (enc->encoded_frames_ == NULL) goto Err;
+
+  enc->mux_ = WebPMuxNew();
+  if (enc->mux_ == NULL) goto Err;
+
+  enc->count_since_key_frame_ = 0;
+  enc->prev_candidate_undecided_ = 0;
+  enc->is_first_frame_ = 1;
+
+  return enc;  // All OK.
+
+ Err:
+  WebPAnimEncoderDelete(enc);
+  return NULL;
+}
+
+// Release the data contained by 'encoded_frame'.
+static void FrameRelease(EncodedFrame* const encoded_frame) {
+  if (encoded_frame != NULL) {
+    WebPDataClear(&encoded_frame->sub_frame_.bitstream);
+    WebPDataClear(&encoded_frame->key_frame_.bitstream);
+    memset(encoded_frame, 0, sizeof(*encoded_frame));
+  }
+}
+
+void WebPAnimEncoderDelete(WebPAnimEncoder* enc) {
+  if (enc != NULL) {;
+    WebPPictureFree(&enc->curr_canvas_copy_);
+    WebPPictureFree(&enc->prev_canvas_);
+    WebPPictureFree(&enc->prev_canvas_disposed_);
+    if (enc->encoded_frames_ != NULL) {
+      size_t i;
+      for (i = 0; i < enc->size_; ++i) {
+        FrameRelease(&enc->encoded_frames_[i]);
+      }
+      WebPSafeFree(enc->encoded_frames_);
+    }
+    WebPMuxDelete(enc->mux_);
+    WebPSafeFree(enc);
+  }
+}
+
+// -----------------------------------------------------------------------------
+// Frame addition.
+
+// Returns cached frame at the given 'position'.
+static EncodedFrame* GetFrame(const WebPAnimEncoder* const enc,
+                              size_t position) {
+  assert(enc->start_ + position < enc->size_);
+  return &enc->encoded_frames_[enc->start_ + position];
+}
+
+// Returns true if 'length' number of pixels in 'src' and 'dst' are identical,
+// assuming the given step sizes between pixels.
+static WEBP_INLINE int ComparePixels(const uint32_t* src, int src_step,
+                                     const uint32_t* dst, int dst_step,
+                                     int length) {
+  assert(length > 0);
+  while (length-- > 0) {
+    if (*src != *dst) {
+      return 0;
+    }
+    src += src_step;
+    dst += dst_step;
+  }
+  return 1;
+}
+
+// Assumes that an initial valid guess of change rectangle 'rect' is passed.
+static void MinimizeChangeRectangle(const WebPPicture* const src,
+                                    const WebPPicture* const dst,
+                                    FrameRect* const rect) {
+  int i, j;
+  // Sanity checks.
+  assert(src->width == dst->width && src->height == dst->height);
+  assert(rect->x_offset_ + rect->width_ <= dst->width);
+  assert(rect->y_offset_ + rect->height_ <= dst->height);
+
+  // Left boundary.
+  for (i = rect->x_offset_; i < rect->x_offset_ + rect->width_; ++i) {
+    const uint32_t* const src_argb =
+        &src->argb[rect->y_offset_ * src->argb_stride + i];
+    const uint32_t* const dst_argb =
+        &dst->argb[rect->y_offset_ * dst->argb_stride + i];
+    if (ComparePixels(src_argb, src->argb_stride, dst_argb, dst->argb_stride,
+                      rect->height_)) {
+      --rect->width_;  // Redundant column.
+      ++rect->x_offset_;
+    } else {
+      break;
+    }
+  }
+  if (rect->width_ == 0) goto End;
+
+  // Right boundary.
+  for (i = rect->x_offset_ + rect->width_ - 1; i >= rect->x_offset_; --i) {
+    const uint32_t* const src_argb =
+        &src->argb[rect->y_offset_ * src->argb_stride + i];
+    const uint32_t* const dst_argb =
+        &dst->argb[rect->y_offset_ * dst->argb_stride + i];
+    if (ComparePixels(src_argb, src->argb_stride, dst_argb, dst->argb_stride,
+                      rect->height_)) {
+      --rect->width_;  // Redundant column.
+    } else {
+      break;
+    }
+  }
+  if (rect->width_ == 0) goto End;
+
+  // Top boundary.
+  for (j = rect->y_offset_; j < rect->y_offset_ + rect->height_; ++j) {
+    const uint32_t* const src_argb =
+        &src->argb[j * src->argb_stride + rect->x_offset_];
+    const uint32_t* const dst_argb =
+        &dst->argb[j * dst->argb_stride + rect->x_offset_];
+    if (ComparePixels(src_argb, 1, dst_argb, 1, rect->width_)) {
+      --rect->height_;  // Redundant row.
+      ++rect->y_offset_;
+    } else {
+      break;
+    }
+  }
+  if (rect->height_ == 0) goto End;
+
+  // Bottom boundary.
+  for (j = rect->y_offset_ + rect->height_ - 1; j >= rect->y_offset_; --j) {
+    const uint32_t* const src_argb =
+        &src->argb[j * src->argb_stride + rect->x_offset_];
+    const uint32_t* const dst_argb =
+        &dst->argb[j * dst->argb_stride + rect->x_offset_];
+    if (ComparePixels(src_argb, 1, dst_argb, 1, rect->width_)) {
+      --rect->height_;  // Redundant row.
+    } else {
+      break;
+    }
+  }
+  if (rect->height_ == 0) goto End;
+
+  if (rect->width_ == 0 || rect->height_ == 0) {
+ End:
+    // TODO(later): This rare case can happen for a bad GIF. In such a case, the
+    // frame should not be encoded at all and the duration of prev frame should
+    // be increased instead. For now, we just create a 1x1 frame at zero offset.
+    rect->x_offset_ = 0;
+    rect->y_offset_ = 0;
+    rect->width_ = 1;
+    rect->height_ = 1;
+  }
+}
+
+// Snap rectangle to even offsets (and adjust dimensions if needed).
+static WEBP_INLINE void SnapToEvenOffsets(FrameRect* const rect) {
+  rect->width_ += (rect->x_offset_ & 1);
+  rect->height_ += (rect->y_offset_ & 1);
+  rect->x_offset_ &= ~1;
+  rect->y_offset_ &= ~1;
+}
+
+// Given previous and current canvas, picks the optimal rectangle for the
+// current frame. The initial guess for 'rect' will be the full canvas.
+static int GetSubRect(const WebPPicture* const prev_canvas,
+                      const WebPPicture* const curr_canvas, int is_key_frame,
+                      int is_first_frame, FrameRect* const rect,
+                      WebPPicture* const sub_frame) {
+  rect->x_offset_ = 0;
+  rect->y_offset_ = 0;
+  rect->width_ = curr_canvas->width;
+  rect->height_ = curr_canvas->height;
+  if (!is_key_frame || is_first_frame) {  // Optimize frame rectangle.
+    // Note: This behaves as expected for first frame, as 'prev_canvas' is
+    // initialized to a fully transparent canvas in the beginning.
+    MinimizeChangeRectangle(prev_canvas, curr_canvas, rect);
+  }
+  SnapToEvenOffsets(rect);
+
+  return WebPPictureView(curr_canvas, rect->x_offset_, rect->y_offset_,
+                         rect->width_, rect->height_, sub_frame);
+}
+
+// TODO: Also used in picture.c. Move to a common location?
+// Copy width x height pixels from 'src' to 'dst' honoring the strides.
+static void CopyPlane(const uint8_t* src, int src_stride,
+                      uint8_t* dst, int dst_stride, int width, int height) {
+  while (height-- > 0) {
+    memcpy(dst, src, width);
+    src += src_stride;
+    dst += dst_stride;
+  }
+}
+
+// Copy pixels from 'src' to 'dst' honoring strides. 'src' and 'dst' are assumed
+// to be already allocated.
+static void CopyPixels(const WebPPicture* const src, WebPPicture* const dst) {
+  assert(src->width == dst->width && src->height == dst->height);
+  assert(src->use_argb && dst->use_argb);
+  CopyPlane((uint8_t*)src->argb, 4 * src->argb_stride, (uint8_t*)dst->argb,
+            4 * dst->argb_stride, 4 * src->width, src->height);
+}
+
+static void DisposeFrameRectangle(int dispose_method,
+                                  const FrameRect* const rect,
+                                  WebPPicture* const curr_canvas) {
+  assert(rect != NULL);
+  if (dispose_method == WEBP_MUX_DISPOSE_BACKGROUND) {
+    WebPUtilClearPic(curr_canvas, rect);
+  }
+}
+
+static uint32_t RectArea(const FrameRect* const rect) {
+  return (uint32_t)rect->width_ * rect->height_;
+}
+
+static int IsBlendingPossible(const WebPPicture* const src,
+                              const WebPPicture* const dst,
+                              const FrameRect* const rect) {
+  int i, j;
+  assert(src->width == dst->width && src->height == dst->height);
+  assert(rect->x_offset_ + rect->width_ <= dst->width);
+  assert(rect->y_offset_ + rect->height_ <= dst->height);
+  for (j = rect->y_offset_; j < rect->y_offset_ + rect->height_; ++j) {
+    for (i = rect->x_offset_; i < rect->x_offset_ + rect->width_; ++i) {
+      const uint32_t src_pixel = src->argb[j * src->argb_stride + i];
+      const uint32_t dst_pixel = dst->argb[j * dst->argb_stride + i];
+      const uint32_t dst_alpha = dst_pixel >> 24;
+      if (dst_alpha != 0xff && src_pixel != dst_pixel) {
+        // In this case, if we use blending, we can't attain the desired
+        // 'dst_pixel' value for this pixel. So, blending is not possible.
+        return 0;
+      }
+    }
+  }
+  return 1;
+}
+
+#define MIN_COLORS_LOSSY     31  // Don't try lossy below this threshold.
+#define MAX_COLORS_LOSSLESS 194  // Don't try lossless above this threshold.
+#define MAX_COLOR_COUNT     256  // Power of 2 greater than MAX_COLORS_LOSSLESS.
+#define HASH_SIZE (MAX_COLOR_COUNT * 4)
+#define HASH_RIGHT_SHIFT     22  // 32 - log2(HASH_SIZE).
+
+// TODO(urvang): Also used in enc/vp8l.c. Move to utils.
+// If the number of colors in the 'pic' is at least MAX_COLOR_COUNT, return
+// MAX_COLOR_COUNT. Otherwise, return the exact number of colors in the 'pic'.
+static int GetColorCount(const WebPPicture* const pic) {
+  int x, y;
+  int num_colors = 0;
+  uint8_t in_use[HASH_SIZE] = { 0 };
+  uint32_t colors[HASH_SIZE];
+  static const uint32_t kHashMul = 0x1e35a7bd;
+  const uint32_t* argb = pic->argb;
+  const int width = pic->width;
+  const int height = pic->height;
+  uint32_t last_pix = ~argb[0];   // so we're sure that last_pix != argb[0]
+
+  for (y = 0; y < height; ++y) {
+    for (x = 0; x < width; ++x) {
+      int key;
+      if (argb[x] == last_pix) {
+        continue;
+      }
+      last_pix = argb[x];
+      key = (kHashMul * last_pix) >> HASH_RIGHT_SHIFT;
+      while (1) {
+        if (!in_use[key]) {
+          colors[key] = last_pix;
+          in_use[key] = 1;
+          ++num_colors;
+          if (num_colors >= MAX_COLOR_COUNT) {
+            return MAX_COLOR_COUNT;  // Exact count not needed.
+          }
+          break;
+        } else if (colors[key] == last_pix) {
+          break;  // The color is already there.
+        } else {
+          // Some other color sits here, so do linear conflict resolution.
+          ++key;
+          key &= (HASH_SIZE - 1);  // Key mask.
+        }
+      }
+    }
+    argb += pic->argb_stride;
+  }
+  return num_colors;
+}
+
+#undef MAX_COLOR_COUNT
+#undef HASH_SIZE
+#undef HASH_RIGHT_SHIFT
+
+// For pixels in 'rect', replace those pixels in 'dst' that are same as 'src' by
+// transparent pixels.
+static void IncreaseTransparency(const WebPPicture* const src,
+                                 const FrameRect* const rect,
+                                 WebPPicture* const dst) {
+  int i, j;
+  assert(src != NULL && dst != NULL && rect != NULL);
+  assert(src->width == dst->width && src->height == dst->height);
+  for (j = rect->y_offset_; j < rect->y_offset_ + rect->height_; ++j) {
+    const uint32_t* const psrc = src->argb + j * src->argb_stride;
+    uint32_t* const pdst = dst->argb + j * dst->argb_stride;
+    for (i = rect->x_offset_; i < rect->x_offset_ + rect->width_; ++i) {
+      if (psrc[i] == pdst[i]) {
+        pdst[i] = TRANSPARENT_COLOR;
+      }
+    }
+  }
+}
+
+#undef TRANSPARENT_COLOR
+
+// Replace similar blocks of pixels by a 'see-through' transparent block
+// with uniform average color.
+static void FlattenSimilarBlocks(const WebPPicture* const src,
+                                 const FrameRect* const rect,
+                                 WebPPicture* const dst) {
+  int i, j;
+  const int block_size = 8;
+  const int y_start = (rect->y_offset_ + block_size) & ~(block_size - 1);
+  const int y_end = (rect->y_offset_ + rect->height_) & ~(block_size - 1);
+  const int x_start = (rect->x_offset_ + block_size) & ~(block_size - 1);
+  const int x_end = (rect->x_offset_ + rect->width_) & ~(block_size - 1);
+  assert(src != NULL && dst != NULL && rect != NULL);
+  assert(src->width == dst->width && src->height == dst->height);
+  assert((block_size & (block_size - 1)) == 0);  // must be a power of 2
+  // Iterate over each block and count similar pixels.
+  for (j = y_start; j < y_end; j += block_size) {
+    for (i = x_start; i < x_end; i += block_size) {
+      int cnt = 0;
+      int avg_r = 0, avg_g = 0, avg_b = 0;
+      int x, y;
+      const uint32_t* const psrc = src->argb + j * src->argb_stride + i;
+      uint32_t* const pdst = dst->argb + j * dst->argb_stride + i;
+      for (y = 0; y < block_size; ++y) {
+        for (x = 0; x < block_size; ++x) {
+          const uint32_t src_pixel = psrc[x + y * src->argb_stride];
+          const int alpha = src_pixel >> 24;
+          if (alpha == 0xff &&
+              src_pixel == pdst[x + y * dst->argb_stride]) {
+              ++cnt;
+              avg_r += (src_pixel >> 16) & 0xff;
+              avg_g += (src_pixel >>  8) & 0xff;
+              avg_b += (src_pixel >>  0) & 0xff;
+          }
+        }
+      }
+      // If we have a fully similar block, we replace it with an
+      // average transparent block. This compresses better in lossy mode.
+      if (cnt == block_size * block_size) {
+        const uint32_t color = (0x00          << 24) |
+                               ((avg_r / cnt) << 16) |
+                               ((avg_g / cnt) <<  8) |
+                               ((avg_b / cnt) <<  0);
+        for (y = 0; y < block_size; ++y) {
+          for (x = 0; x < block_size; ++x) {
+            pdst[x + y * dst->argb_stride] = color;
+          }
+        }
+      }
+    }
+  }
+}
+
+static int EncodeFrame(const WebPConfig* const config, WebPPicture* const pic,
+                       WebPMemoryWriter* const memory) {
+  pic->use_argb = 1;
+  pic->writer = WebPMemoryWrite;
+  pic->custom_ptr = memory;
+  if (!WebPEncode(config, pic)) {
+    return 0;
+  }
+  return 1;
+}
+
+// Struct representing a candidate encoded frame including its metadata.
+typedef struct {
+  WebPMemoryWriter  mem_;
+  WebPMuxFrameInfo  info_;
+  FrameRect         rect_;
+  int               evaluate_;  // True if this candidate should be evaluated.
+} Candidate;
+
+// Generates a candidate encoded frame given a picture and metadata.
+static WebPEncodingError EncodeCandidate(WebPPicture* const sub_frame,
+                                         const FrameRect* const rect,
+                                         const WebPConfig* const config,
+                                         int use_blending, int duration,
+                                         Candidate* const candidate) {
+  WebPEncodingError error_code = VP8_ENC_OK;
+  assert(candidate != NULL);
+  memset(candidate, 0, sizeof(*candidate));
+
+  // Set frame rect and info.
+  candidate->rect_ = *rect;
+  candidate->info_.id = WEBP_CHUNK_ANMF;
+  candidate->info_.x_offset = rect->x_offset_;
+  candidate->info_.y_offset = rect->y_offset_;
+  candidate->info_.dispose_method = WEBP_MUX_DISPOSE_NONE;  // Set later.
+  candidate->info_.blend_method =
+      use_blending ? WEBP_MUX_BLEND : WEBP_MUX_NO_BLEND;
+  candidate->info_.duration = duration;
+
+  // Encode picture.
+  WebPMemoryWriterInit(&candidate->mem_);
+
+  if (!EncodeFrame(config, sub_frame, &candidate->mem_)) {
+    error_code = sub_frame->error_code;
+    goto Err;
+  }
+
+  candidate->evaluate_ = 1;
+  return error_code;
+
+ Err:
+  WebPMemoryWriterClear(&candidate->mem_);
+  return error_code;
+}
+
+static void CopyCurrentCanvas(WebPAnimEncoder* const enc) {
+  if (enc->curr_canvas_copy_modified_) {
+    CopyPixels(enc->curr_canvas_, &enc->curr_canvas_copy_);
+    enc->curr_canvas_copy_modified_ = 0;
+  }
+}
+
+enum {
+  LL_DISP_NONE = 0,
+  LL_DISP_BG,
+  LOSSY_DISP_NONE,
+  LOSSY_DISP_BG,
+  CANDIDATE_COUNT
+};
+
+// Generates candidates for a given dispose method given pre-filled 'rect'
+// and 'sub_frame'.
+static WebPEncodingError GenerateCandidates(
+    WebPAnimEncoder* const enc, Candidate candidates[CANDIDATE_COUNT],
+    WebPMuxAnimDispose dispose_method, int is_lossless, int is_key_frame,
+    const FrameRect* const rect, WebPPicture* sub_frame, int duration,
+    const WebPConfig* const config_ll, const WebPConfig* const config_lossy) {
+  WebPEncodingError error_code = VP8_ENC_OK;
+  const int is_dispose_none = (dispose_method == WEBP_MUX_DISPOSE_NONE);
+  Candidate* const candidate_ll =
+      is_dispose_none ? &candidates[LL_DISP_NONE] : &candidates[LL_DISP_BG];
+  Candidate* const candidate_lossy = is_dispose_none
+                                     ? &candidates[LOSSY_DISP_NONE]
+                                     : &candidates[LOSSY_DISP_BG];
+  WebPPicture* const curr_canvas = &enc->curr_canvas_copy_;
+  const WebPPicture* const prev_canvas =
+      is_dispose_none ? &enc->prev_canvas_ : &enc->prev_canvas_disposed_;
+  const int use_blending =
+      !is_key_frame &&
+      IsBlendingPossible(prev_canvas, curr_canvas, rect);
+
+  // Pick candidates to be tried.
+  if (!enc->options_.allow_mixed) {
+    candidate_ll->evaluate_ = is_lossless;
+    candidate_lossy->evaluate_ = !is_lossless;
+  } else {  // Use a heuristic for trying lossless and/or lossy compression.
+    const int num_colors = GetColorCount(sub_frame);
+    candidate_ll->evaluate_ = (num_colors < MAX_COLORS_LOSSLESS);
+    candidate_lossy->evaluate_ = (num_colors >= MIN_COLORS_LOSSY);
+  }
+
+  // Generate candidates.
+  if (candidate_ll->evaluate_) {
+    CopyCurrentCanvas(enc);
+    if (use_blending) {
+      IncreaseTransparency(prev_canvas, rect, curr_canvas);
+      enc->curr_canvas_copy_modified_ = 1;
+    }
+    error_code = EncodeCandidate(sub_frame, rect, config_ll, use_blending,
+                                 duration, candidate_ll);
+    if (error_code != VP8_ENC_OK) return error_code;
+  }
+  if (candidate_lossy->evaluate_) {
+    CopyCurrentCanvas(enc);
+    if (use_blending) {
+      FlattenSimilarBlocks(prev_canvas, rect, curr_canvas);
+      enc->curr_canvas_copy_modified_ = 1;
+    }
+    error_code = EncodeCandidate(sub_frame, rect, config_lossy, use_blending,
+                                 duration, candidate_lossy);
+    if (error_code != VP8_ENC_OK) return error_code;
+  }
+  return error_code;
+}
+
+#undef MIN_COLORS_LOSSY
+#undef MAX_COLORS_LOSSLESS
+
+static void GetEncodedData(const WebPMemoryWriter* const memory,
+                           WebPData* const encoded_data) {
+  encoded_data->bytes = memory->mem;
+  encoded_data->size  = memory->size;
+}
+
+// Sets dispose method of the previous frame to be 'dispose_method'.
+static void SetPreviousDisposeMethod(WebPAnimEncoder* const enc,
+                                     WebPMuxAnimDispose dispose_method) {
+  const size_t position = enc->count_ - 2;
+  EncodedFrame* const prev_enc_frame = GetFrame(enc, position);
+  assert(enc->count_ >= 2);  // As current and previous frames are in enc.
+
+  if (enc->prev_candidate_undecided_) {
+    assert(dispose_method == WEBP_MUX_DISPOSE_NONE);
+    prev_enc_frame->sub_frame_.dispose_method = dispose_method;
+    prev_enc_frame->key_frame_.dispose_method = dispose_method;
+  } else {
+    WebPMuxFrameInfo* const prev_info = prev_enc_frame->is_key_frame_
+                                        ? &prev_enc_frame->key_frame_
+                                        : &prev_enc_frame->sub_frame_;
+    prev_info->dispose_method = dispose_method;
+  }
+}
+
+// Pick the candidate encoded frame with smallest size and release other
+// candidates.
+// TODO(later): Perhaps a rough SSIM/PSNR produced by the encoder should
+// also be a criteria, in addition to sizes.
+static void PickBestCandidate(WebPAnimEncoder* const enc,
+                              Candidate* const candidates, int is_key_frame,
+                              EncodedFrame* const encoded_frame) {
+  int i;
+  int best_idx = -1;
+  size_t best_size = ~0;
+  for (i = 0; i < CANDIDATE_COUNT; ++i) {
+    if (candidates[i].evaluate_) {
+      const size_t candidate_size = candidates[i].mem_.size;
+      if (candidate_size < best_size) {
+        best_idx = i;
+        best_size = candidate_size;
+      }
+    }
+  }
+  assert(best_idx != -1);
+  for (i = 0; i < CANDIDATE_COUNT; ++i) {
+    if (candidates[i].evaluate_) {
+      if (i == best_idx) {
+        WebPMuxFrameInfo* const dst = is_key_frame
+                                      ? &encoded_frame->key_frame_
+                                      : &encoded_frame->sub_frame_;
+        *dst = candidates[i].info_;
+        GetEncodedData(&candidates[i].mem_, &dst->bitstream);
+        if (!is_key_frame) {
+          // Note: Previous dispose method only matters for non-keyframes.
+          // Also, we don't want to modify previous dispose method that was
+          // selected when a non key-frame was assumed.
+          const WebPMuxAnimDispose prev_dispose_method =
+              (best_idx == LL_DISP_NONE || best_idx == LOSSY_DISP_NONE)
+                  ? WEBP_MUX_DISPOSE_NONE
+                  : WEBP_MUX_DISPOSE_BACKGROUND;
+          SetPreviousDisposeMethod(enc, prev_dispose_method);
+        }
+        enc->prev_rect = candidates[i].rect_;  // save for next frame.
+      } else {
+        WebPMemoryWriterClear(&candidates[i].mem_);
+        candidates[i].evaluate_ = 0;
+      }
+    }
+  }
+}
+
+// Depending on the configuration, tries different compressions
+// (lossy/lossless), dispose methods, blending methods etc to encode the current
+// frame and outputs the best one in 'encoded_frame'.
+static WebPEncodingError SetFrame(WebPAnimEncoder* const enc, int duration,
+                                  const WebPConfig* const config,
+                                  int is_key_frame,
+                                  EncodedFrame* const encoded_frame) {
+  int i;
+  WebPEncodingError error_code = VP8_ENC_OK;
+  const WebPPicture* const curr_canvas = &enc->curr_canvas_copy_;
+  const WebPPicture* const prev_canvas = &enc->prev_canvas_;
+  Candidate candidates[CANDIDATE_COUNT];
+  const int is_lossless = config->lossless;
+  const int is_first_frame = enc->is_first_frame_;
+
+  int try_dispose_none = 1;  // Default.
+  FrameRect rect_none;
+  WebPPicture sub_frame_none;
+
+  // If current frame is a key-frame, dispose method of previous frame doesn't
+  // matter, so we don't try dispose to background.
+  // Also, if key-frame insertion is on, and previous frame could be picked as
+  // either a sub-frame or a key-frame, then we can't be sure about what frame
+  // rectangle would be disposed. In that case too, we don't try dispose to
+  // background.
+  const int dispose_bg_possible =
+      !is_key_frame && !enc->prev_candidate_undecided_;
+  int try_dispose_bg = 0;  // Default.
+  FrameRect rect_bg;
+  WebPPicture sub_frame_bg;
+
+  WebPConfig config_ll = *config;
+  WebPConfig config_lossy = *config;
+  config_ll.lossless = 1;
+  config_lossy.lossless = 0;
+  enc->last_config = *config;
+  enc->last_config2 = config->lossless ? config_lossy : config_ll;
+
+  if (!WebPPictureInit(&sub_frame_none) || !WebPPictureInit(&sub_frame_bg)) {
+    return VP8_ENC_ERROR_INVALID_CONFIGURATION;
+  }
+
+  for (i = 0; i < CANDIDATE_COUNT; ++i) {
+    candidates[i].evaluate_ = 0;
+  }
+
+  // Change-rectangle assuming previous frame was DISPOSE_NONE.
+  GetSubRect(prev_canvas, curr_canvas, is_key_frame, is_first_frame,
+             &rect_none, &sub_frame_none);
+
+  if (dispose_bg_possible) {
+    // Change-rectangle assuming previous frame was DISPOSE_BACKGROUND.
+    WebPPicture* const prev_canvas_disposed = &enc->prev_canvas_disposed_;
+    CopyPixels(prev_canvas, prev_canvas_disposed);
+    DisposeFrameRectangle(WEBP_MUX_DISPOSE_BACKGROUND, &enc->prev_rect,
+                          prev_canvas_disposed);
+    GetSubRect(prev_canvas_disposed, curr_canvas, is_key_frame, is_first_frame,
+               &rect_bg, &sub_frame_bg);
+
+    if (enc->options_.minimize_size) {  // Try both dispose methods.
+      try_dispose_bg = 1;
+      try_dispose_none = 1;
+    } else if (RectArea(&rect_bg) < RectArea(&rect_none)) {
+      try_dispose_bg = 1;  // Pick DISPOSE_BACKGROUND.
+      try_dispose_none = 0;
+    }
+  }
+
+  if (try_dispose_none) {
+    error_code = GenerateCandidates(
+        enc, candidates, WEBP_MUX_DISPOSE_NONE, is_lossless, is_key_frame,
+        &rect_none, &sub_frame_none, duration, &config_ll, &config_lossy);
+    if (error_code != VP8_ENC_OK) goto Err;
+  }
+
+  if (try_dispose_bg) {
+    assert(!enc->is_first_frame_);
+    assert(dispose_bg_possible);
+    error_code =
+        GenerateCandidates(enc, candidates, WEBP_MUX_DISPOSE_BACKGROUND,
+                           is_lossless, is_key_frame, &rect_bg, &sub_frame_bg,
+                           duration, &config_ll, &config_lossy);
+    if (error_code != VP8_ENC_OK) goto Err;
+  }
+
+  PickBestCandidate(enc, candidates, is_key_frame, encoded_frame);
+
+  goto End;
+
+ Err:
+  for (i = 0; i < CANDIDATE_COUNT; ++i) {
+    if (candidates[i].evaluate_) {
+      WebPMemoryWriterClear(&candidates[i].mem_);
+    }
+  }
+
+ End:
+  WebPPictureFree(&sub_frame_none);
+  WebPPictureFree(&sub_frame_bg);
+  return error_code;
+}
+
+// Calculate the penalty incurred if we encode given frame as a key frame
+// instead of a sub-frame.
+static int64_t KeyFramePenalty(const EncodedFrame* const encoded_frame) {
+  return ((int64_t)encoded_frame->key_frame_.bitstream.size -
+          encoded_frame->sub_frame_.bitstream.size);
+}
+
+static int CacheFrame(WebPAnimEncoder* const enc, int duration,
+                      const WebPConfig* const config) {
+  int ok = 0;
+  WebPEncodingError error_code = VP8_ENC_OK;
+  const size_t position = enc->count_;
+  EncodedFrame* const encoded_frame = GetFrame(enc, position);
+
+  ++enc->count_;
+
+  if (enc->is_first_frame_) {  // Add this as a key-frame.
+    error_code =
+        SetFrame(enc, duration, config, 1, encoded_frame);
+    if (error_code != VP8_ENC_OK) {
+      goto End;
+    }
+    assert(position == 0 && enc->count_ == 1);
+    encoded_frame->is_key_frame_ = 1;
+    enc->flush_count_ = 0;
+    enc->count_since_key_frame_ = 0;
+    enc->prev_candidate_undecided_ = 0;
+  } else {
+    ++enc->count_since_key_frame_;
+    if (enc->count_since_key_frame_ <= enc->options_.kmin) {
+      // Add this as a frame rectangle.
+      error_code = SetFrame(enc, duration, config, 0, encoded_frame);
+      if (error_code != VP8_ENC_OK) {
+        goto End;
+      }
+      encoded_frame->is_key_frame_ = 0;
+      enc->flush_count_ = enc->count_ - 1;
+      enc->prev_candidate_undecided_ = 0;
+    } else {
+      int64_t curr_delta;
+
+      // Add this as a frame rectangle to enc.
+      error_code = SetFrame(enc, duration, config, 0, encoded_frame);
+      if (error_code != VP8_ENC_OK) goto End;
+
+      // Add this as a key-frame to enc, too.
+      error_code = SetFrame(enc, duration, config, 1, encoded_frame);
+      if (error_code != VP8_ENC_OK) goto End;
+
+      // Analyze size difference of the two variants.
+      curr_delta = KeyFramePenalty(encoded_frame);
+      if (curr_delta <= enc->best_delta_) {  // Pick this as the key-frame.
+        if (enc->keyframe_ != KEYFRAME_NONE) {
+          EncodedFrame* const old_keyframe = GetFrame(enc, enc->keyframe_);
+          assert(old_keyframe->is_key_frame_);
+          old_keyframe->is_key_frame_ = 0;
+        }
+        encoded_frame->is_key_frame_ = 1;
+        enc->keyframe_ = (int)position;
+        enc->best_delta_ = curr_delta;
+        enc->flush_count_ = enc->count_ - 1;  // We can flush previous frames.
+      } else {
+        encoded_frame->is_key_frame_ = 0;
+      }
+      // Note: We need '>=' below because when kmin and kmax are both zero,
+      // count_since_key_frame will always be > kmax.
+      if (enc->count_since_key_frame_ >= enc->options_.kmax) {
+        enc->flush_count_ = enc->count_ - 1;
+        enc->count_since_key_frame_ = 0;
+        enc->keyframe_ = KEYFRAME_NONE;
+        enc->best_delta_ = DELTA_INFINITY;
+      }
+      enc->prev_candidate_undecided_ = 1;
+    }
+  }
+
+  // Update previous to previous and previous canvases for next call.
+  CopyPixels(enc->curr_canvas_, &enc->prev_canvas_);
+  enc->is_first_frame_ = 0;
+  ok = 1;
+
+ End:
+  if (!ok) {
+    FrameRelease(encoded_frame);
+    --enc->count_;  // We reset the count, as the frame addition failed.
+    if (enc->options_.verbose) {
+      fprintf(stderr, "ERROR adding frame. WebPEncodingError: %d.\n",
+              error_code);
+    }
+  }
+  enc->curr_canvas_->error_code = error_code;   // report error_code
+  assert(ok || error_code != VP8_ENC_OK);
+  return ok;
+}
+
+static int FlushFrames(WebPAnimEncoder* const enc) {
+  while (enc->flush_count_ > 0) {
+    WebPMuxError err;
+    EncodedFrame* const curr = GetFrame(enc, 0);
+    const WebPMuxFrameInfo* const info =
+        curr->is_key_frame_ ? &curr->key_frame_ : &curr->sub_frame_;
+    assert(enc->mux_ != NULL);
+    err = WebPMuxPushFrame(enc->mux_, info, 1);
+    if (err != WEBP_MUX_OK) {
+      if (enc->options_.verbose) {
+        fprintf(stderr, "ERROR adding frame. WebPMuxError: %d.\n", err);
+      }
+      return 0;
+    }
+    if (enc->options_.verbose) {
+      fprintf(stderr,
+              "Added frame. offset:%d,%d duration:%d dispose:%d blend:%d\n",
+              info->x_offset, info->y_offset, info->duration,
+              info->dispose_method, info->blend_method);
+    }
+    ++enc->frame_count_;
+    FrameRelease(curr);
+    ++enc->start_;
+    --enc->flush_count_;
+    --enc->count_;
+    if (enc->keyframe_ != KEYFRAME_NONE) --enc->keyframe_;
+  }
+
+  if (enc->count_ == 1 && enc->start_ != 0) {
+    // Move enc->start to index 0.
+    const int enc_start_tmp = (int)enc->start_;
+    EncodedFrame temp = enc->encoded_frames_[0];
+    enc->encoded_frames_[0] = enc->encoded_frames_[enc_start_tmp];
+    enc->encoded_frames_[enc_start_tmp] = temp;
+    FrameRelease(&enc->encoded_frames_[enc_start_tmp]);
+    enc->start_ = 0;
+  }
+  return 1;
+}
+
+#undef DELTA_INFINITY
+#undef KEYFRAME_NONE
+
+int WebPAnimEncoderAdd(WebPAnimEncoder* enc, WebPPicture* frame, int duration,
+                       const WebPConfig* encoder_config) {
+  WebPConfig config;
+  if (enc == NULL || frame == NULL) {
+    return 0;
+  }
+  if (frame->width != enc->canvas_width_ ||
+      frame->height != enc->canvas_height_ || !frame->use_argb ||
+      duration < 0) {
+    frame->error_code = VP8_ENC_ERROR_INVALID_CONFIGURATION;
+    if (enc->options_.verbose) {
+      fprintf(stderr, "ERROR adding frame: Invalid input.\n");
+    }
+    return 0;
+  }
+  if (encoder_config != NULL) {
+    config = *encoder_config;
+  } else {
+    WebPConfigInit(&config);
+    config.lossless = 1;
+  }
+  assert(enc->curr_canvas_ == NULL);
+  enc->curr_canvas_ = frame;  // Store reference.
+  assert(enc->curr_canvas_copy_modified_ == 1);
+  CopyCurrentCanvas(enc);
+
+  if (!CacheFrame(enc, duration, &config)) {
+    return 0;
+  }
+  if (!FlushFrames(enc)) {
+    return 0;
+  }
+  enc->curr_canvas_ = NULL;
+  enc->curr_canvas_copy_modified_ = 1;
+  return 1;
+}
+
+// -----------------------------------------------------------------------------
+// Bitstream assembly.
+
+static int DecodeFrameOntoCanvas(const WebPMuxFrameInfo* const frame,
+                                 WebPPicture* const canvas) {
+  const WebPData* const image = &frame->bitstream;
+  WebPPicture sub_image;
+  WebPDecoderConfig config;
+  WebPInitDecoderConfig(&config);
+  WebPUtilClearPic(canvas, NULL);
+  if (WebPGetFeatures(image->bytes, image->size, &config.input) !=
+      VP8_STATUS_OK) {
+    return 0;
+  }
+  if (!WebPPictureView(canvas, frame->x_offset, frame->y_offset,
+                       config.input.width, config.input.height, &sub_image)) {
+    return 0;
+  }
+  config.output.is_external_memory = 1;
+  config.output.colorspace = MODE_BGRA;
+  config.output.u.RGBA.rgba = (uint8_t*)sub_image.argb;
+  config.output.u.RGBA.stride = sub_image.argb_stride * 4;
+  config.output.u.RGBA.size = config.output.u.RGBA.stride * sub_image.height;
+
+  if (WebPDecode(image->bytes, image->size, &config) != VP8_STATUS_OK) {
+    return 0;
+  }
+  return 1;
+}
+
+static int FrameToFullCanvas(WebPAnimEncoder* const enc,
+                             const WebPMuxFrameInfo* const frame,
+                             WebPData* const full_image) {
+  WebPPicture* const canvas_buf = &enc->curr_canvas_copy_;
+  WebPMemoryWriter mem1, mem2;
+  WebPMemoryWriterInit(&mem1);
+  WebPMemoryWriterInit(&mem2);
+
+  if (!DecodeFrameOntoCanvas(frame, canvas_buf)) goto Err;
+  if (!EncodeFrame(&enc->last_config, canvas_buf, &mem1)) goto Err;
+  GetEncodedData(&mem1, full_image);
+
+  if (enc->options_.allow_mixed) {
+    if (!EncodeFrame(&enc->last_config, canvas_buf, &mem2)) goto Err;
+    if (mem2.size < mem1.size) {
+      GetEncodedData(&mem2, full_image);
+      WebPMemoryWriterClear(&mem1);
+    } else {
+      WebPMemoryWriterClear(&mem2);
+    }
+  }
+  return 1;
+
+ Err:
+  WebPMemoryWriterClear(&mem1);
+  WebPMemoryWriterClear(&mem2);
+  return 0;
+}
+
+// Convert a single-frame animation to a non-animated image if appropriate.
+// TODO(urvang): Can we pick one of the two heuristically (based on frame
+// rectangle and/or presence of alpha)?
+static WebPMuxError OptimizeSingleFrame(WebPAnimEncoder* const enc,
+                                        WebPData* const webp_data) {
+  WebPMuxError err = WEBP_MUX_OK;
+  int canvas_width, canvas_height;
+  WebPMuxFrameInfo frame;
+  WebPData full_image;
+  WebPData webp_data2;
+  WebPMux* const mux = WebPMuxCreate(webp_data, 0);
+  if (mux == NULL) return WEBP_MUX_BAD_DATA;
+  assert(enc->frame_count_ == 1);
+  WebPDataInit(&frame.bitstream);
+  WebPDataInit(&full_image);
+  WebPDataInit(&webp_data2);
+
+  err = WebPMuxGetFrame(mux, 1, &frame);
+  if (err != WEBP_MUX_OK) goto End;
+  if (frame.id != WEBP_CHUNK_ANMF) goto End;  // Non-animation: nothing to do.
+  err = WebPMuxGetCanvasSize(mux, &canvas_width, &canvas_height);
+  if (err != WEBP_MUX_OK) goto End;
+  if (!FrameToFullCanvas(enc, &frame, &full_image)) {
+    err = WEBP_MUX_BAD_DATA;
+    goto End;
+  }
+  err = WebPMuxSetImage(mux, &full_image, 1);
+  if (err != WEBP_MUX_OK) goto End;
+  err = WebPMuxAssemble(mux, &webp_data2);
+  if (err != WEBP_MUX_OK) goto End;
+
+  if (webp_data2.size < webp_data->size) {  // Pick 'webp_data2' if smaller.
+    WebPDataClear(webp_data);
+    *webp_data = webp_data2;
+    WebPDataInit(&webp_data2);
+  }
+
+ End:
+  WebPDataClear(&frame.bitstream);
+  WebPDataClear(&full_image);
+  WebPMuxDelete(mux);
+  WebPDataClear(&webp_data2);
+  return err;
+}
+
+int WebPAnimEncoderAssemble(WebPAnimEncoder* enc, WebPData* webp_data) {
+  WebPMux* mux;
+  WebPMuxError err;
+
+  if (enc == NULL) {
+    return 0;
+  }
+  if (webp_data == NULL) {
+    if (enc->options_.verbose) {
+      fprintf(stderr, "ERROR assembling: NULL input\n");
+    }
+    return 0;
+  }
+
+  // Flush any remaining frames.
+  enc->flush_count_ = enc->count_;
+  if (!FlushFrames(enc)) {
+    return 0;
+  }
+
+  // Set definitive canvas size.
+  mux = enc->mux_;
+  err = WebPMuxSetCanvasSize(mux, enc->canvas_width_, enc->canvas_height_);
+  if (err != WEBP_MUX_OK) goto Err;
+
+  err = WebPMuxSetAnimationParams(mux, &enc->options_.anim_params);
+  if (err != WEBP_MUX_OK) goto Err;
+
+  // Assemble into a WebP bitstream.
+  err = WebPMuxAssemble(mux, webp_data);
+  if (err != WEBP_MUX_OK) goto Err;
+
+  if (enc->frame_count_ == 1) {
+    err = OptimizeSingleFrame(enc, webp_data);
+    if (err != WEBP_MUX_OK) goto Err;
+  }
+
+  return 1;
+
+ Err:
+  if (enc->options_.verbose) {
+    fprintf(stderr, "ERROR assembling WebP: %d\n", err);
+  }
+  return 0;
+}
+
+// -----------------------------------------------------------------------------
diff --git a/Source/LibWebP/src/mux/mux.muxedit.c b/Source/LibWebP/src/mux/mux.muxedit.c
new file mode 100644
index 0000000..87cc442
--- /dev/null
+++ b/Source/LibWebP/src/mux/mux.muxedit.c
@@ -0,0 +1,696 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Set and delete APIs for mux.
+//
+// Authors: Urvang (urvang at google.com)
+//          Vikas (vikasa at google.com)
+
+#include <assert.h>
+#include "./muxi.h"
+#include "../utils/utils.h"
+
+//------------------------------------------------------------------------------
+// Life of a mux object.
+
+static void MuxInit(WebPMux* const mux) {
+  assert(mux != NULL);
+  memset(mux, 0, sizeof(*mux));
+  mux->canvas_width_ = 0;     // just to be explicit
+  mux->canvas_height_ = 0;
+}
+
+WebPMux* WebPNewInternal(int version) {
+  if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_MUX_ABI_VERSION)) {
+    return NULL;
+  } else {
+    WebPMux* const mux = (WebPMux*)WebPSafeMalloc(1ULL, sizeof(WebPMux));
+    if (mux != NULL) MuxInit(mux);
+    return mux;
+  }
+}
+
+// Delete all images in 'wpi_list'.
+static void DeleteAllImages(WebPMuxImage** const wpi_list) {
+  while (*wpi_list != NULL) {
+    *wpi_list = MuxImageDelete(*wpi_list);
+  }
+}
+
+static void MuxRelease(WebPMux* const mux) {
+  assert(mux != NULL);
+  DeleteAllImages(&mux->images_);
+  ChunkListDelete(&mux->vp8x_);
+  ChunkListDelete(&mux->iccp_);
+  ChunkListDelete(&mux->anim_);
+  ChunkListDelete(&mux->exif_);
+  ChunkListDelete(&mux->xmp_);
+  ChunkListDelete(&mux->unknown_);
+}
+
+void WebPMuxDelete(WebPMux* mux) {
+  if (mux != NULL) {
+    MuxRelease(mux);
+    WebPSafeFree(mux);
+  }
+}
+
+//------------------------------------------------------------------------------
+// Helper method(s).
+
+// Handy MACRO, makes MuxSet() very symmetric to MuxGet().
+#define SWITCH_ID_LIST(INDEX, LIST)                                            \
+  if (idx == (INDEX)) {                                                        \
+    err = ChunkAssignData(&chunk, data, copy_data, tag);                       \
+    if (err == WEBP_MUX_OK) {                                                  \
+      err = ChunkSetNth(&chunk, (LIST), nth);                                  \
+    }                                                                          \
+    return err;                                                                \
+  }
+
+static WebPMuxError MuxSet(WebPMux* const mux, uint32_t tag, uint32_t nth,
+                           const WebPData* const data, int copy_data) {
+  WebPChunk chunk;
+  WebPMuxError err = WEBP_MUX_NOT_FOUND;
+  const CHUNK_INDEX idx = ChunkGetIndexFromTag(tag);
+  assert(mux != NULL);
+  assert(!IsWPI(kChunks[idx].id));
+
+  ChunkInit(&chunk);
+  SWITCH_ID_LIST(IDX_VP8X,    &mux->vp8x_);
+  SWITCH_ID_LIST(IDX_ICCP,    &mux->iccp_);
+  SWITCH_ID_LIST(IDX_ANIM,    &mux->anim_);
+  SWITCH_ID_LIST(IDX_EXIF,    &mux->exif_);
+  SWITCH_ID_LIST(IDX_XMP,     &mux->xmp_);
+  SWITCH_ID_LIST(IDX_UNKNOWN, &mux->unknown_);
+  return err;
+}
+#undef SWITCH_ID_LIST
+
+// Create data for frame/fragment given image data, offsets and duration.
+static WebPMuxError CreateFrameFragmentData(
+    int width, int height, const WebPMuxFrameInfo* const info, int is_frame,
+    WebPData* const frame_frgm) {
+  uint8_t* frame_frgm_bytes;
+  const size_t frame_frgm_size = kChunks[is_frame ? IDX_ANMF : IDX_FRGM].size;
+
+  assert(width > 0 && height > 0 && info->duration >= 0);
+  assert(info->dispose_method == (info->dispose_method & 1));
+  // Note: assertion on upper bounds is done in PutLE24().
+
+  frame_frgm_bytes = (uint8_t*)WebPSafeMalloc(1ULL, frame_frgm_size);
+  if (frame_frgm_bytes == NULL) return WEBP_MUX_MEMORY_ERROR;
+
+  PutLE24(frame_frgm_bytes + 0, info->x_offset / 2);
+  PutLE24(frame_frgm_bytes + 3, info->y_offset / 2);
+
+  if (is_frame) {
+    PutLE24(frame_frgm_bytes + 6, width - 1);
+    PutLE24(frame_frgm_bytes + 9, height - 1);
+    PutLE24(frame_frgm_bytes + 12, info->duration);
+    frame_frgm_bytes[15] =
+        (info->blend_method == WEBP_MUX_NO_BLEND ? 2 : 0) |
+        (info->dispose_method == WEBP_MUX_DISPOSE_BACKGROUND ? 1 : 0);
+  }
+
+  frame_frgm->bytes = frame_frgm_bytes;
+  frame_frgm->size = frame_frgm_size;
+  return WEBP_MUX_OK;
+}
+
+// Outputs image data given a bitstream. The bitstream can either be a
+// single-image WebP file or raw VP8/VP8L data.
+// Also outputs 'is_lossless' to be true if the given bitstream is lossless.
+static WebPMuxError GetImageData(const WebPData* const bitstream,
+                                 WebPData* const image, WebPData* const alpha,
+                                 int* const is_lossless) {
+  WebPDataInit(alpha);  // Default: no alpha.
+  if (bitstream->size < TAG_SIZE ||
+      memcmp(bitstream->bytes, "RIFF", TAG_SIZE)) {
+    // It is NOT webp file data. Return input data as is.
+    *image = *bitstream;
+  } else {
+    // It is webp file data. Extract image data from it.
+    const WebPMuxImage* wpi;
+    WebPMux* const mux = WebPMuxCreate(bitstream, 0);
+    if (mux == NULL) return WEBP_MUX_BAD_DATA;
+    wpi = mux->images_;
+    assert(wpi != NULL && wpi->img_ != NULL);
+    *image = wpi->img_->data_;
+    if (wpi->alpha_ != NULL) {
+      *alpha = wpi->alpha_->data_;
+    }
+    WebPMuxDelete(mux);
+  }
+  *is_lossless = VP8LCheckSignature(image->bytes, image->size);
+  return WEBP_MUX_OK;
+}
+
+static WebPMuxError DeleteChunks(WebPChunk** chunk_list, uint32_t tag) {
+  WebPMuxError err = WEBP_MUX_NOT_FOUND;
+  assert(chunk_list);
+  while (*chunk_list) {
+    WebPChunk* const chunk = *chunk_list;
+    if (chunk->tag_ == tag) {
+      *chunk_list = ChunkDelete(chunk);
+      err = WEBP_MUX_OK;
+    } else {
+      chunk_list = &chunk->next_;
+    }
+  }
+  return err;
+}
+
+static WebPMuxError MuxDeleteAllNamedData(WebPMux* const mux, uint32_t tag) {
+  const WebPChunkId id = ChunkGetIdFromTag(tag);
+  assert(mux != NULL);
+  if (IsWPI(id)) return WEBP_MUX_INVALID_ARGUMENT;
+  return DeleteChunks(MuxGetChunkListFromId(mux, id), tag);
+}
+
+//------------------------------------------------------------------------------
+// Set API(s).
+
+WebPMuxError WebPMuxSetChunk(WebPMux* mux, const char fourcc[4],
+                             const WebPData* chunk_data, int copy_data) {
+  uint32_t tag;
+  WebPMuxError err;
+  if (mux == NULL || fourcc == NULL || chunk_data == NULL ||
+      chunk_data->bytes == NULL || chunk_data->size > MAX_CHUNK_PAYLOAD) {
+    return WEBP_MUX_INVALID_ARGUMENT;
+  }
+  tag = ChunkGetTagFromFourCC(fourcc);
+
+  // Delete existing chunk(s) with the same 'fourcc'.
+  err = MuxDeleteAllNamedData(mux, tag);
+  if (err != WEBP_MUX_OK && err != WEBP_MUX_NOT_FOUND) return err;
+
+  // Add the given chunk.
+  return MuxSet(mux, tag, 1, chunk_data, copy_data);
+}
+
+// Creates a chunk from given 'data' and sets it as 1st chunk in 'chunk_list'.
+static WebPMuxError AddDataToChunkList(
+    const WebPData* const data, int copy_data, uint32_t tag,
+    WebPChunk** chunk_list) {
+  WebPChunk chunk;
+  WebPMuxError err;
+  ChunkInit(&chunk);
+  err = ChunkAssignData(&chunk, data, copy_data, tag);
+  if (err != WEBP_MUX_OK) goto Err;
+  err = ChunkSetNth(&chunk, chunk_list, 1);
+  if (err != WEBP_MUX_OK) goto Err;
+  return WEBP_MUX_OK;
+ Err:
+  ChunkRelease(&chunk);
+  return err;
+}
+
+// Extracts image & alpha data from the given bitstream and then sets wpi.alpha_
+// and wpi.img_ appropriately.
+static WebPMuxError SetAlphaAndImageChunks(
+    const WebPData* const bitstream, int copy_data, WebPMuxImage* const wpi) {
+  int is_lossless = 0;
+  WebPData image, alpha;
+  WebPMuxError err = GetImageData(bitstream, &image, &alpha, &is_lossless);
+  const int image_tag =
+      is_lossless ? kChunks[IDX_VP8L].tag : kChunks[IDX_VP8].tag;
+  if (err != WEBP_MUX_OK) return err;
+  if (alpha.bytes != NULL) {
+    err = AddDataToChunkList(&alpha, copy_data, kChunks[IDX_ALPHA].tag,
+                             &wpi->alpha_);
+    if (err != WEBP_MUX_OK) return err;
+  }
+  err = AddDataToChunkList(&image, copy_data, image_tag, &wpi->img_);
+  if (err != WEBP_MUX_OK) return err;
+  return MuxImageFinalize(wpi) ? WEBP_MUX_OK : WEBP_MUX_INVALID_ARGUMENT;
+}
+
+WebPMuxError WebPMuxSetImage(WebPMux* mux, const WebPData* bitstream,
+                             int copy_data) {
+  WebPMuxImage wpi;
+  WebPMuxError err;
+
+  // Sanity checks.
+  if (mux == NULL || bitstream == NULL || bitstream->bytes == NULL ||
+      bitstream->size > MAX_CHUNK_PAYLOAD) {
+    return WEBP_MUX_INVALID_ARGUMENT;
+  }
+
+  if (mux->images_ != NULL) {
+    // Only one 'simple image' can be added in mux. So, remove present images.
+    DeleteAllImages(&mux->images_);
+  }
+
+  MuxImageInit(&wpi);
+  err = SetAlphaAndImageChunks(bitstream, copy_data, &wpi);
+  if (err != WEBP_MUX_OK) goto Err;
+
+  // Add this WebPMuxImage to mux.
+  err = MuxImagePush(&wpi, &mux->images_);
+  if (err != WEBP_MUX_OK) goto Err;
+
+  // All is well.
+  return WEBP_MUX_OK;
+
+ Err:  // Something bad happened.
+  MuxImageRelease(&wpi);
+  return err;
+}
+
+WebPMuxError WebPMuxPushFrame(WebPMux* mux, const WebPMuxFrameInfo* frame,
+                              int copy_data) {
+  WebPMuxImage wpi;
+  WebPMuxError err;
+  int is_frame;
+  const WebPData* const bitstream = &frame->bitstream;
+
+  // Sanity checks.
+  if (mux == NULL || frame == NULL) return WEBP_MUX_INVALID_ARGUMENT;
+
+  is_frame = (frame->id == WEBP_CHUNK_ANMF);
+  if (!(is_frame || (frame->id == WEBP_CHUNK_FRGM))) {
+    return WEBP_MUX_INVALID_ARGUMENT;
+  }
+  if (frame->id == WEBP_CHUNK_FRGM) {     // Dead experiment.
+    return WEBP_MUX_INVALID_ARGUMENT;
+  }
+
+  if (bitstream->bytes == NULL || bitstream->size > MAX_CHUNK_PAYLOAD) {
+    return WEBP_MUX_INVALID_ARGUMENT;
+  }
+
+  if (mux->images_ != NULL) {
+    const WebPMuxImage* const image = mux->images_;
+    const uint32_t image_id = (image->header_ != NULL) ?
+        ChunkGetIdFromTag(image->header_->tag_) : WEBP_CHUNK_IMAGE;
+    if (image_id != frame->id) {
+      return WEBP_MUX_INVALID_ARGUMENT;  // Conflicting frame types.
+    }
+  }
+
+  MuxImageInit(&wpi);
+  err = SetAlphaAndImageChunks(bitstream, copy_data, &wpi);
+  if (err != WEBP_MUX_OK) goto Err;
+  assert(wpi.img_ != NULL);  // As SetAlphaAndImageChunks() was successful.
+
+  {
+    WebPData frame_frgm;
+    const uint32_t tag = kChunks[is_frame ? IDX_ANMF : IDX_FRGM].tag;
+    WebPMuxFrameInfo tmp = *frame;
+    tmp.x_offset &= ~1;  // Snap offsets to even.
+    tmp.y_offset &= ~1;
+    if (!is_frame) {  // Reset unused values.
+      tmp.duration = 1;
+      tmp.dispose_method = WEBP_MUX_DISPOSE_NONE;
+      tmp.blend_method = WEBP_MUX_BLEND;
+    }
+    if (tmp.x_offset < 0 || tmp.x_offset >= MAX_POSITION_OFFSET ||
+        tmp.y_offset < 0 || tmp.y_offset >= MAX_POSITION_OFFSET ||
+        (tmp.duration < 0 || tmp.duration >= MAX_DURATION) ||
+        tmp.dispose_method != (tmp.dispose_method & 1)) {
+      err = WEBP_MUX_INVALID_ARGUMENT;
+      goto Err;
+    }
+    err = CreateFrameFragmentData(wpi.width_, wpi.height_, &tmp, is_frame,
+                                  &frame_frgm);
+    if (err != WEBP_MUX_OK) goto Err;
+    // Add frame/fragment chunk (with copy_data = 1).
+    err = AddDataToChunkList(&frame_frgm, 1, tag, &wpi.header_);
+    WebPDataClear(&frame_frgm);  // frame_frgm owned by wpi.header_ now.
+    if (err != WEBP_MUX_OK) goto Err;
+  }
+
+  // Add this WebPMuxImage to mux.
+  err = MuxImagePush(&wpi, &mux->images_);
+  if (err != WEBP_MUX_OK) goto Err;
+
+  // All is well.
+  return WEBP_MUX_OK;
+
+ Err:  // Something bad happened.
+  MuxImageRelease(&wpi);
+  return err;
+}
+
+WebPMuxError WebPMuxSetAnimationParams(WebPMux* mux,
+                                       const WebPMuxAnimParams* params) {
+  WebPMuxError err;
+  uint8_t data[ANIM_CHUNK_SIZE];
+  const WebPData anim = { data, ANIM_CHUNK_SIZE };
+
+  if (mux == NULL || params == NULL) return WEBP_MUX_INVALID_ARGUMENT;
+  if (params->loop_count < 0 || params->loop_count >= MAX_LOOP_COUNT) {
+    return WEBP_MUX_INVALID_ARGUMENT;
+  }
+
+  // Delete any existing ANIM chunk(s).
+  err = MuxDeleteAllNamedData(mux, kChunks[IDX_ANIM].tag);
+  if (err != WEBP_MUX_OK && err != WEBP_MUX_NOT_FOUND) return err;
+
+  // Set the animation parameters.
+  PutLE32(data, params->bgcolor);
+  PutLE16(data + 4, params->loop_count);
+  return MuxSet(mux, kChunks[IDX_ANIM].tag, 1, &anim, 1);
+}
+
+WebPMuxError WebPMuxSetCanvasSize(WebPMux* mux,
+                                  int width, int height) {
+  WebPMuxError err;
+  if (mux == NULL) {
+    return WEBP_MUX_INVALID_ARGUMENT;
+  }
+  if (width < 0 || height < 0 ||
+      width > MAX_CANVAS_SIZE || height > MAX_CANVAS_SIZE) {
+    return WEBP_MUX_INVALID_ARGUMENT;
+  }
+  if (width * (uint64_t)height >= MAX_IMAGE_AREA) {
+    return WEBP_MUX_INVALID_ARGUMENT;
+  }
+  if ((width * height) == 0 && (width | height) != 0) {
+    // one of width / height is zero, but not both -> invalid!
+    return WEBP_MUX_INVALID_ARGUMENT;
+  }
+  // If we already assembled a VP8X chunk, invalidate it.
+  err = MuxDeleteAllNamedData(mux, kChunks[IDX_VP8X].tag);
+  if (err != WEBP_MUX_OK && err != WEBP_MUX_NOT_FOUND) return err;
+
+  mux->canvas_width_ = width;
+  mux->canvas_height_ = height;
+  return WEBP_MUX_OK;
+}
+
+//------------------------------------------------------------------------------
+// Delete API(s).
+
+WebPMuxError WebPMuxDeleteChunk(WebPMux* mux, const char fourcc[4]) {
+  if (mux == NULL || fourcc == NULL) return WEBP_MUX_INVALID_ARGUMENT;
+  return MuxDeleteAllNamedData(mux, ChunkGetTagFromFourCC(fourcc));
+}
+
+WebPMuxError WebPMuxDeleteFrame(WebPMux* mux, uint32_t nth) {
+  if (mux == NULL) return WEBP_MUX_INVALID_ARGUMENT;
+  return MuxImageDeleteNth(&mux->images_, nth);
+}
+
+//------------------------------------------------------------------------------
+// Assembly of the WebP RIFF file.
+
+static WebPMuxError GetFrameFragmentInfo(
+    const WebPChunk* const frame_frgm_chunk,
+    int* const x_offset, int* const y_offset, int* const duration) {
+  const uint32_t tag = frame_frgm_chunk->tag_;
+  const int is_frame = (tag == kChunks[IDX_ANMF].tag);
+  const WebPData* const data = &frame_frgm_chunk->data_;
+  const size_t expected_data_size =
+      is_frame ? ANMF_CHUNK_SIZE : FRGM_CHUNK_SIZE;
+  assert(frame_frgm_chunk != NULL);
+  assert(tag == kChunks[IDX_ANMF].tag || tag ==  kChunks[IDX_FRGM].tag);
+  if (data->size != expected_data_size) return WEBP_MUX_INVALID_ARGUMENT;
+
+  *x_offset = 2 * GetLE24(data->bytes + 0);
+  *y_offset = 2 * GetLE24(data->bytes + 3);
+  if (is_frame) *duration = GetLE24(data->bytes + 12);
+  return WEBP_MUX_OK;
+}
+
+static WebPMuxError GetImageInfo(const WebPMuxImage* const wpi,
+                                 int* const x_offset, int* const y_offset,
+                                 int* const duration,
+                                 int* const width, int* const height) {
+  const WebPChunk* const frame_frgm_chunk = wpi->header_;
+  WebPMuxError err;
+  assert(wpi != NULL);
+  assert(frame_frgm_chunk != NULL);
+
+  // Get offsets and duration from ANMF/FRGM chunk.
+  err = GetFrameFragmentInfo(frame_frgm_chunk, x_offset, y_offset, duration);
+  if (err != WEBP_MUX_OK) return err;
+
+  // Get width and height from VP8/VP8L chunk.
+  if (width != NULL) *width = wpi->width_;
+  if (height != NULL) *height = wpi->height_;
+  return WEBP_MUX_OK;
+}
+
+// Returns the tightest dimension for the canvas considering the image list.
+static WebPMuxError GetAdjustedCanvasSize(const WebPMux* const mux,
+                                          uint32_t flags,
+                                          int* const width, int* const height) {
+  WebPMuxImage* wpi = NULL;
+  assert(mux != NULL);
+  assert(width != NULL && height != NULL);
+
+  wpi = mux->images_;
+  assert(wpi != NULL);
+  assert(wpi->img_ != NULL);
+
+  if (wpi->next_ != NULL) {
+    int max_x = 0;
+    int max_y = 0;
+    int64_t image_area = 0;
+    // if we have a chain of wpi's, header_ is necessarily set
+    assert(wpi->header_ != NULL);
+    // Aggregate the bounding box for animation frames & fragmented images.
+    for (; wpi != NULL; wpi = wpi->next_) {
+      int x_offset = 0, y_offset = 0, duration = 0, w = 0, h = 0;
+      const WebPMuxError err = GetImageInfo(wpi, &x_offset, &y_offset,
+                                            &duration, &w, &h);
+      const int max_x_pos = x_offset + w;
+      const int max_y_pos = y_offset + h;
+      if (err != WEBP_MUX_OK) return err;
+      assert(x_offset < MAX_POSITION_OFFSET);
+      assert(y_offset < MAX_POSITION_OFFSET);
+
+      if (max_x_pos > max_x) max_x = max_x_pos;
+      if (max_y_pos > max_y) max_y = max_y_pos;
+      image_area += w * h;
+    }
+    *width = max_x;
+    *height = max_y;
+    // Crude check to validate that there are no image overlaps/holes for
+    // fragmented images. Check that the aggregated image area for individual
+    // fragments exactly matches the image area of the constructed canvas.
+    // However, the area-match is necessary but not sufficient condition.
+    if ((flags & FRAGMENTS_FLAG) && (image_area != (max_x * max_y))) {
+      *width = 0;
+      *height = 0;
+      return WEBP_MUX_INVALID_ARGUMENT;
+    }
+  } else {
+    // For a single image, canvas dimensions are same as image dimensions.
+    *width = wpi->width_;
+    *height = wpi->height_;
+  }
+  return WEBP_MUX_OK;
+}
+
+// VP8X format:
+// Total Size : 10,
+// Flags  : 4 bytes,
+// Width  : 3 bytes,
+// Height : 3 bytes.
+static WebPMuxError CreateVP8XChunk(WebPMux* const mux) {
+  WebPMuxError err = WEBP_MUX_OK;
+  uint32_t flags = 0;
+  int width = 0;
+  int height = 0;
+  uint8_t data[VP8X_CHUNK_SIZE];
+  const WebPData vp8x = { data, VP8X_CHUNK_SIZE };
+  const WebPMuxImage* images = NULL;
+
+  assert(mux != NULL);
+  images = mux->images_;  // First image.
+  if (images == NULL || images->img_ == NULL ||
+      images->img_->data_.bytes == NULL) {
+    return WEBP_MUX_INVALID_ARGUMENT;
+  }
+
+  // If VP8X chunk(s) is(are) already present, remove them (and later add new
+  // VP8X chunk with updated flags).
+  err = MuxDeleteAllNamedData(mux, kChunks[IDX_VP8X].tag);
+  if (err != WEBP_MUX_OK && err != WEBP_MUX_NOT_FOUND) return err;
+
+  // Set flags.
+  if (mux->iccp_ != NULL && mux->iccp_->data_.bytes != NULL) {
+    flags |= ICCP_FLAG;
+  }
+  if (mux->exif_ != NULL && mux->exif_->data_.bytes != NULL) {
+    flags |= EXIF_FLAG;
+  }
+  if (mux->xmp_ != NULL && mux->xmp_->data_.bytes != NULL) {
+    flags |= XMP_FLAG;
+  }
+  if (images->header_ != NULL) {
+    if (images->header_->tag_ == kChunks[IDX_FRGM].tag) {
+      // This is a fragmented image.
+      flags |= FRAGMENTS_FLAG;
+    } else if (images->header_->tag_ == kChunks[IDX_ANMF].tag) {
+      // This is an image with animation.
+      flags |= ANIMATION_FLAG;
+    }
+  }
+  if (MuxImageCount(images, WEBP_CHUNK_ALPHA) > 0) {
+    flags |= ALPHA_FLAG;  // Some images have an alpha channel.
+  }
+
+  err = GetAdjustedCanvasSize(mux, flags, &width, &height);
+  if (err != WEBP_MUX_OK) return err;
+
+  if (width <= 0 || height <= 0) {
+    return WEBP_MUX_INVALID_ARGUMENT;
+  }
+  if (width > MAX_CANVAS_SIZE || height > MAX_CANVAS_SIZE) {
+    return WEBP_MUX_INVALID_ARGUMENT;
+  }
+
+  if (mux->canvas_width_ != 0 || mux->canvas_height_ != 0) {
+    if (width > mux->canvas_width_ || height > mux->canvas_height_) {
+      return WEBP_MUX_INVALID_ARGUMENT;
+    }
+    width = mux->canvas_width_;
+    height = mux->canvas_height_;
+  }
+
+  if (flags == 0) {
+    // For Simple Image, VP8X chunk should not be added.
+    return WEBP_MUX_OK;
+  }
+
+  if (MuxHasAlpha(images)) {
+    // This means some frames explicitly/implicitly contain alpha.
+    // Note: This 'flags' update must NOT be done for a lossless image
+    // without a VP8X chunk!
+    flags |= ALPHA_FLAG;
+  }
+
+  PutLE32(data + 0, flags);   // VP8X chunk flags.
+  PutLE24(data + 4, width - 1);   // canvas width.
+  PutLE24(data + 7, height - 1);  // canvas height.
+
+  return MuxSet(mux, kChunks[IDX_VP8X].tag, 1, &vp8x, 1);
+}
+
+// Cleans up 'mux' by removing any unnecessary chunks.
+static WebPMuxError MuxCleanup(WebPMux* const mux) {
+  int num_frames;
+  int num_fragments;
+  int num_anim_chunks;
+
+  // If we have an image with a single fragment or frame, and its rectangle
+  // covers the whole canvas, convert it to a non-animated non-fragmented image
+  // (to avoid writing FRGM/ANMF chunk unnecessarily).
+  WebPMuxError err = WebPMuxNumChunks(mux, kChunks[IDX_ANMF].id, &num_frames);
+  if (err != WEBP_MUX_OK) return err;
+  err = WebPMuxNumChunks(mux, kChunks[IDX_FRGM].id, &num_fragments);
+  if (err != WEBP_MUX_OK) return err;
+  if (num_frames == 1 || num_fragments == 1) {
+    WebPMuxImage* frame_frag;
+    err = MuxImageGetNth((const WebPMuxImage**)&mux->images_, 1, &frame_frag);
+    assert(err == WEBP_MUX_OK);  // We know that one frame/fragment does exist.
+    assert(frame_frag != NULL);
+    if (frame_frag->header_ != NULL &&
+        ((mux->canvas_width_ == 0 && mux->canvas_height_ == 0) ||
+         (frame_frag->width_ == mux->canvas_width_ &&
+          frame_frag->height_ == mux->canvas_height_))) {
+      assert(frame_frag->header_->tag_ == kChunks[IDX_ANMF].tag ||
+             frame_frag->header_->tag_ == kChunks[IDX_FRGM].tag);
+      ChunkDelete(frame_frag->header_);  // Removes ANMF/FRGM chunk.
+      frame_frag->header_ = NULL;
+      num_frames = 0;
+      num_fragments = 0;
+    }
+  }
+  // Remove ANIM chunk if this is a non-animated image.
+  err = WebPMuxNumChunks(mux, kChunks[IDX_ANIM].id, &num_anim_chunks);
+  if (err != WEBP_MUX_OK) return err;
+  if (num_anim_chunks >= 1 && num_frames == 0) {
+    err = MuxDeleteAllNamedData(mux, kChunks[IDX_ANIM].tag);
+    if (err != WEBP_MUX_OK) return err;
+  }
+  return WEBP_MUX_OK;
+}
+
+// Total size of a list of images.
+static size_t ImageListDiskSize(const WebPMuxImage* wpi_list) {
+  size_t size = 0;
+  while (wpi_list != NULL) {
+    size += MuxImageDiskSize(wpi_list);
+    wpi_list = wpi_list->next_;
+  }
+  return size;
+}
+
+// Write out the given list of images into 'dst'.
+static uint8_t* ImageListEmit(const WebPMuxImage* wpi_list, uint8_t* dst) {
+  while (wpi_list != NULL) {
+    dst = MuxImageEmit(wpi_list, dst);
+    wpi_list = wpi_list->next_;
+  }
+  return dst;
+}
+
+WebPMuxError WebPMuxAssemble(WebPMux* mux, WebPData* assembled_data) {
+  size_t size = 0;
+  uint8_t* data = NULL;
+  uint8_t* dst = NULL;
+  WebPMuxError err;
+
+  if (assembled_data == NULL) {
+    return WEBP_MUX_INVALID_ARGUMENT;
+  }
+  // Clean up returned data, in case something goes wrong.
+  memset(assembled_data, 0, sizeof(*assembled_data));
+
+  if (mux == NULL) {
+    return WEBP_MUX_INVALID_ARGUMENT;
+  }
+
+  // Finalize mux.
+  err = MuxCleanup(mux);
+  if (err != WEBP_MUX_OK) return err;
+  err = CreateVP8XChunk(mux);
+  if (err != WEBP_MUX_OK) return err;
+
+  // Allocate data.
+  size = ChunkListDiskSize(mux->vp8x_) + ChunkListDiskSize(mux->iccp_)
+       + ChunkListDiskSize(mux->anim_) + ImageListDiskSize(mux->images_)
+       + ChunkListDiskSize(mux->exif_) + ChunkListDiskSize(mux->xmp_)
+       + ChunkListDiskSize(mux->unknown_) + RIFF_HEADER_SIZE;
+
+  data = (uint8_t*)WebPSafeMalloc(1ULL, size);
+  if (data == NULL) return WEBP_MUX_MEMORY_ERROR;
+
+  // Emit header & chunks.
+  dst = MuxEmitRiffHeader(data, size);
+  dst = ChunkListEmit(mux->vp8x_, dst);
+  dst = ChunkListEmit(mux->iccp_, dst);
+  dst = ChunkListEmit(mux->anim_, dst);
+  dst = ImageListEmit(mux->images_, dst);
+  dst = ChunkListEmit(mux->exif_, dst);
+  dst = ChunkListEmit(mux->xmp_, dst);
+  dst = ChunkListEmit(mux->unknown_, dst);
+  assert(dst == data + size);
+
+  // Validate mux.
+  err = MuxValidate(mux);
+  if (err != WEBP_MUX_OK) {
+    WebPSafeFree(data);
+    data = NULL;
+    size = 0;
+  }
+
+  // Finalize data.
+  assembled_data->bytes = data;
+  assembled_data->size = size;
+
+  return err;
+}
+
+//------------------------------------------------------------------------------
diff --git a/Source/LibWebP/src/mux/mux.muxinternal.c b/Source/LibWebP/src/mux/mux.muxinternal.c
new file mode 100644
index 0000000..b26c15c
--- /dev/null
+++ b/Source/LibWebP/src/mux/mux.muxinternal.c
@@ -0,0 +1,551 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Internal objects and utils for mux.
+//
+// Authors: Urvang (urvang at google.com)
+//          Vikas (vikasa at google.com)
+
+#include <assert.h>
+#include "./muxi.h"
+#include "../utils/utils.h"
+
+#define UNDEFINED_CHUNK_SIZE (-1)
+
+const ChunkInfo kChunks[] = {
+  { MKFOURCC('V', 'P', '8', 'X'),  WEBP_CHUNK_VP8X,    VP8X_CHUNK_SIZE },
+  { MKFOURCC('I', 'C', 'C', 'P'),  WEBP_CHUNK_ICCP,    UNDEFINED_CHUNK_SIZE },
+  { MKFOURCC('A', 'N', 'I', 'M'),  WEBP_CHUNK_ANIM,    ANIM_CHUNK_SIZE },
+  { MKFOURCC('A', 'N', 'M', 'F'),  WEBP_CHUNK_ANMF,    ANMF_CHUNK_SIZE },
+  { MKFOURCC('F', 'R', 'G', 'M'),  WEBP_CHUNK_FRGM,    FRGM_CHUNK_SIZE },
+  { MKFOURCC('A', 'L', 'P', 'H'),  WEBP_CHUNK_ALPHA,   UNDEFINED_CHUNK_SIZE },
+  { MKFOURCC('V', 'P', '8', ' '),  WEBP_CHUNK_IMAGE,   UNDEFINED_CHUNK_SIZE },
+  { MKFOURCC('V', 'P', '8', 'L'),  WEBP_CHUNK_IMAGE,   UNDEFINED_CHUNK_SIZE },
+  { MKFOURCC('E', 'X', 'I', 'F'),  WEBP_CHUNK_EXIF,    UNDEFINED_CHUNK_SIZE },
+  { MKFOURCC('X', 'M', 'P', ' '),  WEBP_CHUNK_XMP,     UNDEFINED_CHUNK_SIZE },
+  { NIL_TAG,                       WEBP_CHUNK_UNKNOWN, UNDEFINED_CHUNK_SIZE },
+
+  { NIL_TAG,                       WEBP_CHUNK_NIL,     UNDEFINED_CHUNK_SIZE }
+};
+
+//------------------------------------------------------------------------------
+
+int WebPGetMuxVersion(void) {
+  return (MUX_MAJ_VERSION << 16) | (MUX_MIN_VERSION << 8) | MUX_REV_VERSION;
+}
+
+//------------------------------------------------------------------------------
+// Life of a chunk object.
+
+void ChunkInit(WebPChunk* const chunk) {
+  assert(chunk);
+  memset(chunk, 0, sizeof(*chunk));
+  chunk->tag_ = NIL_TAG;
+}
+
+WebPChunk* ChunkRelease(WebPChunk* const chunk) {
+  WebPChunk* next;
+  if (chunk == NULL) return NULL;
+  if (chunk->owner_) {
+    WebPDataClear(&chunk->data_);
+  }
+  next = chunk->next_;
+  ChunkInit(chunk);
+  return next;
+}
+
+//------------------------------------------------------------------------------
+// Chunk misc methods.
+
+CHUNK_INDEX ChunkGetIndexFromTag(uint32_t tag) {
+  int i;
+  for (i = 0; kChunks[i].tag != NIL_TAG; ++i) {
+    if (tag == kChunks[i].tag) return (CHUNK_INDEX)i;
+  }
+  return IDX_UNKNOWN;
+}
+
+WebPChunkId ChunkGetIdFromTag(uint32_t tag) {
+  int i;
+  for (i = 0; kChunks[i].tag != NIL_TAG; ++i) {
+    if (tag == kChunks[i].tag) return kChunks[i].id;
+  }
+  return WEBP_CHUNK_UNKNOWN;
+}
+
+uint32_t ChunkGetTagFromFourCC(const char fourcc[4]) {
+  return MKFOURCC(fourcc[0], fourcc[1], fourcc[2], fourcc[3]);
+}
+
+CHUNK_INDEX ChunkGetIndexFromFourCC(const char fourcc[4]) {
+  const uint32_t tag = ChunkGetTagFromFourCC(fourcc);
+  return ChunkGetIndexFromTag(tag);
+}
+
+//------------------------------------------------------------------------------
+// Chunk search methods.
+
+// Returns next chunk in the chunk list with the given tag.
+static WebPChunk* ChunkSearchNextInList(WebPChunk* chunk, uint32_t tag) {
+  while (chunk != NULL && chunk->tag_ != tag) {
+    chunk = chunk->next_;
+  }
+  return chunk;
+}
+
+WebPChunk* ChunkSearchList(WebPChunk* first, uint32_t nth, uint32_t tag) {
+  uint32_t iter = nth;
+  first = ChunkSearchNextInList(first, tag);
+  if (first == NULL) return NULL;
+
+  while (--iter != 0) {
+    WebPChunk* next_chunk = ChunkSearchNextInList(first->next_, tag);
+    if (next_chunk == NULL) break;
+    first = next_chunk;
+  }
+  return ((nth > 0) && (iter > 0)) ? NULL : first;
+}
+
+// Outputs a pointer to 'prev_chunk->next_',
+//   where 'prev_chunk' is the pointer to the chunk at position (nth - 1).
+// Returns true if nth chunk was found.
+static int ChunkSearchListToSet(WebPChunk** chunk_list, uint32_t nth,
+                                WebPChunk*** const location) {
+  uint32_t count = 0;
+  assert(chunk_list != NULL);
+  *location = chunk_list;
+
+  while (*chunk_list != NULL) {
+    WebPChunk* const cur_chunk = *chunk_list;
+    ++count;
+    if (count == nth) return 1;  // Found.
+    chunk_list = &cur_chunk->next_;
+    *location = chunk_list;
+  }
+
+  // *chunk_list is ok to be NULL if adding at last location.
+  return (nth == 0 || (count == nth - 1)) ? 1 : 0;
+}
+
+//------------------------------------------------------------------------------
+// Chunk writer methods.
+
+WebPMuxError ChunkAssignData(WebPChunk* chunk, const WebPData* const data,
+                             int copy_data, uint32_t tag) {
+  // For internally allocated chunks, always copy data & make it owner of data.
+  if (tag == kChunks[IDX_VP8X].tag || tag == kChunks[IDX_ANIM].tag) {
+    copy_data = 1;
+  }
+
+  ChunkRelease(chunk);
+
+  if (data != NULL) {
+    if (copy_data) {        // Copy data.
+      if (!WebPDataCopy(data, &chunk->data_)) return WEBP_MUX_MEMORY_ERROR;
+      chunk->owner_ = 1;    // Chunk is owner of data.
+    } else {                // Don't copy data.
+      chunk->data_ = *data;
+    }
+  }
+  chunk->tag_ = tag;
+  return WEBP_MUX_OK;
+}
+
+WebPMuxError ChunkSetNth(WebPChunk* chunk, WebPChunk** chunk_list,
+                         uint32_t nth) {
+  WebPChunk* new_chunk;
+
+  if (!ChunkSearchListToSet(chunk_list, nth, &chunk_list)) {
+    return WEBP_MUX_NOT_FOUND;
+  }
+
+  new_chunk = (WebPChunk*)WebPSafeMalloc(1ULL, sizeof(*new_chunk));
+  if (new_chunk == NULL) return WEBP_MUX_MEMORY_ERROR;
+  *new_chunk = *chunk;
+  chunk->owner_ = 0;
+  new_chunk->next_ = *chunk_list;
+  *chunk_list = new_chunk;
+  return WEBP_MUX_OK;
+}
+
+//------------------------------------------------------------------------------
+// Chunk deletion method(s).
+
+WebPChunk* ChunkDelete(WebPChunk* const chunk) {
+  WebPChunk* const next = ChunkRelease(chunk);
+  WebPSafeFree(chunk);
+  return next;
+}
+
+void ChunkListDelete(WebPChunk** const chunk_list) {
+  while (*chunk_list != NULL) {
+    *chunk_list = ChunkDelete(*chunk_list);
+  }
+}
+
+//------------------------------------------------------------------------------
+// Chunk serialization methods.
+
+static uint8_t* ChunkEmit(const WebPChunk* const chunk, uint8_t* dst) {
+  const size_t chunk_size = chunk->data_.size;
+  assert(chunk);
+  assert(chunk->tag_ != NIL_TAG);
+  PutLE32(dst + 0, chunk->tag_);
+  PutLE32(dst + TAG_SIZE, (uint32_t)chunk_size);
+  assert(chunk_size == (uint32_t)chunk_size);
+  memcpy(dst + CHUNK_HEADER_SIZE, chunk->data_.bytes, chunk_size);
+  if (chunk_size & 1)
+    dst[CHUNK_HEADER_SIZE + chunk_size] = 0;  // Add padding.
+  return dst + ChunkDiskSize(chunk);
+}
+
+uint8_t* ChunkListEmit(const WebPChunk* chunk_list, uint8_t* dst) {
+  while (chunk_list != NULL) {
+    dst = ChunkEmit(chunk_list, dst);
+    chunk_list = chunk_list->next_;
+  }
+  return dst;
+}
+
+size_t ChunkListDiskSize(const WebPChunk* chunk_list) {
+  size_t size = 0;
+  while (chunk_list != NULL) {
+    size += ChunkDiskSize(chunk_list);
+    chunk_list = chunk_list->next_;
+  }
+  return size;
+}
+
+//------------------------------------------------------------------------------
+// Life of a MuxImage object.
+
+void MuxImageInit(WebPMuxImage* const wpi) {
+  assert(wpi);
+  memset(wpi, 0, sizeof(*wpi));
+}
+
+WebPMuxImage* MuxImageRelease(WebPMuxImage* const wpi) {
+  WebPMuxImage* next;
+  if (wpi == NULL) return NULL;
+  ChunkDelete(wpi->header_);
+  ChunkDelete(wpi->alpha_);
+  ChunkDelete(wpi->img_);
+  ChunkListDelete(&wpi->unknown_);
+
+  next = wpi->next_;
+  MuxImageInit(wpi);
+  return next;
+}
+
+//------------------------------------------------------------------------------
+// MuxImage search methods.
+
+// Get a reference to appropriate chunk list within an image given chunk tag.
+static WebPChunk** GetChunkListFromId(const WebPMuxImage* const wpi,
+                                      WebPChunkId id) {
+  assert(wpi != NULL);
+  switch (id) {
+    case WEBP_CHUNK_ANMF:
+    case WEBP_CHUNK_FRGM:  return (WebPChunk**)&wpi->header_;
+    case WEBP_CHUNK_ALPHA: return (WebPChunk**)&wpi->alpha_;
+    case WEBP_CHUNK_IMAGE: return (WebPChunk**)&wpi->img_;
+    default: return NULL;
+  }
+}
+
+int MuxImageCount(const WebPMuxImage* wpi_list, WebPChunkId id) {
+  int count = 0;
+  const WebPMuxImage* current;
+  for (current = wpi_list; current != NULL; current = current->next_) {
+    if (id == WEBP_CHUNK_NIL) {
+      ++count;  // Special case: count all images.
+    } else {
+      const WebPChunk* const wpi_chunk = *GetChunkListFromId(current, id);
+      if (wpi_chunk != NULL) {
+        const WebPChunkId wpi_chunk_id = ChunkGetIdFromTag(wpi_chunk->tag_);
+        if (wpi_chunk_id == id) ++count;  // Count images with a matching 'id'.
+      }
+    }
+  }
+  return count;
+}
+
+// Outputs a pointer to 'prev_wpi->next_',
+//   where 'prev_wpi' is the pointer to the image at position (nth - 1).
+// Returns true if nth image was found.
+static int SearchImageToGetOrDelete(WebPMuxImage** wpi_list, uint32_t nth,
+                                    WebPMuxImage*** const location) {
+  uint32_t count = 0;
+  assert(wpi_list);
+  *location = wpi_list;
+
+  if (nth == 0) {
+    nth = MuxImageCount(*wpi_list, WEBP_CHUNK_NIL);
+    if (nth == 0) return 0;  // Not found.
+  }
+
+  while (*wpi_list != NULL) {
+    WebPMuxImage* const cur_wpi = *wpi_list;
+    ++count;
+    if (count == nth) return 1;  // Found.
+    wpi_list = &cur_wpi->next_;
+    *location = wpi_list;
+  }
+  return 0;  // Not found.
+}
+
+//------------------------------------------------------------------------------
+// MuxImage writer methods.
+
+WebPMuxError MuxImagePush(const WebPMuxImage* wpi, WebPMuxImage** wpi_list) {
+  WebPMuxImage* new_wpi;
+
+  while (*wpi_list != NULL) {
+    WebPMuxImage* const cur_wpi = *wpi_list;
+    if (cur_wpi->next_ == NULL) break;
+    wpi_list = &cur_wpi->next_;
+  }
+
+  new_wpi = (WebPMuxImage*)WebPSafeMalloc(1ULL, sizeof(*new_wpi));
+  if (new_wpi == NULL) return WEBP_MUX_MEMORY_ERROR;
+  *new_wpi = *wpi;
+  new_wpi->next_ = NULL;
+
+  if (*wpi_list != NULL) {
+    (*wpi_list)->next_ = new_wpi;
+  } else {
+    *wpi_list = new_wpi;
+  }
+  return WEBP_MUX_OK;
+}
+
+//------------------------------------------------------------------------------
+// MuxImage deletion methods.
+
+WebPMuxImage* MuxImageDelete(WebPMuxImage* const wpi) {
+  // Delete the components of wpi. If wpi is NULL this is a noop.
+  WebPMuxImage* const next = MuxImageRelease(wpi);
+  WebPSafeFree(wpi);
+  return next;
+}
+
+WebPMuxError MuxImageDeleteNth(WebPMuxImage** wpi_list, uint32_t nth) {
+  assert(wpi_list);
+  if (!SearchImageToGetOrDelete(wpi_list, nth, &wpi_list)) {
+    return WEBP_MUX_NOT_FOUND;
+  }
+  *wpi_list = MuxImageDelete(*wpi_list);
+  return WEBP_MUX_OK;
+}
+
+//------------------------------------------------------------------------------
+// MuxImage reader methods.
+
+WebPMuxError MuxImageGetNth(const WebPMuxImage** wpi_list, uint32_t nth,
+                            WebPMuxImage** wpi) {
+  assert(wpi_list);
+  assert(wpi);
+  if (!SearchImageToGetOrDelete((WebPMuxImage**)wpi_list, nth,
+                                (WebPMuxImage***)&wpi_list)) {
+    return WEBP_MUX_NOT_FOUND;
+  }
+  *wpi = (WebPMuxImage*)*wpi_list;
+  return WEBP_MUX_OK;
+}
+
+//------------------------------------------------------------------------------
+// MuxImage serialization methods.
+
+// Size of an image.
+size_t MuxImageDiskSize(const WebPMuxImage* const wpi) {
+  size_t size = 0;
+  if (wpi->header_ != NULL) size += ChunkDiskSize(wpi->header_);
+  if (wpi->alpha_ != NULL) size += ChunkDiskSize(wpi->alpha_);
+  if (wpi->img_ != NULL) size += ChunkDiskSize(wpi->img_);
+  if (wpi->unknown_ != NULL) size += ChunkListDiskSize(wpi->unknown_);
+  return size;
+}
+
+// Special case as ANMF/FRGM chunk encapsulates other image chunks.
+static uint8_t* ChunkEmitSpecial(const WebPChunk* const header,
+                                 size_t total_size, uint8_t* dst) {
+  const size_t header_size = header->data_.size;
+  const size_t offset_to_next = total_size - CHUNK_HEADER_SIZE;
+  assert(header->tag_ == kChunks[IDX_ANMF].tag ||
+         header->tag_ == kChunks[IDX_FRGM].tag);
+  PutLE32(dst + 0, header->tag_);
+  PutLE32(dst + TAG_SIZE, (uint32_t)offset_to_next);
+  assert(header_size == (uint32_t)header_size);
+  memcpy(dst + CHUNK_HEADER_SIZE, header->data_.bytes, header_size);
+  if (header_size & 1) {
+    dst[CHUNK_HEADER_SIZE + header_size] = 0;  // Add padding.
+  }
+  return dst + ChunkDiskSize(header);
+}
+
+uint8_t* MuxImageEmit(const WebPMuxImage* const wpi, uint8_t* dst) {
+  // Ordering of chunks to be emitted is strictly as follows:
+  // 1. ANMF/FRGM chunk (if present).
+  // 2. ALPH chunk (if present).
+  // 3. VP8/VP8L chunk.
+  assert(wpi);
+  if (wpi->header_ != NULL) {
+    dst = ChunkEmitSpecial(wpi->header_, MuxImageDiskSize(wpi), dst);
+  }
+  if (wpi->alpha_ != NULL) dst = ChunkEmit(wpi->alpha_, dst);
+  if (wpi->img_ != NULL) dst = ChunkEmit(wpi->img_, dst);
+  if (wpi->unknown_ != NULL) dst = ChunkListEmit(wpi->unknown_, dst);
+  return dst;
+}
+
+//------------------------------------------------------------------------------
+// Helper methods for mux.
+
+int MuxHasAlpha(const WebPMuxImage* images) {
+  while (images != NULL) {
+    if (images->has_alpha_) return 1;
+    images = images->next_;
+  }
+  return 0;
+}
+
+uint8_t* MuxEmitRiffHeader(uint8_t* const data, size_t size) {
+  PutLE32(data + 0, MKFOURCC('R', 'I', 'F', 'F'));
+  PutLE32(data + TAG_SIZE, (uint32_t)size - CHUNK_HEADER_SIZE);
+  assert(size == (uint32_t)size);
+  PutLE32(data + TAG_SIZE + CHUNK_SIZE_BYTES, MKFOURCC('W', 'E', 'B', 'P'));
+  return data + RIFF_HEADER_SIZE;
+}
+
+WebPChunk** MuxGetChunkListFromId(const WebPMux* mux, WebPChunkId id) {
+  assert(mux != NULL);
+  switch (id) {
+    case WEBP_CHUNK_VP8X:    return (WebPChunk**)&mux->vp8x_;
+    case WEBP_CHUNK_ICCP:    return (WebPChunk**)&mux->iccp_;
+    case WEBP_CHUNK_ANIM:    return (WebPChunk**)&mux->anim_;
+    case WEBP_CHUNK_EXIF:    return (WebPChunk**)&mux->exif_;
+    case WEBP_CHUNK_XMP:     return (WebPChunk**)&mux->xmp_;
+    default:                 return (WebPChunk**)&mux->unknown_;
+  }
+}
+
+static int IsNotCompatible(int feature, int num_items) {
+  return (feature != 0) != (num_items > 0);
+}
+
+#define NO_FLAG 0
+
+// Test basic constraints:
+// retrieval, maximum number of chunks by index (use -1 to skip)
+// and feature incompatibility (use NO_FLAG to skip).
+// On success returns WEBP_MUX_OK and stores the chunk count in *num.
+static WebPMuxError ValidateChunk(const WebPMux* const mux, CHUNK_INDEX idx,
+                                  WebPFeatureFlags feature,
+                                  uint32_t vp8x_flags,
+                                  int max, int* num) {
+  const WebPMuxError err =
+      WebPMuxNumChunks(mux, kChunks[idx].id, num);
+  if (err != WEBP_MUX_OK) return err;
+  if (max > -1 && *num > max) return WEBP_MUX_INVALID_ARGUMENT;
+  if (feature != NO_FLAG && IsNotCompatible(vp8x_flags & feature, *num)) {
+    return WEBP_MUX_INVALID_ARGUMENT;
+  }
+  return WEBP_MUX_OK;
+}
+
+WebPMuxError MuxValidate(const WebPMux* const mux) {
+  int num_iccp;
+  int num_exif;
+  int num_xmp;
+  int num_anim;
+  int num_frames;
+  int num_fragments;
+  int num_vp8x;
+  int num_images;
+  int num_alpha;
+  uint32_t flags;
+  WebPMuxError err;
+
+  // Verify mux is not NULL.
+  if (mux == NULL) return WEBP_MUX_INVALID_ARGUMENT;
+
+  // Verify mux has at least one image.
+  if (mux->images_ == NULL) return WEBP_MUX_INVALID_ARGUMENT;
+
+  err = WebPMuxGetFeatures(mux, &flags);
+  if (err != WEBP_MUX_OK) return err;
+
+  // At most one color profile chunk.
+  err = ValidateChunk(mux, IDX_ICCP, ICCP_FLAG, flags, 1, &num_iccp);
+  if (err != WEBP_MUX_OK) return err;
+
+  // At most one EXIF metadata.
+  err = ValidateChunk(mux, IDX_EXIF, EXIF_FLAG, flags, 1, &num_exif);
+  if (err != WEBP_MUX_OK) return err;
+
+  // At most one XMP metadata.
+  err = ValidateChunk(mux, IDX_XMP, XMP_FLAG, flags, 1, &num_xmp);
+  if (err != WEBP_MUX_OK) return err;
+
+  // Animation: ANIMATION_FLAG, ANIM chunk and ANMF chunk(s) are consistent.
+  // At most one ANIM chunk.
+  err = ValidateChunk(mux, IDX_ANIM, NO_FLAG, flags, 1, &num_anim);
+  if (err != WEBP_MUX_OK) return err;
+  err = ValidateChunk(mux, IDX_ANMF, NO_FLAG, flags, -1, &num_frames);
+  if (err != WEBP_MUX_OK) return err;
+
+  {
+    const int has_animation = !!(flags & ANIMATION_FLAG);
+    if (has_animation && (num_anim == 0 || num_frames == 0)) {
+      return WEBP_MUX_INVALID_ARGUMENT;
+    }
+    if (!has_animation && (num_anim == 1 || num_frames > 0)) {
+      return WEBP_MUX_INVALID_ARGUMENT;
+    }
+  }
+
+  // Fragmentation: FRAGMENTS_FLAG and FRGM chunk(s) are consistent.
+  err = ValidateChunk(mux, IDX_FRGM, FRAGMENTS_FLAG, flags, -1, &num_fragments);
+  if (err != WEBP_MUX_OK) return err;
+
+  // Verify either VP8X chunk is present OR there is only one elem in
+  // mux->images_.
+  err = ValidateChunk(mux, IDX_VP8X, NO_FLAG, flags, 1, &num_vp8x);
+  if (err != WEBP_MUX_OK) return err;
+  err = ValidateChunk(mux, IDX_VP8, NO_FLAG, flags, -1, &num_images);
+  if (err != WEBP_MUX_OK) return err;
+  if (num_vp8x == 0 && num_images != 1) return WEBP_MUX_INVALID_ARGUMENT;
+
+  // ALPHA_FLAG & alpha chunk(s) are consistent.
+  if (MuxHasAlpha(mux->images_)) {
+    if (num_vp8x > 0) {
+      // VP8X chunk is present, so it should contain ALPHA_FLAG.
+      if (!(flags & ALPHA_FLAG)) return WEBP_MUX_INVALID_ARGUMENT;
+    } else {
+      // VP8X chunk is not present, so ALPH chunks should NOT be present either.
+      err = WebPMuxNumChunks(mux, WEBP_CHUNK_ALPHA, &num_alpha);
+      if (err != WEBP_MUX_OK) return err;
+      if (num_alpha > 0) return WEBP_MUX_INVALID_ARGUMENT;
+    }
+  } else {  // Mux doesn't need alpha. So, ALPHA_FLAG should NOT be present.
+    if (flags & ALPHA_FLAG) return WEBP_MUX_INVALID_ARGUMENT;
+  }
+
+  // num_fragments & num_images are consistent.
+  if (num_fragments > 0 && num_images != num_fragments) {
+    return WEBP_MUX_INVALID_ARGUMENT;
+  }
+
+  return WEBP_MUX_OK;
+}
+
+#undef NO_FLAG
+
+//------------------------------------------------------------------------------
+
diff --git a/Source/LibWebP/src/mux/mux.muxread.c b/Source/LibWebP/src/mux/mux.muxread.c
new file mode 100644
index 0000000..5bc19ef
--- /dev/null
+++ b/Source/LibWebP/src/mux/mux.muxread.c
@@ -0,0 +1,544 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Read APIs for mux.
+//
+// Authors: Urvang (urvang at google.com)
+//          Vikas (vikasa at google.com)
+
+#include <assert.h>
+#include "./muxi.h"
+#include "../utils/utils.h"
+
+//------------------------------------------------------------------------------
+// Helper method(s).
+
+// Handy MACRO.
+#define SWITCH_ID_LIST(INDEX, LIST)                                           \
+  if (idx == (INDEX)) {                                                       \
+    const WebPChunk* const chunk = ChunkSearchList((LIST), nth,               \
+                                                   kChunks[(INDEX)].tag);     \
+    if (chunk) {                                                              \
+      *data = chunk->data_;                                                   \
+      return WEBP_MUX_OK;                                                     \
+    } else {                                                                  \
+      return WEBP_MUX_NOT_FOUND;                                              \
+    }                                                                         \
+  }
+
+static WebPMuxError MuxGet(const WebPMux* const mux, CHUNK_INDEX idx,
+                           uint32_t nth, WebPData* const data) {
+  assert(mux != NULL);
+  assert(!IsWPI(kChunks[idx].id));
+  WebPDataInit(data);
+
+  SWITCH_ID_LIST(IDX_VP8X, mux->vp8x_);
+  SWITCH_ID_LIST(IDX_ICCP, mux->iccp_);
+  SWITCH_ID_LIST(IDX_ANIM, mux->anim_);
+  SWITCH_ID_LIST(IDX_EXIF, mux->exif_);
+  SWITCH_ID_LIST(IDX_XMP, mux->xmp_);
+  SWITCH_ID_LIST(IDX_UNKNOWN, mux->unknown_);
+  return WEBP_MUX_NOT_FOUND;
+}
+#undef SWITCH_ID_LIST
+
+// Fill the chunk with the given data (includes chunk header bytes), after some
+// verifications.
+static WebPMuxError ChunkVerifyAndAssign(WebPChunk* chunk,
+                                         const uint8_t* data, size_t data_size,
+                                         size_t riff_size, int copy_data) {
+  uint32_t chunk_size;
+  WebPData chunk_data;
+
+  // Sanity checks.
+  if (data_size < CHUNK_HEADER_SIZE) return WEBP_MUX_NOT_ENOUGH_DATA;
+  chunk_size = GetLE32(data + TAG_SIZE);
+
+  {
+    const size_t chunk_disk_size = SizeWithPadding(chunk_size);
+    if (chunk_disk_size > riff_size) return WEBP_MUX_BAD_DATA;
+    if (chunk_disk_size > data_size) return WEBP_MUX_NOT_ENOUGH_DATA;
+  }
+
+  // Data assignment.
+  chunk_data.bytes = data + CHUNK_HEADER_SIZE;
+  chunk_data.size = chunk_size;
+  return ChunkAssignData(chunk, &chunk_data, copy_data, GetLE32(data + 0));
+}
+
+int MuxImageFinalize(WebPMuxImage* const wpi) {
+  const WebPChunk* const img = wpi->img_;
+  const WebPData* const image = &img->data_;
+  const int is_lossless = (img->tag_ == kChunks[IDX_VP8L].tag);
+  int w, h;
+  int vp8l_has_alpha = 0;
+  const int ok = is_lossless ?
+      VP8LGetInfo(image->bytes, image->size, &w, &h, &vp8l_has_alpha) :
+      VP8GetInfo(image->bytes, image->size, image->size, &w, &h);
+  assert(img != NULL);
+  if (ok) {
+    // Ignore ALPH chunk accompanying VP8L.
+    if (is_lossless && (wpi->alpha_ != NULL)) {
+      ChunkDelete(wpi->alpha_);
+      wpi->alpha_ = NULL;
+    }
+    wpi->width_ = w;
+    wpi->height_ = h;
+    wpi->has_alpha_ = vp8l_has_alpha || (wpi->alpha_ != NULL);
+  }
+  return ok;
+}
+
+static int MuxImageParse(const WebPChunk* const chunk, int copy_data,
+                         WebPMuxImage* const wpi) {
+  const uint8_t* bytes = chunk->data_.bytes;
+  size_t size = chunk->data_.size;
+  const uint8_t* const last = bytes + size;
+  WebPChunk subchunk;
+  size_t subchunk_size;
+  ChunkInit(&subchunk);
+
+  assert(chunk->tag_ == kChunks[IDX_ANMF].tag ||
+         chunk->tag_ == kChunks[IDX_FRGM].tag);
+  assert(!wpi->is_partial_);
+
+  // ANMF/FRGM.
+  {
+    const size_t hdr_size = (chunk->tag_ == kChunks[IDX_ANMF].tag) ?
+        ANMF_CHUNK_SIZE : FRGM_CHUNK_SIZE;
+    const WebPData temp = { bytes, hdr_size };
+    // Each of ANMF and FRGM chunk contain a header at the beginning. So, its
+    // size should at least be 'hdr_size'.
+    if (size < hdr_size) goto Fail;
+    ChunkAssignData(&subchunk, &temp, copy_data, chunk->tag_);
+  }
+  ChunkSetNth(&subchunk, &wpi->header_, 1);
+  wpi->is_partial_ = 1;  // Waiting for ALPH and/or VP8/VP8L chunks.
+
+  // Rest of the chunks.
+  subchunk_size = ChunkDiskSize(&subchunk) - CHUNK_HEADER_SIZE;
+  bytes += subchunk_size;
+  size -= subchunk_size;
+
+  while (bytes != last) {
+    ChunkInit(&subchunk);
+    if (ChunkVerifyAndAssign(&subchunk, bytes, size, size,
+                             copy_data) != WEBP_MUX_OK) {
+      goto Fail;
+    }
+    switch (ChunkGetIdFromTag(subchunk.tag_)) {
+      case WEBP_CHUNK_ALPHA:
+        if (wpi->alpha_ != NULL) goto Fail;  // Consecutive ALPH chunks.
+        if (ChunkSetNth(&subchunk, &wpi->alpha_, 1) != WEBP_MUX_OK) goto Fail;
+        wpi->is_partial_ = 1;  // Waiting for a VP8 chunk.
+        break;
+      case WEBP_CHUNK_IMAGE:
+        if (ChunkSetNth(&subchunk, &wpi->img_, 1) != WEBP_MUX_OK) goto Fail;
+        if (!MuxImageFinalize(wpi)) goto Fail;
+        wpi->is_partial_ = 0;  // wpi is completely filled.
+        break;
+      case WEBP_CHUNK_UNKNOWN:
+        if (wpi->is_partial_) goto Fail;  // Encountered an unknown chunk
+                                          // before some image chunks.
+        if (ChunkSetNth(&subchunk, &wpi->unknown_, 0) != WEBP_MUX_OK) goto Fail;
+        break;
+      default:
+        goto Fail;
+        break;
+    }
+    subchunk_size = ChunkDiskSize(&subchunk);
+    bytes += subchunk_size;
+    size -= subchunk_size;
+  }
+  if (wpi->is_partial_) goto Fail;
+  return 1;
+
+ Fail:
+  ChunkRelease(&subchunk);
+  return 0;
+}
+
+//------------------------------------------------------------------------------
+// Create a mux object from WebP-RIFF data.
+
+WebPMux* WebPMuxCreateInternal(const WebPData* bitstream, int copy_data,
+                               int version) {
+  size_t riff_size;
+  uint32_t tag;
+  const uint8_t* end;
+  WebPMux* mux = NULL;
+  WebPMuxImage* wpi = NULL;
+  const uint8_t* data;
+  size_t size;
+  WebPChunk chunk;
+  ChunkInit(&chunk);
+
+  // Sanity checks.
+  if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_MUX_ABI_VERSION)) {
+    return NULL;  // version mismatch
+  }
+  if (bitstream == NULL) return NULL;
+
+  data = bitstream->bytes;
+  size = bitstream->size;
+
+  if (data == NULL) return NULL;
+  if (size < RIFF_HEADER_SIZE) return NULL;
+  if (GetLE32(data + 0) != MKFOURCC('R', 'I', 'F', 'F') ||
+      GetLE32(data + CHUNK_HEADER_SIZE) != MKFOURCC('W', 'E', 'B', 'P')) {
+    return NULL;
+  }
+
+  mux = WebPMuxNew();
+  if (mux == NULL) return NULL;
+
+  if (size < RIFF_HEADER_SIZE + TAG_SIZE) goto Err;
+
+  tag = GetLE32(data + RIFF_HEADER_SIZE);
+  if (tag != kChunks[IDX_VP8].tag &&
+      tag != kChunks[IDX_VP8L].tag &&
+      tag != kChunks[IDX_VP8X].tag) {
+    goto Err;  // First chunk should be VP8, VP8L or VP8X.
+  }
+
+  riff_size = SizeWithPadding(GetLE32(data + TAG_SIZE));
+  if (riff_size > MAX_CHUNK_PAYLOAD || riff_size > size) {
+    goto Err;
+  } else {
+    if (riff_size < size) {  // Redundant data after last chunk.
+      size = riff_size;  // To make sure we don't read any data beyond mux_size.
+    }
+  }
+
+  end = data + size;
+  data += RIFF_HEADER_SIZE;
+  size -= RIFF_HEADER_SIZE;
+
+  wpi = (WebPMuxImage*)WebPSafeMalloc(1ULL, sizeof(*wpi));
+  if (wpi == NULL) goto Err;
+  MuxImageInit(wpi);
+
+  // Loop over chunks.
+  while (data != end) {
+    size_t data_size;
+    WebPChunkId id;
+    WebPChunk** chunk_list;
+    if (ChunkVerifyAndAssign(&chunk, data, size, riff_size,
+                             copy_data) != WEBP_MUX_OK) {
+      goto Err;
+    }
+    data_size = ChunkDiskSize(&chunk);
+    id = ChunkGetIdFromTag(chunk.tag_);
+    switch (id) {
+      case WEBP_CHUNK_ALPHA:
+        if (wpi->alpha_ != NULL) goto Err;  // Consecutive ALPH chunks.
+        if (ChunkSetNth(&chunk, &wpi->alpha_, 1) != WEBP_MUX_OK) goto Err;
+        wpi->is_partial_ = 1;  // Waiting for a VP8 chunk.
+        break;
+      case WEBP_CHUNK_IMAGE:
+        if (ChunkSetNth(&chunk, &wpi->img_, 1) != WEBP_MUX_OK) goto Err;
+        if (!MuxImageFinalize(wpi)) goto Err;
+        wpi->is_partial_ = 0;  // wpi is completely filled.
+ PushImage:
+        // Add this to mux->images_ list.
+        if (MuxImagePush(wpi, &mux->images_) != WEBP_MUX_OK) goto Err;
+        MuxImageInit(wpi);  // Reset for reading next image.
+        break;
+      case WEBP_CHUNK_ANMF:
+        if (wpi->is_partial_) goto Err;  // Previous wpi is still incomplete.
+        if (!MuxImageParse(&chunk, copy_data, wpi)) goto Err;
+        ChunkRelease(&chunk);
+        goto PushImage;
+        break;
+      default:  // A non-image chunk.
+        if (wpi->is_partial_) goto Err;  // Encountered a non-image chunk before
+                                         // getting all chunks of an image.
+        chunk_list = MuxGetChunkListFromId(mux, id);  // List to add this chunk.
+        if (ChunkSetNth(&chunk, chunk_list, 0) != WEBP_MUX_OK) goto Err;
+        if (id == WEBP_CHUNK_VP8X) {  // grab global specs
+          mux->canvas_width_ = GetLE24(data + 12) + 1;
+          mux->canvas_height_ = GetLE24(data + 15) + 1;
+        }
+        break;
+    }
+    data += data_size;
+    size -= data_size;
+    ChunkInit(&chunk);
+  }
+
+  // Validate mux if complete.
+  if (MuxValidate(mux) != WEBP_MUX_OK) goto Err;
+
+  MuxImageDelete(wpi);
+  return mux;  // All OK;
+
+ Err:  // Something bad happened.
+  ChunkRelease(&chunk);
+  MuxImageDelete(wpi);
+  WebPMuxDelete(mux);
+  return NULL;
+}
+
+//------------------------------------------------------------------------------
+// Get API(s).
+
+// Validates that the given mux has a single image.
+static WebPMuxError ValidateForSingleImage(const WebPMux* const mux) {
+  const int num_images = MuxImageCount(mux->images_, WEBP_CHUNK_IMAGE);
+  const int num_frames = MuxImageCount(mux->images_, WEBP_CHUNK_ANMF);
+  const int num_fragments = MuxImageCount(mux->images_, WEBP_CHUNK_FRGM);
+
+  if (num_images == 0) {
+    // No images in mux.
+    return WEBP_MUX_NOT_FOUND;
+  } else if (num_images == 1 && num_frames == 0 && num_fragments == 0) {
+    // Valid case (single image).
+    return WEBP_MUX_OK;
+  } else {
+    // Frame/Fragment case OR an invalid mux.
+    return WEBP_MUX_INVALID_ARGUMENT;
+  }
+}
+
+// Get the canvas width, height and flags after validating that VP8X/VP8/VP8L
+// chunk and canvas size are valid.
+static WebPMuxError MuxGetCanvasInfo(const WebPMux* const mux,
+                                     int* width, int* height, uint32_t* flags) {
+  int w, h;
+  uint32_t f = 0;
+  WebPData data;
+  assert(mux != NULL);
+
+  // Check if VP8X chunk is present.
+  if (MuxGet(mux, IDX_VP8X, 1, &data) == WEBP_MUX_OK) {
+    if (data.size < VP8X_CHUNK_SIZE) return WEBP_MUX_BAD_DATA;
+    f = GetLE32(data.bytes + 0);
+    w = GetLE24(data.bytes + 4) + 1;
+    h = GetLE24(data.bytes + 7) + 1;
+  } else {
+    const WebPMuxImage* const wpi = mux->images_;
+    // Grab user-forced canvas size as default.
+    w = mux->canvas_width_;
+    h = mux->canvas_height_;
+    if (w == 0 && h == 0 && ValidateForSingleImage(mux) == WEBP_MUX_OK) {
+      // single image and not forced canvas size => use dimension of first frame
+      assert(wpi != NULL);
+      w = wpi->width_;
+      h = wpi->height_;
+    }
+    if (wpi != NULL) {
+      if (wpi->has_alpha_) f |= ALPHA_FLAG;
+    }
+  }
+  if (w * (uint64_t)h >= MAX_IMAGE_AREA) return WEBP_MUX_BAD_DATA;
+
+  if (width != NULL) *width = w;
+  if (height != NULL) *height = h;
+  if (flags != NULL) *flags = f;
+  return WEBP_MUX_OK;
+}
+
+WebPMuxError WebPMuxGetCanvasSize(const WebPMux* mux, int* width, int* height) {
+  if (mux == NULL || width == NULL || height == NULL) {
+    return WEBP_MUX_INVALID_ARGUMENT;
+  }
+  return MuxGetCanvasInfo(mux, width, height, NULL);
+}
+
+WebPMuxError WebPMuxGetFeatures(const WebPMux* mux, uint32_t* flags) {
+  if (mux == NULL || flags == NULL) return WEBP_MUX_INVALID_ARGUMENT;
+  return MuxGetCanvasInfo(mux, NULL, NULL, flags);
+}
+
+static uint8_t* EmitVP8XChunk(uint8_t* const dst, int width,
+                              int height, uint32_t flags) {
+  const size_t vp8x_size = CHUNK_HEADER_SIZE + VP8X_CHUNK_SIZE;
+  assert(width >= 1 && height >= 1);
+  assert(width <= MAX_CANVAS_SIZE && height <= MAX_CANVAS_SIZE);
+  assert(width * (uint64_t)height < MAX_IMAGE_AREA);
+  PutLE32(dst, MKFOURCC('V', 'P', '8', 'X'));
+  PutLE32(dst + TAG_SIZE, VP8X_CHUNK_SIZE);
+  PutLE32(dst + CHUNK_HEADER_SIZE, flags);
+  PutLE24(dst + CHUNK_HEADER_SIZE + 4, width - 1);
+  PutLE24(dst + CHUNK_HEADER_SIZE + 7, height - 1);
+  return dst + vp8x_size;
+}
+
+// Assemble a single image WebP bitstream from 'wpi'.
+static WebPMuxError SynthesizeBitstream(const WebPMuxImage* const wpi,
+                                        WebPData* const bitstream) {
+  uint8_t* dst;
+
+  // Allocate data.
+  const int need_vp8x = (wpi->alpha_ != NULL);
+  const size_t vp8x_size = need_vp8x ? CHUNK_HEADER_SIZE + VP8X_CHUNK_SIZE : 0;
+  const size_t alpha_size = need_vp8x ? ChunkDiskSize(wpi->alpha_) : 0;
+  // Note: No need to output ANMF/FRGM chunk for a single image.
+  const size_t size = RIFF_HEADER_SIZE + vp8x_size + alpha_size +
+                      ChunkDiskSize(wpi->img_);
+  uint8_t* const data = (uint8_t*)WebPSafeMalloc(1ULL, size);
+  if (data == NULL) return WEBP_MUX_MEMORY_ERROR;
+
+  // Main RIFF header.
+  dst = MuxEmitRiffHeader(data, size);
+
+  if (need_vp8x) {
+    dst = EmitVP8XChunk(dst, wpi->width_, wpi->height_, ALPHA_FLAG);  // VP8X.
+    dst = ChunkListEmit(wpi->alpha_, dst);       // ALPH.
+  }
+
+  // Bitstream.
+  dst = ChunkListEmit(wpi->img_, dst);
+  assert(dst == data + size);
+
+  // Output.
+  bitstream->bytes = data;
+  bitstream->size = size;
+  return WEBP_MUX_OK;
+}
+
+WebPMuxError WebPMuxGetChunk(const WebPMux* mux, const char fourcc[4],
+                             WebPData* chunk_data) {
+  CHUNK_INDEX idx;
+  if (mux == NULL || fourcc == NULL || chunk_data == NULL) {
+    return WEBP_MUX_INVALID_ARGUMENT;
+  }
+  idx = ChunkGetIndexFromFourCC(fourcc);
+  if (IsWPI(kChunks[idx].id)) {     // An image chunk.
+    return WEBP_MUX_INVALID_ARGUMENT;
+  } else if (idx != IDX_UNKNOWN) {  // A known chunk type.
+    return MuxGet(mux, idx, 1, chunk_data);
+  } else {                          // An unknown chunk type.
+    const WebPChunk* const chunk =
+        ChunkSearchList(mux->unknown_, 1, ChunkGetTagFromFourCC(fourcc));
+    if (chunk == NULL) return WEBP_MUX_NOT_FOUND;
+    *chunk_data = chunk->data_;
+    return WEBP_MUX_OK;
+  }
+}
+
+static WebPMuxError MuxGetImageInternal(const WebPMuxImage* const wpi,
+                                        WebPMuxFrameInfo* const info) {
+  // Set some defaults for unrelated fields.
+  info->x_offset = 0;
+  info->y_offset = 0;
+  info->duration = 1;
+  info->dispose_method = WEBP_MUX_DISPOSE_NONE;
+  info->blend_method = WEBP_MUX_BLEND;
+  // Extract data for related fields.
+  info->id = ChunkGetIdFromTag(wpi->img_->tag_);
+  return SynthesizeBitstream(wpi, &info->bitstream);
+}
+
+static WebPMuxError MuxGetFrameFragmentInternal(const WebPMuxImage* const wpi,
+                                                WebPMuxFrameInfo* const frame) {
+  const int is_frame = (wpi->header_->tag_ == kChunks[IDX_ANMF].tag);
+  const CHUNK_INDEX idx = is_frame ? IDX_ANMF : IDX_FRGM;
+  const WebPData* frame_frgm_data;
+  if (!is_frame) return WEBP_MUX_INVALID_ARGUMENT;
+  assert(wpi->header_ != NULL);  // Already checked by WebPMuxGetFrame().
+  // Get frame/fragment chunk.
+  frame_frgm_data = &wpi->header_->data_;
+  if (frame_frgm_data->size < kChunks[idx].size) return WEBP_MUX_BAD_DATA;
+  // Extract info.
+  frame->x_offset = 2 * GetLE24(frame_frgm_data->bytes + 0);
+  frame->y_offset = 2 * GetLE24(frame_frgm_data->bytes + 3);
+  if (is_frame) {
+    const uint8_t bits = frame_frgm_data->bytes[15];
+    frame->duration = GetLE24(frame_frgm_data->bytes + 12);
+    frame->dispose_method =
+        (bits & 1) ? WEBP_MUX_DISPOSE_BACKGROUND : WEBP_MUX_DISPOSE_NONE;
+    frame->blend_method = (bits & 2) ? WEBP_MUX_NO_BLEND : WEBP_MUX_BLEND;
+  } else {  // Defaults for unused values.
+    frame->duration = 1;
+    frame->dispose_method = WEBP_MUX_DISPOSE_NONE;
+    frame->blend_method = WEBP_MUX_BLEND;
+  }
+  frame->id = ChunkGetIdFromTag(wpi->header_->tag_);
+  return SynthesizeBitstream(wpi, &frame->bitstream);
+}
+
+WebPMuxError WebPMuxGetFrame(
+    const WebPMux* mux, uint32_t nth, WebPMuxFrameInfo* frame) {
+  WebPMuxError err;
+  WebPMuxImage* wpi;
+
+  // Sanity checks.
+  if (mux == NULL || frame == NULL) {
+    return WEBP_MUX_INVALID_ARGUMENT;
+  }
+
+  // Get the nth WebPMuxImage.
+  err = MuxImageGetNth((const WebPMuxImage**)&mux->images_, nth, &wpi);
+  if (err != WEBP_MUX_OK) return err;
+
+  // Get frame info.
+  if (wpi->header_ == NULL) {
+    return MuxGetImageInternal(wpi, frame);
+  } else {
+    return MuxGetFrameFragmentInternal(wpi, frame);
+  }
+}
+
+WebPMuxError WebPMuxGetAnimationParams(const WebPMux* mux,
+                                       WebPMuxAnimParams* params) {
+  WebPData anim;
+  WebPMuxError err;
+
+  if (mux == NULL || params == NULL) return WEBP_MUX_INVALID_ARGUMENT;
+
+  err = MuxGet(mux, IDX_ANIM, 1, &anim);
+  if (err != WEBP_MUX_OK) return err;
+  if (anim.size < kChunks[WEBP_CHUNK_ANIM].size) return WEBP_MUX_BAD_DATA;
+  params->bgcolor = GetLE32(anim.bytes);
+  params->loop_count = GetLE16(anim.bytes + 4);
+
+  return WEBP_MUX_OK;
+}
+
+// Get chunk index from chunk id. Returns IDX_NIL if not found.
+static CHUNK_INDEX ChunkGetIndexFromId(WebPChunkId id) {
+  int i;
+  for (i = 0; kChunks[i].id != WEBP_CHUNK_NIL; ++i) {
+    if (id == kChunks[i].id) return (CHUNK_INDEX)i;
+  }
+  return IDX_NIL;
+}
+
+// Count number of chunks matching 'tag' in the 'chunk_list'.
+// If tag == NIL_TAG, any tag will be matched.
+static int CountChunks(const WebPChunk* const chunk_list, uint32_t tag) {
+  int count = 0;
+  const WebPChunk* current;
+  for (current = chunk_list; current != NULL; current = current->next_) {
+    if (tag == NIL_TAG || current->tag_ == tag) {
+      count++;  // Count chunks whose tags match.
+    }
+  }
+  return count;
+}
+
+WebPMuxError WebPMuxNumChunks(const WebPMux* mux,
+                              WebPChunkId id, int* num_elements) {
+  if (mux == NULL || num_elements == NULL) {
+    return WEBP_MUX_INVALID_ARGUMENT;
+  }
+
+  if (IsWPI(id)) {
+    *num_elements = MuxImageCount(mux->images_, id);
+  } else {
+    WebPChunk* const* chunk_list = MuxGetChunkListFromId(mux, id);
+    const CHUNK_INDEX idx = ChunkGetIndexFromId(id);
+    *num_elements = CountChunks(*chunk_list, kChunks[idx].tag);
+  }
+
+  return WEBP_MUX_OK;
+}
+
+//------------------------------------------------------------------------------
diff --git a/Source/LibWebP/src/mux/muxi.h b/Source/LibWebP/src/mux/muxi.h
new file mode 100644
index 0000000..9479631
--- /dev/null
+++ b/Source/LibWebP/src/mux/muxi.h
@@ -0,0 +1,232 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Internal header for mux library.
+//
+// Author: Urvang (urvang at google.com)
+
+#ifndef WEBP_MUX_MUXI_H_
+#define WEBP_MUX_MUXI_H_
+
+#include <stdlib.h>
+#include "../dec/vp8i.h"
+#include "../dec/vp8li.h"
+#include "../webp/mux.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//------------------------------------------------------------------------------
+// Defines and constants.
+
+#define MUX_MAJ_VERSION 0
+#define MUX_MIN_VERSION 2
+#define MUX_REV_VERSION 2
+
+// Chunk object.
+typedef struct WebPChunk WebPChunk;
+struct WebPChunk {
+  uint32_t        tag_;
+  int             owner_;  // True if *data_ memory is owned internally.
+                           // VP8X, ANIM, and other internally created chunks
+                           // like ANMF/FRGM are always owned.
+  WebPData        data_;
+  WebPChunk*      next_;
+};
+
+// MuxImage object. Store a full WebP image (including ANMF/FRGM chunk, ALPH
+// chunk and VP8/VP8L chunk),
+typedef struct WebPMuxImage WebPMuxImage;
+struct WebPMuxImage {
+  WebPChunk*  header_;      // Corresponds to WEBP_CHUNK_ANMF/WEBP_CHUNK_FRGM.
+  WebPChunk*  alpha_;       // Corresponds to WEBP_CHUNK_ALPHA.
+  WebPChunk*  img_;         // Corresponds to WEBP_CHUNK_IMAGE.
+  WebPChunk*  unknown_;     // Corresponds to WEBP_CHUNK_UNKNOWN.
+  int         width_;
+  int         height_;
+  int         has_alpha_;   // Through ALPH chunk or as part of VP8L.
+  int         is_partial_;  // True if only some of the chunks are filled.
+  WebPMuxImage* next_;
+};
+
+// Main mux object. Stores data chunks.
+struct WebPMux {
+  WebPMuxImage*   images_;
+  WebPChunk*      iccp_;
+  WebPChunk*      exif_;
+  WebPChunk*      xmp_;
+  WebPChunk*      anim_;
+  WebPChunk*      vp8x_;
+
+  WebPChunk*      unknown_;
+  int             canvas_width_;
+  int             canvas_height_;
+};
+
+// CHUNK_INDEX enum: used for indexing within 'kChunks' (defined below) only.
+// Note: the reason for having two enums ('WebPChunkId' and 'CHUNK_INDEX') is to
+// allow two different chunks to have the same id (e.g. WebPChunkId
+// 'WEBP_CHUNK_IMAGE' can correspond to CHUNK_INDEX 'IDX_VP8' or 'IDX_VP8L').
+typedef enum {
+  IDX_VP8X = 0,
+  IDX_ICCP,
+  IDX_ANIM,
+  IDX_ANMF,
+  IDX_FRGM,
+  IDX_ALPHA,
+  IDX_VP8,
+  IDX_VP8L,
+  IDX_EXIF,
+  IDX_XMP,
+  IDX_UNKNOWN,
+
+  IDX_NIL,
+  IDX_LAST_CHUNK
+} CHUNK_INDEX;
+
+#define NIL_TAG 0x00000000u  // To signal void chunk.
+
+typedef struct {
+  uint32_t      tag;
+  WebPChunkId   id;
+  uint32_t      size;
+} ChunkInfo;
+
+extern const ChunkInfo kChunks[IDX_LAST_CHUNK];
+
+//------------------------------------------------------------------------------
+// Chunk object management.
+
+// Initialize.
+void ChunkInit(WebPChunk* const chunk);
+
+// Get chunk index from chunk tag. Returns IDX_UNKNOWN if not found.
+CHUNK_INDEX ChunkGetIndexFromTag(uint32_t tag);
+
+// Get chunk id from chunk tag. Returns WEBP_CHUNK_UNKNOWN if not found.
+WebPChunkId ChunkGetIdFromTag(uint32_t tag);
+
+// Convert a fourcc string to a tag.
+uint32_t ChunkGetTagFromFourCC(const char fourcc[4]);
+
+// Get chunk index from fourcc. Returns IDX_UNKNOWN if given fourcc is unknown.
+CHUNK_INDEX ChunkGetIndexFromFourCC(const char fourcc[4]);
+
+// Search for nth chunk with given 'tag' in the chunk list.
+// nth = 0 means "last of the list".
+WebPChunk* ChunkSearchList(WebPChunk* first, uint32_t nth, uint32_t tag);
+
+// Fill the chunk with the given data.
+WebPMuxError ChunkAssignData(WebPChunk* chunk, const WebPData* const data,
+                             int copy_data, uint32_t tag);
+
+// Sets 'chunk' at nth position in the 'chunk_list'.
+// nth = 0 has the special meaning "last of the list".
+// On success ownership is transferred from 'chunk' to the 'chunk_list'.
+WebPMuxError ChunkSetNth(WebPChunk* chunk, WebPChunk** chunk_list,
+                         uint32_t nth);
+
+// Releases chunk and returns chunk->next_.
+WebPChunk* ChunkRelease(WebPChunk* const chunk);
+
+// Deletes given chunk & returns chunk->next_.
+WebPChunk* ChunkDelete(WebPChunk* const chunk);
+
+// Deletes all chunks in the given chunk list.
+void ChunkListDelete(WebPChunk** const chunk_list);
+
+// Returns size of the chunk including chunk header and padding byte (if any).
+static WEBP_INLINE size_t SizeWithPadding(size_t chunk_size) {
+  return CHUNK_HEADER_SIZE + ((chunk_size + 1) & ~1U);
+}
+
+// Size of a chunk including header and padding.
+static WEBP_INLINE size_t ChunkDiskSize(const WebPChunk* chunk) {
+  const size_t data_size = chunk->data_.size;
+  assert(data_size < MAX_CHUNK_PAYLOAD);
+  return SizeWithPadding(data_size);
+}
+
+// Total size of a list of chunks.
+size_t ChunkListDiskSize(const WebPChunk* chunk_list);
+
+// Write out the given list of chunks into 'dst'.
+uint8_t* ChunkListEmit(const WebPChunk* chunk_list, uint8_t* dst);
+
+//------------------------------------------------------------------------------
+// MuxImage object management.
+
+// Initialize.
+void MuxImageInit(WebPMuxImage* const wpi);
+
+// Releases image 'wpi' and returns wpi->next.
+WebPMuxImage* MuxImageRelease(WebPMuxImage* const wpi);
+
+// Delete image 'wpi' and return the next image in the list or NULL.
+// 'wpi' can be NULL.
+WebPMuxImage* MuxImageDelete(WebPMuxImage* const wpi);
+
+// Count number of images matching the given tag id in the 'wpi_list'.
+// If id == WEBP_CHUNK_NIL, all images will be matched.
+int MuxImageCount(const WebPMuxImage* wpi_list, WebPChunkId id);
+
+// Update width/height/has_alpha info from chunks within wpi.
+// Also remove ALPH chunk if not needed.
+int MuxImageFinalize(WebPMuxImage* const wpi);
+
+// Check if given ID corresponds to an image related chunk.
+static WEBP_INLINE int IsWPI(WebPChunkId id) {
+  switch (id) {
+    case WEBP_CHUNK_ANMF:
+    case WEBP_CHUNK_FRGM:
+    case WEBP_CHUNK_ALPHA:
+    case WEBP_CHUNK_IMAGE:  return 1;
+    default:        return 0;
+  }
+}
+
+// Pushes 'wpi' at the end of 'wpi_list'.
+WebPMuxError MuxImagePush(const WebPMuxImage* wpi, WebPMuxImage** wpi_list);
+
+// Delete nth image in the image list.
+WebPMuxError MuxImageDeleteNth(WebPMuxImage** wpi_list, uint32_t nth);
+
+// Get nth image in the image list.
+WebPMuxError MuxImageGetNth(const WebPMuxImage** wpi_list, uint32_t nth,
+                            WebPMuxImage** wpi);
+
+// Total size of the given image.
+size_t MuxImageDiskSize(const WebPMuxImage* const wpi);
+
+// Write out the given image into 'dst'.
+uint8_t* MuxImageEmit(const WebPMuxImage* const wpi, uint8_t* dst);
+
+//------------------------------------------------------------------------------
+// Helper methods for mux.
+
+// Checks if the given image list contains at least one image with alpha.
+int MuxHasAlpha(const WebPMuxImage* images);
+
+// Write out RIFF header into 'data', given total data size 'size'.
+uint8_t* MuxEmitRiffHeader(uint8_t* const data, size_t size);
+
+// Returns the list where chunk with given ID is to be inserted in mux.
+WebPChunk** MuxGetChunkListFromId(const WebPMux* mux, WebPChunkId id);
+
+// Validates the given mux object.
+WebPMuxError MuxValidate(const WebPMux* const mux);
+
+//------------------------------------------------------------------------------
+
+#ifdef __cplusplus
+}    // extern "C"
+#endif
+
+#endif  /* WEBP_MUX_MUXI_H_ */
diff --git a/Source/LibWebP/src/utils/bit_reader.h b/Source/LibWebP/src/utils/bit_reader.h
new file mode 100644
index 0000000..a4fb72a
--- /dev/null
+++ b/Source/LibWebP/src/utils/bit_reader.h
@@ -0,0 +1,168 @@
+// Copyright 2010 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Boolean decoder
+//
+// Author: Skal (pascal.massimino at gmail.com)
+//         Vikas Arora (vikaas.arora at gmail.com)
+
+#ifndef WEBP_UTILS_BIT_READER_H_
+#define WEBP_UTILS_BIT_READER_H_
+
+#include <assert.h>
+#ifdef _MSC_VER
+#include <stdlib.h>  // _byteswap_ulong
+#endif
+#include "../webp/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// The Boolean decoder needs to maintain infinite precision on the value_ field.
+// However, since range_ is only 8bit, we only need an active window of 8 bits
+// for value_. Left bits (MSB) gets zeroed and shifted away when value_ falls
+// below 128, range_ is updated, and fresh bits read from the bitstream are
+// brought in as LSB. To avoid reading the fresh bits one by one (slow), we
+// cache BITS of them ahead. The total of (BITS + 8) bits must fit into a
+// natural register (with type bit_t). To fetch BITS bits from bitstream we
+// use a type lbit_t.
+//
+// BITS can be any multiple of 8 from 8 to 56 (inclusive).
+// Pick values that fit natural register size.
+
+#if defined(__i386__) || defined(_M_IX86)      // x86 32bit
+#define BITS 24
+#elif defined(__x86_64__) || defined(_M_X64)   // x86 64bit
+#define BITS 56
+#elif defined(__arm__) || defined(_M_ARM)      // ARM
+#define BITS 24
+#elif defined(__mips__)                        // MIPS
+#define BITS 24
+#else                                          // reasonable default
+#define BITS 24  // TODO(skal): test aarch64 and find the proper BITS value.
+#endif
+
+//------------------------------------------------------------------------------
+// Derived types and constants:
+//   bit_t = natural register type for storing 'value_' (which is BITS+8 bits)
+//   range_t = register for 'range_' (which is 8bits only)
+
+#if (BITS > 24)
+typedef uint64_t bit_t;
+#else
+typedef uint32_t bit_t;
+#endif
+
+typedef uint32_t range_t;
+
+//------------------------------------------------------------------------------
+// Bitreader
+
+typedef struct VP8BitReader VP8BitReader;
+struct VP8BitReader {
+  // boolean decoder  (keep the field ordering as is!)
+  bit_t value_;               // current value
+  range_t range_;             // current range minus 1. In [127, 254] interval.
+  int bits_;                  // number of valid bits left
+  // read buffer
+  const uint8_t* buf_;        // next byte to be read
+  const uint8_t* buf_end_;    // end of read buffer
+  int eof_;                   // true if input is exhausted
+};
+
+// Initialize the bit reader and the boolean decoder.
+void VP8InitBitReader(VP8BitReader* const br,
+                      const uint8_t* const start, const uint8_t* const end);
+
+// Update internal pointers to displace the byte buffer by the
+// relative offset 'offset'.
+void VP8RemapBitReader(VP8BitReader* const br, ptrdiff_t offset);
+
+// return the next value made of 'num_bits' bits
+uint32_t VP8GetValue(VP8BitReader* const br, int num_bits);
+static WEBP_INLINE uint32_t VP8Get(VP8BitReader* const br) {
+  return VP8GetValue(br, 1);
+}
+
+// return the next value with sign-extension.
+int32_t VP8GetSignedValue(VP8BitReader* const br, int num_bits);
+
+// bit_reader_inl.h will implement the following methods:
+//   static WEBP_INLINE int VP8GetBit(VP8BitReader* const br, int prob)
+//   static WEBP_INLINE int VP8GetSigned(VP8BitReader* const br, int v)
+// and should be included by the .c files that actually need them.
+// This is to avoid recompiling the whole library whenever this file is touched,
+// and also allowing platform-specific ad-hoc hacks.
+
+// -----------------------------------------------------------------------------
+// Bitreader for lossless format
+
+// maximum number of bits (inclusive) the bit-reader can handle:
+#define VP8L_MAX_NUM_BIT_READ 24
+
+#define VP8L_LBITS 64  // Number of bits prefetched.
+#define VP8L_WBITS 32  // Minimum number of bytes ready after VP8LFillBitWindow.
+
+typedef uint64_t vp8l_val_t;  // right now, this bit-reader can only use 64bit.
+
+typedef struct {
+  vp8l_val_t     val_;        // pre-fetched bits
+  const uint8_t* buf_;        // input byte buffer
+  size_t         len_;        // buffer length
+  size_t         pos_;        // byte position in buf_
+  int            bit_pos_;    // current bit-reading position in val_
+  int            eos_;        // true if a bit was read past the end of buffer
+} VP8LBitReader;
+
+void VP8LInitBitReader(VP8LBitReader* const br,
+                       const uint8_t* const start,
+                       size_t length);
+
+//  Sets a new data buffer.
+void VP8LBitReaderSetBuffer(VP8LBitReader* const br,
+                            const uint8_t* const buffer, size_t length);
+
+// Reads the specified number of bits from read buffer.
+// Flags an error in case end_of_stream or n_bits is more than the allowed limit
+// of VP8L_MAX_NUM_BIT_READ (inclusive).
+// Flags eos_ if this read attempt is going to cross the read buffer.
+uint32_t VP8LReadBits(VP8LBitReader* const br, int n_bits);
+
+// Return the prefetched bits, so they can be looked up.
+static WEBP_INLINE uint32_t VP8LPrefetchBits(VP8LBitReader* const br) {
+  return (uint32_t)(br->val_ >> br->bit_pos_);
+}
+
+// Returns true if there was an attempt at reading bit past the end of
+// the buffer. Doesn't set br->eos_ flag.
+static WEBP_INLINE int VP8LIsEndOfStream(const VP8LBitReader* const br) {
+  assert(br->pos_ <= br->len_);
+  return (br->pos_ == br->len_) && (br->bit_pos_ > VP8L_LBITS);
+}
+
+// For jumping over a number of bits in the bit stream when accessed with
+// VP8LPrefetchBits and VP8LFillBitWindow.
+static WEBP_INLINE void VP8LSetBitPos(VP8LBitReader* const br, int val) {
+  br->bit_pos_ = val;
+  br->eos_ = VP8LIsEndOfStream(br);
+}
+
+// Advances the read buffer by 4 bytes to make room for reading next 32 bits.
+// Speed critical, but infrequent part of the code can be non-inlined.
+extern void VP8LDoFillBitWindow(VP8LBitReader* const br);
+static WEBP_INLINE void VP8LFillBitWindow(VP8LBitReader* const br) {
+  if (br->bit_pos_ >= VP8L_WBITS) VP8LDoFillBitWindow(br);
+}
+
+#ifdef __cplusplus
+}    // extern "C"
+#endif
+
+#endif  /* WEBP_UTILS_BIT_READER_H_ */
diff --git a/Source/LibWebP/src/utils/bit_reader_inl.h b/Source/LibWebP/src/utils/bit_reader_inl.h
new file mode 100644
index 0000000..a5e4399
--- /dev/null
+++ b/Source/LibWebP/src/utils/bit_reader_inl.h
@@ -0,0 +1,172 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Specific inlined methods for boolean decoder [VP8GetBit() ...]
+// This file should be included by the .c sources that actually need to call
+// these methods.
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#ifndef WEBP_UTILS_BIT_READER_INL_H_
+#define WEBP_UTILS_BIT_READER_INL_H_
+
+#ifdef HAVE_CONFIG_H
+#include "../webp/config.h"
+#endif
+
+#ifdef WEBP_FORCE_ALIGNED
+#include <string.h>  // memcpy
+#endif
+
+#include "../dsp/dsp.h"
+#include "./bit_reader.h"
+#include "./endian_inl.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//------------------------------------------------------------------------------
+// Derived type lbit_t = natural type for memory I/O
+
+#if   (BITS > 32)
+typedef uint64_t lbit_t;
+#elif (BITS > 16)
+typedef uint32_t lbit_t;
+#elif (BITS >  8)
+typedef uint16_t lbit_t;
+#else
+typedef uint8_t lbit_t;
+#endif
+
+extern const uint8_t kVP8Log2Range[128];
+extern const uint8_t kVP8NewRange[128];
+
+// special case for the tail byte-reading
+void VP8LoadFinalBytes(VP8BitReader* const br);
+
+//------------------------------------------------------------------------------
+// Inlined critical functions
+
+// makes sure br->value_ has at least BITS bits worth of data
+static WEBP_INLINE void VP8LoadNewBytes(VP8BitReader* const br) {
+  assert(br != NULL && br->buf_ != NULL);
+  // Read 'BITS' bits at a time if possible.
+  if (br->buf_ + sizeof(lbit_t) <= br->buf_end_) {
+    // convert memory type to register type (with some zero'ing!)
+    bit_t bits;
+#if defined(WEBP_FORCE_ALIGNED)
+    lbit_t in_bits;
+    memcpy(&in_bits, br->buf_, sizeof(in_bits));
+#elif defined(WEBP_USE_MIPS32)
+    // This is needed because of un-aligned read.
+    lbit_t in_bits;
+    lbit_t* p_buf_ = (lbit_t*)br->buf_;
+    __asm__ volatile(
+      ".set   push                             \n\t"
+      ".set   at                               \n\t"
+      ".set   macro                            \n\t"
+      "ulw    %[in_bits], 0(%[p_buf_])         \n\t"
+      ".set   pop                              \n\t"
+      : [in_bits]"=r"(in_bits)
+      : [p_buf_]"r"(p_buf_)
+      : "memory", "at"
+    );
+#else
+    const lbit_t in_bits = *(const lbit_t*)br->buf_;
+#endif
+    br->buf_ += BITS >> 3;
+#if !defined(WORDS_BIGENDIAN)
+#if (BITS > 32)
+    bits = BSwap64(in_bits);
+    bits >>= 64 - BITS;
+#elif (BITS >= 24)
+    bits = BSwap32(in_bits);
+    bits >>= (32 - BITS);
+#elif (BITS == 16)
+    bits = BSwap16(in_bits);
+#else   // BITS == 8
+    bits = (bit_t)in_bits;
+#endif  // BITS > 32
+#else    // WORDS_BIGENDIAN
+    bits = (bit_t)in_bits;
+    if (BITS != 8 * sizeof(bit_t)) bits >>= (8 * sizeof(bit_t) - BITS);
+#endif
+    br->value_ = bits | (br->value_ << BITS);
+    br->bits_ += BITS;
+  } else {
+    VP8LoadFinalBytes(br);    // no need to be inlined
+  }
+}
+
+// Read a bit with proba 'prob'. Speed-critical function!
+static WEBP_INLINE int VP8GetBit(VP8BitReader* const br, int prob) {
+  // Don't move this declaration! It makes a big speed difference to store
+  // 'range' *before* calling VP8LoadNewBytes(), even if this function doesn't
+  // alter br->range_ value.
+  range_t range = br->range_;
+  if (br->bits_ < 0) {
+    VP8LoadNewBytes(br);
+  }
+  {
+    const int pos = br->bits_;
+    const range_t split = (range * prob) >> 8;
+    const range_t value = (range_t)(br->value_ >> pos);
+#if defined(__arm__) || defined(_M_ARM)      // ARM-specific
+    const int bit = ((int)(split - value) >> 31) & 1;
+    if (value > split) {
+      range -= split + 1;
+      br->value_ -= (bit_t)(split + 1) << pos;
+    } else {
+      range = split;
+    }
+#else  // faster version on x86
+    int bit;  // Don't use 'const int bit = (value > split);", it's slower.
+    if (value > split) {
+      range -= split + 1;
+      br->value_ -= (bit_t)(split + 1) << pos;
+      bit = 1;
+    } else {
+      range = split;
+      bit = 0;
+    }
+#endif
+    if (range <= (range_t)0x7e) {
+      const int shift = kVP8Log2Range[range];
+      range = kVP8NewRange[range];
+      br->bits_ -= shift;
+    }
+    br->range_ = range;
+    return bit;
+  }
+}
+
+// simplified version of VP8GetBit() for prob=0x80 (note shift is always 1 here)
+static WEBP_INLINE int VP8GetSigned(VP8BitReader* const br, int v) {
+  if (br->bits_ < 0) {
+    VP8LoadNewBytes(br);
+  }
+  {
+    const int pos = br->bits_;
+    const range_t split = br->range_ >> 1;
+    const range_t value = (range_t)(br->value_ >> pos);
+    const int32_t mask = (int32_t)(split - value) >> 31;  // -1 or 0
+    br->bits_ -= 1;
+    br->range_ += mask;
+    br->range_ |= 1;
+    br->value_ -= (bit_t)((split + 1) & mask) << pos;
+    return (v ^ mask) - mask;
+  }
+}
+
+#ifdef __cplusplus
+}    // extern "C"
+#endif
+
+#endif   // WEBP_UTILS_BIT_READER_INL_H_
diff --git a/Source/LibWebP/src/utils/bit_writer.h b/Source/LibWebP/src/utils/bit_writer.h
new file mode 100644
index 0000000..c4be992
--- /dev/null
+++ b/Source/LibWebP/src/utils/bit_writer.h
@@ -0,0 +1,120 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Bit writing and boolean coder
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#ifndef WEBP_UTILS_BIT_WRITER_H_
+#define WEBP_UTILS_BIT_WRITER_H_
+
+#include "../webp/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//------------------------------------------------------------------------------
+// Bit-writing
+
+typedef struct VP8BitWriter VP8BitWriter;
+struct VP8BitWriter {
+  int32_t  range_;      // range-1
+  int32_t  value_;
+  int      run_;        // number of outstanding bits
+  int      nb_bits_;    // number of pending bits
+  uint8_t* buf_;        // internal buffer. Re-allocated regularly. Not owned.
+  size_t   pos_;
+  size_t   max_pos_;
+  int      error_;      // true in case of error
+};
+
+// Initialize the object. Allocates some initial memory based on expected_size.
+int VP8BitWriterInit(VP8BitWriter* const bw, size_t expected_size);
+// Finalize the bitstream coding. Returns a pointer to the internal buffer.
+uint8_t* VP8BitWriterFinish(VP8BitWriter* const bw);
+// Release any pending memory and zeroes the object. Not a mandatory call.
+// Only useful in case of error, when the internal buffer hasn't been grabbed!
+void VP8BitWriterWipeOut(VP8BitWriter* const bw);
+
+int VP8PutBit(VP8BitWriter* const bw, int bit, int prob);
+int VP8PutBitUniform(VP8BitWriter* const bw, int bit);
+void VP8PutBits(VP8BitWriter* const bw, uint32_t value, int nb_bits);
+void VP8PutSignedBits(VP8BitWriter* const bw, int value, int nb_bits);
+
+// Appends some bytes to the internal buffer. Data is copied.
+int VP8BitWriterAppend(VP8BitWriter* const bw,
+                       const uint8_t* data, size_t size);
+
+// return approximate write position (in bits)
+static WEBP_INLINE uint64_t VP8BitWriterPos(const VP8BitWriter* const bw) {
+  return (uint64_t)(bw->pos_ + bw->run_) * 8 + 8 + bw->nb_bits_;
+}
+
+// Returns a pointer to the internal buffer.
+static WEBP_INLINE uint8_t* VP8BitWriterBuf(const VP8BitWriter* const bw) {
+  return bw->buf_;
+}
+// Returns the size of the internal buffer.
+static WEBP_INLINE size_t VP8BitWriterSize(const VP8BitWriter* const bw) {
+  return bw->pos_;
+}
+
+//------------------------------------------------------------------------------
+// VP8LBitWriter
+
+#if defined(__x86_64__) || defined(_M_X64)   // 64bit
+typedef uint64_t vp8l_atype_t;   // accumulator type
+typedef uint32_t vp8l_wtype_t;   // writing type
+#define WSWAP HToLE32
+#else
+typedef uint32_t vp8l_atype_t;
+typedef uint16_t vp8l_wtype_t;
+#define WSWAP HToLE16
+#endif
+
+typedef struct {
+  vp8l_atype_t bits_;   // bit accumulator
+  int          used_;   // number of bits used in accumulator
+  uint8_t*     buf_;    // start of buffer
+  uint8_t*     cur_;    // current write position
+  uint8_t*     end_;    // end of buffer
+
+  // After all bits are written (VP8LBitWriterFinish()), the caller must observe
+  // the state of error_. A value of 1 indicates that a memory allocation
+  // failure has happened during bit writing. A value of 0 indicates successful
+  // writing of bits.
+  int error_;
+} VP8LBitWriter;
+
+static WEBP_INLINE size_t VP8LBitWriterNumBytes(VP8LBitWriter* const bw) {
+  return (bw->cur_ - bw->buf_) + ((bw->used_ + 7) >> 3);
+}
+
+// Returns false in case of memory allocation error.
+int VP8LBitWriterInit(VP8LBitWriter* const bw, size_t expected_size);
+// Finalize the bitstream coding. Returns a pointer to the internal buffer.
+uint8_t* VP8LBitWriterFinish(VP8LBitWriter* const bw);
+// Release any pending memory and zeroes the object.
+void VP8LBitWriterWipeOut(VP8LBitWriter* const bw);
+
+// This function writes bits into bytes in increasing addresses (little endian),
+// and within a byte least-significant-bit first.
+// This function can write up to 32 bits in one go, but VP8LBitReader can only
+// read 24 bits max (VP8L_MAX_NUM_BIT_READ).
+// VP8LBitWriter's error_ flag is set in case of  memory allocation error.
+void VP8LPutBits(VP8LBitWriter* const bw, uint32_t bits, int n_bits);
+
+//------------------------------------------------------------------------------
+
+#ifdef __cplusplus
+}    // extern "C"
+#endif
+
+#endif  /* WEBP_UTILS_BIT_WRITER_H_ */
diff --git a/Source/LibWebP/src/utils/color_cache.h b/Source/LibWebP/src/utils/color_cache.h
new file mode 100644
index 0000000..c3ae314
--- /dev/null
+++ b/Source/LibWebP/src/utils/color_cache.h
@@ -0,0 +1,74 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Color Cache for WebP Lossless
+//
+// Authors: Jyrki Alakuijala (jyrki at google.com)
+//          Urvang Joshi (urvang at google.com)
+
+#ifndef WEBP_UTILS_COLOR_CACHE_H_
+#define WEBP_UTILS_COLOR_CACHE_H_
+
+#include "../webp/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Main color cache struct.
+typedef struct {
+  uint32_t *colors_;  // color entries
+  int hash_shift_;    // Hash shift: 32 - hash_bits_.
+  int hash_bits_;
+} VP8LColorCache;
+
+static const uint32_t kHashMul = 0x1e35a7bd;
+
+static WEBP_INLINE uint32_t VP8LColorCacheLookup(
+    const VP8LColorCache* const cc, uint32_t key) {
+  assert(key <= (~0U >> cc->hash_shift_));
+  return cc->colors_[key];
+}
+
+static WEBP_INLINE void VP8LColorCacheInsert(const VP8LColorCache* const cc,
+                                             uint32_t argb) {
+  const uint32_t key = (kHashMul * argb) >> cc->hash_shift_;
+  cc->colors_[key] = argb;
+}
+
+static WEBP_INLINE int VP8LColorCacheGetIndex(const VP8LColorCache* const cc,
+                                              uint32_t argb) {
+  return (kHashMul * argb) >> cc->hash_shift_;
+}
+
+static WEBP_INLINE int VP8LColorCacheContains(const VP8LColorCache* const cc,
+                                              uint32_t argb) {
+  const uint32_t key = (kHashMul * argb) >> cc->hash_shift_;
+  return cc->colors_[key] == argb;
+}
+
+//------------------------------------------------------------------------------
+
+// Initializes the color cache with 'hash_bits' bits for the keys.
+// Returns false in case of memory error.
+int VP8LColorCacheInit(VP8LColorCache* const color_cache, int hash_bits);
+
+void VP8LColorCacheCopy(const VP8LColorCache* const src,
+                        VP8LColorCache* const dst);
+
+// Delete the memory associated to color cache.
+void VP8LColorCacheClear(VP8LColorCache* const color_cache);
+
+//------------------------------------------------------------------------------
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // WEBP_UTILS_COLOR_CACHE_H_
diff --git a/Source/LibWebP/src/utils/endian_inl.h b/Source/LibWebP/src/utils/endian_inl.h
new file mode 100644
index 0000000..d9a484f
--- /dev/null
+++ b/Source/LibWebP/src/utils/endian_inl.h
@@ -0,0 +1,100 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Endian related functions.
+
+#ifndef WEBP_UTILS_ENDIAN_INL_H_
+#define WEBP_UTILS_ENDIAN_INL_H_
+
+#ifdef HAVE_CONFIG_H
+#include "../webp/config.h"
+#endif
+
+#include "../dsp/dsp.h"
+#include "../webp/types.h"
+
+// some endian fix (e.g.: mips-gcc doesn't define __BIG_ENDIAN__)
+#if !defined(WORDS_BIGENDIAN) && \
+    (defined(__BIG_ENDIAN__) || defined(_M_PPC) || \
+     (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)))
+#define WORDS_BIGENDIAN
+#endif
+
+#if defined(WORDS_BIGENDIAN)
+#define HToLE32 BSwap32
+#define HToLE16 BSwap16
+#else
+#define HToLE32(x) (x)
+#define HToLE16(x) (x)
+#endif
+
+#if !defined(HAVE_CONFIG_H)
+// clang-3.3 and gcc-4.3 have builtin functions for swap32/swap64
+#if LOCAL_GCC_PREREQ(4,3) || LOCAL_CLANG_PREREQ(3,3)
+#define HAVE_BUILTIN_BSWAP32
+#define HAVE_BUILTIN_BSWAP64
+#endif
+// clang-3.3 and gcc-4.8 have a builtin function for swap16
+#if LOCAL_GCC_PREREQ(4,8) || LOCAL_CLANG_PREREQ(3,3)
+#define HAVE_BUILTIN_BSWAP16
+#endif
+#endif  // !HAVE_CONFIG_H
+
+static WEBP_INLINE uint16_t BSwap16(uint16_t x) {
+#if defined(HAVE_BUILTIN_BSWAP16)
+  return __builtin_bswap16(x);
+#elif defined(_MSC_VER)
+  return _byteswap_ushort(x);
+#else
+  // gcc will recognize a 'rorw $8, ...' here:
+  return (x >> 8) | ((x & 0xff) << 8);
+#endif  // HAVE_BUILTIN_BSWAP16
+}
+
+static WEBP_INLINE uint32_t BSwap32(uint32_t x) {
+#if defined(WEBP_USE_MIPS32_R2)
+  uint32_t ret;
+  __asm__ volatile (
+    "wsbh   %[ret], %[x]          \n\t"
+    "rotr   %[ret], %[ret],  16   \n\t"
+    : [ret]"=r"(ret)
+    : [x]"r"(x)
+  );
+  return ret;
+#elif defined(HAVE_BUILTIN_BSWAP32)
+  return __builtin_bswap32(x);
+#elif defined(__i386__) || defined(__x86_64__)
+  uint32_t swapped_bytes;
+  __asm__ volatile("bswap %0" : "=r"(swapped_bytes) : "0"(x));
+  return swapped_bytes;
+#elif defined(_MSC_VER)
+  return (uint32_t)_byteswap_ulong(x);
+#else
+  return (x >> 24) | ((x >> 8) & 0xff00) | ((x << 8) & 0xff0000) | (x << 24);
+#endif  // HAVE_BUILTIN_BSWAP32
+}
+
+static WEBP_INLINE uint64_t BSwap64(uint64_t x) {
+#if defined(HAVE_BUILTIN_BSWAP64)
+  return __builtin_bswap64(x);
+#elif defined(__x86_64__)
+  uint64_t swapped_bytes;
+  __asm__ volatile("bswapq %0" : "=r"(swapped_bytes) : "0"(x));
+  return swapped_bytes;
+#elif defined(_MSC_VER)
+  return (uint64_t)_byteswap_uint64(x);
+#else  // generic code for swapping 64-bit values (suggested by bdb@)
+  x = ((x & 0xffffffff00000000ull) >> 32) | ((x & 0x00000000ffffffffull) << 32);
+  x = ((x & 0xffff0000ffff0000ull) >> 16) | ((x & 0x0000ffff0000ffffull) << 16);
+  x = ((x & 0xff00ff00ff00ff00ull) >>  8) | ((x & 0x00ff00ff00ff00ffull) <<  8);
+  return x;
+#endif  // HAVE_BUILTIN_BSWAP64
+}
+
+#endif  // WEBP_UTILS_ENDIAN_INL_H_
diff --git a/Source/LibWebP/src/utils/filters.h b/Source/LibWebP/src/utils/filters.h
new file mode 100644
index 0000000..76609e0
--- /dev/null
+++ b/Source/LibWebP/src/utils/filters.h
@@ -0,0 +1,32 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Spatial prediction using various filters
+//
+// Author: Urvang (urvang at google.com)
+
+#ifndef WEBP_UTILS_FILTERS_H_
+#define WEBP_UTILS_FILTERS_H_
+
+#include "../webp/types.h"
+#include "../dsp/dsp.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Fast estimate of a potentially good filter.
+WEBP_FILTER_TYPE WebPEstimateBestFilter(const uint8_t* data,
+                                        int width, int height, int stride);
+
+#ifdef __cplusplus
+}    // extern "C"
+#endif
+
+#endif  /* WEBP_UTILS_FILTERS_H_ */
diff --git a/Source/LibWebP/src/utils/huffman.h b/Source/LibWebP/src/utils/huffman.h
new file mode 100644
index 0000000..c28ca32
--- /dev/null
+++ b/Source/LibWebP/src/utils/huffman.h
@@ -0,0 +1,67 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Utilities for building and looking up Huffman trees.
+//
+// Author: Urvang Joshi (urvang at google.com)
+
+#ifndef WEBP_UTILS_HUFFMAN_H_
+#define WEBP_UTILS_HUFFMAN_H_
+
+#include <assert.h>
+#include "../webp/format_constants.h"
+#include "../webp/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define HUFFMAN_TABLE_BITS      8
+#define HUFFMAN_TABLE_MASK      ((1 << HUFFMAN_TABLE_BITS) - 1)
+
+#define LENGTHS_TABLE_BITS      7
+#define LENGTHS_TABLE_MASK      ((1 << LENGTHS_TABLE_BITS) - 1)
+
+
+// Huffman lookup table entry
+typedef struct {
+  uint8_t bits;     // number of bits used for this symbol
+  uint16_t value;   // symbol value or table offset
+} HuffmanCode;
+
+// Huffman table group.
+typedef struct HTreeGroup HTreeGroup;
+struct HTreeGroup {
+  HuffmanCode* htrees[HUFFMAN_CODES_PER_META_CODE];
+  int      is_trivial_literal;  // True, if huffman trees for Red, Blue & Alpha
+                                // Symbols are trivial (have a single code).
+  uint32_t literal_arb;         // If is_trivial_literal is true, this is the
+                                // ARGB value of the pixel, with Green channel
+                                // being set to zero.
+};
+
+// Creates the instance of HTreeGroup with specified number of tree-groups.
+HTreeGroup* VP8LHtreeGroupsNew(int num_htree_groups);
+
+// Releases the memory allocated for HTreeGroup.
+void VP8LHtreeGroupsFree(HTreeGroup* const htree_groups);
+
+// Builds Huffman lookup table assuming code lengths are in symbol order.
+// The 'code_lengths' is pre-allocated temporary memory buffer used for creating
+// the huffman table.
+// Returns built table size or 0 in case of error (invalid tree or
+// memory error).
+int VP8LBuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
+                          const int code_lengths[], int code_lengths_size);
+
+#ifdef __cplusplus
+}    // extern "C"
+#endif
+
+#endif  // WEBP_UTILS_HUFFMAN_H_
diff --git a/Source/LibWebP/src/utils/huffman_encode.h b/Source/LibWebP/src/utils/huffman_encode.h
new file mode 100644
index 0000000..1b28287
--- /dev/null
+++ b/Source/LibWebP/src/utils/huffman_encode.h
@@ -0,0 +1,60 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Author: Jyrki Alakuijala (jyrki at google.com)
+//
+// Entropy encoding (Huffman) for webp lossless
+
+#ifndef WEBP_UTILS_HUFFMAN_ENCODE_H_
+#define WEBP_UTILS_HUFFMAN_ENCODE_H_
+
+#include "../webp/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Struct for holding the tree header in coded form.
+typedef struct {
+  uint8_t code;         // value (0..15) or escape code (16,17,18)
+  uint8_t extra_bits;   // extra bits for escape codes
+} HuffmanTreeToken;
+
+// Struct to represent the tree codes (depth and bits array).
+typedef struct {
+  int       num_symbols;   // Number of symbols.
+  uint8_t*  code_lengths;  // Code lengths of the symbols.
+  uint16_t* codes;         // Symbol Codes.
+} HuffmanTreeCode;
+
+// Struct to represent the Huffman tree.
+typedef struct {
+  uint32_t total_count_;   // Symbol frequency.
+  int value_;              // Symbol value.
+  int pool_index_left_;    // Index for the left sub-tree.
+  int pool_index_right_;   // Index for the right sub-tree.
+} HuffmanTree;
+
+// Turn the Huffman tree into a token sequence.
+// Returns the number of tokens used.
+int VP8LCreateCompressedHuffmanTree(const HuffmanTreeCode* const tree,
+                                    HuffmanTreeToken* tokens, int max_tokens);
+
+// Create an optimized tree, and tokenize it.
+// 'buf_rle' and 'huff_tree' are pre-allocated and the 'tree' is the constructed
+// huffman code tree.
+void VP8LCreateHuffmanTree(uint32_t* const histogram, int tree_depth_limit,
+                           uint8_t* const buf_rle, HuffmanTree* const huff_tree,
+                           HuffmanTreeCode* const tree);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // WEBP_UTILS_HUFFMAN_ENCODE_H_
diff --git a/Source/LibWebP/src/utils/quant_levels.h b/Source/LibWebP/src/utils/quant_levels.h
new file mode 100644
index 0000000..a3f2dcb
--- /dev/null
+++ b/Source/LibWebP/src/utils/quant_levels.h
@@ -0,0 +1,36 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Alpha plane quantization utility
+//
+// Author:  Vikas Arora (vikasa at google.com)
+
+#ifndef WEBP_UTILS_QUANT_LEVELS_H_
+#define WEBP_UTILS_QUANT_LEVELS_H_
+
+#include <stdlib.h>
+
+#include "../webp/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Replace the input 'data' of size 'width'x'height' with 'num-levels'
+// quantized values. If not NULL, 'sse' will contain the sum of squared error.
+// Valid range for 'num_levels' is [2, 256].
+// Returns false in case of error (data is NULL, or parameters are invalid).
+int QuantizeLevels(uint8_t* const data, int width, int height, int num_levels,
+                   uint64_t* const sse);
+
+#ifdef __cplusplus
+}    // extern "C"
+#endif
+
+#endif  /* WEBP_UTILS_QUANT_LEVELS_H_ */
diff --git a/Source/LibWebP/src/utils/quant_levels_dec.h b/Source/LibWebP/src/utils/quant_levels_dec.h
new file mode 100644
index 0000000..ac3d720
--- /dev/null
+++ b/Source/LibWebP/src/utils/quant_levels_dec.h
@@ -0,0 +1,35 @@
+// Copyright 2013 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Alpha plane de-quantization utility
+//
+// Author:  Vikas Arora (vikasa at google.com)
+
+#ifndef WEBP_UTILS_QUANT_LEVELS_DEC_H_
+#define WEBP_UTILS_QUANT_LEVELS_DEC_H_
+
+#include "../webp/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Apply post-processing to input 'data' of size 'width'x'height' assuming that
+// the source was quantized to a reduced number of levels.
+// Strength is in [0..100] and controls the amount of dithering applied.
+// Returns false in case of error (data is NULL, invalid parameters,
+// malloc failure, ...).
+int WebPDequantizeLevels(uint8_t* const data, int width, int height,
+                         int strength);
+
+#ifdef __cplusplus
+}    // extern "C"
+#endif
+
+#endif  /* WEBP_UTILS_QUANT_LEVELS_DEC_H_ */
diff --git a/Source/LibWebP/src/utils/random.h b/Source/LibWebP/src/utils/random.h
new file mode 100644
index 0000000..9993668
--- /dev/null
+++ b/Source/LibWebP/src/utils/random.h
@@ -0,0 +1,63 @@
+// Copyright 2013 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Pseudo-random utilities
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#ifndef WEBP_UTILS_RANDOM_H_
+#define WEBP_UTILS_RANDOM_H_
+
+#include <assert.h>
+#include "../webp/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define VP8_RANDOM_DITHER_FIX 8   // fixed-point precision for dithering
+#define VP8_RANDOM_TABLE_SIZE 55
+
+typedef struct {
+  int index1_, index2_;
+  uint32_t tab_[VP8_RANDOM_TABLE_SIZE];
+  int amp_;
+} VP8Random;
+
+// Initializes random generator with an amplitude 'dithering' in range [0..1].
+void VP8InitRandom(VP8Random* const rg, float dithering);
+
+// Returns a centered pseudo-random number with 'num_bits' amplitude.
+// (uses D.Knuth's Difference-based random generator).
+// 'amp' is in VP8_RANDOM_DITHER_FIX fixed-point precision.
+static WEBP_INLINE int VP8RandomBits2(VP8Random* const rg, int num_bits,
+                                      int amp) {
+  int diff;
+  assert(num_bits + VP8_RANDOM_DITHER_FIX <= 31);
+  diff = rg->tab_[rg->index1_] - rg->tab_[rg->index2_];
+  if (diff < 0) diff += (1u << 31);
+  rg->tab_[rg->index1_] = diff;
+  if (++rg->index1_ == VP8_RANDOM_TABLE_SIZE) rg->index1_ = 0;
+  if (++rg->index2_ == VP8_RANDOM_TABLE_SIZE) rg->index2_ = 0;
+  // sign-extend, 0-center
+  diff = (int)((uint32_t)diff << 1) >> (32 - num_bits);
+  diff = (diff * amp) >> VP8_RANDOM_DITHER_FIX;  // restrict range
+  diff += 1 << (num_bits - 1);                   // shift back to 0.5-center
+  return diff;
+}
+
+static WEBP_INLINE int VP8RandomBits(VP8Random* const rg, int num_bits) {
+  return VP8RandomBits2(rg, num_bits, rg->amp_);
+}
+
+#ifdef __cplusplus
+}    // extern "C"
+#endif
+
+#endif  /* WEBP_UTILS_RANDOM_H_ */
diff --git a/Source/LibWebP/src/utils/rescaler.h b/Source/LibWebP/src/utils/rescaler.h
new file mode 100644
index 0000000..ff3f70e
--- /dev/null
+++ b/Source/LibWebP/src/utils/rescaler.h
@@ -0,0 +1,78 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Rescaling functions
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#ifndef WEBP_UTILS_RESCALER_H_
+#define WEBP_UTILS_RESCALER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "../webp/types.h"
+
+#define WEBP_RESCALER_RFIX 30   // fixed-point precision for multiplies
+
+// Structure used for on-the-fly rescaling
+typedef struct WebPRescaler WebPRescaler;
+struct WebPRescaler {
+  int x_expand;               // true if we're expanding in the x direction
+  int num_channels;           // bytes to jump between pixels
+  int fy_scale, fx_scale;     // fixed-point scaling factor
+  int64_t fxy_scale;          // ''
+  // we need hpel-precise add/sub increments, for the downsampled U/V planes.
+  int y_accum;                // vertical accumulator
+  int y_add, y_sub;           // vertical increments (add ~= src, sub ~= dst)
+  int x_add, x_sub;           // horizontal increments (add ~= src, sub ~= dst)
+  int src_width, src_height;  // source dimensions
+  int dst_width, dst_height;  // destination dimensions
+  uint8_t* dst;
+  int dst_stride;
+  int32_t* irow, *frow;       // work buffer
+};
+
+// Initialize a rescaler given scratch area 'work' and dimensions of src & dst.
+void WebPRescalerInit(WebPRescaler* const rescaler,
+                      int src_width, int src_height,
+                      uint8_t* const dst,
+                      int dst_width, int dst_height, int dst_stride,
+                      int num_channels,
+                      int x_add, int x_sub,
+                      int y_add, int y_sub,
+                      int32_t* const work);
+
+// Returns the number of input lines needed next to produce one output line,
+// considering that the maximum available input lines are 'max_num_lines'.
+int WebPRescaleNeededLines(const WebPRescaler* const rescaler,
+                           int max_num_lines);
+
+// Import multiple rows over all channels, until at least one row is ready to
+// be exported. Returns the actual number of lines that were imported.
+int WebPRescalerImport(WebPRescaler* const rescaler, int num_rows,
+                       const uint8_t* src, int src_stride);
+
+// Return true if there is pending output rows ready.
+static WEBP_INLINE
+int WebPRescalerHasPendingOutput(const WebPRescaler* const rescaler) {
+  return (rescaler->y_accum <= 0);
+}
+
+// Export as many rows as possible. Return the numbers of rows written.
+int WebPRescalerExport(WebPRescaler* const rescaler);
+
+//------------------------------------------------------------------------------
+
+#ifdef __cplusplus
+}    // extern "C"
+#endif
+
+#endif  /* WEBP_UTILS_RESCALER_H_ */
diff --git a/Source/LibWebP/src/utils/thread.h b/Source/LibWebP/src/utils/thread.h
new file mode 100644
index 0000000..3b6c84f
--- /dev/null
+++ b/Source/LibWebP/src/utils/thread.h
@@ -0,0 +1,93 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Multi-threaded worker
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#ifndef WEBP_UTILS_THREAD_H_
+#define WEBP_UTILS_THREAD_H_
+
+#ifdef HAVE_CONFIG_H
+#include "../webp/config.h"
+#endif
+
+#include "../webp/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// State of the worker thread object
+typedef enum {
+  NOT_OK = 0,   // object is unusable
+  OK,           // ready to work
+  WORK          // busy finishing the current task
+} WebPWorkerStatus;
+
+// Function to be called by the worker thread. Takes two opaque pointers as
+// arguments (data1 and data2), and should return false in case of error.
+typedef int (*WebPWorkerHook)(void*, void*);
+
+// Platform-dependent implementation details for the worker.
+typedef struct WebPWorkerImpl WebPWorkerImpl;
+
+// Synchronization object used to launch job in the worker thread
+typedef struct {
+  WebPWorkerImpl* impl_;
+  WebPWorkerStatus status_;
+  WebPWorkerHook hook;    // hook to call
+  void* data1;            // first argument passed to 'hook'
+  void* data2;            // second argument passed to 'hook'
+  int had_error;          // return value of the last call to 'hook'
+} WebPWorker;
+
+// The interface for all thread-worker related functions. All these functions
+// must be implemented.
+typedef struct {
+  // Must be called first, before any other method.
+  void (*Init)(WebPWorker* const worker);
+  // Must be called to initialize the object and spawn the thread. Re-entrant.
+  // Will potentially launch the thread. Returns false in case of error.
+  int (*Reset)(WebPWorker* const worker);
+  // Makes sure the previous work is finished. Returns true if worker->had_error
+  // was not set and no error condition was triggered by the working thread.
+  int (*Sync)(WebPWorker* const worker);
+  // Triggers the thread to call hook() with data1 and data2 arguments. These
+  // hook/data1/data2 values can be changed at any time before calling this
+  // function, but not be changed afterward until the next call to Sync().
+  void (*Launch)(WebPWorker* const worker);
+  // This function is similar to Launch() except that it calls the
+  // hook directly instead of using a thread. Convenient to bypass the thread
+  // mechanism while still using the WebPWorker structs. Sync() must
+  // still be called afterward (for error reporting).
+  void (*Execute)(WebPWorker* const worker);
+  // Kill the thread and terminate the object. To use the object again, one
+  // must call Reset() again.
+  void (*End)(WebPWorker* const worker);
+} WebPWorkerInterface;
+
+// Install a new set of threading functions, overriding the defaults. This
+// should be done before any workers are started, i.e., before any encoding or
+// decoding takes place. The contents of the interface struct are copied, it
+// is safe to free the corresponding memory after this call. This function is
+// not thread-safe. Return false in case of invalid pointer or methods.
+WEBP_EXTERN(int) WebPSetWorkerInterface(
+    const WebPWorkerInterface* const interface);
+
+// Retrieve the currently set thread worker interface.
+WEBP_EXTERN(const WebPWorkerInterface*) WebPGetWorkerInterface(void);
+
+//------------------------------------------------------------------------------
+
+#ifdef __cplusplus
+}    // extern "C"
+#endif
+
+#endif  /* WEBP_UTILS_THREAD_H_ */
diff --git a/Source/LibWebP/src/utils/utils.bit_reader.c b/Source/LibWebP/src/utils/utils.bit_reader.c
new file mode 100644
index 0000000..aa65e97
--- /dev/null
+++ b/Source/LibWebP/src/utils/utils.bit_reader.c
@@ -0,0 +1,208 @@
+// Copyright 2010 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Boolean decoder non-inlined methods
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#ifdef HAVE_CONFIG_H
+#include "../webp/config.h"
+#endif
+
+#include "./bit_reader_inl.h"
+
+//------------------------------------------------------------------------------
+// VP8BitReader
+
+void VP8InitBitReader(VP8BitReader* const br,
+                      const uint8_t* const start, const uint8_t* const end) {
+  assert(br != NULL);
+  assert(start != NULL);
+  assert(start <= end);
+  br->range_   = 255 - 1;
+  br->buf_     = start;
+  br->buf_end_ = end;
+  br->value_   = 0;
+  br->bits_    = -8;   // to load the very first 8bits
+  br->eof_     = 0;
+  VP8LoadNewBytes(br);
+}
+
+void VP8RemapBitReader(VP8BitReader* const br, ptrdiff_t offset) {
+  if (br->buf_ != NULL) {
+    br->buf_ += offset;
+    br->buf_end_ += offset;
+  }
+}
+
+const uint8_t kVP8Log2Range[128] = {
+     7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+  0
+};
+
+// range = ((range - 1) << kVP8Log2Range[range]) + 1
+const uint8_t kVP8NewRange[128] = {
+  127, 127, 191, 127, 159, 191, 223, 127,
+  143, 159, 175, 191, 207, 223, 239, 127,
+  135, 143, 151, 159, 167, 175, 183, 191,
+  199, 207, 215, 223, 231, 239, 247, 127,
+  131, 135, 139, 143, 147, 151, 155, 159,
+  163, 167, 171, 175, 179, 183, 187, 191,
+  195, 199, 203, 207, 211, 215, 219, 223,
+  227, 231, 235, 239, 243, 247, 251, 127,
+  129, 131, 133, 135, 137, 139, 141, 143,
+  145, 147, 149, 151, 153, 155, 157, 159,
+  161, 163, 165, 167, 169, 171, 173, 175,
+  177, 179, 181, 183, 185, 187, 189, 191,
+  193, 195, 197, 199, 201, 203, 205, 207,
+  209, 211, 213, 215, 217, 219, 221, 223,
+  225, 227, 229, 231, 233, 235, 237, 239,
+  241, 243, 245, 247, 249, 251, 253, 127
+};
+
+void VP8LoadFinalBytes(VP8BitReader* const br) {
+  assert(br != NULL && br->buf_ != NULL);
+  // Only read 8bits at a time
+  if (br->buf_ < br->buf_end_) {
+    br->bits_ += 8;
+    br->value_ = (bit_t)(*br->buf_++) | (br->value_ << 8);
+  } else if (!br->eof_) {
+    br->value_ <<= 8;
+    br->bits_ += 8;
+    br->eof_ = 1;
+  }
+}
+
+//------------------------------------------------------------------------------
+// Higher-level calls
+
+uint32_t VP8GetValue(VP8BitReader* const br, int bits) {
+  uint32_t v = 0;
+  while (bits-- > 0) {
+    v |= VP8GetBit(br, 0x80) << bits;
+  }
+  return v;
+}
+
+int32_t VP8GetSignedValue(VP8BitReader* const br, int bits) {
+  const int value = VP8GetValue(br, bits);
+  return VP8Get(br) ? -value : value;
+}
+
+//------------------------------------------------------------------------------
+// VP8LBitReader
+
+#define VP8L_LOG8_WBITS 4  // Number of bytes needed to store VP8L_WBITS bits.
+
+#if !defined(WEBP_FORCE_ALIGNED) && \
+    (defined(__arm__) || defined(_M_ARM) || defined(__aarch64__) || \
+     defined(__i386__) || defined(_M_IX86) || \
+     defined(__x86_64__) || defined(_M_X64))
+#define VP8L_USE_UNALIGNED_LOAD
+#endif
+
+static const uint32_t kBitMask[VP8L_MAX_NUM_BIT_READ + 1] = {
+  0,
+  0x000001, 0x000003, 0x000007, 0x00000f,
+  0x00001f, 0x00003f, 0x00007f, 0x0000ff,
+  0x0001ff, 0x0003ff, 0x0007ff, 0x000fff,
+  0x001fff, 0x003fff, 0x007fff, 0x00ffff,
+  0x01ffff, 0x03ffff, 0x07ffff, 0x0fffff,
+  0x1fffff, 0x3fffff, 0x7fffff, 0xffffff
+};
+
+void VP8LInitBitReader(VP8LBitReader* const br, const uint8_t* const start,
+                       size_t length) {
+  size_t i;
+  vp8l_val_t value = 0;
+  assert(br != NULL);
+  assert(start != NULL);
+  assert(length < 0xfffffff8u);   // can't happen with a RIFF chunk.
+
+  br->len_ = length;
+  br->val_ = 0;
+  br->bit_pos_ = 0;
+  br->eos_ = 0;
+
+  if (length > sizeof(br->val_)) {
+    length = sizeof(br->val_);
+  }
+  for (i = 0; i < length; ++i) {
+    value |= (vp8l_val_t)start[i] << (8 * i);
+  }
+  br->val_ = value;
+  br->pos_ = length;
+  br->buf_ = start;
+}
+
+void VP8LBitReaderSetBuffer(VP8LBitReader* const br,
+                            const uint8_t* const buf, size_t len) {
+  assert(br != NULL);
+  assert(buf != NULL);
+  assert(len < 0xfffffff8u);   // can't happen with a RIFF chunk.
+  br->buf_ = buf;
+  br->len_ = len;
+  // pos_ > len_ should be considered a param error.
+  br->eos_ = (br->pos_ > br->len_) || VP8LIsEndOfStream(br);
+}
+
+// If not at EOS, reload up to VP8L_LBITS byte-by-byte
+static void ShiftBytes(VP8LBitReader* const br) {
+  while (br->bit_pos_ >= 8 && br->pos_ < br->len_) {
+    br->val_ >>= 8;
+    br->val_ |= ((vp8l_val_t)br->buf_[br->pos_]) << (VP8L_LBITS - 8);
+    ++br->pos_;
+    br->bit_pos_ -= 8;
+  }
+  br->eos_ = VP8LIsEndOfStream(br);
+}
+
+void VP8LDoFillBitWindow(VP8LBitReader* const br) {
+  assert(br->bit_pos_ >= VP8L_WBITS);
+  // TODO(jzern): given the fixed read size it may be possible to force
+  //              alignment in this block.
+#if defined(VP8L_USE_UNALIGNED_LOAD)
+  if (br->pos_ + sizeof(br->val_) < br->len_) {
+    br->val_ >>= VP8L_WBITS;
+    br->bit_pos_ -= VP8L_WBITS;
+    // The expression below needs a little-endian arch to work correctly.
+    // This gives a large speedup for decoding speed.
+    br->val_ |= (vp8l_val_t)*(const uint32_t*)(br->buf_ + br->pos_) <<
+                (VP8L_LBITS - VP8L_WBITS);
+    br->pos_ += VP8L_LOG8_WBITS;
+    return;
+  }
+#endif
+  ShiftBytes(br);       // Slow path.
+}
+
+uint32_t VP8LReadBits(VP8LBitReader* const br, int n_bits) {
+  assert(n_bits >= 0);
+  // Flag an error if end_of_stream or n_bits is more than allowed limit.
+  if (!br->eos_ && n_bits <= VP8L_MAX_NUM_BIT_READ) {
+    const uint32_t val =
+        (uint32_t)(br->val_ >> br->bit_pos_) & kBitMask[n_bits];
+    const int new_bits = br->bit_pos_ + n_bits;
+    br->bit_pos_ = new_bits;
+    ShiftBytes(br);
+    return val;
+  } else {
+    br->eos_ = 1;
+    return 0;
+  }
+}
+
+//------------------------------------------------------------------------------
diff --git a/Source/LibWebP/src/utils/utils.bit_writer.c b/Source/LibWebP/src/utils/utils.bit_writer.c
new file mode 100644
index 0000000..52df814
--- /dev/null
+++ b/Source/LibWebP/src/utils/utils.bit_writer.c
@@ -0,0 +1,308 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Bit writing and boolean coder
+//
+// Author: Skal (pascal.massimino at gmail.com)
+//         Vikas Arora (vikaas.arora at gmail.com)
+
+#include <assert.h>
+#include <string.h>   // for memcpy()
+#include <stdlib.h>
+
+#include "./bit_writer.h"
+#include "./endian_inl.h"
+#include "./utils.h"
+
+//------------------------------------------------------------------------------
+// VP8BitWriter
+
+static int BitWriterResize(VP8BitWriter* const bw, size_t extra_size) {
+  uint8_t* new_buf;
+  size_t new_size;
+  const uint64_t needed_size_64b = (uint64_t)bw->pos_ + extra_size;
+  const size_t needed_size = (size_t)needed_size_64b;
+  if (needed_size_64b != needed_size) {
+    bw->error_ = 1;
+    return 0;
+  }
+  if (needed_size <= bw->max_pos_) return 1;
+  // If the following line wraps over 32bit, the test just after will catch it.
+  new_size = 2 * bw->max_pos_;
+  if (new_size < needed_size) new_size = needed_size;
+  if (new_size < 1024) new_size = 1024;
+  new_buf = (uint8_t*)WebPSafeMalloc(1ULL, new_size);
+  if (new_buf == NULL) {
+    bw->error_ = 1;
+    return 0;
+  }
+  if (bw->pos_ > 0) {
+    assert(bw->buf_ != NULL);
+    memcpy(new_buf, bw->buf_, bw->pos_);
+  }
+  WebPSafeFree(bw->buf_);
+  bw->buf_ = new_buf;
+  bw->max_pos_ = new_size;
+  return 1;
+}
+
+static void Flush(VP8BitWriter* const bw) {
+  const int s = 8 + bw->nb_bits_;
+  const int32_t bits = bw->value_ >> s;
+  assert(bw->nb_bits_ >= 0);
+  bw->value_ -= bits << s;
+  bw->nb_bits_ -= 8;
+  if ((bits & 0xff) != 0xff) {
+    size_t pos = bw->pos_;
+    if (!BitWriterResize(bw, bw->run_ + 1)) {
+      return;
+    }
+    if (bits & 0x100) {  // overflow -> propagate carry over pending 0xff's
+      if (pos > 0) bw->buf_[pos - 1]++;
+    }
+    if (bw->run_ > 0) {
+      const int value = (bits & 0x100) ? 0x00 : 0xff;
+      for (; bw->run_ > 0; --bw->run_) bw->buf_[pos++] = value;
+    }
+    bw->buf_[pos++] = bits;
+    bw->pos_ = pos;
+  } else {
+    bw->run_++;   // delay writing of bytes 0xff, pending eventual carry.
+  }
+}
+
+//------------------------------------------------------------------------------
+// renormalization
+
+static const uint8_t kNorm[128] = {  // renorm_sizes[i] = 8 - log2(i)
+     7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+  0
+};
+
+// range = ((range + 1) << kVP8Log2Range[range]) - 1
+static const uint8_t kNewRange[128] = {
+  127, 127, 191, 127, 159, 191, 223, 127, 143, 159, 175, 191, 207, 223, 239,
+  127, 135, 143, 151, 159, 167, 175, 183, 191, 199, 207, 215, 223, 231, 239,
+  247, 127, 131, 135, 139, 143, 147, 151, 155, 159, 163, 167, 171, 175, 179,
+  183, 187, 191, 195, 199, 203, 207, 211, 215, 219, 223, 227, 231, 235, 239,
+  243, 247, 251, 127, 129, 131, 133, 135, 137, 139, 141, 143, 145, 147, 149,
+  151, 153, 155, 157, 159, 161, 163, 165, 167, 169, 171, 173, 175, 177, 179,
+  181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201, 203, 205, 207, 209,
+  211, 213, 215, 217, 219, 221, 223, 225, 227, 229, 231, 233, 235, 237, 239,
+  241, 243, 245, 247, 249, 251, 253, 127
+};
+
+int VP8PutBit(VP8BitWriter* const bw, int bit, int prob) {
+  const int split = (bw->range_ * prob) >> 8;
+  if (bit) {
+    bw->value_ += split + 1;
+    bw->range_ -= split + 1;
+  } else {
+    bw->range_ = split;
+  }
+  if (bw->range_ < 127) {   // emit 'shift' bits out and renormalize
+    const int shift = kNorm[bw->range_];
+    bw->range_ = kNewRange[bw->range_];
+    bw->value_ <<= shift;
+    bw->nb_bits_ += shift;
+    if (bw->nb_bits_ > 0) Flush(bw);
+  }
+  return bit;
+}
+
+int VP8PutBitUniform(VP8BitWriter* const bw, int bit) {
+  const int split = bw->range_ >> 1;
+  if (bit) {
+    bw->value_ += split + 1;
+    bw->range_ -= split + 1;
+  } else {
+    bw->range_ = split;
+  }
+  if (bw->range_ < 127) {
+    bw->range_ = kNewRange[bw->range_];
+    bw->value_ <<= 1;
+    bw->nb_bits_ += 1;
+    if (bw->nb_bits_ > 0) Flush(bw);
+  }
+  return bit;
+}
+
+void VP8PutBits(VP8BitWriter* const bw, uint32_t value, int nb_bits) {
+  uint32_t mask;
+  assert(nb_bits > 0 && nb_bits < 32);
+  for (mask = 1u << (nb_bits - 1); mask; mask >>= 1)
+    VP8PutBitUniform(bw, value & mask);
+}
+
+void VP8PutSignedBits(VP8BitWriter* const bw, int value, int nb_bits) {
+  if (!VP8PutBitUniform(bw, value != 0))
+    return;
+  if (value < 0) {
+    VP8PutBits(bw, ((-value) << 1) | 1, nb_bits + 1);
+  } else {
+    VP8PutBits(bw, value << 1, nb_bits + 1);
+  }
+}
+
+//------------------------------------------------------------------------------
+
+int VP8BitWriterInit(VP8BitWriter* const bw, size_t expected_size) {
+  bw->range_   = 255 - 1;
+  bw->value_   = 0;
+  bw->run_     = 0;
+  bw->nb_bits_ = -8;
+  bw->pos_     = 0;
+  bw->max_pos_ = 0;
+  bw->error_   = 0;
+  bw->buf_     = NULL;
+  return (expected_size > 0) ? BitWriterResize(bw, expected_size) : 1;
+}
+
+uint8_t* VP8BitWriterFinish(VP8BitWriter* const bw) {
+  VP8PutBits(bw, 0, 9 - bw->nb_bits_);
+  bw->nb_bits_ = 0;   // pad with zeroes
+  Flush(bw);
+  return bw->buf_;
+}
+
+int VP8BitWriterAppend(VP8BitWriter* const bw,
+                       const uint8_t* data, size_t size) {
+  assert(data != NULL);
+  if (bw->nb_bits_ != -8) return 0;   // Flush() must have been called
+  if (!BitWriterResize(bw, size)) return 0;
+  memcpy(bw->buf_ + bw->pos_, data, size);
+  bw->pos_ += size;
+  return 1;
+}
+
+void VP8BitWriterWipeOut(VP8BitWriter* const bw) {
+  if (bw != NULL) {
+    WebPSafeFree(bw->buf_);
+    memset(bw, 0, sizeof(*bw));
+  }
+}
+
+//------------------------------------------------------------------------------
+// VP8LBitWriter
+
+// This is the minimum amount of size the memory buffer is guaranteed to grow
+// when extra space is needed.
+#define MIN_EXTRA_SIZE  (32768ULL)
+
+#define VP8L_WRITER_BYTES ((int)sizeof(vp8l_wtype_t))
+#define VP8L_WRITER_BITS (VP8L_WRITER_BYTES * 8)
+#define VP8L_WRITER_MAX_BITS (8 * (int)sizeof(vp8l_atype_t))
+
+// Returns 1 on success.
+static int VP8LBitWriterResize(VP8LBitWriter* const bw, size_t extra_size) {
+  uint8_t* allocated_buf;
+  size_t allocated_size;
+  const size_t max_bytes = bw->end_ - bw->buf_;
+  const size_t current_size = bw->cur_ - bw->buf_;
+  const uint64_t size_required_64b = (uint64_t)current_size + extra_size;
+  const size_t size_required = (size_t)size_required_64b;
+  if (size_required != size_required_64b) {
+    bw->error_ = 1;
+    return 0;
+  }
+  if (max_bytes > 0 && size_required <= max_bytes) return 1;
+  allocated_size = (3 * max_bytes) >> 1;
+  if (allocated_size < size_required) allocated_size = size_required;
+  // make allocated size multiple of 1k
+  allocated_size = (((allocated_size >> 10) + 1) << 10);
+  allocated_buf = (uint8_t*)WebPSafeMalloc(1ULL, allocated_size);
+  if (allocated_buf == NULL) {
+    bw->error_ = 1;
+    return 0;
+  }
+  if (current_size > 0) {
+    memcpy(allocated_buf, bw->buf_, current_size);
+  }
+  WebPSafeFree(bw->buf_);
+  bw->buf_ = allocated_buf;
+  bw->cur_ = bw->buf_ + current_size;
+  bw->end_ = bw->buf_ + allocated_size;
+  return 1;
+}
+
+int VP8LBitWriterInit(VP8LBitWriter* const bw, size_t expected_size) {
+  memset(bw, 0, sizeof(*bw));
+  return VP8LBitWriterResize(bw, expected_size);
+}
+
+void VP8LBitWriterWipeOut(VP8LBitWriter* const bw) {
+  if (bw != NULL) {
+    WebPSafeFree(bw->buf_);
+    memset(bw, 0, sizeof(*bw));
+  }
+}
+
+void VP8LPutBits(VP8LBitWriter* const bw, uint32_t bits, int n_bits) {
+  assert(n_bits <= 32);
+  // That's the max we can handle:
+  assert(bw->used_ + n_bits <= 2 * VP8L_WRITER_MAX_BITS);
+  if (n_bits > 0) {
+    // Local field copy.
+    vp8l_atype_t lbits = bw->bits_;
+    int used = bw->used_;
+    // Special case of overflow handling for 32bit accumulator (2-steps flush).
+    if (VP8L_WRITER_BITS == 16) {
+      if (used + n_bits >= VP8L_WRITER_MAX_BITS) {
+        // Fill up all the VP8L_WRITER_MAX_BITS so it can be flushed out below.
+        const int shift = VP8L_WRITER_MAX_BITS - used;
+        lbits |= (vp8l_atype_t)bits << used;
+        used = VP8L_WRITER_MAX_BITS;
+        n_bits -= shift;
+        bits >>= shift;
+        assert(n_bits <= VP8L_WRITER_MAX_BITS);
+      }
+    }
+    // If needed, make some room by flushing some bits out.
+    while (used >= VP8L_WRITER_BITS) {
+      if (bw->cur_ + VP8L_WRITER_BYTES > bw->end_) {
+        const uint64_t extra_size = (bw->end_ - bw->buf_) + MIN_EXTRA_SIZE;
+        if (extra_size != (size_t)extra_size ||
+            !VP8LBitWriterResize(bw, (size_t)extra_size)) {
+          bw->cur_ = bw->buf_;
+          bw->error_ = 1;
+          return;
+        }
+      }
+      *(vp8l_wtype_t*)bw->cur_ = (vp8l_wtype_t)WSWAP((vp8l_wtype_t)lbits);
+      bw->cur_ += VP8L_WRITER_BYTES;
+      lbits >>= VP8L_WRITER_BITS;
+      used -= VP8L_WRITER_BITS;
+    }
+    // Eventually, insert new bits.
+    bw->bits_ = lbits | ((vp8l_atype_t)bits << used);
+    bw->used_ = used + n_bits;
+  }
+}
+
+uint8_t* VP8LBitWriterFinish(VP8LBitWriter* const bw) {
+  // flush leftover bits
+  if (VP8LBitWriterResize(bw, (bw->used_ + 7) >> 3)) {
+    while (bw->used_ > 0) {
+      *bw->cur_++ = (uint8_t)bw->bits_;
+      bw->bits_ >>= 8;
+      bw->used_ -= 8;
+    }
+    bw->used_ = 0;
+  }
+  return bw->buf_;
+}
+
+//------------------------------------------------------------------------------
diff --git a/Source/LibWebP/src/utils/utils.color_cache.c b/Source/LibWebP/src/utils/utils.color_cache.c
new file mode 100644
index 0000000..a6bb769
--- /dev/null
+++ b/Source/LibWebP/src/utils/utils.color_cache.c
@@ -0,0 +1,49 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Color Cache for WebP Lossless
+//
+// Author: Jyrki Alakuijala (jyrki at google.com)
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include "./color_cache.h"
+#include "../utils/utils.h"
+
+//------------------------------------------------------------------------------
+// VP8LColorCache.
+
+int VP8LColorCacheInit(VP8LColorCache* const cc, int hash_bits) {
+  const int hash_size = 1 << hash_bits;
+  assert(cc != NULL);
+  assert(hash_bits > 0);
+  cc->colors_ = (uint32_t*)WebPSafeCalloc((uint64_t)hash_size,
+                                          sizeof(*cc->colors_));
+  if (cc->colors_ == NULL) return 0;
+  cc->hash_shift_ = 32 - hash_bits;
+  cc->hash_bits_ = hash_bits;
+  return 1;
+}
+
+void VP8LColorCacheClear(VP8LColorCache* const cc) {
+  if (cc != NULL) {
+    WebPSafeFree(cc->colors_);
+    cc->colors_ = NULL;
+  }
+}
+
+void VP8LColorCacheCopy(const VP8LColorCache* const src,
+                        VP8LColorCache* const dst) {
+  assert(src != NULL);
+  assert(dst != NULL);
+  assert(src->hash_bits_ == dst->hash_bits_);
+  memcpy(dst->colors_, src->colors_,
+         ((size_t)1u << dst->hash_bits_) * sizeof(*dst->colors_));
+}
diff --git a/Source/LibWebP/src/utils/utils.filters.c b/Source/LibWebP/src/utils/utils.filters.c
new file mode 100644
index 0000000..95a80ee
--- /dev/null
+++ b/Source/LibWebP/src/utils/utils.filters.c
@@ -0,0 +1,76 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// filter estimation
+//
+// Author: Urvang (urvang at google.com)
+
+#include "./filters.h"
+#include <stdlib.h>
+#include <string.h>
+
+// -----------------------------------------------------------------------------
+// Quick estimate of a potentially interesting filter mode to try.
+
+#define SMAX 16
+#define SDIFF(a, b) (abs((a) - (b)) >> 4)   // Scoring diff, in [0..SMAX)
+
+static WEBP_INLINE int GradientPredictor(uint8_t a, uint8_t b, uint8_t c) {
+  const int g = a + b - c;
+  return ((g & ~0xff) == 0) ? g : (g < 0) ? 0 : 255;  // clip to 8bit
+}
+
+WEBP_FILTER_TYPE WebPEstimateBestFilter(const uint8_t* data,
+                                        int width, int height, int stride) {
+  int i, j;
+  int bins[WEBP_FILTER_LAST][SMAX];
+  memset(bins, 0, sizeof(bins));
+
+  // We only sample every other pixels. That's enough.
+  for (j = 2; j < height - 1; j += 2) {
+    const uint8_t* const p = data + j * stride;
+    int mean = p[0];
+    for (i = 2; i < width - 1; i += 2) {
+      const int diff0 = SDIFF(p[i], mean);
+      const int diff1 = SDIFF(p[i], p[i - 1]);
+      const int diff2 = SDIFF(p[i], p[i - width]);
+      const int grad_pred =
+          GradientPredictor(p[i - 1], p[i - width], p[i - width - 1]);
+      const int diff3 = SDIFF(p[i], grad_pred);
+      bins[WEBP_FILTER_NONE][diff0] = 1;
+      bins[WEBP_FILTER_HORIZONTAL][diff1] = 1;
+      bins[WEBP_FILTER_VERTICAL][diff2] = 1;
+      bins[WEBP_FILTER_GRADIENT][diff3] = 1;
+      mean = (3 * mean + p[i] + 2) >> 2;
+    }
+  }
+  {
+    int filter;
+    WEBP_FILTER_TYPE best_filter = WEBP_FILTER_NONE;
+    int best_score = 0x7fffffff;
+    for (filter = WEBP_FILTER_NONE; filter < WEBP_FILTER_LAST; ++filter) {
+      int score = 0;
+      for (i = 0; i < SMAX; ++i) {
+        if (bins[filter][i] > 0) {
+          score += i;
+        }
+      }
+      if (score < best_score) {
+        best_score = score;
+        best_filter = (WEBP_FILTER_TYPE)filter;
+      }
+    }
+    return best_filter;
+  }
+}
+
+#undef SMAX
+#undef SDIFF
+
+//------------------------------------------------------------------------------
diff --git a/Source/LibWebP/src/utils/utils.h b/Source/LibWebP/src/utils/utils.h
new file mode 100644
index 0000000..7e41933
--- /dev/null
+++ b/Source/LibWebP/src/utils/utils.h
@@ -0,0 +1,121 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Misc. common utility functions
+//
+// Authors: Skal (pascal.massimino at gmail.com)
+//          Urvang (urvang at google.com)
+
+#ifndef WEBP_UTILS_UTILS_H_
+#define WEBP_UTILS_UTILS_H_
+
+#include <assert.h>
+
+#include "../webp/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//------------------------------------------------------------------------------
+// Memory allocation
+
+// This is the maximum memory amount that libwebp will ever try to allocate.
+#define WEBP_MAX_ALLOCABLE_MEMORY (1ULL << 40)
+
+// size-checking safe malloc/calloc: verify that the requested size is not too
+// large, or return NULL. You don't need to call these for constructs like
+// malloc(sizeof(foo)), but only if there's picture-dependent size involved
+// somewhere (like: malloc(num_pixels * sizeof(*something))). That's why this
+// safe malloc() borrows the signature from calloc(), pointing at the dangerous
+// underlying multiply involved.
+WEBP_EXTERN(void*) WebPSafeMalloc(uint64_t nmemb, size_t size);
+// Note that WebPSafeCalloc() expects the second argument type to be 'size_t'
+// in order to favor the "calloc(num_foo, sizeof(foo))" pattern.
+WEBP_EXTERN(void*) WebPSafeCalloc(uint64_t nmemb, size_t size);
+
+// Companion deallocation function to the above allocations.
+WEBP_EXTERN(void) WebPSafeFree(void* const ptr);
+
+//------------------------------------------------------------------------------
+// Reading/writing data.
+
+// Read 16, 24 or 32 bits stored in little-endian order.
+static WEBP_INLINE int GetLE16(const uint8_t* const data) {
+  return (int)(data[0] << 0) | (data[1] << 8);
+}
+
+static WEBP_INLINE int GetLE24(const uint8_t* const data) {
+  return GetLE16(data) | (data[2] << 16);
+}
+
+static WEBP_INLINE uint32_t GetLE32(const uint8_t* const data) {
+  return (uint32_t)GetLE16(data) | (GetLE16(data + 2) << 16);
+}
+
+// Store 16, 24 or 32 bits in little-endian order.
+static WEBP_INLINE void PutLE16(uint8_t* const data, int val) {
+  assert(val < (1 << 16));
+  data[0] = (val >> 0);
+  data[1] = (val >> 8);
+}
+
+static WEBP_INLINE void PutLE24(uint8_t* const data, int val) {
+  assert(val < (1 << 24));
+  PutLE16(data, val & 0xffff);
+  data[2] = (val >> 16);
+}
+
+static WEBP_INLINE void PutLE32(uint8_t* const data, uint32_t val) {
+  PutLE16(data, (int)(val & 0xffff));
+  PutLE16(data + 2, (int)(val >> 16));
+}
+
+// Returns (int)floor(log2(n)). n must be > 0.
+// use GNU builtins where available.
+#if defined(__GNUC__) && \
+    ((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4)
+static WEBP_INLINE int BitsLog2Floor(uint32_t n) {
+  return 31 ^ __builtin_clz(n);
+}
+#elif defined(_MSC_VER) && _MSC_VER > 1310 && \
+      (defined(_M_X64) || defined(_M_IX86))
+#include <intrin.h>
+#pragma intrinsic(_BitScanReverse)
+
+static WEBP_INLINE int BitsLog2Floor(uint32_t n) {
+  uint32_t first_set_bit;
+  _BitScanReverse(&first_set_bit, n);
+  return first_set_bit;
+}
+#else
+static WEBP_INLINE int BitsLog2Floor(uint32_t n) {
+  int log = 0;
+  uint32_t value = n;
+  int i;
+
+  for (i = 4; i >= 0; --i) {
+    const int shift = (1 << i);
+    const uint32_t x = value >> shift;
+    if (x != 0) {
+      value = x;
+      log += shift;
+    }
+  }
+  return log;
+}
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifdef __cplusplus
+}    // extern "C"
+#endif
+
+#endif  /* WEBP_UTILS_UTILS_H_ */
diff --git a/Source/LibWebP/src/utils/utils.huffman.c b/Source/LibWebP/src/utils/utils.huffman.c
new file mode 100644
index 0000000..6992260
--- /dev/null
+++ b/Source/LibWebP/src/utils/utils.huffman.c
@@ -0,0 +1,205 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Utilities for building and looking up Huffman trees.
+//
+// Author: Urvang Joshi (urvang at google.com)
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include "./huffman.h"
+#include "../utils/utils.h"
+#include "../webp/format_constants.h"
+
+// Huffman data read via DecodeImageStream is represented in two (red and green)
+// bytes.
+#define MAX_HTREE_GROUPS    0x10000
+
+HTreeGroup* VP8LHtreeGroupsNew(int num_htree_groups) {
+  HTreeGroup* const htree_groups =
+      (HTreeGroup*)WebPSafeMalloc(num_htree_groups, sizeof(*htree_groups));
+  if (htree_groups == NULL) {
+    return NULL;
+  }
+  assert(num_htree_groups <= MAX_HTREE_GROUPS);
+  return htree_groups;
+}
+
+void VP8LHtreeGroupsFree(HTreeGroup* const htree_groups) {
+  if (htree_groups != NULL) {
+    WebPSafeFree(htree_groups);
+  }
+}
+
+// Returns reverse(reverse(key, len) + 1, len), where reverse(key, len) is the
+// bit-wise reversal of the len least significant bits of key.
+static WEBP_INLINE uint32_t GetNextKey(uint32_t key, int len) {
+  uint32_t step = 1 << (len - 1);
+  while (key & step) {
+    step >>= 1;
+  }
+  return (key & (step - 1)) + step;
+}
+
+// Stores code in table[0], table[step], table[2*step], ..., table[end].
+// Assumes that end is an integer multiple of step.
+static WEBP_INLINE void ReplicateValue(HuffmanCode* table,
+                                       int step, int end,
+                                       HuffmanCode code) {
+  assert(end % step == 0);
+  do {
+    end -= step;
+    table[end] = code;
+  } while (end > 0);
+}
+
+// Returns the table width of the next 2nd level table. count is the histogram
+// of bit lengths for the remaining symbols, len is the code length of the next
+// processed symbol
+static WEBP_INLINE int NextTableBitSize(const int* const count,
+                                        int len, int root_bits) {
+  int left = 1 << (len - root_bits);
+  while (len < MAX_ALLOWED_CODE_LENGTH) {
+    left -= count[len];
+    if (left <= 0) break;
+    ++len;
+    left <<= 1;
+  }
+  return len - root_bits;
+}
+
+int VP8LBuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
+                          const int code_lengths[], int code_lengths_size) {
+  HuffmanCode* table = root_table;  // next available space in table
+  int total_size = 1 << root_bits;  // total size root table + 2nd level table
+  int* sorted = NULL;               // symbols sorted by code length
+  int len;                          // current code length
+  int symbol;                       // symbol index in original or sorted table
+  // number of codes of each length:
+  int count[MAX_ALLOWED_CODE_LENGTH + 1] = { 0 };
+  // offsets in sorted table for each length:
+  int offset[MAX_ALLOWED_CODE_LENGTH + 1];
+
+  assert(code_lengths_size != 0);
+  assert(code_lengths != NULL);
+  assert(root_table != NULL);
+  assert(root_bits > 0);
+
+  // Build histogram of code lengths.
+  for (symbol = 0; symbol < code_lengths_size; ++symbol) {
+    if (code_lengths[symbol] > MAX_ALLOWED_CODE_LENGTH) {
+      return 0;
+    }
+    ++count[code_lengths[symbol]];
+  }
+
+  // Error, all code lengths are zeros.
+  if (count[0] == code_lengths_size) {
+    return 0;
+  }
+
+  // Generate offsets into sorted symbol table by code length.
+  offset[1] = 0;
+  for (len = 1; len < MAX_ALLOWED_CODE_LENGTH; ++len) {
+    if (count[len] > (1 << len)) {
+      return 0;
+    }
+    offset[len + 1] = offset[len] + count[len];
+  }
+
+  sorted = (int*)WebPSafeMalloc(code_lengths_size, sizeof(*sorted));
+  if (sorted == NULL) {
+    return 0;
+  }
+
+  // Sort symbols by length, by symbol order within each length.
+  for (symbol = 0; symbol < code_lengths_size; ++symbol) {
+    const int symbol_code_length = code_lengths[symbol];
+    if (code_lengths[symbol] > 0) {
+      sorted[offset[symbol_code_length]++] = symbol;
+    }
+  }
+
+  // Special case code with only one value.
+  if (offset[MAX_ALLOWED_CODE_LENGTH] == 1) {
+    HuffmanCode code;
+    code.bits = 0;
+    code.value = (uint16_t)sorted[0];
+    ReplicateValue(table, 1, total_size, code);
+    WebPSafeFree(sorted);
+    return total_size;
+  }
+
+  {
+    int step;              // step size to replicate values in current table
+    uint32_t low = -1;     // low bits for current root entry
+    uint32_t mask = total_size - 1;    // mask for low bits
+    uint32_t key = 0;      // reversed prefix code
+    int num_nodes = 1;     // number of Huffman tree nodes
+    int num_open = 1;      // number of open branches in current tree level
+    int table_bits = root_bits;        // key length of current table
+    int table_size = 1 << table_bits;  // size of current table
+    symbol = 0;
+    // Fill in root table.
+    for (len = 1, step = 2; len <= root_bits; ++len, step <<= 1) {
+      num_open <<= 1;
+      num_nodes += num_open;
+      num_open -= count[len];
+      if (num_open < 0) {
+        WebPSafeFree(sorted);
+        return 0;
+      }
+      for (; count[len] > 0; --count[len]) {
+        HuffmanCode code;
+        code.bits = (uint8_t)len;
+        code.value = (uint16_t)sorted[symbol++];
+        ReplicateValue(&table[key], step, table_size, code);
+        key = GetNextKey(key, len);
+      }
+    }
+
+    // Fill in 2nd level tables and add pointers to root table.
+    for (len = root_bits + 1, step = 2; len <= MAX_ALLOWED_CODE_LENGTH;
+         ++len, step <<= 1) {
+      num_open <<= 1;
+      num_nodes += num_open;
+      num_open -= count[len];
+      if (num_open < 0) {
+        WebPSafeFree(sorted);
+        return 0;
+      }
+      for (; count[len] > 0; --count[len]) {
+        HuffmanCode code;
+        if ((key & mask) != low) {
+          table += table_size;
+          table_bits = NextTableBitSize(count, len, root_bits);
+          table_size = 1 << table_bits;
+          total_size += table_size;
+          low = key & mask;
+          root_table[low].bits = (uint8_t)(table_bits + root_bits);
+          root_table[low].value = (uint16_t)((table - root_table) - low);
+        }
+        code.bits = (uint8_t)(len - root_bits);
+        code.value = (uint16_t)sorted[symbol++];
+        ReplicateValue(&table[key >> root_bits], step, table_size, code);
+        key = GetNextKey(key, len);
+      }
+    }
+
+    // Check if tree is full.
+    if (num_nodes != 2 * offset[MAX_ALLOWED_CODE_LENGTH] - 1) {
+      WebPSafeFree(sorted);
+      return 0;
+    }
+  }
+
+  WebPSafeFree(sorted);
+  return total_size;
+}
diff --git a/Source/LibWebP/src/utils/utils.huffman_encode.c b/Source/LibWebP/src/utils/utils.huffman_encode.c
new file mode 100644
index 0000000..76bac74
--- /dev/null
+++ b/Source/LibWebP/src/utils/utils.huffman_encode.c
@@ -0,0 +1,417 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Author: Jyrki Alakuijala (jyrki at google.com)
+//
+// Entropy encoding (Huffman) for webp lossless.
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include "./huffman_encode.h"
+#include "../utils/utils.h"
+#include "../webp/format_constants.h"
+
+// -----------------------------------------------------------------------------
+// Util function to optimize the symbol map for RLE coding
+
+// Heuristics for selecting the stride ranges to collapse.
+static int ValuesShouldBeCollapsedToStrideAverage(int a, int b) {
+  return abs(a - b) < 4;
+}
+
+// Change the population counts in a way that the consequent
+// Huffman tree compression, especially its RLE-part, give smaller output.
+static void OptimizeHuffmanForRle(int length, uint8_t* const good_for_rle,
+                                  uint32_t* const counts) {
+  // 1) Let's make the Huffman code more compatible with rle encoding.
+  int i;
+  for (; length >= 0; --length) {
+    if (length == 0) {
+      return;  // All zeros.
+    }
+    if (counts[length - 1] != 0) {
+      // Now counts[0..length - 1] does not have trailing zeros.
+      break;
+    }
+  }
+  // 2) Let's mark all population counts that already can be encoded
+  // with an rle code.
+  {
+    // Let's not spoil any of the existing good rle codes.
+    // Mark any seq of 0's that is longer as 5 as a good_for_rle.
+    // Mark any seq of non-0's that is longer as 7 as a good_for_rle.
+    uint32_t symbol = counts[0];
+    int stride = 0;
+    for (i = 0; i < length + 1; ++i) {
+      if (i == length || counts[i] != symbol) {
+        if ((symbol == 0 && stride >= 5) ||
+            (symbol != 0 && stride >= 7)) {
+          int k;
+          for (k = 0; k < stride; ++k) {
+            good_for_rle[i - k - 1] = 1;
+          }
+        }
+        stride = 1;
+        if (i != length) {
+          symbol = counts[i];
+        }
+      } else {
+        ++stride;
+      }
+    }
+  }
+  // 3) Let's replace those population counts that lead to more rle codes.
+  {
+    uint32_t stride = 0;
+    uint32_t limit = counts[0];
+    uint32_t sum = 0;
+    for (i = 0; i < length + 1; ++i) {
+      if (i == length || good_for_rle[i] ||
+          (i != 0 && good_for_rle[i - 1]) ||
+          !ValuesShouldBeCollapsedToStrideAverage(counts[i], limit)) {
+        if (stride >= 4 || (stride >= 3 && sum == 0)) {
+          uint32_t k;
+          // The stride must end, collapse what we have, if we have enough (4).
+          uint32_t count = (sum + stride / 2) / stride;
+          if (count < 1) {
+            count = 1;
+          }
+          if (sum == 0) {
+            // Don't make an all zeros stride to be upgraded to ones.
+            count = 0;
+          }
+          for (k = 0; k < stride; ++k) {
+            // We don't want to change value at counts[i],
+            // that is already belonging to the next stride. Thus - 1.
+            counts[i - k - 1] = count;
+          }
+        }
+        stride = 0;
+        sum = 0;
+        if (i < length - 3) {
+          // All interesting strides have a count of at least 4,
+          // at least when non-zeros.
+          limit = (counts[i] + counts[i + 1] +
+                   counts[i + 2] + counts[i + 3] + 2) / 4;
+        } else if (i < length) {
+          limit = counts[i];
+        } else {
+          limit = 0;
+        }
+      }
+      ++stride;
+      if (i != length) {
+        sum += counts[i];
+        if (stride >= 4) {
+          limit = (sum + stride / 2) / stride;
+        }
+      }
+    }
+  }
+}
+
+// A comparer function for two Huffman trees: sorts first by 'total count'
+// (more comes first), and then by 'value' (more comes first).
+static int CompareHuffmanTrees(const void* ptr1, const void* ptr2) {
+  const HuffmanTree* const t1 = (const HuffmanTree*)ptr1;
+  const HuffmanTree* const t2 = (const HuffmanTree*)ptr2;
+  if (t1->total_count_ > t2->total_count_) {
+    return -1;
+  } else if (t1->total_count_ < t2->total_count_) {
+    return 1;
+  } else {
+    assert(t1->value_ != t2->value_);
+    return (t1->value_ < t2->value_) ? -1 : 1;
+  }
+}
+
+static void SetBitDepths(const HuffmanTree* const tree,
+                         const HuffmanTree* const pool,
+                         uint8_t* const bit_depths, int level) {
+  if (tree->pool_index_left_ >= 0) {
+    SetBitDepths(&pool[tree->pool_index_left_], pool, bit_depths, level + 1);
+    SetBitDepths(&pool[tree->pool_index_right_], pool, bit_depths, level + 1);
+  } else {
+    bit_depths[tree->value_] = level;
+  }
+}
+
+// Create an optimal Huffman tree.
+//
+// (data,length): population counts.
+// tree_limit: maximum bit depth (inclusive) of the codes.
+// bit_depths[]: how many bits are used for the symbol.
+//
+// Returns 0 when an error has occurred.
+//
+// The catch here is that the tree cannot be arbitrarily deep
+//
+// count_limit is the value that is to be faked as the minimum value
+// and this minimum value is raised until the tree matches the
+// maximum length requirement.
+//
+// This algorithm is not of excellent performance for very long data blocks,
+// especially when population counts are longer than 2**tree_limit, but
+// we are not planning to use this with extremely long blocks.
+//
+// See http://en.wikipedia.org/wiki/Huffman_coding
+static void GenerateOptimalTree(const uint32_t* const histogram,
+                                int histogram_size,
+                                HuffmanTree* tree, int tree_depth_limit,
+                                uint8_t* const bit_depths) {
+  uint32_t count_min;
+  HuffmanTree* tree_pool;
+  int tree_size_orig = 0;
+  int i;
+
+  for (i = 0; i < histogram_size; ++i) {
+    if (histogram[i] != 0) {
+      ++tree_size_orig;
+    }
+  }
+
+  if (tree_size_orig == 0) {   // pretty optimal already!
+    return;
+  }
+
+  tree_pool = tree + tree_size_orig;
+
+  // For block sizes with less than 64k symbols we never need to do a
+  // second iteration of this loop.
+  // If we actually start running inside this loop a lot, we would perhaps
+  // be better off with the Katajainen algorithm.
+  assert(tree_size_orig <= (1 << (tree_depth_limit - 1)));
+  for (count_min = 1; ; count_min *= 2) {
+    int tree_size = tree_size_orig;
+    // We need to pack the Huffman tree in tree_depth_limit bits.
+    // So, we try by faking histogram entries to be at least 'count_min'.
+    int idx = 0;
+    int j;
+    for (j = 0; j < histogram_size; ++j) {
+      if (histogram[j] != 0) {
+        const uint32_t count =
+            (histogram[j] < count_min) ? count_min : histogram[j];
+        tree[idx].total_count_ = count;
+        tree[idx].value_ = j;
+        tree[idx].pool_index_left_ = -1;
+        tree[idx].pool_index_right_ = -1;
+        ++idx;
+      }
+    }
+
+    // Build the Huffman tree.
+    qsort(tree, tree_size, sizeof(*tree), CompareHuffmanTrees);
+
+    if (tree_size > 1) {  // Normal case.
+      int tree_pool_size = 0;
+      while (tree_size > 1) {  // Finish when we have only one root.
+        uint32_t count;
+        tree_pool[tree_pool_size++] = tree[tree_size - 1];
+        tree_pool[tree_pool_size++] = tree[tree_size - 2];
+        count = tree_pool[tree_pool_size - 1].total_count_ +
+                tree_pool[tree_pool_size - 2].total_count_;
+        tree_size -= 2;
+        {
+          // Search for the insertion point.
+          int k;
+          for (k = 0; k < tree_size; ++k) {
+            if (tree[k].total_count_ <= count) {
+              break;
+            }
+          }
+          memmove(tree + (k + 1), tree + k, (tree_size - k) * sizeof(*tree));
+          tree[k].total_count_ = count;
+          tree[k].value_ = -1;
+
+          tree[k].pool_index_left_ = tree_pool_size - 1;
+          tree[k].pool_index_right_ = tree_pool_size - 2;
+          tree_size = tree_size + 1;
+        }
+      }
+      SetBitDepths(&tree[0], tree_pool, bit_depths, 0);
+    } else if (tree_size == 1) {  // Trivial case: only one element.
+      bit_depths[tree[0].value_] = 1;
+    }
+
+    {
+      // Test if this Huffman tree satisfies our 'tree_depth_limit' criteria.
+      int max_depth = bit_depths[0];
+      for (j = 1; j < histogram_size; ++j) {
+        if (max_depth < bit_depths[j]) {
+          max_depth = bit_depths[j];
+        }
+      }
+      if (max_depth <= tree_depth_limit) {
+        break;
+      }
+    }
+  }
+}
+
+// -----------------------------------------------------------------------------
+// Coding of the Huffman tree values
+
+static HuffmanTreeToken* CodeRepeatedValues(int repetitions,
+                                            HuffmanTreeToken* tokens,
+                                            int value, int prev_value) {
+  assert(value <= MAX_ALLOWED_CODE_LENGTH);
+  if (value != prev_value) {
+    tokens->code = value;
+    tokens->extra_bits = 0;
+    ++tokens;
+    --repetitions;
+  }
+  while (repetitions >= 1) {
+    if (repetitions < 3) {
+      int i;
+      for (i = 0; i < repetitions; ++i) {
+        tokens->code = value;
+        tokens->extra_bits = 0;
+        ++tokens;
+      }
+      break;
+    } else if (repetitions < 7) {
+      tokens->code = 16;
+      tokens->extra_bits = repetitions - 3;
+      ++tokens;
+      break;
+    } else {
+      tokens->code = 16;
+      tokens->extra_bits = 3;
+      ++tokens;
+      repetitions -= 6;
+    }
+  }
+  return tokens;
+}
+
+static HuffmanTreeToken* CodeRepeatedZeros(int repetitions,
+                                           HuffmanTreeToken* tokens) {
+  while (repetitions >= 1) {
+    if (repetitions < 3) {
+      int i;
+      for (i = 0; i < repetitions; ++i) {
+        tokens->code = 0;   // 0-value
+        tokens->extra_bits = 0;
+        ++tokens;
+      }
+      break;
+    } else if (repetitions < 11) {
+      tokens->code = 17;
+      tokens->extra_bits = repetitions - 3;
+      ++tokens;
+      break;
+    } else if (repetitions < 139) {
+      tokens->code = 18;
+      tokens->extra_bits = repetitions - 11;
+      ++tokens;
+      break;
+    } else {
+      tokens->code = 18;
+      tokens->extra_bits = 0x7f;  // 138 repeated 0s
+      ++tokens;
+      repetitions -= 138;
+    }
+  }
+  return tokens;
+}
+
+int VP8LCreateCompressedHuffmanTree(const HuffmanTreeCode* const tree,
+                                    HuffmanTreeToken* tokens, int max_tokens) {
+  HuffmanTreeToken* const starting_token = tokens;
+  HuffmanTreeToken* const ending_token = tokens + max_tokens;
+  const int depth_size = tree->num_symbols;
+  int prev_value = 8;  // 8 is the initial value for rle.
+  int i = 0;
+  assert(tokens != NULL);
+  while (i < depth_size) {
+    const int value = tree->code_lengths[i];
+    int k = i + 1;
+    int runs;
+    while (k < depth_size && tree->code_lengths[k] == value) ++k;
+    runs = k - i;
+    if (value == 0) {
+      tokens = CodeRepeatedZeros(runs, tokens);
+    } else {
+      tokens = CodeRepeatedValues(runs, tokens, value, prev_value);
+      prev_value = value;
+    }
+    i += runs;
+    assert(tokens <= ending_token);
+  }
+  (void)ending_token;    // suppress 'unused variable' warning
+  return (int)(tokens - starting_token);
+}
+
+// -----------------------------------------------------------------------------
+
+// Pre-reversed 4-bit values.
+static const uint8_t kReversedBits[16] = {
+  0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe,
+  0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf
+};
+
+static uint32_t ReverseBits(int num_bits, uint32_t bits) {
+  uint32_t retval = 0;
+  int i = 0;
+  while (i < num_bits) {
+    i += 4;
+    retval |= kReversedBits[bits & 0xf] << (MAX_ALLOWED_CODE_LENGTH + 1 - i);
+    bits >>= 4;
+  }
+  retval >>= (MAX_ALLOWED_CODE_LENGTH + 1 - num_bits);
+  return retval;
+}
+
+// Get the actual bit values for a tree of bit depths.
+static void ConvertBitDepthsToSymbols(HuffmanTreeCode* const tree) {
+  // 0 bit-depth means that the symbol does not exist.
+  int i;
+  int len;
+  uint32_t next_code[MAX_ALLOWED_CODE_LENGTH + 1];
+  int depth_count[MAX_ALLOWED_CODE_LENGTH + 1] = { 0 };
+
+  assert(tree != NULL);
+  len = tree->num_symbols;
+  for (i = 0; i < len; ++i) {
+    const int code_length = tree->code_lengths[i];
+    assert(code_length <= MAX_ALLOWED_CODE_LENGTH);
+    ++depth_count[code_length];
+  }
+  depth_count[0] = 0;  // ignore unused symbol
+  next_code[0] = 0;
+  {
+    uint32_t code = 0;
+    for (i = 1; i <= MAX_ALLOWED_CODE_LENGTH; ++i) {
+      code = (code + depth_count[i - 1]) << 1;
+      next_code[i] = code;
+    }
+  }
+  for (i = 0; i < len; ++i) {
+    const int code_length = tree->code_lengths[i];
+    tree->codes[i] = ReverseBits(code_length, next_code[code_length]++);
+  }
+}
+
+// -----------------------------------------------------------------------------
+// Main entry point
+
+void VP8LCreateHuffmanTree(uint32_t* const histogram, int tree_depth_limit,
+                           uint8_t* const buf_rle,
+                           HuffmanTree* const huff_tree,
+                           HuffmanTreeCode* const huff_code) {
+  const int num_symbols = huff_code->num_symbols;
+  memset(buf_rle, 0, num_symbols * sizeof(*buf_rle));
+  OptimizeHuffmanForRle(num_symbols, buf_rle, histogram);
+  GenerateOptimalTree(histogram, num_symbols, huff_tree, tree_depth_limit,
+                      huff_code->code_lengths);
+  // Create the actual bit codes for the bit lengths.
+  ConvertBitDepthsToSymbols(huff_code);
+}
diff --git a/Source/LibWebP/src/utils/utils.quant_levels.c b/Source/LibWebP/src/utils/utils.quant_levels.c
new file mode 100644
index 0000000..a6a8af3
--- /dev/null
+++ b/Source/LibWebP/src/utils/utils.quant_levels.c
@@ -0,0 +1,140 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Quantize levels for specified number of quantization-levels ([2, 256]).
+// Min and max values are preserved (usual 0 and 255 for alpha plane).
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include <assert.h>
+
+#include "./quant_levels.h"
+
+#define NUM_SYMBOLS     256
+
+#define MAX_ITER  6             // Maximum number of convergence steps.
+#define ERROR_THRESHOLD 1e-4    // MSE stopping criterion.
+
+// -----------------------------------------------------------------------------
+// Quantize levels.
+
+int QuantizeLevels(uint8_t* const data, int width, int height,
+                   int num_levels, uint64_t* const sse) {
+  int freq[NUM_SYMBOLS] = { 0 };
+  int q_level[NUM_SYMBOLS] = { 0 };
+  double inv_q_level[NUM_SYMBOLS] = { 0 };
+  int min_s = 255, max_s = 0;
+  const size_t data_size = height * width;
+  int i, num_levels_in, iter;
+  double last_err = 1.e38, err = 0.;
+  const double err_threshold = ERROR_THRESHOLD * data_size;
+
+  if (data == NULL) {
+    return 0;
+  }
+
+  if (width <= 0 || height <= 0) {
+    return 0;
+  }
+
+  if (num_levels < 2 || num_levels > 256) {
+    return 0;
+  }
+
+  {
+    size_t n;
+    num_levels_in = 0;
+    for (n = 0; n < data_size; ++n) {
+      num_levels_in += (freq[data[n]] == 0);
+      if (min_s > data[n]) min_s = data[n];
+      if (max_s < data[n]) max_s = data[n];
+      ++freq[data[n]];
+    }
+  }
+
+  if (num_levels_in <= num_levels) goto End;  // nothing to do!
+
+  // Start with uniformly spread centroids.
+  for (i = 0; i < num_levels; ++i) {
+    inv_q_level[i] = min_s + (double)(max_s - min_s) * i / (num_levels - 1);
+  }
+
+  // Fixed values. Won't be changed.
+  q_level[min_s] = 0;
+  q_level[max_s] = num_levels - 1;
+  assert(inv_q_level[0] == min_s);
+  assert(inv_q_level[num_levels - 1] == max_s);
+
+  // k-Means iterations.
+  for (iter = 0; iter < MAX_ITER; ++iter) {
+    double q_sum[NUM_SYMBOLS] = { 0 };
+    double q_count[NUM_SYMBOLS] = { 0 };
+    int s, slot = 0;
+
+    // Assign classes to representatives.
+    for (s = min_s; s <= max_s; ++s) {
+      // Keep track of the nearest neighbour 'slot'
+      while (slot < num_levels - 1 &&
+             2 * s > inv_q_level[slot] + inv_q_level[slot + 1]) {
+        ++slot;
+      }
+      if (freq[s] > 0) {
+        q_sum[slot] += s * freq[s];
+        q_count[slot] += freq[s];
+      }
+      q_level[s] = slot;
+    }
+
+    // Assign new representatives to classes.
+    if (num_levels > 2) {
+      for (slot = 1; slot < num_levels - 1; ++slot) {
+        const double count = q_count[slot];
+        if (count > 0.) {
+          inv_q_level[slot] = q_sum[slot] / count;
+        }
+      }
+    }
+
+    // Compute convergence error.
+    err = 0.;
+    for (s = min_s; s <= max_s; ++s) {
+      const double error = s - inv_q_level[q_level[s]];
+      err += freq[s] * error * error;
+    }
+
+    // Check for convergence: we stop as soon as the error is no
+    // longer improving.
+    if (last_err - err < err_threshold) break;
+    last_err = err;
+  }
+
+  // Remap the alpha plane to quantized values.
+  {
+    // double->int rounding operation can be costly, so we do it
+    // once for all before remapping. We also perform the data[] -> slot
+    // mapping, while at it (avoid one indirection in the final loop).
+    uint8_t map[NUM_SYMBOLS];
+    int s;
+    size_t n;
+    for (s = min_s; s <= max_s; ++s) {
+      const int slot = q_level[s];
+      map[s] = (uint8_t)(inv_q_level[slot] + .5);
+    }
+    // Final pass.
+    for (n = 0; n < data_size; ++n) {
+      data[n] = map[data[n]];
+    }
+  }
+ End:
+  // Store sum of squared error if needed.
+  if (sse != NULL) *sse = (uint64_t)err;
+
+  return 1;
+}
+
diff --git a/Source/LibWebP/src/utils/utils.quant_levels_dec.c b/Source/LibWebP/src/utils/utils.quant_levels_dec.c
new file mode 100644
index 0000000..a5e544e
--- /dev/null
+++ b/Source/LibWebP/src/utils/utils.quant_levels_dec.c
@@ -0,0 +1,279 @@
+// Copyright 2013 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Implement gradient smoothing: we replace a current alpha value by its
+// surrounding average if it's close enough (that is: the change will be less
+// than the minimum distance between two quantized level).
+// We use sliding window for computing the 2d moving average.
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include "./quant_levels_dec.h"
+
+#include <string.h>   // for memset
+
+#include "./utils.h"
+
+// #define USE_DITHERING   // uncomment to enable ordered dithering (not vital)
+
+#define FIX 16     // fix-point precision for averaging
+#define LFIX 2     // extra precision for look-up table
+#define LUT_SIZE ((1 << (8 + LFIX)) - 1)  // look-up table size
+
+#if defined(USE_DITHERING)
+
+#define DFIX 4           // extra precision for ordered dithering
+#define DSIZE 4          // dithering size (must be a power of two)
+// cf. http://en.wikipedia.org/wiki/Ordered_dithering
+static const uint8_t kOrderedDither[DSIZE][DSIZE] = {
+  {  0,  8,  2, 10 },     // coefficients are in DFIX fixed-point precision
+  { 12,  4, 14,  6 },
+  {  3, 11,  1,  9 },
+  { 15,  7, 13,  5 }
+};
+
+#else
+#define DFIX 0
+#endif
+
+typedef struct {
+  int width_, height_;  // dimension
+  int row_;             // current input row being processed
+  uint8_t* src_;        // input pointer
+  uint8_t* dst_;        // output pointer
+
+  int radius_;          // filter radius (=delay)
+  int scale_;           // normalization factor, in FIX bits precision
+
+  void* mem_;           // all memory
+
+  // various scratch buffers
+  uint16_t* start_;
+  uint16_t* cur_;
+  uint16_t* end_;
+  uint16_t* top_;
+  uint16_t* average_;
+
+  // input levels distribution
+  int num_levels_;       // number of quantized levels
+  int min_, max_;        // min and max level values
+  int min_level_dist_;   // smallest distance between two consecutive levels
+
+  int16_t* correction_;  // size = 1 + 2*LUT_SIZE  -> ~4k memory
+} SmoothParams;
+
+//------------------------------------------------------------------------------
+
+#define CLIP_MASK (int)(~0U << (8 + DFIX))
+static WEBP_INLINE uint8_t clip_8b(int v) {
+  return (!(v & CLIP_MASK)) ? (uint8_t)(v >> DFIX) : (v < 0) ? 0u : 255u;
+}
+
+// vertical accumulation
+static void VFilter(SmoothParams* const p) {
+  const uint8_t* src = p->src_;
+  const int w = p->width_;
+  uint16_t* const cur = p->cur_;
+  const uint16_t* const top = p->top_;
+  uint16_t* const out = p->end_;
+  uint16_t sum = 0;               // all arithmetic is modulo 16bit
+  int x;
+
+  for (x = 0; x < w; ++x) {
+    uint16_t new_value;
+    sum += src[x];
+    new_value = top[x] + sum;
+    out[x] = new_value - cur[x];  // vertical sum of 'r' pixels.
+    cur[x] = new_value;
+  }
+  // move input pointers one row down
+  p->top_ = p->cur_;
+  p->cur_ += w;
+  if (p->cur_ == p->end_) p->cur_ = p->start_;  // roll-over
+  // We replicate edges, as it's somewhat easier as a boundary condition.
+  // That's why we don't update the 'src' pointer on top/bottom area:
+  if (p->row_ >= 0 && p->row_ < p->height_ - 1) {
+    p->src_ += p->width_;
+  }
+}
+
+// horizontal accumulation. We use mirror replication of missing pixels, as it's
+// a little easier to implement (surprisingly).
+static void HFilter(SmoothParams* const p) {
+  const uint16_t* const in = p->end_;
+  uint16_t* const out = p->average_;
+  const uint32_t scale = p->scale_;
+  const int w = p->width_;
+  const int r = p->radius_;
+
+  int x;
+  for (x = 0; x <= r; ++x) {   // left mirroring
+    const uint16_t delta = in[x + r - 1] + in[r - x];
+    out[x] = (delta * scale) >> FIX;
+  }
+  for (; x < w - r; ++x) {     // bulk middle run
+    const uint16_t delta = in[x + r] - in[x - r - 1];
+    out[x] = (delta * scale) >> FIX;
+  }
+  for (; x < w; ++x) {         // right mirroring
+    const uint16_t delta =
+        2 * in[w - 1] - in[2 * w - 2 - r - x] - in[x - r - 1];
+    out[x] = (delta * scale) >> FIX;
+  }
+}
+
+// emit one filtered output row
+static void ApplyFilter(SmoothParams* const p) {
+  const uint16_t* const average = p->average_;
+  const int w = p->width_;
+  const int16_t* const correction = p->correction_;
+#if defined(USE_DITHERING)
+  const uint8_t* const dither = kOrderedDither[p->row_ % DSIZE];
+#endif
+  uint8_t* const dst = p->dst_;
+  int x;
+  for (x = 0; x < w; ++x) {
+    const int v = dst[x];
+    if (v < p->max_ && v > p->min_) {
+      const int c = (v << DFIX) + correction[average[x] - (v << LFIX)];
+#if defined(USE_DITHERING)
+      dst[x] = clip_8b(c + dither[x % DSIZE]);
+#else
+      dst[x] = clip_8b(c);
+#endif
+    }
+  }
+  p->dst_ += w;  // advance output pointer
+}
+
+//------------------------------------------------------------------------------
+// Initialize correction table
+
+static void InitCorrectionLUT(int16_t* const lut, int min_dist) {
+  // The correction curve is:
+  //   f(x) = x for x <= threshold2
+  //   f(x) = 0 for x >= threshold1
+  // and a linear interpolation for range x=[threshold2, threshold1]
+  // (along with f(-x) = -f(x) symmetry).
+  // Note that: threshold2 = 3/4 * threshold1
+  const int threshold1 = min_dist << LFIX;
+  const int threshold2 = (3 * threshold1) >> 2;
+  const int max_threshold = threshold2 << DFIX;
+  const int delta = threshold1 - threshold2;
+  int i;
+  for (i = 1; i <= LUT_SIZE; ++i) {
+    int c = (i <= threshold2) ? (i << DFIX)
+          : (i < threshold1) ? max_threshold * (threshold1 - i) / delta
+          : 0;
+    c >>= LFIX;
+    lut[+i] = +c;
+    lut[-i] = -c;
+  }
+  lut[0] = 0;
+}
+
+static void CountLevels(const uint8_t* const data, int size,
+                        SmoothParams* const p) {
+  int i, last_level;
+  uint8_t used_levels[256] = { 0 };
+  p->min_ = 255;
+  p->max_ = 0;
+  for (i = 0; i < size; ++i) {
+    const int v = data[i];
+    if (v < p->min_) p->min_ = v;
+    if (v > p->max_) p->max_ = v;
+    used_levels[v] = 1;
+  }
+  // Compute the mininum distance between two non-zero levels.
+  p->min_level_dist_ = p->max_ - p->min_;
+  last_level = -1;
+  for (i = 0; i < 256; ++i) {
+    if (used_levels[i]) {
+      ++p->num_levels_;
+      if (last_level >= 0) {
+        const int level_dist = i - last_level;
+        if (level_dist < p->min_level_dist_) {
+          p->min_level_dist_ = level_dist;
+        }
+      }
+      last_level = i;
+    }
+  }
+}
+
+// Initialize all params.
+static int InitParams(uint8_t* const data, int width, int height,
+                      int radius, SmoothParams* const p) {
+  const int R = 2 * radius + 1;  // total size of the kernel
+
+  const size_t size_scratch_m = (R + 1) * width * sizeof(*p->start_);
+  const size_t size_m =  width * sizeof(*p->average_);
+  const size_t size_lut = (1 + 2 * LUT_SIZE) * sizeof(*p->correction_);
+  const size_t total_size = size_scratch_m + size_m + size_lut;
+  uint8_t* mem = (uint8_t*)WebPSafeMalloc(1U, total_size);
+
+  if (mem == NULL) return 0;
+  p->mem_ = (void*)mem;
+
+  p->start_ = (uint16_t*)mem;
+  p->cur_ = p->start_;
+  p->end_ = p->start_ + R * width;
+  p->top_ = p->end_ - width;
+  memset(p->top_, 0, width * sizeof(*p->top_));
+  mem += size_scratch_m;
+
+  p->average_ = (uint16_t*)mem;
+  mem += size_m;
+
+  p->width_ = width;
+  p->height_ = height;
+  p->src_ = data;
+  p->dst_ = data;
+  p->radius_ = radius;
+  p->scale_ = (1 << (FIX + LFIX)) / (R * R);  // normalization constant
+  p->row_ = -radius;
+
+  // analyze the input distribution so we can best-fit the threshold
+  CountLevels(data, width * height, p);
+
+  // correction table
+  p->correction_ = ((int16_t*)mem) + LUT_SIZE;
+  InitCorrectionLUT(p->correction_, p->min_level_dist_);
+
+  return 1;
+}
+
+static void CleanupParams(SmoothParams* const p) {
+  WebPSafeFree(p->mem_);
+}
+
+int WebPDequantizeLevels(uint8_t* const data, int width, int height,
+                         int strength) {
+  const int radius = 4 * strength / 100;
+  if (strength < 0 || strength > 100) return 0;
+  if (data == NULL || width <= 0 || height <= 0) return 0;  // bad params
+  if (radius > 0) {
+    SmoothParams p;
+    memset(&p, 0, sizeof(p));
+    if (!InitParams(data, width, height, radius, &p)) return 0;
+    if (p.num_levels_ > 2) {
+      for (; p.row_ < p.height_; ++p.row_) {
+        VFilter(&p);  // accumulate average of input
+        // Need to wait few rows in order to prime the filter,
+        // before emitting some output.
+        if (p.row_ >= p.radius_) {
+          HFilter(&p);
+          ApplyFilter(&p);
+        }
+      }
+    }
+    CleanupParams(&p);
+  }
+  return 1;
+}
diff --git a/Source/LibWebP/src/utils/utils.random.c b/Source/LibWebP/src/utils/utils.random.c
new file mode 100644
index 0000000..4c520a6
--- /dev/null
+++ b/Source/LibWebP/src/utils/utils.random.c
@@ -0,0 +1,43 @@
+// Copyright 2013 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Pseudo-random utilities
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include <string.h>
+#include "./random.h"
+
+//------------------------------------------------------------------------------
+
+// 31b-range values
+static const uint32_t kRandomTable[VP8_RANDOM_TABLE_SIZE] = {
+  0x0de15230, 0x03b31886, 0x775faccb, 0x1c88626a, 0x68385c55, 0x14b3b828,
+  0x4a85fef8, 0x49ddb84b, 0x64fcf397, 0x5c550289, 0x4a290000, 0x0d7ec1da,
+  0x5940b7ab, 0x5492577d, 0x4e19ca72, 0x38d38c69, 0x0c01ee65, 0x32a1755f,
+  0x5437f652, 0x5abb2c32, 0x0faa57b1, 0x73f533e7, 0x685feeda, 0x7563cce2,
+  0x6e990e83, 0x4730a7ed, 0x4fc0d9c6, 0x496b153c, 0x4f1403fa, 0x541afb0c,
+  0x73990b32, 0x26d7cb1c, 0x6fcc3706, 0x2cbb77d8, 0x75762f2a, 0x6425ccdd,
+  0x24b35461, 0x0a7d8715, 0x220414a8, 0x141ebf67, 0x56b41583, 0x73e502e3,
+  0x44cab16f, 0x28264d42, 0x73baaefb, 0x0a50ebed, 0x1d6ab6fb, 0x0d3ad40b,
+  0x35db3b68, 0x2b081e83, 0x77ce6b95, 0x5181e5f0, 0x78853bbc, 0x009f9494,
+  0x27e5ed3c
+};
+
+void VP8InitRandom(VP8Random* const rg, float dithering) {
+  memcpy(rg->tab_, kRandomTable, sizeof(rg->tab_));
+  rg->index1_ = 0;
+  rg->index2_ = 31;
+  rg->amp_ = (dithering < 0.0) ? 0
+           : (dithering > 1.0) ? (1 << VP8_RANDOM_DITHER_FIX)
+           : (uint32_t)((1 << VP8_RANDOM_DITHER_FIX) * dithering);
+}
+
+//------------------------------------------------------------------------------
+
diff --git a/Source/LibWebP/src/utils/utils.rescaler.c b/Source/LibWebP/src/utils/utils.rescaler.c
new file mode 100644
index 0000000..20d32d3
--- /dev/null
+++ b/Source/LibWebP/src/utils/utils.rescaler.c
@@ -0,0 +1,82 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Rescaling functions
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include <assert.h>
+#include <stdlib.h>
+#include "../dsp/dsp.h"
+#include "./rescaler.h"
+
+//------------------------------------------------------------------------------
+
+void WebPRescalerInit(WebPRescaler* const wrk, int src_width, int src_height,
+                      uint8_t* const dst, int dst_width, int dst_height,
+                      int dst_stride, int num_channels, int x_add, int x_sub,
+                      int y_add, int y_sub, int32_t* const work) {
+  wrk->x_expand = (src_width < dst_width);
+  wrk->src_width = src_width;
+  wrk->src_height = src_height;
+  wrk->dst_width = dst_width;
+  wrk->dst_height = dst_height;
+  wrk->dst = dst;
+  wrk->dst_stride = dst_stride;
+  wrk->num_channels = num_channels;
+  // for 'x_expand', we use bilinear interpolation
+  wrk->x_add = wrk->x_expand ? (x_sub - 1) : x_add - x_sub;
+  wrk->x_sub = wrk->x_expand ? (x_add - 1) : x_sub;
+  wrk->y_accum = y_add;
+  wrk->y_add = y_add;
+  wrk->y_sub = y_sub;
+  wrk->fx_scale = (1 << WEBP_RESCALER_RFIX) / x_sub;
+  wrk->fy_scale = (1 << WEBP_RESCALER_RFIX) / y_sub;
+  wrk->fxy_scale = wrk->x_expand ?
+      ((int64_t)dst_height << WEBP_RESCALER_RFIX) / (x_sub * src_height) :
+      ((int64_t)dst_height << WEBP_RESCALER_RFIX) / (x_add * src_height);
+  wrk->irow = work;
+  wrk->frow = work + num_channels * dst_width;
+
+  WebPRescalerDspInit();
+}
+
+//------------------------------------------------------------------------------
+// all-in-one calls
+
+int WebPRescaleNeededLines(const WebPRescaler* const wrk, int max_num_lines) {
+  const int num_lines = (wrk->y_accum + wrk->y_sub - 1) / wrk->y_sub;
+  return (num_lines > max_num_lines) ? max_num_lines : num_lines;
+}
+
+int WebPRescalerImport(WebPRescaler* const wrk, int num_lines,
+                       const uint8_t* src, int src_stride) {
+  int total_imported = 0;
+  while (total_imported < num_lines && wrk->y_accum > 0) {
+    int channel;
+    for (channel = 0; channel < wrk->num_channels; ++channel) {
+      WebPRescalerImportRow(wrk, src, channel);
+    }
+    src += src_stride;
+    ++total_imported;
+    wrk->y_accum -= wrk->y_sub;
+  }
+  return total_imported;
+}
+
+int WebPRescalerExport(WebPRescaler* const rescaler) {
+  int total_exported = 0;
+  while (WebPRescalerHasPendingOutput(rescaler)) {
+    WebPRescalerExportRow(rescaler, 0);
+    ++total_exported;
+  }
+  return total_exported;
+}
+
+//------------------------------------------------------------------------------
diff --git a/Source/LibWebP/src/utils/utils.thread.c b/Source/LibWebP/src/utils/utils.thread.c
new file mode 100644
index 0000000..c94022d
--- /dev/null
+++ b/Source/LibWebP/src/utils/utils.thread.c
@@ -0,0 +1,309 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Multi-threaded worker
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include <assert.h>
+#include <string.h>   // for memset()
+#include "./thread.h"
+#include "./utils.h"
+
+#ifdef WEBP_USE_THREAD
+
+#if defined(_WIN32)
+
+#include <windows.h>
+typedef HANDLE pthread_t;
+typedef CRITICAL_SECTION pthread_mutex_t;
+typedef struct {
+  HANDLE waiting_sem_;
+  HANDLE received_sem_;
+  HANDLE signal_event_;
+} pthread_cond_t;
+
+#else  // !_WIN32
+
+#include <pthread.h>
+
+#endif  // _WIN32
+
+struct WebPWorkerImpl {
+  pthread_mutex_t mutex_;
+  pthread_cond_t  condition_;
+  pthread_t       thread_;
+};
+
+#if defined(_WIN32)
+
+//------------------------------------------------------------------------------
+// simplistic pthread emulation layer
+
+#include <process.h>
+
+// _beginthreadex requires __stdcall
+#define THREADFN unsigned int __stdcall
+#define THREAD_RETURN(val) (unsigned int)((DWORD_PTR)val)
+
+static int pthread_create(pthread_t* const thread, const void* attr,
+                          unsigned int (__stdcall *start)(void*), void* arg) {
+  (void)attr;
+  *thread = (pthread_t)_beginthreadex(NULL,   /* void *security */
+                                      0,      /* unsigned stack_size */
+                                      start,
+                                      arg,
+                                      0,      /* unsigned initflag */
+                                      NULL);  /* unsigned *thrdaddr */
+  if (*thread == NULL) return 1;
+  SetThreadPriority(*thread, THREAD_PRIORITY_ABOVE_NORMAL);
+  return 0;
+}
+
+static int pthread_join(pthread_t thread, void** value_ptr) {
+  (void)value_ptr;
+  return (WaitForSingleObject(thread, INFINITE) != WAIT_OBJECT_0 ||
+          CloseHandle(thread) == 0);
+}
+
+// Mutex
+static int pthread_mutex_init(pthread_mutex_t* const mutex, void* mutexattr) {
+  (void)mutexattr;
+  InitializeCriticalSection(mutex);
+  return 0;
+}
+
+static int pthread_mutex_lock(pthread_mutex_t* const mutex) {
+  EnterCriticalSection(mutex);
+  return 0;
+}
+
+static int pthread_mutex_unlock(pthread_mutex_t* const mutex) {
+  LeaveCriticalSection(mutex);
+  return 0;
+}
+
+static int pthread_mutex_destroy(pthread_mutex_t* const mutex) {
+  DeleteCriticalSection(mutex);
+  return 0;
+}
+
+// Condition
+static int pthread_cond_destroy(pthread_cond_t* const condition) {
+  int ok = 1;
+  ok &= (CloseHandle(condition->waiting_sem_) != 0);
+  ok &= (CloseHandle(condition->received_sem_) != 0);
+  ok &= (CloseHandle(condition->signal_event_) != 0);
+  return !ok;
+}
+
+static int pthread_cond_init(pthread_cond_t* const condition, void* cond_attr) {
+  (void)cond_attr;
+  condition->waiting_sem_ = CreateSemaphore(NULL, 0, 1, NULL);
+  condition->received_sem_ = CreateSemaphore(NULL, 0, 1, NULL);
+  condition->signal_event_ = CreateEvent(NULL, FALSE, FALSE, NULL);
+  if (condition->waiting_sem_ == NULL ||
+      condition->received_sem_ == NULL ||
+      condition->signal_event_ == NULL) {
+    pthread_cond_destroy(condition);
+    return 1;
+  }
+  return 0;
+}
+
+static int pthread_cond_signal(pthread_cond_t* const condition) {
+  int ok = 1;
+  if (WaitForSingleObject(condition->waiting_sem_, 0) == WAIT_OBJECT_0) {
+    // a thread is waiting in pthread_cond_wait: allow it to be notified
+    ok = SetEvent(condition->signal_event_);
+    // wait until the event is consumed so the signaler cannot consume
+    // the event via its own pthread_cond_wait.
+    ok &= (WaitForSingleObject(condition->received_sem_, INFINITE) !=
+           WAIT_OBJECT_0);
+  }
+  return !ok;
+}
+
+static int pthread_cond_wait(pthread_cond_t* const condition,
+                             pthread_mutex_t* const mutex) {
+  int ok;
+  // note that there is a consumer available so the signal isn't dropped in
+  // pthread_cond_signal
+  if (!ReleaseSemaphore(condition->waiting_sem_, 1, NULL))
+    return 1;
+  // now unlock the mutex so pthread_cond_signal may be issued
+  pthread_mutex_unlock(mutex);
+  ok = (WaitForSingleObject(condition->signal_event_, INFINITE) ==
+        WAIT_OBJECT_0);
+  ok &= ReleaseSemaphore(condition->received_sem_, 1, NULL);
+  pthread_mutex_lock(mutex);
+  return !ok;
+}
+
+#else  // !_WIN32
+# define THREADFN void*
+# define THREAD_RETURN(val) val
+#endif  // _WIN32
+
+//------------------------------------------------------------------------------
+
+static void Execute(WebPWorker* const worker);  // Forward declaration.
+
+static THREADFN ThreadLoop(void* ptr) {
+  WebPWorker* const worker = (WebPWorker*)ptr;
+  int done = 0;
+  while (!done) {
+    pthread_mutex_lock(&worker->impl_->mutex_);
+    while (worker->status_ == OK) {   // wait in idling mode
+      pthread_cond_wait(&worker->impl_->condition_, &worker->impl_->mutex_);
+    }
+    if (worker->status_ == WORK) {
+      Execute(worker);
+      worker->status_ = OK;
+    } else if (worker->status_ == NOT_OK) {   // finish the worker
+      done = 1;
+    }
+    // signal to the main thread that we're done (for Sync())
+    pthread_cond_signal(&worker->impl_->condition_);
+    pthread_mutex_unlock(&worker->impl_->mutex_);
+  }
+  return THREAD_RETURN(NULL);    // Thread is finished
+}
+
+// main thread state control
+static void ChangeState(WebPWorker* const worker,
+                        WebPWorkerStatus new_status) {
+  // No-op when attempting to change state on a thread that didn't come up.
+  // Checking status_ without acquiring the lock first would result in a data
+  // race.
+  if (worker->impl_ == NULL) return;
+
+  pthread_mutex_lock(&worker->impl_->mutex_);
+  if (worker->status_ >= OK) {
+    // wait for the worker to finish
+    while (worker->status_ != OK) {
+      pthread_cond_wait(&worker->impl_->condition_, &worker->impl_->mutex_);
+    }
+    // assign new status and release the working thread if needed
+    if (new_status != OK) {
+      worker->status_ = new_status;
+      pthread_cond_signal(&worker->impl_->condition_);
+    }
+  }
+  pthread_mutex_unlock(&worker->impl_->mutex_);
+}
+
+#endif  // WEBP_USE_THREAD
+
+//------------------------------------------------------------------------------
+
+static void Init(WebPWorker* const worker) {
+  memset(worker, 0, sizeof(*worker));
+  worker->status_ = NOT_OK;
+}
+
+static int Sync(WebPWorker* const worker) {
+#ifdef WEBP_USE_THREAD
+  ChangeState(worker, OK);
+#endif
+  assert(worker->status_ <= OK);
+  return !worker->had_error;
+}
+
+static int Reset(WebPWorker* const worker) {
+  int ok = 1;
+  worker->had_error = 0;
+  if (worker->status_ < OK) {
+#ifdef WEBP_USE_THREAD
+    worker->impl_ = (WebPWorkerImpl*)WebPSafeCalloc(1, sizeof(*worker->impl_));
+    if (worker->impl_ == NULL) {
+      return 0;
+    }
+    if (pthread_mutex_init(&worker->impl_->mutex_, NULL)) {
+      goto Error;
+    }
+    if (pthread_cond_init(&worker->impl_->condition_, NULL)) {
+      pthread_mutex_destroy(&worker->impl_->mutex_);
+      goto Error;
+    }
+    pthread_mutex_lock(&worker->impl_->mutex_);
+    ok = !pthread_create(&worker->impl_->thread_, NULL, ThreadLoop, worker);
+    if (ok) worker->status_ = OK;
+    pthread_mutex_unlock(&worker->impl_->mutex_);
+    if (!ok) {
+      pthread_mutex_destroy(&worker->impl_->mutex_);
+      pthread_cond_destroy(&worker->impl_->condition_);
+ Error:
+      WebPSafeFree(worker->impl_);
+      worker->impl_ = NULL;
+      return 0;
+    }
+#else
+    worker->status_ = OK;
+#endif
+  } else if (worker->status_ > OK) {
+    ok = Sync(worker);
+  }
+  assert(!ok || (worker->status_ == OK));
+  return ok;
+}
+
+static void Execute(WebPWorker* const worker) {
+  if (worker->hook != NULL) {
+    worker->had_error |= !worker->hook(worker->data1, worker->data2);
+  }
+}
+
+static void Launch(WebPWorker* const worker) {
+#ifdef WEBP_USE_THREAD
+  ChangeState(worker, WORK);
+#else
+  Execute(worker);
+#endif
+}
+
+static void End(WebPWorker* const worker) {
+#ifdef WEBP_USE_THREAD
+  if (worker->impl_ != NULL) {
+    ChangeState(worker, NOT_OK);
+    pthread_join(worker->impl_->thread_, NULL);
+    pthread_mutex_destroy(&worker->impl_->mutex_);
+    pthread_cond_destroy(&worker->impl_->condition_);
+    WebPSafeFree(worker->impl_);
+    worker->impl_ = NULL;
+  }
+#else
+  worker->status_ = NOT_OK;
+  assert(worker->impl_ == NULL);
+#endif
+  assert(worker->status_ == NOT_OK);
+}
+
+//------------------------------------------------------------------------------
+
+static WebPWorkerInterface g_worker_interface = {
+  Init, Reset, Sync, Launch, Execute, End
+};
+
+int WebPSetWorkerInterface(const WebPWorkerInterface* const winterface) {
+  if (winterface == NULL ||
+      winterface->Init == NULL || winterface->Reset == NULL ||
+      winterface->Sync == NULL || winterface->Launch == NULL ||
+      winterface->Execute == NULL || winterface->End == NULL) {
+    return 0;
+  }
+  g_worker_interface = *winterface;
+  return 1;
+}
+
+const WebPWorkerInterface* WebPGetWorkerInterface(void) {
+  return &g_worker_interface;
+}
+
+//------------------------------------------------------------------------------
diff --git a/Source/LibWebP/src/utils/utils.utils.c b/Source/LibWebP/src/utils/utils.utils.c
new file mode 100644
index 0000000..34c963e
--- /dev/null
+++ b/Source/LibWebP/src/utils/utils.utils.c
@@ -0,0 +1,211 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Misc. common utility functions
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#include <stdlib.h>
+#include "./utils.h"
+
+// If PRINT_MEM_INFO is defined, extra info (like total memory used, number of
+// alloc/free etc) is printed. For debugging/tuning purpose only (it's slow,
+// and not multi-thread safe!).
+// An interesting alternative is valgrind's 'massif' tool:
+//    http://valgrind.org/docs/manual/ms-manual.html
+// Here is an example command line:
+/*    valgrind --tool=massif --massif-out-file=massif.out \
+               --stacks=yes --alloc-fn=WebPSafeAlloc --alloc-fn=WebPSafeCalloc
+      ms_print massif.out
+*/
+// In addition:
+// * if PRINT_MEM_TRAFFIC is defined, all the details of the malloc/free cycles
+//   are printed.
+// * if MALLOC_FAIL_AT is defined, the global environment variable
+//   $MALLOC_FAIL_AT is used to simulate a memory error when calloc or malloc
+//   is called for the nth time. Example usage:
+//   export MALLOC_FAIL_AT=50 && ./examples/cwebp input.png
+// * if MALLOC_LIMIT is defined, the global environment variable $MALLOC_LIMIT
+//   sets the maximum amount of memory (in bytes) made available to libwebp.
+//   This can be used to emulate environment with very limited memory.
+//   Example: export MALLOC_LIMIT=64000000 && ./examples/dwebp picture.webp
+
+// #define PRINT_MEM_INFO
+// #define PRINT_MEM_TRAFFIC
+// #define MALLOC_FAIL_AT
+// #define MALLOC_LIMIT
+
+//------------------------------------------------------------------------------
+// Checked memory allocation
+
+#if defined(PRINT_MEM_INFO)
+
+#include <stdio.h>
+#include <stdlib.h>  // for abort()
+
+static int num_malloc_calls = 0;
+static int num_calloc_calls = 0;
+static int num_free_calls = 0;
+static int countdown_to_fail = 0;     // 0 = off
+
+typedef struct MemBlock MemBlock;
+struct MemBlock {
+  void* ptr_;
+  size_t size_;
+  MemBlock* next_;
+};
+
+static MemBlock* all_blocks = NULL;
+static size_t total_mem = 0;
+static size_t total_mem_allocated = 0;
+static size_t high_water_mark = 0;
+static size_t mem_limit = 0;
+
+static int exit_registered = 0;
+
+static void PrintMemInfo(void) {
+  fprintf(stderr, "\nMEMORY INFO:\n");
+  fprintf(stderr, "num calls to: malloc = %4d\n", num_malloc_calls);
+  fprintf(stderr, "              calloc = %4d\n", num_calloc_calls);
+  fprintf(stderr, "              free   = %4d\n", num_free_calls);
+  fprintf(stderr, "total_mem: %u\n", (uint32_t)total_mem);
+  fprintf(stderr, "total_mem allocated: %u\n", (uint32_t)total_mem_allocated);
+  fprintf(stderr, "high-water mark: %u\n", (uint32_t)high_water_mark);
+  while (all_blocks != NULL) {
+    MemBlock* b = all_blocks;
+    all_blocks = b->next_;
+    free(b);
+  }
+}
+
+static void Increment(int* const v) {
+  if (!exit_registered) {
+#if defined(MALLOC_FAIL_AT)
+    {
+      const char* const malloc_fail_at_str = getenv("MALLOC_FAIL_AT");
+      if (malloc_fail_at_str != NULL) {
+        countdown_to_fail = atoi(malloc_fail_at_str);
+      }
+    }
+#endif
+#if defined(MALLOC_LIMIT)
+    {
+      const char* const malloc_limit_str = getenv("MALLOC_LIMIT");
+      if (malloc_limit_str != NULL) {
+        mem_limit = atoi(malloc_limit_str);
+      }
+    }
+#endif
+    (void)countdown_to_fail;
+    (void)mem_limit;
+    atexit(PrintMemInfo);
+    exit_registered = 1;
+  }
+  ++*v;
+}
+
+static void AddMem(void* ptr, size_t size) {
+  if (ptr != NULL) {
+    MemBlock* const b = (MemBlock*)malloc(sizeof(*b));
+    if (b == NULL) abort();
+    b->next_ = all_blocks;
+    all_blocks = b;
+    b->ptr_ = ptr;
+    b->size_ = size;
+    total_mem += size;
+    total_mem_allocated += size;
+#if defined(PRINT_MEM_TRAFFIC)
+#if defined(MALLOC_FAIL_AT)
+    fprintf(stderr, "fail-count: %5d [mem=%u]\n",
+            num_malloc_calls + num_calloc_calls, (uint32_t)total_mem);
+#else
+    fprintf(stderr, "Mem: %u (+%u)\n", (uint32_t)total_mem, (uint32_t)size);
+#endif
+#endif
+    if (total_mem > high_water_mark) high_water_mark = total_mem;
+  }
+}
+
+static void SubMem(void* ptr) {
+  if (ptr != NULL) {
+    MemBlock** b = &all_blocks;
+    // Inefficient search, but that's just for debugging.
+    while (*b != NULL && (*b)->ptr_ != ptr) b = &(*b)->next_;
+    if (*b == NULL) {
+      fprintf(stderr, "Invalid pointer free! (%p)\n", ptr);
+      abort();
+    }
+    {
+      MemBlock* const block = *b;
+      *b = block->next_;
+      total_mem -= block->size_;
+#if defined(PRINT_MEM_TRAFFIC)
+      fprintf(stderr, "Mem: %u (-%u)\n",
+              (uint32_t)total_mem, (uint32_t)block->size_);
+#endif
+      free(block);
+    }
+  }
+}
+
+#else
+#define Increment(v) do {} while (0)
+#define AddMem(p, s) do {} while (0)
+#define SubMem(p)    do {} while (0)
+#endif
+
+// Returns 0 in case of overflow of nmemb * size.
+static int CheckSizeArgumentsOverflow(uint64_t nmemb, size_t size) {
+  const uint64_t total_size = nmemb * size;
+  if (nmemb == 0) return 1;
+  if ((uint64_t)size > WEBP_MAX_ALLOCABLE_MEMORY / nmemb) return 0;
+  if (total_size != (size_t)total_size) return 0;
+#if defined(PRINT_MEM_INFO) && defined(MALLOC_FAIL_AT)
+  if (countdown_to_fail > 0 && --countdown_to_fail == 0) {
+    return 0;    // fake fail!
+  }
+#endif
+#if defined(MALLOC_LIMIT)
+  if (mem_limit > 0 && total_mem + total_size >= mem_limit) {
+    return 0;   // fake fail!
+  }
+#endif
+
+  return 1;
+}
+
+void* WebPSafeMalloc(uint64_t nmemb, size_t size) {
+  void* ptr;
+  Increment(&num_malloc_calls);
+  if (!CheckSizeArgumentsOverflow(nmemb, size)) return NULL;
+  assert(nmemb * size > 0);
+  ptr = malloc((size_t)(nmemb * size));
+  AddMem(ptr, (size_t)(nmemb * size));
+  return ptr;
+}
+
+void* WebPSafeCalloc(uint64_t nmemb, size_t size) {
+  void* ptr;
+  Increment(&num_calloc_calls);
+  if (!CheckSizeArgumentsOverflow(nmemb, size)) return NULL;
+  assert(nmemb * size > 0);
+  ptr = calloc((size_t)nmemb, size);
+  AddMem(ptr, (size_t)(nmemb * size));
+  return ptr;
+}
+
+void WebPSafeFree(void* const ptr) {
+  if (ptr != NULL) {
+    Increment(&num_free_calls);
+    SubMem(ptr);
+  }
+  free(ptr);
+}
+
+//------------------------------------------------------------------------------
diff --git a/Source/LibWebP/src/webp/decode.h b/Source/LibWebP/src/webp/decode.h
new file mode 100644
index 0000000..71224ce
--- /dev/null
+++ b/Source/LibWebP/src/webp/decode.h
@@ -0,0 +1,493 @@
+// Copyright 2010 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+//  Main decoding functions for WebP images.
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#ifndef WEBP_WEBP_DECODE_H_
+#define WEBP_WEBP_DECODE_H_
+
+#include "./types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define WEBP_DECODER_ABI_VERSION 0x0205    // MAJOR(8b) + MINOR(8b)
+
+// Note: forward declaring enumerations is not allowed in (strict) C and C++,
+// the types are left here for reference.
+// typedef enum VP8StatusCode VP8StatusCode;
+// typedef enum WEBP_CSP_MODE WEBP_CSP_MODE;
+typedef struct WebPRGBABuffer WebPRGBABuffer;
+typedef struct WebPYUVABuffer WebPYUVABuffer;
+typedef struct WebPDecBuffer WebPDecBuffer;
+typedef struct WebPIDecoder WebPIDecoder;
+typedef struct WebPBitstreamFeatures WebPBitstreamFeatures;
+typedef struct WebPDecoderOptions WebPDecoderOptions;
+typedef struct WebPDecoderConfig WebPDecoderConfig;
+
+// Return the decoder's version number, packed in hexadecimal using 8bits for
+// each of major/minor/revision. E.g: v2.5.7 is 0x020507.
+WEBP_EXTERN(int) WebPGetDecoderVersion(void);
+
+// Retrieve basic header information: width, height.
+// This function will also validate the header and return 0 in
+// case of formatting error.
+// Pointers 'width' and 'height' can be passed NULL if deemed irrelevant.
+WEBP_EXTERN(int) WebPGetInfo(const uint8_t* data, size_t data_size,
+                             int* width, int* height);
+
+// Decodes WebP images pointed to by 'data' and returns RGBA samples, along
+// with the dimensions in *width and *height. The ordering of samples in
+// memory is R, G, B, A, R, G, B, A... in scan order (endian-independent).
+// The returned pointer should be deleted calling free().
+// Returns NULL in case of error.
+WEBP_EXTERN(uint8_t*) WebPDecodeRGBA(const uint8_t* data, size_t data_size,
+                                     int* width, int* height);
+
+// Same as WebPDecodeRGBA, but returning A, R, G, B, A, R, G, B... ordered data.
+WEBP_EXTERN(uint8_t*) WebPDecodeARGB(const uint8_t* data, size_t data_size,
+                                     int* width, int* height);
+
+// Same as WebPDecodeRGBA, but returning B, G, R, A, B, G, R, A... ordered data.
+WEBP_EXTERN(uint8_t*) WebPDecodeBGRA(const uint8_t* data, size_t data_size,
+                                     int* width, int* height);
+
+// Same as WebPDecodeRGBA, but returning R, G, B, R, G, B... ordered data.
+// If the bitstream contains transparency, it is ignored.
+WEBP_EXTERN(uint8_t*) WebPDecodeRGB(const uint8_t* data, size_t data_size,
+                                    int* width, int* height);
+
+// Same as WebPDecodeRGB, but returning B, G, R, B, G, R... ordered data.
+WEBP_EXTERN(uint8_t*) WebPDecodeBGR(const uint8_t* data, size_t data_size,
+                                    int* width, int* height);
+
+
+// Decode WebP images pointed to by 'data' to Y'UV format(*). The pointer
+// returned is the Y samples buffer. Upon return, *u and *v will point to
+// the U and V chroma data. These U and V buffers need NOT be free()'d,
+// unlike the returned Y luma one. The dimension of the U and V planes
+// are both (*width + 1) / 2 and (*height + 1)/ 2.
+// Upon return, the Y buffer has a stride returned as '*stride', while U and V
+// have a common stride returned as '*uv_stride'.
+// Return NULL in case of error.
+// (*) Also named Y'CbCr. See: http://en.wikipedia.org/wiki/YCbCr
+WEBP_EXTERN(uint8_t*) WebPDecodeYUV(const uint8_t* data, size_t data_size,
+                                    int* width, int* height,
+                                    uint8_t** u, uint8_t** v,
+                                    int* stride, int* uv_stride);
+
+// These five functions are variants of the above ones, that decode the image
+// directly into a pre-allocated buffer 'output_buffer'. The maximum storage
+// available in this buffer is indicated by 'output_buffer_size'. If this
+// storage is not sufficient (or an error occurred), NULL is returned.
+// Otherwise, output_buffer is returned, for convenience.
+// The parameter 'output_stride' specifies the distance (in bytes)
+// between scanlines. Hence, output_buffer_size is expected to be at least
+// output_stride x picture-height.
+WEBP_EXTERN(uint8_t*) WebPDecodeRGBAInto(
+    const uint8_t* data, size_t data_size,
+    uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
+WEBP_EXTERN(uint8_t*) WebPDecodeARGBInto(
+    const uint8_t* data, size_t data_size,
+    uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
+WEBP_EXTERN(uint8_t*) WebPDecodeBGRAInto(
+    const uint8_t* data, size_t data_size,
+    uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
+
+// RGB and BGR variants. Here too the transparency information, if present,
+// will be dropped and ignored.
+WEBP_EXTERN(uint8_t*) WebPDecodeRGBInto(
+    const uint8_t* data, size_t data_size,
+    uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
+WEBP_EXTERN(uint8_t*) WebPDecodeBGRInto(
+    const uint8_t* data, size_t data_size,
+    uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
+
+// WebPDecodeYUVInto() is a variant of WebPDecodeYUV() that operates directly
+// into pre-allocated luma/chroma plane buffers. This function requires the
+// strides to be passed: one for the luma plane and one for each of the
+// chroma ones. The size of each plane buffer is passed as 'luma_size',
+// 'u_size' and 'v_size' respectively.
+// Pointer to the luma plane ('*luma') is returned or NULL if an error occurred
+// during decoding (or because some buffers were found to be too small).
+WEBP_EXTERN(uint8_t*) WebPDecodeYUVInto(
+    const uint8_t* data, size_t data_size,
+    uint8_t* luma, size_t luma_size, int luma_stride,
+    uint8_t* u, size_t u_size, int u_stride,
+    uint8_t* v, size_t v_size, int v_stride);
+
+//------------------------------------------------------------------------------
+// Output colorspaces and buffer
+
+// Colorspaces
+// Note: the naming describes the byte-ordering of packed samples in memory.
+// For instance, MODE_BGRA relates to samples ordered as B,G,R,A,B,G,R,A,...
+// Non-capital names (e.g.:MODE_Argb) relates to pre-multiplied RGB channels.
+// RGBA-4444 and RGB-565 colorspaces are represented by following byte-order:
+// RGBA-4444: [r3 r2 r1 r0 g3 g2 g1 g0], [b3 b2 b1 b0 a3 a2 a1 a0], ...
+// RGB-565: [r4 r3 r2 r1 r0 g5 g4 g3], [g2 g1 g0 b4 b3 b2 b1 b0], ...
+// In the case WEBP_SWAP_16BITS_CSP is defined, the bytes are swapped for
+// these two modes:
+// RGBA-4444: [b3 b2 b1 b0 a3 a2 a1 a0], [r3 r2 r1 r0 g3 g2 g1 g0], ...
+// RGB-565: [g2 g1 g0 b4 b3 b2 b1 b0], [r4 r3 r2 r1 r0 g5 g4 g3], ...
+
+typedef enum WEBP_CSP_MODE {
+  MODE_RGB = 0, MODE_RGBA = 1,
+  MODE_BGR = 2, MODE_BGRA = 3,
+  MODE_ARGB = 4, MODE_RGBA_4444 = 5,
+  MODE_RGB_565 = 6,
+  // RGB-premultiplied transparent modes (alpha value is preserved)
+  MODE_rgbA = 7,
+  MODE_bgrA = 8,
+  MODE_Argb = 9,
+  MODE_rgbA_4444 = 10,
+  // YUV modes must come after RGB ones.
+  MODE_YUV = 11, MODE_YUVA = 12,  // yuv 4:2:0
+  MODE_LAST = 13
+} WEBP_CSP_MODE;
+
+// Some useful macros:
+static WEBP_INLINE int WebPIsPremultipliedMode(WEBP_CSP_MODE mode) {
+  return (mode == MODE_rgbA || mode == MODE_bgrA || mode == MODE_Argb ||
+          mode == MODE_rgbA_4444);
+}
+
+static WEBP_INLINE int WebPIsAlphaMode(WEBP_CSP_MODE mode) {
+  return (mode == MODE_RGBA || mode == MODE_BGRA || mode == MODE_ARGB ||
+          mode == MODE_RGBA_4444 || mode == MODE_YUVA ||
+          WebPIsPremultipliedMode(mode));
+}
+
+static WEBP_INLINE int WebPIsRGBMode(WEBP_CSP_MODE mode) {
+  return (mode < MODE_YUV);
+}
+
+//------------------------------------------------------------------------------
+// WebPDecBuffer: Generic structure for describing the output sample buffer.
+
+struct WebPRGBABuffer {    // view as RGBA
+  uint8_t* rgba;    // pointer to RGBA samples
+  int stride;       // stride in bytes from one scanline to the next.
+  size_t size;      // total size of the *rgba buffer.
+};
+
+struct WebPYUVABuffer {              // view as YUVA
+  uint8_t* y, *u, *v, *a;     // pointer to luma, chroma U/V, alpha samples
+  int y_stride;               // luma stride
+  int u_stride, v_stride;     // chroma strides
+  int a_stride;               // alpha stride
+  size_t y_size;              // luma plane size
+  size_t u_size, v_size;      // chroma planes size
+  size_t a_size;              // alpha-plane size
+};
+
+// Output buffer
+struct WebPDecBuffer {
+  WEBP_CSP_MODE colorspace;  // Colorspace.
+  int width, height;         // Dimensions.
+  int is_external_memory;    // If true, 'internal_memory' pointer is not used.
+  union {
+    WebPRGBABuffer RGBA;
+    WebPYUVABuffer YUVA;
+  } u;                       // Nameless union of buffer parameters.
+  uint32_t       pad[4];     // padding for later use
+
+  uint8_t* private_memory;   // Internally allocated memory (only when
+                             // is_external_memory is false). Should not be used
+                             // externally, but accessed via the buffer union.
+};
+
+// Internal, version-checked, entry point
+WEBP_EXTERN(int) WebPInitDecBufferInternal(WebPDecBuffer*, int);
+
+// Initialize the structure as empty. Must be called before any other use.
+// Returns false in case of version mismatch
+static WEBP_INLINE int WebPInitDecBuffer(WebPDecBuffer* buffer) {
+  return WebPInitDecBufferInternal(buffer, WEBP_DECODER_ABI_VERSION);
+}
+
+// Free any memory associated with the buffer. Must always be called last.
+// Note: doesn't free the 'buffer' structure itself.
+WEBP_EXTERN(void) WebPFreeDecBuffer(WebPDecBuffer* buffer);
+
+//------------------------------------------------------------------------------
+// Enumeration of the status codes
+
+typedef enum VP8StatusCode {
+  VP8_STATUS_OK = 0,
+  VP8_STATUS_OUT_OF_MEMORY,
+  VP8_STATUS_INVALID_PARAM,
+  VP8_STATUS_BITSTREAM_ERROR,
+  VP8_STATUS_UNSUPPORTED_FEATURE,
+  VP8_STATUS_SUSPENDED,
+  VP8_STATUS_USER_ABORT,
+  VP8_STATUS_NOT_ENOUGH_DATA
+} VP8StatusCode;
+
+//------------------------------------------------------------------------------
+// Incremental decoding
+//
+// This API allows streamlined decoding of partial data.
+// Picture can be incrementally decoded as data become available thanks to the
+// WebPIDecoder object. This object can be left in a SUSPENDED state if the
+// picture is only partially decoded, pending additional input.
+// Code example:
+//
+//   WebPInitDecBuffer(&buffer);
+//   buffer.colorspace = mode;
+//   ...
+//   WebPIDecoder* idec = WebPINewDecoder(&buffer);
+//   while (has_more_data) {
+//     // ... (get additional data)
+//     status = WebPIAppend(idec, new_data, new_data_size);
+//     if (status != VP8_STATUS_SUSPENDED ||
+//       break;
+//     }
+//
+//     // The above call decodes the current available buffer.
+//     // Part of the image can now be refreshed by calling to
+//     // WebPIDecGetRGB()/WebPIDecGetYUVA() etc.
+//   }
+//   WebPIDelete(idec);
+
+// Creates a new incremental decoder with the supplied buffer parameter.
+// This output_buffer can be passed NULL, in which case a default output buffer
+// is used (with MODE_RGB). Otherwise, an internal reference to 'output_buffer'
+// is kept, which means that the lifespan of 'output_buffer' must be larger than
+// that of the returned WebPIDecoder object.
+// The supplied 'output_buffer' content MUST NOT be changed between calls to
+// WebPIAppend() or WebPIUpdate() unless 'output_buffer.is_external_memory' is
+// set to 1. In such a case, it is allowed to modify the pointers, size and
+// stride of output_buffer.u.RGBA or output_buffer.u.YUVA, provided they remain
+// within valid bounds.
+// All other fields of WebPDecBuffer MUST remain constant between calls.
+// Returns NULL if the allocation failed.
+WEBP_EXTERN(WebPIDecoder*) WebPINewDecoder(WebPDecBuffer* output_buffer);
+
+// This function allocates and initializes an incremental-decoder object, which
+// will output the RGB/A samples specified by 'csp' into a preallocated
+// buffer 'output_buffer'. The size of this buffer is at least
+// 'output_buffer_size' and the stride (distance in bytes between two scanlines)
+// is specified by 'output_stride'.
+// Additionally, output_buffer can be passed NULL in which case the output
+// buffer will be allocated automatically when the decoding starts. The
+// colorspace 'csp' is taken into account for allocating this buffer. All other
+// parameters are ignored.
+// Returns NULL if the allocation failed, or if some parameters are invalid.
+WEBP_EXTERN(WebPIDecoder*) WebPINewRGB(
+    WEBP_CSP_MODE csp,
+    uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
+
+// This function allocates and initializes an incremental-decoder object, which
+// will output the raw luma/chroma samples into a preallocated planes if
+// supplied. The luma plane is specified by its pointer 'luma', its size
+// 'luma_size' and its stride 'luma_stride'. Similarly, the chroma-u plane
+// is specified by the 'u', 'u_size' and 'u_stride' parameters, and the chroma-v
+// plane by 'v' and 'v_size'. And same for the alpha-plane. The 'a' pointer
+// can be pass NULL in case one is not interested in the transparency plane.
+// Conversely, 'luma' can be passed NULL if no preallocated planes are supplied.
+// In this case, the output buffer will be automatically allocated (using
+// MODE_YUVA) when decoding starts. All parameters are then ignored.
+// Returns NULL if the allocation failed or if a parameter is invalid.
+WEBP_EXTERN(WebPIDecoder*) WebPINewYUVA(
+    uint8_t* luma, size_t luma_size, int luma_stride,
+    uint8_t* u, size_t u_size, int u_stride,
+    uint8_t* v, size_t v_size, int v_stride,
+    uint8_t* a, size_t a_size, int a_stride);
+
+// Deprecated version of the above, without the alpha plane.
+// Kept for backward compatibility.
+WEBP_EXTERN(WebPIDecoder*) WebPINewYUV(
+    uint8_t* luma, size_t luma_size, int luma_stride,
+    uint8_t* u, size_t u_size, int u_stride,
+    uint8_t* v, size_t v_size, int v_stride);
+
+// Deletes the WebPIDecoder object and associated memory. Must always be called
+// if WebPINewDecoder, WebPINewRGB or WebPINewYUV succeeded.
+WEBP_EXTERN(void) WebPIDelete(WebPIDecoder* idec);
+
+// Copies and decodes the next available data. Returns VP8_STATUS_OK when
+// the image is successfully decoded. Returns VP8_STATUS_SUSPENDED when more
+// data is expected. Returns error in other cases.
+WEBP_EXTERN(VP8StatusCode) WebPIAppend(
+    WebPIDecoder* idec, const uint8_t* data, size_t data_size);
+
+// A variant of the above function to be used when data buffer contains
+// partial data from the beginning. In this case data buffer is not copied
+// to the internal memory.
+// Note that the value of the 'data' pointer can change between calls to
+// WebPIUpdate, for instance when the data buffer is resized to fit larger data.
+WEBP_EXTERN(VP8StatusCode) WebPIUpdate(
+    WebPIDecoder* idec, const uint8_t* data, size_t data_size);
+
+// Returns the RGB/A image decoded so far. Returns NULL if output params
+// are not initialized yet. The RGB/A output type corresponds to the colorspace
+// specified during call to WebPINewDecoder() or WebPINewRGB().
+// *last_y is the index of last decoded row in raster scan order. Some pointers
+// (*last_y, *width etc.) can be NULL if corresponding information is not
+// needed.
+WEBP_EXTERN(uint8_t*) WebPIDecGetRGB(
+    const WebPIDecoder* idec, int* last_y,
+    int* width, int* height, int* stride);
+
+// Same as above function to get a YUVA image. Returns pointer to the luma
+// plane or NULL in case of error. If there is no alpha information
+// the alpha pointer '*a' will be returned NULL.
+WEBP_EXTERN(uint8_t*) WebPIDecGetYUVA(
+    const WebPIDecoder* idec, int* last_y,
+    uint8_t** u, uint8_t** v, uint8_t** a,
+    int* width, int* height, int* stride, int* uv_stride, int* a_stride);
+
+// Deprecated alpha-less version of WebPIDecGetYUVA(): it will ignore the
+// alpha information (if present). Kept for backward compatibility.
+static WEBP_INLINE uint8_t* WebPIDecGetYUV(
+    const WebPIDecoder* idec, int* last_y, uint8_t** u, uint8_t** v,
+    int* width, int* height, int* stride, int* uv_stride) {
+  return WebPIDecGetYUVA(idec, last_y, u, v, NULL, width, height,
+                         stride, uv_stride, NULL);
+}
+
+// Generic call to retrieve information about the displayable area.
+// If non NULL, the left/right/width/height pointers are filled with the visible
+// rectangular area so far.
+// Returns NULL in case the incremental decoder object is in an invalid state.
+// Otherwise returns the pointer to the internal representation. This structure
+// is read-only, tied to WebPIDecoder's lifespan and should not be modified.
+WEBP_EXTERN(const WebPDecBuffer*) WebPIDecodedArea(
+    const WebPIDecoder* idec, int* left, int* top, int* width, int* height);
+
+//------------------------------------------------------------------------------
+// Advanced decoding parametrization
+//
+//  Code sample for using the advanced decoding API
+/*
+     // A) Init a configuration object
+     WebPDecoderConfig config;
+     CHECK(WebPInitDecoderConfig(&config));
+
+     // B) optional: retrieve the bitstream's features.
+     CHECK(WebPGetFeatures(data, data_size, &config.input) == VP8_STATUS_OK);
+
+     // C) Adjust 'config', if needed
+     config.no_fancy_upsampling = 1;
+     config.output.colorspace = MODE_BGRA;
+     // etc.
+
+     // Note that you can also make config.output point to an externally
+     // supplied memory buffer, provided it's big enough to store the decoded
+     // picture. Otherwise, config.output will just be used to allocate memory
+     // and store the decoded picture.
+
+     // D) Decode!
+     CHECK(WebPDecode(data, data_size, &config) == VP8_STATUS_OK);
+
+     // E) Decoded image is now in config.output (and config.output.u.RGBA)
+
+     // F) Reclaim memory allocated in config's object. It's safe to call
+     // this function even if the memory is external and wasn't allocated
+     // by WebPDecode().
+     WebPFreeDecBuffer(&config.output);
+*/
+
+// Features gathered from the bitstream
+struct WebPBitstreamFeatures {
+  int width;          // Width in pixels, as read from the bitstream.
+  int height;         // Height in pixels, as read from the bitstream.
+  int has_alpha;      // True if the bitstream contains an alpha channel.
+  int has_animation;  // True if the bitstream is an animation.
+  int format;         // 0 = undefined (/mixed), 1 = lossy, 2 = lossless
+
+  // Unused for now:
+  int no_incremental_decoding;  // if true, using incremental decoding is not
+                                // recommended.
+  int rotate;                   // TODO(later)
+  int uv_sampling;              // should be 0 for now. TODO(later)
+  uint32_t pad[2];              // padding for later use
+};
+
+// Internal, version-checked, entry point
+WEBP_EXTERN(VP8StatusCode) WebPGetFeaturesInternal(
+    const uint8_t*, size_t, WebPBitstreamFeatures*, int);
+
+// Retrieve features from the bitstream. The *features structure is filled
+// with information gathered from the bitstream.
+// Returns VP8_STATUS_OK when the features are successfully retrieved. Returns
+// VP8_STATUS_NOT_ENOUGH_DATA when more data is needed to retrieve the
+// features from headers. Returns error in other cases.
+static WEBP_INLINE VP8StatusCode WebPGetFeatures(
+    const uint8_t* data, size_t data_size,
+    WebPBitstreamFeatures* features) {
+  return WebPGetFeaturesInternal(data, data_size, features,
+                                 WEBP_DECODER_ABI_VERSION);
+}
+
+// Decoding options
+struct WebPDecoderOptions {
+  int bypass_filtering;               // if true, skip the in-loop filtering
+  int no_fancy_upsampling;            // if true, use faster pointwise upsampler
+  int use_cropping;                   // if true, cropping is applied _first_
+  int crop_left, crop_top;            // top-left position for cropping.
+                                      // Will be snapped to even values.
+  int crop_width, crop_height;        // dimension of the cropping area
+  int use_scaling;                    // if true, scaling is applied _afterward_
+  int scaled_width, scaled_height;    // final resolution
+  int use_threads;                    // if true, use multi-threaded decoding
+  int dithering_strength;             // dithering strength (0=Off, 100=full)
+  int flip;                           // flip output vertically
+  int alpha_dithering_strength;       // alpha dithering strength in [0..100]
+
+  // Unused for now:
+  int force_rotation;                 // forced rotation (to be applied _last_)
+  int no_enhancement;                 // if true, discard enhancement layer
+  uint32_t pad[3];                    // padding for later use
+};
+
+// Main object storing the configuration for advanced decoding.
+struct WebPDecoderConfig {
+  WebPBitstreamFeatures input;  // Immutable bitstream features (optional)
+  WebPDecBuffer output;         // Output buffer (can point to external mem)
+  WebPDecoderOptions options;   // Decoding options
+};
+
+// Internal, version-checked, entry point
+WEBP_EXTERN(int) WebPInitDecoderConfigInternal(WebPDecoderConfig*, int);
+
+// Initialize the configuration as empty. This function must always be
+// called first, unless WebPGetFeatures() is to be called.
+// Returns false in case of mismatched version.
+static WEBP_INLINE int WebPInitDecoderConfig(WebPDecoderConfig* config) {
+  return WebPInitDecoderConfigInternal(config, WEBP_DECODER_ABI_VERSION);
+}
+
+// Instantiate a new incremental decoder object with the requested
+// configuration. The bitstream can be passed using 'data' and 'data_size'
+// parameter, in which case the features will be parsed and stored into
+// config->input. Otherwise, 'data' can be NULL and no parsing will occur.
+// Note that 'config' can be NULL too, in which case a default configuration
+// is used.
+// The return WebPIDecoder object must always be deleted calling WebPIDelete().
+// Returns NULL in case of error (and config->status will then reflect
+// the error condition).
+WEBP_EXTERN(WebPIDecoder*) WebPIDecode(const uint8_t* data, size_t data_size,
+                                       WebPDecoderConfig* config);
+
+// Non-incremental version. This version decodes the full data at once, taking
+// 'config' into account. Returns decoding status (which should be VP8_STATUS_OK
+// if the decoding was successful).
+WEBP_EXTERN(VP8StatusCode) WebPDecode(const uint8_t* data, size_t data_size,
+                                      WebPDecoderConfig* config);
+
+#ifdef __cplusplus
+}    // extern "C"
+#endif
+
+#endif  /* WEBP_WEBP_DECODE_H_ */
diff --git a/Source/LibWebP/src/webp/demux.h b/Source/LibWebP/src/webp/demux.h
new file mode 100644
index 0000000..5437d37
--- /dev/null
+++ b/Source/LibWebP/src/webp/demux.h
@@ -0,0 +1,224 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Demux API.
+// Enables extraction of image and extended format data from WebP files.
+
+// Code Example: Demuxing WebP data to extract all the frames, ICC profile
+// and EXIF/XMP metadata.
+/*
+  WebPDemuxer* demux = WebPDemux(&webp_data);
+
+  uint32_t width = WebPDemuxGetI(demux, WEBP_FF_CANVAS_WIDTH);
+  uint32_t height = WebPDemuxGetI(demux, WEBP_FF_CANVAS_HEIGHT);
+  // ... (Get information about the features present in the WebP file).
+  uint32_t flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS);
+
+  // ... (Iterate over all frames).
+  WebPIterator iter;
+  if (WebPDemuxGetFrame(demux, 1, &iter)) {
+    do {
+      // ... (Consume 'iter'; e.g. Decode 'iter.fragment' with WebPDecode(),
+      // ... and get other frame properties like width, height, offsets etc.
+      // ... see 'struct WebPIterator' below for more info).
+    } while (WebPDemuxNextFrame(&iter));
+    WebPDemuxReleaseIterator(&iter);
+  }
+
+  // ... (Extract metadata).
+  WebPChunkIterator chunk_iter;
+  if (flags & ICCP_FLAG) WebPDemuxGetChunk(demux, "ICCP", 1, &chunk_iter);
+  // ... (Consume the ICC profile in 'chunk_iter.chunk').
+  WebPDemuxReleaseChunkIterator(&chunk_iter);
+  if (flags & EXIF_FLAG) WebPDemuxGetChunk(demux, "EXIF", 1, &chunk_iter);
+  // ... (Consume the EXIF metadata in 'chunk_iter.chunk').
+  WebPDemuxReleaseChunkIterator(&chunk_iter);
+  if (flags & XMP_FLAG) WebPDemuxGetChunk(demux, "XMP ", 1, &chunk_iter);
+  // ... (Consume the XMP metadata in 'chunk_iter.chunk').
+  WebPDemuxReleaseChunkIterator(&chunk_iter);
+  WebPDemuxDelete(demux);
+*/
+
+#ifndef WEBP_WEBP_DEMUX_H_
+#define WEBP_WEBP_DEMUX_H_
+
+#include "./mux_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define WEBP_DEMUX_ABI_VERSION 0x0101    // MAJOR(8b) + MINOR(8b)
+
+// Note: forward declaring enumerations is not allowed in (strict) C and C++,
+// the types are left here for reference.
+// typedef enum WebPDemuxState WebPDemuxState;
+// typedef enum WebPFormatFeature WebPFormatFeature;
+typedef struct WebPDemuxer WebPDemuxer;
+typedef struct WebPIterator WebPIterator;
+typedef struct WebPChunkIterator WebPChunkIterator;
+
+//------------------------------------------------------------------------------
+
+// Returns the version number of the demux library, packed in hexadecimal using
+// 8bits for each of major/minor/revision. E.g: v2.5.7 is 0x020507.
+WEBP_EXTERN(int) WebPGetDemuxVersion(void);
+
+//------------------------------------------------------------------------------
+// Life of a Demux object
+
+typedef enum WebPDemuxState {
+  WEBP_DEMUX_PARSE_ERROR    = -1,  // An error occurred while parsing.
+  WEBP_DEMUX_PARSING_HEADER =  0,  // Not enough data to parse full header.
+  WEBP_DEMUX_PARSED_HEADER  =  1,  // Header parsing complete,
+                                   // data may be available.
+  WEBP_DEMUX_DONE           =  2   // Entire file has been parsed.
+} WebPDemuxState;
+
+// Internal, version-checked, entry point
+WEBP_EXTERN(WebPDemuxer*) WebPDemuxInternal(
+    const WebPData*, int, WebPDemuxState*, int);
+
+// Parses the full WebP file given by 'data'.
+// Returns a WebPDemuxer object on successful parse, NULL otherwise.
+static WEBP_INLINE WebPDemuxer* WebPDemux(const WebPData* data) {
+  return WebPDemuxInternal(data, 0, NULL, WEBP_DEMUX_ABI_VERSION);
+}
+
+// Parses the possibly incomplete WebP file given by 'data'.
+// If 'state' is non-NULL it will be set to indicate the status of the demuxer.
+// Returns NULL in case of error or if there isn't enough data to start parsing;
+// and a WebPDemuxer object on successful parse.
+// Note that WebPDemuxer keeps internal pointers to 'data' memory segment.
+// If this data is volatile, the demuxer object should be deleted (by calling
+// WebPDemuxDelete()) and WebPDemuxPartial() called again on the new data.
+// This is usually an inexpensive operation.
+static WEBP_INLINE WebPDemuxer* WebPDemuxPartial(
+    const WebPData* data, WebPDemuxState* state) {
+  return WebPDemuxInternal(data, 1, state, WEBP_DEMUX_ABI_VERSION);
+}
+
+// Frees memory associated with 'dmux'.
+WEBP_EXTERN(void) WebPDemuxDelete(WebPDemuxer* dmux);
+
+//------------------------------------------------------------------------------
+// Data/information extraction.
+
+typedef enum WebPFormatFeature {
+  WEBP_FF_FORMAT_FLAGS,  // Extended format flags present in the 'VP8X' chunk.
+  WEBP_FF_CANVAS_WIDTH,
+  WEBP_FF_CANVAS_HEIGHT,
+  WEBP_FF_LOOP_COUNT,
+  WEBP_FF_BACKGROUND_COLOR,
+  WEBP_FF_FRAME_COUNT    // Number of frames present in the demux object.
+                         // In case of a partial demux, this is the number of
+                         // frames seen so far, with the last frame possibly
+                         // being partial.
+} WebPFormatFeature;
+
+// Get the 'feature' value from the 'dmux'.
+// NOTE: values are only valid if WebPDemux() was used or WebPDemuxPartial()
+// returned a state > WEBP_DEMUX_PARSING_HEADER.
+WEBP_EXTERN(uint32_t) WebPDemuxGetI(
+    const WebPDemuxer* dmux, WebPFormatFeature feature);
+
+//------------------------------------------------------------------------------
+// Frame iteration.
+
+struct WebPIterator {
+  int frame_num;
+  int num_frames;          // equivalent to WEBP_FF_FRAME_COUNT.
+  int fragment_num;
+  int num_fragments;
+  int x_offset, y_offset;  // offset relative to the canvas.
+  int width, height;       // dimensions of this frame or fragment.
+  int duration;            // display duration in milliseconds.
+  WebPMuxAnimDispose dispose_method;  // dispose method for the frame.
+  int complete;   // true if 'fragment' contains a full frame. partial images
+                  // may still be decoded with the WebP incremental decoder.
+  WebPData fragment;  // The frame or fragment given by 'frame_num' and
+                      // 'fragment_num'.
+  int has_alpha;      // True if the frame or fragment contains transparency.
+  WebPMuxAnimBlend blend_method;  // Blend operation for the frame.
+
+  uint32_t pad[2];         // padding for later use.
+  void* private_;          // for internal use only.
+};
+
+// Retrieves frame 'frame_number' from 'dmux'.
+// 'iter->fragment' points to the first fragment on return from this function.
+// Individual fragments may be extracted using WebPDemuxSelectFragment().
+// Setting 'frame_number' equal to 0 will return the last frame of the image.
+// Returns false if 'dmux' is NULL or frame 'frame_number' is not present.
+// Call WebPDemuxReleaseIterator() when use of the iterator is complete.
+// NOTE: 'dmux' must persist for the lifetime of 'iter'.
+WEBP_EXTERN(int) WebPDemuxGetFrame(
+    const WebPDemuxer* dmux, int frame_number, WebPIterator* iter);
+
+// Sets 'iter->fragment' to point to the next ('iter->frame_num' + 1) or
+// previous ('iter->frame_num' - 1) frame. These functions do not loop.
+// Returns true on success, false otherwise.
+WEBP_EXTERN(int) WebPDemuxNextFrame(WebPIterator* iter);
+WEBP_EXTERN(int) WebPDemuxPrevFrame(WebPIterator* iter);
+
+// Sets 'iter->fragment' to reflect fragment number 'fragment_num'.
+// Returns true if fragment 'fragment_num' is present, false otherwise.
+WEBP_EXTERN(int) WebPDemuxSelectFragment(WebPIterator* iter, int fragment_num);
+
+// Releases any memory associated with 'iter'.
+// Must be called before any subsequent calls to WebPDemuxGetChunk() on the same
+// iter. Also, must be called before destroying the associated WebPDemuxer with
+// WebPDemuxDelete().
+WEBP_EXTERN(void) WebPDemuxReleaseIterator(WebPIterator* iter);
+
+//------------------------------------------------------------------------------
+// Chunk iteration.
+
+struct WebPChunkIterator {
+  // The current and total number of chunks with the fourcc given to
+  // WebPDemuxGetChunk().
+  int chunk_num;
+  int num_chunks;
+  WebPData chunk;    // The payload of the chunk.
+
+  uint32_t pad[6];   // padding for later use
+  void* private_;
+};
+
+// Retrieves the 'chunk_number' instance of the chunk with id 'fourcc' from
+// 'dmux'.
+// 'fourcc' is a character array containing the fourcc of the chunk to return,
+// e.g., "ICCP", "XMP ", "EXIF", etc.
+// Setting 'chunk_number' equal to 0 will return the last chunk in a set.
+// Returns true if the chunk is found, false otherwise. Image related chunk
+// payloads are accessed through WebPDemuxGetFrame() and related functions.
+// Call WebPDemuxReleaseChunkIterator() when use of the iterator is complete.
+// NOTE: 'dmux' must persist for the lifetime of the iterator.
+WEBP_EXTERN(int) WebPDemuxGetChunk(const WebPDemuxer* dmux,
+                                   const char fourcc[4], int chunk_number,
+                                   WebPChunkIterator* iter);
+
+// Sets 'iter->chunk' to point to the next ('iter->chunk_num' + 1) or previous
+// ('iter->chunk_num' - 1) chunk. These functions do not loop.
+// Returns true on success, false otherwise.
+WEBP_EXTERN(int) WebPDemuxNextChunk(WebPChunkIterator* iter);
+WEBP_EXTERN(int) WebPDemuxPrevChunk(WebPChunkIterator* iter);
+
+// Releases any memory associated with 'iter'.
+// Must be called before destroying the associated WebPDemuxer with
+// WebPDemuxDelete().
+WEBP_EXTERN(void) WebPDemuxReleaseChunkIterator(WebPChunkIterator* iter);
+
+//------------------------------------------------------------------------------
+
+#ifdef __cplusplus
+}    // extern "C"
+#endif
+
+#endif  /* WEBP_WEBP_DEMUX_H_ */
diff --git a/Source/LibWebP/src/webp/encode.h b/Source/LibWebP/src/webp/encode.h
new file mode 100644
index 0000000..29c66a8
--- /dev/null
+++ b/Source/LibWebP/src/webp/encode.h
@@ -0,0 +1,515 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+//   WebP encoder: main interface
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#ifndef WEBP_WEBP_ENCODE_H_
+#define WEBP_WEBP_ENCODE_H_
+
+#include "./types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define WEBP_ENCODER_ABI_VERSION 0x0206    // MAJOR(8b) + MINOR(8b)
+
+// Note: forward declaring enumerations is not allowed in (strict) C and C++,
+// the types are left here for reference.
+// typedef enum WebPImageHint WebPImageHint;
+// typedef enum WebPEncCSP WebPEncCSP;
+// typedef enum WebPPreset WebPPreset;
+// typedef enum WebPEncodingError WebPEncodingError;
+typedef struct WebPConfig WebPConfig;
+typedef struct WebPPicture WebPPicture;   // main structure for I/O
+typedef struct WebPAuxStats WebPAuxStats;
+typedef struct WebPMemoryWriter WebPMemoryWriter;
+
+// Return the encoder's version number, packed in hexadecimal using 8bits for
+// each of major/minor/revision. E.g: v2.5.7 is 0x020507.
+WEBP_EXTERN(int) WebPGetEncoderVersion(void);
+
+//------------------------------------------------------------------------------
+// One-stop-shop call! No questions asked:
+
+// Returns the size of the compressed data (pointed to by *output), or 0 if
+// an error occurred. The compressed data must be released by the caller
+// using the call 'free(*output)'.
+// These functions compress using the lossy format, and the quality_factor
+// can go from 0 (smaller output, lower quality) to 100 (best quality,
+// larger output).
+WEBP_EXTERN(size_t) WebPEncodeRGB(const uint8_t* rgb,
+                                  int width, int height, int stride,
+                                  float quality_factor, uint8_t** output);
+WEBP_EXTERN(size_t) WebPEncodeBGR(const uint8_t* bgr,
+                                  int width, int height, int stride,
+                                  float quality_factor, uint8_t** output);
+WEBP_EXTERN(size_t) WebPEncodeRGBA(const uint8_t* rgba,
+                                   int width, int height, int stride,
+                                   float quality_factor, uint8_t** output);
+WEBP_EXTERN(size_t) WebPEncodeBGRA(const uint8_t* bgra,
+                                   int width, int height, int stride,
+                                   float quality_factor, uint8_t** output);
+
+// These functions are the equivalent of the above, but compressing in a
+// lossless manner. Files are usually larger than lossy format, but will
+// not suffer any compression loss.
+WEBP_EXTERN(size_t) WebPEncodeLosslessRGB(const uint8_t* rgb,
+                                          int width, int height, int stride,
+                                          uint8_t** output);
+WEBP_EXTERN(size_t) WebPEncodeLosslessBGR(const uint8_t* bgr,
+                                          int width, int height, int stride,
+                                          uint8_t** output);
+WEBP_EXTERN(size_t) WebPEncodeLosslessRGBA(const uint8_t* rgba,
+                                           int width, int height, int stride,
+                                           uint8_t** output);
+WEBP_EXTERN(size_t) WebPEncodeLosslessBGRA(const uint8_t* bgra,
+                                           int width, int height, int stride,
+                                           uint8_t** output);
+
+//------------------------------------------------------------------------------
+// Coding parameters
+
+// Image characteristics hint for the underlying encoder.
+typedef enum WebPImageHint {
+  WEBP_HINT_DEFAULT = 0,  // default preset.
+  WEBP_HINT_PICTURE,      // digital picture, like portrait, inner shot
+  WEBP_HINT_PHOTO,        // outdoor photograph, with natural lighting
+  WEBP_HINT_GRAPH,        // Discrete tone image (graph, map-tile etc).
+  WEBP_HINT_LAST
+} WebPImageHint;
+
+// Compression parameters.
+struct WebPConfig {
+  int lossless;           // Lossless encoding (0=lossy(default), 1=lossless).
+  float quality;          // between 0 (smallest file) and 100 (biggest)
+  int method;             // quality/speed trade-off (0=fast, 6=slower-better)
+
+  WebPImageHint image_hint;  // Hint for image type (lossless only for now).
+
+  // Parameters related to lossy compression only:
+  int target_size;        // if non-zero, set the desired target size in bytes.
+                          // Takes precedence over the 'compression' parameter.
+  float target_PSNR;      // if non-zero, specifies the minimal distortion to
+                          // try to achieve. Takes precedence over target_size.
+  int segments;           // maximum number of segments to use, in [1..4]
+  int sns_strength;       // Spatial Noise Shaping. 0=off, 100=maximum.
+  int filter_strength;    // range: [0 = off .. 100 = strongest]
+  int filter_sharpness;   // range: [0 = off .. 7 = least sharp]
+  int filter_type;        // filtering type: 0 = simple, 1 = strong (only used
+                          // if filter_strength > 0 or autofilter > 0)
+  int autofilter;         // Auto adjust filter's strength [0 = off, 1 = on]
+  int alpha_compression;  // Algorithm for encoding the alpha plane (0 = none,
+                          // 1 = compressed with WebP lossless). Default is 1.
+  int alpha_filtering;    // Predictive filtering method for alpha plane.
+                          //  0: none, 1: fast, 2: best. Default if 1.
+  int alpha_quality;      // Between 0 (smallest size) and 100 (lossless).
+                          // Default is 100.
+  int pass;               // number of entropy-analysis passes (in [1..10]).
+
+  int show_compressed;    // if true, export the compressed picture back.
+                          // In-loop filtering is not applied.
+  int preprocessing;      // preprocessing filter:
+                          // 0=none, 1=segment-smooth, 2=pseudo-random dithering
+  int partitions;         // log2(number of token partitions) in [0..3]. Default
+                          // is set to 0 for easier progressive decoding.
+  int partition_limit;    // quality degradation allowed to fit the 512k limit
+                          // on prediction modes coding (0: no degradation,
+                          // 100: maximum possible degradation).
+  int emulate_jpeg_size;  // If true, compression parameters will be remapped
+                          // to better match the expected output size from
+                          // JPEG compression. Generally, the output size will
+                          // be similar but the degradation will be lower.
+  int thread_level;       // If non-zero, try and use multi-threaded encoding.
+  int low_memory;         // If set, reduce memory usage (but increase CPU use).
+
+  int near_lossless;      // Near lossless encoding [0 = off(default) .. 100].
+                          // This feature is experimental.
+
+  uint32_t pad[4];        // padding for later use
+};
+
+// Enumerate some predefined settings for WebPConfig, depending on the type
+// of source picture. These presets are used when calling WebPConfigPreset().
+typedef enum WebPPreset {
+  WEBP_PRESET_DEFAULT = 0,  // default preset.
+  WEBP_PRESET_PICTURE,      // digital picture, like portrait, inner shot
+  WEBP_PRESET_PHOTO,        // outdoor photograph, with natural lighting
+  WEBP_PRESET_DRAWING,      // hand or line drawing, with high-contrast details
+  WEBP_PRESET_ICON,         // small-sized colorful images
+  WEBP_PRESET_TEXT          // text-like
+} WebPPreset;
+
+// Internal, version-checked, entry point
+WEBP_EXTERN(int) WebPConfigInitInternal(WebPConfig*, WebPPreset, float, int);
+
+// Should always be called, to initialize a fresh WebPConfig structure before
+// modification. Returns false in case of version mismatch. WebPConfigInit()
+// must have succeeded before using the 'config' object.
+// Note that the default values are lossless=0 and quality=75.
+static WEBP_INLINE int WebPConfigInit(WebPConfig* config) {
+  return WebPConfigInitInternal(config, WEBP_PRESET_DEFAULT, 75.f,
+                                WEBP_ENCODER_ABI_VERSION);
+}
+
+// This function will initialize the configuration according to a predefined
+// set of parameters (referred to by 'preset') and a given quality factor.
+// This function can be called as a replacement to WebPConfigInit(). Will
+// return false in case of error.
+static WEBP_INLINE int WebPConfigPreset(WebPConfig* config,
+                                        WebPPreset preset, float quality) {
+  return WebPConfigInitInternal(config, preset, quality,
+                                WEBP_ENCODER_ABI_VERSION);
+}
+
+// Activate the lossless compression mode with the desired efficiency level
+// between 0 (fastest, lowest compression) and 9 (slower, best compression).
+// A good default level is '6', providing a fair tradeoff between compression
+// speed and final compressed size.
+// This function will overwrite several fields from config: 'method', 'quality'
+// and 'lossless'. Returns false in case of parameter error.
+WEBP_EXTERN(int) WebPConfigLosslessPreset(WebPConfig* config, int level);
+
+// Returns true if 'config' is non-NULL and all configuration parameters are
+// within their valid ranges.
+WEBP_EXTERN(int) WebPValidateConfig(const WebPConfig* config);
+
+//------------------------------------------------------------------------------
+// Input / Output
+// Structure for storing auxiliary statistics (mostly for lossy encoding).
+
+struct WebPAuxStats {
+  int coded_size;         // final size
+
+  float PSNR[5];          // peak-signal-to-noise ratio for Y/U/V/All/Alpha
+  int block_count[3];     // number of intra4/intra16/skipped macroblocks
+  int header_bytes[2];    // approximate number of bytes spent for header
+                          // and mode-partition #0
+  int residual_bytes[3][4];  // approximate number of bytes spent for
+                             // DC/AC/uv coefficients for each (0..3) segments.
+  int segment_size[4];    // number of macroblocks in each segments
+  int segment_quant[4];   // quantizer values for each segments
+  int segment_level[4];   // filtering strength for each segments [0..63]
+
+  int alpha_data_size;    // size of the transparency data
+  int layer_data_size;    // size of the enhancement layer data
+
+  // lossless encoder statistics
+  uint32_t lossless_features;  // bit0:predictor bit1:cross-color transform
+                               // bit2:subtract-green bit3:color indexing
+  int histogram_bits;          // number of precision bits of histogram
+  int transform_bits;          // precision bits for transform
+  int cache_bits;              // number of bits for color cache lookup
+  int palette_size;            // number of color in palette, if used
+  int lossless_size;           // final lossless size
+  int lossless_hdr_size;       // lossless header (transform, huffman etc) size
+  int lossless_data_size;      // lossless image data size
+
+  uint32_t pad[2];        // padding for later use
+};
+
+// Signature for output function. Should return true if writing was successful.
+// data/data_size is the segment of data to write, and 'picture' is for
+// reference (and so one can make use of picture->custom_ptr).
+typedef int (*WebPWriterFunction)(const uint8_t* data, size_t data_size,
+                                  const WebPPicture* picture);
+
+// WebPMemoryWrite: a special WebPWriterFunction that writes to memory using
+// the following WebPMemoryWriter object (to be set as a custom_ptr).
+struct WebPMemoryWriter {
+  uint8_t* mem;       // final buffer (of size 'max_size', larger than 'size').
+  size_t   size;      // final size
+  size_t   max_size;  // total capacity
+  uint32_t pad[1];    // padding for later use
+};
+
+// The following must be called first before any use.
+WEBP_EXTERN(void) WebPMemoryWriterInit(WebPMemoryWriter* writer);
+
+// The following must be called to deallocate writer->mem memory. The 'writer'
+// object itself is not deallocated.
+WEBP_EXTERN(void) WebPMemoryWriterClear(WebPMemoryWriter* writer);
+// The custom writer to be used with WebPMemoryWriter as custom_ptr. Upon
+// completion, writer.mem and writer.size will hold the coded data.
+// writer.mem must be freed by calling WebPMemoryWriterClear.
+WEBP_EXTERN(int) WebPMemoryWrite(const uint8_t* data, size_t data_size,
+                                 const WebPPicture* picture);
+
+// Progress hook, called from time to time to report progress. It can return
+// false to request an abort of the encoding process, or true otherwise if
+// everything is OK.
+typedef int (*WebPProgressHook)(int percent, const WebPPicture* picture);
+
+// Color spaces.
+typedef enum WebPEncCSP {
+  // chroma sampling
+  WEBP_YUV420  = 0,        // 4:2:0
+  WEBP_YUV420A = 4,        // alpha channel variant
+  WEBP_CSP_UV_MASK = 3,    // bit-mask to get the UV sampling factors
+  WEBP_CSP_ALPHA_BIT = 4   // bit that is set if alpha is present
+} WebPEncCSP;
+
+// Encoding error conditions.
+typedef enum WebPEncodingError {
+  VP8_ENC_OK = 0,
+  VP8_ENC_ERROR_OUT_OF_MEMORY,            // memory error allocating objects
+  VP8_ENC_ERROR_BITSTREAM_OUT_OF_MEMORY,  // memory error while flushing bits
+  VP8_ENC_ERROR_NULL_PARAMETER,           // a pointer parameter is NULL
+  VP8_ENC_ERROR_INVALID_CONFIGURATION,    // configuration is invalid
+  VP8_ENC_ERROR_BAD_DIMENSION,            // picture has invalid width/height
+  VP8_ENC_ERROR_PARTITION0_OVERFLOW,      // partition is bigger than 512k
+  VP8_ENC_ERROR_PARTITION_OVERFLOW,       // partition is bigger than 16M
+  VP8_ENC_ERROR_BAD_WRITE,                // error while flushing bytes
+  VP8_ENC_ERROR_FILE_TOO_BIG,             // file is bigger than 4G
+  VP8_ENC_ERROR_USER_ABORT,               // abort request by user
+  VP8_ENC_ERROR_LAST                      // list terminator. always last.
+} WebPEncodingError;
+
+// maximum width/height allowed (inclusive), in pixels
+#define WEBP_MAX_DIMENSION 16383
+
+// Main exchange structure (input samples, output bytes, statistics)
+struct WebPPicture {
+  //   INPUT
+  //////////////
+  // Main flag for encoder selecting between ARGB or YUV input.
+  // It is recommended to use ARGB input (*argb, argb_stride) for lossless
+  // compression, and YUV input (*y, *u, *v, etc.) for lossy compression
+  // since these are the respective native colorspace for these formats.
+  int use_argb;
+
+  // YUV input (mostly used for input to lossy compression)
+  WebPEncCSP colorspace;     // colorspace: should be YUV420 for now (=Y'CbCr).
+  int width, height;         // dimensions (less or equal to WEBP_MAX_DIMENSION)
+  uint8_t *y, *u, *v;        // pointers to luma/chroma planes.
+  int y_stride, uv_stride;   // luma/chroma strides.
+  uint8_t* a;                // pointer to the alpha plane
+  int a_stride;              // stride of the alpha plane
+  uint32_t pad1[2];          // padding for later use
+
+  // ARGB input (mostly used for input to lossless compression)
+  uint32_t* argb;            // Pointer to argb (32 bit) plane.
+  int argb_stride;           // This is stride in pixels units, not bytes.
+  uint32_t pad2[3];          // padding for later use
+
+  //   OUTPUT
+  ///////////////
+  // Byte-emission hook, to store compressed bytes as they are ready.
+  WebPWriterFunction writer;  // can be NULL
+  void* custom_ptr;           // can be used by the writer.
+
+  // map for extra information (only for lossy compression mode)
+  int extra_info_type;    // 1: intra type, 2: segment, 3: quant
+                          // 4: intra-16 prediction mode,
+                          // 5: chroma prediction mode,
+                          // 6: bit cost, 7: distortion
+  uint8_t* extra_info;    // if not NULL, points to an array of size
+                          // ((width + 15) / 16) * ((height + 15) / 16) that
+                          // will be filled with a macroblock map, depending
+                          // on extra_info_type.
+
+  //   STATS AND REPORTS
+  ///////////////////////////
+  // Pointer to side statistics (updated only if not NULL)
+  WebPAuxStats* stats;
+
+  // Error code for the latest error encountered during encoding
+  WebPEncodingError error_code;
+
+  // If not NULL, report progress during encoding.
+  WebPProgressHook progress_hook;
+
+  void* user_data;        // this field is free to be set to any value and
+                          // used during callbacks (like progress-report e.g.).
+
+  uint32_t pad3[3];       // padding for later use
+
+  // Unused for now
+  uint8_t *pad4, *pad5;
+  uint32_t pad6[8];       // padding for later use
+
+  // PRIVATE FIELDS
+  ////////////////////
+  void* memory_;          // row chunk of memory for yuva planes
+  void* memory_argb_;     // and for argb too.
+  void* pad7[2];          // padding for later use
+};
+
+// Internal, version-checked, entry point
+WEBP_EXTERN(int) WebPPictureInitInternal(WebPPicture*, int);
+
+// Should always be called, to initialize the structure. Returns false in case
+// of version mismatch. WebPPictureInit() must have succeeded before using the
+// 'picture' object.
+// Note that, by default, use_argb is false and colorspace is WEBP_YUV420.
+static WEBP_INLINE int WebPPictureInit(WebPPicture* picture) {
+  return WebPPictureInitInternal(picture, WEBP_ENCODER_ABI_VERSION);
+}
+
+//------------------------------------------------------------------------------
+// WebPPicture utils
+
+// Convenience allocation / deallocation based on picture->width/height:
+// Allocate y/u/v buffers as per colorspace/width/height specification.
+// Note! This function will free the previous buffer if needed.
+// Returns false in case of memory error.
+WEBP_EXTERN(int) WebPPictureAlloc(WebPPicture* picture);
+
+// Release the memory allocated by WebPPictureAlloc() or WebPPictureImport*().
+// Note that this function does _not_ free the memory used by the 'picture'
+// object itself.
+// Besides memory (which is reclaimed) all other fields of 'picture' are
+// preserved.
+WEBP_EXTERN(void) WebPPictureFree(WebPPicture* picture);
+
+// Copy the pixels of *src into *dst, using WebPPictureAlloc. Upon return, *dst
+// will fully own the copied pixels (this is not a view). The 'dst' picture need
+// not be initialized as its content is overwritten.
+// Returns false in case of memory allocation error.
+WEBP_EXTERN(int) WebPPictureCopy(const WebPPicture* src, WebPPicture* dst);
+
+// Compute PSNR, SSIM or LSIM distortion metric between two pictures.
+// Result is in dB, stores in result[] in the Y/U/V/Alpha/All order.
+// Returns false in case of error (src and ref don't have same dimension, ...)
+// Warning: this function is rather CPU-intensive.
+WEBP_EXTERN(int) WebPPictureDistortion(
+    const WebPPicture* src, const WebPPicture* ref,
+    int metric_type,           // 0 = PSNR, 1 = SSIM, 2 = LSIM
+    float result[5]);
+
+// self-crops a picture to the rectangle defined by top/left/width/height.
+// Returns false in case of memory allocation error, or if the rectangle is
+// outside of the source picture.
+// The rectangle for the view is defined by the top-left corner pixel
+// coordinates (left, top) as well as its width and height. This rectangle
+// must be fully be comprised inside the 'src' source picture. If the source
+// picture uses the YUV420 colorspace, the top and left coordinates will be
+// snapped to even values.
+WEBP_EXTERN(int) WebPPictureCrop(WebPPicture* picture,
+                                 int left, int top, int width, int height);
+
+// Extracts a view from 'src' picture into 'dst'. The rectangle for the view
+// is defined by the top-left corner pixel coordinates (left, top) as well
+// as its width and height. This rectangle must be fully be comprised inside
+// the 'src' source picture. If the source picture uses the YUV420 colorspace,
+// the top and left coordinates will be snapped to even values.
+// Picture 'src' must out-live 'dst' picture. Self-extraction of view is allowed
+// ('src' equal to 'dst') as a mean of fast-cropping (but note that doing so,
+// the original dimension will be lost). Picture 'dst' need not be initialized
+// with WebPPictureInit() if it is different from 'src', since its content will
+// be overwritten.
+// Returns false in case of memory allocation error or invalid parameters.
+WEBP_EXTERN(int) WebPPictureView(const WebPPicture* src,
+                                 int left, int top, int width, int height,
+                                 WebPPicture* dst);
+
+// Returns true if the 'picture' is actually a view and therefore does
+// not own the memory for pixels.
+WEBP_EXTERN(int) WebPPictureIsView(const WebPPicture* picture);
+
+// Rescale a picture to new dimension width x height.
+// If either 'width' or 'height' (but not both) is 0 the corresponding
+// dimension will be calculated preserving the aspect ratio.
+// No gamma correction is applied.
+// Returns false in case of error (invalid parameter or insufficient memory).
+WEBP_EXTERN(int) WebPPictureRescale(WebPPicture* pic, int width, int height);
+
+// Colorspace conversion function to import RGB samples.
+// Previous buffer will be free'd, if any.
+// *rgb buffer should have a size of at least height * rgb_stride.
+// Returns false in case of memory error.
+WEBP_EXTERN(int) WebPPictureImportRGB(
+    WebPPicture* picture, const uint8_t* rgb, int rgb_stride);
+// Same, but for RGBA buffer.
+WEBP_EXTERN(int) WebPPictureImportRGBA(
+    WebPPicture* picture, const uint8_t* rgba, int rgba_stride);
+// Same, but for RGBA buffer. Imports the RGB direct from the 32-bit format
+// input buffer ignoring the alpha channel. Avoids needing to copy the data
+// to a temporary 24-bit RGB buffer to import the RGB only.
+WEBP_EXTERN(int) WebPPictureImportRGBX(
+    WebPPicture* picture, const uint8_t* rgbx, int rgbx_stride);
+
+// Variants of the above, but taking BGR(A|X) input.
+WEBP_EXTERN(int) WebPPictureImportBGR(
+    WebPPicture* picture, const uint8_t* bgr, int bgr_stride);
+WEBP_EXTERN(int) WebPPictureImportBGRA(
+    WebPPicture* picture, const uint8_t* bgra, int bgra_stride);
+WEBP_EXTERN(int) WebPPictureImportBGRX(
+    WebPPicture* picture, const uint8_t* bgrx, int bgrx_stride);
+
+// Converts picture->argb data to the YUV420A format. The 'colorspace'
+// parameter is deprecated and should be equal to WEBP_YUV420.
+// Upon return, picture->use_argb is set to false. The presence of real
+// non-opaque transparent values is detected, and 'colorspace' will be
+// adjusted accordingly. Note that this method is lossy.
+// Returns false in case of error.
+WEBP_EXTERN(int) WebPPictureARGBToYUVA(WebPPicture* picture,
+                                       WebPEncCSP /*colorspace = WEBP_YUV420*/);
+
+// Same as WebPPictureARGBToYUVA(), but the conversion is done using
+// pseudo-random dithering with a strength 'dithering' between
+// 0.0 (no dithering) and 1.0 (maximum dithering). This is useful
+// for photographic picture.
+WEBP_EXTERN(int) WebPPictureARGBToYUVADithered(
+    WebPPicture* picture, WebPEncCSP colorspace, float dithering);
+
+// Performs 'smart' RGBA->YUVA420 downsampling and colorspace conversion.
+// Downsampling is handled with extra care in case of color clipping. This
+// method is roughly 2x slower than WebPPictureARGBToYUVA() but produces better
+// YUV representation.
+// Returns false in case of error.
+WEBP_EXTERN(int) WebPPictureSmartARGBToYUVA(WebPPicture* picture);
+
+// Converts picture->yuv to picture->argb and sets picture->use_argb to true.
+// The input format must be YUV_420 or YUV_420A.
+// Note that the use of this method is discouraged if one has access to the
+// raw ARGB samples, since using YUV420 is comparatively lossy. Also, the
+// conversion from YUV420 to ARGB incurs a small loss too.
+// Returns false in case of error.
+WEBP_EXTERN(int) WebPPictureYUVAToARGB(WebPPicture* picture);
+
+// Helper function: given a width x height plane of RGBA or YUV(A) samples
+// clean-up the YUV or RGB samples under fully transparent area, to help
+// compressibility (no guarantee, though).
+WEBP_EXTERN(void) WebPCleanupTransparentArea(WebPPicture* picture);
+
+// Scan the picture 'picture' for the presence of non fully opaque alpha values.
+// Returns true in such case. Otherwise returns false (indicating that the
+// alpha plane can be ignored altogether e.g.).
+WEBP_EXTERN(int) WebPPictureHasTransparency(const WebPPicture* picture);
+
+// Remove the transparency information (if present) by blending the color with
+// the background color 'background_rgb' (specified as 24bit RGB triplet).
+// After this call, all alpha values are reset to 0xff.
+WEBP_EXTERN(void) WebPBlendAlpha(WebPPicture* pic, uint32_t background_rgb);
+
+//------------------------------------------------------------------------------
+// Main call
+
+// Main encoding call, after config and picture have been initialized.
+// 'picture' must be less than 16384x16384 in dimension (cf WEBP_MAX_DIMENSION),
+// and the 'config' object must be a valid one.
+// Returns false in case of error, true otherwise.
+// In case of error, picture->error_code is updated accordingly.
+// 'picture' can hold the source samples in both YUV(A) or ARGB input, depending
+// on the value of 'picture->use_argb'. It is highly recommended to use
+// the former for lossy encoding, and the latter for lossless encoding
+// (when config.lossless is true). Automatic conversion from one format to
+// another is provided but they both incur some loss.
+WEBP_EXTERN(int) WebPEncode(const WebPConfig* config, WebPPicture* picture);
+
+//------------------------------------------------------------------------------
+
+#ifdef __cplusplus
+}    // extern "C"
+#endif
+
+#endif  /* WEBP_WEBP_ENCODE_H_ */
diff --git a/Source/LibWebP/src/webp/format_constants.h b/Source/LibWebP/src/webp/format_constants.h
new file mode 100644
index 0000000..3c09b79
--- /dev/null
+++ b/Source/LibWebP/src/webp/format_constants.h
@@ -0,0 +1,88 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+//  Internal header for constants related to WebP file format.
+//
+// Author: Urvang (urvang at google.com)
+
+#ifndef WEBP_WEBP_FORMAT_CONSTANTS_H_
+#define WEBP_WEBP_FORMAT_CONSTANTS_H_
+
+// Create fourcc of the chunk from the chunk tag characters.
+#define MKFOURCC(a, b, c, d) ((uint32_t)(a) | (b) << 8 | (c) << 16 | (d) << 24)
+
+// VP8 related constants.
+#define VP8_SIGNATURE 0x9d012a              // Signature in VP8 data.
+#define VP8_MAX_PARTITION0_SIZE (1 << 19)   // max size of mode partition
+#define VP8_MAX_PARTITION_SIZE  (1 << 24)   // max size for token partition
+#define VP8_FRAME_HEADER_SIZE 10  // Size of the frame header within VP8 data.
+
+// VP8L related constants.
+#define VP8L_SIGNATURE_SIZE          1      // VP8L signature size.
+#define VP8L_MAGIC_BYTE              0x2f   // VP8L signature byte.
+#define VP8L_IMAGE_SIZE_BITS         14     // Number of bits used to store
+                                            // width and height.
+#define VP8L_VERSION_BITS            3      // 3 bits reserved for version.
+#define VP8L_VERSION                 0      // version 0
+#define VP8L_FRAME_HEADER_SIZE       5      // Size of the VP8L frame header.
+
+#define MAX_PALETTE_SIZE             256
+#define MAX_CACHE_BITS               11
+#define HUFFMAN_CODES_PER_META_CODE  5
+#define ARGB_BLACK                   0xff000000
+
+#define DEFAULT_CODE_LENGTH          8
+#define MAX_ALLOWED_CODE_LENGTH      15
+
+#define NUM_LITERAL_CODES            256
+#define NUM_LENGTH_CODES             24
+#define NUM_DISTANCE_CODES           40
+#define CODE_LENGTH_CODES            19
+
+#define MIN_HUFFMAN_BITS             2  // min number of Huffman bits
+#define MAX_HUFFMAN_BITS             9  // max number of Huffman bits
+
+#define TRANSFORM_PRESENT            1  // The bit to be written when next data
+                                        // to be read is a transform.
+#define NUM_TRANSFORMS               4  // Maximum number of allowed transform
+                                        // in a bitstream.
+typedef enum {
+  PREDICTOR_TRANSFORM      = 0,
+  CROSS_COLOR_TRANSFORM    = 1,
+  SUBTRACT_GREEN           = 2,
+  COLOR_INDEXING_TRANSFORM = 3
+} VP8LImageTransformType;
+
+// Alpha related constants.
+#define ALPHA_HEADER_LEN            1
+#define ALPHA_NO_COMPRESSION        0
+#define ALPHA_LOSSLESS_COMPRESSION  1
+#define ALPHA_PREPROCESSED_LEVELS   1
+
+// Mux related constants.
+#define TAG_SIZE           4     // Size of a chunk tag (e.g. "VP8L").
+#define CHUNK_SIZE_BYTES   4     // Size needed to store chunk's size.
+#define CHUNK_HEADER_SIZE  8     // Size of a chunk header.
+#define RIFF_HEADER_SIZE   12    // Size of the RIFF header ("RIFFnnnnWEBP").
+#define ANMF_CHUNK_SIZE    16    // Size of an ANMF chunk.
+#define ANIM_CHUNK_SIZE    6     // Size of an ANIM chunk.
+#define FRGM_CHUNK_SIZE    6     // Size of a FRGM chunk.
+#define VP8X_CHUNK_SIZE    10    // Size of a VP8X chunk.
+
+#define MAX_CANVAS_SIZE     (1 << 24)     // 24-bit max for VP8X width/height.
+#define MAX_IMAGE_AREA      (1ULL << 32)  // 32-bit max for width x height.
+#define MAX_LOOP_COUNT      (1 << 16)     // maximum value for loop-count
+#define MAX_DURATION        (1 << 24)     // maximum duration
+#define MAX_POSITION_OFFSET (1 << 24)     // maximum frame/fragment x/y offset
+
+// Maximum chunk payload is such that adding the header and padding won't
+// overflow a uint32_t.
+#define MAX_CHUNK_PAYLOAD (~0U - CHUNK_HEADER_SIZE - 1)
+
+#endif  /* WEBP_WEBP_FORMAT_CONSTANTS_H_ */
diff --git a/Source/LibWebP/src/webp/mux.h b/Source/LibWebP/src/webp/mux.h
new file mode 100644
index 0000000..6736593
--- /dev/null
+++ b/Source/LibWebP/src/webp/mux.h
@@ -0,0 +1,507 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+//  RIFF container manipulation and encoding for WebP images.
+//
+// Authors: Urvang (urvang at google.com)
+//          Vikas (vikasa at google.com)
+
+#ifndef WEBP_WEBP_MUX_H_
+#define WEBP_WEBP_MUX_H_
+
+#include "./encode.h"
+#include "./mux_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define WEBP_MUX_ABI_VERSION 0x0103        // MAJOR(8b) + MINOR(8b)
+
+//------------------------------------------------------------------------------
+// Mux API
+//
+// This API allows manipulation of WebP container images containing features
+// like color profile, metadata, animation and fragmented images.
+//
+// Code Example#1: Create a WebPMux object with image data, color profile and
+// XMP metadata.
+/*
+  int copy_data = 0;
+  WebPMux* mux = WebPMuxNew();
+  // ... (Prepare image data).
+  WebPMuxSetImage(mux, &image, copy_data);
+  // ... (Prepare ICCP color profile data).
+  WebPMuxSetChunk(mux, "ICCP", &icc_profile, copy_data);
+  // ... (Prepare XMP metadata).
+  WebPMuxSetChunk(mux, "XMP ", &xmp, copy_data);
+  // Get data from mux in WebP RIFF format.
+  WebPMuxAssemble(mux, &output_data);
+  WebPMuxDelete(mux);
+  // ... (Consume output_data; e.g. write output_data.bytes to file).
+  WebPDataClear(&output_data);
+*/
+
+// Code Example#2: Get image and color profile data from a WebP file.
+/*
+  int copy_data = 0;
+  // ... (Read data from file).
+  WebPMux* mux = WebPMuxCreate(&data, copy_data);
+  WebPMuxGetFrame(mux, 1, &image);
+  // ... (Consume image; e.g. call WebPDecode() to decode the data).
+  WebPMuxGetChunk(mux, "ICCP", &icc_profile);
+  // ... (Consume icc_data).
+  WebPMuxDelete(mux);
+  free(data);
+*/
+
+// Note: forward declaring enumerations is not allowed in (strict) C and C++,
+// the types are left here for reference.
+// typedef enum WebPMuxError WebPMuxError;
+// typedef enum WebPChunkId WebPChunkId;
+typedef struct WebPMux WebPMux;   // main opaque object.
+typedef struct WebPMuxFrameInfo WebPMuxFrameInfo;
+typedef struct WebPMuxAnimParams WebPMuxAnimParams;
+
+// Error codes
+typedef enum WebPMuxError {
+  WEBP_MUX_OK                 =  1,
+  WEBP_MUX_NOT_FOUND          =  0,
+  WEBP_MUX_INVALID_ARGUMENT   = -1,
+  WEBP_MUX_BAD_DATA           = -2,
+  WEBP_MUX_MEMORY_ERROR       = -3,
+  WEBP_MUX_NOT_ENOUGH_DATA    = -4
+} WebPMuxError;
+
+// IDs for different types of chunks.
+typedef enum WebPChunkId {
+  WEBP_CHUNK_VP8X,     // VP8X
+  WEBP_CHUNK_ICCP,     // ICCP
+  WEBP_CHUNK_ANIM,     // ANIM
+  WEBP_CHUNK_ANMF,     // ANMF
+  WEBP_CHUNK_FRGM,     // FRGM
+  WEBP_CHUNK_ALPHA,    // ALPH
+  WEBP_CHUNK_IMAGE,    // VP8/VP8L
+  WEBP_CHUNK_EXIF,     // EXIF
+  WEBP_CHUNK_XMP,      // XMP
+  WEBP_CHUNK_UNKNOWN,  // Other chunks.
+  WEBP_CHUNK_NIL
+} WebPChunkId;
+
+//------------------------------------------------------------------------------
+
+// Returns the version number of the mux library, packed in hexadecimal using
+// 8bits for each of major/minor/revision. E.g: v2.5.7 is 0x020507.
+WEBP_EXTERN(int) WebPGetMuxVersion(void);
+
+//------------------------------------------------------------------------------
+// Life of a Mux object
+
+// Internal, version-checked, entry point
+WEBP_EXTERN(WebPMux*) WebPNewInternal(int);
+
+// Creates an empty mux object.
+// Returns:
+//   A pointer to the newly created empty mux object.
+//   Or NULL in case of memory error.
+static WEBP_INLINE WebPMux* WebPMuxNew(void) {
+  return WebPNewInternal(WEBP_MUX_ABI_VERSION);
+}
+
+// Deletes the mux object.
+// Parameters:
+//   mux - (in/out) object to be deleted
+WEBP_EXTERN(void) WebPMuxDelete(WebPMux* mux);
+
+//------------------------------------------------------------------------------
+// Mux creation.
+
+// Internal, version-checked, entry point
+WEBP_EXTERN(WebPMux*) WebPMuxCreateInternal(const WebPData*, int, int);
+
+// Creates a mux object from raw data given in WebP RIFF format.
+// Parameters:
+//   bitstream - (in) the bitstream data in WebP RIFF format
+//   copy_data - (in) value 1 indicates given data WILL be copied to the mux
+//               object and value 0 indicates data will NOT be copied.
+// Returns:
+//   A pointer to the mux object created from given data - on success.
+//   NULL - In case of invalid data or memory error.
+static WEBP_INLINE WebPMux* WebPMuxCreate(const WebPData* bitstream,
+                                          int copy_data) {
+  return WebPMuxCreateInternal(bitstream, copy_data, WEBP_MUX_ABI_VERSION);
+}
+
+//------------------------------------------------------------------------------
+// Non-image chunks.
+
+// Note: Only non-image related chunks should be managed through chunk APIs.
+// (Image related chunks are: "ANMF", "FRGM", "VP8 ", "VP8L" and "ALPH").
+// To add, get and delete images, use WebPMuxSetImage(), WebPMuxPushFrame(),
+// WebPMuxGetFrame() and WebPMuxDeleteFrame().
+
+// Adds a chunk with id 'fourcc' and data 'chunk_data' in the mux object.
+// Any existing chunk(s) with the same id will be removed.
+// Parameters:
+//   mux - (in/out) object to which the chunk is to be added
+//   fourcc - (in) a character array containing the fourcc of the given chunk;
+//                 e.g., "ICCP", "XMP ", "EXIF" etc.
+//   chunk_data - (in) the chunk data to be added
+//   copy_data - (in) value 1 indicates given data WILL be copied to the mux
+//               object and value 0 indicates data will NOT be copied.
+// Returns:
+//   WEBP_MUX_INVALID_ARGUMENT - if mux, fourcc or chunk_data is NULL
+//                               or if fourcc corresponds to an image chunk.
+//   WEBP_MUX_MEMORY_ERROR - on memory allocation error.
+//   WEBP_MUX_OK - on success.
+WEBP_EXTERN(WebPMuxError) WebPMuxSetChunk(
+    WebPMux* mux, const char fourcc[4], const WebPData* chunk_data,
+    int copy_data);
+
+// Gets a reference to the data of the chunk with id 'fourcc' in the mux object.
+// The caller should NOT free the returned data.
+// Parameters:
+//   mux - (in) object from which the chunk data is to be fetched
+//   fourcc - (in) a character array containing the fourcc of the chunk;
+//                 e.g., "ICCP", "XMP ", "EXIF" etc.
+//   chunk_data - (out) returned chunk data
+// Returns:
+//   WEBP_MUX_INVALID_ARGUMENT - if mux, fourcc or chunk_data is NULL
+//                               or if fourcc corresponds to an image chunk.
+//   WEBP_MUX_NOT_FOUND - If mux does not contain a chunk with the given id.
+//   WEBP_MUX_OK - on success.
+WEBP_EXTERN(WebPMuxError) WebPMuxGetChunk(
+    const WebPMux* mux, const char fourcc[4], WebPData* chunk_data);
+
+// Deletes the chunk with the given 'fourcc' from the mux object.
+// Parameters:
+//   mux - (in/out) object from which the chunk is to be deleted
+//   fourcc - (in) a character array containing the fourcc of the chunk;
+//                 e.g., "ICCP", "XMP ", "EXIF" etc.
+// Returns:
+//   WEBP_MUX_INVALID_ARGUMENT - if mux or fourcc is NULL
+//                               or if fourcc corresponds to an image chunk.
+//   WEBP_MUX_NOT_FOUND - If mux does not contain a chunk with the given fourcc.
+//   WEBP_MUX_OK - on success.
+WEBP_EXTERN(WebPMuxError) WebPMuxDeleteChunk(
+    WebPMux* mux, const char fourcc[4]);
+
+//------------------------------------------------------------------------------
+// Images.
+
+// Encapsulates data about a single frame/fragment.
+struct WebPMuxFrameInfo {
+  WebPData    bitstream;  // image data: can be a raw VP8/VP8L bitstream
+                          // or a single-image WebP file.
+  int         x_offset;   // x-offset of the frame.
+  int         y_offset;   // y-offset of the frame.
+  int         duration;   // duration of the frame (in milliseconds).
+
+  WebPChunkId id;         // frame type: should be one of WEBP_CHUNK_ANMF,
+                          // WEBP_CHUNK_FRGM or WEBP_CHUNK_IMAGE
+  WebPMuxAnimDispose dispose_method;  // Disposal method for the frame.
+  WebPMuxAnimBlend   blend_method;    // Blend operation for the frame.
+  uint32_t    pad[1];     // padding for later use
+};
+
+// Sets the (non-animated and non-fragmented) image in the mux object.
+// Note: Any existing images (including frames/fragments) will be removed.
+// Parameters:
+//   mux - (in/out) object in which the image is to be set
+//   bitstream - (in) can be a raw VP8/VP8L bitstream or a single-image
+//               WebP file (non-animated and non-fragmented)
+//   copy_data - (in) value 1 indicates given data WILL be copied to the mux
+//               object and value 0 indicates data will NOT be copied.
+// Returns:
+//   WEBP_MUX_INVALID_ARGUMENT - if mux is NULL or bitstream is NULL.
+//   WEBP_MUX_MEMORY_ERROR - on memory allocation error.
+//   WEBP_MUX_OK - on success.
+WEBP_EXTERN(WebPMuxError) WebPMuxSetImage(
+    WebPMux* mux, const WebPData* bitstream, int copy_data);
+
+// Adds a frame at the end of the mux object.
+// Notes: (1) frame.id should be one of WEBP_CHUNK_ANMF or WEBP_CHUNK_FRGM
+//        (2) For setting a non-animated non-fragmented image, use
+//            WebPMuxSetImage() instead.
+//        (3) Type of frame being pushed must be same as the frames in mux.
+//        (4) As WebP only supports even offsets, any odd offset will be snapped
+//            to an even location using: offset &= ~1
+// Parameters:
+//   mux - (in/out) object to which the frame is to be added
+//   frame - (in) frame data.
+//   copy_data - (in) value 1 indicates given data WILL be copied to the mux
+//               object and value 0 indicates data will NOT be copied.
+// Returns:
+//   WEBP_MUX_INVALID_ARGUMENT - if mux or frame is NULL
+//                               or if content of 'frame' is invalid.
+//   WEBP_MUX_MEMORY_ERROR - on memory allocation error.
+//   WEBP_MUX_OK - on success.
+WEBP_EXTERN(WebPMuxError) WebPMuxPushFrame(
+    WebPMux* mux, const WebPMuxFrameInfo* frame, int copy_data);
+
+// Gets the nth frame from the mux object.
+// The content of 'frame->bitstream' is allocated using malloc(), and NOT
+// owned by the 'mux' object. It MUST be deallocated by the caller by calling
+// WebPDataClear().
+// nth=0 has a special meaning - last position.
+// Parameters:
+//   mux - (in) object from which the info is to be fetched
+//   nth - (in) index of the frame in the mux object
+//   frame - (out) data of the returned frame
+// Returns:
+//   WEBP_MUX_INVALID_ARGUMENT - if mux or frame is NULL.
+//   WEBP_MUX_NOT_FOUND - if there are less than nth frames in the mux object.
+//   WEBP_MUX_BAD_DATA - if nth frame chunk in mux is invalid.
+//   WEBP_MUX_MEMORY_ERROR - on memory allocation error.
+//   WEBP_MUX_OK - on success.
+WEBP_EXTERN(WebPMuxError) WebPMuxGetFrame(
+    const WebPMux* mux, uint32_t nth, WebPMuxFrameInfo* frame);
+
+// Deletes a frame from the mux object.
+// nth=0 has a special meaning - last position.
+// Parameters:
+//   mux - (in/out) object from which a frame is to be deleted
+//   nth - (in) The position from which the frame is to be deleted
+// Returns:
+//   WEBP_MUX_INVALID_ARGUMENT - if mux is NULL.
+//   WEBP_MUX_NOT_FOUND - If there are less than nth frames in the mux object
+//                        before deletion.
+//   WEBP_MUX_OK - on success.
+WEBP_EXTERN(WebPMuxError) WebPMuxDeleteFrame(WebPMux* mux, uint32_t nth);
+
+//------------------------------------------------------------------------------
+// Animation.
+
+// Animation parameters.
+struct WebPMuxAnimParams {
+  uint32_t bgcolor;  // Background color of the canvas stored (in MSB order) as:
+                     // Bits 00 to 07: Alpha.
+                     // Bits 08 to 15: Red.
+                     // Bits 16 to 23: Green.
+                     // Bits 24 to 31: Blue.
+  int loop_count;    // Number of times to repeat the animation [0 = infinite].
+};
+
+// Sets the animation parameters in the mux object. Any existing ANIM chunks
+// will be removed.
+// Parameters:
+//   mux - (in/out) object in which ANIM chunk is to be set/added
+//   params - (in) animation parameters.
+// Returns:
+//   WEBP_MUX_INVALID_ARGUMENT - if mux or params is NULL.
+//   WEBP_MUX_MEMORY_ERROR - on memory allocation error.
+//   WEBP_MUX_OK - on success.
+WEBP_EXTERN(WebPMuxError) WebPMuxSetAnimationParams(
+    WebPMux* mux, const WebPMuxAnimParams* params);
+
+// Gets the animation parameters from the mux object.
+// Parameters:
+//   mux - (in) object from which the animation parameters to be fetched
+//   params - (out) animation parameters extracted from the ANIM chunk
+// Returns:
+//   WEBP_MUX_INVALID_ARGUMENT - if mux or params is NULL.
+//   WEBP_MUX_NOT_FOUND - if ANIM chunk is not present in mux object.
+//   WEBP_MUX_OK - on success.
+WEBP_EXTERN(WebPMuxError) WebPMuxGetAnimationParams(
+    const WebPMux* mux, WebPMuxAnimParams* params);
+
+//------------------------------------------------------------------------------
+// Misc Utilities.
+
+// Sets the canvas size for the mux object. The width and height can be
+// specified explicitly or left as zero (0, 0).
+// * When width and height are specified explicitly, then this frame bound is
+//   enforced during subsequent calls to WebPMuxAssemble() and an error is
+//   reported if any animated frame does not completely fit within the canvas.
+// * When unspecified (0, 0), the constructed canvas will get the frame bounds
+//   from the bounding-box over all frames after calling WebPMuxAssemble().
+// Parameters:
+//   mux - (in) object to which the canvas size is to be set
+//   width - (in) canvas width
+//   height - (in) canvas height
+// Returns:
+//   WEBP_MUX_INVALID_ARGUMENT - if mux is NULL; or
+//                               width or height are invalid or out of bounds
+//   WEBP_MUX_OK - on success.
+WEBP_EXTERN(WebPMuxError) WebPMuxSetCanvasSize(WebPMux* mux,
+                                               int width, int height);
+
+// Gets the canvas size from the mux object.
+// Note: This method assumes that the VP8X chunk, if present, is up-to-date.
+// That is, the mux object hasn't been modified since the last call to
+// WebPMuxAssemble() or WebPMuxCreate().
+// Parameters:
+//   mux - (in) object from which the canvas size is to be fetched
+//   width - (out) canvas width
+//   height - (out) canvas height
+// Returns:
+//   WEBP_MUX_INVALID_ARGUMENT - if mux, width or height is NULL.
+//   WEBP_MUX_BAD_DATA - if VP8X/VP8/VP8L chunk or canvas size is invalid.
+//   WEBP_MUX_OK - on success.
+WEBP_EXTERN(WebPMuxError) WebPMuxGetCanvasSize(const WebPMux* mux,
+                                               int* width, int* height);
+
+// Gets the feature flags from the mux object.
+// Note: This method assumes that the VP8X chunk, if present, is up-to-date.
+// That is, the mux object hasn't been modified since the last call to
+// WebPMuxAssemble() or WebPMuxCreate().
+// Parameters:
+//   mux - (in) object from which the features are to be fetched
+//   flags - (out) the flags specifying which features are present in the
+//           mux object. This will be an OR of various flag values.
+//           Enum 'WebPFeatureFlags' can be used to test individual flag values.
+// Returns:
+//   WEBP_MUX_INVALID_ARGUMENT - if mux or flags is NULL.
+//   WEBP_MUX_BAD_DATA - if VP8X/VP8/VP8L chunk or canvas size is invalid.
+//   WEBP_MUX_OK - on success.
+WEBP_EXTERN(WebPMuxError) WebPMuxGetFeatures(const WebPMux* mux,
+                                             uint32_t* flags);
+
+// Gets number of chunks with the given 'id' in the mux object.
+// Parameters:
+//   mux - (in) object from which the info is to be fetched
+//   id - (in) chunk id specifying the type of chunk
+//   num_elements - (out) number of chunks with the given chunk id
+// Returns:
+//   WEBP_MUX_INVALID_ARGUMENT - if mux, or num_elements is NULL.
+//   WEBP_MUX_OK - on success.
+WEBP_EXTERN(WebPMuxError) WebPMuxNumChunks(const WebPMux* mux,
+                                           WebPChunkId id, int* num_elements);
+
+// Assembles all chunks in WebP RIFF format and returns in 'assembled_data'.
+// This function also validates the mux object.
+// Note: The content of 'assembled_data' will be ignored and overwritten.
+// Also, the content of 'assembled_data' is allocated using malloc(), and NOT
+// owned by the 'mux' object. It MUST be deallocated by the caller by calling
+// WebPDataClear(). It's always safe to call WebPDataClear() upon return,
+// even in case of error.
+// Parameters:
+//   mux - (in/out) object whose chunks are to be assembled
+//   assembled_data - (out) assembled WebP data
+// Returns:
+//   WEBP_MUX_BAD_DATA - if mux object is invalid.
+//   WEBP_MUX_INVALID_ARGUMENT - if mux or assembled_data is NULL.
+//   WEBP_MUX_MEMORY_ERROR - on memory allocation error.
+//   WEBP_MUX_OK - on success.
+WEBP_EXTERN(WebPMuxError) WebPMuxAssemble(WebPMux* mux,
+                                          WebPData* assembled_data);
+
+//------------------------------------------------------------------------------
+// WebPAnimEncoder API
+//
+// This API allows encoding (possibly) animated WebP images.
+//
+// Code Example:
+/*
+  WebPAnimEncoderOptions enc_options;
+  WebPAnimEncoderOptionsInit(&enc_options);
+  // Tune 'enc_options' as needed.
+  WebPAnimEncoder* enc = WebPAnimEncoderNew(width, height, &enc_options);
+  while(<there are more frames>) {
+    WebPConfig config;
+    WebPConfigInit(&config);
+    // Tune 'config' as needed.
+    WebPAnimEncoderAdd(enc, frame, duration, &config);
+  }
+  WebPAnimEncoderAssemble(enc, webp_data);
+  WebPAnimEncoderDelete(enc);
+  // Write the 'webp_data' to a file, or re-mux it further.
+*/
+
+typedef struct WebPAnimEncoder WebPAnimEncoder;  // Main opaque object.
+
+// Global options.
+typedef struct {
+  WebPMuxAnimParams anim_params;  // Animation parameters.
+  int minimize_size;    // If true, minimize the output size (slow). Implicitly
+                        // disables key-frame insertion.
+  int kmin;
+  int kmax;             // Minimum and maximum distance between consecutive key
+                        // frames in the output. The library may insert some key
+                        // frames as needed to satisfy this criteria.
+                        // Note that these conditions should hold: kmax > kmin
+                        // and kmin >= kmax / 2 + 1. Also, if kmin == 0, then
+                        // key-frame insertion is disabled; and if kmax == 0,
+                        // then all frames will be key-frames.
+  int allow_mixed;      // If true, use mixed compression mode; may choose
+                        // either lossy and lossless for each frame.
+
+  // TODO(urvang): Instead of printing errors to STDERR, we should have an error
+  // string attached to the encoder.
+  int verbose;          // If true, print encoding info.
+  uint32_t padding[4];  // Padding for later use.
+} WebPAnimEncoderOptions;
+
+// Internal, version-checked, entry point.
+WEBP_EXTERN(int) WebPAnimEncoderOptionsInitInternal(
+    WebPAnimEncoderOptions*, int);
+
+// Should always be called, to initialize a fresh WebPAnimEncoderOptions
+// structure before modification. Returns false in case of version mismatch.
+// WebPAnimEncoderOptionsInit() must have succeeded before using the 'options'
+// object.
+static WEBP_INLINE int WebPAnimEncoderOptionsInit(
+    WebPAnimEncoderOptions* enc_options) {
+  return WebPAnimEncoderOptionsInitInternal(enc_options, WEBP_MUX_ABI_VERSION);
+}
+
+// Internal, version-checked, entry point.
+WEBP_EXTERN(WebPAnimEncoder*) WebPAnimEncoderNewInternal(
+    int, int, const WebPAnimEncoderOptions*, int);
+
+// Creates and initializes a WebPAnimEncoder object.
+// Parameters:
+//   width/height - (in) canvas width and height of the animation.
+//   encoder_options - (in) encoding options; can be passed NULL to pick
+//                     reasonable defaults.
+// Returns:
+//   A pointer to the newly created WebPAnimEncoder object.
+//   Or NULL in case of memory error.
+static WEBP_INLINE WebPAnimEncoder* WebPAnimEncoderNew(
+    int width, int height, const WebPAnimEncoderOptions* enc_options) {
+  return WebPAnimEncoderNewInternal(width, height, enc_options,
+                                    WEBP_MUX_ABI_VERSION);
+}
+
+// Optimize the given frame for WebP, encode it and add it to the
+// WebPAnimEncoder object.
+// Parameters:
+//   enc - (in/out) object to which the frame is to be added.
+//   frame - (in/out) frame data in ARGB or YUVA format.
+//   duration - (in) frame duration
+//   config - (in) encoding options; can be passed NULL to pick
+//            reasonable defaults.
+// Returns:
+//   On error, returns false and frame->error_code is set appropriately.
+//   Otherwise, returns true.
+WEBP_EXTERN(int) WebPAnimEncoderAdd(
+    WebPAnimEncoder* enc, WebPPicture* frame, int duration,
+    const WebPConfig* config);
+
+// Assemble all frames added so far into a WebP bitstream.
+// Parameters:
+//   enc - (in/out) object from which the frames are to be assembled.
+//   webp_data - (out) generated WebP bitstream.
+// Returns:
+//   True on success.
+WEBP_EXTERN(int) WebPAnimEncoderAssemble(WebPAnimEncoder* enc,
+                                         WebPData* webp_data);
+
+// Deletes the WebPAnimEncoder object.
+// Parameters:
+//   anim_enc - (in/out) object to be deleted
+WEBP_EXTERN(void) WebPAnimEncoderDelete(WebPAnimEncoder* anim_enc);
+
+//------------------------------------------------------------------------------
+
+#ifdef __cplusplus
+}    // extern "C"
+#endif
+
+#endif  /* WEBP_WEBP_MUX_H_ */
diff --git a/Source/LibWebP/src/webp/mux_types.h b/Source/LibWebP/src/webp/mux_types.h
new file mode 100644
index 0000000..de71f04
--- /dev/null
+++ b/Source/LibWebP/src/webp/mux_types.h
@@ -0,0 +1,97 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Data-types common to the mux and demux libraries.
+//
+// Author: Urvang (urvang at google.com)
+
+#ifndef WEBP_WEBP_MUX_TYPES_H_
+#define WEBP_WEBP_MUX_TYPES_H_
+
+#include <stdlib.h>  // free()
+#include <string.h>  // memset()
+#include "./types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Note: forward declaring enumerations is not allowed in (strict) C and C++,
+// the types are left here for reference.
+// typedef enum WebPFeatureFlags WebPFeatureFlags;
+// typedef enum WebPMuxAnimDispose WebPMuxAnimDispose;
+// typedef enum WebPMuxAnimBlend WebPMuxAnimBlend;
+typedef struct WebPData WebPData;
+
+// VP8X Feature Flags.
+typedef enum WebPFeatureFlags {
+  FRAGMENTS_FLAG  = 0x00000001,
+  ANIMATION_FLAG  = 0x00000002,
+  XMP_FLAG        = 0x00000004,
+  EXIF_FLAG       = 0x00000008,
+  ALPHA_FLAG      = 0x00000010,
+  ICCP_FLAG       = 0x00000020
+} WebPFeatureFlags;
+
+// Dispose method (animation only). Indicates how the area used by the current
+// frame is to be treated before rendering the next frame on the canvas.
+typedef enum WebPMuxAnimDispose {
+  WEBP_MUX_DISPOSE_NONE,       // Do not dispose.
+  WEBP_MUX_DISPOSE_BACKGROUND  // Dispose to background color.
+} WebPMuxAnimDispose;
+
+// Blend operation (animation only). Indicates how transparent pixels of the
+// current frame are blended with those of the previous canvas.
+typedef enum WebPMuxAnimBlend {
+  WEBP_MUX_BLEND,              // Blend.
+  WEBP_MUX_NO_BLEND            // Do not blend.
+} WebPMuxAnimBlend;
+
+// Data type used to describe 'raw' data, e.g., chunk data
+// (ICC profile, metadata) and WebP compressed image data.
+struct WebPData {
+  const uint8_t* bytes;
+  size_t size;
+};
+
+// Initializes the contents of the 'webp_data' object with default values.
+static WEBP_INLINE void WebPDataInit(WebPData* webp_data) {
+  if (webp_data != NULL) {
+    memset(webp_data, 0, sizeof(*webp_data));
+  }
+}
+
+// Clears the contents of the 'webp_data' object by calling free(). Does not
+// deallocate the object itself.
+static WEBP_INLINE void WebPDataClear(WebPData* webp_data) {
+  if (webp_data != NULL) {
+    free((void*)webp_data->bytes);
+    WebPDataInit(webp_data);
+  }
+}
+
+// Allocates necessary storage for 'dst' and copies the contents of 'src'.
+// Returns true on success.
+static WEBP_INLINE int WebPDataCopy(const WebPData* src, WebPData* dst) {
+  if (src == NULL || dst == NULL) return 0;
+  WebPDataInit(dst);
+  if (src->bytes != NULL && src->size != 0) {
+    dst->bytes = (uint8_t*)malloc(src->size);
+    if (dst->bytes == NULL) return 0;
+    memcpy((void*)dst->bytes, src->bytes, src->size);
+    dst->size = src->size;
+  }
+  return 1;
+}
+
+#ifdef __cplusplus
+}    // extern "C"
+#endif
+
+#endif  /* WEBP_WEBP_MUX_TYPES_H_ */
diff --git a/Source/LibWebP/src/webp/types.h b/Source/LibWebP/src/webp/types.h
new file mode 100644
index 0000000..9f0f145
--- /dev/null
+++ b/Source/LibWebP/src/webp/types.h
@@ -0,0 +1,52 @@
+// Copyright 2010 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+//  Common types
+//
+// Author: Skal (pascal.massimino at gmail.com)
+
+#ifndef WEBP_WEBP_TYPES_H_
+#define WEBP_WEBP_TYPES_H_
+
+#include <stddef.h>  // for size_t
+
+#ifndef _MSC_VER
+#include <inttypes.h>
+#if defined(__cplusplus) || !defined(__STRICT_ANSI__) || \
+    (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L)
+#define WEBP_INLINE inline
+#else
+#define WEBP_INLINE
+#endif
+#else
+typedef signed   char int8_t;
+typedef unsigned char uint8_t;
+typedef signed   short int16_t;
+typedef unsigned short uint16_t;
+typedef signed   int int32_t;
+typedef unsigned int uint32_t;
+typedef unsigned long long int uint64_t;
+typedef long long int int64_t;
+#define WEBP_INLINE __forceinline
+#endif  /* _MSC_VER */
+
+#ifndef WEBP_EXTERN
+// This explicitly marks library functions and allows for changing the
+// signature for e.g., Windows DLL builds.
+# if defined(__GNUC__) && __GNUC__ >= 4
+#  define WEBP_EXTERN(type) extern __attribute__ ((visibility ("default"))) type
+# else
+#  define WEBP_EXTERN(type) extern type
+# endif  /* __GNUC__ >= 4 */
+#endif  /* WEBP_EXTERN */
+
+// Macro to check ABI compatibility (same major revision number)
+#define WEBP_ABI_IS_INCOMPATIBLE(a, b) (((a) >> 8) != ((b) >> 8))
+
+#endif  /* WEBP_WEBP_TYPES_H_ */
diff --git a/Source/MapIntrospector.h b/Source/MapIntrospector.h
new file mode 100644
index 0000000..091ba68
--- /dev/null
+++ b/Source/MapIntrospector.h
@@ -0,0 +1,212 @@
+// ==========================================================
+// STL MapIntrospector class
+//
+// Design and implementation by
+// - Carsten Klein (cklein05 at users.sourceforge.net)
+//
+// This file is part of FreeImage 3
+//
+// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
+// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
+// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
+// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
+// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
+// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
+// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+// THIS DISCLAIMER.
+//
+// Use at your own risk!
+// ==========================================================
+
+#ifndef MAPINTROSPECTOR_H_
+#define MAPINTROSPECTOR_H_
+
+// we need at least one C++ header included, 
+// that defines the C++ Standard Library's version macro, 
+// that is used below to identify the library.
+#include <cstdlib>
+
+/**
+Class MapIntrospector - STL std::map Introspector
+
+The MapIntrospector is a helper class used to calculate or estimate part
+of the internal memory footprint of a std::map, that is the memory used
+by N entries, where N is provided as an argument. This class is used by
+function FreeImage_GetMemorySize, which aims to get the total memory
+usage for a FreeImage bitmap.
+
+The type argument _Maptype must take the type of the std::map to be
+introspected.
+
+This class accounts for 'internal' memory per entry only, that is, the
+size returned does neither include the actual size of the std::map class
+itself, nor does it include the size of referenced keys and values (also
+the actual bytes required for std::string type keys or values are not
+counted). For example, the total memory usage should be something like:
+
+typedef std::map<std::string, double> DBLMAP
+DBLMAP MyMap;
+
+int total_size = sizeof(DBLMAP) + MapIntrospector<DBLMAP>::GetNodesMemorySize(MyMap.size())
+for (DBLMAP::iterator i = MyMap->begin(); i != MyMap->end(); i++) {
+ std::string key = i->first;
+ total_size += key.capacity();
+}
+
+So, basically, this class' task is to get the (constant) number of bytes
+per entry, which is multiplied by N (parameter node_count) and returned
+in method GetNodesMemorySize. Since this heavily depends on the actually
+used C++ Standard Library, this class must be implemented specifically
+for each C++ Standard Library.
+
+At current, there is an implementation available for these C++ Standard
+Libraries:
+
+- Microsoft C++ Standard Library
+- GNU Standard C++ Library v3, libstdc++-v3
+- LLVM "libc++" C++ Standard Library (untested)
+- Unknown C++ Standard Library
+
+Volunteers for testing as well as for providing support for other/new
+libraries are welcome.
+
+The 'Unknown C++ Standard Library' case is used if no other known C++
+Standard Library was detected. It uses a typical _Node structure to
+declare an estimated memory consumption for a node.
+*/
+
+#if defined(_CPPLIB_VER)	// Microsoft C++ Standard Library
+/**
+ The Microsoft C++ Standard Library uses the protected structure _Node
+ of class std::_Tree_nod to represent a node. This class is used by
+ std::_Tree, the base class of std::map. So, since std::map is derived
+ from std::_Tree (and _Node is protected), we can get access to this
+ structure by deriving from std::map.
+
+ Additionally, the Microsoft C++ Standard Library uses a separately
+ allocated end node for its balanced red-black tree so, actually, there
+ are size() + 1 nodes present in memory.
+
+ With all that in place, the total memory for all nodes in std::map
+ is simply (node_count + 1) * sizeof(_Node).
+*/
+template<class _Maptype>
+class MapIntrospector: private _Maptype {
+public:
+	static size_t GetNodesMemorySize(size_t node_count) {
+		return (node_count + 1) * sizeof(_Node);
+	}
+};
+
+#elif defined(__GLIBCXX__)	// GNU Standard C++ Library v3, libstdc++-v3
+/**
+ The GNU Standard C++ Library v3 uses structure std::_Rb_tree_node<_Val>,
+ which is publicly declared in the standard namespace. Its value type
+ _Val is actually the map's value_type std::map::value_type.
+
+ So, the total memory for all nodes in std::map is simply
+ node_count * sizeof(std::_Rb_tree_node<_Val>), _Val being the map's
+ value_type.
+*/
+template<class _Maptype>
+class MapIntrospector {
+private:
+	typedef typename _Maptype::value_type _Val;
+
+public:
+	static size_t GetNodesMemorySize(size_t node_count) {
+		return node_count * sizeof(std::_Rb_tree_node<_Val>);
+	}
+};
+
+#elif defined(_LIBCPP_VERSION)	// "libc++" C++ Standard Library (LLVM)
+/*
+ The "libc++" C++ Standard Library uses structure
+ std::__tree_node<_Val, void*> for regular nodes and one instance of
+ structure std::__tree_end_node<void*> for end nodes, which both are
+ publicly declared in the standard namespace. Its value type _Val is
+ actually the map's value_type std::map::value_type.
+
+ So, the total memory for all nodes in std::map is simply
+ node_count * sizeof(std::__tree_node<_Val, void*>)
+ + sizeof(std::__tree_end_node<void*>).
+ 
+ REMARK: this implementation is not yet tested!
+*/
+template<class _Maptype>
+class MapIntrospector {
+private:
+	typedef typename _Maptype::value_type _Val;
+
+public:
+	static size_t GetNodesMemorySize(size_t node_count) {
+		return node_count * sizeof(std::__tree_node<_Val, void*>) + sizeof(std::__tree_end_node<void*>);
+	}
+};
+
+//#elif defined(_ADD_YOUR_CPP_STD_LIBRARY_HERE_)
+
+#else							// Unknown C++ Standard Library
+/**
+ If we do not know the actual C++ Standard Library and so, have no
+ access to any internal types, we can just make some assumptions about
+ the implementation and memory usage.
+
+ However, all implementations will probably be based on a balanced
+ red-black tree, will also store the map's value_type in each node and
+ need some extra information like the node's color. For a binary tree,
+ at least two pointers, one for left and one for right are required.
+ Since it is handy, many implementations also have a parent pointer.
+
+ We let the compiler calculate the size of the above mentioned items by
+ using a fake structure. By using a real structure (in contrast to just
+ adding numbers/bytes) we'll get correct pointer sizes as well as any
+ padding applied for free.
+*/
+template<class _Maptype>
+class MapIntrospector {
+private:
+	/* Define some handy typedefs to build up the structure. */
+
+	/**
+	 Each node will likely store the value_type of the mapping,
+	 that is a std::pair<_Key, _Value>.
+	*/
+	typedef typename _Maptype::value_type _Val;
+
+	/**
+	 We will need some pointers, since std::map is likely implemented
+	 as a balanced red-black tree.
+	*/
+	typedef void*                         _Ptr;
+
+	/**
+	 Space for some extra information (like the node's color).
+	 An int should be sufficient.
+	*/
+	typedef int                           _Ext;
+
+	/* The memory required for each node will likely look like this
+	 structure. We will just multiply sizeof(_Node) by the number
+	 of nodes to get the total memory of all nodes. By using the
+	 size of the structure, we will also take care of the compiler's
+	 default padding.
+	*/
+	typedef struct {
+		_Ptr _parent_node;
+		_Ptr _left_node;
+		_Ptr _right_node;
+		_Val _value;
+		_Ext _extra_info;
+	} _Node;
+
+public:
+	static size_t GetNodesMemorySize(size_t node_count) {
+		return node_count * sizeof(_Node);
+	}
+};
+
+#endif // Standard C++ Library
+
+#endif // MAPINTROSPECTOR_H_
diff --git a/Source/Metadata/Exif.cpp b/Source/Metadata/Exif.cpp
index ed667b0..35265cb 100644
--- a/Source/Metadata/Exif.cpp
+++ b/Source/Metadata/Exif.cpp
@@ -120,15 +120,15 @@ ReadInt32(BOOL msb_order, const void *buffer) {
 	return value;
 }
 
-static unsigned short 
+static WORD 
 ReadUint16(BOOL msb_order, const void *buffer) {
-	unsigned short value;
+	WORD value;
 	
 	if(msb_order) {
-		value = (unsigned short) ((((BYTE*) buffer)[0] << 8) | ((BYTE*) buffer)[1]);
+		value = (WORD) ((((BYTE*) buffer)[0] << 8) | ((BYTE*) buffer)[1]);
 		return value;
     }
-	value = (unsigned short) ((((BYTE*) buffer)[1] << 8) | ((BYTE*) buffer)[0]);
+	value = (WORD) ((((BYTE*) buffer)[1] << 8) | ((BYTE*) buffer)[0]);
 	return value;
 }
 
@@ -146,9 +146,9 @@ Process a IFD offset
 Returns the offset and the metadata model for this tag
 */
 static void 
-processIFDOffset(FITAG *tag, char *pval, BOOL msb_order, DWORD *subdirOffset, TagLib::MDMODEL *md_model) {
+processIFDOffset(FITAG *tag, const char *pval, BOOL msb_order, DWORD *subdirOffset, TagLib::MDMODEL *md_model) {
 	// get the IFD offset
-	*subdirOffset = (DWORD) ReadUint32(msb_order, pval);
+	*subdirOffset = ReadUint32(msb_order, pval);
 
 	// select a tag info table
 	switch(FreeImage_GetTagID(tag)) {
@@ -162,7 +162,6 @@ processIFDOffset(FITAG *tag, char *pval, BOOL msb_order, DWORD *subdirOffset, Ta
 			*md_model = TagLib::EXIF_INTEROP;
 			break;
 	}
-
 }
 
 /**
@@ -170,7 +169,7 @@ Process a maker note IFD offset
 Returns the offset and the metadata model for this tag
 */
 static void 
-processMakerNote(FIBITMAP *dib, char *pval, BOOL msb_order, DWORD *subdirOffset, TagLib::MDMODEL *md_model) {
+processMakerNote(FIBITMAP *dib, const char *pval, BOOL msb_order, DWORD *subdirOffset, TagLib::MDMODEL *md_model) {
 	FITAG *tagMake = NULL;
 
 	*subdirOffset = 0;
@@ -238,12 +237,12 @@ processMakerNote(FIBITMAP *dib, char *pval, BOOL msb_order, DWORD *subdirOffset,
 		}
 	} else if ((memcmp("FUJIFILM", pval, 8) == 0) || (Maker && (FreeImage_strnicmp("Fujifilm", Maker, 8) == 0))) {
         // Fujifile Makernote
-		// Fujifilm's Makernote always use Intel order altough the Exif section maybe in Intel order or in Motorola order. 
+		// Fujifilm's Makernote always use little-endian order altough the Exif section maybe in little-endian order or in big-endian order. 
 		// If msb_order == TRUE, the Makernote won't be read: 
 		// the value of ifdStart will be 0x0c000000 instead of 0x0000000c and the MakerNote section will be discarded later
 		// in jpeg_read_exif_dir because the IFD is too high
 		*md_model = TagLib::EXIF_MAKERNOTE_FUJIFILM;
-        DWORD ifdStart = (DWORD) ReadUint32(msb_order, pval + 8);
+        DWORD ifdStart = ReadUint32(msb_order, pval + 8);
 		*subdirOffset = ifdStart;
     }
 	else if(memcmp("KYOCERA\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x00\x00\x00", pval, 22) == 0) {
@@ -515,17 +514,19 @@ processExifTag(FIBITMAP *dib, FITAG *tag, char *pval, BOOL msb_order, TagLib::MD
 }
 
 /**
-	Process Exif directory
-
-	@param dib Input FIBITMAP
-	@param tiffp Pointer to the TIFF header
-	@param offset 0th IFD offset
-	@param length Length of the datafile
-	@param msb_order Endianess order of the datafile
-	@return 
+Process Exif directory
+
+ at param dib Input FIBITMAP
+ at param tiffp Pointer to the TIFF header
+ at param dwOffsetIfd0 Offset to the 0th IFD (first IFD)
+ at param dwLength Length of the Exif file
+ at param dwProfileOffset File offset to be used when reading 'offset/value' tags
+ at param msb_order Endianness order of the Exif file (TRUE if big-endian, FALSE if little-endian)
+ at param starting_md_model Metadata model of the IFD (should be TagLib::EXIF_MAIN for a jpeg)
+ at return Returns TRUE if sucessful, returns FALSE otherwise
 */
 static BOOL 
-jpeg_read_exif_dir(FIBITMAP *dib, const BYTE *tiffp, unsigned long offset, unsigned int length, BOOL msb_order) {
+jpeg_read_exif_dir(FIBITMAP *dib, const BYTE *tiffp, DWORD dwOffsetIfd0, DWORD dwLength, DWORD dwProfileOffset, BOOL msb_order, TagLib::MDMODEL starting_md_model) {
 	WORD de, nde;
 
 	std::stack<WORD>			destack;	// directory entries stack
@@ -548,11 +549,11 @@ jpeg_read_exif_dir(FIBITMAP *dib, const BYTE *tiffp, unsigned long offset, unsig
 
 	// set the metadata model to Exif
 
-	TagLib::MDMODEL md_model = TagLib::EXIF_MAIN;
+	TagLib::MDMODEL md_model = starting_md_model;
 
 	// set the pointer to the first IFD (0th IFD) and follow it were it leads.
 
-	const BYTE *ifd0th = (BYTE*)tiffp + offset;
+	const BYTE *ifd0th = (BYTE*)tiffp + (size_t)dwOffsetIfd0;
 
 	const BYTE *ifdp = ifd0th;
 
@@ -576,6 +577,10 @@ jpeg_read_exif_dir(FIBITMAP *dib, const BYTE *tiffp, unsigned long offset, unsig
 
 		// determine how many entries there are in the current IFD
 		nde = ReadUint16(msb_order, ifdp);
+		if (((size_t)(ifdp - tiffp) + 12 * nde) > (size_t)dwLength) {
+			// suspicious IFD offset, ignore
+			continue;
+		}
 
 		for(; de < nde; de++) {
 			char *pde = NULL;	// pointer to the directory entry
@@ -589,7 +594,9 @@ jpeg_read_exif_dir(FIBITMAP *dib, const BYTE *tiffp, unsigned long offset, unsig
 			pde = (char*) DIR_ENTRY_ADDR(ifdp, de);
 
 			// get the tag ID
-			FreeImage_SetTagID(tag, ReadUint16(msb_order, pde));
+			WORD tag_id = ReadUint16(msb_order, pde);
+			FreeImage_SetTagID(tag, tag_id);
+
 			// get the tag type
 			WORD tag_type = (WORD)ReadUint16(msb_order, pde + 2);
             if((tag_type - 1) >= EXIF_NUM_FORMATS) {
@@ -601,7 +608,9 @@ jpeg_read_exif_dir(FIBITMAP *dib, const BYTE *tiffp, unsigned long offset, unsig
 			FreeImage_SetTagType(tag, (FREE_IMAGE_MDTYPE)tag_type);
 
 			// get number of components
-			FreeImage_SetTagCount(tag, ReadUint32(msb_order, pde + 4));
+			DWORD tag_count = ReadUint32(msb_order, pde + 4);
+			FreeImage_SetTagCount(tag, tag_count);
+
             // check that tag length (size of the tag value in bytes) will fit in a DWORD
             unsigned tag_data_width = FreeImage_TagDataWidth(FreeImage_GetTagType(tag));
             if (tag_data_width != 0 && FreeImage_GetTagCount(tag) > ~(DWORD)0 / tag_data_width) {
@@ -615,17 +624,21 @@ jpeg_read_exif_dir(FIBITMAP *dib, const BYTE *tiffp, unsigned long offset, unsig
 				// 4 bytes or less and value is in the dir entry itself
 				pval = pde + 8;
 			} else {
-				// if its bigger than 4 bytes, the directory entry contains an offset
-				// first check if offset exceeds buffer, at this stage FreeImage_GetTagLength may return invalid data
+				// if its bigger than 4 bytes, the directory entry contains an offset				
 				DWORD offset_value = ReadUint32(msb_order, pde + 8);
-				if(offset_value > length) {
+				// the offset can be relative to tiffp or to an external reference (see JPEG-XR)
+				if(dwProfileOffset) {
+					offset_value -= dwProfileOffset;
+				}
+				// first check if offset exceeds buffer, at this stage FreeImage_GetTagLength may return invalid data
+				if(offset_value > dwLength) {
 					// a problem occured : delete the tag (not free'd after)
 					FreeImage_DeleteTag(tag);
 					// jump to next entry
 					continue;
 				}
 				// now check that length does not exceed the buffer size
-				if(FreeImage_GetTagLength(tag) > length - offset_value){
+				if(FreeImage_GetTagLength(tag) > dwLength - offset_value){
 					// a problem occured : delete the tag (not free'd after)
 					FreeImage_DeleteTag(tag);
 					// jump to next entry
@@ -658,10 +671,10 @@ jpeg_read_exif_dir(FIBITMAP *dib, const BYTE *tiffp, unsigned long offset, unsig
 					next_ifd = (BYTE*)tiffp + sub_offset;
 				}
 
-				if((sub_offset < (DWORD) length) && (next_mdmodel != TagLib::UNKNOWN)) {
+				if((sub_offset < dwLength) && (next_mdmodel != TagLib::UNKNOWN)) {
 					// push our current directory state onto the stack
 					ifdstack.push(ifdp);
-					// bump to the next entry
+					// jump to the next entry
 					de++;
 					destack.push(de);
 
@@ -707,7 +720,7 @@ jpeg_read_exif_dir(FIBITMAP *dib, const BYTE *tiffp, unsigned long offset, unsig
 	const WORD entriesCount0th = ReadUint16(msb_order, ifd0th);
 	
 	DWORD next_offset = ReadUint32(msb_order, DIR_ENTRY_ADDR(ifd0th, entriesCount0th));
-	if((next_offset == 0) || (next_offset >= length)) {
+	if((next_offset == 0) || (next_offset >= dwLength)) {
 		return TRUE; //< no thumbnail
 	}
 	
@@ -725,7 +738,7 @@ jpeg_read_exif_dir(FIBITMAP *dib, const BYTE *tiffp, unsigned long offset, unsig
 		
 		// check for buffer overflow
 		const size_t remaining = (size_t)base + 12 - (size_t)tiffp;
-		if(remaining >= length) {
+		if(remaining >= dwLength) {
 			// bad IFD1 directory, ignore it
 			return FALSE;
 		}
@@ -733,9 +746,9 @@ jpeg_read_exif_dir(FIBITMAP *dib, const BYTE *tiffp, unsigned long offset, unsig
 		// get the tag ID
 		WORD tag = ReadUint16(msb_order, base);
 		// get the tag type
-		WORD type = ReadUint16(msb_order, base + sizeof(WORD));
+		/*WORD type = */ReadUint16(msb_order, base + sizeof(WORD));
 		// get number of components
-		DWORD count = ReadUint32(msb_order, base + sizeof(WORD) + sizeof(WORD));
+		/*DWORD count = */ReadUint32(msb_order, base + sizeof(WORD) + sizeof(WORD));
 		// get the tag value
 		DWORD offset = ReadUint32(msb_order, base + sizeof(WORD) + sizeof(WORD) + sizeof(DWORD));
 
@@ -767,7 +780,7 @@ jpeg_read_exif_dir(FIBITMAP *dib, const BYTE *tiffp, unsigned long offset, unsig
 		return TRUE;
 	}
 	
-	if(thOffset + thSize > length) {
+	if(thOffset + thSize > dwLength) {
 		return TRUE;
 	}
 	
@@ -787,44 +800,48 @@ jpeg_read_exif_dir(FIBITMAP *dib, const BYTE *tiffp, unsigned long offset, unsig
 	return TRUE;
 }
 
+// --------------------------------------------------------------------------
+
 /**
-	Read and decode JPEG_APP1 marker (Exif profile)
-	@param dib Input FIBITMAP
-	@param dataptr Pointer to the APP1 marker
-	@param datalen APP1 marker length
-	@return Returns TRUE if successful, FALSE otherwise
+Read and decode JPEG_APP1 marker (Exif profile)
+ at param dib Input FIBITMAP
+ at param data Pointer to the APP1 marker
+ at param length APP1 marker length
+ at return Returns TRUE if successful, FALSE otherwise
 */
 BOOL  
-jpeg_read_exif_profile(FIBITMAP *dib, const BYTE *dataptr, unsigned int datalen) {
+jpeg_read_exif_profile(FIBITMAP *dib, const BYTE *data, unsigned length) {
     // marker identifying string for Exif = "Exif\0\0"
     BYTE exif_signature[6] = { 0x45, 0x78, 0x69, 0x66, 0x00, 0x00 };
-	BYTE lsb_first[4] = { 0x49, 0x49, 0x2A, 0x00 };		// Intel order
-	BYTE msb_first[4] = { 0x4D, 0x4D, 0x00, 0x2A };		// Motorola order
+	BYTE lsb_first[4] = { 0x49, 0x49, 0x2A, 0x00 };		// Classic TIFF signature - little-endian order
+	BYTE msb_first[4] = { 0x4D, 0x4D, 0x00, 0x2A };		// Classic TIFF signature - big-endian order
 
-	unsigned int length = datalen;
-	BYTE *profile = (BYTE*)dataptr;
+	// profile size is up to 32-bit
+	DWORD dwProfileLength = (DWORD)length;
+	BYTE *pbProfile = (BYTE*)data;
 
 	// verify the identifying string
+	if(memcmp(exif_signature, pbProfile, sizeof(exif_signature)) == 0) {
+		// This is an Exif profile
+		// should contain a TIFF header with up to 2 IFDs (IFD stands for 'Image File Directory')
+		// 0th IFD : the image attributes, 1st IFD : may be used for thumbnail
 
-	if(memcmp(exif_signature, profile, sizeof(exif_signature)) == 0) {
-		// Exif profile - TIFF header with 2 IFDs. 0th - the image attributes, 1st - may be used for thumbnail
-
-		profile += sizeof(exif_signature);
-		length  -= sizeof(exif_signature);
+		pbProfile += sizeof(exif_signature);
+		dwProfileLength -= sizeof(exif_signature);
 
 		// read the TIFF header (8 bytes)
 
 		// check the endianess order
 		
-		BOOL bMotorolaOrder = TRUE;
+		BOOL bBigEndian = TRUE;
 
-		if(memcmp(profile, lsb_first, sizeof(lsb_first)) == 0) {
-			// Exif section in Intel order
-			bMotorolaOrder = FALSE;
+		if(memcmp(pbProfile, lsb_first, sizeof(lsb_first)) == 0) {
+			// Exif section is in little-endian order
+			bBigEndian = FALSE;
 		} else {
-			if(memcmp(profile, msb_first, sizeof(msb_first)) == 0) {
-				// Exif section in Motorola order
-				bMotorolaOrder = TRUE;
+			if(memcmp(pbProfile, msb_first, sizeof(msb_first)) == 0) {
+				// Exif section is in big-endian order
+				bBigEndian = TRUE;
 			} else {
 				// Invalid Exif alignment marker
 				return FALSE;
@@ -832,8 +849,8 @@ jpeg_read_exif_profile(FIBITMAP *dib, const BYTE *dataptr, unsigned int datalen)
 		}
 
 		// this is the offset to the first IFD (Image File Directory)
-		unsigned long first_offset = ReadUint32(bMotorolaOrder, profile + 4);
-		if (first_offset > length) {
+		DWORD dwFirstOffset = ReadUint32(bBigEndian, pbProfile + 4);
+		if (dwFirstOffset > dwProfileLength) {
 			// bad Exif data
 			return FALSE;
 		}
@@ -841,7 +858,7 @@ jpeg_read_exif_profile(FIBITMAP *dib, const BYTE *dataptr, unsigned int datalen)
 		/*
 		Note: as FreeImage 3.14.0, this test is no longer needed for images with similar suspicious offset
 		=> tested with Pentax Optio 230, FujiFilm SP-2500 and Canon EOS 300D
-		if (first_offset < 8 || first_offset > 16) {
+		if (dwFirstOffset < 8 || dwFirstOffset > 16) {
 			// This is usually set to 8
 			// but PENTAX Optio 230 has it set differently, and uses it as offset. 
 			FreeImage_OutputMessageProc(FIF_JPEG, "Exif: Suspicious offset of first IFD value");
@@ -849,11 +866,388 @@ jpeg_read_exif_profile(FIBITMAP *dib, const BYTE *dataptr, unsigned int datalen)
 		}
 		*/
 
-		// process Exif directories
-		return jpeg_read_exif_dir(dib, profile, first_offset, length, bMotorolaOrder);
+		// process Exif directories, starting with Exif-TIFF IFD
+		return jpeg_read_exif_dir(dib, pbProfile, dwFirstOffset, dwProfileLength, 0, bBigEndian, TagLib::EXIF_MAIN);
+	}
+
+	return FALSE;
+}
+
+// ==========================================================
+// Exif JPEG helper routines
+// ==========================================================
+
+/**
+Read JPEG_APP1 marker (Exif profile)
+ at param dib Input FIBITMAP
+ at param dataptr Pointer to the APP1 marker
+ at param datalen APP1 marker length
+ at return Returns TRUE if successful, FALSE otherwise
+*/
+BOOL  
+jpeg_read_exif_profile_raw(FIBITMAP *dib, const BYTE *profile, unsigned length) {
+    // marker identifying string for Exif = "Exif\0\0"
+    BYTE exif_signature[6] = { 0x45, 0x78, 0x69, 0x66, 0x00, 0x00 };
+
+	// verify the identifying string
+	if(memcmp(exif_signature, profile, sizeof(exif_signature)) != 0) {
+		// not an Exif profile
+		return FALSE;
+	}
+
+	// create a tag
+	FITAG *tag = FreeImage_CreateTag();
+	if(tag) {
+		FreeImage_SetTagKey(tag, g_TagLib_ExifRawFieldName);
+		FreeImage_SetTagLength(tag, (DWORD)length);
+		FreeImage_SetTagCount(tag, (DWORD)length);
+		FreeImage_SetTagType(tag, FIDT_BYTE);
+		FreeImage_SetTagValue(tag, profile);
+
+		// store the tag
+		FreeImage_SetMetadata(FIMD_EXIF_RAW, dib, FreeImage_GetTagKey(tag), tag);
+
+		// destroy the tag
+		FreeImage_DeleteTag(tag);
+
+		return TRUE;
 	}
 
 	return FALSE;
 }
 
+// ==========================================================
+// Exif JPEG-XR helper routines
+// ==========================================================
+
+/**
+Read and decode JPEG-XR Exif IFD
+ at param dib Input FIBITMAP
+ at param profile Pointer to the Exif marker
+ at param length Exif marker length
+ at param file_offset Reference offset in the original file of each tag value whose length is > 4
+ at return Returns TRUE if successful, FALSE otherwise
+*/
+BOOL  
+jpegxr_read_exif_profile(FIBITMAP *dib, const BYTE *profile, unsigned length, unsigned file_offset) {
+	// assume Little Endian order
+	BOOL bBigEndian = FALSE;
+	
+	// process Exif specific IFD
+	return jpeg_read_exif_dir(dib, profile, 0, length, file_offset, bBigEndian, TagLib::EXIF_EXIF);
+}
+
+/**
+Read and decode JPEG-XR Exif-GPS IFD
+ at param dib Input FIBITMAP
+ at param profile Pointer to the Exif-GPS profile
+ at param length Exif-GPS profile length
+ at param file_offset Reference offset in the original file of each tag value whose length is > 4
+ at return Returns TRUE if successful, FALSE otherwise
+*/
+BOOL  
+jpegxr_read_exif_gps_profile(FIBITMAP *dib, const BYTE *profile, unsigned length, unsigned file_offset) {
+	// assume Little Endian order
+	BOOL bBigEndian = FALSE;
+	
+	// process Exif GPS IFD
+	return jpeg_read_exif_dir(dib, profile, 0, length, file_offset, bBigEndian, TagLib::EXIF_GPS);
+}
+
+// ==========================================================
+// Exif common helper routines
+// ==========================================================
+
+/**
+Rotate a dib according to Exif info
+ at param dib Input / Output dib to rotate
+ at see PluginJPEG.cpp
+*/
+void 
+RotateExif(FIBITMAP **dib) {
+	// check for Exif rotation
+	if(FreeImage_GetMetadataCount(FIMD_EXIF_MAIN, *dib)) {
+		FIBITMAP *rotated = NULL;
+		// process Exif rotation
+		FITAG *tag = NULL;
+		FreeImage_GetMetadata(FIMD_EXIF_MAIN, *dib, "Orientation", &tag);
+		if((tag != NULL) && (FreeImage_GetTagID(tag) == TAG_ORIENTATION)) {
+			const WORD orientation = *((WORD *)FreeImage_GetTagValue(tag));
+			switch (orientation) {
+				case 1:		// "top, left side" => 0�
+					break;
+				case 2:		// "top, right side" => flip left-right
+					FreeImage_FlipHorizontal(*dib);
+					break;
+				case 3:		// "bottom, right side" => -180�
+					rotated = FreeImage_Rotate(*dib, 180);
+					FreeImage_Unload(*dib);
+					*dib = rotated;
+					break;
+				case 4:		// "bottom, left side" => flip up-down
+					FreeImage_FlipVertical(*dib);
+					break;
+				case 5:		// "left side, top" => +90� + flip up-down
+					rotated = FreeImage_Rotate(*dib, 90);
+					FreeImage_Unload(*dib);
+					*dib = rotated;
+					FreeImage_FlipVertical(*dib);
+					break;
+				case 6:		// "right side, top" => -90�
+					rotated = FreeImage_Rotate(*dib, -90);
+					FreeImage_Unload(*dib);
+					*dib = rotated;
+					break;
+				case 7:		// "right side, bottom" => -90� + flip up-down
+					rotated = FreeImage_Rotate(*dib, -90);
+					FreeImage_Unload(*dib);
+					*dib = rotated;
+					FreeImage_FlipVertical(*dib);
+					break;
+				case 8:		// "left side, bottom" => +90�
+					rotated = FreeImage_Rotate(*dib, 90);
+					FreeImage_Unload(*dib);
+					*dib = rotated;
+					break;
+				default:
+					break;
+			}
+		}
+	}
+}
+
+// ==========================================================
+// Exif TIFF JPEG-XR helper routines
+// ==========================================================
+
+class PredicateTagIDCompare {
+public:
+	bool operator()(FITAG *a, FITAG *b) {
+		WORD tag_id_a = FreeImage_GetTagID(a);
+		WORD tag_id_b = FreeImage_GetTagID(b);
+		return (tag_id_a < tag_id_b);
+	}
+};
+
+/**
+Write a metadata model as a TIF IFD to a FIMEMORY handle.
+The entries in the TIF IFD are sorted in ascending order by tag id.	
+The last entry is written as 0 (4 bytes) which means no more IFD to follow. 
+Supported metadata models are
+<ul>
+<li>FIMD_EXIF_MAIN
+<li>FIMD_EXIF_EXIF
+<li>FIMD_EXIF_GPS
+<li>FIMD_EXIF_INTEROP
+</ul>
+The end of the buffer is filled with 4 bytes equal to 0 (end of IFD offset)
+
+ at param dib Input FIBITMAP
+ at param md_model Metadata model to write
+ at param hmem Memory handle
+ at return Returns TRUE if successful, FALSE otherwise
+ at see tiff_get_ifd_profile
+*/
+static BOOL
+tiff_write_ifd(FIBITMAP *dib, FREE_IMAGE_MDMODEL md_model, FIMEMORY *hmem) {
+	FITAG *tag = NULL;
+	FIMETADATA *mdhandle = NULL;
+	std::vector<FITAG*> vTagList;
+	TagLib::MDMODEL internal_md_model;
+
+	DWORD ifd_offset = 0;	// WORD-aligned IFD value offset
+
+	const BYTE empty_byte = 0;
+
+	// start of the file
+	const long start_of_file = FreeImage_TellMemory(hmem);
+
+	// get the metadata count
+	unsigned metadata_count = FreeImage_GetMetadataCount(md_model, dib);
+	if(metadata_count == 0) {
+		return FALSE;
+	}
+
+	TagLib& s = TagLib::instance();
+
+	// check for supported metadata models
+	switch(md_model) {
+		case FIMD_EXIF_MAIN:
+			internal_md_model = TagLib::EXIF_MAIN;
+			break;
+		case FIMD_EXIF_EXIF:
+			internal_md_model = TagLib::EXIF_EXIF;
+			break;
+		case FIMD_EXIF_GPS:
+			internal_md_model = TagLib::EXIF_GPS;
+			break;
+		case FIMD_EXIF_INTEROP:
+			internal_md_model = TagLib::EXIF_INTEROP;
+			break;
+		default:
+			return FALSE;
+	}
+
+	try {
+		// 1) according to the TIFF specifications, 
+		// the entries in a TIF IFD must be sorted in ascending order by tag id
+
+		// store the tags into a vector
+		vTagList.reserve(metadata_count);
+		mdhandle = FreeImage_FindFirstMetadata(md_model, dib, &tag);
+		if(mdhandle) {
+			// parse the tags and store them inside vTagList
+			do {
+				// rewrite the tag id using FreeImage internal database
+				// (in case the tag id is wrong or missing)
+				const char *key = FreeImage_GetTagKey(tag);
+				int tag_id = s.getTagID(internal_md_model, key);
+				if(tag_id != -1) {
+					// this is a known tag, set the tag ID
+					FreeImage_SetTagID(tag, (WORD)tag_id);
+					// record the tag
+					vTagList.push_back(tag);
+				}
+				// else ignore this tag
+			} while(FreeImage_FindNextMetadata(mdhandle, &tag));
+
+			FreeImage_FindCloseMetadata(mdhandle);
+
+			// sort the vector by tag id
+			std::sort(vTagList.begin(), vTagList.end(), PredicateTagIDCompare());
+
+			// update the metadata_count
+			metadata_count = (unsigned)vTagList.size();
+
+		} else {
+			throw(1);
+		}
+
+		// 2) prepare the place for each IFD entries.
 
+		/*
+		An Image File Directory (IFD) consists of a 2-byte count of the number of directory entries (i.e., the number of fields), 
+		followed by a sequence of 12-byte field entries, 
+		followed by a 4-byte offset of the next IFD (or 0 if none). Do not forget to write the 4 bytes of 0 after the last IFD.
+		*/
+
+		{		
+			// prepare place for 2 bytes for number of entries + 12 bytes for each entry
+			unsigned ifd_size = 2 + 12 * metadata_count;
+			FreeImage_WriteMemory(&empty_byte, 1, ifd_size, hmem);
+			// record the offset used to write values > 4-bytes
+			ifd_offset = FreeImage_TellMemory(hmem);
+			// rewind
+			FreeImage_SeekMemory(hmem, start_of_file, SEEK_SET);
+		}
+
+		// 3) write each IFD entry in tag id ascending order
+
+		// number of directory entries
+		WORD nde = (WORD)metadata_count;
+		FreeImage_WriteMemory(&nde, 1, 2, hmem);
+
+		// for each entry ...
+		for(unsigned i = 0; i < metadata_count; i++) {
+			FITAG *tag = vTagList[i];
+			// tag id
+			WORD tag_id = FreeImage_GetTagID(tag);
+			FreeImage_WriteMemory(&tag_id, 1, 2, hmem);
+			// tag type (compliant with TIFF specification)
+			WORD tag_type = (WORD)FreeImage_GetTagType(tag);
+			FreeImage_WriteMemory(&tag_type, 1, 2, hmem);
+			// tag count
+			DWORD tag_count = FreeImage_GetTagCount(tag);
+			FreeImage_WriteMemory(&tag_count, 1, 4, hmem);
+			// tag value or offset (results are in BYTE's units)
+			unsigned tag_length = FreeImage_GetTagLength(tag);
+			if(tag_length <= 4) {
+				// 4 bytes or less, write the value (left justified)
+				const BYTE *tag_value = (BYTE*)FreeImage_GetTagValue(tag);
+				FreeImage_WriteMemory(tag_value, 1, tag_length, hmem);
+				for(unsigned k = tag_length; k < 4; k++) {
+					FreeImage_WriteMemory(&empty_byte, 1, 1, hmem);
+				}
+			} else {
+				// write an offset
+				FreeImage_WriteMemory(&ifd_offset, 1, 4, hmem);
+				// write the value
+				long current_position = FreeImage_TellMemory(hmem);
+				FreeImage_SeekMemory(hmem, ifd_offset, SEEK_SET);
+				FreeImage_WriteMemory(FreeImage_GetTagValue(tag), 1, tag_length, hmem);
+				if(tag_length & 1) {
+					// align to the next WORD boundary
+					FreeImage_WriteMemory(&empty_byte, 1, 1, hmem);
+				}
+				// next offset to use
+				ifd_offset = FreeImage_TellMemory(hmem);
+				// rewind
+				FreeImage_SeekMemory(hmem, current_position, SEEK_SET);
+			}
+		}
+
+		// end-of-IFD or next IFD (0 == none)
+		FreeImage_SeekMemory(hmem, ifd_offset, SEEK_SET);
+		FreeImage_WriteMemory(&empty_byte, 1, 4, hmem);
+
+		return TRUE;
+	}
+	catch(int) {
+		return FALSE;
+	}
+}
+
+/**
+Write a metadata model as a TIF IFD, returns the IFD as a buffer.
+The buffer is allocated by the function and must be freed by the caller, using 'free'.
+ at param dib Input FIBITMAP
+ at param md_model Metadata model to write
+ at param ppbProfile Returned buffer
+ at param uProfileLength Returned buffer size
+ at return Returns TRUE if successful, FALSE otherwise
+ at see tiff_write_ifd
+*/
+BOOL
+tiff_get_ifd_profile(FIBITMAP *dib, FREE_IMAGE_MDMODEL md_model, BYTE **ppbProfile, unsigned *uProfileLength) {
+	FIMEMORY *hmem = NULL;
+
+	try {
+		// open a memory stream
+		hmem = FreeImage_OpenMemory(NULL, 0);
+		if(!hmem) {
+			throw(1);
+		}
+
+		// write the metadata model as a TIF IFD
+		BOOL bResult = tiff_write_ifd(dib, md_model, hmem);
+
+		if(bResult) {
+			BYTE *data = NULL;
+			DWORD size_in_bytes = 0;
+
+			// get a pointer to the stream buffer
+			FreeImage_AcquireMemory(hmem, &data, &size_in_bytes);
+			
+			// (re-)allocate output buffer
+			BYTE *pbProfile = *ppbProfile;
+			pbProfile = (BYTE*)realloc(pbProfile, size_in_bytes);
+			if(!pbProfile) {
+				throw(1);
+			} else {
+				// copy IFD
+				memcpy(pbProfile, data, size_in_bytes);
+				*ppbProfile = pbProfile;
+				*uProfileLength = size_in_bytes;
+			}
+		}
+
+		// free the memory stream
+		FreeImage_CloseMemory(hmem);
+
+		return bResult;
+
+	} catch(int) {
+		FreeImage_CloseMemory(hmem);
+		return FALSE;
+	}
+}
diff --git a/Source/Metadata/FreeImageTag.cpp b/Source/Metadata/FreeImageTag.cpp
index 5d9f303..cc12a5d 100644
--- a/Source/Metadata/FreeImageTag.cpp
+++ b/Source/Metadata/FreeImageTag.cpp
@@ -117,11 +117,23 @@ FreeImage_CloneTag(FITAG *tag) {
 		// tag length
 		dst_tag->length = src_tag->length;
 		// tag value
-		dst_tag->value = (BYTE*)malloc(src_tag->length * sizeof(BYTE));
-		if(!dst_tag->value) {
-			throw FI_MSG_ERROR_MEMORY;
+		switch(dst_tag->type) {
+			case FIDT_ASCII:
+				dst_tag->value = (BYTE*)malloc((src_tag->length + 1) * sizeof(BYTE));
+				if(!dst_tag->value) {
+					throw FI_MSG_ERROR_MEMORY;
+				}
+				memcpy(dst_tag->value, src_tag->value, src_tag->length);
+				((BYTE*)dst_tag->value)[src_tag->length] = 0;
+				break;
+			default:
+				dst_tag->value = (BYTE*)malloc(src_tag->length * sizeof(BYTE));
+				if(!dst_tag->value) {
+					throw FI_MSG_ERROR_MEMORY;
+				}
+				memcpy(dst_tag->value, src_tag->value, src_tag->length);
+				break;
 		}
-		memcpy(dst_tag->value, src_tag->value, src_tag->length);
 
 		return clone;
 
@@ -283,11 +295,6 @@ FreeImage_SetTagValue(FITAG *tag, const void *value) {
 // FITAG internal helper functions
 // --------------------------------------------------------------------------
 
-/**
-Given a FREE_IMAGE_MDTYPE, calculate the size of this type in bytes unit
- at param type Input data type
- at return Returns the size of the data type, in bytes unit
-*/
 unsigned 
 FreeImage_TagDataWidth(FREE_IMAGE_MDTYPE type) {
 	static const unsigned format_bytes[] = { 
@@ -305,9 +312,9 @@ FreeImage_TagDataWidth(FREE_IMAGE_MDTYPE type) {
 		4, // FIDT_FLOAT	= 11,	// 32-bit IEEE floating point 
 		8, // FIDT_DOUBLE	= 12,	// 64-bit IEEE floating point 
 		4, // FIDT_IFD		= 13,	// 32-bit unsigned integer (offset) 
-		4, // FIDT_PALETTE	= 14	// 32-bit RGBQUAD 
-		0, // placeholder (15)
-		8, // FIDT_LONG8	= 16,	// 64-bit unsigned integer 
+		4, // FIDT_PALETTE	= 14	// 32-bit RGBQUAD 
+		0, // placeholder (15)
+		8, // FIDT_LONG8	= 16,	// 64-bit unsigned integer 
 		8, // FIDT_SLONG8	= 17,	// 64-bit signed integer
 		8  // FIDT_IFD8		= 18	// 64-bit unsigned integer (offset)
 	};
@@ -316,3 +323,31 @@ FreeImage_TagDataWidth(FREE_IMAGE_MDTYPE type) {
 		  format_bytes[type] : 0;
 }
 
+size_t 
+FreeImage_GetTagMemorySize(FITAG *tag) {
+	size_t size = 0;
+	if (tag) {
+		FITAGHEADER *tag_header = (FITAGHEADER *)tag->data;
+		size += sizeof(FITAG);
+		size += sizeof(FITAGHEADER);
+		if (tag_header->key) {
+			size += strlen(tag_header->key) + 1;
+		}
+		if (tag_header->description) {
+			size += strlen(tag_header->description) + 1;
+		}
+		if (tag_header->value) {
+			switch (tag_header->type) {
+				case FIDT_ASCII:
+					// for ASCII strings, the value of the count part of an ASCII tag entry includes the NULL.
+					// however, FreeImage adds another '\0' to be sure that this last character is present.
+					size += tag_header->length + 1;
+					break;
+				default:
+					size += tag_header->length;
+					break;
+			}
+		}
+	}
+	return size;
+}
diff --git a/Source/Metadata/FreeImageTag.h b/Source/Metadata/FreeImageTag.h
index 4f3bffa..beb8bc8 100644
--- a/Source/Metadata/FreeImageTag.h
+++ b/Source/Metadata/FreeImageTag.h
@@ -291,14 +291,22 @@
 // Helper functions to deal with the FITAG structure
 // --------------------------------------------------------------------------
 
-/** 
+/**
 Describes the tag format descriptor
+Given a FREE_IMAGE_MDTYPE, calculate the size of this type in bytes unit
 @param type Tag data type
- at return Returns the width of a single element, in bytes
+ at return Returns the size of the data type, in bytes
 @see FREE_IMAGE_MDTYPE
 */
 unsigned FreeImage_TagDataWidth(FREE_IMAGE_MDTYPE type);
 
+/**
+Calculate the memory size required by a tag, including the size of the structure
+ at param tag The tag to examine
+ at return Retuns the memory size used by a tag
+*/
+size_t FreeImage_GetTagMemorySize(FITAG *tag);
+
 // --------------------------------------------------------------------------
 
 /**
@@ -321,15 +329,15 @@ TagInfo *tag_info = s.getTagInfo(EXIF_MAIN, 0x0100);
 </code>
 
 Note on multi-threaded applications : 
-
-The singleton pattern must be carefully constructed in multi-threaded applications. 
-If two threads are to execute the creation method at the same time when a singleton 
-does not yet exist, they both must check for an instance of the singleton and then 
-only one should create the new one.
-The classic solution to this problem is to use mutual exclusion on the class that 
-indicates that the object is being instantiated.
-The FreeImage solution is to instantiate the singleton before any other thread is launched, 
-i.e. inside the FreeImage_Initialise function (see Plugin.cpp). 
+
+The singleton pattern must be carefully constructed in multi-threaded applications. 
+If two threads are to execute the creation method at the same time when a singleton 
+does not yet exist, they both must check for an instance of the singleton and then 
+only one should create the new one.
+The classic solution to this problem is to use mutual exclusion on the class that 
+indicates that the object is being instantiated.
+The FreeImage solution is to instantiate the singleton before any other thread is launched, 
+i.e. inside the FreeImage_Initialise function (see Plugin.cpp). 
 */
 
 class TagLib {
@@ -467,10 +475,18 @@ static const char *g_TagLib_ExifRawFieldName = "ExifRaw";
 extern "C" {
 #endif
 
-// JPEG Exif profile
-BOOL jpeg_read_exif_profile(FIBITMAP *dib, const BYTE *dataptr, unsigned int datalen);
+// JPEG / JPEG-XR Exif profile (see Exif.cpp)
+// --------------------------------------------------------------------------
+BOOL jpeg_read_exif_profile(FIBITMAP *dib, const BYTE *dataptr, unsigned datalen);
+BOOL jpeg_read_exif_profile_raw(FIBITMAP *dib, const BYTE *profile, unsigned length);
+BOOL jpegxr_read_exif_profile(FIBITMAP *dib, const BYTE *profile, unsigned length, unsigned file_offset);
+BOOL jpegxr_read_exif_gps_profile(FIBITMAP *dib, const BYTE *profile, unsigned length, unsigned file_offset);
+
+BOOL tiff_get_ifd_profile(FIBITMAP *dib, FREE_IMAGE_MDMODEL md_model, BYTE **ppbProfile, unsigned *uProfileLength);
 
-// JPEG / TIFF IPTC profile
+
+// JPEG / TIFF IPTC profile (see IPTC.cpp)
+// --------------------------------------------------------------------------
 BOOL read_iptc_profile(FIBITMAP *dib, const BYTE *dataptr, unsigned int datalen);
 BOOL write_iptc_profile(FIBITMAP *dib, BYTE **profile, unsigned *profile_size);
 
diff --git a/Source/Metadata/TagConversion.cpp b/Source/Metadata/TagConversion.cpp
index 06a1970..f058186 100644
--- a/Source/Metadata/TagConversion.cpp
+++ b/Source/Metadata/TagConversion.cpp
@@ -1,1094 +1,1094 @@
-// ==========================================================
-// Tag to string conversion functions
-//
-// Design and implementation by
-// - Herv� Drolon <drolon at infonie.fr>
-//
-// This file is part of FreeImage 3
-//
-// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
-// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
-// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
-// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
-// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
-// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
-// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
-// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
-// THIS DISCLAIMER.
-//
-// Use at your own risk!
-// ==========================================================
-
-#ifdef _MSC_VER 
-#pragma warning (disable : 4786) // identifier was truncated to 'number' characters
-#endif
-
-#include "FreeImage.h"
-#include "Utilities.h"
-#include "FreeImageTag.h"
-#include "FIRational.h"
-
-#define MAX_TEXT_EXTENT	512
-
-/**
-Convert a tag to a C string
-*/
-static const char* 
-ConvertAnyTag(FITAG *tag) {
-	char format[MAX_TEXT_EXTENT];
-	static std::string buffer;
-	DWORD i;
-
-	if(!tag)
-		return NULL;
-
-	buffer.erase();
-	
-	// convert the tag value to a string buffer
-
-	FREE_IMAGE_MDTYPE tag_type = FreeImage_GetTagType(tag);
-	DWORD tag_count = FreeImage_GetTagCount(tag);
-
-	switch(tag_type) {
-		case FIDT_BYTE:		// N x 8-bit unsigned integer 
-		{
-			BYTE *pvalue = (BYTE*)FreeImage_GetTagValue(tag);
-
-			sprintf(format, "%ld",	(LONG) pvalue[0]);
-			buffer += format;
-			for(i = 1; i < tag_count; i++) {
-				sprintf(format, " %ld",	(LONG) pvalue[i]);
-				buffer += format;
-			}
-			break;
-		}
-		case FIDT_SHORT:	// N x 16-bit unsigned integer 
-		{
-			unsigned short *pvalue = (unsigned short *)FreeImage_GetTagValue(tag);
-
-			sprintf(format, "%hu", pvalue[0]);
-			buffer += format;
-			for(i = 1; i < tag_count; i++) {
-				sprintf(format, " %hu",	pvalue[i]);
-				buffer += format;
-			}
-			break;
-		}
-		case FIDT_LONG:		// N x 32-bit unsigned integer 
-		{
-			DWORD *pvalue = (DWORD *)FreeImage_GetTagValue(tag);
-
-			sprintf(format, "%lu", pvalue[0]);
-			buffer += format;
-			for(i = 1; i < tag_count; i++) {
-				sprintf(format, " %lu",	pvalue[i]);
-				buffer += format;
-			}
-			break;
-		}
-		case FIDT_RATIONAL: // N x 64-bit unsigned fraction 
-		{
-			DWORD *pvalue = (DWORD*)FreeImage_GetTagValue(tag);
-
-			sprintf(format, "%ld/%ld", pvalue[0], pvalue[1]);
-			buffer += format;
-			for(i = 1; i < tag_count; i++) {
-				sprintf(format, " %ld/%ld", pvalue[2*i], pvalue[2*i+1]);
-				buffer += format;
-			}
-			break;
-		}
-		case FIDT_SBYTE:	// N x 8-bit signed integer 
-		{
-			char *pvalue = (char*)FreeImage_GetTagValue(tag);
-
-			sprintf(format, "%ld",	(LONG) pvalue[0]);
-			buffer += format;
-			for(i = 1; i < tag_count; i++) {
-				sprintf(format, " %ld",	(LONG) pvalue[i]);
-				buffer += format;
-			}
-			break;
-		}
-		case FIDT_SSHORT:	// N x 16-bit signed integer 
-		{
-			short *pvalue = (short *)FreeImage_GetTagValue(tag);
-
-			sprintf(format, "%hd", pvalue[0]);
-			buffer += format;
-			for(i = 1; i < tag_count; i++) {
-				sprintf(format, " %hd",	pvalue[i]);
-				buffer += format;
-			}
-			break;
-		}
-		case FIDT_SLONG:	// N x 32-bit signed integer 
-		{
-			LONG *pvalue = (LONG *)FreeImage_GetTagValue(tag);
-
-			sprintf(format, "%ld", pvalue[0]);
-			buffer += format;
-			for(i = 1; i < tag_count; i++) {
-				sprintf(format, " %ld",	pvalue[i]);
-				buffer += format;
-			}
-			break;
-		}
-		case FIDT_SRATIONAL:// N x 64-bit signed fraction 
-		{
-			LONG *pvalue = (LONG*)FreeImage_GetTagValue(tag);
-
-			sprintf(format, "%ld/%ld", pvalue[0], pvalue[1]);
-			buffer += format;
-			for(i = 1; i < tag_count; i++) {
-				sprintf(format, " %ld/%ld", pvalue[2*i], pvalue[2*i+1]);
-				buffer += format;
-			}
-			break;
-		}
-		case FIDT_FLOAT:	// N x 32-bit IEEE floating point 
-		{
-			float *pvalue = (float *)FreeImage_GetTagValue(tag);
-
-			sprintf(format, "%f", (double) pvalue[0]);
-			buffer += format;
-			for(i = 1; i < tag_count; i++) {
-				sprintf(format, "%f", (double) pvalue[i]);
-				buffer += format;
-			}
-			break;
-		}
-		case FIDT_DOUBLE:	// N x 64-bit IEEE floating point 
-		{
-			double *pvalue = (double *)FreeImage_GetTagValue(tag);
-
-			sprintf(format, "%f", pvalue[0]);
-			buffer += format;
-			for(i = 1; i < tag_count; i++) {
-				sprintf(format, "%f", pvalue[i]);
-				buffer += format;
-			}
-			break;
-		}
-		case FIDT_IFD:		// N x 32-bit unsigned integer (offset) 
-		{
-			DWORD *pvalue = (DWORD *)FreeImage_GetTagValue(tag);
-
-			sprintf(format, "%X", pvalue[0]);
-			buffer += format;
-			for(i = 1; i < tag_count; i++) {
-				sprintf(format, " %X",	pvalue[i]);
-				buffer += format;
-			}
-			break;
-		}
-		case FIDT_PALETTE:	// N x 32-bit RGBQUAD 
-		{
-			RGBQUAD *pvalue = (RGBQUAD *)FreeImage_GetTagValue(tag);
-
-			sprintf(format, "(%d,%d,%d,%d)", pvalue[0].rgbRed, pvalue[0].rgbGreen, pvalue[0].rgbBlue, pvalue[0].rgbReserved);
-			buffer += format;
-			for(i = 1; i < tag_count; i++) {
-				sprintf(format, " (%d,%d,%d,%d)", pvalue[i].rgbRed, pvalue[i].rgbGreen, pvalue[i].rgbBlue, pvalue[i].rgbReserved);
-				buffer += format;
-			}
-			break;
-		}
-		
-		case FIDT_LONG8:	// N x 64-bit unsigned integer 
-		{
-			UINT64 *pvalue = (UINT64 *)FreeImage_GetTagValue(tag);
-
-			sprintf(format, "%ld", pvalue[0]);
-			buffer += format;
-			for(i = 1; i < tag_count; i++) {
-				sprintf(format, "%ld", pvalue[i]);
-				buffer += format;
-			}
-			break;
-		}
-
-		case FIDT_IFD8:		// N x 64-bit unsigned integer (offset)
-		{
-			UINT64 *pvalue = (UINT64 *)FreeImage_GetTagValue(tag);
-
-			sprintf(format, "%X", pvalue[0]);
-			buffer += format;
-			for(i = 1; i < tag_count; i++) {
-				sprintf(format, "%X", pvalue[i]);
-				buffer += format;
-			}
-			break;
-		}
-
-		case FIDT_SLONG8:	// N x 64-bit signed integer
-		{
-			INT64 *pvalue = (INT64 *)FreeImage_GetTagValue(tag);
-
-			sprintf(format, "%ld", pvalue[0]);
-			buffer += format;
-			for(i = 1; i < tag_count; i++) {
-				sprintf(format, "%ld", pvalue[i]);
-				buffer += format;
-			}
-			break;
-		}
-
-		case FIDT_ASCII:	// 8-bit bytes w/ last byte null 
-		case FIDT_UNDEFINED:// 8-bit untyped data 
-		default:
-		{
-			int max_size = MIN((int)FreeImage_GetTagLength(tag), (int)MAX_TEXT_EXTENT);
-			if(max_size == MAX_TEXT_EXTENT)
-				max_size--;
-			memcpy(format, (char*)FreeImage_GetTagValue(tag), max_size);
-			format[max_size] = '\0';
-			buffer += format;
-			break;
-		}
-	}
-
-	return buffer.c_str();
-}
-
-/**
-Convert a Exif tag to a C string
-*/
-static const char* 
-ConvertExifTag(FITAG *tag) {
-	char format[MAX_TEXT_EXTENT];
-	static std::string buffer;
-
-	if(!tag)
-		return NULL;
-
-	buffer.erase();
-
-	// convert the tag value to a string buffer
-
-	switch(FreeImage_GetTagID(tag)) {
-		case TAG_ORIENTATION:
-		{
-			unsigned short orientation = *((unsigned short *)FreeImage_GetTagValue(tag));
-			switch (orientation) {
-				case 1:
-					return "top, left side";
-				case 2:
-					return "top, right side";
-				case 3:
-					return "bottom, right side";
-				case 4:
-					return "bottom, left side";
-				case 5:
-					return "left side, top";
-				case 6:
-					return "right side, top";
-				case 7:
-					return "right side, bottom";
-				case 8:
-					return "left side, bottom";
-				default:
-					break;
-			}
-		}
-		break;
-
-		case TAG_REFERENCE_BLACK_WHITE:
-		{
-			DWORD *pvalue = (DWORD*)FreeImage_GetTagValue(tag);
-			if(FreeImage_GetTagLength(tag) == 48) {
-				// reference black point value and reference white point value (ReferenceBlackWhite)
-				int blackR = 0, whiteR = 0, blackG = 0, whiteG = 0, blackB = 0, whiteB = 0;
-				if(pvalue[1])
-					blackR = (int)(pvalue[0] / pvalue[1]);
-				if(pvalue[3])
-					whiteR = (int)(pvalue[2] / pvalue[3]);
-				if(pvalue[5])
-					blackG = (int)(pvalue[4] / pvalue[5]);
-				if(pvalue[7])
-					whiteG = (int)(pvalue[6] / pvalue[7]);
-				if(pvalue[9])
-					blackB = (int)(pvalue[8] / pvalue[9]);
-				if(pvalue[11])
-					whiteB = (int)(pvalue[10] / pvalue[11]);
-
-				sprintf(format, "[%d,%d,%d] [%d,%d,%d]", blackR, blackG, blackB, whiteR, whiteG, whiteB);
-				buffer += format;
-				return buffer.c_str();
-			}
-
-		}
-		break;
-
-		case TAG_COLOR_SPACE:
-		{
-			unsigned short colorSpace = *((unsigned short *)FreeImage_GetTagValue(tag));
-			if (colorSpace == 1) {
-				return "sRGB";
-			} else if (colorSpace == 65535) {
-				return "Undefined";
-			} else {
-				return "Unknown";
-			}
-		}
-		break;
-
-		case TAG_COMPONENTS_CONFIGURATION:
-		{
-			const char *componentStrings[7] = {"", "Y", "Cb", "Cr", "R", "G", "B"};
-			BYTE *pvalue = (BYTE*)FreeImage_GetTagValue(tag);
-			for(DWORD i = 0; i < MIN((DWORD)4, FreeImage_GetTagCount(tag)); i++) {
-				int j = pvalue[i];
-				if(j > 0 && j < 7)
-					buffer += componentStrings[j];
-			}
-			return buffer.c_str();
-		}
-		break;
-
-		case TAG_COMPRESSED_BITS_PER_PIXEL:
-		{
-			FIRational r(tag);
-			buffer = r.toString();
-			if(buffer == "1")
-				buffer += " bit/pixel";
-			else 
-				buffer += " bits/pixel";
-			return buffer.c_str();
-		}
-		break;
-
-		case TAG_X_RESOLUTION:
-		case TAG_Y_RESOLUTION:
-		case TAG_FOCAL_PLANE_X_RES:
-		case TAG_FOCAL_PLANE_Y_RES:
-		case TAG_BRIGHTNESS_VALUE:
-		case TAG_EXPOSURE_BIAS_VALUE:
-		{
-			FIRational r(tag);
-			buffer = r.toString();
-			return buffer.c_str();
-		}
-		break;
-
-		case TAG_RESOLUTION_UNIT:
-		case TAG_FOCAL_PLANE_UNIT:
-		{
-			unsigned short resolutionUnit = *((unsigned short *)FreeImage_GetTagValue(tag));
-			switch (resolutionUnit) {
-				case 1:
-					return "(No unit)";
-				case 2:
-					return "inches";
-				case 3:
-					return "cm";
-				default:
-					break;
-			}
-		}
-		break;
-
-		case TAG_YCBCR_POSITIONING:
-		{
-			unsigned short yCbCrPosition = *((unsigned short *)FreeImage_GetTagValue(tag));
-			switch (yCbCrPosition) {
-				case 1:
-					return "Center of pixel array";
-				case 2:
-					return "Datum point";
-				default:
-					break;
-			}
-		} 
-		break;
-
-		case TAG_EXPOSURE_TIME:
-		{
-			FIRational r(tag);
-			buffer = r.toString();
-			buffer += " sec";
-			return buffer.c_str();
-		}
-		break;
-
-		case TAG_SHUTTER_SPEED_VALUE:
-		{
-			FIRational r(tag);
-			LONG apexValue = r.longValue();
-			LONG apexPower = 1 << apexValue;
-			sprintf(format, "1/%d sec", (int)apexPower);
-			buffer += format;
-			return buffer.c_str();
-		}
-		break;
-
-		case TAG_APERTURE_VALUE:
-		case TAG_MAX_APERTURE_VALUE:
-		{
-			FIRational r(tag);
-			double apertureApex = r.doubleValue();
-	        double rootTwo = sqrt((double)2);
-			double fStop = pow(rootTwo, apertureApex);
-			sprintf(format, "F%.1f", fStop);
-			buffer += format;
-			return buffer.c_str();
-		}
-		break;
-
-		case TAG_FNUMBER:
-		{
-			FIRational r(tag);
-			double fnumber = r.doubleValue();
-			sprintf(format, "F%.1f", fnumber);
-			buffer += format;
-			return buffer.c_str();
-		}
-		break;
-
-		case TAG_FOCAL_LENGTH:
-		{
-			FIRational r(tag);
-			double focalLength = r.doubleValue();
-			sprintf(format, "%.1f mm", focalLength);
-			buffer += format;
-			return buffer.c_str();
-		}
-		break;
-
-		case TAG_FOCAL_LENGTH_IN_35MM_FILM:
-		{
-			unsigned short focalLength = *((unsigned short *)FreeImage_GetTagValue(tag));
-			sprintf(format, "%hu mm", focalLength);
-			buffer += format;
-			return buffer.c_str();
-		}
-		break;
-
-		case TAG_FLASH:
-		{
-			unsigned short flash = *((unsigned short *)FreeImage_GetTagValue(tag));
-			switch(flash) {
-				case 0x0000:
-					return "Flash did not fire";
-				case 0x0001:
-					return "Flash fired";
-				case 0x0005:
-					return "Strobe return light not detected";
-				case 0x0007:
-					return "Strobe return light detected";
-				case 0x0009:
-					return "Flash fired, compulsory flash mode";
-				case 0x000D:
-					return "Flash fired, compulsory flash mode, return light not detected";
-				case 0x000F:
-					return "Flash fired, compulsory flash mode, return light detected";
-				case 0x0010:
-					return "Flash did not fire, compulsory flash mode";
-				case 0x0018:
-					return "Flash did not fire, auto mode";
-				case 0x0019:
-					return "Flash fired, auto mode";
-				case 0x001D:
-					return "Flash fired, auto mode, return light not detected";
-				case 0x001F:
-					return "Flash fired, auto mode, return light detected";
-				case 0x0020:
-					return "No flash function";
-				case 0x0041:
-					return "Flash fired, red-eye reduction mode";
-				case 0x0045:
-					return "Flash fired, red-eye reduction mode, return light not detected";
-				case 0x0047:
-					return "Flash fired, red-eye reduction mode, return light detected";
-				case 0x0049:
-					return "Flash fired, compulsory flash mode, red-eye reduction mode";
-				case 0x004D:
-					return "Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected";
-				case 0x004F:
-					return "Flash fired, compulsory flash mode, red-eye reduction mode, return light detected";
-				case 0x0059:
-					return "Flash fired, auto mode, red-eye reduction mode";
-				case 0x005D:
-					return "Flash fired, auto mode, return light not detected, red-eye reduction mode";
-				case 0x005F:
-					return "Flash fired, auto mode, return light detected, red-eye reduction mode";
-				default:
-					sprintf(format, "Unknown (%d)", flash);
-					buffer += format;
-					return buffer.c_str();
-			}
-		}
-		break;
-
-		case TAG_SCENE_TYPE:
-		{
-			BYTE sceneType = *((BYTE*)FreeImage_GetTagValue(tag));
-			if (sceneType == 1) {
-				return "Directly photographed image";
-			} else {
-				sprintf(format, "Unknown (%d)", sceneType);
-				buffer += format;
-				return buffer.c_str();
-			}
-		}
-		break;
-
-		case TAG_SUBJECT_DISTANCE:
-		{
-			FIRational r(tag);
-			if(r.getNumerator() == 0xFFFFFFFF) {
-				return "Infinity";
-			} else if(r.getNumerator() == 0) {
-				return "Distance unknown";
-			} else {
-				double distance = r.doubleValue();
-				sprintf(format, "%.3f meters", distance);
-				buffer += format;
-				return buffer.c_str();
-			}
-		}
-		break;
-			
-		case TAG_METERING_MODE:
-		{
-			unsigned short meteringMode = *((unsigned short *)FreeImage_GetTagValue(tag));
-			switch (meteringMode) {
-				case 0:
-					return "Unknown";
-				case 1:
-					return "Average";
-				case 2:
-					return "Center weighted average";
-				case 3:
-					return "Spot";
-				case 4:
-					return "Multi-spot";
-				case 5:
-					return "Multi-segment";
-				case 6:
-					return "Partial";
-				case 255:
-					return "(Other)";
-				default:
-					return "";
-			}
-		}
-		break;
-
-		case TAG_LIGHT_SOURCE:
-		{
-			unsigned short lightSource = *((unsigned short *)FreeImage_GetTagValue(tag));
-			switch (lightSource) {
-				case 0:
-					return "Unknown";
-				case 1:
-					return "Daylight";
-				case 2:
-					return "Fluorescent";
-				case 3:
-					return "Tungsten (incandescent light)";
-				case 4:
-					return "Flash";
-				case 9:
-					return "Fine weather";
-				case 10:
-					return "Cloudy weather";
-				case 11:
-					return "Shade";
-				case 12:
-					return "Daylight fluorescent (D 5700 - 7100K)";
-				case 13:
-					return "Day white fluorescent (N 4600 - 5400K)";
-				case 14:
-					return "Cool white fluorescent (W 3900 - 4500K)";
-				case 15:
-					return "White fluorescent (WW 3200 - 3700K)";
-				case 17:
-					return "Standard light A";
-				case 18:
-					return "Standard light B";
-				case 19:
-					return "Standard light C";
-				case 20:
-					return "D55";
-				case 21:
-					return "D65";
-				case 22:
-					return "D75";
-				case 23:
-					return "D50";
-				case 24:
-					return "ISO studio tungsten";
-				case 255:
-					return "(Other)";
-				default:
-					return "";
-			}
-		}
-		break;
-
-		case TAG_SENSING_METHOD:
-		{
-			unsigned short sensingMethod = *((unsigned short *)FreeImage_GetTagValue(tag));
-
-			switch (sensingMethod) {
-				case 1:
-					return "(Not defined)";
-				case 2:
-					return "One-chip color area sensor";
-				case 3:
-					return "Two-chip color area sensor";
-				case 4:
-					return "Three-chip color area sensor";
-				case 5:
-					return "Color sequential area sensor";
-				case 7:
-					return "Trilinear sensor";
-				case 8:
-					return "Color sequential linear sensor";
-				default:
-					return "";
-			}
-		}
-		break;
-
-		case TAG_FILE_SOURCE:
-		{
-			BYTE fileSource = *((BYTE*)FreeImage_GetTagValue(tag));
-			if (fileSource == 3) {
-				return "Digital Still Camera (DSC)";
-			} else {
-				sprintf(format, "Unknown (%d)", fileSource);
-				buffer += format;
-				return buffer.c_str();
-			}
-        }
-		break;
-
-		case TAG_EXPOSURE_PROGRAM:
-		{
-			unsigned short exposureProgram = *((unsigned short *)FreeImage_GetTagValue(tag));
-
-			switch (exposureProgram) {
-				case 1:
-					return "Manual control";
-				case 2:
-					return "Program normal";
-				case 3:
-					return "Aperture priority";
-				case 4:
-					return "Shutter priority";
-				case 5:
-					return "Program creative (slow program)";
-				case 6:
-					return "Program action (high-speed program)";
-				case 7:
-					return "Portrait mode";
-				case 8:
-					return "Landscape mode";
-				default:
-					sprintf(format, "Unknown program (%d)", exposureProgram);
-					buffer += format;
-					return buffer.c_str();
-			}
-		}
-		break;
-
-		case TAG_CUSTOM_RENDERED:
-		{
-			unsigned short customRendered = *((unsigned short *)FreeImage_GetTagValue(tag));
-
-			switch (customRendered) {
-				case 0:
-					return "Normal process";
-				case 1:
-					return "Custom process";
-				default:
-					sprintf(format, "Unknown rendering (%d)", customRendered);
-					buffer += format;
-					return buffer.c_str();
-			}
-		}
-		break;
-
-		case TAG_EXPOSURE_MODE:
-		{
-			unsigned short exposureMode = *((unsigned short *)FreeImage_GetTagValue(tag));
-
-			switch (exposureMode) {
-				case 0:
-					return "Auto exposure";
-				case 1:
-					return "Manual exposure";
-				case 2:
-					return "Auto bracket";
-				default:
-					sprintf(format, "Unknown mode (%d)", exposureMode);
-					buffer += format;
-					return buffer.c_str();
-			}
-		}
-		break;
-
-		case TAG_WHITE_BALANCE:
-		{
-			unsigned short whiteBalance = *((unsigned short *)FreeImage_GetTagValue(tag));
-
-			switch (whiteBalance) {
-				case 0:
-					return "Auto white balance";
-				case 1:
-					return "Manual white balance";
-				default:
-					sprintf(format, "Unknown (%d)", whiteBalance);
-					buffer += format;
-					return buffer.c_str();
-			}
-		}
-		break;
-
-		case TAG_SCENE_CAPTURE_TYPE:
-		{
-			unsigned short sceneType = *((unsigned short *)FreeImage_GetTagValue(tag));
-
-			switch (sceneType) {
-				case 0:
-					return "Standard";
-				case 1:
-					return "Landscape";
-				case 2:
-					return "Portrait";
-				case 3:
-					return "Night scene";
-				default:
-					sprintf(format, "Unknown (%d)", sceneType);
-					buffer += format;
-					return buffer.c_str();
-			}
-		}
-		break;
-
-		case TAG_GAIN_CONTROL:
-		{
-			unsigned short gainControl = *((unsigned short *)FreeImage_GetTagValue(tag));
-
-			switch (gainControl) {
-				case 0:
-					return "None";
-				case 1:
-					return "Low gain up";
-				case 2:
-					return "High gain up";
-				case 3:
-					return "Low gain down";
-				case 4:
-					return "High gain down";
-				default:
-					sprintf(format, "Unknown (%d)", gainControl);
-					buffer += format;
-					return buffer.c_str();
-			}
-		}
-		break;
-
-		case TAG_CONTRAST:
-		{
-			unsigned short contrast = *((unsigned short *)FreeImage_GetTagValue(tag));
-
-			switch (contrast) {
-				case 0:
-					return "Normal";
-				case 1:
-					return "Soft";
-				case 2:
-					return "Hard";
-				default:
-					sprintf(format, "Unknown (%d)", contrast);
-					buffer += format;
-					return buffer.c_str();
-			}
-		}
-		break;
-
-		case TAG_SATURATION:
-		{
-			unsigned short saturation = *((unsigned short *)FreeImage_GetTagValue(tag));
-
-			switch (saturation) {
-				case 0:
-					return "Normal";
-				case 1:
-					return "Low saturation";
-				case 2:
-					return "High saturation";
-				default:
-					sprintf(format, "Unknown (%d)", saturation);
-					buffer += format;
-					return buffer.c_str();
-			}
-		}
-		break;
-
-		case TAG_SHARPNESS:
-		{
-			unsigned short sharpness = *((unsigned short *)FreeImage_GetTagValue(tag));
-
-			switch (sharpness) {
-				case 0:
-					return "Normal";
-				case 1:
-					return "Soft";
-				case 2:
-					return "Hard";
-				default:
-					sprintf(format, "Unknown (%d)", sharpness);
-					buffer += format;
-					return buffer.c_str();
-			}
-		}
-		break;
-
-		case TAG_SUBJECT_DISTANCE_RANGE:
-		{
-			unsigned short distanceRange = *((unsigned short *)FreeImage_GetTagValue(tag));
-
-			switch (distanceRange) {
-				case 0:
-					return "unknown";
-				case 1:
-					return "Macro";
-				case 2:
-					return "Close view";
-				case 3:
-					return "Distant view";
-				default:
-					sprintf(format, "Unknown (%d)", distanceRange);
-					buffer += format;
-					return buffer.c_str();
-			}
-		}
-		break;
-
-		case TAG_ISO_SPEED_RATINGS:
-		{
-			unsigned short isoEquiv = *((unsigned short *)FreeImage_GetTagValue(tag));
-			if (isoEquiv < 50) {
-				isoEquiv *= 200;
-			}
-			sprintf(format, "%d", isoEquiv);
-			buffer += format;
-			return buffer.c_str();
-		}
-		break;
-
-		case TAG_USER_COMMENT:
-		{
-			// first 8 bytes are used to define an ID code
-			// we assume this is an ASCII string
-			const BYTE *userComment = (BYTE*)FreeImage_GetTagValue(tag);
-			for(DWORD i = 8; i < FreeImage_GetTagLength(tag); i++) {
-				buffer += userComment[i];
-			}
-			buffer += '\0';
-			return buffer.c_str();
-		}
-		break;
-
-		case TAG_COMPRESSION:
-		{
-			WORD compression = *((WORD*)FreeImage_GetTagValue(tag));
-			switch(compression) {
-				case TAG_COMPRESSION_NONE:
-					sprintf(format, "dump mode (%d)", compression);
-					break;
-				case TAG_COMPRESSION_CCITTRLE:
-					sprintf(format, "CCITT modified Huffman RLE (%d)", compression);
-					break;
-				case TAG_COMPRESSION_CCITTFAX3:
-					sprintf(format, "CCITT Group 3 fax encoding (%d)", compression);
-					break;
-				/*
-				case TAG_COMPRESSION_CCITT_T4:
-					sprintf(format, "CCITT T.4 (TIFF 6 name) (%d)", compression);
-					break;
-				*/
-				case TAG_COMPRESSION_CCITTFAX4:
-					sprintf(format, "CCITT Group 4 fax encoding (%d)", compression);
-					break;
-				/*
-				case TAG_COMPRESSION_CCITT_T6:
-					sprintf(format, "CCITT T.6 (TIFF 6 name) (%d)", compression);
-					break;
-				*/
-				case TAG_COMPRESSION_LZW:
-					sprintf(format, "LZW (%d)", compression);
-					break;
-				case TAG_COMPRESSION_OJPEG:
-					sprintf(format, "!6.0 JPEG (%d)", compression);
-					break;
-				case TAG_COMPRESSION_JPEG:
-					sprintf(format, "JPEG (%d)", compression);
-					break;
-				case TAG_COMPRESSION_NEXT:
-					sprintf(format, "NeXT 2-bit RLE (%d)", compression);
-					break;
-				case TAG_COMPRESSION_CCITTRLEW:
-					sprintf(format, "CCITTRLEW (%d)", compression);
-					break;
-				case TAG_COMPRESSION_PACKBITS:
-					sprintf(format, "PackBits Macintosh RLE (%d)", compression);
-					break;
-				case TAG_COMPRESSION_THUNDERSCAN:
-					sprintf(format, "ThunderScan RLE (%d)", compression);
-					break;
-				case TAG_COMPRESSION_PIXARFILM:
-					sprintf(format, "Pixar companded 10bit LZW (%d)", compression);
-					break;
-				case TAG_COMPRESSION_PIXARLOG:
-					sprintf(format, "Pixar companded 11bit ZIP (%d)", compression);
-					break;
-				case TAG_COMPRESSION_DEFLATE:
-					sprintf(format, "Deflate compression (%d)", compression);
-					break;
-				case TAG_COMPRESSION_ADOBE_DEFLATE:
-					sprintf(format, "Adobe Deflate compression (%d)", compression);
-					break;
-				case TAG_COMPRESSION_DCS:
-					sprintf(format, "Kodak DCS encoding (%d)", compression);
-					break;
-				case TAG_COMPRESSION_JBIG:
-					sprintf(format, "ISO JBIG (%d)", compression);
-					break;
-				case TAG_COMPRESSION_SGILOG:
-					sprintf(format, "SGI Log Luminance RLE (%d)", compression);
-					break;
-				case TAG_COMPRESSION_SGILOG24:
-					sprintf(format, "SGI Log 24-bit packed (%d)", compression);
-					break;
-				case TAG_COMPRESSION_JP2000:
-					sprintf(format, "Leadtools JPEG2000 (%d)", compression);
-					break;
-				case TAG_COMPRESSION_LZMA:
-					sprintf(format, "LZMA2 (%d)", compression);
-					break;
-				default:
-					sprintf(format, "Unknown type (%d)", compression);
-					break;
-			}
-
-			buffer += format;
-			return buffer.c_str();
-		}
-		break;
-	}
-
-	return ConvertAnyTag(tag);
-}
-
-/**
-Convert a Exif GPS tag to a C string
-*/
-static const char* 
-ConvertExifGPSTag(FITAG *tag) {
-	char format[MAX_TEXT_EXTENT];
-	static std::string buffer;
-
-	if(!tag)
-		return NULL;
-
-	buffer.erase();
-
-	// convert the tag value to a string buffer
-
-	switch(FreeImage_GetTagID(tag)) {
-		case TAG_GPS_LATITUDE:
-		case TAG_GPS_LONGITUDE:
-		case TAG_GPS_TIME_STAMP:
-		{
-			DWORD *pvalue = (DWORD*)FreeImage_GetTagValue(tag);
-			if(FreeImage_GetTagLength(tag) == 24) {
-				// dd:mm:ss or hh:mm:ss
-				int dd = 0, mm = 0;
-				double ss = 0;
-
-				// convert to seconds
-				if(pvalue[1])
-					ss += ((double)pvalue[0] / (double)pvalue[1]) * 3600;
-				if(pvalue[3])
-					ss += ((double)pvalue[2] / (double)pvalue[3]) * 60;
-				if(pvalue[5])
-					ss += ((double)pvalue[4] / (double)pvalue[5]);
-				
-				// convert to dd:mm:ss.ss
-				dd = (int)(ss / 3600);
-				mm = (int)(ss / 60) - dd * 60;
-				ss = ss - dd * 3600 - mm * 60;
-
-				sprintf(format, "%d:%d:%.2f", dd, mm, ss);
-				buffer += format;
-				return buffer.c_str();
-			}
-		}
-		break;
-
-		case TAG_GPS_VERSION_ID:
-		case TAG_GPS_LATITUDE_REF:
-		case TAG_GPS_LONGITUDE_REF:
-		case TAG_GPS_ALTITUDE_REF:
-		case TAG_GPS_ALTITUDE:
-		case TAG_GPS_SATELLITES:
-		case TAG_GPS_STATUS:
-		case TAG_GPS_MEASURE_MODE:
-		case TAG_GPS_DOP:
-		case TAG_GPS_SPEED_REF:
-		case TAG_GPS_SPEED:
-		case TAG_GPS_TRACK_REF:
-		case TAG_GPS_TRACK:
-		case TAG_GPS_IMG_DIRECTION_REF:
-		case TAG_GPS_IMG_DIRECTION:
-		case TAG_GPS_MAP_DATUM:
-		case TAG_GPS_DEST_LATITUDE_REF:
-		case TAG_GPS_DEST_LATITUDE:
-		case TAG_GPS_DEST_LONGITUDE_REF:
-		case TAG_GPS_DEST_LONGITUDE:
-		case TAG_GPS_DEST_BEARING_REF:
-		case TAG_GPS_DEST_BEARING:
-		case TAG_GPS_DEST_DISTANCE_REF:
-		case TAG_GPS_DEST_DISTANCE:
-		case TAG_GPS_PROCESSING_METHOD:
-		case TAG_GPS_AREA_INFORMATION:
-		case TAG_GPS_DATE_STAMP:
-		case TAG_GPS_DIFFERENTIAL:
-			break;
-	}
-
-	return ConvertAnyTag(tag);
-}
-
-// ==========================================================
-// Tag to string conversion function
-//
-
-const char* DLL_CALLCONV 
-FreeImage_TagToString(FREE_IMAGE_MDMODEL model, FITAG *tag, char *Make) {
-	switch(model) {
-		case FIMD_EXIF_MAIN:
-		case FIMD_EXIF_EXIF:
-			return ConvertExifTag(tag);
-
-		case FIMD_EXIF_GPS:
-			return ConvertExifGPSTag(tag);
-
-		case FIMD_EXIF_MAKERNOTE:
-			// We should use the Make string to select an appropriate conversion function
-			// TO DO ...
-			break;
-
-		case FIMD_EXIF_INTEROP:
-		default:
-			break;
-	}
-
-	return ConvertAnyTag(tag);
-}
-
+// ==========================================================
+// Tag to string conversion functions
+//
+// Design and implementation by
+// - Herv� Drolon <drolon at infonie.fr>
+//
+// This file is part of FreeImage 3
+//
+// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
+// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
+// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
+// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
+// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
+// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
+// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+// THIS DISCLAIMER.
+//
+// Use at your own risk!
+// ==========================================================
+
+#ifdef _MSC_VER 
+#pragma warning (disable : 4786) // identifier was truncated to 'number' characters
+#endif
+
+#include "FreeImage.h"
+#include "Utilities.h"
+#include "FreeImageTag.h"
+#include "FIRational.h"
+
+#define MAX_TEXT_EXTENT	512
+
+/**
+Convert a tag to a C string
+*/
+static const char* 
+ConvertAnyTag(FITAG *tag) {
+	char format[MAX_TEXT_EXTENT];
+	static std::string buffer;
+	DWORD i;
+
+	if(!tag)
+		return NULL;
+
+	buffer.erase();
+	
+	// convert the tag value to a string buffer
+
+	FREE_IMAGE_MDTYPE tag_type = FreeImage_GetTagType(tag);
+	DWORD tag_count = FreeImage_GetTagCount(tag);
+
+	switch(tag_type) {
+		case FIDT_BYTE:		// N x 8-bit unsigned integer 
+		{
+			BYTE *pvalue = (BYTE*)FreeImage_GetTagValue(tag);
+
+			sprintf(format, "%ld",	(LONG) pvalue[0]);
+			buffer += format;
+			for(i = 1; i < tag_count; i++) {
+				sprintf(format, " %ld",	(LONG) pvalue[i]);
+				buffer += format;
+			}
+			break;
+		}
+		case FIDT_SHORT:	// N x 16-bit unsigned integer 
+		{
+			unsigned short *pvalue = (unsigned short *)FreeImage_GetTagValue(tag);
+
+			sprintf(format, "%hu", pvalue[0]);
+			buffer += format;
+			for(i = 1; i < tag_count; i++) {
+				sprintf(format, " %hu",	pvalue[i]);
+				buffer += format;
+			}
+			break;
+		}
+		case FIDT_LONG:		// N x 32-bit unsigned integer 
+		{
+			DWORD *pvalue = (DWORD *)FreeImage_GetTagValue(tag);
+
+			sprintf(format, "%lu", pvalue[0]);
+			buffer += format;
+			for(i = 1; i < tag_count; i++) {
+				sprintf(format, " %lu",	pvalue[i]);
+				buffer += format;
+			}
+			break;
+		}
+		case FIDT_RATIONAL: // N x 64-bit unsigned fraction 
+		{
+			DWORD *pvalue = (DWORD*)FreeImage_GetTagValue(tag);
+
+			sprintf(format, "%ld/%ld", pvalue[0], pvalue[1]);
+			buffer += format;
+			for(i = 1; i < tag_count; i++) {
+				sprintf(format, " %ld/%ld", pvalue[2*i], pvalue[2*i+1]);
+				buffer += format;
+			}
+			break;
+		}
+		case FIDT_SBYTE:	// N x 8-bit signed integer 
+		{
+			char *pvalue = (char*)FreeImage_GetTagValue(tag);
+
+			sprintf(format, "%ld",	(LONG) pvalue[0]);
+			buffer += format;
+			for(i = 1; i < tag_count; i++) {
+				sprintf(format, " %ld",	(LONG) pvalue[i]);
+				buffer += format;
+			}
+			break;
+		}
+		case FIDT_SSHORT:	// N x 16-bit signed integer 
+		{
+			short *pvalue = (short *)FreeImage_GetTagValue(tag);
+
+			sprintf(format, "%hd", pvalue[0]);
+			buffer += format;
+			for(i = 1; i < tag_count; i++) {
+				sprintf(format, " %hd",	pvalue[i]);
+				buffer += format;
+			}
+			break;
+		}
+		case FIDT_SLONG:	// N x 32-bit signed integer 
+		{
+			LONG *pvalue = (LONG *)FreeImage_GetTagValue(tag);
+
+			sprintf(format, "%ld", pvalue[0]);
+			buffer += format;
+			for(i = 1; i < tag_count; i++) {
+				sprintf(format, " %ld",	pvalue[i]);
+				buffer += format;
+			}
+			break;
+		}
+		case FIDT_SRATIONAL:// N x 64-bit signed fraction 
+		{
+			LONG *pvalue = (LONG*)FreeImage_GetTagValue(tag);
+
+			sprintf(format, "%ld/%ld", pvalue[0], pvalue[1]);
+			buffer += format;
+			for(i = 1; i < tag_count; i++) {
+				sprintf(format, " %ld/%ld", pvalue[2*i], pvalue[2*i+1]);
+				buffer += format;
+			}
+			break;
+		}
+		case FIDT_FLOAT:	// N x 32-bit IEEE floating point 
+		{
+			float *pvalue = (float *)FreeImage_GetTagValue(tag);
+
+			sprintf(format, "%f", (double) pvalue[0]);
+			buffer += format;
+			for(i = 1; i < tag_count; i++) {
+				sprintf(format, "%f", (double) pvalue[i]);
+				buffer += format;
+			}
+			break;
+		}
+		case FIDT_DOUBLE:	// N x 64-bit IEEE floating point 
+		{
+			double *pvalue = (double *)FreeImage_GetTagValue(tag);
+
+			sprintf(format, "%f", pvalue[0]);
+			buffer += format;
+			for(i = 1; i < tag_count; i++) {
+				sprintf(format, "%f", pvalue[i]);
+				buffer += format;
+			}
+			break;
+		}
+		case FIDT_IFD:		// N x 32-bit unsigned integer (offset) 
+		{
+			DWORD *pvalue = (DWORD *)FreeImage_GetTagValue(tag);
+
+			sprintf(format, "%X", pvalue[0]);
+			buffer += format;
+			for(i = 1; i < tag_count; i++) {
+				sprintf(format, " %X",	pvalue[i]);
+				buffer += format;
+			}
+			break;
+		}
+		case FIDT_PALETTE:	// N x 32-bit RGBQUAD 
+		{
+			RGBQUAD *pvalue = (RGBQUAD *)FreeImage_GetTagValue(tag);
+
+			sprintf(format, "(%d,%d,%d,%d)", pvalue[0].rgbRed, pvalue[0].rgbGreen, pvalue[0].rgbBlue, pvalue[0].rgbReserved);
+			buffer += format;
+			for(i = 1; i < tag_count; i++) {
+				sprintf(format, " (%d,%d,%d,%d)", pvalue[i].rgbRed, pvalue[i].rgbGreen, pvalue[i].rgbBlue, pvalue[i].rgbReserved);
+				buffer += format;
+			}
+			break;
+		}
+		
+		case FIDT_LONG8:	// N x 64-bit unsigned integer 
+		{
+			UINT64 *pvalue = (UINT64 *)FreeImage_GetTagValue(tag);
+
+			sprintf(format, "%ld", pvalue[0]);
+			buffer += format;
+			for(i = 1; i < tag_count; i++) {
+				sprintf(format, "%ld", pvalue[i]);
+				buffer += format;
+			}
+			break;
+		}
+
+		case FIDT_IFD8:		// N x 64-bit unsigned integer (offset)
+		{
+			UINT64 *pvalue = (UINT64 *)FreeImage_GetTagValue(tag);
+
+			sprintf(format, "%X", pvalue[0]);
+			buffer += format;
+			for(i = 1; i < tag_count; i++) {
+				sprintf(format, "%X", pvalue[i]);
+				buffer += format;
+			}
+			break;
+		}
+
+		case FIDT_SLONG8:	// N x 64-bit signed integer
+		{
+			INT64 *pvalue = (INT64 *)FreeImage_GetTagValue(tag);
+
+			sprintf(format, "%ld", pvalue[0]);
+			buffer += format;
+			for(i = 1; i < tag_count; i++) {
+				sprintf(format, "%ld", pvalue[i]);
+				buffer += format;
+			}
+			break;
+		}
+
+		case FIDT_ASCII:	// 8-bit bytes w/ last byte null 
+		case FIDT_UNDEFINED:// 8-bit untyped data 
+		default:
+		{
+			int max_size = MIN((int)FreeImage_GetTagLength(tag), (int)MAX_TEXT_EXTENT);
+			if(max_size == MAX_TEXT_EXTENT)
+				max_size--;
+			memcpy(format, (char*)FreeImage_GetTagValue(tag), max_size);
+			format[max_size] = '\0';
+			buffer += format;
+			break;
+		}
+	}
+
+	return buffer.c_str();
+}
+
+/**
+Convert a Exif tag to a C string
+*/
+static const char* 
+ConvertExifTag(FITAG *tag) {
+	char format[MAX_TEXT_EXTENT];
+	static std::string buffer;
+
+	if(!tag)
+		return NULL;
+
+	buffer.erase();
+
+	// convert the tag value to a string buffer
+
+	switch(FreeImage_GetTagID(tag)) {
+		case TAG_ORIENTATION:
+		{
+			unsigned short orientation = *((unsigned short *)FreeImage_GetTagValue(tag));
+			switch (orientation) {
+				case 1:
+					return "top, left side";
+				case 2:
+					return "top, right side";
+				case 3:
+					return "bottom, right side";
+				case 4:
+					return "bottom, left side";
+				case 5:
+					return "left side, top";
+				case 6:
+					return "right side, top";
+				case 7:
+					return "right side, bottom";
+				case 8:
+					return "left side, bottom";
+				default:
+					break;
+			}
+		}
+		break;
+
+		case TAG_REFERENCE_BLACK_WHITE:
+		{
+			DWORD *pvalue = (DWORD*)FreeImage_GetTagValue(tag);
+			if(FreeImage_GetTagLength(tag) == 48) {
+				// reference black point value and reference white point value (ReferenceBlackWhite)
+				int blackR = 0, whiteR = 0, blackG = 0, whiteG = 0, blackB = 0, whiteB = 0;
+				if(pvalue[1])
+					blackR = (int)(pvalue[0] / pvalue[1]);
+				if(pvalue[3])
+					whiteR = (int)(pvalue[2] / pvalue[3]);
+				if(pvalue[5])
+					blackG = (int)(pvalue[4] / pvalue[5]);
+				if(pvalue[7])
+					whiteG = (int)(pvalue[6] / pvalue[7]);
+				if(pvalue[9])
+					blackB = (int)(pvalue[8] / pvalue[9]);
+				if(pvalue[11])
+					whiteB = (int)(pvalue[10] / pvalue[11]);
+
+				sprintf(format, "[%d,%d,%d] [%d,%d,%d]", blackR, blackG, blackB, whiteR, whiteG, whiteB);
+				buffer += format;
+				return buffer.c_str();
+			}
+
+		}
+		break;
+
+		case TAG_COLOR_SPACE:
+		{
+			unsigned short colorSpace = *((unsigned short *)FreeImage_GetTagValue(tag));
+			if (colorSpace == 1) {
+				return "sRGB";
+			} else if (colorSpace == 65535) {
+				return "Undefined";
+			} else {
+				return "Unknown";
+			}
+		}
+		break;
+
+		case TAG_COMPONENTS_CONFIGURATION:
+		{
+			const char *componentStrings[7] = {"", "Y", "Cb", "Cr", "R", "G", "B"};
+			BYTE *pvalue = (BYTE*)FreeImage_GetTagValue(tag);
+			for(DWORD i = 0; i < MIN((DWORD)4, FreeImage_GetTagCount(tag)); i++) {
+				int j = pvalue[i];
+				if(j > 0 && j < 7)
+					buffer += componentStrings[j];
+			}
+			return buffer.c_str();
+		}
+		break;
+
+		case TAG_COMPRESSED_BITS_PER_PIXEL:
+		{
+			FIRational r(tag);
+			buffer = r.toString();
+			if(buffer == "1")
+				buffer += " bit/pixel";
+			else 
+				buffer += " bits/pixel";
+			return buffer.c_str();
+		}
+		break;
+
+		case TAG_X_RESOLUTION:
+		case TAG_Y_RESOLUTION:
+		case TAG_FOCAL_PLANE_X_RES:
+		case TAG_FOCAL_PLANE_Y_RES:
+		case TAG_BRIGHTNESS_VALUE:
+		case TAG_EXPOSURE_BIAS_VALUE:
+		{
+			FIRational r(tag);
+			buffer = r.toString();
+			return buffer.c_str();
+		}
+		break;
+
+		case TAG_RESOLUTION_UNIT:
+		case TAG_FOCAL_PLANE_UNIT:
+		{
+			unsigned short resolutionUnit = *((unsigned short *)FreeImage_GetTagValue(tag));
+			switch (resolutionUnit) {
+				case 1:
+					return "(No unit)";
+				case 2:
+					return "inches";
+				case 3:
+					return "cm";
+				default:
+					break;
+			}
+		}
+		break;
+
+		case TAG_YCBCR_POSITIONING:
+		{
+			unsigned short yCbCrPosition = *((unsigned short *)FreeImage_GetTagValue(tag));
+			switch (yCbCrPosition) {
+				case 1:
+					return "Center of pixel array";
+				case 2:
+					return "Datum point";
+				default:
+					break;
+			}
+		} 
+		break;
+
+		case TAG_EXPOSURE_TIME:
+		{
+			FIRational r(tag);
+			buffer = r.toString();
+			buffer += " sec";
+			return buffer.c_str();
+		}
+		break;
+
+		case TAG_SHUTTER_SPEED_VALUE:
+		{
+			FIRational r(tag);
+			LONG apexValue = r.longValue();
+			LONG apexPower = 1 << apexValue;
+			sprintf(format, "1/%d sec", (int)apexPower);
+			buffer += format;
+			return buffer.c_str();
+		}
+		break;
+
+		case TAG_APERTURE_VALUE:
+		case TAG_MAX_APERTURE_VALUE:
+		{
+			FIRational r(tag);
+			double apertureApex = r.doubleValue();
+	        double rootTwo = sqrt((double)2);
+			double fStop = pow(rootTwo, apertureApex);
+			sprintf(format, "F%.1f", fStop);
+			buffer += format;
+			return buffer.c_str();
+		}
+		break;
+
+		case TAG_FNUMBER:
+		{
+			FIRational r(tag);
+			double fnumber = r.doubleValue();
+			sprintf(format, "F%.1f", fnumber);
+			buffer += format;
+			return buffer.c_str();
+		}
+		break;
+
+		case TAG_FOCAL_LENGTH:
+		{
+			FIRational r(tag);
+			double focalLength = r.doubleValue();
+			sprintf(format, "%.1f mm", focalLength);
+			buffer += format;
+			return buffer.c_str();
+		}
+		break;
+
+		case TAG_FOCAL_LENGTH_IN_35MM_FILM:
+		{
+			unsigned short focalLength = *((unsigned short *)FreeImage_GetTagValue(tag));
+			sprintf(format, "%hu mm", focalLength);
+			buffer += format;
+			return buffer.c_str();
+		}
+		break;
+
+		case TAG_FLASH:
+		{
+			unsigned short flash = *((unsigned short *)FreeImage_GetTagValue(tag));
+			switch(flash) {
+				case 0x0000:
+					return "Flash did not fire";
+				case 0x0001:
+					return "Flash fired";
+				case 0x0005:
+					return "Strobe return light not detected";
+				case 0x0007:
+					return "Strobe return light detected";
+				case 0x0009:
+					return "Flash fired, compulsory flash mode";
+				case 0x000D:
+					return "Flash fired, compulsory flash mode, return light not detected";
+				case 0x000F:
+					return "Flash fired, compulsory flash mode, return light detected";
+				case 0x0010:
+					return "Flash did not fire, compulsory flash mode";
+				case 0x0018:
+					return "Flash did not fire, auto mode";
+				case 0x0019:
+					return "Flash fired, auto mode";
+				case 0x001D:
+					return "Flash fired, auto mode, return light not detected";
+				case 0x001F:
+					return "Flash fired, auto mode, return light detected";
+				case 0x0020:
+					return "No flash function";
+				case 0x0041:
+					return "Flash fired, red-eye reduction mode";
+				case 0x0045:
+					return "Flash fired, red-eye reduction mode, return light not detected";
+				case 0x0047:
+					return "Flash fired, red-eye reduction mode, return light detected";
+				case 0x0049:
+					return "Flash fired, compulsory flash mode, red-eye reduction mode";
+				case 0x004D:
+					return "Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected";
+				case 0x004F:
+					return "Flash fired, compulsory flash mode, red-eye reduction mode, return light detected";
+				case 0x0059:
+					return "Flash fired, auto mode, red-eye reduction mode";
+				case 0x005D:
+					return "Flash fired, auto mode, return light not detected, red-eye reduction mode";
+				case 0x005F:
+					return "Flash fired, auto mode, return light detected, red-eye reduction mode";
+				default:
+					sprintf(format, "Unknown (%d)", flash);
+					buffer += format;
+					return buffer.c_str();
+			}
+		}
+		break;
+
+		case TAG_SCENE_TYPE:
+		{
+			BYTE sceneType = *((BYTE*)FreeImage_GetTagValue(tag));
+			if (sceneType == 1) {
+				return "Directly photographed image";
+			} else {
+				sprintf(format, "Unknown (%d)", sceneType);
+				buffer += format;
+				return buffer.c_str();
+			}
+		}
+		break;
+
+		case TAG_SUBJECT_DISTANCE:
+		{
+			FIRational r(tag);
+			if(r.getNumerator() == 0xFFFFFFFF) {
+				return "Infinity";
+			} else if(r.getNumerator() == 0) {
+				return "Distance unknown";
+			} else {
+				double distance = r.doubleValue();
+				sprintf(format, "%.3f meters", distance);
+				buffer += format;
+				return buffer.c_str();
+			}
+		}
+		break;
+			
+		case TAG_METERING_MODE:
+		{
+			unsigned short meteringMode = *((unsigned short *)FreeImage_GetTagValue(tag));
+			switch (meteringMode) {
+				case 0:
+					return "Unknown";
+				case 1:
+					return "Average";
+				case 2:
+					return "Center weighted average";
+				case 3:
+					return "Spot";
+				case 4:
+					return "Multi-spot";
+				case 5:
+					return "Multi-segment";
+				case 6:
+					return "Partial";
+				case 255:
+					return "(Other)";
+				default:
+					return "";
+			}
+		}
+		break;
+
+		case TAG_LIGHT_SOURCE:
+		{
+			unsigned short lightSource = *((unsigned short *)FreeImage_GetTagValue(tag));
+			switch (lightSource) {
+				case 0:
+					return "Unknown";
+				case 1:
+					return "Daylight";
+				case 2:
+					return "Fluorescent";
+				case 3:
+					return "Tungsten (incandescent light)";
+				case 4:
+					return "Flash";
+				case 9:
+					return "Fine weather";
+				case 10:
+					return "Cloudy weather";
+				case 11:
+					return "Shade";
+				case 12:
+					return "Daylight fluorescent (D 5700 - 7100K)";
+				case 13:
+					return "Day white fluorescent (N 4600 - 5400K)";
+				case 14:
+					return "Cool white fluorescent (W 3900 - 4500K)";
+				case 15:
+					return "White fluorescent (WW 3200 - 3700K)";
+				case 17:
+					return "Standard light A";
+				case 18:
+					return "Standard light B";
+				case 19:
+					return "Standard light C";
+				case 20:
+					return "D55";
+				case 21:
+					return "D65";
+				case 22:
+					return "D75";
+				case 23:
+					return "D50";
+				case 24:
+					return "ISO studio tungsten";
+				case 255:
+					return "(Other)";
+				default:
+					return "";
+			}
+		}
+		break;
+
+		case TAG_SENSING_METHOD:
+		{
+			unsigned short sensingMethod = *((unsigned short *)FreeImage_GetTagValue(tag));
+
+			switch (sensingMethod) {
+				case 1:
+					return "(Not defined)";
+				case 2:
+					return "One-chip color area sensor";
+				case 3:
+					return "Two-chip color area sensor";
+				case 4:
+					return "Three-chip color area sensor";
+				case 5:
+					return "Color sequential area sensor";
+				case 7:
+					return "Trilinear sensor";
+				case 8:
+					return "Color sequential linear sensor";
+				default:
+					return "";
+			}
+		}
+		break;
+
+		case TAG_FILE_SOURCE:
+		{
+			BYTE fileSource = *((BYTE*)FreeImage_GetTagValue(tag));
+			if (fileSource == 3) {
+				return "Digital Still Camera (DSC)";
+			} else {
+				sprintf(format, "Unknown (%d)", fileSource);
+				buffer += format;
+				return buffer.c_str();
+			}
+        }
+		break;
+
+		case TAG_EXPOSURE_PROGRAM:
+		{
+			unsigned short exposureProgram = *((unsigned short *)FreeImage_GetTagValue(tag));
+
+			switch (exposureProgram) {
+				case 1:
+					return "Manual control";
+				case 2:
+					return "Program normal";
+				case 3:
+					return "Aperture priority";
+				case 4:
+					return "Shutter priority";
+				case 5:
+					return "Program creative (slow program)";
+				case 6:
+					return "Program action (high-speed program)";
+				case 7:
+					return "Portrait mode";
+				case 8:
+					return "Landscape mode";
+				default:
+					sprintf(format, "Unknown program (%d)", exposureProgram);
+					buffer += format;
+					return buffer.c_str();
+			}
+		}
+		break;
+
+		case TAG_CUSTOM_RENDERED:
+		{
+			unsigned short customRendered = *((unsigned short *)FreeImage_GetTagValue(tag));
+
+			switch (customRendered) {
+				case 0:
+					return "Normal process";
+				case 1:
+					return "Custom process";
+				default:
+					sprintf(format, "Unknown rendering (%d)", customRendered);
+					buffer += format;
+					return buffer.c_str();
+			}
+		}
+		break;
+
+		case TAG_EXPOSURE_MODE:
+		{
+			unsigned short exposureMode = *((unsigned short *)FreeImage_GetTagValue(tag));
+
+			switch (exposureMode) {
+				case 0:
+					return "Auto exposure";
+				case 1:
+					return "Manual exposure";
+				case 2:
+					return "Auto bracket";
+				default:
+					sprintf(format, "Unknown mode (%d)", exposureMode);
+					buffer += format;
+					return buffer.c_str();
+			}
+		}
+		break;
+
+		case TAG_WHITE_BALANCE:
+		{
+			unsigned short whiteBalance = *((unsigned short *)FreeImage_GetTagValue(tag));
+
+			switch (whiteBalance) {
+				case 0:
+					return "Auto white balance";
+				case 1:
+					return "Manual white balance";
+				default:
+					sprintf(format, "Unknown (%d)", whiteBalance);
+					buffer += format;
+					return buffer.c_str();
+			}
+		}
+		break;
+
+		case TAG_SCENE_CAPTURE_TYPE:
+		{
+			unsigned short sceneType = *((unsigned short *)FreeImage_GetTagValue(tag));
+
+			switch (sceneType) {
+				case 0:
+					return "Standard";
+				case 1:
+					return "Landscape";
+				case 2:
+					return "Portrait";
+				case 3:
+					return "Night scene";
+				default:
+					sprintf(format, "Unknown (%d)", sceneType);
+					buffer += format;
+					return buffer.c_str();
+			}
+		}
+		break;
+
+		case TAG_GAIN_CONTROL:
+		{
+			unsigned short gainControl = *((unsigned short *)FreeImage_GetTagValue(tag));
+
+			switch (gainControl) {
+				case 0:
+					return "None";
+				case 1:
+					return "Low gain up";
+				case 2:
+					return "High gain up";
+				case 3:
+					return "Low gain down";
+				case 4:
+					return "High gain down";
+				default:
+					sprintf(format, "Unknown (%d)", gainControl);
+					buffer += format;
+					return buffer.c_str();
+			}
+		}
+		break;
+
+		case TAG_CONTRAST:
+		{
+			unsigned short contrast = *((unsigned short *)FreeImage_GetTagValue(tag));
+
+			switch (contrast) {
+				case 0:
+					return "Normal";
+				case 1:
+					return "Soft";
+				case 2:
+					return "Hard";
+				default:
+					sprintf(format, "Unknown (%d)", contrast);
+					buffer += format;
+					return buffer.c_str();
+			}
+		}
+		break;
+
+		case TAG_SATURATION:
+		{
+			unsigned short saturation = *((unsigned short *)FreeImage_GetTagValue(tag));
+
+			switch (saturation) {
+				case 0:
+					return "Normal";
+				case 1:
+					return "Low saturation";
+				case 2:
+					return "High saturation";
+				default:
+					sprintf(format, "Unknown (%d)", saturation);
+					buffer += format;
+					return buffer.c_str();
+			}
+		}
+		break;
+
+		case TAG_SHARPNESS:
+		{
+			unsigned short sharpness = *((unsigned short *)FreeImage_GetTagValue(tag));
+
+			switch (sharpness) {
+				case 0:
+					return "Normal";
+				case 1:
+					return "Soft";
+				case 2:
+					return "Hard";
+				default:
+					sprintf(format, "Unknown (%d)", sharpness);
+					buffer += format;
+					return buffer.c_str();
+			}
+		}
+		break;
+
+		case TAG_SUBJECT_DISTANCE_RANGE:
+		{
+			unsigned short distanceRange = *((unsigned short *)FreeImage_GetTagValue(tag));
+
+			switch (distanceRange) {
+				case 0:
+					return "unknown";
+				case 1:
+					return "Macro";
+				case 2:
+					return "Close view";
+				case 3:
+					return "Distant view";
+				default:
+					sprintf(format, "Unknown (%d)", distanceRange);
+					buffer += format;
+					return buffer.c_str();
+			}
+		}
+		break;
+
+		case TAG_ISO_SPEED_RATINGS:
+		{
+			unsigned short isoEquiv = *((unsigned short *)FreeImage_GetTagValue(tag));
+			if (isoEquiv < 50) {
+				isoEquiv *= 200;
+			}
+			sprintf(format, "%d", isoEquiv);
+			buffer += format;
+			return buffer.c_str();
+		}
+		break;
+
+		case TAG_USER_COMMENT:
+		{
+			// first 8 bytes are used to define an ID code
+			// we assume this is an ASCII string
+			const BYTE *userComment = (BYTE*)FreeImage_GetTagValue(tag);
+			for(DWORD i = 8; i < FreeImage_GetTagLength(tag); i++) {
+				buffer += userComment[i];
+			}
+			buffer += '\0';
+			return buffer.c_str();
+		}
+		break;
+
+		case TAG_COMPRESSION:
+		{
+			WORD compression = *((WORD*)FreeImage_GetTagValue(tag));
+			switch(compression) {
+				case TAG_COMPRESSION_NONE:
+					sprintf(format, "dump mode (%d)", compression);
+					break;
+				case TAG_COMPRESSION_CCITTRLE:
+					sprintf(format, "CCITT modified Huffman RLE (%d)", compression);
+					break;
+				case TAG_COMPRESSION_CCITTFAX3:
+					sprintf(format, "CCITT Group 3 fax encoding (%d)", compression);
+					break;
+				/*
+				case TAG_COMPRESSION_CCITT_T4:
+					sprintf(format, "CCITT T.4 (TIFF 6 name) (%d)", compression);
+					break;
+				*/
+				case TAG_COMPRESSION_CCITTFAX4:
+					sprintf(format, "CCITT Group 4 fax encoding (%d)", compression);
+					break;
+				/*
+				case TAG_COMPRESSION_CCITT_T6:
+					sprintf(format, "CCITT T.6 (TIFF 6 name) (%d)", compression);
+					break;
+				*/
+				case TAG_COMPRESSION_LZW:
+					sprintf(format, "LZW (%d)", compression);
+					break;
+				case TAG_COMPRESSION_OJPEG:
+					sprintf(format, "!6.0 JPEG (%d)", compression);
+					break;
+				case TAG_COMPRESSION_JPEG:
+					sprintf(format, "JPEG (%d)", compression);
+					break;
+				case TAG_COMPRESSION_NEXT:
+					sprintf(format, "NeXT 2-bit RLE (%d)", compression);
+					break;
+				case TAG_COMPRESSION_CCITTRLEW:
+					sprintf(format, "CCITTRLEW (%d)", compression);
+					break;
+				case TAG_COMPRESSION_PACKBITS:
+					sprintf(format, "PackBits Macintosh RLE (%d)", compression);
+					break;
+				case TAG_COMPRESSION_THUNDERSCAN:
+					sprintf(format, "ThunderScan RLE (%d)", compression);
+					break;
+				case TAG_COMPRESSION_PIXARFILM:
+					sprintf(format, "Pixar companded 10bit LZW (%d)", compression);
+					break;
+				case TAG_COMPRESSION_PIXARLOG:
+					sprintf(format, "Pixar companded 11bit ZIP (%d)", compression);
+					break;
+				case TAG_COMPRESSION_DEFLATE:
+					sprintf(format, "Deflate compression (%d)", compression);
+					break;
+				case TAG_COMPRESSION_ADOBE_DEFLATE:
+					sprintf(format, "Adobe Deflate compression (%d)", compression);
+					break;
+				case TAG_COMPRESSION_DCS:
+					sprintf(format, "Kodak DCS encoding (%d)", compression);
+					break;
+				case TAG_COMPRESSION_JBIG:
+					sprintf(format, "ISO JBIG (%d)", compression);
+					break;
+				case TAG_COMPRESSION_SGILOG:
+					sprintf(format, "SGI Log Luminance RLE (%d)", compression);
+					break;
+				case TAG_COMPRESSION_SGILOG24:
+					sprintf(format, "SGI Log 24-bit packed (%d)", compression);
+					break;
+				case TAG_COMPRESSION_JP2000:
+					sprintf(format, "Leadtools JPEG2000 (%d)", compression);
+					break;
+				case TAG_COMPRESSION_LZMA:
+					sprintf(format, "LZMA2 (%d)", compression);
+					break;
+				default:
+					sprintf(format, "Unknown type (%d)", compression);
+					break;
+			}
+
+			buffer += format;
+			return buffer.c_str();
+		}
+		break;
+	}
+
+	return ConvertAnyTag(tag);
+}
+
+/**
+Convert a Exif GPS tag to a C string
+*/
+static const char* 
+ConvertExifGPSTag(FITAG *tag) {
+	char format[MAX_TEXT_EXTENT];
+	static std::string buffer;
+
+	if(!tag)
+		return NULL;
+
+	buffer.erase();
+
+	// convert the tag value to a string buffer
+
+	switch(FreeImage_GetTagID(tag)) {
+		case TAG_GPS_LATITUDE:
+		case TAG_GPS_LONGITUDE:
+		case TAG_GPS_TIME_STAMP:
+		{
+			DWORD *pvalue = (DWORD*)FreeImage_GetTagValue(tag);
+			if(FreeImage_GetTagLength(tag) == 24) {
+				// dd:mm:ss or hh:mm:ss
+				int dd = 0, mm = 0;
+				double ss = 0;
+
+				// convert to seconds
+				if(pvalue[1])
+					ss += ((double)pvalue[0] / (double)pvalue[1]) * 3600;
+				if(pvalue[3])
+					ss += ((double)pvalue[2] / (double)pvalue[3]) * 60;
+				if(pvalue[5])
+					ss += ((double)pvalue[4] / (double)pvalue[5]);
+				
+				// convert to dd:mm:ss.ss
+				dd = (int)(ss / 3600);
+				mm = (int)(ss / 60) - dd * 60;
+				ss = ss - dd * 3600 - mm * 60;
+
+				sprintf(format, "%d:%d:%.2f", dd, mm, ss);
+				buffer += format;
+				return buffer.c_str();
+			}
+		}
+		break;
+
+		case TAG_GPS_VERSION_ID:
+		case TAG_GPS_LATITUDE_REF:
+		case TAG_GPS_LONGITUDE_REF:
+		case TAG_GPS_ALTITUDE_REF:
+		case TAG_GPS_ALTITUDE:
+		case TAG_GPS_SATELLITES:
+		case TAG_GPS_STATUS:
+		case TAG_GPS_MEASURE_MODE:
+		case TAG_GPS_DOP:
+		case TAG_GPS_SPEED_REF:
+		case TAG_GPS_SPEED:
+		case TAG_GPS_TRACK_REF:
+		case TAG_GPS_TRACK:
+		case TAG_GPS_IMG_DIRECTION_REF:
+		case TAG_GPS_IMG_DIRECTION:
+		case TAG_GPS_MAP_DATUM:
+		case TAG_GPS_DEST_LATITUDE_REF:
+		case TAG_GPS_DEST_LATITUDE:
+		case TAG_GPS_DEST_LONGITUDE_REF:
+		case TAG_GPS_DEST_LONGITUDE:
+		case TAG_GPS_DEST_BEARING_REF:
+		case TAG_GPS_DEST_BEARING:
+		case TAG_GPS_DEST_DISTANCE_REF:
+		case TAG_GPS_DEST_DISTANCE:
+		case TAG_GPS_PROCESSING_METHOD:
+		case TAG_GPS_AREA_INFORMATION:
+		case TAG_GPS_DATE_STAMP:
+		case TAG_GPS_DIFFERENTIAL:
+			break;
+	}
+
+	return ConvertAnyTag(tag);
+}
+
+// ==========================================================
+// Tag to string conversion function
+//
+
+const char* DLL_CALLCONV 
+FreeImage_TagToString(FREE_IMAGE_MDMODEL model, FITAG *tag, char *Make) {
+	switch(model) {
+		case FIMD_EXIF_MAIN:
+		case FIMD_EXIF_EXIF:
+			return ConvertExifTag(tag);
+
+		case FIMD_EXIF_GPS:
+			return ConvertExifGPSTag(tag);
+
+		case FIMD_EXIF_MAKERNOTE:
+			// We should use the Make string to select an appropriate conversion function
+			// TO DO ...
+			break;
+
+		case FIMD_EXIF_INTEROP:
+		default:
+			break;
+	}
+
+	return ConvertAnyTag(tag);
+}
+
diff --git a/Source/Metadata/XTIFF.cpp b/Source/Metadata/XTIFF.cpp
index e6f6bdd..d5be902 100644
--- a/Source/Metadata/XTIFF.cpp
+++ b/Source/Metadata/XTIFF.cpp
@@ -1,665 +1,766 @@
-// ==========================================================
-// Metadata functions implementation
-// Extended TIFF Directory GEO Tag Support
-//
-// Design and implementation by
-// - Hervé Drolon (drolon at infonie.fr)
-// - Thorsten Radde (support at IdealSoftware.com)
-// - Berend Engelbrecht (softwarecave at users.sourceforge.net)
-// - Mihail Naydenov (mnaydenov at users.sourceforge.net)
-//
-// Based on the LibTIFF xtiffio sample and on LibGeoTIFF
-//
-// This file is part of FreeImage 3
-//
-// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
-// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
-// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
-// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
-// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
-// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
-// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
-// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
-// THIS DISCLAIMER.
-//
-// Use at your own risk!
-// ========================================================== 
-
-#ifdef _MSC_VER
-#pragma warning (disable : 4786) // identifier was truncated to 'number' characters
-#endif
-
-#include "../LibTIFF4/tiffiop.h"
-
-#include "FreeImage.h"
-#include "Utilities.h"
-#include "FreeImageTag.h"
-#include "FIRational.h"
-
-// ----------------------------------------------------------
-//   Extended TIFF Directory GEO Tag Support
-// ----------------------------------------------------------
-
-/**
-  Tiff info structure.
-  Entry format:
-  { TAGNUMBER, ReadCount, WriteCount, DataType, FIELDNUM, OkToChange, PassDirCountOnSet, AsciiName }
-
-  For ReadCount, WriteCount, -1 = unknown.
-*/
-static const TIFFFieldInfo xtiffFieldInfo[] = {
-	{ TIFFTAG_GEOPIXELSCALE, -1, -1, TIFF_DOUBLE, FIELD_CUSTOM, TRUE, TRUE, "GeoPixelScale" },
-	{ TIFFTAG_INTERGRAPH_MATRIX, -1, -1, TIFF_DOUBLE, FIELD_CUSTOM, TRUE, TRUE, "Intergraph TransformationMatrix" },
-	{ TIFFTAG_GEOTRANSMATRIX, -1, -1, TIFF_DOUBLE, FIELD_CUSTOM, TRUE, TRUE, "GeoTransformationMatrix" },
-	{ TIFFTAG_GEOTIEPOINTS,	-1, -1, TIFF_DOUBLE, FIELD_CUSTOM, TRUE, TRUE, "GeoTiePoints" },
-	{ TIFFTAG_GEOKEYDIRECTORY,-1,-1, TIFF_SHORT, FIELD_CUSTOM, TRUE, TRUE, "GeoKeyDirectory" },
-	{ TIFFTAG_GEODOUBLEPARAMS, -1, -1, TIFF_DOUBLE,	FIELD_CUSTOM, TRUE,	TRUE, "GeoDoubleParams" },
-	{ TIFFTAG_GEOASCIIPARAMS, -1, -1, TIFF_ASCII, FIELD_CUSTOM, TRUE, FALSE, "GeoASCIIParams" },
-	{ TIFFTAG_JPL_CARTO_IFD, 1, 1, TIFF_LONG, FIELD_CUSTOM, TRUE, TRUE,	"JPL Carto IFD offset" }  /** Don't use this! **/
-};
-
-static void
-_XTIFFLocalDefaultDirectory(TIFF *tif) {
-	int tag_size = sizeof(xtiffFieldInfo) / sizeof(xtiffFieldInfo[0]);
-	// Install the extended Tag field info
-	TIFFMergeFieldInfo(tif, xtiffFieldInfo, tag_size);
-}
-
-static TIFFExtendProc _ParentExtender;
-
-/**
-This is the callback procedure, and is
-called by the DefaultDirectory method
-every time a new TIFF directory is opened.
-*/
-static void
-_XTIFFDefaultDirectory(TIFF *tif) {
-	// set up our own defaults
-	_XTIFFLocalDefaultDirectory(tif);
-
-	/*
-	Since an XTIFF client module may have overridden
-	the default directory method, we call it now to
-	allow it to set up the rest of its own methods.
-	*/
-	if (_ParentExtender)
-		(*_ParentExtender)(tif);
-}
-
-/**
-XTIFF Initializer -- sets up the callback procedure for the TIFF module
-*/
-void
-XTIFFInitialize(void) {
-	static int first_time = 1;
-
-	if (! first_time)
-		return; /* Been there. Done that. */
-	first_time = 0;
-
-	// Grab the inherited method and install
-	_ParentExtender = TIFFSetTagExtender(_XTIFFDefaultDirectory);
-}
-
-// ----------------------------------------------------------
-//   GeoTIFF tag reading / writing
-// ----------------------------------------------------------
-
-void
-tiff_read_geotiff_profile(TIFF *tif, FIBITMAP *dib) {
-	char defaultKey[16];
-
-	size_t tag_size = sizeof(xtiffFieldInfo) / sizeof(xtiffFieldInfo[0]);
-
-	TagLib& tag_lib = TagLib::instance();
-
-	for(unsigned i = 0; i < tag_size; i++) {
-
-		const TIFFFieldInfo *fieldInfo = &xtiffFieldInfo[i];
-
-		if(fieldInfo->field_type == TIFF_ASCII) {
-			char *params = NULL;
-
-			if(TIFFGetField(tif, fieldInfo->field_tag, &params)) {
-				// create a tag
-				FITAG *tag = FreeImage_CreateTag();
-				if(!tag)
-					return;
-
-				WORD tag_id = (WORD)fieldInfo->field_tag;
-
-				FreeImage_SetTagType(tag, (FREE_IMAGE_MDTYPE)fieldInfo->field_type);
-				FreeImage_SetTagID(tag, tag_id);
-				FreeImage_SetTagKey(tag, tag_lib.getTagFieldName(TagLib::GEOTIFF, tag_id, defaultKey));
-				FreeImage_SetTagDescription(tag, tag_lib.getTagDescription(TagLib::GEOTIFF, tag_id));
-				FreeImage_SetTagLength(tag, (DWORD)strlen(params) + 1);
-				FreeImage_SetTagCount(tag, FreeImage_GetTagLength(tag));
-				FreeImage_SetTagValue(tag, params);
-				FreeImage_SetMetadata(FIMD_GEOTIFF, dib, FreeImage_GetTagKey(tag), tag);
-
-				// delete the tag
-				FreeImage_DeleteTag(tag);
-			}
-		} else {
-			short tag_count = 0;
-			void* data = NULL;
-
-			if(TIFFGetField(tif, fieldInfo->field_tag, &tag_count, &data)) {
-				// create a tag
-				FITAG *tag = FreeImage_CreateTag();
-				if(!tag)
-					return;
-
-				WORD tag_id = (WORD)fieldInfo->field_tag;
-				FREE_IMAGE_MDTYPE tag_type = (FREE_IMAGE_MDTYPE)fieldInfo->field_type;
-
-				FreeImage_SetTagType(tag, tag_type);
-				FreeImage_SetTagID(tag, tag_id);
-				FreeImage_SetTagKey(tag, tag_lib.getTagFieldName(TagLib::GEOTIFF, tag_id, defaultKey));
-				FreeImage_SetTagDescription(tag, tag_lib.getTagDescription(TagLib::GEOTIFF, tag_id));
-				FreeImage_SetTagLength(tag, FreeImage_TagDataWidth(tag_type) * tag_count);
-				FreeImage_SetTagCount(tag, tag_count);
-				FreeImage_SetTagValue(tag, data);
-				FreeImage_SetMetadata(FIMD_GEOTIFF, dib, FreeImage_GetTagKey(tag), tag);
-
-				// delete the tag
-				FreeImage_DeleteTag(tag);
-			}
-		}
-	} // for(tag_size)
-}
-
-void
-tiff_write_geotiff_profile(TIFF *tif, FIBITMAP *dib) {
-	char defaultKey[16];
-
-	if(FreeImage_GetMetadataCount(FIMD_GEOTIFF, dib) == 0) {
-		return;
-	}
-
-	size_t tag_size = sizeof(xtiffFieldInfo) / sizeof(xtiffFieldInfo[0]);
-
-	TagLib& tag_lib = TagLib::instance();
-
-	for(unsigned i = 0; i < tag_size; i++) {
-		const TIFFFieldInfo *fieldInfo = &xtiffFieldInfo[i];
-
-		FITAG *tag = NULL;
-		const char *key = tag_lib.getTagFieldName(TagLib::GEOTIFF, (WORD)fieldInfo->field_tag, defaultKey);
-
-		if(FreeImage_GetMetadata(FIMD_GEOTIFF, dib, key, &tag)) {
-			if(FreeImage_GetTagType(tag) == FIDT_ASCII) {
-				TIFFSetField(tif, fieldInfo->field_tag, FreeImage_GetTagValue(tag));
-			} else {
-				TIFFSetField(tif, fieldInfo->field_tag, FreeImage_GetTagCount(tag), FreeImage_GetTagValue(tag));
-			}
-		}
-	}
-}
-
-// ----------------------------------------------------------
-//   EXIF tag reading & writing
-// ----------------------------------------------------------
-
-/**
-Read a single exif tag
-*/
-static BOOL 
-tiff_read_exif_tag(TIFF *tif, TagLib::MDMODEL md_model, FIBITMAP *dib, TagLib& tagLib, TIFFDirectory *td, uint32 tag) {
-	const TIFFField *fip;
-	uint32 value_count;
-	int mem_alloc = 0;
-	void *raw_data = NULL;
-
-	if(tag == TIFFTAG_EXIFIFD) {
-		return TRUE;
-	}
-
-	// get the tag key - use NULL to avoid reading GeoTIFF tags
-	const char *key = tagLib.getTagFieldName(md_model, (WORD)tag, NULL);
-	if(key == NULL) {
-		return TRUE;
-	}
-
-	fip = TIFFFieldWithTag(tif, tag);
-	if(fip == NULL) {
-		return TRUE;
-	}
-
-	if(fip->field_passcount) { //<- "passcount" means "returns count"
-		if (fip->field_readcount != TIFF_VARIABLE2) { //<- TIFF_VARIABLE2 means "uses LONG count"
-
-			// assume TIFF_VARIABLE (uses SHORT count)
-			uint16 value_count16;
-			if(TIFFGetField(tif, tag, &value_count16, &raw_data) != 1) {
-				return TRUE;
-			}
-			value_count = value_count16;
-		} else {
-			if(TIFFGetField(tif, tag, &value_count, &raw_data) != 1) {
-				return TRUE;
-			}
-		}
-	} else {
-
-		// determine count
-
-		if (fip->field_readcount == TIFF_VARIABLE || fip->field_readcount == TIFF_VARIABLE2) {
-			value_count = 1;
-		} else if (fip->field_readcount == TIFF_SPP) {
-			value_count = td->td_samplesperpixel;
-		} else {
-			value_count = fip->field_readcount;
-		}
-
-		// access fields as pointers to data
-		// (### determining this is NOT robust... and hardly can be. It is implemented looking the _TIFFVGetField code)
-
-		if(fip->field_tag == TIFFTAG_TRANSFERFUNCTION) {
-			// reading this tag cause a bug probably located somewhere inside libtiff
-			return TRUE;
-		}
-
-		if ((fip->field_type == TIFF_ASCII
-		     || fip->field_readcount == TIFF_VARIABLE
-		     || fip->field_readcount == TIFF_VARIABLE2
-		     || fip->field_readcount == TIFF_SPP
-			 || value_count > 1)
-			 
-			 && fip->field_tag != TIFFTAG_PAGENUMBER
-			 && fip->field_tag != TIFFTAG_HALFTONEHINTS
-			 && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING
-			 && fip->field_tag != TIFFTAG_DOTRANGE
-
-			 && fip->field_tag != TIFFTAG_BITSPERSAMPLE	//<- these two are tricky - 
-			 && fip->field_tag != TIFFTAG_COMPRESSION	//<- they are defined as TIFF_VARIABLE but in reality return a single value
-			 ) {
-				 if(TIFFGetField(tif, tag, &raw_data) != 1) {
-					 return TRUE;
-				 }
-		} else {
-
-			// access fields as values
-
-			const int value_size = _TIFFDataSize(fip->field_type);
-			raw_data = _TIFFmalloc(value_size * value_count);
-			mem_alloc = 1;
-			int ok = FALSE;
-			
-			// ### if value_count > 1, tag is PAGENUMBER or HALFTONEHINTS or YCBCRSUBSAMPLING or DOTRANGE, 
-			// all off which are value_count == 2 (see tif_dirinfo.c)
-			switch(value_count)
-			{
-				case 1:
-					ok = TIFFGetField(tif, tag, raw_data);
-					break;
-				case 2:
-					ok = TIFFGetField(tif, tag, raw_data, (BYTE*)(raw_data) + value_size*1);
-					break;
-/* # we might need more in the future:
-				case 3:
-					ok = TIFFGetField(tif, tag, raw_data, (BYTE*)(raw_data) + value_size*1, (BYTE*)(raw_data) + value_size*2);
-					break;
-*/
-				default:
-					FreeImage_OutputMessageProc(FIF_TIFF, "Unimplemented variable number of parameters for Tiff Tag %s", fip->field_name);
-					break;
-			}
-			if(ok != 1) {
-				_TIFFfree(raw_data);
-				return TRUE;
-			}
-		}
-	}
-
-	// build FreeImage tag from Tiff Tag data we collected
-
-	FITAG *fitag = FreeImage_CreateTag();
-	if(!fitag) {
-		if(mem_alloc) {
-			_TIFFfree(raw_data);
-		}
-		return FALSE;
-	}
-
-	FreeImage_SetTagID(fitag, (WORD)tag);
-	FreeImage_SetTagKey(fitag, key);
-
-	switch(fip->field_type) {
-		case TIFF_BYTE:
-			FreeImage_SetTagType(fitag, FIDT_BYTE);
-			FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
-			FreeImage_SetTagCount(fitag, value_count);
-			FreeImage_SetTagValue(fitag, raw_data);
-			break;
-
-		case TIFF_UNDEFINED:
-			FreeImage_SetTagType(fitag, FIDT_UNDEFINED);
-			FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
-			FreeImage_SetTagCount(fitag, value_count);
-			FreeImage_SetTagValue(fitag, raw_data);
-			break;
-
-		case TIFF_SBYTE:
-			FreeImage_SetTagType(fitag, FIDT_SBYTE);
-			FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
-			FreeImage_SetTagCount(fitag, value_count);
-			FreeImage_SetTagValue(fitag, raw_data);
-			break;
-
-		case TIFF_SHORT:
-			FreeImage_SetTagType(fitag, FIDT_SHORT);
-			FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
-			FreeImage_SetTagCount(fitag, value_count);
-			FreeImage_SetTagValue(fitag, raw_data);
-			break;
-
-		case TIFF_SSHORT:
-			FreeImage_SetTagType(fitag, FIDT_SSHORT);
-			FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
-			FreeImage_SetTagCount(fitag, value_count);
-			FreeImage_SetTagValue(fitag, raw_data);
-			break;
-
-		case TIFF_LONG:
-			FreeImage_SetTagType(fitag, FIDT_LONG);
-			FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
-			FreeImage_SetTagCount(fitag, value_count);
-			FreeImage_SetTagValue(fitag, raw_data);
-			break;
-
-		case TIFF_IFD:
-			FreeImage_SetTagType(fitag, FIDT_IFD);
-			FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
-			FreeImage_SetTagCount(fitag, value_count);
-			FreeImage_SetTagValue(fitag, raw_data);
-			break;
-
-		case TIFF_SLONG:
-			FreeImage_SetTagType(fitag, FIDT_SLONG);
-			FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
-			FreeImage_SetTagCount(fitag, value_count);
-			FreeImage_SetTagValue(fitag, raw_data);
-			break;
-
-		case TIFF_RATIONAL: {
-			// LibTIFF converts rational to floats : reconvert floats to rationals
-			DWORD *rvalue = (DWORD*)malloc(2 * value_count * sizeof(DWORD));
-			for(uint32 i = 0; i < value_count; i++) {
-				float *fv = (float*)raw_data;
-				FIRational rational(fv[i]);
-				rvalue[2*i] = rational.getNumerator();
-				rvalue[2*i+1] = rational.getDenominator();
-			}
-			FreeImage_SetTagType(fitag, FIDT_RATIONAL);
-			FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
-			FreeImage_SetTagCount(fitag, value_count);
-			FreeImage_SetTagValue(fitag, rvalue);
-			free(rvalue);
-		}
-		break;
-
-		case TIFF_SRATIONAL: {
-			// LibTIFF converts rational to floats : reconvert floats to rationals
-			LONG *rvalue = (LONG*)malloc(2 * value_count * sizeof(LONG));
-			for(uint32 i = 0; i < value_count; i++) {
-				float *fv = (float*)raw_data;
-				FIRational rational(fv[i]);
-				rvalue[2*i] = rational.getNumerator();
-				rvalue[2*i+1] = rational.getDenominator();
-			}
-			FreeImage_SetTagType(fitag, FIDT_RATIONAL);
-			FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
-			FreeImage_SetTagCount(fitag, value_count);
-			FreeImage_SetTagValue(fitag, rvalue);
-			free(rvalue);
-		}
-		break;
-
-		case TIFF_FLOAT:
-			FreeImage_SetTagType(fitag, FIDT_FLOAT);
-			FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
-			FreeImage_SetTagCount(fitag, value_count);
-			FreeImage_SetTagValue(fitag, raw_data);
-			break;
-
-		case TIFF_DOUBLE:
-			FreeImage_SetTagType(fitag, FIDT_DOUBLE);
-			FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
-			FreeImage_SetTagCount(fitag, value_count);
-			FreeImage_SetTagValue(fitag, raw_data);
-			break;
-
-		case TIFF_LONG8:	// BigTIFF 64-bit unsigned integer 
-			FreeImage_SetTagType(fitag, FIDT_LONG8);
-			FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
-			FreeImage_SetTagCount(fitag, value_count);
-			FreeImage_SetTagValue(fitag, raw_data);
-			break;
-
-		case TIFF_IFD8:		// BigTIFF 64-bit unsigned integer (offset) 
-			FreeImage_SetTagType(fitag, FIDT_IFD8);
-			FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
-			FreeImage_SetTagCount(fitag, value_count);
-			FreeImage_SetTagValue(fitag, raw_data);
-			break;
-
-		case TIFF_SLONG8:		// BigTIFF 64-bit signed integer 
-			FreeImage_SetTagType(fitag, FIDT_SLONG8);
-			FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
-			FreeImage_SetTagCount(fitag, value_count);
-			FreeImage_SetTagValue(fitag, raw_data);
-			break;
-
-		default: {
-			// remember that raw_data = _TIFFmalloc(value_size * value_count);
-			const int value_size = _TIFFDataSize(fip->field_type);
-			size_t length = value_size * value_count;
-			FreeImage_SetTagType(fitag, FIDT_ASCII);
-			FreeImage_SetTagLength(fitag, (DWORD)length);
-			FreeImage_SetTagCount(fitag, (DWORD)length);
-			FreeImage_SetTagValue(fitag, raw_data);
-		}
-		break;
-	}
-
-	const char *description = tagLib.getTagDescription(md_model, (WORD)tag);
-	if(description) {
-		FreeImage_SetTagDescription(fitag, description);
-	}
-	// store the tag
-	FreeImage_SetMetadata(tagLib.getFreeImageModel(md_model), dib, FreeImage_GetTagKey(fitag), fitag);
-
-	// destroy the tag
-	FreeImage_DeleteTag(fitag);
-
-	if(mem_alloc) {
-		_TIFFfree(raw_data);
-	}
-	return TRUE;
-}
-
-/**
-Read all known exif tags
-*/
-BOOL 
-tiff_read_exif_tags(TIFF *tif, TagLib::MDMODEL md_model, FIBITMAP *dib) {
-	int  i;
-	short count;
-
-	TagLib& tagLib = TagLib::instance();
-
-	TIFFDirectory *td = &tif->tif_dir;
-
-	count = (short) TIFFGetTagListCount(tif);
-	for(i = 0; i < count; i++) {
-		uint32 tag = TIFFGetTagListEntry(tif, i);
-		// read the tag
-		if (!tiff_read_exif_tag(tif, md_model, dib, tagLib, td, tag))
-			return FALSE;
-	}
-
-	// we want to know values of standard tags too!!
-
-	// loop over all Core Directory Tags
-	// ### uses private data, but there is no other way
-	if(md_model == TagLib::EXIF_MAIN) {
-
-		uint32 lastTag = 0;	//<- used to prevent reading some tags twice (as stored in tif_fieldinfo)
-
-		for (int fi = 0, nfi = (int)tif->tif_nfields; nfi > 0; nfi--, fi++) {
-			const TIFFField *fld = tif->tif_fields[fi];
-
-			if(fld->field_tag == lastTag)
-				continue;
-
-			// test if tag value is set
-			// (lifted directly form LibTiff _TIFFWriteDirectory)
-
-			if( fld->field_bit == FIELD_CUSTOM ) {
-				int ci, is_set = FALSE;
-
-				for( ci = 0; ci < td->td_customValueCount; ci++ ) {
-					is_set |= (td->td_customValues[ci].info == fld);
-				}
-
-				if( !is_set ) {
-					continue;
-				}
-
-			} else if(!TIFFFieldSet(tif, fld->field_bit)) {
-				continue;
-			}
-
-			// process *all* other tags (some will be ignored)
-
-			tiff_read_exif_tag(tif, md_model, dib, tagLib, td, fld->field_tag);
-
-
-			lastTag = fld->field_tag;
-		}
-
-	}
-
-	return TRUE;
-
-}
-
-
-/**
-Skip tags that are already handled by the LibTIFF writing process
-*/
-static BOOL 
-skip_write_field(TIFF* tif, uint32 tag) {
-	switch (tag) {
-		case TIFFTAG_SAMPLEFORMAT:
-		case TIFFTAG_IMAGEWIDTH:
-		case TIFFTAG_IMAGELENGTH:
-		case TIFFTAG_SAMPLESPERPIXEL:
-		case TIFFTAG_BITSPERSAMPLE:
-		case TIFFTAG_PHOTOMETRIC:
-		case TIFFTAG_PLANARCONFIG:
-		case TIFFTAG_ROWSPERSTRIP:
-		case TIFFTAG_STRIPBYTECOUNTS:
-		case TIFFTAG_STRIPOFFSETS:
-		case TIFFTAG_RESOLUTIONUNIT:
-		case TIFFTAG_XRESOLUTION:
-		case TIFFTAG_YRESOLUTION:
-		case TIFFTAG_SUBFILETYPE:
-		case TIFFTAG_PAGENUMBER:
-		case TIFFTAG_COLORMAP:
-		case TIFFTAG_ORIENTATION:
-		case TIFFTAG_COMPRESSION:
-		case TIFFTAG_PREDICTOR:
-		case TIFFTAG_GROUP3OPTIONS:
-		case TIFFTAG_FILLORDER:
-			// skip always, values have been set in SaveOneTIFF()
-			return TRUE;
-			break;
-		
-		case TIFFTAG_RICHTIFFIPTC:
-			// skip always, IPTC metadata model is set in tiff_write_iptc_profile()
-			return TRUE;
-			break;
-
-		case TIFFTAG_YCBCRCOEFFICIENTS:
-		case TIFFTAG_REFERENCEBLACKWHITE:
-		case TIFFTAG_YCBCRSUBSAMPLING:
-			// skip as they cannot be filled yet
-			return TRUE;
-			break;
-			
-		case TIFFTAG_PAGENAME:
-		{
-			char *value = NULL;
-			TIFFGetField(tif, TIFFTAG_PAGENAME, &value);
-			// only skip if no value has been set
-			if(value == NULL) {
-				return FALSE;
-			} else {
-				return TRUE;
-			}
-		}
-		default:
-			return FALSE;
-			break;
-	}
-}
-
-/**
-Write all known exif tags
-*/
-BOOL 
-tiff_write_exif_tags(TIFF *tif, TagLib::MDMODEL md_model, FIBITMAP *dib) {
-	char defaultKey[16];
-	
-	// only EXIF_MAIN so far
-	if(md_model != TagLib::EXIF_MAIN) {
-		return FALSE;
-	}
-	
-	if(FreeImage_GetMetadataCount(FIMD_EXIF_MAIN, dib) == 0) {
-		return FALSE;
-	}
-	
-	TagLib& tag_lib = TagLib::instance();
-	
-	for (int fi = 0, nfi = (int)tif->tif_nfields; nfi > 0; nfi--, fi++) {
-		const TIFFField *fld = tif->tif_fields[fi];
-
-		if(skip_write_field(tif, fld->field_tag)) {
-			// skip tags that are already handled by the LibTIFF writing process
-			continue;
-		}
-
-		FITAG *tag = NULL;
-		// get the tag key
-		const char *key = tag_lib.getTagFieldName(TagLib::EXIF_MAIN, (WORD)fld->field_tag, defaultKey);
-
-		if(FreeImage_GetMetadata(FIMD_EXIF_MAIN, dib, key, &tag)) {
-			FREE_IMAGE_MDTYPE tag_type = FreeImage_GetTagType(tag);
-			TIFFDataType tif_tag_type = fld->field_type;
-			
-			// check for identical formats
-
-			// (enum value are the sames between FREE_IMAGE_MDTYPE and TIFFDataType types)
-			if((int)tif_tag_type != (int)tag_type) {
-				// skip tag or _TIFFmemcpy will fail
-				continue;
-			}
-			// type of storage may differ (e.g. rationnal array vs float array type)
-			if(_TIFFDataSize(tif_tag_type) != FreeImage_TagDataWidth(tag_type)) {
-				// skip tag or _TIFFmemcpy will fail
-				continue;
-			}
-
-			if(tag_type == FIDT_ASCII) {
-				TIFFSetField(tif, fld->field_tag, FreeImage_GetTagValue(tag));
-			} else {
-				TIFFSetField(tif, fld->field_tag, FreeImage_GetTagCount(tag), FreeImage_GetTagValue(tag));
-			}
-		}
-	}
-
-	return TRUE;
-}
+// ==========================================================
+// Metadata functions implementation
+// Extended TIFF Directory GEO Tag Support
+//
+// Design and implementation by
+// - Hervé Drolon (drolon at infonie.fr)
+// - Thorsten Radde (support at IdealSoftware.com)
+// - Berend Engelbrecht (softwarecave at users.sourceforge.net)
+// - Mihail Naydenov (mnaydenov at users.sourceforge.net)
+//
+// Based on the LibTIFF xtiffio sample and on LibGeoTIFF
+//
+// This file is part of FreeImage 3
+//
+// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
+// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
+// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
+// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
+// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
+// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
+// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+// THIS DISCLAIMER.
+//
+// Use at your own risk!
+// ========================================================== 
+
+#ifdef _MSC_VER
+#pragma warning (disable : 4786) // identifier was truncated to 'number' characters
+#endif
+
+#include "../LibTIFF4/tiffiop.h"
+
+#include "FreeImage.h"
+#include "Utilities.h"
+#include "FreeImageTag.h"
+#include "FIRational.h"
+
+// ----------------------------------------------------------
+//   Extended TIFF Directory GEO Tag Support
+// ----------------------------------------------------------
+
+/**
+  Tiff info structure.
+  Entry format:
+  { TAGNUMBER, ReadCount, WriteCount, DataType, FIELDNUM, OkToChange, PassDirCountOnSet, AsciiName }
+
+  For ReadCount, WriteCount, -1 = unknown.
+*/
+static const TIFFFieldInfo xtiffFieldInfo[] = {
+  { TIFFTAG_GEOPIXELSCALE, -1, -1, TIFF_DOUBLE, FIELD_CUSTOM, TRUE, TRUE, (char*)"GeoPixelScale" },
+  { TIFFTAG_INTERGRAPH_MATRIX, -1, -1, TIFF_DOUBLE, FIELD_CUSTOM, TRUE, TRUE, (char*)"Intergraph TransformationMatrix" },
+  { TIFFTAG_GEOTRANSMATRIX, -1, -1, TIFF_DOUBLE, FIELD_CUSTOM, TRUE, TRUE, (char*)"GeoTransformationMatrix" },
+  { TIFFTAG_GEOTIEPOINTS,	-1, -1, TIFF_DOUBLE, FIELD_CUSTOM, TRUE, TRUE, (char*)"GeoTiePoints" },
+  { TIFFTAG_GEOKEYDIRECTORY,-1,-1, TIFF_SHORT, FIELD_CUSTOM, TRUE, TRUE, (char*)"GeoKeyDirectory" },
+  { TIFFTAG_GEODOUBLEPARAMS, -1, -1, TIFF_DOUBLE,	FIELD_CUSTOM, TRUE, TRUE, (char*)"GeoDoubleParams" },
+  { TIFFTAG_GEOASCIIPARAMS, -1, -1, TIFF_ASCII, FIELD_CUSTOM, TRUE, FALSE, (char*) "GeoASCIIParams" },
+  { TIFFTAG_JPL_CARTO_IFD, 1, 1, TIFF_LONG, FIELD_CUSTOM, TRUE, TRUE, (char*)"JPL Carto IFD offset" }  /** Don't use this! **/
+};
+
+static void
+_XTIFFLocalDefaultDirectory(TIFF *tif) {
+	int tag_size = sizeof(xtiffFieldInfo) / sizeof(xtiffFieldInfo[0]);
+	// Install the extended Tag field info
+	TIFFMergeFieldInfo(tif, xtiffFieldInfo, tag_size);
+}
+
+static TIFFExtendProc _ParentExtender;
+
+/**
+This is the callback procedure, and is
+called by the DefaultDirectory method
+every time a new TIFF directory is opened.
+*/
+static void
+_XTIFFDefaultDirectory(TIFF *tif) {
+	// set up our own defaults
+	_XTIFFLocalDefaultDirectory(tif);
+
+	/*
+	Since an XTIFF client module may have overridden
+	the default directory method, we call it now to
+	allow it to set up the rest of its own methods.
+	*/
+	if (_ParentExtender) {
+		(*_ParentExtender)(tif);
+	}
+}
+
+/**
+XTIFF Initializer -- sets up the callback procedure for the TIFF module.
+ at see PluginTIFF::InitTIFF
+*/
+void
+XTIFFInitialize(void) {
+	static int first_time = 1;
+
+	if (! first_time) {
+		return; /* Been there. Done that. */
+	}
+	first_time = 0;
+
+	// Grab the inherited method and install
+	_ParentExtender = TIFFSetTagExtender(_XTIFFDefaultDirectory);
+}
+
+// ----------------------------------------------------------
+//   GeoTIFF tag reading / writing
+// ----------------------------------------------------------
+
+BOOL
+tiff_read_geotiff_profile(TIFF *tif, FIBITMAP *dib) {
+	char defaultKey[16];
+
+	// first check for a mandatory tag
+	{
+		short tag_count = 0;
+		void* data = NULL;
+		
+		if(!TIFFGetField(tif, TIFFTAG_GEOKEYDIRECTORY, &tag_count, &data)) {
+			// no GeoTIFF tag here
+			return TRUE;
+		}
+	}
+
+	// next, read GeoTIFF tags
+
+	const size_t tag_size = sizeof(xtiffFieldInfo) / sizeof(xtiffFieldInfo[0]);
+
+	TagLib& tag_lib = TagLib::instance();
+
+	for(size_t i = 0; i < tag_size; i++) {
+
+		const TIFFFieldInfo *fieldInfo = &xtiffFieldInfo[i];
+
+		if(fieldInfo->field_type == TIFF_ASCII) {
+			char *params = NULL;
+
+			if(TIFFGetField(tif, fieldInfo->field_tag, &params)) {
+				// create a tag
+				FITAG *tag = FreeImage_CreateTag();
+				if(!tag) {
+					return FALSE;
+				}
+
+				WORD tag_id = (WORD)fieldInfo->field_tag;
+
+				FreeImage_SetTagType(tag, (FREE_IMAGE_MDTYPE)fieldInfo->field_type);
+				FreeImage_SetTagID(tag, tag_id);
+				FreeImage_SetTagKey(tag, tag_lib.getTagFieldName(TagLib::GEOTIFF, tag_id, defaultKey));
+				FreeImage_SetTagDescription(tag, tag_lib.getTagDescription(TagLib::GEOTIFF, tag_id));
+				FreeImage_SetTagLength(tag, (DWORD)strlen(params) + 1);
+				FreeImage_SetTagCount(tag, FreeImage_GetTagLength(tag));
+				FreeImage_SetTagValue(tag, params);
+				FreeImage_SetMetadata(FIMD_GEOTIFF, dib, FreeImage_GetTagKey(tag), tag);
+
+				// delete the tag
+				FreeImage_DeleteTag(tag);
+			}
+		} else {
+			short tag_count = 0;
+			void* data = NULL;
+
+			if(TIFFGetField(tif, fieldInfo->field_tag, &tag_count, &data)) {
+				// create a tag
+				FITAG *tag = FreeImage_CreateTag();
+				if(!tag) {
+					return FALSE;
+				}
+
+				WORD tag_id = (WORD)fieldInfo->field_tag;
+				FREE_IMAGE_MDTYPE tag_type = (FREE_IMAGE_MDTYPE)fieldInfo->field_type;
+
+				FreeImage_SetTagType(tag, tag_type);
+				FreeImage_SetTagID(tag, tag_id);
+				FreeImage_SetTagKey(tag, tag_lib.getTagFieldName(TagLib::GEOTIFF, tag_id, defaultKey));
+				FreeImage_SetTagDescription(tag, tag_lib.getTagDescription(TagLib::GEOTIFF, tag_id));
+				FreeImage_SetTagLength(tag, FreeImage_TagDataWidth(tag_type) * tag_count);
+				FreeImage_SetTagCount(tag, tag_count);
+				FreeImage_SetTagValue(tag, data);
+				FreeImage_SetMetadata(FIMD_GEOTIFF, dib, FreeImage_GetTagKey(tag), tag);
+
+				// delete the tag
+				FreeImage_DeleteTag(tag);
+			}
+		}
+	} // for(tag_size)
+
+	return TRUE;
+}
+
+BOOL
+tiff_write_geotiff_profile(TIFF *tif, FIBITMAP *dib) {
+	char defaultKey[16];
+
+	if(FreeImage_GetMetadataCount(FIMD_GEOTIFF, dib) == 0) {
+		// no GeoTIFF tag here
+		return TRUE;
+	}
+
+	const size_t tag_size = sizeof(xtiffFieldInfo) / sizeof(xtiffFieldInfo[0]);
+
+	TagLib& tag_lib = TagLib::instance();
+
+	for(size_t i = 0; i < tag_size; i++) {
+		const TIFFFieldInfo *fieldInfo = &xtiffFieldInfo[i];
+
+		FITAG *tag = NULL;
+		const char *key = tag_lib.getTagFieldName(TagLib::GEOTIFF, (WORD)fieldInfo->field_tag, defaultKey);
+
+		if(FreeImage_GetMetadata(FIMD_GEOTIFF, dib, key, &tag)) {
+			if(FreeImage_GetTagType(tag) == FIDT_ASCII) {
+				TIFFSetField(tif, fieldInfo->field_tag, FreeImage_GetTagValue(tag));
+			} else {
+				TIFFSetField(tif, fieldInfo->field_tag, FreeImage_GetTagCount(tag), FreeImage_GetTagValue(tag));
+			}
+		}
+	}
+
+	return TRUE;
+}
+
+// ----------------------------------------------------------
+//   TIFF EXIF tag reading & writing
+// ----------------------------------------------------------
+
+/**
+Read a single Exif tag
+
+ at param tif TIFF handle
+ at param tag_id TIFF Tag ID
+ at param dib Image being read
+ at param md_model Metadata model where to store the tag
+ at return Returns TRUE if successful, returns FALSE otherwise
+*/
+static BOOL 
+tiff_read_exif_tag(TIFF *tif, uint32 tag_id, FIBITMAP *dib, TagLib::MDMODEL md_model) {
+	uint32 value_count = 0;
+	int mem_alloc = 0;
+	void *raw_data = NULL;
+
+	if(tag_id == TIFFTAG_EXIFIFD) {
+		// Exif IFD offset - skip this tag
+		// md_model should be EXIF_MAIN, the Exif IFD is processed later using the EXIF_EXIF metadata model
+		return TRUE;
+	}
+	if((tag_id == TIFFTAG_GPSIFD) && (md_model == TagLib::EXIF_MAIN)) {
+		// Exif GPS IFD offset - skip this tag
+		// should be processed in another way ...
+		return TRUE;
+	}
+	
+	TagLib& tagLib = TagLib::instance();
+
+	// get the tag key - use NULL to avoid reading GeoTIFF tags
+	const char *key = tagLib.getTagFieldName(md_model, (WORD)tag_id, NULL);
+	if(key == NULL) {
+		return TRUE;
+	}
+
+	const TIFFField *fip = TIFFFieldWithTag(tif, tag_id);
+	if(fip == NULL) {
+		return TRUE;
+	}
+
+	if(TIFFFieldPassCount(fip)) { 
+		// a count value is required for 'TIFFGetField'
+
+		if (TIFFFieldReadCount(fip) != TIFF_VARIABLE2) {
+			// a count is required, it will be of type uint16
+			uint16 value_count16 = 0;
+			if(TIFFGetField(tif, tag_id, &value_count16, &raw_data) != 1) {
+				// stop, ignore error
+				return TRUE;
+			}
+			value_count = value_count16;
+		} else {
+			// a count is required, it will be of type uint32
+			uint32 value_count32 = 0;
+			if(TIFFGetField(tif, tag_id, &value_count32, &raw_data) != 1) {
+				// stop, ignore error
+				return TRUE;
+			}
+			value_count = value_count32;
+		}
+
+	} else {
+		// determine count
+
+		if (TIFFFieldReadCount(fip) == TIFF_VARIABLE || TIFFFieldReadCount(fip) == TIFF_VARIABLE2) {
+			value_count = 1;
+		} else if (TIFFFieldReadCount(fip) == TIFF_SPP) {
+			uint16 spp;
+			TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &spp);
+			value_count = spp;
+		} else {
+			value_count = TIFFFieldReadCount(fip);
+		}
+
+		// access fields as pointers to data
+		// (### determining this is NOT robust... and hardly can be. It is implemented looking the _TIFFVGetField code)
+
+		if(TIFFFieldTag(fip) == TIFFTAG_TRANSFERFUNCTION) {
+			// reading this tag cause a bug probably located somewhere inside libtiff
+			return TRUE;
+		}
+
+		if ((TIFFFieldDataType(fip) == TIFF_ASCII
+		     || TIFFFieldReadCount(fip) == TIFF_VARIABLE
+		     || TIFFFieldReadCount(fip) == TIFF_VARIABLE2
+		     || TIFFFieldReadCount(fip) == TIFF_SPP
+			 || value_count > 1)
+			 
+			 && TIFFFieldTag(fip) != TIFFTAG_PAGENUMBER
+			 && TIFFFieldTag(fip) != TIFFTAG_HALFTONEHINTS
+			 && TIFFFieldTag(fip) != TIFFTAG_YCBCRSUBSAMPLING
+			 && TIFFFieldTag(fip) != TIFFTAG_DOTRANGE
+
+			 && TIFFFieldTag(fip) != TIFFTAG_BITSPERSAMPLE	//<- these two are tricky - 
+			 && TIFFFieldTag(fip) != TIFFTAG_COMPRESSION	//<- they are defined as TIFF_VARIABLE but in reality return a single value
+			 ) {
+				 if(TIFFGetField(tif, tag_id, &raw_data) != 1) {
+					 // stop, ignore error
+					 return TRUE;
+				 }
+		} else {
+			int value_size = 0;
+
+			// access fields as values
+
+			// Note: 
+			// For TIFF_RATIONAL values, TIFFDataWidth() returns 8, but LibTIFF use internaly 4-byte float to represent rationals.
+			{
+				TIFFDataType tag_type = TIFFFieldDataType(fip);
+				switch(tag_type) {
+					case TIFF_RATIONAL:
+					case TIFF_SRATIONAL:
+						value_size = 4;
+						break;
+					default:
+						value_size = TIFFDataWidth(tag_type);
+						break;
+				}
+			}
+
+			raw_data = _TIFFmalloc(value_size * value_count);
+			mem_alloc = 1;
+			int ok = FALSE;
+			
+			// ### if value_count > 1, tag is PAGENUMBER or HALFTONEHINTS or YCBCRSUBSAMPLING or DOTRANGE, 
+			// all off which are value_count == 2 (see tif_dirinfo.c)
+			switch(value_count)
+			{
+				case 1:
+					ok = TIFFGetField(tif, tag_id, raw_data);
+					break;
+				case 2:
+					ok = TIFFGetField(tif, tag_id, raw_data, (BYTE*)(raw_data) + value_size*1);
+					break;
+/* # we might need more in the future:
+				case 3:
+					ok = TIFFGetField(tif, tag_id, raw_data, (BYTE*)(raw_data) + value_size*1, (BYTE*)(raw_data) + value_size*2);
+					break;
+*/
+				default:
+					FreeImage_OutputMessageProc(FIF_TIFF, "Unimplemented variable number of parameters for Tiff Tag %s", TIFFFieldName(fip));
+					break;
+			}
+			if(ok != 1) {
+				_TIFFfree(raw_data);
+				return TRUE;
+			}
+		}
+	}
+
+	// build FreeImage tag from Tiff Tag data we collected
+
+	FITAG *fitag = FreeImage_CreateTag();
+	if(!fitag) {
+		if(mem_alloc) {
+			_TIFFfree(raw_data);
+		}
+		return FALSE;
+	}
+
+	FreeImage_SetTagID(fitag, (WORD)tag_id);
+	FreeImage_SetTagKey(fitag, key);
+
+	switch(TIFFFieldDataType(fip)) {
+		case TIFF_BYTE:
+			FreeImage_SetTagType(fitag, FIDT_BYTE);
+			FreeImage_SetTagLength(fitag, TIFFDataWidth( TIFFFieldDataType(fip) ) * value_count);
+			FreeImage_SetTagCount(fitag, value_count);
+			FreeImage_SetTagValue(fitag, raw_data);
+			break;
+
+		case TIFF_UNDEFINED:
+			FreeImage_SetTagType(fitag, FIDT_UNDEFINED);
+			FreeImage_SetTagLength(fitag, TIFFDataWidth( TIFFFieldDataType(fip) ) * value_count);
+			FreeImage_SetTagCount(fitag, value_count);
+			FreeImage_SetTagValue(fitag, raw_data);
+			break;
+
+		case TIFF_SBYTE:
+			FreeImage_SetTagType(fitag, FIDT_SBYTE);
+			FreeImage_SetTagLength(fitag, TIFFDataWidth( TIFFFieldDataType(fip) ) * value_count);
+			FreeImage_SetTagCount(fitag, value_count);
+			FreeImage_SetTagValue(fitag, raw_data);
+			break;
+
+		case TIFF_SHORT:
+			FreeImage_SetTagType(fitag, FIDT_SHORT);
+			FreeImage_SetTagLength(fitag, TIFFDataWidth( TIFFFieldDataType(fip) ) * value_count);
+			FreeImage_SetTagCount(fitag, value_count);
+			FreeImage_SetTagValue(fitag, raw_data);
+			break;
+
+		case TIFF_SSHORT:
+			FreeImage_SetTagType(fitag, FIDT_SSHORT);
+			FreeImage_SetTagLength(fitag, TIFFDataWidth( TIFFFieldDataType(fip) ) * value_count);
+			FreeImage_SetTagCount(fitag, value_count);
+			FreeImage_SetTagValue(fitag, raw_data);
+			break;
+
+		case TIFF_LONG:
+			FreeImage_SetTagType(fitag, FIDT_LONG);
+			FreeImage_SetTagLength(fitag, TIFFDataWidth( TIFFFieldDataType(fip) ) * value_count);
+			FreeImage_SetTagCount(fitag, value_count);
+			FreeImage_SetTagValue(fitag, raw_data);
+			break;
+
+		case TIFF_IFD:
+			FreeImage_SetTagType(fitag, FIDT_IFD);
+			FreeImage_SetTagLength(fitag, TIFFDataWidth( TIFFFieldDataType(fip) ) * value_count);
+			FreeImage_SetTagCount(fitag, value_count);
+			FreeImage_SetTagValue(fitag, raw_data);
+			break;
+
+		case TIFF_SLONG:
+			FreeImage_SetTagType(fitag, FIDT_SLONG);
+			FreeImage_SetTagLength(fitag, TIFFDataWidth( TIFFFieldDataType(fip) ) * value_count);
+			FreeImage_SetTagCount(fitag, value_count);
+			FreeImage_SetTagValue(fitag, raw_data);
+			break;
+
+		case TIFF_RATIONAL: {
+			// LibTIFF converts rational to floats : reconvert floats to rationals
+			DWORD *rvalue = (DWORD*)malloc(2 * value_count * sizeof(DWORD));
+			for(uint32 i = 0; i < value_count; i++) {
+				float *fv = (float*)raw_data;
+				FIRational rational(fv[i]);
+				rvalue[2*i] = rational.getNumerator();
+				rvalue[2*i+1] = rational.getDenominator();
+			}
+			FreeImage_SetTagType(fitag, FIDT_RATIONAL);
+			FreeImage_SetTagLength(fitag, TIFFDataWidth( TIFFFieldDataType(fip) ) * value_count);
+			FreeImage_SetTagCount(fitag, value_count);
+			FreeImage_SetTagValue(fitag, rvalue);
+			free(rvalue);
+		}
+		break;
+
+		case TIFF_SRATIONAL: {
+			// LibTIFF converts rational to floats : reconvert floats to rationals
+			LONG *rvalue = (LONG*)malloc(2 * value_count * sizeof(LONG));
+			for(uint32 i = 0; i < value_count; i++) {
+				float *fv = (float*)raw_data;
+				FIRational rational(fv[i]);
+				rvalue[2*i] = rational.getNumerator();
+				rvalue[2*i+1] = rational.getDenominator();
+			}
+			FreeImage_SetTagType(fitag, FIDT_RATIONAL);
+			FreeImage_SetTagLength(fitag, TIFFDataWidth( TIFFFieldDataType(fip) ) * value_count);
+			FreeImage_SetTagCount(fitag, value_count);
+			FreeImage_SetTagValue(fitag, rvalue);
+			free(rvalue);
+		}
+		break;
+
+		case TIFF_FLOAT:
+			FreeImage_SetTagType(fitag, FIDT_FLOAT);
+			FreeImage_SetTagLength(fitag, TIFFDataWidth( TIFFFieldDataType(fip) ) * value_count);
+			FreeImage_SetTagCount(fitag, value_count);
+			FreeImage_SetTagValue(fitag, raw_data);
+			break;
+
+		case TIFF_DOUBLE:
+			FreeImage_SetTagType(fitag, FIDT_DOUBLE);
+			FreeImage_SetTagLength(fitag, TIFFDataWidth( TIFFFieldDataType(fip) ) * value_count);
+			FreeImage_SetTagCount(fitag, value_count);
+			FreeImage_SetTagValue(fitag, raw_data);
+			break;
+
+		case TIFF_LONG8:	// BigTIFF 64-bit unsigned integer 
+			FreeImage_SetTagType(fitag, FIDT_LONG8);
+			FreeImage_SetTagLength(fitag, TIFFDataWidth( TIFFFieldDataType(fip) ) * value_count);
+			FreeImage_SetTagCount(fitag, value_count);
+			FreeImage_SetTagValue(fitag, raw_data);
+			break;
+
+		case TIFF_IFD8:		// BigTIFF 64-bit unsigned integer (offset) 
+			FreeImage_SetTagType(fitag, FIDT_IFD8);
+			FreeImage_SetTagLength(fitag, TIFFDataWidth( TIFFFieldDataType(fip) ) * value_count);
+			FreeImage_SetTagCount(fitag, value_count);
+			FreeImage_SetTagValue(fitag, raw_data);
+			break;
+
+		case TIFF_SLONG8:		// BigTIFF 64-bit signed integer 
+			FreeImage_SetTagType(fitag, FIDT_SLONG8);
+			FreeImage_SetTagLength(fitag, TIFFDataWidth( TIFFFieldDataType(fip) ) * value_count);
+			FreeImage_SetTagCount(fitag, value_count);
+			FreeImage_SetTagValue(fitag, raw_data);
+			break;
+
+		case TIFF_ASCII:
+		default: {
+			size_t length = 0;
+			if(!mem_alloc && (TIFFFieldDataType(fip) == TIFF_ASCII) && (TIFFFieldReadCount(fip) == TIFF_VARIABLE)) {
+				// when metadata tag is of type ASCII and it's value is of variable size (TIFF_VARIABLE),
+				// tiff_read_exif_tag function gives length of 1 so all strings are truncated ...
+				// ... try to avoid this by using an explicit calculation for 'length'
+				length = strlen((char*)raw_data) + 1;
+			}
+			else {
+				// remember that raw_data = _TIFFmalloc(value_size * value_count);
+				const int value_size = TIFFDataWidth( TIFFFieldDataType(fip) );
+				length = value_size * value_count;
+			}
+			FreeImage_SetTagType(fitag, FIDT_ASCII);
+			FreeImage_SetTagLength(fitag, (DWORD)length);
+			FreeImage_SetTagCount(fitag, (DWORD)length);
+			FreeImage_SetTagValue(fitag, raw_data);
+		}
+		break;
+	}
+
+	const char *description = tagLib.getTagDescription(md_model, (WORD)tag_id);
+	if(description) {
+		FreeImage_SetTagDescription(fitag, description);
+	}
+	// store the tag
+	FreeImage_SetMetadata(tagLib.getFreeImageModel(md_model), dib, FreeImage_GetTagKey(fitag), fitag);
+
+	// destroy the tag
+	FreeImage_DeleteTag(fitag);
+
+	if(mem_alloc) {
+		_TIFFfree(raw_data);
+	}
+	return TRUE;
+}
+
+/**
+Read all known exif tags
+
+ at param tif TIFF handle
+ at param md_model Metadata model where to store the tags
+ at param dib Image being read
+ at return Returns TRUE if successful, returns FALSE otherwise
+*/
+BOOL 
+tiff_read_exif_tags(TIFF *tif, TagLib::MDMODEL md_model, FIBITMAP *dib) {
+
+	TagLib& tagLib = TagLib::instance();
+
+	const int count = TIFFGetTagListCount(tif);
+	for(int i = 0; i < count; i++) {
+		uint32 tag_id = TIFFGetTagListEntry(tif, i);
+		// read the tag
+		if (!tiff_read_exif_tag(tif, tag_id, dib, md_model))
+			return FALSE;
+	}
+
+	// we want to know values of standard tags too!!
+
+	// loop over all Core Directory Tags
+	// ### uses private data, but there is no other way
+	if(md_model == TagLib::EXIF_MAIN) {
+		const TIFFDirectory *td = &tif->tif_dir;
+
+		uint32 lastTag = 0;	//<- used to prevent reading some tags twice (as stored in tif_fieldinfo)
+
+		for (int fi = 0, nfi = (int)tif->tif_nfields; nfi > 0; nfi--, fi++) {
+			const TIFFField *fld = tif->tif_fields[fi];
+
+			const uint32 tag_id = TIFFFieldTag(fld);
+
+			if(tag_id == lastTag) {
+				continue;
+			}
+
+			// test if tag value is set
+			// (lifted directly from LibTiff _TIFFWriteDirectory)
+
+			if( fld->field_bit == FIELD_CUSTOM ) {
+				int is_set = FALSE;
+
+				for(int ci = 0; ci < td->td_customValueCount; ci++ ) {
+					is_set |= (td->td_customValues[ci].info == fld);
+				}
+
+				if( !is_set ) {
+					continue;
+				}
+
+			} else if(!TIFFFieldSet(tif, fld->field_bit)) {
+				continue;
+			}
+
+			// process *all* other tags (some will be ignored)
+
+			tiff_read_exif_tag(tif, tag_id, dib, md_model);
+
+			lastTag = tag_id;
+		}
+
+	}
+
+	return TRUE;
+}
+
+
+/**
+Skip tags that are already handled by the LibTIFF writing process
+*/
+static BOOL 
+skip_write_field(TIFF* tif, uint32 tag) {
+	switch (tag) {
+		case TIFFTAG_SUBFILETYPE:
+		case TIFFTAG_OSUBFILETYPE:
+		case TIFFTAG_IMAGEWIDTH:
+		case TIFFTAG_IMAGELENGTH:
+		case TIFFTAG_BITSPERSAMPLE:
+		case TIFFTAG_COMPRESSION:
+		case TIFFTAG_PHOTOMETRIC:
+		case TIFFTAG_THRESHHOLDING:
+		case TIFFTAG_CELLWIDTH:
+		case TIFFTAG_CELLLENGTH:
+		case TIFFTAG_FILLORDER:
+		case TIFFTAG_STRIPOFFSETS:
+		case TIFFTAG_ORIENTATION:
+		case TIFFTAG_SAMPLESPERPIXEL:
+		case TIFFTAG_ROWSPERSTRIP:
+		case TIFFTAG_STRIPBYTECOUNTS:
+		case TIFFTAG_MINSAMPLEVALUE:
+		case TIFFTAG_MAXSAMPLEVALUE:
+		case TIFFTAG_XRESOLUTION:
+		case TIFFTAG_YRESOLUTION:
+		case TIFFTAG_PLANARCONFIG:
+		case TIFFTAG_FREEOFFSETS:
+		case TIFFTAG_FREEBYTECOUNTS:
+		case TIFFTAG_GRAYRESPONSEUNIT:
+		case TIFFTAG_GRAYRESPONSECURVE:
+		case TIFFTAG_GROUP3OPTIONS:
+		case TIFFTAG_GROUP4OPTIONS:
+		case TIFFTAG_RESOLUTIONUNIT:
+		case TIFFTAG_PAGENUMBER:
+		case TIFFTAG_COLORRESPONSEUNIT:
+		case TIFFTAG_PREDICTOR:
+		case TIFFTAG_COLORMAP:
+		case TIFFTAG_HALFTONEHINTS:
+		case TIFFTAG_TILEWIDTH:
+		case TIFFTAG_TILELENGTH:
+		case TIFFTAG_TILEOFFSETS:
+		case TIFFTAG_TILEBYTECOUNTS:
+		case TIFFTAG_EXTRASAMPLES:
+		case TIFFTAG_SAMPLEFORMAT:
+		case TIFFTAG_SMINSAMPLEVALUE:
+		case TIFFTAG_SMAXSAMPLEVALUE:
+			// skip always, values have been set in SaveOneTIFF()
+			return TRUE;
+			break;
+		
+		case TIFFTAG_RICHTIFFIPTC:
+			// skip always, IPTC metadata model is set in tiff_write_iptc_profile()
+			return TRUE;
+			break;
+
+		case TIFFTAG_YCBCRCOEFFICIENTS:
+		case TIFFTAG_REFERENCEBLACKWHITE:
+		case TIFFTAG_YCBCRSUBSAMPLING:
+			// skip as they cannot be filled yet
+			return TRUE;
+			break;
+			
+		case TIFFTAG_PAGENAME:
+		{
+			char *value = NULL;
+			TIFFGetField(tif, TIFFTAG_PAGENAME, &value);
+			// only skip if no value has been set
+			if(value == NULL) {
+				return FALSE;
+			} else {
+				return TRUE;
+			}
+		}
+		default:
+			return FALSE;
+			break;
+	}
+}
+
+/**
+Write all known exif tags
+
+ at param tif TIFF handle
+ at param md_model Metadata model from where to load the tags
+ at param dib Image being written
+ at return Returns TRUE if successful, returns FALSE otherwise
+*/
+BOOL 
+tiff_write_exif_tags(TIFF *tif, TagLib::MDMODEL md_model, FIBITMAP *dib) {
+	char defaultKey[16];
+	
+	// only EXIF_MAIN so far
+	if(md_model != TagLib::EXIF_MAIN) {
+		return FALSE;
+	}
+	
+	if(FreeImage_GetMetadataCount(FIMD_EXIF_MAIN, dib) == 0) {
+		return FALSE;
+	}
+	
+	TagLib& tag_lib = TagLib::instance();
+	
+	for (int fi = 0, nfi = (int)tif->tif_nfields; nfi > 0; nfi--, fi++) {
+		const TIFFField *fld = tif->tif_fields[fi];
+		
+		const uint32 tag_id = TIFFFieldTag(fld);
+
+		if(skip_write_field(tif, tag_id)) {
+			// skip tags that are already handled by the LibTIFF writing process
+			continue;
+		}
+
+		FITAG *tag = NULL;
+		// get the tag key
+		const char *key = tag_lib.getTagFieldName(TagLib::EXIF_MAIN, (WORD)tag_id, defaultKey);
+
+		if(FreeImage_GetMetadata(FIMD_EXIF_MAIN, dib, key, &tag)) {
+			FREE_IMAGE_MDTYPE tag_type = FreeImage_GetTagType(tag);
+			TIFFDataType tif_tag_type = TIFFFieldDataType(fld);
+			
+			// check for identical formats
+
+			// (enum value are the sames between FREE_IMAGE_MDTYPE and TIFFDataType types)
+			if((int)tif_tag_type != (int)tag_type) {
+				// skip tag or _TIFFmemcpy will fail
+				continue;
+			}
+			// type of storage may differ (e.g. rationnal array vs float array type)
+			if((unsigned)_TIFFDataSize(tif_tag_type) != FreeImage_TagDataWidth(tag_type)) {
+				// skip tag or _TIFFmemcpy will fail
+				continue;
+			}
+
+			if(tag_type == FIDT_ASCII) {
+				TIFFSetField(tif, tag_id, FreeImage_GetTagValue(tag));
+			} else {
+				TIFFSetField(tif, tag_id, FreeImage_GetTagCount(tag), FreeImage_GetTagValue(tag));
+			}
+		}
+	}
+
+	return TRUE;
+}
diff --git a/Source/OpenEXR/Copyrights/ilmbase/AUTHORS b/Source/OpenEXR/Copyrights/ilmbase/AUTHORS
index 51c1f9c..1120e6c 100644
--- a/Source/OpenEXR/Copyrights/ilmbase/AUTHORS
+++ b/Source/OpenEXR/Copyrights/ilmbase/AUTHORS
@@ -1,21 +1,21 @@
-Developers:
------------
-
-Florian Kainz <kainz at ilm.com>
-Rod Bogart <rgb at ilm.com>
-Drew Hess <dhess at ilm.com>
-Bill Anderson <wja at ilm.com>
-Wojciech Jarosz <wjarosz at ucsd.edu>
-
-Contributors:
--------------
-
-Rito Trevino
-Josh Pines
-Christian Rouet
-
-Win32 build system:
--------------------
-
-Nick Porcino <NPorcino at lucasarts.com>
-Kimball Thurston
+Developers:
+-----------
+
+Florian Kainz <kainz at ilm.com>
+Rod Bogart <rgb at ilm.com>
+Drew Hess <dhess at ilm.com>
+Bill Anderson <wja at ilm.com>
+Wojciech Jarosz <wjarosz at ucsd.edu>
+
+Contributors:
+-------------
+
+Rito Trevino
+Josh Pines
+Christian Rouet
+
+Win32 build system:
+-------------------
+
+Nick Porcino <NPorcino at lucasarts.com>
+Kimball Thurston
diff --git a/Source/OpenEXR/Copyrights/ilmbase/COPYING b/Source/OpenEXR/Copyrights/ilmbase/COPYING
index 6372750..7681f42 100644
--- a/Source/OpenEXR/Copyrights/ilmbase/COPYING
+++ b/Source/OpenEXR/Copyrights/ilmbase/COPYING
@@ -1,34 +1,34 @@
-Copyright (c) 2006, Industrial Light & Magic, a division of Lucasfilm
-Entertainment Company Ltd.  Portions contributed and copyright held by
-others as indicated.  All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-    * Redistributions of source code must retain the above
-      copyright notice, this list of conditions and the following
-      disclaimer.
-
-    * Redistributions in binary form must reproduce the above
-      copyright notice, this list of conditions and the following
-      disclaimer in the documentation and/or other materials provided with
-      the distribution.
-
-    * Neither the name of Industrial Light & Magic nor the names of
-      any other contributors to this software may be used to endorse or
-      promote products derived from this software without specific prior
-      written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
+Copyright (c) 2006, Industrial Light & Magic, a division of Lucasfilm
+Entertainment Company Ltd.  Portions contributed and copyright held by
+others as indicated.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above
+      copyright notice, this list of conditions and the following
+      disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided with
+      the distribution.
+
+    * Neither the name of Industrial Light & Magic nor the names of
+      any other contributors to this software may be used to endorse or
+      promote products derived from this software without specific prior
+      written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/Source/OpenEXR/Copyrights/ilmbase/ChangeLog b/Source/OpenEXR/Copyrights/ilmbase/ChangeLog
index 2e409d2..4cfd2cc 100644
--- a/Source/OpenEXR/Copyrights/ilmbase/ChangeLog
+++ b/Source/OpenEXR/Copyrights/ilmbase/ChangeLog
@@ -1,109 +1,136 @@
-Version 1.0.3
-        * Added support for enabling/disabling large stack optimisations, used in
-          halfFunction.h.
-          (Piotr Stanczyk)
-	* Added ImathNoise.(h/cpp) files. Initializes Perlin noise to match the
-	  Renderman implmenetation.
-	  (Pixar Contribution)
-	* Fixed a number of missing includes to comply with stricter 
-	  enforcement by gnu compilers.
-	  (Piotr Stanczyk)
-	* Depracated compiler flag: -Wno-long-double since it is no longer
-	  supported under OS X.
-	  (Piotr Stanczyk)
-	* A minor API change to Imath::Frustum has been made:  the functions
-	  'near' and 'far' have been renamed to 'nearPlane' and 'farPlane' due
-	  to conflicts with certain windows headers.  The former alternate
-	  accessor names for these values on windows ('hither' and 'yon')
-	  remain, though should be considered deprecated.
-	  (David Lenihan)
-	* Added SVD, eigenvalue solver, and procrustes fit calculations
-	  to ImathMatrixAlgo.
-	  (Chris Twigg, Ji Hun Yu)
-	* Added Imath::FrustumTest for frustum visibility testing.
-	  (Eric Johnston)
-	* Fixed a stack corruption in the matrix minorOf functions.
-	  (Nick Rasmussen)
-	* Visual studio 2008 project files have been added to the vc/vc9
-	  directory, and several minor visual studio compile fixes have
-	  been applied.
-	  (Nick Rasmussen)
-	* Updated the so verison to 7.
-	  (Piotr Stanczyk)
-	* Depracated the MacCode_Warrior and Shake submodules.
-	  (Piotr Stanczyk)
-
-Version 1.0.2
-	* Added support for targetting builds on 64bit Windows and minimising 
-	  number of compiler warnings on Windows. Thanks to Ger Hobbelt for his
-	  contributions to CreateDLL.
-	  (Ji Hun Yu)
-	* Removed a spurious restrict qualifier in the matrix manipulation code
-	  that was causing the 64-bit MS compiler to generate code in release 
-	  mode that caused incorrect results. 
-	  (Ji Hun Yu)
-	* Added patches for improving universal binaries on OS X. Thanks to
-	  Paul Schneider for the contribution
-	  (Piotr Stanczyk)
-	* Imath::Box optimization: remove loops from methods by partially 
-	  specializing the class, for boxes of two and three dimensions.
-	  (Piotr Stanczyk)
-	* Added explicit copy constructors to Imath::Matrix33<T> and
-	  ImathMatrix44<T> to make conversions between float and double
-	  matrices more convenient.
-	  (Florian Kainz)
-	* Added slerpShortestArc() and euclideanInnerProduct() functions
-	  to Imath::Quat<T>.
-	  (Nick Porcino)
-	* Added 4D vector class template Imath::Vec4<T>.
-	  (Nick Porcino)
-	* Copy constructors and assignment operators for Matrix33<T>
-	  and Matrix44<T> are up to 25% faster.  Added matrix constructors
-	  that do not initialize the matrix (this is faster in cases where
-	  the initial value of the matrix is immediately overwritten anyway).
-	  (Nick Porcino)
-	* Rewrote function closestPointOnBox(point,box).  Shortened
-	  the code, improved numerical accuracy, fixed a bug where
-	  closestPointOnBox(box.center(),box) would return the center
-	  of the +Z side of the box, even if the +/-X or +/-Y sides
-	  were closer.
-	  (Florian Kainz)
-	* Rewrote function findEntryAndExitPoints() in ImathBoxAlgo.h.
-	  Results are now consistent with those from intersect(), also
-	  in ImathBoxAlgo.h.
-	  (Florian Kainz)
-	* Made Vec2<T>::length() and Vec3<T>::length() more accurate for
-	  vectors whose length is less than sqrt(limits<T>::smallest());
-	  (Florian Kainz)
-	* Made Quat<T>::angle() more accurate for small angles.
-	  (Don Hatch) 
-
-Version 1.0.1:
-	* Removed Windows .suo files from distribution.
-	  (Eric Wimmer)
-
-Version 1.0.0:
-	* Bumped DSO version number to 6.0
-	  (Florian Kainz)
-	* Rounding during float-to-half conversion now implements
-	  "round to nearest even" mode: if the original float value
-	  is exactly in the middle between the two closest half values
-	  then rounding chooses the half value whose least significant
-	  bit is zero.
-	  (Florian Kainz)
-	* Installation Tuning:
-	  - Corrected version number on dso's (libtool) - now 5.0
-	  - Separated ILMBASE_LDFLAGS and ILMBASE_LIBS so that test programs
-	    in configure scripts of packages dependent on IlmBase can link
-	    with static libraries properly
-	  - eliminated some warning messages during install
-	  (Andrew Kunz)
-	
-Version 0.9.0:
-	* Initial release of this code as a separate library.
-	  Previously the libraries contained were part of
-	  version 1.4.0 of OpenEXR
-	* New build scripts for Linux/Unix
-	  (Andrew Kunz)
-	* New Windows project files and build scripts
-	  (Kimball Thurston)
+Version 2.x.x
+	* Bumped version to track OpenEXR
+	  (Piotr Stanczyk)
+
+Version 2.0.1
+	* Bumped version to track OpenEXR
+	  (Piotr Stanczyk)
+
+Version 2.0.0
+	* Bumped version to track OpenEXR
+	  (Piotr Stanczyk)
+	* Numerous minor fixes, missing includes etc
+
+Version 1.1.0.beta.1
+	* Added new module PyIlmBase : python bindings for IlmBase
+	  (Nick Rasmussen)
+	* Added git specific files 
+	  (Piotr Stanczyk)
+	* Minor fixes for newer gcc versions and OS X.
+	  (misc)
+	* Preparation for OpenEXR v2 release { remove message for final release }
+	  (Piotr Stanczyk)
+        * Updated the so verison to 10
+	  (Piotr Stanczyk)
+	* Initial use of the CMake build system 
+	  (Nicholas Yue)
+
+Version 1.0.3
+        * Added support for enabling/disabling large stack optimisations, used in
+          halfFunction.h.
+          (Piotr Stanczyk)
+	* Added ImathNoise.(h/cpp) files. Initializes Perlin noise to match the
+	  Renderman implmenetation.
+	  (Pixar Contribution)
+	* Fixed a number of missing includes to comply with stricter 
+	  enforcement by gnu compilers.
+	  (Piotr Stanczyk)
+	* Depracated compiler flag: -Wno-long-double since it is no longer
+	  supported under OS X.
+	  (Piotr Stanczyk)
+	* A minor API change to Imath::Frustum has been made:  the functions
+	  'near' and 'far' have been renamed to 'nearPlane' and 'farPlane' due
+	  to conflicts with certain windows headers.  The former alternate
+	  accessor names for these values on windows ('hither' and 'yon')
+	  remain, though should be considered deprecated.
+	  (David Lenihan)
+	* Added SVD, eigenvalue solver, and procrustes fit calculations
+	  to ImathMatrixAlgo.
+	  (Chris Twigg, Ji Hun Yu)
+	* Added Imath::FrustumTest for frustum visibility testing.
+	  (Eric Johnston)
+	* Fixed a stack corruption in the matrix minorOf functions.
+	  (Nick Rasmussen)
+	* Visual studio 2008 project files have been added to the vc/vc9
+	  directory, and several minor visual studio compile fixes have
+	  been applied.
+	  (Nick Rasmussen)
+	* Updated the so verison to 7.
+	  (Piotr Stanczyk)
+	* Depracated the MacCode_Warrior and Shake submodules.
+	  (Piotr Stanczyk)
+
+Version 1.0.2
+	* Added support for targetting builds on 64bit Windows and minimising 
+	  number of compiler warnings on Windows. Thanks to Ger Hobbelt for his
+	  contributions to CreateDLL.
+	  (Ji Hun Yu)
+	* Removed a spurious restrict qualifier in the matrix manipulation code
+	  that was causing the 64-bit MS compiler to generate code in release 
+	  mode that caused incorrect results. 
+	  (Ji Hun Yu)
+	* Added patches for improving universal binaries on OS X. Thanks to
+	  Paul Schneider for the contribution
+	  (Piotr Stanczyk)
+	* Imath::Box optimization: remove loops from methods by partially 
+	  specializing the class, for boxes of two and three dimensions.
+	  (Piotr Stanczyk)
+	* Added explicit copy constructors to Imath::Matrix33<T> and
+	  ImathMatrix44<T> to make conversions between float and double
+	  matrices more convenient.
+	  (Florian Kainz)
+	* Added slerpShortestArc() and euclideanInnerProduct() functions
+	  to Imath::Quat<T>.
+	  (Nick Porcino)
+	* Added 4D vector class template Imath::Vec4<T>.
+	  (Nick Porcino)
+	* Copy constructors and assignment operators for Matrix33<T>
+	  and Matrix44<T> are up to 25% faster.  Added matrix constructors
+	  that do not initialize the matrix (this is faster in cases where
+	  the initial value of the matrix is immediately overwritten anyway).
+	  (Nick Porcino)
+	* Rewrote function closestPointOnBox(point,box).  Shortened
+	  the code, improved numerical accuracy, fixed a bug where
+	  closestPointOnBox(box.center(),box) would return the center
+	  of the +Z side of the box, even if the +/-X or +/-Y sides
+	  were closer.
+	  (Florian Kainz)
+	* Rewrote function findEntryAndExitPoints() in ImathBoxAlgo.h.
+	  Results are now consistent with those from intersect(), also
+	  in ImathBoxAlgo.h.
+	  (Florian Kainz)
+	* Made Vec2<T>::length() and Vec3<T>::length() more accurate for
+	  vectors whose length is less than sqrt(limits<T>::smallest());
+	  (Florian Kainz)
+	* Made Quat<T>::angle() more accurate for small angles.
+	  (Don Hatch) 
+
+Version 1.0.1:
+	* Removed Windows .suo files from distribution.
+	  (Eric Wimmer)
+
+Version 1.0.0:
+	* Bumped DSO version number to 6.0
+	  (Florian Kainz)
+	* Rounding during float-to-half conversion now implements
+	  "round to nearest even" mode: if the original float value
+	  is exactly in the middle between the two closest half values
+	  then rounding chooses the half value whose least significant
+	  bit is zero.
+	  (Florian Kainz)
+	* Installation Tuning:
+	  - Corrected version number on dso's (libtool) - now 5.0
+	  - Separated ILMBASE_LDFLAGS and ILMBASE_LIBS so that test programs
+	    in configure scripts of packages dependent on IlmBase can link
+	    with static libraries properly
+	  - eliminated some warning messages during install
+	  (Andrew Kunz)
+	
+Version 0.9.0:
+	* Initial release of this code as a separate library.
+	  Previously the libraries contained were part of
+	  version 1.4.0 of OpenEXR
+	* New build scripts for Linux/Unix
+	  (Andrew Kunz)
+	* New Windows project files and build scripts
+	  (Kimball Thurston)
diff --git a/Source/OpenEXR/Copyrights/ilmbase/INSTALL b/Source/OpenEXR/Copyrights/ilmbase/INSTALL
index 85ddb18..55396ad 100644
--- a/Source/OpenEXR/Copyrights/ilmbase/INSTALL
+++ b/Source/OpenEXR/Copyrights/ilmbase/INSTALL
@@ -1,2 +1,2 @@
-See the README file for instructions on how to build IlmBase from
-source. 
+See the README file for instructions on how to build IlmBase from
+source. 
diff --git a/Source/OpenEXR/Copyrights/ilmbase/LICENSE b/Source/OpenEXR/Copyrights/ilmbase/LICENSE
index 6372750..7681f42 100644
--- a/Source/OpenEXR/Copyrights/ilmbase/LICENSE
+++ b/Source/OpenEXR/Copyrights/ilmbase/LICENSE
@@ -1,34 +1,34 @@
-Copyright (c) 2006, Industrial Light & Magic, a division of Lucasfilm
-Entertainment Company Ltd.  Portions contributed and copyright held by
-others as indicated.  All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-    * Redistributions of source code must retain the above
-      copyright notice, this list of conditions and the following
-      disclaimer.
-
-    * Redistributions in binary form must reproduce the above
-      copyright notice, this list of conditions and the following
-      disclaimer in the documentation and/or other materials provided with
-      the distribution.
-
-    * Neither the name of Industrial Light & Magic nor the names of
-      any other contributors to this software may be used to endorse or
-      promote products derived from this software without specific prior
-      written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
+Copyright (c) 2006, Industrial Light & Magic, a division of Lucasfilm
+Entertainment Company Ltd.  Portions contributed and copyright held by
+others as indicated.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above
+      copyright notice, this list of conditions and the following
+      disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided with
+      the distribution.
+
+    * Neither the name of Industrial Light & Magic nor the names of
+      any other contributors to this software may be used to endorse or
+      promote products derived from this software without specific prior
+      written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/Source/OpenEXR/Copyrights/ilmbase/NEWS b/Source/OpenEXR/Copyrights/ilmbase/NEWS
index 0f49920..0782927 100644
--- a/Source/OpenEXR/Copyrights/ilmbase/NEWS
+++ b/Source/OpenEXR/Copyrights/ilmbase/NEWS
@@ -1,3 +1,3 @@
-Version 0.9.0:
-    - Initial release
-
+Version 0.9.0:
+    - Initial release
+
diff --git a/Source/OpenEXR/Copyrights/ilmbase/README b/Source/OpenEXR/Copyrights/ilmbase/README
index 1d1251b..04e3c3c 100644
--- a/Source/OpenEXR/Copyrights/ilmbase/README
+++ b/Source/OpenEXR/Copyrights/ilmbase/README
@@ -1,60 +1,70 @@
-ABOUT THE ILMBASE LIBRARIES 
-----------------------------
-
-Half is a class that encapsulates our 16-bit floating-point format.
-
-IlmThread is a thread abstraction library for use with OpenEXR
-and other software packages.  It currently supports pthreads and
-Windows threads.
-
-Imath implements 2D and 3D vectors, 3x3 and 4x4 matrices, quaternions
-and other useful 2D and 3D math functions.
-
-Iex is an exception-handling library.
-
-If you have questions about using the IlmBase libraries, you may want
-to join our developer mailing list.  See http://www.openexr.com for
-details.
-
-
-LICENSE
--------
-
-The IlmBase source code distribution is free software.  See the file
-named COPYING (included in this distribution) for details.
-
-
-BUILDING ILMBASE
-----------------
-
-To build IlmBase on GNU/Linux or other UNIX-like systems, do this:
-
-./configure
-make
-make install
-
-unless you obtained IlmBase directly from CVS, in which case you
-should first read README.CVS.
-
-See README.OSX for details on building IlmBase in MacOS X.
-
-Do `make check` to run the IlmBase confidence tests.  They should all
-pass; if you find a test that does not pass on your system, please let
-us know.
-
-Other UNIX variants haven't been tested, but should be easy to build.
-Let us know if you're having problems porting IlmBase to a particular
-platform.
-
-All include files needed to use the IlmBase libraries are installed in the 
-OpenEXR subdirectory of the install prefix, e.g. /usr/local/include/OpenEXR.
-
-
-USING ILMBASE IN YOUR APPLICATIONS
-----------------------------------
-
-On systems with support for pkg-config, use `pkg-config --cflags
-IlmBase` for the C++ flags required to compile against IlmBase
-headers; and `pkg-config --libs IlmBase` for the linker flags required
-to link against IlmBase libraries.
-
+ABOUT THE ILMBASE LIBRARIES 
+----------------------------
+
+Half is a class that encapsulates our 16-bit floating-point format.
+
+IlmThread is a thread abstraction library for use with OpenEXR
+and other software packages.  It currently supports pthreads and
+Windows threads.
+
+Imath implements 2D and 3D vectors, 3x3 and 4x4 matrices, quaternions
+and other useful 2D and 3D math functions.
+
+Iex is an exception-handling library.
+
+If you have questions about using the IlmBase libraries, you may want
+to join our developer mailing list.  See http://www.openexr.com for
+details.
+
+
+LICENSE
+-------
+
+The IlmBase source code distribution is free software.  See the file
+named COPYING (included in this distribution) for details.
+
+
+BUILDING ILMBASE
+----------------
+
+To build IlmBase on GNU/Linux or other UNIX-like systems, do this:
+
+./configure
+make
+make install
+
+unless you obtained IlmBase directly from git, in which case you
+should first read README.git
+
+
+Please type :
+
+./configure --help
+
+for a list of options in relation to building IlmBase libraries. In 
+particular, peruse README.namespaces for information regarding the 
+use of namespaces in IlmBase and OpenEXR.
+
+
+See README.OSX for details on building IlmBase in MacOS X.
+
+Do `make check` to run the IlmBase confidence tests.  They should all
+pass; if you find a test that does not pass on your system, please let
+us know.
+
+Other UNIX variants haven't been tested, but should be easy to build.
+Let us know if you're having problems porting IlmBase to a particular
+platform.
+
+All include files needed to use the IlmBase libraries are installed in the 
+OpenEXR subdirectory of the install prefix, e.g. /usr/local/include/OpenEXR.
+
+
+USING ILMBASE IN YOUR APPLICATIONS
+----------------------------------
+
+On systems with support for pkg-config, use `pkg-config --cflags
+IlmBase` for the C++ flags required to compile against IlmBase
+headers; and `pkg-config --libs IlmBase` for the linker flags required
+to link against IlmBase libraries.
+
diff --git a/Source/OpenEXR/Copyrights/ilmbase/README.CVS b/Source/OpenEXR/Copyrights/ilmbase/README.CVS
index c69064d..f3b6599 100644
--- a/Source/OpenEXR/Copyrights/ilmbase/README.CVS
+++ b/Source/OpenEXR/Copyrights/ilmbase/README.CVS
@@ -1,16 +1,16 @@
-If you're using IlmBase from CVS, you should run the bootstrap script 
-to create the auto* files.  It's a good idea to run this whenever you
-update IlmBase from CVS.
-
-Then run './configure' and make.
-
-Note that the configure.ac file requires a fairly new version of
-automake.  If you get this error message:
-
-running aclocal ...
-aclocal: configure.ac: 142: macro `AM_CFLAGS' not found in library
-aclocal: configure.ac: 143: macro `AM_CXXFLAGS' not found in library
-failed!
-
-you should upgrade your automake to version 1.6 or better.
-
+If you're using IlmBase from CVS, you should run the bootstrap script 
+to create the auto* files.  It's a good idea to run this whenever you
+update IlmBase from CVS.
+
+Then run './configure' and make.
+
+Note that the configure.ac file requires a fairly new version of
+automake.  If you get this error message:
+
+running aclocal ...
+aclocal: configure.ac: 142: macro `AM_CFLAGS' not found in library
+aclocal: configure.ac: 143: macro `AM_CXXFLAGS' not found in library
+failed!
+
+you should upgrade your automake to version 1.6 or better.
+
diff --git a/Source/OpenEXR/Copyrights/ilmbase/README.OSX b/Source/OpenEXR/Copyrights/ilmbase/README.OSX
index 170890d..498f0d3 100644
--- a/Source/OpenEXR/Copyrights/ilmbase/README.OSX
+++ b/Source/OpenEXR/Copyrights/ilmbase/README.OSX
@@ -1,68 +1,101 @@
-IlmBase on MacOS X
-------------------
-
-Building IlmBase on MacOS X is just like building it on GNU/Linux. 
-Follow the instructions in the README file under BUILDLING ILMBASE,
-but see below re: shared libraries.
-
-
-Universal Builds on Mac OS X
-------------------
-OS X supports multiple architectures. By default, IlmBase will be built
-for the system doing the building. For example, if you build IlmBase on
-an Intel system, the libraries will be built for Intel.
-
-You can specify building for a different architecture, or multiple architectures,
-by passing the "--enable-osx-arch" flag to configure. Building for multiple
-architectures requires that "--disable-dependency-tracking" be passed as well.
-
-For example, to build for Intel and PowerPC:
-
-./configure --enable-osx-arch="i386 ppc" --disable-dependency-tracking.
-
-To build "4-way universal" for 32-bit and 64-bit Intel and PowerPC:
-
-./configure --enable-osx-arch="i386 ppc x86_64 ppc64" --disable-dependency-tracking.
-
-For more information on universal builds, see:
-
-http://developer.apple.com/documentation/Porting/Conceptual/PortingUNIX/compiling/chapter_4_section_3.html
-
-Earlier releases of IlmBase included an "--enable-osx-universal-binaries" 
-switch, which specifies a two-way universal build: Intel and PowerPC, 32-bit only. 
-This is still available, but deprecated in favor of the more flexible 
-"--enable-osx-arch" and "--enable-osx-sdk" switches.
-
-
-Choosing an SDK on Mac OS X
-------------------
-OS X allows you to specify one of several SDKs, or sysroots. This allows you to 
-target systems other than the system that your build machine runs.
-
-For example, if you are building on Mac OS X 10.4, but you need access to features 
-that were introduced in Mac OS X 10.5, you can build against the Mac OS X 10.5 
-versions of system libraries and headers.
-
-You can choose to build IlmBase with a specific SDK using the "--enable-osx-sdk" 
-switch. For example:
-
-./configure --enable-osx-sdk=MacOSX10.5.sdk
-
-If you are building on Mac OS X 10.4 and want to build universal, you will need to 
-specify the universal version of the 10.4 SDK: MacOSX10.4u.sdk. Otherwise, you probably 
-don't need to specify an SDK.
-
-For more information on sysroots, see:
-
-http://developer.apple.com/documentation/DeveloperTools/gcc-4.2.1/gcc/Directory-Options.html
-
-
-Shared libraries
-----------------
-
-IlmBase requires the "flat namespace" option when built as a shared
-library.  You may have problems trying to use IlmBase shared libraries
-with applications that expect OS X's two-level namespace.  We have not
-tested the shared libs extensively, though they appear to work with
-exrdisplay and exrheader, but use them at your own risk.  We will
-support two-level namespace shared libs in a future release.
+IlmBase on MacOS X
+------------------
+
+Building IlmBase on MacOS X is just like building it on GNU/Linux. 
+Follow the instructions in the README file under BUILDLING ILMBASE,
+but see below re: shared libraries.
+
+
+Missing gnu automake tools on  Mac OS X 10.8+
+------------------
+Later versions of OS X ,10.8+, do not, by default have all the necessary 
+tools for building. In particular,  Autoconf and Automake may be missing. 
+
+The following commands will download and install the necessary components:
+
+cd ~/myDevLoc
+curl -OL http://ftpmirror.gnu.org/autoconf/autoconf-2.64.tar.gz
+tar xzf autoconf-2.64.tar.gz
+cd autoconf-2.64
+./configure --prefix=~/myDevLoc/autotools-bin
+make; make install
+
+cd ~/myDevLoc
+curl -OL http://ftpmirror.gnu.org/automake/automake-1.12.tar.gz
+tar xzf automake-1.12.tar.gz
+cd automake-1.12
+./configure --prefix=~/myDevLoc/autotools-bin
+make; make install
+
+cd ~/myDevLoc
+curl -OL http://ftpmirror.gnu.org/libtool/libtool-2.4.tar.gz
+tar xzf libtool-2.4.tar.gz
+cd libtool-2.4
+./configure --prefix=~/myDevLoc/autotools-bin
+make; make install
+
+
+You may want to export the installation path for your convenience.
+Finally, make sure that you have installed the command line tools for XCode.
+
+
+Universal Builds on Mac OS X
+------------------
+OS X supports multiple architectures. By default, IlmBase will be built
+for the system doing the building. For example, if you build IlmBase on
+an Intel system, the libraries will be built for Intel.
+
+You can specify building for a different architecture, or multiple architectures,
+by passing the "--enable-osx-arch" flag to configure. Building for multiple
+architectures requires that "--disable-dependency-tracking" be passed as well.
+
+For example, to build for Intel and PowerPC:
+
+./configure --enable-osx-arch="i386 ppc" --disable-dependency-tracking.
+
+To build "4-way universal" for 32-bit and 64-bit Intel and PowerPC:
+
+./configure --enable-osx-arch="i386 ppc x86_64 ppc64" --disable-dependency-tracking.
+
+For more information on universal builds, see:
+
+http://developer.apple.com/documentation/Porting/Conceptual/PortingUNIX/compiling/chapter_4_section_3.html
+
+Earlier releases of IlmBase included an "--enable-osx-universal-binaries" 
+switch, which specifies a two-way universal build: Intel and PowerPC, 32-bit only. 
+This is still available, but deprecated in favor of the more flexible 
+"--enable-osx-arch" and "--enable-osx-sdk" switches.
+
+
+Choosing an SDK on Mac OS X
+------------------
+OS X allows you to specify one of several SDKs, or sysroots. This allows you to 
+target systems other than the system that your build machine runs.
+
+For example, if you are building on Mac OS X 10.4, but you need access to features 
+that were introduced in Mac OS X 10.5, you can build against the Mac OS X 10.5 
+versions of system libraries and headers.
+
+You can choose to build IlmBase with a specific SDK using the "--enable-osx-sdk" 
+switch. For example:
+
+./configure --enable-osx-sdk=MacOSX10.5.sdk
+
+If you are building on Mac OS X 10.4 and want to build universal, you will need to 
+specify the universal version of the 10.4 SDK: MacOSX10.4u.sdk. Otherwise, you probably 
+don't need to specify an SDK.
+
+For more information on sysroots, see:
+
+http://developer.apple.com/documentation/DeveloperTools/gcc-4.2.1/gcc/Directory-Options.html
+
+
+Shared libraries
+----------------
+
+IlmBase requires the "flat namespace" option when built as a shared
+library.  You may have problems trying to use IlmBase shared libraries
+with applications that expect OS X's two-level namespace.  We have not
+tested the shared libs extensively, though they appear to work with
+exrdisplay and exrheader, but use them at your own risk.  We will
+support two-level namespace shared libs in a future release.
diff --git a/Source/OpenEXR/Copyrights/ilmbase/README.git b/Source/OpenEXR/Copyrights/ilmbase/README.git
new file mode 100644
index 0000000..e597775
--- /dev/null
+++ b/Source/OpenEXR/Copyrights/ilmbase/README.git
@@ -0,0 +1,16 @@
+If you're using IlmBase from github, you should run the bootstrap script 
+to create the auto* files.  It's a good idea to run this whenever you
+update IlmBase from github.
+
+Then run './configure' and make.
+
+Note that the configure.ac file requires a fairly new version of
+automake.  If you get this error message:
+
+running aclocal ...
+aclocal: configure.ac: 142: macro `AM_CFLAGS' not found in library
+aclocal: configure.ac: 143: macro `AM_CXXFLAGS' not found in library
+failed!
+
+you should upgrade your automake to version 1.6 or better.
+
diff --git a/Source/OpenEXR/Copyrights/ilmbase/README.namespacing b/Source/OpenEXR/Copyrights/ilmbase/README.namespacing
new file mode 100644
index 0000000..4371d82
--- /dev/null
+++ b/Source/OpenEXR/Copyrights/ilmbase/README.namespacing
@@ -0,0 +1,83 @@
+------------------------------------------------
+ On the use of namespace in IlmBase and OpenEXR
+------------------------------------------------
+
+v2.0 of the code base introduces user configurable namespaces for
+component libraries. This addition introduces the ability to deal with 
+multiple versions of these libraries loaded at runtime.
+An example case:
+    Application is built with OpenEXR v1.7, but the required plugin 
+    requires functionality from OpenEXR v2.0.
+    
+    By injecting the version number into the (mangled) symbols, via
+    the namespacing mechanism, and changing the soname, via the build
+    system, the developer can link his plugin against the v2.0 library
+    At run time the dynamic linker can load both the 1.7 and 2.0
+    versions of the library since the library soname are different and
+    the symbols are different.
+    
+
+When building IlmBase or OpenEXR the following configure script options 
+are available:
+    --enable-namespaceversioning
+and
+    --enable-customusernamespace
+
+
+
+-- Internal Library Namespace
+The option, --enable-namespaceversioning, controls the namespace that 
+is used in the library. Without an argument (see below) the library 
+will be built with a suffix made up of the major and minor versions.
+For example, for version 2.0.0, the internal library namespaces will be
+Imath_2_0, Iex_2_0, IlmThread_2_0 etc
+
+For additional flexibility and control, this option can take an additional 
+argument in which case the internal library namespace will be suffixed 
+accordingly. 
+For example: 
+    ./configure --enable-namespaceversioning=ILM
+will result in the namespaces of the type Imath_ILM, Iex_ILM etc.
+
+This can be useful for completely isolating your local build.
+
+Code using the library should continue to use the namespace Imath, or for
+greater portability IMATH_NAMESPACE, to refer to objects in libImath. 
+In particular, the explicit use of the internal namespace is discouraged.
+This ensures that code will continue to compile with customised or future 
+versions of the library, which may have a different internal namespace.
+
+Similarily, for other namespaces in the libraries: Iex, IlmThread and IlmImf.
+
+Note that this scheme allows existing code to compile without modifications, 
+since the 'old' namespaces Imath, Iex, IlmThread and IlmImf continue to be 
+available, albeit in a slightly different form.
+This is achieved via the following, in the Imath case: 
+    namespace IMATH_INTERNAL_NAMESPACE {}
+    namespace IMATH_NAMESPACE 
+    {
+         using namespace IMATH_INTERNAL_NAMESPACE;
+    }
+This is included in all header files in the Imath library and similar ones
+are present for the libraries Iex, IlmThread and IlmImf.
+
+The only exception to this is where user code has forward declarations of 
+objects in the Imf namespace, as these will forward declare symbols in an 
+incorrect namespace
+These forward declarations should be removed, and replaced with 
+    #include <ImfForward.h>, 
+which forward-declares all types correctly.
+
+
+
+-- Public/User Library Namespace
+The option, --enable-customusernamespace, can override the namespace into 
+which we will 'export' the internal namespace. This takes an argument 
+that sets the name of the custom user namespace.
+In the example above, IMATH_NAMESPACE could be resolved into something other
+than Imath, say Imath_MySpecialNamespace.
+
+In nearly all cases, this will not be used as per the above discussion
+regarding code compatibility.
+Its presence is to provide a mechanism for not prohibiting the case when 
+the application must pass objects from two different versions of the library.
diff --git a/Source/OpenEXR/Copyrights/ilmbase/README.win32 b/Source/OpenEXR/Copyrights/ilmbase/README.win32
index 0e4b3ca..eec6627 100644
--- a/Source/OpenEXR/Copyrights/ilmbase/README.win32
+++ b/Source/OpenEXR/Copyrights/ilmbase/README.win32
@@ -189,7 +189,7 @@ Step 5. Compile OpenEXR_Viewers
   d. Build the Release configuration of the OpenEXR_Viewers.
 
   e. Build the Debug configuration if desired.
-

+
 At this point, the Deploy folder should be fully built out and ready
 to be used.  Both exrdisplay and playexr are meant to be launched from
 the command line, as they originated as unix commands, so open a command
diff --git a/Source/OpenEXR/Copyrights/openexr/AUTHORS b/Source/OpenEXR/Copyrights/openexr/AUTHORS
index 2926b13..e16202d 100644
--- a/Source/OpenEXR/Copyrights/openexr/AUTHORS
+++ b/Source/OpenEXR/Copyrights/openexr/AUTHORS
@@ -8,6 +8,8 @@ Paul Schneider <paultschneider at mac.com>
 Bill Anderson <wja at ilm.com>
 Wojciech Jarosz <wjarosz at ucsd.edu>
 Andrew Kunz <akunz at ilm.com>
+Piotr Stanczyk <pstanczyk at ilm.com>
+Peter Hillman <peterh at weta.co.nz>
 
 Contributors:
 -------------
@@ -20,6 +22,10 @@ Rodrigo Damazio <rdamazio at lsi.usp.br>
 Greg Ward <gward at lmi.net>
 Joseph Goldstone <joseph at lp.com>
 Loren Carpenter, Pixar Animation Studios
+Nicholas Yue <yue.nicholas at gmail.com>
+Yunfeng Bai (ILM)
+Pascal Jette (Autodesk)
+Karl Rasche, DreamWorks Animation <Karl.Rasche at dreamworks.com>
 
 Win32 build system:
 -------------------
diff --git a/Source/OpenEXR/Copyrights/openexr/ChangeLog b/Source/OpenEXR/Copyrights/openexr/ChangeLog
index 58212f4..32a2cae 100644
--- a/Source/OpenEXR/Copyrights/openexr/ChangeLog
+++ b/Source/OpenEXR/Copyrights/openexr/ChangeLog
@@ -1,5 +1,43 @@
+Version 2.0.1
+	* Temporarily turning off optimisation code path
+	  (Piotr Stanczyk)
+	* Added additional tests for future optimisation refactoring
+	  (Piotr Stanczyk / Peter Hillman)
+	* Fixes for StringVectors
+	  (Peter Hillman)
+	* Additional checks for type mismatches
+	  (Peter Hillman)
+	* Fix for Composite Deep Scanline
+	  (Brendan Bolles)
+
+Version 2.0.0
+	* Updated Documentation
+	   (Peter Hillman)
+	* Updated Namespacing mechanism
+	   (Piotr Stanczyk)
+	* Fixes for succd & predd
+	   (Peter Hillman)
+	* Fixes for FPE control registers
+	   (Piotr Stanczyk)
+	* Additional checks and tests on DeepImages, scanlines and tiles
+	   (Peter Hillman)
+	* Folded in Autodesk read optimisations for RGB(A) files
+	  (Pascal Jette, Peter Hillman)
+	* Updated the bootstrap scripts to use libtoolize if glibtoolize isn't available on darwin. 
+	  (Nick Rasmussen)
+	* Numerous minor fixes, missing includes etc
+
+Version 2.0.0.beta.1:
+* Please read the separate file for v2 additions and changes.
+	* Added git specific files 
+	  (Piotr Stanczyk)
+	* Updated the so verison to 20
+	  (Piotr Stanczyk)
+	* Initial use of the CMake build system 
+	  (Nicholas Yue)
+
 Version 1.7.1:
-        * Updated the .so verison to 7.
+	* Updated the .so verison to 7.
 	  (Piotr Stanczyk)     
 
 Version 1.7.0:
diff --git a/Source/OpenEXR/Copyrights/openexr/PATENTS b/Source/OpenEXR/Copyrights/openexr/PATENTS
new file mode 100644
index 0000000..ce9fb28
--- /dev/null
+++ b/Source/OpenEXR/Copyrights/openexr/PATENTS
@@ -0,0 +1,23 @@
+Additional IP Rights Grant (Patents) "DreamWorks Lossy Compression" means the
+copyrightable works distributed by DreamWorks Animation as part of the OpenEXR
+Project. Within the OpenEXR project, DreamWorks Animation hereby grants to you
+a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable 
+(except as stated in this section) patent license to make, have made, use, 
+import, sell products which incorporate this IP as part of the OpenEXR 
+standard, transfer, and otherwise run, modify and propagate the contents of 
+this implementation of DreamWorks Lossy Compression within the OpenEXR standard,
+where such license applies only to those patent claims, both currently owned by 
+DreamWorks Animation and acquired in the future, licensable by DreamWorks
+Animation that are necessarily infringed by this implementation of DreamWorks 
+Lossy Compression. This grant does not include use of DreamWorks Lossy 
+Compression outside of the OpenEXR standard. This grant does not include claims
+that would be infringed only as a consequence of further modification of this 
+implementation. If you or your agent or exclusive licensee institute or order 
+or agree to the institution of patent litigation against any entity (including
+a cross-claim or counterclaim in a lawsuit) alleging that this implementation 
+of DreamWorks Lossy Compression or any code incorporated within this 
+implementation of DreamWorks Lossy Compression constitutes direct or 
+contributory patent infringement, or inducement of patent infringement, then 
+any patent rights granted to you under this License for this implementation 
+of DreamWorks Lossy Compression shall terminate as of the date such litigation
+is filed.
diff --git a/Source/OpenEXR/Copyrights/openexr/README b/Source/OpenEXR/Copyrights/openexr/README
index 3d9d9c1..7038b1c 100644
--- a/Source/OpenEXR/Copyrights/openexr/README
+++ b/Source/OpenEXR/Copyrights/openexr/README
@@ -41,8 +41,17 @@ GNU/Linux or other UNIX-like systems, do this:
 make
 make install
 
-unless you obtained OpenEXR directly from CVS, in which case you
-should first read README.CVS.
+unless you obtained IlmBase directly from git, in which case you
+should first read README.git
+
+
+Please type :
+
+./configure --help
+
+for a list of options in relation to building IlmBase libraries. In 
+particular, peruse README.namespaces for information regarding the 
+use of namespaces in IlmBase and OpenEXR.
 
 See README.OSX for details on building OpenEXR in MacOS X.
 
diff --git a/Source/OpenEXR/Copyrights/openexr/README.CVS b/Source/OpenEXR/Copyrights/openexr/README.CVS
index 90a4fa3..daee537 100644
--- a/Source/OpenEXR/Copyrights/openexr/README.CVS
+++ b/Source/OpenEXR/Copyrights/openexr/README.CVS
@@ -1,16 +1,16 @@
-If you're using OpenEXR from CVS, you should run the bootstrap script
-to create the auto* files.  It's a good idea to run this whenever you
-update OpenEXR from CVS.
-
-Then run './configure' and make.
-
-Note that the configure.ac file requires a fairly new version of
-automake.  If you get this error message:
-
-running aclocal ...
-aclocal: configure.ac: 142: macro `AM_CFLAGS' not found in library
-aclocal: configure.ac: 143: macro `AM_CXXFLAGS' not found in library
-failed!
-
-you should upgrade your automake to version 1.6 or better.
-
+If you're using OpenEXR from CVS, you should run the bootstrap script
+to create the auto* files.  It's a good idea to run this whenever you
+update OpenEXR from CVS.
+
+Then run './configure' and make.
+
+Note that the configure.ac file requires a fairly new version of
+automake.  If you get this error message:
+
+running aclocal ...
+aclocal: configure.ac: 142: macro `AM_CFLAGS' not found in library
+aclocal: configure.ac: 143: macro `AM_CXXFLAGS' not found in library
+failed!
+
+you should upgrade your automake to version 1.6 or better.
+
diff --git a/Source/OpenEXR/Copyrights/openexr/README.OSX b/Source/OpenEXR/Copyrights/openexr/README.OSX
index 0cbab78..646646d 100644
--- a/Source/OpenEXR/Copyrights/openexr/README.OSX
+++ b/Source/OpenEXR/Copyrights/openexr/README.OSX
@@ -5,6 +5,42 @@ Building OpenEXR on MacOS X is just like building it on GNU/Linux.
 Follow the instructions in the README file under BUILDLING OPENEXR,
 but see below re: shared libraries.
 
+Missing gnu automake tools on  Mac OS X 10.8+
+------------------
+Later versions of OS X ,10.8+, do not, by default have all the necessary 
+tools for building. In particular,  Autoconf and Automake may be missing. 
+
+The following commands will download and install the necessary components:
+
+cd ~/myDevLoc
+curl -OL http://ftpmirror.gnu.org/autoconf/autoconf-2.64.tar.gz
+tar xzf autoconf-2.64.tar.gz
+cd autoconf-2.64
+./configure --prefix=~/myDevLoc/autotools-bin
+make; make install
+
+cd ~/myDevLoc
+curl -OL http://ftpmirror.gnu.org/automake/automake-1.12.tar.gz
+tar xzf automake-1.12.tar.gz
+cd automake-1.12
+./configure --prefix=~/myDevLoc/autotools-bin
+make; make install
+
+cd ~/myDevLoc
+curl -OL http://ftpmirror.gnu.org/libtool/libtool-2.4.tar.gz
+tar xzf libtool-2.4.tar.gz
+cd libtool-2.4
+./configure --prefix=~/myDevLoc/autotools-bin
+make; make install
+
+
+You may want to export the installation path for your convenience.
+Finally, make sure that you have installed the command line tools for XCode.
+
+
+Universal Builds on Mac OS X
+------------------
+
 On OS X 10.4, you can build universal binaries by passing
 '--enable-osx-universal-binaries --disable-dependency-tracking' to the
 configure script.  The default is *not* to build universal binaries.
diff --git a/Source/OpenEXR/Copyrights/openexr/README.git b/Source/OpenEXR/Copyrights/openexr/README.git
new file mode 100644
index 0000000..d963e72
--- /dev/null
+++ b/Source/OpenEXR/Copyrights/openexr/README.git
@@ -0,0 +1,16 @@
+If you're using IlmBase from github, you should run the bootstrap script 
+to create the auto* files.  It's a good idea to run this whenever you
+update IlmBase from github.
+
+Then run './configure' and make.
+
+Note that the configure.ac file requires a fairly new version of
+automake.  If you get this error message:
+
+running aclocal ...
+aclocal: configure.ac: 142: macro `AM_CFLAGS' not found in library
+aclocal: configure.ac: 143: macro `AM_CXXFLAGS' not found in library
+failed!
+
+you should upgrade your automake to version 1.6 or better.
+
diff --git a/Source/OpenEXR/Copyrights/openexr/README.namespacing b/Source/OpenEXR/Copyrights/openexr/README.namespacing
new file mode 100644
index 0000000..ffae65f
--- /dev/null
+++ b/Source/OpenEXR/Copyrights/openexr/README.namespacing
@@ -0,0 +1,83 @@
+------------------------------------------------
+ On the use of namespace in IlmBase and OpenEXR
+------------------------------------------------
+
+v2.0 of the code base introduces user configurable namespaces for
+component libraries. This addition introduces the ability to deal with 
+multiple versions of these libraries loaded at runtime.
+An example case:
+    Application is built with OpenEXR v1.7, but the required plugin 
+    requires functionality from OpenEXR v2.0.
+    
+    By injecting the version number into the (mangled) symbols, via
+    the namespacing mechanism, and changing the soname, via the build
+    system, the developer can link his plugin against the v2.0 library
+    At run time the dynamic linker can load both the 1.7 and 2.0
+    versions of the library since the library soname are different and
+    the symbols are different.
+    
+
+When building IlmBase or OpenEXR the following configure script options 
+are available:
+    --enable-namespaceversioning
+and
+    --enable-customusernamespace
+
+
+
+-- Internal Library Namespace
+The option, --enable-namespaceversioning, controls the namespace that 
+is used in the library. Without an argument (see below) the library 
+will be built with a suffix made up of the major and minor versions.
+For example, for version 2.0.0, the internal library namespaces will be
+Imath_2_0, Iex_2_0, IlmThread_2_0 etc
+
+For additional flexibility and control, this option can take an additional 
+argument in which case the internal library namespace will be suffixed 
+accordingly. 
+For example: 
+    ./configure --enable-namespaceversioning=ILM
+will result in the namespaces of the type Imath_ILM, Iex_ILM etc.
+
+This can be useful for completely isolating your local build.
+
+Code using the library should continue to use the namespace Imath, or for
+greater portability IMATH_NAMESPACE, to refer to objects in libImath. 
+In particular, the explicit use of the internal namespace is discouraged.
+This ensures that code will continue to compile with customised or future 
+versions of the library, which may have a different internal namespace.
+
+Similarily, for other namespaces in the libraries: Iex, IlmThread and IlmImf.
+
+Note that this scheme allows existing code to compile without modifications, 
+since the 'old' namespaces Imath, Iex, IlmThread and IlmImf continue to be 
+available, albeit in a slightly different form.
+This is achieved via the following, in the Imath case: 
+    namespace IMATH_INTERNAL_NAMESPACE {}
+    namespace IMATH_NAMESPACE 
+    {
+         using namespace IMATH_INTERNAL_NAMESPACE;
+    }
+This is included in all header files in the Imath library and similar ones
+are present for the libraries Iex, IlmThread and IlmImf.
+
+The only exception to this is where user code has forward declarations of 
+objects in the Imf namespace, as these will forward declare symbols in an 
+incorrect namespace
+These forward declarations should be removed, and replaced with 
+    #include <ImfForward.h>, 
+which forward-declares all types correctly.
+
+
+
+-- Public/User Library Namespace
+The option, --enable-customusernamespace, can override the namespace into 
+which we will 'export' the internal namespace. This takes an argument 
+that sets the name of the custom user namespace.
+In the example above, IMATH_NAMESPACE could be resolved into something other
+than Imath, say Imath_MySpecialNamespace.
+
+In nearly all cases, this will not be used as per the above discussion
+regarding code compatibility.
+Its presence is to provide a mechanism for not prohibiting the case when 
+the application must pass objects from two different versions of the library.
diff --git a/Source/OpenEXR/Copyrights/openexr/README.win32 b/Source/OpenEXR/Copyrights/openexr/README.win32
index 060908d..e69de29 100644
--- a/Source/OpenEXR/Copyrights/openexr/README.win32
+++ b/Source/OpenEXR/Copyrights/openexr/README.win32
@@ -1,197 +0,0 @@
-OpenEXR is one of six software packages that were designed to work
-together: IlmBase, PyIlmBase, OpenEXR, OpenEXR_Viewers, CTL and
-OpenEXR_CTL.  You may only be interested in OpenEXR or you may want
-to build it together wth the other packages.
-
-What follows are instructions for building all five packages.
-If you are only interested in OpenEXR, stop after step 2.
-
-A couple of notes before getting started:
-
-- This is not the only way to do this. This document describes a path
-that doesn't involve installing libraries into default system paths,
-but rather, creates a standalone universe.
-- Some of these steps may be a bit redundant, and will be optimized in
-the future.
-- The Debug versions of the libraries and tools are not required if
-you are not going to be doing any debugging, and can be optionally
-built.
-
-The source will build under both Visual Studio versions 7 and 8, and 
-there are separate directories for the corresponding build files.  The
-tag <vc7|8> is used in this document to describe the appropriate folder
-in the path that corresponds to your the version of Visual Studio.
-
-The Visual Studio project files assume, and help build out, a directory
-called "Deploy".   In the end, this directory will contain the objects
-that might then be moved away from the source for general running of the
-compiled programs.  The directory structure at the end of compiling all
-the related tools looks like this:
-
-Deploy
-  include
-  lib
-    Debug
-    Release
-  bin
-    Debug
-    Release
-openexr-cvs (name as desired)
-  IlmBase
-  PyIlmBase
-  OpenEXR
-  OpenEXR_Viewers
-ctl-cvs (name as desired)
-  CTL
-  OpenEXR_CTL
-fltk
-  FL
-  GL
-  lib
-nvidia
-  include
-    GL
-    glh
-  lib
-
-If OpenEXR_Viewers is not being compiled, then fltk and nvidia will
-not be needed, but that will be covered later.
-
-Step 1. Compile IlmBase
-
-  a. Point Visual Studio at the .sln file in vc\<vc7|8>\IlmBase in the
-  IlmBase subdirectory
-
-  b. Select the Release configuration and hit Build Solution.  This
-  will create the Deploy directory, and copy the relevant parts to it.
-
-  c. If the debug versions are desired, select the Debug configuration
-  and hit Build Solution.  This will add the Debug directories to Deploy.
-
-Step 2. Compile OpenEXR support
-
-  a. Retrieve the zlib binaries. The project files are set up to link
-     against the dll version of zlib, but can easily be changed to link
-     against a static version, or a self-built version if desired.
-
-    1. Go to http://www.zlib.net and download the precompiled DLL
-       version of zlib (as of writing, zlib123-dll.zip)
-
-    2. If you don't wish to put the files into your MS visual studio
-       directories and install the dll into windows\system32:
-
-        a. Put a copy of zlib1.dll into Deploy\bin\Release and
-           Deploy\bin\Debug
-
-        b. Copy the header files into Deploy\include
-
-        c. Copy zdll.lib and zdll.exp into Deploy\lib\Release and
-           Deploy\lib\Debug
-
-  b. Open the Visual Studio project in OpenEXR\vc\<vc7|8>\OpenEXR.
-
-  c. Select the Release configuration and build. The IlmImfTest
-     program runs a confidence test of your build to make sure
-     it is able to work, and may take some time to complete.
-
-  d. Optionally select the Debug configuration and build.
-
-Step 3. Compile CTL support
-
-  a. Open the Visual Studio project in CTL\vc\<vc7|8>\CTL.
-
-  b. Select the Release configuration and build. The IlmCtlTest
-     program runs a confidence test of your build to make sure it is
-     able to work, and may take some time to complete.
-
-  c. Optionally select the Debug configuration and build.
-
-Step 4. Compile OpenEXR_CTL support
-
-  a. Open the Visual Studio project in OpenEXR_CTL\vc\<vc7|8>\OpenEXR_CTL.
-
-  b. Select the Release configuration and build.
-
-  c. Optionally select the Debug configuration and build.
-
-Step 5. Compile OpenEXR_Viewers
-
-  a. Open the appropriate Visual Studio project in 
-     OpenEXR_Viewers\vc\<vc7|8>\OpenEXR_Viewers depending on whether or not
-     you want CTL support.
-
-  b. exrdisplay requires fltk to work.
-
-    1. Go to http://www.fltk.org and download fltk 1.1.7
-
-    2. Open its project files and compile using the instructions they
-       provide.
-
-    3. Create the fltk directory at the top level of your directory
-       structure as presented above and copy the FL, GL, and lib folders
-       into the fltk directory
-
-    4. exrdisplay links fltk statically, so no dll is needed.
-
-  c. playexr requires the nvidia cg library as well as glut and glew.
-
-    1. Setup the cg toolkit
-
-      a. Go to http://developer.nvidia.com, the developer section and
-         download the cg toolkit, version 1.5, and install it.  The path
-         where you choose to install Cg is referred to by the
-         <Cg install location> tag in the steps below.
- 
-      b. During the installation, if the integrate with visual studio
-         option is selected, the header files will be automatically found.
-         Otherwise, copy the directory <Cg install location>\Cg\include\Cg
-         to Deploy\include\Cg
-
-      b. Copy the cg.dll and cgGL.dll from the <Cg install location>\Cg\bin
-         into Deploy\bin\Release and Deploy\bin\Debug, or otherwise make
-         them available (put them in system32, add to path, etc.)
-
-      c. Copy the cg.lib and cgGL.lib from <Cg install location>\Cg\lib
-         into Deploy\lib\Release and Deploy\lib\Debug
-
-    2. Make glut available. This can be done via several mechanisms. 
-       See step 4 below.
-
-    3. Make glew available. This can be done via several mechanisms.
-       http://glew.sourceforge.net is the master site for this
-       library. See step 4 below.
-
-    4. nVidia makes both glut and glew available in their SDK package,
-       which is a fairly large download, but provides a wealth of other
-       information on programming for the GPU, and is generally a useful
-       package, so that is the path chosen for this set up.
-
-      a. Go to http://developer.nvidia.com and download version 10 of the
-         SDK and install it.  It will prompt you to install the Cg toolkit,
-         but this is not necessary as it was handled in step 1.  The path
-         where you choose to install the SDK is referred to by the
-         <SDK install location> tag in the steps below.
-
-      b. Make an nvidia folder at the top level, with an include and
-         lib folder inside it.  Inside the lib folder, make Debug and
-         Release folders.
-
-      c. Copy the <SDK install location>\external\include\GL directory into 
-         nvidia\include the GL and glh folders into nvidia\include.
-
-      d. Copy the glew headers in <SDK install location>\common\GLEW\include\GL
-         into nvidia\include\GL.
-
-      e. Copy <SDK install location>\common\GLEW\lib\glew32.lib and 
-         <SDK install location>\external\lib\glut32.lib into Deploy\bin\Release.
-
-      f. Copy bin\glut32.dll and bin\glew32.dll into Deploy\bin\Release.
-
-  d. Build the Release configuration of the OpenEXR_Viewers.
-
-  e. Build the Debug configuration if desired.
-
-At this point, the Deploy folder should be fully built out and ready
-to be used.  Both exrdisplay and playexr are meant to be launched from
-the command line, as they originated as unix commands, so open a command
-prompt, cd to the Deploy\bin\Release folder and enjoy.
diff --git a/Source/OpenEXR/Half/Makefile.am b/Source/OpenEXR/Half/Makefile.am
deleted file mode 100644
index c591f55..0000000
--- a/Source/OpenEXR/Half/Makefile.am
+++ /dev/null
@@ -1,32 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-INCLUDES = -I$(top_srcdir)/config
-
-lib_LTLIBRARIES = libHalf.la
-
-libHalf_la_SOURCES = half.cpp half.h halfFunction.h halfLimits.h
-
-libHalf_la_LDFLAGS = -version-info @LIBTOOL_VERSION@ -no-undefined
-
-libHalfincludedir = $(includedir)/OpenEXR
-
-libHalfinclude_HEADERS = half.h halfFunction.h halfLimits.h
-
-# these are used to build eLut.h and toFloat.h dynamically
-EXTRA_DIST = eLut.cpp toFloat.cpp
-
-CLEANFILES = eLut eLut.h toFloat toFloat.h
-
-eLut_SOURCES = eLut.cpp
-
-toFloat_SOURCES = toFloat.cpp
-
-eLut.h:	eLut
-	./eLut > eLut.h
-
-toFloat.h: toFloat
-	   ./toFloat > toFloat.h
-
-BUILT_SOURCES = eLut.h toFloat.h
-
-noinst_PROGRAMS = eLut toFloat
diff --git a/Source/OpenEXR/Half/Makefile.in b/Source/OpenEXR/Half/Makefile.in
deleted file mode 100644
index 51c8024..0000000
--- a/Source/OpenEXR/Half/Makefile.in
+++ /dev/null
@@ -1,558 +0,0 @@
-# Makefile.in generated by automake 1.9.6 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005  Free Software Foundation, Inc.
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
- at SET_MAKE@
-
-
-
-srcdir = @srcdir@
-top_srcdir = @top_srcdir@
-VPATH = @srcdir@
-pkgdatadir = $(datadir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-top_builddir = ..
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-INSTALL = @INSTALL@
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-build_triplet = @build@
-host_triplet = @host@
-noinst_PROGRAMS = eLut$(EXEEXT) toFloat$(EXEEXT)
-subdir = Half
-DIST_COMMON = $(libHalfinclude_HEADERS) $(srcdir)/Makefile.am \
-	$(srcdir)/Makefile.in
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
-	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
-	$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
-	$(top_srcdir)/m4/threads.m4 $(top_srcdir)/configure.ac
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
-	$(ACLOCAL_M4)
-mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config/IlmBaseConfig.h
-CONFIG_CLEAN_FILES =
-am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
-am__vpath_adj = case $$p in \
-    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
-    *) f=$$p;; \
-  esac;
-am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
-am__installdirs = "$(DESTDIR)$(libdir)" \
-	"$(DESTDIR)$(libHalfincludedir)"
-libLTLIBRARIES_INSTALL = $(INSTALL)
-LTLIBRARIES = $(lib_LTLIBRARIES)
-libHalf_la_LIBADD =
-am_libHalf_la_OBJECTS = half.lo
-libHalf_la_OBJECTS = $(am_libHalf_la_OBJECTS)
-PROGRAMS = $(noinst_PROGRAMS)
-am_eLut_OBJECTS = eLut.$(OBJEXT)
-eLut_OBJECTS = $(am_eLut_OBJECTS)
-eLut_LDADD = $(LDADD)
-am_toFloat_OBJECTS = toFloat.$(OBJEXT)
-toFloat_OBJECTS = $(am_toFloat_OBJECTS)
-toFloat_LDADD = $(LDADD)
-DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/config
-depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
-CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
-	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
-LTCXXCOMPILE = $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) \
-	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
-	$(AM_CXXFLAGS) $(CXXFLAGS)
-CXXLD = $(CXX)
-CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \
-	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
-COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
-	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
-	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
-	$(AM_CFLAGS) $(CFLAGS)
-CCLD = $(CC)
-LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
-	$(AM_LDFLAGS) $(LDFLAGS) -o $@
-SOURCES = $(libHalf_la_SOURCES) $(eLut_SOURCES) $(toFloat_SOURCES)
-DIST_SOURCES = $(libHalf_la_SOURCES) $(eLut_SOURCES) \
-	$(toFloat_SOURCES)
-libHalfincludeHEADERS_INSTALL = $(INSTALL_HEADER)
-HEADERS = $(libHalfinclude_HEADERS)
-ETAGS = etags
-CTAGS = ctags
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = @ACLOCAL@
-AMDEP_FALSE = @AMDEP_FALSE@
-AMDEP_TRUE = @AMDEP_TRUE@
-AMTAR = @AMTAR@
-AM_CFLAGS = @AM_CFLAGS@
-AM_CXXFLAGS = @AM_CXXFLAGS@
-AR = @AR@
-AUTOCONF = @AUTOCONF@
-AUTOHEADER = @AUTOHEADER@
-AUTOMAKE = @AUTOMAKE@
-AWK = @AWK@
-CC = @CC@
-CCDEPMODE = @CCDEPMODE@
-CFLAGS = @CFLAGS@
-CPP = @CPP@
-CPPFLAGS = @CPPFLAGS@
-CXX = @CXX@
-CXXCPP = @CXXCPP@
-CXXDEPMODE = @CXXDEPMODE@
-CXXFLAGS = @CXXFLAGS@
-CYGPATH_W = @CYGPATH_W@
-DEFS = @DEFS@
-DEPDIR = @DEPDIR@
-DSYMUTIL = @DSYMUTIL@
-DUMPBIN = @DUMPBIN@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EGREP = @EGREP@
-EXEEXT = @EXEEXT@
-FGREP = @FGREP@
-GREP = @GREP@
-HAVE_UCONTEXT_H = @HAVE_UCONTEXT_H@
-ILMBASE_VERSION = @ILMBASE_VERSION@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LD = @LD@
-LDFLAGS = @LDFLAGS@
-LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
-LIBTOOL = @LIBTOOL@
-LIBTOOL_VERSION = @LIBTOOL_VERSION@
-LIPO = @LIPO@
-LN_S = @LN_S@
-LTLIBOBJS = @LTLIBOBJS@
-MAINT = @MAINT@
-MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
-MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
-MAKEINFO = @MAKEINFO@
-NM = @NM@
-NMEDIT = @NMEDIT@
-OBJDUMP = @OBJDUMP@
-OBJEXT = @OBJEXT@
-OTOOL = @OTOOL@
-OTOOL64 = @OTOOL64@
-PACKAGE = @PACKAGE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-PTHREAD_CC = @PTHREAD_CC@
-PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
-PTHREAD_LIBS = @PTHREAD_LIBS@
-RANLIB = @RANLIB@
-SED = @SED@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-STRIP = @STRIP@
-VERSION = @VERSION@
-ac_ct_AR = @ac_ct_AR@
-ac_ct_CC = @ac_ct_CC@
-ac_ct_CXX = @ac_ct_CXX@
-ac_ct_DSYMUTIL = @ac_ct_DSYMUTIL@
-ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
-ac_ct_LIPO = @ac_ct_LIPO@
-ac_ct_NMEDIT = @ac_ct_NMEDIT@
-ac_ct_OBJDUMP = @ac_ct_OBJDUMP@
-ac_ct_OTOOL = @ac_ct_OTOOL@
-ac_ct_OTOOL64 = @ac_ct_OTOOL64@
-ac_ct_RANLIB = @ac_ct_RANLIB@
-ac_ct_STRIP = @ac_ct_STRIP@
-acx_pthread_config = @acx_pthread_config@
-am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
-am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
-am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
-am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
-am__include = @am__include@
-am__leading_dot = @am__leading_dot@
-am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
-bindir = @bindir@
-build = @build@
-build_alias = @build_alias@
-build_cpu = @build_cpu@
-build_os = @build_os@
-build_vendor = @build_vendor@
-datadir = @datadir@
-exec_prefix = @exec_prefix@
-host = @host@
-host_alias = @host_alias@
-host_cpu = @host_cpu@
-host_os = @host_os@
-host_vendor = @host_vendor@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-libdir = @libdir@
-libexecdir = @libexecdir@
-localstatedir = @localstatedir@
-lt_ECHO = @lt_ECHO@
-mandir = @mandir@
-mkdir_p = @mkdir_p@
-oldincludedir = @oldincludedir@
-prefix = @prefix@
-program_transform_name = @program_transform_name@
-sbindir = @sbindir@
-sharedstatedir = @sharedstatedir@
-sysconfdir = @sysconfdir@
-target_alias = @target_alias@
-INCLUDES = -I$(top_srcdir)/config
-lib_LTLIBRARIES = libHalf.la
-libHalf_la_SOURCES = half.cpp half.h halfFunction.h halfLimits.h
-libHalf_la_LDFLAGS = -version-info @LIBTOOL_VERSION@ -no-undefined
-libHalfincludedir = $(includedir)/OpenEXR
-libHalfinclude_HEADERS = half.h halfFunction.h halfLimits.h
-
-# these are used to build eLut.h and toFloat.h dynamically
-EXTRA_DIST = eLut.cpp toFloat.cpp
-CLEANFILES = eLut eLut.h toFloat toFloat.h
-eLut_SOURCES = eLut.cpp
-toFloat_SOURCES = toFloat.cpp
-BUILT_SOURCES = eLut.h toFloat.h
-all: $(BUILT_SOURCES)
-	$(MAKE) $(AM_MAKEFLAGS) all-am
-
-.SUFFIXES:
-.SUFFIXES: .cpp .lo .o .obj
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
-	@for dep in $?; do \
-	  case '$(am__configure_deps)' in \
-	    *$$dep*) \
-	      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
-		&& exit 0; \
-	      exit 1;; \
-	  esac; \
-	done; \
-	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu  Half/Makefile'; \
-	cd $(top_srcdir) && \
-	  $(AUTOMAKE) --gnu  Half/Makefile
-.PRECIOUS: Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
-	@case '$?' in \
-	  *config.status*) \
-	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
-	  *) \
-	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
-	esac;
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-install-libLTLIBRARIES: $(lib_LTLIBRARIES)
-	@$(NORMAL_INSTALL)
-	test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)"
-	@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
-	  if test -f $$p; then \
-	    f=$(am__strip_dir) \
-	    echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
-	    $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
-	  else :; fi; \
-	done
-
-uninstall-libLTLIBRARIES:
-	@$(NORMAL_UNINSTALL)
-	@set -x; list='$(lib_LTLIBRARIES)'; for p in $$list; do \
-	  p=$(am__strip_dir) \
-	  echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
-	  $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
-	done
-
-clean-libLTLIBRARIES:
-	-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
-	@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
-	  dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
-	  test "$$dir" != "$$p" || dir=.; \
-	  echo "rm -f \"$${dir}/so_locations\""; \
-	  rm -f "$${dir}/so_locations"; \
-	done
-libHalf.la: $(libHalf_la_OBJECTS) $(libHalf_la_DEPENDENCIES) 
-	$(CXXLINK) -rpath $(libdir) $(libHalf_la_LDFLAGS) $(libHalf_la_OBJECTS) $(libHalf_la_LIBADD) $(LIBS)
-
-clean-noinstPROGRAMS:
-	@list='$(noinst_PROGRAMS)'; for p in $$list; do \
-	  f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
-	  echo " rm -f $$p $$f"; \
-	  rm -f $$p $$f ; \
-	done
-eLut$(EXEEXT): $(eLut_OBJECTS) $(eLut_DEPENDENCIES) 
-	@rm -f eLut$(EXEEXT)
-	$(CXXLINK) $(eLut_LDFLAGS) $(eLut_OBJECTS) $(eLut_LDADD) $(LIBS)
-toFloat$(EXEEXT): $(toFloat_OBJECTS) $(toFloat_DEPENDENCIES) 
-	@rm -f toFloat$(EXEEXT)
-	$(CXXLINK) $(toFloat_LDFLAGS) $(toFloat_OBJECTS) $(toFloat_LDADD) $(LIBS)
-
-mostlyclean-compile:
-	-rm -f *.$(OBJEXT)
-
-distclean-compile:
-	-rm -f *.tab.c
-
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/eLut.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/half.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/toFloat.Po at am__quote@
-
-.cpp.o:
- at am__fastdepCXX_TRUE@	if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
- at am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(CXXCOMPILE) -c -o $@ $<
-
-.cpp.obj:
- at am__fastdepCXX_TRUE@	if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
- at am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
-
-.cpp.lo:
- at am__fastdepCXX_TRUE@	if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
- at am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(LTCXXCOMPILE) -c -o $@ $<
-
-mostlyclean-libtool:
-	-rm -f *.lo
-
-clean-libtool:
-	-rm -rf .libs _libs
-
-distclean-libtool:
-	-rm -f libtool
-uninstall-info-am:
-install-libHalfincludeHEADERS: $(libHalfinclude_HEADERS)
-	@$(NORMAL_INSTALL)
-	test -z "$(libHalfincludedir)" || $(mkdir_p) "$(DESTDIR)$(libHalfincludedir)"
-	@list='$(libHalfinclude_HEADERS)'; for p in $$list; do \
-	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
-	  f=$(am__strip_dir) \
-	  echo " $(libHalfincludeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(libHalfincludedir)/$$f'"; \
-	  $(libHalfincludeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(libHalfincludedir)/$$f"; \
-	done
-
-uninstall-libHalfincludeHEADERS:
-	@$(NORMAL_UNINSTALL)
-	@list='$(libHalfinclude_HEADERS)'; for p in $$list; do \
-	  f=$(am__strip_dir) \
-	  echo " rm -f '$(DESTDIR)$(libHalfincludedir)/$$f'"; \
-	  rm -f "$(DESTDIR)$(libHalfincludedir)/$$f"; \
-	done
-
-ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
-	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
-	unique=`for i in $$list; do \
-	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
-	mkid -fID $$unique
-tags: TAGS
-
-TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
-		$(TAGS_FILES) $(LISP)
-	tags=; \
-	here=`pwd`; \
-	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
-	unique=`for i in $$list; do \
-	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
-	if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
-	  test -n "$$unique" || unique=$$empty_fix; \
-	  $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
-	    $$tags $$unique; \
-	fi
-ctags: CTAGS
-CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
-		$(TAGS_FILES) $(LISP)
-	tags=; \
-	here=`pwd`; \
-	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
-	unique=`for i in $$list; do \
-	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
-	test -z "$(CTAGS_ARGS)$$tags$$unique" \
-	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
-	     $$tags $$unique
-
-GTAGS:
-	here=`$(am__cd) $(top_builddir) && pwd` \
-	  && cd $(top_srcdir) \
-	  && gtags -i $(GTAGS_ARGS) $$here
-
-distclean-tags:
-	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
-distdir: $(DISTFILES)
-	@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
-	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
-	list='$(DISTFILES)'; for file in $$list; do \
-	  case $$file in \
-	    $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
-	    $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
-	  esac; \
-	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
-	  dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
-	  if test "$$dir" != "$$file" && test "$$dir" != "."; then \
-	    dir="/$$dir"; \
-	    $(mkdir_p) "$(distdir)$$dir"; \
-	  else \
-	    dir=''; \
-	  fi; \
-	  if test -d $$d/$$file; then \
-	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
-	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
-	    fi; \
-	    cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
-	  else \
-	    test -f $(distdir)/$$file \
-	    || cp -p $$d/$$file $(distdir)/$$file \
-	    || exit 1; \
-	  fi; \
-	done
-check-am: all-am
-check: $(BUILT_SOURCES)
-	$(MAKE) $(AM_MAKEFLAGS) check-am
-all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS)
-installdirs:
-	for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libHalfincludedir)"; do \
-	  test -z "$$dir" || $(mkdir_p) "$$dir"; \
-	done
-install: $(BUILT_SOURCES)
-	$(MAKE) $(AM_MAKEFLAGS) install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
-	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
-	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	  `test -z '$(STRIP)' || \
-	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
-mostlyclean-generic:
-
-clean-generic:
-	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
-
-distclean-generic:
-	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-
-maintainer-clean-generic:
-	@echo "This command is intended for maintainers to use"
-	@echo "it deletes files that may require special tools to rebuild."
-	-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
-clean: clean-am
-
-clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
-	clean-noinstPROGRAMS mostlyclean-am
-
-distclean: distclean-am
-	-rm -rf ./$(DEPDIR)
-	-rm -f Makefile
-distclean-am: clean-am distclean-compile distclean-generic \
-	distclean-libtool distclean-tags
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-info: info-am
-
-info-am:
-
-install-data-am: install-libHalfincludeHEADERS
-
-install-exec-am: install-libLTLIBRARIES
-
-install-info: install-info-am
-
-install-man:
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
-	-rm -rf ./$(DEPDIR)
-	-rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-compile mostlyclean-generic \
-	mostlyclean-libtool
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am: uninstall-info-am uninstall-libHalfincludeHEADERS \
-	uninstall-libLTLIBRARIES
-
-.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
-	clean-libLTLIBRARIES clean-libtool clean-noinstPROGRAMS ctags \
-	distclean distclean-compile distclean-generic \
-	distclean-libtool distclean-tags distdir dvi dvi-am html \
-	html-am info info-am install install-am install-data \
-	install-data-am install-exec install-exec-am install-info \
-	install-info-am install-libHalfincludeHEADERS \
-	install-libLTLIBRARIES install-man install-strip installcheck \
-	installcheck-am installdirs maintainer-clean \
-	maintainer-clean-generic mostlyclean mostlyclean-compile \
-	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
-	tags uninstall uninstall-am uninstall-info-am \
-	uninstall-libHalfincludeHEADERS uninstall-libLTLIBRARIES
-
-
-eLut.h:	eLut
-	./eLut > eLut.h
-
-toFloat.h: toFloat
-	   ./toFloat > toFloat.h
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
diff --git a/Source/OpenEXR/Half/half.cpp b/Source/OpenEXR/Half/half.cpp
index 1a3f650..609aaa1 100644
--- a/Source/OpenEXR/Half/half.cpp
+++ b/Source/OpenEXR/Half/half.cpp
@@ -53,11 +53,10 @@ using namespace std;
 // Lookup tables for half-to-float and float-to-half conversion
 //-------------------------------------------------------------
 
-HALF_EXPORT_CONST half::uif half::_toFloat[1 << 16] =
-#include "toFloat.h"
-HALF_EXPORT_CONST unsigned short half::_eLut[1 << 9] =
-#include "eLut.h"
-
+HALF_EXPORT const half::uif half::_toFloat[1 << 16] =
+    #include "toFloat.h"
+HALF_EXPORT const unsigned short half::_eLut[1 << 9] =
+    #include "eLut.h"
 
 //-----------------------------------------------
 // Overflow handler for float-to-half conversion;
@@ -65,7 +64,7 @@ HALF_EXPORT_CONST unsigned short half::_eLut[1 << 9] =
 // which may be trapped by the operating system.
 //-----------------------------------------------
 
-float
+HALF_EXPORT float
 half::overflow ()
 {
     volatile float f = 1e10;
@@ -82,7 +81,7 @@ half::overflow ()
 // zeroes, denormalized numbers and exponent overflows.
 //-----------------------------------------------------
 
-short
+HALF_EXPORT short
 half::convert (int i)
 {
     //
@@ -222,7 +221,7 @@ half::convert (int i)
 // Stream I/O operators
 //---------------------
 
-ostream &
+HALF_EXPORT ostream &
 operator << (ostream &os, half h)
 {
     os << float (h);
@@ -230,7 +229,7 @@ operator << (ostream &os, half h)
 }
 
 
-istream &
+HALF_EXPORT istream &
 operator >> (istream &is, half &h)
 {
     float f;
@@ -245,7 +244,7 @@ operator >> (istream &is, half &h)
 // floats and halfs, mostly for debugging
 //---------------------------------------
 
-void
+HALF_EXPORT void
 printBits (ostream &os, half h)
 {
     unsigned short b = h.bits();
@@ -260,7 +259,7 @@ printBits (ostream &os, half h)
 }
 
 
-void
+HALF_EXPORT void
 printBits (ostream &os, float f)
 {
     half::uif x;
@@ -276,7 +275,7 @@ printBits (ostream &os, float f)
 }
 
 
-void
+HALF_EXPORT void
 printBits (char c[19], half h)
 {
     unsigned short b = h.bits();
@@ -293,7 +292,7 @@ printBits (char c[19], half h)
 }
 
 
-void
+HALF_EXPORT void
 printBits (char c[35], float f)
 {
     half::uif x;
diff --git a/Source/OpenEXR/Half/half.h b/Source/OpenEXR/Half/half.h
index 5e707ef..f78e4f6 100644
--- a/Source/OpenEXR/Half/half.h
+++ b/Source/OpenEXR/Half/half.h
@@ -85,21 +85,10 @@
 #ifndef _HALF_H_
 #define _HALF_H_
 
+#include "halfExport.h"    // for definition of HALF_EXPORT
 #include <iostream>
 
-#if defined(OPENEXR_DLL)
-    #if defined(HALF_EXPORTS)
-	#define HALF_EXPORT __declspec(dllexport)
-    #else
-	#define HALF_EXPORT __declspec(dllimport)
-    #endif
-    #define HALF_EXPORT_CONST
-#else
-    #define HALF_EXPORT
-    #define HALF_EXPORT_CONST const
-#endif
-
-class HALF_EXPORT half
+class half
 {
   public:
 
@@ -208,8 +197,8 @@ class HALF_EXPORT half
     // Access to the internal representation
     //--------------------------------------
 
-    unsigned short	bits () const;
-    void		setBits (unsigned short bits);
+    HALF_EXPORT unsigned short	bits () const;
+    HALF_EXPORT void		setBits (unsigned short bits);
 
 
   public:
@@ -222,31 +211,33 @@ class HALF_EXPORT half
 
   private:
 
-    static short	convert (int i);
-    static float	overflow ();
+    HALF_EXPORT static short                  convert (int i);
+    HALF_EXPORT static float                  overflow ();
 
-    unsigned short	_h;
+    unsigned short                            _h;
 
-    static HALF_EXPORT_CONST uif		_toFloat[1 << 16];
-    static HALF_EXPORT_CONST unsigned short _eLut[1 << 9];
+    HALF_EXPORT static const uif              _toFloat[1 << 16];
+    HALF_EXPORT static const unsigned short   _eLut[1 << 9];
 };
 
+
+
 //-----------
 // Stream I/O
 //-----------
 
-HALF_EXPORT std::ostream &		operator << (std::ostream &os, half  h);
-HALF_EXPORT std::istream &		operator >> (std::istream &is, half &h);
+HALF_EXPORT std::ostream &      operator << (std::ostream &os, half  h);
+HALF_EXPORT std::istream &      operator >> (std::istream &is, half &h);
 
 
 //----------
 // Debugging
 //----------
 
-HALF_EXPORT void			printBits   (std::ostream &os, half  h);
-HALF_EXPORT void			printBits   (std::ostream &os, float f);
-HALF_EXPORT void			printBits   (char  c[19], half  h);
-HALF_EXPORT void			printBits   (char  c[35], float f);
+HALF_EXPORT void        printBits   (std::ostream &os, half  h);
+HALF_EXPORT void        printBits   (std::ostream &os, float f);
+HALF_EXPORT void        printBits   (char  c[19], half  h);
+HALF_EXPORT void        printBits   (char  c[35], float f);
 
 
 //-------------------------------------------------------------------------
diff --git a/Source/OpenEXR/Half/halfExport.h b/Source/OpenEXR/Half/halfExport.h
new file mode 100644
index 0000000..3a0c86a
--- /dev/null
+++ b/Source/OpenEXR/Half/halfExport.h
@@ -0,0 +1,27 @@
+#ifndef HALFEXPORT_H
+#define HALFEXPORT_H
+
+//
+//  Copyright (c) 2008 Lucasfilm Entertainment Company Ltd.
+//  All rights reserved.   Used under authorization.
+//  This material contains the confidential and proprietary
+//  information of Lucasfilm Entertainment Company and
+//  may not be copied in whole or in part without the express
+//  written permission of Lucasfilm Entertainment Company.
+//  This copyright notice does not imply publication.
+//
+
+#if defined(OPENEXR_DLL)
+    #if defined(HALF_EXPORTS)
+    #define HALF_EXPORT __declspec(dllexport)
+    #else
+    #define HALF_EXPORT __declspec(dllimport)
+    #endif
+    #define HALF_EXPORT_CONST
+#else
+    #define HALF_EXPORT
+    #define HALF_EXPORT_CONST const
+#endif
+
+#endif // #ifndef HALFEXPORT_H
+
diff --git a/Source/OpenEXR/Half/halfFunction.h b/Source/OpenEXR/Half/halfFunction.h
index 37dbf50..98c1d17 100644
--- a/Source/OpenEXR/Half/halfFunction.h
+++ b/Source/OpenEXR/Half/halfFunction.h
@@ -85,7 +85,7 @@
 
 #include "half.h"
 
-#include <IlmBaseConfig.h>
+#include "IlmBaseConfig.h"
 #ifndef ILMBASE_HAVE_LARGE_STACK  
 #include <string.h>     // need this for memset
 #else 
@@ -123,6 +123,7 @@ class halfFunction
     T		operator () (half x) const;
 
   private:
+
 #ifdef ILMBASE_HAVE_LARGE_STACK
     T		_lut[1 << 16];
 #else
diff --git a/Source/OpenEXR/Iex/IexBaseExc.cpp b/Source/OpenEXR/Iex/IexBaseExc.cpp
index c85b0c2..3b2e197 100644
--- a/Source/OpenEXR/Iex/IexBaseExc.cpp
+++ b/Source/OpenEXR/Iex/IexBaseExc.cpp
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -40,14 +40,22 @@
 //
 //---------------------------------------------------------------------
 
+#include "IexExport.h"
 #include "IexBaseExc.h"
+#include "IexMacros.h"
 
-namespace Iex {
-namespace {
+#ifdef PLATFORM_WINDOWS
+#include <windows.h>
+#endif
 
+#include <stdlib.h>
+
+IEX_INTERNAL_NAMESPACE_SOURCE_ENTER
 
-StackTracer currentStackTracer = 0;
 
+namespace {
+
+StackTracer currentStackTracer = 0;
 
 } // namespace
 
@@ -125,5 +133,24 @@ BaseExc::append (std::stringstream &s)
     return *this;
 }
 
+IEX_INTERNAL_NAMESPACE_SOURCE_EXIT
 
-} // namespace Iex
+
+#ifdef PLATFORM_WINDOWS
+
+#pragma optimize("", off)
+void
+iex_debugTrap()
+{
+    if (0 != getenv("IEXDEBUGTHROW"))
+        ::DebugBreak();
+}
+#else
+void
+iex_debugTrap()
+{
+    // how to in Linux?
+    if (0 != ::getenv("IEXDEBUGTHROW"))
+        __builtin_trap();
+}
+#endif
diff --git a/Source/OpenEXR/Iex/IexBaseExc.h b/Source/OpenEXR/Iex/IexBaseExc.h
index 9d8ab24..bf016f7 100644
--- a/Source/OpenEXR/Iex/IexBaseExc.h
+++ b/Source/OpenEXR/Iex/IexBaseExc.h
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -33,10 +33,11 @@
 ///////////////////////////////////////////////////////////////////////////
 
 
-
 #ifndef INCLUDED_IEXBASEEXC_H
 #define INCLUDED_IEXBASEEXC_H
 
+#include "IexNamespace.h"
+#include "IexExport.h"
 
 //----------------------------------------------------------
 //
@@ -49,12 +50,8 @@
 #include <exception>
 #include <sstream>
 
-namespace Iex {
+IEX_INTERNAL_NAMESPACE_HEADER_ENTER
 
-#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
-// Tell MS VC++ to suppress exception specification warnings
-#pragma warning(disable:4290)
-#endif
 
 //-------------------------------
 // Our most basic exception class
@@ -68,29 +65,29 @@ class BaseExc: public std::string, public std::exception
     // Constructors and destructor
     //----------------------------
 
-    BaseExc (const char *s = 0) throw();	// std::string (s)
-    BaseExc (const std::string &s) throw();	// std::string (s)
-    BaseExc (std::stringstream &s) throw();	// std::string (s.str())
+    IEX_EXPORT BaseExc (const char *s = 0) throw();     // std::string (s)
+    IEX_EXPORT BaseExc (const std::string &s) throw();  // std::string (s)
+    IEX_EXPORT BaseExc (std::stringstream &s) throw();  // std::string (s.str())
 
-    BaseExc (const BaseExc &be) throw();
-    virtual ~BaseExc () throw ();
+    IEX_EXPORT BaseExc (const BaseExc &be) throw();
+    IEX_EXPORT virtual ~BaseExc () throw ();
 
     //--------------------------------------------
     // what() method -- e.what() returns e.c_str()
     //--------------------------------------------
 
-    virtual const char * what () const throw ();
+    IEX_EXPORT virtual const char * what () const throw ();
 
 
     //--------------------------------------------------
     // Convenient methods to change the exception's text
     //--------------------------------------------------
 
-    BaseExc &		assign (std::stringstream &s);	// assign (s.str())
-    BaseExc &		operator = (std::stringstream &s);
+    IEX_EXPORT BaseExc &            assign (std::stringstream &s);	// assign (s.str())
+    IEX_EXPORT BaseExc &            operator = (std::stringstream &s);
 
-    BaseExc &		append (std::stringstream &s);	// append (s.str())
-    BaseExc &		operator += (std::stringstream &s);
+    IEX_EXPORT BaseExc &            append (std::stringstream &s);	// append (s.str())
+    IEX_EXPORT BaseExc &            operator += (std::stringstream &s);
 
 
     //--------------------------------------------------
@@ -98,11 +95,11 @@ class BaseExc: public std::string, public std::exception
     // the definitions above.
     //--------------------------------------------------
 
-    BaseExc &		assign (const char *s);
-    BaseExc &		operator = (const char *s);
+    IEX_EXPORT BaseExc &            assign (const char *s);
+    IEX_EXPORT BaseExc &            operator = (const char *s);
 
-    BaseExc &		append (const char *s);
-    BaseExc &		operator += (const char *s);
+    IEX_EXPORT BaseExc &            append (const char *s);
+    IEX_EXPORT BaseExc &            operator += (const char *s);
 
 
     //--------------------------------------------------
@@ -112,11 +109,11 @@ class BaseExc: public std::string, public std::exception
     // has been installed (see below, setStackTracer()).
     //--------------------------------------------------
 
-    const std::string &	stackTrace () const;
+    IEX_EXPORT const std::string &  stackTrace () const;
 
   private:
 
-    std::string		_stackTrace;
+    std::string                     _stackTrace;
 };
 
 
@@ -125,50 +122,54 @@ class BaseExc: public std::string, public std::exception
 // class derived directly or indirectly from BaseExc:
 //-----------------------------------------------------
 
-#define DEFINE_EXC(name, base)				        \
-    class name: public base				        \
-    {							        \
+#define DEFINE_EXC_EXP(exp, name, base)                         \
+    class exp name: public base                                 \
+    {                                                           \
       public:                                                   \
-	name (const char* text=0)      throw(): base (text) {}	\
-	name (const std::string &text) throw(): base (text) {}	\
-	name (std::stringstream &text) throw(): base (text) {}	\
+        name()                         throw(): base (0)    {}  \
+        name (const char* text)        throw(): base (text) {}  \
+        name (const std::string &text) throw(): base (text) {}  \
+        name (std::stringstream &text) throw(): base (text) {}  \
+        ~name() throw() { }                                     \
     };
 
+// For backward compatibility.
+#define DEFINE_EXC(name, base) DEFINE_EXC_EXP(, name, base)
+
 
 //--------------------------------------------------------
 // Some exceptions which should be useful in most programs
 //--------------------------------------------------------
+DEFINE_EXC_EXP (IEX_EXPORT, ArgExc, BaseExc)    // Invalid arguments to a function call
 
-DEFINE_EXC (ArgExc,   BaseExc) 	 // Invalid arguments to a function call
-
-DEFINE_EXC (LogicExc, BaseExc) 	 // General error in a program's logic,
-				 // for example, a function was called
-				 // in a context where the call does
-				 // not make sense.
+DEFINE_EXC_EXP (IEX_EXPORT, LogicExc, BaseExc)  // General error in a program's logic,
+                                                // for example, a function was called
+                                                // in a context where the call does
+                                                // not make sense.
 
-DEFINE_EXC (InputExc, BaseExc) 	 // Invalid input data, e.g. from a file
+DEFINE_EXC_EXP (IEX_EXPORT, InputExc, BaseExc)  // Invalid input data, e.g. from a file
 
-DEFINE_EXC (IoExc, BaseExc) 	 // Input or output operation failed
+DEFINE_EXC_EXP (IEX_EXPORT, IoExc, BaseExc)     // Input or output operation failed
 
-DEFINE_EXC (MathExc,  BaseExc) 	 // Arithmetic exception; more specific
-				 // exceptions derived from this class
-				 // are defined in ExcMath.h
+DEFINE_EXC_EXP (IEX_EXPORT, MathExc, BaseExc) 	// Arithmetic exception; more specific
+                                                // exceptions derived from this class
+                                                // are defined in ExcMath.h
 
-DEFINE_EXC (ErrnoExc, BaseExc) 	 // Base class for exceptions corresponding
-				 // to errno values (see errno.h); more
-				 // specific exceptions derived from this
-				 // class are defined in ExcErrno.h
+DEFINE_EXC_EXP (IEX_EXPORT, ErrnoExc, BaseExc)  // Base class for exceptions corresponding
+                                                // to errno values (see errno.h); more
+                                                // specific exceptions derived from this
+                                                // class are defined in ExcErrno.h
 
-DEFINE_EXC (NoImplExc, BaseExc)  // Missing method exception e.g. from a
-				 // call to a method that is only partially
-				 // or not at all implemented. A reminder
-				 // to lazy software people to get back
-				 // to work.
+DEFINE_EXC_EXP (IEX_EXPORT, NoImplExc, BaseExc) // Missing method exception e.g. from a
+                                                // call to a method that is only partially
+                                                // or not at all implemented. A reminder
+                                                // to lazy software people to get back
+                                                // to work.
 
-DEFINE_EXC (NullExc, BaseExc) 	 // A pointer is inappropriately null.
+DEFINE_EXC_EXP (IEX_EXPORT, NullExc, BaseExc)   // A pointer is inappropriately null.
 
-DEFINE_EXC (TypeExc, BaseExc) 	 // An object is an inappropriate type,
-				 // i.e. a dynamnic_cast failed.
+DEFINE_EXC_EXP (IEX_EXPORT, TypeExc, BaseExc)   // An object is an inappropriate type,
+                                                // i.e. a dynamnic_cast failed.
 
 
 //----------------------------------------------------------------------
@@ -199,8 +200,8 @@ DEFINE_EXC (TypeExc, BaseExc) 	 // An object is an inappropriate type,
 
 typedef std::string (* StackTracer) ();
 
-void		setStackTracer (StackTracer stackTracer);
-StackTracer	stackTracer ();
+IEX_EXPORT void        setStackTracer (StackTracer stackTracer);
+IEX_EXPORT StackTracer stackTracer ();
 
 
 //-----------------
@@ -257,10 +258,7 @@ BaseExc::stackTrace () const
     return _stackTrace;
 }
 
-#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
-#pragma warning(default:4290)
-#endif
 
-} // namespace Iex
+IEX_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_IEXBASEEXC_H
diff --git a/Source/OpenEXR/Iex/IexErrnoExc.h b/Source/OpenEXR/Iex/IexErrnoExc.h
index 53cc28f..027c7a4 100644
--- a/Source/OpenEXR/Iex/IexErrnoExc.h
+++ b/Source/OpenEXR/Iex/IexErrnoExc.h
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -45,8 +45,7 @@
 
 #include "IexBaseExc.h"
 
-namespace Iex {
-
+IEX_INTERNAL_NAMESPACE_HEADER_ENTER
 
 DEFINE_EXC (EpermExc, ErrnoExc)
 DEFINE_EXC (EnoentExc, ErrnoExc)
@@ -204,7 +203,6 @@ DEFINE_EXC (EcantextentExc, ErrnoExc)
 DEFINE_EXC (EinvaltimeExc, ErrnoExc)
 DEFINE_EXC (EdestroyedExc, ErrnoExc)
 
-
-} // namespace Iex
+IEX_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/Source/OpenEXR/Iex/IexExport.h b/Source/OpenEXR/Iex/IexExport.h
new file mode 100644
index 0000000..270c1cf
--- /dev/null
+++ b/Source/OpenEXR/Iex/IexExport.h
@@ -0,0 +1,51 @@
+#ifndef IEXEXPORT_H
+#define IEXEXPORT_H
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2012, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission. 
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#if defined(OPENEXR_DLL)
+    #if defined(IEX_EXPORTS)
+    #define IEX_EXPORT __declspec(dllexport)
+    #else
+    #define IEX_EXPORT __declspec(dllimport)
+    #endif
+    #define IEX_EXPORT_CONST
+#else
+    #define IEX_EXPORT
+    #define IEX_EXPORT_CONST const
+#endif
+
+#endif // #ifndef IEXEXPORT_H
+
diff --git a/Source/OpenEXR/Iex/IexForward.h b/Source/OpenEXR/Iex/IexForward.h
new file mode 100644
index 0000000..743771c
--- /dev/null
+++ b/Source/OpenEXR/Iex/IexForward.h
@@ -0,0 +1,229 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2012, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission. 
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef INCLUDED_IEXFORWARD_H
+#define INCLUDED_IEXFORWARD_H
+
+#include "IexNamespace.h"
+
+IEX_INTERNAL_NAMESPACE_HEADER_ENTER
+
+//
+// Base exceptions.
+//
+
+class BaseExc;
+class ArgExc;
+class LogicExc;
+class InputExc;
+class IoExc;
+class MathExc;
+class ErrnoExc;
+class NoImplExc;
+class NullExc;
+class TypeExc;
+
+//
+// Math exceptions.
+//
+
+class OverflowExc;
+class UnderflowExc;
+class DivzeroExc;
+class InexactExc;
+class InvalidFpOpExc;
+
+//
+// Errno exceptions.
+//
+
+class EpermExc;
+class EnoentExc;
+class EsrchExc;
+class EintrExc;
+class EioExc;
+class EnxioExc;
+class E2bigExc;
+class EnoexecExc;
+class EbadfExc;
+class EchildExc;
+class EagainExc;
+class EnomemExc;
+class EaccesExc;
+class EfaultExc;
+class EnotblkExc;
+class EbusyExc;
+class EexistExc;
+class ExdevExc;
+class EnodevExc;
+class EnotdirExc;
+class EisdirExc;
+class EinvalExc;
+class EnfileExc;
+class EmfileExc;
+class EnottyExc;
+class EtxtbsyExc;
+class EfbigExc;
+class EnospcExc;
+class EspipeExc;
+class ErofsExc;
+class EmlinkExc;
+class EpipeExc;
+class EdomExc;
+class ErangeExc;
+class EnomsgExc;
+class EidrmExc;
+class EchrngExc;
+class El2nsyncExc;
+class El3hltExc;
+class El3rstExc;
+class ElnrngExc;
+class EunatchExc;
+class EnocsiExc;
+class El2hltExc;
+class EdeadlkExc;
+class EnolckExc;
+class EbadeExc;
+class EbadrExc;
+class ExfullExc;
+class EnoanoExc;
+class EbadrqcExc;
+class EbadsltExc;
+class EdeadlockExc;
+class EbfontExc;
+class EnostrExc;
+class EnodataExc;
+class EtimeExc;
+class EnosrExc;
+class EnonetExc;
+class EnopkgExc;
+class EremoteExc;
+class EnolinkExc;
+class EadvExc;
+class EsrmntExc;
+class EcommExc;
+class EprotoExc;
+class EmultihopExc;
+class EbadmsgExc;
+class EnametoolongExc;
+class EoverflowExc;
+class EnotuniqExc;
+class EbadfdExc;
+class EremchgExc;
+class ElibaccExc;
+class ElibbadExc;
+class ElibscnExc;
+class ElibmaxExc;
+class ElibexecExc;
+class EilseqExc;
+class EnosysExc;
+class EloopExc;
+class ErestartExc;
+class EstrpipeExc;
+class EnotemptyExc;
+class EusersExc;
+class EnotsockExc;
+class EdestaddrreqExc;
+class EmsgsizeExc;
+class EprototypeExc;
+class EnoprotooptExc;
+class EprotonosupportExc;
+class EsocktnosupportExc;
+class EopnotsuppExc;
+class EpfnosupportExc;
+class EafnosupportExc;
+class EaddrinuseExc;
+class EaddrnotavailExc;
+class EnetdownExc;
+class EnetunreachExc;
+class EnetresetExc;
+class EconnabortedExc;
+class EconnresetExc;
+class EnobufsExc;
+class EisconnExc;
+class EnotconnExc;
+class EshutdownExc;
+class EtoomanyrefsExc;
+class EtimedoutExc;
+class EconnrefusedExc;
+class EhostdownExc;
+class EhostunreachExc;
+class EalreadyExc;
+class EinprogressExc;
+class EstaleExc;
+class EioresidExc;
+class EucleanExc;
+class EnotnamExc;
+class EnavailExc;
+class EisnamExc;
+class EremoteioExc;
+class EinitExc;
+class EremdevExc;
+class EcanceledExc;
+class EnolimfileExc;
+class EproclimExc;
+class EdisjointExc;
+class EnologinExc;
+class EloginlimExc;
+class EgrouploopExc;
+class EnoattachExc;
+class EnotsupExc;
+class EnoattrExc;
+class EdircorruptedExc;
+class EdquotExc;
+class EnfsremoteExc;
+class EcontrollerExc;
+class EnotcontrollerExc;
+class EenqueuedExc;
+class EnotenqueuedExc;
+class EjoinedExc;
+class EnotjoinedExc;
+class EnoprocExc;
+class EmustrunExc;
+class EnotstoppedExc;
+class EclockcpuExc;
+class EinvalstateExc;
+class EnoexistExc;
+class EendofminorExc;
+class EbufsizeExc;
+class EemptyExc;
+class EnointrgroupExc;
+class EinvalmodeExc;
+class EcantextentExc;
+class EinvaltimeExc;
+class EdestroyedExc;
+
+IEX_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif // INCLUDED_IEXFORWARD_H
diff --git a/Source/OpenEXR/Iex/IexMacros.h b/Source/OpenEXR/Iex/IexMacros.h
index e3988a2..18d37bd 100644
--- a/Source/OpenEXR/Iex/IexMacros.h
+++ b/Source/OpenEXR/Iex/IexMacros.h
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -55,13 +55,19 @@
 //	
 //----------------------------------------------------------------------------
 
-#define THROW(type, text)	\
-    do				\
-    {				\
-	std::stringstream s;	\
-	s << text;		\
-	throw type (s);		\
-    }				\
+#include "IexExport.h"
+#include "IexForward.h"
+
+IEX_EXPORT void iex_debugTrap();
+
+#define THROW(type, text)       \
+    do                          \
+    {                           \
+        iex_debugTrap();        \
+        std::stringstream s;	\
+        s << text;              \
+        throw type (s);         \
+    }                           \
     while (0)
 
 
@@ -88,22 +94,22 @@
 //	}
 //----------------------------------------------------------------------------
 
-#define APPEND_EXC(exc, text)	\
-    do				\
-    {				\
-	std::stringstream s;	\
-	s << text;		\
-	exc.append (s);		\
-    }				\
+#define APPEND_EXC(exc, text)   \
+    do                          \
+    {                           \
+        std::stringstream s;    \
+        s << text;              \
+        exc.append (s);         \
+    }                           \
     while (0)
 
-#define REPLACE_EXC(exc, text)	\
-    do				\
-    {				\
-	std::stringstream s;	\
-	s << text;		\
-	exc.assign (s);		\
-    }				\
+#define REPLACE_EXC(exc, text)  \
+    do                          \
+    {                           \
+        std::stringstream s;    \
+        s << text;              \
+        exc.assign (s);         \
+    }                           \
     while (0)
 
 
@@ -117,13 +123,13 @@
 //
 //-------------------------------------------------------------
 
-#define THROW_ERRNO(text)		\
-    do					\
-    {					\
-	std::stringstream s;		\
-	s << text;			\
-	::Iex::throwErrnoExc (s.str());	\
-    }					\
+#define THROW_ERRNO(text)                         \
+    do                                            \
+    {                                             \
+        std::stringstream s;                      \
+        s << text;                                \
+        ::IEX_NAMESPACE::throwErrnoExc (s.str()); \
+    }                                             \
     while (0)
 
 
@@ -132,17 +138,33 @@
 //
 // Example:
 //
-//	ASSERT (ptr != NULL, NullExc, "Null pointer" );
+//	ASSERT (ptr != 0, NullExc, "Null pointer" );
 //
 //-------------------------------------------------------------
 
 #define ASSERT(assertion, type, text)   \
     do                                  \
     {                                   \
-	if ((assertion) == false)       \
-	    THROW (type, text);         \
+        if( (assertion) == false )      \
+        {                               \
+            THROW( type, text );        \
+        }                               \
     }                                   \
     while (0)
 
+//-------------------------------------------------------------
+// A macro to throw an IEX_NAMESPACE::LogicExc if an assertion is false,
+// with the text composed from the source code file, line number,
+// and assertion argument text.
+//
+// Example:
+//
+//      LOGIC_ASSERT (i < n);
+//
+//-------------------------------------------------------------
+#define LOGIC_ASSERT(assertion)           \
+    ASSERT(assertion,                     \
+           IEX_NAMESPACE::LogicExc,       \
+           __FILE__ << "(" << __LINE__ << "): logical assertion failed: " << #assertion )
 
 #endif
diff --git a/Source/OpenEXR/Iex/IexMathExc.h b/Source/OpenEXR/Iex/IexMathExc.h
index 4ef90d3..795f500 100644
--- a/Source/OpenEXR/Iex/IexMathExc.h
+++ b/Source/OpenEXR/Iex/IexMathExc.h
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -39,7 +39,7 @@
 
 #include "IexBaseExc.h"
 
-namespace Iex {
+IEX_INTERNAL_NAMESPACE_HEADER_ENTER
 
 //---------------------------------------------------------
 // Exception classess which correspond to specific floating
@@ -52,7 +52,6 @@ DEFINE_EXC (DivzeroExc,     MathExc)	// Division by zero
 DEFINE_EXC (InexactExc,     MathExc)	// Inexact result
 DEFINE_EXC (InvalidFpOpExc, MathExc)	// Invalid operation
 
+IEX_INTERNAL_NAMESPACE_HEADER_EXIT
 
-} // namespace Iex
-
-#endif
+#endif // INCLUDED_IEXMATHEXC_H
diff --git a/Source/OpenEXR/Iex/IexNamespace.h b/Source/OpenEXR/Iex/IexNamespace.h
new file mode 100644
index 0000000..bef1572
--- /dev/null
+++ b/Source/OpenEXR/Iex/IexNamespace.h
@@ -0,0 +1,112 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2012, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission. 
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef INCLUDED_IEXNAMESPACE_H
+#define INCLUDED_IEXNAMESPACE_H
+
+//
+// The purpose of this file is to make it possible to specify an
+// IEX_INTERNAL_NAMESPACE as a preprocessor definition and have all of the
+// Iex symbols defined within that namespace rather than the standard
+// Iex namespace.  Those symbols are made available to client code through
+// the IEX_NAMESPACE in addition to the IEX_INTERNAL_NAMESPACE.
+//
+// To ensure source code compatibility, the IEX_NAMESPACE defaults to Iex
+// and then "using namespace IEX_INTERNAL_NAMESPACE;" brings all of the
+// declarations from the IEX_INTERNAL_NAMESPACE into the IEX_NAMESPACE.  This
+// means that client code can continue to use syntax like Iex::BaseExc, but
+// at link time it will resolve to a mangled symbol based on the
+// IEX_INTERNAL_NAMESPACE.
+//
+// As an example, if one needed to build against a newer version of Iex and
+// have it run alongside an older version in the same application, it is now
+// possible to use an internal namespace to prevent collisions between the
+// older versions of Iex symbols and the newer ones.  To do this, the
+// following could be defined at build time:
+//
+// IEX_INTERNAL_NAMESPACE = Iex_v2
+//
+// This means that declarations inside Iex headers look like this (after the
+// preprocessor has done its work):
+//
+// namespace Iex_v2 {
+//     ...
+//     class declarations
+//     ...
+// }
+//
+// namespace Iex {
+//     using namespace Iex_v2;
+// }
+//
+
+//
+// Open Source version of this file pulls in the IlmBaseConfig.h file
+// for the configure time options.
+//
+#include "IlmBaseConfig.h"
+
+#ifndef IEX_NAMESPACE
+#define IEX_NAMESPACE Iex
+#endif
+
+#ifndef IEX_INTERNAL_NAMESPACE
+#define IEX_INTERNAL_NAMESPACE IEX_NAMESPACE
+#endif
+
+//
+// We need to be sure that we import the internal namespace into the public one.
+// To do this, we use the small bit of code below which initially defines
+// IEX_INTERNAL_NAMESPACE (so it can be referenced) and then defines
+// IEX_NAMESPACE and pulls the internal symbols into the public namespace.
+//
+
+namespace IEX_INTERNAL_NAMESPACE {}
+namespace IEX_NAMESPACE {
+    using namespace IEX_INTERNAL_NAMESPACE;
+}
+
+//
+// There are identical pairs of HEADER/SOURCE ENTER/EXIT macros so that
+// future extension to the namespace mechanism is possible without changing
+// project source code.
+//
+
+#define IEX_INTERNAL_NAMESPACE_HEADER_ENTER namespace IEX_INTERNAL_NAMESPACE {
+#define IEX_INTERNAL_NAMESPACE_HEADER_EXIT }
+
+#define IEX_INTERNAL_NAMESPACE_SOURCE_ENTER namespace IEX_INTERNAL_NAMESPACE {
+#define IEX_INTERNAL_NAMESPACE_SOURCE_EXIT }
+
+#endif // INCLUDED_IEXNAMESPACE_H
diff --git a/Source/OpenEXR/Iex/IexThrowErrnoExc.cpp b/Source/OpenEXR/Iex/IexThrowErrnoExc.cpp
index 410a45c..32e7fb2 100644
--- a/Source/OpenEXR/Iex/IexThrowErrnoExc.cpp
+++ b/Source/OpenEXR/Iex/IexThrowErrnoExc.cpp
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -46,11 +46,20 @@
 #include <string.h>
 #include <errno.h>
 
-namespace Iex {
+#ifdef PLATFORM_WINDOWS
+#include <windows.h>
+#endif
+
+IEX_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 void throwErrnoExc (const std::string &text, int errnum)
 {
+#ifdef PLATFORM_WINDOWS
+    if (0 != getenv("IEXDEBUGTHROW"))
+        DebugBreak();
+#endif
+
     const char *entext = strerror (errnum);
     std::string tmp (text);
     std::string::size_type pos;
@@ -855,5 +864,10 @@ void throwErrnoExc (const std::string &text)
     throwErrnoExc (text, errno);
 }
 
+void throwErrnoExc()
+{
+    std::string txt = "%T.";
+    throwErrnoExc (txt);
+}
 
-} // namespace Iex
+IEX_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/Iex/IexThrowErrnoExc.h b/Source/OpenEXR/Iex/IexThrowErrnoExc.h
index 5b41dcc..224ed2b 100644
--- a/Source/OpenEXR/Iex/IexThrowErrnoExc.h
+++ b/Source/OpenEXR/Iex/IexThrowErrnoExc.h
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -44,8 +44,9 @@
 //----------------------------------------------------------
 
 #include "IexBaseExc.h"
+#include "IexExport.h"
 
-namespace Iex {
+IEX_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 //--------------------------------------------------------------------------
@@ -87,10 +88,10 @@ namespace Iex {
 //
 //--------------------------------------------------------------------------
 
-void throwErrnoExc (const std::string &txt, int errnum);
-void throwErrnoExc (const std::string &txt = "%T." /*, int errnum = oserror() */);
+IEX_EXPORT void throwErrnoExc(const std::string &txt, int errnum);
+IEX_EXPORT void throwErrnoExc(const std::string &txt);
+IEX_EXPORT void throwErrnoExc();
 
+IEX_INTERNAL_NAMESPACE_HEADER_EXIT
 
-} // namespace Iex
-
-#endif
+#endif // INCLUDED_IEXTHROWERRNOEXC_H
diff --git a/Source/OpenEXR/Iex/Makefile.am b/Source/OpenEXR/Iex/Makefile.am
deleted file mode 100644
index 9b6df1b..0000000
--- a/Source/OpenEXR/Iex/Makefile.am
+++ /dev/null
@@ -1,16 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-INCLUDES = -I$(top_srcdir)/config
-
-lib_LTLIBRARIES = libIex.la
-
-libIex_la_SOURCES = IexThrowErrnoExc.cpp IexBaseExc.cpp IexBaseExc.h \
-		    IexErrnoExc.h Iex.h IexMacros.h IexMathExc.h \
-		    IexThrowErrnoExc.h
-
-libIex_la_LDFLAGS = -version-info @LIBTOOL_VERSION@ -no-undefined
-
-libIexincludedir = $(includedir)/OpenEXR
-
-libIexinclude_HEADERS = IexBaseExc.h IexMathExc.h IexThrowErrnoExc.h \
-			IexErrnoExc.h IexMacros.h Iex.h
diff --git a/Source/OpenEXR/Iex/Makefile.in b/Source/OpenEXR/Iex/Makefile.in
deleted file mode 100644
index 942a32d..0000000
--- a/Source/OpenEXR/Iex/Makefile.in
+++ /dev/null
@@ -1,521 +0,0 @@
-# Makefile.in generated by automake 1.9.6 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005  Free Software Foundation, Inc.
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
- at SET_MAKE@
-
-
-srcdir = @srcdir@
-top_srcdir = @top_srcdir@
-VPATH = @srcdir@
-pkgdatadir = $(datadir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-top_builddir = ..
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-INSTALL = @INSTALL@
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-build_triplet = @build@
-host_triplet = @host@
-subdir = Iex
-DIST_COMMON = $(libIexinclude_HEADERS) $(srcdir)/Makefile.am \
-	$(srcdir)/Makefile.in
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
-	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
-	$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
-	$(top_srcdir)/m4/threads.m4 $(top_srcdir)/configure.ac
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
-	$(ACLOCAL_M4)
-mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config/IlmBaseConfig.h
-CONFIG_CLEAN_FILES =
-am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
-am__vpath_adj = case $$p in \
-    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
-    *) f=$$p;; \
-  esac;
-am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
-am__installdirs = "$(DESTDIR)$(libdir)" \
-	"$(DESTDIR)$(libIexincludedir)"
-libLTLIBRARIES_INSTALL = $(INSTALL)
-LTLIBRARIES = $(lib_LTLIBRARIES)
-libIex_la_LIBADD =
-am_libIex_la_OBJECTS = IexThrowErrnoExc.lo IexBaseExc.lo
-libIex_la_OBJECTS = $(am_libIex_la_OBJECTS)
-DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/config
-depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
-CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
-	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
-LTCXXCOMPILE = $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) \
-	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
-	$(AM_CXXFLAGS) $(CXXFLAGS)
-CXXLD = $(CXX)
-CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \
-	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
-COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
-	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
-	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
-	$(AM_CFLAGS) $(CFLAGS)
-CCLD = $(CC)
-LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
-	$(AM_LDFLAGS) $(LDFLAGS) -o $@
-SOURCES = $(libIex_la_SOURCES)
-DIST_SOURCES = $(libIex_la_SOURCES)
-libIexincludeHEADERS_INSTALL = $(INSTALL_HEADER)
-HEADERS = $(libIexinclude_HEADERS)
-ETAGS = etags
-CTAGS = ctags
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = @ACLOCAL@
-AMDEP_FALSE = @AMDEP_FALSE@
-AMDEP_TRUE = @AMDEP_TRUE@
-AMTAR = @AMTAR@
-AM_CFLAGS = @AM_CFLAGS@
-AM_CXXFLAGS = @AM_CXXFLAGS@
-AR = @AR@
-AUTOCONF = @AUTOCONF@
-AUTOHEADER = @AUTOHEADER@
-AUTOMAKE = @AUTOMAKE@
-AWK = @AWK@
-CC = @CC@
-CCDEPMODE = @CCDEPMODE@
-CFLAGS = @CFLAGS@
-CPP = @CPP@
-CPPFLAGS = @CPPFLAGS@
-CXX = @CXX@
-CXXCPP = @CXXCPP@
-CXXDEPMODE = @CXXDEPMODE@
-CXXFLAGS = @CXXFLAGS@
-CYGPATH_W = @CYGPATH_W@
-DEFS = @DEFS@
-DEPDIR = @DEPDIR@
-DSYMUTIL = @DSYMUTIL@
-DUMPBIN = @DUMPBIN@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EGREP = @EGREP@
-EXEEXT = @EXEEXT@
-FGREP = @FGREP@
-GREP = @GREP@
-HAVE_UCONTEXT_H = @HAVE_UCONTEXT_H@
-ILMBASE_VERSION = @ILMBASE_VERSION@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LD = @LD@
-LDFLAGS = @LDFLAGS@
-LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
-LIBTOOL = @LIBTOOL@
-LIBTOOL_VERSION = @LIBTOOL_VERSION@
-LIPO = @LIPO@
-LN_S = @LN_S@
-LTLIBOBJS = @LTLIBOBJS@
-MAINT = @MAINT@
-MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
-MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
-MAKEINFO = @MAKEINFO@
-NM = @NM@
-NMEDIT = @NMEDIT@
-OBJDUMP = @OBJDUMP@
-OBJEXT = @OBJEXT@
-OTOOL = @OTOOL@
-OTOOL64 = @OTOOL64@
-PACKAGE = @PACKAGE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-PTHREAD_CC = @PTHREAD_CC@
-PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
-PTHREAD_LIBS = @PTHREAD_LIBS@
-RANLIB = @RANLIB@
-SED = @SED@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-STRIP = @STRIP@
-VERSION = @VERSION@
-ac_ct_AR = @ac_ct_AR@
-ac_ct_CC = @ac_ct_CC@
-ac_ct_CXX = @ac_ct_CXX@
-ac_ct_DSYMUTIL = @ac_ct_DSYMUTIL@
-ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
-ac_ct_LIPO = @ac_ct_LIPO@
-ac_ct_NMEDIT = @ac_ct_NMEDIT@
-ac_ct_OBJDUMP = @ac_ct_OBJDUMP@
-ac_ct_OTOOL = @ac_ct_OTOOL@
-ac_ct_OTOOL64 = @ac_ct_OTOOL64@
-ac_ct_RANLIB = @ac_ct_RANLIB@
-ac_ct_STRIP = @ac_ct_STRIP@
-acx_pthread_config = @acx_pthread_config@
-am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
-am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
-am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
-am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
-am__include = @am__include@
-am__leading_dot = @am__leading_dot@
-am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
-bindir = @bindir@
-build = @build@
-build_alias = @build_alias@
-build_cpu = @build_cpu@
-build_os = @build_os@
-build_vendor = @build_vendor@
-datadir = @datadir@
-exec_prefix = @exec_prefix@
-host = @host@
-host_alias = @host_alias@
-host_cpu = @host_cpu@
-host_os = @host_os@
-host_vendor = @host_vendor@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-libdir = @libdir@
-libexecdir = @libexecdir@
-localstatedir = @localstatedir@
-lt_ECHO = @lt_ECHO@
-mandir = @mandir@
-mkdir_p = @mkdir_p@
-oldincludedir = @oldincludedir@
-prefix = @prefix@
-program_transform_name = @program_transform_name@
-sbindir = @sbindir@
-sharedstatedir = @sharedstatedir@
-sysconfdir = @sysconfdir@
-target_alias = @target_alias@
-INCLUDES = -I$(top_srcdir)/config
-lib_LTLIBRARIES = libIex.la
-libIex_la_SOURCES = IexThrowErrnoExc.cpp IexBaseExc.cpp IexBaseExc.h \
-		    IexErrnoExc.h Iex.h IexMacros.h IexMathExc.h \
-		    IexThrowErrnoExc.h
-
-libIex_la_LDFLAGS = -version-info @LIBTOOL_VERSION@ -no-undefined
-libIexincludedir = $(includedir)/OpenEXR
-libIexinclude_HEADERS = IexBaseExc.h IexMathExc.h IexThrowErrnoExc.h \
-			IexErrnoExc.h IexMacros.h Iex.h
-
-all: all-am
-
-.SUFFIXES:
-.SUFFIXES: .cpp .lo .o .obj
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
-	@for dep in $?; do \
-	  case '$(am__configure_deps)' in \
-	    *$$dep*) \
-	      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
-		&& exit 0; \
-	      exit 1;; \
-	  esac; \
-	done; \
-	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu  Iex/Makefile'; \
-	cd $(top_srcdir) && \
-	  $(AUTOMAKE) --gnu  Iex/Makefile
-.PRECIOUS: Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
-	@case '$?' in \
-	  *config.status*) \
-	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
-	  *) \
-	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
-	esac;
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-install-libLTLIBRARIES: $(lib_LTLIBRARIES)
-	@$(NORMAL_INSTALL)
-	test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)"
-	@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
-	  if test -f $$p; then \
-	    f=$(am__strip_dir) \
-	    echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
-	    $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
-	  else :; fi; \
-	done
-
-uninstall-libLTLIBRARIES:
-	@$(NORMAL_UNINSTALL)
-	@set -x; list='$(lib_LTLIBRARIES)'; for p in $$list; do \
-	  p=$(am__strip_dir) \
-	  echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
-	  $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
-	done
-
-clean-libLTLIBRARIES:
-	-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
-	@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
-	  dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
-	  test "$$dir" != "$$p" || dir=.; \
-	  echo "rm -f \"$${dir}/so_locations\""; \
-	  rm -f "$${dir}/so_locations"; \
-	done
-libIex.la: $(libIex_la_OBJECTS) $(libIex_la_DEPENDENCIES) 
-	$(CXXLINK) -rpath $(libdir) $(libIex_la_LDFLAGS) $(libIex_la_OBJECTS) $(libIex_la_LIBADD) $(LIBS)
-
-mostlyclean-compile:
-	-rm -f *.$(OBJEXT)
-
-distclean-compile:
-	-rm -f *.tab.c
-
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/IexBaseExc.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/IexThrowErrnoExc.Plo at am__quote@
-
-.cpp.o:
- at am__fastdepCXX_TRUE@	if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
- at am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(CXXCOMPILE) -c -o $@ $<
-
-.cpp.obj:
- at am__fastdepCXX_TRUE@	if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
- at am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
-
-.cpp.lo:
- at am__fastdepCXX_TRUE@	if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
- at am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(LTCXXCOMPILE) -c -o $@ $<
-
-mostlyclean-libtool:
-	-rm -f *.lo
-
-clean-libtool:
-	-rm -rf .libs _libs
-
-distclean-libtool:
-	-rm -f libtool
-uninstall-info-am:
-install-libIexincludeHEADERS: $(libIexinclude_HEADERS)
-	@$(NORMAL_INSTALL)
-	test -z "$(libIexincludedir)" || $(mkdir_p) "$(DESTDIR)$(libIexincludedir)"
-	@list='$(libIexinclude_HEADERS)'; for p in $$list; do \
-	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
-	  f=$(am__strip_dir) \
-	  echo " $(libIexincludeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(libIexincludedir)/$$f'"; \
-	  $(libIexincludeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(libIexincludedir)/$$f"; \
-	done
-
-uninstall-libIexincludeHEADERS:
-	@$(NORMAL_UNINSTALL)
-	@list='$(libIexinclude_HEADERS)'; for p in $$list; do \
-	  f=$(am__strip_dir) \
-	  echo " rm -f '$(DESTDIR)$(libIexincludedir)/$$f'"; \
-	  rm -f "$(DESTDIR)$(libIexincludedir)/$$f"; \
-	done
-
-ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
-	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
-	unique=`for i in $$list; do \
-	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
-	mkid -fID $$unique
-tags: TAGS
-
-TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
-		$(TAGS_FILES) $(LISP)
-	tags=; \
-	here=`pwd`; \
-	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
-	unique=`for i in $$list; do \
-	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
-	if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
-	  test -n "$$unique" || unique=$$empty_fix; \
-	  $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
-	    $$tags $$unique; \
-	fi
-ctags: CTAGS
-CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
-		$(TAGS_FILES) $(LISP)
-	tags=; \
-	here=`pwd`; \
-	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
-	unique=`for i in $$list; do \
-	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
-	test -z "$(CTAGS_ARGS)$$tags$$unique" \
-	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
-	     $$tags $$unique
-
-GTAGS:
-	here=`$(am__cd) $(top_builddir) && pwd` \
-	  && cd $(top_srcdir) \
-	  && gtags -i $(GTAGS_ARGS) $$here
-
-distclean-tags:
-	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
-distdir: $(DISTFILES)
-	@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
-	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
-	list='$(DISTFILES)'; for file in $$list; do \
-	  case $$file in \
-	    $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
-	    $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
-	  esac; \
-	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
-	  dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
-	  if test "$$dir" != "$$file" && test "$$dir" != "."; then \
-	    dir="/$$dir"; \
-	    $(mkdir_p) "$(distdir)$$dir"; \
-	  else \
-	    dir=''; \
-	  fi; \
-	  if test -d $$d/$$file; then \
-	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
-	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
-	    fi; \
-	    cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
-	  else \
-	    test -f $(distdir)/$$file \
-	    || cp -p $$d/$$file $(distdir)/$$file \
-	    || exit 1; \
-	  fi; \
-	done
-check-am: all-am
-check: check-am
-all-am: Makefile $(LTLIBRARIES) $(HEADERS)
-installdirs:
-	for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libIexincludedir)"; do \
-	  test -z "$$dir" || $(mkdir_p) "$$dir"; \
-	done
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
-	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
-	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	  `test -z '$(STRIP)' || \
-	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
-mostlyclean-generic:
-
-clean-generic:
-
-distclean-generic:
-	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-
-maintainer-clean-generic:
-	@echo "This command is intended for maintainers to use"
-	@echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
-
-clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
-	mostlyclean-am
-
-distclean: distclean-am
-	-rm -rf ./$(DEPDIR)
-	-rm -f Makefile
-distclean-am: clean-am distclean-compile distclean-generic \
-	distclean-libtool distclean-tags
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-info: info-am
-
-info-am:
-
-install-data-am: install-libIexincludeHEADERS
-
-install-exec-am: install-libLTLIBRARIES
-
-install-info: install-info-am
-
-install-man:
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
-	-rm -rf ./$(DEPDIR)
-	-rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-compile mostlyclean-generic \
-	mostlyclean-libtool
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am: uninstall-info-am uninstall-libIexincludeHEADERS \
-	uninstall-libLTLIBRARIES
-
-.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
-	clean-libLTLIBRARIES clean-libtool ctags distclean \
-	distclean-compile distclean-generic distclean-libtool \
-	distclean-tags distdir dvi dvi-am html html-am info info-am \
-	install install-am install-data install-data-am install-exec \
-	install-exec-am install-info install-info-am \
-	install-libIexincludeHEADERS install-libLTLIBRARIES \
-	install-man install-strip installcheck installcheck-am \
-	installdirs maintainer-clean maintainer-clean-generic \
-	mostlyclean mostlyclean-compile mostlyclean-generic \
-	mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \
-	uninstall-am uninstall-info-am uninstall-libIexincludeHEADERS \
-	uninstall-libLTLIBRARIES
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
diff --git a/Source/OpenEXR/IexMath/IexMathFloatExc.cpp b/Source/OpenEXR/IexMath/IexMathFloatExc.cpp
new file mode 100644
index 0000000..7f492b3
--- /dev/null
+++ b/Source/OpenEXR/IexMath/IexMathFloatExc.cpp
@@ -0,0 +1,113 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 1997-2012, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+//-----------------------------------------------------
+//
+//	A function to control which IEEE floating
+//	point exceptions will be translated into
+//	C++ MathExc exceptions.
+//
+//-----------------------------------------------------
+
+#include <IexMathFloatExc.h>
+#include <IexMacros.h>
+#include <IexMathFpu.h>
+
+#if 0
+    #include <iostream>
+    #define debug(x) (std::cout << x << std::flush)
+#else
+    #define debug(x)
+#endif
+
+IEX_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+
+namespace {
+
+void
+fpeHandler (int type, const char explanation[])
+{
+    switch (type)
+    {
+      case IEEE_OVERFLOW:
+	throw OverflowExc (explanation);
+
+      case IEEE_UNDERFLOW:
+	throw UnderflowExc (explanation);
+
+      case IEEE_DIVZERO:
+	throw DivzeroExc (explanation);
+
+      case IEEE_INEXACT:
+	throw InexactExc (explanation);
+
+      case IEEE_INVALID:
+	throw InvalidFpOpExc (explanation);
+    }
+
+    throw MathExc (explanation);
+}
+
+} // namespace
+
+
+void
+mathExcOn (int when)
+{
+    debug ("mathExcOn (when = 0x" << std::hex << when << ")\n");
+
+    setFpExceptions (when);
+    setFpExceptionHandler (fpeHandler);
+}
+
+
+int
+getMathExcOn ()
+{
+    int when = fpExceptions();
+
+    debug ("getMathExcOn () == 0x" << std::hex << when << ")\n");
+
+    return when;
+}
+
+void
+MathExcOn::handleOutstandingExceptions()
+{
+    handleExceptionsSetInRegisters();
+}
+
+
+IEX_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IexMath/IexMathFloatExc.h b/Source/OpenEXR/IexMath/IexMathFloatExc.h
new file mode 100644
index 0000000..825dba1
--- /dev/null
+++ b/Source/OpenEXR/IexMath/IexMathFloatExc.h
@@ -0,0 +1,146 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission. 
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef INCLUDED_IEXMATHFLOATEXC_H
+#define INCLUDED_IEXMATHFLOATEXC_H
+
+#ifndef IEXMATH_EXPORT_H
+#define IEXMATH_EXPORT_H
+
+#if defined(OPENEXR_DLL)
+    #if defined(IEX_EXPORTS)
+    #define IEXMATH_EXPORT __declspec(dllexport)
+    #else
+    #define IEXMATH_EXPORT __declspec(dllimport)
+    #endif
+    #define IEXMATH_EXPORT_CONST
+#else
+    #define IEXMATH_EXPORT
+    #define IEXMATH_EXPORT_CONST const
+#endif
+
+#endif
+
+#include "IexNamespace.h"
+#include "IexMathExc.h"
+//#include <IexBaseExc.h>
+#include "IexMathIeeeExc.h"
+
+IEX_INTERNAL_NAMESPACE_HEADER_ENTER
+
+
+//-------------------------------------------------------------
+// Function mathExcOn() defines which floating point exceptions
+// will be trapped and converted to C++ exceptions.
+//-------------------------------------------------------------
+
+IEXMATH_EXPORT
+void mathExcOn (int when = (IEEE_OVERFLOW | IEEE_DIVZERO | IEEE_INVALID));
+
+
+//----------------------------------------------------------------------
+// Function getMathExcOn() tells you for which floating point exceptions
+// trapping and conversion to C++ exceptions is currently enabled.
+//----------------------------------------------------------------------
+
+IEXMATH_EXPORT
+int getMathExcOn();
+
+
+//------------------------------------------------------------------------
+// A classs that temporarily sets floating point exception trapping
+// and conversion, and later restores the previous settings.
+//
+// Example:
+//
+//	float
+//	trickyComputation (float x)
+//	{
+//	    MathExcOn meo (0);		// temporarily disable floating
+//	    				// point exception trapping
+//
+//	    float result = ...;		// computation which may cause
+//	    				// floating point exceptions
+//
+//	    return result;		// destruction of meo restores
+//	}				// the program's previous floating
+//					// point exception settings
+//------------------------------------------------------------------------
+
+class IEXMATH_EXPORT MathExcOn
+{
+  public:
+
+    MathExcOn (int when)
+	:
+	_changed (false)
+    {
+	_saved = getMathExcOn(); 
+
+	if (_saved != when)
+	{
+	    _changed = true;
+	    mathExcOn (when);
+	}
+    }
+
+    ~MathExcOn ()
+    {
+	if (_changed)
+	    mathExcOn (_saved);
+    }
+
+    // It is possible for functions to set the exception registers
+    // yet not trigger a SIGFPE.  Specifically, the implementation
+    // of pow(x, y) we're using can generates a NaN from a negative x
+    // and fractional y but a SIGFPE is not generated.
+    // This function examimes the exception registers and calls the
+    // fpHandler if those registers modulo the exception mask are set.
+    // It should be called wherever this class is commonly used where it has
+    // been found that certain floating point exceptions are not being thrown.
+
+    void handleOutstandingExceptions();
+
+  private:
+
+    bool                        _changed;
+    int				_saved;
+};
+
+
+IEX_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif
diff --git a/Source/OpenEXR/IexMath/IexMathFpu.cpp b/Source/OpenEXR/IexMath/IexMathFpu.cpp
new file mode 100644
index 0000000..ff51b09
--- /dev/null
+++ b/Source/OpenEXR/IexMath/IexMathFpu.cpp
@@ -0,0 +1,530 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 1997, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission. 
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+//------------------------------------------------------------------------
+//
+//	Functions to control floating point exceptions.
+//
+//------------------------------------------------------------------------
+
+#include "IexMathFpu.h"
+
+//#include <stdint.h>
+#include <IlmBaseConfig.h>
+#include <stdio.h>
+
+#if 0
+    #include <iostream>
+    #define debug(x) (std::cout << x << std::flush)
+#else
+    #define debug(x)
+#endif
+
+#if defined(HAVE_UCONTEXT_H) && (defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || defined(_M_IX86))
+
+#include <ucontext.h>
+#include <signal.h>
+#include <iostream>
+#include <stdint.h>
+
+
+IEX_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+
+
+namespace FpuControl
+{
+
+//-------------------------------------------------------------------
+//
+//    Modern x86 processors and all AMD64 processors have two
+//    sets of floating-point control/status registers: cw and sw
+//    for legacy x87 stack-based arithmetic, and mxcsr for
+//    SIMD arithmetic.  When setting exception masks or checking
+//    for exceptions, we must set/check all relevant registers,
+//    since applications may contain code that uses either FP
+//    model.
+//
+//    These functions handle both FP models for x86 and AMD64.
+//
+//-------------------------------------------------------------------
+
+//-------------------------------------------------------------------
+//
+//    Restore the control register state from a signal handler
+//    user context, optionally clearing the exception bits
+//    in the restored control register, if applicable.
+//
+//-------------------------------------------------------------------
+
+void restoreControlRegs (const ucontext_t & ucon,
+			 bool clearExceptions = false);
+
+
+//------------------------------------------------------------
+//
+//    Set exception mask bits in the control register state.
+//    A value of 1 means the exception is masked, a value of
+//    0 means the exception is enabled.
+//
+//    setExceptionMask returns the previous mask value.  If
+//    the 'exceptions' pointer is non-null, it returns in 
+//    this argument the FPU exception bits.
+//
+//------------------------------------------------------------
+
+const int INVALID_EXC   = (1<<0);
+const int DENORMAL_EXC  = (1<<1);
+const int DIVZERO_EXC   = (1<<2);
+const int OVERFLOW_EXC  = (1<<3);
+const int UNDERFLOW_EXC = (1<<4);
+const int INEXACT_EXC   = (1<<5);
+const int ALL_EXC       = INVALID_EXC  | DENORMAL_EXC  | DIVZERO_EXC |
+                          OVERFLOW_EXC | UNDERFLOW_EXC | INEXACT_EXC;
+
+int setExceptionMask (int mask, int * exceptions = 0);
+int getExceptionMask ();
+
+
+//---------------------------------------------
+//
+//    Get/clear the exception bits in the FPU.
+//
+//---------------------------------------------
+
+int  getExceptions ();
+void clearExceptions ();
+
+
+//------------------------------------------------------------------
+//
+//    Everything below here is implementation.  Do not use these
+//    constants or functions in your applications or libraries.
+//    This is not the code you're looking for.  Move along.
+//
+//    Optimization notes -- on a Pentium 4, at least, it appears
+//    to be faster to get the mxcsr first and then the cw; and to
+//    set the cw first and then the mxcsr.  Also, it seems to
+//    be faster to clear the sw exception bits after setting
+//    cw and mxcsr.
+//
+//------------------------------------------------------------------
+
+static inline uint16_t
+getSw ()
+{
+    uint16_t sw;
+    asm volatile ("fnstsw %0" : "=m" (sw) : );
+    return sw;
+}
+
+static inline void
+setCw (uint16_t cw)
+{
+    asm volatile ("fldcw %0" : : "m" (cw) );
+}
+
+static inline uint16_t
+getCw ()
+{
+    uint16_t cw;
+    asm volatile ("fnstcw %0" : "=m" (cw) : );
+    return cw;
+}
+
+static inline void
+setMxcsr (uint32_t mxcsr, bool clearExceptions)
+{
+    mxcsr &= clearExceptions ? 0xffffffc0 : 0xffffffff;
+    asm volatile ("ldmxcsr %0" : : "m" (mxcsr) );
+}
+
+static inline uint32_t
+getMxcsr ()
+{
+    uint32_t mxcsr;
+    asm volatile ("stmxcsr %0" : "=m" (mxcsr) : );
+    return mxcsr;
+}
+
+static inline int
+calcMask (uint16_t cw, uint32_t mxcsr)
+{
+    //
+    // Hopefully, if the user has been using FpuControl functions,
+    // the masks are the same, but just in case they're not, we
+    // AND them together to report the proper subset of the masks.
+    //
+
+    return (cw & ALL_EXC) & ((mxcsr >> 7) & ALL_EXC);
+}
+
+inline int
+setExceptionMask (int mask, int * exceptions)
+{
+    uint16_t cw = getCw ();
+    uint32_t mxcsr = getMxcsr ();
+    
+    if (exceptions)
+	*exceptions = (mxcsr & ALL_EXC) | (getSw () & ALL_EXC);
+
+    int oldmask = calcMask (cw, mxcsr);
+
+    //
+    // The exception constants are chosen very carefully so that
+    // we can do a simple mask and shift operation to insert
+    // them into the control words.  The mask operation is for 
+    // safety, in case the user accidentally set some other
+    // bits in the exception mask.
+    //
+
+    mask &= ALL_EXC;
+    cw = (cw & ~ALL_EXC) | mask;
+    mxcsr = (mxcsr & ~(ALL_EXC << 7)) | (mask << 7);
+
+    setCw (cw);
+    setMxcsr (mxcsr, false);
+
+    return oldmask;
+}
+
+inline int
+getExceptionMask ()
+{
+    uint32_t mxcsr = getMxcsr ();
+    uint16_t cw = getCw ();
+    return calcMask (cw, mxcsr);
+}
+
+inline int
+getExceptions ()
+{
+    return (getMxcsr () | getSw ()) & ALL_EXC;
+}
+
+void
+clearExceptions ()
+{
+    uint32_t mxcsr = getMxcsr () & 0xffffffc0;
+    asm volatile ("ldmxcsr %0\n"
+		  "fnclex"
+		  : : "m" (mxcsr) );
+}
+
+// If the fpe was taken while doing a float-to-int cast using the x87,
+// the rounding mode and possibly the precision will be wrong.  So instead
+// of restoring to the state as of the fault, we force the rounding mode
+// to be 'nearest' and the precision to be double extended.
+//
+// rounding mode is in bits 10-11, value 00 == round to nearest
+// precision is in bits 8-9, value 11 == double extended (80-bit)
+//
+const uint16_t cwRestoreMask = ~((3 << 10) | (3 << 8));
+const uint16_t cwRestoreVal = (0 << 10) | (3 << 8);
+
+
+#ifdef ILMBASE_HAVE_CONTROL_REGISTER_SUPPORT
+
+inline void
+restoreControlRegs (const ucontext_t & ucon, bool clearExceptions)
+{
+    setCw ((ucon.uc_mcontext.fpregs->cwd & cwRestoreMask) | cwRestoreVal);
+    setMxcsr (ucon.uc_mcontext.fpregs->mxcsr, clearExceptions);
+}
+
+#else
+
+//
+// Ugly, the mxcsr isn't defined in GNU libc ucontext_t, but
+// it's passed to the signal handler by the kernel.  Use
+// the kernel's version of the ucontext to get it, see
+// <asm/sigcontext.h>
+//
+
+#include <asm/sigcontext.h>
+
+inline void
+restoreControlRegs (const ucontext_t & ucon, bool clearExceptions)
+{
+    setCw ((ucon.uc_mcontext.fpregs->cw & cwRestoreMask) | cwRestoreVal);
+    
+    _fpstate * kfp = reinterpret_cast<_fpstate *> (ucon.uc_mcontext.fpregs);
+    setMxcsr (kfp->magic == 0 ? kfp->mxcsr : 0, clearExceptions);
+}
+
+#endif
+
+} // namespace FpuControl
+
+
+namespace {
+
+volatile FpExceptionHandler fpeHandler = 0;
+
+extern "C" void
+catchSigFpe (int sig, siginfo_t *info, ucontext_t *ucon)
+{
+    debug ("catchSigFpe (sig = "<< sig << ", ...)\n");
+
+    FpuControl::restoreControlRegs (*ucon, true);
+
+    if (fpeHandler == 0)
+	return;
+
+    if (info->si_code == SI_USER)
+    {
+	fpeHandler (0, "Floating-point exception, caused by "
+		       "a signal sent from another process.");
+	return;
+    }
+
+    if (sig == SIGFPE)
+    {
+	switch (info->si_code)
+	{
+	  //
+	  // IEEE 754 floating point exceptions:
+	  //
+
+	  case FPE_FLTDIV:
+	    fpeHandler (IEEE_DIVZERO, "Floating-point division by zero.");
+	    return;
+
+	  case FPE_FLTOVF:
+	    fpeHandler (IEEE_OVERFLOW, "Floating-point overflow.");
+	    return;
+
+	  case FPE_FLTUND:
+	    fpeHandler (IEEE_UNDERFLOW, "Floating-point underflow.");
+	    return;
+
+	  case FPE_FLTRES:
+	    fpeHandler (IEEE_INEXACT, "Inexact floating-point result.");
+	    return;
+
+	  case FPE_FLTINV:
+	    fpeHandler (IEEE_INVALID, "Invalid floating-point operation.");
+	    return;
+
+	  //
+	  // Other arithmetic exceptions which can also
+	  // be trapped by the operating system:
+	  //
+
+	  case FPE_INTDIV:
+	    fpeHandler (0, "Integer division by zero.");
+	    break;
+
+	  case FPE_INTOVF:
+	    fpeHandler (0, "Integer overflow.");
+	    break;
+
+	  case FPE_FLTSUB:
+	    fpeHandler (0, "Subscript out of range.");
+	    break;
+	}
+    }
+
+    fpeHandler (0, "Floating-point exception.");
+}
+
+} // namespace
+
+void
+setFpExceptions (int when)
+{
+    int mask = FpuControl::ALL_EXC;
+
+    if (when & IEEE_OVERFLOW)
+	mask &= ~FpuControl::OVERFLOW_EXC;
+    if (when & IEEE_UNDERFLOW)
+	mask &= ~FpuControl::UNDERFLOW_EXC;
+    if (when & IEEE_DIVZERO)
+	mask &= ~FpuControl::DIVZERO_EXC;
+    if (when & IEEE_INEXACT)
+	mask &= ~FpuControl::INEXACT_EXC;
+    if (when & IEEE_INVALID)
+	mask &= ~FpuControl::INVALID_EXC;
+
+    //
+    // The Linux kernel apparently sometimes passes
+    // incorrect si_info to signal handlers unless
+    // the exception flags are cleared.
+    //
+    // XXX is this still true on 2.4+ kernels?
+    //
+    
+    FpuControl::setExceptionMask (mask);
+    FpuControl::clearExceptions ();
+}
+
+
+int
+fpExceptions ()
+{
+    int mask = FpuControl::getExceptionMask ();
+
+    int when = 0;
+
+    if (!(mask & FpuControl::OVERFLOW_EXC))
+	when |= IEEE_OVERFLOW;
+    if (!(mask & FpuControl::UNDERFLOW_EXC))
+	when |= IEEE_UNDERFLOW;
+    if (!(mask & FpuControl::DIVZERO_EXC))
+	when |= IEEE_DIVZERO;
+    if (!(mask & FpuControl::INEXACT_EXC))
+	when |= IEEE_INEXACT;
+    if (!(mask & FpuControl::INVALID_EXC))
+	when |= IEEE_INVALID;
+
+    return when;
+}
+
+void
+handleExceptionsSetInRegisters()
+{
+    if (fpeHandler == 0)
+	return;
+
+    int mask = FpuControl::getExceptionMask ();
+
+    int exc = FpuControl::getExceptions();
+
+    if (!(mask & FpuControl::DIVZERO_EXC) && (exc & FpuControl::DIVZERO_EXC))
+    {
+        fpeHandler(IEEE_DIVZERO, "Floating-point division by zero.");
+        return;
+    }
+
+    if (!(mask & FpuControl::OVERFLOW_EXC) && (exc & FpuControl::OVERFLOW_EXC))
+    {
+        fpeHandler(IEEE_OVERFLOW, "Floating-point overflow.");
+        return;
+    }
+
+    if (!(mask & FpuControl::UNDERFLOW_EXC) && (exc & FpuControl::UNDERFLOW_EXC))
+    {
+        fpeHandler(IEEE_UNDERFLOW, "Floating-point underflow.");
+        return;
+    }
+
+    if (!(mask & FpuControl::INEXACT_EXC) && (exc & FpuControl::INEXACT_EXC))
+    {
+        fpeHandler(IEEE_INEXACT, "Inexact floating-point result.");
+        return;
+    }
+
+    if (!(mask & FpuControl::INVALID_EXC) && (exc & FpuControl::INVALID_EXC))
+    {
+        fpeHandler(IEEE_INVALID, "Invalid floating-point operation.");
+        return;
+    }
+}
+
+
+void
+setFpExceptionHandler (FpExceptionHandler handler)
+{
+    if (fpeHandler == 0)
+    {
+	struct sigaction action;
+	sigemptyset (&action.sa_mask);
+	action.sa_flags = SA_SIGINFO | SA_NOMASK;
+	action.sa_sigaction = (void (*) (int, siginfo_t *, void *)) catchSigFpe;
+	action.sa_restorer = 0;
+
+	sigaction (SIGFPE, &action, 0);
+    }
+
+    fpeHandler = handler;
+}
+
+
+IEX_INTERNAL_NAMESPACE_SOURCE_EXIT
+
+
+#else
+
+#include <signal.h>
+#include <assert.h>
+
+IEX_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+
+namespace 
+{
+	volatile FpExceptionHandler fpeHandler = 0;
+	void fpExc_(int x)
+	{
+	    if (fpeHandler != 0)
+	    {
+		fpeHandler(x, "");
+	    }
+	    else
+	    {
+		assert(0 != "Floating point exception");
+	    }
+	}
+}
+
+void
+setFpExceptions( int )
+{
+}
+
+
+void
+setFpExceptionHandler (FpExceptionHandler handler)
+{
+    // improve floating point exception handling nanoscopically above "nothing at all"
+    fpeHandler = handler;
+    signal(SIGFPE, fpExc_);
+}
+
+int
+fpExceptions()
+{
+    return 0;
+}
+
+void
+handleExceptionsSetInRegisters()
+{
+    // No implementation on this platform
+}
+
+IEX_INTERNAL_NAMESPACE_SOURCE_EXIT
+
+#endif
diff --git a/Source/OpenEXR/IexMath/IexMathFpu.h b/Source/OpenEXR/IexMath/IexMathFpu.h
new file mode 100644
index 0000000..df2a3e5
--- /dev/null
+++ b/Source/OpenEXR/IexMath/IexMathFpu.h
@@ -0,0 +1,91 @@
+#ifndef INCLUDED_IEXMATHFPU_H
+#define INCLUDED_IEXMATHFPU_H
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 1997, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission. 
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+//------------------------------------------------------------------------
+//
+//	Functions to control floating point exceptions.
+//
+//------------------------------------------------------------------------
+
+#include "IexMathIeeeExc.h"
+#include "IexNamespace.h"
+
+IEX_INTERNAL_NAMESPACE_HEADER_ENTER
+
+
+//-----------------------------------------
+// setFpExceptions() defines which floating
+// point exceptions cause SIGFPE signals.
+//-----------------------------------------
+
+void setFpExceptions (int when = (IEEE_OVERFLOW | IEEE_DIVZERO | IEEE_INVALID));
+
+
+//----------------------------------------
+// fpExceptions() tells you which floating
+// point exceptions cause SIGFPE signals.
+//----------------------------------------
+
+int fpExceptions ();
+
+
+//------------------------------------------
+// setFpExceptionHandler() defines a handler
+// that will be called when SIGFPE occurs.
+//------------------------------------------
+
+extern "C" typedef void (* FpExceptionHandler) (int type, const char explanation[]);
+
+void setFpExceptionHandler (FpExceptionHandler handler);
+
+// -----------------------------------------
+// handleExceptionsSetInRegisters() examines
+// the exception registers and calls the
+// floating point exception handler if the
+// bits are set.  This function exists to 
+// allow trapping of exception register states
+// that can get set though no SIGFPE occurs.
+// -----------------------------------------
+
+void handleExceptionsSetInRegisters();
+
+
+IEX_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+#endif
diff --git a/Source/OpenEXR/IexMath/IexMathIeeeExc.h b/Source/OpenEXR/IexMath/IexMathIeeeExc.h
new file mode 100644
index 0000000..efadebe
--- /dev/null
+++ b/Source/OpenEXR/IexMath/IexMathIeeeExc.h
@@ -0,0 +1,62 @@
+#ifndef INCLUDED_IEXMATHIEEE_EXC_H
+#define INCLUDED_IEXMATHIEEE_EXC_H
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 1997, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission. 
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+//---------------------------------------------------------------------------
+//
+//	Names for the loating point exceptions defined by IEEE standard 754
+//
+//---------------------------------------------------------------------------
+
+#include "IexNamespace.h"
+
+IEX_INTERNAL_NAMESPACE_HEADER_ENTER
+
+
+enum IeeeExcType
+{
+    IEEE_OVERFLOW  = 1,
+    IEEE_UNDERFLOW = 2,
+    IEEE_DIVZERO   = 4,
+    IEEE_INEXACT   = 8,
+    IEEE_INVALID   = 16
+};
+
+
+IEX_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif
diff --git a/Source/OpenEXR/IlmBaseConfig.h b/Source/OpenEXR/IlmBaseConfig.h
index cc8bb9d..203ecba 100644
--- a/Source/OpenEXR/IlmBaseConfig.h
+++ b/Source/OpenEXR/IlmBaseConfig.h
@@ -1,46 +1,61 @@
-//
-// Define and set to 1 if the target system has POSIX thread support
-// and you want OpenEXR to use it for multithreaded file I/O.
-//
-
-#undef HAVE_PTHREAD		// currently disabled in FreeImage
-
-//
-// Define and set to 1 if the target system supports POSIX semaphores
-// and you want OpenEXR to use them; otherwise, OpenEXR will use its
-// own semaphore implementation.
-//
-
+/**
+Define and set to 1 if the target system has POSIX thread support
+and you want IlmBase to use it for multithreaded file I/O.
+*/
+#if defined(_MSC_VER) || defined(__MINGW32__)
+#undef HAVE_PTHREAD
+#else
+#undef HAVE_PTHREAD
+#endif
+
+/**
+Define and set to 1 if the target system supports POSIX semaphores
+and you want OpenEXR to use them; otherwise, OpenEXR will use its
+own semaphore implementation.
+*/
+#if defined(_MSC_VER) || defined(__MINGW32__)
+#undef HAVE_POSIX_SEMAPHORES
+#else
 #undef HAVE_POSIX_SEMAPHORES
+#endif
 
-//
-// Define and set to 1 if the target system is a Darwin-based system
-// (e.g., OS X).
-//
+/**
+Define and set to 1 if the target system has support for large stack sizes.
+*/
+#undef ILMBASE_HAVE_LARGE_STACK
 
-#undef HAVE_DARWIN
+/**
+Current (internal) library namepace name and corresponding public client namespaces.
+*/
+#define ILMBASE_INTERNAL_NAMESPACE_CUSTOM 1
+#define IMATH_INTERNAL_NAMESPACE Imath_2_2
+#define IEX_INTERNAL_NAMESPACE Iex_2_2
+#define ILMTHREAD_INTERNAL_NAMESPACE IlmThread_2_2
 
-//
-// Define and set to 1 if the target system supports a proc filesystem
-// compatible with the Linux kernel's proc filesystem.  Note that this
-// is only used by a program in the IlmImfTest test suite, it's not
-// used by any OpenEXR library or application code.
-//
+#define IMATH_NAMESPACE Imath
+#define IEX_NAMESPACE Iex
+#define ILMTHREAD_NAMESPACE IlmThread
 
-#undef HAVE_LINUX_PROCFS
+/**
+Required for system-specific debug trap code in IexBaseExc.cpp
+*/
+#ifdef _WIN32
+#define PLATFORM_WINDOWS 1
+#endif
 
 //
-// Define and set to 1 if the target system includes the NVIDIA Cg
-// runtime.  The exrdisplay program will use a fragment shader to
-// accelerate the display of OpenEXR images.
+// Version information
 //
+#define ILMBASE_VERSION_STRING "2.2.0"
+#define ILMBASE_PACKAGE_STRING "IlmBase 2.2.0"
 
-#undef HAVE_FRAGMENT_SHADERS
+#define ILMBASE_VERSION_MAJOR 2
+#define ILMBASE_VERSION_MINOR 2
+#define ILMBASE_VERSION_PATCH 0
+
+// Version as a single hex number, e.g. 0x01000300 == 1.0.3
+#define ILMBASE_VERSION_HEX ((ILMBASE_VERSION_MAJOR << 24) | \
+                             (ILMBASE_VERSION_MINOR << 16) | \
+                             (ILMBASE_VERSION_PATCH <<  8))
 
-//
-// Define and set to 1 if the target system has a complete <iomanip>
-// implementation, specifically if it supports the std::right
-// formatter.
-//
 
-#undef HAVE_COMPLETE_IOMANIP
diff --git a/Source/OpenEXR/IlmImf/ImfAcesFile.cpp b/Source/OpenEXR/IlmImf/ImfAcesFile.cpp
index e84f9fe..8f33fb0 100644
--- a/Source/OpenEXR/IlmImf/ImfAcesFile.cpp
+++ b/Source/OpenEXR/IlmImf/ImfAcesFile.cpp
@@ -42,12 +42,14 @@
 #include <ImfRgbaFile.h>
 #include <ImfStandardAttributes.h>
 #include <Iex.h>
+#include <algorithm>
 
 using namespace std;
-using namespace Imath;
-using namespace Iex;
+using namespace IMATH_NAMESPACE;
+using namespace IEX_NAMESPACE;
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 const Chromaticities &
@@ -135,7 +137,7 @@ AcesOutputFile::AcesOutputFile
 
 
 AcesOutputFile::AcesOutputFile
-    (OStream &os,
+    (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
      const Header &header,
      RgbaChannels rgbaChannels,
      int numThreads)
@@ -159,11 +161,11 @@ AcesOutputFile::AcesOutputFile
 
 AcesOutputFile::AcesOutputFile
     (const std::string &name,
-     const Imath::Box2i &displayWindow,
-     const Imath::Box2i &dataWindow,
+     const IMATH_NAMESPACE::Box2i &displayWindow,
+     const IMATH_NAMESPACE::Box2i &dataWindow,
      RgbaChannels rgbaChannels,
      float pixelAspectRatio,
-     const Imath::V2f screenWindowCenter,
+     const IMATH_NAMESPACE::V2f screenWindowCenter,
      float screenWindowWidth,
      LineOrder lineOrder,
      Compression compression,
@@ -199,7 +201,7 @@ AcesOutputFile::AcesOutputFile
      int height,
      RgbaChannels rgbaChannels,
      float pixelAspectRatio,
-     const Imath::V2f screenWindowCenter,
+     const IMATH_NAMESPACE::V2f screenWindowCenter,
      float screenWindowWidth,
      LineOrder lineOrder,
      Compression compression,
@@ -266,14 +268,14 @@ AcesOutputFile::header () const
 }
 
 
-const Imath::Box2i &
+const IMATH_NAMESPACE::Box2i &
 AcesOutputFile::displayWindow () const
 {
     return _data->rgbaFile->displayWindow();
 }
 
 
-const Imath::Box2i &
+const IMATH_NAMESPACE::Box2i &
 AcesOutputFile::dataWindow () const
 {
     return _data->rgbaFile->dataWindow();
@@ -287,7 +289,7 @@ AcesOutputFile::pixelAspectRatio () const
 }
 
 
-const Imath::V2f
+const IMATH_NAMESPACE::V2f
 AcesOutputFile::screenWindowCenter () const
 {
     return _data->rgbaFile->screenWindowCenter();
@@ -552,14 +554,14 @@ AcesInputFile::header () const
 }
 
 
-const Imath::Box2i &
+const IMATH_NAMESPACE::Box2i &
 AcesInputFile::displayWindow () const
 {
     return _data->rgbaFile->displayWindow();
 }
 
 
-const Imath::Box2i &
+const IMATH_NAMESPACE::Box2i &
 AcesInputFile::dataWindow () const
 {
     return _data->rgbaFile->dataWindow();
@@ -573,7 +575,7 @@ AcesInputFile::pixelAspectRatio () const
 }
 
 
-const Imath::V2f
+const IMATH_NAMESPACE::V2f
 AcesInputFile::screenWindowCenter () const
 {
     return _data->rgbaFile->screenWindowCenter();
@@ -628,4 +630,4 @@ AcesInputFile::version () const
     return _data->rgbaFile->version();
 }
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfAcesFile.h b/Source/OpenEXR/IlmImf/ImfAcesFile.h
index 2ab7314..b801a86 100644
--- a/Source/OpenEXR/IlmImf/ImfAcesFile.h
+++ b/Source/OpenEXR/IlmImf/ImfAcesFile.h
@@ -77,20 +77,19 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfHeader.h>
-#include <ImfRgba.h>
+#include "ImfHeader.h"
+#include "ImfRgba.h"
 #include "ImathVec.h"
 #include "ImathBox.h"
-#include <ImfThreading.h>
-#include <string>
+#include "ImfThreading.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+#include "ImfForward.h"
 
-namespace Imf {
+#include <string>
 
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-class RgbaOutputFile;
-class RgbaInputFile;
-struct PreviewRgba;
-class Chromaticities;
 
 //
 // ACES red, green, blue and white-point chromaticities.
@@ -103,7 +102,7 @@ const Chromaticities &	acesChromaticities ();
 // ACES output file.
 //
 
-class AcesOutputFile
+class IMF_EXPORT AcesOutputFile
 {
   public:
 
@@ -123,7 +122,7 @@ class AcesOutputFile
     // automatically close the file.
     //----------------------------------------------------
 
-    AcesOutputFile (OStream &os,
+    AcesOutputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
 		    const Header &header,
 		    RgbaChannels rgbaChannels = WRITE_RGBA,
                     int numThreads = globalThreadCount());
@@ -135,11 +134,11 @@ class AcesOutputFile
     //----------------------------------------------------------------
 
     AcesOutputFile (const std::string &name,
-		    const Imath::Box2i &displayWindow,
-		    const Imath::Box2i &dataWindow = Imath::Box2i(),
+		    const IMATH_NAMESPACE::Box2i &displayWindow,
+		    const IMATH_NAMESPACE::Box2i &dataWindow = IMATH_NAMESPACE::Box2i(),
 		    RgbaChannels rgbaChannels = WRITE_RGBA,
 		    float pixelAspectRatio = 1,
-		    const Imath::V2f screenWindowCenter = Imath::V2f (0, 0),
+		    const IMATH_NAMESPACE::V2f screenWindowCenter = IMATH_NAMESPACE::V2f (0, 0),
 		    float screenWindowWidth = 1,
 		    LineOrder lineOrder = INCREASING_Y,
 		    Compression compression = PIZ_COMPRESSION,
@@ -157,7 +156,7 @@ class AcesOutputFile
 		    int height,
 		    RgbaChannels rgbaChannels = WRITE_RGBA,
 		    float pixelAspectRatio = 1,
-		    const Imath::V2f screenWindowCenter = Imath::V2f (0, 0),
+		    const IMATH_NAMESPACE::V2f screenWindowCenter = IMATH_NAMESPACE::V2f (0, 0),
 		    float screenWindowWidth = 1,
 		    LineOrder lineOrder = INCREASING_Y,
 		    Compression compression = PIZ_COMPRESSION,
@@ -198,10 +197,10 @@ class AcesOutputFile
     //--------------------------
 
     const Header &		header () const;
-    const Imath::Box2i &	displayWindow () const;
-    const Imath::Box2i &	dataWindow () const;
+    const IMATH_NAMESPACE::Box2i &	displayWindow () const;
+    const IMATH_NAMESPACE::Box2i &	dataWindow () const;
     float			pixelAspectRatio () const;
-    const Imath::V2f		screenWindowCenter () const;
+    const IMATH_NAMESPACE::V2f		screenWindowCenter () const;
     float			screenWindowWidth () const;
     LineOrder			lineOrder () const;
     Compression			compression () const;
@@ -230,7 +229,7 @@ class AcesOutputFile
 // ACES input file
 //
 
-class AcesInputFile
+class IMF_EXPORT AcesInputFile
 {
   public:
 
@@ -250,7 +249,7 @@ class AcesInputFile
     // close the file.
     //-----------------------------------------------------------
 
-    AcesInputFile (IStream &is,
+    AcesInputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
 		   int numThreads = globalThreadCount());
 
 
@@ -288,10 +287,10 @@ class AcesInputFile
     //--------------------------
 
     const Header &		header () const;
-    const Imath::Box2i &	displayWindow () const;
-    const Imath::Box2i &	dataWindow () const;
+    const IMATH_NAMESPACE::Box2i &	displayWindow () const;
+    const IMATH_NAMESPACE::Box2i &	dataWindow () const;
     float			pixelAspectRatio () const;
-    const Imath::V2f		screenWindowCenter () const;
+    const IMATH_NAMESPACE::V2f		screenWindowCenter () const;
     float			screenWindowWidth () const;
     LineOrder			lineOrder () const;
     Compression			compression () const;
@@ -317,6 +316,9 @@ class AcesInputFile
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfArray.h b/Source/OpenEXR/IlmImf/ImfArray.h
index 18eb66f..6a80d8f 100644
--- a/Source/OpenEXR/IlmImf/ImfArray.h
+++ b/Source/OpenEXR/IlmImf/ImfArray.h
@@ -37,6 +37,8 @@
 #ifndef INCLUDED_IMF_ARRAY_H
 #define INCLUDED_IMF_ARRAY_H
 
+#include "ImfForward.h"
+
 //-------------------------------------------------------------------------
 //
 // class Array
@@ -69,8 +71,7 @@
 //
 //-------------------------------------------------------------------------
 
-namespace Imf {
-
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 template <class T>
 class Array
@@ -81,8 +82,8 @@ class Array
     // Constructors and destructors
     //-----------------------------
 
-     Array ()				{_data = 0;}
-     Array (long size)			{_data = new T[size];}
+     Array ()				{_data = 0; _size = 0;}
+     Array (long size)			{_data = new T[size]; _size = size;}
     ~Array ()				{delete [] _data;}
 
 
@@ -110,11 +111,19 @@ class Array
     void resizeEraseUnsafe (long size);
 
 
+    //-------------------------------
+    // Return the size of this array.
+    //-------------------------------
+
+    long size() const   {return _size;}
+
+
   private:
 
     Array (const Array &);		// Copying and assignment
     Array & operator = (const Array &);	// are not implemented
 
+    long _size;
     T * _data;
 };
 
@@ -157,11 +166,20 @@ class Array2D
     void resizeEraseUnsafe (long sizeX, long sizeY);
 
 
+    //-------------------------------
+    // Return the size of this array.
+    //-------------------------------
+
+    long height() const  {return _sizeX;}
+    long width() const   {return _sizeY;}
+
+
   private:
 
     Array2D (const Array2D &);			// Copying and assignment
     Array2D & operator = (const Array2D &);	// are not implemented
 
+    long        _sizeX;
     long	_sizeY;
     T *		_data;
 };
@@ -177,6 +195,7 @@ Array<T>::resizeErase (long size)
 {
     T *tmp = new T[size];
     delete [] _data;
+    _size = size;
     _data = tmp;
 }
 
@@ -187,14 +206,16 @@ Array<T>::resizeEraseUnsafe (long size)
 {
     delete [] _data;
     _data = 0;
+    _size = 0;
     _data = new T[size];
+    _size = size;
 }
 
 
 template <class T>
 inline
 Array2D<T>::Array2D ():
-    _sizeY (0), _data (0)
+    _sizeX(0), _sizeY (0), _data (0)
 {
     // emtpy
 }
@@ -203,7 +224,7 @@ Array2D<T>::Array2D ():
 template <class T>
 inline
 Array2D<T>::Array2D (long sizeX, long sizeY):
-    _sizeY (sizeY), _data (new T[sizeX * sizeY])
+    _sizeX (sizeX), _sizeY (sizeY), _data (new T[sizeX * sizeY])
 {
     // emtpy
 }
@@ -239,6 +260,7 @@ Array2D<T>::resizeErase (long sizeX, long sizeY)
 {
     T *tmp = new T[sizeX * sizeY];
     delete [] _data;
+    _sizeX = sizeX;
     _sizeY = sizeY;
     _data = tmp;
 }
@@ -250,12 +272,14 @@ Array2D<T>::resizeEraseUnsafe (long sizeX, long sizeY)
 {
     delete [] _data;
     _data = 0;
+    _sizeX = 0;
     _sizeY = 0;
     _data = new T[sizeX * sizeY];
+    _sizeX = sizeX;
     _sizeY = sizeY;
 }
 
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
-} // namespace Imf
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfAttribute.cpp b/Source/OpenEXR/IlmImf/ImfAttribute.cpp
index feb5f83..cb4ac36 100644
--- a/Source/OpenEXR/IlmImf/ImfAttribute.cpp
+++ b/Source/OpenEXR/IlmImf/ImfAttribute.cpp
@@ -46,11 +46,13 @@
 #include <string.h>
 #include <map>
 
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER 
 
-using IlmThread::Mutex;
-using IlmThread::Lock;
+
+using ILMTHREAD_NAMESPACE::Mutex;
+using ILMTHREAD_NAMESPACE::Lock;
 
 
 Attribute::Attribute () {}
@@ -119,7 +121,7 @@ Attribute::registerAttributeType (const char typeName[],
     Lock lock (tMap.mutex);
 
     if (tMap.find (typeName) != tMap.end())
-	THROW (Iex::ArgExc, "Cannot register image file attribute "
+	THROW (IEX_NAMESPACE::ArgExc, "Cannot register image file attribute "
 			    "type \"" << typeName << "\". "
 			    "The type has already been registered.");
 
@@ -146,11 +148,11 @@ Attribute::newAttribute (const char typeName[])
     TypeMap::const_iterator i = tMap.find (typeName);
 
     if (i == tMap.end())
-	THROW (Iex::ArgExc, "Cannot create image file attribute of "
+	THROW (IEX_NAMESPACE::ArgExc, "Cannot create image file attribute of "
 			    "unknown type \"" << typeName << "\".");
 
     return (i->second)();
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfAttribute.h b/Source/OpenEXR/IlmImf/ImfAttribute.h
index 520c20c..86762ad 100644
--- a/Source/OpenEXR/IlmImf/ImfAttribute.h
+++ b/Source/OpenEXR/IlmImf/ImfAttribute.h
@@ -44,14 +44,16 @@
 //-----------------------------------------------------------------------------
 
 #include "IexBaseExc.h"
-#include <ImfIO.h>
-#include <ImfXdr.h>
+#include "ImfIO.h"
+#include "ImfXdr.h"
+#include "ImfForward.h"
+#include "ImfExport.h"
+#include "ImfNamespace.h"
 
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-namespace Imf {
 
-
-class Attribute
+class IMF_EXPORT Attribute
 {
   public:
 
@@ -81,10 +83,10 @@ class Attribute
     // Type-specific attribute I/O and copying
     //----------------------------------------
 
-    virtual void		writeValueTo (OStream &os,
+    virtual void		writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
 					      int version) const = 0;
 
-    virtual void		readValueFrom (IStream &is,
+    virtual void		readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
 					       int size,
 					       int version) = 0;
 
@@ -128,7 +130,7 @@ class Attribute
 //-------------------------------------------------
 // Class template for attributes of a specific type
 //-------------------------------------------------
-
+    
 template <class T>
 class TypedAttribute: public Attribute
 {
@@ -186,10 +188,10 @@ class TypedAttribute: public Attribute
     // Depending on type T, these functions may have to be specialized.
     //-----------------------------------------------------------------
 
-    virtual void		writeValueTo (OStream &os,
+    virtual void		writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
 					      int version) const;
 
-    virtual void		readValueFrom (IStream &is,
+    virtual void		readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
 					       int size,
 					       int version);
 
@@ -233,11 +235,9 @@ class TypedAttribute: public Attribute
     T					_value;
 };
 
-
 //------------------------------------
 // Implementation of TypedAttribute<T>
 //------------------------------------
-
 template <class T>
 TypedAttribute<T>::TypedAttribute ():
     Attribute (),
@@ -248,7 +248,7 @@ TypedAttribute<T>::TypedAttribute ():
 
 
 template <class T>
-TypedAttribute<T>::TypedAttribute (const T &value):
+TypedAttribute<T>::TypedAttribute (const T & value):
     Attribute (),
     _value (value)
 {
@@ -316,17 +316,20 @@ TypedAttribute<T>::copy () const
 
 template <class T>
 void		
-TypedAttribute<T>::writeValueTo (OStream &os, int version) const
+TypedAttribute<T>::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
+                                    int version) const
 {
-    Xdr::write <StreamIO> (os, _value);
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (os, _value);
 }
 
 
 template <class T>
 void		
-TypedAttribute<T>::readValueFrom (IStream &is, int size, int version)
+TypedAttribute<T>::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
+                                     int size,
+                                     int version)
 {
-    Xdr::read <StreamIO> (is, _value);
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, _value);
 }
 
 
@@ -346,7 +349,7 @@ TypedAttribute<T>::cast (Attribute *attribute)
 	dynamic_cast <TypedAttribute<T> *> (attribute);
 
     if (t == 0)
-	throw Iex::TypeExc ("Unexpected attribute type.");
+	throw IEX_NAMESPACE::TypeExc ("Unexpected attribute type.");
 
     return t;
 }
@@ -360,14 +363,14 @@ TypedAttribute<T>::cast (const Attribute *attribute)
 	dynamic_cast <const TypedAttribute<T> *> (attribute);
 
     if (t == 0)
-	throw Iex::TypeExc ("Unexpected attribute type.");
+	throw IEX_NAMESPACE::TypeExc ("Unexpected attribute type.");
 
     return t;
 }
 
 
 template <class T>
-inline TypedAttribute<T> &	
+inline TypedAttribute<T> &
 TypedAttribute<T>::cast (Attribute &attribute)
 {
     return *cast (&attribute);
@@ -398,30 +401,7 @@ TypedAttribute<T>::unRegisterAttributeType ()
 }
 
 
-} // namespace Imf
-
-#if defined(OPENEXR_DLL) && defined(_MSC_VER)
-    // Tell MS VC++ to disable "non dll-interface class used as base
-    // for dll-interface class" and "no suitable definition provided
-    // for explicit template"
-    #pragma warning (disable : 4275 4661)
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
-    #if defined (ILMIMF_EXPORTS)
- 	#define IMF_EXPIMP_TEMPLATE
-    #else
- 	#define IMF_EXPIMP_TEMPLATE extern
-    #endif
-
-    IMF_EXPIMP_TEMPLATE template class Imf::TypedAttribute<float>;
-    IMF_EXPIMP_TEMPLATE template class Imf::TypedAttribute<double>;
-
-    #pragma warning(default : 4251)
-    #undef EXTERN_TEMPLATE
-#endif
-
-// Metrowerks compiler wants the .cpp file inlined, too
-#ifdef __MWERKS__
-#include <ImfAttribute.cpp>
-#endif
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfAutoArray.h b/Source/OpenEXR/IlmImf/ImfAutoArray.h
index edb8b10..c1ecaff 100644
--- a/Source/OpenEXR/IlmImf/ImfAutoArray.h
+++ b/Source/OpenEXR/IlmImf/ImfAutoArray.h
@@ -44,9 +44,10 @@
 //
 //-----------------------------------------------------------------------------
 
-#include "OpenEXRConfig.h"
+#include "ImfNamespace.h"
+#include <string.h>
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 #if !defined (HAVE_LARGE_STACK)
@@ -88,6 +89,7 @@ namespace Imf {
 
 #endif
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfB44Compressor.cpp b/Source/OpenEXR/IlmImf/ImfB44Compressor.cpp
index 231c18c..f13e143 100644
--- a/Source/OpenEXR/IlmImf/ImfB44Compressor.cpp
+++ b/Source/OpenEXR/IlmImf/ImfB44Compressor.cpp
@@ -97,11 +97,11 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfB44Compressor.h>
-#include <ImfHeader.h>
-#include <ImfChannelList.h>
-#include <ImfMisc.h>
-#include <ImfCheckedArithmetic.h>
+#include "ImfB44Compressor.h"
+#include "ImfHeader.h"
+#include "ImfChannelList.h"
+#include "ImfMisc.h"
+#include "ImfCheckedArithmetic.h"
 #include <ImathFun.h>
 #include <ImathBox.h>
 #include <Iex.h>
@@ -110,13 +110,16 @@
 #include <string.h>
 #include <assert.h>
 #include <algorithm>
+#include "ImfNamespace.h"
 
-namespace Imf {
 
-using Imath::divp;
-using Imath::modp;
-using Imath::Box2i;
-using Imath::V2i;
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+
+using IMATH_NAMESPACE::divp;
+using IMATH_NAMESPACE::modp;
+using IMATH_NAMESPACE::Box2i;
+using IMATH_NAMESPACE::V2i;
 using std::min;
 
 namespace {
@@ -261,79 +264,79 @@ pack (const unsigned short s[16],
 
     do
     {
-	shift += 1;
-
-	//
-	// Compute absolute differences, d[0] ... d[15],
-	// between tMax and t[0] ... t[15].
-	//
-	// Shift and round the absolute differences.
-	//
-
-	for (int i = 0; i < 16; ++i)
-	    d[i] = shiftAndRound (tMax - t[i], shift);
-
-	//
-	// Convert d[0] .. d[15] into running differences
-	//
-
-	r[ 0] = d[ 0] - d[ 4] + bias;
-	r[ 1] = d[ 4] - d[ 8] + bias;
-	r[ 2] = d[ 8] - d[12] + bias;
-
-	r[ 3] = d[ 0] - d[ 1] + bias;
-	r[ 4] = d[ 4] - d[ 5] + bias;
-	r[ 5] = d[ 8] - d[ 9] + bias;
-	r[ 6] = d[12] - d[13] + bias;
-
-	r[ 7] = d[ 1] - d[ 2] + bias;
-	r[ 8] = d[ 5] - d[ 6] + bias;
-	r[ 9] = d[ 9] - d[10] + bias;
-	r[10] = d[13] - d[14] + bias;
-
-	r[11] = d[ 2] - d[ 3] + bias;
-	r[12] = d[ 6] - d[ 7] + bias;
-	r[13] = d[10] - d[11] + bias;
-	r[14] = d[14] - d[15] + bias;
-
-	rMin = r[0];
-	rMax = r[0];
-
-	for (int i = 1; i < 15; ++i)
-	{
-	    if (rMin > r[i])
-		rMin = r[i];
-
-	    if (rMax < r[i])
-		rMax = r[i];
-	}
+        shift += 1;
+
+        //
+        // Compute absolute differences, d[0] ... d[15],
+        // between tMax and t[0] ... t[15].
+        //
+        // Shift and round the absolute differences.
+        //
+
+        for (int i = 0; i < 16; ++i)
+            d[i] = shiftAndRound (tMax - t[i], shift);
+
+        //
+        // Convert d[0] .. d[15] into running differences
+        //
+
+        r[ 0] = d[ 0] - d[ 4] + bias;
+        r[ 1] = d[ 4] - d[ 8] + bias;
+        r[ 2] = d[ 8] - d[12] + bias;
+
+        r[ 3] = d[ 0] - d[ 1] + bias;
+        r[ 4] = d[ 4] - d[ 5] + bias;
+        r[ 5] = d[ 8] - d[ 9] + bias;
+        r[ 6] = d[12] - d[13] + bias;
+
+        r[ 7] = d[ 1] - d[ 2] + bias;
+        r[ 8] = d[ 5] - d[ 6] + bias;
+        r[ 9] = d[ 9] - d[10] + bias;
+        r[10] = d[13] - d[14] + bias;
+
+        r[11] = d[ 2] - d[ 3] + bias;
+        r[12] = d[ 6] - d[ 7] + bias;
+        r[13] = d[10] - d[11] + bias;
+        r[14] = d[14] - d[15] + bias;
+
+        rMin = r[0];
+        rMax = r[0];
+
+        for (int i = 1; i < 15; ++i)
+        {
+            if (rMin > r[i])
+                rMin = r[i];
+
+            if (rMax < r[i])
+                rMax = r[i];
+        }
     }
     while (rMin < 0 || rMax > 0x3f);
 
     if (rMin == bias && rMax == bias && optFlatFields)
     {
-	//
-	// Special case - all pixels have the same value.
-	// We encode this in 3 instead of 14 bytes by
-	// storing the value 0xfc in the third output byte,
-	// which cannot occur in the 14-byte encoding.
-	//
-
-	b[0] = (t[0] >> 8);
-	b[1] =  t[0];
-	b[2] = 0xfc;
-
-	return 3;
+        //
+        // Special case - all pixels have the same value.
+        // We encode this in 3 instead of 14 bytes by
+        // storing the value 0xfc in the third output byte,
+        // which cannot occur in the 14-byte encoding.
+        //
+
+        b[0] = (t[0] >> 8);
+        b[1] = (unsigned char) t[0];
+        b[2] = 0xfc;
+
+        return 3;
     }
 
     if (exactMax)
     {
-	//
-	// Adjust t[0] so that the pixel whose value is equal
-	// to tMax gets represented as accurately as possible.
-	//
+        //
+        // Adjust t[0] so that the pixel whose value is equal
+        // to tMax gets represented as accurately as possible.
+        //
 
-	t[0] = tMax - (d[0] << shift);
+        t[0] = tMax - (d[0] << shift);
     }
 
     //
@@ -341,7 +344,7 @@ pack (const unsigned short s[16],
     //
 
     b[ 0] = (t[0] >> 8);
-    b[ 1] =  t[0];
+    b[ 1] = (unsigned char) t[0];
 
     b[ 2] = (unsigned char) ((shift << 2) | (r[ 0] >> 4));
     b[ 3] = (unsigned char) ((r[ 0] << 4) | (r[ 1] >> 2));
@@ -436,7 +439,7 @@ unpack3 (const unsigned char b[3], unsigned short s[16])
 void
 notEnoughData ()
 {
-    throw Iex::InputExc ("Error decompressing data "
+    throw IEX_NAMESPACE::InputExc ("Error decompressing data "
 			 "(input data are shorter than expected).");
 }
 
@@ -444,7 +447,7 @@ notEnoughData ()
 void
 tooMuchData ()
 {
-    throw Iex::InputExc ("Error decompressing data "
+    throw IEX_NAMESPACE::InputExc ("Error decompressing data "
 			 "(input data are longer than expected).");
 }
 
@@ -587,7 +590,7 @@ B44Compressor::compress (const char *inPtr,
 int
 B44Compressor::compressTile (const char *inPtr,
 			     int inSize,
-			     Imath::Box2i range,
+			     IMATH_NAMESPACE::Box2i range,
 			     const char *&outPtr)
 {
     return compress (inPtr, inSize, range, outPtr);
@@ -611,7 +614,7 @@ B44Compressor::uncompress (const char *inPtr,
 int
 B44Compressor::uncompressTile (const char *inPtr,
 			       int inSize,
-			       Imath::Box2i range,
+			       IMATH_NAMESPACE::Box2i range,
 			       const char *&outPtr)
 {
     return uncompress (inPtr, inSize, range, outPtr);
@@ -621,7 +624,7 @@ B44Compressor::uncompressTile (const char *inPtr,
 int
 B44Compressor::compress (const char *inPtr,
 			 int inSize,
-			 Imath::Box2i range,
+			 IMATH_NAMESPACE::Box2i range,
 			 const char *&outPtr)
 {
     //
@@ -863,7 +866,7 @@ B44Compressor::compress (const char *inPtr,
 int
 B44Compressor::uncompress (const char *inPtr,
 			   int inSize,
-			   Imath::Box2i range,
+			   IMATH_NAMESPACE::Box2i range,
 			   const char *&outPtr)
 {
     //
@@ -1066,4 +1069,4 @@ B44Compressor::uncompress (const char *inPtr,
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfB44Compressor.h b/Source/OpenEXR/IlmImf/ImfB44Compressor.h
index 32b3713..5c381c1 100644
--- a/Source/OpenEXR/IlmImf/ImfB44Compressor.h
+++ b/Source/OpenEXR/IlmImf/ImfB44Compressor.h
@@ -42,14 +42,15 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfCompressor.h>
+#include "ImfCompressor.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+#include "ImfForward.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-class ChannelList;
 
-
-class B44Compressor: public Compressor
+class IMF_EXPORT B44Compressor: public Compressor
 {
   public:
 
@@ -71,7 +72,7 @@ class B44Compressor: public Compressor
                   
     virtual int		compressTile (const char *inPtr,
 				      int inSize,
-				      Imath::Box2i range,
+				      IMATH_NAMESPACE::Box2i range,
 				      const char *&outPtr);
 
     virtual int		uncompress (const char *inPtr,
@@ -81,7 +82,7 @@ class B44Compressor: public Compressor
                     
     virtual int		uncompressTile (const char *inPtr,
 					int inSize,
-					Imath::Box2i range,
+					IMATH_NAMESPACE::Box2i range,
 					const char *&outPtr);
   private:
 
@@ -89,12 +90,12 @@ class B44Compressor: public Compressor
     
     int			compress (const char *inPtr,
 				  int inSize,
-				  Imath::Box2i range,
+				  IMATH_NAMESPACE::Box2i range,
 				  const char *&outPtr);
  
     int			uncompress (const char *inPtr,
 				    int inSize,
-				    Imath::Box2i range,
+				    IMATH_NAMESPACE::Box2i range,
 				    const char *&outPtr);
 
     int			_maxScanLineSize;
@@ -112,6 +113,6 @@ class B44Compressor: public Compressor
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfBoxAttribute.cpp b/Source/OpenEXR/IlmImf/ImfBoxAttribute.cpp
index d275d11..6d44d0c 100644
--- a/Source/OpenEXR/IlmImf/ImfBoxAttribute.cpp
+++ b/Source/OpenEXR/IlmImf/ImfBoxAttribute.cpp
@@ -44,8 +44,9 @@
 #include <ImfBoxAttribute.h>
 
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
+using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;
 
 template <>
 const char *
@@ -57,7 +58,7 @@ Box2iAttribute::staticTypeName ()
 
 template <>
 void
-Box2iAttribute::writeValueTo (OStream &os, int version) const
+Box2iAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     Xdr::write <StreamIO> (os, _value.min.x);
     Xdr::write <StreamIO> (os, _value.min.y);
@@ -68,7 +69,7 @@ Box2iAttribute::writeValueTo (OStream &os, int version) const
 
 template <>
 void
-Box2iAttribute::readValueFrom (IStream &is, int size, int version)
+Box2iAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     Xdr::read <StreamIO> (is, _value.min.x);
     Xdr::read <StreamIO> (is, _value.min.y);
@@ -87,7 +88,7 @@ Box2fAttribute::staticTypeName ()
 
 template <>
 void
-Box2fAttribute::writeValueTo (OStream &os, int version) const
+Box2fAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     Xdr::write <StreamIO> (os, _value.min.x);
     Xdr::write <StreamIO> (os, _value.min.y);
@@ -98,7 +99,7 @@ Box2fAttribute::writeValueTo (OStream &os, int version) const
 
 template <>
 void
-Box2fAttribute::readValueFrom (IStream &is, int size, int version)
+Box2fAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     Xdr::read <StreamIO> (is, _value.min.x);
     Xdr::read <StreamIO> (is, _value.min.y);
@@ -107,4 +108,4 @@ Box2fAttribute::readValueFrom (IStream &is, int size, int version)
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT 
diff --git a/Source/OpenEXR/IlmImf/ImfBoxAttribute.h b/Source/OpenEXR/IlmImf/ImfBoxAttribute.h
index fe35391..7bf2585 100644
--- a/Source/OpenEXR/IlmImf/ImfBoxAttribute.h
+++ b/Source/OpenEXR/IlmImf/ImfBoxAttribute.h
@@ -44,30 +44,44 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfAttribute.h>
+#include "ImfForward.h"
+#include "ImfExport.h"
+#include "ImfAttribute.h"
 #include "ImathBox.h"
+#include "ImfNamespace.h"
 
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-namespace Imf {
 
+typedef TypedAttribute<IMATH_NAMESPACE::Box2i> Box2iAttribute;
 
-typedef TypedAttribute<Imath::Box2i> Box2iAttribute;
-template <> const char *Box2iAttribute::staticTypeName ();
-template <> void Box2iAttribute::writeValueTo (OStream &, int) const;
-template <> void Box2iAttribute::readValueFrom (IStream &, int, int);
+template <>
+IMF_EXPORT
+const char *Box2iAttribute::staticTypeName ();
+template <>
+IMF_EXPORT
+void Box2iAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &,
+                                   int) const;
+template <>
+IMF_EXPORT
+void Box2iAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &,
+                                    int, int);
 
 
-typedef TypedAttribute<Imath::Box2f> Box2fAttribute;
-template <> const char *Box2fAttribute::staticTypeName ();
-template <> void Box2fAttribute::writeValueTo (OStream &, int) const;
-template <> void Box2fAttribute::readValueFrom (IStream &, int, int);
+typedef TypedAttribute<IMATH_NAMESPACE::Box2f> Box2fAttribute;
+template <>
+IMF_EXPORT
+const char *Box2fAttribute::staticTypeName ();
+template <>
+IMF_EXPORT
+void Box2fAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &,
+                                   int) const;
+template <>
+IMF_EXPORT
+void Box2fAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &,
+                                    int, int);
 
 
-} // namespace Imf
-
-// Metrowerks compiler wants the .cpp file inlined, too
-#ifdef __MWERKS__
-#include <ImfBoxAttribute.cpp>
-#endif
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfCRgbaFile.cpp b/Source/OpenEXR/IlmImf/ImfCRgbaFile.cpp
index 1fcf8c6..48363b4 100644
--- a/Source/OpenEXR/IlmImf/ImfCRgbaFile.cpp
+++ b/Source/OpenEXR/IlmImf/ImfCRgbaFile.cpp
@@ -53,16 +53,20 @@
 #include <ImfChannelList.h>
 #include <ImfLut.h>
 #include "half.h"
+#include "ImfNamespace.h"
+#include "ImathForward.h"
+
 #include <string.h>
 
-using Imath::Box2i;
-using Imath::Box2f;
-using Imath::V2i;
-using Imath::V2f;
-using Imath::V3i;
-using Imath::V3f;
-using Imath::M33f;
-using Imath::M44f;
+
+using IMATH_NAMESPACE::Box2i;
+using IMATH_NAMESPACE::Box2f;
+using IMATH_NAMESPACE::V2i;
+using IMATH_NAMESPACE::V2f;
+using IMATH_NAMESPACE::V3i;
+using IMATH_NAMESPACE::V3f;
+using IMATH_NAMESPACE::M33f;
+using IMATH_NAMESPACE::M44f;
 
 
 namespace {
@@ -80,73 +84,73 @@ setErrorMessage (const std::exception &e)
 }
 
 
-inline Imf::Header *
+inline OPENEXR_IMF_INTERNAL_NAMESPACE::Header *
 header (ImfHeader *hdr)
 {
-    return (Imf::Header *)(hdr);
+    return (OPENEXR_IMF_INTERNAL_NAMESPACE::Header *)(hdr);
 }
 
 
-inline const Imf::Header *
+inline const OPENEXR_IMF_INTERNAL_NAMESPACE::Header *
 header (const ImfHeader *hdr)
 {
-    return (const Imf::Header *)(hdr);
+    return (const OPENEXR_IMF_INTERNAL_NAMESPACE::Header *)(hdr);
 }
 
 
-inline Imf::RgbaOutputFile *
+inline OPENEXR_IMF_INTERNAL_NAMESPACE::RgbaOutputFile *
 outfile (ImfOutputFile *out)
 {
-    return (Imf::RgbaOutputFile *) out;
+    return (OPENEXR_IMF_INTERNAL_NAMESPACE::RgbaOutputFile *) out;
 }
 
 
-inline const Imf::RgbaOutputFile *
+inline const OPENEXR_IMF_INTERNAL_NAMESPACE::RgbaOutputFile *
 outfile (const ImfOutputFile *out)
 {
-    return (const Imf::RgbaOutputFile *) out;
+    return (const OPENEXR_IMF_INTERNAL_NAMESPACE::RgbaOutputFile *) out;
 }
 
 
-inline Imf::TiledRgbaOutputFile *
+inline OPENEXR_IMF_INTERNAL_NAMESPACE::TiledRgbaOutputFile *
 outfile (ImfTiledOutputFile *out)
 {
-    return (Imf::TiledRgbaOutputFile *) out;
+    return (OPENEXR_IMF_INTERNAL_NAMESPACE::TiledRgbaOutputFile *) out;
 }
 
 
-inline const Imf::TiledRgbaOutputFile *
+inline const OPENEXR_IMF_INTERNAL_NAMESPACE::TiledRgbaOutputFile *
 outfile (const ImfTiledOutputFile *out)
 {
-    return (const Imf::TiledRgbaOutputFile *) out;
+    return (const OPENEXR_IMF_INTERNAL_NAMESPACE::TiledRgbaOutputFile *) out;
 }
 
 
-inline Imf::RgbaInputFile *
+inline OPENEXR_IMF_INTERNAL_NAMESPACE::RgbaInputFile *
 infile (ImfInputFile *in)
 {
-    return (Imf::RgbaInputFile *) in;
+    return (OPENEXR_IMF_INTERNAL_NAMESPACE::RgbaInputFile *) in;
 }
 
 
-inline const Imf::RgbaInputFile *
+inline const OPENEXR_IMF_INTERNAL_NAMESPACE::RgbaInputFile *
 infile (const ImfInputFile *in)
 {
-    return (const Imf::RgbaInputFile *) in;
+    return (const OPENEXR_IMF_INTERNAL_NAMESPACE::RgbaInputFile *) in;
 }
 
 
-inline Imf::TiledRgbaInputFile *
+inline OPENEXR_IMF_INTERNAL_NAMESPACE::TiledRgbaInputFile *
 infile (ImfTiledInputFile *in)
 {
-    return (Imf::TiledRgbaInputFile *) in;
+    return (OPENEXR_IMF_INTERNAL_NAMESPACE::TiledRgbaInputFile *) in;
 }
 
 
-inline const Imf::TiledRgbaInputFile *
+inline const OPENEXR_IMF_INTERNAL_NAMESPACE::TiledRgbaInputFile *
 infile (const ImfTiledInputFile *in)
 {
-    return (const Imf::TiledRgbaInputFile *) in;
+    return (const OPENEXR_IMF_INTERNAL_NAMESPACE::TiledRgbaInputFile *) in;
 }
 
 
@@ -188,7 +192,7 @@ ImfNewHeader (void)
 {
     try
     {
-	return (ImfHeader *) new Imf::Header;
+	return (ImfHeader *) new OPENEXR_IMF_INTERNAL_NAMESPACE::Header;
     }
     catch (const std::exception &e)
     {
@@ -210,7 +214,7 @@ ImfCopyHeader (const ImfHeader *hdr)
 {
     try
     {
-	return (ImfHeader *) new Imf::Header (*header (hdr));
+	return (ImfHeader *) new OPENEXR_IMF_INTERNAL_NAMESPACE::Header (*header (hdr));
     }
     catch (const std::exception &e)
     {
@@ -289,8 +293,8 @@ void
 ImfHeaderScreenWindowCenter (const ImfHeader *hdr, float *x, float *y)
 {
     const V2i &swc = header(hdr)->screenWindowCenter();
-    *x = swc.x;
-    *y = swc.y;
+    *x = (float) swc.x;
+    *y = (float) swc.y;
 }
 
 
@@ -311,7 +315,7 @@ ImfHeaderScreenWindowWidth (const ImfHeader *hdr)
 void	
 ImfHeaderSetLineOrder (ImfHeader *hdr, int lineOrder)
 {
-    header(hdr)->lineOrder() = Imf::LineOrder (lineOrder);
+    header(hdr)->lineOrder() = OPENEXR_IMF_INTERNAL_NAMESPACE::LineOrder (lineOrder);
 }
 
 
@@ -325,7 +329,7 @@ ImfHeaderLineOrder (const ImfHeader *hdr)
 void	
 ImfHeaderSetCompression (ImfHeader *hdr, int compression)
 {
-    header(hdr)->compression() = Imf::Compression (compression);
+    header(hdr)->compression() = OPENEXR_IMF_INTERNAL_NAMESPACE::Compression (compression);
 }
 
 
@@ -343,11 +347,11 @@ ImfHeaderSetIntAttribute (ImfHeader *hdr, const char name[], int value)
     {
 	if (header(hdr)->find(name) == header(hdr)->end())
 	{
-	    header(hdr)->insert (name, Imf::IntAttribute (value));
+	    header(hdr)->insert (name, OPENEXR_IMF_INTERNAL_NAMESPACE::IntAttribute (value));
 	}
 	else
 	{
-	    header(hdr)->typedAttribute<Imf::IntAttribute>(name).value() =
+	    header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::IntAttribute>(name).value() =
 		value;
 	}
 
@@ -366,7 +370,7 @@ ImfHeaderIntAttribute (const ImfHeader *hdr, const char name[], int *value)
 {
     try
     {
-	*value = header(hdr)->typedAttribute<Imf::IntAttribute>(name).value();
+	*value = header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::IntAttribute>(name).value();
 	return 1;
     }
     catch (const std::exception &e)
@@ -384,11 +388,11 @@ ImfHeaderSetFloatAttribute (ImfHeader *hdr, const char name[], float value)
     {
 	if (header(hdr)->find(name) == header(hdr)->end())
 	{
-	    header(hdr)->insert (name, Imf::FloatAttribute (value));
+	    header(hdr)->insert (name, OPENEXR_IMF_INTERNAL_NAMESPACE::FloatAttribute (value));
 	}
 	else
 	{
-	    header(hdr)->typedAttribute<Imf::FloatAttribute>(name).value() =
+	    header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::FloatAttribute>(name).value() =
 		value;
 	}
 
@@ -409,11 +413,11 @@ ImfHeaderSetDoubleAttribute (ImfHeader *hdr, const char name[], double value)
     {
 	if (header(hdr)->find(name) == header(hdr)->end())
 	{
-	    header(hdr)->insert (name, Imf::DoubleAttribute (value));
+	    header(hdr)->insert (name, OPENEXR_IMF_INTERNAL_NAMESPACE::DoubleAttribute (value));
 	}
 	else
 	{
-	    header(hdr)->typedAttribute<Imf::DoubleAttribute>(name).value() =
+	    header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::DoubleAttribute>(name).value() =
 		value;
 	}
 
@@ -432,7 +436,7 @@ ImfHeaderFloatAttribute (const ImfHeader *hdr, const char name[], float *value)
 {
     try
     {
-	*value = header(hdr)->typedAttribute<Imf::FloatAttribute>(name).value();
+	*value = header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::FloatAttribute>(name).value();
 	return 1;
     }
     catch (const std::exception &e)
@@ -451,7 +455,7 @@ ImfHeaderDoubleAttribute (const ImfHeader *hdr,
     try
     {
 	*value = header(hdr)->
-	    typedAttribute<Imf::DoubleAttribute>(name).value();
+	    typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::DoubleAttribute>(name).value();
 
 	return 1;
     }
@@ -472,11 +476,11 @@ ImfHeaderSetStringAttribute (ImfHeader *hdr,
     {
 	if (header(hdr)->find(name) == header(hdr)->end())
 	{
-	    header(hdr)->insert (name, Imf::StringAttribute (value));
+	    header(hdr)->insert (name, OPENEXR_IMF_INTERNAL_NAMESPACE::StringAttribute (value));
 	}
 	else
 	{
-	    header(hdr)->typedAttribute<Imf::StringAttribute>(name).value() =
+	    header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::StringAttribute>(name).value() =
 		value;
 	}
 
@@ -498,7 +502,7 @@ ImfHeaderStringAttribute (const ImfHeader *hdr,
     try
     {
 	*value = header(hdr)->
-	    typedAttribute<Imf::StringAttribute>(name).value().c_str();
+	    typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::StringAttribute>(name).value().c_str();
 
 	return 1;
     }
@@ -522,11 +526,11 @@ ImfHeaderSetBox2iAttribute (ImfHeader *hdr,
 
 	if (header(hdr)->find(name) == header(hdr)->end())
 	{
-	    header(hdr)->insert (name, Imf::Box2iAttribute (box));
+	    header(hdr)->insert (name, OPENEXR_IMF_INTERNAL_NAMESPACE::Box2iAttribute (box));
 	}
 	else
 	{
-	    header(hdr)->typedAttribute<Imf::Box2iAttribute>(name).value() =
+	    header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::Box2iAttribute>(name).value() =
 		box;
 	}
 
@@ -549,7 +553,7 @@ ImfHeaderBox2iAttribute (const ImfHeader *hdr,
     try
     {
 	const Box2i &box =
-	    header(hdr)->typedAttribute<Imf::Box2iAttribute>(name).value();
+	    header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::Box2iAttribute>(name).value();
 
 	*xMin = box.min.x;
 	*yMin = box.min.y;
@@ -578,11 +582,11 @@ ImfHeaderSetBox2fAttribute (ImfHeader *hdr,
 
 	if (header(hdr)->find(name) == header(hdr)->end())
 	{
-	    header(hdr)->insert (name, Imf::Box2fAttribute (box));
+	    header(hdr)->insert (name, OPENEXR_IMF_INTERNAL_NAMESPACE::Box2fAttribute (box));
 	}
 	else
 	{
-	    header(hdr)->typedAttribute<Imf::Box2fAttribute>(name).value() =
+	    header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::Box2fAttribute>(name).value() =
 		box;
 	}
 
@@ -605,7 +609,7 @@ ImfHeaderBox2fAttribute (const ImfHeader *hdr,
     try
     {
 	const Box2f &box =
-	    header(hdr)->typedAttribute<Imf::Box2fAttribute>(name).value();
+	    header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::Box2fAttribute>(name).value();
 
 	*xMin = box.min.x;
 	*yMin = box.min.y;
@@ -632,9 +636,9 @@ ImfHeaderSetV2iAttribute (ImfHeader *hdr,
 	V2i v (x, y);
 
 	if (header(hdr)->find(name) == header(hdr)->end())
-	    header(hdr)->insert (name, Imf::V2iAttribute (v));
+	    header(hdr)->insert (name, OPENEXR_IMF_INTERNAL_NAMESPACE::V2iAttribute (v));
 	else
-	    header(hdr)->typedAttribute<Imf::V2iAttribute>(name).value() = v;
+	    header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::V2iAttribute>(name).value() = v;
 
 	return 1;
     }
@@ -654,7 +658,7 @@ ImfHeaderV2iAttribute (const ImfHeader *hdr,
     try
     {
 	const V2i &v =
-	    header(hdr)->typedAttribute<Imf::V2iAttribute>(name).value();
+	    header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::V2iAttribute>(name).value();
 
 	*x = v.x;
 	*y = v.y;
@@ -679,9 +683,9 @@ ImfHeaderSetV2fAttribute (ImfHeader *hdr,
 	V2f v (x, y);
 
 	if (header(hdr)->find(name) == header(hdr)->end())
-	    header(hdr)->insert (name, Imf::V2fAttribute (v));
+	    header(hdr)->insert (name, OPENEXR_IMF_INTERNAL_NAMESPACE::V2fAttribute (v));
 	else
-	    header(hdr)->typedAttribute<Imf::V2fAttribute>(name).value() = v;
+	    header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::V2fAttribute>(name).value() = v;
 
 	return 1;
     }
@@ -701,7 +705,7 @@ ImfHeaderV2fAttribute (const ImfHeader *hdr,
     try
     {
 	const V2f &v =
-	    header(hdr)->typedAttribute<Imf::V2fAttribute>(name).value();
+	    header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::V2fAttribute>(name).value();
 
 	*x = v.x;
 	*y = v.y;
@@ -726,9 +730,9 @@ ImfHeaderSetV3iAttribute (ImfHeader *hdr,
 	V3i v (x, y, z);
 
 	if (header(hdr)->find(name) == header(hdr)->end())
-	    header(hdr)->insert (name, Imf::V3iAttribute (v));
+	    header(hdr)->insert (name, OPENEXR_IMF_INTERNAL_NAMESPACE::V3iAttribute (v));
 	else
-	    header(hdr)->typedAttribute<Imf::V3iAttribute>(name).value() = v;
+	    header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::V3iAttribute>(name).value() = v;
 
 	return 1;
     }
@@ -748,7 +752,7 @@ ImfHeaderV3iAttribute (const ImfHeader *hdr,
     try
     {
 	const V3i &v =
-	    header(hdr)->typedAttribute<Imf::V3iAttribute>(name).value();
+	    header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::V3iAttribute>(name).value();
 
 	*x = v.x;
 	*y = v.y;
@@ -774,9 +778,9 @@ ImfHeaderSetV3fAttribute (ImfHeader *hdr,
 	V3f v (x, y, z);
 
 	if (header(hdr)->find(name) == header(hdr)->end())
-	    header(hdr)->insert (name, Imf::V3fAttribute (v));
+	    header(hdr)->insert (name, OPENEXR_IMF_INTERNAL_NAMESPACE::V3fAttribute (v));
 	else
-	    header(hdr)->typedAttribute<Imf::V3fAttribute>(name).value() = v;
+	    header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::V3fAttribute>(name).value() = v;
 
 	return 1;
     }
@@ -796,7 +800,7 @@ ImfHeaderV3fAttribute (const ImfHeader *hdr,
     try
     {
 	const V3f &v =
-	    header(hdr)->typedAttribute<Imf::V3fAttribute>(name).value();
+	    header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::V3fAttribute>(name).value();
 
 	*x = v.x;
 	*y = v.y;
@@ -822,9 +826,9 @@ ImfHeaderSetM33fAttribute (ImfHeader *hdr,
 	M33f m3 (m);
 
 	if (header(hdr)->find(name) == header(hdr)->end())
-	    header(hdr)->insert (name, Imf::M33fAttribute (m3));
+	    header(hdr)->insert (name, OPENEXR_IMF_INTERNAL_NAMESPACE::M33fAttribute (m3));
 	else
-	    header(hdr)->typedAttribute<Imf::M33fAttribute>(name).value() = m3;
+	    header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::M33fAttribute>(name).value() = m3;
 
 	return 1;
     }
@@ -844,7 +848,7 @@ ImfHeaderM33fAttribute (const ImfHeader *hdr,
     try
     {
 	const M33f &m3 =
-	    header(hdr)->typedAttribute<Imf::M33fAttribute>(name).value();
+	    header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::M33fAttribute>(name).value();
 
 	m[0][0] = m3[0][0];
 	m[0][1] = m3[0][1];
@@ -878,9 +882,9 @@ ImfHeaderSetM44fAttribute (ImfHeader *hdr,
 	M44f m4 (m);
 
 	if (header(hdr)->find(name) == header(hdr)->end())
-	    header(hdr)->insert (name, Imf::M44fAttribute (m4));
+	    header(hdr)->insert (name, OPENEXR_IMF_INTERNAL_NAMESPACE::M44fAttribute (m4));
 	else
-	    header(hdr)->typedAttribute<Imf::M44fAttribute>(name).value() = m4;
+	    header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::M44fAttribute>(name).value() = m4;
 
 	return 1;
     }
@@ -900,7 +904,7 @@ ImfHeaderM44fAttribute (const ImfHeader *hdr,
     try
     {
 	const M44f &m4 =
-	    header(hdr)->typedAttribute<Imf::M44fAttribute>(name).value();
+	    header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::M44fAttribute>(name).value();
 
 	m[0][0] = m4[0][0];
 	m[0][1] = m4[0][1];
@@ -937,8 +941,8 @@ ImfOpenOutputFile (const char name[], const ImfHeader *hdr, int channels)
 {
     try
     {
-	return (ImfOutputFile *) new Imf::RgbaOutputFile
-	    (name, *header(hdr), Imf::RgbaChannels (channels));
+	return (ImfOutputFile *) new OPENEXR_IMF_INTERNAL_NAMESPACE::RgbaOutputFile
+	    (name, *header(hdr), OPENEXR_IMF_INTERNAL_NAMESPACE::RgbaChannels (channels));
     }
     catch (const std::exception &e)
     {
@@ -972,7 +976,7 @@ ImfOutputSetFrameBuffer (ImfOutputFile *out,
 {
     try
     {
-	outfile(out)->setFrameBuffer ((Imf::Rgba *)base, xStride, yStride);
+	outfile(out)->setFrameBuffer ((OPENEXR_IMF_INTERNAL_NAMESPACE::Rgba *)base, xStride, yStride);
 	return 1;
     }
     catch (const std::exception &e)
@@ -1029,12 +1033,12 @@ ImfOpenTiledOutputFile (const char name[],
 {
     try
     {
-	return (ImfTiledOutputFile *) new Imf::TiledRgbaOutputFile
+	return (ImfTiledOutputFile *) new OPENEXR_IMF_INTERNAL_NAMESPACE::TiledRgbaOutputFile
 		    (name, *header(hdr),
-		     Imf::RgbaChannels (channels),
+		     OPENEXR_IMF_INTERNAL_NAMESPACE::RgbaChannels (channels),
 		     xSize, ySize,
-		     Imf::LevelMode (mode),
-		     Imf::LevelRoundingMode (rmode));
+		     OPENEXR_IMF_INTERNAL_NAMESPACE::LevelMode (mode),
+		     OPENEXR_IMF_INTERNAL_NAMESPACE::LevelRoundingMode (rmode));
     }
     catch (const std::exception &e)
     {
@@ -1068,7 +1072,7 @@ ImfTiledOutputSetFrameBuffer (ImfTiledOutputFile *out,
 {
     try
     {
-	outfile(out)->setFrameBuffer ((Imf::Rgba *)base, xStride, yStride);
+	outfile(out)->setFrameBuffer ((OPENEXR_IMF_INTERNAL_NAMESPACE::Rgba *)base, xStride, yStride);
 	return 1;
     }
     catch (const std::exception &e)
@@ -1163,7 +1167,7 @@ ImfOpenInputFile (const char name[])
 {
     try
     {
-	return (ImfInputFile *) new Imf::RgbaInputFile (name);
+	return (ImfInputFile *) new OPENEXR_IMF_INTERNAL_NAMESPACE::RgbaInputFile (name);
     }
     catch (const std::exception &e)
     {
@@ -1197,7 +1201,7 @@ ImfInputSetFrameBuffer (ImfInputFile *in,
 {
     try
     {
-	infile(in)->setFrameBuffer ((Imf::Rgba *) base, xStride, yStride);
+	infile(in)->setFrameBuffer ((OPENEXR_IMF_INTERNAL_NAMESPACE::Rgba *) base, xStride, yStride);
 	return 1;
     }
     catch (const std::exception &e)
@@ -1250,7 +1254,7 @@ ImfOpenTiledInputFile (const char name[])
 {
     try
     {
-	return (ImfTiledInputFile *) new Imf::TiledRgbaInputFile (name);
+	return (ImfTiledInputFile *) new OPENEXR_IMF_INTERNAL_NAMESPACE::TiledRgbaInputFile (name);
     }
     catch (const std::exception &e)
     {
@@ -1284,7 +1288,7 @@ ImfTiledInputSetFrameBuffer (ImfTiledInputFile *in,
 {
     try
     {
-	infile(in)->setFrameBuffer ((Imf::Rgba *) base, xStride, yStride);
+	infile(in)->setFrameBuffer ((OPENEXR_IMF_INTERNAL_NAMESPACE::Rgba *) base, xStride, yStride);
 	return 1;
     }
     catch (const std::exception &e)
@@ -1386,8 +1390,8 @@ ImfNewRound12logLut (int channels)
 {
     try
     {
-	return (ImfLut *) new Imf::RgbaLut
-	    (Imf::round12log, Imf::RgbaChannels (channels));
+	return (ImfLut *) new OPENEXR_IMF_INTERNAL_NAMESPACE::RgbaLut
+	    (OPENEXR_IMF_INTERNAL_NAMESPACE::round12log, OPENEXR_IMF_INTERNAL_NAMESPACE::RgbaChannels (channels));
     }
     catch (const std::exception &e)
     {
@@ -1402,8 +1406,8 @@ ImfNewRoundNBitLut (unsigned int n, int channels)
 {
     try
     {
-	return (ImfLut *) new Imf::RgbaLut
-	    (Imf::roundNBit (n), Imf::RgbaChannels (channels));
+	return (ImfLut *) new OPENEXR_IMF_INTERNAL_NAMESPACE::RgbaLut
+	    (OPENEXR_IMF_INTERNAL_NAMESPACE::roundNBit (n), OPENEXR_IMF_INTERNAL_NAMESPACE::RgbaChannels (channels));
     }
     catch (const std::exception &e)
     {
@@ -1416,14 +1420,14 @@ ImfNewRoundNBitLut (unsigned int n, int channels)
 void
 ImfDeleteLut (ImfLut *lut)
 {
-    delete (Imf::RgbaLut *) lut;
+    delete (OPENEXR_IMF_INTERNAL_NAMESPACE::RgbaLut *) lut;
 }
 
 
 void
 ImfApplyLut (ImfLut *lut, ImfRgba *data, int nData, int stride)
 {
-    ((Imf::RgbaLut *)lut)->apply ((Imf::Rgba *)data, nData, stride);
+    ((OPENEXR_IMF_INTERNAL_NAMESPACE::RgbaLut *)lut)->apply ((OPENEXR_IMF_INTERNAL_NAMESPACE::Rgba *)data, nData, stride);
 }
 
 
diff --git a/Source/OpenEXR/IlmImf/ImfCRgbaFile.h b/Source/OpenEXR/IlmImf/ImfCRgbaFile.h
index e3dc1ce..5ac2bf8 100644
--- a/Source/OpenEXR/IlmImf/ImfCRgbaFile.h
+++ b/Source/OpenEXR/IlmImf/ImfCRgbaFile.h
@@ -35,6 +35,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef INCLUDED_IMF_C_RGBA_FILE_H
 #define INCLUDED_IMF_C_RGBA_FILE_H
 
+#include "ImfExport.h"
 
 #include <stdlib.h>
 
@@ -48,15 +49,19 @@ extern "C" {
 
 typedef unsigned short ImfHalf;
 
+IMF_EXPORT 
 void	ImfFloatToHalf (float f,
 			ImfHalf *h);
 
+IMF_EXPORT 
 void	ImfFloatToHalfArray (int n,
 			    const float f[/*n*/],
 			    ImfHalf h[/*n*/]);
 
+IMF_EXPORT 
 float	ImfHalfToFloat (ImfHalf h);
 
+IMF_EXPORT 
 void	ImfHalfToFloatArray (int n,
 			    const ImfHalf h[/*n*/],
 			    float f[/*n*/]);
@@ -151,150 +156,191 @@ typedef struct ImfRgba ImfRgba;
 struct ImfHeader;
 typedef struct ImfHeader ImfHeader;
 
+IMF_EXPORT 
 ImfHeader *	ImfNewHeader (void);
 
+IMF_EXPORT 
 void		ImfDeleteHeader (ImfHeader *hdr);
 
+IMF_EXPORT 
 ImfHeader *	ImfCopyHeader (const ImfHeader *hdr);
 
+IMF_EXPORT 
 void		ImfHeaderSetDisplayWindow (ImfHeader *hdr,
 					   int xMin, int yMin,
 					   int xMax, int yMax);
 
+IMF_EXPORT 
 void		ImfHeaderDisplayWindow (const ImfHeader *hdr,
 					int *xMin, int *yMin,
 					int *xMax, int *yMax);
 
+IMF_EXPORT 
 void		ImfHeaderSetDataWindow (ImfHeader *hdr,
 					int xMin, int yMin,
 					int xMax, int yMax);
 
+IMF_EXPORT 
 void		ImfHeaderDataWindow (const ImfHeader *hdr,
 				     int *xMin, int *yMin,
 				     int *xMax, int *yMax);
 
+IMF_EXPORT 
 void		ImfHeaderSetPixelAspectRatio (ImfHeader *hdr,
 					      float pixelAspectRatio);
 
+IMF_EXPORT 
 float		ImfHeaderPixelAspectRatio (const ImfHeader *hdr);
 
+IMF_EXPORT 
 void		ImfHeaderSetScreenWindowCenter (ImfHeader *hdr,
 						float x, float y);
 
+IMF_EXPORT 
 void		ImfHeaderScreenWindowCenter (const ImfHeader *hdr,
 					     float *x, float *y);
 
+IMF_EXPORT 
 void		ImfHeaderSetScreenWindowWidth (ImfHeader *hdr,
 					       float width);
 
+IMF_EXPORT 
 float		ImfHeaderScreenWindowWidth (const ImfHeader *hdr);
 
+IMF_EXPORT 
 void		ImfHeaderSetLineOrder (ImfHeader *hdr,
 				       int lineOrder);
 
+IMF_EXPORT 
 int		ImfHeaderLineOrder (const ImfHeader *hdr);
 			    
+IMF_EXPORT 
 void		ImfHeaderSetCompression (ImfHeader *hdr,
 					 int compression);
 
+IMF_EXPORT 
 int		ImfHeaderCompression (const ImfHeader *hdr);
 
+IMF_EXPORT 
 int		ImfHeaderSetIntAttribute (ImfHeader *hdr,
 					  const char name[],
 					  int value);
 
+IMF_EXPORT 
 int		ImfHeaderIntAttribute (const ImfHeader *hdr,
 				       const char name[],
 				       int *value);
 
+IMF_EXPORT 
 int		ImfHeaderSetFloatAttribute (ImfHeader *hdr,
 					    const char name[],
 					    float value);
 
+IMF_EXPORT 
 int		ImfHeaderSetDoubleAttribute (ImfHeader *hdr,
 					     const char name[],
 					     double value);
 
+IMF_EXPORT 
 int		ImfHeaderFloatAttribute (const ImfHeader *hdr,
 				         const char name[],
 				         float *value);
 
+IMF_EXPORT 
 int		ImfHeaderDoubleAttribute (const ImfHeader *hdr,
 				          const char name[],
 				          double *value);
 
+IMF_EXPORT 
 int		ImfHeaderSetStringAttribute (ImfHeader *hdr,
 					     const char name[],
 					     const char value[]);
 
+IMF_EXPORT 
 int		ImfHeaderStringAttribute (const ImfHeader *hdr,
 				         const char name[],
 					  const char **value);
 
+IMF_EXPORT 
 int		ImfHeaderSetBox2iAttribute (ImfHeader *hdr,
 					    const char name[],
 					    int xMin, int yMin,
 					    int xMax, int yMax);
 
+IMF_EXPORT 
 int		ImfHeaderBox2iAttribute (const ImfHeader *hdr,
 					 const char name[],
 					 int *xMin, int *yMin,
 					 int *xMax, int *yMax);
 
+IMF_EXPORT 
 int		ImfHeaderSetBox2fAttribute (ImfHeader *hdr,
 					    const char name[],
 					    float xMin, float yMin,
 					    float xMax, float yMax);
 
+IMF_EXPORT 
 int		ImfHeaderBox2fAttribute (const ImfHeader *hdr,
 					 const char name[],
 					 float *xMin, float *yMin,
 					 float *xMax, float *yMax);
 
+IMF_EXPORT 
 int		ImfHeaderSetV2iAttribute (ImfHeader *hdr,
 				         const char name[],
 				         int x, int y);
 
+IMF_EXPORT 
 int		ImfHeaderV2iAttribute (const ImfHeader *hdr,
 				       const char name[],
 				       int *x, int *y);
 
+IMF_EXPORT 
 int		ImfHeaderSetV2fAttribute (ImfHeader *hdr,
 				          const char name[],
 				          float x, float y);
 
+IMF_EXPORT 
 int		ImfHeaderV2fAttribute (const ImfHeader *hdr,
 				       const char name[],
 				       float *x, float *y);
 
+IMF_EXPORT 
 int		ImfHeaderSetV3iAttribute (ImfHeader *hdr,
 				          const char name[],
 				          int x, int y, int z);
 
+IMF_EXPORT 
 int		ImfHeaderV3iAttribute (const ImfHeader *hdr,
 				       const char name[],
 				       int *x, int *y, int *z);
 
+IMF_EXPORT 
 int		ImfHeaderSetV3fAttribute (ImfHeader *hdr,
 				          const char name[],
 				          float x, float y, float z);
 
+IMF_EXPORT 
 int		ImfHeaderV3fAttribute (const ImfHeader *hdr,
 				       const char name[],
 				       float *x, float *y, float *z);
 
+IMF_EXPORT 
 int		ImfHeaderSetM33fAttribute (ImfHeader *hdr,
 					   const char name[],
 					   const float m[3][3]);
 
+IMF_EXPORT 
 int		ImfHeaderM33fAttribute (const ImfHeader *hdr,
 					const char name[],
 					float m[3][3]);
 
+IMF_EXPORT 
 int		ImfHeaderSetM44fAttribute (ImfHeader *hdr,
 					   const char name[],
 					   const float m[4][4]);
 
+IMF_EXPORT 
 int		ImfHeaderM44fAttribute (const ImfHeader *hdr,
 					const char name[],
 					float m[4][4]);
@@ -306,24 +352,31 @@ int		ImfHeaderM44fAttribute (const ImfHeader *hdr,
 struct ImfOutputFile;
 typedef struct ImfOutputFile ImfOutputFile;
 
+IMF_EXPORT 
 ImfOutputFile *	ImfOpenOutputFile (const char name[],
 				   const ImfHeader *hdr,
 				   int channels);
 
+IMF_EXPORT 
 int			ImfCloseOutputFile (ImfOutputFile *out);
 
+IMF_EXPORT 
 int			ImfOutputSetFrameBuffer (ImfOutputFile *out,
 						 const ImfRgba *base,
 						 size_t xStride,
 						 size_t yStride);
 
+IMF_EXPORT 
 int			ImfOutputWritePixels (ImfOutputFile *out,
 					      int numScanLines);
 
+IMF_EXPORT 
 int			ImfOutputCurrentScanLine (const ImfOutputFile *out);
 
+IMF_EXPORT 
 const ImfHeader *	ImfOutputHeader (const ImfOutputFile *out);
 
+IMF_EXPORT 
 int			ImfOutputChannels (const ImfOutputFile *out);
 
 
@@ -334,37 +387,49 @@ int			ImfOutputChannels (const ImfOutputFile *out);
 struct ImfTiledOutputFile;
 typedef struct ImfTiledOutputFile ImfTiledOutputFile;
 
+IMF_EXPORT 
 ImfTiledOutputFile *	ImfOpenTiledOutputFile (const char name[],
 					        const ImfHeader *hdr,
 						int channels,
 						int xSize, int ySize,
 						int mode, int rmode);
 
+IMF_EXPORT 
 int		ImfCloseTiledOutputFile (ImfTiledOutputFile *out);
 
+IMF_EXPORT 
 int		ImfTiledOutputSetFrameBuffer (ImfTiledOutputFile *out,
 					      const ImfRgba *base,
 					      size_t xStride,
 					      size_t yStride);
 
+IMF_EXPORT 
 int		ImfTiledOutputWriteTile (ImfTiledOutputFile *out,
 					 int dx, int dy,
 					 int lx, int ly);
 
+IMF_EXPORT 
 int             ImfTiledOutputWriteTiles (ImfTiledOutputFile *out,
                                           int dxMin, int dxMax,
                                           int dyMin, int dyMax,
                                           int lx, int ly);
 
+IMF_EXPORT 
 const ImfHeader *	ImfTiledOutputHeader (const ImfTiledOutputFile *out);
 
+IMF_EXPORT 
 int		ImfTiledOutputChannels (const ImfTiledOutputFile *out);
 
+IMF_EXPORT 
 int		ImfTiledOutputTileXSize (const ImfTiledOutputFile *out);
 
+IMF_EXPORT 
 int		ImfTiledOutputTileYSize (const ImfTiledOutputFile *out);
 
+IMF_EXPORT 
 int		ImfTiledOutputLevelMode (const ImfTiledOutputFile *out);
+
+IMF_EXPORT 
 int	       	ImfTiledOutputLevelRoundingMode
 						(const ImfTiledOutputFile *out);
 
@@ -378,21 +443,27 @@ typedef struct ImfInputFile ImfInputFile;
 
 ImfInputFile *		ImfOpenInputFile (const char name[]);
 
+IMF_EXPORT 
 int			ImfCloseInputFile (ImfInputFile *in);
 
+IMF_EXPORT 
 int			ImfInputSetFrameBuffer (ImfInputFile *in,
 						ImfRgba *base,
 						size_t xStride,
 						size_t yStride);
 
+IMF_EXPORT 
 int			ImfInputReadPixels (ImfInputFile *in,
 					    int scanLine1,
 					    int scanLine2);
 
+IMF_EXPORT 
 const ImfHeader *	ImfInputHeader (const ImfInputFile *in);
 
+IMF_EXPORT 
 int			ImfInputChannels (const ImfInputFile *in);
 
+IMF_EXPORT 
 const char *            ImfInputFileName (const ImfInputFile *in);
 
 
@@ -403,36 +474,48 @@ const char *            ImfInputFileName (const ImfInputFile *in);
 struct ImfTiledInputFile;
 typedef struct ImfTiledInputFile ImfTiledInputFile;
 
+IMF_EXPORT 
 ImfTiledInputFile *	ImfOpenTiledInputFile (const char name[]);
 
+IMF_EXPORT 
 int		ImfCloseTiledInputFile (ImfTiledInputFile *in);
 
+IMF_EXPORT 
 int		ImfTiledInputSetFrameBuffer (ImfTiledInputFile *in,
 					     ImfRgba *base,
 					     size_t xStride,
 					     size_t yStride);
 
+IMF_EXPORT 
 int		ImfTiledInputReadTile (ImfTiledInputFile *in,
 				       int dx, int dy,
 				       int lx, int ly);
 
+IMF_EXPORT 
 int		ImfTiledInputReadTiles (ImfTiledInputFile *in,
                                         int dxMin, int dxMax,
                                         int dyMin, int dyMax,
                                         int lx, int ly);
 
+IMF_EXPORT 
 const ImfHeader *	ImfTiledInputHeader (const ImfTiledInputFile *in);
 
+IMF_EXPORT 
 int		ImfTiledInputChannels (const ImfTiledInputFile *in);
 
+IMF_EXPORT 
 const char *		ImfTiledInputFileName (const ImfTiledInputFile *in);
 
+IMF_EXPORT 
 int		ImfTiledInputTileXSize (const ImfTiledInputFile *in);
 
+IMF_EXPORT 
 int		ImfTiledInputTileYSize (const ImfTiledInputFile *in);
 
+IMF_EXPORT 
 int		ImfTiledInputLevelMode (const ImfTiledInputFile *in);
 
+IMF_EXPORT 
 int	       	ImfTiledInputLevelRoundingMode
 					       (const ImfTiledInputFile *in);
 
@@ -443,12 +526,16 @@ int	       	ImfTiledInputLevelRoundingMode
 struct ImfLut;
 typedef struct ImfLut ImfLut;
 
+IMF_EXPORT 
 ImfLut *		ImfNewRound12logLut (int channels);
 
+IMF_EXPORT 
 ImfLut *		ImfNewRoundNBitLut (unsigned int n, int channels);
 
+IMF_EXPORT 
 void			ImfDeleteLut (ImfLut *lut);
 
+IMF_EXPORT 
 void			ImfApplyLut (ImfLut *lut,
 				     ImfRgba *data,
 				     int nData,
@@ -457,6 +544,7 @@ void			ImfApplyLut (ImfLut *lut,
 ** Most recent error message
 */
 
+IMF_EXPORT 
 const char *		ImfErrorMessage (void);
 
 
diff --git a/Source/OpenEXR/IlmImf/ImfChannelList.cpp b/Source/OpenEXR/IlmImf/ImfChannelList.cpp
index 9b1f904..ae2ccaa 100644
--- a/Source/OpenEXR/IlmImf/ImfChannelList.cpp
+++ b/Source/OpenEXR/IlmImf/ImfChannelList.cpp
@@ -47,8 +47,9 @@
 
 using std::string;
 using std::set;
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 Channel::Channel (PixelType t, int xs, int ys, bool pl):
@@ -75,7 +76,7 @@ void
 ChannelList::insert (const char name[], const Channel &channel)
 {
     if (name[0] == 0)
-	THROW (Iex::ArgExc, "Image channel name cannot be an empty string.");
+	THROW (IEX_NAMESPACE::ArgExc, "Image channel name cannot be an empty string.");
 
     _map[name] = channel;
 }
@@ -94,7 +95,7 @@ ChannelList::operator [] (const char name[])
     ChannelMap::iterator i = _map.find (name);
 
     if (i == _map.end())
-	THROW (Iex::ArgExc, "Cannot find image channel \"" << name << "\".");
+	THROW (IEX_NAMESPACE::ArgExc, "Cannot find image channel \"" << name << "\".");
 
     return i->second;
 }
@@ -106,7 +107,7 @@ ChannelList::operator [] (const char name[]) const
     ChannelMap::const_iterator i = _map.find (name);
 
     if (i == _map.end())
-	THROW (Iex::ArgExc, "Cannot find image channel \"" << name << "\".");
+	THROW (IEX_NAMESPACE::ArgExc, "Cannot find image channel \"" << name << "\".");
 
     return i->second;
 }
@@ -255,7 +256,7 @@ ChannelList::channelsWithPrefix (const char prefix[],
 				 Iterator &last)
 {
     first = last = _map.lower_bound (prefix);
-    int n = strlen (prefix);
+    size_t n = int(strlen (prefix));
 
     while (last != Iterator (_map.end()) &&
 	   strncmp (last.name(), prefix, n) <= 0)
@@ -271,7 +272,7 @@ ChannelList::channelsWithPrefix (const char prefix[],
 				 ConstIterator &last) const
 {
     first = last = _map.lower_bound (prefix);
-    int n = strlen (prefix);
+    size_t n = strlen (prefix);
 
     while (last != ConstIterator (_map.end()) &&
 	   strncmp (last.name(), prefix, n) <= 0)
@@ -318,4 +319,4 @@ ChannelList::operator == (const ChannelList &other) const
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfChannelList.h b/Source/OpenEXR/IlmImf/ImfChannelList.h
index f3e513a..fc31a15 100644
--- a/Source/OpenEXR/IlmImf/ImfChannelList.h
+++ b/Source/OpenEXR/IlmImf/ImfChannelList.h
@@ -44,17 +44,20 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfName.h>
-#include <ImfPixelType.h>
+#include "ImfName.h"
+#include "ImfPixelType.h"
+
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
 #include <map>
 #include <set>
 #include <string>
 
-
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
-struct Channel
+struct IMF_EXPORT Channel
 {
     //------------------------------
     // Data type; see ImfPixelType.h
@@ -111,7 +114,7 @@ struct Channel
 };
 
 
-class ChannelList
+class IMF_EXPORT ChannelList
 {
   public:
 
@@ -129,7 +132,7 @@ class ChannelList
     // Access to existing channels:
     //
     // [n]		Returns a reference to the channel with name n.
-    //			If no channel with name n exists, an Iex::ArgExc
+    //			If no channel with name n exists, an IEX_NAMESPACE::ArgExc
     //			is thrown.
     //
     // findChannel(n)	Returns a pointer to the channel with name n,
@@ -428,6 +431,6 @@ operator != (const ChannelList::ConstIterator &x,
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfChannelListAttribute.cpp b/Source/OpenEXR/IlmImf/ImfChannelListAttribute.cpp
index df2790b..5549493 100644
--- a/Source/OpenEXR/IlmImf/ImfChannelListAttribute.cpp
+++ b/Source/OpenEXR/IlmImf/ImfChannelListAttribute.cpp
@@ -42,26 +42,26 @@
 
 #include <ImfChannelListAttribute.h>
 
-
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 namespace {
 
 template <size_t N>
 void checkIsNullTerminated (const char (&str)[N], const char *what)
 {
-    for (int i = 0; i < N; ++i) {
+    for (size_t i = 0; i < N; ++i) {
         if (str[i] == '\0')
             return;
    }
     std::stringstream s;
     s << "Invalid " << what << ": it is more than " << (N - 1) 
       << " characters long.";
-    throw Iex::InputExc(s);
+    throw IEX_NAMESPACE::InputExc(s);
 }
 
 } // namespace
 
+
 template <>
 const char *
 ChannelListAttribute::staticTypeName ()
@@ -69,6 +69,7 @@ ChannelListAttribute::staticTypeName ()
     return "chlist";
 }
 
+using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;
 
 template <>
 void
@@ -105,7 +106,9 @@ ChannelListAttribute::writeValueTo (OStream &os, int version) const
 
 template <>
 void
-ChannelListAttribute::readValueFrom (IStream &is, int size, int version)
+ChannelListAttribute::readValueFrom (IStream &is,
+                                     int size,
+                                     int version)
 {
     while (true)
     {
@@ -114,7 +117,7 @@ ChannelListAttribute::readValueFrom (IStream &is, int size, int version)
 	//
 
 	char name[Name::SIZE];
-	Xdr::read <StreamIO> (is, Name::MAX_LENGTH, name);
+	Xdr::read <StreamIO> (is,Name::MAX_LENGTH,name);
 
 	if (name[0] == 0)
 	    break;
@@ -136,10 +139,12 @@ ChannelListAttribute::readValueFrom (IStream &is, int size, int version)
 	Xdr::read <StreamIO> (is, xSampling);
 	Xdr::read <StreamIO> (is, ySampling);
 
-	_value.insert
-	    (name, Channel (PixelType (type), xSampling, ySampling, pLinear));
+	_value.insert (name, Channel (PixelType (type),
+	                              xSampling,
+	                              ySampling,
+	                              pLinear));
     }
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT 
diff --git a/Source/OpenEXR/IlmImf/ImfChannelListAttribute.h b/Source/OpenEXR/IlmImf/ImfChannelListAttribute.h
index 050ecf9..60d8907 100644
--- a/Source/OpenEXR/IlmImf/ImfChannelListAttribute.h
+++ b/Source/OpenEXR/IlmImf/ImfChannelListAttribute.h
@@ -43,25 +43,32 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfAttribute.h>
-#include <ImfChannelList.h>
+#include "ImfAttribute.h"
+#include "ImfChannelList.h"
+#include "ImfExport.h"
 
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-namespace Imf {
 
+typedef TypedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::ChannelList> ChannelListAttribute;
 
-typedef TypedAttribute<ChannelList> ChannelListAttribute;
-template <> const char *ChannelListAttribute::staticTypeName ();
-template <> void ChannelListAttribute::writeValueTo (OStream &, int) const;
-template <> void ChannelListAttribute::readValueFrom (IStream &, int, int);
+template <>
+IMF_EXPORT
+const char *ChannelListAttribute::staticTypeName ();
 
+template <>
+IMF_EXPORT
+void ChannelListAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &,
+                                         int) const;
 
-} // namespace Imf
+template <>
+IMF_EXPORT
+void ChannelListAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &,
+                                          int, int);
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
-// Metrowerks compiler wants the .cpp file inlined, too
-#ifdef __MWERKS__
-#include <ImfChannelListAttribute.cpp>
-#endif
 
 #endif
 
diff --git a/Source/OpenEXR/IlmImf/ImfCheckedArithmetic.h b/Source/OpenEXR/IlmImf/ImfCheckedArithmetic.h
index 00eb93d..6a7fc15 100644
--- a/Source/OpenEXR/IlmImf/ImfCheckedArithmetic.h
+++ b/Source/OpenEXR/IlmImf/ImfCheckedArithmetic.h
@@ -43,15 +43,16 @@
 //-----------------------------------------------------------------------------
 
 #include <limits>
-#include <IexMathExc.h>
+#include "IexMathExc.h"
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 template <bool b> struct StaticAssertionFailed;
 template <> struct StaticAssertionFailed <true> {};
 
 #define IMF_STATIC_ASSERT(x) \
-    do {StaticAssertionFailed <x> staticAssertionFailed;} while (false)
+    do {StaticAssertionFailed <x> staticAssertionFailed; ((void) staticAssertionFailed);} while (false)
 
 
 template <class T>
@@ -66,7 +67,7 @@ uiMult (T a, T b)
                         std::numeric_limits<T>::is_integer);
 
     if (a > 0 && b > std::numeric_limits<T>::max() / a)
-        throw Iex::OverflowExc ("Integer multiplication overflow.");
+        throw IEX_NAMESPACE::OverflowExc ("Integer multiplication overflow.");
 
     return a * b;
 }
@@ -84,7 +85,7 @@ uiDiv (T a, T b)
                         std::numeric_limits<T>::is_integer);
 
     if (b == 0)
-        throw Iex::DivzeroExc ("Integer division by zero.");
+        throw IEX_NAMESPACE::DivzeroExc ("Integer division by zero.");
 
     return a / b;
 }
@@ -102,7 +103,7 @@ uiAdd (T a, T b)
                         std::numeric_limits<T>::is_integer);
 
     if (a > std::numeric_limits<T>::max() - b)
-        throw Iex::OverflowExc ("Integer addition overflow.");
+        throw IEX_NAMESPACE::OverflowExc ("Integer addition overflow.");
 
     return a + b;
 }
@@ -120,7 +121,7 @@ uiSub (T a, T b)
                         std::numeric_limits<T>::is_integer);
 
     if (a < b)
-        throw Iex::UnderflowExc ("Integer subtraction underflow.");
+        throw IEX_NAMESPACE::UnderflowExc ("Integer subtraction underflow.");
 
     return a - b;
 }
@@ -138,7 +139,7 @@ checkArraySize (T n, size_t s)
     //
     //      size_t (n) * s
     //
-    // would overflow, then throw an Iex::OverflowExc exception.
+    // would overflow, then throw an IEX_NAMESPACE::OverflowExc exception.
     // Otherwise return
     //
     //      size_t (n).
@@ -150,12 +151,13 @@ checkArraySize (T n, size_t s)
     IMF_STATIC_ASSERT (sizeof (T) <= sizeof (size_t));
 
     if (size_t (n) > std::numeric_limits<size_t>::max() / s)
-        throw Iex::OverflowExc ("Integer multiplication overflow.");
+        throw IEX_NAMESPACE::OverflowExc ("Integer multiplication overflow.");
 
     return size_t (n);
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfChromaticities.cpp b/Source/OpenEXR/IlmImf/ImfChromaticities.cpp
index 2db9d0e..f354cdf 100644
--- a/Source/OpenEXR/IlmImf/ImfChromaticities.cpp
+++ b/Source/OpenEXR/IlmImf/ImfChromaticities.cpp
@@ -41,14 +41,16 @@
 //-----------------------------------------------------------------------------
 
 #include <ImfChromaticities.h>
+#include "ImfNamespace.h"
+#include <string.h>
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
    
-Chromaticities::Chromaticities (const Imath::V2f &red,
-				const Imath::V2f &green,
-				const Imath::V2f &blue,
-				const Imath::V2f &white)
+Chromaticities::Chromaticities (const IMATH_NAMESPACE::V2f &red,
+				const IMATH_NAMESPACE::V2f &green,
+				const IMATH_NAMESPACE::V2f &blue,
+				const IMATH_NAMESPACE::V2f &white)
 :
     red (red),
     green (green),
@@ -58,8 +60,22 @@ Chromaticities::Chromaticities (const Imath::V2f &red,
     // empty
 }
 
+    
+bool
+Chromaticities::operator == (const Chromaticities & c) const
+{
+    return red == c.red && green == c.green && blue == c.blue;
+}
 
-Imath::M44f
+    
+bool
+Chromaticities::operator != (const Chromaticities & c) const
+{
+    return red != c.red || green != c.green || blue != c.blue;
+}
+    
+    
+IMATH_NAMESPACE::M44f
 RGBtoXYZ (const Chromaticities chroma, float Y)
 {
     //
@@ -107,7 +123,7 @@ RGBtoXYZ (const Chromaticities chroma, float Y)
     // Assemble the matrix
     //
 
-    Imath::M44f M;
+    IMATH_NAMESPACE::M44f M;
 
     M[0][0] = Sr * chroma.red.x;
     M[0][1] = Sr * chroma.red.y;
@@ -125,11 +141,11 @@ RGBtoXYZ (const Chromaticities chroma, float Y)
 }
 
 
-Imath::M44f
+IMATH_NAMESPACE::M44f
 XYZtoRGB (const Chromaticities chroma, float Y)
 {
     return RGBtoXYZ (chroma, Y).inverse();
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfChromaticities.h b/Source/OpenEXR/IlmImf/ImfChromaticities.h
index 28e8c51..9af4769 100644
--- a/Source/OpenEXR/IlmImf/ImfChromaticities.h
+++ b/Source/OpenEXR/IlmImf/ImfChromaticities.h
@@ -45,31 +45,42 @@
 
 #include "ImathVec.h"
 #include "ImathMatrix.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
 
-namespace Imf {
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
    
-struct Chromaticities
+struct IMF_EXPORT Chromaticities
 {
     //-----------------------------------------------
     // The CIE x and y coordinates of the RGB triples
     // (1,0,0), (0,1,0), (0,0,1) and (1,1,1).
     //-----------------------------------------------
 
-    Imath::V2f	red;
-    Imath::V2f	green;
-    Imath::V2f	blue;
-    Imath::V2f	white;
+    IMATH_NAMESPACE::V2f	red;
+    IMATH_NAMESPACE::V2f	green;
+    IMATH_NAMESPACE::V2f	blue;
+    IMATH_NAMESPACE::V2f	white;
 
     //--------------------------------------------
     // Default constructor produces chromaticities
     // according to Rec. ITU-R BT.709-3
     //--------------------------------------------
 
-    Chromaticities (const Imath::V2f &red   = Imath::V2f (0.6400f, 0.3300f),
-		    const Imath::V2f &green = Imath::V2f (0.3000f, 0.6000f),
-		    const Imath::V2f &blue  = Imath::V2f (0.1500f, 0.0600f),
-		    const Imath::V2f &white = Imath::V2f (0.3127f, 0.3290f));
+    Chromaticities (const IMATH_NAMESPACE::V2f &red   = IMATH_NAMESPACE::V2f (0.6400f, 0.3300f),
+		    const IMATH_NAMESPACE::V2f &green = IMATH_NAMESPACE::V2f (0.3000f, 0.6000f),
+		    const IMATH_NAMESPACE::V2f &blue  = IMATH_NAMESPACE::V2f (0.1500f, 0.0600f),
+		    const IMATH_NAMESPACE::V2f &white = IMATH_NAMESPACE::V2f (0.3127f, 0.3290f));
+    
+    
+    //---------
+    // Equality
+    //---------
+    
+    bool		operator == (const Chromaticities &v) const;    
+    bool		operator != (const Chromaticities &v) const;
 };
 
 
@@ -111,10 +122,10 @@ struct Chromaticities
 // 	YYZtoRGB(c,Y) returns RGBtoXYZ(c,Y).inverse().
 // 
 
-Imath::M44f	RGBtoXYZ (const Chromaticities chroma, float Y);
-Imath::M44f	XYZtoRGB (const Chromaticities chroma, float Y);
+IMF_EXPORT IMATH_NAMESPACE::M44f    RGBtoXYZ (const Chromaticities chroma, float Y);
+IMF_EXPORT IMATH_NAMESPACE::M44f    XYZtoRGB (const Chromaticities chroma, float Y);
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfChromaticitiesAttribute.cpp b/Source/OpenEXR/IlmImf/ImfChromaticitiesAttribute.cpp
index 03f3a8d..4d7b985 100644
--- a/Source/OpenEXR/IlmImf/ImfChromaticitiesAttribute.cpp
+++ b/Source/OpenEXR/IlmImf/ImfChromaticitiesAttribute.cpp
@@ -42,8 +42,9 @@
 #include <ImfChromaticitiesAttribute.h>
 
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
+using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;
 
 template <>
 const char *
@@ -55,7 +56,7 @@ ChromaticitiesAttribute::staticTypeName ()
 
 template <>
 void
-ChromaticitiesAttribute::writeValueTo (OStream &os, int version) const
+ChromaticitiesAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     Xdr::write <StreamIO> (os, _value.red.x);
     Xdr::write <StreamIO> (os, _value.red.y);
@@ -70,7 +71,7 @@ ChromaticitiesAttribute::writeValueTo (OStream &os, int version) const
 
 template <>
 void
-ChromaticitiesAttribute::readValueFrom (IStream &is, int size, int version)
+ChromaticitiesAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     Xdr::read <StreamIO> (is, _value.red.x);
     Xdr::read <StreamIO> (is, _value.red.y);
@@ -83,4 +84,4 @@ ChromaticitiesAttribute::readValueFrom (IStream &is, int size, int version)
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT 
diff --git a/Source/OpenEXR/IlmImf/ImfChromaticitiesAttribute.h b/Source/OpenEXR/IlmImf/ImfChromaticitiesAttribute.h
index 08357fa..6c0c35a 100644
--- a/Source/OpenEXR/IlmImf/ImfChromaticitiesAttribute.h
+++ b/Source/OpenEXR/IlmImf/ImfChromaticitiesAttribute.h
@@ -43,30 +43,31 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfAttribute.h>
-#include <ImfChromaticities.h>
+#include "ImfAttribute.h"
+#include "ImfChromaticities.h"
 
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-namespace Imf {
 
-
-typedef TypedAttribute<Chromaticities> ChromaticitiesAttribute;
+typedef TypedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::Chromaticities> ChromaticitiesAttribute;
 
 template <>
+IMF_EXPORT
 const char *ChromaticitiesAttribute::staticTypeName ();
 
 template <>
-void ChromaticitiesAttribute::writeValueTo (OStream &, int) const;
+IMF_EXPORT
+void ChromaticitiesAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &,
+                                            int) const;
 
 template <>
-void ChromaticitiesAttribute::readValueFrom (IStream &, int, int);
+IMF_EXPORT
+void ChromaticitiesAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &,
+                                             int,
+                                             int);
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
-// Metrowerks compiler wants the .cpp file inlined, too
-#ifdef __MWERKS__
-#include <ImfChromaticitiesAttribute.cpp>
-#endif
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfCompositeDeepScanLine.cpp b/Source/OpenEXR/IlmImf/ImfCompositeDeepScanLine.cpp
new file mode 100644
index 0000000..7e0dac0
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfCompositeDeepScanLine.cpp
@@ -0,0 +1,591 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2012, Weta Digital Ltd
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Weta Digital nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission. 
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+#include "ImfCompositeDeepScanLine.h"
+#include "ImfDeepScanLineInputPart.h"
+#include "ImfDeepScanLineInputFile.h"
+#include "ImfChannelList.h"
+#include "ImfFrameBuffer.h"
+#include "ImfDeepFrameBuffer.h"
+#include "ImfDeepCompositing.h"
+#include "ImfPixelType.h"
+#include "IlmThreadPool.h"
+
+#include <Iex.h>
+#include <vector>
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+using std::vector;
+using std::string;
+using IMATH_NAMESPACE::Box2i;
+using ILMTHREAD_NAMESPACE::Task;
+using ILMTHREAD_NAMESPACE::TaskGroup;
+using ILMTHREAD_NAMESPACE::ThreadPool;
+
+
+
+struct CompositeDeepScanLine::Data{
+    public :
+    vector<DeepScanLineInputFile *>     _file;   // array of files    
+    vector<DeepScanLineInputPart *>     _part;   // array of parts 
+    FrameBuffer            _outputFrameBuffer;   // output frame buffer provided
+    bool                               _zback;   // true if we are using zback (otherwise channel 1 = channel 0)
+    vector< vector<float> >      _channeldata;   // pixel values, read from the input, one array per channel
+    vector< int >               _sampleCounts;   // total per-pixel sample counts,   
+    Box2i                         _dataWindow;   // data window of combined inputs
+    DeepCompositing *                   _comp;   // user-provided compositor
+    vector<string>                  _channels;   // names of channels that will be composited
+    vector<int>                    _bufferMap;   // entry _outputFrameBuffer[n].name() == _channels[ _bufferMap[n] ].name()
+    
+    void check_valid(const Header & header);     // check newly added part/file is OK; on first good call, set _zback/_dataWindow
+
+    //
+    // set up the given deep frame buffer to contain the required channels
+    // resize counts and pointers to the width of _dataWindow
+    // zero-out all counts, since the datawindow may be smaller than/not include this part
+    //
+
+    void handleDeepFrameBuffer (DeepFrameBuffer & buf,
+                                vector<unsigned int> & counts,        //per-pixel counts
+                                vector< vector<float *> > & pointers, //per-channel-per-pixel pointers to data
+                                const Header & header,
+                                int start,
+                                int end);
+
+    Data();
+};
+
+CompositeDeepScanLine::Data::Data() : _zback(false) , _comp(NULL) {}
+
+CompositeDeepScanLine::CompositeDeepScanLine() : _Data(new Data) {}
+
+CompositeDeepScanLine::~CompositeDeepScanLine()
+{
+   delete _Data;
+}
+
+void
+CompositeDeepScanLine::addSource(DeepScanLineInputPart* part)
+{
+  _Data->check_valid(part->header());
+  _Data->_part.push_back(part);
+}
+
+void
+CompositeDeepScanLine::addSource(DeepScanLineInputFile* file)
+{
+    _Data->check_valid(file->header());
+    _Data->_file.push_back(file);
+}
+
+int 
+CompositeDeepScanLine::sources() const
+{
+   return int(_Data->_part.size())+int(_Data->_file.size());
+}
+
+void
+CompositeDeepScanLine::Data::check_valid(const Header & header)
+{
+
+    bool has_z=false;
+    bool has_alpha=false;
+    // check good channel names
+    for( ChannelList::ConstIterator i=header.channels().begin();i!=header.channels().end();++i)
+    {
+        std::string n(i.name()); 
+        if(n=="ZBack")
+        {
+            _zback=true;
+        }
+        else if(n=="Z")
+        {
+            has_z=true;
+        }
+        else if(n=="A")
+        {
+            has_alpha=true;
+        }
+    }
+    
+    if(!has_z)
+    {
+        throw IEX_NAMESPACE::ArgExc("Deep data provided to CompositeDeepScanLine is missing a Z channel");
+    }
+    
+    if(!has_alpha)
+    {
+        throw IEX_NAMESPACE::ArgExc("Deep data provided to CompositeDeepScanLine is missing an alpha channel");
+    }
+    
+    
+    if(_part.size()==0 && _file.size()==0)
+    {
+       // first in - update and return
+
+       _dataWindow = header.dataWindow();
+       
+       return;
+    }
+    
+    
+    const Header * const match_header = _part.size()>0 ? &_part[0]->header() : &_file[0]->header();
+    
+    // check the sizes match
+    if(match_header->displayWindow() != header.displayWindow())
+    {
+        throw IEX_NAMESPACE::ArgExc("Deep data provided to CompositeDeepScanLine has a different displayWindow to previously provided data");
+    }
+    
+    _dataWindow.extendBy(header.dataWindow());
+    
+}
+void 
+CompositeDeepScanLine::Data::handleDeepFrameBuffer (DeepFrameBuffer& buf,
+                                                    std::vector< unsigned int > & counts,
+                                                    vector< std::vector< float* > > & pointers,
+                                                    const Header& header,
+                                                    int start,
+                                                    int end)
+{
+    int width=_dataWindow.size().x+1;
+    size_t pixelcount = width * (end-start+1);
+    pointers.resize(_channels.size());
+    counts.resize(pixelcount);
+    buf.insertSampleCountSlice (Slice (OPENEXR_IMF_INTERNAL_NAMESPACE::UINT,
+                                (char *) (&counts[0]-_dataWindow.min.x-start*width),
+                                sizeof(unsigned int),
+                                sizeof(unsigned int)*width));
+
+    pointers[0].resize(pixelcount);
+    buf.insert ("Z", DeepSlice (OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT,
+                                (char *)(&pointers[0][0]-_dataWindow.min.x-start*width),
+                                sizeof(float *),
+                                sizeof(float *)*width,
+                                sizeof(float) ));
+
+    if(_zback)
+    {
+        pointers[1].resize(pixelcount);
+        buf.insert ("ZBack", DeepSlice (OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT,
+                                        (char *)(&pointers[1][0]-_dataWindow.min.x-start*width),
+                                        sizeof(float *),
+                                        sizeof(float *)*width,
+                                        sizeof(float) ));
+    }
+
+    pointers[2].resize(pixelcount);
+    buf.insert ("A", DeepSlice (OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT,
+                                (char *)(&pointers[2][0]-_dataWindow.min.x-start*width),
+                                sizeof(float *),
+                                sizeof(float *)*width,
+                                sizeof(float) ));
+
+
+    size_t i =0;
+    for(FrameBuffer::ConstIterator qt  = _outputFrameBuffer.begin();
+                                   qt != _outputFrameBuffer.end();
+                                   qt++)
+    {
+        int channel_in_source = _bufferMap[i];
+        if(channel_in_source>2)
+        {
+            // not dealt with yet (0,1,2 previously inserted)
+            pointers[channel_in_source].resize(pixelcount);
+            buf.insert (qt.name(),
+                        DeepSlice (OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT,
+                                   (char *)(&pointers[channel_in_source][0]-_dataWindow.min.x-start*width),
+                                   sizeof(float *),
+                                   sizeof(float *)*width,
+                                   sizeof(float) ));
+        }
+
+        i++;
+    }
+
+}
+
+void
+CompositeDeepScanLine::setCompositing(DeepCompositing* c)
+{
+  _Data->_comp=c;
+}
+
+const IMATH_NAMESPACE::Box2i& CompositeDeepScanLine::dataWindow() const
+{
+  return  _Data->_dataWindow;
+}
+
+
+void
+CompositeDeepScanLine::setFrameBuffer(const FrameBuffer& fr)
+{
+    
+    //
+    // count channels; build map between channels in frame buffer
+    // and channels in internal buffers
+    //
+    
+    _Data->_channels.resize(3);
+    _Data->_channels[0]="Z";
+    _Data->_channels[1]=_Data->_zback ? "ZBack" : "Z";
+    _Data->_channels[2]="A";
+    _Data->_bufferMap.resize(0);
+    
+    for(FrameBuffer::ConstIterator q=fr.begin();q!=fr.end();q++)
+    {
+        string name(q.name());
+        if(name=="ZBack")
+        {
+            _Data->_bufferMap.push_back(1);
+        }else if(name=="Z")
+        {
+            _Data->_bufferMap.push_back(0);
+        }else if(name=="A")
+        {
+            _Data->_bufferMap.push_back(2);
+        }else{
+            _Data->_bufferMap.push_back(_Data->_channels.size());
+            _Data->_channels.push_back(name);
+        }
+    }
+    
+  _Data->_outputFrameBuffer=fr;
+}
+
+namespace 
+{
+    
+class LineCompositeTask : public Task
+{
+  public:
+
+    LineCompositeTask ( TaskGroup* group ,
+                        CompositeDeepScanLine::Data * data,
+                    int y,
+                    int start,
+                    vector<const char*>* names,
+                    vector<vector< vector<float *> > >* pointers,
+                    vector<unsigned int>* total_sizes,
+                    vector<unsigned int>* num_sources
+                  ) : Task(group) ,
+                     _Data(data),
+                     _y(y),
+                     _start(start),
+                     _names(names),
+                     _pointers(pointers),
+                     _total_sizes(total_sizes),
+                     _num_sources(num_sources)
+                     {}
+
+    virtual ~LineCompositeTask () {}
+
+    virtual void                execute ();
+    CompositeDeepScanLine::Data*         _Data;
+    int                                  _y;
+    int                                  _start;
+    vector<const char *>*                _names;
+    vector<vector< vector<float *> > >*  _pointers;
+    vector<unsigned int>*                _total_sizes;
+    vector<unsigned int>*                _num_sources;
+
+};
+
+
+void
+composite_line(int y,
+               int start,
+               CompositeDeepScanLine::Data * _Data,
+               vector<const char *> & names,
+               const vector<vector< vector<float *> > >  & pointers,
+               const vector<unsigned int> & total_sizes,
+               const vector<unsigned int> & num_sources
+              )
+{
+    vector<float> output_pixel(names.size());    //the pixel we'll output to
+    vector<const float *> inputs(names.size());
+    DeepCompositing d; // fallback compositing engine
+    DeepCompositing * comp= _Data->_comp ? _Data->_comp : &d;
+
+    int pixel = (y-start)*(_Data->_dataWindow.max.x+1-_Data->_dataWindow.min.x);
+    
+     for(int x=_Data->_dataWindow.min.x;x<=_Data->_dataWindow.max.x;x++)
+     {
+           // set inputs[] to point to the first sample of the first part of each channel
+           // if there's a zback, set all channel independently...
+
+          if(_Data->_zback)
+          {
+
+              for(size_t channel=0;channel<names.size();channel++)
+              {
+                 inputs[channel]=pointers[0][channel][pixel];
+              }
+
+          }else{
+
+              // otherwise, set 0 and 1 to point to Z
+
+
+              inputs[0]=pointers[0][0][pixel];
+              inputs[1]=pointers[0][0][pixel];
+              for(size_t channel=2;channel<names.size();channel++)
+              {
+                  inputs[channel]=pointers[0][channel][pixel];
+              }
+
+          }
+          comp->composite_pixel(&output_pixel[0],
+                                &inputs[0],
+                                &names[0],
+                                names.size(),
+                                total_sizes[pixel],
+                                num_sources[pixel]
+                               );
+
+
+           size_t channel_number=0;
+
+
+           //
+           // write out composited value into internal frame buffer
+           //
+           for(FrameBuffer::Iterator it = _Data->_outputFrameBuffer.begin();it !=_Data->_outputFrameBuffer.end();it++)
+           {
+
+               float value = output_pixel[ _Data->_bufferMap[channel_number] ]; // value to write
+
+
+                // cast to half float if necessary
+               if(it.slice().type==OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT)
+               {
+                   * (float *)(it.slice().base + y*it.slice().yStride + x*it.slice().xStride) = value;
+               }
+               else if(it.slice().type==HALF)
+               {
+                   * (half *)(it.slice().base + y*it.slice().yStride + x*it.slice().xStride) = half(value);
+               }
+
+               channel_number++;
+
+           }
+
+           pixel++;
+
+       }// next pixel on row
+}
+
+void LineCompositeTask::execute()
+{
+  composite_line(_y,_start,_Data,*_names,*_pointers,*_total_sizes,*_num_sources);
+}
+
+
+}
+
+void
+CompositeDeepScanLine::readPixels(int start, int end)
+{
+   size_t parts = _Data->_file.size() + _Data->_part.size(); // total of files+parts
+   
+   vector<DeepFrameBuffer> framebuffers(parts);
+   vector< vector<unsigned int> > counts(parts);
+   
+   //
+   // for each part, a pointer to an array of channels
+   //
+   vector<vector< vector<float *> > > pointers(parts);
+   vector<const Header *> headers(parts);
+   
+   {
+     size_t i;
+     for(i=0;i<_Data->_file.size();i++)
+     {
+         headers[i] = &_Data->_file[i]->header();
+     }
+     
+     for(size_t j=0;j<_Data->_part.size();j++)
+     {
+        headers[i+j] = &_Data->_part[j]->header();
+     }
+   }
+   
+   
+   for(size_t i=0;i<parts;i++)
+   {
+     _Data->handleDeepFrameBuffer(framebuffers[i],counts[i],pointers[i],*headers[i],start,end);
+   }
+   
+   //
+   // set frame buffers and read scanlines from all parts
+   // TODO what happens if SCANLINE not in data window?
+   //
+   
+   {
+       size_t i=0;
+       for(i=0;i<_Data->_file.size();i++)
+       {
+            _Data->_file[i]->setFrameBuffer(framebuffers[i]);
+            _Data->_file[i]->readPixelSampleCounts(start,end);
+       }
+       for(size_t j=0;j<_Data->_part.size();j++)
+       {
+           _Data->_part[j]->setFrameBuffer(framebuffers[i+j]);
+           _Data->_part[j]->readPixelSampleCounts(start,end); 
+       }
+   }   
+   
+   
+   //
+   //  total width
+   //
+   
+   size_t total_width = _Data->_dataWindow.size().x+1;
+   size_t total_pixels = total_width*(end-start+1);
+   vector<unsigned int> total_sizes(total_pixels);
+   vector<unsigned int> num_sources(total_pixels); //number of parts with non-zero sample count
+   
+   size_t overall_sample_count=0; // sum of all samples in all images between start and end
+   
+   
+   //
+   // accumulate pixel counts
+   //
+   for(size_t ptr=0;ptr<total_pixels;ptr++)
+   {
+       total_sizes[ptr]=0;
+       num_sources[ptr]=0;
+       for(size_t j=0;j<parts;j++)
+       {
+          total_sizes[ptr]+=counts[j][ptr];
+          if(counts[j][ptr]>0) num_sources[ptr]++;
+       }
+       overall_sample_count+=total_sizes[ptr];
+       
+       
+       
+   }
+   
+  
+  
+   
+   //
+   // allocate arrays for pixel data
+   // samples array accessed as in pixels[channel][sample]
+   //
+   
+   vector<vector<float> > samples( _Data->_channels.size() );
+   
+   for(size_t channel=0;channel<_Data->_channels.size();channel++)
+   {
+       if( channel!=1 || _Data->_zback)
+       {            
+           samples[channel].resize(overall_sample_count);
+       }
+   }
+   
+   for(size_t channel=0;channel<samples.size();channel++)
+   {
+       
+       if( channel!=1 || _Data->_zback)
+       {
+           
+           samples[channel].resize(overall_sample_count);
+       
+       
+          //
+          // allocate pointers for channel data
+          //
+          
+          size_t offset=0;
+       
+          for(size_t pixel=0;pixel<total_pixels;pixel++)
+          {
+              for(size_t part=0 ; part<parts && offset<overall_sample_count ; part++ )
+              {
+                      pointers[part][channel][pixel]=&samples[channel][offset];           
+                      offset+=counts[part][pixel];
+              }
+          }
+       
+       }
+   }
+   
+   //
+   // read data
+   //
+   
+   for(size_t i=0;i<_Data->_file.size();i++)
+   {
+       _Data->_file[i]->readPixels(start,end);
+   }
+   for(size_t j=0;j<_Data->_part.size();j++)
+   {
+       _Data->_part[j]->readPixels(start,end); 
+   }
+   
+   
+   
+   
+   //
+   // composite pixels and write back to framebuffer
+  //
+   
+   
+   // turn vector of strings into array of char *
+   // and make sure 'ZBack' channel is correct
+   vector<const char *> names(_Data->_channels.size());
+   for(size_t i=0;i<names.size();i++)
+   {
+       names[i]=_Data->_channels[i].c_str();
+   }
+   
+   if(!_Data->_zback) names[1]=names[0]; // no zback channel, so make it point to z
+
+   
+   
+   TaskGroup g;
+   for(int y=start;y<=end;y++)
+   {
+       ThreadPool::addGlobalTask(new LineCompositeTask(&g,_Data,y,start,&names,&pointers,&total_sizes,&num_sources));
+   }//next row
+}  
+
+const FrameBuffer& 
+CompositeDeepScanLine::frameBuffer() const
+{
+  return _Data->_outputFrameBuffer;
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfCompositeDeepScanLine.h b/Source/OpenEXR/IlmImf/ImfCompositeDeepScanLine.h
new file mode 100644
index 0000000..2dc23e5
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfCompositeDeepScanLine.h
@@ -0,0 +1,142 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2012, Weta Digital Ltd
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Weta Digital nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission. 
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+#ifndef INCLUDED_IMF_COMPOSITEDEEPSCANLINE_H
+#define INCLUDED_IMF_COMPOSITEDEEPSCANLINE_H
+
+//-----------------------------------------------------------------------------
+//
+//	Class to composite deep samples into a frame buffer
+//      Initialise with a deep input part or deep inputfile
+//      (also supports multiple files and parts, and will 
+//       composite them together, as long as their sizes and channelmaps agree)
+//       
+//      Then call setFrameBuffer, and readPixels, exactly as for reading 
+//      regular scanline images.
+//
+//      Restrictions - source file(s) must contain at least Z and alpha channels
+//                   - if multiple files/parts are provided, sizes must match
+//                   - all requested channels will be composited as premultiplied
+//                   - only half and float channels can be requested
+//
+//      This object should not be considered threadsafe
+//  
+//      The default compositing engine will give spurious results with overlapping
+//      volumetric samples - you may derive from DeepCompositing class, override the 
+//      sort_pixel() and composite_pixel() functions, and pass an instance to 
+//      setCompositing(). 
+//
+//-----------------------------------------------------------------------------
+
+#include "ImfForward.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+#include <ImathBox.h>
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+class IMF_EXPORT CompositeDeepScanLine
+{
+    public:
+        CompositeDeepScanLine();
+       virtual ~CompositeDeepScanLine();
+        
+        /// set the source data as a part
+        ///@note all parts must remain valid until after last interaction with DeepComp
+        void addSource(DeepScanLineInputPart * part);
+        
+        /// set the source data as a file
+        ///@note all file must remain valid until after last interaction with DeepComp
+        void addSource(DeepScanLineInputFile * file);
+        
+        
+        /////////////////////////////////////////
+        //
+        // set the frame buffer for output values
+        // the buffers specified must be large enough
+        // to handle the dataWindow() 
+        //
+        /////////////////////////////////////////
+        void setFrameBuffer(const FrameBuffer & fr);
+        
+        
+        
+        /////////////////////////////////////////
+        //
+        // retrieve frameBuffer
+        //
+        ////////////////////////////////////////
+        const FrameBuffer & frameBuffer() const;
+        
+        
+        //////////////////////////////////////////////////
+        //
+        // read scanlines start to end from the source(s)
+        // storing the result in the frame buffer provided
+        //
+        //////////////////////////////////////////////////
+        
+        void readPixels(int start,int end);
+        
+        int sources() const; // return number of sources
+        
+        /////////////////////////////////////////////////
+        //
+        // retrieve the datawindow
+        // If multiple parts are specified, this will
+        // be the union of the dataWindow of all parts
+        //
+        ////////////////////////////////////////////////
+        
+        const IMATH_NAMESPACE::Box2i & dataWindow() const;
+        
+ 
+        //
+        // override default sorting/compositing operation
+        // (otherwise an instance of the base class will be used)
+        //
+        
+        void setCompositing(DeepCompositing *);
+        
+      struct Data; 
+    private :  
+      struct Data *_Data;
+      
+      CompositeDeepScanLine(const CompositeDeepScanLine &); // not implemented
+      const CompositeDeepScanLine & operator=(const CompositeDeepScanLine &);  // not implemented
+};
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif
diff --git a/Source/OpenEXR/IlmImf/ImfCompression.h b/Source/OpenEXR/IlmImf/ImfCompression.h
index 2115943..c066d34 100644
--- a/Source/OpenEXR/IlmImf/ImfCompression.h
+++ b/Source/OpenEXR/IlmImf/ImfCompression.h
@@ -42,9 +42,9 @@
 //	enum Compression
 //
 //-----------------------------------------------------------------------------
+#include "ImfNamespace.h"
 
-namespace Imf {
-
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 enum Compression
 {
@@ -66,10 +66,19 @@ enum Compression
     B44A_COMPRESSION = 7,	// lossy 4-by-4 pixel block compression,
     				// flat fields are compressed more
 
+    DWAA_COMPRESSION = 8,       // lossy DCT based compression, in blocks
+                                // of 32 scanlines. More efficient for partial
+                                // buffer access.
+
+    DWAB_COMPRESSION = 9,       // lossy DCT based compression, in blocks
+                                // of 256 scanlines. More efficient space
+                                // wise and faster to decode full frames
+                                // than DWAA_COMPRESSION.
+
     NUM_COMPRESSION_METHODS	// number of different compression methods
 };
 
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
-} // namespace Imf
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfCompressionAttribute.cpp b/Source/OpenEXR/IlmImf/ImfCompressionAttribute.cpp
index 0c28d16..a32c689 100644
--- a/Source/OpenEXR/IlmImf/ImfCompressionAttribute.cpp
+++ b/Source/OpenEXR/IlmImf/ImfCompressionAttribute.cpp
@@ -40,10 +40,12 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfCompressionAttribute.h>
+#include "ImfCompressionAttribute.h"
 
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;
 
 
 template <>
@@ -56,7 +58,7 @@ CompressionAttribute::staticTypeName ()
 
 template <>
 void
-CompressionAttribute::writeValueTo (OStream &os, int version) const
+CompressionAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     unsigned char tmp = _value;
     Xdr::write <StreamIO> (os, tmp);
@@ -65,7 +67,7 @@ CompressionAttribute::writeValueTo (OStream &os, int version) const
 
 template <>
 void
-CompressionAttribute::readValueFrom (IStream &is, int size, int version)
+CompressionAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     unsigned char tmp;
     Xdr::read <StreamIO> (is, tmp);
@@ -73,4 +75,4 @@ CompressionAttribute::readValueFrom (IStream &is, int size, int version)
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT 
diff --git a/Source/OpenEXR/IlmImf/ImfCompressionAttribute.h b/Source/OpenEXR/IlmImf/ImfCompressionAttribute.h
index 268c26b..bfc72de 100644
--- a/Source/OpenEXR/IlmImf/ImfCompressionAttribute.h
+++ b/Source/OpenEXR/IlmImf/ImfCompressionAttribute.h
@@ -43,24 +43,22 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfAttribute.h>
-#include <ImfCompression.h>
+#include "ImfAttribute.h"
+#include "ImfCompression.h"
 
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-namespace Imf {
 
-
-typedef TypedAttribute<Compression> CompressionAttribute;
+typedef TypedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::Compression> CompressionAttribute;
 template <> const char *CompressionAttribute::staticTypeName ();
-template <> void CompressionAttribute::writeValueTo (OStream &, int) const;
-template <> void CompressionAttribute::readValueFrom (IStream &, int, int);
+template <> void CompressionAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &,
+                                                     int) const;
+template <> void CompressionAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &,
+                                                      int,
+                                                      int);
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
-// Metrowerks compiler wants the .cpp file inlined, too
-#ifdef __MWERKS__
-#include <ImfCompressionAttribute.cpp>
-#endif
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfCompressor.cpp b/Source/OpenEXR/IlmImf/ImfCompressor.cpp
index 96bde8f..1905a4d 100644
--- a/Source/OpenEXR/IlmImf/ImfCompressor.cpp
+++ b/Source/OpenEXR/IlmImf/ImfCompressor.cpp
@@ -40,17 +40,19 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfCompressor.h>
-#include <ImfRleCompressor.h>
-#include <ImfZipCompressor.h>
-#include <ImfPizCompressor.h>
-#include <ImfPxr24Compressor.h>
-#include <ImfB44Compressor.h>
-#include <ImfCheckedArithmetic.h>
+#include "ImfCompressor.h"
+#include "ImfRleCompressor.h"
+#include "ImfZipCompressor.h"
+#include "ImfPizCompressor.h"
+#include "ImfPxr24Compressor.h"
+#include "ImfB44Compressor.h"
+#include "ImfDwaCompressor.h"
+#include "ImfCheckedArithmetic.h"
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
-using Imath::Box2i;
+using IMATH_NAMESPACE::Box2i;
 
 
 Compressor::Compressor (const Header &hdr): _header (hdr) {}
@@ -99,6 +101,8 @@ isValidCompression (Compression c)
       case PXR24_COMPRESSION:
       case B44_COMPRESSION:
       case B44A_COMPRESSION:
+      case DWAA_COMPRESSION:
+      case DWAB_COMPRESSION:
 
 	return true;
 
@@ -108,6 +112,19 @@ isValidCompression (Compression c)
     }
 }
 
+bool isValidDeepCompression(Compression c)
+{
+  switch(c)
+  {
+      case NO_COMPRESSION:
+      case RLE_COMPRESSION:
+      case ZIPS_COMPRESSION:
+          return true;
+      default :
+          return false;
+  }
+}
+
 
 Compressor *
 newCompressor (Compression c, size_t maxScanLineSize, const Header &hdr)
@@ -142,6 +159,16 @@ newCompressor (Compression c, size_t maxScanLineSize, const Header &hdr)
 
 	return new B44Compressor (hdr, maxScanLineSize, 32, true);
 
+      case DWAA_COMPRESSION:
+
+	return new DwaCompressor (hdr, maxScanLineSize, 32, 
+                               DwaCompressor::STATIC_HUFFMAN);
+
+      case DWAB_COMPRESSION:
+
+	return new DwaCompressor (hdr, maxScanLineSize, 256, 
+                               DwaCompressor::STATIC_HUFFMAN);
+
       default:
 
 	return 0;
@@ -182,6 +209,12 @@ newTileCompressor (Compression c,
 
 	return new B44Compressor (hdr, tileLineSize, numTileLines, true);
 
+      case DWAA_COMPRESSION:
+      case DWAB_COMPRESSION:
+
+	return new DwaCompressor (hdr, tileLineSize, numTileLines, 
+                               DwaCompressor::DEFLATE);
+
       default:
 
 	return 0;
@@ -189,4 +222,5 @@ newTileCompressor (Compression c,
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
+
diff --git a/Source/OpenEXR/IlmImf/ImfCompressor.h b/Source/OpenEXR/IlmImf/ImfCompressor.h
index 6039396..d04a4bb 100644
--- a/Source/OpenEXR/IlmImf/ImfCompressor.h
+++ b/Source/OpenEXR/IlmImf/ImfCompressor.h
@@ -43,16 +43,19 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfCompression.h>
+#include "ImfCompression.h"
 #include "ImathBox.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+#include "ImfForward.h"
+
 #include <stdlib.h>
 
-namespace Imf {
 
-class Header;
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
-class Compressor
+class IMF_EXPORT Compressor
 {
   public:
 
@@ -162,7 +165,7 @@ class Compressor
 
     virtual int		compressTile (const char *inPtr,
 				      int inSize,
-				      Imath::Box2i range,
+				      IMATH_NAMESPACE::Box2i range,
 				      const char *&outPtr);
 
     //-------------------------------------------------------------------------
@@ -188,7 +191,7 @@ class Compressor
 
     virtual int		uncompressTile (const char *inPtr,
 					int inSize,
-					Imath::Box2i range,
+					IMATH_NAMESPACE::Box2i range,
 					const char *&outPtr);
 
   private:
@@ -201,7 +204,15 @@ class Compressor
 // Test if c is a valid compression type
 //--------------------------------------
 
-bool		isValidCompression (Compression c);
+IMF_EXPORT 
+bool isValidCompression (Compression c);
+
+//--------------------------------------
+// Test if c is valid for deep data
+//--------------------------------------
+
+IMF_EXPORT
+bool            isValidDeepCompression (Compression c);
 
 
 //-----------------------------------------------------------------
@@ -219,6 +230,7 @@ bool		isValidCompression (Compression c);
 //
 //-----------------------------------------------------------------
 
+IMF_EXPORT 
 Compressor *	newCompressor (Compression c,
 			       size_t maxScanLineSize,
 			       const Header &hdr);
@@ -241,12 +253,13 @@ Compressor *	newCompressor (Compression c,
 //
 //-----------------------------------------------------------------
 
+IMF_EXPORT 
 Compressor *    newTileCompressor (Compression c,
 				   size_t tileLineSize,
 				   size_t numTileLines,
 				   const Header &hdr);
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfConvert.cpp b/Source/OpenEXR/IlmImf/ImfConvert.cpp
index 0d6a4a1..cce7163 100644
--- a/Source/OpenEXR/IlmImf/ImfConvert.cpp
+++ b/Source/OpenEXR/IlmImf/ImfConvert.cpp
@@ -40,10 +40,14 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfConvert.h>
+#include "ImfConvert.h"
+#include "ImfNamespace.h"
+
 #include <limits.h>
 
-namespace Imf {
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
 namespace {
 
 inline bool
@@ -116,7 +120,7 @@ uintToHalf (unsigned int ui)
     if (ui >  HALF_MAX)
 	return half::posInf();
 
-    return half (ui);
+    return half ((float) ui);
 }
 
 
@@ -136,4 +140,4 @@ floatToHalf (float f)
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfConvert.h b/Source/OpenEXR/IlmImf/ImfConvert.h
index fc2c037..b0a7f47 100644
--- a/Source/OpenEXR/IlmImf/ImfConvert.h
+++ b/Source/OpenEXR/IlmImf/ImfConvert.h
@@ -47,9 +47,11 @@
 //-----------------------------------------------------------------------------
 
 #include "half.h"
+#include "ImfExport.h"
+#include "ImfNamespace.h"
 
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-namespace Imf {
 
 //---------------------------------------------------------
 // Conversion from half or float to unsigned int:
@@ -70,8 +72,8 @@ namespace Imf {
 //
 //---------------------------------------------------------
 
-unsigned int	halfToUint (half h);
-unsigned int	floatToUint (float f);
+IMF_EXPORT unsigned int	halfToUint (half h);
+IMF_EXPORT unsigned int	floatToUint (float f);
 
 
 //---------------------------------------------------------
@@ -95,10 +97,11 @@ unsigned int	floatToUint (float f);
 //
 //---------------------------------------------------------
 
-half		uintToHalf (unsigned int ui);
-half		floatToHalf (float f);
+IMF_EXPORT half		uintToHalf (unsigned int ui);
+IMF_EXPORT half		floatToHalf (float f);
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfDeepCompositing.cpp b/Source/OpenEXR/IlmImf/ImfDeepCompositing.cpp
new file mode 100644
index 0000000..76702c1
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfDeepCompositing.cpp
@@ -0,0 +1,110 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2012, Weta Digital Ltd
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Weta Digital nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission. 
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#include "ImfDeepCompositing.h"
+
+#include "ImfNamespace.h"
+#include <algorithm>
+#include <vector>
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+using std::sort;
+using std::vector;
+DeepCompositing::DeepCompositing()
+{
+}
+
+DeepCompositing::~DeepCompositing()
+{
+}
+
+void 
+DeepCompositing::composite_pixel (float outputs[],
+                                  const float* inputs[],
+                                  const char*channel_names[],
+                                  int num_channels,
+                                  int num_samples,
+                                  int sources)
+{
+    for(int i=0;i<num_channels;i++) outputs[i]=0.0;
+    // no samples? do nothing
+   if(num_samples==0)
+   {
+       return;
+   }
+   
+   vector<int> sort_order;
+   if(sources>1)
+   {
+       sort_order.resize(num_samples);
+       for(int i=0;i<num_samples;i++) sort_order[i]=i;
+       sort(&sort_order[0],inputs,channel_names,num_channels,num_samples,sources);
+   }
+   
+   
+   for(int i=0;i<num_samples;i++)
+   {
+       int s=(sources>1) ? sort_order[i] : i;
+       float alpha=outputs[2]; 
+       if(alpha>=1.0) return;
+       
+       for(int c=0;c<num_channels;c++)
+       {
+           outputs[c]+=(1.0-alpha)*inputs[c][s];
+       }
+   }   
+}
+
+struct sort_helper
+{
+    const float ** inputs;
+    bool operator() (int a,int b) 
+    {
+        if(inputs[0][a] < inputs[0][b]) return true;
+        if(inputs[0][a] > inputs[0][b]) return false;
+        if(inputs[1][a] < inputs[1][b]) return true;
+        if(inputs[1][a] > inputs[1][b]) return false;
+        return a<b;
+    }
+    sort_helper(const float ** i) : inputs(i) {}
+};
+
+void
+DeepCompositing::sort(int order[], const float* inputs[], const char* channel_names[], int num_channels, int num_samples, int sources)
+{
+  std::sort(order+0,order+num_samples,sort_helper(inputs));
+}
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfDeepCompositing.h b/Source/OpenEXR/IlmImf/ImfDeepCompositing.h
new file mode 100644
index 0000000..b400efc
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfDeepCompositing.h
@@ -0,0 +1,132 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2012, Weta Digital Ltd
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Weta Digital nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission. 
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+#ifndef INCLUDED_IMF_DEEPCOMPOSITING_H
+#define INCLUDED_IMF_DEEPCOMPOSITING_H
+
+//-----------------------------------------------------------------------------
+//
+//	Class to sort and composite deep samples into a frame buffer
+//      You may derive from this class to change the way that CompositeDeepScanLine
+//      and CompositeDeepTile combine samples together - pass an instance of your derived
+//      class to the compositing engine
+//
+//-----------------------------------------------------------------------------
+
+#include "ImfForward.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+class IMF_EXPORT DeepCompositing
+{
+    public:
+        DeepCompositing();
+        virtual ~DeepCompositing();
+        
+        
+        //////////////////////////////////////////////
+        ///
+        /// composite together the given channels
+        /// 
+        ///  @param outputs       - return array of pixel values - 
+        ///  @param inputs        - arrays of input sample
+        ///  @param channel_names - array of channel names for corresponding channels
+        ///  @param num_channels  - number of active channels (3 or greater)    
+        ///  @param num_samples   - number of values in all input arrays
+        ///  @param sources       - number of different sources
+        ///
+        /// each array input has num_channels entries: outputs[n] should be the composited
+        /// values in array inputs[n], whose name will be given by channel_names[n]
+        /// 
+        /// The channel ordering shall be as follows:
+        /// Position Channel
+        ///    0     Z
+        ///    1     ZBack (if no ZBack, then inputs[1]==inputs[0] and channel_names[1]==channel_names[0])
+        ///    2     A (alpha channel)
+        ///    3-n   other channels - only channels in the frame buffer will appear here
+        ///
+        /// since a Z and Alpha channel is required, and channel[1] is ZBack or another copy of Z
+        /// there will always be 3 or more channels.
+        ///
+        /// The default implementation calls sort() if and only if more than one source is active,
+        /// composites all samples together using the Over operator from front to back,
+        /// stopping as soon as a sample with alpha=1 is found
+        /// It also blanks all outputs if num_samples==0
+        ///
+        /// note - multiple threads may call composite_pixel simultaneously for different pixels
+        ///
+        ///
+        //////////////////////////////////////////////
+        virtual void composite_pixel(float outputs[],
+                                     const float * inputs[],
+                                     const char * channel_names[],
+                                     int num_channels,
+                                     int num_samples,
+                                     int sources
+                                     );
+                                     
+        
+       
+       ////////////////////////////////////////////////////////////////
+       ///
+       /// find the depth order for samples with given channel values
+       /// does not sort the values in-place. Instead it populates
+       /// array 'order' with the desired sorting order
+       ///
+       /// the default operation sorts samples from front to back according to their Z channel
+       ///
+       /// @param order         - required output order. order[n] shall be the nth closest sample
+       /// @param inputs        - arrays of input samples, one array per channel_name
+       /// @param channel_names - array of channel names for corresponding channels
+       /// @param num_channels  - number of channels (3 or greater)  
+       /// @param num_samples   - number of samples in each array
+       /// @param sources       - number of different sources the data arises from
+       ///
+       /// the channel layout is identical to composite_pixel() 
+       ///
+       ///////////////////////////////////////////////////////////////
+                                     
+       virtual void sort(int order[],
+                         const float * inputs[],
+                         const char * channel_names[],
+                         int num_channels,
+                         int num_samples,
+                         int sources);
+};
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif
diff --git a/Source/OpenEXR/IlmImf/ImfDeepFrameBuffer.cpp b/Source/OpenEXR/IlmImf/ImfDeepFrameBuffer.cpp
new file mode 100644
index 0000000..1dfd453
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfDeepFrameBuffer.cpp
@@ -0,0 +1,230 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#include "ImfDeepFrameBuffer.h"
+#include "Iex.h"
+
+
+using namespace std;
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+DeepSlice::DeepSlice (PixelType t,
+                      char *b,
+                      size_t xst,
+                      size_t yst,
+                      size_t spst,
+                      int xsm,
+                      int ysm,
+                      double fv,
+                      bool xtc,
+                      bool ytc)
+:
+    Slice (t, b, xst, yst, xsm, ysm, fv, xtc, ytc),
+    sampleStride (spst)
+{
+    // empty
+}
+
+
+void
+DeepFrameBuffer::insert (const char name[], const DeepSlice &slice)
+{
+    if (name[0] == 0)
+    {
+        THROW (IEX_NAMESPACE::ArgExc,
+               "Frame buffer slice name cannot be an empty string.");
+    }
+
+    _map[name] = slice;
+}
+
+
+void
+DeepFrameBuffer::insert (const string &name, const DeepSlice &slice)
+{
+    insert (name.c_str(), slice);
+}
+
+
+DeepSlice &
+DeepFrameBuffer::operator [] (const char name[])
+{
+    SliceMap::iterator i = _map.find (name);
+
+    if (i == _map.end())
+    {
+        THROW (IEX_NAMESPACE::ArgExc,
+               "Cannot find frame buffer slice \"" << name << "\".");
+    }
+
+    return i->second;
+}
+
+
+const DeepSlice &
+DeepFrameBuffer::operator [] (const char name[]) const
+{
+    SliceMap::const_iterator i = _map.find (name);
+
+    if (i == _map.end())
+    {
+        THROW (IEX_NAMESPACE::ArgExc,
+               "Cannot find frame buffer slice \"" << name << "\".");
+    }
+
+    return i->second;
+}
+
+
+DeepSlice &
+DeepFrameBuffer::operator [] (const string &name)
+{
+    return this->operator[] (name.c_str());
+}
+
+
+const DeepSlice &
+DeepFrameBuffer::operator [] (const string &name) const
+{
+    return this->operator[] (name.c_str());
+}
+
+
+DeepSlice *
+DeepFrameBuffer::findSlice (const char name[])
+{
+    SliceMap::iterator i = _map.find (name);
+    return (i == _map.end())? 0: &i->second;
+}
+
+
+const DeepSlice *
+DeepFrameBuffer::findSlice (const char name[]) const
+{
+    SliceMap::const_iterator i = _map.find (name);
+    return (i == _map.end())? 0: &i->second;
+}
+
+
+DeepSlice *
+DeepFrameBuffer::findSlice (const string &name)
+{
+    return findSlice (name.c_str());
+}
+
+
+const DeepSlice *
+DeepFrameBuffer::findSlice (const string &name) const
+{
+    return findSlice (name.c_str());
+}
+
+
+DeepFrameBuffer::Iterator
+DeepFrameBuffer::begin ()
+{
+    return _map.begin();
+}
+
+
+DeepFrameBuffer::ConstIterator
+DeepFrameBuffer::begin () const
+{
+    return _map.begin();
+}
+
+
+DeepFrameBuffer::Iterator
+DeepFrameBuffer::end ()
+{
+    return _map.end();
+}
+
+
+DeepFrameBuffer::ConstIterator
+DeepFrameBuffer::end () const
+{
+    return _map.end();
+}
+
+
+DeepFrameBuffer::Iterator
+DeepFrameBuffer::find (const char name[])
+{
+    return _map.find (name);
+}
+
+
+DeepFrameBuffer::ConstIterator
+DeepFrameBuffer::find (const char name[]) const
+{
+    return _map.find (name);
+}
+
+
+DeepFrameBuffer::Iterator
+DeepFrameBuffer::find (const string &name)
+{
+    return find (name.c_str());
+}
+
+
+DeepFrameBuffer::ConstIterator
+DeepFrameBuffer::find (const string &name) const
+{
+    return find (name.c_str());
+}
+
+
+void
+DeepFrameBuffer::insertSampleCountSlice(const Slice & slice)
+{
+    if (slice.type != UINT)
+    {
+        throw IEX_NAMESPACE::ArgExc("The type of sample count slice should be UINT.");
+    }
+
+    _sampleCounts = slice;
+}
+
+
+const Slice &
+DeepFrameBuffer::getSampleCountSlice() const
+{
+    return _sampleCounts;
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfDeepFrameBuffer.h b/Source/OpenEXR/IlmImf/ImfDeepFrameBuffer.h
new file mode 100644
index 0000000..8eec6ff
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfDeepFrameBuffer.h
@@ -0,0 +1,339 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef IMFDEEPFRAMEBUFFER_H_
+#define IMFDEEPFRAMEBUFFER_H_
+
+#include "ImfFrameBuffer.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+//--------------------------------------------------------
+// Description of a single deep slice of the frame buffer:
+//--------------------------------------------------------
+
+struct IMF_EXPORT DeepSlice : public Slice
+{
+    //---------------------------------------------------------------------
+    // The stride for each sample in this slice.
+    //
+    // Memory layout:  The address of sample i in pixel (x, y) is
+    //
+    //  base + (xp / xSampling) * xStride + (yp / ySampling) * yStride
+    //       + i * sampleStride
+    //
+    // where xp and yp are computed as follows:
+    //
+    //  * If we are reading or writing a scanline-based file:
+    //
+    //      xp = x
+    //      yp = y
+    //
+    //  * If we are reading a tile whose upper left coorner is at (xt, yt):
+    //
+    //      if xTileCoords is true then xp = x - xt, else xp = x
+    //      if yTileCoords is true then yp = y - yt, else yp = y
+    //
+    //---------------------------------------------------------------------
+
+    int sampleStride;
+
+    //------------
+    // Constructor
+    //------------
+    DeepSlice (PixelType type = HALF,
+               char * base = 0,
+               size_t xStride = 0,
+               size_t yStride = 0,
+               size_t sampleStride = 0,
+               int xSampling = 1,
+               int ySampling = 1,
+               double fillValue = 0.0,
+               bool xTileCoords = false,
+               bool yTileCoords = false);
+};
+
+//-----------------
+// DeepFrameBuffer.
+//-----------------
+
+class IMF_EXPORT DeepFrameBuffer
+{
+  public:
+
+
+    //------------
+    // Add a slice
+    //------------
+
+    void                        insert (const char name[],
+                                        const DeepSlice &slice);
+
+    void                        insert (const std::string &name,
+                                        const DeepSlice &slice);
+
+    //----------------------------------------------------------------
+    // Access to existing slices:
+    //
+    // [n]              Returns a reference to the slice with name n.
+    //                  If no slice with name n exists, an IEX_NAMESPACE::ArgExc
+    //                  is thrown.
+    //
+    // findSlice(n)     Returns a pointer to the slice with name n,
+    //                  or 0 if no slice with name n exists.
+    //
+    //----------------------------------------------------------------
+
+    DeepSlice &                 operator [] (const char name[]);
+    const DeepSlice &           operator [] (const char name[]) const;
+
+    DeepSlice &                 operator [] (const std::string &name);
+    const DeepSlice &           operator [] (const std::string &name) const;
+
+    DeepSlice *                 findSlice (const char name[]);
+    const DeepSlice *           findSlice (const char name[]) const;
+
+    DeepSlice *                 findSlice (const std::string &name);
+    const DeepSlice *           findSlice (const std::string &name) const;
+
+
+    //-----------------------------------------
+    // Iterator-style access to existing slices
+    //-----------------------------------------
+
+    typedef std::map <Name, DeepSlice> SliceMap;
+
+    class Iterator;
+    class ConstIterator;
+
+    Iterator                    begin ();
+    ConstIterator               begin () const;
+
+    Iterator                    end ();
+    ConstIterator               end () const;
+
+    Iterator                    find (const char name[]);
+    ConstIterator               find (const char name[]) const;
+
+    Iterator                    find (const std::string &name);
+    ConstIterator               find (const std::string &name) const;
+
+    //----------------------------------------------------
+    // Public function for accessing a sample count slice.
+    //----------------------------------------------------
+
+    void                        insertSampleCountSlice(const Slice & slice);
+    const Slice &               getSampleCountSlice() const;
+
+  private:
+
+    SliceMap                    _map;
+    Slice                       _sampleCounts;
+};
+
+//----------
+// Iterators
+//----------
+
+class DeepFrameBuffer::Iterator
+{
+  public:
+
+    Iterator ();
+    Iterator (const DeepFrameBuffer::SliceMap::iterator &i);
+
+    Iterator &                  operator ++ ();
+    Iterator                    operator ++ (int);
+
+    const char *                name () const;
+    DeepSlice &                 slice () const;
+
+  private:
+
+    friend class DeepFrameBuffer::ConstIterator;
+
+    DeepFrameBuffer::SliceMap::iterator _i;
+};
+
+
+class DeepFrameBuffer::ConstIterator
+{
+  public:
+
+    ConstIterator ();
+    ConstIterator (const DeepFrameBuffer::SliceMap::const_iterator &i);
+    ConstIterator (const DeepFrameBuffer::Iterator &other);
+
+    ConstIterator &             operator ++ ();
+    ConstIterator               operator ++ (int);
+
+    const char *                name () const;
+    const DeepSlice &           slice () const;
+
+  private:
+
+    friend bool operator == (const ConstIterator &, const ConstIterator &);
+    friend bool operator != (const ConstIterator &, const ConstIterator &);
+
+    DeepFrameBuffer::SliceMap::const_iterator _i;
+};
+
+
+//-----------------
+// Inline Functions
+//-----------------
+
+inline
+DeepFrameBuffer::Iterator::Iterator (): _i()
+{
+    // empty
+}
+
+
+inline
+DeepFrameBuffer::Iterator::Iterator (const DeepFrameBuffer::SliceMap::iterator &i):
+    _i (i)
+{
+    // empty
+}
+
+
+inline DeepFrameBuffer::Iterator &
+DeepFrameBuffer::Iterator::operator ++ ()
+{
+    ++_i;
+    return *this;
+}
+
+
+inline DeepFrameBuffer::Iterator
+DeepFrameBuffer::Iterator::operator ++ (int)
+{
+    Iterator tmp = *this;
+    ++_i;
+    return tmp;
+}
+
+
+inline const char *
+DeepFrameBuffer::Iterator::name () const
+{
+    return *_i->first;
+}
+
+
+inline DeepSlice &
+DeepFrameBuffer::Iterator::slice () const
+{
+    return _i->second;
+}
+
+
+inline
+DeepFrameBuffer::ConstIterator::ConstIterator (): _i()
+{
+    // empty
+}
+
+inline
+DeepFrameBuffer::ConstIterator::ConstIterator
+    (const DeepFrameBuffer::SliceMap::const_iterator &i): _i (i)
+{
+    // empty
+}
+
+
+inline
+DeepFrameBuffer::ConstIterator::ConstIterator (const DeepFrameBuffer::Iterator &other):
+    _i (other._i)
+{
+    // empty
+}
+
+inline DeepFrameBuffer::ConstIterator &
+DeepFrameBuffer::ConstIterator::operator ++ ()
+{
+    ++_i;
+    return *this;
+}
+
+
+inline DeepFrameBuffer::ConstIterator
+DeepFrameBuffer::ConstIterator::operator ++ (int)
+{
+    ConstIterator tmp = *this;
+    ++_i;
+    return tmp;
+}
+
+
+inline const char *
+DeepFrameBuffer::ConstIterator::name () const
+{
+    return *_i->first;
+}
+
+inline const DeepSlice &
+DeepFrameBuffer::ConstIterator::slice () const
+{
+    return _i->second;
+}
+
+
+inline bool
+operator == (const DeepFrameBuffer::ConstIterator &x,
+             const DeepFrameBuffer::ConstIterator &y)
+{
+    return x._i == y._i;
+}
+
+
+inline bool
+operator != (const DeepFrameBuffer::ConstIterator &x,
+             const DeepFrameBuffer::ConstIterator &y)
+{
+    return !(x == y);
+}
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
+
+
+
+#endif /* IMFDEEPFRAMEBUFFER_H_ */
diff --git a/Source/OpenEXR/IlmImf/ImfDeepImageState.h b/Source/OpenEXR/IlmImf/ImfDeepImageState.h
new file mode 100644
index 0000000..a3941c4
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfDeepImageState.h
@@ -0,0 +1,96 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2013, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission. 
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+#ifndef INCLUDED_IMF_DEEPIMAGESTATE_H
+#define INCLUDED_IMF_DEEPIMAGESTATE_H
+
+//-----------------------------------------------------------------------------
+//
+//      enum DeepImageState -- describes how orderly the pixel data
+//      in a deep image are
+//
+//      The samples in a deep image pixel may be sorted according to
+//      depth, and the sample depths or depth ranges may or may not
+//      overlap each other.  A pixel is
+//
+//          - SORTED if for every i and j with i < j
+//
+//              (Z[i] < Z[j]) || (Z[i] == Z[j] && ZBack[i] < ZBack[j]),
+//
+//          - NON_OVERLAPPING if for every i and j with i != j
+//
+//              (Z[i] <  Z[j] && ZBack[i] <= Z[j]) ||
+//              (Z[j] <  Z[i] && ZBack[j] <= Z[i]) ||
+//              (Z[i] == Z[j] && ZBack[i] <= Z[i] & ZBack[j] > Z[j]) ||
+//              (Z[i] == Z[j] && ZBack[j] <= Z[j] & ZBack[i] > Z[i]),
+//
+//          - TIDY if it is SORTED and NON_OVERLAPPING,
+//
+//          - MESSY if it is neither SORTED nor NON_OVERLAPPING.
+//
+//      A deep image is
+//
+//          - MESSY if at least one of its pixels is MESSY,
+//          - SORTED if all of its pixels are SORTED,
+//          - NON_OVERLAPPING if all of its pixels are NON_OVERLAPPING,
+//          - TIDY if all of its pixels are TIDY.
+//
+//      Note: the rather complicated definition of NON_OVERLAPPING prohibits
+//      overlapping volume samples, coincident point samples and point samples
+//      in the middle of a volume sample, but it does allow point samples at
+//      the front or back of a volume sample.
+//
+//-----------------------------------------------------------------------------
+
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+enum DeepImageState
+{
+    DIS_MESSY = 0,
+    DIS_SORTED = 1,
+    DIS_NON_OVERLAPPING = 2,
+    DIS_TIDY = 3,
+
+    DIS_NUMSTATES   // Number of different image states
+};
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+#endif
diff --git a/Source/OpenEXR/IlmImf/ImfDeepImageStateAttribute.cpp b/Source/OpenEXR/IlmImf/ImfDeepImageStateAttribute.cpp
new file mode 100644
index 0000000..86a70a6
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfDeepImageStateAttribute.cpp
@@ -0,0 +1,78 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2013, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission. 
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+//-----------------------------------------------------------------------------
+//
+//	class DeepImageStateAttribute
+//
+//-----------------------------------------------------------------------------
+
+#include <ImfDeepImageStateAttribute.h>
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;
+
+template <>
+const char *
+DeepImageStateAttribute::staticTypeName ()
+{
+    return "deepImageState";
+}
+
+
+template <>
+void
+DeepImageStateAttribute::writeValueTo
+    (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
+{
+    unsigned char tmp = _value;
+    Xdr::write <StreamIO> (os, tmp);
+}
+
+
+template <>
+void
+DeepImageStateAttribute::readValueFrom
+    (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
+{
+    unsigned char tmp;
+    Xdr::read <StreamIO> (is, tmp);
+    _value = DeepImageState (tmp);
+}
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT 
diff --git a/Source/OpenEXR/IlmImf/ImfDeepImageStateAttribute.h b/Source/OpenEXR/IlmImf/ImfDeepImageStateAttribute.h
new file mode 100644
index 0000000..6174e94
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfDeepImageStateAttribute.h
@@ -0,0 +1,68 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2013, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission. 
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef INCLUDED_IMF_DEEPIMAGESTATE_ATTRIBUTE_H
+#define INCLUDED_IMF_DEEPIMAGESTATE_ATTRIBUTE_H
+
+
+//-----------------------------------------------------------------------------
+//
+//	class DeepImageStateAttribute
+//
+//-----------------------------------------------------------------------------
+
+#include "ImfAttribute.h"
+#include "ImfDeepImageState.h"
+#include "ImfExport.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+
+typedef TypedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::DeepImageState>
+    DeepImageStateAttribute;
+
+template <> IMF_EXPORT const char *DeepImageStateAttribute::staticTypeName ();
+
+template <> IMF_EXPORT
+void DeepImageStateAttribute::writeValueTo
+    (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &, int) const;
+
+template <> IMF_EXPORT
+void DeepImageStateAttribute::readValueFrom
+    (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &, int, int);
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif
diff --git a/Source/OpenEXR/IlmImf/ImfDeepScanLineInputFile.cpp b/Source/OpenEXR/IlmImf/ImfDeepScanLineInputFile.cpp
new file mode 100644
index 0000000..8a7002b
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfDeepScanLineInputFile.cpp
@@ -0,0 +1,2025 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+//-----------------------------------------------------------------------------
+//
+//      class DeepScanLineInputFile
+//
+//-----------------------------------------------------------------------------
+
+#include <ImfDeepScanLineInputFile.h>
+#include <ImfChannelList.h>
+#include <ImfMisc.h>
+#include <ImfStdIO.h>
+#include <ImfCompressor.h>
+#include <ImfXdr.h>
+#include <ImfConvert.h>
+#include <ImfThreading.h>
+#include <ImfPartType.h>
+#include <ImfVersion.h>
+#include "ImfMultiPartInputFile.h"
+#include "ImfDeepFrameBuffer.h"
+#include "ImfInputStreamMutex.h"
+#include "ImfInputPartData.h"
+
+
+#include "ImathBox.h"
+#include "ImathFun.h"
+
+
+#include "IlmThreadPool.h"
+#include "IlmThreadSemaphore.h"
+#include "IlmThreadMutex.h"
+
+#include "Iex.h"
+
+#include <string>
+#include <vector>
+#include <assert.h>
+#include <limits>
+#include <algorithm>
+
+
+#include "ImfNamespace.h"
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+using IMATH_NAMESPACE::Box2i;
+using IMATH_NAMESPACE::divp;
+using IMATH_NAMESPACE::modp;
+using std::string;
+using std::vector;
+using std::ifstream;
+using std::min;
+using std::max;
+using ILMTHREAD_NAMESPACE::Mutex;
+using ILMTHREAD_NAMESPACE::Lock;
+using ILMTHREAD_NAMESPACE::Semaphore;
+using ILMTHREAD_NAMESPACE::Task;
+using ILMTHREAD_NAMESPACE::TaskGroup;
+using ILMTHREAD_NAMESPACE::ThreadPool;
+
+namespace {
+
+struct InSliceInfo
+{
+    PixelType           typeInFrameBuffer;
+    PixelType           typeInFile;
+    char *              base;
+    char*               pointerArrayBase;
+    size_t              xPointerStride;
+    size_t              yPointerStride;
+    size_t              sampleStride;
+    int                 xSampling;
+    int                 ySampling;
+    bool                fill;
+    bool                skip;
+    double              fillValue;
+
+    InSliceInfo (PixelType typeInFrameBuffer = HALF,
+                 char * base = NULL,
+                 PixelType typeInFile = HALF,
+                 size_t xPointerStride = 0,
+                 size_t yPointerStride = 0,
+                 size_t sampleStride = 0,
+                 int xSampling = 1,
+                 int ySampling = 1,
+                 bool fill = false,
+                 bool skip = false,
+                 double fillValue = 0.0);
+};
+
+
+InSliceInfo::InSliceInfo (PixelType tifb,
+                          char * b,
+                          PixelType tifl,
+                          size_t xpst,
+                          size_t ypst,
+                          size_t spst,
+                          int xsm, int ysm,
+                          bool f, bool s,
+                          double fv)
+:
+    typeInFrameBuffer (tifb),
+    typeInFile (tifl),
+    base(b),
+    xPointerStride (xpst),
+    yPointerStride (ypst),
+    sampleStride (spst),
+    xSampling (xsm),
+    ySampling (ysm),
+    fill (f),
+    skip (s),
+    fillValue (fv)
+{
+    // empty
+}
+
+
+struct LineBuffer
+{
+    const char *        uncompressedData;
+    char *              buffer;
+    Int64               packedDataSize;
+    Int64               unpackedDataSize;
+
+    int                 minY;
+    int                 maxY;
+    Compressor *        compressor;
+    Compressor::Format  format;
+    int                 number;
+    bool                hasException;
+    string              exception;
+
+    LineBuffer ();
+    ~LineBuffer ();
+
+    inline void         wait () {_sem.wait();}
+    inline void         post () {_sem.post();}
+
+  private:
+
+    Semaphore           _sem;
+};
+
+
+LineBuffer::LineBuffer ():
+    uncompressedData (0),
+    buffer (0),
+    packedDataSize (0),
+    compressor (0),
+    format (defaultFormat(compressor)),
+    number (-1),
+    hasException (false),
+    exception (),
+    _sem (1)
+{
+    // empty
+}
+
+
+LineBuffer::~LineBuffer ()
+{
+    if (compressor != 0)
+        delete compressor;
+}
+
+} // namespace
+
+
+struct DeepScanLineInputFile::Data: public Mutex
+{
+    Header                      header;             // the image header
+    int                         version;            // file's version
+    DeepFrameBuffer             frameBuffer;        // framebuffer to write into
+    LineOrder                   lineOrder;          // order of the scanlines in file
+    int                         minX;               // data window's min x coord
+    int                         maxX;               // data window's max x coord
+    int                         minY;               // data window's min y coord
+    int                         maxY;               // data window's max x coord
+    vector<Int64>               lineOffsets;        // stores offsets in file for
+                                                    // each line
+    bool                        fileIsComplete;     // True if no scanlines are missing
+                                                    // in the file
+    int                         nextLineBufferMinY; // minimum y of the next linebuffer
+    vector<size_t>              bytesPerLine;       // combined size of a line over all
+                                                    // channels
+    vector<size_t>              offsetInLineBuffer; // offset for each scanline in its
+                                                    // linebuffer
+    vector<InSliceInfo*>        slices;             // info about channels in file
+
+    vector<LineBuffer*>         lineBuffers;        // each holds one line buffer
+    int                         linesInBuffer;      // number of scanlines each buffer
+                                                    // holds
+    int                         partNumber;         // part number
+    int                         numThreads;         // number of threads
+    
+    bool                        multiPartBackwardSupport;       // if we are reading a multipart file using single file API
+    MultiPartInputFile*         multiPartFile;      // for multipart files opened as single part
+    bool                        memoryMapped;       // if the stream is memory mapped
+
+    Array2D<unsigned int>       sampleCount;        // the number of samples
+                                                    // in each pixel
+
+    Array<unsigned int>         lineSampleCount;    // the number of samples
+                                                    // in each line
+
+    Array<bool>                 gotSampleCount;     // for each scanline, indicating if
+                                                    // we have got its sample count table
+
+    char*                       sampleCountSliceBase; // pointer to the start of
+                                                      // the sample count array
+    int                         sampleCountXStride; // x stride of the sample count array
+    int                         sampleCountYStride; // y stride of the sample count array
+    bool                        frameBufferValid;   // set by setFrameBuffer: excepts if readPixelSampleCounts if false
+
+    Array<char>                 sampleCountTableBuffer;
+                                                    // the buffer for sample count table
+
+    Compressor*                 sampleCountTableComp;
+                                                    // the decompressor for sample count table
+
+    int                         combinedSampleSize; // total size of all channels combined: used to sanity check sample table size
+
+    int                         maxSampleCountTableSize;
+                                                    // the max size in bytes for a pixel
+                                                    // sample count table
+    InputStreamMutex*   _streamData;
+    bool                _deleteStream;
+                                                    
+
+    Data (int numThreads);
+    ~Data ();
+
+    inline LineBuffer * getLineBuffer (int number); // hash function from line
+                                                    // buffer indices into our
+                                                    // vector of line buffers
+};
+
+
+DeepScanLineInputFile::Data::Data (int numThreads):
+        partNumber(-1),
+        numThreads(numThreads),
+        multiPartBackwardSupport(false),
+        multiPartFile(NULL),
+        memoryMapped(false),
+        frameBufferValid(false),
+        _streamData(NULL),
+        _deleteStream(false)
+{
+    //
+    // We need at least one lineBuffer, but if threading is used,
+    // to keep n threads busy we need 2*n lineBuffers
+    //
+
+    lineBuffers.resize (max (1, 2 * numThreads));
+
+    for (size_t i = 0; i < lineBuffers.size(); i++)
+        lineBuffers[i] = 0;
+
+    sampleCountTableComp = 0;
+}
+
+
+DeepScanLineInputFile::Data::~Data ()
+{
+    for (size_t i = 0; i < lineBuffers.size(); i++)
+        if (lineBuffers[i] != 0)
+            delete lineBuffers[i];
+
+    for (size_t i = 0; i < slices.size(); i++)
+        delete slices[i];
+
+    if (sampleCountTableComp != 0)
+        delete sampleCountTableComp;
+    
+    if (multiPartBackwardSupport)
+        delete multiPartFile;
+}
+
+
+inline LineBuffer *
+DeepScanLineInputFile::Data::getLineBuffer (int lineBufferNumber)
+{
+    return lineBuffers[lineBufferNumber % lineBuffers.size()];
+}
+
+
+namespace {
+
+
+void
+reconstructLineOffsets (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
+                        LineOrder lineOrder,
+                        vector<Int64> &lineOffsets)
+{
+    Int64 position = is.tellg();
+
+    try
+    {
+        for (unsigned int i = 0; i < lineOffsets.size(); i++)
+        {
+            Int64 lineOffset = is.tellg();
+
+            int y;
+            OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, y);
+            
+            Int64 packed_offset;
+            Int64 packed_sample;
+            OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, packed_offset);
+            OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, packed_sample);
+            //next is unpacked sample table size - skip this too
+            Xdr::skip <StreamIO> (is, packed_offset+packed_sample+8);
+
+            if (lineOrder == INCREASING_Y)
+                lineOffsets[i] = lineOffset;
+            else
+                lineOffsets[lineOffsets.size() - i - 1] = lineOffset;
+        }
+    }
+    catch (...)
+    {
+        //
+        // Suppress all exceptions.  This functions is
+        // called only to reconstruct the line offset
+        // table for incomplete files, and exceptions
+        // are likely.
+        //
+    }
+
+    is.clear();
+    is.seekg (position);
+}
+
+
+void
+readLineOffsets (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
+                 LineOrder lineOrder,
+                 vector<Int64> &lineOffsets,
+                 bool &complete)
+{
+    for (unsigned int i = 0; i < lineOffsets.size(); i++)
+    {
+        OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, lineOffsets[i]);
+    }
+
+    complete = true;
+
+    for (unsigned int i = 0; i < lineOffsets.size(); i++)
+    {
+        if (lineOffsets[i] <= 0)
+        {
+            //
+            // Invalid data in the line offset table mean that
+            // the file is probably incomplete (the table is
+            // the last thing written to the file).  Either
+            // some process is still busy writing the file,
+            // or writing the file was aborted.
+            //
+            // We should still be able to read the existing
+            // parts of the file.  In order to do this, we
+            // have to make a sequential scan over the scan
+            // line data to reconstruct the line offset table.
+            //
+
+            complete = false;
+            reconstructLineOffsets (is, lineOrder, lineOffsets);
+            break;
+        }
+    }
+}
+
+
+void
+readPixelData (InputStreamMutex *streamData,
+               DeepScanLineInputFile::Data *ifd,
+               int minY,
+               char *&buffer,
+               Int64 &packedDataSize,
+               Int64 &unpackedDataSize)
+{
+    //
+    // Read a single line buffer from the input file.
+    //
+    // If the input file is not memory-mapped, we copy the pixel data into
+    // into the array pointed to by buffer.  If the file is memory-mapped,
+    // then we change where buffer points to instead of writing into the
+    // array (hence buffer needs to be a reference to a char *).
+    //
+
+    int lineBufferNumber = (minY - ifd->minY) / ifd->linesInBuffer;
+
+    Int64 lineOffset = ifd->lineOffsets[lineBufferNumber];
+
+    if (lineOffset == 0)
+        THROW (IEX_NAMESPACE::InputExc, "Scan line " << minY << " is missing.");
+
+    //
+    // Seek to the start of the scan line in the file,
+    // if necessary.
+    //
+
+    if (!isMultiPart(ifd->version))
+    {
+        if (ifd->nextLineBufferMinY != minY)
+            streamData->is->seekg (lineOffset);
+    }
+    else
+    {
+        //
+        // In a multi-part file, the file pointer may have been moved by
+        // other parts, so we have to ask tellg() where we are.
+        //
+        if (streamData->is->tellg() != ifd->lineOffsets[lineBufferNumber])
+            streamData->is->seekg (lineOffset);
+    }
+
+    //
+    // Read the data block's header.
+    //
+
+    int yInFile;
+
+    //
+    // Read the part number when we are dealing with a multi-part file.
+    //
+
+    if (isMultiPart(ifd->version))
+    {
+        int partNumber;
+        OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*streamData->is, partNumber);
+        if (partNumber != ifd->partNumber)
+        {
+            THROW (IEX_NAMESPACE::ArgExc, "Unexpected part number " << partNumber
+                   << ", should be " << ifd->partNumber << ".");
+        }
+    }
+
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*streamData->is, yInFile);
+
+    if (yInFile != minY)
+        throw IEX_NAMESPACE::InputExc ("Unexpected data block y coordinate.");
+
+    Int64 sampleCountTableSize;
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*streamData->is, sampleCountTableSize);
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*streamData->is, packedDataSize);
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*streamData->is, unpackedDataSize);
+
+
+    //
+    // We make a check on the data size requirements here.
+    // Whilst we wish to store 64bit sizes on disk, not all the compressors
+    // have been made to work with such data sizes and are still limited to
+    // using signed 32 bit (int) for the data size. As such, this version
+    // insists that we validate that the data size does not exceed the data
+    // type max limit.
+    // @TODO refactor the compressor code to ensure full 64-bit support.
+    //
+
+    int compressorMaxDataSize = std::numeric_limits<int>::max();
+    if (packedDataSize   > Int64(compressorMaxDataSize) ||
+        unpackedDataSize > Int64(compressorMaxDataSize))
+    {
+        THROW (IEX_NAMESPACE::ArgExc, "This version of the library does not support "
+              << "the allocation of data with size  > " << compressorMaxDataSize
+              << " file unpacked size :" << unpackedDataSize
+              << " file packed size   :" << packedDataSize << ".\n");
+    }
+
+    //
+    // Skip the pixel sample count table because we have read this data.
+    //
+
+    Xdr::skip <StreamIO> (*streamData->is, sampleCountTableSize);
+
+    //
+    // Read the pixel data.
+    //
+
+    if (streamData->is->isMemoryMapped ())
+        buffer = streamData->is->readMemoryMapped (packedDataSize);
+    else
+    {
+        // (TODO) check if the packed data size is too big?
+        // (TODO) better memory management. Don't delete buffer all the time.
+        if (buffer != 0) delete[] buffer;
+        buffer = new char[packedDataSize];
+        streamData->is->read (buffer, packedDataSize);
+    }
+
+    //
+    // Keep track of which scan line is the next one in
+    // the file, so that we can avoid redundant seekg()
+    // operations (seekg() can be fairly expensive).
+    //
+
+    if (ifd->lineOrder == INCREASING_Y)
+        ifd->nextLineBufferMinY = minY + ifd->linesInBuffer;
+    else
+        ifd->nextLineBufferMinY = minY - ifd->linesInBuffer;
+}
+
+//
+// A LineBufferTask encapsulates the task uncompressing a set of
+// scanlines (line buffer) and copying them into the frame buffer.
+//
+
+class LineBufferTask : public Task
+{
+  public:
+
+    LineBufferTask (TaskGroup *group,
+                    DeepScanLineInputFile::Data *ifd,
+                    LineBuffer *lineBuffer,
+                    int scanLineMin,
+                    int scanLineMax);
+
+    virtual ~LineBufferTask ();
+
+    virtual void                execute ();
+
+  private:
+
+    DeepScanLineInputFile::Data *   _ifd;
+    LineBuffer *                _lineBuffer;
+    int                         _scanLineMin;
+    int                         _scanLineMax;
+};
+
+
+LineBufferTask::LineBufferTask
+    (TaskGroup *group,
+     DeepScanLineInputFile::Data *ifd,
+     LineBuffer *lineBuffer,
+     int scanLineMin,
+     int scanLineMax)
+:
+    Task (group),
+    _ifd (ifd),
+    _lineBuffer (lineBuffer),
+    _scanLineMin (scanLineMin),
+    _scanLineMax (scanLineMax)
+{
+    // empty
+}
+
+
+LineBufferTask::~LineBufferTask ()
+{
+    //
+    // Signal that the line buffer is now free
+    //
+
+    _lineBuffer->post ();
+}
+
+
+void
+LineBufferTask::execute ()
+{
+    try
+    {
+        //
+        // Uncompress the data, if necessary
+        //
+
+        if (_lineBuffer->uncompressedData == 0)
+        {
+            Int64 uncompressedSize = 0;
+            int maxY = min (_lineBuffer->maxY, _ifd->maxY);
+
+            for (int i = _lineBuffer->minY - _ifd->minY;
+                 i <= maxY - _ifd->minY;
+                 ++i)
+            {
+                uncompressedSize += (int) _ifd->bytesPerLine[i];
+            }
+
+            //
+            // Create the compressor everytime when we want to use it,
+            // because we don't know maxBytesPerLine beforehand.
+            // (TODO) optimize this. don't do this every time.
+            //
+
+            if (_lineBuffer->compressor != 0)
+                delete _lineBuffer->compressor;
+            Int64 maxBytesPerLine = 0;
+            for (int i = _lineBuffer->minY - _ifd->minY;
+                 i <= maxY - _ifd->minY;
+                 ++i)
+            {
+                if (_ifd->bytesPerLine[i] > maxBytesPerLine)
+                    maxBytesPerLine = _ifd->bytesPerLine[i];
+            }
+            _lineBuffer->compressor = newCompressor(_ifd->header.compression(),
+                                                    maxBytesPerLine,
+                                                    _ifd->header);
+
+            if (_lineBuffer->compressor &&
+                _lineBuffer->packedDataSize < uncompressedSize)
+            {
+                _lineBuffer->format = _lineBuffer->compressor->format();
+
+                _lineBuffer->packedDataSize = _lineBuffer->compressor->uncompress
+                    (_lineBuffer->buffer, _lineBuffer->packedDataSize,
+                     _lineBuffer->minY, _lineBuffer->uncompressedData);
+            }
+            else
+            {
+                //
+                // If the line is uncompressed, it's in XDR format,
+                // regardless of the compressor's output format.
+                //
+
+                _lineBuffer->format = Compressor::XDR;
+                _lineBuffer->uncompressedData = _lineBuffer->buffer;
+            }
+        }
+
+        int yStart, yStop, dy;
+
+        if (_ifd->lineOrder == INCREASING_Y)
+        {
+            yStart = _scanLineMin;
+            yStop = _scanLineMax + 1;
+            dy = 1;
+        }
+        else
+        {
+            yStart = _scanLineMax;
+            yStop = _scanLineMin - 1;
+            dy = -1;
+        }
+
+        for (int y = yStart; y != yStop; y += dy)
+        {
+            //
+            // Convert one scan line's worth of pixel data back
+            // from the machine-independent representation, and
+            // store the result in the frame buffer.
+            //
+
+            const char *readPtr = _lineBuffer->uncompressedData +
+                                  _ifd->offsetInLineBuffer[y - _ifd->minY];
+
+            //
+            // Iterate over all image channels.
+            //
+
+            for (unsigned int i = 0; i < _ifd->slices.size(); ++i)
+            {
+                //
+                // Test if scan line y of this channel contains any data
+                // (the scan line contains data only if y % ySampling == 0).
+                //
+
+                InSliceInfo &slice = *_ifd->slices[i];
+
+                if (modp (y, slice.ySampling) != 0)
+                    continue;
+
+                //
+                // Find the x coordinates of the leftmost and rightmost
+                // sampled pixels (i.e. pixels within the data window
+                // for which x % xSampling == 0).
+                //
+
+                //
+                // Fill the frame buffer with pixel data.
+                //
+
+                if (slice.skip)
+                {
+                    //
+                    // The file contains data for this channel, but
+                    // the frame buffer contains no slice for this channel.
+                    //
+
+                    skipChannel (readPtr, slice.typeInFile,
+                                 _ifd->lineSampleCount[y - _ifd->minY]);
+                }
+                else
+                {
+                    //
+                    // The frame buffer contains a slice for this channel.
+                    //
+
+                    int width = (_ifd->maxX - _ifd->minX + 1);
+
+                    copyIntoDeepFrameBuffer (readPtr, slice.base,
+                                             (char*) (&_ifd->sampleCount[0][0]
+                                                      - _ifd->minX
+                                                      - _ifd->minY * width),
+                                             sizeof(unsigned int) * 1,
+                                             sizeof(unsigned int) * width,
+                                             y, _ifd->minX, _ifd->maxX,
+                                             0, 0,
+                                             0, 0,
+                                             slice.sampleStride, 
+                                             slice.xPointerStride,
+                                             slice.yPointerStride,
+                                             slice.fill,
+                                             slice.fillValue, _lineBuffer->format,
+                                             slice.typeInFrameBuffer,
+                                             slice.typeInFile);
+                }
+            }
+        }
+    }
+    catch (std::exception &e)
+    {
+        if (!_lineBuffer->hasException)
+        {
+            _lineBuffer->exception = e.what();
+            _lineBuffer->hasException = true;
+        }
+    }
+    catch (...)
+    {
+        if (!_lineBuffer->hasException)
+        {
+            _lineBuffer->exception = "unrecognized exception";
+            _lineBuffer->hasException = true;
+        }
+    }
+}
+
+
+LineBufferTask *
+newLineBufferTask
+    (TaskGroup *group,
+     DeepScanLineInputFile::Data *ifd,
+     int number,
+     int scanLineMin,
+     int scanLineMax)
+{
+    //
+    // Wait for a line buffer to become available, fill the line
+    // buffer with raw data from the file if necessary, and create
+    // a new LineBufferTask whose execute() method will uncompress
+    // the contents of the buffer and copy the pixels into the
+    // frame buffer.
+    //
+
+    LineBuffer *lineBuffer = ifd->getLineBuffer (number);
+
+    try
+    {
+        lineBuffer->wait ();
+
+        if (lineBuffer->number != number)
+        {
+            lineBuffer->minY = ifd->minY + number * ifd->linesInBuffer;
+            lineBuffer->maxY = lineBuffer->minY + ifd->linesInBuffer - 1;
+
+            lineBuffer->number = number;
+            lineBuffer->uncompressedData = 0;
+
+            readPixelData (ifd->_streamData, ifd, lineBuffer->minY,
+                           lineBuffer->buffer,
+                           lineBuffer->packedDataSize,
+                           lineBuffer->unpackedDataSize);
+        }
+    }
+    catch (std::exception &e)
+    {
+        if (!lineBuffer->hasException)
+        {
+            lineBuffer->exception = e.what();
+            lineBuffer->hasException = true;
+        }
+        lineBuffer->number = -1;
+        lineBuffer->post();
+        throw;
+    }
+    catch (...)
+    {
+        //
+        // Reading from the file caused an exception.
+        // Signal that the line buffer is free, and
+        // re-throw the exception.
+        //
+
+        lineBuffer->exception = "unrecognized exception";
+        lineBuffer->hasException = true;
+        lineBuffer->number = -1;
+        lineBuffer->post();
+        throw;
+    }
+
+    scanLineMin = max (lineBuffer->minY, scanLineMin);
+    scanLineMax = min (lineBuffer->maxY, scanLineMax);
+
+    return new LineBufferTask (group, ifd, lineBuffer,
+                               scanLineMin, scanLineMax);
+}
+
+} // namespace
+
+
+void DeepScanLineInputFile::initialize(const Header& header)
+{
+    try
+    {
+        if (header.type() != DEEPSCANLINE)
+            throw IEX_NAMESPACE::ArgExc("Can't build a DeepScanLineInputFile from "
+            "a type-mismatched part.");
+        
+        if(header.version()!=1)
+        {
+            THROW(IEX_NAMESPACE::ArgExc, "Version " << header.version() << " not supported for deepscanline images in this version of the library");
+        }
+        
+        _data->header = header;
+
+        _data->lineOrder = _data->header.lineOrder();
+
+        const Box2i &dataWindow = _data->header.dataWindow();
+
+        _data->minX = dataWindow.min.x;
+        _data->maxX = dataWindow.max.x;
+        _data->minY = dataWindow.min.y;
+        _data->maxY = dataWindow.max.y;
+
+        _data->sampleCount.resizeErase(_data->maxY - _data->minY + 1,
+                                       _data->maxX - _data->minX + 1);
+        _data->lineSampleCount.resizeErase(_data->maxY - _data->minY + 1);
+
+        Compressor* compressor = newCompressor(_data->header.compression(),
+                                               0,
+                                               _data->header);
+
+        _data->linesInBuffer = numLinesInBuffer (compressor);
+
+        delete compressor;
+
+        _data->nextLineBufferMinY = _data->minY - 1;
+
+        int lineOffsetSize = (dataWindow.max.y - dataWindow.min.y +
+                              _data->linesInBuffer) / _data->linesInBuffer;
+
+        _data->lineOffsets.resize (lineOffsetSize);
+
+        for (size_t i = 0; i < _data->lineBuffers.size(); i++)
+            _data->lineBuffers[i] = new LineBuffer ();
+
+        _data->gotSampleCount.resizeErase(_data->maxY - _data->minY + 1);
+        for (int i = 0; i < _data->maxY - _data->minY + 1; i++)
+            _data->gotSampleCount[i] = false;
+
+        _data->maxSampleCountTableSize = min(_data->linesInBuffer, _data->maxY - _data->minY + 1) *
+                                        (_data->maxX - _data->minX + 1) *
+                                        sizeof(unsigned int);
+
+        _data->sampleCountTableBuffer.resizeErase(_data->maxSampleCountTableSize);
+
+        _data->sampleCountTableComp = newCompressor(_data->header.compression(),
+                                                    _data->maxSampleCountTableSize,
+                                                    _data->header);
+
+        _data->bytesPerLine.resize (_data->maxY - _data->minY + 1);
+        
+        const ChannelList & c=header.channels();
+        
+        _data->combinedSampleSize=0;
+        for(ChannelList::ConstIterator i=c.begin();i!=c.end();i++)
+        {
+            switch(i.channel().type)
+            {
+                case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF  :
+                    _data->combinedSampleSize+=Xdr::size<half>();
+                    break;
+                case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT :
+                    _data->combinedSampleSize+=Xdr::size<float>();
+                    break;
+                case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT  :
+                    _data->combinedSampleSize+=Xdr::size<unsigned int>();
+                    break;
+                default :
+                    THROW(IEX_NAMESPACE::ArgExc, "Bad type for channel " << i.name() << " initializing deepscanline reader");
+                    
+            }
+        }
+        
+    }
+    catch (...)
+    {
+        delete _data;
+        _data=NULL;
+        throw;
+    }
+}
+
+
+DeepScanLineInputFile::DeepScanLineInputFile(InputPartData* part)
+    
+{
+
+    _data = new Data(part->numThreads);
+    _data->_deleteStream=false;
+    _data->_streamData = part->mutex;
+    _data->memoryMapped = _data->_streamData->is->isMemoryMapped();
+    _data->version = part->version;
+
+    initialize(part->header);
+
+    _data->lineOffsets = part->chunkOffsets;
+
+    _data->partNumber = part->partNumber;
+}
+
+
+DeepScanLineInputFile::DeepScanLineInputFile
+    (const char fileName[], int numThreads)
+:
+     _data (new Data (numThreads))
+{
+    _data->_streamData = new InputStreamMutex();
+    _data->_deleteStream = true;
+    OPENEXR_IMF_INTERNAL_NAMESPACE::IStream* is = 0;
+
+    try
+    {
+        is = new StdIFStream (fileName);
+        readMagicNumberAndVersionField(*is, _data->version);
+        //
+        // Backward compatibility to read multpart file.
+        //
+        if (isMultiPart(_data->version))
+        {
+            compatibilityInitialize(*is);
+            return;
+        }
+        _data->_streamData->is = is;
+        _data->memoryMapped = is->isMemoryMapped();
+        _data->header.readFrom (*_data->_streamData->is, _data->version);
+        _data->header.sanityCheck (isTiled (_data->version));
+
+        initialize(_data->header);
+
+        readLineOffsets (*_data->_streamData->is,
+                         _data->lineOrder,
+                         _data->lineOffsets,
+                         _data->fileIsComplete);
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        if (is)          delete is;
+        if (_data && _data->_streamData) delete _data->_streamData;
+        if (_data)       delete _data;
+
+        REPLACE_EXC (e, "Cannot read image file "
+                        "\"" << fileName << "\". " << e);
+        throw;
+    }
+    catch (...)
+    {
+        if (is)          delete is;
+        if (_data && _data->_streamData) delete _data->_streamData;
+        if (_data)       delete _data;
+
+        throw;
+    }
+}
+
+
+DeepScanLineInputFile::DeepScanLineInputFile
+    (const Header &header,
+     OPENEXR_IMF_INTERNAL_NAMESPACE::IStream *is,
+     int version,
+     int numThreads)
+:
+    _data (new Data (numThreads))
+{
+    _data->_streamData=new InputStreamMutex();
+    _data->_deleteStream=false;
+    _data->_streamData->is = is;
+    
+    _data->memoryMapped = is->isMemoryMapped();
+
+    _data->version =version;
+    
+    initialize (header);
+
+    readLineOffsets (*_data->_streamData->is,
+                     _data->lineOrder,
+                     _data->lineOffsets,
+                     _data->fileIsComplete);
+}
+
+
+DeepScanLineInputFile::~DeepScanLineInputFile ()
+{
+    if (_data->_deleteStream)
+        delete _data->_streamData->is;
+
+    if (_data)
+    {
+        if (!_data->memoryMapped)
+            for (size_t i = 0; i < _data->lineBuffers.size(); i++)
+                delete [] _data->lineBuffers[i]->buffer;
+
+        //
+        // Unless this file was opened via the multipart API, delete the streamdata
+        // object too.
+        // (TODO) it should be "isMultiPart(data->version)", but when there is only
+        // single part,
+        // (see the above constructor) the version field is not set.
+        //
+        // (TODO) we should have a way to tell if the stream data is owned by this
+        // file or by a parent multipart file.
+        //
+
+        if (_data->partNumber == -1 && _data->_streamData)
+            delete _data->_streamData;
+
+        delete _data;
+    }
+}
+
+void
+DeepScanLineInputFile::compatibilityInitialize(OPENEXR_IMF_INTERNAL_NAMESPACE::IStream& is)
+{
+    is.seekg(0);
+    //
+    // Construct a MultiPartInputFile, initialize TiledInputFile
+    // with the part 0 data.
+    // (TODO) maybe change the third parameter of the constructor of MultiPartInputFile later.
+    //
+    _data->multiPartBackwardSupport = true;
+    _data->multiPartFile = new MultiPartInputFile(is, _data->numThreads);
+    InputPartData* part = _data->multiPartFile->getPart(0);
+    
+    multiPartInitialize(part);
+}
+
+void DeepScanLineInputFile::multiPartInitialize(InputPartData* part)
+{
+    
+    _data->_streamData = part->mutex;
+    _data->memoryMapped = _data->_streamData->is->isMemoryMapped();
+    _data->version = part->version;
+    
+    initialize(part->header);
+    
+    _data->lineOffsets = part->chunkOffsets;
+    
+    _data->partNumber = part->partNumber;
+    
+}
+
+
+const char *
+DeepScanLineInputFile::fileName () const
+{
+    return _data->_streamData->is->fileName();
+}
+
+
+const Header &
+DeepScanLineInputFile::header () const
+{
+    return _data->header;
+}
+
+
+int
+DeepScanLineInputFile::version () const
+{
+    return _data->version;
+}
+
+
+void
+DeepScanLineInputFile::setFrameBuffer (const DeepFrameBuffer &frameBuffer)
+{
+    Lock lock (*_data->_streamData);
+
+    
+    //
+    // Check if the new frame buffer descriptor is
+    // compatible with the image file header.
+    //
+
+    const ChannelList &channels = _data->header.channels();
+
+    for (DeepFrameBuffer::ConstIterator j = frameBuffer.begin();
+         j != frameBuffer.end();
+         ++j)
+    {
+        ChannelList::ConstIterator i = channels.find (j.name());
+
+        if (i == channels.end())
+            continue;
+
+        if (i.channel().xSampling != j.slice().xSampling ||
+            i.channel().ySampling != j.slice().ySampling)
+            THROW (IEX_NAMESPACE::ArgExc, "X and/or y subsampling factors "
+                                "of \"" << i.name() << "\" channel "
+                                "of input file \"" << fileName() << "\" are "
+                                "not compatible with the frame buffer's "
+                                "subsampling factors.");
+    }
+
+    //
+    // Store the pixel sample count table.
+    // (TODO) Support for different sampling rates?
+    //
+
+    const Slice& sampleCountSlice = frameBuffer.getSampleCountSlice();
+    if (sampleCountSlice.base == 0)
+    {
+        throw IEX_NAMESPACE::ArgExc ("Invalid base pointer, please set a proper sample count slice.");
+    }
+    else
+    {
+        _data->sampleCountSliceBase = sampleCountSlice.base;
+        _data->sampleCountXStride = sampleCountSlice.xStride;
+        _data->sampleCountYStride = sampleCountSlice.yStride;
+    }
+
+    //
+    // Initialize the slice table for readPixels().
+    //
+
+    vector<InSliceInfo*> slices;
+    ChannelList::ConstIterator i = channels.begin();
+
+    for (DeepFrameBuffer::ConstIterator j = frameBuffer.begin();
+         j != frameBuffer.end();
+         ++j)
+    {
+        while (i != channels.end() && strcmp (i.name(), j.name()) < 0)
+        {
+            //
+            // Channel i is present in the file but not
+            // in the frame buffer; data for channel i
+            // will be skipped during readPixels().
+            //
+
+            slices.push_back (new InSliceInfo (i.channel().type,
+                                               NULL,
+                                               i.channel().type,
+                                               0,
+                                               0,
+                                               0, // sampleStride
+                                               i.channel().xSampling,
+                                               i.channel().ySampling,
+                                               false,  // fill
+                                               true, // skip
+                                               0.0)); // fillValue
+            ++i;
+        }
+
+        bool fill = false;
+
+        if (i == channels.end() || strcmp (i.name(), j.name()) > 0)
+        {
+            //
+            // Channel i is present in the frame buffer, but not in the file.
+            // In the frame buffer, slice j will be filled with a default value.
+            //
+
+            fill = true;
+        }
+
+        slices.push_back (new InSliceInfo (j.slice().type,
+                                           j.slice().base,
+                                           fill? j.slice().type:
+                                                 i.channel().type,
+                                           j.slice().xStride,
+                                           j.slice().yStride,
+                                           j.slice().sampleStride,
+                                           j.slice().xSampling,
+                                           j.slice().ySampling,
+                                           fill,
+                                           false, // skip
+                                           j.slice().fillValue));
+
+
+        if (i != channels.end() && !fill)
+            ++i;
+    }
+
+    //
+    // Client may want data to be filled in multiple arrays,
+    // so we reset gotSampleCount and bytesPerLine.
+    //
+
+    for (long i = 0; i < _data->gotSampleCount.size(); i++)
+        _data->gotSampleCount[i] = false;
+    for (size_t i = 0; i < _data->bytesPerLine.size(); i++)
+        _data->bytesPerLine[i] = 0;
+
+    //
+    // Store the new frame buffer.
+    //
+
+    _data->frameBuffer = frameBuffer;
+
+    for (size_t i = 0; i < _data->slices.size(); i++)
+        delete _data->slices[i];
+    _data->slices = slices;
+    _data->frameBufferValid = true;
+}
+
+
+const DeepFrameBuffer &
+DeepScanLineInputFile::frameBuffer () const
+{
+    Lock lock (*_data->_streamData);
+    return _data->frameBuffer;
+}
+
+
+bool
+DeepScanLineInputFile::isComplete () const
+{
+    return _data->fileIsComplete;
+}
+
+
+void
+DeepScanLineInputFile::readPixels (int scanLine1, int scanLine2)
+{
+    try
+    {
+        Lock lock (*_data->_streamData);
+
+        if (_data->slices.size() == 0)
+            throw IEX_NAMESPACE::ArgExc ("No frame buffer specified "
+                               "as pixel data destination.");
+
+        int scanLineMin = min (scanLine1, scanLine2);
+        int scanLineMax = max (scanLine1, scanLine2);
+
+        if (scanLineMin < _data->minY || scanLineMax > _data->maxY)
+            throw IEX_NAMESPACE::ArgExc ("Tried to read scan line outside "
+                               "the image file's data window.");
+
+        for (int i = scanLineMin; i <= scanLineMax; i++)
+        {
+            if (_data->gotSampleCount[i - _data->minY] == false)
+                throw IEX_NAMESPACE::ArgExc ("Tried to read scan line without "
+                                   "knowing the sample counts, please"
+                                   "read the sample counts first.");
+        }
+
+ 
+        //
+        // We impose a numbering scheme on the lineBuffers where the first
+        // scanline is contained in lineBuffer 1.
+        //
+        // Determine the first and last lineBuffer numbers in this scanline
+        // range. We always attempt to read the scanlines in the order that
+        // they are stored in the file.
+        //
+
+        int start, stop, dl;
+
+        if (_data->lineOrder == INCREASING_Y)
+        {
+            start = (scanLineMin - _data->minY) / _data->linesInBuffer;
+            stop  = (scanLineMax - _data->minY) / _data->linesInBuffer + 1;
+            dl = 1;
+        }
+        else
+        {
+            start = (scanLineMax - _data->minY) / _data->linesInBuffer;
+            stop  = (scanLineMin - _data->minY) / _data->linesInBuffer - 1;
+            dl = -1;
+        }
+
+        //
+        // Create a task group for all line buffer tasks.  When the
+        // task group goes out of scope, the destructor waits until
+        // all tasks are complete.
+        //
+
+        {
+            TaskGroup taskGroup;
+
+            //
+            // Add the line buffer tasks.
+            //
+            // The tasks will execute in the order that they are created
+            // because we lock the line buffers during construction and the
+            // constructors are called by the main thread.  Hence, in order
+            // for a successive task to execute the previous task which
+            // used that line buffer must have completed already.
+            //
+
+            for (int l = start; l != stop; l += dl)
+            {
+                ThreadPool::addGlobalTask (newLineBufferTask (&taskGroup,
+                                                              _data, l,
+                                                              scanLineMin,
+                                                              scanLineMax));
+            }
+
+            //
+            // finish all tasks
+            //
+        }
+
+        //
+        // Exeption handling:
+        //
+        // LineBufferTask::execute() may have encountered exceptions, but
+        // those exceptions occurred in another thread, not in the thread
+        // that is executing this call to ScanLineInputFile::readPixels().
+        // LineBufferTask::execute() has caught all exceptions and stored
+        // the exceptions' what() strings in the line buffers.
+        // Now we check if any line buffer contains a stored exception; if
+        // this is the case then we re-throw the exception in this thread.
+        // (It is possible that multiple line buffers contain stored
+        // exceptions.  We re-throw the first exception we find and
+        // ignore all others.)
+        //
+
+        const string *exception = 0;
+
+        for (size_t i = 0; i < _data->lineBuffers.size(); ++i)
+        {
+            LineBuffer *lineBuffer = _data->lineBuffers[i];
+
+            if (lineBuffer->hasException && !exception)
+                exception = &lineBuffer->exception;
+
+            lineBuffer->hasException = false;
+        }
+
+        if (exception)
+            throw IEX_NAMESPACE::IoExc (*exception);
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        REPLACE_EXC (e, "Error reading pixel data from image "
+                        "file \"" << fileName() << "\". " << e);
+        throw;
+    }
+}
+
+
+void
+DeepScanLineInputFile::readPixels (int scanLine)
+{
+    readPixels (scanLine, scanLine);
+}
+
+
+void
+DeepScanLineInputFile::rawPixelData (int firstScanLine,
+                                     char *pixelData,
+                                     Int64 &pixelDataSize)
+{
+   
+    
+    int minY = lineBufferMinY
+    (firstScanLine, _data->minY, _data->linesInBuffer);
+    int lineBufferNumber = (minY - _data->minY) / _data->linesInBuffer;
+    
+    Int64 lineOffset = _data->lineOffsets[lineBufferNumber];
+    
+    if (lineOffset == 0)
+        THROW (IEX_NAMESPACE::InputExc, "Scan line " << minY << " is missing.");
+    
+    
+    // enter the lock here - prevent another thread reseeking the file during read
+    Lock lock (*_data->_streamData);
+    
+    //
+    // Seek to the start of the scan line in the file,
+    //
+    
+    if (_data->_streamData->is->tellg() != _data->lineOffsets[lineBufferNumber])
+        _data->_streamData->is->seekg (lineOffset);
+    
+    //
+    // Read the data block's header.
+    //
+    
+    int yInFile;
+    
+    //
+    // Read the part number when we are dealing with a multi-part file.
+    //
+    
+    if (isMultiPart(_data->version))
+    {
+        int partNumber;
+        OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*_data->_streamData->is, partNumber);
+        if (partNumber != _data->partNumber)
+        {
+            THROW (IEX_NAMESPACE::ArgExc, "Unexpected part number " << partNumber
+            << ", should be " << _data->partNumber << ".");
+        }
+    }
+    
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*_data->_streamData->is, yInFile);
+    
+    if (yInFile != minY)
+        throw IEX_NAMESPACE::InputExc ("Unexpected data block y coordinate.");
+    
+    Int64 sampleCountTableSize;
+    Int64 packedDataSize;
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*_data->_streamData->is, sampleCountTableSize);
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*_data->_streamData->is, packedDataSize);
+    
+    // total requirement for reading all the data
+    
+    Int64 totalSizeRequired=28+sampleCountTableSize+packedDataSize;
+    
+    bool big_enough = totalSizeRequired<=pixelDataSize;
+    
+    pixelDataSize = totalSizeRequired;
+    
+    // was the block we were given big enough?
+    if(!big_enough || pixelData==NULL)
+    {        
+        // special case: seek stream back to start if we are at the beginning (regular reading pixels assumes it doesn't need to seek
+        // in single part files)
+        if(!isMultiPart(_data->version))
+        {
+          if (_data->nextLineBufferMinY == minY)
+              _data->_streamData->is->seekg (lineOffset);
+        }
+        // leave lock here - bail before reading more data
+        return;
+    }
+    
+    // copy the values we have read into the output block
+    *(int *) pixelData = yInFile;
+    *(Int64 *) (pixelData+4) =sampleCountTableSize;
+    *(Int64 *) (pixelData+12) = packedDataSize;
+    
+    // didn't read the unpackedsize - do that now
+    Xdr::read<StreamIO> (*_data->_streamData->is, *(Int64 *) (pixelData+20));
+    
+    // read the actual data
+    _data->_streamData->is->read(pixelData+28, sampleCountTableSize+packedDataSize);
+    
+    // special case: seek stream back to start if we are at the beginning (regular reading pixels assumes it doesn't need to seek
+    // in single part files)
+    if(!isMultiPart(_data->version))
+    {
+        if (_data->nextLineBufferMinY == minY)
+            _data->_streamData->is->seekg (lineOffset);
+    }
+    
+    // leave lock here
+    
+}
+
+void DeepScanLineInputFile::readPixels (const char* rawPixelData, 
+                                        const DeepFrameBuffer& frameBuffer, 
+                                        int scanLine1, 
+                                        int scanLine2) const
+{
+    //
+    // read header from block - already converted from Xdr to native format
+    //
+    int data_scanline = *(int *) rawPixelData;
+    Int64 sampleCountTableDataSize=*(Int64 *) (rawPixelData+4);
+    Int64 packedDataSize = *(Int64 *) (rawPixelData+12);
+    Int64 unpackedDataSize = *(Int64 *) (rawPixelData+20);
+
+    
+    
+    //
+    // Uncompress the data, if necessary
+    //
+    
+    
+    Compressor * decomp = NULL;
+    const char * uncompressed_data;
+    Compressor::Format format = Compressor::XDR;
+    if(packedDataSize <unpackedDataSize)
+    {
+        decomp = newCompressor(_data->header.compression(),
+                                             unpackedDataSize,
+                                             _data->header);
+                                             
+        decomp->uncompress(rawPixelData+28+sampleCountTableDataSize,
+                           packedDataSize,
+                           data_scanline, uncompressed_data);
+        format = decomp->format();
+    }
+    else
+    {
+        //
+        // If the line is uncompressed, it's in XDR format,
+        // regardless of the compressor's output format.
+        //
+        
+        format = Compressor::XDR;
+        uncompressed_data = rawPixelData+28+sampleCountTableDataSize;
+    }
+  
+    
+    int yStart, yStop, dy;
+    
+    if (_data->lineOrder == INCREASING_Y)
+    {
+        yStart = scanLine1;
+        yStop = scanLine2 + 1;
+        dy = 1;
+    }
+    else
+    {
+        yStart = scanLine2;
+        yStop = scanLine1 - 1;
+        dy = -1;
+    }
+    
+    
+    
+    const char* samplecount_base = frameBuffer.getSampleCountSlice().base;
+    int samplecount_xstride = frameBuffer.getSampleCountSlice().xStride;
+    int samplecount_ystride = frameBuffer.getSampleCountSlice().yStride;
+    
+    //
+    // For each line within the block, get the count of bytes.
+    //
+    
+    int minYInLineBuffer = data_scanline;
+    int maxYInLineBuffer = min(minYInLineBuffer + _data->linesInBuffer - 1, _data->maxY);
+    
+    vector<size_t> bytesPerLine(1+_data->maxY-_data->minY);
+    
+    
+    bytesPerDeepLineTable (_data->header,
+                           minYInLineBuffer,
+                           maxYInLineBuffer,
+                           samplecount_base,
+                           samplecount_xstride,
+                           samplecount_ystride,
+                           bytesPerLine);
+                           
+    //
+    // For each scanline within the block, get the offset.
+    //
+      
+    vector<size_t> offsetInLineBuffer;
+    offsetInLineBufferTable (bytesPerLine,
+                             minYInLineBuffer - _data->minY,
+                             maxYInLineBuffer - _data->minY,
+                             _data->linesInBuffer,
+                             offsetInLineBuffer);
+                             
+                             
+    const ChannelList & channels=header().channels();    
+    
+    
+    for (int y = yStart; y != yStop; y += dy)
+    {
+        
+        const char *readPtr =uncompressed_data +
+        offsetInLineBuffer[y - _data->minY];
+
+        //
+        // need to know the total number of samples on a scanline to skip channels
+        // compute on demand: -1 means uncomputed
+        //
+        int lineSampleCount = -1;
+        
+        
+        //
+        // Iterate over all image channels in frame buffer
+        //
+    
+    
+        ChannelList::ConstIterator i = channels.begin();
+                             
+        for (DeepFrameBuffer::ConstIterator j = frameBuffer.begin();
+                                            j != frameBuffer.end();
+             ++j)
+        {
+            while (i != channels.end() && strcmp (i.name(), j.name()) < 0)
+            {
+                //
+                // Channel i is present in the file but not
+                // in the frame buffer; skip
+                    
+                if(lineSampleCount==-1)
+                {
+                     lineSampleCount=0;
+                     const char * ptr = (samplecount_base+y*samplecount_ystride + samplecount_xstride*_data->minX);
+                     for(int x=_data->minX;x<=_data->maxX;x++)
+                     { 
+                         
+                          lineSampleCount+=*(const unsigned int *) ptr;
+                          ptr+=samplecount_xstride;
+                     }
+                }
+
+               skipChannel (readPtr, i.channel().type, lineSampleCount );
+        
+                ++i;
+            }
+                                 
+            bool fill = false;
+                                 
+            if (i == channels.end() || strcmp (i.name(), j.name()) > 0)
+            {
+                //
+                // Channel i is present in the frame buffer, but not in the file.
+                // In the frame buffer, slice j will be filled with a default value.
+                //
+                                     
+               fill = true;
+            }
+            if (modp (y, i.channel().ySampling) == 0)
+            {        
+                
+                copyIntoDeepFrameBuffer (readPtr, j.slice().base,
+                                         samplecount_base,
+                                         samplecount_xstride,
+                                         samplecount_ystride,
+                                         y, _data->minX, _data->maxX,
+                                         0, 0,
+                                         0, 0,
+                                         j.slice().sampleStride, 
+                                         j.slice().xStride,
+                                         j.slice().yStride,
+                                         fill,
+                                         j.slice().fillValue, 
+                                         format,
+                                         j.slice().type,
+                                         i.channel().type);
+                                         
+                ++i;
+                                         
+            }
+        }//next slice in framebuffer
+    }//next row in image
+    
+    //
+    // clean up
+    //
+    
+    delete decomp;    
+}
+        
+      
+
+void DeepScanLineInputFile::readPixelSampleCounts (const char* rawPixelData, 
+                                                   const DeepFrameBuffer& frameBuffer, 
+                                                   int scanLine1, 
+                                                   int scanLine2) const
+{
+    //
+    // read header from block - already converted from Xdr to native format
+    //
+    int data_scanline = *(int *) rawPixelData;
+    Int64 sampleCountTableDataSize=*(Int64 *) (rawPixelData+4);
+    
+    
+    int maxY;
+    maxY = min(data_scanline + _data->linesInBuffer - 1, _data->maxY);
+    
+    if(scanLine1 != data_scanline)
+    {
+        THROW(IEX_NAMESPACE::ArgExc,"readPixelSampleCounts(rawPixelData,frameBuffer,"<< scanLine1 << ',' << scanLine2 << ") called with incorrect start scanline - should be " << data_scanline );
+    }
+    
+    if(scanLine2 != maxY)
+    {
+        THROW(IEX_NAMESPACE::ArgExc,"readPixelSampleCounts(rawPixelData,frameBuffer,"<< scanLine1 << ',' << scanLine2 << ") called with incorrect end scanline - should be " << maxY );
+    }
+    
+    
+    //
+    // If the sample count table is compressed, we'll uncompress it.
+    //
+    
+    Int64 rawSampleCountTableSize = (maxY - data_scanline + 1) * (_data->maxX - _data->minX + 1) *
+    Xdr::size <unsigned int> ();
+    
+    
+    Compressor * decomp=NULL;
+    const char* readPtr;
+    if (sampleCountTableDataSize < rawSampleCountTableSize)
+    {
+        decomp = newCompressor(_data->header.compression(),
+                               rawSampleCountTableSize,
+                               _data->header);
+                                                    
+        decomp->uncompress(rawPixelData+28,
+                                               sampleCountTableDataSize,
+                                               data_scanline,
+                                               readPtr);
+    }
+    else readPtr = rawPixelData+28;
+    
+    char* base = frameBuffer.getSampleCountSlice().base;
+    int xStride = frameBuffer.getSampleCountSlice().xStride;
+    int yStride = frameBuffer.getSampleCountSlice().yStride;
+    
+   
+    
+    for (int y = scanLine1; y <= scanLine2; y++)
+    {
+        int lastAccumulatedCount = 0;
+        for (int x = _data->minX; x <= _data->maxX; x++)
+        {
+            int accumulatedCount, count;
+            
+            //
+            // Read the sample count for pixel (x, y).
+            //
+            
+            Xdr::read <CharPtrIO> (readPtr, accumulatedCount);
+            if (x == _data->minX)
+                count = accumulatedCount;
+            else
+                count = accumulatedCount - lastAccumulatedCount;
+            lastAccumulatedCount = accumulatedCount;
+            
+            //
+            // Store the data in both internal and external data structure.
+            //
+            
+            sampleCount(base, xStride, yStride, x, y) = count;
+        }
+    }
+    
+    if(decomp)
+    {
+       delete decomp;
+    }
+}
+
+
+
+namespace
+{
+
+void
+readSampleCountForLineBlock(InputStreamMutex* streamData,
+                            DeepScanLineInputFile::Data* data,
+                            int lineBlockId)
+{
+    streamData->is->seekg(data->lineOffsets[lineBlockId]);
+
+    if (isMultiPart(data->version))
+    {
+        int partNumber;
+        OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*streamData->is, partNumber);
+
+        if (partNumber != data->partNumber)
+            throw IEX_NAMESPACE::ArgExc("Unexpected part number.");
+    }
+
+    int minY;
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*streamData->is, minY);
+
+    //
+    // Check the correctness of minY.
+    //
+
+    if (minY != data->minY + lineBlockId * data->linesInBuffer)
+        throw IEX_NAMESPACE::ArgExc("Unexpected data block y coordinate.");
+
+    int maxY;
+    maxY = min(minY + data->linesInBuffer - 1, data->maxY);
+
+    Int64 sampleCountTableDataSize;
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*streamData->is, sampleCountTableDataSize);
+
+    
+    
+    if(sampleCountTableDataSize>data->maxSampleCountTableSize)
+    {
+        THROW (IEX_NAMESPACE::ArgExc, "Bad sampleCountTableDataSize read from chunk "<< lineBlockId << ": expected " << data->maxSampleCountTableSize << " or less, got "<< sampleCountTableDataSize);
+    }
+    
+    Int64 packedDataSize;
+    Int64 unpackedDataSize;
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*streamData->is, packedDataSize);
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*streamData->is, unpackedDataSize);
+
+    
+    
+    //
+    // We make a check on the data size requirements here.
+    // Whilst we wish to store 64bit sizes on disk, not all the compressors
+    // have been made to work with such data sizes and are still limited to
+    // using signed 32 bit (int) for the data size. As such, this version
+    // insists that we validate that the data size does not exceed the data
+    // type max limit.
+    // @TODO refactor the compressor code to ensure full 64-bit support.
+    //
+
+    int compressorMaxDataSize = std::numeric_limits<int>::max();
+    if (sampleCountTableDataSize > Int64(compressorMaxDataSize))
+    {
+        THROW (IEX_NAMESPACE::ArgExc, "This version of the library does not "
+              << "support the allocation of data with size  > "
+              << compressorMaxDataSize
+              << " file table size    :" << sampleCountTableDataSize << ".\n");
+    }
+    streamData->is->read(data->sampleCountTableBuffer, sampleCountTableDataSize);
+    
+    const char* readPtr;
+
+    //
+    // If the sample count table is compressed, we'll uncompress it.
+    //
+
+
+    if (sampleCountTableDataSize < data->maxSampleCountTableSize)
+    {
+        if(!data->sampleCountTableComp)
+        {
+            THROW(IEX_NAMESPACE::ArgExc,"Deep scanline data corrupt at chunk " << lineBlockId << " (sampleCountTableDataSize error)");
+        }
+        data->sampleCountTableComp->uncompress(data->sampleCountTableBuffer,
+                                               sampleCountTableDataSize,
+                                               minY,
+                                               readPtr);
+    }
+    else readPtr = data->sampleCountTableBuffer;
+
+    char* base = data->sampleCountSliceBase;
+    int xStride = data->sampleCountXStride;
+    int yStride = data->sampleCountYStride;
+
+    // total number of samples in block: used to check samplecount table doesn't
+    // reference more data than exists
+    
+    size_t cumulative_total_samples=0;
+    
+    for (int y = minY; y <= maxY; y++)
+    {
+        int yInDataWindow = y - data->minY;
+        data->lineSampleCount[yInDataWindow] = 0;
+
+        int lastAccumulatedCount = 0;
+        for (int x = data->minX; x <= data->maxX; x++)
+        {
+            int accumulatedCount, count;
+
+            //
+            // Read the sample count for pixel (x, y).
+            //
+
+            Xdr::read <CharPtrIO> (readPtr, accumulatedCount);
+            
+            // sample count table should always contain monotonically
+            // increasing values.
+            if (accumulatedCount < lastAccumulatedCount)
+            {
+                THROW(IEX_NAMESPACE::ArgExc,"Deep scanline sampleCount data corrupt at chunk " << lineBlockId << " (negative sample count detected)");
+            }
+
+            count = accumulatedCount - lastAccumulatedCount;
+            lastAccumulatedCount = accumulatedCount;
+
+            //
+            // Store the data in both internal and external data structure.
+            //
+
+            data->sampleCount[yInDataWindow][x - data->minX] = count;
+            data->lineSampleCount[yInDataWindow] += count;
+            sampleCount(base, xStride, yStride, x, y) = count;
+        }
+        cumulative_total_samples+=data->lineSampleCount[yInDataWindow];
+        if(cumulative_total_samples*data->combinedSampleSize > unpackedDataSize)
+        {
+            THROW(IEX_NAMESPACE::ArgExc,"Deep scanline sampleCount data corrupt at chunk " << lineBlockId << ": pixel data only contains " << unpackedDataSize 
+            << " bytes of data but table references at least " << cumulative_total_samples*data->combinedSampleSize << " bytes of sample data" );            
+        }
+        data->gotSampleCount[y - data->minY] = true;
+    }
+}
+
+
+void
+fillSampleCountFromCache(int y, DeepScanLineInputFile::Data* data)
+{
+    int yInDataWindow = y - data->minY;
+    char* base = data->sampleCountSliceBase;
+    int xStride = data->sampleCountXStride;
+    int yStride = data->sampleCountYStride;
+    
+    for (int x = data->minX; x <= data->maxX; x++)
+    {
+        unsigned int count = data->sampleCount[yInDataWindow][x - data->minX];    
+        sampleCount(base, xStride, yStride, x, y) = count;
+    }
+}
+
+} // namespace
+
+void
+DeepScanLineInputFile::readPixelSampleCounts (int scanline1, int scanline2)
+{
+    Int64 savedFilePos = 0;
+
+    if(!_data->frameBufferValid)
+    {
+        throw IEX_NAMESPACE::ArgExc("readPixelSampleCounts called with no valid frame buffer");
+    }
+    
+    try
+    {
+        Lock lock (*_data->_streamData);
+
+        savedFilePos = _data->_streamData->is->tellg();
+
+        int scanLineMin = min (scanline1, scanline2);
+        int scanLineMax = max (scanline1, scanline2);
+
+        if (scanLineMin < _data->minY || scanLineMax > _data->maxY)
+            throw IEX_NAMESPACE::ArgExc ("Tried to read scan line sample counts outside "
+                               "the image file's data window.");
+
+        for (int i = scanLineMin; i <= scanLineMax; i++)
+        {
+            //
+            // if scanline is already read, it'll be in the cache
+            // otherwise, read from file, store in cache and in caller's framebuffer
+            //
+            if (_data->gotSampleCount[i - _data->minY])
+            {
+                fillSampleCountFromCache(i,_data);
+                                         
+            }else{
+
+                int lineBlockId = ( i - _data->minY ) / _data->linesInBuffer;
+
+                readSampleCountForLineBlock ( _data->_streamData, _data, lineBlockId );
+
+                int minYInLineBuffer = lineBlockId * _data->linesInBuffer + _data->minY;
+                int maxYInLineBuffer = min ( minYInLineBuffer + _data->linesInBuffer - 1, _data->maxY );
+
+                //
+                // For each line within the block, get the count of bytes.
+                //
+
+                bytesPerDeepLineTable ( _data->header,
+                                        minYInLineBuffer,
+                                        maxYInLineBuffer,
+                                        _data->sampleCountSliceBase,
+                                        _data->sampleCountXStride,
+                                        _data->sampleCountYStride,
+                                        _data->bytesPerLine );
+
+                //
+                // For each scanline within the block, get the offset.
+                //
+
+                offsetInLineBufferTable ( _data->bytesPerLine,
+                                          minYInLineBuffer - _data->minY,
+                                          maxYInLineBuffer - _data->minY,
+                                          _data->linesInBuffer,
+                                          _data->offsetInLineBuffer );
+            }
+        }
+
+        _data->_streamData->is->seekg(savedFilePos);
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        REPLACE_EXC (e, "Error reading sample count data from image "
+                        "file \"" << fileName() << "\". " << e);
+
+        _data->_streamData->is->seekg(savedFilePos);
+
+        throw;
+    }
+}
+
+void
+DeepScanLineInputFile::readPixelSampleCounts(int scanline)
+{
+    readPixelSampleCounts(scanline, scanline);
+}
+
+int 
+DeepScanLineInputFile::firstScanLineInChunk(int y) const
+{
+    return int((y-_data->minY)/_data->linesInBuffer)*_data->linesInBuffer + _data->minY;
+}
+
+int
+DeepScanLineInputFile::lastScanLineInChunk(int y) const
+{
+    int minY = firstScanLineInChunk(y);
+    return min(minY+_data->linesInBuffer-1,_data->maxY);
+}
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfDeepScanLineInputFile.h b/Source/OpenEXR/IlmImf/ImfDeepScanLineInputFile.h
new file mode 100644
index 0000000..87a4065
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfDeepScanLineInputFile.h
@@ -0,0 +1,276 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+#ifndef INCLUDED_IMF_DEEP_SCAN_LINE_INPUT_FILE_H
+#define INCLUDED_IMF_DEEP_SCAN_LINE_INPUT_FILE_H
+
+//-----------------------------------------------------------------------------
+//
+//      class DeepScanLineInputFile
+//
+//-----------------------------------------------------------------------------
+
+#include "ImfThreading.h"
+#include "ImfGenericInputFile.h"
+#include "ImfNamespace.h"
+#include "ImfForward.h"
+#include "ImfExport.h"
+#include "ImfDeepScanLineOutputFile.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+
+class IMF_EXPORT DeepScanLineInputFile : public GenericInputFile
+{
+  public:
+
+    //------------
+    // Constructor
+    //------------
+
+    DeepScanLineInputFile (const char fileName[],
+                           int numThreads = globalThreadCount());
+
+    DeepScanLineInputFile (const Header &header, OPENEXR_IMF_INTERNAL_NAMESPACE::IStream *is,
+                           int version, /*version field from file*/
+                           int numThreads = globalThreadCount());
+
+
+    //-----------------------------------------
+    // Destructor -- deallocates internal data
+    // structures, but does not close the file.
+    //-----------------------------------------
+
+    virtual ~DeepScanLineInputFile ();
+
+
+    //------------------------
+    // Access to the file name
+    //------------------------
+
+    const char *        fileName () const;
+
+
+    //--------------------------
+    // Access to the file header
+    //--------------------------
+
+    const Header &      header () const;
+
+
+    //----------------------------------
+    // Access to the file format version
+    //----------------------------------
+
+    int                 version () const;
+
+
+    //-----------------------------------------------------------
+    // Set the current frame buffer -- copies the FrameBuffer
+    // object into the InputFile object.
+    //
+    // The current frame buffer is the destination for the pixel
+    // data read from the file.  The current frame buffer must be
+    // set at least once before readPixels() is called.
+    // The current frame buffer can be changed after each call
+    // to readPixels().
+    //-----------------------------------------------------------
+
+    void                setFrameBuffer (const DeepFrameBuffer &frameBuffer);
+
+
+    //-----------------------------------
+    // Access to the current frame buffer
+    //-----------------------------------
+
+    const DeepFrameBuffer & frameBuffer () const;
+
+
+    //---------------------------------------------------------------
+    // Check if the file is complete:
+    //
+    // isComplete() returns true if all pixels in the data window are
+    // present in the input file, or false if any pixels are missing.
+    // (Another program may still be busy writing the file, or file
+    // writing may have been aborted prematurely.)
+    //---------------------------------------------------------------
+
+    bool                isComplete () const;
+
+
+    //---------------------------------------------------------------
+    // Read pixel data:
+    //
+    // readPixels(s1,s2) reads all scan lines with y coordinates
+    // in the interval [min (s1, s2), max (s1, s2)] from the file,
+    // and stores them in the current frame buffer.
+    //
+    // Both s1 and s2 must be within the interval
+    // [header().dataWindow().min.y, header.dataWindow().max.y]
+    //
+    // The scan lines can be read from the file in random order, and
+    // individual scan lines may be skipped or read multiple times.
+    // For maximum efficiency, the scan lines should be read in the
+    // order in which they were written to the file.
+    //
+    // readPixels(s) calls readPixels(s,s).
+    //
+    // If threading is enabled, readPixels (s1, s2) tries to perform
+    // decopmression of multiple scanlines in parallel.
+    //
+    //---------------------------------------------------------------
+
+    void                readPixels (int scanLine1, int scanLine2);
+    void                readPixels (int scanLine);
+
+    
+  
+    //---------------------------------------------------------------
+    // Extract pixel data from pre-read block
+    //
+    // readPixels(rawPixelData,frameBuffer,s1,s2) reads all scan lines with y coordinates
+    // in the interval [min (s1, s2), max (s1, s2)] from the data provided and
+    // stores them in the provided frameBuffer.
+    // the data can be obtained from a call to rawPixelData()
+    //
+    //
+    // Both s1 and s2 must be within the data specified
+    //
+    // you must provide a frameBuffer with a samplecountslice, which must have been read
+    // and the data valid - readPixels uses your sample count buffer to compute
+    // offsets to the data it needs
+    //
+    // This call does not block, and is thread safe for clients with an existing
+    // threading model. The InputFile's frameBuffer is not used in this call.
+    //
+    // This call is only provided for clients which have an existing threading model in place
+    // and unpredictable access patterns to the data.
+    // The fastest way to read an entire image is to enable threading,use setFrameBuffer then
+    // readPixels(header().dataWindow().min.y, header.dataWindow().max.y)
+    //
+    //---------------------------------------------------------------
+    
+    void                readPixels (const char * rawPixelData,
+                                    const DeepFrameBuffer & frameBuffer,
+                                    int scanLine1,
+                                    int scanLine2) const;
+
+    //----------------------------------------------
+    // Read a block of raw pixel data from the file,
+    // without uncompressing it (this function is
+    // used to implement OutputFile::copyPixels()).
+    // note: returns the entire payload of the relevant chunk of data, not including part number
+    // including compressed and uncompressed sizes
+    // on entry, if pixelDataSize is insufficiently large, no bytes are read (pixelData can safely be NULL)
+    // on exit, pixelDataSize is the number of bytes required to read the chunk
+    // 
+    //----------------------------------------------
+
+    void                rawPixelData (int firstScanLine,
+                                      char * pixelData,
+                                      Int64 &pixelDataSize);
+
+                                      
+    //-------------------------------------------------
+    // firstScanLineInChunk() returns the row number of the first row that's stored in the
+    // same chunk as scanline y. Depending on the compression mode, this may not be the same as y
+    //
+    // lastScanLineInChunk() returns the row number of the last row that's stored in the same
+    // chunk as scanline y.  Depending on the compression mode, this may not be the same as y.
+    // The last chunk in the file may be smaller than all the others
+    //
+    //------------------------------------------------
+    int                 firstScanLineInChunk(int y) const;
+    int                 lastScanLineInChunk (int y) const;
+                                      
+    //-----------------------------------------------------------
+    // Read pixel sample counts into a slice in the frame buffer.
+    //
+    // readPixelSampleCounts(s1, s2) reads all the counts of
+    // pixel samples with y coordinates in the interval
+    // [min (s1, s2), max (s1, s2)] from the file, and stores
+    // them in the slice naming "sample count".
+    //
+    // Both s1 and s2 must be within the interval
+    // [header().dataWindow().min.y, header.dataWindow().max.y]
+    //
+    // readPixelSampleCounts(s) calls readPixelSampleCounts(s,s).
+    // 
+    //-----------------------------------------------------------
+
+    void                readPixelSampleCounts (int scanline1,
+                                               int scanline2);
+    void                readPixelSampleCounts (int scanline);
+    
+    
+    //----------------------------------------------------------
+    // Read pixel sample counts into the provided frameBuffer
+    // using a block read of data read by rawPixelData    
+    // for multi-scanline compression schemes, you must decode the entire block
+    // so scanline1=firstScanLineInChunk(y) and scanline2=lastScanLineInChunk(y)
+    // 
+    // This call does not block, and is thread safe for clients with an existing
+    // threading model. The InputFile's frameBuffer is not used in this call.
+    //
+    // The fastest way to read an entire image is to enable threading in OpenEXR, use setFrameBuffer then
+    // readPixelSampleCounts(header().dataWindow().min.y, header.dataWindow().max.y)
+    //
+    //----------------------------------------------------------
+    void                readPixelSampleCounts (const char * rawdata , 
+                                               const DeepFrameBuffer & frameBuffer,
+                                               int scanLine1 , 
+                                               int scanLine2) const;
+
+    struct Data;
+
+  private:
+
+    Data *              _data;
+
+    DeepScanLineInputFile   (InputPartData* part);
+
+    void                initialize(const Header& header);
+    void compatibilityInitialize(OPENEXR_IMF_INTERNAL_NAMESPACE::IStream & is);
+    void multiPartInitialize(InputPartData* part);
+
+    friend class         InputFile;
+    friend class MultiPartInputFile;
+    friend void DeepScanLineOutputFile::copyPixels(DeepScanLineInputFile &);
+};
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif
diff --git a/Source/OpenEXR/IlmImf/ImfDeepScanLineInputPart.cpp b/Source/OpenEXR/IlmImf/ImfDeepScanLineInputPart.cpp
new file mode 100644
index 0000000..068e1d4
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfDeepScanLineInputPart.cpp
@@ -0,0 +1,149 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+#include "ImfDeepScanLineInputPart.h"
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+DeepScanLineInputPart::DeepScanLineInputPart(MultiPartInputFile& multiPartFile, int partNumber)
+{
+    file = multiPartFile.getInputPart<DeepScanLineInputFile>(partNumber);
+}
+
+
+const char *
+DeepScanLineInputPart::fileName () const
+{
+    return file->fileName();
+}
+
+
+const Header &
+DeepScanLineInputPart::header () const
+{
+    return file->header();
+}
+
+
+int
+DeepScanLineInputPart::version () const
+{
+    return file->version();
+}
+
+
+void
+DeepScanLineInputPart::setFrameBuffer (const DeepFrameBuffer &frameBuffer)
+{
+    file->setFrameBuffer(frameBuffer);
+}
+
+
+const DeepFrameBuffer &
+DeepScanLineInputPart::frameBuffer () const
+{
+    return file->frameBuffer();
+}
+
+
+bool
+DeepScanLineInputPart::isComplete () const
+{
+    return file->isComplete();
+}
+
+
+void
+DeepScanLineInputPart::readPixels (int scanLine1, int scanLine2)
+{
+    file->readPixels(scanLine1, scanLine2);
+}
+
+
+void
+DeepScanLineInputPart::readPixels (int scanLine)
+{
+    file->readPixels(scanLine);
+}
+
+
+void
+DeepScanLineInputPart::rawPixelData (int firstScanLine,
+                                     char *pixelData,
+                                     Int64 &pixelDataSize)
+{
+    file->rawPixelData(firstScanLine, pixelData, pixelDataSize);
+}
+
+
+void
+DeepScanLineInputPart::readPixelSampleCounts(int scanline1,
+                                            int scanline2)
+{
+    file->readPixelSampleCounts(scanline1, scanline2);
+}
+
+
+void
+DeepScanLineInputPart::readPixelSampleCounts(int scanline)
+{
+    file->readPixelSampleCounts(scanline);
+}
+
+int 
+DeepScanLineInputPart::firstScanLineInChunk(int y) const
+{
+    return file->firstScanLineInChunk(y);
+}
+
+int 
+DeepScanLineInputPart::lastScanLineInChunk(int y) const
+{
+    return file->lastScanLineInChunk(y);
+}
+
+void 
+DeepScanLineInputPart::readPixels(const char* rawPixelData, const DeepFrameBuffer& frameBuffer, int scanLine1, int scanLine2) const
+{
+    return file->readPixels(rawPixelData,frameBuffer,scanLine1,scanLine2);
+}
+void 
+DeepScanLineInputPart::readPixelSampleCounts(const char* rawdata, const DeepFrameBuffer& frameBuffer, int scanLine1, int scanLine2) const
+{
+   return file->readPixelSampleCounts(rawdata,frameBuffer,scanLine1,scanLine2);
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfDeepScanLineInputPart.h b/Source/OpenEXR/IlmImf/ImfDeepScanLineInputPart.h
new file mode 100644
index 0000000..c21786b
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfDeepScanLineInputPart.h
@@ -0,0 +1,181 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+#ifndef IMFDEEPSCANLINEINPUTPART_H_
+#define IMFDEEPSCANLINEINPUTPART_H_
+
+#include "ImfMultiPartInputFile.h"
+#include "ImfDeepScanLineInputFile.h"
+#include "ImfDeepScanLineOutputFile.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+class IMF_EXPORT DeepScanLineInputPart
+{
+  public:
+
+    DeepScanLineInputPart(MultiPartInputFile& file, int partNumber);
+
+    //------------------------
+    // Access to the file name
+    //------------------------
+
+    const char *        fileName () const;
+
+
+    //--------------------------
+    // Access to the file header
+    //--------------------------
+
+    const Header &      header () const;
+
+
+    //----------------------------------
+    // Access to the file format version
+    //----------------------------------
+
+    int                 version () const;
+
+
+    //-----------------------------------------------------------
+    // Set the current frame buffer -- copies the FrameBuffer
+    // object into the InputFile object.
+    //
+    // The current frame buffer is the destination for the pixel
+    // data read from the file.  The current frame buffer must be
+    // set at least once before readPixels() is called.
+    // The current frame buffer can be changed after each call
+    // to readPixels().
+    //-----------------------------------------------------------
+
+    void                setFrameBuffer (const DeepFrameBuffer &frameBuffer);
+
+
+    //-----------------------------------
+    // Access to the current frame buffer
+    //-----------------------------------
+
+    const DeepFrameBuffer & frameBuffer () const;
+
+
+    //---------------------------------------------------------------
+    // Check if the file is complete:
+    //
+    // isComplete() returns true if all pixels in the data window are
+    // present in the input file, or false if any pixels are missing.
+    // (Another program may still be busy writing the file, or file
+    // writing may have been aborted prematurely.)
+    //---------------------------------------------------------------
+
+    bool                isComplete () const;
+
+
+    //---------------------------------------------------------------
+    // Read pixel data:
+    //
+    // readPixels(s1,s2) reads all scan lines with y coordinates
+    // in the interval [min (s1, s2), max (s1, s2)] from the file,
+    // and stores them in the current frame buffer.
+    //
+    // Both s1 and s2 must be within the interval
+    // [header().dataWindow().min.y, header.dataWindow().max.y]
+    //
+    // The scan lines can be read from the file in random order, and
+    // individual scan lines may be skipped or read multiple times.
+    // For maximum efficiency, the scan lines should be read in the
+    // order in which they were written to the file.
+    //
+    // readPixels(s) calls readPixels(s,s).
+    //
+    // If threading is enabled, readPixels (s1, s2) tries to perform
+    // decopmression of multiple scanlines in parallel.
+    //
+    //---------------------------------------------------------------
+
+    void                readPixels (int scanLine1, int scanLine2);
+    void                readPixels (int scanLine);
+    void                readPixels (const char * rawPixelData,const DeepFrameBuffer & frameBuffer,
+                                    int scanLine1,int scanLine2) const;
+
+    //----------------------------------------------
+    // Read a block of raw pixel data from the file,
+    // without uncompressing it (this function is
+    // used to implement OutputFile::copyPixels()).
+    //----------------------------------------------
+
+    void                rawPixelData (int firstScanLine,
+                                      char * pixelData,
+                                      Int64 &pixelDataSize);
+                             
+                                      
+    //-----------------------------------------------------------
+    // Read pixel sample counts into a slice in the frame buffer.
+    //
+    // readPixelSampleCounts(s1, s2) reads all the counts of
+    // pixel samples with y coordinates in the interval
+    // [min (s1, s2), max (s1, s2)] from the file, and stores
+    // them in the slice naming "sample count".
+    //
+    // Both s1 and s2 must be within the interval
+    // [header().dataWindow().min.y, header.dataWindow().max.y]
+    //
+    // readPixelSampleCounts(s) calls readPixelSampleCounts(s,s).
+    //-----------------------------------------------------------
+
+    void                readPixelSampleCounts(int scanline1,
+                                              int scanline2);
+    void                readPixelSampleCounts(int scanline);
+    
+    void                readPixelSampleCounts( const char * rawdata , const DeepFrameBuffer & frameBuffer,
+                                               int scanLine1 , int scanLine2) const;
+                                               
+    int                 firstScanLineInChunk(int y) const;
+    int                 lastScanLineInChunk (int y) const;
+  private:
+    DeepScanLineInputFile *file;
+    
+    // needed for copyPixels 
+    friend void DeepScanLineOutputFile::copyPixels(DeepScanLineInputPart &);
+};
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
+
+
+#endif /* IMFDEEPSCANLINEINPUTPART_H_ */
diff --git a/Source/OpenEXR/IlmImf/ImfDeepScanLineOutputFile.cpp b/Source/OpenEXR/IlmImf/ImfDeepScanLineOutputFile.cpp
new file mode 100644
index 0000000..ebee084
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfDeepScanLineOutputFile.cpp
@@ -0,0 +1,1552 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+//-----------------------------------------------------------------------------
+//
+//      class DeepScanLineOutputFile
+//
+//-----------------------------------------------------------------------------
+
+#include <ImfDeepScanLineOutputFile.h>
+#include <ImfDeepScanLineInputFile.h>
+#include <ImfDeepScanLineInputPart.h>
+#include <ImfChannelList.h>
+#include <ImfMisc.h>
+#include <ImfStdIO.h>
+#include <ImfCompressor.h>
+#include "ImathBox.h"
+#include "ImathFun.h"
+#include <ImfArray.h>
+#include <ImfXdr.h>
+#include <ImfPreviewImageAttribute.h>
+#include <ImfPartType.h>
+#include "ImfDeepFrameBuffer.h"
+#include "ImfOutputStreamMutex.h"
+#include "ImfOutputPartData.h"
+
+#include "IlmThreadPool.h"
+#include "IlmThreadSemaphore.h"
+#include "IlmThreadMutex.h"
+#include "Iex.h"
+#include <string>
+#include <vector>
+#include <fstream>
+#include <assert.h>
+#include <algorithm>
+
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+using IMATH_NAMESPACE::Box2i;
+using IMATH_NAMESPACE::divp;
+using IMATH_NAMESPACE::modp;
+using std::string;
+using std::vector;
+using std::ofstream;
+using std::min;
+using std::max;
+using ILMTHREAD_NAMESPACE::Mutex;
+using ILMTHREAD_NAMESPACE::Lock;
+using ILMTHREAD_NAMESPACE::Semaphore;
+using ILMTHREAD_NAMESPACE::Task;
+using ILMTHREAD_NAMESPACE::TaskGroup;
+using ILMTHREAD_NAMESPACE::ThreadPool;
+
+namespace {
+
+
+struct OutSliceInfo
+{
+    PixelType                    type;
+    const char *                 base;
+    ptrdiff_t                    sampleStride;
+    ptrdiff_t                    xStride;
+    ptrdiff_t                    yStride;
+    int                          xSampling;
+    int                          ySampling;
+    bool                         zero;
+
+    OutSliceInfo (PixelType type = HALF,
+                  const char * base =NULL,
+                  ptrdiff_t sampleStride = 0,
+                  ptrdiff_t xStride = 0,
+                  ptrdiff_t yStride =0,
+                  int xSampling = 1,
+                  int ySampling = 1,
+                  bool zero = false);
+};
+
+
+OutSliceInfo::OutSliceInfo (PixelType t,
+                            const char * base,
+                            ptrdiff_t spstride,
+                            ptrdiff_t xst,
+                            ptrdiff_t yst,
+                            int xsm, int ysm,
+                            bool z)
+:
+    type (t),
+    base (base),
+    sampleStride (spstride),
+    xStride(xst),
+    yStride(yst),
+    xSampling (xsm),
+    ySampling (ysm),
+    zero (z)
+{
+    // empty
+}
+
+
+struct LineBuffer
+{
+    Array< Array<char> >  buffer;
+    Array<char>           consecutiveBuffer;
+    const char *          dataPtr;
+    Int64                 uncompressedDataSize;
+    Int64                 dataSize;
+    Array<char>           sampleCountTableBuffer;
+    const char *          sampleCountTablePtr;
+    Int64                 sampleCountTableSize;
+    Compressor*           sampleCountTableCompressor;
+    int                   minY;                 // the min y scanline stored
+    int                   maxY;                 // the max y scanline stored
+    int                   scanLineMin;          // the min y scanline writing out
+    int                   scanLineMax;          // the max y scanline writing out
+    Compressor *          compressor;
+    bool                  partiallyFull;        // has incomplete data
+    bool                  hasException;
+    string                exception;
+
+    LineBuffer (int linesInBuffer);
+    ~LineBuffer ();
+
+    void                  wait () {_sem.wait();}
+    void                  post () {_sem.post();}
+
+  private:
+
+    Semaphore             _sem;
+};
+
+
+LineBuffer::LineBuffer (int linesInBuffer) :
+    dataPtr (0),
+    dataSize (0),
+    sampleCountTablePtr (0),
+    sampleCountTableCompressor (0),
+    compressor (0),
+    partiallyFull (false),
+    hasException (false),
+    exception (),
+    _sem (1)
+{
+    buffer.resizeErase(linesInBuffer);
+}
+
+
+LineBuffer::~LineBuffer ()
+{
+    if (compressor != 0)
+        delete compressor;
+
+    if (sampleCountTableCompressor != 0)
+        delete sampleCountTableCompressor;
+}
+
+} // namespace
+
+
+struct DeepScanLineOutputFile::Data
+{
+    Header                      header;                // the image header
+    int                         version;               // file format version
+    bool                        multipart;             // from a multipart file
+    Int64                       previewPosition;       // file position for preview
+    DeepFrameBuffer             frameBuffer;           // framebuffer to write into
+    int                         currentScanLine;       // next scanline to be written
+    int                         missingScanLines;      // number of lines to write
+    LineOrder                   lineOrder;             // the file's lineorder
+    int                         minX;                  // data window's min x coord
+    int                         maxX;                  // data window's max x coord
+    int                         minY;                  // data window's min y coord
+    int                         maxY;                  // data window's max x coord
+    vector<Int64>               lineOffsets;           // stores offsets in file for
+                                                       // each scanline
+    vector<size_t>              bytesPerLine;          // combined size of a line over
+                                                       // all channels
+    Compressor::Format          format;                // compressor's data format
+    vector<OutSliceInfo*>       slices;                // info about channels in file
+    Int64                       lineOffsetsPosition;   // file position for line
+                                                       // offset table
+
+    vector<LineBuffer*>         lineBuffers;           // each holds one line buffer
+    int                         linesInBuffer;         // number of scanlines each
+                                                       // buffer holds
+    int                         partNumber;            // the output part number
+
+    char*                       sampleCountSliceBase;  // the pointer to the number
+                                                       // of samples in each pixel
+    int                         sampleCountXStride;    // the x stride for sampleCountSliceBase
+    int                         sampleCountYStride;    // the y stride for sampleCountSliceBase
+
+    Array<unsigned int>         lineSampleCount;       // the number of samples
+                                                       // in each line
+
+    Int64                       maxSampleCountTableSize;
+                                                       // the max size in bytes for a pixel
+                                                       // sample count table
+    OutputStreamMutex*  _streamData;
+    bool                _deleteStream;
+
+    Data (int numThreads);
+    ~Data ();
+
+
+    inline LineBuffer *         getLineBuffer (int number);// hash function from line
+                                                           // buffer indices into our
+                                                           // vector of line buffers
+
+    inline int&                 getSampleCount(int x, int y); // get the number of samples
+                                                              // in each pixel
+};
+
+
+DeepScanLineOutputFile::Data::Data (int numThreads):
+    lineOffsetsPosition (0),
+    partNumber (-1) ,
+    _streamData(NULL),
+    _deleteStream(false)
+{
+    //
+    // We need at least one lineBuffer, but if threading is used,
+    // to keep n threads busy we need 2*n lineBuffers.
+    //
+
+    lineBuffers.resize (max (1, 2 * numThreads));
+    for (size_t i = 0; i < lineBuffers.size(); i++)
+        lineBuffers[i] = 0;
+}
+
+
+DeepScanLineOutputFile::Data::~Data ()
+{
+    for (size_t i = 0; i < lineBuffers.size(); i++)
+        if (lineBuffers[i] != 0)
+            delete lineBuffers[i];
+
+    for (size_t i = 0; i < slices.size(); i++)
+        delete slices[i];
+}
+
+
+int&
+DeepScanLineOutputFile::Data::getSampleCount(int x, int y)
+{
+    return sampleCount(sampleCountSliceBase,
+                       sampleCountXStride,
+                       sampleCountYStride,
+                       x, y);
+}
+
+
+LineBuffer*
+DeepScanLineOutputFile::Data::getLineBuffer (int number)
+{
+    return lineBuffers[number % lineBuffers.size()];
+}
+
+
+namespace {
+
+Int64
+writeLineOffsets (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, const vector<Int64> &lineOffsets)
+{
+    Int64 pos = os.tellp();
+
+    if (pos == -1)
+        IEX_NAMESPACE::throwErrnoExc ("Cannot determine current file position (%T).");
+
+    for (unsigned int i = 0; i < lineOffsets.size(); i++)
+        OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (os, lineOffsets[i]);
+
+    return pos;
+}
+
+
+void
+writePixelData (OutputStreamMutex *filedata,
+                DeepScanLineOutputFile::Data *partdata,
+                int lineBufferMinY,
+                const char pixelData[],
+                Int64 packedDataSize,
+                Int64 unpackedDataSize,
+                const char sampleCountTableData[],
+                Int64 sampleCountTableSize)
+{
+    //
+    // Store a block of pixel data in the output file, and try
+    // to keep track of the current writing position the file
+    // without calling tellp() (tellp() can be fairly expensive).
+    //
+
+    Int64 currentPosition = filedata->currentPosition;
+    filedata->currentPosition = 0;
+
+    if (currentPosition == 0)
+        currentPosition = filedata->os->tellp();
+
+    partdata->lineOffsets[(partdata->currentScanLine - partdata->minY) / partdata->linesInBuffer] =
+        currentPosition;
+
+    #ifdef DEBUG
+
+        assert (filedata->os->tellp() == currentPosition);
+
+    #endif
+
+    //
+    // Write the optional part number.
+    //
+
+    if (partdata->multipart)
+    {
+        OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*filedata->os, partdata->partNumber);
+    }
+
+    //
+    // Write the y coordinate of the first scanline in the chunk.
+    //
+
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*filedata->os, lineBufferMinY);
+
+    //
+    // Write the packed size of the pixel sample count table.
+    //
+
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*filedata->os, sampleCountTableSize);
+
+    //
+    // Write the packed pixel data size.
+    //
+
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*filedata->os, packedDataSize);
+
+    //
+    // Write the unpacked pixel data size.
+    //
+
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*filedata->os, unpackedDataSize);
+
+    //
+    // Write the packed pixel sample count table.
+    //
+
+    filedata->os->write (sampleCountTableData, sampleCountTableSize);
+
+    //
+    // Write the compressed data.
+    //
+
+    filedata->os->write (pixelData, packedDataSize);
+
+    //
+    // Update stream position.
+    //
+
+    filedata->currentPosition = currentPosition      +
+                                Xdr::size<int>()     +  // y coordinate
+                                Xdr::size<Int64>()   +  // packed sample count table size
+                                Xdr::size<Int64>()   +  // packed data size
+                                Xdr::size<Int64>()   +  // unpacked data size
+                                sampleCountTableSize +  // pixel sample count table
+                                packedDataSize;         // pixel data
+
+    if (partdata->multipart)
+    {
+        filedata->currentPosition += Xdr::size<int>();  // optional part number
+    }
+}
+
+
+inline void
+writePixelData (OutputStreamMutex* filedata,
+                DeepScanLineOutputFile::Data *partdata,
+                const LineBuffer *lineBuffer)
+{
+    writePixelData (filedata, partdata,
+                    lineBuffer->minY,
+                    lineBuffer->dataPtr,
+                    lineBuffer->dataSize,
+                    lineBuffer->uncompressedDataSize,
+                    lineBuffer->sampleCountTablePtr,
+                    lineBuffer->sampleCountTableSize);
+}
+
+
+void
+convertToXdr (DeepScanLineOutputFile::Data *ofd,
+              Array<char> &lineBuffer,
+              int lineBufferMinY,
+              int lineBufferMaxY,
+              int inSize)
+{
+    //
+    // Convert the contents of a lineBuffer from the machine's native
+    // representation to Xdr format.  This function is called by
+    // CompressLineBuffer::execute(), below, if the compressor wanted
+    // its input pixel data in the machine's native format, but then
+    // failed to compress the data (most compressors will expand rather
+    // than compress random input data).
+    //
+    // Note that this routine assumes that the machine's native
+    // representation of the pixel data has the same size as the
+    // Xdr representation.  This makes it possible to convert the
+    // pixel data in place, without an intermediate temporary buffer.
+    //
+
+    //
+    // Iterate over all scanlines in the lineBuffer to convert.
+    //
+
+    char* writePtr = &lineBuffer[0];
+    for (int y = lineBufferMinY; y <= lineBufferMaxY; y++)
+    {
+        //
+        // Set these to point to the start of line y.
+        // We will write to writePtr from readPtr.
+        //
+
+        const char *readPtr = writePtr;
+
+        //
+        // Iterate over all slices in the file.
+        //
+
+        for (unsigned int i = 0; i < ofd->slices.size(); ++i)
+        {
+            //
+            // Test if scan line y of this channel is
+            // contains any data (the scan line contains
+            // data only if y % ySampling == 0).
+            //
+
+            const OutSliceInfo &slice = *ofd->slices[i];
+
+            if (modp (y, slice.ySampling) != 0)
+                continue;
+
+            //
+            // Find the number of sampled pixels, dMaxX-dMinX+1, for
+            // slice i in scan line y (i.e. pixels within the data window
+            // for which x % xSampling == 0).
+            //
+
+            int xSampleCount = ofd->lineSampleCount[y - ofd->minY];
+
+            //
+            // Convert the samples in place.
+            //
+
+            convertInPlace (writePtr, readPtr, slice.type, xSampleCount);
+        }
+    }
+}
+
+
+//
+// A LineBufferTask encapsulates the task of copying a set of scanlines
+// from the user's frame buffer into a LineBuffer object, compressing
+// the data if necessary.
+//
+
+class LineBufferTask: public Task
+{
+  public:
+
+    LineBufferTask (TaskGroup *group,
+                    DeepScanLineOutputFile::Data *ofd,
+                    int number,
+                    int scanLineMin,
+                    int scanLineMax);
+
+    virtual ~LineBufferTask ();
+
+    virtual void        execute ();
+
+  private:
+
+    DeepScanLineOutputFile::Data *  _ofd;
+    LineBuffer *        _lineBuffer;
+};
+
+
+LineBufferTask::LineBufferTask
+    (TaskGroup *group,
+     DeepScanLineOutputFile::Data *ofd,
+     int number,
+     int scanLineMin,
+     int scanLineMax)
+:
+    Task (group),
+    _ofd (ofd),
+    _lineBuffer (_ofd->getLineBuffer(number))
+{
+    //
+    // Wait for the lineBuffer to become available
+    //
+
+    _lineBuffer->wait ();
+
+    //
+    // Initialize the lineBuffer data if necessary
+    //
+
+    if (!_lineBuffer->partiallyFull)
+    {
+
+        _lineBuffer->minY = _ofd->minY + number * _ofd->linesInBuffer;
+
+        _lineBuffer->maxY = min (_lineBuffer->minY + _ofd->linesInBuffer - 1,
+                                 _ofd->maxY);
+
+        _lineBuffer->partiallyFull = true;
+    }
+
+    _lineBuffer->scanLineMin = max (_lineBuffer->minY, scanLineMin);
+    _lineBuffer->scanLineMax = min (_lineBuffer->maxY, scanLineMax);
+}
+
+
+LineBufferTask::~LineBufferTask ()
+{
+    //
+    // Signal that the line buffer is now free
+    //
+
+    _lineBuffer->post ();
+}
+
+
+void
+LineBufferTask::execute ()
+{
+    try
+    {
+        //
+        // First copy the pixel data from the
+        // frame buffer into the line buffer
+        //
+
+        int yStart, yStop, dy;
+
+        if (_ofd->lineOrder == INCREASING_Y)
+        {
+            yStart = _lineBuffer->scanLineMin;
+            yStop = _lineBuffer->scanLineMax + 1;
+            dy = 1;
+        }
+        else
+        {
+            yStart = _lineBuffer->scanLineMax;
+            yStop = _lineBuffer->scanLineMin - 1;
+            dy = -1;
+        }
+
+        //
+        // Allocate buffers for scanlines.
+        // And calculate the sample counts for each line.
+        //
+
+        bytesPerDeepLineTable (_ofd->header,
+                               _lineBuffer->scanLineMin,
+                               _lineBuffer->scanLineMax,
+                               _ofd->sampleCountSliceBase,
+                               _ofd->sampleCountXStride,
+                               _ofd->sampleCountYStride,
+                               _ofd->bytesPerLine);
+        for (int i = _lineBuffer->scanLineMin; i <= _lineBuffer->scanLineMax; i++)
+        {
+            // (TODO) don't do this all the time.
+            _lineBuffer->buffer[i - _lineBuffer->minY].resizeErase(
+                            _ofd->bytesPerLine[i - _ofd->minY]);
+
+            for (int j = _ofd->minX; j <= _ofd->maxX; j++)
+                _ofd->lineSampleCount[i - _ofd->minY] += _ofd->getSampleCount(j, i);
+        }
+
+        //
+        // Copy data from frame buffer to line buffer.
+        //
+
+        int y;
+
+        for (y = yStart; y != yStop; y += dy)
+        {
+            //
+            // Gather one scan line's worth of pixel data and store
+            // them in _ofd->lineBuffer.
+            //
+
+            char *writePtr = &_lineBuffer->buffer[y - _lineBuffer->minY][0];
+            //
+            // Iterate over all image channels.
+            //
+
+            for (unsigned int i = 0; i < _ofd->slices.size(); ++i)
+            {
+                //
+                // Test if scan line y of this channel contains any data
+                // (the scan line contains data only if y % ySampling == 0).
+                //
+
+                const OutSliceInfo &slice = *_ofd->slices[i];
+
+                if (modp (y, slice.ySampling) != 0)
+                    continue;
+
+                //
+                // Fill the line buffer with with pixel data.
+                //
+
+                if (slice.zero)
+                {
+                    //
+                    // The frame buffer contains no data for this channel.
+                    // Store zeroes in _lineBuffer->buffer.
+                    //
+
+                    fillChannelWithZeroes (writePtr, _ofd->format, slice.type,
+                                           _ofd->lineSampleCount[y - _ofd->minY]);
+                }
+                else
+                {
+
+                    copyFromDeepFrameBuffer (writePtr, slice.base,
+                                             _ofd->sampleCountSliceBase,
+                                             _ofd->sampleCountXStride,
+                                             _ofd->sampleCountYStride,
+                                             y, _ofd->minX, _ofd->maxX,
+                                             0, 0,//offsets for samplecount
+                                             0, 0,//offsets for data
+                                             slice.sampleStride, 
+                                             slice.xStride,
+                                             slice.yStride,
+                                             _ofd->format,
+                                             slice.type);
+                }
+            }
+        }
+
+        //
+        // If the next scanline isn't past the bounds of the lineBuffer
+        // then we have partially filled the linebuffer,
+        // otherwise the whole linebuffer is filled and then
+        // we compress the linebuffer and write it out.
+        //
+
+        if (y >= _lineBuffer->minY && y <= _lineBuffer->maxY)
+            return;
+
+        //
+        // Copy all data into a consecutive buffer.
+        //
+
+        Int64 totalBytes = 0;
+        Int64 maxBytesPerLine = 0;
+        for (int i = 0; i < _lineBuffer->maxY - _lineBuffer->minY + 1; i++)
+        {
+            totalBytes += _lineBuffer->buffer[i].size();
+            if (Int64(_lineBuffer->buffer[i].size()) > maxBytesPerLine)
+                maxBytesPerLine = _lineBuffer->buffer[i].size();
+        }
+        _lineBuffer->consecutiveBuffer.resizeErase(totalBytes);
+
+        int pos = 0;
+        for (int i = 0; i < _lineBuffer->maxY - _lineBuffer->minY + 1; i++)
+        {
+            memcpy(_lineBuffer->consecutiveBuffer + pos,
+                   &_lineBuffer->buffer[i][0],
+                   _lineBuffer->buffer[i].size());
+            pos += _lineBuffer->buffer[i].size();
+        }
+
+        _lineBuffer->dataPtr = _lineBuffer->consecutiveBuffer;
+
+        _lineBuffer->dataSize = totalBytes;
+        _lineBuffer->uncompressedDataSize = _lineBuffer->dataSize;
+
+        //
+        // Compress the pixel sample count table.
+        //
+
+        char* ptr = _lineBuffer->sampleCountTableBuffer;
+        Int64 tableDataSize = 0;
+        for (int i = _lineBuffer->minY; i <= _lineBuffer->maxY; i++)
+        {
+            int count = 0;
+            for (int j = _ofd->minX; j <= _ofd->maxX; j++)
+            {
+                count += _ofd->getSampleCount(j, i);
+                Xdr::write <CharPtrIO> (ptr, count);
+                tableDataSize += sizeof (int);
+            }
+        }
+
+       if(_lineBuffer->sampleCountTableCompressor)
+       {
+          _lineBuffer->sampleCountTableSize =
+                  _lineBuffer->sampleCountTableCompressor->compress (
+                                                      _lineBuffer->sampleCountTableBuffer,
+                                                      tableDataSize,
+                                                      _lineBuffer->minY,
+                                                      _lineBuffer->sampleCountTablePtr);
+       }
+
+        //
+        // If we can't make data shrink (or we weren't compressing), then just use the raw data.
+        //
+
+        if (!_lineBuffer->sampleCountTableCompressor || 
+            _lineBuffer->sampleCountTableSize >= tableDataSize)
+        {
+            _lineBuffer->sampleCountTableSize = tableDataSize;
+            _lineBuffer->sampleCountTablePtr = _lineBuffer->sampleCountTableBuffer;
+        }
+
+        //
+        // Compress the sample data
+        //
+
+        // (TODO) don't do this all the time.
+        if (_lineBuffer->compressor != 0)
+            delete _lineBuffer->compressor;
+        _lineBuffer->compressor = newCompressor (_ofd->header.compression(),
+                                                 maxBytesPerLine,
+                                                 _ofd->header);
+
+        Compressor *compressor = _lineBuffer->compressor;
+
+        if (compressor)
+        {
+            const char *compPtr;
+
+            Int64 compSize = compressor->compress (_lineBuffer->dataPtr,
+                                                 _lineBuffer->dataSize,
+                                                 _lineBuffer->minY, compPtr);
+
+            if (compSize < _lineBuffer->dataSize)
+            {
+                _lineBuffer->dataSize = compSize;
+                _lineBuffer->dataPtr = compPtr;
+            }
+            else if (_ofd->format == Compressor::NATIVE)
+            {
+                //
+                // The data did not shrink during compression, but
+                // we cannot write to the file using the machine's
+                // native format, so we need to convert the lineBuffer
+                // to Xdr.
+                //
+
+                convertToXdr (_ofd, _lineBuffer->consecutiveBuffer, _lineBuffer->minY,
+                              _lineBuffer->maxY, _lineBuffer->dataSize);
+            }
+        }
+
+        _lineBuffer->partiallyFull = false;
+    }
+    catch (std::exception &e)
+    {
+        if (!_lineBuffer->hasException)
+        {
+            _lineBuffer->exception = e.what ();
+            _lineBuffer->hasException = true;
+        }
+    }
+    catch (...)
+    {
+        if (!_lineBuffer->hasException)
+        {
+            _lineBuffer->exception = "unrecognized exception";
+            _lineBuffer->hasException = true;
+        }
+    }
+}
+
+} // namespace
+
+
+DeepScanLineOutputFile::DeepScanLineOutputFile
+    (const char fileName[],
+     const Header &header,
+     int numThreads)
+:
+    _data (new Data (numThreads))
+{
+    _data->_streamData=new OutputStreamMutex ();
+    _data->_deleteStream=true;
+    try
+    {
+        header.sanityCheck();
+        _data->_streamData->os = new StdOFStream (fileName);
+        initialize (header);
+        _data->_streamData->currentPosition = _data->_streamData->os->tellp();
+
+        // Write header and empty offset table to the file.
+        writeMagicNumberAndVersionField(*_data->_streamData->os, _data->header);
+        _data->previewPosition =
+                _data->header.writeTo (*_data->_streamData->os);
+        _data->lineOffsetsPosition =
+                writeLineOffsets (*_data->_streamData->os, _data->lineOffsets);
+	_data->multipart=false;// not multipart; only one header
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        delete _data->_streamData;
+        delete _data;
+
+        REPLACE_EXC (e, "Cannot open image file "
+                        "\"" << fileName << "\". " << e);
+        throw;
+    }
+    catch (...)
+    {
+        delete _data->_streamData;
+        delete _data;
+        throw;
+    }
+}
+
+
+DeepScanLineOutputFile::DeepScanLineOutputFile
+    (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
+     const Header &header,
+     int numThreads)
+:
+    _data (new Data (numThreads))
+    
+{
+    _data->_streamData   = new OutputStreamMutex ();
+    _data->_deleteStream = false;
+    try
+    {
+        header.sanityCheck();
+        _data->_streamData->os = &os;
+        initialize (header);
+        _data->_streamData->currentPosition = _data->_streamData->os->tellp();
+
+        // Write header and empty offset table to the file.
+        writeMagicNumberAndVersionField(*_data->_streamData->os, _data->header);
+        _data->previewPosition =
+                _data->header.writeTo (*_data->_streamData->os);
+        _data->lineOffsetsPosition =
+                writeLineOffsets (*_data->_streamData->os, _data->lineOffsets);
+	_data->multipart=false;
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        delete _data->_streamData;
+        delete _data;
+
+        REPLACE_EXC (e, "Cannot open image file "
+                        "\"" << os.fileName() << "\". " << e);
+        throw;
+    }
+    catch (...)
+    {
+        delete _data->_streamData;
+        delete _data;
+        throw;
+    }
+}
+
+DeepScanLineOutputFile::DeepScanLineOutputFile(const OutputPartData* part)
+{
+    try
+    {
+        if (part->header.type() != DEEPSCANLINE)
+            throw IEX_NAMESPACE::ArgExc("Can't build a DeepScanLineOutputFile from a type-mismatched part.");
+
+        _data = new Data (part->numThreads);
+        _data->_streamData = part->mutex;
+        _data->_deleteStream=false;
+        initialize (part->header);
+        _data->partNumber = part->partNumber;
+        _data->lineOffsetsPosition = part->chunkOffsetTablePosition;
+        _data->previewPosition = part->previewPosition;
+	_data->multipart=part->multipart;
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        delete _data;
+
+        REPLACE_EXC (e, "Cannot initialize output part "
+                        "\"" << part->partNumber << "\". " << e);
+        throw;
+    }
+    catch (...)
+    {
+        delete _data;
+        throw;
+    }
+}
+
+void
+DeepScanLineOutputFile::initialize (const Header &header)
+{
+    _data->header = header;
+
+    _data->header.setType(DEEPSCANLINE);
+    
+    const Box2i &dataWindow = header.dataWindow();
+
+    _data->currentScanLine = (header.lineOrder() == INCREASING_Y)?
+                                 dataWindow.min.y: dataWindow.max.y;
+
+    _data->missingScanLines = dataWindow.max.y - dataWindow.min.y + 1;
+    _data->lineOrder = header.lineOrder();
+    _data->minX = dataWindow.min.x;
+    _data->maxX = dataWindow.max.x;
+    _data->minY = dataWindow.min.y;
+    _data->maxY = dataWindow.max.y;
+
+    _data->lineSampleCount.resizeErase(_data->maxY - _data->minY + 1);
+
+    Compressor* compressor = newCompressor (_data->header.compression(),
+                                            0,
+                                            _data->header);
+    _data->format = defaultFormat (compressor);
+    _data->linesInBuffer = numLinesInBuffer (compressor);
+    if (compressor != 0)
+        delete compressor;
+
+    int lineOffsetSize = (_data->maxY - _data->minY +
+                          _data->linesInBuffer) / _data->linesInBuffer;
+
+
+    _data->header.setChunkCount(lineOffsetSize);
+
+    _data->lineOffsets.resize (lineOffsetSize);
+
+    _data->bytesPerLine.resize (_data->maxY - _data->minY + 1);
+
+    _data->maxSampleCountTableSize = min(_data->linesInBuffer, _data->maxY - _data->minY + 1) *
+                                     (_data->maxX - _data->minX + 1) *
+                                     sizeof(unsigned int);
+
+    for (size_t i = 0; i < _data->lineBuffers.size(); ++i)
+    {
+        _data->lineBuffers[i] = new LineBuffer (_data->linesInBuffer);
+        _data->lineBuffers[i]->sampleCountTableBuffer.resizeErase(_data->maxSampleCountTableSize);
+
+        _data->lineBuffers[i]->sampleCountTableCompressor =
+        newCompressor (_data->header.compression(),
+                               _data->maxSampleCountTableSize,
+                               _data->header);
+    }
+}
+
+
+DeepScanLineOutputFile::~DeepScanLineOutputFile ()
+{
+    {
+        Lock lock(*_data->_streamData);
+        Int64 originalPosition = _data->_streamData->os->tellp();
+
+        if (_data->lineOffsetsPosition > 0)
+        {
+            try
+            {
+                _data->_streamData->os->seekp (_data->lineOffsetsPosition);
+                writeLineOffsets (*_data->_streamData->os, _data->lineOffsets);
+
+                //
+                // Restore the original position.
+                //
+                _data->_streamData->os->seekp (originalPosition);
+            }
+            catch (...)
+            {
+                //
+                // We cannot safely throw any exceptions from here.
+                // This destructor may have been called because the
+                // stack is currently being unwound for another
+                // exception.
+                //
+            }
+        }
+    }
+
+    if (_data->_deleteStream)
+        delete _data->_streamData->os;
+
+    //
+    // (TODO) we should have a way to tell if the stream data is owned by this file or
+    // by a parent multipart file.
+    //
+
+    if (_data->partNumber == -1)
+        delete _data->_streamData;
+
+    delete _data;
+}
+
+
+const char *
+DeepScanLineOutputFile::fileName () const
+{
+    return _data->_streamData->os->fileName();
+}
+
+
+const Header &
+DeepScanLineOutputFile::header () const
+{
+    return _data->header;
+}
+
+
+void
+DeepScanLineOutputFile::setFrameBuffer (const DeepFrameBuffer &frameBuffer)
+{
+    Lock lock (*_data->_streamData);
+
+    //
+    // Check if the new frame buffer descriptor
+    // is compatible with the image file header.
+    //
+
+    const ChannelList &channels = _data->header.channels();
+
+    for (ChannelList::ConstIterator i = channels.begin();
+         i != channels.end();
+         ++i)
+    {
+        DeepFrameBuffer::ConstIterator j = frameBuffer.find (i.name());
+
+        if (j == frameBuffer.end())
+            continue;
+
+        if (i.channel().type != j.slice().type)
+        {
+            THROW (IEX_NAMESPACE::ArgExc, "Pixel type of \"" << i.name() << "\" channel "
+                                "of output file \"" << fileName() << "\" is "
+                                "not compatible with the frame buffer's "
+                                "pixel type.");
+        }
+
+        if (i.channel().xSampling != j.slice().xSampling ||
+            i.channel().ySampling != j.slice().ySampling)
+        {
+            THROW (IEX_NAMESPACE::ArgExc, "X and/or y subsampling factors "
+                                "of \"" << i.name() << "\" channel "
+                                "of output file \"" << fileName() << "\" are "
+                                "not compatible with the frame buffer's "
+                                "subsampling factors.");
+        }
+    }
+
+    //
+    // Store the pixel sample count table.
+    // (TODO) Support for different sampling rates?
+    //
+
+    const Slice& sampleCountSlice = frameBuffer.getSampleCountSlice();
+    if (sampleCountSlice.base == 0)
+    {
+        throw IEX_NAMESPACE::ArgExc ("Invalid base pointer, please set a proper sample count slice.");
+    }
+    else
+    {
+        _data->sampleCountSliceBase = sampleCountSlice.base;
+        _data->sampleCountXStride = sampleCountSlice.xStride;
+        _data->sampleCountYStride = sampleCountSlice.yStride;
+    }
+
+    //
+    // Initialize slice table for writePixels().
+    // Pixel sample count slice is not presented in the header,
+    // so it wouldn't be added here.
+    // Store the pixel base pointer table.
+    // (TODO) Support for different sampling rates?
+    //
+
+    vector<OutSliceInfo*> slices;
+
+    for (ChannelList::ConstIterator i = channels.begin();
+         i != channels.end();
+         ++i)
+    {
+        DeepFrameBuffer::ConstIterator j = frameBuffer.find (i.name());
+
+        if (j == frameBuffer.end())
+        {
+            //
+            // Channel i is not present in the frame buffer.
+            // In the file, channel i will contain only zeroes.
+            //
+
+            slices.push_back (new OutSliceInfo (i.channel().type,
+                                                NULL,// base
+                                                0,// sampleStride,
+                                                0,// xStride
+                                                0,// yStride
+                                                i.channel().xSampling,
+                                                i.channel().ySampling,
+                                                true)); // zero
+        }
+        else
+        {
+            //
+            // Channel i is present in the frame buffer.
+            //
+
+            slices.push_back (new OutSliceInfo (j.slice().type,
+                                                j.slice().base,                      
+                                                j.slice().sampleStride,
+                                                j.slice().xStride,
+                                                j.slice().yStride,
+                                                j.slice().xSampling,
+                                                j.slice().ySampling,
+                                                false)); // zero
+
+        }
+    }
+
+    //
+    // Store the new frame buffer.
+    //
+
+    _data->frameBuffer = frameBuffer;
+
+    for (size_t i = 0; i < _data->slices.size(); i++)
+        delete _data->slices[i];
+    _data->slices = slices;
+}
+
+
+const DeepFrameBuffer &
+DeepScanLineOutputFile::frameBuffer () const
+{
+    Lock lock (*_data->_streamData);
+    return _data->frameBuffer;
+}
+
+
+void
+DeepScanLineOutputFile::writePixels (int numScanLines)
+{
+    try
+    {
+        Lock lock (*_data->_streamData);
+
+        if (_data->slices.size() == 0)
+            throw IEX_NAMESPACE::ArgExc ("No frame buffer specified "
+                               "as pixel data source.");
+
+        //
+        // Maintain two iterators:
+        //     nextWriteBuffer: next linebuffer to be written to the file
+        //     nextCompressBuffer: next linebuffer to compress
+        //
+
+        int first = (_data->currentScanLine - _data->minY) /
+                         _data->linesInBuffer;
+
+        int nextWriteBuffer = first;
+        int nextCompressBuffer;
+        int stop;
+        int step;
+        int scanLineMin;
+        int scanLineMax;
+
+        {
+            //
+            // Create a task group for all line buffer tasks. When the
+            // taskgroup goes out of scope, the destructor waits until
+            // all tasks are complete.
+            //
+
+            TaskGroup taskGroup;
+
+            //
+            // Determine the range of lineBuffers that intersect the scan
+            // line range.  Then add the initial compression tasks to the
+            // thread pool.  We always add in at least one task but the
+            // individual task might not do anything if numScanLines == 0.
+            //
+
+            if (_data->lineOrder == INCREASING_Y)
+            {
+                int last = (_data->currentScanLine + (numScanLines - 1) -
+                            _data->minY) / _data->linesInBuffer;
+
+                scanLineMin = _data->currentScanLine;
+                scanLineMax = _data->currentScanLine + numScanLines - 1;
+
+                int numTasks = max (min ((int)_data->lineBuffers.size(),
+                                         last - first + 1),
+                                    1);
+
+                for (int i = 0; i < numTasks; i++)
+                {
+                    ThreadPool::addGlobalTask
+                        (new LineBufferTask (&taskGroup, _data, first + i,
+                                             scanLineMin, scanLineMax));
+                }
+
+                nextCompressBuffer = first + numTasks;
+                stop = last + 1;
+                step = 1;
+            }
+            else
+            {
+                int last = (_data->currentScanLine - (numScanLines - 1) -
+                            _data->minY) / _data->linesInBuffer;
+
+                scanLineMax = _data->currentScanLine;
+                scanLineMin = _data->currentScanLine - numScanLines + 1;
+
+                int numTasks = max (min ((int)_data->lineBuffers.size(),
+                                         first - last + 1),
+                                    1);
+
+                for (int i = 0; i < numTasks; i++)
+                {
+                    ThreadPool::addGlobalTask
+                        (new LineBufferTask (&taskGroup, _data, first - i,
+                                             scanLineMin, scanLineMax));
+                }
+
+                nextCompressBuffer = first - numTasks;
+                stop = last - 1;
+                step = -1;
+            }
+
+            while (true)
+            {
+                if (_data->missingScanLines <= 0)
+                {
+                    throw IEX_NAMESPACE::ArgExc ("Tried to write more scan lines "
+                                       "than specified by the data window.");
+                }
+
+                //
+                // Wait until the next line buffer is ready to be written
+                //
+
+                LineBuffer *writeBuffer =
+                    _data->getLineBuffer (nextWriteBuffer);
+
+                writeBuffer->wait();
+
+                int numLines = writeBuffer->scanLineMax -
+                               writeBuffer->scanLineMin + 1;
+
+                _data->missingScanLines -= numLines;
+
+                //
+                // If the line buffer is only partially full, then it is
+                // not complete and we cannot write it to disk yet.
+                //
+
+                if (writeBuffer->partiallyFull)
+                {
+                    _data->currentScanLine = _data->currentScanLine +
+                                             step * numLines;
+                    writeBuffer->post();
+
+                    return;
+                }
+
+                //
+                // Write the line buffer
+                //
+
+                writePixelData (_data->_streamData, _data, writeBuffer);
+                nextWriteBuffer += step;
+
+                _data->currentScanLine = _data->currentScanLine +
+                                         step * numLines;
+
+                #ifdef DEBUG
+
+                    assert (_data->currentScanLine ==
+                            ((_data->lineOrder == INCREASING_Y) ?
+                             writeBuffer->scanLineMax + 1:
+                             writeBuffer->scanLineMin - 1));
+
+                #endif
+
+                //
+                // Release the lock on the line buffer
+                //
+
+                writeBuffer->post();
+
+                //
+                // If this was the last line buffer in the scanline range
+                //
+
+                if (nextWriteBuffer == stop)
+                    break;
+
+                //
+                // If there are no more line buffers to compress,
+                // then only continue to write out remaining lineBuffers
+                //
+
+                if (nextCompressBuffer == stop)
+                    continue;
+
+                //
+                // Add nextCompressBuffer as a compression task
+                //
+
+                ThreadPool::addGlobalTask
+                    (new LineBufferTask (&taskGroup, _data, nextCompressBuffer,
+                                         scanLineMin, scanLineMax));
+
+                //
+                // Update the next line buffer we need to compress
+                //
+
+                nextCompressBuffer += step;
+            }
+
+            //
+            // Finish all tasks
+            //
+        }
+
+        //
+        // Exeption handling:
+        //
+        // LineBufferTask::execute() may have encountered exceptions, but
+        // those exceptions occurred in another thread, not in the thread
+        // that is executing this call to OutputFile::writePixels().
+        // LineBufferTask::execute() has caught all exceptions and stored
+        // the exceptions' what() strings in the line buffers.
+        // Now we check if any line buffer contains a stored exception; if
+        // this is the case then we re-throw the exception in this thread.
+        // (It is possible that multiple line buffers contain stored
+        // exceptions.  We re-throw the first exception we find and
+        // ignore all others.)
+        //
+
+        const string *exception = 0;
+
+        for (size_t i = 0; i < _data->lineBuffers.size(); ++i)
+        {
+            LineBuffer *lineBuffer = _data->lineBuffers[i];
+
+            if (lineBuffer->hasException && !exception)
+                exception = &lineBuffer->exception;
+
+            lineBuffer->hasException = false;
+        }
+
+        if (exception)
+            throw IEX_NAMESPACE::IoExc (*exception);
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        REPLACE_EXC (e, "Failed to write pixel data to image "
+                        "file \"" << fileName() << "\". " << e);
+        throw;
+    }
+}
+
+
+int
+DeepScanLineOutputFile::currentScanLine () const
+{
+    Lock lock (*_data->_streamData);
+    return _data->currentScanLine;
+}
+
+
+void
+DeepScanLineOutputFile::copyPixels (DeepScanLineInputPart &in)
+{
+    copyPixels(*in.file);
+}
+
+void
+DeepScanLineOutputFile::copyPixels (DeepScanLineInputFile &in)
+{
+
+    Lock lock (*_data->_streamData);
+
+    //
+    // Check if this file's and and the InputFile's
+    // headers are compatible.
+    //
+
+    const Header &hdr = _data->header;
+    const Header &inHdr = in.header();
+
+    if(!inHdr.hasType() || inHdr.type()!=DEEPSCANLINE)
+    {
+        THROW (IEX_NAMESPACE::ArgExc, "Cannot copy pixels from image "
+                            "file \"" << in.fileName() << "\" to image "
+                            "file \"" << fileName() << "\": the input needs to be a deep scanline image");
+    }
+    if (!(hdr.dataWindow() == inHdr.dataWindow()))
+        THROW (IEX_NAMESPACE::ArgExc, "Cannot copy pixels from image "
+                            "file \"" << in.fileName() << "\" to image "
+                            "file \"" << fileName() << "\". "
+                            "The files have different data windows.");
+
+    if (!(hdr.lineOrder() == inHdr.lineOrder()))
+        THROW (IEX_NAMESPACE::ArgExc, "Quick pixel copy from image "
+                            "file \"" << in.fileName() << "\" to image "
+                            "file \"" << fileName() << "\" failed. "
+                            "The files have different line orders.");
+
+    if (!(hdr.compression() == inHdr.compression()))
+        THROW (IEX_NAMESPACE::ArgExc, "Quick pixel copy from image "
+                            "file \"" << in.fileName() << "\" to image "
+                            "file \"" << fileName() << "\" failed. "
+                            "The files use different compression methods.");
+
+    if (!(hdr.channels() == inHdr.channels()))
+        THROW (IEX_NAMESPACE::ArgExc, "Quick pixel copy from image "
+                            "file \"" << in.fileName() << "\" to image "
+                            "file \"" << fileName() << "\" failed.  "
+                            "The files have different channel lists.");
+
+    //
+    // Verify that no pixel data have been written to this file yet.
+    //
+
+    const Box2i &dataWindow = hdr.dataWindow();
+
+    if (_data->missingScanLines != dataWindow.max.y - dataWindow.min.y + 1)
+        THROW (IEX_NAMESPACE::LogicExc, "Quick pixel copy from image "
+                              "file \"" << in.fileName() << "\" to image "
+                              "file \"" << fileName() << "\" failed. "
+                              "\"" << fileName() << "\" already contains "
+                              "pixel data.");
+
+    //
+    // Copy the pixel data.
+    //
+
+    vector<char> data(4096);
+    
+    while (_data->missingScanLines > 0)
+    {
+        Int64 dataSize = (Int64) data.size();
+        in.rawPixelData(_data->currentScanLine, &data[0], dataSize);
+        if(dataSize > data.size())
+        {
+            // block wasn't big enough - go again with enough memory this time
+            data.resize(dataSize);
+            in.rawPixelData(_data->currentScanLine, &data[0], dataSize);
+        }
+
+        // extract header from block to pass to writePixelData
+        
+        Int64 packedSampleCountSize = *(Int64 *) (&data[4]);
+        Int64 packedDataSize = *(Int64 *) (&data[12]);
+        Int64 unpackedDataSize = *(Int64 *) (&data[20]);
+        const char * sampleCountTable = &data[0]+28;
+        const char * pixelData = sampleCountTable + packedSampleCountSize;
+        
+        
+        writePixelData (_data->_streamData, _data, lineBufferMinY (_data->currentScanLine,
+                                               _data->minY,
+                                               _data->linesInBuffer),
+                        pixelData, packedDataSize, unpackedDataSize,sampleCountTable,packedSampleCountSize);
+
+        _data->currentScanLine += (_data->lineOrder == INCREASING_Y)?
+                                   _data->linesInBuffer: -_data->linesInBuffer;
+
+        _data->missingScanLines -= _data->linesInBuffer;
+    }
+}
+
+
+void
+DeepScanLineOutputFile::updatePreviewImage (const PreviewRgba newPixels[])
+{
+    Lock lock (*_data->_streamData);
+
+    if (_data->previewPosition <= 0)
+        THROW (IEX_NAMESPACE::LogicExc, "Cannot update preview image pixels. "
+                              "File \"" << fileName() << "\" does not "
+                              "contain a preview image.");
+
+    //
+    // Store the new pixels in the header's preview image attribute.
+    //
+
+    PreviewImageAttribute &pia =
+        _data->header.typedAttribute <PreviewImageAttribute> ("preview");
+
+    PreviewImage &pi = pia.value();
+    PreviewRgba *pixels = pi.pixels();
+    int numPixels = pi.width() * pi.height();
+
+    for (int i = 0; i < numPixels; ++i)
+        pixels[i] = newPixels[i];
+
+    //
+    // Save the current file position, jump to the position in
+    // the file where the preview image starts, store the new
+    // preview image, and jump back to the saved file position.
+    //
+
+    Int64 savedPosition = _data->_streamData->os->tellp();
+
+    try
+    {
+        _data->_streamData->os->seekp (_data->previewPosition);
+        pia.writeValueTo (*_data->_streamData->os, _data->version);
+        _data->_streamData->os->seekp (savedPosition);
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        REPLACE_EXC (e, "Cannot update preview image pixels for "
+                        "file \"" << fileName() << "\". " << e);
+        throw;
+    }
+}
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfDeepScanLineOutputFile.h b/Source/OpenEXR/IlmImf/ImfDeepScanLineOutputFile.h
new file mode 100644
index 0000000..c823d7f
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfDeepScanLineOutputFile.h
@@ -0,0 +1,244 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef INCLUDED_IMF_DEEP_SCAN_LINE_OUTPUT_FILE_H
+#define INCLUDED_IMF_DEEP_SCAN_LINE_OUTPUT_FILE_H
+
+//-----------------------------------------------------------------------------
+//
+//      class DeepScanLineOutputFile
+//
+//-----------------------------------------------------------------------------
+
+#include "ImfHeader.h"
+#include "ImfFrameBuffer.h"
+#include "ImfThreading.h"
+#include "ImfGenericOutputFile.h"
+#include "ImfNamespace.h"
+#include "ImfForward.h"
+#include "ImfExport.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+
+struct PreviewRgba;
+
+class IMF_EXPORT DeepScanLineOutputFile : public GenericOutputFile
+{
+  public:
+
+    //-----------------------------------------------------------
+    // Constructor -- opens the file and writes the file header.
+    // The file header is also copied into the DeepScanLineOutputFile
+    // object, and can later be accessed via the header() method.
+    // Destroying this DeepScanLineOutputFile object automatically closes
+    // the file.
+    //
+    // numThreads determines the number of threads that will be
+    // used to write the file (see ImfThreading.h).
+    //-----------------------------------------------------------
+
+    DeepScanLineOutputFile (const char fileName[], const Header &header,
+                int numThreads = globalThreadCount());
+
+
+    //------------------------------------------------------------
+    // Constructor -- attaches the new DeepScanLineOutputFile object
+    // to a file that has already been opened, and writes the file header.
+    // The file header is also copied into the DeepScanLineOutputFile
+    // object, and can later be accessed via the header() method.
+    // Destroying this DeepScanLineOutputFile object does not automatically
+    // close the file.
+    //
+    // numThreads determines the number of threads that will be
+    // used to write the file (see ImfThreading.h).
+    //------------------------------------------------------------
+
+    DeepScanLineOutputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, const Header &header,
+                int numThreads = globalThreadCount());
+
+
+    //-------------------------------------------------
+    // Destructor
+    //
+    // Destroying the DeepScanLineOutputFile object
+    // before writing all scan lines within the data
+    // window results in an incomplete file.
+    //-------------------------------------------------
+
+    virtual ~DeepScanLineOutputFile ();
+
+
+    //------------------------
+    // Access to the file name
+    //------------------------
+
+    const char *        fileName () const;
+
+
+    //--------------------------
+    // Access to the file header
+    //--------------------------
+
+    const Header &      header () const;
+
+
+    //-------------------------------------------------------
+    // Set the current frame buffer -- copies the FrameBuffer
+    // object into the OutputFile object.
+    //
+    // The current frame buffer is the source of the pixel
+    // data written to the file.  The current frame buffer
+    // must be set at least once before writePixels() is
+    // called.  The current frame buffer can be changed
+    // after each call to writePixels.
+    //-------------------------------------------------------
+
+    void                setFrameBuffer (const DeepFrameBuffer &frameBuffer);
+
+
+    //-----------------------------------
+    // Access to the current frame buffer
+    //-----------------------------------
+
+    const DeepFrameBuffer & frameBuffer () const;
+
+
+    //-------------------------------------------------------------------
+    // Write pixel data:
+    //
+    // writePixels(n) retrieves the next n scan lines worth of data from
+    // the current frame buffer, starting with the scan line indicated by
+    // currentScanLine(), and stores the data in the output file, and
+    // progressing in the direction indicated by header.lineOrder().
+    //
+    // To produce a complete and correct file, exactly m scan lines must
+    // be written, where m is equal to
+    // header().dataWindow().max.y - header().dataWindow().min.y + 1.
+    //-------------------------------------------------------------------
+
+    void                writePixels (int numScanLines = 1);
+
+
+    //------------------------------------------------------------------
+    // Access to the current scan line:
+    //
+    // currentScanLine() returns the y coordinate of the first scan line
+    // that will be read from the current frame buffer during the next
+    // call to writePixels().
+    //
+    // If header.lineOrder() == INCREASING_Y:
+    //
+    //  The current scan line before the first call to writePixels()
+    //  is header().dataWindow().min.y.  After writing each scan line,
+    //  the current scan line is incremented by 1.
+    //
+    // If header.lineOrder() == DECREASING_Y:
+    //
+    //  The current scan line before the first call to writePixels()
+    //  is header().dataWindow().max.y.  After writing each scan line,
+    //  the current scan line is decremented by 1.
+    //
+    //------------------------------------------------------------------
+
+    int                 currentScanLine () const;
+
+
+    //--------------------------------------------------------------
+    // Shortcut to copy all pixels from an InputFile into this file,
+    // without uncompressing and then recompressing the pixel data.
+    // This file's header must be compatible with the InputFile's
+    // header:  The two header's "dataWindow", "compression",
+    // "lineOrder" and "channels" attributes must be the same.
+    //--------------------------------------------------------------
+
+    void                copyPixels (DeepScanLineInputFile &in);
+    
+    // --------------------------------------------------------------
+    // Shortcut to copy pixels from a given part of a multipart file
+    // --------------------------------------------------------------
+    void                copyPixels (DeepScanLineInputPart &in);
+
+
+    //--------------------------------------------------------------
+    // Updating the preview image:
+    //
+    // updatePreviewImage() supplies a new set of pixels for the
+    // preview image attribute in the file's header.  If the header
+    // does not contain a preview image, updatePreviewImage() throws
+    // an IEX_NAMESPACE::LogicExc.
+    //
+    // Note: updatePreviewImage() is necessary because images are
+    // often stored in a file incrementally, a few scan lines at a
+    // time, while the image is being generated.  Since the preview
+    // image is an attribute in the file's header, it gets stored in
+    // the file as soon as the file is opened, but we may not know
+    // what the preview image should look like until we have written
+    // the last scan line of the main image.
+    //
+    //--------------------------------------------------------------
+
+    void                updatePreviewImage (const PreviewRgba newPixels[]);
+
+
+    struct Data;
+
+  private:
+
+    //------------------------------------------------------------
+    // Constructor -- attaches the OutputStreamMutex to the
+    // given one from MultiPartOutputFile. Set the previewPosition
+    // and lineOffsetsPosition which have been acquired from
+    // the constructor of MultiPartOutputFile as well.
+    //------------------------------------------------------------
+    DeepScanLineOutputFile (const OutputPartData* part);
+
+    DeepScanLineOutputFile (const DeepScanLineOutputFile &);                    // not implemented
+    DeepScanLineOutputFile & operator = (const DeepScanLineOutputFile &);       // not implemented
+
+    void                initialize (const Header &header);
+    void                initializeLineBuffer();
+
+    Data *              _data;
+
+
+
+    friend class MultiPartOutputFile;
+};
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif
diff --git a/Source/OpenEXR/IlmImf/ImfDeepScanLineOutputPart.cpp b/Source/OpenEXR/IlmImf/ImfDeepScanLineOutputPart.cpp
new file mode 100644
index 0000000..d7a44e8
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfDeepScanLineOutputPart.cpp
@@ -0,0 +1,107 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#include "ImfDeepScanLineOutputPart.h"
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+DeepScanLineOutputPart::DeepScanLineOutputPart(MultiPartOutputFile& multiPartFile, int partNumber)
+{
+    file = multiPartFile.getOutputPart<DeepScanLineOutputFile>(partNumber);
+}
+
+
+const char *
+DeepScanLineOutputPart::fileName () const
+{
+    return file->fileName();
+}
+
+
+const Header &
+DeepScanLineOutputPart::header () const
+{
+    return file->header();
+}
+
+
+void
+DeepScanLineOutputPart::setFrameBuffer (const DeepFrameBuffer &frameBuffer)
+{
+    file->setFrameBuffer(frameBuffer);
+}
+
+
+const DeepFrameBuffer &
+DeepScanLineOutputPart::frameBuffer () const
+{
+    return file->frameBuffer();
+}
+
+
+void
+DeepScanLineOutputPart::writePixels (int numScanLines)
+{
+    file->writePixels(numScanLines);
+}
+
+
+int
+DeepScanLineOutputPart::currentScanLine () const
+{
+    return file->currentScanLine();
+}
+
+
+void
+DeepScanLineOutputPart::copyPixels (DeepScanLineInputFile &in)
+{
+    file->copyPixels(in);
+}
+
+void
+DeepScanLineOutputPart::copyPixels (DeepScanLineInputPart &in)
+{
+    file->copyPixels(in);
+}
+
+void
+DeepScanLineOutputPart::updatePreviewImage (const PreviewRgba newPixels[])
+{
+    file->updatePreviewImage(newPixels);
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
+
diff --git a/Source/OpenEXR/IlmImf/ImfDeepScanLineOutputPart.h b/Source/OpenEXR/IlmImf/ImfDeepScanLineOutputPart.h
new file mode 100644
index 0000000..05410f3
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfDeepScanLineOutputPart.h
@@ -0,0 +1,168 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef IMFDEEPSCANLINEOUTPUTPART_H_
+#define IMFDEEPSCANLINEOUTPUTPART_H_
+
+#include "ImfDeepScanLineOutputFile.h"
+#include "ImfMultiPartOutputFile.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+class IMF_EXPORT DeepScanLineOutputPart
+{
+  public:
+
+    DeepScanLineOutputPart(MultiPartOutputFile& multiPartFile, int partNumber);
+
+    //------------------------
+    // Access to the file name
+    //------------------------
+
+    const char *        fileName () const;
+
+
+    //--------------------------
+    // Access to the file header
+    //--------------------------
+
+    const Header &      header () const;
+
+
+    //-------------------------------------------------------
+    // Set the current frame buffer -- copies the FrameBuffer
+    // object into the OutputFile object.
+    //
+    // The current frame buffer is the source of the pixel
+    // data written to the file.  The current frame buffer
+    // must be set at least once before writePixels() is
+    // called.  The current frame buffer can be changed
+    // after each call to writePixels.
+    //-------------------------------------------------------
+
+    void                setFrameBuffer (const DeepFrameBuffer &frameBuffer);
+
+
+    //-----------------------------------
+    // Access to the current frame buffer
+    //-----------------------------------
+
+    const DeepFrameBuffer & frameBuffer () const;
+
+
+    //-------------------------------------------------------------------
+    // Write pixel data:
+    //
+    // writePixels(n) retrieves the next n scan lines worth of data from
+    // the current frame buffer, starting with the scan line indicated by
+    // currentScanLine(), and stores the data in the output file, and
+    // progressing in the direction indicated by header.lineOrder().
+    //
+    // To produce a complete and correct file, exactly m scan lines must
+    // be written, where m is equal to
+    // header().dataWindow().max.y - header().dataWindow().min.y + 1.
+    //-------------------------------------------------------------------
+
+    void                writePixels (int numScanLines = 1);
+
+
+    //------------------------------------------------------------------
+    // Access to the current scan line:
+    //
+    // currentScanLine() returns the y coordinate of the first scan line
+    // that will be read from the current frame buffer during the next
+    // call to writePixels().
+    //
+    // If header.lineOrder() == INCREASING_Y:
+    //
+    //  The current scan line before the first call to writePixels()
+    //  is header().dataWindow().min.y.  After writing each scan line,
+    //  the current scan line is incremented by 1.
+    //
+    // If header.lineOrder() == DECREASING_Y:
+    //
+    //  The current scan line before the first call to writePixels()
+    //  is header().dataWindow().max.y.  After writing each scan line,
+    //  the current scan line is decremented by 1.
+    //
+    //------------------------------------------------------------------
+
+    int                 currentScanLine () const;
+
+
+    //--------------------------------------------------------------
+    // Shortcut to copy all pixels from an InputFile into this file,
+    // without uncompressing and then recompressing the pixel data.
+    // This file's header must be compatible with the InputFile's
+    // header:  The two header's "dataWindow", "compression",
+    // "lineOrder" and "channels" attributes must be the same.
+    //--------------------------------------------------------------
+
+    void                copyPixels (DeepScanLineInputFile &in);
+    void                copyPixels (DeepScanLineInputPart &in);
+
+
+    //--------------------------------------------------------------
+    // Updating the preview image:
+    //
+    // updatePreviewImage() supplies a new set of pixels for the
+    // preview image attribute in the file's header.  If the header
+    // does not contain a preview image, updatePreviewImage() throws
+    // an IEX_NAMESPACE::LogicExc.
+    //
+    // Note: updatePreviewImage() is necessary because images are
+    // often stored in a file incrementally, a few scan lines at a
+    // time, while the image is being generated.  Since the preview
+    // image is an attribute in the file's header, it gets stored in
+    // the file as soon as the file is opened, but we may not know
+    // what the preview image should look like until we have written
+    // the last scan line of the main image.
+    //
+    //--------------------------------------------------------------
+
+    void                updatePreviewImage (const PreviewRgba newPixels[]);
+
+  private:
+      DeepScanLineOutputFile* file;
+};
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
+
+
+#endif /* IMFDEEPSCANLINEOUTPUTPART_H_ */
diff --git a/Source/OpenEXR/IlmImf/ImfDeepTiledInputFile.cpp b/Source/OpenEXR/IlmImf/ImfDeepTiledInputFile.cpp
new file mode 100644
index 0000000..4919620
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfDeepTiledInputFile.cpp
@@ -0,0 +1,1979 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+//-----------------------------------------------------------------------------
+//
+//      class DeepTiledInputFile
+//
+//-----------------------------------------------------------------------------
+
+#include <ImfDeepTiledInputFile.h>
+#include <ImfTileDescriptionAttribute.h>
+#include <ImfChannelList.h>
+#include <ImfMisc.h>
+#include <ImfTiledMisc.h>
+#include <ImfStdIO.h>
+#include <ImfCompressor.h>
+#include "ImathBox.h"
+#include <ImfXdr.h>
+#include <ImfConvert.h>
+#include <ImfVersion.h>
+#include <ImfTileOffsets.h>
+#include <ImfThreading.h>
+#include <ImfPartType.h>
+#include <ImfMultiPartInputFile.h>
+#include "IlmThreadPool.h"
+#include "IlmThreadSemaphore.h"
+#include "IlmThreadMutex.h"
+#include "ImfInputStreamMutex.h"
+#include "ImfInputPartData.h"
+#include "ImathVec.h"
+#include "Iex.h"
+#include <string>
+#include <vector>
+#include <algorithm>
+#include <assert.h>
+#include <limits>
+
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+using IMATH_NAMESPACE::Box2i;
+using IMATH_NAMESPACE::V2i;
+using std::string;
+using std::vector;
+using std::min;
+using std::max;
+using ILMTHREAD_NAMESPACE::Mutex;
+using ILMTHREAD_NAMESPACE::Lock;
+using ILMTHREAD_NAMESPACE::Semaphore;
+using ILMTHREAD_NAMESPACE::Task;
+using ILMTHREAD_NAMESPACE::TaskGroup;
+using ILMTHREAD_NAMESPACE::ThreadPool;
+
+namespace {
+
+struct TInSliceInfo
+{
+    PixelType           typeInFrameBuffer;
+    PixelType           typeInFile;
+    char*               pointerArrayBase;
+    size_t              xStride;
+    size_t              yStride;
+    ptrdiff_t           sampleStride;
+    bool                fill;
+    bool                skip;
+    double              fillValue;
+    int                 xTileCoords;
+    int                 yTileCoords;
+
+    TInSliceInfo (PixelType typeInFrameBuffer = HALF,
+                  char * base = NULL,
+                  PixelType typeInFile = HALF,
+                  size_t xStride = 0,
+                  size_t yStride = 0,
+                  ptrdiff_t sampleStride = 0,
+                  bool fill = false,
+                  bool skip = false,
+                  double fillValue = 0.0,
+                  int xTileCoords = 0,
+                  int yTileCoords = 0);
+};
+
+
+TInSliceInfo::TInSliceInfo (PixelType tifb,
+                            char * b,
+                            PixelType tifl,
+                            size_t xs, size_t ys,
+                            ptrdiff_t spst,
+                            bool f, bool s,
+                            double fv,
+                            int xtc,
+                            int ytc)
+:
+    typeInFrameBuffer (tifb),
+    typeInFile (tifl),
+    pointerArrayBase (b),
+    xStride (xs),
+    yStride (ys),
+    sampleStride (spst),
+    fill (f),
+    skip (s),
+    fillValue (fv),
+    xTileCoords (xtc),
+    yTileCoords (ytc)
+{
+    // empty
+}
+
+
+struct TileBuffer
+{
+    Array2D<unsigned int>       sampleCount;
+    const char *                uncompressedData;
+    char *                      buffer;
+    Int64                         dataSize;
+    Int64                         uncompressedDataSize;
+    Compressor *                compressor;
+    Compressor::Format          format;
+    int                         dx;
+    int                         dy;
+    int                         lx;
+    int                         ly;
+    bool                        hasException;
+    string                      exception;
+
+     TileBuffer ();
+    ~TileBuffer ();
+
+    inline void         wait () {_sem.wait();}
+    inline void         post () {_sem.post();}
+
+ protected:
+
+    Semaphore _sem;
+};
+
+
+TileBuffer::TileBuffer ():
+    uncompressedData (0),
+    buffer (0),
+    dataSize (0),
+    compressor (0),
+    format (defaultFormat (compressor)),
+    dx (-1),
+    dy (-1),
+    lx (-1),
+    ly (-1),
+    hasException (false),
+    exception (),
+    _sem (1)
+{
+    // empty
+}
+
+
+TileBuffer::~TileBuffer ()
+{
+    delete compressor;
+}
+
+} // namespace
+
+
+class MultiPartInputFile;
+
+
+//
+// struct TiledInputFile::Data stores things that will be
+// needed between calls to readTile()
+//
+
+struct DeepTiledInputFile::Data: public Mutex
+{
+    Header          header;                         // the image header
+    TileDescription tileDesc;                       // describes the tile layout
+    int             version;                        // file's version
+    DeepFrameBuffer frameBuffer;                    // framebuffer to write into
+    LineOrder       lineOrder;                      // the file's lineorder
+    int             minX;                           // data window's min x coord
+    int             maxX;                           // data window's max x coord
+    int             minY;                           // data window's min y coord
+    int             maxY;                           // data window's max x coord
+
+    int             numXLevels;                     // number of x levels
+    int             numYLevels;                     // number of y levels
+    int *           numXTiles;                      // number of x tiles at a level
+    int *           numYTiles;                      // number of y tiles at a level
+
+    TileOffsets     tileOffsets;                    // stores offsets in file for
+    // each tile
+
+    bool            fileIsComplete;                 // True if no tiles are missing
+                                                    // in the file
+
+    vector<TInSliceInfo*> slices;                    // info about channels in file
+
+                                                    // ourselves? or does someone
+                                                    // else do it?
+
+    int             partNumber;                     // part number
+
+    bool            multiPartBackwardSupport;       // if we are reading a multipart file
+                                                    // using OpenEXR 1.7 API
+
+    int             numThreads;                     // number of threads
+
+    MultiPartInputFile* multiPartFile;              // the MultiPartInputFile used to
+                                                    // support backward compatibility
+
+    vector<TileBuffer*> tileBuffers;                // each holds a single tile
+
+    bool            memoryMapped;                   // if the stream is memory mapped
+
+    char*           sampleCountSliceBase;           // pointer to the start of
+                                                    // the sample count array
+    ptrdiff_t       sampleCountXStride;             // x stride of the sample count array
+    ptrdiff_t       sampleCountYStride;             // y stride of the sample count array
+
+    int             sampleCountXTileCoords;         // the value of xTileCoords from the
+                                                    // sample count slice
+    int             sampleCountYTileCoords;         // the value of yTileCoords from the
+                                                    // sample count slice
+
+    Array<char>     sampleCountTableBuffer;         // the buffer for sample count table
+
+    Compressor*     sampleCountTableComp;           // the decompressor for sample count table
+
+    Int64           maxSampleCountTableSize;        // the max size in bytes for a pixel
+                                                    // sample count table
+    int             combinedSampleSize;             // total size of all channels combined to check sampletable size
+                                                    
+    InputStreamMutex *  _streamData;
+    bool                _deleteStream; // should we delete the stream
+     Data (int numThreads);
+    ~Data ();
+
+    inline TileBuffer * getTileBuffer (int number);
+                                                    // hash function from tile indices
+                                                    // into our vector of tile buffers
+
+    int&                getSampleCount(int x, int y);
+                                                    // get the number of samples
+                                                    // in each pixel
+};
+
+
+DeepTiledInputFile::Data::Data (int numThreads):
+    numXTiles (0),
+    numYTiles (0),
+    partNumber (-1),
+    multiPartBackwardSupport(false),
+    numThreads(numThreads),
+    memoryMapped(false),
+    _streamData(NULL),
+    _deleteStream(false)
+{
+    //
+    // We need at least one tileBuffer, but if threading is used,
+    // to keep n threads busy we need 2*n tileBuffers
+    //
+
+    tileBuffers.resize (max (1, 2 * numThreads));
+}
+
+
+DeepTiledInputFile::Data::~Data ()
+{
+    delete [] numXTiles;
+    delete [] numYTiles;
+
+    for (size_t i = 0; i < tileBuffers.size(); i++)
+        delete tileBuffers[i];
+
+    if (multiPartBackwardSupport)
+        delete multiPartFile;
+
+    for (size_t i = 0; i < slices.size(); i++)
+        delete slices[i];
+}
+
+
+TileBuffer*
+DeepTiledInputFile::Data::getTileBuffer (int number)
+{
+    return tileBuffers[number % tileBuffers.size()];
+}
+
+
+int&
+DeepTiledInputFile::Data::getSampleCount(int x, int y)
+{
+    return sampleCount(sampleCountSliceBase,
+                       sampleCountXStride,
+                       sampleCountYStride,
+                       x, y);
+}
+
+
+namespace {
+
+void
+readTileData (InputStreamMutex *streamData,
+              DeepTiledInputFile::Data *ifd,
+              int dx, int dy,
+              int lx, int ly,
+              char *&buffer,
+              Int64 &dataSize,
+              Int64 &unpackedDataSize)
+{
+    //
+    // Read a single tile block from the file and into the array pointed
+    // to by buffer.  If the file is memory-mapped, then we change where
+    // buffer points instead of writing into the array (hence buffer needs
+    // to be a reference to a char *).
+    //
+
+    //
+    // Look up the location for this tile in the Index and
+    // seek to that position if necessary
+    //
+
+    Int64 tileOffset = ifd->tileOffsets (dx, dy, lx, ly);
+
+    if (tileOffset == 0)
+    {
+        THROW (IEX_NAMESPACE::InputExc, "Tile (" << dx << ", " << dy << ", " <<
+                              lx << ", " << ly << ") is missing.");
+    }
+
+    //
+    // In a multi-part file, the next chunk does not need to
+    // belong to the same part, so we have to compare the
+    // offset here.
+    //
+
+    if ( !isMultiPart(ifd->version) )
+    {
+        if (streamData->currentPosition != tileOffset)
+            streamData->is->seekg(tileOffset);
+    }
+    else
+    {
+        //
+        // In a multi-part file, the file pointer may be moved by other
+        // parts, so we have to ask tellg() where we are.
+        //
+        if (streamData->is->tellg() != tileOffset)
+            streamData->is->seekg (tileOffset);
+    }
+
+    //
+    // Read the first few bytes of the tile (the header).
+    // Verify that the tile coordinates and the level number
+    // are correct.
+    //
+
+    int tileXCoord, tileYCoord, levelX, levelY;
+
+    if (isMultiPart(ifd->version))
+    {
+        int partNumber;
+        Xdr::read <StreamIO> (*streamData->is, partNumber);
+        if (partNumber != ifd->partNumber)
+        {
+            THROW (IEX_NAMESPACE::ArgExc, "Unexpected part number " << partNumber
+                   << ", should be " << ifd->partNumber << ".");
+        }
+    }
+
+    Xdr::read <StreamIO> (*streamData->is, tileXCoord);
+    Xdr::read <StreamIO> (*streamData->is, tileYCoord);
+    Xdr::read <StreamIO> (*streamData->is, levelX);
+    Xdr::read <StreamIO> (*streamData->is, levelY);
+
+    Int64 tableSize;
+    Xdr::read <StreamIO> (*streamData->is, tableSize);
+
+    Xdr::read <StreamIO> (*streamData->is, dataSize);
+    Xdr::read <StreamIO> (*streamData->is, unpackedDataSize);
+
+
+    //
+    // Skip the pixel sample count table because we have read this data.
+    //
+
+    Xdr::skip <StreamIO> (*streamData->is, tableSize);
+
+
+    if (tileXCoord != dx)
+        throw IEX_NAMESPACE::InputExc ("Unexpected tile x coordinate.");
+
+    if (tileYCoord != dy)
+        throw IEX_NAMESPACE::InputExc ("Unexpected tile y coordinate.");
+
+    if (levelX != lx)
+        throw IEX_NAMESPACE::InputExc ("Unexpected tile x level number coordinate.");
+
+    if (levelY != ly)
+        throw IEX_NAMESPACE::InputExc ("Unexpected tile y level number coordinate.");
+
+    //
+    // Read the pixel data.
+    //
+
+    if (streamData->is->isMemoryMapped ())
+        buffer = streamData->is->readMemoryMapped (dataSize);
+    else
+    {
+        // (TODO) check if the packed data size is too big?
+        // (TODO) better memory management here. Don't delete buffer everytime.
+        if (buffer != 0) delete[] buffer;
+        buffer = new char[dataSize];
+        streamData->is->read (buffer, dataSize);
+    }
+
+    //
+    // Keep track of which tile is the next one in
+    // the file, so that we can avoid redundant seekg()
+    // operations (seekg() can be fairly expensive).
+    //
+
+    streamData->currentPosition = tileOffset + 4 * Xdr::size<int>() +
+                                  3 * Xdr::size<Int64>()            +
+                                  tableSize                         +
+                                  dataSize;
+}
+
+
+void
+readNextTileData (InputStreamMutex *streamData,
+                  DeepTiledInputFile::Data *ifd,
+                  int &dx, int &dy,
+                  int &lx, int &ly,
+                  char * & buffer,
+                  Int64 &dataSize,
+                  Int64 &unpackedDataSize)
+{
+    //
+    // Read the next tile block from the file
+    //
+
+    //
+    // Read the first few bytes of the tile (the header).
+    //
+
+    Xdr::read <StreamIO> (*streamData->is, dx);
+    Xdr::read <StreamIO> (*streamData->is, dy);
+    Xdr::read <StreamIO> (*streamData->is, lx);
+    Xdr::read <StreamIO> (*streamData->is, ly);
+
+    Int64 tableSize;
+    Xdr::read <StreamIO> (*streamData->is, tableSize);
+
+    Xdr::read <StreamIO> (*streamData->is, dataSize);
+    Xdr::read <StreamIO> (*streamData->is, unpackedDataSize);
+
+    //
+    // Skip the pixel sample count table because we have read this data.
+    //
+
+    Xdr::skip <StreamIO> (*streamData->is, tableSize);
+
+    //
+    // Read the pixel data.
+    //
+
+    streamData->is->read (buffer, dataSize);
+
+    //
+    // Keep track of which tile is the next one in
+    // the file, so that we can avoid redundant seekg()
+    // operations (seekg() can be fairly expensive).
+    //
+
+    streamData->currentPosition += 4 * Xdr::size<int>()   +
+                                   3 * Xdr::size<Int64>() +
+                                   tableSize              +
+                                   dataSize;
+}
+
+
+//
+// A TileBufferTask encapsulates the task of uncompressing
+// a single tile and copying it into the frame buffer.
+//
+
+class TileBufferTask : public Task
+{
+  public:
+
+    TileBufferTask (TaskGroup *group,
+                    DeepTiledInputFile::Data *ifd,
+                    TileBuffer *tileBuffer);
+
+    virtual ~TileBufferTask ();
+
+    virtual void                execute ();
+
+  private:
+
+    DeepTiledInputFile::Data *      _ifd;
+    TileBuffer *                _tileBuffer;
+};
+
+
+TileBufferTask::TileBufferTask
+    (TaskGroup *group,
+     DeepTiledInputFile::Data *ifd,
+     TileBuffer *tileBuffer)
+:
+    Task (group),
+    _ifd (ifd),
+    _tileBuffer (tileBuffer)
+{
+    // empty
+}
+
+
+TileBufferTask::~TileBufferTask ()
+{
+    //
+    // Signal that the tile buffer is now free
+    //
+
+    _tileBuffer->post ();
+}
+
+
+void
+TileBufferTask::execute ()
+{
+    try
+    {
+        //
+        // Calculate information about the tile
+        //
+
+        Box2i tileRange = OPENEXR_IMF_INTERNAL_NAMESPACE::dataWindowForTile (
+                _ifd->tileDesc,
+                _ifd->minX, _ifd->maxX,
+                _ifd->minY, _ifd->maxY,
+                _tileBuffer->dx,
+                _tileBuffer->dy,
+                _tileBuffer->lx,
+                _tileBuffer->ly);
+
+        //
+        // Get the size of the tile.
+        //
+
+        Array<unsigned int> numPixelsPerScanLine;
+        numPixelsPerScanLine.resizeErase(tileRange.max.y - tileRange.min.y + 1);
+
+        int sizeOfTile = 0;
+        int maxBytesPerTileLine = 0;
+
+        for (int y = tileRange.min.y; y <= tileRange.max.y; y++)
+        {
+            numPixelsPerScanLine[y - tileRange.min.y] = 0;
+
+            int bytesPerLine = 0;
+
+            for (int x = tileRange.min.x; x <= tileRange.max.x; x++)
+            {
+                int xOffset = _ifd->sampleCountXTileCoords * tileRange.min.x;
+                int yOffset = _ifd->sampleCountYTileCoords * tileRange.min.y;
+
+                int count = _ifd->getSampleCount(x - xOffset, y - yOffset);
+                for (unsigned int c = 0; c < _ifd->slices.size(); ++c)
+                {
+                    sizeOfTile += count * pixelTypeSize(_ifd->slices[c]->typeInFile);
+                    bytesPerLine += count * pixelTypeSize(_ifd->slices[c]->typeInFile);
+                }
+                numPixelsPerScanLine[y - tileRange.min.y] += count;
+            }
+
+            if (bytesPerLine > maxBytesPerTileLine)
+                maxBytesPerTileLine = bytesPerLine;
+        }
+
+        // (TODO) don't do this every time.
+        if (_tileBuffer->compressor != 0)
+            delete _tileBuffer->compressor;
+        _tileBuffer->compressor = newTileCompressor
+                                  (_ifd->header.compression(),
+                                   maxBytesPerTileLine,
+                                   _ifd->tileDesc.ySize,
+                                   _ifd->header);
+
+        //
+        // Uncompress the data, if necessary
+        //
+
+        if (_tileBuffer->compressor && _tileBuffer->dataSize < Int64(sizeOfTile))
+        {
+            _tileBuffer->format = _tileBuffer->compressor->format();
+
+            _tileBuffer->dataSize = _tileBuffer->compressor->uncompressTile
+                (_tileBuffer->buffer, _tileBuffer->dataSize,
+                 tileRange, _tileBuffer->uncompressedData);
+        }
+        else
+        {
+            //
+            // If the line is uncompressed, it's in XDR format,
+            // regardless of the compressor's output format.
+            //
+
+            _tileBuffer->format = Compressor::XDR;
+            _tileBuffer->uncompressedData = _tileBuffer->buffer;
+        }
+
+        //
+        // Convert the tile of pixel data back from the machine-independent
+        // representation, and store the result in the frame buffer.
+        //
+
+        const char *readPtr = _tileBuffer->uncompressedData;
+                                                        // points to where we
+                                                        // read from in the
+                                                        // tile block
+
+        //
+        // Iterate over the scan lines in the tile.
+        //
+
+        for (int y = tileRange.min.y; y <= tileRange.max.y; ++y)
+        {
+            //
+            // Iterate over all image channels.
+            //
+
+            for (unsigned int i = 0; i < _ifd->slices.size(); ++i)
+            {
+                TInSliceInfo &slice = *_ifd->slices[i];
+
+                //
+                // These offsets are used to facilitate both
+                // absolute and tile-relative pixel coordinates.
+                //
+
+                int xOffsetForData = (slice.xTileCoords == 0) ? 0 : tileRange.min.x;
+                int yOffsetForData = (slice.yTileCoords == 0) ? 0 : tileRange.min.y;
+                int xOffsetForSampleCount =
+                        (_ifd->sampleCountXTileCoords == 0) ? 0 : tileRange.min.x;
+                int yOffsetForSampleCount =
+                        (_ifd->sampleCountYTileCoords == 0) ? 0 : tileRange.min.y;
+
+                //
+                // Fill the frame buffer with pixel data.
+                //
+
+                if (slice.skip)
+                {
+                    //
+                    // The file contains data for this channel, but
+                    // the frame buffer contains no slice for this channel.
+                    //
+
+                    skipChannel (readPtr, slice.typeInFile,
+                                 numPixelsPerScanLine[y - tileRange.min.y]);
+                }
+                else
+                {
+                    //
+                    // The frame buffer contains a slice for this channel.
+                    //
+
+                    copyIntoDeepFrameBuffer (readPtr, slice.pointerArrayBase,
+                                             _ifd->sampleCountSliceBase,
+                                             _ifd->sampleCountXStride,
+                                             _ifd->sampleCountYStride,
+                                             y,
+                                             tileRange.min.x,
+                                             tileRange.max.x,
+                                             xOffsetForSampleCount, yOffsetForSampleCount,
+                                             xOffsetForData, yOffsetForData,
+                                             slice.sampleStride, 
+                                             slice.xStride,
+                                             slice.yStride,
+                                             slice.fill,
+                                             slice.fillValue, _tileBuffer->format,
+                                             slice.typeInFrameBuffer,
+                                             slice.typeInFile);
+                }
+            }
+        }
+    }
+    catch (std::exception &e)
+    {
+        if (!_tileBuffer->hasException)
+        {
+            _tileBuffer->exception = e.what ();
+            _tileBuffer->hasException = true;
+        }
+    }
+    catch (...)
+    {
+        if (!_tileBuffer->hasException)
+        {
+            _tileBuffer->exception = "unrecognized exception";
+            _tileBuffer->hasException = true;
+        }
+    }
+}
+
+
+TileBufferTask *
+newTileBufferTask
+    (TaskGroup *group,
+     DeepTiledInputFile::Data *ifd,
+     int number,
+     int dx, int dy,
+     int lx, int ly)
+{
+    //
+    // Wait for a tile buffer to become available,
+    // fill the buffer with raw data from the file,
+    // and create a new TileBufferTask whose execute()
+    // method will uncompress the tile and copy the
+    // tile's pixels into the frame buffer.
+    //
+
+    TileBuffer *tileBuffer = ifd->getTileBuffer (number);
+
+    try
+    {
+        tileBuffer->wait();
+
+        tileBuffer->dx = dx;
+        tileBuffer->dy = dy;
+        tileBuffer->lx = lx;
+        tileBuffer->ly = ly;
+
+        tileBuffer->uncompressedData = 0;
+
+        readTileData (ifd->_streamData, ifd, dx, dy, lx, ly,
+                      tileBuffer->buffer,
+                      tileBuffer->dataSize,
+                      tileBuffer->uncompressedDataSize);
+    }
+    catch (...)
+    {
+        //
+        // Reading from the file caused an exception.
+        // Signal that the tile buffer is free, and
+        // re-throw the exception.
+        //
+
+        tileBuffer->post();
+        throw;
+    }
+
+    return new TileBufferTask (group, ifd, tileBuffer);
+}
+
+
+} // namespace
+
+
+DeepTiledInputFile::DeepTiledInputFile (const char fileName[], int numThreads):
+    _data (new Data (numThreads))
+{
+    _data->_deleteStream=true;
+    //
+    // This constructor is called when a user
+    // explicitly wants to read a tiled file.
+    //
+
+    IStream* is = 0;
+    try
+    {
+        is = new StdIFStream (fileName);
+        readMagicNumberAndVersionField(*is, _data->version);
+
+        //
+        // Compatibility to read multpart file.
+        //
+        if (isMultiPart(_data->version))
+        {
+            compatibilityInitialize(*is);
+        }
+        else
+        {
+            _data->_streamData = new InputStreamMutex();
+            _data->_streamData->is = is;
+            _data->header.readFrom (*_data->_streamData->is, _data->version);
+            initialize();
+            _data->tileOffsets.readFrom (*(_data->_streamData->is), _data->fileIsComplete,false,true);
+            _data->_streamData->currentPosition = _data->_streamData->is->tellg();
+        }
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        if (is)          delete is;
+        if (_data && !_data->multiPartBackwardSupport && _data->_streamData) delete _data->_streamData;
+        if (_data)       delete _data;
+
+        REPLACE_EXC (e, "Cannot open image file "
+                        "\"" << fileName << "\". " << e);
+        throw;
+    }
+    catch (...)
+    {
+        if (is)          delete is;
+        if (_data && !_data->multiPartBackwardSupport && _data->_streamData) delete _data->_streamData;
+        if (_data)       delete _data;
+
+        throw;
+    }
+}
+
+
+DeepTiledInputFile::DeepTiledInputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int numThreads):
+    _data (new Data (numThreads))
+{
+    _data->_streamData=0;
+    _data->_deleteStream=false;
+    
+    //
+    // This constructor is called when a user
+    // explicitly wants to read a tiled file.
+    //
+
+    try
+    {
+        readMagicNumberAndVersionField(is, _data->version);
+
+        //
+        // Backward compatibility to read multpart file.
+        //
+        if (isMultiPart(_data->version))
+        {
+            compatibilityInitialize(is);
+        }
+        else
+        {
+            _data->_streamData = new InputStreamMutex();
+            _data->_streamData->is = &is;
+            _data->header.readFrom (*_data->_streamData->is, _data->version);
+            initialize();
+            // file is guaranteed not to be multipart, but is deep
+            _data->tileOffsets.readFrom (*(_data->_streamData->is), _data->fileIsComplete, false,true);
+            _data->memoryMapped = _data->_streamData->is->isMemoryMapped();
+            _data->_streamData->currentPosition = _data->_streamData->is->tellg();
+        }
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        if (_data && !_data->multiPartBackwardSupport && _data->_streamData) delete _data->_streamData;
+        if (_data)       delete _data;
+
+        REPLACE_EXC (e, "Cannot open image file "
+                        "\"" << is.fileName() << "\". " << e);
+        throw;
+    }
+    catch (...)
+    {
+        if (_data && !_data->multiPartBackwardSupport && _data->_streamData) delete _data->_streamData;
+        if (_data)       delete _data;
+
+        throw;
+    }
+}
+
+
+DeepTiledInputFile::DeepTiledInputFile (const Header &header,
+                                        OPENEXR_IMF_INTERNAL_NAMESPACE::IStream *is,
+                                        int version,
+                                        int numThreads) :
+    _data (new Data (numThreads))
+    
+{
+    _data->_streamData->is = is;
+    _data->_deleteStream=false;
+    
+    //
+    // This constructor called by class Imf::InputFile
+    // when a user wants to just read an image file, and
+    // doesn't care or know if the file is tiled.
+    // No need to have backward compatibility here, because
+    // we have the header.
+    //
+
+    _data->header = header;
+    _data->version = version;
+    initialize();
+    _data->tileOffsets.readFrom (*(_data->_streamData->is), _data->fileIsComplete,false,true);
+    _data->memoryMapped = is->isMemoryMapped();
+    _data->_streamData->currentPosition = _data->_streamData->is->tellg();
+}
+
+
+DeepTiledInputFile::DeepTiledInputFile (InputPartData* part) :
+    _data (new Data (part->numThreads))
+{
+    _data->_deleteStream=false;
+    multiPartInitialize(part);
+}
+
+
+void
+DeepTiledInputFile::compatibilityInitialize(OPENEXR_IMF_INTERNAL_NAMESPACE::IStream& is)
+{
+    is.seekg(0);
+    //
+    // Construct a MultiPartInputFile, initialize TiledInputFile
+    // with the part 0 data.
+    // (TODO) maybe change the third parameter of the constructor of MultiPartInputFile later.
+    //
+    _data->multiPartFile = new MultiPartInputFile(is, _data->numThreads);
+    _data->multiPartBackwardSupport = true;
+    InputPartData* part = _data->multiPartFile->getPart(0);
+
+    multiPartInitialize(part);
+}
+
+
+void
+DeepTiledInputFile::multiPartInitialize(InputPartData* part)
+{
+    if (isTiled(part->header.type()) == false)
+        THROW (IEX_NAMESPACE::ArgExc, "Can't build a DeepTiledInputFile from a part of type " << part->header.type());
+
+    _data->_streamData = part->mutex;
+    _data->header = part->header;
+    _data->version = part->version;
+    _data->partNumber = part->partNumber;
+    _data->memoryMapped = _data->_streamData->is->isMemoryMapped();
+    initialize();
+    _data->tileOffsets.readFrom(part->chunkOffsets , _data->fileIsComplete);
+    _data->_streamData->currentPosition = _data->_streamData->is->tellg();
+}
+
+
+void
+DeepTiledInputFile::initialize ()
+{
+    if (_data->partNumber == -1)
+        if (_data->header.type() != DEEPTILE)
+            throw IEX_NAMESPACE::ArgExc ("Expected a deep tiled file but the file is not deep tiled.");
+   if(_data->header.version()!=1)
+   {
+       THROW(IEX_NAMESPACE::ArgExc, "Version " << _data->header.version() << " not supported for deeptiled images in this version of the library");
+   }
+        
+    _data->header.sanityCheck (true);
+
+    _data->tileDesc = _data->header.tileDescription();
+    _data->lineOrder = _data->header.lineOrder();
+
+    //
+    // Save the dataWindow information
+    //
+
+    const Box2i &dataWindow = _data->header.dataWindow();
+    _data->minX = dataWindow.min.x;
+    _data->maxX = dataWindow.max.x;
+    _data->minY = dataWindow.min.y;
+    _data->maxY = dataWindow.max.y;
+
+    //
+    // Precompute level and tile information to speed up utility functions
+    //
+
+    precalculateTileInfo (_data->tileDesc,
+                          _data->minX, _data->maxX,
+                          _data->minY, _data->maxY,
+                          _data->numXTiles, _data->numYTiles,
+                          _data->numXLevels, _data->numYLevels);
+
+    //
+    // Create all the TileBuffers and allocate their internal buffers
+    //
+
+    _data->tileOffsets = TileOffsets (_data->tileDesc.mode,
+                                      _data->numXLevels,
+                                      _data->numYLevels,
+                                      _data->numXTiles,
+                                      _data->numYTiles);
+
+    for (size_t i = 0; i < _data->tileBuffers.size(); i++)
+        _data->tileBuffers[i] = new TileBuffer ();
+
+    _data->maxSampleCountTableSize = _data->tileDesc.ySize *
+                                     _data->tileDesc.xSize *
+                                     sizeof(int);
+
+    _data->sampleCountTableBuffer.resizeErase(_data->maxSampleCountTableSize);
+
+    _data->sampleCountTableComp = newCompressor(_data->header.compression(),
+                                                _data->maxSampleCountTableSize,
+                                                _data->header);
+                                                
+                                                
+    const ChannelList & c=_data->header.channels();
+    _data->combinedSampleSize=0;
+    for(ChannelList::ConstIterator i=c.begin();i!=c.end();i++)
+    {
+        switch( i.channel().type )
+        {
+            case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF  :
+                _data->combinedSampleSize+=Xdr::size<half>();
+                break;
+            case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT :
+                _data->combinedSampleSize+=Xdr::size<float>();
+                break;
+            case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT  :
+                _data->combinedSampleSize+=Xdr::size<unsigned int>();
+                break;
+            default :
+                THROW(IEX_NAMESPACE::ArgExc, "Bad type for channel " << i.name() << " initializing deepscanline reader");
+        }
+    }
+                                                  
+}
+
+
+DeepTiledInputFile::~DeepTiledInputFile ()
+{
+    if (!_data->memoryMapped)
+        for (size_t i = 0; i < _data->tileBuffers.size(); i++)
+            if (_data->tileBuffers[i]->buffer != 0)
+                delete [] _data->tileBuffers[i]->buffer;
+
+    if (_data->_deleteStream)
+        delete _data->_streamData->is;
+
+    //
+    // (TODO) we should have a way to tell if the stream data is owned by this file or
+    // by a parent multipart file.
+    //
+
+    if (_data->partNumber == -1)
+        delete _data->_streamData;
+
+    delete _data;
+}
+
+
+const char *
+DeepTiledInputFile::fileName () const
+{
+    return _data->_streamData->is->fileName();
+}
+
+
+const Header &
+DeepTiledInputFile::header () const
+{
+    return _data->header;
+}
+
+
+int
+DeepTiledInputFile::version () const
+{
+    return _data->version;
+}
+
+
+void
+DeepTiledInputFile::setFrameBuffer (const DeepFrameBuffer &frameBuffer)
+{
+    Lock lock (*_data->_streamData);
+
+    //
+    // Set the frame buffer
+    //
+
+    //
+    // Check if the new frame buffer descriptor is
+    // compatible with the image file header.
+    //
+
+    const ChannelList &channels = _data->header.channels();
+
+    for (DeepFrameBuffer::ConstIterator j = frameBuffer.begin();
+         j != frameBuffer.end();
+         ++j)
+    {
+        ChannelList::ConstIterator i = channels.find (j.name());
+
+        if (i == channels.end())
+            continue;
+
+        if (i.channel().xSampling != j.slice().xSampling ||
+            i.channel().ySampling != j.slice().ySampling)
+            THROW (IEX_NAMESPACE::ArgExc, "X and/or y subsampling factors "
+                                "of \"" << i.name() << "\" channel "
+                                "of input file \"" << fileName() << "\" are "
+                                "not compatible with the frame buffer's "
+                                "subsampling factors.");
+    }
+
+    //
+    // Store the pixel sample count table.
+    // (TODO) Support for different sampling rates?
+    //
+
+    const Slice& sampleCountSlice = frameBuffer.getSampleCountSlice();
+    if (sampleCountSlice.base == 0)
+    {
+        throw IEX_NAMESPACE::ArgExc ("Invalid base pointer, please set a proper sample count slice.");
+    }
+    else
+    {
+        _data->sampleCountSliceBase = sampleCountSlice.base;
+        _data->sampleCountXStride = sampleCountSlice.xStride;
+        _data->sampleCountYStride = sampleCountSlice.yStride;
+        _data->sampleCountXTileCoords = sampleCountSlice.xTileCoords;
+        _data->sampleCountYTileCoords = sampleCountSlice.yTileCoords;
+    }
+
+    //
+    // Initialize the slice table for readPixels().
+    //
+
+    vector<TInSliceInfo*> slices;
+    ChannelList::ConstIterator i = channels.begin();
+
+    for (DeepFrameBuffer::ConstIterator j = frameBuffer.begin();
+         j != frameBuffer.end();
+         ++j)
+    {
+        while (i != channels.end() && strcmp (i.name(), j.name()) < 0)
+        {
+            //
+            // Channel i is present in the file but not
+            // in the frame buffer; data for channel i
+            // will be skipped during readPixels().
+            //
+
+            slices.push_back (new TInSliceInfo (i.channel().type,
+                                                NULL,
+                                                i.channel().type,
+                                                0,      // xStride
+                                                0,      // yStride
+                                                0,      // sampleStride
+                                                false,  // fill
+                                                true,   // skip
+                                                0.0));  // fillValue
+            ++i;
+        }
+
+        bool fill = false;
+
+        if (i == channels.end() || strcmp (i.name(), j.name()) > 0)
+        {
+            //
+            // Channel i is present in the frame buffer, but not in the file.
+            // In the frame buffer, slice j will be filled with a default value.
+            //
+
+            fill = true;
+        }
+
+        slices.push_back (new TInSliceInfo (j.slice().type,
+                                            j.slice().base,
+                                            fill? j.slice().type: i.channel().type,
+                                            j.slice().xStride,
+                                            j.slice().yStride,
+                                            j.slice().sampleStride,
+                                            fill,
+                                            false, // skip
+                                            j.slice().fillValue,
+                                            (j.slice().xTileCoords)? 1: 0,
+                                            (j.slice().yTileCoords)? 1: 0));
+
+
+        if (i != channels.end() && !fill)
+            ++i;
+    }
+
+    // (TODO) inspect the following code. It's additional to the scanline input file.
+    // Is this needed?
+
+    while (i != channels.end())
+    {
+        //
+        // Channel i is present in the file but not
+        // in the frame buffer; data for channel i
+        // will be skipped during readPixels().
+        //
+
+        slices.push_back (new TInSliceInfo (i.channel().type,
+                                            NULL,
+                                            i.channel().type,
+                                            0, // xStride
+                                            0, // yStride
+                                            0, // sampleStride
+                                            false,  // fill
+                                            true, // skip
+                                            0.0)); // fillValue
+        ++i;
+    }
+
+    //
+    // Store the new frame buffer.
+    //
+
+    _data->frameBuffer = frameBuffer;
+
+    for (size_t i = 0; i < _data->slices.size(); i++)
+        delete _data->slices[i];
+    _data->slices = slices;
+}
+
+
+const DeepFrameBuffer &
+DeepTiledInputFile::frameBuffer () const
+{
+    Lock lock (*_data->_streamData);
+    return _data->frameBuffer;
+}
+
+
+bool
+DeepTiledInputFile::isComplete () const
+{
+    return _data->fileIsComplete;
+}
+
+
+void
+DeepTiledInputFile::readTiles (int dx1, int dx2, int dy1, int dy2, int lx, int ly)
+{
+    //
+    // Read a range of tiles from the file into the framebuffer
+    //
+
+    try
+    {
+        Lock lock (*_data->_streamData);
+
+        if (_data->slices.size() == 0)
+            throw IEX_NAMESPACE::ArgExc ("No frame buffer specified "
+                               "as pixel data destination.");
+
+        if (!isValidLevel (lx, ly))
+            THROW (IEX_NAMESPACE::ArgExc,
+                   "Level coordinate "
+                   "(" << lx << ", " << ly << ") "
+                   "is invalid.");
+
+        //
+        // Determine the first and last tile coordinates in both dimensions.
+        // We always attempt to read the range of tiles in the order that
+        // they are stored in the file.
+        //
+
+        if (dx1 > dx2)
+            std::swap (dx1, dx2);
+
+        if (dy1 > dy2)
+            std::swap (dy1, dy2);
+
+        int dyStart = dy1;
+        int dyStop  = dy2 + 1;
+        int dY      = 1;
+
+        if (_data->lineOrder == DECREASING_Y)
+        {
+            dyStart = dy2;
+            dyStop  = dy1 - 1;
+            dY      = -1;
+        }
+
+        //
+        // Create a task group for all tile buffer tasks.  When the
+        // task group goes out of scope, the destructor waits until
+        // all tasks are complete.
+        //
+
+        {
+            TaskGroup taskGroup;
+            int tileNumber = 0;
+
+            for (int dy = dyStart; dy != dyStop; dy += dY)
+            {
+                for (int dx = dx1; dx <= dx2; dx++)
+                {
+                    if (!isValidTile (dx, dy, lx, ly))
+                        THROW (IEX_NAMESPACE::ArgExc,
+                               "Tile (" << dx << ", " << dy << ", " <<
+                               lx << "," << ly << ") is not a valid tile.");
+
+                    ThreadPool::addGlobalTask (newTileBufferTask (&taskGroup,
+                                                                  _data,
+                                                                  tileNumber++,
+                                                                  dx, dy,
+                                                                  lx, ly));
+                }
+            }
+
+            //
+            // finish all tasks
+            //
+        }
+
+        //
+        // Exeption handling:
+        //
+        // TileBufferTask::execute() may have encountered exceptions, but
+        // those exceptions occurred in another thread, not in the thread
+        // that is executing this call to TiledInputFile::readTiles().
+        // TileBufferTask::execute() has caught all exceptions and stored
+        // the exceptions' what() strings in the tile buffers.
+        // Now we check if any tile buffer contains a stored exception; if
+        // this is the case then we re-throw the exception in this thread.
+        // (It is possible that multiple tile buffers contain stored
+        // exceptions.  We re-throw the first exception we find and
+        // ignore all others.)
+        //
+
+        const string *exception = 0;
+
+        for (size_t i = 0; i < _data->tileBuffers.size(); ++i)
+        {
+            TileBuffer *tileBuffer = _data->tileBuffers[i];
+
+            if (tileBuffer->hasException && !exception)
+                exception = &tileBuffer->exception;
+
+            tileBuffer->hasException = false;
+        }
+
+        if (exception)
+            throw IEX_NAMESPACE::IoExc (*exception);
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        REPLACE_EXC (e, "Error reading pixel data from image "
+                        "file \"" << fileName() << "\". " << e);
+        throw;
+    }
+}
+
+
+void
+DeepTiledInputFile::readTiles (int dx1, int dx2, int dy1, int dy2, int l)
+{
+    readTiles (dx1, dx2, dy1, dy2, l, l);
+}
+
+
+void
+DeepTiledInputFile::readTile (int dx, int dy, int lx, int ly)
+{
+    readTiles (dx, dx, dy, dy, lx, ly);
+}
+
+
+void
+DeepTiledInputFile::readTile (int dx, int dy, int l)
+{
+    readTile (dx, dy, l, l);
+}
+
+
+void
+DeepTiledInputFile::rawTileData (int &dx, int &dy,
+                             int &lx, int &ly,
+                             char * pixelData,
+                             Int64 &pixelDataSize) const
+{
+     if (!isValidTile (dx, dy, lx, ly))
+               throw IEX_NAMESPACE::ArgExc ("Tried to read a tile outside "
+                                   "the image file's data window.");
+    
+     Int64 tileOffset = _data->tileOffsets (dx, dy, lx, ly);
+                                   
+     if(tileOffset == 0)
+     {
+        THROW (IEX_NAMESPACE::InputExc, "Tile (" << dx << ", " << dy << ", " <<
+        lx << ", " << ly << ") is missing.");
+     }
+     
+     Lock lock(*_data->_streamData);
+                                   
+     if (_data->_streamData->is->tellg() != tileOffset)
+                                          _data->_streamData->is->seekg (tileOffset);
+                                   
+     
+     //
+     // Read the first few bytes of the tile (the header).
+     // Verify that the tile coordinates and the level number
+     // are correct.
+     //
+     
+     int tileXCoord, tileYCoord, levelX, levelY;
+     
+     if (isMultiPart(_data->version))
+     {
+         int partNumber;
+         Xdr::read <StreamIO> (*_data->_streamData->is, partNumber);
+         if (partNumber != _data->partNumber)
+         {
+             THROW (IEX_NAMESPACE::ArgExc, "Unexpected part number " << partNumber
+             << ", should be " << _data->partNumber << ".");
+         }
+     }
+     
+     Xdr::read <StreamIO> (*_data->_streamData->is, tileXCoord);
+     Xdr::read <StreamIO> (*_data->_streamData->is, tileYCoord);
+     Xdr::read <StreamIO> (*_data->_streamData->is, levelX);
+     Xdr::read <StreamIO> (*_data->_streamData->is, levelY);
+     
+     Int64 sampleCountTableSize;
+     Int64 packedDataSize;
+     Xdr::read <StreamIO> (*_data->_streamData->is, sampleCountTableSize);
+     
+     Xdr::read <StreamIO> (*_data->_streamData->is, packedDataSize);
+     
+          
+     
+     if (tileXCoord != dx)
+         throw IEX_NAMESPACE::InputExc ("Unexpected tile x coordinate.");
+     
+     if (tileYCoord != dy)
+         throw IEX_NAMESPACE::InputExc ("Unexpected tile y coordinate.");
+     
+     if (levelX != lx)
+         throw IEX_NAMESPACE::InputExc ("Unexpected tile x level number coordinate.");
+     
+     if (levelY != ly)
+         throw IEX_NAMESPACE::InputExc ("Unexpected tile y level number coordinate.");
+     
+     
+     // total requirement for reading all the data
+     
+     Int64 totalSizeRequired=40+sampleCountTableSize+packedDataSize;
+     
+     bool big_enough = totalSizeRequired<=pixelDataSize;
+     
+     pixelDataSize = totalSizeRequired;
+     
+     // was the block we were given big enough?
+     if(!big_enough || pixelData==NULL)
+     {        
+         // special case: seek stream back to start if we are at the beginning (regular reading pixels assumes it doesn't need to seek
+         // in single part files)
+         if(!isMultiPart(_data->version))
+         {
+             _data->_streamData->is->seekg(_data->_streamData->currentPosition); 
+         }
+         // leave lock here - bail before reading more data
+         return;
+     }
+     
+     // copy the values we have read into the output block
+     *(int *) (pixelData+0) = dx;
+     *(int *) (pixelData+4) = dy;
+     *(int *) (pixelData+8) = levelX;
+     *(int *) (pixelData+12) = levelY;
+     *(Int64 *) (pixelData+16) =sampleCountTableSize;
+     *(Int64 *) (pixelData+24) = packedDataSize;
+     
+     // didn't read the unpackedsize - do that now
+     Xdr::read<StreamIO> (*_data->_streamData->is, *(Int64 *) (pixelData+32));
+     
+     // read the actual data
+     _data->_streamData->is->read(pixelData+40, sampleCountTableSize+packedDataSize);
+     
+     
+     if(!isMultiPart(_data->version))
+     {
+         _data->_streamData->currentPosition+=sampleCountTableSize+packedDataSize+40;
+     }
+     
+     // leave lock here
+     
+     
+}
+
+
+unsigned int
+DeepTiledInputFile::tileXSize () const
+{
+    return _data->tileDesc.xSize;
+}
+
+
+unsigned int
+DeepTiledInputFile::tileYSize () const
+{
+    return _data->tileDesc.ySize;
+}
+
+
+LevelMode
+DeepTiledInputFile::levelMode () const
+{
+    return _data->tileDesc.mode;
+}
+
+
+LevelRoundingMode
+DeepTiledInputFile::levelRoundingMode () const
+{
+    return _data->tileDesc.roundingMode;
+}
+
+
+int
+DeepTiledInputFile::numLevels () const
+{
+    if (levelMode() == RIPMAP_LEVELS)
+        THROW (IEX_NAMESPACE::LogicExc, "Error calling numLevels() on image "
+                              "file \"" << fileName() << "\" "
+                              "(numLevels() is not defined for files "
+                              "with RIPMAP level mode).");
+
+    return _data->numXLevels;
+}
+
+
+int
+DeepTiledInputFile::numXLevels () const
+{
+    return _data->numXLevels;
+}
+
+
+int
+DeepTiledInputFile::numYLevels () const
+{
+    return _data->numYLevels;
+}
+
+
+bool
+DeepTiledInputFile::isValidLevel (int lx, int ly) const
+{
+    if (lx < 0 || ly < 0)
+        return false;
+
+    if (levelMode() == MIPMAP_LEVELS && lx != ly)
+        return false;
+
+    if (lx >= numXLevels() || ly >= numYLevels())
+        return false;
+
+    return true;
+}
+
+
+int
+DeepTiledInputFile::levelWidth (int lx) const
+{
+    try
+    {
+        return levelSize (_data->minX, _data->maxX, lx,
+                          _data->tileDesc.roundingMode);
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        REPLACE_EXC (e, "Error calling levelWidth() on image "
+                        "file \"" << fileName() << "\". " << e);
+        throw;
+    }
+}
+
+
+int
+DeepTiledInputFile::levelHeight (int ly) const
+{
+    try
+    {
+        return levelSize (_data->minY, _data->maxY, ly,
+                          _data->tileDesc.roundingMode);
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        REPLACE_EXC (e, "Error calling levelHeight() on image "
+                        "file \"" << fileName() << "\". " << e);
+        throw;
+    }
+}
+
+
+int
+DeepTiledInputFile::numXTiles (int lx) const
+{
+    if (lx < 0 || lx >= _data->numXLevels)
+    {
+        THROW (IEX_NAMESPACE::ArgExc, "Error calling numXTiles() on image "
+                            "file \"" << _data->_streamData->is->fileName() << "\" "
+                            "(Argument is not in valid range).");
+
+    }
+
+    return _data->numXTiles[lx];
+}
+
+
+int
+DeepTiledInputFile::numYTiles (int ly) const
+{
+    if (ly < 0 || ly >= _data->numYLevels)
+    {
+        THROW (IEX_NAMESPACE::ArgExc, "Error calling numYTiles() on image "
+                            "file \"" << _data->_streamData->is->fileName() << "\" "
+                            "(Argument is not in valid range).");
+    }
+
+    return _data->numYTiles[ly];
+}
+
+
+Box2i
+DeepTiledInputFile::dataWindowForLevel (int l) const
+{
+    return dataWindowForLevel (l, l);
+}
+
+
+Box2i
+DeepTiledInputFile::dataWindowForLevel (int lx, int ly) const
+{
+    try
+    {
+        return OPENEXR_IMF_INTERNAL_NAMESPACE::dataWindowForLevel (
+                _data->tileDesc,
+                _data->minX, _data->maxX,
+                _data->minY, _data->maxY,
+                lx, ly);
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        REPLACE_EXC (e, "Error calling dataWindowForLevel() on image "
+                        "file \"" << fileName() << "\". " << e);
+        throw;
+    }
+}
+
+
+Box2i
+DeepTiledInputFile::dataWindowForTile (int dx, int dy, int l) const
+{
+    return dataWindowForTile (dx, dy, l, l);
+}
+
+
+Box2i
+DeepTiledInputFile::dataWindowForTile (int dx, int dy, int lx, int ly) const
+{
+    try
+    {
+        if (!isValidTile (dx, dy, lx, ly))
+            throw IEX_NAMESPACE::ArgExc ("Arguments not in valid range.");
+
+        return OPENEXR_IMF_INTERNAL_NAMESPACE::dataWindowForTile (
+                _data->tileDesc,
+                _data->minX, _data->maxX,
+                _data->minY, _data->maxY,
+                dx, dy, lx, ly);
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        REPLACE_EXC (e, "Error calling dataWindowForTile() on image "
+                        "file \"" << fileName() << "\". " << e);
+        throw;
+    }
+}
+
+
+bool
+DeepTiledInputFile::isValidTile (int dx, int dy, int lx, int ly) const
+{
+    return ((lx < _data->numXLevels && lx >= 0) &&
+            (ly < _data->numYLevels && ly >= 0) &&
+            (dx < _data->numXTiles[lx] && dx >= 0) &&
+            (dy < _data->numYTiles[ly] && dy >= 0));
+}
+
+
+void
+DeepTiledInputFile::readPixelSampleCounts (int dx1, int dx2,
+                                           int dy1, int dy2,
+                                           int lx,  int ly)
+{
+    Int64 savedFilePos = 0;
+
+    try
+    {
+        Lock lock (*_data->_streamData);
+
+        savedFilePos = _data->_streamData->is->tellg();
+
+        
+        if (!isValidLevel (lx, ly))
+        {
+            THROW (IEX_NAMESPACE::ArgExc,
+                   "Level coordinate "
+                   "(" << lx << ", " << ly << ") "
+                   "is invalid.");
+        }
+        
+        if (dx1 > dx2)
+            std::swap (dx1, dx2);
+
+        if (dy1 > dy2)
+            std::swap (dy1, dy2);
+
+        int dyStart = dy1;
+        int dyStop  = dy2 + 1;
+        int dY      = 1;
+
+        if (_data->lineOrder == DECREASING_Y)
+        {
+            dyStart = dy2;
+            dyStop  = dy1 - 1;
+            dY      = -1;
+        }
+
+        // (TODO) Check if we have read the sample counts for those tiles,
+        // if we have, no need to read again.
+        for (int dy = dyStart; dy != dyStop; dy += dY)
+        {
+            for (int dx = dx1; dx <= dx2; dx++)
+            {
+                
+                if (!isValidTile (dx, dy, lx, ly))
+                {
+                    THROW (IEX_NAMESPACE::ArgExc,
+                           "Tile (" << dx << ", " << dy << ", " <<
+                           lx << "," << ly << ") is not a valid tile.");
+                }
+                
+                Box2i tileRange = OPENEXR_IMF_INTERNAL_NAMESPACE::dataWindowForTile (
+                        _data->tileDesc,
+                        _data->minX, _data->maxX,
+                        _data->minY, _data->maxY,
+                        dx, dy, lx, ly);
+
+                int xOffset = _data->sampleCountXTileCoords * tileRange.min.x;
+                int yOffset = _data->sampleCountYTileCoords * tileRange.min.y;
+
+                //
+                // Skip and check the tile coordinates.
+                //
+
+                _data->_streamData->is->seekg(_data->tileOffsets(dx, dy, lx, ly));
+
+                if (isMultiPart(_data->version))
+                {
+                    int partNumber;
+                    Xdr::read <StreamIO> (*_data->_streamData->is, partNumber);
+
+                    if (partNumber != _data->partNumber)
+                        throw IEX_NAMESPACE::InputExc ("Unexpected part number.");
+                }
+
+                int xInFile, yInFile, lxInFile, lyInFile;
+                Xdr::read <StreamIO> (*_data->_streamData->is, xInFile);
+                Xdr::read <StreamIO> (*_data->_streamData->is, yInFile);
+                Xdr::read <StreamIO> (*_data->_streamData->is, lxInFile);
+                Xdr::read <StreamIO> (*_data->_streamData->is, lyInFile);
+
+                if (xInFile != dx)
+                    throw IEX_NAMESPACE::InputExc ("Unexpected tile x coordinate.");
+
+                if (yInFile != dy)
+                    throw IEX_NAMESPACE::InputExc ("Unexpected tile y coordinate.");
+
+                if (lxInFile != lx)
+                    throw IEX_NAMESPACE::InputExc ("Unexpected tile x level number coordinate.");
+
+                if (lyInFile != ly)
+                    throw IEX_NAMESPACE::InputExc ("Unexpected tile y level number coordinate.");
+
+                Int64 tableSize, dataSize, unpackedDataSize;
+                Xdr::read <StreamIO> (*_data->_streamData->is, tableSize);
+                Xdr::read <StreamIO> (*_data->_streamData->is, dataSize);
+                Xdr::read <StreamIO> (*_data->_streamData->is, unpackedDataSize);
+
+                
+                if(tableSize>_data->maxSampleCountTableSize)
+                {
+                    THROW (IEX_NAMESPACE::ArgExc, "Bad sampleCountTableDataSize read from tile "<< dx << ',' << dy << ',' << lx << ',' << ly << ": expected " << _data->maxSampleCountTableSize << " or less, got "<< tableSize);
+                }
+                    
+                
+                //
+                // We make a check on the data size requirements here.
+                // Whilst we wish to store 64bit sizes on disk, not all the compressors
+                // have been made to work with such data sizes and are still limited to
+                // using signed 32 bit (int) for the data size. As such, this version
+                // insists that we validate that the data size does not exceed the data
+                // type max limit.
+                // @TODO refactor the compressor code to ensure full 64-bit support.
+                //
+
+                Int64 compressorMaxDataSize = Int64(std::numeric_limits<int>::max());
+                if (dataSize         > compressorMaxDataSize ||
+                    unpackedDataSize > compressorMaxDataSize ||
+                    tableSize        > compressorMaxDataSize)
+                {
+                    THROW (IEX_NAMESPACE::ArgExc, "This version of the library does not"
+                          << "support the allocation of data with size  > "
+                          << compressorMaxDataSize
+                          << " file table size    :" << tableSize
+                          << " file unpacked size :" << unpackedDataSize
+                          << " file packed size   :" << dataSize << ".\n");
+                }
+
+                //
+                // Read and uncompress the pixel sample count table.
+                //
+
+                _data->_streamData->is->read(_data->sampleCountTableBuffer, tableSize);
+
+                const char* readPtr;
+
+                if (tableSize < _data->maxSampleCountTableSize)
+                {
+                    if(!_data->sampleCountTableComp)
+                    {
+                        THROW(IEX_NAMESPACE::ArgExc,"Deep scanline data corrupt at tile " << dx << ',' << dy << ',' << lx << ',' <<  ly << " (sampleCountTableDataSize error)");
+                    }
+                    _data->sampleCountTableComp->uncompress(_data->sampleCountTableBuffer,
+                                                            tableSize,
+                                                            tileRange.min.y,
+                                                            readPtr);
+                }
+                else
+                    readPtr = _data->sampleCountTableBuffer;
+
+                size_t cumulative_total_samples =0;
+                int lastAccumulatedCount;
+                for (int j = tileRange.min.y; j <= tileRange.max.y; j++)
+                {
+                    lastAccumulatedCount = 0;
+                    for (int i = tileRange.min.x; i <= tileRange.max.x; i++)
+                    {
+                        int accumulatedCount;
+                        Xdr::read <CharPtrIO> (readPtr, accumulatedCount);
+                        
+                        if (accumulatedCount < lastAccumulatedCount)
+                        {
+                            THROW(IEX_NAMESPACE::ArgExc,"Deep tile sampleCount data corrupt at tile " 
+                                  << dx << ',' << dy << ',' << lx << ',' <<  ly << " (negative sample count detected)");
+                        }
+
+                        int count = accumulatedCount - lastAccumulatedCount;
+                        lastAccumulatedCount = accumulatedCount;
+                        
+                        _data->getSampleCount(i - xOffset, j - yOffset) =count;
+                    }
+                    cumulative_total_samples += lastAccumulatedCount;
+                }
+                
+                if(cumulative_total_samples * _data->combinedSampleSize > unpackedDataSize)
+                {
+                    THROW(IEX_NAMESPACE::ArgExc,"Deep scanline sampleCount data corrupt at tile " 
+                                                << dx << ',' << dy << ',' << lx << ',' <<  ly 
+                                                << ": pixel data only contains " << unpackedDataSize 
+                                                << " bytes of data but table references at least " 
+                                                << cumulative_total_samples*_data->combinedSampleSize << " bytes of sample data" );            
+                }
+                    
+            }
+        }
+
+        _data->_streamData->is->seekg(savedFilePos);
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        REPLACE_EXC (e, "Error reading sample count data from image "
+                        "file \"" << fileName() << "\". " << e);
+
+         _data->_streamData->is->seekg(savedFilePos);
+
+        throw;
+    }
+}
+
+
+void
+DeepTiledInputFile::readPixelSampleCount (int dx, int dy, int l)
+{
+    readPixelSampleCount (dx, dy, l, l);
+}
+
+
+void
+DeepTiledInputFile::readPixelSampleCount (int dx, int dy, int lx, int ly)
+{
+    readPixelSampleCounts (dx, dx, dy, dy, lx, ly);
+}
+
+
+void
+DeepTiledInputFile::readPixelSampleCounts (int dx1, int dx2,
+                                           int dy1, int dy2,
+                                           int l)
+{
+    readPixelSampleCounts (dx1, dx2, dy1, dy2, l, l);
+}
+
+
+size_t
+DeepTiledInputFile::totalTiles() const
+{
+    //
+    // Calculate the total number of tiles in the file
+    //
+    
+    int numAllTiles = 0;
+    
+    switch (levelMode ())
+    {
+        case ONE_LEVEL:
+        case MIPMAP_LEVELS:
+            
+            for (int i_l = 0; i_l < numLevels (); ++i_l)
+                numAllTiles += numXTiles (i_l) * numYTiles (i_l);
+            
+            break;
+            
+        case RIPMAP_LEVELS:
+            
+            for (int i_ly = 0; i_ly < numYLevels (); ++i_ly)
+                for (int i_lx = 0; i_lx < numXLevels (); ++i_lx)
+                    numAllTiles += numXTiles (i_lx) * numYTiles (i_ly);
+                
+                break;
+            
+        default:
+            
+            throw IEX_NAMESPACE::ArgExc ("Unknown LevelMode format.");
+    }
+    return numAllTiles;
+}
+
+
+
+
+void 
+DeepTiledInputFile::getTileOrder(int dx[],int dy[],int lx[],int ly[]) const
+{
+  return _data->tileOffsets.getTileOrder(dx,dy,lx,ly);
+  
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfDeepTiledInputFile.h b/Source/OpenEXR/IlmImf/ImfDeepTiledInputFile.h
new file mode 100644
index 0000000..87294b5
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfDeepTiledInputFile.h
@@ -0,0 +1,437 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+#ifndef INCLUDED_IMF_DEEP_TILED_INPUT_FILE_H
+#define INCLUDED_IMF_DEEP_TILED_INPUT_FILE_H
+
+//-----------------------------------------------------------------------------
+//
+//      class DeepTiledInputFile
+//
+//-----------------------------------------------------------------------------
+
+#include "ImfHeader.h"
+#include "ImfFrameBuffer.h"
+#include "ImathBox.h"
+#include "ImfTileDescription.h"
+#include "ImfThreading.h"
+#include "ImfGenericInputFile.h"
+#include "ImfDeepFrameBuffer.h"
+#include "ImfDeepTiledOutputFile.h"
+#include "ImfForward.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+class IMF_EXPORT DeepTiledInputFile : public GenericInputFile
+{
+  public:
+
+    //--------------------------------------------------------------------
+    // A constructor that opens the file with the specified name, and
+    // reads the file header.  The constructor throws an IEX_NAMESPACE::ArgExc
+    // exception if the file is not tiled.
+    // The numThreads parameter specifies how many worker threads this
+    // file will try to keep busy when decompressing individual tiles.
+    // Destroying TiledInputFile objects constructed with this constructor
+    // automatically closes the corresponding files.
+    //--------------------------------------------------------------------
+
+    DeepTiledInputFile (const char fileName[],
+                    int numThreads = globalThreadCount ());
+
+
+    // ----------------------------------------------------------
+    // A constructor that attaches the new TiledInputFile object
+    // to a file that has already been opened.
+    // Destroying TiledInputFile objects constructed with this
+    // constructor does not automatically close the corresponding
+    // files.
+    // ----------------------------------------------------------
+
+    DeepTiledInputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int numThreads = globalThreadCount ());
+
+
+    //-----------
+    // Destructor
+    //-----------
+
+    virtual ~DeepTiledInputFile ();
+
+
+    //------------------------
+    // Access to the file name
+    //------------------------
+
+    const char *        fileName () const;
+
+
+    //--------------------------
+    // Access to the file header
+    //--------------------------
+
+    const Header &      header () const;
+
+
+    //----------------------------------
+    // Access to the file format version
+    //----------------------------------
+
+    int                 version () const;
+
+
+    //-----------------------------------------------------------
+    // Set the current frame buffer -- copies the FrameBuffer
+    // object into the TiledInputFile object.
+    //
+    // The current frame buffer is the destination for the pixel
+    // data read from the file.  The current frame buffer must be
+    // set at least once before readTile() is called.
+    // The current frame buffer can be changed after each call
+    // to readTile().
+    //-----------------------------------------------------------
+
+    void                setFrameBuffer (const DeepFrameBuffer &frameBuffer);
+
+
+    //-----------------------------------
+    // Access to the current frame buffer
+    //-----------------------------------
+
+    const DeepFrameBuffer & frameBuffer () const;
+
+
+    //------------------------------------------------------------
+    // Check if the file is complete:
+    //
+    // isComplete() returns true if all pixels in the data window
+    // (in all levels) are present in the input file, or false if
+    // any pixels are missing.  (Another program may still be busy
+    // writing the file, or file writing may have been aborted
+    // prematurely.)
+    //------------------------------------------------------------
+
+    bool                isComplete () const;
+
+
+    //--------------------------------------------------
+    // Utility functions:
+    //--------------------------------------------------
+
+    //---------------------------------------------------------
+    // Multiresolution mode and tile size:
+    // The following functions return the xSize, ySize and mode
+    // fields of the file header's TileDescriptionAttribute.
+    //---------------------------------------------------------
+
+    unsigned int        tileXSize () const;
+    unsigned int        tileYSize () const;
+    LevelMode           levelMode () const;
+    LevelRoundingMode   levelRoundingMode () const;
+
+
+    //--------------------------------------------------------------------
+    // Number of levels:
+    //
+    // numXLevels() returns the file's number of levels in x direction.
+    //
+    //  if levelMode() == ONE_LEVEL:
+    //      return value is: 1
+    //
+    //  if levelMode() == MIPMAP_LEVELS:
+    //      return value is: rfunc (log (max (w, h)) / log (2)) + 1
+    //
+    //  if levelMode() == RIPMAP_LEVELS:
+    //      return value is: rfunc (log (w) / log (2)) + 1
+    //
+    //  where
+    //      w is the width of the image's data window,  max.x - min.x + 1,
+    //      y is the height of the image's data window, max.y - min.y + 1,
+    //      and rfunc(x) is either floor(x), or ceil(x), depending on
+    //      whether levelRoundingMode() returns ROUND_DOWN or ROUND_UP.
+    //
+    // numYLevels() returns the file's number of levels in y direction.
+    //
+    //  if levelMode() == ONE_LEVEL or levelMode() == MIPMAP_LEVELS:
+    //      return value is the same as for numXLevels()
+    //
+    //  if levelMode() == RIPMAP_LEVELS:
+    //      return value is: rfunc (log (h) / log (2)) + 1
+    //
+    //
+    // numLevels() is a convenience function for use with
+    // MIPMAP_LEVELS files.
+    //
+    //  if levelMode() == ONE_LEVEL or levelMode() == MIPMAP_LEVELS:
+    //      return value is the same as for numXLevels()
+    //
+    //  if levelMode() == RIPMAP_LEVELS:
+    //      an IEX_NAMESPACE::LogicExc exception is thrown
+    //
+    // isValidLevel(lx, ly) returns true if the file contains
+    // a level with level number (lx, ly), false if not.
+    //
+    // totalTiles() returns the total number of tiles in the image
+    //
+    //--------------------------------------------------------------------
+
+    int                 numLevels () const;
+    int                 numXLevels () const;
+    int                 numYLevels () const;
+    bool                isValidLevel (int lx, int ly) const;
+    size_t              totalTiles() const;
+
+    //----------------------------------------------------------
+    // Dimensions of a level:
+    //
+    // levelWidth(lx) returns the width of a level with level
+    // number (lx, *), where * is any number.
+    //
+    //  return value is:
+    //      max (1, rfunc (w / pow (2, lx)))
+    //
+    //
+    // levelHeight(ly) returns the height of a level with level
+    // number (*, ly), where * is any number.
+    //
+    //  return value is:
+    //      max (1, rfunc (h / pow (2, ly)))
+    //
+    //----------------------------------------------------------
+
+    int                 levelWidth  (int lx) const;
+    int                 levelHeight (int ly) const;
+
+
+    //--------------------------------------------------------------
+    // Number of tiles:
+    //
+    // numXTiles(lx) returns the number of tiles in x direction
+    // that cover a level with level number (lx, *), where * is
+    // any number.
+    //
+    //  return value is:
+    //      (levelWidth(lx) + tileXSize() - 1) / tileXSize()
+    //
+    //
+    // numYTiles(ly) returns the number of tiles in y direction
+    // that cover a level with level number (*, ly), where * is
+    // any number.
+    //
+    //  return value is:
+    //      (levelHeight(ly) + tileXSize() - 1) / tileXSize()
+    //
+    //--------------------------------------------------------------
+
+    int                 numXTiles (int lx = 0) const;
+    int                 numYTiles (int ly = 0) const;
+
+
+    //---------------------------------------------------------------
+    // Level pixel ranges:
+    //
+    // dataWindowForLevel(lx, ly) returns a 2-dimensional region of
+    // valid pixel coordinates for a level with level number (lx, ly)
+    //
+    //  return value is a Box2i with min value:
+    //      (dataWindow.min.x, dataWindow.min.y)
+    //
+    //  and max value:
+    //      (dataWindow.min.x + levelWidth(lx) - 1,
+    //       dataWindow.min.y + levelHeight(ly) - 1)
+    //
+    // dataWindowForLevel(level) is a convenience function used
+    // for ONE_LEVEL and MIPMAP_LEVELS files.  It returns
+    // dataWindowForLevel(level, level).
+    //
+    //---------------------------------------------------------------
+
+    IMATH_NAMESPACE::Box2i        dataWindowForLevel (int l = 0) const;
+    IMATH_NAMESPACE::Box2i        dataWindowForLevel (int lx, int ly) const;
+
+
+    //-------------------------------------------------------------------
+    // Tile pixel ranges:
+    //
+    // dataWindowForTile(dx, dy, lx, ly) returns a 2-dimensional
+    // region of valid pixel coordinates for a tile with tile coordinates
+    // (dx,dy) and level number (lx, ly).
+    //
+    //  return value is a Box2i with min value:
+    //      (dataWindow.min.x + dx * tileXSize(),
+    //       dataWindow.min.y + dy * tileYSize())
+    //
+    //  and max value:
+    //      (dataWindow.min.x + (dx + 1) * tileXSize() - 1,
+    //       dataWindow.min.y + (dy + 1) * tileYSize() - 1)
+    //
+    // dataWindowForTile(dx, dy, level) is a convenience function
+    // used for ONE_LEVEL and MIPMAP_LEVELS files.  It returns
+    // dataWindowForTile(dx, dy, level, level).
+    //
+    //-------------------------------------------------------------------
+
+    IMATH_NAMESPACE::Box2i        dataWindowForTile (int dx, int dy, int l = 0) const;
+
+    IMATH_NAMESPACE::Box2i        dataWindowForTile (int dx, int dy,
+                                           int lx, int ly) const;
+
+    //------------------------------------------------------------
+    // Read pixel data:
+    //
+    // readTile(dx, dy, lx, ly) reads the tile with tile
+    // coordinates (dx, dy), and level number (lx, ly),
+    // and stores it in the current frame buffer.
+    //
+    //   dx must lie in the interval [0, numXTiles(lx)-1]
+    //   dy must lie in the interval [0, numYTiles(ly)-1]
+    //
+    //   lx must lie in the interval [0, numXLevels()-1]
+    //   ly must lie in the inverval [0, numYLevels()-1]
+    //
+    // readTile(dx, dy, level) is a convenience function used
+    // for ONE_LEVEL and MIPMAP_LEVELS files.  It calls
+    // readTile(dx, dy, level, level).
+    //
+    // The two readTiles(dx1, dx2, dy1, dy2, ...) functions allow
+    // reading multiple tiles at once.  If multi-threading is used
+    // the multiple tiles are read concurrently.
+    //
+    // Pixels that are outside the pixel coordinate range for the
+    // tile's level, are never accessed by readTile().
+    //
+    // Attempting to access a tile that is not present in the file
+    // throws an InputExc exception.
+    //
+    //------------------------------------------------------------
+
+    void                readTile  (int dx, int dy, int l = 0);
+    void                readTile  (int dx, int dy, int lx, int ly);
+
+    void                readTiles (int dx1, int dx2, int dy1, int dy2,
+                                   int lx, int ly);
+
+    void                readTiles (int dx1, int dx2, int dy1, int dy2,
+                                   int l = 0);
+
+
+    //--------------------------------------------------
+    // Read a tile of raw pixel data from the file,
+    // without uncompressing it (this function is
+    // used to implement TiledOutputFile::copyPixels()).
+    //--------------------------------------------------
+
+    void                rawTileData (int &dx, int &dy,
+                                     int &lx, int &ly,
+                                     char *pixelData,
+                                     Int64 &dataSize) const;
+
+    //------------------------------------------------------------------
+    // Read pixel sample counts into a slice in the frame buffer.
+    //
+    // readPixelSampleCount(dx, dy, lx, ly) reads the sample counts
+    // for tile (dx, dy) in level (lx, ly).
+    //
+    // readPixelSampleCount(dx, dy, l) calls
+    // readPixelSampleCount(dx, dy, lx = l, ly = l)
+    //
+    // dx must lie in the interval [0, numXTiles(lx)-1]
+    // dy must lie in the interval [0, numYTiles(ly)-1]
+    //
+    // lx must lie in the interval [0, numXLevels()-1]
+    // ly must lie in the inverval [0, numYLevels()-1]
+    //
+    // readPixelSampleCounts(dx1, dx2, dy1, dy2, lx, ly) reads all
+    // the sample counts for tiles within range
+    // [(min(dx1, dx2), min(dy1, dy2))...(max(dx1, dx2), max(dy1, dy2)],
+    // and on level (lx, ly)
+    //
+    // readPixelSampleCounts(dx1, dx2, dy1, dy2, l) calls
+    // readPixelSampleCounts(dx1, dx2, dy1, dy2, lx = l, ly = l).
+    //------------------------------------------------------------------
+
+    void                readPixelSampleCount  (int dx, int dy, int l = 0);
+    void                readPixelSampleCount  (int dx, int dy, int lx, int ly);
+
+    void                readPixelSampleCounts (int dx1, int dx2,
+                                              int dy1, int dy2,
+                                              int lx, int ly);
+
+    void                readPixelSampleCounts (int dx1, int dx2,
+                                              int dy1, int dy2,
+                                              int l = 0);
+
+    struct Data;
+
+    
+    
+  private:
+
+    friend class InputFile;
+    friend class MultiPartInputFile;
+
+    DeepTiledInputFile (InputPartData* part);
+
+    DeepTiledInputFile (const DeepTiledInputFile &);              // not implemented
+    DeepTiledInputFile & operator = (const DeepTiledInputFile &); // not implemented
+
+    DeepTiledInputFile (const Header &header, OPENEXR_IMF_INTERNAL_NAMESPACE::IStream *is, int version,
+                    int numThreads);
+
+    void                initialize ();
+    void                multiPartInitialize(InputPartData* part);
+    void                compatibilityInitialize(OPENEXR_IMF_INTERNAL_NAMESPACE::IStream& is);
+
+    bool                isValidTile (int dx, int dy,
+                                     int lx, int ly) const;
+
+    size_t              bytesPerLineForTile (int dx, int dy,
+                                             int lx, int ly) const;
+           
+                                                
+    void                getTileOrder(int dx[],int dy[],int lx[],int ly[]) const;
+                                             
+    
+    Data *              _data;
+
+
+    // needed for copyPixels
+    friend void DeepTiledOutputFile::copyPixels(DeepTiledInputFile &);
+};
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif
diff --git a/Source/OpenEXR/IlmImf/ImfDeepTiledInputPart.cpp b/Source/OpenEXR/IlmImf/ImfDeepTiledInputPart.cpp
new file mode 100644
index 0000000..1262f23
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfDeepTiledInputPart.cpp
@@ -0,0 +1,273 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+#include "ImfDeepTiledInputPart.h"
+#include "ImfMultiPartInputFile.h"
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+DeepTiledInputPart::DeepTiledInputPart(MultiPartInputFile& multiPartFile, int partNumber)
+{
+    file = multiPartFile.getInputPart<DeepTiledInputFile>(partNumber);
+}
+
+
+const char *
+DeepTiledInputPart::fileName () const
+{
+    return file->fileName();
+}
+
+
+const Header &
+DeepTiledInputPart::header () const
+{
+    return file->header();
+}
+
+
+int
+DeepTiledInputPart::version () const
+{
+    return file->version();
+}
+
+
+void
+DeepTiledInputPart::setFrameBuffer (const DeepFrameBuffer &frameBuffer)
+{
+    file->setFrameBuffer(frameBuffer);
+}
+
+
+const DeepFrameBuffer &
+DeepTiledInputPart::frameBuffer () const
+{
+    return file->frameBuffer();
+}
+
+
+bool
+DeepTiledInputPart::isComplete () const
+{
+    return file->isComplete();
+}
+
+
+unsigned int
+DeepTiledInputPart::tileXSize () const
+{
+    return file->isComplete();
+}
+
+
+unsigned int
+DeepTiledInputPart::tileYSize () const
+{
+    return file->tileYSize();
+}
+
+
+LevelMode
+DeepTiledInputPart::levelMode () const
+{
+    return file->levelMode();
+}
+
+
+LevelRoundingMode
+DeepTiledInputPart::levelRoundingMode () const
+{
+    return file->levelRoundingMode();
+}
+
+
+int
+DeepTiledInputPart::numLevels () const
+{
+    return file->numLevels();
+}
+
+
+int
+DeepTiledInputPart::numXLevels () const
+{
+    return file->numXLevels();
+}
+
+
+int
+DeepTiledInputPart::numYLevels () const
+{
+    return file->numYLevels();
+}
+
+
+bool
+DeepTiledInputPart::isValidLevel (int lx, int ly) const
+{
+    return file->isValidLevel(lx, ly);
+}
+
+
+int
+DeepTiledInputPart::levelWidth  (int lx) const
+{
+    return file->levelWidth(lx);
+}
+
+
+int
+DeepTiledInputPart::levelHeight (int ly) const
+{
+    return file->levelHeight(ly);
+}
+
+
+int
+DeepTiledInputPart::numXTiles (int lx) const
+{
+    return file->numXTiles(lx);
+}
+
+
+int
+DeepTiledInputPart::numYTiles (int ly) const
+{
+    return file->numYTiles(ly);
+}
+
+
+IMATH_NAMESPACE::Box2i
+DeepTiledInputPart::dataWindowForLevel (int l) const
+{
+    return file->dataWindowForLevel(l);
+}
+
+IMATH_NAMESPACE::Box2i
+DeepTiledInputPart::dataWindowForLevel (int lx, int ly) const
+{
+    return file->dataWindowForLevel(lx, ly);
+}
+
+
+IMATH_NAMESPACE::Box2i
+DeepTiledInputPart::dataWindowForTile (int dx, int dy, int l) const
+{
+    return file->dataWindowForTile(dx, dy, l);
+}
+
+
+IMATH_NAMESPACE::Box2i
+DeepTiledInputPart::dataWindowForTile (int dx, int dy,
+                                       int lx, int ly) const
+{
+    return file->dataWindowForTile(dx, dy, lx, ly);
+}
+
+
+void
+DeepTiledInputPart::readTile  (int dx, int dy, int l)
+{
+    file->readTile(dx, dy, l);
+}
+
+
+void
+DeepTiledInputPart::readTile  (int dx, int dy, int lx, int ly)
+{
+    file->readTile(dx, dy, lx, ly);
+}
+
+
+void
+DeepTiledInputPart::readTiles (int dx1, int dx2, int dy1, int dy2,
+                               int lx, int ly)
+{
+    file->readTiles(dx1, dx2, dy1, dy2, lx, ly);
+}
+
+
+void
+DeepTiledInputPart::readTiles (int dx1, int dx2, int dy1, int dy2,
+                               int l)
+{
+    file->readTiles(dx1, dx2, dy1, dy2, l);
+}
+
+
+void
+DeepTiledInputPart::rawTileData (int &dx, int &dy,
+                                 int &lx, int &ly,
+                                 char * pixelData,
+                                 Int64 & dataSize) const
+{
+    file->rawTileData(dx, dy, lx, ly, pixelData, dataSize );
+}
+
+
+void
+DeepTiledInputPart::readPixelSampleCount  (int dx, int dy, int l)
+{
+    file->readPixelSampleCount(dx, dy, l);
+}
+
+
+void
+DeepTiledInputPart::readPixelSampleCount  (int dx, int dy, int lx, int ly)
+{
+    file->readPixelSampleCount(dx, dy, lx, ly);
+}
+
+
+void
+DeepTiledInputPart::readPixelSampleCounts (int dx1, int dx2,
+                                          int dy1, int dy2,
+                                          int lx, int ly)
+{
+    file->readPixelSampleCounts(dx1, dx2, dy1, dy2, lx, ly);
+}
+
+void
+DeepTiledInputPart::readPixelSampleCounts (int dx1, int dx2,
+                                          int dy1, int dy2,
+                                          int l)
+{
+    file->readPixelSampleCounts(dx1, dx2, dy1, dy2, l);
+}
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfDeepTiledInputPart.h b/Source/OpenEXR/IlmImf/ImfDeepTiledInputPart.h
new file mode 100644
index 0000000..8663639
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfDeepTiledInputPart.h
@@ -0,0 +1,362 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+#ifndef IMFDEEPTILEDINPUTPART_H_
+#define IMFDEEPTILEDINPUTPART_H_
+
+#include "ImfDeepTiledInputFile.h"
+#include "ImfNamespace.h"
+#include "ImfForward.h"
+#include "ImfExport.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+class IMF_EXPORT DeepTiledInputPart
+{
+  public:
+
+    DeepTiledInputPart(MultiPartInputFile& multiPartFile, int partNumber);
+
+    //------------------------
+    // Access to the file name
+    //------------------------
+
+    const char *        fileName () const;
+
+
+    //--------------------------
+    // Access to the file header
+    //--------------------------
+
+    const Header &      header () const;
+
+
+    //----------------------------------
+    // Access to the file format version
+    //----------------------------------
+
+    int                 version () const;
+
+
+    //-----------------------------------------------------------
+    // Set the current frame buffer -- copies the FrameBuffer
+    // object into the TiledInputFile object.
+    //
+    // The current frame buffer is the destination for the pixel
+    // data read from the file.  The current frame buffer must be
+    // set at least once before readTile() is called.
+    // The current frame buffer can be changed after each call
+    // to readTile().
+    //-----------------------------------------------------------
+
+    void                setFrameBuffer (const DeepFrameBuffer &frameBuffer);
+
+
+    //-----------------------------------
+    // Access to the current frame buffer
+    //-----------------------------------
+
+    const DeepFrameBuffer & frameBuffer () const;
+
+
+    //------------------------------------------------------------
+    // Check if the file is complete:
+    //
+    // isComplete() returns true if all pixels in the data window
+    // (in all levels) are present in the input file, or false if
+    // any pixels are missing.  (Another program may still be busy
+    // writing the file, or file writing may have been aborted
+    // prematurely.)
+    //------------------------------------------------------------
+
+    bool                isComplete () const;
+
+
+    //--------------------------------------------------
+    // Utility functions:
+    //--------------------------------------------------
+
+    //---------------------------------------------------------
+    // Multiresolution mode and tile size:
+    // The following functions return the xSize, ySize and mode
+    // fields of the file header's TileDescriptionAttribute.
+    //---------------------------------------------------------
+
+    unsigned int        tileXSize () const;
+    unsigned int        tileYSize () const;
+    LevelMode           levelMode () const;
+    LevelRoundingMode   levelRoundingMode () const;
+
+
+    //--------------------------------------------------------------------
+    // Number of levels:
+    //
+    // numXLevels() returns the file's number of levels in x direction.
+    //
+    //  if levelMode() == ONE_LEVEL:
+    //      return value is: 1
+    //
+    //  if levelMode() == MIPMAP_LEVELS:
+    //      return value is: rfunc (log (max (w, h)) / log (2)) + 1
+    //
+    //  if levelMode() == RIPMAP_LEVELS:
+    //      return value is: rfunc (log (w) / log (2)) + 1
+    //
+    //  where
+    //      w is the width of the image's data window,  max.x - min.x + 1,
+    //      y is the height of the image's data window, max.y - min.y + 1,
+    //      and rfunc(x) is either floor(x), or ceil(x), depending on
+    //      whether levelRoundingMode() returns ROUND_DOWN or ROUND_UP.
+    //
+    // numYLevels() returns the file's number of levels in y direction.
+    //
+    //  if levelMode() == ONE_LEVEL or levelMode() == MIPMAP_LEVELS:
+    //      return value is the same as for numXLevels()
+    //
+    //  if levelMode() == RIPMAP_LEVELS:
+    //      return value is: rfunc (log (h) / log (2)) + 1
+    //
+    //
+    // numLevels() is a convenience function for use with
+    // MIPMAP_LEVELS files.
+    //
+    //  if levelMode() == ONE_LEVEL or levelMode() == MIPMAP_LEVELS:
+    //      return value is the same as for numXLevels()
+    //
+    //  if levelMode() == RIPMAP_LEVELS:
+    //      an IEX_NAMESPACE::LogicExc exception is thrown
+    //
+    // isValidLevel(lx, ly) returns true if the file contains
+    // a level with level number (lx, ly), false if not.
+    //
+    //--------------------------------------------------------------------
+
+    int                 numLevels () const;
+    int                 numXLevels () const;
+    int                 numYLevels () const;
+    bool                isValidLevel (int lx, int ly) const;
+
+
+    //----------------------------------------------------------
+    // Dimensions of a level:
+    //
+    // levelWidth(lx) returns the width of a level with level
+    // number (lx, *), where * is any number.
+    //
+    //  return value is:
+    //      max (1, rfunc (w / pow (2, lx)))
+    //
+    //
+    // levelHeight(ly) returns the height of a level with level
+    // number (*, ly), where * is any number.
+    //
+    //  return value is:
+    //      max (1, rfunc (h / pow (2, ly)))
+    //
+    //----------------------------------------------------------
+
+    int                 levelWidth  (int lx) const;
+    int                 levelHeight (int ly) const;
+
+
+    //--------------------------------------------------------------
+    // Number of tiles:
+    //
+    // numXTiles(lx) returns the number of tiles in x direction
+    // that cover a level with level number (lx, *), where * is
+    // any number.
+    //
+    //  return value is:
+    //      (levelWidth(lx) + tileXSize() - 1) / tileXSize()
+    //
+    //
+    // numYTiles(ly) returns the number of tiles in y direction
+    // that cover a level with level number (*, ly), where * is
+    // any number.
+    //
+    //  return value is:
+    //      (levelHeight(ly) + tileXSize() - 1) / tileXSize()
+    //
+    //--------------------------------------------------------------
+
+    int                 numXTiles (int lx = 0) const;
+    int                 numYTiles (int ly = 0) const;
+
+
+    //---------------------------------------------------------------
+    // Level pixel ranges:
+    //
+    // dataWindowForLevel(lx, ly) returns a 2-dimensional region of
+    // valid pixel coordinates for a level with level number (lx, ly)
+    //
+    //  return value is a Box2i with min value:
+    //      (dataWindow.min.x, dataWindow.min.y)
+    //
+    //  and max value:
+    //      (dataWindow.min.x + levelWidth(lx) - 1,
+    //       dataWindow.min.y + levelHeight(ly) - 1)
+    //
+    // dataWindowForLevel(level) is a convenience function used
+    // for ONE_LEVEL and MIPMAP_LEVELS files.  It returns
+    // dataWindowForLevel(level, level).
+    //
+    //---------------------------------------------------------------
+
+    IMATH_NAMESPACE::Box2i        dataWindowForLevel (int l = 0) const;
+    IMATH_NAMESPACE::Box2i        dataWindowForLevel (int lx, int ly) const;
+
+
+    //-------------------------------------------------------------------
+    // Tile pixel ranges:
+    //
+    // dataWindowForTile(dx, dy, lx, ly) returns a 2-dimensional
+    // region of valid pixel coordinates for a tile with tile coordinates
+    // (dx,dy) and level number (lx, ly).
+    //
+    //  return value is a Box2i with min value:
+    //      (dataWindow.min.x + dx * tileXSize(),
+    //       dataWindow.min.y + dy * tileYSize())
+    //
+    //  and max value:
+    //      (dataWindow.min.x + (dx + 1) * tileXSize() - 1,
+    //       dataWindow.min.y + (dy + 1) * tileYSize() - 1)
+    //
+    // dataWindowForTile(dx, dy, level) is a convenience function
+    // used for ONE_LEVEL and MIPMAP_LEVELS files.  It returns
+    // dataWindowForTile(dx, dy, level, level).
+    //
+    //-------------------------------------------------------------------
+
+    IMATH_NAMESPACE::Box2i        dataWindowForTile (int dx, int dy, int l = 0) const;
+
+    IMATH_NAMESPACE::Box2i        dataWindowForTile (int dx, int dy,
+                                         int lx, int ly) const;
+
+    //------------------------------------------------------------
+    // Read pixel data:
+    //
+    // readTile(dx, dy, lx, ly) reads the tile with tile
+    // coordinates (dx, dy), and level number (lx, ly),
+    // and stores it in the current frame buffer.
+    //
+    //   dx must lie in the interval [0, numXTiles(lx)-1]
+    //   dy must lie in the interval [0, numYTiles(ly)-1]
+    //
+    //   lx must lie in the interval [0, numXLevels()-1]
+    //   ly must lie in the inverval [0, numYLevels()-1]
+    //
+    // readTile(dx, dy, level) is a convenience function used
+    // for ONE_LEVEL and MIPMAP_LEVELS files.  It calls
+    // readTile(dx, dy, level, level).
+    //
+    // The two readTiles(dx1, dx2, dy1, dy2, ...) functions allow
+    // reading multiple tiles at once.  If multi-threading is used
+    // the multiple tiles are read concurrently.
+    //
+    // Pixels that are outside the pixel coordinate range for the
+    // tile's level, are never accessed by readTile().
+    //
+    // Attempting to access a tile that is not present in the file
+    // throws an InputExc exception.
+    //
+    //------------------------------------------------------------
+
+    void                readTile  (int dx, int dy, int l = 0);
+    void                readTile  (int dx, int dy, int lx, int ly);
+
+    void                readTiles (int dx1, int dx2, int dy1, int dy2,
+                                 int lx, int ly);
+
+    void                readTiles (int dx1, int dx2, int dy1, int dy2,
+                                 int l = 0);
+
+
+    //--------------------------------------------------
+    // Read a tile of raw pixel data from the file,
+    // without uncompressing it (this function is
+    // used to implement TiledOutputFile::copyPixels()).
+    //--------------------------------------------------
+
+    void                rawTileData (int &dx, int &dy,
+                                   int &lx, int &ly,
+                                   char *data,
+                                   Int64 &dataSize
+                                   ) const;
+
+    //------------------------------------------------------------------
+    // Read pixel sample counts into a slice in the frame buffer.
+    //
+    // readPixelSampleCount(dx, dy, lx, ly) reads the sample counts
+    // for tile (dx, dy) in level (lx, ly).
+    //
+    // readPixelSampleCount(dx, dy, l) calls
+    // readPixelSampleCount(dx, dy, lx = l, ly = l)
+    //
+    // dx must lie in the interval [0, numXTiles(lx)-1]
+    // dy must lie in the interval [0, numYTiles(ly)-1]
+    //
+    // lx must lie in the interval [0, numXLevels()-1]
+    // ly must lie in the inverval [0, numYLevels()-1]
+    //
+    // readPixelSampleCounts(dx1, dx2, dy1, dy2, lx, ly) reads all
+    // the sample counts for tiles within range
+    // [(min(dx1, dx2), min(dy1, dy2))...(max(dx1, dx2), max(dy1, dy2)],
+    // and on level (lx, ly)
+    //
+    // readPixelSampleCounts(dx1, dx2, dy1, dy2, l) calls
+    // readPixelSampleCounts(dx1, dx2, dy1, dy2, lx = l, ly = l).
+    //------------------------------------------------------------------
+
+    void                readPixelSampleCount  (int dx, int dy, int l = 0);
+    void                readPixelSampleCount  (int dx, int dy, int lx, int ly);
+
+    void                readPixelSampleCounts (int dx1, int dx2,
+                                            int dy1, int dy2,
+                                            int lx, int ly);
+
+    void                readPixelSampleCounts (int dx1, int dx2,
+                                            int dy1, int dy2,
+                                            int l = 0);
+
+  private:
+    DeepTiledInputFile* file;
+
+    friend void DeepTiledOutputFile::copyPixels(DeepTiledInputPart &);
+};
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+#endif /* IMFDEEPTILEDINPUTPART_H_ */
diff --git a/Source/OpenEXR/IlmImf/ImfDeepTiledOutputFile.cpp b/Source/OpenEXR/IlmImf/ImfDeepTiledOutputFile.cpp
new file mode 100644
index 0000000..a9b226b
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfDeepTiledOutputFile.cpp
@@ -0,0 +1,2055 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+//-----------------------------------------------------------------------------
+//
+//      class DeepTiledOutputFile
+//
+//-----------------------------------------------------------------------------
+
+#include "ImfDeepTiledOutputFile.h"
+#include "ImfDeepTiledInputFile.h"
+#include "ImfDeepTiledInputPart.h"
+#include "ImfInputFile.h"
+#include "ImfTileDescriptionAttribute.h"
+#include "ImfPreviewImageAttribute.h"
+#include "ImfChannelList.h"
+#include "ImfMisc.h"
+#include "ImfTiledMisc.h"
+#include "ImfStdIO.h"
+#include "ImfCompressor.h"
+#include "ImfOutputStreamMutex.h"
+#include "ImfOutputPartData.h"
+#include "ImfArray.h"
+#include "ImfXdr.h"
+#include "ImfVersion.h"
+#include "ImfTileOffsets.h"
+#include "ImfThreading.h"
+#include "ImfPartType.h"
+
+#include "ImathBox.h"
+
+#include "IlmThreadPool.h"
+#include "IlmThreadSemaphore.h"
+#include "IlmThreadMutex.h"
+
+#include "Iex.h"
+
+#include <string>
+#include <vector>
+#include <fstream>
+#include <assert.h>
+#include <map>
+#include <algorithm>
+
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+using IMATH_NAMESPACE::Box2i;
+using IMATH_NAMESPACE::V2i;
+using std::string;
+using std::vector;
+using std::ofstream;
+using std::map;
+using std::min;
+using std::max;
+using std::swap;
+using ILMTHREAD_NAMESPACE::Mutex;
+using ILMTHREAD_NAMESPACE::Lock;
+using ILMTHREAD_NAMESPACE::Semaphore;
+using ILMTHREAD_NAMESPACE::Task;
+using ILMTHREAD_NAMESPACE::TaskGroup;
+using ILMTHREAD_NAMESPACE::ThreadPool;
+
+namespace {
+
+struct TOutSliceInfo
+{
+    PixelType                   type;
+    const char *                base;
+    size_t                      sampleStride;
+    size_t                      xStride;
+    size_t                      yStride;
+    bool                        zero;
+    int                         xTileCoords;
+    int                         yTileCoords;
+
+    TOutSliceInfo (PixelType type = HALF,
+                   size_t sampleStride = 0,
+                   size_t xStride = 0,
+                   size_t yStride = 0,
+                   bool zero = false,
+                   int xTileCoords = 0,
+                   int yTileCoords = 0);
+};
+
+
+TOutSliceInfo::TOutSliceInfo (PixelType t,
+                              size_t spst,
+                              size_t xStride,
+                              size_t yStride,
+                              bool z,
+                              int xtc,
+                              int ytc)
+:
+    type (t),
+    sampleStride (spst),
+    xStride(xStride),
+    yStride(yStride),
+    zero (z),
+    xTileCoords (xtc),
+    yTileCoords (ytc)
+{
+    // empty
+}
+
+
+struct TileCoord
+{
+    int         dx;
+    int         dy;
+    int         lx;
+    int         ly;
+
+
+    TileCoord (int xTile = 0, int yTile = 0,
+               int xLevel = 0, int yLevel = 0)
+    :
+        dx (xTile),  dy (yTile),
+        lx (xLevel), ly (yLevel)
+    {
+        // empty
+    }
+
+
+    bool
+    operator < (const TileCoord &other) const
+    {
+        return (ly < other.ly) ||
+               (ly == other.ly && lx < other.lx) ||
+               ((ly == other.ly && lx == other.lx) &&
+                    ((dy < other.dy) || (dy == other.dy && dx < other.dx)));
+    }
+
+
+    bool
+    operator == (const TileCoord &other) const
+    {
+        return lx == other.lx &&
+               ly == other.ly &&
+               dx == other.dx &&
+               dy == other.dy;
+    }
+};
+
+
+struct BufferedTile
+{
+    char *      pixelData;
+    Int64         pixelDataSize;
+    Int64         unpackedDataSize;
+    char *      sampleCountTableData;
+    Int64         sampleCountTableSize;
+
+    BufferedTile (const char *data, int size, int unpackedSize,
+                  const char *tableData, int tableSize):
+        pixelData (0),
+        pixelDataSize(size),
+        unpackedDataSize(unpackedSize),
+        sampleCountTableData(0),
+        sampleCountTableSize(tableSize)
+    {
+        pixelData = new char[pixelDataSize];
+        memcpy (pixelData, data, pixelDataSize);
+
+        sampleCountTableData = new char[tableSize];
+        memcpy (sampleCountTableData, tableData, tableSize);
+    }
+
+    ~BufferedTile()
+    {
+        delete [] pixelData;
+        delete [] sampleCountTableData;
+    }
+};
+
+
+typedef map <TileCoord, BufferedTile *> TileMap;
+
+
+struct TileBuffer
+{
+    Array<char>         buffer;
+    const char *        dataPtr;
+    Int64               dataSize;
+    Int64               uncompressedSize;
+    Compressor *        compressor;
+    Array<char>         sampleCountTableBuffer;
+    const char *        sampleCountTablePtr;
+    Int64               sampleCountTableSize;
+    Compressor*         sampleCountTableCompressor;
+    TileCoord           tileCoord;
+    bool                hasException;
+    string              exception;
+
+     TileBuffer ();
+    ~TileBuffer ();
+
+    inline void         wait () {_sem.wait();}
+    inline void         post () {_sem.post();}
+
+  protected:
+
+    Semaphore           _sem;
+};
+
+
+TileBuffer::TileBuffer ():
+    dataPtr (0),
+    dataSize (0),
+    compressor (0),
+    sampleCountTablePtr (0),
+    sampleCountTableCompressor (0),
+    hasException (false),
+    exception (),
+    _sem (1)
+{
+    // empty
+}
+
+
+TileBuffer::~TileBuffer ()
+{
+    if (compressor != 0)
+        delete compressor;
+
+    if (sampleCountTableCompressor != 0)
+        delete sampleCountTableCompressor;
+}
+
+
+} // namespace
+
+
+struct DeepTiledOutputFile::Data
+{
+    Header              header;                 // the image header
+    int                 version;                // file format version
+    bool                multipart;              // file is multipart
+    TileDescription     tileDesc;               // describes the tile layout
+    DeepFrameBuffer     frameBuffer;            // framebuffer to write into
+    Int64               previewPosition;
+    LineOrder           lineOrder;              // the file's lineorder
+    int                 minX;                   // data window's min x coord
+    int                 maxX;                   // data window's max x coord
+    int                 minY;                   // data window's min y coord
+    int                 maxY;                   // data window's max x coord
+
+    int                 numXLevels;             // number of x levels
+    int                 numYLevels;             // number of y levels
+    int *               numXTiles;              // number of x tiles at a level
+    int *               numYTiles;              // number of y tiles at a level
+
+    TileOffsets         tileOffsets;            // stores offsets in file for
+                                                // each tile
+
+    Compressor::Format  format;                 // compressor's data format
+    vector<TOutSliceInfo*> slices;              // info about channels in file
+
+    vector<TileBuffer*> tileBuffers;
+
+    Int64               tileOffsetsPosition;    // position of the tile index
+
+    TileMap             tileMap;                // the map of buffered tiles
+    TileCoord           nextTileToWrite;
+
+    int                 partNumber;             // the output part number
+
+    char*               sampleCountSliceBase;   // the pointer to the number
+                                                // of samples in each pixel
+    int                 sampleCountXStride;     // the x stride for sampleCountSliceBase
+    int                 sampleCountYStride;     // the y stride for sampleCountSliceBase
+    int                 sampleCountXTileCoords; // using x coordinates relative to current tile
+    int                 sampleCountYTileCoords; // using y coordinates relative to current tile
+
+    Int64                 maxSampleCountTableSize;// the max size in bytes for a pixel
+                                                // sample count table
+    OutputStreamMutex*  _streamData;
+    bool                _deleteStream;
+                                                
+     Data (int numThreads);
+    ~Data ();
+
+    inline TileBuffer * getTileBuffer (int number);
+                                                // hash function from tile
+                                                // buffer coords into our
+                                                // vector of tile buffers
+
+    int&                getSampleCount(int x, int y);
+                                                // get the number of samples
+                                                // in each pixel
+
+    TileCoord           nextTileCoord (const TileCoord &a);
+};
+
+
+DeepTiledOutputFile::Data::Data (int numThreads):
+    numXTiles(0),
+    numYTiles(0),
+    tileOffsetsPosition (0),
+    partNumber(-1),
+    _streamData(NULL),
+    _deleteStream(true)
+{
+    //
+    // We need at least one tileBuffer, but if threading is used,
+    // to keep n threads busy we need 2*n tileBuffers
+    //
+
+    tileBuffers.resize (max (1, 2 * numThreads));
+    for (size_t i = 0; i < tileBuffers.size(); i++)
+        tileBuffers[i] = 0;
+}
+
+
+DeepTiledOutputFile::Data::~Data ()
+{
+    delete [] numXTiles;
+    delete [] numYTiles;
+
+    //
+    // Delete all the tile buffers, if any still happen to exist
+    //
+
+    for (TileMap::iterator i = tileMap.begin(); i != tileMap.end(); ++i)
+        delete i->second;
+
+    for (size_t i = 0; i < tileBuffers.size(); i++)
+        if (tileBuffers[i] != 0)
+            delete tileBuffers[i];
+
+    for (size_t i = 0; i < slices.size(); i++)
+        delete slices[i];
+}
+
+
+int&
+DeepTiledOutputFile::Data::getSampleCount(int x, int y)
+{
+    return sampleCount(sampleCountSliceBase,
+                       sampleCountXStride,
+                       sampleCountYStride,
+                       x, y);
+}
+
+
+TileBuffer*
+DeepTiledOutputFile::Data::getTileBuffer (int number)
+{
+    return tileBuffers[number % tileBuffers.size()];
+}
+
+
+TileCoord
+DeepTiledOutputFile::Data::nextTileCoord (const TileCoord &a)
+{
+    TileCoord b = a;
+
+    if (lineOrder == INCREASING_Y)
+    {
+        b.dx++;
+
+        if (b.dx >= numXTiles[b.lx])
+        {
+            b.dx = 0;
+            b.dy++;
+
+            if (b.dy >= numYTiles[b.ly])
+            {
+                //
+                // the next tile is in the next level
+                //
+
+                b.dy = 0;
+
+                switch (tileDesc.mode)
+                {
+                  case ONE_LEVEL:
+                  case MIPMAP_LEVELS:
+
+                    b.lx++;
+                    b.ly++;
+                    break;
+
+                  case RIPMAP_LEVELS:
+
+                    b.lx++;
+
+                    if (b.lx >= numXLevels)
+                    {
+                        b.lx = 0;
+                        b.ly++;
+
+                        #ifdef DEBUG
+                            assert (b.ly <= numYLevels);
+                        #endif
+                    }
+                    break;
+                  case NUM_LEVELMODES :
+                      throw IEX_NAMESPACE::LogicExc("unknown level mode computing nextTileCoord");
+                }
+            }
+        }
+    }
+    else if (lineOrder == DECREASING_Y)
+    {
+        b.dx++;
+
+        if (b.dx >= numXTiles[b.lx])
+        {
+            b.dx = 0;
+            b.dy--;
+
+            if (b.dy < 0)
+            {
+                //
+                // the next tile is in the next level
+                //
+
+                switch (tileDesc.mode)
+                {
+                  case ONE_LEVEL:
+                  case MIPMAP_LEVELS:
+
+                    b.lx++;
+                    b.ly++;
+                    break;
+
+                  case RIPMAP_LEVELS:
+
+                    b.lx++;
+
+                    if (b.lx >= numXLevels)
+                    {
+                        b.lx = 0;
+                        b.ly++;
+
+                        #ifdef DEBUG
+                            assert (b.ly <= numYLevels);
+                        #endif
+                    }
+                    break;
+                  case NUM_LEVELMODES :
+                      throw IEX_NAMESPACE::LogicExc("unknown level mode computing nextTileCoord");
+                }
+
+                if (b.ly < numYLevels)
+                    b.dy = numYTiles[b.ly] - 1;
+            }
+        }
+    }else if(lineOrder==RANDOM_Y)
+    {                 
+        THROW (IEX_NAMESPACE::ArgExc,
+              "can't compute next tile from randomly ordered image: use getTilesInOrder instead");
+        
+    }
+
+    return b;
+}
+
+
+namespace {
+
+void
+writeTileData (DeepTiledOutputFile::Data *ofd,
+               int dx, int dy,
+               int lx, int ly,
+               const char pixelData[],
+               Int64 pixelDataSize,
+               Int64 unpackedDataSize,
+               const char sampleCountTableData[],
+               Int64 sampleCountTableSize)
+{
+    
+    //
+    // Store a block of pixel data in the output file, and try
+    // to keep track of the current writing position the file,
+    // without calling tellp() (tellp() can be fairly expensive).
+    //
+
+    Int64 currentPosition = ofd->_streamData->currentPosition;
+    ofd->_streamData->currentPosition = 0;
+
+    if (currentPosition == 0)
+        currentPosition = ofd->_streamData->os->tellp();
+
+    ofd->tileOffsets (dx, dy, lx, ly) = currentPosition;
+
+    #ifdef DEBUG
+        assert (ofd->_streamData->os->tellp() == currentPosition);
+    #endif
+
+    //
+    // Write the tile header.
+    //
+
+    if (ofd->multipart)
+    {
+        Xdr::write <StreamIO> (*ofd->_streamData->os, ofd->partNumber);
+    }
+    Xdr::write <StreamIO> (*ofd->_streamData->os, dx);
+    Xdr::write <StreamIO> (*ofd->_streamData->os, dy);
+    Xdr::write <StreamIO> (*ofd->_streamData->os, lx);
+    Xdr::write <StreamIO> (*ofd->_streamData->os, ly);
+
+    //
+    // Write the packed size of the pixel sample count table (64 bits)
+    //
+
+    Xdr::write <StreamIO> (*ofd->_streamData->os, sampleCountTableSize);
+
+    //
+    // Write the packed and unpacked data size (64 bits each)
+    //
+
+    Xdr::write <StreamIO> (*ofd->_streamData->os, pixelDataSize);
+    Xdr::write <StreamIO> (*ofd->_streamData->os, unpackedDataSize);
+
+    //
+    // Write the compressed pixel sample count table.
+    //
+
+    ofd->_streamData->os->write (sampleCountTableData, sampleCountTableSize);
+
+    //
+    // Write the compressed data.
+    //
+
+    ofd->_streamData->os->write (pixelData, pixelDataSize);
+
+    //
+    // Keep current position in the file so that we can avoid
+    // redundant seekg() operations (seekg() can be fairly expensive).
+    //
+
+    ofd->_streamData->currentPosition = currentPosition        +
+                                  4 * Xdr::size<int>()   + // dx, dy, lx, ly,
+                                  3 * Xdr::size<Int64>() + // sampleCountTableSize,
+                                                           // pixelDataSize,
+                                                           // unpackedDataSize
+                                  sampleCountTableSize   +
+                                  pixelDataSize;
+
+    if (ofd->multipart)
+    {
+        ofd->_streamData->currentPosition += Xdr::size<int>();
+    }
+}
+
+
+
+void
+bufferedTileWrite (
+                   DeepTiledOutputFile::Data *ofd,
+                   int dx, int dy,
+                   int lx, int ly,
+                   const char pixelData[],
+                   Int64 pixelDataSize,
+                   Int64 unpackedDataSize,
+                   const char sampleCountTableData[],
+                   Int64 sampleCountTableSize)
+{
+    //
+    // Check if a tile with coordinates (dx,dy,lx,ly) has already been written.
+    //
+
+    if (ofd->tileOffsets (dx, dy, lx, ly))
+    {
+        THROW (IEX_NAMESPACE::ArgExc,
+               "Attempt to write tile "
+               "(" << dx << ", " << dy << ", " << lx << ", " << ly << ") "
+               "more than once.");
+    }
+
+    //
+    // If tiles can be written in random order, then don't buffer anything.
+    //
+
+    if (ofd->lineOrder == RANDOM_Y)
+    {
+        writeTileData (ofd, dx, dy, lx, ly,
+                       pixelData, pixelDataSize, unpackedDataSize,
+                       sampleCountTableData, sampleCountTableSize);
+        return;
+    }
+
+    //
+    // If the tiles cannot be written in random order, then check if a
+    // tile with coordinates (dx,dy,lx,ly) has already been buffered.
+    //
+
+    TileCoord currentTile = TileCoord(dx, dy, lx, ly);
+
+    if (ofd->tileMap.find (currentTile) != ofd->tileMap.end())
+    {
+        THROW (IEX_NAMESPACE::ArgExc,
+               "Attempt to write tile "
+               "(" << dx << ", " << dy << ", " << lx << ", " << ly << ") "
+               "more than once.");
+    }
+
+    //
+    // If all the tiles before this one have already been written to the file,
+    // then write this tile immediately and check if we have buffered tiles
+    // that can be written after this tile.
+    //
+    // Otherwise, buffer the tile so it can be written to file later.
+    //
+
+    if (ofd->nextTileToWrite == currentTile)
+    {
+        writeTileData (ofd, dx, dy, lx, ly,
+                       pixelData, pixelDataSize, unpackedDataSize,
+                       sampleCountTableData, sampleCountTableSize);
+        ofd->nextTileToWrite = ofd->nextTileCoord (ofd->nextTileToWrite);
+
+        TileMap::iterator i = ofd->tileMap.find (ofd->nextTileToWrite);
+
+        //
+        // Step through the tiles and write all successive buffered tiles after
+        // the current one.
+        //
+
+        while(i != ofd->tileMap.end())
+        {
+            //
+            // Write the tile, and then delete the tile's buffered data
+            //
+
+            writeTileData (ofd,
+                           i->first.dx, i->first.dy,
+                           i->first.lx, i->first.ly,
+                           i->second->pixelData,
+                           i->second->pixelDataSize,
+                           i->second->unpackedDataSize,
+                           i->second->sampleCountTableData,
+                           i->second->sampleCountTableSize);
+
+            delete i->second;
+            ofd->tileMap.erase (i);
+
+            //
+            // Proceed to the next tile
+            //
+
+            ofd->nextTileToWrite = ofd->nextTileCoord (ofd->nextTileToWrite);
+            i = ofd->tileMap.find (ofd->nextTileToWrite);
+        }
+    }
+    else
+    {
+        //
+        // Create a new BufferedTile, copy the pixelData into it, and
+        // insert it into the tileMap.
+        //
+
+        ofd->tileMap[currentTile] =
+            new BufferedTile ((const char *)pixelData, pixelDataSize, unpackedDataSize,
+                              sampleCountTableData, sampleCountTableSize);
+    }
+}
+
+
+void
+convertToXdr (DeepTiledOutputFile::Data *ofd,
+              Array<char>& tileBuffer,
+              int numScanLines,
+              vector<Int64>& bytesPerLine)
+{
+    //
+    // Convert the contents of a TiledOutputFile's tileBuffer from the
+    // machine's native representation to Xdr format. This function is called
+    // by writeTile(), below, if the compressor wanted its input pixel data
+    // in the machine's native format, but then failed to compress the data
+    // (most compressors will expand rather than compress random input data).
+    //
+    // Note that this routine assumes that the machine's native representation
+    // of the pixel data has the same size as the Xdr representation.  This
+    // makes it possible to convert the pixel data in place, without an
+    // intermediate temporary buffer.
+    //
+
+    //
+    // Set these to point to the start of the tile.
+    // We will write to toPtr, and read from fromPtr.
+    //
+
+    char *writePtr = tileBuffer;
+    const char *readPtr = writePtr;
+
+    //
+    // Iterate over all scan lines in the tile.
+    //
+
+    for (int y = 0; y < numScanLines; ++y)
+    {
+        //
+        // Iterate over all slices in the file.
+        //
+
+        for (unsigned int i = 0; i < ofd->slices.size(); ++i)
+        {
+            const TOutSliceInfo &slice = *ofd->slices[i];
+
+            //
+            // Convert the samples in place.
+            //
+
+            Int64 numPixelsPerScanLine = bytesPerLine[y];
+
+            convertInPlace (writePtr, readPtr, slice.type,
+                            numPixelsPerScanLine);
+        }
+    }
+
+    #ifdef DEBUG
+
+        assert (writePtr == readPtr);
+
+    #endif
+}
+
+
+//
+// A TileBufferTask encapsulates the task of copying a tile from
+// the user's framebuffer into a LineBuffer and compressing the data
+// if necessary.
+//
+
+class TileBufferTask: public Task
+{
+  public:
+
+    TileBufferTask (TaskGroup *group,
+                    DeepTiledOutputFile::Data *ofd,
+                    int number,
+                    int dx, int dy,
+                    int lx, int ly);
+
+    virtual ~TileBufferTask ();
+
+    virtual void                execute ();
+
+  private:
+
+    DeepTiledOutputFile::Data *     _ofd;
+    TileBuffer *                _tileBuffer;
+};
+
+
+TileBufferTask::TileBufferTask
+    (TaskGroup *group,
+     DeepTiledOutputFile::Data *ofd,
+     int number,
+     int dx, int dy,
+     int lx, int ly)
+:
+    Task (group),
+    _ofd (ofd),
+    _tileBuffer (_ofd->getTileBuffer (number))
+{
+    //
+    // Wait for the tileBuffer to become available
+    //
+
+    _tileBuffer->wait ();
+    _tileBuffer->tileCoord = TileCoord (dx, dy, lx, ly);
+}
+
+
+TileBufferTask::~TileBufferTask ()
+{
+    //
+    // Signal that the tile buffer is now free
+    //
+
+    _tileBuffer->post ();
+}
+
+
+void
+TileBufferTask::execute ()
+{
+    try
+    {
+        //
+        // First copy the pixel data from the frame buffer
+        // into the tile buffer
+        //
+        // Convert one tile's worth of pixel data to
+        // a machine-independent representation, and store
+        // the result in _tileBuffer->buffer.
+        //
+
+        Box2i tileRange = OPENEXR_IMF_INTERNAL_NAMESPACE::dataWindowForTile (
+                _ofd->tileDesc,
+                _ofd->minX, _ofd->maxX,
+                _ofd->minY, _ofd->maxY,
+                _tileBuffer->tileCoord.dx,
+                _tileBuffer->tileCoord.dy,
+                _tileBuffer->tileCoord.lx,
+                _tileBuffer->tileCoord.ly);
+
+        int numScanLines = tileRange.max.y - tileRange.min.y + 1;
+//        int numPixelsPerScanLine = tileRange.max.x - tileRange.min.x + 1;
+
+        //
+        // Get the bytes for each line.
+        //
+
+        vector<Int64> bytesPerLine(_ofd->tileDesc.ySize);
+        vector<int> xOffsets(_ofd->slices.size());
+        vector<int> yOffsets(_ofd->slices.size());
+        for (size_t i = 0; i < _ofd->slices.size(); i++)
+        {
+            const TOutSliceInfo &slice = *_ofd->slices[i];
+            xOffsets[i] = slice.xTileCoords * tileRange.min.x;
+            yOffsets[i] = slice.yTileCoords * tileRange.min.y;
+        }
+
+        calculateBytesPerLine(_ofd->header,
+                              _ofd->sampleCountSliceBase,
+                              _ofd->sampleCountXStride,
+                              _ofd->sampleCountYStride,
+                              tileRange.min.x, tileRange.max.x,
+                              tileRange.min.y, tileRange.max.y,
+                              xOffsets, yOffsets,
+                              bytesPerLine);
+
+        //
+        // Allocate the memory for internal buffer.
+        // (TODO) more efficient memory management?
+        //
+
+        Int64 totalBytes = 0;
+        Int64 maxBytesPerTileLine = 0;
+        for (size_t i = 0; i < bytesPerLine.size(); i++)
+        {
+            totalBytes += bytesPerLine[i];
+            if (bytesPerLine[i] > maxBytesPerTileLine)
+                maxBytesPerTileLine = bytesPerLine[i];
+        }
+        _tileBuffer->buffer.resizeErase(totalBytes);
+
+        char *writePtr = _tileBuffer->buffer;
+
+        //
+        // Iterate over the scan lines in the tile.
+        //
+
+        int xOffsetForSampleCount =
+                (_ofd->sampleCountXTileCoords == 0) ? 0 : tileRange.min.x;
+        int yOffsetForSampleCount =
+                (_ofd->sampleCountYTileCoords == 0) ? 0 : tileRange.min.y;
+
+        for (int y = tileRange.min.y; y <= tileRange.max.y; ++y)
+        {
+            //
+            // Iterate over all image channels.
+            //
+
+            for (unsigned int i = 0; i < _ofd->slices.size(); ++i)
+            {
+                const TOutSliceInfo &slice = *_ofd->slices[i];
+
+
+                //
+                // Fill the tile buffer with pixel data.
+                //
+
+                if (slice.zero)
+                {
+                    //
+                    // The frame buffer contains no data for this channel.
+                    // Store zeroes in _data->tileBuffer.
+                    //
+
+                    fillChannelWithZeroes (writePtr, _ofd->format, slice.type,
+                                           bytesPerLine[y - tileRange.min.y]);
+                }
+                else
+                {
+                    //
+                    // The frame buffer contains data for this channel.
+                    //
+
+                
+                    int xOffsetForData = slice.xTileCoords ? tileRange.min.x : 0;
+                    int yOffsetForData = slice.yTileCoords ? tileRange.min.y : 0;
+
+                    // (TOOD) treat sample count offsets differently.
+                    copyFromDeepFrameBuffer (writePtr,
+                                             slice.base,
+                                             _ofd->sampleCountSliceBase,
+                                             _ofd->sampleCountXStride,
+                                             _ofd->sampleCountYStride,
+                                             y,
+                                             tileRange.min.x,
+                                             tileRange.max.x,
+                                             xOffsetForSampleCount,
+                                             yOffsetForSampleCount,
+                                             xOffsetForData,
+                                             yOffsetForData,
+                                             slice.sampleStride,
+                                             slice.xStride,
+                                             slice.yStride,
+                                             _ofd->format,
+                                             slice.type);
+#if defined(DEBUG)
+                      assert(writePtr-_tileBuffer->buffer<=totalBytes);
+#endif
+                }
+            }
+        }
+
+        //
+        // Compress the pixel sample count table.
+        //
+
+        char* ptr = _tileBuffer->sampleCountTableBuffer;
+        Int64 tableDataSize = 0;
+        for (int i = tileRange.min.y; i <= tileRange.max.y; i++)
+        {
+            int count = 0;
+            for (int j = tileRange.min.x; j <= tileRange.max.x; j++)
+            {
+                count += _ofd->getSampleCount(j - xOffsetForSampleCount,
+                                              i - yOffsetForSampleCount);
+                Xdr::write <CharPtrIO> (ptr, count);
+                tableDataSize += sizeof (int);
+            }
+        }
+
+       if(_tileBuffer->sampleCountTableCompressor)
+       {
+           _tileBuffer->sampleCountTableSize =
+                _tileBuffer->sampleCountTableCompressor->compress (
+                                                    _tileBuffer->sampleCountTableBuffer,
+                                                    tableDataSize,
+                                                    tileRange.min.y,
+                                                    _tileBuffer->sampleCountTablePtr);
+       }
+       
+        //
+        // If we can't make data shrink (or compression was disabled), then just use the raw data.
+        //
+
+        if ( ! _tileBuffer->sampleCountTableCompressor ||
+            _tileBuffer->sampleCountTableSize >= _ofd->maxSampleCountTableSize)
+        {
+            _tileBuffer->sampleCountTableSize = _ofd->maxSampleCountTableSize;
+            _tileBuffer->sampleCountTablePtr = _tileBuffer->sampleCountTableBuffer;
+        }
+
+        //
+        // Compress the contents of the tileBuffer,
+        // and store the compressed data in the output file.
+        //
+
+        _tileBuffer->dataSize = writePtr - _tileBuffer->buffer;
+        _tileBuffer->uncompressedSize = _tileBuffer->dataSize;
+        _tileBuffer->dataPtr = _tileBuffer->buffer;
+
+        // (TODO) don't do this all the time.
+        if (_tileBuffer->compressor != 0)
+            delete _tileBuffer->compressor;
+        _tileBuffer->compressor = newTileCompressor
+                                    (_ofd->header.compression(),
+                                     maxBytesPerTileLine,
+                                     _ofd->tileDesc.ySize,
+                                     _ofd->header);
+
+        if (_tileBuffer->compressor)
+        {
+            const char *compPtr;
+
+            Int64 compSize = _tileBuffer->compressor->compressTile
+                                                (_tileBuffer->dataPtr,
+                                                 _tileBuffer->dataSize,
+                                                 tileRange, compPtr);
+
+            if (compSize < _tileBuffer->dataSize)
+            {
+                _tileBuffer->dataSize = compSize;
+                _tileBuffer->dataPtr = compPtr;
+            }
+            else if (_ofd->format == Compressor::NATIVE)
+            {
+                //
+                // The data did not shrink during compression, but
+                // we cannot write to the file using native format,
+                // so we need to convert the lineBuffer to Xdr.
+                //
+
+                convertToXdr (_ofd, _tileBuffer->buffer, numScanLines,
+                              bytesPerLine);
+            }
+        }
+    }
+    catch (std::exception &e)
+    {
+        if (!_tileBuffer->hasException)
+        {
+            _tileBuffer->exception = e.what ();
+            _tileBuffer->hasException = true;
+        }
+    }
+    catch (...)
+    {
+        if (!_tileBuffer->hasException)
+        {
+            _tileBuffer->exception = "unrecognized exception";
+            _tileBuffer->hasException = true;
+        }
+    }
+}
+
+} // namespace
+
+
+DeepTiledOutputFile::DeepTiledOutputFile
+    (const char fileName[],
+     const Header &header,
+     int numThreads)
+:
+    _data (new Data (numThreads))
+
+{
+    _data->_streamData=new OutputStreamMutex();
+    _data->_deleteStream =true;
+    try
+    {
+        header.sanityCheck (true);
+        _data->_streamData->os = new StdOFStream (fileName);
+        initialize (header);
+        _data->_streamData->currentPosition = _data->_streamData->os->tellp();
+
+        // Write header and empty offset table to the file.
+        writeMagicNumberAndVersionField(*_data->_streamData->os, _data->header);
+        _data->previewPosition = _data->header.writeTo (*_data->_streamData->os, true);
+        _data->tileOffsetsPosition = _data->tileOffsets.writeTo (*_data->_streamData->os);
+	_data->multipart = false;
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        if (_data && _data->_streamData && _data->_streamData->os) delete _data->_streamData->os;
+        if (_data && _data->_streamData)     delete _data->_streamData;
+        if (_data)           delete _data;
+
+        REPLACE_EXC (e, "Cannot open image file "
+                        "\"" << fileName << "\". " << e);
+        throw;
+    }
+    catch (...)
+    {
+        if (_data && _data->_streamData && _data->_streamData->os) delete _data->_streamData->os;
+        if (_data->_streamData)     delete _data->_streamData;
+        if (_data)           delete _data;
+
+        throw;
+    }
+}
+
+
+DeepTiledOutputFile::DeepTiledOutputFile
+    (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
+     const Header &header,
+     int numThreads)
+:
+    _data (new Data (numThreads))
+{
+    _data->_streamData=new OutputStreamMutex();
+    _data->_deleteStream=false;
+    
+    try
+    {
+        header.sanityCheck(true);
+        _data->_streamData->os = &os;
+        initialize (header);
+        _data->_streamData->currentPosition = _data->_streamData->os->tellp();
+
+        // Write header and empty offset table to the file.
+        writeMagicNumberAndVersionField(*_data->_streamData->os, _data->header);
+        _data->previewPosition = _data->header.writeTo (*_data->_streamData->os, true);
+        _data->tileOffsetsPosition = _data->tileOffsets.writeTo (*_data->_streamData->os);
+	_data->multipart = false;
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        if (_data && _data->_streamData) delete _data->_streamData;
+        if (_data)       delete _data;
+
+        REPLACE_EXC (e, "Cannot open image file "
+                        "\"" << os.fileName() << "\". " << e);
+        throw;
+    }
+    catch (...)
+    {
+        if (_data && _data->_streamData) delete _data->_streamData;
+        if (_data)       delete _data;
+
+        throw;
+    }
+}
+
+DeepTiledOutputFile::DeepTiledOutputFile(const OutputPartData* part) 
+{
+   
+    try
+    {
+        if (part->header.type() != DEEPTILE)
+            throw IEX_NAMESPACE::ArgExc("Can't build a DeepTiledOutputFile from "
+                              "a type-mismatched part.");
+
+        _data = new Data (part->numThreads);
+        _data->_streamData=part->mutex;
+        _data->_deleteStream=false;
+        initialize(part->header);
+        _data->partNumber = part->partNumber;
+        _data->tileOffsetsPosition = part->chunkOffsetTablePosition;
+        _data->previewPosition = part->previewPosition;
+	_data->multipart = part->multipart;
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        if (_data) delete _data;
+
+        REPLACE_EXC (e, "Cannot initialize output part "
+                        "\"" << part->partNumber << "\". " << e);
+        throw;
+    }
+    catch (...)
+    {
+        if (_data) delete _data;
+
+        throw;
+    }
+}
+
+void
+DeepTiledOutputFile::initialize (const Header &header)
+{
+    _data->header = header;
+    _data->header.setType(DEEPTILE);
+    _data->lineOrder = _data->header.lineOrder();
+
+    //
+    // Check that the file is indeed tiled
+    //
+
+    _data->tileDesc = _data->header.tileDescription();
+
+    //
+    // Save the dataWindow information
+    //
+
+    const Box2i &dataWindow = _data->header.dataWindow();
+    _data->minX = dataWindow.min.x;
+    _data->maxX = dataWindow.max.x;
+    _data->minY = dataWindow.min.y;
+    _data->maxY = dataWindow.max.y;
+
+    //
+    // Precompute level and tile information to speed up utility functions
+    //
+
+    precalculateTileInfo (_data->tileDesc,
+                          _data->minX, _data->maxX,
+                          _data->minY, _data->maxY,
+                          _data->numXTiles, _data->numYTiles,
+                          _data->numXLevels, _data->numYLevels);
+
+    //
+    // Determine the first tile coordinate that we will be writing
+    // if the file is not RANDOM_Y.
+    //
+
+    _data->nextTileToWrite = (_data->lineOrder == INCREASING_Y)?
+                               TileCoord (0, 0, 0, 0):
+                               TileCoord (0, _data->numYTiles[0] - 1, 0, 0);
+
+    Compressor* compressor = newTileCompressor
+                                (_data->header.compression(),
+                                 0,
+                                 _data->tileDesc.ySize,
+                                 _data->header);
+
+    _data->format = defaultFormat (compressor);
+
+    if (compressor != 0)
+        delete compressor;
+
+    _data->tileOffsets = TileOffsets (_data->tileDesc.mode,
+                                      _data->numXLevels,
+                                      _data->numYLevels,
+                                      _data->numXTiles,
+                                      _data->numYTiles);
+                                      
+    //ignore the existing value of chunkCount - correct it if it's wrong
+    _data->header.setChunkCount(getChunkOffsetTableSize(_data->header,true));                                   
+                                      
+    _data->maxSampleCountTableSize = _data->tileDesc.ySize *
+                                     _data->tileDesc.xSize *
+                                     sizeof(int);
+
+                                     
+    for (size_t i = 0; i < _data->tileBuffers.size(); i++)
+    {
+        _data->tileBuffers[i] = new TileBuffer ();
+
+        _data->tileBuffers[i]->sampleCountTableBuffer.
+                resizeErase(_data->maxSampleCountTableSize);
+
+        char * p = &(_data->tileBuffers[i]->sampleCountTableBuffer[0]);
+        memset (p, 0, _data->maxSampleCountTableSize);
+
+        _data->tileBuffers[i]->sampleCountTableCompressor =
+                newCompressor (_data->header.compression(),
+                               _data->maxSampleCountTableSize,
+                               _data->header);
+    }
+}
+
+
+DeepTiledOutputFile::~DeepTiledOutputFile ()
+{
+    if (_data)
+    {
+        {
+            Lock lock(*_data->_streamData);
+            Int64 originalPosition = _data->_streamData->os->tellp();
+
+            if (_data->tileOffsetsPosition > 0)
+            {
+                try
+                {
+                    _data->_streamData->os->seekp (_data->tileOffsetsPosition);
+                    _data->tileOffsets.writeTo (*_data->_streamData->os);
+
+                    //
+                    // Restore the original position.
+                    //
+                    _data->_streamData->os->seekp (originalPosition);
+                }
+                catch (...)
+                {
+                    //
+                    // We cannot safely throw any exceptions from here.
+                    // This destructor may have been called because the
+                    // stack is currently being unwound for another
+                    // exception.
+                    //
+                }
+            }
+        }
+
+        if (_data->_deleteStream && _data->_streamData)
+            delete _data->_streamData->os;
+
+        //
+        // (TODO) we should have a way to tell if the stream data is owned by
+        // this file or by a parent multipart file.
+        //
+
+        if (_data->partNumber == -1 && _data->_streamData)
+            delete _data->_streamData;
+
+        delete _data;
+    }
+}
+
+
+const char *
+DeepTiledOutputFile::fileName () const
+{
+    return _data->_streamData->os->fileName();
+}
+
+
+const Header &
+DeepTiledOutputFile::header () const
+{
+    return _data->header;
+}
+
+
+void
+DeepTiledOutputFile::setFrameBuffer (const DeepFrameBuffer &frameBuffer)
+{
+    Lock lock (*_data->_streamData);
+
+    //
+    // Check if the new frame buffer descriptor
+    // is compatible with the image file header.
+    //
+
+    const ChannelList &channels = _data->header.channels();
+
+    for (ChannelList::ConstIterator i = channels.begin();
+         i != channels.end();
+         ++i)
+    {
+        DeepFrameBuffer::ConstIterator j = frameBuffer.find (i.name());
+
+        if (j == frameBuffer.end())
+            continue;
+
+        if (i.channel().type != j.slice().type)
+            THROW (IEX_NAMESPACE::ArgExc, "Pixel type of \"" << i.name() << "\" channel "
+                                "of output file \"" << fileName() << "\" is "
+                                "not compatible with the frame buffer's "
+                                "pixel type.");
+
+        if (j.slice().xSampling != 1 || j.slice().ySampling != 1)
+            THROW (IEX_NAMESPACE::ArgExc, "All channels in a tiled file must have"
+                                "sampling (1,1).");
+    }
+
+    //
+    // Store the pixel sample count table.
+    //
+
+    const Slice& sampleCountSlice = frameBuffer.getSampleCountSlice();
+    if (sampleCountSlice.base == 0)
+    {
+        throw IEX_NAMESPACE::ArgExc ("Invalid base pointer, please set a proper sample count slice.");
+    }
+    else
+    {
+        _data->sampleCountSliceBase = sampleCountSlice.base;
+        _data->sampleCountXStride = sampleCountSlice.xStride;
+        _data->sampleCountYStride = sampleCountSlice.yStride;
+        _data->sampleCountXTileCoords = sampleCountSlice.xTileCoords;
+        _data->sampleCountYTileCoords = sampleCountSlice.yTileCoords;
+    }
+
+    //
+    // Initialize slice table for writePixels().
+    // Pixel sample count slice is not presented in the header,
+    // so it wouldn't be added here.
+    // Store the pixel base pointer table.
+    //
+
+    vector<TOutSliceInfo*> slices;
+
+    for (ChannelList::ConstIterator i = channels.begin();
+         i != channels.end();
+         ++i)
+    {
+        DeepFrameBuffer::ConstIterator j = frameBuffer.find (i.name());
+
+        if (j == frameBuffer.end())
+        {
+            //
+            // Channel i is not present in the frame buffer.
+            // In the file, channel i will contain only zeroes.
+            //
+
+            slices.push_back (new TOutSliceInfo (i.channel().type,
+                                                 0, // sampleStride,
+                                                 0, // xStride
+                                                 0, // yStride
+                                                 true)); // zero
+        }
+        else
+        {
+            //
+            // Channel i is present in the frame buffer.
+            //
+
+            slices.push_back (new TOutSliceInfo (j.slice().type,
+                                                 j.slice().sampleStride,
+                                                 j.slice().xStride,
+                                                 j.slice().yStride,
+                                                 false, // zero
+                                                 (j.slice().xTileCoords)? 1: 0,
+                                                 (j.slice().yTileCoords)? 1: 0));
+
+            TOutSliceInfo* slice = slices.back();
+            slice->base = j.slice().base;
+            
+        }
+    }
+
+    //
+    // Store the new frame buffer.
+    //
+
+    _data->frameBuffer = frameBuffer;
+
+    for (size_t i = 0; i < _data->slices.size(); i++)
+        delete _data->slices[i];
+    _data->slices = slices;
+}
+
+
+const DeepFrameBuffer &
+DeepTiledOutputFile::frameBuffer () const
+{
+    Lock lock (*_data->_streamData);
+    return _data->frameBuffer;
+}
+
+
+void
+DeepTiledOutputFile::writeTiles (int dx1, int dx2, int dy1, int dy2,
+                             int lx, int ly)
+{
+    try
+    {
+        Lock lock (*_data->_streamData);
+
+        if (_data->slices.size() == 0)
+            throw IEX_NAMESPACE::ArgExc ("No frame buffer specified "
+                               "as pixel data source.");
+
+        if (!isValidTile (dx1, dy1, lx, ly) || !isValidTile (dx2, dy2, lx, ly))
+            throw IEX_NAMESPACE::ArgExc ("Tile coordinates are invalid.");
+
+        if (!isValidLevel (lx, ly))
+            THROW (IEX_NAMESPACE::ArgExc,
+                   "Level coordinate "
+                   "(" << lx << ", " << ly << ") "
+                   "is invalid.");
+        //
+        // Determine the first and last tile coordinates in both dimensions
+        // based on the file's lineOrder
+        //
+
+        if (dx1 > dx2)
+            swap (dx1, dx2);
+
+        if (dy1 > dy2)
+            swap (dy1, dy2);
+
+        int dyStart = dy1;
+        int dyStop  = dy2 + 1;
+        int dY      = 1;
+
+        if (_data->lineOrder == DECREASING_Y)
+        {
+            dyStart = dy2;
+            dyStop  = dy1 - 1;
+            dY      = -1;
+        }
+
+        int numTiles = (dx2 - dx1 + 1) * (dy2 - dy1 + 1);
+        int numTasks = min ((int)_data->tileBuffers.size(), numTiles);
+
+        //
+        // Create a task group for all tile buffer tasks.  When the
+        // task group goes out of scope, the destructor waits until
+        // all tasks are complete.
+        //
+
+        {
+            TaskGroup taskGroup;
+
+            //
+            // Add in the initial compression tasks to the thread pool
+            //
+
+            int nextCompBuffer = 0;
+            int dxComp         = dx1;
+            int dyComp         = dyStart;
+
+            while (nextCompBuffer < numTasks)
+            {
+                ThreadPool::addGlobalTask (new TileBufferTask (&taskGroup,
+                                                               _data,
+                                                               nextCompBuffer++,
+                                                               dxComp, dyComp,
+                                                               lx, ly));
+                dxComp++;
+
+                if (dxComp > dx2)
+                {
+                    dxComp = dx1;
+                    dyComp += dY;
+                }
+            }
+
+            //
+            // Write the compressed buffers and add in more compression
+            // tasks until done
+            //
+
+            int nextWriteBuffer = 0;
+            int dxWrite         = dx1;
+            int dyWrite         = dyStart;
+
+            while (nextWriteBuffer < numTiles)
+            {
+                //
+                // Wait until the nextWriteBuffer is ready to be written
+                //
+
+                TileBuffer* writeBuffer =
+                                    _data->getTileBuffer (nextWriteBuffer);
+
+                writeBuffer->wait();
+
+                //
+                // Write the tilebuffer
+                //
+
+                bufferedTileWrite ( _data, dxWrite, dyWrite, lx, ly,
+                                   writeBuffer->dataPtr,
+                                   writeBuffer->dataSize,
+                                   writeBuffer->uncompressedSize,
+                                   writeBuffer->sampleCountTablePtr,
+                                   writeBuffer->sampleCountTableSize);
+
+                //
+                // Release the lock on nextWriteBuffer
+                //
+
+                writeBuffer->post();
+
+                //
+                // If there are no more tileBuffers to compress, then
+                // only continue to write out remaining tileBuffers,
+                // otherwise keep adding compression tasks.
+                //
+
+                if (nextCompBuffer < numTiles)
+                {
+                    //
+                    // add nextCompBuffer as a compression Task
+                    //
+
+                    ThreadPool::addGlobalTask
+                        (new TileBufferTask (&taskGroup,
+                                             _data,
+                                             nextCompBuffer,
+                                             dxComp, dyComp,
+                                             lx, ly));
+                }
+
+                nextWriteBuffer++;
+                dxWrite++;
+
+                if (dxWrite > dx2)
+                {
+                    dxWrite = dx1;
+                    dyWrite += dY;
+                }
+
+                nextCompBuffer++;
+                dxComp++;
+
+                if (dxComp > dx2)
+                {
+                    dxComp = dx1;
+                    dyComp += dY;
+                }
+            }
+
+            //
+            // finish all tasks
+            //
+        }
+
+        //
+        // Exeption handling:
+        //
+        // TileBufferTask::execute() may have encountered exceptions, but
+        // those exceptions occurred in another thread, not in the thread
+        // that is executing this call to TiledOutputFile::writeTiles().
+        // TileBufferTask::execute() has caught all exceptions and stored
+        // the exceptions' what() strings in the tile buffers.
+        // Now we check if any tile buffer contains a stored exception; if
+        // this is the case then we re-throw the exception in this thread.
+        // (It is possible that multiple tile buffers contain stored
+        // exceptions.  We re-throw the first exception we find and
+        // ignore all others.)
+        //
+
+        const string *exception = 0;
+
+        for (size_t i = 0; i < _data->tileBuffers.size(); ++i)
+        {
+            TileBuffer *tileBuffer = _data->tileBuffers[i];
+
+            if (tileBuffer->hasException && !exception)
+                exception = &tileBuffer->exception;
+
+            tileBuffer->hasException = false;
+        }
+
+        if (exception)
+            throw IEX_NAMESPACE::IoExc (*exception);
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        REPLACE_EXC (e, "Failed to write pixel data to image "
+                        "file \"" << fileName() << "\". " << e);
+        throw;
+    }
+}
+
+
+void
+DeepTiledOutputFile::writeTiles (int dx1, int dxMax, int dyMin, int dyMax, int l)
+{
+    writeTiles (dx1, dxMax, dyMin, dyMax, l, l);
+}
+
+
+void
+DeepTiledOutputFile::writeTile (int dx, int dy, int lx, int ly)
+{
+    writeTiles (dx, dx, dy, dy, lx, ly);
+}
+
+
+void
+DeepTiledOutputFile::writeTile (int dx, int dy, int l)
+{
+    writeTile(dx, dy, l, l);
+}
+
+
+void
+DeepTiledOutputFile::copyPixels (DeepTiledInputFile &in)
+{
+
+   //
+   // Check if this file's and and the InputFile's
+   // headers are compatible.
+   //
+
+   const Header &hdr = _data->header;
+   const Header &inHdr = in.header();
+
+   
+   
+   if (!(hdr.tileDescription() == inHdr.tileDescription()))
+        THROW (IEX_NAMESPACE::ArgExc, "Quick pixel copy from image "
+                            "file \"" << in.fileName() << "\" to image "
+                            "file \"" << fileName() << "\" failed. "
+                            "The files have different tile descriptions.");
+
+   if (!(hdr.dataWindow() == inHdr.dataWindow()))
+        THROW (IEX_NAMESPACE::ArgExc, "Cannot copy pixels from image "
+                            "file \"" << in.fileName() << "\" to image "
+                            "file \"" << fileName() << "\". The "
+                            "files have different data windows.");
+
+    if (!(hdr.lineOrder() == inHdr.lineOrder()))
+        THROW (IEX_NAMESPACE::ArgExc, "Quick pixel copy from image "
+                            "file \"" << in.fileName() << "\" to image "
+                            "file \"" << fileName() << "\" failed. "
+                            "The files have different line orders.");
+
+    if (!(hdr.compression() == inHdr.compression()))
+        THROW (IEX_NAMESPACE::ArgExc, "Quick pixel copy from image "
+                            "file \"" << in.fileName() << "\" to image "
+                            "file \"" << fileName() << "\" failed. "
+                            "The files use different compression methods.");
+
+    if (!(hdr.channels() == inHdr.channels()))
+        THROW (IEX_NAMESPACE::ArgExc, "Quick pixel copy from image "
+                             "file \"" << in.fileName() << "\" to image "
+                             "file \"" << fileName() << "\" "
+                             "failed.  The files have different channel "
+                             "lists.");
+
+
+    // Verify that no pixel data have been written to this file yet.
+    //
+
+    if (!_data->tileOffsets.isEmpty())
+        THROW (IEX_NAMESPACE::LogicExc, "Quick pixel copy from image "
+                              "file \"" << in.fileName() << "\" to image "
+                              "file \"" << _data->_streamData->os->fileName() << "\" "
+                              "failed. \"" << fileName() << "\" "
+                              "already contains pixel data.");
+
+ 
+    int numAllTiles = in.totalTiles();                              
+                              
+    Lock lock (*_data->_streamData);
+    
+    //
+    // special handling for random tiles
+    //
+    
+    vector<int> dx_list(_data->lineOrder==RANDOM_Y ? numAllTiles : 1);
+    vector<int> dy_list(_data->lineOrder==RANDOM_Y ? numAllTiles : 1);
+    vector<int> lx_list(_data->lineOrder==RANDOM_Y ? numAllTiles : 1);
+    vector<int> ly_list(_data->lineOrder==RANDOM_Y ? numAllTiles : 1);
+    
+    if(_data->lineOrder==RANDOM_Y)
+    {
+        in.getTileOrder(&dx_list[0],&dy_list[0],&lx_list[0],&ly_list[0]);
+        _data->nextTileToWrite.dx=dx_list[0];
+        _data->nextTileToWrite.dy=dy_list[0];
+        _data->nextTileToWrite.lx=lx_list[0];
+        _data->nextTileToWrite.ly=ly_list[0];
+    }
+    
+
+    vector<char> data(4096);
+    for (int i = 0; i < numAllTiles; ++i)
+    {
+
+        int dx = _data->nextTileToWrite.dx;
+        int dy = _data->nextTileToWrite.dy;
+        int lx = _data->nextTileToWrite.lx;
+        int ly = _data->nextTileToWrite.ly;
+
+        Int64 dataSize = data.size();
+
+        in.rawTileData (dx, dy, lx, ly, &data[0], dataSize);
+        if(dataSize>data.size())
+        {
+            data.resize(dataSize);
+            in.rawTileData (dx, dy, lx, ly, &data[0], dataSize);
+        }
+        Int64 sampleCountTableSize = *(Int64 *)(&data[0] + 16);
+        Int64 pixelDataSize = *(Int64 *)(&data[0] + 24);
+        Int64 unpackedPixelDataSize = *(Int64 *)(&data[0] + 32);
+        char * sampleCountTable = &data[0]+40;
+        char * pixelData = sampleCountTable + sampleCountTableSize;
+        
+        writeTileData (_data, dx, dy, lx, ly, pixelData, pixelDataSize,unpackedPixelDataSize,sampleCountTable,sampleCountTableSize);
+        
+        
+        if(_data->lineOrder==RANDOM_Y)
+        {
+            if(i<numAllTiles-1)
+            {
+              _data->nextTileToWrite.dx=dx_list[i+1];
+              _data->nextTileToWrite.dy=dy_list[i+1];
+              _data->nextTileToWrite.lx=lx_list[i+1];
+              _data->nextTileToWrite.ly=ly_list[i+1];
+            }
+        }else{   
+          _data->nextTileToWrite = _data->nextTileCoord (_data->nextTileToWrite);
+        }
+        
+    }
+}
+
+
+void
+DeepTiledOutputFile::copyPixels (DeepTiledInputPart &in)
+{
+  copyPixels(*in.file);
+}
+
+
+unsigned int
+DeepTiledOutputFile::tileXSize () const
+{
+    return _data->tileDesc.xSize;
+}
+
+
+unsigned int
+DeepTiledOutputFile::tileYSize () const
+{
+    return _data->tileDesc.ySize;
+}
+
+
+LevelMode
+DeepTiledOutputFile::levelMode () const
+{
+    return _data->tileDesc.mode;
+}
+
+
+LevelRoundingMode
+DeepTiledOutputFile::levelRoundingMode () const
+{
+    return _data->tileDesc.roundingMode;
+}
+
+
+int
+DeepTiledOutputFile::numLevels () const
+{
+    if (levelMode() == RIPMAP_LEVELS)
+        THROW (IEX_NAMESPACE::LogicExc, "Error calling numLevels() on image "
+                              "file \"" << fileName() << "\" "
+                              "(numLevels() is not defined for RIPMAPs).");
+    return _data->numXLevels;
+}
+
+
+int
+DeepTiledOutputFile::numXLevels () const
+{
+    return _data->numXLevels;
+}
+
+
+int
+DeepTiledOutputFile::numYLevels () const
+{
+    return _data->numYLevels;
+}
+
+
+bool
+DeepTiledOutputFile::isValidLevel (int lx, int ly) const
+{
+    if (lx < 0 || ly < 0)
+        return false;
+
+    if (levelMode() == MIPMAP_LEVELS && lx != ly)
+        return false;
+
+    if (lx >= numXLevels() || ly >= numYLevels())
+        return false;
+
+    return true;
+}
+
+
+int
+DeepTiledOutputFile::levelWidth (int lx) const
+{
+    try
+    {
+        int retVal = levelSize (_data->minX, _data->maxX, lx,
+                                _data->tileDesc.roundingMode);
+
+        return retVal;
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        REPLACE_EXC (e, "Error calling levelWidth() on image "
+                        "file \"" << fileName() << "\". " << e);
+        throw;
+    }
+}
+
+
+int
+DeepTiledOutputFile::levelHeight (int ly) const
+{
+    try
+    {
+        return levelSize (_data->minY, _data->maxY, ly,
+                          _data->tileDesc.roundingMode);
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        REPLACE_EXC (e, "Error calling levelHeight() on image "
+                        "file \"" << fileName() << "\". " << e);
+        throw;
+    }
+}
+
+
+int
+DeepTiledOutputFile::numXTiles (int lx) const
+{
+    if (lx < 0 || lx >= _data->numXLevels)
+        THROW (IEX_NAMESPACE::LogicExc, "Error calling numXTiles() on image "
+                              "file \"" << _data->_streamData->os->fileName() << "\" "
+                              "(Argument is not in valid range).");
+
+    return _data->numXTiles[lx];
+}
+
+
+int
+DeepTiledOutputFile::numYTiles (int ly) const
+{
+   if (ly < 0 || ly >= _data->numYLevels)
+        THROW (IEX_NAMESPACE::LogicExc, "Error calling numXTiles() on image "
+                              "file \"" << _data->_streamData->os->fileName() << "\" "
+                              "(Argument is not in valid range).");
+
+    return _data->numYTiles[ly];
+}
+
+
+Box2i
+DeepTiledOutputFile::dataWindowForLevel (int l) const
+{
+    return dataWindowForLevel (l, l);
+}
+
+
+Box2i
+DeepTiledOutputFile::dataWindowForLevel (int lx, int ly) const
+{
+    try
+    {
+        return OPENEXR_IMF_INTERNAL_NAMESPACE::dataWindowForLevel (
+                _data->tileDesc,
+                _data->minX, _data->maxX,
+                _data->minY, _data->maxY,
+                lx, ly);
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        REPLACE_EXC (e, "Error calling dataWindowForLevel() on image "
+                        "file \"" << fileName() << "\". " << e);
+        throw;
+    }
+}
+
+
+Box2i
+DeepTiledOutputFile::dataWindowForTile (int dx, int dy, int l) const
+{
+    return dataWindowForTile (dx, dy, l, l);
+}
+
+
+Box2i
+DeepTiledOutputFile::dataWindowForTile (int dx, int dy, int lx, int ly) const
+{
+    try
+    {
+        if (!isValidTile (dx, dy, lx, ly))
+            throw IEX_NAMESPACE::ArgExc ("Arguments not in valid range.");
+
+        return OPENEXR_IMF_INTERNAL_NAMESPACE::dataWindowForTile (
+                _data->tileDesc,
+                _data->minX, _data->maxX,
+                _data->minY, _data->maxY,
+                dx, dy,
+                lx, ly);
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        REPLACE_EXC (e, "Error calling dataWindowForTile() on image "
+                        "file \"" << fileName() << "\". " << e);
+        throw;
+    }
+}
+
+
+bool
+DeepTiledOutputFile::isValidTile (int dx, int dy, int lx, int ly) const
+{
+    return ((lx < _data->numXLevels && lx >= 0) &&
+            (ly < _data->numYLevels && ly >= 0) &&
+            (dx < _data->numXTiles[lx] && dx >= 0) &&
+            (dy < _data->numYTiles[ly] && dy >= 0));
+}
+
+
+void
+DeepTiledOutputFile::updatePreviewImage (const PreviewRgba newPixels[])
+{
+    Lock lock (*_data->_streamData);
+
+    if (_data->previewPosition <= 0)
+        THROW (IEX_NAMESPACE::LogicExc, "Cannot update preview image pixels. "
+                              "File \"" << fileName() << "\" does not "
+                              "contain a preview image.");
+
+    //
+    // Store the new pixels in the header's preview image attribute.
+    //
+
+    PreviewImageAttribute &pia =
+        _data->header.typedAttribute <PreviewImageAttribute> ("preview");
+
+    PreviewImage &pi = pia.value();
+    PreviewRgba *pixels = pi.pixels();
+    int numPixels = pi.width() * pi.height();
+
+    for (int i = 0; i < numPixels; ++i)
+        pixels[i] = newPixels[i];
+
+    //
+    // Save the current file position, jump to the position in
+    // the file where the preview image starts, store the new
+    // preview image, and jump back to the saved file position.
+    //
+
+    Int64 savedPosition = _data->_streamData->os->tellp();
+
+    try
+    {
+        _data->_streamData->os->seekp (_data->previewPosition);
+        pia.writeValueTo (*_data->_streamData->os, _data->version);
+        _data->_streamData->os->seekp (savedPosition);
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        REPLACE_EXC (e, "Cannot update preview image pixels for "
+                        "file \"" << fileName() << "\". " << e);
+        throw;
+    }
+}
+
+
+void
+DeepTiledOutputFile::breakTile
+    (int dx, int dy,
+     int lx, int ly,
+     int offset,
+     int length,
+     char c)
+{
+    Lock lock (*_data->_streamData);
+
+    Int64 position = _data->tileOffsets (dx, dy, lx, ly);
+
+    if (!position)
+        THROW (IEX_NAMESPACE::ArgExc,
+               "Cannot overwrite tile "
+               "(" << dx << ", " << dy << ", " << lx << "," << ly << "). "
+               "The tile has not yet been stored in "
+               "file \"" << fileName() << "\".");
+
+    _data->_streamData->currentPosition = 0;
+    _data->_streamData->os->seekp (position + offset);
+
+    for (int i = 0; i < length; ++i)
+        _data->_streamData->os->write (&c, 1);
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfDeepTiledOutputFile.h b/Source/OpenEXR/IlmImf/ImfDeepTiledOutputFile.h
new file mode 100644
index 0000000..e12dda1
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfDeepTiledOutputFile.h
@@ -0,0 +1,475 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+#ifndef INCLUDED_IMF_DEEP_TILED_OUTPUT_FILE_H
+#define INCLUDED_IMF_DEEP_TILED_OUTPUT_FILE_H
+
+//-----------------------------------------------------------------------------
+//
+//      class DeepTiledOutputFile
+//
+//-----------------------------------------------------------------------------
+
+#include "ImfHeader.h"
+#include "ImfFrameBuffer.h"
+#include "ImathBox.h"
+#include "ImfThreading.h"
+#include "ImfGenericOutputFile.h"
+#include "ImfNamespace.h"
+#include "ImfForward.h"
+#include "ImfExport.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+
+class IMF_EXPORT DeepTiledOutputFile : public GenericOutputFile
+{
+  public:
+
+    //-------------------------------------------------------------------
+    // A constructor that opens the file with the specified name, and
+    // writes the file header.  The file header is also copied into the
+    // TiledOutputFile object, and can later be accessed via the header()
+    // method.
+    //
+    // Destroying TiledOutputFile constructed with this constructor
+    // automatically closes the corresponding files.
+    //
+    // The header must contain a TileDescriptionAttribute called "tiles".
+    //
+    // The x and y subsampling factors for all image channels must be 1;
+    // subsampling is not supported.
+    //
+    // Tiles can be written to the file in arbitrary order.  The line
+    // order attribute can be used to cause the tiles to be sorted in
+    // the file.  When the file is read later, reading the tiles in the
+    // same order as they are in the file tends to be significantly
+    // faster than reading the tiles in random order (see writeTile,
+    // below).
+    //-------------------------------------------------------------------
+
+    DeepTiledOutputFile (const char fileName[],
+                         const Header &header,
+                         int numThreads = globalThreadCount ());
+
+
+    // ----------------------------------------------------------------
+    // A constructor that attaches the new TiledOutputFile object to
+    // a file that has already been opened.  Destroying TiledOutputFile
+    // objects constructed with this constructor does not automatically
+    // close the corresponding files.
+    // ----------------------------------------------------------------
+
+    DeepTiledOutputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
+                         const Header &header,
+                         int numThreads = globalThreadCount ());
+
+
+    //-----------------------------------------------------
+    // Destructor
+    //
+    // Destroying a TiledOutputFile object before all tiles
+    // have been written results in an incomplete file.
+    //-----------------------------------------------------
+
+    virtual ~DeepTiledOutputFile ();
+
+
+    //------------------------
+    // Access to the file name
+    //------------------------
+
+    const char *        fileName () const;
+
+
+    //--------------------------
+    // Access to the file header
+    //--------------------------
+
+    const Header &      header () const;
+
+
+    //-------------------------------------------------------
+    // Set the current frame buffer -- copies the FrameBuffer
+    // object into the TiledOutputFile object.
+    //
+    // The current frame buffer is the source of the pixel
+    // data written to the file.  The current frame buffer
+    // must be set at least once before writeTile() is
+    // called.  The current frame buffer can be changed
+    // after each call to writeTile().
+    //-------------------------------------------------------
+
+    void                setFrameBuffer (const DeepFrameBuffer &frameBuffer);
+
+
+    //-----------------------------------
+    // Access to the current frame buffer
+    //-----------------------------------
+
+    const DeepFrameBuffer & frameBuffer () const;
+
+
+    //-------------------
+    // Utility functions:
+    //-------------------
+
+    //---------------------------------------------------------
+    // Multiresolution mode and tile size:
+    // The following functions return the xSize, ySize and mode
+    // fields of the file header's TileDescriptionAttribute.
+    //---------------------------------------------------------
+
+    unsigned int        tileXSize () const;
+    unsigned int        tileYSize () const;
+    LevelMode           levelMode () const;
+    LevelRoundingMode   levelRoundingMode () const;
+
+
+    //--------------------------------------------------------------------
+    // Number of levels:
+    //
+    // numXLevels() returns the file's number of levels in x direction.
+    //
+    //  if levelMode() == ONE_LEVEL:
+    //      return value is: 1
+    //
+    //  if levelMode() == MIPMAP_LEVELS:
+    //      return value is: rfunc (log (max (w, h)) / log (2)) + 1
+    //
+    //  if levelMode() == RIPMAP_LEVELS:
+    //      return value is: rfunc (log (w) / log (2)) + 1
+    //
+    //  where
+    //      w is the width of the image's data window,  max.x - min.x + 1,
+    //      y is the height of the image's data window, max.y - min.y + 1,
+    //      and rfunc(x) is either floor(x), or ceil(x), depending on
+    //      whether levelRoundingMode() returns ROUND_DOWN or ROUND_UP.
+    //
+    // numYLevels() returns the file's number of levels in y direction.
+    //
+    //  if levelMode() == ONE_LEVEL or levelMode() == MIPMAP_LEVELS:
+    //      return value is the same as for numXLevels()
+    //
+    //  if levelMode() == RIPMAP_LEVELS:
+    //      return value is: rfunc (log (h) / log (2)) + 1
+    //
+    //
+    // numLevels() is a convenience function for use with MIPMAP_LEVELS
+    // files.
+    //
+    //  if levelMode() == ONE_LEVEL or levelMode() == MIPMAP_LEVELS:
+    //      return value is the same as for numXLevels()
+    //
+    //  if levelMode() == RIPMAP_LEVELS:
+    //      an IEX_NAMESPACE::LogicExc exception is thrown
+    //
+    // isValidLevel(lx, ly) returns true if the file contains
+    // a level with level number (lx, ly), false if not.
+    //
+    //--------------------------------------------------------------------
+
+    int                 numLevels () const;
+    int                 numXLevels () const;
+    int                 numYLevels () const;
+    bool                isValidLevel (int lx, int ly) const;
+
+
+    //---------------------------------------------------------
+    // Dimensions of a level:
+    //
+    // levelWidth(lx) returns the width of a level with level
+    // number (lx, *), where * is any number.
+    //
+    //  return value is:
+    //      max (1, rfunc (w / pow (2, lx)))
+    //
+    //
+    // levelHeight(ly) returns the height of a level with level
+    // number (*, ly), where * is any number.
+    //
+    //  return value is:
+    //      max (1, rfunc (h / pow (2, ly)))
+    //
+    //---------------------------------------------------------
+
+    int                 levelWidth  (int lx) const;
+    int                 levelHeight (int ly) const;
+
+
+    //----------------------------------------------------------
+    // Number of tiles:
+    //
+    // numXTiles(lx) returns the number of tiles in x direction
+    // that cover a level with level number (lx, *), where * is
+    // any number.
+    //
+    //  return value is:
+    //      (levelWidth(lx) + tileXSize() - 1) / tileXSize()
+    //
+    //
+    // numYTiles(ly) returns the number of tiles in y direction
+    // that cover a level with level number (*, ly), where * is
+    // any number.
+    //
+    //  return value is:
+    //      (levelHeight(ly) + tileXSize() - 1) / tileXSize()
+    //
+    //----------------------------------------------------------
+
+    int                 numXTiles (int lx = 0) const;
+    int                 numYTiles (int ly = 0) const;
+
+
+    //---------------------------------------------------------
+    // Level pixel ranges:
+    //
+    // dataWindowForLevel(lx, ly) returns a 2-dimensional
+    // region of valid pixel coordinates for a level with
+    // level number (lx, ly)
+    //
+    //  return value is a Box2i with min value:
+    //      (dataWindow.min.x, dataWindow.min.y)
+    //
+    //  and max value:
+    //      (dataWindow.min.x + levelWidth(lx) - 1,
+    //       dataWindow.min.y + levelHeight(ly) - 1)
+    //
+    // dataWindowForLevel(level) is a convenience function used
+    // for ONE_LEVEL and MIPMAP_LEVELS files.  It returns
+    // dataWindowForLevel(level, level).
+    //
+    //---------------------------------------------------------
+
+    IMATH_NAMESPACE::Box2i        dataWindowForLevel (int l = 0) const;
+    IMATH_NAMESPACE::Box2i        dataWindowForLevel (int lx, int ly) const;
+
+
+    //-------------------------------------------------------------------
+    // Tile pixel ranges:
+    //
+    // dataWindowForTile(dx, dy, lx, ly) returns a 2-dimensional
+    // region of valid pixel coordinates for a tile with tile coordinates
+    // (dx,dy) and level number (lx, ly).
+    //
+    //  return value is a Box2i with min value:
+    //      (dataWindow.min.x + dx * tileXSize(),
+    //       dataWindow.min.y + dy * tileYSize())
+    //
+    //  and max value:
+    //      (dataWindow.min.x + (dx + 1) * tileXSize() - 1,
+    //       dataWindow.min.y + (dy + 1) * tileYSize() - 1)
+    //
+    // dataWindowForTile(dx, dy, level) is a convenience function
+    // used for ONE_LEVEL and MIPMAP_LEVELS files.  It returns
+    // dataWindowForTile(dx, dy, level, level).
+    //
+    //-------------------------------------------------------------------
+
+    IMATH_NAMESPACE::Box2i        dataWindowForTile (int dx, int dy,
+                                           int l = 0) const;
+
+    IMATH_NAMESPACE::Box2i        dataWindowForTile (int dx, int dy,
+                                           int lx, int ly) const;
+
+    //------------------------------------------------------------------
+    // Write pixel data:
+    //
+    // writeTile(dx, dy, lx, ly) writes the tile with tile
+    // coordinates (dx, dy), and level number (lx, ly) to
+    // the file.
+    //
+    //   dx must lie in the interval [0, numXTiles(lx) - 1]
+    //   dy must lie in the interval [0, numYTiles(ly) - 1]
+    //
+    //   lx must lie in the interval [0, numXLevels() - 1]
+    //   ly must lie in the inverval [0, numYLevels() - 1]
+    //
+    // writeTile(dx, dy, level) is a convenience function
+    // used for ONE_LEVEL and MIPMAP_LEVEL files.  It calls
+    // writeTile(dx, dy, level, level).
+    //
+    // The two writeTiles(dx1, dx2, dy1, dy2, ...) functions allow
+    // writing multiple tiles at once.  If multi-threading is used
+    // multiple tiles are written concurrently.  The tile coordinates,
+    // dx1, dx2 and dy1, dy2, specify inclusive ranges of tile
+    // coordinates.  It is valid for dx1 < dx2 or dy1 < dy2; the
+    // tiles are always written in the order specified by the line
+    // order attribute.  Hence, it is not possible to specify an
+    // "invalid" or empty tile range.
+    //
+    // Pixels that are outside the pixel coordinate range for the tile's
+    // level, are never accessed by writeTile().
+    //
+    // Each tile in the file must be written exactly once.
+    //
+    // The file's line order attribute determines the order of the tiles
+    // in the file:
+    //
+    //   INCREASING_Y   In the file, the tiles for each level are stored
+    //                  in a contiguous block.  The levels are ordered
+    //                  like this:
+    //
+    //                      (0, 0)   (1, 0)   ... (nx-1, 0)
+    //                      (0, 1)   (1, 1)   ... (nx-1, 1)
+    //                       ...
+    //                      (0,ny-1) (1,ny-1) ... (nx-1,ny-1)
+    //
+    //                  where nx = numXLevels(), and ny = numYLevels().
+    //                  In an individual level, (lx, ly), the tiles
+    //                  are stored in the following order:
+    //
+    //                      (0, 0)   (1, 0)   ... (tx-1, 0)
+    //                      (0, 1)   (1, 1)   ... (tx-1, 1)
+    //                       ...
+    //                      (0,ty-1) (1,ty-1) ... (tx-1,ty-1)
+    //
+    //                  where tx = numXTiles(lx),
+    //                  and   ty = numYTiles(ly).
+    //
+    //   DECREASING_Y   As for INCREASING_Y, the tiles for each level
+    //                  are stored in a contiguous block.  The levels
+    //                  are ordered the same way as for INCREASING_Y,
+    //                  but within an individual level, the tiles
+    //                  are stored in this order:
+    //
+    //                      (0,ty-1) (1,ty-1) ... (tx-1,ty-1)
+    //                       ...
+    //                      (0, 1)   (1, 1)   ... (tx-1, 1)
+    //                      (0, 0)   (1, 0)   ... (tx-1, 0)
+    //
+    //
+    //   RANDOM_Y       The order of the calls to writeTile() determines
+    //                  the order of the tiles in the file.
+    //
+    //------------------------------------------------------------------
+
+    void                writeTile  (int dx, int dy, int l = 0);
+    void                writeTile  (int dx, int dy, int lx, int ly);
+
+    void                writeTiles (int dx1, int dx2, int dy1, int dy2,
+                                    int lx, int ly);
+
+    void                writeTiles (int dx1, int dx2, int dy1, int dy2,
+                                    int l = 0);
+
+
+    //------------------------------------------------------------------
+    // Shortcut to copy all pixels from a TiledInputFile into this file,
+    // without uncompressing and then recompressing the pixel data.
+    // This file's header must be compatible with the TiledInputFile's
+    // header:  The two header's "dataWindow", "compression",
+    // "lineOrder", "channels", and "tiles" attributes must be the same.
+    //------------------------------------------------------------------
+
+    void                copyPixels (DeepTiledInputFile &in);
+    void                copyPixels (DeepTiledInputPart &in);
+
+
+
+    //--------------------------------------------------------------
+    // Updating the preview image:
+    //
+    // updatePreviewImage() supplies a new set of pixels for the
+    // preview image attribute in the file's header.  If the header
+    // does not contain a preview image, updatePreviewImage() throws
+    // an IEX_NAMESPACE::LogicExc.
+    //
+    // Note: updatePreviewImage() is necessary because images are
+    // often stored in a file incrementally, a few tiles at a time,
+    // while the image is being generated.  Since the preview image
+    // is an attribute in the file's header, it gets stored in the
+    // file as soon as the file is opened, but we may not know what
+    // the preview image should look like until we have written the
+    // last tile of the main image.
+    //
+    //--------------------------------------------------------------
+
+    void                updatePreviewImage (const PreviewRgba newPixels[]);
+
+
+    //-------------------------------------------------------------
+    // Break a tile -- for testing and debugging only:
+    //
+    // breakTile(dx,dy,lx,ly,p,n,c) introduces an error into the
+    // output file by writing n copies of character c, starting
+    // p bytes from the beginning of the tile with tile coordinates
+    // (dx, dy) and level number (lx, ly).
+    //
+    // Warning: Calling this function usually results in a broken
+    // image file.  The file or parts of it may not be readable,
+    // or the file may contain bad data.
+    //
+    //-------------------------------------------------------------
+
+    void                breakTile  (int dx, int dy,
+                                    int lx, int ly,
+                                    int offset,
+                                    int length,
+                                    char c);
+    struct Data;
+
+  private:
+
+    // ----------------------------------------------------------------
+    // A constructor attaches the OutputStreamMutex to the
+    // given one from MultiPartOutputFile. Set the previewPosition
+    // and lineOffsetsPosition which have been acquired from
+    // the constructor of MultiPartOutputFile as well.
+    // ----------------------------------------------------------------
+    DeepTiledOutputFile (const OutputPartData* part);
+
+    DeepTiledOutputFile (const DeepTiledOutputFile &);              // not implemented
+    DeepTiledOutputFile & operator = (const DeepTiledOutputFile &); // not implemented
+
+    void                initialize (const Header &header);
+
+    bool                isValidTile (int dx, int dy,
+                                     int lx, int ly) const;
+
+    size_t              bytesPerLineForTile (int dx, int dy,
+                                             int lx, int ly) const;
+
+    Data *              _data;
+
+
+    friend class MultiPartOutputFile;
+
+};
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif
diff --git a/Source/OpenEXR/IlmImf/ImfDeepTiledOutputPart.cpp b/Source/OpenEXR/IlmImf/ImfDeepTiledOutputPart.cpp
new file mode 100644
index 0000000..7239c01
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfDeepTiledOutputPart.cpp
@@ -0,0 +1,250 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#include "ImfDeepTiledOutputPart.h"
+#include "ImfMultiPartOutputFile.h"
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+DeepTiledOutputPart::DeepTiledOutputPart(MultiPartOutputFile& multiPartFile, int partNumber)
+{
+    file = multiPartFile.getOutputPart<DeepTiledOutputFile>(partNumber);
+}
+
+const char *
+DeepTiledOutputPart::fileName () const
+{
+    return file->fileName();
+}
+
+
+const Header &
+DeepTiledOutputPart::header () const
+{
+    return file->header();
+}
+
+
+void
+DeepTiledOutputPart::setFrameBuffer (const DeepFrameBuffer &frameBuffer)
+{
+    file->setFrameBuffer(frameBuffer);
+}
+
+
+const DeepFrameBuffer &
+DeepTiledOutputPart::frameBuffer () const
+{
+    return file->frameBuffer();
+}
+
+
+unsigned int
+DeepTiledOutputPart::tileXSize () const
+{
+    return file->tileXSize();
+}
+
+
+unsigned int
+DeepTiledOutputPart::tileYSize () const
+{
+    return file->tileYSize();
+}
+
+
+LevelMode
+DeepTiledOutputPart::levelMode () const
+{
+    return file->levelMode();
+}
+
+
+LevelRoundingMode
+DeepTiledOutputPart::levelRoundingMode () const
+{
+    return file->levelRoundingMode();
+}
+
+
+int
+DeepTiledOutputPart::numLevels () const
+{
+    return file->numLevels();
+}
+
+
+int
+DeepTiledOutputPart::numXLevels () const
+{
+    return file->numXLevels();
+}
+
+
+int
+DeepTiledOutputPart::numYLevels () const
+{
+    return file->numYLevels();
+}
+
+
+bool
+DeepTiledOutputPart::isValidLevel (int lx, int ly) const
+{
+    return file->isValidLevel(lx, ly);
+}
+
+
+int
+DeepTiledOutputPart::levelWidth  (int lx) const
+{
+    return file->levelWidth(lx);
+}
+
+
+int
+DeepTiledOutputPart::levelHeight (int ly) const
+{
+    return file->levelHeight(ly);
+}
+
+
+int
+DeepTiledOutputPart::numXTiles (int lx) const
+{
+    return file->numXTiles(lx);
+}
+
+
+int
+DeepTiledOutputPart::numYTiles (int ly) const
+{
+    return file->numYTiles(ly);
+}
+
+
+
+IMATH_NAMESPACE::Box2i
+DeepTiledOutputPart::dataWindowForLevel (int l) const
+{
+    return file->dataWindowForLevel(l);
+}
+
+
+IMATH_NAMESPACE::Box2i
+DeepTiledOutputPart::dataWindowForLevel (int lx, int ly) const
+{
+    return file->dataWindowForLevel(lx, ly);
+}
+
+
+IMATH_NAMESPACE::Box2i
+DeepTiledOutputPart::dataWindowForTile (int dx, int dy,
+                                        int l) const
+{
+    return file->dataWindowForTile(dx, dy, l);
+}
+
+
+IMATH_NAMESPACE::Box2i
+DeepTiledOutputPart::dataWindowForTile (int dx, int dy,
+                                        int lx, int ly) const
+{
+    return file->dataWindowForTile(dx, dy, lx, ly);
+}
+
+
+void
+DeepTiledOutputPart::writeTile  (int dx, int dy, int l)
+{
+    file->writeTile(dx, dy, l);
+}
+
+
+void
+DeepTiledOutputPart::writeTile  (int dx, int dy, int lx, int ly)
+{
+    file->writeTile(dx, dy, lx, ly);
+}
+
+
+void
+DeepTiledOutputPart::writeTiles (int dx1, int dx2, int dy1, int dy2,
+                                 int lx, int ly)
+{
+    file->writeTiles(dx1, dx2, dy1, dy2, lx, ly);
+}
+
+
+void
+DeepTiledOutputPart::writeTiles (int dx1, int dx2, int dy1, int dy2,
+                                 int l)
+{
+    file->writeTiles(dx1, dx2, dy1, dy2, l);
+}
+
+
+void
+DeepTiledOutputPart::copyPixels (DeepTiledInputFile &in)
+{
+    file->copyPixels(in);
+}
+
+
+void
+DeepTiledOutputPart::copyPixels (DeepTiledInputPart &in)
+{
+    file->copyPixels(in);
+}
+
+
+void
+DeepTiledOutputPart::updatePreviewImage (const PreviewRgba newPixels[])
+{
+    file->updatePreviewImage(newPixels);
+}
+
+
+void
+DeepTiledOutputPart::breakTile  (int dx, int dy,
+                                 int lx, int ly,
+                                 int offset,
+                                 int length,
+                                 char c)
+{
+    file->breakTile(dx, dy, lx, ly, offset, length, c);
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfDeepTiledOutputPart.h b/Source/OpenEXR/IlmImf/ImfDeepTiledOutputPart.h
new file mode 100644
index 0000000..c88da12
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfDeepTiledOutputPart.h
@@ -0,0 +1,394 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef IMFDEEPTILEDOUTPUTPART_H_
+#define IMFDEEPTILEDOUTPUTPART_H_
+
+#include "ImfForward.h"
+#include "ImfDeepTiledInputFile.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+
+class IMF_EXPORT DeepTiledOutputPart
+{
+  public:
+
+    DeepTiledOutputPart(MultiPartOutputFile& multiPartFile, int partNumber);
+
+    //------------------------
+    // Access to the file name
+    //------------------------
+
+    const char *        fileName () const;
+
+
+    //--------------------------
+    // Access to the file header
+    //--------------------------
+
+    const Header &      header () const;
+
+
+    //-------------------------------------------------------
+    // Set the current frame buffer -- copies the FrameBuffer
+    // object into the TiledOutputFile object.
+    //
+    // The current frame buffer is the source of the pixel
+    // data written to the file.  The current frame buffer
+    // must be set at least once before writeTile() is
+    // called.  The current frame buffer can be changed
+    // after each call to writeTile().
+    //-------------------------------------------------------
+
+    void                setFrameBuffer (const DeepFrameBuffer &frameBuffer);
+
+
+    //-----------------------------------
+    // Access to the current frame buffer
+    //-----------------------------------
+
+    const DeepFrameBuffer & frameBuffer () const;
+
+
+    //-------------------
+    // Utility functions:
+    //-------------------
+
+    //---------------------------------------------------------
+    // Multiresolution mode and tile size:
+    // The following functions return the xSize, ySize and mode
+    // fields of the file header's TileDescriptionAttribute.
+    //---------------------------------------------------------
+
+    unsigned int        tileXSize () const;
+    unsigned int        tileYSize () const;
+    LevelMode           levelMode () const;
+    LevelRoundingMode   levelRoundingMode () const;
+
+
+    //--------------------------------------------------------------------
+    // Number of levels:
+    //
+    // numXLevels() returns the file's number of levels in x direction.
+    //
+    //  if levelMode() == ONE_LEVEL:
+    //      return value is: 1
+    //
+    //  if levelMode() == MIPMAP_LEVELS:
+    //      return value is: rfunc (log (max (w, h)) / log (2)) + 1
+    //
+    //  if levelMode() == RIPMAP_LEVELS:
+    //      return value is: rfunc (log (w) / log (2)) + 1
+    //
+    //  where
+    //      w is the width of the image's data window,  max.x - min.x + 1,
+    //      y is the height of the image's data window, max.y - min.y + 1,
+    //      and rfunc(x) is either floor(x), or ceil(x), depending on
+    //      whether levelRoundingMode() returns ROUND_DOWN or ROUND_UP.
+    //
+    // numYLevels() returns the file's number of levels in y direction.
+    //
+    //  if levelMode() == ONE_LEVEL or levelMode() == MIPMAP_LEVELS:
+    //      return value is the same as for numXLevels()
+    //
+    //  if levelMode() == RIPMAP_LEVELS:
+    //      return value is: rfunc (log (h) / log (2)) + 1
+    //
+    //
+    // numLevels() is a convenience function for use with MIPMAP_LEVELS
+    // files.
+    //
+    //  if levelMode() == ONE_LEVEL or levelMode() == MIPMAP_LEVELS:
+    //      return value is the same as for numXLevels()
+    //
+    //  if levelMode() == RIPMAP_LEVELS:
+    //      an IEX_NAMESPACE::LogicExc exception is thrown
+    //
+    // isValidLevel(lx, ly) returns true if the file contains
+    // a level with level number (lx, ly), false if not.
+    //
+    //--------------------------------------------------------------------
+
+    int                 numLevels () const;
+    int                 numXLevels () const;
+    int                 numYLevels () const;
+    bool                isValidLevel (int lx, int ly) const;
+
+
+    //---------------------------------------------------------
+    // Dimensions of a level:
+    //
+    // levelWidth(lx) returns the width of a level with level
+    // number (lx, *), where * is any number.
+    //
+    //  return value is:
+    //      max (1, rfunc (w / pow (2, lx)))
+    //
+    //
+    // levelHeight(ly) returns the height of a level with level
+    // number (*, ly), where * is any number.
+    //
+    //  return value is:
+    //      max (1, rfunc (h / pow (2, ly)))
+    //
+    //---------------------------------------------------------
+
+    int                 levelWidth  (int lx) const;
+    int                 levelHeight (int ly) const;
+
+
+    //----------------------------------------------------------
+    // Number of tiles:
+    //
+    // numXTiles(lx) returns the number of tiles in x direction
+    // that cover a level with level number (lx, *), where * is
+    // any number.
+    //
+    //  return value is:
+    //      (levelWidth(lx) + tileXSize() - 1) / tileXSize()
+    //
+    //
+    // numYTiles(ly) returns the number of tiles in y direction
+    // that cover a level with level number (*, ly), where * is
+    // any number.
+    //
+    //  return value is:
+    //      (levelHeight(ly) + tileXSize() - 1) / tileXSize()
+    //
+    //----------------------------------------------------------
+
+    int                 numXTiles (int lx = 0) const;
+    int                 numYTiles (int ly = 0) const;
+
+
+    //---------------------------------------------------------
+    // Level pixel ranges:
+    //
+    // dataWindowForLevel(lx, ly) returns a 2-dimensional
+    // region of valid pixel coordinates for a level with
+    // level number (lx, ly)
+    //
+    //  return value is a Box2i with min value:
+    //      (dataWindow.min.x, dataWindow.min.y)
+    //
+    //  and max value:
+    //      (dataWindow.min.x + levelWidth(lx) - 1,
+    //       dataWindow.min.y + levelHeight(ly) - 1)
+    //
+    // dataWindowForLevel(level) is a convenience function used
+    // for ONE_LEVEL and MIPMAP_LEVELS files.  It returns
+    // dataWindowForLevel(level, level).
+    //
+    //---------------------------------------------------------
+
+    IMATH_NAMESPACE::Box2i        dataWindowForLevel (int l = 0) const;
+    IMATH_NAMESPACE::Box2i        dataWindowForLevel (int lx, int ly) const;
+
+
+    //-------------------------------------------------------------------
+    // Tile pixel ranges:
+    //
+    // dataWindowForTile(dx, dy, lx, ly) returns a 2-dimensional
+    // region of valid pixel coordinates for a tile with tile coordinates
+    // (dx,dy) and level number (lx, ly).
+    //
+    //  return value is a Box2i with min value:
+    //      (dataWindow.min.x + dx * tileXSize(),
+    //       dataWindow.min.y + dy * tileYSize())
+    //
+    //  and max value:
+    //      (dataWindow.min.x + (dx + 1) * tileXSize() - 1,
+    //       dataWindow.min.y + (dy + 1) * tileYSize() - 1)
+    //
+    // dataWindowForTile(dx, dy, level) is a convenience function
+    // used for ONE_LEVEL and MIPMAP_LEVELS files.  It returns
+    // dataWindowForTile(dx, dy, level, level).
+    //
+    //-------------------------------------------------------------------
+
+    IMATH_NAMESPACE::Box2i        dataWindowForTile (int dx, int dy,
+                                         int l = 0) const;
+
+    IMATH_NAMESPACE::Box2i        dataWindowForTile (int dx, int dy,
+                                         int lx, int ly) const;
+
+    //------------------------------------------------------------------
+    // Write pixel data:
+    //
+    // writeTile(dx, dy, lx, ly) writes the tile with tile
+    // coordinates (dx, dy), and level number (lx, ly) to
+    // the file.
+    //
+    //   dx must lie in the interval [0, numXTiles(lx) - 1]
+    //   dy must lie in the interval [0, numYTiles(ly) - 1]
+    //
+    //   lx must lie in the interval [0, numXLevels() - 1]
+    //   ly must lie in the inverval [0, numYLevels() - 1]
+    //
+    // writeTile(dx, dy, level) is a convenience function
+    // used for ONE_LEVEL and MIPMAP_LEVEL files.  It calls
+    // writeTile(dx, dy, level, level).
+    //
+    // The two writeTiles(dx1, dx2, dy1, dy2, ...) functions allow
+    // writing multiple tiles at once.  If multi-threading is used
+    // multiple tiles are written concurrently.  The tile coordinates,
+    // dx1, dx2 and dy1, dy2, specify inclusive ranges of tile
+    // coordinates.  It is valid for dx1 < dx2 or dy1 < dy2; the
+    // tiles are always written in the order specified by the line
+    // order attribute.  Hence, it is not possible to specify an
+    // "invalid" or empty tile range.
+    //
+    // Pixels that are outside the pixel coordinate range for the tile's
+    // level, are never accessed by writeTile().
+    //
+    // Each tile in the file must be written exactly once.
+    //
+    // The file's line order attribute determines the order of the tiles
+    // in the file:
+    //
+    //   INCREASING_Y   In the file, the tiles for each level are stored
+    //                  in a contiguous block.  The levels are ordered
+    //                  like this:
+    //
+    //                      (0, 0)   (1, 0)   ... (nx-1, 0)
+    //                      (0, 1)   (1, 1)   ... (nx-1, 1)
+    //                       ...
+    //                      (0,ny-1) (1,ny-1) ... (nx-1,ny-1)
+    //
+    //                  where nx = numXLevels(), and ny = numYLevels().
+    //                  In an individual level, (lx, ly), the tiles
+    //                  are stored in the following order:
+    //
+    //                      (0, 0)   (1, 0)   ... (tx-1, 0)
+    //                      (0, 1)   (1, 1)   ... (tx-1, 1)
+    //                       ...
+    //                      (0,ty-1) (1,ty-1) ... (tx-1,ty-1)
+    //
+    //                  where tx = numXTiles(lx),
+    //                  and   ty = numYTiles(ly).
+    //
+    //   DECREASING_Y   As for INCREASING_Y, the tiles for each level
+    //                  are stored in a contiguous block.  The levels
+    //                  are ordered the same way as for INCREASING_Y,
+    //                  but within an individual level, the tiles
+    //                  are stored in this order:
+    //
+    //                      (0,ty-1) (1,ty-1) ... (tx-1,ty-1)
+    //                       ...
+    //                      (0, 1)   (1, 1)   ... (tx-1, 1)
+    //                      (0, 0)   (1, 0)   ... (tx-1, 0)
+    //
+    //
+    //   RANDOM_Y       The order of the calls to writeTile() determines
+    //                  the order of the tiles in the file.
+    //
+    //------------------------------------------------------------------
+
+    void                writeTile  (int dx, int dy, int l = 0);
+    void                writeTile  (int dx, int dy, int lx, int ly);
+
+    void                writeTiles (int dx1, int dx2, int dy1, int dy2,
+                                  int lx, int ly);
+
+    void                writeTiles (int dx1, int dx2, int dy1, int dy2,
+                                  int l = 0);
+
+
+    //------------------------------------------------------------------
+    // Shortcut to copy all pixels from a TiledInputFile into this file,
+    // without uncompressing and then recompressing the pixel data.
+    // This file's header must be compatible with the TiledInputFile's
+    // header:  The two header's "dataWindow", "compression",
+    // "lineOrder", "channels", and "tiles" attributes must be the same.
+    //------------------------------------------------------------------
+
+    void                copyPixels (DeepTiledInputFile &in);
+    void                copyPixels (DeepTiledInputPart &in);
+    
+
+
+
+    //--------------------------------------------------------------
+    // Updating the preview image:
+    //
+    // updatePreviewImage() supplies a new set of pixels for the
+    // preview image attribute in the file's header.  If the header
+    // does not contain a preview image, updatePreviewImage() throws
+    // an IEX_NAMESPACE::LogicExc.
+    //
+    // Note: updatePreviewImage() is necessary because images are
+    // often stored in a file incrementally, a few tiles at a time,
+    // while the image is being generated.  Since the preview image
+    // is an attribute in the file's header, it gets stored in the
+    // file as soon as the file is opened, but we may not know what
+    // the preview image should look like until we have written the
+    // last tile of the main image.
+    //
+    //--------------------------------------------------------------
+
+    void                updatePreviewImage (const PreviewRgba newPixels[]);
+
+
+    //-------------------------------------------------------------
+    // Break a tile -- for testing and debugging only:
+    //
+    // breakTile(dx,dy,lx,ly,p,n,c) introduces an error into the
+    // output file by writing n copies of character c, starting
+    // p bytes from the beginning of the tile with tile coordinates
+    // (dx, dy) and level number (lx, ly).
+    //
+    // Warning: Calling this function usually results in a broken
+    // image file.  The file or parts of it may not be readable,
+    // or the file may contain bad data.
+    //
+    //-------------------------------------------------------------
+
+    void                breakTile  (int dx, int dy,
+                                  int lx, int ly,
+                                  int offset,
+                                  int length,
+                                  char c);
+
+  private:
+    DeepTiledOutputFile* file;
+    
+};
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif /* IMFDEEPTILEDOUTPUTPART_H_ */
diff --git a/Source/OpenEXR/IlmImf/ImfDoubleAttribute.cpp b/Source/OpenEXR/IlmImf/ImfDoubleAttribute.cpp
index 1ed40c0..cbeabe3 100644
--- a/Source/OpenEXR/IlmImf/ImfDoubleAttribute.cpp
+++ b/Source/OpenEXR/IlmImf/ImfDoubleAttribute.cpp
@@ -43,7 +43,7 @@
 #include <ImfDoubleAttribute.h>
 
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 template <>
@@ -54,4 +54,4 @@ DoubleAttribute::staticTypeName ()
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT 
diff --git a/Source/OpenEXR/IlmImf/ImfDoubleAttribute.h b/Source/OpenEXR/IlmImf/ImfDoubleAttribute.h
index bafd1ef..d9a88a8 100644
--- a/Source/OpenEXR/IlmImf/ImfDoubleAttribute.h
+++ b/Source/OpenEXR/IlmImf/ImfDoubleAttribute.h
@@ -43,21 +43,17 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfAttribute.h>
+#include "ImfAttribute.h"
+#include "ImfExport.h"
 
-
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 typedef TypedAttribute<double> DoubleAttribute;
-template <> const char *DoubleAttribute::staticTypeName ();
+template <> IMF_EXPORT const char *DoubleAttribute::staticTypeName ();
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
-// Metrowerks compiler wants the .cpp file inlined, too
-#ifdef __MWERKS__
-#include <ImfDoubleAttribute.cpp>
-#endif
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfDwaCompressor.cpp b/Source/OpenEXR/IlmImf/ImfDwaCompressor.cpp
new file mode 100644
index 0000000..1c1bd45
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfDwaCompressor.cpp
@@ -0,0 +1,3424 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2009-2014 DreamWorks Animation LLC. 
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of DreamWorks Animation nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+//---------------------------------------------------
+//
+// class DwaCompressor -- Store lossy RGB data by quantizing
+//                          DCT components.
+//
+// First, we try and figure out what compression strategy to take
+// based in channel name. For RGB channels, we want a lossy method
+// described below. But, if we have alpha, we should do something
+// different (and probably using RLE). If we have depth, or velocity,
+// or something else, just fall back to ZIP. The rules for deciding 
+// which strategy to use are setup in initializeDefaultChannelRules().
+// When writing a file, the relevant rules needed to decode are written
+// into the start of the data block, making a self-contained file. 
+// If initializeDefaultChannelRules() doesn't quite suite your naming
+// conventions, you can adjust the rules without breaking decoder
+// compatability.
+//
+// If we're going to lossy compress R, G, or B channels, it's easier
+// to toss bits in a more perceptual uniform space. One could argue
+// at length as to what constitutes perceptually uniform, expecially 
+// when storing either scene/input/focal plane referred and output referred
+// data. 
+//
+// We'll compromise. For values <= 1, we use a traditional power function
+// (without any of that straight-line business at the bottom). For values > 1,
+// we want something more like a log function, since power functions blow
+// up. At 1, we want a smooth blend between the functions. So, we use a 
+// piecewise function that does just that - see dwaLookups.cpp for 
+// a little more detail.
+//
+// Also, if we find that we have R, G, and B channels from the same layer,
+// we can get a bit more compression efficiency by transforming to a Y'CbCr
+// space. We use the 709 transform, but with Cb,Cr = 0 for an input of 
+// (0, 0, 0), instead of the traditional Cb,Cr = .5. Shifting the zero point
+// makes no sense with large range data. Transforms are done to from 
+// the perceptual space data, not the linear-light space data (R'G'B' ->
+// (Y'CbCr, not RGB -> YCbCr).
+//
+// Next, we forward DCT the data. This is done with a floating
+// point DCT, as we don't really have control over the src range. The 
+// resulting values are dropped to half-float precision. 
+//
+// Now, we need to quantize. Quantization departs from the usual way 
+// of dividing and rounding. Instead, we start with some floating 
+// point "base-error" value. From this, we can derive quantization 
+// error for each DCT component. Take the standard JPEG quantization
+// tables and normalize them by the smallest value. Then, multiply
+// the normalized quant tables by our base-error value. This gives
+// a range of errors for each DCT component.
+//
+// For each DCT component, we want to find a quantized value that 
+// is within +- the per-component error. Pick the quantized value
+// that has the fewest bits set in its' binary representation. 
+// Brute-forcing the search would make for extremly inefficient 
+// compression. Fortunatly, we can precompute a table to assist 
+// with this search. 
+//
+// For each 16-bit float value, there are at most 15 other values with
+// fewer bits set. We can precompute these values in a compact form, since
+// many source values have far fewer that 15 possible quantized values. 
+// Now, instead of searching the entire range +- the component error,
+// we can just search at most 15 quantization candidates. The search can
+// be accelerated a bit more by sorting the candidates by the 
+// number of bits set, in increasing order. Then, the search can stop
+// once a candidate is found w/i the per-component quantization 
+// error range.
+//
+// The quantization strategy has the side-benefit that there is no
+// de-quantization step upon decode, so we don't bother recording
+// the quantization table.
+//
+// Ok. So we now have quantized values. Time for entropy coding. We
+// can use either static Huffman or zlib/DEFLATE. The static Huffman
+// is more efficient at compacting data, but can have a greater 
+// overhead, especially for smaller tile/strip sizes. 
+//
+// There is some additional fun, like ZIP compressing the DC components
+// instead of Huffman/zlib, which helps make things slightly smaller.
+//
+// Compression level is controlled by setting an int/float/double attribute
+// on the header named "dwaCompressionLevel". This is a thinly veiled name for 
+// the "base-error" value mentioned above. The "base-error" is just
+// dwaCompressionLevel / 100000. The default value of 45.0 is generally 
+// pretty good at generating "visually lossless" values at reasonable
+// data rates. Setting dwaCompressionLevel to 0 should result in no additional
+// quantization at the quantization stage (though there may be 
+// quantization in practice at the CSC/DCT steps). But if you really
+// want lossless compression, there are pleanty of other choices 
+// of compressors ;)
+//
+// When dealing with FLOAT source buffers, we first quantize the source
+// to HALF and continue down as we would for HALF source.
+//
+//---------------------------------------------------
+
+
+#include "ImfDwaCompressor.h"
+#include "ImfDwaCompressorSimd.h"
+
+#include "ImfChannelList.h"
+#include "ImfStandardAttributes.h"
+#include "ImfHeader.h"
+#include "ImfHuf.h"
+#include "ImfInt64.h"
+#include "ImfIntAttribute.h"
+#include "ImfIO.h"
+#include "ImfMisc.h"
+#include "ImfNamespace.h"
+#include "ImfRle.h"
+#include "ImfSimd.h"
+#include "ImfSystemSpecific.h"
+#include "ImfXdr.h"
+#include "ImfZip.h"
+
+#include "ImathFun.h"
+#include "ImathBox.h"
+#include "ImathVec.h"
+#include "half.h"
+
+#include "dwaLookups.h"
+
+#include <vector>
+#include <string>
+#include <cctype>
+#include <cassert>
+#include <algorithm>
+
+// Windows specific addition to prevent the indirect import of the redefined min/max macros
+#if defined _WIN32 || defined _WIN64
+	#ifdef NOMINMAX
+		#undef NOMINMAX
+	#endif
+	#define NOMINMAX
+#endif
+#include <zlib.h>
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+
+namespace {
+
+    //
+    // Function pointer to dispatch to an approprate 
+    // convertFloatToHalf64_* impl, based on runtime cpu checking.
+    // Should be initialized in DwaCompressor::initializeFuncs()
+    //
+
+    void (*convertFloatToHalf64)(unsigned short*, float*) =
+        convertFloatToHalf64_scalar;
+
+    // 
+    // Function pointer for dispatching a fromHalfZigZag_ impl
+    //
+    
+    void (*fromHalfZigZag)(unsigned short*, float*) =
+        fromHalfZigZag_scalar;
+
+    //
+    // Dispatch the inverse DCT on an 8x8 block, where the last
+    // n rows can be all zeros. The n=0 case converts the full block.
+    //
+    void (*dctInverse8x8_0)(float*) = dctInverse8x8_scalar<0>;
+    void (*dctInverse8x8_1)(float*) = dctInverse8x8_scalar<1>;
+    void (*dctInverse8x8_2)(float*) = dctInverse8x8_scalar<2>;
+    void (*dctInverse8x8_3)(float*) = dctInverse8x8_scalar<3>;
+    void (*dctInverse8x8_4)(float*) = dctInverse8x8_scalar<4>;
+    void (*dctInverse8x8_5)(float*) = dctInverse8x8_scalar<5>;
+    void (*dctInverse8x8_6)(float*) = dctInverse8x8_scalar<6>;
+    void (*dctInverse8x8_7)(float*) = dctInverse8x8_scalar<7>;
+    
+} // namespace
+
+
+struct DwaCompressor::ChannelData
+{
+    std::string         name;
+    CompressorScheme    compression;  
+    int                 xSampling;
+    int                 ySampling;
+    PixelType           type;
+    bool                pLinear;
+
+    int                 width;
+    int                 height;
+
+    //
+    // Incoming and outgoing data is scanline interleaved, and it's much
+    // easier to operate on contiguous data.  Assuming the planare unc
+    // buffer is to hold RLE data, we need to rearrange to make bytes
+    // adjacent.
+    //
+
+    char               *planarUncBuffer;
+    char               *planarUncBufferEnd;
+
+    char               *planarUncRle[4];
+    char               *planarUncRleEnd[4];
+
+    PixelType           planarUncType;
+    int                 planarUncSize;
+};
+
+
+struct DwaCompressor::CscChannelSet
+{
+    int idx[3];
+};
+
+
+struct DwaCompressor::Classifier
+{
+    Classifier (std::string suffix,
+                CompressorScheme scheme,
+                PixelType type,
+                int cscIdx,
+                bool caseInsensitive):
+        _suffix(suffix),
+        _scheme(scheme),
+        _type(type),
+        _cscIdx(cscIdx),
+        _caseInsensitive(caseInsensitive)
+    {
+        if (caseInsensitive) 
+            transform(_suffix.begin(), _suffix.end(), _suffix.begin(), tolower);
+    }
+
+    Classifier (const char *&ptr, int size)
+    {
+        if (size <= 0) 
+            throw Iex::InputExc("Error uncompressing DWA data"
+                                " (truncated rule).");
+            
+        {
+            char suffix[Name::SIZE];
+            memset (suffix, 0, Name::SIZE);
+            Xdr::read<CharPtrIO> (ptr, std::min(size, Name::SIZE-1), suffix);
+            _suffix = std::string(suffix);
+        }
+
+        if (size < _suffix.length() + 1 + 2*Xdr::size<char>()) 
+            throw Iex::InputExc("Error uncompressing DWA data"
+                                " (truncated rule).");
+
+        char value;
+        Xdr::read<CharPtrIO> (ptr, value);
+
+        _cscIdx = (int)(value >> 4) - 1;
+        if (_cscIdx < -1 || _cscIdx >= 3) 
+            throw Iex::InputExc("Error uncompressing DWA data"
+                                " (corrupt cscIdx rule).");
+
+        _scheme = (CompressorScheme)((value >> 2) & 3);
+        if (_scheme < 0 || _scheme >= NUM_COMPRESSOR_SCHEMES) 
+            throw Iex::InputExc("Error uncompressing DWA data"
+                                " (corrupt scheme rule).");
+
+        _caseInsensitive = (value & 1 ? true : false);
+
+        Xdr::read<CharPtrIO> (ptr, value);
+        if (value < 0 || value >= NUM_PIXELTYPES) 
+            throw Iex::InputExc("Error uncompressing DWA data"
+                                " (corrupt rule).");
+        _type = (PixelType)value;
+    }
+
+    bool match (const std::string &suffix, const PixelType type) const
+    {
+        if (_type != type) return false;
+
+        if (_caseInsensitive) 
+        {
+            std::string tmp(suffix);
+            transform(tmp.begin(), tmp.end(), tmp.begin(), tolower);
+            return tmp == _suffix;
+        }
+
+        return suffix == _suffix;
+    }
+
+    size_t size () const 
+    {
+        // string length + \0
+        size_t sizeBytes = _suffix.length() + 1;
+
+        // 1 byte for scheme / cscIdx / caseInsensitive, and 1 byte for type
+        sizeBytes += 2 * Xdr::size<char>();
+
+        return sizeBytes;
+    }
+
+    void write (char *&ptr) const
+    {
+        Xdr::write<CharPtrIO> (ptr, _suffix.c_str());
+
+        // Encode _cscIdx (-1-3) in the upper 4 bits,
+        //        _scheme (0-2)  in the next 2 bits
+        //        _caseInsen     in the bottom bit
+        unsigned char value = 0;
+        value |= ((unsigned char)(_cscIdx+1)      & 15) << 4;
+        value |= ((unsigned char)_scheme          &  3) << 2;
+        value |=  (unsigned char)_caseInsensitive &  1;
+
+        Xdr::write<CharPtrIO> (ptr, value);
+        Xdr::write<CharPtrIO> (ptr, (unsigned char)_type);
+    }
+
+    std::string      _suffix;
+    CompressorScheme _scheme;
+    PixelType        _type;
+    int              _cscIdx;
+    bool             _caseInsensitive;
+};
+
+
+//
+// Base class for the LOSSY_DCT decoder classes
+//
+
+class DwaCompressor::LossyDctDecoderBase
+{
+  public:
+
+    LossyDctDecoderBase
+        (char *packedAc,
+         char *packedDc,
+         const unsigned short *toLinear,
+         int width,
+         int height);
+
+    virtual ~LossyDctDecoderBase ();
+
+    void execute();
+
+    //
+    // These return number of items, not bytes. Each item
+    // is an unsigned short
+    //
+
+    int numAcValuesEncoded() const { return _packedAcCount; }
+    int numDcValuesEncoded() const { return _packedDcCount; }
+
+  protected:
+
+    //
+    // Un-RLE the packed AC components into 
+    // a half buffer. The half block should 
+    // be the full 8x8 block (in zig-zag order
+    // still), not the first AC component. 
+    //
+    // currAcComp is advanced as bytes are decoded.
+    //
+    // This returns the index of the last non-zero
+    // value in the buffer - with the index into zig zag
+    // order data. If we return 0, we have DC only data.
+    // 
+
+    int unRleAc (unsigned short *&currAcComp,
+                 unsigned short  *halfZigBlock); 
+
+
+    //
+    // if NATIVE and XDR are really the same values, we can
+    // skip some processing and speed things along
+    //
+
+    bool                  _isNativeXdr;
+
+
+    //
+    // Counts of how many items have been packed into the
+    // AC and DC buffers
+    //
+
+    int                   _packedAcCount;
+    int                   _packedDcCount;
+
+
+    //
+    // AC and DC buffers to pack
+    //
+
+    char                 *_packedAc;
+    char                 *_packedDc;
+
+
+    // 
+    // half -> half LUT to transform from nonlinear to linear
+    //
+
+    const unsigned short *_toLinear;
+
+
+    //
+    // image dimensions
+    //
+
+    int                   _width;
+    int                   _height;
+
+
+    //
+    // Pointers to the start of each scanlines, to be filled on decode
+    // Generally, these will be filled by the subclasses.
+    //
+
+    std::vector< std::vector<char *> > _rowPtrs;
+
+
+    // 
+    // The type of each data that _rowPtrs[i] is referring. Layout
+    // is in the same order as _rowPtrs[].
+    //
+
+    std::vector<PixelType>             _type;
+    std::vector<SimdAlignedBuffer64f>  _dctData;
+};
+
+
+//
+// Used to decode a single channel of LOSSY_DCT data.
+//
+
+class DwaCompressor::LossyDctDecoder: public LossyDctDecoderBase
+{
+  public:
+
+    //
+    // toLinear is a half-float LUT to convert the encoded values 
+    // back to linear light. If you want to skip this step, pass
+    // in NULL here.
+    //
+
+    LossyDctDecoder
+        (std::vector<char *> &rowPtrs,
+         char *packedAc,
+         char *packedDc,
+         const unsigned short *toLinear,
+         int width,
+         int height,
+         PixelType type)
+    :
+        LossyDctDecoderBase(packedAc, packedDc, toLinear, width, height)
+    {
+        _rowPtrs.push_back(rowPtrs);
+        _type.push_back(type);
+    }
+
+    virtual ~LossyDctDecoder () {}
+};
+
+
+//
+// Used to decode 3 channels of LOSSY_DCT data that
+// are grouped together and color space converted.
+//
+
+class DwaCompressor::LossyDctDecoderCsc: public LossyDctDecoderBase
+{
+  public:
+
+    //
+    // toLinear is a half-float LUT to convert the encoded values 
+    // back to linear light. If you want to skip this step, pass
+    // in NULL here.
+    //
+
+    LossyDctDecoderCsc
+        (std::vector<char *> &rowPtrsR,
+         std::vector<char *> &rowPtrsG,
+         std::vector<char *> &rowPtrsB,
+         char *packedAc,
+         char *packedDc,
+         const unsigned short *toLinear,
+         int width,
+         int height,
+         PixelType typeR,
+         PixelType typeG,
+         PixelType typeB)
+    :
+        LossyDctDecoderBase(packedAc, packedDc, toLinear, width, height)
+    {
+        _rowPtrs.push_back(rowPtrsR);
+        _rowPtrs.push_back(rowPtrsG);
+        _rowPtrs.push_back(rowPtrsB);
+        _type.push_back(typeR);
+        _type.push_back(typeG);
+        _type.push_back(typeB);
+    }
+
+    virtual ~LossyDctDecoderCsc () {}
+};
+
+
+// 
+// Base class for encoding using the lossy DCT scheme
+//
+
+class DwaCompressor::LossyDctEncoderBase
+{
+  public:
+
+    LossyDctEncoderBase
+        (float quantBaseError,
+         char *packedAc,
+         char *packedDc,
+         const unsigned short *toNonlinear,
+         int width,
+         int height);
+
+    virtual ~LossyDctEncoderBase ();
+
+    void execute ();
+
+    //
+    // These return number of items, not bytes. Each item
+    // is an unsigned short
+    //
+
+    int     numAcValuesEncoded () const {return _numAcComp;}
+    int     numDcValuesEncoded () const {return _numDcComp;}
+
+  protected:
+
+    void    toZigZag (half *dst, half *src);
+    int     countSetBits (unsigned short src);
+    half    quantize (half src, float errorTolerance);
+    void    rleAc (half *block, unsigned short *&acPtr);
+
+    float                      _quantBaseError;
+
+    int                        _width,
+                               _height;
+    const unsigned short      *_toNonlinear;
+
+    int                        _numAcComp,
+                               _numDcComp;
+
+    std::vector< std::vector<const char *> > _rowPtrs;
+    std::vector<PixelType>                   _type;
+    std::vector<SimdAlignedBuffer64f>        _dctData;
+
+
+    //
+    // Pointers to the buffers where AC and DC
+    // DCT components should be packed for 
+    // lossless compression downstream
+    //
+
+    char                      *_packedAc;
+    char                      *_packedDc;
+
+
+    //
+    // Our "quantization tables" - the example JPEG tables, 
+    // normalized so that the smallest value in each is 1.0.
+    // This gives us a relationship between error in DCT 
+    // components
+    //
+
+    float                      _quantTableY[64];
+    float                      _quantTableCbCr[64];
+};
+
+
+
+//
+// Single channel lossy DCT encoder
+//
+
+class DwaCompressor::LossyDctEncoder: public LossyDctEncoderBase
+{
+  public:
+
+    LossyDctEncoder
+        (float quantBaseError,
+         std::vector<const char *> &rowPtrs,
+         char *packedAc,
+         char *packedDc,
+         const unsigned short *toNonlinear,
+         int width,
+         int height,
+         PixelType type)
+    :
+        LossyDctEncoderBase
+            (quantBaseError, packedAc, packedDc, toNonlinear, width, height)
+    {
+        _rowPtrs.push_back(rowPtrs);
+        _type.push_back(type);
+    }
+
+    virtual ~LossyDctEncoder () {}
+};
+    
+
+//
+// RGB channel lossy DCT encoder
+//
+
+class DwaCompressor::LossyDctEncoderCsc: public LossyDctEncoderBase
+{
+  public:
+
+    LossyDctEncoderCsc
+        (float quantBaseError,
+         std::vector<const char *> &rowPtrsR,
+         std::vector<const char *> &rowPtrsG,
+         std::vector<const char *> &rowPtrsB,
+         char *packedAc,
+         char *packedDc,
+         const unsigned short *toNonlinear,
+         int width,
+         int height,
+         PixelType typeR,
+         PixelType typeG,
+         PixelType typeB)
+    :
+        LossyDctEncoderBase
+            (quantBaseError, packedAc, packedDc, toNonlinear, width, height)
+    {
+        _type.push_back(typeR);
+        _type.push_back(typeG);
+        _type.push_back(typeB);
+
+        _rowPtrs.push_back(rowPtrsR);
+        _rowPtrs.push_back(rowPtrsG);
+        _rowPtrs.push_back(rowPtrsB);
+    }
+
+    virtual ~LossyDctEncoderCsc () {}
+};
+
+
+// ==============================================================
+//
+//                     LossyDctDecoderBase
+//
+// --------------------------------------------------------------
+
+DwaCompressor::LossyDctDecoderBase::LossyDctDecoderBase
+    (char *packedAc,
+     char *packedDc,
+     const unsigned short *toLinear,
+     int width,
+     int height)
+:
+    _isNativeXdr(false),
+    _packedAcCount(0),
+    _packedDcCount(0),
+    _packedAc(packedAc),
+    _packedDc(packedDc),
+    _toLinear(toLinear),
+    _width(width),
+    _height(height)
+{
+    if (_toLinear == 0)
+        _toLinear = dwaCompressorNoOp;
+
+    _isNativeXdr = GLOBAL_SYSTEM_LITTLE_ENDIAN;
+}
+
+
+DwaCompressor::LossyDctDecoderBase::~LossyDctDecoderBase () {}
+
+
+void
+DwaCompressor::LossyDctDecoderBase::execute ()
+{
+    int numComp        = _rowPtrs.size();
+    int lastNonZero    = 0;
+    int numBlocksX     = (int) ceil ((float)_width  / 8.0f);
+    int numBlocksY     = (int) ceil ((float)_height / 8.0f);
+    int leftoverX      = _width  - (numBlocksX-1) * 8;
+    int leftoverY      = _height - (numBlocksY-1) * 8;
+
+    int numFullBlocksX = (int)floor ((float)_width / 8.0f);
+
+    unsigned short tmpShortNative = 0;
+    unsigned short tmpShortXdr    = 0;
+    const char *tmpConstCharPtr   = 0;
+
+    unsigned short                    *currAcComp = (unsigned short *)_packedAc;
+    std::vector<unsigned short *>      currDcComp (_rowPtrs.size());
+    std::vector<SimdAlignedBuffer64us> halfZigBlock (_rowPtrs.size());
+
+    if (_type.size() != _rowPtrs.size())
+        throw Iex::BaseExc ("Row pointers and types mismatch in count");
+
+    if ((_rowPtrs.size() != 3) && (_rowPtrs.size() != 1))
+        throw Iex::NoImplExc ("Only 1 and 3 channel encoding is supported");
+
+    _dctData.resize(numComp);
+
+    //
+    // Allocate a temp aligned buffer to hold a rows worth of full 
+    // 8x8 half-float blocks
+    //
+
+    unsigned char *rowBlockHandle = new unsigned char
+        [numComp * numBlocksX * 64 * sizeof(unsigned short) + _SSE_ALIGNMENT];
+
+    unsigned short *rowBlock[3];
+
+    rowBlock[0] = (unsigned short*)rowBlockHandle;
+
+    for (int i = 0; i < _SSE_ALIGNMENT; ++i)
+    {
+        if (((size_t)(rowBlockHandle + i) & _SSE_ALIGNMENT_MASK) == 0)
+            rowBlock[0] = (unsigned short *)(rowBlockHandle + i);
+    }
+
+    for (int comp = 1; comp < numComp; ++comp)
+        rowBlock[comp] = rowBlock[comp - 1] + numBlocksX * 64;
+ 
+    //
+    // Pack DC components together by common plane, so we can get 
+    // a little more out of differencing them. We'll always have 
+    // one component per block, so we can computed offsets.
+    //
+
+    currDcComp[0] = (unsigned short *)_packedDc;
+
+    for (unsigned int comp = 1; comp < numComp; ++comp)
+        currDcComp[comp] = currDcComp[comp - 1] + numBlocksX * numBlocksY;
+
+    for (int blocky = 0; blocky < numBlocksY; ++blocky)
+    {
+        int maxY = 8;
+
+        if (blocky == numBlocksY-1)
+            maxY = leftoverY;
+
+        int maxX = 8;
+
+        for (int blockx = 0; blockx < numBlocksX; ++blockx)
+        {
+            if (blockx == numBlocksX-1)
+                maxX = leftoverX;
+
+            //
+            // If we can detect that the block is constant values
+            // (all components only have DC values, and all AC is 0),
+            // we can do everything only on 1 value, instead of all
+            // 64. 
+            //
+            // This won't really help for regular images, but it is
+            // meant more for layers with large swaths of black 
+            //
+
+            bool blockIsConstant = true;
+
+            for (unsigned int comp = 0; comp < numComp; ++comp)
+            {
+
+                //
+                // DC component is stored separately
+                //
+
+                #ifdef IMF_HAVE_SSE2
+                    {
+                        __m128i *dst = (__m128i*)halfZigBlock[comp]._buffer;
+
+                        dst[7] = _mm_setzero_si128();
+                        dst[6] = _mm_setzero_si128();
+                        dst[5] = _mm_setzero_si128();
+                        dst[4] = _mm_setzero_si128();
+                        dst[3] = _mm_setzero_si128();
+                        dst[2] = _mm_setzero_si128();
+                        dst[1] = _mm_setzero_si128();
+                        dst[0] = _mm_insert_epi16
+                            (_mm_setzero_si128(), *currDcComp[comp]++, 0);
+                    }
+                #else  /* IMF_HAVE_SSE2 */
+
+                    memset (halfZigBlock[comp]._buffer, 0, 64 * 2);
+                    halfZigBlock[comp]._buffer[0] = *currDcComp[comp]++;
+
+                #endif /* IMF_HAVE_SSE2 */
+
+                _packedDcCount++;
+                
+                //
+                // UnRLE the AC. This will modify currAcComp
+                //
+
+                lastNonZero = unRleAc (currAcComp, halfZigBlock[comp]._buffer);
+
+                //
+                // Convert from XDR to NATIVE
+                //
+
+                if (!_isNativeXdr)
+                {
+                    for (int i = 0; i < 64; ++i)
+                    {
+                        tmpShortXdr      = halfZigBlock[comp]._buffer[i];
+                        tmpConstCharPtr  = (const char *)&tmpShortXdr;
+
+                        Xdr::read<CharPtrIO> (tmpConstCharPtr, tmpShortNative);
+
+                        halfZigBlock[comp]._buffer[i] = tmpShortNative;
+                    }
+                }
+
+                if (lastNonZero == 0)
+                {
+                    //
+                    // DC only case - AC components are all 0   
+                    //
+
+                    half h;
+
+                    h.setBits (halfZigBlock[comp]._buffer[0]);
+                    _dctData[comp]._buffer[0] = (float)h;
+
+                    dctInverse8x8DcOnly (_dctData[comp]._buffer);
+                }
+                else
+                {
+                    //
+                    // We have some AC components that are non-zero. 
+                    // Can't use the 'constant block' optimization
+                    //
+
+                    blockIsConstant = false;
+
+                    //
+                    // Un-Zig zag 
+                    //
+
+                    (*fromHalfZigZag)
+                        (halfZigBlock[comp]._buffer, _dctData[comp]._buffer);
+
+                    //
+                    // Zig-Zag indices in normal layout are as follows:
+                    //
+                    // 0   1   3   6   10  15  21  28
+                    // 2   4   7   11  16  22  29  36
+                    // 5   8   12  17  23  30  37  43
+                    // 9   13  18  24  31  38  44  49
+                    // 14  19  25  32  39  45  50  54
+                    // 20  26  33  40  46  51  55  58
+                    // 27  34  41  47  52  56  59  61
+                    // 35  42  48  53  57  60  62  63
+                    //
+                    // If lastNonZero is less than the first item on
+                    // each row, we know that the whole row is zero and 
+                    // can be skipped in the row-oriented part of the
+                    // iDCT. 
+                    //
+                    // The unrolled logic here is:
+                    //
+                    //    if lastNonZero < rowStartIdx[i],
+                    //    zeroedRows = rowsEmpty[i]
+                    //
+                    // where:
+                    //
+                    //    const int rowStartIdx[] = {2, 5, 9, 14, 20, 27, 35};
+                    //    const int rowsEmpty[]   = {7, 6, 5,  4,  3,  2,  1};
+                    //
+
+                    if (lastNonZero < 2)
+                        dctInverse8x8_7(_dctData[comp]._buffer);
+                    else if (lastNonZero < 5)
+                        dctInverse8x8_6(_dctData[comp]._buffer);
+                    else if (lastNonZero < 9)
+                        dctInverse8x8_5(_dctData[comp]._buffer);
+                    else if (lastNonZero < 14)
+                        dctInverse8x8_4(_dctData[comp]._buffer);
+                    else if (lastNonZero < 20)
+                        dctInverse8x8_3(_dctData[comp]._buffer);
+                    else if (lastNonZero < 27)
+                        dctInverse8x8_2(_dctData[comp]._buffer);
+                    else if (lastNonZero < 35)
+                        dctInverse8x8_1(_dctData[comp]._buffer);
+                    else
+                        dctInverse8x8_0(_dctData[comp]._buffer);
+                }
+            }
+
+            //
+            // Perform the CSC
+            //
+
+            if (numComp == 3)
+            {
+                if (!blockIsConstant)
+                {
+                    csc709Inverse64 (_dctData[0]._buffer, 
+                                     _dctData[1]._buffer, 
+                                     _dctData[2]._buffer);
+
+                }
+                else
+                {
+                    csc709Inverse (_dctData[0]._buffer[0], 
+                                   _dctData[1]._buffer[0], 
+                                   _dctData[2]._buffer[0]);
+                }
+            }
+
+            //
+            // Float -> Half conversion. 
+            //
+            // If the block has a constant value, just convert the first pixel.
+            //
+
+            for (unsigned int comp = 0; comp < numComp; ++comp)
+            {
+                if (!blockIsConstant)
+                {
+                    (*convertFloatToHalf64)
+                        (&rowBlock[comp][blockx*64], _dctData[comp]._buffer);
+                }
+                else
+                {
+                    #if IMF_HAVE_SSE2
+
+                        __m128i *dst = (__m128i*)&rowBlock[comp][blockx*64];
+
+                        dst[0] = _mm_set1_epi16
+                            (((half)_dctData[comp]._buffer[0]).bits());
+
+                        dst[1] = dst[0];
+                        dst[2] = dst[0];
+                        dst[3] = dst[0];
+                        dst[4] = dst[0];
+                        dst[5] = dst[0];
+                        dst[6] = dst[0];
+                        dst[7] = dst[0];
+
+                    #else  /* IMF_HAVE_SSE2 */
+
+                        unsigned short *dst = &rowBlock[comp][blockx*64];
+
+                        dst[0] = ((half)_dctData[comp]._buffer[0]).bits();
+
+                        for (int i = 1; i < 64; ++i)
+                        {
+                            dst[i] = dst[0];
+                        }
+
+                    #endif /* IMF_HAVE_SSE2 */
+                } // blockIsConstant
+            } // comp
+        } // blockx
+
+        //
+        // At this point, we have half-float nonlinear value blocked
+        // in rowBlock[][]. We need to unblock the data, transfer
+        // back to linear, and write the results in the _rowPtrs[].
+        //
+        // There is a fast-path for aligned rows, which helps
+        // things a little. Since this fast path is only valid
+        // for full 8-element wide blocks, the partial x blocks
+        // are broken into a separate loop below.
+        //
+        // At the moment, the fast path requires:
+        //   * sse support
+        //   * aligned row pointers
+        //   * full 8-element wide blocks
+        //
+
+        for (int comp = 0; comp < numComp; ++comp)
+        {
+            //
+            // Test if we can use the fast path
+            //
+
+        #ifdef IMF_HAVE_SSE2
+
+            bool fastPath = true;
+
+            for (int y = 8 * blocky; y < 8 * blocky + maxY; ++y)
+            {
+                if ((size_t)_rowPtrs[comp][y] & _SSE_ALIGNMENT_MASK)
+                    fastPath = false;
+            }
+
+            if (fastPath)
+            {
+                //
+                // Handle all the full X blocks, in a fast path with sse2 and
+                // aligned row pointers
+                //
+
+                for (int y=8*blocky; y<8*blocky+maxY; ++y)
+                {
+                    __m128i *dst = (__m128i *)_rowPtrs[comp][y];
+                    __m128i *src = (__m128i *)&rowBlock[comp][(y & 0x7) * 8];
+
+
+                    for (int blockx = 0; blockx < numFullBlocksX; ++blockx)
+                    {
+                        //
+                        // These may need some twiddling.
+                        // Run with multiples of 8
+                        //
+
+                        _mm_prefetch ((char *)(src + 16), _MM_HINT_NTA); 
+
+                        unsigned short i0  = _mm_extract_epi16 (*src, 0);
+                        unsigned short i1  = _mm_extract_epi16 (*src, 1);
+                        unsigned short i2  = _mm_extract_epi16 (*src, 2);
+                        unsigned short i3  = _mm_extract_epi16 (*src, 3);
+
+                        unsigned short i4  = _mm_extract_epi16 (*src, 4);
+                        unsigned short i5  = _mm_extract_epi16 (*src, 5);
+                        unsigned short i6  = _mm_extract_epi16 (*src, 6);
+                        unsigned short i7  = _mm_extract_epi16 (*src, 7);
+
+                        i0 = _toLinear[i0];
+                        i1 = _toLinear[i1];
+                        i2 = _toLinear[i2];
+                        i3 = _toLinear[i3];
+
+                        i4 = _toLinear[i4];
+                        i5 = _toLinear[i5];
+                        i6 = _toLinear[i6];
+                        i7 = _toLinear[i7];
+
+                        *dst = _mm_insert_epi16 (_mm_setzero_si128(), i0, 0);
+                        *dst = _mm_insert_epi16 (*dst, i1, 1);
+                        *dst = _mm_insert_epi16 (*dst, i2, 2);
+                        *dst = _mm_insert_epi16 (*dst, i3, 3);
+
+                        *dst = _mm_insert_epi16 (*dst, i4, 4);
+                        *dst = _mm_insert_epi16 (*dst, i5, 5);
+                        *dst = _mm_insert_epi16 (*dst, i6, 6);
+                        *dst = _mm_insert_epi16 (*dst, i7, 7);
+
+                        src += 8;
+                        dst++;
+                    }
+                }
+            }
+            else
+            {
+
+        #endif /* IMF_HAVE_SSE2 */
+
+                //
+                // Basic scalar kinda slow path for handling the full X blocks
+                //
+
+                for (int y = 8 * blocky; y < 8 * blocky + maxY; ++y)
+                {
+                    unsigned short *dst = (unsigned short *)_rowPtrs[comp][y];
+
+                    for (int blockx = 0; blockx < numFullBlocksX; ++blockx)
+                    {
+                        unsigned short *src =
+                            &rowBlock[comp][blockx * 64 + ((y & 0x7) * 8)];
+
+                        dst[0] = _toLinear[src[0]];
+                        dst[1] = _toLinear[src[1]];
+                        dst[2] = _toLinear[src[2]];
+                        dst[3] = _toLinear[src[3]];
+
+                        dst[4] = _toLinear[src[4]];
+                        dst[5] = _toLinear[src[5]];
+                        dst[6] = _toLinear[src[6]];
+                        dst[7] = _toLinear[src[7]];
+
+                        dst += 8;
+                    }
+                }
+
+        #ifdef IMF_HAVE_SSE2
+
+            }
+
+        #endif /* IMF_HAVE_SSE2 */
+
+            //
+            // If we have partial X blocks, deal with all those now
+            // Since this should be minimal work, there currently
+            // is only one path that should work for everyone.
+            //
+
+            if (numFullBlocksX != numBlocksX)
+            {
+                for (int y = 8 * blocky; y < 8 * blocky + maxY; ++y)
+                {
+                    unsigned short *src = (unsigned short *)
+                        &rowBlock[comp][numFullBlocksX * 64 + ((y & 0x7) * 8)];
+
+                    unsigned short *dst = (unsigned short *)_rowPtrs[comp][y];
+
+                    dst += 8 * numFullBlocksX;
+
+                    for (int x = 0; x < maxX; ++x)
+                    {
+                        *dst++ = _toLinear[*src++];
+                    }
+                }
+            }
+        } // comp
+    } // blocky
+
+    //
+    // Walk over all the channels that are of type FLOAT.
+    // Convert from HALF XDR back to FLOAT XDR.
+    //
+
+    for (unsigned int chan = 0; chan < numComp; ++chan)
+    {
+
+        if (_type[chan] != FLOAT)
+            continue;
+
+        std::vector<unsigned short> halfXdr (_width);
+
+        for (int y=0; y<_height; ++y)
+        {
+            char *floatXdrPtr = _rowPtrs[chan][y];
+
+            memcpy(&halfXdr[0], floatXdrPtr, _width*sizeof(unsigned short));
+
+            const char *halfXdrPtr = (const char *)(&halfXdr[0]);
+
+            for (int x=0; x<_width; ++x)
+            {
+                half tmpHalf;
+
+                Xdr::read<CharPtrIO> (halfXdrPtr, tmpHalf);
+                Xdr::write<CharPtrIO> (floatXdrPtr, (float)tmpHalf);
+
+                // 
+                // Xdr::write and Xdr::read will advance the ptrs
+                //
+            }
+        }
+    }
+
+    delete[] rowBlockHandle;
+}
+
+
+//
+// Un-RLE the packed AC components into 
+// a half buffer. The half block should 
+// be the full 8x8 block (in zig-zag order
+// still), not the first AC component. 
+//
+// currAcComp is advanced as bytes are decoded.
+//
+// This returns the index of the last non-zero
+// value in the buffer - with the index into zig zag
+// order data. If we return 0, we have DC only data.
+// 
+// This is assuminging that halfZigBlock is zero'ed
+// prior to calling
+//
+
+int 
+DwaCompressor::LossyDctDecoderBase::unRleAc
+    (unsigned short *&currAcComp,
+     unsigned short  *halfZigBlock) 
+{
+    //
+    // Un-RLE the RLE'd blocks. If we find an item whose
+    // high byte is 0xff, then insert the number of 0's
+    // as indicated by the low byte.
+    //
+    // Otherwise, just copy the number verbaitm.
+    //
+
+    int lastNonZero          = 0;
+    int dctComp              = 1; 
+
+    //
+    // Start with a zero'ed block, so we don't have to
+    // write when we hit a run symbol
+    //
+
+    while (dctComp < 64)
+    {
+        if (*currAcComp == 0xff00)
+        {
+            // 
+            // End of block
+            //
+
+            dctComp = 64;
+
+        }
+        else if ((*currAcComp) >> 8 == 0xff)
+        {
+            //
+            // Run detected! Insert 0's.
+            //
+            // Since the block has been zeroed, just advance the ptr
+            // 
+
+            dctComp += (*currAcComp) & 0xff; 
+        }
+        else
+        {
+            // 
+            // Not a run, just copy over the value
+            //
+
+            lastNonZero = dctComp;
+            halfZigBlock[dctComp] = *currAcComp;
+
+            dctComp++;
+        }
+
+        _packedAcCount++;
+        currAcComp++;
+    }
+
+    return lastNonZero;
+}
+
+
+// ==============================================================
+//
+//                     LossyDctEncoderBase
+//
+// --------------------------------------------------------------
+
+DwaCompressor::LossyDctEncoderBase::LossyDctEncoderBase
+    (float quantBaseError,
+     char *packedAc,
+     char *packedDc,
+     const unsigned short *toNonlinear,
+     int width,
+     int height)
+:
+    _quantBaseError(quantBaseError),
+    _width(width),
+    _height(height),
+    _toNonlinear(toNonlinear),
+    _numAcComp(0),
+    _numDcComp(0),
+    _packedAc(packedAc),
+    _packedDc(packedDc)
+{
+    //
+    // Here, we take the generic JPEG quantization tables and
+    // normalize them by the smallest component in each table.
+    // This gives us a relationship amongst the DCT components,
+    // in terms of how sensitive each component is to
+    // error.
+    //
+    // A higher normalized value means we can quantize more,
+    // and a small normalized value means we can quantize less.
+    //
+    // Eventually, we will want an acceptable quantization
+    // error range for each component. We find this by
+    // multiplying some user-specified level (_quantBaseError)
+    // by the normalized table (_quantTableY, _quantTableCbCr) to
+    // find the acceptable quantization error range.
+    //
+    // The quantization table is not needed for decoding, and
+    // is not transmitted. So, if you want to get really fancy,
+    // you could derive some content-dependent quantization
+    // table, and the decoder would not need to be changed. But,
+    // for now, we'll just use statice quantization tables.
+    //
+
+    int jpegQuantTableY[] =
+    {
+        16,  11,  10,  16,   24,   40,   51,   61,
+        12,  12,  14,  19,   26,   58,   60,   55,
+        14,  13,  16,  24,   40,   57,   69,   56,
+        14,  17,  22,  29,   51,   87,   80,   62,
+        18,  22,  37,  56,   68,  109,  103,   77,
+        24,  35,  55,  64,   81,  104,  113,   92,
+        49,  64,  78,  87,  103,  121,  120,  101,
+        72,  92,  95,  98,  112,  100,  103,   99
+    };
+
+    int jpegQuantTableYMin = 10;
+
+    int jpegQuantTableCbCr[] =
+    {
+        17,  18,  24,  47,  99,  99,  99,  99,
+        18,  21,  26,  66,  99,  99,  99,  99,
+        24,  26,  56,  99,  99,  99,  99,  99,
+        47,  66,  99,  99,  99,  99,  99,  99,
+        99,  99,  99,  99,  99,  99,  99,  99,
+        99,  99,  99,  99,  99,  99,  99,  99,
+        99,  99,  99,  99,  99,  99,  99,  99,
+        99,  99,  99,  99,  99,  99,  99,  99
+    };
+
+    int jpegQuantTableCbCrMin = 17;
+
+    for (int idx = 0; idx < 64; ++idx)
+    {
+        _quantTableY[idx] = static_cast<float> (jpegQuantTableY[idx]) /
+                            static_cast<float> (jpegQuantTableYMin);
+
+        _quantTableCbCr[idx] = static_cast<float> (jpegQuantTableCbCr[idx]) /
+                               static_cast<float> (jpegQuantTableCbCrMin);
+    }
+    
+    if (_quantBaseError < 0)
+        quantBaseError = 0;
+}
+
+
+DwaCompressor::LossyDctEncoderBase::~LossyDctEncoderBase () 
+{
+}
+
+
+//
+// Given three channels of source data, encoding by first applying
+// a color space conversion to a YCbCr space.  Otherwise, if we only
+// have one channel, just encode it as is. 
+//
+// Other numbers of channels are somewhat unexpected at this point,
+// and will throw an exception.
+//
+
+void
+DwaCompressor::LossyDctEncoderBase::execute ()
+{
+    int  numBlocksX   = (int)ceil ((float)_width / 8.0f);
+    int  numBlocksY   = (int)ceil ((float)_height/ 8.0f);
+
+    half halfZigCoef[64]; 
+    half halfCoef[64];
+
+    std::vector<unsigned short *> currDcComp (_rowPtrs.size());
+    unsigned short               *currAcComp = (unsigned short *)_packedAc;
+
+    _dctData.resize (_rowPtrs.size());
+    _numAcComp = 0;
+    _numDcComp = 0;
+ 
+    assert (_type.size() == _rowPtrs.size());
+    assert ((_rowPtrs.size() == 3) || (_rowPtrs.size() == 1));
+
+    // 
+    // Allocate a temp half buffer to quantize into for
+    // any FLOAT source channels.
+    //
+
+    int tmpHalfBufferElements = 0;
+
+    for (unsigned int chan = 0; chan < _rowPtrs.size(); ++chan)
+        if (_type[chan] == FLOAT)
+            tmpHalfBufferElements += _width * _height;
+
+    std::vector<unsigned short> tmpHalfBuffer (tmpHalfBufferElements);
+
+    char *tmpHalfBufferPtr = 0;
+
+    if (tmpHalfBufferElements)
+        tmpHalfBufferPtr = (char *)&tmpHalfBuffer[0];
+
+    //
+    // Run over all the float scanlines, quantizing, 
+    // and re-assigning _rowPtr[y]. We need to translate
+    // FLOAT XDR to HALF XDR.
+    //
+
+    for (unsigned int chan = 0; chan < _rowPtrs.size(); ++chan)
+    {
+        if (_type[chan] != FLOAT)
+            continue;
+    
+        for (int y = 0; y < _height; ++y)
+        {
+            float       src = 0;
+            const char *srcXdr = _rowPtrs[chan][y];
+            char       *dstXdr = tmpHalfBufferPtr;
+           
+            for (int x = 0; x < _width; ++x)
+            {
+
+                Xdr::read<CharPtrIO> (srcXdr, src);
+                Xdr::write<CharPtrIO> (dstXdr, ((half)src).bits());
+
+                //
+                // Xdr::read and Xdr::write will advance the ptr
+                //
+            }
+
+            _rowPtrs[chan][y] = (const char *)tmpHalfBufferPtr;
+            tmpHalfBufferPtr += _width * sizeof (unsigned short);
+        }
+    }
+
+    //
+    // Pack DC components together by common plane, so we can get 
+    // a little more out of differencing them. We'll always have 
+    // one component per block, so we can computed offsets.
+    //
+
+    currDcComp[0] = (unsigned short *)_packedDc;
+
+    for (unsigned int chan = 1; chan < _rowPtrs.size(); ++chan)
+        currDcComp[chan] = currDcComp[chan-1] + numBlocksX * numBlocksY;
+
+    for (int blocky = 0; blocky < numBlocksY; ++blocky)
+    {
+        for (int blockx = 0; blockx < numBlocksX; ++blockx)
+        {
+            half           h;
+            unsigned short tmpShortXdr, tmpShortNative;
+            char          *tmpCharPtr;
+
+            for (unsigned int chan = 0; chan < _rowPtrs.size(); ++chan)
+            {
+                //
+                // Break the source into 8x8 blocks. If we don't
+                // fit at the edges, mirror.
+                //
+                // Also, convert from linear to nonlinear representation.
+                // Our source is assumed to be XDR, and we need to convert
+                // to NATIVE prior to converting to float.
+                //
+                // If we're converting linear -> nonlinear, assume that the
+                // XDR -> NATIVE conversion is built into the lookup. Otherwise,
+                // we'll need to explicitly do it.
+                //
+
+                for (int y = 0; y < 8; ++y)
+                {
+                    for (int x = 0; x < 8; ++x)
+                    {
+                        int vx = 8 * blockx + x;
+                        int vy = 8 * blocky + y;
+
+                        if (vx >= _width)
+                            vx = _width - (vx - (_width - 1));
+                        
+                        if (vx < 0) vx = _width-1;
+
+                        if (vy >=_height)
+                            vy = _height - (vy - (_height - 1));
+
+                        if (vy < 0) vy = _height-1;
+                    
+                        tmpShortXdr =
+                            ((const unsigned short *)(_rowPtrs[chan])[vy])[vx];
+
+                        if (_toNonlinear)
+                        {
+                            h.setBits (_toNonlinear[tmpShortXdr]);
+                        }
+                        else
+                        {
+                            const char *tmpConstCharPtr =
+                                (const char *)(&tmpShortXdr);
+
+                            Xdr::read<CharPtrIO>
+                                (tmpConstCharPtr, tmpShortNative);
+
+                            h.setBits(tmpShortNative);
+                        }
+
+                        _dctData[chan]._buffer[y * 8 + x] = (float)h;
+                    } // x
+                } // y
+            } // chan
+
+            //
+            // Color space conversion
+            //
+
+            if (_rowPtrs.size() == 3)
+            {
+                csc709Forward64 (_dctData[0]._buffer, 
+                                 _dctData[1]._buffer, 
+                                 _dctData[2]._buffer);
+            }
+
+            for (unsigned int chan = 0; chan < _rowPtrs.size(); ++chan)
+            {
+                //
+                // Forward DCT
+                //
+
+                dctForward8x8(_dctData[chan]._buffer);
+
+                //
+                // Quantize to half, and zigzag
+                //
+
+                if (chan == 0)
+                {
+                    for (int i = 0; i < 64; ++i)
+                    {
+                        halfCoef[i] =
+                            quantize ((half)_dctData[chan]._buffer[i],
+                                      _quantBaseError*_quantTableY[i]);
+                    }
+                }
+                else
+                {
+                    for (int i = 0; i < 64; ++i)
+                    {
+                        halfCoef[i] =
+                            quantize ((half)_dctData[chan]._buffer[i],
+                                      _quantBaseError*_quantTableCbCr[i]);
+                    }
+                }
+
+                toZigZag (halfZigCoef, halfCoef);
+                
+                //
+                // Convert from NATIVE back to XDR, before we write out
+                //
+
+                for (int i = 0; i < 64; ++i)
+                {
+                    tmpCharPtr = (char *)&tmpShortXdr;
+                    Xdr::write<CharPtrIO>(tmpCharPtr, halfZigCoef[i].bits());
+                    halfZigCoef[i].setBits(tmpShortXdr);
+                }
+
+                //
+                // Save the DC component separately, to be compressed on
+                // its own.
+                //
+
+                *currDcComp[chan]++ = halfZigCoef[0].bits();
+                _numDcComp++;
+                
+                //
+                // Then RLE the AC components (which will record the count
+                // of the resulting number of items)
+                //
+
+                rleAc (halfZigCoef, currAcComp);
+            } // chan
+        } // blockx
+    } // blocky              
+}
+
+
+// 
+// Reorder from zig-zag order to normal ordering
+//
+
+void 
+DwaCompressor::LossyDctEncoderBase::toZigZag (half *dst, half *src) 
+{
+    const int remap[] =
+    {
+         0, 
+         1,  8,
+        16,  9,  2,
+         3, 10, 17, 24,
+        32, 25, 18, 11, 4,
+         5, 12, 19, 26, 33, 40,
+        48, 41, 34, 27, 20, 13, 6,
+         7, 14, 21, 28, 35, 42, 49, 56,
+            57, 50, 43, 36, 29, 22, 15,
+                23, 30, 37, 44, 51, 58,
+                    59, 52, 45, 38, 31,
+                        39, 46, 53, 60,
+                            61, 54, 47,
+                                55, 62,
+                                    63
+    };
+
+    for (int i=0; i<64; ++i)
+        dst[i] = src[remap[i]];
+}
+
+
+//
+// Precomputing the bit count runs faster than using
+// the builtin instruction, at least in one case..
+//
+// Precomputing 8-bits is no slower than 16-bits,
+// and saves a fair bit of overhead..
+//
+
+int
+DwaCompressor::LossyDctEncoderBase::countSetBits (unsigned short src)
+{
+    static const unsigned short numBitsSet[256] =
+    {
+        0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
+        1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+        1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+        1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+        3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+        1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+        3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+        3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+        3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+        4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
+    };
+
+    return numBitsSet[src & 0xff] + numBitsSet[src >> 8];
+}
+
+
+//
+// Take a DCT coefficient, as well as an acceptable error. Search
+// nearby values within the error tolerance, that have fewer 
+// bits set.
+//
+// The list of candidates has been pre-computed and sorted 
+// in order of increasing numbers of bits set. This way, we
+// can stop searching as soon as we find a candidate that
+// is within the error tolerance.
+//
+
+half
+DwaCompressor::LossyDctEncoderBase::quantize (half src, float errorTolerance)
+{
+    half            tmp;
+    float           srcFloat      = (float)src;
+    int             numSetBits    = countSetBits(src.bits());
+    const unsigned short *closest = closestData + closestDataOffset[src.bits()];
+
+    for (int targetNumSetBits = numSetBits - 1;
+         targetNumSetBits >= 0;
+         --targetNumSetBits)
+    {
+        tmp.setBits (*closest);
+
+        if (fabs ((float)tmp - srcFloat) < errorTolerance)
+            return tmp;
+
+        closest++;
+    }
+
+    return src;
+}
+
+
+//
+// RLE the zig-zag of the AC components + copy over 
+// into another tmp buffer
+//
+// Try to do a simple RLE scheme to reduce run's of 0's. This
+// differs from the jpeg EOB case, since EOB just indicates that
+// the rest of the block is zero. In our case, we have lots of
+// NaN symbols, which shouldn't be allowed to occur in DCT 
+// coefficents - so we'll use them for encoding runs.
+//
+// If the high byte is 0xff, then we have a run of 0's, of length
+// given by the low byte. For example, 0xff03 would be a run
+// of 3 0's, starting at the current location.
+//
+// block is our block of 64 coefficients
+// acPtr a pointer to back the RLE'd values into.
+//
+// This will advance the counter, _numAcComp.
+//
+
+void
+DwaCompressor::LossyDctEncoderBase::rleAc
+    (half *block,
+     unsigned short *&acPtr)
+{
+    int dctComp              = 1; 
+    unsigned short rleSymbol = 0x0;
+
+    while (dctComp < 64)
+    {
+        int runLen = 1;
+    
+        //
+        // If we don't have a 0, output verbatim
+        //
+
+        if (block[dctComp].bits() != rleSymbol)
+        {
+            *acPtr++ =  block[dctComp].bits();
+            _numAcComp++;
+
+            dctComp += runLen;
+            continue;
+        }
+
+        //
+        // We're sitting on a 0, so see how big the run is.
+        //
+
+        while ((dctComp+runLen < 64) && 
+               (block[dctComp+runLen].bits() == rleSymbol))
+        {
+            runLen++;
+        }
+
+        //
+        // If the run len is too small, just output verbatim
+        // otherwise output our run token
+        //
+        // Originally, we wouldn't have a separate symbol for
+        // "end of block". But in some experimentation, it looks
+        // like using 0xff00 for "end of block" can save a bit
+        // of space. 
+        //
+
+        if (runLen == 1)
+        {
+            runLen           = 1;
+            *acPtr++ = block[dctComp].bits();
+            _numAcComp++;
+
+            //
+            // Using 0xff00 for "end of block"
+            //
+        }
+        else if (runLen + dctComp == 64)
+        {
+            //
+            // Signal EOB
+            //
+
+            *acPtr++ = 0xff00;
+            _numAcComp++;
+        }
+        else
+        {
+            // 
+            // Signal normal run
+            //
+
+            *acPtr++   = 0xff00 | runLen;
+            _numAcComp++;
+        }
+
+        //
+        // Advance by runLen
+        //
+
+        dctComp += runLen;
+    }
+}
+
+
+// ==============================================================
+//
+//                     DwaCompressor
+//
+// --------------------------------------------------------------
+
+// 
+// DwaCompressor()
+//
+
+DwaCompressor::DwaCompressor
+    (const Header &hdr,
+     int maxScanLineSize,
+     int numScanLines,
+     AcCompression acCompression)
+:
+    Compressor(hdr),
+    _acCompression(acCompression),
+    _maxScanLineSize(maxScanLineSize),
+    _numScanLines(numScanLines),
+    _channels(hdr.channels()),
+    _packedAcBuffer(0),
+    _packedAcBufferSize(0),
+    _packedDcBuffer(0),
+    _packedDcBufferSize(0),
+    _rleBuffer(0),
+    _rleBufferSize(0),
+    _outBuffer(0),
+    _outBufferSize(0),
+    _zip(0),
+    _dwaCompressionLevel(45.0)
+{
+    _min[0] = hdr.dataWindow().min.x;
+    _min[1] = hdr.dataWindow().min.y;
+    _max[0] = hdr.dataWindow().max.x;
+    _max[1] = hdr.dataWindow().max.y;
+
+    for (int i=0; i < NUM_COMPRESSOR_SCHEMES; ++i) 
+    {
+        _planarUncBuffer[i] = 0;
+        _planarUncBufferSize[i] = 0;
+    }
+    
+    //
+    // Check the header for a quality attribute
+    //
+
+    if (hasDwaCompressionLevel (hdr))
+        _dwaCompressionLevel = dwaCompressionLevel (hdr);
+}
+
+
+DwaCompressor::~DwaCompressor()
+{
+    delete[] _packedAcBuffer;
+    delete[] _packedDcBuffer;
+    delete[] _rleBuffer;
+    delete[] _outBuffer;
+    delete _zip;
+
+    for (int i=0; i<NUM_COMPRESSOR_SCHEMES; ++i)
+        delete[] _planarUncBuffer[i];
+}
+
+
+int
+DwaCompressor::numScanLines() const
+{
+    return _numScanLines;
+}
+
+
+Imf::Compressor::Format 
+DwaCompressor::format() const
+{
+    if (GLOBAL_SYSTEM_LITTLE_ENDIAN)
+        return NATIVE;
+    else
+        return XDR;
+}
+
+
+int
+DwaCompressor::compress
+    (const char *inPtr,
+     int inSize,
+     int minY,
+     const char *&outPtr)
+{
+    return compress
+        (inPtr,
+         inSize, 
+         Imath::Box2i (Imath::V2i (_min[0], minY),
+                       Imath::V2i (_max[0], minY + numScanLines() - 1)),
+         outPtr);
+}
+
+
+int
+DwaCompressor::compressTile
+    (const char *inPtr,
+     int inSize,
+     Imath::Box2i range,
+     const char *&outPtr)
+{
+    return compress (inPtr, inSize, range, outPtr);
+}
+
+
+int 
+DwaCompressor::compress
+    (const char *inPtr,
+     int inSize,
+     Imath::Box2i range,
+     const char  *&outPtr)
+{
+    const char *inDataPtr   = inPtr;
+    char       *packedAcEnd = 0;
+    char       *packedDcEnd = 0; 
+    int         fileVersion = 2;   // Starting with 2, we write the channel
+                                   // classification rules into the file
+
+    if (fileVersion < 2) 
+        initializeLegacyChannelRules();
+    else 
+        initializeDefaultChannelRules();
+
+    size_t outBufferSize = 0;
+    initializeBuffers(outBufferSize);
+
+    unsigned short          channelRuleSize = 0;
+    std::vector<Classifier> channelRules;
+    if (fileVersion >= 2) 
+    {
+        relevantChannelRules(channelRules);
+
+        channelRuleSize = Xdr::size<unsigned short>();
+        for (size_t i = 0; i < channelRules.size(); ++i) 
+            channelRuleSize += channelRules[i].size();
+    }
+
+    //
+    // Remember to allocate _outBuffer, if we haven't done so already.
+    //
+
+    outBufferSize += channelRuleSize;
+    if (outBufferSize > _outBufferSize) 
+    {
+        _outBufferSize = outBufferSize;
+        if (_outBuffer == 0)
+            delete[] _outBuffer;       
+        _outBuffer = new char[outBufferSize];
+    }
+
+    char *outDataPtr = &_outBuffer[NUM_SIZES_SINGLE * sizeof(Imf::Int64) +
+                                   channelRuleSize];
+
+    //
+    // We might not be dealing with any color data, in which
+    // case the AC buffer size will be 0, and deferencing
+    // a vector will not be a good thing to do.
+    //
+
+    if (_packedAcBuffer)
+        packedAcEnd = _packedAcBuffer;
+
+    if (_packedDcBuffer)
+        packedDcEnd = _packedDcBuffer;
+
+    #define OBIDX(x) (Int64 *)&_outBuffer[x * sizeof (Int64)]
+
+    Int64 *version                 = OBIDX (VERSION);
+    Int64 *unknownUncompressedSize = OBIDX (UNKNOWN_UNCOMPRESSED_SIZE);
+    Int64 *unknownCompressedSize   = OBIDX (UNKNOWN_COMPRESSED_SIZE);
+    Int64 *acCompressedSize        = OBIDX (AC_COMPRESSED_SIZE);
+    Int64 *dcCompressedSize        = OBIDX (DC_COMPRESSED_SIZE);
+    Int64 *rleCompressedSize       = OBIDX (RLE_COMPRESSED_SIZE);
+    Int64 *rleUncompressedSize     = OBIDX (RLE_UNCOMPRESSED_SIZE);
+    Int64 *rleRawSize              = OBIDX (RLE_RAW_SIZE);
+
+    Int64 *totalAcUncompressedCount = OBIDX (AC_UNCOMPRESSED_COUNT);
+    Int64 *totalDcUncompressedCount = OBIDX (DC_UNCOMPRESSED_COUNT);
+
+    Int64 *acCompression            = OBIDX (AC_COMPRESSION);
+
+    int minX   = range.min.x;
+    int maxX   = std::min(range.max.x, _max[0]);
+    int minY   = range.min.y;
+    int maxY   = std::min(range.max.y, _max[1]);
+
+    //
+    // Zero all the numbers in the chunk header
+    //
+
+    memset (_outBuffer, 0, NUM_SIZES_SINGLE * sizeof (Int64));
+
+    //
+    // Setup the AC compression strategy and the version in the data block,
+    // then write the relevant channel classification rules if needed
+    //
+    *version       = fileVersion;  
+    *acCompression = _acCompression;
+
+    setupChannelData (minX, minY, maxX, maxY);
+
+    if (fileVersion >= 2) 
+    {
+        char *writePtr = &_outBuffer[NUM_SIZES_SINGLE * sizeof(Imf::Int64)];
+        Xdr::write<CharPtrIO> (writePtr, channelRuleSize);
+        
+        for (size_t i = 0; i < channelRules.size(); ++i) 
+            channelRules[i].write(writePtr);
+    }
+
+    //
+    // Determine the start of each row in the input buffer
+    // Channels are interleaved by scanline
+    //
+
+    std::vector<bool> encodedChannels (_channelData.size());
+    std::vector< std::vector<const char *> > rowPtrs (_channelData.size());
+
+    for (unsigned int chan = 0; chan < _channelData.size(); ++chan)
+        encodedChannels[chan] = false;
+
+    inDataPtr =  inPtr;
+
+    for (int y = minY; y <= maxY; ++y)
+    {
+        for (unsigned int chan = 0; chan < _channelData.size(); ++chan)
+        {
+
+            ChannelData *cd = &_channelData[chan];
+
+            if (Imath::modp(y, cd->ySampling) != 0)
+                continue;
+
+            rowPtrs[chan].push_back(inDataPtr);
+            inDataPtr += cd->width * Imf::pixelTypeSize(cd->type);
+        }
+    }
+
+    inDataPtr = inPtr;
+
+    // 
+    // Make a pass over all our CSC sets and try to encode them first
+    // 
+
+    for (unsigned int csc = 0; csc < _cscSets.size(); ++csc)
+    {
+
+        LossyDctEncoderCsc encoder
+            (_dwaCompressionLevel / 100000.f,
+             rowPtrs[_cscSets[csc].idx[0]],
+             rowPtrs[_cscSets[csc].idx[1]],
+             rowPtrs[_cscSets[csc].idx[2]],
+             packedAcEnd,
+             packedDcEnd,
+             dwaCompressorToNonlinear,
+             _channelData[_cscSets[csc].idx[0]].width,
+             _channelData[_cscSets[csc].idx[0]].height,
+             _channelData[_cscSets[csc].idx[0]].type,
+             _channelData[_cscSets[csc].idx[1]].type,
+             _channelData[_cscSets[csc].idx[2]].type);
+
+        encoder.execute();
+
+        *totalAcUncompressedCount  += encoder.numAcValuesEncoded();
+        *totalDcUncompressedCount  += encoder.numDcValuesEncoded();
+
+        packedAcEnd += encoder.numAcValuesEncoded() * sizeof(unsigned short);
+        packedDcEnd += encoder.numDcValuesEncoded() * sizeof(unsigned short);
+
+        encodedChannels[_cscSets[csc].idx[0]] = true;
+        encodedChannels[_cscSets[csc].idx[1]] = true;
+        encodedChannels[_cscSets[csc].idx[2]] = true;
+    }
+
+    for (unsigned int chan = 0; chan < _channelData.size(); ++chan)
+    {
+        ChannelData *cd = &_channelData[chan];
+
+        if (encodedChannels[chan])
+            continue;
+
+        switch (cd->compression)
+        {
+          case LOSSY_DCT:
+
+            //
+            // For LOSSY_DCT, treat this just like the CSC'd case,
+            // but only operate on one channel
+            //
+
+            {
+                const unsigned short *nonlinearLut = 0;
+
+                if (!cd->pLinear)
+                    nonlinearLut = dwaCompressorToNonlinear; 
+
+                LossyDctEncoder encoder
+                    (_dwaCompressionLevel / 100000.f,
+                     rowPtrs[chan],
+                     packedAcEnd,
+                     packedDcEnd,
+                     nonlinearLut,
+                     cd->width,
+                     cd->height,
+                     cd->type);
+
+                encoder.execute();
+
+                *totalAcUncompressedCount  += encoder.numAcValuesEncoded();
+                *totalDcUncompressedCount  += encoder.numDcValuesEncoded();
+
+                packedAcEnd +=
+                    encoder.numAcValuesEncoded() * sizeof (unsigned short);
+
+                packedDcEnd +=
+                    encoder.numDcValuesEncoded() * sizeof (unsigned short);
+            }
+
+            break;
+
+          case RLE:
+
+            //
+            // For RLE, bash the bytes up so that the first bytes of each
+            // pixel are contingous, as are the second bytes, and so on.
+            //
+
+            for (unsigned int y = 0; y < rowPtrs[chan].size(); ++y)
+            {
+                const char *row = rowPtrs[chan][y];
+
+                for (int x = 0; x < cd->width; ++x)
+                {
+                    for (int byte = 0;
+                         byte < Imf::pixelTypeSize (cd->type);
+                         ++byte)
+                    {
+                            
+                        *cd->planarUncRleEnd[byte]++ = *row++;
+                    }
+                }
+
+                *rleRawSize += cd->width * Imf::pixelTypeSize(cd->type);
+            }
+
+            break;
+
+          case UNKNOWN:
+           
+            //
+            // Otherwise, just copy data over verbatim
+            //
+
+            {
+                int scanlineSize = cd->width * Imf::pixelTypeSize(cd->type);
+
+                for (unsigned int y = 0; y < rowPtrs[chan].size(); ++y)
+                {
+                    memcpy (cd->planarUncBufferEnd,
+                            rowPtrs[chan][y],
+                            scanlineSize);
+    
+                    cd->planarUncBufferEnd += scanlineSize;
+                }
+
+                *unknownUncompressedSize += cd->planarUncSize;
+            }
+
+            break;
+
+          default:
+
+            assert (false);
+        }
+
+        encodedChannels[chan] = true;
+    }
+
+    //
+    // Pack the Unknown data into the output buffer first. Instead of
+    // just copying it uncompressed, try zlib compression at least.
+    //
+
+    if (*unknownUncompressedSize > 0)
+    {
+        uLongf inSize  = (uLongf)(*unknownUncompressedSize);
+        uLongf outSize = (uLongf)(ceil ((float)inSize * 1.01f) + 100);
+
+        if (Z_OK != ::compress2 ((Bytef *)outDataPtr,
+                                 &outSize,
+                                 (const Bytef *)_planarUncBuffer[UNKNOWN],
+                                 inSize,
+                                 9))
+        {
+            throw Iex::BaseExc ("Data compression (zlib) failed.");
+        }
+
+        outDataPtr += outSize;
+        *unknownCompressedSize = outSize;
+    }
+
+    //
+    // Now, pack all the Lossy DCT coefficients into our output
+    // buffer, with Huffman encoding.
+    //
+    // Also, record the compressed size and the number of 
+    // uncompressed componentns we have.
+    //
+
+    if (*totalAcUncompressedCount > 0)
+    { 
+        switch (_acCompression)
+        {
+          case STATIC_HUFFMAN:
+
+            *acCompressedSize = (int)
+                hufCompress((unsigned short *)_packedAcBuffer,
+                            (int)*totalAcUncompressedCount,
+                            outDataPtr);                
+            break;
+
+          case DEFLATE:
+
+            {
+                uLongf destLen = (uLongf)
+                    (2 * (*totalAcUncompressedCount) * sizeof (unsigned short));
+
+                if (Z_OK != ::compress2
+                                ((Bytef *)outDataPtr,
+                                 &destLen,
+                                 (Bytef *)_packedAcBuffer, 
+                                 (uLong)(*totalAcUncompressedCount
+                                                * sizeof (unsigned short)),
+                                 9))
+                {
+                    throw Iex::InputExc ("Data compression (zlib) failed.");
+                }
+
+                *acCompressedSize = destLen;        
+            }
+
+            break;
+
+          default:
+            
+            assert (false);
+        }
+
+        outDataPtr += *acCompressedSize;
+    }
+
+    // 
+    // Handle the DC components separately
+    //
+
+    if (*totalDcUncompressedCount > 0)
+    {
+        *dcCompressedSize = _zip->compress
+            (_packedDcBuffer,
+             (int)(*totalDcUncompressedCount) * sizeof (unsigned short),
+             outDataPtr);
+
+        outDataPtr += *dcCompressedSize;
+    }
+
+    // 
+    // If we have RLE data, first RLE encode it and set the uncompressed
+    // size. Then, deflate the results and set the compressed size.
+    //    
+
+    if (*rleRawSize > 0)
+    {
+        *rleUncompressedSize = rleCompress
+            ((int)(*rleRawSize),
+             _planarUncBuffer[RLE],
+             (signed char *)_rleBuffer);
+
+        uLongf dstLen =
+            (uLongf)ceil (1.01f * (float) * rleUncompressedSize) + 24;
+
+        if (Z_OK != ::compress2
+                        ((Bytef *)outDataPtr, 
+                         &dstLen, 
+                         (Bytef *)_rleBuffer, 
+                         (uLong)(*rleUncompressedSize),
+                         9))
+        {
+            throw Iex::BaseExc ("Error compressing RLE'd data.");
+        }
+        
+       *rleCompressedSize = dstLen;
+        outDataPtr       += *rleCompressedSize;
+    }
+
+    // 
+    // Flip the counters to XDR format
+    //         
+
+    for (int i = 0; i < NUM_SIZES_SINGLE; ++i)
+    {
+        Int64  src = *(((Int64 *)_outBuffer) + i);
+        char  *dst = (char *)(((Int64 *)_outBuffer) + i);
+
+        Xdr::write<CharPtrIO> (dst, src);
+    }
+
+    //
+    // We're done - compute the number of bytes we packed
+    //
+
+    outPtr = _outBuffer;
+
+    return static_cast<int>(outDataPtr - _outBuffer + 1);
+}
+
+
+int
+DwaCompressor::uncompress
+    (const char *inPtr,
+     int inSize,
+     int minY,
+     const char *&outPtr)
+{
+    return uncompress (inPtr,
+                       inSize,
+                       Imath::Box2i (Imath::V2i (_min[0], minY),
+                       Imath::V2i (_max[0], minY + numScanLines() - 1)),
+                       outPtr);
+}
+
+
+int 
+DwaCompressor::uncompressTile
+    (const char *inPtr,
+     int inSize,
+     Imath::Box2i range,
+     const char *&outPtr)
+{
+    return uncompress (inPtr, inSize, range, outPtr);
+}
+
+
+int 
+DwaCompressor::uncompress
+    (const char *inPtr,
+     int inSize,
+     Imath::Box2i range,
+     const char *&outPtr)
+{
+    int minX = range.min.x;
+    int maxX = std::min (range.max.x, _max[0]);
+    int minY = range.min.y;
+    int maxY = std::min (range.max.y, _max[1]);
+
+    int headerSize = NUM_SIZES_SINGLE*sizeof(Int64);
+    if (inSize < headerSize) 
+    {
+        throw Iex::InputExc("Error uncompressing DWA data"
+                            "(truncated header).");
+    }
+
+    // 
+    // Flip the counters from XDR to NATIVE
+    //
+
+    for (int i = 0; i < NUM_SIZES_SINGLE; ++i)
+    {
+        Int64      *dst =  (((Int64 *)inPtr) + i);
+        const char *src = (char *)(((Int64 *)inPtr) + i);
+
+        Xdr::read<CharPtrIO> (src, *dst);
+    }
+
+    //
+    // Unwind all the counter info
+    //
+
+    const Int64 *inPtr64 = (const Int64*) inPtr;
+
+    Int64 version                  = *(inPtr64 + VERSION);
+    Int64 unknownUncompressedSize  = *(inPtr64 + UNKNOWN_UNCOMPRESSED_SIZE);
+    Int64 unknownCompressedSize    = *(inPtr64 + UNKNOWN_COMPRESSED_SIZE);
+    Int64 acCompressedSize         = *(inPtr64 + AC_COMPRESSED_SIZE);
+    Int64 dcCompressedSize         = *(inPtr64 + DC_COMPRESSED_SIZE);
+    Int64 rleCompressedSize        = *(inPtr64 + RLE_COMPRESSED_SIZE);
+    Int64 rleUncompressedSize      = *(inPtr64 + RLE_UNCOMPRESSED_SIZE);
+    Int64 rleRawSize               = *(inPtr64 + RLE_RAW_SIZE);
+ 
+    Int64 totalAcUncompressedCount = *(inPtr64 + AC_UNCOMPRESSED_COUNT); 
+    Int64 totalDcUncompressedCount = *(inPtr64 + DC_UNCOMPRESSED_COUNT); 
+
+    Int64 acCompression            = *(inPtr64 + AC_COMPRESSION); 
+
+    Int64 compressedSize           = unknownCompressedSize + 
+                                     acCompressedSize +
+                                     dcCompressedSize +
+                                     rleCompressedSize;
+
+    const char *dataPtr            = inPtr + NUM_SIZES_SINGLE * sizeof(Int64);
+
+    if (inSize < headerSize + compressedSize) 
+    {
+        throw Iex::InputExc("Error uncompressing DWA data"
+                            "(truncated file).");
+    }
+
+    if (unknownUncompressedSize < 0  || 
+        unknownCompressedSize < 0    ||
+        acCompressedSize < 0         || 
+        dcCompressedSize < 0         ||
+        rleCompressedSize < 0        || 
+        rleUncompressedSize < 0      ||
+        rleRawSize < 0               ||  
+        totalAcUncompressedCount < 0 || 
+        totalDcUncompressedCount < 0) 
+    {
+        throw Iex::InputExc("Error uncompressing DWA data"
+                            " (corrupt header).");
+    }
+
+    if (version < 2) 
+        initializeLegacyChannelRules();
+    else
+    {
+        unsigned short ruleSize = 0;
+        Xdr::read<CharPtrIO>(dataPtr, ruleSize);
+
+        if (ruleSize < 0) 
+            throw Iex::InputExc("Error uncompressing DWA data"
+                                " (corrupt header file).");
+
+        headerSize += ruleSize;
+        if (inSize < headerSize + compressedSize)
+            throw Iex::InputExc("Error uncompressing DWA data"
+                                " (truncated file).");
+
+        _channelRules.clear();
+        ruleSize -= Xdr::size<unsigned short> ();
+        while (ruleSize > 0) 
+        {
+            Classifier rule(dataPtr, ruleSize);
+            
+            _channelRules.push_back(rule);
+            ruleSize -= rule.size();
+        }
+    }
+
+
+    size_t outBufferSize = 0;
+    initializeBuffers(outBufferSize);
+
+    //
+    // Allocate _outBuffer, if we haven't done so already
+    //
+
+    if (_maxScanLineSize * numScanLines() > _outBufferSize) 
+    {
+        _outBufferSize = _maxScanLineSize * numScanLines();
+        if (_outBuffer != 0)
+            delete[] _outBuffer;
+        _outBuffer = new char[_maxScanLineSize * numScanLines()];
+    }
+
+
+    char *outBufferEnd = _outBuffer;
+
+       
+    //
+    // Find the start of the RLE packed AC components and
+    // the DC components for each channel. This will be handy   
+    // if you want to decode the channels in parallel later on.
+    //
+
+    char *packedAcBufferEnd = 0; 
+
+    if (_packedAcBuffer)
+        packedAcBufferEnd = _packedAcBuffer;
+
+    char *packedDcBufferEnd = 0;
+
+    if (_packedDcBuffer)
+        packedDcBufferEnd = _packedDcBuffer;
+
+    //
+    // UNKNOWN data is packed first, followed by the 
+    // Huffman-compressed AC, then the DC values, 
+    // and then the zlib compressed RLE data.
+    //
+    
+    const char *compressedUnknownBuf = dataPtr;
+
+    const char *compressedAcBuf      = compressedUnknownBuf + 
+                                  static_cast<ptrdiff_t>(unknownCompressedSize);
+    const char *compressedDcBuf      = compressedAcBuf +
+                                  static_cast<ptrdiff_t>(acCompressedSize);
+    const char *compressedRleBuf     = compressedDcBuf + 
+                                  static_cast<ptrdiff_t>(dcCompressedSize);
+
+    // 
+    // Sanity check that the version is something we expect. Right now, 
+    // we can decode version 0, 1, and 2. v1 adds 'end of block' symbols
+    // to the AC RLE. v2 adds channel classification rules at the 
+    // start of the data block.
+    //
+
+    if ((version < 0) || (version > 2))
+        throw Iex::InputExc ("Invalid version of compressed data block");    
+
+    setupChannelData(minX, minY, maxX, maxY);
+
+    // 
+    // Uncompress the UNKNOWN data into _planarUncBuffer[UNKNOWN]
+    //
+
+    if (unknownCompressedSize > 0)
+    {
+        uLongf outSize = static_cast<uLongf>(
+                ceil( (float)unknownUncompressedSize * 1.01) + 100);
+
+        if (unknownUncompressedSize < 0 || 
+            outSize > _planarUncBufferSize[UNKNOWN]) 
+        {
+            throw Iex::InputExc("Error uncompressing DWA data"
+                                "(corrupt header).");
+        }
+
+        if (Z_OK != ::uncompress
+                        ((Bytef *)_planarUncBuffer[UNKNOWN],
+                         &outSize,
+                         (Bytef *)compressedUnknownBuf,
+                         (uLong)unknownCompressedSize))
+        {
+            throw Iex::BaseExc("Error uncompressing UNKNOWN data.");
+        }
+    }
+
+    // 
+    // Uncompress the AC data into _packedAcBuffer
+    //
+
+    if (acCompressedSize > 0)
+    {
+        if (totalAcUncompressedCount*sizeof(unsigned short) > _packedAcBufferSize)
+        {
+            throw Iex::InputExc("Error uncompressing DWA data"
+                                "(corrupt header).");
+        }
+
+        //
+        // Don't trust the user to get it right, look in the file.
+        //
+
+        switch (acCompression)
+        {
+          case STATIC_HUFFMAN:
+
+            hufUncompress
+                (compressedAcBuf, 
+                 (int)acCompressedSize, 
+                 (unsigned short *)_packedAcBuffer, 
+                 (int)totalAcUncompressedCount); 
+
+            break;
+
+          case DEFLATE:
+            {
+                uLongf destLen =
+                    (int)(totalAcUncompressedCount) * sizeof (unsigned short);
+
+                if (Z_OK != ::uncompress
+                                ((Bytef *)_packedAcBuffer,
+                                 &destLen,
+                                 (Bytef *)compressedAcBuf,
+                                 (uLong)acCompressedSize))
+                {
+                    throw Iex::InputExc ("Data decompression (zlib) failed.");
+                }
+
+                if (totalAcUncompressedCount * sizeof (unsigned short) !=
+                                destLen)
+                {
+                    throw Iex::InputExc ("AC data corrupt.");     
+                }
+            }
+            break;
+
+          default:
+
+            throw Iex::NoImplExc ("Unknown AC Compression");
+            break;
+        }
+    }
+
+    //
+    // Uncompress the DC data into _packedDcBuffer
+    //
+
+    if (dcCompressedSize > 0)
+    {
+        if (totalDcUncompressedCount*sizeof(unsigned short) > _packedDcBufferSize)
+        {
+            throw Iex::InputExc("Error uncompressing DWA data"
+                                "(corrupt header).");
+        }
+
+        if (_zip->uncompress
+                    (compressedDcBuf, (int)dcCompressedSize, _packedDcBuffer)
+            != (int)totalDcUncompressedCount * sizeof (unsigned short))
+        {
+            throw Iex::BaseExc("DC data corrupt.");
+        }
+    }
+
+    //
+    // Uncompress the RLE data into _rleBuffer, then unRLE the results
+    // into _planarUncBuffer[RLE]
+    //
+
+    if (rleRawSize > 0)
+    {
+        if (rleUncompressedSize > _rleBufferSize ||
+            rleRawSize > _planarUncBufferSize[RLE])
+        {
+            throw Iex::InputExc("Error uncompressing DWA data"
+                                "(corrupt header).");
+        }
+ 
+        uLongf dstLen = (uLongf)rleUncompressedSize;
+
+        if (Z_OK != ::uncompress
+                        ((Bytef *)_rleBuffer,
+                         &dstLen,
+                         (Bytef *)compressedRleBuf,
+                         (uLong)rleCompressedSize))
+        {
+            throw Iex::BaseExc("Error uncompressing RLE data.");
+        }
+
+        if (dstLen != rleUncompressedSize)
+            throw Iex::BaseExc("RLE data corrupted");
+
+        if (rleUncompress
+                ((int)rleUncompressedSize, 
+                 (int)rleRawSize,
+                 (signed char *)_rleBuffer,
+                 _planarUncBuffer[RLE]) != rleRawSize)
+        {        
+            throw Iex::BaseExc("RLE data corrupted");
+        }
+    }
+
+    //
+    // Determine the start of each row in the output buffer
+    //
+
+    std::vector<bool> decodedChannels (_channelData.size());
+    std::vector< std::vector<char *> > rowPtrs (_channelData.size());
+
+    for (unsigned int chan = 0; chan < _channelData.size(); ++chan)
+        decodedChannels[chan] = false;
+
+    outBufferEnd = _outBuffer;
+
+    for (int y = minY; y <= maxY; ++y)
+    {
+        for (unsigned int chan = 0; chan < _channelData.size(); ++chan)
+        {
+            ChannelData *cd = &_channelData[chan];
+
+            if (Imath::modp (y, cd->ySampling) != 0)
+                continue;
+
+            rowPtrs[chan].push_back (outBufferEnd);
+            outBufferEnd += cd->width * Imf::pixelTypeSize (cd->type);
+        }
+    }
+
+    //
+    // Setup to decode each block of 3 channels that need to
+    // be handled together
+    //
+
+    for (unsigned int csc = 0; csc < _cscSets.size(); ++csc)
+    {
+        int rChan = _cscSets[csc].idx[0];    
+        int gChan = _cscSets[csc].idx[1];    
+        int bChan = _cscSets[csc].idx[2];    
+
+
+        LossyDctDecoderCsc decoder
+            (rowPtrs[rChan],
+             rowPtrs[gChan],
+             rowPtrs[bChan],
+             packedAcBufferEnd,
+             packedDcBufferEnd,
+             dwaCompressorToLinear,
+             _channelData[rChan].width,
+             _channelData[rChan].height,
+             _channelData[rChan].type,
+             _channelData[gChan].type,
+             _channelData[bChan].type);
+
+        decoder.execute();
+
+        packedAcBufferEnd +=
+            decoder.numAcValuesEncoded() * sizeof (unsigned short);
+
+        packedDcBufferEnd +=
+            decoder.numDcValuesEncoded() * sizeof (unsigned short);
+
+        decodedChannels[rChan] = true;
+        decodedChannels[gChan] = true;
+        decodedChannels[bChan] = true;
+    }
+
+    //
+    // Setup to handle the remaining channels by themselves
+    //
+
+    for (unsigned int chan = 0; chan < _channelData.size(); ++chan)
+    {
+        if (decodedChannels[chan])
+            continue;
+
+        ChannelData *cd = &_channelData[chan];
+        int pixelSize = Imf::pixelTypeSize (cd->type);
+
+        switch (cd->compression)
+        {
+          case LOSSY_DCT:
+
+            //
+            // Setup a single-channel lossy DCT decoder pointing
+            // at the output buffer
+            //
+
+            {
+                const unsigned short *linearLut = 0;
+
+                if (!cd->pLinear)
+                    linearLut = dwaCompressorToLinear;
+
+                LossyDctDecoder decoder
+                    (rowPtrs[chan],
+                     packedAcBufferEnd,
+                     packedDcBufferEnd,
+                     linearLut,
+                     cd->width,
+                     cd->height,
+                     cd->type);
+
+                decoder.execute();   
+
+                packedAcBufferEnd += 
+                    decoder.numAcValuesEncoded() * sizeof (unsigned short);
+
+                packedDcBufferEnd += 
+                    decoder.numDcValuesEncoded() * sizeof (unsigned short);
+            }
+
+            break;
+
+          case RLE:
+
+            //
+            // For the RLE case, the data has been un-RLE'd into
+            // planarUncRleEnd[], but is still split out by bytes.
+            // We need to rearrange the bytes back into the correct
+            // order in the output buffer;
+            //
+
+            {
+                int row = 0;
+
+                for (int y = minY; y <= maxY; ++y)
+                {
+                    if (Imath::modp (y, cd->ySampling) != 0)
+                        continue;
+
+                    char *dst = rowPtrs[chan][row];
+
+                    if (pixelSize == 2)
+                    {
+                        interleaveByte2 (dst, 
+                                         cd->planarUncRleEnd[0],
+                                         cd->planarUncRleEnd[1],
+                                         cd->width);
+                                            
+                        cd->planarUncRleEnd[0] += cd->width;
+                        cd->planarUncRleEnd[1] += cd->width;
+                    }
+                    else
+                    {
+                        for (int x = 0; x < cd->width; ++x)
+                        {
+                            for (int byte = 0; byte < pixelSize; ++byte)
+                            {
+                               *dst++ = *cd->planarUncRleEnd[byte]++;
+                            }
+                        }
+                    }
+
+                    row++;
+                }
+            }
+
+            break;
+
+          case UNKNOWN:
+
+            //
+            // In the UNKNOWN case, data is already in planarUncBufferEnd
+            // and just needs to copied over to the output buffer
+            //
+
+            {
+                int row             = 0;
+                int dstScanlineSize = cd->width * Imf::pixelTypeSize (cd->type);
+
+                for (int y = minY; y <= maxY; ++y)
+                {
+                    if (Imath::modp (y, cd->ySampling) != 0)
+                        continue;
+
+                    memcpy (rowPtrs[chan][row],
+                            cd->planarUncBufferEnd,
+                            dstScanlineSize);
+
+                    cd->planarUncBufferEnd += dstScanlineSize;
+                    row++;
+                }
+            }
+
+            break;
+
+          default:
+
+            throw Iex::NoImplExc ("Unhandled compression scheme case");
+            break;
+        }
+
+        decodedChannels[chan] = true;
+    }
+
+    //
+    // Return a ptr to _outBuffer
+    //
+
+    outPtr = _outBuffer;
+    return (int)(outBufferEnd - _outBuffer);
+}
+
+
+// static
+void
+DwaCompressor::initializeFuncs()
+{
+    convertFloatToHalf64 = convertFloatToHalf64_scalar;
+    fromHalfZigZag       = fromHalfZigZag_scalar;
+
+    CpuId cpuId;
+
+    //
+    // Setup HALF <-> FLOAT conversion implementations
+    //
+
+    if (cpuId.avx && cpuId.f16c)
+    {
+        convertFloatToHalf64 = convertFloatToHalf64_f16c;
+        fromHalfZigZag       = fromHalfZigZag_f16c;
+    } 
+
+    //
+    // Setup inverse DCT implementations
+    //
+
+    dctInverse8x8_0 = dctInverse8x8_scalar<0>;
+    dctInverse8x8_1 = dctInverse8x8_scalar<1>;
+    dctInverse8x8_2 = dctInverse8x8_scalar<2>;
+    dctInverse8x8_3 = dctInverse8x8_scalar<3>;
+    dctInverse8x8_4 = dctInverse8x8_scalar<4>;
+    dctInverse8x8_5 = dctInverse8x8_scalar<5>;
+    dctInverse8x8_6 = dctInverse8x8_scalar<6>;
+    dctInverse8x8_7 = dctInverse8x8_scalar<7>;
+
+    if (cpuId.avx) 
+    {
+        dctInverse8x8_0 = dctInverse8x8_avx<0>;
+        dctInverse8x8_1 = dctInverse8x8_avx<1>;
+        dctInverse8x8_2 = dctInverse8x8_avx<2>;
+        dctInverse8x8_3 = dctInverse8x8_avx<3>;
+        dctInverse8x8_4 = dctInverse8x8_avx<4>;
+        dctInverse8x8_5 = dctInverse8x8_avx<5>;
+        dctInverse8x8_6 = dctInverse8x8_avx<6>;
+        dctInverse8x8_7 = dctInverse8x8_avx<7>;
+    } 
+    else if (cpuId.sse2) 
+    {
+        dctInverse8x8_0 = dctInverse8x8_sse2<0>;
+        dctInverse8x8_1 = dctInverse8x8_sse2<1>;
+        dctInverse8x8_2 = dctInverse8x8_sse2<2>;
+        dctInverse8x8_3 = dctInverse8x8_sse2<3>;
+        dctInverse8x8_4 = dctInverse8x8_sse2<4>;
+        dctInverse8x8_5 = dctInverse8x8_sse2<5>;
+        dctInverse8x8_6 = dctInverse8x8_sse2<6>;
+        dctInverse8x8_7 = dctInverse8x8_sse2<7>;
+    }
+}
+
+
+//
+// Handle channel classification and buffer allocation once we know
+// how to classify channels
+//
+
+void
+DwaCompressor::initializeBuffers (size_t &outBufferSize)
+{
+    classifyChannels (_channels, _channelData, _cscSets);
+
+    //
+    // _outBuffer needs to be big enough to hold all our 
+    // compressed data - which could vary depending on what sort
+    // of channels we have. 
+    //
+
+    int maxOutBufferSize  = 0;
+    int numLossyDctChans  = 0;
+    int unknownBufferSize = 0;
+    int rleBufferSize     = 0;
+
+    int maxLossyDctAcSize = (int)ceil ((float)numScanLines() / 8.0f) * 
+                            (int)ceil ((float)(_max[0] - _min[0] + 1) / 8.0f) *
+                            63 * sizeof (unsigned short);
+
+    int maxLossyDctDcSize = (int)ceil ((float)numScanLines() / 8.0f) * 
+                            (int)ceil ((float)(_max[0] - _min[0] + 1) / 8.0f) *
+                            sizeof (unsigned short);
+
+    for (unsigned int chan = 0; chan < _channelData.size(); ++chan)
+    {
+        switch (_channelData[chan].compression)
+        {
+          case LOSSY_DCT:
+
+            //
+            // This is the size of the number of packed
+            // components, plus the requirements for
+            // maximum Huffman encoding size.
+            //
+
+            maxOutBufferSize += 2 * maxLossyDctAcSize + 65536;
+            numLossyDctChans++;
+            break;
+
+          case RLE:
+            {
+                //
+                // RLE, if gone horribly wrong, could double the size
+                // of the source data.
+                //
+
+                int rleAmount = 2 * numScanLines() * (_max[0] - _min[0] + 1) *
+                                Imf::pixelTypeSize (_channelData[chan].type);
+
+                rleBufferSize += rleAmount;
+            }
+            break;
+
+
+          case UNKNOWN:
+
+            unknownBufferSize += numScanLines() * (_max[0] - _min[0] + 1) *
+                                 Imf::pixelTypeSize (_channelData[chan].type);
+            break;
+
+          default:
+
+            throw Iex::NoImplExc ("Unhandled compression scheme case");
+            break;
+        }
+    }
+
+    //
+    // Also, since the results of the RLE are packed into 
+    // the output buffer, we need the extra room there. But
+    // we're going to zlib compress() the data we pack, 
+    // which could take slightly more space
+    //
+
+    maxOutBufferSize += (int)(ceil (1.01f * (float)rleBufferSize) + 100);
+    
+    //
+    // And the same goes for the UNKNOWN data
+    //
+
+    maxOutBufferSize += (int)(ceil (1.01f * (float)unknownBufferSize) + 100);
+
+    //
+    // Allocate a zip/deflate compressor big enought to hold the DC data
+    // and include it's compressed results in the size requirements
+    // for our output buffer
+    //
+
+    if (_zip == 0) 
+        _zip = new Zip (maxLossyDctDcSize * numLossyDctChans);
+    else if (_zip->maxRawSize() < maxLossyDctDcSize * numLossyDctChans)
+    {
+        delete _zip;
+        _zip = new Zip (maxLossyDctDcSize * numLossyDctChans);
+    }
+
+
+    maxOutBufferSize += _zip->maxCompressedSize();
+
+    //
+    // We also need to reserve space at the head of the buffer to 
+    // write out the size of our various packed and compressed data.
+    //
+
+    maxOutBufferSize += NUM_SIZES_SINGLE * sizeof (Int64); 
+                    
+
+    //
+    // Later, we're going to hijack outBuffer for the result of
+    // both encoding and decoding. So it needs to be big enough
+    // to hold either a buffers' worth of uncompressed or
+    // compressed data
+    //
+    // For encoding, we'll need _outBuffer to hold maxOutBufferSize bytes,
+    // but for decoding, we only need it to be maxScanLineSize*numScanLines.
+    // Cache the max size for now, and alloc the buffer when we either
+    // encode or decode.
+    //
+
+    outBufferSize = maxOutBufferSize;
+
+
+    //
+    // _packedAcBuffer holds the quantized DCT coefficients prior
+    // to Huffman encoding
+    //
+
+    if (maxLossyDctAcSize * numLossyDctChans > _packedAcBufferSize)
+    {
+        _packedAcBufferSize = maxLossyDctAcSize * numLossyDctChans;
+        if (_packedAcBuffer != 0) 
+            delete[] _packedAcBuffer;
+        _packedAcBuffer = new char[_packedAcBufferSize];
+    }
+
+    //
+    // _packedDcBuffer holds one quantized DCT coef per 8x8 block
+    //
+
+    if (maxLossyDctDcSize * numLossyDctChans > _packedDcBufferSize)
+    {
+        _packedDcBufferSize = maxLossyDctDcSize * numLossyDctChans;
+        if (_packedDcBuffer != 0) 
+            delete[] _packedDcBuffer;
+        _packedDcBuffer     = new char[_packedDcBufferSize];
+    }
+
+    if (rleBufferSize > _rleBufferSize) 
+    {
+        _rleBufferSize = rleBufferSize;
+        if (_rleBuffer != 0) 
+            delete[] _rleBuffer;
+        _rleBuffer = new char[rleBufferSize];
+    }
+
+    // 
+    // The planar uncompressed buffer will hold float data for LOSSY_DCT
+    // compressed values, and whatever the native type is for other
+    // channels. We're going to use this to hold data in a planar
+    // format, as opposed to the native interleaved format we take
+    // into compress() and give back from uncompress().
+    //
+    // This also makes it easier to compress the UNKNOWN and RLE data
+    // all in one swoop (for each compression scheme).
+    //
+
+    int planarUncBufferSize[NUM_COMPRESSOR_SCHEMES];
+    for (int i=0; i<NUM_COMPRESSOR_SCHEMES; ++i)
+        planarUncBufferSize[i] = 0;
+
+    for (unsigned int chan = 0; chan < _channelData.size(); ++chan)
+    {
+        switch (_channelData[chan].compression)
+        {
+          case LOSSY_DCT:
+            break;
+
+          case RLE:
+            planarUncBufferSize[RLE] +=
+                     numScanLines() * (_max[0] - _min[0] + 1) *
+                     Imf::pixelTypeSize (_channelData[chan].type);
+            break;
+
+          case UNKNOWN: 
+            planarUncBufferSize[UNKNOWN] +=
+                     numScanLines() * (_max[0] - _min[0] + 1) *
+                     Imf::pixelTypeSize (_channelData[chan].type);
+            break;
+
+          default:
+            throw Iex::NoImplExc ("Unhandled compression scheme case");
+            break;
+        }
+    }
+
+    //
+    // UNKNOWN data is going to be zlib compressed, which needs 
+    // a little extra headroom
+    //
+
+    if (planarUncBufferSize[UNKNOWN] > 0)
+    {
+        planarUncBufferSize[UNKNOWN] =
+            (int) ceil (1.01f * (float)planarUncBufferSize[UNKNOWN]) + 100;
+    }
+
+    for (int i = 0; i < NUM_COMPRESSOR_SCHEMES; ++i)
+    {
+        if (planarUncBufferSize[i] > _planarUncBufferSize[i]) 
+        {
+            _planarUncBufferSize[i] = planarUncBufferSize[i];
+            if (_planarUncBuffer[i] != 0) 
+                delete[] _planarUncBuffer[i];
+            _planarUncBuffer[i] = new char[planarUncBufferSize[i]];
+        }
+    }
+}
+
+
+//
+// Setup channel classification rules to use when writing files
+//
+
+void
+DwaCompressor::initializeDefaultChannelRules ()
+{
+    _channelRules.clear();
+
+    _channelRules.push_back (Classifier ("R",     LOSSY_DCT, HALF,   0, false));
+    _channelRules.push_back (Classifier ("R",     LOSSY_DCT, FLOAT,  0, false));
+    _channelRules.push_back (Classifier ("G",     LOSSY_DCT, HALF,   1, false));
+    _channelRules.push_back (Classifier ("G",     LOSSY_DCT, FLOAT,  1, false));
+    _channelRules.push_back (Classifier ("B",     LOSSY_DCT, HALF,   2, false));
+    _channelRules.push_back (Classifier ("B",     LOSSY_DCT, FLOAT,  2, false));
+
+    _channelRules.push_back (Classifier ("Y",     LOSSY_DCT, HALF,  -1, false));
+    _channelRules.push_back (Classifier ("Y",     LOSSY_DCT, FLOAT, -1, false));
+    _channelRules.push_back (Classifier ("BY",    LOSSY_DCT, HALF,  -1, false));
+    _channelRules.push_back (Classifier ("BY",    LOSSY_DCT, FLOAT, -1, false));
+    _channelRules.push_back (Classifier ("RY",    LOSSY_DCT, HALF,  -1, false));
+    _channelRules.push_back (Classifier ("RY",    LOSSY_DCT, FLOAT, -1, false));
+
+    _channelRules.push_back (Classifier ("A",     RLE,       UINT,  -1, false));
+    _channelRules.push_back (Classifier ("A",     RLE,       HALF,  -1, false));
+    _channelRules.push_back (Classifier ("A",     RLE,       FLOAT, -1, false));
+}
+
+
+//
+// Setup channel classification rules when reading files with VERSION < 2
+//
+
+void
+DwaCompressor::initializeLegacyChannelRules ()
+{
+    _channelRules.clear();
+
+    _channelRules.push_back (Classifier ("r",     LOSSY_DCT, HALF,   0, true));
+    _channelRules.push_back (Classifier ("r",     LOSSY_DCT, FLOAT,  0, true));
+    _channelRules.push_back (Classifier ("red",   LOSSY_DCT, HALF,   0, true));
+    _channelRules.push_back (Classifier ("red",   LOSSY_DCT, FLOAT,  0, true));
+    _channelRules.push_back (Classifier ("g",     LOSSY_DCT, HALF,   1, true));
+    _channelRules.push_back (Classifier ("g",     LOSSY_DCT, FLOAT,  1, true));
+    _channelRules.push_back (Classifier ("grn",   LOSSY_DCT, HALF,   1, true));
+    _channelRules.push_back (Classifier ("grn",   LOSSY_DCT, FLOAT,  1, true));
+    _channelRules.push_back (Classifier ("green", LOSSY_DCT, HALF,   1, true));
+    _channelRules.push_back (Classifier ("green", LOSSY_DCT, FLOAT,  1, true));
+    _channelRules.push_back (Classifier ("b",     LOSSY_DCT, HALF,   2, true));
+    _channelRules.push_back (Classifier ("b",     LOSSY_DCT, FLOAT,  2, true));
+    _channelRules.push_back (Classifier ("blu",   LOSSY_DCT, HALF,   2, true));
+    _channelRules.push_back (Classifier ("blu",   LOSSY_DCT, FLOAT,  2, true));
+    _channelRules.push_back (Classifier ("blue",  LOSSY_DCT, HALF,   2, true));
+    _channelRules.push_back (Classifier ("blue",  LOSSY_DCT, FLOAT,  2, true));
+
+    _channelRules.push_back (Classifier ("y",     LOSSY_DCT, HALF,  -1, true));
+    _channelRules.push_back (Classifier ("y",     LOSSY_DCT, FLOAT, -1, true));
+    _channelRules.push_back (Classifier ("by",    LOSSY_DCT, HALF,  -1, true));
+    _channelRules.push_back (Classifier ("by",    LOSSY_DCT, FLOAT, -1, true));
+    _channelRules.push_back (Classifier ("ry",    LOSSY_DCT, HALF,  -1, true));
+    _channelRules.push_back (Classifier ("ry",    LOSSY_DCT, FLOAT, -1, true));
+    _channelRules.push_back (Classifier ("a",     RLE,       UINT,  -1, true));
+    _channelRules.push_back (Classifier ("a",     RLE,       HALF,  -1, true));
+    _channelRules.push_back (Classifier ("a",     RLE,       FLOAT, -1, true));
+}
+
+
+// 
+// Given a set of rules and ChannelData, figure out which rules apply
+//
+
+void
+DwaCompressor::relevantChannelRules (std::vector<Classifier> &rules) const 
+{
+    rules.clear();
+
+    std::vector<std::string> suffixes;
+    
+    for (size_t cd = 0; cd < _channelData.size(); ++cd) 
+    {
+        std::string suffix  = _channelData[cd].name;
+        size_t      lastDot = suffix.find_last_of ('.');
+
+        if (lastDot != std::string::npos)
+            suffix = suffix.substr (lastDot+1, std::string::npos);
+
+        suffixes.push_back(suffix);
+    }
+
+    
+    for (size_t i = 0; i < _channelRules.size(); ++i) 
+    {
+        for (size_t cd = 0; cd < _channelData.size(); ++cd) 
+        {
+            if (_channelRules[i].match (suffixes[cd], _channelData[cd].type ))
+            {
+                rules.push_back (_channelRules[i]);
+                break;
+            }
+        }       
+    }
+}
+
+
+//
+// Take our initial list of channels, and cache the contents.
+//
+// Determine approprate compression schemes for each channel,
+// and figure out which sets should potentially be CSC'ed 
+// prior to lossy compression.
+//
+
+void
+DwaCompressor::classifyChannels
+    (ChannelList channels,
+     std::vector<ChannelData> &chanData,
+     std::vector<CscChannelSet> &cscData)
+{
+    //
+    // prefixMap used to map channel name prefixes to 
+    // potential CSC-able sets of channels.
+    //
+
+    std::map<std::string, DwaCompressor::CscChannelSet> prefixMap;
+    std::vector<DwaCompressor::CscChannelSet>           tmpCscSet;
+
+    unsigned int numChan = 0;
+
+    for (ChannelList::Iterator c = channels.begin(); c != channels.end(); ++c)
+        numChan++;
+    
+    if (numChan)
+        chanData.resize (numChan);
+
+    //
+    // Cache the relevant data from the channel structs.
+    //
+
+    unsigned int offset = 0;
+
+    for (ChannelList::Iterator c = channels.begin(); c != channels.end(); ++c)
+    {
+        chanData[offset].name        = std::string (c.name());
+        chanData[offset].compression = UNKNOWN;
+        chanData[offset].xSampling   = c.channel().xSampling;
+        chanData[offset].ySampling   = c.channel().ySampling;
+        chanData[offset].type        = c.channel().type;
+        chanData[offset].pLinear     = c.channel().pLinear;
+
+        offset++;
+    }
+
+    //
+    // Try and figure out which channels should be
+    // compressed by which means.
+    //
+
+    for (offset = 0; offset<numChan; ++offset)
+    {
+        std::string prefix  = "";
+        std::string suffix  = chanData[offset].name;
+        size_t      lastDot = suffix.find_last_of ('.');
+
+        if (lastDot != std::string::npos)
+        {
+            prefix = suffix.substr (0,         lastDot);
+            suffix = suffix.substr (lastDot+1, std::string::npos);
+        } 
+
+        //
+        // Make sure we have an entry in our CSC set map 
+        //
+
+        std::map<std::string, DwaCompressor::CscChannelSet>::iterator 
+            theSet = prefixMap.find (prefix);
+
+        if (theSet == prefixMap.end())
+        {
+            DwaCompressor::CscChannelSet tmpSet;
+
+            tmpSet.idx[0] = 
+            tmpSet.idx[1] = 
+            tmpSet.idx[2] = -1;
+
+            prefixMap[prefix] = tmpSet;
+        }
+
+        // 
+        // Check the suffix against the list of classifications
+        // we defined previously. If the _cscIdx is not negative,
+        // it indicates that we should be part of a CSC group.
+        //
+
+        for (std::vector<Classifier>::iterator i = _channelRules.begin();
+             i != _channelRules.end();
+             ++i)
+        {
+            if ( i->match(suffix, chanData[offset].type) )
+            {
+                chanData[offset].compression = i->_scheme;
+
+                if ( i->_cscIdx >= 0)
+                    prefixMap[prefix].idx[i->_cscIdx] = offset;
+            }
+        }
+    }
+
+    //
+    // Finally, try and find RGB sets of channels which 
+    // can be CSC'ed to a Y'CbCr space prior to loss, for
+    // better compression.
+    //
+    // Walk over our set of candidates, and see who has
+    // all three channels defined (and has common sampling
+    // patterns, etc).
+    //
+
+    for (std::map<std::string, DwaCompressor::CscChannelSet>::iterator 
+         theItem = prefixMap.begin(); theItem != prefixMap.end();
+         ++theItem)
+    {
+        int red = (*theItem).second.idx[0];
+        int grn = (*theItem).second.idx[1];
+        int blu = (*theItem).second.idx[2];
+
+        if ((red < 0) || (grn < 0) || (blu < 0))
+            continue;
+
+        if ((chanData[red].xSampling != chanData[grn].xSampling) ||
+            (chanData[red].xSampling != chanData[blu].xSampling) ||
+            (chanData[grn].xSampling != chanData[blu].xSampling) ||
+            (chanData[red].ySampling != chanData[grn].ySampling) ||
+            (chanData[red].ySampling != chanData[blu].ySampling) ||
+            (chanData[grn].ySampling != chanData[blu].ySampling))
+        {
+            continue;
+        }
+        
+        tmpCscSet.push_back ((*theItem).second);
+    }
+    
+    size_t numCsc = tmpCscSet.size();
+
+    if (numCsc)
+        cscData.resize(numCsc);
+
+    for (offset = 0; offset < numCsc; ++offset)
+        cscData[offset] = tmpCscSet[offset];
+}
+
+
+
+//
+// Setup some buffer pointers, determine channel sizes, things
+// like that.
+//
+
+void
+DwaCompressor::setupChannelData (int minX, int minY, int maxX, int maxY)
+{
+    char *planarUncBuffer[NUM_COMPRESSOR_SCHEMES];
+
+    for (int i=0; i<NUM_COMPRESSOR_SCHEMES; ++i)
+    {
+        planarUncBuffer[i] = 0;
+
+        if (_planarUncBuffer[i])
+            planarUncBuffer[i] =  _planarUncBuffer[i];
+    }
+
+    for (unsigned int chan = 0; chan < _channelData.size(); ++chan)
+    {
+        ChannelData *cd = &_channelData[chan];
+
+        cd->width  = Imf::numSamples (cd->xSampling, minX, maxX);
+        cd->height = Imf::numSamples (cd->ySampling, minY, maxY);
+                                
+        cd->planarUncSize =
+            cd->width * cd->height * Imf::pixelTypeSize (cd->type);
+                                  
+        cd->planarUncBuffer    = planarUncBuffer[cd->compression];
+        cd->planarUncBufferEnd = cd->planarUncBuffer;
+
+        cd->planarUncRle[0]    = cd->planarUncBuffer;
+        cd->planarUncRleEnd[0] = cd->planarUncRle[0];
+
+        for (int byte = 1; byte < Imf::pixelTypeSize(cd->type); ++byte)
+        {
+            cd->planarUncRle[byte] = 
+                         cd->planarUncRle[byte-1] + cd->width * cd->height;
+
+            cd->planarUncRleEnd[byte] =
+                         cd->planarUncRle[byte];
+        }
+
+        cd->planarUncType = cd->type;
+
+        if (cd->compression == LOSSY_DCT)
+        {
+            cd->planarUncType = FLOAT;
+        }
+        else
+        {
+            planarUncBuffer[cd->compression] +=
+                cd->width * cd->height * Imf::pixelTypeSize (cd->planarUncType);
+        }
+    }
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfDwaCompressor.h b/Source/OpenEXR/IlmImf/ImfDwaCompressor.h
new file mode 100644
index 0000000..8e390b0
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfDwaCompressor.h
@@ -0,0 +1,210 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2009-2014 DreamWorks Animation LLC. 
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of DreamWorks Animation nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef INCLUDED_IMF_DWA_COMRESSOR_H
+#define INCLUDED_IMF_DWA_COMRESSOR_H
+
+//------------------------------------------------------------------------------
+//
+// class DwaCompressor -- Store lossy RGB data by quantizing DCT components.
+//
+//------------------------------------------------------------------------------
+
+#include <vector>
+#include <half.h>
+
+#include "ImfInt64.h"
+#include "ImfZip.h"
+#include "ImfChannelList.h"
+#include "ImfCompressor.h"
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+class DwaCompressor: public Compressor
+{
+  public:
+
+    enum AcCompression 
+    {
+        STATIC_HUFFMAN,
+        DEFLATE,
+    };
+
+
+    DwaCompressor (const Header &hdr, 
+                   int           maxScanLineSize,
+                   int           numScanLines,    // ideally is a multiple of 8
+                   AcCompression acCompression);
+
+    virtual ~DwaCompressor ();
+
+    virtual int numScanLines () const;
+
+    virtual Imf::Compressor::Format format () const;
+
+    virtual int compress (const char *inPtr,
+                          int         inSize,
+                          int         minY,
+                          const char *&outPtr);
+
+    virtual int compressTile (const char   *inPtr,
+                              int           inSize,
+                              Imath::Box2i  range,
+                              const char  *&outPtr);
+
+    virtual int uncompress (const char *inPtr,
+                            int         inSize,
+                            int         minY,
+                            const char *&outPtr);
+
+    virtual int uncompressTile (const char  *inPtr,
+                                int          inSize,
+                                Imath::Box2i range,
+                                const char *&outPtr);
+
+    static void initializeFuncs ();
+
+  private:
+
+    struct ChannelData;
+    struct CscChannelSet;
+    struct Classifier;
+    
+    class LossyDctDecoderBase;
+    class LossyDctDecoder;
+    class LossyDctDecoderCsc;
+
+    class LossyDctEncoderBase;
+    class LossyDctEncoder;
+    class LossyDctEncoderCsc;
+
+    enum CompressorScheme 
+    {
+        UNKNOWN = 0,
+        LOSSY_DCT,
+        RLE,
+        
+        NUM_COMPRESSOR_SCHEMES
+    };
+
+    //
+    // Per-chunk compressed data sizes, one value per chunk
+    //
+
+    enum DataSizesSingle 
+    {
+        VERSION = 0,                  // Version number:
+                                      //   0: classic
+                                      //   1: adds "end of block" to the AC RLE
+
+        UNKNOWN_UNCOMPRESSED_SIZE,    // Size of leftover data, uncompressed.
+        UNKNOWN_COMPRESSED_SIZE,      // Size of leftover data, zlib compressed.
+
+        AC_COMPRESSED_SIZE,           // AC RLE + Huffman size
+        DC_COMPRESSED_SIZE,           // DC + Deflate size
+        RLE_COMPRESSED_SIZE,          // RLE + Deflate data size
+        RLE_UNCOMPRESSED_SIZE,        // RLE'd data size 
+        RLE_RAW_SIZE,                 // Un-RLE'd data size
+
+        AC_UNCOMPRESSED_COUNT,        // AC RLE number of elements
+        DC_UNCOMPRESSED_COUNT,        // DC number of elements
+
+        AC_COMPRESSION,               // AC compression strategy
+        NUM_SIZES_SINGLE
+    };
+
+    AcCompression     _acCompression;
+
+    int               _maxScanLineSize;
+    int               _numScanLines;
+    int               _min[2], _max[2];
+
+    ChannelList                _channels;
+    std::vector<ChannelData>   _channelData;
+    std::vector<CscChannelSet> _cscSets;
+    std::vector<Classifier>    _channelRules;
+
+    char             *_packedAcBuffer;
+    size_t            _packedAcBufferSize;
+    char             *_packedDcBuffer;
+    size_t            _packedDcBufferSize;
+    char             *_rleBuffer;
+    size_t            _rleBufferSize;
+    char             *_outBuffer;
+    size_t            _outBufferSize;
+    char             *_planarUncBuffer[NUM_COMPRESSOR_SCHEMES];
+    size_t            _planarUncBufferSize[NUM_COMPRESSOR_SCHEMES];
+
+    Zip              *_zip;
+    float             _dwaCompressionLevel;
+
+    int compress (const char   *inPtr,
+                  int           inSize,
+                  Imath::Box2i  range,
+                  const char  *&outPtr);
+
+    int uncompress (const char   *inPtr,
+                    int           inSize,
+                    Imath::Box2i  range,
+                    const char  *&outPtr);
+
+    void initializeBuffers (size_t&);
+    void initializeDefaultChannelRules ();
+    void initializeLegacyChannelRules ();
+
+    void relevantChannelRules( std::vector<Classifier> &) const;
+
+    //
+    // Populate our cached version of the channel data with
+    // data from the real channel list. We want to 
+    // copy over attributes, determine compression schemes
+    // releveant for the channel type, and find sets of
+    // channels to be compressed from Y'CbCr data instead 
+    // of R'G'B'.
+    //
+
+    void classifyChannels (ChannelList                  channels,
+                           std::vector<ChannelData>    &chanData, 
+                           std::vector<CscChannelSet>  &cscData);
+
+    // 
+    // Compute various buffer pointers for each channel
+    //
+
+    void setupChannelData (int minX, int minY, int maxX, int maxY);
+};
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif 
diff --git a/Source/OpenEXR/IlmImf/ImfDwaCompressorSimd.h b/Source/OpenEXR/IlmImf/ImfDwaCompressorSimd.h
new file mode 100644
index 0000000..93246f6
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfDwaCompressorSimd.h
@@ -0,0 +1,2145 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2009-2014 DreamWorks Animation LLC. 
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of DreamWorks Animation nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef IMF_DWACOMPRESSORSIMD_H_HAS_BEEN_INCLUDED
+#define IMF_DWACOMPRESSORSIMD_H_HAS_BEEN_INCLUDED
+
+//
+// Various SSE accelerated functions, used by Imf::DwaCompressor. 
+// These have been separated into a separate .h file, as the fast
+// paths are done with template specialization.
+//
+// Unless otherwise noted, all pointers are assumed to be 32-byte 
+// aligned. Unaligned pointers may risk seg-faulting.
+//
+
+#include "ImfNamespace.h"
+#include "ImfSimd.h"
+#include "ImfSystemSpecific.h"
+#include "OpenEXRConfig.h"
+
+#include <half.h>
+#include <assert.h>
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+#define _SSE_ALIGNMENT        32
+#define _SSE_ALIGNMENT_MASK 0x0F
+#define _AVX_ALIGNMENT_MASK 0x1F
+
+//
+// Test if we should enable GCC inline asm paths for AVX
+//
+
+#ifdef OPENEXR_IMF_HAVE_GCC_INLINE_ASM_AVX 
+
+    #define IMF_HAVE_GCC_INLINEASM
+
+    #ifdef __LP64__
+        #define IMF_HAVE_GCC_INLINEASM_64
+    #endif /* __LP64__ */
+
+#endif /* OPENEXR_IMF_HAVE_GCC_INLINE_ASM_AVX */
+
+//
+// A simple 64-element array, aligned properly for SIMD access. 
+//
+
+template <class T>
+class SimdAlignedBuffer64
+{
+    public:
+
+        SimdAlignedBuffer64(): _buffer (0), _handle (0)           
+        {
+            alloc();
+        }
+
+        SimdAlignedBuffer64(const SimdAlignedBuffer64 &rhs): _handle(0)
+        {
+            alloc();
+            memcpy (_buffer, rhs._buffer, 64 * sizeof (T));
+        }
+
+        ~SimdAlignedBuffer64 ()
+        {
+            EXRFreeAligned (_handle);
+            _handle = 0;
+            _buffer = 0;
+        }
+
+        void alloc()
+        {
+            //
+            // Try EXRAllocAligned first - but it might fallback to
+            // unaligned allocs. If so, overalloc.
+            //
+
+            _handle = (char *) EXRAllocAligned
+                (64 * sizeof(T), _SSE_ALIGNMENT);
+
+            if (((size_t)_handle & (_SSE_ALIGNMENT - 1)) == 0)
+            {
+                _buffer = (T *)_handle;
+                return;
+            }
+
+            EXRFreeAligned(_handle);
+            _handle = (char *) EXRAllocAligned
+                (64 * sizeof(T) + _SSE_ALIGNMENT, _SSE_ALIGNMENT);
+
+            char *aligned = _handle;
+
+            while ((size_t)aligned & (_SSE_ALIGNMENT - 1))
+                aligned++;
+
+            _buffer = (T *)aligned;    
+        }
+
+        T     *_buffer;
+
+    private:
+
+        char  *_handle;
+};
+
+typedef SimdAlignedBuffer64<float>          SimdAlignedBuffer64f;
+typedef SimdAlignedBuffer64<unsigned short> SimdAlignedBuffer64us;
+
+namespace {
+
+//
+// Color space conversion, Inverse 709 CSC, Y'CbCr -> R'G'B'
+//
+
+void
+csc709Inverse (float &comp0, float &comp1, float &comp2)
+{
+    float src[3];
+
+    src[0] = comp0;
+    src[1] = comp1;
+    src[2] = comp2;
+
+    comp0 = src[0]                    + 1.5747f * src[2];
+    comp1 = src[0] - 0.1873f * src[1] - 0.4682f * src[2];
+    comp2 = src[0] + 1.8556f * src[1];
+}
+
+#ifndef IMF_HAVE_SSE2
+
+
+//
+// Scalar color space conversion, based on 709 primiary chromaticies.
+// No scaling or offsets, just the matrix
+//
+
+void
+csc709Inverse64 (float *comp0, float *comp1, float *comp2)
+{
+    for (int i = 0; i < 64; ++i)
+        csc709Inverse (comp0[i], comp1[i], comp2[i]);
+}
+
+#else /* IMF_HAVE_SSE2 */
+
+//
+// SSE2 color space conversion
+//
+
+void
+csc709Inverse64 (float *comp0, float *comp1, float *comp2)
+{
+    __m128 c0 = { 1.5747f,  1.5747f,  1.5747f,  1.5747f};
+    __m128 c1 = { 1.8556f,  1.8556f,  1.8556f,  1.8556f};
+    __m128 c2 = {-0.1873f, -0.1873f, -0.1873f, -0.1873f};
+    __m128 c3 = {-0.4682f, -0.4682f, -0.4682f, -0.4682f}; 
+
+    __m128 *r = (__m128 *)comp0;
+    __m128 *g = (__m128 *)comp1;
+    __m128 *b = (__m128 *)comp2;
+    __m128 src[3];
+
+    #define CSC_INVERSE_709_SSE2_LOOP(i)                       \
+            src[0] = r[i];                                     \
+            src[1] = g[i];                                     \
+            src[2] = b[i];                                     \
+                                                               \
+            r[i] = _mm_add_ps (r[i], _mm_mul_ps (src[2], c0)); \
+                                                               \
+            g[i]   = _mm_mul_ps (g[i], c2);                    \
+            src[2] = _mm_mul_ps (src[2], c3);                  \
+            g[i]   = _mm_add_ps (g[i], src[0]);                \
+            g[i]   = _mm_add_ps (g[i], src[2]);                \
+                                                               \
+            b[i] = _mm_mul_ps (c1,   src[1]);                  \
+            b[i] = _mm_add_ps (b[i], src[0]);
+
+    CSC_INVERSE_709_SSE2_LOOP (0)
+    CSC_INVERSE_709_SSE2_LOOP (1)
+    CSC_INVERSE_709_SSE2_LOOP (2)
+    CSC_INVERSE_709_SSE2_LOOP (3)
+
+    CSC_INVERSE_709_SSE2_LOOP (4)
+    CSC_INVERSE_709_SSE2_LOOP (5)
+    CSC_INVERSE_709_SSE2_LOOP (6)
+    CSC_INVERSE_709_SSE2_LOOP (7)
+
+    CSC_INVERSE_709_SSE2_LOOP (8)
+    CSC_INVERSE_709_SSE2_LOOP (9)
+    CSC_INVERSE_709_SSE2_LOOP (10)
+    CSC_INVERSE_709_SSE2_LOOP (11)
+
+    CSC_INVERSE_709_SSE2_LOOP (12)
+    CSC_INVERSE_709_SSE2_LOOP (13)
+    CSC_INVERSE_709_SSE2_LOOP (14)
+    CSC_INVERSE_709_SSE2_LOOP (15)
+}
+
+#endif /* IMF_HAVE_SSE2 */
+
+
+//
+// Color space conversion, Forward 709 CSC, R'G'B' -> Y'CbCr
+//
+// Simple FPU color space conversion. Based on the 709
+// primary chromaticies, with no scaling or offsets.
+//
+
+void
+csc709Forward64 (float *comp0, float *comp1, float *comp2)
+{
+    float src[3];
+
+    for (int i = 0; i<64; ++i)
+    {
+        src[0] = comp0[i];    
+        src[1] = comp1[i]; 
+        src[2] = comp2[i];     
+
+        comp0[i] =  0.2126f * src[0] + 0.7152f * src[1] + 0.0722f * src[2];
+        comp1[i] = -0.1146f * src[0] - 0.3854f * src[1] + 0.5000f * src[2];
+        comp2[i] =  0.5000f * src[0] - 0.4542f * src[1] - 0.0458f * src[2];
+    }
+}
+
+
+//
+// Byte interleaving of 2 byte arrays:
+//    src0 = AAAA 
+//    src1 = BBBB
+//    dst  = ABABABAB
+//
+// numBytes is the size of each of the source buffers
+//
+
+#ifndef IMF_HAVE_SSE2 
+
+// 
+// Scalar default implementation 
+//
+
+void
+interleaveByte2 (char *dst, char *src0, char *src1, int numBytes)
+{
+    for (int x = 0; x < numBytes; ++x)
+    {
+        dst[2 * x]     = src0[x];
+        dst[2 * x + 1] = src1[x];
+    }
+}
+
+#else  /* IMF_HAVE_SSE2 */
+
+// 
+// SSE2 byte interleaving
+//
+
+void
+interleaveByte2 (char *dst, char *src0, char *src1, int numBytes)
+{
+    int dstAlignment  = (size_t)dst  % 16;
+    int src0Alignment = (size_t)src0 % 16;
+    int src1Alignment = (size_t)src1 % 16;
+
+    __m128i *dst_epi8  = (__m128i*)dst;
+    __m128i *src0_epi8 = (__m128i*)src0;
+    __m128i *src1_epi8 = (__m128i*)src1;
+    int sseWidth  =  numBytes / 16;
+
+    if ((!dstAlignment) && (!src0Alignment) && (!src1Alignment))
+    {
+        __m128i tmp0, tmp1;
+
+        //
+        // Aligned loads and stores
+        //
+
+        for (int x = 0; x < sseWidth; ++x)
+        {
+            tmp0 = src0_epi8[x];
+            tmp1 = src1_epi8[x];
+
+            _mm_stream_si128 (&dst_epi8[2 * x],
+                              _mm_unpacklo_epi8 (tmp0, tmp1));
+
+            _mm_stream_si128 (&dst_epi8[2 * x + 1],
+                              _mm_unpackhi_epi8 (tmp0, tmp1));
+        }
+
+        //
+        // Then do run the leftovers one at a time
+        //
+
+        for (int x = 16 * sseWidth; x < numBytes; ++x)
+        {
+            dst[2 * x]     = src0[x];
+            dst[2 * x + 1] = src1[x];
+        }
+    }
+    else if ((!dstAlignment) && (src0Alignment == 8) && (src1Alignment == 8))
+    {
+        //
+        // Aligned stores, but catch up a few values so we can 
+        // use aligned loads
+        //
+    
+        for (int x = 0; x < 8; ++x)
+        {
+            dst[2 * x]     = src0[x];
+            dst[2 * x + 1] = src1[x];
+        }
+
+        dst_epi8  = (__m128i*)&dst[16];
+        src0_epi8 = (__m128i*)&src0[8];
+        src1_epi8 = (__m128i*)&src1[8];
+        sseWidth  =  (numBytes - 8) / 16;
+
+        for (int x=0; x<sseWidth; ++x)
+        {
+            _mm_stream_si128 (&dst_epi8[2 * x],
+                              _mm_unpacklo_epi8 (src0_epi8[x], src1_epi8[x]));
+
+            _mm_stream_si128 (&dst_epi8[2 * x + 1],
+                              _mm_unpackhi_epi8 (src0_epi8[x], src1_epi8[x]));
+        }
+
+        //
+        // Then do run the leftovers one at a time
+        //
+
+        for (int x = 16 * sseWidth + 8; x < numBytes; ++x)
+        {
+            dst[2 * x]     = src0[x];
+            dst[2 * x + 1] = src1[x];
+        }
+    }
+    else
+    {
+        //
+        // Unaligned everything
+        //
+
+        for (int x = 0; x < sseWidth; ++x)
+        {
+            __m128i tmpSrc0_epi8 = _mm_loadu_si128 (&src0_epi8[x]);
+            __m128i tmpSrc1_epi8 = _mm_loadu_si128 (&src1_epi8[x]);
+
+            _mm_storeu_si128 (&dst_epi8[2 * x],
+                              _mm_unpacklo_epi8 (tmpSrc0_epi8, tmpSrc1_epi8));
+
+            _mm_storeu_si128 (&dst_epi8[2 * x + 1],
+                              _mm_unpackhi_epi8 (tmpSrc0_epi8, tmpSrc1_epi8));
+        }
+
+        //
+        // Then do run the leftovers one at a time
+        //
+
+        for (int x = 16 * sseWidth; x < numBytes; ++x)
+        {
+            dst[2 * x]     = src0[x];
+            dst[2 * x + 1] = src1[x];
+        }
+    }
+}
+
+#endif /* IMF_HAVE_SSE2 */
+
+
+//
+// Float -> half float conversion
+//
+// To enable F16C based conversion, we can't rely on compile-time
+// detection, hence the multiple defined versions. Pick one based
+// on runtime cpuid detection.
+//
+
+//
+// Default boring conversion
+//
+
+void 
+convertFloatToHalf64_scalar (unsigned short *dst, float *src)
+{
+    for (int i=0; i<64; ++i)
+        dst[i] = ((half)src[i]).bits();
+}
+
+
+//
+// F16C conversion - Assumes aligned src and dst
+//
+
+void
+convertFloatToHalf64_f16c (unsigned short *dst, float *src)
+{
+    //
+    // Ordinarly, I'd avoid using inline asm and prefer intrinsics. 
+    // However, in order to get the intrinsics, we need to tell 
+    // the compiler to generate VEX instructions.
+    //
+    // (On the GCC side, -mf16c goes ahead and activates -mavc,
+    //  resulting in VEX code. Without -mf16c, no intrinsics..)
+    //
+    // Now, it's quite likely that we'll find ourselves in situations
+    // where we want to build *without* VEX, in order to maintain
+    // maximum compatability. But to get there with intrinsics,
+    // we'd need to break out code into a separate file. Bleh.
+    // I'll take the asm.
+    //
+
+    #if defined IMF_HAVE_GCC_INLINEASM
+        __asm__
+           ("vmovaps       (%0),     %%ymm0         \n"
+            "vmovaps   0x20(%0),     %%ymm1         \n"
+            "vmovaps   0x40(%0),     %%ymm2         \n"
+            "vmovaps   0x60(%0),     %%ymm3         \n"
+            "vcvtps2ph $0,           %%ymm0, %%xmm0 \n"
+            "vcvtps2ph $0,           %%ymm1, %%xmm1 \n"
+            "vcvtps2ph $0,           %%ymm2, %%xmm2 \n"
+            "vcvtps2ph $0,           %%ymm3, %%xmm3 \n"
+            "vmovdqa   %%xmm0,       0x00(%1)       \n"
+            "vmovdqa   %%xmm1,       0x10(%1)       \n"
+            "vmovdqa   %%xmm2,       0x20(%1)       \n"
+            "vmovdqa   %%xmm3,       0x30(%1)       \n"
+            "vmovaps   0x80(%0),     %%ymm0         \n"
+            "vmovaps   0xa0(%0),     %%ymm1         \n"
+            "vmovaps   0xc0(%0),     %%ymm2         \n"
+            "vmovaps   0xe0(%0),     %%ymm3         \n"
+            "vcvtps2ph $0,           %%ymm0, %%xmm0 \n"
+            "vcvtps2ph $0,           %%ymm1, %%xmm1 \n"
+            "vcvtps2ph $0,           %%ymm2, %%xmm2 \n"
+            "vcvtps2ph $0,           %%ymm3, %%xmm3 \n"
+            "vmovdqa   %%xmm0,       0x40(%1)       \n"
+            "vmovdqa   %%xmm1,       0x50(%1)       \n"
+            "vmovdqa   %%xmm2,       0x60(%1)       \n"
+            "vmovdqa   %%xmm3,       0x70(%1)       \n"
+        #ifndef __AVX__
+            "vzeroupper                             \n"
+        #endif /* __AVX__ */
+            : /* Output  */                
+            : /* Input   */ "r"(src), "r"(dst)
+        #ifndef __AVX__
+            : /* Clobber */ "%xmm0", "%xmm1", "%xmm2", "%xmm3", "memory"
+        #else
+            : /* Clobber */ "%ymm0", "%ymm1", "%ymm2", "%ymm3", "memory"
+        #endif /* __AVX__ */
+           );
+    #else
+        convertFloatToHalf64_scalar (dst, src);
+    #endif /* IMF_HAVE_GCC_INLINEASM */
+}
+
+
+//
+// Convert an 8x8 block of HALF from zig-zag order to
+// FLOAT in normal order. The order we want is:
+//
+//          src                           dst 
+//  0  1  2  3  4  5  6  7       0  1  5  6 14 15 27 28
+//  8  9 10 11 12 13 14 15       2  4  7 13 16 26 29 42
+// 16 17 18 19 20 21 22 23       3  8 12 17 25 30 41 43
+// 24 25 26 27 28 29 30 31       9 11 18 24 31 40 44 53  
+// 32 33 34 35 36 37 38 39      10 19 23 32 39 45 52 54
+// 40 41 42 43 44 45 46 47      20 22 33 38 46 51 55 60
+// 48 49 50 51 52 53 54 55      21 34 37 47 50 56 59 61
+// 56 57 58 59 60 61 62 63      35 36 48 49 57 58 62 63
+//
+
+void
+fromHalfZigZag_scalar (unsigned short *src, float *dst)
+{
+    half *srcHalf = (half *)src;
+
+    dst[0] = (float)srcHalf[0];
+    dst[1] = (float)srcHalf[1];
+    dst[2] = (float)srcHalf[5];
+    dst[3] = (float)srcHalf[6];
+    dst[4] = (float)srcHalf[14];
+    dst[5] = (float)srcHalf[15];
+    dst[6] = (float)srcHalf[27];
+    dst[7] = (float)srcHalf[28];
+    dst[8] = (float)srcHalf[2];
+    dst[9] = (float)srcHalf[4];
+
+    dst[10] = (float)srcHalf[7];
+    dst[11] = (float)srcHalf[13];
+    dst[12] = (float)srcHalf[16];
+    dst[13] = (float)srcHalf[26];
+    dst[14] = (float)srcHalf[29];
+    dst[15] = (float)srcHalf[42];
+    dst[16] = (float)srcHalf[3];
+    dst[17] = (float)srcHalf[8];
+    dst[18] = (float)srcHalf[12];
+    dst[19] = (float)srcHalf[17];
+
+    dst[20] = (float)srcHalf[25];
+    dst[21] = (float)srcHalf[30];
+    dst[22] = (float)srcHalf[41];
+    dst[23] = (float)srcHalf[43];
+    dst[24] = (float)srcHalf[9];
+    dst[25] = (float)srcHalf[11];
+    dst[26] = (float)srcHalf[18];
+    dst[27] = (float)srcHalf[24];
+    dst[28] = (float)srcHalf[31];
+    dst[29] = (float)srcHalf[40];
+
+    dst[30] = (float)srcHalf[44];
+    dst[31] = (float)srcHalf[53];
+    dst[32] = (float)srcHalf[10];
+    dst[33] = (float)srcHalf[19];
+    dst[34] = (float)srcHalf[23];
+    dst[35] = (float)srcHalf[32];
+    dst[36] = (float)srcHalf[39];
+    dst[37] = (float)srcHalf[45];
+    dst[38] = (float)srcHalf[52];
+    dst[39] = (float)srcHalf[54];
+
+    dst[40] = (float)srcHalf[20];
+    dst[41] = (float)srcHalf[22];
+    dst[42] = (float)srcHalf[33];
+    dst[43] = (float)srcHalf[38];
+    dst[44] = (float)srcHalf[46];
+    dst[45] = (float)srcHalf[51];
+    dst[46] = (float)srcHalf[55];
+    dst[47] = (float)srcHalf[60];
+    dst[48] = (float)srcHalf[21];
+    dst[49] = (float)srcHalf[34];
+
+    dst[50] = (float)srcHalf[37];
+    dst[51] = (float)srcHalf[47];
+    dst[52] = (float)srcHalf[50];
+    dst[53] = (float)srcHalf[56];
+    dst[54] = (float)srcHalf[59];
+    dst[55] = (float)srcHalf[61];
+    dst[56] = (float)srcHalf[35];
+    dst[57] = (float)srcHalf[36];
+    dst[58] = (float)srcHalf[48];
+    dst[59] = (float)srcHalf[49];
+
+    dst[60] = (float)srcHalf[57];
+    dst[61] = (float)srcHalf[58];
+    dst[62] = (float)srcHalf[62];
+    dst[63] = (float)srcHalf[63];
+}
+
+
+//
+// If we can form the correct ordering in xmm registers,
+// we can use F16C to convert from HALF -> FLOAT. However,
+// making the correct order isn't trivial. 
+// 
+// We want to re-order a source 8x8 matrix from:
+//
+//  0  1  2  3  4  5  6  7       0  1  5  6 14 15 27 28
+//  8  9 10 11 12 13 14 15       2  4  7 13 16 26 29 42
+// 16 17 18 19 20 21 22 23       3  8 12 17 25 30 41 43
+// 24 25 26 27 28 29 30 31       9 11 18 24 31 40 44 53   (A)
+// 32 33 34 35 36 37 38 39  --> 10 19 23 32 39 45 52 54
+// 40 41 42 43 44 45 46 47      20 22 33 38 46 51 55 60
+// 48 49 50 51 52 53 54 55      21 34 37 47 50 56 59 61
+// 56 57 58 59 60 61 62 63      35 36 48 49 57 58 62 63
+//
+// Which looks like a mess, right? 
+//
+// Now, check out the NE/SW diagonals of (A). Along those lines, 
+// we have runs of contiguous values! If we rewrite (A) a bit, we get:
+//
+//  0
+//  1  2
+//  5  4  3
+//  6  7  8  9
+// 14 13 12 11 10
+// 15 16 17 18 19 20
+// 27 26 25 24 23 22 21            (B)
+// 28 29 30 31 32 33 34 35
+//    42 41 40 39 38 37 36
+//       43 44 45 46 47 48
+//          53 52 51 50 49
+//             54 55 56 57
+//                60 59 58
+//                   61 62
+//                      63
+//
+// In this ordering, the columns are the rows (A). If we can 'transpose' 
+// (B), we'll achieve our goal. But we want this to fit nicely into 
+// xmm registers and still be able to load large runs efficiently.  
+// Also, notice that the odd rows are in ascending order, while 
+// the even rows are in descending order. 
+//
+// If we 'fold' the bottom half up into the top, we can preserve ordered
+// runs accross rows, and still keep all the correct values in columns. 
+// After transposing, we'll need to rotate things back into place. 
+// This gives us:
+//
+//  0 | 42   41   40   39   38   37   36
+//  1    2 | 43   44   45   46   47   48
+//  5    4    3 | 53   52   51   50   49
+//  6    7    8    9 | 54   55   56   57      (C)
+// 14   13   12   11   10 | 60   59   58
+// 15   16   17   18   19   20 | 61   62
+// 27   26   25   24   23   22   21 | 61
+// 28   29   30   31   32   33   34   35
+//
+// But hang on. We still have the backwards descending rows to deal with.
+// Lets reverse the even rows so that all values are in ascending order
+//
+//  36   37  38   39   40   41   42 | 0
+//  1    2 | 43   44   45   46   47   48
+//  49   50  51   52   53 |  3    4    5  
+//  6    7    8    9 | 54   55   56   57      (D)
+// 58   59   60 | 10   11   12   13   14  
+// 15   16   17   18   19   20 | 61   62
+// 61 | 21   22   23   24   25   26   27 
+// 28   29   30   31   32   33   34   35
+//
+// If we can form (D),  we will then:
+//   1) Reverse the even rows
+//   2) Transpose
+//   3) Rotate the rows 
+//
+// and we'll have (A).
+//
+
+void 
+fromHalfZigZag_f16c (unsigned short *src, float *dst)
+{
+    #if defined IMF_HAVE_GCC_INLINEASM_64
+        __asm__
+
+           /* x3 <- 0                    
+            * x8 <- [ 0- 7]              
+            * x6 <- [56-63]              
+            * x9 <- [21-28]              
+            * x7 <- [28-35]              
+            * x3 <- [ 6- 9] (lower half) */
+          
+          ("vpxor   %%xmm3,  %%xmm3, %%xmm3   \n"
+           "vmovdqa    (%0), %%xmm8           \n"
+           "vmovdqa 112(%0), %%xmm6           \n"
+           "vmovdqu  42(%0), %%xmm9           \n"
+           "vmovdqu  56(%0), %%xmm7           \n"
+           "vmovq    12(%0), %%xmm3           \n"
+
+           /* Setup rows 0-2 of A in xmm0-xmm2 
+            * x1 <- x8 >> 16 (1 value)     
+            * x2 <- x8 << 32 (2 values)    
+            * x0 <- alignr([35-42], x8, 2) 
+            * x1 <- blend(x1, [41-48])     
+            * x2 <- blend(x2, [49-56])     */
+
+           "vpsrldq      $2, %%xmm8, %%xmm1   \n"      
+           "vpslldq      $4, %%xmm8, %%xmm2   \n"      
+           "vpalignr     $2, 70(%0), %%xmm8, %%xmm0 \n"
+           "vpblendw  $0xfc, 82(%0), %%xmm1, %%xmm1 \n"
+           "vpblendw  $0x1f, 98(%0), %%xmm2, %%xmm2 \n"
+     
+           /* Setup rows 4-6 of A in xmm4-xmm6 
+            * x4 <- x6 >> 32 (2 values)   
+            * x5 <- x6 << 16 (1 value)    
+            * x6 <- alignr(x6,x9,14)      
+            * x4 <- blend(x4, [ 7-14])    
+            * x5 <- blend(x5, [15-22])    */
+
+           "vpsrldq      $4, %%xmm6, %%xmm4         \n"
+           "vpslldq      $2, %%xmm6, %%xmm5         \n"
+           "vpalignr    $14, %%xmm6, %%xmm9, %%xmm6 \n"
+           "vpblendw  $0xf8, 14(%0), %%xmm4, %%xmm4 \n"
+           "vpblendw  $0x3f, 30(%0), %%xmm5, %%xmm5 \n"
+
+           /* Load the upper half of row 3 into xmm3 
+            * x3 <- [54-57] (upper half) */
+
+           "vpinsrq      $1, 108(%0), %%xmm3, %%xmm3\n"
+
+           /* Reverse the even rows. We're not using PSHUFB as
+            * that requires loading an extra constant all the time,
+            * and we're alreadly pretty memory bound.
+            */
+
+           "vpshuflw $0x1b, %%xmm0, %%xmm0          \n" 
+           "vpshuflw $0x1b, %%xmm2, %%xmm2          \n" 
+           "vpshuflw $0x1b, %%xmm4, %%xmm4          \n" 
+           "vpshuflw $0x1b, %%xmm6, %%xmm6          \n" 
+
+           "vpshufhw $0x1b, %%xmm0, %%xmm0          \n" 
+           "vpshufhw $0x1b, %%xmm2, %%xmm2          \n" 
+           "vpshufhw $0x1b, %%xmm4, %%xmm4          \n" 
+           "vpshufhw $0x1b, %%xmm6, %%xmm6          \n" 
+
+           "vpshufd $0x4e, %%xmm0, %%xmm0          \n" 
+           "vpshufd $0x4e, %%xmm2, %%xmm2          \n" 
+           "vpshufd $0x4e, %%xmm4, %%xmm4          \n" 
+           "vpshufd $0x4e, %%xmm6, %%xmm6          \n" 
+
+           /* Transpose xmm0-xmm7 into xmm8-xmm15 */
+
+           "vpunpcklwd %%xmm1, %%xmm0, %%xmm8       \n"
+           "vpunpcklwd %%xmm3, %%xmm2, %%xmm9       \n"
+           "vpunpcklwd %%xmm5, %%xmm4, %%xmm10      \n"
+           "vpunpcklwd %%xmm7, %%xmm6, %%xmm11      \n"
+           "vpunpckhwd %%xmm1, %%xmm0, %%xmm12      \n"
+           "vpunpckhwd %%xmm3, %%xmm2, %%xmm13      \n"
+           "vpunpckhwd %%xmm5, %%xmm4, %%xmm14      \n"
+           "vpunpckhwd %%xmm7, %%xmm6, %%xmm15      \n"
+     
+           "vpunpckldq  %%xmm9,  %%xmm8, %%xmm0     \n"
+           "vpunpckldq %%xmm11, %%xmm10, %%xmm1     \n"
+           "vpunpckhdq  %%xmm9,  %%xmm8, %%xmm2     \n"
+           "vpunpckhdq %%xmm11, %%xmm10, %%xmm3     \n"
+           "vpunpckldq %%xmm13, %%xmm12, %%xmm4     \n"
+           "vpunpckldq %%xmm15, %%xmm14, %%xmm5     \n"
+           "vpunpckhdq %%xmm13, %%xmm12, %%xmm6     \n"
+           "vpunpckhdq %%xmm15, %%xmm14, %%xmm7     \n"
+     
+           "vpunpcklqdq %%xmm1,  %%xmm0, %%xmm8     \n"
+           "vpunpckhqdq %%xmm1,  %%xmm0, %%xmm9     \n"
+           "vpunpcklqdq %%xmm3,  %%xmm2, %%xmm10    \n"
+           "vpunpckhqdq %%xmm3,  %%xmm2, %%xmm11    \n"
+           "vpunpcklqdq %%xmm4,  %%xmm5, %%xmm12    \n"
+           "vpunpckhqdq %%xmm5,  %%xmm4, %%xmm13    \n"
+           "vpunpcklqdq %%xmm7,  %%xmm6, %%xmm14    \n"
+           "vpunpckhqdq %%xmm7,  %%xmm6, %%xmm15    \n"
+
+           /* Rotate the rows to get the correct final order. 
+            * Rotating xmm12 isn't needed, as we can handle
+            * the rotation in the PUNPCKLQDQ above. Rotating
+            * xmm8 isn't needed as it's already in the right order           
+            */
+
+           "vpalignr  $2,  %%xmm9,  %%xmm9,  %%xmm9 \n"
+           "vpalignr  $4, %%xmm10, %%xmm10, %%xmm10 \n"
+           "vpalignr  $6, %%xmm11, %%xmm11, %%xmm11 \n"
+           "vpalignr $10, %%xmm13, %%xmm13, %%xmm13 \n"
+           "vpalignr $12, %%xmm14, %%xmm14, %%xmm14 \n"
+           "vpalignr $14, %%xmm15, %%xmm15, %%xmm15 \n"
+
+            /* Convert from half -> float */
+
+           "vcvtph2ps  %%xmm8, %%ymm8            \n"  
+           "vcvtph2ps  %%xmm9, %%ymm9            \n"
+           "vcvtph2ps %%xmm10, %%ymm10           \n"
+           "vcvtph2ps %%xmm11, %%ymm11           \n"
+           "vcvtph2ps %%xmm12, %%ymm12           \n"
+           "vcvtph2ps %%xmm13, %%ymm13           \n"
+           "vcvtph2ps %%xmm14, %%ymm14           \n"
+           "vcvtph2ps %%xmm15, %%ymm15           \n"
+           
+           /* Move float values to dst */
+
+           "vmovaps    %%ymm8,    (%1)           \n"
+           "vmovaps    %%ymm9,  32(%1)           \n"
+           "vmovaps   %%ymm10,  64(%1)           \n" 
+           "vmovaps   %%ymm11,  96(%1)           \n" 
+           "vmovaps   %%ymm12, 128(%1)           \n" 
+           "vmovaps   %%ymm13, 160(%1)           \n" 
+           "vmovaps   %%ymm14, 192(%1)           \n" 
+           "vmovaps   %%ymm15, 224(%1)           \n"
+        #ifndef __AVX__
+            "vzeroupper                          \n"
+        #endif /* __AVX__ */
+            : /* Output  */                
+            : /* Input   */ "r"(src), "r"(dst)
+            : /* Clobber */ "memory",
+        #ifndef __AVX__
+                            "%xmm0",  "%xmm1",  "%xmm2",  "%xmm3", 
+                            "%xmm4",  "%xmm5",  "%xmm6",  "%xmm7",
+                            "%xmm8",  "%xmm9",  "%xmm10", "%xmm11",
+                            "%xmm12", "%xmm13", "%xmm14", "%xmm15"
+        #else
+                            "%ymm0",  "%ymm1",  "%ymm2",  "%ymm3", 
+                            "%ymm4",  "%ymm5",  "%ymm6",  "%ymm7",
+                            "%ymm8",  "%ymm9",  "%ymm10", "%ymm11",
+                            "%ymm12", "%ymm13", "%ymm14", "%ymm15"
+        #endif /* __AVX__ */
+        );
+
+    #else
+        fromHalfZigZag_scalar(src, dst);
+    #endif /* defined IMF_HAVE_GCC_INLINEASM_64 */
+}
+
+
+//
+// Inverse 8x8 DCT, only inverting the DC. This assumes that
+// all AC frequencies are 0.
+//
+
+#ifndef IMF_HAVE_SSE2
+
+void 
+dctInverse8x8DcOnly (float *data)
+{
+    float val = data[0] * 3.535536e-01f * 3.535536e-01f;
+
+    for (int i = 0; i < 64; ++i)
+        data[i] = val;
+}
+
+#else  /* IMF_HAVE_SSE2 */
+
+void
+dctInverse8x8DcOnly (float *data)
+{
+    __m128 src = _mm_set1_ps (data[0] * 3.535536e-01f * 3.535536e-01f);
+    __m128 *dst = (__m128 *)data;
+
+    for (int i = 0; i < 16; ++i)
+        dst[i] = src;
+}
+
+#endif /* IMF_HAVE_SSE2 */
+
+
+//
+// Full 8x8 Inverse DCT:
+//
+// Simple inverse DCT on an 8x8 block, with scalar ops only.
+//  Operates on data in-place.
+//
+// This is based on the iDCT formuation (y = frequency domain,
+//                                       x = spatial domain)
+//
+//    [x0]    [        ][y0]    [        ][y1] 
+//    [x1] =  [  M1    ][y2]  + [  M2    ][y3] 
+//    [x2]    [        ][y4]    [        ][y5] 
+//    [x3]    [        ][y6]    [        ][y7]
+//
+//    [x7]    [        ][y0]    [        ][y1] 
+//    [x6] =  [  M1    ][y2]  - [  M2    ][y3] 
+//    [x5]    [        ][y4]    [        ][y5] 
+//    [x4]    [        ][y6]    [        ][y7]
+//
+// where M1:             M2:
+//
+//   [a  c  a   f]     [b  d  e  g]
+//   [a  f -a  -c]     [d -g -b -e]
+//   [a -f -a   c]     [e -b  g  d]
+//   [a -c  a  -f]     [g -e  d -b]
+//
+// and the constants are as defined below..
+//
+// If you know how many of the lower rows are zero, that can
+// be passed in to help speed things up. If you don't know, 
+// just set zeroedRows=0.
+//
+
+//
+// Default implementation
+//
+
+template <int zeroedRows>
+void
+dctInverse8x8_scalar (float *data)
+{
+    const float a = .5f * cosf (3.14159f / 4.0f);
+    const float b = .5f * cosf (3.14159f / 16.0f);
+    const float c = .5f * cosf (3.14159f / 8.0f);
+    const float d = .5f * cosf (3.f*3.14159f / 16.0f);
+    const float e = .5f * cosf (5.f*3.14159f / 16.0f);
+    const float f = .5f * cosf (3.f*3.14159f / 8.0f);
+    const float g = .5f * cosf (7.f*3.14159f / 16.0f);
+
+    float alpha[4], beta[4], theta[4], gamma[4];
+
+    float *rowPtr = NULL;
+
+    //
+    // First pass - row wise.
+    //
+    // This looks less-compact than the description above in
+    // an attempt to fold together common sub-expressions.
+    //
+
+    for (int row = 0; row < 8 - zeroedRows; ++row)
+    {
+        rowPtr = data + row * 8;
+
+        alpha[0] = c * rowPtr[2]; 
+        alpha[1] = f * rowPtr[2]; 
+        alpha[2] = c * rowPtr[6]; 
+        alpha[3] = f * rowPtr[6]; 
+
+        beta[0] = b * rowPtr[1] + d * rowPtr[3] + e * rowPtr[5] + g * rowPtr[7];
+        beta[1] = d * rowPtr[1] - g * rowPtr[3] - b * rowPtr[5] - e * rowPtr[7];
+        beta[2] = e * rowPtr[1] - b * rowPtr[3] + g * rowPtr[5] + d * rowPtr[7];
+        beta[3] = g * rowPtr[1] - e * rowPtr[3] + d * rowPtr[5] - b * rowPtr[7];
+
+        theta[0] = a * (rowPtr[0] + rowPtr[4]);
+        theta[3] = a * (rowPtr[0] - rowPtr[4]);
+
+        theta[1] = alpha[0] + alpha[3]; 
+        theta[2] = alpha[1] - alpha[2]; 
+
+
+        gamma[0] = theta[0] + theta[1];
+        gamma[1] = theta[3] + theta[2];
+        gamma[2] = theta[3] - theta[2];
+        gamma[3] = theta[0] - theta[1];
+
+
+        rowPtr[0] = gamma[0] + beta[0];
+        rowPtr[1] = gamma[1] + beta[1];
+        rowPtr[2] = gamma[2] + beta[2];
+        rowPtr[3] = gamma[3] + beta[3];
+
+        rowPtr[4] = gamma[3] - beta[3];
+        rowPtr[5] = gamma[2] - beta[2];
+        rowPtr[6] = gamma[1] - beta[1];
+        rowPtr[7] = gamma[0] - beta[0];
+    }
+
+    //
+    // Second pass - column wise.
+    //
+
+    for (int column = 0; column < 8; ++column)
+    {
+        alpha[0] = c * data[16+column]; 
+        alpha[1] = f * data[16+column]; 
+        alpha[2] = c * data[48+column]; 
+        alpha[3] = f * data[48+column]; 
+
+        beta[0] = b * data[8+column]  + d * data[24+column] +
+                  e * data[40+column] + g * data[56+column];
+
+        beta[1] = d * data[8+column]  - g * data[24+column] -
+                  b * data[40+column] - e * data[56+column];
+
+        beta[2] = e * data[8+column]  - b * data[24+column] + 
+                  g * data[40+column] + d * data[56+column];
+
+        beta[3] = g * data[8+column]  - e * data[24+column] + 
+                  d * data[40+column] - b * data[56+column];
+
+        theta[0] = a * (data[column] + data[32+column]);
+        theta[3] = a * (data[column] - data[32+column]);
+
+        theta[1] = alpha[0] + alpha[3]; 
+        theta[2] = alpha[1] - alpha[2]; 
+
+        gamma[0] = theta[0] + theta[1];
+        gamma[1] = theta[3] + theta[2];
+        gamma[2] = theta[3] - theta[2];
+        gamma[3] = theta[0] - theta[1];
+
+        data[     column] = gamma[0] + beta[0];
+        data[ 8 + column] = gamma[1] + beta[1];
+        data[16 + column] = gamma[2] + beta[2];
+        data[24 + column] = gamma[3] + beta[3];
+
+        data[32 + column] = gamma[3] - beta[3];
+        data[40 + column] = gamma[2] - beta[2];
+        data[48 + column] = gamma[1] - beta[1];
+        data[56 + column] = gamma[0] - beta[0];
+    }
+}
+
+
+//
+// SSE2 Implementation
+//
+
+template <int zeroedRows>
+void
+dctInverse8x8_sse2 (float *data)
+{
+    #ifdef IMF_HAVE_SSE2
+        __m128 a  = {3.535536e-01f,3.535536e-01f,3.535536e-01f,3.535536e-01f};
+        __m128 b  = {4.903927e-01f,4.903927e-01f,4.903927e-01f,4.903927e-01f};
+        __m128 c  = {4.619398e-01f,4.619398e-01f,4.619398e-01f,4.619398e-01f};
+        __m128 d  = {4.157349e-01f,4.157349e-01f,4.157349e-01f,4.157349e-01f};
+        __m128 e  = {2.777855e-01f,2.777855e-01f,2.777855e-01f,2.777855e-01f};
+        __m128 f  = {1.913422e-01f,1.913422e-01f,1.913422e-01f,1.913422e-01f};
+        __m128 g  = {9.754573e-02f,9.754573e-02f,9.754573e-02f,9.754573e-02f};
+
+        __m128 c0 = {3.535536e-01f, 3.535536e-01f, 3.535536e-01f, 3.535536e-01f};
+        __m128 c1 = {4.619398e-01f, 1.913422e-01f,-1.913422e-01f,-4.619398e-01f};
+        __m128 c2 = {3.535536e-01f,-3.535536e-01f,-3.535536e-01f, 3.535536e-01f};
+        __m128 c3 = {1.913422e-01f,-4.619398e-01f, 4.619398e-01f,-1.913422e-01f};
+
+        __m128 c4 = {4.903927e-01f, 4.157349e-01f, 2.777855e-01f, 9.754573e-02f};
+        __m128 c5 = {4.157349e-01f,-9.754573e-02f,-4.903927e-01f,-2.777855e-01f};
+        __m128 c6 = {2.777855e-01f,-4.903927e-01f, 9.754573e-02f, 4.157349e-01f};
+        __m128 c7 = {9.754573e-02f,-2.777855e-01f, 4.157349e-01f,-4.903927e-01f};
+
+        __m128 *srcVec = (__m128 *)data;
+        __m128 x[8], evenSum, oddSum;
+        __m128 in[8], alpha[4], beta[4], theta[4], gamma[4];
+        
+        //
+        // Rows -   
+        //
+        //  Treat this just like matrix-vector multiplication. The
+        //  trick is to note that:
+        //
+        //    [M00 M01 M02 M03][v0]   [(v0 M00) + (v1 M01) + (v2 M02) + (v3 M03)]
+        //    [M10 M11 M12 M13][v1] = [(v0 M10) + (v1 M11) + (v2 M12) + (v3 M13)]
+        //    [M20 M21 M22 M23][v2]   [(v0 M20) + (v1 M21) + (v2 M22) + (v3 M23)]
+        //    [M30 M31 M32 M33][v3]   [(v0 M30) + (v1 M31) + (v2 M32) + (v3 M33)]
+        //
+        // Then, we can fill a register with v_i and multiply by the i-th column
+        // of M, accumulating across all i-s. 
+        //
+        // The kids refer to the populating of a register with a single value
+        // "broadcasting", and it can be done with a shuffle instruction. It
+        // seems to be the slowest part of the whole ordeal.
+        //
+        // Our matrix columns are stored above in c0-c7. c0-3 make up M1, and
+        // c4-7 are from M2.
+        //
+
+        #define DCT_INVERSE_8x8_SS2_ROW_LOOP(i)                             \
+            /*                                                              \
+             * Broadcast the components of the row                          \
+             */                                                             \
+                                                                            \
+            x[0] = _mm_shuffle_ps (srcVec[2 * i],                           \
+                                   srcVec[2 * i],                           \
+                                   _MM_SHUFFLE (0, 0, 0, 0));               \
+                                                                            \
+            x[1] = _mm_shuffle_ps (srcVec[2 * i],                           \
+                                   srcVec[2 * i],                           \
+                                   _MM_SHUFFLE (1, 1, 1, 1));               \
+                                                                            \
+            x[2] = _mm_shuffle_ps (srcVec[2 * i],                           \
+                                   srcVec[2 * i],                           \
+                                   _MM_SHUFFLE (2, 2, 2, 2));               \
+                                                                            \
+            x[3] = _mm_shuffle_ps (srcVec[2 * i],                           \
+                                   srcVec[2 * i],                           \
+                                   _MM_SHUFFLE (3, 3, 3, 3));               \
+                                                                            \
+            x[4] = _mm_shuffle_ps (srcVec[2 * i + 1],                       \
+                                   srcVec[2 * i + 1],                       \
+                                   _MM_SHUFFLE (0, 0, 0, 0));               \
+                                                                            \
+            x[5] = _mm_shuffle_ps (srcVec[2 * i + 1],                       \
+                                   srcVec[2 * i + 1],                       \
+                                   _MM_SHUFFLE (1, 1, 1, 1));               \
+                                                                            \
+            x[6] = _mm_shuffle_ps (srcVec[2 * i + 1],                       \
+                                   srcVec[2 * i + 1],                       \
+                                   _MM_SHUFFLE (2, 2, 2, 2));               \
+                                                                            \
+            x[7] = _mm_shuffle_ps (srcVec[2 * i + 1],                       \
+                                   srcVec[2 * i + 1],                       \
+                                   _MM_SHUFFLE (3, 3, 3, 3));               \
+            /*                                                              \
+             * Multiply the components by each column of the matrix         \
+             */                                                             \
+                                                                            \
+            x[0] = _mm_mul_ps (x[0], c0);                                   \
+            x[2] = _mm_mul_ps (x[2], c1);                                   \
+            x[4] = _mm_mul_ps (x[4], c2);                                   \
+            x[6] = _mm_mul_ps (x[6], c3);                                   \
+                                                                            \
+            x[1] = _mm_mul_ps (x[1], c4);                                   \
+            x[3] = _mm_mul_ps (x[3], c5);                                   \
+            x[5] = _mm_mul_ps (x[5], c6);                                   \
+            x[7] = _mm_mul_ps (x[7], c7);                                   \
+                                                                            \
+            /*                                                              \
+             * Add across                                                   \
+             */                                                             \
+                                                                            \
+            evenSum = _mm_setzero_ps();                                     \
+            evenSum = _mm_add_ps (evenSum, x[0]);                           \
+            evenSum = _mm_add_ps (evenSum, x[2]);                           \
+            evenSum = _mm_add_ps (evenSum, x[4]);                           \
+            evenSum = _mm_add_ps (evenSum, x[6]);                           \
+                                                                            \
+            oddSum = _mm_setzero_ps();                                      \
+            oddSum = _mm_add_ps (oddSum, x[1]);                             \
+            oddSum = _mm_add_ps (oddSum, x[3]);                             \
+            oddSum = _mm_add_ps (oddSum, x[5]);                             \
+            oddSum = _mm_add_ps (oddSum, x[7]);                             \
+                                                                            \
+            /*                                                              \
+             * Final Sum:                                                   \
+             *    out [0, 1, 2, 3] = evenSum + oddSum                       \
+             *    out [7, 6, 5, 4] = evenSum - oddSum                       \
+             */                                                             \
+                                                                            \
+            srcVec[2 * i]     = _mm_add_ps (evenSum, oddSum);               \
+            srcVec[2 * i + 1] = _mm_sub_ps (evenSum, oddSum);               \
+            srcVec[2 * i + 1] = _mm_shuffle_ps (srcVec[2 * i + 1],          \
+                                                srcVec[2 * i + 1],          \
+                                                _MM_SHUFFLE (0, 1, 2, 3));
+
+        switch (zeroedRows)
+        {
+          case 0:
+          default:
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (0)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (1)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (2)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (3)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (4)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (5)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (6)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (7)
+            break;
+
+          case 1:
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (0)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (1)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (2)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (3)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (4)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (5)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (6)
+            break;
+
+          case 2:
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (0)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (1)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (2)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (3)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (4)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (5)
+            break;
+
+          case 3:
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (0)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (1)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (2)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (3)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (4)
+            break;
+
+          case 4:
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (0)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (1)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (2)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (3)
+            break;
+
+          case 5:
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (0)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (1)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (2)
+            break;
+
+          case 6:
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (0)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (1)
+            break;
+
+          case 7:
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (0)
+            break;
+        }
+
+        //
+        // Columns -
+        //
+        // This is slightly more straightforward, if less readable. Here
+        // we just operate on 4 columns at a time, in two batches.
+        //
+        // The slight mess is to try and cache sub-expressions, which
+        // we ignore in the row-wise pass.
+        //
+
+        for (int col = 0; col < 2; ++col)
+        {
+
+            for (int i = 0; i < 8; ++i)
+                in[i] = srcVec[2 * i + col];
+
+            alpha[0] = _mm_mul_ps (c, in[2]);
+            alpha[1] = _mm_mul_ps (f, in[2]);
+            alpha[2] = _mm_mul_ps (c, in[6]);
+            alpha[3] = _mm_mul_ps (f, in[6]);
+
+            beta[0] = _mm_add_ps (_mm_add_ps (_mm_mul_ps (in[1], b),
+                                                          _mm_mul_ps (in[3], d)),
+                                              _mm_add_ps (_mm_mul_ps (in[5], e),
+                                                          _mm_mul_ps (in[7], g)));
+
+            beta[1] = _mm_sub_ps (_mm_sub_ps (_mm_mul_ps (in[1], d),
+                                                          _mm_mul_ps (in[3], g)),
+                                              _mm_add_ps (_mm_mul_ps (in[5], b),
+                                                          _mm_mul_ps (in[7], e)));
+
+            beta[2] = _mm_add_ps (_mm_sub_ps (_mm_mul_ps (in[1], e),
+                                                          _mm_mul_ps (in[3], b)),
+                                              _mm_add_ps (_mm_mul_ps (in[5], g),
+                                                          _mm_mul_ps (in[7], d)));
+
+            beta[3] = _mm_add_ps (_mm_sub_ps (_mm_mul_ps (in[1], g),
+                                                          _mm_mul_ps (in[3], e)),
+                                              _mm_sub_ps (_mm_mul_ps (in[5], d),
+                                                          _mm_mul_ps (in[7], b)));
+
+            theta[0] = _mm_mul_ps (a, _mm_add_ps (in[0], in[4]));
+            theta[3] = _mm_mul_ps (a, _mm_sub_ps (in[0], in[4]));
+
+            theta[1] = _mm_add_ps (alpha[0], alpha[3]);
+            theta[2] = _mm_sub_ps (alpha[1], alpha[2]);
+
+            gamma[0] = _mm_add_ps (theta[0], theta[1]);
+            gamma[1] = _mm_add_ps (theta[3], theta[2]);
+            gamma[2] = _mm_sub_ps (theta[3], theta[2]);
+            gamma[3] = _mm_sub_ps (theta[0], theta[1]);
+
+            srcVec[  col] = _mm_add_ps (gamma[0], beta[0]);
+            srcVec[2+col] = _mm_add_ps (gamma[1], beta[1]);
+            srcVec[4+col] = _mm_add_ps (gamma[2], beta[2]);
+            srcVec[6+col] = _mm_add_ps (gamma[3], beta[3]);
+
+            srcVec[ 8+col] = _mm_sub_ps (gamma[3], beta[3]);
+            srcVec[10+col] = _mm_sub_ps (gamma[2], beta[2]);
+            srcVec[12+col] = _mm_sub_ps (gamma[1], beta[1]);
+            srcVec[14+col] = _mm_sub_ps (gamma[0], beta[0]);
+        }
+
+    #else /* IMF_HAVE_SSE2 */
+
+        dctInverse8x8_scalar<zeroedRows> (data);
+
+    #endif /* IMF_HAVE_SSE2 */
+}
+
+
+//
+// AVX Implementation
+//
+
+#define STR(A) #A
+
+#define IDCT_AVX_SETUP_2_ROWS(_DST0,  _DST1,  _TMP0,  _TMP1, \
+                              _OFF00, _OFF01, _OFF10, _OFF11) \
+    "vmovaps                 " STR(_OFF00) "(%0),  %%xmm" STR(_TMP0) "  \n" \
+    "vmovaps                 " STR(_OFF01) "(%0),  %%xmm" STR(_TMP1) "  \n" \
+    "                                                                                \n" \
+    "vinsertf128  $1, " STR(_OFF10) "(%0), %%ymm" STR(_TMP0) ", %%ymm" STR(_TMP0) "  \n" \
+    "vinsertf128  $1, " STR(_OFF11) "(%0), %%ymm" STR(_TMP1) ", %%ymm" STR(_TMP1) "  \n" \
+    "                                                                                \n" \
+    "vunpcklpd      %%ymm" STR(_TMP1) ",  %%ymm" STR(_TMP0) ",  %%ymm" STR(_DST0) "  \n" \
+    "vunpckhpd      %%ymm" STR(_TMP1) ",  %%ymm" STR(_TMP0) ",  %%ymm" STR(_DST1) "  \n" \
+    "                                                                                \n" \
+    "vunpcklps      %%ymm" STR(_DST1) ",  %%ymm" STR(_DST0) ",  %%ymm" STR(_TMP0) "  \n" \
+    "vunpckhps      %%ymm" STR(_DST1) ",  %%ymm" STR(_DST0) ",  %%ymm" STR(_TMP1) "  \n" \
+    "                                                                                \n" \
+    "vunpcklpd      %%ymm" STR(_TMP1) ",  %%ymm" STR(_TMP0) ",  %%ymm" STR(_DST0) "  \n" \
+    "vunpckhpd      %%ymm" STR(_TMP1) ",  %%ymm" STR(_TMP0) ",  %%ymm" STR(_DST1) "  \n" 
+
+#define IDCT_AVX_MMULT_ROWS(_SRC)                       \
+    /* Broadcast the source values into y12-y15 */      \
+    "vpermilps $0x00, " STR(_SRC) ", %%ymm12       \n"  \
+    "vpermilps $0x55, " STR(_SRC) ", %%ymm13       \n"  \
+    "vpermilps $0xaa, " STR(_SRC) ", %%ymm14       \n"  \
+    "vpermilps $0xff, " STR(_SRC) ", %%ymm15       \n"  \
+                                                        \
+    /* Multiple coefs and the broadcasted values */     \
+    "vmulps    %%ymm12,  %%ymm8, %%ymm12     \n"        \
+    "vmulps    %%ymm13,  %%ymm9, %%ymm13     \n"        \
+    "vmulps    %%ymm14, %%ymm10, %%ymm14     \n"        \
+    "vmulps    %%ymm15, %%ymm11, %%ymm15     \n"        \
+                                                        \
+    /* Accumulate the result back into the source */    \
+    "vaddps    %%ymm13, %%ymm12, %%ymm12      \n"       \
+    "vaddps    %%ymm15, %%ymm14, %%ymm14      \n"       \
+    "vaddps    %%ymm14, %%ymm12, " STR(_SRC) "\n"     
+
+#define IDCT_AVX_EO_TO_ROW_HALVES(_EVEN, _ODD, _FRONT, _BACK)      \
+    "vsubps   " STR(_ODD) "," STR(_EVEN) "," STR(_BACK)  "\n"  \
+    "vaddps   " STR(_ODD) "," STR(_EVEN) "," STR(_FRONT) "\n"  \
+    /* Reverse the back half                                */ \
+    "vpermilps $0x1b," STR(_BACK) "," STR(_BACK) "\n"  
+
+/* In order to allow for path paths when we know certain rows
+ * of the 8x8 block are zero, most of the body of the DCT is
+ * in the following macro. Statements are wrapped in a ROWn()
+ * macro, where n is the lowest row in the 8x8 block in which
+ * they depend.
+ *
+ * This should work for the cases where we have 2-8 full rows.
+ * the 1-row case is special, and we'll handle it seperately.  
+ */
+#define IDCT_AVX_BODY \
+    /* ==============================================               
+     *               Row 1D DCT                                     
+     * ----------------------------------------------
+     */                                                           \
+                                                                  \
+    /* Setup for the row-oriented 1D DCT. Assuming that (%0) holds 
+     * the row-major 8x8 block, load ymm0-3 with the even columns
+     * and ymm4-7 with the odd columns. The lower half of the ymm
+     * holds one row, while the upper half holds the next row.
+     *
+     * If our source is:
+     *    a0 a1 a2 a3   a4 a5 a6 a7
+     *    b0 b1 b2 b3   b4 b5 b6 b7
+     *
+     * We'll be forming:
+     *    a0 a2 a4 a6   b0 b2 b4 b6
+     *    a1 a3 a5 a7   b1 b3 b5 b7
+     */                                                              \
+    ROW0( IDCT_AVX_SETUP_2_ROWS(0, 4, 14, 15,    0,  16,  32,  48) ) \
+    ROW2( IDCT_AVX_SETUP_2_ROWS(1, 5, 12, 13,   64,  80,  96, 112) ) \
+    ROW4( IDCT_AVX_SETUP_2_ROWS(2, 6, 10, 11,  128, 144, 160, 176) ) \
+    ROW6( IDCT_AVX_SETUP_2_ROWS(3, 7,  8,  9,  192, 208, 224, 240) ) \
+                                                                     \
+    /* Multiple the even columns (ymm0-3) by the matrix M1
+     * storing the results back in ymm0-3
+     *
+     * Assume that (%1) holds the matrix in column major order
+     */                                                              \
+    "vbroadcastf128   (%1),  %%ymm8         \n"                      \
+    "vbroadcastf128 16(%1),  %%ymm9         \n"                      \
+    "vbroadcastf128 32(%1), %%ymm10         \n"                      \
+    "vbroadcastf128 48(%1), %%ymm11         \n"                      \
+                                                                     \
+    ROW0( IDCT_AVX_MMULT_ROWS(%%ymm0) )                              \
+    ROW2( IDCT_AVX_MMULT_ROWS(%%ymm1) )                              \
+    ROW4( IDCT_AVX_MMULT_ROWS(%%ymm2) )                              \
+    ROW6( IDCT_AVX_MMULT_ROWS(%%ymm3) )                              \
+                                                                     \
+    /* Repeat, but with the odd columns (ymm4-7) and the 
+     * matrix M2
+     */                                                              \
+    "vbroadcastf128  64(%1),  %%ymm8         \n"                     \
+    "vbroadcastf128  80(%1),  %%ymm9         \n"                     \
+    "vbroadcastf128  96(%1), %%ymm10         \n"                     \
+    "vbroadcastf128 112(%1), %%ymm11         \n"                     \
+                                                                     \
+    ROW0( IDCT_AVX_MMULT_ROWS(%%ymm4) )                              \
+    ROW2( IDCT_AVX_MMULT_ROWS(%%ymm5) )                              \
+    ROW4( IDCT_AVX_MMULT_ROWS(%%ymm6) )                              \
+    ROW6( IDCT_AVX_MMULT_ROWS(%%ymm7) )                              \
+                                                                     \
+    /* Sum the M1 (ymm0-3) and M2 (ymm4-7) results to get the 
+     * front halves of the results, and difference to get the 
+     * back halves. The front halfs end up in ymm0-3, the back
+     * halves end up in ymm12-15. 
+     */                                                                \
+    ROW0( IDCT_AVX_EO_TO_ROW_HALVES(%%ymm0, %%ymm4, %%ymm0, %%ymm12) ) \
+    ROW2( IDCT_AVX_EO_TO_ROW_HALVES(%%ymm1, %%ymm5, %%ymm1, %%ymm13) ) \
+    ROW4( IDCT_AVX_EO_TO_ROW_HALVES(%%ymm2, %%ymm6, %%ymm2, %%ymm14) ) \
+    ROW6( IDCT_AVX_EO_TO_ROW_HALVES(%%ymm3, %%ymm7, %%ymm3, %%ymm15) ) \
+                                                                       \
+    /* Reassemble the rows halves into ymm0-7  */                      \
+    ROW7( "vperm2f128 $0x13, %%ymm3, %%ymm15, %%ymm7   \n" )           \
+    ROW6( "vperm2f128 $0x02, %%ymm3, %%ymm15, %%ymm6   \n" )           \
+    ROW5( "vperm2f128 $0x13, %%ymm2, %%ymm14, %%ymm5   \n" )           \
+    ROW4( "vperm2f128 $0x02, %%ymm2, %%ymm14, %%ymm4   \n" )           \
+    ROW3( "vperm2f128 $0x13, %%ymm1, %%ymm13, %%ymm3   \n" )           \
+    ROW2( "vperm2f128 $0x02, %%ymm1, %%ymm13, %%ymm2   \n" )           \
+    ROW1( "vperm2f128 $0x13, %%ymm0, %%ymm12, %%ymm1   \n" )           \
+    ROW0( "vperm2f128 $0x02, %%ymm0, %%ymm12, %%ymm0   \n" )           \
+                                                                       \
+                                                                       \
+    /* ==============================================
+     *                Column 1D DCT 
+     * ----------------------------------------------
+     */                                                                \
+                                                                       \
+    /* Rows should be in ymm0-7, and M2 columns should still be 
+     * preserved in ymm8-11.  M2 has 4 unique values (and +- 
+     * versions of each), and all (positive) values appear in 
+     * the first column (and row), which is in ymm8.
+     *
+     * For the column-wise DCT, we need to:
+     *   1) Broadcast each element a row of M2 into 4 vectors
+     *   2) Multiple the odd rows (ymm1,3,5,7) by the broadcasts.
+     *   3) Accumulate into ymm12-15 for the odd outputs.
+     *
+     * Instead of doing 16 broadcasts for each element in M2, 
+     * do 4, filling y8-11 with:
+     *
+     *     ymm8:  [ b  b  b  b  | b  b  b  b ]
+     *     ymm9:  [ d  d  d  d  | d  d  d  d ]
+     *     ymm10: [ e  e  e  e  | e  e  e  e ]
+     *     ymm11: [ g  g  g  g  | g  g  g  g ]
+     * 
+     * And deal with the negative values by subtracting during accum.
+     */                                                                \
+    "vpermilps        $0xff,  %%ymm8, %%ymm11  \n"                     \
+    "vpermilps        $0xaa,  %%ymm8, %%ymm10  \n"                     \
+    "vpermilps        $0x55,  %%ymm8, %%ymm9   \n"                     \
+    "vpermilps        $0x00,  %%ymm8, %%ymm8   \n"                     \
+                                                                       \
+    /* This one is easy, since we have ymm12-15 open for scratch   
+     *    ymm12 = b ymm1 + d ymm3 + e ymm5 + g ymm7 
+     */                                                                \
+    ROW1( "vmulps    %%ymm1,  %%ymm8, %%ymm12    \n" )                 \
+    ROW3( "vmulps    %%ymm3,  %%ymm9, %%ymm13    \n" )                 \
+    ROW5( "vmulps    %%ymm5, %%ymm10, %%ymm14    \n" )                 \
+    ROW7( "vmulps    %%ymm7, %%ymm11, %%ymm15    \n" )                 \
+                                                                       \
+    ROW3( "vaddps   %%ymm12, %%ymm13, %%ymm12    \n" )                 \
+    ROW7( "vaddps   %%ymm14, %%ymm15, %%ymm14    \n" )                 \
+    ROW5( "vaddps   %%ymm12, %%ymm14, %%ymm12    \n" )                 \
+                                                                       \
+    /* Tricker, since only y13-15 are open for scratch   
+     *    ymm13 = d ymm1 - g ymm3 - b ymm5 - e ymm7 
+     */                                                                \
+    ROW1( "vmulps    %%ymm1,   %%ymm9, %%ymm13   \n" )                 \
+    ROW3( "vmulps    %%ymm3,  %%ymm11, %%ymm14   \n" )                 \
+    ROW5( "vmulps    %%ymm5,   %%ymm8, %%ymm15   \n" )                 \
+                                                                       \
+    ROW5( "vaddps    %%ymm14, %%ymm15, %%ymm14   \n" )                 \
+    ROW3( "vsubps    %%ymm14, %%ymm13, %%ymm13   \n" )                 \
+                                                                       \
+    ROW7( "vmulps    %%ymm7,  %%ymm10, %%ymm15   \n" )                 \
+    ROW7( "vsubps    %%ymm15, %%ymm13, %%ymm13   \n" )                 \
+                                                                       \
+    /* Tricker still, as only y14-15 are open for scratch   
+     *    ymm14 = e ymm1 - b ymm3 + g ymm5 + d ymm7 
+     */                                                                \
+    ROW1( "vmulps     %%ymm1, %%ymm10,  %%ymm14  \n" )                 \
+    ROW3( "vmulps     %%ymm3,  %%ymm8,  %%ymm15  \n" )                 \
+                                                                       \
+    ROW3( "vsubps    %%ymm15, %%ymm14, %%ymm14   \n" )                 \
+                                                                       \
+    ROW5( "vmulps     %%ymm5, %%ymm11, %%ymm15   \n" )                 \
+    ROW5( "vaddps    %%ymm15, %%ymm14, %%ymm14   \n" )                 \
+                                                                       \
+    ROW7( "vmulps    %%ymm7,   %%ymm9, %%ymm15   \n" )                 \
+    ROW7( "vaddps    %%ymm15, %%ymm14, %%ymm14   \n" )                 \
+                                                                       \
+                                                                       \
+    /* Easy, as we can blow away ymm1,3,5,7 for scratch
+     *    ymm15 = g ymm1 - e ymm3 + d ymm5 - b ymm7 
+     */                                                                \
+    ROW1( "vmulps    %%ymm1, %%ymm11, %%ymm15    \n" )                 \
+    ROW3( "vmulps    %%ymm3, %%ymm10,  %%ymm3    \n" )                 \
+    ROW5( "vmulps    %%ymm5,  %%ymm9,  %%ymm5    \n" )                 \
+    ROW7( "vmulps    %%ymm7,  %%ymm8,  %%ymm7    \n" )                 \
+                                                                       \
+    ROW5( "vaddps   %%ymm15,  %%ymm5, %%ymm15    \n" )                 \
+    ROW7( "vaddps    %%ymm3,  %%ymm7,  %%ymm3    \n" )                 \
+    ROW3( "vsubps    %%ymm3, %%ymm15, %%ymm15    \n" )                 \
+                                                                       \
+                                                                       \
+    /* Load coefs for M1. Because we're going to broadcast
+     * coefs, we don't need to load the actual structure from
+     * M1. Instead, just load enough that we can broadcast.
+     * There are only 6 unique values in M1, but they're in +-
+     * pairs, leaving only 3 unique coefs if we add and subtract 
+     * properly.
+     *
+     * Fill      ymm1 with coef[2] = [ a  a  c  f | a  a  c  f ]
+     * Broadcast ymm5 with           [ f  f  f  f | f  f  f  f ]
+     * Broadcast ymm3 with           [ c  c  c  c | c  c  c  c ]
+     * Broadcast ymm1 with           [ a  a  a  a | a  a  a  a ]
+     */                                                                \
+    "vbroadcastf128   8(%1),  %%ymm1          \n"                      \
+    "vpermilps        $0xff,  %%ymm1, %%ymm5  \n"                      \
+    "vpermilps        $0xaa,  %%ymm1, %%ymm3  \n"                      \
+    "vpermilps        $0x00,  %%ymm1, %%ymm1  \n"                      \
+                                                                       \
+    /* If we expand E = [M1] [x0 x2 x4 x6]^t, we get the following 
+     * common expressions:
+     *
+     *   E_0 = ymm8  = (a ymm0 + a ymm4) + (c ymm2 + f ymm6) 
+     *   E_3 = ymm11 = (a ymm0 + a ymm4) - (c ymm2 + f ymm6)
+     * 
+     *   E_1 = ymm9  = (a ymm0 - a ymm4) + (f ymm2 - c ymm6)
+     *   E_2 = ymm10 = (a ymm0 - a ymm4) - (f ymm2 - c ymm6)
+     *
+     * Afterwards, ymm8-11 will hold the even outputs.
+     */                                                                \
+                                                                       \
+    /*  ymm11 = (a ymm0 + a ymm4),   ymm1 = (a ymm0 - a ymm4) */       \
+    ROW0( "vmulps    %%ymm1,  %%ymm0, %%ymm11   \n" )                  \
+    ROW4( "vmulps    %%ymm1,  %%ymm4,  %%ymm4   \n" )                  \
+    ROW0( "vmovaps   %%ymm11, %%ymm1            \n" )                  \
+    ROW4( "vaddps    %%ymm4, %%ymm11, %%ymm11   \n" )                  \
+    ROW4( "vsubps    %%ymm4,  %%ymm1,  %%ymm1   \n" )                  \
+                                                                       \
+    /* ymm7 = (c ymm2 + f ymm6) */                                     \
+    ROW2( "vmulps    %%ymm3, %%ymm2,  %%ymm7    \n" )                  \
+    ROW6( "vmulps    %%ymm5, %%ymm6,  %%ymm9    \n" )                  \
+    ROW6( "vaddps    %%ymm9, %%ymm7,  %%ymm7    \n" )                  \
+                                                                       \
+    /* E_0 = ymm8  = (a ymm0 + a ymm4) + (c ymm2 + f ymm6) 
+     * E_3 = ymm11 = (a ymm0 + a ymm4) - (c ymm2 + f ymm6) 
+     */                                                                \
+    ROW0( "vmovaps   %%ymm11, %%ymm8            \n" )                  \
+    ROW2( "vaddps     %%ymm7, %%ymm8,  %%ymm8   \n" )                  \
+    ROW2( "vsubps     %%ymm7, %%ymm11, %%ymm11  \n" )                  \
+                                                                       \
+    /* ymm7 = (f ymm2 - c ymm6) */                                     \
+    ROW2( "vmulps     %%ymm5,  %%ymm2, %%ymm7   \n" )                  \
+    ROW6( "vmulps     %%ymm3,  %%ymm6, %%ymm9   \n" )                  \
+    ROW6( "vsubps     %%ymm9,  %%ymm7, %%ymm7   \n" )                  \
+                                                                       \
+    /* E_1 = ymm9  = (a ymm0 - a ymm4) + (f ymm2 - c ymm6) 
+     * E_2 = ymm10 = (a ymm0 - a ymm4) - (f ymm2 - c ymm6)
+     */                                                                \
+    ROW0( "vmovaps   %%ymm1,  %%ymm9            \n" )                  \
+    ROW0( "vmovaps   %%ymm1, %%ymm10            \n" )                  \
+    ROW2( "vaddps    %%ymm7,  %%ymm1,  %%ymm9   \n" )                  \
+    ROW2( "vsubps    %%ymm7,  %%ymm1,  %%ymm10  \n" )                  \
+                                                                       \
+    /* Add the even (ymm8-11) and the odds (ymm12-15), 
+     * placing the results into ymm0-7 
+     */                                                                \
+    "vaddps   %%ymm12,  %%ymm8, %%ymm0       \n"                       \
+    "vaddps   %%ymm13,  %%ymm9, %%ymm1       \n"                       \
+    "vaddps   %%ymm14, %%ymm10, %%ymm2       \n"                       \
+    "vaddps   %%ymm15, %%ymm11, %%ymm3       \n"                       \
+                                                                       \
+    "vsubps   %%ymm12,  %%ymm8, %%ymm7       \n"                       \
+    "vsubps   %%ymm13,  %%ymm9, %%ymm6       \n"                       \
+    "vsubps   %%ymm14, %%ymm10, %%ymm5       \n"                       \
+    "vsubps   %%ymm15, %%ymm11, %%ymm4       \n"                       \
+                                                                       \
+    /* Copy out the results from ymm0-7  */                            \
+    "vmovaps   %%ymm0,    (%0)                   \n"                   \
+    "vmovaps   %%ymm1,  32(%0)                   \n"                   \
+    "vmovaps   %%ymm2,  64(%0)                   \n"                   \
+    "vmovaps   %%ymm3,  96(%0)                   \n"                   \
+    "vmovaps   %%ymm4, 128(%0)                   \n"                   \
+    "vmovaps   %%ymm5, 160(%0)                   \n"                   \
+    "vmovaps   %%ymm6, 192(%0)                   \n"                   \
+    "vmovaps   %%ymm7, 224(%0)                   \n"            
+
+/* Output, input, and clobber (OIC) sections of the inline asm */
+#define IDCT_AVX_OIC(_IN0)                          \
+        : /* Output  */                            \
+        : /* Input   */ "r"(_IN0), "r"(sAvxCoef)      \
+        : /* Clobber */ "memory",                  \
+                        "%xmm0",  "%xmm1",  "%xmm2",  "%xmm3", \
+                        "%xmm4",  "%xmm5",  "%xmm6",  "%xmm7", \
+                        "%xmm8",  "%xmm9",  "%xmm10", "%xmm11",\
+                        "%xmm12", "%xmm13", "%xmm14", "%xmm15" 
+
+/* Include vzeroupper for non-AVX builds                */
+#ifndef __AVX__ 
+    #define IDCT_AVX_ASM(_IN0)   \
+        __asm__(                 \
+            IDCT_AVX_BODY        \
+            "vzeroupper      \n" \
+            IDCT_AVX_OIC(_IN0)   \
+        );                       
+#else /* __AVX__ */
+    #define IDCT_AVX_ASM(_IN0)   \
+        __asm__(                 \
+            IDCT_AVX_BODY        \
+            IDCT_AVX_OIC(_IN0)   \
+        );                       
+#endif /* __AVX__ */
+
+template <int zeroedRows>
+void
+dctInverse8x8_avx (float *data)
+{
+    #if defined IMF_HAVE_GCC_INLINEASM_64
+
+    /* The column-major version of M1, followed by the 
+     * column-major version of M2:
+     *   
+     *          [ a  c  a  f ]          [ b  d  e  g ]
+     *   M1  =  [ a  f -a -c ]    M2 =  [ d -g -b -e ]
+     *          [ a -f -a  c ]          [ e -b  g  d ]
+     *          [ a -c  a -f ]          [ g -e  d -b ]
+     */   
+    const float sAvxCoef[32]  __attribute__((aligned(32))) = {
+        3.535536e-01,  3.535536e-01,  3.535536e-01,  3.535536e-01, /* a  a  a  a */
+        4.619398e-01,  1.913422e-01, -1.913422e-01, -4.619398e-01, /* c  f -f -c */
+        3.535536e-01, -3.535536e-01, -3.535536e-01,  3.535536e-01, /* a -a -a  a */
+        1.913422e-01, -4.619398e-01,  4.619398e-01, -1.913422e-01, /* f -c  c -f */
+
+        4.903927e-01,  4.157349e-01,  2.777855e-01,  9.754573e-02, /* b  d  e  g */
+        4.157349e-01, -9.754573e-02, -4.903927e-01, -2.777855e-01, /* d -g -b -e */
+        2.777855e-01, -4.903927e-01,  9.754573e-02,  4.157349e-01, /* e -b  g  d */
+        9.754573e-02, -2.777855e-01,  4.157349e-01, -4.903927e-01  /* g -e  d -b */
+    };
+
+        #define ROW0(_X) _X
+        #define ROW1(_X) _X
+        #define ROW2(_X) _X
+        #define ROW3(_X) _X 
+        #define ROW4(_X) _X
+        #define ROW5(_X) _X 
+        #define ROW6(_X) _X
+        #define ROW7(_X) _X 
+
+        if (zeroedRows == 0) {
+
+            IDCT_AVX_ASM(data)
+
+        } else if (zeroedRows == 1) {
+
+            #undef  ROW7
+            #define ROW7(_X)
+            IDCT_AVX_ASM(data)
+
+        } else if (zeroedRows == 2) {
+
+            #undef  ROW6
+            #define ROW6(_X)
+            IDCT_AVX_ASM(data)
+
+        } else if (zeroedRows == 3) {
+
+            #undef  ROW5
+            #define ROW5(_X)
+            IDCT_AVX_ASM(data)
+
+        } else if (zeroedRows == 4) {
+
+            #undef  ROW4
+            #define ROW4(_X)
+            IDCT_AVX_ASM(data)
+
+        } else if (zeroedRows == 5) {
+
+            #undef  ROW3
+            #define ROW3(_X)
+            IDCT_AVX_ASM(data)
+
+        } else if (zeroedRows == 6) {
+
+            #undef  ROW2
+            #define ROW2(_X)
+            IDCT_AVX_ASM(data)
+
+        } else if (zeroedRows == 7) {
+
+            __asm__(  
+
+                /* ==============================================
+                 *                Row 1D DCT 
+                 * ----------------------------------------------
+                 */ 
+                IDCT_AVX_SETUP_2_ROWS(0, 4, 14, 15,    0,  16,  32,  48) 
+
+                "vbroadcastf128   (%1),  %%ymm8         \n"
+                "vbroadcastf128 16(%1),  %%ymm9         \n"
+                "vbroadcastf128 32(%1), %%ymm10         \n"
+                "vbroadcastf128 48(%1), %%ymm11         \n"
+
+                /* Stash a vector of [a a a a | a a a a] away  in ymm2 */
+                "vinsertf128 $1,  %%xmm8,  %%ymm8,  %%ymm2 \n"
+
+                IDCT_AVX_MMULT_ROWS(%%ymm0) 
+
+                "vbroadcastf128  64(%1),  %%ymm8         \n"
+                "vbroadcastf128  80(%1),  %%ymm9         \n"
+                "vbroadcastf128  96(%1), %%ymm10         \n"
+                "vbroadcastf128 112(%1), %%ymm11         \n"
+
+                IDCT_AVX_MMULT_ROWS(%%ymm4) 
+
+                IDCT_AVX_EO_TO_ROW_HALVES(%%ymm0, %%ymm4, %%ymm0, %%ymm12) 
+
+                "vperm2f128 $0x02, %%ymm0, %%ymm12, %%ymm0   \n" 
+
+                /* ==============================================
+                 *                Column 1D DCT 
+                 * ----------------------------------------------
+                 */ 
+
+                /* DC only, so multiple by a and we're done */
+                "vmulps   %%ymm2, %%ymm0, %%ymm0  \n"
+
+                /* Copy out results  */
+                "vmovaps %%ymm0,    (%0)          \n"
+                "vmovaps %%ymm0,  32(%0)          \n"
+                "vmovaps %%ymm0,  64(%0)          \n"
+                "vmovaps %%ymm0,  96(%0)          \n"
+                "vmovaps %%ymm0, 128(%0)          \n"
+                "vmovaps %%ymm0, 160(%0)          \n"
+                "vmovaps %%ymm0, 192(%0)          \n"
+                "vmovaps %%ymm0, 224(%0)          \n"
+
+                #ifndef __AVX__
+                    "vzeroupper                   \n" 
+                #endif /* __AVX__ */
+                IDCT_AVX_OIC(data)
+            );
+        } else {
+            assert(false); // Invalid template instance parameter
+        }
+    #else  /* IMF_HAVE_GCC_INLINEASM_64 */
+
+        dctInverse8x8_scalar<zeroedRows>(data);
+
+    #endif /*  IMF_HAVE_GCC_INLINEASM_64 */
+}
+
+
+//
+// Full 8x8 Forward DCT:
+//
+// Base forward 8x8 DCT implementation. Works on the data in-place
+//
+// The implementation describedin Pennebaker + Mitchell,
+//  section 4.3.2, and illustrated in figure 4-7
+//
+// The basic idea is that the 1D DCT math reduces to:
+//
+//   2*out_0            = c_4 [(s_07 + s_34) + (s_12 + s_56)]
+//   2*out_4            = c_4 [(s_07 + s_34) - (s_12 + s_56)]
+//
+//   {2*out_2, 2*out_6} = rot_6 ((d_12 - d_56), (s_07 - s_34))
+//
+//   {2*out_3, 2*out_5} = rot_-3 (d_07 - c_4 (s_12 - s_56),
+//                                d_34 - c_4 (d_12 + d_56))
+//
+//   {2*out_1, 2*out_7} = rot_-1 (d_07 + c_4 (s_12 - s_56),
+//                               -d_34 - c_4 (d_12 + d_56))
+//
+// where:
+//
+//    c_i  = cos(i*pi/16)
+//    s_i  = sin(i*pi/16)
+//
+//    s_ij = in_i + in_j
+//    d_ij = in_i - in_j
+//
+//    rot_i(x, y) = {c_i*x + s_i*y, -s_i*x + c_i*y} 
+//
+// We'll run the DCT in two passes. First, run the 1D DCT on 
+// the rows, in-place. Then, run over the columns in-place, 
+// and be done with it.
+//
+
+#ifndef IMF_HAVE_SSE2
+
+//
+// Default implementation
+//
+
+void 
+dctForward8x8 (float *data)
+{
+    float A0, A1, A2, A3, A4, A5, A6, A7;
+    float K0, K1, rot_x, rot_y;
+
+    float *srcPtr = data;
+    float *dstPtr = data;
+
+    const float c1 = cosf (3.14159f * 1.0f / 16.0f);
+    const float c2 = cosf (3.14159f * 2.0f / 16.0f);
+    const float c3 = cosf (3.14159f * 3.0f / 16.0f);
+    const float c4 = cosf (3.14159f * 4.0f / 16.0f);
+    const float c5 = cosf (3.14159f * 5.0f / 16.0f);
+    const float c6 = cosf (3.14159f * 6.0f / 16.0f);
+    const float c7 = cosf (3.14159f * 7.0f / 16.0f);
+
+    const float c1Half = .5f * c1; 
+    const float c2Half = .5f * c2;
+    const float c3Half = .5f * c3;
+    const float c5Half = .5f * c5;
+    const float c6Half = .5f * c6;
+    const float c7Half = .5f * c7;
+
+    //
+    // First pass - do a 1D DCT over the rows and write the 
+    //              results back in place
+    //
+
+    for (int row=0; row<8; ++row)
+    {
+        float *srcRowPtr = srcPtr + 8 * row;
+        float *dstRowPtr = dstPtr + 8 * row;
+
+        A0 = srcRowPtr[0] + srcRowPtr[7];
+        A1 = srcRowPtr[1] + srcRowPtr[2];
+        A2 = srcRowPtr[1] - srcRowPtr[2];
+        A3 = srcRowPtr[3] + srcRowPtr[4];
+        A4 = srcRowPtr[3] - srcRowPtr[4];
+        A5 = srcRowPtr[5] + srcRowPtr[6];
+        A6 = srcRowPtr[5] - srcRowPtr[6];
+        A7 = srcRowPtr[0] - srcRowPtr[7];      
+
+        K0 = c4 * (A0 + A3); 
+        K1 = c4 * (A1 + A5); 
+
+        dstRowPtr[0] = .5f * (K0 + K1);
+        dstRowPtr[4] = .5f * (K0 - K1);
+
+        //
+        // (2*dst2, 2*dst6) = rot 6 (d12 - d56,  s07 - s34)
+        //
+
+        rot_x = A2 - A6;
+        rot_y = A0 - A3;
+
+        dstRowPtr[2] =  c6Half * rot_x + c2Half * rot_y;
+        dstRowPtr[6] =  c6Half * rot_y - c2Half * rot_x;
+
+        //
+        // K0, K1 are active until after dst[1],dst[7]
+        //  as well as dst[3], dst[5] are computed.
+        //
+
+        K0 = c4 * (A1 - A5);      
+        K1 = -1 * c4 * (A2 + A6); 
+
+        //
+        // Two ways to do a rotation:
+        //
+        //  rot i (x, y) = 
+        //           X =  c_i*x + s_i*y
+        //           Y = -s_i*x + c_i*y
+        //
+        //        OR
+        //
+        //           X = c_i*(x+y) + (s_i-c_i)*y
+        //           Y = c_i*y     - (s_i+c_i)*x
+        //
+        // the first case has 4 multiplies, but fewer constants,
+        // while the 2nd case has fewer multiplies but takes more space.
+
+        //
+        // (2*dst3, 2*dst5) = rot -3 ( d07 - K0,  d34 + K1 )
+        //
+
+        rot_x = A7 - K0;
+        rot_y = A4 + K1;
+
+        dstRowPtr[3] = c3Half * rot_x - c5Half * rot_y;
+        dstRowPtr[5] = c5Half * rot_x + c3Half * rot_y;
+
+        //
+        // (2*dst1, 2*dst7) = rot -1 ( d07 + K0,  K1  - d34 )
+        //
+
+        rot_x = A7 + K0;
+        rot_y = K1 - A4;
+
+        //
+        // A: 4, 7 are inactive. All A's are inactive
+        //
+
+        dstRowPtr[1] = c1Half * rot_x - c7Half * rot_y;
+        dstRowPtr[7] = c7Half * rot_x + c1Half * rot_y;
+    }
+
+    //
+    // Second pass - do the same, but on the columns
+    //
+
+    for (int column = 0; column < 8; ++column)
+    {
+
+        A0 = srcPtr[     column] + srcPtr[56 + column];
+        A7 = srcPtr[     column] - srcPtr[56 + column];
+
+        A1 = srcPtr[ 8 + column] + srcPtr[16 + column];
+        A2 = srcPtr[ 8 + column] - srcPtr[16 + column];
+
+        A3 = srcPtr[24 + column] + srcPtr[32 + column];
+        A4 = srcPtr[24 + column] - srcPtr[32 + column];
+
+        A5 = srcPtr[40 + column] + srcPtr[48 + column];
+        A6 = srcPtr[40 + column] - srcPtr[48 + column];
+
+        K0 = c4 * (A0 + A3); 
+        K1 = c4 * (A1 + A5); 
+
+        dstPtr[   column] = .5f * (K0 + K1);
+        dstPtr[32+column] = .5f * (K0 - K1);
+
+        //
+        // (2*dst2, 2*dst6) = rot 6 ( d12 - d56,  s07 - s34 )
+        //
+
+        rot_x = A2 - A6;
+        rot_y = A0 - A3;
+
+        dstPtr[16+column] = .5f * (c6 * rot_x + c2 * rot_y);
+        dstPtr[48+column] = .5f * (c6 * rot_y - c2 * rot_x);
+
+        //
+        // K0, K1 are active until after dst[1],dst[7]
+        //  as well as dst[3], dst[5] are computed.
+        //
+
+        K0 = c4 * (A1 - A5);      
+        K1 = -1 * c4 * (A2 + A6); 
+
+        //
+        // (2*dst3, 2*dst5) = rot -3 ( d07 - K0,  d34 + K1 )
+        //
+
+        rot_x = A7 - K0;
+        rot_y = A4 + K1;
+
+        dstPtr[24+column] = .5f * (c3 * rot_x - c5 * rot_y);
+        dstPtr[40+column] = .5f * (c5 * rot_x + c3 * rot_y);
+
+        //
+        // (2*dst1, 2*dst7) = rot -1 ( d07 + K0,  K1  - d34 )
+        //
+
+        rot_x = A7 + K0;
+        rot_y = K1 - A4;
+
+        dstPtr[ 8+column] = .5f * (c1 * rot_x - c7 * rot_y);
+        dstPtr[56+column] = .5f * (c7 * rot_x + c1 * rot_y);
+    }
+}
+
+#else  /* IMF_HAVE_SSE2 */
+
+//
+// SSE2 implementation
+//
+// Here, we're always doing a column-wise operation
+// plus transposes. This might be faster to do differently
+// between rows-wise and column-wise
+//
+
+void 
+dctForward8x8 (float *data)
+{
+    __m128 *srcVec = (__m128 *)data;
+    __m128  a0Vec, a1Vec, a2Vec, a3Vec, a4Vec, a5Vec, a6Vec, a7Vec;
+    __m128  k0Vec, k1Vec, rotXVec, rotYVec;
+    __m128  transTmp[4], transTmp2[4];
+
+    __m128  c4Vec     = { .70710678f,  .70710678f,  .70710678f,  .70710678f};
+    __m128  c4NegVec  = {-.70710678f, -.70710678f, -.70710678f, -.70710678f};
+
+    __m128  c1HalfVec = {.490392640f, .490392640f, .490392640f, .490392640f}; 
+    __m128  c2HalfVec = {.461939770f, .461939770f, .461939770f, .461939770f};
+    __m128  c3HalfVec = {.415734810f, .415734810f, .415734810f, .415734810f}; 
+    __m128  c5HalfVec = {.277785120f, .277785120f, .277785120f, .277785120f}; 
+    __m128  c6HalfVec = {.191341720f, .191341720f, .191341720f, .191341720f};
+    __m128  c7HalfVec = {.097545161f, .097545161f, .097545161f, .097545161f}; 
+
+    __m128  halfVec   = {.5f, .5f, .5f, .5f};
+
+    for (int iter = 0; iter < 2; ++iter)
+    {
+        //
+        //  Operate on 4 columns at a time. The
+        //    offsets into our row-major array are:
+        //                  0:  0      1
+        //                  1:  2      3
+        //                  2:  4      5
+        //                  3:  6      7
+        //                  4:  8      9
+        //                  5: 10     11
+        //                  6: 12     13
+        //                  7: 14     15
+        //
+
+        for (int pass=0; pass<2; ++pass)
+        {
+            a0Vec = _mm_add_ps (srcVec[ 0 + pass], srcVec[14 + pass]);
+            a1Vec = _mm_add_ps (srcVec[ 2 + pass], srcVec[ 4 + pass]);
+            a3Vec = _mm_add_ps (srcVec[ 6 + pass], srcVec[ 8 + pass]);
+            a5Vec = _mm_add_ps (srcVec[10 + pass], srcVec[12 + pass]);
+ 
+            a7Vec = _mm_sub_ps (srcVec[ 0 + pass], srcVec[14 + pass]);
+            a2Vec = _mm_sub_ps (srcVec[ 2 + pass], srcVec[ 4 + pass]);
+            a4Vec = _mm_sub_ps (srcVec[ 6 + pass], srcVec[ 8 + pass]);
+            a6Vec = _mm_sub_ps (srcVec[10 + pass], srcVec[12 + pass]);
+
+            //
+            // First stage; Compute out_0 and out_4
+            //
+
+            k0Vec = _mm_add_ps (a0Vec, a3Vec);
+            k1Vec = _mm_add_ps (a1Vec, a5Vec);
+
+            k0Vec = _mm_mul_ps (c4Vec, k0Vec);
+            k1Vec = _mm_mul_ps (c4Vec, k1Vec);
+
+            srcVec[0 + pass] = _mm_add_ps (k0Vec, k1Vec);
+            srcVec[8 + pass] = _mm_sub_ps (k0Vec, k1Vec);
+
+            srcVec[0 + pass] = _mm_mul_ps (srcVec[0 + pass], halfVec );
+            srcVec[8 + pass] = _mm_mul_ps (srcVec[8 + pass], halfVec );
+
+
+            //
+            // Second stage; Compute out_2 and out_6
+            //
+            
+            k0Vec = _mm_sub_ps (a2Vec, a6Vec);
+            k1Vec = _mm_sub_ps (a0Vec, a3Vec);
+
+            srcVec[ 4 + pass] = _mm_add_ps (_mm_mul_ps (c6HalfVec, k0Vec),
+                                            _mm_mul_ps (c2HalfVec, k1Vec));
+
+            srcVec[12 + pass] = _mm_sub_ps (_mm_mul_ps (c6HalfVec, k1Vec), 
+                                            _mm_mul_ps (c2HalfVec, k0Vec));
+
+            //
+            // Precompute K0 and K1 for the remaining stages
+            //
+
+            k0Vec = _mm_mul_ps (_mm_sub_ps (a1Vec, a5Vec), c4Vec);
+            k1Vec = _mm_mul_ps (_mm_add_ps (a2Vec, a6Vec), c4NegVec); 
+
+            //
+            // Third Stage, compute out_3 and out_5
+            //
+
+            rotXVec = _mm_sub_ps (a7Vec, k0Vec);
+            rotYVec = _mm_add_ps (a4Vec, k1Vec);
+
+            srcVec[ 6 + pass] = _mm_sub_ps (_mm_mul_ps (c3HalfVec, rotXVec),
+                                            _mm_mul_ps (c5HalfVec, rotYVec));
+
+            srcVec[10 + pass] = _mm_add_ps (_mm_mul_ps (c5HalfVec, rotXVec),
+                                            _mm_mul_ps (c3HalfVec, rotYVec));
+
+            //
+            // Fourth Stage, compute out_1 and out_7
+            //
+
+            rotXVec = _mm_add_ps (a7Vec, k0Vec);
+            rotYVec = _mm_sub_ps (k1Vec, a4Vec);
+
+            srcVec[ 2 + pass] = _mm_sub_ps (_mm_mul_ps (c1HalfVec, rotXVec),
+                                            _mm_mul_ps (c7HalfVec, rotYVec));
+
+            srcVec[14 + pass] = _mm_add_ps (_mm_mul_ps (c7HalfVec, rotXVec), 
+                                            _mm_mul_ps (c1HalfVec, rotYVec));
+        }
+
+        //
+        // Transpose the matrix, in 4x4 blocks. So, if we have our
+        // 8x8 matrix divied into 4x4 blocks:
+        //
+        //         M0 | M1         M0t | M2t
+        //        ----+---   -->  -----+------
+        //         M2 | M3         M1t | M3t
+        //
+
+        //
+        // M0t, done in place, the first half.
+        //
+
+        transTmp[0] = _mm_shuffle_ps (srcVec[0], srcVec[2], 0x44);
+        transTmp[1] = _mm_shuffle_ps (srcVec[4], srcVec[6], 0x44);
+        transTmp[3] = _mm_shuffle_ps (srcVec[4], srcVec[6], 0xEE);
+        transTmp[2] = _mm_shuffle_ps (srcVec[0], srcVec[2], 0xEE);
+
+        //
+        // M3t, also done in place, the first half.
+        //
+
+        transTmp2[0] = _mm_shuffle_ps (srcVec[ 9], srcVec[11], 0x44);
+        transTmp2[1] = _mm_shuffle_ps (srcVec[13], srcVec[15], 0x44);
+        transTmp2[2] = _mm_shuffle_ps (srcVec[ 9], srcVec[11], 0xEE);
+        transTmp2[3] = _mm_shuffle_ps (srcVec[13], srcVec[15], 0xEE);
+
+        //
+        // M0t, the second half.
+        //
+
+        srcVec[0] = _mm_shuffle_ps (transTmp[0], transTmp[1], 0x88);
+        srcVec[4] = _mm_shuffle_ps (transTmp[2], transTmp[3], 0x88);
+        srcVec[2] = _mm_shuffle_ps (transTmp[0], transTmp[1], 0xDD);
+        srcVec[6] = _mm_shuffle_ps (transTmp[2], transTmp[3], 0xDD);
+
+        //
+        // M3t, the second half.
+        //
+
+        srcVec[ 9] = _mm_shuffle_ps (transTmp2[0], transTmp2[1], 0x88);
+        srcVec[13] = _mm_shuffle_ps (transTmp2[2], transTmp2[3], 0x88);
+        srcVec[11] = _mm_shuffle_ps (transTmp2[0], transTmp2[1], 0xDD);
+        srcVec[15] = _mm_shuffle_ps (transTmp2[2], transTmp2[3], 0xDD);
+
+        //
+        // M1 and M2 need to be done at the same time, because we're
+        //  swapping. 
+        //
+        // First, the first half of M1t
+        //
+
+        transTmp[0] = _mm_shuffle_ps (srcVec[1], srcVec[3], 0x44);
+        transTmp[1] = _mm_shuffle_ps (srcVec[5], srcVec[7], 0x44);
+        transTmp[2] = _mm_shuffle_ps (srcVec[1], srcVec[3], 0xEE);
+        transTmp[3] = _mm_shuffle_ps (srcVec[5], srcVec[7], 0xEE);
+
+        //
+        // And the first half of M2t
+        //
+
+        transTmp2[0] = _mm_shuffle_ps (srcVec[ 8], srcVec[10], 0x44);
+        transTmp2[1] = _mm_shuffle_ps (srcVec[12], srcVec[14], 0x44);
+        transTmp2[2] = _mm_shuffle_ps (srcVec[ 8], srcVec[10], 0xEE);
+        transTmp2[3] = _mm_shuffle_ps (srcVec[12], srcVec[14], 0xEE);
+
+        //
+        // Second half of M1t
+        //
+
+        srcVec[ 8] = _mm_shuffle_ps (transTmp[0], transTmp[1], 0x88);
+        srcVec[12] = _mm_shuffle_ps (transTmp[2], transTmp[3], 0x88);
+        srcVec[10] = _mm_shuffle_ps (transTmp[0], transTmp[1], 0xDD);
+        srcVec[14] = _mm_shuffle_ps (transTmp[2], transTmp[3], 0xDD);
+
+        //
+        // Second half of M2
+        //
+
+        srcVec[1] = _mm_shuffle_ps (transTmp2[0], transTmp2[1], 0x88);
+        srcVec[5] = _mm_shuffle_ps (transTmp2[2], transTmp2[3], 0x88);
+        srcVec[3] = _mm_shuffle_ps (transTmp2[0], transTmp2[1], 0xDD);
+        srcVec[7] = _mm_shuffle_ps (transTmp2[2], transTmp2[3], 0xDD);
+    }
+}
+
+#endif /* IMF_HAVE_SSE2 */
+
+} // anonymous namespace
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif
diff --git a/Source/OpenEXR/IlmImf/ImfEnvmap.cpp b/Source/OpenEXR/IlmImf/ImfEnvmap.cpp
index fdb04ac..f962fc9 100644
--- a/Source/OpenEXR/IlmImf/ImfEnvmap.cpp
+++ b/Source/OpenEXR/IlmImf/ImfEnvmap.cpp
@@ -39,15 +39,20 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfEnvmap.h>
+#include "ImfEnvmap.h"
 #include "ImathFun.h"
+#include "ImfNamespace.h"
+
 #include <algorithm>
 #include <math.h>
 
 using namespace std;
-using namespace Imath;
+using namespace IMATH_NAMESPACE;
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
 
-namespace Imf {
 namespace LatLongMap {
 
 V2f	
@@ -72,9 +77,9 @@ latLong (const Box2i &dataWindow, const V2f &pixelPosition)
 
     if (dataWindow.max.y > dataWindow.min.y)
     {
-	latitude = -M_PI *
-		  ((pixelPosition.y  - dataWindow.min.y) /
-		   (dataWindow.max.y - dataWindow.min.y) - 0.5f);
+        latitude = -1 * float(M_PI) *
+            ((pixelPosition.y  - dataWindow.min.y) /
+            (dataWindow.max.y - dataWindow.min.y) - 0.5f);
     }
     else
     {
@@ -83,7 +88,7 @@ latLong (const Box2i &dataWindow, const V2f &pixelPosition)
 
     if (dataWindow.max.x > dataWindow.min.x)
     {
-	longitude = -2 * M_PI *
+	longitude = -2 * float(M_PI) *
 		   ((pixelPosition.x  - dataWindow.min.x) /
 		    (dataWindow.max.x - dataWindow.min.x) - 0.5f);
     }
@@ -99,8 +104,8 @@ latLong (const Box2i &dataWindow, const V2f &pixelPosition)
 V2f
 pixelPosition (const Box2i &dataWindow, const V2f &latLong)
 {
-    float x = latLong.y / (-2 * M_PI) + 0.5f;
-    float y = latLong.x / -M_PI + 0.5f;
+    float x = latLong.y / (-2 * float(M_PI)) + 0.5f;
+    float y = latLong.x / (-1 * float(M_PI)) + 0.5f;
 
     return V2f (x * (dataWindow.max.x - dataWindow.min.x) + dataWindow.min.x,
 		y * (dataWindow.max.y - dataWindow.min.y) + dataWindow.min.y);
@@ -325,4 +330,6 @@ direction (CubeMapFace face, const Box2i &dataWindow, const V2f &positionInFace)
 }
 
 } // namespace CubeMap
-} // namespace Imf
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfEnvmap.h b/Source/OpenEXR/IlmImf/ImfEnvmap.h
index 30c61e7..16e4ee3 100644
--- a/Source/OpenEXR/IlmImf/ImfEnvmap.h
+++ b/Source/OpenEXR/IlmImf/ImfEnvmap.h
@@ -73,8 +73,11 @@
 //-----------------------------------------------------------------------------
 
 #include "ImathBox.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
 
-namespace Imf {
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 //--------------------------------
 // Supported environment map types
@@ -116,7 +119,8 @@ namespace LatLongMap
     // and longitude.
     //----------------------------------------------------
 
-    Imath::V2f		latLong (const Imath::V3f &direction);
+    IMF_EXPORT 
+    IMATH_NAMESPACE::V2f		latLong (const IMATH_NAMESPACE::V3f &direction);
 
 
     //--------------------------------------------------------
@@ -125,8 +129,9 @@ namespace LatLongMap
     // and longitude.
     //--------------------------------------------------------
 
-    Imath::V2f		latLong (const Imath::Box2i &dataWindow,
-				 const Imath::V2f &pixelPosition);
+    IMF_EXPORT 
+    IMATH_NAMESPACE::V2f		latLong (const IMATH_NAMESPACE::Box2i &dataWindow,
+				 const IMATH_NAMESPACE::V2f &pixelPosition);
 
 
     //-------------------------------------------------------------
@@ -134,8 +139,9 @@ namespace LatLongMap
     // longitude and latitude, into a corresponding pixel position.
     //-------------------------------------------------------------
 
-    Imath::V2f		pixelPosition (const Imath::Box2i &dataWindow,
-				       const Imath::V2f &latLong);
+    IMF_EXPORT 
+    IMATH_NAMESPACE::V2f		pixelPosition (const IMATH_NAMESPACE::Box2i &dataWindow,
+				       const IMATH_NAMESPACE::V2f &latLong);
 
 
     //-----------------------------------------------------
@@ -144,8 +150,9 @@ namespace LatLongMap
     // to pixelPosition(dw,latLong(dw,dir)).
     //-----------------------------------------------------
 
-    Imath::V2f		pixelPosition (const Imath::Box2i &dataWindow,
-				       const Imath::V3f &direction);
+    IMF_EXPORT 
+    IMATH_NAMESPACE::V2f		pixelPosition (const IMATH_NAMESPACE::Box2i &dataWindow,
+				       const IMATH_NAMESPACE::V3f &direction);
 
 
     //--------------------------------------------------------
@@ -153,8 +160,9 @@ namespace LatLongMap
     // map into a corresponding 3D direction.
     //--------------------------------------------------------
 
-    Imath::V3f		direction (const Imath::Box2i &dataWindow,
-				   const Imath::V2f &pixelPosition);
+    IMF_EXPORT 
+    IMATH_NAMESPACE::V3f		direction (const IMATH_NAMESPACE::Box2i &dataWindow,
+				   const IMATH_NAMESPACE::V2f &pixelPosition);
 }
 
 
@@ -260,7 +268,8 @@ namespace CubeMap
     // Width and height of a cube's face, in pixels
     //---------------------------------------------
 
-    int			sizeOfFace (const Imath::Box2i &dataWindow);
+    IMF_EXPORT 
+    int			sizeOfFace (const IMATH_NAMESPACE::Box2i &dataWindow);
 
 
     //------------------------------------------
@@ -268,8 +277,9 @@ namespace CubeMap
     // that is covered by the specified face.
     //------------------------------------------
 
-    Imath::Box2i	dataWindowForFace (CubeMapFace face,
-					   const Imath::Box2i &dataWindow);
+    IMF_EXPORT 
+    IMATH_NAMESPACE::Box2i	dataWindowForFace (CubeMapFace face,
+					   const IMATH_NAMESPACE::Box2i &dataWindow);
 
 
     //----------------------------------------------------
@@ -279,9 +289,10 @@ namespace CubeMap
     // in the environment map.
     //----------------------------------------------------
 
-    Imath::V2f		pixelPosition (CubeMapFace face,
-				       const Imath::Box2i &dataWindow,
-				       Imath::V2f positionInFace);
+    IMF_EXPORT 
+    IMATH_NAMESPACE::V2f		pixelPosition (CubeMapFace face,
+				       const IMATH_NAMESPACE::Box2i &dataWindow,
+				       IMATH_NAMESPACE::V2f positionInFace);
 
 
     //--------------------------------------------------------------
@@ -300,10 +311,11 @@ namespace CubeMap
     //
     //--------------------------------------------------------------
 
-    void		faceAndPixelPosition (const Imath::V3f &direction,
-					      const Imath::Box2i &dataWindow,
+    IMF_EXPORT 
+    void		faceAndPixelPosition (const IMATH_NAMESPACE::V3f &direction,
+					      const IMATH_NAMESPACE::Box2i &dataWindow,
 					      CubeMapFace &face,
-					      Imath::V2f &positionInFace);
+					      IMATH_NAMESPACE::V2f &positionInFace);
 
    
     // --------------------------------------------------------
@@ -311,12 +323,14 @@ namespace CubeMap
     // compute the corresponding 3D direction.
     // --------------------------------------------------------
 
-    Imath::V3f		direction (CubeMapFace face,
-				   const Imath::Box2i &dataWindow,
-				   const Imath::V2f &positionInFace);
+    IMF_EXPORT 
+    IMATH_NAMESPACE::V3f		direction (CubeMapFace face,
+				   const IMATH_NAMESPACE::Box2i &dataWindow,
+				   const IMATH_NAMESPACE::V2f &positionInFace);
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfEnvmapAttribute.cpp b/Source/OpenEXR/IlmImf/ImfEnvmapAttribute.cpp
index 03a7928..b6f88c2 100644
--- a/Source/OpenEXR/IlmImf/ImfEnvmapAttribute.cpp
+++ b/Source/OpenEXR/IlmImf/ImfEnvmapAttribute.cpp
@@ -42,8 +42,9 @@
 #include <ImfEnvmapAttribute.h>
 
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
+using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;
 
 template <>
 const char *
@@ -55,7 +56,7 @@ EnvmapAttribute::staticTypeName ()
 
 template <>
 void
-EnvmapAttribute::writeValueTo (OStream &os, int version) const
+EnvmapAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     unsigned char tmp = _value;
     Xdr::write <StreamIO> (os, tmp);
@@ -64,7 +65,7 @@ EnvmapAttribute::writeValueTo (OStream &os, int version) const
 
 template <>
 void
-EnvmapAttribute::readValueFrom (IStream &is, int size, int version)
+EnvmapAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     unsigned char tmp;
     Xdr::read <StreamIO> (is, tmp);
@@ -72,4 +73,4 @@ EnvmapAttribute::readValueFrom (IStream &is, int size, int version)
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT 
diff --git a/Source/OpenEXR/IlmImf/ImfEnvmapAttribute.h b/Source/OpenEXR/IlmImf/ImfEnvmapAttribute.h
index 716883f..0d0129b 100644
--- a/Source/OpenEXR/IlmImf/ImfEnvmapAttribute.h
+++ b/Source/OpenEXR/IlmImf/ImfEnvmapAttribute.h
@@ -42,24 +42,27 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfAttribute.h>
-#include <ImfEnvmap.h>
+#include "ImfAttribute.h"
+#include "ImfEnvmap.h"
+#include "ImfExport.h"
 
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-namespace Imf {
 
+typedef TypedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::Envmap> EnvmapAttribute;
 
-typedef TypedAttribute<Envmap> EnvmapAttribute;
-template <> const char *EnvmapAttribute::staticTypeName ();
-template <> void EnvmapAttribute::writeValueTo (OStream &, int) const;
-template <> void EnvmapAttribute::readValueFrom (IStream &, int, int);
+template <> IMF_EXPORT const char *EnvmapAttribute::staticTypeName ();
 
+template <> IMF_EXPORT
+void EnvmapAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &,
+                                    int) const;
 
-} // namespace Imf
+template <> IMF_EXPORT
+void EnvmapAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &,
+                                     int,
+                                     int);
 
-// Metrowerks compiler wants the .cpp file inlined, too
-#ifdef __MWERKS__
-#include <ImfEnvmapAttribute.cpp>
-#endif
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfExport.h b/Source/OpenEXR/IlmImf/ImfExport.h
new file mode 100644
index 0000000..6563fd5
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfExport.h
@@ -0,0 +1,46 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2012, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission. 
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#if defined(OPENEXR_DLL)
+    #if defined(ILMIMF_EXPORTS)
+	    #define IMF_EXPORT __declspec(dllexport)
+        #define IMF_EXPORT_CONST extern __declspec(dllexport)
+    #else
+	    #define IMF_EXPORT __declspec(dllimport)
+	    #define IMF_EXPORT_CONST extern __declspec(dllimport)
+    #endif
+#else
+    #define IMF_EXPORT
+    #define IMF_EXPORT_CONST extern const
+#endif
diff --git a/Source/OpenEXR/IlmImf/ImfFastHuf.cpp b/Source/OpenEXR/IlmImf/ImfFastHuf.cpp
new file mode 100644
index 0000000..86c84dc
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfFastHuf.cpp
@@ -0,0 +1,768 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2009-2014 DreamWorks Animation LLC. 
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of DreamWorks Animation nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#include "ImfFastHuf.h"
+#include <Iex.h>
+
+#include <string.h>
+#include <assert.h>
+#include <math.h>
+#include <vector>
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+//
+// Adapted from hufUnpackEncTable - 
+// We don't need to reconstruct the code book, just the encoded
+// lengths for each symbol. From the lengths, we can build the
+// base + offset tables. This should be a bit more efficient
+// for sparse code books.
+// 
+//   table     - ptr to the start of the code length data. Will be
+//               updated as we decode data
+//
+//   numBytes  - size of the encoded table (I think)?
+//
+//   minSymbol - smallest symbol in the code book
+//
+//   maxSymbol - largest symbol in the code book. 
+//
+//   rleSymbol - the symbol to trigger RLE in the encoded bitstream
+//
+
+FastHufDecoder::FastHufDecoder
+    (const char *&table,
+     int numBytes,
+     int minSymbol,
+     int maxSymbol,
+     int rleSymbol)
+:
+    _rleSymbol (rleSymbol),
+    _numSymbols (0),
+    _minCodeLength (255),
+    _maxCodeLength (0),
+    _idToSymbol (0)
+{
+    //
+    // List of symbols that we find with non-zero code lengths
+    // (listed in the order we find them). Store these in the
+    // same format as the code book stores codes + lengths - 
+    // low 6 bits are the length, everything above that is
+    // the symbol.
+    //
+
+    std::vector<Int64> symbols;
+
+    //
+    // The 'base' table is the minimum code at each code length. base[i]
+    // is the smallest code (numerically) of length i.
+    //
+
+    Int64 base[MAX_CODE_LEN + 1];     
+
+    //
+    // The 'offset' table is the position (in sorted order) of the first id
+    // of a given code lenght. Array is indexed by code length, like base.  
+    //
+
+    Int64 offset[MAX_CODE_LEN + 1];   
+
+    //
+    // Count of how many codes at each length there are. Array is 
+    // indexed by code length, like base and offset.
+    //
+
+    size_t codeCount[MAX_CODE_LEN + 1];    
+
+    for (int i = 0; i <= MAX_CODE_LEN; ++i)
+    {
+        codeCount[i] = 0;
+        base[i]      = 0xffffffffffffffffL;
+        offset[i]    = 0;
+    }
+
+    //
+    // Count the number of codes, the min/max code lengths, the number of
+    // codes with each length, and record symbols with non-zero code
+    // length as we find them.
+    //
+
+    const char *currByte     = table;
+    Int64       currBits     = 0;
+    int         currBitCount = 0;
+
+    const int SHORT_ZEROCODE_RUN = 59;
+    const int LONG_ZEROCODE_RUN  = 63;
+    const int SHORTEST_LONG_RUN  = 2 + LONG_ZEROCODE_RUN - SHORT_ZEROCODE_RUN;
+
+    for (Int64 symbol = minSymbol; symbol <= maxSymbol; symbol++)
+    {
+        if (currByte - table > numBytes)
+        {
+            throw Iex::InputExc ("Error decoding Huffman table "
+                                 "(Truncated table data).");
+        }
+
+        //
+        // Next code length - either:
+        //       0-58  (literal code length)
+        //       59-62 (various lengths runs of 0)
+        //       63    (run of n 0's, with n is the next 8 bits)
+        //
+
+        Int64 codeLen = readBits (6, currBits, currBitCount, currByte);
+
+        if (codeLen == (Int64) LONG_ZEROCODE_RUN)
+        {
+            if (currByte - table > numBytes)
+            {
+                throw Iex::InputExc ("Error decoding Huffman table "
+                                     "(Truncated table data).");
+            }
+
+            int runLen = readBits (8, currBits, currBitCount, currByte) +
+                         SHORTEST_LONG_RUN;
+
+            if (symbol + runLen > maxSymbol + 1)
+            {
+                throw Iex::InputExc ("Error decoding Huffman table "
+                                     "(Run beyond end of table).");
+            }
+            
+            symbol += runLen - 1;
+
+        }
+        else if (codeLen >= (Int64) SHORT_ZEROCODE_RUN)
+        {
+            int runLen = codeLen - SHORT_ZEROCODE_RUN + 2;
+
+            if (symbol + runLen > maxSymbol + 1)
+            {
+                throw Iex::InputExc ("Error decoding Huffman table "
+                                     "(Run beyond end of table).");
+            }
+
+            symbol += runLen - 1;
+
+        }
+        else if (codeLen != 0)
+        {
+            symbols.push_back ((symbol << 6) | (codeLen & 63));
+
+            if (codeLen < _minCodeLength)
+                _minCodeLength = codeLen;
+
+            if (codeLen > _maxCodeLength)
+                _maxCodeLength = codeLen;
+
+            codeCount[codeLen]++;
+        }
+    }
+
+    for (int i = 0; i < MAX_CODE_LEN; ++i)
+        _numSymbols += codeCount[i];
+
+    table = currByte;
+
+    //
+    // Compute base - once we have the code length counts, there
+    //                is a closed form solution for this
+    //
+
+    {
+        double* countTmp = new double[_maxCodeLength+1];
+
+        for (int l = _minCodeLength; l <= _maxCodeLength; ++l)
+        {
+            countTmp[l] = (double)codeCount[l] * 
+                          (double)(2 << (_maxCodeLength-l));
+        }
+    
+        for (int l = _minCodeLength; l <= _maxCodeLength; ++l)
+        {
+            double tmp = 0;
+
+            for (int k =l + 1; k <= _maxCodeLength; ++k)
+                tmp += countTmp[k];
+            
+            tmp /= (double)(2 << (_maxCodeLength - l));
+
+            base[l] = (Int64)ceil (tmp);
+        }
+
+        delete [] countTmp;
+    }
+   
+    //
+    // Compute offset - these are the positions of the first
+    //                  id (not symbol) that has length [i]
+    //
+
+    offset[_maxCodeLength] = 0;
+
+    for (int i= _maxCodeLength - 1; i >= _minCodeLength; i--)
+        offset[i] = offset[i + 1] + codeCount[i + 1];
+
+    //
+    // Allocate and fill the symbol-to-id mapping. Smaller Ids should be
+    // mapped to less-frequent symbols (which have longer codes). Use
+    // the offset table to tell us where the id's for a given code 
+    // length start off.
+    //
+
+    _idToSymbol = new int[_numSymbols];
+
+    Int64 mapping[MAX_CODE_LEN + 1];
+    for (int i = 0; i < MAX_CODE_LEN + 1; ++i) 
+        mapping[i] = -1;
+    for (int i = _minCodeLength; i <= _maxCodeLength; ++i)
+        mapping[i] = offset[i];
+
+    for (std::vector<Int64>::const_iterator i = symbols.begin(); 
+         i != symbols.end();
+         ++i)
+    {
+        int codeLen = *i & 63;
+        int symbol  = *i >> 6;
+
+        if (mapping[codeLen] >= _numSymbols)
+            throw Iex::InputExc ("Huffman decode error "
+                                  "(Invalid symbol in header).");
+        
+        _idToSymbol[mapping[codeLen]] = symbol;
+        mapping[codeLen]++;
+    }
+
+    buildTables(base, offset);
+}
+
+
+FastHufDecoder::~FastHufDecoder()
+{
+    delete[] _idToSymbol;
+}
+
+
+//
+// Static check if the decoder is enabled.
+//
+// ATM, I only have access to little endian hardware for testing,
+// so I'm not entirely sure that we are reading fom the bit stream
+// properly on BE. 
+//
+// If you happen to have more obscure hardware, check that the 
+// byte swapping in refill() is happening sensable, add an endian 
+// check if needed, and fix the preprocessor magic here.
+//
+
+#define READ64(c) \
+    ((Int64)(c)[0] << 56) | ((Int64)(c)[1] << 48) | ((Int64)(c)[2] << 40) | \
+    ((Int64)(c)[3] << 32) | ((Int64)(c)[4] << 24) | ((Int64)(c)[5] << 16) | \
+    ((Int64)(c)[6] <<  8) | ((Int64)(c)[7] ) 
+
+#ifdef __INTEL_COMPILER // ICC built-in swap for LE hosts
+    #if defined (__i386__) || defined(__x86_64__)
+        #undef  READ64
+        #define READ64(c) _bswap64 (*(const Int64*)(c))
+    #endif
+#endif
+
+
+bool
+FastHufDecoder::enabled()
+{
+    #if defined(__INTEL_COMPILER) || defined(__GNUC__)  
+
+        //
+        // Enabled for ICC, GCC:
+        //       __i386__   -> x86
+        //       __x86_64__ -> 64-bit x86
+        //
+
+        #if defined (__i386__) || defined(__x86_64__)
+            return true;
+        #else
+            return false;
+        #endif
+
+    #elif defined (_MSC_VER)
+
+        //
+        // Enabled for Visual Studio:
+        //        _M_IX86 -> x86
+        //        _M_X64  -> 64bit x86
+
+        #if defined (_M_IX86) || defined(_M_X64)
+            return true;
+        #else
+            return false;
+        #endif
+
+    #else
+
+        //
+        // Unknown compiler - Be safe and disable.
+        //
+        return false;
+    #endif
+}
+
+//
+//
+// Built the acceleration tables for lookups on the upper bits
+// as well as the 'LJ' tables.
+//
+
+void
+FastHufDecoder::buildTables (Int64 *base, Int64 *offset)
+{
+    //
+    // Build the 'left justified' base table, by shifting base left..
+    //
+
+    for (int i = 0; i <= MAX_CODE_LEN; ++i)
+    {
+        if (base[i] != 0xffffffffffffffffL)
+        {
+            _ljBase[i] = base[i] << (64 - i);
+        }
+        else
+        {
+            //
+            // Unused code length - insert dummy values
+            //
+
+            _ljBase[i] = 0xffffffffffffffffL;
+        }
+    }
+
+    //
+    // Combine some terms into a big fat constant, which for
+    // lack of a better term we'll call the 'left justified' 
+    // offset table (because it serves the same function
+    // as 'offset', when using the left justified base table.
+    //
+
+    for (int i = 0; i <= MAX_CODE_LEN; ++i)
+        _ljOffset[i] = offset[i] - (_ljBase[i] >> (64 - i));
+
+    //
+    // Build the acceleration tables for the lookups of
+    // short codes ( <= TABLE_LOOKUP_BITS long)
+    //
+
+    for (Int64 i = 0; i < 1 << TABLE_LOOKUP_BITS; ++i)
+    {
+        Int64 value = i << (64 - TABLE_LOOKUP_BITS);
+
+        _tableSymbol[i]  = 0xffff;
+        _tableCodeLen[i] = 0; 
+
+        for (int codeLen = _minCodeLength; codeLen <= _maxCodeLength; ++codeLen)
+        {
+            if (_ljBase[codeLen] <= value)
+            {
+                _tableCodeLen[i] = codeLen;
+
+                Int64 id = _ljOffset[codeLen] + (value >> (64 - codeLen));
+                if (id < _numSymbols)
+                {
+                    _tableSymbol[i] = _idToSymbol[id];
+                }
+                else
+                {
+                    throw Iex::InputExc ("Huffman decode error "
+                                          "(Overrun).");
+                }
+                break;
+            }
+        }
+    }
+
+    //
+    // Store the smallest value in the table that points to real data.
+    // This should be the entry for the largest length that has 
+    // valid data (in our case, non-dummy _ljBase)
+    //
+
+    int minIdx = TABLE_LOOKUP_BITS;
+
+    while (minIdx > 0 && _ljBase[minIdx] == 0xffffffffffffffffL)
+        minIdx--;
+
+    if (minIdx < 0)
+    {
+        //
+        // Error, no codes with lengths 0-TABLE_LOOKUP_BITS used.
+        // Set the min value such that the table is never tested.
+        //
+
+        _tableMin = 0xffffffffffffffffL;
+    }
+    else
+    {
+        _tableMin = _ljBase[minIdx];
+    }
+}
+
+
+// 
+// For decoding, we're holding onto 2 Int64's. 
+//
+// The first (buffer), holds the next bits from the bitstream to be 
+// decoded. For certain paths in the decoder, we only need TABLE_LOOKUP_BITS
+// valid bits to decode the next symbol. For other paths, we need a full
+// 64-bits to decode a symbol. 
+//
+// When we need to refill 'buffer', we could pull bits straight from 
+// the bitstream. But this is very slow and requires lots of book keeping
+// (what's the next bit in the next byte?). Instead, we keep another Int64
+// around that we use to refill from. While this doesn't cut down on the
+// book keeping (still need to know how many valid bits), it does cut
+// down on some of the bit shifting crazy and byte access. 
+//
+// The refill Int64 (bufferBack) gets left-shifted after we've pulled
+// off bits. If we run out of bits in the input bit stream, we just
+// shift in 0's to bufferBack. 
+//
+// The refill act takes numBits from the top of bufferBack and sticks
+// them in the bottom of buffer. If there arn't enough bits in bufferBack,
+// it gets refilled (to 64-bits) from the input bitstream.
+//
+
+inline void
+FastHufDecoder::refill
+    (Int64 &buffer,
+     int numBits,                       // number of bits to refill
+     Int64 &bufferBack,                 // the next 64-bits, to refill from
+     int &bufferBackNumBits,            // number of bits left in bufferBack
+     const unsigned char *&currByte,    // current byte in the bitstream
+     int &currBitsLeft)                 // number of bits left in the bitsream
+{
+    // 
+    // Refill bits into the bottom of buffer, from the top of bufferBack.
+    // Always top up buffer to be completely full.
+    //
+
+    buffer |= bufferBack >> (64 - numBits);
+
+    if (bufferBackNumBits < numBits)
+    {
+        numBits -= bufferBackNumBits;
+
+        // 
+        // Refill all of bufferBack from the bitstream. Either grab
+        // a full 64-bit chunk, or whatever bytes are left. If we
+        // don't have 64-bits left, pad with 0's.
+        //
+
+        if (currBitsLeft >= 64)
+        {
+            bufferBack        = READ64 (currByte); 
+            bufferBackNumBits = 64;
+            currByte         += sizeof (Int64);
+            currBitsLeft     -= 8 * sizeof (Int64);
+
+        }
+        else
+        {
+            bufferBack        = 0;
+            bufferBackNumBits = 64; 
+
+            Int64 shift = 56;
+            
+            while (currBitsLeft > 0)
+            {
+                bufferBack |= ((Int64)(*currByte)) << shift;
+
+                currByte++;
+                shift        -= 8;
+                currBitsLeft -= 8;
+            }
+
+            //
+            // At this point, currBitsLeft might be negative, just because
+            // we're subtracting whole bytes. To keep anyone from freaking
+            // out, zero the counter.
+            //
+
+            if (currBitsLeft < 0)
+                currBitsLeft = 0;
+        }
+
+        buffer |= bufferBack >> (64 - numBits);
+    }
+    
+    bufferBack         = bufferBack << numBits;
+    bufferBackNumBits -= numBits;
+
+    // 
+    // We can have cases where the previous shift of bufferBack is << 64 - 
+    // in which case no shift occurs. The bit count math still works though,
+    // so if we don't have any bits left, zero out bufferBack.
+    //
+
+    if (bufferBackNumBits == 0)
+        bufferBack = 0;
+}
+
+//
+// Read the next few bits out of a bitstream. Will be given a backing buffer
+// (buffer) that may still have data left over from previous reads
+// (bufferNumBits).  Bitstream pointer (currByte) will be advanced when needed.
+//
+
+inline Int64 
+FastHufDecoder::readBits
+    (int numBits,
+     Int64 &buffer,             // c
+     int &bufferNumBits,        // lc
+     const char *&currByte)     // in
+{
+    while (bufferNumBits < numBits)
+    {
+        buffer = (buffer << 8) | *(unsigned char*)(currByte++);
+        bufferNumBits += 8;
+    }
+
+    bufferNumBits -= numBits;
+    return (buffer >> bufferNumBits) & ((1 << numBits) - 1);
+}
+
+
+//
+// Decode using a the 'One-Shift' strategy for decoding, with a 
+// small-ish table to accelerate decoding of short codes.
+//
+// If possible, try looking up codes into the acceleration table.
+// This has a few benifits - there's no search involved; We don't
+// need an additional lookup to map id to symbol; we don't need
+// a full 64-bits (so less refilling). 
+//
+
+void
+FastHufDecoder::decode
+    (const unsigned char *src,
+     int numSrcBits,
+     unsigned short *dst, 
+     int numDstElems)
+{
+    if (numSrcBits < 128)
+        throw Iex::InputExc ("Error choosing Huffman decoder implementation "
+                             "(insufficient number of bits).");
+
+    //
+    // Current position (byte/bit) in the src data stream
+    // (after the first buffer fill)
+    //
+
+    const unsigned char *currByte = src + 2 * sizeof (Int64);
+
+    numSrcBits -= 8 * 2 * sizeof (Int64);
+
+    //
+    // 64-bit buffer holding the current bits in the stream
+    //
+
+    Int64 buffer            = READ64 (src); 
+    int   bufferNumBits     = 64;
+
+    //
+    // 64-bit buffer holding the next bits in the stream
+    //
+
+    Int64 bufferBack        = READ64 ((src + sizeof (Int64))); 
+    int   bufferBackNumBits = 64;
+
+    int dstIdx = 0;
+
+    while (dstIdx < numDstElems)
+    {
+        int  codeLen;
+        int  symbol;
+
+        //
+        // Test if we can be table accelerated. If so, directly
+        // lookup the output symbol. Otherwise, we need to fall
+        // back to searching for the code.
+        //
+        // If we're doing table lookups, we don't really need
+        // a re-filled buffer, so long as we have TABLE_LOOKUP_BITS
+        // left. But for a search, we do need a refilled table.
+        //
+
+        if (_tableMin <= buffer)
+        {
+            int tableIdx = buffer >> (64 - TABLE_LOOKUP_BITS);
+
+            // 
+            // For invalid codes, _tableCodeLen[] should return 0. This
+            // will cause the decoder to get stuck in the current spot
+            // until we run out of elements, then barf that the codestream
+            // is bad.  So we don't need to stick a condition like
+            //     if (codeLen > _maxCodeLength) in this inner.
+            //
+
+            codeLen = _tableCodeLen[tableIdx];
+            symbol  = _tableSymbol[tableIdx];
+        }
+        else
+        {
+            if (bufferNumBits < 64)
+            {
+                refill (buffer,
+                        64 - bufferNumBits,
+                        bufferBack,
+                        bufferBackNumBits,
+                        currByte,
+                        numSrcBits);
+
+                bufferNumBits = 64;
+            }
+
+            // 
+            // Brute force search: 
+            // Find the smallest length where _ljBase[length] <= buffer
+            //
+
+            codeLen = TABLE_LOOKUP_BITS + 1;
+
+            while (_ljBase[codeLen] > buffer && codeLen <= _maxCodeLength)
+                codeLen++;
+
+            if (codeLen > _maxCodeLength)
+            {
+                throw Iex::InputExc ("Huffman decode error "
+                                     "(Decoded an invalid symbol).");
+            }
+
+            Int64 id = _ljOffset[codeLen] + (buffer >> (64 - codeLen));
+            if (id < _numSymbols)
+            {
+                symbol = _idToSymbol[id];
+            }
+            else
+            {
+                throw Iex::InputExc ("Huffman decode error "
+                                     "(Decoded an invalid symbol).");
+            }
+        }
+
+        //
+        // Shift over bit stream, and update the bit count in the buffer
+        //
+
+        buffer = buffer << codeLen;
+        bufferNumBits -= codeLen;
+
+        //
+        // If we recieved a RLE symbol (_rleSymbol), then we need
+        // to read ahead 8 bits to know how many times to repeat
+        // the previous symbol. Need to ensure we at least have
+        // 8 bits of data in the buffer
+        //
+
+        if (symbol == _rleSymbol)
+        {
+            if (bufferNumBits < 8)
+            {
+                refill (buffer,
+                        64 - bufferNumBits,
+                        bufferBack,
+                        bufferBackNumBits,
+                        currByte,
+                        numSrcBits);
+
+                bufferNumBits = 64;
+            }
+
+            int rleCount = buffer >> 56;
+
+            if (dstIdx < 1)
+            {
+                throw Iex::InputExc ("Huffman decode error (RLE code "
+                                     "with no previous symbol).");
+            }
+
+            if (dstIdx + rleCount > numDstElems)
+            {
+                throw Iex::InputExc ("Huffman decode error (Symbol run "
+                                     "beyond expected output buffer length).");
+            }
+
+            if (rleCount <= 0) 
+            {
+                throw Iex::InputExc("Huffman decode error"
+                                    " (Invalid RLE length)");
+            }
+
+            for (int i = 0; i < rleCount; ++i)
+                dst[dstIdx + i] = dst[dstIdx - 1];
+
+            dstIdx += rleCount;
+
+            buffer = buffer << 8;
+            bufferNumBits -= 8;
+        }
+        else
+        {
+            dst[dstIdx] = symbol;
+            dstIdx++;
+        }
+
+        //
+        // refill bit stream buffer if we're below the number of 
+        // bits needed for a table lookup
+        //
+
+        if (bufferNumBits < TABLE_LOOKUP_BITS)
+        {
+            refill (buffer,
+                    64 - bufferNumBits,
+                    bufferBack,
+                    bufferBackNumBits,
+                    currByte,
+                    numSrcBits);
+
+            bufferNumBits = 64;
+        }
+    }
+
+    if (numSrcBits != 0)
+    {
+        throw Iex::InputExc ("Huffman decode error (Compressed data remains "
+                             "after filling expected output buffer).");
+    }
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfFastHuf.h b/Source/OpenEXR/IlmImf/ImfFastHuf.h
new file mode 100644
index 0000000..ce7fd3f
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfFastHuf.h
@@ -0,0 +1,148 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2009-2014 DreamWorks Animation LLC. 
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of DreamWorks Animation nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef INCLUDED_IMF_FAST_HUF_H
+#define INCLUDED_IMF_FAST_HUF_H
+
+#include "ImfInt64.h"
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+//
+// Alternative Canonical Huffman decoder:
+//
+// Canonical Huffman decoder based on 'On the Implementation of Minimum
+// Redundancy Prefix Codes' by Moffat and Turpin - highly recommended
+// reading as a good description of the problem space, as well as 
+// a fast decoding algorithm.
+//
+// The premise is that instead of working directly with the coded 
+// symbols, we create a new ordering based on the frequency of symbols.
+// Less frequent symbols (and thus longer codes) are ordered earler.
+// We're calling the values in this ordering 'Ids', as oppsed to 
+// 'Symbols' - which are the short values we eventually want decoded.
+//
+// With this new ordering, a few small tables can be derived ('base' 
+// and 'offset') which drive the decoding. To cut down on the 
+// linear scanning of these tables, you can add a small table
+// to directly look up short codes (as you might in a traditional
+// lookup-table driven decoder). 
+//
+// The decoder is meant to be compatible with the encoder (and decoder)
+// in ImfHuf.cpp, just faster. For ease of implementation, this decoder
+// should only be used on compressed bitstreams >= 128 bits long.
+//
+
+class FastHufDecoder
+{
+  public:
+
+    //
+    // Longest compressed code length that ImfHuf supports (58 bits)
+    //
+
+    static const int MAX_CODE_LEN = 58;
+
+    //
+    // Number of bits in our acceleration table. Should match all
+    // codes up to TABLE_LOOKUP_BITS in length.
+    //
+
+    static const int TABLE_LOOKUP_BITS = 12;
+
+    FastHufDecoder (const char*& table,
+                    int numBytes,
+                    int minSymbol,
+                    int maxSymbol,
+                    int rleSymbol);
+
+    ~FastHufDecoder ();
+
+    static bool enabled ();
+
+    void decode (const unsigned char *src,
+                 int numSrcBits,
+                 unsigned short *dst,
+                 int numDstElems);
+
+  private:
+
+    void  buildTables (Int64*, Int64*);
+    void  refill (Int64&, int, Int64&, int&, const unsigned char *&, int&);
+    Int64 readBits (int, Int64&, int&, const char *&);
+
+    int             _rleSymbol;        // RLE symbol written by the encoder.
+                                       // This could be 65536, so beware
+                                       // when you use shorts to hold things.
+
+    int             _numSymbols;       // Number of symbols in the codebook.
+
+    unsigned char   _minCodeLength;    // Minimum code length, in bits.
+    unsigned char   _maxCodeLength;    // Maximum code length, in bits.
+
+    int            *_idToSymbol;       // Maps Ids to symbols. Ids are a symbol
+                                       // ordering sorted first in terms of 
+                                       // code length, and by code within
+                                       // the same length. Ids run from 0
+                                       // to mNumSymbols-1.
+
+    Int64 _ljBase[MAX_CODE_LEN + 1];   // the 'left justified base' table.
+                                       // Takes base[i] (i = code length)
+                                       // and 'left justifies' it into an Int64
+
+    Int64 _ljOffset[MAX_CODE_LEN +1 ]; // There are some other terms that can 
+                                       // be folded into constants when taking
+                                       // the 'left justified' decode path. This
+                                       // holds those constants, indexed by
+                                       // code length
+
+    //
+    // We can accelerate the 'left justified' processing by running the
+    // top TABLE_LOOKUP_BITS through a LUT, to find the symbol and code
+    // length. These are those acceleration tables.
+    //
+    // Even though our evental 'symbols' are ushort's, the encoder adds
+    // a symbol to indicate RLE. So with a dense code book, we could
+    // have 2^16+1 codes, so both mIdToSymbol and mTableSymbol need
+    // to be bigger than 16 bits.
+    //
+
+    int            _tableSymbol[1 << TABLE_LOOKUP_BITS];
+    unsigned char  _tableCodeLen[1 << TABLE_LOOKUP_BITS];
+    Int64          _tableMin;
+};
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif 
diff --git a/Source/OpenEXR/IlmImf/ImfFloatAttribute.cpp b/Source/OpenEXR/IlmImf/ImfFloatAttribute.cpp
index 22366c3..4e22e90 100644
--- a/Source/OpenEXR/IlmImf/ImfFloatAttribute.cpp
+++ b/Source/OpenEXR/IlmImf/ImfFloatAttribute.cpp
@@ -43,7 +43,7 @@
 #include <ImfFloatAttribute.h>
 
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 template <>
@@ -54,4 +54,4 @@ FloatAttribute::staticTypeName ()
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT 
diff --git a/Source/OpenEXR/IlmImf/ImfFloatAttribute.h b/Source/OpenEXR/IlmImf/ImfFloatAttribute.h
index 60d6f23..7370721 100644
--- a/Source/OpenEXR/IlmImf/ImfFloatAttribute.h
+++ b/Source/OpenEXR/IlmImf/ImfFloatAttribute.h
@@ -43,21 +43,16 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfAttribute.h>
+#include "ImfAttribute.h"
 
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 typedef TypedAttribute<float> FloatAttribute;
-template <> const char *FloatAttribute::staticTypeName ();
+template <> IMF_EXPORT const char *FloatAttribute::staticTypeName ();
 
 
-} // namespace Imf
-
-// Metrowerks compiler wants the .cpp file inlined, too
-#ifdef __MWERKS__
-#include <ImfFloatAttribute.cpp>
-#endif
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfFloatVectorAttribute.cpp b/Source/OpenEXR/IlmImf/ImfFloatVectorAttribute.cpp
new file mode 100644
index 0000000..49eda90
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfFloatVectorAttribute.cpp
@@ -0,0 +1,84 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2013, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission. 
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+//-----------------------------------------------------------------------------
+//
+//	class FloatVectorAttribute
+//
+//-----------------------------------------------------------------------------
+
+#include <ImfFloatVectorAttribute.h>
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+
+using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;
+
+
+template <>
+const char *
+FloatVectorAttribute::staticTypeName ()
+{
+    return "floatvector";
+}
+
+
+template <>
+void
+FloatVectorAttribute::writeValueTo
+    (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
+{
+    int n = _value.size();
+
+    for (int i = 0; i < n; ++i)
+        Xdr::write <StreamIO> (os, _value[i]);
+}
+
+
+template <>
+void
+FloatVectorAttribute::readValueFrom
+    (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
+{
+    int n = size / Xdr::size<float>();
+    _value.resize (n);
+
+    for (int i = 0; i < n; ++i)
+       Xdr::read <StreamIO> (is, _value[i]);
+}
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT 
diff --git a/Source/OpenEXR/IlmImf/ImfFloatVectorAttribute.h b/Source/OpenEXR/IlmImf/ImfFloatVectorAttribute.h
new file mode 100644
index 0000000..66e7642
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfFloatVectorAttribute.h
@@ -0,0 +1,76 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2007, Weta Digital Ltd
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Weta Digital nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission. 
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef INCLUDED_IMF_FLOATVECTOR_ATTRIBUTE_H
+#define INCLUDED_IMF_FLOATVECTOR_ATTRIBUTE_H
+
+//-----------------------------------------------------------------------------
+//
+//	class FloatVectorAttribute
+//
+//-----------------------------------------------------------------------------
+
+#include "ImfAttribute.h"
+#include "ImfNamespace.h"
+
+#include <vector>
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+typedef std::vector<float>
+    FloatVector;
+
+typedef TypedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::FloatVector>
+    FloatVectorAttribute;
+
+template <>
+IMF_EXPORT
+const char *FloatVectorAttribute::staticTypeName ();
+
+template <>
+IMF_EXPORT
+void FloatVectorAttribute::writeValueTo
+    (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &, int) const;
+
+template <>
+IMF_EXPORT
+void FloatVectorAttribute::readValueFrom
+    (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &, int, int);
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif
diff --git a/Source/OpenEXR/IlmImf/ImfForward.h b/Source/OpenEXR/IlmImf/ImfForward.h
new file mode 100644
index 0000000..ea51c24
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfForward.h
@@ -0,0 +1,127 @@
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// Portions (c) 2012 Weta Digital Ltd
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission. 
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef INCLUDED_IMF_FORWARD_H
+#define INCLUDED_IMF_FORWARD_H
+
+////////////////////////////////////////////////////////////////////
+//
+// Forward declarations for OpenEXR - correctly declares namespace
+//
+////////////////////////////////////////////////////////////////////
+
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+
+// classes for basic types;
+template<class T> class Array;
+template<class T> class Array2D;
+struct Channel;
+class  ChannelList;
+struct Chromaticities;
+
+// attributes used in headers are TypedAttributes
+class Attribute;
+
+class Header;
+
+// file handling classes
+class OutputFile;
+class TiledInputFile;
+class ScanLineInputFile;
+class InputFile;
+class TiledOutputFile;
+class DeepScanLineInputFile;
+class DeepScanLineOutputFile;
+class DeepTiledInputFile;
+class DeepTiledOutputFile;
+class AcesInputFile;
+class AcesOutputFile;
+class TiledInputPart;
+class TiledInputFile;
+class TileOffsets;
+
+// multipart file handling
+class GenericInputFile;
+class GenericOutputFile;
+class MultiPartInputFile;
+class MultiPartOutputFile;
+
+class InputPart;
+class TiledInputPart;
+class DeepScanLineInputPart;
+class DeepTiledInputPart;
+
+class OutputPart;
+class ScanLineOutputPart;
+class TiledOutputPart;
+class DeepScanLineOutputPart;
+class DeepTiledOutputPart;
+
+
+// internal use only
+struct InputPartData;
+struct OutputStreamMutex;
+struct OutputPartData;
+struct InputStreamMutex;
+
+// frame buffers
+
+class  FrameBuffer;
+class  DeepFrameBuffer;
+struct DeepSlice;
+
+// compositing
+class DeepCompositing;
+class CompositeDeepScanLine;
+
+// preview image
+class PreviewImage;
+struct PreviewRgba;
+
+// streams
+class OStream;
+class IStream;
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+#endif // include guard
diff --git a/Source/OpenEXR/IlmImf/ImfFrameBuffer.cpp b/Source/OpenEXR/IlmImf/ImfFrameBuffer.cpp
index f4c8fd0..bced3b1 100644
--- a/Source/OpenEXR/IlmImf/ImfFrameBuffer.cpp
+++ b/Source/OpenEXR/IlmImf/ImfFrameBuffer.cpp
@@ -36,8 +36,8 @@
 
 //-----------------------------------------------------------------------------
 //
-//	class Slice
-//	class FrameBuffer
+//      class Slice
+//      class FrameBuffer
 //
 //-----------------------------------------------------------------------------
 
@@ -47,15 +47,17 @@
 
 using namespace std;
 
-namespace Imf {
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 Slice::Slice (PixelType t,
-	      char *b,
-	      size_t xst,
-	      size_t yst,
-	      int xsm,
-	      int ysm,
-	      double fv,
+              char *b,
+              size_t xst,
+              size_t yst,
+              int xsm,
+              int ysm,
+              double fv,
               bool xtc,
               bool ytc)
 :
@@ -73,20 +75,20 @@ Slice::Slice (PixelType t,
 }
 
 
-void	
+void
 FrameBuffer::insert (const char name[], const Slice &slice)
 {
     if (name[0] == 0)
     {
-	THROW (Iex::ArgExc,
-	       "Frame buffer slice name cannot be an empty string.");
+        THROW (IEX_NAMESPACE::ArgExc,
+               "Frame buffer slice name cannot be an empty string.");
     }
 
     _map[name] = slice;
 }
 
 
-void	
+void
 FrameBuffer::insert (const string &name, const Slice &slice)
 {
     insert (name.c_str(), slice);
@@ -100,8 +102,8 @@ FrameBuffer::operator [] (const char name[])
 
     if (i == _map.end())
     {
-	THROW (Iex::ArgExc,
-	       "Cannot find frame buffer slice \"" << name << "\".");
+        THROW (IEX_NAMESPACE::ArgExc,
+               "Cannot find frame buffer slice \"" << name << "\".");
     }
 
     return i->second;
@@ -115,8 +117,8 @@ FrameBuffer::operator [] (const char name[]) const
 
     if (i == _map.end())
     {
-	THROW (Iex::ArgExc,
-	       "Cannot find frame buffer slice \"" << name << "\".");
+        THROW (IEX_NAMESPACE::ArgExc,
+               "Cannot find frame buffer slice \"" << name << "\".");
     }
 
     return i->second;
@@ -167,14 +169,14 @@ FrameBuffer::findSlice (const string &name) const
 }
 
 
-FrameBuffer::Iterator		
+FrameBuffer::Iterator
 FrameBuffer::begin ()
 {
     return _map.begin();
 }
 
 
-FrameBuffer::ConstIterator	
+FrameBuffer::ConstIterator
 FrameBuffer::begin () const
 {
     return _map.begin();
@@ -188,7 +190,7 @@ FrameBuffer::end ()
 }
 
 
-FrameBuffer::ConstIterator	
+FrameBuffer::ConstIterator
 FrameBuffer::end () const
 {
     return _map.end();
@@ -223,4 +225,4 @@ FrameBuffer::find (const string &name) const
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfFrameBuffer.h b/Source/OpenEXR/IlmImf/ImfFrameBuffer.h
index 3b6cc92..a810cfa 100644
--- a/Source/OpenEXR/IlmImf/ImfFrameBuffer.h
+++ b/Source/OpenEXR/IlmImf/ImfFrameBuffer.h
@@ -39,18 +39,21 @@
 
 //-----------------------------------------------------------------------------
 //
-//	class Slice
-//	class FrameBuffer
+//      class Slice
+//      class FrameBuffer
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfName.h>
-#include <ImfPixelType.h>
+#include "ImfName.h"
+#include "ImfPixelType.h"
+#include "ImfExport.h"
+#include "ImfNamespace.h"
+
 #include <map>
 #include <string>
 
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 //-------------------------------------------------------
@@ -62,37 +65,37 @@ namespace Imf {
 // component is called a "slice".
 //-------------------------------------------------------
 
-struct Slice
+struct IMF_EXPORT Slice
 {
     //------------------------------
     // Data type; see ImfPixelType.h
     //------------------------------
 
-    PixelType		type;
+    PixelType           type;
 
 
     //---------------------------------------------------------------------
     // Memory layout:  The address of pixel (x, y) is
     //
-    //	base + (xp / xSampling) * xStride + (yp / ySampling) * yStride
+    //  base + (xp / xSampling) * xStride + (yp / ySampling) * yStride
     //
     // where xp and yp are computed as follows:
     //
-    //	* If we are reading or writing a scanline-based file:
+    //  * If we are reading or writing a scanline-based file:
     //
-    //	    xp = x
-    //	    yp = y
+    //      xp = x
+    //      yp = y
     //
     //  * If we are reading a tile whose upper left coorner is at (xt, yt):
     //
-    //	    if xTileCoords is true then xp = x - xt, else xp = x
-    //	    if yTileCoords is true then yp = y - yt, else yp = y
+    //      if xTileCoords is true then xp = x - xt, else xp = x
+    //      if yTileCoords is true then yp = y - yt, else yp = y
     //
     //---------------------------------------------------------------------
 
-    char *		base;
-    size_t		xStride;
-    size_t		yStride;
+    char *              base;
+    size_t              xStride;
+    size_t              yStride;
 
 
     //--------------------------------------------
@@ -103,8 +106,8 @@ struct Slice
     //
     //--------------------------------------------
 
-    int			xSampling;
-    int			ySampling;
+    int                 xSampling;
+    int                 ySampling;
 
 
     //----------------------------------------------------------
@@ -112,7 +115,7 @@ struct Slice
     // a channel that corresponds to this slice is read.
     //----------------------------------------------------------
 
-    double		fillValue;
+    double              fillValue;
     
 
     //-------------------------------------------------------
@@ -136,18 +139,18 @@ struct Slice
     //------------
 
     Slice (PixelType type = HALF,
-	   char * base = 0,
-	   size_t xStride = 0,
-	   size_t yStride = 0,
-	   int xSampling = 1,
-	   int ySampling = 1,
-	   double fillValue = 0.0,
+           char * base = 0,
+           size_t xStride = 0,
+           size_t yStride = 0,
+           int xSampling = 1,
+           int ySampling = 1,
+           double fillValue = 0.0,
            bool xTileCoords = false,
            bool yTileCoords = false);
 };
 
 
-class FrameBuffer
+class IMF_EXPORT FrameBuffer
 {
   public:
 
@@ -155,35 +158,35 @@ class FrameBuffer
     // Add a slice
     //------------
 
-    void			insert (const char name[],
-					const Slice &slice);
+    void                        insert (const char name[],
+                                        const Slice &slice);
 
-    void			insert (const std::string &name,
-					const Slice &slice);
+    void                        insert (const std::string &name,
+                                        const Slice &slice);
 
     //----------------------------------------------------------------
     // Access to existing slices:
     //
-    // [n]		Returns a reference to the slice with name n.
-    //			If no slice with name n exists, an Iex::ArgExc
-    //			is thrown.
+    // [n]              Returns a reference to the slice with name n.
+    //                  If no slice with name n exists, an IEX_NAMESPACE::ArgExc
+    //                  is thrown.
     //
-    // findSlice(n)	Returns a pointer to the slice with name n,
-    //			or 0 if no slice with name n exists.
+    // findSlice(n)     Returns a pointer to the slice with name n,
+    //                  or 0 if no slice with name n exists.
     //
     //----------------------------------------------------------------
 
-    Slice &			operator [] (const char name[]);
-    const Slice &		operator [] (const char name[]) const;
+    Slice &                     operator [] (const char name[]);
+    const Slice &               operator [] (const char name[]) const;
 
-    Slice &			operator [] (const std::string &name);
-    const Slice &		operator [] (const std::string &name) const;
+    Slice &                     operator [] (const std::string &name);
+    const Slice &               operator [] (const std::string &name) const;
 
-    Slice *			findSlice (const char name[]);
-    const Slice *		findSlice (const char name[]) const;
+    Slice *                     findSlice (const char name[]);
+    const Slice *               findSlice (const char name[]) const;
 
-    Slice *			findSlice (const std::string &name);
-    const Slice *		findSlice (const std::string &name) const;
+    Slice *                     findSlice (const std::string &name);
+    const Slice *               findSlice (const std::string &name) const;
 
 
     //-----------------------------------------
@@ -195,21 +198,21 @@ class FrameBuffer
     class Iterator;
     class ConstIterator;
 
-    Iterator			begin ();
-    ConstIterator		begin () const;
+    Iterator                    begin ();
+    ConstIterator               begin () const;
 
-    Iterator			end ();
-    ConstIterator		end () const;
+    Iterator                    end ();
+    ConstIterator               end () const;
 
-    Iterator			find (const char name[]);
-    ConstIterator		find (const char name[]) const;
+    Iterator                    find (const char name[]);
+    ConstIterator               find (const char name[]) const;
 
-    Iterator			find (const std::string &name);
-    ConstIterator		find (const std::string &name) const;
+    Iterator                    find (const std::string &name);
+    ConstIterator               find (const std::string &name) const;
 
   private:
 
-    SliceMap			_map;
+    SliceMap                    _map;
 };
 
 
@@ -224,11 +227,11 @@ class FrameBuffer::Iterator
     Iterator ();
     Iterator (const FrameBuffer::SliceMap::iterator &i);
 
-    Iterator &			operator ++ ();
-    Iterator 			operator ++ (int);
+    Iterator &                  operator ++ ();
+    Iterator                    operator ++ (int);
 
-    const char *		name () const;
-    Slice &			slice () const;
+    const char *                name () const;
+    Slice &                     slice () const;
 
   private:
 
@@ -246,11 +249,11 @@ class FrameBuffer::ConstIterator
     ConstIterator (const FrameBuffer::SliceMap::const_iterator &i);
     ConstIterator (const FrameBuffer::Iterator &other);
 
-    ConstIterator &		operator ++ ();
-    ConstIterator 		operator ++ (int);
+    ConstIterator &             operator ++ ();
+    ConstIterator               operator ++ (int);
 
-    const char *		name () const;
-    const Slice &		slice () const;
+    const char *                name () const;
+    const Slice &               slice () const;
 
   private:
 
@@ -280,7 +283,7 @@ FrameBuffer::Iterator::Iterator (const FrameBuffer::SliceMap::iterator &i):
 }
 
 
-inline FrameBuffer::Iterator &		
+inline FrameBuffer::Iterator &
 FrameBuffer::Iterator::operator ++ ()
 {
     ++_i;
@@ -288,7 +291,7 @@ FrameBuffer::Iterator::operator ++ ()
 }
 
 
-inline FrameBuffer::Iterator 	
+inline FrameBuffer::Iterator
 FrameBuffer::Iterator::operator ++ (int)
 {
     Iterator tmp = *this;
@@ -304,7 +307,7 @@ FrameBuffer::Iterator::name () const
 }
 
 
-inline Slice &	
+inline Slice &
 FrameBuffer::Iterator::slice () const
 {
     return _i->second;
@@ -340,7 +343,7 @@ FrameBuffer::ConstIterator::operator ++ ()
 }
 
 
-inline FrameBuffer::ConstIterator 		
+inline FrameBuffer::ConstIterator
 FrameBuffer::ConstIterator::operator ++ (int)
 {
     ConstIterator tmp = *this;
@@ -355,7 +358,7 @@ FrameBuffer::ConstIterator::name () const
     return *_i->first;
 }
 
-inline const Slice &	
+inline const Slice &
 FrameBuffer::ConstIterator::slice () const
 {
     return _i->second;
@@ -364,7 +367,7 @@ FrameBuffer::ConstIterator::slice () const
 
 inline bool
 operator == (const FrameBuffer::ConstIterator &x,
-	     const FrameBuffer::ConstIterator &y)
+             const FrameBuffer::ConstIterator &y)
 {
     return x._i == y._i;
 }
@@ -372,12 +375,12 @@ operator == (const FrameBuffer::ConstIterator &x,
 
 inline bool
 operator != (const FrameBuffer::ConstIterator &x,
-	     const FrameBuffer::ConstIterator &y)
+             const FrameBuffer::ConstIterator &y)
 {
     return !(x == y);
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfFramesPerSecond.cpp b/Source/OpenEXR/IlmImf/ImfFramesPerSecond.cpp
index cc533a0..b56f948 100644
--- a/Source/OpenEXR/IlmImf/ImfFramesPerSecond.cpp
+++ b/Source/OpenEXR/IlmImf/ImfFramesPerSecond.cpp
@@ -41,9 +41,10 @@
 #include <ImfFramesPerSecond.h>
 #include "ImathFun.h"
 
-using namespace Imath;
+using namespace IMATH_NAMESPACE;
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 Rational
 guessExactFps (double fps)
@@ -72,4 +73,4 @@ guessExactFps (const Rational &fps)
     return fps;
 }
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfFramesPerSecond.h b/Source/OpenEXR/IlmImf/ImfFramesPerSecond.h
index cbef984..59ab4cb 100644
--- a/Source/OpenEXR/IlmImf/ImfFramesPerSecond.h
+++ b/Source/OpenEXR/IlmImf/ImfFramesPerSecond.h
@@ -65,9 +65,13 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfRational.h>
+#include "ImfRational.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-namespace Imf {
 
 inline Rational	fps_23_976 ()	{return Rational (24000, 1001);}
 inline Rational	fps_24 ()	{return Rational (24, 1);}
@@ -80,9 +84,11 @@ inline Rational	fps_50 ()	{return Rational (50, 1);}
 inline Rational	fps_59_94 ()	{return Rational (60000, 1001);}
 inline Rational	fps_60 ()	{return Rational (60, 1);}
 
-Rational	guessExactFps (double fps);
-Rational	guessExactFps (const Rational &fps);
+IMF_EXPORT Rational	guessExactFps (double fps);
+IMF_EXPORT Rational	guessExactFps (const Rational &fps);
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
-} // namespace Imf
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfGenericInputFile.cpp b/Source/OpenEXR/IlmImf/ImfGenericInputFile.cpp
new file mode 100644
index 0000000..0096a0a
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfGenericInputFile.cpp
@@ -0,0 +1,76 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#include "ImfGenericInputFile.h"
+
+#include <ImfVersion.h>
+#include <ImfXdr.h>
+#include <Iex.h>
+#include <OpenEXRConfig.h>
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+void GenericInputFile::readMagicNumberAndVersionField(OPENEXR_IMF_INTERNAL_NAMESPACE::IStream& is, int& version)
+{
+    //
+    // Read the magic number and the file format version number.
+    // Then check if we can read the rest of this file.
+    //
+
+    int magic;
+
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, magic);
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, version);
+
+    if (magic != MAGIC)
+    {
+        throw IEX_NAMESPACE::InputExc ("File is not an image file.");
+    }
+
+    if (getVersion (version) != EXR_VERSION)
+    {
+        THROW (IEX_NAMESPACE::InputExc, "Cannot read "
+                              "version " << getVersion (version) << " "
+                              "image files.  Current file format version "
+                              "is " << EXR_VERSION << ".");
+    }
+
+    if (!supportsFlags (getFlags (version)))
+    {
+        THROW (IEX_NAMESPACE::InputExc, "The file format version number's flag field "
+                              "contains unrecognized flags.");
+    }
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfGenericInputFile.h b/Source/OpenEXR/IlmImf/ImfGenericInputFile.h
new file mode 100644
index 0000000..78b32ba
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfGenericInputFile.h
@@ -0,0 +1,58 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef IMFGENERICINPUTFILE_H_
+#define IMFGENERICINPUTFILE_H_
+
+#include "ImfIO.h"
+#include "ImfHeader.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+class IMF_EXPORT GenericInputFile
+{
+    public:
+        virtual ~GenericInputFile() {}
+
+    protected:
+        GenericInputFile() {}
+        void readMagicNumberAndVersionField(OPENEXR_IMF_INTERNAL_NAMESPACE::IStream& is, int& version);
+};
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+#endif /* IMFGENERICINPUTFILE_H_ */
diff --git a/Source/OpenEXR/IlmImf/ImfGenericOutputFile.cpp b/Source/OpenEXR/IlmImf/ImfGenericOutputFile.cpp
new file mode 100644
index 0000000..8ec707b
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfGenericOutputFile.cpp
@@ -0,0 +1,112 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#include "ImfGenericOutputFile.h"
+
+#include <ImfBoxAttribute.h>
+#include <ImfFloatAttribute.h>
+#include <ImfTimeCodeAttribute.h>
+#include <ImfChromaticitiesAttribute.h>
+
+#include <ImfMisc.h>
+#include <ImfPartType.h>
+
+#include "ImfNamespace.h"
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+    
+using namespace std;
+
+
+    
+void
+GenericOutputFile::writeMagicNumberAndVersionField (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream& os,
+                                                    const Header& header)
+{
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (os, MAGIC);
+
+    int version = EXR_VERSION;
+
+    if (header.hasType() && isDeepData(header.type()))
+    {
+        version |= NON_IMAGE_FLAG;
+    }
+    else
+    {
+        // (TODO) we may want to check something else in function signature
+        // instead of hasTileDescription()?
+        if (header.hasTileDescription())
+            version |= TILED_FLAG;
+    }
+
+    if (usesLongNames (header))
+        version |= LONG_NAMES_FLAG;
+
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (os, version);
+}
+
+void
+GenericOutputFile::writeMagicNumberAndVersionField (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream& os,
+                                                    const Header * headers,
+                                                    int parts)
+{
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (os, MAGIC);
+
+    int version = EXR_VERSION;
+
+    if (parts == 1)
+    {
+        if (headers[0].type() == TILEDIMAGE)
+            version |= TILED_FLAG;
+    }
+    else
+    {
+        version |= MULTI_PART_FILE_FLAG;
+    }
+    
+    for (int i = 0; i < parts; i++)
+    {
+        if (usesLongNames (headers[i]))
+            version |= LONG_NAMES_FLAG;
+
+        if (headers[i].hasType() && isImage(headers[i].type()) == false)
+            version |= NON_IMAGE_FLAG;
+    }
+
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (os, version);
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfGenericOutputFile.h b/Source/OpenEXR/IlmImf/ImfGenericOutputFile.h
new file mode 100644
index 0000000..6b37f2a
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfGenericOutputFile.h
@@ -0,0 +1,62 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef IMFGENERICOUTPUTFILE_H_
+#define IMFGENERICOUTPUTFILE_H_
+
+#include "ImfVersion.h"
+#include "ImfIO.h"
+#include "ImfXdr.h"
+#include "ImfHeader.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+
+class IMF_EXPORT GenericOutputFile
+{
+    public:
+        virtual ~GenericOutputFile() {}
+
+    protected:
+        GenericOutputFile() {}
+        void writeMagicNumberAndVersionField (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream& os, const Header& header);
+        void writeMagicNumberAndVersionField (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream& os, const Header * headers, int parts);
+  
+};
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif /* GENERICOUTPUTFILE_H_ */
diff --git a/Source/OpenEXR/IlmImf/ImfHeader.cpp b/Source/OpenEXR/IlmImf/ImfHeader.cpp
index e64300a..d6b55f3 100644
--- a/Source/OpenEXR/IlmImf/ImfHeader.cpp
+++ b/Source/OpenEXR/IlmImf/ImfHeader.cpp
@@ -49,9 +49,12 @@
 #include <ImfChannelListAttribute.h>
 #include <ImfChromaticitiesAttribute.h>
 #include <ImfCompressionAttribute.h>
+#include <ImfDeepImageStateAttribute.h>
 #include <ImfDoubleAttribute.h>
+#include <ImfDwaCompressor.h>
 #include <ImfEnvmapAttribute.h>
 #include <ImfFloatAttribute.h>
+#include <ImfFloatVectorAttribute.h>
 #include <ImfIntAttribute.h>
 #include <ImfKeyCodeAttribute.h>
 #include <ImfLineOrderAttribute.h>
@@ -64,21 +67,23 @@
 #include <ImfTileDescriptionAttribute.h>
 #include <ImfTimeCodeAttribute.h>
 #include <ImfVecAttribute.h>
+#include <ImfPartType.h>
 #include "IlmThreadMutex.h"
 #include "Iex.h"
 #include <sstream>
 #include <stdlib.h>
 #include <time.h>
 
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 using namespace std;
-using Imath::Box2i;
-using Imath::V2i;
-using Imath::V2f;
-using IlmThread::Mutex;
-using IlmThread::Lock;
+using IMATH_NAMESPACE::Box2i;
+using IMATH_NAMESPACE::V2i;
+using IMATH_NAMESPACE::V2f;
+using ILMTHREAD_NAMESPACE::Mutex;
+using ILMTHREAD_NAMESPACE::Lock;
 
 
 namespace {
@@ -109,54 +114,17 @@ initialize (Header &header,
     header.insert ("channels", ChannelListAttribute ());
 }
 
-
-bool
-usesLongNames (const Header &header)
-{
-    //
-    // If an OpenEXR file contains any attribute names, attribute type names
-    // or channel names longer than 31 characters, then the file cannot be
-    // read by older versions of the IlmImf library (up to OpenEXR 1.6.1).
-    // Before writing the file header, we check if the header contains
-    // any names longer than 31 characters; if it does, then we set the
-    // LONG_NAMES_FLAG in the file version number.  Older versions of the
-    // IlmImf library will refuse to read files that have the LONG_NAMES_FLAG
-    // set.  Without the flag, older versions of the library would mis-
-    // interpret the file as broken.
-    //
-
-    for (Header::ConstIterator i = header.begin();
-         i != header.end();
-         ++i)
-    {
-        if (strlen (i.name()) >= 32 || strlen (i.attribute().typeName()) >= 32)
-            return true;
-    }
-
-    const ChannelList &channels = header.channels();
-
-    for (ChannelList::ConstIterator i = channels.begin();
-         i != channels.end();
-         ++i)
-    {
-        if (strlen (i.name()) >= 32)
-            return true;
-    }
-
-    return false;
-}
-
 template <size_t N>
 void checkIsNullTerminated (const char (&str)[N], const char *what)
 {
-	for (int i = 0; i < N; ++i) {
+	for (size_t i = 0; i < N; ++i) {
 		if (str[i] == '\0')
 			return;
 	}
 	std::stringstream s;
 	s << "Invalid " << what << ": it is more than " << (N - 1) 
 		<< " characters long.";
-	throw Iex::InputExc(s);
+	throw IEX_NAMESPACE::InputExc(s);
 }
 
 } // namespace
@@ -285,10 +253,31 @@ Header::operator = (const Header &other)
 
 
 void
+Header::erase (const char name[])
+{
+    if (name[0] == 0)
+        THROW (IEX_NAMESPACE::ArgExc, "Image attribute name cannot be an empty string.");
+    
+    
+    AttributeMap::iterator i = _map.find (name);
+    if (i != _map.end())
+        _map.erase (i);
+
+}
+
+
+void
+Header::erase (const string &name)
+{
+    erase (name.c_str());
+}
+    
+    
+void
 Header::insert (const char name[], const Attribute &attribute)
 {
     if (name[0] == 0)
-	THROW (Iex::ArgExc, "Image attribute name cannot be an empty string.");
+	THROW (IEX_NAMESPACE::ArgExc, "Image attribute name cannot be an empty string.");
 
     AttributeMap::iterator i = _map.find (name);
 
@@ -309,7 +298,7 @@ Header::insert (const char name[], const Attribute &attribute)
     else
     {
 	if (strcmp (i->second->typeName(), attribute.typeName()))
-	    THROW (Iex::TypeExc, "Cannot assign a value of "
+	    THROW (IEX_NAMESPACE::TypeExc, "Cannot assign a value of "
 				 "type \"" << attribute.typeName() << "\" "
 				 "to image attribute \"" << name << "\" of "
 				 "type \"" << i->second->typeName() << "\".");
@@ -334,7 +323,7 @@ Header::operator [] (const char name[])
     AttributeMap::iterator i = _map.find (name);
 
     if (i == _map.end())
-	THROW (Iex::ArgExc, "Cannot find image attribute \"" << name << "\".");
+	THROW (IEX_NAMESPACE::ArgExc, "Cannot find image attribute \"" << name << "\".");
 
     return *i->second;
 }
@@ -346,7 +335,7 @@ Header::operator [] (const char name[]) const
     AttributeMap::const_iterator i = _map.find (name);
 
     if (i == _map.end())
-	THROW (Iex::ArgExc, "Cannot find image attribute \"" << name << "\".");
+	THROW (IEX_NAMESPACE::ArgExc, "Cannot find image attribute \"" << name << "\".");
 
     return *i->second;
 }
@@ -422,7 +411,7 @@ Header::find (const string &name) const
 }
 
 
-Imath::Box2i &	
+IMATH_NAMESPACE::Box2i &	
 Header::displayWindow ()
 {
     return static_cast <Box2iAttribute &>
@@ -430,7 +419,7 @@ Header::displayWindow ()
 }
 
 
-const Imath::Box2i &
+const IMATH_NAMESPACE::Box2i &
 Header::displayWindow () const
 {
     return static_cast <const Box2iAttribute &>
@@ -438,7 +427,7 @@ Header::displayWindow () const
 }
 
 
-Imath::Box2i &	
+IMATH_NAMESPACE::Box2i &	
 Header::dataWindow ()
 {
     return static_cast <Box2iAttribute &>
@@ -446,7 +435,7 @@ Header::dataWindow ()
 }
 
 
-const Imath::Box2i &
+const IMATH_NAMESPACE::Box2i &
 Header::dataWindow () const
 {
     return static_cast <const Box2iAttribute &>
@@ -470,7 +459,7 @@ Header::pixelAspectRatio () const
 }
 
 
-Imath::V2f &	
+IMATH_NAMESPACE::V2f &	
 Header::screenWindowCenter ()
 {
     return static_cast <V2fAttribute &>
@@ -478,7 +467,7 @@ Header::screenWindowCenter ()
 }
 
 
-const Imath::V2f &	
+const IMATH_NAMESPACE::V2f &	
 Header::screenWindowCenter () const
 {
     return static_cast <const V2fAttribute &>
@@ -551,6 +540,162 @@ Header::compression () const
 
 
 void
+Header::setName(const string& name)
+{
+    insert ("name", StringAttribute (name));
+}
+
+
+bool
+Header::hasName() const
+{
+    return findTypedAttribute <StringAttribute> ("name") != 0;
+}
+
+
+string &
+Header::name()
+{
+    return typedAttribute <StringAttribute> ("name").value();
+}
+
+
+const string &
+Header::name() const
+{
+    return typedAttribute <StringAttribute> ("name").value();
+}
+
+
+void
+Header::setType(const string& type)
+{
+    if (isSupportedType(type) == false)
+    {
+        throw IEX_NAMESPACE::ArgExc (type + "is not a supported image type." +
+                           "The following are supported: " +
+                           SCANLINEIMAGE + ", " +
+                           TILEDIMAGE + ", " +
+                           DEEPSCANLINE + " or " +
+                           DEEPTILE + ".");
+    }
+
+    insert ("type", StringAttribute (type));
+
+    // (TODO) Should we do it here?
+    if (isDeepData(type) && hasVersion() == false)
+    {
+        setVersion(1);
+    }
+}
+
+
+bool
+Header::hasType() const
+{
+    return findTypedAttribute <StringAttribute> ("type") != 0;
+}
+
+
+string &
+Header::type()
+{
+    return typedAttribute <StringAttribute> ("type").value();
+}
+
+
+const string &
+Header::type() const
+{
+    return typedAttribute <StringAttribute> ("type").value();
+}
+
+
+void
+Header::setView(const string& view)
+{
+    insert ("view", StringAttribute (view));
+}
+
+
+bool
+Header::hasView() const
+{
+    return findTypedAttribute <StringAttribute> ("view") != 0;
+}
+
+
+string &
+Header::view()
+{
+    return typedAttribute <StringAttribute> ("view").value();
+}
+
+
+const string &
+Header::view() const
+{
+    return typedAttribute <StringAttribute> ("view").value();
+}
+
+
+void
+Header::setVersion(const int version)
+{
+    if (version != 1)
+    {
+        throw IEX_NAMESPACE::ArgExc ("We can only process version 1");
+    }
+
+    insert ("version", IntAttribute (version));
+}
+
+
+bool
+Header::hasVersion() const
+{
+    return findTypedAttribute <IntAttribute> ("version") != 0;
+}
+
+
+int &
+Header::version()
+{
+    return typedAttribute <IntAttribute> ("version").value();
+}
+
+
+const int &
+Header::version() const
+{
+    return typedAttribute <IntAttribute> ("version").value();
+}
+
+void 
+Header::setChunkCount(int chunks)
+{
+    insert("chunkCount",IntAttribute(chunks));
+}
+
+bool 
+Header::hasChunkCount() const
+{
+   return findTypedAttribute<IntAttribute>("chunkCount") != 0;
+}
+
+int& 
+Header::chunkCount()
+{
+    return typedAttribute <IntAttribute> ("chunkCount").value();
+}
+
+const int& 
+Header::chunkCount() const
+{
+    return typedAttribute <IntAttribute> ("chunkCount").value();
+}
+
+void
 Header::setTileDescription(const TileDescription& td)
 {
     insert ("tiles", TileDescriptionAttribute (td));
@@ -606,7 +751,7 @@ Header::hasPreviewImage () const
 
 
 void		
-Header::sanityCheck (bool isTiled) const
+Header::sanityCheck (bool isTiled, bool isMultipartFile) const
 {
     //
     // The display window and the data window must each
@@ -625,7 +770,7 @@ Header::sanityCheck (bool isTiled) const
 	displayWindow.max.x >=  (INT_MAX / 2) ||
 	displayWindow.max.y >=  (INT_MAX / 2))
     {
-	throw Iex::ArgExc ("Invalid display window in image header.");
+	throw IEX_NAMESPACE::ArgExc ("Invalid display window in image header.");
     }
 
     const Box2i &dataWindow = this->dataWindow();
@@ -637,23 +782,35 @@ Header::sanityCheck (bool isTiled) const
 	dataWindow.max.x >=  (INT_MAX / 2) ||
 	dataWindow.max.y >=  (INT_MAX / 2))
     {
-	throw Iex::ArgExc ("Invalid data window in image header.");
+	throw IEX_NAMESPACE::ArgExc ("Invalid data window in image header.");
     }
 
     if (maxImageWidth > 0 &&
-	maxImageWidth < dataWindow.max.x - dataWindow.min.x + 1)
+        maxImageWidth < (dataWindow.max.x - dataWindow.min.x + 1))
     {
-	THROW (Iex::ArgExc, "The width of the data window exceeds the "
+	THROW (IEX_NAMESPACE::ArgExc, "The width of the data window exceeds the "
 			    "maximum width of " << maxImageWidth << "pixels.");
     }
 
     if (maxImageHeight > 0 &&
 	maxImageHeight < dataWindow.max.y - dataWindow.min.y + 1)
     {
-	THROW (Iex::ArgExc, "The width of the data window exceeds the "
+	THROW (IEX_NAMESPACE::ArgExc, "The width of the data window exceeds the "
 			    "maximum width of " << maxImageHeight << "pixels.");
     }
 
+   // chunk table must be smaller than the maximum image area
+   // (only reachable for unknown types or damaged files: will have thrown earlier
+   //  for regular image types)
+   if( maxImageHeight>0 && maxImageWidth>0 && 
+       hasChunkCount() && chunkCount()>Int64(maxImageWidth)*Int64(maxImageHeight))
+   {
+       THROW (IEX_NAMESPACE::ArgExc, "chunkCount exceeds maximum area of "
+       << Int64(maxImageWidth)*Int64(maxImageHeight) << " pixels." );
+       
+   }
+
+
     //
     // The pixel aspect ratio must be greater than 0.
     // In applications, numbers like the the display or
@@ -673,7 +830,7 @@ Header::sanityCheck (bool isTiled) const
     if (pixelAspectRatio < MIN_PIXEL_ASPECT_RATIO ||
 	pixelAspectRatio > MAX_PIXEL_ASPECT_RATIO)
     {
-	throw Iex::ArgExc ("Invalid pixel aspect ratio in image header.");
+	throw IEX_NAMESPACE::ArgExc ("Invalid pixel aspect ratio in image header.");
     }
 
     //
@@ -687,10 +844,43 @@ Header::sanityCheck (bool isTiled) const
     float screenWindowWidth = this->screenWindowWidth();
 
     if (screenWindowWidth < 0)
-	throw Iex::ArgExc ("Invalid screen window width in image header.");
+	throw IEX_NAMESPACE::ArgExc ("Invalid screen window width in image header.");
 
     //
-    // If the file is tiled, verify that the tile description has resonable
+    // If the file has multiple parts, verify that each header has attribute
+    // name and type.
+    // (TODO) We may want to check more stuff here.
+    //
+
+    if (isMultipartFile)
+    {
+        if (!hasName())
+        {
+            throw IEX_NAMESPACE::ArgExc ("Headers in a multipart file should"
+                               " have name attribute.");
+        }
+
+        if (!hasType())
+        {
+            throw IEX_NAMESPACE::ArgExc ("Headers in a multipart file should"
+                               " have type attribute.");
+        }
+
+    }
+    
+    const std::string & part_type=hasType() ? type() : "";
+    
+    if(part_type!="" && !isSupportedType(part_type))
+    {
+        //
+        // skip remaining sanity checks with unsupported types - they may not hold
+        //
+        return;
+    }
+    
+   
+    //
+    // If the file is tiled, verify that the tile description has reasonable
     // values and check to see if the lineOrder is one of the predefined 3.
     // If the file is not tiled, then the lineOrder can only be INCREASING_Y
     // or DECREASING_Y.
@@ -702,48 +892,50 @@ Header::sanityCheck (bool isTiled) const
     {
 	if (!hasTileDescription())
 	{
-	    throw Iex::ArgExc ("Tiled image has no tile "
+	    throw IEX_NAMESPACE::ArgExc ("Tiled image has no tile "
 			       "description attribute.");
 	}
 
 	const TileDescription &tileDesc = tileDescription();
 
 	if (tileDesc.xSize <= 0 || tileDesc.ySize <= 0)
-	    throw Iex::ArgExc ("Invalid tile size in image header.");
+	    throw IEX_NAMESPACE::ArgExc ("Invalid tile size in image header.");
 
 	if (maxTileWidth > 0 &&
-	    maxTileWidth < tileDesc.xSize)
+	    maxTileWidth < int(tileDesc.xSize))
 	{
-	    THROW (Iex::ArgExc, "The width of the tiles exceeds the maximum "
+	    THROW (IEX_NAMESPACE::ArgExc, "The width of the tiles exceeds the maximum "
 				"width of " << maxTileWidth << "pixels.");
 	}
 
 	if (maxTileHeight > 0 &&
-	    maxTileHeight < tileDesc.ySize)
+	    maxTileHeight < int(tileDesc.ySize))
 	{
-	    THROW (Iex::ArgExc, "The width of the tiles exceeds the maximum "
+	    THROW (IEX_NAMESPACE::ArgExc, "The width of the tiles exceeds the maximum "
 				"width of " << maxTileHeight << "pixels.");
 	}
 
 	if (tileDesc.mode != ONE_LEVEL &&
 	    tileDesc.mode != MIPMAP_LEVELS &&
 	    tileDesc.mode != RIPMAP_LEVELS)
-	    throw Iex::ArgExc ("Invalid level mode in image header.");
+	    throw IEX_NAMESPACE::ArgExc ("Invalid level mode in image header.");
 
 	if (tileDesc.roundingMode != ROUND_UP &&
 	    tileDesc.roundingMode != ROUND_DOWN)
-	    throw Iex::ArgExc ("Invalid level rounding mode in image header.");
+	    throw IEX_NAMESPACE::ArgExc ("Invalid level rounding mode in image header.");
 
 	if (lineOrder != INCREASING_Y &&
 	    lineOrder != DECREASING_Y &&
 	    lineOrder != RANDOM_Y)
-	    throw Iex::ArgExc ("Invalid line order in image header.");
+	    throw IEX_NAMESPACE::ArgExc ("Invalid line order in image header.");
     }
     else
     {
-	if (lineOrder != INCREASING_Y &&
-	    lineOrder != DECREASING_Y)
-	    throw Iex::ArgExc ("Invalid line order in image header.");
+        if (lineOrder != INCREASING_Y &&
+            lineOrder != DECREASING_Y)
+            throw IEX_NAMESPACE::ArgExc ("Invalid line order in image header.");
+        
+        
     }
 
     //
@@ -751,7 +943,13 @@ Header::sanityCheck (bool isTiled) const
     //
 
     if (!isValidCompression (this->compression()))
-	throw Iex::ArgExc ("Unknown compression type in image header.");
+  	throw IEX_NAMESPACE::ArgExc ("Unknown compression type in image header.");
+    
+    if(isDeepData(part_type))
+    {
+        if (!isValidDeepCompression (this->compression()))
+            throw IEX_NAMESPACE::ArgExc ("Compression type in header not valid for deep data");
+    }
 
     //
     // Check the channel list:
@@ -774,24 +972,24 @@ Header::sanityCheck (bool isTiled) const
 	     i != channels.end();
 	     ++i)
 	{
-	    if (i.channel().type != UINT &&
-		i.channel().type != HALF &&
-		i.channel().type != FLOAT)
+	    if (i.channel().type != OPENEXR_IMF_INTERNAL_NAMESPACE::UINT &&
+		    i.channel().type != OPENEXR_IMF_INTERNAL_NAMESPACE::HALF &&
+		    i.channel().type != OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT)
 	    {
-		THROW (Iex::ArgExc, "Pixel type of \"" << i.name() << "\" "
+		THROW (IEX_NAMESPACE::ArgExc, "Pixel type of \"" << i.name() << "\" "
 			            "image channel is invalid.");
 	    }
 
 	    if (i.channel().xSampling != 1)
 	    {
-		THROW (Iex::ArgExc, "The x subsampling factor for the "
+		THROW (IEX_NAMESPACE::ArgExc, "The x subsampling factor for the "
 				    "\"" << i.name() << "\" channel "
 				    "is not 1.");
 	    }	
 
 	    if (i.channel().ySampling != 1)
 	    {
-		THROW (Iex::ArgExc, "The y subsampling factor for the "
+		THROW (IEX_NAMESPACE::ArgExc, "The y subsampling factor for the "
 				    "\"" << i.name() << "\" channel "
 				    "is not 1.");
 	    }	
@@ -803,31 +1001,31 @@ Header::sanityCheck (bool isTiled) const
 	     i != channels.end();
 	     ++i)
 	{
-	    if (i.channel().type != UINT &&
-		i.channel().type != HALF &&
-		i.channel().type != FLOAT)
+	    if (i.channel().type != OPENEXR_IMF_INTERNAL_NAMESPACE::UINT &&
+		    i.channel().type != OPENEXR_IMF_INTERNAL_NAMESPACE::HALF &&
+		    i.channel().type != OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT)
 	    {
-		THROW (Iex::ArgExc, "Pixel type of \"" << i.name() << "\" "
+		THROW (IEX_NAMESPACE::ArgExc, "Pixel type of \"" << i.name() << "\" "
 			            "image channel is invalid.");
 	    }
 
 	    if (i.channel().xSampling < 1)
 	    {
-		THROW (Iex::ArgExc, "The x subsampling factor for the "
+		THROW (IEX_NAMESPACE::ArgExc, "The x subsampling factor for the "
 				    "\"" << i.name() << "\" channel "
 				    "is invalid.");
 	    }
 
 	    if (i.channel().ySampling < 1)
 	    {
-		THROW (Iex::ArgExc, "The y subsampling factor for the "
+		THROW (IEX_NAMESPACE::ArgExc, "The y subsampling factor for the "
 				    "\"" << i.name() << "\" channel "
 				    "is invalid.");
 	    }
 
 	    if (dataWindow.min.x % i.channel().xSampling)
 	    {
-		THROW (Iex::ArgExc, "The minimum x coordinate of the "
+		THROW (IEX_NAMESPACE::ArgExc, "The minimum x coordinate of the "
 				    "image's data window is not a multiple "
 				    "of the x subsampling factor of "
 				    "the \"" << i.name() << "\" channel.");
@@ -835,7 +1033,7 @@ Header::sanityCheck (bool isTiled) const
 
 	    if (dataWindow.min.y % i.channel().ySampling)
 	    {
-		THROW (Iex::ArgExc, "The minimum y coordinate of the "
+		THROW (IEX_NAMESPACE::ArgExc, "The minimum y coordinate of the "
 				    "image's data window is not a multiple "
 				    "of the y subsampling factor of "
 				    "the \"" << i.name() << "\" channel.");
@@ -844,7 +1042,7 @@ Header::sanityCheck (bool isTiled) const
 	    if ((dataWindow.max.x - dataWindow.min.x + 1) %
 		    i.channel().xSampling)
 	    {
-		THROW (Iex::ArgExc, "Number of pixels per row in the "
+		THROW (IEX_NAMESPACE::ArgExc, "Number of pixels per row in the "
 				    "image's data window is not a multiple "
 				    "of the x subsampling factor of "
 				    "the \"" << i.name() << "\" channel.");
@@ -853,7 +1051,7 @@ Header::sanityCheck (bool isTiled) const
 	    if ((dataWindow.max.y - dataWindow.min.y + 1) %
 		    i.channel().ySampling)
 	    {
-		THROW (Iex::ArgExc, "Number of pixels per column in the "
+		THROW (IEX_NAMESPACE::ArgExc, "Number of pixels per column in the "
 				    "image's data window is not a multiple "
 				    "of the y subsampling factor of "
 				    "the \"" << i.name() << "\" channel.");
@@ -879,26 +1077,23 @@ Header::setMaxTileSize (int maxWidth, int maxHeight)
 }
 
 
+bool
+Header::readsNothing()
+{
+    return _readsNothing;
+}
+
+
 Int64
-Header::writeTo (OStream &os, bool isTiled) const
+Header::writeTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, bool isTiled) const
 {
     //
     // Write a "magic number" to identify the file as an image file.
     // Write the current file format version number.
     //
 
-    Xdr::write <StreamIO> (os, MAGIC);
-
     int version = EXR_VERSION;
 
-    if (isTiled)
-        version |= TILED_FLAG;
-
-    if (usesLongNames (*this))
-        version |= LONG_NAMES_FLAG;
-
-    Xdr::write <StreamIO> (os, version);
-
     //
     // Write all attributes.  If we have a preview image attribute,
     // keep track of its position in the file.
@@ -915,8 +1110,8 @@ Header::writeTo (OStream &os, bool isTiled) const
 	// Write the attribute's name and type.
 	//
 
-	Xdr::write <StreamIO> (os, i.name());
-	Xdr::write <StreamIO> (os, i.attribute().typeName());
+	OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (os, i.name());
+	OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (os, i.attribute().typeName());
 
 	//
 	// Write the size of the attribute value,
@@ -927,60 +1122,33 @@ Header::writeTo (OStream &os, bool isTiled) const
 	i.attribute().writeValueTo (oss, version);
 
 	std::string s = oss.str();
-	Xdr::write <StreamIO> (os, (int) s.length());
+	OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (os, (int) s.length());
 
 	if (&i.attribute() == preview)
 	    previewPosition = os.tellp();
 
-	os.write (s.data(), s.length());
+	os.write (s.data(), int(s.length()));
     }
 
     //
     // Write zero-length attribute name to mark the end of the header.
     //
 
-    Xdr::write <StreamIO> (os, "");
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (os, "");
 
     return previewPosition;
 }
 
 
 void
-Header::readFrom (IStream &is, int &version)
+Header::readFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int &version)
 {
     //
-    // Read the magic number and the file format version number.
-    // Then check if we can read the rest of this file.
-    //
-
-    int magic;
-
-    Xdr::read <StreamIO> (is, magic);
-    Xdr::read <StreamIO> (is, version);
-
-    if (magic != MAGIC)
-    {
-	throw Iex::InputExc ("File is not an image file.");
-    }
-
-    if (getVersion (version) != EXR_VERSION)
-    {
-	THROW (Iex::InputExc, "Cannot read "
-			      "version " << getVersion (version) << " "
-			      "image files.  Current file format version "
-			      "is " << EXR_VERSION << ".");
-    }
-    
-    if (!supportsFlags (getFlags (version)))
-    {
-	THROW (Iex::InputExc, "The file format version number's flag field "
-			      "contains unrecognized flags.");
-    }
-
-    //
     // Read all attributes.
     //
 
+    int attrCount = 0;
+
     while (true)
     {
 	//
@@ -989,10 +1157,16 @@ Header::readFrom (IStream &is, int &version)
 	//
 
 	char name[Name::SIZE];
-	Xdr::read <StreamIO> (is, Name::MAX_LENGTH, name);
+	OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, Name::MAX_LENGTH, name);
 
 	if (name[0] == 0)
+	{
+	    if (attrCount == 0) _readsNothing = true;
+	    else                _readsNothing = false;
 	    break;
+	}
+
+	attrCount++;
 
 	checkIsNullTerminated (name, "attribute name");
 
@@ -1003,9 +1177,9 @@ Header::readFrom (IStream &is, int &version)
 	char typeName[Name::SIZE];
 	int size;
 
-	Xdr::read <StreamIO> (is, Name::MAX_LENGTH, typeName);
+	OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, Name::MAX_LENGTH, typeName);
 	checkIsNullTerminated (typeName, "attribute type name");
-	Xdr::read <StreamIO> (is, size);
+	OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, size);
 
 	AttributeMap::iterator i = _map.find (name);
 
@@ -1018,7 +1192,7 @@ Header::readFrom (IStream &is, int &version)
 	    //
 
 	    if (strncmp (i->second->typeName(), typeName, sizeof (typeName)))
-		THROW (Iex::InputExc, "Unexpected type for image attribute "
+		THROW (IEX_NAMESPACE::InputExc, "Unexpected type for image attribute "
 				      "\"" << name << "\".");
 
 	    i->second->readValueFrom (is, size, version);
@@ -1075,9 +1249,11 @@ staticInitialize ()
 	ChannelListAttribute::registerAttributeType();
 	CompressionAttribute::registerAttributeType();
 	ChromaticitiesAttribute::registerAttributeType();
+	DeepImageStateAttribute::registerAttributeType();
 	DoubleAttribute::registerAttributeType();
 	EnvmapAttribute::registerAttributeType();
 	FloatAttribute::registerAttributeType();
+	FloatVectorAttribute::registerAttributeType();
 	IntAttribute::registerAttributeType();
 	KeyCodeAttribute::registerAttributeType();
 	LineOrderAttribute::registerAttributeType();
@@ -1097,10 +1273,11 @@ staticInitialize ()
 	V3dAttribute::registerAttributeType();
 	V3fAttribute::registerAttributeType();
 	V3iAttribute::registerAttributeType();
+	DwaCompressor::initializeFuncs();
 
 	initialized = true;
     }
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfHeader.h b/Source/OpenEXR/IlmImf/ImfHeader.h
index bec6bc1..756a62e 100644
--- a/Source/OpenEXR/IlmImf/ImfHeader.h
+++ b/Source/OpenEXR/IlmImf/ImfHeader.h
@@ -43,29 +43,30 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfLineOrder.h>
-#include <ImfCompression.h>
-#include <ImfName.h>
-#include <ImfTileDescription.h>
-#include <ImfInt64.h>
+#include "ImfLineOrder.h"
+#include "ImfCompression.h"
+#include "ImfName.h"
+#include "ImfTileDescription.h"
+#include "ImfInt64.h"
 #include "ImathVec.h"
 #include "ImathBox.h"
 #include "IexBaseExc.h"
+
+#include "ImfForward.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
 #include <map>
 #include <iosfwd>
 #include <string>
 
-namespace Imf {
 
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-class Attribute;
-class ChannelList;
-class IStream;
-class OStream;
-class PreviewImage;
+using std::string;
 
 
-class Header
+class IMF_EXPORT Header
 {
   public:
     
@@ -77,7 +78,7 @@ class Header
     Header (int width = 64,
 	    int height = 64,
 	    float pixelAspectRatio = 1,
-	    const Imath::V2f &screenWindowCenter = Imath::V2f (0, 0),
+	    const IMATH_NAMESPACE::V2f &screenWindowCenter = IMATH_NAMESPACE::V2f (0, 0),
 	    float screenWindowWidth = 1,
 	    LineOrder lineOrder = INCREASING_Y,
 	    Compression = ZIP_COMPRESSION);
@@ -90,9 +91,9 @@ class Header
 
     Header (int width,
 	    int height,
-	    const Imath::Box2i &dataWindow,
+	    const IMATH_NAMESPACE::Box2i &dataWindow,
 	    float pixelAspectRatio = 1,
-	    const Imath::V2f &screenWindowCenter = Imath::V2f (0, 0),
+	    const IMATH_NAMESPACE::V2f &screenWindowCenter = IMATH_NAMESPACE::V2f (0, 0),
 	    float screenWindowWidth = 1,
 	    LineOrder lineOrder = INCREASING_Y,
 	    Compression = ZIP_COMPRESSION);
@@ -103,10 +104,10 @@ class Header
     // both specified explicitly.
     //----------------------------------------------------------
 
-    Header (const Imath::Box2i &displayWindow,
-	    const Imath::Box2i &dataWindow,
+    Header (const IMATH_NAMESPACE::Box2i &displayWindow,
+	    const IMATH_NAMESPACE::Box2i &dataWindow,
 	    float pixelAspectRatio = 1,
-	    const Imath::V2f &screenWindowCenter = Imath::V2f (0, 0),
+	    const IMATH_NAMESPACE::V2f &screenWindowCenter = IMATH_NAMESPACE::V2f (0, 0),
 	    float screenWindowWidth = 1,
 	    LineOrder lineOrder = INCREASING_Y,
 	    Compression = ZIP_COMPRESSION);
@@ -146,7 +147,7 @@ class Header
     //			is copied into this attribute.
     //
     //			If an attribute with name n exists, and its
-    //			type is different from attr, an Iex::TypeExc
+    //			type is different from attr, an IEX_NAMESPACE::TypeExc
     //			is thrown.
     //
     //---------------------------------------------------------------
@@ -157,19 +158,34 @@ class Header
     void			insert (const std::string &name,
 				        const Attribute &attribute);
 
+    //---------------------------------------------------------------
+    // Remove an attribute:
+    //
+    // remove(n)       If an attribute with name n exists, then it
+    //                 is removed from the map of present attributes.
+    //
+    //                 If no attribute with name n exists, then this
+    //                 functions becomes a 'no-op'
+    //
+    //---------------------------------------------------------------
+    void                        erase (const char name[]);
+    void                        erase (const std::string &name);
+
+    
+    
     //------------------------------------------------------------------
     // Access to existing attributes:
     //
     // [n]			Returns a reference to the attribute
     //				with name n.  If no attribute with
-    //				name n exists, an Iex::ArgExc is thrown.
+    //				name n exists, an IEX_NAMESPACE::ArgExc is thrown.
     //
     // typedAttribute<T>(n)	Returns a reference to the attribute
     //				with name n and type T.  If no attribute
-    //				with name n exists, an Iex::ArgExc is
+    //				with name n exists, an IEX_NAMESPACE::ArgExc is
     //				thrown.  If an attribute with name n
     //				exists, but its type is not T, an
-    //				Iex::TypeExc is thrown.
+    //				IEX_NAMESPACE::TypeExc is thrown.
     //
     // findTypedAttribute<T>(n)	Returns a pointer to the attribute with
     //				name n and type T, or 0 if no attribute
@@ -222,17 +238,17 @@ class Header
     // Access to predefined attributes
     //--------------------------------
 
-    Imath::Box2i &		displayWindow ();
-    const Imath::Box2i &	displayWindow () const;
+    IMATH_NAMESPACE::Box2i &		displayWindow ();
+    const IMATH_NAMESPACE::Box2i &	displayWindow () const;
 
-    Imath::Box2i &		dataWindow ();
-    const Imath::Box2i &	dataWindow () const;
+    IMATH_NAMESPACE::Box2i &		dataWindow ();
+    const IMATH_NAMESPACE::Box2i &	dataWindow () const;
 
     float &			pixelAspectRatio ();
     const float &		pixelAspectRatio () const;
 
-    Imath::V2f &		screenWindowCenter ();
-    const Imath::V2f &		screenWindowCenter () const;
+    IMATH_NAMESPACE::V2f &		screenWindowCenter ();
+    const IMATH_NAMESPACE::V2f &		screenWindowCenter () const;
 
     float &			screenWindowWidth ();
     const float &		screenWindowWidth () const;
@@ -247,6 +263,52 @@ class Header
     const Compression &		compression () const;
 
 
+    //-----------------------------------------------------
+    // Access to required attributes for multipart files
+    // They are optional to non-multipart files and mandatory
+    // for multipart files.
+    //-----------------------------------------------------
+    void                        setName (const string& name);
+
+    string&                     name();
+    const string&               name() const;
+
+    bool                        hasName() const;
+
+    void                        setType (const string& Type);
+
+    string&                     type();
+    const string&               type() const;
+
+    bool                        hasType() const;
+
+    void                        setVersion (const int version);
+
+    int&                        version();
+    const int&                  version() const;
+
+    bool                        hasVersion() const;
+
+    //
+    // the chunkCount attribute is set automatically when a file is written.
+    // There is no need to set it manually
+    //
+    void                        setChunkCount(int chunks);
+    bool                        hasChunkCount() const;
+    const int &                 chunkCount() const;
+    int &                       chunkCount();
+
+    
+    //
+    // for multipart files, return whether the file has a view string attribute
+    // (for the deprecated single part multiview format EXR, see ImfMultiView.h)
+    //
+    void                       setView(const string & view);
+    bool                       hasView() const;
+    string &                   view();
+    const string &             view() const;
+    
+
     //----------------------------------------------------------------------
     // Tile Description:
     //
@@ -314,7 +376,8 @@ class Header
     // header
     //-------------------------------------------------------------
 
-    void			sanityCheck (bool isTiled = false) const;
+    void			sanityCheck (bool isTiled = false,
+        			             bool isMultipartFile = false) const;
 
 
     //----------------------------------------------------------------
@@ -336,6 +399,11 @@ class Header
     static void			setMaxImageSize (int maxWidth, int maxHeight);
     static void			setMaxTileSize (int maxWidth, int maxHeight);
 
+    //
+    // Check if the header reads nothing.
+    //
+    bool                        readsNothing();
+
 
     //------------------------------------------------------------------
     // Input and output:
@@ -348,14 +416,18 @@ class Header
     //------------------------------------------------------------------
 
 
-    Int64			writeTo (OStream &os,
+    Int64			writeTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
 					 bool isTiled = false) const;
 
-    void			readFrom (IStream &is, int &version);
+    void			readFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
+        			          int &version);
+    
 
   private:
 
     AttributeMap		_map;
+
+    bool                        _readsNothing;
 };
 
 
@@ -552,7 +624,7 @@ Header::typedAttribute (const char name[])
     T *tattr = dynamic_cast <T*> (attr);
 
     if (tattr == 0)
-	throw Iex::TypeExc ("Unexpected attribute type.");
+	throw IEX_NAMESPACE::TypeExc ("Unexpected attribute type.");
 
     return *tattr;
 }
@@ -566,7 +638,7 @@ Header::typedAttribute (const char name[]) const
     const T *tattr = dynamic_cast <const T*> (attr);
 
     if (tattr == 0)
-	throw Iex::TypeExc ("Unexpected attribute type.");
+	throw IEX_NAMESPACE::TypeExc ("Unexpected attribute type.");
 
     return *tattr;
 }
@@ -622,6 +694,6 @@ Header::findTypedAttribute (const std::string &name) const
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfHuf.cpp b/Source/OpenEXR/IlmImf/ImfHuf.cpp
index 0de7d34..a375d05 100644
--- a/Source/OpenEXR/IlmImf/ImfHuf.cpp
+++ b/Source/OpenEXR/IlmImf/ImfHuf.cpp
@@ -47,17 +47,20 @@
 
 #include <ImfHuf.h>
 #include <ImfInt64.h>
-#include <ImfAutoArray.h>
+#include "ImfAutoArray.h"
+#include "ImfFastHuf.h"
 #include "Iex.h"
-#include <string.h>
-#include <assert.h>
+#include <cstring>
+#include <cassert>
 #include <algorithm>
 
 
 using namespace std;
-using namespace Iex;
+using namespace IEX_NAMESPACE;
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
-namespace Imf {
 namespace {
 
 
@@ -568,7 +571,7 @@ hufUnpackEncTable
 	}
     }
 
-    *pcode = (char *) p;
+    *pcode = const_cast<char *>(p);
 
     hufCanonicalCodeTable (hcode);
 }
@@ -726,9 +729,15 @@ inline void
 sendCode (Int64 sCode, int runCount, Int64 runCode,
 	  Int64 &c, int &lc, char *&out)
 {
-    static const int RLMIN = 32; // min count to activate run-length coding
-
-    if (runCount > RLMIN)
+    //
+    // Output a run of runCount instances of the symbol sCount.
+    // Output the symbols explicitly, or if that is shorter, output
+    // the sCode symbol once followed by a runCode symbol and runCount
+    // expressed as an 8-bit number.
+    //
+    
+    if (hufLength (sCode) + hufLength (runCode) + 8 <
+        hufLength (sCode) * runCount)
     {
 	outputCode (sCode, c, lc, out);
 	outputCode (runCode, c, lc, out);
@@ -1012,7 +1021,8 @@ hufCompress (const unsigned short raw[],
 
     countFrequencies (freq, raw, nRaw);
 
-    int im, iM;
+    int im = 0;
+    int iM = 0;
     hufBuildEncTable (freq, &im, &iM);
 
     char *tableStart = compressed + 20;
@@ -1058,29 +1068,47 @@ hufUncompress (const char compressed[],
 
     const char *ptr = compressed + 20;
 
-    AutoArray <Int64, HUF_ENCSIZE> freq;
-    AutoArray <HufDec, HUF_DECSIZE> hdec;
-
-    hufClearDecTable (hdec);
-
-    hufUnpackEncTable (&ptr, nCompressed - (ptr - compressed), im, iM, freq);
+    // 
+    // Fast decoder needs at least 2x64-bits of compressed data, and
+    // needs to be run-able on this platform. Otherwise, fall back
+    // to the original decoder
+    //
 
-    try
+    if (FastHufDecoder::enabled() && nBits > 128)
     {
-	if (nBits > 8 * (nCompressed - (ptr - compressed)))
-	    invalidNBits();
-
-	hufBuildDecTable (freq, im, iM, hdec);
-	hufDecode (freq, hdec, ptr, nBits, iM, nRaw, raw);
+        FastHufDecoder fhd (ptr, nCompressed - (ptr - compressed), im, iM, iM);
+        fhd.decode ((unsigned char*)ptr, nBits, raw, nRaw);
     }
-    catch (...)
+    else
     {
-	hufFreeDecTable (hdec);
-	throw;
+        AutoArray <Int64, HUF_ENCSIZE> freq;
+        AutoArray <HufDec, HUF_DECSIZE> hdec;
+
+        hufClearDecTable (hdec);
+
+        hufUnpackEncTable (&ptr,
+                           nCompressed - (ptr - compressed),
+                           im,
+                           iM,
+                           freq);
+
+        try
+        {
+            if (nBits > 8 * (nCompressed - (ptr - compressed)))
+                invalidNBits();
+
+            hufBuildDecTable (freq, im, iM, hdec);
+            hufDecode (freq, hdec, ptr, nBits, iM, nRaw, raw);
+        }
+        catch (...)
+        {
+            hufFreeDecTable (hdec);
+            throw;
+        }
+
+        hufFreeDecTable (hdec);
     }
-
-    hufFreeDecTable (hdec);
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfHuf.h b/Source/OpenEXR/IlmImf/ImfHuf.h
index 5134dfd..fa89604 100644
--- a/Source/OpenEXR/IlmImf/ImfHuf.h
+++ b/Source/OpenEXR/IlmImf/ImfHuf.h
@@ -37,6 +37,8 @@
 #ifndef INCLUDED_IMF_HUF_H
 #define INCLUDED_IMF_HUF_H
 
+#include "ImfExport.h"
+#include "ImfNamespace.h"
 
 //-----------------------------------------------------------------------------
 //
@@ -58,15 +60,16 @@
 //
 //-----------------------------------------------------------------------------
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
+IMF_EXPORT 
 int
 hufCompress (const unsigned short raw[/*nRaw*/],
 	     int nRaw,
 	     char compressed[/*2 * nRaw + 65536*/]);
 
-
+IMF_EXPORT
 void
 hufUncompress (const char compressed[/*nCompressed*/],
 	       int nCompressed,
@@ -74,6 +77,6 @@ hufUncompress (const char compressed[/*nCompressed*/],
 	       int nRaw);
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfIO.cpp b/Source/OpenEXR/IlmImf/ImfIO.cpp
index 711cdbb..c52fc54 100644
--- a/Source/OpenEXR/IlmImf/ImfIO.cpp
+++ b/Source/OpenEXR/IlmImf/ImfIO.cpp
@@ -41,8 +41,9 @@
 
 #include <ImfIO.h>
 #include "Iex.h"
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 IStream::IStream (const char fileName[]): _fileName (fileName)
@@ -67,7 +68,7 @@ IStream::isMemoryMapped () const
 char *
 IStream::readMemoryMapped (int n)
 {
-    throw Iex::InputExc ("Attempt to perform a memory-mapped read "
+    throw IEX_NAMESPACE::InputExc ("Attempt to perform a memory-mapped read "
 			 "on a file that is not memory mapped.");
     return 0;
 }
@@ -106,4 +107,4 @@ OStream::fileName () const
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfIO.h b/Source/OpenEXR/IlmImf/ImfIO.h
index 44f51a3..4416d17 100644
--- a/Source/OpenEXR/IlmImf/ImfIO.h
+++ b/Source/OpenEXR/IlmImf/ImfIO.h
@@ -42,16 +42,20 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfInt64.h>
+#include "ImfInt64.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
 #include <string>
 
-namespace Imf {
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 //-----------------------------------------------------------
 // class IStream -- an abstract base class for input streams.
 //-----------------------------------------------------------
 
-class IStream
+class IMF_EXPORT IStream
 {
   public:
 
@@ -148,7 +152,7 @@ class IStream
 // class OStream -- an abstract base class for output streams
 //-----------------------------------------------------------
 
-class OStream
+class IMF_EXPORT OStream
 {
   public:
 
@@ -216,13 +220,13 @@ struct StreamIO
     static void
     writeChars (OStream &os, const char c[/*n*/], int n)
     {
-	os.write (c, n);
+        os.write (c, n);
     }
 
     static bool
     readChars (IStream &is, char c[/*n*/], int n)
     {
-	return is.read (c, n);
+        return is.read (c, n);
     }
 };
 
@@ -232,21 +236,20 @@ struct CharPtrIO
     static void
     writeChars (char *&op, const char c[/*n*/], int n)
     {
-	while (n--)
-	    *op++ = *c++;
+        while (n--)
+            *op++ = *c++;
     }
 
     static bool
     readChars (const char *&ip, char c[/*n*/], int n)
     {
-	while (n--)
-	    *c++ = *ip++;
+        while (n--)
+            *c++ = *ip++;
 
-	return true;
+        return true;
     }
 };
 
-
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfInputFile.cpp b/Source/OpenEXR/IlmImf/ImfInputFile.cpp
index e8b6425..3f4f861 100644
--- a/Source/OpenEXR/IlmImf/ImfInputFile.cpp
+++ b/Source/OpenEXR/IlmImf/ImfInputFile.cpp
@@ -38,29 +38,38 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfInputFile.h>
-#include <ImfScanLineInputFile.h>
-#include <ImfTiledInputFile.h>
-#include <ImfChannelList.h>
-#include <ImfMisc.h>
-#include <ImfStdIO.h>
-#include <ImfVersion.h>
+#include "ImfInputFile.h"
+#include "ImfScanLineInputFile.h"
+#include "ImfTiledInputFile.h"
+#include "ImfChannelList.h"
+#include "ImfMisc.h"
+#include "ImfStdIO.h"
+#include "ImfVersion.h"
+#include "ImfPartType.h"
+#include "ImfInputPartData.h"
+#include "ImfMultiPartInputFile.h"
+
+#include <ImfCompositeDeepScanLine.h>
+#include <ImfDeepScanLineInputFile.h>
+
 #include "ImathFun.h"
 #include "IlmThreadMutex.h"
 #include "Iex.h"
 #include "half.h"
+
 #include <fstream>
 #include <algorithm>
 
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
-using Imath::Box2i;
-using Imath::divp;
-using Imath::modp;
-using IlmThread::Mutex;
-using IlmThread::Lock;
+using IMATH_NAMESPACE::Box2i;
+using IMATH_NAMESPACE::divp;
+using IMATH_NAMESPACE::modp;
+using ILMTHREAD_NAMESPACE::Mutex;
+using ILMTHREAD_NAMESPACE::Lock;
 
 
 //
@@ -68,43 +77,60 @@ using IlmThread::Lock;
 // needed between calls to readPixels
 //
 
-struct InputFile::Data: public Mutex
+struct InputFile::Data : public Mutex
 {
     Header              header;
     int                 version;
-    IStream *		is;
-    bool		deleteStream;
+    bool                isTiled;
 
     TiledInputFile *	tFile;
     ScanLineInputFile *	sFile;
+    DeepScanLineInputFile * dsFile;
 
     LineOrder		lineOrder;      // the file's lineorder
     int			minY;           // data window's min y coord
     int			maxY;           // data window's max x coord
     
-    FrameBuffer		tFileBuffer;
+    FrameBuffer		tFileBuffer; 
     FrameBuffer *	cachedBuffer;
+    CompositeDeepScanLine * compositor; // for loading deep files
     
     int			cachedTileY;
     int                 offset;
     
     int                 numThreads;
 
-     Data (bool del, int numThreads);
+    int                 partNumber;
+    InputPartData*      part;
+
+    bool                multiPartBackwardSupport;
+    MultiPartInputFile* multiPartFile;
+    InputStreamMutex    * _streamData;
+    bool                _deleteStream;
+
+     Data (int numThreads);
     ~Data ();
 
     void		deleteCachedBuffer();
 };
 
 
-InputFile::Data::Data (bool del, int numThreads):
-    is (0),
-    deleteStream (del),
+InputFile::Data::Data (int numThreads):
+    isTiled (false),
     tFile (0),
     sFile (0),
+    dsFile(0),
     cachedBuffer (0),
+    compositor(0),
     cachedTileY (-1),
-    numThreads (numThreads)
+    numThreads (numThreads),
+    partNumber (-1),
+    part(NULL),
+    multiPartBackwardSupport (false),
+    multiPartFile (0),
+    _streamData(0),
+    _deleteStream(false)
+           
 {
     // empty
 }
@@ -112,13 +138,19 @@ InputFile::Data::Data (bool del, int numThreads):
 
 InputFile::Data::~Data ()
 {
-    delete tFile;
-    delete sFile;
-
-    if (deleteStream)
-	delete is;
+    if (tFile)
+        delete tFile;
+    if (sFile)
+        delete sFile;
+    if (dsFile)
+        delete dsFile;
+    if (compositor)
+        delete compositor;
 
     deleteCachedBuffer();
+
+    if (multiPartBackwardSupport && multiPartFile)
+        delete multiPartFile;
 }
 
 
@@ -140,20 +172,22 @@ InputFile::Data::deleteCachedBuffer()
 
 	    switch (s.type)
 	    {
-	      case UINT:
+	      case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
 
 		delete [] (((unsigned int *)s.base) + offset);
 		break;
 
-	      case HALF:
+	      case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
 
 		delete [] ((half *)s.base + offset);
 		break;
 
-	      case FLOAT:
+	      case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
 
 		delete [] (((float *)s.base) + offset);
 		break;
+              case NUM_PIXELTYPES :
+                  throw(IEX_NAMESPACE::ArgExc("Invalid pixel type"));
 	    }                
 	}
 
@@ -161,7 +195,7 @@ InputFile::Data::deleteCachedBuffer()
 	// delete the cached frame buffer
 	//
 
-	delete cachedBuffer;        
+	delete cachedBuffer;
 	cachedBuffer = 0;
     }
 }
@@ -184,7 +218,7 @@ bufferedReadPixels (InputFile::Data* ifd, int scanLine1, int scanLine2)
 
     if (minY < ifd->minY || maxY >  ifd->maxY)
     {
-        throw Iex::ArgExc ("Tried to read scan line outside "
+        throw IEX_NAMESPACE::ArgExc ("Tried to read scan line outside "
 			   "the image file's data window.");
     }
 
@@ -293,7 +327,7 @@ bufferedReadPixels (InputFile::Data* ifd, int scanLine1, int scanLine2)
 		     x <= levelRange.max.x;
 		     x += toSlice.xSampling)
                 {
-		    for (size_t i = 0; i < size; ++i)
+		    for (int i = 0; i < size; ++i)
 			toPtr[i] = fromPtr[i];
 
 		    fromPtr += fromSlice.xStride * toSlice.xSampling;
@@ -309,16 +343,57 @@ bufferedReadPixels (InputFile::Data* ifd, int scanLine1, int scanLine2)
 
 
 InputFile::InputFile (const char fileName[], int numThreads):
-    _data (new Data (true, numThreads))
+    _data (new Data (numThreads))
 {
+    _data->_streamData = NULL;
+    _data->_deleteStream=true;
+    
+    OPENEXR_IMF_INTERNAL_NAMESPACE::IStream* is = 0;
     try
     {
-	_data->is = new StdIFStream (fileName);
-	initialize();
+        is = new StdIFStream (fileName);
+        readMagicNumberAndVersionField(*is, _data->version);
+
+        //
+        // compatibility to read multipart file.
+        //
+        if (isMultiPart(_data->version))
+        {
+            compatibilityInitialize(*is);
+        }
+        else
+        {
+            _data->_streamData = new InputStreamMutex();
+            _data->_streamData->is = is;
+            _data->header.readFrom (*_data->_streamData->is, _data->version);
+            
+            // fix type attribute in single part regular image types
+            // (may be wrong if an old version of OpenEXR converts
+            // a tiled image to scanline or vice versa)
+            if(!isNonImage(_data->version)  && 
+               !isMultiPart(_data->version) && 
+               _data->header.hasType())
+            {
+                _data->header.setType(isTiled(_data->version) ? TILEDIMAGE : SCANLINEIMAGE);
+            }
+            
+            _data->header.sanityCheck (isTiled (_data->version));
+
+            initialize();
+        }
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
-	delete _data;
+        if (is)          delete is;
+         
+        if ( _data && !_data->multiPartBackwardSupport  && _data->_streamData)
+        {
+            delete _data->_streamData;
+            _data->_streamData=NULL;
+        }
+        
+        if (_data)       delete _data;
+        _data=NULL;
 
         REPLACE_EXC (e, "Cannot read image file "
 			"\"" << fileName << "\". " << e);
@@ -326,23 +401,60 @@ InputFile::InputFile (const char fileName[], int numThreads):
     }
     catch (...)
     {
-	delete _data;
+        if (is)          delete is;
+        if (_data && !_data->multiPartBackwardSupport && _data->_streamData)
+        {
+            delete _data->_streamData;
+        }
+        if (_data)       delete _data;
+
         throw;
     }
 }
 
 
-InputFile::InputFile (IStream &is, int numThreads):
-    _data (new Data (false, numThreads))
+InputFile::InputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int numThreads):
+    _data (new Data (numThreads))
 {
+    _data->_streamData=NULL;
+    _data->_deleteStream=false;
     try
     {
-	_data->is = &is;
-	initialize();
+        readMagicNumberAndVersionField(is, _data->version);
+
+        //
+        // Backward compatibility to read multpart file.
+        //
+        if (isMultiPart(_data->version))
+        {
+            compatibilityInitialize(is);
+        }
+        else
+        {
+            _data->_streamData = new InputStreamMutex();
+            _data->_streamData->is = &is;
+            _data->header.readFrom (*_data->_streamData->is, _data->version);
+            
+            // fix type attribute in single part regular image types
+            // (may be wrong if an old version of OpenEXR converts
+            // a tiled image to scanline or vice versa)
+            if(!isNonImage(_data->version)  && 
+               !isMultiPart(_data->version) &&  
+               _data->header.hasType())
+            {
+                _data->header.setType(isTiled(_data->version) ? TILEDIMAGE : SCANLINEIMAGE);
+            }
+            
+            _data->header.sanityCheck (isTiled (_data->version));
+
+            initialize();
+        }
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
-	delete _data;
+        if (_data && !_data->multiPartBackwardSupport && _data->_streamData) delete _data->_streamData;
+        if (_data)       delete _data;
+        _data=NULL; 
 
         REPLACE_EXC (e, "Cannot read image file "
 			"\"" << is.fileName() << "\". " << e);
@@ -350,54 +462,159 @@ InputFile::InputFile (IStream &is, int numThreads):
     }
     catch (...)
     {
-	delete _data;
+        if (_data &&  !_data->multiPartBackwardSupport  && _data->_streamData) delete _data->_streamData;
+        if (_data)       delete _data;
+        _data=NULL;
         throw;
     }
 }
 
 
+InputFile::InputFile (InputPartData* part) :
+    _data (new Data (part->numThreads))
+{
+    _data->_deleteStream=false;
+    multiPartInitialize (part);
+}
+
+
 void
-InputFile::initialize ()
+InputFile::compatibilityInitialize (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream& is)
 {
-    _data->header.readFrom (*_data->is, _data->version);
-    _data->header.sanityCheck (isTiled (_data->version));
+    is.seekg(0);
 
-    if (isTiled (_data->version))
-    {
-	_data->lineOrder = _data->header.lineOrder();
+    //
+    // Construct a MultiPartInputFile, initialize InputFile
+    // with the part 0 data.
+    // (TODO) may want to have a way to set the reconstruction flag.
+    //
+    _data->multiPartBackwardSupport = true;
+    _data->multiPartFile = new MultiPartInputFile(is, _data->numThreads);
+    InputPartData* part = _data->multiPartFile->getPart(0);
+
+    multiPartInitialize (part);
+}
 
-	//
-	// Save the dataWindow information
-	//
 
-	const Box2i &dataWindow = _data->header.dataWindow();
-	_data->minY = dataWindow.min.y;
-	_data->maxY = dataWindow.max.y;
+void
+InputFile::multiPartInitialize (InputPartData* part)
+{
+    _data->_streamData = part->mutex;
+    _data->version = part->version;
+    _data->header = part->header;
+    _data->partNumber = part->partNumber;
+    _data->part = part;
+
+    initialize();
+}
+
+
+void
+InputFile::initialize ()
+{
+    if (!_data->part)
+    {
+        if(_data->header.hasType() && _data->header.type()==DEEPSCANLINE)
+        {
+            _data->isTiled=false;
+            const Box2i &dataWindow = _data->header.dataWindow();
+            _data->minY = dataWindow.min.y;
+            _data->maxY = dataWindow.max.y;
+            
+            _data->dsFile = new DeepScanLineInputFile (_data->header,
+                                               _data->_streamData->is,
+                                               _data->version,
+                                               _data->numThreads);
+            _data->compositor = new CompositeDeepScanLine;
+            _data->compositor->addSource(_data->dsFile);
+        }
+        
+        else if (isTiled (_data->version))
+        {
+            _data->isTiled = true;
+            _data->lineOrder = _data->header.lineOrder();
+
+            //
+            // Save the dataWindow information
+            //
     
-	_data->tFile = new TiledInputFile (_data->header,
-					   _data->is,
-					   _data->version,
-                                           _data->numThreads);
+            const Box2i &dataWindow = _data->header.dataWindow();
+            _data->minY = dataWindow.min.y;
+            _data->maxY = dataWindow.max.y;
+
+            _data->tFile = new TiledInputFile (_data->header,
+                                               _data->_streamData->is,
+                                               _data->version,
+                                               _data->numThreads);
+        }
+        
+        else if(!_data->header.hasType() || _data->header.type()==SCANLINEIMAGE)
+        {
+            _data->sFile = new ScanLineInputFile (_data->header,
+                                                  _data->_streamData->is,
+                                                  _data->numThreads);
+        }else{
+            // type set but not recognised
+            
+            THROW(IEX_NAMESPACE::ArgExc, "InputFile cannot handle parts of type " << _data->header.type());
+        }
     }
     else
     {
-	_data->sFile = new ScanLineInputFile (_data->header,
-					      _data->is,
-                                              _data->numThreads);
+        if(_data->header.hasType() && _data->header.type()==DEEPSCANLINE)
+        {
+            _data->isTiled=false;
+            const Box2i &dataWindow = _data->header.dataWindow();
+            _data->minY = dataWindow.min.y;
+            _data->maxY = dataWindow.max.y;
+            
+            _data->dsFile = new DeepScanLineInputFile (_data->part);
+            _data->compositor = new CompositeDeepScanLine;
+            _data->compositor->addSource(_data->dsFile);
+        }
+        else if (isTiled (_data->header.type()))
+        {
+            _data->isTiled = true;
+            _data->lineOrder = _data->header.lineOrder();
+
+            //
+            // Save the dataWindow information
+            //
+
+            const Box2i &dataWindow = _data->header.dataWindow();
+            _data->minY = dataWindow.min.y;
+            _data->maxY = dataWindow.max.y;
+
+            _data->tFile = new TiledInputFile (_data->part);
+        }
+        else if(!_data->header.hasType() || _data->header.type()==SCANLINEIMAGE)
+        {
+            _data->sFile = new ScanLineInputFile (_data->part);
+        }else{
+            THROW(IEX_NAMESPACE::ArgExc, "InputFile cannot handle parts of type " << _data->header.type());
+            
+        }
     }
 }
 
-
+#include <iostream>
 InputFile::~InputFile ()
 {
-    delete _data;
-}
+    if (_data->_deleteStream)
+        delete _data->_streamData->is;
 
+    // unless this file was opened via the multipart API,
+    // delete the streamData object too
+    if (_data->partNumber==-1 && _data->_streamData)
+        delete _data->_streamData;
+
+    if (_data)  delete _data;
+}
 
 const char *
 InputFile::fileName () const
 {
-    return _data->is->fileName();
+    return _data->_streamData->is->fileName();
 }
 
 
@@ -418,7 +635,7 @@ InputFile::version () const
 void
 InputFile::setFrameBuffer (const FrameBuffer &frameBuffer)
 {
-    if (isTiled (_data->version))
+    if (_data->isTiled)
     {
 	Lock lock (*_data);
 
@@ -473,7 +690,7 @@ InputFile::setFrameBuffer (const FrameBuffer &frameBuffer)
 
 		switch (s.type)
 		{
-		  case UINT:
+		  case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
 
 		    _data->cachedBuffer->insert
 			(k.name(),
@@ -488,7 +705,7 @@ InputFile::setFrameBuffer (const FrameBuffer &frameBuffer)
 				false, true));
 		    break;
 
-		  case HALF:
+		  case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
 
 		    _data->cachedBuffer->insert
 			(k.name(),
@@ -503,11 +720,11 @@ InputFile::setFrameBuffer (const FrameBuffer &frameBuffer)
 				false, true));
 		    break;
 
-		  case FLOAT:
+		  case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
 
 		    _data->cachedBuffer->insert
 			(k.name(),
-			 Slice (FLOAT,
+			 Slice (OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT,
 				(char *)(new float[tileRowSize] - 
 					_data->offset),
 				sizeof(float),
@@ -520,7 +737,7 @@ InputFile::setFrameBuffer (const FrameBuffer &frameBuffer)
 
 		  default:
 
-		    throw Iex::ArgExc ("Unknown pixel data type.");
+		    throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
 		}
 	    }
 
@@ -529,9 +746,12 @@ InputFile::setFrameBuffer (const FrameBuffer &frameBuffer)
 
 	_data->tFileBuffer = frameBuffer;
     }
-    else
+    else if(_data->compositor)
     {
-        _data->sFile->setFrameBuffer (frameBuffer);
+        _data->compositor->setFrameBuffer(frameBuffer);
+    }else {
+        _data->sFile->setFrameBuffer(frameBuffer);
+        _data->tFileBuffer = frameBuffer;
     }
 }
 
@@ -539,7 +759,11 @@ InputFile::setFrameBuffer (const FrameBuffer &frameBuffer)
 const FrameBuffer &
 InputFile::frameBuffer () const
 {
-    if (isTiled (_data->version))
+    if(_data->compositor)
+    {
+        return _data->compositor->frameBuffer();
+    }
+    else if(_data->isTiled)
     {
 	Lock lock (*_data);
 	return _data->tFileBuffer;
@@ -554,17 +778,34 @@ InputFile::frameBuffer () const
 bool
 InputFile::isComplete () const
 {
-    if (isTiled (_data->version))
+    if (_data->dsFile)
+        return _data->dsFile->isComplete();
+    else if (_data->isTiled)
 	return _data->tFile->isComplete();
     else
 	return _data->sFile->isComplete();
 }
 
+bool
+InputFile::isOptimizationEnabled() const
+{
+   if(_data->sFile)
+   {
+       return _data->sFile->isOptimizationEnabled();
+   }else{
+       return false;
+   }
+}
+
 
 void
 InputFile::readPixels (int scanLine1, int scanLine2)
 {
-    if (isTiled (_data->version))
+    if (_data->compositor)
+    {
+        _data->compositor->readPixels(scanLine1,scanLine2);
+    }
+    else if (_data->isTiled)
     {
 	Lock lock (*_data);
         bufferedReadPixels (_data, scanLine1, scanLine2);
@@ -590,15 +831,21 @@ InputFile::rawPixelData (int firstScanLine,
 {
     try
     {
-	if (isTiled (_data->version))
+        if (_data->dsFile)
+        {
+            throw IEX_NAMESPACE::ArgExc ("Tried to read a raw scanline "
+            "from a deep image.");
+        }
+        
+	else if (_data->isTiled)
 	{
-	    throw Iex::ArgExc ("Tried to read a raw scanline "
+	    throw IEX_NAMESPACE::ArgExc ("Tried to read a raw scanline "
 			       "from a tiled image.");
 	}
         
         _data->sFile->rawPixelData (firstScanLine, pixelData, pixelDataSize);
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
 	REPLACE_EXC (e, "Error reading pixel data from image "
 		        "file \"" << fileName() << "\". " << e);
@@ -615,15 +862,15 @@ InputFile::rawTileData (int &dx, int &dy,
 {
     try
     {
-	if (!isTiled (_data->version))
+	if (!_data->isTiled)
 	{
-	    throw Iex::ArgExc ("Tried to read a raw tile "
+	    throw IEX_NAMESPACE::ArgExc ("Tried to read a raw tile "
 			       "from a scanline-based image.");
 	}
         
         _data->tFile->rawTileData (dx, dy, lx, ly, pixelData, pixelDataSize);
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
 	REPLACE_EXC (e, "Error reading tile data from image "
 		        "file \"" << fileName() << "\". " << e);
@@ -635,9 +882,9 @@ InputFile::rawTileData (int &dx, int &dy,
 TiledInputFile*
 InputFile::tFile()
 {
-    if (!isTiled (_data->version))
+    if (!_data->isTiled)
     {
-	throw Iex::ArgExc ("Cannot get a TiledInputFile pointer "
+	throw IEX_NAMESPACE::ArgExc ("Cannot get a TiledInputFile pointer "
 			   "from an InputFile that is not tiled.");
     }
 
@@ -645,4 +892,4 @@ InputFile::tFile()
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfInputFile.h b/Source/OpenEXR/IlmImf/ImfInputFile.h
index af9256b..42c6352 100644
--- a/Source/OpenEXR/IlmImf/ImfInputFile.h
+++ b/Source/OpenEXR/IlmImf/ImfInputFile.h
@@ -43,20 +43,22 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfHeader.h>
-#include <ImfFrameBuffer.h>
-#include <ImfTiledOutputFile.h>
-#include <string>
+#include "ImfHeader.h"
+#include "ImfFrameBuffer.h"
+#include "ImfTiledOutputFile.h"
+#include "ImfThreading.h"
+#include "ImfGenericInputFile.h"
+#include "ImfNamespace.h"
+#include "ImfForward.h"
+#include "ImfExport.h"
+
 #include <fstream>
-#include <ImfThreading.h>
 
-namespace Imf {
 
-class TiledInputFile;
-class ScanLineInputFile;
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
-class InputFile
+class IMF_EXPORT InputFile : public GenericInputFile
 {
   public:
 
@@ -80,7 +82,7 @@ class InputFile
     // used to read the file (see ImfThreading.h).
     //-------------------------------------------------------------
 
-    InputFile (IStream &is, int numThreads = globalThreadCount());
+    InputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int numThreads = globalThreadCount());
 
 
     //-----------
@@ -143,6 +145,29 @@ class InputFile
 
     bool		isComplete () const;
 
+    
+    //---------------------------------------------------------------
+    // Check if SSE optimization is enabled
+    //
+    // Call after setFrameBuffer() to query whether optimized file decoding
+    // is available - decode times will be faster if returns true
+    //
+    // Optimization depends on:
+    //   the file type (only scanline data is supported),
+    //   the framebuffer channels (RGB/RGBA mono or stereo)
+    //   the framebuffer channel types (all channels half-float format only)
+    //   the file channels (RGB/RGBA mono or stereo)
+    //   the file channel types (all channel half-float format only)
+    //   whether SSE2 instruction support was detected at compile time
+    //
+    // Calling isOptimizationEnabled before setFrameBuffer will throw an exception
+    //
+    //---------------------------------------------------------------
+    
+    bool                isOptimizationEnabled () const;
+    
+    
+    
 
     //---------------------------------------------------------------
     // Read pixel data:
@@ -192,18 +217,24 @@ class InputFile
     
   private:
 
+    InputFile (InputPartData* part);
     InputFile (const InputFile &);			// not implemented
     InputFile & operator = (const InputFile &);		// not implemented
 
     void		initialize ();
+    void                multiPartInitialize(InputPartData* part);
+    void                compatibilityInitialize(OPENEXR_IMF_INTERNAL_NAMESPACE::IStream& is);
     TiledInputFile *	tFile ();
     
     friend void TiledOutputFile::copyPixels (InputFile &);
     
     Data *		_data;
+
+
+    friend class MultiPartInputFile;
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfInputPart.cpp b/Source/OpenEXR/IlmImf/ImfInputPart.cpp
new file mode 100644
index 0000000..7cfce0f
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfInputPart.cpp
@@ -0,0 +1,114 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#include "ImfInputPart.h"
+#include "ImfNamespace.h"
+
+#include "ImfMultiPartInputFile.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+InputPart::InputPart(MultiPartInputFile& multiPartFile, int partNumber)
+{
+    file = multiPartFile.getInputPart<InputFile>(partNumber);
+}
+
+const char *
+InputPart::fileName () const
+{
+    return file->fileName();
+}
+
+const Header &
+InputPart::header () const
+{
+    return file->header();
+}
+
+int
+InputPart::version () const
+{
+    return file->version();
+}
+
+void
+InputPart::setFrameBuffer (const FrameBuffer &frameBuffer)
+{
+    file->setFrameBuffer(frameBuffer);
+}
+
+const FrameBuffer &
+InputPart::frameBuffer () const
+{
+    return file->frameBuffer();
+}
+
+bool
+InputPart::isComplete () const
+{
+    return file->isComplete();
+}
+
+bool
+InputPart::isOptimizationEnabled() const
+{
+   return file->isOptimizationEnabled();
+}
+
+void
+InputPart::readPixels (int scanLine1, int scanLine2)
+{
+    file->readPixels(scanLine1, scanLine2);
+}
+
+void
+InputPart::readPixels (int scanLine)
+{
+    file->readPixels(scanLine);
+}
+
+void
+InputPart::rawPixelData (int firstScanLine, const char *&pixelData, int &pixelDataSize)
+{
+    file->rawPixelData(firstScanLine, pixelData, pixelDataSize);
+}
+
+void
+InputPart::rawTileData (int &dx, int &dy, int &lx, int &ly,
+             const char *&pixelData, int &pixelDataSize)
+{
+    file->rawTileData(dx, dy, lx, ly, pixelData, pixelDataSize);
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfInputPart.h b/Source/OpenEXR/IlmImf/ImfInputPart.h
new file mode 100644
index 0000000..bfc30e3
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfInputPart.h
@@ -0,0 +1,84 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef IMFINPUTPART_H_
+#define IMFINPUTPART_H_
+
+#include "ImfInputFile.h"
+#include "ImfOutputPart.h"
+#include "ImfForward.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+//-------------------------------------------------------------------
+// class InputPart:
+//
+// Same interface as InputFile. Please refer to InputFile.
+//-------------------------------------------------------------------
+
+class IMF_EXPORT InputPart
+{
+    public:
+        InputPart(MultiPartInputFile& multiPartFile, int partNumber);
+
+        const char *        fileName () const;
+        const Header &      header () const;
+        int                 version () const;
+        void                setFrameBuffer (const FrameBuffer &frameBuffer);
+        const FrameBuffer & frameBuffer () const;
+        bool                isComplete () const;
+        bool                isOptimizationEnabled () const;
+        void                readPixels (int scanLine1, int scanLine2);
+        void                readPixels (int scanLine);
+        void                rawPixelData (int firstScanLine,
+                                          const char *&pixelData,
+                                          int &pixelDataSize);
+        void                rawTileData (int &dx, int &dy,
+                                         int &lx, int &ly,
+                                         const char *&pixelData,
+                                         int &pixelDataSize);
+
+    private:
+        InputFile* file;
+    // for internal use - give OutputFile and TiledOutputFile access to file for copyPixels
+    friend void OutputFile::copyPixels(InputPart&);
+    friend void TiledOutputFile::copyPixels(InputPart&);
+    
+};
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif /* IMFINPUTPART_H_ */
diff --git a/Source/OpenEXR/IlmImf/ImfInputPartData.cpp b/Source/OpenEXR/IlmImf/ImfInputPartData.cpp
new file mode 100644
index 0000000..d241aed
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfInputPartData.cpp
@@ -0,0 +1,51 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#include "ImfInputPartData.h"
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+InputPartData::InputPartData(InputStreamMutex* mutex, const Header &header,
+                             int partNumber, int numThreads, int version):
+        header(header),
+        numThreads(numThreads),
+        partNumber(partNumber),
+        version(version),       
+        mutex(mutex),
+        completed(false)
+{
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfInputPartData.h b/Source/OpenEXR/IlmImf/ImfInputPartData.h
new file mode 100644
index 0000000..e03952b
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfInputPartData.h
@@ -0,0 +1,69 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef IMFINPUTPARTDATA_H_
+#define IMFINPUTPARTDATA_H_
+
+#include <vector>
+
+#include "ImfInputStreamMutex.h"
+#include "ImfHeader.h"
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+
+struct InputPartData
+{
+        Header                  header;
+        int                     numThreads;
+        int                     partNumber;
+        int                     version;
+        InputStreamMutex*       mutex;
+        std::vector<Int64>      chunkOffsets;
+        bool                    completed;
+
+        InputPartData(InputStreamMutex* mutex, const Header &header,
+                      int partNumber, int numThreads, int version);
+
+};
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
+
+
+#endif /* IMFINPUTPARTDATA_H_ */
diff --git a/Source/OpenEXR/IlmImf/ImfInputStreamMutex.h b/Source/OpenEXR/IlmImf/ImfInputStreamMutex.h
new file mode 100644
index 0000000..c491dbe
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfInputStreamMutex.h
@@ -0,0 +1,68 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef IMFINPUTSTREAMMUTEX_H_
+#define IMFINPUTSTREAMMUTEX_H_
+
+#include "ImfIO.h"
+#include "IlmThreadMutex.h"
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+using ILMTHREAD_NAMESPACE::Mutex;
+
+//
+// Used to wrap OPENEXR_IMF_INTERNAL_NAMESPACE::IStream as a Mutex.
+//
+struct InputStreamMutex : public Mutex
+{
+    OPENEXR_IMF_INTERNAL_NAMESPACE::IStream* is;
+    Int64 currentPosition;
+
+    InputStreamMutex()
+    {
+        is = 0;
+        currentPosition = 0;
+    }
+};
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
+
+
+#endif /* IMFINPUTSTREAMMUTEX_H_ */
diff --git a/Source/OpenEXR/IlmImf/ImfInt64.h b/Source/OpenEXR/IlmImf/ImfInt64.h
index d8fdc81..761557d 100644
--- a/Source/OpenEXR/IlmImf/ImfInt64.h
+++ b/Source/OpenEXR/IlmImf/ImfInt64.h
@@ -42,11 +42,15 @@
 //----------------------------------------------------------------------------
 
 #include "ImathInt64.h"
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-using Imath::Int64;
+using IMATH_NAMESPACE::Int64;
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+
+
+
+#endif // INCLUDED_IMF_INT64_H
diff --git a/Source/OpenEXR/IlmImf/ImfIntAttribute.cpp b/Source/OpenEXR/IlmImf/ImfIntAttribute.cpp
index f233b58..7486a2e 100644
--- a/Source/OpenEXR/IlmImf/ImfIntAttribute.cpp
+++ b/Source/OpenEXR/IlmImf/ImfIntAttribute.cpp
@@ -43,7 +43,7 @@
 #include <ImfIntAttribute.h>
 
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 template <>
@@ -54,4 +54,4 @@ IntAttribute::staticTypeName ()
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT 
diff --git a/Source/OpenEXR/IlmImf/ImfIntAttribute.h b/Source/OpenEXR/IlmImf/ImfIntAttribute.h
index c67e5b1..3d271ca 100644
--- a/Source/OpenEXR/IlmImf/ImfIntAttribute.h
+++ b/Source/OpenEXR/IlmImf/ImfIntAttribute.h
@@ -43,21 +43,16 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfAttribute.h>
+#include "ImfAttribute.h"
+#include "ImfNamespace.h"
 
-
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 typedef TypedAttribute<int> IntAttribute;
-template <> const char *IntAttribute::staticTypeName ();
-
+template <> IMF_EXPORT const char *IntAttribute::staticTypeName ();
 
-} // namespace Imf
 
-// Metrowerks compiler wants the .cpp file inlined, too
-#ifdef __MWERKS__
-#include <ImfIntAttribute.cpp>
-#endif
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfKeyCode.cpp b/Source/OpenEXR/IlmImf/ImfKeyCode.cpp
index b199cf5..f90e433 100644
--- a/Source/OpenEXR/IlmImf/ImfKeyCode.cpp
+++ b/Source/OpenEXR/IlmImf/ImfKeyCode.cpp
@@ -41,8 +41,9 @@
 
 #include <ImfKeyCode.h>
 #include "Iex.h"
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
    
 KeyCode::KeyCode (int filmMfcCode,
@@ -101,7 +102,7 @@ void
 KeyCode::setFilmMfcCode (int filmMfcCode)
 {
     if (filmMfcCode < 0 || filmMfcCode > 99)
-	throw Iex::ArgExc ("Invalid key code film manufacturer code "
+	throw IEX_NAMESPACE::ArgExc ("Invalid key code film manufacturer code "
 			   "(must be between 0 and 99).");
 
     _filmMfcCode = filmMfcCode;
@@ -118,7 +119,7 @@ void
 KeyCode::setFilmType (int filmType)
 {
     if (filmType < 0 || filmType > 99)
-	throw Iex::ArgExc ("Invalid key code film type "
+	throw IEX_NAMESPACE::ArgExc ("Invalid key code film type "
 			   "(must be between 0 and 99).");
 
     _filmType = filmType;
@@ -135,7 +136,7 @@ void
 KeyCode::setPrefix (int prefix)
 {
     if (prefix < 0 || prefix > 999999)
-	throw Iex::ArgExc ("Invalid key code prefix "
+	throw IEX_NAMESPACE::ArgExc ("Invalid key code prefix "
 			   "(must be between 0 and 999999).");
 
     _prefix = prefix;
@@ -153,7 +154,7 @@ void
 KeyCode::setCount (int count)
 {
     if (count < 0 || count > 9999)
-	throw Iex::ArgExc ("Invalid key code count "
+	throw IEX_NAMESPACE::ArgExc ("Invalid key code count "
 			   "(must be between 0 and 9999).");
 
     _count = count;
@@ -171,7 +172,7 @@ void
 KeyCode::setPerfOffset (int perfOffset)
 {
     if (perfOffset < 0 || perfOffset > 119)
-	throw Iex::ArgExc ("Invalid key code perforation offset "
+	throw IEX_NAMESPACE::ArgExc ("Invalid key code perforation offset "
 			   "(must be between 0 and 119).");
 
     _perfOffset = perfOffset;
@@ -189,7 +190,7 @@ void
 KeyCode::setPerfsPerFrame (int perfsPerFrame)
 {
     if (perfsPerFrame < 1 || perfsPerFrame > 15)
-	throw Iex::ArgExc ("Invalid key code number of perforations per frame "
+	throw IEX_NAMESPACE::ArgExc ("Invalid key code number of perforations per frame "
 			   "(must be between 1 and 15).");
 
     _perfsPerFrame = perfsPerFrame;
@@ -207,10 +208,10 @@ void
 KeyCode::setPerfsPerCount (int perfsPerCount)
 {
     if (perfsPerCount < 20 || perfsPerCount > 120)
-	throw Iex::ArgExc ("Invalid key code number of perforations per count "
+	throw IEX_NAMESPACE::ArgExc ("Invalid key code number of perforations per count "
 			   "(must be between 20 and 120).");
 
     _perfsPerCount = perfsPerCount;
 }
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfKeyCode.h b/Source/OpenEXR/IlmImf/ImfKeyCode.h
index 93dd915..2146101 100644
--- a/Source/OpenEXR/IlmImf/ImfKeyCode.h
+++ b/Source/OpenEXR/IlmImf/ImfKeyCode.h
@@ -95,11 +95,13 @@
 // 			Latent Image Identification Information
 //
 //-----------------------------------------------------------------------------
+#include "ImfNamespace.h"
+#include "ImfExport.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
    
-class KeyCode
+class IMF_EXPORT KeyCode
 {
   public:
 
@@ -156,6 +158,10 @@ class KeyCode
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
+
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfKeyCodeAttribute.cpp b/Source/OpenEXR/IlmImf/ImfKeyCodeAttribute.cpp
index 00156bd..06c666b 100644
--- a/Source/OpenEXR/IlmImf/ImfKeyCodeAttribute.cpp
+++ b/Source/OpenEXR/IlmImf/ImfKeyCodeAttribute.cpp
@@ -41,8 +41,9 @@
 
 #include <ImfKeyCodeAttribute.h>
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
+using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;
 
 template <>
 const char *
@@ -54,7 +55,7 @@ KeyCodeAttribute::staticTypeName ()
 
 template <>
 void
-KeyCodeAttribute::writeValueTo (OStream &os, int version) const
+KeyCodeAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     Xdr::write <StreamIO> (os, _value.filmMfcCode());
     Xdr::write <StreamIO> (os, _value.filmType());
@@ -68,7 +69,7 @@ KeyCodeAttribute::writeValueTo (OStream &os, int version) const
 
 template <>
 void
-KeyCodeAttribute::readValueFrom (IStream &is, int size, int version)
+KeyCodeAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     int tmp;
 
@@ -95,4 +96,4 @@ KeyCodeAttribute::readValueFrom (IStream &is, int size, int version)
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT 
diff --git a/Source/OpenEXR/IlmImf/ImfKeyCodeAttribute.h b/Source/OpenEXR/IlmImf/ImfKeyCodeAttribute.h
index 9ec8f84..00d4ece 100644
--- a/Source/OpenEXR/IlmImf/ImfKeyCodeAttribute.h
+++ b/Source/OpenEXR/IlmImf/ImfKeyCodeAttribute.h
@@ -43,30 +43,31 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfAttribute.h>
-#include <ImfKeyCode.h>
+#include "ImfAttribute.h"
+#include "ImfKeyCode.h"
+#include "ImfExport.h"
 
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
-typedef TypedAttribute<KeyCode> KeyCodeAttribute;
+typedef TypedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::KeyCode> KeyCodeAttribute;
 
 template <>
+IMF_EXPORT
 const char *KeyCodeAttribute::staticTypeName ();
 
 template <>
-void KeyCodeAttribute::writeValueTo (OStream &, int) const;
+IMF_EXPORT
+void KeyCodeAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &,
+                                     int) const;
 
 template <>
-void KeyCodeAttribute::readValueFrom (IStream &, int, int);
+IMF_EXPORT
+void KeyCodeAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &,
+                                      int, int);
 
 
-} // namespace Imf
-
-// Metrowerks compiler wants the .cpp file inlined, too
-#ifdef __MWERKS__
-#include <ImfKeyCodeAttribute.cpp>
-#endif
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfLineOrder.h b/Source/OpenEXR/IlmImf/ImfLineOrder.h
index 2f91352..8f30bed 100644
--- a/Source/OpenEXR/IlmImf/ImfLineOrder.h
+++ b/Source/OpenEXR/IlmImf/ImfLineOrder.h
@@ -42,8 +42,9 @@
 //	enum LineOrder
 //
 //-----------------------------------------------------------------------------
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 enum LineOrder
@@ -59,6 +60,10 @@ enum LineOrder
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
+
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfLineOrderAttribute.cpp b/Source/OpenEXR/IlmImf/ImfLineOrderAttribute.cpp
index 6b9c0f9..aebbac7 100644
--- a/Source/OpenEXR/IlmImf/ImfLineOrderAttribute.cpp
+++ b/Source/OpenEXR/IlmImf/ImfLineOrderAttribute.cpp
@@ -41,11 +41,12 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfLineOrderAttribute.h>
+#include "ImfLineOrderAttribute.h"
 
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
+using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;
 
 template <>
 const char *
@@ -57,7 +58,7 @@ LineOrderAttribute::staticTypeName ()
 
 template <>
 void
-LineOrderAttribute::writeValueTo (OStream &os, int version) const
+LineOrderAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     unsigned char tmp = _value;
     Xdr::write <StreamIO> (os, tmp);
@@ -66,7 +67,7 @@ LineOrderAttribute::writeValueTo (OStream &os, int version) const
 
 template <>
 void
-LineOrderAttribute::readValueFrom (IStream &is, int size, int version)
+LineOrderAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     unsigned char tmp;
     Xdr::read <StreamIO> (is, tmp);
@@ -74,4 +75,4 @@ LineOrderAttribute::readValueFrom (IStream &is, int size, int version)
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT 
diff --git a/Source/OpenEXR/IlmImf/ImfLineOrderAttribute.h b/Source/OpenEXR/IlmImf/ImfLineOrderAttribute.h
index eb9301e..342c3d0 100644
--- a/Source/OpenEXR/IlmImf/ImfLineOrderAttribute.h
+++ b/Source/OpenEXR/IlmImf/ImfLineOrderAttribute.h
@@ -43,24 +43,30 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfAttribute.h>
-#include <ImfLineOrder.h>
+#include "ImfAttribute.h"
+#include "ImfLineOrder.h"
+#include "ImfExport.h"
 
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-namespace Imf {
 
+typedef TypedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::LineOrder> LineOrderAttribute;
 
-typedef TypedAttribute<LineOrder> LineOrderAttribute;
-template <> const char *LineOrderAttribute::staticTypeName ();
-template <> void LineOrderAttribute::writeValueTo (OStream &, int) const;
-template <> void LineOrderAttribute::readValueFrom (IStream &, int, int);
+template <> 
+IMF_EXPORT 
+const char *LineOrderAttribute::staticTypeName ();
 
+template <> 
+IMF_EXPORT 
+void LineOrderAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &,
+                                       int) const;
 
-} // namespace Imf
+template <> 
+IMF_EXPORT 
+void LineOrderAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &,
+                                        int, int);
 
-// Metrowerks compiler wants the .cpp file inlined, too
-#ifdef __MWERKS__
-#include <ImfLineOrderAttribute.cpp>
-#endif
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfLut.cpp b/Source/OpenEXR/IlmImf/ImfLut.cpp
index 284bd21..3209abc 100644
--- a/Source/OpenEXR/IlmImf/ImfLut.cpp
+++ b/Source/OpenEXR/IlmImf/ImfLut.cpp
@@ -45,8 +45,9 @@
 #include <ImfLut.h>
 #include <math.h>
 #include <assert.h>
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 void
@@ -62,7 +63,7 @@ HalfLut::apply (half *data, int nData, int stride) const
 
 
 void
-HalfLut::apply (const Slice &data, const Imath::Box2i &dataWindow) const
+HalfLut::apply (const Slice &data, const IMATH_NAMESPACE::Box2i &dataWindow) const
 {
     assert (data.type == HALF);
     assert (dataWindow.min.x % data.xSampling == 0);
@@ -119,7 +120,7 @@ RgbaLut::apply (Rgba *data, int nData, int stride) const
 void
 RgbaLut::apply (Rgba *base,
 		int xStride, int yStride,
-		const Imath::Box2i &dataWindow) const
+		const IMATH_NAMESPACE::Box2i &dataWindow) const
 {
     base += dataWindow.min.y * yStride;
 
@@ -173,4 +174,5 @@ round12log (half x)
     return middleval * pow (2.0, (int12log - 2000.0) / 200.0);
 }
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
+
diff --git a/Source/OpenEXR/IlmImf/ImfLut.h b/Source/OpenEXR/IlmImf/ImfLut.h
index ca702d2..b9ccc4c 100644
--- a/Source/OpenEXR/IlmImf/ImfLut.h
+++ b/Source/OpenEXR/IlmImf/ImfLut.h
@@ -45,18 +45,20 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfRgbaFile.h>
-#include <ImfFrameBuffer.h>
+#include "ImfRgbaFile.h"
+#include "ImfFrameBuffer.h"
 #include "ImathBox.h"
 #include "halfFunction.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 //
 // Lookup table for individual half channels.
 //
 
-class HalfLut
+class IMF_EXPORT HalfLut
 {
   public:
 
@@ -82,7 +84,7 @@ class HalfLut
     //---------------------------------------------------------------
 
     void apply (const Slice &data,
-		const Imath::Box2i &dataWindow) const;
+		const IMATH_NAMESPACE::Box2i &dataWindow) const;
 
   private:
 
@@ -94,7 +96,7 @@ class HalfLut
 // Lookup table for combined RGBA data.
 //
 
-class RgbaLut
+class IMF_EXPORT RgbaLut
 {
   public:
 
@@ -122,7 +124,7 @@ class RgbaLut
     void apply (Rgba *base,
 		int xStride,
 		int yStride,
-		const Imath::Box2i &dataWindow) const;
+		const IMATH_NAMESPACE::Box2i &dataWindow) const;
 
   private:
 
@@ -139,6 +141,7 @@ class RgbaLut
 // the center [2000] and that number is near 0.18.
 //
 
+IMF_EXPORT 
 half round12log (half x);
 
 
@@ -180,6 +183,6 @@ RgbaLut::RgbaLut (Function f, RgbaChannels chn):
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfMatrixAttribute.cpp b/Source/OpenEXR/IlmImf/ImfMatrixAttribute.cpp
index f4e447a..84efe7e 100644
--- a/Source/OpenEXR/IlmImf/ImfMatrixAttribute.cpp
+++ b/Source/OpenEXR/IlmImf/ImfMatrixAttribute.cpp
@@ -46,7 +46,10 @@
 #include <ImfMatrixAttribute.h>
 
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+
+using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;
 
 
 template <>
@@ -59,7 +62,7 @@ M33fAttribute::staticTypeName ()
 
 template <>
 void
-M33fAttribute::writeValueTo (OStream &os, int version) const
+M33fAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     Xdr::write <StreamIO> (os, _value[0][0]);
     Xdr::write <StreamIO> (os, _value[0][1]);
@@ -77,7 +80,7 @@ M33fAttribute::writeValueTo (OStream &os, int version) const
 
 template <>
 void
-M33fAttribute::readValueFrom (IStream &is, int size, int version)
+M33fAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     Xdr::read <StreamIO> (is, _value[0][0]);
     Xdr::read <StreamIO> (is, _value[0][1]);
@@ -103,7 +106,7 @@ M33dAttribute::staticTypeName ()
 
 template <>
 void
-M33dAttribute::writeValueTo (OStream &os, int version) const
+M33dAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     Xdr::write <StreamIO> (os, _value[0][0]);
     Xdr::write <StreamIO> (os, _value[0][1]);
@@ -121,7 +124,7 @@ M33dAttribute::writeValueTo (OStream &os, int version) const
 
 template <>
 void
-M33dAttribute::readValueFrom (IStream &is, int size, int version)
+M33dAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     Xdr::read <StreamIO> (is, _value[0][0]);
     Xdr::read <StreamIO> (is, _value[0][1]);
@@ -147,7 +150,7 @@ M44fAttribute::staticTypeName ()
 
 template <>
 void
-M44fAttribute::writeValueTo (OStream &os, int version) const
+M44fAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     Xdr::write <StreamIO> (os, _value[0][0]);
     Xdr::write <StreamIO> (os, _value[0][1]);
@@ -173,7 +176,7 @@ M44fAttribute::writeValueTo (OStream &os, int version) const
 
 template <>
 void
-M44fAttribute::readValueFrom (IStream &is, int size, int version)
+M44fAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     Xdr::read <StreamIO> (is, _value[0][0]);
     Xdr::read <StreamIO> (is, _value[0][1]);
@@ -207,7 +210,7 @@ M44dAttribute::staticTypeName ()
 
 template <>
 void
-M44dAttribute::writeValueTo (OStream &os, int version) const
+M44dAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     Xdr::write <StreamIO> (os, _value[0][0]);
     Xdr::write <StreamIO> (os, _value[0][1]);
@@ -233,7 +236,7 @@ M44dAttribute::writeValueTo (OStream &os, int version) const
 
 template <>
 void
-M44dAttribute::readValueFrom (IStream &is, int size, int version)
+M44dAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     Xdr::read <StreamIO> (is, _value[0][0]);
     Xdr::read <StreamIO> (is, _value[0][1]);
@@ -257,4 +260,4 @@ M44dAttribute::readValueFrom (IStream &is, int size, int version)
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT 
diff --git a/Source/OpenEXR/IlmImf/ImfMatrixAttribute.h b/Source/OpenEXR/IlmImf/ImfMatrixAttribute.h
index 2bb515b..31f1466 100644
--- a/Source/OpenEXR/IlmImf/ImfMatrixAttribute.h
+++ b/Source/OpenEXR/IlmImf/ImfMatrixAttribute.h
@@ -46,42 +46,38 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfAttribute.h>
+#include "ImfAttribute.h"
 #include "ImathMatrix.h"
+#include "ImfExport.h"
 
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
-typedef TypedAttribute<Imath::M33f> M33fAttribute;
-template <> const char *M33fAttribute::staticTypeName ();
-template <> void M33fAttribute::writeValueTo (OStream &, int) const;
-template <> void M33fAttribute::readValueFrom (IStream &, int, int);
+typedef TypedAttribute<IMATH_NAMESPACE::M33f> M33fAttribute;
+template <> IMF_EXPORT const char *M33fAttribute::staticTypeName ();
+template <> IMF_EXPORT void M33fAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &, int) const;
+template <> IMF_EXPORT void M33fAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &, int, int);
 
 
-typedef TypedAttribute<Imath::M33d> M33dAttribute;
-template <> const char *M33dAttribute::staticTypeName ();
-template <> void M33dAttribute::writeValueTo (OStream &, int) const;
-template <> void M33dAttribute::readValueFrom (IStream &, int, int);
+typedef TypedAttribute<IMATH_NAMESPACE::M33d> M33dAttribute;
+template <> IMF_EXPORT const char *M33dAttribute::staticTypeName ();
+template <> IMF_EXPORT void M33dAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &, int) const;
+template <> IMF_EXPORT void M33dAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &, int, int);
 
 
-typedef TypedAttribute<Imath::M44f> M44fAttribute;
-template <> const char *M44fAttribute::staticTypeName ();
-template <> void M44fAttribute::writeValueTo (OStream &, int) const;
-template <> void M44fAttribute::readValueFrom (IStream &, int, int);
+typedef TypedAttribute<IMATH_NAMESPACE::M44f> M44fAttribute;
+template <> IMF_EXPORT const char *M44fAttribute::staticTypeName ();
+template <> IMF_EXPORT void M44fAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &, int) const;
+template <> IMF_EXPORT void M44fAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &, int, int);
 
 
-typedef TypedAttribute<Imath::M44d> M44dAttribute;
-template <> const char *M44dAttribute::staticTypeName ();
-template <> void M44dAttribute::writeValueTo (OStream &, int) const;
-template <> void M44dAttribute::readValueFrom (IStream &, int, int);
+typedef TypedAttribute<IMATH_NAMESPACE::M44d> M44dAttribute;
+template <> IMF_EXPORT const char *M44dAttribute::staticTypeName ();
+template <> IMF_EXPORT void M44dAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &, int) const;
+template <> IMF_EXPORT void M44dAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &, int, int);
 
 
-} // namespace Imf
-
-// Metrowerks compiler wants the .cpp file inlined, too
-#ifdef __MWERKS__
-#include <ImfMatrixAttribute.cpp>
-#endif
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfMisc.cpp b/Source/OpenEXR/IlmImf/ImfMisc.cpp
index e13f390..37a6281 100644
--- a/Source/OpenEXR/IlmImf/ImfMisc.cpp
+++ b/Source/OpenEXR/IlmImf/ImfMisc.cpp
@@ -42,6 +42,7 @@
 
 #include <ImfMisc.h>
 #include <ImfHeader.h>
+#include <ImfAttribute.h>
 #include <ImfCompressor.h>
 #include <ImfChannelList.h>
 #include <ImfXdr.h>
@@ -49,12 +50,15 @@
 #include <Iex.h>
 #include <ImfStdIO.h>
 #include <ImfConvert.h>
+#include <ImfPartType.h>
+#include <ImfTileDescription.h>
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
-using Imath::Box2i;
-using Imath::divp;
-using Imath::modp;
+using IMATH_NAMESPACE::Box2i;
+using IMATH_NAMESPACE::divp;
+using IMATH_NAMESPACE::modp;
 using std::vector;
 
 int
@@ -64,24 +68,24 @@ pixelTypeSize (PixelType type)
 
     switch (type)
     {
-      case UINT:
+      case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
 	
 	size = Xdr::size <unsigned int> ();
 	break;
 
-      case HALF:
+      case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
 
 	size = Xdr::size <half> ();
 	break;
 
-      case FLOAT:
+      case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
 
 	size = Xdr::size <float> ();
 	break;
 
       default:
 
-	throw Iex::ArgExc ("Unknown pixel type.");
+	throw IEX_NAMESPACE::ArgExc ("Unknown pixel type.");
     }
 
     return size;
@@ -129,26 +133,114 @@ bytesPerLineTable (const Header &header,
 }
 
 
+const int&
+sampleCount(const char* base, int xStride, int yStride, int x, int y)
+{
+    const char* ptr = base + y * yStride + x * xStride;
+    int* intPtr = (int*) ptr;
+
+    return *intPtr;
+}
+
+int&
+sampleCount(char* base, int xStride, int yStride, int x, int y)
+{
+    char* ptr = base + y * yStride + x * xStride;
+    int* intPtr = (int*) ptr;
+    
+    return *intPtr;
+}
+
+
+size_t
+bytesPerDeepLineTable (const Header &header,
+                       int minY, int maxY,
+                       const char* base,
+                       int xStride,
+                       int yStride,
+                       vector<size_t> &bytesPerLine)
+{
+    const Box2i &dataWindow = header.dataWindow();
+    const ChannelList &channels = header.channels();
+
+    for (ChannelList::ConstIterator c = channels.begin();
+         c != channels.end();
+         ++c)
+    {
+        for (int y = minY; y <= maxY; ++y)
+            if (modp (y, c.channel().ySampling) == 0)
+            {
+                int nBytes = 0;
+                for (int x = dataWindow.min.x; x <= dataWindow.max.x; x++)
+                {
+                    if (modp (x, c.channel().xSampling) == 0)
+                        nBytes += pixelTypeSize (c.channel().type) *
+                                  sampleCount(base, xStride, yStride, x, y);
+                }
+                bytesPerLine[y - dataWindow.min.y] += nBytes;
+            }
+    }
+
+    size_t maxBytesPerLine = 0;
+
+    for (int y = minY; y <= maxY; ++y)
+        if (maxBytesPerLine < bytesPerLine[y - dataWindow.min.y])
+            maxBytesPerLine = bytesPerLine[y - dataWindow.min.y];
+
+    return maxBytesPerLine;
+}
+
+
+size_t
+bytesPerDeepLineTable (const Header &header,
+                       char* base,
+                       int xStride,
+                       int yStride,
+                       vector<size_t> &bytesPerLine)
+{
+    return bytesPerDeepLineTable(header,
+                                 header.dataWindow().min.y,
+                                 header.dataWindow().max.y,
+                                 base,
+                                 xStride,
+                                 yStride,
+                                 bytesPerLine);
+}
+
+
 void
 offsetInLineBufferTable (const vector<size_t> &bytesPerLine,
-			 int linesInLineBuffer,
-			 vector<size_t> &offsetInLineBuffer)
+                         int scanline1, int scanline2,
+                         int linesInLineBuffer,
+                         vector<size_t> &offsetInLineBuffer)
 {
     offsetInLineBuffer.resize (bytesPerLine.size());
 
     size_t offset = 0;
 
-    for (int i = 0; i < bytesPerLine.size(); ++i)
+    for (int i = scanline1; i <= scanline2; ++i)
     {
-	if (i % linesInLineBuffer == 0)
-	    offset = 0;
+        if (i % linesInLineBuffer == 0)
+            offset = 0;
 
-	offsetInLineBuffer[i] = offset;
-	offset += bytesPerLine[i];
+        offsetInLineBuffer[i] = offset;
+        offset += bytesPerLine[i];
     }
 }
 
 
+void
+offsetInLineBufferTable (const vector<size_t> &bytesPerLine,
+			 int linesInLineBuffer,
+			 vector<size_t> &offsetInLineBuffer)
+{
+    offsetInLineBufferTable (bytesPerLine,
+                             0, bytesPerLine.size() - 1,
+                             linesInLineBuffer,
+                             offsetInLineBuffer);
+}
+
+
 int
 lineBufferMinY (int y, int minY, int linesInLineBuffer)
 {
@@ -202,7 +294,7 @@ copyIntoFrameBuffer (const char *& readPtr,
 
         switch (typeInFrameBuffer)
         {
-	  case UINT:
+	  case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
             
             {
                 unsigned int fillVal = (unsigned int) (fillValue);
@@ -215,7 +307,7 @@ copyIntoFrameBuffer (const char *& readPtr,
             }
             break;
 
-          case HALF:
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
 
             {
                 half fillVal = half (fillValue);
@@ -228,7 +320,7 @@ copyIntoFrameBuffer (const char *& readPtr,
             }
             break;
 
-          case FLOAT:
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
 
             {
                 float fillVal = float (fillValue);
@@ -243,7 +335,7 @@ copyIntoFrameBuffer (const char *& readPtr,
 
           default:
 
-            throw Iex::ArgExc ("Unknown pixel data type.");
+            throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
         }
     }
     else if (format == Compressor::XDR)
@@ -258,11 +350,11 @@ copyIntoFrameBuffer (const char *& readPtr,
 
         switch (typeInFrameBuffer)
         {
-          case UINT:
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
     
             switch (typeInFile)
             {
-              case UINT:
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
 
                 while (writePtr <= endPtr)
                 {
@@ -271,7 +363,7 @@ copyIntoFrameBuffer (const char *& readPtr,
                 }
                 break;
 
-              case HALF:
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
 
                 while (writePtr <= endPtr)
                 {
@@ -282,7 +374,7 @@ copyIntoFrameBuffer (const char *& readPtr,
                 }
                 break;
 
-              case FLOAT:
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
 
                 while (writePtr <= endPtr)
                 {
@@ -292,14 +384,17 @@ copyIntoFrameBuffer (const char *& readPtr,
                     writePtr += xStride;
                 }
                 break;
+                
+              default:                  
+                  throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
             }
             break;
 
-          case HALF:
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
 
             switch (typeInFile)
             {
-              case UINT:
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
 
                 while (writePtr <= endPtr)
                 {
@@ -310,7 +405,7 @@ copyIntoFrameBuffer (const char *& readPtr,
                 }
                 break;
                 
-              case HALF:
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
 
                 while (writePtr <= endPtr)
                 {
@@ -319,7 +414,7 @@ copyIntoFrameBuffer (const char *& readPtr,
                 }
                 break;
 
-              case FLOAT:
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
 
                 while (writePtr <= endPtr)
                 {
@@ -329,14 +424,17 @@ copyIntoFrameBuffer (const char *& readPtr,
                     writePtr += xStride;
                 }
                 break;
+              default:
+                  
+                  throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
             }
             break;
 
-          case FLOAT:
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
 
             switch (typeInFile)
             {
-              case UINT:
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
 
                 while (writePtr <= endPtr)
                 {
@@ -347,7 +445,7 @@ copyIntoFrameBuffer (const char *& readPtr,
                 }
                 break;
 
-              case HALF:
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
 
                 while (writePtr <= endPtr)
                 {
@@ -358,7 +456,7 @@ copyIntoFrameBuffer (const char *& readPtr,
                 }
                 break;
 
-              case FLOAT:
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
 
                 while (writePtr <= endPtr)
                 {
@@ -366,12 +464,15 @@ copyIntoFrameBuffer (const char *& readPtr,
                     writePtr += xStride;
                 }
                 break;
+              default:
+                  
+                  throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
             }
             break;
 
           default:
 
-            throw Iex::ArgExc ("Unknown pixel data type.");
+            throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
         }
     }
     else
@@ -383,11 +484,11 @@ copyIntoFrameBuffer (const char *& readPtr,
 
         switch (typeInFrameBuffer)
         {
-          case UINT:
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
     
             switch (typeInFile)
             {
-              case UINT:
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
 
                 while (writePtr <= endPtr)
                 {
@@ -399,7 +500,7 @@ copyIntoFrameBuffer (const char *& readPtr,
                 }
                 break;
 
-              case HALF:
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
 
                 while (writePtr <= endPtr)
                 {
@@ -410,7 +511,7 @@ copyIntoFrameBuffer (const char *& readPtr,
                 }
                 break;
 
-              case FLOAT:
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
 
                 while (writePtr <= endPtr)
                 {
@@ -424,14 +525,18 @@ copyIntoFrameBuffer (const char *& readPtr,
                     writePtr += xStride;
                 }
                 break;
+                
+              default:
+                  
+                  throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
             }
             break;
 
-          case HALF:
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
 
             switch (typeInFile)
             {
-              case UINT:
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
 
                 while (writePtr <= endPtr)
                 {
@@ -446,17 +551,25 @@ copyIntoFrameBuffer (const char *& readPtr,
                 }
                 break;
 
-              case HALF:
-
-                while (writePtr <= endPtr)
-                {
-                    *(half *) writePtr = *(half *)readPtr;
-                    readPtr += sizeof (half);
-                    writePtr += xStride;
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
+
+                // If we're tightly packed, just memcpy
+                if (xStride == sizeof(half)) {
+                    int numBytes = endPtr-writePtr+sizeof(half);
+                    memcpy(writePtr, readPtr, numBytes);
+                    readPtr  += numBytes;
+                    writePtr += numBytes;                    
+                } else {
+                    while (writePtr <= endPtr)
+                    {
+                        *(half *) writePtr = *(half *)readPtr;
+                        readPtr += sizeof (half);
+                        writePtr += xStride;
+                    }
                 }
                 break;
 
-              case FLOAT:
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
 
                 while (writePtr <= endPtr)
                 {
@@ -470,14 +583,17 @@ copyIntoFrameBuffer (const char *& readPtr,
                     writePtr += xStride;
                 }
                 break;
+              default:
+                  
+                  throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
             }
             break;
 
-          case FLOAT:
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
 
             switch (typeInFile)
             {
-              case UINT:
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
 
                 while (writePtr <= endPtr)
                 {
@@ -492,7 +608,7 @@ copyIntoFrameBuffer (const char *& readPtr,
                 }
                 break;
 
-              case HALF:
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
 
                 while (writePtr <= endPtr)
                 {
@@ -503,7 +619,7 @@ copyIntoFrameBuffer (const char *& readPtr,
                 }
                 break;
 
-              case FLOAT:
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
 
                 while (writePtr <= endPtr)
                 {
@@ -514,12 +630,716 @@ copyIntoFrameBuffer (const char *& readPtr,
                     writePtr += xStride;
                 }
                 break;
+              default:
+                  
+                  throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
+            }
+            break;
+
+          default:
+
+            throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
+        }
+    }
+}
+
+void
+copyIntoDeepFrameBuffer (const char *& readPtr,
+                         char * base,
+                         const char* sampleCountBase,
+                         ptrdiff_t sampleCountXStride,
+                         ptrdiff_t sampleCountYStride,
+                         int y, int minX, int maxX,
+                         int xOffsetForSampleCount,
+                         int yOffsetForSampleCount,
+                         int xOffsetForData,
+                         int yOffsetForData,
+                         ptrdiff_t sampleStride,
+                         ptrdiff_t xPointerStride,
+                         ptrdiff_t yPointerStride,
+                         bool fill,
+                         double fillValue,
+                         Compressor::Format format,
+                         PixelType typeInFrameBuffer,
+                         PixelType typeInFile)
+{
+    //
+    // Copy a horizontal row of pixels from an input
+    // file's line or tile buffer to a frame buffer.
+    //
+
+    if (fill)
+    {
+        //
+        // The file contains no data for this channel.
+        // Store a default value in the frame buffer.
+        //
+
+        switch (typeInFrameBuffer)
+        {
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
+
+            {
+                unsigned int fillVal = (unsigned int) (fillValue);
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    if(writePtr)
+                    {
+                        int count = sampleCount(sampleCountBase,
+                                                sampleCountXStride,
+                                                sampleCountYStride,
+                                                x - xOffsetForSampleCount,
+                                                y - yOffsetForSampleCount);
+                        for (int i = 0; i < count; i++)
+                        {
+                            *(unsigned int *) writePtr = fillVal;
+                            writePtr += sampleStride;
+                        }
+                    }
+                }
+            }
+            break;
+
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
+
+            {
+                half fillVal = half (fillValue);
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    
+                    if(writePtr)
+                    {                            
+                        int count = sampleCount(sampleCountBase,
+                                                sampleCountXStride,
+                                                sampleCountYStride,
+                                                x - xOffsetForSampleCount,
+                                                y - yOffsetForSampleCount);
+                        for (int i = 0; i < count; i++)
+                        {
+                            *(half *) writePtr = fillVal;
+                           writePtr += sampleStride;
+                       }
+                    }
+                }
+            }
+            break;
+
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
+
+            {
+                float fillVal = float (fillValue);
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    
+                    if(writePtr)
+                    {
+                        int count = sampleCount(sampleCountBase,
+                                                sampleCountXStride,
+                                                sampleCountYStride,
+                                                x - xOffsetForSampleCount,
+                                                y - yOffsetForSampleCount);
+                        for (int i = 0; i < count; i++)
+                        {
+                            *(float *) writePtr = fillVal;
+                            writePtr += sampleStride;
+                        }
+                    }
+                }
+            }
+            break;
+
+          default:
+
+            throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
+        }
+    }
+    else if (format == Compressor::XDR)
+    {
+        //
+        // The the line or tile buffer is in XDR format.
+        //
+        // Convert the pixels from the file's machine-
+        // independent representation, and store the
+        // results in the frame buffer.
+        //
+
+        switch (typeInFrameBuffer)
+        {
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
+
+            switch (typeInFile)
+            {
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    
+                    int count = sampleCount(sampleCountBase,
+                                            sampleCountXStride,
+                                            sampleCountYStride,
+                                            x - xOffsetForSampleCount,
+                                            y - yOffsetForSampleCount);
+                    if(writePtr)
+                    {
+                   
+                        for (int i = 0; i < count; i++)
+                        {
+                            Xdr::read <CharPtrIO> (readPtr, *(unsigned int *) writePtr);
+                            writePtr += sampleStride;
+                        }
+                    }else{
+                        Xdr::skip <CharPtrIO> (readPtr,count*Xdr::size<unsigned int>());
+                    }
+                }
+                break;
+
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    
+                    int count = sampleCount(sampleCountBase,
+                                            sampleCountXStride,
+                                            sampleCountYStride,
+                                            x - xOffsetForSampleCount,
+                                            y - yOffsetForSampleCount);
+                    if(writePtr)
+                    {
+
+                        for (int i = 0; i < count; i++)
+                        {
+                            half h;
+                            Xdr::read <CharPtrIO> (readPtr, h);
+                           *(unsigned int *) writePtr = halfToUint (h);
+                           writePtr += sampleStride;
+                       }
+                    }else{
+                       Xdr::skip <CharPtrIO> (readPtr,count*Xdr::size<half>());
+                    }
+                }
+                break;
+
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    
+                    int count = sampleCount(sampleCountBase,
+                                            sampleCountXStride,
+                                            sampleCountYStride,
+                                            x - xOffsetForSampleCount,
+                                            y - yOffsetForSampleCount);
+                                                                                        
+                    if(writePtr)
+                    {
+                        for (int i = 0; i < count; i++)
+                        {
+                            float f;
+                            Xdr::read <CharPtrIO> (readPtr, f);
+                            *(unsigned int *)writePtr = floatToUint (f);
+                            writePtr += sampleStride;
+                        } 
+                     }else{
+                       Xdr::skip <CharPtrIO> (readPtr,count*Xdr::size<float>());
+                     }
+                
+                }
+                break;
+              default:
+                  throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
+            }
+            break;
+
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
+
+            switch (typeInFile)
+            {
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    
+                    int count = sampleCount(sampleCountBase,
+                                            sampleCountXStride,
+                                            sampleCountYStride,
+                                            x - xOffsetForSampleCount,
+                                            y - yOffsetForSampleCount);
+                    if(writePtr)
+                    {
+
+                        for (int i = 0; i < count; i++)
+                        {
+                            unsigned int ui;
+                            Xdr::read <CharPtrIO> (readPtr, ui);
+                            *(half *) writePtr = uintToHalf (ui);
+                            writePtr += sampleStride;
+                        }
+                    }else{
+                        Xdr::skip <CharPtrIO> (readPtr,count*Xdr::size<unsigned int>());
+                    }
+                }
+                break;
+
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    
+                    int count = sampleCount(sampleCountBase,
+                                            sampleCountXStride,
+                                            sampleCountYStride,
+                                            x - xOffsetForSampleCount,
+                                            y - yOffsetForSampleCount);
+                    if(writePtr)
+                    {
+                    
+                        for (int i = 0; i < count; i++)
+                        {
+                            Xdr::read <CharPtrIO> (readPtr, *(half *) writePtr);
+                            writePtr += sampleStride;
+                        }
+                    }else{
+                        Xdr::skip <CharPtrIO> (readPtr,count*Xdr::size<half>());
+                    }
+                }
+                break;
+
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **) (base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    
+                    int count = sampleCount(sampleCountBase,
+                                            sampleCountXStride,
+                                            sampleCountYStride,
+                                            x - xOffsetForSampleCount,
+                                            y - yOffsetForSampleCount);
+                    if(writePtr)
+                    {
+                        for (int i = 0; i < count; i++)
+                        {
+                            float f;
+                            Xdr::read <CharPtrIO> (readPtr, f);
+                            *(half *) writePtr = floatToHalf (f);
+                            writePtr += sampleStride;
+                        }
+                    }else{
+                        Xdr::skip <CharPtrIO> (readPtr,count*Xdr::size<float>());
+                    }
+                }
+                break;
+              default:
+                  
+                  throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
+            }
+            break;
+
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
+
+            switch (typeInFile)
+            {
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    
+                    int count = sampleCount(sampleCountBase,
+                                            sampleCountXStride,
+                                            sampleCountYStride,
+                                            x - xOffsetForSampleCount,
+                                            y - yOffsetForSampleCount);
+                    if(writePtr)
+                    {
+                        for (int i = 0; i < count; i++)
+                        {
+                            unsigned int ui;
+                            Xdr::read <CharPtrIO> (readPtr, ui);
+                            *(float *) writePtr = float (ui);
+                            writePtr += sampleStride;
+                        }
+                    }else{
+                        Xdr::skip <CharPtrIO> (readPtr,count*Xdr::size<unsigned int>());
+                    }
+                }
+                break;
+
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    
+                    int count = sampleCount(sampleCountBase,
+                                            sampleCountXStride,
+                                            sampleCountYStride,
+                                            x - xOffsetForSampleCount,
+                                            y - yOffsetForSampleCount);
+                    if(writePtr)
+                    {
+
+                        for (int i = 0; i < count; i++)
+                        {
+                            half h;
+                            Xdr::read <CharPtrIO> (readPtr, h);
+                            *(float *) writePtr = float (h);
+                            writePtr += sampleStride;
+                        }
+                    
+                   }else{
+                      Xdr::skip <CharPtrIO> (readPtr,count*Xdr::size<half>());
+                   }               
+                }
+                break;
+
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    
+                    int count = sampleCount(sampleCountBase,
+                                            sampleCountXStride,
+                                            sampleCountYStride,
+                                            x - xOffsetForSampleCount,
+                                            y - yOffsetForSampleCount);
+                    if(writePtr)
+                    {
+                    
+                        for (int i = 0; i < count; i++)
+                        {
+                            Xdr::read <CharPtrIO> (readPtr, *(float *) writePtr);
+                            writePtr += sampleStride;
+                        }
+                    } else{
+                        Xdr::skip <CharPtrIO> (readPtr,count*Xdr::size<float>());
+                    }      
+                    
+                }
+                break;
+              default:
+                  
+                  throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
+            }
+            break;
+
+          default:
+
+            throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
+        }
+    }
+    else
+    {
+        //
+        // The the line or tile buffer is in NATIVE format.
+        // Copy the results into the frame buffer.
+        //
+
+        switch (typeInFrameBuffer)
+        {
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
+
+            switch (typeInFile)
+            {
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    
+                    int count = sampleCount(sampleCountBase,
+                                            sampleCountXStride,
+                                            sampleCountYStride,
+                                            x - xOffsetForSampleCount,
+                                            y - yOffsetForSampleCount);
+                                            
+                    if(writePtr)
+                    {
+                         for (int i = 0; i < count; i++)
+                         {
+                             for (size_t i = 0; i < sizeof (unsigned int); ++i)
+                                 writePtr[i] = readPtr[i];
+
+                             readPtr += sizeof (unsigned int);
+                             writePtr += sampleStride;
+                         }
+                    }else{
+                        readPtr+=sizeof(unsigned int)*count;
+                    }
+                }
+                break;
+
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    
+                    int count = sampleCount(sampleCountBase,
+                                            sampleCountXStride,
+                                            sampleCountYStride,
+                                            x - xOffsetForSampleCount,
+                                            y - yOffsetForSampleCount);
+                                            
+                    if(writePtr)
+                    {
+                        for (int i = 0; i < count; i++)
+                        {
+                            half h = *(half *) readPtr;
+                            *(unsigned int *) writePtr = halfToUint (h);
+                            readPtr += sizeof (half);
+                            writePtr += sampleStride;
+                        }
+                    }else{
+                        readPtr+=sizeof(half)*count;
+                    }
+                }
+                break;
+
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    
+                    int count = sampleCount(sampleCountBase,
+                                            sampleCountXStride,
+                                            sampleCountYStride,
+                                            x - xOffsetForSampleCount,
+                                            y - yOffsetForSampleCount);
+                                            
+                    if(writePtr)
+                    {
+                    
+                        for (int i = 0; i < count; i++)
+                        {
+                            float f;
+
+                            for (size_t i = 0; i < sizeof (float); ++i)
+                                ((char *)&f)[i] = readPtr[i];
+
+                            *(unsigned int *)writePtr = floatToUint (f);
+                            readPtr += sizeof (float);
+                            writePtr += sampleStride;
+                        }
+                    }else{
+                        readPtr+=sizeof(float)*count;
+                    }
+                }
+                break;
+              default:
+                  
+                  throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
+            }
+            break;
+
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
+
+            switch (typeInFile)
+            {
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    
+                    int count = sampleCount(sampleCountBase,
+                                            sampleCountXStride,
+                                            sampleCountYStride,
+                                            x - xOffsetForSampleCount,
+                                            y - yOffsetForSampleCount);
+                                            
+                    if(writePtr)
+                    {
+                         for (int i = 0; i < count; i++)
+                         {
+                             unsigned int ui;
+ 
+                             for (size_t i = 0; i < sizeof (unsigned int); ++i)
+                                 ((char *)&ui)[i] = readPtr[i];
+  
+                             *(half *) writePtr = uintToHalf (ui);
+                             readPtr += sizeof (unsigned int);
+                             writePtr += sampleStride;
+                         }
+                    }else{
+                        readPtr+=sizeof(unsigned int)*count;
+                    }
+                }
+                break;
+
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    
+                    int count = sampleCount(sampleCountBase,
+                                            sampleCountXStride,
+                                            sampleCountYStride,
+                                            x - xOffsetForSampleCount,
+                                            y - yOffsetForSampleCount);
+                                            
+                    if(writePtr)
+                    {
+                         for (int i = 0; i < count; i++)
+                         {
+                             *(half *) writePtr = *(half *)readPtr;
+                             readPtr += sizeof (half);
+                             writePtr += sampleStride;
+                         }
+                    }else{
+                        readPtr+=sizeof(half)*count;
+                    }
+                }
+                break;
+
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    
+                    int count = sampleCount(sampleCountBase,
+                                            sampleCountXStride,
+                                            sampleCountYStride,
+                                            x - xOffsetForSampleCount,
+                                            y - yOffsetForSampleCount);
+                                            
+                    if(writePtr)
+                    {
+                         for (int i = 0; i < count; i++)
+                         {
+                            float f;
+
+                             for (size_t i = 0; i < sizeof (float); ++i)
+                                 ((char *)&f)[i] = readPtr[i];
+
+                            *(half *) writePtr = floatToHalf (f);
+                            readPtr += sizeof (float);
+                            writePtr += sampleStride;
+                         }
+                    }else{
+                        readPtr+=sizeof(float)*count;
+                    }
+                }
+                break;
+              default:
+                  
+                  throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
+            }
+            break;
+
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
+
+            switch (typeInFile)
+            {
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    
+                    int count = sampleCount(sampleCountBase,
+                                            sampleCountXStride,
+                                            sampleCountYStride,
+                                            x - xOffsetForSampleCount,
+                                            y - yOffsetForSampleCount);
+                                            
+                    if(writePtr)
+                    {
+                         for (int i = 0; i < count; i++)
+                         {
+                              unsigned int ui;
+ 
+                              for (size_t i = 0; i < sizeof (unsigned int); ++i)
+                                  ((char *)&ui)[i] = readPtr[i];
+
+                              *(float *) writePtr = float (ui);
+                              readPtr += sizeof (unsigned int);
+                              writePtr += sampleStride;
+                         }
+                    }else{
+                        readPtr+=sizeof(unsigned int)*count;
+                    }
+                }
+                break;
+
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    
+                    int count = sampleCount(sampleCountBase,
+                                            sampleCountXStride,
+                                            sampleCountYStride,
+                                            x - xOffsetForSampleCount,
+                                            y - yOffsetForSampleCount);
+                                            
+                    if(writePtr)
+                    {
+                         for (int i = 0; i < count; i++)
+                         {
+                             half h = *(half *) readPtr;
+                             *(float *) writePtr = float (h);
+                             readPtr += sizeof (half);
+                             writePtr += sampleStride;
+                         }
+                    }else{
+                        readPtr+=sizeof(half)*count;
+                    }
+                }
+                break;
+
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    
+                    int count = sampleCount(sampleCountBase,
+                                            sampleCountXStride,
+                                            sampleCountYStride,
+                                            x - xOffsetForSampleCount,
+                                            y - yOffsetForSampleCount);
+                                            
+                    if(writePtr)
+                    {
+                         for (int i = 0; i < count; i++)
+                         {
+                              for (size_t i = 0; i < sizeof (float); ++i)
+                                  writePtr[i] = readPtr[i];
+
+                             readPtr += sizeof (float);
+                             writePtr += sampleStride;
+                         }
+                    }else{
+                        readPtr+=sizeof(float)*count;
+                    }
+                }
+                break;
+              default:
+                  
+                  throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
             }
             break;
 
           default:
 
-            throw Iex::ArgExc ("Unknown pixel data type.");
+            throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
         }
     }
 }
@@ -532,24 +1352,24 @@ skipChannel (const char *& readPtr,
 {
     switch (typeInFile)
     {
-      case UINT:
+      case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
         
         Xdr::skip <CharPtrIO> (readPtr, Xdr::size <unsigned int> () * xSize);
         break;
 
-      case HALF:
+      case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
 
         Xdr::skip <CharPtrIO> (readPtr, Xdr::size <half> () * xSize);
         break;
 
-      case FLOAT:
+      case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
 
         Xdr::skip <CharPtrIO> (readPtr, Xdr::size <float> () * xSize);
         break;
 
       default:
 
-        throw Iex::ArgExc ("Unknown pixel data type.");
+        throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
     }
 }
 
@@ -562,27 +1382,27 @@ convertInPlace (char *& writePtr,
 {
     switch (type)
     {
-      case UINT:
+      case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
     
-        for (int j = 0; j < numPixels; ++j)
+        for (size_t j = 0; j < numPixels; ++j)
         {
             Xdr::write <CharPtrIO> (writePtr, *(const unsigned int *) readPtr);
             readPtr += sizeof(unsigned int);
         }
         break;
     
-      case HALF:
+      case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
     
-        for (int j = 0; j < numPixels; ++j)
+        for (size_t j = 0; j < numPixels; ++j)
         {               
             Xdr::write <CharPtrIO> (writePtr, *(const half *) readPtr);
             readPtr += sizeof(half);
         }
         break;
     
-      case FLOAT:
+      case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
     
-        for (int j = 0; j < numPixels; ++j)
+        for (size_t j = 0; j < numPixels; ++j)
         {
             Xdr::write <CharPtrIO> (writePtr, *(const float *) readPtr);
             readPtr += sizeof(float);
@@ -591,7 +1411,7 @@ convertInPlace (char *& writePtr,
     
       default:
     
-        throw Iex::ArgExc ("Unknown pixel data type.");
+        throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
     }
 }
 
@@ -617,7 +1437,7 @@ copyFromFrameBuffer (char *& writePtr,
 
         switch (type)
         {
-          case UINT:
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
 
             while (readPtr <= endPtr)
             {
@@ -627,7 +1447,7 @@ copyFromFrameBuffer (char *& writePtr,
             }
             break;
 
-          case HALF:
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
 
             while (readPtr <= endPtr)
             {
@@ -636,7 +1456,7 @@ copyFromFrameBuffer (char *& writePtr,
             }
             break;
 
-          case FLOAT:
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
 
             while (readPtr <= endPtr)
             {
@@ -647,7 +1467,7 @@ copyFromFrameBuffer (char *& writePtr,
 
           default:
 
-            throw Iex::ArgExc ("Unknown pixel data type.");
+            throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
         }
     }
     else
@@ -658,7 +1478,7 @@ copyFromFrameBuffer (char *& writePtr,
 
         switch (type)
         {
-          case UINT:
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
 
             while (readPtr <= endPtr)
             {
@@ -669,7 +1489,7 @@ copyFromFrameBuffer (char *& writePtr,
             }
             break;
 
-          case HALF:
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
 
             while (readPtr <= endPtr)
             {
@@ -679,7 +1499,7 @@ copyFromFrameBuffer (char *& writePtr,
             }
             break;
 
-          case FLOAT:
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
 
             while (readPtr <= endPtr)
             {
@@ -692,7 +1512,186 @@ copyFromFrameBuffer (char *& writePtr,
             
           default:
 
-            throw Iex::ArgExc ("Unknown pixel data type.");
+            throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
+        }
+    }
+}
+
+void
+copyFromDeepFrameBuffer (char *& writePtr,
+                         const char * base,
+                         char* sampleCountBase,
+                         ptrdiff_t sampleCountXStride,
+                         ptrdiff_t sampleCountYStride,
+                         int y, int xMin, int xMax,
+                         int xOffsetForSampleCount,
+                         int yOffsetForSampleCount,
+                         int xOffsetForData,
+                         int yOffsetForData,
+                         ptrdiff_t sampleStride,
+                         ptrdiff_t dataXStride,
+                         ptrdiff_t dataYStride,
+                         Compressor::Format format,
+                         PixelType type)
+{
+    //
+    // Copy a horizontal row of pixels from a frame
+    // buffer to an output file's line or tile buffer.
+    //
+
+    if (format == Compressor::XDR)
+    {
+        //
+        // The the line or tile buffer is in XDR format.
+        //
+
+        switch (type)
+        {
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
+
+            for (int x = xMin; x <= xMax; x++)
+            {
+                unsigned int count =
+                        sampleCount(sampleCountBase,
+                                   sampleCountXStride,
+                                   sampleCountYStride,
+                                   x - xOffsetForSampleCount,
+                                   y - yOffsetForSampleCount);
+                const char* ptr = base + (y-yOffsetForData) * dataYStride + (x-xOffsetForData) * dataXStride;
+                const char* readPtr = ((const char**) ptr)[0];
+                for (unsigned int i = 0; i < count; i++)
+                {
+                    Xdr::write <CharPtrIO> (writePtr,
+                                            *(const unsigned int *) readPtr);
+                    readPtr += sampleStride;
+                }
+            }
+            break;
+
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
+
+            for (int x = xMin; x <= xMax; x++)
+            {
+                unsigned int count =
+                        sampleCount(sampleCountBase,
+                                   sampleCountXStride,
+                                   sampleCountYStride,
+                                   x - xOffsetForSampleCount,
+                                   y - yOffsetForSampleCount);
+                const char* ptr = base + (y-yOffsetForData) * dataYStride + (x-xOffsetForData) * dataXStride;
+                const char* readPtr = ((const char**) ptr)[0];
+                for (unsigned int i = 0; i < count; i++)
+                {
+                    Xdr::write <CharPtrIO> (writePtr, *(const half *) readPtr);
+                    readPtr += sampleStride;
+                }
+            }
+            break;
+
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
+
+            for (int x = xMin; x <= xMax; x++)
+            {
+                unsigned int count =
+                        sampleCount(sampleCountBase,
+                                   sampleCountXStride,
+                                   sampleCountYStride,
+                                   x - xOffsetForSampleCount,
+                                   y - yOffsetForSampleCount);
+                const char* ptr = base + (y-yOffsetForData) * dataYStride + (x-xOffsetForData) * dataXStride;                                   
+                                   
+                const char* readPtr = ((const char**) ptr)[0];
+                for (unsigned int i = 0; i < count; i++)
+                {
+                    Xdr::write <CharPtrIO> (writePtr, *(const float *) readPtr);
+                    readPtr += sampleStride;
+                }
+            }
+            break;
+
+          default:
+
+            throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
+        }
+    }
+    else
+    {
+        //
+        // The the line or tile buffer is in NATIVE format.
+        //
+
+        switch (type)
+        {
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
+
+            for (int x = xMin; x <= xMax; x++)
+            {
+                unsigned int count =
+                        sampleCount(sampleCountBase,
+                                   sampleCountXStride,
+                                   sampleCountYStride,
+                                   x - xOffsetForSampleCount,
+                                   y - yOffsetForSampleCount);
+                                   
+                const char* ptr = base + (y-yOffsetForData) * dataYStride + (x-xOffsetForData) * dataXStride;                                                                      
+                const char* readPtr = ((const char**) ptr)[0];
+                for (unsigned int i = 0; i < count; i++)
+                {
+                    for (size_t j = 0; j < sizeof (unsigned int); ++j)
+                        *writePtr++ = readPtr[j];
+
+                    readPtr += sampleStride;
+                }
+            }
+            break;
+
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
+
+            for (int x = xMin; x <= xMax; x++)
+            {
+                unsigned int count =
+                        sampleCount(sampleCountBase,
+                                   sampleCountXStride,
+                                   sampleCountYStride,
+                                   x - xOffsetForSampleCount,
+                                   y - yOffsetForSampleCount);
+                const char* ptr = base + (y-yOffsetForData) * dataYStride + (x-xOffsetForData) * dataXStride;                                   
+                const char* readPtr = ((const char**) ptr)[0];
+                for (unsigned int i = 0; i < count; i++)
+                {
+                    *(half *) writePtr = *(const half *) readPtr;
+                    writePtr += sizeof (half);
+                    readPtr += sampleStride;
+                }
+            }
+            break;
+
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
+
+            for (int x = xMin; x <= xMax; x++)
+            {
+                unsigned int count =
+                        sampleCount(sampleCountBase,
+                                   sampleCountXStride,
+                                   sampleCountYStride,
+                                   x - xOffsetForSampleCount,
+                                   y - yOffsetForSampleCount);
+                                   
+                const char* ptr = base + (y-yOffsetForData) * dataYStride + (x-xOffsetForData) * dataXStride;                                   
+                const char* readPtr = ((const char**) ptr)[0];
+                for (unsigned int i = 0; i < count; i++)
+                {
+                    for (size_t j = 0; j < sizeof (float); ++j)
+                        *writePtr++ = readPtr[j];
+
+                    readPtr += sampleStride;
+                }
+            }
+            break;
+
+          default:
+
+            throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
         }
     }
 }
@@ -712,30 +1711,30 @@ fillChannelWithZeroes (char *& writePtr,
 
         switch (type)
         {
-          case UINT:
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
 
-            for (int j = 0; j < xSize; ++j)
+            for (size_t j = 0; j < xSize; ++j)
                 Xdr::write <CharPtrIO> (writePtr, (unsigned int) 0);
 
             break;
 
-          case HALF:
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
 
-            for (int j = 0; j < xSize; ++j)
+            for (size_t j = 0; j < xSize; ++j)
                 Xdr::write <CharPtrIO> (writePtr, (half) 0);
 
             break;
 
-          case FLOAT:
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
 
-            for (int j = 0; j < xSize; ++j)
+            for (size_t j = 0; j < xSize; ++j)
                 Xdr::write <CharPtrIO> (writePtr, (float) 0);
 
             break;
             
           default:
 
-            throw Iex::ArgExc ("Unknown pixel data type.");
+            throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
         }
     }
     else
@@ -746,9 +1745,9 @@ fillChannelWithZeroes (char *& writePtr,
 
         switch (type)
         {
-          case UINT:
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
 
-            for (int j = 0; j < xSize; ++j)
+            for (size_t j = 0; j < xSize; ++j)
             {
                 static const unsigned int ui = 0;
 
@@ -757,18 +1756,18 @@ fillChannelWithZeroes (char *& writePtr,
             }
             break;
 
-          case HALF:
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
 
-            for (int j = 0; j < xSize; ++j)
+            for (size_t j = 0; j < xSize; ++j)
             {
                 *(half *) writePtr = half (0);
                 writePtr += sizeof (half);
             }
             break;
 
-          case FLOAT:
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
 
-            for (int j = 0; j < xSize; ++j)
+            for (size_t j = 0; j < xSize; ++j)
             {
                 static const float f = 0;
 
@@ -779,9 +1778,95 @@ fillChannelWithZeroes (char *& writePtr,
             
           default:
 
-            throw Iex::ArgExc ("Unknown pixel data type.");
+            throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
         }
     }
 }
 
-} // namespace Imf
+bool
+usesLongNames (const Header &header)
+{
+    //
+    // If an OpenEXR file contains any attribute names, attribute type names
+    // or channel names longer than 31 characters, then the file cannot be
+    // read by older versions of the IlmImf library (up to OpenEXR 1.6.1).
+    // Before writing the file header, we check if the header contains
+    // any names longer than 31 characters; if it does, then we set the
+    // LONG_NAMES_FLAG in the file version number.  Older versions of the
+    // IlmImf library will refuse to read files that have the LONG_NAMES_FLAG
+    // set.  Without the flag, older versions of the library would mis-
+    // interpret the file as broken.
+    //
+
+    for (Header::ConstIterator i = header.begin();
+         i != header.end();
+         ++i)
+    {
+        if (strlen (i.name()) >= 32 || strlen (i.attribute().typeName()) >= 32)
+            return true;
+    }
+
+    const ChannelList &channels = header.channels();
+
+    for (ChannelList::ConstIterator i = channels.begin();
+         i != channels.end();
+         ++i)
+    {
+        if (strlen (i.name()) >= 32)
+            return true;
+    }
+
+    return false;
+}
+
+int
+getScanlineChunkOffsetTableSize(const Header& header)
+{
+    const Box2i &dataWindow = header.dataWindow();
+
+    vector<size_t> bytesPerLine;
+    size_t maxBytesPerLine = bytesPerLineTable (header,
+                                                bytesPerLine);
+
+    Compressor* compressor = newCompressor(header.compression(),
+                                           maxBytesPerLine,
+                                           header);
+
+    int linesInBuffer = numLinesInBuffer (compressor);
+
+    int lineOffsetSize = (dataWindow.max.y - dataWindow.min.y +
+                          linesInBuffer) / linesInBuffer;
+
+    delete compressor;
+
+    return lineOffsetSize;
+}
+
+//
+// Located in ImfTiledMisc.cpp
+//
+int
+getTiledChunkOffsetTableSize(const Header& header);
+
+int
+getChunkOffsetTableSize(const Header& header,bool ignore_attribute)
+{
+    if(!ignore_attribute && header.hasChunkCount())
+    {
+        return header.chunkCount();
+    }
+    
+    if(header.hasType()  && !isSupportedType(header.type()))
+    {
+        throw IEX_NAMESPACE::ArgExc ("unsupported header type to "
+        "get chunk offset table size");
+    }
+    if (isTiled(header.type()) == false)
+        return getScanlineChunkOffsetTableSize(header);
+    else
+        return getTiledChunkOffsetTableSize(header);
+    
+}
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfMisc.h b/Source/OpenEXR/IlmImf/ImfMisc.h
index 85718f4..cc697e2 100644
--- a/Source/OpenEXR/IlmImf/ImfMisc.h
+++ b/Source/OpenEXR/IlmImf/ImfMisc.h
@@ -43,19 +43,26 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfPixelType.h>
+#include "ImfPixelType.h"
+#include "ImfCompressor.h"
+#include "ImfArray.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+#include "ImfForward.h"
+
+#include <cstddef>
 #include <vector>
-#include <ImfCompressor.h>
 
-namespace Imf {
 
-class Header;
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
 
 //
 // Return the size of a single value of the indicated type,
 // in the machine's native format.
 //
 
+IMF_EXPORT
 int	pixelTypeSize (PixelType type);
 
 
@@ -67,6 +74,7 @@ int	pixelTypeSize (PixelType type);
 // interval [2, 6].
 //
 
+IMF_EXPORT
 int	numSamples (int s, int a, int b);
 
 
@@ -77,19 +85,76 @@ int	numSamples (int s, int a, int b);
 // the pixel data are tightly packed).
 //
 
+IMF_EXPORT
 size_t	bytesPerLineTable (const Header &header,
 		           std::vector<size_t> &bytesPerLine);
 
+
+//
+// Get the sample count for pixel (x, y) using the array base
+// pointer, xStride and yStride.
+//
+
+IMF_EXPORT
+int&
+sampleCount(char* base, int xStride, int yStride, int x, int y);
+
+
+IMF_EXPORT
+const int&
+sampleCount(const char* base, int xStride, int yStride, int x, int y);
+
+//
+// Build a table that lists, for each scanline in a DEEP file's
+// data window, how many bytes are required to store all
+// pixels in all channels in scanlines ranged in [minY, maxY]
+// (assuming that the pixel data are tightly packed).
+//
+
+IMF_EXPORT
+size_t bytesPerDeepLineTable (const Header &header,
+                              int minY, int maxY,
+                              const char* base,
+                              int xStride,
+                              int yStride,
+                              std::vector<size_t> &bytesPerLine);
+
+
+//
+// Build a table that lists, for each scanline in a DEEP file's
+// data window, how many bytes are required to store all
+// pixels in all channels in every scanline (assuming that
+// the pixel data are tightly packed).
+//
+
+IMF_EXPORT
+size_t bytesPerDeepLineTable (const Header &header,
+                              char* base,
+                              int xStride,
+                              int yStride,
+                              std::vector<size_t> &bytesPerLine);
+
+
 //
 // For scanline-based files, pixels are read or written in
 // in multi-scanline blocks.  Internally, class OutputFile
 // and class ScanLineInputFile store a block of scan lines
 // in a "line buffer".  Function offsetInLineBufferTable()
-// builds a table that lists, for each scan line in a file's
-// data window, the location of the pixel data for the scanline
-// relative to the beginning of the line buffer.
+// builds a table that lists, scanlines within range
+// [scanline1, scanline2], the location of the pixel data
+// for the scanline relative to the beginning of the line buffer,
+// where scanline1 = 0 represents the first line in the DATA WINDOW.
+// The one without specifying the range will make scanline1 = 0
+// and scanline2 = bytesPerLine.size().
 //
 
+IMF_EXPORT
+void    offsetInLineBufferTable (const std::vector<size_t> &bytesPerLine,
+                                 int scanline1, int scanline2,
+                                 int linesInLineBuffer,
+                                 std::vector<size_t> &offsetInLineBuffer);
+
+IMF_EXPORT
 void	offsetInLineBufferTable (const std::vector<size_t> &bytesPerLine,
 				 int linesInLineBuffer,
 				 std::vector<size_t> &offsetInLineBuffer);
@@ -100,8 +165,8 @@ void	offsetInLineBufferTable (const std::vector<size_t> &bytesPerLine,
 // (minY is the minimum y coordinate of the file's data window.)
 //
 
-int	lineBufferMinY (int y, int minY, int linesInLineBuffer);
-int	lineBufferMaxY (int y, int minY, int linesInLineBuffer);
+IMF_EXPORT int	lineBufferMinY (int y, int minY, int linesInLineBuffer);
+IMF_EXPORT int	lineBufferMaxY (int y, int minY, int linesInLineBuffer);
 
 
 //
@@ -109,6 +174,7 @@ int	lineBufferMaxY (int y, int minY, int linesInLineBuffer);
 // If compressor is 0, return Compressor::XDR.
 //
 
+IMF_EXPORT
 Compressor::Format defaultFormat (Compressor *compressor);
 
 
@@ -117,6 +183,7 @@ Compressor::Format defaultFormat (Compressor *compressor);
 // or uncompress at once.  If compressor is 0, return 1.
 //
 
+IMF_EXPORT
 int     numLinesInBuffer (Compressor *compressor);
 
 
@@ -146,6 +213,7 @@ int     numLinesInBuffer (Compressor *compressor);
 //    typeInFile        the pixel data type in the input file's channel
 //
 
+IMF_EXPORT
 void    copyIntoFrameBuffer (const char *&readPtr,
 			     char *writePtr,
                              char *endPtr,
@@ -156,6 +224,68 @@ void    copyIntoFrameBuffer (const char *&readPtr,
                              PixelType typeInFrameBuffer,
                              PixelType typeInFile);
 
+
+//
+// Copy a single channel of a horizontal row of pixels from an
+// input file's internal line buffer or tile buffer into a
+// frame buffer slice.  If necessary, perform on-the-fly data
+// type conversion.
+//
+//    readPtr             initially points to the beginning of the
+//                        data in the line or tile buffer. readPtr
+//                        is advanced as the pixel data are copied;
+//                        when copyIntoFrameBuffer() returns,
+//                        readPtr points just past the end of the
+//                        copied data.
+//
+//    base                point to each pixel in the framebuffer
+//
+//    sampleCountBase,    provide the number of samples in each pixel
+//    sampleCountXStride,
+//    sampleCountYStride
+//
+//    y                   the scanline to copy. The coordinate is
+//                        relative to the datawindow.min.y.
+//
+//    minX, maxX          used to indicate which pixels in the scanline
+//                        will be copied.
+//
+//    xOffsetForSampleCount,    used to offset the sample count array
+//    yOffsetForSampleCount,    and the base array.
+//    xOffsetForData,
+//    yOffsetForData
+//
+//    xStride             the xStride for the frame buffer slice
+//
+//    format              indicates if the line or tile buffer is
+//                        in NATIVE or XDR format.
+//
+//    typeInFrameBuffer   the pixel data type of the frame buffer slice
+//
+//    typeInFile          the pixel data type in the input file's channel
+//
+
+IMF_EXPORT
+void    copyIntoDeepFrameBuffer (const char *& readPtr,
+                                 char * base,
+                                 const char* sampleCountBase,
+                                 ptrdiff_t sampleCountXStride,
+                                 ptrdiff_t sampleCountYStride,
+                                 int y, int minX, int maxX,
+                                 int xOffsetForSampleCount,
+                                 int yOffsetForSampleCount,
+                                 int xOffsetForData,
+                                 int yOffsetForData,
+                                 ptrdiff_t xStride,
+                                 ptrdiff_t xPointerStride,
+                                 ptrdiff_t yPointerStride,
+                                 bool fill,
+                                 double fillValue,
+                                 Compressor::Format format,
+                                 PixelType typeInFrameBuffer,
+                                 PixelType typeInFile);
+
+
 //
 // Given a pointer into a an input file's line buffer or tile buffer,
 // skip over the data for xSize pixels of type typeInFile.
@@ -164,6 +294,7 @@ void    copyIntoFrameBuffer (const char *&readPtr,
 // skipped data.
 //
 
+IMF_EXPORT
 void    skipChannel (const char *&readPtr,
 		     PixelType typeInFile,
 		     size_t xSize);
@@ -187,6 +318,7 @@ void    skipChannel (const char *&readPtr,
 //    numPixels		number of pixels in the input and output arrays
 // 
 
+IMF_EXPORT
 void    convertInPlace (char *&toPtr,
 			const char *&fromPtr,
 			PixelType type,
@@ -218,6 +350,7 @@ void    convertInPlace (char *&toPtr,
 //			data type conversion)
 //
 
+IMF_EXPORT
 void    copyFromFrameBuffer (char *&writePtr,
 			     const char *&readPtr,
                              const char *endPtr,
@@ -226,6 +359,69 @@ void    copyFromFrameBuffer (char *&writePtr,
 			     PixelType type);
 
 //
+// Copy a single channel of a horizontal row of pixels from a
+// a frame buffer in a deep data file into an output file's
+// internal line buffer or tile buffer.
+//
+//    writePtr                  initially points to the beginning of the
+//                              data in the line or tile buffer. writePtr
+//                              is advanced as the pixel data are copied;
+//                              when copyFromDeepFrameBuffer() returns,
+//                              writePtr points just past the end of the
+//                              copied data.
+//
+//    base                      the start pointer of each pixel in this channel.
+//                              It points to the real data in FrameBuffer.
+//                              It is different for different channels.
+//                              dataWindowMinX and dataWindowMinY are involved in
+//                              locating for base.
+//
+//    sampleCountBase,          used to locate the position to get
+//    sampleCountXStride,       the number of samples for each pixel.
+//    sampleCountYStride        Used to determine how far we should
+//                              read based on the pointer provided by base.
+//
+//    y                         the scanline to copy. If we are dealing
+//                              with a tiled deep file, then probably a portion
+//                              of the scanline is copied.
+//
+//    xMin, xMax                used to indicate which pixels in the scanline
+//                              will be copied.
+//
+//    xOffsetForSampleCount,    used to offset the sample count array
+//    yOffsetForSampleCount,    and the base array.
+//    xOffsetForData,
+//    yOffsetForData
+//
+//    xStride                   the xStride for the frame buffer slice
+//
+//    format                    indicates if the line or tile buffer is
+//                              in NATIVE or XDR format.
+//
+//    type                      the pixel data type in the frame buffer
+//                              and in the output file's channel (function
+//                              copyFromFrameBuffer() doesn't do on-the-fly
+//                              data type conversion)
+//
+
+IMF_EXPORT
+void    copyFromDeepFrameBuffer (char *& writePtr,
+                                 const char * base,
+                                 char* sampleCountBase,
+                                 ptrdiff_t sampleCountXStride,
+                                 ptrdiff_t sampleCountYStride,
+                                 int y, int xMin, int xMax,
+                                 int xOffsetForSampleCount,
+                                 int yOffsetForSampleCount,
+                                 int xOffsetForData,
+                                 int yOffsetForData,
+                                 ptrdiff_t sampleStride,
+                                 ptrdiff_t xStrideForData,
+                                 ptrdiff_t yStrideForData,
+                                 Compressor::Format format,
+                                 PixelType type);
+
+//
 // Fill part of an output file's line buffer or tile buffer with
 // zeroes.  This routine is called when an output file contains
 // a channel for which the frame buffer contains no corresponding
@@ -245,11 +441,26 @@ void    copyFromFrameBuffer (char *&writePtr,
 //    xSize             number of pixels to be filled with zeroes.
 //
 
+IMF_EXPORT
 void    fillChannelWithZeroes (char *&writePtr,
 			       Compressor::Format format,
 			       PixelType type,
 			       size_t xSize);
 
-} // namespace Imf
+IMF_EXPORT
+bool usesLongNames (const Header &header);
+
+
+//
+// compute size of chunk offset table - if ignore_attribute set to true
+// will compute from the image size and layout, rather than the attribute
+// The default behaviour is to read the attribute
+//
+
+IMF_EXPORT
+int getChunkOffsetTableSize(const Header& header,bool ignore_attribute=false);
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfMultiPartInputFile.cpp b/Source/OpenEXR/IlmImf/ImfMultiPartInputFile.cpp
new file mode 100644
index 0000000..81ccf6b
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfMultiPartInputFile.cpp
@@ -0,0 +1,783 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#include "ImfMultiPartInputFile.h"
+
+#include "ImfTimeCodeAttribute.h"
+#include "ImfChromaticitiesAttribute.h"
+#include "ImfBoxAttribute.h"
+#include "ImfFloatAttribute.h"
+#include "ImfStdIO.h"
+#include "ImfTileOffsets.h"
+#include "ImfMisc.h"
+#include "ImfTiledMisc.h"
+#include "ImfInputStreamMutex.h"
+#include "ImfInputPartData.h"
+#include "ImfPartType.h"
+#include "ImfInputFile.h"
+#include "ImfScanLineInputFile.h"
+#include "ImfTiledInputFile.h"
+#include "ImfDeepScanLineInputFile.h"
+#include "ImfDeepTiledInputFile.h"
+#include "ImfVersion.h"
+
+#include <OpenEXRConfig.h>
+#include <IlmThread.h>
+#include <IlmThreadMutex.h>
+
+#include <Iex.h>
+#include <map>
+#include <set>
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+using ILMTHREAD_NAMESPACE::Mutex;
+using ILMTHREAD_NAMESPACE::Lock;
+using IMATH_NAMESPACE::Box2i;
+
+using std::vector;
+using std::map;
+using std::set;
+using std::string;
+
+namespace
+{
+    // Controls whether we error out in the event of shared attribute
+    // inconsistency in the input file
+    static const bool strictSharedAttribute = true;
+}
+
+struct MultiPartInputFile::Data: public InputStreamMutex
+{
+    int                         version;        // Version of this file.
+    bool                        deleteStream;   // If we should delete the stream during destruction.
+    vector<InputPartData*>      parts;          // Data to initialize Output files.
+    int                         numThreads;     // Number of threads
+    bool                        reconstructChunkOffsetTable;    // If we should reconstruct
+                                                                // the offset table if it's broken.
+    std::map<int,GenericInputFile*> _inputFiles;
+    std::vector<Header>             _headers;
+
+    
+    void                    chunkOffsetReconstruction(OPENEXR_IMF_INTERNAL_NAMESPACE::IStream& is, const std::vector<InputPartData*>& parts);
+                                                      
+    void                    readChunkOffsetTables(bool reconstructChunkOffsetTable);
+                                                      
+    bool                    checkSharedAttributesValues(const Header & src,
+                                                        const Header & dst,
+                                                        std::vector<std::string> & conflictingAttributes) const;
+                                                                                                          
+   TileOffsets*            createTileOffsets(const Header& header);
+   
+   InputPartData*          getPart(int partNumber);
+   
+    Data (bool deleteStream, int numThreads, bool reconstructChunkOffsetTable):
+        InputStreamMutex(),
+        deleteStream (deleteStream),
+        numThreads (numThreads),
+        reconstructChunkOffsetTable(reconstructChunkOffsetTable)
+    {
+    }
+
+    ~Data()
+    {
+        if (deleteStream) delete is;
+
+        for (size_t i = 0; i < parts.size(); i++)
+            delete parts[i];
+    }
+    
+    template <class T>
+    T*    createInputPartT(int partNumber)
+    {
+
+    }
+};
+
+MultiPartInputFile::MultiPartInputFile(const char fileName[],
+                           int numThreads,
+                           bool reconstructChunkOffsetTable):
+    _data(new Data(true, numThreads, reconstructChunkOffsetTable))
+{
+    try
+    {
+        _data->is = new StdIFStream (fileName);
+        initialize();
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        delete _data;
+
+        REPLACE_EXC (e, "Cannot read image file "
+                        "\"" << fileName << "\". " << e);
+        throw;
+    }
+    catch (...)
+    {
+        delete _data;
+        throw;
+    }
+}
+
+MultiPartInputFile::MultiPartInputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream& is,
+                                        int numThreads,
+                                        bool reconstructChunkOffsetTable):
+    _data(new Data(false, numThreads, reconstructChunkOffsetTable))
+{
+    try
+    {
+        _data->is = &is;
+        initialize();
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        delete _data;
+
+        REPLACE_EXC (e, "Cannot read image file "
+                        "\"" << is.fileName() << "\". " << e);
+        throw;
+    }
+    catch (...)
+    {
+        delete _data;
+        throw;
+    }
+}
+
+template<class T>
+T*
+MultiPartInputFile::getInputPart(int partNumber)
+{
+    Lock lock(*_data);
+            if (_data->_inputFiles.find(partNumber) == _data->_inputFiles.end())
+        {
+            T* file = new T(_data->getPart(partNumber));
+            _data->_inputFiles.insert(std::make_pair(partNumber, (GenericInputFile*) file));
+            return file;
+        }
+        else return (T*) _data->_inputFiles[partNumber];
+}
+
+
+template InputFile* MultiPartInputFile::getInputPart<InputFile>(int);
+template TiledInputFile* MultiPartInputFile::getInputPart<TiledInputFile>(int);
+template DeepScanLineInputFile* MultiPartInputFile::getInputPart<DeepScanLineInputFile>(int);
+template DeepTiledInputFile* MultiPartInputFile::getInputPart<DeepTiledInputFile>(int);
+
+InputPartData*
+MultiPartInputFile::getPart(int partNumber)
+{
+    return _data->getPart(partNumber);
+}
+
+
+
+const Header &
+ MultiPartInputFile::header(int n) const
+{
+    return _data->_headers[n];
+}
+
+
+
+MultiPartInputFile::~MultiPartInputFile()
+{
+    for (map<int, GenericInputFile*>::iterator it = _data->_inputFiles.begin();
+         it != _data->_inputFiles.end(); it++)
+    {
+        delete it->second;
+    }
+
+    delete _data;
+}
+
+
+bool
+MultiPartInputFile::Data::checkSharedAttributesValues(const Header & src,
+                                                const Header & dst,
+                                                vector<string> & conflictingAttributes) const
+{
+    conflictingAttributes.clear();
+
+    bool conflict = false;
+
+    //
+    // Display Window
+    //
+    if (src.displayWindow() != dst.displayWindow())
+    {
+        conflict = true;
+        conflictingAttributes.push_back ("displayWindow");
+    }
+
+
+    //
+    // Pixel Aspect Ratio
+    //
+    if (src.pixelAspectRatio() != dst.pixelAspectRatio())
+    {
+        conflict = true;
+        conflictingAttributes.push_back ("pixelAspectRatio");
+    }
+
+
+    //
+    // Timecode
+    //
+    const TimeCodeAttribute * srcTimeCode = src.findTypedAttribute<
+          TimeCodeAttribute> (TimeCodeAttribute::staticTypeName());
+    const TimeCodeAttribute * dstTimeCode = dst.findTypedAttribute<
+          TimeCodeAttribute> (TimeCodeAttribute::staticTypeName());
+
+    if (dstTimeCode)
+    {
+        if  ( (srcTimeCode && (srcTimeCode->value() != dstTimeCode->value())) ||
+              (!srcTimeCode))
+        {
+            conflict = true;
+            conflictingAttributes.push_back (TimeCodeAttribute::staticTypeName());
+        }
+    }
+
+    //
+    // Chromaticities
+    //
+    const ChromaticitiesAttribute * srcChrom =  src.findTypedAttribute<
+          ChromaticitiesAttribute> (ChromaticitiesAttribute::staticTypeName());
+    const ChromaticitiesAttribute * dstChrom =  dst.findTypedAttribute<
+          ChromaticitiesAttribute> (ChromaticitiesAttribute::staticTypeName());
+
+    if (dstChrom)
+    {
+        if ( (srcChrom && (srcChrom->value() != dstChrom->value())) ||
+             (!srcChrom))
+        {
+            conflict = true;
+            conflictingAttributes.push_back (ChromaticitiesAttribute::staticTypeName());
+        }
+    }
+
+
+    return conflict;
+}
+
+
+void
+MultiPartInputFile::initialize()
+{
+    readMagicNumberAndVersionField(*_data->is, _data->version);
+    
+    bool multipart = isMultiPart(_data->version);
+    bool tiled = isTiled(_data->version);
+
+    //
+    // Multipart files don't have and shouldn't have the tiled bit set.
+    //
+
+    if (tiled && multipart)
+        throw IEX_NAMESPACE::InputExc ("Multipart files cannot have the tiled bit set");
+
+    
+    int pos = 0;
+    while (true)
+    {
+        Header header;
+        header.readFrom(*_data->is, _data->version);
+
+        //
+        // If we read nothing then we stop reading.
+        //
+
+        if (header.readsNothing())
+        {
+            pos++;
+            break;
+        }
+
+        _data->_headers.push_back(header);
+        
+        if(multipart == false)
+          break;
+    }
+
+    //
+    // Perform usual check on headers.
+    //
+
+    for (size_t i = 0; i < _data->_headers.size(); i++)
+    {
+        //
+        // Silently invent a type if the file is a single part regular image.
+        //
+
+        if( _data->_headers[i].hasType() == false )
+        {
+            if(multipart)
+
+                throw IEX_NAMESPACE::ArgExc ("Every header in a multipart file should have a type");
+          
+            _data->_headers[i].setType(tiled ? TILEDIMAGE : SCANLINEIMAGE);
+        }
+        else
+        {
+            
+            //
+            // Silently fix the header type if it's wrong
+            // (happens when a regular Image file written by EXR_2.0 is rewritten by an older library,
+            //  so doesn't effect deep image types)
+            //
+
+            if(!multipart && !isNonImage(_data->version))
+            {
+                _data->_headers[i].setType(tiled ? TILEDIMAGE : SCANLINEIMAGE);
+            }
+        }
+         
+
+        
+        if( _data->_headers[i].hasName() == false )
+        {
+            if(multipart)
+                throw IEX_NAMESPACE::ArgExc ("Every header in a multipart file should have a name");
+        }
+        
+        if (isTiled(_data->_headers[i].type()))
+            _data->_headers[i].sanityCheck(true, multipart);
+        else
+            _data->_headers[i].sanityCheck(false, multipart);
+    }
+
+    //
+    // Check name uniqueness.
+    //
+
+    if (multipart)
+    {
+        set<string> names;
+        for (size_t i = 0; i < _data->_headers.size(); i++)
+        {
+        
+            if (names.find(_data->_headers[i].name()) != names.end())
+            {
+                throw IEX_NAMESPACE::InputExc ("Header name " + _data->_headers[i].name() +
+                                   " is not a unique name.");
+            }
+            names.insert(_data->_headers[i].name());
+        }
+    }
+    
+    //
+    // Check shared attributes compliance.
+    //
+
+    if (multipart && strictSharedAttribute)
+    {
+        for (size_t i = 1; i < _data->_headers.size(); i++)
+        {
+            vector <string> attrs;
+            if (_data->checkSharedAttributesValues (_data->_headers[0], _data->_headers[i], attrs))
+            {
+                string attrNames;
+                for (size_t j=0; j<attrs.size(); j++)
+                    attrNames += " " + attrs[j];
+                throw IEX_NAMESPACE::InputExc ("Header name " + _data->_headers[i].name() +
+                                     " has non-conforming shared attributes: "+
+                                     attrNames);
+            }
+        }
+    }
+
+    //
+    // Create InputParts and read chunk offset tables.
+    //
+        
+    for (size_t i = 0; i < _data->_headers.size(); i++)
+        _data->parts.push_back(
+                new InputPartData(_data, _data->_headers[i], i, _data->numThreads, _data->version));
+
+    _data->readChunkOffsetTables(_data->reconstructChunkOffsetTable);
+}
+
+TileOffsets*
+MultiPartInputFile::Data::createTileOffsets(const Header& header)
+{
+    //
+    // Get the dataWindow information
+    //
+
+    const Box2i &dataWindow = header.dataWindow();
+    int minX = dataWindow.min.x;
+    int maxX = dataWindow.max.x;
+    int minY = dataWindow.min.y;
+    int maxY = dataWindow.max.y;
+
+    //
+    // Precompute level and tile information
+    //
+
+    int* numXTiles;
+    int* numYTiles;
+    int numXLevels, numYLevels;
+    TileDescription tileDesc = header.tileDescription();
+    precalculateTileInfo (tileDesc,
+                          minX, maxX,
+                          minY, maxY,
+                          numXTiles, numYTiles,
+                          numXLevels, numYLevels);
+
+    TileOffsets* tileOffsets = new TileOffsets (tileDesc.mode,
+                                                numXLevels,
+                                                numYLevels,
+                                                numXTiles,
+                                                numYTiles);
+    delete [] numXTiles;
+    delete [] numYTiles;
+
+    return tileOffsets;
+}
+
+
+void
+MultiPartInputFile::Data::chunkOffsetReconstruction(OPENEXR_IMF_INTERNAL_NAMESPACE::IStream& is, const vector<InputPartData*>& parts)
+{
+    //
+    // Reconstruct broken chunk offset tables. Stop once we received any exception.
+    //
+
+    Int64 position = is.tellg();
+
+    
+    //
+    // check we understand all the parts available: if not, we cannot continue
+    // exceptions thrown here should trickle back up to the constructor
+    //
+    
+    for (size_t i = 0; i < parts.size(); i++)
+    {
+        Header& header=parts[i]->header;
+        
+        //
+        // do we have a valid type entry?
+        // we only need them for true multipart files or single part non-image (deep) files
+        //
+        if(!header.hasType() && (isMultiPart(version) || isNonImage(version)))
+        {
+            throw IEX_NAMESPACE::ArgExc("cannot reconstruct incomplete file: part with missing type");
+        }
+        if(!isSupportedType(header.type()))
+        {
+            throw IEX_NAMESPACE::ArgExc("cannot reconstruct incomplete file: part with unknown type "+header.type());
+        }
+    }
+    
+    
+    // how many chunks should we read? We should stop when we reach the end
+    size_t total_chunks = 0;
+        
+    // for tiled-based parts, array of (pointers to) tileOffsets objects
+    // to create mapping between tile coordinates and chunk table indices
+    
+    
+    vector<TileOffsets*> tileOffsets(parts.size());
+    
+    // for scanline-based parts, number of scanlines in each part
+    vector<int> rowsizes(parts.size());
+        
+    for(size_t i = 0 ; i < parts.size() ; i++)
+    {
+        total_chunks += parts[i]->chunkOffsets.size();
+        if (isTiled(parts[i]->header.type()))
+        {
+            tileOffsets[i] = createTileOffsets(parts[i]->header);
+        }else{
+            tileOffsets[i] = NULL;
+            // (TODO) fix this so that it doesn't need to be revised for future compression types.
+            switch(parts[i]->header.compression())
+            {
+                case DWAB_COMPRESSION :
+                    rowsizes[i] = 256;
+                    break;
+                case PIZ_COMPRESSION :
+                case B44_COMPRESSION :
+                case B44A_COMPRESSION :
+                case DWAA_COMPRESSION :
+                    rowsizes[i]=32;
+                    break;
+                case ZIP_COMPRESSION :
+                case PXR24_COMPRESSION :
+                    rowsizes[i]=16;
+                    break;
+                case ZIPS_COMPRESSION :
+                case RLE_COMPRESSION :
+                case NO_COMPRESSION :
+                    rowsizes[i]=1;
+                    break;
+                default :
+                    throw(IEX_NAMESPACE::ArgExc("Unknown compression method in chunk offset reconstruction"));
+            }
+        }
+     }
+        
+     try
+     {
+            
+        //
+        // 
+        //
+        
+        Int64 chunk_start = position;
+        for (size_t i = 0; i < total_chunks ; i++)
+        {
+            //
+            // do we have a part number?
+            //
+            
+            int partNumber = 0;
+            if(isMultiPart(version))
+            {
+                OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, partNumber);
+            }
+            
+            
+            
+            if(partNumber<0 || partNumber>int(parts.size()))
+            {
+                // bail here - bad part number
+                throw int();
+            }
+            
+            Header& header = parts[partNumber]->header;
+
+            // size of chunk NOT including multipart field
+            
+            Int64 size_of_chunk=0;
+
+            if (isTiled(header.type()))
+            {
+                //
+                // 
+                //
+                int tilex,tiley,levelx,levely;
+                OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, tilex);
+                OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, tiley);
+                OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, levelx);
+                OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, levely);
+                
+                //std::cout << "chunk_start for " << tilex <<',' << tiley << ',' << levelx << ' ' << levely << ':' << chunk_start << std::endl;
+                    
+                
+                if(!tileOffsets[partNumber])
+                {
+                    // this shouldn't actually happen - we should have allocated a valid
+                    // tileOffsets for any part which isTiled
+                    throw int();
+                    
+                }
+                
+                if(!tileOffsets[partNumber]->isValidTile(tilex,tiley,levelx,levely))
+                {
+                    //std::cout << "invalid tile : aborting\n";
+                    throw int();
+                }
+                
+                (*tileOffsets[partNumber])(tilex,tiley,levelx,levely)=chunk_start;
+                
+                // compute chunk sizes - different procedure for deep tiles and regular
+                // ones
+                if(header.type()==DEEPTILE)
+                {
+                    Int64 packed_offset;
+                    Int64 packed_sample;
+                    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, packed_offset);
+                    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, packed_sample);
+                    
+                    //add 40 byte header to packed sizes (tile coordinates, packed sizes, unpacked size)
+                    size_of_chunk=packed_offset+packed_sample+40;
+                }
+                else
+                {
+                    
+                    // regular image has 20 bytes of header, 4 byte chunksize;
+                    int chunksize;
+                    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, chunksize);
+                    size_of_chunk=chunksize+20;
+                }
+            }
+            else
+            {
+                int y_coordinate;
+                OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, y_coordinate);
+                
+                y_coordinate -= header.dataWindow().min.y;
+                y_coordinate /= rowsizes[partNumber];   
+                
+                if(y_coordinate < 0 || y_coordinate >= int(parts[partNumber]->chunkOffsets.size()))
+                {
+                    //std::cout << "aborting reconstruction: bad data " << y_coordinate << endl;
+                    //bail to exception catcher: broken scanline
+                    throw int();
+                }
+                
+                parts[partNumber]->chunkOffsets[y_coordinate]=chunk_start;
+                //std::cout << "chunk_start for " << y_coordinate << ':' << chunk_start << std::endl;
+                
+                if(header.type()==DEEPSCANLINE)
+                {
+                    Int64 packed_offset;
+                    Int64 packed_sample;
+                    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, packed_offset);
+                    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, packed_sample);
+                    
+                    
+                    size_of_chunk=packed_offset+packed_sample+28;
+                }
+                else
+                {
+                    int chunksize;
+                    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, chunksize);   
+                    size_of_chunk=chunksize+8;
+                }
+                
+            }
+            
+            if(isMultiPart(version))
+            {
+                chunk_start+=4;
+            }
+            
+            chunk_start+=size_of_chunk;
+            
+            //std::cout << " next chunk +"<<size_of_chunk << " = " << chunk_start << std::endl;
+            
+            is.seekg(chunk_start);
+            
+        }
+        
+    }
+    catch (...)
+    {
+        //
+        // Suppress all exceptions.  This functions is
+        // called only to reconstruct the line offset
+        // table for incomplete files, and exceptions
+        // are likely.
+        //
+    }
+
+    // copy tiled part data back to chunk offsets
+    
+    for(size_t partNumber=0;partNumber<parts.size();partNumber++)
+    {
+        if(tileOffsets[partNumber])
+        {
+            size_t pos=0;
+            vector<vector<vector <Int64> > > offsets = tileOffsets[partNumber]->getOffsets();
+            for (size_t l = 0; l < offsets.size(); l++)
+                for (size_t y = 0; y < offsets[l].size(); y++)
+                    for (size_t x = 0; x < offsets[l][y].size(); x++)
+                    {
+                        parts[ partNumber ]->chunkOffsets[pos] = offsets[l][y][x];
+                        pos++;
+                    }
+           delete tileOffsets[partNumber];
+        }
+    }
+
+    is.clear();
+    is.seekg (position);
+}
+
+InputPartData*
+MultiPartInputFile::Data::getPart(int partNumber)
+{
+    if (partNumber < 0 || partNumber >= (int) parts.size())
+        throw IEX_NAMESPACE::ArgExc ("Part number is not in valid range.");
+    return parts[partNumber];
+}
+
+
+
+void
+MultiPartInputFile::Data::readChunkOffsetTables(bool reconstructChunkOffsetTable)
+{
+    bool brokenPartsExist = false;
+
+    for (size_t i = 0; i < parts.size(); i++)
+    {
+        int chunkOffsetTableSize = getChunkOffsetTableSize(parts[i]->header,false);
+        parts[i]->chunkOffsets.resize(chunkOffsetTableSize);
+
+        for (int j = 0; j < chunkOffsetTableSize; j++)
+            OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*is, parts[i]->chunkOffsets[j]);
+
+        //
+        // Check chunk offsets, reconstruct if broken.
+        // At first we assume the table is complete.
+        //
+        parts[i]->completed = true;
+        for (int j = 0; j < chunkOffsetTableSize; j++)
+        {
+            if (parts[i]->chunkOffsets[j] <= 0)
+            {
+                brokenPartsExist = true;
+                parts[i]->completed = false;
+                break;
+            }
+        }
+    }
+
+    if (brokenPartsExist && reconstructChunkOffsetTable)
+        chunkOffsetReconstruction(*is, parts);
+}
+
+int 
+MultiPartInputFile::version() const
+{
+    return _data->version;
+}
+
+bool 
+MultiPartInputFile::partComplete(int part) const
+{
+  return _data->parts[part]->completed;
+}
+
+int 
+MultiPartInputFile::parts() const
+{
+   return int(_data->_headers.size());
+}
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfMultiPartInputFile.h b/Source/OpenEXR/IlmImf/ImfMultiPartInputFile.h
new file mode 100644
index 0000000..51ef9d3
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfMultiPartInputFile.h
@@ -0,0 +1,128 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef IMFMULTIPARTINPUTFILE_H_
+#define IMFMULTIPARTINPUTFILE_H_
+
+#include "ImfGenericInputFile.h"
+#include "ImfNamespace.h"
+#include "ImfForward.h"
+#include "ImfThreading.h"
+#include "ImfExport.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+
+class IMF_EXPORT MultiPartInputFile : public GenericInputFile
+{
+  public:
+    MultiPartInputFile(const char fileName[],
+                       int numThreads = globalThreadCount(),
+                       bool reconstructChunkOffsetTable = true);
+
+    MultiPartInputFile(IStream& is,
+                       int numThreads = globalThreadCount(),
+                       bool reconstructChunkOffsetTable = true);
+
+    virtual ~MultiPartInputFile();
+
+    // ----------------------
+    // Count of number of parts in file
+    // ---------------------
+    int parts() const;
+    
+    
+    //----------------------
+    // Access to the headers
+    //----------------------
+
+    const Header &  header(int n) const;
+    
+
+    //----------------------------------
+    // Access to the file format version
+    //----------------------------------
+
+    int			    version () const;
+
+
+    // =----------------------------------------
+    // Check whether the entire chunk offset
+    // table for the part is written correctly
+    // -----------------------------------------
+    bool partComplete(int part) const;
+
+
+
+    struct Data;
+
+
+  private:
+    Data*                           _data;
+
+    MultiPartInputFile(const MultiPartInputFile &); // not implemented
+
+    
+    //
+    // used internally by 'Part' types to access individual parts of the multipart file
+    //
+    template<class T> T*    getInputPart(int partNumber);
+    InputPartData*          getPart(int);
+    
+    void                    initialize();
+
+
+    
+
+    friend class InputPart;
+    friend class ScanLineInputPart;
+    friend class TiledInputPart;
+    friend class DeepScanLineInputPart;
+    friend class DeepTiledInputPart;
+
+    //
+    // For backward compatibility.
+    //
+
+    friend class InputFile;
+    friend class TiledInputFile;
+    friend class ScanLineInputFile;
+    friend class DeepScanLineInputFile;
+    friend class DeepTiledInputFile;
+};
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif /* IMFMULTIPARTINPUTFILE_H_ */
diff --git a/Source/OpenEXR/IlmImf/ImfMultiPartOutputFile.cpp b/Source/OpenEXR/IlmImf/ImfMultiPartOutputFile.cpp
new file mode 100644
index 0000000..32b2ae1
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfMultiPartOutputFile.cpp
@@ -0,0 +1,519 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#include "ImfMultiPartOutputFile.h"
+#include "ImfBoxAttribute.h"
+#include "ImfFloatAttribute.h"
+#include "ImfTimeCodeAttribute.h"
+#include "ImfChromaticitiesAttribute.h"
+#include "ImfOutputPartData.h"
+#include "ImfPartType.h"
+#include "ImfOutputFile.h"
+#include "ImfTiledOutputFile.h"
+#include "ImfThreading.h"
+#include "IlmThreadMutex.h"
+#include "ImfMisc.h"
+#include "ImfStdIO.h"
+#include "ImfDeepScanLineOutputFile.h"
+#include "ImfDeepTiledOutputFile.h"
+#include "ImfOutputStreamMutex.h"
+
+#include "ImfNamespace.h"
+#include <Iex.h>
+
+
+#include <set>
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+using IMATH_NAMESPACE::Box2i;
+using ILMTHREAD_NAMESPACE::Lock;
+    
+
+using std::vector;
+using std::map;
+using std::set;
+
+
+struct MultiPartOutputFile::Data: public OutputStreamMutex
+{
+        vector<OutputPartData*>         parts;        // Contains data to initialize Output files.
+        bool                            deleteStream; // If we should delete the stream when destruction.
+        int                             numThreads;   // The number of threads.
+        std::map<int, GenericOutputFile*>    _outputFiles;
+        std::vector<Header>                  _headers;
+        
+        
+        void                    headerNameUniquenessCheck (const std::vector<Header> &headers);
+        
+        void                    writeHeadersToFile (const std::vector<Header> &headers); 
+        
+        void                    writeChunkTableOffsets (std::vector<OutputPartData*> &parts);
+        
+        
+        //-------------------------------------
+        // ensure that _headers is valid: called by constructors
+        //-------------------------------------
+        void                    do_header_sanity_checks(bool overrideSharedAttributes);
+        
+        // ------------------------------------------------
+        // Given a source header, we copy over all the 'shared attributes' to
+        // the destination header and remove any conflicting ones.
+        // ------------------------------------------------
+        void                    overrideSharedAttributesValues (const Header & src,
+                                                                Header & dst);
+                                                                
+        // ------------------------------------------------
+        // Given a source header, we check the destination header for any
+        // attributes that are part of the shared attribute set. For attributes
+        // present in both we check the values. For attribute present in 
+        // destination but absent in source we return false.
+        // For attributes present in src but missing from dst we return false
+        // and add the attribute to dst.
+        // We return false for all other cases.
+        // If we return true then we also populate the conflictingAttributes
+        // vector with the names of the attributes that failed the above.
+        // ------------------------------------------------
+        bool                    checkSharedAttributesValues (const Header & src,
+                                                             const Header & dst, 
+                                                             std::vector<std::string> & conflictingAttributes) const;
+        Data (bool deleteStream, int numThreads):
+            OutputStreamMutex(),
+            deleteStream (deleteStream),
+            numThreads (numThreads)
+        {
+        }
+        
+
+        ~Data()
+        {
+            if (deleteStream) delete os;
+
+            for (size_t i = 0; i < parts.size(); i++)
+                delete parts[i];
+        }
+};
+
+void
+MultiPartOutputFile::Data::do_header_sanity_checks(bool overrideSharedAttributes)
+{
+    size_t parts = _headers.size();
+    if (parts == 0) 
+        throw IEX_NAMESPACE::ArgExc ("Empty header list.");
+    
+    bool isMultiPart = (parts > 1); 
+    
+    //
+    // Do part 0 checks first.
+    //
+    
+    _headers[0].sanityCheck (_headers[0].hasTileDescription(), isMultiPart);
+        
+    
+    if (isMultiPart)
+    {
+        // multipart files must contain a chunkCount attribute
+        _headers[0].setChunkCount(getChunkOffsetTableSize(_headers[0],true));
+        
+        for (size_t i = 1; i < parts; i++)
+        {
+            if (_headers[i].hasType() == false)
+                throw IEX_NAMESPACE::ArgExc ("Every header in a multipart file should have a type");
+            
+            
+            _headers[i].setChunkCount(getChunkOffsetTableSize(_headers[i],true));
+            _headers[i].sanityCheck (_headers[i].hasTileDescription(), isMultiPart);
+            
+            
+            if (overrideSharedAttributes)
+                overrideSharedAttributesValues(_headers[0],_headers[i]);
+            else
+            {
+                std::vector<std::string> conflictingAttributes;
+                bool valid =checkSharedAttributesValues (_headers[0],
+                                                         _headers[i], 
+                                                         conflictingAttributes);
+                if (valid)
+                {
+                    string excMsg("Conflicting attributes found for header :: ");
+                    excMsg += _headers[i].name();
+                    for (size_t i=0; i<conflictingAttributes.size(); i++)
+                        excMsg += " '" + conflictingAttributes[i] + "' ";
+                                                             
+                    THROW (IEX_NAMESPACE::ArgExc, excMsg);
+                }
+            }
+        }
+        
+        headerNameUniquenessCheck(_headers);
+        
+    }else{
+        
+        // add chunk count offset to single part data (if not an image)
+        
+        if (_headers[0].hasType() && isImage(_headers[0].type()) == false)
+        {
+            _headers[0].setChunkCount(getChunkOffsetTableSize(_headers[0],true));
+        }
+        
+    }
+}
+
+    
+MultiPartOutputFile::MultiPartOutputFile (const char fileName[],
+                                          const Header * headers,
+                                          int parts,
+                                          bool overrideSharedAttributes,
+                                          int numThreads)
+:
+    _data (new Data (true, numThreads))
+{
+    // grab headers
+    _data->_headers.resize(parts);
+    
+    for(int i=0;i<parts;i++)
+    {
+       _data->_headers[i]=headers[i];
+    }
+    try
+    {
+  
+         _data->do_header_sanity_checks(overrideSharedAttributes);
+
+        //
+        // Build parts and write headers and offset tables to file.
+        //
+
+        _data->os = new StdOFStream (fileName);
+        for (size_t i = 0; i < _data->_headers.size(); i++)
+            _data->parts.push_back( new OutputPartData(_data, _data->_headers[i], i, numThreads, parts>1 ) );
+
+        writeMagicNumberAndVersionField(*_data->os, &_data->_headers[0],_data->_headers.size());
+        _data->writeHeadersToFile(_data->_headers);
+        _data->writeChunkTableOffsets(_data->parts);
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        delete _data;
+
+        REPLACE_EXC (e, "Cannot open image file "
+                        "\"" << fileName << "\". " << e);
+        throw;
+    }
+    catch (...)
+    {
+        delete _data;
+        throw;
+    }
+}
+
+MultiPartOutputFile::MultiPartOutputFile(OStream& os, 
+                                         const Header* headers, 
+                                         int parts, 
+                                         bool overrideSharedAttributes, 
+                                         int numThreads): 
+                                         _data(new Data(false,numThreads))
+{
+    // grab headers
+    _data->_headers.resize(parts);
+    _data->os=&os;
+    
+    for(int i=0;i<parts;i++)
+    {
+        _data->_headers[i]=headers[i];
+    }
+    try
+    {
+        
+        _data->do_header_sanity_checks(overrideSharedAttributes);
+        
+        //
+        // Build parts and write headers and offset tables to file.
+        //
+        
+        for (size_t i = 0; i < _data->_headers.size(); i++)
+            _data->parts.push_back( new OutputPartData(_data, _data->_headers[i], i, numThreads, parts>1 ) );
+        
+        writeMagicNumberAndVersionField(*_data->os, &_data->_headers[0],_data->_headers.size());
+        _data->writeHeadersToFile(_data->_headers);
+        _data->writeChunkTableOffsets(_data->parts);
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        delete _data;
+        
+        REPLACE_EXC (e, "Cannot open image stream "
+        "\"" << os.fileName() << "\". " << e);
+        throw;
+    }
+    catch (...)
+    {
+        delete _data;
+        throw;
+    }
+}
+
+
+const Header &
+MultiPartOutputFile::header(int n) const
+{
+    if(n<0 || n>int(_data->_headers.size()))
+    {
+        throw IEX_NAMESPACE::ArgExc("MultiPartOutputFile::header called with invalid part number");
+    }
+    return _data->_headers[n];
+}
+
+int
+MultiPartOutputFile::parts() const
+{
+   return _data->_headers.size();
+}
+
+
+MultiPartOutputFile::~MultiPartOutputFile ()
+{
+    for (map<int, GenericOutputFile*>::iterator it = _data->_outputFiles.begin();
+         it != _data->_outputFiles.end(); it++)
+    {
+        delete it->second;
+    }
+
+    delete _data;
+}
+
+template <class T>
+T*
+MultiPartOutputFile::getOutputPart(int partNumber)
+{
+    Lock lock(*_data);
+    if (_data->_outputFiles.find(partNumber) == _data->_outputFiles.end())
+    {
+        T* file = new T(_data->parts[partNumber]);
+        _data->_outputFiles.insert(std::make_pair(partNumber, (GenericOutputFile*) file));
+        return file;
+    }
+    else return (T*) _data->_outputFiles[partNumber];
+}
+
+// instance above function for all four types
+template OutputFile* MultiPartOutputFile::getOutputPart<OutputFile>(int);
+template TiledOutputFile * MultiPartOutputFile::getOutputPart<TiledOutputFile>(int);
+template DeepScanLineOutputFile * MultiPartOutputFile::getOutputPart<DeepScanLineOutputFile> (int);
+template DeepTiledOutputFile * MultiPartOutputFile::getOutputPart<DeepTiledOutputFile> (int);
+
+
+
+void 
+MultiPartOutputFile::Data::overrideSharedAttributesValues(const Header & src, Header & dst)
+{
+    //
+    // Display Window
+    //
+    const Box2iAttribute * displayWindow = 
+    src.findTypedAttribute<Box2iAttribute> ("displayWindow");
+    
+    if (displayWindow)
+        dst.insert ("displayWindow", *displayWindow);
+    else 
+        dst.erase ("displayWindow");
+    
+    
+    //
+    // Pixel Aspect Ratio
+    //
+    const FloatAttribute * pixelAspectRatio = 
+    src.findTypedAttribute<FloatAttribute> ("pixelAspectRatio");
+    
+    if (pixelAspectRatio)
+        dst.insert ("pixelAspectRatio", *pixelAspectRatio);
+    else 
+        dst.erase ("pixelAspectRatio");
+    
+    
+    //
+    // Timecode
+    //
+    const TimeCodeAttribute * timeCode = 
+    src.findTypedAttribute<TimeCodeAttribute> ("timecode");
+    
+    if (timeCode)
+        dst.insert ("timecode", *timeCode);
+    else 
+        dst.erase ("timecode");
+    
+    
+    //
+    // Chromaticities
+    //
+    const ChromaticitiesAttribute * chromaticities = 
+    src.findTypedAttribute<ChromaticitiesAttribute> ("chromaticities");
+    
+    if (chromaticities)
+        dst.insert ("chromaticities", *chromaticities);
+    else 
+        dst.erase ("chromaticities");
+    
+}
+
+
+bool 
+MultiPartOutputFile::Data::checkSharedAttributesValues(const Header & src,
+        const Header & dst,
+        vector<string> & conflictingAttributes) const
+{
+    bool conflict = false;
+
+    //
+    // Display Window
+    //
+    if (src.displayWindow() != dst.displayWindow())
+    {
+        conflict = true;
+        conflictingAttributes.push_back ("displayWindow");
+    }
+
+
+    //
+    // Pixel Aspect Ratio
+    //
+    if (src.pixelAspectRatio() != dst.pixelAspectRatio())
+    {
+        conflict = true;
+        conflictingAttributes.push_back ("pixelAspectRatio");
+    }
+
+
+    //
+    // Timecode
+    //
+    const TimeCodeAttribute * srcTimeCode = src.findTypedAttribute<
+                                            TimeCodeAttribute> (TimeCodeAttribute::staticTypeName());
+    const TimeCodeAttribute * dstTimeCode = dst.findTypedAttribute<
+                                            TimeCodeAttribute> (TimeCodeAttribute::staticTypeName());
+
+    if (dstTimeCode)
+    {
+        if ((srcTimeCode && (srcTimeCode->value() != dstTimeCode->value())) ||
+                (!srcTimeCode))
+        {
+            conflict = true;
+            conflictingAttributes.push_back (TimeCodeAttribute::staticTypeName());
+        }
+    }
+
+    //
+    // Chromaticities
+    //
+    const ChromaticitiesAttribute * srcChrom =  src.findTypedAttribute<
+            ChromaticitiesAttribute> (ChromaticitiesAttribute::staticTypeName());
+    const ChromaticitiesAttribute * dstChrom =  dst.findTypedAttribute<
+            ChromaticitiesAttribute> (ChromaticitiesAttribute::staticTypeName());
+
+    if (dstChrom)
+    {
+        if ( (srcChrom && (srcChrom->value() != dstChrom->value())) ||
+                (!srcChrom))
+        {
+            conflict = true;
+            conflictingAttributes.push_back (ChromaticitiesAttribute::staticTypeName());
+        }
+    }
+
+    return conflict;
+}
+                                                      
+
+void
+MultiPartOutputFile::Data::headerNameUniquenessCheck (const vector<Header> &headers)
+{
+    set<string> names;
+    for (size_t i = 0; i < headers.size(); i++)
+    {
+        if (names.find(headers[i].name()) != names.end())
+            throw IEX_NAMESPACE::ArgExc ("Each part should have a unique name.");
+        names.insert(headers[i].name());
+    }
+}
+
+void
+MultiPartOutputFile::Data::writeHeadersToFile (const vector<Header> &headers)
+{
+    for (size_t i = 0; i < headers.size(); i++)
+    {
+
+        // (TODO) consider deep files' preview images here.
+        if (headers[i].type() == TILEDIMAGE)
+            parts[i]->previewPosition = headers[i].writeTo(*os, true);
+        else
+            parts[i]->previewPosition = headers[i].writeTo(*os, false);
+    }
+
+    //
+    // If a multipart file, write zero-length attribute name to mark the end of all headers.
+    //
+
+    if (headers.size() !=1)
+         OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*os, "");
+}
+
+void
+MultiPartOutputFile::Data::writeChunkTableOffsets (vector<OutputPartData*> &parts)
+{
+    for (size_t i = 0; i < parts.size(); i++)
+    {
+        int chunkTableSize = getChunkOffsetTableSize(parts[i]->header,false);
+
+        Int64 pos = os->tellp();
+
+        if (pos == -1)
+            IEX_NAMESPACE::throwErrnoExc ("Cannot determine current file position (%T).");
+
+        parts[i]->chunkOffsetTablePosition = os->tellp();
+
+        //
+        // Fill in empty data for now. We'll write actual offsets during destruction.
+        //
+
+        for (int j = 0; j < chunkTableSize; j++)
+        {
+            Int64 empty = 0;
+            OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*os, empty);
+        }
+    }
+}
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfMultiPartOutputFile.h b/Source/OpenEXR/IlmImf/ImfMultiPartOutputFile.h
new file mode 100644
index 0000000..d5d6bfc
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfMultiPartOutputFile.h
@@ -0,0 +1,118 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// Portions (c) 2012 Weta Digital Ltd
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef MULTIPARTOUTPUTFILE_H_
+#define MULTIPARTOUTPUTFILE_H_
+
+#include "ImfHeader.h"
+#include "ImfGenericOutputFile.h"
+#include "ImfForward.h"
+#include "ImfThreading.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+
+//
+// Class responsible for handling the writing of multipart images.
+//
+// Note: Certain attributes are 'common' to all parts. Notably:
+// * Display Window
+// * Pixel Aspect Ratio
+// * Time Code
+// * Chromaticities
+// The first header forms the basis for the set of attributes that are shared 
+// across the constituent parts.
+//
+// Parameters
+//  headers - pointer to array of headers; one for each part of the image file
+//  parts - count of number of parts
+//  overrideSharedAttributes - toggle for the handling of shared attributes.
+//                             set false to check for inconsistencies, true
+//                             to copy the values over from the first header.
+//  numThreads - number of threads that should be used in encoding the data.
+//
+    
+class IMF_EXPORT MultiPartOutputFile : public GenericOutputFile
+{
+    public:
+        MultiPartOutputFile(const char fileName[],
+                            const Header * headers,
+                            int parts,
+                            bool overrideSharedAttributes = false,
+                            int numThreads = globalThreadCount());
+                            
+        MultiPartOutputFile(OStream & os,
+                            const Header * headers,
+                            int parts,
+                            bool overrideSharedAttributes = false,
+                            int numThreads = globalThreadCount());                            
+
+        //
+        // return number of parts in file
+        //
+        int parts() const ;
+        
+        
+        //
+        // return header for part n
+        // (note: may have additional attributes compared to that passed to constructor)
+        //
+        const Header & header(int n) const;
+                            
+        ~MultiPartOutputFile();
+
+        struct Data;
+
+    private:
+        Data*                           _data;
+
+        MultiPartOutputFile(const MultiPartOutputFile &); // not implemented
+        
+        template<class T>         T*  getOutputPart(int partNumber);
+
+    
+    friend class OutputPart;
+    friend class TiledOutputPart;
+    friend class DeepScanLineOutputPart;
+    friend class DeepTiledOutputPart;
+};
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif /* MULTIPARTOUTPUTFILE_H_ */
diff --git a/Source/OpenEXR/IlmImf/ImfMultiView.cpp b/Source/OpenEXR/IlmImf/ImfMultiView.cpp
index 8750c67..acca3fe 100644
--- a/Source/OpenEXR/IlmImf/ImfMultiView.cpp
+++ b/Source/OpenEXR/IlmImf/ImfMultiView.cpp
@@ -41,8 +41,10 @@
 #include <ImfMultiView.h>
 
 using namespace std;
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
-namespace Imf {
 namespace {
 
 StringVector
@@ -101,7 +103,7 @@ viewNum (const string &view, const StringVector &multiView)
     // otherwise, it's some other (valid) view
     //
 
-    for (int i = 0; i < multiView.size(); ++i)
+    for (size_t i = 0; i < multiView.size(); ++i)
     {
 	if (multiView[i] == view)
 	    return i;
@@ -228,11 +230,11 @@ areCounterparts (const string &channel1,
     //
 
     StringVector chan1 = parseString (channel1);
-    unsigned int size1 = chan1.size();	// number of SECTIONS in string
+    size_t size1 = chan1.size();	// number of SECTIONS in string
     					// name (not string length)
 
     StringVector chan2 = parseString (channel2);
-    unsigned int size2 = chan2.size();
+    size_t size2 = chan2.size();
 
     if (size1 == 0 || size2 == 0)
 	return false;
@@ -288,7 +290,7 @@ areCounterparts (const string &channel1,
     if (size1 != size2)
 	return false;
 
-    for(int i = 0; i < size1; ++i)
+    for(size_t i = 0; i < size1; ++i)
     {
 	if (i != size1 - 2 && chan1[i] != chan2[i])
 	    return false;
@@ -381,7 +383,7 @@ insertViewName (const string &channel,
 
     string newName;
 
-    for (int j = 0; j < s.size(); ++j)
+    for (size_t j = 0; j < s.size(); ++j)
     {
 	if (j < s.size() - 1)
 	    newName += s[j] + ".";
@@ -393,4 +395,41 @@ insertViewName (const string &channel,
 }
 
 
-} // namespace Imf
+string
+removeViewName(const string & channel,const string & view)
+{
+    StringVector s = parseString (channel, '.');
+
+    if (s.size() == 0)
+	return ""; // nothing in, nothing out
+
+    if (s.size() == 1)
+    {
+	//
+	// Channel in the default view, since no periods in its name.
+	// No viewname to remove
+	//
+
+	return channel;
+    }
+
+    string newName;
+    for( size_t j = 0 ; j < s.size() ; ++j)
+    {
+	    // only add the penultimate string part
+	    // if it doesn't match the view name
+	    if(j+2!=s.size() || s[j]!=view)
+	    {
+                  newName += s[j];
+	          if(j+1!=s.size())
+	          {
+                      newName  += ".";
+	          }
+	    }
+    }
+
+    return newName;
+
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfMultiView.h b/Source/OpenEXR/IlmImf/ImfMultiView.h
index 6d03d5e..127f97d 100644
--- a/Source/OpenEXR/IlmImf/ImfMultiView.h
+++ b/Source/OpenEXR/IlmImf/ImfMultiView.h
@@ -35,8 +35,10 @@
 #ifndef INCLUDED_IMF_MULTIVIEW_H
 #define INCLUDED_IMF_MULTIVIEW_H
 
-#include <ImfChannelList.h>
-#include <ImfStringVectorAttribute.h>
+#include "ImfChannelList.h"
+#include "ImfStringVectorAttribute.h"
+#include "ImfExport.h"
+#include "ImfNamespace.h"
 
 //-----------------------------------------------------------------------------
 //
@@ -80,7 +82,7 @@
 //
 //-----------------------------------------------------------------------------
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 //
 // Return the name of the default view given a multi-view string vector,
@@ -88,6 +90,7 @@ namespace Imf {
 // vector is empty, return "".
 //
 
+IMF_EXPORT
 std::string defaultViewName (const StringVector &multiView);
 
 
@@ -97,6 +100,7 @@ std::string defaultViewName (const StringVector &multiView);
 // is not a member of any named view.
 //
 
+IMF_EXPORT
 std::string viewFromChannelName (const std::string &channel,
                                  const StringVector &multiView);
 
@@ -107,6 +111,7 @@ std::string viewFromChannelName (const std::string &channel,
 // belongs to no view or if both channels belong to the same view.)
 //
 
+IMF_EXPORT
 bool areCounterparts (const std::string &channel1,
                       const std::string &channel2,
                       const StringVector &multiView);
@@ -115,6 +120,7 @@ bool areCounterparts (const std::string &channel1,
 // Return a list of all channels belonging to view viewName.
 //
 
+IMF_EXPORT
 ChannelList channelsInView (const std::string &viewName,
                             const ChannelList &channelList,
                             const StringVector &multiView);
@@ -123,6 +129,7 @@ ChannelList channelsInView (const std::string &viewName,
 // Return a list of channels not associated with any view.
 //
 
+IMF_EXPORT
 ChannelList channelsInNoView (const ChannelList &channelList,
                               const StringVector &multiView);
 
@@ -132,6 +139,7 @@ ChannelList channelsInNoView (const ChannelList &channelList,
 // X.right.Y, X.centre.Y, etc.).
 //
 
+IMF_EXPORT
 ChannelList channelInAllViews (const std::string &channame,
                                const ChannelList &channelList,
                                const StringVector &multiView);
@@ -143,6 +151,7 @@ ChannelList channelInAllViews (const std::string &channame,
 // exist.
 //
 
+IMF_EXPORT
 std::string channelInOtherView (const std::string &channel,
                                 const ChannelList &channelList,
                                 const StringVector &multiView,
@@ -155,10 +164,24 @@ std::string channelInOtherView (const std::string &channel,
 // not insert the view name.
 //
 
+IMF_EXPORT
 std::string insertViewName (const std::string &channel,
 			    const StringVector &multiView,
 			    int i);
 
-} // namespace Imf
+//
+// Given a channel name that does may include a view name, return
+// string without the view name. If the string does not contain
+// the view name, return the string unaltered.
+// (Will only remove the viewname if it is in the correct position 
+//  in the string)
+//
+
+IMF_EXPORT
+std::string removeViewName (const std::string &channel,
+		            const std::string &view);
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfName.h b/Source/OpenEXR/IlmImf/ImfName.h
index ebb9f86..4d4f25a 100644
--- a/Source/OpenEXR/IlmImf/ImfName.h
+++ b/Source/OpenEXR/IlmImf/ImfName.h
@@ -45,8 +45,9 @@
 //-----------------------------------------------------------------------------
 
 #include <string.h>
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 class Name
@@ -141,6 +142,9 @@ operator < (const Name &x, const Name &y)
 }
 
 
-} // namespace IMF
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfNamespace.h b/Source/OpenEXR/IlmImf/ImfNamespace.h
new file mode 100644
index 0000000..c36a31e
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfNamespace.h
@@ -0,0 +1,115 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2012, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef INCLUDED_IMFNAMESPACE_H
+#define INCLUDED_IMFNAMESPACE_H
+
+//
+// The purpose of this file is to have all of the Imath symbols defined within 
+// the OPENEXR_IMF_INTERNAL_NAMESPACE namespace rather than the standard Imath
+// namespace. Those symbols are made available to client code through the 
+// OPENEXR_IMF_NAMESPACE in addition to the OPENEXR_IMF_INTERNAL_NAMESPACE.
+//
+// To ensure source code compatibility, the OPENEXR_IMF_NAMESPACE defaults to
+// Imath and then "using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;" brings all
+// of the declarations from the OPENEXR_IMF_INTERNAL_NAMESPACE into the
+// OPENEXR_IMF_NAMESPACE.
+// This means that client code can continue to use syntax like
+// Imf::Header, but at link time it will resolve to a
+// mangled symbol based on the OPENEXR_IMF_INTERNAL_NAMESPACE.
+//
+// As an example, if one needed to build against a newer version of Imath and
+// have it run alongside an older version in the same application, it is now
+// possible to use an internal namespace to prevent collisions between the
+// older versions of Imath symbols and the newer ones.  To do this, the
+// following could be defined at build time:
+//
+// OPENEXR_IMF_INTERNAL_NAMESPACE = Imf_v2
+//
+// This means that declarations inside Imath headers look like this (after
+// the preprocessor has done its work):
+//
+// namespace Imf_v2 {
+//     ...
+//     class declarations
+//     ...
+// }
+//
+// namespace Imf {
+//     using namespace IMF_NAMESPACE_v2;
+// }
+//
+
+//
+// Open Source version of this file pulls in the OpenEXRConfig.h file
+// for the configure time options.
+//
+#include "OpenEXRConfig.h"
+
+
+#ifndef OPENEXR_IMF_NAMESPACE
+#define OPENEXR_IMF_NAMESPACE Imf
+#endif
+
+#ifndef OPENEXR_IMF_INTERNAL_NAMESPACE
+#define OPENEXR_IMF_INTERNAL_NAMESPACE OPENEXR_IMF_NAMESPACE
+#endif
+
+//
+// We need to be sure that we import the internal namespace into the public one.
+// To do this, we use the small bit of code below which initially defines
+// OPENEXR_IMF_INTERNAL_NAMESPACE (so it can be referenced) and then defines
+// OPENEXR_IMF_NAMESPACE and pulls the internal symbols into the public
+// namespace.
+//
+
+namespace OPENEXR_IMF_INTERNAL_NAMESPACE {}
+namespace OPENEXR_IMF_NAMESPACE {
+     using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;
+}
+
+//
+// There are identical pairs of HEADER/SOURCE ENTER/EXIT macros so that
+// future extension to the namespace mechanism is possible without changing
+// project source code.
+//
+
+#define OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER namespace OPENEXR_IMF_INTERNAL_NAMESPACE {
+#define OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT }
+
+#define OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER namespace OPENEXR_IMF_INTERNAL_NAMESPACE {
+#define OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT }
+
+
+#endif /* INCLUDED_IMFNAMESPACE_H */
diff --git a/Source/OpenEXR/IlmImf/ImfOpaqueAttribute.cpp b/Source/OpenEXR/IlmImf/ImfOpaqueAttribute.cpp
index 0abaa86..4a473ef 100644
--- a/Source/OpenEXR/IlmImf/ImfOpaqueAttribute.cpp
+++ b/Source/OpenEXR/IlmImf/ImfOpaqueAttribute.cpp
@@ -43,8 +43,9 @@
 #include <ImfOpaqueAttribute.h>
 #include "Iex.h"
 #include <string.h>
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 OpaqueAttribute::OpaqueAttribute (const char typeName[]):
@@ -87,14 +88,14 @@ OpaqueAttribute::copy () const
 
 
 void	
-OpaqueAttribute::writeValueTo (OStream &os, int version) const
+OpaqueAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     Xdr::write <StreamIO> (os, _data, _dataSize);
 }
 
 
 void	
-OpaqueAttribute::readValueFrom (IStream &is, int size, int version)
+OpaqueAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     _data.resizeErase (size);
     _dataSize = size;
@@ -109,7 +110,7 @@ OpaqueAttribute::copyValueFrom (const Attribute &other)
 
     if (oa == 0 || strcmp (_typeName, oa->_typeName))
     {
-	THROW (Iex::TypeExc, "Cannot copy the value of an "
+	THROW (IEX_NAMESPACE::TypeExc, "Cannot copy the value of an "
 			     "image file attribute of type "
 			     "\"" << other.typeName() << "\" "
 			     "to an attribute of type "
@@ -122,4 +123,4 @@ OpaqueAttribute::copyValueFrom (const Attribute &other)
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfOpaqueAttribute.h b/Source/OpenEXR/IlmImf/ImfOpaqueAttribute.h
index 864ae93..1682bfd 100644
--- a/Source/OpenEXR/IlmImf/ImfOpaqueAttribute.h
+++ b/Source/OpenEXR/IlmImf/ImfOpaqueAttribute.h
@@ -49,13 +49,14 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfAttribute.h>
-#include <ImfArray.h>
+#include "ImfAttribute.h"
+#include "ImfArray.h"
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
-class OpaqueAttribute: public Attribute
+class IMF_EXPORT OpaqueAttribute: public Attribute
 {
   public:
 
@@ -86,10 +87,10 @@ class OpaqueAttribute: public Attribute
     // I/O and copying
     //----------------
 
-    virtual void		writeValueTo (OStream &os,
+    virtual void		writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
 					      int version) const;
 
-    virtual void		readValueFrom (IStream &is,
+    virtual void		readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
 					       int size,
 					       int version);
 
@@ -104,11 +105,6 @@ class OpaqueAttribute: public Attribute
 };
 
 
-} // namespace Imf
-
-// Metrowerks compiler wants the .cpp file inlined, too
-#ifdef __MWERKS__
-#include <ImfOpaqueAttribute.cpp>
-#endif
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfOptimizedPixelReading.h b/Source/OpenEXR/IlmImf/ImfOptimizedPixelReading.h
new file mode 100644
index 0000000..1c83497
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfOptimizedPixelReading.h
@@ -0,0 +1,646 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2012, Autodesk, Inc.
+// 
+// All rights reserved.
+//
+// Implementation of IIF-specific file format and speed optimizations 
+// provided by Innobec Technologies inc on behalf of Autodesk.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission. 
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#pragma once
+
+#ifndef INCLUDED_IMF_OPTIMIZED_PIXEL_READING_H
+#define INCLUDED_IMF_OPTIMIZED_PIXEL_READING_H
+
+#include "ImfSimd.h"
+#include "ImfSystemSpecific.h"
+#include <iostream>
+#include "ImfChannelList.h"
+#include "ImfFrameBuffer.h"
+#include "ImfStringVectorAttribute.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+class OptimizationMode
+{
+public:
+
+
+    bool _optimizable;
+    int _ySampling;
+    OptimizationMode() : _optimizable(false) {}
+    
+};
+
+
+#if IMF_HAVE_SSE2
+
+
+//------------------------------------------------------------------------
+// Test for SSE pointer alignemnt
+//------------------------------------------------------------------------
+EXR_FORCEINLINE
+bool
+isPointerSSEAligned (const void* EXR_RESTRICT pPointer)
+{
+    unsigned long trailingBits = ((unsigned long)pPointer) & 15;
+    return trailingBits == 0;
+}
+
+//------------------------------------------------------------------------
+// Load SSE from address into register
+//------------------------------------------------------------------------
+template<bool IS_ALIGNED>
+EXR_FORCEINLINE
+__m128i loadSSE (__m128i*& loadAddress)
+{
+    // throw exception :: this is not accepted
+    return _mm_loadu_si128 (loadAddress);
+}
+
+template<>
+EXR_FORCEINLINE
+__m128i loadSSE<false> (__m128i*& loadAddress)
+{
+    return _mm_loadu_si128 (loadAddress);
+}
+
+template<>
+EXR_FORCEINLINE
+__m128i loadSSE<true> (__m128i*& loadAddress)
+{
+    return _mm_load_si128 (loadAddress);
+}
+
+//------------------------------------------------------------------------
+// Store SSE from register into address
+//------------------------------------------------------------------------
+template<bool IS_ALIGNED>
+EXR_FORCEINLINE
+void storeSSE (__m128i*& storeAddress, __m128i& dataToStore)
+{
+
+}
+
+template<>
+EXR_FORCEINLINE
+void
+storeSSE<false> (__m128i*& storeAddress, __m128i& dataToStore)
+{
+    _mm_storeu_si128 (storeAddress, dataToStore);
+}
+
+template<>
+EXR_FORCEINLINE
+void
+storeSSE<true> (__m128i*& storeAddress, __m128i& dataToStore)
+{
+    _mm_stream_si128 (storeAddress, dataToStore);
+}
+
+
+
+//------------------------------------------------------------------------
+//
+// Write to RGBA
+//
+//------------------------------------------------------------------------
+
+//
+// Using SSE intrinsics
+//
+template<bool READ_PTR_ALIGNED, bool WRITE_PTR_ALIGNED>
+EXR_FORCEINLINE 
+void writeToRGBASSETemplate 
+    (__m128i*& readPtrSSERed,
+     __m128i*& readPtrSSEGreen,
+     __m128i*& readPtrSSEBlue,
+     __m128i*& readPtrSSEAlpha,
+     __m128i*& writePtrSSE,
+     const size_t& lPixelsToCopySSE)
+{
+    for (size_t i = 0; i < lPixelsToCopySSE; ++i)
+    {
+        __m128i redRegister   = loadSSE<READ_PTR_ALIGNED> (readPtrSSERed);
+        __m128i greenRegister = loadSSE<READ_PTR_ALIGNED> (readPtrSSEGreen);
+        __m128i blueRegister  = loadSSE<READ_PTR_ALIGNED> (readPtrSSEBlue);
+        __m128i alphaRegister = loadSSE<READ_PTR_ALIGNED> (readPtrSSEAlpha);
+
+        __m128i redGreenRegister  = _mm_unpacklo_epi16 (redRegister,
+                                                        greenRegister);
+        __m128i blueAlphaRegister = _mm_unpacklo_epi16 (blueRegister,
+                                                        alphaRegister);
+
+        __m128i pixel12Register   = _mm_unpacklo_epi32 (redGreenRegister,
+                                                        blueAlphaRegister);
+        __m128i pixel34Register   = _mm_unpackhi_epi32 (redGreenRegister,
+                                                        blueAlphaRegister);
+
+        storeSSE<WRITE_PTR_ALIGNED> (writePtrSSE, pixel12Register);
+        ++writePtrSSE;
+
+        storeSSE<WRITE_PTR_ALIGNED> (writePtrSSE, pixel34Register);
+        ++writePtrSSE;
+
+        redGreenRegister  = _mm_unpackhi_epi16 (redRegister, greenRegister);
+        blueAlphaRegister = _mm_unpackhi_epi16 (blueRegister, alphaRegister);
+
+        pixel12Register   = _mm_unpacklo_epi32 (redGreenRegister,
+                                                blueAlphaRegister);
+        pixel34Register   = _mm_unpackhi_epi32 (redGreenRegister,
+                                                blueAlphaRegister);
+
+        storeSSE<WRITE_PTR_ALIGNED> (writePtrSSE, pixel12Register);
+        ++writePtrSSE;
+        
+        storeSSE<WRITE_PTR_ALIGNED> (writePtrSSE, pixel34Register);
+        ++writePtrSSE;
+
+        ++readPtrSSEAlpha;
+        ++readPtrSSEBlue;
+        ++readPtrSSEGreen;
+        ++readPtrSSERed;
+    }
+}
+
+//
+// Not using SSE intrinsics.  This is still faster than the alternative
+// because we have multiple read pointers and therefore we are able to
+// take advantage of data locality for write operations.
+//
+EXR_FORCEINLINE 
+void writeToRGBANormal (unsigned short*& readPtrRed,
+                        unsigned short*& readPtrGreen,
+                        unsigned short*& readPtrBlue,
+                        unsigned short*& readPtrAlpha,
+                        unsigned short*& writePtr,
+                        const size_t& lPixelsToCopy)
+{
+    for (size_t i = 0; i < lPixelsToCopy; ++i)
+    {
+        *(writePtr++) = *(readPtrRed++);
+        *(writePtr++) = *(readPtrGreen++);
+        *(writePtr++) = *(readPtrBlue++);
+        *(writePtr++) = *(readPtrAlpha++);
+    }
+}
+
+//
+// Determine which (template) version to use by checking whether pointers
+// are aligned
+//
+EXR_FORCEINLINE 
+void optimizedWriteToRGBA (unsigned short*& readPtrRed,
+                           unsigned short*& readPtrGreen,
+                           unsigned short*& readPtrBlue,
+                           unsigned short*& readPtrAlpha,
+                           unsigned short*& writePtr,
+                           const size_t& pixelsToCopySSE,
+                           const size_t& pixelsToCopyNormal)
+{
+    bool readPtrAreAligned = true;
+
+    readPtrAreAligned &= isPointerSSEAligned(readPtrRed);
+    readPtrAreAligned &= isPointerSSEAligned(readPtrGreen);
+    readPtrAreAligned &= isPointerSSEAligned(readPtrBlue);
+    readPtrAreAligned &= isPointerSSEAligned(readPtrAlpha);
+
+    bool writePtrIsAligned = isPointerSSEAligned(writePtr);
+
+    if (!readPtrAreAligned && !writePtrIsAligned)
+    {
+        writeToRGBASSETemplate<false, false> ((__m128i*&)readPtrRed,
+                                              (__m128i*&)readPtrGreen,
+                                              (__m128i*&)readPtrBlue,
+                                              (__m128i*&)readPtrAlpha,
+                                              (__m128i*&)writePtr,
+                                              pixelsToCopySSE);
+    }
+    else if (!readPtrAreAligned && writePtrIsAligned)
+    {
+        writeToRGBASSETemplate<false, true> ((__m128i*&)readPtrRed,
+                                             (__m128i*&)readPtrGreen,
+                                             (__m128i*&)readPtrBlue,
+                                             (__m128i*&)readPtrAlpha,
+                                             (__m128i*&)writePtr,
+                                             pixelsToCopySSE);
+    }
+    else if (readPtrAreAligned && !writePtrIsAligned)
+    {
+        writeToRGBASSETemplate<true, false> ((__m128i*&)readPtrRed,
+                                             (__m128i*&)readPtrGreen,
+                                             (__m128i*&)readPtrBlue,
+                                             (__m128i*&)readPtrAlpha,
+                                             (__m128i*&)writePtr,
+                                             pixelsToCopySSE);
+    }
+    else if(readPtrAreAligned && writePtrIsAligned)
+    {
+        writeToRGBASSETemplate<true, true> ((__m128i*&)readPtrRed,
+                                            (__m128i*&)readPtrGreen,
+                                            (__m128i*&)readPtrBlue,
+                                            (__m128i*&)readPtrAlpha,
+                                            (__m128i*&)writePtr,
+                                            pixelsToCopySSE);
+    }
+
+    writeToRGBANormal (readPtrRed, readPtrGreen, readPtrBlue, readPtrAlpha,
+                       writePtr, pixelsToCopyNormal);
+}
+
+
+
+//------------------------------------------------------------------------
+//
+// Write to RGBA Fill A
+//
+//------------------------------------------------------------------------
+
+//
+// Using SSE intrinsics
+//
+template<bool READ_PTR_ALIGNED, bool WRITE_PTR_ALIGNED>
+EXR_FORCEINLINE 
+void
+writeToRGBAFillASSETemplate (__m128i*& readPtrSSERed,
+                             __m128i*& readPtrSSEGreen,
+                             __m128i*& readPtrSSEBlue,
+                             const unsigned short& alphaFillValue,
+                             __m128i*& writePtrSSE,
+                             const size_t& pixelsToCopySSE)
+{
+    const __m128i dummyAlphaRegister = _mm_set_epi16 (alphaFillValue,
+                                                      alphaFillValue,
+                                                      alphaFillValue,
+                                                      alphaFillValue,
+                                                      alphaFillValue,
+                                                      alphaFillValue,
+                                                      alphaFillValue,
+                                                      alphaFillValue);
+
+    for (size_t pixelCounter = 0; pixelCounter < pixelsToCopySSE; ++pixelCounter)
+    {
+        __m128i redRegister   = loadSSE<READ_PTR_ALIGNED> (readPtrSSERed);
+        __m128i greenRegister = loadSSE<READ_PTR_ALIGNED> (readPtrSSEGreen);
+        __m128i blueRegister  = loadSSE<READ_PTR_ALIGNED> (readPtrSSEBlue);
+
+        __m128i redGreenRegister  = _mm_unpacklo_epi16 (redRegister,
+                                                        greenRegister);
+        __m128i blueAlphaRegister = _mm_unpacklo_epi16 (blueRegister,
+                                                        dummyAlphaRegister);
+
+        __m128i pixel12Register   = _mm_unpacklo_epi32 (redGreenRegister,
+                                                        blueAlphaRegister);
+        __m128i pixel34Register   = _mm_unpackhi_epi32 (redGreenRegister,
+                                                        blueAlphaRegister);
+
+        storeSSE<WRITE_PTR_ALIGNED> (writePtrSSE, pixel12Register);
+        ++writePtrSSE;
+
+        storeSSE<WRITE_PTR_ALIGNED> (writePtrSSE, pixel34Register);
+        ++writePtrSSE;
+
+        redGreenRegister  = _mm_unpackhi_epi16 (redRegister,
+                                                greenRegister);
+        blueAlphaRegister = _mm_unpackhi_epi16 (blueRegister,
+                                                dummyAlphaRegister);
+
+        pixel12Register   = _mm_unpacklo_epi32 (redGreenRegister,
+                                                blueAlphaRegister);
+        pixel34Register   = _mm_unpackhi_epi32 (redGreenRegister,
+                                                blueAlphaRegister);
+
+        storeSSE<WRITE_PTR_ALIGNED> (writePtrSSE, pixel12Register);
+        ++writePtrSSE;
+
+        storeSSE<WRITE_PTR_ALIGNED> (writePtrSSE, pixel34Register);
+        ++writePtrSSE;
+
+        ++readPtrSSEBlue;
+        ++readPtrSSEGreen;
+        ++readPtrSSERed;
+    }
+}
+
+//
+// Not using SSE intrinsics.  This is still faster than the alternative
+// because we have multiple read pointers and therefore we are able to
+// take advantage of data locality for write operations.
+//
+EXR_FORCEINLINE
+void
+writeToRGBAFillANormal (unsigned short*& readPtrRed,
+                        unsigned short*& readPtrGreen,
+                        unsigned short*& readPtrBlue,
+                        const unsigned short& alphaFillValue,
+                        unsigned short*& writePtr,
+                        const size_t& pixelsToCopy)
+{
+    for (size_t i = 0; i < pixelsToCopy; ++i)
+    {
+        *(writePtr++) = *(readPtrRed++);
+        *(writePtr++) = *(readPtrGreen++);
+        *(writePtr++) = *(readPtrBlue++);
+        *(writePtr++) = alphaFillValue;
+    }
+}
+
+//
+// Determine which (template) version to use by checking whether pointers
+// are aligned.
+//
+EXR_FORCEINLINE 
+void
+optimizedWriteToRGBAFillA (unsigned short*& readPtrRed,
+                           unsigned short*& readPtrGreen,
+                           unsigned short*& readPtrBlue,
+                           const unsigned short& alphaFillValue,
+                           unsigned short*& writePtr,
+                           const size_t& pixelsToCopySSE,
+                           const size_t& pixelsToCopyNormal)
+{
+    bool readPtrAreAligned = true;
+
+    readPtrAreAligned &= isPointerSSEAligned (readPtrRed);
+    readPtrAreAligned &= isPointerSSEAligned (readPtrGreen);
+    readPtrAreAligned &= isPointerSSEAligned (readPtrBlue);
+
+    bool writePtrIsAligned = isPointerSSEAligned (writePtr);
+
+    if (!readPtrAreAligned && !writePtrIsAligned)
+    {
+        writeToRGBAFillASSETemplate<false, false> ((__m128i*&)readPtrRed,
+                                                   (__m128i*&)readPtrGreen,
+                                                   (__m128i*&)readPtrBlue,
+                                                   alphaFillValue,
+                                                   (__m128i*&)writePtr,
+                                                   pixelsToCopySSE);
+    }
+    else if (!readPtrAreAligned && writePtrIsAligned)
+    {
+        writeToRGBAFillASSETemplate<false, true> ((__m128i*&)readPtrRed,
+                                                  (__m128i*&)readPtrGreen,
+                                                  (__m128i*&)readPtrBlue,
+                                                  alphaFillValue,
+                                                  (__m128i*&)writePtr,
+                                                  pixelsToCopySSE);
+    }
+    else if (readPtrAreAligned && !writePtrIsAligned)
+    {
+        writeToRGBAFillASSETemplate<true, false> ((__m128i*&)readPtrRed,
+                                                  (__m128i*&)readPtrGreen,
+                                                  (__m128i*&)readPtrBlue,
+                                                  alphaFillValue,
+                                                  (__m128i*&)writePtr,
+                                                  pixelsToCopySSE);
+    }
+    else if (readPtrAreAligned && writePtrIsAligned)
+    {
+        writeToRGBAFillASSETemplate<true, true> ((__m128i*&)readPtrRed,
+                                                 (__m128i*&)readPtrGreen,
+                                                 (__m128i*&)readPtrBlue,
+                                                 alphaFillValue,
+                                                 (__m128i*&)writePtr,
+                                                 pixelsToCopySSE);
+    }
+
+    writeToRGBAFillANormal (readPtrRed,
+                            readPtrGreen, readPtrBlue, alphaFillValue,
+                            writePtr, pixelsToCopyNormal);
+}
+
+
+
+//------------------------------------------------------------------------
+//
+// Write to RGB
+//
+//------------------------------------------------------------------------
+
+//
+// Using SSE intrinsics
+//
+template<bool READ_PTR_ALIGNED, bool WRITE_PTR_ALIGNED>
+EXR_FORCEINLINE 
+void
+writeToRGBSSETemplate (__m128i*& readPtrSSERed,
+                       __m128i*& readPtrSSEGreen,
+                       __m128i*& readPtrSSEBlue,
+                       __m128i*& writePtrSSE,
+                       const size_t& pixelsToCopySSE)
+{
+
+    for (size_t pixelCounter = 0; pixelCounter < pixelsToCopySSE; ++pixelCounter)
+    {
+        //
+        // Need to shuffle and unpack pointers to obtain my first register
+        // We must save 8 pixels at a time, so we must have the following three registers at the end:
+        // 1) R1 G1 B1 R2 G2 B2 R3 G3
+        // 2) B3 R4 G4 B4 R5 G5 B5 R6
+        // 3) G6 B6 R7 G7 B7 R8 G8 B8
+        //
+        __m128i redRegister = loadSSE<READ_PTR_ALIGNED> (readPtrSSERed);
+        __m128i greenRegister = loadSSE<READ_PTR_ALIGNED> (readPtrSSEGreen);
+        __m128i blueRegister = loadSSE<READ_PTR_ALIGNED> (readPtrSSEBlue);
+
+        //
+        // First register: R1 G1 B1 R2 G2 B2 R3 G3
+        // Construct 2 registers and then unpack them to obtain our final result:
+        //
+        __m128i redGreenRegister  = _mm_unpacklo_epi16 (redRegister,
+                                                        greenRegister);
+        __m128i redBlueRegister   = _mm_unpacklo_epi16 (redRegister,
+                                                        blueRegister);
+        __m128i greenBlueRegister = _mm_unpacklo_epi16 (greenRegister,
+                                                        blueRegister);
+
+        // Left Part (R1 G1 B1 R2)
+        __m128i quarterRight = _mm_shufflelo_epi16 (redBlueRegister,
+                                                    _MM_SHUFFLE(3,0,2,1));
+        __m128i halfLeft     = _mm_unpacklo_epi32 (redGreenRegister,
+                                                   quarterRight);
+
+        // Right Part (G2 B2 R3 G3)
+        __m128i quarterLeft  = _mm_shuffle_epi32 (greenBlueRegister,
+                                                 _MM_SHUFFLE(3,2,0,1));
+        quarterRight         = _mm_shuffle_epi32 (redGreenRegister,
+                                                 _MM_SHUFFLE(3,0,1,2));
+        __m128i halfRight    = _mm_unpacklo_epi32 (quarterLeft, quarterRight);
+
+        __m128i fullRegister = _mm_unpacklo_epi64 (halfLeft, halfRight);
+        storeSSE<WRITE_PTR_ALIGNED> (writePtrSSE, fullRegister);
+        ++writePtrSSE;
+
+        //
+        // Second register: B3 R4 G4 B4 R5 G5 B5 R6
+        //
+
+        // Left Part (B3, R4, G4, B4)
+        quarterLeft  = _mm_shufflehi_epi16 (redBlueRegister,
+                                            _MM_SHUFFLE(0, 3, 2, 1));
+        quarterRight = _mm_shufflehi_epi16 (greenBlueRegister,
+                                            _MM_SHUFFLE(1, 0, 3, 2));
+        halfLeft     = _mm_unpackhi_epi32 (quarterLeft, quarterRight);
+
+        // Update the registers
+        redGreenRegister  = _mm_unpackhi_epi16 (redRegister, greenRegister);
+        redBlueRegister   = _mm_unpackhi_epi16 (redRegister, blueRegister);
+        greenBlueRegister = _mm_unpackhi_epi16 (greenRegister, blueRegister);
+
+        // Right Part (R5 G5 B5 R6)
+        quarterRight = _mm_shufflelo_epi16 (redBlueRegister,
+                                            _MM_SHUFFLE(3,0,2,1));
+        halfRight    = _mm_unpacklo_epi32 (redGreenRegister, quarterRight);
+
+        fullRegister = _mm_unpacklo_epi64 (halfLeft, halfRight);
+        storeSSE<WRITE_PTR_ALIGNED> (writePtrSSE, fullRegister);
+        ++writePtrSSE;
+
+        //
+        // Third register: G6 B6 R7 G7 B7 R8 G8 B8
+        //
+
+        // Left part (G6 B6 R7 G7)
+        quarterLeft  = _mm_shuffle_epi32 (greenBlueRegister,
+                                          _MM_SHUFFLE(3,2,0,1));
+        quarterRight = _mm_shuffle_epi32 (redGreenRegister,
+                                          _MM_SHUFFLE(3,0,1,2));
+        halfLeft     = _mm_unpacklo_epi32 (quarterLeft, quarterRight);
+
+        // Right part (B7 R8 G8 B8)
+        quarterLeft  = _mm_shufflehi_epi16 (redBlueRegister,
+                                            _MM_SHUFFLE(0, 3, 2, 1));
+        quarterRight = _mm_shufflehi_epi16 (greenBlueRegister,
+                                            _MM_SHUFFLE(1, 0, 3, 2));
+        halfRight    = _mm_unpackhi_epi32 (quarterLeft, quarterRight);
+
+        fullRegister = _mm_unpacklo_epi64 (halfLeft, halfRight);
+        storeSSE<WRITE_PTR_ALIGNED> (writePtrSSE, fullRegister);
+        ++writePtrSSE;
+
+        //
+        // Increment read pointers
+        //
+        ++readPtrSSEBlue;
+        ++readPtrSSEGreen;
+        ++readPtrSSERed;
+    }
+}
+
+//
+// Not using SSE intrinsics.  This is still faster than the alternative
+// because we have multiple read pointers and therefore we are able to
+// take advantage of data locality for write operations.
+//
+EXR_FORCEINLINE 
+void
+writeToRGBNormal (unsigned short*& readPtrRed,
+                  unsigned short*& readPtrGreen,
+                  unsigned short*& readPtrBlue,
+                  unsigned short*& writePtr,
+                  const size_t& pixelsToCopy)
+{
+    for (size_t i = 0; i < pixelsToCopy; ++i)
+    {
+        *(writePtr++) = *(readPtrRed++);
+        *(writePtr++) = *(readPtrGreen++);
+        *(writePtr++) = *(readPtrBlue++);
+    }
+}
+
+//
+// Determine which (template) version to use by checking whether pointers
+// are aligned
+//
+EXR_FORCEINLINE 
+void optimizedWriteToRGB (unsigned short*& readPtrRed,
+                          unsigned short*& readPtrGreen,
+                          unsigned short*& readPtrBlue,
+                          unsigned short*& writePtr,
+                          const size_t& pixelsToCopySSE,
+                          const size_t& pixelsToCopyNormal)
+{
+    bool readPtrAreAligned = true;
+
+    readPtrAreAligned &= isPointerSSEAligned(readPtrRed);
+    readPtrAreAligned &= isPointerSSEAligned(readPtrGreen);
+    readPtrAreAligned &= isPointerSSEAligned(readPtrBlue);
+
+    bool writePtrIsAligned = isPointerSSEAligned(writePtr);
+
+    if (!readPtrAreAligned && !writePtrIsAligned)
+    {
+        writeToRGBSSETemplate<false, false> ((__m128i*&)readPtrRed,
+                                             (__m128i*&)readPtrGreen,
+                                             (__m128i*&)readPtrBlue,
+                                             (__m128i*&)writePtr,
+                                             pixelsToCopySSE);
+    }
+    else if (!readPtrAreAligned && writePtrIsAligned)
+    {
+        writeToRGBSSETemplate<false, true> ((__m128i*&)readPtrRed,
+                                            (__m128i*&)readPtrGreen,
+                                            (__m128i*&)readPtrBlue,
+                                            (__m128i*&)writePtr,
+                                            pixelsToCopySSE);
+    }
+    else if (readPtrAreAligned && !writePtrIsAligned)
+    {
+        writeToRGBSSETemplate<true, false> ((__m128i*&)readPtrRed,
+                                            (__m128i*&)readPtrGreen,
+                                            (__m128i*&)readPtrBlue,
+                                            (__m128i*&)writePtr,
+                                            pixelsToCopySSE);
+    }
+    else if (readPtrAreAligned && writePtrIsAligned)
+    {
+        writeToRGBSSETemplate<true, true> ((__m128i*&)readPtrRed,
+                                           (__m128i*&)readPtrGreen,
+                                           (__m128i*&)readPtrBlue,
+                                           (__m128i*&)writePtr,
+                                           pixelsToCopySSE);
+    }
+
+
+    writeToRGBNormal (readPtrRed, readPtrGreen, readPtrBlue,
+                      writePtr, pixelsToCopyNormal);
+}
+
+
+
+
+#else // ! defined IMF_HAVE_SSE2
+
+#endif // defined IMF_HAVE_SSE2
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif
diff --git a/Source/OpenEXR/IlmImf/ImfOutputFile.cpp b/Source/OpenEXR/IlmImf/ImfOutputFile.cpp
index 31a339e..2619d9c 100644
--- a/Source/OpenEXR/IlmImf/ImfOutputFile.cpp
+++ b/Source/OpenEXR/IlmImf/ImfOutputFile.cpp
@@ -1,3 +1,7 @@
+//
+///\todo: version needs fixing!
+//
+
 ///////////////////////////////////////////////////////////////////////////
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
@@ -48,34 +52,41 @@
 #include "ImathBox.h"
 #include "ImathFun.h"
 #include <ImfArray.h>
-#include <ImfXdr.h>
+#include "ImfXdr.h"
 #include <ImfPreviewImageAttribute.h>
+#include <ImfPartType.h>
 #include "IlmThreadPool.h"
+#include "ImfOutputStreamMutex.h"
 #include "IlmThreadSemaphore.h"
 #include "IlmThreadMutex.h"
 #include "Iex.h"
+#include "ImfInputPart.h"
+#include "ImfNamespace.h"
+#include "ImfOutputPartData.h"
+
 #include <string>
 #include <vector>
 #include <fstream>
 #include <assert.h>
+#include <algorithm>
 
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
-namespace Imf {
-
-using Imath::Box2i;
-using Imath::divp;
-using Imath::modp;
+using IMATH_NAMESPACE::Box2i;
+using IMATH_NAMESPACE::divp;
+using IMATH_NAMESPACE::modp;
 using std::string;
 using std::vector;
 using std::ofstream;
 using std::min;
 using std::max;
-using IlmThread::Mutex;
-using IlmThread::Lock;
-using IlmThread::Semaphore;
-using IlmThread::Task;
-using IlmThread::TaskGroup;
-using IlmThread::ThreadPool;
+using ILMTHREAD_NAMESPACE::Mutex;
+using ILMTHREAD_NAMESPACE::Lock;
+using ILMTHREAD_NAMESPACE::Semaphore;
+using ILMTHREAD_NAMESPACE::Task;
+using ILMTHREAD_NAMESPACE::TaskGroup;
+using ILMTHREAD_NAMESPACE::ThreadPool;
+
 
 namespace {
 
@@ -97,6 +108,7 @@ struct OutSliceInfo
 	          int xSampling = 1,
 	          int ySampling = 1,
 	          bool zero = false);
+                  
 };
 
 
@@ -165,11 +177,11 @@ LineBuffer::~LineBuffer ()
 
 } // namespace
 
-
-struct OutputFile::Data: public Mutex
+struct OutputFile::Data
 {
     Header		 header;		// the image header
-    int			 version;		// file format version
+    bool                 multiPart;		// is the file multipart?
+    int			 version;               // version attribute \todo NOT BEING WRITTEN PROPERLY
     Int64		 previewPosition;       // file position for preview
     FrameBuffer		 frameBuffer;           // framebuffer to write into
     int			 currentScanLine;       // next scanline to be written
@@ -187,18 +199,18 @@ struct OutputFile::Data: public Mutex
                                                 // its linebuffer
     Compressor::Format	 format;                // compressor's data format
     vector<OutSliceInfo> slices;		// info about channels in file
-    OStream *		 os;			// file stream to write to
-    bool		 deleteStream;
     Int64		 lineOffsetsPosition;   // file position for line
                                                 // offset table
-    Int64		 currentPosition;       // current file position
 
     vector<LineBuffer*>  lineBuffers;           // each holds one line buffer
     int			 linesInBuffer;         // number of scanlines each
                                                 // buffer holds
     size_t		 lineBufferSize;        // size of the line buffer
 
-     Data (bool deleteStream, int numThreads);
+    int                  partNumber;            // the output part number
+    OutputStreamMutex *  _streamData;         
+    bool                 _deleteStream;
+     Data (int numThreads);
     ~Data ();
 
 
@@ -208,10 +220,11 @@ struct OutputFile::Data: public Mutex
 };
 
 
-OutputFile::Data::Data (bool deleteStream, int numThreads):
-    os (0),
-    deleteStream (deleteStream),
-    lineOffsetsPosition (0)
+OutputFile::Data::Data (int numThreads):
+    lineOffsetsPosition (0),
+    partNumber (-1),
+    _streamData(0),
+    _deleteStream(false)
 {
     //
     // We need at least one lineBuffer, but if threading is used,
@@ -224,9 +237,6 @@ OutputFile::Data::Data (bool deleteStream, int numThreads):
 
 OutputFile::Data::~Data ()
 {
-    if (deleteStream)
-	delete os;
-
     for (size_t i = 0; i < lineBuffers.size(); i++)
         delete lineBuffers[i];
 }
@@ -238,30 +248,29 @@ OutputFile::Data::getLineBuffer (int number)
     return lineBuffers[number % lineBuffers.size()];
 }
 
-
 namespace {
 
-
 Int64
-writeLineOffsets (OStream &os, const vector<Int64> &lineOffsets)
+writeLineOffsets (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, const vector<Int64> &lineOffsets)
 {
     Int64 pos = os.tellp();
 
     if (pos == -1)
-	Iex::throwErrnoExc ("Cannot determine current file position (%T).");
-
+	IEX_NAMESPACE::throwErrnoExc ("Cannot determine current file position (%T).");
+    
     for (unsigned int i = 0; i < lineOffsets.size(); i++)
-	Xdr::write <StreamIO> (os, lineOffsets[i]);
+	Xdr::write<StreamIO> (os, lineOffsets[i]);
 
     return pos;
 }
 
 
 void
-writePixelData (OutputFile::Data *ofd,
+writePixelData (OutputStreamMutex *filedata,
+                OutputFile::Data *partdata,
                 int lineBufferMinY,
-		const char pixelData[],
-		int pixelDataSize)
+                const char pixelData[],
+                int pixelDataSize)
 {
     //
     // Store a block of pixel data in the output file, and try
@@ -269,39 +278,53 @@ writePixelData (OutputFile::Data *ofd,
     // without calling tellp() (tellp() can be fairly expensive).
     //
 
-    Int64 currentPosition = ofd->currentPosition;
-    ofd->currentPosition = 0;
+    Int64 currentPosition = filedata->currentPosition;
+    filedata->currentPosition = 0;
 
     if (currentPosition == 0)
-	currentPosition = ofd->os->tellp();
+        currentPosition = filedata->os->tellp();
 
-    ofd->lineOffsets[(ofd->currentScanLine - ofd->minY) / ofd->linesInBuffer] =
-	currentPosition;
+    partdata->lineOffsets[(partdata->currentScanLine - partdata->minY) / partdata->linesInBuffer] =
+        currentPosition;
 
     #ifdef DEBUG
 
-	assert (ofd->os->tellp() == currentPosition);
+        assert (filedata->os->tellp() == currentPosition);
 
     #endif
+    
+	
+	
+    if (partdata->multiPart)
+    {
+        OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*filedata->os, partdata->partNumber);
+    }
+    
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*filedata->os, lineBufferMinY);
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*filedata->os, pixelDataSize);
+    filedata->os->write (pixelData, pixelDataSize);
 
-    Xdr::write <StreamIO> (*ofd->os, lineBufferMinY);
-    Xdr::write <StreamIO> (*ofd->os, pixelDataSize);
-    ofd->os->write (pixelData, pixelDataSize);
+    filedata->currentPosition = currentPosition +
+                           Xdr::size<int>() +
+                           Xdr::size<int>() +
+                           pixelDataSize;
 
-    ofd->currentPosition = currentPosition +
-			   Xdr::size<int>() +
-			   Xdr::size<int>() +
-			   pixelDataSize;
+    if (partdata->multiPart)
+    {
+        filedata->currentPosition += Xdr::size<int>();
+    }
 }
 
 
 inline void
-writePixelData (OutputFile::Data *ofd, const LineBuffer *lineBuffer)
+writePixelData (OutputStreamMutex* filedata,
+                OutputFile::Data *partdata,
+                const LineBuffer *lineBuffer)
 {
-    writePixelData (ofd,
-		    lineBuffer->minY,
+    writePixelData (filedata, partdata,
+                    lineBuffer->minY,
                     lineBuffer->dataPtr,
-		    lineBuffer->dataSize);
+                    lineBuffer->dataSize);
 }
 
 
@@ -326,35 +349,18 @@ convertToXdr (OutputFile::Data *ofd,
     // pixel data in place, without an intermediate temporary buffer.
     //
    
-    int startY, endY;		// The first and last scanlines in
-    				// the file that are in the lineBuffer.
-    int step;
-    
-    if (ofd->lineOrder == INCREASING_Y)
-    {
-	startY = max (lineBufferMinY, ofd->minY);
-	endY = min (lineBufferMaxY, ofd->maxY) + 1;
-        step = 1;
-    }
-    else
-    {
-	startY = min (lineBufferMaxY, ofd->maxY);
-	endY = max (lineBufferMinY, ofd->minY) - 1;
-        step = -1;
-    }
-
     //
     // Iterate over all scanlines in the lineBuffer to convert.
     //
 
-    for (int y = startY; y != endY; y += step)
+    char *writePtr = &lineBuffer[0];
+    for (int y = lineBufferMinY; y <= lineBufferMaxY; y++)
     {
 	//
         // Set these to point to the start of line y.
         // We will write to writePtr from readPtr.
 	//
-	
-        char *writePtr = lineBuffer + ofd->offsetInLineBuffer[y - ofd->minY];
+
         const char *readPtr = writePtr;
         
 	//
@@ -507,7 +513,7 @@ LineBufferTask::execute ()
             //
             // Iterate over all image channels.
             //
-        
+
             for (unsigned int i = 0; i < _ofd->slices.size(); ++i)
             {
                 //
@@ -650,17 +656,30 @@ OutputFile::OutputFile
      const Header &header,
      int numThreads)
 :
-    _data (new Data (true, numThreads))
+    _data (new Data (numThreads))
+    
 {
+    _data->_streamData=new OutputStreamMutex ();
+    _data->_deleteStream=true;
     try
     {
 	header.sanityCheck();
-	_data->os = new StdOFStream (fileName);
+	_data->_streamData->os = new StdOFStream (fileName);
+        _data->multiPart=false; // only one header, not multipart
 	initialize (header);
+	_data->_streamData->currentPosition = _data->_streamData->os->tellp();
+        
+	// Write header and empty offset table to the file.
+	writeMagicNumberAndVersionField(*_data->_streamData->os, _data->header);
+	_data->previewPosition =
+	        _data->header.writeTo (*_data->_streamData->os);
+        _data->lineOffsetsPosition =
+                writeLineOffsets (*_data->_streamData->os,_data->lineOffsets);
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
-	delete _data;
+        if (_data && _data->_streamData) delete _data->_streamData;
+	if (_data)       delete _data;
 
 	REPLACE_EXC (e, "Cannot open image file "
 			"\"" << fileName << "\". " << e);
@@ -668,28 +687,43 @@ OutputFile::OutputFile
     }
     catch (...)
     {
-	delete _data;
+        if (_data && _data->_streamData) delete _data->_streamData;
+        if (_data)       delete _data;
+
         throw;
     }
 }
 
 
 OutputFile::OutputFile
-    (OStream &os,
+    (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
      const Header &header,
      int numThreads)
 :
-    _data (new Data (false, numThreads))
+    _data (new Data (numThreads))
 {
+    
+    _data->_streamData=new OutputStreamMutex ();
+    _data->_deleteStream=false;
     try
     {
 	header.sanityCheck();
-	_data->os = &os;
+	_data->_streamData->os = &os;
+        _data->multiPart=false;
 	initialize (header);
+	_data->_streamData->currentPosition = _data->_streamData->os->tellp();
+
+	// Write header and empty offset table to the file.
+	writeMagicNumberAndVersionField(*_data->_streamData->os, _data->header);
+	_data->previewPosition =
+	        _data->header.writeTo (*_data->_streamData->os);
+        _data->lineOffsetsPosition =
+                writeLineOffsets (*_data->_streamData->os, _data->lineOffsets);
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
-	delete _data;
+        if (_data && _data->_streamData) delete _data->_streamData;
+	if (_data)       delete _data;
 
 	REPLACE_EXC (e, "Cannot open image file "
 			"\"" << os.fileName() << "\". " << e);
@@ -697,17 +731,58 @@ OutputFile::OutputFile
     }
     catch (...)
     {
-	delete _data;
+        if (_data && _data->_streamData) delete _data->_streamData;
+        if (_data)       delete _data;
+
         throw;
     }
 }
 
+OutputFile::OutputFile(const OutputPartData* part) : _data(NULL)
+{
+    try
+    {
+        if (part->header.type() != SCANLINEIMAGE)
+            throw IEX_NAMESPACE::ArgExc("Can't build a OutputFile from a type-mismatched part.");
+
+        _data = new Data (part->numThreads);
+        _data->_streamData = part->mutex;
+        _data->_deleteStream=false;
+        _data->multiPart=part->multipart;
+
+        initialize (part->header);
+        _data->partNumber = part->partNumber;
+        _data->lineOffsetsPosition = part->chunkOffsetTablePosition;
+        _data->previewPosition = part->previewPosition;
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        if (_data) delete _data;
+
+        REPLACE_EXC (e, "Cannot initialize output part "
+                        "\"" << part->partNumber << "\". " << e);
+        throw;
+    }
+    catch (...)
+    {
+        if (_data) delete _data;
+
+        throw;
+    }
+}
 
 void
 OutputFile::initialize (const Header &header)
 {
     _data->header = header;
 
+    // "fix" the type if it happens to be set incorrectly
+    // (attribute is optional, but ensure it is correct if it exists)
+    if(_data->header.hasType())
+    {
+        _data->header.setType(SCANLINEIMAGE);
+    }
+    
     const Box2i &dataWindow = header.dataWindow();
 
     _data->currentScanLine = (header.lineOrder() == INCREASING_Y)?
@@ -743,18 +818,11 @@ OutputFile::initialize (const Header &header)
 			  _data->linesInBuffer) / _data->linesInBuffer;
 
     _data->lineOffsets.resize (lineOffsetSize);
-
+    
+    
     offsetInLineBufferTable (_data->bytesPerLine,
 			     _data->linesInBuffer,
 			     _data->offsetInLineBuffer);
-
-    _data->previewPosition =
-	_data->header.writeTo (*_data->os);
-
-    _data->lineOffsetsPosition =
-	writeLineOffsets (*_data->os, _data->lineOffsets);
-
-    _data->currentPosition = _data->os->tellp();
 }
 
 
@@ -763,12 +831,20 @@ OutputFile::~OutputFile ()
     if (_data)
     {
         {
+            Lock lock(*_data->_streamData);
+            Int64 originalPosition = _data->_streamData->os->tellp();
+
             if (_data->lineOffsetsPosition > 0)
             {
                 try
                 {
-                    _data->os->seekp (_data->lineOffsetsPosition);
-                    writeLineOffsets (*_data->os, _data->lineOffsets);
+                    _data->_streamData->os->seekp (_data->lineOffsetsPosition);
+                    writeLineOffsets (*_data->_streamData->os, _data->lineOffsets);
+
+                    //
+                    // Restore the original position.
+                    //
+                    _data->_streamData->os->seekp (originalPosition);
                 }
                 catch (...)
                 {
@@ -782,15 +858,22 @@ OutputFile::~OutputFile ()
             }
         }
 
+        if (_data->_deleteStream && _data->_streamData)
+            delete _data->_streamData->os;
+
+        if (_data->partNumber == -1 && _data->_streamData)
+            delete _data->_streamData;
+
 	delete _data;
     }
+
 }
 
 
 const char *
 OutputFile::fileName () const
 {
-    return _data->os->fileName();
+    return _data->_streamData->os->fileName();
 }
 
 
@@ -804,7 +887,7 @@ OutputFile::header () const
 void	
 OutputFile::setFrameBuffer (const FrameBuffer &frameBuffer)
 {
-    Lock lock (*_data);
+    Lock lock (*_data->_streamData);
     
     //
     // Check if the new frame buffer descriptor
@@ -824,7 +907,7 @@ OutputFile::setFrameBuffer (const FrameBuffer &frameBuffer)
 
 	if (i.channel().type != j.slice().type)
 	{
-	    THROW (Iex::ArgExc, "Pixel type of \"" << i.name() << "\" channel "
+	    THROW (IEX_NAMESPACE::ArgExc, "Pixel type of \"" << i.name() << "\" channel "
 			        "of output file \"" << fileName() << "\" is "
 			        "not compatible with the frame buffer's "
 			        "pixel type.");
@@ -833,7 +916,7 @@ OutputFile::setFrameBuffer (const FrameBuffer &frameBuffer)
 	if (i.channel().xSampling != j.slice().xSampling ||
 	    i.channel().ySampling != j.slice().ySampling)
 	{
-	    THROW (Iex::ArgExc, "X and/or y subsampling factors "
+	    THROW (IEX_NAMESPACE::ArgExc, "X and/or y subsampling factors "
 				"of \"" << i.name() << "\" channel "
 				"of output file \"" << fileName() << "\" are "
 				"not compatible with the frame buffer's "
@@ -896,7 +979,7 @@ OutputFile::setFrameBuffer (const FrameBuffer &frameBuffer)
 const FrameBuffer &
 OutputFile::frameBuffer () const
 {
-    Lock lock (*_data);
+    Lock lock (*_data->_streamData);
     return _data->frameBuffer;
 }
 
@@ -906,10 +989,10 @@ OutputFile::writePixels (int numScanLines)
 {
     try
     {
-        Lock lock (*_data);
+        Lock lock (*_data->_streamData);
 
 	if (_data->slices.size() == 0)
-	    throw Iex::ArgExc ("No frame buffer specified "
+	    throw IEX_NAMESPACE::ArgExc ("No frame buffer specified "
 			       "as pixel data source.");
 
         //
@@ -995,7 +1078,7 @@ OutputFile::writePixels (int numScanLines)
             {
                 if (_data->missingScanLines <= 0)
                 {
-                    throw Iex::ArgExc ("Tried to write more scan lines "
+                    throw IEX_NAMESPACE::ArgExc ("Tried to write more scan lines "
                                        "than specified by the data window.");
                 }
     
@@ -1031,7 +1114,7 @@ OutputFile::writePixels (int numScanLines)
                 // Write the line buffer
 		//
 
-                writePixelData (_data, writeBuffer);
+                writePixelData (_data->_streamData, _data, writeBuffer);
                 nextWriteBuffer += step;
 
                 _data->currentScanLine = _data->currentScanLine +
@@ -1104,7 +1187,7 @@ OutputFile::writePixels (int numScanLines)
 
 	const string *exception = 0;
 
-        for (int i = 0; i < _data->lineBuffers.size(); ++i)
+        for (size_t i = 0; i < _data->lineBuffers.size(); ++i)
 	{
             LineBuffer *lineBuffer = _data->lineBuffers[i];
 
@@ -1115,9 +1198,9 @@ OutputFile::writePixels (int numScanLines)
 	}
 
 	if (exception)
-	    throw Iex::IoExc (*exception);
+	    throw IEX_NAMESPACE::IoExc (*exception);
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
 	REPLACE_EXC (e, "Failed to write pixel data to image "
 		        "file \"" << fileName() << "\". " << e);
@@ -1129,7 +1212,7 @@ OutputFile::writePixels (int numScanLines)
 int	
 OutputFile::currentScanLine () const
 {
-    Lock lock (*_data);
+    Lock lock (*_data->_streamData);
     return _data->currentScanLine;
 }
 
@@ -1137,7 +1220,7 @@ OutputFile::currentScanLine () const
 void	
 OutputFile::copyPixels (InputFile &in)
 {
-    Lock lock (*_data);
+    Lock lock (*_data->_streamData);
 
     //
     // Check if this file's and and the InputFile's
@@ -1148,7 +1231,7 @@ OutputFile::copyPixels (InputFile &in)
     const Header &inHdr = in.header();
 
     if (inHdr.find("tiles") != inHdr.end())
-	THROW (Iex::ArgExc, "Cannot copy pixels from image "
+	THROW (IEX_NAMESPACE::ArgExc, "Cannot copy pixels from image "
 			    "file \"" << in.fileName() << "\" to image "
 			    "file \"" << fileName() << "\". "
                             "The input file is tiled, but the output file is "
@@ -1156,25 +1239,25 @@ OutputFile::copyPixels (InputFile &in)
                             "instead.");
 
     if (!(hdr.dataWindow() == inHdr.dataWindow()))
-	THROW (Iex::ArgExc, "Cannot copy pixels from image "
+	THROW (IEX_NAMESPACE::ArgExc, "Cannot copy pixels from image "
 			    "file \"" << in.fileName() << "\" to image "
 			    "file \"" << fileName() << "\". "
                             "The files have different data windows.");
 
     if (!(hdr.lineOrder() == inHdr.lineOrder()))
-	THROW (Iex::ArgExc, "Quick pixel copy from image "
+	THROW (IEX_NAMESPACE::ArgExc, "Quick pixel copy from image "
 			    "file \"" << in.fileName() << "\" to image "
 			    "file \"" << fileName() << "\" failed. "
 			    "The files have different line orders.");
 
     if (!(hdr.compression() == inHdr.compression()))
-	THROW (Iex::ArgExc, "Quick pixel copy from image "
+	THROW (IEX_NAMESPACE::ArgExc, "Quick pixel copy from image "
 			    "file \"" << in.fileName() << "\" to image "
 			    "file \"" << fileName() << "\" failed. "
 			    "The files use different compression methods.");
 
     if (!(hdr.channels() == inHdr.channels()))
-	THROW (Iex::ArgExc, "Quick pixel copy from image "
+	THROW (IEX_NAMESPACE::ArgExc, "Quick pixel copy from image "
 			    "file \"" << in.fileName() << "\" to image "
 			    "file \"" << fileName() << "\" failed.  "
 			    "The files have different channel lists.");
@@ -1186,7 +1269,7 @@ OutputFile::copyPixels (InputFile &in)
     const Box2i &dataWindow = hdr.dataWindow();
 
     if (_data->missingScanLines != dataWindow.max.y - dataWindow.min.y + 1)
-	THROW (Iex::LogicExc, "Quick pixel copy from image "
+	THROW (IEX_NAMESPACE::LogicExc, "Quick pixel copy from image "
 			      "file \"" << in.fileName() << "\" to image "
 			      "file \"" << fileName() << "\" failed. "
 			      "\"" << fileName() << "\" already contains "
@@ -1203,9 +1286,9 @@ OutputFile::copyPixels (InputFile &in)
 
 	in.rawPixelData (_data->currentScanLine, pixelData, pixelDataSize);
 
-	writePixelData (_data, lineBufferMinY (_data->currentScanLine,
-				               _data->minY,
-				               _data->linesInBuffer),
+        writePixelData (_data->_streamData, _data, lineBufferMinY (_data->currentScanLine,
+                                               _data->minY,
+                                               _data->linesInBuffer),
                         pixelData, pixelDataSize);
 
 	_data->currentScanLine += (_data->lineOrder == INCREASING_Y)?
@@ -1217,12 +1300,20 @@ OutputFile::copyPixels (InputFile &in)
 
 
 void
+OutputFile::copyPixels( InputPart & in)
+{
+    copyPixels(*in.file);
+}
+
+
+
+void
 OutputFile::updatePreviewImage (const PreviewRgba newPixels[])
 {
-    Lock lock (*_data);
+    Lock lock (*_data->_streamData);
 
     if (_data->previewPosition <= 0)
-	THROW (Iex::LogicExc, "Cannot update preview image pixels. "
+	THROW (IEX_NAMESPACE::LogicExc, "Cannot update preview image pixels. "
 			      "File \"" << fileName() << "\" does not "
 			      "contain a preview image.");
 
@@ -1246,15 +1337,15 @@ OutputFile::updatePreviewImage (const PreviewRgba newPixels[])
     // preview image, and jump back to the saved file position.
     //
 
-    Int64 savedPosition = _data->os->tellp();
+    Int64 savedPosition = _data->_streamData->os->tellp();
 
     try
     {
-	_data->os->seekp (_data->previewPosition);
-	pia.writeValueTo (*_data->os, _data->version);
-	_data->os->seekp (savedPosition);
+        _data->_streamData->os->seekp (_data->previewPosition);
+	pia.writeValueTo (*_data->_streamData->os, _data->version);
+	_data->_streamData->os->seekp (savedPosition);
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
 	REPLACE_EXC (e, "Cannot update preview image pixels for "
 			"file \"" << fileName() << "\". " << e);
@@ -1266,22 +1357,22 @@ OutputFile::updatePreviewImage (const PreviewRgba newPixels[])
 void	
 OutputFile::breakScanLine  (int y, int offset, int length, char c)
 {
-    Lock lock (*_data);
+    Lock lock (*_data->_streamData);
 
     Int64 position = 
 	_data->lineOffsets[(y - _data->minY) / _data->linesInBuffer];
 
     if (!position)
-	THROW (Iex::ArgExc, "Cannot overwrite scan line " << y << ". "
+	THROW (IEX_NAMESPACE::ArgExc, "Cannot overwrite scan line " << y << ". "
 			    "The scan line has not yet been stored in "
 			    "file \"" << fileName() << "\".");
 
-    _data->currentPosition = 0;
-    _data->os->seekp (position + offset);
+    _data->_streamData->currentPosition = 0;
+    _data->_streamData->os->seekp (position + offset);
 
     for (int i = 0; i < length; ++i)
-	_data->os->write (&c, 1);
+        _data->_streamData->os->write (&c, 1);
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfOutputFile.h b/Source/OpenEXR/IlmImf/ImfOutputFile.h
index bdc317a..00f9f80 100644
--- a/Source/OpenEXR/IlmImf/ImfOutputFile.h
+++ b/Source/OpenEXR/IlmImf/ImfOutputFile.h
@@ -43,17 +43,18 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfHeader.h>
-#include <ImfFrameBuffer.h>
-#include <ImfThreading.h>
+#include "ImfHeader.h"
+#include "ImfFrameBuffer.h"
+#include "ImfThreading.h"
+#include "ImfGenericOutputFile.h"
+#include "ImfNamespace.h"
+#include "ImfForward.h"
+#include "ImfExport.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-class InputFile;
-struct PreviewRgba;
 
-
-class OutputFile
+class IMF_EXPORT OutputFile : public GenericOutputFile
 {
   public:
 
@@ -84,7 +85,7 @@ class OutputFile
     // used to write the file (see ImfThreading.h).
     //------------------------------------------------------------
 
-    OutputFile (OStream &os, const Header &header,
+    OutputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, const Header &header,
                 int numThreads = globalThreadCount());
 
 
@@ -183,6 +184,14 @@ class OutputFile
     //--------------------------------------------------------------
 
     void		copyPixels (InputFile &in);
+    
+    //-------------------------------------------------------------
+    // Shortcut to copy all pixels from an InputPart into this file
+    // - equivalent to copyPixel(InputFile &in) but for multipart files
+    //---------------------------------------------------------------
+    
+    void                copyPixels (InputPart &in);
+        
 
 
     //--------------------------------------------------------------
@@ -191,7 +200,7 @@ class OutputFile
     // updatePreviewImage() supplies a new set of pixels for the
     // preview image attribute in the file's header.  If the header
     // does not contain a preview image, updatePreviewImage() throws
-    // an Iex::LogicExc.
+    // an IEX_NAMESPACE::LogicExc.
     //
     // Note: updatePreviewImage() is necessary because images are
     // often stored in a file incrementally, a few scan lines at a
@@ -227,15 +236,28 @@ class OutputFile
 
   private:
 
+    //------------------------------------------------------------
+    // Constructor -- attaches the OutputStreamMutex to the
+    // given one from MultiPartOutputFile. Set the previewPosition
+    // and lineOffsetsPosition which have been acquired from
+    // the constructor of MultiPartOutputFile as well.
+    //------------------------------------------------------------
+    OutputFile (const OutputPartData* part);
+
     OutputFile (const OutputFile &);			// not implemented
     OutputFile & operator = (const OutputFile &);	// not implemented
 
     void		initialize (const Header &header);
 
     Data *		_data;
+
+
+    friend class MultiPartOutputFile;
+    
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfOutputPart.cpp b/Source/OpenEXR/IlmImf/ImfOutputPart.cpp
new file mode 100644
index 0000000..920b4d3
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfOutputPart.cpp
@@ -0,0 +1,105 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#include "ImfOutputPart.h"
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+OutputPart::OutputPart(MultiPartOutputFile& multiPartFile, int partNumber)
+{
+    file = multiPartFile.getOutputPart<OutputFile>(partNumber);
+}
+
+const char *
+OutputPart::fileName () const
+{
+    return file->fileName();
+}
+
+const Header &
+OutputPart::header () const
+{
+    return file->header();
+}
+
+void
+OutputPart::setFrameBuffer (const FrameBuffer &frameBuffer)
+{
+    file->setFrameBuffer(frameBuffer);
+}
+
+const FrameBuffer &
+OutputPart::frameBuffer () const
+{
+    return file->frameBuffer();
+}
+
+void
+OutputPart::writePixels (int numScanLines)
+{
+    file->writePixels(numScanLines);
+}
+
+int
+OutputPart::currentScanLine () const
+{
+    return file->currentScanLine();
+}
+
+void
+OutputPart::copyPixels (InputFile &in)
+{
+    file->copyPixels(in);
+}
+
+void
+OutputPart::copyPixels (InputPart &in)
+{
+    file->copyPixels(in);
+}
+
+void
+OutputPart::updatePreviewImage (const PreviewRgba newPixels[])
+{
+    file->updatePreviewImage(newPixels);
+}
+
+void
+OutputPart::breakScanLine  (int y, int offset, int length, char c)
+{
+    file->breakScanLine(y, offset, length, c);
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfOutputPart.h b/Source/OpenEXR/IlmImf/ImfOutputPart.h
new file mode 100644
index 0000000..41f3cf3
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfOutputPart.h
@@ -0,0 +1,77 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef IMFOUTPUTPART_H_
+#define IMFOUTPUTPART_H_
+
+#include "ImfMultiPartOutputFile.h"
+#include "ImfOutputFile.h"
+#include "ImfForward.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+
+//---------------------------------------------------------------------
+// class OutputPart:
+//
+// Same interface as OutputFile. Please refer to OutputFile.
+//---------------------------------------------------------------------
+
+class IMF_EXPORT OutputPart
+{
+    public:
+        OutputPart(MultiPartOutputFile& multiPartFile, int partNumber);
+
+        const char *        fileName () const;
+        const Header &      header () const;
+        void                setFrameBuffer (const FrameBuffer &frameBuffer);
+        const FrameBuffer & frameBuffer () const;
+        void                writePixels (int numScanLines = 1);
+        int                 currentScanLine () const;
+        void                copyPixels (InputFile &in);
+        void                copyPixels (InputPart &in);
+        
+        void                updatePreviewImage (const PreviewRgba newPixels[]);
+        void                breakScanLine  (int y, int offset, int length, char c);
+
+    private:
+        OutputFile* file;
+};
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif /* IMFOUTPUTPART_H_ */
diff --git a/Source/OpenEXR/IlmImf/ImfOutputPartData.cpp b/Source/OpenEXR/IlmImf/ImfOutputPartData.cpp
new file mode 100644
index 0000000..b517a47
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfOutputPartData.cpp
@@ -0,0 +1,52 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#include "ImfOutputPartData.h"
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+
+OutputPartData::OutputPartData(OutputStreamMutex* mutex, const Header &header,
+                               int partNumber, int numThreads, bool multipart):
+        header(header),
+        numThreads(numThreads),
+        partNumber(partNumber),
+        multipart(multipart),
+        mutex(mutex)
+{
+}
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfOutputPartData.h b/Source/OpenEXR/IlmImf/ImfOutputPartData.h
new file mode 100644
index 0000000..ac8159a
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfOutputPartData.h
@@ -0,0 +1,62 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef IMFOUTPUTPARTDATA_H_
+#define IMFOUTPUTPARTDATA_H_
+
+#include "ImfHeader.h"
+#include "ImfForward.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+struct IMF_EXPORT OutputPartData
+{
+        Header                  header;
+        Int64                   chunkOffsetTablePosition;
+        Int64                   previewPosition;
+        int                     numThreads;
+        int                     partNumber;
+	bool                    multipart;
+        OutputStreamMutex*      mutex;
+
+        OutputPartData(OutputStreamMutex* mutex, const Header &header,
+                       int partNumber, int numThreads, bool multipart);
+
+};
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif /* IMFOUTPUTPARTDATA_H_ */
diff --git a/Source/OpenEXR/IlmImf/ImfOutputStreamMutex.h b/Source/OpenEXR/IlmImf/ImfOutputStreamMutex.h
new file mode 100644
index 0000000..bf5e1c3
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfOutputStreamMutex.h
@@ -0,0 +1,70 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef IMFOUTPUTSTREAMMUTEX_H_
+#define IMFOUTPUTSTREAMMUTEX_H_
+
+#include <vector>
+
+#include "ImfIO.h"
+#include "IlmThreadMutex.h"
+#include "ImfGenericOutputFile.h"
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+using ILMTHREAD_NAMESPACE::Mutex;
+
+//
+// Used to wrap OPENEXR_IMF_INTERNAL_NAMESPACE::OStream as a Mutex.
+//
+struct OutputStreamMutex : public Mutex
+{
+        OPENEXR_IMF_INTERNAL_NAMESPACE::OStream* os;
+        Int64 currentPosition;
+
+        OutputStreamMutex()
+        {
+            os = 0;
+            currentPosition = 0;
+        }
+};
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
+
+
+#endif /* IMFOUTPUTSTREAMMUTEX_H_ */
diff --git a/Source/OpenEXR/IlmImf/ImfPartHelper.h b/Source/OpenEXR/IlmImf/ImfPartHelper.h
new file mode 100644
index 0000000..d55cc7b
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfPartHelper.h
@@ -0,0 +1,262 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2012, Weta Digital Ltd
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Weta Digital nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission. 
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+#ifndef INCLUDED_IMF_PARTHELPER_H
+#define INCLUDED_IMF_PARTHELPER_H
+
+//-----------------------------------------------------------------------------
+//
+//	Functions to help split channels into separate parts: provide a list of
+//      channels, with desired views. call SplitChannels to assign a part to each
+//      layer, or correct the name of the channel.
+//      Also can enumerate the parts in a file and list which parts channels are in
+//
+//      This is a good way to offer a 'create Multipart file' checkbox to the user in a
+//      write dialog box: Populate a list of MultiViewChannelName objects,
+//      call SplitChannels with whether single or multipart files are required.
+//      Then write the number of parts it specifies, using internal_name for the channel
+//      names in the ChannelList and FrameBuffer objects. There should be no need
+//      for different codepaths for single part and multipart files
+//
+//      Similarly, on reading a file as a MultiPartInputFile, use GetChannelsInMultiPartFile to
+//      enumerate all channels in the file, using internal_name in FrameBuffer objects
+//      to read the channel
+//   
+//
+//-----------------------------------------------------------------------------
+
+#include "ImfForward.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+#include "ImfMultiPartInputFile.h"
+#include "ImfChannelList.h"
+#include "ImfStringVectorAttribute.h"
+#include "ImfStandardAttributes.h"
+#include "ImfMultiView.h"
+
+#include <string>
+#include <map>
+#include <set>
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+struct MultiViewChannelName{
+  
+public:
+  std::string name;         ///< name of channel
+  std::string view;         ///< view for channel
+  
+  int part_number;          ///< part number: updated by SplitChannels
+  std::string internal_name;///< name used in headers: in singlepart mode, may contain viewname
+  
+  virtual ~MultiViewChannelName() {}
+    
+    //return layer for this channel, or "" if no layer
+    std::string getLayer() const 
+    {
+        std::size_t q=name.rfind('.');
+	if(  q==name.npos  )
+	{
+	    return "";
+	}
+	return name.substr(0,q);
+    
+  }
+
+  std::string getSuffix() const
+  {
+        std::size_t q=name.rfind('.');
+	if(  q==name.npos  )
+	{
+	    return name;
+	}
+	return name.substr(q+1);
+      
+  }
+  
+};
+
+
+
+//
+///\brief assigns individual channels to different parts based on their layer and view name
+///       input is an array, list, vector etc of MultiViewChannelName objects
+///       on entry, each MultiViewChannelName name/view must be set (view can be empty if not multiview)
+///
+///       if singlepart set, then on exit part_number will be zero, and internal_name will have view name inserted
+///       otherwise, each channel will be assigned to a different part based on its layer name and view name
+///
+/// @param begin pointer to first MultiViewChannelName item
+/// @param end   pointer to end of MultiViewChannelName item array
+/// @return      total number of parts required
+//
+
+template<typename T> int 
+SplitChannels(const T & begin,const T & end,bool multipart=true,const std::string & heroView="")
+{
+    if(!multipart)
+    {
+	for(T i=begin;i!=end;i++)
+	{
+	    i->part_number=0;
+	
+	    //does this have a view name set?
+	    if(i->view=="")
+	    {
+		i->internal_name=i->name;
+	    }else{
+		
+		std::string lname = i->getLayer();
+	   
+		// no layer, only non-hero views get view name in layer name
+	
+	    
+		if(lname=="")
+		{
+		    if(i->view==heroView)
+		    {
+			i->internal_name = i->name;
+		    }else{
+			i->internal_name = i->view+"."+i->name;
+		    }
+		}else{
+		    i->internal_name = lname+"."+i->view+"."+i->getSuffix();
+		}
+	    }
+	}
+	// single part created
+	return 1;
+    }else{
+	// step 1: extract individual layers and parts
+	// for each layer, enumerate which views are active
+	
+	std::map< std::string , std::set< std::string > > viewsInLayers;
+	for(T i=begin;i!=end;i++)
+	{
+	    viewsInLayers[i->getLayer()].insert(i->view);
+	}
+	
+	// step 2: assign a part number to each layer/view
+	
+	std::map< std::pair<std::string,std::string> , int > layerToPart;
+	
+	int partCount=0;
+	
+	for(std::map< std::string , std::set< std::string > >::const_iterator layer=viewsInLayers.begin();
+	    layer!=viewsInLayers.end();layer++)
+	{
+	    // if this layer has a heroView, insert that first
+	    bool layer_has_hero = layer->second.find(heroView)!=layer->second.end();
+	    if( layer_has_hero )
+	    {
+		layerToPart[ std::make_pair(layer->first,heroView) ] = partCount++;
+	    }
+	    
+	    
+	    // insert other layers which aren't the hero view
+	    for(std::set< std::string >::const_iterator view=layer->second.begin();
+		view!=layer->second.end();view++)
+	    {
+		if(*view!=heroView)
+		{
+		    layerToPart[ std::make_pair(layer->first,*view) ] = partCount++;
+		}
+	    }
+		
+	}
+	
+	// step 3: update part number of each provided channel
+	
+	for( T i=begin;i!=end;i++)
+	{
+	    i->internal_name=i->name;
+	    i->part_number = layerToPart[ std::make_pair(i->getLayer(),i->view) ];
+	}
+	
+	
+	// return number of parts created
+	return partCount;
+    }
+}
+
+//
+// populate the chans vector<MultiViewChannelName> with a list of channels in the file
+// and their corresponding part number
+//
+template<class T> void
+GetChannelsInMultiPartFile(const MultiPartInputFile & file,T & chans)
+{
+    bool has_multiview=false;
+    StringVector mview; 
+    if(file.parts()==1)
+    {
+	if(hasMultiView(file.header(0)))
+	{
+	    mview=multiView(file.header(0));
+	    has_multiview=true;
+	}
+    }
+    
+    for(int p=0;p<file.parts();p++)
+    {
+	const ChannelList & c=file.header(p).channels();
+	
+	std::string view="";
+	if(file.header(p).hasView())
+	{
+	    view=file.header(p).view();
+	}
+	for(ChannelList::ConstIterator i=c.begin();i!=c.end();i++)
+	{
+	    MultiViewChannelName m;
+            m.name=std::string(i.name());
+	    m.internal_name=m.name;
+
+	    if(has_multiview)
+	    {
+		m.view=viewFromChannelName(m.name,mview);
+		m.name=removeViewName(m.internal_name,m.view);
+	    }else{
+		m.view=view;
+	    }
+            m.part_number=p;
+	    chans.push_back(m);
+		
+	}
+    }
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif
diff --git a/Source/OpenEXR/IlmImf/ImfPartType.cpp b/Source/OpenEXR/IlmImf/ImfPartType.cpp
new file mode 100644
index 0000000..2856d44
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfPartType.cpp
@@ -0,0 +1,63 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#include <ImfPartType.h>
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+using std::string;
+
+bool isImage(const string& name)
+{
+    return (name == SCANLINEIMAGE || name == TILEDIMAGE);
+}
+
+bool isTiled(const string& name)
+{
+    return (name == TILEDIMAGE || name == DEEPTILE);
+}
+
+bool isDeepData(const string& name)
+{
+    return (name == DEEPTILE || name == DEEPSCANLINE);
+}
+
+bool isSupportedType(const string& name)
+{
+    return (name == SCANLINEIMAGE || name == TILEDIMAGE ||
+            name == DEEPSCANLINE || name == DEEPTILE);
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfPartType.h b/Source/OpenEXR/IlmImf/ImfPartType.h
new file mode 100644
index 0000000..423bce0
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfPartType.h
@@ -0,0 +1,62 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef IMFPARTTYPE_H_
+#define IMFPARTTYPE_H_
+
+#include <string>
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+
+const std::string SCANLINEIMAGE = "scanlineimage";
+const std::string TILEDIMAGE    = "tiledimage";
+const std::string DEEPSCANLINE  = "deepscanline";
+const std::string DEEPTILE      = "deeptile";
+
+IMF_EXPORT bool isImage(const std::string& name);
+
+IMF_EXPORT bool isTiled(const std::string& name);
+
+IMF_EXPORT bool isDeepData(const std::string& name);
+
+IMF_EXPORT bool isSupportedType(const std::string& name);
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+#endif /* IMFPARTTYPE_H_ */
diff --git a/Source/OpenEXR/IlmImf/ImfPixelType.h b/Source/OpenEXR/IlmImf/ImfPixelType.h
index 8f504ef..4b8005e 100644
--- a/Source/OpenEXR/IlmImf/ImfPixelType.h
+++ b/Source/OpenEXR/IlmImf/ImfPixelType.h
@@ -43,19 +43,25 @@
 //
 //-----------------------------------------------------------------------------
 
-namespace Imf {
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 enum PixelType
 {
-    UINT  = 0,		// unsigned int (32 bit)
-    HALF  = 1,		// half (16 bit floating point)
-    FLOAT = 2,		// float (32 bit floating point)
+    UINT   = 0,		// unsigned int (32 bit)
+    HALF   = 1,		// half (16 bit floating point)
+    FLOAT  = 2,		// float (32 bit floating point)
 
     NUM_PIXELTYPES	// number of different pixel types
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
+
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfPizCompressor.cpp b/Source/OpenEXR/IlmImf/ImfPizCompressor.cpp
index 9ceb8c6..46c6fba 100644
--- a/Source/OpenEXR/IlmImf/ImfPizCompressor.cpp
+++ b/Source/OpenEXR/IlmImf/ImfPizCompressor.cpp
@@ -39,29 +39,30 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfPizCompressor.h>
-#include <ImfHeader.h>
-#include <ImfChannelList.h>
-#include <ImfHuf.h>
-#include <ImfWav.h>
-#include <ImfMisc.h>
-#include <ImfCheckedArithmetic.h>
+#include "ImfPizCompressor.h"
+#include "ImfHeader.h"
+#include "ImfChannelList.h"
+#include "ImfHuf.h"
+#include "ImfWav.h"
+#include "ImfMisc.h"
+#include "ImfCheckedArithmetic.h"
 #include <ImathFun.h>
 #include <ImathBox.h>
 #include <Iex.h>
-#include <ImfIO.h>
-#include <ImfXdr.h>
-#include <ImfAutoArray.h>
+#include "ImfIO.h"
+#include "ImfXdr.h"
+#include "ImfAutoArray.h"
 #include <string.h>
 #include <assert.h>
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
-using Imath::divp;
-using Imath::modp;
-using Imath::Box2i;
-using Imath::V2i;
-using Iex::InputExc;
+using IMATH_NAMESPACE::divp;
+using IMATH_NAMESPACE::modp;
+using IMATH_NAMESPACE::Box2i;
+using IMATH_NAMESPACE::V2i;
+using IEX_NAMESPACE::InputExc;
 
 namespace {
 
@@ -267,7 +268,7 @@ PizCompressor::compress (const char *inPtr,
 int
 PizCompressor::compressTile (const char *inPtr,
 			     int inSize,
-			     Imath::Box2i range,
+			     IMATH_NAMESPACE::Box2i range,
 			     const char *&outPtr)
 {
     return compress (inPtr, inSize, range, outPtr);
@@ -291,7 +292,7 @@ PizCompressor::uncompress (const char *inPtr,
 int
 PizCompressor::uncompressTile (const char *inPtr,
 			       int inSize,
-			       Imath::Box2i range,
+			       IMATH_NAMESPACE::Box2i range,
 			       const char *&outPtr)
 {
     return uncompress (inPtr, inSize, range, outPtr);
@@ -301,7 +302,7 @@ PizCompressor::uncompressTile (const char *inPtr,
 int
 PizCompressor::compress (const char *inPtr,
 			 int inSize,
-			 Imath::Box2i range,
+			 IMATH_NAMESPACE::Box2i range,
 			 const char *&outPtr)
 {
     //
@@ -310,7 +311,7 @@ PizCompressor::compress (const char *inPtr,
     //
 
     //
-    // Special case �- empty input buffer
+    // Special case �- empty input buffer
     //
 
     if (inSize == 0)
@@ -483,7 +484,7 @@ PizCompressor::compress (const char *inPtr,
 int
 PizCompressor::uncompress (const char *inPtr,
 			   int inSize,
-			   Imath::Box2i range,
+			   IMATH_NAMESPACE::Box2i range,
 			   const char *&outPtr)
 {
     //
@@ -663,4 +664,4 @@ PizCompressor::uncompress (const char *inPtr,
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfPizCompressor.h b/Source/OpenEXR/IlmImf/ImfPizCompressor.h
index 0945a8c..fb3086b 100644
--- a/Source/OpenEXR/IlmImf/ImfPizCompressor.h
+++ b/Source/OpenEXR/IlmImf/ImfPizCompressor.h
@@ -42,14 +42,16 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfCompressor.h>
+#include "ImfCompressor.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+#include "ImfForward.h"
 
-namespace Imf {
 
-class ChannelList;
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
-class PizCompressor: public Compressor
+class IMF_EXPORT PizCompressor: public Compressor
 {
   public:
 
@@ -70,7 +72,7 @@ class PizCompressor: public Compressor
                   
     virtual int		compressTile (const char *inPtr,
 				      int inSize,
-				      Imath::Box2i range,
+				      IMATH_NAMESPACE::Box2i range,
 				      const char *&outPtr);
 
     virtual int		uncompress (const char *inPtr,
@@ -80,7 +82,7 @@ class PizCompressor: public Compressor
                     
     virtual int		uncompressTile (const char *inPtr,
 					int inSize,
-					Imath::Box2i range,
+					IMATH_NAMESPACE::Box2i range,
 					const char *&outPtr);
   private:
 
@@ -88,12 +90,12 @@ class PizCompressor: public Compressor
     
     int			compress (const char *inPtr,
 				  int inSize,
-				  Imath::Box2i range,
+				  IMATH_NAMESPACE::Box2i range,
 				  const char *&outPtr);
  
     int			uncompress (const char *inPtr,
 				    int inSize,
-				    Imath::Box2i range,
+				    IMATH_NAMESPACE::Box2i range,
 				    const char *&outPtr);
 
     int			_maxScanLineSize;
@@ -110,6 +112,6 @@ class PizCompressor: public Compressor
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfPreviewImage.cpp b/Source/OpenEXR/IlmImf/ImfPreviewImage.cpp
index d47d931..8027d0f 100644
--- a/Source/OpenEXR/IlmImf/ImfPreviewImage.cpp
+++ b/Source/OpenEXR/IlmImf/ImfPreviewImage.cpp
@@ -39,11 +39,12 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfPreviewImage.h>
-#include <ImfCheckedArithmetic.h>
+#include "ImfPreviewImage.h"
+#include "ImfCheckedArithmetic.h"
 #include "Iex.h"
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 PreviewImage::PreviewImage (unsigned int width,
@@ -100,4 +101,4 @@ PreviewImage::operator = (const PreviewImage &other)
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfPreviewImage.h b/Source/OpenEXR/IlmImf/ImfPreviewImage.h
index d016620..dcd2ebe 100644
--- a/Source/OpenEXR/IlmImf/ImfPreviewImage.h
+++ b/Source/OpenEXR/IlmImf/ImfPreviewImage.h
@@ -36,6 +36,9 @@
 #ifndef INCLUDED_IMF_PREVIEW_IMAGE_H
 #define INCLUDED_IMF_PREVIEW_IMAGE_H
 
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
 //-----------------------------------------------------------------------------
 //
 //	class PreviewImage -- a usually small, low-dynamic range image,
@@ -45,10 +48,11 @@
 //
 //-----------------------------------------------------------------------------
 
-namespace Imf {
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
-struct PreviewRgba
+struct IMF_EXPORT PreviewRgba
 {
     unsigned char	r;	// Red, green and blue components of
     unsigned char	g;	// the pixel's color; intensity is
@@ -66,7 +70,7 @@ struct PreviewRgba
 };
 
 
-class PreviewImage
+class IMF_EXPORT PreviewImage
 {
   public:
 
@@ -126,6 +130,6 @@ class PreviewImage
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfPreviewImageAttribute.cpp b/Source/OpenEXR/IlmImf/ImfPreviewImageAttribute.cpp
index 476c756..8729f88 100644
--- a/Source/OpenEXR/IlmImf/ImfPreviewImageAttribute.cpp
+++ b/Source/OpenEXR/IlmImf/ImfPreviewImageAttribute.cpp
@@ -42,8 +42,9 @@
 #include <ImfPreviewImageAttribute.h>
 
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
+using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;
 
 template <>
 const char *
@@ -55,7 +56,7 @@ PreviewImageAttribute::staticTypeName ()
 
 template <>
 void
-PreviewImageAttribute::writeValueTo (OStream &os, int version) const
+PreviewImageAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     Xdr::write <StreamIO> (os, _value.width());
     Xdr::write <StreamIO> (os, _value.height());
@@ -75,7 +76,7 @@ PreviewImageAttribute::writeValueTo (OStream &os, int version) const
 
 template <>
 void
-PreviewImageAttribute::readValueFrom (IStream &is, int size, int version)
+PreviewImageAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     int width, height;
 
@@ -99,4 +100,4 @@ PreviewImageAttribute::readValueFrom (IStream &is, int size, int version)
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT 
diff --git a/Source/OpenEXR/IlmImf/ImfPreviewImageAttribute.h b/Source/OpenEXR/IlmImf/ImfPreviewImageAttribute.h
index f08b9b7..160e409 100644
--- a/Source/OpenEXR/IlmImf/ImfPreviewImageAttribute.h
+++ b/Source/OpenEXR/IlmImf/ImfPreviewImageAttribute.h
@@ -42,30 +42,29 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfAttribute.h>
-#include <ImfPreviewImage.h>
+#include "ImfAttribute.h"
+#include "ImfPreviewImage.h"
 
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-namespace Imf {
 
-
-typedef TypedAttribute<PreviewImage> PreviewImageAttribute;
+typedef TypedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::PreviewImage> PreviewImageAttribute;
 
 template <>
+IMF_EXPORT
 const char *PreviewImageAttribute::staticTypeName ();
 
 template <>
-void PreviewImageAttribute::writeValueTo (OStream &, int) const;
+IMF_EXPORT
+void PreviewImageAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &,
+                                          int) const;
 
 template <>
-void PreviewImageAttribute::readValueFrom (IStream &, int, int);
-
+IMF_EXPORT
+void PreviewImageAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &,
+                                           int, int);
 
-} // namespace Imf
 
-// Metrowerks compiler wants the .cpp file inlined, too
-#ifdef __MWERKS__
-#include <ImfPreviewImageAttribute.cpp>
-#endif
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfPxr24Compressor.cpp b/Source/OpenEXR/IlmImf/ImfPxr24Compressor.cpp
index 8f3fb2c..6489576 100644
--- a/Source/OpenEXR/IlmImf/ImfPxr24Compressor.cpp
+++ b/Source/OpenEXR/IlmImf/ImfPxr24Compressor.cpp
@@ -62,24 +62,27 @@
 //	string of bytes is compressed with zlib.
 //
 //-----------------------------------------------------------------------------
-//#define ZLIB_WINAPI 
 
-#include <ImfPxr24Compressor.h>
-#include <ImfHeader.h>
-#include <ImfChannelList.h>
-#include <ImfMisc.h>
-#include <ImfCheckedArithmetic.h>
+#include "ImfPxr24Compressor.h"
+#include "ImfHeader.h"
+#include "ImfChannelList.h"
+#include "ImfMisc.h"
+#include "ImfCheckedArithmetic.h"
+#include "ImfNamespace.h"
+
 #include <ImathFun.h>
 #include <Iex.h>
+
 #include <half.h>
 #include <zlib.h>
 #include <assert.h>
 #include <algorithm>
 
 using namespace std;
-using namespace Imath;
+using namespace IMATH_NAMESPACE;
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
-namespace Imf {
 namespace {
 
 //
@@ -161,7 +164,7 @@ floatToFloat24 (float f)
 void
 notEnoughData ()
 {
-    throw Iex::InputExc ("Error decompressing data "
+    throw IEX_NAMESPACE::InputExc ("Error decompressing data "
 			 "(input data are shorter than expected).");
 }
 
@@ -169,7 +172,7 @@ notEnoughData ()
 void
 tooMuchData ()
 {
-    throw Iex::InputExc ("Error decompressing data "
+    throw IEX_NAMESPACE::InputExc ("Error decompressing data "
 			 "(input data are longer than expected).");
 }
 
@@ -312,7 +315,7 @@ Pxr24Compressor::compress (const char *inPtr,
 
 	    switch (c.type)
 	    {
-	      case UINT:
+	      case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
 
 		ptr[0] = tmpBufferEnd;
 		ptr[1] = ptr[0] + n;
@@ -325,7 +328,7 @@ Pxr24Compressor::compress (const char *inPtr,
 		    unsigned int pixel;
 		    char *pPtr = (char *) &pixel;
 
-		    for (int k = 0; k < sizeof (pixel); ++k)
+		    for (size_t k = 0; k < sizeof (pixel); ++k)
 			*pPtr++ = *inPtr++;
 
 		    unsigned int diff = pixel - previousPixel;
@@ -339,7 +342,7 @@ Pxr24Compressor::compress (const char *inPtr,
 
 		break;
 
-	      case HALF:
+	      case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
 
 		ptr[0] = tmpBufferEnd;
 		ptr[1] = ptr[0] + n;
@@ -361,7 +364,7 @@ Pxr24Compressor::compress (const char *inPtr,
 
 		break;
 
-	      case FLOAT:
+	      case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
 
 		ptr[0] = tmpBufferEnd;
 		ptr[1] = ptr[0] + n;
@@ -373,7 +376,7 @@ Pxr24Compressor::compress (const char *inPtr,
 		    float pixel;
 		    char *pPtr = (char *) &pixel;
 
-		    for (int k = 0; k < sizeof (pixel); ++k)
+		    for (size_t k = 0; k < sizeof (pixel); ++k)
 			*pPtr++ = *inPtr++;
 
 		    unsigned int pixel24 = floatToFloat24 (pixel);
@@ -401,7 +404,7 @@ Pxr24Compressor::compress (const char *inPtr,
 			    (const Bytef *) _tmpBuffer,
 			    tmpBufferEnd - _tmpBuffer))
     {
-	throw Iex::BaseExc ("Data compression (zlib) failed.");
+	throw IEX_NAMESPACE::BaseExc ("Data compression (zlib) failed.");
     }
 
     outPtr = _outBuffer;
@@ -428,7 +431,7 @@ Pxr24Compressor::uncompress (const char *inPtr,
 			      (const Bytef *) inPtr,
 			      inSize))
     {
-	throw Iex::InputExc ("Data decompression (zlib) failed.");
+	throw IEX_NAMESPACE::InputExc ("Data decompression (zlib) failed.");
     }
 
     int minX = range.min.x;
@@ -457,7 +460,7 @@ Pxr24Compressor::uncompress (const char *inPtr,
 
 	    switch (c.type)
 	    {
-	      case UINT:
+	      case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
 
 		ptr[0] = tmpBufferEnd;
 		ptr[1] = ptr[0] + n;
@@ -465,7 +468,7 @@ Pxr24Compressor::uncompress (const char *inPtr,
 		ptr[3] = ptr[2] + n;
 		tmpBufferEnd = ptr[3] + n;
 
-		if (tmpBufferEnd - _tmpBuffer > tmpSize)
+		if ( (uLongf)(tmpBufferEnd - _tmpBuffer) > tmpSize)
 		    notEnoughData();
 
 		for (int j = 0; j < n; ++j)
@@ -479,19 +482,19 @@ Pxr24Compressor::uncompress (const char *inPtr,
 
 		    char *pPtr = (char *) &pixel;
 
-		    for (int k = 0; k < sizeof (pixel); ++k)
+		    for (size_t k = 0; k < sizeof (pixel); ++k)
 			*writePtr++ = *pPtr++;
 		}
 
 		break;
 
-	      case HALF:
+	      case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
 
 		ptr[0] = tmpBufferEnd;
 		ptr[1] = ptr[0] + n;
 		tmpBufferEnd = ptr[1] + n;
 
-		if (tmpBufferEnd - _tmpBuffer > tmpSize)
+        if ( (uLongf)(tmpBufferEnd - _tmpBuffer) > tmpSize)
 		    notEnoughData();
 
 		for (int j = 0; j < n; ++j)
@@ -508,14 +511,14 @@ Pxr24Compressor::uncompress (const char *inPtr,
 
 		break;
 
-	      case FLOAT:
+	      case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
 
 		ptr[0] = tmpBufferEnd;
 		ptr[1] = ptr[0] + n;
 		ptr[2] = ptr[1] + n;
 		tmpBufferEnd = ptr[2] + n;
 
-		if (tmpBufferEnd - _tmpBuffer > tmpSize)
+        if ( (uLongf) (tmpBufferEnd - _tmpBuffer) > tmpSize)
 		    notEnoughData();
 
 		for (int j = 0; j < n; ++j)
@@ -527,7 +530,7 @@ Pxr24Compressor::uncompress (const char *inPtr,
 
 		    char *pPtr = (char *) &pixel;
 
-		    for (int k = 0; k < sizeof (pixel); ++k)
+		    for (size_t k = 0; k < sizeof (pixel); ++k)
 			*writePtr++ = *pPtr++;
 		}
 
@@ -540,11 +543,11 @@ Pxr24Compressor::uncompress (const char *inPtr,
 	}
     }
 
-    if (tmpBufferEnd - _tmpBuffer < tmpSize)
+    if ((uLongf) (tmpBufferEnd - _tmpBuffer) < tmpSize)
 	tooMuchData();
 
     outPtr = _outBuffer;
     return writePtr - _outBuffer;
 }
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfPxr24Compressor.h b/Source/OpenEXR/IlmImf/ImfPxr24Compressor.h
index 71e6109..026e926 100644
--- a/Source/OpenEXR/IlmImf/ImfPxr24Compressor.h
+++ b/Source/OpenEXR/IlmImf/ImfPxr24Compressor.h
@@ -40,14 +40,15 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfCompressor.h>
+#include "ImfCompressor.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+#include "ImfForward.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-class ChannelList;
 
-
-class Pxr24Compressor: public Compressor
+class IMF_EXPORT Pxr24Compressor: public Compressor
 {
   public:
 
@@ -68,7 +69,7 @@ class Pxr24Compressor: public Compressor
                   
     virtual int		compressTile (const char *inPtr,
 				      int inSize,
-				      Imath::Box2i range,
+				      IMATH_NAMESPACE::Box2i range,
 				      const char *&outPtr);
 
     virtual int		uncompress (const char *inPtr,
@@ -78,18 +79,18 @@ class Pxr24Compressor: public Compressor
                     
     virtual int		uncompressTile (const char *inPtr,
 					int inSize,
-					Imath::Box2i range,
+					IMATH_NAMESPACE::Box2i range,
 					const char *&outPtr);
   private:
 
     int			compress (const char *inPtr,
 				  int inSize,
-				  Imath::Box2i range,
+				  IMATH_NAMESPACE::Box2i range,
 				  const char *&outPtr);
  
     int			uncompress (const char *inPtr,
 				    int inSize,
-				    Imath::Box2i range,
+				    IMATH_NAMESPACE::Box2i range,
 				    const char *&outPtr);
 
     int			_maxScanLineSize;
@@ -103,6 +104,6 @@ class Pxr24Compressor: public Compressor
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfRational.cpp b/Source/OpenEXR/IlmImf/ImfRational.cpp
index ae6bc0a..fda7fc9 100644
--- a/Source/OpenEXR/IlmImf/ImfRational.cpp
+++ b/Source/OpenEXR/IlmImf/ImfRational.cpp
@@ -45,8 +45,10 @@
 #include <cmath>
 
 using namespace std;
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
-namespace Imf {
 namespace {
 
 double
@@ -122,4 +124,4 @@ Rational::Rational (double x)
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfRational.h b/Source/OpenEXR/IlmImf/ImfRational.h
index 4bad7b8..ba62b6b 100644
--- a/Source/OpenEXR/IlmImf/ImfRational.h
+++ b/Source/OpenEXR/IlmImf/ImfRational.h
@@ -36,6 +36,9 @@
 #ifndef INCLUDED_IMF_RATIONAL_H
 #define INCLUDED_IMF_RATIONAL_H
 
+#include "ImfExport.h"
+#include "ImfNamespace.h"
+
 //-----------------------------------------------------------------------------
 //
 //	Rational numbers
@@ -50,9 +53,10 @@
 //
 //-----------------------------------------------------------------------------
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
 
-class Rational
+class IMF_EXPORT Rational
 {
   public:
 
@@ -88,6 +92,7 @@ class Rational
     operator double () const {return double (n) / double (d);}
 };
 
-} // namespace Imf
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfRationalAttribute.cpp b/Source/OpenEXR/IlmImf/ImfRationalAttribute.cpp
index 757ca27..a416468 100644
--- a/Source/OpenEXR/IlmImf/ImfRationalAttribute.cpp
+++ b/Source/OpenEXR/IlmImf/ImfRationalAttribute.cpp
@@ -41,8 +41,9 @@
 #include <ImfRationalAttribute.h>
 
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
+using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;
 
 template <>
 const char *
@@ -54,7 +55,7 @@ RationalAttribute::staticTypeName ()
 
 template <>
 void
-RationalAttribute::writeValueTo (OStream &os, int version) const
+RationalAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     Xdr::write <StreamIO> (os, _value.n);
     Xdr::write <StreamIO> (os, _value.d);
@@ -63,11 +64,11 @@ RationalAttribute::writeValueTo (OStream &os, int version) const
 
 template <>
 void
-RationalAttribute::readValueFrom (IStream &is, int size, int version)
+RationalAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     Xdr::read <StreamIO> (is, _value.n);
     Xdr::read <StreamIO> (is, _value.d);
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT 
diff --git a/Source/OpenEXR/IlmImf/ImfRationalAttribute.h b/Source/OpenEXR/IlmImf/ImfRationalAttribute.h
index 862bbf4..988fe01 100644
--- a/Source/OpenEXR/IlmImf/ImfRationalAttribute.h
+++ b/Source/OpenEXR/IlmImf/ImfRationalAttribute.h
@@ -41,30 +41,29 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfAttribute.h>
-#include <ImfRational.h>
+#include "ImfAttribute.h"
+#include "ImfRational.h"
 
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-namespace Imf {
 
-
-typedef TypedAttribute<Rational> RationalAttribute;
+typedef TypedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::Rational> RationalAttribute;
 
 template <>
+IMF_EXPORT
 const char *RationalAttribute::staticTypeName ();
 
 template <>
-void RationalAttribute::writeValueTo (OStream &, int) const;
+IMF_EXPORT
+void RationalAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &,
+                                      int) const;
 
 template <>
-void RationalAttribute::readValueFrom (IStream &, int, int);
-
+IMF_EXPORT
+void RationalAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &,
+                                       int, int);
 
-} // namespace Imf
 
-// Metrowerks compiler wants the .cpp file inlined, too
-#ifdef __MWERKS__
-#include <ImfRationalAttribute.cpp>
-#endif
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfRgba.h b/Source/OpenEXR/IlmImf/ImfRgba.h
index e68cb4b..dccba9f 100644
--- a/Source/OpenEXR/IlmImf/ImfRgba.h
+++ b/Source/OpenEXR/IlmImf/ImfRgba.h
@@ -43,8 +43,9 @@
 //-----------------------------------------------------------------------------
 
 #include "half.h"
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 //
@@ -99,6 +100,10 @@ enum RgbaChannels
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
+
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfRgbaFile.cpp b/Source/OpenEXR/IlmImf/ImfRgbaFile.cpp
index 540d128..c2b604a 100644
--- a/Source/OpenEXR/IlmImf/ImfRgbaFile.cpp
+++ b/Source/OpenEXR/IlmImf/ImfRgbaFile.cpp
@@ -51,13 +51,14 @@
 #include <string.h>
 #include <algorithm>
 
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 using namespace std;
-using namespace Imath;
+using namespace IMATH_NAMESPACE;
 using namespace RgbaYca;
-using namespace IlmThread;
+using namespace ILMTHREAD_NAMESPACE;
 
 namespace {
 
@@ -357,7 +358,7 @@ RgbaOutputFile::ToYca::writePixels (int numScanLines)
 {
     if (_fbBase == 0)
     {
-	THROW (Iex::ArgExc, "No frame buffer was specified as the "
+	THROW (IEX_NAMESPACE::ArgExc, "No frame buffer was specified as the "
 			    "pixel data source for image file "
 			    "\"" << _outputFile.fileName() << "\".");
     }
@@ -570,7 +571,7 @@ RgbaOutputFile::RgbaOutputFile (const char name[],
 }
 
 
-RgbaOutputFile::RgbaOutputFile (OStream &os,
+RgbaOutputFile::RgbaOutputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
 				const Header &header,
 				RgbaChannels rgbaChannels,
                                 int numThreads):
@@ -587,11 +588,11 @@ RgbaOutputFile::RgbaOutputFile (OStream &os,
 
 
 RgbaOutputFile::RgbaOutputFile (const char name[],
-				const Imath::Box2i &displayWindow,
-				const Imath::Box2i &dataWindow,
+				const IMATH_NAMESPACE::Box2i &displayWindow,
+				const IMATH_NAMESPACE::Box2i &dataWindow,
 				RgbaChannels rgbaChannels,
 				float pixelAspectRatio,
-				const Imath::V2f screenWindowCenter,
+				const IMATH_NAMESPACE::V2f screenWindowCenter,
 				float screenWindowWidth,
 				LineOrder lineOrder,
 				Compression compression,
@@ -620,7 +621,7 @@ RgbaOutputFile::RgbaOutputFile (const char name[],
 				int height,
 				RgbaChannels rgbaChannels,
 				float pixelAspectRatio,
-				const Imath::V2f screenWindowCenter,
+				const IMATH_NAMESPACE::V2f screenWindowCenter,
 				float screenWindowWidth,
 				LineOrder lineOrder,
 				Compression compression,
@@ -722,14 +723,14 @@ RgbaOutputFile::frameBuffer () const
 }
 
 
-const Imath::Box2i &
+const IMATH_NAMESPACE::Box2i &
 RgbaOutputFile::displayWindow () const
 {
     return _outputFile->header().displayWindow();
 }
 
 
-const Imath::Box2i &
+const IMATH_NAMESPACE::Box2i &
 RgbaOutputFile::dataWindow () const
 {
     return _outputFile->header().dataWindow();
@@ -743,7 +744,7 @@ RgbaOutputFile::pixelAspectRatio () const
 }
 
 
-const Imath::V2f
+const IMATH_NAMESPACE::V2f
 RgbaOutputFile::screenWindowCenter () const
 {
     return _outputFile->header().screenWindowCenter();
@@ -970,7 +971,7 @@ RgbaInputFile::FromYca::readPixels (int scanLine)
 {
     if (_fbBase == 0)
     {
-	THROW (Iex::ArgExc, "No frame buffer was specified as the "
+	THROW (IEX_NAMESPACE::ArgExc, "No frame buffer was specified as the "
 			    "pixel data destination for image file "
 			    "\"" << _inputFile.fileName() << "\".");
     }
@@ -1173,7 +1174,7 @@ RgbaInputFile::RgbaInputFile (const char name[], int numThreads):
 }
 
 
-RgbaInputFile::RgbaInputFile (IStream &is, int numThreads):
+RgbaInputFile::RgbaInputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int numThreads):
     _inputFile (new InputFile (is, numThreads)),
     _fromYca (0),
     _channelNamePrefix ("")
@@ -1200,7 +1201,7 @@ RgbaInputFile::RgbaInputFile (const char name[],
 }
 
 
-RgbaInputFile::RgbaInputFile (IStream &is,
+RgbaInputFile::RgbaInputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
 			      const string &layerName,
 			      int numThreads)
 :
@@ -1338,14 +1339,14 @@ RgbaInputFile::frameBuffer () const
 }
 
 
-const Imath::Box2i &
+const IMATH_NAMESPACE::Box2i &
 RgbaInputFile::displayWindow () const
 {
     return _inputFile->header().displayWindow();
 }
 
 
-const Imath::Box2i &
+const IMATH_NAMESPACE::Box2i &
 RgbaInputFile::dataWindow () const
 {
     return _inputFile->header().dataWindow();
@@ -1359,7 +1360,7 @@ RgbaInputFile::pixelAspectRatio () const
 }
 
 
-const Imath::V2f	
+const IMATH_NAMESPACE::V2f	
 RgbaInputFile::screenWindowCenter () const
 {
     return _inputFile->header().screenWindowCenter();
@@ -1401,4 +1402,4 @@ RgbaInputFile::version () const
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfRgbaFile.h b/Source/OpenEXR/IlmImf/ImfRgbaFile.h
index eec67dc..10a74a0 100644
--- a/Source/OpenEXR/IlmImf/ImfRgbaFile.h
+++ b/Source/OpenEXR/IlmImf/ImfRgbaFile.h
@@ -47,27 +47,25 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfHeader.h>
-#include <ImfFrameBuffer.h>
-#include <ImfRgba.h>
+#include "ImfHeader.h"
+#include "ImfFrameBuffer.h"
+#include "ImfRgba.h"
 #include "ImathVec.h"
 #include "ImathBox.h"
 #include "half.h"
-#include <ImfThreading.h>
+#include "ImfThreading.h"
 #include <string>
+#include "ImfNamespace.h"
+#include "ImfForward.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
-class OutputFile;
-class InputFile;
-struct PreviewRgba;
-
 //
 // RGBA output file.
 //
 
-class RgbaOutputFile
+class IMF_EXPORT RgbaOutputFile
 {
   public:
 
@@ -87,7 +85,7 @@ class RgbaOutputFile
     // automatically close the file.
     //----------------------------------------------------
 
-    RgbaOutputFile (OStream &os,
+    RgbaOutputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
 		    const Header &header,
 		    RgbaChannels rgbaChannels = WRITE_RGBA,
                     int numThreads = globalThreadCount());
@@ -99,11 +97,11 @@ class RgbaOutputFile
     //----------------------------------------------------------------
 
     RgbaOutputFile (const char name[],
-		    const Imath::Box2i &displayWindow,
-		    const Imath::Box2i &dataWindow = Imath::Box2i(),
+		    const IMATH_NAMESPACE::Box2i &displayWindow,
+		    const IMATH_NAMESPACE::Box2i &dataWindow = IMATH_NAMESPACE::Box2i(),
 		    RgbaChannels rgbaChannels = WRITE_RGBA,
 		    float pixelAspectRatio = 1,
-		    const Imath::V2f screenWindowCenter = Imath::V2f (0, 0),
+		    const IMATH_NAMESPACE::V2f screenWindowCenter = IMATH_NAMESPACE::V2f (0, 0),
 		    float screenWindowWidth = 1,
 		    LineOrder lineOrder = INCREASING_Y,
 		    Compression compression = PIZ_COMPRESSION,
@@ -121,7 +119,7 @@ class RgbaOutputFile
 		    int height,
 		    RgbaChannels rgbaChannels = WRITE_RGBA,
 		    float pixelAspectRatio = 1,
-		    const Imath::V2f screenWindowCenter = Imath::V2f (0, 0),
+		    const IMATH_NAMESPACE::V2f screenWindowCenter = IMATH_NAMESPACE::V2f (0, 0),
 		    float screenWindowWidth = 1,
 		    LineOrder lineOrder = INCREASING_Y,
 		    Compression compression = PIZ_COMPRESSION,
@@ -162,10 +160,10 @@ class RgbaOutputFile
 
     const Header &		header () const;
     const FrameBuffer &		frameBuffer () const;
-    const Imath::Box2i &	displayWindow () const;
-    const Imath::Box2i &	dataWindow () const;
+    const IMATH_NAMESPACE::Box2i &	displayWindow () const;
+    const IMATH_NAMESPACE::Box2i &	dataWindow () const;
     float			pixelAspectRatio () const;
-    const Imath::V2f		screenWindowCenter () const;
+    const IMATH_NAMESPACE::V2f		screenWindowCenter () const;
     float			screenWindowWidth () const;
     LineOrder			lineOrder () const;
     Compression			compression () const;
@@ -227,7 +225,7 @@ class RgbaOutputFile
 // RGBA input file
 //
 
-class RgbaInputFile
+class IMF_EXPORT RgbaInputFile
 {
   public:
 
@@ -246,7 +244,7 @@ class RgbaInputFile
     // close the file.
     //-----------------------------------------------------------
 
-    RgbaInputFile (IStream &is, int numThreads = globalThreadCount());
+    RgbaInputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int numThreads = globalThreadCount());
 
 
     //--------------------------------------------------------------
@@ -259,7 +257,7 @@ class RgbaInputFile
 		   const std::string &layerName,
 		   int numThreads = globalThreadCount());
 
-    RgbaInputFile (IStream &is,
+    RgbaInputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
 		   const std::string &layerName,
 		   int numThreads = globalThreadCount());
 
@@ -308,10 +306,10 @@ class RgbaInputFile
 
     const Header &		header () const;
     const FrameBuffer &		frameBuffer () const;
-    const Imath::Box2i &	displayWindow () const;
-    const Imath::Box2i &	dataWindow () const;
+    const IMATH_NAMESPACE::Box2i &	displayWindow () const;
+    const IMATH_NAMESPACE::Box2i &	dataWindow () const;
     float			pixelAspectRatio () const;
-    const Imath::V2f		screenWindowCenter () const;
+    const IMATH_NAMESPACE::V2f		screenWindowCenter () const;
     float			screenWindowWidth () const;
     LineOrder			lineOrder () const;
     Compression			compression () const;
@@ -339,6 +337,10 @@ class RgbaInputFile
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
+
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfRgbaYca.cpp b/Source/OpenEXR/IlmImf/ImfRgbaYca.cpp
index 9a571de..c6212f3 100644
--- a/Source/OpenEXR/IlmImf/ImfRgbaYca.cpp
+++ b/Source/OpenEXR/IlmImf/ImfRgbaYca.cpp
@@ -46,10 +46,12 @@
 #include <assert.h>
 #include <algorithm>
 
-using namespace Imath;
+using namespace IMATH_NAMESPACE;
 using namespace std;
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
-namespace Imf {
 namespace RgbaYca {
 
 
@@ -354,7 +356,7 @@ reconstructChromaVert (int n,
 
 			 
 void
-YCAtoRGBA (const Imath::V3f &yw,
+YCAtoRGBA (const IMATH_NAMESPACE::V3f &yw,
 	   int n,
 	   const Rgba ycaIn[/*n*/],
 	   Rgba rgbaOut[/*n*/])
@@ -437,7 +439,7 @@ desaturate (const Rgba &in, float f, const V3f &yw, Rgba &out)
 
 			 
 void
-fixSaturation (const Imath::V3f &yw,
+fixSaturation (const IMATH_NAMESPACE::V3f &yw,
 	       int n,
 	       const Rgba * const rgbaIn[3],
 	       Rgba rgbaOut[/*n*/])
@@ -492,4 +494,4 @@ fixSaturation (const Imath::V3f &yw,
 }
 
 } // namespace RgbaYca
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfRgbaYca.h b/Source/OpenEXR/IlmImf/ImfRgbaYca.h
index 4a2743e..c4c6775 100644
--- a/Source/OpenEXR/IlmImf/ImfRgbaYca.h
+++ b/Source/OpenEXR/IlmImf/ImfRgbaYca.h
@@ -114,10 +114,12 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfRgba.h>
-#include <ImfChromaticities.h>
+#include "ImfRgba.h"
+#include "ImfChromaticities.h"
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-namespace Imf {
 namespace RgbaYca {
 
 
@@ -132,9 +134,10 @@ static const int N2 = N / 2;
 //
 // Convert a set of primary chromaticities into a set of weighting
 // factors for computing a pixels's luminance, Y, from R, G and B
-// 
-
-Imath::V3f computeYw (const Chromaticities &cr);
+//
+ 
+IMF_EXPORT
+IMATH_NAMESPACE::V3f computeYw (const Chromaticities &cr);
 
 
 //
@@ -148,7 +151,8 @@ Imath::V3f computeYw (const Chromaticities &cr);
 // yw is a set of RGB-to-Y weighting factors, as computed by computeYw().
 //
 
-void RGBAtoYCA (const Imath::V3f &yw,
+IMF_EXPORT
+void RGBAtoYCA (const IMATH_NAMESPACE::V3f &yw,
 		int n,
 	        bool aIsValid,
 		const Rgba rgbaIn[/*n*/],
@@ -164,6 +168,7 @@ void RGBAtoYCA (const Imath::V3f &yw,
 // "real" input pixel.
 //
 
+IMF_EXPORT
 void decimateChromaHoriz (int n,
 			  const Rgba ycaIn[/*n+N-1*/],
 			  Rgba ycaOut[/*n*/]);
@@ -174,6 +179,7 @@ void decimateChromaHoriz (int n,
 // of output pixels.
 //
 
+IMF_EXPORT
 void decimateChromaVert (int n,
 			 const Rgba * const ycaIn[N],
 			 Rgba ycaOut[/*n*/]);
@@ -185,6 +191,7 @@ void decimateChromaVert (int n,
 // are rounded to roundY and roundC bits respectively.
 //
 
+IMF_EXPORT
 void roundYCA (int n,
 	       unsigned int roundY,
 	       unsigned int roundC,
@@ -196,6 +203,7 @@ void roundYCA (int n,
 // reconstruct the missing chroma values.
 //
 
+IMF_EXPORT
 void reconstructChromaHoriz (int n,
 			     const Rgba ycaIn[/*n+N-1*/],
 			     Rgba ycaOut[/*n*/]);
@@ -205,6 +213,7 @@ void reconstructChromaHoriz (int n,
 // reconstruct chroma from the surronding N scan lines.
 //
 
+IMF_EXPORT
 void reconstructChromaVert (int n,
 			    const Rgba * const ycaIn[N],
 			    Rgba ycaOut[/*n*/]);
@@ -215,7 +224,8 @@ void reconstructChromaVert (int n,
 // yw is a set of RGB-to-Y weighting factors, as computed by computeYw().
 //
 
-void YCAtoRGBA (const Imath::V3f &yw,
+IMF_EXPORT
+void YCAtoRGBA (const IMATH_NAMESPACE::V3f &yw,
 		int n,
 		const Rgba ycaIn[/*n*/],
 		Rgba rgbaOut[/*n*/]);
@@ -237,12 +247,13 @@ void YCAtoRGBA (const Imath::V3f &yw,
 // saturation of rgbaIn[1], and stores the result in rgbaOut.
 //
 
-void fixSaturation (const Imath::V3f &yw,
+IMF_EXPORT
+void fixSaturation (const IMATH_NAMESPACE::V3f &yw,
 		    int n,
 		    const Rgba * const rgbaIn[3],
 		    Rgba rgbaOut[/*n*/]);
 
 } // namespace RgbaYca
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfRle.cpp b/Source/OpenEXR/IlmImf/ImfRle.cpp
new file mode 100644
index 0000000..7be6ac4
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfRle.cpp
@@ -0,0 +1,157 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission. 
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#include <string.h>
+#include "ImfRle.h"
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+namespace {
+
+const int MIN_RUN_LENGTH = 3;
+const int MAX_RUN_LENGTH = 127;
+
+}
+
+//
+// Compress an array of bytes, using run-length encoding,
+// and return the length of the compressed data.
+//
+
+int
+rleCompress (int inLength, const char in[], signed char out[])
+{
+    const char *inEnd = in + inLength;
+    const char *runStart = in;
+    const char *runEnd = in + 1;
+    signed char *outWrite = out;
+
+    while (runStart < inEnd)
+    {
+	while (runEnd < inEnd &&
+	       *runStart == *runEnd &&
+	       runEnd - runStart - 1 < MAX_RUN_LENGTH)
+	{
+	    ++runEnd;
+	}
+
+	if (runEnd - runStart >= MIN_RUN_LENGTH)
+	{
+	    //
+	    // Compressable run
+	    //
+
+	    *outWrite++ = (runEnd - runStart) - 1;
+	    *outWrite++ = *(signed char *) runStart;
+	    runStart = runEnd;
+	}
+	else
+	{
+	    //
+	    // Uncompressable run
+	    //
+
+	    while (runEnd < inEnd &&
+		   ((runEnd + 1 >= inEnd ||
+		     *runEnd != *(runEnd + 1)) ||
+		    (runEnd + 2 >= inEnd ||
+		     *(runEnd + 1) != *(runEnd + 2))) &&
+		   runEnd - runStart < MAX_RUN_LENGTH)
+	    {
+		++runEnd;
+	    }
+
+	    *outWrite++ = runStart - runEnd;
+
+	    while (runStart < runEnd)
+	    {
+		*outWrite++ = *(signed char *) (runStart++);
+	    }
+	}
+
+	++runEnd;
+    }
+
+    return outWrite - out;
+}
+
+
+//
+// Uncompress an array of bytes compressed with rleCompress().
+// Returns the length of the oncompressed data, or 0 if the
+// length of the uncompressed data would be more than maxLength.
+//
+
+int
+rleUncompress (int inLength, int maxLength, const signed char in[], char out[])
+{
+    char *outStart = out;
+
+    while (inLength > 0)
+    {
+	if (*in < 0)
+	{
+	    int count = -((int)*in++);
+	    inLength -= count + 1;
+
+	    if (0 > (maxLength -= count))
+		return 0;
+
+        memcpy(out, in, count);
+        out += count;
+        in  += count;
+	}
+	else
+	{
+	    int count = *in++;
+	    inLength -= 2;
+
+	    if (0 > (maxLength -= count + 1))
+		return 0;
+
+        memset(out, *(char*)in, count+1);
+        out += count+1;
+
+	    in++;
+	}
+    }
+
+    return out - outStart;
+}
+
+
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfRle.h b/Source/OpenEXR/IlmImf/ImfRle.h
new file mode 100644
index 0000000..0def336
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfRle.h
@@ -0,0 +1,63 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission. 
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef INCLUDED_IMF_RLE_H_
+#define INCLUDED_IMF_RLE_H_
+
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+//
+// Compress an array of bytes, using run-length encoding,
+// and return the length of the compressed data.
+//
+
+IMF_EXPORT
+int rleCompress (int inLength, const char in[], signed char out[]);
+
+//
+// Uncompress an array of bytes compressed with rleCompress().
+// Returns the length of the uncompressed data, or 0 if the
+// length of the uncompressed data would be more than maxLength.
+//
+
+IMF_EXPORT
+int rleUncompress (int inLength, int maxLength,
+                                 const signed char in[], char out[]);
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif
diff --git a/Source/OpenEXR/IlmImf/ImfRleCompressor.cpp b/Source/OpenEXR/IlmImf/ImfRleCompressor.cpp
index 90619b4..33914e8 100644
--- a/Source/OpenEXR/IlmImf/ImfRleCompressor.cpp
+++ b/Source/OpenEXR/IlmImf/ImfRleCompressor.cpp
@@ -40,124 +40,13 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfRleCompressor.h>
-#include <ImfCheckedArithmetic.h>
+#include "ImfRleCompressor.h"
+#include "ImfCheckedArithmetic.h"
+#include "ImfRle.h"
 #include "Iex.h"
+#include "ImfNamespace.h"
 
-namespace Imf {
-namespace {
-
-const int MIN_RUN_LENGTH = 3;
-const int MAX_RUN_LENGTH = 127;
-
-
-//
-// Compress an array of bytes, using run-length encoding,
-// and return the length of the compressed data.
-//
-
-int
-rleCompress (int inLength, const char in[], signed char out[])
-{
-    const char *inEnd = in + inLength;
-    const char *runStart = in;
-    const char *runEnd = in + 1;
-    signed char *outWrite = out;
-
-    while (runStart < inEnd)
-    {
-	while (runEnd < inEnd &&
-	       *runStart == *runEnd &&
-	       runEnd - runStart - 1 < MAX_RUN_LENGTH)
-	{
-	    ++runEnd;
-	}
-
-	if (runEnd - runStart >= MIN_RUN_LENGTH)
-	{
-	    //
-	    // Compressable run
-	    //
-
-	    *outWrite++ = (runEnd - runStart) - 1;
-	    *outWrite++ = *(signed char *) runStart;
-	    runStart = runEnd;
-	}
-	else
-	{
-	    //
-	    // Uncompressable run
-	    //
-
-	    while (runEnd < inEnd &&
-		   ((runEnd + 1 >= inEnd ||
-		     *runEnd != *(runEnd + 1)) ||
-		    (runEnd + 2 >= inEnd ||
-		     *(runEnd + 1) != *(runEnd + 2))) &&
-		   runEnd - runStart < MAX_RUN_LENGTH)
-	    {
-		++runEnd;
-	    }
-
-	    *outWrite++ = runStart - runEnd;
-
-	    while (runStart < runEnd)
-	    {
-		*outWrite++ = *(signed char *) (runStart++);
-	    }
-	}
-
-	++runEnd;
-    }
-
-    return outWrite - out;
-}
-
-
-//
-// Uncompress an array of bytes compressed with rleCompress().
-// Returns the length of the oncompressed data, or 0 if the
-// length of the uncompressed data would be more than maxLength.
-//
-
-int
-rleUncompress (int inLength, int maxLength, const signed char in[], char out[])
-{
-    char *outStart = out;
-
-    while (inLength > 0)
-    {
-	if (*in < 0)
-	{
-	    int count = -((int)*in++);
-	    inLength -= count + 1;
-
-	    if (0 > (maxLength -= count))
-		return 0;
-
-	    while (count-- > 0)
-		*out++ = *(char *) (in++);
-	}
-	else
-	{
-	    int count = *in++;
-	    inLength -= 2;
-
-	    if (0 > (maxLength -= count + 1))
-		return 0;
-
-	    while (count-- >= 0)
-		*out++ = *(char *) in;
-
-	    in++;
-	}
-    }
-
-    return out - outStart;
-}
-
-} // namespace
-
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 RleCompressor::RleCompressor (const Header &hdr, size_t maxScanLineSize):
     Compressor (hdr),
@@ -195,7 +84,7 @@ RleCompressor::compress (const char *inPtr,
 			 const char *&outPtr)
 {
     //
-    // Special case �- empty input buffer
+    // Special case �- empty input buffer
     //
 
     if (inSize == 0)
@@ -261,7 +150,7 @@ RleCompressor::uncompress (const char *inPtr,
 			   const char *&outPtr)
 {
     //
-    // Special case �- empty input buffer
+    // Special case �- empty input buffer
     //
 
     if (inSize == 0)
@@ -280,7 +169,7 @@ RleCompressor::uncompress (const char *inPtr,
 				       (const signed char *) inPtr,
 				       _tmpBuffer)))
     {
-	throw Iex::InputExc ("Data decoding (rle) failed.");
+	throw IEX_NAMESPACE::InputExc ("Data decoding (rle) failed.");
     }
 
     //
@@ -328,4 +217,4 @@ RleCompressor::uncompress (const char *inPtr,
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfRleCompressor.h b/Source/OpenEXR/IlmImf/ImfRleCompressor.h
index e272381..af3d30e 100644
--- a/Source/OpenEXR/IlmImf/ImfRleCompressor.h
+++ b/Source/OpenEXR/IlmImf/ImfRleCompressor.h
@@ -43,12 +43,13 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfCompressor.h>
+#include "ImfCompressor.h"
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
-class RleCompressor: public Compressor
+class IMF_EXPORT RleCompressor: public Compressor
 {
   public:
 
@@ -74,6 +75,6 @@ class RleCompressor: public Compressor
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfScanLineInputFile.cpp b/Source/OpenEXR/IlmImf/ImfScanLineInputFile.cpp
index c5c6465..9e13b9f 100644
--- a/Source/OpenEXR/IlmImf/ImfScanLineInputFile.cpp
+++ b/Source/OpenEXR/IlmImf/ImfScanLineInputFile.cpp
@@ -39,41 +39,50 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfScanLineInputFile.h>
-#include <ImfChannelList.h>
-#include <ImfMisc.h>
-#include <ImfStdIO.h>
-#include <ImfCompressor.h>
+#include "ImfScanLineInputFile.h"
+#include "ImfChannelList.h"
+#include "ImfMisc.h"
+#include "ImfStdIO.h"
+#include "ImfCompressor.h"
 #include "ImathBox.h"
 #include "ImathFun.h"
 #include <ImfXdr.h>
 #include <ImfConvert.h>
 #include <ImfThreading.h>
+#include <ImfPartType.h>
 #include "IlmThreadPool.h"
 #include "IlmThreadSemaphore.h"
 #include "IlmThreadMutex.h"
 #include "Iex.h"
+#include "ImfVersion.h"
+#include "ImfOptimizedPixelReading.h"
+#include "ImfNamespace.h"
+#include "ImfStandardAttributes.h"
+
+#include <algorithm>
 #include <string>
 #include <vector>
 #include <assert.h>
+#include <cstring>
 
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
-namespace Imf {
 
-using Imath::Box2i;
-using Imath::divp;
-using Imath::modp;
+using IMATH_NAMESPACE::Box2i;
+using IMATH_NAMESPACE::divp;
+using IMATH_NAMESPACE::modp;
 using std::string;
 using std::vector;
 using std::ifstream;
 using std::min;
 using std::max;
-using IlmThread::Mutex;
-using IlmThread::Lock;
-using IlmThread::Semaphore;
-using IlmThread::Task;
-using IlmThread::TaskGroup;
-using IlmThread::ThreadPool;
+using std::sort;
+using ILMTHREAD_NAMESPACE::Mutex;
+using ILMTHREAD_NAMESPACE::Lock;
+using ILMTHREAD_NAMESPACE::Semaphore;
+using ILMTHREAD_NAMESPACE::Task;
+using ILMTHREAD_NAMESPACE::TaskGroup;
+using ILMTHREAD_NAMESPACE::ThreadPool;
 
 namespace {
 
@@ -171,6 +180,29 @@ LineBuffer::~LineBuffer ()
     delete compressor;
 }
 
+/// helper struct used to detect the order that the channels are stored
+
+struct sliceOptimizationData
+{
+    const char * base;   ///< pointer to pixel data 
+    bool fill;           ///< is this channel being filled with constant, instead of read?
+    half fillValue;      ///< if filling, the value to use
+    size_t offset;       ///< position this channel will be in the read buffer, accounting for previous channels, as well as their type
+    PixelType type;      ///< type of channel
+    size_t xStride;      ///< x-stride of channel in buffer (must be set to cause channels to interleave)
+    size_t yStride;      ///< y-stride of channel in buffer (must be same in all channels, else order will change, which is bad)
+    int xSampling;       ///< channel x sampling
+    int ySampling;       ///< channel y sampling
+            
+            
+    /// we need to keep the list sorted in the order they'll be written to memory
+    bool operator<(const sliceOptimizationData& other ) const
+    {
+        return base < other.base;
+    }
+};
+    
+
 } // namespace
 
 
@@ -194,24 +226,31 @@ struct ScanLineInputFile::Data: public Mutex
     vector<size_t>	offsetInLineBuffer; // offset for each scanline in its
                                             // linebuffer
     vector<InSliceInfo>	slices;             // info about channels in file
-    IStream *		is;                 // file stream to read from
     
     vector<LineBuffer*> lineBuffers;        // each holds one line buffer
     int			linesInBuffer;      // number of scanlines each buffer
                                             // holds
     size_t		lineBufferSize;     // size of the line buffer
+    int                 partNumber;         // part number
 
-     Data (IStream *is, int numThreads);
+    bool                memoryMapped;       // if the stream is memory mapped
+    OptimizationMode    optimizationMode;   // optimizibility of the input file
+    vector<sliceOptimizationData>  optimizationData; ///< channel ordering for optimized reading
+    
+    Data (int numThreads);
     ~Data ();
     
     inline LineBuffer * getLineBuffer (int number); // hash function from line
     						    // buffer indices into our
 						    // vector of line buffers
+    
+    
 };
 
 
-ScanLineInputFile::Data::Data (IStream *is, int numThreads):
-    is (is)
+ScanLineInputFile::Data::Data (int numThreads):
+        partNumber(-1),
+        memoryMapped(false)
 {
     //
     // We need at least one lineBuffer, but if threading is used,
@@ -240,7 +279,7 @@ namespace {
 
 
 void
-reconstructLineOffsets (IStream &is,
+reconstructLineOffsets (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
 			LineOrder lineOrder,
 			vector<Int64> &lineOffsets)
 {
@@ -253,10 +292,10 @@ reconstructLineOffsets (IStream &is,
 	    Int64 lineOffset = is.tellg();
 
 	    int y;
-	    Xdr::read <StreamIO> (is, y);
+	    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, y);
 
 	    int dataSize;
-	    Xdr::read <StreamIO> (is, dataSize);
+	    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, dataSize);
 
 	    Xdr::skip <StreamIO> (is, dataSize);
 
@@ -282,14 +321,14 @@ reconstructLineOffsets (IStream &is,
 
 
 void
-readLineOffsets (IStream &is,
+readLineOffsets (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
 		 LineOrder lineOrder,
 		 vector<Int64> &lineOffsets,
 		 bool &complete)
 {
     for (unsigned int i = 0; i < lineOffsets.size(); i++)
     {
-	Xdr::read <StreamIO> (is, lineOffsets[i]);
+	OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, lineOffsets[i]);
     }
 
     complete = true;
@@ -320,7 +359,8 @@ readLineOffsets (IStream &is,
 
 
 void
-readPixelData (ScanLineInputFile::Data *ifd,
+readPixelData (InputStreamMutex *streamData,
+               ScanLineInputFile::Data *ifd,
 	       int minY,
 	       char *&buffer,
 	       int &dataSize)
@@ -334,19 +374,32 @@ readPixelData (ScanLineInputFile::Data *ifd,
     // array (hence buffer needs to be a reference to a char *).
     //
 
-    Int64 lineOffset =
-	ifd->lineOffsets[(minY - ifd->minY) / ifd->linesInBuffer];
+    int lineBufferNumber = (minY - ifd->minY) / ifd->linesInBuffer;
+
+    Int64 lineOffset = ifd->lineOffsets[lineBufferNumber];
 
     if (lineOffset == 0)
-	THROW (Iex::InputExc, "Scan line " << minY << " is missing.");
+	THROW (IEX_NAMESPACE::InputExc, "Scan line " << minY << " is missing.");
 
     //
     // Seek to the start of the scan line in the file,
     // if necessary.
     //
 
-    if (ifd->nextLineBufferMinY != minY)
-	ifd->is->seekg (lineOffset);
+    if ( !isMultiPart(ifd->version) )
+    {
+        if (ifd->nextLineBufferMinY != minY)
+            streamData->is->seekg (lineOffset);
+    }
+    else
+    {
+        //
+        // In a multi-part file, the file pointer may have been moved by
+        // other parts, so we have to ask tellg() where we are.
+        //
+        if (streamData->is->tellg() != ifd->lineOffsets[lineBufferNumber])
+            streamData->is->seekg (lineOffset);
+    }
 
     //
     // Read the data block's header.
@@ -354,23 +407,37 @@ readPixelData (ScanLineInputFile::Data *ifd,
 
     int yInFile;
 
-    Xdr::read <StreamIO> (*ifd->is, yInFile);
-    Xdr::read <StreamIO> (*ifd->is, dataSize);
+    //
+    // Read the part number when we are dealing with a multi-part file.
+    //
+    if (isMultiPart(ifd->version))
+    {
+        int partNumber;
+        OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*streamData->is, partNumber);
+        if (partNumber != ifd->partNumber)
+        {
+            THROW (IEX_NAMESPACE::ArgExc, "Unexpected part number " << partNumber
+                   << ", should be " << ifd->partNumber << ".");
+        }
+    }
+
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*streamData->is, yInFile);
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*streamData->is, dataSize);
     
     if (yInFile != minY)
-        throw Iex::InputExc ("Unexpected data block y coordinate.");
+        throw IEX_NAMESPACE::InputExc ("Unexpected data block y coordinate.");
 
     if (dataSize > (int) ifd->lineBufferSize)
-	throw Iex::InputExc ("Unexpected data block length.");
+	throw IEX_NAMESPACE::InputExc ("Unexpected data block length.");
 
     //
     // Read the pixel data.
     //
 
-    if (ifd->is->isMemoryMapped ())
-        buffer = ifd->is->readMemoryMapped (dataSize);
+    if (streamData->is->isMemoryMapped ())
+        buffer = streamData->is->readMemoryMapped (dataSize);
     else
-        ifd->is->read (buffer, dataSize);
+        streamData->is->read (buffer, dataSize);
 
     //
     // Keep track of which scan line is the next one in
@@ -379,11 +446,12 @@ readPixelData (ScanLineInputFile::Data *ifd,
     //
 
     if (ifd->lineOrder == INCREASING_Y)
-	ifd->nextLineBufferMinY = minY + ifd->linesInBuffer;
+        ifd->nextLineBufferMinY = minY + ifd->linesInBuffer;
     else
-	ifd->nextLineBufferMinY = minY - ifd->linesInBuffer;
+        ifd->nextLineBufferMinY = minY - ifd->linesInBuffer;
 }
 
+                        
 
 //
 // A LineBufferTask encapsulates the task uncompressing a set of
@@ -398,7 +466,8 @@ class LineBufferTask : public Task
                     ScanLineInputFile::Data *ifd,
 		    LineBuffer *lineBuffer,
                     int scanLineMin,
-		    int scanLineMax);
+		    int scanLineMax,
+                    OptimizationMode optimizationMode);
 
     virtual ~LineBufferTask ();
 
@@ -410,6 +479,7 @@ class LineBufferTask : public Task
     LineBuffer *		_lineBuffer;
     int				_scanLineMin;
     int				_scanLineMax;
+    OptimizationMode            _optimizationMode;
 };
 
 
@@ -418,13 +488,14 @@ LineBufferTask::LineBufferTask
      ScanLineInputFile::Data *ifd,
      LineBuffer *lineBuffer,
      int scanLineMin,
-     int scanLineMax)
+     int scanLineMax,OptimizationMode optimizationMode)
 :
     Task (group),
     _ifd (ifd),
     _lineBuffer (lineBuffer),
     _scanLineMin (scanLineMin),
-    _scanLineMax (scanLineMax)
+    _scanLineMax (scanLineMax),
+    _optimizationMode(optimizationMode)
 {
     // empty
 }
@@ -467,8 +538,10 @@ LineBufferTask::execute ()
                 _lineBuffer->format = _lineBuffer->compressor->format();
 
                 _lineBuffer->dataSize = _lineBuffer->compressor->uncompress
-                    (_lineBuffer->buffer, _lineBuffer->dataSize,
-		     _lineBuffer->minY, _lineBuffer->uncompressedData);
+                    (_lineBuffer->buffer,
+                     _lineBuffer->dataSize,
+		     _lineBuffer->minY,
+                     _lineBuffer->uncompressedData);
             }
             else
             {
@@ -587,98 +660,456 @@ LineBufferTask::execute ()
 }
 
 
-LineBufferTask *
-newLineBufferTask
+#ifdef IMF_HAVE_SSE2
+//
+// IIF format is more restricted than a perfectly generic one,
+// so it is possible to perform some optimizations.
+//
+class LineBufferTaskIIF : public Task
+{
+    public:
+        
+        LineBufferTaskIIF (TaskGroup *group,
+                           ScanLineInputFile::Data *ifd,
+                           LineBuffer *lineBuffer,
+                           int scanLineMin,
+                           int scanLineMax,
+                           OptimizationMode optimizationMode);
+                           
+        virtual ~LineBufferTaskIIF ();
+                           
+        virtual void                execute ();
+        
+        template<typename TYPE>
+        void getWritePointer (int y,
+                              unsigned short*& pOutWritePointerRight,
+                              size_t& outPixelsToCopySSE,
+                              size_t& outPixelsToCopyNormal,int bank=0) const;
+                              
+        template<typename TYPE>
+        void getWritePointerStereo (int y,
+                                    unsigned short*& outWritePointerRight,
+                                    unsigned short*& outWritePointerLeft,
+                                    size_t& outPixelsToCopySSE,
+                                    size_t& outPixelsToCopyNormal) const;
+
+    private:
+        
+        ScanLineInputFile::Data *   _ifd;
+        LineBuffer *                _lineBuffer;
+        int                         _scanLineMin;
+        int                         _scanLineMax;
+        OptimizationMode            _optimizationMode;
+  
+};
+
+LineBufferTaskIIF::LineBufferTaskIIF
     (TaskGroup *group,
      ScanLineInputFile::Data *ifd,
-     int number,
+     LineBuffer *lineBuffer,
      int scanLineMin,
-     int scanLineMax)
+     int scanLineMax,
+     OptimizationMode optimizationMode
+    )
+    :
+     Task (group),
+     _ifd (ifd),
+     _lineBuffer (lineBuffer),
+     _scanLineMin (scanLineMin),
+     _scanLineMax (scanLineMax),
+     _optimizationMode (optimizationMode)
 {
-    //
-    // Wait for a line buffer to become available, fill the line
-    // buffer with raw data from the file if necessary, and create
-    // a new LineBufferTask whose execute() method will uncompress
-    // the contents of the buffer and copy the pixels into the
-    // frame buffer.
-    //
+     /*
+     //
+     // indicates the optimised path has been taken
+     //
+     static bool could_optimise=false;
+     if(could_optimise==false)
+     {
+         std::cerr << " optimised path\n";
+         could_optimise=true;
+     }
+     */
+}
+ 
+LineBufferTaskIIF::~LineBufferTaskIIF ()
+{
+     //
+     // Signal that the line buffer is now free
+     //
+     
+     _lineBuffer->post ();
+}
+ 
+// Return 0 if we are to skip because of sampling
+// channelBank is 0 for the first group of channels, 1 for the second
+template<typename TYPE>
+void LineBufferTaskIIF::getWritePointer 
+                            (int y,
+                             unsigned short*& outWritePointerRight,
+                             size_t& outPixelsToCopySSE,
+                             size_t& outPixelsToCopyNormal,
+                             int channelBank
+                            ) const
+{
+      // Channels are saved alphabetically, so the order is B G R.
+      // The last slice (R) will give us the location of our write pointer.
+      // The only slice that we support skipping is alpha, i.e. the first one.  
+      // This does not impact the write pointer or the pixels to copy at all.
+      
+      size_t nbSlicesInBank = _ifd->optimizationData.size();
+      
+      int sizeOfSingleValue = sizeof(TYPE);
+      
+      if(_ifd->optimizationData.size()>4)
+      {
+          // there are two banks - we only copy one at once
+          nbSlicesInBank/=2;
+      }
+
+      
+      size_t firstChannel = 0;
+      if(channelBank==1)
+      {
+          firstChannel = _ifd->optimizationData.size()/2;
+      }
+      
+       sliceOptimizationData& firstSlice = _ifd->optimizationData[firstChannel];
+      
+      if (modp (y, firstSlice.ySampling) != 0)
+      {
+          outPixelsToCopySSE    = 0;
+          outPixelsToCopyNormal = 0;
+          outWritePointerRight  = 0;
+      }
+      
+      const char* linePtr1  = firstSlice.base +
+      divp (y, firstSlice.ySampling) *
+      firstSlice.yStride;
+      
+      int dMinX1 = divp (_ifd->minX, firstSlice.xSampling);
+      int dMaxX1 = divp (_ifd->maxX, firstSlice.xSampling);
+      
+      // Construct the writePtr so that we start writing at
+      // linePtr + Min offset in the line.
+      outWritePointerRight =  (unsigned short*)(linePtr1 +
+      dMinX1 * firstSlice.xStride );
+      
+      size_t bytesToCopy  = ((linePtr1 + dMaxX1 * firstSlice.xStride ) -
+      (linePtr1 + dMinX1 * firstSlice.xStride )) + 2;
+      size_t shortsToCopy = bytesToCopy / sizeOfSingleValue;
+      size_t pixelsToCopy = (shortsToCopy / nbSlicesInBank ) + 1;
+      
+      // We only support writing to SSE if we have no pixels to copy normally
+      outPixelsToCopySSE    = pixelsToCopy / 8;
+      outPixelsToCopyNormal = pixelsToCopy % 8;
+      
+}
 
-    LineBuffer *lineBuffer = ifd->getLineBuffer (number);
 
+template<typename TYPE>
+void LineBufferTaskIIF::getWritePointerStereo 
+                          (int y,
+                           unsigned short*& outWritePointerRight,
+                           unsigned short*& outWritePointerLeft,
+                           size_t& outPixelsToCopySSE,
+                           size_t& outPixelsToCopyNormal) const
+{
+   getWritePointer<TYPE>(y,outWritePointerRight,outPixelsToCopySSE,outPixelsToCopyNormal,0);
+   
+   
+   if(outWritePointerRight)
+   {
+       getWritePointer<TYPE>(y,outWritePointerLeft,outPixelsToCopySSE,outPixelsToCopyNormal,1);
+   }
+   
+}
+
+void
+LineBufferTaskIIF::execute()
+{
     try
     {
-	lineBuffer->wait ();
-	
-	if (lineBuffer->number != number)
-	{
-	    lineBuffer->minY = ifd->minY + number * ifd->linesInBuffer;
-	    lineBuffer->maxY = lineBuffer->minY + ifd->linesInBuffer - 1;
-	    
-	    lineBuffer->number = number;
-	    lineBuffer->uncompressedData = 0;
-
-	    readPixelData (ifd, lineBuffer->minY,
-			   lineBuffer->buffer,
-			   lineBuffer->dataSize);
-	}
+        //
+        // Uncompress the data, if necessary
+        //
+        
+        if (_lineBuffer->uncompressedData == 0)
+        {
+            int uncompressedSize = 0;
+            int maxY = min (_lineBuffer->maxY, _ifd->maxY);
+            
+            for (int i = _lineBuffer->minY - _ifd->minY;
+            i <= maxY - _ifd->minY;
+            ++i)
+            {
+                uncompressedSize += (int) _ifd->bytesPerLine[i];
+            }
+            
+            if (_lineBuffer->compressor &&
+                _lineBuffer->dataSize < uncompressedSize)
+            {
+                _lineBuffer->format = _lineBuffer->compressor->format();
+                
+                _lineBuffer->dataSize =
+                _lineBuffer->compressor->uncompress (_lineBuffer->buffer,
+                                                     _lineBuffer->dataSize,
+                                                     _lineBuffer->minY,
+                                                     _lineBuffer->uncompressedData);
+            }
+            else
+            {
+                //
+                // If the line is uncompressed, it's in XDR format,
+                // regardless of the compressor's output format.
+                //
+                
+                _lineBuffer->format = Compressor::XDR;
+                _lineBuffer->uncompressedData = _lineBuffer->buffer;
+            }
+        }
+        
+        int yStart, yStop, dy;
+        
+        if (_ifd->lineOrder == INCREASING_Y)
+        {
+            yStart = _scanLineMin;
+            yStop = _scanLineMax + 1;
+            dy = 1;
+        }
+        else
+        {
+            yStart = _scanLineMax;
+            yStop = _scanLineMin - 1;
+            dy = -1;
+        }
+        
+        for (int y = yStart; y != yStop; y += dy)
+        {
+            if (modp (y, _optimizationMode._ySampling) != 0)
+                continue;
+            
+            //
+            // Convert one scan line's worth of pixel data back
+            // from the machine-independent representation, and
+            // store the result in the frame buffer.
+            //
+            
+            // Set the readPtr to read at the start of uncompressedData
+            // but with an offet based on calculated array.
+            // _ifd->offsetInLineBuffer contains offsets based on which
+            // line we are currently processing.
+            // Stride will be taken into consideration later.
+                
+                
+            const char* readPtr = _lineBuffer->uncompressedData +
+            _ifd->offsetInLineBuffer[y - _ifd->minY];
+            
+            size_t pixelsToCopySSE = 0;
+            size_t pixelsToCopyNormal = 0;
+            
+            unsigned short* writePtrLeft = 0;
+            unsigned short* writePtrRight = 0;
+            
+            size_t channels = _ifd->optimizationData.size();
+       
+            if(channels>4)
+            {
+                getWritePointerStereo<half>(y, writePtrRight, writePtrLeft, pixelsToCopySSE, pixelsToCopyNormal);
+            }
+            else 
+            {
+                getWritePointer<half>(y, writePtrRight, pixelsToCopySSE, pixelsToCopyNormal);
+            }
+            
+            if (writePtrRight == 0 && pixelsToCopySSE == 0 && pixelsToCopyNormal == 0)
+            {
+                continue;
+            }
+            
+            
+            //
+            // support reading up to eight channels
+            //
+            unsigned short* readPointers[8];
+            
+            for (size_t i = 0; i < channels ; ++i)
+            {
+                readPointers[i] = (unsigned short*)readPtr + (_ifd->optimizationData[i].offset * (pixelsToCopySSE * 8 + pixelsToCopyNormal));
+            }
+            
+            //RGB only
+            if(channels==3 || channels == 6 )
+            {
+                    optimizedWriteToRGB(readPointers[0], readPointers[1], readPointers[2], writePtrRight, pixelsToCopySSE, pixelsToCopyNormal);
+                  
+                    //stereo RGB
+                    if( channels == 6)
+                    {
+                        optimizedWriteToRGB(readPointers[3], readPointers[4], readPointers[5], writePtrLeft, pixelsToCopySSE, pixelsToCopyNormal);
+                    }                
+            //RGBA
+            }else if(channels==4 || channels==8)
+            {
+                
+                if(_ifd->optimizationData[3].fill)
+                {
+                    optimizedWriteToRGBAFillA(readPointers[0], readPointers[1], readPointers[2], _ifd->optimizationData[3].fillValue.bits() , writePtrRight, pixelsToCopySSE, pixelsToCopyNormal);
+                }else{
+                    optimizedWriteToRGBA(readPointers[0], readPointers[1], readPointers[2], readPointers[3] , writePtrRight, pixelsToCopySSE, pixelsToCopyNormal);
+                }
+                
+                //stereo RGBA
+                if( channels == 8)
+                {
+                    if(_ifd->optimizationData[7].fill)
+                    {
+                        optimizedWriteToRGBAFillA(readPointers[4], readPointers[5], readPointers[6], _ifd->optimizationData[7].fillValue.bits() , writePtrLeft, pixelsToCopySSE, pixelsToCopyNormal);
+                    }else{
+                        optimizedWriteToRGBA(readPointers[4], readPointers[5], readPointers[6], readPointers[7] , writePtrLeft, pixelsToCopySSE, pixelsToCopyNormal);
+                    }
+                }
+            }
+            else {
+                throw(IEX_NAMESPACE::LogicExc("IIF mode called with incorrect channel pattern"));
+            }
+            
+            // If we are in NO_OPTIMIZATION mode, this class will never
+            // get instantiated, so no need to check for it and duplicate
+            // the code.
+        }
     }
-	catch (std::exception &e)
-	{
-	if (!lineBuffer->hasException)
-	{
-		lineBuffer->exception = e.what();
-		lineBuffer->hasException = true;
-	}
-	lineBuffer->number = -1;
-	lineBuffer->post();\
-	throw;
-	}
-	catch (...)
+    catch (std::exception &e)
     {
-	//
-	// Reading from the file caused an exception.
-	// Signal that the line buffer is free, and
-	// re-throw the exception.
-	//
-
-	lineBuffer->exception = "unrecognized exception";
-	lineBuffer->hasException = true;
-	lineBuffer->number = -1;
-	lineBuffer->post();
-	throw;
+        if (!_lineBuffer->hasException)
+        {
+            _lineBuffer->exception = e.what();
+            _lineBuffer->hasException = true;
+        }
+    }
+    catch (...)
+    {
+        if (!_lineBuffer->hasException)
+        {
+            _lineBuffer->exception = "unrecognized exception";
+            _lineBuffer->hasException = true;
+        }
     }
-    
-    scanLineMin = max (lineBuffer->minY, scanLineMin);
-    scanLineMax = min (lineBuffer->maxY, scanLineMax);
-
-    return new LineBufferTask (group, ifd, lineBuffer,
-			       scanLineMin, scanLineMax);
 }
+#endif
+
+
+Task *
+newLineBufferTask (TaskGroup *group,
+                   InputStreamMutex *streamData,
+                   ScanLineInputFile::Data *ifd,
+                   int number,
+                   int scanLineMin,
+                   int scanLineMax,
+                   OptimizationMode optimizationMode)
+{
+     //
+     // Wait for a line buffer to become available, fill the line
+     // buffer with raw data from the file if necessary, and create
+     // a new LineBufferTask whose execute() method will uncompress
+     // the contents of the buffer and copy the pixels into the
+     // frame buffer.
+     //
+     
+     LineBuffer *lineBuffer = ifd->getLineBuffer (number);
+     
+     try
+     {
+         lineBuffer->wait ();
+         
+         if (lineBuffer->number != number)
+         {
+             lineBuffer->minY = ifd->minY + number * ifd->linesInBuffer;
+             lineBuffer->maxY = lineBuffer->minY + ifd->linesInBuffer - 1;
+             
+             lineBuffer->number = number;
+             lineBuffer->uncompressedData = 0;
+             
+             readPixelData (streamData, ifd, lineBuffer->minY,
+                            lineBuffer->buffer,
+                            lineBuffer->dataSize);
+         }
+     }
+     catch (std::exception &e)
+     {
+         if (!lineBuffer->hasException)
+         {
+             lineBuffer->exception = e.what();
+             lineBuffer->hasException = true;
+         }
+         lineBuffer->number = -1;
+         lineBuffer->post();
+         throw;
+     }
+     catch (...)
+     {
+         //
+         // Reading from the file caused an exception.
+         // Signal that the line buffer is free, and
+         // re-throw the exception.
+         //
+         
+         lineBuffer->exception = "unrecognized exception";
+         lineBuffer->hasException = true;
+         lineBuffer->number = -1;
+         lineBuffer->post();
+         throw;
+     }
+     
+     scanLineMin = max (lineBuffer->minY, scanLineMin);
+     scanLineMax = min (lineBuffer->maxY, scanLineMax);
+     
+     
+     Task* retTask = 0;
+     
+#ifdef IMF_HAVE_SSE2     
+     if (optimizationMode._optimizable)
+     {
+         
+         retTask = new LineBufferTaskIIF (group, ifd, lineBuffer,
+                                          scanLineMin, scanLineMax,
+                                          optimizationMode);
+      
+     }
+     else
+#endif         
+     {
+         retTask = new LineBufferTask (group, ifd, lineBuffer,
+                                       scanLineMin, scanLineMax,
+                                       optimizationMode);
+     }
+     
+     return retTask;
+     
+ }
+ 
+  
+
 
 } // namespace
 
 
-ScanLineInputFile::ScanLineInputFile
-    (const Header &header,
-     IStream *is,
-     int numThreads)
-:
-    _data (new Data (is, numThreads))
+void ScanLineInputFile::initialize(const Header& header)
 {
     try
     {
-	_data->header = header;
+        _data->header = header;
 
-	_data->lineOrder = _data->header.lineOrder();
+        _data->lineOrder = _data->header.lineOrder();
 
-	const Box2i &dataWindow = _data->header.dataWindow();
+        const Box2i &dataWindow = _data->header.dataWindow();
 
-	_data->minX = dataWindow.min.x;
-	_data->maxX = dataWindow.max.x;
-	_data->minY = dataWindow.min.y;
-	_data->maxY = dataWindow.max.y;
+        _data->minX = dataWindow.min.x;
+        _data->maxX = dataWindow.max.x;
+        _data->minY = dataWindow.min.y;
+        _data->maxY = dataWindow.max.y;
 
-	size_t maxBytesPerLine = bytesPerLineTable (_data->header,
+        size_t maxBytesPerLine = bytesPerLineTable (_data->header,
                                                     _data->bytesPerLine);
 
         for (size_t i = 0; i < _data->lineBuffers.size(); i++)
@@ -690,43 +1121,106 @@ ScanLineInputFile::ScanLineInputFile
         }
 
         _data->linesInBuffer =
-	    numLinesInBuffer (_data->lineBuffers[0]->compressor);
+            numLinesInBuffer (_data->lineBuffers[0]->compressor);
 
         _data->lineBufferSize = maxBytesPerLine * _data->linesInBuffer;
 
-        if (!_data->is->isMemoryMapped())
+        if (!_streamData->is->isMemoryMapped())
+        {
             for (size_t i = 0; i < _data->lineBuffers.size(); i++)
-                _data->lineBuffers[i]->buffer = new char[_data->lineBufferSize];
-
-	_data->nextLineBufferMinY = _data->minY - 1;
-
-	offsetInLineBufferTable (_data->bytesPerLine,
-				 _data->linesInBuffer,
-				 _data->offsetInLineBuffer);
+            {
+                _data->lineBuffers[i]->buffer = (char *) EXRAllocAligned(_data->lineBufferSize*sizeof(char),16);
+            }
+        }
+        _data->nextLineBufferMinY = _data->minY - 1;
 
-	int lineOffsetSize = (dataWindow.max.y - dataWindow.min.y +
-			      _data->linesInBuffer) / _data->linesInBuffer;
+        offsetInLineBufferTable (_data->bytesPerLine,
+                                 _data->linesInBuffer,
+                                 _data->offsetInLineBuffer);
 
-	_data->lineOffsets.resize (lineOffsetSize);
+        int lineOffsetSize = (dataWindow.max.y - dataWindow.min.y +
+                              _data->linesInBuffer) / _data->linesInBuffer;
 
-	readLineOffsets (*_data->is,
-			 _data->lineOrder,
-			 _data->lineOffsets,
-			 _data->fileIsComplete);
+        _data->lineOffsets.resize (lineOffsetSize);
     }
     catch (...)
     {
-	delete _data;
-	throw;
+        delete _data;
+        _data=NULL;
+        throw;
     }
 }
 
 
+ScanLineInputFile::ScanLineInputFile(InputPartData* part)
+{
+    if (part->header.type() != SCANLINEIMAGE)
+        throw IEX_NAMESPACE::ArgExc("Can't build a ScanLineInputFile from a type-mismatched part.");
+
+    _data = new Data(part->numThreads);
+    _streamData = part->mutex;
+    _data->memoryMapped = _streamData->is->isMemoryMapped();
+
+    _data->version = part->version;
+
+    initialize(part->header);
+
+    _data->lineOffsets = part->chunkOffsets;
+
+    _data->partNumber = part->partNumber;
+    //
+    // (TODO) change this code later.
+    // The completeness of the file should be detected in MultiPartInputFile.
+    //
+    _data->fileIsComplete = true;
+}
+
+
+ScanLineInputFile::ScanLineInputFile
+    (const Header &header,
+     OPENEXR_IMF_INTERNAL_NAMESPACE::IStream *is,
+     int numThreads)
+:
+    _data (new Data (numThreads)),
+    _streamData (new InputStreamMutex())
+{
+    _streamData->is = is;
+    _data->memoryMapped = is->isMemoryMapped();
+
+    initialize(header);
+    
+    //
+    // (TODO) this is nasty - we need a better way of working out what type of file has been used.
+    // in any case I believe this constructor only gets used with single part files
+    // and 'version' currently only tracks multipart state, so setting to 0 (not multipart) works for us
+    //
+    
+    _data->version=0;
+    readLineOffsets (*_streamData->is,
+                     _data->lineOrder,
+                     _data->lineOffsets,
+                     _data->fileIsComplete);
+}
+
+
 ScanLineInputFile::~ScanLineInputFile ()
 {
-    if (!_data->is->isMemoryMapped())
+    if (!_data->memoryMapped)
+    {
         for (size_t i = 0; i < _data->lineBuffers.size(); i++)
-            delete [] _data->lineBuffers[i]->buffer;
+        {
+            EXRFreeAligned(_data->lineBuffers[i]->buffer);
+        }
+    }
+            
+
+    //
+    // ScanLineInputFile should never delete the stream,
+    // because it does not own the stream.
+    // We just delete the Mutex here.
+    //
+    if (_data->partNumber == -1)
+        delete _streamData;
 
     delete _data;
 }
@@ -735,7 +1229,7 @@ ScanLineInputFile::~ScanLineInputFile ()
 const char *
 ScanLineInputFile::fileName () const
 {
-    return _data->is->fileName();
+    return _streamData->is->fileName();
 }
 
 
@@ -753,18 +1247,99 @@ ScanLineInputFile::version () const
 }
 
 
-void	
-ScanLineInputFile::setFrameBuffer (const FrameBuffer &frameBuffer)
+namespace
 {
-    Lock lock (*_data);
-
+    
+    
+// returns the optimization state for the given arrangement of frame bufers
+// this assumes:
+//   both the file and framebuffer are half float data
+//   both the file and framebuffer have xSampling and ySampling=1
+//   entries in optData are sorted into their interleave order (i.e. by base address)
+//   These tests are done by SetFrameBuffer as it is building optData
+//  
+OptimizationMode
+detectOptimizationMode (const vector<sliceOptimizationData>& optData)
+{
+    OptimizationMode w;
+    
+    // need to be compiled with SSE optimisations: if not, just returns false
+#if IMF_HAVE_SSE2
+    
+    
+    // only handle reading 3,4,6 or 8 channels
+    switch(optData.size())
+    {
+        case 3 : break;
+        case 4 : break;
+        case 6 : break;
+        case 8 : break;
+        default :
+            return w;
+    }
+    
     //
-    // Check if the new frame buffer descriptor is
-    // compatible with the image file header.
+    // the point at which data switches between the primary and secondary bank
     //
+    size_t bankSize = optData.size()>4 ? optData.size()/2 : optData.size();
+    
+    for(size_t i=0;i<optData.size();i++)
+    {
+        const sliceOptimizationData& data = optData[i];
+        // can't fill anything other than channel 3 or channel 7
+        if(data.fill)
+        {
+            if(i!=3 && i!=7)
+            {
+                return w;
+            }
+        }
+        
+        // cannot have gaps in the channel layout, so the stride must be (number of channels written in the bank)*2
+        if(data.xStride !=bankSize*2)
+        {
+            return w;
+        }
+        
+        // each bank of channels must be channel interleaved: each channel base pointer must be (previous channel+2)
+        // this also means channel sampling pattern must be consistent, as must yStride
+        if(i!=0 && i!=bankSize)
+        {
+            if(data.base!=optData[i-1].base+2)
+            {
+                return w;
+            }
+        }
+        if(i!=0)
+        {
+            
+            if(data.yStride!=optData[i-1].yStride)
+            {
+                return w;
+            }
+        }
+    }
+    
 
-    const ChannelList &channels = _data->header.channels();
+    w._ySampling=optData[0].ySampling;
+    w._optimizable=true;
+    
+#endif
+
+    return w;
+}
+
+
+} // Anonymous namespace
 
+void	
+ScanLineInputFile::setFrameBuffer (const FrameBuffer &frameBuffer)
+{
+    Lock lock (*_streamData);
+
+    
+    
+    const ChannelList &channels = _data->header.channels();
     for (FrameBuffer::ConstIterator j = frameBuffer.begin();
 	 j != frameBuffer.end();
 	 ++j)
@@ -776,20 +1351,37 @@ ScanLineInputFile::setFrameBuffer (const FrameBuffer &frameBuffer)
 
 	if (i.channel().xSampling != j.slice().xSampling ||
 	    i.channel().ySampling != j.slice().ySampling)
-	    THROW (Iex::ArgExc, "X and/or y subsampling factors "
+	    THROW (IEX_NAMESPACE::ArgExc, "X and/or y subsampling factors "
 				"of \"" << i.name() << "\" channel "
 				"of input file \"" << fileName() << "\" are "
 				"not compatible with the frame buffer's "
 				"subsampling factors.");
     }
 
+    // optimization is possible if this is a little endian system
+    // and both inputs and outputs are half floats
+    // 
+    bool optimizationPossible = true;
+    
+    if (!GLOBAL_SYSTEM_LITTLE_ENDIAN)
+    {
+        optimizationPossible =false;
+    }
+    
+    vector<sliceOptimizationData> optData;
+    
+
     //
     // Initialize the slice table for readPixels().
     //
 
     vector<InSliceInfo> slices;
     ChannelList::ConstIterator i = channels.begin();
-
+    
+    // current offset of channel: pixel data starts at offset*width into the
+    // decompressed scanline buffer
+    size_t offset = 0;
+    
     for (FrameBuffer::ConstIterator j = frameBuffer.begin();
 	 j != frameBuffer.end();
 	 ++j)
@@ -812,7 +1404,20 @@ ScanLineInputFile::setFrameBuffer (const FrameBuffer &frameBuffer)
 					   false,  // fill
 					   true, // skip
 					   0.0)); // fillValue
-	    ++i;
+	    
+              switch(i.channel().type)
+              {
+                  case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF :
+                      offset++;
+                      break;
+                  case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT :
+                      offset+=2;
+                      break;
+                  case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT :
+                      offset+=2;
+                      break;
+              }
+              ++i;
 	}
 
 	bool fill = false;
@@ -839,23 +1444,88 @@ ScanLineInputFile::setFrameBuffer (const FrameBuffer &frameBuffer)
 				       false, // skip
 				       j.slice().fillValue));
 
+          if(!fill && i.channel().type!=OPENEXR_IMF_INTERNAL_NAMESPACE::HALF)
+          {
+              optimizationPossible = false;
+          }
+          
+          if(j.slice().type != OPENEXR_IMF_INTERNAL_NAMESPACE::HALF)
+          {
+              optimizationPossible = false;
+          }
+          if(j.slice().xSampling!=1 || j.slice().ySampling!=1)
+          {
+              optimizationPossible = false;
+          }
+
+          
+          if(optimizationPossible)
+          {
+              sliceOptimizationData dat;
+              dat.base = j.slice().base;
+              dat.fill = fill;
+              dat.fillValue = j.slice().fillValue;
+              dat.offset = offset;
+              dat.xStride = j.slice().xStride;
+              dat.yStride = j.slice().yStride;
+              dat.xSampling = j.slice().xSampling;
+              dat.ySampling = j.slice().ySampling;
+              optData.push_back(dat);
+          }
+          
+          if(!fill)
+          {
+              switch(i.channel().type)
+              {
+                  case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF :
+                      offset++;
+                      break;
+                  case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT :
+                      offset+=2;
+                      break;
+                  case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT :
+                      offset+=2;
+                      break;
+              }
+          }
+          
+
+          
 	if (i != channels.end() && !fill)
 	    ++i;
     }
 
+   
+   if(optimizationPossible)
+   {
+       //
+       // check optimisibility
+       // based on channel ordering and fill channel positions
+       //
+       sort(optData.begin(),optData.end());
+       _data->optimizationMode = detectOptimizationMode(optData);
+   }
+   
+   if(!optimizationPossible || _data->optimizationMode._optimizable==false)
+   {   
+       optData = vector<sliceOptimizationData>();
+       _data->optimizationMode._optimizable=false;
+   }
+    
     //
     // Store the new frame buffer.
     //
 
     _data->frameBuffer = frameBuffer;
     _data->slices = slices;
+    _data->optimizationData = optData;
 }
 
 
 const FrameBuffer &
 ScanLineInputFile::frameBuffer () const
 {
-    Lock lock (*_data);
+    Lock lock (*_streamData);
     return _data->frameBuffer;
 }
 
@@ -866,23 +1536,32 @@ ScanLineInputFile::isComplete () const
     return _data->fileIsComplete;
 }
 
+bool ScanLineInputFile::isOptimizationEnabled() const
+{
+    if (_data->slices.size() == 0)
+        throw IEX_NAMESPACE::ArgExc ("No frame buffer specified "
+        "as pixel data destination.");
+    
+    return _data->optimizationMode._optimizable;
+}
+
 
 void	
 ScanLineInputFile::readPixels (int scanLine1, int scanLine2)
 {
     try
     {
-        Lock lock (*_data);
+        Lock lock (*_streamData);
 
 	if (_data->slices.size() == 0)
-	    throw Iex::ArgExc ("No frame buffer specified "
+	    throw IEX_NAMESPACE::ArgExc ("No frame buffer specified "
 			       "as pixel data destination.");
 
 	int scanLineMin = min (scanLine1, scanLine2);
 	int scanLineMax = max (scanLine1, scanLine2);
 
 	if (scanLineMin < _data->minY || scanLineMax > _data->maxY)
-	    throw Iex::ArgExc ("Tried to read scan line outside "
+	    throw IEX_NAMESPACE::ArgExc ("Tried to read scan line outside "
 			       "the image file's data window.");
 
         //
@@ -931,9 +1610,11 @@ ScanLineInputFile::readPixels (int scanLine1, int scanLine2)
             for (int l = start; l != stop; l += dl)
             {
                 ThreadPool::addGlobalTask (newLineBufferTask (&taskGroup,
+                                                              _streamData,
                                                               _data, l,
                                                               scanLineMin,
-                                                              scanLineMax));
+                                                              scanLineMax,
+                                                              _data->optimizationMode));
             }
         
 	    //
@@ -958,7 +1639,7 @@ ScanLineInputFile::readPixels (int scanLine1, int scanLine2)
 
 	const string *exception = 0;
 
-        for (int i = 0; i < _data->lineBuffers.size(); ++i)
+        for (size_t i = 0; i < _data->lineBuffers.size(); ++i)
 	{
             LineBuffer *lineBuffer = _data->lineBuffers[i];
 
@@ -969,9 +1650,9 @@ ScanLineInputFile::readPixels (int scanLine1, int scanLine2)
 	}
 
 	if (exception)
-	    throw Iex::IoExc (*exception);
+	    throw IEX_NAMESPACE::IoExc (*exception);
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
 	REPLACE_EXC (e, "Error reading pixel data from image "
 		        "file \"" << fileName() << "\". " << e);
@@ -994,11 +1675,11 @@ ScanLineInputFile::rawPixelData (int firstScanLine,
 {
     try
     {
-        Lock lock (*_data);
+        Lock lock (*_streamData);
 
 	if (firstScanLine < _data->minY || firstScanLine > _data->maxY)
 	{
-	    throw Iex::ArgExc ("Tried to read scan line outside "
+	    throw IEX_NAMESPACE::ArgExc ("Tried to read scan line outside "
 			       "the image file's data window.");
 	}
 
@@ -1006,11 +1687,11 @@ ScanLineInputFile::rawPixelData (int firstScanLine,
 	    (firstScanLine, _data->minY, _data->linesInBuffer);
 
 	readPixelData
-	    (_data, minY, _data->lineBuffers[0]->buffer, pixelDataSize);
+	    (_streamData, _data, minY, _data->lineBuffers[0]->buffer, pixelDataSize);
 
 	pixelData = _data->lineBuffers[0]->buffer;
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
 	REPLACE_EXC (e, "Error reading pixel data from image "
 		        "file \"" << fileName() << "\". " << e);
@@ -1018,4 +1699,4 @@ ScanLineInputFile::rawPixelData (int firstScanLine,
     }
 }
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfScanLineInputFile.h b/Source/OpenEXR/IlmImf/ImfScanLineInputFile.h
index 02b36e2..4f5e2da 100644
--- a/Source/OpenEXR/IlmImf/ImfScanLineInputFile.h
+++ b/Source/OpenEXR/IlmImf/ImfScanLineInputFile.h
@@ -42,14 +42,19 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfHeader.h>
-#include <ImfFrameBuffer.h>
-#include <ImfThreading.h>
+#include "ImfHeader.h"
+#include "ImfFrameBuffer.h"
+#include "ImfThreading.h"
+#include "ImfInputStreamMutex.h"
+#include "ImfInputPartData.h"
+#include "ImfGenericInputFile.h"
+#include "ImfExport.h"
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
-class ScanLineInputFile
+class IMF_EXPORT ScanLineInputFile : public GenericInputFile
 {
   public:
 
@@ -57,7 +62,7 @@ class ScanLineInputFile
     // Constructor
     //------------
 
-    ScanLineInputFile (const Header &header, IStream *is,
+    ScanLineInputFile (const Header &header, OPENEXR_IMF_INTERNAL_NAMESPACE::IStream *is,
                        int numThreads = globalThreadCount());
 
 
@@ -122,6 +127,26 @@ class ScanLineInputFile
 
     bool		isComplete () const;
 
+    
+    
+    //---------------------------------------------------------------
+    // Check if SSE optimisation is enabled
+    //
+    // Call after setFrameBuffer() to query whether optimised file decoding
+    // is available - decode times will be faster if returns true
+    //
+    // Optimisation depends on the framebuffer channels and channel types
+    // as well as the file/part channels and channel types, as well as
+    // whether SSE2 instruction support was detected at compile time
+    //
+    // Calling before setFrameBuffer will throw an exception
+    //
+    //---------------------------------------------------------------
+    
+    bool                isOptimizationEnabled () const;
+    
+    
+    
 
     //---------------------------------------------------------------
     // Read pixel data:
@@ -164,9 +189,22 @@ class ScanLineInputFile
   private:
 
     Data *		_data;
+
+    InputStreamMutex*   _streamData;
+
+    ScanLineInputFile   (InputPartData* part);
+
+    void                initialize(const Header& header);
+
+    friend class MultiPartInputFile;
+    friend class InputFile;
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
+
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfSimd.h b/Source/OpenEXR/IlmImf/ImfSimd.h
new file mode 100644
index 0000000..09b1042
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfSimd.h
@@ -0,0 +1,59 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2012, Autodesk, Inc.
+// 
+// All rights reserved.
+//
+// Implementation of IIF-specific file format and speed optimizations 
+// provided by Innobec Technologies inc on behalf of Autodesk.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission. 
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef INCLUDED_IMF_SIMD_H
+#define INCLUDED_IMF_SIMD_H
+
+//
+// Compile time SSE detection:
+//    IMF_HAVE_SSE2 - Defined if it's safe to compile SSE2 optimizations
+//
+
+
+// GCC and Visual Studio SSE2 compiler flags
+#if defined __SSE2__ || (_MSC_VER >= 1300 && !_M_CEE_PURE)
+    #define IMF_HAVE_SSE2 1
+#endif
+
+extern "C"
+{
+#if IMF_HAVE_SSE2
+    #include <emmintrin.h>
+    #include <mmintrin.h>
+#endif
+}
+
+#endif
diff --git a/Source/OpenEXR/IlmImf/ImfStandardAttributes.cpp b/Source/OpenEXR/IlmImf/ImfStandardAttributes.cpp
index baa2c1f..df952c2 100644
--- a/Source/OpenEXR/IlmImf/ImfStandardAttributes.cpp
+++ b/Source/OpenEXR/IlmImf/ImfStandardAttributes.cpp
@@ -85,19 +85,23 @@
 	return name##Attribute(header).value();				 \
     }
 
+#include "ImfNamespace.h"
 
-namespace Imf {
+using namespace IMATH_NAMESPACE;
+using namespace std;
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
    
 IMF_STD_ATTRIBUTE_IMP (chromaticities, Chromaticities, Chromaticities)
 IMF_STD_ATTRIBUTE_IMP (whiteLuminance, WhiteLuminance, float)
-IMF_STD_ATTRIBUTE_IMP (adoptedNeutral, AdoptedNeutral, Imath::V2f)
-IMF_STD_ATTRIBUTE_IMP (renderingTransform, RenderingTransform, std::string)
-IMF_STD_ATTRIBUTE_IMP (lookModTransform, LookModTransform, std::string)
+IMF_STD_ATTRIBUTE_IMP (adoptedNeutral, AdoptedNeutral, V2f)
+IMF_STD_ATTRIBUTE_IMP (renderingTransform, RenderingTransform, string)
+IMF_STD_ATTRIBUTE_IMP (lookModTransform, LookModTransform, string)
 IMF_STD_ATTRIBUTE_IMP (xDensity, XDensity, float)
-IMF_STD_ATTRIBUTE_IMP (owner, Owner, std::string)
-IMF_STD_ATTRIBUTE_IMP (comments, Comments, std::string)
-IMF_STD_ATTRIBUTE_IMP (capDate, CapDate, std::string)
+IMF_STD_ATTRIBUTE_IMP (owner, Owner, string)
+IMF_STD_ATTRIBUTE_IMP (comments, Comments, string)
+IMF_STD_ATTRIBUTE_IMP (capDate, CapDate, string)
 IMF_STD_ATTRIBUTE_IMP (utcOffset, UtcOffset, float)
 IMF_STD_ATTRIBUTE_IMP (longitude, Longitude, float)
 IMF_STD_ATTRIBUTE_IMP (latitude, Latitude, float)
@@ -109,10 +113,13 @@ IMF_STD_ATTRIBUTE_IMP (isoSpeed, IsoSpeed, float)
 IMF_STD_ATTRIBUTE_IMP (envmap, Envmap, Envmap)
 IMF_STD_ATTRIBUTE_IMP (keyCode, KeyCode, KeyCode)
 IMF_STD_ATTRIBUTE_IMP (timeCode, TimeCode, TimeCode)
-IMF_STD_ATTRIBUTE_IMP (wrapmodes, Wrapmodes, std::string)
+IMF_STD_ATTRIBUTE_IMP (wrapmodes, Wrapmodes, string)
 IMF_STD_ATTRIBUTE_IMP (framesPerSecond, FramesPerSecond, Rational)
 IMF_STD_ATTRIBUTE_IMP (multiView, MultiView, StringVector)
-IMF_STD_ATTRIBUTE_IMP (worldToCamera, WorldToCamera, Imath::M44f)
-IMF_STD_ATTRIBUTE_IMP (worldToNDC, WorldToNDC, Imath::M44f)
+IMF_STD_ATTRIBUTE_IMP (worldToCamera, WorldToCamera, M44f)
+IMF_STD_ATTRIBUTE_IMP (worldToNDC, WorldToNDC, M44f)
+IMF_STD_ATTRIBUTE_IMP (deepImageState, DeepImageState, DeepImageState)
+IMF_STD_ATTRIBUTE_IMP (originalDataWindow, OriginalDataWindow, Box2i)
+IMF_STD_ATTRIBUTE_IMP (dwaCompressionLevel, DwaCompressionLevel, float)
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfStandardAttributes.h b/Source/OpenEXR/IlmImf/ImfStandardAttributes.h
index 38783b1..4280ac4 100644
--- a/Source/OpenEXR/IlmImf/ImfStandardAttributes.h
+++ b/Source/OpenEXR/IlmImf/ImfStandardAttributes.h
@@ -54,29 +54,35 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfHeader.h>
-#include <ImfChromaticitiesAttribute.h>
-#include <ImfEnvmapAttribute.h>
-#include <ImfFloatAttribute.h>
-#include <ImfKeyCodeAttribute.h>
-#include <ImfMatrixAttribute.h>
-#include <ImfRationalAttribute.h>
-#include <ImfStringAttribute.h>
-#include <ImfStringVectorAttribute.h>
-#include <ImfTimeCodeAttribute.h>
-#include <ImfVecAttribute.h>
-
-#define IMF_STD_ATTRIBUTE_DEF(name,suffix,type)				      \
-									      \
-    void			 add##suffix (Header &header, const type &v); \
-    bool			 has##suffix (const Header &header);	      \
-    const TypedAttribute<type> & name##Attribute (const Header &header);      \
-    TypedAttribute<type> &	 name##Attribute (Header &header);	      \
-    const type &		 name (const Header &header);		      \
-    type &			 name (Header &header);
-
-
-namespace Imf {
+#include "ImfHeader.h"
+#include "ImfBoxAttribute.h"
+#include "ImfChromaticitiesAttribute.h"
+#include "ImfEnvmapAttribute.h"
+#include "ImfDeepImageStateAttribute.h"
+#include "ImfFloatAttribute.h"
+#include "ImfKeyCodeAttribute.h"
+#include "ImfMatrixAttribute.h"
+#include "ImfRationalAttribute.h"
+#include "ImfStringAttribute.h"
+#include "ImfStringVectorAttribute.h"
+#include "ImfTimeCodeAttribute.h"
+#include "ImfVecAttribute.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
+#define IMF_STD_ATTRIBUTE_DEF(name,suffix,object)                            \
+                                                                             \
+    OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER                              \
+    IMF_EXPORT void           add##suffix (Header &header, const object &v); \
+    IMF_EXPORT bool           has##suffix (const Header &header);            \
+    IMF_EXPORT const TypedAttribute<object> &                                \
+                              name##Attribute (const Header &header);        \
+    IMF_EXPORT TypedAttribute<object> &                                      \
+                              name##Attribute (Header &header);              \
+    IMF_EXPORT const object &                                                \
+                              name (const Header &header);                   \
+    IMF_EXPORT object &       name (Header &header);                         \
+    OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT                               \
 
 //
 // chromaticities -- for RGB images, specifies the CIE (x,y)
@@ -107,7 +113,7 @@ IMF_STD_ATTRIBUTE_DEF (whiteLuminance, WhiteLuminance, float)
 // be mapped to neutral values on the display.
 //
 
-IMF_STD_ATTRIBUTE_DEF (adoptedNeutral, AdoptedNeutral, Imath::V2f)
+IMF_STD_ATTRIBUTE_DEF (adoptedNeutral, AdoptedNeutral, IMATH_NAMESPACE::V2f)
 
 
 //
@@ -316,7 +322,7 @@ IMF_STD_ATTRIBUTE_DEF (multiView , MultiView, StringVector)
 // Camera coordinate space in OpenEXR is the same as in Pixar's Renderman.
 // 
 
-IMF_STD_ATTRIBUTE_DEF (worldToCamera, WorldToCamera, Imath::M44f)
+IMF_STD_ATTRIBUTE_DEF (worldToCamera, WorldToCamera, IMATH_NAMESPACE::M44f)
 
 
 // 
@@ -336,8 +342,41 @@ IMF_STD_ATTRIBUTE_DEF (worldToCamera, WorldToCamera, Imath::M44f)
 // NDC space in OpenEXR is the same as in Pixar's Renderman.
 // 
 
-IMF_STD_ATTRIBUTE_DEF (worldToNDC, WorldToNDC, Imath::M44f)
+IMF_STD_ATTRIBUTE_DEF (worldToNDC, WorldToNDC, IMATH_NAMESPACE::M44f)
+
+
+//
+// deepImageState -- specifies whether the pixels in a deep image are
+// sorted and non-overlapping.
+//
+// Note: this attribute can be set by application code that writes a file
+// in order to tell applications that read the file whether the pixel data
+// must be cleaned up prior to image processing operations such as flattening. 
+// The IlmImf library does not verify that the attribute is consistent with
+// the actual state of the pixels.  Application software may assume that the
+// attribute is valid, as long as the software will not crash or lock up if
+// any pixels are inconsistent with the deepImageState attribute.
+//
+
+IMF_STD_ATTRIBUTE_DEF (deepImageState, DeepImageState, DeepImageState)
+
+
+//
+// originalDataWindow -- if application software crops an image, then it
+// should save the data window of the original, un-cropped image in the
+// originalDataWindow attribute.
+//
+
+IMF_STD_ATTRIBUTE_DEF
+    (originalDataWindow, OriginalDataWindow, IMATH_NAMESPACE::Box2i)
+
+
+//
+// dwaCompressionLevel -- sets the quality level for images compressed
+// with the DWAA or DWAB method.
+//
+
+IMF_STD_ATTRIBUTE_DEF (dwaCompressionLevel, DwaCompressionLevel, float)
 
-} // namespace Imf
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfStdIO.cpp b/Source/OpenEXR/IlmImf/ImfStdIO.cpp
index 5028410..1839a94 100644
--- a/Source/OpenEXR/IlmImf/ImfStdIO.cpp
+++ b/Source/OpenEXR/IlmImf/ImfStdIO.cpp
@@ -45,8 +45,10 @@
 #include <errno.h>
 
 using namespace std;
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
-namespace Imf {
 namespace {
 
 void
@@ -62,11 +64,11 @@ checkError (istream &is, streamsize expected = 0)
     if (!is)
     {
 	if (errno)
-	    Iex::throwErrnoExc();
+	    IEX_NAMESPACE::throwErrnoExc();
 
 	if (is.gcount() < expected) 
 	{
-		THROW (Iex::InputExc, "Early end of file: read " << is.gcount() 
+		THROW (IEX_NAMESPACE::InputExc, "Early end of file: read " << is.gcount() 
 			<< " out of " << expected << " requested bytes.");
 	}
 	return false;
@@ -82,9 +84,9 @@ checkError (ostream &os)
     if (!os)
     {
 	if (errno)
-	    Iex::throwErrnoExc();
+	    IEX_NAMESPACE::throwErrnoExc();
 
-	throw Iex::ErrnoExc ("File output failed.");
+	throw IEX_NAMESPACE::ErrnoExc ("File output failed.");
     }
 }
 
@@ -92,20 +94,20 @@ checkError (ostream &os)
 
 
 StdIFStream::StdIFStream (const char fileName[]):
-    IStream (fileName),
+    OPENEXR_IMF_INTERNAL_NAMESPACE::IStream (fileName),
     _is (new ifstream (fileName, ios_base::binary)),
     _deleteStream (true)
 {
     if (!*_is)
     {
 	delete _is;
-	Iex::throwErrnoExc();
+	IEX_NAMESPACE::throwErrnoExc();
     }
 }
 
     
 StdIFStream::StdIFStream (ifstream &is, const char fileName[]):
-    IStream (fileName),
+    OPENEXR_IMF_INTERNAL_NAMESPACE::IStream (fileName),
     _is (&is),
     _deleteStream (false)
 {
@@ -124,7 +126,7 @@ bool
 StdIFStream::read (char c[/*n*/], int n)
 {
     if (!*_is)
-        throw Iex::InputExc ("Unexpected end of file.");
+        throw IEX_NAMESPACE::InputExc ("Unexpected end of file.");
 
     clearError();
     _is->read (c, n);
@@ -155,20 +157,20 @@ StdIFStream::clear ()
 
 
 StdOFStream::StdOFStream (const char fileName[]):
-    OStream (fileName),
+    OPENEXR_IMF_INTERNAL_NAMESPACE::OStream (fileName),
     _os (new ofstream (fileName, ios_base::binary)),
     _deleteStream (true)
 {
     if (!*_os)
     {
 	delete _os;
-	Iex::throwErrnoExc();
+	IEX_NAMESPACE::throwErrnoExc();
     }
 }
 
 
 StdOFStream::StdOFStream (ofstream &os, const char fileName[]):
-    OStream (fileName),
+    OPENEXR_IMF_INTERNAL_NAMESPACE::OStream (fileName),
     _os (&os),
     _deleteStream (false)
 {
@@ -207,7 +209,7 @@ StdOFStream::seekp (Int64 pos)
 }
 
 
-StdOSStream::StdOSStream (): OStream ("(string)")
+StdOSStream::StdOSStream (): OPENEXR_IMF_INTERNAL_NAMESPACE::OStream ("(string)")
 {
     // empty
 }
@@ -237,4 +239,4 @@ StdOSStream::seekp (Int64 pos)
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfStdIO.h b/Source/OpenEXR/IlmImf/ImfStdIO.h
index 0137b45..56ea4e2 100644
--- a/Source/OpenEXR/IlmImf/ImfStdIO.h
+++ b/Source/OpenEXR/IlmImf/ImfStdIO.h
@@ -43,18 +43,22 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfIO.h>
+#include "ImfIO.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
 #include <fstream>
 #include <sstream>
 
-namespace Imf {
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 //-------------------------------------------
 // class StdIFStream -- an implementation of
-// class IStream based on class std::ifstream
+// class OPENEXR_IMF_INTERNAL_NAMESPACE::IStream based on class std::ifstream
 //-------------------------------------------
 
-class StdIFStream: public IStream
+class IMF_EXPORT StdIFStream: public OPENEXR_IMF_INTERNAL_NAMESPACE::IStream
 {
   public:
 
@@ -91,10 +95,10 @@ class StdIFStream: public IStream
 
 //-------------------------------------------
 // class StdOFStream -- an implementation of
-// class OStream based on class std::ofstream
+// class OPENEXR_IMF_INTERNAL_NAMESPACE::OStream based on class std::ofstream
 //-------------------------------------------
 
-class StdOFStream: public OStream
+class IMF_EXPORT StdOFStream: public OPENEXR_IMF_INTERNAL_NAMESPACE::OStream
 {
   public:
 
@@ -130,10 +134,10 @@ class StdOFStream: public OStream
 
 //------------------------------------------------
 // class StdOSStream -- an implementation of class
-// OStream, based on class std::ostringstream
+// OPENEXR_IMF_INTERNAL_NAMESPACE::OStream, based on class std::ostringstream
 //------------------------------------------------
 
-class StdOSStream: public OStream
+class IMF_EXPORT StdOSStream: public OPENEXR_IMF_INTERNAL_NAMESPACE::OStream
 {
   public:
 
@@ -151,6 +155,6 @@ class StdOSStream: public OStream
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfStringAttribute.cpp b/Source/OpenEXR/IlmImf/ImfStringAttribute.cpp
index 6f6ca94..cd241ba 100644
--- a/Source/OpenEXR/IlmImf/ImfStringAttribute.cpp
+++ b/Source/OpenEXR/IlmImf/ImfStringAttribute.cpp
@@ -43,8 +43,9 @@
 #include <ImfStringAttribute.h>
 
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
+using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;
 
 template <>
 const char *
@@ -56,7 +57,7 @@ StringAttribute::staticTypeName ()
 
 template <>
 void
-StringAttribute::writeValueTo (OStream &os, int version) const
+StringAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     int size = _value.size();
 
@@ -67,7 +68,7 @@ StringAttribute::writeValueTo (OStream &os, int version) const
 
 template <>
 void
-StringAttribute::readValueFrom (IStream &is, int size, int version)
+StringAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     _value.resize (size);
 
@@ -76,4 +77,4 @@ StringAttribute::readValueFrom (IStream &is, int size, int version)
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT 
diff --git a/Source/OpenEXR/IlmImf/ImfStringAttribute.h b/Source/OpenEXR/IlmImf/ImfStringAttribute.h
index 3ce76eb..f5d62d7 100644
--- a/Source/OpenEXR/IlmImf/ImfStringAttribute.h
+++ b/Source/OpenEXR/IlmImf/ImfStringAttribute.h
@@ -43,24 +43,29 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfAttribute.h>
+#include "ImfAttribute.h"
 #include <string>
 
-
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 typedef TypedAttribute<std::string> StringAttribute;
-template <> const char *StringAttribute::staticTypeName ();
-template <> void StringAttribute::writeValueTo (OStream &, int) const;
-template <> void StringAttribute::readValueFrom (IStream &, int, int);
 
+template <>
+IMF_EXPORT
+const char *StringAttribute::staticTypeName ();
 
-} // namespace Imf
+template <>
+IMF_EXPORT
+void StringAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &,
+                                    int) const;
 
-// Metrowerks compiler wants the .cpp file inlined, too
-#ifdef __MWERKS__
-#include <ImfStringAttribute.cpp>
-#endif
+template <>
+IMF_EXPORT
+void StringAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &,
+                                     int, int);
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfStringVectorAttribute.cpp b/Source/OpenEXR/IlmImf/ImfStringVectorAttribute.cpp
index 76b21be..88fdf8e 100644
--- a/Source/OpenEXR/IlmImf/ImfStringVectorAttribute.cpp
+++ b/Source/OpenEXR/IlmImf/ImfStringVectorAttribute.cpp
@@ -32,17 +32,19 @@
 ///////////////////////////////////////////////////////////////////////////
 
 
-
 //-----------------------------------------------------------------------------
 //
-//	class StringAttribute
+//	class StringVectorAttribute
 //
 //-----------------------------------------------------------------------------
 
 #include <ImfStringVectorAttribute.h>
 
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+
+using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;
 
 
 template <>
@@ -55,7 +57,7 @@ StringVectorAttribute::staticTypeName ()
 
 template <>
 void
-StringVectorAttribute::writeValueTo (OStream &os, int version) const
+StringVectorAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     int size = _value.size();
 
@@ -70,7 +72,7 @@ StringVectorAttribute::writeValueTo (OStream &os, int version) const
 
 template <>
 void
-StringVectorAttribute::readValueFrom (IStream &is, int size, int version)
+StringVectorAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     int read = 0;
 
@@ -83,7 +85,11 @@ StringVectorAttribute::readValueFrom (IStream &is, int size, int version)
        std::string str;
        str.resize (strSize);
   
-       Xdr::read<StreamIO> (is, &str[0], strSize);
+       if( strSize>0 )
+       {
+           Xdr::read<StreamIO> (is, &str[0], strSize);
+       }
+       
        read += strSize;
 
        _value.push_back (str);
@@ -91,4 +97,4 @@ StringVectorAttribute::readValueFrom (IStream &is, int size, int version)
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT 
diff --git a/Source/OpenEXR/IlmImf/ImfStringVectorAttribute.h b/Source/OpenEXR/IlmImf/ImfStringVectorAttribute.h
index 752a486..d13ef96 100644
--- a/Source/OpenEXR/IlmImf/ImfStringVectorAttribute.h
+++ b/Source/OpenEXR/IlmImf/ImfStringVectorAttribute.h
@@ -42,25 +42,33 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfAttribute.h>
+#include "ImfAttribute.h"
+#include "ImfNamespace.h"
+
 #include <string>
 #include <vector>
 
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 typedef std::vector<std::string> StringVector;
-typedef TypedAttribute<StringVector> StringVectorAttribute;
-template <> const char *StringVectorAttribute::staticTypeName ();
-template <> void StringVectorAttribute::writeValueTo (OStream &, int) const;
-template <> void StringVectorAttribute::readValueFrom (IStream &, int, int);
+typedef TypedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::StringVector> StringVectorAttribute;
 
+template <>
+IMF_EXPORT
+const char *StringVectorAttribute::staticTypeName ();
 
-} // namespace Imf
+template <>
+IMF_EXPORT
+void StringVectorAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &,
+                                          int) const;
 
-// Metrowerks compiler wants the .cpp file inlined, too
-#ifdef __MWERKS__
-#include <ImfStringVectorAttribute.cpp>
-#endif
+template <>
+IMF_EXPORT
+void StringVectorAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &,
+                                           int, int);
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfSystemSpecific.cpp b/Source/OpenEXR/IlmImf/ImfSystemSpecific.cpp
new file mode 100644
index 0000000..d10f9bc
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfSystemSpecific.cpp
@@ -0,0 +1,129 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2009-2014 DreamWorks Animation LLC. 
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of DreamWorks Animation nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#include "ImfSimd.h"
+#include "ImfSystemSpecific.h"
+#include "ImfNamespace.h"
+#include "OpenEXRConfig.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+namespace {
+#if defined(IMF_HAVE_SSE2) &&  defined(__GNUC__)
+
+    // Helper functions for gcc + SSE enabled
+    void cpuid(int n, int &eax, int &ebx, int &ecx, int &edx)
+    {
+        __asm__ __volatile__ (
+            "cpuid"
+            : /* Output  */ "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) 
+            : /* Input   */ "a"(n)
+            : /* Clobber */);
+    }
+
+#else // IMF_HAVE_SSE2 && __GNUC__
+
+    // Helper functions for generic compiler - all disabled
+    void cpuid(int n, int &eax, int &ebx, int &ecx, int &edx)
+    {
+        eax = ebx = ecx = edx = 0;
+    }
+
+#endif // IMF_HAVE_SSE2 && __GNUC__
+
+
+#ifdef OPENEXR_IMF_HAVE_GCC_INLINE_ASM_AVX
+
+    void xgetbv(int n, int &eax, int &edx)
+    {
+        __asm__ __volatile__ (
+            "xgetbv"
+            : /* Output  */ "=a"(eax), "=d"(edx) 
+            : /* Input   */ "c"(n)
+            : /* Clobber */);
+    }
+
+#else //  OPENEXR_IMF_HAVE_GCC_INLINE_ASM_AVX
+
+    void xgetbv(int n, int &eax, int &edx)
+    {
+        eax = edx = 0;
+    }
+
+#endif //  OPENEXR_IMF_HAVE_GCC_INLINE_ASM_AVX
+
+} // namespace 
+
+CpuId::CpuId():
+    sse2(false), 
+    sse3(false), 
+    ssse3(false),
+    sse4_1(false), 
+    sse4_2(false), 
+    avx(false), 
+    f16c(false)
+{
+    bool osxsave = false;
+    int  max     = 0;
+    int  eax, ebx, ecx, edx;
+
+    cpuid(0, max, ebx, ecx, edx);
+    if (max > 0)
+    {
+        cpuid(1, eax, ebx, ecx, edx);
+        sse2    = ( edx & (1<<26) );
+        sse3    = ( ecx & (1<< 0) );
+        ssse3   = ( ecx & (1<< 9) );
+        sse4_1  = ( ecx & (1<<19) );
+        sse4_2  = ( ecx & (1<<20) );
+        osxsave = ( ecx & (1<<27) );
+        avx     = ( ecx & (1<<28) );
+        f16c    = ( ecx & (1<<29) );
+
+        if (!osxsave)
+        {
+            avx = f16c = false;
+        }
+        else
+        {
+            xgetbv(0, eax, edx);
+            // eax bit 1 - SSE managed, bit 2 - AVX managed
+            if ((eax & 6) != 6)
+            {
+                avx = f16c = false;
+            }
+        }
+    }
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfSystemSpecific.h b/Source/OpenEXR/IlmImf/ImfSystemSpecific.h
new file mode 100644
index 0000000..c0261a7
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfSystemSpecific.h
@@ -0,0 +1,172 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2012, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission. 
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef INCLUDED_IMF_COMPILER_SPECIFIC_H
+#define INCLUDED_IMF_COMPILER_SPECIFIC_H
+
+#include <ImfNamespace.h>
+#include <ImfSimd.h>
+#include <stdlib.h>
+#include "ImfExport.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+
+static unsigned long  systemEndianCheckValue   = 0x12345678;
+static unsigned long* systemEndianCheckPointer = &systemEndianCheckValue;
+
+// EXR files are little endian - check processor architecture is too
+// (optimisation currently not supported for big endian machines)
+static bool GLOBAL_SYSTEM_LITTLE_ENDIAN =
+        (*(unsigned char*)systemEndianCheckPointer == 0x78 ? true : false);
+
+
+#ifdef IMF_HAVE_SSE2
+
+#ifdef __GNUC__
+// Causes issues on certain gcc versions
+//#define EXR_FORCEINLINE inline __attribute__((always_inline))
+#define EXR_FORCEINLINE inline
+#define EXR_RESTRICT __restrict
+
+static void* EXRAllocAligned(size_t size, size_t alignment)
+{
+    void* ptr = 0;
+    posix_memalign(&ptr, alignment, size);
+    return ptr;
+}
+
+
+static void EXRFreeAligned(void* ptr)
+{
+    free(ptr);
+}
+
+#elif defined _MSC_VER
+
+#define EXR_FORCEINLINE __forceinline
+#define EXR_RESTRICT __restrict
+
+static void* EXRAllocAligned(size_t size, size_t alignment)
+{
+    return _aligned_malloc(size, alignment);
+}
+
+
+static void EXRFreeAligned(void* ptr)
+{
+    _aligned_free(ptr);
+}
+
+#elif defined (__INTEL_COMPILER) || \
+        defined(__ICL) || \
+        defined(__ICC) || \
+        defined(__ECC)
+
+#define EXR_FORCEINLINE inline
+#define EXR_RESTRICT restrict
+
+static void* EXRAllocAligned(size_t size, size_t alignment)
+{
+    return _mm_malloc(size, alignment);
+}
+
+
+static void EXRFreeAligned(void* ptr)
+{
+    _mm_free(ptr);
+}
+
+#else
+
+// generic compiler
+#define EXR_FORCEINLINE inline
+#define EXR_RESTRICT
+
+static void* EXRAllocAligned(size_t size, size_t alignment)
+{
+    return malloc(size);
+}
+
+
+static void EXRFreeAligned(void* ptr)
+{
+    free(ptr);
+}
+
+#endif // compiler switch
+
+
+#else // IMF_HAVE_SSE2
+
+
+#define EXR_FORCEINLINE inline
+#define EXR_RESTRICT
+
+static void* EXRAllocAligned(size_t size, size_t alignment)
+{
+    return malloc(size);
+}
+
+
+static void EXRFreeAligned(void* ptr)
+{
+    free(ptr);
+}
+
+
+#endif  // IMF_HAVE_SSE2
+
+// 
+// Simple CPUID based runtime detection of various capabilities
+//
+class IMF_EXPORT CpuId
+{
+    public:
+        CpuId();
+
+        bool sse2;
+        bool sse3;
+        bool ssse3;
+        bool sse4_1;
+        bool sse4_2;
+        bool avx;
+        bool f16c;
+};
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+#endif //include guard
diff --git a/Source/OpenEXR/IlmImf/ImfTestFile.cpp b/Source/OpenEXR/IlmImf/ImfTestFile.cpp
index 1bf7872..198a4d5 100644
--- a/Source/OpenEXR/IlmImf/ImfTestFile.cpp
+++ b/Source/OpenEXR/IlmImf/ImfTestFile.cpp
@@ -45,12 +45,17 @@
 #include <ImfStdIO.h>
 #include <ImfXdr.h>
 #include <ImfVersion.h>
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 bool
-isOpenExrFile (const char fileName[], bool &tiled)
+isOpenExrFile
+    (const char fileName[],
+     bool &tiled,
+     bool &deep,
+     bool &multiPart)
 {
     try
     {
@@ -61,6 +66,8 @@ isOpenExrFile (const char fileName[], bool &tiled)
 	Xdr::read <StreamIO> (is, version);
 
 	tiled = isTiled (version);
+        deep = isNonImage (version);
+        multiPart = isMultiPart (version);
 	return magic == MAGIC;
     }
     catch (...)
@@ -72,24 +79,62 @@ isOpenExrFile (const char fileName[], bool &tiled)
 
 
 bool
+isOpenExrFile (const char fileName[], bool &tiled, bool &deep)
+{
+    bool multiPart;
+    return isOpenExrFile (fileName, tiled, deep, multiPart);
+}
+
+
+bool
+isOpenExrFile (const char fileName[], bool &tiled)
+{
+    bool deep, multiPart;
+    return isOpenExrFile (fileName, tiled, deep, multiPart);
+}
+
+
+bool
 isOpenExrFile (const char fileName[])
 {
-    bool tiled;
-    return isOpenExrFile (fileName, tiled);
+    bool tiled, deep, multiPart;
+    return isOpenExrFile (fileName, tiled, deep, multiPart);
 }
 
 
 bool
 isTiledOpenExrFile (const char fileName[])
 {
-    bool exr, tiled;
-    exr = isOpenExrFile (fileName, tiled);
+    bool exr, tiled, deep, multiPart;
+    exr = isOpenExrFile (fileName, tiled, deep, multiPart);
     return exr && tiled;
 }
 
 
 bool
-isOpenExrFile (IStream &is, bool &tiled)
+isDeepOpenExrFile (const char fileName[])
+{
+    bool exr, tiled, deep, multiPart;
+    exr = isOpenExrFile (fileName, tiled, deep, multiPart);
+    return exr && deep;
+}
+
+
+bool
+isMultiPartOpenExrFile (const char fileName[])
+{
+    bool exr, tiled, deep, multiPart;
+    exr = isOpenExrFile (fileName, tiled, deep, multiPart);
+    return exr && multiPart;
+}
+
+
+bool
+isOpenExrFile
+    (IStream &is,
+     bool &tiled,
+     bool &deep,
+     bool &multiPart)
 {
     try
     {
@@ -105,6 +150,8 @@ isOpenExrFile (IStream &is, bool &tiled)
 	is.seekg (pos);
 
 	tiled = isTiled (version);
+	deep = isNonImage (version);
+	multiPart = isMultiPart (version);
 	return magic == MAGIC;
     }
     catch (...)
@@ -117,19 +164,53 @@ isOpenExrFile (IStream &is, bool &tiled)
 
 
 bool
-isOpenExrFile (IStream &is)
+isOpenExrFile (IStream &is, bool &tiled, bool &deep)
+{
+    bool multiPart;
+    return isOpenExrFile (is, tiled, deep, multiPart);
+}
+
+
+bool
+isOpenExrFile (IStream &is, bool &tiled)
+{
+    bool deep, multiPart;
+    return isOpenExrFile (is, tiled, deep, multiPart);
+}
+
+
+bool
+isOpenExrFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is)
 {
-    bool tiled;
-    return isOpenExrFile (is, tiled);
+    bool tiled, deep, multiPart;
+    return isOpenExrFile (is, tiled, deep, multiPart);
 }
 
 
 bool
-isTiledOpenExrFile (IStream &is)
+isTiledOpenExrFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is)
 {
-    bool exr, tiled;
-    exr = isOpenExrFile (is, tiled);
+    bool exr, tiled, deep, multiPart;
+    exr = isOpenExrFile (is, tiled, deep, multiPart);
     return exr && tiled;
 }
 
-} // namespace Imf
+
+bool
+isDeepOpenExrFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is)
+{
+    bool exr, tiled, deep, multiPart;
+    exr = isOpenExrFile (is, tiled, deep, multiPart);
+    return exr && deep;
+}
+
+
+bool
+isMultiPartOpenExrFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is)
+{
+    bool exr, tiled, deep, multiPart;
+    exr = isOpenExrFile (is, tiled, deep, multiPart);
+    return exr && multiPart;
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfTestFile.h b/Source/OpenEXR/IlmImf/ImfTestFile.h
index d81c61a..d02d3bc 100644
--- a/Source/OpenEXR/IlmImf/ImfTestFile.h
+++ b/Source/OpenEXR/IlmImf/ImfTestFile.h
@@ -44,20 +44,54 @@
 //
 //-----------------------------------------------------------------------------
 
+#include "ImfForward.h"
+#include "ImfExport.h"
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-class IStream;
 
+IMF_EXPORT bool isOpenExrFile (const char fileName[]);
 
-bool isOpenExrFile (const char fileName[], bool &isTiled);
-bool isOpenExrFile (const char fileName[]);
-bool isTiledOpenExrFile (const char fileName[]);
-bool isOpenExrFile (IStream &is, bool &isTiled);
-bool isOpenExrFile (IStream &is);
-bool isTiledOpenExrFile (IStream &is);
+IMF_EXPORT bool isOpenExrFile (const char fileName[],
+                               bool &isTiled);
 
+IMF_EXPORT bool isOpenExrFile (const char fileName[],
+                               bool &isTiled,
+                               bool &isDeep);
 
-} // namespace Imf
+IMF_EXPORT bool isOpenExrFile (const char fileName[],
+                               bool &isTiled,
+                               bool &isDeep,
+                               bool &isMultiPart);
+
+IMF_EXPORT bool isTiledOpenExrFile (const char fileName[]);
+
+IMF_EXPORT bool isDeepOpenExrFile (const char fileName[]);
+
+IMF_EXPORT bool isMultiPartOpenExrFile (const char fileName[]);
+
+IMF_EXPORT bool isOpenExrFile (IStream &is);
+
+IMF_EXPORT bool isOpenExrFile (IStream &is,
+                               bool &isTiled);
+
+IMF_EXPORT bool isOpenExrFile (IStream &is,
+                               bool &isTiled,
+                               bool &isDeep);
+
+IMF_EXPORT bool isOpenExrFile (IStream &is,
+                               bool &isTiled,
+                               bool &isDeep,
+                               bool &isMultiPart);
+
+IMF_EXPORT bool isTiledOpenExrFile (IStream &is);
+
+IMF_EXPORT bool isDeepOpenExrFile (IStream &is);
+
+IMF_EXPORT bool isMultiPartOpenExrFile (IStream &is);
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfThreading.cpp b/Source/OpenEXR/IlmImf/ImfThreading.cpp
index 80f569c..a3cf383 100644
--- a/Source/OpenEXR/IlmImf/ImfThreading.cpp
+++ b/Source/OpenEXR/IlmImf/ImfThreading.cpp
@@ -38,23 +38,25 @@
 //
 //-----------------------------------------------------------------------------
 
+#include "ImfThreading.h"
 #include "IlmThreadPool.h"
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 int
 globalThreadCount ()
 {
-    return IlmThread::ThreadPool::globalThreadPool().numThreads();
+    return ILMTHREAD_NAMESPACE::ThreadPool::globalThreadPool().numThreads();
 }
 
 
 void
 setGlobalThreadCount (int count)
 {
-    IlmThread::ThreadPool::globalThreadPool().setNumThreads (count);
+    ILMTHREAD_NAMESPACE::ThreadPool::globalThreadPool().setNumThreads (count);
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfThreading.h b/Source/OpenEXR/IlmImf/ImfThreading.h
index 50fe35e..4d1db04 100644
--- a/Source/OpenEXR/IlmImf/ImfThreading.h
+++ b/Source/OpenEXR/IlmImf/ImfThreading.h
@@ -35,6 +35,9 @@
 #ifndef INCLUDED_IMF_THREADING_H
 #define INCLUDED_IMF_THREADING_H
 
+#include "ImfExport.h"
+#include "ImfNamespace.h"
+
 //-----------------------------------------------------------------------------
 //
 //	Threading support for the IlmImf library
@@ -69,7 +72,7 @@
 //
 //-----------------------------------------------------------------------------
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 //-----------------------------------------------------------------------------
@@ -77,16 +80,16 @@ namespace Imf {
 // compression and decompression of OpenEXR files.
 //-----------------------------------------------------------------------------
     
-int     globalThreadCount ();
+IMF_EXPORT int     globalThreadCount ();
 
 
 //-----------------------------------------------------------------------------
 // Change the number of Imf-global worker threads
 //-----------------------------------------------------------------------------
 
-void    setGlobalThreadCount (int count);
+IMF_EXPORT void    setGlobalThreadCount (int count);
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfTileDescription.h b/Source/OpenEXR/IlmImf/ImfTileDescription.h
index 78bcc0b..7b219c8 100644
--- a/Source/OpenEXR/IlmImf/ImfTileDescription.h
+++ b/Source/OpenEXR/IlmImf/ImfTileDescription.h
@@ -41,8 +41,9 @@
 //	class TileDescription and enum LevelMode
 //
 //-----------------------------------------------------------------------------
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 enum LevelMode
@@ -97,6 +98,10 @@ class TileDescription
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
+
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfTileDescriptionAttribute.cpp b/Source/OpenEXR/IlmImf/ImfTileDescriptionAttribute.cpp
index e15f10f..18aead5 100644
--- a/Source/OpenEXR/IlmImf/ImfTileDescriptionAttribute.cpp
+++ b/Source/OpenEXR/IlmImf/ImfTileDescriptionAttribute.cpp
@@ -42,8 +42,9 @@
 #include <ImfTileDescriptionAttribute.h>
 
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
+using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;
 
 template <>
 const char *
@@ -55,7 +56,7 @@ TileDescriptionAttribute::staticTypeName ()
 
 template <>
 void
-TileDescriptionAttribute::writeValueTo (OStream &os, int version) const
+TileDescriptionAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     Xdr::write <StreamIO> (os, _value.xSize);
     Xdr::write <StreamIO> (os, _value.ySize);
@@ -67,7 +68,7 @@ TileDescriptionAttribute::writeValueTo (OStream &os, int version) const
 
 template <>
 void
-TileDescriptionAttribute::readValueFrom (IStream &is,
+TileDescriptionAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
 					 int size,
 					 int version)
 {
@@ -82,4 +83,4 @@ TileDescriptionAttribute::readValueFrom (IStream &is,
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT 
diff --git a/Source/OpenEXR/IlmImf/ImfTileDescriptionAttribute.h b/Source/OpenEXR/IlmImf/ImfTileDescriptionAttribute.h
index 8a7125a..a8b69b9 100644
--- a/Source/OpenEXR/IlmImf/ImfTileDescriptionAttribute.h
+++ b/Source/OpenEXR/IlmImf/ImfTileDescriptionAttribute.h
@@ -42,32 +42,31 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfAttribute.h>
-#include <ImfTileDescription.h>
+#include "ImfAttribute.h"
+#include "ImfTileDescription.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-
-typedef TypedAttribute<TileDescription> TileDescriptionAttribute;
+typedef TypedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::TileDescription> TileDescriptionAttribute;
 
 template <>
+IMF_EXPORT 
 const char *
 TileDescriptionAttribute::staticTypeName ();
 
 template <>
+IMF_EXPORT 
 void
-TileDescriptionAttribute::writeValueTo (OStream &, int) const;
+TileDescriptionAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &,
+                                        int) const;
 
 template <>
+IMF_EXPORT 
 void
-TileDescriptionAttribute::readValueFrom (IStream &, int, int);
-
+TileDescriptionAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &,
+                                         int, int);
 
-} // namespace Imf
 
-// Metrowerks compiler wants the .cpp file inlined, too
-#ifdef __MWERKS__
-#include <ImfTileDescriptionAttribute.cpp>
-#endif
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfTileOffsets.cpp b/Source/OpenEXR/IlmImf/ImfTileOffsets.cpp
index b1fa29c..b0b40f6 100644
--- a/Source/OpenEXR/IlmImf/ImfTileOffsets.cpp
+++ b/Source/OpenEXR/IlmImf/ImfTileOffsets.cpp
@@ -43,8 +43,10 @@
 #include <ImfXdr.h>
 #include <ImfIO.h>
 #include "Iex.h"
+#include "ImfNamespace.h"
+#include <algorithm>
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 TileOffsets::TileOffsets (LevelMode mode,
@@ -77,20 +79,23 @@ TileOffsets::TileOffsets (LevelMode mode,
 
         _offsets.resize (_numXLevels * _numYLevels);
 
-        for (unsigned int ly = 0; ly < _numYLevels; ++ly)
+        for (int ly = 0; ly < _numYLevels; ++ly)
         {
-            for (unsigned int lx = 0; lx < _numXLevels; ++lx)
+            for (int lx = 0; lx < _numXLevels; ++lx)
             {
                 int l = ly * _numXLevels + lx;
                 _offsets[l].resize (numYTiles[ly]);
 
-                for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
+                for (size_t dy = 0; dy < _offsets[l].size(); ++dy)
                 {
                     _offsets[l][dy].resize (numXTiles[lx]);
                 }
             }
         }
         break;
+
+      case NUM_LEVELMODES :
+          throw IEX_NAMESPACE::ArgExc("Bad initialisation of TileOffsets object");
     }
 }
 
@@ -109,7 +114,7 @@ TileOffsets::anyOffsetsAreInvalid () const
 
 
 void
-TileOffsets::findTiles (IStream &is)
+TileOffsets::findTiles (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, bool isMultiPartFile, bool isDeep, bool skipOnly)
 {
     for (unsigned int l = 0; l < _offsets.size(); ++l)
     {
@@ -119,22 +124,43 @@ TileOffsets::findTiles (IStream &is)
 	    {
 		Int64 tileOffset = is.tellg();
 
+		if (isMultiPartFile)
+		{
+		    int partNumber;
+		    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, partNumber);
+		}
+
 		int tileX;
-		Xdr::read <StreamIO> (is, tileX);
+		OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, tileX);
 
 		int tileY;
-		Xdr::read <StreamIO> (is, tileY);
+		OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, tileY);
 
 		int levelX;
-		Xdr::read <StreamIO> (is, levelX);
+		OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, levelX);
 
 		int levelY;
-		Xdr::read <StreamIO> (is, levelY);
-
-		int dataSize;
-		Xdr::read <StreamIO> (is, dataSize);
+		OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, levelY);
 
-		Xdr::skip <StreamIO> (is, dataSize);
+                if(isDeep)
+                {
+                     Int64 packed_offset_table_size;
+                     Int64 packed_sample_size;
+                     
+                     OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, packed_offset_table_size);
+                     OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, packed_sample_size);
+                     
+                     // next Int64 is unpacked sample size - skip that too
+                     Xdr::skip <StreamIO> (is, packed_offset_table_size+packed_sample_size+8);
+                    
+                }else{
+                    
+		     int dataSize;
+		     OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, dataSize);
+
+		     Xdr::skip <StreamIO> (is, dataSize);
+                }
+		if (skipOnly) continue;
 
 		if (!isValidTile(tileX, tileY, levelX, levelY))
 		    return;
@@ -147,7 +173,7 @@ TileOffsets::findTiles (IStream &is)
 
 
 void
-TileOffsets::reconstructFromFile (IStream &is)
+TileOffsets::reconstructFromFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,bool isMultiPart,bool isDeep)
 {
     //
     // Try to reconstruct a missing tile offset table by sequentially
@@ -159,7 +185,7 @@ TileOffsets::reconstructFromFile (IStream &is)
 
     try
     {
-	findTiles (is);
+	findTiles (is,isMultiPart,isDeep,false);
     }
     catch (...)
     {
@@ -176,7 +202,7 @@ TileOffsets::reconstructFromFile (IStream &is)
 
 
 void
-TileOffsets::readFrom (IStream &is, bool &complete)
+TileOffsets::readFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, bool &complete,bool isMultiPartFile, bool isDeep)
 {
     //
     // Read in the tile offsets from the file's tile offset table
@@ -185,7 +211,7 @@ TileOffsets::readFrom (IStream &is, bool &complete)
     for (unsigned int l = 0; l < _offsets.size(); ++l)
 	for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
 	    for (unsigned int dx = 0; dx < _offsets[l][dy].size(); ++dx)
-		Xdr::read <StreamIO> (is, _offsets[l][dy][dx]);
+		OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, _offsets[l][dy][dx]);
 
     //
     // Check if any tile offsets are invalid.
@@ -204,7 +230,7 @@ TileOffsets::readFrom (IStream &is, bool &complete)
     if (anyOffsetsAreInvalid())
     {
 	complete = false;
-	reconstructFromFile (is);
+	reconstructFromFile (is,isMultiPartFile,isDeep);
     }
     else
     {
@@ -214,8 +240,36 @@ TileOffsets::readFrom (IStream &is, bool &complete)
 }
 
 
+void
+TileOffsets::readFrom (std::vector<Int64> chunkOffsets,bool &complete)
+{
+    size_t totalSize = 0;
+ 
+    for (unsigned int l = 0; l < _offsets.size(); ++l)
+        for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
+            totalSize += _offsets[l][dy].size();
+
+    if (chunkOffsets.size() != totalSize)
+        throw IEX_NAMESPACE::ArgExc ("Wrong offset count, not able to read from this array");
+
+
+
+    int pos = 0;
+    for (size_t l = 0; l < _offsets.size(); ++l)
+        for (size_t dy = 0; dy < _offsets[l].size(); ++dy)
+            for (size_t dx = 0; dx < _offsets[l][dy].size(); ++dx)
+            {
+                _offsets[l][dy][dx] = chunkOffsets[pos];
+                pos++;
+            }
+
+    complete = !anyOffsetsAreInvalid();
+
+}
+
+
 Int64
-TileOffsets::writeTo (OStream &os) const
+TileOffsets::writeTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os) const
 {
     //
     // Write the tile offset table to the file, and
@@ -226,16 +280,122 @@ TileOffsets::writeTo (OStream &os) const
     Int64 pos = os.tellp();
 
     if (pos == -1)
-	Iex::throwErrnoExc ("Cannot determine current file position (%T).");
+	IEX_NAMESPACE::throwErrnoExc ("Cannot determine current file position (%T).");
 
     for (unsigned int l = 0; l < _offsets.size(); ++l)
 	for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
 	    for (unsigned int dx = 0; dx < _offsets[l][dy].size(); ++dx)
-		Xdr::write <StreamIO> (os, _offsets[l][dy][dx]);
+		OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (os, _offsets[l][dy][dx]);
 
     return pos;
 }
 
+namespace {
+struct tilepos{
+    Int64 filePos;
+    int dx;
+    int dy;
+    int l;
+    bool operator <(const tilepos & other) const
+    {
+        return filePos < other.filePos;
+    }
+};
+}
+//-------------------------------------
+// fill array with tile coordinates in the order they appear in the file
+//
+// each input array must be of size (totalTiles)
+// 
+//
+// if the tile order is not RANDOM_Y, it is more efficient to compute the
+// tile ordering rather than using this function
+//
+//-------------------------------------
+void TileOffsets::getTileOrder(int dx_table[],int dy_table[],int lx_table[],int ly_table[]) const
+{
+    // 
+    // helper class
+    // 
+
+    // how many entries?
+    size_t entries=0;
+    for (unsigned int l = 0; l < _offsets.size(); ++l)
+        for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
+           entries+=_offsets[l][dy].size();
+        
+    std::vector<struct tilepos> table(entries);
+    
+    size_t i = 0;
+    for (unsigned int l = 0; l < _offsets.size(); ++l)
+        for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
+            for (unsigned int dx = 0; dx < _offsets[l][dy].size(); ++dx)
+            {
+                table[i].filePos = _offsets[l][dy][dx];
+                table[i].dx = dx;
+                table[i].dy = dy;
+                table[i].l = l;
+
+                ++i;
+                
+            }
+              
+    std::sort(table.begin(),table.end());
+    
+    //
+    // write out the values
+    //
+    
+    // pass 1: write out dx and dy, since these are independent of level mode
+    
+    for(size_t i=0;i<entries;i++)
+    {
+        dx_table[i] = table[i].dx;
+        dy_table[i] = table[i].dy;
+    }
+
+    // now write out the levels, which depend on the level mode
+    
+    switch (_mode)
+    {
+        case ONE_LEVEL:
+        {
+            for(size_t i=0;i<entries;i++)
+            {
+                lx_table[i] = 0;
+                ly_table[i] = 0;               
+            }
+            break;            
+        }
+        case MIPMAP_LEVELS:
+        {
+            for(size_t i=0;i<entries;i++)
+            {
+                lx_table[i]= table[i].l;
+                ly_table[i] =table[i].l;               
+                
+            }
+            break;
+        }
+            
+        case RIPMAP_LEVELS:
+        {
+            for(size_t i=0;i<entries;i++)
+            {
+                lx_table[i]= table[i].l % _numXLevels;
+                ly_table[i] = table[i].l / _numXLevels; 
+                
+            }
+            break;
+        }
+        case NUM_LEVELMODES :
+            throw IEX_NAMESPACE::LogicExc("Bad level mode getting tile order");
+    }
+    
+    
+    
+}
+
 
 bool
 TileOffsets::isEmpty () const
@@ -252,6 +412,7 @@ TileOffsets::isEmpty () const
 bool
 TileOffsets::isValidTile (int dx, int dy, int lx, int ly) const
 {
+    if(lx<0 || ly < 0 || dx<0 || dy < 0) return false;
     switch (_mode)
     {
       case ONE_LEVEL:
@@ -259,8 +420,8 @@ TileOffsets::isValidTile (int dx, int dy, int lx, int ly) const
         if (lx == 0 &&
 	    ly == 0 &&
 	    _offsets.size() > 0 &&
-            _offsets[0].size() > dy &&
-            _offsets[0][dy].size() > dx)
+            int(_offsets[0].size()) > dy &&
+            int(_offsets[0][dy].size()) > dx)
 	{
             return true;
 	}
@@ -271,9 +432,9 @@ TileOffsets::isValidTile (int dx, int dy, int lx, int ly) const
 
         if (lx < _numXLevels &&
 	    ly < _numYLevels &&
-            _offsets.size() > lx &&
-            _offsets[lx].size() > dy &&
-            _offsets[lx][dy].size() > dx)
+            int(_offsets.size()) > lx &&
+            int(_offsets[lx].size()) > dy &&
+            int(_offsets[lx][dy].size()) > dx)
 	{
             return true;
 	}
@@ -284,9 +445,9 @@ TileOffsets::isValidTile (int dx, int dy, int lx, int ly) const
 
         if (lx < _numXLevels &&
 	    ly < _numYLevels &&
-            _offsets.size() > lx + ly * _numXLevels &&
-            _offsets[lx + ly * _numXLevels].size() > dy &&
-            _offsets[lx + ly * _numXLevels][dy].size() > dx)
+	    (_offsets.size() > (size_t) lx+  ly *  (size_t) _numXLevels) &&
+            int(_offsets[lx + ly * _numXLevels].size()) > dy &&
+            int(_offsets[lx + ly * _numXLevels][dy].size()) > dx)
 	{
             return true;
 	}
@@ -330,7 +491,7 @@ TileOffsets::operator () (int dx, int dy, int lx, int ly)
 
       default:
 
-        throw Iex::ArgExc ("Unknown LevelMode format.");
+        throw IEX_NAMESPACE::ArgExc ("Unknown LevelMode format.");
     }
 }
 
@@ -370,7 +531,7 @@ TileOffsets::operator () (int dx, int dy, int lx, int ly) const
 
       default:
 
-        throw Iex::ArgExc ("Unknown LevelMode format.");
+        throw IEX_NAMESPACE::ArgExc ("Unknown LevelMode format.");
     }
 }
 
@@ -381,5 +542,11 @@ TileOffsets::operator () (int dx, int dy, int l) const
     return operator () (dx, dy, l, l);
 }
 
+const std::vector<std::vector<std::vector <Int64> > >&
+TileOffsets::getOffsets() const
+{
+    return _offsets;
+}
+
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfTileOffsets.h b/Source/OpenEXR/IlmImf/ImfTileOffsets.h
index 7b2b4c2..d8c151e 100644
--- a/Source/OpenEXR/IlmImf/ImfTileOffsets.h
+++ b/Source/OpenEXR/IlmImf/ImfTileOffsets.h
@@ -42,17 +42,17 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfTileDescription.h>
-#include <ImfInt64.h>
+#include "ImfTileDescription.h"
+#include "ImfInt64.h"
 #include <vector>
+#include "ImfNamespace.h"
+#include "ImfForward.h"
+#include "ImfExport.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-class IStream;
-class OStream;
 
-
-class TileOffsets
+class IMF_EXPORT TileOffsets
 {
   public:
 
@@ -66,8 +66,9 @@ class TileOffsets
     // File I/O
     // --------
 
-    void		readFrom (IStream &is, bool &complete);
-    Int64		writeTo (OStream &os) const;
+    void		readFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,  bool &complete,bool isMultiPart,bool isDeep);
+    void                readFrom (std::vector<Int64> chunkOffsets,bool &complete);
+    Int64		writeTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os) const;
 
 
     //-----------------------------------------------------------
@@ -76,7 +77,16 @@ class TileOffsets
 
     bool		isEmpty () const;
     
-
+    
+    
+    //-----------------------------------------------------------
+    // populate 'list' with tiles coordinates in the order they appear
+    // in the offset table (assumes full table!
+    // each array myst be at leat totalTiles long
+    //-----------------------------------------------------------
+    void getTileOrder(int dx_table[], int dy_table[], int lx_table[], int ly_table[]) const;
+    
+    
     //-----------------------
     // Access to the elements
     //-----------------------
@@ -85,23 +95,31 @@ class TileOffsets
     Int64 &		operator () (int dx, int dy, int l);
     const Int64 &	operator () (int dx, int dy, int lx, int ly) const;
     const Int64 &	operator () (int dx, int dy, int l) const;
-
+    bool        isValidTile (int dx, int dy, int lx, int ly) const;
+    const std::vector<std::vector<std::vector <Int64> > >& getOffsets() const;
+    
   private:
-  
-    void		findTiles (IStream &is);
-    void		reconstructFromFile (IStream &is);
-    bool		readTile (IStream &is);
+
+    void		findTiles (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, bool isMultiPartFile,
+                                   bool isDeep,
+        		           bool skipOnly);
+    void		reconstructFromFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,bool isMultiPartFile,bool isDeep);
+    bool		readTile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is);
     bool		anyOffsetsAreInvalid () const;
-    bool		isValidTile (int dx, int dy, int lx, int ly) const;
 
     LevelMode		_mode;
     int			_numXLevels;
     int			_numYLevels;
 
     std::vector<std::vector<std::vector <Int64> > > _offsets;
+    
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
+
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfTiledInputFile.cpp b/Source/OpenEXR/IlmImf/ImfTiledInputFile.cpp
index a45c3ac..cd244cc 100644
--- a/Source/OpenEXR/IlmImf/ImfTiledInputFile.cpp
+++ b/Source/OpenEXR/IlmImf/ImfTiledInputFile.cpp
@@ -38,19 +38,21 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfTiledInputFile.h>
-#include <ImfTileDescriptionAttribute.h>
-#include <ImfChannelList.h>
-#include <ImfMisc.h>
-#include <ImfTiledMisc.h>
-#include <ImfStdIO.h>
-#include <ImfCompressor.h>
-#include "ImathBox.h"
-#include <ImfXdr.h>
-#include <ImfConvert.h>
-#include <ImfVersion.h>
-#include <ImfTileOffsets.h>
-#include <ImfThreading.h>
+#include "ImfTiledInputFile.h"
+#include "ImfTileDescriptionAttribute.h"
+#include "ImfChannelList.h"
+#include "ImfMisc.h"
+#include "ImfTiledMisc.h"
+#include "ImfStdIO.h"
+#include "ImfCompressor.h"
+#include "ImfXdr.h"
+#include "ImfConvert.h"
+#include "ImfVersion.h"
+#include "ImfTileOffsets.h"
+#include "ImfThreading.h"
+#include "ImfPartType.h"
+#include "ImfMultiPartInputFile.h"
+#include "ImfInputStreamMutex.h"
 #include "IlmThreadPool.h"
 #include "IlmThreadSemaphore.h"
 #include "IlmThreadMutex.h"
@@ -60,22 +62,23 @@
 #include <vector>
 #include <algorithm>
 #include <assert.h>
+#include "ImfInputPartData.h"
+#include "ImfNamespace.h"
 
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
-namespace Imf {
-
-using Imath::Box2i;
-using Imath::V2i;
+using IMATH_NAMESPACE::Box2i;
+using IMATH_NAMESPACE::V2i;
 using std::string;
 using std::vector;
 using std::min;
 using std::max;
-using IlmThread::Mutex;
-using IlmThread::Lock;
-using IlmThread::Semaphore;
-using IlmThread::Task;
-using IlmThread::TaskGroup;
-using IlmThread::ThreadPool;
+using ILMTHREAD_NAMESPACE::Mutex;
+using ILMTHREAD_NAMESPACE::Lock;
+using ILMTHREAD_NAMESPACE::Semaphore;
+using ILMTHREAD_NAMESPACE::Task;
+using ILMTHREAD_NAMESPACE::TaskGroup;
+using ILMTHREAD_NAMESPACE::ThreadPool;
 
 namespace {
 
@@ -157,6 +160,7 @@ struct TileBuffer
 
 TileBuffer::TileBuffer (Compressor *comp):
     uncompressedData (0),
+    buffer (0),
     dataSize (0),
     compressor (comp),
     format (defaultFormat (compressor)),
@@ -180,6 +184,9 @@ TileBuffer::~TileBuffer ()
 } // namespace
 
 
+class MultiPartInputFile;
+
+
 //
 // struct TiledInputFile::Data stores things that will be
 // needed between calls to readTile()
@@ -187,48 +194,53 @@ TileBuffer::~TileBuffer ()
 
 struct TiledInputFile::Data: public Mutex
 {
-    Header	    header;		    // the image header
-    TileDescription tileDesc;		    // describes the tile layout
-    int		    version;		    // file's version
-    FrameBuffer	    frameBuffer;	    // framebuffer to write into
-    LineOrder	    lineOrder;		    // the file's lineorder
-    int		    minX;		    // data window's min x coord
-    int		    maxX;		    // data window's max x coord
-    int		    minY;		    // data window's min y coord
-    int		    maxY;		    // data window's max x coord
+    Header	    header;	        	    // the image header
+    TileDescription tileDesc;		            // describes the tile layout
+    int		    version;		            // file's version
+    FrameBuffer	    frameBuffer;	            // framebuffer to write into
+    LineOrder	    lineOrder;		            // the file's lineorder
+    int		    minX;		            // data window's min x coord
+    int		    maxX;		            // data window's max x coord
+    int		    minY;		            // data window's min y coord
+    int		    maxY;		            // data window's max x coord
+
+    int		    numXLevels;		            // number of x levels
+    int		    numYLevels;		            // number of y levels
+    int *	    numXTiles;		            // number of x tiles at a level
+    int *	    numYTiles;		            // number of y tiles at a level
 
-    int		    numXLevels;		    // number of x levels
-    int		    numYLevels;		    // number of y levels
-    int *	    numXTiles;		    // number of x tiles at a level
-    int *	    numYTiles;		    // number of y tiles at a level
+    TileOffsets	    tileOffsets;	            // stores offsets in file for
+    // each tile
 
-    TileOffsets	    tileOffsets;	    // stores offsets in file for
-					    // each tile
+    bool	    fileIsComplete;	            // True if no tiles are missing
+                                                    // in the file
 
-    bool	    fileIsComplete;	    // True if no tiles are missing
-    					    // in the file
+    vector<TInSliceInfo> slices;        	    // info about channels in file
 
-    Int64	    currentPosition;        // file offset for current tile,
-					    // used to prevent unnecessary
-					    // seeking
+    size_t	    bytesPerPixel;                  // size of an uncompressed pixel
 
-    vector<TInSliceInfo> slices;	    // info about channels in file
-    IStream *	    is;			    // file stream to read from
+    size_t	    maxBytesPerTileLine;            // combined size of a line
+                                                    // over all channels
 
-    bool	    deleteStream;	    // should we delete the stream
-					    // ourselves? or does someone
-					    // else do it?
+    int             partNumber;                     // part number
 
-    size_t	    bytesPerPixel;          // size of an uncompressed pixel
+    bool            multiPartBackwardSupport;       // if we are reading a multipart file
+                                                    // using OpenEXR 1.7 API
 
-    size_t	    maxBytesPerTileLine;    // combined size of a line
-					    // over all channels
+    int             numThreads;                     // number of threads
 
+    MultiPartInputFile* multiPartFile;              // the MultiPartInputFile used to
+                                                    // support backward compatibility
     
-    vector<TileBuffer*> tileBuffers;        // each holds a single tile
-    size_t          tileBufferSize;	    // size of the tile buffers
+    vector<TileBuffer*> tileBuffers;                // each holds a single tile
+    size_t          tileBufferSize;	            // size of the tile buffers
 
-     Data (bool deleteStream, int numThreads);
+    bool            memoryMapped;                   // if the stream is memory mapped
+
+    InputStreamMutex * _streamData;
+    bool                _deleteStream;
+
+     Data (int numThreads);
     ~Data ();
 
     inline TileBuffer * getTileBuffer (int number);
@@ -237,11 +249,15 @@ struct TiledInputFile::Data: public Mutex
 };
 
 
-TiledInputFile::Data::Data (bool del, int numThreads):
+TiledInputFile::Data::Data (int numThreads):
     numXTiles (0),
     numYTiles (0),
-    is (0),
-    deleteStream (del)
+    partNumber (-1),
+    multiPartBackwardSupport(false),
+    numThreads(numThreads),
+    memoryMapped(false),
+    _streamData(NULL),
+    _deleteStream(false)
 {
     //
     // We need at least one tileBuffer, but if threading is used,
@@ -257,11 +273,11 @@ TiledInputFile::Data::~Data ()
     delete [] numXTiles;
     delete [] numYTiles;
 
-    if (deleteStream)
-	delete is;
-
     for (size_t i = 0; i < tileBuffers.size(); i++)
         delete tileBuffers[i];
+
+    if (multiPartBackwardSupport)
+        delete multiPartFile;
 }
 
 
@@ -275,7 +291,8 @@ TiledInputFile::Data::getTileBuffer (int number)
 namespace {
 
 void
-readTileData (TiledInputFile::Data *ifd,
+readTileData (InputStreamMutex *streamData,
+              TiledInputFile::Data *ifd,
 	      int dx, int dy,
 	      int lx, int ly,
               char *&buffer,
@@ -297,12 +314,31 @@ readTileData (TiledInputFile::Data *ifd,
 
     if (tileOffset == 0)
     {
-        THROW (Iex::InputExc, "Tile (" << dx << ", " << dy << ", " <<
+        THROW (IEX_NAMESPACE::InputExc, "Tile (" << dx << ", " << dy << ", " <<
 			      lx << ", " << ly << ") is missing.");
     }
 
-    if (ifd->currentPosition != tileOffset)
-        ifd->is->seekg (tileOffset);
+
+    //
+    // In a multi-part file, the next chunk does not need to
+    // belong to the same part, so we have to compare the
+    // offset here.
+    //
+
+    if (!isMultiPart(ifd->version))
+    {
+        if (streamData->currentPosition != tileOffset)
+            streamData->is->seekg (tileOffset);
+    }
+    else
+    {
+        //
+        // In a multi-part file, the file pointer may be moved by other
+        // parts, so we have to ask tellg() where we are.
+        //
+        if (streamData->is->tellg() != tileOffset)
+            streamData->is->seekg (tileOffset);
+    }
 
     //
     // Read the first few bytes of the tile (the header).
@@ -312,35 +348,46 @@ readTileData (TiledInputFile::Data *ifd,
     
     int tileXCoord, tileYCoord, levelX, levelY;
 
-    Xdr::read <StreamIO> (*ifd->is, tileXCoord);
-    Xdr::read <StreamIO> (*ifd->is, tileYCoord);
-    Xdr::read <StreamIO> (*ifd->is, levelX);
-    Xdr::read <StreamIO> (*ifd->is, levelY);
-    Xdr::read <StreamIO> (*ifd->is, dataSize);
+    if (isMultiPart(ifd->version))
+    {
+        int partNumber;
+        Xdr::read <StreamIO> (*streamData->is, partNumber);
+        if (partNumber != ifd->partNumber)
+        {
+            THROW (IEX_NAMESPACE::ArgExc, "Unexpected part number " << partNumber
+                   << ", should be " << ifd->partNumber << ".");
+        }
+    }
+
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*streamData->is, tileXCoord);
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*streamData->is, tileYCoord);
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*streamData->is, levelX);
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*streamData->is, levelY);
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*streamData->is, dataSize);
 
     if (tileXCoord != dx)
-        throw Iex::InputExc ("Unexpected tile x coordinate.");
+        throw IEX_NAMESPACE::InputExc ("Unexpected tile x coordinate.");
 
     if (tileYCoord != dy)
-        throw Iex::InputExc ("Unexpected tile y coordinate.");
+        throw IEX_NAMESPACE::InputExc ("Unexpected tile y coordinate.");
 
     if (levelX != lx)
-        throw Iex::InputExc ("Unexpected tile x level number coordinate.");
+        throw IEX_NAMESPACE::InputExc ("Unexpected tile x level number coordinate.");
 
     if (levelY != ly)
-        throw Iex::InputExc ("Unexpected tile y level number coordinate.");
+        throw IEX_NAMESPACE::InputExc ("Unexpected tile y level number coordinate.");
 
     if (dataSize > (int) ifd->tileBufferSize)
-        throw Iex::InputExc ("Unexpected tile block length.");
+        throw IEX_NAMESPACE::InputExc ("Unexpected tile block length.");
 
     //
     // Read the pixel data.
     //
 
-    if (ifd->is->isMemoryMapped ())
-        buffer = ifd->is->readMemoryMapped (dataSize);
+    if (streamData->is->isMemoryMapped ())
+        buffer = streamData->is->readMemoryMapped (dataSize);
     else
-        ifd->is->read (buffer, dataSize);
+        streamData->is->read (buffer, dataSize);
 
     //
     // Keep track of which tile is the next one in
@@ -348,12 +395,13 @@ readTileData (TiledInputFile::Data *ifd,
     // operations (seekg() can be fairly expensive).
     //
     
-    ifd->currentPosition = tileOffset + 5 * Xdr::size<int>() + dataSize;
+    streamData->currentPosition = tileOffset + 5 * Xdr::size<int>() + dataSize;
 }
 
 
 void
-readNextTileData (TiledInputFile::Data *ifd,
+readNextTileData (InputStreamMutex *streamData,
+                  TiledInputFile::Data *ifd,
 		  int &dx, int &dy,
 		  int &lx, int &ly,
                   char * & buffer,
@@ -363,24 +411,34 @@ readNextTileData (TiledInputFile::Data *ifd,
     // Read the next tile block from the file
     //
 
+    if(isMultiPart(ifd->version))
+    {
+        int part;
+        Xdr::read <StreamIO> (*streamData->is, part);
+        if(part!=ifd->partNumber)
+        {
+           throw IEX_NAMESPACE::InputExc("Unexpected part number in readNextTileData");
+        }
+    }
+
     //
     // Read the first few bytes of the tile (the header).
     //
 
-    Xdr::read <StreamIO> (*ifd->is, dx);
-    Xdr::read <StreamIO> (*ifd->is, dy);
-    Xdr::read <StreamIO> (*ifd->is, lx);
-    Xdr::read <StreamIO> (*ifd->is, ly);
-    Xdr::read <StreamIO> (*ifd->is, dataSize);
+    Xdr::read <StreamIO> (*streamData->is, dx);
+    Xdr::read <StreamIO> (*streamData->is, dy);
+    Xdr::read <StreamIO> (*streamData->is, lx);
+    Xdr::read <StreamIO> (*streamData->is, ly);
+    Xdr::read <StreamIO> (*streamData->is, dataSize);
 
     if (dataSize > (int) ifd->tileBufferSize)
-        throw Iex::InputExc ("Unexpected tile block length.");
+        throw IEX_NAMESPACE::InputExc ("Unexpected tile block length.");
     
     //
     // Read the pixel data.
     //
 
-    ifd->is->read (buffer, dataSize);
+    streamData->is->read (buffer, dataSize);
     
     //
     // Keep track of which tile is the next one in
@@ -388,7 +446,7 @@ readNextTileData (TiledInputFile::Data *ifd,
     // operations (seekg() can be fairly expensive).
     //
 
-    ifd->currentPosition += 5 * Xdr::size<int>() + dataSize;
+    streamData->currentPosition += 5 * Xdr::size<int>() + dataSize;
 }
 
 
@@ -448,14 +506,15 @@ TileBufferTask::execute ()
         // Calculate information about the tile
         //
     
-        Box2i tileRange = Imf::dataWindowForTile (_ifd->tileDesc,
-                                                  _ifd->minX, _ifd->maxX,
-                                                  _ifd->minY, _ifd->maxY,
-                                                  _tileBuffer->dx,
-                                                  _tileBuffer->dy,
-                                                  _tileBuffer->lx,
-                                                  _tileBuffer->ly);
-    
+        Box2i tileRange =  OPENEXR_IMF_INTERNAL_NAMESPACE::dataWindowForTile (
+                _ifd->tileDesc,
+                _ifd->minX, _ifd->maxX,
+                _ifd->minY, _ifd->maxY,
+                _tileBuffer->dx,
+                _tileBuffer->dy,
+                _tileBuffer->lx,
+                _tileBuffer->ly);
+
         int numPixelsPerScanLine = tileRange.max.x - tileRange.min.x + 1;
     
         int numPixelsInTile = numPixelsPerScanLine *
@@ -579,6 +638,7 @@ TileBufferTask::execute ()
 TileBufferTask *
 newTileBufferTask
     (TaskGroup *group,
+     InputStreamMutex *streamData,
      TiledInputFile::Data *ifd,
      int number,
      int dx, int dy,
@@ -605,7 +665,7 @@ newTileBufferTask
 
 	tileBuffer->uncompressedData = 0;
 
-	readTileData (ifd, dx, dy, lx, ly,
+	readTileData (streamData, ifd, dx, dy, lx, ly,
 		      tileBuffer->buffer,
 		      tileBuffer->dataSize);
     }
@@ -629,22 +689,55 @@ newTileBufferTask
 
 
 TiledInputFile::TiledInputFile (const char fileName[], int numThreads):
-    _data (new Data (true, numThreads))
+    _data (new Data (numThreads))
 {
+    _data->_streamData=NULL;
+    _data->_deleteStream=true;
+    
     //
     // This constructor is called when a user
     // explicitly wants to read a tiled file.
     //
 
+
+    IStream* is = 0;
     try
     {
-	_data->is = new StdIFStream (fileName);
-	_data->header.readFrom (*_data->is, _data->version);
+        is = new StdIFStream (fileName);
+	readMagicNumberAndVersionField(*is, _data->version);
+
+	//
+        // Backward compatibility to read multpart file.
+        //
+	if (isMultiPart(_data->version))
+	{
+	    compatibilityInitialize(*is);
+	    return;
+	}
+
+	_data->_streamData = new InputStreamMutex();
+	_data->_streamData->is = is;
+	_data->header.readFrom (*_data->_streamData->is, _data->version);
 	initialize();
+        //read tile offsets - we are not multipart or deep
+        _data->tileOffsets.readFrom (*(_data->_streamData->is), _data->fileIsComplete,false,false);
+	_data->_streamData->currentPosition = _data->_streamData->is->tellg();
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
-	delete _data;
+        if (_data->_streamData != 0)
+        {
+            if (_data->_streamData->is != 0)
+            {
+                delete _data->_streamData->is;
+                _data->_streamData->is = is = 0;
+            }
+
+            delete _data->_streamData;
+        }
+
+        if (is != 0)
+            delete is;
 
 	REPLACE_EXC (e, "Cannot open image file "
 			"\"" << fileName << "\". " << e);
@@ -652,28 +745,61 @@ TiledInputFile::TiledInputFile (const char fileName[], int numThreads):
     }
     catch (...)
     {
-	delete _data;
+        if ( _data->_streamData != 0)
+        {
+            if ( _data->_streamData->is != 0)
+            {
+                delete _data->_streamData->is;
+                _data->_streamData->is = is = 0;
+            }
+
+            delete _data->_streamData;
+        }
+
+        if (is != 0)
+            delete is;
         throw;
     }
 }
 
 
-TiledInputFile::TiledInputFile (IStream &is, int numThreads):
-    _data (new Data (false, numThreads))
+TiledInputFile::TiledInputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int numThreads):
+    _data (new Data (numThreads))
 {
+    _data->_deleteStream=false;
     //
     // This constructor is called when a user
     // explicitly wants to read a tiled file.
     //
 
+    bool streamDataCreated = false;
+
     try
     {
-	_data->is = &is;
-	_data->header.readFrom (*_data->is, _data->version);
+	readMagicNumberAndVersionField(is, _data->version);
+
+	//
+	// Backward compatibility to read multpart file.
+	//
+	if (isMultiPart(_data->version))
+        {
+	    compatibilityInitialize(is);
+            return;
+        }
+
+	streamDataCreated = true;
+	_data->_streamData = new InputStreamMutex();
+	_data->_streamData->is = &is;
+	_data->header.readFrom (*_data->_streamData->is, _data->version);
 	initialize();
+        // file is guaranteed to be single part, regular image
+        _data->tileOffsets.readFrom (*(_data->_streamData->is), _data->fileIsComplete,false,false);
+	_data->memoryMapped = _data->_streamData->is->isMemoryMapped();
+	_data->_streamData->currentPosition = _data->_streamData->is->tellg();
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
+        if (streamDataCreated) delete _data->_streamData;
 	delete _data;
 
 	REPLACE_EXC (e, "Cannot open image file "
@@ -682,39 +808,110 @@ TiledInputFile::TiledInputFile (IStream &is, int numThreads):
     }
     catch (...)
     {
+        if (streamDataCreated) delete _data->_streamData;
 	delete _data;
         throw;
     }
 }
 
 
-TiledInputFile::TiledInputFile
-    (const Header &header,
-     IStream *is,
-     int version,
-     int numThreads)
-:
-    _data (new Data (false, numThreads))
+TiledInputFile::TiledInputFile (const Header &header,
+                                OPENEXR_IMF_INTERNAL_NAMESPACE::IStream *is,
+                                int version,
+                                int numThreads) :
+    _data (new Data (numThreads))
 {
+    _data->_deleteStream=false;
+    _data->_streamData = new InputStreamMutex();
     //
     // This constructor called by class Imf::InputFile
     // when a user wants to just read an image file, and
     // doesn't care or know if the file is tiled.
+    // No need to have backward compatibility here, because
+    // we have somehow got the header.
     //
 
-    _data->is = is;
+    _data->_streamData->is = is;
     _data->header = header;
     _data->version = version;
     initialize();
+    _data->tileOffsets.readFrom (*(_data->_streamData->is),_data->fileIsComplete,false,false);
+    _data->memoryMapped = is->isMemoryMapped();
+    _data->_streamData->currentPosition = _data->_streamData->is->tellg();
+}
+
+
+TiledInputFile::TiledInputFile (InputPartData* part) 
+{
+    _data = new Data (part->numThreads);
+    _data->_deleteStream=false;
+    multiPartInitialize(part);
 }
 
 
 void
-TiledInputFile::initialize ()
+TiledInputFile::compatibilityInitialize(OPENEXR_IMF_INTERNAL_NAMESPACE::IStream& is)
+{
+    is.seekg(0);
+    //
+    // Construct a MultiPartInputFile, initialize TiledInputFile
+    // with the part 0 data.
+    // (TODO) maybe change the third parameter of the constructor of MultiPartInputFile later.
+    //
+    _data->multiPartBackwardSupport = true;
+    _data->multiPartFile = new MultiPartInputFile(is, _data->numThreads);
+    InputPartData* part = _data->multiPartFile->getPart(0);
+
+    multiPartInitialize(part);
+}
+
+
+void
+TiledInputFile::multiPartInitialize(InputPartData* part)
 {
-    if (!isTiled (_data->version))
-	throw Iex::ArgExc ("Expected a tiled file but the file is not tiled.");
+    if (part->header.type() != TILEDIMAGE)
+        throw IEX_NAMESPACE::ArgExc("Can't build a TiledInputFile from a type-mismatched part.");
+
+    _data->_streamData = part->mutex;
+    _data->header = part->header;
+    _data->version = part->version;
+    _data->partNumber = part->partNumber;
+    _data->memoryMapped = _data->_streamData->is->isMemoryMapped();
+    initialize();
+    _data->tileOffsets.readFrom(part->chunkOffsets,_data->fileIsComplete);
+    _data->_streamData->currentPosition = _data->_streamData->is->tellg();
+}
+
 
+void
+TiledInputFile::initialize ()
+{
+    // fix bad types in header (arises when a tool built against an older version of
+    // OpenEXR converts a scanline image to tiled)
+    // only applies when file is a single part, regular image, tiled file
+    //
+    if(!isMultiPart(_data->version) &&
+       !isNonImage(_data->version) && 
+       isTiled(_data->version) && 
+       _data->header.hasType() )
+    {
+        _data->header.setType(TILEDIMAGE);
+    }
+    
+    if (_data->partNumber == -1)
+    {
+        if (!isTiled (_data->version))
+            throw IEX_NAMESPACE::ArgExc ("Expected a tiled file but the file is not tiled.");
+        
+    }
+    else
+    {
+        if(_data->header.hasType() && _data->header.type()!=TILEDIMAGE)
+        {
+            throw IEX_NAMESPACE::ArgExc ("TiledInputFile used for non-tiledimage part.");
+        }
+    }
+    
     _data->header.sanityCheck (true);
 
     _data->tileDesc = _data->header.tileDescription();
@@ -758,7 +955,7 @@ TiledInputFile::initialize ()
 						   _data->tileDesc.ySize,
 						   _data->header));
 
-        if (!_data->is->isMemoryMapped ())
+        if (!_data->_streamData->is->isMemoryMapped ())
             _data->tileBuffers[i]->buffer = new char [_data->tileBufferSize];
     }
 
@@ -767,19 +964,21 @@ TiledInputFile::initialize ()
 				      _data->numYLevels,
 				      _data->numXTiles,
 				      _data->numYTiles);
-
-    _data->tileOffsets.readFrom (*(_data->is), _data->fileIsComplete);
-
-    _data->currentPosition = _data->is->tellg();
 }
 
 
 TiledInputFile::~TiledInputFile ()
 {
-    if (!_data->is->isMemoryMapped())
+    if (!_data->memoryMapped)
         for (size_t i = 0; i < _data->tileBuffers.size(); i++)
             delete [] _data->tileBuffers[i]->buffer;
 
+    if (_data->_deleteStream)
+        delete _data->_streamData->is;
+
+    if (_data->partNumber == -1)
+        delete _data->_streamData;
+
     delete _data;
 }
 
@@ -787,7 +986,7 @@ TiledInputFile::~TiledInputFile ()
 const char *
 TiledInputFile::fileName () const
 {
-    return _data->is->fileName();
+    return _data->_streamData->is->fileName();
 }
 
 
@@ -808,7 +1007,7 @@ TiledInputFile::version () const
 void	
 TiledInputFile::setFrameBuffer (const FrameBuffer &frameBuffer)
 {
-    Lock lock (*_data);
+    Lock lock (*_data->_streamData);
 
     //
     // Set the frame buffer
@@ -832,7 +1031,7 @@ TiledInputFile::setFrameBuffer (const FrameBuffer &frameBuffer)
 
         if (i.channel().xSampling != j.slice().xSampling ||
             i.channel().ySampling != j.slice().ySampling)
-            THROW (Iex::ArgExc, "X and/or y subsampling factors "
+            THROW (IEX_NAMESPACE::ArgExc, "X and/or y subsampling factors "
 				"of \"" << i.name() << "\" channel "
 				"of input file \"" << fileName() << "\" are "
 				"not compatible with the frame buffer's "
@@ -927,7 +1126,7 @@ TiledInputFile::setFrameBuffer (const FrameBuffer &frameBuffer)
 const FrameBuffer &
 TiledInputFile::frameBuffer () const
 {
-    Lock lock (*_data);
+    Lock lock (*_data->_streamData);
     return _data->frameBuffer;
 }
 
@@ -948,12 +1147,18 @@ TiledInputFile::readTiles (int dx1, int dx2, int dy1, int dy2, int lx, int ly)
 
     try
     {
-        Lock lock (*_data);
+        Lock lock (*_data->_streamData);
 
         if (_data->slices.size() == 0)
-            throw Iex::ArgExc ("No frame buffer specified "
+            throw IEX_NAMESPACE::ArgExc ("No frame buffer specified "
 			       "as pixel data destination.");
         
+        if (!isValidLevel (lx, ly))
+            THROW (IEX_NAMESPACE::ArgExc,
+                   "Level coordinate "
+                   "(" << lx << ", " << ly << ") "
+                   "is invalid.");
+
         //
         // Determine the first and last tile coordinates in both dimensions.
         // We always attempt to read the range of tiles in the order that
@@ -992,11 +1197,12 @@ TiledInputFile::readTiles (int dx1, int dx2, int dy1, int dy2, int lx, int ly)
                 for (int dx = dx1; dx <= dx2; dx++)
                 {
                     if (!isValidTile (dx, dy, lx, ly))
-                        THROW (Iex::ArgExc,
+                        THROW (IEX_NAMESPACE::ArgExc,
 			       "Tile (" << dx << ", " << dy << ", " <<
 			       lx << "," << ly << ") is not a valid tile.");
                     
                     ThreadPool::addGlobalTask (newTileBufferTask (&taskGroup,
+                                                                  _data->_streamData,
                                                                   _data,
                                                                   tileNumber++,
                                                                   dx, dy,
@@ -1026,7 +1232,7 @@ TiledInputFile::readTiles (int dx1, int dx2, int dy1, int dy2, int lx, int ly)
 
 	const string *exception = 0;
 
-        for (int i = 0; i < _data->tileBuffers.size(); ++i)
+        for (size_t i = 0; i < _data->tileBuffers.size(); ++i)
 	{
             TileBuffer *tileBuffer = _data->tileBuffers[i];
 
@@ -1037,9 +1243,9 @@ TiledInputFile::readTiles (int dx1, int dx2, int dy1, int dy2, int lx, int ly)
 	}
 
 	if (exception)
-	    throw Iex::IoExc (*exception);
+	    throw IEX_NAMESPACE::IoExc (*exception);
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
         REPLACE_EXC (e, "Error reading pixel data from image "
                         "file \"" << fileName() << "\". " << e);
@@ -1077,21 +1283,39 @@ TiledInputFile::rawTileData (int &dx, int &dy,
 {
     try
     {
-        Lock lock (*_data);
+        Lock lock (*_data->_streamData);
 
         if (!isValidTile (dx, dy, lx, ly))
-            throw Iex::ArgExc ("Tried to read a tile outside "
+            throw IEX_NAMESPACE::ArgExc ("Tried to read a tile outside "
 			       "the image file's data window.");
 
         TileBuffer *tileBuffer = _data->getTileBuffer (0);
-        
-        readNextTileData (_data, dx, dy, lx, ly,
+
+        //
+        // if file is a multipart file, we have to seek to the required tile
+        // since we don't know where the file pointer is
+        //
+        int old_dx=dx;
+        int old_dy=dy;
+        int old_lx=lx;
+        int old_ly=ly;
+        if(isMultiPart(version()))
+        {
+            _data->_streamData->is->seekg(_data->tileOffsets(dx,dy,lx,ly));
+        }
+        readNextTileData (_data->_streamData, _data, dx, dy, lx, ly,
 			  tileBuffer->buffer,
                           pixelDataSize);
-
+        if(isMultiPart(version()))
+        {
+            if (old_dx!=dx || old_dy !=dy || old_lx!=lx || old_ly!=ly)
+            {
+                throw IEX_NAMESPACE::ArgExc ("rawTileData read the wrong tile");
+            }
+        }
         pixelData = tileBuffer->buffer;
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
         REPLACE_EXC (e, "Error reading pixel data from image "
 			"file \"" << fileName() << "\". " << e);
@@ -1132,7 +1356,7 @@ int
 TiledInputFile::numLevels () const
 {
     if (levelMode() == RIPMAP_LEVELS)
-	THROW (Iex::LogicExc, "Error calling numLevels() on image "
+	THROW (IEX_NAMESPACE::LogicExc, "Error calling numLevels() on image "
 			      "file \"" << fileName() << "\" "
 			      "(numLevels() is not defined for files "
 			      "with RIPMAP level mode).");
@@ -1179,7 +1403,7 @@ TiledInputFile::levelWidth (int lx) const
         return levelSize (_data->minX, _data->maxX, lx,
 			  _data->tileDesc.roundingMode);
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
 	REPLACE_EXC (e, "Error calling levelWidth() on image "
 			"file \"" << fileName() << "\". " << e);
@@ -1196,7 +1420,7 @@ TiledInputFile::levelHeight (int ly) const
         return levelSize (_data->minY, _data->maxY, ly,
                           _data->tileDesc.roundingMode);
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
 	REPLACE_EXC (e, "Error calling levelHeight() on image "
 			"file \"" << fileName() << "\". " << e);
@@ -1210,8 +1434,8 @@ TiledInputFile::numXTiles (int lx) const
 {
     if (lx < 0 || lx >= _data->numXLevels)
     {
-        THROW (Iex::ArgExc, "Error calling numXTiles() on image "
-			    "file \"" << _data->is->fileName() << "\" "
+        THROW (IEX_NAMESPACE::ArgExc, "Error calling numXTiles() on image "
+			    "file \"" << _data->_streamData->is->fileName() << "\" "
 			    "(Argument is not in valid range).");
 
     }
@@ -1225,8 +1449,8 @@ TiledInputFile::numYTiles (int ly) const
 {
     if (ly < 0 || ly >= _data->numYLevels)
     {
-        THROW (Iex::ArgExc, "Error calling numYTiles() on image "
-			    "file \"" << _data->is->fileName() << "\" "
+        THROW (IEX_NAMESPACE::ArgExc, "Error calling numYTiles() on image "
+			    "file \"" << _data->_streamData->is->fileName() << "\" "
 			    "(Argument is not in valid range).");
     }
     
@@ -1246,12 +1470,13 @@ TiledInputFile::dataWindowForLevel (int lx, int ly) const
 {
     try
     {
-	return Imf::dataWindowForLevel (_data->tileDesc,
-			        	_data->minX, _data->maxX,
-				        _data->minY, _data->maxY,
-				        lx, ly);
+	return OPENEXR_IMF_INTERNAL_NAMESPACE::dataWindowForLevel (
+	        _data->tileDesc,
+	        _data->minX, _data->maxX,
+	        _data->minY, _data->maxY,
+	        lx, ly);
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
 	REPLACE_EXC (e, "Error calling dataWindowForLevel() on image "
 			"file \"" << fileName() << "\". " << e);
@@ -1273,14 +1498,15 @@ TiledInputFile::dataWindowForTile (int dx, int dy, int lx, int ly) const
     try
     {
 	if (!isValidTile (dx, dy, lx, ly))
-	    throw Iex::ArgExc ("Arguments not in valid range.");
+	    throw IEX_NAMESPACE::ArgExc ("Arguments not in valid range.");
 
-        return Imf::dataWindowForTile (_data->tileDesc,
-				       _data->minX, _data->maxX,
-				       _data->minY, _data->maxY,
-				       dx, dy, lx, ly);
+        return OPENEXR_IMF_INTERNAL_NAMESPACE::dataWindowForTile (
+                _data->tileDesc,
+                _data->minX, _data->maxX,
+                _data->minY, _data->maxY,
+                dx, dy, lx, ly);
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
 	REPLACE_EXC (e, "Error calling dataWindowForTile() on image "
 			"file \"" << fileName() << "\". " << e);
@@ -1298,5 +1524,10 @@ TiledInputFile::isValidTile (int dx, int dy, int lx, int ly) const
             (dy < _data->numYTiles[ly] && dy >= 0));
 }
 
+void TiledInputFile::tileOrder(int dx[], int dy[], int lx[], int ly[]) const
+{
+   return _data->tileOffsets.getTileOrder(dx,dy,lx,ly);
+}
+
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfTiledInputFile.h b/Source/OpenEXR/IlmImf/ImfTiledInputFile.h
index 13eb84f..108ec7a 100644
--- a/Source/OpenEXR/IlmImf/ImfTiledInputFile.h
+++ b/Source/OpenEXR/IlmImf/ImfTiledInputFile.h
@@ -42,22 +42,26 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfHeader.h>
-#include <ImfFrameBuffer.h>
+#include "ImfHeader.h"
+#include "ImfFrameBuffer.h"
 #include "ImathBox.h"
-#include <ImfTileDescription.h>
-#include <ImfThreading.h>
+#include "ImfTileDescription.h"
+#include "ImfThreading.h"
+#include "ImfGenericInputFile.h"
+#include "ImfTiledOutputFile.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
-class TiledInputFile
+class IMF_EXPORT TiledInputFile : public GenericInputFile
 {
   public:
 
     //--------------------------------------------------------------------
     // A constructor that opens the file with the specified name, and
-    // reads the file header.  The constructor throws an Iex::ArgExc
+    // reads the file header.  The constructor throws an IEX_NAMESPACE::ArgExc
     // exception if the file is not tiled.
     // The numThreads parameter specifies how many worker threads this
     // file will try to keep busy when decompressing individual tiles.
@@ -77,7 +81,7 @@ class TiledInputFile
     // files.
     // ----------------------------------------------------------
 
-    TiledInputFile (IStream &is, int numThreads = globalThreadCount ());
+    TiledInputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int numThreads = globalThreadCount ());
 
 
     //-----------
@@ -194,7 +198,7 @@ class TiledInputFile
     //      return value is the same as for numXLevels()
     //
     //	if levelMode() == RIPMAP_LEVELS:
-    //      an Iex::LogicExc exception is thrown
+    //      an IEX_NAMESPACE::LogicExc exception is thrown
     //
     // isValidLevel(lx, ly) returns true if the file contains 
     // a level with level number (lx, ly), false if not.
@@ -272,8 +276,8 @@ class TiledInputFile
     //
     //---------------------------------------------------------------
 
-    Imath::Box2i	dataWindowForLevel (int l = 0) const;
-    Imath::Box2i	dataWindowForLevel (int lx, int ly) const;
+    IMATH_NAMESPACE::Box2i	dataWindowForLevel (int l = 0) const;
+    IMATH_NAMESPACE::Box2i	dataWindowForLevel (int lx, int ly) const;
 
 
     //-------------------------------------------------------------------
@@ -297,9 +301,9 @@ class TiledInputFile
     //
     //-------------------------------------------------------------------
 
-    Imath::Box2i	dataWindowForTile (int dx, int dy, int l = 0) const;
+    IMATH_NAMESPACE::Box2i	dataWindowForTile (int dx, int dy, int l = 0) const;
 
-    Imath::Box2i	dataWindowForTile (int dx, int dy,
+    IMATH_NAMESPACE::Box2i	dataWindowForTile (int dx, int dy,
                                            int lx, int ly) const;
 
     //------------------------------------------------------------
@@ -345,6 +349,10 @@ class TiledInputFile
     // Read a tile of raw pixel data from the file,
     // without uncompressing it (this function is
     // used to implement TiledOutputFile::copyPixels()).
+    //
+    // for single part files, reads the next tile in the file
+    // for multipart files, reads the tile specified by dx,dy,lx,ly
+    //
     //--------------------------------------------------
 
     void		rawTileData (int &dx, int &dy,
@@ -357,14 +365,19 @@ class TiledInputFile
   private:
 
     friend class InputFile;
+    friend class MultiPartInputFile;
+
+    TiledInputFile (InputPartData* part);
 
     TiledInputFile (const TiledInputFile &);		  // not implemented
     TiledInputFile & operator = (const TiledInputFile &); // not implemented
 
-    TiledInputFile (const Header &header, IStream *is, int version,
+    TiledInputFile (const Header &header, OPENEXR_IMF_INTERNAL_NAMESPACE::IStream *is, int version,
                     int numThreads);
 
     void		initialize ();
+    void                multiPartInitialize(InputPartData* part);
+    void                compatibilityInitialize(OPENEXR_IMF_INTERNAL_NAMESPACE::IStream& is);
 
     bool		isValidTile (int dx, int dy,
 				     int lx, int ly) const;
@@ -372,10 +385,17 @@ class TiledInputFile
     size_t		bytesPerLineForTile (int dx, int dy,
 					     int lx, int ly) const;
 
+    void                tileOrder(int dx[],int dy[],int lx[],int ly[]) const;
     Data *		_data;
+
+    friend void TiledOutputFile::copyPixels(TiledInputFile &);
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
+
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfTiledInputPart.cpp b/Source/OpenEXR/IlmImf/ImfTiledInputPart.cpp
new file mode 100644
index 0000000..3f89d95
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfTiledInputPart.cpp
@@ -0,0 +1,208 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#include "ImfTiledInputPart.h"
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+TiledInputPart::TiledInputPart(MultiPartInputFile& multiPartFile, int partNumber)
+{
+    file = multiPartFile.getInputPart<TiledInputFile>(partNumber);
+}
+
+const char *
+TiledInputPart::fileName () const
+{
+    return file->fileName();
+}
+
+const Header &
+TiledInputPart::header () const
+{
+    return file->header();
+}
+
+int
+TiledInputPart::version () const
+{
+    return file->version();
+}
+
+void
+TiledInputPart::setFrameBuffer (const FrameBuffer &frameBuffer)
+{
+    file->setFrameBuffer(frameBuffer);
+}
+
+const FrameBuffer &
+TiledInputPart::frameBuffer () const
+{
+    return file->frameBuffer();
+}
+
+bool
+TiledInputPart::isComplete () const
+{
+    return file->isComplete();
+}
+
+unsigned int
+TiledInputPart::tileXSize () const
+{
+    return file->tileXSize();
+}
+
+unsigned int
+TiledInputPart::tileYSize () const
+{
+    return file->tileYSize();
+}
+
+LevelMode
+TiledInputPart::levelMode () const
+{
+    return file->levelMode();
+}
+
+LevelRoundingMode
+TiledInputPart::levelRoundingMode () const
+{
+    return file->levelRoundingMode();
+}
+
+int
+TiledInputPart::numLevels () const
+{
+    return file->numLevels();
+}
+
+int
+TiledInputPart::numXLevels () const
+{
+    return file->numXLevels();
+}
+
+int
+TiledInputPart::numYLevels () const
+{
+    return file->numYLevels();
+}
+
+bool
+TiledInputPart::isValidLevel (int lx, int ly) const
+{
+    return file->isValidLevel(lx, ly);
+}
+
+int
+TiledInputPart::levelWidth  (int lx) const
+{
+    return file->levelWidth(lx);
+}
+
+int
+TiledInputPart::levelHeight (int ly) const
+{
+    return file->levelHeight(ly);
+}
+
+int
+TiledInputPart::numXTiles (int lx) const
+{
+    return file->numXTiles(lx);
+}
+
+int
+TiledInputPart::numYTiles (int ly) const
+{
+    return file->numYTiles(ly);
+}
+
+IMATH_NAMESPACE::Box2i
+TiledInputPart::dataWindowForLevel (int l) const
+{
+    return file->dataWindowForLevel(l);
+}
+
+IMATH_NAMESPACE::Box2i
+TiledInputPart::dataWindowForLevel (int lx, int ly) const
+{
+    return file->dataWindowForLevel(lx, ly);
+}
+
+IMATH_NAMESPACE::Box2i
+TiledInputPart::dataWindowForTile (int dx, int dy, int l) const
+{
+    return file->dataWindowForTile(dx, dy, l);
+}
+
+IMATH_NAMESPACE::Box2i
+TiledInputPart::dataWindowForTile (int dx, int dy, int lx, int ly) const
+{
+    return file->dataWindowForTile(dx, dy, lx, ly);
+}
+
+void
+TiledInputPart::readTile  (int dx, int dy, int l)
+{
+    file->readTile(dx, dy, l);
+}
+
+void
+TiledInputPart::readTile  (int dx, int dy, int lx, int ly)
+{
+    file->readTile(dx, dy, lx, ly);
+}
+
+void
+TiledInputPart::readTiles (int dx1, int dx2, int dy1, int dy2, int lx, int ly)
+{
+    file->readTiles(dx1, dx2, dy1, dy2, lx, ly);
+}
+
+void
+TiledInputPart::readTiles (int dx1, int dx2, int dy1, int dy2, int l)
+{
+    file->readTiles(dx1, dx2, dy1, dy2, l);
+}
+
+void
+TiledInputPart::rawTileData (int &dx, int &dy, int &lx, int &ly,
+             const char *&pixelData, int &pixelDataSize)
+{
+    file->rawTileData(dx, dy, lx, ly, pixelData, pixelDataSize);
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfTiledInputPart.h b/Source/OpenEXR/IlmImf/ImfTiledInputPart.h
new file mode 100644
index 0000000..ea44c02
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfTiledInputPart.h
@@ -0,0 +1,100 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef IMFTILEDINPUTPART_H_
+#define IMFTILEDINPUTPART_H_
+
+#include "ImfMultiPartInputFile.h"
+#include "ImfTiledInputFile.h"
+#include "ImfNamespace.h"
+#include "ImfForward.h"
+#include "ImfExport.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+//-----------------------------------------------------------------------------
+// class TiledInputPart:
+//
+// Same interface as TiledInputFile. Please have a reference to TiledInputFile.
+//-----------------------------------------------------------------------------
+
+class IMF_EXPORT TiledInputPart
+{
+    public:
+        TiledInputPart(MultiPartInputFile& multiPartFile, int partNumber);
+
+        const char *        fileName () const;
+        const Header &      header () const;
+        int                 version () const;
+        void                setFrameBuffer (const FrameBuffer &frameBuffer);
+        const FrameBuffer & frameBuffer () const;
+        bool                isComplete () const;
+        unsigned int        tileXSize () const;
+        unsigned int        tileYSize () const;
+        LevelMode           levelMode () const;
+        LevelRoundingMode   levelRoundingMode () const;
+        int                 numLevels () const;
+        int                 numXLevels () const;
+        int                 numYLevels () const;
+        bool                isValidLevel (int lx, int ly) const;
+        int                 levelWidth  (int lx) const;
+        int                 levelHeight (int ly) const;
+        int                 numXTiles (int lx = 0) const;
+        int                 numYTiles (int ly = 0) const;
+        IMATH_NAMESPACE::Box2i        dataWindowForLevel (int l = 0) const;
+        IMATH_NAMESPACE::Box2i        dataWindowForLevel (int lx, int ly) const;
+        IMATH_NAMESPACE::Box2i        dataWindowForTile (int dx, int dy, int l = 0) const;
+        IMATH_NAMESPACE::Box2i        dataWindowForTile (int dx, int dy,
+                                               int lx, int ly) const;
+        void                readTile  (int dx, int dy, int l = 0);
+        void                readTile  (int dx, int dy, int lx, int ly);
+        void                readTiles (int dx1, int dx2, int dy1, int dy2,
+                                       int lx, int ly);
+        void                readTiles (int dx1, int dx2, int dy1, int dy2,
+                                       int l = 0);
+        void                rawTileData (int &dx, int &dy,
+                                         int &lx, int &ly,
+                                         const char *&pixelData,
+                                         int &pixelDataSize);
+
+    private:
+        TiledInputFile* file;
+      // for internal use - allow TiledOutputFile access to file for copyPixels
+      friend class TiledOutputFile;
+      
+};
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif /* IMFTILEDINPUTPART_H_ */
diff --git a/Source/OpenEXR/IlmImf/ImfTiledMisc.cpp b/Source/OpenEXR/IlmImf/ImfTiledMisc.cpp
index 7c723bb..d72d823 100644
--- a/Source/OpenEXR/IlmImf/ImfTiledMisc.cpp
+++ b/Source/OpenEXR/IlmImf/ImfTiledMisc.cpp
@@ -43,19 +43,22 @@
 #include "Iex.h"
 #include <ImfMisc.h>
 #include <ImfChannelList.h>
+#include <ImfTileDescription.h>
+#include <algorithm>
 
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
-using Imath::Box2i;
-using Imath::V2i;
+using IMATH_NAMESPACE::Box2i;
+using IMATH_NAMESPACE::V2i;
 
 
 int
 levelSize (int min, int max, int l, LevelRoundingMode rmode)
 {
     if (l < 0)
-	throw Iex::ArgExc ("Argument not in valid range.");
+	throw IEX_NAMESPACE::ArgExc ("Argument not in valid range.");
 
     int a = max - min + 1;
     int b = (1 << l);
@@ -124,6 +127,40 @@ calculateBytesPerPixel (const Header &header)
 }
 
 
+void
+calculateBytesPerLine (const Header &header,
+                       char* sampleCountBase,
+                       int sampleCountXStride,
+                       int sampleCountYStride,
+                       int minX, int maxX,
+                       int minY, int maxY,
+                       std::vector<int>& xOffsets,
+                       std::vector<int>& yOffsets,
+                       std::vector<Int64>& bytesPerLine)
+{
+    const ChannelList &channels = header.channels();
+
+    int pos = 0;
+    for (ChannelList::ConstIterator c = channels.begin();
+         c != channels.end();
+         ++c, ++pos)
+    {
+        int xOffset = xOffsets[pos];
+        int yOffset = yOffsets[pos];
+        int i = 0;
+        for (int y = minY - yOffset; y <= maxY - yOffset; y++, i++)
+            for (int x = minX - xOffset; x <= maxX - xOffset; x++)
+            {
+                bytesPerLine[i] += sampleCount(sampleCountBase,
+                                               sampleCountXStride,
+                                               sampleCountYStride,
+                                               x, y)
+                                   * pixelTypeSize (c.channel().type);
+            }
+    }
+}
+
+
 namespace {
 
 int
@@ -208,7 +245,7 @@ calculateNumXLevels (const TileDescription& tileDesc,
 
       default:
 
-	throw Iex::ArgExc ("Unknown LevelMode format.");
+	throw IEX_NAMESPACE::ArgExc ("Unknown LevelMode format.");
     }
 
     return num;
@@ -248,7 +285,7 @@ calculateNumYLevels (const TileDescription& tileDesc,
 
       default:
 
-	throw Iex::ArgExc ("Unknown LevelMode format.");
+	throw IEX_NAMESPACE::ArgExc ("Unknown LevelMode format.");
     }
 
     return num;
@@ -298,4 +335,55 @@ precalculateTileInfo (const TileDescription& tileDesc,
 }
 
 
-} // namespace Imf
+int
+getTiledChunkOffsetTableSize(const Header& header)
+{
+    //
+    // Save the dataWindow information
+    //
+
+    const Box2i &dataWindow = header.dataWindow();
+    
+    //
+    // Precompute level and tile information.
+    //
+
+    int* numXTiles;
+    int* numYTiles;
+    int numXLevels;
+    int numYLevels;
+    precalculateTileInfo (header.tileDescription(),
+                          dataWindow.min.x, dataWindow.max.x,
+                          dataWindow.min.y, dataWindow.max.y,
+                          numXTiles, numYTiles,
+                          numXLevels, numYLevels);
+
+    //
+    // Calculate lineOffsetSize.
+    //
+    int lineOffsetSize = 0;
+    const TileDescription &desc = header.tileDescription();
+    switch (desc.mode)
+    {
+        case ONE_LEVEL:
+        case MIPMAP_LEVELS:
+            for (int i = 0; i < numXLevels; i++)
+                lineOffsetSize += numXTiles[i] * numYTiles[i];
+            break;
+        case RIPMAP_LEVELS:
+            for (int i = 0; i < numXLevels; i++)
+                for (int j = 0; j < numYLevels; j++)
+                    lineOffsetSize += numXTiles[i] * numYTiles[j];
+            break;
+        case NUM_LEVELMODES :
+            throw IEX_NAMESPACE::LogicExc("Bad level mode getting chunk offset table size");
+    }
+
+    delete[] numXTiles;
+    delete[] numYTiles;
+
+    return lineOffsetSize;
+}
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfTiledMisc.h b/Source/OpenEXR/IlmImf/ImfTiledMisc.h
index 9342c6f..2696663 100644
--- a/Source/OpenEXR/IlmImf/ImfTiledMisc.h
+++ b/Source/OpenEXR/IlmImf/ImfTiledMisc.h
@@ -43,33 +43,64 @@
 //-----------------------------------------------------------------------------
 
 #include "ImathBox.h"
-#include <ImfHeader.h>
+#include "ImfHeader.h"
+#include "ImfNamespace.h"
+
 #include <stdio.h>
+#include <vector>
+
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
+IMF_EXPORT 
 int levelSize (int min, int max, int l, LevelRoundingMode rmode);
 
-Imath::Box2i dataWindowForLevel (const TileDescription &tileDesc,
+IMF_EXPORT 
+IMATH_NAMESPACE::Box2i dataWindowForLevel (const TileDescription &tileDesc,
 				 int minX, int maxX,
 				 int minY, int maxY,
 				 int lx, int ly);
 
-Imath::Box2i dataWindowForTile (const TileDescription &tileDesc,
+IMF_EXPORT 
+IMATH_NAMESPACE::Box2i dataWindowForTile (const TileDescription &tileDesc,
 				int minX, int maxX,
 				int minY, int maxY,
 				int dx, int dy,
 				int lx, int ly);
 
+IMF_EXPORT 
 size_t calculateBytesPerPixel (const Header &header);
 
+//
+// Calculate the count of bytes for each lines in range [minY, maxY],
+// and pixels in range [minX, maxX].
+// Data will be saved in bytesPerLine.
+// sampleCountBase, sampleCountXStride and sampleCountYStride are
+// used to get the sample count values.
+//
+
+IMF_EXPORT 
+void calculateBytesPerLine (const Header &header,
+                            char* sampleCountBase,
+                            int sampleCountXStride,
+                            int sampleCountYStride,
+                            int minX, int maxX,
+                            int minY, int maxY,
+                            std::vector<int>& xOffsets,
+                            std::vector<int>& yOffsets,
+                            std::vector<Int64>& bytesPerLine);
+
+IMF_EXPORT 
 void precalculateTileInfo (const TileDescription& tileDesc,
 			   int minX, int maxX,
 			   int minY, int maxY,
 			   int *&numXTiles, int *&numYTiles,
 			   int &numXLevels, int &numYLevels);
 
+IMF_EXPORT 
+int getTiledChunkOffsetTableSize(const Header& header);
+
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfTiledOutputFile.cpp b/Source/OpenEXR/IlmImf/ImfTiledOutputFile.cpp
index 9a96ac9..3a17561 100644
--- a/Source/OpenEXR/IlmImf/ImfTiledOutputFile.cpp
+++ b/Source/OpenEXR/IlmImf/ImfTiledOutputFile.cpp
@@ -40,7 +40,9 @@
 
 #include <ImfTiledOutputFile.h>
 #include <ImfTiledInputFile.h>
+#include <ImfTiledInputPart.h>
 #include <ImfInputFile.h>
+#include <ImfInputPart.h>
 #include <ImfTileDescriptionAttribute.h>
 #include <ImfPreviewImageAttribute.h>
 #include <ImfChannelList.h>
@@ -54,21 +56,27 @@
 #include <ImfVersion.h>
 #include <ImfTileOffsets.h>
 #include <ImfThreading.h>
+#include <ImfPartType.h>
 #include "IlmThreadPool.h"
 #include "IlmThreadSemaphore.h"
 #include "IlmThreadMutex.h"
+#include "ImfOutputStreamMutex.h"
+#include "ImfOutputPartData.h"
 #include "Iex.h"
 #include <string>
 #include <vector>
 #include <fstream>
 #include <assert.h>
 #include <map>
+#include <algorithm>
 
+#include "ImfNamespace.h"
 
-namespace Imf {
 
-using Imath::Box2i;
-using Imath::V2i;
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+using IMATH_NAMESPACE::Box2i;
+using IMATH_NAMESPACE::V2i;
 using std::string;
 using std::vector;
 using std::ofstream;
@@ -76,12 +84,12 @@ using std::map;
 using std::min;
 using std::max;
 using std::swap;
-using IlmThread::Mutex;
-using IlmThread::Lock;
-using IlmThread::Semaphore;
-using IlmThread::Task;
-using IlmThread::TaskGroup;
-using IlmThread::ThreadPool;
+using ILMTHREAD_NAMESPACE::Mutex;
+using ILMTHREAD_NAMESPACE::Lock;
+using ILMTHREAD_NAMESPACE::Semaphore;
+using ILMTHREAD_NAMESPACE::Task;
+using ILMTHREAD_NAMESPACE::TaskGroup;
+using ILMTHREAD_NAMESPACE::ThreadPool;
 
 namespace {
 
@@ -229,10 +237,11 @@ TileBuffer::~TileBuffer ()
 } // namespace
 
 
-struct TiledOutputFile::Data: public Mutex
+struct TiledOutputFile::Data
 {
     Header		header;			// the image header
     int			version;		// file format version
+    bool                multipart;              // part came from a multipart file
     TileDescription	tileDesc;		// describes the tile layout
     FrameBuffer		frameBuffer;		// framebuffer to write into
     Int64		previewPosition;
@@ -252,8 +261,6 @@ struct TiledOutputFile::Data: public Mutex
 
     Compressor::Format	format;			// compressor's data format
     vector<TOutSliceInfo> slices;		// info about channels in file
-    OStream *		os;			// file stream to write to
-    bool		deleteStream;
 
     size_t		maxBytesPerTileLine;	// combined size of a tile line
 						// over all channels
@@ -263,12 +270,13 @@ struct TiledOutputFile::Data: public Mutex
     size_t		tileBufferSize;         // size of a tile buffer
 
     Int64		tileOffsetsPosition;	// position of the tile index
-    Int64		currentPosition;	// current position in the file
     
     TileMap		tileMap;
     TileCoord		nextTileToWrite;
 
-     Data (bool del, int numThreads);
+    int                 partNumber;             // the output part number
+
+     Data (int numThreads);
     ~Data ();
     
     inline TileBuffer *	getTileBuffer (int number);
@@ -280,12 +288,12 @@ struct TiledOutputFile::Data: public Mutex
 };
 
 
-TiledOutputFile::Data::Data (bool del, int numThreads):
+TiledOutputFile::Data::Data (int numThreads):
+    multipart(false),
     numXTiles(0),
     numYTiles(0),
-    os (0),
-    deleteStream (del),
-    tileOffsetsPosition (0)
+    tileOffsetsPosition (0),
+    partNumber(-1)
 {
     //
     // We need at least one tileBuffer, but if threading is used,
@@ -301,9 +309,6 @@ TiledOutputFile::Data::~Data ()
     delete [] numXTiles;
     delete [] numYTiles;
 
-    if (deleteStream)
-	delete os;
-    
     //
     // Delete all the tile buffers, if any still happen to exist
     //
@@ -368,6 +373,9 @@ TiledOutputFile::Data::nextTileCoord (const TileCoord &a)
 			#endif
                     }
                     break;
+                  case  NUM_LEVELMODES:
+                      throw(IEX_NAMESPACE::ArgExc("Invalid tile description"));
+                      
                 }
             }
         }
@@ -410,6 +418,9 @@ TiledOutputFile::Data::nextTileCoord (const TileCoord &a)
 			#endif
                     }
                     break;
+                  case  NUM_LEVELMODES:
+                      throw(IEX_NAMESPACE::ArgExc("Invalid tile description"));
+                      
                 }
 
 		if (b.ly < numYLevels)
@@ -425,7 +436,8 @@ TiledOutputFile::Data::nextTileCoord (const TileCoord &a)
 namespace {
 
 void
-writeTileData (TiledOutputFile::Data *ofd,
+writeTileData (OutputStreamMutex *streamData,
+               TiledOutputFile::Data *ofd,
                int dx, int dy,
 	       int lx, int ly, 
                const char pixelData[],
@@ -437,44 +449,54 @@ writeTileData (TiledOutputFile::Data *ofd,
     // without calling tellp() (tellp() can be fairly expensive).
     //
 
-    Int64 currentPosition = ofd->currentPosition;
-    ofd->currentPosition = 0;
+    Int64 currentPosition = streamData->currentPosition;
+    streamData->currentPosition = 0;
 
     if (currentPosition == 0)
-        currentPosition = ofd->os->tellp();
+        currentPosition = streamData->os->tellp();
 
     ofd->tileOffsets (dx, dy, lx, ly) = currentPosition;
 
     #ifdef DEBUG
-	assert (ofd->os->tellp() == currentPosition);
+	assert (streamData->os->tellp() == currentPosition);
     #endif
 
     //
     // Write the tile header.
     //
 
-    Xdr::write <StreamIO> (*ofd->os, dx);
-    Xdr::write <StreamIO> (*ofd->os, dy);
-    Xdr::write <StreamIO> (*ofd->os, lx);
-    Xdr::write <StreamIO> (*ofd->os, ly);
-    Xdr::write <StreamIO> (*ofd->os, pixelDataSize);
+    if (ofd->multipart)
+    {
+        Xdr::write <StreamIO> (*streamData->os, ofd->partNumber);
+    }
+    Xdr::write <StreamIO> (*streamData->os, dx);
+    Xdr::write <StreamIO> (*streamData->os, dy);
+    Xdr::write <StreamIO> (*streamData->os, lx);
+    Xdr::write <StreamIO> (*streamData->os, ly);
+    Xdr::write <StreamIO> (*streamData->os, pixelDataSize);
 
-    ofd->os->write (pixelData, pixelDataSize);    
+    streamData->os->write (pixelData, pixelDataSize);
 
     //
     // Keep current position in the file so that we can avoid 
     // redundant seekg() operations (seekg() can be fairly expensive).
     //
 
-    ofd->currentPosition = currentPosition +
+    streamData->currentPosition = currentPosition +
                            5 * Xdr::size<int>() +
                            pixelDataSize;
+
+    if (ofd->multipart)
+    {
+        streamData->currentPosition += Xdr::size<int>();
+    }
 }
 
 
 
 void
-bufferedTileWrite (TiledOutputFile::Data *ofd,
+bufferedTileWrite (OutputStreamMutex *streamData,
+                   TiledOutputFile::Data *ofd,
                    int dx, int dy,
 		   int lx, int ly, 
                    const char pixelData[],
@@ -486,9 +508,9 @@ bufferedTileWrite (TiledOutputFile::Data *ofd,
 
     if (ofd->tileOffsets (dx, dy, lx, ly))
     {
-	THROW (Iex::ArgExc,
+	THROW (IEX_NAMESPACE::ArgExc,
 	       "Attempt to write tile "
-	       "(" << dx << ", " << dy << ", " << lx << "," << ly << ") "
+	       "(" << dx << ", " << dy << ", " << lx << ", " << ly << ") "
 	       "more than once.");
     }
 
@@ -498,7 +520,7 @@ bufferedTileWrite (TiledOutputFile::Data *ofd,
     
     if (ofd->lineOrder == RANDOM_Y)
     {
-        writeTileData (ofd, dx, dy, lx, ly, pixelData, pixelDataSize);
+        writeTileData (streamData, ofd, dx, dy, lx, ly, pixelData, pixelDataSize);
         return;
     }
     
@@ -511,9 +533,9 @@ bufferedTileWrite (TiledOutputFile::Data *ofd,
 
     if (ofd->tileMap.find (currentTile) != ofd->tileMap.end())
     {
-	THROW (Iex::ArgExc,
+	THROW (IEX_NAMESPACE::ArgExc,
 	       "Attempt to write tile "
-	       "(" << dx << ", " << dy << ", " << lx << "," << ly << ") "
+	       "(" << dx << ", " << dy << ", " << lx << ", " << ly << ") "
 	       "more than once.");
     }
 
@@ -527,7 +549,7 @@ bufferedTileWrite (TiledOutputFile::Data *ofd,
     
     if (ofd->nextTileToWrite == currentTile)
     {
-        writeTileData (ofd, dx, dy, lx, ly, pixelData, pixelDataSize);        
+        writeTileData (streamData, ofd, dx, dy, lx, ly, pixelData, pixelDataSize);
         ofd->nextTileToWrite = ofd->nextTileCoord (ofd->nextTileToWrite);
 
         TileMap::iterator i = ofd->tileMap.find (ofd->nextTileToWrite);
@@ -543,7 +565,8 @@ bufferedTileWrite (TiledOutputFile::Data *ofd,
             // Write the tile, and then delete the tile's buffered data
             //
 
-            writeTileData (ofd,
+            writeTileData (streamData,
+                           ofd,
 			   i->first.dx, i->first.dy,
 			   i->first.lx, i->first.ly,
 			   i->second->pixelData,
@@ -704,7 +727,7 @@ TileBufferTask::execute ()
     
         char *writePtr = _tileBuffer->buffer;
     
-        Box2i tileRange = Imf::dataWindowForTile (_ofd->tileDesc,
+        Box2i tileRange = dataWindowForTile (_ofd->tileDesc,
                                                   _ofd->minX, _ofd->maxX,
                                                   _ofd->minY, _ofd->maxY,
                                                   _tileBuffer->tileCoord.dx,
@@ -834,16 +857,26 @@ TiledOutputFile::TiledOutputFile
      const Header &header,
      int numThreads)
 :
-    _data (new Data (true, numThreads))
+    _data (new Data (numThreads)),
+    _streamData (new OutputStreamMutex()),
+    _deleteStream (true)
 {
     try
     {
 	header.sanityCheck (true);
-	_data->os = new StdOFStream (fileName);
+	_streamData->os = new StdOFStream (fileName);
+        _data->multipart=false; // since we opened with one header we can't be multipart        
 	initialize (header);
+	_streamData->currentPosition = _streamData->os->tellp();
+
+	// Write header and empty offset table to the file.
+        writeMagicNumberAndVersionField(*_streamData->os, _data->header);
+	_data->previewPosition = _data->header.writeTo (*_streamData->os, true);
+        _data->tileOffsetsPosition = _data->tileOffsets.writeTo (*_streamData->os);
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
+        delete _streamData;
 	delete _data;
 
 	REPLACE_EXC (e, "Cannot open image file "
@@ -852,6 +885,7 @@ TiledOutputFile::TiledOutputFile
     }
     catch (...)
     {
+        delete _streamData;
 	delete _data;
         throw;
     }
@@ -859,20 +893,31 @@ TiledOutputFile::TiledOutputFile
 
 
 TiledOutputFile::TiledOutputFile
-    (OStream &os,
+    (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
      const Header &header,
      int numThreads)
 :
-    _data (new Data (false, numThreads))
+    _data (new Data (numThreads)),
+    _streamData (new OutputStreamMutex()),
+    _deleteStream (false)
 {
     try
     {
 	header.sanityCheck(true);
-	_data->os = &os;
+	_streamData->os = &os;
+        _data->multipart=false; // since we opened with one header we can't be multipart
 	initialize (header);
+	_streamData->currentPosition = _streamData->os->tellp();
+
+	// Write header and empty offset table to the file.
+	writeMagicNumberAndVersionField(*_streamData->os, _data->header);
+	_data->previewPosition = _data->header.writeTo (*_streamData->os, true);
+        _data->tileOffsetsPosition = _data->tileOffsets.writeTo (*_streamData->os);
+	
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
+        delete _streamData;
 	delete _data;
 
 	REPLACE_EXC (e, "Cannot open image file "
@@ -881,11 +926,42 @@ TiledOutputFile::TiledOutputFile
     }
     catch (...)
     {
+        delete _streamData;
 	delete _data;
         throw;
     }
 }
 
+TiledOutputFile::TiledOutputFile(const OutputPartData* part) :
+    _deleteStream (false)
+{
+    try
+    {
+        if (part->header.type() != TILEDIMAGE)
+            throw IEX_NAMESPACE::ArgExc("Can't build a TiledOutputFile from a type-mismatched part.");
+
+        _streamData = part->mutex;
+        _data = new Data(part->numThreads);
+        _data->multipart=part->multipart;
+        initialize(part->header);
+        _data->partNumber = part->partNumber;
+        _data->tileOffsetsPosition = part->chunkOffsetTablePosition;
+        _data->previewPosition = part->previewPosition;
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        delete _data;
+
+        REPLACE_EXC (e, "Cannot initialize output part "
+                        "\"" << part->partNumber << "\". " << e);
+        throw;
+    }
+    catch (...)
+    {
+        delete _data;
+        throw;
+    }
+}
 
 void
 TiledOutputFile::initialize (const Header &header)
@@ -893,12 +969,25 @@ TiledOutputFile::initialize (const Header &header)
     _data->header = header;
     _data->lineOrder = _data->header.lineOrder();
 
+    
+    
     //
     // Check that the file is indeed tiled
     //
 
     _data->tileDesc = _data->header.tileDescription();
 
+    
+    //
+    // 'Fix' the type attribute if it exists but is incorrectly set
+    // (attribute is optional, but ensure it is correct if it exists)
+    //
+    if(_data->header.hasType())
+    {
+        _data->header.setType(TILEDIMAGE);
+    }
+
+    
     //
     // Save the dataWindow information
     //
@@ -932,7 +1021,7 @@ TiledOutputFile::initialize (const Header &header)
 	    calculateBytesPerPixel (_data->header) * _data->tileDesc.xSize;
 
     _data->tileBufferSize = _data->maxBytesPerTileLine * _data->tileDesc.ySize;
-    
+     
     //
     // Create all the TileBuffers and allocate their internal buffers
     //
@@ -955,11 +1044,6 @@ TiledOutputFile::initialize (const Header &header)
 				      _data->numYLevels,
 				      _data->numXTiles,
 				      _data->numYTiles);
-
-    _data->previewPosition = _data->header.writeTo (*_data->os, true);
-
-    _data->tileOffsetsPosition = _data->tileOffsets.writeTo (*_data->os);
-    _data->currentPosition = _data->os->tellp();
 }
 
 
@@ -968,12 +1052,20 @@ TiledOutputFile::~TiledOutputFile ()
     if (_data)
     {
         {
+            Lock lock(*_streamData);
+            Int64 originalPosition = _streamData->os->tellp();
+
             if (_data->tileOffsetsPosition > 0)
             {
                 try
                 {
-                    _data->os->seekp (_data->tileOffsetsPosition);
-                    _data->tileOffsets.writeTo (*_data->os);
+                    _streamData->os->seekp (_data->tileOffsetsPosition);
+                    _data->tileOffsets.writeTo (*_streamData->os);
+
+                    //
+                    // Restore the original position.
+                    //
+                    _streamData->os->seekp (originalPosition);
                 }
                 catch (...)
                 {
@@ -987,6 +1079,12 @@ TiledOutputFile::~TiledOutputFile ()
             }
         }
         
+        if (_deleteStream && _streamData)
+            delete _streamData->os;
+
+        if (_data->partNumber == -1)
+            delete _streamData;
+
         delete _data;
     }
 }
@@ -995,7 +1093,7 @@ TiledOutputFile::~TiledOutputFile ()
 const char *
 TiledOutputFile::fileName () const
 {
-    return _data->os->fileName();
+    return _streamData->os->fileName();
 }
 
 
@@ -1009,7 +1107,7 @@ TiledOutputFile::header () const
 void	
 TiledOutputFile::setFrameBuffer (const FrameBuffer &frameBuffer)
 {
-    Lock lock (*_data);
+    Lock lock (*_streamData);
 
     //
     // Check if the new frame buffer descriptor
@@ -1028,13 +1126,13 @@ TiledOutputFile::setFrameBuffer (const FrameBuffer &frameBuffer)
 	    continue;
 
 	if (i.channel().type != j.slice().type)
-	    THROW (Iex::ArgExc, "Pixel type of \"" << i.name() << "\" channel "
+	    THROW (IEX_NAMESPACE::ArgExc, "Pixel type of \"" << i.name() << "\" channel "
 				"of output file \"" << fileName() << "\" is "
 				"not compatible with the frame buffer's "
 				"pixel type.");
 
 	if (j.slice().xSampling != 1 || j.slice().ySampling != 1)
-	    THROW (Iex::ArgExc, "All channels in a tiled file must have"
+	    THROW (IEX_NAMESPACE::ArgExc, "All channels in a tiled file must have"
 				"sampling (1,1).");
     }
     
@@ -1091,7 +1189,7 @@ TiledOutputFile::setFrameBuffer (const FrameBuffer &frameBuffer)
 const FrameBuffer &
 TiledOutputFile::frameBuffer () const
 {
-    Lock lock (*_data);
+    Lock lock (*_streamData);
     return _data->frameBuffer;
 }
 
@@ -1102,15 +1200,20 @@ TiledOutputFile::writeTiles (int dx1, int dx2, int dy1, int dy2,
 {
     try
     {
-        Lock lock (*_data);
+        Lock lock (*_streamData);
 
         if (_data->slices.size() == 0)
-	    throw Iex::ArgExc ("No frame buffer specified "
+	    throw IEX_NAMESPACE::ArgExc ("No frame buffer specified "
 			       "as pixel data source.");
 
 	if (!isValidTile (dx1, dy1, lx, ly) || !isValidTile (dx2, dy2, lx, ly))
-	    throw Iex::ArgExc ("Tile coordinates are invalid.");
+	    throw IEX_NAMESPACE::ArgExc ("Tile coordinates are invalid.");
 
+	if (!isValidLevel (lx, ly))
+	    THROW (IEX_NAMESPACE::ArgExc,
+                   "Level coordinate "
+                   "(" << lx << ", " << ly << ") "
+                   "is invalid.");
         //
         // Determine the first and last tile coordinates in both dimensions
         // based on the file's lineOrder
@@ -1193,7 +1296,7 @@ TiledOutputFile::writeTiles (int dx1, int dx2, int dy1, int dy2,
                 // Write the tilebuffer
 		//
 
-                bufferedTileWrite (_data, dxWrite, dyWrite, lx, ly,
+                bufferedTileWrite (_streamData, _data, dxWrite, dyWrite, lx, ly,
                                    writeBuffer->dataPtr,
                                    writeBuffer->dataSize);
                 
@@ -1264,7 +1367,7 @@ TiledOutputFile::writeTiles (int dx1, int dx2, int dy1, int dy2,
 
 	const string *exception = 0;
 
-        for (int i = 0; i < _data->tileBuffers.size(); ++i)
+        for (size_t i = 0; i < _data->tileBuffers.size(); ++i)
 	{
             TileBuffer *tileBuffer = _data->tileBuffers[i];
 
@@ -1275,9 +1378,9 @@ TiledOutputFile::writeTiles (int dx1, int dx2, int dy1, int dy2,
 	}
 
 	if (exception)
-	    throw Iex::IoExc (*exception);
+	    throw IEX_NAMESPACE::IoExc (*exception);
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
         REPLACE_EXC (e, "Failed to write pixel data to image "
                         "file \"" << fileName() << "\". " << e);
@@ -1310,7 +1413,7 @@ TiledOutputFile::writeTile (int dx, int dy, int l)
 void	
 TiledOutputFile::copyPixels (TiledInputFile &in)
 {
-    Lock lock (*_data);
+    Lock lock (*_streamData);
 
     //
     // Check if this file's and and the InputFile's
@@ -1321,38 +1424,38 @@ TiledOutputFile::copyPixels (TiledInputFile &in)
     const Header &inHdr = in.header(); 
 
     if (!hdr.hasTileDescription() || !inHdr.hasTileDescription())
-        THROW (Iex::ArgExc, "Cannot perform a quick pixel copy from image "
+        THROW (IEX_NAMESPACE::ArgExc, "Cannot perform a quick pixel copy from image "
 			    "file \"" << in.fileName() << "\" to image "
 			    "file \"" << fileName() << "\".  The "
                             "output file is tiled, but the input file is not.  "
                             "Try using OutputFile::copyPixels() instead.");
 
     if (!(hdr.tileDescription() == inHdr.tileDescription()))
-        THROW (Iex::ArgExc, "Quick pixel copy from image "
+        THROW (IEX_NAMESPACE::ArgExc, "Quick pixel copy from image "
 			    "file \"" << in.fileName() << "\" to image "
 			    "file \"" << fileName() << "\" failed. "
 			    "The files have different tile descriptions.");
 
     if (!(hdr.dataWindow() == inHdr.dataWindow()))
-        THROW (Iex::ArgExc, "Cannot copy pixels from image "
+        THROW (IEX_NAMESPACE::ArgExc, "Cannot copy pixels from image "
 			    "file \"" << in.fileName() << "\" to image "
 			    "file \"" << fileName() << "\". The "
                             "files have different data windows.");
 
     if (!(hdr.lineOrder() == inHdr.lineOrder()))
-        THROW (Iex::ArgExc, "Quick pixel copy from image "
+        THROW (IEX_NAMESPACE::ArgExc, "Quick pixel copy from image "
 			    "file \"" << in.fileName() << "\" to image "
 			    "file \"" << fileName() << "\" failed. "
 			    "The files have different line orders.");
 
     if (!(hdr.compression() == inHdr.compression()))
-        THROW (Iex::ArgExc, "Quick pixel copy from image "
+        THROW (IEX_NAMESPACE::ArgExc, "Quick pixel copy from image "
 			    "file \"" << in.fileName() << "\" to image "
 			    "file \"" << fileName() << "\" failed. "
 			    "The files use different compression methods.");
 
     if (!(hdr.channels() == inHdr.channels()))
-        THROW (Iex::ArgExc, "Quick pixel copy from image "
+        THROW (IEX_NAMESPACE::ArgExc, "Quick pixel copy from image "
 			     "file \"" << in.fileName() << "\" to image "
 			     "file \"" << fileName() << "\" "
                              "failed.  The files have different channel "
@@ -1363,9 +1466,9 @@ TiledOutputFile::copyPixels (TiledInputFile &in)
     //
 
     if (!_data->tileOffsets.isEmpty())
-        THROW (Iex::LogicExc, "Quick pixel copy from image "
+        THROW (IEX_NAMESPACE::LogicExc, "Quick pixel copy from image "
 			      "file \"" << in.fileName() << "\" to image "
-			      "file \"" << _data->os->fileName() << "\" "
+			      "file \"" << _streamData->os->fileName() << "\" "
                               "failed. \"" << fileName() << "\" "
                               "already contains pixel data.");
 
@@ -1380,22 +1483,38 @@ TiledOutputFile::copyPixels (TiledInputFile &in)
       case ONE_LEVEL:
       case MIPMAP_LEVELS:
 
-        for (size_t i_l = 0; i_l < numLevels (); ++i_l)
+        for (int i_l = 0; i_l < numLevels (); ++i_l)
             numAllTiles += numXTiles (i_l) * numYTiles (i_l);
 
         break;
 
       case RIPMAP_LEVELS:
 
-        for (size_t i_ly = 0; i_ly < numYLevels (); ++i_ly)
-            for (size_t i_lx = 0; i_lx < numXLevels (); ++i_lx)
+        for (int i_ly = 0; i_ly < numYLevels (); ++i_ly)
+            for (int i_lx = 0; i_lx < numXLevels (); ++i_lx)
                 numAllTiles += numXTiles (i_lx) * numYTiles (i_ly);
 
         break;
 
       default:
 
-        throw Iex::ArgExc ("Unknown LevelMode format.");
+        throw IEX_NAMESPACE::ArgExc ("Unknown LevelMode format.");
+    }
+
+     bool random_y = _data->lineOrder==RANDOM_Y;
+
+    std::vector<int> dx_table(random_y ? numAllTiles : 1);
+    std::vector<int> dy_table(random_y ? numAllTiles : 1);
+    std::vector<int> lx_table(random_y ? numAllTiles : 1);
+    std::vector<int> ly_table(random_y ? numAllTiles : 1);
+    
+    if(random_y)
+    {
+        in.tileOrder(&dx_table[0],&dy_table[0],&lx_table[0],&ly_table[0]);
+        _data->nextTileToWrite.dx=dx_table[0];
+        _data->nextTileToWrite.dy=dy_table[0];
+        _data->nextTileToWrite.lx=lx_table[0];
+        _data->nextTileToWrite.ly=ly_table[0];
     }
 
     for (int i = 0; i < numAllTiles; ++i)
@@ -1408,8 +1527,22 @@ TiledOutputFile::copyPixels (TiledInputFile &in)
         int lx = _data->nextTileToWrite.lx;
         int ly = _data->nextTileToWrite.ly;
 
+        
         in.rawTileData (dx, dy, lx, ly, pixelData, pixelDataSize);
-        writeTileData (_data, dx, dy, lx, ly, pixelData, pixelDataSize);
+        writeTileData (_streamData, _data, dx, dy, lx, ly, pixelData, pixelDataSize);
+        
+        if(random_y)
+        {
+            if(i<numAllTiles-1)
+            {
+               _data->nextTileToWrite.dx=dx_table[i+1];
+               _data->nextTileToWrite.dy=dy_table[i+1];
+               _data->nextTileToWrite.lx=lx_table[i+1];
+               _data->nextTileToWrite.ly=ly_table[i+1];
+            }
+        }else{
+            _data->nextTileToWrite=_data->nextTileCoord(_data->nextTileToWrite);
+        }
     }
 }
 
@@ -1421,6 +1554,20 @@ TiledOutputFile::copyPixels (InputFile &in)
 }
 
 
+void    
+TiledOutputFile::copyPixels (InputPart &in)
+{
+    copyPixels (*in.file);
+}
+
+void    
+TiledOutputFile::copyPixels (TiledInputPart &in)
+{
+    copyPixels (*in.file);
+}
+
+
+
 unsigned int
 TiledOutputFile::tileXSize () const
 {
@@ -1453,7 +1600,7 @@ int
 TiledOutputFile::numLevels () const
 {
     if (levelMode() == RIPMAP_LEVELS)
-	THROW (Iex::LogicExc, "Error calling numLevels() on image "
+	THROW (IEX_NAMESPACE::LogicExc, "Error calling numLevels() on image "
 			      "file \"" << fileName() << "\" "
 			      "(numLevels() is not defined for RIPMAPs).");
     return _data->numXLevels;
@@ -1500,7 +1647,7 @@ TiledOutputFile::levelWidth (int lx) const
         
         return retVal;
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
 	REPLACE_EXC (e, "Error calling levelWidth() on image "
 			"file \"" << fileName() << "\". " << e);
@@ -1517,7 +1664,7 @@ TiledOutputFile::levelHeight (int ly) const
 	return levelSize (_data->minY, _data->maxY, ly,
 			  _data->tileDesc.roundingMode);
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
 	REPLACE_EXC (e, "Error calling levelHeight() on image "
 			"file \"" << fileName() << "\". " << e);
@@ -1530,8 +1677,8 @@ int
 TiledOutputFile::numXTiles (int lx) const
 {
     if (lx < 0 || lx >= _data->numXLevels)
-	THROW (Iex::LogicExc, "Error calling numXTiles() on image "
-			      "file \"" << _data->os->fileName() << "\" "
+	THROW (IEX_NAMESPACE::LogicExc, "Error calling numXTiles() on image "
+			      "file \"" << _streamData->os->fileName() << "\" "
 			      "(Argument is not in valid range).");
 
     return _data->numXTiles[lx];
@@ -1542,8 +1689,8 @@ int
 TiledOutputFile::numYTiles (int ly) const
 {
    if (ly < 0 || ly >= _data->numYLevels)
-	THROW (Iex::LogicExc, "Error calling numXTiles() on image "
-			      "file \"" << _data->os->fileName() << "\" "
+	THROW (IEX_NAMESPACE::LogicExc, "Error calling numXTiles() on image "
+			      "file \"" << _streamData->os->fileName() << "\" "
 			      "(Argument is not in valid range).");
 
     return _data->numYTiles[ly];
@@ -1562,12 +1709,13 @@ TiledOutputFile::dataWindowForLevel (int lx, int ly) const
 {
     try
     {
-	return Imf::dataWindowForLevel (_data->tileDesc,
-			        	_data->minX, _data->maxX,
-				        _data->minY, _data->maxY,
-					lx, ly);
+	return OPENEXR_IMF_INTERNAL_NAMESPACE::dataWindowForLevel (
+	        _data->tileDesc,
+	        _data->minX, _data->maxX,
+	        _data->minY, _data->maxY,
+	        lx, ly);
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
 	REPLACE_EXC (e, "Error calling dataWindowForLevel() on image "
 			"file \"" << fileName() << "\". " << e);
@@ -1589,15 +1737,16 @@ TiledOutputFile::dataWindowForTile (int dx, int dy, int lx, int ly) const
     try
     {
 	if (!isValidTile (dx, dy, lx, ly))
-	    throw Iex::ArgExc ("Arguments not in valid range.");
-
-	return Imf::dataWindowForTile (_data->tileDesc,
-		        	       _data->minX, _data->maxX,
-			               _data->minY, _data->maxY,
-        			       dx, dy,
-	        		       lx, ly);
+	    throw IEX_NAMESPACE::ArgExc ("Arguments not in valid range.");
+
+	return OPENEXR_IMF_INTERNAL_NAMESPACE::dataWindowForTile (
+	        _data->tileDesc,
+	        _data->minX, _data->maxX,
+	        _data->minY, _data->maxY,
+	        dx, dy,
+	        lx, ly);
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
 	REPLACE_EXC (e, "Error calling dataWindowForTile() on image "
 			"file \"" << fileName() << "\". " << e);
@@ -1619,10 +1768,10 @@ TiledOutputFile::isValidTile (int dx, int dy, int lx, int ly) const
 void
 TiledOutputFile::updatePreviewImage (const PreviewRgba newPixels[])
 {
-    Lock lock (*_data);
+    Lock lock (*_streamData);
 
     if (_data->previewPosition <= 0)
-	THROW (Iex::LogicExc, "Cannot update preview image pixels. "
+	THROW (IEX_NAMESPACE::LogicExc, "Cannot update preview image pixels. "
 			      "File \"" << fileName() << "\" does not "
 			      "contain a preview image.");
 
@@ -1646,15 +1795,15 @@ TiledOutputFile::updatePreviewImage (const PreviewRgba newPixels[])
     // preview image, and jump back to the saved file position.
     //
 
-    Int64 savedPosition = _data->os->tellp();
+    Int64 savedPosition = _streamData->os->tellp();
 
     try
     {
-	_data->os->seekp (_data->previewPosition);
-	pia.writeValueTo (*_data->os, _data->version);
-	_data->os->seekp (savedPosition);
+        _streamData->os->seekp (_data->previewPosition);
+	pia.writeValueTo (*_streamData->os, _data->version);
+	_streamData->os->seekp (savedPosition);
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
 	REPLACE_EXC (e, "Cannot update preview image pixels for "
 			"file \"" << fileName() << "\". " << e);
@@ -1671,22 +1820,22 @@ TiledOutputFile::breakTile
      int length,
      char c)
 {
-    Lock lock (*_data);
+    Lock lock (*_streamData);
 
     Int64 position = _data->tileOffsets (dx, dy, lx, ly);
 
     if (!position)
-	THROW (Iex::ArgExc,
+	THROW (IEX_NAMESPACE::ArgExc,
 	       "Cannot overwrite tile "
 	       "(" << dx << ", " << dy << ", " << lx << "," << ly << "). "
 	       "The tile has not yet been stored in "
 	       "file \"" << fileName() << "\".");
 
-    _data->currentPosition = 0;
-    _data->os->seekp (position + offset);
+    _streamData->currentPosition = 0;
+    _streamData->os->seekp (position + offset);
 
     for (int i = 0; i < length; ++i)
-	_data->os->write (&c, 1);
+        _streamData->os->write (&c, 1);
 }
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfTiledOutputFile.h b/Source/OpenEXR/IlmImf/ImfTiledOutputFile.h
index 3b4f3ff..bfd6bea 100644
--- a/Source/OpenEXR/IlmImf/ImfTiledOutputFile.h
+++ b/Source/OpenEXR/IlmImf/ImfTiledOutputFile.h
@@ -42,20 +42,24 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfHeader.h>
-#include <ImfFrameBuffer.h>
+#include "ImfHeader.h"
+#include "ImfFrameBuffer.h"
 #include "ImathBox.h"
-#include <ImfTileDescription.h>
-#include <ImfThreading.h>
+#include "ImfTileDescription.h"
+#include "ImfThreading.h"
+#include "ImfGenericOutputFile.h"
+#include "ImfForward.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-namespace Imf {
 
-class TiledInputFile;
-class InputFile;
 struct PreviewRgba;
 
 
-class TiledOutputFile
+class IMF_EXPORT TiledOutputFile : public GenericOutputFile
 {
   public:
 
@@ -93,7 +97,7 @@ class TiledOutputFile
     // close the corresponding files.
     // ----------------------------------------------------------------
 
-    TiledOutputFile (OStream &os,
+    TiledOutputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
 		     const Header &header,
                      int numThreads = globalThreadCount ());
 
@@ -195,7 +199,7 @@ class TiledOutputFile
     //      return value is the same as for numXLevels()
     //
     //	if levelMode() == RIPMAP_LEVELS:
-    //      an Iex::LogicExc exception is thrown
+    //      an IEX_NAMESPACE::LogicExc exception is thrown
     //
     // isValidLevel(lx, ly) returns true if the file contains 
     // a level with level number (lx, ly), false if not.
@@ -274,8 +278,8 @@ class TiledOutputFile
     //
     //---------------------------------------------------------
 
-    Imath::Box2i	dataWindowForLevel (int l = 0) const;
-    Imath::Box2i	dataWindowForLevel (int lx, int ly) const;
+    IMATH_NAMESPACE::Box2i	dataWindowForLevel (int l = 0) const;
+    IMATH_NAMESPACE::Box2i	dataWindowForLevel (int lx, int ly) const;
 
 
     //-------------------------------------------------------------------
@@ -299,10 +303,10 @@ class TiledOutputFile
     //
     //-------------------------------------------------------------------
 
-    Imath::Box2i	dataWindowForTile (int dx, int dy,
+    IMATH_NAMESPACE::Box2i	dataWindowForTile (int dx, int dy,
 					   int l = 0) const;
 
-    Imath::Box2i	dataWindowForTile (int dx, int dy,
+    IMATH_NAMESPACE::Box2i	dataWindowForTile (int dx, int dy,
 					   int lx, int ly) const;
 
     //------------------------------------------------------------------
@@ -396,8 +400,9 @@ class TiledOutputFile
     //------------------------------------------------------------------
     
     void		copyPixels (TiledInputFile &in);
+    void                copyPixels (TiledInputPart &in);
+    
     
-
     //------------------------------------------------------------------
     // Shortcut to copy all pixels from an InputFile into this file,
     // without uncompressing and then recompressing the pixel data.
@@ -409,7 +414,9 @@ class TiledOutputFile
     //------------------------------------------------------------------
     
     void		copyPixels (InputFile &in);
+    void                copyPixels (InputPart &in);
 
+    
 
     //--------------------------------------------------------------
     // Updating the preview image:
@@ -417,7 +424,7 @@ class TiledOutputFile
     // updatePreviewImage() supplies a new set of pixels for the
     // preview image attribute in the file's header.  If the header
     // does not contain a preview image, updatePreviewImage() throws
-    // an Iex::LogicExc.
+    // an IEX_NAMESPACE::LogicExc.
     //
     // Note: updatePreviewImage() is necessary because images are
     // often stored in a file incrementally, a few tiles at a time,
@@ -455,6 +462,14 @@ class TiledOutputFile
 
   private:
 
+    // ----------------------------------------------------------------
+    // A constructor attaches the OutputStreamMutex to the
+    // given one from MultiPartOutputFile. Set the previewPosition
+    // and lineOffsetsPosition which have been acquired from
+    // the constructor of MultiPartOutputFile as well.
+    // ----------------------------------------------------------------
+    TiledOutputFile (const OutputPartData* part);
+
     TiledOutputFile (const TiledOutputFile &);		    // not implemented
     TiledOutputFile & operator = (const TiledOutputFile &); // not implemented
 
@@ -467,9 +482,14 @@ class TiledOutputFile
 					     int lx, int ly) const;
 
     Data *		_data;
+
+    OutputStreamMutex*  _streamData;
+    bool                _deleteStream;
+
+    friend class MultiPartOutputFile;
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfTiledOutputPart.cpp b/Source/OpenEXR/IlmImf/ImfTiledOutputPart.cpp
new file mode 100644
index 0000000..cfa0e78
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfTiledOutputPart.cpp
@@ -0,0 +1,228 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#include "ImfTiledOutputPart.h"
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+TiledOutputPart::TiledOutputPart(MultiPartOutputFile& multiPartFile, int partNumber)
+{
+    file = multiPartFile.getOutputPart<TiledOutputFile>(partNumber);
+}
+
+const char *
+TiledOutputPart::fileName () const
+{
+    return file->fileName();
+}
+
+const Header &
+TiledOutputPart::header () const
+{
+    return file->header();
+}
+
+void
+TiledOutputPart::setFrameBuffer (const FrameBuffer &frameBuffer)
+{
+    file->setFrameBuffer(frameBuffer);
+}
+
+const FrameBuffer &
+TiledOutputPart::frameBuffer () const
+{
+    return file->frameBuffer();
+}
+
+unsigned int
+TiledOutputPart::tileXSize () const
+{
+    return file->tileXSize();
+}
+
+unsigned int
+TiledOutputPart::tileYSize () const
+{
+    return file->tileYSize();
+}
+
+LevelMode
+TiledOutputPart::levelMode () const
+{
+    return file->levelMode();
+}
+
+LevelRoundingMode
+TiledOutputPart::levelRoundingMode () const
+{
+    return file->levelRoundingMode();
+}
+
+int
+TiledOutputPart::numLevels () const
+{
+    return file->numLevels();
+}
+
+int
+TiledOutputPart::numXLevels () const
+{
+    return file->numXLevels();
+}
+
+int
+TiledOutputPart::numYLevels () const
+{
+    return file->numYLevels();
+}
+
+bool
+TiledOutputPart::isValidLevel (int lx, int ly) const
+{
+    return file->isValidLevel(lx, ly);
+}
+
+int
+TiledOutputPart::levelWidth  (int lx) const
+{
+    return file->levelWidth(lx);
+}
+
+int
+TiledOutputPart::levelHeight (int ly) const
+{
+    return file->levelHeight(ly);
+}
+
+int
+TiledOutputPart::numXTiles (int lx) const
+{
+    return file->numXTiles(lx);
+}
+
+int
+TiledOutputPart::numYTiles (int ly) const
+{
+    return file->numYTiles(ly);
+}
+
+IMATH_NAMESPACE::Box2i
+TiledOutputPart::dataWindowForLevel (int l) const
+{
+    return file->dataWindowForLevel(l);
+}
+
+IMATH_NAMESPACE::Box2i
+TiledOutputPart::dataWindowForLevel (int lx, int ly) const
+{
+    return file->dataWindowForLevel(lx, ly);
+}
+
+IMATH_NAMESPACE::Box2i
+TiledOutputPart::dataWindowForTile (int dx, int dy, int l) const
+{
+    return file->dataWindowForTile(dx, dy, l);
+}
+
+IMATH_NAMESPACE::Box2i
+TiledOutputPart::dataWindowForTile (int dx, int dy, int lx, int ly) const
+{
+    return file->dataWindowForTile(dx, dy, lx, ly);
+}
+
+void
+TiledOutputPart::writeTile  (int dx, int dy, int l)
+{
+    file->writeTile(dx, dy, l);
+}
+
+void
+TiledOutputPart::writeTile  (int dx, int dy, int lx, int ly)
+{
+    file->writeTile(dx, dy, lx, ly);
+}
+
+void
+TiledOutputPart::writeTiles (int dx1, int dx2, int dy1, int dy2, int lx, int ly)
+{
+    file->writeTiles(dx1, dx2, dy1, dy2, lx, ly);
+}
+
+void
+TiledOutputPart::writeTiles (int dx1, int dx2, int dy1, int dy2, int l)
+{
+    file->writeTiles(dx1, dx2, dy1, dy2, l);
+}
+
+void
+TiledOutputPart::copyPixels (TiledInputFile &in)
+{
+    file->copyPixels(in);
+}
+
+void
+TiledOutputPart::copyPixels (InputFile &in)
+{
+    file->copyPixels(in);
+}
+
+void
+TiledOutputPart::copyPixels (TiledInputPart &in)
+{
+    file->copyPixels(in);
+}
+
+void
+TiledOutputPart::copyPixels (InputPart &in)
+{
+    file->copyPixels(in);
+}
+
+
+
+void
+TiledOutputPart::updatePreviewImage (const PreviewRgba newPixels[])
+{
+    file->updatePreviewImage(newPixels);
+}
+
+void
+TiledOutputPart::breakTile  (int dx, int dy, int lx, int ly, int offset, int length, char c)
+{
+    file->breakTile(dx, dy, lx, ly, offset, length, c);
+}
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfTiledOutputPart.h b/Source/OpenEXR/IlmImf/ImfTiledOutputPart.h
new file mode 100644
index 0000000..1af84be
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfTiledOutputPart.h
@@ -0,0 +1,105 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef IMFTILEDOUTPUTPART_H_
+#define IMFTILEDOUTPUTPART_H_
+
+#include "ImfMultiPartOutputFile.h"
+#include "ImfTiledOutputFile.h"
+#include "ImfForward.h"
+#include "ImfExport.h"
+#include "ImfNamespace.h"
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+//-------------------------------------------------------------------------------
+// class TiledOutputPart:
+//
+// Same interface as TiledOutputFile. Please have a reference to TiledOutputFile.
+//-------------------------------------------------------------------------------
+
+class IMF_EXPORT TiledOutputPart
+{
+    public:
+        TiledOutputPart(MultiPartOutputFile& multiPartFile, int partNumber);
+
+        const char *        fileName () const;
+        const Header &      header () const;
+        void                setFrameBuffer (const FrameBuffer &frameBuffer);
+        const FrameBuffer & frameBuffer () const;
+        unsigned int        tileXSize () const;
+        unsigned int        tileYSize () const;
+        LevelMode           levelMode () const;
+        LevelRoundingMode   levelRoundingMode () const;
+        int                 numLevels () const;
+        int                 numXLevels () const;
+        int                 numYLevels () const;
+        bool                isValidLevel (int lx, int ly) const;
+        int                 levelWidth  (int lx) const;
+        int                 levelHeight (int ly) const;
+        int                 numXTiles (int lx = 0) const;
+        int                 numYTiles (int ly = 0) const;
+        IMATH_NAMESPACE::Box2i        dataWindowForLevel (int l = 0) const;
+        IMATH_NAMESPACE::Box2i        dataWindowForLevel (int lx, int ly) const;
+        IMATH_NAMESPACE::Box2i        dataWindowForTile (int dx, int dy,
+                                               int l = 0) const;
+        IMATH_NAMESPACE::Box2i        dataWindowForTile (int dx, int dy,
+                                               int lx, int ly) const;
+        void                writeTile  (int dx, int dy, int l = 0);
+        void                writeTile  (int dx, int dy, int lx, int ly);
+        void                writeTiles (int dx1, int dx2, int dy1, int dy2,
+                                        int lx, int ly);
+        void                writeTiles (int dx1, int dx2, int dy1, int dy2,
+                                        int l = 0);
+        void                copyPixels (TiledInputFile &in);
+        void                copyPixels (InputFile &in);
+        void                copyPixels (TiledInputPart &in);
+        void                copyPixels (InputPart &in);
+        
+        
+        void                updatePreviewImage (const PreviewRgba newPixels[]);
+        void                breakTile  (int dx, int dy,
+                                        int lx, int ly,
+                                        int offset,
+                                        int length,
+                                        char c);
+
+    private:
+        TiledOutputFile* file;
+};
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif /* IMFTILEDOUTPUTPART_H_ */
diff --git a/Source/OpenEXR/IlmImf/ImfTiledRgbaFile.cpp b/Source/OpenEXR/IlmImf/ImfTiledRgbaFile.cpp
index 1448fe6..157aec0 100644
--- a/Source/OpenEXR/IlmImf/ImfTiledRgbaFile.cpp
+++ b/Source/OpenEXR/IlmImf/ImfTiledRgbaFile.cpp
@@ -51,13 +51,14 @@
 #include "IlmThreadMutex.h"
 #include "Iex.h"
 
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 using namespace std;
-using namespace Imath;
+using namespace IMATH_NAMESPACE;
 using namespace RgbaYca;
-using namespace IlmThread;
+using namespace ILMTHREAD_NAMESPACE;
 
 namespace {
 
@@ -77,7 +78,7 @@ insertChannels (Header &header,
 
 	if (rgbaChannels & WRITE_C)
 	{
-	    THROW (Iex::ArgExc, "Cannot open file \"" << fileName << "\" "
+	    THROW (IEX_NAMESPACE::ArgExc, "Cannot open file \"" << fileName << "\" "
 				"for writing.  Tiled image files do not "
 				"support subsampled chroma channels.");
 	}
@@ -213,7 +214,7 @@ TiledRgbaOutputFile::ToYa::writeTile (int dx, int dy, int lx, int ly)
 {
     if (_fbBase == 0)
     {
-	THROW (Iex::ArgExc, "No frame buffer was specified as the "
+	THROW (IEX_NAMESPACE::ArgExc, "No frame buffer was specified as the "
 			    "pixel data source for image file "
 			    "\"" << _outputFile.fileName() << "\".");
     }
@@ -280,7 +281,7 @@ TiledRgbaOutputFile::TiledRgbaOutputFile
 
 
 TiledRgbaOutputFile::TiledRgbaOutputFile
-    (OStream &os,
+    (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
      const Header &header,
      RgbaChannels rgbaChannels,
      int tileXSize,
@@ -309,11 +310,11 @@ TiledRgbaOutputFile::TiledRgbaOutputFile
      int tileYSize,
      LevelMode mode,
      LevelRoundingMode rmode,
-     const Imath::Box2i &displayWindow,
-     const Imath::Box2i &dataWindow,
+     const IMATH_NAMESPACE::Box2i &displayWindow,
+     const IMATH_NAMESPACE::Box2i &dataWindow,
      RgbaChannels rgbaChannels,
      float pixelAspectRatio,
-     const Imath::V2f screenWindowCenter,
+     const IMATH_NAMESPACE::V2f screenWindowCenter,
      float screenWindowWidth,
      LineOrder lineOrder,
      Compression compression,
@@ -349,7 +350,7 @@ TiledRgbaOutputFile::TiledRgbaOutputFile
      LevelRoundingMode rmode,
      RgbaChannels rgbaChannels,
      float pixelAspectRatio,
-     const Imath::V2f screenWindowCenter,
+     const IMATH_NAMESPACE::V2f screenWindowCenter,
      float screenWindowWidth,
      LineOrder lineOrder,
      Compression compression,
@@ -423,14 +424,14 @@ TiledRgbaOutputFile::frameBuffer () const
 }
 
 
-const Imath::Box2i &
+const IMATH_NAMESPACE::Box2i &
 TiledRgbaOutputFile::displayWindow () const
 {
     return _outputFile->header().displayWindow();
 }
 
 
-const Imath::Box2i &
+const IMATH_NAMESPACE::Box2i &
 TiledRgbaOutputFile::dataWindow () const
 {
     return _outputFile->header().dataWindow();
@@ -444,7 +445,7 @@ TiledRgbaOutputFile::pixelAspectRatio () const
 }
 
 
-const Imath::V2f
+const IMATH_NAMESPACE::V2f
 TiledRgbaOutputFile::screenWindowCenter () const
 {
     return _outputFile->header().screenWindowCenter();
@@ -563,28 +564,28 @@ TiledRgbaOutputFile::numYTiles (int ly) const
 }
 
 
-Imath::Box2i
+IMATH_NAMESPACE::Box2i
 TiledRgbaOutputFile::dataWindowForLevel (int l) const
 {
      return _outputFile->dataWindowForLevel (l);
 }
 
 
-Imath::Box2i
+IMATH_NAMESPACE::Box2i
 TiledRgbaOutputFile::dataWindowForLevel (int lx, int ly) const
 {
      return _outputFile->dataWindowForLevel (lx, ly);
 }
 
 
-Imath::Box2i
+IMATH_NAMESPACE::Box2i
 TiledRgbaOutputFile::dataWindowForTile (int dx, int dy, int l) const
 {
      return _outputFile->dataWindowForTile (dx, dy, l);
 }
 
 
-Imath::Box2i
+IMATH_NAMESPACE::Box2i
 TiledRgbaOutputFile::dataWindowForTile (int dx, int dy, int lx, int ly) const
 {
      return _outputFile->dataWindowForTile (dx, dy, lx, ly);
@@ -731,7 +732,7 @@ TiledRgbaInputFile::FromYa::readTile (int dx, int dy, int lx, int ly)
 {
     if (_fbBase == 0)
     {
-	THROW (Iex::ArgExc, "No frame buffer was specified as the "
+	THROW (IEX_NAMESPACE::ArgExc, "No frame buffer was specified as the "
 			    "pixel data destination for image file "
 			    "\"" << _inputFile.fileName() << "\".");
     }
@@ -778,7 +779,7 @@ TiledRgbaInputFile::TiledRgbaInputFile (const char name[], int numThreads):
 }
 
 
-TiledRgbaInputFile::TiledRgbaInputFile (IStream &is, int numThreads):
+TiledRgbaInputFile::TiledRgbaInputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int numThreads):
     _inputFile (new TiledInputFile (is, numThreads)),
     _fromYa (0),
     _channelNamePrefix ("")
@@ -801,7 +802,7 @@ TiledRgbaInputFile::TiledRgbaInputFile (const char name[],
 }
 
 
-TiledRgbaInputFile::TiledRgbaInputFile (IStream &is,
+TiledRgbaInputFile::TiledRgbaInputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
 					const string &layerName,
 					int numThreads)
 :
@@ -906,14 +907,14 @@ TiledRgbaInputFile::frameBuffer () const
 }
 
 
-const Imath::Box2i &
+const IMATH_NAMESPACE::Box2i &
 TiledRgbaInputFile::displayWindow () const
 {
     return _inputFile->header().displayWindow();
 }
 
 
-const Imath::Box2i &
+const IMATH_NAMESPACE::Box2i &
 TiledRgbaInputFile::dataWindow () const
 {
     return _inputFile->header().dataWindow();
@@ -927,7 +928,7 @@ TiledRgbaInputFile::pixelAspectRatio () const
 }
 
 
-const Imath::V2f	
+const IMATH_NAMESPACE::V2f	
 TiledRgbaInputFile::screenWindowCenter () const
 {
     return _inputFile->header().screenWindowCenter();
@@ -1060,28 +1061,28 @@ TiledRgbaInputFile::numYTiles (int ly) const
 }
 
 
-Imath::Box2i
+IMATH_NAMESPACE::Box2i
 TiledRgbaInputFile::dataWindowForLevel (int l) const
 {
      return _inputFile->dataWindowForLevel (l);
 }
 
 
-Imath::Box2i
+IMATH_NAMESPACE::Box2i
 TiledRgbaInputFile::dataWindowForLevel (int lx, int ly) const
 {
      return _inputFile->dataWindowForLevel (lx, ly);
 }
 
 
-Imath::Box2i
+IMATH_NAMESPACE::Box2i
 TiledRgbaInputFile::dataWindowForTile (int dx, int dy, int l) const
 {
      return _inputFile->dataWindowForTile (dx, dy, l);
 }
 
 
-Imath::Box2i
+IMATH_NAMESPACE::Box2i
 TiledRgbaInputFile::dataWindowForTile (int dx, int dy, int lx, int ly) const
 {
      return _inputFile->dataWindowForTile (dx, dy, lx, ly);
@@ -1159,4 +1160,4 @@ TiledRgbaOutputFile::breakTile  (int dx, int dy, int lx, int ly,
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfTiledRgbaFile.h b/Source/OpenEXR/IlmImf/ImfTiledRgbaFile.h
index 5fcd22b..978ba36 100644
--- a/Source/OpenEXR/IlmImf/ImfTiledRgbaFile.h
+++ b/Source/OpenEXR/IlmImf/ImfTiledRgbaFile.h
@@ -45,28 +45,27 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfHeader.h>
-#include <ImfFrameBuffer.h>
+#include "ImfHeader.h"
+#include "ImfFrameBuffer.h"
 #include "ImathVec.h"
 #include "ImathBox.h"
 #include "half.h"
-#include <ImfTileDescription.h>
-#include <ImfRgba.h>
-#include <ImfThreading.h>
+#include "ImfTileDescription.h"
+#include "ImfRgba.h"
+#include "ImfThreading.h"
 #include <string>
+#include "ImfNamespace.h"
+#include "ImfForward.h"
 
-namespace Imf {
 
-class TiledOutputFile;
-class TiledInputFile;
-struct PreviewRgba;
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 //
 // Tiled RGBA output file.
 //
 
-class TiledRgbaOutputFile
+class IMF_EXPORT TiledRgbaOutputFile
 {
   public:
 
@@ -97,7 +96,7 @@ class TiledRgbaOutputFile
     // corresponding files.
     //---------------------------------------------------
 
-    TiledRgbaOutputFile (OStream &os,
+    TiledRgbaOutputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
 			 const Header &header,
 			 RgbaChannels rgbaChannels,
 			 int tileXSize,
@@ -118,12 +117,12 @@ class TiledRgbaOutputFile
 			 int tileYSize,
 			 LevelMode mode,
 			 LevelRoundingMode rmode,
-			 const Imath::Box2i &displayWindow,
-			 const Imath::Box2i &dataWindow = Imath::Box2i(),
+			 const IMATH_NAMESPACE::Box2i &displayWindow,
+			 const IMATH_NAMESPACE::Box2i &dataWindow = IMATH_NAMESPACE::Box2i(),
 			 RgbaChannels rgbaChannels = WRITE_RGBA,
 			 float pixelAspectRatio = 1,
-			 const Imath::V2f screenWindowCenter =
-						    Imath::V2f (0, 0),
+			 const IMATH_NAMESPACE::V2f screenWindowCenter =
+						    IMATH_NAMESPACE::V2f (0, 0),
 			 float screenWindowWidth = 1,
 			 LineOrder lineOrder = INCREASING_Y,
 			 Compression compression = ZIP_COMPRESSION,
@@ -145,8 +144,8 @@ class TiledRgbaOutputFile
 			 LevelRoundingMode rmode = ROUND_DOWN,
 			 RgbaChannels rgbaChannels = WRITE_RGBA,
 			 float pixelAspectRatio = 1,
-			 const Imath::V2f screenWindowCenter =
-						    Imath::V2f (0, 0),
+			 const IMATH_NAMESPACE::V2f screenWindowCenter =
+						    IMATH_NAMESPACE::V2f (0, 0),
 			 float screenWindowWidth = 1,
 			 LineOrder lineOrder = INCREASING_Y,
 			 Compression compression = ZIP_COMPRESSION,
@@ -174,10 +173,10 @@ class TiledRgbaOutputFile
 
     const Header &		header () const;
     const FrameBuffer &		frameBuffer () const;
-    const Imath::Box2i &	displayWindow () const;
-    const Imath::Box2i &	dataWindow () const;
+    const IMATH_NAMESPACE::Box2i &	displayWindow () const;
+    const IMATH_NAMESPACE::Box2i &	dataWindow () const;
     float			pixelAspectRatio () const;
-    const Imath::V2f		screenWindowCenter () const;
+    const IMATH_NAMESPACE::V2f		screenWindowCenter () const;
     float			screenWindowWidth () const;
     LineOrder			lineOrder () const;
     Compression			compression () const;
@@ -204,13 +203,13 @@ class TiledRgbaOutputFile
     int			numXTiles (int lx = 0) const;
     int			numYTiles (int ly = 0) const;
 
-    Imath::Box2i	dataWindowForLevel (int l = 0) const;
-    Imath::Box2i	dataWindowForLevel (int lx, int ly) const;
+    IMATH_NAMESPACE::Box2i	dataWindowForLevel (int l = 0) const;
+    IMATH_NAMESPACE::Box2i	dataWindowForLevel (int lx, int ly) const;
 
-    Imath::Box2i	dataWindowForTile (int dx, int dy,
+    IMATH_NAMESPACE::Box2i	dataWindowForTile (int dx, int dy,
 					   int l = 0) const;
 
-    Imath::Box2i	dataWindowForTile (int dx, int dy,
+    IMATH_NAMESPACE::Box2i	dataWindowForTile (int dx, int dy,
 					   int lx, int ly) const;
 
     //------------------------------------------------------------------
@@ -295,7 +294,7 @@ class TiledRgbaOutputFile
 // Tiled RGBA input file
 //
 
-class TiledRgbaInputFile
+class IMF_EXPORT TiledRgbaInputFile
 {
   public:
 
@@ -319,7 +318,7 @@ class TiledRgbaInputFile
     // corresponding files.
     //-------------------------------------------------------
 
-    TiledRgbaInputFile (IStream &is, int numThreads = globalThreadCount ());
+    TiledRgbaInputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int numThreads = globalThreadCount ());
 
 
     //------------------------------------------------------------
@@ -332,7 +331,7 @@ class TiledRgbaInputFile
 		        const std::string &layerName,
 		        int numThreads = globalThreadCount());
 
-    TiledRgbaInputFile (IStream &is,
+    TiledRgbaInputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
 		        const std::string &layerName,
 		        int numThreads = globalThreadCount());
 
@@ -371,10 +370,10 @@ class TiledRgbaInputFile
 
     const Header &		header () const;
     const FrameBuffer &		frameBuffer () const;
-    const Imath::Box2i &	displayWindow () const;
-    const Imath::Box2i &	dataWindow () const;
+    const IMATH_NAMESPACE::Box2i &	displayWindow () const;
+    const IMATH_NAMESPACE::Box2i &	dataWindow () const;
     float			pixelAspectRatio () const;
-    const Imath::V2f		screenWindowCenter () const;
+    const IMATH_NAMESPACE::V2f		screenWindowCenter () const;
     float			screenWindowWidth () const;
     LineOrder			lineOrder () const;
     Compression			compression () const;
@@ -409,13 +408,13 @@ class TiledRgbaInputFile
     int			numXTiles (int lx = 0) const;
     int			numYTiles (int ly = 0) const;
 
-    Imath::Box2i	dataWindowForLevel (int l = 0) const;
-    Imath::Box2i	dataWindowForLevel (int lx, int ly) const;
+    IMATH_NAMESPACE::Box2i	dataWindowForLevel (int l = 0) const;
+    IMATH_NAMESPACE::Box2i	dataWindowForLevel (int lx, int ly) const;
 
-    Imath::Box2i	dataWindowForTile (int dx, int dy,
+    IMATH_NAMESPACE::Box2i	dataWindowForTile (int dx, int dy,
 					   int l = 0) const;
 
-    Imath::Box2i	dataWindowForTile (int dx, int dy,
+    IMATH_NAMESPACE::Box2i	dataWindowForTile (int dx, int dy,
 					   int lx, int ly) const;
 					   
 
@@ -474,6 +473,10 @@ class TiledRgbaInputFile
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
+
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfTimeCode.cpp b/Source/OpenEXR/IlmImf/ImfTimeCode.cpp
index 9b34cce..88b9d1c 100644
--- a/Source/OpenEXR/IlmImf/ImfTimeCode.cpp
+++ b/Source/OpenEXR/IlmImf/ImfTimeCode.cpp
@@ -41,8 +41,9 @@
 
 #include <ImfTimeCode.h>
 #include "Iex.h"
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
    
 TimeCode::TimeCode ()
@@ -118,6 +119,21 @@ TimeCode::operator = (const TimeCode &other)
     return *this;
 }
 
+    
+bool
+TimeCode::operator == (const TimeCode & c) const
+{
+    return (_time == c._time && _user == c._user);
+}
+
+
+bool
+TimeCode::operator != (const TimeCode & c) const
+{
+    return (_time != c._time || _user != c._user);
+}
+    
+    
 
 namespace {
 
@@ -169,7 +185,7 @@ void
 TimeCode::setHours (int value)
 {
     if (value < 0 || value > 23)
-	throw Iex::ArgExc ("Cannot set hours field in time code. "
+	throw IEX_NAMESPACE::ArgExc ("Cannot set hours field in time code. "
 			   "New value is out of range.");
 
     setBitField (_time, 24, 29, binaryToBcd (value));
@@ -187,7 +203,7 @@ void
 TimeCode::setMinutes (int value)
 {
     if (value < 0 || value > 59)
-	throw Iex::ArgExc ("Cannot set minutes field in time code. "
+	throw IEX_NAMESPACE::ArgExc ("Cannot set minutes field in time code. "
 			   "New value is out of range.");
 
     setBitField (_time, 16, 22, binaryToBcd (value));
@@ -205,7 +221,7 @@ void
 TimeCode::setSeconds (int value)
 {
     if (value < 0 || value > 59)
-	throw Iex::ArgExc ("Cannot set seconds field in time code. "
+	throw IEX_NAMESPACE::ArgExc ("Cannot set seconds field in time code. "
 			   "New value is out of range.");
 
     setBitField (_time, 8, 14, binaryToBcd (value));
@@ -223,7 +239,7 @@ void
 TimeCode::setFrame (int value)
 {
     if (value < 0 || value > 59)
-	throw Iex::ArgExc ("Cannot set frame field in time code. "
+	throw IEX_NAMESPACE::ArgExc ("Cannot set frame field in time code. "
 			   "New value is out of range.");
 
     setBitField (_time, 0, 5, binaryToBcd (value));
@@ -233,7 +249,7 @@ TimeCode::setFrame (int value)
 bool
 TimeCode::dropFrame () const
 {
-    return bool (bitField (_time, 6, 6));
+    return !!bitField (_time, 6, 6);
 }
 
 
@@ -247,7 +263,7 @@ TimeCode::setDropFrame (bool value)
 bool
 TimeCode::colorFrame () const
 {
-    return bool (bitField (_time, 7, 7));
+    return !!bitField (_time, 7, 7);
 }
 
 
@@ -261,7 +277,7 @@ TimeCode::setColorFrame (bool value)
 bool
 TimeCode::fieldPhase () const
 {
-    return bool (bitField (_time, 15, 15));
+    return !!bitField (_time, 15, 15);
 }
 
 
@@ -275,7 +291,7 @@ TimeCode::setFieldPhase (bool value)
 bool
 TimeCode::bgf0 () const
 {
-    return bool (bitField (_time, 23, 23));
+    return !!bitField (_time, 23, 23);
 }
 
 
@@ -289,7 +305,7 @@ TimeCode::setBgf0 (bool value)
 bool
 TimeCode::bgf1 () const
 {
-    return bool (bitField (_time, 30, 30));
+    return!!bitField (_time, 30, 30);
 }
 
 
@@ -303,7 +319,7 @@ TimeCode::setBgf1 (bool value)
 bool
 TimeCode::bgf2 () const
 {
-    return bool (bitField (_time, 31, 31));
+    return !!bitField (_time, 31, 31);
 }
 
 
@@ -318,7 +334,7 @@ int
 TimeCode::binaryGroup (int group) const
 {
     if (group < 1 || group > 8)
-	throw Iex::ArgExc ("Cannot extract binary group from time code "
+	throw IEX_NAMESPACE::ArgExc ("Cannot extract binary group from time code "
 		           "user data.  Group number is out of range.");
 
     int minBit = 4 * (group - 1);
@@ -331,7 +347,7 @@ void
 TimeCode::setBinaryGroup (int group, int value)
 {
     if (group < 1 || group > 8)
-	throw Iex::ArgExc ("Cannot extract binary group from time code "
+	throw IEX_NAMESPACE::ArgExc ("Cannot extract binary group from time code "
 		           "user data.  Group number is out of range.");
 
     int minBit = 4 * (group - 1);
@@ -412,4 +428,4 @@ TimeCode::setUserData (unsigned int value)
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfTimeCode.h b/Source/OpenEXR/IlmImf/ImfTimeCode.h
index 3030d49..751c416 100644
--- a/Source/OpenEXR/IlmImf/ImfTimeCode.h
+++ b/Source/OpenEXR/IlmImf/ImfTimeCode.h
@@ -36,6 +36,9 @@
 #ifndef INCLUDED_IMF_TIME_CODE_H
 #define INCLUDED_IMF_TIME_CODE_H
 
+#include "ImfExport.h"
+#include "ImfNamespace.h"
+
 //-----------------------------------------------------------------------------
 //
 //	class TimeCode
@@ -110,10 +113,10 @@
 //
 //-----------------------------------------------------------------------------
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
    
-class TimeCode
+class IMF_EXPORT TimeCode
 {
   public:
 
@@ -213,7 +216,15 @@ class TimeCode
     unsigned int	userData () const;
 
     void		setUserData (unsigned int value);
-
+    
+    
+    //---------
+    // Equality
+    //---------
+    
+    bool		operator == (const TimeCode &v) const;    
+    bool		operator != (const TimeCode &v) const;
+    
   private:
 
     unsigned int	_time;
@@ -221,6 +232,11 @@ class TimeCode
 };
 
 
-} // namespace Imf
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
+
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfTimeCodeAttribute.cpp b/Source/OpenEXR/IlmImf/ImfTimeCodeAttribute.cpp
index 2c2088b..5e7ea59 100644
--- a/Source/OpenEXR/IlmImf/ImfTimeCodeAttribute.cpp
+++ b/Source/OpenEXR/IlmImf/ImfTimeCodeAttribute.cpp
@@ -41,8 +41,9 @@
 
 #include <ImfTimeCodeAttribute.h>
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
+using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;
 
 template <>
 const char *
@@ -54,7 +55,7 @@ TimeCodeAttribute::staticTypeName ()
 
 template <>
 void
-TimeCodeAttribute::writeValueTo (OStream &os, int version) const
+TimeCodeAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     Xdr::write <StreamIO> (os, _value.timeAndFlags());
     Xdr::write <StreamIO> (os, _value.userData());
@@ -63,7 +64,7 @@ TimeCodeAttribute::writeValueTo (OStream &os, int version) const
 
 template <>
 void
-TimeCodeAttribute::readValueFrom (IStream &is, int size, int version)
+TimeCodeAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     unsigned int tmp;
 
@@ -75,4 +76,4 @@ TimeCodeAttribute::readValueFrom (IStream &is, int size, int version)
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT 
diff --git a/Source/OpenEXR/IlmImf/ImfTimeCodeAttribute.h b/Source/OpenEXR/IlmImf/ImfTimeCodeAttribute.h
index 3d548fa..ccd893a 100644
--- a/Source/OpenEXR/IlmImf/ImfTimeCodeAttribute.h
+++ b/Source/OpenEXR/IlmImf/ImfTimeCodeAttribute.h
@@ -43,30 +43,32 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfAttribute.h>
-#include <ImfTimeCode.h>
+#include "ImfAttribute.h"
+#include "ImfTimeCode.h"
 
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-namespace Imf {
 
-
-typedef TypedAttribute<TimeCode> TimeCodeAttribute;
+typedef TypedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::TimeCode> TimeCodeAttribute;
 
 template <>
+IMF_EXPORT
 const char *TimeCodeAttribute::staticTypeName ();
 
 template <>
-void TimeCodeAttribute::writeValueTo (OStream &, int) const;
+IMF_EXPORT
+void TimeCodeAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &,
+                                      int) const;
 
 template <>
-void TimeCodeAttribute::readValueFrom (IStream &, int, int);
+IMF_EXPORT
+void TimeCodeAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &,
+                                       int, int);
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 
-} // namespace Imf
 
-// Metrowerks compiler wants the .cpp file inlined, too
-#ifdef __MWERKS__
-#include <ImfTimeCodeAttribute.cpp>
-#endif
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfVecAttribute.cpp b/Source/OpenEXR/IlmImf/ImfVecAttribute.cpp
index 7527bfd..7d51904 100644
--- a/Source/OpenEXR/IlmImf/ImfVecAttribute.cpp
+++ b/Source/OpenEXR/IlmImf/ImfVecAttribute.cpp
@@ -48,8 +48,9 @@
 #include <ImfVecAttribute.h>
 
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
+using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;
 
 template <>
 const char *
@@ -61,7 +62,7 @@ V2iAttribute::staticTypeName ()
 
 template <>
 void
-V2iAttribute::writeValueTo (OStream &os, int version) const
+V2iAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     Xdr::write <StreamIO> (os, _value.x);
     Xdr::write <StreamIO> (os, _value.y);
@@ -70,7 +71,7 @@ V2iAttribute::writeValueTo (OStream &os, int version) const
 
 template <>
 void
-V2iAttribute::readValueFrom (IStream &is, int size, int version)
+V2iAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     Xdr::read <StreamIO> (is, _value.x);
     Xdr::read <StreamIO> (is, _value.y);
@@ -87,7 +88,7 @@ V2fAttribute::staticTypeName ()
 
 template <>
 void
-V2fAttribute::writeValueTo (OStream &os, int version) const
+V2fAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     Xdr::write <StreamIO> (os, _value.x);
     Xdr::write <StreamIO> (os, _value.y);
@@ -96,7 +97,7 @@ V2fAttribute::writeValueTo (OStream &os, int version) const
 
 template <>
 void
-V2fAttribute::readValueFrom (IStream &is, int size, int version)
+V2fAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     Xdr::read <StreamIO> (is, _value.x);
     Xdr::read <StreamIO> (is, _value.y);
@@ -113,7 +114,7 @@ V2dAttribute::staticTypeName ()
 
 template <>
 void
-V2dAttribute::writeValueTo (OStream &os, int version) const
+V2dAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     Xdr::write <StreamIO> (os, _value.x);
     Xdr::write <StreamIO> (os, _value.y);
@@ -122,7 +123,7 @@ V2dAttribute::writeValueTo (OStream &os, int version) const
 
 template <>
 void
-V2dAttribute::readValueFrom (IStream &is, int size, int version)
+V2dAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     Xdr::read <StreamIO> (is, _value.x);
     Xdr::read <StreamIO> (is, _value.y);
@@ -139,7 +140,7 @@ V3iAttribute::staticTypeName ()
 
 template <>
 void
-V3iAttribute::writeValueTo (OStream &os, int version) const
+V3iAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     Xdr::write <StreamIO> (os, _value.x);
     Xdr::write <StreamIO> (os, _value.y);
@@ -149,7 +150,7 @@ V3iAttribute::writeValueTo (OStream &os, int version) const
 
 template <>
 void
-V3iAttribute::readValueFrom (IStream &is, int size, int version)
+V3iAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     Xdr::read <StreamIO> (is, _value.x);
     Xdr::read <StreamIO> (is, _value.y);
@@ -167,7 +168,7 @@ V3fAttribute::staticTypeName ()
 
 template <>
 void
-V3fAttribute::writeValueTo (OStream &os, int version) const
+V3fAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     Xdr::write <StreamIO> (os, _value.x);
     Xdr::write <StreamIO> (os, _value.y);
@@ -177,7 +178,7 @@ V3fAttribute::writeValueTo (OStream &os, int version) const
 
 template <>
 void
-V3fAttribute::readValueFrom (IStream &is, int size, int version)
+V3fAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     Xdr::read <StreamIO> (is, _value.x);
     Xdr::read <StreamIO> (is, _value.y);
@@ -195,7 +196,7 @@ V3dAttribute::staticTypeName ()
 
 template <>
 void
-V3dAttribute::writeValueTo (OStream &os, int version) const
+V3dAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     Xdr::write <StreamIO> (os, _value.x);
     Xdr::write <StreamIO> (os, _value.y);
@@ -205,7 +206,7 @@ V3dAttribute::writeValueTo (OStream &os, int version) const
 
 template <>
 void
-V3dAttribute::readValueFrom (IStream &is, int size, int version)
+V3dAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     Xdr::read <StreamIO> (is, _value.x);
     Xdr::read <StreamIO> (is, _value.y);
@@ -213,4 +214,4 @@ V3dAttribute::readValueFrom (IStream &is, int size, int version)
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT 
diff --git a/Source/OpenEXR/IlmImf/ImfVecAttribute.h b/Source/OpenEXR/IlmImf/ImfVecAttribute.h
index b0b79ba..8480fe6 100644
--- a/Source/OpenEXR/IlmImf/ImfVecAttribute.h
+++ b/Source/OpenEXR/IlmImf/ImfVecAttribute.h
@@ -48,54 +48,53 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfAttribute.h>
+#include "ImfAttribute.h"
 #include "ImathVec.h"
 
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-namespace Imf {
+typedef TypedAttribute<IMATH_NAMESPACE::V2i> V2iAttribute;
+template <> IMF_EXPORT const char *V2iAttribute::staticTypeName ();
+template <> IMF_EXPORT void V2iAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &, int) const;
+template <> IMF_EXPORT void V2iAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &, int, int);
 
 
-typedef TypedAttribute<Imath::V2i> V2iAttribute;
-template <> const char *V2iAttribute::staticTypeName ();
-template <> void V2iAttribute::writeValueTo (OStream &, int) const;
-template <> void V2iAttribute::readValueFrom (IStream &, int, int);
+typedef TypedAttribute<IMATH_NAMESPACE::V2f> V2fAttribute;
+template <> IMF_EXPORT const char *V2fAttribute::staticTypeName ();
+template <> IMF_EXPORT void V2fAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &, int) const;
+template <> IMF_EXPORT void V2fAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &, int, int);
 
 
-typedef TypedAttribute<Imath::V2f> V2fAttribute;
-template <> const char *V2fAttribute::staticTypeName ();
-template <> void V2fAttribute::writeValueTo (OStream &, int) const;
-template <> void V2fAttribute::readValueFrom (IStream &, int, int);
+typedef TypedAttribute<IMATH_NAMESPACE::V2d> V2dAttribute;
+template <> IMF_EXPORT const char *V2dAttribute::staticTypeName ();
+template <> IMF_EXPORT void V2dAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &, int) const;
+template <> IMF_EXPORT void V2dAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &, int, int);
 
 
-typedef TypedAttribute<Imath::V2d> V2dAttribute;
-template <> const char *V2dAttribute::staticTypeName ();
-template <> void V2dAttribute::writeValueTo (OStream &, int) const;
-template <> void V2dAttribute::readValueFrom (IStream &, int, int);
+typedef TypedAttribute<IMATH_NAMESPACE::V3i> V3iAttribute;
+template <> IMF_EXPORT const char *V3iAttribute::staticTypeName ();
+template <> IMF_EXPORT void V3iAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &, int) const;
+template <> IMF_EXPORT void V3iAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &, int, int);
 
 
-typedef TypedAttribute<Imath::V3i> V3iAttribute;
-template <> const char *V3iAttribute::staticTypeName ();
-template <> void V3iAttribute::writeValueTo (OStream &, int) const;
-template <> void V3iAttribute::readValueFrom (IStream &, int, int);
+typedef TypedAttribute<IMATH_NAMESPACE::V3f> V3fAttribute;
+template <> IMF_EXPORT const char *V3fAttribute::staticTypeName ();
+template <> IMF_EXPORT void V3fAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &, int) const;
+template <> IMF_EXPORT void V3fAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &, int, int);
 
 
-typedef TypedAttribute<Imath::V3f> V3fAttribute;
-template <> const char *V3fAttribute::staticTypeName ();
-template <> void V3fAttribute::writeValueTo (OStream &, int) const;
-template <> void V3fAttribute::readValueFrom (IStream &, int, int);
+typedef TypedAttribute<IMATH_NAMESPACE::V3d> V3dAttribute;
+template <> IMF_EXPORT const char *V3dAttribute::staticTypeName ();
+template <> IMF_EXPORT void V3dAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &, int) const;
+template <> IMF_EXPORT void V3dAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &, int, int);
 
 
-typedef TypedAttribute<Imath::V3d> V3dAttribute;
-template <> const char *V3dAttribute::staticTypeName ();
-template <> void V3dAttribute::writeValueTo (OStream &, int) const;
-template <> void V3dAttribute::readValueFrom (IStream &, int, int);
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 
-} // namespace Imf
+#if defined (OPENEXR_IMF_INTERNAL_NAMESPACE_AUTO_EXPOSE)
+namespace Imf { using namespace OPENEXR_IMF_INTERNAL_NAMESPACE; }
 
-// Metrowerks compiler wants the .cpp file inlined, too
-#ifdef __MWERKS__
-#include <ImfVecAttribute.cpp>
 #endif
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfVersion.cpp b/Source/OpenEXR/IlmImf/ImfVersion.cpp
index 3814479..4f49aa0 100644
--- a/Source/OpenEXR/IlmImf/ImfVersion.cpp
+++ b/Source/OpenEXR/IlmImf/ImfVersion.cpp
@@ -41,8 +41,9 @@
 
 
 #include <ImfVersion.h>
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 bool
@@ -55,5 +56,5 @@ isImfMagic (const char bytes[4])
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
 
diff --git a/Source/OpenEXR/IlmImf/ImfVersion.h b/Source/OpenEXR/IlmImf/ImfVersion.h
index 34fb93b..de2577f 100644
--- a/Source/OpenEXR/IlmImf/ImfVersion.h
+++ b/Source/OpenEXR/IlmImf/ImfVersion.h
@@ -42,9 +42,10 @@
 //
 //-----------------------------------------------------------------------------
 
+#include "ImfExport.h"
+#include "ImfNamespace.h"
 
-namespace Imf {
-
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 //
 // The MAGIC number is stored in the first four bytes of every
@@ -88,11 +89,19 @@ const int LONG_NAMES_FLAG       = 0x00000400;   // File contains long
                                                 // attribute or channel
                                                 // names
 
+const int NON_IMAGE_FLAG        = 0x00000800;   // File has at least one part
+                                                // which is not a regular
+                                                // scanline image or regular tiled image
+                                                // (that is, it is a deep format)
+
+const int MULTI_PART_FILE_FLAG  = 0x00001000;   // File has multiple parts
+
 //
 // Bitwise OR of all known flags.
 //
 
-const int ALL_FLAGS		= TILED_FLAG | LONG_NAMES_FLAG;
+const int ALL_FLAGS		= TILED_FLAG | LONG_NAMES_FLAG |
+                                  NON_IMAGE_FLAG | MULTI_PART_FILE_FLAG;
 
 
 //
@@ -100,6 +109,8 @@ const int ALL_FLAGS		= TILED_FLAG | LONG_NAMES_FLAG;
 //
 
 inline bool  isTiled (int version)	{return !!(version & TILED_FLAG);}
+inline bool  isMultiPart (int version)  {return version & MULTI_PART_FILE_FLAG; }
+inline bool  isNonImage(int version)    {return version & NON_IMAGE_FLAG; }
 inline int   makeTiled (int version)	{return version | TILED_FLAG;}
 inline int   makeNotTiled (int version) {return version & ~TILED_FLAG;}
 inline int   getVersion (int version)	{return version & VERSION_NUMBER_FIELD;}
@@ -112,9 +123,14 @@ inline bool  supportsFlags (int flags)	{return !(flags & ~ALL_FLAGS);}
 // file is probably an OpenEXR image file, false if not.
 //
 
+IMF_EXPORT 
 bool	     isImfMagic (const char bytes[4]);
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
+
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfWav.cpp b/Source/OpenEXR/IlmImf/ImfWav.cpp
index d4486d5..5d71d56 100644
--- a/Source/OpenEXR/IlmImf/ImfWav.cpp
+++ b/Source/OpenEXR/IlmImf/ImfWav.cpp
@@ -46,8 +46,9 @@
 
 
 #include <ImfWav.h>
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 namespace {
 
 
@@ -387,4 +388,4 @@ wav2Decode
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfWav.h b/Source/OpenEXR/IlmImf/ImfWav.h
index 815d2d5..9751433 100644
--- a/Source/OpenEXR/IlmImf/ImfWav.h
+++ b/Source/OpenEXR/IlmImf/ImfWav.h
@@ -42,10 +42,13 @@
 //	16-bit Haar Wavelet encoding and decoding
 //
 //-----------------------------------------------------------------------------
+#include "ImfNamespace.h"
+#include "ImfExport.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
+IMF_EXPORT 
 void
 wav2Encode
     (unsigned short *in, // io: values in[y][x] are transformed in place
@@ -55,6 +58,7 @@ wav2Encode
      int     oy,	 // i : y offset
      unsigned short mx); // i : maximum in[x][y] value
 
+IMF_EXPORT
 void
 wav2Decode
     (unsigned short *in, // io: values in[y][x] are transformed in place
@@ -65,6 +69,10 @@ wav2Decode
      unsigned short mx); // i : maximum in[x][y] value
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
+
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfXdr.h b/Source/OpenEXR/IlmImf/ImfXdr.h
index 7992921..0af6f67 100644
--- a/Source/OpenEXR/IlmImf/ImfXdr.h
+++ b/Source/OpenEXR/IlmImf/ImfXdr.h
@@ -36,6 +36,7 @@
 #ifndef INCLUDED_IMF_XDR_H
 #define INCLUDED_IMF_XDR_H
 
+
 //----------------------------------------------------------------------------
 //
 //	Xdr -- routines to convert data between the machine's native
@@ -102,12 +103,15 @@
 //
 //----------------------------------------------------------------------------
 
-#include <ImfInt64.h>
+#include "ImfInt64.h"
 #include "IexMathExc.h"
 #include "half.h"
 #include <limits.h>
 
-namespace Imf {
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
 namespace Xdr {
 
 
@@ -711,7 +715,7 @@ read (T &in, signed long &v)
 	if (( b[4] ||  b[5] ||  b[6] ||  b[7]) &&
 	    (~b[4] || ~b[5] || ~b[6] || ~b[7]))
 	{
-	    throw Iex::OverflowExc ("Long int overflow - read a large "
+	    throw IEX_NAMESPACE::OverflowExc ("Long int overflow - read a large "
 				    "64-bit integer in a 32-bit process.");
 	}
 
@@ -751,7 +755,7 @@ read (T &in, unsigned long &v)
 
 	if (b[4] || b[5] || b[6] || b[7])
 	{
-	    throw Iex::OverflowExc ("Long int overflow - read a large "
+	    throw IEX_NAMESPACE::OverflowExc ("Long int overflow - read a large "
 				    "64-bit integer in a 32-bit process.");
 	}
 
@@ -905,12 +909,19 @@ template <> inline int size <signed int> ()		{return 4;}
 template <> inline int size <unsigned int> ()		{return 4;}
 template <> inline int size <signed long> ()		{return 8;}
 template <> inline int size <unsigned long> ()		{return 8;}
+template <> inline int size <unsigned long long> ()     {return 8;}
 template <> inline int size <float> ()			{return 4;}
 template <> inline int size <double> ()			{return 8;}
 template <> inline int size <half> ()			{return 2;}
 
 
 } // namespace Xdr
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+#if defined (OPENEXR_IMF_INTERNAL_NAMESPACE_AUTO_EXPOSE)
+namespace Imf{using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;}
+#endif
+
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/ImfZip.cpp b/Source/OpenEXR/IlmImf/ImfZip.cpp
new file mode 100644
index 0000000..93d625e
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfZip.cpp
@@ -0,0 +1,196 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission. 
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#include "ImfZip.h"
+#include "ImfCheckedArithmetic.h"
+#include "ImfNamespace.h"
+#include "Iex.h"
+
+#include <math.h>
+#include <zlib.h>
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+Imf::Zip::Zip(size_t maxRawSize):
+    _maxRawSize(maxRawSize),
+    _tmpBuffer(0)
+{
+    _tmpBuffer = new char[_maxRawSize];
+}
+
+Imf::Zip::Zip(size_t maxScanLineSize, size_t numScanLines):
+    _maxRawSize(0),
+    _tmpBuffer(0)
+{
+    _maxRawSize = uiMult (maxScanLineSize, numScanLines);
+    _tmpBuffer  = new char[_maxRawSize];
+}
+
+Imf::Zip::~Zip()
+{
+    if (_tmpBuffer) delete[] _tmpBuffer;
+}
+
+size_t
+Imf::Zip::maxRawSize()
+{
+    return _maxRawSize;
+}
+
+size_t
+Imf::Zip::maxCompressedSize()
+{
+    return uiAdd (uiAdd (_maxRawSize,
+               size_t (ceil (_maxRawSize * 0.01))),
+                  size_t (100));
+}
+
+int
+Imf::Zip::compress(const char *raw, int rawSize, char *compressed)
+{
+    //
+    // Reorder the pixel data.
+    //
+
+    {
+        char *t1 = _tmpBuffer;
+        char *t2 = _tmpBuffer + (rawSize + 1) / 2;
+        const char *stop = raw + rawSize;
+
+        while (true)
+        {
+            if (raw < stop)
+            *(t1++) = *(raw++);
+            else
+            break;
+
+            if (raw < stop)
+            *(t2++) = *(raw++);
+            else
+            break;
+        }
+    }
+
+    //
+    // Predictor.
+    //
+
+    {
+        unsigned char *t    = (unsigned char *) _tmpBuffer + 1;
+        unsigned char *stop = (unsigned char *) _tmpBuffer + rawSize;
+        int p = t[-1];
+
+        while (t < stop)
+        {
+            int d = int (t[0]) - p + (128 + 256);
+            p = t[0];
+            t[0] = d;
+            ++t;
+        }
+    }
+
+    //
+    // Compress the data using zlib
+    //
+
+    uLongf outSize = int(ceil(rawSize * 1.01)) + 100;
+
+    if (Z_OK != ::compress ((Bytef *)compressed, &outSize,
+                (const Bytef *) _tmpBuffer, rawSize))
+    {
+        throw Iex::BaseExc ("Data compression (zlib) failed.");
+    }
+
+    return outSize;
+}
+
+int
+Imf::Zip::uncompress(const char *compressed, int compressedSize,
+                                            char *raw)
+{
+    //
+    // Decompress the data using zlib
+    //
+
+    uLongf outSize = _maxRawSize;
+
+    if (Z_OK != ::uncompress ((Bytef *)_tmpBuffer, &outSize,
+                     (const Bytef *) compressed, compressedSize))
+    {
+        throw Iex::InputExc ("Data decompression (zlib) failed.");
+    }
+
+    //
+    // Predictor.
+    //
+    {
+        unsigned char *t    = (unsigned char *) _tmpBuffer + 1;
+        unsigned char *stop = (unsigned char *) _tmpBuffer + outSize;
+
+        while (t < stop)
+        {
+            int d = int (t[-1]) + int (t[0]) - 128;
+            t[0] = d;
+            ++t;
+        }
+    }
+
+    //
+    // Reorder the pixel data.
+    //
+
+    {
+        const char *t1 = _tmpBuffer;
+        const char *t2 = _tmpBuffer + (outSize + 1) / 2;
+        char *s = raw;
+        char *stop = s + outSize;
+
+        while (true)
+        {
+            if (s < stop)
+            *(s++) = *(t1++);
+            else
+            break;
+
+            if (s < stop)
+            *(s++) = *(t2++);
+            else
+            break;
+        }
+    }
+
+    return outSize;
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmImf/ImfZip.h b/Source/OpenEXR/IlmImf/ImfZip.h
new file mode 100644
index 0000000..03f2c5e
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/ImfZip.h
@@ -0,0 +1,78 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission. 
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+#ifndef INCLUDED_IMF_ZIP_H
+#define INCLUDED_IMF_ZIP_H
+
+#include "ImfNamespace.h"
+
+#include <cstddef>
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+class Zip
+{
+    public:
+        explicit Zip(size_t rawMaxSize);
+        Zip(size_t maxScanlineSize, size_t numScanLines);
+        ~Zip();
+
+        size_t maxRawSize();
+        size_t maxCompressedSize();
+
+        //
+        // Compress the raw data into the provided buffer.
+        // Returns the amount of compressed data.
+        //
+        int compress(const char *raw, int rawSize, char *compressed);
+
+        // 
+        // Uncompress the compressed data into the provided
+        // buffer. Returns the amount of raw data actually decoded.
+        //
+        int uncompress(const char *compressed, int compressedSize,
+                                                 char *raw);
+
+    private:
+        size_t _maxRawSize;
+        char  *_tmpBuffer;
+
+        Zip();
+        Zip(const Zip&);
+};
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif
diff --git a/Source/OpenEXR/IlmImf/ImfZipCompressor.cpp b/Source/OpenEXR/IlmImf/ImfZipCompressor.cpp
index 1a56adf..b0d6989 100644
--- a/Source/OpenEXR/IlmImf/ImfZipCompressor.cpp
+++ b/Source/OpenEXR/IlmImf/ImfZipCompressor.cpp
@@ -39,14 +39,14 @@
 //	class ZipCompressor
 //
 //-----------------------------------------------------------------------------
-//#define ZLIB_WINAPI
 
-#include <ImfZipCompressor.h>
-#include <ImfCheckedArithmetic.h>
+#include "ImfZipCompressor.h"
+#include "ImfCheckedArithmetic.h"
 #include "Iex.h"
 #include <zlib.h>
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 ZipCompressor::ZipCompressor
@@ -57,28 +57,15 @@ ZipCompressor::ZipCompressor
     Compressor (hdr),
     _maxScanLineSize (maxScanLineSize),
     _numScanLines (numScanLines),
-    _tmpBuffer (0),
-    _outBuffer (0)
+    _outBuffer (0),
+    _zip(maxScanLineSize, numScanLines)
 {
-    size_t maxInBytes =
-        uiMult (maxScanLineSize, numScanLines);
-
-    size_t maxOutBytes =
-        uiAdd (uiAdd (maxInBytes,
-                      size_t (ceil (maxInBytes * 0.01))),
-               size_t (100));
-
-    _tmpBuffer =
-	new char [maxInBytes];
-
-    _outBuffer =
-	new char [maxOutBytes];
+    _outBuffer = new char[_zip.maxCompressedSize()];
 }
 
 
 ZipCompressor::~ZipCompressor ()
 {
-    delete [] _tmpBuffer;
     delete [] _outBuffer;
 }
 
@@ -97,7 +84,7 @@ ZipCompressor::compress (const char *inPtr,
 			 const char *&outPtr)
 {
     //
-    // Special case �- empty input buffer
+    // Special case �- empty input buffer
     //
 
     if (inSize == 0)
@@ -106,58 +93,7 @@ ZipCompressor::compress (const char *inPtr,
 	return 0;
     }
 
-    //
-    // Reorder the pixel data.
-    //
-
-    {
-	char *t1 = _tmpBuffer;
-	char *t2 = _tmpBuffer + (inSize + 1) / 2;
-	const char *stop = inPtr + inSize;
-
-	while (true)
-	{
-	    if (inPtr < stop)
-		*(t1++) = *(inPtr++);
-	    else
-		break;
-
-	    if (inPtr < stop)
-		*(t2++) = *(inPtr++);
-	    else
-		break;
-	}
-    }
-
-    //
-    // Predictor.
-    //
-
-    {
-	unsigned char *t = (unsigned char *) _tmpBuffer + 1;
-	unsigned char *stop = (unsigned char *) _tmpBuffer + inSize;
-	int p = t[-1];
-
-	while (t < stop)
-	{
-	    int d = int (t[0]) - p + (128 + 256);
-	    p = t[0];
-	    t[0] = d;
-	    ++t;
-	}
-    }
-
-    //
-    // Compress the data using zlib
-    //
-
-    uLongf outSize = int(ceil(inSize * 1.01)) + 100;
-
-    if (Z_OK != ::compress ((Bytef *)_outBuffer, &outSize,
-			    (const Bytef *) _tmpBuffer, inSize))
-    {
-	throw Iex::BaseExc ("Data compression (zlib) failed.");
-    }
+    int outSize = _zip.compress(inPtr, inSize, _outBuffer);
 
     outPtr = _outBuffer;
     return outSize;
@@ -171,7 +107,7 @@ ZipCompressor::uncompress (const char *inPtr,
 			   const char *&outPtr)
 {
     //
-    // Special case �- empty input buffer
+    // Special case �- empty input buffer
     //
 
     if (inSize == 0)
@@ -180,61 +116,12 @@ ZipCompressor::uncompress (const char *inPtr,
 	return 0;
     }
 
-    //
-    // Decompress the data using zlib
-    //
-
-    uLongf outSize = _maxScanLineSize * _numScanLines;
-
-    if (Z_OK != ::uncompress ((Bytef *)_tmpBuffer, &outSize,
-			      (const Bytef *) inPtr, inSize))
-    {
-	throw Iex::InputExc ("Data decompression (zlib) failed.");
-    }
-
-    //
-    // Predictor.
-    //
-
-    {
-	unsigned char *t = (unsigned char *) _tmpBuffer + 1;
-	unsigned char *stop = (unsigned char *) _tmpBuffer + outSize;
-
-	while (t < stop)
-	{
-	    int d = int (t[-1]) + int (t[0]) - 128;
-	    t[0] = d;
-	    ++t;
-	}
-    }
-
-    //
-    // Reorder the pixel data.
-    //
-
-    {
-	const char *t1 = _tmpBuffer;
-	const char *t2 = _tmpBuffer + (outSize + 1) / 2;
-	char *s = _outBuffer;
-	char *stop = s + outSize;
-
-	while (true)
-	{
-	    if (s < stop)
-		*(s++) = *(t1++);
-	    else
-		break;
-
-	    if (s < stop)
-		*(s++) = *(t2++);
-	    else
-		break;
-	}
-    }
+    int outSize = _zip.uncompress(inPtr, inSize, _outBuffer);
 
     outPtr = _outBuffer;
     return outSize;
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
+
diff --git a/Source/OpenEXR/IlmImf/ImfZipCompressor.h b/Source/OpenEXR/IlmImf/ImfZipCompressor.h
index a515348..03a88e8 100644
--- a/Source/OpenEXR/IlmImf/ImfZipCompressor.h
+++ b/Source/OpenEXR/IlmImf/ImfZipCompressor.h
@@ -43,9 +43,11 @@
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfCompressor.h>
+#include "ImfCompressor.h"
+#include "ImfZip.h"
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 class ZipCompressor: public Compressor
@@ -73,11 +75,15 @@ class ZipCompressor: public Compressor
 
     int		_maxScanLineSize;
     int		_numScanLines;
-    char *	_tmpBuffer;
     char *	_outBuffer;
+    Zip     _zip;
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
+
 
 #endif
diff --git a/Source/OpenEXR/IlmImf/Makefile.am b/Source/OpenEXR/IlmImf/Makefile.am
deleted file mode 100644
index d5b2b1c..0000000
--- a/Source/OpenEXR/IlmImf/Makefile.am
+++ /dev/null
@@ -1,128 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-lib_LTLIBRARIES = libIlmImf.la
-
-libIlmImf_la_SOURCES = ImfAttribute.cpp ImfBoxAttribute.cpp ImfCRgbaFile.cpp \
-		       ImfChannelList.cpp ImfChannelListAttribute.cpp \
-		       ImfFloatAttribute.cpp ImfFrameBuffer.cpp \
-		       ImfHeader.cpp ImfIO.cpp ImfInputFile.cpp \
-		       ImfIntAttribute.cpp ImfLineOrderAttribute.cpp \
-		       ImfMatrixAttribute.cpp ImfOpaqueAttribute.cpp \
-		       ImfOutputFile.cpp ImfRgbaFile.cpp \
-		       ImfStringAttribute.cpp ImfVecAttribute.cpp ImfHuf.cpp \
-		       ImfThreading.cpp \
-		       ImfWav.cpp ImfLut.cpp ImfCompressor.cpp \
-		       ImfRleCompressor.cpp ImfZipCompressor.cpp \
-		       ImfPizCompressor.cpp ImfB44Compressor.cpp ImfMisc.cpp \
-		       ImfCompressionAttribute.cpp ImfDoubleAttribute.cpp \
-		       ImfAttribute.h ImfBoxAttribute.h \
-		       ImfCRgbaFile.h ImfChannelList.h \
-		       ImfChannelListAttribute.h \
-		       ImfCompressionAttribute.h \
-	               ImfDoubleAttribute.h ImfFloatAttribute.h \
-	               ImfFrameBuffer.h ImfHeader.h ImfIO.h \
-		       ImfInputFile.h ImfIntAttribute.h \
-		       ImfLineOrderAttribute.h ImfMatrixAttribute.h \
-		       ImfOpaqueAttribute.h ImfOutputFile.h \
-		       ImfRgbaFile.h ImfStringAttribute.h \
-		       ImfVecAttribute.h ImfHuf.h ImfWav.h ImfLut.h \
-		       ImfArray.h ImfCompression.h ImfLineOrder.h \
-		       ImfName.h ImfPixelType.h ImfVersion.h ImfXdr.h \
-		       ImfCompressor.h ImfRleCompressor.h ImfZipCompressor.h \
-		       ImfPizCompressor.h ImfMisc.h ImfAutoArray.h \
-		       ImfConvert.cpp ImfConvert.h ImfPreviewImage.cpp \
-		       ImfPreviewImage.h ImfPreviewImageAttribute.cpp \
-		       ImfPreviewImageAttribute.h ImfVersion.cpp \
-		       ImfChromaticities.cpp ImfChromaticities.h \
-		       ImfChromaticitiesAttribute.cpp \
-		       ImfChromaticitiesAttribute.h \
-		       ImfKeyCode.cpp ImfKeyCode.h \
-		       ImfKeyCodeAttribute.cpp ImfKeyCodeAttribute.h \
-		       ImfTimeCode.cpp ImfTimeCode.h \
-		       ImfTimeCodeAttribute.cpp ImfTimeCodeAttribute.h \
-		       ImfRational.cpp ImfRational.h \
-		       ImfRationalAttribute.cpp ImfRationalAttribute.h \
-		       ImfFramesPerSecond.cpp ImfFramesPerSecond.h \
-		       ImfStandardAttributes.cpp ImfStandardAttributes.h \
-		       ImfStdIO.cpp ImfStdIO.h ImfEnvmap.cpp ImfEnvmap.h \
-		       ImfEnvmapAttribute.cpp ImfEnvmapAttribute.h \
-		       ImfInt64.h ImfRgba.h ImfScanLineInputFile.cpp \
-		       ImfScanLineInputFile.h ImfTiledInputFile.cpp \
-		       ImfTiledMisc.cpp ImfTiledOutputFile.cpp \
-		       ImfTiledRgbaFile.cpp ImfTileDescriptionAttribute.cpp \
-		       ImfTileOffsets.cpp ImfTileDescription.h \
-		       ImfTileDescriptionAttribute.h ImfTileOffsets.h \
-		       ImfTiledInputFile.h ImfTiledMisc.h \
-		       ImfTiledOutputFile.h ImfTiledRgbaFile.h \
-		       ImfRgbaYca.cpp ImfRgbaYca.h \
-		       ImfPxr24Compressor.cpp ImfPxr24Compressor.h \
- 		       ImfTestFile.cpp ImfTestFile.h ImfThreading.h \
-                       ImfStringVectorAttribute.cpp ImfStringVectorAttribute.h \
-                       ImfMultiView.cpp ImfMultiView.h \
-		       ImfAcesFile.cpp ImfAcesFile.h \
-		       ImfCheckedArithmetic.h
-
-libIlmImf_la_LDFLAGS = @ILMBASE_LDFLAGS@ -version-info @LIBTOOL_VERSION@ \
-			-no-undefined
-
-libIlmImf_la_LIBADD =  -lz @ILMBASE_LIBS@
-
-libIlmImfincludedir = $(includedir)/OpenEXR
-
-libIlmImfinclude_HEADERS = ImfAttribute.h ImfBoxAttribute.h \
-			   ImfCRgbaFile.h ImfChannelList.h \
-			   ImfChannelListAttribute.h \
-			   ImfCompressionAttribute.h \
-	                   ImfDoubleAttribute.h ImfFloatAttribute.h \
-	                   ImfFrameBuffer.h ImfHeader.h ImfIO.h \
-			   ImfInputFile.h ImfIntAttribute.h \
-			   ImfLineOrderAttribute.h ImfMatrixAttribute.h \
-			   ImfOpaqueAttribute.h ImfOutputFile.h \
-			   ImfRgbaFile.h ImfStringAttribute.h \
-			   ImfVecAttribute.h ImfHuf.h ImfWav.h ImfLut.h \
-			   ImfArray.h ImfCompression.h ImfLineOrder.h \
-			   ImfName.h ImfPixelType.h ImfVersion.h ImfXdr.h \
-			   ImfConvert.h ImfPreviewImage.h \
-			   ImfPreviewImageAttribute.h ImfChromaticities.h \
-			   ImfChromaticitiesAttribute.h \
-			   ImfKeyCode.h ImfKeyCodeAttribute.h \
-			   ImfTimeCode.h ImfTimeCodeAttribute.h \
-			   ImfRational.h ImfRationalAttribute.h \
-			   ImfFramesPerSecond.h \
-			   ImfStandardAttributes.h \
-		       	   ImfEnvmap.h \
-		       	   ImfEnvmapAttribute.h \
-		           ImfInt64.h ImfRgba.h \
-		           ImfTileDescription.h \
-		           ImfTileDescriptionAttribute.h \
-		           ImfTiledInputFile.h \
-		           ImfTiledOutputFile.h ImfTiledRgbaFile.h \
-			   ImfRgbaYca.h \
-			   ImfTestFile.h ImfThreading.h \
-			   ImfB44Compressor.h ImfStringVectorAttribute.h \
-			   ImfMultiView.h \
-			   ImfAcesFile.h
-
-noinst_HEADERS = ImfCompressor.h ImfRleCompressor.h ImfZipCompressor.h \
-		 ImfPizCompressor.h ImfMisc.h ImfAutoArray.h ImfTiledMisc.h \
-		 ImfTileOffsets.h ImfScanLineInputFile.h ImfPxr24Compressor.h \
-		 ImfCheckedArithmetic.h
-
-EXTRA_DIST = $(noinst_HEADERS) b44ExpLogTable.cpp b44ExpLogTable.h
-
-
-INCLUDES = @ILMBASE_CXXFLAGS@ \
-	   -I$(top_builddir)  \
-	   -I$(top_srcdir)/config
-
-CLEANFILES = b44ExpLogTable b44ExpLogTable.h
-
-b44ExpLogTable_SOURCES = b44ExpLogTable.cpp
-b44ExpLogTable_LDADD = @ILMBASE_LDFLAGS@ @ILMBASE_LIBS@
-
-b44ExpLogTable.h: b44ExpLogTable
-	./b44ExpLogTable > b44ExpLogTable.h
-
-BUILT_SOURCES = b44ExpLogTable.h
-
-noinst_PROGRAMS = b44ExpLogTable
diff --git a/Source/OpenEXR/IlmImf/Makefile.in b/Source/OpenEXR/IlmImf/Makefile.in
deleted file mode 100644
index d4c8107..0000000
--- a/Source/OpenEXR/IlmImf/Makefile.in
+++ /dev/null
@@ -1,736 +0,0 @@
-# Makefile.in generated by automake 1.9.6 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005  Free Software Foundation, Inc.
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
- at SET_MAKE@
-
-
-
-srcdir = @srcdir@
-top_srcdir = @top_srcdir@
-VPATH = @srcdir@
-pkgdatadir = $(datadir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-top_builddir = ..
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-INSTALL = @INSTALL@
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-build_triplet = @build@
-host_triplet = @host@
-noinst_PROGRAMS = b44ExpLogTable$(EXEEXT)
-subdir = IlmImf
-DIST_COMMON = $(libIlmImfinclude_HEADERS) $(noinst_HEADERS) \
-	$(srcdir)/Makefile.am $(srcdir)/Makefile.in
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/compilelinkrun.m4 \
-	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
-	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
-	$(top_srcdir)/m4/lt~obsolete.m4 \
-	$(top_srcdir)/m4/path.pkgconfig.m4 $(top_srcdir)/m4/threads.m4 \
-	$(top_srcdir)/configure.ac
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
-	$(ACLOCAL_M4)
-mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config/OpenEXRConfig.h
-CONFIG_CLEAN_FILES =
-am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
-am__vpath_adj = case $$p in \
-    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
-    *) f=$$p;; \
-  esac;
-am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
-am__installdirs = "$(DESTDIR)$(libdir)" \
-	"$(DESTDIR)$(libIlmImfincludedir)"
-libLTLIBRARIES_INSTALL = $(INSTALL)
-LTLIBRARIES = $(lib_LTLIBRARIES)
-libIlmImf_la_DEPENDENCIES =
-am_libIlmImf_la_OBJECTS = ImfAttribute.lo ImfBoxAttribute.lo \
-	ImfCRgbaFile.lo ImfChannelList.lo ImfChannelListAttribute.lo \
-	ImfFloatAttribute.lo ImfFrameBuffer.lo ImfHeader.lo ImfIO.lo \
-	ImfInputFile.lo ImfIntAttribute.lo ImfLineOrderAttribute.lo \
-	ImfMatrixAttribute.lo ImfOpaqueAttribute.lo ImfOutputFile.lo \
-	ImfRgbaFile.lo ImfStringAttribute.lo ImfVecAttribute.lo \
-	ImfHuf.lo ImfThreading.lo ImfWav.lo ImfLut.lo ImfCompressor.lo \
-	ImfRleCompressor.lo ImfZipCompressor.lo ImfPizCompressor.lo \
-	ImfB44Compressor.lo ImfMisc.lo ImfCompressionAttribute.lo \
-	ImfDoubleAttribute.lo ImfConvert.lo ImfPreviewImage.lo \
-	ImfPreviewImageAttribute.lo ImfVersion.lo ImfChromaticities.lo \
-	ImfChromaticitiesAttribute.lo ImfKeyCode.lo \
-	ImfKeyCodeAttribute.lo ImfTimeCode.lo ImfTimeCodeAttribute.lo \
-	ImfRational.lo ImfRationalAttribute.lo ImfFramesPerSecond.lo \
-	ImfStandardAttributes.lo ImfStdIO.lo ImfEnvmap.lo \
-	ImfEnvmapAttribute.lo ImfScanLineInputFile.lo \
-	ImfTiledInputFile.lo ImfTiledMisc.lo ImfTiledOutputFile.lo \
-	ImfTiledRgbaFile.lo ImfTileDescriptionAttribute.lo \
-	ImfTileOffsets.lo ImfRgbaYca.lo ImfPxr24Compressor.lo \
-	ImfTestFile.lo ImfStringVectorAttribute.lo ImfMultiView.lo \
-	ImfAcesFile.lo
-libIlmImf_la_OBJECTS = $(am_libIlmImf_la_OBJECTS)
-PROGRAMS = $(noinst_PROGRAMS)
-am_b44ExpLogTable_OBJECTS = b44ExpLogTable.$(OBJEXT)
-b44ExpLogTable_OBJECTS = $(am_b44ExpLogTable_OBJECTS)
-b44ExpLogTable_DEPENDENCIES =
-DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/config
-depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
-CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
-	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
-LTCXXCOMPILE = $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) \
-	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
-	$(AM_CXXFLAGS) $(CXXFLAGS)
-CXXLD = $(CXX)
-CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \
-	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
-COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
-	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
-	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
-	$(AM_CFLAGS) $(CFLAGS)
-CCLD = $(CC)
-LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
-	$(AM_LDFLAGS) $(LDFLAGS) -o $@
-SOURCES = $(libIlmImf_la_SOURCES) $(b44ExpLogTable_SOURCES)
-DIST_SOURCES = $(libIlmImf_la_SOURCES) $(b44ExpLogTable_SOURCES)
-libIlmImfincludeHEADERS_INSTALL = $(INSTALL_HEADER)
-HEADERS = $(libIlmImfinclude_HEADERS) $(noinst_HEADERS)
-ETAGS = etags
-CTAGS = ctags
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = @ACLOCAL@
-AMDEP_FALSE = @AMDEP_FALSE@
-AMDEP_TRUE = @AMDEP_TRUE@
-AMTAR = @AMTAR@
-AM_CFLAGS = @AM_CFLAGS@
-AM_CXXFLAGS = @AM_CXXFLAGS@
-AR = @AR@
-AUTOCONF = @AUTOCONF@
-AUTOHEADER = @AUTOHEADER@
-AUTOMAKE = @AUTOMAKE@
-AWK = @AWK@
-BUILD_IMFEXAMPLES_FALSE = @BUILD_IMFEXAMPLES_FALSE@
-BUILD_IMFEXAMPLES_TRUE = @BUILD_IMFEXAMPLES_TRUE@
-BUILD_IMFFUZZTEST_FALSE = @BUILD_IMFFUZZTEST_FALSE@
-BUILD_IMFFUZZTEST_TRUE = @BUILD_IMFFUZZTEST_TRUE@
-CC = @CC@
-CCDEPMODE = @CCDEPMODE@
-CFLAGS = @CFLAGS@
-CPP = @CPP@
-CPPFLAGS = @CPPFLAGS@
-CXX = @CXX@
-CXXCPP = @CXXCPP@
-CXXDEPMODE = @CXXDEPMODE@
-CXXFLAGS = @CXXFLAGS@
-CYGPATH_W = @CYGPATH_W@
-DEFS = @DEFS@
-DEPDIR = @DEPDIR@
-DSYMUTIL = @DSYMUTIL@
-DUMPBIN = @DUMPBIN@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EGREP = @EGREP@
-EXEEXT = @EXEEXT@
-FGREP = @FGREP@
-GREP = @GREP@
-ILMBASE_CXXFLAGS = @ILMBASE_CXXFLAGS@
-ILMBASE_LDFLAGS = @ILMBASE_LDFLAGS@
-ILMBASE_LIBS = @ILMBASE_LIBS@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LD = @LD@
-LDFLAGS = @LDFLAGS@
-LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
-LIBTOOL = @LIBTOOL@
-LIBTOOL_VERSION = @LIBTOOL_VERSION@
-LIPO = @LIPO@
-LN_S = @LN_S@
-LTLIBOBJS = @LTLIBOBJS@
-MAINT = @MAINT@
-MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
-MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
-MAKEINFO = @MAKEINFO@
-NM = @NM@
-NMEDIT = @NMEDIT@
-OBJDUMP = @OBJDUMP@
-OBJEXT = @OBJEXT@
-OPENEXR_VERSION = @OPENEXR_VERSION@
-OTOOL = @OTOOL@
-OTOOL64 = @OTOOL64@
-PACKAGE = @PACKAGE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-PKG_CONFIG = @PKG_CONFIG@
-PTHREAD_CC = @PTHREAD_CC@
-PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
-PTHREAD_LIBS = @PTHREAD_LIBS@
-RANLIB = @RANLIB@
-SED = @SED@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-STRIP = @STRIP@
-VERSION = @VERSION@
-ac_ct_AR = @ac_ct_AR@
-ac_ct_CC = @ac_ct_CC@
-ac_ct_CXX = @ac_ct_CXX@
-ac_ct_DSYMUTIL = @ac_ct_DSYMUTIL@
-ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
-ac_ct_LIPO = @ac_ct_LIPO@
-ac_ct_NMEDIT = @ac_ct_NMEDIT@
-ac_ct_OBJDUMP = @ac_ct_OBJDUMP@
-ac_ct_OTOOL = @ac_ct_OTOOL@
-ac_ct_OTOOL64 = @ac_ct_OTOOL64@
-ac_ct_RANLIB = @ac_ct_RANLIB@
-ac_ct_STRIP = @ac_ct_STRIP@
-acx_pthread_config = @acx_pthread_config@
-am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
-am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
-am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
-am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
-am__include = @am__include@
-am__leading_dot = @am__leading_dot@
-am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
-bindir = @bindir@
-build = @build@
-build_alias = @build_alias@
-build_cpu = @build_cpu@
-build_os = @build_os@
-build_vendor = @build_vendor@
-datadir = @datadir@
-exec_prefix = @exec_prefix@
-host = @host@
-host_alias = @host_alias@
-host_cpu = @host_cpu@
-host_os = @host_os@
-host_vendor = @host_vendor@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-libdir = @libdir@
-libexecdir = @libexecdir@
-localstatedir = @localstatedir@
-lt_ECHO = @lt_ECHO@
-mandir = @mandir@
-mkdir_p = @mkdir_p@
-oldincludedir = @oldincludedir@
-prefix = @prefix@
-program_transform_name = @program_transform_name@
-sbindir = @sbindir@
-sharedstatedir = @sharedstatedir@
-sysconfdir = @sysconfdir@
-target_alias = @target_alias@
-lib_LTLIBRARIES = libIlmImf.la
-libIlmImf_la_SOURCES = ImfAttribute.cpp ImfBoxAttribute.cpp ImfCRgbaFile.cpp \
-		       ImfChannelList.cpp ImfChannelListAttribute.cpp \
-		       ImfFloatAttribute.cpp ImfFrameBuffer.cpp \
-		       ImfHeader.cpp ImfIO.cpp ImfInputFile.cpp \
-		       ImfIntAttribute.cpp ImfLineOrderAttribute.cpp \
-		       ImfMatrixAttribute.cpp ImfOpaqueAttribute.cpp \
-		       ImfOutputFile.cpp ImfRgbaFile.cpp \
-		       ImfStringAttribute.cpp ImfVecAttribute.cpp ImfHuf.cpp \
-		       ImfThreading.cpp \
-		       ImfWav.cpp ImfLut.cpp ImfCompressor.cpp \
-		       ImfRleCompressor.cpp ImfZipCompressor.cpp \
-		       ImfPizCompressor.cpp ImfB44Compressor.cpp ImfMisc.cpp \
-		       ImfCompressionAttribute.cpp ImfDoubleAttribute.cpp \
-		       ImfAttribute.h ImfBoxAttribute.h \
-		       ImfCRgbaFile.h ImfChannelList.h \
-		       ImfChannelListAttribute.h \
-		       ImfCompressionAttribute.h \
-	               ImfDoubleAttribute.h ImfFloatAttribute.h \
-	               ImfFrameBuffer.h ImfHeader.h ImfIO.h \
-		       ImfInputFile.h ImfIntAttribute.h \
-		       ImfLineOrderAttribute.h ImfMatrixAttribute.h \
-		       ImfOpaqueAttribute.h ImfOutputFile.h \
-		       ImfRgbaFile.h ImfStringAttribute.h \
-		       ImfVecAttribute.h ImfHuf.h ImfWav.h ImfLut.h \
-		       ImfArray.h ImfCompression.h ImfLineOrder.h \
-		       ImfName.h ImfPixelType.h ImfVersion.h ImfXdr.h \
-		       ImfCompressor.h ImfRleCompressor.h ImfZipCompressor.h \
-		       ImfPizCompressor.h ImfMisc.h ImfAutoArray.h \
-		       ImfConvert.cpp ImfConvert.h ImfPreviewImage.cpp \
-		       ImfPreviewImage.h ImfPreviewImageAttribute.cpp \
-		       ImfPreviewImageAttribute.h ImfVersion.cpp \
-		       ImfChromaticities.cpp ImfChromaticities.h \
-		       ImfChromaticitiesAttribute.cpp \
-		       ImfChromaticitiesAttribute.h \
-		       ImfKeyCode.cpp ImfKeyCode.h \
-		       ImfKeyCodeAttribute.cpp ImfKeyCodeAttribute.h \
-		       ImfTimeCode.cpp ImfTimeCode.h \
-		       ImfTimeCodeAttribute.cpp ImfTimeCodeAttribute.h \
-		       ImfRational.cpp ImfRational.h \
-		       ImfRationalAttribute.cpp ImfRationalAttribute.h \
-		       ImfFramesPerSecond.cpp ImfFramesPerSecond.h \
-		       ImfStandardAttributes.cpp ImfStandardAttributes.h \
-		       ImfStdIO.cpp ImfStdIO.h ImfEnvmap.cpp ImfEnvmap.h \
-		       ImfEnvmapAttribute.cpp ImfEnvmapAttribute.h \
-		       ImfInt64.h ImfRgba.h ImfScanLineInputFile.cpp \
-		       ImfScanLineInputFile.h ImfTiledInputFile.cpp \
-		       ImfTiledMisc.cpp ImfTiledOutputFile.cpp \
-		       ImfTiledRgbaFile.cpp ImfTileDescriptionAttribute.cpp \
-		       ImfTileOffsets.cpp ImfTileDescription.h \
-		       ImfTileDescriptionAttribute.h ImfTileOffsets.h \
-		       ImfTiledInputFile.h ImfTiledMisc.h \
-		       ImfTiledOutputFile.h ImfTiledRgbaFile.h \
-		       ImfRgbaYca.cpp ImfRgbaYca.h \
-		       ImfPxr24Compressor.cpp ImfPxr24Compressor.h \
- 		       ImfTestFile.cpp ImfTestFile.h ImfThreading.h \
-                       ImfStringVectorAttribute.cpp ImfStringVectorAttribute.h \
-                       ImfMultiView.cpp ImfMultiView.h \
-		       ImfAcesFile.cpp ImfAcesFile.h \
-		       ImfCheckedArithmetic.h
-
-libIlmImf_la_LDFLAGS = @ILMBASE_LDFLAGS@ -version-info @LIBTOOL_VERSION@ \
-			-no-undefined
-
-libIlmImf_la_LIBADD = -lz @ILMBASE_LIBS@
-libIlmImfincludedir = $(includedir)/OpenEXR
-libIlmImfinclude_HEADERS = ImfAttribute.h ImfBoxAttribute.h \
-			   ImfCRgbaFile.h ImfChannelList.h \
-			   ImfChannelListAttribute.h \
-			   ImfCompressionAttribute.h \
-	                   ImfDoubleAttribute.h ImfFloatAttribute.h \
-	                   ImfFrameBuffer.h ImfHeader.h ImfIO.h \
-			   ImfInputFile.h ImfIntAttribute.h \
-			   ImfLineOrderAttribute.h ImfMatrixAttribute.h \
-			   ImfOpaqueAttribute.h ImfOutputFile.h \
-			   ImfRgbaFile.h ImfStringAttribute.h \
-			   ImfVecAttribute.h ImfHuf.h ImfWav.h ImfLut.h \
-			   ImfArray.h ImfCompression.h ImfLineOrder.h \
-			   ImfName.h ImfPixelType.h ImfVersion.h ImfXdr.h \
-			   ImfConvert.h ImfPreviewImage.h \
-			   ImfPreviewImageAttribute.h ImfChromaticities.h \
-			   ImfChromaticitiesAttribute.h \
-			   ImfKeyCode.h ImfKeyCodeAttribute.h \
-			   ImfTimeCode.h ImfTimeCodeAttribute.h \
-			   ImfRational.h ImfRationalAttribute.h \
-			   ImfFramesPerSecond.h \
-			   ImfStandardAttributes.h \
-		       	   ImfEnvmap.h \
-		       	   ImfEnvmapAttribute.h \
-		           ImfInt64.h ImfRgba.h \
-		           ImfTileDescription.h \
-		           ImfTileDescriptionAttribute.h \
-		           ImfTiledInputFile.h \
-		           ImfTiledOutputFile.h ImfTiledRgbaFile.h \
-			   ImfRgbaYca.h \
-			   ImfTestFile.h ImfThreading.h \
-			   ImfB44Compressor.h ImfStringVectorAttribute.h \
-			   ImfMultiView.h \
-			   ImfAcesFile.h
-
-noinst_HEADERS = ImfCompressor.h ImfRleCompressor.h ImfZipCompressor.h \
-		 ImfPizCompressor.h ImfMisc.h ImfAutoArray.h ImfTiledMisc.h \
-		 ImfTileOffsets.h ImfScanLineInputFile.h ImfPxr24Compressor.h \
-		 ImfCheckedArithmetic.h
-
-EXTRA_DIST = $(noinst_HEADERS) b44ExpLogTable.cpp b44ExpLogTable.h
-INCLUDES = @ILMBASE_CXXFLAGS@ \
-	   -I$(top_builddir)  \
-	   -I$(top_srcdir)/config
-
-CLEANFILES = b44ExpLogTable b44ExpLogTable.h
-b44ExpLogTable_SOURCES = b44ExpLogTable.cpp
-b44ExpLogTable_LDADD = @ILMBASE_LDFLAGS@ @ILMBASE_LIBS@
-BUILT_SOURCES = b44ExpLogTable.h
-all: $(BUILT_SOURCES)
-	$(MAKE) $(AM_MAKEFLAGS) all-am
-
-.SUFFIXES:
-.SUFFIXES: .cpp .lo .o .obj
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
-	@for dep in $?; do \
-	  case '$(am__configure_deps)' in \
-	    *$$dep*) \
-	      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
-		&& exit 0; \
-	      exit 1;; \
-	  esac; \
-	done; \
-	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu  IlmImf/Makefile'; \
-	cd $(top_srcdir) && \
-	  $(AUTOMAKE) --gnu  IlmImf/Makefile
-.PRECIOUS: Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
-	@case '$?' in \
-	  *config.status*) \
-	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
-	  *) \
-	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
-	esac;
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-install-libLTLIBRARIES: $(lib_LTLIBRARIES)
-	@$(NORMAL_INSTALL)
-	test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)"
-	@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
-	  if test -f $$p; then \
-	    f=$(am__strip_dir) \
-	    echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
-	    $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
-	  else :; fi; \
-	done
-
-uninstall-libLTLIBRARIES:
-	@$(NORMAL_UNINSTALL)
-	@set -x; list='$(lib_LTLIBRARIES)'; for p in $$list; do \
-	  p=$(am__strip_dir) \
-	  echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
-	  $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
-	done
-
-clean-libLTLIBRARIES:
-	-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
-	@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
-	  dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
-	  test "$$dir" != "$$p" || dir=.; \
-	  echo "rm -f \"$${dir}/so_locations\""; \
-	  rm -f "$${dir}/so_locations"; \
-	done
-libIlmImf.la: $(libIlmImf_la_OBJECTS) $(libIlmImf_la_DEPENDENCIES) 
-	$(CXXLINK) -rpath $(libdir) $(libIlmImf_la_LDFLAGS) $(libIlmImf_la_OBJECTS) $(libIlmImf_la_LIBADD) $(LIBS)
-
-clean-noinstPROGRAMS:
-	@list='$(noinst_PROGRAMS)'; for p in $$list; do \
-	  f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
-	  echo " rm -f $$p $$f"; \
-	  rm -f $$p $$f ; \
-	done
-b44ExpLogTable$(EXEEXT): $(b44ExpLogTable_OBJECTS) $(b44ExpLogTable_DEPENDENCIES) 
-	@rm -f b44ExpLogTable$(EXEEXT)
-	$(CXXLINK) $(b44ExpLogTable_LDFLAGS) $(b44ExpLogTable_OBJECTS) $(b44ExpLogTable_LDADD) $(LIBS)
-
-mostlyclean-compile:
-	-rm -f *.$(OBJEXT)
-
-distclean-compile:
-	-rm -f *.tab.c
-
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfAcesFile.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfAttribute.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfB44Compressor.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfBoxAttribute.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfCRgbaFile.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfChannelList.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfChannelListAttribute.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfChromaticities.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfChromaticitiesAttribute.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfCompressionAttribute.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfCompressor.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfConvert.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfDoubleAttribute.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfEnvmap.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfEnvmapAttribute.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfFloatAttribute.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfFrameBuffer.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfFramesPerSecond.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfHeader.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfHuf.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfIO.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfInputFile.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfIntAttribute.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfKeyCode.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfKeyCodeAttribute.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfLineOrderAttribute.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfLut.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfMatrixAttribute.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfMisc.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfMultiView.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfOpaqueAttribute.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfOutputFile.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfPizCompressor.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfPreviewImage.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfPreviewImageAttribute.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfPxr24Compressor.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfRational.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfRationalAttribute.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfRgbaFile.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfRgbaYca.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfRleCompressor.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfScanLineInputFile.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfStandardAttributes.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfStdIO.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfStringAttribute.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfStringVectorAttribute.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfTestFile.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfThreading.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfTileDescriptionAttribute.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfTileOffsets.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfTiledInputFile.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfTiledMisc.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfTiledOutputFile.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfTiledRgbaFile.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfTimeCode.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfTimeCodeAttribute.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfVecAttribute.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfVersion.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfWav.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImfZipCompressor.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/b44ExpLogTable.Po at am__quote@
-
-.cpp.o:
- at am__fastdepCXX_TRUE@	if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
- at am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(CXXCOMPILE) -c -o $@ $<
-
-.cpp.obj:
- at am__fastdepCXX_TRUE@	if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
- at am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
-
-.cpp.lo:
- at am__fastdepCXX_TRUE@	if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
- at am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(LTCXXCOMPILE) -c -o $@ $<
-
-mostlyclean-libtool:
-	-rm -f *.lo
-
-clean-libtool:
-	-rm -rf .libs _libs
-
-distclean-libtool:
-	-rm -f libtool
-uninstall-info-am:
-install-libIlmImfincludeHEADERS: $(libIlmImfinclude_HEADERS)
-	@$(NORMAL_INSTALL)
-	test -z "$(libIlmImfincludedir)" || $(mkdir_p) "$(DESTDIR)$(libIlmImfincludedir)"
-	@list='$(libIlmImfinclude_HEADERS)'; for p in $$list; do \
-	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
-	  f=$(am__strip_dir) \
-	  echo " $(libIlmImfincludeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(libIlmImfincludedir)/$$f'"; \
-	  $(libIlmImfincludeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(libIlmImfincludedir)/$$f"; \
-	done
-
-uninstall-libIlmImfincludeHEADERS:
-	@$(NORMAL_UNINSTALL)
-	@list='$(libIlmImfinclude_HEADERS)'; for p in $$list; do \
-	  f=$(am__strip_dir) \
-	  echo " rm -f '$(DESTDIR)$(libIlmImfincludedir)/$$f'"; \
-	  rm -f "$(DESTDIR)$(libIlmImfincludedir)/$$f"; \
-	done
-
-ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
-	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
-	unique=`for i in $$list; do \
-	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
-	mkid -fID $$unique
-tags: TAGS
-
-TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
-		$(TAGS_FILES) $(LISP)
-	tags=; \
-	here=`pwd`; \
-	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
-	unique=`for i in $$list; do \
-	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
-	if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
-	  test -n "$$unique" || unique=$$empty_fix; \
-	  $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
-	    $$tags $$unique; \
-	fi
-ctags: CTAGS
-CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
-		$(TAGS_FILES) $(LISP)
-	tags=; \
-	here=`pwd`; \
-	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
-	unique=`for i in $$list; do \
-	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
-	test -z "$(CTAGS_ARGS)$$tags$$unique" \
-	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
-	     $$tags $$unique
-
-GTAGS:
-	here=`$(am__cd) $(top_builddir) && pwd` \
-	  && cd $(top_srcdir) \
-	  && gtags -i $(GTAGS_ARGS) $$here
-
-distclean-tags:
-	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
-distdir: $(DISTFILES)
-	@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
-	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
-	list='$(DISTFILES)'; for file in $$list; do \
-	  case $$file in \
-	    $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
-	    $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
-	  esac; \
-	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
-	  dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
-	  if test "$$dir" != "$$file" && test "$$dir" != "."; then \
-	    dir="/$$dir"; \
-	    $(mkdir_p) "$(distdir)$$dir"; \
-	  else \
-	    dir=''; \
-	  fi; \
-	  if test -d $$d/$$file; then \
-	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
-	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
-	    fi; \
-	    cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
-	  else \
-	    test -f $(distdir)/$$file \
-	    || cp -p $$d/$$file $(distdir)/$$file \
-	    || exit 1; \
-	  fi; \
-	done
-check-am: all-am
-check: $(BUILT_SOURCES)
-	$(MAKE) $(AM_MAKEFLAGS) check-am
-all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS)
-installdirs:
-	for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libIlmImfincludedir)"; do \
-	  test -z "$$dir" || $(mkdir_p) "$$dir"; \
-	done
-install: $(BUILT_SOURCES)
-	$(MAKE) $(AM_MAKEFLAGS) install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
-	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
-	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	  `test -z '$(STRIP)' || \
-	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
-mostlyclean-generic:
-
-clean-generic:
-	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
-
-distclean-generic:
-	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-
-maintainer-clean-generic:
-	@echo "This command is intended for maintainers to use"
-	@echo "it deletes files that may require special tools to rebuild."
-	-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
-clean: clean-am
-
-clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
-	clean-noinstPROGRAMS mostlyclean-am
-
-distclean: distclean-am
-	-rm -rf ./$(DEPDIR)
-	-rm -f Makefile
-distclean-am: clean-am distclean-compile distclean-generic \
-	distclean-libtool distclean-tags
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-info: info-am
-
-info-am:
-
-install-data-am: install-libIlmImfincludeHEADERS
-
-install-exec-am: install-libLTLIBRARIES
-
-install-info: install-info-am
-
-install-man:
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
-	-rm -rf ./$(DEPDIR)
-	-rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-compile mostlyclean-generic \
-	mostlyclean-libtool
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am: uninstall-info-am uninstall-libIlmImfincludeHEADERS \
-	uninstall-libLTLIBRARIES
-
-.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
-	clean-libLTLIBRARIES clean-libtool clean-noinstPROGRAMS ctags \
-	distclean distclean-compile distclean-generic \
-	distclean-libtool distclean-tags distdir dvi dvi-am html \
-	html-am info info-am install install-am install-data \
-	install-data-am install-exec install-exec-am install-info \
-	install-info-am install-libIlmImfincludeHEADERS \
-	install-libLTLIBRARIES install-man install-strip installcheck \
-	installcheck-am installdirs maintainer-clean \
-	maintainer-clean-generic mostlyclean mostlyclean-compile \
-	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
-	tags uninstall uninstall-am uninstall-info-am \
-	uninstall-libIlmImfincludeHEADERS uninstall-libLTLIBRARIES
-
-
-b44ExpLogTable.h: b44ExpLogTable
-	./b44ExpLogTable > b44ExpLogTable.h
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
diff --git a/Source/OpenEXR/IlmImf/dwaLookups.cpp b/Source/OpenEXR/IlmImf/dwaLookups.cpp
new file mode 100644
index 0000000..19ec831
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/dwaLookups.cpp
@@ -0,0 +1,573 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2009-2014 DreamWorks Animation LLC. 
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of DreamWorks Animation nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+//
+// A program to generate various acceleration lookup tables 
+// for Imf::DwaCompressor
+//
+
+#include <cstddef>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <vector>
+
+#include <OpenEXRConfig.h>
+
+#ifdef OPENEXR_IMF_HAVE_SYSCONF_NPROCESSORS_ONLN
+#include <unistd.h>
+#endif
+
+#include <half.h>
+#include <IlmThread.h>
+#include <IlmThreadSemaphore.h>
+#include <ImfIO.h>
+#include <ImfXdr.h>
+#include "ImfNamespace.h"
+
+using namespace OPENEXR_IMF_NAMESPACE;
+
+namespace {
+
+    class LutHeaderWorker
+    {
+        public:
+            class Runner : public IlmThread::Thread
+            {
+                public:
+                    Runner(LutHeaderWorker &worker, bool output):
+                        IlmThread::Thread(),
+                        _worker(worker),
+                        _output(output)
+                    {
+                        start();
+                    }
+
+                    virtual ~Runner()
+                    {
+                        _semaphore.wait();
+                    }
+
+                    virtual void run()
+                    {
+                        _semaphore.post();
+                        _worker.run(_output);
+                    }
+
+                private:
+                    LutHeaderWorker     &_worker;
+                    bool                 _output;
+                    IlmThread::Semaphore _semaphore;
+
+            }; // class LutHeaderWorker::Runner
+
+
+            LutHeaderWorker(size_t startValue,
+                            size_t endValue):
+                _lastCandidateCount(0),
+                _startValue(startValue),
+                _endValue(endValue),
+                _numElements(0),
+                _offset(new size_t[numValues()]),
+                _elements(new unsigned short[1024*1024*2])
+            {
+            }
+
+            ~LutHeaderWorker()
+            {
+                delete[] _offset;
+                delete[] _elements;
+            }
+
+            size_t lastCandidateCount() const
+            {
+                return _lastCandidateCount;
+            }
+
+            size_t numValues() const 
+            {
+                return _endValue - _startValue;
+            }
+
+            size_t numElements() const
+            {
+                return _numElements;
+            }
+
+            const size_t* offset() const
+            {
+                return _offset;
+            }
+
+            const unsigned short* elements() const
+            {
+                return _elements;
+            }
+
+            void run(bool outputProgress)
+            {
+                half candidate[16];
+                int  candidateCount = 0;
+
+                for (size_t input=_startValue; input<_endValue; ++input) {
+
+                    if (outputProgress) {
+#ifdef __GNUC__
+                        if (input % 100 == 0) {
+                            fprintf(stderr, 
+                            " Building acceleration for DwaCompressor, %.2f %%      %c",
+                                          100.*(float)input/(float)numValues(), 13);
+                        }
+#else
+                        if (input % 1000 == 0) {
+                            fprintf(stderr, 
+                            " Building acceleration for DwaCompressor, %.2f %%\n",
+                                          100.*(float)input/(float)numValues());
+                        }
+#endif
+                    } 
+
+                    
+                    int  numSetBits = countSetBits(input);
+                    half inputHalf, closestHalf;
+
+                    inputHalf.setBits(input);
+
+                    _offset[input - _startValue] = _numElements;
+
+                    // Gather candidates
+                    candidateCount = 0;
+                    for (int targetNumSetBits=numSetBits-1; targetNumSetBits>=0;
+                                                           --targetNumSetBits) {
+                        bool valueFound = false;
+
+                        for (int i=0; i<65536; ++i) {
+                            if (countSetBits(i) != targetNumSetBits) continue;
+
+                            if (!valueFound) {
+                                closestHalf.setBits(i);
+                                valueFound = true;
+                            } else {
+                                half tmpHalf;
+
+                                tmpHalf.setBits(i);
+
+                                if (fabs((float)inputHalf - (float)tmpHalf) < 
+                                    fabs((float)inputHalf - (float)closestHalf)) {
+                                    closestHalf = tmpHalf;
+                                }
+                            }
+                        }
+
+                        if (valueFound == false) {
+                            fprintf(stderr, "bork bork bork!\n");
+                        }       
+
+                        candidate[candidateCount] = closestHalf;
+                        candidateCount++;
+                    }
+
+                    // Sort candidates by increasing number of bits set
+                    for (int i=0; i<candidateCount; ++i) {
+                        for (int j=i+1; j<candidateCount; ++j) {
+
+                            int   iCnt = countSetBits(candidate[i].bits());
+                            int   jCnt = countSetBits(candidate[j].bits());
+
+                            if (jCnt < iCnt) {
+                                half tmp     = candidate[i];
+                                candidate[i] = candidate[j];
+                                candidate[j] = tmp;
+                            }
+                        }
+                    }
+
+                    // Copy candidates to the data buffer;
+                    for (int i=0; i<candidateCount; ++i) {
+                        _elements[_numElements] = candidate[i].bits();
+                        _numElements++;
+                    }
+
+                    if (input == _endValue-1) {
+                        _lastCandidateCount = candidateCount;
+                    }
+                }
+            }
+            
+
+        private:
+            size_t          _lastCandidateCount;
+            size_t          _startValue;
+            size_t          _endValue;
+            size_t          _numElements;
+            size_t         *_offset;
+            unsigned short *_elements;
+
+            //
+            // Precomputing the bit count runs faster than using
+            // the builtin instruction, at least in one case..
+            //
+            // Precomputing 8-bits is no slower than 16-bits,
+            // and saves a fair bit of overhead..
+            //
+            int countSetBits(unsigned short src)
+            {
+                static const unsigned short numBitsSet[256] =
+                {
+                    0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
+                    1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+                    1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+                    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+                    1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+                    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+                    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+                    3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+                    1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+                    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+                    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+                    3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+                    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+                    3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+                    3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+                    4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
+                };
+
+                return numBitsSet[src & 0xff] + numBitsSet[src >> 8];
+            }
+
+    }; // class LutHeaderWorker
+
+} // namespace
+
+
+//
+// Generate a no-op LUT, to cut down in conditional branches
+//
+void
+generateNoop()
+{
+    printf("const unsigned short dwaCompressorNoOp[] = \n");
+    printf("{");
+    for (int i=0; i<65536; ++i) {
+
+        if (i % 8 == 0) {
+            printf("\n    ");
+        }
+
+        unsigned short dst;
+        char *tmp = (char *)(&dst);
+
+        unsigned short src = (unsigned short)i;
+        Xdr::write <CharPtrIO> (tmp,  src);
+
+        printf("0x%04x, ", dst);
+    }
+    printf("\n};\n");
+}
+
+//
+// Nonlinearly encode luminance. For values below 1.0, we want
+// to use a gamma 2.2 function to match what is fairly common
+// for storing output referred. However, > 1, gamma functions blow up,
+// and log functions are much better behaved. We could use a log 
+// function everywhere, but it tends to over-sample dark 
+// regions and undersample the brighter regions, when 
+// compared to the way real devices reproduce values.
+//
+// So, above 1, use a log function which is a smooth blend
+// into the gamma function. 
+//
+//  Nonlinear(linear) = 
+//
+//    linear^(1./2.2)             / linear <= 1.0
+//                               |
+//    ln(linear)/ln(e^2.2) + 1    \ otherwise
+//
+//
+// toNonlinear[] needs to take in XDR format half float values,
+// and output NATIVE format float. 
+//
+// toLinear[] does the opposite - takes in NATIVE half and 
+// outputs XDR half values.
+//
+
+void
+generateToLinear()
+{
+    unsigned short toLinear[65536];
+
+    toLinear[0] = 0;
+
+    for (int i=1; i<65536; ++i) {
+        half  h;
+        float sign    = 1;
+        float logBase = pow(2.7182818, 2.2);
+
+        // map  NaN and inf to 0
+        if ((i & 0x7c00) == 0x7c00) {
+            toLinear[i]    = 0;
+            continue;
+        }
+
+        //
+        // _toLinear - assume i is NATIVE, but our output needs
+        //             to get flipped to XDR
+        //
+        h.setBits(i);
+        sign = 1;
+        if ((float)h < 0) {
+            sign = -1;
+        } 
+
+        if ( fabs( (float)h) <= 1.0 ) {
+            h  = (half)(sign * pow((float)fabs((float)h), 2.2f));
+        } else {
+            h  = (half)(sign * pow(logBase, (float)(fabs((float)h) - 1.0)));
+        }
+
+        {
+            char *tmp = (char *)(&toLinear[i]);
+
+            Xdr::write <CharPtrIO> ( tmp,  h.bits());
+        }
+    }
+    
+    printf("const unsigned short dwaCompressorToLinear[] = \n");
+    printf("{");
+    for (int i=0; i<65536; ++i) {
+        if (i % 8 == 0) {
+            printf("\n    ");
+        }
+        printf("0x%04x, ", toLinear[i]);
+    }
+    printf("\n};\n");
+}
+
+
+void
+generateToNonlinear()
+{
+    unsigned short toNonlinear[65536];
+
+    toNonlinear[0] = 0;
+
+    for (int i=1; i<65536; ++i) {
+        unsigned short usNative, usXdr;
+        half  h;
+        float sign    = 1;
+        float logBase = pow(2.7182818, 2.2);
+
+        usXdr           = i;
+
+        {
+            const char *tmp = (char *)(&usXdr);
+
+            Xdr::read<CharPtrIO>(tmp, usNative);
+        }
+
+        // map  NaN and inf to 0
+        if ((usNative & 0x7c00) == 0x7c00) {
+            toNonlinear[i] = 0;
+            continue;
+        }
+
+        //
+        // toNonlinear - assume i is XDR
+        //
+        h.setBits(usNative);
+        sign = 1;
+        if ((float)h < 0) {
+            sign = -1;
+        } 
+
+        if ( fabs( (float)h ) <= 1.0) {
+            h = (half)(sign * pow(fabs((float)h), 1.f/2.2f));
+        } else {
+            h = (half)(sign * ( log(fabs((float)h)) / log(logBase) + 1.0) );
+        }
+        toNonlinear[i] = h.bits();
+    }
+
+    printf("const unsigned short dwaCompressorToNonlinear[] = \n");
+    printf("{");
+    for (int i=0; i<65536; ++i) {
+        if (i % 8 == 0) {
+            printf("\n    ");
+        }
+        printf("0x%04x, ", toNonlinear[i]);
+    }
+    printf("\n};\n");
+}
+
+//
+// Attempt to get available CPUs in a somewhat portable way. 
+//
+
+int
+cpuCount()
+{
+    if (!IlmThread::supportsThreads()) return 1;
+
+    int cpuCount = 1;
+
+#if defined (OPENEXR_IMF_HAVE_SYSCONF_NPROCESSORS_ONLN)
+
+    cpuCount = sysconf(_SC_NPROCESSORS_ONLN);
+
+#elif defined (_WIN32)
+
+    SYSTEM_INFO sysinfo;
+    GetSystemInfo( &sysinfo );
+    cpuCount = sysinfo.dwNumberOfProcessors;
+
+#endif
+
+    if (cpuCount < 1) cpuCount = 1;
+    return cpuCount;
+}
+
+//
+// Generate acceleration luts for the quantization.
+//
+// For each possible input value, we want to find the closest numbers
+// which have one fewer bits set than before. 
+//
+// This gives us num_bits(input)-1 values per input. If we alloc
+// space for everything, that's like a 2MB table. We can do better
+// by compressing all the values to be contigious and using offset
+// pointers.
+//
+// After we've found the candidates with fewer bits set, sort them
+// based on increasing numbers of bits set. This way, on quantize(),
+// we can scan through the list and halt once we find the first
+// candidate within the error range. For small values that can 
+// be quantized to 0, 0 is the first value tested and the search
+// can exit fairly quickly.
+//
+
+void
+generateLutHeader()
+{
+    std::vector<LutHeaderWorker*> workers;
+
+    size_t numWorkers     = cpuCount();
+    size_t workerInterval = 65536 / numWorkers;
+
+    for (size_t i=0; i<numWorkers; ++i) {
+        if (i != numWorkers-1) {
+            workers.push_back( new LutHeaderWorker( i   *workerInterval, 
+                                                   (i+1)*workerInterval) );
+        } else {
+            workers.push_back( new LutHeaderWorker(i*workerInterval, 65536) );
+        }
+    }
+
+    if (IlmThread::supportsThreads()) {
+        std::vector<LutHeaderWorker::Runner*> runners;
+        for (size_t i=0; i<workers.size(); ++i) {
+            runners.push_back( new LutHeaderWorker::Runner(*workers[i], (i==0)) );
+        }
+
+        for (size_t i=0; i<workers.size(); ++i) {
+            delete runners[i];
+        }
+    } else {
+        for (size_t i=0; i<workers.size(); ++i) {
+            workers[i]->run(i == 0);
+        }
+    }
+
+    printf("static unsigned int closestDataOffset[] = {\n");
+    int offsetIdx  = 0;
+    int offsetPrev = 0;
+    for (size_t i=0; i<workers.size(); ++i) {
+        for (size_t value=0; value<workers[i]->numValues(); ++value) {
+            if (offsetIdx % 8 == 0) {
+                printf("    ");
+            }
+            printf("%6lu, ", workers[i]->offset()[value] + offsetPrev);
+            if (offsetIdx % 8 == 7) {
+                printf("\n");
+            }
+            offsetIdx++;
+        }
+        offsetPrev += workers[i]->offset()[workers[i]->numValues()-1] + 
+                      workers[i]->lastCandidateCount();
+    }
+    printf("};\n\n\n");
+
+
+    printf("static unsigned short closestData[] = {\n");
+    int elementIdx = 0;
+    for (size_t i=0; i<workers.size(); ++i) {
+        for (size_t element=0; element<workers[i]->numElements(); ++element) {
+            if (elementIdx % 8 == 0) {
+                printf("    ");
+            }
+            printf("%5d, ", workers[i]->elements()[element]);
+            if (elementIdx % 8 == 7) {
+                printf("\n");
+            }
+            elementIdx++;
+        }    
+    }
+    printf("};\n\n\n");
+
+    for (size_t i=0; i<workers.size(); ++i) {
+        delete workers[i];
+    }
+}
+
+
+int
+main(int argc, char **argv)
+{
+    printf("#include <cstddef>\n");
+    printf("\n\n\n");
+
+    generateNoop();
+
+    printf("\n\n\n");
+
+    generateToLinear();
+
+    printf("\n\n\n");
+
+    generateToNonlinear();
+
+    printf("\n\n\n");
+
+    generateLutHeader();
+
+    return 0;
+}
diff --git a/Source/OpenEXR/IlmImf/dwaLookups.h b/Source/OpenEXR/IlmImf/dwaLookups.h
new file mode 100644
index 0000000..63c0d3d
--- /dev/null
+++ b/Source/OpenEXR/IlmImf/dwaLookups.h
@@ -0,0 +1,98334 @@
+#include <cstddef>
+
+
+
+const unsigned short dwaCompressorNoOp[] = 
+{
+    0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 
+    0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 
+    0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 
+    0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 
+    0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 
+    0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 
+    0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 
+    0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 
+    0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 
+    0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 
+    0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 
+    0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 
+    0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 
+    0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 
+    0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 
+    0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, 
+    0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 
+    0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, 
+    0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 
+    0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, 
+    0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 
+    0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, 
+    0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 
+    0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, 
+    0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 
+    0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, 
+    0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 
+    0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, 
+    0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 
+    0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, 
+    0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 
+    0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff, 
+    0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, 0x0107, 
+    0x0108, 0x0109, 0x010a, 0x010b, 0x010c, 0x010d, 0x010e, 0x010f, 
+    0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116, 0x0117, 
+    0x0118, 0x0119, 0x011a, 0x011b, 0x011c, 0x011d, 0x011e, 0x011f, 
+    0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126, 0x0127, 
+    0x0128, 0x0129, 0x012a, 0x012b, 0x012c, 0x012d, 0x012e, 0x012f, 
+    0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136, 0x0137, 
+    0x0138, 0x0139, 0x013a, 0x013b, 0x013c, 0x013d, 0x013e, 0x013f, 
+    0x0140, 0x0141, 0x0142, 0x0143, 0x0144, 0x0145, 0x0146, 0x0147, 
+    0x0148, 0x0149, 0x014a, 0x014b, 0x014c, 0x014d, 0x014e, 0x014f, 
+    0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155, 0x0156, 0x0157, 
+    0x0158, 0x0159, 0x015a, 0x015b, 0x015c, 0x015d, 0x015e, 0x015f, 
+    0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165, 0x0166, 0x0167, 
+    0x0168, 0x0169, 0x016a, 0x016b, 0x016c, 0x016d, 0x016e, 0x016f, 
+    0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175, 0x0176, 0x0177, 
+    0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d, 0x017e, 0x017f, 
+    0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185, 0x0186, 0x0187, 
+    0x0188, 0x0189, 0x018a, 0x018b, 0x018c, 0x018d, 0x018e, 0x018f, 
+    0x0190, 0x0191, 0x0192, 0x0193, 0x0194, 0x0195, 0x0196, 0x0197, 
+    0x0198, 0x0199, 0x019a, 0x019b, 0x019c, 0x019d, 0x019e, 0x019f, 
+    0x01a0, 0x01a1, 0x01a2, 0x01a3, 0x01a4, 0x01a5, 0x01a6, 0x01a7, 
+    0x01a8, 0x01a9, 0x01aa, 0x01ab, 0x01ac, 0x01ad, 0x01ae, 0x01af, 
+    0x01b0, 0x01b1, 0x01b2, 0x01b3, 0x01b4, 0x01b5, 0x01b6, 0x01b7, 
+    0x01b8, 0x01b9, 0x01ba, 0x01bb, 0x01bc, 0x01bd, 0x01be, 0x01bf, 
+    0x01c0, 0x01c1, 0x01c2, 0x01c3, 0x01c4, 0x01c5, 0x01c6, 0x01c7, 
+    0x01c8, 0x01c9, 0x01ca, 0x01cb, 0x01cc, 0x01cd, 0x01ce, 0x01cf, 
+    0x01d0, 0x01d1, 0x01d2, 0x01d3, 0x01d4, 0x01d5, 0x01d6, 0x01d7, 
+    0x01d8, 0x01d9, 0x01da, 0x01db, 0x01dc, 0x01dd, 0x01de, 0x01df, 
+    0x01e0, 0x01e1, 0x01e2, 0x01e3, 0x01e4, 0x01e5, 0x01e6, 0x01e7, 
+    0x01e8, 0x01e9, 0x01ea, 0x01eb, 0x01ec, 0x01ed, 0x01ee, 0x01ef, 
+    0x01f0, 0x01f1, 0x01f2, 0x01f3, 0x01f4, 0x01f5, 0x01f6, 0x01f7, 
+    0x01f8, 0x01f9, 0x01fa, 0x01fb, 0x01fc, 0x01fd, 0x01fe, 0x01ff, 
+    0x0200, 0x0201, 0x0202, 0x0203, 0x0204, 0x0205, 0x0206, 0x0207, 
+    0x0208, 0x0209, 0x020a, 0x020b, 0x020c, 0x020d, 0x020e, 0x020f, 
+    0x0210, 0x0211, 0x0212, 0x0213, 0x0214, 0x0215, 0x0216, 0x0217, 
+    0x0218, 0x0219, 0x021a, 0x021b, 0x021c, 0x021d, 0x021e, 0x021f, 
+    0x0220, 0x0221, 0x0222, 0x0223, 0x0224, 0x0225, 0x0226, 0x0227, 
+    0x0228, 0x0229, 0x022a, 0x022b, 0x022c, 0x022d, 0x022e, 0x022f, 
+    0x0230, 0x0231, 0x0232, 0x0233, 0x0234, 0x0235, 0x0236, 0x0237, 
+    0x0238, 0x0239, 0x023a, 0x023b, 0x023c, 0x023d, 0x023e, 0x023f, 
+    0x0240, 0x0241, 0x0242, 0x0243, 0x0244, 0x0245, 0x0246, 0x0247, 
+    0x0248, 0x0249, 0x024a, 0x024b, 0x024c, 0x024d, 0x024e, 0x024f, 
+    0x0250, 0x0251, 0x0252, 0x0253, 0x0254, 0x0255, 0x0256, 0x0257, 
+    0x0258, 0x0259, 0x025a, 0x025b, 0x025c, 0x025d, 0x025e, 0x025f, 
+    0x0260, 0x0261, 0x0262, 0x0263, 0x0264, 0x0265, 0x0266, 0x0267, 
+    0x0268, 0x0269, 0x026a, 0x026b, 0x026c, 0x026d, 0x026e, 0x026f, 
+    0x0270, 0x0271, 0x0272, 0x0273, 0x0274, 0x0275, 0x0276, 0x0277, 
+    0x0278, 0x0279, 0x027a, 0x027b, 0x027c, 0x027d, 0x027e, 0x027f, 
+    0x0280, 0x0281, 0x0282, 0x0283, 0x0284, 0x0285, 0x0286, 0x0287, 
+    0x0288, 0x0289, 0x028a, 0x028b, 0x028c, 0x028d, 0x028e, 0x028f, 
+    0x0290, 0x0291, 0x0292, 0x0293, 0x0294, 0x0295, 0x0296, 0x0297, 
+    0x0298, 0x0299, 0x029a, 0x029b, 0x029c, 0x029d, 0x029e, 0x029f, 
+    0x02a0, 0x02a1, 0x02a2, 0x02a3, 0x02a4, 0x02a5, 0x02a6, 0x02a7, 
+    0x02a8, 0x02a9, 0x02aa, 0x02ab, 0x02ac, 0x02ad, 0x02ae, 0x02af, 
+    0x02b0, 0x02b1, 0x02b2, 0x02b3, 0x02b4, 0x02b5, 0x02b6, 0x02b7, 
+    0x02b8, 0x02b9, 0x02ba, 0x02bb, 0x02bc, 0x02bd, 0x02be, 0x02bf, 
+    0x02c0, 0x02c1, 0x02c2, 0x02c3, 0x02c4, 0x02c5, 0x02c6, 0x02c7, 
+    0x02c8, 0x02c9, 0x02ca, 0x02cb, 0x02cc, 0x02cd, 0x02ce, 0x02cf, 
+    0x02d0, 0x02d1, 0x02d2, 0x02d3, 0x02d4, 0x02d5, 0x02d6, 0x02d7, 
+    0x02d8, 0x02d9, 0x02da, 0x02db, 0x02dc, 0x02dd, 0x02de, 0x02df, 
+    0x02e0, 0x02e1, 0x02e2, 0x02e3, 0x02e4, 0x02e5, 0x02e6, 0x02e7, 
+    0x02e8, 0x02e9, 0x02ea, 0x02eb, 0x02ec, 0x02ed, 0x02ee, 0x02ef, 
+    0x02f0, 0x02f1, 0x02f2, 0x02f3, 0x02f4, 0x02f5, 0x02f6, 0x02f7, 
+    0x02f8, 0x02f9, 0x02fa, 0x02fb, 0x02fc, 0x02fd, 0x02fe, 0x02ff, 
+    0x0300, 0x0301, 0x0302, 0x0303, 0x0304, 0x0305, 0x0306, 0x0307, 
+    0x0308, 0x0309, 0x030a, 0x030b, 0x030c, 0x030d, 0x030e, 0x030f, 
+    0x0310, 0x0311, 0x0312, 0x0313, 0x0314, 0x0315, 0x0316, 0x0317, 
+    0x0318, 0x0319, 0x031a, 0x031b, 0x031c, 0x031d, 0x031e, 0x031f, 
+    0x0320, 0x0321, 0x0322, 0x0323, 0x0324, 0x0325, 0x0326, 0x0327, 
+    0x0328, 0x0329, 0x032a, 0x032b, 0x032c, 0x032d, 0x032e, 0x032f, 
+    0x0330, 0x0331, 0x0332, 0x0333, 0x0334, 0x0335, 0x0336, 0x0337, 
+    0x0338, 0x0339, 0x033a, 0x033b, 0x033c, 0x033d, 0x033e, 0x033f, 
+    0x0340, 0x0341, 0x0342, 0x0343, 0x0344, 0x0345, 0x0346, 0x0347, 
+    0x0348, 0x0349, 0x034a, 0x034b, 0x034c, 0x034d, 0x034e, 0x034f, 
+    0x0350, 0x0351, 0x0352, 0x0353, 0x0354, 0x0355, 0x0356, 0x0357, 
+    0x0358, 0x0359, 0x035a, 0x035b, 0x035c, 0x035d, 0x035e, 0x035f, 
+    0x0360, 0x0361, 0x0362, 0x0363, 0x0364, 0x0365, 0x0366, 0x0367, 
+    0x0368, 0x0369, 0x036a, 0x036b, 0x036c, 0x036d, 0x036e, 0x036f, 
+    0x0370, 0x0371, 0x0372, 0x0373, 0x0374, 0x0375, 0x0376, 0x0377, 
+    0x0378, 0x0379, 0x037a, 0x037b, 0x037c, 0x037d, 0x037e, 0x037f, 
+    0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x0386, 0x0387, 
+    0x0388, 0x0389, 0x038a, 0x038b, 0x038c, 0x038d, 0x038e, 0x038f, 
+    0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 
+    0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, 
+    0x03a0, 0x03a1, 0x03a2, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, 
+    0x03a8, 0x03a9, 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03ae, 0x03af, 
+    0x03b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, 
+    0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, 
+    0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 
+    0x03c8, 0x03c9, 0x03ca, 0x03cb, 0x03cc, 0x03cd, 0x03ce, 0x03cf, 
+    0x03d0, 0x03d1, 0x03d2, 0x03d3, 0x03d4, 0x03d5, 0x03d6, 0x03d7, 
+    0x03d8, 0x03d9, 0x03da, 0x03db, 0x03dc, 0x03dd, 0x03de, 0x03df, 
+    0x03e0, 0x03e1, 0x03e2, 0x03e3, 0x03e4, 0x03e5, 0x03e6, 0x03e7, 
+    0x03e8, 0x03e9, 0x03ea, 0x03eb, 0x03ec, 0x03ed, 0x03ee, 0x03ef, 
+    0x03f0, 0x03f1, 0x03f2, 0x03f3, 0x03f4, 0x03f5, 0x03f6, 0x03f7, 
+    0x03f8, 0x03f9, 0x03fa, 0x03fb, 0x03fc, 0x03fd, 0x03fe, 0x03ff, 
+    0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, 
+    0x0408, 0x0409, 0x040a, 0x040b, 0x040c, 0x040d, 0x040e, 0x040f, 
+    0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 
+    0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, 
+    0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 
+    0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, 
+    0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 
+    0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, 
+    0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 
+    0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f, 
+    0x0450, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, 
+    0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x045d, 0x045e, 0x045f, 
+    0x0460, 0x0461, 0x0462, 0x0463, 0x0464, 0x0465, 0x0466, 0x0467, 
+    0x0468, 0x0469, 0x046a, 0x046b, 0x046c, 0x046d, 0x046e, 0x046f, 
+    0x0470, 0x0471, 0x0472, 0x0473, 0x0474, 0x0475, 0x0476, 0x0477, 
+    0x0478, 0x0479, 0x047a, 0x047b, 0x047c, 0x047d, 0x047e, 0x047f, 
+    0x0480, 0x0481, 0x0482, 0x0483, 0x0484, 0x0485, 0x0486, 0x0487, 
+    0x0488, 0x0489, 0x048a, 0x048b, 0x048c, 0x048d, 0x048e, 0x048f, 
+    0x0490, 0x0491, 0x0492, 0x0493, 0x0494, 0x0495, 0x0496, 0x0497, 
+    0x0498, 0x0499, 0x049a, 0x049b, 0x049c, 0x049d, 0x049e, 0x049f, 
+    0x04a0, 0x04a1, 0x04a2, 0x04a3, 0x04a4, 0x04a5, 0x04a6, 0x04a7, 
+    0x04a8, 0x04a9, 0x04aa, 0x04ab, 0x04ac, 0x04ad, 0x04ae, 0x04af, 
+    0x04b0, 0x04b1, 0x04b2, 0x04b3, 0x04b4, 0x04b5, 0x04b6, 0x04b7, 
+    0x04b8, 0x04b9, 0x04ba, 0x04bb, 0x04bc, 0x04bd, 0x04be, 0x04bf, 
+    0x04c0, 0x04c1, 0x04c2, 0x04c3, 0x04c4, 0x04c5, 0x04c6, 0x04c7, 
+    0x04c8, 0x04c9, 0x04ca, 0x04cb, 0x04cc, 0x04cd, 0x04ce, 0x04cf, 
+    0x04d0, 0x04d1, 0x04d2, 0x04d3, 0x04d4, 0x04d5, 0x04d6, 0x04d7, 
+    0x04d8, 0x04d9, 0x04da, 0x04db, 0x04dc, 0x04dd, 0x04de, 0x04df, 
+    0x04e0, 0x04e1, 0x04e2, 0x04e3, 0x04e4, 0x04e5, 0x04e6, 0x04e7, 
+    0x04e8, 0x04e9, 0x04ea, 0x04eb, 0x04ec, 0x04ed, 0x04ee, 0x04ef, 
+    0x04f0, 0x04f1, 0x04f2, 0x04f3, 0x04f4, 0x04f5, 0x04f6, 0x04f7, 
+    0x04f8, 0x04f9, 0x04fa, 0x04fb, 0x04fc, 0x04fd, 0x04fe, 0x04ff, 
+    0x0500, 0x0501, 0x0502, 0x0503, 0x0504, 0x0505, 0x0506, 0x0507, 
+    0x0508, 0x0509, 0x050a, 0x050b, 0x050c, 0x050d, 0x050e, 0x050f, 
+    0x0510, 0x0511, 0x0512, 0x0513, 0x0514, 0x0515, 0x0516, 0x0517, 
+    0x0518, 0x0519, 0x051a, 0x051b, 0x051c, 0x051d, 0x051e, 0x051f, 
+    0x0520, 0x0521, 0x0522, 0x0523, 0x0524, 0x0525, 0x0526, 0x0527, 
+    0x0528, 0x0529, 0x052a, 0x052b, 0x052c, 0x052d, 0x052e, 0x052f, 
+    0x0530, 0x0531, 0x0532, 0x0533, 0x0534, 0x0535, 0x0536, 0x0537, 
+    0x0538, 0x0539, 0x053a, 0x053b, 0x053c, 0x053d, 0x053e, 0x053f, 
+    0x0540, 0x0541, 0x0542, 0x0543, 0x0544, 0x0545, 0x0546, 0x0547, 
+    0x0548, 0x0549, 0x054a, 0x054b, 0x054c, 0x054d, 0x054e, 0x054f, 
+    0x0550, 0x0551, 0x0552, 0x0553, 0x0554, 0x0555, 0x0556, 0x0557, 
+    0x0558, 0x0559, 0x055a, 0x055b, 0x055c, 0x055d, 0x055e, 0x055f, 
+    0x0560, 0x0561, 0x0562, 0x0563, 0x0564, 0x0565, 0x0566, 0x0567, 
+    0x0568, 0x0569, 0x056a, 0x056b, 0x056c, 0x056d, 0x056e, 0x056f, 
+    0x0570, 0x0571, 0x0572, 0x0573, 0x0574, 0x0575, 0x0576, 0x0577, 
+    0x0578, 0x0579, 0x057a, 0x057b, 0x057c, 0x057d, 0x057e, 0x057f, 
+    0x0580, 0x0581, 0x0582, 0x0583, 0x0584, 0x0585, 0x0586, 0x0587, 
+    0x0588, 0x0589, 0x058a, 0x058b, 0x058c, 0x058d, 0x058e, 0x058f, 
+    0x0590, 0x0591, 0x0592, 0x0593, 0x0594, 0x0595, 0x0596, 0x0597, 
+    0x0598, 0x0599, 0x059a, 0x059b, 0x059c, 0x059d, 0x059e, 0x059f, 
+    0x05a0, 0x05a1, 0x05a2, 0x05a3, 0x05a4, 0x05a5, 0x05a6, 0x05a7, 
+    0x05a8, 0x05a9, 0x05aa, 0x05ab, 0x05ac, 0x05ad, 0x05ae, 0x05af, 
+    0x05b0, 0x05b1, 0x05b2, 0x05b3, 0x05b4, 0x05b5, 0x05b6, 0x05b7, 
+    0x05b8, 0x05b9, 0x05ba, 0x05bb, 0x05bc, 0x05bd, 0x05be, 0x05bf, 
+    0x05c0, 0x05c1, 0x05c2, 0x05c3, 0x05c4, 0x05c5, 0x05c6, 0x05c7, 
+    0x05c8, 0x05c9, 0x05ca, 0x05cb, 0x05cc, 0x05cd, 0x05ce, 0x05cf, 
+    0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, 
+    0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df, 
+    0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, 
+    0x05e8, 0x05e9, 0x05ea, 0x05eb, 0x05ec, 0x05ed, 0x05ee, 0x05ef, 
+    0x05f0, 0x05f1, 0x05f2, 0x05f3, 0x05f4, 0x05f5, 0x05f6, 0x05f7, 
+    0x05f8, 0x05f9, 0x05fa, 0x05fb, 0x05fc, 0x05fd, 0x05fe, 0x05ff, 
+    0x0600, 0x0601, 0x0602, 0x0603, 0x0604, 0x0605, 0x0606, 0x0607, 
+    0x0608, 0x0609, 0x060a, 0x060b, 0x060c, 0x060d, 0x060e, 0x060f, 
+    0x0610, 0x0611, 0x0612, 0x0613, 0x0614, 0x0615, 0x0616, 0x0617, 
+    0x0618, 0x0619, 0x061a, 0x061b, 0x061c, 0x061d, 0x061e, 0x061f, 
+    0x0620, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, 
+    0x0628, 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f, 
+    0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, 
+    0x0638, 0x0639, 0x063a, 0x063b, 0x063c, 0x063d, 0x063e, 0x063f, 
+    0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 
+    0x0648, 0x0649, 0x064a, 0x064b, 0x064c, 0x064d, 0x064e, 0x064f, 
+    0x0650, 0x0651, 0x0652, 0x0653, 0x0654, 0x0655, 0x0656, 0x0657, 
+    0x0658, 0x0659, 0x065a, 0x065b, 0x065c, 0x065d, 0x065e, 0x065f, 
+    0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, 
+    0x0668, 0x0669, 0x066a, 0x066b, 0x066c, 0x066d, 0x066e, 0x066f, 
+    0x0670, 0x0671, 0x0672, 0x0673, 0x0674, 0x0675, 0x0676, 0x0677, 
+    0x0678, 0x0679, 0x067a, 0x067b, 0x067c, 0x067d, 0x067e, 0x067f, 
+    0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0686, 0x0687, 
+    0x0688, 0x0689, 0x068a, 0x068b, 0x068c, 0x068d, 0x068e, 0x068f, 
+    0x0690, 0x0691, 0x0692, 0x0693, 0x0694, 0x0695, 0x0696, 0x0697, 
+    0x0698, 0x0699, 0x069a, 0x069b, 0x069c, 0x069d, 0x069e, 0x069f, 
+    0x06a0, 0x06a1, 0x06a2, 0x06a3, 0x06a4, 0x06a5, 0x06a6, 0x06a7, 
+    0x06a8, 0x06a9, 0x06aa, 0x06ab, 0x06ac, 0x06ad, 0x06ae, 0x06af, 
+    0x06b0, 0x06b1, 0x06b2, 0x06b3, 0x06b4, 0x06b5, 0x06b6, 0x06b7, 
+    0x06b8, 0x06b9, 0x06ba, 0x06bb, 0x06bc, 0x06bd, 0x06be, 0x06bf, 
+    0x06c0, 0x06c1, 0x06c2, 0x06c3, 0x06c4, 0x06c5, 0x06c6, 0x06c7, 
+    0x06c8, 0x06c9, 0x06ca, 0x06cb, 0x06cc, 0x06cd, 0x06ce, 0x06cf, 
+    0x06d0, 0x06d1, 0x06d2, 0x06d3, 0x06d4, 0x06d5, 0x06d6, 0x06d7, 
+    0x06d8, 0x06d9, 0x06da, 0x06db, 0x06dc, 0x06dd, 0x06de, 0x06df, 
+    0x06e0, 0x06e1, 0x06e2, 0x06e3, 0x06e4, 0x06e5, 0x06e6, 0x06e7, 
+    0x06e8, 0x06e9, 0x06ea, 0x06eb, 0x06ec, 0x06ed, 0x06ee, 0x06ef, 
+    0x06f0, 0x06f1, 0x06f2, 0x06f3, 0x06f4, 0x06f5, 0x06f6, 0x06f7, 
+    0x06f8, 0x06f9, 0x06fa, 0x06fb, 0x06fc, 0x06fd, 0x06fe, 0x06ff, 
+    0x0700, 0x0701, 0x0702, 0x0703, 0x0704, 0x0705, 0x0706, 0x0707, 
+    0x0708, 0x0709, 0x070a, 0x070b, 0x070c, 0x070d, 0x070e, 0x070f, 
+    0x0710, 0x0711, 0x0712, 0x0713, 0x0714, 0x0715, 0x0716, 0x0717, 
+    0x0718, 0x0719, 0x071a, 0x071b, 0x071c, 0x071d, 0x071e, 0x071f, 
+    0x0720, 0x0721, 0x0722, 0x0723, 0x0724, 0x0725, 0x0726, 0x0727, 
+    0x0728, 0x0729, 0x072a, 0x072b, 0x072c, 0x072d, 0x072e, 0x072f, 
+    0x0730, 0x0731, 0x0732, 0x0733, 0x0734, 0x0735, 0x0736, 0x0737, 
+    0x0738, 0x0739, 0x073a, 0x073b, 0x073c, 0x073d, 0x073e, 0x073f, 
+    0x0740, 0x0741, 0x0742, 0x0743, 0x0744, 0x0745, 0x0746, 0x0747, 
+    0x0748, 0x0749, 0x074a, 0x074b, 0x074c, 0x074d, 0x074e, 0x074f, 
+    0x0750, 0x0751, 0x0752, 0x0753, 0x0754, 0x0755, 0x0756, 0x0757, 
+    0x0758, 0x0759, 0x075a, 0x075b, 0x075c, 0x075d, 0x075e, 0x075f, 
+    0x0760, 0x0761, 0x0762, 0x0763, 0x0764, 0x0765, 0x0766, 0x0767, 
+    0x0768, 0x0769, 0x076a, 0x076b, 0x076c, 0x076d, 0x076e, 0x076f, 
+    0x0770, 0x0771, 0x0772, 0x0773, 0x0774, 0x0775, 0x0776, 0x0777, 
+    0x0778, 0x0779, 0x077a, 0x077b, 0x077c, 0x077d, 0x077e, 0x077f, 
+    0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0786, 0x0787, 
+    0x0788, 0x0789, 0x078a, 0x078b, 0x078c, 0x078d, 0x078e, 0x078f, 
+    0x0790, 0x0791, 0x0792, 0x0793, 0x0794, 0x0795, 0x0796, 0x0797, 
+    0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d, 0x079e, 0x079f, 
+    0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a6, 0x07a7, 
+    0x07a8, 0x07a9, 0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07ae, 0x07af, 
+    0x07b0, 0x07b1, 0x07b2, 0x07b3, 0x07b4, 0x07b5, 0x07b6, 0x07b7, 
+    0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bc, 0x07bd, 0x07be, 0x07bf, 
+    0x07c0, 0x07c1, 0x07c2, 0x07c3, 0x07c4, 0x07c5, 0x07c6, 0x07c7, 
+    0x07c8, 0x07c9, 0x07ca, 0x07cb, 0x07cc, 0x07cd, 0x07ce, 0x07cf, 
+    0x07d0, 0x07d1, 0x07d2, 0x07d3, 0x07d4, 0x07d5, 0x07d6, 0x07d7, 
+    0x07d8, 0x07d9, 0x07da, 0x07db, 0x07dc, 0x07dd, 0x07de, 0x07df, 
+    0x07e0, 0x07e1, 0x07e2, 0x07e3, 0x07e4, 0x07e5, 0x07e6, 0x07e7, 
+    0x07e8, 0x07e9, 0x07ea, 0x07eb, 0x07ec, 0x07ed, 0x07ee, 0x07ef, 
+    0x07f0, 0x07f1, 0x07f2, 0x07f3, 0x07f4, 0x07f5, 0x07f6, 0x07f7, 
+    0x07f8, 0x07f9, 0x07fa, 0x07fb, 0x07fc, 0x07fd, 0x07fe, 0x07ff, 
+    0x0800, 0x0801, 0x0802, 0x0803, 0x0804, 0x0805, 0x0806, 0x0807, 
+    0x0808, 0x0809, 0x080a, 0x080b, 0x080c, 0x080d, 0x080e, 0x080f, 
+    0x0810, 0x0811, 0x0812, 0x0813, 0x0814, 0x0815, 0x0816, 0x0817, 
+    0x0818, 0x0819, 0x081a, 0x081b, 0x081c, 0x081d, 0x081e, 0x081f, 
+    0x0820, 0x0821, 0x0822, 0x0823, 0x0824, 0x0825, 0x0826, 0x0827, 
+    0x0828, 0x0829, 0x082a, 0x082b, 0x082c, 0x082d, 0x082e, 0x082f, 
+    0x0830, 0x0831, 0x0832, 0x0833, 0x0834, 0x0835, 0x0836, 0x0837, 
+    0x0838, 0x0839, 0x083a, 0x083b, 0x083c, 0x083d, 0x083e, 0x083f, 
+    0x0840, 0x0841, 0x0842, 0x0843, 0x0844, 0x0845, 0x0846, 0x0847, 
+    0x0848, 0x0849, 0x084a, 0x084b, 0x084c, 0x084d, 0x084e, 0x084f, 
+    0x0850, 0x0851, 0x0852, 0x0853, 0x0854, 0x0855, 0x0856, 0x0857, 
+    0x0858, 0x0859, 0x085a, 0x085b, 0x085c, 0x085d, 0x085e, 0x085f, 
+    0x0860, 0x0861, 0x0862, 0x0863, 0x0864, 0x0865, 0x0866, 0x0867, 
+    0x0868, 0x0869, 0x086a, 0x086b, 0x086c, 0x086d, 0x086e, 0x086f, 
+    0x0870, 0x0871, 0x0872, 0x0873, 0x0874, 0x0875, 0x0876, 0x0877, 
+    0x0878, 0x0879, 0x087a, 0x087b, 0x087c, 0x087d, 0x087e, 0x087f, 
+    0x0880, 0x0881, 0x0882, 0x0883, 0x0884, 0x0885, 0x0886, 0x0887, 
+    0x0888, 0x0889, 0x088a, 0x088b, 0x088c, 0x088d, 0x088e, 0x088f, 
+    0x0890, 0x0891, 0x0892, 0x0893, 0x0894, 0x0895, 0x0896, 0x0897, 
+    0x0898, 0x0899, 0x089a, 0x089b, 0x089c, 0x089d, 0x089e, 0x089f, 
+    0x08a0, 0x08a1, 0x08a2, 0x08a3, 0x08a4, 0x08a5, 0x08a6, 0x08a7, 
+    0x08a8, 0x08a9, 0x08aa, 0x08ab, 0x08ac, 0x08ad, 0x08ae, 0x08af, 
+    0x08b0, 0x08b1, 0x08b2, 0x08b3, 0x08b4, 0x08b5, 0x08b6, 0x08b7, 
+    0x08b8, 0x08b9, 0x08ba, 0x08bb, 0x08bc, 0x08bd, 0x08be, 0x08bf, 
+    0x08c0, 0x08c1, 0x08c2, 0x08c3, 0x08c4, 0x08c5, 0x08c6, 0x08c7, 
+    0x08c8, 0x08c9, 0x08ca, 0x08cb, 0x08cc, 0x08cd, 0x08ce, 0x08cf, 
+    0x08d0, 0x08d1, 0x08d2, 0x08d3, 0x08d4, 0x08d5, 0x08d6, 0x08d7, 
+    0x08d8, 0x08d9, 0x08da, 0x08db, 0x08dc, 0x08dd, 0x08de, 0x08df, 
+    0x08e0, 0x08e1, 0x08e2, 0x08e3, 0x08e4, 0x08e5, 0x08e6, 0x08e7, 
+    0x08e8, 0x08e9, 0x08ea, 0x08eb, 0x08ec, 0x08ed, 0x08ee, 0x08ef, 
+    0x08f0, 0x08f1, 0x08f2, 0x08f3, 0x08f4, 0x08f5, 0x08f6, 0x08f7, 
+    0x08f8, 0x08f9, 0x08fa, 0x08fb, 0x08fc, 0x08fd, 0x08fe, 0x08ff, 
+    0x0900, 0x0901, 0x0902, 0x0903, 0x0904, 0x0905, 0x0906, 0x0907, 
+    0x0908, 0x0909, 0x090a, 0x090b, 0x090c, 0x090d, 0x090e, 0x090f, 
+    0x0910, 0x0911, 0x0912, 0x0913, 0x0914, 0x0915, 0x0916, 0x0917, 
+    0x0918, 0x0919, 0x091a, 0x091b, 0x091c, 0x091d, 0x091e, 0x091f, 
+    0x0920, 0x0921, 0x0922, 0x0923, 0x0924, 0x0925, 0x0926, 0x0927, 
+    0x0928, 0x0929, 0x092a, 0x092b, 0x092c, 0x092d, 0x092e, 0x092f, 
+    0x0930, 0x0931, 0x0932, 0x0933, 0x0934, 0x0935, 0x0936, 0x0937, 
+    0x0938, 0x0939, 0x093a, 0x093b, 0x093c, 0x093d, 0x093e, 0x093f, 
+    0x0940, 0x0941, 0x0942, 0x0943, 0x0944, 0x0945, 0x0946, 0x0947, 
+    0x0948, 0x0949, 0x094a, 0x094b, 0x094c, 0x094d, 0x094e, 0x094f, 
+    0x0950, 0x0951, 0x0952, 0x0953, 0x0954, 0x0955, 0x0956, 0x0957, 
+    0x0958, 0x0959, 0x095a, 0x095b, 0x095c, 0x095d, 0x095e, 0x095f, 
+    0x0960, 0x0961, 0x0962, 0x0963, 0x0964, 0x0965, 0x0966, 0x0967, 
+    0x0968, 0x0969, 0x096a, 0x096b, 0x096c, 0x096d, 0x096e, 0x096f, 
+    0x0970, 0x0971, 0x0972, 0x0973, 0x0974, 0x0975, 0x0976, 0x0977, 
+    0x0978, 0x0979, 0x097a, 0x097b, 0x097c, 0x097d, 0x097e, 0x097f, 
+    0x0980, 0x0981, 0x0982, 0x0983, 0x0984, 0x0985, 0x0986, 0x0987, 
+    0x0988, 0x0989, 0x098a, 0x098b, 0x098c, 0x098d, 0x098e, 0x098f, 
+    0x0990, 0x0991, 0x0992, 0x0993, 0x0994, 0x0995, 0x0996, 0x0997, 
+    0x0998, 0x0999, 0x099a, 0x099b, 0x099c, 0x099d, 0x099e, 0x099f, 
+    0x09a0, 0x09a1, 0x09a2, 0x09a3, 0x09a4, 0x09a5, 0x09a6, 0x09a7, 
+    0x09a8, 0x09a9, 0x09aa, 0x09ab, 0x09ac, 0x09ad, 0x09ae, 0x09af, 
+    0x09b0, 0x09b1, 0x09b2, 0x09b3, 0x09b4, 0x09b5, 0x09b6, 0x09b7, 
+    0x09b8, 0x09b9, 0x09ba, 0x09bb, 0x09bc, 0x09bd, 0x09be, 0x09bf, 
+    0x09c0, 0x09c1, 0x09c2, 0x09c3, 0x09c4, 0x09c5, 0x09c6, 0x09c7, 
+    0x09c8, 0x09c9, 0x09ca, 0x09cb, 0x09cc, 0x09cd, 0x09ce, 0x09cf, 
+    0x09d0, 0x09d1, 0x09d2, 0x09d3, 0x09d4, 0x09d5, 0x09d6, 0x09d7, 
+    0x09d8, 0x09d9, 0x09da, 0x09db, 0x09dc, 0x09dd, 0x09de, 0x09df, 
+    0x09e0, 0x09e1, 0x09e2, 0x09e3, 0x09e4, 0x09e5, 0x09e6, 0x09e7, 
+    0x09e8, 0x09e9, 0x09ea, 0x09eb, 0x09ec, 0x09ed, 0x09ee, 0x09ef, 
+    0x09f0, 0x09f1, 0x09f2, 0x09f3, 0x09f4, 0x09f5, 0x09f6, 0x09f7, 
+    0x09f8, 0x09f9, 0x09fa, 0x09fb, 0x09fc, 0x09fd, 0x09fe, 0x09ff, 
+    0x0a00, 0x0a01, 0x0a02, 0x0a03, 0x0a04, 0x0a05, 0x0a06, 0x0a07, 
+    0x0a08, 0x0a09, 0x0a0a, 0x0a0b, 0x0a0c, 0x0a0d, 0x0a0e, 0x0a0f, 
+    0x0a10, 0x0a11, 0x0a12, 0x0a13, 0x0a14, 0x0a15, 0x0a16, 0x0a17, 
+    0x0a18, 0x0a19, 0x0a1a, 0x0a1b, 0x0a1c, 0x0a1d, 0x0a1e, 0x0a1f, 
+    0x0a20, 0x0a21, 0x0a22, 0x0a23, 0x0a24, 0x0a25, 0x0a26, 0x0a27, 
+    0x0a28, 0x0a29, 0x0a2a, 0x0a2b, 0x0a2c, 0x0a2d, 0x0a2e, 0x0a2f, 
+    0x0a30, 0x0a31, 0x0a32, 0x0a33, 0x0a34, 0x0a35, 0x0a36, 0x0a37, 
+    0x0a38, 0x0a39, 0x0a3a, 0x0a3b, 0x0a3c, 0x0a3d, 0x0a3e, 0x0a3f, 
+    0x0a40, 0x0a41, 0x0a42, 0x0a43, 0x0a44, 0x0a45, 0x0a46, 0x0a47, 
+    0x0a48, 0x0a49, 0x0a4a, 0x0a4b, 0x0a4c, 0x0a4d, 0x0a4e, 0x0a4f, 
+    0x0a50, 0x0a51, 0x0a52, 0x0a53, 0x0a54, 0x0a55, 0x0a56, 0x0a57, 
+    0x0a58, 0x0a59, 0x0a5a, 0x0a5b, 0x0a5c, 0x0a5d, 0x0a5e, 0x0a5f, 
+    0x0a60, 0x0a61, 0x0a62, 0x0a63, 0x0a64, 0x0a65, 0x0a66, 0x0a67, 
+    0x0a68, 0x0a69, 0x0a6a, 0x0a6b, 0x0a6c, 0x0a6d, 0x0a6e, 0x0a6f, 
+    0x0a70, 0x0a71, 0x0a72, 0x0a73, 0x0a74, 0x0a75, 0x0a76, 0x0a77, 
+    0x0a78, 0x0a79, 0x0a7a, 0x0a7b, 0x0a7c, 0x0a7d, 0x0a7e, 0x0a7f, 
+    0x0a80, 0x0a81, 0x0a82, 0x0a83, 0x0a84, 0x0a85, 0x0a86, 0x0a87, 
+    0x0a88, 0x0a89, 0x0a8a, 0x0a8b, 0x0a8c, 0x0a8d, 0x0a8e, 0x0a8f, 
+    0x0a90, 0x0a91, 0x0a92, 0x0a93, 0x0a94, 0x0a95, 0x0a96, 0x0a97, 
+    0x0a98, 0x0a99, 0x0a9a, 0x0a9b, 0x0a9c, 0x0a9d, 0x0a9e, 0x0a9f, 
+    0x0aa0, 0x0aa1, 0x0aa2, 0x0aa3, 0x0aa4, 0x0aa5, 0x0aa6, 0x0aa7, 
+    0x0aa8, 0x0aa9, 0x0aaa, 0x0aab, 0x0aac, 0x0aad, 0x0aae, 0x0aaf, 
+    0x0ab0, 0x0ab1, 0x0ab2, 0x0ab3, 0x0ab4, 0x0ab5, 0x0ab6, 0x0ab7, 
+    0x0ab8, 0x0ab9, 0x0aba, 0x0abb, 0x0abc, 0x0abd, 0x0abe, 0x0abf, 
+    0x0ac0, 0x0ac1, 0x0ac2, 0x0ac3, 0x0ac4, 0x0ac5, 0x0ac6, 0x0ac7, 
+    0x0ac8, 0x0ac9, 0x0aca, 0x0acb, 0x0acc, 0x0acd, 0x0ace, 0x0acf, 
+    0x0ad0, 0x0ad1, 0x0ad2, 0x0ad3, 0x0ad4, 0x0ad5, 0x0ad6, 0x0ad7, 
+    0x0ad8, 0x0ad9, 0x0ada, 0x0adb, 0x0adc, 0x0add, 0x0ade, 0x0adf, 
+    0x0ae0, 0x0ae1, 0x0ae2, 0x0ae3, 0x0ae4, 0x0ae5, 0x0ae6, 0x0ae7, 
+    0x0ae8, 0x0ae9, 0x0aea, 0x0aeb, 0x0aec, 0x0aed, 0x0aee, 0x0aef, 
+    0x0af0, 0x0af1, 0x0af2, 0x0af3, 0x0af4, 0x0af5, 0x0af6, 0x0af7, 
+    0x0af8, 0x0af9, 0x0afa, 0x0afb, 0x0afc, 0x0afd, 0x0afe, 0x0aff, 
+    0x0b00, 0x0b01, 0x0b02, 0x0b03, 0x0b04, 0x0b05, 0x0b06, 0x0b07, 
+    0x0b08, 0x0b09, 0x0b0a, 0x0b0b, 0x0b0c, 0x0b0d, 0x0b0e, 0x0b0f, 
+    0x0b10, 0x0b11, 0x0b12, 0x0b13, 0x0b14, 0x0b15, 0x0b16, 0x0b17, 
+    0x0b18, 0x0b19, 0x0b1a, 0x0b1b, 0x0b1c, 0x0b1d, 0x0b1e, 0x0b1f, 
+    0x0b20, 0x0b21, 0x0b22, 0x0b23, 0x0b24, 0x0b25, 0x0b26, 0x0b27, 
+    0x0b28, 0x0b29, 0x0b2a, 0x0b2b, 0x0b2c, 0x0b2d, 0x0b2e, 0x0b2f, 
+    0x0b30, 0x0b31, 0x0b32, 0x0b33, 0x0b34, 0x0b35, 0x0b36, 0x0b37, 
+    0x0b38, 0x0b39, 0x0b3a, 0x0b3b, 0x0b3c, 0x0b3d, 0x0b3e, 0x0b3f, 
+    0x0b40, 0x0b41, 0x0b42, 0x0b43, 0x0b44, 0x0b45, 0x0b46, 0x0b47, 
+    0x0b48, 0x0b49, 0x0b4a, 0x0b4b, 0x0b4c, 0x0b4d, 0x0b4e, 0x0b4f, 
+    0x0b50, 0x0b51, 0x0b52, 0x0b53, 0x0b54, 0x0b55, 0x0b56, 0x0b57, 
+    0x0b58, 0x0b59, 0x0b5a, 0x0b5b, 0x0b5c, 0x0b5d, 0x0b5e, 0x0b5f, 
+    0x0b60, 0x0b61, 0x0b62, 0x0b63, 0x0b64, 0x0b65, 0x0b66, 0x0b67, 
+    0x0b68, 0x0b69, 0x0b6a, 0x0b6b, 0x0b6c, 0x0b6d, 0x0b6e, 0x0b6f, 
+    0x0b70, 0x0b71, 0x0b72, 0x0b73, 0x0b74, 0x0b75, 0x0b76, 0x0b77, 
+    0x0b78, 0x0b79, 0x0b7a, 0x0b7b, 0x0b7c, 0x0b7d, 0x0b7e, 0x0b7f, 
+    0x0b80, 0x0b81, 0x0b82, 0x0b83, 0x0b84, 0x0b85, 0x0b86, 0x0b87, 
+    0x0b88, 0x0b89, 0x0b8a, 0x0b8b, 0x0b8c, 0x0b8d, 0x0b8e, 0x0b8f, 
+    0x0b90, 0x0b91, 0x0b92, 0x0b93, 0x0b94, 0x0b95, 0x0b96, 0x0b97, 
+    0x0b98, 0x0b99, 0x0b9a, 0x0b9b, 0x0b9c, 0x0b9d, 0x0b9e, 0x0b9f, 
+    0x0ba0, 0x0ba1, 0x0ba2, 0x0ba3, 0x0ba4, 0x0ba5, 0x0ba6, 0x0ba7, 
+    0x0ba8, 0x0ba9, 0x0baa, 0x0bab, 0x0bac, 0x0bad, 0x0bae, 0x0baf, 
+    0x0bb0, 0x0bb1, 0x0bb2, 0x0bb3, 0x0bb4, 0x0bb5, 0x0bb6, 0x0bb7, 
+    0x0bb8, 0x0bb9, 0x0bba, 0x0bbb, 0x0bbc, 0x0bbd, 0x0bbe, 0x0bbf, 
+    0x0bc0, 0x0bc1, 0x0bc2, 0x0bc3, 0x0bc4, 0x0bc5, 0x0bc6, 0x0bc7, 
+    0x0bc8, 0x0bc9, 0x0bca, 0x0bcb, 0x0bcc, 0x0bcd, 0x0bce, 0x0bcf, 
+    0x0bd0, 0x0bd1, 0x0bd2, 0x0bd3, 0x0bd4, 0x0bd5, 0x0bd6, 0x0bd7, 
+    0x0bd8, 0x0bd9, 0x0bda, 0x0bdb, 0x0bdc, 0x0bdd, 0x0bde, 0x0bdf, 
+    0x0be0, 0x0be1, 0x0be2, 0x0be3, 0x0be4, 0x0be5, 0x0be6, 0x0be7, 
+    0x0be8, 0x0be9, 0x0bea, 0x0beb, 0x0bec, 0x0bed, 0x0bee, 0x0bef, 
+    0x0bf0, 0x0bf1, 0x0bf2, 0x0bf3, 0x0bf4, 0x0bf5, 0x0bf6, 0x0bf7, 
+    0x0bf8, 0x0bf9, 0x0bfa, 0x0bfb, 0x0bfc, 0x0bfd, 0x0bfe, 0x0bff, 
+    0x0c00, 0x0c01, 0x0c02, 0x0c03, 0x0c04, 0x0c05, 0x0c06, 0x0c07, 
+    0x0c08, 0x0c09, 0x0c0a, 0x0c0b, 0x0c0c, 0x0c0d, 0x0c0e, 0x0c0f, 
+    0x0c10, 0x0c11, 0x0c12, 0x0c13, 0x0c14, 0x0c15, 0x0c16, 0x0c17, 
+    0x0c18, 0x0c19, 0x0c1a, 0x0c1b, 0x0c1c, 0x0c1d, 0x0c1e, 0x0c1f, 
+    0x0c20, 0x0c21, 0x0c22, 0x0c23, 0x0c24, 0x0c25, 0x0c26, 0x0c27, 
+    0x0c28, 0x0c29, 0x0c2a, 0x0c2b, 0x0c2c, 0x0c2d, 0x0c2e, 0x0c2f, 
+    0x0c30, 0x0c31, 0x0c32, 0x0c33, 0x0c34, 0x0c35, 0x0c36, 0x0c37, 
+    0x0c38, 0x0c39, 0x0c3a, 0x0c3b, 0x0c3c, 0x0c3d, 0x0c3e, 0x0c3f, 
+    0x0c40, 0x0c41, 0x0c42, 0x0c43, 0x0c44, 0x0c45, 0x0c46, 0x0c47, 
+    0x0c48, 0x0c49, 0x0c4a, 0x0c4b, 0x0c4c, 0x0c4d, 0x0c4e, 0x0c4f, 
+    0x0c50, 0x0c51, 0x0c52, 0x0c53, 0x0c54, 0x0c55, 0x0c56, 0x0c57, 
+    0x0c58, 0x0c59, 0x0c5a, 0x0c5b, 0x0c5c, 0x0c5d, 0x0c5e, 0x0c5f, 
+    0x0c60, 0x0c61, 0x0c62, 0x0c63, 0x0c64, 0x0c65, 0x0c66, 0x0c67, 
+    0x0c68, 0x0c69, 0x0c6a, 0x0c6b, 0x0c6c, 0x0c6d, 0x0c6e, 0x0c6f, 
+    0x0c70, 0x0c71, 0x0c72, 0x0c73, 0x0c74, 0x0c75, 0x0c76, 0x0c77, 
+    0x0c78, 0x0c79, 0x0c7a, 0x0c7b, 0x0c7c, 0x0c7d, 0x0c7e, 0x0c7f, 
+    0x0c80, 0x0c81, 0x0c82, 0x0c83, 0x0c84, 0x0c85, 0x0c86, 0x0c87, 
+    0x0c88, 0x0c89, 0x0c8a, 0x0c8b, 0x0c8c, 0x0c8d, 0x0c8e, 0x0c8f, 
+    0x0c90, 0x0c91, 0x0c92, 0x0c93, 0x0c94, 0x0c95, 0x0c96, 0x0c97, 
+    0x0c98, 0x0c99, 0x0c9a, 0x0c9b, 0x0c9c, 0x0c9d, 0x0c9e, 0x0c9f, 
+    0x0ca0, 0x0ca1, 0x0ca2, 0x0ca3, 0x0ca4, 0x0ca5, 0x0ca6, 0x0ca7, 
+    0x0ca8, 0x0ca9, 0x0caa, 0x0cab, 0x0cac, 0x0cad, 0x0cae, 0x0caf, 
+    0x0cb0, 0x0cb1, 0x0cb2, 0x0cb3, 0x0cb4, 0x0cb5, 0x0cb6, 0x0cb7, 
+    0x0cb8, 0x0cb9, 0x0cba, 0x0cbb, 0x0cbc, 0x0cbd, 0x0cbe, 0x0cbf, 
+    0x0cc0, 0x0cc1, 0x0cc2, 0x0cc3, 0x0cc4, 0x0cc5, 0x0cc6, 0x0cc7, 
+    0x0cc8, 0x0cc9, 0x0cca, 0x0ccb, 0x0ccc, 0x0ccd, 0x0cce, 0x0ccf, 
+    0x0cd0, 0x0cd1, 0x0cd2, 0x0cd3, 0x0cd4, 0x0cd5, 0x0cd6, 0x0cd7, 
+    0x0cd8, 0x0cd9, 0x0cda, 0x0cdb, 0x0cdc, 0x0cdd, 0x0cde, 0x0cdf, 
+    0x0ce0, 0x0ce1, 0x0ce2, 0x0ce3, 0x0ce4, 0x0ce5, 0x0ce6, 0x0ce7, 
+    0x0ce8, 0x0ce9, 0x0cea, 0x0ceb, 0x0cec, 0x0ced, 0x0cee, 0x0cef, 
+    0x0cf0, 0x0cf1, 0x0cf2, 0x0cf3, 0x0cf4, 0x0cf5, 0x0cf6, 0x0cf7, 
+    0x0cf8, 0x0cf9, 0x0cfa, 0x0cfb, 0x0cfc, 0x0cfd, 0x0cfe, 0x0cff, 
+    0x0d00, 0x0d01, 0x0d02, 0x0d03, 0x0d04, 0x0d05, 0x0d06, 0x0d07, 
+    0x0d08, 0x0d09, 0x0d0a, 0x0d0b, 0x0d0c, 0x0d0d, 0x0d0e, 0x0d0f, 
+    0x0d10, 0x0d11, 0x0d12, 0x0d13, 0x0d14, 0x0d15, 0x0d16, 0x0d17, 
+    0x0d18, 0x0d19, 0x0d1a, 0x0d1b, 0x0d1c, 0x0d1d, 0x0d1e, 0x0d1f, 
+    0x0d20, 0x0d21, 0x0d22, 0x0d23, 0x0d24, 0x0d25, 0x0d26, 0x0d27, 
+    0x0d28, 0x0d29, 0x0d2a, 0x0d2b, 0x0d2c, 0x0d2d, 0x0d2e, 0x0d2f, 
+    0x0d30, 0x0d31, 0x0d32, 0x0d33, 0x0d34, 0x0d35, 0x0d36, 0x0d37, 
+    0x0d38, 0x0d39, 0x0d3a, 0x0d3b, 0x0d3c, 0x0d3d, 0x0d3e, 0x0d3f, 
+    0x0d40, 0x0d41, 0x0d42, 0x0d43, 0x0d44, 0x0d45, 0x0d46, 0x0d47, 
+    0x0d48, 0x0d49, 0x0d4a, 0x0d4b, 0x0d4c, 0x0d4d, 0x0d4e, 0x0d4f, 
+    0x0d50, 0x0d51, 0x0d52, 0x0d53, 0x0d54, 0x0d55, 0x0d56, 0x0d57, 
+    0x0d58, 0x0d59, 0x0d5a, 0x0d5b, 0x0d5c, 0x0d5d, 0x0d5e, 0x0d5f, 
+    0x0d60, 0x0d61, 0x0d62, 0x0d63, 0x0d64, 0x0d65, 0x0d66, 0x0d67, 
+    0x0d68, 0x0d69, 0x0d6a, 0x0d6b, 0x0d6c, 0x0d6d, 0x0d6e, 0x0d6f, 
+    0x0d70, 0x0d71, 0x0d72, 0x0d73, 0x0d74, 0x0d75, 0x0d76, 0x0d77, 
+    0x0d78, 0x0d79, 0x0d7a, 0x0d7b, 0x0d7c, 0x0d7d, 0x0d7e, 0x0d7f, 
+    0x0d80, 0x0d81, 0x0d82, 0x0d83, 0x0d84, 0x0d85, 0x0d86, 0x0d87, 
+    0x0d88, 0x0d89, 0x0d8a, 0x0d8b, 0x0d8c, 0x0d8d, 0x0d8e, 0x0d8f, 
+    0x0d90, 0x0d91, 0x0d92, 0x0d93, 0x0d94, 0x0d95, 0x0d96, 0x0d97, 
+    0x0d98, 0x0d99, 0x0d9a, 0x0d9b, 0x0d9c, 0x0d9d, 0x0d9e, 0x0d9f, 
+    0x0da0, 0x0da1, 0x0da2, 0x0da3, 0x0da4, 0x0da5, 0x0da6, 0x0da7, 
+    0x0da8, 0x0da9, 0x0daa, 0x0dab, 0x0dac, 0x0dad, 0x0dae, 0x0daf, 
+    0x0db0, 0x0db1, 0x0db2, 0x0db3, 0x0db4, 0x0db5, 0x0db6, 0x0db7, 
+    0x0db8, 0x0db9, 0x0dba, 0x0dbb, 0x0dbc, 0x0dbd, 0x0dbe, 0x0dbf, 
+    0x0dc0, 0x0dc1, 0x0dc2, 0x0dc3, 0x0dc4, 0x0dc5, 0x0dc6, 0x0dc7, 
+    0x0dc8, 0x0dc9, 0x0dca, 0x0dcb, 0x0dcc, 0x0dcd, 0x0dce, 0x0dcf, 
+    0x0dd0, 0x0dd1, 0x0dd2, 0x0dd3, 0x0dd4, 0x0dd5, 0x0dd6, 0x0dd7, 
+    0x0dd8, 0x0dd9, 0x0dda, 0x0ddb, 0x0ddc, 0x0ddd, 0x0dde, 0x0ddf, 
+    0x0de0, 0x0de1, 0x0de2, 0x0de3, 0x0de4, 0x0de5, 0x0de6, 0x0de7, 
+    0x0de8, 0x0de9, 0x0dea, 0x0deb, 0x0dec, 0x0ded, 0x0dee, 0x0def, 
+    0x0df0, 0x0df1, 0x0df2, 0x0df3, 0x0df4, 0x0df5, 0x0df6, 0x0df7, 
+    0x0df8, 0x0df9, 0x0dfa, 0x0dfb, 0x0dfc, 0x0dfd, 0x0dfe, 0x0dff, 
+    0x0e00, 0x0e01, 0x0e02, 0x0e03, 0x0e04, 0x0e05, 0x0e06, 0x0e07, 
+    0x0e08, 0x0e09, 0x0e0a, 0x0e0b, 0x0e0c, 0x0e0d, 0x0e0e, 0x0e0f, 
+    0x0e10, 0x0e11, 0x0e12, 0x0e13, 0x0e14, 0x0e15, 0x0e16, 0x0e17, 
+    0x0e18, 0x0e19, 0x0e1a, 0x0e1b, 0x0e1c, 0x0e1d, 0x0e1e, 0x0e1f, 
+    0x0e20, 0x0e21, 0x0e22, 0x0e23, 0x0e24, 0x0e25, 0x0e26, 0x0e27, 
+    0x0e28, 0x0e29, 0x0e2a, 0x0e2b, 0x0e2c, 0x0e2d, 0x0e2e, 0x0e2f, 
+    0x0e30, 0x0e31, 0x0e32, 0x0e33, 0x0e34, 0x0e35, 0x0e36, 0x0e37, 
+    0x0e38, 0x0e39, 0x0e3a, 0x0e3b, 0x0e3c, 0x0e3d, 0x0e3e, 0x0e3f, 
+    0x0e40, 0x0e41, 0x0e42, 0x0e43, 0x0e44, 0x0e45, 0x0e46, 0x0e47, 
+    0x0e48, 0x0e49, 0x0e4a, 0x0e4b, 0x0e4c, 0x0e4d, 0x0e4e, 0x0e4f, 
+    0x0e50, 0x0e51, 0x0e52, 0x0e53, 0x0e54, 0x0e55, 0x0e56, 0x0e57, 
+    0x0e58, 0x0e59, 0x0e5a, 0x0e5b, 0x0e5c, 0x0e5d, 0x0e5e, 0x0e5f, 
+    0x0e60, 0x0e61, 0x0e62, 0x0e63, 0x0e64, 0x0e65, 0x0e66, 0x0e67, 
+    0x0e68, 0x0e69, 0x0e6a, 0x0e6b, 0x0e6c, 0x0e6d, 0x0e6e, 0x0e6f, 
+    0x0e70, 0x0e71, 0x0e72, 0x0e73, 0x0e74, 0x0e75, 0x0e76, 0x0e77, 
+    0x0e78, 0x0e79, 0x0e7a, 0x0e7b, 0x0e7c, 0x0e7d, 0x0e7e, 0x0e7f, 
+    0x0e80, 0x0e81, 0x0e82, 0x0e83, 0x0e84, 0x0e85, 0x0e86, 0x0e87, 
+    0x0e88, 0x0e89, 0x0e8a, 0x0e8b, 0x0e8c, 0x0e8d, 0x0e8e, 0x0e8f, 
+    0x0e90, 0x0e91, 0x0e92, 0x0e93, 0x0e94, 0x0e95, 0x0e96, 0x0e97, 
+    0x0e98, 0x0e99, 0x0e9a, 0x0e9b, 0x0e9c, 0x0e9d, 0x0e9e, 0x0e9f, 
+    0x0ea0, 0x0ea1, 0x0ea2, 0x0ea3, 0x0ea4, 0x0ea5, 0x0ea6, 0x0ea7, 
+    0x0ea8, 0x0ea9, 0x0eaa, 0x0eab, 0x0eac, 0x0ead, 0x0eae, 0x0eaf, 
+    0x0eb0, 0x0eb1, 0x0eb2, 0x0eb3, 0x0eb4, 0x0eb5, 0x0eb6, 0x0eb7, 
+    0x0eb8, 0x0eb9, 0x0eba, 0x0ebb, 0x0ebc, 0x0ebd, 0x0ebe, 0x0ebf, 
+    0x0ec0, 0x0ec1, 0x0ec2, 0x0ec3, 0x0ec4, 0x0ec5, 0x0ec6, 0x0ec7, 
+    0x0ec8, 0x0ec9, 0x0eca, 0x0ecb, 0x0ecc, 0x0ecd, 0x0ece, 0x0ecf, 
+    0x0ed0, 0x0ed1, 0x0ed2, 0x0ed3, 0x0ed4, 0x0ed5, 0x0ed6, 0x0ed7, 
+    0x0ed8, 0x0ed9, 0x0eda, 0x0edb, 0x0edc, 0x0edd, 0x0ede, 0x0edf, 
+    0x0ee0, 0x0ee1, 0x0ee2, 0x0ee3, 0x0ee4, 0x0ee5, 0x0ee6, 0x0ee7, 
+    0x0ee8, 0x0ee9, 0x0eea, 0x0eeb, 0x0eec, 0x0eed, 0x0eee, 0x0eef, 
+    0x0ef0, 0x0ef1, 0x0ef2, 0x0ef3, 0x0ef4, 0x0ef5, 0x0ef6, 0x0ef7, 
+    0x0ef8, 0x0ef9, 0x0efa, 0x0efb, 0x0efc, 0x0efd, 0x0efe, 0x0eff, 
+    0x0f00, 0x0f01, 0x0f02, 0x0f03, 0x0f04, 0x0f05, 0x0f06, 0x0f07, 
+    0x0f08, 0x0f09, 0x0f0a, 0x0f0b, 0x0f0c, 0x0f0d, 0x0f0e, 0x0f0f, 
+    0x0f10, 0x0f11, 0x0f12, 0x0f13, 0x0f14, 0x0f15, 0x0f16, 0x0f17, 
+    0x0f18, 0x0f19, 0x0f1a, 0x0f1b, 0x0f1c, 0x0f1d, 0x0f1e, 0x0f1f, 
+    0x0f20, 0x0f21, 0x0f22, 0x0f23, 0x0f24, 0x0f25, 0x0f26, 0x0f27, 
+    0x0f28, 0x0f29, 0x0f2a, 0x0f2b, 0x0f2c, 0x0f2d, 0x0f2e, 0x0f2f, 
+    0x0f30, 0x0f31, 0x0f32, 0x0f33, 0x0f34, 0x0f35, 0x0f36, 0x0f37, 
+    0x0f38, 0x0f39, 0x0f3a, 0x0f3b, 0x0f3c, 0x0f3d, 0x0f3e, 0x0f3f, 
+    0x0f40, 0x0f41, 0x0f42, 0x0f43, 0x0f44, 0x0f45, 0x0f46, 0x0f47, 
+    0x0f48, 0x0f49, 0x0f4a, 0x0f4b, 0x0f4c, 0x0f4d, 0x0f4e, 0x0f4f, 
+    0x0f50, 0x0f51, 0x0f52, 0x0f53, 0x0f54, 0x0f55, 0x0f56, 0x0f57, 
+    0x0f58, 0x0f59, 0x0f5a, 0x0f5b, 0x0f5c, 0x0f5d, 0x0f5e, 0x0f5f, 
+    0x0f60, 0x0f61, 0x0f62, 0x0f63, 0x0f64, 0x0f65, 0x0f66, 0x0f67, 
+    0x0f68, 0x0f69, 0x0f6a, 0x0f6b, 0x0f6c, 0x0f6d, 0x0f6e, 0x0f6f, 
+    0x0f70, 0x0f71, 0x0f72, 0x0f73, 0x0f74, 0x0f75, 0x0f76, 0x0f77, 
+    0x0f78, 0x0f79, 0x0f7a, 0x0f7b, 0x0f7c, 0x0f7d, 0x0f7e, 0x0f7f, 
+    0x0f80, 0x0f81, 0x0f82, 0x0f83, 0x0f84, 0x0f85, 0x0f86, 0x0f87, 
+    0x0f88, 0x0f89, 0x0f8a, 0x0f8b, 0x0f8c, 0x0f8d, 0x0f8e, 0x0f8f, 
+    0x0f90, 0x0f91, 0x0f92, 0x0f93, 0x0f94, 0x0f95, 0x0f96, 0x0f97, 
+    0x0f98, 0x0f99, 0x0f9a, 0x0f9b, 0x0f9c, 0x0f9d, 0x0f9e, 0x0f9f, 
+    0x0fa0, 0x0fa1, 0x0fa2, 0x0fa3, 0x0fa4, 0x0fa5, 0x0fa6, 0x0fa7, 
+    0x0fa8, 0x0fa9, 0x0faa, 0x0fab, 0x0fac, 0x0fad, 0x0fae, 0x0faf, 
+    0x0fb0, 0x0fb1, 0x0fb2, 0x0fb3, 0x0fb4, 0x0fb5, 0x0fb6, 0x0fb7, 
+    0x0fb8, 0x0fb9, 0x0fba, 0x0fbb, 0x0fbc, 0x0fbd, 0x0fbe, 0x0fbf, 
+    0x0fc0, 0x0fc1, 0x0fc2, 0x0fc3, 0x0fc4, 0x0fc5, 0x0fc6, 0x0fc7, 
+    0x0fc8, 0x0fc9, 0x0fca, 0x0fcb, 0x0fcc, 0x0fcd, 0x0fce, 0x0fcf, 
+    0x0fd0, 0x0fd1, 0x0fd2, 0x0fd3, 0x0fd4, 0x0fd5, 0x0fd6, 0x0fd7, 
+    0x0fd8, 0x0fd9, 0x0fda, 0x0fdb, 0x0fdc, 0x0fdd, 0x0fde, 0x0fdf, 
+    0x0fe0, 0x0fe1, 0x0fe2, 0x0fe3, 0x0fe4, 0x0fe5, 0x0fe6, 0x0fe7, 
+    0x0fe8, 0x0fe9, 0x0fea, 0x0feb, 0x0fec, 0x0fed, 0x0fee, 0x0fef, 
+    0x0ff0, 0x0ff1, 0x0ff2, 0x0ff3, 0x0ff4, 0x0ff5, 0x0ff6, 0x0ff7, 
+    0x0ff8, 0x0ff9, 0x0ffa, 0x0ffb, 0x0ffc, 0x0ffd, 0x0ffe, 0x0fff, 
+    0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 0x1007, 
+    0x1008, 0x1009, 0x100a, 0x100b, 0x100c, 0x100d, 0x100e, 0x100f, 
+    0x1010, 0x1011, 0x1012, 0x1013, 0x1014, 0x1015, 0x1016, 0x1017, 
+    0x1018, 0x1019, 0x101a, 0x101b, 0x101c, 0x101d, 0x101e, 0x101f, 
+    0x1020, 0x1021, 0x1022, 0x1023, 0x1024, 0x1025, 0x1026, 0x1027, 
+    0x1028, 0x1029, 0x102a, 0x102b, 0x102c, 0x102d, 0x102e, 0x102f, 
+    0x1030, 0x1031, 0x1032, 0x1033, 0x1034, 0x1035, 0x1036, 0x1037, 
+    0x1038, 0x1039, 0x103a, 0x103b, 0x103c, 0x103d, 0x103e, 0x103f, 
+    0x1040, 0x1041, 0x1042, 0x1043, 0x1044, 0x1045, 0x1046, 0x1047, 
+    0x1048, 0x1049, 0x104a, 0x104b, 0x104c, 0x104d, 0x104e, 0x104f, 
+    0x1050, 0x1051, 0x1052, 0x1053, 0x1054, 0x1055, 0x1056, 0x1057, 
+    0x1058, 0x1059, 0x105a, 0x105b, 0x105c, 0x105d, 0x105e, 0x105f, 
+    0x1060, 0x1061, 0x1062, 0x1063, 0x1064, 0x1065, 0x1066, 0x1067, 
+    0x1068, 0x1069, 0x106a, 0x106b, 0x106c, 0x106d, 0x106e, 0x106f, 
+    0x1070, 0x1071, 0x1072, 0x1073, 0x1074, 0x1075, 0x1076, 0x1077, 
+    0x1078, 0x1079, 0x107a, 0x107b, 0x107c, 0x107d, 0x107e, 0x107f, 
+    0x1080, 0x1081, 0x1082, 0x1083, 0x1084, 0x1085, 0x1086, 0x1087, 
+    0x1088, 0x1089, 0x108a, 0x108b, 0x108c, 0x108d, 0x108e, 0x108f, 
+    0x1090, 0x1091, 0x1092, 0x1093, 0x1094, 0x1095, 0x1096, 0x1097, 
+    0x1098, 0x1099, 0x109a, 0x109b, 0x109c, 0x109d, 0x109e, 0x109f, 
+    0x10a0, 0x10a1, 0x10a2, 0x10a3, 0x10a4, 0x10a5, 0x10a6, 0x10a7, 
+    0x10a8, 0x10a9, 0x10aa, 0x10ab, 0x10ac, 0x10ad, 0x10ae, 0x10af, 
+    0x10b0, 0x10b1, 0x10b2, 0x10b3, 0x10b4, 0x10b5, 0x10b6, 0x10b7, 
+    0x10b8, 0x10b9, 0x10ba, 0x10bb, 0x10bc, 0x10bd, 0x10be, 0x10bf, 
+    0x10c0, 0x10c1, 0x10c2, 0x10c3, 0x10c4, 0x10c5, 0x10c6, 0x10c7, 
+    0x10c8, 0x10c9, 0x10ca, 0x10cb, 0x10cc, 0x10cd, 0x10ce, 0x10cf, 
+    0x10d0, 0x10d1, 0x10d2, 0x10d3, 0x10d4, 0x10d5, 0x10d6, 0x10d7, 
+    0x10d8, 0x10d9, 0x10da, 0x10db, 0x10dc, 0x10dd, 0x10de, 0x10df, 
+    0x10e0, 0x10e1, 0x10e2, 0x10e3, 0x10e4, 0x10e5, 0x10e6, 0x10e7, 
+    0x10e8, 0x10e9, 0x10ea, 0x10eb, 0x10ec, 0x10ed, 0x10ee, 0x10ef, 
+    0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6, 0x10f7, 
+    0x10f8, 0x10f9, 0x10fa, 0x10fb, 0x10fc, 0x10fd, 0x10fe, 0x10ff, 
+    0x1100, 0x1101, 0x1102, 0x1103, 0x1104, 0x1105, 0x1106, 0x1107, 
+    0x1108, 0x1109, 0x110a, 0x110b, 0x110c, 0x110d, 0x110e, 0x110f, 
+    0x1110, 0x1111, 0x1112, 0x1113, 0x1114, 0x1115, 0x1116, 0x1117, 
+    0x1118, 0x1119, 0x111a, 0x111b, 0x111c, 0x111d, 0x111e, 0x111f, 
+    0x1120, 0x1121, 0x1122, 0x1123, 0x1124, 0x1125, 0x1126, 0x1127, 
+    0x1128, 0x1129, 0x112a, 0x112b, 0x112c, 0x112d, 0x112e, 0x112f, 
+    0x1130, 0x1131, 0x1132, 0x1133, 0x1134, 0x1135, 0x1136, 0x1137, 
+    0x1138, 0x1139, 0x113a, 0x113b, 0x113c, 0x113d, 0x113e, 0x113f, 
+    0x1140, 0x1141, 0x1142, 0x1143, 0x1144, 0x1145, 0x1146, 0x1147, 
+    0x1148, 0x1149, 0x114a, 0x114b, 0x114c, 0x114d, 0x114e, 0x114f, 
+    0x1150, 0x1151, 0x1152, 0x1153, 0x1154, 0x1155, 0x1156, 0x1157, 
+    0x1158, 0x1159, 0x115a, 0x115b, 0x115c, 0x115d, 0x115e, 0x115f, 
+    0x1160, 0x1161, 0x1162, 0x1163, 0x1164, 0x1165, 0x1166, 0x1167, 
+    0x1168, 0x1169, 0x116a, 0x116b, 0x116c, 0x116d, 0x116e, 0x116f, 
+    0x1170, 0x1171, 0x1172, 0x1173, 0x1174, 0x1175, 0x1176, 0x1177, 
+    0x1178, 0x1179, 0x117a, 0x117b, 0x117c, 0x117d, 0x117e, 0x117f, 
+    0x1180, 0x1181, 0x1182, 0x1183, 0x1184, 0x1185, 0x1186, 0x1187, 
+    0x1188, 0x1189, 0x118a, 0x118b, 0x118c, 0x118d, 0x118e, 0x118f, 
+    0x1190, 0x1191, 0x1192, 0x1193, 0x1194, 0x1195, 0x1196, 0x1197, 
+    0x1198, 0x1199, 0x119a, 0x119b, 0x119c, 0x119d, 0x119e, 0x119f, 
+    0x11a0, 0x11a1, 0x11a2, 0x11a3, 0x11a4, 0x11a5, 0x11a6, 0x11a7, 
+    0x11a8, 0x11a9, 0x11aa, 0x11ab, 0x11ac, 0x11ad, 0x11ae, 0x11af, 
+    0x11b0, 0x11b1, 0x11b2, 0x11b3, 0x11b4, 0x11b5, 0x11b6, 0x11b7, 
+    0x11b8, 0x11b9, 0x11ba, 0x11bb, 0x11bc, 0x11bd, 0x11be, 0x11bf, 
+    0x11c0, 0x11c1, 0x11c2, 0x11c3, 0x11c4, 0x11c5, 0x11c6, 0x11c7, 
+    0x11c8, 0x11c9, 0x11ca, 0x11cb, 0x11cc, 0x11cd, 0x11ce, 0x11cf, 
+    0x11d0, 0x11d1, 0x11d2, 0x11d3, 0x11d4, 0x11d5, 0x11d6, 0x11d7, 
+    0x11d8, 0x11d9, 0x11da, 0x11db, 0x11dc, 0x11dd, 0x11de, 0x11df, 
+    0x11e0, 0x11e1, 0x11e2, 0x11e3, 0x11e4, 0x11e5, 0x11e6, 0x11e7, 
+    0x11e8, 0x11e9, 0x11ea, 0x11eb, 0x11ec, 0x11ed, 0x11ee, 0x11ef, 
+    0x11f0, 0x11f1, 0x11f2, 0x11f3, 0x11f4, 0x11f5, 0x11f6, 0x11f7, 
+    0x11f8, 0x11f9, 0x11fa, 0x11fb, 0x11fc, 0x11fd, 0x11fe, 0x11ff, 
+    0x1200, 0x1201, 0x1202, 0x1203, 0x1204, 0x1205, 0x1206, 0x1207, 
+    0x1208, 0x1209, 0x120a, 0x120b, 0x120c, 0x120d, 0x120e, 0x120f, 
+    0x1210, 0x1211, 0x1212, 0x1213, 0x1214, 0x1215, 0x1216, 0x1217, 
+    0x1218, 0x1219, 0x121a, 0x121b, 0x121c, 0x121d, 0x121e, 0x121f, 
+    0x1220, 0x1221, 0x1222, 0x1223, 0x1224, 0x1225, 0x1226, 0x1227, 
+    0x1228, 0x1229, 0x122a, 0x122b, 0x122c, 0x122d, 0x122e, 0x122f, 
+    0x1230, 0x1231, 0x1232, 0x1233, 0x1234, 0x1235, 0x1236, 0x1237, 
+    0x1238, 0x1239, 0x123a, 0x123b, 0x123c, 0x123d, 0x123e, 0x123f, 
+    0x1240, 0x1241, 0x1242, 0x1243, 0x1244, 0x1245, 0x1246, 0x1247, 
+    0x1248, 0x1249, 0x124a, 0x124b, 0x124c, 0x124d, 0x124e, 0x124f, 
+    0x1250, 0x1251, 0x1252, 0x1253, 0x1254, 0x1255, 0x1256, 0x1257, 
+    0x1258, 0x1259, 0x125a, 0x125b, 0x125c, 0x125d, 0x125e, 0x125f, 
+    0x1260, 0x1261, 0x1262, 0x1263, 0x1264, 0x1265, 0x1266, 0x1267, 
+    0x1268, 0x1269, 0x126a, 0x126b, 0x126c, 0x126d, 0x126e, 0x126f, 
+    0x1270, 0x1271, 0x1272, 0x1273, 0x1274, 0x1275, 0x1276, 0x1277, 
+    0x1278, 0x1279, 0x127a, 0x127b, 0x127c, 0x127d, 0x127e, 0x127f, 
+    0x1280, 0x1281, 0x1282, 0x1283, 0x1284, 0x1285, 0x1286, 0x1287, 
+    0x1288, 0x1289, 0x128a, 0x128b, 0x128c, 0x128d, 0x128e, 0x128f, 
+    0x1290, 0x1291, 0x1292, 0x1293, 0x1294, 0x1295, 0x1296, 0x1297, 
+    0x1298, 0x1299, 0x129a, 0x129b, 0x129c, 0x129d, 0x129e, 0x129f, 
+    0x12a0, 0x12a1, 0x12a2, 0x12a3, 0x12a4, 0x12a5, 0x12a6, 0x12a7, 
+    0x12a8, 0x12a9, 0x12aa, 0x12ab, 0x12ac, 0x12ad, 0x12ae, 0x12af, 
+    0x12b0, 0x12b1, 0x12b2, 0x12b3, 0x12b4, 0x12b5, 0x12b6, 0x12b7, 
+    0x12b8, 0x12b9, 0x12ba, 0x12bb, 0x12bc, 0x12bd, 0x12be, 0x12bf, 
+    0x12c0, 0x12c1, 0x12c2, 0x12c3, 0x12c4, 0x12c5, 0x12c6, 0x12c7, 
+    0x12c8, 0x12c9, 0x12ca, 0x12cb, 0x12cc, 0x12cd, 0x12ce, 0x12cf, 
+    0x12d0, 0x12d1, 0x12d2, 0x12d3, 0x12d4, 0x12d5, 0x12d6, 0x12d7, 
+    0x12d8, 0x12d9, 0x12da, 0x12db, 0x12dc, 0x12dd, 0x12de, 0x12df, 
+    0x12e0, 0x12e1, 0x12e2, 0x12e3, 0x12e4, 0x12e5, 0x12e6, 0x12e7, 
+    0x12e8, 0x12e9, 0x12ea, 0x12eb, 0x12ec, 0x12ed, 0x12ee, 0x12ef, 
+    0x12f0, 0x12f1, 0x12f2, 0x12f3, 0x12f4, 0x12f5, 0x12f6, 0x12f7, 
+    0x12f8, 0x12f9, 0x12fa, 0x12fb, 0x12fc, 0x12fd, 0x12fe, 0x12ff, 
+    0x1300, 0x1301, 0x1302, 0x1303, 0x1304, 0x1305, 0x1306, 0x1307, 
+    0x1308, 0x1309, 0x130a, 0x130b, 0x130c, 0x130d, 0x130e, 0x130f, 
+    0x1310, 0x1311, 0x1312, 0x1313, 0x1314, 0x1315, 0x1316, 0x1317, 
+    0x1318, 0x1319, 0x131a, 0x131b, 0x131c, 0x131d, 0x131e, 0x131f, 
+    0x1320, 0x1321, 0x1322, 0x1323, 0x1324, 0x1325, 0x1326, 0x1327, 
+    0x1328, 0x1329, 0x132a, 0x132b, 0x132c, 0x132d, 0x132e, 0x132f, 
+    0x1330, 0x1331, 0x1332, 0x1333, 0x1334, 0x1335, 0x1336, 0x1337, 
+    0x1338, 0x1339, 0x133a, 0x133b, 0x133c, 0x133d, 0x133e, 0x133f, 
+    0x1340, 0x1341, 0x1342, 0x1343, 0x1344, 0x1345, 0x1346, 0x1347, 
+    0x1348, 0x1349, 0x134a, 0x134b, 0x134c, 0x134d, 0x134e, 0x134f, 
+    0x1350, 0x1351, 0x1352, 0x1353, 0x1354, 0x1355, 0x1356, 0x1357, 
+    0x1358, 0x1359, 0x135a, 0x135b, 0x135c, 0x135d, 0x135e, 0x135f, 
+    0x1360, 0x1361, 0x1362, 0x1363, 0x1364, 0x1365, 0x1366, 0x1367, 
+    0x1368, 0x1369, 0x136a, 0x136b, 0x136c, 0x136d, 0x136e, 0x136f, 
+    0x1370, 0x1371, 0x1372, 0x1373, 0x1374, 0x1375, 0x1376, 0x1377, 
+    0x1378, 0x1379, 0x137a, 0x137b, 0x137c, 0x137d, 0x137e, 0x137f, 
+    0x1380, 0x1381, 0x1382, 0x1383, 0x1384, 0x1385, 0x1386, 0x1387, 
+    0x1388, 0x1389, 0x138a, 0x138b, 0x138c, 0x138d, 0x138e, 0x138f, 
+    0x1390, 0x1391, 0x1392, 0x1393, 0x1394, 0x1395, 0x1396, 0x1397, 
+    0x1398, 0x1399, 0x139a, 0x139b, 0x139c, 0x139d, 0x139e, 0x139f, 
+    0x13a0, 0x13a1, 0x13a2, 0x13a3, 0x13a4, 0x13a5, 0x13a6, 0x13a7, 
+    0x13a8, 0x13a9, 0x13aa, 0x13ab, 0x13ac, 0x13ad, 0x13ae, 0x13af, 
+    0x13b0, 0x13b1, 0x13b2, 0x13b3, 0x13b4, 0x13b5, 0x13b6, 0x13b7, 
+    0x13b8, 0x13b9, 0x13ba, 0x13bb, 0x13bc, 0x13bd, 0x13be, 0x13bf, 
+    0x13c0, 0x13c1, 0x13c2, 0x13c3, 0x13c4, 0x13c5, 0x13c6, 0x13c7, 
+    0x13c8, 0x13c9, 0x13ca, 0x13cb, 0x13cc, 0x13cd, 0x13ce, 0x13cf, 
+    0x13d0, 0x13d1, 0x13d2, 0x13d3, 0x13d4, 0x13d5, 0x13d6, 0x13d7, 
+    0x13d8, 0x13d9, 0x13da, 0x13db, 0x13dc, 0x13dd, 0x13de, 0x13df, 
+    0x13e0, 0x13e1, 0x13e2, 0x13e3, 0x13e4, 0x13e5, 0x13e6, 0x13e7, 
+    0x13e8, 0x13e9, 0x13ea, 0x13eb, 0x13ec, 0x13ed, 0x13ee, 0x13ef, 
+    0x13f0, 0x13f1, 0x13f2, 0x13f3, 0x13f4, 0x13f5, 0x13f6, 0x13f7, 
+    0x13f8, 0x13f9, 0x13fa, 0x13fb, 0x13fc, 0x13fd, 0x13fe, 0x13ff, 
+    0x1400, 0x1401, 0x1402, 0x1403, 0x1404, 0x1405, 0x1406, 0x1407, 
+    0x1408, 0x1409, 0x140a, 0x140b, 0x140c, 0x140d, 0x140e, 0x140f, 
+    0x1410, 0x1411, 0x1412, 0x1413, 0x1414, 0x1415, 0x1416, 0x1417, 
+    0x1418, 0x1419, 0x141a, 0x141b, 0x141c, 0x141d, 0x141e, 0x141f, 
+    0x1420, 0x1421, 0x1422, 0x1423, 0x1424, 0x1425, 0x1426, 0x1427, 
+    0x1428, 0x1429, 0x142a, 0x142b, 0x142c, 0x142d, 0x142e, 0x142f, 
+    0x1430, 0x1431, 0x1432, 0x1433, 0x1434, 0x1435, 0x1436, 0x1437, 
+    0x1438, 0x1439, 0x143a, 0x143b, 0x143c, 0x143d, 0x143e, 0x143f, 
+    0x1440, 0x1441, 0x1442, 0x1443, 0x1444, 0x1445, 0x1446, 0x1447, 
+    0x1448, 0x1449, 0x144a, 0x144b, 0x144c, 0x144d, 0x144e, 0x144f, 
+    0x1450, 0x1451, 0x1452, 0x1453, 0x1454, 0x1455, 0x1456, 0x1457, 
+    0x1458, 0x1459, 0x145a, 0x145b, 0x145c, 0x145d, 0x145e, 0x145f, 
+    0x1460, 0x1461, 0x1462, 0x1463, 0x1464, 0x1465, 0x1466, 0x1467, 
+    0x1468, 0x1469, 0x146a, 0x146b, 0x146c, 0x146d, 0x146e, 0x146f, 
+    0x1470, 0x1471, 0x1472, 0x1473, 0x1474, 0x1475, 0x1476, 0x1477, 
+    0x1478, 0x1479, 0x147a, 0x147b, 0x147c, 0x147d, 0x147e, 0x147f, 
+    0x1480, 0x1481, 0x1482, 0x1483, 0x1484, 0x1485, 0x1486, 0x1487, 
+    0x1488, 0x1489, 0x148a, 0x148b, 0x148c, 0x148d, 0x148e, 0x148f, 
+    0x1490, 0x1491, 0x1492, 0x1493, 0x1494, 0x1495, 0x1496, 0x1497, 
+    0x1498, 0x1499, 0x149a, 0x149b, 0x149c, 0x149d, 0x149e, 0x149f, 
+    0x14a0, 0x14a1, 0x14a2, 0x14a3, 0x14a4, 0x14a5, 0x14a6, 0x14a7, 
+    0x14a8, 0x14a9, 0x14aa, 0x14ab, 0x14ac, 0x14ad, 0x14ae, 0x14af, 
+    0x14b0, 0x14b1, 0x14b2, 0x14b3, 0x14b4, 0x14b5, 0x14b6, 0x14b7, 
+    0x14b8, 0x14b9, 0x14ba, 0x14bb, 0x14bc, 0x14bd, 0x14be, 0x14bf, 
+    0x14c0, 0x14c1, 0x14c2, 0x14c3, 0x14c4, 0x14c5, 0x14c6, 0x14c7, 
+    0x14c8, 0x14c9, 0x14ca, 0x14cb, 0x14cc, 0x14cd, 0x14ce, 0x14cf, 
+    0x14d0, 0x14d1, 0x14d2, 0x14d3, 0x14d4, 0x14d5, 0x14d6, 0x14d7, 
+    0x14d8, 0x14d9, 0x14da, 0x14db, 0x14dc, 0x14dd, 0x14de, 0x14df, 
+    0x14e0, 0x14e1, 0x14e2, 0x14e3, 0x14e4, 0x14e5, 0x14e6, 0x14e7, 
+    0x14e8, 0x14e9, 0x14ea, 0x14eb, 0x14ec, 0x14ed, 0x14ee, 0x14ef, 
+    0x14f0, 0x14f1, 0x14f2, 0x14f3, 0x14f4, 0x14f5, 0x14f6, 0x14f7, 
+    0x14f8, 0x14f9, 0x14fa, 0x14fb, 0x14fc, 0x14fd, 0x14fe, 0x14ff, 
+    0x1500, 0x1501, 0x1502, 0x1503, 0x1504, 0x1505, 0x1506, 0x1507, 
+    0x1508, 0x1509, 0x150a, 0x150b, 0x150c, 0x150d, 0x150e, 0x150f, 
+    0x1510, 0x1511, 0x1512, 0x1513, 0x1514, 0x1515, 0x1516, 0x1517, 
+    0x1518, 0x1519, 0x151a, 0x151b, 0x151c, 0x151d, 0x151e, 0x151f, 
+    0x1520, 0x1521, 0x1522, 0x1523, 0x1524, 0x1525, 0x1526, 0x1527, 
+    0x1528, 0x1529, 0x152a, 0x152b, 0x152c, 0x152d, 0x152e, 0x152f, 
+    0x1530, 0x1531, 0x1532, 0x1533, 0x1534, 0x1535, 0x1536, 0x1537, 
+    0x1538, 0x1539, 0x153a, 0x153b, 0x153c, 0x153d, 0x153e, 0x153f, 
+    0x1540, 0x1541, 0x1542, 0x1543, 0x1544, 0x1545, 0x1546, 0x1547, 
+    0x1548, 0x1549, 0x154a, 0x154b, 0x154c, 0x154d, 0x154e, 0x154f, 
+    0x1550, 0x1551, 0x1552, 0x1553, 0x1554, 0x1555, 0x1556, 0x1557, 
+    0x1558, 0x1559, 0x155a, 0x155b, 0x155c, 0x155d, 0x155e, 0x155f, 
+    0x1560, 0x1561, 0x1562, 0x1563, 0x1564, 0x1565, 0x1566, 0x1567, 
+    0x1568, 0x1569, 0x156a, 0x156b, 0x156c, 0x156d, 0x156e, 0x156f, 
+    0x1570, 0x1571, 0x1572, 0x1573, 0x1574, 0x1575, 0x1576, 0x1577, 
+    0x1578, 0x1579, 0x157a, 0x157b, 0x157c, 0x157d, 0x157e, 0x157f, 
+    0x1580, 0x1581, 0x1582, 0x1583, 0x1584, 0x1585, 0x1586, 0x1587, 
+    0x1588, 0x1589, 0x158a, 0x158b, 0x158c, 0x158d, 0x158e, 0x158f, 
+    0x1590, 0x1591, 0x1592, 0x1593, 0x1594, 0x1595, 0x1596, 0x1597, 
+    0x1598, 0x1599, 0x159a, 0x159b, 0x159c, 0x159d, 0x159e, 0x159f, 
+    0x15a0, 0x15a1, 0x15a2, 0x15a3, 0x15a4, 0x15a5, 0x15a6, 0x15a7, 
+    0x15a8, 0x15a9, 0x15aa, 0x15ab, 0x15ac, 0x15ad, 0x15ae, 0x15af, 
+    0x15b0, 0x15b1, 0x15b2, 0x15b3, 0x15b4, 0x15b5, 0x15b6, 0x15b7, 
+    0x15b8, 0x15b9, 0x15ba, 0x15bb, 0x15bc, 0x15bd, 0x15be, 0x15bf, 
+    0x15c0, 0x15c1, 0x15c2, 0x15c3, 0x15c4, 0x15c5, 0x15c6, 0x15c7, 
+    0x15c8, 0x15c9, 0x15ca, 0x15cb, 0x15cc, 0x15cd, 0x15ce, 0x15cf, 
+    0x15d0, 0x15d1, 0x15d2, 0x15d3, 0x15d4, 0x15d5, 0x15d6, 0x15d7, 
+    0x15d8, 0x15d9, 0x15da, 0x15db, 0x15dc, 0x15dd, 0x15de, 0x15df, 
+    0x15e0, 0x15e1, 0x15e2, 0x15e3, 0x15e4, 0x15e5, 0x15e6, 0x15e7, 
+    0x15e8, 0x15e9, 0x15ea, 0x15eb, 0x15ec, 0x15ed, 0x15ee, 0x15ef, 
+    0x15f0, 0x15f1, 0x15f2, 0x15f3, 0x15f4, 0x15f5, 0x15f6, 0x15f7, 
+    0x15f8, 0x15f9, 0x15fa, 0x15fb, 0x15fc, 0x15fd, 0x15fe, 0x15ff, 
+    0x1600, 0x1601, 0x1602, 0x1603, 0x1604, 0x1605, 0x1606, 0x1607, 
+    0x1608, 0x1609, 0x160a, 0x160b, 0x160c, 0x160d, 0x160e, 0x160f, 
+    0x1610, 0x1611, 0x1612, 0x1613, 0x1614, 0x1615, 0x1616, 0x1617, 
+    0x1618, 0x1619, 0x161a, 0x161b, 0x161c, 0x161d, 0x161e, 0x161f, 
+    0x1620, 0x1621, 0x1622, 0x1623, 0x1624, 0x1625, 0x1626, 0x1627, 
+    0x1628, 0x1629, 0x162a, 0x162b, 0x162c, 0x162d, 0x162e, 0x162f, 
+    0x1630, 0x1631, 0x1632, 0x1633, 0x1634, 0x1635, 0x1636, 0x1637, 
+    0x1638, 0x1639, 0x163a, 0x163b, 0x163c, 0x163d, 0x163e, 0x163f, 
+    0x1640, 0x1641, 0x1642, 0x1643, 0x1644, 0x1645, 0x1646, 0x1647, 
+    0x1648, 0x1649, 0x164a, 0x164b, 0x164c, 0x164d, 0x164e, 0x164f, 
+    0x1650, 0x1651, 0x1652, 0x1653, 0x1654, 0x1655, 0x1656, 0x1657, 
+    0x1658, 0x1659, 0x165a, 0x165b, 0x165c, 0x165d, 0x165e, 0x165f, 
+    0x1660, 0x1661, 0x1662, 0x1663, 0x1664, 0x1665, 0x1666, 0x1667, 
+    0x1668, 0x1669, 0x166a, 0x166b, 0x166c, 0x166d, 0x166e, 0x166f, 
+    0x1670, 0x1671, 0x1672, 0x1673, 0x1674, 0x1675, 0x1676, 0x1677, 
+    0x1678, 0x1679, 0x167a, 0x167b, 0x167c, 0x167d, 0x167e, 0x167f, 
+    0x1680, 0x1681, 0x1682, 0x1683, 0x1684, 0x1685, 0x1686, 0x1687, 
+    0x1688, 0x1689, 0x168a, 0x168b, 0x168c, 0x168d, 0x168e, 0x168f, 
+    0x1690, 0x1691, 0x1692, 0x1693, 0x1694, 0x1695, 0x1696, 0x1697, 
+    0x1698, 0x1699, 0x169a, 0x169b, 0x169c, 0x169d, 0x169e, 0x169f, 
+    0x16a0, 0x16a1, 0x16a2, 0x16a3, 0x16a4, 0x16a5, 0x16a6, 0x16a7, 
+    0x16a8, 0x16a9, 0x16aa, 0x16ab, 0x16ac, 0x16ad, 0x16ae, 0x16af, 
+    0x16b0, 0x16b1, 0x16b2, 0x16b3, 0x16b4, 0x16b5, 0x16b6, 0x16b7, 
+    0x16b8, 0x16b9, 0x16ba, 0x16bb, 0x16bc, 0x16bd, 0x16be, 0x16bf, 
+    0x16c0, 0x16c1, 0x16c2, 0x16c3, 0x16c4, 0x16c5, 0x16c6, 0x16c7, 
+    0x16c8, 0x16c9, 0x16ca, 0x16cb, 0x16cc, 0x16cd, 0x16ce, 0x16cf, 
+    0x16d0, 0x16d1, 0x16d2, 0x16d3, 0x16d4, 0x16d5, 0x16d6, 0x16d7, 
+    0x16d8, 0x16d9, 0x16da, 0x16db, 0x16dc, 0x16dd, 0x16de, 0x16df, 
+    0x16e0, 0x16e1, 0x16e2, 0x16e3, 0x16e4, 0x16e5, 0x16e6, 0x16e7, 
+    0x16e8, 0x16e9, 0x16ea, 0x16eb, 0x16ec, 0x16ed, 0x16ee, 0x16ef, 
+    0x16f0, 0x16f1, 0x16f2, 0x16f3, 0x16f4, 0x16f5, 0x16f6, 0x16f7, 
+    0x16f8, 0x16f9, 0x16fa, 0x16fb, 0x16fc, 0x16fd, 0x16fe, 0x16ff, 
+    0x1700, 0x1701, 0x1702, 0x1703, 0x1704, 0x1705, 0x1706, 0x1707, 
+    0x1708, 0x1709, 0x170a, 0x170b, 0x170c, 0x170d, 0x170e, 0x170f, 
+    0x1710, 0x1711, 0x1712, 0x1713, 0x1714, 0x1715, 0x1716, 0x1717, 
+    0x1718, 0x1719, 0x171a, 0x171b, 0x171c, 0x171d, 0x171e, 0x171f, 
+    0x1720, 0x1721, 0x1722, 0x1723, 0x1724, 0x1725, 0x1726, 0x1727, 
+    0x1728, 0x1729, 0x172a, 0x172b, 0x172c, 0x172d, 0x172e, 0x172f, 
+    0x1730, 0x1731, 0x1732, 0x1733, 0x1734, 0x1735, 0x1736, 0x1737, 
+    0x1738, 0x1739, 0x173a, 0x173b, 0x173c, 0x173d, 0x173e, 0x173f, 
+    0x1740, 0x1741, 0x1742, 0x1743, 0x1744, 0x1745, 0x1746, 0x1747, 
+    0x1748, 0x1749, 0x174a, 0x174b, 0x174c, 0x174d, 0x174e, 0x174f, 
+    0x1750, 0x1751, 0x1752, 0x1753, 0x1754, 0x1755, 0x1756, 0x1757, 
+    0x1758, 0x1759, 0x175a, 0x175b, 0x175c, 0x175d, 0x175e, 0x175f, 
+    0x1760, 0x1761, 0x1762, 0x1763, 0x1764, 0x1765, 0x1766, 0x1767, 
+    0x1768, 0x1769, 0x176a, 0x176b, 0x176c, 0x176d, 0x176e, 0x176f, 
+    0x1770, 0x1771, 0x1772, 0x1773, 0x1774, 0x1775, 0x1776, 0x1777, 
+    0x1778, 0x1779, 0x177a, 0x177b, 0x177c, 0x177d, 0x177e, 0x177f, 
+    0x1780, 0x1781, 0x1782, 0x1783, 0x1784, 0x1785, 0x1786, 0x1787, 
+    0x1788, 0x1789, 0x178a, 0x178b, 0x178c, 0x178d, 0x178e, 0x178f, 
+    0x1790, 0x1791, 0x1792, 0x1793, 0x1794, 0x1795, 0x1796, 0x1797, 
+    0x1798, 0x1799, 0x179a, 0x179b, 0x179c, 0x179d, 0x179e, 0x179f, 
+    0x17a0, 0x17a1, 0x17a2, 0x17a3, 0x17a4, 0x17a5, 0x17a6, 0x17a7, 
+    0x17a8, 0x17a9, 0x17aa, 0x17ab, 0x17ac, 0x17ad, 0x17ae, 0x17af, 
+    0x17b0, 0x17b1, 0x17b2, 0x17b3, 0x17b4, 0x17b5, 0x17b6, 0x17b7, 
+    0x17b8, 0x17b9, 0x17ba, 0x17bb, 0x17bc, 0x17bd, 0x17be, 0x17bf, 
+    0x17c0, 0x17c1, 0x17c2, 0x17c3, 0x17c4, 0x17c5, 0x17c6, 0x17c7, 
+    0x17c8, 0x17c9, 0x17ca, 0x17cb, 0x17cc, 0x17cd, 0x17ce, 0x17cf, 
+    0x17d0, 0x17d1, 0x17d2, 0x17d3, 0x17d4, 0x17d5, 0x17d6, 0x17d7, 
+    0x17d8, 0x17d9, 0x17da, 0x17db, 0x17dc, 0x17dd, 0x17de, 0x17df, 
+    0x17e0, 0x17e1, 0x17e2, 0x17e3, 0x17e4, 0x17e5, 0x17e6, 0x17e7, 
+    0x17e8, 0x17e9, 0x17ea, 0x17eb, 0x17ec, 0x17ed, 0x17ee, 0x17ef, 
+    0x17f0, 0x17f1, 0x17f2, 0x17f3, 0x17f4, 0x17f5, 0x17f6, 0x17f7, 
+    0x17f8, 0x17f9, 0x17fa, 0x17fb, 0x17fc, 0x17fd, 0x17fe, 0x17ff, 
+    0x1800, 0x1801, 0x1802, 0x1803, 0x1804, 0x1805, 0x1806, 0x1807, 
+    0x1808, 0x1809, 0x180a, 0x180b, 0x180c, 0x180d, 0x180e, 0x180f, 
+    0x1810, 0x1811, 0x1812, 0x1813, 0x1814, 0x1815, 0x1816, 0x1817, 
+    0x1818, 0x1819, 0x181a, 0x181b, 0x181c, 0x181d, 0x181e, 0x181f, 
+    0x1820, 0x1821, 0x1822, 0x1823, 0x1824, 0x1825, 0x1826, 0x1827, 
+    0x1828, 0x1829, 0x182a, 0x182b, 0x182c, 0x182d, 0x182e, 0x182f, 
+    0x1830, 0x1831, 0x1832, 0x1833, 0x1834, 0x1835, 0x1836, 0x1837, 
+    0x1838, 0x1839, 0x183a, 0x183b, 0x183c, 0x183d, 0x183e, 0x183f, 
+    0x1840, 0x1841, 0x1842, 0x1843, 0x1844, 0x1845, 0x1846, 0x1847, 
+    0x1848, 0x1849, 0x184a, 0x184b, 0x184c, 0x184d, 0x184e, 0x184f, 
+    0x1850, 0x1851, 0x1852, 0x1853, 0x1854, 0x1855, 0x1856, 0x1857, 
+    0x1858, 0x1859, 0x185a, 0x185b, 0x185c, 0x185d, 0x185e, 0x185f, 
+    0x1860, 0x1861, 0x1862, 0x1863, 0x1864, 0x1865, 0x1866, 0x1867, 
+    0x1868, 0x1869, 0x186a, 0x186b, 0x186c, 0x186d, 0x186e, 0x186f, 
+    0x1870, 0x1871, 0x1872, 0x1873, 0x1874, 0x1875, 0x1876, 0x1877, 
+    0x1878, 0x1879, 0x187a, 0x187b, 0x187c, 0x187d, 0x187e, 0x187f, 
+    0x1880, 0x1881, 0x1882, 0x1883, 0x1884, 0x1885, 0x1886, 0x1887, 
+    0x1888, 0x1889, 0x188a, 0x188b, 0x188c, 0x188d, 0x188e, 0x188f, 
+    0x1890, 0x1891, 0x1892, 0x1893, 0x1894, 0x1895, 0x1896, 0x1897, 
+    0x1898, 0x1899, 0x189a, 0x189b, 0x189c, 0x189d, 0x189e, 0x189f, 
+    0x18a0, 0x18a1, 0x18a2, 0x18a3, 0x18a4, 0x18a5, 0x18a6, 0x18a7, 
+    0x18a8, 0x18a9, 0x18aa, 0x18ab, 0x18ac, 0x18ad, 0x18ae, 0x18af, 
+    0x18b0, 0x18b1, 0x18b2, 0x18b3, 0x18b4, 0x18b5, 0x18b6, 0x18b7, 
+    0x18b8, 0x18b9, 0x18ba, 0x18bb, 0x18bc, 0x18bd, 0x18be, 0x18bf, 
+    0x18c0, 0x18c1, 0x18c2, 0x18c3, 0x18c4, 0x18c5, 0x18c6, 0x18c7, 
+    0x18c8, 0x18c9, 0x18ca, 0x18cb, 0x18cc, 0x18cd, 0x18ce, 0x18cf, 
+    0x18d0, 0x18d1, 0x18d2, 0x18d3, 0x18d4, 0x18d5, 0x18d6, 0x18d7, 
+    0x18d8, 0x18d9, 0x18da, 0x18db, 0x18dc, 0x18dd, 0x18de, 0x18df, 
+    0x18e0, 0x18e1, 0x18e2, 0x18e3, 0x18e4, 0x18e5, 0x18e6, 0x18e7, 
+    0x18e8, 0x18e9, 0x18ea, 0x18eb, 0x18ec, 0x18ed, 0x18ee, 0x18ef, 
+    0x18f0, 0x18f1, 0x18f2, 0x18f3, 0x18f4, 0x18f5, 0x18f6, 0x18f7, 
+    0x18f8, 0x18f9, 0x18fa, 0x18fb, 0x18fc, 0x18fd, 0x18fe, 0x18ff, 
+    0x1900, 0x1901, 0x1902, 0x1903, 0x1904, 0x1905, 0x1906, 0x1907, 
+    0x1908, 0x1909, 0x190a, 0x190b, 0x190c, 0x190d, 0x190e, 0x190f, 
+    0x1910, 0x1911, 0x1912, 0x1913, 0x1914, 0x1915, 0x1916, 0x1917, 
+    0x1918, 0x1919, 0x191a, 0x191b, 0x191c, 0x191d, 0x191e, 0x191f, 
+    0x1920, 0x1921, 0x1922, 0x1923, 0x1924, 0x1925, 0x1926, 0x1927, 
+    0x1928, 0x1929, 0x192a, 0x192b, 0x192c, 0x192d, 0x192e, 0x192f, 
+    0x1930, 0x1931, 0x1932, 0x1933, 0x1934, 0x1935, 0x1936, 0x1937, 
+    0x1938, 0x1939, 0x193a, 0x193b, 0x193c, 0x193d, 0x193e, 0x193f, 
+    0x1940, 0x1941, 0x1942, 0x1943, 0x1944, 0x1945, 0x1946, 0x1947, 
+    0x1948, 0x1949, 0x194a, 0x194b, 0x194c, 0x194d, 0x194e, 0x194f, 
+    0x1950, 0x1951, 0x1952, 0x1953, 0x1954, 0x1955, 0x1956, 0x1957, 
+    0x1958, 0x1959, 0x195a, 0x195b, 0x195c, 0x195d, 0x195e, 0x195f, 
+    0x1960, 0x1961, 0x1962, 0x1963, 0x1964, 0x1965, 0x1966, 0x1967, 
+    0x1968, 0x1969, 0x196a, 0x196b, 0x196c, 0x196d, 0x196e, 0x196f, 
+    0x1970, 0x1971, 0x1972, 0x1973, 0x1974, 0x1975, 0x1976, 0x1977, 
+    0x1978, 0x1979, 0x197a, 0x197b, 0x197c, 0x197d, 0x197e, 0x197f, 
+    0x1980, 0x1981, 0x1982, 0x1983, 0x1984, 0x1985, 0x1986, 0x1987, 
+    0x1988, 0x1989, 0x198a, 0x198b, 0x198c, 0x198d, 0x198e, 0x198f, 
+    0x1990, 0x1991, 0x1992, 0x1993, 0x1994, 0x1995, 0x1996, 0x1997, 
+    0x1998, 0x1999, 0x199a, 0x199b, 0x199c, 0x199d, 0x199e, 0x199f, 
+    0x19a0, 0x19a1, 0x19a2, 0x19a3, 0x19a4, 0x19a5, 0x19a6, 0x19a7, 
+    0x19a8, 0x19a9, 0x19aa, 0x19ab, 0x19ac, 0x19ad, 0x19ae, 0x19af, 
+    0x19b0, 0x19b1, 0x19b2, 0x19b3, 0x19b4, 0x19b5, 0x19b6, 0x19b7, 
+    0x19b8, 0x19b9, 0x19ba, 0x19bb, 0x19bc, 0x19bd, 0x19be, 0x19bf, 
+    0x19c0, 0x19c1, 0x19c2, 0x19c3, 0x19c4, 0x19c5, 0x19c6, 0x19c7, 
+    0x19c8, 0x19c9, 0x19ca, 0x19cb, 0x19cc, 0x19cd, 0x19ce, 0x19cf, 
+    0x19d0, 0x19d1, 0x19d2, 0x19d3, 0x19d4, 0x19d5, 0x19d6, 0x19d7, 
+    0x19d8, 0x19d9, 0x19da, 0x19db, 0x19dc, 0x19dd, 0x19de, 0x19df, 
+    0x19e0, 0x19e1, 0x19e2, 0x19e3, 0x19e4, 0x19e5, 0x19e6, 0x19e7, 
+    0x19e8, 0x19e9, 0x19ea, 0x19eb, 0x19ec, 0x19ed, 0x19ee, 0x19ef, 
+    0x19f0, 0x19f1, 0x19f2, 0x19f3, 0x19f4, 0x19f5, 0x19f6, 0x19f7, 
+    0x19f8, 0x19f9, 0x19fa, 0x19fb, 0x19fc, 0x19fd, 0x19fe, 0x19ff, 
+    0x1a00, 0x1a01, 0x1a02, 0x1a03, 0x1a04, 0x1a05, 0x1a06, 0x1a07, 
+    0x1a08, 0x1a09, 0x1a0a, 0x1a0b, 0x1a0c, 0x1a0d, 0x1a0e, 0x1a0f, 
+    0x1a10, 0x1a11, 0x1a12, 0x1a13, 0x1a14, 0x1a15, 0x1a16, 0x1a17, 
+    0x1a18, 0x1a19, 0x1a1a, 0x1a1b, 0x1a1c, 0x1a1d, 0x1a1e, 0x1a1f, 
+    0x1a20, 0x1a21, 0x1a22, 0x1a23, 0x1a24, 0x1a25, 0x1a26, 0x1a27, 
+    0x1a28, 0x1a29, 0x1a2a, 0x1a2b, 0x1a2c, 0x1a2d, 0x1a2e, 0x1a2f, 
+    0x1a30, 0x1a31, 0x1a32, 0x1a33, 0x1a34, 0x1a35, 0x1a36, 0x1a37, 
+    0x1a38, 0x1a39, 0x1a3a, 0x1a3b, 0x1a3c, 0x1a3d, 0x1a3e, 0x1a3f, 
+    0x1a40, 0x1a41, 0x1a42, 0x1a43, 0x1a44, 0x1a45, 0x1a46, 0x1a47, 
+    0x1a48, 0x1a49, 0x1a4a, 0x1a4b, 0x1a4c, 0x1a4d, 0x1a4e, 0x1a4f, 
+    0x1a50, 0x1a51, 0x1a52, 0x1a53, 0x1a54, 0x1a55, 0x1a56, 0x1a57, 
+    0x1a58, 0x1a59, 0x1a5a, 0x1a5b, 0x1a5c, 0x1a5d, 0x1a5e, 0x1a5f, 
+    0x1a60, 0x1a61, 0x1a62, 0x1a63, 0x1a64, 0x1a65, 0x1a66, 0x1a67, 
+    0x1a68, 0x1a69, 0x1a6a, 0x1a6b, 0x1a6c, 0x1a6d, 0x1a6e, 0x1a6f, 
+    0x1a70, 0x1a71, 0x1a72, 0x1a73, 0x1a74, 0x1a75, 0x1a76, 0x1a77, 
+    0x1a78, 0x1a79, 0x1a7a, 0x1a7b, 0x1a7c, 0x1a7d, 0x1a7e, 0x1a7f, 
+    0x1a80, 0x1a81, 0x1a82, 0x1a83, 0x1a84, 0x1a85, 0x1a86, 0x1a87, 
+    0x1a88, 0x1a89, 0x1a8a, 0x1a8b, 0x1a8c, 0x1a8d, 0x1a8e, 0x1a8f, 
+    0x1a90, 0x1a91, 0x1a92, 0x1a93, 0x1a94, 0x1a95, 0x1a96, 0x1a97, 
+    0x1a98, 0x1a99, 0x1a9a, 0x1a9b, 0x1a9c, 0x1a9d, 0x1a9e, 0x1a9f, 
+    0x1aa0, 0x1aa1, 0x1aa2, 0x1aa3, 0x1aa4, 0x1aa5, 0x1aa6, 0x1aa7, 
+    0x1aa8, 0x1aa9, 0x1aaa, 0x1aab, 0x1aac, 0x1aad, 0x1aae, 0x1aaf, 
+    0x1ab0, 0x1ab1, 0x1ab2, 0x1ab3, 0x1ab4, 0x1ab5, 0x1ab6, 0x1ab7, 
+    0x1ab8, 0x1ab9, 0x1aba, 0x1abb, 0x1abc, 0x1abd, 0x1abe, 0x1abf, 
+    0x1ac0, 0x1ac1, 0x1ac2, 0x1ac3, 0x1ac4, 0x1ac5, 0x1ac6, 0x1ac7, 
+    0x1ac8, 0x1ac9, 0x1aca, 0x1acb, 0x1acc, 0x1acd, 0x1ace, 0x1acf, 
+    0x1ad0, 0x1ad1, 0x1ad2, 0x1ad3, 0x1ad4, 0x1ad5, 0x1ad6, 0x1ad7, 
+    0x1ad8, 0x1ad9, 0x1ada, 0x1adb, 0x1adc, 0x1add, 0x1ade, 0x1adf, 
+    0x1ae0, 0x1ae1, 0x1ae2, 0x1ae3, 0x1ae4, 0x1ae5, 0x1ae6, 0x1ae7, 
+    0x1ae8, 0x1ae9, 0x1aea, 0x1aeb, 0x1aec, 0x1aed, 0x1aee, 0x1aef, 
+    0x1af0, 0x1af1, 0x1af2, 0x1af3, 0x1af4, 0x1af5, 0x1af6, 0x1af7, 
+    0x1af8, 0x1af9, 0x1afa, 0x1afb, 0x1afc, 0x1afd, 0x1afe, 0x1aff, 
+    0x1b00, 0x1b01, 0x1b02, 0x1b03, 0x1b04, 0x1b05, 0x1b06, 0x1b07, 
+    0x1b08, 0x1b09, 0x1b0a, 0x1b0b, 0x1b0c, 0x1b0d, 0x1b0e, 0x1b0f, 
+    0x1b10, 0x1b11, 0x1b12, 0x1b13, 0x1b14, 0x1b15, 0x1b16, 0x1b17, 
+    0x1b18, 0x1b19, 0x1b1a, 0x1b1b, 0x1b1c, 0x1b1d, 0x1b1e, 0x1b1f, 
+    0x1b20, 0x1b21, 0x1b22, 0x1b23, 0x1b24, 0x1b25, 0x1b26, 0x1b27, 
+    0x1b28, 0x1b29, 0x1b2a, 0x1b2b, 0x1b2c, 0x1b2d, 0x1b2e, 0x1b2f, 
+    0x1b30, 0x1b31, 0x1b32, 0x1b33, 0x1b34, 0x1b35, 0x1b36, 0x1b37, 
+    0x1b38, 0x1b39, 0x1b3a, 0x1b3b, 0x1b3c, 0x1b3d, 0x1b3e, 0x1b3f, 
+    0x1b40, 0x1b41, 0x1b42, 0x1b43, 0x1b44, 0x1b45, 0x1b46, 0x1b47, 
+    0x1b48, 0x1b49, 0x1b4a, 0x1b4b, 0x1b4c, 0x1b4d, 0x1b4e, 0x1b4f, 
+    0x1b50, 0x1b51, 0x1b52, 0x1b53, 0x1b54, 0x1b55, 0x1b56, 0x1b57, 
+    0x1b58, 0x1b59, 0x1b5a, 0x1b5b, 0x1b5c, 0x1b5d, 0x1b5e, 0x1b5f, 
+    0x1b60, 0x1b61, 0x1b62, 0x1b63, 0x1b64, 0x1b65, 0x1b66, 0x1b67, 
+    0x1b68, 0x1b69, 0x1b6a, 0x1b6b, 0x1b6c, 0x1b6d, 0x1b6e, 0x1b6f, 
+    0x1b70, 0x1b71, 0x1b72, 0x1b73, 0x1b74, 0x1b75, 0x1b76, 0x1b77, 
+    0x1b78, 0x1b79, 0x1b7a, 0x1b7b, 0x1b7c, 0x1b7d, 0x1b7e, 0x1b7f, 
+    0x1b80, 0x1b81, 0x1b82, 0x1b83, 0x1b84, 0x1b85, 0x1b86, 0x1b87, 
+    0x1b88, 0x1b89, 0x1b8a, 0x1b8b, 0x1b8c, 0x1b8d, 0x1b8e, 0x1b8f, 
+    0x1b90, 0x1b91, 0x1b92, 0x1b93, 0x1b94, 0x1b95, 0x1b96, 0x1b97, 
+    0x1b98, 0x1b99, 0x1b9a, 0x1b9b, 0x1b9c, 0x1b9d, 0x1b9e, 0x1b9f, 
+    0x1ba0, 0x1ba1, 0x1ba2, 0x1ba3, 0x1ba4, 0x1ba5, 0x1ba6, 0x1ba7, 
+    0x1ba8, 0x1ba9, 0x1baa, 0x1bab, 0x1bac, 0x1bad, 0x1bae, 0x1baf, 
+    0x1bb0, 0x1bb1, 0x1bb2, 0x1bb3, 0x1bb4, 0x1bb5, 0x1bb6, 0x1bb7, 
+    0x1bb8, 0x1bb9, 0x1bba, 0x1bbb, 0x1bbc, 0x1bbd, 0x1bbe, 0x1bbf, 
+    0x1bc0, 0x1bc1, 0x1bc2, 0x1bc3, 0x1bc4, 0x1bc5, 0x1bc6, 0x1bc7, 
+    0x1bc8, 0x1bc9, 0x1bca, 0x1bcb, 0x1bcc, 0x1bcd, 0x1bce, 0x1bcf, 
+    0x1bd0, 0x1bd1, 0x1bd2, 0x1bd3, 0x1bd4, 0x1bd5, 0x1bd6, 0x1bd7, 
+    0x1bd8, 0x1bd9, 0x1bda, 0x1bdb, 0x1bdc, 0x1bdd, 0x1bde, 0x1bdf, 
+    0x1be0, 0x1be1, 0x1be2, 0x1be3, 0x1be4, 0x1be5, 0x1be6, 0x1be7, 
+    0x1be8, 0x1be9, 0x1bea, 0x1beb, 0x1bec, 0x1bed, 0x1bee, 0x1bef, 
+    0x1bf0, 0x1bf1, 0x1bf2, 0x1bf3, 0x1bf4, 0x1bf5, 0x1bf6, 0x1bf7, 
+    0x1bf8, 0x1bf9, 0x1bfa, 0x1bfb, 0x1bfc, 0x1bfd, 0x1bfe, 0x1bff, 
+    0x1c00, 0x1c01, 0x1c02, 0x1c03, 0x1c04, 0x1c05, 0x1c06, 0x1c07, 
+    0x1c08, 0x1c09, 0x1c0a, 0x1c0b, 0x1c0c, 0x1c0d, 0x1c0e, 0x1c0f, 
+    0x1c10, 0x1c11, 0x1c12, 0x1c13, 0x1c14, 0x1c15, 0x1c16, 0x1c17, 
+    0x1c18, 0x1c19, 0x1c1a, 0x1c1b, 0x1c1c, 0x1c1d, 0x1c1e, 0x1c1f, 
+    0x1c20, 0x1c21, 0x1c22, 0x1c23, 0x1c24, 0x1c25, 0x1c26, 0x1c27, 
+    0x1c28, 0x1c29, 0x1c2a, 0x1c2b, 0x1c2c, 0x1c2d, 0x1c2e, 0x1c2f, 
+    0x1c30, 0x1c31, 0x1c32, 0x1c33, 0x1c34, 0x1c35, 0x1c36, 0x1c37, 
+    0x1c38, 0x1c39, 0x1c3a, 0x1c3b, 0x1c3c, 0x1c3d, 0x1c3e, 0x1c3f, 
+    0x1c40, 0x1c41, 0x1c42, 0x1c43, 0x1c44, 0x1c45, 0x1c46, 0x1c47, 
+    0x1c48, 0x1c49, 0x1c4a, 0x1c4b, 0x1c4c, 0x1c4d, 0x1c4e, 0x1c4f, 
+    0x1c50, 0x1c51, 0x1c52, 0x1c53, 0x1c54, 0x1c55, 0x1c56, 0x1c57, 
+    0x1c58, 0x1c59, 0x1c5a, 0x1c5b, 0x1c5c, 0x1c5d, 0x1c5e, 0x1c5f, 
+    0x1c60, 0x1c61, 0x1c62, 0x1c63, 0x1c64, 0x1c65, 0x1c66, 0x1c67, 
+    0x1c68, 0x1c69, 0x1c6a, 0x1c6b, 0x1c6c, 0x1c6d, 0x1c6e, 0x1c6f, 
+    0x1c70, 0x1c71, 0x1c72, 0x1c73, 0x1c74, 0x1c75, 0x1c76, 0x1c77, 
+    0x1c78, 0x1c79, 0x1c7a, 0x1c7b, 0x1c7c, 0x1c7d, 0x1c7e, 0x1c7f, 
+    0x1c80, 0x1c81, 0x1c82, 0x1c83, 0x1c84, 0x1c85, 0x1c86, 0x1c87, 
+    0x1c88, 0x1c89, 0x1c8a, 0x1c8b, 0x1c8c, 0x1c8d, 0x1c8e, 0x1c8f, 
+    0x1c90, 0x1c91, 0x1c92, 0x1c93, 0x1c94, 0x1c95, 0x1c96, 0x1c97, 
+    0x1c98, 0x1c99, 0x1c9a, 0x1c9b, 0x1c9c, 0x1c9d, 0x1c9e, 0x1c9f, 
+    0x1ca0, 0x1ca1, 0x1ca2, 0x1ca3, 0x1ca4, 0x1ca5, 0x1ca6, 0x1ca7, 
+    0x1ca8, 0x1ca9, 0x1caa, 0x1cab, 0x1cac, 0x1cad, 0x1cae, 0x1caf, 
+    0x1cb0, 0x1cb1, 0x1cb2, 0x1cb3, 0x1cb4, 0x1cb5, 0x1cb6, 0x1cb7, 
+    0x1cb8, 0x1cb9, 0x1cba, 0x1cbb, 0x1cbc, 0x1cbd, 0x1cbe, 0x1cbf, 
+    0x1cc0, 0x1cc1, 0x1cc2, 0x1cc3, 0x1cc4, 0x1cc5, 0x1cc6, 0x1cc7, 
+    0x1cc8, 0x1cc9, 0x1cca, 0x1ccb, 0x1ccc, 0x1ccd, 0x1cce, 0x1ccf, 
+    0x1cd0, 0x1cd1, 0x1cd2, 0x1cd3, 0x1cd4, 0x1cd5, 0x1cd6, 0x1cd7, 
+    0x1cd8, 0x1cd9, 0x1cda, 0x1cdb, 0x1cdc, 0x1cdd, 0x1cde, 0x1cdf, 
+    0x1ce0, 0x1ce1, 0x1ce2, 0x1ce3, 0x1ce4, 0x1ce5, 0x1ce6, 0x1ce7, 
+    0x1ce8, 0x1ce9, 0x1cea, 0x1ceb, 0x1cec, 0x1ced, 0x1cee, 0x1cef, 
+    0x1cf0, 0x1cf1, 0x1cf2, 0x1cf3, 0x1cf4, 0x1cf5, 0x1cf6, 0x1cf7, 
+    0x1cf8, 0x1cf9, 0x1cfa, 0x1cfb, 0x1cfc, 0x1cfd, 0x1cfe, 0x1cff, 
+    0x1d00, 0x1d01, 0x1d02, 0x1d03, 0x1d04, 0x1d05, 0x1d06, 0x1d07, 
+    0x1d08, 0x1d09, 0x1d0a, 0x1d0b, 0x1d0c, 0x1d0d, 0x1d0e, 0x1d0f, 
+    0x1d10, 0x1d11, 0x1d12, 0x1d13, 0x1d14, 0x1d15, 0x1d16, 0x1d17, 
+    0x1d18, 0x1d19, 0x1d1a, 0x1d1b, 0x1d1c, 0x1d1d, 0x1d1e, 0x1d1f, 
+    0x1d20, 0x1d21, 0x1d22, 0x1d23, 0x1d24, 0x1d25, 0x1d26, 0x1d27, 
+    0x1d28, 0x1d29, 0x1d2a, 0x1d2b, 0x1d2c, 0x1d2d, 0x1d2e, 0x1d2f, 
+    0x1d30, 0x1d31, 0x1d32, 0x1d33, 0x1d34, 0x1d35, 0x1d36, 0x1d37, 
+    0x1d38, 0x1d39, 0x1d3a, 0x1d3b, 0x1d3c, 0x1d3d, 0x1d3e, 0x1d3f, 
+    0x1d40, 0x1d41, 0x1d42, 0x1d43, 0x1d44, 0x1d45, 0x1d46, 0x1d47, 
+    0x1d48, 0x1d49, 0x1d4a, 0x1d4b, 0x1d4c, 0x1d4d, 0x1d4e, 0x1d4f, 
+    0x1d50, 0x1d51, 0x1d52, 0x1d53, 0x1d54, 0x1d55, 0x1d56, 0x1d57, 
+    0x1d58, 0x1d59, 0x1d5a, 0x1d5b, 0x1d5c, 0x1d5d, 0x1d5e, 0x1d5f, 
+    0x1d60, 0x1d61, 0x1d62, 0x1d63, 0x1d64, 0x1d65, 0x1d66, 0x1d67, 
+    0x1d68, 0x1d69, 0x1d6a, 0x1d6b, 0x1d6c, 0x1d6d, 0x1d6e, 0x1d6f, 
+    0x1d70, 0x1d71, 0x1d72, 0x1d73, 0x1d74, 0x1d75, 0x1d76, 0x1d77, 
+    0x1d78, 0x1d79, 0x1d7a, 0x1d7b, 0x1d7c, 0x1d7d, 0x1d7e, 0x1d7f, 
+    0x1d80, 0x1d81, 0x1d82, 0x1d83, 0x1d84, 0x1d85, 0x1d86, 0x1d87, 
+    0x1d88, 0x1d89, 0x1d8a, 0x1d8b, 0x1d8c, 0x1d8d, 0x1d8e, 0x1d8f, 
+    0x1d90, 0x1d91, 0x1d92, 0x1d93, 0x1d94, 0x1d95, 0x1d96, 0x1d97, 
+    0x1d98, 0x1d99, 0x1d9a, 0x1d9b, 0x1d9c, 0x1d9d, 0x1d9e, 0x1d9f, 
+    0x1da0, 0x1da1, 0x1da2, 0x1da3, 0x1da4, 0x1da5, 0x1da6, 0x1da7, 
+    0x1da8, 0x1da9, 0x1daa, 0x1dab, 0x1dac, 0x1dad, 0x1dae, 0x1daf, 
+    0x1db0, 0x1db1, 0x1db2, 0x1db3, 0x1db4, 0x1db5, 0x1db6, 0x1db7, 
+    0x1db8, 0x1db9, 0x1dba, 0x1dbb, 0x1dbc, 0x1dbd, 0x1dbe, 0x1dbf, 
+    0x1dc0, 0x1dc1, 0x1dc2, 0x1dc3, 0x1dc4, 0x1dc5, 0x1dc6, 0x1dc7, 
+    0x1dc8, 0x1dc9, 0x1dca, 0x1dcb, 0x1dcc, 0x1dcd, 0x1dce, 0x1dcf, 
+    0x1dd0, 0x1dd1, 0x1dd2, 0x1dd3, 0x1dd4, 0x1dd5, 0x1dd6, 0x1dd7, 
+    0x1dd8, 0x1dd9, 0x1dda, 0x1ddb, 0x1ddc, 0x1ddd, 0x1dde, 0x1ddf, 
+    0x1de0, 0x1de1, 0x1de2, 0x1de3, 0x1de4, 0x1de5, 0x1de6, 0x1de7, 
+    0x1de8, 0x1de9, 0x1dea, 0x1deb, 0x1dec, 0x1ded, 0x1dee, 0x1def, 
+    0x1df0, 0x1df1, 0x1df2, 0x1df3, 0x1df4, 0x1df5, 0x1df6, 0x1df7, 
+    0x1df8, 0x1df9, 0x1dfa, 0x1dfb, 0x1dfc, 0x1dfd, 0x1dfe, 0x1dff, 
+    0x1e00, 0x1e01, 0x1e02, 0x1e03, 0x1e04, 0x1e05, 0x1e06, 0x1e07, 
+    0x1e08, 0x1e09, 0x1e0a, 0x1e0b, 0x1e0c, 0x1e0d, 0x1e0e, 0x1e0f, 
+    0x1e10, 0x1e11, 0x1e12, 0x1e13, 0x1e14, 0x1e15, 0x1e16, 0x1e17, 
+    0x1e18, 0x1e19, 0x1e1a, 0x1e1b, 0x1e1c, 0x1e1d, 0x1e1e, 0x1e1f, 
+    0x1e20, 0x1e21, 0x1e22, 0x1e23, 0x1e24, 0x1e25, 0x1e26, 0x1e27, 
+    0x1e28, 0x1e29, 0x1e2a, 0x1e2b, 0x1e2c, 0x1e2d, 0x1e2e, 0x1e2f, 
+    0x1e30, 0x1e31, 0x1e32, 0x1e33, 0x1e34, 0x1e35, 0x1e36, 0x1e37, 
+    0x1e38, 0x1e39, 0x1e3a, 0x1e3b, 0x1e3c, 0x1e3d, 0x1e3e, 0x1e3f, 
+    0x1e40, 0x1e41, 0x1e42, 0x1e43, 0x1e44, 0x1e45, 0x1e46, 0x1e47, 
+    0x1e48, 0x1e49, 0x1e4a, 0x1e4b, 0x1e4c, 0x1e4d, 0x1e4e, 0x1e4f, 
+    0x1e50, 0x1e51, 0x1e52, 0x1e53, 0x1e54, 0x1e55, 0x1e56, 0x1e57, 
+    0x1e58, 0x1e59, 0x1e5a, 0x1e5b, 0x1e5c, 0x1e5d, 0x1e5e, 0x1e5f, 
+    0x1e60, 0x1e61, 0x1e62, 0x1e63, 0x1e64, 0x1e65, 0x1e66, 0x1e67, 
+    0x1e68, 0x1e69, 0x1e6a, 0x1e6b, 0x1e6c, 0x1e6d, 0x1e6e, 0x1e6f, 
+    0x1e70, 0x1e71, 0x1e72, 0x1e73, 0x1e74, 0x1e75, 0x1e76, 0x1e77, 
+    0x1e78, 0x1e79, 0x1e7a, 0x1e7b, 0x1e7c, 0x1e7d, 0x1e7e, 0x1e7f, 
+    0x1e80, 0x1e81, 0x1e82, 0x1e83, 0x1e84, 0x1e85, 0x1e86, 0x1e87, 
+    0x1e88, 0x1e89, 0x1e8a, 0x1e8b, 0x1e8c, 0x1e8d, 0x1e8e, 0x1e8f, 
+    0x1e90, 0x1e91, 0x1e92, 0x1e93, 0x1e94, 0x1e95, 0x1e96, 0x1e97, 
+    0x1e98, 0x1e99, 0x1e9a, 0x1e9b, 0x1e9c, 0x1e9d, 0x1e9e, 0x1e9f, 
+    0x1ea0, 0x1ea1, 0x1ea2, 0x1ea3, 0x1ea4, 0x1ea5, 0x1ea6, 0x1ea7, 
+    0x1ea8, 0x1ea9, 0x1eaa, 0x1eab, 0x1eac, 0x1ead, 0x1eae, 0x1eaf, 
+    0x1eb0, 0x1eb1, 0x1eb2, 0x1eb3, 0x1eb4, 0x1eb5, 0x1eb6, 0x1eb7, 
+    0x1eb8, 0x1eb9, 0x1eba, 0x1ebb, 0x1ebc, 0x1ebd, 0x1ebe, 0x1ebf, 
+    0x1ec0, 0x1ec1, 0x1ec2, 0x1ec3, 0x1ec4, 0x1ec5, 0x1ec6, 0x1ec7, 
+    0x1ec8, 0x1ec9, 0x1eca, 0x1ecb, 0x1ecc, 0x1ecd, 0x1ece, 0x1ecf, 
+    0x1ed0, 0x1ed1, 0x1ed2, 0x1ed3, 0x1ed4, 0x1ed5, 0x1ed6, 0x1ed7, 
+    0x1ed8, 0x1ed9, 0x1eda, 0x1edb, 0x1edc, 0x1edd, 0x1ede, 0x1edf, 
+    0x1ee0, 0x1ee1, 0x1ee2, 0x1ee3, 0x1ee4, 0x1ee5, 0x1ee6, 0x1ee7, 
+    0x1ee8, 0x1ee9, 0x1eea, 0x1eeb, 0x1eec, 0x1eed, 0x1eee, 0x1eef, 
+    0x1ef0, 0x1ef1, 0x1ef2, 0x1ef3, 0x1ef4, 0x1ef5, 0x1ef6, 0x1ef7, 
+    0x1ef8, 0x1ef9, 0x1efa, 0x1efb, 0x1efc, 0x1efd, 0x1efe, 0x1eff, 
+    0x1f00, 0x1f01, 0x1f02, 0x1f03, 0x1f04, 0x1f05, 0x1f06, 0x1f07, 
+    0x1f08, 0x1f09, 0x1f0a, 0x1f0b, 0x1f0c, 0x1f0d, 0x1f0e, 0x1f0f, 
+    0x1f10, 0x1f11, 0x1f12, 0x1f13, 0x1f14, 0x1f15, 0x1f16, 0x1f17, 
+    0x1f18, 0x1f19, 0x1f1a, 0x1f1b, 0x1f1c, 0x1f1d, 0x1f1e, 0x1f1f, 
+    0x1f20, 0x1f21, 0x1f22, 0x1f23, 0x1f24, 0x1f25, 0x1f26, 0x1f27, 
+    0x1f28, 0x1f29, 0x1f2a, 0x1f2b, 0x1f2c, 0x1f2d, 0x1f2e, 0x1f2f, 
+    0x1f30, 0x1f31, 0x1f32, 0x1f33, 0x1f34, 0x1f35, 0x1f36, 0x1f37, 
+    0x1f38, 0x1f39, 0x1f3a, 0x1f3b, 0x1f3c, 0x1f3d, 0x1f3e, 0x1f3f, 
+    0x1f40, 0x1f41, 0x1f42, 0x1f43, 0x1f44, 0x1f45, 0x1f46, 0x1f47, 
+    0x1f48, 0x1f49, 0x1f4a, 0x1f4b, 0x1f4c, 0x1f4d, 0x1f4e, 0x1f4f, 
+    0x1f50, 0x1f51, 0x1f52, 0x1f53, 0x1f54, 0x1f55, 0x1f56, 0x1f57, 
+    0x1f58, 0x1f59, 0x1f5a, 0x1f5b, 0x1f5c, 0x1f5d, 0x1f5e, 0x1f5f, 
+    0x1f60, 0x1f61, 0x1f62, 0x1f63, 0x1f64, 0x1f65, 0x1f66, 0x1f67, 
+    0x1f68, 0x1f69, 0x1f6a, 0x1f6b, 0x1f6c, 0x1f6d, 0x1f6e, 0x1f6f, 
+    0x1f70, 0x1f71, 0x1f72, 0x1f73, 0x1f74, 0x1f75, 0x1f76, 0x1f77, 
+    0x1f78, 0x1f79, 0x1f7a, 0x1f7b, 0x1f7c, 0x1f7d, 0x1f7e, 0x1f7f, 
+    0x1f80, 0x1f81, 0x1f82, 0x1f83, 0x1f84, 0x1f85, 0x1f86, 0x1f87, 
+    0x1f88, 0x1f89, 0x1f8a, 0x1f8b, 0x1f8c, 0x1f8d, 0x1f8e, 0x1f8f, 
+    0x1f90, 0x1f91, 0x1f92, 0x1f93, 0x1f94, 0x1f95, 0x1f96, 0x1f97, 
+    0x1f98, 0x1f99, 0x1f9a, 0x1f9b, 0x1f9c, 0x1f9d, 0x1f9e, 0x1f9f, 
+    0x1fa0, 0x1fa1, 0x1fa2, 0x1fa3, 0x1fa4, 0x1fa5, 0x1fa6, 0x1fa7, 
+    0x1fa8, 0x1fa9, 0x1faa, 0x1fab, 0x1fac, 0x1fad, 0x1fae, 0x1faf, 
+    0x1fb0, 0x1fb1, 0x1fb2, 0x1fb3, 0x1fb4, 0x1fb5, 0x1fb6, 0x1fb7, 
+    0x1fb8, 0x1fb9, 0x1fba, 0x1fbb, 0x1fbc, 0x1fbd, 0x1fbe, 0x1fbf, 
+    0x1fc0, 0x1fc1, 0x1fc2, 0x1fc3, 0x1fc4, 0x1fc5, 0x1fc6, 0x1fc7, 
+    0x1fc8, 0x1fc9, 0x1fca, 0x1fcb, 0x1fcc, 0x1fcd, 0x1fce, 0x1fcf, 
+    0x1fd0, 0x1fd1, 0x1fd2, 0x1fd3, 0x1fd4, 0x1fd5, 0x1fd6, 0x1fd7, 
+    0x1fd8, 0x1fd9, 0x1fda, 0x1fdb, 0x1fdc, 0x1fdd, 0x1fde, 0x1fdf, 
+    0x1fe0, 0x1fe1, 0x1fe2, 0x1fe3, 0x1fe4, 0x1fe5, 0x1fe6, 0x1fe7, 
+    0x1fe8, 0x1fe9, 0x1fea, 0x1feb, 0x1fec, 0x1fed, 0x1fee, 0x1fef, 
+    0x1ff0, 0x1ff1, 0x1ff2, 0x1ff3, 0x1ff4, 0x1ff5, 0x1ff6, 0x1ff7, 
+    0x1ff8, 0x1ff9, 0x1ffa, 0x1ffb, 0x1ffc, 0x1ffd, 0x1ffe, 0x1fff, 
+    0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 
+    0x2008, 0x2009, 0x200a, 0x200b, 0x200c, 0x200d, 0x200e, 0x200f, 
+    0x2010, 0x2011, 0x2012, 0x2013, 0x2014, 0x2015, 0x2016, 0x2017, 
+    0x2018, 0x2019, 0x201a, 0x201b, 0x201c, 0x201d, 0x201e, 0x201f, 
+    0x2020, 0x2021, 0x2022, 0x2023, 0x2024, 0x2025, 0x2026, 0x2027, 
+    0x2028, 0x2029, 0x202a, 0x202b, 0x202c, 0x202d, 0x202e, 0x202f, 
+    0x2030, 0x2031, 0x2032, 0x2033, 0x2034, 0x2035, 0x2036, 0x2037, 
+    0x2038, 0x2039, 0x203a, 0x203b, 0x203c, 0x203d, 0x203e, 0x203f, 
+    0x2040, 0x2041, 0x2042, 0x2043, 0x2044, 0x2045, 0x2046, 0x2047, 
+    0x2048, 0x2049, 0x204a, 0x204b, 0x204c, 0x204d, 0x204e, 0x204f, 
+    0x2050, 0x2051, 0x2052, 0x2053, 0x2054, 0x2055, 0x2056, 0x2057, 
+    0x2058, 0x2059, 0x205a, 0x205b, 0x205c, 0x205d, 0x205e, 0x205f, 
+    0x2060, 0x2061, 0x2062, 0x2063, 0x2064, 0x2065, 0x2066, 0x2067, 
+    0x2068, 0x2069, 0x206a, 0x206b, 0x206c, 0x206d, 0x206e, 0x206f, 
+    0x2070, 0x2071, 0x2072, 0x2073, 0x2074, 0x2075, 0x2076, 0x2077, 
+    0x2078, 0x2079, 0x207a, 0x207b, 0x207c, 0x207d, 0x207e, 0x207f, 
+    0x2080, 0x2081, 0x2082, 0x2083, 0x2084, 0x2085, 0x2086, 0x2087, 
+    0x2088, 0x2089, 0x208a, 0x208b, 0x208c, 0x208d, 0x208e, 0x208f, 
+    0x2090, 0x2091, 0x2092, 0x2093, 0x2094, 0x2095, 0x2096, 0x2097, 
+    0x2098, 0x2099, 0x209a, 0x209b, 0x209c, 0x209d, 0x209e, 0x209f, 
+    0x20a0, 0x20a1, 0x20a2, 0x20a3, 0x20a4, 0x20a5, 0x20a6, 0x20a7, 
+    0x20a8, 0x20a9, 0x20aa, 0x20ab, 0x20ac, 0x20ad, 0x20ae, 0x20af, 
+    0x20b0, 0x20b1, 0x20b2, 0x20b3, 0x20b4, 0x20b5, 0x20b6, 0x20b7, 
+    0x20b8, 0x20b9, 0x20ba, 0x20bb, 0x20bc, 0x20bd, 0x20be, 0x20bf, 
+    0x20c0, 0x20c1, 0x20c2, 0x20c3, 0x20c4, 0x20c5, 0x20c6, 0x20c7, 
+    0x20c8, 0x20c9, 0x20ca, 0x20cb, 0x20cc, 0x20cd, 0x20ce, 0x20cf, 
+    0x20d0, 0x20d1, 0x20d2, 0x20d3, 0x20d4, 0x20d5, 0x20d6, 0x20d7, 
+    0x20d8, 0x20d9, 0x20da, 0x20db, 0x20dc, 0x20dd, 0x20de, 0x20df, 
+    0x20e0, 0x20e1, 0x20e2, 0x20e3, 0x20e4, 0x20e5, 0x20e6, 0x20e7, 
+    0x20e8, 0x20e9, 0x20ea, 0x20eb, 0x20ec, 0x20ed, 0x20ee, 0x20ef, 
+    0x20f0, 0x20f1, 0x20f2, 0x20f3, 0x20f4, 0x20f5, 0x20f6, 0x20f7, 
+    0x20f8, 0x20f9, 0x20fa, 0x20fb, 0x20fc, 0x20fd, 0x20fe, 0x20ff, 
+    0x2100, 0x2101, 0x2102, 0x2103, 0x2104, 0x2105, 0x2106, 0x2107, 
+    0x2108, 0x2109, 0x210a, 0x210b, 0x210c, 0x210d, 0x210e, 0x210f, 
+    0x2110, 0x2111, 0x2112, 0x2113, 0x2114, 0x2115, 0x2116, 0x2117, 
+    0x2118, 0x2119, 0x211a, 0x211b, 0x211c, 0x211d, 0x211e, 0x211f, 
+    0x2120, 0x2121, 0x2122, 0x2123, 0x2124, 0x2125, 0x2126, 0x2127, 
+    0x2128, 0x2129, 0x212a, 0x212b, 0x212c, 0x212d, 0x212e, 0x212f, 
+    0x2130, 0x2131, 0x2132, 0x2133, 0x2134, 0x2135, 0x2136, 0x2137, 
+    0x2138, 0x2139, 0x213a, 0x213b, 0x213c, 0x213d, 0x213e, 0x213f, 
+    0x2140, 0x2141, 0x2142, 0x2143, 0x2144, 0x2145, 0x2146, 0x2147, 
+    0x2148, 0x2149, 0x214a, 0x214b, 0x214c, 0x214d, 0x214e, 0x214f, 
+    0x2150, 0x2151, 0x2152, 0x2153, 0x2154, 0x2155, 0x2156, 0x2157, 
+    0x2158, 0x2159, 0x215a, 0x215b, 0x215c, 0x215d, 0x215e, 0x215f, 
+    0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 
+    0x2168, 0x2169, 0x216a, 0x216b, 0x216c, 0x216d, 0x216e, 0x216f, 
+    0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 
+    0x2178, 0x2179, 0x217a, 0x217b, 0x217c, 0x217d, 0x217e, 0x217f, 
+    0x2180, 0x2181, 0x2182, 0x2183, 0x2184, 0x2185, 0x2186, 0x2187, 
+    0x2188, 0x2189, 0x218a, 0x218b, 0x218c, 0x218d, 0x218e, 0x218f, 
+    0x2190, 0x2191, 0x2192, 0x2193, 0x2194, 0x2195, 0x2196, 0x2197, 
+    0x2198, 0x2199, 0x219a, 0x219b, 0x219c, 0x219d, 0x219e, 0x219f, 
+    0x21a0, 0x21a1, 0x21a2, 0x21a3, 0x21a4, 0x21a5, 0x21a6, 0x21a7, 
+    0x21a8, 0x21a9, 0x21aa, 0x21ab, 0x21ac, 0x21ad, 0x21ae, 0x21af, 
+    0x21b0, 0x21b1, 0x21b2, 0x21b3, 0x21b4, 0x21b5, 0x21b6, 0x21b7, 
+    0x21b8, 0x21b9, 0x21ba, 0x21bb, 0x21bc, 0x21bd, 0x21be, 0x21bf, 
+    0x21c0, 0x21c1, 0x21c2, 0x21c3, 0x21c4, 0x21c5, 0x21c6, 0x21c7, 
+    0x21c8, 0x21c9, 0x21ca, 0x21cb, 0x21cc, 0x21cd, 0x21ce, 0x21cf, 
+    0x21d0, 0x21d1, 0x21d2, 0x21d3, 0x21d4, 0x21d5, 0x21d6, 0x21d7, 
+    0x21d8, 0x21d9, 0x21da, 0x21db, 0x21dc, 0x21dd, 0x21de, 0x21df, 
+    0x21e0, 0x21e1, 0x21e2, 0x21e3, 0x21e4, 0x21e5, 0x21e6, 0x21e7, 
+    0x21e8, 0x21e9, 0x21ea, 0x21eb, 0x21ec, 0x21ed, 0x21ee, 0x21ef, 
+    0x21f0, 0x21f1, 0x21f2, 0x21f3, 0x21f4, 0x21f5, 0x21f6, 0x21f7, 
+    0x21f8, 0x21f9, 0x21fa, 0x21fb, 0x21fc, 0x21fd, 0x21fe, 0x21ff, 
+    0x2200, 0x2201, 0x2202, 0x2203, 0x2204, 0x2205, 0x2206, 0x2207, 
+    0x2208, 0x2209, 0x220a, 0x220b, 0x220c, 0x220d, 0x220e, 0x220f, 
+    0x2210, 0x2211, 0x2212, 0x2213, 0x2214, 0x2215, 0x2216, 0x2217, 
+    0x2218, 0x2219, 0x221a, 0x221b, 0x221c, 0x221d, 0x221e, 0x221f, 
+    0x2220, 0x2221, 0x2222, 0x2223, 0x2224, 0x2225, 0x2226, 0x2227, 
+    0x2228, 0x2229, 0x222a, 0x222b, 0x222c, 0x222d, 0x222e, 0x222f, 
+    0x2230, 0x2231, 0x2232, 0x2233, 0x2234, 0x2235, 0x2236, 0x2237, 
+    0x2238, 0x2239, 0x223a, 0x223b, 0x223c, 0x223d, 0x223e, 0x223f, 
+    0x2240, 0x2241, 0x2242, 0x2243, 0x2244, 0x2245, 0x2246, 0x2247, 
+    0x2248, 0x2249, 0x224a, 0x224b, 0x224c, 0x224d, 0x224e, 0x224f, 
+    0x2250, 0x2251, 0x2252, 0x2253, 0x2254, 0x2255, 0x2256, 0x2257, 
+    0x2258, 0x2259, 0x225a, 0x225b, 0x225c, 0x225d, 0x225e, 0x225f, 
+    0x2260, 0x2261, 0x2262, 0x2263, 0x2264, 0x2265, 0x2266, 0x2267, 
+    0x2268, 0x2269, 0x226a, 0x226b, 0x226c, 0x226d, 0x226e, 0x226f, 
+    0x2270, 0x2271, 0x2272, 0x2273, 0x2274, 0x2275, 0x2276, 0x2277, 
+    0x2278, 0x2279, 0x227a, 0x227b, 0x227c, 0x227d, 0x227e, 0x227f, 
+    0x2280, 0x2281, 0x2282, 0x2283, 0x2284, 0x2285, 0x2286, 0x2287, 
+    0x2288, 0x2289, 0x228a, 0x228b, 0x228c, 0x228d, 0x228e, 0x228f, 
+    0x2290, 0x2291, 0x2292, 0x2293, 0x2294, 0x2295, 0x2296, 0x2297, 
+    0x2298, 0x2299, 0x229a, 0x229b, 0x229c, 0x229d, 0x229e, 0x229f, 
+    0x22a0, 0x22a1, 0x22a2, 0x22a3, 0x22a4, 0x22a5, 0x22a6, 0x22a7, 
+    0x22a8, 0x22a9, 0x22aa, 0x22ab, 0x22ac, 0x22ad, 0x22ae, 0x22af, 
+    0x22b0, 0x22b1, 0x22b2, 0x22b3, 0x22b4, 0x22b5, 0x22b6, 0x22b7, 
+    0x22b8, 0x22b9, 0x22ba, 0x22bb, 0x22bc, 0x22bd, 0x22be, 0x22bf, 
+    0x22c0, 0x22c1, 0x22c2, 0x22c3, 0x22c4, 0x22c5, 0x22c6, 0x22c7, 
+    0x22c8, 0x22c9, 0x22ca, 0x22cb, 0x22cc, 0x22cd, 0x22ce, 0x22cf, 
+    0x22d0, 0x22d1, 0x22d2, 0x22d3, 0x22d4, 0x22d5, 0x22d6, 0x22d7, 
+    0x22d8, 0x22d9, 0x22da, 0x22db, 0x22dc, 0x22dd, 0x22de, 0x22df, 
+    0x22e0, 0x22e1, 0x22e2, 0x22e3, 0x22e4, 0x22e5, 0x22e6, 0x22e7, 
+    0x22e8, 0x22e9, 0x22ea, 0x22eb, 0x22ec, 0x22ed, 0x22ee, 0x22ef, 
+    0x22f0, 0x22f1, 0x22f2, 0x22f3, 0x22f4, 0x22f5, 0x22f6, 0x22f7, 
+    0x22f8, 0x22f9, 0x22fa, 0x22fb, 0x22fc, 0x22fd, 0x22fe, 0x22ff, 
+    0x2300, 0x2301, 0x2302, 0x2303, 0x2304, 0x2305, 0x2306, 0x2307, 
+    0x2308, 0x2309, 0x230a, 0x230b, 0x230c, 0x230d, 0x230e, 0x230f, 
+    0x2310, 0x2311, 0x2312, 0x2313, 0x2314, 0x2315, 0x2316, 0x2317, 
+    0x2318, 0x2319, 0x231a, 0x231b, 0x231c, 0x231d, 0x231e, 0x231f, 
+    0x2320, 0x2321, 0x2322, 0x2323, 0x2324, 0x2325, 0x2326, 0x2327, 
+    0x2328, 0x2329, 0x232a, 0x232b, 0x232c, 0x232d, 0x232e, 0x232f, 
+    0x2330, 0x2331, 0x2332, 0x2333, 0x2334, 0x2335, 0x2336, 0x2337, 
+    0x2338, 0x2339, 0x233a, 0x233b, 0x233c, 0x233d, 0x233e, 0x233f, 
+    0x2340, 0x2341, 0x2342, 0x2343, 0x2344, 0x2345, 0x2346, 0x2347, 
+    0x2348, 0x2349, 0x234a, 0x234b, 0x234c, 0x234d, 0x234e, 0x234f, 
+    0x2350, 0x2351, 0x2352, 0x2353, 0x2354, 0x2355, 0x2356, 0x2357, 
+    0x2358, 0x2359, 0x235a, 0x235b, 0x235c, 0x235d, 0x235e, 0x235f, 
+    0x2360, 0x2361, 0x2362, 0x2363, 0x2364, 0x2365, 0x2366, 0x2367, 
+    0x2368, 0x2369, 0x236a, 0x236b, 0x236c, 0x236d, 0x236e, 0x236f, 
+    0x2370, 0x2371, 0x2372, 0x2373, 0x2374, 0x2375, 0x2376, 0x2377, 
+    0x2378, 0x2379, 0x237a, 0x237b, 0x237c, 0x237d, 0x237e, 0x237f, 
+    0x2380, 0x2381, 0x2382, 0x2383, 0x2384, 0x2385, 0x2386, 0x2387, 
+    0x2388, 0x2389, 0x238a, 0x238b, 0x238c, 0x238d, 0x238e, 0x238f, 
+    0x2390, 0x2391, 0x2392, 0x2393, 0x2394, 0x2395, 0x2396, 0x2397, 
+    0x2398, 0x2399, 0x239a, 0x239b, 0x239c, 0x239d, 0x239e, 0x239f, 
+    0x23a0, 0x23a1, 0x23a2, 0x23a3, 0x23a4, 0x23a5, 0x23a6, 0x23a7, 
+    0x23a8, 0x23a9, 0x23aa, 0x23ab, 0x23ac, 0x23ad, 0x23ae, 0x23af, 
+    0x23b0, 0x23b1, 0x23b2, 0x23b3, 0x23b4, 0x23b5, 0x23b6, 0x23b7, 
+    0x23b8, 0x23b9, 0x23ba, 0x23bb, 0x23bc, 0x23bd, 0x23be, 0x23bf, 
+    0x23c0, 0x23c1, 0x23c2, 0x23c3, 0x23c4, 0x23c5, 0x23c6, 0x23c7, 
+    0x23c8, 0x23c9, 0x23ca, 0x23cb, 0x23cc, 0x23cd, 0x23ce, 0x23cf, 
+    0x23d0, 0x23d1, 0x23d2, 0x23d3, 0x23d4, 0x23d5, 0x23d6, 0x23d7, 
+    0x23d8, 0x23d9, 0x23da, 0x23db, 0x23dc, 0x23dd, 0x23de, 0x23df, 
+    0x23e0, 0x23e1, 0x23e2, 0x23e3, 0x23e4, 0x23e5, 0x23e6, 0x23e7, 
+    0x23e8, 0x23e9, 0x23ea, 0x23eb, 0x23ec, 0x23ed, 0x23ee, 0x23ef, 
+    0x23f0, 0x23f1, 0x23f2, 0x23f3, 0x23f4, 0x23f5, 0x23f6, 0x23f7, 
+    0x23f8, 0x23f9, 0x23fa, 0x23fb, 0x23fc, 0x23fd, 0x23fe, 0x23ff, 
+    0x2400, 0x2401, 0x2402, 0x2403, 0x2404, 0x2405, 0x2406, 0x2407, 
+    0x2408, 0x2409, 0x240a, 0x240b, 0x240c, 0x240d, 0x240e, 0x240f, 
+    0x2410, 0x2411, 0x2412, 0x2413, 0x2414, 0x2415, 0x2416, 0x2417, 
+    0x2418, 0x2419, 0x241a, 0x241b, 0x241c, 0x241d, 0x241e, 0x241f, 
+    0x2420, 0x2421, 0x2422, 0x2423, 0x2424, 0x2425, 0x2426, 0x2427, 
+    0x2428, 0x2429, 0x242a, 0x242b, 0x242c, 0x242d, 0x242e, 0x242f, 
+    0x2430, 0x2431, 0x2432, 0x2433, 0x2434, 0x2435, 0x2436, 0x2437, 
+    0x2438, 0x2439, 0x243a, 0x243b, 0x243c, 0x243d, 0x243e, 0x243f, 
+    0x2440, 0x2441, 0x2442, 0x2443, 0x2444, 0x2445, 0x2446, 0x2447, 
+    0x2448, 0x2449, 0x244a, 0x244b, 0x244c, 0x244d, 0x244e, 0x244f, 
+    0x2450, 0x2451, 0x2452, 0x2453, 0x2454, 0x2455, 0x2456, 0x2457, 
+    0x2458, 0x2459, 0x245a, 0x245b, 0x245c, 0x245d, 0x245e, 0x245f, 
+    0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, 0x2467, 
+    0x2468, 0x2469, 0x246a, 0x246b, 0x246c, 0x246d, 0x246e, 0x246f, 
+    0x2470, 0x2471, 0x2472, 0x2473, 0x2474, 0x2475, 0x2476, 0x2477, 
+    0x2478, 0x2479, 0x247a, 0x247b, 0x247c, 0x247d, 0x247e, 0x247f, 
+    0x2480, 0x2481, 0x2482, 0x2483, 0x2484, 0x2485, 0x2486, 0x2487, 
+    0x2488, 0x2489, 0x248a, 0x248b, 0x248c, 0x248d, 0x248e, 0x248f, 
+    0x2490, 0x2491, 0x2492, 0x2493, 0x2494, 0x2495, 0x2496, 0x2497, 
+    0x2498, 0x2499, 0x249a, 0x249b, 0x249c, 0x249d, 0x249e, 0x249f, 
+    0x24a0, 0x24a1, 0x24a2, 0x24a3, 0x24a4, 0x24a5, 0x24a6, 0x24a7, 
+    0x24a8, 0x24a9, 0x24aa, 0x24ab, 0x24ac, 0x24ad, 0x24ae, 0x24af, 
+    0x24b0, 0x24b1, 0x24b2, 0x24b3, 0x24b4, 0x24b5, 0x24b6, 0x24b7, 
+    0x24b8, 0x24b9, 0x24ba, 0x24bb, 0x24bc, 0x24bd, 0x24be, 0x24bf, 
+    0x24c0, 0x24c1, 0x24c2, 0x24c3, 0x24c4, 0x24c5, 0x24c6, 0x24c7, 
+    0x24c8, 0x24c9, 0x24ca, 0x24cb, 0x24cc, 0x24cd, 0x24ce, 0x24cf, 
+    0x24d0, 0x24d1, 0x24d2, 0x24d3, 0x24d4, 0x24d5, 0x24d6, 0x24d7, 
+    0x24d8, 0x24d9, 0x24da, 0x24db, 0x24dc, 0x24dd, 0x24de, 0x24df, 
+    0x24e0, 0x24e1, 0x24e2, 0x24e3, 0x24e4, 0x24e5, 0x24e6, 0x24e7, 
+    0x24e8, 0x24e9, 0x24ea, 0x24eb, 0x24ec, 0x24ed, 0x24ee, 0x24ef, 
+    0x24f0, 0x24f1, 0x24f2, 0x24f3, 0x24f4, 0x24f5, 0x24f6, 0x24f7, 
+    0x24f8, 0x24f9, 0x24fa, 0x24fb, 0x24fc, 0x24fd, 0x24fe, 0x24ff, 
+    0x2500, 0x2501, 0x2502, 0x2503, 0x2504, 0x2505, 0x2506, 0x2507, 
+    0x2508, 0x2509, 0x250a, 0x250b, 0x250c, 0x250d, 0x250e, 0x250f, 
+    0x2510, 0x2511, 0x2512, 0x2513, 0x2514, 0x2515, 0x2516, 0x2517, 
+    0x2518, 0x2519, 0x251a, 0x251b, 0x251c, 0x251d, 0x251e, 0x251f, 
+    0x2520, 0x2521, 0x2522, 0x2523, 0x2524, 0x2525, 0x2526, 0x2527, 
+    0x2528, 0x2529, 0x252a, 0x252b, 0x252c, 0x252d, 0x252e, 0x252f, 
+    0x2530, 0x2531, 0x2532, 0x2533, 0x2534, 0x2535, 0x2536, 0x2537, 
+    0x2538, 0x2539, 0x253a, 0x253b, 0x253c, 0x253d, 0x253e, 0x253f, 
+    0x2540, 0x2541, 0x2542, 0x2543, 0x2544, 0x2545, 0x2546, 0x2547, 
+    0x2548, 0x2549, 0x254a, 0x254b, 0x254c, 0x254d, 0x254e, 0x254f, 
+    0x2550, 0x2551, 0x2552, 0x2553, 0x2554, 0x2555, 0x2556, 0x2557, 
+    0x2558, 0x2559, 0x255a, 0x255b, 0x255c, 0x255d, 0x255e, 0x255f, 
+    0x2560, 0x2561, 0x2562, 0x2563, 0x2564, 0x2565, 0x2566, 0x2567, 
+    0x2568, 0x2569, 0x256a, 0x256b, 0x256c, 0x256d, 0x256e, 0x256f, 
+    0x2570, 0x2571, 0x2572, 0x2573, 0x2574, 0x2575, 0x2576, 0x2577, 
+    0x2578, 0x2579, 0x257a, 0x257b, 0x257c, 0x257d, 0x257e, 0x257f, 
+    0x2580, 0x2581, 0x2582, 0x2583, 0x2584, 0x2585, 0x2586, 0x2587, 
+    0x2588, 0x2589, 0x258a, 0x258b, 0x258c, 0x258d, 0x258e, 0x258f, 
+    0x2590, 0x2591, 0x2592, 0x2593, 0x2594, 0x2595, 0x2596, 0x2597, 
+    0x2598, 0x2599, 0x259a, 0x259b, 0x259c, 0x259d, 0x259e, 0x259f, 
+    0x25a0, 0x25a1, 0x25a2, 0x25a3, 0x25a4, 0x25a5, 0x25a6, 0x25a7, 
+    0x25a8, 0x25a9, 0x25aa, 0x25ab, 0x25ac, 0x25ad, 0x25ae, 0x25af, 
+    0x25b0, 0x25b1, 0x25b2, 0x25b3, 0x25b4, 0x25b5, 0x25b6, 0x25b7, 
+    0x25b8, 0x25b9, 0x25ba, 0x25bb, 0x25bc, 0x25bd, 0x25be, 0x25bf, 
+    0x25c0, 0x25c1, 0x25c2, 0x25c3, 0x25c4, 0x25c5, 0x25c6, 0x25c7, 
+    0x25c8, 0x25c9, 0x25ca, 0x25cb, 0x25cc, 0x25cd, 0x25ce, 0x25cf, 
+    0x25d0, 0x25d1, 0x25d2, 0x25d3, 0x25d4, 0x25d5, 0x25d6, 0x25d7, 
+    0x25d8, 0x25d9, 0x25da, 0x25db, 0x25dc, 0x25dd, 0x25de, 0x25df, 
+    0x25e0, 0x25e1, 0x25e2, 0x25e3, 0x25e4, 0x25e5, 0x25e6, 0x25e7, 
+    0x25e8, 0x25e9, 0x25ea, 0x25eb, 0x25ec, 0x25ed, 0x25ee, 0x25ef, 
+    0x25f0, 0x25f1, 0x25f2, 0x25f3, 0x25f4, 0x25f5, 0x25f6, 0x25f7, 
+    0x25f8, 0x25f9, 0x25fa, 0x25fb, 0x25fc, 0x25fd, 0x25fe, 0x25ff, 
+    0x2600, 0x2601, 0x2602, 0x2603, 0x2604, 0x2605, 0x2606, 0x2607, 
+    0x2608, 0x2609, 0x260a, 0x260b, 0x260c, 0x260d, 0x260e, 0x260f, 
+    0x2610, 0x2611, 0x2612, 0x2613, 0x2614, 0x2615, 0x2616, 0x2617, 
+    0x2618, 0x2619, 0x261a, 0x261b, 0x261c, 0x261d, 0x261e, 0x261f, 
+    0x2620, 0x2621, 0x2622, 0x2623, 0x2624, 0x2625, 0x2626, 0x2627, 
+    0x2628, 0x2629, 0x262a, 0x262b, 0x262c, 0x262d, 0x262e, 0x262f, 
+    0x2630, 0x2631, 0x2632, 0x2633, 0x2634, 0x2635, 0x2636, 0x2637, 
+    0x2638, 0x2639, 0x263a, 0x263b, 0x263c, 0x263d, 0x263e, 0x263f, 
+    0x2640, 0x2641, 0x2642, 0x2643, 0x2644, 0x2645, 0x2646, 0x2647, 
+    0x2648, 0x2649, 0x264a, 0x264b, 0x264c, 0x264d, 0x264e, 0x264f, 
+    0x2650, 0x2651, 0x2652, 0x2653, 0x2654, 0x2655, 0x2656, 0x2657, 
+    0x2658, 0x2659, 0x265a, 0x265b, 0x265c, 0x265d, 0x265e, 0x265f, 
+    0x2660, 0x2661, 0x2662, 0x2663, 0x2664, 0x2665, 0x2666, 0x2667, 
+    0x2668, 0x2669, 0x266a, 0x266b, 0x266c, 0x266d, 0x266e, 0x266f, 
+    0x2670, 0x2671, 0x2672, 0x2673, 0x2674, 0x2675, 0x2676, 0x2677, 
+    0x2678, 0x2679, 0x267a, 0x267b, 0x267c, 0x267d, 0x267e, 0x267f, 
+    0x2680, 0x2681, 0x2682, 0x2683, 0x2684, 0x2685, 0x2686, 0x2687, 
+    0x2688, 0x2689, 0x268a, 0x268b, 0x268c, 0x268d, 0x268e, 0x268f, 
+    0x2690, 0x2691, 0x2692, 0x2693, 0x2694, 0x2695, 0x2696, 0x2697, 
+    0x2698, 0x2699, 0x269a, 0x269b, 0x269c, 0x269d, 0x269e, 0x269f, 
+    0x26a0, 0x26a1, 0x26a2, 0x26a3, 0x26a4, 0x26a5, 0x26a6, 0x26a7, 
+    0x26a8, 0x26a9, 0x26aa, 0x26ab, 0x26ac, 0x26ad, 0x26ae, 0x26af, 
+    0x26b0, 0x26b1, 0x26b2, 0x26b3, 0x26b4, 0x26b5, 0x26b6, 0x26b7, 
+    0x26b8, 0x26b9, 0x26ba, 0x26bb, 0x26bc, 0x26bd, 0x26be, 0x26bf, 
+    0x26c0, 0x26c1, 0x26c2, 0x26c3, 0x26c4, 0x26c5, 0x26c6, 0x26c7, 
+    0x26c8, 0x26c9, 0x26ca, 0x26cb, 0x26cc, 0x26cd, 0x26ce, 0x26cf, 
+    0x26d0, 0x26d1, 0x26d2, 0x26d3, 0x26d4, 0x26d5, 0x26d6, 0x26d7, 
+    0x26d8, 0x26d9, 0x26da, 0x26db, 0x26dc, 0x26dd, 0x26de, 0x26df, 
+    0x26e0, 0x26e1, 0x26e2, 0x26e3, 0x26e4, 0x26e5, 0x26e6, 0x26e7, 
+    0x26e8, 0x26e9, 0x26ea, 0x26eb, 0x26ec, 0x26ed, 0x26ee, 0x26ef, 
+    0x26f0, 0x26f1, 0x26f2, 0x26f3, 0x26f4, 0x26f5, 0x26f6, 0x26f7, 
+    0x26f8, 0x26f9, 0x26fa, 0x26fb, 0x26fc, 0x26fd, 0x26fe, 0x26ff, 
+    0x2700, 0x2701, 0x2702, 0x2703, 0x2704, 0x2705, 0x2706, 0x2707, 
+    0x2708, 0x2709, 0x270a, 0x270b, 0x270c, 0x270d, 0x270e, 0x270f, 
+    0x2710, 0x2711, 0x2712, 0x2713, 0x2714, 0x2715, 0x2716, 0x2717, 
+    0x2718, 0x2719, 0x271a, 0x271b, 0x271c, 0x271d, 0x271e, 0x271f, 
+    0x2720, 0x2721, 0x2722, 0x2723, 0x2724, 0x2725, 0x2726, 0x2727, 
+    0x2728, 0x2729, 0x272a, 0x272b, 0x272c, 0x272d, 0x272e, 0x272f, 
+    0x2730, 0x2731, 0x2732, 0x2733, 0x2734, 0x2735, 0x2736, 0x2737, 
+    0x2738, 0x2739, 0x273a, 0x273b, 0x273c, 0x273d, 0x273e, 0x273f, 
+    0x2740, 0x2741, 0x2742, 0x2743, 0x2744, 0x2745, 0x2746, 0x2747, 
+    0x2748, 0x2749, 0x274a, 0x274b, 0x274c, 0x274d, 0x274e, 0x274f, 
+    0x2750, 0x2751, 0x2752, 0x2753, 0x2754, 0x2755, 0x2756, 0x2757, 
+    0x2758, 0x2759, 0x275a, 0x275b, 0x275c, 0x275d, 0x275e, 0x275f, 
+    0x2760, 0x2761, 0x2762, 0x2763, 0x2764, 0x2765, 0x2766, 0x2767, 
+    0x2768, 0x2769, 0x276a, 0x276b, 0x276c, 0x276d, 0x276e, 0x276f, 
+    0x2770, 0x2771, 0x2772, 0x2773, 0x2774, 0x2775, 0x2776, 0x2777, 
+    0x2778, 0x2779, 0x277a, 0x277b, 0x277c, 0x277d, 0x277e, 0x277f, 
+    0x2780, 0x2781, 0x2782, 0x2783, 0x2784, 0x2785, 0x2786, 0x2787, 
+    0x2788, 0x2789, 0x278a, 0x278b, 0x278c, 0x278d, 0x278e, 0x278f, 
+    0x2790, 0x2791, 0x2792, 0x2793, 0x2794, 0x2795, 0x2796, 0x2797, 
+    0x2798, 0x2799, 0x279a, 0x279b, 0x279c, 0x279d, 0x279e, 0x279f, 
+    0x27a0, 0x27a1, 0x27a2, 0x27a3, 0x27a4, 0x27a5, 0x27a6, 0x27a7, 
+    0x27a8, 0x27a9, 0x27aa, 0x27ab, 0x27ac, 0x27ad, 0x27ae, 0x27af, 
+    0x27b0, 0x27b1, 0x27b2, 0x27b3, 0x27b4, 0x27b5, 0x27b6, 0x27b7, 
+    0x27b8, 0x27b9, 0x27ba, 0x27bb, 0x27bc, 0x27bd, 0x27be, 0x27bf, 
+    0x27c0, 0x27c1, 0x27c2, 0x27c3, 0x27c4, 0x27c5, 0x27c6, 0x27c7, 
+    0x27c8, 0x27c9, 0x27ca, 0x27cb, 0x27cc, 0x27cd, 0x27ce, 0x27cf, 
+    0x27d0, 0x27d1, 0x27d2, 0x27d3, 0x27d4, 0x27d5, 0x27d6, 0x27d7, 
+    0x27d8, 0x27d9, 0x27da, 0x27db, 0x27dc, 0x27dd, 0x27de, 0x27df, 
+    0x27e0, 0x27e1, 0x27e2, 0x27e3, 0x27e4, 0x27e5, 0x27e6, 0x27e7, 
+    0x27e8, 0x27e9, 0x27ea, 0x27eb, 0x27ec, 0x27ed, 0x27ee, 0x27ef, 
+    0x27f0, 0x27f1, 0x27f2, 0x27f3, 0x27f4, 0x27f5, 0x27f6, 0x27f7, 
+    0x27f8, 0x27f9, 0x27fa, 0x27fb, 0x27fc, 0x27fd, 0x27fe, 0x27ff, 
+    0x2800, 0x2801, 0x2802, 0x2803, 0x2804, 0x2805, 0x2806, 0x2807, 
+    0x2808, 0x2809, 0x280a, 0x280b, 0x280c, 0x280d, 0x280e, 0x280f, 
+    0x2810, 0x2811, 0x2812, 0x2813, 0x2814, 0x2815, 0x2816, 0x2817, 
+    0x2818, 0x2819, 0x281a, 0x281b, 0x281c, 0x281d, 0x281e, 0x281f, 
+    0x2820, 0x2821, 0x2822, 0x2823, 0x2824, 0x2825, 0x2826, 0x2827, 
+    0x2828, 0x2829, 0x282a, 0x282b, 0x282c, 0x282d, 0x282e, 0x282f, 
+    0x2830, 0x2831, 0x2832, 0x2833, 0x2834, 0x2835, 0x2836, 0x2837, 
+    0x2838, 0x2839, 0x283a, 0x283b, 0x283c, 0x283d, 0x283e, 0x283f, 
+    0x2840, 0x2841, 0x2842, 0x2843, 0x2844, 0x2845, 0x2846, 0x2847, 
+    0x2848, 0x2849, 0x284a, 0x284b, 0x284c, 0x284d, 0x284e, 0x284f, 
+    0x2850, 0x2851, 0x2852, 0x2853, 0x2854, 0x2855, 0x2856, 0x2857, 
+    0x2858, 0x2859, 0x285a, 0x285b, 0x285c, 0x285d, 0x285e, 0x285f, 
+    0x2860, 0x2861, 0x2862, 0x2863, 0x2864, 0x2865, 0x2866, 0x2867, 
+    0x2868, 0x2869, 0x286a, 0x286b, 0x286c, 0x286d, 0x286e, 0x286f, 
+    0x2870, 0x2871, 0x2872, 0x2873, 0x2874, 0x2875, 0x2876, 0x2877, 
+    0x2878, 0x2879, 0x287a, 0x287b, 0x287c, 0x287d, 0x287e, 0x287f, 
+    0x2880, 0x2881, 0x2882, 0x2883, 0x2884, 0x2885, 0x2886, 0x2887, 
+    0x2888, 0x2889, 0x288a, 0x288b, 0x288c, 0x288d, 0x288e, 0x288f, 
+    0x2890, 0x2891, 0x2892, 0x2893, 0x2894, 0x2895, 0x2896, 0x2897, 
+    0x2898, 0x2899, 0x289a, 0x289b, 0x289c, 0x289d, 0x289e, 0x289f, 
+    0x28a0, 0x28a1, 0x28a2, 0x28a3, 0x28a4, 0x28a5, 0x28a6, 0x28a7, 
+    0x28a8, 0x28a9, 0x28aa, 0x28ab, 0x28ac, 0x28ad, 0x28ae, 0x28af, 
+    0x28b0, 0x28b1, 0x28b2, 0x28b3, 0x28b4, 0x28b5, 0x28b6, 0x28b7, 
+    0x28b8, 0x28b9, 0x28ba, 0x28bb, 0x28bc, 0x28bd, 0x28be, 0x28bf, 
+    0x28c0, 0x28c1, 0x28c2, 0x28c3, 0x28c4, 0x28c5, 0x28c6, 0x28c7, 
+    0x28c8, 0x28c9, 0x28ca, 0x28cb, 0x28cc, 0x28cd, 0x28ce, 0x28cf, 
+    0x28d0, 0x28d1, 0x28d2, 0x28d3, 0x28d4, 0x28d5, 0x28d6, 0x28d7, 
+    0x28d8, 0x28d9, 0x28da, 0x28db, 0x28dc, 0x28dd, 0x28de, 0x28df, 
+    0x28e0, 0x28e1, 0x28e2, 0x28e3, 0x28e4, 0x28e5, 0x28e6, 0x28e7, 
+    0x28e8, 0x28e9, 0x28ea, 0x28eb, 0x28ec, 0x28ed, 0x28ee, 0x28ef, 
+    0x28f0, 0x28f1, 0x28f2, 0x28f3, 0x28f4, 0x28f5, 0x28f6, 0x28f7, 
+    0x28f8, 0x28f9, 0x28fa, 0x28fb, 0x28fc, 0x28fd, 0x28fe, 0x28ff, 
+    0x2900, 0x2901, 0x2902, 0x2903, 0x2904, 0x2905, 0x2906, 0x2907, 
+    0x2908, 0x2909, 0x290a, 0x290b, 0x290c, 0x290d, 0x290e, 0x290f, 
+    0x2910, 0x2911, 0x2912, 0x2913, 0x2914, 0x2915, 0x2916, 0x2917, 
+    0x2918, 0x2919, 0x291a, 0x291b, 0x291c, 0x291d, 0x291e, 0x291f, 
+    0x2920, 0x2921, 0x2922, 0x2923, 0x2924, 0x2925, 0x2926, 0x2927, 
+    0x2928, 0x2929, 0x292a, 0x292b, 0x292c, 0x292d, 0x292e, 0x292f, 
+    0x2930, 0x2931, 0x2932, 0x2933, 0x2934, 0x2935, 0x2936, 0x2937, 
+    0x2938, 0x2939, 0x293a, 0x293b, 0x293c, 0x293d, 0x293e, 0x293f, 
+    0x2940, 0x2941, 0x2942, 0x2943, 0x2944, 0x2945, 0x2946, 0x2947, 
+    0x2948, 0x2949, 0x294a, 0x294b, 0x294c, 0x294d, 0x294e, 0x294f, 
+    0x2950, 0x2951, 0x2952, 0x2953, 0x2954, 0x2955, 0x2956, 0x2957, 
+    0x2958, 0x2959, 0x295a, 0x295b, 0x295c, 0x295d, 0x295e, 0x295f, 
+    0x2960, 0x2961, 0x2962, 0x2963, 0x2964, 0x2965, 0x2966, 0x2967, 
+    0x2968, 0x2969, 0x296a, 0x296b, 0x296c, 0x296d, 0x296e, 0x296f, 
+    0x2970, 0x2971, 0x2972, 0x2973, 0x2974, 0x2975, 0x2976, 0x2977, 
+    0x2978, 0x2979, 0x297a, 0x297b, 0x297c, 0x297d, 0x297e, 0x297f, 
+    0x2980, 0x2981, 0x2982, 0x2983, 0x2984, 0x2985, 0x2986, 0x2987, 
+    0x2988, 0x2989, 0x298a, 0x298b, 0x298c, 0x298d, 0x298e, 0x298f, 
+    0x2990, 0x2991, 0x2992, 0x2993, 0x2994, 0x2995, 0x2996, 0x2997, 
+    0x2998, 0x2999, 0x299a, 0x299b, 0x299c, 0x299d, 0x299e, 0x299f, 
+    0x29a0, 0x29a1, 0x29a2, 0x29a3, 0x29a4, 0x29a5, 0x29a6, 0x29a7, 
+    0x29a8, 0x29a9, 0x29aa, 0x29ab, 0x29ac, 0x29ad, 0x29ae, 0x29af, 
+    0x29b0, 0x29b1, 0x29b2, 0x29b3, 0x29b4, 0x29b5, 0x29b6, 0x29b7, 
+    0x29b8, 0x29b9, 0x29ba, 0x29bb, 0x29bc, 0x29bd, 0x29be, 0x29bf, 
+    0x29c0, 0x29c1, 0x29c2, 0x29c3, 0x29c4, 0x29c5, 0x29c6, 0x29c7, 
+    0x29c8, 0x29c9, 0x29ca, 0x29cb, 0x29cc, 0x29cd, 0x29ce, 0x29cf, 
+    0x29d0, 0x29d1, 0x29d2, 0x29d3, 0x29d4, 0x29d5, 0x29d6, 0x29d7, 
+    0x29d8, 0x29d9, 0x29da, 0x29db, 0x29dc, 0x29dd, 0x29de, 0x29df, 
+    0x29e0, 0x29e1, 0x29e2, 0x29e3, 0x29e4, 0x29e5, 0x29e6, 0x29e7, 
+    0x29e8, 0x29e9, 0x29ea, 0x29eb, 0x29ec, 0x29ed, 0x29ee, 0x29ef, 
+    0x29f0, 0x29f1, 0x29f2, 0x29f3, 0x29f4, 0x29f5, 0x29f6, 0x29f7, 
+    0x29f8, 0x29f9, 0x29fa, 0x29fb, 0x29fc, 0x29fd, 0x29fe, 0x29ff, 
+    0x2a00, 0x2a01, 0x2a02, 0x2a03, 0x2a04, 0x2a05, 0x2a06, 0x2a07, 
+    0x2a08, 0x2a09, 0x2a0a, 0x2a0b, 0x2a0c, 0x2a0d, 0x2a0e, 0x2a0f, 
+    0x2a10, 0x2a11, 0x2a12, 0x2a13, 0x2a14, 0x2a15, 0x2a16, 0x2a17, 
+    0x2a18, 0x2a19, 0x2a1a, 0x2a1b, 0x2a1c, 0x2a1d, 0x2a1e, 0x2a1f, 
+    0x2a20, 0x2a21, 0x2a22, 0x2a23, 0x2a24, 0x2a25, 0x2a26, 0x2a27, 
+    0x2a28, 0x2a29, 0x2a2a, 0x2a2b, 0x2a2c, 0x2a2d, 0x2a2e, 0x2a2f, 
+    0x2a30, 0x2a31, 0x2a32, 0x2a33, 0x2a34, 0x2a35, 0x2a36, 0x2a37, 
+    0x2a38, 0x2a39, 0x2a3a, 0x2a3b, 0x2a3c, 0x2a3d, 0x2a3e, 0x2a3f, 
+    0x2a40, 0x2a41, 0x2a42, 0x2a43, 0x2a44, 0x2a45, 0x2a46, 0x2a47, 
+    0x2a48, 0x2a49, 0x2a4a, 0x2a4b, 0x2a4c, 0x2a4d, 0x2a4e, 0x2a4f, 
+    0x2a50, 0x2a51, 0x2a52, 0x2a53, 0x2a54, 0x2a55, 0x2a56, 0x2a57, 
+    0x2a58, 0x2a59, 0x2a5a, 0x2a5b, 0x2a5c, 0x2a5d, 0x2a5e, 0x2a5f, 
+    0x2a60, 0x2a61, 0x2a62, 0x2a63, 0x2a64, 0x2a65, 0x2a66, 0x2a67, 
+    0x2a68, 0x2a69, 0x2a6a, 0x2a6b, 0x2a6c, 0x2a6d, 0x2a6e, 0x2a6f, 
+    0x2a70, 0x2a71, 0x2a72, 0x2a73, 0x2a74, 0x2a75, 0x2a76, 0x2a77, 
+    0x2a78, 0x2a79, 0x2a7a, 0x2a7b, 0x2a7c, 0x2a7d, 0x2a7e, 0x2a7f, 
+    0x2a80, 0x2a81, 0x2a82, 0x2a83, 0x2a84, 0x2a85, 0x2a86, 0x2a87, 
+    0x2a88, 0x2a89, 0x2a8a, 0x2a8b, 0x2a8c, 0x2a8d, 0x2a8e, 0x2a8f, 
+    0x2a90, 0x2a91, 0x2a92, 0x2a93, 0x2a94, 0x2a95, 0x2a96, 0x2a97, 
+    0x2a98, 0x2a99, 0x2a9a, 0x2a9b, 0x2a9c, 0x2a9d, 0x2a9e, 0x2a9f, 
+    0x2aa0, 0x2aa1, 0x2aa2, 0x2aa3, 0x2aa4, 0x2aa5, 0x2aa6, 0x2aa7, 
+    0x2aa8, 0x2aa9, 0x2aaa, 0x2aab, 0x2aac, 0x2aad, 0x2aae, 0x2aaf, 
+    0x2ab0, 0x2ab1, 0x2ab2, 0x2ab3, 0x2ab4, 0x2ab5, 0x2ab6, 0x2ab7, 
+    0x2ab8, 0x2ab9, 0x2aba, 0x2abb, 0x2abc, 0x2abd, 0x2abe, 0x2abf, 
+    0x2ac0, 0x2ac1, 0x2ac2, 0x2ac3, 0x2ac4, 0x2ac5, 0x2ac6, 0x2ac7, 
+    0x2ac8, 0x2ac9, 0x2aca, 0x2acb, 0x2acc, 0x2acd, 0x2ace, 0x2acf, 
+    0x2ad0, 0x2ad1, 0x2ad2, 0x2ad3, 0x2ad4, 0x2ad5, 0x2ad6, 0x2ad7, 
+    0x2ad8, 0x2ad9, 0x2ada, 0x2adb, 0x2adc, 0x2add, 0x2ade, 0x2adf, 
+    0x2ae0, 0x2ae1, 0x2ae2, 0x2ae3, 0x2ae4, 0x2ae5, 0x2ae6, 0x2ae7, 
+    0x2ae8, 0x2ae9, 0x2aea, 0x2aeb, 0x2aec, 0x2aed, 0x2aee, 0x2aef, 
+    0x2af0, 0x2af1, 0x2af2, 0x2af3, 0x2af4, 0x2af5, 0x2af6, 0x2af7, 
+    0x2af8, 0x2af9, 0x2afa, 0x2afb, 0x2afc, 0x2afd, 0x2afe, 0x2aff, 
+    0x2b00, 0x2b01, 0x2b02, 0x2b03, 0x2b04, 0x2b05, 0x2b06, 0x2b07, 
+    0x2b08, 0x2b09, 0x2b0a, 0x2b0b, 0x2b0c, 0x2b0d, 0x2b0e, 0x2b0f, 
+    0x2b10, 0x2b11, 0x2b12, 0x2b13, 0x2b14, 0x2b15, 0x2b16, 0x2b17, 
+    0x2b18, 0x2b19, 0x2b1a, 0x2b1b, 0x2b1c, 0x2b1d, 0x2b1e, 0x2b1f, 
+    0x2b20, 0x2b21, 0x2b22, 0x2b23, 0x2b24, 0x2b25, 0x2b26, 0x2b27, 
+    0x2b28, 0x2b29, 0x2b2a, 0x2b2b, 0x2b2c, 0x2b2d, 0x2b2e, 0x2b2f, 
+    0x2b30, 0x2b31, 0x2b32, 0x2b33, 0x2b34, 0x2b35, 0x2b36, 0x2b37, 
+    0x2b38, 0x2b39, 0x2b3a, 0x2b3b, 0x2b3c, 0x2b3d, 0x2b3e, 0x2b3f, 
+    0x2b40, 0x2b41, 0x2b42, 0x2b43, 0x2b44, 0x2b45, 0x2b46, 0x2b47, 
+    0x2b48, 0x2b49, 0x2b4a, 0x2b4b, 0x2b4c, 0x2b4d, 0x2b4e, 0x2b4f, 
+    0x2b50, 0x2b51, 0x2b52, 0x2b53, 0x2b54, 0x2b55, 0x2b56, 0x2b57, 
+    0x2b58, 0x2b59, 0x2b5a, 0x2b5b, 0x2b5c, 0x2b5d, 0x2b5e, 0x2b5f, 
+    0x2b60, 0x2b61, 0x2b62, 0x2b63, 0x2b64, 0x2b65, 0x2b66, 0x2b67, 
+    0x2b68, 0x2b69, 0x2b6a, 0x2b6b, 0x2b6c, 0x2b6d, 0x2b6e, 0x2b6f, 
+    0x2b70, 0x2b71, 0x2b72, 0x2b73, 0x2b74, 0x2b75, 0x2b76, 0x2b77, 
+    0x2b78, 0x2b79, 0x2b7a, 0x2b7b, 0x2b7c, 0x2b7d, 0x2b7e, 0x2b7f, 
+    0x2b80, 0x2b81, 0x2b82, 0x2b83, 0x2b84, 0x2b85, 0x2b86, 0x2b87, 
+    0x2b88, 0x2b89, 0x2b8a, 0x2b8b, 0x2b8c, 0x2b8d, 0x2b8e, 0x2b8f, 
+    0x2b90, 0x2b91, 0x2b92, 0x2b93, 0x2b94, 0x2b95, 0x2b96, 0x2b97, 
+    0x2b98, 0x2b99, 0x2b9a, 0x2b9b, 0x2b9c, 0x2b9d, 0x2b9e, 0x2b9f, 
+    0x2ba0, 0x2ba1, 0x2ba2, 0x2ba3, 0x2ba4, 0x2ba5, 0x2ba6, 0x2ba7, 
+    0x2ba8, 0x2ba9, 0x2baa, 0x2bab, 0x2bac, 0x2bad, 0x2bae, 0x2baf, 
+    0x2bb0, 0x2bb1, 0x2bb2, 0x2bb3, 0x2bb4, 0x2bb5, 0x2bb6, 0x2bb7, 
+    0x2bb8, 0x2bb9, 0x2bba, 0x2bbb, 0x2bbc, 0x2bbd, 0x2bbe, 0x2bbf, 
+    0x2bc0, 0x2bc1, 0x2bc2, 0x2bc3, 0x2bc4, 0x2bc5, 0x2bc6, 0x2bc7, 
+    0x2bc8, 0x2bc9, 0x2bca, 0x2bcb, 0x2bcc, 0x2bcd, 0x2bce, 0x2bcf, 
+    0x2bd0, 0x2bd1, 0x2bd2, 0x2bd3, 0x2bd4, 0x2bd5, 0x2bd6, 0x2bd7, 
+    0x2bd8, 0x2bd9, 0x2bda, 0x2bdb, 0x2bdc, 0x2bdd, 0x2bde, 0x2bdf, 
+    0x2be0, 0x2be1, 0x2be2, 0x2be3, 0x2be4, 0x2be5, 0x2be6, 0x2be7, 
+    0x2be8, 0x2be9, 0x2bea, 0x2beb, 0x2bec, 0x2bed, 0x2bee, 0x2bef, 
+    0x2bf0, 0x2bf1, 0x2bf2, 0x2bf3, 0x2bf4, 0x2bf5, 0x2bf6, 0x2bf7, 
+    0x2bf8, 0x2bf9, 0x2bfa, 0x2bfb, 0x2bfc, 0x2bfd, 0x2bfe, 0x2bff, 
+    0x2c00, 0x2c01, 0x2c02, 0x2c03, 0x2c04, 0x2c05, 0x2c06, 0x2c07, 
+    0x2c08, 0x2c09, 0x2c0a, 0x2c0b, 0x2c0c, 0x2c0d, 0x2c0e, 0x2c0f, 
+    0x2c10, 0x2c11, 0x2c12, 0x2c13, 0x2c14, 0x2c15, 0x2c16, 0x2c17, 
+    0x2c18, 0x2c19, 0x2c1a, 0x2c1b, 0x2c1c, 0x2c1d, 0x2c1e, 0x2c1f, 
+    0x2c20, 0x2c21, 0x2c22, 0x2c23, 0x2c24, 0x2c25, 0x2c26, 0x2c27, 
+    0x2c28, 0x2c29, 0x2c2a, 0x2c2b, 0x2c2c, 0x2c2d, 0x2c2e, 0x2c2f, 
+    0x2c30, 0x2c31, 0x2c32, 0x2c33, 0x2c34, 0x2c35, 0x2c36, 0x2c37, 
+    0x2c38, 0x2c39, 0x2c3a, 0x2c3b, 0x2c3c, 0x2c3d, 0x2c3e, 0x2c3f, 
+    0x2c40, 0x2c41, 0x2c42, 0x2c43, 0x2c44, 0x2c45, 0x2c46, 0x2c47, 
+    0x2c48, 0x2c49, 0x2c4a, 0x2c4b, 0x2c4c, 0x2c4d, 0x2c4e, 0x2c4f, 
+    0x2c50, 0x2c51, 0x2c52, 0x2c53, 0x2c54, 0x2c55, 0x2c56, 0x2c57, 
+    0x2c58, 0x2c59, 0x2c5a, 0x2c5b, 0x2c5c, 0x2c5d, 0x2c5e, 0x2c5f, 
+    0x2c60, 0x2c61, 0x2c62, 0x2c63, 0x2c64, 0x2c65, 0x2c66, 0x2c67, 
+    0x2c68, 0x2c69, 0x2c6a, 0x2c6b, 0x2c6c, 0x2c6d, 0x2c6e, 0x2c6f, 
+    0x2c70, 0x2c71, 0x2c72, 0x2c73, 0x2c74, 0x2c75, 0x2c76, 0x2c77, 
+    0x2c78, 0x2c79, 0x2c7a, 0x2c7b, 0x2c7c, 0x2c7d, 0x2c7e, 0x2c7f, 
+    0x2c80, 0x2c81, 0x2c82, 0x2c83, 0x2c84, 0x2c85, 0x2c86, 0x2c87, 
+    0x2c88, 0x2c89, 0x2c8a, 0x2c8b, 0x2c8c, 0x2c8d, 0x2c8e, 0x2c8f, 
+    0x2c90, 0x2c91, 0x2c92, 0x2c93, 0x2c94, 0x2c95, 0x2c96, 0x2c97, 
+    0x2c98, 0x2c99, 0x2c9a, 0x2c9b, 0x2c9c, 0x2c9d, 0x2c9e, 0x2c9f, 
+    0x2ca0, 0x2ca1, 0x2ca2, 0x2ca3, 0x2ca4, 0x2ca5, 0x2ca6, 0x2ca7, 
+    0x2ca8, 0x2ca9, 0x2caa, 0x2cab, 0x2cac, 0x2cad, 0x2cae, 0x2caf, 
+    0x2cb0, 0x2cb1, 0x2cb2, 0x2cb3, 0x2cb4, 0x2cb5, 0x2cb6, 0x2cb7, 
+    0x2cb8, 0x2cb9, 0x2cba, 0x2cbb, 0x2cbc, 0x2cbd, 0x2cbe, 0x2cbf, 
+    0x2cc0, 0x2cc1, 0x2cc2, 0x2cc3, 0x2cc4, 0x2cc5, 0x2cc6, 0x2cc7, 
+    0x2cc8, 0x2cc9, 0x2cca, 0x2ccb, 0x2ccc, 0x2ccd, 0x2cce, 0x2ccf, 
+    0x2cd0, 0x2cd1, 0x2cd2, 0x2cd3, 0x2cd4, 0x2cd5, 0x2cd6, 0x2cd7, 
+    0x2cd8, 0x2cd9, 0x2cda, 0x2cdb, 0x2cdc, 0x2cdd, 0x2cde, 0x2cdf, 
+    0x2ce0, 0x2ce1, 0x2ce2, 0x2ce3, 0x2ce4, 0x2ce5, 0x2ce6, 0x2ce7, 
+    0x2ce8, 0x2ce9, 0x2cea, 0x2ceb, 0x2cec, 0x2ced, 0x2cee, 0x2cef, 
+    0x2cf0, 0x2cf1, 0x2cf2, 0x2cf3, 0x2cf4, 0x2cf5, 0x2cf6, 0x2cf7, 
+    0x2cf8, 0x2cf9, 0x2cfa, 0x2cfb, 0x2cfc, 0x2cfd, 0x2cfe, 0x2cff, 
+    0x2d00, 0x2d01, 0x2d02, 0x2d03, 0x2d04, 0x2d05, 0x2d06, 0x2d07, 
+    0x2d08, 0x2d09, 0x2d0a, 0x2d0b, 0x2d0c, 0x2d0d, 0x2d0e, 0x2d0f, 
+    0x2d10, 0x2d11, 0x2d12, 0x2d13, 0x2d14, 0x2d15, 0x2d16, 0x2d17, 
+    0x2d18, 0x2d19, 0x2d1a, 0x2d1b, 0x2d1c, 0x2d1d, 0x2d1e, 0x2d1f, 
+    0x2d20, 0x2d21, 0x2d22, 0x2d23, 0x2d24, 0x2d25, 0x2d26, 0x2d27, 
+    0x2d28, 0x2d29, 0x2d2a, 0x2d2b, 0x2d2c, 0x2d2d, 0x2d2e, 0x2d2f, 
+    0x2d30, 0x2d31, 0x2d32, 0x2d33, 0x2d34, 0x2d35, 0x2d36, 0x2d37, 
+    0x2d38, 0x2d39, 0x2d3a, 0x2d3b, 0x2d3c, 0x2d3d, 0x2d3e, 0x2d3f, 
+    0x2d40, 0x2d41, 0x2d42, 0x2d43, 0x2d44, 0x2d45, 0x2d46, 0x2d47, 
+    0x2d48, 0x2d49, 0x2d4a, 0x2d4b, 0x2d4c, 0x2d4d, 0x2d4e, 0x2d4f, 
+    0x2d50, 0x2d51, 0x2d52, 0x2d53, 0x2d54, 0x2d55, 0x2d56, 0x2d57, 
+    0x2d58, 0x2d59, 0x2d5a, 0x2d5b, 0x2d5c, 0x2d5d, 0x2d5e, 0x2d5f, 
+    0x2d60, 0x2d61, 0x2d62, 0x2d63, 0x2d64, 0x2d65, 0x2d66, 0x2d67, 
+    0x2d68, 0x2d69, 0x2d6a, 0x2d6b, 0x2d6c, 0x2d6d, 0x2d6e, 0x2d6f, 
+    0x2d70, 0x2d71, 0x2d72, 0x2d73, 0x2d74, 0x2d75, 0x2d76, 0x2d77, 
+    0x2d78, 0x2d79, 0x2d7a, 0x2d7b, 0x2d7c, 0x2d7d, 0x2d7e, 0x2d7f, 
+    0x2d80, 0x2d81, 0x2d82, 0x2d83, 0x2d84, 0x2d85, 0x2d86, 0x2d87, 
+    0x2d88, 0x2d89, 0x2d8a, 0x2d8b, 0x2d8c, 0x2d8d, 0x2d8e, 0x2d8f, 
+    0x2d90, 0x2d91, 0x2d92, 0x2d93, 0x2d94, 0x2d95, 0x2d96, 0x2d97, 
+    0x2d98, 0x2d99, 0x2d9a, 0x2d9b, 0x2d9c, 0x2d9d, 0x2d9e, 0x2d9f, 
+    0x2da0, 0x2da1, 0x2da2, 0x2da3, 0x2da4, 0x2da5, 0x2da6, 0x2da7, 
+    0x2da8, 0x2da9, 0x2daa, 0x2dab, 0x2dac, 0x2dad, 0x2dae, 0x2daf, 
+    0x2db0, 0x2db1, 0x2db2, 0x2db3, 0x2db4, 0x2db5, 0x2db6, 0x2db7, 
+    0x2db8, 0x2db9, 0x2dba, 0x2dbb, 0x2dbc, 0x2dbd, 0x2dbe, 0x2dbf, 
+    0x2dc0, 0x2dc1, 0x2dc2, 0x2dc3, 0x2dc4, 0x2dc5, 0x2dc6, 0x2dc7, 
+    0x2dc8, 0x2dc9, 0x2dca, 0x2dcb, 0x2dcc, 0x2dcd, 0x2dce, 0x2dcf, 
+    0x2dd0, 0x2dd1, 0x2dd2, 0x2dd3, 0x2dd4, 0x2dd5, 0x2dd6, 0x2dd7, 
+    0x2dd8, 0x2dd9, 0x2dda, 0x2ddb, 0x2ddc, 0x2ddd, 0x2dde, 0x2ddf, 
+    0x2de0, 0x2de1, 0x2de2, 0x2de3, 0x2de4, 0x2de5, 0x2de6, 0x2de7, 
+    0x2de8, 0x2de9, 0x2dea, 0x2deb, 0x2dec, 0x2ded, 0x2dee, 0x2def, 
+    0x2df0, 0x2df1, 0x2df2, 0x2df3, 0x2df4, 0x2df5, 0x2df6, 0x2df7, 
+    0x2df8, 0x2df9, 0x2dfa, 0x2dfb, 0x2dfc, 0x2dfd, 0x2dfe, 0x2dff, 
+    0x2e00, 0x2e01, 0x2e02, 0x2e03, 0x2e04, 0x2e05, 0x2e06, 0x2e07, 
+    0x2e08, 0x2e09, 0x2e0a, 0x2e0b, 0x2e0c, 0x2e0d, 0x2e0e, 0x2e0f, 
+    0x2e10, 0x2e11, 0x2e12, 0x2e13, 0x2e14, 0x2e15, 0x2e16, 0x2e17, 
+    0x2e18, 0x2e19, 0x2e1a, 0x2e1b, 0x2e1c, 0x2e1d, 0x2e1e, 0x2e1f, 
+    0x2e20, 0x2e21, 0x2e22, 0x2e23, 0x2e24, 0x2e25, 0x2e26, 0x2e27, 
+    0x2e28, 0x2e29, 0x2e2a, 0x2e2b, 0x2e2c, 0x2e2d, 0x2e2e, 0x2e2f, 
+    0x2e30, 0x2e31, 0x2e32, 0x2e33, 0x2e34, 0x2e35, 0x2e36, 0x2e37, 
+    0x2e38, 0x2e39, 0x2e3a, 0x2e3b, 0x2e3c, 0x2e3d, 0x2e3e, 0x2e3f, 
+    0x2e40, 0x2e41, 0x2e42, 0x2e43, 0x2e44, 0x2e45, 0x2e46, 0x2e47, 
+    0x2e48, 0x2e49, 0x2e4a, 0x2e4b, 0x2e4c, 0x2e4d, 0x2e4e, 0x2e4f, 
+    0x2e50, 0x2e51, 0x2e52, 0x2e53, 0x2e54, 0x2e55, 0x2e56, 0x2e57, 
+    0x2e58, 0x2e59, 0x2e5a, 0x2e5b, 0x2e5c, 0x2e5d, 0x2e5e, 0x2e5f, 
+    0x2e60, 0x2e61, 0x2e62, 0x2e63, 0x2e64, 0x2e65, 0x2e66, 0x2e67, 
+    0x2e68, 0x2e69, 0x2e6a, 0x2e6b, 0x2e6c, 0x2e6d, 0x2e6e, 0x2e6f, 
+    0x2e70, 0x2e71, 0x2e72, 0x2e73, 0x2e74, 0x2e75, 0x2e76, 0x2e77, 
+    0x2e78, 0x2e79, 0x2e7a, 0x2e7b, 0x2e7c, 0x2e7d, 0x2e7e, 0x2e7f, 
+    0x2e80, 0x2e81, 0x2e82, 0x2e83, 0x2e84, 0x2e85, 0x2e86, 0x2e87, 
+    0x2e88, 0x2e89, 0x2e8a, 0x2e8b, 0x2e8c, 0x2e8d, 0x2e8e, 0x2e8f, 
+    0x2e90, 0x2e91, 0x2e92, 0x2e93, 0x2e94, 0x2e95, 0x2e96, 0x2e97, 
+    0x2e98, 0x2e99, 0x2e9a, 0x2e9b, 0x2e9c, 0x2e9d, 0x2e9e, 0x2e9f, 
+    0x2ea0, 0x2ea1, 0x2ea2, 0x2ea3, 0x2ea4, 0x2ea5, 0x2ea6, 0x2ea7, 
+    0x2ea8, 0x2ea9, 0x2eaa, 0x2eab, 0x2eac, 0x2ead, 0x2eae, 0x2eaf, 
+    0x2eb0, 0x2eb1, 0x2eb2, 0x2eb3, 0x2eb4, 0x2eb5, 0x2eb6, 0x2eb7, 
+    0x2eb8, 0x2eb9, 0x2eba, 0x2ebb, 0x2ebc, 0x2ebd, 0x2ebe, 0x2ebf, 
+    0x2ec0, 0x2ec1, 0x2ec2, 0x2ec3, 0x2ec4, 0x2ec5, 0x2ec6, 0x2ec7, 
+    0x2ec8, 0x2ec9, 0x2eca, 0x2ecb, 0x2ecc, 0x2ecd, 0x2ece, 0x2ecf, 
+    0x2ed0, 0x2ed1, 0x2ed2, 0x2ed3, 0x2ed4, 0x2ed5, 0x2ed6, 0x2ed7, 
+    0x2ed8, 0x2ed9, 0x2eda, 0x2edb, 0x2edc, 0x2edd, 0x2ede, 0x2edf, 
+    0x2ee0, 0x2ee1, 0x2ee2, 0x2ee3, 0x2ee4, 0x2ee5, 0x2ee6, 0x2ee7, 
+    0x2ee8, 0x2ee9, 0x2eea, 0x2eeb, 0x2eec, 0x2eed, 0x2eee, 0x2eef, 
+    0x2ef0, 0x2ef1, 0x2ef2, 0x2ef3, 0x2ef4, 0x2ef5, 0x2ef6, 0x2ef7, 
+    0x2ef8, 0x2ef9, 0x2efa, 0x2efb, 0x2efc, 0x2efd, 0x2efe, 0x2eff, 
+    0x2f00, 0x2f01, 0x2f02, 0x2f03, 0x2f04, 0x2f05, 0x2f06, 0x2f07, 
+    0x2f08, 0x2f09, 0x2f0a, 0x2f0b, 0x2f0c, 0x2f0d, 0x2f0e, 0x2f0f, 
+    0x2f10, 0x2f11, 0x2f12, 0x2f13, 0x2f14, 0x2f15, 0x2f16, 0x2f17, 
+    0x2f18, 0x2f19, 0x2f1a, 0x2f1b, 0x2f1c, 0x2f1d, 0x2f1e, 0x2f1f, 
+    0x2f20, 0x2f21, 0x2f22, 0x2f23, 0x2f24, 0x2f25, 0x2f26, 0x2f27, 
+    0x2f28, 0x2f29, 0x2f2a, 0x2f2b, 0x2f2c, 0x2f2d, 0x2f2e, 0x2f2f, 
+    0x2f30, 0x2f31, 0x2f32, 0x2f33, 0x2f34, 0x2f35, 0x2f36, 0x2f37, 
+    0x2f38, 0x2f39, 0x2f3a, 0x2f3b, 0x2f3c, 0x2f3d, 0x2f3e, 0x2f3f, 
+    0x2f40, 0x2f41, 0x2f42, 0x2f43, 0x2f44, 0x2f45, 0x2f46, 0x2f47, 
+    0x2f48, 0x2f49, 0x2f4a, 0x2f4b, 0x2f4c, 0x2f4d, 0x2f4e, 0x2f4f, 
+    0x2f50, 0x2f51, 0x2f52, 0x2f53, 0x2f54, 0x2f55, 0x2f56, 0x2f57, 
+    0x2f58, 0x2f59, 0x2f5a, 0x2f5b, 0x2f5c, 0x2f5d, 0x2f5e, 0x2f5f, 
+    0x2f60, 0x2f61, 0x2f62, 0x2f63, 0x2f64, 0x2f65, 0x2f66, 0x2f67, 
+    0x2f68, 0x2f69, 0x2f6a, 0x2f6b, 0x2f6c, 0x2f6d, 0x2f6e, 0x2f6f, 
+    0x2f70, 0x2f71, 0x2f72, 0x2f73, 0x2f74, 0x2f75, 0x2f76, 0x2f77, 
+    0x2f78, 0x2f79, 0x2f7a, 0x2f7b, 0x2f7c, 0x2f7d, 0x2f7e, 0x2f7f, 
+    0x2f80, 0x2f81, 0x2f82, 0x2f83, 0x2f84, 0x2f85, 0x2f86, 0x2f87, 
+    0x2f88, 0x2f89, 0x2f8a, 0x2f8b, 0x2f8c, 0x2f8d, 0x2f8e, 0x2f8f, 
+    0x2f90, 0x2f91, 0x2f92, 0x2f93, 0x2f94, 0x2f95, 0x2f96, 0x2f97, 
+    0x2f98, 0x2f99, 0x2f9a, 0x2f9b, 0x2f9c, 0x2f9d, 0x2f9e, 0x2f9f, 
+    0x2fa0, 0x2fa1, 0x2fa2, 0x2fa3, 0x2fa4, 0x2fa5, 0x2fa6, 0x2fa7, 
+    0x2fa8, 0x2fa9, 0x2faa, 0x2fab, 0x2fac, 0x2fad, 0x2fae, 0x2faf, 
+    0x2fb0, 0x2fb1, 0x2fb2, 0x2fb3, 0x2fb4, 0x2fb5, 0x2fb6, 0x2fb7, 
+    0x2fb8, 0x2fb9, 0x2fba, 0x2fbb, 0x2fbc, 0x2fbd, 0x2fbe, 0x2fbf, 
+    0x2fc0, 0x2fc1, 0x2fc2, 0x2fc3, 0x2fc4, 0x2fc5, 0x2fc6, 0x2fc7, 
+    0x2fc8, 0x2fc9, 0x2fca, 0x2fcb, 0x2fcc, 0x2fcd, 0x2fce, 0x2fcf, 
+    0x2fd0, 0x2fd1, 0x2fd2, 0x2fd3, 0x2fd4, 0x2fd5, 0x2fd6, 0x2fd7, 
+    0x2fd8, 0x2fd9, 0x2fda, 0x2fdb, 0x2fdc, 0x2fdd, 0x2fde, 0x2fdf, 
+    0x2fe0, 0x2fe1, 0x2fe2, 0x2fe3, 0x2fe4, 0x2fe5, 0x2fe6, 0x2fe7, 
+    0x2fe8, 0x2fe9, 0x2fea, 0x2feb, 0x2fec, 0x2fed, 0x2fee, 0x2fef, 
+    0x2ff0, 0x2ff1, 0x2ff2, 0x2ff3, 0x2ff4, 0x2ff5, 0x2ff6, 0x2ff7, 
+    0x2ff8, 0x2ff9, 0x2ffa, 0x2ffb, 0x2ffc, 0x2ffd, 0x2ffe, 0x2fff, 
+    0x3000, 0x3001, 0x3002, 0x3003, 0x3004, 0x3005, 0x3006, 0x3007, 
+    0x3008, 0x3009, 0x300a, 0x300b, 0x300c, 0x300d, 0x300e, 0x300f, 
+    0x3010, 0x3011, 0x3012, 0x3013, 0x3014, 0x3015, 0x3016, 0x3017, 
+    0x3018, 0x3019, 0x301a, 0x301b, 0x301c, 0x301d, 0x301e, 0x301f, 
+    0x3020, 0x3021, 0x3022, 0x3023, 0x3024, 0x3025, 0x3026, 0x3027, 
+    0x3028, 0x3029, 0x302a, 0x302b, 0x302c, 0x302d, 0x302e, 0x302f, 
+    0x3030, 0x3031, 0x3032, 0x3033, 0x3034, 0x3035, 0x3036, 0x3037, 
+    0x3038, 0x3039, 0x303a, 0x303b, 0x303c, 0x303d, 0x303e, 0x303f, 
+    0x3040, 0x3041, 0x3042, 0x3043, 0x3044, 0x3045, 0x3046, 0x3047, 
+    0x3048, 0x3049, 0x304a, 0x304b, 0x304c, 0x304d, 0x304e, 0x304f, 
+    0x3050, 0x3051, 0x3052, 0x3053, 0x3054, 0x3055, 0x3056, 0x3057, 
+    0x3058, 0x3059, 0x305a, 0x305b, 0x305c, 0x305d, 0x305e, 0x305f, 
+    0x3060, 0x3061, 0x3062, 0x3063, 0x3064, 0x3065, 0x3066, 0x3067, 
+    0x3068, 0x3069, 0x306a, 0x306b, 0x306c, 0x306d, 0x306e, 0x306f, 
+    0x3070, 0x3071, 0x3072, 0x3073, 0x3074, 0x3075, 0x3076, 0x3077, 
+    0x3078, 0x3079, 0x307a, 0x307b, 0x307c, 0x307d, 0x307e, 0x307f, 
+    0x3080, 0x3081, 0x3082, 0x3083, 0x3084, 0x3085, 0x3086, 0x3087, 
+    0x3088, 0x3089, 0x308a, 0x308b, 0x308c, 0x308d, 0x308e, 0x308f, 
+    0x3090, 0x3091, 0x3092, 0x3093, 0x3094, 0x3095, 0x3096, 0x3097, 
+    0x3098, 0x3099, 0x309a, 0x309b, 0x309c, 0x309d, 0x309e, 0x309f, 
+    0x30a0, 0x30a1, 0x30a2, 0x30a3, 0x30a4, 0x30a5, 0x30a6, 0x30a7, 
+    0x30a8, 0x30a9, 0x30aa, 0x30ab, 0x30ac, 0x30ad, 0x30ae, 0x30af, 
+    0x30b0, 0x30b1, 0x30b2, 0x30b3, 0x30b4, 0x30b5, 0x30b6, 0x30b7, 
+    0x30b8, 0x30b9, 0x30ba, 0x30bb, 0x30bc, 0x30bd, 0x30be, 0x30bf, 
+    0x30c0, 0x30c1, 0x30c2, 0x30c3, 0x30c4, 0x30c5, 0x30c6, 0x30c7, 
+    0x30c8, 0x30c9, 0x30ca, 0x30cb, 0x30cc, 0x30cd, 0x30ce, 0x30cf, 
+    0x30d0, 0x30d1, 0x30d2, 0x30d3, 0x30d4, 0x30d5, 0x30d6, 0x30d7, 
+    0x30d8, 0x30d9, 0x30da, 0x30db, 0x30dc, 0x30dd, 0x30de, 0x30df, 
+    0x30e0, 0x30e1, 0x30e2, 0x30e3, 0x30e4, 0x30e5, 0x30e6, 0x30e7, 
+    0x30e8, 0x30e9, 0x30ea, 0x30eb, 0x30ec, 0x30ed, 0x30ee, 0x30ef, 
+    0x30f0, 0x30f1, 0x30f2, 0x30f3, 0x30f4, 0x30f5, 0x30f6, 0x30f7, 
+    0x30f8, 0x30f9, 0x30fa, 0x30fb, 0x30fc, 0x30fd, 0x30fe, 0x30ff, 
+    0x3100, 0x3101, 0x3102, 0x3103, 0x3104, 0x3105, 0x3106, 0x3107, 
+    0x3108, 0x3109, 0x310a, 0x310b, 0x310c, 0x310d, 0x310e, 0x310f, 
+    0x3110, 0x3111, 0x3112, 0x3113, 0x3114, 0x3115, 0x3116, 0x3117, 
+    0x3118, 0x3119, 0x311a, 0x311b, 0x311c, 0x311d, 0x311e, 0x311f, 
+    0x3120, 0x3121, 0x3122, 0x3123, 0x3124, 0x3125, 0x3126, 0x3127, 
+    0x3128, 0x3129, 0x312a, 0x312b, 0x312c, 0x312d, 0x312e, 0x312f, 
+    0x3130, 0x3131, 0x3132, 0x3133, 0x3134, 0x3135, 0x3136, 0x3137, 
+    0x3138, 0x3139, 0x313a, 0x313b, 0x313c, 0x313d, 0x313e, 0x313f, 
+    0x3140, 0x3141, 0x3142, 0x3143, 0x3144, 0x3145, 0x3146, 0x3147, 
+    0x3148, 0x3149, 0x314a, 0x314b, 0x314c, 0x314d, 0x314e, 0x314f, 
+    0x3150, 0x3151, 0x3152, 0x3153, 0x3154, 0x3155, 0x3156, 0x3157, 
+    0x3158, 0x3159, 0x315a, 0x315b, 0x315c, 0x315d, 0x315e, 0x315f, 
+    0x3160, 0x3161, 0x3162, 0x3163, 0x3164, 0x3165, 0x3166, 0x3167, 
+    0x3168, 0x3169, 0x316a, 0x316b, 0x316c, 0x316d, 0x316e, 0x316f, 
+    0x3170, 0x3171, 0x3172, 0x3173, 0x3174, 0x3175, 0x3176, 0x3177, 
+    0x3178, 0x3179, 0x317a, 0x317b, 0x317c, 0x317d, 0x317e, 0x317f, 
+    0x3180, 0x3181, 0x3182, 0x3183, 0x3184, 0x3185, 0x3186, 0x3187, 
+    0x3188, 0x3189, 0x318a, 0x318b, 0x318c, 0x318d, 0x318e, 0x318f, 
+    0x3190, 0x3191, 0x3192, 0x3193, 0x3194, 0x3195, 0x3196, 0x3197, 
+    0x3198, 0x3199, 0x319a, 0x319b, 0x319c, 0x319d, 0x319e, 0x319f, 
+    0x31a0, 0x31a1, 0x31a2, 0x31a3, 0x31a4, 0x31a5, 0x31a6, 0x31a7, 
+    0x31a8, 0x31a9, 0x31aa, 0x31ab, 0x31ac, 0x31ad, 0x31ae, 0x31af, 
+    0x31b0, 0x31b1, 0x31b2, 0x31b3, 0x31b4, 0x31b5, 0x31b6, 0x31b7, 
+    0x31b8, 0x31b9, 0x31ba, 0x31bb, 0x31bc, 0x31bd, 0x31be, 0x31bf, 
+    0x31c0, 0x31c1, 0x31c2, 0x31c3, 0x31c4, 0x31c5, 0x31c6, 0x31c7, 
+    0x31c8, 0x31c9, 0x31ca, 0x31cb, 0x31cc, 0x31cd, 0x31ce, 0x31cf, 
+    0x31d0, 0x31d1, 0x31d2, 0x31d3, 0x31d4, 0x31d5, 0x31d6, 0x31d7, 
+    0x31d8, 0x31d9, 0x31da, 0x31db, 0x31dc, 0x31dd, 0x31de, 0x31df, 
+    0x31e0, 0x31e1, 0x31e2, 0x31e3, 0x31e4, 0x31e5, 0x31e6, 0x31e7, 
+    0x31e8, 0x31e9, 0x31ea, 0x31eb, 0x31ec, 0x31ed, 0x31ee, 0x31ef, 
+    0x31f0, 0x31f1, 0x31f2, 0x31f3, 0x31f4, 0x31f5, 0x31f6, 0x31f7, 
+    0x31f8, 0x31f9, 0x31fa, 0x31fb, 0x31fc, 0x31fd, 0x31fe, 0x31ff, 
+    0x3200, 0x3201, 0x3202, 0x3203, 0x3204, 0x3205, 0x3206, 0x3207, 
+    0x3208, 0x3209, 0x320a, 0x320b, 0x320c, 0x320d, 0x320e, 0x320f, 
+    0x3210, 0x3211, 0x3212, 0x3213, 0x3214, 0x3215, 0x3216, 0x3217, 
+    0x3218, 0x3219, 0x321a, 0x321b, 0x321c, 0x321d, 0x321e, 0x321f, 
+    0x3220, 0x3221, 0x3222, 0x3223, 0x3224, 0x3225, 0x3226, 0x3227, 
+    0x3228, 0x3229, 0x322a, 0x322b, 0x322c, 0x322d, 0x322e, 0x322f, 
+    0x3230, 0x3231, 0x3232, 0x3233, 0x3234, 0x3235, 0x3236, 0x3237, 
+    0x3238, 0x3239, 0x323a, 0x323b, 0x323c, 0x323d, 0x323e, 0x323f, 
+    0x3240, 0x3241, 0x3242, 0x3243, 0x3244, 0x3245, 0x3246, 0x3247, 
+    0x3248, 0x3249, 0x324a, 0x324b, 0x324c, 0x324d, 0x324e, 0x324f, 
+    0x3250, 0x3251, 0x3252, 0x3253, 0x3254, 0x3255, 0x3256, 0x3257, 
+    0x3258, 0x3259, 0x325a, 0x325b, 0x325c, 0x325d, 0x325e, 0x325f, 
+    0x3260, 0x3261, 0x3262, 0x3263, 0x3264, 0x3265, 0x3266, 0x3267, 
+    0x3268, 0x3269, 0x326a, 0x326b, 0x326c, 0x326d, 0x326e, 0x326f, 
+    0x3270, 0x3271, 0x3272, 0x3273, 0x3274, 0x3275, 0x3276, 0x3277, 
+    0x3278, 0x3279, 0x327a, 0x327b, 0x327c, 0x327d, 0x327e, 0x327f, 
+    0x3280, 0x3281, 0x3282, 0x3283, 0x3284, 0x3285, 0x3286, 0x3287, 
+    0x3288, 0x3289, 0x328a, 0x328b, 0x328c, 0x328d, 0x328e, 0x328f, 
+    0x3290, 0x3291, 0x3292, 0x3293, 0x3294, 0x3295, 0x3296, 0x3297, 
+    0x3298, 0x3299, 0x329a, 0x329b, 0x329c, 0x329d, 0x329e, 0x329f, 
+    0x32a0, 0x32a1, 0x32a2, 0x32a3, 0x32a4, 0x32a5, 0x32a6, 0x32a7, 
+    0x32a8, 0x32a9, 0x32aa, 0x32ab, 0x32ac, 0x32ad, 0x32ae, 0x32af, 
+    0x32b0, 0x32b1, 0x32b2, 0x32b3, 0x32b4, 0x32b5, 0x32b6, 0x32b7, 
+    0x32b8, 0x32b9, 0x32ba, 0x32bb, 0x32bc, 0x32bd, 0x32be, 0x32bf, 
+    0x32c0, 0x32c1, 0x32c2, 0x32c3, 0x32c4, 0x32c5, 0x32c6, 0x32c7, 
+    0x32c8, 0x32c9, 0x32ca, 0x32cb, 0x32cc, 0x32cd, 0x32ce, 0x32cf, 
+    0x32d0, 0x32d1, 0x32d2, 0x32d3, 0x32d4, 0x32d5, 0x32d6, 0x32d7, 
+    0x32d8, 0x32d9, 0x32da, 0x32db, 0x32dc, 0x32dd, 0x32de, 0x32df, 
+    0x32e0, 0x32e1, 0x32e2, 0x32e3, 0x32e4, 0x32e5, 0x32e6, 0x32e7, 
+    0x32e8, 0x32e9, 0x32ea, 0x32eb, 0x32ec, 0x32ed, 0x32ee, 0x32ef, 
+    0x32f0, 0x32f1, 0x32f2, 0x32f3, 0x32f4, 0x32f5, 0x32f6, 0x32f7, 
+    0x32f8, 0x32f9, 0x32fa, 0x32fb, 0x32fc, 0x32fd, 0x32fe, 0x32ff, 
+    0x3300, 0x3301, 0x3302, 0x3303, 0x3304, 0x3305, 0x3306, 0x3307, 
+    0x3308, 0x3309, 0x330a, 0x330b, 0x330c, 0x330d, 0x330e, 0x330f, 
+    0x3310, 0x3311, 0x3312, 0x3313, 0x3314, 0x3315, 0x3316, 0x3317, 
+    0x3318, 0x3319, 0x331a, 0x331b, 0x331c, 0x331d, 0x331e, 0x331f, 
+    0x3320, 0x3321, 0x3322, 0x3323, 0x3324, 0x3325, 0x3326, 0x3327, 
+    0x3328, 0x3329, 0x332a, 0x332b, 0x332c, 0x332d, 0x332e, 0x332f, 
+    0x3330, 0x3331, 0x3332, 0x3333, 0x3334, 0x3335, 0x3336, 0x3337, 
+    0x3338, 0x3339, 0x333a, 0x333b, 0x333c, 0x333d, 0x333e, 0x333f, 
+    0x3340, 0x3341, 0x3342, 0x3343, 0x3344, 0x3345, 0x3346, 0x3347, 
+    0x3348, 0x3349, 0x334a, 0x334b, 0x334c, 0x334d, 0x334e, 0x334f, 
+    0x3350, 0x3351, 0x3352, 0x3353, 0x3354, 0x3355, 0x3356, 0x3357, 
+    0x3358, 0x3359, 0x335a, 0x335b, 0x335c, 0x335d, 0x335e, 0x335f, 
+    0x3360, 0x3361, 0x3362, 0x3363, 0x3364, 0x3365, 0x3366, 0x3367, 
+    0x3368, 0x3369, 0x336a, 0x336b, 0x336c, 0x336d, 0x336e, 0x336f, 
+    0x3370, 0x3371, 0x3372, 0x3373, 0x3374, 0x3375, 0x3376, 0x3377, 
+    0x3378, 0x3379, 0x337a, 0x337b, 0x337c, 0x337d, 0x337e, 0x337f, 
+    0x3380, 0x3381, 0x3382, 0x3383, 0x3384, 0x3385, 0x3386, 0x3387, 
+    0x3388, 0x3389, 0x338a, 0x338b, 0x338c, 0x338d, 0x338e, 0x338f, 
+    0x3390, 0x3391, 0x3392, 0x3393, 0x3394, 0x3395, 0x3396, 0x3397, 
+    0x3398, 0x3399, 0x339a, 0x339b, 0x339c, 0x339d, 0x339e, 0x339f, 
+    0x33a0, 0x33a1, 0x33a2, 0x33a3, 0x33a4, 0x33a5, 0x33a6, 0x33a7, 
+    0x33a8, 0x33a9, 0x33aa, 0x33ab, 0x33ac, 0x33ad, 0x33ae, 0x33af, 
+    0x33b0, 0x33b1, 0x33b2, 0x33b3, 0x33b4, 0x33b5, 0x33b6, 0x33b7, 
+    0x33b8, 0x33b9, 0x33ba, 0x33bb, 0x33bc, 0x33bd, 0x33be, 0x33bf, 
+    0x33c0, 0x33c1, 0x33c2, 0x33c3, 0x33c4, 0x33c5, 0x33c6, 0x33c7, 
+    0x33c8, 0x33c9, 0x33ca, 0x33cb, 0x33cc, 0x33cd, 0x33ce, 0x33cf, 
+    0x33d0, 0x33d1, 0x33d2, 0x33d3, 0x33d4, 0x33d5, 0x33d6, 0x33d7, 
+    0x33d8, 0x33d9, 0x33da, 0x33db, 0x33dc, 0x33dd, 0x33de, 0x33df, 
+    0x33e0, 0x33e1, 0x33e2, 0x33e3, 0x33e4, 0x33e5, 0x33e6, 0x33e7, 
+    0x33e8, 0x33e9, 0x33ea, 0x33eb, 0x33ec, 0x33ed, 0x33ee, 0x33ef, 
+    0x33f0, 0x33f1, 0x33f2, 0x33f3, 0x33f4, 0x33f5, 0x33f6, 0x33f7, 
+    0x33f8, 0x33f9, 0x33fa, 0x33fb, 0x33fc, 0x33fd, 0x33fe, 0x33ff, 
+    0x3400, 0x3401, 0x3402, 0x3403, 0x3404, 0x3405, 0x3406, 0x3407, 
+    0x3408, 0x3409, 0x340a, 0x340b, 0x340c, 0x340d, 0x340e, 0x340f, 
+    0x3410, 0x3411, 0x3412, 0x3413, 0x3414, 0x3415, 0x3416, 0x3417, 
+    0x3418, 0x3419, 0x341a, 0x341b, 0x341c, 0x341d, 0x341e, 0x341f, 
+    0x3420, 0x3421, 0x3422, 0x3423, 0x3424, 0x3425, 0x3426, 0x3427, 
+    0x3428, 0x3429, 0x342a, 0x342b, 0x342c, 0x342d, 0x342e, 0x342f, 
+    0x3430, 0x3431, 0x3432, 0x3433, 0x3434, 0x3435, 0x3436, 0x3437, 
+    0x3438, 0x3439, 0x343a, 0x343b, 0x343c, 0x343d, 0x343e, 0x343f, 
+    0x3440, 0x3441, 0x3442, 0x3443, 0x3444, 0x3445, 0x3446, 0x3447, 
+    0x3448, 0x3449, 0x344a, 0x344b, 0x344c, 0x344d, 0x344e, 0x344f, 
+    0x3450, 0x3451, 0x3452, 0x3453, 0x3454, 0x3455, 0x3456, 0x3457, 
+    0x3458, 0x3459, 0x345a, 0x345b, 0x345c, 0x345d, 0x345e, 0x345f, 
+    0x3460, 0x3461, 0x3462, 0x3463, 0x3464, 0x3465, 0x3466, 0x3467, 
+    0x3468, 0x3469, 0x346a, 0x346b, 0x346c, 0x346d, 0x346e, 0x346f, 
+    0x3470, 0x3471, 0x3472, 0x3473, 0x3474, 0x3475, 0x3476, 0x3477, 
+    0x3478, 0x3479, 0x347a, 0x347b, 0x347c, 0x347d, 0x347e, 0x347f, 
+    0x3480, 0x3481, 0x3482, 0x3483, 0x3484, 0x3485, 0x3486, 0x3487, 
+    0x3488, 0x3489, 0x348a, 0x348b, 0x348c, 0x348d, 0x348e, 0x348f, 
+    0x3490, 0x3491, 0x3492, 0x3493, 0x3494, 0x3495, 0x3496, 0x3497, 
+    0x3498, 0x3499, 0x349a, 0x349b, 0x349c, 0x349d, 0x349e, 0x349f, 
+    0x34a0, 0x34a1, 0x34a2, 0x34a3, 0x34a4, 0x34a5, 0x34a6, 0x34a7, 
+    0x34a8, 0x34a9, 0x34aa, 0x34ab, 0x34ac, 0x34ad, 0x34ae, 0x34af, 
+    0x34b0, 0x34b1, 0x34b2, 0x34b3, 0x34b4, 0x34b5, 0x34b6, 0x34b7, 
+    0x34b8, 0x34b9, 0x34ba, 0x34bb, 0x34bc, 0x34bd, 0x34be, 0x34bf, 
+    0x34c0, 0x34c1, 0x34c2, 0x34c3, 0x34c4, 0x34c5, 0x34c6, 0x34c7, 
+    0x34c8, 0x34c9, 0x34ca, 0x34cb, 0x34cc, 0x34cd, 0x34ce, 0x34cf, 
+    0x34d0, 0x34d1, 0x34d2, 0x34d3, 0x34d4, 0x34d5, 0x34d6, 0x34d7, 
+    0x34d8, 0x34d9, 0x34da, 0x34db, 0x34dc, 0x34dd, 0x34de, 0x34df, 
+    0x34e0, 0x34e1, 0x34e2, 0x34e3, 0x34e4, 0x34e5, 0x34e6, 0x34e7, 
+    0x34e8, 0x34e9, 0x34ea, 0x34eb, 0x34ec, 0x34ed, 0x34ee, 0x34ef, 
+    0x34f0, 0x34f1, 0x34f2, 0x34f3, 0x34f4, 0x34f5, 0x34f6, 0x34f7, 
+    0x34f8, 0x34f9, 0x34fa, 0x34fb, 0x34fc, 0x34fd, 0x34fe, 0x34ff, 
+    0x3500, 0x3501, 0x3502, 0x3503, 0x3504, 0x3505, 0x3506, 0x3507, 
+    0x3508, 0x3509, 0x350a, 0x350b, 0x350c, 0x350d, 0x350e, 0x350f, 
+    0x3510, 0x3511, 0x3512, 0x3513, 0x3514, 0x3515, 0x3516, 0x3517, 
+    0x3518, 0x3519, 0x351a, 0x351b, 0x351c, 0x351d, 0x351e, 0x351f, 
+    0x3520, 0x3521, 0x3522, 0x3523, 0x3524, 0x3525, 0x3526, 0x3527, 
+    0x3528, 0x3529, 0x352a, 0x352b, 0x352c, 0x352d, 0x352e, 0x352f, 
+    0x3530, 0x3531, 0x3532, 0x3533, 0x3534, 0x3535, 0x3536, 0x3537, 
+    0x3538, 0x3539, 0x353a, 0x353b, 0x353c, 0x353d, 0x353e, 0x353f, 
+    0x3540, 0x3541, 0x3542, 0x3543, 0x3544, 0x3545, 0x3546, 0x3547, 
+    0x3548, 0x3549, 0x354a, 0x354b, 0x354c, 0x354d, 0x354e, 0x354f, 
+    0x3550, 0x3551, 0x3552, 0x3553, 0x3554, 0x3555, 0x3556, 0x3557, 
+    0x3558, 0x3559, 0x355a, 0x355b, 0x355c, 0x355d, 0x355e, 0x355f, 
+    0x3560, 0x3561, 0x3562, 0x3563, 0x3564, 0x3565, 0x3566, 0x3567, 
+    0x3568, 0x3569, 0x356a, 0x356b, 0x356c, 0x356d, 0x356e, 0x356f, 
+    0x3570, 0x3571, 0x3572, 0x3573, 0x3574, 0x3575, 0x3576, 0x3577, 
+    0x3578, 0x3579, 0x357a, 0x357b, 0x357c, 0x357d, 0x357e, 0x357f, 
+    0x3580, 0x3581, 0x3582, 0x3583, 0x3584, 0x3585, 0x3586, 0x3587, 
+    0x3588, 0x3589, 0x358a, 0x358b, 0x358c, 0x358d, 0x358e, 0x358f, 
+    0x3590, 0x3591, 0x3592, 0x3593, 0x3594, 0x3595, 0x3596, 0x3597, 
+    0x3598, 0x3599, 0x359a, 0x359b, 0x359c, 0x359d, 0x359e, 0x359f, 
+    0x35a0, 0x35a1, 0x35a2, 0x35a3, 0x35a4, 0x35a5, 0x35a6, 0x35a7, 
+    0x35a8, 0x35a9, 0x35aa, 0x35ab, 0x35ac, 0x35ad, 0x35ae, 0x35af, 
+    0x35b0, 0x35b1, 0x35b2, 0x35b3, 0x35b4, 0x35b5, 0x35b6, 0x35b7, 
+    0x35b8, 0x35b9, 0x35ba, 0x35bb, 0x35bc, 0x35bd, 0x35be, 0x35bf, 
+    0x35c0, 0x35c1, 0x35c2, 0x35c3, 0x35c4, 0x35c5, 0x35c6, 0x35c7, 
+    0x35c8, 0x35c9, 0x35ca, 0x35cb, 0x35cc, 0x35cd, 0x35ce, 0x35cf, 
+    0x35d0, 0x35d1, 0x35d2, 0x35d3, 0x35d4, 0x35d5, 0x35d6, 0x35d7, 
+    0x35d8, 0x35d9, 0x35da, 0x35db, 0x35dc, 0x35dd, 0x35de, 0x35df, 
+    0x35e0, 0x35e1, 0x35e2, 0x35e3, 0x35e4, 0x35e5, 0x35e6, 0x35e7, 
+    0x35e8, 0x35e9, 0x35ea, 0x35eb, 0x35ec, 0x35ed, 0x35ee, 0x35ef, 
+    0x35f0, 0x35f1, 0x35f2, 0x35f3, 0x35f4, 0x35f5, 0x35f6, 0x35f7, 
+    0x35f8, 0x35f9, 0x35fa, 0x35fb, 0x35fc, 0x35fd, 0x35fe, 0x35ff, 
+    0x3600, 0x3601, 0x3602, 0x3603, 0x3604, 0x3605, 0x3606, 0x3607, 
+    0x3608, 0x3609, 0x360a, 0x360b, 0x360c, 0x360d, 0x360e, 0x360f, 
+    0x3610, 0x3611, 0x3612, 0x3613, 0x3614, 0x3615, 0x3616, 0x3617, 
+    0x3618, 0x3619, 0x361a, 0x361b, 0x361c, 0x361d, 0x361e, 0x361f, 
+    0x3620, 0x3621, 0x3622, 0x3623, 0x3624, 0x3625, 0x3626, 0x3627, 
+    0x3628, 0x3629, 0x362a, 0x362b, 0x362c, 0x362d, 0x362e, 0x362f, 
+    0x3630, 0x3631, 0x3632, 0x3633, 0x3634, 0x3635, 0x3636, 0x3637, 
+    0x3638, 0x3639, 0x363a, 0x363b, 0x363c, 0x363d, 0x363e, 0x363f, 
+    0x3640, 0x3641, 0x3642, 0x3643, 0x3644, 0x3645, 0x3646, 0x3647, 
+    0x3648, 0x3649, 0x364a, 0x364b, 0x364c, 0x364d, 0x364e, 0x364f, 
+    0x3650, 0x3651, 0x3652, 0x3653, 0x3654, 0x3655, 0x3656, 0x3657, 
+    0x3658, 0x3659, 0x365a, 0x365b, 0x365c, 0x365d, 0x365e, 0x365f, 
+    0x3660, 0x3661, 0x3662, 0x3663, 0x3664, 0x3665, 0x3666, 0x3667, 
+    0x3668, 0x3669, 0x366a, 0x366b, 0x366c, 0x366d, 0x366e, 0x366f, 
+    0x3670, 0x3671, 0x3672, 0x3673, 0x3674, 0x3675, 0x3676, 0x3677, 
+    0x3678, 0x3679, 0x367a, 0x367b, 0x367c, 0x367d, 0x367e, 0x367f, 
+    0x3680, 0x3681, 0x3682, 0x3683, 0x3684, 0x3685, 0x3686, 0x3687, 
+    0x3688, 0x3689, 0x368a, 0x368b, 0x368c, 0x368d, 0x368e, 0x368f, 
+    0x3690, 0x3691, 0x3692, 0x3693, 0x3694, 0x3695, 0x3696, 0x3697, 
+    0x3698, 0x3699, 0x369a, 0x369b, 0x369c, 0x369d, 0x369e, 0x369f, 
+    0x36a0, 0x36a1, 0x36a2, 0x36a3, 0x36a4, 0x36a5, 0x36a6, 0x36a7, 
+    0x36a8, 0x36a9, 0x36aa, 0x36ab, 0x36ac, 0x36ad, 0x36ae, 0x36af, 
+    0x36b0, 0x36b1, 0x36b2, 0x36b3, 0x36b4, 0x36b5, 0x36b6, 0x36b7, 
+    0x36b8, 0x36b9, 0x36ba, 0x36bb, 0x36bc, 0x36bd, 0x36be, 0x36bf, 
+    0x36c0, 0x36c1, 0x36c2, 0x36c3, 0x36c4, 0x36c5, 0x36c6, 0x36c7, 
+    0x36c8, 0x36c9, 0x36ca, 0x36cb, 0x36cc, 0x36cd, 0x36ce, 0x36cf, 
+    0x36d0, 0x36d1, 0x36d2, 0x36d3, 0x36d4, 0x36d5, 0x36d6, 0x36d7, 
+    0x36d8, 0x36d9, 0x36da, 0x36db, 0x36dc, 0x36dd, 0x36de, 0x36df, 
+    0x36e0, 0x36e1, 0x36e2, 0x36e3, 0x36e4, 0x36e5, 0x36e6, 0x36e7, 
+    0x36e8, 0x36e9, 0x36ea, 0x36eb, 0x36ec, 0x36ed, 0x36ee, 0x36ef, 
+    0x36f0, 0x36f1, 0x36f2, 0x36f3, 0x36f4, 0x36f5, 0x36f6, 0x36f7, 
+    0x36f8, 0x36f9, 0x36fa, 0x36fb, 0x36fc, 0x36fd, 0x36fe, 0x36ff, 
+    0x3700, 0x3701, 0x3702, 0x3703, 0x3704, 0x3705, 0x3706, 0x3707, 
+    0x3708, 0x3709, 0x370a, 0x370b, 0x370c, 0x370d, 0x370e, 0x370f, 
+    0x3710, 0x3711, 0x3712, 0x3713, 0x3714, 0x3715, 0x3716, 0x3717, 
+    0x3718, 0x3719, 0x371a, 0x371b, 0x371c, 0x371d, 0x371e, 0x371f, 
+    0x3720, 0x3721, 0x3722, 0x3723, 0x3724, 0x3725, 0x3726, 0x3727, 
+    0x3728, 0x3729, 0x372a, 0x372b, 0x372c, 0x372d, 0x372e, 0x372f, 
+    0x3730, 0x3731, 0x3732, 0x3733, 0x3734, 0x3735, 0x3736, 0x3737, 
+    0x3738, 0x3739, 0x373a, 0x373b, 0x373c, 0x373d, 0x373e, 0x373f, 
+    0x3740, 0x3741, 0x3742, 0x3743, 0x3744, 0x3745, 0x3746, 0x3747, 
+    0x3748, 0x3749, 0x374a, 0x374b, 0x374c, 0x374d, 0x374e, 0x374f, 
+    0x3750, 0x3751, 0x3752, 0x3753, 0x3754, 0x3755, 0x3756, 0x3757, 
+    0x3758, 0x3759, 0x375a, 0x375b, 0x375c, 0x375d, 0x375e, 0x375f, 
+    0x3760, 0x3761, 0x3762, 0x3763, 0x3764, 0x3765, 0x3766, 0x3767, 
+    0x3768, 0x3769, 0x376a, 0x376b, 0x376c, 0x376d, 0x376e, 0x376f, 
+    0x3770, 0x3771, 0x3772, 0x3773, 0x3774, 0x3775, 0x3776, 0x3777, 
+    0x3778, 0x3779, 0x377a, 0x377b, 0x377c, 0x377d, 0x377e, 0x377f, 
+    0x3780, 0x3781, 0x3782, 0x3783, 0x3784, 0x3785, 0x3786, 0x3787, 
+    0x3788, 0x3789, 0x378a, 0x378b, 0x378c, 0x378d, 0x378e, 0x378f, 
+    0x3790, 0x3791, 0x3792, 0x3793, 0x3794, 0x3795, 0x3796, 0x3797, 
+    0x3798, 0x3799, 0x379a, 0x379b, 0x379c, 0x379d, 0x379e, 0x379f, 
+    0x37a0, 0x37a1, 0x37a2, 0x37a3, 0x37a4, 0x37a5, 0x37a6, 0x37a7, 
+    0x37a8, 0x37a9, 0x37aa, 0x37ab, 0x37ac, 0x37ad, 0x37ae, 0x37af, 
+    0x37b0, 0x37b1, 0x37b2, 0x37b3, 0x37b4, 0x37b5, 0x37b6, 0x37b7, 
+    0x37b8, 0x37b9, 0x37ba, 0x37bb, 0x37bc, 0x37bd, 0x37be, 0x37bf, 
+    0x37c0, 0x37c1, 0x37c2, 0x37c3, 0x37c4, 0x37c5, 0x37c6, 0x37c7, 
+    0x37c8, 0x37c9, 0x37ca, 0x37cb, 0x37cc, 0x37cd, 0x37ce, 0x37cf, 
+    0x37d0, 0x37d1, 0x37d2, 0x37d3, 0x37d4, 0x37d5, 0x37d6, 0x37d7, 
+    0x37d8, 0x37d9, 0x37da, 0x37db, 0x37dc, 0x37dd, 0x37de, 0x37df, 
+    0x37e0, 0x37e1, 0x37e2, 0x37e3, 0x37e4, 0x37e5, 0x37e6, 0x37e7, 
+    0x37e8, 0x37e9, 0x37ea, 0x37eb, 0x37ec, 0x37ed, 0x37ee, 0x37ef, 
+    0x37f0, 0x37f1, 0x37f2, 0x37f3, 0x37f4, 0x37f5, 0x37f6, 0x37f7, 
+    0x37f8, 0x37f9, 0x37fa, 0x37fb, 0x37fc, 0x37fd, 0x37fe, 0x37ff, 
+    0x3800, 0x3801, 0x3802, 0x3803, 0x3804, 0x3805, 0x3806, 0x3807, 
+    0x3808, 0x3809, 0x380a, 0x380b, 0x380c, 0x380d, 0x380e, 0x380f, 
+    0x3810, 0x3811, 0x3812, 0x3813, 0x3814, 0x3815, 0x3816, 0x3817, 
+    0x3818, 0x3819, 0x381a, 0x381b, 0x381c, 0x381d, 0x381e, 0x381f, 
+    0x3820, 0x3821, 0x3822, 0x3823, 0x3824, 0x3825, 0x3826, 0x3827, 
+    0x3828, 0x3829, 0x382a, 0x382b, 0x382c, 0x382d, 0x382e, 0x382f, 
+    0x3830, 0x3831, 0x3832, 0x3833, 0x3834, 0x3835, 0x3836, 0x3837, 
+    0x3838, 0x3839, 0x383a, 0x383b, 0x383c, 0x383d, 0x383e, 0x383f, 
+    0x3840, 0x3841, 0x3842, 0x3843, 0x3844, 0x3845, 0x3846, 0x3847, 
+    0x3848, 0x3849, 0x384a, 0x384b, 0x384c, 0x384d, 0x384e, 0x384f, 
+    0x3850, 0x3851, 0x3852, 0x3853, 0x3854, 0x3855, 0x3856, 0x3857, 
+    0x3858, 0x3859, 0x385a, 0x385b, 0x385c, 0x385d, 0x385e, 0x385f, 
+    0x3860, 0x3861, 0x3862, 0x3863, 0x3864, 0x3865, 0x3866, 0x3867, 
+    0x3868, 0x3869, 0x386a, 0x386b, 0x386c, 0x386d, 0x386e, 0x386f, 
+    0x3870, 0x3871, 0x3872, 0x3873, 0x3874, 0x3875, 0x3876, 0x3877, 
+    0x3878, 0x3879, 0x387a, 0x387b, 0x387c, 0x387d, 0x387e, 0x387f, 
+    0x3880, 0x3881, 0x3882, 0x3883, 0x3884, 0x3885, 0x3886, 0x3887, 
+    0x3888, 0x3889, 0x388a, 0x388b, 0x388c, 0x388d, 0x388e, 0x388f, 
+    0x3890, 0x3891, 0x3892, 0x3893, 0x3894, 0x3895, 0x3896, 0x3897, 
+    0x3898, 0x3899, 0x389a, 0x389b, 0x389c, 0x389d, 0x389e, 0x389f, 
+    0x38a0, 0x38a1, 0x38a2, 0x38a3, 0x38a4, 0x38a5, 0x38a6, 0x38a7, 
+    0x38a8, 0x38a9, 0x38aa, 0x38ab, 0x38ac, 0x38ad, 0x38ae, 0x38af, 
+    0x38b0, 0x38b1, 0x38b2, 0x38b3, 0x38b4, 0x38b5, 0x38b6, 0x38b7, 
+    0x38b8, 0x38b9, 0x38ba, 0x38bb, 0x38bc, 0x38bd, 0x38be, 0x38bf, 
+    0x38c0, 0x38c1, 0x38c2, 0x38c3, 0x38c4, 0x38c5, 0x38c6, 0x38c7, 
+    0x38c8, 0x38c9, 0x38ca, 0x38cb, 0x38cc, 0x38cd, 0x38ce, 0x38cf, 
+    0x38d0, 0x38d1, 0x38d2, 0x38d3, 0x38d4, 0x38d5, 0x38d6, 0x38d7, 
+    0x38d8, 0x38d9, 0x38da, 0x38db, 0x38dc, 0x38dd, 0x38de, 0x38df, 
+    0x38e0, 0x38e1, 0x38e2, 0x38e3, 0x38e4, 0x38e5, 0x38e6, 0x38e7, 
+    0x38e8, 0x38e9, 0x38ea, 0x38eb, 0x38ec, 0x38ed, 0x38ee, 0x38ef, 
+    0x38f0, 0x38f1, 0x38f2, 0x38f3, 0x38f4, 0x38f5, 0x38f6, 0x38f7, 
+    0x38f8, 0x38f9, 0x38fa, 0x38fb, 0x38fc, 0x38fd, 0x38fe, 0x38ff, 
+    0x3900, 0x3901, 0x3902, 0x3903, 0x3904, 0x3905, 0x3906, 0x3907, 
+    0x3908, 0x3909, 0x390a, 0x390b, 0x390c, 0x390d, 0x390e, 0x390f, 
+    0x3910, 0x3911, 0x3912, 0x3913, 0x3914, 0x3915, 0x3916, 0x3917, 
+    0x3918, 0x3919, 0x391a, 0x391b, 0x391c, 0x391d, 0x391e, 0x391f, 
+    0x3920, 0x3921, 0x3922, 0x3923, 0x3924, 0x3925, 0x3926, 0x3927, 
+    0x3928, 0x3929, 0x392a, 0x392b, 0x392c, 0x392d, 0x392e, 0x392f, 
+    0x3930, 0x3931, 0x3932, 0x3933, 0x3934, 0x3935, 0x3936, 0x3937, 
+    0x3938, 0x3939, 0x393a, 0x393b, 0x393c, 0x393d, 0x393e, 0x393f, 
+    0x3940, 0x3941, 0x3942, 0x3943, 0x3944, 0x3945, 0x3946, 0x3947, 
+    0x3948, 0x3949, 0x394a, 0x394b, 0x394c, 0x394d, 0x394e, 0x394f, 
+    0x3950, 0x3951, 0x3952, 0x3953, 0x3954, 0x3955, 0x3956, 0x3957, 
+    0x3958, 0x3959, 0x395a, 0x395b, 0x395c, 0x395d, 0x395e, 0x395f, 
+    0x3960, 0x3961, 0x3962, 0x3963, 0x3964, 0x3965, 0x3966, 0x3967, 
+    0x3968, 0x3969, 0x396a, 0x396b, 0x396c, 0x396d, 0x396e, 0x396f, 
+    0x3970, 0x3971, 0x3972, 0x3973, 0x3974, 0x3975, 0x3976, 0x3977, 
+    0x3978, 0x3979, 0x397a, 0x397b, 0x397c, 0x397d, 0x397e, 0x397f, 
+    0x3980, 0x3981, 0x3982, 0x3983, 0x3984, 0x3985, 0x3986, 0x3987, 
+    0x3988, 0x3989, 0x398a, 0x398b, 0x398c, 0x398d, 0x398e, 0x398f, 
+    0x3990, 0x3991, 0x3992, 0x3993, 0x3994, 0x3995, 0x3996, 0x3997, 
+    0x3998, 0x3999, 0x399a, 0x399b, 0x399c, 0x399d, 0x399e, 0x399f, 
+    0x39a0, 0x39a1, 0x39a2, 0x39a3, 0x39a4, 0x39a5, 0x39a6, 0x39a7, 
+    0x39a8, 0x39a9, 0x39aa, 0x39ab, 0x39ac, 0x39ad, 0x39ae, 0x39af, 
+    0x39b0, 0x39b1, 0x39b2, 0x39b3, 0x39b4, 0x39b5, 0x39b6, 0x39b7, 
+    0x39b8, 0x39b9, 0x39ba, 0x39bb, 0x39bc, 0x39bd, 0x39be, 0x39bf, 
+    0x39c0, 0x39c1, 0x39c2, 0x39c3, 0x39c4, 0x39c5, 0x39c6, 0x39c7, 
+    0x39c8, 0x39c9, 0x39ca, 0x39cb, 0x39cc, 0x39cd, 0x39ce, 0x39cf, 
+    0x39d0, 0x39d1, 0x39d2, 0x39d3, 0x39d4, 0x39d5, 0x39d6, 0x39d7, 
+    0x39d8, 0x39d9, 0x39da, 0x39db, 0x39dc, 0x39dd, 0x39de, 0x39df, 
+    0x39e0, 0x39e1, 0x39e2, 0x39e3, 0x39e4, 0x39e5, 0x39e6, 0x39e7, 
+    0x39e8, 0x39e9, 0x39ea, 0x39eb, 0x39ec, 0x39ed, 0x39ee, 0x39ef, 
+    0x39f0, 0x39f1, 0x39f2, 0x39f3, 0x39f4, 0x39f5, 0x39f6, 0x39f7, 
+    0x39f8, 0x39f9, 0x39fa, 0x39fb, 0x39fc, 0x39fd, 0x39fe, 0x39ff, 
+    0x3a00, 0x3a01, 0x3a02, 0x3a03, 0x3a04, 0x3a05, 0x3a06, 0x3a07, 
+    0x3a08, 0x3a09, 0x3a0a, 0x3a0b, 0x3a0c, 0x3a0d, 0x3a0e, 0x3a0f, 
+    0x3a10, 0x3a11, 0x3a12, 0x3a13, 0x3a14, 0x3a15, 0x3a16, 0x3a17, 
+    0x3a18, 0x3a19, 0x3a1a, 0x3a1b, 0x3a1c, 0x3a1d, 0x3a1e, 0x3a1f, 
+    0x3a20, 0x3a21, 0x3a22, 0x3a23, 0x3a24, 0x3a25, 0x3a26, 0x3a27, 
+    0x3a28, 0x3a29, 0x3a2a, 0x3a2b, 0x3a2c, 0x3a2d, 0x3a2e, 0x3a2f, 
+    0x3a30, 0x3a31, 0x3a32, 0x3a33, 0x3a34, 0x3a35, 0x3a36, 0x3a37, 
+    0x3a38, 0x3a39, 0x3a3a, 0x3a3b, 0x3a3c, 0x3a3d, 0x3a3e, 0x3a3f, 
+    0x3a40, 0x3a41, 0x3a42, 0x3a43, 0x3a44, 0x3a45, 0x3a46, 0x3a47, 
+    0x3a48, 0x3a49, 0x3a4a, 0x3a4b, 0x3a4c, 0x3a4d, 0x3a4e, 0x3a4f, 
+    0x3a50, 0x3a51, 0x3a52, 0x3a53, 0x3a54, 0x3a55, 0x3a56, 0x3a57, 
+    0x3a58, 0x3a59, 0x3a5a, 0x3a5b, 0x3a5c, 0x3a5d, 0x3a5e, 0x3a5f, 
+    0x3a60, 0x3a61, 0x3a62, 0x3a63, 0x3a64, 0x3a65, 0x3a66, 0x3a67, 
+    0x3a68, 0x3a69, 0x3a6a, 0x3a6b, 0x3a6c, 0x3a6d, 0x3a6e, 0x3a6f, 
+    0x3a70, 0x3a71, 0x3a72, 0x3a73, 0x3a74, 0x3a75, 0x3a76, 0x3a77, 
+    0x3a78, 0x3a79, 0x3a7a, 0x3a7b, 0x3a7c, 0x3a7d, 0x3a7e, 0x3a7f, 
+    0x3a80, 0x3a81, 0x3a82, 0x3a83, 0x3a84, 0x3a85, 0x3a86, 0x3a87, 
+    0x3a88, 0x3a89, 0x3a8a, 0x3a8b, 0x3a8c, 0x3a8d, 0x3a8e, 0x3a8f, 
+    0x3a90, 0x3a91, 0x3a92, 0x3a93, 0x3a94, 0x3a95, 0x3a96, 0x3a97, 
+    0x3a98, 0x3a99, 0x3a9a, 0x3a9b, 0x3a9c, 0x3a9d, 0x3a9e, 0x3a9f, 
+    0x3aa0, 0x3aa1, 0x3aa2, 0x3aa3, 0x3aa4, 0x3aa5, 0x3aa6, 0x3aa7, 
+    0x3aa8, 0x3aa9, 0x3aaa, 0x3aab, 0x3aac, 0x3aad, 0x3aae, 0x3aaf, 
+    0x3ab0, 0x3ab1, 0x3ab2, 0x3ab3, 0x3ab4, 0x3ab5, 0x3ab6, 0x3ab7, 
+    0x3ab8, 0x3ab9, 0x3aba, 0x3abb, 0x3abc, 0x3abd, 0x3abe, 0x3abf, 
+    0x3ac0, 0x3ac1, 0x3ac2, 0x3ac3, 0x3ac4, 0x3ac5, 0x3ac6, 0x3ac7, 
+    0x3ac8, 0x3ac9, 0x3aca, 0x3acb, 0x3acc, 0x3acd, 0x3ace, 0x3acf, 
+    0x3ad0, 0x3ad1, 0x3ad2, 0x3ad3, 0x3ad4, 0x3ad5, 0x3ad6, 0x3ad7, 
+    0x3ad8, 0x3ad9, 0x3ada, 0x3adb, 0x3adc, 0x3add, 0x3ade, 0x3adf, 
+    0x3ae0, 0x3ae1, 0x3ae2, 0x3ae3, 0x3ae4, 0x3ae5, 0x3ae6, 0x3ae7, 
+    0x3ae8, 0x3ae9, 0x3aea, 0x3aeb, 0x3aec, 0x3aed, 0x3aee, 0x3aef, 
+    0x3af0, 0x3af1, 0x3af2, 0x3af3, 0x3af4, 0x3af5, 0x3af6, 0x3af7, 
+    0x3af8, 0x3af9, 0x3afa, 0x3afb, 0x3afc, 0x3afd, 0x3afe, 0x3aff, 
+    0x3b00, 0x3b01, 0x3b02, 0x3b03, 0x3b04, 0x3b05, 0x3b06, 0x3b07, 
+    0x3b08, 0x3b09, 0x3b0a, 0x3b0b, 0x3b0c, 0x3b0d, 0x3b0e, 0x3b0f, 
+    0x3b10, 0x3b11, 0x3b12, 0x3b13, 0x3b14, 0x3b15, 0x3b16, 0x3b17, 
+    0x3b18, 0x3b19, 0x3b1a, 0x3b1b, 0x3b1c, 0x3b1d, 0x3b1e, 0x3b1f, 
+    0x3b20, 0x3b21, 0x3b22, 0x3b23, 0x3b24, 0x3b25, 0x3b26, 0x3b27, 
+    0x3b28, 0x3b29, 0x3b2a, 0x3b2b, 0x3b2c, 0x3b2d, 0x3b2e, 0x3b2f, 
+    0x3b30, 0x3b31, 0x3b32, 0x3b33, 0x3b34, 0x3b35, 0x3b36, 0x3b37, 
+    0x3b38, 0x3b39, 0x3b3a, 0x3b3b, 0x3b3c, 0x3b3d, 0x3b3e, 0x3b3f, 
+    0x3b40, 0x3b41, 0x3b42, 0x3b43, 0x3b44, 0x3b45, 0x3b46, 0x3b47, 
+    0x3b48, 0x3b49, 0x3b4a, 0x3b4b, 0x3b4c, 0x3b4d, 0x3b4e, 0x3b4f, 
+    0x3b50, 0x3b51, 0x3b52, 0x3b53, 0x3b54, 0x3b55, 0x3b56, 0x3b57, 
+    0x3b58, 0x3b59, 0x3b5a, 0x3b5b, 0x3b5c, 0x3b5d, 0x3b5e, 0x3b5f, 
+    0x3b60, 0x3b61, 0x3b62, 0x3b63, 0x3b64, 0x3b65, 0x3b66, 0x3b67, 
+    0x3b68, 0x3b69, 0x3b6a, 0x3b6b, 0x3b6c, 0x3b6d, 0x3b6e, 0x3b6f, 
+    0x3b70, 0x3b71, 0x3b72, 0x3b73, 0x3b74, 0x3b75, 0x3b76, 0x3b77, 
+    0x3b78, 0x3b79, 0x3b7a, 0x3b7b, 0x3b7c, 0x3b7d, 0x3b7e, 0x3b7f, 
+    0x3b80, 0x3b81, 0x3b82, 0x3b83, 0x3b84, 0x3b85, 0x3b86, 0x3b87, 
+    0x3b88, 0x3b89, 0x3b8a, 0x3b8b, 0x3b8c, 0x3b8d, 0x3b8e, 0x3b8f, 
+    0x3b90, 0x3b91, 0x3b92, 0x3b93, 0x3b94, 0x3b95, 0x3b96, 0x3b97, 
+    0x3b98, 0x3b99, 0x3b9a, 0x3b9b, 0x3b9c, 0x3b9d, 0x3b9e, 0x3b9f, 
+    0x3ba0, 0x3ba1, 0x3ba2, 0x3ba3, 0x3ba4, 0x3ba5, 0x3ba6, 0x3ba7, 
+    0x3ba8, 0x3ba9, 0x3baa, 0x3bab, 0x3bac, 0x3bad, 0x3bae, 0x3baf, 
+    0x3bb0, 0x3bb1, 0x3bb2, 0x3bb3, 0x3bb4, 0x3bb5, 0x3bb6, 0x3bb7, 
+    0x3bb8, 0x3bb9, 0x3bba, 0x3bbb, 0x3bbc, 0x3bbd, 0x3bbe, 0x3bbf, 
+    0x3bc0, 0x3bc1, 0x3bc2, 0x3bc3, 0x3bc4, 0x3bc5, 0x3bc6, 0x3bc7, 
+    0x3bc8, 0x3bc9, 0x3bca, 0x3bcb, 0x3bcc, 0x3bcd, 0x3bce, 0x3bcf, 
+    0x3bd0, 0x3bd1, 0x3bd2, 0x3bd3, 0x3bd4, 0x3bd5, 0x3bd6, 0x3bd7, 
+    0x3bd8, 0x3bd9, 0x3bda, 0x3bdb, 0x3bdc, 0x3bdd, 0x3bde, 0x3bdf, 
+    0x3be0, 0x3be1, 0x3be2, 0x3be3, 0x3be4, 0x3be5, 0x3be6, 0x3be7, 
+    0x3be8, 0x3be9, 0x3bea, 0x3beb, 0x3bec, 0x3bed, 0x3bee, 0x3bef, 
+    0x3bf0, 0x3bf1, 0x3bf2, 0x3bf3, 0x3bf4, 0x3bf5, 0x3bf6, 0x3bf7, 
+    0x3bf8, 0x3bf9, 0x3bfa, 0x3bfb, 0x3bfc, 0x3bfd, 0x3bfe, 0x3bff, 
+    0x3c00, 0x3c01, 0x3c02, 0x3c03, 0x3c04, 0x3c05, 0x3c06, 0x3c07, 
+    0x3c08, 0x3c09, 0x3c0a, 0x3c0b, 0x3c0c, 0x3c0d, 0x3c0e, 0x3c0f, 
+    0x3c10, 0x3c11, 0x3c12, 0x3c13, 0x3c14, 0x3c15, 0x3c16, 0x3c17, 
+    0x3c18, 0x3c19, 0x3c1a, 0x3c1b, 0x3c1c, 0x3c1d, 0x3c1e, 0x3c1f, 
+    0x3c20, 0x3c21, 0x3c22, 0x3c23, 0x3c24, 0x3c25, 0x3c26, 0x3c27, 
+    0x3c28, 0x3c29, 0x3c2a, 0x3c2b, 0x3c2c, 0x3c2d, 0x3c2e, 0x3c2f, 
+    0x3c30, 0x3c31, 0x3c32, 0x3c33, 0x3c34, 0x3c35, 0x3c36, 0x3c37, 
+    0x3c38, 0x3c39, 0x3c3a, 0x3c3b, 0x3c3c, 0x3c3d, 0x3c3e, 0x3c3f, 
+    0x3c40, 0x3c41, 0x3c42, 0x3c43, 0x3c44, 0x3c45, 0x3c46, 0x3c47, 
+    0x3c48, 0x3c49, 0x3c4a, 0x3c4b, 0x3c4c, 0x3c4d, 0x3c4e, 0x3c4f, 
+    0x3c50, 0x3c51, 0x3c52, 0x3c53, 0x3c54, 0x3c55, 0x3c56, 0x3c57, 
+    0x3c58, 0x3c59, 0x3c5a, 0x3c5b, 0x3c5c, 0x3c5d, 0x3c5e, 0x3c5f, 
+    0x3c60, 0x3c61, 0x3c62, 0x3c63, 0x3c64, 0x3c65, 0x3c66, 0x3c67, 
+    0x3c68, 0x3c69, 0x3c6a, 0x3c6b, 0x3c6c, 0x3c6d, 0x3c6e, 0x3c6f, 
+    0x3c70, 0x3c71, 0x3c72, 0x3c73, 0x3c74, 0x3c75, 0x3c76, 0x3c77, 
+    0x3c78, 0x3c79, 0x3c7a, 0x3c7b, 0x3c7c, 0x3c7d, 0x3c7e, 0x3c7f, 
+    0x3c80, 0x3c81, 0x3c82, 0x3c83, 0x3c84, 0x3c85, 0x3c86, 0x3c87, 
+    0x3c88, 0x3c89, 0x3c8a, 0x3c8b, 0x3c8c, 0x3c8d, 0x3c8e, 0x3c8f, 
+    0x3c90, 0x3c91, 0x3c92, 0x3c93, 0x3c94, 0x3c95, 0x3c96, 0x3c97, 
+    0x3c98, 0x3c99, 0x3c9a, 0x3c9b, 0x3c9c, 0x3c9d, 0x3c9e, 0x3c9f, 
+    0x3ca0, 0x3ca1, 0x3ca2, 0x3ca3, 0x3ca4, 0x3ca5, 0x3ca6, 0x3ca7, 
+    0x3ca8, 0x3ca9, 0x3caa, 0x3cab, 0x3cac, 0x3cad, 0x3cae, 0x3caf, 
+    0x3cb0, 0x3cb1, 0x3cb2, 0x3cb3, 0x3cb4, 0x3cb5, 0x3cb6, 0x3cb7, 
+    0x3cb8, 0x3cb9, 0x3cba, 0x3cbb, 0x3cbc, 0x3cbd, 0x3cbe, 0x3cbf, 
+    0x3cc0, 0x3cc1, 0x3cc2, 0x3cc3, 0x3cc4, 0x3cc5, 0x3cc6, 0x3cc7, 
+    0x3cc8, 0x3cc9, 0x3cca, 0x3ccb, 0x3ccc, 0x3ccd, 0x3cce, 0x3ccf, 
+    0x3cd0, 0x3cd1, 0x3cd2, 0x3cd3, 0x3cd4, 0x3cd5, 0x3cd6, 0x3cd7, 
+    0x3cd8, 0x3cd9, 0x3cda, 0x3cdb, 0x3cdc, 0x3cdd, 0x3cde, 0x3cdf, 
+    0x3ce0, 0x3ce1, 0x3ce2, 0x3ce3, 0x3ce4, 0x3ce5, 0x3ce6, 0x3ce7, 
+    0x3ce8, 0x3ce9, 0x3cea, 0x3ceb, 0x3cec, 0x3ced, 0x3cee, 0x3cef, 
+    0x3cf0, 0x3cf1, 0x3cf2, 0x3cf3, 0x3cf4, 0x3cf5, 0x3cf6, 0x3cf7, 
+    0x3cf8, 0x3cf9, 0x3cfa, 0x3cfb, 0x3cfc, 0x3cfd, 0x3cfe, 0x3cff, 
+    0x3d00, 0x3d01, 0x3d02, 0x3d03, 0x3d04, 0x3d05, 0x3d06, 0x3d07, 
+    0x3d08, 0x3d09, 0x3d0a, 0x3d0b, 0x3d0c, 0x3d0d, 0x3d0e, 0x3d0f, 
+    0x3d10, 0x3d11, 0x3d12, 0x3d13, 0x3d14, 0x3d15, 0x3d16, 0x3d17, 
+    0x3d18, 0x3d19, 0x3d1a, 0x3d1b, 0x3d1c, 0x3d1d, 0x3d1e, 0x3d1f, 
+    0x3d20, 0x3d21, 0x3d22, 0x3d23, 0x3d24, 0x3d25, 0x3d26, 0x3d27, 
+    0x3d28, 0x3d29, 0x3d2a, 0x3d2b, 0x3d2c, 0x3d2d, 0x3d2e, 0x3d2f, 
+    0x3d30, 0x3d31, 0x3d32, 0x3d33, 0x3d34, 0x3d35, 0x3d36, 0x3d37, 
+    0x3d38, 0x3d39, 0x3d3a, 0x3d3b, 0x3d3c, 0x3d3d, 0x3d3e, 0x3d3f, 
+    0x3d40, 0x3d41, 0x3d42, 0x3d43, 0x3d44, 0x3d45, 0x3d46, 0x3d47, 
+    0x3d48, 0x3d49, 0x3d4a, 0x3d4b, 0x3d4c, 0x3d4d, 0x3d4e, 0x3d4f, 
+    0x3d50, 0x3d51, 0x3d52, 0x3d53, 0x3d54, 0x3d55, 0x3d56, 0x3d57, 
+    0x3d58, 0x3d59, 0x3d5a, 0x3d5b, 0x3d5c, 0x3d5d, 0x3d5e, 0x3d5f, 
+    0x3d60, 0x3d61, 0x3d62, 0x3d63, 0x3d64, 0x3d65, 0x3d66, 0x3d67, 
+    0x3d68, 0x3d69, 0x3d6a, 0x3d6b, 0x3d6c, 0x3d6d, 0x3d6e, 0x3d6f, 
+    0x3d70, 0x3d71, 0x3d72, 0x3d73, 0x3d74, 0x3d75, 0x3d76, 0x3d77, 
+    0x3d78, 0x3d79, 0x3d7a, 0x3d7b, 0x3d7c, 0x3d7d, 0x3d7e, 0x3d7f, 
+    0x3d80, 0x3d81, 0x3d82, 0x3d83, 0x3d84, 0x3d85, 0x3d86, 0x3d87, 
+    0x3d88, 0x3d89, 0x3d8a, 0x3d8b, 0x3d8c, 0x3d8d, 0x3d8e, 0x3d8f, 
+    0x3d90, 0x3d91, 0x3d92, 0x3d93, 0x3d94, 0x3d95, 0x3d96, 0x3d97, 
+    0x3d98, 0x3d99, 0x3d9a, 0x3d9b, 0x3d9c, 0x3d9d, 0x3d9e, 0x3d9f, 
+    0x3da0, 0x3da1, 0x3da2, 0x3da3, 0x3da4, 0x3da5, 0x3da6, 0x3da7, 
+    0x3da8, 0x3da9, 0x3daa, 0x3dab, 0x3dac, 0x3dad, 0x3dae, 0x3daf, 
+    0x3db0, 0x3db1, 0x3db2, 0x3db3, 0x3db4, 0x3db5, 0x3db6, 0x3db7, 
+    0x3db8, 0x3db9, 0x3dba, 0x3dbb, 0x3dbc, 0x3dbd, 0x3dbe, 0x3dbf, 
+    0x3dc0, 0x3dc1, 0x3dc2, 0x3dc3, 0x3dc4, 0x3dc5, 0x3dc6, 0x3dc7, 
+    0x3dc8, 0x3dc9, 0x3dca, 0x3dcb, 0x3dcc, 0x3dcd, 0x3dce, 0x3dcf, 
+    0x3dd0, 0x3dd1, 0x3dd2, 0x3dd3, 0x3dd4, 0x3dd5, 0x3dd6, 0x3dd7, 
+    0x3dd8, 0x3dd9, 0x3dda, 0x3ddb, 0x3ddc, 0x3ddd, 0x3dde, 0x3ddf, 
+    0x3de0, 0x3de1, 0x3de2, 0x3de3, 0x3de4, 0x3de5, 0x3de6, 0x3de7, 
+    0x3de8, 0x3de9, 0x3dea, 0x3deb, 0x3dec, 0x3ded, 0x3dee, 0x3def, 
+    0x3df0, 0x3df1, 0x3df2, 0x3df3, 0x3df4, 0x3df5, 0x3df6, 0x3df7, 
+    0x3df8, 0x3df9, 0x3dfa, 0x3dfb, 0x3dfc, 0x3dfd, 0x3dfe, 0x3dff, 
+    0x3e00, 0x3e01, 0x3e02, 0x3e03, 0x3e04, 0x3e05, 0x3e06, 0x3e07, 
+    0x3e08, 0x3e09, 0x3e0a, 0x3e0b, 0x3e0c, 0x3e0d, 0x3e0e, 0x3e0f, 
+    0x3e10, 0x3e11, 0x3e12, 0x3e13, 0x3e14, 0x3e15, 0x3e16, 0x3e17, 
+    0x3e18, 0x3e19, 0x3e1a, 0x3e1b, 0x3e1c, 0x3e1d, 0x3e1e, 0x3e1f, 
+    0x3e20, 0x3e21, 0x3e22, 0x3e23, 0x3e24, 0x3e25, 0x3e26, 0x3e27, 
+    0x3e28, 0x3e29, 0x3e2a, 0x3e2b, 0x3e2c, 0x3e2d, 0x3e2e, 0x3e2f, 
+    0x3e30, 0x3e31, 0x3e32, 0x3e33, 0x3e34, 0x3e35, 0x3e36, 0x3e37, 
+    0x3e38, 0x3e39, 0x3e3a, 0x3e3b, 0x3e3c, 0x3e3d, 0x3e3e, 0x3e3f, 
+    0x3e40, 0x3e41, 0x3e42, 0x3e43, 0x3e44, 0x3e45, 0x3e46, 0x3e47, 
+    0x3e48, 0x3e49, 0x3e4a, 0x3e4b, 0x3e4c, 0x3e4d, 0x3e4e, 0x3e4f, 
+    0x3e50, 0x3e51, 0x3e52, 0x3e53, 0x3e54, 0x3e55, 0x3e56, 0x3e57, 
+    0x3e58, 0x3e59, 0x3e5a, 0x3e5b, 0x3e5c, 0x3e5d, 0x3e5e, 0x3e5f, 
+    0x3e60, 0x3e61, 0x3e62, 0x3e63, 0x3e64, 0x3e65, 0x3e66, 0x3e67, 
+    0x3e68, 0x3e69, 0x3e6a, 0x3e6b, 0x3e6c, 0x3e6d, 0x3e6e, 0x3e6f, 
+    0x3e70, 0x3e71, 0x3e72, 0x3e73, 0x3e74, 0x3e75, 0x3e76, 0x3e77, 
+    0x3e78, 0x3e79, 0x3e7a, 0x3e7b, 0x3e7c, 0x3e7d, 0x3e7e, 0x3e7f, 
+    0x3e80, 0x3e81, 0x3e82, 0x3e83, 0x3e84, 0x3e85, 0x3e86, 0x3e87, 
+    0x3e88, 0x3e89, 0x3e8a, 0x3e8b, 0x3e8c, 0x3e8d, 0x3e8e, 0x3e8f, 
+    0x3e90, 0x3e91, 0x3e92, 0x3e93, 0x3e94, 0x3e95, 0x3e96, 0x3e97, 
+    0x3e98, 0x3e99, 0x3e9a, 0x3e9b, 0x3e9c, 0x3e9d, 0x3e9e, 0x3e9f, 
+    0x3ea0, 0x3ea1, 0x3ea2, 0x3ea3, 0x3ea4, 0x3ea5, 0x3ea6, 0x3ea7, 
+    0x3ea8, 0x3ea9, 0x3eaa, 0x3eab, 0x3eac, 0x3ead, 0x3eae, 0x3eaf, 
+    0x3eb0, 0x3eb1, 0x3eb2, 0x3eb3, 0x3eb4, 0x3eb5, 0x3eb6, 0x3eb7, 
+    0x3eb8, 0x3eb9, 0x3eba, 0x3ebb, 0x3ebc, 0x3ebd, 0x3ebe, 0x3ebf, 
+    0x3ec0, 0x3ec1, 0x3ec2, 0x3ec3, 0x3ec4, 0x3ec5, 0x3ec6, 0x3ec7, 
+    0x3ec8, 0x3ec9, 0x3eca, 0x3ecb, 0x3ecc, 0x3ecd, 0x3ece, 0x3ecf, 
+    0x3ed0, 0x3ed1, 0x3ed2, 0x3ed3, 0x3ed4, 0x3ed5, 0x3ed6, 0x3ed7, 
+    0x3ed8, 0x3ed9, 0x3eda, 0x3edb, 0x3edc, 0x3edd, 0x3ede, 0x3edf, 
+    0x3ee0, 0x3ee1, 0x3ee2, 0x3ee3, 0x3ee4, 0x3ee5, 0x3ee6, 0x3ee7, 
+    0x3ee8, 0x3ee9, 0x3eea, 0x3eeb, 0x3eec, 0x3eed, 0x3eee, 0x3eef, 
+    0x3ef0, 0x3ef1, 0x3ef2, 0x3ef3, 0x3ef4, 0x3ef5, 0x3ef6, 0x3ef7, 
+    0x3ef8, 0x3ef9, 0x3efa, 0x3efb, 0x3efc, 0x3efd, 0x3efe, 0x3eff, 
+    0x3f00, 0x3f01, 0x3f02, 0x3f03, 0x3f04, 0x3f05, 0x3f06, 0x3f07, 
+    0x3f08, 0x3f09, 0x3f0a, 0x3f0b, 0x3f0c, 0x3f0d, 0x3f0e, 0x3f0f, 
+    0x3f10, 0x3f11, 0x3f12, 0x3f13, 0x3f14, 0x3f15, 0x3f16, 0x3f17, 
+    0x3f18, 0x3f19, 0x3f1a, 0x3f1b, 0x3f1c, 0x3f1d, 0x3f1e, 0x3f1f, 
+    0x3f20, 0x3f21, 0x3f22, 0x3f23, 0x3f24, 0x3f25, 0x3f26, 0x3f27, 
+    0x3f28, 0x3f29, 0x3f2a, 0x3f2b, 0x3f2c, 0x3f2d, 0x3f2e, 0x3f2f, 
+    0x3f30, 0x3f31, 0x3f32, 0x3f33, 0x3f34, 0x3f35, 0x3f36, 0x3f37, 
+    0x3f38, 0x3f39, 0x3f3a, 0x3f3b, 0x3f3c, 0x3f3d, 0x3f3e, 0x3f3f, 
+    0x3f40, 0x3f41, 0x3f42, 0x3f43, 0x3f44, 0x3f45, 0x3f46, 0x3f47, 
+    0x3f48, 0x3f49, 0x3f4a, 0x3f4b, 0x3f4c, 0x3f4d, 0x3f4e, 0x3f4f, 
+    0x3f50, 0x3f51, 0x3f52, 0x3f53, 0x3f54, 0x3f55, 0x3f56, 0x3f57, 
+    0x3f58, 0x3f59, 0x3f5a, 0x3f5b, 0x3f5c, 0x3f5d, 0x3f5e, 0x3f5f, 
+    0x3f60, 0x3f61, 0x3f62, 0x3f63, 0x3f64, 0x3f65, 0x3f66, 0x3f67, 
+    0x3f68, 0x3f69, 0x3f6a, 0x3f6b, 0x3f6c, 0x3f6d, 0x3f6e, 0x3f6f, 
+    0x3f70, 0x3f71, 0x3f72, 0x3f73, 0x3f74, 0x3f75, 0x3f76, 0x3f77, 
+    0x3f78, 0x3f79, 0x3f7a, 0x3f7b, 0x3f7c, 0x3f7d, 0x3f7e, 0x3f7f, 
+    0x3f80, 0x3f81, 0x3f82, 0x3f83, 0x3f84, 0x3f85, 0x3f86, 0x3f87, 
+    0x3f88, 0x3f89, 0x3f8a, 0x3f8b, 0x3f8c, 0x3f8d, 0x3f8e, 0x3f8f, 
+    0x3f90, 0x3f91, 0x3f92, 0x3f93, 0x3f94, 0x3f95, 0x3f96, 0x3f97, 
+    0x3f98, 0x3f99, 0x3f9a, 0x3f9b, 0x3f9c, 0x3f9d, 0x3f9e, 0x3f9f, 
+    0x3fa0, 0x3fa1, 0x3fa2, 0x3fa3, 0x3fa4, 0x3fa5, 0x3fa6, 0x3fa7, 
+    0x3fa8, 0x3fa9, 0x3faa, 0x3fab, 0x3fac, 0x3fad, 0x3fae, 0x3faf, 
+    0x3fb0, 0x3fb1, 0x3fb2, 0x3fb3, 0x3fb4, 0x3fb5, 0x3fb6, 0x3fb7, 
+    0x3fb8, 0x3fb9, 0x3fba, 0x3fbb, 0x3fbc, 0x3fbd, 0x3fbe, 0x3fbf, 
+    0x3fc0, 0x3fc1, 0x3fc2, 0x3fc3, 0x3fc4, 0x3fc5, 0x3fc6, 0x3fc7, 
+    0x3fc8, 0x3fc9, 0x3fca, 0x3fcb, 0x3fcc, 0x3fcd, 0x3fce, 0x3fcf, 
+    0x3fd0, 0x3fd1, 0x3fd2, 0x3fd3, 0x3fd4, 0x3fd5, 0x3fd6, 0x3fd7, 
+    0x3fd8, 0x3fd9, 0x3fda, 0x3fdb, 0x3fdc, 0x3fdd, 0x3fde, 0x3fdf, 
+    0x3fe0, 0x3fe1, 0x3fe2, 0x3fe3, 0x3fe4, 0x3fe5, 0x3fe6, 0x3fe7, 
+    0x3fe8, 0x3fe9, 0x3fea, 0x3feb, 0x3fec, 0x3fed, 0x3fee, 0x3fef, 
+    0x3ff0, 0x3ff1, 0x3ff2, 0x3ff3, 0x3ff4, 0x3ff5, 0x3ff6, 0x3ff7, 
+    0x3ff8, 0x3ff9, 0x3ffa, 0x3ffb, 0x3ffc, 0x3ffd, 0x3ffe, 0x3fff, 
+    0x4000, 0x4001, 0x4002, 0x4003, 0x4004, 0x4005, 0x4006, 0x4007, 
+    0x4008, 0x4009, 0x400a, 0x400b, 0x400c, 0x400d, 0x400e, 0x400f, 
+    0x4010, 0x4011, 0x4012, 0x4013, 0x4014, 0x4015, 0x4016, 0x4017, 
+    0x4018, 0x4019, 0x401a, 0x401b, 0x401c, 0x401d, 0x401e, 0x401f, 
+    0x4020, 0x4021, 0x4022, 0x4023, 0x4024, 0x4025, 0x4026, 0x4027, 
+    0x4028, 0x4029, 0x402a, 0x402b, 0x402c, 0x402d, 0x402e, 0x402f, 
+    0x4030, 0x4031, 0x4032, 0x4033, 0x4034, 0x4035, 0x4036, 0x4037, 
+    0x4038, 0x4039, 0x403a, 0x403b, 0x403c, 0x403d, 0x403e, 0x403f, 
+    0x4040, 0x4041, 0x4042, 0x4043, 0x4044, 0x4045, 0x4046, 0x4047, 
+    0x4048, 0x4049, 0x404a, 0x404b, 0x404c, 0x404d, 0x404e, 0x404f, 
+    0x4050, 0x4051, 0x4052, 0x4053, 0x4054, 0x4055, 0x4056, 0x4057, 
+    0x4058, 0x4059, 0x405a, 0x405b, 0x405c, 0x405d, 0x405e, 0x405f, 
+    0x4060, 0x4061, 0x4062, 0x4063, 0x4064, 0x4065, 0x4066, 0x4067, 
+    0x4068, 0x4069, 0x406a, 0x406b, 0x406c, 0x406d, 0x406e, 0x406f, 
+    0x4070, 0x4071, 0x4072, 0x4073, 0x4074, 0x4075, 0x4076, 0x4077, 
+    0x4078, 0x4079, 0x407a, 0x407b, 0x407c, 0x407d, 0x407e, 0x407f, 
+    0x4080, 0x4081, 0x4082, 0x4083, 0x4084, 0x4085, 0x4086, 0x4087, 
+    0x4088, 0x4089, 0x408a, 0x408b, 0x408c, 0x408d, 0x408e, 0x408f, 
+    0x4090, 0x4091, 0x4092, 0x4093, 0x4094, 0x4095, 0x4096, 0x4097, 
+    0x4098, 0x4099, 0x409a, 0x409b, 0x409c, 0x409d, 0x409e, 0x409f, 
+    0x40a0, 0x40a1, 0x40a2, 0x40a3, 0x40a4, 0x40a5, 0x40a6, 0x40a7, 
+    0x40a8, 0x40a9, 0x40aa, 0x40ab, 0x40ac, 0x40ad, 0x40ae, 0x40af, 
+    0x40b0, 0x40b1, 0x40b2, 0x40b3, 0x40b4, 0x40b5, 0x40b6, 0x40b7, 
+    0x40b8, 0x40b9, 0x40ba, 0x40bb, 0x40bc, 0x40bd, 0x40be, 0x40bf, 
+    0x40c0, 0x40c1, 0x40c2, 0x40c3, 0x40c4, 0x40c5, 0x40c6, 0x40c7, 
+    0x40c8, 0x40c9, 0x40ca, 0x40cb, 0x40cc, 0x40cd, 0x40ce, 0x40cf, 
+    0x40d0, 0x40d1, 0x40d2, 0x40d3, 0x40d4, 0x40d5, 0x40d6, 0x40d7, 
+    0x40d8, 0x40d9, 0x40da, 0x40db, 0x40dc, 0x40dd, 0x40de, 0x40df, 
+    0x40e0, 0x40e1, 0x40e2, 0x40e3, 0x40e4, 0x40e5, 0x40e6, 0x40e7, 
+    0x40e8, 0x40e9, 0x40ea, 0x40eb, 0x40ec, 0x40ed, 0x40ee, 0x40ef, 
+    0x40f0, 0x40f1, 0x40f2, 0x40f3, 0x40f4, 0x40f5, 0x40f6, 0x40f7, 
+    0x40f8, 0x40f9, 0x40fa, 0x40fb, 0x40fc, 0x40fd, 0x40fe, 0x40ff, 
+    0x4100, 0x4101, 0x4102, 0x4103, 0x4104, 0x4105, 0x4106, 0x4107, 
+    0x4108, 0x4109, 0x410a, 0x410b, 0x410c, 0x410d, 0x410e, 0x410f, 
+    0x4110, 0x4111, 0x4112, 0x4113, 0x4114, 0x4115, 0x4116, 0x4117, 
+    0x4118, 0x4119, 0x411a, 0x411b, 0x411c, 0x411d, 0x411e, 0x411f, 
+    0x4120, 0x4121, 0x4122, 0x4123, 0x4124, 0x4125, 0x4126, 0x4127, 
+    0x4128, 0x4129, 0x412a, 0x412b, 0x412c, 0x412d, 0x412e, 0x412f, 
+    0x4130, 0x4131, 0x4132, 0x4133, 0x4134, 0x4135, 0x4136, 0x4137, 
+    0x4138, 0x4139, 0x413a, 0x413b, 0x413c, 0x413d, 0x413e, 0x413f, 
+    0x4140, 0x4141, 0x4142, 0x4143, 0x4144, 0x4145, 0x4146, 0x4147, 
+    0x4148, 0x4149, 0x414a, 0x414b, 0x414c, 0x414d, 0x414e, 0x414f, 
+    0x4150, 0x4151, 0x4152, 0x4153, 0x4154, 0x4155, 0x4156, 0x4157, 
+    0x4158, 0x4159, 0x415a, 0x415b, 0x415c, 0x415d, 0x415e, 0x415f, 
+    0x4160, 0x4161, 0x4162, 0x4163, 0x4164, 0x4165, 0x4166, 0x4167, 
+    0x4168, 0x4169, 0x416a, 0x416b, 0x416c, 0x416d, 0x416e, 0x416f, 
+    0x4170, 0x4171, 0x4172, 0x4173, 0x4174, 0x4175, 0x4176, 0x4177, 
+    0x4178, 0x4179, 0x417a, 0x417b, 0x417c, 0x417d, 0x417e, 0x417f, 
+    0x4180, 0x4181, 0x4182, 0x4183, 0x4184, 0x4185, 0x4186, 0x4187, 
+    0x4188, 0x4189, 0x418a, 0x418b, 0x418c, 0x418d, 0x418e, 0x418f, 
+    0x4190, 0x4191, 0x4192, 0x4193, 0x4194, 0x4195, 0x4196, 0x4197, 
+    0x4198, 0x4199, 0x419a, 0x419b, 0x419c, 0x419d, 0x419e, 0x419f, 
+    0x41a0, 0x41a1, 0x41a2, 0x41a3, 0x41a4, 0x41a5, 0x41a6, 0x41a7, 
+    0x41a8, 0x41a9, 0x41aa, 0x41ab, 0x41ac, 0x41ad, 0x41ae, 0x41af, 
+    0x41b0, 0x41b1, 0x41b2, 0x41b3, 0x41b4, 0x41b5, 0x41b6, 0x41b7, 
+    0x41b8, 0x41b9, 0x41ba, 0x41bb, 0x41bc, 0x41bd, 0x41be, 0x41bf, 
+    0x41c0, 0x41c1, 0x41c2, 0x41c3, 0x41c4, 0x41c5, 0x41c6, 0x41c7, 
+    0x41c8, 0x41c9, 0x41ca, 0x41cb, 0x41cc, 0x41cd, 0x41ce, 0x41cf, 
+    0x41d0, 0x41d1, 0x41d2, 0x41d3, 0x41d4, 0x41d5, 0x41d6, 0x41d7, 
+    0x41d8, 0x41d9, 0x41da, 0x41db, 0x41dc, 0x41dd, 0x41de, 0x41df, 
+    0x41e0, 0x41e1, 0x41e2, 0x41e3, 0x41e4, 0x41e5, 0x41e6, 0x41e7, 
+    0x41e8, 0x41e9, 0x41ea, 0x41eb, 0x41ec, 0x41ed, 0x41ee, 0x41ef, 
+    0x41f0, 0x41f1, 0x41f2, 0x41f3, 0x41f4, 0x41f5, 0x41f6, 0x41f7, 
+    0x41f8, 0x41f9, 0x41fa, 0x41fb, 0x41fc, 0x41fd, 0x41fe, 0x41ff, 
+    0x4200, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205, 0x4206, 0x4207, 
+    0x4208, 0x4209, 0x420a, 0x420b, 0x420c, 0x420d, 0x420e, 0x420f, 
+    0x4210, 0x4211, 0x4212, 0x4213, 0x4214, 0x4215, 0x4216, 0x4217, 
+    0x4218, 0x4219, 0x421a, 0x421b, 0x421c, 0x421d, 0x421e, 0x421f, 
+    0x4220, 0x4221, 0x4222, 0x4223, 0x4224, 0x4225, 0x4226, 0x4227, 
+    0x4228, 0x4229, 0x422a, 0x422b, 0x422c, 0x422d, 0x422e, 0x422f, 
+    0x4230, 0x4231, 0x4232, 0x4233, 0x4234, 0x4235, 0x4236, 0x4237, 
+    0x4238, 0x4239, 0x423a, 0x423b, 0x423c, 0x423d, 0x423e, 0x423f, 
+    0x4240, 0x4241, 0x4242, 0x4243, 0x4244, 0x4245, 0x4246, 0x4247, 
+    0x4248, 0x4249, 0x424a, 0x424b, 0x424c, 0x424d, 0x424e, 0x424f, 
+    0x4250, 0x4251, 0x4252, 0x4253, 0x4254, 0x4255, 0x4256, 0x4257, 
+    0x4258, 0x4259, 0x425a, 0x425b, 0x425c, 0x425d, 0x425e, 0x425f, 
+    0x4260, 0x4261, 0x4262, 0x4263, 0x4264, 0x4265, 0x4266, 0x4267, 
+    0x4268, 0x4269, 0x426a, 0x426b, 0x426c, 0x426d, 0x426e, 0x426f, 
+    0x4270, 0x4271, 0x4272, 0x4273, 0x4274, 0x4275, 0x4276, 0x4277, 
+    0x4278, 0x4279, 0x427a, 0x427b, 0x427c, 0x427d, 0x427e, 0x427f, 
+    0x4280, 0x4281, 0x4282, 0x4283, 0x4284, 0x4285, 0x4286, 0x4287, 
+    0x4288, 0x4289, 0x428a, 0x428b, 0x428c, 0x428d, 0x428e, 0x428f, 
+    0x4290, 0x4291, 0x4292, 0x4293, 0x4294, 0x4295, 0x4296, 0x4297, 
+    0x4298, 0x4299, 0x429a, 0x429b, 0x429c, 0x429d, 0x429e, 0x429f, 
+    0x42a0, 0x42a1, 0x42a2, 0x42a3, 0x42a4, 0x42a5, 0x42a6, 0x42a7, 
+    0x42a8, 0x42a9, 0x42aa, 0x42ab, 0x42ac, 0x42ad, 0x42ae, 0x42af, 
+    0x42b0, 0x42b1, 0x42b2, 0x42b3, 0x42b4, 0x42b5, 0x42b6, 0x42b7, 
+    0x42b8, 0x42b9, 0x42ba, 0x42bb, 0x42bc, 0x42bd, 0x42be, 0x42bf, 
+    0x42c0, 0x42c1, 0x42c2, 0x42c3, 0x42c4, 0x42c5, 0x42c6, 0x42c7, 
+    0x42c8, 0x42c9, 0x42ca, 0x42cb, 0x42cc, 0x42cd, 0x42ce, 0x42cf, 
+    0x42d0, 0x42d1, 0x42d2, 0x42d3, 0x42d4, 0x42d5, 0x42d6, 0x42d7, 
+    0x42d8, 0x42d9, 0x42da, 0x42db, 0x42dc, 0x42dd, 0x42de, 0x42df, 
+    0x42e0, 0x42e1, 0x42e2, 0x42e3, 0x42e4, 0x42e5, 0x42e6, 0x42e7, 
+    0x42e8, 0x42e9, 0x42ea, 0x42eb, 0x42ec, 0x42ed, 0x42ee, 0x42ef, 
+    0x42f0, 0x42f1, 0x42f2, 0x42f3, 0x42f4, 0x42f5, 0x42f6, 0x42f7, 
+    0x42f8, 0x42f9, 0x42fa, 0x42fb, 0x42fc, 0x42fd, 0x42fe, 0x42ff, 
+    0x4300, 0x4301, 0x4302, 0x4303, 0x4304, 0x4305, 0x4306, 0x4307, 
+    0x4308, 0x4309, 0x430a, 0x430b, 0x430c, 0x430d, 0x430e, 0x430f, 
+    0x4310, 0x4311, 0x4312, 0x4313, 0x4314, 0x4315, 0x4316, 0x4317, 
+    0x4318, 0x4319, 0x431a, 0x431b, 0x431c, 0x431d, 0x431e, 0x431f, 
+    0x4320, 0x4321, 0x4322, 0x4323, 0x4324, 0x4325, 0x4326, 0x4327, 
+    0x4328, 0x4329, 0x432a, 0x432b, 0x432c, 0x432d, 0x432e, 0x432f, 
+    0x4330, 0x4331, 0x4332, 0x4333, 0x4334, 0x4335, 0x4336, 0x4337, 
+    0x4338, 0x4339, 0x433a, 0x433b, 0x433c, 0x433d, 0x433e, 0x433f, 
+    0x4340, 0x4341, 0x4342, 0x4343, 0x4344, 0x4345, 0x4346, 0x4347, 
+    0x4348, 0x4349, 0x434a, 0x434b, 0x434c, 0x434d, 0x434e, 0x434f, 
+    0x4350, 0x4351, 0x4352, 0x4353, 0x4354, 0x4355, 0x4356, 0x4357, 
+    0x4358, 0x4359, 0x435a, 0x435b, 0x435c, 0x435d, 0x435e, 0x435f, 
+    0x4360, 0x4361, 0x4362, 0x4363, 0x4364, 0x4365, 0x4366, 0x4367, 
+    0x4368, 0x4369, 0x436a, 0x436b, 0x436c, 0x436d, 0x436e, 0x436f, 
+    0x4370, 0x4371, 0x4372, 0x4373, 0x4374, 0x4375, 0x4376, 0x4377, 
+    0x4378, 0x4379, 0x437a, 0x437b, 0x437c, 0x437d, 0x437e, 0x437f, 
+    0x4380, 0x4381, 0x4382, 0x4383, 0x4384, 0x4385, 0x4386, 0x4387, 
+    0x4388, 0x4389, 0x438a, 0x438b, 0x438c, 0x438d, 0x438e, 0x438f, 
+    0x4390, 0x4391, 0x4392, 0x4393, 0x4394, 0x4395, 0x4396, 0x4397, 
+    0x4398, 0x4399, 0x439a, 0x439b, 0x439c, 0x439d, 0x439e, 0x439f, 
+    0x43a0, 0x43a1, 0x43a2, 0x43a3, 0x43a4, 0x43a5, 0x43a6, 0x43a7, 
+    0x43a8, 0x43a9, 0x43aa, 0x43ab, 0x43ac, 0x43ad, 0x43ae, 0x43af, 
+    0x43b0, 0x43b1, 0x43b2, 0x43b3, 0x43b4, 0x43b5, 0x43b6, 0x43b7, 
+    0x43b8, 0x43b9, 0x43ba, 0x43bb, 0x43bc, 0x43bd, 0x43be, 0x43bf, 
+    0x43c0, 0x43c1, 0x43c2, 0x43c3, 0x43c4, 0x43c5, 0x43c6, 0x43c7, 
+    0x43c8, 0x43c9, 0x43ca, 0x43cb, 0x43cc, 0x43cd, 0x43ce, 0x43cf, 
+    0x43d0, 0x43d1, 0x43d2, 0x43d3, 0x43d4, 0x43d5, 0x43d6, 0x43d7, 
+    0x43d8, 0x43d9, 0x43da, 0x43db, 0x43dc, 0x43dd, 0x43de, 0x43df, 
+    0x43e0, 0x43e1, 0x43e2, 0x43e3, 0x43e4, 0x43e5, 0x43e6, 0x43e7, 
+    0x43e8, 0x43e9, 0x43ea, 0x43eb, 0x43ec, 0x43ed, 0x43ee, 0x43ef, 
+    0x43f0, 0x43f1, 0x43f2, 0x43f3, 0x43f4, 0x43f5, 0x43f6, 0x43f7, 
+    0x43f8, 0x43f9, 0x43fa, 0x43fb, 0x43fc, 0x43fd, 0x43fe, 0x43ff, 
+    0x4400, 0x4401, 0x4402, 0x4403, 0x4404, 0x4405, 0x4406, 0x4407, 
+    0x4408, 0x4409, 0x440a, 0x440b, 0x440c, 0x440d, 0x440e, 0x440f, 
+    0x4410, 0x4411, 0x4412, 0x4413, 0x4414, 0x4415, 0x4416, 0x4417, 
+    0x4418, 0x4419, 0x441a, 0x441b, 0x441c, 0x441d, 0x441e, 0x441f, 
+    0x4420, 0x4421, 0x4422, 0x4423, 0x4424, 0x4425, 0x4426, 0x4427, 
+    0x4428, 0x4429, 0x442a, 0x442b, 0x442c, 0x442d, 0x442e, 0x442f, 
+    0x4430, 0x4431, 0x4432, 0x4433, 0x4434, 0x4435, 0x4436, 0x4437, 
+    0x4438, 0x4439, 0x443a, 0x443b, 0x443c, 0x443d, 0x443e, 0x443f, 
+    0x4440, 0x4441, 0x4442, 0x4443, 0x4444, 0x4445, 0x4446, 0x4447, 
+    0x4448, 0x4449, 0x444a, 0x444b, 0x444c, 0x444d, 0x444e, 0x444f, 
+    0x4450, 0x4451, 0x4452, 0x4453, 0x4454, 0x4455, 0x4456, 0x4457, 
+    0x4458, 0x4459, 0x445a, 0x445b, 0x445c, 0x445d, 0x445e, 0x445f, 
+    0x4460, 0x4461, 0x4462, 0x4463, 0x4464, 0x4465, 0x4466, 0x4467, 
+    0x4468, 0x4469, 0x446a, 0x446b, 0x446c, 0x446d, 0x446e, 0x446f, 
+    0x4470, 0x4471, 0x4472, 0x4473, 0x4474, 0x4475, 0x4476, 0x4477, 
+    0x4478, 0x4479, 0x447a, 0x447b, 0x447c, 0x447d, 0x447e, 0x447f, 
+    0x4480, 0x4481, 0x4482, 0x4483, 0x4484, 0x4485, 0x4486, 0x4487, 
+    0x4488, 0x4489, 0x448a, 0x448b, 0x448c, 0x448d, 0x448e, 0x448f, 
+    0x4490, 0x4491, 0x4492, 0x4493, 0x4494, 0x4495, 0x4496, 0x4497, 
+    0x4498, 0x4499, 0x449a, 0x449b, 0x449c, 0x449d, 0x449e, 0x449f, 
+    0x44a0, 0x44a1, 0x44a2, 0x44a3, 0x44a4, 0x44a5, 0x44a6, 0x44a7, 
+    0x44a8, 0x44a9, 0x44aa, 0x44ab, 0x44ac, 0x44ad, 0x44ae, 0x44af, 
+    0x44b0, 0x44b1, 0x44b2, 0x44b3, 0x44b4, 0x44b5, 0x44b6, 0x44b7, 
+    0x44b8, 0x44b9, 0x44ba, 0x44bb, 0x44bc, 0x44bd, 0x44be, 0x44bf, 
+    0x44c0, 0x44c1, 0x44c2, 0x44c3, 0x44c4, 0x44c5, 0x44c6, 0x44c7, 
+    0x44c8, 0x44c9, 0x44ca, 0x44cb, 0x44cc, 0x44cd, 0x44ce, 0x44cf, 
+    0x44d0, 0x44d1, 0x44d2, 0x44d3, 0x44d4, 0x44d5, 0x44d6, 0x44d7, 
+    0x44d8, 0x44d9, 0x44da, 0x44db, 0x44dc, 0x44dd, 0x44de, 0x44df, 
+    0x44e0, 0x44e1, 0x44e2, 0x44e3, 0x44e4, 0x44e5, 0x44e6, 0x44e7, 
+    0x44e8, 0x44e9, 0x44ea, 0x44eb, 0x44ec, 0x44ed, 0x44ee, 0x44ef, 
+    0x44f0, 0x44f1, 0x44f2, 0x44f3, 0x44f4, 0x44f5, 0x44f6, 0x44f7, 
+    0x44f8, 0x44f9, 0x44fa, 0x44fb, 0x44fc, 0x44fd, 0x44fe, 0x44ff, 
+    0x4500, 0x4501, 0x4502, 0x4503, 0x4504, 0x4505, 0x4506, 0x4507, 
+    0x4508, 0x4509, 0x450a, 0x450b, 0x450c, 0x450d, 0x450e, 0x450f, 
+    0x4510, 0x4511, 0x4512, 0x4513, 0x4514, 0x4515, 0x4516, 0x4517, 
+    0x4518, 0x4519, 0x451a, 0x451b, 0x451c, 0x451d, 0x451e, 0x451f, 
+    0x4520, 0x4521, 0x4522, 0x4523, 0x4524, 0x4525, 0x4526, 0x4527, 
+    0x4528, 0x4529, 0x452a, 0x452b, 0x452c, 0x452d, 0x452e, 0x452f, 
+    0x4530, 0x4531, 0x4532, 0x4533, 0x4534, 0x4535, 0x4536, 0x4537, 
+    0x4538, 0x4539, 0x453a, 0x453b, 0x453c, 0x453d, 0x453e, 0x453f, 
+    0x4540, 0x4541, 0x4542, 0x4543, 0x4544, 0x4545, 0x4546, 0x4547, 
+    0x4548, 0x4549, 0x454a, 0x454b, 0x454c, 0x454d, 0x454e, 0x454f, 
+    0x4550, 0x4551, 0x4552, 0x4553, 0x4554, 0x4555, 0x4556, 0x4557, 
+    0x4558, 0x4559, 0x455a, 0x455b, 0x455c, 0x455d, 0x455e, 0x455f, 
+    0x4560, 0x4561, 0x4562, 0x4563, 0x4564, 0x4565, 0x4566, 0x4567, 
+    0x4568, 0x4569, 0x456a, 0x456b, 0x456c, 0x456d, 0x456e, 0x456f, 
+    0x4570, 0x4571, 0x4572, 0x4573, 0x4574, 0x4575, 0x4576, 0x4577, 
+    0x4578, 0x4579, 0x457a, 0x457b, 0x457c, 0x457d, 0x457e, 0x457f, 
+    0x4580, 0x4581, 0x4582, 0x4583, 0x4584, 0x4585, 0x4586, 0x4587, 
+    0x4588, 0x4589, 0x458a, 0x458b, 0x458c, 0x458d, 0x458e, 0x458f, 
+    0x4590, 0x4591, 0x4592, 0x4593, 0x4594, 0x4595, 0x4596, 0x4597, 
+    0x4598, 0x4599, 0x459a, 0x459b, 0x459c, 0x459d, 0x459e, 0x459f, 
+    0x45a0, 0x45a1, 0x45a2, 0x45a3, 0x45a4, 0x45a5, 0x45a6, 0x45a7, 
+    0x45a8, 0x45a9, 0x45aa, 0x45ab, 0x45ac, 0x45ad, 0x45ae, 0x45af, 
+    0x45b0, 0x45b1, 0x45b2, 0x45b3, 0x45b4, 0x45b5, 0x45b6, 0x45b7, 
+    0x45b8, 0x45b9, 0x45ba, 0x45bb, 0x45bc, 0x45bd, 0x45be, 0x45bf, 
+    0x45c0, 0x45c1, 0x45c2, 0x45c3, 0x45c4, 0x45c5, 0x45c6, 0x45c7, 
+    0x45c8, 0x45c9, 0x45ca, 0x45cb, 0x45cc, 0x45cd, 0x45ce, 0x45cf, 
+    0x45d0, 0x45d1, 0x45d2, 0x45d3, 0x45d4, 0x45d5, 0x45d6, 0x45d7, 
+    0x45d8, 0x45d9, 0x45da, 0x45db, 0x45dc, 0x45dd, 0x45de, 0x45df, 
+    0x45e0, 0x45e1, 0x45e2, 0x45e3, 0x45e4, 0x45e5, 0x45e6, 0x45e7, 
+    0x45e8, 0x45e9, 0x45ea, 0x45eb, 0x45ec, 0x45ed, 0x45ee, 0x45ef, 
+    0x45f0, 0x45f1, 0x45f2, 0x45f3, 0x45f4, 0x45f5, 0x45f6, 0x45f7, 
+    0x45f8, 0x45f9, 0x45fa, 0x45fb, 0x45fc, 0x45fd, 0x45fe, 0x45ff, 
+    0x4600, 0x4601, 0x4602, 0x4603, 0x4604, 0x4605, 0x4606, 0x4607, 
+    0x4608, 0x4609, 0x460a, 0x460b, 0x460c, 0x460d, 0x460e, 0x460f, 
+    0x4610, 0x4611, 0x4612, 0x4613, 0x4614, 0x4615, 0x4616, 0x4617, 
+    0x4618, 0x4619, 0x461a, 0x461b, 0x461c, 0x461d, 0x461e, 0x461f, 
+    0x4620, 0x4621, 0x4622, 0x4623, 0x4624, 0x4625, 0x4626, 0x4627, 
+    0x4628, 0x4629, 0x462a, 0x462b, 0x462c, 0x462d, 0x462e, 0x462f, 
+    0x4630, 0x4631, 0x4632, 0x4633, 0x4634, 0x4635, 0x4636, 0x4637, 
+    0x4638, 0x4639, 0x463a, 0x463b, 0x463c, 0x463d, 0x463e, 0x463f, 
+    0x4640, 0x4641, 0x4642, 0x4643, 0x4644, 0x4645, 0x4646, 0x4647, 
+    0x4648, 0x4649, 0x464a, 0x464b, 0x464c, 0x464d, 0x464e, 0x464f, 
+    0x4650, 0x4651, 0x4652, 0x4653, 0x4654, 0x4655, 0x4656, 0x4657, 
+    0x4658, 0x4659, 0x465a, 0x465b, 0x465c, 0x465d, 0x465e, 0x465f, 
+    0x4660, 0x4661, 0x4662, 0x4663, 0x4664, 0x4665, 0x4666, 0x4667, 
+    0x4668, 0x4669, 0x466a, 0x466b, 0x466c, 0x466d, 0x466e, 0x466f, 
+    0x4670, 0x4671, 0x4672, 0x4673, 0x4674, 0x4675, 0x4676, 0x4677, 
+    0x4678, 0x4679, 0x467a, 0x467b, 0x467c, 0x467d, 0x467e, 0x467f, 
+    0x4680, 0x4681, 0x4682, 0x4683, 0x4684, 0x4685, 0x4686, 0x4687, 
+    0x4688, 0x4689, 0x468a, 0x468b, 0x468c, 0x468d, 0x468e, 0x468f, 
+    0x4690, 0x4691, 0x4692, 0x4693, 0x4694, 0x4695, 0x4696, 0x4697, 
+    0x4698, 0x4699, 0x469a, 0x469b, 0x469c, 0x469d, 0x469e, 0x469f, 
+    0x46a0, 0x46a1, 0x46a2, 0x46a3, 0x46a4, 0x46a5, 0x46a6, 0x46a7, 
+    0x46a8, 0x46a9, 0x46aa, 0x46ab, 0x46ac, 0x46ad, 0x46ae, 0x46af, 
+    0x46b0, 0x46b1, 0x46b2, 0x46b3, 0x46b4, 0x46b5, 0x46b6, 0x46b7, 
+    0x46b8, 0x46b9, 0x46ba, 0x46bb, 0x46bc, 0x46bd, 0x46be, 0x46bf, 
+    0x46c0, 0x46c1, 0x46c2, 0x46c3, 0x46c4, 0x46c5, 0x46c6, 0x46c7, 
+    0x46c8, 0x46c9, 0x46ca, 0x46cb, 0x46cc, 0x46cd, 0x46ce, 0x46cf, 
+    0x46d0, 0x46d1, 0x46d2, 0x46d3, 0x46d4, 0x46d5, 0x46d6, 0x46d7, 
+    0x46d8, 0x46d9, 0x46da, 0x46db, 0x46dc, 0x46dd, 0x46de, 0x46df, 
+    0x46e0, 0x46e1, 0x46e2, 0x46e3, 0x46e4, 0x46e5, 0x46e6, 0x46e7, 
+    0x46e8, 0x46e9, 0x46ea, 0x46eb, 0x46ec, 0x46ed, 0x46ee, 0x46ef, 
+    0x46f0, 0x46f1, 0x46f2, 0x46f3, 0x46f4, 0x46f5, 0x46f6, 0x46f7, 
+    0x46f8, 0x46f9, 0x46fa, 0x46fb, 0x46fc, 0x46fd, 0x46fe, 0x46ff, 
+    0x4700, 0x4701, 0x4702, 0x4703, 0x4704, 0x4705, 0x4706, 0x4707, 
+    0x4708, 0x4709, 0x470a, 0x470b, 0x470c, 0x470d, 0x470e, 0x470f, 
+    0x4710, 0x4711, 0x4712, 0x4713, 0x4714, 0x4715, 0x4716, 0x4717, 
+    0x4718, 0x4719, 0x471a, 0x471b, 0x471c, 0x471d, 0x471e, 0x471f, 
+    0x4720, 0x4721, 0x4722, 0x4723, 0x4724, 0x4725, 0x4726, 0x4727, 
+    0x4728, 0x4729, 0x472a, 0x472b, 0x472c, 0x472d, 0x472e, 0x472f, 
+    0x4730, 0x4731, 0x4732, 0x4733, 0x4734, 0x4735, 0x4736, 0x4737, 
+    0x4738, 0x4739, 0x473a, 0x473b, 0x473c, 0x473d, 0x473e, 0x473f, 
+    0x4740, 0x4741, 0x4742, 0x4743, 0x4744, 0x4745, 0x4746, 0x4747, 
+    0x4748, 0x4749, 0x474a, 0x474b, 0x474c, 0x474d, 0x474e, 0x474f, 
+    0x4750, 0x4751, 0x4752, 0x4753, 0x4754, 0x4755, 0x4756, 0x4757, 
+    0x4758, 0x4759, 0x475a, 0x475b, 0x475c, 0x475d, 0x475e, 0x475f, 
+    0x4760, 0x4761, 0x4762, 0x4763, 0x4764, 0x4765, 0x4766, 0x4767, 
+    0x4768, 0x4769, 0x476a, 0x476b, 0x476c, 0x476d, 0x476e, 0x476f, 
+    0x4770, 0x4771, 0x4772, 0x4773, 0x4774, 0x4775, 0x4776, 0x4777, 
+    0x4778, 0x4779, 0x477a, 0x477b, 0x477c, 0x477d, 0x477e, 0x477f, 
+    0x4780, 0x4781, 0x4782, 0x4783, 0x4784, 0x4785, 0x4786, 0x4787, 
+    0x4788, 0x4789, 0x478a, 0x478b, 0x478c, 0x478d, 0x478e, 0x478f, 
+    0x4790, 0x4791, 0x4792, 0x4793, 0x4794, 0x4795, 0x4796, 0x4797, 
+    0x4798, 0x4799, 0x479a, 0x479b, 0x479c, 0x479d, 0x479e, 0x479f, 
+    0x47a0, 0x47a1, 0x47a2, 0x47a3, 0x47a4, 0x47a5, 0x47a6, 0x47a7, 
+    0x47a8, 0x47a9, 0x47aa, 0x47ab, 0x47ac, 0x47ad, 0x47ae, 0x47af, 
+    0x47b0, 0x47b1, 0x47b2, 0x47b3, 0x47b4, 0x47b5, 0x47b6, 0x47b7, 
+    0x47b8, 0x47b9, 0x47ba, 0x47bb, 0x47bc, 0x47bd, 0x47be, 0x47bf, 
+    0x47c0, 0x47c1, 0x47c2, 0x47c3, 0x47c4, 0x47c5, 0x47c6, 0x47c7, 
+    0x47c8, 0x47c9, 0x47ca, 0x47cb, 0x47cc, 0x47cd, 0x47ce, 0x47cf, 
+    0x47d0, 0x47d1, 0x47d2, 0x47d3, 0x47d4, 0x47d5, 0x47d6, 0x47d7, 
+    0x47d8, 0x47d9, 0x47da, 0x47db, 0x47dc, 0x47dd, 0x47de, 0x47df, 
+    0x47e0, 0x47e1, 0x47e2, 0x47e3, 0x47e4, 0x47e5, 0x47e6, 0x47e7, 
+    0x47e8, 0x47e9, 0x47ea, 0x47eb, 0x47ec, 0x47ed, 0x47ee, 0x47ef, 
+    0x47f0, 0x47f1, 0x47f2, 0x47f3, 0x47f4, 0x47f5, 0x47f6, 0x47f7, 
+    0x47f8, 0x47f9, 0x47fa, 0x47fb, 0x47fc, 0x47fd, 0x47fe, 0x47ff, 
+    0x4800, 0x4801, 0x4802, 0x4803, 0x4804, 0x4805, 0x4806, 0x4807, 
+    0x4808, 0x4809, 0x480a, 0x480b, 0x480c, 0x480d, 0x480e, 0x480f, 
+    0x4810, 0x4811, 0x4812, 0x4813, 0x4814, 0x4815, 0x4816, 0x4817, 
+    0x4818, 0x4819, 0x481a, 0x481b, 0x481c, 0x481d, 0x481e, 0x481f, 
+    0x4820, 0x4821, 0x4822, 0x4823, 0x4824, 0x4825, 0x4826, 0x4827, 
+    0x4828, 0x4829, 0x482a, 0x482b, 0x482c, 0x482d, 0x482e, 0x482f, 
+    0x4830, 0x4831, 0x4832, 0x4833, 0x4834, 0x4835, 0x4836, 0x4837, 
+    0x4838, 0x4839, 0x483a, 0x483b, 0x483c, 0x483d, 0x483e, 0x483f, 
+    0x4840, 0x4841, 0x4842, 0x4843, 0x4844, 0x4845, 0x4846, 0x4847, 
+    0x4848, 0x4849, 0x484a, 0x484b, 0x484c, 0x484d, 0x484e, 0x484f, 
+    0x4850, 0x4851, 0x4852, 0x4853, 0x4854, 0x4855, 0x4856, 0x4857, 
+    0x4858, 0x4859, 0x485a, 0x485b, 0x485c, 0x485d, 0x485e, 0x485f, 
+    0x4860, 0x4861, 0x4862, 0x4863, 0x4864, 0x4865, 0x4866, 0x4867, 
+    0x4868, 0x4869, 0x486a, 0x486b, 0x486c, 0x486d, 0x486e, 0x486f, 
+    0x4870, 0x4871, 0x4872, 0x4873, 0x4874, 0x4875, 0x4876, 0x4877, 
+    0x4878, 0x4879, 0x487a, 0x487b, 0x487c, 0x487d, 0x487e, 0x487f, 
+    0x4880, 0x4881, 0x4882, 0x4883, 0x4884, 0x4885, 0x4886, 0x4887, 
+    0x4888, 0x4889, 0x488a, 0x488b, 0x488c, 0x488d, 0x488e, 0x488f, 
+    0x4890, 0x4891, 0x4892, 0x4893, 0x4894, 0x4895, 0x4896, 0x4897, 
+    0x4898, 0x4899, 0x489a, 0x489b, 0x489c, 0x489d, 0x489e, 0x489f, 
+    0x48a0, 0x48a1, 0x48a2, 0x48a3, 0x48a4, 0x48a5, 0x48a6, 0x48a7, 
+    0x48a8, 0x48a9, 0x48aa, 0x48ab, 0x48ac, 0x48ad, 0x48ae, 0x48af, 
+    0x48b0, 0x48b1, 0x48b2, 0x48b3, 0x48b4, 0x48b5, 0x48b6, 0x48b7, 
+    0x48b8, 0x48b9, 0x48ba, 0x48bb, 0x48bc, 0x48bd, 0x48be, 0x48bf, 
+    0x48c0, 0x48c1, 0x48c2, 0x48c3, 0x48c4, 0x48c5, 0x48c6, 0x48c7, 
+    0x48c8, 0x48c9, 0x48ca, 0x48cb, 0x48cc, 0x48cd, 0x48ce, 0x48cf, 
+    0x48d0, 0x48d1, 0x48d2, 0x48d3, 0x48d4, 0x48d5, 0x48d6, 0x48d7, 
+    0x48d8, 0x48d9, 0x48da, 0x48db, 0x48dc, 0x48dd, 0x48de, 0x48df, 
+    0x48e0, 0x48e1, 0x48e2, 0x48e3, 0x48e4, 0x48e5, 0x48e6, 0x48e7, 
+    0x48e8, 0x48e9, 0x48ea, 0x48eb, 0x48ec, 0x48ed, 0x48ee, 0x48ef, 
+    0x48f0, 0x48f1, 0x48f2, 0x48f3, 0x48f4, 0x48f5, 0x48f6, 0x48f7, 
+    0x48f8, 0x48f9, 0x48fa, 0x48fb, 0x48fc, 0x48fd, 0x48fe, 0x48ff, 
+    0x4900, 0x4901, 0x4902, 0x4903, 0x4904, 0x4905, 0x4906, 0x4907, 
+    0x4908, 0x4909, 0x490a, 0x490b, 0x490c, 0x490d, 0x490e, 0x490f, 
+    0x4910, 0x4911, 0x4912, 0x4913, 0x4914, 0x4915, 0x4916, 0x4917, 
+    0x4918, 0x4919, 0x491a, 0x491b, 0x491c, 0x491d, 0x491e, 0x491f, 
+    0x4920, 0x4921, 0x4922, 0x4923, 0x4924, 0x4925, 0x4926, 0x4927, 
+    0x4928, 0x4929, 0x492a, 0x492b, 0x492c, 0x492d, 0x492e, 0x492f, 
+    0x4930, 0x4931, 0x4932, 0x4933, 0x4934, 0x4935, 0x4936, 0x4937, 
+    0x4938, 0x4939, 0x493a, 0x493b, 0x493c, 0x493d, 0x493e, 0x493f, 
+    0x4940, 0x4941, 0x4942, 0x4943, 0x4944, 0x4945, 0x4946, 0x4947, 
+    0x4948, 0x4949, 0x494a, 0x494b, 0x494c, 0x494d, 0x494e, 0x494f, 
+    0x4950, 0x4951, 0x4952, 0x4953, 0x4954, 0x4955, 0x4956, 0x4957, 
+    0x4958, 0x4959, 0x495a, 0x495b, 0x495c, 0x495d, 0x495e, 0x495f, 
+    0x4960, 0x4961, 0x4962, 0x4963, 0x4964, 0x4965, 0x4966, 0x4967, 
+    0x4968, 0x4969, 0x496a, 0x496b, 0x496c, 0x496d, 0x496e, 0x496f, 
+    0x4970, 0x4971, 0x4972, 0x4973, 0x4974, 0x4975, 0x4976, 0x4977, 
+    0x4978, 0x4979, 0x497a, 0x497b, 0x497c, 0x497d, 0x497e, 0x497f, 
+    0x4980, 0x4981, 0x4982, 0x4983, 0x4984, 0x4985, 0x4986, 0x4987, 
+    0x4988, 0x4989, 0x498a, 0x498b, 0x498c, 0x498d, 0x498e, 0x498f, 
+    0x4990, 0x4991, 0x4992, 0x4993, 0x4994, 0x4995, 0x4996, 0x4997, 
+    0x4998, 0x4999, 0x499a, 0x499b, 0x499c, 0x499d, 0x499e, 0x499f, 
+    0x49a0, 0x49a1, 0x49a2, 0x49a3, 0x49a4, 0x49a5, 0x49a6, 0x49a7, 
+    0x49a8, 0x49a9, 0x49aa, 0x49ab, 0x49ac, 0x49ad, 0x49ae, 0x49af, 
+    0x49b0, 0x49b1, 0x49b2, 0x49b3, 0x49b4, 0x49b5, 0x49b6, 0x49b7, 
+    0x49b8, 0x49b9, 0x49ba, 0x49bb, 0x49bc, 0x49bd, 0x49be, 0x49bf, 
+    0x49c0, 0x49c1, 0x49c2, 0x49c3, 0x49c4, 0x49c5, 0x49c6, 0x49c7, 
+    0x49c8, 0x49c9, 0x49ca, 0x49cb, 0x49cc, 0x49cd, 0x49ce, 0x49cf, 
+    0x49d0, 0x49d1, 0x49d2, 0x49d3, 0x49d4, 0x49d5, 0x49d6, 0x49d7, 
+    0x49d8, 0x49d9, 0x49da, 0x49db, 0x49dc, 0x49dd, 0x49de, 0x49df, 
+    0x49e0, 0x49e1, 0x49e2, 0x49e3, 0x49e4, 0x49e5, 0x49e6, 0x49e7, 
+    0x49e8, 0x49e9, 0x49ea, 0x49eb, 0x49ec, 0x49ed, 0x49ee, 0x49ef, 
+    0x49f0, 0x49f1, 0x49f2, 0x49f3, 0x49f4, 0x49f5, 0x49f6, 0x49f7, 
+    0x49f8, 0x49f9, 0x49fa, 0x49fb, 0x49fc, 0x49fd, 0x49fe, 0x49ff, 
+    0x4a00, 0x4a01, 0x4a02, 0x4a03, 0x4a04, 0x4a05, 0x4a06, 0x4a07, 
+    0x4a08, 0x4a09, 0x4a0a, 0x4a0b, 0x4a0c, 0x4a0d, 0x4a0e, 0x4a0f, 
+    0x4a10, 0x4a11, 0x4a12, 0x4a13, 0x4a14, 0x4a15, 0x4a16, 0x4a17, 
+    0x4a18, 0x4a19, 0x4a1a, 0x4a1b, 0x4a1c, 0x4a1d, 0x4a1e, 0x4a1f, 
+    0x4a20, 0x4a21, 0x4a22, 0x4a23, 0x4a24, 0x4a25, 0x4a26, 0x4a27, 
+    0x4a28, 0x4a29, 0x4a2a, 0x4a2b, 0x4a2c, 0x4a2d, 0x4a2e, 0x4a2f, 
+    0x4a30, 0x4a31, 0x4a32, 0x4a33, 0x4a34, 0x4a35, 0x4a36, 0x4a37, 
+    0x4a38, 0x4a39, 0x4a3a, 0x4a3b, 0x4a3c, 0x4a3d, 0x4a3e, 0x4a3f, 
+    0x4a40, 0x4a41, 0x4a42, 0x4a43, 0x4a44, 0x4a45, 0x4a46, 0x4a47, 
+    0x4a48, 0x4a49, 0x4a4a, 0x4a4b, 0x4a4c, 0x4a4d, 0x4a4e, 0x4a4f, 
+    0x4a50, 0x4a51, 0x4a52, 0x4a53, 0x4a54, 0x4a55, 0x4a56, 0x4a57, 
+    0x4a58, 0x4a59, 0x4a5a, 0x4a5b, 0x4a5c, 0x4a5d, 0x4a5e, 0x4a5f, 
+    0x4a60, 0x4a61, 0x4a62, 0x4a63, 0x4a64, 0x4a65, 0x4a66, 0x4a67, 
+    0x4a68, 0x4a69, 0x4a6a, 0x4a6b, 0x4a6c, 0x4a6d, 0x4a6e, 0x4a6f, 
+    0x4a70, 0x4a71, 0x4a72, 0x4a73, 0x4a74, 0x4a75, 0x4a76, 0x4a77, 
+    0x4a78, 0x4a79, 0x4a7a, 0x4a7b, 0x4a7c, 0x4a7d, 0x4a7e, 0x4a7f, 
+    0x4a80, 0x4a81, 0x4a82, 0x4a83, 0x4a84, 0x4a85, 0x4a86, 0x4a87, 
+    0x4a88, 0x4a89, 0x4a8a, 0x4a8b, 0x4a8c, 0x4a8d, 0x4a8e, 0x4a8f, 
+    0x4a90, 0x4a91, 0x4a92, 0x4a93, 0x4a94, 0x4a95, 0x4a96, 0x4a97, 
+    0x4a98, 0x4a99, 0x4a9a, 0x4a9b, 0x4a9c, 0x4a9d, 0x4a9e, 0x4a9f, 
+    0x4aa0, 0x4aa1, 0x4aa2, 0x4aa3, 0x4aa4, 0x4aa5, 0x4aa6, 0x4aa7, 
+    0x4aa8, 0x4aa9, 0x4aaa, 0x4aab, 0x4aac, 0x4aad, 0x4aae, 0x4aaf, 
+    0x4ab0, 0x4ab1, 0x4ab2, 0x4ab3, 0x4ab4, 0x4ab5, 0x4ab6, 0x4ab7, 
+    0x4ab8, 0x4ab9, 0x4aba, 0x4abb, 0x4abc, 0x4abd, 0x4abe, 0x4abf, 
+    0x4ac0, 0x4ac1, 0x4ac2, 0x4ac3, 0x4ac4, 0x4ac5, 0x4ac6, 0x4ac7, 
+    0x4ac8, 0x4ac9, 0x4aca, 0x4acb, 0x4acc, 0x4acd, 0x4ace, 0x4acf, 
+    0x4ad0, 0x4ad1, 0x4ad2, 0x4ad3, 0x4ad4, 0x4ad5, 0x4ad6, 0x4ad7, 
+    0x4ad8, 0x4ad9, 0x4ada, 0x4adb, 0x4adc, 0x4add, 0x4ade, 0x4adf, 
+    0x4ae0, 0x4ae1, 0x4ae2, 0x4ae3, 0x4ae4, 0x4ae5, 0x4ae6, 0x4ae7, 
+    0x4ae8, 0x4ae9, 0x4aea, 0x4aeb, 0x4aec, 0x4aed, 0x4aee, 0x4aef, 
+    0x4af0, 0x4af1, 0x4af2, 0x4af3, 0x4af4, 0x4af5, 0x4af6, 0x4af7, 
+    0x4af8, 0x4af9, 0x4afa, 0x4afb, 0x4afc, 0x4afd, 0x4afe, 0x4aff, 
+    0x4b00, 0x4b01, 0x4b02, 0x4b03, 0x4b04, 0x4b05, 0x4b06, 0x4b07, 
+    0x4b08, 0x4b09, 0x4b0a, 0x4b0b, 0x4b0c, 0x4b0d, 0x4b0e, 0x4b0f, 
+    0x4b10, 0x4b11, 0x4b12, 0x4b13, 0x4b14, 0x4b15, 0x4b16, 0x4b17, 
+    0x4b18, 0x4b19, 0x4b1a, 0x4b1b, 0x4b1c, 0x4b1d, 0x4b1e, 0x4b1f, 
+    0x4b20, 0x4b21, 0x4b22, 0x4b23, 0x4b24, 0x4b25, 0x4b26, 0x4b27, 
+    0x4b28, 0x4b29, 0x4b2a, 0x4b2b, 0x4b2c, 0x4b2d, 0x4b2e, 0x4b2f, 
+    0x4b30, 0x4b31, 0x4b32, 0x4b33, 0x4b34, 0x4b35, 0x4b36, 0x4b37, 
+    0x4b38, 0x4b39, 0x4b3a, 0x4b3b, 0x4b3c, 0x4b3d, 0x4b3e, 0x4b3f, 
+    0x4b40, 0x4b41, 0x4b42, 0x4b43, 0x4b44, 0x4b45, 0x4b46, 0x4b47, 
+    0x4b48, 0x4b49, 0x4b4a, 0x4b4b, 0x4b4c, 0x4b4d, 0x4b4e, 0x4b4f, 
+    0x4b50, 0x4b51, 0x4b52, 0x4b53, 0x4b54, 0x4b55, 0x4b56, 0x4b57, 
+    0x4b58, 0x4b59, 0x4b5a, 0x4b5b, 0x4b5c, 0x4b5d, 0x4b5e, 0x4b5f, 
+    0x4b60, 0x4b61, 0x4b62, 0x4b63, 0x4b64, 0x4b65, 0x4b66, 0x4b67, 
+    0x4b68, 0x4b69, 0x4b6a, 0x4b6b, 0x4b6c, 0x4b6d, 0x4b6e, 0x4b6f, 
+    0x4b70, 0x4b71, 0x4b72, 0x4b73, 0x4b74, 0x4b75, 0x4b76, 0x4b77, 
+    0x4b78, 0x4b79, 0x4b7a, 0x4b7b, 0x4b7c, 0x4b7d, 0x4b7e, 0x4b7f, 
+    0x4b80, 0x4b81, 0x4b82, 0x4b83, 0x4b84, 0x4b85, 0x4b86, 0x4b87, 
+    0x4b88, 0x4b89, 0x4b8a, 0x4b8b, 0x4b8c, 0x4b8d, 0x4b8e, 0x4b8f, 
+    0x4b90, 0x4b91, 0x4b92, 0x4b93, 0x4b94, 0x4b95, 0x4b96, 0x4b97, 
+    0x4b98, 0x4b99, 0x4b9a, 0x4b9b, 0x4b9c, 0x4b9d, 0x4b9e, 0x4b9f, 
+    0x4ba0, 0x4ba1, 0x4ba2, 0x4ba3, 0x4ba4, 0x4ba5, 0x4ba6, 0x4ba7, 
+    0x4ba8, 0x4ba9, 0x4baa, 0x4bab, 0x4bac, 0x4bad, 0x4bae, 0x4baf, 
+    0x4bb0, 0x4bb1, 0x4bb2, 0x4bb3, 0x4bb4, 0x4bb5, 0x4bb6, 0x4bb7, 
+    0x4bb8, 0x4bb9, 0x4bba, 0x4bbb, 0x4bbc, 0x4bbd, 0x4bbe, 0x4bbf, 
+    0x4bc0, 0x4bc1, 0x4bc2, 0x4bc3, 0x4bc4, 0x4bc5, 0x4bc6, 0x4bc7, 
+    0x4bc8, 0x4bc9, 0x4bca, 0x4bcb, 0x4bcc, 0x4bcd, 0x4bce, 0x4bcf, 
+    0x4bd0, 0x4bd1, 0x4bd2, 0x4bd3, 0x4bd4, 0x4bd5, 0x4bd6, 0x4bd7, 
+    0x4bd8, 0x4bd9, 0x4bda, 0x4bdb, 0x4bdc, 0x4bdd, 0x4bde, 0x4bdf, 
+    0x4be0, 0x4be1, 0x4be2, 0x4be3, 0x4be4, 0x4be5, 0x4be6, 0x4be7, 
+    0x4be8, 0x4be9, 0x4bea, 0x4beb, 0x4bec, 0x4bed, 0x4bee, 0x4bef, 
+    0x4bf0, 0x4bf1, 0x4bf2, 0x4bf3, 0x4bf4, 0x4bf5, 0x4bf6, 0x4bf7, 
+    0x4bf8, 0x4bf9, 0x4bfa, 0x4bfb, 0x4bfc, 0x4bfd, 0x4bfe, 0x4bff, 
+    0x4c00, 0x4c01, 0x4c02, 0x4c03, 0x4c04, 0x4c05, 0x4c06, 0x4c07, 
+    0x4c08, 0x4c09, 0x4c0a, 0x4c0b, 0x4c0c, 0x4c0d, 0x4c0e, 0x4c0f, 
+    0x4c10, 0x4c11, 0x4c12, 0x4c13, 0x4c14, 0x4c15, 0x4c16, 0x4c17, 
+    0x4c18, 0x4c19, 0x4c1a, 0x4c1b, 0x4c1c, 0x4c1d, 0x4c1e, 0x4c1f, 
+    0x4c20, 0x4c21, 0x4c22, 0x4c23, 0x4c24, 0x4c25, 0x4c26, 0x4c27, 
+    0x4c28, 0x4c29, 0x4c2a, 0x4c2b, 0x4c2c, 0x4c2d, 0x4c2e, 0x4c2f, 
+    0x4c30, 0x4c31, 0x4c32, 0x4c33, 0x4c34, 0x4c35, 0x4c36, 0x4c37, 
+    0x4c38, 0x4c39, 0x4c3a, 0x4c3b, 0x4c3c, 0x4c3d, 0x4c3e, 0x4c3f, 
+    0x4c40, 0x4c41, 0x4c42, 0x4c43, 0x4c44, 0x4c45, 0x4c46, 0x4c47, 
+    0x4c48, 0x4c49, 0x4c4a, 0x4c4b, 0x4c4c, 0x4c4d, 0x4c4e, 0x4c4f, 
+    0x4c50, 0x4c51, 0x4c52, 0x4c53, 0x4c54, 0x4c55, 0x4c56, 0x4c57, 
+    0x4c58, 0x4c59, 0x4c5a, 0x4c5b, 0x4c5c, 0x4c5d, 0x4c5e, 0x4c5f, 
+    0x4c60, 0x4c61, 0x4c62, 0x4c63, 0x4c64, 0x4c65, 0x4c66, 0x4c67, 
+    0x4c68, 0x4c69, 0x4c6a, 0x4c6b, 0x4c6c, 0x4c6d, 0x4c6e, 0x4c6f, 
+    0x4c70, 0x4c71, 0x4c72, 0x4c73, 0x4c74, 0x4c75, 0x4c76, 0x4c77, 
+    0x4c78, 0x4c79, 0x4c7a, 0x4c7b, 0x4c7c, 0x4c7d, 0x4c7e, 0x4c7f, 
+    0x4c80, 0x4c81, 0x4c82, 0x4c83, 0x4c84, 0x4c85, 0x4c86, 0x4c87, 
+    0x4c88, 0x4c89, 0x4c8a, 0x4c8b, 0x4c8c, 0x4c8d, 0x4c8e, 0x4c8f, 
+    0x4c90, 0x4c91, 0x4c92, 0x4c93, 0x4c94, 0x4c95, 0x4c96, 0x4c97, 
+    0x4c98, 0x4c99, 0x4c9a, 0x4c9b, 0x4c9c, 0x4c9d, 0x4c9e, 0x4c9f, 
+    0x4ca0, 0x4ca1, 0x4ca2, 0x4ca3, 0x4ca4, 0x4ca5, 0x4ca6, 0x4ca7, 
+    0x4ca8, 0x4ca9, 0x4caa, 0x4cab, 0x4cac, 0x4cad, 0x4cae, 0x4caf, 
+    0x4cb0, 0x4cb1, 0x4cb2, 0x4cb3, 0x4cb4, 0x4cb5, 0x4cb6, 0x4cb7, 
+    0x4cb8, 0x4cb9, 0x4cba, 0x4cbb, 0x4cbc, 0x4cbd, 0x4cbe, 0x4cbf, 
+    0x4cc0, 0x4cc1, 0x4cc2, 0x4cc3, 0x4cc4, 0x4cc5, 0x4cc6, 0x4cc7, 
+    0x4cc8, 0x4cc9, 0x4cca, 0x4ccb, 0x4ccc, 0x4ccd, 0x4cce, 0x4ccf, 
+    0x4cd0, 0x4cd1, 0x4cd2, 0x4cd3, 0x4cd4, 0x4cd5, 0x4cd6, 0x4cd7, 
+    0x4cd8, 0x4cd9, 0x4cda, 0x4cdb, 0x4cdc, 0x4cdd, 0x4cde, 0x4cdf, 
+    0x4ce0, 0x4ce1, 0x4ce2, 0x4ce3, 0x4ce4, 0x4ce5, 0x4ce6, 0x4ce7, 
+    0x4ce8, 0x4ce9, 0x4cea, 0x4ceb, 0x4cec, 0x4ced, 0x4cee, 0x4cef, 
+    0x4cf0, 0x4cf1, 0x4cf2, 0x4cf3, 0x4cf4, 0x4cf5, 0x4cf6, 0x4cf7, 
+    0x4cf8, 0x4cf9, 0x4cfa, 0x4cfb, 0x4cfc, 0x4cfd, 0x4cfe, 0x4cff, 
+    0x4d00, 0x4d01, 0x4d02, 0x4d03, 0x4d04, 0x4d05, 0x4d06, 0x4d07, 
+    0x4d08, 0x4d09, 0x4d0a, 0x4d0b, 0x4d0c, 0x4d0d, 0x4d0e, 0x4d0f, 
+    0x4d10, 0x4d11, 0x4d12, 0x4d13, 0x4d14, 0x4d15, 0x4d16, 0x4d17, 
+    0x4d18, 0x4d19, 0x4d1a, 0x4d1b, 0x4d1c, 0x4d1d, 0x4d1e, 0x4d1f, 
+    0x4d20, 0x4d21, 0x4d22, 0x4d23, 0x4d24, 0x4d25, 0x4d26, 0x4d27, 
+    0x4d28, 0x4d29, 0x4d2a, 0x4d2b, 0x4d2c, 0x4d2d, 0x4d2e, 0x4d2f, 
+    0x4d30, 0x4d31, 0x4d32, 0x4d33, 0x4d34, 0x4d35, 0x4d36, 0x4d37, 
+    0x4d38, 0x4d39, 0x4d3a, 0x4d3b, 0x4d3c, 0x4d3d, 0x4d3e, 0x4d3f, 
+    0x4d40, 0x4d41, 0x4d42, 0x4d43, 0x4d44, 0x4d45, 0x4d46, 0x4d47, 
+    0x4d48, 0x4d49, 0x4d4a, 0x4d4b, 0x4d4c, 0x4d4d, 0x4d4e, 0x4d4f, 
+    0x4d50, 0x4d51, 0x4d52, 0x4d53, 0x4d54, 0x4d55, 0x4d56, 0x4d57, 
+    0x4d58, 0x4d59, 0x4d5a, 0x4d5b, 0x4d5c, 0x4d5d, 0x4d5e, 0x4d5f, 
+    0x4d60, 0x4d61, 0x4d62, 0x4d63, 0x4d64, 0x4d65, 0x4d66, 0x4d67, 
+    0x4d68, 0x4d69, 0x4d6a, 0x4d6b, 0x4d6c, 0x4d6d, 0x4d6e, 0x4d6f, 
+    0x4d70, 0x4d71, 0x4d72, 0x4d73, 0x4d74, 0x4d75, 0x4d76, 0x4d77, 
+    0x4d78, 0x4d79, 0x4d7a, 0x4d7b, 0x4d7c, 0x4d7d, 0x4d7e, 0x4d7f, 
+    0x4d80, 0x4d81, 0x4d82, 0x4d83, 0x4d84, 0x4d85, 0x4d86, 0x4d87, 
+    0x4d88, 0x4d89, 0x4d8a, 0x4d8b, 0x4d8c, 0x4d8d, 0x4d8e, 0x4d8f, 
+    0x4d90, 0x4d91, 0x4d92, 0x4d93, 0x4d94, 0x4d95, 0x4d96, 0x4d97, 
+    0x4d98, 0x4d99, 0x4d9a, 0x4d9b, 0x4d9c, 0x4d9d, 0x4d9e, 0x4d9f, 
+    0x4da0, 0x4da1, 0x4da2, 0x4da3, 0x4da4, 0x4da5, 0x4da6, 0x4da7, 
+    0x4da8, 0x4da9, 0x4daa, 0x4dab, 0x4dac, 0x4dad, 0x4dae, 0x4daf, 
+    0x4db0, 0x4db1, 0x4db2, 0x4db3, 0x4db4, 0x4db5, 0x4db6, 0x4db7, 
+    0x4db8, 0x4db9, 0x4dba, 0x4dbb, 0x4dbc, 0x4dbd, 0x4dbe, 0x4dbf, 
+    0x4dc0, 0x4dc1, 0x4dc2, 0x4dc3, 0x4dc4, 0x4dc5, 0x4dc6, 0x4dc7, 
+    0x4dc8, 0x4dc9, 0x4dca, 0x4dcb, 0x4dcc, 0x4dcd, 0x4dce, 0x4dcf, 
+    0x4dd0, 0x4dd1, 0x4dd2, 0x4dd3, 0x4dd4, 0x4dd5, 0x4dd6, 0x4dd7, 
+    0x4dd8, 0x4dd9, 0x4dda, 0x4ddb, 0x4ddc, 0x4ddd, 0x4dde, 0x4ddf, 
+    0x4de0, 0x4de1, 0x4de2, 0x4de3, 0x4de4, 0x4de5, 0x4de6, 0x4de7, 
+    0x4de8, 0x4de9, 0x4dea, 0x4deb, 0x4dec, 0x4ded, 0x4dee, 0x4def, 
+    0x4df0, 0x4df1, 0x4df2, 0x4df3, 0x4df4, 0x4df5, 0x4df6, 0x4df7, 
+    0x4df8, 0x4df9, 0x4dfa, 0x4dfb, 0x4dfc, 0x4dfd, 0x4dfe, 0x4dff, 
+    0x4e00, 0x4e01, 0x4e02, 0x4e03, 0x4e04, 0x4e05, 0x4e06, 0x4e07, 
+    0x4e08, 0x4e09, 0x4e0a, 0x4e0b, 0x4e0c, 0x4e0d, 0x4e0e, 0x4e0f, 
+    0x4e10, 0x4e11, 0x4e12, 0x4e13, 0x4e14, 0x4e15, 0x4e16, 0x4e17, 
+    0x4e18, 0x4e19, 0x4e1a, 0x4e1b, 0x4e1c, 0x4e1d, 0x4e1e, 0x4e1f, 
+    0x4e20, 0x4e21, 0x4e22, 0x4e23, 0x4e24, 0x4e25, 0x4e26, 0x4e27, 
+    0x4e28, 0x4e29, 0x4e2a, 0x4e2b, 0x4e2c, 0x4e2d, 0x4e2e, 0x4e2f, 
+    0x4e30, 0x4e31, 0x4e32, 0x4e33, 0x4e34, 0x4e35, 0x4e36, 0x4e37, 
+    0x4e38, 0x4e39, 0x4e3a, 0x4e3b, 0x4e3c, 0x4e3d, 0x4e3e, 0x4e3f, 
+    0x4e40, 0x4e41, 0x4e42, 0x4e43, 0x4e44, 0x4e45, 0x4e46, 0x4e47, 
+    0x4e48, 0x4e49, 0x4e4a, 0x4e4b, 0x4e4c, 0x4e4d, 0x4e4e, 0x4e4f, 
+    0x4e50, 0x4e51, 0x4e52, 0x4e53, 0x4e54, 0x4e55, 0x4e56, 0x4e57, 
+    0x4e58, 0x4e59, 0x4e5a, 0x4e5b, 0x4e5c, 0x4e5d, 0x4e5e, 0x4e5f, 
+    0x4e60, 0x4e61, 0x4e62, 0x4e63, 0x4e64, 0x4e65, 0x4e66, 0x4e67, 
+    0x4e68, 0x4e69, 0x4e6a, 0x4e6b, 0x4e6c, 0x4e6d, 0x4e6e, 0x4e6f, 
+    0x4e70, 0x4e71, 0x4e72, 0x4e73, 0x4e74, 0x4e75, 0x4e76, 0x4e77, 
+    0x4e78, 0x4e79, 0x4e7a, 0x4e7b, 0x4e7c, 0x4e7d, 0x4e7e, 0x4e7f, 
+    0x4e80, 0x4e81, 0x4e82, 0x4e83, 0x4e84, 0x4e85, 0x4e86, 0x4e87, 
+    0x4e88, 0x4e89, 0x4e8a, 0x4e8b, 0x4e8c, 0x4e8d, 0x4e8e, 0x4e8f, 
+    0x4e90, 0x4e91, 0x4e92, 0x4e93, 0x4e94, 0x4e95, 0x4e96, 0x4e97, 
+    0x4e98, 0x4e99, 0x4e9a, 0x4e9b, 0x4e9c, 0x4e9d, 0x4e9e, 0x4e9f, 
+    0x4ea0, 0x4ea1, 0x4ea2, 0x4ea3, 0x4ea4, 0x4ea5, 0x4ea6, 0x4ea7, 
+    0x4ea8, 0x4ea9, 0x4eaa, 0x4eab, 0x4eac, 0x4ead, 0x4eae, 0x4eaf, 
+    0x4eb0, 0x4eb1, 0x4eb2, 0x4eb3, 0x4eb4, 0x4eb5, 0x4eb6, 0x4eb7, 
+    0x4eb8, 0x4eb9, 0x4eba, 0x4ebb, 0x4ebc, 0x4ebd, 0x4ebe, 0x4ebf, 
+    0x4ec0, 0x4ec1, 0x4ec2, 0x4ec3, 0x4ec4, 0x4ec5, 0x4ec6, 0x4ec7, 
+    0x4ec8, 0x4ec9, 0x4eca, 0x4ecb, 0x4ecc, 0x4ecd, 0x4ece, 0x4ecf, 
+    0x4ed0, 0x4ed1, 0x4ed2, 0x4ed3, 0x4ed4, 0x4ed5, 0x4ed6, 0x4ed7, 
+    0x4ed8, 0x4ed9, 0x4eda, 0x4edb, 0x4edc, 0x4edd, 0x4ede, 0x4edf, 
+    0x4ee0, 0x4ee1, 0x4ee2, 0x4ee3, 0x4ee4, 0x4ee5, 0x4ee6, 0x4ee7, 
+    0x4ee8, 0x4ee9, 0x4eea, 0x4eeb, 0x4eec, 0x4eed, 0x4eee, 0x4eef, 
+    0x4ef0, 0x4ef1, 0x4ef2, 0x4ef3, 0x4ef4, 0x4ef5, 0x4ef6, 0x4ef7, 
+    0x4ef8, 0x4ef9, 0x4efa, 0x4efb, 0x4efc, 0x4efd, 0x4efe, 0x4eff, 
+    0x4f00, 0x4f01, 0x4f02, 0x4f03, 0x4f04, 0x4f05, 0x4f06, 0x4f07, 
+    0x4f08, 0x4f09, 0x4f0a, 0x4f0b, 0x4f0c, 0x4f0d, 0x4f0e, 0x4f0f, 
+    0x4f10, 0x4f11, 0x4f12, 0x4f13, 0x4f14, 0x4f15, 0x4f16, 0x4f17, 
+    0x4f18, 0x4f19, 0x4f1a, 0x4f1b, 0x4f1c, 0x4f1d, 0x4f1e, 0x4f1f, 
+    0x4f20, 0x4f21, 0x4f22, 0x4f23, 0x4f24, 0x4f25, 0x4f26, 0x4f27, 
+    0x4f28, 0x4f29, 0x4f2a, 0x4f2b, 0x4f2c, 0x4f2d, 0x4f2e, 0x4f2f, 
+    0x4f30, 0x4f31, 0x4f32, 0x4f33, 0x4f34, 0x4f35, 0x4f36, 0x4f37, 
+    0x4f38, 0x4f39, 0x4f3a, 0x4f3b, 0x4f3c, 0x4f3d, 0x4f3e, 0x4f3f, 
+    0x4f40, 0x4f41, 0x4f42, 0x4f43, 0x4f44, 0x4f45, 0x4f46, 0x4f47, 
+    0x4f48, 0x4f49, 0x4f4a, 0x4f4b, 0x4f4c, 0x4f4d, 0x4f4e, 0x4f4f, 
+    0x4f50, 0x4f51, 0x4f52, 0x4f53, 0x4f54, 0x4f55, 0x4f56, 0x4f57, 
+    0x4f58, 0x4f59, 0x4f5a, 0x4f5b, 0x4f5c, 0x4f5d, 0x4f5e, 0x4f5f, 
+    0x4f60, 0x4f61, 0x4f62, 0x4f63, 0x4f64, 0x4f65, 0x4f66, 0x4f67, 
+    0x4f68, 0x4f69, 0x4f6a, 0x4f6b, 0x4f6c, 0x4f6d, 0x4f6e, 0x4f6f, 
+    0x4f70, 0x4f71, 0x4f72, 0x4f73, 0x4f74, 0x4f75, 0x4f76, 0x4f77, 
+    0x4f78, 0x4f79, 0x4f7a, 0x4f7b, 0x4f7c, 0x4f7d, 0x4f7e, 0x4f7f, 
+    0x4f80, 0x4f81, 0x4f82, 0x4f83, 0x4f84, 0x4f85, 0x4f86, 0x4f87, 
+    0x4f88, 0x4f89, 0x4f8a, 0x4f8b, 0x4f8c, 0x4f8d, 0x4f8e, 0x4f8f, 
+    0x4f90, 0x4f91, 0x4f92, 0x4f93, 0x4f94, 0x4f95, 0x4f96, 0x4f97, 
+    0x4f98, 0x4f99, 0x4f9a, 0x4f9b, 0x4f9c, 0x4f9d, 0x4f9e, 0x4f9f, 
+    0x4fa0, 0x4fa1, 0x4fa2, 0x4fa3, 0x4fa4, 0x4fa5, 0x4fa6, 0x4fa7, 
+    0x4fa8, 0x4fa9, 0x4faa, 0x4fab, 0x4fac, 0x4fad, 0x4fae, 0x4faf, 
+    0x4fb0, 0x4fb1, 0x4fb2, 0x4fb3, 0x4fb4, 0x4fb5, 0x4fb6, 0x4fb7, 
+    0x4fb8, 0x4fb9, 0x4fba, 0x4fbb, 0x4fbc, 0x4fbd, 0x4fbe, 0x4fbf, 
+    0x4fc0, 0x4fc1, 0x4fc2, 0x4fc3, 0x4fc4, 0x4fc5, 0x4fc6, 0x4fc7, 
+    0x4fc8, 0x4fc9, 0x4fca, 0x4fcb, 0x4fcc, 0x4fcd, 0x4fce, 0x4fcf, 
+    0x4fd0, 0x4fd1, 0x4fd2, 0x4fd3, 0x4fd4, 0x4fd5, 0x4fd6, 0x4fd7, 
+    0x4fd8, 0x4fd9, 0x4fda, 0x4fdb, 0x4fdc, 0x4fdd, 0x4fde, 0x4fdf, 
+    0x4fe0, 0x4fe1, 0x4fe2, 0x4fe3, 0x4fe4, 0x4fe5, 0x4fe6, 0x4fe7, 
+    0x4fe8, 0x4fe9, 0x4fea, 0x4feb, 0x4fec, 0x4fed, 0x4fee, 0x4fef, 
+    0x4ff0, 0x4ff1, 0x4ff2, 0x4ff3, 0x4ff4, 0x4ff5, 0x4ff6, 0x4ff7, 
+    0x4ff8, 0x4ff9, 0x4ffa, 0x4ffb, 0x4ffc, 0x4ffd, 0x4ffe, 0x4fff, 
+    0x5000, 0x5001, 0x5002, 0x5003, 0x5004, 0x5005, 0x5006, 0x5007, 
+    0x5008, 0x5009, 0x500a, 0x500b, 0x500c, 0x500d, 0x500e, 0x500f, 
+    0x5010, 0x5011, 0x5012, 0x5013, 0x5014, 0x5015, 0x5016, 0x5017, 
+    0x5018, 0x5019, 0x501a, 0x501b, 0x501c, 0x501d, 0x501e, 0x501f, 
+    0x5020, 0x5021, 0x5022, 0x5023, 0x5024, 0x5025, 0x5026, 0x5027, 
+    0x5028, 0x5029, 0x502a, 0x502b, 0x502c, 0x502d, 0x502e, 0x502f, 
+    0x5030, 0x5031, 0x5032, 0x5033, 0x5034, 0x5035, 0x5036, 0x5037, 
+    0x5038, 0x5039, 0x503a, 0x503b, 0x503c, 0x503d, 0x503e, 0x503f, 
+    0x5040, 0x5041, 0x5042, 0x5043, 0x5044, 0x5045, 0x5046, 0x5047, 
+    0x5048, 0x5049, 0x504a, 0x504b, 0x504c, 0x504d, 0x504e, 0x504f, 
+    0x5050, 0x5051, 0x5052, 0x5053, 0x5054, 0x5055, 0x5056, 0x5057, 
+    0x5058, 0x5059, 0x505a, 0x505b, 0x505c, 0x505d, 0x505e, 0x505f, 
+    0x5060, 0x5061, 0x5062, 0x5063, 0x5064, 0x5065, 0x5066, 0x5067, 
+    0x5068, 0x5069, 0x506a, 0x506b, 0x506c, 0x506d, 0x506e, 0x506f, 
+    0x5070, 0x5071, 0x5072, 0x5073, 0x5074, 0x5075, 0x5076, 0x5077, 
+    0x5078, 0x5079, 0x507a, 0x507b, 0x507c, 0x507d, 0x507e, 0x507f, 
+    0x5080, 0x5081, 0x5082, 0x5083, 0x5084, 0x5085, 0x5086, 0x5087, 
+    0x5088, 0x5089, 0x508a, 0x508b, 0x508c, 0x508d, 0x508e, 0x508f, 
+    0x5090, 0x5091, 0x5092, 0x5093, 0x5094, 0x5095, 0x5096, 0x5097, 
+    0x5098, 0x5099, 0x509a, 0x509b, 0x509c, 0x509d, 0x509e, 0x509f, 
+    0x50a0, 0x50a1, 0x50a2, 0x50a3, 0x50a4, 0x50a5, 0x50a6, 0x50a7, 
+    0x50a8, 0x50a9, 0x50aa, 0x50ab, 0x50ac, 0x50ad, 0x50ae, 0x50af, 
+    0x50b0, 0x50b1, 0x50b2, 0x50b3, 0x50b4, 0x50b5, 0x50b6, 0x50b7, 
+    0x50b8, 0x50b9, 0x50ba, 0x50bb, 0x50bc, 0x50bd, 0x50be, 0x50bf, 
+    0x50c0, 0x50c1, 0x50c2, 0x50c3, 0x50c4, 0x50c5, 0x50c6, 0x50c7, 
+    0x50c8, 0x50c9, 0x50ca, 0x50cb, 0x50cc, 0x50cd, 0x50ce, 0x50cf, 
+    0x50d0, 0x50d1, 0x50d2, 0x50d3, 0x50d4, 0x50d5, 0x50d6, 0x50d7, 
+    0x50d8, 0x50d9, 0x50da, 0x50db, 0x50dc, 0x50dd, 0x50de, 0x50df, 
+    0x50e0, 0x50e1, 0x50e2, 0x50e3, 0x50e4, 0x50e5, 0x50e6, 0x50e7, 
+    0x50e8, 0x50e9, 0x50ea, 0x50eb, 0x50ec, 0x50ed, 0x50ee, 0x50ef, 
+    0x50f0, 0x50f1, 0x50f2, 0x50f3, 0x50f4, 0x50f5, 0x50f6, 0x50f7, 
+    0x50f8, 0x50f9, 0x50fa, 0x50fb, 0x50fc, 0x50fd, 0x50fe, 0x50ff, 
+    0x5100, 0x5101, 0x5102, 0x5103, 0x5104, 0x5105, 0x5106, 0x5107, 
+    0x5108, 0x5109, 0x510a, 0x510b, 0x510c, 0x510d, 0x510e, 0x510f, 
+    0x5110, 0x5111, 0x5112, 0x5113, 0x5114, 0x5115, 0x5116, 0x5117, 
+    0x5118, 0x5119, 0x511a, 0x511b, 0x511c, 0x511d, 0x511e, 0x511f, 
+    0x5120, 0x5121, 0x5122, 0x5123, 0x5124, 0x5125, 0x5126, 0x5127, 
+    0x5128, 0x5129, 0x512a, 0x512b, 0x512c, 0x512d, 0x512e, 0x512f, 
+    0x5130, 0x5131, 0x5132, 0x5133, 0x5134, 0x5135, 0x5136, 0x5137, 
+    0x5138, 0x5139, 0x513a, 0x513b, 0x513c, 0x513d, 0x513e, 0x513f, 
+    0x5140, 0x5141, 0x5142, 0x5143, 0x5144, 0x5145, 0x5146, 0x5147, 
+    0x5148, 0x5149, 0x514a, 0x514b, 0x514c, 0x514d, 0x514e, 0x514f, 
+    0x5150, 0x5151, 0x5152, 0x5153, 0x5154, 0x5155, 0x5156, 0x5157, 
+    0x5158, 0x5159, 0x515a, 0x515b, 0x515c, 0x515d, 0x515e, 0x515f, 
+    0x5160, 0x5161, 0x5162, 0x5163, 0x5164, 0x5165, 0x5166, 0x5167, 
+    0x5168, 0x5169, 0x516a, 0x516b, 0x516c, 0x516d, 0x516e, 0x516f, 
+    0x5170, 0x5171, 0x5172, 0x5173, 0x5174, 0x5175, 0x5176, 0x5177, 
+    0x5178, 0x5179, 0x517a, 0x517b, 0x517c, 0x517d, 0x517e, 0x517f, 
+    0x5180, 0x5181, 0x5182, 0x5183, 0x5184, 0x5185, 0x5186, 0x5187, 
+    0x5188, 0x5189, 0x518a, 0x518b, 0x518c, 0x518d, 0x518e, 0x518f, 
+    0x5190, 0x5191, 0x5192, 0x5193, 0x5194, 0x5195, 0x5196, 0x5197, 
+    0x5198, 0x5199, 0x519a, 0x519b, 0x519c, 0x519d, 0x519e, 0x519f, 
+    0x51a0, 0x51a1, 0x51a2, 0x51a3, 0x51a4, 0x51a5, 0x51a6, 0x51a7, 
+    0x51a8, 0x51a9, 0x51aa, 0x51ab, 0x51ac, 0x51ad, 0x51ae, 0x51af, 
+    0x51b0, 0x51b1, 0x51b2, 0x51b3, 0x51b4, 0x51b5, 0x51b6, 0x51b7, 
+    0x51b8, 0x51b9, 0x51ba, 0x51bb, 0x51bc, 0x51bd, 0x51be, 0x51bf, 
+    0x51c0, 0x51c1, 0x51c2, 0x51c3, 0x51c4, 0x51c5, 0x51c6, 0x51c7, 
+    0x51c8, 0x51c9, 0x51ca, 0x51cb, 0x51cc, 0x51cd, 0x51ce, 0x51cf, 
+    0x51d0, 0x51d1, 0x51d2, 0x51d3, 0x51d4, 0x51d5, 0x51d6, 0x51d7, 
+    0x51d8, 0x51d9, 0x51da, 0x51db, 0x51dc, 0x51dd, 0x51de, 0x51df, 
+    0x51e0, 0x51e1, 0x51e2, 0x51e3, 0x51e4, 0x51e5, 0x51e6, 0x51e7, 
+    0x51e8, 0x51e9, 0x51ea, 0x51eb, 0x51ec, 0x51ed, 0x51ee, 0x51ef, 
+    0x51f0, 0x51f1, 0x51f2, 0x51f3, 0x51f4, 0x51f5, 0x51f6, 0x51f7, 
+    0x51f8, 0x51f9, 0x51fa, 0x51fb, 0x51fc, 0x51fd, 0x51fe, 0x51ff, 
+    0x5200, 0x5201, 0x5202, 0x5203, 0x5204, 0x5205, 0x5206, 0x5207, 
+    0x5208, 0x5209, 0x520a, 0x520b, 0x520c, 0x520d, 0x520e, 0x520f, 
+    0x5210, 0x5211, 0x5212, 0x5213, 0x5214, 0x5215, 0x5216, 0x5217, 
+    0x5218, 0x5219, 0x521a, 0x521b, 0x521c, 0x521d, 0x521e, 0x521f, 
+    0x5220, 0x5221, 0x5222, 0x5223, 0x5224, 0x5225, 0x5226, 0x5227, 
+    0x5228, 0x5229, 0x522a, 0x522b, 0x522c, 0x522d, 0x522e, 0x522f, 
+    0x5230, 0x5231, 0x5232, 0x5233, 0x5234, 0x5235, 0x5236, 0x5237, 
+    0x5238, 0x5239, 0x523a, 0x523b, 0x523c, 0x523d, 0x523e, 0x523f, 
+    0x5240, 0x5241, 0x5242, 0x5243, 0x5244, 0x5245, 0x5246, 0x5247, 
+    0x5248, 0x5249, 0x524a, 0x524b, 0x524c, 0x524d, 0x524e, 0x524f, 
+    0x5250, 0x5251, 0x5252, 0x5253, 0x5254, 0x5255, 0x5256, 0x5257, 
+    0x5258, 0x5259, 0x525a, 0x525b, 0x525c, 0x525d, 0x525e, 0x525f, 
+    0x5260, 0x5261, 0x5262, 0x5263, 0x5264, 0x5265, 0x5266, 0x5267, 
+    0x5268, 0x5269, 0x526a, 0x526b, 0x526c, 0x526d, 0x526e, 0x526f, 
+    0x5270, 0x5271, 0x5272, 0x5273, 0x5274, 0x5275, 0x5276, 0x5277, 
+    0x5278, 0x5279, 0x527a, 0x527b, 0x527c, 0x527d, 0x527e, 0x527f, 
+    0x5280, 0x5281, 0x5282, 0x5283, 0x5284, 0x5285, 0x5286, 0x5287, 
+    0x5288, 0x5289, 0x528a, 0x528b, 0x528c, 0x528d, 0x528e, 0x528f, 
+    0x5290, 0x5291, 0x5292, 0x5293, 0x5294, 0x5295, 0x5296, 0x5297, 
+    0x5298, 0x5299, 0x529a, 0x529b, 0x529c, 0x529d, 0x529e, 0x529f, 
+    0x52a0, 0x52a1, 0x52a2, 0x52a3, 0x52a4, 0x52a5, 0x52a6, 0x52a7, 
+    0x52a8, 0x52a9, 0x52aa, 0x52ab, 0x52ac, 0x52ad, 0x52ae, 0x52af, 
+    0x52b0, 0x52b1, 0x52b2, 0x52b3, 0x52b4, 0x52b5, 0x52b6, 0x52b7, 
+    0x52b8, 0x52b9, 0x52ba, 0x52bb, 0x52bc, 0x52bd, 0x52be, 0x52bf, 
+    0x52c0, 0x52c1, 0x52c2, 0x52c3, 0x52c4, 0x52c5, 0x52c6, 0x52c7, 
+    0x52c8, 0x52c9, 0x52ca, 0x52cb, 0x52cc, 0x52cd, 0x52ce, 0x52cf, 
+    0x52d0, 0x52d1, 0x52d2, 0x52d3, 0x52d4, 0x52d5, 0x52d6, 0x52d7, 
+    0x52d8, 0x52d9, 0x52da, 0x52db, 0x52dc, 0x52dd, 0x52de, 0x52df, 
+    0x52e0, 0x52e1, 0x52e2, 0x52e3, 0x52e4, 0x52e5, 0x52e6, 0x52e7, 
+    0x52e8, 0x52e9, 0x52ea, 0x52eb, 0x52ec, 0x52ed, 0x52ee, 0x52ef, 
+    0x52f0, 0x52f1, 0x52f2, 0x52f3, 0x52f4, 0x52f5, 0x52f6, 0x52f7, 
+    0x52f8, 0x52f9, 0x52fa, 0x52fb, 0x52fc, 0x52fd, 0x52fe, 0x52ff, 
+    0x5300, 0x5301, 0x5302, 0x5303, 0x5304, 0x5305, 0x5306, 0x5307, 
+    0x5308, 0x5309, 0x530a, 0x530b, 0x530c, 0x530d, 0x530e, 0x530f, 
+    0x5310, 0x5311, 0x5312, 0x5313, 0x5314, 0x5315, 0x5316, 0x5317, 
+    0x5318, 0x5319, 0x531a, 0x531b, 0x531c, 0x531d, 0x531e, 0x531f, 
+    0x5320, 0x5321, 0x5322, 0x5323, 0x5324, 0x5325, 0x5326, 0x5327, 
+    0x5328, 0x5329, 0x532a, 0x532b, 0x532c, 0x532d, 0x532e, 0x532f, 
+    0x5330, 0x5331, 0x5332, 0x5333, 0x5334, 0x5335, 0x5336, 0x5337, 
+    0x5338, 0x5339, 0x533a, 0x533b, 0x533c, 0x533d, 0x533e, 0x533f, 
+    0x5340, 0x5341, 0x5342, 0x5343, 0x5344, 0x5345, 0x5346, 0x5347, 
+    0x5348, 0x5349, 0x534a, 0x534b, 0x534c, 0x534d, 0x534e, 0x534f, 
+    0x5350, 0x5351, 0x5352, 0x5353, 0x5354, 0x5355, 0x5356, 0x5357, 
+    0x5358, 0x5359, 0x535a, 0x535b, 0x535c, 0x535d, 0x535e, 0x535f, 
+    0x5360, 0x5361, 0x5362, 0x5363, 0x5364, 0x5365, 0x5366, 0x5367, 
+    0x5368, 0x5369, 0x536a, 0x536b, 0x536c, 0x536d, 0x536e, 0x536f, 
+    0x5370, 0x5371, 0x5372, 0x5373, 0x5374, 0x5375, 0x5376, 0x5377, 
+    0x5378, 0x5379, 0x537a, 0x537b, 0x537c, 0x537d, 0x537e, 0x537f, 
+    0x5380, 0x5381, 0x5382, 0x5383, 0x5384, 0x5385, 0x5386, 0x5387, 
+    0x5388, 0x5389, 0x538a, 0x538b, 0x538c, 0x538d, 0x538e, 0x538f, 
+    0x5390, 0x5391, 0x5392, 0x5393, 0x5394, 0x5395, 0x5396, 0x5397, 
+    0x5398, 0x5399, 0x539a, 0x539b, 0x539c, 0x539d, 0x539e, 0x539f, 
+    0x53a0, 0x53a1, 0x53a2, 0x53a3, 0x53a4, 0x53a5, 0x53a6, 0x53a7, 
+    0x53a8, 0x53a9, 0x53aa, 0x53ab, 0x53ac, 0x53ad, 0x53ae, 0x53af, 
+    0x53b0, 0x53b1, 0x53b2, 0x53b3, 0x53b4, 0x53b5, 0x53b6, 0x53b7, 
+    0x53b8, 0x53b9, 0x53ba, 0x53bb, 0x53bc, 0x53bd, 0x53be, 0x53bf, 
+    0x53c0, 0x53c1, 0x53c2, 0x53c3, 0x53c4, 0x53c5, 0x53c6, 0x53c7, 
+    0x53c8, 0x53c9, 0x53ca, 0x53cb, 0x53cc, 0x53cd, 0x53ce, 0x53cf, 
+    0x53d0, 0x53d1, 0x53d2, 0x53d3, 0x53d4, 0x53d5, 0x53d6, 0x53d7, 
+    0x53d8, 0x53d9, 0x53da, 0x53db, 0x53dc, 0x53dd, 0x53de, 0x53df, 
+    0x53e0, 0x53e1, 0x53e2, 0x53e3, 0x53e4, 0x53e5, 0x53e6, 0x53e7, 
+    0x53e8, 0x53e9, 0x53ea, 0x53eb, 0x53ec, 0x53ed, 0x53ee, 0x53ef, 
+    0x53f0, 0x53f1, 0x53f2, 0x53f3, 0x53f4, 0x53f5, 0x53f6, 0x53f7, 
+    0x53f8, 0x53f9, 0x53fa, 0x53fb, 0x53fc, 0x53fd, 0x53fe, 0x53ff, 
+    0x5400, 0x5401, 0x5402, 0x5403, 0x5404, 0x5405, 0x5406, 0x5407, 
+    0x5408, 0x5409, 0x540a, 0x540b, 0x540c, 0x540d, 0x540e, 0x540f, 
+    0x5410, 0x5411, 0x5412, 0x5413, 0x5414, 0x5415, 0x5416, 0x5417, 
+    0x5418, 0x5419, 0x541a, 0x541b, 0x541c, 0x541d, 0x541e, 0x541f, 
+    0x5420, 0x5421, 0x5422, 0x5423, 0x5424, 0x5425, 0x5426, 0x5427, 
+    0x5428, 0x5429, 0x542a, 0x542b, 0x542c, 0x542d, 0x542e, 0x542f, 
+    0x5430, 0x5431, 0x5432, 0x5433, 0x5434, 0x5435, 0x5436, 0x5437, 
+    0x5438, 0x5439, 0x543a, 0x543b, 0x543c, 0x543d, 0x543e, 0x543f, 
+    0x5440, 0x5441, 0x5442, 0x5443, 0x5444, 0x5445, 0x5446, 0x5447, 
+    0x5448, 0x5449, 0x544a, 0x544b, 0x544c, 0x544d, 0x544e, 0x544f, 
+    0x5450, 0x5451, 0x5452, 0x5453, 0x5454, 0x5455, 0x5456, 0x5457, 
+    0x5458, 0x5459, 0x545a, 0x545b, 0x545c, 0x545d, 0x545e, 0x545f, 
+    0x5460, 0x5461, 0x5462, 0x5463, 0x5464, 0x5465, 0x5466, 0x5467, 
+    0x5468, 0x5469, 0x546a, 0x546b, 0x546c, 0x546d, 0x546e, 0x546f, 
+    0x5470, 0x5471, 0x5472, 0x5473, 0x5474, 0x5475, 0x5476, 0x5477, 
+    0x5478, 0x5479, 0x547a, 0x547b, 0x547c, 0x547d, 0x547e, 0x547f, 
+    0x5480, 0x5481, 0x5482, 0x5483, 0x5484, 0x5485, 0x5486, 0x5487, 
+    0x5488, 0x5489, 0x548a, 0x548b, 0x548c, 0x548d, 0x548e, 0x548f, 
+    0x5490, 0x5491, 0x5492, 0x5493, 0x5494, 0x5495, 0x5496, 0x5497, 
+    0x5498, 0x5499, 0x549a, 0x549b, 0x549c, 0x549d, 0x549e, 0x549f, 
+    0x54a0, 0x54a1, 0x54a2, 0x54a3, 0x54a4, 0x54a5, 0x54a6, 0x54a7, 
+    0x54a8, 0x54a9, 0x54aa, 0x54ab, 0x54ac, 0x54ad, 0x54ae, 0x54af, 
+    0x54b0, 0x54b1, 0x54b2, 0x54b3, 0x54b4, 0x54b5, 0x54b6, 0x54b7, 
+    0x54b8, 0x54b9, 0x54ba, 0x54bb, 0x54bc, 0x54bd, 0x54be, 0x54bf, 
+    0x54c0, 0x54c1, 0x54c2, 0x54c3, 0x54c4, 0x54c5, 0x54c6, 0x54c7, 
+    0x54c8, 0x54c9, 0x54ca, 0x54cb, 0x54cc, 0x54cd, 0x54ce, 0x54cf, 
+    0x54d0, 0x54d1, 0x54d2, 0x54d3, 0x54d4, 0x54d5, 0x54d6, 0x54d7, 
+    0x54d8, 0x54d9, 0x54da, 0x54db, 0x54dc, 0x54dd, 0x54de, 0x54df, 
+    0x54e0, 0x54e1, 0x54e2, 0x54e3, 0x54e4, 0x54e5, 0x54e6, 0x54e7, 
+    0x54e8, 0x54e9, 0x54ea, 0x54eb, 0x54ec, 0x54ed, 0x54ee, 0x54ef, 
+    0x54f0, 0x54f1, 0x54f2, 0x54f3, 0x54f4, 0x54f5, 0x54f6, 0x54f7, 
+    0x54f8, 0x54f9, 0x54fa, 0x54fb, 0x54fc, 0x54fd, 0x54fe, 0x54ff, 
+    0x5500, 0x5501, 0x5502, 0x5503, 0x5504, 0x5505, 0x5506, 0x5507, 
+    0x5508, 0x5509, 0x550a, 0x550b, 0x550c, 0x550d, 0x550e, 0x550f, 
+    0x5510, 0x5511, 0x5512, 0x5513, 0x5514, 0x5515, 0x5516, 0x5517, 
+    0x5518, 0x5519, 0x551a, 0x551b, 0x551c, 0x551d, 0x551e, 0x551f, 
+    0x5520, 0x5521, 0x5522, 0x5523, 0x5524, 0x5525, 0x5526, 0x5527, 
+    0x5528, 0x5529, 0x552a, 0x552b, 0x552c, 0x552d, 0x552e, 0x552f, 
+    0x5530, 0x5531, 0x5532, 0x5533, 0x5534, 0x5535, 0x5536, 0x5537, 
+    0x5538, 0x5539, 0x553a, 0x553b, 0x553c, 0x553d, 0x553e, 0x553f, 
+    0x5540, 0x5541, 0x5542, 0x5543, 0x5544, 0x5545, 0x5546, 0x5547, 
+    0x5548, 0x5549, 0x554a, 0x554b, 0x554c, 0x554d, 0x554e, 0x554f, 
+    0x5550, 0x5551, 0x5552, 0x5553, 0x5554, 0x5555, 0x5556, 0x5557, 
+    0x5558, 0x5559, 0x555a, 0x555b, 0x555c, 0x555d, 0x555e, 0x555f, 
+    0x5560, 0x5561, 0x5562, 0x5563, 0x5564, 0x5565, 0x5566, 0x5567, 
+    0x5568, 0x5569, 0x556a, 0x556b, 0x556c, 0x556d, 0x556e, 0x556f, 
+    0x5570, 0x5571, 0x5572, 0x5573, 0x5574, 0x5575, 0x5576, 0x5577, 
+    0x5578, 0x5579, 0x557a, 0x557b, 0x557c, 0x557d, 0x557e, 0x557f, 
+    0x5580, 0x5581, 0x5582, 0x5583, 0x5584, 0x5585, 0x5586, 0x5587, 
+    0x5588, 0x5589, 0x558a, 0x558b, 0x558c, 0x558d, 0x558e, 0x558f, 
+    0x5590, 0x5591, 0x5592, 0x5593, 0x5594, 0x5595, 0x5596, 0x5597, 
+    0x5598, 0x5599, 0x559a, 0x559b, 0x559c, 0x559d, 0x559e, 0x559f, 
+    0x55a0, 0x55a1, 0x55a2, 0x55a3, 0x55a4, 0x55a5, 0x55a6, 0x55a7, 
+    0x55a8, 0x55a9, 0x55aa, 0x55ab, 0x55ac, 0x55ad, 0x55ae, 0x55af, 
+    0x55b0, 0x55b1, 0x55b2, 0x55b3, 0x55b4, 0x55b5, 0x55b6, 0x55b7, 
+    0x55b8, 0x55b9, 0x55ba, 0x55bb, 0x55bc, 0x55bd, 0x55be, 0x55bf, 
+    0x55c0, 0x55c1, 0x55c2, 0x55c3, 0x55c4, 0x55c5, 0x55c6, 0x55c7, 
+    0x55c8, 0x55c9, 0x55ca, 0x55cb, 0x55cc, 0x55cd, 0x55ce, 0x55cf, 
+    0x55d0, 0x55d1, 0x55d2, 0x55d3, 0x55d4, 0x55d5, 0x55d6, 0x55d7, 
+    0x55d8, 0x55d9, 0x55da, 0x55db, 0x55dc, 0x55dd, 0x55de, 0x55df, 
+    0x55e0, 0x55e1, 0x55e2, 0x55e3, 0x55e4, 0x55e5, 0x55e6, 0x55e7, 
+    0x55e8, 0x55e9, 0x55ea, 0x55eb, 0x55ec, 0x55ed, 0x55ee, 0x55ef, 
+    0x55f0, 0x55f1, 0x55f2, 0x55f3, 0x55f4, 0x55f5, 0x55f6, 0x55f7, 
+    0x55f8, 0x55f9, 0x55fa, 0x55fb, 0x55fc, 0x55fd, 0x55fe, 0x55ff, 
+    0x5600, 0x5601, 0x5602, 0x5603, 0x5604, 0x5605, 0x5606, 0x5607, 
+    0x5608, 0x5609, 0x560a, 0x560b, 0x560c, 0x560d, 0x560e, 0x560f, 
+    0x5610, 0x5611, 0x5612, 0x5613, 0x5614, 0x5615, 0x5616, 0x5617, 
+    0x5618, 0x5619, 0x561a, 0x561b, 0x561c, 0x561d, 0x561e, 0x561f, 
+    0x5620, 0x5621, 0x5622, 0x5623, 0x5624, 0x5625, 0x5626, 0x5627, 
+    0x5628, 0x5629, 0x562a, 0x562b, 0x562c, 0x562d, 0x562e, 0x562f, 
+    0x5630, 0x5631, 0x5632, 0x5633, 0x5634, 0x5635, 0x5636, 0x5637, 
+    0x5638, 0x5639, 0x563a, 0x563b, 0x563c, 0x563d, 0x563e, 0x563f, 
+    0x5640, 0x5641, 0x5642, 0x5643, 0x5644, 0x5645, 0x5646, 0x5647, 
+    0x5648, 0x5649, 0x564a, 0x564b, 0x564c, 0x564d, 0x564e, 0x564f, 
+    0x5650, 0x5651, 0x5652, 0x5653, 0x5654, 0x5655, 0x5656, 0x5657, 
+    0x5658, 0x5659, 0x565a, 0x565b, 0x565c, 0x565d, 0x565e, 0x565f, 
+    0x5660, 0x5661, 0x5662, 0x5663, 0x5664, 0x5665, 0x5666, 0x5667, 
+    0x5668, 0x5669, 0x566a, 0x566b, 0x566c, 0x566d, 0x566e, 0x566f, 
+    0x5670, 0x5671, 0x5672, 0x5673, 0x5674, 0x5675, 0x5676, 0x5677, 
+    0x5678, 0x5679, 0x567a, 0x567b, 0x567c, 0x567d, 0x567e, 0x567f, 
+    0x5680, 0x5681, 0x5682, 0x5683, 0x5684, 0x5685, 0x5686, 0x5687, 
+    0x5688, 0x5689, 0x568a, 0x568b, 0x568c, 0x568d, 0x568e, 0x568f, 
+    0x5690, 0x5691, 0x5692, 0x5693, 0x5694, 0x5695, 0x5696, 0x5697, 
+    0x5698, 0x5699, 0x569a, 0x569b, 0x569c, 0x569d, 0x569e, 0x569f, 
+    0x56a0, 0x56a1, 0x56a2, 0x56a3, 0x56a4, 0x56a5, 0x56a6, 0x56a7, 
+    0x56a8, 0x56a9, 0x56aa, 0x56ab, 0x56ac, 0x56ad, 0x56ae, 0x56af, 
+    0x56b0, 0x56b1, 0x56b2, 0x56b3, 0x56b4, 0x56b5, 0x56b6, 0x56b7, 
+    0x56b8, 0x56b9, 0x56ba, 0x56bb, 0x56bc, 0x56bd, 0x56be, 0x56bf, 
+    0x56c0, 0x56c1, 0x56c2, 0x56c3, 0x56c4, 0x56c5, 0x56c6, 0x56c7, 
+    0x56c8, 0x56c9, 0x56ca, 0x56cb, 0x56cc, 0x56cd, 0x56ce, 0x56cf, 
+    0x56d0, 0x56d1, 0x56d2, 0x56d3, 0x56d4, 0x56d5, 0x56d6, 0x56d7, 
+    0x56d8, 0x56d9, 0x56da, 0x56db, 0x56dc, 0x56dd, 0x56de, 0x56df, 
+    0x56e0, 0x56e1, 0x56e2, 0x56e3, 0x56e4, 0x56e5, 0x56e6, 0x56e7, 
+    0x56e8, 0x56e9, 0x56ea, 0x56eb, 0x56ec, 0x56ed, 0x56ee, 0x56ef, 
+    0x56f0, 0x56f1, 0x56f2, 0x56f3, 0x56f4, 0x56f5, 0x56f6, 0x56f7, 
+    0x56f8, 0x56f9, 0x56fa, 0x56fb, 0x56fc, 0x56fd, 0x56fe, 0x56ff, 
+    0x5700, 0x5701, 0x5702, 0x5703, 0x5704, 0x5705, 0x5706, 0x5707, 
+    0x5708, 0x5709, 0x570a, 0x570b, 0x570c, 0x570d, 0x570e, 0x570f, 
+    0x5710, 0x5711, 0x5712, 0x5713, 0x5714, 0x5715, 0x5716, 0x5717, 
+    0x5718, 0x5719, 0x571a, 0x571b, 0x571c, 0x571d, 0x571e, 0x571f, 
+    0x5720, 0x5721, 0x5722, 0x5723, 0x5724, 0x5725, 0x5726, 0x5727, 
+    0x5728, 0x5729, 0x572a, 0x572b, 0x572c, 0x572d, 0x572e, 0x572f, 
+    0x5730, 0x5731, 0x5732, 0x5733, 0x5734, 0x5735, 0x5736, 0x5737, 
+    0x5738, 0x5739, 0x573a, 0x573b, 0x573c, 0x573d, 0x573e, 0x573f, 
+    0x5740, 0x5741, 0x5742, 0x5743, 0x5744, 0x5745, 0x5746, 0x5747, 
+    0x5748, 0x5749, 0x574a, 0x574b, 0x574c, 0x574d, 0x574e, 0x574f, 
+    0x5750, 0x5751, 0x5752, 0x5753, 0x5754, 0x5755, 0x5756, 0x5757, 
+    0x5758, 0x5759, 0x575a, 0x575b, 0x575c, 0x575d, 0x575e, 0x575f, 
+    0x5760, 0x5761, 0x5762, 0x5763, 0x5764, 0x5765, 0x5766, 0x5767, 
+    0x5768, 0x5769, 0x576a, 0x576b, 0x576c, 0x576d, 0x576e, 0x576f, 
+    0x5770, 0x5771, 0x5772, 0x5773, 0x5774, 0x5775, 0x5776, 0x5777, 
+    0x5778, 0x5779, 0x577a, 0x577b, 0x577c, 0x577d, 0x577e, 0x577f, 
+    0x5780, 0x5781, 0x5782, 0x5783, 0x5784, 0x5785, 0x5786, 0x5787, 
+    0x5788, 0x5789, 0x578a, 0x578b, 0x578c, 0x578d, 0x578e, 0x578f, 
+    0x5790, 0x5791, 0x5792, 0x5793, 0x5794, 0x5795, 0x5796, 0x5797, 
+    0x5798, 0x5799, 0x579a, 0x579b, 0x579c, 0x579d, 0x579e, 0x579f, 
+    0x57a0, 0x57a1, 0x57a2, 0x57a3, 0x57a4, 0x57a5, 0x57a6, 0x57a7, 
+    0x57a8, 0x57a9, 0x57aa, 0x57ab, 0x57ac, 0x57ad, 0x57ae, 0x57af, 
+    0x57b0, 0x57b1, 0x57b2, 0x57b3, 0x57b4, 0x57b5, 0x57b6, 0x57b7, 
+    0x57b8, 0x57b9, 0x57ba, 0x57bb, 0x57bc, 0x57bd, 0x57be, 0x57bf, 
+    0x57c0, 0x57c1, 0x57c2, 0x57c3, 0x57c4, 0x57c5, 0x57c6, 0x57c7, 
+    0x57c8, 0x57c9, 0x57ca, 0x57cb, 0x57cc, 0x57cd, 0x57ce, 0x57cf, 
+    0x57d0, 0x57d1, 0x57d2, 0x57d3, 0x57d4, 0x57d5, 0x57d6, 0x57d7, 
+    0x57d8, 0x57d9, 0x57da, 0x57db, 0x57dc, 0x57dd, 0x57de, 0x57df, 
+    0x57e0, 0x57e1, 0x57e2, 0x57e3, 0x57e4, 0x57e5, 0x57e6, 0x57e7, 
+    0x57e8, 0x57e9, 0x57ea, 0x57eb, 0x57ec, 0x57ed, 0x57ee, 0x57ef, 
+    0x57f0, 0x57f1, 0x57f2, 0x57f3, 0x57f4, 0x57f5, 0x57f6, 0x57f7, 
+    0x57f8, 0x57f9, 0x57fa, 0x57fb, 0x57fc, 0x57fd, 0x57fe, 0x57ff, 
+    0x5800, 0x5801, 0x5802, 0x5803, 0x5804, 0x5805, 0x5806, 0x5807, 
+    0x5808, 0x5809, 0x580a, 0x580b, 0x580c, 0x580d, 0x580e, 0x580f, 
+    0x5810, 0x5811, 0x5812, 0x5813, 0x5814, 0x5815, 0x5816, 0x5817, 
+    0x5818, 0x5819, 0x581a, 0x581b, 0x581c, 0x581d, 0x581e, 0x581f, 
+    0x5820, 0x5821, 0x5822, 0x5823, 0x5824, 0x5825, 0x5826, 0x5827, 
+    0x5828, 0x5829, 0x582a, 0x582b, 0x582c, 0x582d, 0x582e, 0x582f, 
+    0x5830, 0x5831, 0x5832, 0x5833, 0x5834, 0x5835, 0x5836, 0x5837, 
+    0x5838, 0x5839, 0x583a, 0x583b, 0x583c, 0x583d, 0x583e, 0x583f, 
+    0x5840, 0x5841, 0x5842, 0x5843, 0x5844, 0x5845, 0x5846, 0x5847, 
+    0x5848, 0x5849, 0x584a, 0x584b, 0x584c, 0x584d, 0x584e, 0x584f, 
+    0x5850, 0x5851, 0x5852, 0x5853, 0x5854, 0x5855, 0x5856, 0x5857, 
+    0x5858, 0x5859, 0x585a, 0x585b, 0x585c, 0x585d, 0x585e, 0x585f, 
+    0x5860, 0x5861, 0x5862, 0x5863, 0x5864, 0x5865, 0x5866, 0x5867, 
+    0x5868, 0x5869, 0x586a, 0x586b, 0x586c, 0x586d, 0x586e, 0x586f, 
+    0x5870, 0x5871, 0x5872, 0x5873, 0x5874, 0x5875, 0x5876, 0x5877, 
+    0x5878, 0x5879, 0x587a, 0x587b, 0x587c, 0x587d, 0x587e, 0x587f, 
+    0x5880, 0x5881, 0x5882, 0x5883, 0x5884, 0x5885, 0x5886, 0x5887, 
+    0x5888, 0x5889, 0x588a, 0x588b, 0x588c, 0x588d, 0x588e, 0x588f, 
+    0x5890, 0x5891, 0x5892, 0x5893, 0x5894, 0x5895, 0x5896, 0x5897, 
+    0x5898, 0x5899, 0x589a, 0x589b, 0x589c, 0x589d, 0x589e, 0x589f, 
+    0x58a0, 0x58a1, 0x58a2, 0x58a3, 0x58a4, 0x58a5, 0x58a6, 0x58a7, 
+    0x58a8, 0x58a9, 0x58aa, 0x58ab, 0x58ac, 0x58ad, 0x58ae, 0x58af, 
+    0x58b0, 0x58b1, 0x58b2, 0x58b3, 0x58b4, 0x58b5, 0x58b6, 0x58b7, 
+    0x58b8, 0x58b9, 0x58ba, 0x58bb, 0x58bc, 0x58bd, 0x58be, 0x58bf, 
+    0x58c0, 0x58c1, 0x58c2, 0x58c3, 0x58c4, 0x58c5, 0x58c6, 0x58c7, 
+    0x58c8, 0x58c9, 0x58ca, 0x58cb, 0x58cc, 0x58cd, 0x58ce, 0x58cf, 
+    0x58d0, 0x58d1, 0x58d2, 0x58d3, 0x58d4, 0x58d5, 0x58d6, 0x58d7, 
+    0x58d8, 0x58d9, 0x58da, 0x58db, 0x58dc, 0x58dd, 0x58de, 0x58df, 
+    0x58e0, 0x58e1, 0x58e2, 0x58e3, 0x58e4, 0x58e5, 0x58e6, 0x58e7, 
+    0x58e8, 0x58e9, 0x58ea, 0x58eb, 0x58ec, 0x58ed, 0x58ee, 0x58ef, 
+    0x58f0, 0x58f1, 0x58f2, 0x58f3, 0x58f4, 0x58f5, 0x58f6, 0x58f7, 
+    0x58f8, 0x58f9, 0x58fa, 0x58fb, 0x58fc, 0x58fd, 0x58fe, 0x58ff, 
+    0x5900, 0x5901, 0x5902, 0x5903, 0x5904, 0x5905, 0x5906, 0x5907, 
+    0x5908, 0x5909, 0x590a, 0x590b, 0x590c, 0x590d, 0x590e, 0x590f, 
+    0x5910, 0x5911, 0x5912, 0x5913, 0x5914, 0x5915, 0x5916, 0x5917, 
+    0x5918, 0x5919, 0x591a, 0x591b, 0x591c, 0x591d, 0x591e, 0x591f, 
+    0x5920, 0x5921, 0x5922, 0x5923, 0x5924, 0x5925, 0x5926, 0x5927, 
+    0x5928, 0x5929, 0x592a, 0x592b, 0x592c, 0x592d, 0x592e, 0x592f, 
+    0x5930, 0x5931, 0x5932, 0x5933, 0x5934, 0x5935, 0x5936, 0x5937, 
+    0x5938, 0x5939, 0x593a, 0x593b, 0x593c, 0x593d, 0x593e, 0x593f, 
+    0x5940, 0x5941, 0x5942, 0x5943, 0x5944, 0x5945, 0x5946, 0x5947, 
+    0x5948, 0x5949, 0x594a, 0x594b, 0x594c, 0x594d, 0x594e, 0x594f, 
+    0x5950, 0x5951, 0x5952, 0x5953, 0x5954, 0x5955, 0x5956, 0x5957, 
+    0x5958, 0x5959, 0x595a, 0x595b, 0x595c, 0x595d, 0x595e, 0x595f, 
+    0x5960, 0x5961, 0x5962, 0x5963, 0x5964, 0x5965, 0x5966, 0x5967, 
+    0x5968, 0x5969, 0x596a, 0x596b, 0x596c, 0x596d, 0x596e, 0x596f, 
+    0x5970, 0x5971, 0x5972, 0x5973, 0x5974, 0x5975, 0x5976, 0x5977, 
+    0x5978, 0x5979, 0x597a, 0x597b, 0x597c, 0x597d, 0x597e, 0x597f, 
+    0x5980, 0x5981, 0x5982, 0x5983, 0x5984, 0x5985, 0x5986, 0x5987, 
+    0x5988, 0x5989, 0x598a, 0x598b, 0x598c, 0x598d, 0x598e, 0x598f, 
+    0x5990, 0x5991, 0x5992, 0x5993, 0x5994, 0x5995, 0x5996, 0x5997, 
+    0x5998, 0x5999, 0x599a, 0x599b, 0x599c, 0x599d, 0x599e, 0x599f, 
+    0x59a0, 0x59a1, 0x59a2, 0x59a3, 0x59a4, 0x59a5, 0x59a6, 0x59a7, 
+    0x59a8, 0x59a9, 0x59aa, 0x59ab, 0x59ac, 0x59ad, 0x59ae, 0x59af, 
+    0x59b0, 0x59b1, 0x59b2, 0x59b3, 0x59b4, 0x59b5, 0x59b6, 0x59b7, 
+    0x59b8, 0x59b9, 0x59ba, 0x59bb, 0x59bc, 0x59bd, 0x59be, 0x59bf, 
+    0x59c0, 0x59c1, 0x59c2, 0x59c3, 0x59c4, 0x59c5, 0x59c6, 0x59c7, 
+    0x59c8, 0x59c9, 0x59ca, 0x59cb, 0x59cc, 0x59cd, 0x59ce, 0x59cf, 
+    0x59d0, 0x59d1, 0x59d2, 0x59d3, 0x59d4, 0x59d5, 0x59d6, 0x59d7, 
+    0x59d8, 0x59d9, 0x59da, 0x59db, 0x59dc, 0x59dd, 0x59de, 0x59df, 
+    0x59e0, 0x59e1, 0x59e2, 0x59e3, 0x59e4, 0x59e5, 0x59e6, 0x59e7, 
+    0x59e8, 0x59e9, 0x59ea, 0x59eb, 0x59ec, 0x59ed, 0x59ee, 0x59ef, 
+    0x59f0, 0x59f1, 0x59f2, 0x59f3, 0x59f4, 0x59f5, 0x59f6, 0x59f7, 
+    0x59f8, 0x59f9, 0x59fa, 0x59fb, 0x59fc, 0x59fd, 0x59fe, 0x59ff, 
+    0x5a00, 0x5a01, 0x5a02, 0x5a03, 0x5a04, 0x5a05, 0x5a06, 0x5a07, 
+    0x5a08, 0x5a09, 0x5a0a, 0x5a0b, 0x5a0c, 0x5a0d, 0x5a0e, 0x5a0f, 
+    0x5a10, 0x5a11, 0x5a12, 0x5a13, 0x5a14, 0x5a15, 0x5a16, 0x5a17, 
+    0x5a18, 0x5a19, 0x5a1a, 0x5a1b, 0x5a1c, 0x5a1d, 0x5a1e, 0x5a1f, 
+    0x5a20, 0x5a21, 0x5a22, 0x5a23, 0x5a24, 0x5a25, 0x5a26, 0x5a27, 
+    0x5a28, 0x5a29, 0x5a2a, 0x5a2b, 0x5a2c, 0x5a2d, 0x5a2e, 0x5a2f, 
+    0x5a30, 0x5a31, 0x5a32, 0x5a33, 0x5a34, 0x5a35, 0x5a36, 0x5a37, 
+    0x5a38, 0x5a39, 0x5a3a, 0x5a3b, 0x5a3c, 0x5a3d, 0x5a3e, 0x5a3f, 
+    0x5a40, 0x5a41, 0x5a42, 0x5a43, 0x5a44, 0x5a45, 0x5a46, 0x5a47, 
+    0x5a48, 0x5a49, 0x5a4a, 0x5a4b, 0x5a4c, 0x5a4d, 0x5a4e, 0x5a4f, 
+    0x5a50, 0x5a51, 0x5a52, 0x5a53, 0x5a54, 0x5a55, 0x5a56, 0x5a57, 
+    0x5a58, 0x5a59, 0x5a5a, 0x5a5b, 0x5a5c, 0x5a5d, 0x5a5e, 0x5a5f, 
+    0x5a60, 0x5a61, 0x5a62, 0x5a63, 0x5a64, 0x5a65, 0x5a66, 0x5a67, 
+    0x5a68, 0x5a69, 0x5a6a, 0x5a6b, 0x5a6c, 0x5a6d, 0x5a6e, 0x5a6f, 
+    0x5a70, 0x5a71, 0x5a72, 0x5a73, 0x5a74, 0x5a75, 0x5a76, 0x5a77, 
+    0x5a78, 0x5a79, 0x5a7a, 0x5a7b, 0x5a7c, 0x5a7d, 0x5a7e, 0x5a7f, 
+    0x5a80, 0x5a81, 0x5a82, 0x5a83, 0x5a84, 0x5a85, 0x5a86, 0x5a87, 
+    0x5a88, 0x5a89, 0x5a8a, 0x5a8b, 0x5a8c, 0x5a8d, 0x5a8e, 0x5a8f, 
+    0x5a90, 0x5a91, 0x5a92, 0x5a93, 0x5a94, 0x5a95, 0x5a96, 0x5a97, 
+    0x5a98, 0x5a99, 0x5a9a, 0x5a9b, 0x5a9c, 0x5a9d, 0x5a9e, 0x5a9f, 
+    0x5aa0, 0x5aa1, 0x5aa2, 0x5aa3, 0x5aa4, 0x5aa5, 0x5aa6, 0x5aa7, 
+    0x5aa8, 0x5aa9, 0x5aaa, 0x5aab, 0x5aac, 0x5aad, 0x5aae, 0x5aaf, 
+    0x5ab0, 0x5ab1, 0x5ab2, 0x5ab3, 0x5ab4, 0x5ab5, 0x5ab6, 0x5ab7, 
+    0x5ab8, 0x5ab9, 0x5aba, 0x5abb, 0x5abc, 0x5abd, 0x5abe, 0x5abf, 
+    0x5ac0, 0x5ac1, 0x5ac2, 0x5ac3, 0x5ac4, 0x5ac5, 0x5ac6, 0x5ac7, 
+    0x5ac8, 0x5ac9, 0x5aca, 0x5acb, 0x5acc, 0x5acd, 0x5ace, 0x5acf, 
+    0x5ad0, 0x5ad1, 0x5ad2, 0x5ad3, 0x5ad4, 0x5ad5, 0x5ad6, 0x5ad7, 
+    0x5ad8, 0x5ad9, 0x5ada, 0x5adb, 0x5adc, 0x5add, 0x5ade, 0x5adf, 
+    0x5ae0, 0x5ae1, 0x5ae2, 0x5ae3, 0x5ae4, 0x5ae5, 0x5ae6, 0x5ae7, 
+    0x5ae8, 0x5ae9, 0x5aea, 0x5aeb, 0x5aec, 0x5aed, 0x5aee, 0x5aef, 
+    0x5af0, 0x5af1, 0x5af2, 0x5af3, 0x5af4, 0x5af5, 0x5af6, 0x5af7, 
+    0x5af8, 0x5af9, 0x5afa, 0x5afb, 0x5afc, 0x5afd, 0x5afe, 0x5aff, 
+    0x5b00, 0x5b01, 0x5b02, 0x5b03, 0x5b04, 0x5b05, 0x5b06, 0x5b07, 
+    0x5b08, 0x5b09, 0x5b0a, 0x5b0b, 0x5b0c, 0x5b0d, 0x5b0e, 0x5b0f, 
+    0x5b10, 0x5b11, 0x5b12, 0x5b13, 0x5b14, 0x5b15, 0x5b16, 0x5b17, 
+    0x5b18, 0x5b19, 0x5b1a, 0x5b1b, 0x5b1c, 0x5b1d, 0x5b1e, 0x5b1f, 
+    0x5b20, 0x5b21, 0x5b22, 0x5b23, 0x5b24, 0x5b25, 0x5b26, 0x5b27, 
+    0x5b28, 0x5b29, 0x5b2a, 0x5b2b, 0x5b2c, 0x5b2d, 0x5b2e, 0x5b2f, 
+    0x5b30, 0x5b31, 0x5b32, 0x5b33, 0x5b34, 0x5b35, 0x5b36, 0x5b37, 
+    0x5b38, 0x5b39, 0x5b3a, 0x5b3b, 0x5b3c, 0x5b3d, 0x5b3e, 0x5b3f, 
+    0x5b40, 0x5b41, 0x5b42, 0x5b43, 0x5b44, 0x5b45, 0x5b46, 0x5b47, 
+    0x5b48, 0x5b49, 0x5b4a, 0x5b4b, 0x5b4c, 0x5b4d, 0x5b4e, 0x5b4f, 
+    0x5b50, 0x5b51, 0x5b52, 0x5b53, 0x5b54, 0x5b55, 0x5b56, 0x5b57, 
+    0x5b58, 0x5b59, 0x5b5a, 0x5b5b, 0x5b5c, 0x5b5d, 0x5b5e, 0x5b5f, 
+    0x5b60, 0x5b61, 0x5b62, 0x5b63, 0x5b64, 0x5b65, 0x5b66, 0x5b67, 
+    0x5b68, 0x5b69, 0x5b6a, 0x5b6b, 0x5b6c, 0x5b6d, 0x5b6e, 0x5b6f, 
+    0x5b70, 0x5b71, 0x5b72, 0x5b73, 0x5b74, 0x5b75, 0x5b76, 0x5b77, 
+    0x5b78, 0x5b79, 0x5b7a, 0x5b7b, 0x5b7c, 0x5b7d, 0x5b7e, 0x5b7f, 
+    0x5b80, 0x5b81, 0x5b82, 0x5b83, 0x5b84, 0x5b85, 0x5b86, 0x5b87, 
+    0x5b88, 0x5b89, 0x5b8a, 0x5b8b, 0x5b8c, 0x5b8d, 0x5b8e, 0x5b8f, 
+    0x5b90, 0x5b91, 0x5b92, 0x5b93, 0x5b94, 0x5b95, 0x5b96, 0x5b97, 
+    0x5b98, 0x5b99, 0x5b9a, 0x5b9b, 0x5b9c, 0x5b9d, 0x5b9e, 0x5b9f, 
+    0x5ba0, 0x5ba1, 0x5ba2, 0x5ba3, 0x5ba4, 0x5ba5, 0x5ba6, 0x5ba7, 
+    0x5ba8, 0x5ba9, 0x5baa, 0x5bab, 0x5bac, 0x5bad, 0x5bae, 0x5baf, 
+    0x5bb0, 0x5bb1, 0x5bb2, 0x5bb3, 0x5bb4, 0x5bb5, 0x5bb6, 0x5bb7, 
+    0x5bb8, 0x5bb9, 0x5bba, 0x5bbb, 0x5bbc, 0x5bbd, 0x5bbe, 0x5bbf, 
+    0x5bc0, 0x5bc1, 0x5bc2, 0x5bc3, 0x5bc4, 0x5bc5, 0x5bc6, 0x5bc7, 
+    0x5bc8, 0x5bc9, 0x5bca, 0x5bcb, 0x5bcc, 0x5bcd, 0x5bce, 0x5bcf, 
+    0x5bd0, 0x5bd1, 0x5bd2, 0x5bd3, 0x5bd4, 0x5bd5, 0x5bd6, 0x5bd7, 
+    0x5bd8, 0x5bd9, 0x5bda, 0x5bdb, 0x5bdc, 0x5bdd, 0x5bde, 0x5bdf, 
+    0x5be0, 0x5be1, 0x5be2, 0x5be3, 0x5be4, 0x5be5, 0x5be6, 0x5be7, 
+    0x5be8, 0x5be9, 0x5bea, 0x5beb, 0x5bec, 0x5bed, 0x5bee, 0x5bef, 
+    0x5bf0, 0x5bf1, 0x5bf2, 0x5bf3, 0x5bf4, 0x5bf5, 0x5bf6, 0x5bf7, 
+    0x5bf8, 0x5bf9, 0x5bfa, 0x5bfb, 0x5bfc, 0x5bfd, 0x5bfe, 0x5bff, 
+    0x5c00, 0x5c01, 0x5c02, 0x5c03, 0x5c04, 0x5c05, 0x5c06, 0x5c07, 
+    0x5c08, 0x5c09, 0x5c0a, 0x5c0b, 0x5c0c, 0x5c0d, 0x5c0e, 0x5c0f, 
+    0x5c10, 0x5c11, 0x5c12, 0x5c13, 0x5c14, 0x5c15, 0x5c16, 0x5c17, 
+    0x5c18, 0x5c19, 0x5c1a, 0x5c1b, 0x5c1c, 0x5c1d, 0x5c1e, 0x5c1f, 
+    0x5c20, 0x5c21, 0x5c22, 0x5c23, 0x5c24, 0x5c25, 0x5c26, 0x5c27, 
+    0x5c28, 0x5c29, 0x5c2a, 0x5c2b, 0x5c2c, 0x5c2d, 0x5c2e, 0x5c2f, 
+    0x5c30, 0x5c31, 0x5c32, 0x5c33, 0x5c34, 0x5c35, 0x5c36, 0x5c37, 
+    0x5c38, 0x5c39, 0x5c3a, 0x5c3b, 0x5c3c, 0x5c3d, 0x5c3e, 0x5c3f, 
+    0x5c40, 0x5c41, 0x5c42, 0x5c43, 0x5c44, 0x5c45, 0x5c46, 0x5c47, 
+    0x5c48, 0x5c49, 0x5c4a, 0x5c4b, 0x5c4c, 0x5c4d, 0x5c4e, 0x5c4f, 
+    0x5c50, 0x5c51, 0x5c52, 0x5c53, 0x5c54, 0x5c55, 0x5c56, 0x5c57, 
+    0x5c58, 0x5c59, 0x5c5a, 0x5c5b, 0x5c5c, 0x5c5d, 0x5c5e, 0x5c5f, 
+    0x5c60, 0x5c61, 0x5c62, 0x5c63, 0x5c64, 0x5c65, 0x5c66, 0x5c67, 
+    0x5c68, 0x5c69, 0x5c6a, 0x5c6b, 0x5c6c, 0x5c6d, 0x5c6e, 0x5c6f, 
+    0x5c70, 0x5c71, 0x5c72, 0x5c73, 0x5c74, 0x5c75, 0x5c76, 0x5c77, 
+    0x5c78, 0x5c79, 0x5c7a, 0x5c7b, 0x5c7c, 0x5c7d, 0x5c7e, 0x5c7f, 
+    0x5c80, 0x5c81, 0x5c82, 0x5c83, 0x5c84, 0x5c85, 0x5c86, 0x5c87, 
+    0x5c88, 0x5c89, 0x5c8a, 0x5c8b, 0x5c8c, 0x5c8d, 0x5c8e, 0x5c8f, 
+    0x5c90, 0x5c91, 0x5c92, 0x5c93, 0x5c94, 0x5c95, 0x5c96, 0x5c97, 
+    0x5c98, 0x5c99, 0x5c9a, 0x5c9b, 0x5c9c, 0x5c9d, 0x5c9e, 0x5c9f, 
+    0x5ca0, 0x5ca1, 0x5ca2, 0x5ca3, 0x5ca4, 0x5ca5, 0x5ca6, 0x5ca7, 
+    0x5ca8, 0x5ca9, 0x5caa, 0x5cab, 0x5cac, 0x5cad, 0x5cae, 0x5caf, 
+    0x5cb0, 0x5cb1, 0x5cb2, 0x5cb3, 0x5cb4, 0x5cb5, 0x5cb6, 0x5cb7, 
+    0x5cb8, 0x5cb9, 0x5cba, 0x5cbb, 0x5cbc, 0x5cbd, 0x5cbe, 0x5cbf, 
+    0x5cc0, 0x5cc1, 0x5cc2, 0x5cc3, 0x5cc4, 0x5cc5, 0x5cc6, 0x5cc7, 
+    0x5cc8, 0x5cc9, 0x5cca, 0x5ccb, 0x5ccc, 0x5ccd, 0x5cce, 0x5ccf, 
+    0x5cd0, 0x5cd1, 0x5cd2, 0x5cd3, 0x5cd4, 0x5cd5, 0x5cd6, 0x5cd7, 
+    0x5cd8, 0x5cd9, 0x5cda, 0x5cdb, 0x5cdc, 0x5cdd, 0x5cde, 0x5cdf, 
+    0x5ce0, 0x5ce1, 0x5ce2, 0x5ce3, 0x5ce4, 0x5ce5, 0x5ce6, 0x5ce7, 
+    0x5ce8, 0x5ce9, 0x5cea, 0x5ceb, 0x5cec, 0x5ced, 0x5cee, 0x5cef, 
+    0x5cf0, 0x5cf1, 0x5cf2, 0x5cf3, 0x5cf4, 0x5cf5, 0x5cf6, 0x5cf7, 
+    0x5cf8, 0x5cf9, 0x5cfa, 0x5cfb, 0x5cfc, 0x5cfd, 0x5cfe, 0x5cff, 
+    0x5d00, 0x5d01, 0x5d02, 0x5d03, 0x5d04, 0x5d05, 0x5d06, 0x5d07, 
+    0x5d08, 0x5d09, 0x5d0a, 0x5d0b, 0x5d0c, 0x5d0d, 0x5d0e, 0x5d0f, 
+    0x5d10, 0x5d11, 0x5d12, 0x5d13, 0x5d14, 0x5d15, 0x5d16, 0x5d17, 
+    0x5d18, 0x5d19, 0x5d1a, 0x5d1b, 0x5d1c, 0x5d1d, 0x5d1e, 0x5d1f, 
+    0x5d20, 0x5d21, 0x5d22, 0x5d23, 0x5d24, 0x5d25, 0x5d26, 0x5d27, 
+    0x5d28, 0x5d29, 0x5d2a, 0x5d2b, 0x5d2c, 0x5d2d, 0x5d2e, 0x5d2f, 
+    0x5d30, 0x5d31, 0x5d32, 0x5d33, 0x5d34, 0x5d35, 0x5d36, 0x5d37, 
+    0x5d38, 0x5d39, 0x5d3a, 0x5d3b, 0x5d3c, 0x5d3d, 0x5d3e, 0x5d3f, 
+    0x5d40, 0x5d41, 0x5d42, 0x5d43, 0x5d44, 0x5d45, 0x5d46, 0x5d47, 
+    0x5d48, 0x5d49, 0x5d4a, 0x5d4b, 0x5d4c, 0x5d4d, 0x5d4e, 0x5d4f, 
+    0x5d50, 0x5d51, 0x5d52, 0x5d53, 0x5d54, 0x5d55, 0x5d56, 0x5d57, 
+    0x5d58, 0x5d59, 0x5d5a, 0x5d5b, 0x5d5c, 0x5d5d, 0x5d5e, 0x5d5f, 
+    0x5d60, 0x5d61, 0x5d62, 0x5d63, 0x5d64, 0x5d65, 0x5d66, 0x5d67, 
+    0x5d68, 0x5d69, 0x5d6a, 0x5d6b, 0x5d6c, 0x5d6d, 0x5d6e, 0x5d6f, 
+    0x5d70, 0x5d71, 0x5d72, 0x5d73, 0x5d74, 0x5d75, 0x5d76, 0x5d77, 
+    0x5d78, 0x5d79, 0x5d7a, 0x5d7b, 0x5d7c, 0x5d7d, 0x5d7e, 0x5d7f, 
+    0x5d80, 0x5d81, 0x5d82, 0x5d83, 0x5d84, 0x5d85, 0x5d86, 0x5d87, 
+    0x5d88, 0x5d89, 0x5d8a, 0x5d8b, 0x5d8c, 0x5d8d, 0x5d8e, 0x5d8f, 
+    0x5d90, 0x5d91, 0x5d92, 0x5d93, 0x5d94, 0x5d95, 0x5d96, 0x5d97, 
+    0x5d98, 0x5d99, 0x5d9a, 0x5d9b, 0x5d9c, 0x5d9d, 0x5d9e, 0x5d9f, 
+    0x5da0, 0x5da1, 0x5da2, 0x5da3, 0x5da4, 0x5da5, 0x5da6, 0x5da7, 
+    0x5da8, 0x5da9, 0x5daa, 0x5dab, 0x5dac, 0x5dad, 0x5dae, 0x5daf, 
+    0x5db0, 0x5db1, 0x5db2, 0x5db3, 0x5db4, 0x5db5, 0x5db6, 0x5db7, 
+    0x5db8, 0x5db9, 0x5dba, 0x5dbb, 0x5dbc, 0x5dbd, 0x5dbe, 0x5dbf, 
+    0x5dc0, 0x5dc1, 0x5dc2, 0x5dc3, 0x5dc4, 0x5dc5, 0x5dc6, 0x5dc7, 
+    0x5dc8, 0x5dc9, 0x5dca, 0x5dcb, 0x5dcc, 0x5dcd, 0x5dce, 0x5dcf, 
+    0x5dd0, 0x5dd1, 0x5dd2, 0x5dd3, 0x5dd4, 0x5dd5, 0x5dd6, 0x5dd7, 
+    0x5dd8, 0x5dd9, 0x5dda, 0x5ddb, 0x5ddc, 0x5ddd, 0x5dde, 0x5ddf, 
+    0x5de0, 0x5de1, 0x5de2, 0x5de3, 0x5de4, 0x5de5, 0x5de6, 0x5de7, 
+    0x5de8, 0x5de9, 0x5dea, 0x5deb, 0x5dec, 0x5ded, 0x5dee, 0x5def, 
+    0x5df0, 0x5df1, 0x5df2, 0x5df3, 0x5df4, 0x5df5, 0x5df6, 0x5df7, 
+    0x5df8, 0x5df9, 0x5dfa, 0x5dfb, 0x5dfc, 0x5dfd, 0x5dfe, 0x5dff, 
+    0x5e00, 0x5e01, 0x5e02, 0x5e03, 0x5e04, 0x5e05, 0x5e06, 0x5e07, 
+    0x5e08, 0x5e09, 0x5e0a, 0x5e0b, 0x5e0c, 0x5e0d, 0x5e0e, 0x5e0f, 
+    0x5e10, 0x5e11, 0x5e12, 0x5e13, 0x5e14, 0x5e15, 0x5e16, 0x5e17, 
+    0x5e18, 0x5e19, 0x5e1a, 0x5e1b, 0x5e1c, 0x5e1d, 0x5e1e, 0x5e1f, 
+    0x5e20, 0x5e21, 0x5e22, 0x5e23, 0x5e24, 0x5e25, 0x5e26, 0x5e27, 
+    0x5e28, 0x5e29, 0x5e2a, 0x5e2b, 0x5e2c, 0x5e2d, 0x5e2e, 0x5e2f, 
+    0x5e30, 0x5e31, 0x5e32, 0x5e33, 0x5e34, 0x5e35, 0x5e36, 0x5e37, 
+    0x5e38, 0x5e39, 0x5e3a, 0x5e3b, 0x5e3c, 0x5e3d, 0x5e3e, 0x5e3f, 
+    0x5e40, 0x5e41, 0x5e42, 0x5e43, 0x5e44, 0x5e45, 0x5e46, 0x5e47, 
+    0x5e48, 0x5e49, 0x5e4a, 0x5e4b, 0x5e4c, 0x5e4d, 0x5e4e, 0x5e4f, 
+    0x5e50, 0x5e51, 0x5e52, 0x5e53, 0x5e54, 0x5e55, 0x5e56, 0x5e57, 
+    0x5e58, 0x5e59, 0x5e5a, 0x5e5b, 0x5e5c, 0x5e5d, 0x5e5e, 0x5e5f, 
+    0x5e60, 0x5e61, 0x5e62, 0x5e63, 0x5e64, 0x5e65, 0x5e66, 0x5e67, 
+    0x5e68, 0x5e69, 0x5e6a, 0x5e6b, 0x5e6c, 0x5e6d, 0x5e6e, 0x5e6f, 
+    0x5e70, 0x5e71, 0x5e72, 0x5e73, 0x5e74, 0x5e75, 0x5e76, 0x5e77, 
+    0x5e78, 0x5e79, 0x5e7a, 0x5e7b, 0x5e7c, 0x5e7d, 0x5e7e, 0x5e7f, 
+    0x5e80, 0x5e81, 0x5e82, 0x5e83, 0x5e84, 0x5e85, 0x5e86, 0x5e87, 
+    0x5e88, 0x5e89, 0x5e8a, 0x5e8b, 0x5e8c, 0x5e8d, 0x5e8e, 0x5e8f, 
+    0x5e90, 0x5e91, 0x5e92, 0x5e93, 0x5e94, 0x5e95, 0x5e96, 0x5e97, 
+    0x5e98, 0x5e99, 0x5e9a, 0x5e9b, 0x5e9c, 0x5e9d, 0x5e9e, 0x5e9f, 
+    0x5ea0, 0x5ea1, 0x5ea2, 0x5ea3, 0x5ea4, 0x5ea5, 0x5ea6, 0x5ea7, 
+    0x5ea8, 0x5ea9, 0x5eaa, 0x5eab, 0x5eac, 0x5ead, 0x5eae, 0x5eaf, 
+    0x5eb0, 0x5eb1, 0x5eb2, 0x5eb3, 0x5eb4, 0x5eb5, 0x5eb6, 0x5eb7, 
+    0x5eb8, 0x5eb9, 0x5eba, 0x5ebb, 0x5ebc, 0x5ebd, 0x5ebe, 0x5ebf, 
+    0x5ec0, 0x5ec1, 0x5ec2, 0x5ec3, 0x5ec4, 0x5ec5, 0x5ec6, 0x5ec7, 
+    0x5ec8, 0x5ec9, 0x5eca, 0x5ecb, 0x5ecc, 0x5ecd, 0x5ece, 0x5ecf, 
+    0x5ed0, 0x5ed1, 0x5ed2, 0x5ed3, 0x5ed4, 0x5ed5, 0x5ed6, 0x5ed7, 
+    0x5ed8, 0x5ed9, 0x5eda, 0x5edb, 0x5edc, 0x5edd, 0x5ede, 0x5edf, 
+    0x5ee0, 0x5ee1, 0x5ee2, 0x5ee3, 0x5ee4, 0x5ee5, 0x5ee6, 0x5ee7, 
+    0x5ee8, 0x5ee9, 0x5eea, 0x5eeb, 0x5eec, 0x5eed, 0x5eee, 0x5eef, 
+    0x5ef0, 0x5ef1, 0x5ef2, 0x5ef3, 0x5ef4, 0x5ef5, 0x5ef6, 0x5ef7, 
+    0x5ef8, 0x5ef9, 0x5efa, 0x5efb, 0x5efc, 0x5efd, 0x5efe, 0x5eff, 
+    0x5f00, 0x5f01, 0x5f02, 0x5f03, 0x5f04, 0x5f05, 0x5f06, 0x5f07, 
+    0x5f08, 0x5f09, 0x5f0a, 0x5f0b, 0x5f0c, 0x5f0d, 0x5f0e, 0x5f0f, 
+    0x5f10, 0x5f11, 0x5f12, 0x5f13, 0x5f14, 0x5f15, 0x5f16, 0x5f17, 
+    0x5f18, 0x5f19, 0x5f1a, 0x5f1b, 0x5f1c, 0x5f1d, 0x5f1e, 0x5f1f, 
+    0x5f20, 0x5f21, 0x5f22, 0x5f23, 0x5f24, 0x5f25, 0x5f26, 0x5f27, 
+    0x5f28, 0x5f29, 0x5f2a, 0x5f2b, 0x5f2c, 0x5f2d, 0x5f2e, 0x5f2f, 
+    0x5f30, 0x5f31, 0x5f32, 0x5f33, 0x5f34, 0x5f35, 0x5f36, 0x5f37, 
+    0x5f38, 0x5f39, 0x5f3a, 0x5f3b, 0x5f3c, 0x5f3d, 0x5f3e, 0x5f3f, 
+    0x5f40, 0x5f41, 0x5f42, 0x5f43, 0x5f44, 0x5f45, 0x5f46, 0x5f47, 
+    0x5f48, 0x5f49, 0x5f4a, 0x5f4b, 0x5f4c, 0x5f4d, 0x5f4e, 0x5f4f, 
+    0x5f50, 0x5f51, 0x5f52, 0x5f53, 0x5f54, 0x5f55, 0x5f56, 0x5f57, 
+    0x5f58, 0x5f59, 0x5f5a, 0x5f5b, 0x5f5c, 0x5f5d, 0x5f5e, 0x5f5f, 
+    0x5f60, 0x5f61, 0x5f62, 0x5f63, 0x5f64, 0x5f65, 0x5f66, 0x5f67, 
+    0x5f68, 0x5f69, 0x5f6a, 0x5f6b, 0x5f6c, 0x5f6d, 0x5f6e, 0x5f6f, 
+    0x5f70, 0x5f71, 0x5f72, 0x5f73, 0x5f74, 0x5f75, 0x5f76, 0x5f77, 
+    0x5f78, 0x5f79, 0x5f7a, 0x5f7b, 0x5f7c, 0x5f7d, 0x5f7e, 0x5f7f, 
+    0x5f80, 0x5f81, 0x5f82, 0x5f83, 0x5f84, 0x5f85, 0x5f86, 0x5f87, 
+    0x5f88, 0x5f89, 0x5f8a, 0x5f8b, 0x5f8c, 0x5f8d, 0x5f8e, 0x5f8f, 
+    0x5f90, 0x5f91, 0x5f92, 0x5f93, 0x5f94, 0x5f95, 0x5f96, 0x5f97, 
+    0x5f98, 0x5f99, 0x5f9a, 0x5f9b, 0x5f9c, 0x5f9d, 0x5f9e, 0x5f9f, 
+    0x5fa0, 0x5fa1, 0x5fa2, 0x5fa3, 0x5fa4, 0x5fa5, 0x5fa6, 0x5fa7, 
+    0x5fa8, 0x5fa9, 0x5faa, 0x5fab, 0x5fac, 0x5fad, 0x5fae, 0x5faf, 
+    0x5fb0, 0x5fb1, 0x5fb2, 0x5fb3, 0x5fb4, 0x5fb5, 0x5fb6, 0x5fb7, 
+    0x5fb8, 0x5fb9, 0x5fba, 0x5fbb, 0x5fbc, 0x5fbd, 0x5fbe, 0x5fbf, 
+    0x5fc0, 0x5fc1, 0x5fc2, 0x5fc3, 0x5fc4, 0x5fc5, 0x5fc6, 0x5fc7, 
+    0x5fc8, 0x5fc9, 0x5fca, 0x5fcb, 0x5fcc, 0x5fcd, 0x5fce, 0x5fcf, 
+    0x5fd0, 0x5fd1, 0x5fd2, 0x5fd3, 0x5fd4, 0x5fd5, 0x5fd6, 0x5fd7, 
+    0x5fd8, 0x5fd9, 0x5fda, 0x5fdb, 0x5fdc, 0x5fdd, 0x5fde, 0x5fdf, 
+    0x5fe0, 0x5fe1, 0x5fe2, 0x5fe3, 0x5fe4, 0x5fe5, 0x5fe6, 0x5fe7, 
+    0x5fe8, 0x5fe9, 0x5fea, 0x5feb, 0x5fec, 0x5fed, 0x5fee, 0x5fef, 
+    0x5ff0, 0x5ff1, 0x5ff2, 0x5ff3, 0x5ff4, 0x5ff5, 0x5ff6, 0x5ff7, 
+    0x5ff8, 0x5ff9, 0x5ffa, 0x5ffb, 0x5ffc, 0x5ffd, 0x5ffe, 0x5fff, 
+    0x6000, 0x6001, 0x6002, 0x6003, 0x6004, 0x6005, 0x6006, 0x6007, 
+    0x6008, 0x6009, 0x600a, 0x600b, 0x600c, 0x600d, 0x600e, 0x600f, 
+    0x6010, 0x6011, 0x6012, 0x6013, 0x6014, 0x6015, 0x6016, 0x6017, 
+    0x6018, 0x6019, 0x601a, 0x601b, 0x601c, 0x601d, 0x601e, 0x601f, 
+    0x6020, 0x6021, 0x6022, 0x6023, 0x6024, 0x6025, 0x6026, 0x6027, 
+    0x6028, 0x6029, 0x602a, 0x602b, 0x602c, 0x602d, 0x602e, 0x602f, 
+    0x6030, 0x6031, 0x6032, 0x6033, 0x6034, 0x6035, 0x6036, 0x6037, 
+    0x6038, 0x6039, 0x603a, 0x603b, 0x603c, 0x603d, 0x603e, 0x603f, 
+    0x6040, 0x6041, 0x6042, 0x6043, 0x6044, 0x6045, 0x6046, 0x6047, 
+    0x6048, 0x6049, 0x604a, 0x604b, 0x604c, 0x604d, 0x604e, 0x604f, 
+    0x6050, 0x6051, 0x6052, 0x6053, 0x6054, 0x6055, 0x6056, 0x6057, 
+    0x6058, 0x6059, 0x605a, 0x605b, 0x605c, 0x605d, 0x605e, 0x605f, 
+    0x6060, 0x6061, 0x6062, 0x6063, 0x6064, 0x6065, 0x6066, 0x6067, 
+    0x6068, 0x6069, 0x606a, 0x606b, 0x606c, 0x606d, 0x606e, 0x606f, 
+    0x6070, 0x6071, 0x6072, 0x6073, 0x6074, 0x6075, 0x6076, 0x6077, 
+    0x6078, 0x6079, 0x607a, 0x607b, 0x607c, 0x607d, 0x607e, 0x607f, 
+    0x6080, 0x6081, 0x6082, 0x6083, 0x6084, 0x6085, 0x6086, 0x6087, 
+    0x6088, 0x6089, 0x608a, 0x608b, 0x608c, 0x608d, 0x608e, 0x608f, 
+    0x6090, 0x6091, 0x6092, 0x6093, 0x6094, 0x6095, 0x6096, 0x6097, 
+    0x6098, 0x6099, 0x609a, 0x609b, 0x609c, 0x609d, 0x609e, 0x609f, 
+    0x60a0, 0x60a1, 0x60a2, 0x60a3, 0x60a4, 0x60a5, 0x60a6, 0x60a7, 
+    0x60a8, 0x60a9, 0x60aa, 0x60ab, 0x60ac, 0x60ad, 0x60ae, 0x60af, 
+    0x60b0, 0x60b1, 0x60b2, 0x60b3, 0x60b4, 0x60b5, 0x60b6, 0x60b7, 
+    0x60b8, 0x60b9, 0x60ba, 0x60bb, 0x60bc, 0x60bd, 0x60be, 0x60bf, 
+    0x60c0, 0x60c1, 0x60c2, 0x60c3, 0x60c4, 0x60c5, 0x60c6, 0x60c7, 
+    0x60c8, 0x60c9, 0x60ca, 0x60cb, 0x60cc, 0x60cd, 0x60ce, 0x60cf, 
+    0x60d0, 0x60d1, 0x60d2, 0x60d3, 0x60d4, 0x60d5, 0x60d6, 0x60d7, 
+    0x60d8, 0x60d9, 0x60da, 0x60db, 0x60dc, 0x60dd, 0x60de, 0x60df, 
+    0x60e0, 0x60e1, 0x60e2, 0x60e3, 0x60e4, 0x60e5, 0x60e6, 0x60e7, 
+    0x60e8, 0x60e9, 0x60ea, 0x60eb, 0x60ec, 0x60ed, 0x60ee, 0x60ef, 
+    0x60f0, 0x60f1, 0x60f2, 0x60f3, 0x60f4, 0x60f5, 0x60f6, 0x60f7, 
+    0x60f8, 0x60f9, 0x60fa, 0x60fb, 0x60fc, 0x60fd, 0x60fe, 0x60ff, 
+    0x6100, 0x6101, 0x6102, 0x6103, 0x6104, 0x6105, 0x6106, 0x6107, 
+    0x6108, 0x6109, 0x610a, 0x610b, 0x610c, 0x610d, 0x610e, 0x610f, 
+    0x6110, 0x6111, 0x6112, 0x6113, 0x6114, 0x6115, 0x6116, 0x6117, 
+    0x6118, 0x6119, 0x611a, 0x611b, 0x611c, 0x611d, 0x611e, 0x611f, 
+    0x6120, 0x6121, 0x6122, 0x6123, 0x6124, 0x6125, 0x6126, 0x6127, 
+    0x6128, 0x6129, 0x612a, 0x612b, 0x612c, 0x612d, 0x612e, 0x612f, 
+    0x6130, 0x6131, 0x6132, 0x6133, 0x6134, 0x6135, 0x6136, 0x6137, 
+    0x6138, 0x6139, 0x613a, 0x613b, 0x613c, 0x613d, 0x613e, 0x613f, 
+    0x6140, 0x6141, 0x6142, 0x6143, 0x6144, 0x6145, 0x6146, 0x6147, 
+    0x6148, 0x6149, 0x614a, 0x614b, 0x614c, 0x614d, 0x614e, 0x614f, 
+    0x6150, 0x6151, 0x6152, 0x6153, 0x6154, 0x6155, 0x6156, 0x6157, 
+    0x6158, 0x6159, 0x615a, 0x615b, 0x615c, 0x615d, 0x615e, 0x615f, 
+    0x6160, 0x6161, 0x6162, 0x6163, 0x6164, 0x6165, 0x6166, 0x6167, 
+    0x6168, 0x6169, 0x616a, 0x616b, 0x616c, 0x616d, 0x616e, 0x616f, 
+    0x6170, 0x6171, 0x6172, 0x6173, 0x6174, 0x6175, 0x6176, 0x6177, 
+    0x6178, 0x6179, 0x617a, 0x617b, 0x617c, 0x617d, 0x617e, 0x617f, 
+    0x6180, 0x6181, 0x6182, 0x6183, 0x6184, 0x6185, 0x6186, 0x6187, 
+    0x6188, 0x6189, 0x618a, 0x618b, 0x618c, 0x618d, 0x618e, 0x618f, 
+    0x6190, 0x6191, 0x6192, 0x6193, 0x6194, 0x6195, 0x6196, 0x6197, 
+    0x6198, 0x6199, 0x619a, 0x619b, 0x619c, 0x619d, 0x619e, 0x619f, 
+    0x61a0, 0x61a1, 0x61a2, 0x61a3, 0x61a4, 0x61a5, 0x61a6, 0x61a7, 
+    0x61a8, 0x61a9, 0x61aa, 0x61ab, 0x61ac, 0x61ad, 0x61ae, 0x61af, 
+    0x61b0, 0x61b1, 0x61b2, 0x61b3, 0x61b4, 0x61b5, 0x61b6, 0x61b7, 
+    0x61b8, 0x61b9, 0x61ba, 0x61bb, 0x61bc, 0x61bd, 0x61be, 0x61bf, 
+    0x61c0, 0x61c1, 0x61c2, 0x61c3, 0x61c4, 0x61c5, 0x61c6, 0x61c7, 
+    0x61c8, 0x61c9, 0x61ca, 0x61cb, 0x61cc, 0x61cd, 0x61ce, 0x61cf, 
+    0x61d0, 0x61d1, 0x61d2, 0x61d3, 0x61d4, 0x61d5, 0x61d6, 0x61d7, 
+    0x61d8, 0x61d9, 0x61da, 0x61db, 0x61dc, 0x61dd, 0x61de, 0x61df, 
+    0x61e0, 0x61e1, 0x61e2, 0x61e3, 0x61e4, 0x61e5, 0x61e6, 0x61e7, 
+    0x61e8, 0x61e9, 0x61ea, 0x61eb, 0x61ec, 0x61ed, 0x61ee, 0x61ef, 
+    0x61f0, 0x61f1, 0x61f2, 0x61f3, 0x61f4, 0x61f5, 0x61f6, 0x61f7, 
+    0x61f8, 0x61f9, 0x61fa, 0x61fb, 0x61fc, 0x61fd, 0x61fe, 0x61ff, 
+    0x6200, 0x6201, 0x6202, 0x6203, 0x6204, 0x6205, 0x6206, 0x6207, 
+    0x6208, 0x6209, 0x620a, 0x620b, 0x620c, 0x620d, 0x620e, 0x620f, 
+    0x6210, 0x6211, 0x6212, 0x6213, 0x6214, 0x6215, 0x6216, 0x6217, 
+    0x6218, 0x6219, 0x621a, 0x621b, 0x621c, 0x621d, 0x621e, 0x621f, 
+    0x6220, 0x6221, 0x6222, 0x6223, 0x6224, 0x6225, 0x6226, 0x6227, 
+    0x6228, 0x6229, 0x622a, 0x622b, 0x622c, 0x622d, 0x622e, 0x622f, 
+    0x6230, 0x6231, 0x6232, 0x6233, 0x6234, 0x6235, 0x6236, 0x6237, 
+    0x6238, 0x6239, 0x623a, 0x623b, 0x623c, 0x623d, 0x623e, 0x623f, 
+    0x6240, 0x6241, 0x6242, 0x6243, 0x6244, 0x6245, 0x6246, 0x6247, 
+    0x6248, 0x6249, 0x624a, 0x624b, 0x624c, 0x624d, 0x624e, 0x624f, 
+    0x6250, 0x6251, 0x6252, 0x6253, 0x6254, 0x6255, 0x6256, 0x6257, 
+    0x6258, 0x6259, 0x625a, 0x625b, 0x625c, 0x625d, 0x625e, 0x625f, 
+    0x6260, 0x6261, 0x6262, 0x6263, 0x6264, 0x6265, 0x6266, 0x6267, 
+    0x6268, 0x6269, 0x626a, 0x626b, 0x626c, 0x626d, 0x626e, 0x626f, 
+    0x6270, 0x6271, 0x6272, 0x6273, 0x6274, 0x6275, 0x6276, 0x6277, 
+    0x6278, 0x6279, 0x627a, 0x627b, 0x627c, 0x627d, 0x627e, 0x627f, 
+    0x6280, 0x6281, 0x6282, 0x6283, 0x6284, 0x6285, 0x6286, 0x6287, 
+    0x6288, 0x6289, 0x628a, 0x628b, 0x628c, 0x628d, 0x628e, 0x628f, 
+    0x6290, 0x6291, 0x6292, 0x6293, 0x6294, 0x6295, 0x6296, 0x6297, 
+    0x6298, 0x6299, 0x629a, 0x629b, 0x629c, 0x629d, 0x629e, 0x629f, 
+    0x62a0, 0x62a1, 0x62a2, 0x62a3, 0x62a4, 0x62a5, 0x62a6, 0x62a7, 
+    0x62a8, 0x62a9, 0x62aa, 0x62ab, 0x62ac, 0x62ad, 0x62ae, 0x62af, 
+    0x62b0, 0x62b1, 0x62b2, 0x62b3, 0x62b4, 0x62b5, 0x62b6, 0x62b7, 
+    0x62b8, 0x62b9, 0x62ba, 0x62bb, 0x62bc, 0x62bd, 0x62be, 0x62bf, 
+    0x62c0, 0x62c1, 0x62c2, 0x62c3, 0x62c4, 0x62c5, 0x62c6, 0x62c7, 
+    0x62c8, 0x62c9, 0x62ca, 0x62cb, 0x62cc, 0x62cd, 0x62ce, 0x62cf, 
+    0x62d0, 0x62d1, 0x62d2, 0x62d3, 0x62d4, 0x62d5, 0x62d6, 0x62d7, 
+    0x62d8, 0x62d9, 0x62da, 0x62db, 0x62dc, 0x62dd, 0x62de, 0x62df, 
+    0x62e0, 0x62e1, 0x62e2, 0x62e3, 0x62e4, 0x62e5, 0x62e6, 0x62e7, 
+    0x62e8, 0x62e9, 0x62ea, 0x62eb, 0x62ec, 0x62ed, 0x62ee, 0x62ef, 
+    0x62f0, 0x62f1, 0x62f2, 0x62f3, 0x62f4, 0x62f5, 0x62f6, 0x62f7, 
+    0x62f8, 0x62f9, 0x62fa, 0x62fb, 0x62fc, 0x62fd, 0x62fe, 0x62ff, 
+    0x6300, 0x6301, 0x6302, 0x6303, 0x6304, 0x6305, 0x6306, 0x6307, 
+    0x6308, 0x6309, 0x630a, 0x630b, 0x630c, 0x630d, 0x630e, 0x630f, 
+    0x6310, 0x6311, 0x6312, 0x6313, 0x6314, 0x6315, 0x6316, 0x6317, 
+    0x6318, 0x6319, 0x631a, 0x631b, 0x631c, 0x631d, 0x631e, 0x631f, 
+    0x6320, 0x6321, 0x6322, 0x6323, 0x6324, 0x6325, 0x6326, 0x6327, 
+    0x6328, 0x6329, 0x632a, 0x632b, 0x632c, 0x632d, 0x632e, 0x632f, 
+    0x6330, 0x6331, 0x6332, 0x6333, 0x6334, 0x6335, 0x6336, 0x6337, 
+    0x6338, 0x6339, 0x633a, 0x633b, 0x633c, 0x633d, 0x633e, 0x633f, 
+    0x6340, 0x6341, 0x6342, 0x6343, 0x6344, 0x6345, 0x6346, 0x6347, 
+    0x6348, 0x6349, 0x634a, 0x634b, 0x634c, 0x634d, 0x634e, 0x634f, 
+    0x6350, 0x6351, 0x6352, 0x6353, 0x6354, 0x6355, 0x6356, 0x6357, 
+    0x6358, 0x6359, 0x635a, 0x635b, 0x635c, 0x635d, 0x635e, 0x635f, 
+    0x6360, 0x6361, 0x6362, 0x6363, 0x6364, 0x6365, 0x6366, 0x6367, 
+    0x6368, 0x6369, 0x636a, 0x636b, 0x636c, 0x636d, 0x636e, 0x636f, 
+    0x6370, 0x6371, 0x6372, 0x6373, 0x6374, 0x6375, 0x6376, 0x6377, 
+    0x6378, 0x6379, 0x637a, 0x637b, 0x637c, 0x637d, 0x637e, 0x637f, 
+    0x6380, 0x6381, 0x6382, 0x6383, 0x6384, 0x6385, 0x6386, 0x6387, 
+    0x6388, 0x6389, 0x638a, 0x638b, 0x638c, 0x638d, 0x638e, 0x638f, 
+    0x6390, 0x6391, 0x6392, 0x6393, 0x6394, 0x6395, 0x6396, 0x6397, 
+    0x6398, 0x6399, 0x639a, 0x639b, 0x639c, 0x639d, 0x639e, 0x639f, 
+    0x63a0, 0x63a1, 0x63a2, 0x63a3, 0x63a4, 0x63a5, 0x63a6, 0x63a7, 
+    0x63a8, 0x63a9, 0x63aa, 0x63ab, 0x63ac, 0x63ad, 0x63ae, 0x63af, 
+    0x63b0, 0x63b1, 0x63b2, 0x63b3, 0x63b4, 0x63b5, 0x63b6, 0x63b7, 
+    0x63b8, 0x63b9, 0x63ba, 0x63bb, 0x63bc, 0x63bd, 0x63be, 0x63bf, 
+    0x63c0, 0x63c1, 0x63c2, 0x63c3, 0x63c4, 0x63c5, 0x63c6, 0x63c7, 
+    0x63c8, 0x63c9, 0x63ca, 0x63cb, 0x63cc, 0x63cd, 0x63ce, 0x63cf, 
+    0x63d0, 0x63d1, 0x63d2, 0x63d3, 0x63d4, 0x63d5, 0x63d6, 0x63d7, 
+    0x63d8, 0x63d9, 0x63da, 0x63db, 0x63dc, 0x63dd, 0x63de, 0x63df, 
+    0x63e0, 0x63e1, 0x63e2, 0x63e3, 0x63e4, 0x63e5, 0x63e6, 0x63e7, 
+    0x63e8, 0x63e9, 0x63ea, 0x63eb, 0x63ec, 0x63ed, 0x63ee, 0x63ef, 
+    0x63f0, 0x63f1, 0x63f2, 0x63f3, 0x63f4, 0x63f5, 0x63f6, 0x63f7, 
+    0x63f8, 0x63f9, 0x63fa, 0x63fb, 0x63fc, 0x63fd, 0x63fe, 0x63ff, 
+    0x6400, 0x6401, 0x6402, 0x6403, 0x6404, 0x6405, 0x6406, 0x6407, 
+    0x6408, 0x6409, 0x640a, 0x640b, 0x640c, 0x640d, 0x640e, 0x640f, 
+    0x6410, 0x6411, 0x6412, 0x6413, 0x6414, 0x6415, 0x6416, 0x6417, 
+    0x6418, 0x6419, 0x641a, 0x641b, 0x641c, 0x641d, 0x641e, 0x641f, 
+    0x6420, 0x6421, 0x6422, 0x6423, 0x6424, 0x6425, 0x6426, 0x6427, 
+    0x6428, 0x6429, 0x642a, 0x642b, 0x642c, 0x642d, 0x642e, 0x642f, 
+    0x6430, 0x6431, 0x6432, 0x6433, 0x6434, 0x6435, 0x6436, 0x6437, 
+    0x6438, 0x6439, 0x643a, 0x643b, 0x643c, 0x643d, 0x643e, 0x643f, 
+    0x6440, 0x6441, 0x6442, 0x6443, 0x6444, 0x6445, 0x6446, 0x6447, 
+    0x6448, 0x6449, 0x644a, 0x644b, 0x644c, 0x644d, 0x644e, 0x644f, 
+    0x6450, 0x6451, 0x6452, 0x6453, 0x6454, 0x6455, 0x6456, 0x6457, 
+    0x6458, 0x6459, 0x645a, 0x645b, 0x645c, 0x645d, 0x645e, 0x645f, 
+    0x6460, 0x6461, 0x6462, 0x6463, 0x6464, 0x6465, 0x6466, 0x6467, 
+    0x6468, 0x6469, 0x646a, 0x646b, 0x646c, 0x646d, 0x646e, 0x646f, 
+    0x6470, 0x6471, 0x6472, 0x6473, 0x6474, 0x6475, 0x6476, 0x6477, 
+    0x6478, 0x6479, 0x647a, 0x647b, 0x647c, 0x647d, 0x647e, 0x647f, 
+    0x6480, 0x6481, 0x6482, 0x6483, 0x6484, 0x6485, 0x6486, 0x6487, 
+    0x6488, 0x6489, 0x648a, 0x648b, 0x648c, 0x648d, 0x648e, 0x648f, 
+    0x6490, 0x6491, 0x6492, 0x6493, 0x6494, 0x6495, 0x6496, 0x6497, 
+    0x6498, 0x6499, 0x649a, 0x649b, 0x649c, 0x649d, 0x649e, 0x649f, 
+    0x64a0, 0x64a1, 0x64a2, 0x64a3, 0x64a4, 0x64a5, 0x64a6, 0x64a7, 
+    0x64a8, 0x64a9, 0x64aa, 0x64ab, 0x64ac, 0x64ad, 0x64ae, 0x64af, 
+    0x64b0, 0x64b1, 0x64b2, 0x64b3, 0x64b4, 0x64b5, 0x64b6, 0x64b7, 
+    0x64b8, 0x64b9, 0x64ba, 0x64bb, 0x64bc, 0x64bd, 0x64be, 0x64bf, 
+    0x64c0, 0x64c1, 0x64c2, 0x64c3, 0x64c4, 0x64c5, 0x64c6, 0x64c7, 
+    0x64c8, 0x64c9, 0x64ca, 0x64cb, 0x64cc, 0x64cd, 0x64ce, 0x64cf, 
+    0x64d0, 0x64d1, 0x64d2, 0x64d3, 0x64d4, 0x64d5, 0x64d6, 0x64d7, 
+    0x64d8, 0x64d9, 0x64da, 0x64db, 0x64dc, 0x64dd, 0x64de, 0x64df, 
+    0x64e0, 0x64e1, 0x64e2, 0x64e3, 0x64e4, 0x64e5, 0x64e6, 0x64e7, 
+    0x64e8, 0x64e9, 0x64ea, 0x64eb, 0x64ec, 0x64ed, 0x64ee, 0x64ef, 
+    0x64f0, 0x64f1, 0x64f2, 0x64f3, 0x64f4, 0x64f5, 0x64f6, 0x64f7, 
+    0x64f8, 0x64f9, 0x64fa, 0x64fb, 0x64fc, 0x64fd, 0x64fe, 0x64ff, 
+    0x6500, 0x6501, 0x6502, 0x6503, 0x6504, 0x6505, 0x6506, 0x6507, 
+    0x6508, 0x6509, 0x650a, 0x650b, 0x650c, 0x650d, 0x650e, 0x650f, 
+    0x6510, 0x6511, 0x6512, 0x6513, 0x6514, 0x6515, 0x6516, 0x6517, 
+    0x6518, 0x6519, 0x651a, 0x651b, 0x651c, 0x651d, 0x651e, 0x651f, 
+    0x6520, 0x6521, 0x6522, 0x6523, 0x6524, 0x6525, 0x6526, 0x6527, 
+    0x6528, 0x6529, 0x652a, 0x652b, 0x652c, 0x652d, 0x652e, 0x652f, 
+    0x6530, 0x6531, 0x6532, 0x6533, 0x6534, 0x6535, 0x6536, 0x6537, 
+    0x6538, 0x6539, 0x653a, 0x653b, 0x653c, 0x653d, 0x653e, 0x653f, 
+    0x6540, 0x6541, 0x6542, 0x6543, 0x6544, 0x6545, 0x6546, 0x6547, 
+    0x6548, 0x6549, 0x654a, 0x654b, 0x654c, 0x654d, 0x654e, 0x654f, 
+    0x6550, 0x6551, 0x6552, 0x6553, 0x6554, 0x6555, 0x6556, 0x6557, 
+    0x6558, 0x6559, 0x655a, 0x655b, 0x655c, 0x655d, 0x655e, 0x655f, 
+    0x6560, 0x6561, 0x6562, 0x6563, 0x6564, 0x6565, 0x6566, 0x6567, 
+    0x6568, 0x6569, 0x656a, 0x656b, 0x656c, 0x656d, 0x656e, 0x656f, 
+    0x6570, 0x6571, 0x6572, 0x6573, 0x6574, 0x6575, 0x6576, 0x6577, 
+    0x6578, 0x6579, 0x657a, 0x657b, 0x657c, 0x657d, 0x657e, 0x657f, 
+    0x6580, 0x6581, 0x6582, 0x6583, 0x6584, 0x6585, 0x6586, 0x6587, 
+    0x6588, 0x6589, 0x658a, 0x658b, 0x658c, 0x658d, 0x658e, 0x658f, 
+    0x6590, 0x6591, 0x6592, 0x6593, 0x6594, 0x6595, 0x6596, 0x6597, 
+    0x6598, 0x6599, 0x659a, 0x659b, 0x659c, 0x659d, 0x659e, 0x659f, 
+    0x65a0, 0x65a1, 0x65a2, 0x65a3, 0x65a4, 0x65a5, 0x65a6, 0x65a7, 
+    0x65a8, 0x65a9, 0x65aa, 0x65ab, 0x65ac, 0x65ad, 0x65ae, 0x65af, 
+    0x65b0, 0x65b1, 0x65b2, 0x65b3, 0x65b4, 0x65b5, 0x65b6, 0x65b7, 
+    0x65b8, 0x65b9, 0x65ba, 0x65bb, 0x65bc, 0x65bd, 0x65be, 0x65bf, 
+    0x65c0, 0x65c1, 0x65c2, 0x65c3, 0x65c4, 0x65c5, 0x65c6, 0x65c7, 
+    0x65c8, 0x65c9, 0x65ca, 0x65cb, 0x65cc, 0x65cd, 0x65ce, 0x65cf, 
+    0x65d0, 0x65d1, 0x65d2, 0x65d3, 0x65d4, 0x65d5, 0x65d6, 0x65d7, 
+    0x65d8, 0x65d9, 0x65da, 0x65db, 0x65dc, 0x65dd, 0x65de, 0x65df, 
+    0x65e0, 0x65e1, 0x65e2, 0x65e3, 0x65e4, 0x65e5, 0x65e6, 0x65e7, 
+    0x65e8, 0x65e9, 0x65ea, 0x65eb, 0x65ec, 0x65ed, 0x65ee, 0x65ef, 
+    0x65f0, 0x65f1, 0x65f2, 0x65f3, 0x65f4, 0x65f5, 0x65f6, 0x65f7, 
+    0x65f8, 0x65f9, 0x65fa, 0x65fb, 0x65fc, 0x65fd, 0x65fe, 0x65ff, 
+    0x6600, 0x6601, 0x6602, 0x6603, 0x6604, 0x6605, 0x6606, 0x6607, 
+    0x6608, 0x6609, 0x660a, 0x660b, 0x660c, 0x660d, 0x660e, 0x660f, 
+    0x6610, 0x6611, 0x6612, 0x6613, 0x6614, 0x6615, 0x6616, 0x6617, 
+    0x6618, 0x6619, 0x661a, 0x661b, 0x661c, 0x661d, 0x661e, 0x661f, 
+    0x6620, 0x6621, 0x6622, 0x6623, 0x6624, 0x6625, 0x6626, 0x6627, 
+    0x6628, 0x6629, 0x662a, 0x662b, 0x662c, 0x662d, 0x662e, 0x662f, 
+    0x6630, 0x6631, 0x6632, 0x6633, 0x6634, 0x6635, 0x6636, 0x6637, 
+    0x6638, 0x6639, 0x663a, 0x663b, 0x663c, 0x663d, 0x663e, 0x663f, 
+    0x6640, 0x6641, 0x6642, 0x6643, 0x6644, 0x6645, 0x6646, 0x6647, 
+    0x6648, 0x6649, 0x664a, 0x664b, 0x664c, 0x664d, 0x664e, 0x664f, 
+    0x6650, 0x6651, 0x6652, 0x6653, 0x6654, 0x6655, 0x6656, 0x6657, 
+    0x6658, 0x6659, 0x665a, 0x665b, 0x665c, 0x665d, 0x665e, 0x665f, 
+    0x6660, 0x6661, 0x6662, 0x6663, 0x6664, 0x6665, 0x6666, 0x6667, 
+    0x6668, 0x6669, 0x666a, 0x666b, 0x666c, 0x666d, 0x666e, 0x666f, 
+    0x6670, 0x6671, 0x6672, 0x6673, 0x6674, 0x6675, 0x6676, 0x6677, 
+    0x6678, 0x6679, 0x667a, 0x667b, 0x667c, 0x667d, 0x667e, 0x667f, 
+    0x6680, 0x6681, 0x6682, 0x6683, 0x6684, 0x6685, 0x6686, 0x6687, 
+    0x6688, 0x6689, 0x668a, 0x668b, 0x668c, 0x668d, 0x668e, 0x668f, 
+    0x6690, 0x6691, 0x6692, 0x6693, 0x6694, 0x6695, 0x6696, 0x6697, 
+    0x6698, 0x6699, 0x669a, 0x669b, 0x669c, 0x669d, 0x669e, 0x669f, 
+    0x66a0, 0x66a1, 0x66a2, 0x66a3, 0x66a4, 0x66a5, 0x66a6, 0x66a7, 
+    0x66a8, 0x66a9, 0x66aa, 0x66ab, 0x66ac, 0x66ad, 0x66ae, 0x66af, 
+    0x66b0, 0x66b1, 0x66b2, 0x66b3, 0x66b4, 0x66b5, 0x66b6, 0x66b7, 
+    0x66b8, 0x66b9, 0x66ba, 0x66bb, 0x66bc, 0x66bd, 0x66be, 0x66bf, 
+    0x66c0, 0x66c1, 0x66c2, 0x66c3, 0x66c4, 0x66c5, 0x66c6, 0x66c7, 
+    0x66c8, 0x66c9, 0x66ca, 0x66cb, 0x66cc, 0x66cd, 0x66ce, 0x66cf, 
+    0x66d0, 0x66d1, 0x66d2, 0x66d3, 0x66d4, 0x66d5, 0x66d6, 0x66d7, 
+    0x66d8, 0x66d9, 0x66da, 0x66db, 0x66dc, 0x66dd, 0x66de, 0x66df, 
+    0x66e0, 0x66e1, 0x66e2, 0x66e3, 0x66e4, 0x66e5, 0x66e6, 0x66e7, 
+    0x66e8, 0x66e9, 0x66ea, 0x66eb, 0x66ec, 0x66ed, 0x66ee, 0x66ef, 
+    0x66f0, 0x66f1, 0x66f2, 0x66f3, 0x66f4, 0x66f5, 0x66f6, 0x66f7, 
+    0x66f8, 0x66f9, 0x66fa, 0x66fb, 0x66fc, 0x66fd, 0x66fe, 0x66ff, 
+    0x6700, 0x6701, 0x6702, 0x6703, 0x6704, 0x6705, 0x6706, 0x6707, 
+    0x6708, 0x6709, 0x670a, 0x670b, 0x670c, 0x670d, 0x670e, 0x670f, 
+    0x6710, 0x6711, 0x6712, 0x6713, 0x6714, 0x6715, 0x6716, 0x6717, 
+    0x6718, 0x6719, 0x671a, 0x671b, 0x671c, 0x671d, 0x671e, 0x671f, 
+    0x6720, 0x6721, 0x6722, 0x6723, 0x6724, 0x6725, 0x6726, 0x6727, 
+    0x6728, 0x6729, 0x672a, 0x672b, 0x672c, 0x672d, 0x672e, 0x672f, 
+    0x6730, 0x6731, 0x6732, 0x6733, 0x6734, 0x6735, 0x6736, 0x6737, 
+    0x6738, 0x6739, 0x673a, 0x673b, 0x673c, 0x673d, 0x673e, 0x673f, 
+    0x6740, 0x6741, 0x6742, 0x6743, 0x6744, 0x6745, 0x6746, 0x6747, 
+    0x6748, 0x6749, 0x674a, 0x674b, 0x674c, 0x674d, 0x674e, 0x674f, 
+    0x6750, 0x6751, 0x6752, 0x6753, 0x6754, 0x6755, 0x6756, 0x6757, 
+    0x6758, 0x6759, 0x675a, 0x675b, 0x675c, 0x675d, 0x675e, 0x675f, 
+    0x6760, 0x6761, 0x6762, 0x6763, 0x6764, 0x6765, 0x6766, 0x6767, 
+    0x6768, 0x6769, 0x676a, 0x676b, 0x676c, 0x676d, 0x676e, 0x676f, 
+    0x6770, 0x6771, 0x6772, 0x6773, 0x6774, 0x6775, 0x6776, 0x6777, 
+    0x6778, 0x6779, 0x677a, 0x677b, 0x677c, 0x677d, 0x677e, 0x677f, 
+    0x6780, 0x6781, 0x6782, 0x6783, 0x6784, 0x6785, 0x6786, 0x6787, 
+    0x6788, 0x6789, 0x678a, 0x678b, 0x678c, 0x678d, 0x678e, 0x678f, 
+    0x6790, 0x6791, 0x6792, 0x6793, 0x6794, 0x6795, 0x6796, 0x6797, 
+    0x6798, 0x6799, 0x679a, 0x679b, 0x679c, 0x679d, 0x679e, 0x679f, 
+    0x67a0, 0x67a1, 0x67a2, 0x67a3, 0x67a4, 0x67a5, 0x67a6, 0x67a7, 
+    0x67a8, 0x67a9, 0x67aa, 0x67ab, 0x67ac, 0x67ad, 0x67ae, 0x67af, 
+    0x67b0, 0x67b1, 0x67b2, 0x67b3, 0x67b4, 0x67b5, 0x67b6, 0x67b7, 
+    0x67b8, 0x67b9, 0x67ba, 0x67bb, 0x67bc, 0x67bd, 0x67be, 0x67bf, 
+    0x67c0, 0x67c1, 0x67c2, 0x67c3, 0x67c4, 0x67c5, 0x67c6, 0x67c7, 
+    0x67c8, 0x67c9, 0x67ca, 0x67cb, 0x67cc, 0x67cd, 0x67ce, 0x67cf, 
+    0x67d0, 0x67d1, 0x67d2, 0x67d3, 0x67d4, 0x67d5, 0x67d6, 0x67d7, 
+    0x67d8, 0x67d9, 0x67da, 0x67db, 0x67dc, 0x67dd, 0x67de, 0x67df, 
+    0x67e0, 0x67e1, 0x67e2, 0x67e3, 0x67e4, 0x67e5, 0x67e6, 0x67e7, 
+    0x67e8, 0x67e9, 0x67ea, 0x67eb, 0x67ec, 0x67ed, 0x67ee, 0x67ef, 
+    0x67f0, 0x67f1, 0x67f2, 0x67f3, 0x67f4, 0x67f5, 0x67f6, 0x67f7, 
+    0x67f8, 0x67f9, 0x67fa, 0x67fb, 0x67fc, 0x67fd, 0x67fe, 0x67ff, 
+    0x6800, 0x6801, 0x6802, 0x6803, 0x6804, 0x6805, 0x6806, 0x6807, 
+    0x6808, 0x6809, 0x680a, 0x680b, 0x680c, 0x680d, 0x680e, 0x680f, 
+    0x6810, 0x6811, 0x6812, 0x6813, 0x6814, 0x6815, 0x6816, 0x6817, 
+    0x6818, 0x6819, 0x681a, 0x681b, 0x681c, 0x681d, 0x681e, 0x681f, 
+    0x6820, 0x6821, 0x6822, 0x6823, 0x6824, 0x6825, 0x6826, 0x6827, 
+    0x6828, 0x6829, 0x682a, 0x682b, 0x682c, 0x682d, 0x682e, 0x682f, 
+    0x6830, 0x6831, 0x6832, 0x6833, 0x6834, 0x6835, 0x6836, 0x6837, 
+    0x6838, 0x6839, 0x683a, 0x683b, 0x683c, 0x683d, 0x683e, 0x683f, 
+    0x6840, 0x6841, 0x6842, 0x6843, 0x6844, 0x6845, 0x6846, 0x6847, 
+    0x6848, 0x6849, 0x684a, 0x684b, 0x684c, 0x684d, 0x684e, 0x684f, 
+    0x6850, 0x6851, 0x6852, 0x6853, 0x6854, 0x6855, 0x6856, 0x6857, 
+    0x6858, 0x6859, 0x685a, 0x685b, 0x685c, 0x685d, 0x685e, 0x685f, 
+    0x6860, 0x6861, 0x6862, 0x6863, 0x6864, 0x6865, 0x6866, 0x6867, 
+    0x6868, 0x6869, 0x686a, 0x686b, 0x686c, 0x686d, 0x686e, 0x686f, 
+    0x6870, 0x6871, 0x6872, 0x6873, 0x6874, 0x6875, 0x6876, 0x6877, 
+    0x6878, 0x6879, 0x687a, 0x687b, 0x687c, 0x687d, 0x687e, 0x687f, 
+    0x6880, 0x6881, 0x6882, 0x6883, 0x6884, 0x6885, 0x6886, 0x6887, 
+    0x6888, 0x6889, 0x688a, 0x688b, 0x688c, 0x688d, 0x688e, 0x688f, 
+    0x6890, 0x6891, 0x6892, 0x6893, 0x6894, 0x6895, 0x6896, 0x6897, 
+    0x6898, 0x6899, 0x689a, 0x689b, 0x689c, 0x689d, 0x689e, 0x689f, 
+    0x68a0, 0x68a1, 0x68a2, 0x68a3, 0x68a4, 0x68a5, 0x68a6, 0x68a7, 
+    0x68a8, 0x68a9, 0x68aa, 0x68ab, 0x68ac, 0x68ad, 0x68ae, 0x68af, 
+    0x68b0, 0x68b1, 0x68b2, 0x68b3, 0x68b4, 0x68b5, 0x68b6, 0x68b7, 
+    0x68b8, 0x68b9, 0x68ba, 0x68bb, 0x68bc, 0x68bd, 0x68be, 0x68bf, 
+    0x68c0, 0x68c1, 0x68c2, 0x68c3, 0x68c4, 0x68c5, 0x68c6, 0x68c7, 
+    0x68c8, 0x68c9, 0x68ca, 0x68cb, 0x68cc, 0x68cd, 0x68ce, 0x68cf, 
+    0x68d0, 0x68d1, 0x68d2, 0x68d3, 0x68d4, 0x68d5, 0x68d6, 0x68d7, 
+    0x68d8, 0x68d9, 0x68da, 0x68db, 0x68dc, 0x68dd, 0x68de, 0x68df, 
+    0x68e0, 0x68e1, 0x68e2, 0x68e3, 0x68e4, 0x68e5, 0x68e6, 0x68e7, 
+    0x68e8, 0x68e9, 0x68ea, 0x68eb, 0x68ec, 0x68ed, 0x68ee, 0x68ef, 
+    0x68f0, 0x68f1, 0x68f2, 0x68f3, 0x68f4, 0x68f5, 0x68f6, 0x68f7, 
+    0x68f8, 0x68f9, 0x68fa, 0x68fb, 0x68fc, 0x68fd, 0x68fe, 0x68ff, 
+    0x6900, 0x6901, 0x6902, 0x6903, 0x6904, 0x6905, 0x6906, 0x6907, 
+    0x6908, 0x6909, 0x690a, 0x690b, 0x690c, 0x690d, 0x690e, 0x690f, 
+    0x6910, 0x6911, 0x6912, 0x6913, 0x6914, 0x6915, 0x6916, 0x6917, 
+    0x6918, 0x6919, 0x691a, 0x691b, 0x691c, 0x691d, 0x691e, 0x691f, 
+    0x6920, 0x6921, 0x6922, 0x6923, 0x6924, 0x6925, 0x6926, 0x6927, 
+    0x6928, 0x6929, 0x692a, 0x692b, 0x692c, 0x692d, 0x692e, 0x692f, 
+    0x6930, 0x6931, 0x6932, 0x6933, 0x6934, 0x6935, 0x6936, 0x6937, 
+    0x6938, 0x6939, 0x693a, 0x693b, 0x693c, 0x693d, 0x693e, 0x693f, 
+    0x6940, 0x6941, 0x6942, 0x6943, 0x6944, 0x6945, 0x6946, 0x6947, 
+    0x6948, 0x6949, 0x694a, 0x694b, 0x694c, 0x694d, 0x694e, 0x694f, 
+    0x6950, 0x6951, 0x6952, 0x6953, 0x6954, 0x6955, 0x6956, 0x6957, 
+    0x6958, 0x6959, 0x695a, 0x695b, 0x695c, 0x695d, 0x695e, 0x695f, 
+    0x6960, 0x6961, 0x6962, 0x6963, 0x6964, 0x6965, 0x6966, 0x6967, 
+    0x6968, 0x6969, 0x696a, 0x696b, 0x696c, 0x696d, 0x696e, 0x696f, 
+    0x6970, 0x6971, 0x6972, 0x6973, 0x6974, 0x6975, 0x6976, 0x6977, 
+    0x6978, 0x6979, 0x697a, 0x697b, 0x697c, 0x697d, 0x697e, 0x697f, 
+    0x6980, 0x6981, 0x6982, 0x6983, 0x6984, 0x6985, 0x6986, 0x6987, 
+    0x6988, 0x6989, 0x698a, 0x698b, 0x698c, 0x698d, 0x698e, 0x698f, 
+    0x6990, 0x6991, 0x6992, 0x6993, 0x6994, 0x6995, 0x6996, 0x6997, 
+    0x6998, 0x6999, 0x699a, 0x699b, 0x699c, 0x699d, 0x699e, 0x699f, 
+    0x69a0, 0x69a1, 0x69a2, 0x69a3, 0x69a4, 0x69a5, 0x69a6, 0x69a7, 
+    0x69a8, 0x69a9, 0x69aa, 0x69ab, 0x69ac, 0x69ad, 0x69ae, 0x69af, 
+    0x69b0, 0x69b1, 0x69b2, 0x69b3, 0x69b4, 0x69b5, 0x69b6, 0x69b7, 
+    0x69b8, 0x69b9, 0x69ba, 0x69bb, 0x69bc, 0x69bd, 0x69be, 0x69bf, 
+    0x69c0, 0x69c1, 0x69c2, 0x69c3, 0x69c4, 0x69c5, 0x69c6, 0x69c7, 
+    0x69c8, 0x69c9, 0x69ca, 0x69cb, 0x69cc, 0x69cd, 0x69ce, 0x69cf, 
+    0x69d0, 0x69d1, 0x69d2, 0x69d3, 0x69d4, 0x69d5, 0x69d6, 0x69d7, 
+    0x69d8, 0x69d9, 0x69da, 0x69db, 0x69dc, 0x69dd, 0x69de, 0x69df, 
+    0x69e0, 0x69e1, 0x69e2, 0x69e3, 0x69e4, 0x69e5, 0x69e6, 0x69e7, 
+    0x69e8, 0x69e9, 0x69ea, 0x69eb, 0x69ec, 0x69ed, 0x69ee, 0x69ef, 
+    0x69f0, 0x69f1, 0x69f2, 0x69f3, 0x69f4, 0x69f5, 0x69f6, 0x69f7, 
+    0x69f8, 0x69f9, 0x69fa, 0x69fb, 0x69fc, 0x69fd, 0x69fe, 0x69ff, 
+    0x6a00, 0x6a01, 0x6a02, 0x6a03, 0x6a04, 0x6a05, 0x6a06, 0x6a07, 
+    0x6a08, 0x6a09, 0x6a0a, 0x6a0b, 0x6a0c, 0x6a0d, 0x6a0e, 0x6a0f, 
+    0x6a10, 0x6a11, 0x6a12, 0x6a13, 0x6a14, 0x6a15, 0x6a16, 0x6a17, 
+    0x6a18, 0x6a19, 0x6a1a, 0x6a1b, 0x6a1c, 0x6a1d, 0x6a1e, 0x6a1f, 
+    0x6a20, 0x6a21, 0x6a22, 0x6a23, 0x6a24, 0x6a25, 0x6a26, 0x6a27, 
+    0x6a28, 0x6a29, 0x6a2a, 0x6a2b, 0x6a2c, 0x6a2d, 0x6a2e, 0x6a2f, 
+    0x6a30, 0x6a31, 0x6a32, 0x6a33, 0x6a34, 0x6a35, 0x6a36, 0x6a37, 
+    0x6a38, 0x6a39, 0x6a3a, 0x6a3b, 0x6a3c, 0x6a3d, 0x6a3e, 0x6a3f, 
+    0x6a40, 0x6a41, 0x6a42, 0x6a43, 0x6a44, 0x6a45, 0x6a46, 0x6a47, 
+    0x6a48, 0x6a49, 0x6a4a, 0x6a4b, 0x6a4c, 0x6a4d, 0x6a4e, 0x6a4f, 
+    0x6a50, 0x6a51, 0x6a52, 0x6a53, 0x6a54, 0x6a55, 0x6a56, 0x6a57, 
+    0x6a58, 0x6a59, 0x6a5a, 0x6a5b, 0x6a5c, 0x6a5d, 0x6a5e, 0x6a5f, 
+    0x6a60, 0x6a61, 0x6a62, 0x6a63, 0x6a64, 0x6a65, 0x6a66, 0x6a67, 
+    0x6a68, 0x6a69, 0x6a6a, 0x6a6b, 0x6a6c, 0x6a6d, 0x6a6e, 0x6a6f, 
+    0x6a70, 0x6a71, 0x6a72, 0x6a73, 0x6a74, 0x6a75, 0x6a76, 0x6a77, 
+    0x6a78, 0x6a79, 0x6a7a, 0x6a7b, 0x6a7c, 0x6a7d, 0x6a7e, 0x6a7f, 
+    0x6a80, 0x6a81, 0x6a82, 0x6a83, 0x6a84, 0x6a85, 0x6a86, 0x6a87, 
+    0x6a88, 0x6a89, 0x6a8a, 0x6a8b, 0x6a8c, 0x6a8d, 0x6a8e, 0x6a8f, 
+    0x6a90, 0x6a91, 0x6a92, 0x6a93, 0x6a94, 0x6a95, 0x6a96, 0x6a97, 
+    0x6a98, 0x6a99, 0x6a9a, 0x6a9b, 0x6a9c, 0x6a9d, 0x6a9e, 0x6a9f, 
+    0x6aa0, 0x6aa1, 0x6aa2, 0x6aa3, 0x6aa4, 0x6aa5, 0x6aa6, 0x6aa7, 
+    0x6aa8, 0x6aa9, 0x6aaa, 0x6aab, 0x6aac, 0x6aad, 0x6aae, 0x6aaf, 
+    0x6ab0, 0x6ab1, 0x6ab2, 0x6ab3, 0x6ab4, 0x6ab5, 0x6ab6, 0x6ab7, 
+    0x6ab8, 0x6ab9, 0x6aba, 0x6abb, 0x6abc, 0x6abd, 0x6abe, 0x6abf, 
+    0x6ac0, 0x6ac1, 0x6ac2, 0x6ac3, 0x6ac4, 0x6ac5, 0x6ac6, 0x6ac7, 
+    0x6ac8, 0x6ac9, 0x6aca, 0x6acb, 0x6acc, 0x6acd, 0x6ace, 0x6acf, 
+    0x6ad0, 0x6ad1, 0x6ad2, 0x6ad3, 0x6ad4, 0x6ad5, 0x6ad6, 0x6ad7, 
+    0x6ad8, 0x6ad9, 0x6ada, 0x6adb, 0x6adc, 0x6add, 0x6ade, 0x6adf, 
+    0x6ae0, 0x6ae1, 0x6ae2, 0x6ae3, 0x6ae4, 0x6ae5, 0x6ae6, 0x6ae7, 
+    0x6ae8, 0x6ae9, 0x6aea, 0x6aeb, 0x6aec, 0x6aed, 0x6aee, 0x6aef, 
+    0x6af0, 0x6af1, 0x6af2, 0x6af3, 0x6af4, 0x6af5, 0x6af6, 0x6af7, 
+    0x6af8, 0x6af9, 0x6afa, 0x6afb, 0x6afc, 0x6afd, 0x6afe, 0x6aff, 
+    0x6b00, 0x6b01, 0x6b02, 0x6b03, 0x6b04, 0x6b05, 0x6b06, 0x6b07, 
+    0x6b08, 0x6b09, 0x6b0a, 0x6b0b, 0x6b0c, 0x6b0d, 0x6b0e, 0x6b0f, 
+    0x6b10, 0x6b11, 0x6b12, 0x6b13, 0x6b14, 0x6b15, 0x6b16, 0x6b17, 
+    0x6b18, 0x6b19, 0x6b1a, 0x6b1b, 0x6b1c, 0x6b1d, 0x6b1e, 0x6b1f, 
+    0x6b20, 0x6b21, 0x6b22, 0x6b23, 0x6b24, 0x6b25, 0x6b26, 0x6b27, 
+    0x6b28, 0x6b29, 0x6b2a, 0x6b2b, 0x6b2c, 0x6b2d, 0x6b2e, 0x6b2f, 
+    0x6b30, 0x6b31, 0x6b32, 0x6b33, 0x6b34, 0x6b35, 0x6b36, 0x6b37, 
+    0x6b38, 0x6b39, 0x6b3a, 0x6b3b, 0x6b3c, 0x6b3d, 0x6b3e, 0x6b3f, 
+    0x6b40, 0x6b41, 0x6b42, 0x6b43, 0x6b44, 0x6b45, 0x6b46, 0x6b47, 
+    0x6b48, 0x6b49, 0x6b4a, 0x6b4b, 0x6b4c, 0x6b4d, 0x6b4e, 0x6b4f, 
+    0x6b50, 0x6b51, 0x6b52, 0x6b53, 0x6b54, 0x6b55, 0x6b56, 0x6b57, 
+    0x6b58, 0x6b59, 0x6b5a, 0x6b5b, 0x6b5c, 0x6b5d, 0x6b5e, 0x6b5f, 
+    0x6b60, 0x6b61, 0x6b62, 0x6b63, 0x6b64, 0x6b65, 0x6b66, 0x6b67, 
+    0x6b68, 0x6b69, 0x6b6a, 0x6b6b, 0x6b6c, 0x6b6d, 0x6b6e, 0x6b6f, 
+    0x6b70, 0x6b71, 0x6b72, 0x6b73, 0x6b74, 0x6b75, 0x6b76, 0x6b77, 
+    0x6b78, 0x6b79, 0x6b7a, 0x6b7b, 0x6b7c, 0x6b7d, 0x6b7e, 0x6b7f, 
+    0x6b80, 0x6b81, 0x6b82, 0x6b83, 0x6b84, 0x6b85, 0x6b86, 0x6b87, 
+    0x6b88, 0x6b89, 0x6b8a, 0x6b8b, 0x6b8c, 0x6b8d, 0x6b8e, 0x6b8f, 
+    0x6b90, 0x6b91, 0x6b92, 0x6b93, 0x6b94, 0x6b95, 0x6b96, 0x6b97, 
+    0x6b98, 0x6b99, 0x6b9a, 0x6b9b, 0x6b9c, 0x6b9d, 0x6b9e, 0x6b9f, 
+    0x6ba0, 0x6ba1, 0x6ba2, 0x6ba3, 0x6ba4, 0x6ba5, 0x6ba6, 0x6ba7, 
+    0x6ba8, 0x6ba9, 0x6baa, 0x6bab, 0x6bac, 0x6bad, 0x6bae, 0x6baf, 
+    0x6bb0, 0x6bb1, 0x6bb2, 0x6bb3, 0x6bb4, 0x6bb5, 0x6bb6, 0x6bb7, 
+    0x6bb8, 0x6bb9, 0x6bba, 0x6bbb, 0x6bbc, 0x6bbd, 0x6bbe, 0x6bbf, 
+    0x6bc0, 0x6bc1, 0x6bc2, 0x6bc3, 0x6bc4, 0x6bc5, 0x6bc6, 0x6bc7, 
+    0x6bc8, 0x6bc9, 0x6bca, 0x6bcb, 0x6bcc, 0x6bcd, 0x6bce, 0x6bcf, 
+    0x6bd0, 0x6bd1, 0x6bd2, 0x6bd3, 0x6bd4, 0x6bd5, 0x6bd6, 0x6bd7, 
+    0x6bd8, 0x6bd9, 0x6bda, 0x6bdb, 0x6bdc, 0x6bdd, 0x6bde, 0x6bdf, 
+    0x6be0, 0x6be1, 0x6be2, 0x6be3, 0x6be4, 0x6be5, 0x6be6, 0x6be7, 
+    0x6be8, 0x6be9, 0x6bea, 0x6beb, 0x6bec, 0x6bed, 0x6bee, 0x6bef, 
+    0x6bf0, 0x6bf1, 0x6bf2, 0x6bf3, 0x6bf4, 0x6bf5, 0x6bf6, 0x6bf7, 
+    0x6bf8, 0x6bf9, 0x6bfa, 0x6bfb, 0x6bfc, 0x6bfd, 0x6bfe, 0x6bff, 
+    0x6c00, 0x6c01, 0x6c02, 0x6c03, 0x6c04, 0x6c05, 0x6c06, 0x6c07, 
+    0x6c08, 0x6c09, 0x6c0a, 0x6c0b, 0x6c0c, 0x6c0d, 0x6c0e, 0x6c0f, 
+    0x6c10, 0x6c11, 0x6c12, 0x6c13, 0x6c14, 0x6c15, 0x6c16, 0x6c17, 
+    0x6c18, 0x6c19, 0x6c1a, 0x6c1b, 0x6c1c, 0x6c1d, 0x6c1e, 0x6c1f, 
+    0x6c20, 0x6c21, 0x6c22, 0x6c23, 0x6c24, 0x6c25, 0x6c26, 0x6c27, 
+    0x6c28, 0x6c29, 0x6c2a, 0x6c2b, 0x6c2c, 0x6c2d, 0x6c2e, 0x6c2f, 
+    0x6c30, 0x6c31, 0x6c32, 0x6c33, 0x6c34, 0x6c35, 0x6c36, 0x6c37, 
+    0x6c38, 0x6c39, 0x6c3a, 0x6c3b, 0x6c3c, 0x6c3d, 0x6c3e, 0x6c3f, 
+    0x6c40, 0x6c41, 0x6c42, 0x6c43, 0x6c44, 0x6c45, 0x6c46, 0x6c47, 
+    0x6c48, 0x6c49, 0x6c4a, 0x6c4b, 0x6c4c, 0x6c4d, 0x6c4e, 0x6c4f, 
+    0x6c50, 0x6c51, 0x6c52, 0x6c53, 0x6c54, 0x6c55, 0x6c56, 0x6c57, 
+    0x6c58, 0x6c59, 0x6c5a, 0x6c5b, 0x6c5c, 0x6c5d, 0x6c5e, 0x6c5f, 
+    0x6c60, 0x6c61, 0x6c62, 0x6c63, 0x6c64, 0x6c65, 0x6c66, 0x6c67, 
+    0x6c68, 0x6c69, 0x6c6a, 0x6c6b, 0x6c6c, 0x6c6d, 0x6c6e, 0x6c6f, 
+    0x6c70, 0x6c71, 0x6c72, 0x6c73, 0x6c74, 0x6c75, 0x6c76, 0x6c77, 
+    0x6c78, 0x6c79, 0x6c7a, 0x6c7b, 0x6c7c, 0x6c7d, 0x6c7e, 0x6c7f, 
+    0x6c80, 0x6c81, 0x6c82, 0x6c83, 0x6c84, 0x6c85, 0x6c86, 0x6c87, 
+    0x6c88, 0x6c89, 0x6c8a, 0x6c8b, 0x6c8c, 0x6c8d, 0x6c8e, 0x6c8f, 
+    0x6c90, 0x6c91, 0x6c92, 0x6c93, 0x6c94, 0x6c95, 0x6c96, 0x6c97, 
+    0x6c98, 0x6c99, 0x6c9a, 0x6c9b, 0x6c9c, 0x6c9d, 0x6c9e, 0x6c9f, 
+    0x6ca0, 0x6ca1, 0x6ca2, 0x6ca3, 0x6ca4, 0x6ca5, 0x6ca6, 0x6ca7, 
+    0x6ca8, 0x6ca9, 0x6caa, 0x6cab, 0x6cac, 0x6cad, 0x6cae, 0x6caf, 
+    0x6cb0, 0x6cb1, 0x6cb2, 0x6cb3, 0x6cb4, 0x6cb5, 0x6cb6, 0x6cb7, 
+    0x6cb8, 0x6cb9, 0x6cba, 0x6cbb, 0x6cbc, 0x6cbd, 0x6cbe, 0x6cbf, 
+    0x6cc0, 0x6cc1, 0x6cc2, 0x6cc3, 0x6cc4, 0x6cc5, 0x6cc6, 0x6cc7, 
+    0x6cc8, 0x6cc9, 0x6cca, 0x6ccb, 0x6ccc, 0x6ccd, 0x6cce, 0x6ccf, 
+    0x6cd0, 0x6cd1, 0x6cd2, 0x6cd3, 0x6cd4, 0x6cd5, 0x6cd6, 0x6cd7, 
+    0x6cd8, 0x6cd9, 0x6cda, 0x6cdb, 0x6cdc, 0x6cdd, 0x6cde, 0x6cdf, 
+    0x6ce0, 0x6ce1, 0x6ce2, 0x6ce3, 0x6ce4, 0x6ce5, 0x6ce6, 0x6ce7, 
+    0x6ce8, 0x6ce9, 0x6cea, 0x6ceb, 0x6cec, 0x6ced, 0x6cee, 0x6cef, 
+    0x6cf0, 0x6cf1, 0x6cf2, 0x6cf3, 0x6cf4, 0x6cf5, 0x6cf6, 0x6cf7, 
+    0x6cf8, 0x6cf9, 0x6cfa, 0x6cfb, 0x6cfc, 0x6cfd, 0x6cfe, 0x6cff, 
+    0x6d00, 0x6d01, 0x6d02, 0x6d03, 0x6d04, 0x6d05, 0x6d06, 0x6d07, 
+    0x6d08, 0x6d09, 0x6d0a, 0x6d0b, 0x6d0c, 0x6d0d, 0x6d0e, 0x6d0f, 
+    0x6d10, 0x6d11, 0x6d12, 0x6d13, 0x6d14, 0x6d15, 0x6d16, 0x6d17, 
+    0x6d18, 0x6d19, 0x6d1a, 0x6d1b, 0x6d1c, 0x6d1d, 0x6d1e, 0x6d1f, 
+    0x6d20, 0x6d21, 0x6d22, 0x6d23, 0x6d24, 0x6d25, 0x6d26, 0x6d27, 
+    0x6d28, 0x6d29, 0x6d2a, 0x6d2b, 0x6d2c, 0x6d2d, 0x6d2e, 0x6d2f, 
+    0x6d30, 0x6d31, 0x6d32, 0x6d33, 0x6d34, 0x6d35, 0x6d36, 0x6d37, 
+    0x6d38, 0x6d39, 0x6d3a, 0x6d3b, 0x6d3c, 0x6d3d, 0x6d3e, 0x6d3f, 
+    0x6d40, 0x6d41, 0x6d42, 0x6d43, 0x6d44, 0x6d45, 0x6d46, 0x6d47, 
+    0x6d48, 0x6d49, 0x6d4a, 0x6d4b, 0x6d4c, 0x6d4d, 0x6d4e, 0x6d4f, 
+    0x6d50, 0x6d51, 0x6d52, 0x6d53, 0x6d54, 0x6d55, 0x6d56, 0x6d57, 
+    0x6d58, 0x6d59, 0x6d5a, 0x6d5b, 0x6d5c, 0x6d5d, 0x6d5e, 0x6d5f, 
+    0x6d60, 0x6d61, 0x6d62, 0x6d63, 0x6d64, 0x6d65, 0x6d66, 0x6d67, 
+    0x6d68, 0x6d69, 0x6d6a, 0x6d6b, 0x6d6c, 0x6d6d, 0x6d6e, 0x6d6f, 
+    0x6d70, 0x6d71, 0x6d72, 0x6d73, 0x6d74, 0x6d75, 0x6d76, 0x6d77, 
+    0x6d78, 0x6d79, 0x6d7a, 0x6d7b, 0x6d7c, 0x6d7d, 0x6d7e, 0x6d7f, 
+    0x6d80, 0x6d81, 0x6d82, 0x6d83, 0x6d84, 0x6d85, 0x6d86, 0x6d87, 
+    0x6d88, 0x6d89, 0x6d8a, 0x6d8b, 0x6d8c, 0x6d8d, 0x6d8e, 0x6d8f, 
+    0x6d90, 0x6d91, 0x6d92, 0x6d93, 0x6d94, 0x6d95, 0x6d96, 0x6d97, 
+    0x6d98, 0x6d99, 0x6d9a, 0x6d9b, 0x6d9c, 0x6d9d, 0x6d9e, 0x6d9f, 
+    0x6da0, 0x6da1, 0x6da2, 0x6da3, 0x6da4, 0x6da5, 0x6da6, 0x6da7, 
+    0x6da8, 0x6da9, 0x6daa, 0x6dab, 0x6dac, 0x6dad, 0x6dae, 0x6daf, 
+    0x6db0, 0x6db1, 0x6db2, 0x6db3, 0x6db4, 0x6db5, 0x6db6, 0x6db7, 
+    0x6db8, 0x6db9, 0x6dba, 0x6dbb, 0x6dbc, 0x6dbd, 0x6dbe, 0x6dbf, 
+    0x6dc0, 0x6dc1, 0x6dc2, 0x6dc3, 0x6dc4, 0x6dc5, 0x6dc6, 0x6dc7, 
+    0x6dc8, 0x6dc9, 0x6dca, 0x6dcb, 0x6dcc, 0x6dcd, 0x6dce, 0x6dcf, 
+    0x6dd0, 0x6dd1, 0x6dd2, 0x6dd3, 0x6dd4, 0x6dd5, 0x6dd6, 0x6dd7, 
+    0x6dd8, 0x6dd9, 0x6dda, 0x6ddb, 0x6ddc, 0x6ddd, 0x6dde, 0x6ddf, 
+    0x6de0, 0x6de1, 0x6de2, 0x6de3, 0x6de4, 0x6de5, 0x6de6, 0x6de7, 
+    0x6de8, 0x6de9, 0x6dea, 0x6deb, 0x6dec, 0x6ded, 0x6dee, 0x6def, 
+    0x6df0, 0x6df1, 0x6df2, 0x6df3, 0x6df4, 0x6df5, 0x6df6, 0x6df7, 
+    0x6df8, 0x6df9, 0x6dfa, 0x6dfb, 0x6dfc, 0x6dfd, 0x6dfe, 0x6dff, 
+    0x6e00, 0x6e01, 0x6e02, 0x6e03, 0x6e04, 0x6e05, 0x6e06, 0x6e07, 
+    0x6e08, 0x6e09, 0x6e0a, 0x6e0b, 0x6e0c, 0x6e0d, 0x6e0e, 0x6e0f, 
+    0x6e10, 0x6e11, 0x6e12, 0x6e13, 0x6e14, 0x6e15, 0x6e16, 0x6e17, 
+    0x6e18, 0x6e19, 0x6e1a, 0x6e1b, 0x6e1c, 0x6e1d, 0x6e1e, 0x6e1f, 
+    0x6e20, 0x6e21, 0x6e22, 0x6e23, 0x6e24, 0x6e25, 0x6e26, 0x6e27, 
+    0x6e28, 0x6e29, 0x6e2a, 0x6e2b, 0x6e2c, 0x6e2d, 0x6e2e, 0x6e2f, 
+    0x6e30, 0x6e31, 0x6e32, 0x6e33, 0x6e34, 0x6e35, 0x6e36, 0x6e37, 
+    0x6e38, 0x6e39, 0x6e3a, 0x6e3b, 0x6e3c, 0x6e3d, 0x6e3e, 0x6e3f, 
+    0x6e40, 0x6e41, 0x6e42, 0x6e43, 0x6e44, 0x6e45, 0x6e46, 0x6e47, 
+    0x6e48, 0x6e49, 0x6e4a, 0x6e4b, 0x6e4c, 0x6e4d, 0x6e4e, 0x6e4f, 
+    0x6e50, 0x6e51, 0x6e52, 0x6e53, 0x6e54, 0x6e55, 0x6e56, 0x6e57, 
+    0x6e58, 0x6e59, 0x6e5a, 0x6e5b, 0x6e5c, 0x6e5d, 0x6e5e, 0x6e5f, 
+    0x6e60, 0x6e61, 0x6e62, 0x6e63, 0x6e64, 0x6e65, 0x6e66, 0x6e67, 
+    0x6e68, 0x6e69, 0x6e6a, 0x6e6b, 0x6e6c, 0x6e6d, 0x6e6e, 0x6e6f, 
+    0x6e70, 0x6e71, 0x6e72, 0x6e73, 0x6e74, 0x6e75, 0x6e76, 0x6e77, 
+    0x6e78, 0x6e79, 0x6e7a, 0x6e7b, 0x6e7c, 0x6e7d, 0x6e7e, 0x6e7f, 
+    0x6e80, 0x6e81, 0x6e82, 0x6e83, 0x6e84, 0x6e85, 0x6e86, 0x6e87, 
+    0x6e88, 0x6e89, 0x6e8a, 0x6e8b, 0x6e8c, 0x6e8d, 0x6e8e, 0x6e8f, 
+    0x6e90, 0x6e91, 0x6e92, 0x6e93, 0x6e94, 0x6e95, 0x6e96, 0x6e97, 
+    0x6e98, 0x6e99, 0x6e9a, 0x6e9b, 0x6e9c, 0x6e9d, 0x6e9e, 0x6e9f, 
+    0x6ea0, 0x6ea1, 0x6ea2, 0x6ea3, 0x6ea4, 0x6ea5, 0x6ea6, 0x6ea7, 
+    0x6ea8, 0x6ea9, 0x6eaa, 0x6eab, 0x6eac, 0x6ead, 0x6eae, 0x6eaf, 
+    0x6eb0, 0x6eb1, 0x6eb2, 0x6eb3, 0x6eb4, 0x6eb5, 0x6eb6, 0x6eb7, 
+    0x6eb8, 0x6eb9, 0x6eba, 0x6ebb, 0x6ebc, 0x6ebd, 0x6ebe, 0x6ebf, 
+    0x6ec0, 0x6ec1, 0x6ec2, 0x6ec3, 0x6ec4, 0x6ec5, 0x6ec6, 0x6ec7, 
+    0x6ec8, 0x6ec9, 0x6eca, 0x6ecb, 0x6ecc, 0x6ecd, 0x6ece, 0x6ecf, 
+    0x6ed0, 0x6ed1, 0x6ed2, 0x6ed3, 0x6ed4, 0x6ed5, 0x6ed6, 0x6ed7, 
+    0x6ed8, 0x6ed9, 0x6eda, 0x6edb, 0x6edc, 0x6edd, 0x6ede, 0x6edf, 
+    0x6ee0, 0x6ee1, 0x6ee2, 0x6ee3, 0x6ee4, 0x6ee5, 0x6ee6, 0x6ee7, 
+    0x6ee8, 0x6ee9, 0x6eea, 0x6eeb, 0x6eec, 0x6eed, 0x6eee, 0x6eef, 
+    0x6ef0, 0x6ef1, 0x6ef2, 0x6ef3, 0x6ef4, 0x6ef5, 0x6ef6, 0x6ef7, 
+    0x6ef8, 0x6ef9, 0x6efa, 0x6efb, 0x6efc, 0x6efd, 0x6efe, 0x6eff, 
+    0x6f00, 0x6f01, 0x6f02, 0x6f03, 0x6f04, 0x6f05, 0x6f06, 0x6f07, 
+    0x6f08, 0x6f09, 0x6f0a, 0x6f0b, 0x6f0c, 0x6f0d, 0x6f0e, 0x6f0f, 
+    0x6f10, 0x6f11, 0x6f12, 0x6f13, 0x6f14, 0x6f15, 0x6f16, 0x6f17, 
+    0x6f18, 0x6f19, 0x6f1a, 0x6f1b, 0x6f1c, 0x6f1d, 0x6f1e, 0x6f1f, 
+    0x6f20, 0x6f21, 0x6f22, 0x6f23, 0x6f24, 0x6f25, 0x6f26, 0x6f27, 
+    0x6f28, 0x6f29, 0x6f2a, 0x6f2b, 0x6f2c, 0x6f2d, 0x6f2e, 0x6f2f, 
+    0x6f30, 0x6f31, 0x6f32, 0x6f33, 0x6f34, 0x6f35, 0x6f36, 0x6f37, 
+    0x6f38, 0x6f39, 0x6f3a, 0x6f3b, 0x6f3c, 0x6f3d, 0x6f3e, 0x6f3f, 
+    0x6f40, 0x6f41, 0x6f42, 0x6f43, 0x6f44, 0x6f45, 0x6f46, 0x6f47, 
+    0x6f48, 0x6f49, 0x6f4a, 0x6f4b, 0x6f4c, 0x6f4d, 0x6f4e, 0x6f4f, 
+    0x6f50, 0x6f51, 0x6f52, 0x6f53, 0x6f54, 0x6f55, 0x6f56, 0x6f57, 
+    0x6f58, 0x6f59, 0x6f5a, 0x6f5b, 0x6f5c, 0x6f5d, 0x6f5e, 0x6f5f, 
+    0x6f60, 0x6f61, 0x6f62, 0x6f63, 0x6f64, 0x6f65, 0x6f66, 0x6f67, 
+    0x6f68, 0x6f69, 0x6f6a, 0x6f6b, 0x6f6c, 0x6f6d, 0x6f6e, 0x6f6f, 
+    0x6f70, 0x6f71, 0x6f72, 0x6f73, 0x6f74, 0x6f75, 0x6f76, 0x6f77, 
+    0x6f78, 0x6f79, 0x6f7a, 0x6f7b, 0x6f7c, 0x6f7d, 0x6f7e, 0x6f7f, 
+    0x6f80, 0x6f81, 0x6f82, 0x6f83, 0x6f84, 0x6f85, 0x6f86, 0x6f87, 
+    0x6f88, 0x6f89, 0x6f8a, 0x6f8b, 0x6f8c, 0x6f8d, 0x6f8e, 0x6f8f, 
+    0x6f90, 0x6f91, 0x6f92, 0x6f93, 0x6f94, 0x6f95, 0x6f96, 0x6f97, 
+    0x6f98, 0x6f99, 0x6f9a, 0x6f9b, 0x6f9c, 0x6f9d, 0x6f9e, 0x6f9f, 
+    0x6fa0, 0x6fa1, 0x6fa2, 0x6fa3, 0x6fa4, 0x6fa5, 0x6fa6, 0x6fa7, 
+    0x6fa8, 0x6fa9, 0x6faa, 0x6fab, 0x6fac, 0x6fad, 0x6fae, 0x6faf, 
+    0x6fb0, 0x6fb1, 0x6fb2, 0x6fb3, 0x6fb4, 0x6fb5, 0x6fb6, 0x6fb7, 
+    0x6fb8, 0x6fb9, 0x6fba, 0x6fbb, 0x6fbc, 0x6fbd, 0x6fbe, 0x6fbf, 
+    0x6fc0, 0x6fc1, 0x6fc2, 0x6fc3, 0x6fc4, 0x6fc5, 0x6fc6, 0x6fc7, 
+    0x6fc8, 0x6fc9, 0x6fca, 0x6fcb, 0x6fcc, 0x6fcd, 0x6fce, 0x6fcf, 
+    0x6fd0, 0x6fd1, 0x6fd2, 0x6fd3, 0x6fd4, 0x6fd5, 0x6fd6, 0x6fd7, 
+    0x6fd8, 0x6fd9, 0x6fda, 0x6fdb, 0x6fdc, 0x6fdd, 0x6fde, 0x6fdf, 
+    0x6fe0, 0x6fe1, 0x6fe2, 0x6fe3, 0x6fe4, 0x6fe5, 0x6fe6, 0x6fe7, 
+    0x6fe8, 0x6fe9, 0x6fea, 0x6feb, 0x6fec, 0x6fed, 0x6fee, 0x6fef, 
+    0x6ff0, 0x6ff1, 0x6ff2, 0x6ff3, 0x6ff4, 0x6ff5, 0x6ff6, 0x6ff7, 
+    0x6ff8, 0x6ff9, 0x6ffa, 0x6ffb, 0x6ffc, 0x6ffd, 0x6ffe, 0x6fff, 
+    0x7000, 0x7001, 0x7002, 0x7003, 0x7004, 0x7005, 0x7006, 0x7007, 
+    0x7008, 0x7009, 0x700a, 0x700b, 0x700c, 0x700d, 0x700e, 0x700f, 
+    0x7010, 0x7011, 0x7012, 0x7013, 0x7014, 0x7015, 0x7016, 0x7017, 
+    0x7018, 0x7019, 0x701a, 0x701b, 0x701c, 0x701d, 0x701e, 0x701f, 
+    0x7020, 0x7021, 0x7022, 0x7023, 0x7024, 0x7025, 0x7026, 0x7027, 
+    0x7028, 0x7029, 0x702a, 0x702b, 0x702c, 0x702d, 0x702e, 0x702f, 
+    0x7030, 0x7031, 0x7032, 0x7033, 0x7034, 0x7035, 0x7036, 0x7037, 
+    0x7038, 0x7039, 0x703a, 0x703b, 0x703c, 0x703d, 0x703e, 0x703f, 
+    0x7040, 0x7041, 0x7042, 0x7043, 0x7044, 0x7045, 0x7046, 0x7047, 
+    0x7048, 0x7049, 0x704a, 0x704b, 0x704c, 0x704d, 0x704e, 0x704f, 
+    0x7050, 0x7051, 0x7052, 0x7053, 0x7054, 0x7055, 0x7056, 0x7057, 
+    0x7058, 0x7059, 0x705a, 0x705b, 0x705c, 0x705d, 0x705e, 0x705f, 
+    0x7060, 0x7061, 0x7062, 0x7063, 0x7064, 0x7065, 0x7066, 0x7067, 
+    0x7068, 0x7069, 0x706a, 0x706b, 0x706c, 0x706d, 0x706e, 0x706f, 
+    0x7070, 0x7071, 0x7072, 0x7073, 0x7074, 0x7075, 0x7076, 0x7077, 
+    0x7078, 0x7079, 0x707a, 0x707b, 0x707c, 0x707d, 0x707e, 0x707f, 
+    0x7080, 0x7081, 0x7082, 0x7083, 0x7084, 0x7085, 0x7086, 0x7087, 
+    0x7088, 0x7089, 0x708a, 0x708b, 0x708c, 0x708d, 0x708e, 0x708f, 
+    0x7090, 0x7091, 0x7092, 0x7093, 0x7094, 0x7095, 0x7096, 0x7097, 
+    0x7098, 0x7099, 0x709a, 0x709b, 0x709c, 0x709d, 0x709e, 0x709f, 
+    0x70a0, 0x70a1, 0x70a2, 0x70a3, 0x70a4, 0x70a5, 0x70a6, 0x70a7, 
+    0x70a8, 0x70a9, 0x70aa, 0x70ab, 0x70ac, 0x70ad, 0x70ae, 0x70af, 
+    0x70b0, 0x70b1, 0x70b2, 0x70b3, 0x70b4, 0x70b5, 0x70b6, 0x70b7, 
+    0x70b8, 0x70b9, 0x70ba, 0x70bb, 0x70bc, 0x70bd, 0x70be, 0x70bf, 
+    0x70c0, 0x70c1, 0x70c2, 0x70c3, 0x70c4, 0x70c5, 0x70c6, 0x70c7, 
+    0x70c8, 0x70c9, 0x70ca, 0x70cb, 0x70cc, 0x70cd, 0x70ce, 0x70cf, 
+    0x70d0, 0x70d1, 0x70d2, 0x70d3, 0x70d4, 0x70d5, 0x70d6, 0x70d7, 
+    0x70d8, 0x70d9, 0x70da, 0x70db, 0x70dc, 0x70dd, 0x70de, 0x70df, 
+    0x70e0, 0x70e1, 0x70e2, 0x70e3, 0x70e4, 0x70e5, 0x70e6, 0x70e7, 
+    0x70e8, 0x70e9, 0x70ea, 0x70eb, 0x70ec, 0x70ed, 0x70ee, 0x70ef, 
+    0x70f0, 0x70f1, 0x70f2, 0x70f3, 0x70f4, 0x70f5, 0x70f6, 0x70f7, 
+    0x70f8, 0x70f9, 0x70fa, 0x70fb, 0x70fc, 0x70fd, 0x70fe, 0x70ff, 
+    0x7100, 0x7101, 0x7102, 0x7103, 0x7104, 0x7105, 0x7106, 0x7107, 
+    0x7108, 0x7109, 0x710a, 0x710b, 0x710c, 0x710d, 0x710e, 0x710f, 
+    0x7110, 0x7111, 0x7112, 0x7113, 0x7114, 0x7115, 0x7116, 0x7117, 
+    0x7118, 0x7119, 0x711a, 0x711b, 0x711c, 0x711d, 0x711e, 0x711f, 
+    0x7120, 0x7121, 0x7122, 0x7123, 0x7124, 0x7125, 0x7126, 0x7127, 
+    0x7128, 0x7129, 0x712a, 0x712b, 0x712c, 0x712d, 0x712e, 0x712f, 
+    0x7130, 0x7131, 0x7132, 0x7133, 0x7134, 0x7135, 0x7136, 0x7137, 
+    0x7138, 0x7139, 0x713a, 0x713b, 0x713c, 0x713d, 0x713e, 0x713f, 
+    0x7140, 0x7141, 0x7142, 0x7143, 0x7144, 0x7145, 0x7146, 0x7147, 
+    0x7148, 0x7149, 0x714a, 0x714b, 0x714c, 0x714d, 0x714e, 0x714f, 
+    0x7150, 0x7151, 0x7152, 0x7153, 0x7154, 0x7155, 0x7156, 0x7157, 
+    0x7158, 0x7159, 0x715a, 0x715b, 0x715c, 0x715d, 0x715e, 0x715f, 
+    0x7160, 0x7161, 0x7162, 0x7163, 0x7164, 0x7165, 0x7166, 0x7167, 
+    0x7168, 0x7169, 0x716a, 0x716b, 0x716c, 0x716d, 0x716e, 0x716f, 
+    0x7170, 0x7171, 0x7172, 0x7173, 0x7174, 0x7175, 0x7176, 0x7177, 
+    0x7178, 0x7179, 0x717a, 0x717b, 0x717c, 0x717d, 0x717e, 0x717f, 
+    0x7180, 0x7181, 0x7182, 0x7183, 0x7184, 0x7185, 0x7186, 0x7187, 
+    0x7188, 0x7189, 0x718a, 0x718b, 0x718c, 0x718d, 0x718e, 0x718f, 
+    0x7190, 0x7191, 0x7192, 0x7193, 0x7194, 0x7195, 0x7196, 0x7197, 
+    0x7198, 0x7199, 0x719a, 0x719b, 0x719c, 0x719d, 0x719e, 0x719f, 
+    0x71a0, 0x71a1, 0x71a2, 0x71a3, 0x71a4, 0x71a5, 0x71a6, 0x71a7, 
+    0x71a8, 0x71a9, 0x71aa, 0x71ab, 0x71ac, 0x71ad, 0x71ae, 0x71af, 
+    0x71b0, 0x71b1, 0x71b2, 0x71b3, 0x71b4, 0x71b5, 0x71b6, 0x71b7, 
+    0x71b8, 0x71b9, 0x71ba, 0x71bb, 0x71bc, 0x71bd, 0x71be, 0x71bf, 
+    0x71c0, 0x71c1, 0x71c2, 0x71c3, 0x71c4, 0x71c5, 0x71c6, 0x71c7, 
+    0x71c8, 0x71c9, 0x71ca, 0x71cb, 0x71cc, 0x71cd, 0x71ce, 0x71cf, 
+    0x71d0, 0x71d1, 0x71d2, 0x71d3, 0x71d4, 0x71d5, 0x71d6, 0x71d7, 
+    0x71d8, 0x71d9, 0x71da, 0x71db, 0x71dc, 0x71dd, 0x71de, 0x71df, 
+    0x71e0, 0x71e1, 0x71e2, 0x71e3, 0x71e4, 0x71e5, 0x71e6, 0x71e7, 
+    0x71e8, 0x71e9, 0x71ea, 0x71eb, 0x71ec, 0x71ed, 0x71ee, 0x71ef, 
+    0x71f0, 0x71f1, 0x71f2, 0x71f3, 0x71f4, 0x71f5, 0x71f6, 0x71f7, 
+    0x71f8, 0x71f9, 0x71fa, 0x71fb, 0x71fc, 0x71fd, 0x71fe, 0x71ff, 
+    0x7200, 0x7201, 0x7202, 0x7203, 0x7204, 0x7205, 0x7206, 0x7207, 
+    0x7208, 0x7209, 0x720a, 0x720b, 0x720c, 0x720d, 0x720e, 0x720f, 
+    0x7210, 0x7211, 0x7212, 0x7213, 0x7214, 0x7215, 0x7216, 0x7217, 
+    0x7218, 0x7219, 0x721a, 0x721b, 0x721c, 0x721d, 0x721e, 0x721f, 
+    0x7220, 0x7221, 0x7222, 0x7223, 0x7224, 0x7225, 0x7226, 0x7227, 
+    0x7228, 0x7229, 0x722a, 0x722b, 0x722c, 0x722d, 0x722e, 0x722f, 
+    0x7230, 0x7231, 0x7232, 0x7233, 0x7234, 0x7235, 0x7236, 0x7237, 
+    0x7238, 0x7239, 0x723a, 0x723b, 0x723c, 0x723d, 0x723e, 0x723f, 
+    0x7240, 0x7241, 0x7242, 0x7243, 0x7244, 0x7245, 0x7246, 0x7247, 
+    0x7248, 0x7249, 0x724a, 0x724b, 0x724c, 0x724d, 0x724e, 0x724f, 
+    0x7250, 0x7251, 0x7252, 0x7253, 0x7254, 0x7255, 0x7256, 0x7257, 
+    0x7258, 0x7259, 0x725a, 0x725b, 0x725c, 0x725d, 0x725e, 0x725f, 
+    0x7260, 0x7261, 0x7262, 0x7263, 0x7264, 0x7265, 0x7266, 0x7267, 
+    0x7268, 0x7269, 0x726a, 0x726b, 0x726c, 0x726d, 0x726e, 0x726f, 
+    0x7270, 0x7271, 0x7272, 0x7273, 0x7274, 0x7275, 0x7276, 0x7277, 
+    0x7278, 0x7279, 0x727a, 0x727b, 0x727c, 0x727d, 0x727e, 0x727f, 
+    0x7280, 0x7281, 0x7282, 0x7283, 0x7284, 0x7285, 0x7286, 0x7287, 
+    0x7288, 0x7289, 0x728a, 0x728b, 0x728c, 0x728d, 0x728e, 0x728f, 
+    0x7290, 0x7291, 0x7292, 0x7293, 0x7294, 0x7295, 0x7296, 0x7297, 
+    0x7298, 0x7299, 0x729a, 0x729b, 0x729c, 0x729d, 0x729e, 0x729f, 
+    0x72a0, 0x72a1, 0x72a2, 0x72a3, 0x72a4, 0x72a5, 0x72a6, 0x72a7, 
+    0x72a8, 0x72a9, 0x72aa, 0x72ab, 0x72ac, 0x72ad, 0x72ae, 0x72af, 
+    0x72b0, 0x72b1, 0x72b2, 0x72b3, 0x72b4, 0x72b5, 0x72b6, 0x72b7, 
+    0x72b8, 0x72b9, 0x72ba, 0x72bb, 0x72bc, 0x72bd, 0x72be, 0x72bf, 
+    0x72c0, 0x72c1, 0x72c2, 0x72c3, 0x72c4, 0x72c5, 0x72c6, 0x72c7, 
+    0x72c8, 0x72c9, 0x72ca, 0x72cb, 0x72cc, 0x72cd, 0x72ce, 0x72cf, 
+    0x72d0, 0x72d1, 0x72d2, 0x72d3, 0x72d4, 0x72d5, 0x72d6, 0x72d7, 
+    0x72d8, 0x72d9, 0x72da, 0x72db, 0x72dc, 0x72dd, 0x72de, 0x72df, 
+    0x72e0, 0x72e1, 0x72e2, 0x72e3, 0x72e4, 0x72e5, 0x72e6, 0x72e7, 
+    0x72e8, 0x72e9, 0x72ea, 0x72eb, 0x72ec, 0x72ed, 0x72ee, 0x72ef, 
+    0x72f0, 0x72f1, 0x72f2, 0x72f3, 0x72f4, 0x72f5, 0x72f6, 0x72f7, 
+    0x72f8, 0x72f9, 0x72fa, 0x72fb, 0x72fc, 0x72fd, 0x72fe, 0x72ff, 
+    0x7300, 0x7301, 0x7302, 0x7303, 0x7304, 0x7305, 0x7306, 0x7307, 
+    0x7308, 0x7309, 0x730a, 0x730b, 0x730c, 0x730d, 0x730e, 0x730f, 
+    0x7310, 0x7311, 0x7312, 0x7313, 0x7314, 0x7315, 0x7316, 0x7317, 
+    0x7318, 0x7319, 0x731a, 0x731b, 0x731c, 0x731d, 0x731e, 0x731f, 
+    0x7320, 0x7321, 0x7322, 0x7323, 0x7324, 0x7325, 0x7326, 0x7327, 
+    0x7328, 0x7329, 0x732a, 0x732b, 0x732c, 0x732d, 0x732e, 0x732f, 
+    0x7330, 0x7331, 0x7332, 0x7333, 0x7334, 0x7335, 0x7336, 0x7337, 
+    0x7338, 0x7339, 0x733a, 0x733b, 0x733c, 0x733d, 0x733e, 0x733f, 
+    0x7340, 0x7341, 0x7342, 0x7343, 0x7344, 0x7345, 0x7346, 0x7347, 
+    0x7348, 0x7349, 0x734a, 0x734b, 0x734c, 0x734d, 0x734e, 0x734f, 
+    0x7350, 0x7351, 0x7352, 0x7353, 0x7354, 0x7355, 0x7356, 0x7357, 
+    0x7358, 0x7359, 0x735a, 0x735b, 0x735c, 0x735d, 0x735e, 0x735f, 
+    0x7360, 0x7361, 0x7362, 0x7363, 0x7364, 0x7365, 0x7366, 0x7367, 
+    0x7368, 0x7369, 0x736a, 0x736b, 0x736c, 0x736d, 0x736e, 0x736f, 
+    0x7370, 0x7371, 0x7372, 0x7373, 0x7374, 0x7375, 0x7376, 0x7377, 
+    0x7378, 0x7379, 0x737a, 0x737b, 0x737c, 0x737d, 0x737e, 0x737f, 
+    0x7380, 0x7381, 0x7382, 0x7383, 0x7384, 0x7385, 0x7386, 0x7387, 
+    0x7388, 0x7389, 0x738a, 0x738b, 0x738c, 0x738d, 0x738e, 0x738f, 
+    0x7390, 0x7391, 0x7392, 0x7393, 0x7394, 0x7395, 0x7396, 0x7397, 
+    0x7398, 0x7399, 0x739a, 0x739b, 0x739c, 0x739d, 0x739e, 0x739f, 
+    0x73a0, 0x73a1, 0x73a2, 0x73a3, 0x73a4, 0x73a5, 0x73a6, 0x73a7, 
+    0x73a8, 0x73a9, 0x73aa, 0x73ab, 0x73ac, 0x73ad, 0x73ae, 0x73af, 
+    0x73b0, 0x73b1, 0x73b2, 0x73b3, 0x73b4, 0x73b5, 0x73b6, 0x73b7, 
+    0x73b8, 0x73b9, 0x73ba, 0x73bb, 0x73bc, 0x73bd, 0x73be, 0x73bf, 
+    0x73c0, 0x73c1, 0x73c2, 0x73c3, 0x73c4, 0x73c5, 0x73c6, 0x73c7, 
+    0x73c8, 0x73c9, 0x73ca, 0x73cb, 0x73cc, 0x73cd, 0x73ce, 0x73cf, 
+    0x73d0, 0x73d1, 0x73d2, 0x73d3, 0x73d4, 0x73d5, 0x73d6, 0x73d7, 
+    0x73d8, 0x73d9, 0x73da, 0x73db, 0x73dc, 0x73dd, 0x73de, 0x73df, 
+    0x73e0, 0x73e1, 0x73e2, 0x73e3, 0x73e4, 0x73e5, 0x73e6, 0x73e7, 
+    0x73e8, 0x73e9, 0x73ea, 0x73eb, 0x73ec, 0x73ed, 0x73ee, 0x73ef, 
+    0x73f0, 0x73f1, 0x73f2, 0x73f3, 0x73f4, 0x73f5, 0x73f6, 0x73f7, 
+    0x73f8, 0x73f9, 0x73fa, 0x73fb, 0x73fc, 0x73fd, 0x73fe, 0x73ff, 
+    0x7400, 0x7401, 0x7402, 0x7403, 0x7404, 0x7405, 0x7406, 0x7407, 
+    0x7408, 0x7409, 0x740a, 0x740b, 0x740c, 0x740d, 0x740e, 0x740f, 
+    0x7410, 0x7411, 0x7412, 0x7413, 0x7414, 0x7415, 0x7416, 0x7417, 
+    0x7418, 0x7419, 0x741a, 0x741b, 0x741c, 0x741d, 0x741e, 0x741f, 
+    0x7420, 0x7421, 0x7422, 0x7423, 0x7424, 0x7425, 0x7426, 0x7427, 
+    0x7428, 0x7429, 0x742a, 0x742b, 0x742c, 0x742d, 0x742e, 0x742f, 
+    0x7430, 0x7431, 0x7432, 0x7433, 0x7434, 0x7435, 0x7436, 0x7437, 
+    0x7438, 0x7439, 0x743a, 0x743b, 0x743c, 0x743d, 0x743e, 0x743f, 
+    0x7440, 0x7441, 0x7442, 0x7443, 0x7444, 0x7445, 0x7446, 0x7447, 
+    0x7448, 0x7449, 0x744a, 0x744b, 0x744c, 0x744d, 0x744e, 0x744f, 
+    0x7450, 0x7451, 0x7452, 0x7453, 0x7454, 0x7455, 0x7456, 0x7457, 
+    0x7458, 0x7459, 0x745a, 0x745b, 0x745c, 0x745d, 0x745e, 0x745f, 
+    0x7460, 0x7461, 0x7462, 0x7463, 0x7464, 0x7465, 0x7466, 0x7467, 
+    0x7468, 0x7469, 0x746a, 0x746b, 0x746c, 0x746d, 0x746e, 0x746f, 
+    0x7470, 0x7471, 0x7472, 0x7473, 0x7474, 0x7475, 0x7476, 0x7477, 
+    0x7478, 0x7479, 0x747a, 0x747b, 0x747c, 0x747d, 0x747e, 0x747f, 
+    0x7480, 0x7481, 0x7482, 0x7483, 0x7484, 0x7485, 0x7486, 0x7487, 
+    0x7488, 0x7489, 0x748a, 0x748b, 0x748c, 0x748d, 0x748e, 0x748f, 
+    0x7490, 0x7491, 0x7492, 0x7493, 0x7494, 0x7495, 0x7496, 0x7497, 
+    0x7498, 0x7499, 0x749a, 0x749b, 0x749c, 0x749d, 0x749e, 0x749f, 
+    0x74a0, 0x74a1, 0x74a2, 0x74a3, 0x74a4, 0x74a5, 0x74a6, 0x74a7, 
+    0x74a8, 0x74a9, 0x74aa, 0x74ab, 0x74ac, 0x74ad, 0x74ae, 0x74af, 
+    0x74b0, 0x74b1, 0x74b2, 0x74b3, 0x74b4, 0x74b5, 0x74b6, 0x74b7, 
+    0x74b8, 0x74b9, 0x74ba, 0x74bb, 0x74bc, 0x74bd, 0x74be, 0x74bf, 
+    0x74c0, 0x74c1, 0x74c2, 0x74c3, 0x74c4, 0x74c5, 0x74c6, 0x74c7, 
+    0x74c8, 0x74c9, 0x74ca, 0x74cb, 0x74cc, 0x74cd, 0x74ce, 0x74cf, 
+    0x74d0, 0x74d1, 0x74d2, 0x74d3, 0x74d4, 0x74d5, 0x74d6, 0x74d7, 
+    0x74d8, 0x74d9, 0x74da, 0x74db, 0x74dc, 0x74dd, 0x74de, 0x74df, 
+    0x74e0, 0x74e1, 0x74e2, 0x74e3, 0x74e4, 0x74e5, 0x74e6, 0x74e7, 
+    0x74e8, 0x74e9, 0x74ea, 0x74eb, 0x74ec, 0x74ed, 0x74ee, 0x74ef, 
+    0x74f0, 0x74f1, 0x74f2, 0x74f3, 0x74f4, 0x74f5, 0x74f6, 0x74f7, 
+    0x74f8, 0x74f9, 0x74fa, 0x74fb, 0x74fc, 0x74fd, 0x74fe, 0x74ff, 
+    0x7500, 0x7501, 0x7502, 0x7503, 0x7504, 0x7505, 0x7506, 0x7507, 
+    0x7508, 0x7509, 0x750a, 0x750b, 0x750c, 0x750d, 0x750e, 0x750f, 
+    0x7510, 0x7511, 0x7512, 0x7513, 0x7514, 0x7515, 0x7516, 0x7517, 
+    0x7518, 0x7519, 0x751a, 0x751b, 0x751c, 0x751d, 0x751e, 0x751f, 
+    0x7520, 0x7521, 0x7522, 0x7523, 0x7524, 0x7525, 0x7526, 0x7527, 
+    0x7528, 0x7529, 0x752a, 0x752b, 0x752c, 0x752d, 0x752e, 0x752f, 
+    0x7530, 0x7531, 0x7532, 0x7533, 0x7534, 0x7535, 0x7536, 0x7537, 
+    0x7538, 0x7539, 0x753a, 0x753b, 0x753c, 0x753d, 0x753e, 0x753f, 
+    0x7540, 0x7541, 0x7542, 0x7543, 0x7544, 0x7545, 0x7546, 0x7547, 
+    0x7548, 0x7549, 0x754a, 0x754b, 0x754c, 0x754d, 0x754e, 0x754f, 
+    0x7550, 0x7551, 0x7552, 0x7553, 0x7554, 0x7555, 0x7556, 0x7557, 
+    0x7558, 0x7559, 0x755a, 0x755b, 0x755c, 0x755d, 0x755e, 0x755f, 
+    0x7560, 0x7561, 0x7562, 0x7563, 0x7564, 0x7565, 0x7566, 0x7567, 
+    0x7568, 0x7569, 0x756a, 0x756b, 0x756c, 0x756d, 0x756e, 0x756f, 
+    0x7570, 0x7571, 0x7572, 0x7573, 0x7574, 0x7575, 0x7576, 0x7577, 
+    0x7578, 0x7579, 0x757a, 0x757b, 0x757c, 0x757d, 0x757e, 0x757f, 
+    0x7580, 0x7581, 0x7582, 0x7583, 0x7584, 0x7585, 0x7586, 0x7587, 
+    0x7588, 0x7589, 0x758a, 0x758b, 0x758c, 0x758d, 0x758e, 0x758f, 
+    0x7590, 0x7591, 0x7592, 0x7593, 0x7594, 0x7595, 0x7596, 0x7597, 
+    0x7598, 0x7599, 0x759a, 0x759b, 0x759c, 0x759d, 0x759e, 0x759f, 
+    0x75a0, 0x75a1, 0x75a2, 0x75a3, 0x75a4, 0x75a5, 0x75a6, 0x75a7, 
+    0x75a8, 0x75a9, 0x75aa, 0x75ab, 0x75ac, 0x75ad, 0x75ae, 0x75af, 
+    0x75b0, 0x75b1, 0x75b2, 0x75b3, 0x75b4, 0x75b5, 0x75b6, 0x75b7, 
+    0x75b8, 0x75b9, 0x75ba, 0x75bb, 0x75bc, 0x75bd, 0x75be, 0x75bf, 
+    0x75c0, 0x75c1, 0x75c2, 0x75c3, 0x75c4, 0x75c5, 0x75c6, 0x75c7, 
+    0x75c8, 0x75c9, 0x75ca, 0x75cb, 0x75cc, 0x75cd, 0x75ce, 0x75cf, 
+    0x75d0, 0x75d1, 0x75d2, 0x75d3, 0x75d4, 0x75d5, 0x75d6, 0x75d7, 
+    0x75d8, 0x75d9, 0x75da, 0x75db, 0x75dc, 0x75dd, 0x75de, 0x75df, 
+    0x75e0, 0x75e1, 0x75e2, 0x75e3, 0x75e4, 0x75e5, 0x75e6, 0x75e7, 
+    0x75e8, 0x75e9, 0x75ea, 0x75eb, 0x75ec, 0x75ed, 0x75ee, 0x75ef, 
+    0x75f0, 0x75f1, 0x75f2, 0x75f3, 0x75f4, 0x75f5, 0x75f6, 0x75f7, 
+    0x75f8, 0x75f9, 0x75fa, 0x75fb, 0x75fc, 0x75fd, 0x75fe, 0x75ff, 
+    0x7600, 0x7601, 0x7602, 0x7603, 0x7604, 0x7605, 0x7606, 0x7607, 
+    0x7608, 0x7609, 0x760a, 0x760b, 0x760c, 0x760d, 0x760e, 0x760f, 
+    0x7610, 0x7611, 0x7612, 0x7613, 0x7614, 0x7615, 0x7616, 0x7617, 
+    0x7618, 0x7619, 0x761a, 0x761b, 0x761c, 0x761d, 0x761e, 0x761f, 
+    0x7620, 0x7621, 0x7622, 0x7623, 0x7624, 0x7625, 0x7626, 0x7627, 
+    0x7628, 0x7629, 0x762a, 0x762b, 0x762c, 0x762d, 0x762e, 0x762f, 
+    0x7630, 0x7631, 0x7632, 0x7633, 0x7634, 0x7635, 0x7636, 0x7637, 
+    0x7638, 0x7639, 0x763a, 0x763b, 0x763c, 0x763d, 0x763e, 0x763f, 
+    0x7640, 0x7641, 0x7642, 0x7643, 0x7644, 0x7645, 0x7646, 0x7647, 
+    0x7648, 0x7649, 0x764a, 0x764b, 0x764c, 0x764d, 0x764e, 0x764f, 
+    0x7650, 0x7651, 0x7652, 0x7653, 0x7654, 0x7655, 0x7656, 0x7657, 
+    0x7658, 0x7659, 0x765a, 0x765b, 0x765c, 0x765d, 0x765e, 0x765f, 
+    0x7660, 0x7661, 0x7662, 0x7663, 0x7664, 0x7665, 0x7666, 0x7667, 
+    0x7668, 0x7669, 0x766a, 0x766b, 0x766c, 0x766d, 0x766e, 0x766f, 
+    0x7670, 0x7671, 0x7672, 0x7673, 0x7674, 0x7675, 0x7676, 0x7677, 
+    0x7678, 0x7679, 0x767a, 0x767b, 0x767c, 0x767d, 0x767e, 0x767f, 
+    0x7680, 0x7681, 0x7682, 0x7683, 0x7684, 0x7685, 0x7686, 0x7687, 
+    0x7688, 0x7689, 0x768a, 0x768b, 0x768c, 0x768d, 0x768e, 0x768f, 
+    0x7690, 0x7691, 0x7692, 0x7693, 0x7694, 0x7695, 0x7696, 0x7697, 
+    0x7698, 0x7699, 0x769a, 0x769b, 0x769c, 0x769d, 0x769e, 0x769f, 
+    0x76a0, 0x76a1, 0x76a2, 0x76a3, 0x76a4, 0x76a5, 0x76a6, 0x76a7, 
+    0x76a8, 0x76a9, 0x76aa, 0x76ab, 0x76ac, 0x76ad, 0x76ae, 0x76af, 
+    0x76b0, 0x76b1, 0x76b2, 0x76b3, 0x76b4, 0x76b5, 0x76b6, 0x76b7, 
+    0x76b8, 0x76b9, 0x76ba, 0x76bb, 0x76bc, 0x76bd, 0x76be, 0x76bf, 
+    0x76c0, 0x76c1, 0x76c2, 0x76c3, 0x76c4, 0x76c5, 0x76c6, 0x76c7, 
+    0x76c8, 0x76c9, 0x76ca, 0x76cb, 0x76cc, 0x76cd, 0x76ce, 0x76cf, 
+    0x76d0, 0x76d1, 0x76d2, 0x76d3, 0x76d4, 0x76d5, 0x76d6, 0x76d7, 
+    0x76d8, 0x76d9, 0x76da, 0x76db, 0x76dc, 0x76dd, 0x76de, 0x76df, 
+    0x76e0, 0x76e1, 0x76e2, 0x76e3, 0x76e4, 0x76e5, 0x76e6, 0x76e7, 
+    0x76e8, 0x76e9, 0x76ea, 0x76eb, 0x76ec, 0x76ed, 0x76ee, 0x76ef, 
+    0x76f0, 0x76f1, 0x76f2, 0x76f3, 0x76f4, 0x76f5, 0x76f6, 0x76f7, 
+    0x76f8, 0x76f9, 0x76fa, 0x76fb, 0x76fc, 0x76fd, 0x76fe, 0x76ff, 
+    0x7700, 0x7701, 0x7702, 0x7703, 0x7704, 0x7705, 0x7706, 0x7707, 
+    0x7708, 0x7709, 0x770a, 0x770b, 0x770c, 0x770d, 0x770e, 0x770f, 
+    0x7710, 0x7711, 0x7712, 0x7713, 0x7714, 0x7715, 0x7716, 0x7717, 
+    0x7718, 0x7719, 0x771a, 0x771b, 0x771c, 0x771d, 0x771e, 0x771f, 
+    0x7720, 0x7721, 0x7722, 0x7723, 0x7724, 0x7725, 0x7726, 0x7727, 
+    0x7728, 0x7729, 0x772a, 0x772b, 0x772c, 0x772d, 0x772e, 0x772f, 
+    0x7730, 0x7731, 0x7732, 0x7733, 0x7734, 0x7735, 0x7736, 0x7737, 
+    0x7738, 0x7739, 0x773a, 0x773b, 0x773c, 0x773d, 0x773e, 0x773f, 
+    0x7740, 0x7741, 0x7742, 0x7743, 0x7744, 0x7745, 0x7746, 0x7747, 
+    0x7748, 0x7749, 0x774a, 0x774b, 0x774c, 0x774d, 0x774e, 0x774f, 
+    0x7750, 0x7751, 0x7752, 0x7753, 0x7754, 0x7755, 0x7756, 0x7757, 
+    0x7758, 0x7759, 0x775a, 0x775b, 0x775c, 0x775d, 0x775e, 0x775f, 
+    0x7760, 0x7761, 0x7762, 0x7763, 0x7764, 0x7765, 0x7766, 0x7767, 
+    0x7768, 0x7769, 0x776a, 0x776b, 0x776c, 0x776d, 0x776e, 0x776f, 
+    0x7770, 0x7771, 0x7772, 0x7773, 0x7774, 0x7775, 0x7776, 0x7777, 
+    0x7778, 0x7779, 0x777a, 0x777b, 0x777c, 0x777d, 0x777e, 0x777f, 
+    0x7780, 0x7781, 0x7782, 0x7783, 0x7784, 0x7785, 0x7786, 0x7787, 
+    0x7788, 0x7789, 0x778a, 0x778b, 0x778c, 0x778d, 0x778e, 0x778f, 
+    0x7790, 0x7791, 0x7792, 0x7793, 0x7794, 0x7795, 0x7796, 0x7797, 
+    0x7798, 0x7799, 0x779a, 0x779b, 0x779c, 0x779d, 0x779e, 0x779f, 
+    0x77a0, 0x77a1, 0x77a2, 0x77a3, 0x77a4, 0x77a5, 0x77a6, 0x77a7, 
+    0x77a8, 0x77a9, 0x77aa, 0x77ab, 0x77ac, 0x77ad, 0x77ae, 0x77af, 
+    0x77b0, 0x77b1, 0x77b2, 0x77b3, 0x77b4, 0x77b5, 0x77b6, 0x77b7, 
+    0x77b8, 0x77b9, 0x77ba, 0x77bb, 0x77bc, 0x77bd, 0x77be, 0x77bf, 
+    0x77c0, 0x77c1, 0x77c2, 0x77c3, 0x77c4, 0x77c5, 0x77c6, 0x77c7, 
+    0x77c8, 0x77c9, 0x77ca, 0x77cb, 0x77cc, 0x77cd, 0x77ce, 0x77cf, 
+    0x77d0, 0x77d1, 0x77d2, 0x77d3, 0x77d4, 0x77d5, 0x77d6, 0x77d7, 
+    0x77d8, 0x77d9, 0x77da, 0x77db, 0x77dc, 0x77dd, 0x77de, 0x77df, 
+    0x77e0, 0x77e1, 0x77e2, 0x77e3, 0x77e4, 0x77e5, 0x77e6, 0x77e7, 
+    0x77e8, 0x77e9, 0x77ea, 0x77eb, 0x77ec, 0x77ed, 0x77ee, 0x77ef, 
+    0x77f0, 0x77f1, 0x77f2, 0x77f3, 0x77f4, 0x77f5, 0x77f6, 0x77f7, 
+    0x77f8, 0x77f9, 0x77fa, 0x77fb, 0x77fc, 0x77fd, 0x77fe, 0x77ff, 
+    0x7800, 0x7801, 0x7802, 0x7803, 0x7804, 0x7805, 0x7806, 0x7807, 
+    0x7808, 0x7809, 0x780a, 0x780b, 0x780c, 0x780d, 0x780e, 0x780f, 
+    0x7810, 0x7811, 0x7812, 0x7813, 0x7814, 0x7815, 0x7816, 0x7817, 
+    0x7818, 0x7819, 0x781a, 0x781b, 0x781c, 0x781d, 0x781e, 0x781f, 
+    0x7820, 0x7821, 0x7822, 0x7823, 0x7824, 0x7825, 0x7826, 0x7827, 
+    0x7828, 0x7829, 0x782a, 0x782b, 0x782c, 0x782d, 0x782e, 0x782f, 
+    0x7830, 0x7831, 0x7832, 0x7833, 0x7834, 0x7835, 0x7836, 0x7837, 
+    0x7838, 0x7839, 0x783a, 0x783b, 0x783c, 0x783d, 0x783e, 0x783f, 
+    0x7840, 0x7841, 0x7842, 0x7843, 0x7844, 0x7845, 0x7846, 0x7847, 
+    0x7848, 0x7849, 0x784a, 0x784b, 0x784c, 0x784d, 0x784e, 0x784f, 
+    0x7850, 0x7851, 0x7852, 0x7853, 0x7854, 0x7855, 0x7856, 0x7857, 
+    0x7858, 0x7859, 0x785a, 0x785b, 0x785c, 0x785d, 0x785e, 0x785f, 
+    0x7860, 0x7861, 0x7862, 0x7863, 0x7864, 0x7865, 0x7866, 0x7867, 
+    0x7868, 0x7869, 0x786a, 0x786b, 0x786c, 0x786d, 0x786e, 0x786f, 
+    0x7870, 0x7871, 0x7872, 0x7873, 0x7874, 0x7875, 0x7876, 0x7877, 
+    0x7878, 0x7879, 0x787a, 0x787b, 0x787c, 0x787d, 0x787e, 0x787f, 
+    0x7880, 0x7881, 0x7882, 0x7883, 0x7884, 0x7885, 0x7886, 0x7887, 
+    0x7888, 0x7889, 0x788a, 0x788b, 0x788c, 0x788d, 0x788e, 0x788f, 
+    0x7890, 0x7891, 0x7892, 0x7893, 0x7894, 0x7895, 0x7896, 0x7897, 
+    0x7898, 0x7899, 0x789a, 0x789b, 0x789c, 0x789d, 0x789e, 0x789f, 
+    0x78a0, 0x78a1, 0x78a2, 0x78a3, 0x78a4, 0x78a5, 0x78a6, 0x78a7, 
+    0x78a8, 0x78a9, 0x78aa, 0x78ab, 0x78ac, 0x78ad, 0x78ae, 0x78af, 
+    0x78b0, 0x78b1, 0x78b2, 0x78b3, 0x78b4, 0x78b5, 0x78b6, 0x78b7, 
+    0x78b8, 0x78b9, 0x78ba, 0x78bb, 0x78bc, 0x78bd, 0x78be, 0x78bf, 
+    0x78c0, 0x78c1, 0x78c2, 0x78c3, 0x78c4, 0x78c5, 0x78c6, 0x78c7, 
+    0x78c8, 0x78c9, 0x78ca, 0x78cb, 0x78cc, 0x78cd, 0x78ce, 0x78cf, 
+    0x78d0, 0x78d1, 0x78d2, 0x78d3, 0x78d4, 0x78d5, 0x78d6, 0x78d7, 
+    0x78d8, 0x78d9, 0x78da, 0x78db, 0x78dc, 0x78dd, 0x78de, 0x78df, 
+    0x78e0, 0x78e1, 0x78e2, 0x78e3, 0x78e4, 0x78e5, 0x78e6, 0x78e7, 
+    0x78e8, 0x78e9, 0x78ea, 0x78eb, 0x78ec, 0x78ed, 0x78ee, 0x78ef, 
+    0x78f0, 0x78f1, 0x78f2, 0x78f3, 0x78f4, 0x78f5, 0x78f6, 0x78f7, 
+    0x78f8, 0x78f9, 0x78fa, 0x78fb, 0x78fc, 0x78fd, 0x78fe, 0x78ff, 
+    0x7900, 0x7901, 0x7902, 0x7903, 0x7904, 0x7905, 0x7906, 0x7907, 
+    0x7908, 0x7909, 0x790a, 0x790b, 0x790c, 0x790d, 0x790e, 0x790f, 
+    0x7910, 0x7911, 0x7912, 0x7913, 0x7914, 0x7915, 0x7916, 0x7917, 
+    0x7918, 0x7919, 0x791a, 0x791b, 0x791c, 0x791d, 0x791e, 0x791f, 
+    0x7920, 0x7921, 0x7922, 0x7923, 0x7924, 0x7925, 0x7926, 0x7927, 
+    0x7928, 0x7929, 0x792a, 0x792b, 0x792c, 0x792d, 0x792e, 0x792f, 
+    0x7930, 0x7931, 0x7932, 0x7933, 0x7934, 0x7935, 0x7936, 0x7937, 
+    0x7938, 0x7939, 0x793a, 0x793b, 0x793c, 0x793d, 0x793e, 0x793f, 
+    0x7940, 0x7941, 0x7942, 0x7943, 0x7944, 0x7945, 0x7946, 0x7947, 
+    0x7948, 0x7949, 0x794a, 0x794b, 0x794c, 0x794d, 0x794e, 0x794f, 
+    0x7950, 0x7951, 0x7952, 0x7953, 0x7954, 0x7955, 0x7956, 0x7957, 
+    0x7958, 0x7959, 0x795a, 0x795b, 0x795c, 0x795d, 0x795e, 0x795f, 
+    0x7960, 0x7961, 0x7962, 0x7963, 0x7964, 0x7965, 0x7966, 0x7967, 
+    0x7968, 0x7969, 0x796a, 0x796b, 0x796c, 0x796d, 0x796e, 0x796f, 
+    0x7970, 0x7971, 0x7972, 0x7973, 0x7974, 0x7975, 0x7976, 0x7977, 
+    0x7978, 0x7979, 0x797a, 0x797b, 0x797c, 0x797d, 0x797e, 0x797f, 
+    0x7980, 0x7981, 0x7982, 0x7983, 0x7984, 0x7985, 0x7986, 0x7987, 
+    0x7988, 0x7989, 0x798a, 0x798b, 0x798c, 0x798d, 0x798e, 0x798f, 
+    0x7990, 0x7991, 0x7992, 0x7993, 0x7994, 0x7995, 0x7996, 0x7997, 
+    0x7998, 0x7999, 0x799a, 0x799b, 0x799c, 0x799d, 0x799e, 0x799f, 
+    0x79a0, 0x79a1, 0x79a2, 0x79a3, 0x79a4, 0x79a5, 0x79a6, 0x79a7, 
+    0x79a8, 0x79a9, 0x79aa, 0x79ab, 0x79ac, 0x79ad, 0x79ae, 0x79af, 
+    0x79b0, 0x79b1, 0x79b2, 0x79b3, 0x79b4, 0x79b5, 0x79b6, 0x79b7, 
+    0x79b8, 0x79b9, 0x79ba, 0x79bb, 0x79bc, 0x79bd, 0x79be, 0x79bf, 
+    0x79c0, 0x79c1, 0x79c2, 0x79c3, 0x79c4, 0x79c5, 0x79c6, 0x79c7, 
+    0x79c8, 0x79c9, 0x79ca, 0x79cb, 0x79cc, 0x79cd, 0x79ce, 0x79cf, 
+    0x79d0, 0x79d1, 0x79d2, 0x79d3, 0x79d4, 0x79d5, 0x79d6, 0x79d7, 
+    0x79d8, 0x79d9, 0x79da, 0x79db, 0x79dc, 0x79dd, 0x79de, 0x79df, 
+    0x79e0, 0x79e1, 0x79e2, 0x79e3, 0x79e4, 0x79e5, 0x79e6, 0x79e7, 
+    0x79e8, 0x79e9, 0x79ea, 0x79eb, 0x79ec, 0x79ed, 0x79ee, 0x79ef, 
+    0x79f0, 0x79f1, 0x79f2, 0x79f3, 0x79f4, 0x79f5, 0x79f6, 0x79f7, 
+    0x79f8, 0x79f9, 0x79fa, 0x79fb, 0x79fc, 0x79fd, 0x79fe, 0x79ff, 
+    0x7a00, 0x7a01, 0x7a02, 0x7a03, 0x7a04, 0x7a05, 0x7a06, 0x7a07, 
+    0x7a08, 0x7a09, 0x7a0a, 0x7a0b, 0x7a0c, 0x7a0d, 0x7a0e, 0x7a0f, 
+    0x7a10, 0x7a11, 0x7a12, 0x7a13, 0x7a14, 0x7a15, 0x7a16, 0x7a17, 
+    0x7a18, 0x7a19, 0x7a1a, 0x7a1b, 0x7a1c, 0x7a1d, 0x7a1e, 0x7a1f, 
+    0x7a20, 0x7a21, 0x7a22, 0x7a23, 0x7a24, 0x7a25, 0x7a26, 0x7a27, 
+    0x7a28, 0x7a29, 0x7a2a, 0x7a2b, 0x7a2c, 0x7a2d, 0x7a2e, 0x7a2f, 
+    0x7a30, 0x7a31, 0x7a32, 0x7a33, 0x7a34, 0x7a35, 0x7a36, 0x7a37, 
+    0x7a38, 0x7a39, 0x7a3a, 0x7a3b, 0x7a3c, 0x7a3d, 0x7a3e, 0x7a3f, 
+    0x7a40, 0x7a41, 0x7a42, 0x7a43, 0x7a44, 0x7a45, 0x7a46, 0x7a47, 
+    0x7a48, 0x7a49, 0x7a4a, 0x7a4b, 0x7a4c, 0x7a4d, 0x7a4e, 0x7a4f, 
+    0x7a50, 0x7a51, 0x7a52, 0x7a53, 0x7a54, 0x7a55, 0x7a56, 0x7a57, 
+    0x7a58, 0x7a59, 0x7a5a, 0x7a5b, 0x7a5c, 0x7a5d, 0x7a5e, 0x7a5f, 
+    0x7a60, 0x7a61, 0x7a62, 0x7a63, 0x7a64, 0x7a65, 0x7a66, 0x7a67, 
+    0x7a68, 0x7a69, 0x7a6a, 0x7a6b, 0x7a6c, 0x7a6d, 0x7a6e, 0x7a6f, 
+    0x7a70, 0x7a71, 0x7a72, 0x7a73, 0x7a74, 0x7a75, 0x7a76, 0x7a77, 
+    0x7a78, 0x7a79, 0x7a7a, 0x7a7b, 0x7a7c, 0x7a7d, 0x7a7e, 0x7a7f, 
+    0x7a80, 0x7a81, 0x7a82, 0x7a83, 0x7a84, 0x7a85, 0x7a86, 0x7a87, 
+    0x7a88, 0x7a89, 0x7a8a, 0x7a8b, 0x7a8c, 0x7a8d, 0x7a8e, 0x7a8f, 
+    0x7a90, 0x7a91, 0x7a92, 0x7a93, 0x7a94, 0x7a95, 0x7a96, 0x7a97, 
+    0x7a98, 0x7a99, 0x7a9a, 0x7a9b, 0x7a9c, 0x7a9d, 0x7a9e, 0x7a9f, 
+    0x7aa0, 0x7aa1, 0x7aa2, 0x7aa3, 0x7aa4, 0x7aa5, 0x7aa6, 0x7aa7, 
+    0x7aa8, 0x7aa9, 0x7aaa, 0x7aab, 0x7aac, 0x7aad, 0x7aae, 0x7aaf, 
+    0x7ab0, 0x7ab1, 0x7ab2, 0x7ab3, 0x7ab4, 0x7ab5, 0x7ab6, 0x7ab7, 
+    0x7ab8, 0x7ab9, 0x7aba, 0x7abb, 0x7abc, 0x7abd, 0x7abe, 0x7abf, 
+    0x7ac0, 0x7ac1, 0x7ac2, 0x7ac3, 0x7ac4, 0x7ac5, 0x7ac6, 0x7ac7, 
+    0x7ac8, 0x7ac9, 0x7aca, 0x7acb, 0x7acc, 0x7acd, 0x7ace, 0x7acf, 
+    0x7ad0, 0x7ad1, 0x7ad2, 0x7ad3, 0x7ad4, 0x7ad5, 0x7ad6, 0x7ad7, 
+    0x7ad8, 0x7ad9, 0x7ada, 0x7adb, 0x7adc, 0x7add, 0x7ade, 0x7adf, 
+    0x7ae0, 0x7ae1, 0x7ae2, 0x7ae3, 0x7ae4, 0x7ae5, 0x7ae6, 0x7ae7, 
+    0x7ae8, 0x7ae9, 0x7aea, 0x7aeb, 0x7aec, 0x7aed, 0x7aee, 0x7aef, 
+    0x7af0, 0x7af1, 0x7af2, 0x7af3, 0x7af4, 0x7af5, 0x7af6, 0x7af7, 
+    0x7af8, 0x7af9, 0x7afa, 0x7afb, 0x7afc, 0x7afd, 0x7afe, 0x7aff, 
+    0x7b00, 0x7b01, 0x7b02, 0x7b03, 0x7b04, 0x7b05, 0x7b06, 0x7b07, 
+    0x7b08, 0x7b09, 0x7b0a, 0x7b0b, 0x7b0c, 0x7b0d, 0x7b0e, 0x7b0f, 
+    0x7b10, 0x7b11, 0x7b12, 0x7b13, 0x7b14, 0x7b15, 0x7b16, 0x7b17, 
+    0x7b18, 0x7b19, 0x7b1a, 0x7b1b, 0x7b1c, 0x7b1d, 0x7b1e, 0x7b1f, 
+    0x7b20, 0x7b21, 0x7b22, 0x7b23, 0x7b24, 0x7b25, 0x7b26, 0x7b27, 
+    0x7b28, 0x7b29, 0x7b2a, 0x7b2b, 0x7b2c, 0x7b2d, 0x7b2e, 0x7b2f, 
+    0x7b30, 0x7b31, 0x7b32, 0x7b33, 0x7b34, 0x7b35, 0x7b36, 0x7b37, 
+    0x7b38, 0x7b39, 0x7b3a, 0x7b3b, 0x7b3c, 0x7b3d, 0x7b3e, 0x7b3f, 
+    0x7b40, 0x7b41, 0x7b42, 0x7b43, 0x7b44, 0x7b45, 0x7b46, 0x7b47, 
+    0x7b48, 0x7b49, 0x7b4a, 0x7b4b, 0x7b4c, 0x7b4d, 0x7b4e, 0x7b4f, 
+    0x7b50, 0x7b51, 0x7b52, 0x7b53, 0x7b54, 0x7b55, 0x7b56, 0x7b57, 
+    0x7b58, 0x7b59, 0x7b5a, 0x7b5b, 0x7b5c, 0x7b5d, 0x7b5e, 0x7b5f, 
+    0x7b60, 0x7b61, 0x7b62, 0x7b63, 0x7b64, 0x7b65, 0x7b66, 0x7b67, 
+    0x7b68, 0x7b69, 0x7b6a, 0x7b6b, 0x7b6c, 0x7b6d, 0x7b6e, 0x7b6f, 
+    0x7b70, 0x7b71, 0x7b72, 0x7b73, 0x7b74, 0x7b75, 0x7b76, 0x7b77, 
+    0x7b78, 0x7b79, 0x7b7a, 0x7b7b, 0x7b7c, 0x7b7d, 0x7b7e, 0x7b7f, 
+    0x7b80, 0x7b81, 0x7b82, 0x7b83, 0x7b84, 0x7b85, 0x7b86, 0x7b87, 
+    0x7b88, 0x7b89, 0x7b8a, 0x7b8b, 0x7b8c, 0x7b8d, 0x7b8e, 0x7b8f, 
+    0x7b90, 0x7b91, 0x7b92, 0x7b93, 0x7b94, 0x7b95, 0x7b96, 0x7b97, 
+    0x7b98, 0x7b99, 0x7b9a, 0x7b9b, 0x7b9c, 0x7b9d, 0x7b9e, 0x7b9f, 
+    0x7ba0, 0x7ba1, 0x7ba2, 0x7ba3, 0x7ba4, 0x7ba5, 0x7ba6, 0x7ba7, 
+    0x7ba8, 0x7ba9, 0x7baa, 0x7bab, 0x7bac, 0x7bad, 0x7bae, 0x7baf, 
+    0x7bb0, 0x7bb1, 0x7bb2, 0x7bb3, 0x7bb4, 0x7bb5, 0x7bb6, 0x7bb7, 
+    0x7bb8, 0x7bb9, 0x7bba, 0x7bbb, 0x7bbc, 0x7bbd, 0x7bbe, 0x7bbf, 
+    0x7bc0, 0x7bc1, 0x7bc2, 0x7bc3, 0x7bc4, 0x7bc5, 0x7bc6, 0x7bc7, 
+    0x7bc8, 0x7bc9, 0x7bca, 0x7bcb, 0x7bcc, 0x7bcd, 0x7bce, 0x7bcf, 
+    0x7bd0, 0x7bd1, 0x7bd2, 0x7bd3, 0x7bd4, 0x7bd5, 0x7bd6, 0x7bd7, 
+    0x7bd8, 0x7bd9, 0x7bda, 0x7bdb, 0x7bdc, 0x7bdd, 0x7bde, 0x7bdf, 
+    0x7be0, 0x7be1, 0x7be2, 0x7be3, 0x7be4, 0x7be5, 0x7be6, 0x7be7, 
+    0x7be8, 0x7be9, 0x7bea, 0x7beb, 0x7bec, 0x7bed, 0x7bee, 0x7bef, 
+    0x7bf0, 0x7bf1, 0x7bf2, 0x7bf3, 0x7bf4, 0x7bf5, 0x7bf6, 0x7bf7, 
+    0x7bf8, 0x7bf9, 0x7bfa, 0x7bfb, 0x7bfc, 0x7bfd, 0x7bfe, 0x7bff, 
+    0x7c00, 0x7c01, 0x7c02, 0x7c03, 0x7c04, 0x7c05, 0x7c06, 0x7c07, 
+    0x7c08, 0x7c09, 0x7c0a, 0x7c0b, 0x7c0c, 0x7c0d, 0x7c0e, 0x7c0f, 
+    0x7c10, 0x7c11, 0x7c12, 0x7c13, 0x7c14, 0x7c15, 0x7c16, 0x7c17, 
+    0x7c18, 0x7c19, 0x7c1a, 0x7c1b, 0x7c1c, 0x7c1d, 0x7c1e, 0x7c1f, 
+    0x7c20, 0x7c21, 0x7c22, 0x7c23, 0x7c24, 0x7c25, 0x7c26, 0x7c27, 
+    0x7c28, 0x7c29, 0x7c2a, 0x7c2b, 0x7c2c, 0x7c2d, 0x7c2e, 0x7c2f, 
+    0x7c30, 0x7c31, 0x7c32, 0x7c33, 0x7c34, 0x7c35, 0x7c36, 0x7c37, 
+    0x7c38, 0x7c39, 0x7c3a, 0x7c3b, 0x7c3c, 0x7c3d, 0x7c3e, 0x7c3f, 
+    0x7c40, 0x7c41, 0x7c42, 0x7c43, 0x7c44, 0x7c45, 0x7c46, 0x7c47, 
+    0x7c48, 0x7c49, 0x7c4a, 0x7c4b, 0x7c4c, 0x7c4d, 0x7c4e, 0x7c4f, 
+    0x7c50, 0x7c51, 0x7c52, 0x7c53, 0x7c54, 0x7c55, 0x7c56, 0x7c57, 
+    0x7c58, 0x7c59, 0x7c5a, 0x7c5b, 0x7c5c, 0x7c5d, 0x7c5e, 0x7c5f, 
+    0x7c60, 0x7c61, 0x7c62, 0x7c63, 0x7c64, 0x7c65, 0x7c66, 0x7c67, 
+    0x7c68, 0x7c69, 0x7c6a, 0x7c6b, 0x7c6c, 0x7c6d, 0x7c6e, 0x7c6f, 
+    0x7c70, 0x7c71, 0x7c72, 0x7c73, 0x7c74, 0x7c75, 0x7c76, 0x7c77, 
+    0x7c78, 0x7c79, 0x7c7a, 0x7c7b, 0x7c7c, 0x7c7d, 0x7c7e, 0x7c7f, 
+    0x7c80, 0x7c81, 0x7c82, 0x7c83, 0x7c84, 0x7c85, 0x7c86, 0x7c87, 
+    0x7c88, 0x7c89, 0x7c8a, 0x7c8b, 0x7c8c, 0x7c8d, 0x7c8e, 0x7c8f, 
+    0x7c90, 0x7c91, 0x7c92, 0x7c93, 0x7c94, 0x7c95, 0x7c96, 0x7c97, 
+    0x7c98, 0x7c99, 0x7c9a, 0x7c9b, 0x7c9c, 0x7c9d, 0x7c9e, 0x7c9f, 
+    0x7ca0, 0x7ca1, 0x7ca2, 0x7ca3, 0x7ca4, 0x7ca5, 0x7ca6, 0x7ca7, 
+    0x7ca8, 0x7ca9, 0x7caa, 0x7cab, 0x7cac, 0x7cad, 0x7cae, 0x7caf, 
+    0x7cb0, 0x7cb1, 0x7cb2, 0x7cb3, 0x7cb4, 0x7cb5, 0x7cb6, 0x7cb7, 
+    0x7cb8, 0x7cb9, 0x7cba, 0x7cbb, 0x7cbc, 0x7cbd, 0x7cbe, 0x7cbf, 
+    0x7cc0, 0x7cc1, 0x7cc2, 0x7cc3, 0x7cc4, 0x7cc5, 0x7cc6, 0x7cc7, 
+    0x7cc8, 0x7cc9, 0x7cca, 0x7ccb, 0x7ccc, 0x7ccd, 0x7cce, 0x7ccf, 
+    0x7cd0, 0x7cd1, 0x7cd2, 0x7cd3, 0x7cd4, 0x7cd5, 0x7cd6, 0x7cd7, 
+    0x7cd8, 0x7cd9, 0x7cda, 0x7cdb, 0x7cdc, 0x7cdd, 0x7cde, 0x7cdf, 
+    0x7ce0, 0x7ce1, 0x7ce2, 0x7ce3, 0x7ce4, 0x7ce5, 0x7ce6, 0x7ce7, 
+    0x7ce8, 0x7ce9, 0x7cea, 0x7ceb, 0x7cec, 0x7ced, 0x7cee, 0x7cef, 
+    0x7cf0, 0x7cf1, 0x7cf2, 0x7cf3, 0x7cf4, 0x7cf5, 0x7cf6, 0x7cf7, 
+    0x7cf8, 0x7cf9, 0x7cfa, 0x7cfb, 0x7cfc, 0x7cfd, 0x7cfe, 0x7cff, 
+    0x7d00, 0x7d01, 0x7d02, 0x7d03, 0x7d04, 0x7d05, 0x7d06, 0x7d07, 
+    0x7d08, 0x7d09, 0x7d0a, 0x7d0b, 0x7d0c, 0x7d0d, 0x7d0e, 0x7d0f, 
+    0x7d10, 0x7d11, 0x7d12, 0x7d13, 0x7d14, 0x7d15, 0x7d16, 0x7d17, 
+    0x7d18, 0x7d19, 0x7d1a, 0x7d1b, 0x7d1c, 0x7d1d, 0x7d1e, 0x7d1f, 
+    0x7d20, 0x7d21, 0x7d22, 0x7d23, 0x7d24, 0x7d25, 0x7d26, 0x7d27, 
+    0x7d28, 0x7d29, 0x7d2a, 0x7d2b, 0x7d2c, 0x7d2d, 0x7d2e, 0x7d2f, 
+    0x7d30, 0x7d31, 0x7d32, 0x7d33, 0x7d34, 0x7d35, 0x7d36, 0x7d37, 
+    0x7d38, 0x7d39, 0x7d3a, 0x7d3b, 0x7d3c, 0x7d3d, 0x7d3e, 0x7d3f, 
+    0x7d40, 0x7d41, 0x7d42, 0x7d43, 0x7d44, 0x7d45, 0x7d46, 0x7d47, 
+    0x7d48, 0x7d49, 0x7d4a, 0x7d4b, 0x7d4c, 0x7d4d, 0x7d4e, 0x7d4f, 
+    0x7d50, 0x7d51, 0x7d52, 0x7d53, 0x7d54, 0x7d55, 0x7d56, 0x7d57, 
+    0x7d58, 0x7d59, 0x7d5a, 0x7d5b, 0x7d5c, 0x7d5d, 0x7d5e, 0x7d5f, 
+    0x7d60, 0x7d61, 0x7d62, 0x7d63, 0x7d64, 0x7d65, 0x7d66, 0x7d67, 
+    0x7d68, 0x7d69, 0x7d6a, 0x7d6b, 0x7d6c, 0x7d6d, 0x7d6e, 0x7d6f, 
+    0x7d70, 0x7d71, 0x7d72, 0x7d73, 0x7d74, 0x7d75, 0x7d76, 0x7d77, 
+    0x7d78, 0x7d79, 0x7d7a, 0x7d7b, 0x7d7c, 0x7d7d, 0x7d7e, 0x7d7f, 
+    0x7d80, 0x7d81, 0x7d82, 0x7d83, 0x7d84, 0x7d85, 0x7d86, 0x7d87, 
+    0x7d88, 0x7d89, 0x7d8a, 0x7d8b, 0x7d8c, 0x7d8d, 0x7d8e, 0x7d8f, 
+    0x7d90, 0x7d91, 0x7d92, 0x7d93, 0x7d94, 0x7d95, 0x7d96, 0x7d97, 
+    0x7d98, 0x7d99, 0x7d9a, 0x7d9b, 0x7d9c, 0x7d9d, 0x7d9e, 0x7d9f, 
+    0x7da0, 0x7da1, 0x7da2, 0x7da3, 0x7da4, 0x7da5, 0x7da6, 0x7da7, 
+    0x7da8, 0x7da9, 0x7daa, 0x7dab, 0x7dac, 0x7dad, 0x7dae, 0x7daf, 
+    0x7db0, 0x7db1, 0x7db2, 0x7db3, 0x7db4, 0x7db5, 0x7db6, 0x7db7, 
+    0x7db8, 0x7db9, 0x7dba, 0x7dbb, 0x7dbc, 0x7dbd, 0x7dbe, 0x7dbf, 
+    0x7dc0, 0x7dc1, 0x7dc2, 0x7dc3, 0x7dc4, 0x7dc5, 0x7dc6, 0x7dc7, 
+    0x7dc8, 0x7dc9, 0x7dca, 0x7dcb, 0x7dcc, 0x7dcd, 0x7dce, 0x7dcf, 
+    0x7dd0, 0x7dd1, 0x7dd2, 0x7dd3, 0x7dd4, 0x7dd5, 0x7dd6, 0x7dd7, 
+    0x7dd8, 0x7dd9, 0x7dda, 0x7ddb, 0x7ddc, 0x7ddd, 0x7dde, 0x7ddf, 
+    0x7de0, 0x7de1, 0x7de2, 0x7de3, 0x7de4, 0x7de5, 0x7de6, 0x7de7, 
+    0x7de8, 0x7de9, 0x7dea, 0x7deb, 0x7dec, 0x7ded, 0x7dee, 0x7def, 
+    0x7df0, 0x7df1, 0x7df2, 0x7df3, 0x7df4, 0x7df5, 0x7df6, 0x7df7, 
+    0x7df8, 0x7df9, 0x7dfa, 0x7dfb, 0x7dfc, 0x7dfd, 0x7dfe, 0x7dff, 
+    0x7e00, 0x7e01, 0x7e02, 0x7e03, 0x7e04, 0x7e05, 0x7e06, 0x7e07, 
+    0x7e08, 0x7e09, 0x7e0a, 0x7e0b, 0x7e0c, 0x7e0d, 0x7e0e, 0x7e0f, 
+    0x7e10, 0x7e11, 0x7e12, 0x7e13, 0x7e14, 0x7e15, 0x7e16, 0x7e17, 
+    0x7e18, 0x7e19, 0x7e1a, 0x7e1b, 0x7e1c, 0x7e1d, 0x7e1e, 0x7e1f, 
+    0x7e20, 0x7e21, 0x7e22, 0x7e23, 0x7e24, 0x7e25, 0x7e26, 0x7e27, 
+    0x7e28, 0x7e29, 0x7e2a, 0x7e2b, 0x7e2c, 0x7e2d, 0x7e2e, 0x7e2f, 
+    0x7e30, 0x7e31, 0x7e32, 0x7e33, 0x7e34, 0x7e35, 0x7e36, 0x7e37, 
+    0x7e38, 0x7e39, 0x7e3a, 0x7e3b, 0x7e3c, 0x7e3d, 0x7e3e, 0x7e3f, 
+    0x7e40, 0x7e41, 0x7e42, 0x7e43, 0x7e44, 0x7e45, 0x7e46, 0x7e47, 
+    0x7e48, 0x7e49, 0x7e4a, 0x7e4b, 0x7e4c, 0x7e4d, 0x7e4e, 0x7e4f, 
+    0x7e50, 0x7e51, 0x7e52, 0x7e53, 0x7e54, 0x7e55, 0x7e56, 0x7e57, 
+    0x7e58, 0x7e59, 0x7e5a, 0x7e5b, 0x7e5c, 0x7e5d, 0x7e5e, 0x7e5f, 
+    0x7e60, 0x7e61, 0x7e62, 0x7e63, 0x7e64, 0x7e65, 0x7e66, 0x7e67, 
+    0x7e68, 0x7e69, 0x7e6a, 0x7e6b, 0x7e6c, 0x7e6d, 0x7e6e, 0x7e6f, 
+    0x7e70, 0x7e71, 0x7e72, 0x7e73, 0x7e74, 0x7e75, 0x7e76, 0x7e77, 
+    0x7e78, 0x7e79, 0x7e7a, 0x7e7b, 0x7e7c, 0x7e7d, 0x7e7e, 0x7e7f, 
+    0x7e80, 0x7e81, 0x7e82, 0x7e83, 0x7e84, 0x7e85, 0x7e86, 0x7e87, 
+    0x7e88, 0x7e89, 0x7e8a, 0x7e8b, 0x7e8c, 0x7e8d, 0x7e8e, 0x7e8f, 
+    0x7e90, 0x7e91, 0x7e92, 0x7e93, 0x7e94, 0x7e95, 0x7e96, 0x7e97, 
+    0x7e98, 0x7e99, 0x7e9a, 0x7e9b, 0x7e9c, 0x7e9d, 0x7e9e, 0x7e9f, 
+    0x7ea0, 0x7ea1, 0x7ea2, 0x7ea3, 0x7ea4, 0x7ea5, 0x7ea6, 0x7ea7, 
+    0x7ea8, 0x7ea9, 0x7eaa, 0x7eab, 0x7eac, 0x7ead, 0x7eae, 0x7eaf, 
+    0x7eb0, 0x7eb1, 0x7eb2, 0x7eb3, 0x7eb4, 0x7eb5, 0x7eb6, 0x7eb7, 
+    0x7eb8, 0x7eb9, 0x7eba, 0x7ebb, 0x7ebc, 0x7ebd, 0x7ebe, 0x7ebf, 
+    0x7ec0, 0x7ec1, 0x7ec2, 0x7ec3, 0x7ec4, 0x7ec5, 0x7ec6, 0x7ec7, 
+    0x7ec8, 0x7ec9, 0x7eca, 0x7ecb, 0x7ecc, 0x7ecd, 0x7ece, 0x7ecf, 
+    0x7ed0, 0x7ed1, 0x7ed2, 0x7ed3, 0x7ed4, 0x7ed5, 0x7ed6, 0x7ed7, 
+    0x7ed8, 0x7ed9, 0x7eda, 0x7edb, 0x7edc, 0x7edd, 0x7ede, 0x7edf, 
+    0x7ee0, 0x7ee1, 0x7ee2, 0x7ee3, 0x7ee4, 0x7ee5, 0x7ee6, 0x7ee7, 
+    0x7ee8, 0x7ee9, 0x7eea, 0x7eeb, 0x7eec, 0x7eed, 0x7eee, 0x7eef, 
+    0x7ef0, 0x7ef1, 0x7ef2, 0x7ef3, 0x7ef4, 0x7ef5, 0x7ef6, 0x7ef7, 
+    0x7ef8, 0x7ef9, 0x7efa, 0x7efb, 0x7efc, 0x7efd, 0x7efe, 0x7eff, 
+    0x7f00, 0x7f01, 0x7f02, 0x7f03, 0x7f04, 0x7f05, 0x7f06, 0x7f07, 
+    0x7f08, 0x7f09, 0x7f0a, 0x7f0b, 0x7f0c, 0x7f0d, 0x7f0e, 0x7f0f, 
+    0x7f10, 0x7f11, 0x7f12, 0x7f13, 0x7f14, 0x7f15, 0x7f16, 0x7f17, 
+    0x7f18, 0x7f19, 0x7f1a, 0x7f1b, 0x7f1c, 0x7f1d, 0x7f1e, 0x7f1f, 
+    0x7f20, 0x7f21, 0x7f22, 0x7f23, 0x7f24, 0x7f25, 0x7f26, 0x7f27, 
+    0x7f28, 0x7f29, 0x7f2a, 0x7f2b, 0x7f2c, 0x7f2d, 0x7f2e, 0x7f2f, 
+    0x7f30, 0x7f31, 0x7f32, 0x7f33, 0x7f34, 0x7f35, 0x7f36, 0x7f37, 
+    0x7f38, 0x7f39, 0x7f3a, 0x7f3b, 0x7f3c, 0x7f3d, 0x7f3e, 0x7f3f, 
+    0x7f40, 0x7f41, 0x7f42, 0x7f43, 0x7f44, 0x7f45, 0x7f46, 0x7f47, 
+    0x7f48, 0x7f49, 0x7f4a, 0x7f4b, 0x7f4c, 0x7f4d, 0x7f4e, 0x7f4f, 
+    0x7f50, 0x7f51, 0x7f52, 0x7f53, 0x7f54, 0x7f55, 0x7f56, 0x7f57, 
+    0x7f58, 0x7f59, 0x7f5a, 0x7f5b, 0x7f5c, 0x7f5d, 0x7f5e, 0x7f5f, 
+    0x7f60, 0x7f61, 0x7f62, 0x7f63, 0x7f64, 0x7f65, 0x7f66, 0x7f67, 
+    0x7f68, 0x7f69, 0x7f6a, 0x7f6b, 0x7f6c, 0x7f6d, 0x7f6e, 0x7f6f, 
+    0x7f70, 0x7f71, 0x7f72, 0x7f73, 0x7f74, 0x7f75, 0x7f76, 0x7f77, 
+    0x7f78, 0x7f79, 0x7f7a, 0x7f7b, 0x7f7c, 0x7f7d, 0x7f7e, 0x7f7f, 
+    0x7f80, 0x7f81, 0x7f82, 0x7f83, 0x7f84, 0x7f85, 0x7f86, 0x7f87, 
+    0x7f88, 0x7f89, 0x7f8a, 0x7f8b, 0x7f8c, 0x7f8d, 0x7f8e, 0x7f8f, 
+    0x7f90, 0x7f91, 0x7f92, 0x7f93, 0x7f94, 0x7f95, 0x7f96, 0x7f97, 
+    0x7f98, 0x7f99, 0x7f9a, 0x7f9b, 0x7f9c, 0x7f9d, 0x7f9e, 0x7f9f, 
+    0x7fa0, 0x7fa1, 0x7fa2, 0x7fa3, 0x7fa4, 0x7fa5, 0x7fa6, 0x7fa7, 
+    0x7fa8, 0x7fa9, 0x7faa, 0x7fab, 0x7fac, 0x7fad, 0x7fae, 0x7faf, 
+    0x7fb0, 0x7fb1, 0x7fb2, 0x7fb3, 0x7fb4, 0x7fb5, 0x7fb6, 0x7fb7, 
+    0x7fb8, 0x7fb9, 0x7fba, 0x7fbb, 0x7fbc, 0x7fbd, 0x7fbe, 0x7fbf, 
+    0x7fc0, 0x7fc1, 0x7fc2, 0x7fc3, 0x7fc4, 0x7fc5, 0x7fc6, 0x7fc7, 
+    0x7fc8, 0x7fc9, 0x7fca, 0x7fcb, 0x7fcc, 0x7fcd, 0x7fce, 0x7fcf, 
+    0x7fd0, 0x7fd1, 0x7fd2, 0x7fd3, 0x7fd4, 0x7fd5, 0x7fd6, 0x7fd7, 
+    0x7fd8, 0x7fd9, 0x7fda, 0x7fdb, 0x7fdc, 0x7fdd, 0x7fde, 0x7fdf, 
+    0x7fe0, 0x7fe1, 0x7fe2, 0x7fe3, 0x7fe4, 0x7fe5, 0x7fe6, 0x7fe7, 
+    0x7fe8, 0x7fe9, 0x7fea, 0x7feb, 0x7fec, 0x7fed, 0x7fee, 0x7fef, 
+    0x7ff0, 0x7ff1, 0x7ff2, 0x7ff3, 0x7ff4, 0x7ff5, 0x7ff6, 0x7ff7, 
+    0x7ff8, 0x7ff9, 0x7ffa, 0x7ffb, 0x7ffc, 0x7ffd, 0x7ffe, 0x7fff, 
+    0x8000, 0x8001, 0x8002, 0x8003, 0x8004, 0x8005, 0x8006, 0x8007, 
+    0x8008, 0x8009, 0x800a, 0x800b, 0x800c, 0x800d, 0x800e, 0x800f, 
+    0x8010, 0x8011, 0x8012, 0x8013, 0x8014, 0x8015, 0x8016, 0x8017, 
+    0x8018, 0x8019, 0x801a, 0x801b, 0x801c, 0x801d, 0x801e, 0x801f, 
+    0x8020, 0x8021, 0x8022, 0x8023, 0x8024, 0x8025, 0x8026, 0x8027, 
+    0x8028, 0x8029, 0x802a, 0x802b, 0x802c, 0x802d, 0x802e, 0x802f, 
+    0x8030, 0x8031, 0x8032, 0x8033, 0x8034, 0x8035, 0x8036, 0x8037, 
+    0x8038, 0x8039, 0x803a, 0x803b, 0x803c, 0x803d, 0x803e, 0x803f, 
+    0x8040, 0x8041, 0x8042, 0x8043, 0x8044, 0x8045, 0x8046, 0x8047, 
+    0x8048, 0x8049, 0x804a, 0x804b, 0x804c, 0x804d, 0x804e, 0x804f, 
+    0x8050, 0x8051, 0x8052, 0x8053, 0x8054, 0x8055, 0x8056, 0x8057, 
+    0x8058, 0x8059, 0x805a, 0x805b, 0x805c, 0x805d, 0x805e, 0x805f, 
+    0x8060, 0x8061, 0x8062, 0x8063, 0x8064, 0x8065, 0x8066, 0x8067, 
+    0x8068, 0x8069, 0x806a, 0x806b, 0x806c, 0x806d, 0x806e, 0x806f, 
+    0x8070, 0x8071, 0x8072, 0x8073, 0x8074, 0x8075, 0x8076, 0x8077, 
+    0x8078, 0x8079, 0x807a, 0x807b, 0x807c, 0x807d, 0x807e, 0x807f, 
+    0x8080, 0x8081, 0x8082, 0x8083, 0x8084, 0x8085, 0x8086, 0x8087, 
+    0x8088, 0x8089, 0x808a, 0x808b, 0x808c, 0x808d, 0x808e, 0x808f, 
+    0x8090, 0x8091, 0x8092, 0x8093, 0x8094, 0x8095, 0x8096, 0x8097, 
+    0x8098, 0x8099, 0x809a, 0x809b, 0x809c, 0x809d, 0x809e, 0x809f, 
+    0x80a0, 0x80a1, 0x80a2, 0x80a3, 0x80a4, 0x80a5, 0x80a6, 0x80a7, 
+    0x80a8, 0x80a9, 0x80aa, 0x80ab, 0x80ac, 0x80ad, 0x80ae, 0x80af, 
+    0x80b0, 0x80b1, 0x80b2, 0x80b3, 0x80b4, 0x80b5, 0x80b6, 0x80b7, 
+    0x80b8, 0x80b9, 0x80ba, 0x80bb, 0x80bc, 0x80bd, 0x80be, 0x80bf, 
+    0x80c0, 0x80c1, 0x80c2, 0x80c3, 0x80c4, 0x80c5, 0x80c6, 0x80c7, 
+    0x80c8, 0x80c9, 0x80ca, 0x80cb, 0x80cc, 0x80cd, 0x80ce, 0x80cf, 
+    0x80d0, 0x80d1, 0x80d2, 0x80d3, 0x80d4, 0x80d5, 0x80d6, 0x80d7, 
+    0x80d8, 0x80d9, 0x80da, 0x80db, 0x80dc, 0x80dd, 0x80de, 0x80df, 
+    0x80e0, 0x80e1, 0x80e2, 0x80e3, 0x80e4, 0x80e5, 0x80e6, 0x80e7, 
+    0x80e8, 0x80e9, 0x80ea, 0x80eb, 0x80ec, 0x80ed, 0x80ee, 0x80ef, 
+    0x80f0, 0x80f1, 0x80f2, 0x80f3, 0x80f4, 0x80f5, 0x80f6, 0x80f7, 
+    0x80f8, 0x80f9, 0x80fa, 0x80fb, 0x80fc, 0x80fd, 0x80fe, 0x80ff, 
+    0x8100, 0x8101, 0x8102, 0x8103, 0x8104, 0x8105, 0x8106, 0x8107, 
+    0x8108, 0x8109, 0x810a, 0x810b, 0x810c, 0x810d, 0x810e, 0x810f, 
+    0x8110, 0x8111, 0x8112, 0x8113, 0x8114, 0x8115, 0x8116, 0x8117, 
+    0x8118, 0x8119, 0x811a, 0x811b, 0x811c, 0x811d, 0x811e, 0x811f, 
+    0x8120, 0x8121, 0x8122, 0x8123, 0x8124, 0x8125, 0x8126, 0x8127, 
+    0x8128, 0x8129, 0x812a, 0x812b, 0x812c, 0x812d, 0x812e, 0x812f, 
+    0x8130, 0x8131, 0x8132, 0x8133, 0x8134, 0x8135, 0x8136, 0x8137, 
+    0x8138, 0x8139, 0x813a, 0x813b, 0x813c, 0x813d, 0x813e, 0x813f, 
+    0x8140, 0x8141, 0x8142, 0x8143, 0x8144, 0x8145, 0x8146, 0x8147, 
+    0x8148, 0x8149, 0x814a, 0x814b, 0x814c, 0x814d, 0x814e, 0x814f, 
+    0x8150, 0x8151, 0x8152, 0x8153, 0x8154, 0x8155, 0x8156, 0x8157, 
+    0x8158, 0x8159, 0x815a, 0x815b, 0x815c, 0x815d, 0x815e, 0x815f, 
+    0x8160, 0x8161, 0x8162, 0x8163, 0x8164, 0x8165, 0x8166, 0x8167, 
+    0x8168, 0x8169, 0x816a, 0x816b, 0x816c, 0x816d, 0x816e, 0x816f, 
+    0x8170, 0x8171, 0x8172, 0x8173, 0x8174, 0x8175, 0x8176, 0x8177, 
+    0x8178, 0x8179, 0x817a, 0x817b, 0x817c, 0x817d, 0x817e, 0x817f, 
+    0x8180, 0x8181, 0x8182, 0x8183, 0x8184, 0x8185, 0x8186, 0x8187, 
+    0x8188, 0x8189, 0x818a, 0x818b, 0x818c, 0x818d, 0x818e, 0x818f, 
+    0x8190, 0x8191, 0x8192, 0x8193, 0x8194, 0x8195, 0x8196, 0x8197, 
+    0x8198, 0x8199, 0x819a, 0x819b, 0x819c, 0x819d, 0x819e, 0x819f, 
+    0x81a0, 0x81a1, 0x81a2, 0x81a3, 0x81a4, 0x81a5, 0x81a6, 0x81a7, 
+    0x81a8, 0x81a9, 0x81aa, 0x81ab, 0x81ac, 0x81ad, 0x81ae, 0x81af, 
+    0x81b0, 0x81b1, 0x81b2, 0x81b3, 0x81b4, 0x81b5, 0x81b6, 0x81b7, 
+    0x81b8, 0x81b9, 0x81ba, 0x81bb, 0x81bc, 0x81bd, 0x81be, 0x81bf, 
+    0x81c0, 0x81c1, 0x81c2, 0x81c3, 0x81c4, 0x81c5, 0x81c6, 0x81c7, 
+    0x81c8, 0x81c9, 0x81ca, 0x81cb, 0x81cc, 0x81cd, 0x81ce, 0x81cf, 
+    0x81d0, 0x81d1, 0x81d2, 0x81d3, 0x81d4, 0x81d5, 0x81d6, 0x81d7, 
+    0x81d8, 0x81d9, 0x81da, 0x81db, 0x81dc, 0x81dd, 0x81de, 0x81df, 
+    0x81e0, 0x81e1, 0x81e2, 0x81e3, 0x81e4, 0x81e5, 0x81e6, 0x81e7, 
+    0x81e8, 0x81e9, 0x81ea, 0x81eb, 0x81ec, 0x81ed, 0x81ee, 0x81ef, 
+    0x81f0, 0x81f1, 0x81f2, 0x81f3, 0x81f4, 0x81f5, 0x81f6, 0x81f7, 
+    0x81f8, 0x81f9, 0x81fa, 0x81fb, 0x81fc, 0x81fd, 0x81fe, 0x81ff, 
+    0x8200, 0x8201, 0x8202, 0x8203, 0x8204, 0x8205, 0x8206, 0x8207, 
+    0x8208, 0x8209, 0x820a, 0x820b, 0x820c, 0x820d, 0x820e, 0x820f, 
+    0x8210, 0x8211, 0x8212, 0x8213, 0x8214, 0x8215, 0x8216, 0x8217, 
+    0x8218, 0x8219, 0x821a, 0x821b, 0x821c, 0x821d, 0x821e, 0x821f, 
+    0x8220, 0x8221, 0x8222, 0x8223, 0x8224, 0x8225, 0x8226, 0x8227, 
+    0x8228, 0x8229, 0x822a, 0x822b, 0x822c, 0x822d, 0x822e, 0x822f, 
+    0x8230, 0x8231, 0x8232, 0x8233, 0x8234, 0x8235, 0x8236, 0x8237, 
+    0x8238, 0x8239, 0x823a, 0x823b, 0x823c, 0x823d, 0x823e, 0x823f, 
+    0x8240, 0x8241, 0x8242, 0x8243, 0x8244, 0x8245, 0x8246, 0x8247, 
+    0x8248, 0x8249, 0x824a, 0x824b, 0x824c, 0x824d, 0x824e, 0x824f, 
+    0x8250, 0x8251, 0x8252, 0x8253, 0x8254, 0x8255, 0x8256, 0x8257, 
+    0x8258, 0x8259, 0x825a, 0x825b, 0x825c, 0x825d, 0x825e, 0x825f, 
+    0x8260, 0x8261, 0x8262, 0x8263, 0x8264, 0x8265, 0x8266, 0x8267, 
+    0x8268, 0x8269, 0x826a, 0x826b, 0x826c, 0x826d, 0x826e, 0x826f, 
+    0x8270, 0x8271, 0x8272, 0x8273, 0x8274, 0x8275, 0x8276, 0x8277, 
+    0x8278, 0x8279, 0x827a, 0x827b, 0x827c, 0x827d, 0x827e, 0x827f, 
+    0x8280, 0x8281, 0x8282, 0x8283, 0x8284, 0x8285, 0x8286, 0x8287, 
+    0x8288, 0x8289, 0x828a, 0x828b, 0x828c, 0x828d, 0x828e, 0x828f, 
+    0x8290, 0x8291, 0x8292, 0x8293, 0x8294, 0x8295, 0x8296, 0x8297, 
+    0x8298, 0x8299, 0x829a, 0x829b, 0x829c, 0x829d, 0x829e, 0x829f, 
+    0x82a0, 0x82a1, 0x82a2, 0x82a3, 0x82a4, 0x82a5, 0x82a6, 0x82a7, 
+    0x82a8, 0x82a9, 0x82aa, 0x82ab, 0x82ac, 0x82ad, 0x82ae, 0x82af, 
+    0x82b0, 0x82b1, 0x82b2, 0x82b3, 0x82b4, 0x82b5, 0x82b6, 0x82b7, 
+    0x82b8, 0x82b9, 0x82ba, 0x82bb, 0x82bc, 0x82bd, 0x82be, 0x82bf, 
+    0x82c0, 0x82c1, 0x82c2, 0x82c3, 0x82c4, 0x82c5, 0x82c6, 0x82c7, 
+    0x82c8, 0x82c9, 0x82ca, 0x82cb, 0x82cc, 0x82cd, 0x82ce, 0x82cf, 
+    0x82d0, 0x82d1, 0x82d2, 0x82d3, 0x82d4, 0x82d5, 0x82d6, 0x82d7, 
+    0x82d8, 0x82d9, 0x82da, 0x82db, 0x82dc, 0x82dd, 0x82de, 0x82df, 
+    0x82e0, 0x82e1, 0x82e2, 0x82e3, 0x82e4, 0x82e5, 0x82e6, 0x82e7, 
+    0x82e8, 0x82e9, 0x82ea, 0x82eb, 0x82ec, 0x82ed, 0x82ee, 0x82ef, 
+    0x82f0, 0x82f1, 0x82f2, 0x82f3, 0x82f4, 0x82f5, 0x82f6, 0x82f7, 
+    0x82f8, 0x82f9, 0x82fa, 0x82fb, 0x82fc, 0x82fd, 0x82fe, 0x82ff, 
+    0x8300, 0x8301, 0x8302, 0x8303, 0x8304, 0x8305, 0x8306, 0x8307, 
+    0x8308, 0x8309, 0x830a, 0x830b, 0x830c, 0x830d, 0x830e, 0x830f, 
+    0x8310, 0x8311, 0x8312, 0x8313, 0x8314, 0x8315, 0x8316, 0x8317, 
+    0x8318, 0x8319, 0x831a, 0x831b, 0x831c, 0x831d, 0x831e, 0x831f, 
+    0x8320, 0x8321, 0x8322, 0x8323, 0x8324, 0x8325, 0x8326, 0x8327, 
+    0x8328, 0x8329, 0x832a, 0x832b, 0x832c, 0x832d, 0x832e, 0x832f, 
+    0x8330, 0x8331, 0x8332, 0x8333, 0x8334, 0x8335, 0x8336, 0x8337, 
+    0x8338, 0x8339, 0x833a, 0x833b, 0x833c, 0x833d, 0x833e, 0x833f, 
+    0x8340, 0x8341, 0x8342, 0x8343, 0x8344, 0x8345, 0x8346, 0x8347, 
+    0x8348, 0x8349, 0x834a, 0x834b, 0x834c, 0x834d, 0x834e, 0x834f, 
+    0x8350, 0x8351, 0x8352, 0x8353, 0x8354, 0x8355, 0x8356, 0x8357, 
+    0x8358, 0x8359, 0x835a, 0x835b, 0x835c, 0x835d, 0x835e, 0x835f, 
+    0x8360, 0x8361, 0x8362, 0x8363, 0x8364, 0x8365, 0x8366, 0x8367, 
+    0x8368, 0x8369, 0x836a, 0x836b, 0x836c, 0x836d, 0x836e, 0x836f, 
+    0x8370, 0x8371, 0x8372, 0x8373, 0x8374, 0x8375, 0x8376, 0x8377, 
+    0x8378, 0x8379, 0x837a, 0x837b, 0x837c, 0x837d, 0x837e, 0x837f, 
+    0x8380, 0x8381, 0x8382, 0x8383, 0x8384, 0x8385, 0x8386, 0x8387, 
+    0x8388, 0x8389, 0x838a, 0x838b, 0x838c, 0x838d, 0x838e, 0x838f, 
+    0x8390, 0x8391, 0x8392, 0x8393, 0x8394, 0x8395, 0x8396, 0x8397, 
+    0x8398, 0x8399, 0x839a, 0x839b, 0x839c, 0x839d, 0x839e, 0x839f, 
+    0x83a0, 0x83a1, 0x83a2, 0x83a3, 0x83a4, 0x83a5, 0x83a6, 0x83a7, 
+    0x83a8, 0x83a9, 0x83aa, 0x83ab, 0x83ac, 0x83ad, 0x83ae, 0x83af, 
+    0x83b0, 0x83b1, 0x83b2, 0x83b3, 0x83b4, 0x83b5, 0x83b6, 0x83b7, 
+    0x83b8, 0x83b9, 0x83ba, 0x83bb, 0x83bc, 0x83bd, 0x83be, 0x83bf, 
+    0x83c0, 0x83c1, 0x83c2, 0x83c3, 0x83c4, 0x83c5, 0x83c6, 0x83c7, 
+    0x83c8, 0x83c9, 0x83ca, 0x83cb, 0x83cc, 0x83cd, 0x83ce, 0x83cf, 
+    0x83d0, 0x83d1, 0x83d2, 0x83d3, 0x83d4, 0x83d5, 0x83d6, 0x83d7, 
+    0x83d8, 0x83d9, 0x83da, 0x83db, 0x83dc, 0x83dd, 0x83de, 0x83df, 
+    0x83e0, 0x83e1, 0x83e2, 0x83e3, 0x83e4, 0x83e5, 0x83e6, 0x83e7, 
+    0x83e8, 0x83e9, 0x83ea, 0x83eb, 0x83ec, 0x83ed, 0x83ee, 0x83ef, 
+    0x83f0, 0x83f1, 0x83f2, 0x83f3, 0x83f4, 0x83f5, 0x83f6, 0x83f7, 
+    0x83f8, 0x83f9, 0x83fa, 0x83fb, 0x83fc, 0x83fd, 0x83fe, 0x83ff, 
+    0x8400, 0x8401, 0x8402, 0x8403, 0x8404, 0x8405, 0x8406, 0x8407, 
+    0x8408, 0x8409, 0x840a, 0x840b, 0x840c, 0x840d, 0x840e, 0x840f, 
+    0x8410, 0x8411, 0x8412, 0x8413, 0x8414, 0x8415, 0x8416, 0x8417, 
+    0x8418, 0x8419, 0x841a, 0x841b, 0x841c, 0x841d, 0x841e, 0x841f, 
+    0x8420, 0x8421, 0x8422, 0x8423, 0x8424, 0x8425, 0x8426, 0x8427, 
+    0x8428, 0x8429, 0x842a, 0x842b, 0x842c, 0x842d, 0x842e, 0x842f, 
+    0x8430, 0x8431, 0x8432, 0x8433, 0x8434, 0x8435, 0x8436, 0x8437, 
+    0x8438, 0x8439, 0x843a, 0x843b, 0x843c, 0x843d, 0x843e, 0x843f, 
+    0x8440, 0x8441, 0x8442, 0x8443, 0x8444, 0x8445, 0x8446, 0x8447, 
+    0x8448, 0x8449, 0x844a, 0x844b, 0x844c, 0x844d, 0x844e, 0x844f, 
+    0x8450, 0x8451, 0x8452, 0x8453, 0x8454, 0x8455, 0x8456, 0x8457, 
+    0x8458, 0x8459, 0x845a, 0x845b, 0x845c, 0x845d, 0x845e, 0x845f, 
+    0x8460, 0x8461, 0x8462, 0x8463, 0x8464, 0x8465, 0x8466, 0x8467, 
+    0x8468, 0x8469, 0x846a, 0x846b, 0x846c, 0x846d, 0x846e, 0x846f, 
+    0x8470, 0x8471, 0x8472, 0x8473, 0x8474, 0x8475, 0x8476, 0x8477, 
+    0x8478, 0x8479, 0x847a, 0x847b, 0x847c, 0x847d, 0x847e, 0x847f, 
+    0x8480, 0x8481, 0x8482, 0x8483, 0x8484, 0x8485, 0x8486, 0x8487, 
+    0x8488, 0x8489, 0x848a, 0x848b, 0x848c, 0x848d, 0x848e, 0x848f, 
+    0x8490, 0x8491, 0x8492, 0x8493, 0x8494, 0x8495, 0x8496, 0x8497, 
+    0x8498, 0x8499, 0x849a, 0x849b, 0x849c, 0x849d, 0x849e, 0x849f, 
+    0x84a0, 0x84a1, 0x84a2, 0x84a3, 0x84a4, 0x84a5, 0x84a6, 0x84a7, 
+    0x84a8, 0x84a9, 0x84aa, 0x84ab, 0x84ac, 0x84ad, 0x84ae, 0x84af, 
+    0x84b0, 0x84b1, 0x84b2, 0x84b3, 0x84b4, 0x84b5, 0x84b6, 0x84b7, 
+    0x84b8, 0x84b9, 0x84ba, 0x84bb, 0x84bc, 0x84bd, 0x84be, 0x84bf, 
+    0x84c0, 0x84c1, 0x84c2, 0x84c3, 0x84c4, 0x84c5, 0x84c6, 0x84c7, 
+    0x84c8, 0x84c9, 0x84ca, 0x84cb, 0x84cc, 0x84cd, 0x84ce, 0x84cf, 
+    0x84d0, 0x84d1, 0x84d2, 0x84d3, 0x84d4, 0x84d5, 0x84d6, 0x84d7, 
+    0x84d8, 0x84d9, 0x84da, 0x84db, 0x84dc, 0x84dd, 0x84de, 0x84df, 
+    0x84e0, 0x84e1, 0x84e2, 0x84e3, 0x84e4, 0x84e5, 0x84e6, 0x84e7, 
+    0x84e8, 0x84e9, 0x84ea, 0x84eb, 0x84ec, 0x84ed, 0x84ee, 0x84ef, 
+    0x84f0, 0x84f1, 0x84f2, 0x84f3, 0x84f4, 0x84f5, 0x84f6, 0x84f7, 
+    0x84f8, 0x84f9, 0x84fa, 0x84fb, 0x84fc, 0x84fd, 0x84fe, 0x84ff, 
+    0x8500, 0x8501, 0x8502, 0x8503, 0x8504, 0x8505, 0x8506, 0x8507, 
+    0x8508, 0x8509, 0x850a, 0x850b, 0x850c, 0x850d, 0x850e, 0x850f, 
+    0x8510, 0x8511, 0x8512, 0x8513, 0x8514, 0x8515, 0x8516, 0x8517, 
+    0x8518, 0x8519, 0x851a, 0x851b, 0x851c, 0x851d, 0x851e, 0x851f, 
+    0x8520, 0x8521, 0x8522, 0x8523, 0x8524, 0x8525, 0x8526, 0x8527, 
+    0x8528, 0x8529, 0x852a, 0x852b, 0x852c, 0x852d, 0x852e, 0x852f, 
+    0x8530, 0x8531, 0x8532, 0x8533, 0x8534, 0x8535, 0x8536, 0x8537, 
+    0x8538, 0x8539, 0x853a, 0x853b, 0x853c, 0x853d, 0x853e, 0x853f, 
+    0x8540, 0x8541, 0x8542, 0x8543, 0x8544, 0x8545, 0x8546, 0x8547, 
+    0x8548, 0x8549, 0x854a, 0x854b, 0x854c, 0x854d, 0x854e, 0x854f, 
+    0x8550, 0x8551, 0x8552, 0x8553, 0x8554, 0x8555, 0x8556, 0x8557, 
+    0x8558, 0x8559, 0x855a, 0x855b, 0x855c, 0x855d, 0x855e, 0x855f, 
+    0x8560, 0x8561, 0x8562, 0x8563, 0x8564, 0x8565, 0x8566, 0x8567, 
+    0x8568, 0x8569, 0x856a, 0x856b, 0x856c, 0x856d, 0x856e, 0x856f, 
+    0x8570, 0x8571, 0x8572, 0x8573, 0x8574, 0x8575, 0x8576, 0x8577, 
+    0x8578, 0x8579, 0x857a, 0x857b, 0x857c, 0x857d, 0x857e, 0x857f, 
+    0x8580, 0x8581, 0x8582, 0x8583, 0x8584, 0x8585, 0x8586, 0x8587, 
+    0x8588, 0x8589, 0x858a, 0x858b, 0x858c, 0x858d, 0x858e, 0x858f, 
+    0x8590, 0x8591, 0x8592, 0x8593, 0x8594, 0x8595, 0x8596, 0x8597, 
+    0x8598, 0x8599, 0x859a, 0x859b, 0x859c, 0x859d, 0x859e, 0x859f, 
+    0x85a0, 0x85a1, 0x85a2, 0x85a3, 0x85a4, 0x85a5, 0x85a6, 0x85a7, 
+    0x85a8, 0x85a9, 0x85aa, 0x85ab, 0x85ac, 0x85ad, 0x85ae, 0x85af, 
+    0x85b0, 0x85b1, 0x85b2, 0x85b3, 0x85b4, 0x85b5, 0x85b6, 0x85b7, 
+    0x85b8, 0x85b9, 0x85ba, 0x85bb, 0x85bc, 0x85bd, 0x85be, 0x85bf, 
+    0x85c0, 0x85c1, 0x85c2, 0x85c3, 0x85c4, 0x85c5, 0x85c6, 0x85c7, 
+    0x85c8, 0x85c9, 0x85ca, 0x85cb, 0x85cc, 0x85cd, 0x85ce, 0x85cf, 
+    0x85d0, 0x85d1, 0x85d2, 0x85d3, 0x85d4, 0x85d5, 0x85d6, 0x85d7, 
+    0x85d8, 0x85d9, 0x85da, 0x85db, 0x85dc, 0x85dd, 0x85de, 0x85df, 
+    0x85e0, 0x85e1, 0x85e2, 0x85e3, 0x85e4, 0x85e5, 0x85e6, 0x85e7, 
+    0x85e8, 0x85e9, 0x85ea, 0x85eb, 0x85ec, 0x85ed, 0x85ee, 0x85ef, 
+    0x85f0, 0x85f1, 0x85f2, 0x85f3, 0x85f4, 0x85f5, 0x85f6, 0x85f7, 
+    0x85f8, 0x85f9, 0x85fa, 0x85fb, 0x85fc, 0x85fd, 0x85fe, 0x85ff, 
+    0x8600, 0x8601, 0x8602, 0x8603, 0x8604, 0x8605, 0x8606, 0x8607, 
+    0x8608, 0x8609, 0x860a, 0x860b, 0x860c, 0x860d, 0x860e, 0x860f, 
+    0x8610, 0x8611, 0x8612, 0x8613, 0x8614, 0x8615, 0x8616, 0x8617, 
+    0x8618, 0x8619, 0x861a, 0x861b, 0x861c, 0x861d, 0x861e, 0x861f, 
+    0x8620, 0x8621, 0x8622, 0x8623, 0x8624, 0x8625, 0x8626, 0x8627, 
+    0x8628, 0x8629, 0x862a, 0x862b, 0x862c, 0x862d, 0x862e, 0x862f, 
+    0x8630, 0x8631, 0x8632, 0x8633, 0x8634, 0x8635, 0x8636, 0x8637, 
+    0x8638, 0x8639, 0x863a, 0x863b, 0x863c, 0x863d, 0x863e, 0x863f, 
+    0x8640, 0x8641, 0x8642, 0x8643, 0x8644, 0x8645, 0x8646, 0x8647, 
+    0x8648, 0x8649, 0x864a, 0x864b, 0x864c, 0x864d, 0x864e, 0x864f, 
+    0x8650, 0x8651, 0x8652, 0x8653, 0x8654, 0x8655, 0x8656, 0x8657, 
+    0x8658, 0x8659, 0x865a, 0x865b, 0x865c, 0x865d, 0x865e, 0x865f, 
+    0x8660, 0x8661, 0x8662, 0x8663, 0x8664, 0x8665, 0x8666, 0x8667, 
+    0x8668, 0x8669, 0x866a, 0x866b, 0x866c, 0x866d, 0x866e, 0x866f, 
+    0x8670, 0x8671, 0x8672, 0x8673, 0x8674, 0x8675, 0x8676, 0x8677, 
+    0x8678, 0x8679, 0x867a, 0x867b, 0x867c, 0x867d, 0x867e, 0x867f, 
+    0x8680, 0x8681, 0x8682, 0x8683, 0x8684, 0x8685, 0x8686, 0x8687, 
+    0x8688, 0x8689, 0x868a, 0x868b, 0x868c, 0x868d, 0x868e, 0x868f, 
+    0x8690, 0x8691, 0x8692, 0x8693, 0x8694, 0x8695, 0x8696, 0x8697, 
+    0x8698, 0x8699, 0x869a, 0x869b, 0x869c, 0x869d, 0x869e, 0x869f, 
+    0x86a0, 0x86a1, 0x86a2, 0x86a3, 0x86a4, 0x86a5, 0x86a6, 0x86a7, 
+    0x86a8, 0x86a9, 0x86aa, 0x86ab, 0x86ac, 0x86ad, 0x86ae, 0x86af, 
+    0x86b0, 0x86b1, 0x86b2, 0x86b3, 0x86b4, 0x86b5, 0x86b6, 0x86b7, 
+    0x86b8, 0x86b9, 0x86ba, 0x86bb, 0x86bc, 0x86bd, 0x86be, 0x86bf, 
+    0x86c0, 0x86c1, 0x86c2, 0x86c3, 0x86c4, 0x86c5, 0x86c6, 0x86c7, 
+    0x86c8, 0x86c9, 0x86ca, 0x86cb, 0x86cc, 0x86cd, 0x86ce, 0x86cf, 
+    0x86d0, 0x86d1, 0x86d2, 0x86d3, 0x86d4, 0x86d5, 0x86d6, 0x86d7, 
+    0x86d8, 0x86d9, 0x86da, 0x86db, 0x86dc, 0x86dd, 0x86de, 0x86df, 
+    0x86e0, 0x86e1, 0x86e2, 0x86e3, 0x86e4, 0x86e5, 0x86e6, 0x86e7, 
+    0x86e8, 0x86e9, 0x86ea, 0x86eb, 0x86ec, 0x86ed, 0x86ee, 0x86ef, 
+    0x86f0, 0x86f1, 0x86f2, 0x86f3, 0x86f4, 0x86f5, 0x86f6, 0x86f7, 
+    0x86f8, 0x86f9, 0x86fa, 0x86fb, 0x86fc, 0x86fd, 0x86fe, 0x86ff, 
+    0x8700, 0x8701, 0x8702, 0x8703, 0x8704, 0x8705, 0x8706, 0x8707, 
+    0x8708, 0x8709, 0x870a, 0x870b, 0x870c, 0x870d, 0x870e, 0x870f, 
+    0x8710, 0x8711, 0x8712, 0x8713, 0x8714, 0x8715, 0x8716, 0x8717, 
+    0x8718, 0x8719, 0x871a, 0x871b, 0x871c, 0x871d, 0x871e, 0x871f, 
+    0x8720, 0x8721, 0x8722, 0x8723, 0x8724, 0x8725, 0x8726, 0x8727, 
+    0x8728, 0x8729, 0x872a, 0x872b, 0x872c, 0x872d, 0x872e, 0x872f, 
+    0x8730, 0x8731, 0x8732, 0x8733, 0x8734, 0x8735, 0x8736, 0x8737, 
+    0x8738, 0x8739, 0x873a, 0x873b, 0x873c, 0x873d, 0x873e, 0x873f, 
+    0x8740, 0x8741, 0x8742, 0x8743, 0x8744, 0x8745, 0x8746, 0x8747, 
+    0x8748, 0x8749, 0x874a, 0x874b, 0x874c, 0x874d, 0x874e, 0x874f, 
+    0x8750, 0x8751, 0x8752, 0x8753, 0x8754, 0x8755, 0x8756, 0x8757, 
+    0x8758, 0x8759, 0x875a, 0x875b, 0x875c, 0x875d, 0x875e, 0x875f, 
+    0x8760, 0x8761, 0x8762, 0x8763, 0x8764, 0x8765, 0x8766, 0x8767, 
+    0x8768, 0x8769, 0x876a, 0x876b, 0x876c, 0x876d, 0x876e, 0x876f, 
+    0x8770, 0x8771, 0x8772, 0x8773, 0x8774, 0x8775, 0x8776, 0x8777, 
+    0x8778, 0x8779, 0x877a, 0x877b, 0x877c, 0x877d, 0x877e, 0x877f, 
+    0x8780, 0x8781, 0x8782, 0x8783, 0x8784, 0x8785, 0x8786, 0x8787, 
+    0x8788, 0x8789, 0x878a, 0x878b, 0x878c, 0x878d, 0x878e, 0x878f, 
+    0x8790, 0x8791, 0x8792, 0x8793, 0x8794, 0x8795, 0x8796, 0x8797, 
+    0x8798, 0x8799, 0x879a, 0x879b, 0x879c, 0x879d, 0x879e, 0x879f, 
+    0x87a0, 0x87a1, 0x87a2, 0x87a3, 0x87a4, 0x87a5, 0x87a6, 0x87a7, 
+    0x87a8, 0x87a9, 0x87aa, 0x87ab, 0x87ac, 0x87ad, 0x87ae, 0x87af, 
+    0x87b0, 0x87b1, 0x87b2, 0x87b3, 0x87b4, 0x87b5, 0x87b6, 0x87b7, 
+    0x87b8, 0x87b9, 0x87ba, 0x87bb, 0x87bc, 0x87bd, 0x87be, 0x87bf, 
+    0x87c0, 0x87c1, 0x87c2, 0x87c3, 0x87c4, 0x87c5, 0x87c6, 0x87c7, 
+    0x87c8, 0x87c9, 0x87ca, 0x87cb, 0x87cc, 0x87cd, 0x87ce, 0x87cf, 
+    0x87d0, 0x87d1, 0x87d2, 0x87d3, 0x87d4, 0x87d5, 0x87d6, 0x87d7, 
+    0x87d8, 0x87d9, 0x87da, 0x87db, 0x87dc, 0x87dd, 0x87de, 0x87df, 
+    0x87e0, 0x87e1, 0x87e2, 0x87e3, 0x87e4, 0x87e5, 0x87e6, 0x87e7, 
+    0x87e8, 0x87e9, 0x87ea, 0x87eb, 0x87ec, 0x87ed, 0x87ee, 0x87ef, 
+    0x87f0, 0x87f1, 0x87f2, 0x87f3, 0x87f4, 0x87f5, 0x87f6, 0x87f7, 
+    0x87f8, 0x87f9, 0x87fa, 0x87fb, 0x87fc, 0x87fd, 0x87fe, 0x87ff, 
+    0x8800, 0x8801, 0x8802, 0x8803, 0x8804, 0x8805, 0x8806, 0x8807, 
+    0x8808, 0x8809, 0x880a, 0x880b, 0x880c, 0x880d, 0x880e, 0x880f, 
+    0x8810, 0x8811, 0x8812, 0x8813, 0x8814, 0x8815, 0x8816, 0x8817, 
+    0x8818, 0x8819, 0x881a, 0x881b, 0x881c, 0x881d, 0x881e, 0x881f, 
+    0x8820, 0x8821, 0x8822, 0x8823, 0x8824, 0x8825, 0x8826, 0x8827, 
+    0x8828, 0x8829, 0x882a, 0x882b, 0x882c, 0x882d, 0x882e, 0x882f, 
+    0x8830, 0x8831, 0x8832, 0x8833, 0x8834, 0x8835, 0x8836, 0x8837, 
+    0x8838, 0x8839, 0x883a, 0x883b, 0x883c, 0x883d, 0x883e, 0x883f, 
+    0x8840, 0x8841, 0x8842, 0x8843, 0x8844, 0x8845, 0x8846, 0x8847, 
+    0x8848, 0x8849, 0x884a, 0x884b, 0x884c, 0x884d, 0x884e, 0x884f, 
+    0x8850, 0x8851, 0x8852, 0x8853, 0x8854, 0x8855, 0x8856, 0x8857, 
+    0x8858, 0x8859, 0x885a, 0x885b, 0x885c, 0x885d, 0x885e, 0x885f, 
+    0x8860, 0x8861, 0x8862, 0x8863, 0x8864, 0x8865, 0x8866, 0x8867, 
+    0x8868, 0x8869, 0x886a, 0x886b, 0x886c, 0x886d, 0x886e, 0x886f, 
+    0x8870, 0x8871, 0x8872, 0x8873, 0x8874, 0x8875, 0x8876, 0x8877, 
+    0x8878, 0x8879, 0x887a, 0x887b, 0x887c, 0x887d, 0x887e, 0x887f, 
+    0x8880, 0x8881, 0x8882, 0x8883, 0x8884, 0x8885, 0x8886, 0x8887, 
+    0x8888, 0x8889, 0x888a, 0x888b, 0x888c, 0x888d, 0x888e, 0x888f, 
+    0x8890, 0x8891, 0x8892, 0x8893, 0x8894, 0x8895, 0x8896, 0x8897, 
+    0x8898, 0x8899, 0x889a, 0x889b, 0x889c, 0x889d, 0x889e, 0x889f, 
+    0x88a0, 0x88a1, 0x88a2, 0x88a3, 0x88a4, 0x88a5, 0x88a6, 0x88a7, 
+    0x88a8, 0x88a9, 0x88aa, 0x88ab, 0x88ac, 0x88ad, 0x88ae, 0x88af, 
+    0x88b0, 0x88b1, 0x88b2, 0x88b3, 0x88b4, 0x88b5, 0x88b6, 0x88b7, 
+    0x88b8, 0x88b9, 0x88ba, 0x88bb, 0x88bc, 0x88bd, 0x88be, 0x88bf, 
+    0x88c0, 0x88c1, 0x88c2, 0x88c3, 0x88c4, 0x88c5, 0x88c6, 0x88c7, 
+    0x88c8, 0x88c9, 0x88ca, 0x88cb, 0x88cc, 0x88cd, 0x88ce, 0x88cf, 
+    0x88d0, 0x88d1, 0x88d2, 0x88d3, 0x88d4, 0x88d5, 0x88d6, 0x88d7, 
+    0x88d8, 0x88d9, 0x88da, 0x88db, 0x88dc, 0x88dd, 0x88de, 0x88df, 
+    0x88e0, 0x88e1, 0x88e2, 0x88e3, 0x88e4, 0x88e5, 0x88e6, 0x88e7, 
+    0x88e8, 0x88e9, 0x88ea, 0x88eb, 0x88ec, 0x88ed, 0x88ee, 0x88ef, 
+    0x88f0, 0x88f1, 0x88f2, 0x88f3, 0x88f4, 0x88f5, 0x88f6, 0x88f7, 
+    0x88f8, 0x88f9, 0x88fa, 0x88fb, 0x88fc, 0x88fd, 0x88fe, 0x88ff, 
+    0x8900, 0x8901, 0x8902, 0x8903, 0x8904, 0x8905, 0x8906, 0x8907, 
+    0x8908, 0x8909, 0x890a, 0x890b, 0x890c, 0x890d, 0x890e, 0x890f, 
+    0x8910, 0x8911, 0x8912, 0x8913, 0x8914, 0x8915, 0x8916, 0x8917, 
+    0x8918, 0x8919, 0x891a, 0x891b, 0x891c, 0x891d, 0x891e, 0x891f, 
+    0x8920, 0x8921, 0x8922, 0x8923, 0x8924, 0x8925, 0x8926, 0x8927, 
+    0x8928, 0x8929, 0x892a, 0x892b, 0x892c, 0x892d, 0x892e, 0x892f, 
+    0x8930, 0x8931, 0x8932, 0x8933, 0x8934, 0x8935, 0x8936, 0x8937, 
+    0x8938, 0x8939, 0x893a, 0x893b, 0x893c, 0x893d, 0x893e, 0x893f, 
+    0x8940, 0x8941, 0x8942, 0x8943, 0x8944, 0x8945, 0x8946, 0x8947, 
+    0x8948, 0x8949, 0x894a, 0x894b, 0x894c, 0x894d, 0x894e, 0x894f, 
+    0x8950, 0x8951, 0x8952, 0x8953, 0x8954, 0x8955, 0x8956, 0x8957, 
+    0x8958, 0x8959, 0x895a, 0x895b, 0x895c, 0x895d, 0x895e, 0x895f, 
+    0x8960, 0x8961, 0x8962, 0x8963, 0x8964, 0x8965, 0x8966, 0x8967, 
+    0x8968, 0x8969, 0x896a, 0x896b, 0x896c, 0x896d, 0x896e, 0x896f, 
+    0x8970, 0x8971, 0x8972, 0x8973, 0x8974, 0x8975, 0x8976, 0x8977, 
+    0x8978, 0x8979, 0x897a, 0x897b, 0x897c, 0x897d, 0x897e, 0x897f, 
+    0x8980, 0x8981, 0x8982, 0x8983, 0x8984, 0x8985, 0x8986, 0x8987, 
+    0x8988, 0x8989, 0x898a, 0x898b, 0x898c, 0x898d, 0x898e, 0x898f, 
+    0x8990, 0x8991, 0x8992, 0x8993, 0x8994, 0x8995, 0x8996, 0x8997, 
+    0x8998, 0x8999, 0x899a, 0x899b, 0x899c, 0x899d, 0x899e, 0x899f, 
+    0x89a0, 0x89a1, 0x89a2, 0x89a3, 0x89a4, 0x89a5, 0x89a6, 0x89a7, 
+    0x89a8, 0x89a9, 0x89aa, 0x89ab, 0x89ac, 0x89ad, 0x89ae, 0x89af, 
+    0x89b0, 0x89b1, 0x89b2, 0x89b3, 0x89b4, 0x89b5, 0x89b6, 0x89b7, 
+    0x89b8, 0x89b9, 0x89ba, 0x89bb, 0x89bc, 0x89bd, 0x89be, 0x89bf, 
+    0x89c0, 0x89c1, 0x89c2, 0x89c3, 0x89c4, 0x89c5, 0x89c6, 0x89c7, 
+    0x89c8, 0x89c9, 0x89ca, 0x89cb, 0x89cc, 0x89cd, 0x89ce, 0x89cf, 
+    0x89d0, 0x89d1, 0x89d2, 0x89d3, 0x89d4, 0x89d5, 0x89d6, 0x89d7, 
+    0x89d8, 0x89d9, 0x89da, 0x89db, 0x89dc, 0x89dd, 0x89de, 0x89df, 
+    0x89e0, 0x89e1, 0x89e2, 0x89e3, 0x89e4, 0x89e5, 0x89e6, 0x89e7, 
+    0x89e8, 0x89e9, 0x89ea, 0x89eb, 0x89ec, 0x89ed, 0x89ee, 0x89ef, 
+    0x89f0, 0x89f1, 0x89f2, 0x89f3, 0x89f4, 0x89f5, 0x89f6, 0x89f7, 
+    0x89f8, 0x89f9, 0x89fa, 0x89fb, 0x89fc, 0x89fd, 0x89fe, 0x89ff, 
+    0x8a00, 0x8a01, 0x8a02, 0x8a03, 0x8a04, 0x8a05, 0x8a06, 0x8a07, 
+    0x8a08, 0x8a09, 0x8a0a, 0x8a0b, 0x8a0c, 0x8a0d, 0x8a0e, 0x8a0f, 
+    0x8a10, 0x8a11, 0x8a12, 0x8a13, 0x8a14, 0x8a15, 0x8a16, 0x8a17, 
+    0x8a18, 0x8a19, 0x8a1a, 0x8a1b, 0x8a1c, 0x8a1d, 0x8a1e, 0x8a1f, 
+    0x8a20, 0x8a21, 0x8a22, 0x8a23, 0x8a24, 0x8a25, 0x8a26, 0x8a27, 
+    0x8a28, 0x8a29, 0x8a2a, 0x8a2b, 0x8a2c, 0x8a2d, 0x8a2e, 0x8a2f, 
+    0x8a30, 0x8a31, 0x8a32, 0x8a33, 0x8a34, 0x8a35, 0x8a36, 0x8a37, 
+    0x8a38, 0x8a39, 0x8a3a, 0x8a3b, 0x8a3c, 0x8a3d, 0x8a3e, 0x8a3f, 
+    0x8a40, 0x8a41, 0x8a42, 0x8a43, 0x8a44, 0x8a45, 0x8a46, 0x8a47, 
+    0x8a48, 0x8a49, 0x8a4a, 0x8a4b, 0x8a4c, 0x8a4d, 0x8a4e, 0x8a4f, 
+    0x8a50, 0x8a51, 0x8a52, 0x8a53, 0x8a54, 0x8a55, 0x8a56, 0x8a57, 
+    0x8a58, 0x8a59, 0x8a5a, 0x8a5b, 0x8a5c, 0x8a5d, 0x8a5e, 0x8a5f, 
+    0x8a60, 0x8a61, 0x8a62, 0x8a63, 0x8a64, 0x8a65, 0x8a66, 0x8a67, 
+    0x8a68, 0x8a69, 0x8a6a, 0x8a6b, 0x8a6c, 0x8a6d, 0x8a6e, 0x8a6f, 
+    0x8a70, 0x8a71, 0x8a72, 0x8a73, 0x8a74, 0x8a75, 0x8a76, 0x8a77, 
+    0x8a78, 0x8a79, 0x8a7a, 0x8a7b, 0x8a7c, 0x8a7d, 0x8a7e, 0x8a7f, 
+    0x8a80, 0x8a81, 0x8a82, 0x8a83, 0x8a84, 0x8a85, 0x8a86, 0x8a87, 
+    0x8a88, 0x8a89, 0x8a8a, 0x8a8b, 0x8a8c, 0x8a8d, 0x8a8e, 0x8a8f, 
+    0x8a90, 0x8a91, 0x8a92, 0x8a93, 0x8a94, 0x8a95, 0x8a96, 0x8a97, 
+    0x8a98, 0x8a99, 0x8a9a, 0x8a9b, 0x8a9c, 0x8a9d, 0x8a9e, 0x8a9f, 
+    0x8aa0, 0x8aa1, 0x8aa2, 0x8aa3, 0x8aa4, 0x8aa5, 0x8aa6, 0x8aa7, 
+    0x8aa8, 0x8aa9, 0x8aaa, 0x8aab, 0x8aac, 0x8aad, 0x8aae, 0x8aaf, 
+    0x8ab0, 0x8ab1, 0x8ab2, 0x8ab3, 0x8ab4, 0x8ab5, 0x8ab6, 0x8ab7, 
+    0x8ab8, 0x8ab9, 0x8aba, 0x8abb, 0x8abc, 0x8abd, 0x8abe, 0x8abf, 
+    0x8ac0, 0x8ac1, 0x8ac2, 0x8ac3, 0x8ac4, 0x8ac5, 0x8ac6, 0x8ac7, 
+    0x8ac8, 0x8ac9, 0x8aca, 0x8acb, 0x8acc, 0x8acd, 0x8ace, 0x8acf, 
+    0x8ad0, 0x8ad1, 0x8ad2, 0x8ad3, 0x8ad4, 0x8ad5, 0x8ad6, 0x8ad7, 
+    0x8ad8, 0x8ad9, 0x8ada, 0x8adb, 0x8adc, 0x8add, 0x8ade, 0x8adf, 
+    0x8ae0, 0x8ae1, 0x8ae2, 0x8ae3, 0x8ae4, 0x8ae5, 0x8ae6, 0x8ae7, 
+    0x8ae8, 0x8ae9, 0x8aea, 0x8aeb, 0x8aec, 0x8aed, 0x8aee, 0x8aef, 
+    0x8af0, 0x8af1, 0x8af2, 0x8af3, 0x8af4, 0x8af5, 0x8af6, 0x8af7, 
+    0x8af8, 0x8af9, 0x8afa, 0x8afb, 0x8afc, 0x8afd, 0x8afe, 0x8aff, 
+    0x8b00, 0x8b01, 0x8b02, 0x8b03, 0x8b04, 0x8b05, 0x8b06, 0x8b07, 
+    0x8b08, 0x8b09, 0x8b0a, 0x8b0b, 0x8b0c, 0x8b0d, 0x8b0e, 0x8b0f, 
+    0x8b10, 0x8b11, 0x8b12, 0x8b13, 0x8b14, 0x8b15, 0x8b16, 0x8b17, 
+    0x8b18, 0x8b19, 0x8b1a, 0x8b1b, 0x8b1c, 0x8b1d, 0x8b1e, 0x8b1f, 
+    0x8b20, 0x8b21, 0x8b22, 0x8b23, 0x8b24, 0x8b25, 0x8b26, 0x8b27, 
+    0x8b28, 0x8b29, 0x8b2a, 0x8b2b, 0x8b2c, 0x8b2d, 0x8b2e, 0x8b2f, 
+    0x8b30, 0x8b31, 0x8b32, 0x8b33, 0x8b34, 0x8b35, 0x8b36, 0x8b37, 
+    0x8b38, 0x8b39, 0x8b3a, 0x8b3b, 0x8b3c, 0x8b3d, 0x8b3e, 0x8b3f, 
+    0x8b40, 0x8b41, 0x8b42, 0x8b43, 0x8b44, 0x8b45, 0x8b46, 0x8b47, 
+    0x8b48, 0x8b49, 0x8b4a, 0x8b4b, 0x8b4c, 0x8b4d, 0x8b4e, 0x8b4f, 
+    0x8b50, 0x8b51, 0x8b52, 0x8b53, 0x8b54, 0x8b55, 0x8b56, 0x8b57, 
+    0x8b58, 0x8b59, 0x8b5a, 0x8b5b, 0x8b5c, 0x8b5d, 0x8b5e, 0x8b5f, 
+    0x8b60, 0x8b61, 0x8b62, 0x8b63, 0x8b64, 0x8b65, 0x8b66, 0x8b67, 
+    0x8b68, 0x8b69, 0x8b6a, 0x8b6b, 0x8b6c, 0x8b6d, 0x8b6e, 0x8b6f, 
+    0x8b70, 0x8b71, 0x8b72, 0x8b73, 0x8b74, 0x8b75, 0x8b76, 0x8b77, 
+    0x8b78, 0x8b79, 0x8b7a, 0x8b7b, 0x8b7c, 0x8b7d, 0x8b7e, 0x8b7f, 
+    0x8b80, 0x8b81, 0x8b82, 0x8b83, 0x8b84, 0x8b85, 0x8b86, 0x8b87, 
+    0x8b88, 0x8b89, 0x8b8a, 0x8b8b, 0x8b8c, 0x8b8d, 0x8b8e, 0x8b8f, 
+    0x8b90, 0x8b91, 0x8b92, 0x8b93, 0x8b94, 0x8b95, 0x8b96, 0x8b97, 
+    0x8b98, 0x8b99, 0x8b9a, 0x8b9b, 0x8b9c, 0x8b9d, 0x8b9e, 0x8b9f, 
+    0x8ba0, 0x8ba1, 0x8ba2, 0x8ba3, 0x8ba4, 0x8ba5, 0x8ba6, 0x8ba7, 
+    0x8ba8, 0x8ba9, 0x8baa, 0x8bab, 0x8bac, 0x8bad, 0x8bae, 0x8baf, 
+    0x8bb0, 0x8bb1, 0x8bb2, 0x8bb3, 0x8bb4, 0x8bb5, 0x8bb6, 0x8bb7, 
+    0x8bb8, 0x8bb9, 0x8bba, 0x8bbb, 0x8bbc, 0x8bbd, 0x8bbe, 0x8bbf, 
+    0x8bc0, 0x8bc1, 0x8bc2, 0x8bc3, 0x8bc4, 0x8bc5, 0x8bc6, 0x8bc7, 
+    0x8bc8, 0x8bc9, 0x8bca, 0x8bcb, 0x8bcc, 0x8bcd, 0x8bce, 0x8bcf, 
+    0x8bd0, 0x8bd1, 0x8bd2, 0x8bd3, 0x8bd4, 0x8bd5, 0x8bd6, 0x8bd7, 
+    0x8bd8, 0x8bd9, 0x8bda, 0x8bdb, 0x8bdc, 0x8bdd, 0x8bde, 0x8bdf, 
+    0x8be0, 0x8be1, 0x8be2, 0x8be3, 0x8be4, 0x8be5, 0x8be6, 0x8be7, 
+    0x8be8, 0x8be9, 0x8bea, 0x8beb, 0x8bec, 0x8bed, 0x8bee, 0x8bef, 
+    0x8bf0, 0x8bf1, 0x8bf2, 0x8bf3, 0x8bf4, 0x8bf5, 0x8bf6, 0x8bf7, 
+    0x8bf8, 0x8bf9, 0x8bfa, 0x8bfb, 0x8bfc, 0x8bfd, 0x8bfe, 0x8bff, 
+    0x8c00, 0x8c01, 0x8c02, 0x8c03, 0x8c04, 0x8c05, 0x8c06, 0x8c07, 
+    0x8c08, 0x8c09, 0x8c0a, 0x8c0b, 0x8c0c, 0x8c0d, 0x8c0e, 0x8c0f, 
+    0x8c10, 0x8c11, 0x8c12, 0x8c13, 0x8c14, 0x8c15, 0x8c16, 0x8c17, 
+    0x8c18, 0x8c19, 0x8c1a, 0x8c1b, 0x8c1c, 0x8c1d, 0x8c1e, 0x8c1f, 
+    0x8c20, 0x8c21, 0x8c22, 0x8c23, 0x8c24, 0x8c25, 0x8c26, 0x8c27, 
+    0x8c28, 0x8c29, 0x8c2a, 0x8c2b, 0x8c2c, 0x8c2d, 0x8c2e, 0x8c2f, 
+    0x8c30, 0x8c31, 0x8c32, 0x8c33, 0x8c34, 0x8c35, 0x8c36, 0x8c37, 
+    0x8c38, 0x8c39, 0x8c3a, 0x8c3b, 0x8c3c, 0x8c3d, 0x8c3e, 0x8c3f, 
+    0x8c40, 0x8c41, 0x8c42, 0x8c43, 0x8c44, 0x8c45, 0x8c46, 0x8c47, 
+    0x8c48, 0x8c49, 0x8c4a, 0x8c4b, 0x8c4c, 0x8c4d, 0x8c4e, 0x8c4f, 
+    0x8c50, 0x8c51, 0x8c52, 0x8c53, 0x8c54, 0x8c55, 0x8c56, 0x8c57, 
+    0x8c58, 0x8c59, 0x8c5a, 0x8c5b, 0x8c5c, 0x8c5d, 0x8c5e, 0x8c5f, 
+    0x8c60, 0x8c61, 0x8c62, 0x8c63, 0x8c64, 0x8c65, 0x8c66, 0x8c67, 
+    0x8c68, 0x8c69, 0x8c6a, 0x8c6b, 0x8c6c, 0x8c6d, 0x8c6e, 0x8c6f, 
+    0x8c70, 0x8c71, 0x8c72, 0x8c73, 0x8c74, 0x8c75, 0x8c76, 0x8c77, 
+    0x8c78, 0x8c79, 0x8c7a, 0x8c7b, 0x8c7c, 0x8c7d, 0x8c7e, 0x8c7f, 
+    0x8c80, 0x8c81, 0x8c82, 0x8c83, 0x8c84, 0x8c85, 0x8c86, 0x8c87, 
+    0x8c88, 0x8c89, 0x8c8a, 0x8c8b, 0x8c8c, 0x8c8d, 0x8c8e, 0x8c8f, 
+    0x8c90, 0x8c91, 0x8c92, 0x8c93, 0x8c94, 0x8c95, 0x8c96, 0x8c97, 
+    0x8c98, 0x8c99, 0x8c9a, 0x8c9b, 0x8c9c, 0x8c9d, 0x8c9e, 0x8c9f, 
+    0x8ca0, 0x8ca1, 0x8ca2, 0x8ca3, 0x8ca4, 0x8ca5, 0x8ca6, 0x8ca7, 
+    0x8ca8, 0x8ca9, 0x8caa, 0x8cab, 0x8cac, 0x8cad, 0x8cae, 0x8caf, 
+    0x8cb0, 0x8cb1, 0x8cb2, 0x8cb3, 0x8cb4, 0x8cb5, 0x8cb6, 0x8cb7, 
+    0x8cb8, 0x8cb9, 0x8cba, 0x8cbb, 0x8cbc, 0x8cbd, 0x8cbe, 0x8cbf, 
+    0x8cc0, 0x8cc1, 0x8cc2, 0x8cc3, 0x8cc4, 0x8cc5, 0x8cc6, 0x8cc7, 
+    0x8cc8, 0x8cc9, 0x8cca, 0x8ccb, 0x8ccc, 0x8ccd, 0x8cce, 0x8ccf, 
+    0x8cd0, 0x8cd1, 0x8cd2, 0x8cd3, 0x8cd4, 0x8cd5, 0x8cd6, 0x8cd7, 
+    0x8cd8, 0x8cd9, 0x8cda, 0x8cdb, 0x8cdc, 0x8cdd, 0x8cde, 0x8cdf, 
+    0x8ce0, 0x8ce1, 0x8ce2, 0x8ce3, 0x8ce4, 0x8ce5, 0x8ce6, 0x8ce7, 
+    0x8ce8, 0x8ce9, 0x8cea, 0x8ceb, 0x8cec, 0x8ced, 0x8cee, 0x8cef, 
+    0x8cf0, 0x8cf1, 0x8cf2, 0x8cf3, 0x8cf4, 0x8cf5, 0x8cf6, 0x8cf7, 
+    0x8cf8, 0x8cf9, 0x8cfa, 0x8cfb, 0x8cfc, 0x8cfd, 0x8cfe, 0x8cff, 
+    0x8d00, 0x8d01, 0x8d02, 0x8d03, 0x8d04, 0x8d05, 0x8d06, 0x8d07, 
+    0x8d08, 0x8d09, 0x8d0a, 0x8d0b, 0x8d0c, 0x8d0d, 0x8d0e, 0x8d0f, 
+    0x8d10, 0x8d11, 0x8d12, 0x8d13, 0x8d14, 0x8d15, 0x8d16, 0x8d17, 
+    0x8d18, 0x8d19, 0x8d1a, 0x8d1b, 0x8d1c, 0x8d1d, 0x8d1e, 0x8d1f, 
+    0x8d20, 0x8d21, 0x8d22, 0x8d23, 0x8d24, 0x8d25, 0x8d26, 0x8d27, 
+    0x8d28, 0x8d29, 0x8d2a, 0x8d2b, 0x8d2c, 0x8d2d, 0x8d2e, 0x8d2f, 
+    0x8d30, 0x8d31, 0x8d32, 0x8d33, 0x8d34, 0x8d35, 0x8d36, 0x8d37, 
+    0x8d38, 0x8d39, 0x8d3a, 0x8d3b, 0x8d3c, 0x8d3d, 0x8d3e, 0x8d3f, 
+    0x8d40, 0x8d41, 0x8d42, 0x8d43, 0x8d44, 0x8d45, 0x8d46, 0x8d47, 
+    0x8d48, 0x8d49, 0x8d4a, 0x8d4b, 0x8d4c, 0x8d4d, 0x8d4e, 0x8d4f, 
+    0x8d50, 0x8d51, 0x8d52, 0x8d53, 0x8d54, 0x8d55, 0x8d56, 0x8d57, 
+    0x8d58, 0x8d59, 0x8d5a, 0x8d5b, 0x8d5c, 0x8d5d, 0x8d5e, 0x8d5f, 
+    0x8d60, 0x8d61, 0x8d62, 0x8d63, 0x8d64, 0x8d65, 0x8d66, 0x8d67, 
+    0x8d68, 0x8d69, 0x8d6a, 0x8d6b, 0x8d6c, 0x8d6d, 0x8d6e, 0x8d6f, 
+    0x8d70, 0x8d71, 0x8d72, 0x8d73, 0x8d74, 0x8d75, 0x8d76, 0x8d77, 
+    0x8d78, 0x8d79, 0x8d7a, 0x8d7b, 0x8d7c, 0x8d7d, 0x8d7e, 0x8d7f, 
+    0x8d80, 0x8d81, 0x8d82, 0x8d83, 0x8d84, 0x8d85, 0x8d86, 0x8d87, 
+    0x8d88, 0x8d89, 0x8d8a, 0x8d8b, 0x8d8c, 0x8d8d, 0x8d8e, 0x8d8f, 
+    0x8d90, 0x8d91, 0x8d92, 0x8d93, 0x8d94, 0x8d95, 0x8d96, 0x8d97, 
+    0x8d98, 0x8d99, 0x8d9a, 0x8d9b, 0x8d9c, 0x8d9d, 0x8d9e, 0x8d9f, 
+    0x8da0, 0x8da1, 0x8da2, 0x8da3, 0x8da4, 0x8da5, 0x8da6, 0x8da7, 
+    0x8da8, 0x8da9, 0x8daa, 0x8dab, 0x8dac, 0x8dad, 0x8dae, 0x8daf, 
+    0x8db0, 0x8db1, 0x8db2, 0x8db3, 0x8db4, 0x8db5, 0x8db6, 0x8db7, 
+    0x8db8, 0x8db9, 0x8dba, 0x8dbb, 0x8dbc, 0x8dbd, 0x8dbe, 0x8dbf, 
+    0x8dc0, 0x8dc1, 0x8dc2, 0x8dc3, 0x8dc4, 0x8dc5, 0x8dc6, 0x8dc7, 
+    0x8dc8, 0x8dc9, 0x8dca, 0x8dcb, 0x8dcc, 0x8dcd, 0x8dce, 0x8dcf, 
+    0x8dd0, 0x8dd1, 0x8dd2, 0x8dd3, 0x8dd4, 0x8dd5, 0x8dd6, 0x8dd7, 
+    0x8dd8, 0x8dd9, 0x8dda, 0x8ddb, 0x8ddc, 0x8ddd, 0x8dde, 0x8ddf, 
+    0x8de0, 0x8de1, 0x8de2, 0x8de3, 0x8de4, 0x8de5, 0x8de6, 0x8de7, 
+    0x8de8, 0x8de9, 0x8dea, 0x8deb, 0x8dec, 0x8ded, 0x8dee, 0x8def, 
+    0x8df0, 0x8df1, 0x8df2, 0x8df3, 0x8df4, 0x8df5, 0x8df6, 0x8df7, 
+    0x8df8, 0x8df9, 0x8dfa, 0x8dfb, 0x8dfc, 0x8dfd, 0x8dfe, 0x8dff, 
+    0x8e00, 0x8e01, 0x8e02, 0x8e03, 0x8e04, 0x8e05, 0x8e06, 0x8e07, 
+    0x8e08, 0x8e09, 0x8e0a, 0x8e0b, 0x8e0c, 0x8e0d, 0x8e0e, 0x8e0f, 
+    0x8e10, 0x8e11, 0x8e12, 0x8e13, 0x8e14, 0x8e15, 0x8e16, 0x8e17, 
+    0x8e18, 0x8e19, 0x8e1a, 0x8e1b, 0x8e1c, 0x8e1d, 0x8e1e, 0x8e1f, 
+    0x8e20, 0x8e21, 0x8e22, 0x8e23, 0x8e24, 0x8e25, 0x8e26, 0x8e27, 
+    0x8e28, 0x8e29, 0x8e2a, 0x8e2b, 0x8e2c, 0x8e2d, 0x8e2e, 0x8e2f, 
+    0x8e30, 0x8e31, 0x8e32, 0x8e33, 0x8e34, 0x8e35, 0x8e36, 0x8e37, 
+    0x8e38, 0x8e39, 0x8e3a, 0x8e3b, 0x8e3c, 0x8e3d, 0x8e3e, 0x8e3f, 
+    0x8e40, 0x8e41, 0x8e42, 0x8e43, 0x8e44, 0x8e45, 0x8e46, 0x8e47, 
+    0x8e48, 0x8e49, 0x8e4a, 0x8e4b, 0x8e4c, 0x8e4d, 0x8e4e, 0x8e4f, 
+    0x8e50, 0x8e51, 0x8e52, 0x8e53, 0x8e54, 0x8e55, 0x8e56, 0x8e57, 
+    0x8e58, 0x8e59, 0x8e5a, 0x8e5b, 0x8e5c, 0x8e5d, 0x8e5e, 0x8e5f, 
+    0x8e60, 0x8e61, 0x8e62, 0x8e63, 0x8e64, 0x8e65, 0x8e66, 0x8e67, 
+    0x8e68, 0x8e69, 0x8e6a, 0x8e6b, 0x8e6c, 0x8e6d, 0x8e6e, 0x8e6f, 
+    0x8e70, 0x8e71, 0x8e72, 0x8e73, 0x8e74, 0x8e75, 0x8e76, 0x8e77, 
+    0x8e78, 0x8e79, 0x8e7a, 0x8e7b, 0x8e7c, 0x8e7d, 0x8e7e, 0x8e7f, 
+    0x8e80, 0x8e81, 0x8e82, 0x8e83, 0x8e84, 0x8e85, 0x8e86, 0x8e87, 
+    0x8e88, 0x8e89, 0x8e8a, 0x8e8b, 0x8e8c, 0x8e8d, 0x8e8e, 0x8e8f, 
+    0x8e90, 0x8e91, 0x8e92, 0x8e93, 0x8e94, 0x8e95, 0x8e96, 0x8e97, 
+    0x8e98, 0x8e99, 0x8e9a, 0x8e9b, 0x8e9c, 0x8e9d, 0x8e9e, 0x8e9f, 
+    0x8ea0, 0x8ea1, 0x8ea2, 0x8ea3, 0x8ea4, 0x8ea5, 0x8ea6, 0x8ea7, 
+    0x8ea8, 0x8ea9, 0x8eaa, 0x8eab, 0x8eac, 0x8ead, 0x8eae, 0x8eaf, 
+    0x8eb0, 0x8eb1, 0x8eb2, 0x8eb3, 0x8eb4, 0x8eb5, 0x8eb6, 0x8eb7, 
+    0x8eb8, 0x8eb9, 0x8eba, 0x8ebb, 0x8ebc, 0x8ebd, 0x8ebe, 0x8ebf, 
+    0x8ec0, 0x8ec1, 0x8ec2, 0x8ec3, 0x8ec4, 0x8ec5, 0x8ec6, 0x8ec7, 
+    0x8ec8, 0x8ec9, 0x8eca, 0x8ecb, 0x8ecc, 0x8ecd, 0x8ece, 0x8ecf, 
+    0x8ed0, 0x8ed1, 0x8ed2, 0x8ed3, 0x8ed4, 0x8ed5, 0x8ed6, 0x8ed7, 
+    0x8ed8, 0x8ed9, 0x8eda, 0x8edb, 0x8edc, 0x8edd, 0x8ede, 0x8edf, 
+    0x8ee0, 0x8ee1, 0x8ee2, 0x8ee3, 0x8ee4, 0x8ee5, 0x8ee6, 0x8ee7, 
+    0x8ee8, 0x8ee9, 0x8eea, 0x8eeb, 0x8eec, 0x8eed, 0x8eee, 0x8eef, 
+    0x8ef0, 0x8ef1, 0x8ef2, 0x8ef3, 0x8ef4, 0x8ef5, 0x8ef6, 0x8ef7, 
+    0x8ef8, 0x8ef9, 0x8efa, 0x8efb, 0x8efc, 0x8efd, 0x8efe, 0x8eff, 
+    0x8f00, 0x8f01, 0x8f02, 0x8f03, 0x8f04, 0x8f05, 0x8f06, 0x8f07, 
+    0x8f08, 0x8f09, 0x8f0a, 0x8f0b, 0x8f0c, 0x8f0d, 0x8f0e, 0x8f0f, 
+    0x8f10, 0x8f11, 0x8f12, 0x8f13, 0x8f14, 0x8f15, 0x8f16, 0x8f17, 
+    0x8f18, 0x8f19, 0x8f1a, 0x8f1b, 0x8f1c, 0x8f1d, 0x8f1e, 0x8f1f, 
+    0x8f20, 0x8f21, 0x8f22, 0x8f23, 0x8f24, 0x8f25, 0x8f26, 0x8f27, 
+    0x8f28, 0x8f29, 0x8f2a, 0x8f2b, 0x8f2c, 0x8f2d, 0x8f2e, 0x8f2f, 
+    0x8f30, 0x8f31, 0x8f32, 0x8f33, 0x8f34, 0x8f35, 0x8f36, 0x8f37, 
+    0x8f38, 0x8f39, 0x8f3a, 0x8f3b, 0x8f3c, 0x8f3d, 0x8f3e, 0x8f3f, 
+    0x8f40, 0x8f41, 0x8f42, 0x8f43, 0x8f44, 0x8f45, 0x8f46, 0x8f47, 
+    0x8f48, 0x8f49, 0x8f4a, 0x8f4b, 0x8f4c, 0x8f4d, 0x8f4e, 0x8f4f, 
+    0x8f50, 0x8f51, 0x8f52, 0x8f53, 0x8f54, 0x8f55, 0x8f56, 0x8f57, 
+    0x8f58, 0x8f59, 0x8f5a, 0x8f5b, 0x8f5c, 0x8f5d, 0x8f5e, 0x8f5f, 
+    0x8f60, 0x8f61, 0x8f62, 0x8f63, 0x8f64, 0x8f65, 0x8f66, 0x8f67, 
+    0x8f68, 0x8f69, 0x8f6a, 0x8f6b, 0x8f6c, 0x8f6d, 0x8f6e, 0x8f6f, 
+    0x8f70, 0x8f71, 0x8f72, 0x8f73, 0x8f74, 0x8f75, 0x8f76, 0x8f77, 
+    0x8f78, 0x8f79, 0x8f7a, 0x8f7b, 0x8f7c, 0x8f7d, 0x8f7e, 0x8f7f, 
+    0x8f80, 0x8f81, 0x8f82, 0x8f83, 0x8f84, 0x8f85, 0x8f86, 0x8f87, 
+    0x8f88, 0x8f89, 0x8f8a, 0x8f8b, 0x8f8c, 0x8f8d, 0x8f8e, 0x8f8f, 
+    0x8f90, 0x8f91, 0x8f92, 0x8f93, 0x8f94, 0x8f95, 0x8f96, 0x8f97, 
+    0x8f98, 0x8f99, 0x8f9a, 0x8f9b, 0x8f9c, 0x8f9d, 0x8f9e, 0x8f9f, 
+    0x8fa0, 0x8fa1, 0x8fa2, 0x8fa3, 0x8fa4, 0x8fa5, 0x8fa6, 0x8fa7, 
+    0x8fa8, 0x8fa9, 0x8faa, 0x8fab, 0x8fac, 0x8fad, 0x8fae, 0x8faf, 
+    0x8fb0, 0x8fb1, 0x8fb2, 0x8fb3, 0x8fb4, 0x8fb5, 0x8fb6, 0x8fb7, 
+    0x8fb8, 0x8fb9, 0x8fba, 0x8fbb, 0x8fbc, 0x8fbd, 0x8fbe, 0x8fbf, 
+    0x8fc0, 0x8fc1, 0x8fc2, 0x8fc3, 0x8fc4, 0x8fc5, 0x8fc6, 0x8fc7, 
+    0x8fc8, 0x8fc9, 0x8fca, 0x8fcb, 0x8fcc, 0x8fcd, 0x8fce, 0x8fcf, 
+    0x8fd0, 0x8fd1, 0x8fd2, 0x8fd3, 0x8fd4, 0x8fd5, 0x8fd6, 0x8fd7, 
+    0x8fd8, 0x8fd9, 0x8fda, 0x8fdb, 0x8fdc, 0x8fdd, 0x8fde, 0x8fdf, 
+    0x8fe0, 0x8fe1, 0x8fe2, 0x8fe3, 0x8fe4, 0x8fe5, 0x8fe6, 0x8fe7, 
+    0x8fe8, 0x8fe9, 0x8fea, 0x8feb, 0x8fec, 0x8fed, 0x8fee, 0x8fef, 
+    0x8ff0, 0x8ff1, 0x8ff2, 0x8ff3, 0x8ff4, 0x8ff5, 0x8ff6, 0x8ff7, 
+    0x8ff8, 0x8ff9, 0x8ffa, 0x8ffb, 0x8ffc, 0x8ffd, 0x8ffe, 0x8fff, 
+    0x9000, 0x9001, 0x9002, 0x9003, 0x9004, 0x9005, 0x9006, 0x9007, 
+    0x9008, 0x9009, 0x900a, 0x900b, 0x900c, 0x900d, 0x900e, 0x900f, 
+    0x9010, 0x9011, 0x9012, 0x9013, 0x9014, 0x9015, 0x9016, 0x9017, 
+    0x9018, 0x9019, 0x901a, 0x901b, 0x901c, 0x901d, 0x901e, 0x901f, 
+    0x9020, 0x9021, 0x9022, 0x9023, 0x9024, 0x9025, 0x9026, 0x9027, 
+    0x9028, 0x9029, 0x902a, 0x902b, 0x902c, 0x902d, 0x902e, 0x902f, 
+    0x9030, 0x9031, 0x9032, 0x9033, 0x9034, 0x9035, 0x9036, 0x9037, 
+    0x9038, 0x9039, 0x903a, 0x903b, 0x903c, 0x903d, 0x903e, 0x903f, 
+    0x9040, 0x9041, 0x9042, 0x9043, 0x9044, 0x9045, 0x9046, 0x9047, 
+    0x9048, 0x9049, 0x904a, 0x904b, 0x904c, 0x904d, 0x904e, 0x904f, 
+    0x9050, 0x9051, 0x9052, 0x9053, 0x9054, 0x9055, 0x9056, 0x9057, 
+    0x9058, 0x9059, 0x905a, 0x905b, 0x905c, 0x905d, 0x905e, 0x905f, 
+    0x9060, 0x9061, 0x9062, 0x9063, 0x9064, 0x9065, 0x9066, 0x9067, 
+    0x9068, 0x9069, 0x906a, 0x906b, 0x906c, 0x906d, 0x906e, 0x906f, 
+    0x9070, 0x9071, 0x9072, 0x9073, 0x9074, 0x9075, 0x9076, 0x9077, 
+    0x9078, 0x9079, 0x907a, 0x907b, 0x907c, 0x907d, 0x907e, 0x907f, 
+    0x9080, 0x9081, 0x9082, 0x9083, 0x9084, 0x9085, 0x9086, 0x9087, 
+    0x9088, 0x9089, 0x908a, 0x908b, 0x908c, 0x908d, 0x908e, 0x908f, 
+    0x9090, 0x9091, 0x9092, 0x9093, 0x9094, 0x9095, 0x9096, 0x9097, 
+    0x9098, 0x9099, 0x909a, 0x909b, 0x909c, 0x909d, 0x909e, 0x909f, 
+    0x90a0, 0x90a1, 0x90a2, 0x90a3, 0x90a4, 0x90a5, 0x90a6, 0x90a7, 
+    0x90a8, 0x90a9, 0x90aa, 0x90ab, 0x90ac, 0x90ad, 0x90ae, 0x90af, 
+    0x90b0, 0x90b1, 0x90b2, 0x90b3, 0x90b4, 0x90b5, 0x90b6, 0x90b7, 
+    0x90b8, 0x90b9, 0x90ba, 0x90bb, 0x90bc, 0x90bd, 0x90be, 0x90bf, 
+    0x90c0, 0x90c1, 0x90c2, 0x90c3, 0x90c4, 0x90c5, 0x90c6, 0x90c7, 
+    0x90c8, 0x90c9, 0x90ca, 0x90cb, 0x90cc, 0x90cd, 0x90ce, 0x90cf, 
+    0x90d0, 0x90d1, 0x90d2, 0x90d3, 0x90d4, 0x90d5, 0x90d6, 0x90d7, 
+    0x90d8, 0x90d9, 0x90da, 0x90db, 0x90dc, 0x90dd, 0x90de, 0x90df, 
+    0x90e0, 0x90e1, 0x90e2, 0x90e3, 0x90e4, 0x90e5, 0x90e6, 0x90e7, 
+    0x90e8, 0x90e9, 0x90ea, 0x90eb, 0x90ec, 0x90ed, 0x90ee, 0x90ef, 
+    0x90f0, 0x90f1, 0x90f2, 0x90f3, 0x90f4, 0x90f5, 0x90f6, 0x90f7, 
+    0x90f8, 0x90f9, 0x90fa, 0x90fb, 0x90fc, 0x90fd, 0x90fe, 0x90ff, 
+    0x9100, 0x9101, 0x9102, 0x9103, 0x9104, 0x9105, 0x9106, 0x9107, 
+    0x9108, 0x9109, 0x910a, 0x910b, 0x910c, 0x910d, 0x910e, 0x910f, 
+    0x9110, 0x9111, 0x9112, 0x9113, 0x9114, 0x9115, 0x9116, 0x9117, 
+    0x9118, 0x9119, 0x911a, 0x911b, 0x911c, 0x911d, 0x911e, 0x911f, 
+    0x9120, 0x9121, 0x9122, 0x9123, 0x9124, 0x9125, 0x9126, 0x9127, 
+    0x9128, 0x9129, 0x912a, 0x912b, 0x912c, 0x912d, 0x912e, 0x912f, 
+    0x9130, 0x9131, 0x9132, 0x9133, 0x9134, 0x9135, 0x9136, 0x9137, 
+    0x9138, 0x9139, 0x913a, 0x913b, 0x913c, 0x913d, 0x913e, 0x913f, 
+    0x9140, 0x9141, 0x9142, 0x9143, 0x9144, 0x9145, 0x9146, 0x9147, 
+    0x9148, 0x9149, 0x914a, 0x914b, 0x914c, 0x914d, 0x914e, 0x914f, 
+    0x9150, 0x9151, 0x9152, 0x9153, 0x9154, 0x9155, 0x9156, 0x9157, 
+    0x9158, 0x9159, 0x915a, 0x915b, 0x915c, 0x915d, 0x915e, 0x915f, 
+    0x9160, 0x9161, 0x9162, 0x9163, 0x9164, 0x9165, 0x9166, 0x9167, 
+    0x9168, 0x9169, 0x916a, 0x916b, 0x916c, 0x916d, 0x916e, 0x916f, 
+    0x9170, 0x9171, 0x9172, 0x9173, 0x9174, 0x9175, 0x9176, 0x9177, 
+    0x9178, 0x9179, 0x917a, 0x917b, 0x917c, 0x917d, 0x917e, 0x917f, 
+    0x9180, 0x9181, 0x9182, 0x9183, 0x9184, 0x9185, 0x9186, 0x9187, 
+    0x9188, 0x9189, 0x918a, 0x918b, 0x918c, 0x918d, 0x918e, 0x918f, 
+    0x9190, 0x9191, 0x9192, 0x9193, 0x9194, 0x9195, 0x9196, 0x9197, 
+    0x9198, 0x9199, 0x919a, 0x919b, 0x919c, 0x919d, 0x919e, 0x919f, 
+    0x91a0, 0x91a1, 0x91a2, 0x91a3, 0x91a4, 0x91a5, 0x91a6, 0x91a7, 
+    0x91a8, 0x91a9, 0x91aa, 0x91ab, 0x91ac, 0x91ad, 0x91ae, 0x91af, 
+    0x91b0, 0x91b1, 0x91b2, 0x91b3, 0x91b4, 0x91b5, 0x91b6, 0x91b7, 
+    0x91b8, 0x91b9, 0x91ba, 0x91bb, 0x91bc, 0x91bd, 0x91be, 0x91bf, 
+    0x91c0, 0x91c1, 0x91c2, 0x91c3, 0x91c4, 0x91c5, 0x91c6, 0x91c7, 
+    0x91c8, 0x91c9, 0x91ca, 0x91cb, 0x91cc, 0x91cd, 0x91ce, 0x91cf, 
+    0x91d0, 0x91d1, 0x91d2, 0x91d3, 0x91d4, 0x91d5, 0x91d6, 0x91d7, 
+    0x91d8, 0x91d9, 0x91da, 0x91db, 0x91dc, 0x91dd, 0x91de, 0x91df, 
+    0x91e0, 0x91e1, 0x91e2, 0x91e3, 0x91e4, 0x91e5, 0x91e6, 0x91e7, 
+    0x91e8, 0x91e9, 0x91ea, 0x91eb, 0x91ec, 0x91ed, 0x91ee, 0x91ef, 
+    0x91f0, 0x91f1, 0x91f2, 0x91f3, 0x91f4, 0x91f5, 0x91f6, 0x91f7, 
+    0x91f8, 0x91f9, 0x91fa, 0x91fb, 0x91fc, 0x91fd, 0x91fe, 0x91ff, 
+    0x9200, 0x9201, 0x9202, 0x9203, 0x9204, 0x9205, 0x9206, 0x9207, 
+    0x9208, 0x9209, 0x920a, 0x920b, 0x920c, 0x920d, 0x920e, 0x920f, 
+    0x9210, 0x9211, 0x9212, 0x9213, 0x9214, 0x9215, 0x9216, 0x9217, 
+    0x9218, 0x9219, 0x921a, 0x921b, 0x921c, 0x921d, 0x921e, 0x921f, 
+    0x9220, 0x9221, 0x9222, 0x9223, 0x9224, 0x9225, 0x9226, 0x9227, 
+    0x9228, 0x9229, 0x922a, 0x922b, 0x922c, 0x922d, 0x922e, 0x922f, 
+    0x9230, 0x9231, 0x9232, 0x9233, 0x9234, 0x9235, 0x9236, 0x9237, 
+    0x9238, 0x9239, 0x923a, 0x923b, 0x923c, 0x923d, 0x923e, 0x923f, 
+    0x9240, 0x9241, 0x9242, 0x9243, 0x9244, 0x9245, 0x9246, 0x9247, 
+    0x9248, 0x9249, 0x924a, 0x924b, 0x924c, 0x924d, 0x924e, 0x924f, 
+    0x9250, 0x9251, 0x9252, 0x9253, 0x9254, 0x9255, 0x9256, 0x9257, 
+    0x9258, 0x9259, 0x925a, 0x925b, 0x925c, 0x925d, 0x925e, 0x925f, 
+    0x9260, 0x9261, 0x9262, 0x9263, 0x9264, 0x9265, 0x9266, 0x9267, 
+    0x9268, 0x9269, 0x926a, 0x926b, 0x926c, 0x926d, 0x926e, 0x926f, 
+    0x9270, 0x9271, 0x9272, 0x9273, 0x9274, 0x9275, 0x9276, 0x9277, 
+    0x9278, 0x9279, 0x927a, 0x927b, 0x927c, 0x927d, 0x927e, 0x927f, 
+    0x9280, 0x9281, 0x9282, 0x9283, 0x9284, 0x9285, 0x9286, 0x9287, 
+    0x9288, 0x9289, 0x928a, 0x928b, 0x928c, 0x928d, 0x928e, 0x928f, 
+    0x9290, 0x9291, 0x9292, 0x9293, 0x9294, 0x9295, 0x9296, 0x9297, 
+    0x9298, 0x9299, 0x929a, 0x929b, 0x929c, 0x929d, 0x929e, 0x929f, 
+    0x92a0, 0x92a1, 0x92a2, 0x92a3, 0x92a4, 0x92a5, 0x92a6, 0x92a7, 
+    0x92a8, 0x92a9, 0x92aa, 0x92ab, 0x92ac, 0x92ad, 0x92ae, 0x92af, 
+    0x92b0, 0x92b1, 0x92b2, 0x92b3, 0x92b4, 0x92b5, 0x92b6, 0x92b7, 
+    0x92b8, 0x92b9, 0x92ba, 0x92bb, 0x92bc, 0x92bd, 0x92be, 0x92bf, 
+    0x92c0, 0x92c1, 0x92c2, 0x92c3, 0x92c4, 0x92c5, 0x92c6, 0x92c7, 
+    0x92c8, 0x92c9, 0x92ca, 0x92cb, 0x92cc, 0x92cd, 0x92ce, 0x92cf, 
+    0x92d0, 0x92d1, 0x92d2, 0x92d3, 0x92d4, 0x92d5, 0x92d6, 0x92d7, 
+    0x92d8, 0x92d9, 0x92da, 0x92db, 0x92dc, 0x92dd, 0x92de, 0x92df, 
+    0x92e0, 0x92e1, 0x92e2, 0x92e3, 0x92e4, 0x92e5, 0x92e6, 0x92e7, 
+    0x92e8, 0x92e9, 0x92ea, 0x92eb, 0x92ec, 0x92ed, 0x92ee, 0x92ef, 
+    0x92f0, 0x92f1, 0x92f2, 0x92f3, 0x92f4, 0x92f5, 0x92f6, 0x92f7, 
+    0x92f8, 0x92f9, 0x92fa, 0x92fb, 0x92fc, 0x92fd, 0x92fe, 0x92ff, 
+    0x9300, 0x9301, 0x9302, 0x9303, 0x9304, 0x9305, 0x9306, 0x9307, 
+    0x9308, 0x9309, 0x930a, 0x930b, 0x930c, 0x930d, 0x930e, 0x930f, 
+    0x9310, 0x9311, 0x9312, 0x9313, 0x9314, 0x9315, 0x9316, 0x9317, 
+    0x9318, 0x9319, 0x931a, 0x931b, 0x931c, 0x931d, 0x931e, 0x931f, 
+    0x9320, 0x9321, 0x9322, 0x9323, 0x9324, 0x9325, 0x9326, 0x9327, 
+    0x9328, 0x9329, 0x932a, 0x932b, 0x932c, 0x932d, 0x932e, 0x932f, 
+    0x9330, 0x9331, 0x9332, 0x9333, 0x9334, 0x9335, 0x9336, 0x9337, 
+    0x9338, 0x9339, 0x933a, 0x933b, 0x933c, 0x933d, 0x933e, 0x933f, 
+    0x9340, 0x9341, 0x9342, 0x9343, 0x9344, 0x9345, 0x9346, 0x9347, 
+    0x9348, 0x9349, 0x934a, 0x934b, 0x934c, 0x934d, 0x934e, 0x934f, 
+    0x9350, 0x9351, 0x9352, 0x9353, 0x9354, 0x9355, 0x9356, 0x9357, 
+    0x9358, 0x9359, 0x935a, 0x935b, 0x935c, 0x935d, 0x935e, 0x935f, 
+    0x9360, 0x9361, 0x9362, 0x9363, 0x9364, 0x9365, 0x9366, 0x9367, 
+    0x9368, 0x9369, 0x936a, 0x936b, 0x936c, 0x936d, 0x936e, 0x936f, 
+    0x9370, 0x9371, 0x9372, 0x9373, 0x9374, 0x9375, 0x9376, 0x9377, 
+    0x9378, 0x9379, 0x937a, 0x937b, 0x937c, 0x937d, 0x937e, 0x937f, 
+    0x9380, 0x9381, 0x9382, 0x9383, 0x9384, 0x9385, 0x9386, 0x9387, 
+    0x9388, 0x9389, 0x938a, 0x938b, 0x938c, 0x938d, 0x938e, 0x938f, 
+    0x9390, 0x9391, 0x9392, 0x9393, 0x9394, 0x9395, 0x9396, 0x9397, 
+    0x9398, 0x9399, 0x939a, 0x939b, 0x939c, 0x939d, 0x939e, 0x939f, 
+    0x93a0, 0x93a1, 0x93a2, 0x93a3, 0x93a4, 0x93a5, 0x93a6, 0x93a7, 
+    0x93a8, 0x93a9, 0x93aa, 0x93ab, 0x93ac, 0x93ad, 0x93ae, 0x93af, 
+    0x93b0, 0x93b1, 0x93b2, 0x93b3, 0x93b4, 0x93b5, 0x93b6, 0x93b7, 
+    0x93b8, 0x93b9, 0x93ba, 0x93bb, 0x93bc, 0x93bd, 0x93be, 0x93bf, 
+    0x93c0, 0x93c1, 0x93c2, 0x93c3, 0x93c4, 0x93c5, 0x93c6, 0x93c7, 
+    0x93c8, 0x93c9, 0x93ca, 0x93cb, 0x93cc, 0x93cd, 0x93ce, 0x93cf, 
+    0x93d0, 0x93d1, 0x93d2, 0x93d3, 0x93d4, 0x93d5, 0x93d6, 0x93d7, 
+    0x93d8, 0x93d9, 0x93da, 0x93db, 0x93dc, 0x93dd, 0x93de, 0x93df, 
+    0x93e0, 0x93e1, 0x93e2, 0x93e3, 0x93e4, 0x93e5, 0x93e6, 0x93e7, 
+    0x93e8, 0x93e9, 0x93ea, 0x93eb, 0x93ec, 0x93ed, 0x93ee, 0x93ef, 
+    0x93f0, 0x93f1, 0x93f2, 0x93f3, 0x93f4, 0x93f5, 0x93f6, 0x93f7, 
+    0x93f8, 0x93f9, 0x93fa, 0x93fb, 0x93fc, 0x93fd, 0x93fe, 0x93ff, 
+    0x9400, 0x9401, 0x9402, 0x9403, 0x9404, 0x9405, 0x9406, 0x9407, 
+    0x9408, 0x9409, 0x940a, 0x940b, 0x940c, 0x940d, 0x940e, 0x940f, 
+    0x9410, 0x9411, 0x9412, 0x9413, 0x9414, 0x9415, 0x9416, 0x9417, 
+    0x9418, 0x9419, 0x941a, 0x941b, 0x941c, 0x941d, 0x941e, 0x941f, 
+    0x9420, 0x9421, 0x9422, 0x9423, 0x9424, 0x9425, 0x9426, 0x9427, 
+    0x9428, 0x9429, 0x942a, 0x942b, 0x942c, 0x942d, 0x942e, 0x942f, 
+    0x9430, 0x9431, 0x9432, 0x9433, 0x9434, 0x9435, 0x9436, 0x9437, 
+    0x9438, 0x9439, 0x943a, 0x943b, 0x943c, 0x943d, 0x943e, 0x943f, 
+    0x9440, 0x9441, 0x9442, 0x9443, 0x9444, 0x9445, 0x9446, 0x9447, 
+    0x9448, 0x9449, 0x944a, 0x944b, 0x944c, 0x944d, 0x944e, 0x944f, 
+    0x9450, 0x9451, 0x9452, 0x9453, 0x9454, 0x9455, 0x9456, 0x9457, 
+    0x9458, 0x9459, 0x945a, 0x945b, 0x945c, 0x945d, 0x945e, 0x945f, 
+    0x9460, 0x9461, 0x9462, 0x9463, 0x9464, 0x9465, 0x9466, 0x9467, 
+    0x9468, 0x9469, 0x946a, 0x946b, 0x946c, 0x946d, 0x946e, 0x946f, 
+    0x9470, 0x9471, 0x9472, 0x9473, 0x9474, 0x9475, 0x9476, 0x9477, 
+    0x9478, 0x9479, 0x947a, 0x947b, 0x947c, 0x947d, 0x947e, 0x947f, 
+    0x9480, 0x9481, 0x9482, 0x9483, 0x9484, 0x9485, 0x9486, 0x9487, 
+    0x9488, 0x9489, 0x948a, 0x948b, 0x948c, 0x948d, 0x948e, 0x948f, 
+    0x9490, 0x9491, 0x9492, 0x9493, 0x9494, 0x9495, 0x9496, 0x9497, 
+    0x9498, 0x9499, 0x949a, 0x949b, 0x949c, 0x949d, 0x949e, 0x949f, 
+    0x94a0, 0x94a1, 0x94a2, 0x94a3, 0x94a4, 0x94a5, 0x94a6, 0x94a7, 
+    0x94a8, 0x94a9, 0x94aa, 0x94ab, 0x94ac, 0x94ad, 0x94ae, 0x94af, 
+    0x94b0, 0x94b1, 0x94b2, 0x94b3, 0x94b4, 0x94b5, 0x94b6, 0x94b7, 
+    0x94b8, 0x94b9, 0x94ba, 0x94bb, 0x94bc, 0x94bd, 0x94be, 0x94bf, 
+    0x94c0, 0x94c1, 0x94c2, 0x94c3, 0x94c4, 0x94c5, 0x94c6, 0x94c7, 
+    0x94c8, 0x94c9, 0x94ca, 0x94cb, 0x94cc, 0x94cd, 0x94ce, 0x94cf, 
+    0x94d0, 0x94d1, 0x94d2, 0x94d3, 0x94d4, 0x94d5, 0x94d6, 0x94d7, 
+    0x94d8, 0x94d9, 0x94da, 0x94db, 0x94dc, 0x94dd, 0x94de, 0x94df, 
+    0x94e0, 0x94e1, 0x94e2, 0x94e3, 0x94e4, 0x94e5, 0x94e6, 0x94e7, 
+    0x94e8, 0x94e9, 0x94ea, 0x94eb, 0x94ec, 0x94ed, 0x94ee, 0x94ef, 
+    0x94f0, 0x94f1, 0x94f2, 0x94f3, 0x94f4, 0x94f5, 0x94f6, 0x94f7, 
+    0x94f8, 0x94f9, 0x94fa, 0x94fb, 0x94fc, 0x94fd, 0x94fe, 0x94ff, 
+    0x9500, 0x9501, 0x9502, 0x9503, 0x9504, 0x9505, 0x9506, 0x9507, 
+    0x9508, 0x9509, 0x950a, 0x950b, 0x950c, 0x950d, 0x950e, 0x950f, 
+    0x9510, 0x9511, 0x9512, 0x9513, 0x9514, 0x9515, 0x9516, 0x9517, 
+    0x9518, 0x9519, 0x951a, 0x951b, 0x951c, 0x951d, 0x951e, 0x951f, 
+    0x9520, 0x9521, 0x9522, 0x9523, 0x9524, 0x9525, 0x9526, 0x9527, 
+    0x9528, 0x9529, 0x952a, 0x952b, 0x952c, 0x952d, 0x952e, 0x952f, 
+    0x9530, 0x9531, 0x9532, 0x9533, 0x9534, 0x9535, 0x9536, 0x9537, 
+    0x9538, 0x9539, 0x953a, 0x953b, 0x953c, 0x953d, 0x953e, 0x953f, 
+    0x9540, 0x9541, 0x9542, 0x9543, 0x9544, 0x9545, 0x9546, 0x9547, 
+    0x9548, 0x9549, 0x954a, 0x954b, 0x954c, 0x954d, 0x954e, 0x954f, 
+    0x9550, 0x9551, 0x9552, 0x9553, 0x9554, 0x9555, 0x9556, 0x9557, 
+    0x9558, 0x9559, 0x955a, 0x955b, 0x955c, 0x955d, 0x955e, 0x955f, 
+    0x9560, 0x9561, 0x9562, 0x9563, 0x9564, 0x9565, 0x9566, 0x9567, 
+    0x9568, 0x9569, 0x956a, 0x956b, 0x956c, 0x956d, 0x956e, 0x956f, 
+    0x9570, 0x9571, 0x9572, 0x9573, 0x9574, 0x9575, 0x9576, 0x9577, 
+    0x9578, 0x9579, 0x957a, 0x957b, 0x957c, 0x957d, 0x957e, 0x957f, 
+    0x9580, 0x9581, 0x9582, 0x9583, 0x9584, 0x9585, 0x9586, 0x9587, 
+    0x9588, 0x9589, 0x958a, 0x958b, 0x958c, 0x958d, 0x958e, 0x958f, 
+    0x9590, 0x9591, 0x9592, 0x9593, 0x9594, 0x9595, 0x9596, 0x9597, 
+    0x9598, 0x9599, 0x959a, 0x959b, 0x959c, 0x959d, 0x959e, 0x959f, 
+    0x95a0, 0x95a1, 0x95a2, 0x95a3, 0x95a4, 0x95a5, 0x95a6, 0x95a7, 
+    0x95a8, 0x95a9, 0x95aa, 0x95ab, 0x95ac, 0x95ad, 0x95ae, 0x95af, 
+    0x95b0, 0x95b1, 0x95b2, 0x95b3, 0x95b4, 0x95b5, 0x95b6, 0x95b7, 
+    0x95b8, 0x95b9, 0x95ba, 0x95bb, 0x95bc, 0x95bd, 0x95be, 0x95bf, 
+    0x95c0, 0x95c1, 0x95c2, 0x95c3, 0x95c4, 0x95c5, 0x95c6, 0x95c7, 
+    0x95c8, 0x95c9, 0x95ca, 0x95cb, 0x95cc, 0x95cd, 0x95ce, 0x95cf, 
+    0x95d0, 0x95d1, 0x95d2, 0x95d3, 0x95d4, 0x95d5, 0x95d6, 0x95d7, 
+    0x95d8, 0x95d9, 0x95da, 0x95db, 0x95dc, 0x95dd, 0x95de, 0x95df, 
+    0x95e0, 0x95e1, 0x95e2, 0x95e3, 0x95e4, 0x95e5, 0x95e6, 0x95e7, 
+    0x95e8, 0x95e9, 0x95ea, 0x95eb, 0x95ec, 0x95ed, 0x95ee, 0x95ef, 
+    0x95f0, 0x95f1, 0x95f2, 0x95f3, 0x95f4, 0x95f5, 0x95f6, 0x95f7, 
+    0x95f8, 0x95f9, 0x95fa, 0x95fb, 0x95fc, 0x95fd, 0x95fe, 0x95ff, 
+    0x9600, 0x9601, 0x9602, 0x9603, 0x9604, 0x9605, 0x9606, 0x9607, 
+    0x9608, 0x9609, 0x960a, 0x960b, 0x960c, 0x960d, 0x960e, 0x960f, 
+    0x9610, 0x9611, 0x9612, 0x9613, 0x9614, 0x9615, 0x9616, 0x9617, 
+    0x9618, 0x9619, 0x961a, 0x961b, 0x961c, 0x961d, 0x961e, 0x961f, 
+    0x9620, 0x9621, 0x9622, 0x9623, 0x9624, 0x9625, 0x9626, 0x9627, 
+    0x9628, 0x9629, 0x962a, 0x962b, 0x962c, 0x962d, 0x962e, 0x962f, 
+    0x9630, 0x9631, 0x9632, 0x9633, 0x9634, 0x9635, 0x9636, 0x9637, 
+    0x9638, 0x9639, 0x963a, 0x963b, 0x963c, 0x963d, 0x963e, 0x963f, 
+    0x9640, 0x9641, 0x9642, 0x9643, 0x9644, 0x9645, 0x9646, 0x9647, 
+    0x9648, 0x9649, 0x964a, 0x964b, 0x964c, 0x964d, 0x964e, 0x964f, 
+    0x9650, 0x9651, 0x9652, 0x9653, 0x9654, 0x9655, 0x9656, 0x9657, 
+    0x9658, 0x9659, 0x965a, 0x965b, 0x965c, 0x965d, 0x965e, 0x965f, 
+    0x9660, 0x9661, 0x9662, 0x9663, 0x9664, 0x9665, 0x9666, 0x9667, 
+    0x9668, 0x9669, 0x966a, 0x966b, 0x966c, 0x966d, 0x966e, 0x966f, 
+    0x9670, 0x9671, 0x9672, 0x9673, 0x9674, 0x9675, 0x9676, 0x9677, 
+    0x9678, 0x9679, 0x967a, 0x967b, 0x967c, 0x967d, 0x967e, 0x967f, 
+    0x9680, 0x9681, 0x9682, 0x9683, 0x9684, 0x9685, 0x9686, 0x9687, 
+    0x9688, 0x9689, 0x968a, 0x968b, 0x968c, 0x968d, 0x968e, 0x968f, 
+    0x9690, 0x9691, 0x9692, 0x9693, 0x9694, 0x9695, 0x9696, 0x9697, 
+    0x9698, 0x9699, 0x969a, 0x969b, 0x969c, 0x969d, 0x969e, 0x969f, 
+    0x96a0, 0x96a1, 0x96a2, 0x96a3, 0x96a4, 0x96a5, 0x96a6, 0x96a7, 
+    0x96a8, 0x96a9, 0x96aa, 0x96ab, 0x96ac, 0x96ad, 0x96ae, 0x96af, 
+    0x96b0, 0x96b1, 0x96b2, 0x96b3, 0x96b4, 0x96b5, 0x96b6, 0x96b7, 
+    0x96b8, 0x96b9, 0x96ba, 0x96bb, 0x96bc, 0x96bd, 0x96be, 0x96bf, 
+    0x96c0, 0x96c1, 0x96c2, 0x96c3, 0x96c4, 0x96c5, 0x96c6, 0x96c7, 
+    0x96c8, 0x96c9, 0x96ca, 0x96cb, 0x96cc, 0x96cd, 0x96ce, 0x96cf, 
+    0x96d0, 0x96d1, 0x96d2, 0x96d3, 0x96d4, 0x96d5, 0x96d6, 0x96d7, 
+    0x96d8, 0x96d9, 0x96da, 0x96db, 0x96dc, 0x96dd, 0x96de, 0x96df, 
+    0x96e0, 0x96e1, 0x96e2, 0x96e3, 0x96e4, 0x96e5, 0x96e6, 0x96e7, 
+    0x96e8, 0x96e9, 0x96ea, 0x96eb, 0x96ec, 0x96ed, 0x96ee, 0x96ef, 
+    0x96f0, 0x96f1, 0x96f2, 0x96f3, 0x96f4, 0x96f5, 0x96f6, 0x96f7, 
+    0x96f8, 0x96f9, 0x96fa, 0x96fb, 0x96fc, 0x96fd, 0x96fe, 0x96ff, 
+    0x9700, 0x9701, 0x9702, 0x9703, 0x9704, 0x9705, 0x9706, 0x9707, 
+    0x9708, 0x9709, 0x970a, 0x970b, 0x970c, 0x970d, 0x970e, 0x970f, 
+    0x9710, 0x9711, 0x9712, 0x9713, 0x9714, 0x9715, 0x9716, 0x9717, 
+    0x9718, 0x9719, 0x971a, 0x971b, 0x971c, 0x971d, 0x971e, 0x971f, 
+    0x9720, 0x9721, 0x9722, 0x9723, 0x9724, 0x9725, 0x9726, 0x9727, 
+    0x9728, 0x9729, 0x972a, 0x972b, 0x972c, 0x972d, 0x972e, 0x972f, 
+    0x9730, 0x9731, 0x9732, 0x9733, 0x9734, 0x9735, 0x9736, 0x9737, 
+    0x9738, 0x9739, 0x973a, 0x973b, 0x973c, 0x973d, 0x973e, 0x973f, 
+    0x9740, 0x9741, 0x9742, 0x9743, 0x9744, 0x9745, 0x9746, 0x9747, 
+    0x9748, 0x9749, 0x974a, 0x974b, 0x974c, 0x974d, 0x974e, 0x974f, 
+    0x9750, 0x9751, 0x9752, 0x9753, 0x9754, 0x9755, 0x9756, 0x9757, 
+    0x9758, 0x9759, 0x975a, 0x975b, 0x975c, 0x975d, 0x975e, 0x975f, 
+    0x9760, 0x9761, 0x9762, 0x9763, 0x9764, 0x9765, 0x9766, 0x9767, 
+    0x9768, 0x9769, 0x976a, 0x976b, 0x976c, 0x976d, 0x976e, 0x976f, 
+    0x9770, 0x9771, 0x9772, 0x9773, 0x9774, 0x9775, 0x9776, 0x9777, 
+    0x9778, 0x9779, 0x977a, 0x977b, 0x977c, 0x977d, 0x977e, 0x977f, 
+    0x9780, 0x9781, 0x9782, 0x9783, 0x9784, 0x9785, 0x9786, 0x9787, 
+    0x9788, 0x9789, 0x978a, 0x978b, 0x978c, 0x978d, 0x978e, 0x978f, 
+    0x9790, 0x9791, 0x9792, 0x9793, 0x9794, 0x9795, 0x9796, 0x9797, 
+    0x9798, 0x9799, 0x979a, 0x979b, 0x979c, 0x979d, 0x979e, 0x979f, 
+    0x97a0, 0x97a1, 0x97a2, 0x97a3, 0x97a4, 0x97a5, 0x97a6, 0x97a7, 
+    0x97a8, 0x97a9, 0x97aa, 0x97ab, 0x97ac, 0x97ad, 0x97ae, 0x97af, 
+    0x97b0, 0x97b1, 0x97b2, 0x97b3, 0x97b4, 0x97b5, 0x97b6, 0x97b7, 
+    0x97b8, 0x97b9, 0x97ba, 0x97bb, 0x97bc, 0x97bd, 0x97be, 0x97bf, 
+    0x97c0, 0x97c1, 0x97c2, 0x97c3, 0x97c4, 0x97c5, 0x97c6, 0x97c7, 
+    0x97c8, 0x97c9, 0x97ca, 0x97cb, 0x97cc, 0x97cd, 0x97ce, 0x97cf, 
+    0x97d0, 0x97d1, 0x97d2, 0x97d3, 0x97d4, 0x97d5, 0x97d6, 0x97d7, 
+    0x97d8, 0x97d9, 0x97da, 0x97db, 0x97dc, 0x97dd, 0x97de, 0x97df, 
+    0x97e0, 0x97e1, 0x97e2, 0x97e3, 0x97e4, 0x97e5, 0x97e6, 0x97e7, 
+    0x97e8, 0x97e9, 0x97ea, 0x97eb, 0x97ec, 0x97ed, 0x97ee, 0x97ef, 
+    0x97f0, 0x97f1, 0x97f2, 0x97f3, 0x97f4, 0x97f5, 0x97f6, 0x97f7, 
+    0x97f8, 0x97f9, 0x97fa, 0x97fb, 0x97fc, 0x97fd, 0x97fe, 0x97ff, 
+    0x9800, 0x9801, 0x9802, 0x9803, 0x9804, 0x9805, 0x9806, 0x9807, 
+    0x9808, 0x9809, 0x980a, 0x980b, 0x980c, 0x980d, 0x980e, 0x980f, 
+    0x9810, 0x9811, 0x9812, 0x9813, 0x9814, 0x9815, 0x9816, 0x9817, 
+    0x9818, 0x9819, 0x981a, 0x981b, 0x981c, 0x981d, 0x981e, 0x981f, 
+    0x9820, 0x9821, 0x9822, 0x9823, 0x9824, 0x9825, 0x9826, 0x9827, 
+    0x9828, 0x9829, 0x982a, 0x982b, 0x982c, 0x982d, 0x982e, 0x982f, 
+    0x9830, 0x9831, 0x9832, 0x9833, 0x9834, 0x9835, 0x9836, 0x9837, 
+    0x9838, 0x9839, 0x983a, 0x983b, 0x983c, 0x983d, 0x983e, 0x983f, 
+    0x9840, 0x9841, 0x9842, 0x9843, 0x9844, 0x9845, 0x9846, 0x9847, 
+    0x9848, 0x9849, 0x984a, 0x984b, 0x984c, 0x984d, 0x984e, 0x984f, 
+    0x9850, 0x9851, 0x9852, 0x9853, 0x9854, 0x9855, 0x9856, 0x9857, 
+    0x9858, 0x9859, 0x985a, 0x985b, 0x985c, 0x985d, 0x985e, 0x985f, 
+    0x9860, 0x9861, 0x9862, 0x9863, 0x9864, 0x9865, 0x9866, 0x9867, 
+    0x9868, 0x9869, 0x986a, 0x986b, 0x986c, 0x986d, 0x986e, 0x986f, 
+    0x9870, 0x9871, 0x9872, 0x9873, 0x9874, 0x9875, 0x9876, 0x9877, 
+    0x9878, 0x9879, 0x987a, 0x987b, 0x987c, 0x987d, 0x987e, 0x987f, 
+    0x9880, 0x9881, 0x9882, 0x9883, 0x9884, 0x9885, 0x9886, 0x9887, 
+    0x9888, 0x9889, 0x988a, 0x988b, 0x988c, 0x988d, 0x988e, 0x988f, 
+    0x9890, 0x9891, 0x9892, 0x9893, 0x9894, 0x9895, 0x9896, 0x9897, 
+    0x9898, 0x9899, 0x989a, 0x989b, 0x989c, 0x989d, 0x989e, 0x989f, 
+    0x98a0, 0x98a1, 0x98a2, 0x98a3, 0x98a4, 0x98a5, 0x98a6, 0x98a7, 
+    0x98a8, 0x98a9, 0x98aa, 0x98ab, 0x98ac, 0x98ad, 0x98ae, 0x98af, 
+    0x98b0, 0x98b1, 0x98b2, 0x98b3, 0x98b4, 0x98b5, 0x98b6, 0x98b7, 
+    0x98b8, 0x98b9, 0x98ba, 0x98bb, 0x98bc, 0x98bd, 0x98be, 0x98bf, 
+    0x98c0, 0x98c1, 0x98c2, 0x98c3, 0x98c4, 0x98c5, 0x98c6, 0x98c7, 
+    0x98c8, 0x98c9, 0x98ca, 0x98cb, 0x98cc, 0x98cd, 0x98ce, 0x98cf, 
+    0x98d0, 0x98d1, 0x98d2, 0x98d3, 0x98d4, 0x98d5, 0x98d6, 0x98d7, 
+    0x98d8, 0x98d9, 0x98da, 0x98db, 0x98dc, 0x98dd, 0x98de, 0x98df, 
+    0x98e0, 0x98e1, 0x98e2, 0x98e3, 0x98e4, 0x98e5, 0x98e6, 0x98e7, 
+    0x98e8, 0x98e9, 0x98ea, 0x98eb, 0x98ec, 0x98ed, 0x98ee, 0x98ef, 
+    0x98f0, 0x98f1, 0x98f2, 0x98f3, 0x98f4, 0x98f5, 0x98f6, 0x98f7, 
+    0x98f8, 0x98f9, 0x98fa, 0x98fb, 0x98fc, 0x98fd, 0x98fe, 0x98ff, 
+    0x9900, 0x9901, 0x9902, 0x9903, 0x9904, 0x9905, 0x9906, 0x9907, 
+    0x9908, 0x9909, 0x990a, 0x990b, 0x990c, 0x990d, 0x990e, 0x990f, 
+    0x9910, 0x9911, 0x9912, 0x9913, 0x9914, 0x9915, 0x9916, 0x9917, 
+    0x9918, 0x9919, 0x991a, 0x991b, 0x991c, 0x991d, 0x991e, 0x991f, 
+    0x9920, 0x9921, 0x9922, 0x9923, 0x9924, 0x9925, 0x9926, 0x9927, 
+    0x9928, 0x9929, 0x992a, 0x992b, 0x992c, 0x992d, 0x992e, 0x992f, 
+    0x9930, 0x9931, 0x9932, 0x9933, 0x9934, 0x9935, 0x9936, 0x9937, 
+    0x9938, 0x9939, 0x993a, 0x993b, 0x993c, 0x993d, 0x993e, 0x993f, 
+    0x9940, 0x9941, 0x9942, 0x9943, 0x9944, 0x9945, 0x9946, 0x9947, 
+    0x9948, 0x9949, 0x994a, 0x994b, 0x994c, 0x994d, 0x994e, 0x994f, 
+    0x9950, 0x9951, 0x9952, 0x9953, 0x9954, 0x9955, 0x9956, 0x9957, 
+    0x9958, 0x9959, 0x995a, 0x995b, 0x995c, 0x995d, 0x995e, 0x995f, 
+    0x9960, 0x9961, 0x9962, 0x9963, 0x9964, 0x9965, 0x9966, 0x9967, 
+    0x9968, 0x9969, 0x996a, 0x996b, 0x996c, 0x996d, 0x996e, 0x996f, 
+    0x9970, 0x9971, 0x9972, 0x9973, 0x9974, 0x9975, 0x9976, 0x9977, 
+    0x9978, 0x9979, 0x997a, 0x997b, 0x997c, 0x997d, 0x997e, 0x997f, 
+    0x9980, 0x9981, 0x9982, 0x9983, 0x9984, 0x9985, 0x9986, 0x9987, 
+    0x9988, 0x9989, 0x998a, 0x998b, 0x998c, 0x998d, 0x998e, 0x998f, 
+    0x9990, 0x9991, 0x9992, 0x9993, 0x9994, 0x9995, 0x9996, 0x9997, 
+    0x9998, 0x9999, 0x999a, 0x999b, 0x999c, 0x999d, 0x999e, 0x999f, 
+    0x99a0, 0x99a1, 0x99a2, 0x99a3, 0x99a4, 0x99a5, 0x99a6, 0x99a7, 
+    0x99a8, 0x99a9, 0x99aa, 0x99ab, 0x99ac, 0x99ad, 0x99ae, 0x99af, 
+    0x99b0, 0x99b1, 0x99b2, 0x99b3, 0x99b4, 0x99b5, 0x99b6, 0x99b7, 
+    0x99b8, 0x99b9, 0x99ba, 0x99bb, 0x99bc, 0x99bd, 0x99be, 0x99bf, 
+    0x99c0, 0x99c1, 0x99c2, 0x99c3, 0x99c4, 0x99c5, 0x99c6, 0x99c7, 
+    0x99c8, 0x99c9, 0x99ca, 0x99cb, 0x99cc, 0x99cd, 0x99ce, 0x99cf, 
+    0x99d0, 0x99d1, 0x99d2, 0x99d3, 0x99d4, 0x99d5, 0x99d6, 0x99d7, 
+    0x99d8, 0x99d9, 0x99da, 0x99db, 0x99dc, 0x99dd, 0x99de, 0x99df, 
+    0x99e0, 0x99e1, 0x99e2, 0x99e3, 0x99e4, 0x99e5, 0x99e6, 0x99e7, 
+    0x99e8, 0x99e9, 0x99ea, 0x99eb, 0x99ec, 0x99ed, 0x99ee, 0x99ef, 
+    0x99f0, 0x99f1, 0x99f2, 0x99f3, 0x99f4, 0x99f5, 0x99f6, 0x99f7, 
+    0x99f8, 0x99f9, 0x99fa, 0x99fb, 0x99fc, 0x99fd, 0x99fe, 0x99ff, 
+    0x9a00, 0x9a01, 0x9a02, 0x9a03, 0x9a04, 0x9a05, 0x9a06, 0x9a07, 
+    0x9a08, 0x9a09, 0x9a0a, 0x9a0b, 0x9a0c, 0x9a0d, 0x9a0e, 0x9a0f, 
+    0x9a10, 0x9a11, 0x9a12, 0x9a13, 0x9a14, 0x9a15, 0x9a16, 0x9a17, 
+    0x9a18, 0x9a19, 0x9a1a, 0x9a1b, 0x9a1c, 0x9a1d, 0x9a1e, 0x9a1f, 
+    0x9a20, 0x9a21, 0x9a22, 0x9a23, 0x9a24, 0x9a25, 0x9a26, 0x9a27, 
+    0x9a28, 0x9a29, 0x9a2a, 0x9a2b, 0x9a2c, 0x9a2d, 0x9a2e, 0x9a2f, 
+    0x9a30, 0x9a31, 0x9a32, 0x9a33, 0x9a34, 0x9a35, 0x9a36, 0x9a37, 
+    0x9a38, 0x9a39, 0x9a3a, 0x9a3b, 0x9a3c, 0x9a3d, 0x9a3e, 0x9a3f, 
+    0x9a40, 0x9a41, 0x9a42, 0x9a43, 0x9a44, 0x9a45, 0x9a46, 0x9a47, 
+    0x9a48, 0x9a49, 0x9a4a, 0x9a4b, 0x9a4c, 0x9a4d, 0x9a4e, 0x9a4f, 
+    0x9a50, 0x9a51, 0x9a52, 0x9a53, 0x9a54, 0x9a55, 0x9a56, 0x9a57, 
+    0x9a58, 0x9a59, 0x9a5a, 0x9a5b, 0x9a5c, 0x9a5d, 0x9a5e, 0x9a5f, 
+    0x9a60, 0x9a61, 0x9a62, 0x9a63, 0x9a64, 0x9a65, 0x9a66, 0x9a67, 
+    0x9a68, 0x9a69, 0x9a6a, 0x9a6b, 0x9a6c, 0x9a6d, 0x9a6e, 0x9a6f, 
+    0x9a70, 0x9a71, 0x9a72, 0x9a73, 0x9a74, 0x9a75, 0x9a76, 0x9a77, 
+    0x9a78, 0x9a79, 0x9a7a, 0x9a7b, 0x9a7c, 0x9a7d, 0x9a7e, 0x9a7f, 
+    0x9a80, 0x9a81, 0x9a82, 0x9a83, 0x9a84, 0x9a85, 0x9a86, 0x9a87, 
+    0x9a88, 0x9a89, 0x9a8a, 0x9a8b, 0x9a8c, 0x9a8d, 0x9a8e, 0x9a8f, 
+    0x9a90, 0x9a91, 0x9a92, 0x9a93, 0x9a94, 0x9a95, 0x9a96, 0x9a97, 
+    0x9a98, 0x9a99, 0x9a9a, 0x9a9b, 0x9a9c, 0x9a9d, 0x9a9e, 0x9a9f, 
+    0x9aa0, 0x9aa1, 0x9aa2, 0x9aa3, 0x9aa4, 0x9aa5, 0x9aa6, 0x9aa7, 
+    0x9aa8, 0x9aa9, 0x9aaa, 0x9aab, 0x9aac, 0x9aad, 0x9aae, 0x9aaf, 
+    0x9ab0, 0x9ab1, 0x9ab2, 0x9ab3, 0x9ab4, 0x9ab5, 0x9ab6, 0x9ab7, 
+    0x9ab8, 0x9ab9, 0x9aba, 0x9abb, 0x9abc, 0x9abd, 0x9abe, 0x9abf, 
+    0x9ac0, 0x9ac1, 0x9ac2, 0x9ac3, 0x9ac4, 0x9ac5, 0x9ac6, 0x9ac7, 
+    0x9ac8, 0x9ac9, 0x9aca, 0x9acb, 0x9acc, 0x9acd, 0x9ace, 0x9acf, 
+    0x9ad0, 0x9ad1, 0x9ad2, 0x9ad3, 0x9ad4, 0x9ad5, 0x9ad6, 0x9ad7, 
+    0x9ad8, 0x9ad9, 0x9ada, 0x9adb, 0x9adc, 0x9add, 0x9ade, 0x9adf, 
+    0x9ae0, 0x9ae1, 0x9ae2, 0x9ae3, 0x9ae4, 0x9ae5, 0x9ae6, 0x9ae7, 
+    0x9ae8, 0x9ae9, 0x9aea, 0x9aeb, 0x9aec, 0x9aed, 0x9aee, 0x9aef, 
+    0x9af0, 0x9af1, 0x9af2, 0x9af3, 0x9af4, 0x9af5, 0x9af6, 0x9af7, 
+    0x9af8, 0x9af9, 0x9afa, 0x9afb, 0x9afc, 0x9afd, 0x9afe, 0x9aff, 
+    0x9b00, 0x9b01, 0x9b02, 0x9b03, 0x9b04, 0x9b05, 0x9b06, 0x9b07, 
+    0x9b08, 0x9b09, 0x9b0a, 0x9b0b, 0x9b0c, 0x9b0d, 0x9b0e, 0x9b0f, 
+    0x9b10, 0x9b11, 0x9b12, 0x9b13, 0x9b14, 0x9b15, 0x9b16, 0x9b17, 
+    0x9b18, 0x9b19, 0x9b1a, 0x9b1b, 0x9b1c, 0x9b1d, 0x9b1e, 0x9b1f, 
+    0x9b20, 0x9b21, 0x9b22, 0x9b23, 0x9b24, 0x9b25, 0x9b26, 0x9b27, 
+    0x9b28, 0x9b29, 0x9b2a, 0x9b2b, 0x9b2c, 0x9b2d, 0x9b2e, 0x9b2f, 
+    0x9b30, 0x9b31, 0x9b32, 0x9b33, 0x9b34, 0x9b35, 0x9b36, 0x9b37, 
+    0x9b38, 0x9b39, 0x9b3a, 0x9b3b, 0x9b3c, 0x9b3d, 0x9b3e, 0x9b3f, 
+    0x9b40, 0x9b41, 0x9b42, 0x9b43, 0x9b44, 0x9b45, 0x9b46, 0x9b47, 
+    0x9b48, 0x9b49, 0x9b4a, 0x9b4b, 0x9b4c, 0x9b4d, 0x9b4e, 0x9b4f, 
+    0x9b50, 0x9b51, 0x9b52, 0x9b53, 0x9b54, 0x9b55, 0x9b56, 0x9b57, 
+    0x9b58, 0x9b59, 0x9b5a, 0x9b5b, 0x9b5c, 0x9b5d, 0x9b5e, 0x9b5f, 
+    0x9b60, 0x9b61, 0x9b62, 0x9b63, 0x9b64, 0x9b65, 0x9b66, 0x9b67, 
+    0x9b68, 0x9b69, 0x9b6a, 0x9b6b, 0x9b6c, 0x9b6d, 0x9b6e, 0x9b6f, 
+    0x9b70, 0x9b71, 0x9b72, 0x9b73, 0x9b74, 0x9b75, 0x9b76, 0x9b77, 
+    0x9b78, 0x9b79, 0x9b7a, 0x9b7b, 0x9b7c, 0x9b7d, 0x9b7e, 0x9b7f, 
+    0x9b80, 0x9b81, 0x9b82, 0x9b83, 0x9b84, 0x9b85, 0x9b86, 0x9b87, 
+    0x9b88, 0x9b89, 0x9b8a, 0x9b8b, 0x9b8c, 0x9b8d, 0x9b8e, 0x9b8f, 
+    0x9b90, 0x9b91, 0x9b92, 0x9b93, 0x9b94, 0x9b95, 0x9b96, 0x9b97, 
+    0x9b98, 0x9b99, 0x9b9a, 0x9b9b, 0x9b9c, 0x9b9d, 0x9b9e, 0x9b9f, 
+    0x9ba0, 0x9ba1, 0x9ba2, 0x9ba3, 0x9ba4, 0x9ba5, 0x9ba6, 0x9ba7, 
+    0x9ba8, 0x9ba9, 0x9baa, 0x9bab, 0x9bac, 0x9bad, 0x9bae, 0x9baf, 
+    0x9bb0, 0x9bb1, 0x9bb2, 0x9bb3, 0x9bb4, 0x9bb5, 0x9bb6, 0x9bb7, 
+    0x9bb8, 0x9bb9, 0x9bba, 0x9bbb, 0x9bbc, 0x9bbd, 0x9bbe, 0x9bbf, 
+    0x9bc0, 0x9bc1, 0x9bc2, 0x9bc3, 0x9bc4, 0x9bc5, 0x9bc6, 0x9bc7, 
+    0x9bc8, 0x9bc9, 0x9bca, 0x9bcb, 0x9bcc, 0x9bcd, 0x9bce, 0x9bcf, 
+    0x9bd0, 0x9bd1, 0x9bd2, 0x9bd3, 0x9bd4, 0x9bd5, 0x9bd6, 0x9bd7, 
+    0x9bd8, 0x9bd9, 0x9bda, 0x9bdb, 0x9bdc, 0x9bdd, 0x9bde, 0x9bdf, 
+    0x9be0, 0x9be1, 0x9be2, 0x9be3, 0x9be4, 0x9be5, 0x9be6, 0x9be7, 
+    0x9be8, 0x9be9, 0x9bea, 0x9beb, 0x9bec, 0x9bed, 0x9bee, 0x9bef, 
+    0x9bf0, 0x9bf1, 0x9bf2, 0x9bf3, 0x9bf4, 0x9bf5, 0x9bf6, 0x9bf7, 
+    0x9bf8, 0x9bf9, 0x9bfa, 0x9bfb, 0x9bfc, 0x9bfd, 0x9bfe, 0x9bff, 
+    0x9c00, 0x9c01, 0x9c02, 0x9c03, 0x9c04, 0x9c05, 0x9c06, 0x9c07, 
+    0x9c08, 0x9c09, 0x9c0a, 0x9c0b, 0x9c0c, 0x9c0d, 0x9c0e, 0x9c0f, 
+    0x9c10, 0x9c11, 0x9c12, 0x9c13, 0x9c14, 0x9c15, 0x9c16, 0x9c17, 
+    0x9c18, 0x9c19, 0x9c1a, 0x9c1b, 0x9c1c, 0x9c1d, 0x9c1e, 0x9c1f, 
+    0x9c20, 0x9c21, 0x9c22, 0x9c23, 0x9c24, 0x9c25, 0x9c26, 0x9c27, 
+    0x9c28, 0x9c29, 0x9c2a, 0x9c2b, 0x9c2c, 0x9c2d, 0x9c2e, 0x9c2f, 
+    0x9c30, 0x9c31, 0x9c32, 0x9c33, 0x9c34, 0x9c35, 0x9c36, 0x9c37, 
+    0x9c38, 0x9c39, 0x9c3a, 0x9c3b, 0x9c3c, 0x9c3d, 0x9c3e, 0x9c3f, 
+    0x9c40, 0x9c41, 0x9c42, 0x9c43, 0x9c44, 0x9c45, 0x9c46, 0x9c47, 
+    0x9c48, 0x9c49, 0x9c4a, 0x9c4b, 0x9c4c, 0x9c4d, 0x9c4e, 0x9c4f, 
+    0x9c50, 0x9c51, 0x9c52, 0x9c53, 0x9c54, 0x9c55, 0x9c56, 0x9c57, 
+    0x9c58, 0x9c59, 0x9c5a, 0x9c5b, 0x9c5c, 0x9c5d, 0x9c5e, 0x9c5f, 
+    0x9c60, 0x9c61, 0x9c62, 0x9c63, 0x9c64, 0x9c65, 0x9c66, 0x9c67, 
+    0x9c68, 0x9c69, 0x9c6a, 0x9c6b, 0x9c6c, 0x9c6d, 0x9c6e, 0x9c6f, 
+    0x9c70, 0x9c71, 0x9c72, 0x9c73, 0x9c74, 0x9c75, 0x9c76, 0x9c77, 
+    0x9c78, 0x9c79, 0x9c7a, 0x9c7b, 0x9c7c, 0x9c7d, 0x9c7e, 0x9c7f, 
+    0x9c80, 0x9c81, 0x9c82, 0x9c83, 0x9c84, 0x9c85, 0x9c86, 0x9c87, 
+    0x9c88, 0x9c89, 0x9c8a, 0x9c8b, 0x9c8c, 0x9c8d, 0x9c8e, 0x9c8f, 
+    0x9c90, 0x9c91, 0x9c92, 0x9c93, 0x9c94, 0x9c95, 0x9c96, 0x9c97, 
+    0x9c98, 0x9c99, 0x9c9a, 0x9c9b, 0x9c9c, 0x9c9d, 0x9c9e, 0x9c9f, 
+    0x9ca0, 0x9ca1, 0x9ca2, 0x9ca3, 0x9ca4, 0x9ca5, 0x9ca6, 0x9ca7, 
+    0x9ca8, 0x9ca9, 0x9caa, 0x9cab, 0x9cac, 0x9cad, 0x9cae, 0x9caf, 
+    0x9cb0, 0x9cb1, 0x9cb2, 0x9cb3, 0x9cb4, 0x9cb5, 0x9cb6, 0x9cb7, 
+    0x9cb8, 0x9cb9, 0x9cba, 0x9cbb, 0x9cbc, 0x9cbd, 0x9cbe, 0x9cbf, 
+    0x9cc0, 0x9cc1, 0x9cc2, 0x9cc3, 0x9cc4, 0x9cc5, 0x9cc6, 0x9cc7, 
+    0x9cc8, 0x9cc9, 0x9cca, 0x9ccb, 0x9ccc, 0x9ccd, 0x9cce, 0x9ccf, 
+    0x9cd0, 0x9cd1, 0x9cd2, 0x9cd3, 0x9cd4, 0x9cd5, 0x9cd6, 0x9cd7, 
+    0x9cd8, 0x9cd9, 0x9cda, 0x9cdb, 0x9cdc, 0x9cdd, 0x9cde, 0x9cdf, 
+    0x9ce0, 0x9ce1, 0x9ce2, 0x9ce3, 0x9ce4, 0x9ce5, 0x9ce6, 0x9ce7, 
+    0x9ce8, 0x9ce9, 0x9cea, 0x9ceb, 0x9cec, 0x9ced, 0x9cee, 0x9cef, 
+    0x9cf0, 0x9cf1, 0x9cf2, 0x9cf3, 0x9cf4, 0x9cf5, 0x9cf6, 0x9cf7, 
+    0x9cf8, 0x9cf9, 0x9cfa, 0x9cfb, 0x9cfc, 0x9cfd, 0x9cfe, 0x9cff, 
+    0x9d00, 0x9d01, 0x9d02, 0x9d03, 0x9d04, 0x9d05, 0x9d06, 0x9d07, 
+    0x9d08, 0x9d09, 0x9d0a, 0x9d0b, 0x9d0c, 0x9d0d, 0x9d0e, 0x9d0f, 
+    0x9d10, 0x9d11, 0x9d12, 0x9d13, 0x9d14, 0x9d15, 0x9d16, 0x9d17, 
+    0x9d18, 0x9d19, 0x9d1a, 0x9d1b, 0x9d1c, 0x9d1d, 0x9d1e, 0x9d1f, 
+    0x9d20, 0x9d21, 0x9d22, 0x9d23, 0x9d24, 0x9d25, 0x9d26, 0x9d27, 
+    0x9d28, 0x9d29, 0x9d2a, 0x9d2b, 0x9d2c, 0x9d2d, 0x9d2e, 0x9d2f, 
+    0x9d30, 0x9d31, 0x9d32, 0x9d33, 0x9d34, 0x9d35, 0x9d36, 0x9d37, 
+    0x9d38, 0x9d39, 0x9d3a, 0x9d3b, 0x9d3c, 0x9d3d, 0x9d3e, 0x9d3f, 
+    0x9d40, 0x9d41, 0x9d42, 0x9d43, 0x9d44, 0x9d45, 0x9d46, 0x9d47, 
+    0x9d48, 0x9d49, 0x9d4a, 0x9d4b, 0x9d4c, 0x9d4d, 0x9d4e, 0x9d4f, 
+    0x9d50, 0x9d51, 0x9d52, 0x9d53, 0x9d54, 0x9d55, 0x9d56, 0x9d57, 
+    0x9d58, 0x9d59, 0x9d5a, 0x9d5b, 0x9d5c, 0x9d5d, 0x9d5e, 0x9d5f, 
+    0x9d60, 0x9d61, 0x9d62, 0x9d63, 0x9d64, 0x9d65, 0x9d66, 0x9d67, 
+    0x9d68, 0x9d69, 0x9d6a, 0x9d6b, 0x9d6c, 0x9d6d, 0x9d6e, 0x9d6f, 
+    0x9d70, 0x9d71, 0x9d72, 0x9d73, 0x9d74, 0x9d75, 0x9d76, 0x9d77, 
+    0x9d78, 0x9d79, 0x9d7a, 0x9d7b, 0x9d7c, 0x9d7d, 0x9d7e, 0x9d7f, 
+    0x9d80, 0x9d81, 0x9d82, 0x9d83, 0x9d84, 0x9d85, 0x9d86, 0x9d87, 
+    0x9d88, 0x9d89, 0x9d8a, 0x9d8b, 0x9d8c, 0x9d8d, 0x9d8e, 0x9d8f, 
+    0x9d90, 0x9d91, 0x9d92, 0x9d93, 0x9d94, 0x9d95, 0x9d96, 0x9d97, 
+    0x9d98, 0x9d99, 0x9d9a, 0x9d9b, 0x9d9c, 0x9d9d, 0x9d9e, 0x9d9f, 
+    0x9da0, 0x9da1, 0x9da2, 0x9da3, 0x9da4, 0x9da5, 0x9da6, 0x9da7, 
+    0x9da8, 0x9da9, 0x9daa, 0x9dab, 0x9dac, 0x9dad, 0x9dae, 0x9daf, 
+    0x9db0, 0x9db1, 0x9db2, 0x9db3, 0x9db4, 0x9db5, 0x9db6, 0x9db7, 
+    0x9db8, 0x9db9, 0x9dba, 0x9dbb, 0x9dbc, 0x9dbd, 0x9dbe, 0x9dbf, 
+    0x9dc0, 0x9dc1, 0x9dc2, 0x9dc3, 0x9dc4, 0x9dc5, 0x9dc6, 0x9dc7, 
+    0x9dc8, 0x9dc9, 0x9dca, 0x9dcb, 0x9dcc, 0x9dcd, 0x9dce, 0x9dcf, 
+    0x9dd0, 0x9dd1, 0x9dd2, 0x9dd3, 0x9dd4, 0x9dd5, 0x9dd6, 0x9dd7, 
+    0x9dd8, 0x9dd9, 0x9dda, 0x9ddb, 0x9ddc, 0x9ddd, 0x9dde, 0x9ddf, 
+    0x9de0, 0x9de1, 0x9de2, 0x9de3, 0x9de4, 0x9de5, 0x9de6, 0x9de7, 
+    0x9de8, 0x9de9, 0x9dea, 0x9deb, 0x9dec, 0x9ded, 0x9dee, 0x9def, 
+    0x9df0, 0x9df1, 0x9df2, 0x9df3, 0x9df4, 0x9df5, 0x9df6, 0x9df7, 
+    0x9df8, 0x9df9, 0x9dfa, 0x9dfb, 0x9dfc, 0x9dfd, 0x9dfe, 0x9dff, 
+    0x9e00, 0x9e01, 0x9e02, 0x9e03, 0x9e04, 0x9e05, 0x9e06, 0x9e07, 
+    0x9e08, 0x9e09, 0x9e0a, 0x9e0b, 0x9e0c, 0x9e0d, 0x9e0e, 0x9e0f, 
+    0x9e10, 0x9e11, 0x9e12, 0x9e13, 0x9e14, 0x9e15, 0x9e16, 0x9e17, 
+    0x9e18, 0x9e19, 0x9e1a, 0x9e1b, 0x9e1c, 0x9e1d, 0x9e1e, 0x9e1f, 
+    0x9e20, 0x9e21, 0x9e22, 0x9e23, 0x9e24, 0x9e25, 0x9e26, 0x9e27, 
+    0x9e28, 0x9e29, 0x9e2a, 0x9e2b, 0x9e2c, 0x9e2d, 0x9e2e, 0x9e2f, 
+    0x9e30, 0x9e31, 0x9e32, 0x9e33, 0x9e34, 0x9e35, 0x9e36, 0x9e37, 
+    0x9e38, 0x9e39, 0x9e3a, 0x9e3b, 0x9e3c, 0x9e3d, 0x9e3e, 0x9e3f, 
+    0x9e40, 0x9e41, 0x9e42, 0x9e43, 0x9e44, 0x9e45, 0x9e46, 0x9e47, 
+    0x9e48, 0x9e49, 0x9e4a, 0x9e4b, 0x9e4c, 0x9e4d, 0x9e4e, 0x9e4f, 
+    0x9e50, 0x9e51, 0x9e52, 0x9e53, 0x9e54, 0x9e55, 0x9e56, 0x9e57, 
+    0x9e58, 0x9e59, 0x9e5a, 0x9e5b, 0x9e5c, 0x9e5d, 0x9e5e, 0x9e5f, 
+    0x9e60, 0x9e61, 0x9e62, 0x9e63, 0x9e64, 0x9e65, 0x9e66, 0x9e67, 
+    0x9e68, 0x9e69, 0x9e6a, 0x9e6b, 0x9e6c, 0x9e6d, 0x9e6e, 0x9e6f, 
+    0x9e70, 0x9e71, 0x9e72, 0x9e73, 0x9e74, 0x9e75, 0x9e76, 0x9e77, 
+    0x9e78, 0x9e79, 0x9e7a, 0x9e7b, 0x9e7c, 0x9e7d, 0x9e7e, 0x9e7f, 
+    0x9e80, 0x9e81, 0x9e82, 0x9e83, 0x9e84, 0x9e85, 0x9e86, 0x9e87, 
+    0x9e88, 0x9e89, 0x9e8a, 0x9e8b, 0x9e8c, 0x9e8d, 0x9e8e, 0x9e8f, 
+    0x9e90, 0x9e91, 0x9e92, 0x9e93, 0x9e94, 0x9e95, 0x9e96, 0x9e97, 
+    0x9e98, 0x9e99, 0x9e9a, 0x9e9b, 0x9e9c, 0x9e9d, 0x9e9e, 0x9e9f, 
+    0x9ea0, 0x9ea1, 0x9ea2, 0x9ea3, 0x9ea4, 0x9ea5, 0x9ea6, 0x9ea7, 
+    0x9ea8, 0x9ea9, 0x9eaa, 0x9eab, 0x9eac, 0x9ead, 0x9eae, 0x9eaf, 
+    0x9eb0, 0x9eb1, 0x9eb2, 0x9eb3, 0x9eb4, 0x9eb5, 0x9eb6, 0x9eb7, 
+    0x9eb8, 0x9eb9, 0x9eba, 0x9ebb, 0x9ebc, 0x9ebd, 0x9ebe, 0x9ebf, 
+    0x9ec0, 0x9ec1, 0x9ec2, 0x9ec3, 0x9ec4, 0x9ec5, 0x9ec6, 0x9ec7, 
+    0x9ec8, 0x9ec9, 0x9eca, 0x9ecb, 0x9ecc, 0x9ecd, 0x9ece, 0x9ecf, 
+    0x9ed0, 0x9ed1, 0x9ed2, 0x9ed3, 0x9ed4, 0x9ed5, 0x9ed6, 0x9ed7, 
+    0x9ed8, 0x9ed9, 0x9eda, 0x9edb, 0x9edc, 0x9edd, 0x9ede, 0x9edf, 
+    0x9ee0, 0x9ee1, 0x9ee2, 0x9ee3, 0x9ee4, 0x9ee5, 0x9ee6, 0x9ee7, 
+    0x9ee8, 0x9ee9, 0x9eea, 0x9eeb, 0x9eec, 0x9eed, 0x9eee, 0x9eef, 
+    0x9ef0, 0x9ef1, 0x9ef2, 0x9ef3, 0x9ef4, 0x9ef5, 0x9ef6, 0x9ef7, 
+    0x9ef8, 0x9ef9, 0x9efa, 0x9efb, 0x9efc, 0x9efd, 0x9efe, 0x9eff, 
+    0x9f00, 0x9f01, 0x9f02, 0x9f03, 0x9f04, 0x9f05, 0x9f06, 0x9f07, 
+    0x9f08, 0x9f09, 0x9f0a, 0x9f0b, 0x9f0c, 0x9f0d, 0x9f0e, 0x9f0f, 
+    0x9f10, 0x9f11, 0x9f12, 0x9f13, 0x9f14, 0x9f15, 0x9f16, 0x9f17, 
+    0x9f18, 0x9f19, 0x9f1a, 0x9f1b, 0x9f1c, 0x9f1d, 0x9f1e, 0x9f1f, 
+    0x9f20, 0x9f21, 0x9f22, 0x9f23, 0x9f24, 0x9f25, 0x9f26, 0x9f27, 
+    0x9f28, 0x9f29, 0x9f2a, 0x9f2b, 0x9f2c, 0x9f2d, 0x9f2e, 0x9f2f, 
+    0x9f30, 0x9f31, 0x9f32, 0x9f33, 0x9f34, 0x9f35, 0x9f36, 0x9f37, 
+    0x9f38, 0x9f39, 0x9f3a, 0x9f3b, 0x9f3c, 0x9f3d, 0x9f3e, 0x9f3f, 
+    0x9f40, 0x9f41, 0x9f42, 0x9f43, 0x9f44, 0x9f45, 0x9f46, 0x9f47, 
+    0x9f48, 0x9f49, 0x9f4a, 0x9f4b, 0x9f4c, 0x9f4d, 0x9f4e, 0x9f4f, 
+    0x9f50, 0x9f51, 0x9f52, 0x9f53, 0x9f54, 0x9f55, 0x9f56, 0x9f57, 
+    0x9f58, 0x9f59, 0x9f5a, 0x9f5b, 0x9f5c, 0x9f5d, 0x9f5e, 0x9f5f, 
+    0x9f60, 0x9f61, 0x9f62, 0x9f63, 0x9f64, 0x9f65, 0x9f66, 0x9f67, 
+    0x9f68, 0x9f69, 0x9f6a, 0x9f6b, 0x9f6c, 0x9f6d, 0x9f6e, 0x9f6f, 
+    0x9f70, 0x9f71, 0x9f72, 0x9f73, 0x9f74, 0x9f75, 0x9f76, 0x9f77, 
+    0x9f78, 0x9f79, 0x9f7a, 0x9f7b, 0x9f7c, 0x9f7d, 0x9f7e, 0x9f7f, 
+    0x9f80, 0x9f81, 0x9f82, 0x9f83, 0x9f84, 0x9f85, 0x9f86, 0x9f87, 
+    0x9f88, 0x9f89, 0x9f8a, 0x9f8b, 0x9f8c, 0x9f8d, 0x9f8e, 0x9f8f, 
+    0x9f90, 0x9f91, 0x9f92, 0x9f93, 0x9f94, 0x9f95, 0x9f96, 0x9f97, 
+    0x9f98, 0x9f99, 0x9f9a, 0x9f9b, 0x9f9c, 0x9f9d, 0x9f9e, 0x9f9f, 
+    0x9fa0, 0x9fa1, 0x9fa2, 0x9fa3, 0x9fa4, 0x9fa5, 0x9fa6, 0x9fa7, 
+    0x9fa8, 0x9fa9, 0x9faa, 0x9fab, 0x9fac, 0x9fad, 0x9fae, 0x9faf, 
+    0x9fb0, 0x9fb1, 0x9fb2, 0x9fb3, 0x9fb4, 0x9fb5, 0x9fb6, 0x9fb7, 
+    0x9fb8, 0x9fb9, 0x9fba, 0x9fbb, 0x9fbc, 0x9fbd, 0x9fbe, 0x9fbf, 
+    0x9fc0, 0x9fc1, 0x9fc2, 0x9fc3, 0x9fc4, 0x9fc5, 0x9fc6, 0x9fc7, 
+    0x9fc8, 0x9fc9, 0x9fca, 0x9fcb, 0x9fcc, 0x9fcd, 0x9fce, 0x9fcf, 
+    0x9fd0, 0x9fd1, 0x9fd2, 0x9fd3, 0x9fd4, 0x9fd5, 0x9fd6, 0x9fd7, 
+    0x9fd8, 0x9fd9, 0x9fda, 0x9fdb, 0x9fdc, 0x9fdd, 0x9fde, 0x9fdf, 
+    0x9fe0, 0x9fe1, 0x9fe2, 0x9fe3, 0x9fe4, 0x9fe5, 0x9fe6, 0x9fe7, 
+    0x9fe8, 0x9fe9, 0x9fea, 0x9feb, 0x9fec, 0x9fed, 0x9fee, 0x9fef, 
+    0x9ff0, 0x9ff1, 0x9ff2, 0x9ff3, 0x9ff4, 0x9ff5, 0x9ff6, 0x9ff7, 
+    0x9ff8, 0x9ff9, 0x9ffa, 0x9ffb, 0x9ffc, 0x9ffd, 0x9ffe, 0x9fff, 
+    0xa000, 0xa001, 0xa002, 0xa003, 0xa004, 0xa005, 0xa006, 0xa007, 
+    0xa008, 0xa009, 0xa00a, 0xa00b, 0xa00c, 0xa00d, 0xa00e, 0xa00f, 
+    0xa010, 0xa011, 0xa012, 0xa013, 0xa014, 0xa015, 0xa016, 0xa017, 
+    0xa018, 0xa019, 0xa01a, 0xa01b, 0xa01c, 0xa01d, 0xa01e, 0xa01f, 
+    0xa020, 0xa021, 0xa022, 0xa023, 0xa024, 0xa025, 0xa026, 0xa027, 
+    0xa028, 0xa029, 0xa02a, 0xa02b, 0xa02c, 0xa02d, 0xa02e, 0xa02f, 
+    0xa030, 0xa031, 0xa032, 0xa033, 0xa034, 0xa035, 0xa036, 0xa037, 
+    0xa038, 0xa039, 0xa03a, 0xa03b, 0xa03c, 0xa03d, 0xa03e, 0xa03f, 
+    0xa040, 0xa041, 0xa042, 0xa043, 0xa044, 0xa045, 0xa046, 0xa047, 
+    0xa048, 0xa049, 0xa04a, 0xa04b, 0xa04c, 0xa04d, 0xa04e, 0xa04f, 
+    0xa050, 0xa051, 0xa052, 0xa053, 0xa054, 0xa055, 0xa056, 0xa057, 
+    0xa058, 0xa059, 0xa05a, 0xa05b, 0xa05c, 0xa05d, 0xa05e, 0xa05f, 
+    0xa060, 0xa061, 0xa062, 0xa063, 0xa064, 0xa065, 0xa066, 0xa067, 
+    0xa068, 0xa069, 0xa06a, 0xa06b, 0xa06c, 0xa06d, 0xa06e, 0xa06f, 
+    0xa070, 0xa071, 0xa072, 0xa073, 0xa074, 0xa075, 0xa076, 0xa077, 
+    0xa078, 0xa079, 0xa07a, 0xa07b, 0xa07c, 0xa07d, 0xa07e, 0xa07f, 
+    0xa080, 0xa081, 0xa082, 0xa083, 0xa084, 0xa085, 0xa086, 0xa087, 
+    0xa088, 0xa089, 0xa08a, 0xa08b, 0xa08c, 0xa08d, 0xa08e, 0xa08f, 
+    0xa090, 0xa091, 0xa092, 0xa093, 0xa094, 0xa095, 0xa096, 0xa097, 
+    0xa098, 0xa099, 0xa09a, 0xa09b, 0xa09c, 0xa09d, 0xa09e, 0xa09f, 
+    0xa0a0, 0xa0a1, 0xa0a2, 0xa0a3, 0xa0a4, 0xa0a5, 0xa0a6, 0xa0a7, 
+    0xa0a8, 0xa0a9, 0xa0aa, 0xa0ab, 0xa0ac, 0xa0ad, 0xa0ae, 0xa0af, 
+    0xa0b0, 0xa0b1, 0xa0b2, 0xa0b3, 0xa0b4, 0xa0b5, 0xa0b6, 0xa0b7, 
+    0xa0b8, 0xa0b9, 0xa0ba, 0xa0bb, 0xa0bc, 0xa0bd, 0xa0be, 0xa0bf, 
+    0xa0c0, 0xa0c1, 0xa0c2, 0xa0c3, 0xa0c4, 0xa0c5, 0xa0c6, 0xa0c7, 
+    0xa0c8, 0xa0c9, 0xa0ca, 0xa0cb, 0xa0cc, 0xa0cd, 0xa0ce, 0xa0cf, 
+    0xa0d0, 0xa0d1, 0xa0d2, 0xa0d3, 0xa0d4, 0xa0d5, 0xa0d6, 0xa0d7, 
+    0xa0d8, 0xa0d9, 0xa0da, 0xa0db, 0xa0dc, 0xa0dd, 0xa0de, 0xa0df, 
+    0xa0e0, 0xa0e1, 0xa0e2, 0xa0e3, 0xa0e4, 0xa0e5, 0xa0e6, 0xa0e7, 
+    0xa0e8, 0xa0e9, 0xa0ea, 0xa0eb, 0xa0ec, 0xa0ed, 0xa0ee, 0xa0ef, 
+    0xa0f0, 0xa0f1, 0xa0f2, 0xa0f3, 0xa0f4, 0xa0f5, 0xa0f6, 0xa0f7, 
+    0xa0f8, 0xa0f9, 0xa0fa, 0xa0fb, 0xa0fc, 0xa0fd, 0xa0fe, 0xa0ff, 
+    0xa100, 0xa101, 0xa102, 0xa103, 0xa104, 0xa105, 0xa106, 0xa107, 
+    0xa108, 0xa109, 0xa10a, 0xa10b, 0xa10c, 0xa10d, 0xa10e, 0xa10f, 
+    0xa110, 0xa111, 0xa112, 0xa113, 0xa114, 0xa115, 0xa116, 0xa117, 
+    0xa118, 0xa119, 0xa11a, 0xa11b, 0xa11c, 0xa11d, 0xa11e, 0xa11f, 
+    0xa120, 0xa121, 0xa122, 0xa123, 0xa124, 0xa125, 0xa126, 0xa127, 
+    0xa128, 0xa129, 0xa12a, 0xa12b, 0xa12c, 0xa12d, 0xa12e, 0xa12f, 
+    0xa130, 0xa131, 0xa132, 0xa133, 0xa134, 0xa135, 0xa136, 0xa137, 
+    0xa138, 0xa139, 0xa13a, 0xa13b, 0xa13c, 0xa13d, 0xa13e, 0xa13f, 
+    0xa140, 0xa141, 0xa142, 0xa143, 0xa144, 0xa145, 0xa146, 0xa147, 
+    0xa148, 0xa149, 0xa14a, 0xa14b, 0xa14c, 0xa14d, 0xa14e, 0xa14f, 
+    0xa150, 0xa151, 0xa152, 0xa153, 0xa154, 0xa155, 0xa156, 0xa157, 
+    0xa158, 0xa159, 0xa15a, 0xa15b, 0xa15c, 0xa15d, 0xa15e, 0xa15f, 
+    0xa160, 0xa161, 0xa162, 0xa163, 0xa164, 0xa165, 0xa166, 0xa167, 
+    0xa168, 0xa169, 0xa16a, 0xa16b, 0xa16c, 0xa16d, 0xa16e, 0xa16f, 
+    0xa170, 0xa171, 0xa172, 0xa173, 0xa174, 0xa175, 0xa176, 0xa177, 
+    0xa178, 0xa179, 0xa17a, 0xa17b, 0xa17c, 0xa17d, 0xa17e, 0xa17f, 
+    0xa180, 0xa181, 0xa182, 0xa183, 0xa184, 0xa185, 0xa186, 0xa187, 
+    0xa188, 0xa189, 0xa18a, 0xa18b, 0xa18c, 0xa18d, 0xa18e, 0xa18f, 
+    0xa190, 0xa191, 0xa192, 0xa193, 0xa194, 0xa195, 0xa196, 0xa197, 
+    0xa198, 0xa199, 0xa19a, 0xa19b, 0xa19c, 0xa19d, 0xa19e, 0xa19f, 
+    0xa1a0, 0xa1a1, 0xa1a2, 0xa1a3, 0xa1a4, 0xa1a5, 0xa1a6, 0xa1a7, 
+    0xa1a8, 0xa1a9, 0xa1aa, 0xa1ab, 0xa1ac, 0xa1ad, 0xa1ae, 0xa1af, 
+    0xa1b0, 0xa1b1, 0xa1b2, 0xa1b3, 0xa1b4, 0xa1b5, 0xa1b6, 0xa1b7, 
+    0xa1b8, 0xa1b9, 0xa1ba, 0xa1bb, 0xa1bc, 0xa1bd, 0xa1be, 0xa1bf, 
+    0xa1c0, 0xa1c1, 0xa1c2, 0xa1c3, 0xa1c4, 0xa1c5, 0xa1c6, 0xa1c7, 
+    0xa1c8, 0xa1c9, 0xa1ca, 0xa1cb, 0xa1cc, 0xa1cd, 0xa1ce, 0xa1cf, 
+    0xa1d0, 0xa1d1, 0xa1d2, 0xa1d3, 0xa1d4, 0xa1d5, 0xa1d6, 0xa1d7, 
+    0xa1d8, 0xa1d9, 0xa1da, 0xa1db, 0xa1dc, 0xa1dd, 0xa1de, 0xa1df, 
+    0xa1e0, 0xa1e1, 0xa1e2, 0xa1e3, 0xa1e4, 0xa1e5, 0xa1e6, 0xa1e7, 
+    0xa1e8, 0xa1e9, 0xa1ea, 0xa1eb, 0xa1ec, 0xa1ed, 0xa1ee, 0xa1ef, 
+    0xa1f0, 0xa1f1, 0xa1f2, 0xa1f3, 0xa1f4, 0xa1f5, 0xa1f6, 0xa1f7, 
+    0xa1f8, 0xa1f9, 0xa1fa, 0xa1fb, 0xa1fc, 0xa1fd, 0xa1fe, 0xa1ff, 
+    0xa200, 0xa201, 0xa202, 0xa203, 0xa204, 0xa205, 0xa206, 0xa207, 
+    0xa208, 0xa209, 0xa20a, 0xa20b, 0xa20c, 0xa20d, 0xa20e, 0xa20f, 
+    0xa210, 0xa211, 0xa212, 0xa213, 0xa214, 0xa215, 0xa216, 0xa217, 
+    0xa218, 0xa219, 0xa21a, 0xa21b, 0xa21c, 0xa21d, 0xa21e, 0xa21f, 
+    0xa220, 0xa221, 0xa222, 0xa223, 0xa224, 0xa225, 0xa226, 0xa227, 
+    0xa228, 0xa229, 0xa22a, 0xa22b, 0xa22c, 0xa22d, 0xa22e, 0xa22f, 
+    0xa230, 0xa231, 0xa232, 0xa233, 0xa234, 0xa235, 0xa236, 0xa237, 
+    0xa238, 0xa239, 0xa23a, 0xa23b, 0xa23c, 0xa23d, 0xa23e, 0xa23f, 
+    0xa240, 0xa241, 0xa242, 0xa243, 0xa244, 0xa245, 0xa246, 0xa247, 
+    0xa248, 0xa249, 0xa24a, 0xa24b, 0xa24c, 0xa24d, 0xa24e, 0xa24f, 
+    0xa250, 0xa251, 0xa252, 0xa253, 0xa254, 0xa255, 0xa256, 0xa257, 
+    0xa258, 0xa259, 0xa25a, 0xa25b, 0xa25c, 0xa25d, 0xa25e, 0xa25f, 
+    0xa260, 0xa261, 0xa262, 0xa263, 0xa264, 0xa265, 0xa266, 0xa267, 
+    0xa268, 0xa269, 0xa26a, 0xa26b, 0xa26c, 0xa26d, 0xa26e, 0xa26f, 
+    0xa270, 0xa271, 0xa272, 0xa273, 0xa274, 0xa275, 0xa276, 0xa277, 
+    0xa278, 0xa279, 0xa27a, 0xa27b, 0xa27c, 0xa27d, 0xa27e, 0xa27f, 
+    0xa280, 0xa281, 0xa282, 0xa283, 0xa284, 0xa285, 0xa286, 0xa287, 
+    0xa288, 0xa289, 0xa28a, 0xa28b, 0xa28c, 0xa28d, 0xa28e, 0xa28f, 
+    0xa290, 0xa291, 0xa292, 0xa293, 0xa294, 0xa295, 0xa296, 0xa297, 
+    0xa298, 0xa299, 0xa29a, 0xa29b, 0xa29c, 0xa29d, 0xa29e, 0xa29f, 
+    0xa2a0, 0xa2a1, 0xa2a2, 0xa2a3, 0xa2a4, 0xa2a5, 0xa2a6, 0xa2a7, 
+    0xa2a8, 0xa2a9, 0xa2aa, 0xa2ab, 0xa2ac, 0xa2ad, 0xa2ae, 0xa2af, 
+    0xa2b0, 0xa2b1, 0xa2b2, 0xa2b3, 0xa2b4, 0xa2b5, 0xa2b6, 0xa2b7, 
+    0xa2b8, 0xa2b9, 0xa2ba, 0xa2bb, 0xa2bc, 0xa2bd, 0xa2be, 0xa2bf, 
+    0xa2c0, 0xa2c1, 0xa2c2, 0xa2c3, 0xa2c4, 0xa2c5, 0xa2c6, 0xa2c7, 
+    0xa2c8, 0xa2c9, 0xa2ca, 0xa2cb, 0xa2cc, 0xa2cd, 0xa2ce, 0xa2cf, 
+    0xa2d0, 0xa2d1, 0xa2d2, 0xa2d3, 0xa2d4, 0xa2d5, 0xa2d6, 0xa2d7, 
+    0xa2d8, 0xa2d9, 0xa2da, 0xa2db, 0xa2dc, 0xa2dd, 0xa2de, 0xa2df, 
+    0xa2e0, 0xa2e1, 0xa2e2, 0xa2e3, 0xa2e4, 0xa2e5, 0xa2e6, 0xa2e7, 
+    0xa2e8, 0xa2e9, 0xa2ea, 0xa2eb, 0xa2ec, 0xa2ed, 0xa2ee, 0xa2ef, 
+    0xa2f0, 0xa2f1, 0xa2f2, 0xa2f3, 0xa2f4, 0xa2f5, 0xa2f6, 0xa2f7, 
+    0xa2f8, 0xa2f9, 0xa2fa, 0xa2fb, 0xa2fc, 0xa2fd, 0xa2fe, 0xa2ff, 
+    0xa300, 0xa301, 0xa302, 0xa303, 0xa304, 0xa305, 0xa306, 0xa307, 
+    0xa308, 0xa309, 0xa30a, 0xa30b, 0xa30c, 0xa30d, 0xa30e, 0xa30f, 
+    0xa310, 0xa311, 0xa312, 0xa313, 0xa314, 0xa315, 0xa316, 0xa317, 
+    0xa318, 0xa319, 0xa31a, 0xa31b, 0xa31c, 0xa31d, 0xa31e, 0xa31f, 
+    0xa320, 0xa321, 0xa322, 0xa323, 0xa324, 0xa325, 0xa326, 0xa327, 
+    0xa328, 0xa329, 0xa32a, 0xa32b, 0xa32c, 0xa32d, 0xa32e, 0xa32f, 
+    0xa330, 0xa331, 0xa332, 0xa333, 0xa334, 0xa335, 0xa336, 0xa337, 
+    0xa338, 0xa339, 0xa33a, 0xa33b, 0xa33c, 0xa33d, 0xa33e, 0xa33f, 
+    0xa340, 0xa341, 0xa342, 0xa343, 0xa344, 0xa345, 0xa346, 0xa347, 
+    0xa348, 0xa349, 0xa34a, 0xa34b, 0xa34c, 0xa34d, 0xa34e, 0xa34f, 
+    0xa350, 0xa351, 0xa352, 0xa353, 0xa354, 0xa355, 0xa356, 0xa357, 
+    0xa358, 0xa359, 0xa35a, 0xa35b, 0xa35c, 0xa35d, 0xa35e, 0xa35f, 
+    0xa360, 0xa361, 0xa362, 0xa363, 0xa364, 0xa365, 0xa366, 0xa367, 
+    0xa368, 0xa369, 0xa36a, 0xa36b, 0xa36c, 0xa36d, 0xa36e, 0xa36f, 
+    0xa370, 0xa371, 0xa372, 0xa373, 0xa374, 0xa375, 0xa376, 0xa377, 
+    0xa378, 0xa379, 0xa37a, 0xa37b, 0xa37c, 0xa37d, 0xa37e, 0xa37f, 
+    0xa380, 0xa381, 0xa382, 0xa383, 0xa384, 0xa385, 0xa386, 0xa387, 
+    0xa388, 0xa389, 0xa38a, 0xa38b, 0xa38c, 0xa38d, 0xa38e, 0xa38f, 
+    0xa390, 0xa391, 0xa392, 0xa393, 0xa394, 0xa395, 0xa396, 0xa397, 
+    0xa398, 0xa399, 0xa39a, 0xa39b, 0xa39c, 0xa39d, 0xa39e, 0xa39f, 
+    0xa3a0, 0xa3a1, 0xa3a2, 0xa3a3, 0xa3a4, 0xa3a5, 0xa3a6, 0xa3a7, 
+    0xa3a8, 0xa3a9, 0xa3aa, 0xa3ab, 0xa3ac, 0xa3ad, 0xa3ae, 0xa3af, 
+    0xa3b0, 0xa3b1, 0xa3b2, 0xa3b3, 0xa3b4, 0xa3b5, 0xa3b6, 0xa3b7, 
+    0xa3b8, 0xa3b9, 0xa3ba, 0xa3bb, 0xa3bc, 0xa3bd, 0xa3be, 0xa3bf, 
+    0xa3c0, 0xa3c1, 0xa3c2, 0xa3c3, 0xa3c4, 0xa3c5, 0xa3c6, 0xa3c7, 
+    0xa3c8, 0xa3c9, 0xa3ca, 0xa3cb, 0xa3cc, 0xa3cd, 0xa3ce, 0xa3cf, 
+    0xa3d0, 0xa3d1, 0xa3d2, 0xa3d3, 0xa3d4, 0xa3d5, 0xa3d6, 0xa3d7, 
+    0xa3d8, 0xa3d9, 0xa3da, 0xa3db, 0xa3dc, 0xa3dd, 0xa3de, 0xa3df, 
+    0xa3e0, 0xa3e1, 0xa3e2, 0xa3e3, 0xa3e4, 0xa3e5, 0xa3e6, 0xa3e7, 
+    0xa3e8, 0xa3e9, 0xa3ea, 0xa3eb, 0xa3ec, 0xa3ed, 0xa3ee, 0xa3ef, 
+    0xa3f0, 0xa3f1, 0xa3f2, 0xa3f3, 0xa3f4, 0xa3f5, 0xa3f6, 0xa3f7, 
+    0xa3f8, 0xa3f9, 0xa3fa, 0xa3fb, 0xa3fc, 0xa3fd, 0xa3fe, 0xa3ff, 
+    0xa400, 0xa401, 0xa402, 0xa403, 0xa404, 0xa405, 0xa406, 0xa407, 
+    0xa408, 0xa409, 0xa40a, 0xa40b, 0xa40c, 0xa40d, 0xa40e, 0xa40f, 
+    0xa410, 0xa411, 0xa412, 0xa413, 0xa414, 0xa415, 0xa416, 0xa417, 
+    0xa418, 0xa419, 0xa41a, 0xa41b, 0xa41c, 0xa41d, 0xa41e, 0xa41f, 
+    0xa420, 0xa421, 0xa422, 0xa423, 0xa424, 0xa425, 0xa426, 0xa427, 
+    0xa428, 0xa429, 0xa42a, 0xa42b, 0xa42c, 0xa42d, 0xa42e, 0xa42f, 
+    0xa430, 0xa431, 0xa432, 0xa433, 0xa434, 0xa435, 0xa436, 0xa437, 
+    0xa438, 0xa439, 0xa43a, 0xa43b, 0xa43c, 0xa43d, 0xa43e, 0xa43f, 
+    0xa440, 0xa441, 0xa442, 0xa443, 0xa444, 0xa445, 0xa446, 0xa447, 
+    0xa448, 0xa449, 0xa44a, 0xa44b, 0xa44c, 0xa44d, 0xa44e, 0xa44f, 
+    0xa450, 0xa451, 0xa452, 0xa453, 0xa454, 0xa455, 0xa456, 0xa457, 
+    0xa458, 0xa459, 0xa45a, 0xa45b, 0xa45c, 0xa45d, 0xa45e, 0xa45f, 
+    0xa460, 0xa461, 0xa462, 0xa463, 0xa464, 0xa465, 0xa466, 0xa467, 
+    0xa468, 0xa469, 0xa46a, 0xa46b, 0xa46c, 0xa46d, 0xa46e, 0xa46f, 
+    0xa470, 0xa471, 0xa472, 0xa473, 0xa474, 0xa475, 0xa476, 0xa477, 
+    0xa478, 0xa479, 0xa47a, 0xa47b, 0xa47c, 0xa47d, 0xa47e, 0xa47f, 
+    0xa480, 0xa481, 0xa482, 0xa483, 0xa484, 0xa485, 0xa486, 0xa487, 
+    0xa488, 0xa489, 0xa48a, 0xa48b, 0xa48c, 0xa48d, 0xa48e, 0xa48f, 
+    0xa490, 0xa491, 0xa492, 0xa493, 0xa494, 0xa495, 0xa496, 0xa497, 
+    0xa498, 0xa499, 0xa49a, 0xa49b, 0xa49c, 0xa49d, 0xa49e, 0xa49f, 
+    0xa4a0, 0xa4a1, 0xa4a2, 0xa4a3, 0xa4a4, 0xa4a5, 0xa4a6, 0xa4a7, 
+    0xa4a8, 0xa4a9, 0xa4aa, 0xa4ab, 0xa4ac, 0xa4ad, 0xa4ae, 0xa4af, 
+    0xa4b0, 0xa4b1, 0xa4b2, 0xa4b3, 0xa4b4, 0xa4b5, 0xa4b6, 0xa4b7, 
+    0xa4b8, 0xa4b9, 0xa4ba, 0xa4bb, 0xa4bc, 0xa4bd, 0xa4be, 0xa4bf, 
+    0xa4c0, 0xa4c1, 0xa4c2, 0xa4c3, 0xa4c4, 0xa4c5, 0xa4c6, 0xa4c7, 
+    0xa4c8, 0xa4c9, 0xa4ca, 0xa4cb, 0xa4cc, 0xa4cd, 0xa4ce, 0xa4cf, 
+    0xa4d0, 0xa4d1, 0xa4d2, 0xa4d3, 0xa4d4, 0xa4d5, 0xa4d6, 0xa4d7, 
+    0xa4d8, 0xa4d9, 0xa4da, 0xa4db, 0xa4dc, 0xa4dd, 0xa4de, 0xa4df, 
+    0xa4e0, 0xa4e1, 0xa4e2, 0xa4e3, 0xa4e4, 0xa4e5, 0xa4e6, 0xa4e7, 
+    0xa4e8, 0xa4e9, 0xa4ea, 0xa4eb, 0xa4ec, 0xa4ed, 0xa4ee, 0xa4ef, 
+    0xa4f0, 0xa4f1, 0xa4f2, 0xa4f3, 0xa4f4, 0xa4f5, 0xa4f6, 0xa4f7, 
+    0xa4f8, 0xa4f9, 0xa4fa, 0xa4fb, 0xa4fc, 0xa4fd, 0xa4fe, 0xa4ff, 
+    0xa500, 0xa501, 0xa502, 0xa503, 0xa504, 0xa505, 0xa506, 0xa507, 
+    0xa508, 0xa509, 0xa50a, 0xa50b, 0xa50c, 0xa50d, 0xa50e, 0xa50f, 
+    0xa510, 0xa511, 0xa512, 0xa513, 0xa514, 0xa515, 0xa516, 0xa517, 
+    0xa518, 0xa519, 0xa51a, 0xa51b, 0xa51c, 0xa51d, 0xa51e, 0xa51f, 
+    0xa520, 0xa521, 0xa522, 0xa523, 0xa524, 0xa525, 0xa526, 0xa527, 
+    0xa528, 0xa529, 0xa52a, 0xa52b, 0xa52c, 0xa52d, 0xa52e, 0xa52f, 
+    0xa530, 0xa531, 0xa532, 0xa533, 0xa534, 0xa535, 0xa536, 0xa537, 
+    0xa538, 0xa539, 0xa53a, 0xa53b, 0xa53c, 0xa53d, 0xa53e, 0xa53f, 
+    0xa540, 0xa541, 0xa542, 0xa543, 0xa544, 0xa545, 0xa546, 0xa547, 
+    0xa548, 0xa549, 0xa54a, 0xa54b, 0xa54c, 0xa54d, 0xa54e, 0xa54f, 
+    0xa550, 0xa551, 0xa552, 0xa553, 0xa554, 0xa555, 0xa556, 0xa557, 
+    0xa558, 0xa559, 0xa55a, 0xa55b, 0xa55c, 0xa55d, 0xa55e, 0xa55f, 
+    0xa560, 0xa561, 0xa562, 0xa563, 0xa564, 0xa565, 0xa566, 0xa567, 
+    0xa568, 0xa569, 0xa56a, 0xa56b, 0xa56c, 0xa56d, 0xa56e, 0xa56f, 
+    0xa570, 0xa571, 0xa572, 0xa573, 0xa574, 0xa575, 0xa576, 0xa577, 
+    0xa578, 0xa579, 0xa57a, 0xa57b, 0xa57c, 0xa57d, 0xa57e, 0xa57f, 
+    0xa580, 0xa581, 0xa582, 0xa583, 0xa584, 0xa585, 0xa586, 0xa587, 
+    0xa588, 0xa589, 0xa58a, 0xa58b, 0xa58c, 0xa58d, 0xa58e, 0xa58f, 
+    0xa590, 0xa591, 0xa592, 0xa593, 0xa594, 0xa595, 0xa596, 0xa597, 
+    0xa598, 0xa599, 0xa59a, 0xa59b, 0xa59c, 0xa59d, 0xa59e, 0xa59f, 
+    0xa5a0, 0xa5a1, 0xa5a2, 0xa5a3, 0xa5a4, 0xa5a5, 0xa5a6, 0xa5a7, 
+    0xa5a8, 0xa5a9, 0xa5aa, 0xa5ab, 0xa5ac, 0xa5ad, 0xa5ae, 0xa5af, 
+    0xa5b0, 0xa5b1, 0xa5b2, 0xa5b3, 0xa5b4, 0xa5b5, 0xa5b6, 0xa5b7, 
+    0xa5b8, 0xa5b9, 0xa5ba, 0xa5bb, 0xa5bc, 0xa5bd, 0xa5be, 0xa5bf, 
+    0xa5c0, 0xa5c1, 0xa5c2, 0xa5c3, 0xa5c4, 0xa5c5, 0xa5c6, 0xa5c7, 
+    0xa5c8, 0xa5c9, 0xa5ca, 0xa5cb, 0xa5cc, 0xa5cd, 0xa5ce, 0xa5cf, 
+    0xa5d0, 0xa5d1, 0xa5d2, 0xa5d3, 0xa5d4, 0xa5d5, 0xa5d6, 0xa5d7, 
+    0xa5d8, 0xa5d9, 0xa5da, 0xa5db, 0xa5dc, 0xa5dd, 0xa5de, 0xa5df, 
+    0xa5e0, 0xa5e1, 0xa5e2, 0xa5e3, 0xa5e4, 0xa5e5, 0xa5e6, 0xa5e7, 
+    0xa5e8, 0xa5e9, 0xa5ea, 0xa5eb, 0xa5ec, 0xa5ed, 0xa5ee, 0xa5ef, 
+    0xa5f0, 0xa5f1, 0xa5f2, 0xa5f3, 0xa5f4, 0xa5f5, 0xa5f6, 0xa5f7, 
+    0xa5f8, 0xa5f9, 0xa5fa, 0xa5fb, 0xa5fc, 0xa5fd, 0xa5fe, 0xa5ff, 
+    0xa600, 0xa601, 0xa602, 0xa603, 0xa604, 0xa605, 0xa606, 0xa607, 
+    0xa608, 0xa609, 0xa60a, 0xa60b, 0xa60c, 0xa60d, 0xa60e, 0xa60f, 
+    0xa610, 0xa611, 0xa612, 0xa613, 0xa614, 0xa615, 0xa616, 0xa617, 
+    0xa618, 0xa619, 0xa61a, 0xa61b, 0xa61c, 0xa61d, 0xa61e, 0xa61f, 
+    0xa620, 0xa621, 0xa622, 0xa623, 0xa624, 0xa625, 0xa626, 0xa627, 
+    0xa628, 0xa629, 0xa62a, 0xa62b, 0xa62c, 0xa62d, 0xa62e, 0xa62f, 
+    0xa630, 0xa631, 0xa632, 0xa633, 0xa634, 0xa635, 0xa636, 0xa637, 
+    0xa638, 0xa639, 0xa63a, 0xa63b, 0xa63c, 0xa63d, 0xa63e, 0xa63f, 
+    0xa640, 0xa641, 0xa642, 0xa643, 0xa644, 0xa645, 0xa646, 0xa647, 
+    0xa648, 0xa649, 0xa64a, 0xa64b, 0xa64c, 0xa64d, 0xa64e, 0xa64f, 
+    0xa650, 0xa651, 0xa652, 0xa653, 0xa654, 0xa655, 0xa656, 0xa657, 
+    0xa658, 0xa659, 0xa65a, 0xa65b, 0xa65c, 0xa65d, 0xa65e, 0xa65f, 
+    0xa660, 0xa661, 0xa662, 0xa663, 0xa664, 0xa665, 0xa666, 0xa667, 
+    0xa668, 0xa669, 0xa66a, 0xa66b, 0xa66c, 0xa66d, 0xa66e, 0xa66f, 
+    0xa670, 0xa671, 0xa672, 0xa673, 0xa674, 0xa675, 0xa676, 0xa677, 
+    0xa678, 0xa679, 0xa67a, 0xa67b, 0xa67c, 0xa67d, 0xa67e, 0xa67f, 
+    0xa680, 0xa681, 0xa682, 0xa683, 0xa684, 0xa685, 0xa686, 0xa687, 
+    0xa688, 0xa689, 0xa68a, 0xa68b, 0xa68c, 0xa68d, 0xa68e, 0xa68f, 
+    0xa690, 0xa691, 0xa692, 0xa693, 0xa694, 0xa695, 0xa696, 0xa697, 
+    0xa698, 0xa699, 0xa69a, 0xa69b, 0xa69c, 0xa69d, 0xa69e, 0xa69f, 
+    0xa6a0, 0xa6a1, 0xa6a2, 0xa6a3, 0xa6a4, 0xa6a5, 0xa6a6, 0xa6a7, 
+    0xa6a8, 0xa6a9, 0xa6aa, 0xa6ab, 0xa6ac, 0xa6ad, 0xa6ae, 0xa6af, 
+    0xa6b0, 0xa6b1, 0xa6b2, 0xa6b3, 0xa6b4, 0xa6b5, 0xa6b6, 0xa6b7, 
+    0xa6b8, 0xa6b9, 0xa6ba, 0xa6bb, 0xa6bc, 0xa6bd, 0xa6be, 0xa6bf, 
+    0xa6c0, 0xa6c1, 0xa6c2, 0xa6c3, 0xa6c4, 0xa6c5, 0xa6c6, 0xa6c7, 
+    0xa6c8, 0xa6c9, 0xa6ca, 0xa6cb, 0xa6cc, 0xa6cd, 0xa6ce, 0xa6cf, 
+    0xa6d0, 0xa6d1, 0xa6d2, 0xa6d3, 0xa6d4, 0xa6d5, 0xa6d6, 0xa6d7, 
+    0xa6d8, 0xa6d9, 0xa6da, 0xa6db, 0xa6dc, 0xa6dd, 0xa6de, 0xa6df, 
+    0xa6e0, 0xa6e1, 0xa6e2, 0xa6e3, 0xa6e4, 0xa6e5, 0xa6e6, 0xa6e7, 
+    0xa6e8, 0xa6e9, 0xa6ea, 0xa6eb, 0xa6ec, 0xa6ed, 0xa6ee, 0xa6ef, 
+    0xa6f0, 0xa6f1, 0xa6f2, 0xa6f3, 0xa6f4, 0xa6f5, 0xa6f6, 0xa6f7, 
+    0xa6f8, 0xa6f9, 0xa6fa, 0xa6fb, 0xa6fc, 0xa6fd, 0xa6fe, 0xa6ff, 
+    0xa700, 0xa701, 0xa702, 0xa703, 0xa704, 0xa705, 0xa706, 0xa707, 
+    0xa708, 0xa709, 0xa70a, 0xa70b, 0xa70c, 0xa70d, 0xa70e, 0xa70f, 
+    0xa710, 0xa711, 0xa712, 0xa713, 0xa714, 0xa715, 0xa716, 0xa717, 
+    0xa718, 0xa719, 0xa71a, 0xa71b, 0xa71c, 0xa71d, 0xa71e, 0xa71f, 
+    0xa720, 0xa721, 0xa722, 0xa723, 0xa724, 0xa725, 0xa726, 0xa727, 
+    0xa728, 0xa729, 0xa72a, 0xa72b, 0xa72c, 0xa72d, 0xa72e, 0xa72f, 
+    0xa730, 0xa731, 0xa732, 0xa733, 0xa734, 0xa735, 0xa736, 0xa737, 
+    0xa738, 0xa739, 0xa73a, 0xa73b, 0xa73c, 0xa73d, 0xa73e, 0xa73f, 
+    0xa740, 0xa741, 0xa742, 0xa743, 0xa744, 0xa745, 0xa746, 0xa747, 
+    0xa748, 0xa749, 0xa74a, 0xa74b, 0xa74c, 0xa74d, 0xa74e, 0xa74f, 
+    0xa750, 0xa751, 0xa752, 0xa753, 0xa754, 0xa755, 0xa756, 0xa757, 
+    0xa758, 0xa759, 0xa75a, 0xa75b, 0xa75c, 0xa75d, 0xa75e, 0xa75f, 
+    0xa760, 0xa761, 0xa762, 0xa763, 0xa764, 0xa765, 0xa766, 0xa767, 
+    0xa768, 0xa769, 0xa76a, 0xa76b, 0xa76c, 0xa76d, 0xa76e, 0xa76f, 
+    0xa770, 0xa771, 0xa772, 0xa773, 0xa774, 0xa775, 0xa776, 0xa777, 
+    0xa778, 0xa779, 0xa77a, 0xa77b, 0xa77c, 0xa77d, 0xa77e, 0xa77f, 
+    0xa780, 0xa781, 0xa782, 0xa783, 0xa784, 0xa785, 0xa786, 0xa787, 
+    0xa788, 0xa789, 0xa78a, 0xa78b, 0xa78c, 0xa78d, 0xa78e, 0xa78f, 
+    0xa790, 0xa791, 0xa792, 0xa793, 0xa794, 0xa795, 0xa796, 0xa797, 
+    0xa798, 0xa799, 0xa79a, 0xa79b, 0xa79c, 0xa79d, 0xa79e, 0xa79f, 
+    0xa7a0, 0xa7a1, 0xa7a2, 0xa7a3, 0xa7a4, 0xa7a5, 0xa7a6, 0xa7a7, 
+    0xa7a8, 0xa7a9, 0xa7aa, 0xa7ab, 0xa7ac, 0xa7ad, 0xa7ae, 0xa7af, 
+    0xa7b0, 0xa7b1, 0xa7b2, 0xa7b3, 0xa7b4, 0xa7b5, 0xa7b6, 0xa7b7, 
+    0xa7b8, 0xa7b9, 0xa7ba, 0xa7bb, 0xa7bc, 0xa7bd, 0xa7be, 0xa7bf, 
+    0xa7c0, 0xa7c1, 0xa7c2, 0xa7c3, 0xa7c4, 0xa7c5, 0xa7c6, 0xa7c7, 
+    0xa7c8, 0xa7c9, 0xa7ca, 0xa7cb, 0xa7cc, 0xa7cd, 0xa7ce, 0xa7cf, 
+    0xa7d0, 0xa7d1, 0xa7d2, 0xa7d3, 0xa7d4, 0xa7d5, 0xa7d6, 0xa7d7, 
+    0xa7d8, 0xa7d9, 0xa7da, 0xa7db, 0xa7dc, 0xa7dd, 0xa7de, 0xa7df, 
+    0xa7e0, 0xa7e1, 0xa7e2, 0xa7e3, 0xa7e4, 0xa7e5, 0xa7e6, 0xa7e7, 
+    0xa7e8, 0xa7e9, 0xa7ea, 0xa7eb, 0xa7ec, 0xa7ed, 0xa7ee, 0xa7ef, 
+    0xa7f0, 0xa7f1, 0xa7f2, 0xa7f3, 0xa7f4, 0xa7f5, 0xa7f6, 0xa7f7, 
+    0xa7f8, 0xa7f9, 0xa7fa, 0xa7fb, 0xa7fc, 0xa7fd, 0xa7fe, 0xa7ff, 
+    0xa800, 0xa801, 0xa802, 0xa803, 0xa804, 0xa805, 0xa806, 0xa807, 
+    0xa808, 0xa809, 0xa80a, 0xa80b, 0xa80c, 0xa80d, 0xa80e, 0xa80f, 
+    0xa810, 0xa811, 0xa812, 0xa813, 0xa814, 0xa815, 0xa816, 0xa817, 
+    0xa818, 0xa819, 0xa81a, 0xa81b, 0xa81c, 0xa81d, 0xa81e, 0xa81f, 
+    0xa820, 0xa821, 0xa822, 0xa823, 0xa824, 0xa825, 0xa826, 0xa827, 
+    0xa828, 0xa829, 0xa82a, 0xa82b, 0xa82c, 0xa82d, 0xa82e, 0xa82f, 
+    0xa830, 0xa831, 0xa832, 0xa833, 0xa834, 0xa835, 0xa836, 0xa837, 
+    0xa838, 0xa839, 0xa83a, 0xa83b, 0xa83c, 0xa83d, 0xa83e, 0xa83f, 
+    0xa840, 0xa841, 0xa842, 0xa843, 0xa844, 0xa845, 0xa846, 0xa847, 
+    0xa848, 0xa849, 0xa84a, 0xa84b, 0xa84c, 0xa84d, 0xa84e, 0xa84f, 
+    0xa850, 0xa851, 0xa852, 0xa853, 0xa854, 0xa855, 0xa856, 0xa857, 
+    0xa858, 0xa859, 0xa85a, 0xa85b, 0xa85c, 0xa85d, 0xa85e, 0xa85f, 
+    0xa860, 0xa861, 0xa862, 0xa863, 0xa864, 0xa865, 0xa866, 0xa867, 
+    0xa868, 0xa869, 0xa86a, 0xa86b, 0xa86c, 0xa86d, 0xa86e, 0xa86f, 
+    0xa870, 0xa871, 0xa872, 0xa873, 0xa874, 0xa875, 0xa876, 0xa877, 
+    0xa878, 0xa879, 0xa87a, 0xa87b, 0xa87c, 0xa87d, 0xa87e, 0xa87f, 
+    0xa880, 0xa881, 0xa882, 0xa883, 0xa884, 0xa885, 0xa886, 0xa887, 
+    0xa888, 0xa889, 0xa88a, 0xa88b, 0xa88c, 0xa88d, 0xa88e, 0xa88f, 
+    0xa890, 0xa891, 0xa892, 0xa893, 0xa894, 0xa895, 0xa896, 0xa897, 
+    0xa898, 0xa899, 0xa89a, 0xa89b, 0xa89c, 0xa89d, 0xa89e, 0xa89f, 
+    0xa8a0, 0xa8a1, 0xa8a2, 0xa8a3, 0xa8a4, 0xa8a5, 0xa8a6, 0xa8a7, 
+    0xa8a8, 0xa8a9, 0xa8aa, 0xa8ab, 0xa8ac, 0xa8ad, 0xa8ae, 0xa8af, 
+    0xa8b0, 0xa8b1, 0xa8b2, 0xa8b3, 0xa8b4, 0xa8b5, 0xa8b6, 0xa8b7, 
+    0xa8b8, 0xa8b9, 0xa8ba, 0xa8bb, 0xa8bc, 0xa8bd, 0xa8be, 0xa8bf, 
+    0xa8c0, 0xa8c1, 0xa8c2, 0xa8c3, 0xa8c4, 0xa8c5, 0xa8c6, 0xa8c7, 
+    0xa8c8, 0xa8c9, 0xa8ca, 0xa8cb, 0xa8cc, 0xa8cd, 0xa8ce, 0xa8cf, 
+    0xa8d0, 0xa8d1, 0xa8d2, 0xa8d3, 0xa8d4, 0xa8d5, 0xa8d6, 0xa8d7, 
+    0xa8d8, 0xa8d9, 0xa8da, 0xa8db, 0xa8dc, 0xa8dd, 0xa8de, 0xa8df, 
+    0xa8e0, 0xa8e1, 0xa8e2, 0xa8e3, 0xa8e4, 0xa8e5, 0xa8e6, 0xa8e7, 
+    0xa8e8, 0xa8e9, 0xa8ea, 0xa8eb, 0xa8ec, 0xa8ed, 0xa8ee, 0xa8ef, 
+    0xa8f0, 0xa8f1, 0xa8f2, 0xa8f3, 0xa8f4, 0xa8f5, 0xa8f6, 0xa8f7, 
+    0xa8f8, 0xa8f9, 0xa8fa, 0xa8fb, 0xa8fc, 0xa8fd, 0xa8fe, 0xa8ff, 
+    0xa900, 0xa901, 0xa902, 0xa903, 0xa904, 0xa905, 0xa906, 0xa907, 
+    0xa908, 0xa909, 0xa90a, 0xa90b, 0xa90c, 0xa90d, 0xa90e, 0xa90f, 
+    0xa910, 0xa911, 0xa912, 0xa913, 0xa914, 0xa915, 0xa916, 0xa917, 
+    0xa918, 0xa919, 0xa91a, 0xa91b, 0xa91c, 0xa91d, 0xa91e, 0xa91f, 
+    0xa920, 0xa921, 0xa922, 0xa923, 0xa924, 0xa925, 0xa926, 0xa927, 
+    0xa928, 0xa929, 0xa92a, 0xa92b, 0xa92c, 0xa92d, 0xa92e, 0xa92f, 
+    0xa930, 0xa931, 0xa932, 0xa933, 0xa934, 0xa935, 0xa936, 0xa937, 
+    0xa938, 0xa939, 0xa93a, 0xa93b, 0xa93c, 0xa93d, 0xa93e, 0xa93f, 
+    0xa940, 0xa941, 0xa942, 0xa943, 0xa944, 0xa945, 0xa946, 0xa947, 
+    0xa948, 0xa949, 0xa94a, 0xa94b, 0xa94c, 0xa94d, 0xa94e, 0xa94f, 
+    0xa950, 0xa951, 0xa952, 0xa953, 0xa954, 0xa955, 0xa956, 0xa957, 
+    0xa958, 0xa959, 0xa95a, 0xa95b, 0xa95c, 0xa95d, 0xa95e, 0xa95f, 
+    0xa960, 0xa961, 0xa962, 0xa963, 0xa964, 0xa965, 0xa966, 0xa967, 
+    0xa968, 0xa969, 0xa96a, 0xa96b, 0xa96c, 0xa96d, 0xa96e, 0xa96f, 
+    0xa970, 0xa971, 0xa972, 0xa973, 0xa974, 0xa975, 0xa976, 0xa977, 
+    0xa978, 0xa979, 0xa97a, 0xa97b, 0xa97c, 0xa97d, 0xa97e, 0xa97f, 
+    0xa980, 0xa981, 0xa982, 0xa983, 0xa984, 0xa985, 0xa986, 0xa987, 
+    0xa988, 0xa989, 0xa98a, 0xa98b, 0xa98c, 0xa98d, 0xa98e, 0xa98f, 
+    0xa990, 0xa991, 0xa992, 0xa993, 0xa994, 0xa995, 0xa996, 0xa997, 
+    0xa998, 0xa999, 0xa99a, 0xa99b, 0xa99c, 0xa99d, 0xa99e, 0xa99f, 
+    0xa9a0, 0xa9a1, 0xa9a2, 0xa9a3, 0xa9a4, 0xa9a5, 0xa9a6, 0xa9a7, 
+    0xa9a8, 0xa9a9, 0xa9aa, 0xa9ab, 0xa9ac, 0xa9ad, 0xa9ae, 0xa9af, 
+    0xa9b0, 0xa9b1, 0xa9b2, 0xa9b3, 0xa9b4, 0xa9b5, 0xa9b6, 0xa9b7, 
+    0xa9b8, 0xa9b9, 0xa9ba, 0xa9bb, 0xa9bc, 0xa9bd, 0xa9be, 0xa9bf, 
+    0xa9c0, 0xa9c1, 0xa9c2, 0xa9c3, 0xa9c4, 0xa9c5, 0xa9c6, 0xa9c7, 
+    0xa9c8, 0xa9c9, 0xa9ca, 0xa9cb, 0xa9cc, 0xa9cd, 0xa9ce, 0xa9cf, 
+    0xa9d0, 0xa9d1, 0xa9d2, 0xa9d3, 0xa9d4, 0xa9d5, 0xa9d6, 0xa9d7, 
+    0xa9d8, 0xa9d9, 0xa9da, 0xa9db, 0xa9dc, 0xa9dd, 0xa9de, 0xa9df, 
+    0xa9e0, 0xa9e1, 0xa9e2, 0xa9e3, 0xa9e4, 0xa9e5, 0xa9e6, 0xa9e7, 
+    0xa9e8, 0xa9e9, 0xa9ea, 0xa9eb, 0xa9ec, 0xa9ed, 0xa9ee, 0xa9ef, 
+    0xa9f0, 0xa9f1, 0xa9f2, 0xa9f3, 0xa9f4, 0xa9f5, 0xa9f6, 0xa9f7, 
+    0xa9f8, 0xa9f9, 0xa9fa, 0xa9fb, 0xa9fc, 0xa9fd, 0xa9fe, 0xa9ff, 
+    0xaa00, 0xaa01, 0xaa02, 0xaa03, 0xaa04, 0xaa05, 0xaa06, 0xaa07, 
+    0xaa08, 0xaa09, 0xaa0a, 0xaa0b, 0xaa0c, 0xaa0d, 0xaa0e, 0xaa0f, 
+    0xaa10, 0xaa11, 0xaa12, 0xaa13, 0xaa14, 0xaa15, 0xaa16, 0xaa17, 
+    0xaa18, 0xaa19, 0xaa1a, 0xaa1b, 0xaa1c, 0xaa1d, 0xaa1e, 0xaa1f, 
+    0xaa20, 0xaa21, 0xaa22, 0xaa23, 0xaa24, 0xaa25, 0xaa26, 0xaa27, 
+    0xaa28, 0xaa29, 0xaa2a, 0xaa2b, 0xaa2c, 0xaa2d, 0xaa2e, 0xaa2f, 
+    0xaa30, 0xaa31, 0xaa32, 0xaa33, 0xaa34, 0xaa35, 0xaa36, 0xaa37, 
+    0xaa38, 0xaa39, 0xaa3a, 0xaa3b, 0xaa3c, 0xaa3d, 0xaa3e, 0xaa3f, 
+    0xaa40, 0xaa41, 0xaa42, 0xaa43, 0xaa44, 0xaa45, 0xaa46, 0xaa47, 
+    0xaa48, 0xaa49, 0xaa4a, 0xaa4b, 0xaa4c, 0xaa4d, 0xaa4e, 0xaa4f, 
+    0xaa50, 0xaa51, 0xaa52, 0xaa53, 0xaa54, 0xaa55, 0xaa56, 0xaa57, 
+    0xaa58, 0xaa59, 0xaa5a, 0xaa5b, 0xaa5c, 0xaa5d, 0xaa5e, 0xaa5f, 
+    0xaa60, 0xaa61, 0xaa62, 0xaa63, 0xaa64, 0xaa65, 0xaa66, 0xaa67, 
+    0xaa68, 0xaa69, 0xaa6a, 0xaa6b, 0xaa6c, 0xaa6d, 0xaa6e, 0xaa6f, 
+    0xaa70, 0xaa71, 0xaa72, 0xaa73, 0xaa74, 0xaa75, 0xaa76, 0xaa77, 
+    0xaa78, 0xaa79, 0xaa7a, 0xaa7b, 0xaa7c, 0xaa7d, 0xaa7e, 0xaa7f, 
+    0xaa80, 0xaa81, 0xaa82, 0xaa83, 0xaa84, 0xaa85, 0xaa86, 0xaa87, 
+    0xaa88, 0xaa89, 0xaa8a, 0xaa8b, 0xaa8c, 0xaa8d, 0xaa8e, 0xaa8f, 
+    0xaa90, 0xaa91, 0xaa92, 0xaa93, 0xaa94, 0xaa95, 0xaa96, 0xaa97, 
+    0xaa98, 0xaa99, 0xaa9a, 0xaa9b, 0xaa9c, 0xaa9d, 0xaa9e, 0xaa9f, 
+    0xaaa0, 0xaaa1, 0xaaa2, 0xaaa3, 0xaaa4, 0xaaa5, 0xaaa6, 0xaaa7, 
+    0xaaa8, 0xaaa9, 0xaaaa, 0xaaab, 0xaaac, 0xaaad, 0xaaae, 0xaaaf, 
+    0xaab0, 0xaab1, 0xaab2, 0xaab3, 0xaab4, 0xaab5, 0xaab6, 0xaab7, 
+    0xaab8, 0xaab9, 0xaaba, 0xaabb, 0xaabc, 0xaabd, 0xaabe, 0xaabf, 
+    0xaac0, 0xaac1, 0xaac2, 0xaac3, 0xaac4, 0xaac5, 0xaac6, 0xaac7, 
+    0xaac8, 0xaac9, 0xaaca, 0xaacb, 0xaacc, 0xaacd, 0xaace, 0xaacf, 
+    0xaad0, 0xaad1, 0xaad2, 0xaad3, 0xaad4, 0xaad5, 0xaad6, 0xaad7, 
+    0xaad8, 0xaad9, 0xaada, 0xaadb, 0xaadc, 0xaadd, 0xaade, 0xaadf, 
+    0xaae0, 0xaae1, 0xaae2, 0xaae3, 0xaae4, 0xaae5, 0xaae6, 0xaae7, 
+    0xaae8, 0xaae9, 0xaaea, 0xaaeb, 0xaaec, 0xaaed, 0xaaee, 0xaaef, 
+    0xaaf0, 0xaaf1, 0xaaf2, 0xaaf3, 0xaaf4, 0xaaf5, 0xaaf6, 0xaaf7, 
+    0xaaf8, 0xaaf9, 0xaafa, 0xaafb, 0xaafc, 0xaafd, 0xaafe, 0xaaff, 
+    0xab00, 0xab01, 0xab02, 0xab03, 0xab04, 0xab05, 0xab06, 0xab07, 
+    0xab08, 0xab09, 0xab0a, 0xab0b, 0xab0c, 0xab0d, 0xab0e, 0xab0f, 
+    0xab10, 0xab11, 0xab12, 0xab13, 0xab14, 0xab15, 0xab16, 0xab17, 
+    0xab18, 0xab19, 0xab1a, 0xab1b, 0xab1c, 0xab1d, 0xab1e, 0xab1f, 
+    0xab20, 0xab21, 0xab22, 0xab23, 0xab24, 0xab25, 0xab26, 0xab27, 
+    0xab28, 0xab29, 0xab2a, 0xab2b, 0xab2c, 0xab2d, 0xab2e, 0xab2f, 
+    0xab30, 0xab31, 0xab32, 0xab33, 0xab34, 0xab35, 0xab36, 0xab37, 
+    0xab38, 0xab39, 0xab3a, 0xab3b, 0xab3c, 0xab3d, 0xab3e, 0xab3f, 
+    0xab40, 0xab41, 0xab42, 0xab43, 0xab44, 0xab45, 0xab46, 0xab47, 
+    0xab48, 0xab49, 0xab4a, 0xab4b, 0xab4c, 0xab4d, 0xab4e, 0xab4f, 
+    0xab50, 0xab51, 0xab52, 0xab53, 0xab54, 0xab55, 0xab56, 0xab57, 
+    0xab58, 0xab59, 0xab5a, 0xab5b, 0xab5c, 0xab5d, 0xab5e, 0xab5f, 
+    0xab60, 0xab61, 0xab62, 0xab63, 0xab64, 0xab65, 0xab66, 0xab67, 
+    0xab68, 0xab69, 0xab6a, 0xab6b, 0xab6c, 0xab6d, 0xab6e, 0xab6f, 
+    0xab70, 0xab71, 0xab72, 0xab73, 0xab74, 0xab75, 0xab76, 0xab77, 
+    0xab78, 0xab79, 0xab7a, 0xab7b, 0xab7c, 0xab7d, 0xab7e, 0xab7f, 
+    0xab80, 0xab81, 0xab82, 0xab83, 0xab84, 0xab85, 0xab86, 0xab87, 
+    0xab88, 0xab89, 0xab8a, 0xab8b, 0xab8c, 0xab8d, 0xab8e, 0xab8f, 
+    0xab90, 0xab91, 0xab92, 0xab93, 0xab94, 0xab95, 0xab96, 0xab97, 
+    0xab98, 0xab99, 0xab9a, 0xab9b, 0xab9c, 0xab9d, 0xab9e, 0xab9f, 
+    0xaba0, 0xaba1, 0xaba2, 0xaba3, 0xaba4, 0xaba5, 0xaba6, 0xaba7, 
+    0xaba8, 0xaba9, 0xabaa, 0xabab, 0xabac, 0xabad, 0xabae, 0xabaf, 
+    0xabb0, 0xabb1, 0xabb2, 0xabb3, 0xabb4, 0xabb5, 0xabb6, 0xabb7, 
+    0xabb8, 0xabb9, 0xabba, 0xabbb, 0xabbc, 0xabbd, 0xabbe, 0xabbf, 
+    0xabc0, 0xabc1, 0xabc2, 0xabc3, 0xabc4, 0xabc5, 0xabc6, 0xabc7, 
+    0xabc8, 0xabc9, 0xabca, 0xabcb, 0xabcc, 0xabcd, 0xabce, 0xabcf, 
+    0xabd0, 0xabd1, 0xabd2, 0xabd3, 0xabd4, 0xabd5, 0xabd6, 0xabd7, 
+    0xabd8, 0xabd9, 0xabda, 0xabdb, 0xabdc, 0xabdd, 0xabde, 0xabdf, 
+    0xabe0, 0xabe1, 0xabe2, 0xabe3, 0xabe4, 0xabe5, 0xabe6, 0xabe7, 
+    0xabe8, 0xabe9, 0xabea, 0xabeb, 0xabec, 0xabed, 0xabee, 0xabef, 
+    0xabf0, 0xabf1, 0xabf2, 0xabf3, 0xabf4, 0xabf5, 0xabf6, 0xabf7, 
+    0xabf8, 0xabf9, 0xabfa, 0xabfb, 0xabfc, 0xabfd, 0xabfe, 0xabff, 
+    0xac00, 0xac01, 0xac02, 0xac03, 0xac04, 0xac05, 0xac06, 0xac07, 
+    0xac08, 0xac09, 0xac0a, 0xac0b, 0xac0c, 0xac0d, 0xac0e, 0xac0f, 
+    0xac10, 0xac11, 0xac12, 0xac13, 0xac14, 0xac15, 0xac16, 0xac17, 
+    0xac18, 0xac19, 0xac1a, 0xac1b, 0xac1c, 0xac1d, 0xac1e, 0xac1f, 
+    0xac20, 0xac21, 0xac22, 0xac23, 0xac24, 0xac25, 0xac26, 0xac27, 
+    0xac28, 0xac29, 0xac2a, 0xac2b, 0xac2c, 0xac2d, 0xac2e, 0xac2f, 
+    0xac30, 0xac31, 0xac32, 0xac33, 0xac34, 0xac35, 0xac36, 0xac37, 
+    0xac38, 0xac39, 0xac3a, 0xac3b, 0xac3c, 0xac3d, 0xac3e, 0xac3f, 
+    0xac40, 0xac41, 0xac42, 0xac43, 0xac44, 0xac45, 0xac46, 0xac47, 
+    0xac48, 0xac49, 0xac4a, 0xac4b, 0xac4c, 0xac4d, 0xac4e, 0xac4f, 
+    0xac50, 0xac51, 0xac52, 0xac53, 0xac54, 0xac55, 0xac56, 0xac57, 
+    0xac58, 0xac59, 0xac5a, 0xac5b, 0xac5c, 0xac5d, 0xac5e, 0xac5f, 
+    0xac60, 0xac61, 0xac62, 0xac63, 0xac64, 0xac65, 0xac66, 0xac67, 
+    0xac68, 0xac69, 0xac6a, 0xac6b, 0xac6c, 0xac6d, 0xac6e, 0xac6f, 
+    0xac70, 0xac71, 0xac72, 0xac73, 0xac74, 0xac75, 0xac76, 0xac77, 
+    0xac78, 0xac79, 0xac7a, 0xac7b, 0xac7c, 0xac7d, 0xac7e, 0xac7f, 
+    0xac80, 0xac81, 0xac82, 0xac83, 0xac84, 0xac85, 0xac86, 0xac87, 
+    0xac88, 0xac89, 0xac8a, 0xac8b, 0xac8c, 0xac8d, 0xac8e, 0xac8f, 
+    0xac90, 0xac91, 0xac92, 0xac93, 0xac94, 0xac95, 0xac96, 0xac97, 
+    0xac98, 0xac99, 0xac9a, 0xac9b, 0xac9c, 0xac9d, 0xac9e, 0xac9f, 
+    0xaca0, 0xaca1, 0xaca2, 0xaca3, 0xaca4, 0xaca5, 0xaca6, 0xaca7, 
+    0xaca8, 0xaca9, 0xacaa, 0xacab, 0xacac, 0xacad, 0xacae, 0xacaf, 
+    0xacb0, 0xacb1, 0xacb2, 0xacb3, 0xacb4, 0xacb5, 0xacb6, 0xacb7, 
+    0xacb8, 0xacb9, 0xacba, 0xacbb, 0xacbc, 0xacbd, 0xacbe, 0xacbf, 
+    0xacc0, 0xacc1, 0xacc2, 0xacc3, 0xacc4, 0xacc5, 0xacc6, 0xacc7, 
+    0xacc8, 0xacc9, 0xacca, 0xaccb, 0xaccc, 0xaccd, 0xacce, 0xaccf, 
+    0xacd0, 0xacd1, 0xacd2, 0xacd3, 0xacd4, 0xacd5, 0xacd6, 0xacd7, 
+    0xacd8, 0xacd9, 0xacda, 0xacdb, 0xacdc, 0xacdd, 0xacde, 0xacdf, 
+    0xace0, 0xace1, 0xace2, 0xace3, 0xace4, 0xace5, 0xace6, 0xace7, 
+    0xace8, 0xace9, 0xacea, 0xaceb, 0xacec, 0xaced, 0xacee, 0xacef, 
+    0xacf0, 0xacf1, 0xacf2, 0xacf3, 0xacf4, 0xacf5, 0xacf6, 0xacf7, 
+    0xacf8, 0xacf9, 0xacfa, 0xacfb, 0xacfc, 0xacfd, 0xacfe, 0xacff, 
+    0xad00, 0xad01, 0xad02, 0xad03, 0xad04, 0xad05, 0xad06, 0xad07, 
+    0xad08, 0xad09, 0xad0a, 0xad0b, 0xad0c, 0xad0d, 0xad0e, 0xad0f, 
+    0xad10, 0xad11, 0xad12, 0xad13, 0xad14, 0xad15, 0xad16, 0xad17, 
+    0xad18, 0xad19, 0xad1a, 0xad1b, 0xad1c, 0xad1d, 0xad1e, 0xad1f, 
+    0xad20, 0xad21, 0xad22, 0xad23, 0xad24, 0xad25, 0xad26, 0xad27, 
+    0xad28, 0xad29, 0xad2a, 0xad2b, 0xad2c, 0xad2d, 0xad2e, 0xad2f, 
+    0xad30, 0xad31, 0xad32, 0xad33, 0xad34, 0xad35, 0xad36, 0xad37, 
+    0xad38, 0xad39, 0xad3a, 0xad3b, 0xad3c, 0xad3d, 0xad3e, 0xad3f, 
+    0xad40, 0xad41, 0xad42, 0xad43, 0xad44, 0xad45, 0xad46, 0xad47, 
+    0xad48, 0xad49, 0xad4a, 0xad4b, 0xad4c, 0xad4d, 0xad4e, 0xad4f, 
+    0xad50, 0xad51, 0xad52, 0xad53, 0xad54, 0xad55, 0xad56, 0xad57, 
+    0xad58, 0xad59, 0xad5a, 0xad5b, 0xad5c, 0xad5d, 0xad5e, 0xad5f, 
+    0xad60, 0xad61, 0xad62, 0xad63, 0xad64, 0xad65, 0xad66, 0xad67, 
+    0xad68, 0xad69, 0xad6a, 0xad6b, 0xad6c, 0xad6d, 0xad6e, 0xad6f, 
+    0xad70, 0xad71, 0xad72, 0xad73, 0xad74, 0xad75, 0xad76, 0xad77, 
+    0xad78, 0xad79, 0xad7a, 0xad7b, 0xad7c, 0xad7d, 0xad7e, 0xad7f, 
+    0xad80, 0xad81, 0xad82, 0xad83, 0xad84, 0xad85, 0xad86, 0xad87, 
+    0xad88, 0xad89, 0xad8a, 0xad8b, 0xad8c, 0xad8d, 0xad8e, 0xad8f, 
+    0xad90, 0xad91, 0xad92, 0xad93, 0xad94, 0xad95, 0xad96, 0xad97, 
+    0xad98, 0xad99, 0xad9a, 0xad9b, 0xad9c, 0xad9d, 0xad9e, 0xad9f, 
+    0xada0, 0xada1, 0xada2, 0xada3, 0xada4, 0xada5, 0xada6, 0xada7, 
+    0xada8, 0xada9, 0xadaa, 0xadab, 0xadac, 0xadad, 0xadae, 0xadaf, 
+    0xadb0, 0xadb1, 0xadb2, 0xadb3, 0xadb4, 0xadb5, 0xadb6, 0xadb7, 
+    0xadb8, 0xadb9, 0xadba, 0xadbb, 0xadbc, 0xadbd, 0xadbe, 0xadbf, 
+    0xadc0, 0xadc1, 0xadc2, 0xadc3, 0xadc4, 0xadc5, 0xadc6, 0xadc7, 
+    0xadc8, 0xadc9, 0xadca, 0xadcb, 0xadcc, 0xadcd, 0xadce, 0xadcf, 
+    0xadd0, 0xadd1, 0xadd2, 0xadd3, 0xadd4, 0xadd5, 0xadd6, 0xadd7, 
+    0xadd8, 0xadd9, 0xadda, 0xaddb, 0xaddc, 0xaddd, 0xadde, 0xaddf, 
+    0xade0, 0xade1, 0xade2, 0xade3, 0xade4, 0xade5, 0xade6, 0xade7, 
+    0xade8, 0xade9, 0xadea, 0xadeb, 0xadec, 0xaded, 0xadee, 0xadef, 
+    0xadf0, 0xadf1, 0xadf2, 0xadf3, 0xadf4, 0xadf5, 0xadf6, 0xadf7, 
+    0xadf8, 0xadf9, 0xadfa, 0xadfb, 0xadfc, 0xadfd, 0xadfe, 0xadff, 
+    0xae00, 0xae01, 0xae02, 0xae03, 0xae04, 0xae05, 0xae06, 0xae07, 
+    0xae08, 0xae09, 0xae0a, 0xae0b, 0xae0c, 0xae0d, 0xae0e, 0xae0f, 
+    0xae10, 0xae11, 0xae12, 0xae13, 0xae14, 0xae15, 0xae16, 0xae17, 
+    0xae18, 0xae19, 0xae1a, 0xae1b, 0xae1c, 0xae1d, 0xae1e, 0xae1f, 
+    0xae20, 0xae21, 0xae22, 0xae23, 0xae24, 0xae25, 0xae26, 0xae27, 
+    0xae28, 0xae29, 0xae2a, 0xae2b, 0xae2c, 0xae2d, 0xae2e, 0xae2f, 
+    0xae30, 0xae31, 0xae32, 0xae33, 0xae34, 0xae35, 0xae36, 0xae37, 
+    0xae38, 0xae39, 0xae3a, 0xae3b, 0xae3c, 0xae3d, 0xae3e, 0xae3f, 
+    0xae40, 0xae41, 0xae42, 0xae43, 0xae44, 0xae45, 0xae46, 0xae47, 
+    0xae48, 0xae49, 0xae4a, 0xae4b, 0xae4c, 0xae4d, 0xae4e, 0xae4f, 
+    0xae50, 0xae51, 0xae52, 0xae53, 0xae54, 0xae55, 0xae56, 0xae57, 
+    0xae58, 0xae59, 0xae5a, 0xae5b, 0xae5c, 0xae5d, 0xae5e, 0xae5f, 
+    0xae60, 0xae61, 0xae62, 0xae63, 0xae64, 0xae65, 0xae66, 0xae67, 
+    0xae68, 0xae69, 0xae6a, 0xae6b, 0xae6c, 0xae6d, 0xae6e, 0xae6f, 
+    0xae70, 0xae71, 0xae72, 0xae73, 0xae74, 0xae75, 0xae76, 0xae77, 
+    0xae78, 0xae79, 0xae7a, 0xae7b, 0xae7c, 0xae7d, 0xae7e, 0xae7f, 
+    0xae80, 0xae81, 0xae82, 0xae83, 0xae84, 0xae85, 0xae86, 0xae87, 
+    0xae88, 0xae89, 0xae8a, 0xae8b, 0xae8c, 0xae8d, 0xae8e, 0xae8f, 
+    0xae90, 0xae91, 0xae92, 0xae93, 0xae94, 0xae95, 0xae96, 0xae97, 
+    0xae98, 0xae99, 0xae9a, 0xae9b, 0xae9c, 0xae9d, 0xae9e, 0xae9f, 
+    0xaea0, 0xaea1, 0xaea2, 0xaea3, 0xaea4, 0xaea5, 0xaea6, 0xaea7, 
+    0xaea8, 0xaea9, 0xaeaa, 0xaeab, 0xaeac, 0xaead, 0xaeae, 0xaeaf, 
+    0xaeb0, 0xaeb1, 0xaeb2, 0xaeb3, 0xaeb4, 0xaeb5, 0xaeb6, 0xaeb7, 
+    0xaeb8, 0xaeb9, 0xaeba, 0xaebb, 0xaebc, 0xaebd, 0xaebe, 0xaebf, 
+    0xaec0, 0xaec1, 0xaec2, 0xaec3, 0xaec4, 0xaec5, 0xaec6, 0xaec7, 
+    0xaec8, 0xaec9, 0xaeca, 0xaecb, 0xaecc, 0xaecd, 0xaece, 0xaecf, 
+    0xaed0, 0xaed1, 0xaed2, 0xaed3, 0xaed4, 0xaed5, 0xaed6, 0xaed7, 
+    0xaed8, 0xaed9, 0xaeda, 0xaedb, 0xaedc, 0xaedd, 0xaede, 0xaedf, 
+    0xaee0, 0xaee1, 0xaee2, 0xaee3, 0xaee4, 0xaee5, 0xaee6, 0xaee7, 
+    0xaee8, 0xaee9, 0xaeea, 0xaeeb, 0xaeec, 0xaeed, 0xaeee, 0xaeef, 
+    0xaef0, 0xaef1, 0xaef2, 0xaef3, 0xaef4, 0xaef5, 0xaef6, 0xaef7, 
+    0xaef8, 0xaef9, 0xaefa, 0xaefb, 0xaefc, 0xaefd, 0xaefe, 0xaeff, 
+    0xaf00, 0xaf01, 0xaf02, 0xaf03, 0xaf04, 0xaf05, 0xaf06, 0xaf07, 
+    0xaf08, 0xaf09, 0xaf0a, 0xaf0b, 0xaf0c, 0xaf0d, 0xaf0e, 0xaf0f, 
+    0xaf10, 0xaf11, 0xaf12, 0xaf13, 0xaf14, 0xaf15, 0xaf16, 0xaf17, 
+    0xaf18, 0xaf19, 0xaf1a, 0xaf1b, 0xaf1c, 0xaf1d, 0xaf1e, 0xaf1f, 
+    0xaf20, 0xaf21, 0xaf22, 0xaf23, 0xaf24, 0xaf25, 0xaf26, 0xaf27, 
+    0xaf28, 0xaf29, 0xaf2a, 0xaf2b, 0xaf2c, 0xaf2d, 0xaf2e, 0xaf2f, 
+    0xaf30, 0xaf31, 0xaf32, 0xaf33, 0xaf34, 0xaf35, 0xaf36, 0xaf37, 
+    0xaf38, 0xaf39, 0xaf3a, 0xaf3b, 0xaf3c, 0xaf3d, 0xaf3e, 0xaf3f, 
+    0xaf40, 0xaf41, 0xaf42, 0xaf43, 0xaf44, 0xaf45, 0xaf46, 0xaf47, 
+    0xaf48, 0xaf49, 0xaf4a, 0xaf4b, 0xaf4c, 0xaf4d, 0xaf4e, 0xaf4f, 
+    0xaf50, 0xaf51, 0xaf52, 0xaf53, 0xaf54, 0xaf55, 0xaf56, 0xaf57, 
+    0xaf58, 0xaf59, 0xaf5a, 0xaf5b, 0xaf5c, 0xaf5d, 0xaf5e, 0xaf5f, 
+    0xaf60, 0xaf61, 0xaf62, 0xaf63, 0xaf64, 0xaf65, 0xaf66, 0xaf67, 
+    0xaf68, 0xaf69, 0xaf6a, 0xaf6b, 0xaf6c, 0xaf6d, 0xaf6e, 0xaf6f, 
+    0xaf70, 0xaf71, 0xaf72, 0xaf73, 0xaf74, 0xaf75, 0xaf76, 0xaf77, 
+    0xaf78, 0xaf79, 0xaf7a, 0xaf7b, 0xaf7c, 0xaf7d, 0xaf7e, 0xaf7f, 
+    0xaf80, 0xaf81, 0xaf82, 0xaf83, 0xaf84, 0xaf85, 0xaf86, 0xaf87, 
+    0xaf88, 0xaf89, 0xaf8a, 0xaf8b, 0xaf8c, 0xaf8d, 0xaf8e, 0xaf8f, 
+    0xaf90, 0xaf91, 0xaf92, 0xaf93, 0xaf94, 0xaf95, 0xaf96, 0xaf97, 
+    0xaf98, 0xaf99, 0xaf9a, 0xaf9b, 0xaf9c, 0xaf9d, 0xaf9e, 0xaf9f, 
+    0xafa0, 0xafa1, 0xafa2, 0xafa3, 0xafa4, 0xafa5, 0xafa6, 0xafa7, 
+    0xafa8, 0xafa9, 0xafaa, 0xafab, 0xafac, 0xafad, 0xafae, 0xafaf, 
+    0xafb0, 0xafb1, 0xafb2, 0xafb3, 0xafb4, 0xafb5, 0xafb6, 0xafb7, 
+    0xafb8, 0xafb9, 0xafba, 0xafbb, 0xafbc, 0xafbd, 0xafbe, 0xafbf, 
+    0xafc0, 0xafc1, 0xafc2, 0xafc3, 0xafc4, 0xafc5, 0xafc6, 0xafc7, 
+    0xafc8, 0xafc9, 0xafca, 0xafcb, 0xafcc, 0xafcd, 0xafce, 0xafcf, 
+    0xafd0, 0xafd1, 0xafd2, 0xafd3, 0xafd4, 0xafd5, 0xafd6, 0xafd7, 
+    0xafd8, 0xafd9, 0xafda, 0xafdb, 0xafdc, 0xafdd, 0xafde, 0xafdf, 
+    0xafe0, 0xafe1, 0xafe2, 0xafe3, 0xafe4, 0xafe5, 0xafe6, 0xafe7, 
+    0xafe8, 0xafe9, 0xafea, 0xafeb, 0xafec, 0xafed, 0xafee, 0xafef, 
+    0xaff0, 0xaff1, 0xaff2, 0xaff3, 0xaff4, 0xaff5, 0xaff6, 0xaff7, 
+    0xaff8, 0xaff9, 0xaffa, 0xaffb, 0xaffc, 0xaffd, 0xaffe, 0xafff, 
+    0xb000, 0xb001, 0xb002, 0xb003, 0xb004, 0xb005, 0xb006, 0xb007, 
+    0xb008, 0xb009, 0xb00a, 0xb00b, 0xb00c, 0xb00d, 0xb00e, 0xb00f, 
+    0xb010, 0xb011, 0xb012, 0xb013, 0xb014, 0xb015, 0xb016, 0xb017, 
+    0xb018, 0xb019, 0xb01a, 0xb01b, 0xb01c, 0xb01d, 0xb01e, 0xb01f, 
+    0xb020, 0xb021, 0xb022, 0xb023, 0xb024, 0xb025, 0xb026, 0xb027, 
+    0xb028, 0xb029, 0xb02a, 0xb02b, 0xb02c, 0xb02d, 0xb02e, 0xb02f, 
+    0xb030, 0xb031, 0xb032, 0xb033, 0xb034, 0xb035, 0xb036, 0xb037, 
+    0xb038, 0xb039, 0xb03a, 0xb03b, 0xb03c, 0xb03d, 0xb03e, 0xb03f, 
+    0xb040, 0xb041, 0xb042, 0xb043, 0xb044, 0xb045, 0xb046, 0xb047, 
+    0xb048, 0xb049, 0xb04a, 0xb04b, 0xb04c, 0xb04d, 0xb04e, 0xb04f, 
+    0xb050, 0xb051, 0xb052, 0xb053, 0xb054, 0xb055, 0xb056, 0xb057, 
+    0xb058, 0xb059, 0xb05a, 0xb05b, 0xb05c, 0xb05d, 0xb05e, 0xb05f, 
+    0xb060, 0xb061, 0xb062, 0xb063, 0xb064, 0xb065, 0xb066, 0xb067, 
+    0xb068, 0xb069, 0xb06a, 0xb06b, 0xb06c, 0xb06d, 0xb06e, 0xb06f, 
+    0xb070, 0xb071, 0xb072, 0xb073, 0xb074, 0xb075, 0xb076, 0xb077, 
+    0xb078, 0xb079, 0xb07a, 0xb07b, 0xb07c, 0xb07d, 0xb07e, 0xb07f, 
+    0xb080, 0xb081, 0xb082, 0xb083, 0xb084, 0xb085, 0xb086, 0xb087, 
+    0xb088, 0xb089, 0xb08a, 0xb08b, 0xb08c, 0xb08d, 0xb08e, 0xb08f, 
+    0xb090, 0xb091, 0xb092, 0xb093, 0xb094, 0xb095, 0xb096, 0xb097, 
+    0xb098, 0xb099, 0xb09a, 0xb09b, 0xb09c, 0xb09d, 0xb09e, 0xb09f, 
+    0xb0a0, 0xb0a1, 0xb0a2, 0xb0a3, 0xb0a4, 0xb0a5, 0xb0a6, 0xb0a7, 
+    0xb0a8, 0xb0a9, 0xb0aa, 0xb0ab, 0xb0ac, 0xb0ad, 0xb0ae, 0xb0af, 
+    0xb0b0, 0xb0b1, 0xb0b2, 0xb0b3, 0xb0b4, 0xb0b5, 0xb0b6, 0xb0b7, 
+    0xb0b8, 0xb0b9, 0xb0ba, 0xb0bb, 0xb0bc, 0xb0bd, 0xb0be, 0xb0bf, 
+    0xb0c0, 0xb0c1, 0xb0c2, 0xb0c3, 0xb0c4, 0xb0c5, 0xb0c6, 0xb0c7, 
+    0xb0c8, 0xb0c9, 0xb0ca, 0xb0cb, 0xb0cc, 0xb0cd, 0xb0ce, 0xb0cf, 
+    0xb0d0, 0xb0d1, 0xb0d2, 0xb0d3, 0xb0d4, 0xb0d5, 0xb0d6, 0xb0d7, 
+    0xb0d8, 0xb0d9, 0xb0da, 0xb0db, 0xb0dc, 0xb0dd, 0xb0de, 0xb0df, 
+    0xb0e0, 0xb0e1, 0xb0e2, 0xb0e3, 0xb0e4, 0xb0e5, 0xb0e6, 0xb0e7, 
+    0xb0e8, 0xb0e9, 0xb0ea, 0xb0eb, 0xb0ec, 0xb0ed, 0xb0ee, 0xb0ef, 
+    0xb0f0, 0xb0f1, 0xb0f2, 0xb0f3, 0xb0f4, 0xb0f5, 0xb0f6, 0xb0f7, 
+    0xb0f8, 0xb0f9, 0xb0fa, 0xb0fb, 0xb0fc, 0xb0fd, 0xb0fe, 0xb0ff, 
+    0xb100, 0xb101, 0xb102, 0xb103, 0xb104, 0xb105, 0xb106, 0xb107, 
+    0xb108, 0xb109, 0xb10a, 0xb10b, 0xb10c, 0xb10d, 0xb10e, 0xb10f, 
+    0xb110, 0xb111, 0xb112, 0xb113, 0xb114, 0xb115, 0xb116, 0xb117, 
+    0xb118, 0xb119, 0xb11a, 0xb11b, 0xb11c, 0xb11d, 0xb11e, 0xb11f, 
+    0xb120, 0xb121, 0xb122, 0xb123, 0xb124, 0xb125, 0xb126, 0xb127, 
+    0xb128, 0xb129, 0xb12a, 0xb12b, 0xb12c, 0xb12d, 0xb12e, 0xb12f, 
+    0xb130, 0xb131, 0xb132, 0xb133, 0xb134, 0xb135, 0xb136, 0xb137, 
+    0xb138, 0xb139, 0xb13a, 0xb13b, 0xb13c, 0xb13d, 0xb13e, 0xb13f, 
+    0xb140, 0xb141, 0xb142, 0xb143, 0xb144, 0xb145, 0xb146, 0xb147, 
+    0xb148, 0xb149, 0xb14a, 0xb14b, 0xb14c, 0xb14d, 0xb14e, 0xb14f, 
+    0xb150, 0xb151, 0xb152, 0xb153, 0xb154, 0xb155, 0xb156, 0xb157, 
+    0xb158, 0xb159, 0xb15a, 0xb15b, 0xb15c, 0xb15d, 0xb15e, 0xb15f, 
+    0xb160, 0xb161, 0xb162, 0xb163, 0xb164, 0xb165, 0xb166, 0xb167, 
+    0xb168, 0xb169, 0xb16a, 0xb16b, 0xb16c, 0xb16d, 0xb16e, 0xb16f, 
+    0xb170, 0xb171, 0xb172, 0xb173, 0xb174, 0xb175, 0xb176, 0xb177, 
+    0xb178, 0xb179, 0xb17a, 0xb17b, 0xb17c, 0xb17d, 0xb17e, 0xb17f, 
+    0xb180, 0xb181, 0xb182, 0xb183, 0xb184, 0xb185, 0xb186, 0xb187, 
+    0xb188, 0xb189, 0xb18a, 0xb18b, 0xb18c, 0xb18d, 0xb18e, 0xb18f, 
+    0xb190, 0xb191, 0xb192, 0xb193, 0xb194, 0xb195, 0xb196, 0xb197, 
+    0xb198, 0xb199, 0xb19a, 0xb19b, 0xb19c, 0xb19d, 0xb19e, 0xb19f, 
+    0xb1a0, 0xb1a1, 0xb1a2, 0xb1a3, 0xb1a4, 0xb1a5, 0xb1a6, 0xb1a7, 
+    0xb1a8, 0xb1a9, 0xb1aa, 0xb1ab, 0xb1ac, 0xb1ad, 0xb1ae, 0xb1af, 
+    0xb1b0, 0xb1b1, 0xb1b2, 0xb1b3, 0xb1b4, 0xb1b5, 0xb1b6, 0xb1b7, 
+    0xb1b8, 0xb1b9, 0xb1ba, 0xb1bb, 0xb1bc, 0xb1bd, 0xb1be, 0xb1bf, 
+    0xb1c0, 0xb1c1, 0xb1c2, 0xb1c3, 0xb1c4, 0xb1c5, 0xb1c6, 0xb1c7, 
+    0xb1c8, 0xb1c9, 0xb1ca, 0xb1cb, 0xb1cc, 0xb1cd, 0xb1ce, 0xb1cf, 
+    0xb1d0, 0xb1d1, 0xb1d2, 0xb1d3, 0xb1d4, 0xb1d5, 0xb1d6, 0xb1d7, 
+    0xb1d8, 0xb1d9, 0xb1da, 0xb1db, 0xb1dc, 0xb1dd, 0xb1de, 0xb1df, 
+    0xb1e0, 0xb1e1, 0xb1e2, 0xb1e3, 0xb1e4, 0xb1e5, 0xb1e6, 0xb1e7, 
+    0xb1e8, 0xb1e9, 0xb1ea, 0xb1eb, 0xb1ec, 0xb1ed, 0xb1ee, 0xb1ef, 
+    0xb1f0, 0xb1f1, 0xb1f2, 0xb1f3, 0xb1f4, 0xb1f5, 0xb1f6, 0xb1f7, 
+    0xb1f8, 0xb1f9, 0xb1fa, 0xb1fb, 0xb1fc, 0xb1fd, 0xb1fe, 0xb1ff, 
+    0xb200, 0xb201, 0xb202, 0xb203, 0xb204, 0xb205, 0xb206, 0xb207, 
+    0xb208, 0xb209, 0xb20a, 0xb20b, 0xb20c, 0xb20d, 0xb20e, 0xb20f, 
+    0xb210, 0xb211, 0xb212, 0xb213, 0xb214, 0xb215, 0xb216, 0xb217, 
+    0xb218, 0xb219, 0xb21a, 0xb21b, 0xb21c, 0xb21d, 0xb21e, 0xb21f, 
+    0xb220, 0xb221, 0xb222, 0xb223, 0xb224, 0xb225, 0xb226, 0xb227, 
+    0xb228, 0xb229, 0xb22a, 0xb22b, 0xb22c, 0xb22d, 0xb22e, 0xb22f, 
+    0xb230, 0xb231, 0xb232, 0xb233, 0xb234, 0xb235, 0xb236, 0xb237, 
+    0xb238, 0xb239, 0xb23a, 0xb23b, 0xb23c, 0xb23d, 0xb23e, 0xb23f, 
+    0xb240, 0xb241, 0xb242, 0xb243, 0xb244, 0xb245, 0xb246, 0xb247, 
+    0xb248, 0xb249, 0xb24a, 0xb24b, 0xb24c, 0xb24d, 0xb24e, 0xb24f, 
+    0xb250, 0xb251, 0xb252, 0xb253, 0xb254, 0xb255, 0xb256, 0xb257, 
+    0xb258, 0xb259, 0xb25a, 0xb25b, 0xb25c, 0xb25d, 0xb25e, 0xb25f, 
+    0xb260, 0xb261, 0xb262, 0xb263, 0xb264, 0xb265, 0xb266, 0xb267, 
+    0xb268, 0xb269, 0xb26a, 0xb26b, 0xb26c, 0xb26d, 0xb26e, 0xb26f, 
+    0xb270, 0xb271, 0xb272, 0xb273, 0xb274, 0xb275, 0xb276, 0xb277, 
+    0xb278, 0xb279, 0xb27a, 0xb27b, 0xb27c, 0xb27d, 0xb27e, 0xb27f, 
+    0xb280, 0xb281, 0xb282, 0xb283, 0xb284, 0xb285, 0xb286, 0xb287, 
+    0xb288, 0xb289, 0xb28a, 0xb28b, 0xb28c, 0xb28d, 0xb28e, 0xb28f, 
+    0xb290, 0xb291, 0xb292, 0xb293, 0xb294, 0xb295, 0xb296, 0xb297, 
+    0xb298, 0xb299, 0xb29a, 0xb29b, 0xb29c, 0xb29d, 0xb29e, 0xb29f, 
+    0xb2a0, 0xb2a1, 0xb2a2, 0xb2a3, 0xb2a4, 0xb2a5, 0xb2a6, 0xb2a7, 
+    0xb2a8, 0xb2a9, 0xb2aa, 0xb2ab, 0xb2ac, 0xb2ad, 0xb2ae, 0xb2af, 
+    0xb2b0, 0xb2b1, 0xb2b2, 0xb2b3, 0xb2b4, 0xb2b5, 0xb2b6, 0xb2b7, 
+    0xb2b8, 0xb2b9, 0xb2ba, 0xb2bb, 0xb2bc, 0xb2bd, 0xb2be, 0xb2bf, 
+    0xb2c0, 0xb2c1, 0xb2c2, 0xb2c3, 0xb2c4, 0xb2c5, 0xb2c6, 0xb2c7, 
+    0xb2c8, 0xb2c9, 0xb2ca, 0xb2cb, 0xb2cc, 0xb2cd, 0xb2ce, 0xb2cf, 
+    0xb2d0, 0xb2d1, 0xb2d2, 0xb2d3, 0xb2d4, 0xb2d5, 0xb2d6, 0xb2d7, 
+    0xb2d8, 0xb2d9, 0xb2da, 0xb2db, 0xb2dc, 0xb2dd, 0xb2de, 0xb2df, 
+    0xb2e0, 0xb2e1, 0xb2e2, 0xb2e3, 0xb2e4, 0xb2e5, 0xb2e6, 0xb2e7, 
+    0xb2e8, 0xb2e9, 0xb2ea, 0xb2eb, 0xb2ec, 0xb2ed, 0xb2ee, 0xb2ef, 
+    0xb2f0, 0xb2f1, 0xb2f2, 0xb2f3, 0xb2f4, 0xb2f5, 0xb2f6, 0xb2f7, 
+    0xb2f8, 0xb2f9, 0xb2fa, 0xb2fb, 0xb2fc, 0xb2fd, 0xb2fe, 0xb2ff, 
+    0xb300, 0xb301, 0xb302, 0xb303, 0xb304, 0xb305, 0xb306, 0xb307, 
+    0xb308, 0xb309, 0xb30a, 0xb30b, 0xb30c, 0xb30d, 0xb30e, 0xb30f, 
+    0xb310, 0xb311, 0xb312, 0xb313, 0xb314, 0xb315, 0xb316, 0xb317, 
+    0xb318, 0xb319, 0xb31a, 0xb31b, 0xb31c, 0xb31d, 0xb31e, 0xb31f, 
+    0xb320, 0xb321, 0xb322, 0xb323, 0xb324, 0xb325, 0xb326, 0xb327, 
+    0xb328, 0xb329, 0xb32a, 0xb32b, 0xb32c, 0xb32d, 0xb32e, 0xb32f, 
+    0xb330, 0xb331, 0xb332, 0xb333, 0xb334, 0xb335, 0xb336, 0xb337, 
+    0xb338, 0xb339, 0xb33a, 0xb33b, 0xb33c, 0xb33d, 0xb33e, 0xb33f, 
+    0xb340, 0xb341, 0xb342, 0xb343, 0xb344, 0xb345, 0xb346, 0xb347, 
+    0xb348, 0xb349, 0xb34a, 0xb34b, 0xb34c, 0xb34d, 0xb34e, 0xb34f, 
+    0xb350, 0xb351, 0xb352, 0xb353, 0xb354, 0xb355, 0xb356, 0xb357, 
+    0xb358, 0xb359, 0xb35a, 0xb35b, 0xb35c, 0xb35d, 0xb35e, 0xb35f, 
+    0xb360, 0xb361, 0xb362, 0xb363, 0xb364, 0xb365, 0xb366, 0xb367, 
+    0xb368, 0xb369, 0xb36a, 0xb36b, 0xb36c, 0xb36d, 0xb36e, 0xb36f, 
+    0xb370, 0xb371, 0xb372, 0xb373, 0xb374, 0xb375, 0xb376, 0xb377, 
+    0xb378, 0xb379, 0xb37a, 0xb37b, 0xb37c, 0xb37d, 0xb37e, 0xb37f, 
+    0xb380, 0xb381, 0xb382, 0xb383, 0xb384, 0xb385, 0xb386, 0xb387, 
+    0xb388, 0xb389, 0xb38a, 0xb38b, 0xb38c, 0xb38d, 0xb38e, 0xb38f, 
+    0xb390, 0xb391, 0xb392, 0xb393, 0xb394, 0xb395, 0xb396, 0xb397, 
+    0xb398, 0xb399, 0xb39a, 0xb39b, 0xb39c, 0xb39d, 0xb39e, 0xb39f, 
+    0xb3a0, 0xb3a1, 0xb3a2, 0xb3a3, 0xb3a4, 0xb3a5, 0xb3a6, 0xb3a7, 
+    0xb3a8, 0xb3a9, 0xb3aa, 0xb3ab, 0xb3ac, 0xb3ad, 0xb3ae, 0xb3af, 
+    0xb3b0, 0xb3b1, 0xb3b2, 0xb3b3, 0xb3b4, 0xb3b5, 0xb3b6, 0xb3b7, 
+    0xb3b8, 0xb3b9, 0xb3ba, 0xb3bb, 0xb3bc, 0xb3bd, 0xb3be, 0xb3bf, 
+    0xb3c0, 0xb3c1, 0xb3c2, 0xb3c3, 0xb3c4, 0xb3c5, 0xb3c6, 0xb3c7, 
+    0xb3c8, 0xb3c9, 0xb3ca, 0xb3cb, 0xb3cc, 0xb3cd, 0xb3ce, 0xb3cf, 
+    0xb3d0, 0xb3d1, 0xb3d2, 0xb3d3, 0xb3d4, 0xb3d5, 0xb3d6, 0xb3d7, 
+    0xb3d8, 0xb3d9, 0xb3da, 0xb3db, 0xb3dc, 0xb3dd, 0xb3de, 0xb3df, 
+    0xb3e0, 0xb3e1, 0xb3e2, 0xb3e3, 0xb3e4, 0xb3e5, 0xb3e6, 0xb3e7, 
+    0xb3e8, 0xb3e9, 0xb3ea, 0xb3eb, 0xb3ec, 0xb3ed, 0xb3ee, 0xb3ef, 
+    0xb3f0, 0xb3f1, 0xb3f2, 0xb3f3, 0xb3f4, 0xb3f5, 0xb3f6, 0xb3f7, 
+    0xb3f8, 0xb3f9, 0xb3fa, 0xb3fb, 0xb3fc, 0xb3fd, 0xb3fe, 0xb3ff, 
+    0xb400, 0xb401, 0xb402, 0xb403, 0xb404, 0xb405, 0xb406, 0xb407, 
+    0xb408, 0xb409, 0xb40a, 0xb40b, 0xb40c, 0xb40d, 0xb40e, 0xb40f, 
+    0xb410, 0xb411, 0xb412, 0xb413, 0xb414, 0xb415, 0xb416, 0xb417, 
+    0xb418, 0xb419, 0xb41a, 0xb41b, 0xb41c, 0xb41d, 0xb41e, 0xb41f, 
+    0xb420, 0xb421, 0xb422, 0xb423, 0xb424, 0xb425, 0xb426, 0xb427, 
+    0xb428, 0xb429, 0xb42a, 0xb42b, 0xb42c, 0xb42d, 0xb42e, 0xb42f, 
+    0xb430, 0xb431, 0xb432, 0xb433, 0xb434, 0xb435, 0xb436, 0xb437, 
+    0xb438, 0xb439, 0xb43a, 0xb43b, 0xb43c, 0xb43d, 0xb43e, 0xb43f, 
+    0xb440, 0xb441, 0xb442, 0xb443, 0xb444, 0xb445, 0xb446, 0xb447, 
+    0xb448, 0xb449, 0xb44a, 0xb44b, 0xb44c, 0xb44d, 0xb44e, 0xb44f, 
+    0xb450, 0xb451, 0xb452, 0xb453, 0xb454, 0xb455, 0xb456, 0xb457, 
+    0xb458, 0xb459, 0xb45a, 0xb45b, 0xb45c, 0xb45d, 0xb45e, 0xb45f, 
+    0xb460, 0xb461, 0xb462, 0xb463, 0xb464, 0xb465, 0xb466, 0xb467, 
+    0xb468, 0xb469, 0xb46a, 0xb46b, 0xb46c, 0xb46d, 0xb46e, 0xb46f, 
+    0xb470, 0xb471, 0xb472, 0xb473, 0xb474, 0xb475, 0xb476, 0xb477, 
+    0xb478, 0xb479, 0xb47a, 0xb47b, 0xb47c, 0xb47d, 0xb47e, 0xb47f, 
+    0xb480, 0xb481, 0xb482, 0xb483, 0xb484, 0xb485, 0xb486, 0xb487, 
+    0xb488, 0xb489, 0xb48a, 0xb48b, 0xb48c, 0xb48d, 0xb48e, 0xb48f, 
+    0xb490, 0xb491, 0xb492, 0xb493, 0xb494, 0xb495, 0xb496, 0xb497, 
+    0xb498, 0xb499, 0xb49a, 0xb49b, 0xb49c, 0xb49d, 0xb49e, 0xb49f, 
+    0xb4a0, 0xb4a1, 0xb4a2, 0xb4a3, 0xb4a4, 0xb4a5, 0xb4a6, 0xb4a7, 
+    0xb4a8, 0xb4a9, 0xb4aa, 0xb4ab, 0xb4ac, 0xb4ad, 0xb4ae, 0xb4af, 
+    0xb4b0, 0xb4b1, 0xb4b2, 0xb4b3, 0xb4b4, 0xb4b5, 0xb4b6, 0xb4b7, 
+    0xb4b8, 0xb4b9, 0xb4ba, 0xb4bb, 0xb4bc, 0xb4bd, 0xb4be, 0xb4bf, 
+    0xb4c0, 0xb4c1, 0xb4c2, 0xb4c3, 0xb4c4, 0xb4c5, 0xb4c6, 0xb4c7, 
+    0xb4c8, 0xb4c9, 0xb4ca, 0xb4cb, 0xb4cc, 0xb4cd, 0xb4ce, 0xb4cf, 
+    0xb4d0, 0xb4d1, 0xb4d2, 0xb4d3, 0xb4d4, 0xb4d5, 0xb4d6, 0xb4d7, 
+    0xb4d8, 0xb4d9, 0xb4da, 0xb4db, 0xb4dc, 0xb4dd, 0xb4de, 0xb4df, 
+    0xb4e0, 0xb4e1, 0xb4e2, 0xb4e3, 0xb4e4, 0xb4e5, 0xb4e6, 0xb4e7, 
+    0xb4e8, 0xb4e9, 0xb4ea, 0xb4eb, 0xb4ec, 0xb4ed, 0xb4ee, 0xb4ef, 
+    0xb4f0, 0xb4f1, 0xb4f2, 0xb4f3, 0xb4f4, 0xb4f5, 0xb4f6, 0xb4f7, 
+    0xb4f8, 0xb4f9, 0xb4fa, 0xb4fb, 0xb4fc, 0xb4fd, 0xb4fe, 0xb4ff, 
+    0xb500, 0xb501, 0xb502, 0xb503, 0xb504, 0xb505, 0xb506, 0xb507, 
+    0xb508, 0xb509, 0xb50a, 0xb50b, 0xb50c, 0xb50d, 0xb50e, 0xb50f, 
+    0xb510, 0xb511, 0xb512, 0xb513, 0xb514, 0xb515, 0xb516, 0xb517, 
+    0xb518, 0xb519, 0xb51a, 0xb51b, 0xb51c, 0xb51d, 0xb51e, 0xb51f, 
+    0xb520, 0xb521, 0xb522, 0xb523, 0xb524, 0xb525, 0xb526, 0xb527, 
+    0xb528, 0xb529, 0xb52a, 0xb52b, 0xb52c, 0xb52d, 0xb52e, 0xb52f, 
+    0xb530, 0xb531, 0xb532, 0xb533, 0xb534, 0xb535, 0xb536, 0xb537, 
+    0xb538, 0xb539, 0xb53a, 0xb53b, 0xb53c, 0xb53d, 0xb53e, 0xb53f, 
+    0xb540, 0xb541, 0xb542, 0xb543, 0xb544, 0xb545, 0xb546, 0xb547, 
+    0xb548, 0xb549, 0xb54a, 0xb54b, 0xb54c, 0xb54d, 0xb54e, 0xb54f, 
+    0xb550, 0xb551, 0xb552, 0xb553, 0xb554, 0xb555, 0xb556, 0xb557, 
+    0xb558, 0xb559, 0xb55a, 0xb55b, 0xb55c, 0xb55d, 0xb55e, 0xb55f, 
+    0xb560, 0xb561, 0xb562, 0xb563, 0xb564, 0xb565, 0xb566, 0xb567, 
+    0xb568, 0xb569, 0xb56a, 0xb56b, 0xb56c, 0xb56d, 0xb56e, 0xb56f, 
+    0xb570, 0xb571, 0xb572, 0xb573, 0xb574, 0xb575, 0xb576, 0xb577, 
+    0xb578, 0xb579, 0xb57a, 0xb57b, 0xb57c, 0xb57d, 0xb57e, 0xb57f, 
+    0xb580, 0xb581, 0xb582, 0xb583, 0xb584, 0xb585, 0xb586, 0xb587, 
+    0xb588, 0xb589, 0xb58a, 0xb58b, 0xb58c, 0xb58d, 0xb58e, 0xb58f, 
+    0xb590, 0xb591, 0xb592, 0xb593, 0xb594, 0xb595, 0xb596, 0xb597, 
+    0xb598, 0xb599, 0xb59a, 0xb59b, 0xb59c, 0xb59d, 0xb59e, 0xb59f, 
+    0xb5a0, 0xb5a1, 0xb5a2, 0xb5a3, 0xb5a4, 0xb5a5, 0xb5a6, 0xb5a7, 
+    0xb5a8, 0xb5a9, 0xb5aa, 0xb5ab, 0xb5ac, 0xb5ad, 0xb5ae, 0xb5af, 
+    0xb5b0, 0xb5b1, 0xb5b2, 0xb5b3, 0xb5b4, 0xb5b5, 0xb5b6, 0xb5b7, 
+    0xb5b8, 0xb5b9, 0xb5ba, 0xb5bb, 0xb5bc, 0xb5bd, 0xb5be, 0xb5bf, 
+    0xb5c0, 0xb5c1, 0xb5c2, 0xb5c3, 0xb5c4, 0xb5c5, 0xb5c6, 0xb5c7, 
+    0xb5c8, 0xb5c9, 0xb5ca, 0xb5cb, 0xb5cc, 0xb5cd, 0xb5ce, 0xb5cf, 
+    0xb5d0, 0xb5d1, 0xb5d2, 0xb5d3, 0xb5d4, 0xb5d5, 0xb5d6, 0xb5d7, 
+    0xb5d8, 0xb5d9, 0xb5da, 0xb5db, 0xb5dc, 0xb5dd, 0xb5de, 0xb5df, 
+    0xb5e0, 0xb5e1, 0xb5e2, 0xb5e3, 0xb5e4, 0xb5e5, 0xb5e6, 0xb5e7, 
+    0xb5e8, 0xb5e9, 0xb5ea, 0xb5eb, 0xb5ec, 0xb5ed, 0xb5ee, 0xb5ef, 
+    0xb5f0, 0xb5f1, 0xb5f2, 0xb5f3, 0xb5f4, 0xb5f5, 0xb5f6, 0xb5f7, 
+    0xb5f8, 0xb5f9, 0xb5fa, 0xb5fb, 0xb5fc, 0xb5fd, 0xb5fe, 0xb5ff, 
+    0xb600, 0xb601, 0xb602, 0xb603, 0xb604, 0xb605, 0xb606, 0xb607, 
+    0xb608, 0xb609, 0xb60a, 0xb60b, 0xb60c, 0xb60d, 0xb60e, 0xb60f, 
+    0xb610, 0xb611, 0xb612, 0xb613, 0xb614, 0xb615, 0xb616, 0xb617, 
+    0xb618, 0xb619, 0xb61a, 0xb61b, 0xb61c, 0xb61d, 0xb61e, 0xb61f, 
+    0xb620, 0xb621, 0xb622, 0xb623, 0xb624, 0xb625, 0xb626, 0xb627, 
+    0xb628, 0xb629, 0xb62a, 0xb62b, 0xb62c, 0xb62d, 0xb62e, 0xb62f, 
+    0xb630, 0xb631, 0xb632, 0xb633, 0xb634, 0xb635, 0xb636, 0xb637, 
+    0xb638, 0xb639, 0xb63a, 0xb63b, 0xb63c, 0xb63d, 0xb63e, 0xb63f, 
+    0xb640, 0xb641, 0xb642, 0xb643, 0xb644, 0xb645, 0xb646, 0xb647, 
+    0xb648, 0xb649, 0xb64a, 0xb64b, 0xb64c, 0xb64d, 0xb64e, 0xb64f, 
+    0xb650, 0xb651, 0xb652, 0xb653, 0xb654, 0xb655, 0xb656, 0xb657, 
+    0xb658, 0xb659, 0xb65a, 0xb65b, 0xb65c, 0xb65d, 0xb65e, 0xb65f, 
+    0xb660, 0xb661, 0xb662, 0xb663, 0xb664, 0xb665, 0xb666, 0xb667, 
+    0xb668, 0xb669, 0xb66a, 0xb66b, 0xb66c, 0xb66d, 0xb66e, 0xb66f, 
+    0xb670, 0xb671, 0xb672, 0xb673, 0xb674, 0xb675, 0xb676, 0xb677, 
+    0xb678, 0xb679, 0xb67a, 0xb67b, 0xb67c, 0xb67d, 0xb67e, 0xb67f, 
+    0xb680, 0xb681, 0xb682, 0xb683, 0xb684, 0xb685, 0xb686, 0xb687, 
+    0xb688, 0xb689, 0xb68a, 0xb68b, 0xb68c, 0xb68d, 0xb68e, 0xb68f, 
+    0xb690, 0xb691, 0xb692, 0xb693, 0xb694, 0xb695, 0xb696, 0xb697, 
+    0xb698, 0xb699, 0xb69a, 0xb69b, 0xb69c, 0xb69d, 0xb69e, 0xb69f, 
+    0xb6a0, 0xb6a1, 0xb6a2, 0xb6a3, 0xb6a4, 0xb6a5, 0xb6a6, 0xb6a7, 
+    0xb6a8, 0xb6a9, 0xb6aa, 0xb6ab, 0xb6ac, 0xb6ad, 0xb6ae, 0xb6af, 
+    0xb6b0, 0xb6b1, 0xb6b2, 0xb6b3, 0xb6b4, 0xb6b5, 0xb6b6, 0xb6b7, 
+    0xb6b8, 0xb6b9, 0xb6ba, 0xb6bb, 0xb6bc, 0xb6bd, 0xb6be, 0xb6bf, 
+    0xb6c0, 0xb6c1, 0xb6c2, 0xb6c3, 0xb6c4, 0xb6c5, 0xb6c6, 0xb6c7, 
+    0xb6c8, 0xb6c9, 0xb6ca, 0xb6cb, 0xb6cc, 0xb6cd, 0xb6ce, 0xb6cf, 
+    0xb6d0, 0xb6d1, 0xb6d2, 0xb6d3, 0xb6d4, 0xb6d5, 0xb6d6, 0xb6d7, 
+    0xb6d8, 0xb6d9, 0xb6da, 0xb6db, 0xb6dc, 0xb6dd, 0xb6de, 0xb6df, 
+    0xb6e0, 0xb6e1, 0xb6e2, 0xb6e3, 0xb6e4, 0xb6e5, 0xb6e6, 0xb6e7, 
+    0xb6e8, 0xb6e9, 0xb6ea, 0xb6eb, 0xb6ec, 0xb6ed, 0xb6ee, 0xb6ef, 
+    0xb6f0, 0xb6f1, 0xb6f2, 0xb6f3, 0xb6f4, 0xb6f5, 0xb6f6, 0xb6f7, 
+    0xb6f8, 0xb6f9, 0xb6fa, 0xb6fb, 0xb6fc, 0xb6fd, 0xb6fe, 0xb6ff, 
+    0xb700, 0xb701, 0xb702, 0xb703, 0xb704, 0xb705, 0xb706, 0xb707, 
+    0xb708, 0xb709, 0xb70a, 0xb70b, 0xb70c, 0xb70d, 0xb70e, 0xb70f, 
+    0xb710, 0xb711, 0xb712, 0xb713, 0xb714, 0xb715, 0xb716, 0xb717, 
+    0xb718, 0xb719, 0xb71a, 0xb71b, 0xb71c, 0xb71d, 0xb71e, 0xb71f, 
+    0xb720, 0xb721, 0xb722, 0xb723, 0xb724, 0xb725, 0xb726, 0xb727, 
+    0xb728, 0xb729, 0xb72a, 0xb72b, 0xb72c, 0xb72d, 0xb72e, 0xb72f, 
+    0xb730, 0xb731, 0xb732, 0xb733, 0xb734, 0xb735, 0xb736, 0xb737, 
+    0xb738, 0xb739, 0xb73a, 0xb73b, 0xb73c, 0xb73d, 0xb73e, 0xb73f, 
+    0xb740, 0xb741, 0xb742, 0xb743, 0xb744, 0xb745, 0xb746, 0xb747, 
+    0xb748, 0xb749, 0xb74a, 0xb74b, 0xb74c, 0xb74d, 0xb74e, 0xb74f, 
+    0xb750, 0xb751, 0xb752, 0xb753, 0xb754, 0xb755, 0xb756, 0xb757, 
+    0xb758, 0xb759, 0xb75a, 0xb75b, 0xb75c, 0xb75d, 0xb75e, 0xb75f, 
+    0xb760, 0xb761, 0xb762, 0xb763, 0xb764, 0xb765, 0xb766, 0xb767, 
+    0xb768, 0xb769, 0xb76a, 0xb76b, 0xb76c, 0xb76d, 0xb76e, 0xb76f, 
+    0xb770, 0xb771, 0xb772, 0xb773, 0xb774, 0xb775, 0xb776, 0xb777, 
+    0xb778, 0xb779, 0xb77a, 0xb77b, 0xb77c, 0xb77d, 0xb77e, 0xb77f, 
+    0xb780, 0xb781, 0xb782, 0xb783, 0xb784, 0xb785, 0xb786, 0xb787, 
+    0xb788, 0xb789, 0xb78a, 0xb78b, 0xb78c, 0xb78d, 0xb78e, 0xb78f, 
+    0xb790, 0xb791, 0xb792, 0xb793, 0xb794, 0xb795, 0xb796, 0xb797, 
+    0xb798, 0xb799, 0xb79a, 0xb79b, 0xb79c, 0xb79d, 0xb79e, 0xb79f, 
+    0xb7a0, 0xb7a1, 0xb7a2, 0xb7a3, 0xb7a4, 0xb7a5, 0xb7a6, 0xb7a7, 
+    0xb7a8, 0xb7a9, 0xb7aa, 0xb7ab, 0xb7ac, 0xb7ad, 0xb7ae, 0xb7af, 
+    0xb7b0, 0xb7b1, 0xb7b2, 0xb7b3, 0xb7b4, 0xb7b5, 0xb7b6, 0xb7b7, 
+    0xb7b8, 0xb7b9, 0xb7ba, 0xb7bb, 0xb7bc, 0xb7bd, 0xb7be, 0xb7bf, 
+    0xb7c0, 0xb7c1, 0xb7c2, 0xb7c3, 0xb7c4, 0xb7c5, 0xb7c6, 0xb7c7, 
+    0xb7c8, 0xb7c9, 0xb7ca, 0xb7cb, 0xb7cc, 0xb7cd, 0xb7ce, 0xb7cf, 
+    0xb7d0, 0xb7d1, 0xb7d2, 0xb7d3, 0xb7d4, 0xb7d5, 0xb7d6, 0xb7d7, 
+    0xb7d8, 0xb7d9, 0xb7da, 0xb7db, 0xb7dc, 0xb7dd, 0xb7de, 0xb7df, 
+    0xb7e0, 0xb7e1, 0xb7e2, 0xb7e3, 0xb7e4, 0xb7e5, 0xb7e6, 0xb7e7, 
+    0xb7e8, 0xb7e9, 0xb7ea, 0xb7eb, 0xb7ec, 0xb7ed, 0xb7ee, 0xb7ef, 
+    0xb7f0, 0xb7f1, 0xb7f2, 0xb7f3, 0xb7f4, 0xb7f5, 0xb7f6, 0xb7f7, 
+    0xb7f8, 0xb7f9, 0xb7fa, 0xb7fb, 0xb7fc, 0xb7fd, 0xb7fe, 0xb7ff, 
+    0xb800, 0xb801, 0xb802, 0xb803, 0xb804, 0xb805, 0xb806, 0xb807, 
+    0xb808, 0xb809, 0xb80a, 0xb80b, 0xb80c, 0xb80d, 0xb80e, 0xb80f, 
+    0xb810, 0xb811, 0xb812, 0xb813, 0xb814, 0xb815, 0xb816, 0xb817, 
+    0xb818, 0xb819, 0xb81a, 0xb81b, 0xb81c, 0xb81d, 0xb81e, 0xb81f, 
+    0xb820, 0xb821, 0xb822, 0xb823, 0xb824, 0xb825, 0xb826, 0xb827, 
+    0xb828, 0xb829, 0xb82a, 0xb82b, 0xb82c, 0xb82d, 0xb82e, 0xb82f, 
+    0xb830, 0xb831, 0xb832, 0xb833, 0xb834, 0xb835, 0xb836, 0xb837, 
+    0xb838, 0xb839, 0xb83a, 0xb83b, 0xb83c, 0xb83d, 0xb83e, 0xb83f, 
+    0xb840, 0xb841, 0xb842, 0xb843, 0xb844, 0xb845, 0xb846, 0xb847, 
+    0xb848, 0xb849, 0xb84a, 0xb84b, 0xb84c, 0xb84d, 0xb84e, 0xb84f, 
+    0xb850, 0xb851, 0xb852, 0xb853, 0xb854, 0xb855, 0xb856, 0xb857, 
+    0xb858, 0xb859, 0xb85a, 0xb85b, 0xb85c, 0xb85d, 0xb85e, 0xb85f, 
+    0xb860, 0xb861, 0xb862, 0xb863, 0xb864, 0xb865, 0xb866, 0xb867, 
+    0xb868, 0xb869, 0xb86a, 0xb86b, 0xb86c, 0xb86d, 0xb86e, 0xb86f, 
+    0xb870, 0xb871, 0xb872, 0xb873, 0xb874, 0xb875, 0xb876, 0xb877, 
+    0xb878, 0xb879, 0xb87a, 0xb87b, 0xb87c, 0xb87d, 0xb87e, 0xb87f, 
+    0xb880, 0xb881, 0xb882, 0xb883, 0xb884, 0xb885, 0xb886, 0xb887, 
+    0xb888, 0xb889, 0xb88a, 0xb88b, 0xb88c, 0xb88d, 0xb88e, 0xb88f, 
+    0xb890, 0xb891, 0xb892, 0xb893, 0xb894, 0xb895, 0xb896, 0xb897, 
+    0xb898, 0xb899, 0xb89a, 0xb89b, 0xb89c, 0xb89d, 0xb89e, 0xb89f, 
+    0xb8a0, 0xb8a1, 0xb8a2, 0xb8a3, 0xb8a4, 0xb8a5, 0xb8a6, 0xb8a7, 
+    0xb8a8, 0xb8a9, 0xb8aa, 0xb8ab, 0xb8ac, 0xb8ad, 0xb8ae, 0xb8af, 
+    0xb8b0, 0xb8b1, 0xb8b2, 0xb8b3, 0xb8b4, 0xb8b5, 0xb8b6, 0xb8b7, 
+    0xb8b8, 0xb8b9, 0xb8ba, 0xb8bb, 0xb8bc, 0xb8bd, 0xb8be, 0xb8bf, 
+    0xb8c0, 0xb8c1, 0xb8c2, 0xb8c3, 0xb8c4, 0xb8c5, 0xb8c6, 0xb8c7, 
+    0xb8c8, 0xb8c9, 0xb8ca, 0xb8cb, 0xb8cc, 0xb8cd, 0xb8ce, 0xb8cf, 
+    0xb8d0, 0xb8d1, 0xb8d2, 0xb8d3, 0xb8d4, 0xb8d5, 0xb8d6, 0xb8d7, 
+    0xb8d8, 0xb8d9, 0xb8da, 0xb8db, 0xb8dc, 0xb8dd, 0xb8de, 0xb8df, 
+    0xb8e0, 0xb8e1, 0xb8e2, 0xb8e3, 0xb8e4, 0xb8e5, 0xb8e6, 0xb8e7, 
+    0xb8e8, 0xb8e9, 0xb8ea, 0xb8eb, 0xb8ec, 0xb8ed, 0xb8ee, 0xb8ef, 
+    0xb8f0, 0xb8f1, 0xb8f2, 0xb8f3, 0xb8f4, 0xb8f5, 0xb8f6, 0xb8f7, 
+    0xb8f8, 0xb8f9, 0xb8fa, 0xb8fb, 0xb8fc, 0xb8fd, 0xb8fe, 0xb8ff, 
+    0xb900, 0xb901, 0xb902, 0xb903, 0xb904, 0xb905, 0xb906, 0xb907, 
+    0xb908, 0xb909, 0xb90a, 0xb90b, 0xb90c, 0xb90d, 0xb90e, 0xb90f, 
+    0xb910, 0xb911, 0xb912, 0xb913, 0xb914, 0xb915, 0xb916, 0xb917, 
+    0xb918, 0xb919, 0xb91a, 0xb91b, 0xb91c, 0xb91d, 0xb91e, 0xb91f, 
+    0xb920, 0xb921, 0xb922, 0xb923, 0xb924, 0xb925, 0xb926, 0xb927, 
+    0xb928, 0xb929, 0xb92a, 0xb92b, 0xb92c, 0xb92d, 0xb92e, 0xb92f, 
+    0xb930, 0xb931, 0xb932, 0xb933, 0xb934, 0xb935, 0xb936, 0xb937, 
+    0xb938, 0xb939, 0xb93a, 0xb93b, 0xb93c, 0xb93d, 0xb93e, 0xb93f, 
+    0xb940, 0xb941, 0xb942, 0xb943, 0xb944, 0xb945, 0xb946, 0xb947, 
+    0xb948, 0xb949, 0xb94a, 0xb94b, 0xb94c, 0xb94d, 0xb94e, 0xb94f, 
+    0xb950, 0xb951, 0xb952, 0xb953, 0xb954, 0xb955, 0xb956, 0xb957, 
+    0xb958, 0xb959, 0xb95a, 0xb95b, 0xb95c, 0xb95d, 0xb95e, 0xb95f, 
+    0xb960, 0xb961, 0xb962, 0xb963, 0xb964, 0xb965, 0xb966, 0xb967, 
+    0xb968, 0xb969, 0xb96a, 0xb96b, 0xb96c, 0xb96d, 0xb96e, 0xb96f, 
+    0xb970, 0xb971, 0xb972, 0xb973, 0xb974, 0xb975, 0xb976, 0xb977, 
+    0xb978, 0xb979, 0xb97a, 0xb97b, 0xb97c, 0xb97d, 0xb97e, 0xb97f, 
+    0xb980, 0xb981, 0xb982, 0xb983, 0xb984, 0xb985, 0xb986, 0xb987, 
+    0xb988, 0xb989, 0xb98a, 0xb98b, 0xb98c, 0xb98d, 0xb98e, 0xb98f, 
+    0xb990, 0xb991, 0xb992, 0xb993, 0xb994, 0xb995, 0xb996, 0xb997, 
+    0xb998, 0xb999, 0xb99a, 0xb99b, 0xb99c, 0xb99d, 0xb99e, 0xb99f, 
+    0xb9a0, 0xb9a1, 0xb9a2, 0xb9a3, 0xb9a4, 0xb9a5, 0xb9a6, 0xb9a7, 
+    0xb9a8, 0xb9a9, 0xb9aa, 0xb9ab, 0xb9ac, 0xb9ad, 0xb9ae, 0xb9af, 
+    0xb9b0, 0xb9b1, 0xb9b2, 0xb9b3, 0xb9b4, 0xb9b5, 0xb9b6, 0xb9b7, 
+    0xb9b8, 0xb9b9, 0xb9ba, 0xb9bb, 0xb9bc, 0xb9bd, 0xb9be, 0xb9bf, 
+    0xb9c0, 0xb9c1, 0xb9c2, 0xb9c3, 0xb9c4, 0xb9c5, 0xb9c6, 0xb9c7, 
+    0xb9c8, 0xb9c9, 0xb9ca, 0xb9cb, 0xb9cc, 0xb9cd, 0xb9ce, 0xb9cf, 
+    0xb9d0, 0xb9d1, 0xb9d2, 0xb9d3, 0xb9d4, 0xb9d5, 0xb9d6, 0xb9d7, 
+    0xb9d8, 0xb9d9, 0xb9da, 0xb9db, 0xb9dc, 0xb9dd, 0xb9de, 0xb9df, 
+    0xb9e0, 0xb9e1, 0xb9e2, 0xb9e3, 0xb9e4, 0xb9e5, 0xb9e6, 0xb9e7, 
+    0xb9e8, 0xb9e9, 0xb9ea, 0xb9eb, 0xb9ec, 0xb9ed, 0xb9ee, 0xb9ef, 
+    0xb9f0, 0xb9f1, 0xb9f2, 0xb9f3, 0xb9f4, 0xb9f5, 0xb9f6, 0xb9f7, 
+    0xb9f8, 0xb9f9, 0xb9fa, 0xb9fb, 0xb9fc, 0xb9fd, 0xb9fe, 0xb9ff, 
+    0xba00, 0xba01, 0xba02, 0xba03, 0xba04, 0xba05, 0xba06, 0xba07, 
+    0xba08, 0xba09, 0xba0a, 0xba0b, 0xba0c, 0xba0d, 0xba0e, 0xba0f, 
+    0xba10, 0xba11, 0xba12, 0xba13, 0xba14, 0xba15, 0xba16, 0xba17, 
+    0xba18, 0xba19, 0xba1a, 0xba1b, 0xba1c, 0xba1d, 0xba1e, 0xba1f, 
+    0xba20, 0xba21, 0xba22, 0xba23, 0xba24, 0xba25, 0xba26, 0xba27, 
+    0xba28, 0xba29, 0xba2a, 0xba2b, 0xba2c, 0xba2d, 0xba2e, 0xba2f, 
+    0xba30, 0xba31, 0xba32, 0xba33, 0xba34, 0xba35, 0xba36, 0xba37, 
+    0xba38, 0xba39, 0xba3a, 0xba3b, 0xba3c, 0xba3d, 0xba3e, 0xba3f, 
+    0xba40, 0xba41, 0xba42, 0xba43, 0xba44, 0xba45, 0xba46, 0xba47, 
+    0xba48, 0xba49, 0xba4a, 0xba4b, 0xba4c, 0xba4d, 0xba4e, 0xba4f, 
+    0xba50, 0xba51, 0xba52, 0xba53, 0xba54, 0xba55, 0xba56, 0xba57, 
+    0xba58, 0xba59, 0xba5a, 0xba5b, 0xba5c, 0xba5d, 0xba5e, 0xba5f, 
+    0xba60, 0xba61, 0xba62, 0xba63, 0xba64, 0xba65, 0xba66, 0xba67, 
+    0xba68, 0xba69, 0xba6a, 0xba6b, 0xba6c, 0xba6d, 0xba6e, 0xba6f, 
+    0xba70, 0xba71, 0xba72, 0xba73, 0xba74, 0xba75, 0xba76, 0xba77, 
+    0xba78, 0xba79, 0xba7a, 0xba7b, 0xba7c, 0xba7d, 0xba7e, 0xba7f, 
+    0xba80, 0xba81, 0xba82, 0xba83, 0xba84, 0xba85, 0xba86, 0xba87, 
+    0xba88, 0xba89, 0xba8a, 0xba8b, 0xba8c, 0xba8d, 0xba8e, 0xba8f, 
+    0xba90, 0xba91, 0xba92, 0xba93, 0xba94, 0xba95, 0xba96, 0xba97, 
+    0xba98, 0xba99, 0xba9a, 0xba9b, 0xba9c, 0xba9d, 0xba9e, 0xba9f, 
+    0xbaa0, 0xbaa1, 0xbaa2, 0xbaa3, 0xbaa4, 0xbaa5, 0xbaa6, 0xbaa7, 
+    0xbaa8, 0xbaa9, 0xbaaa, 0xbaab, 0xbaac, 0xbaad, 0xbaae, 0xbaaf, 
+    0xbab0, 0xbab1, 0xbab2, 0xbab3, 0xbab4, 0xbab5, 0xbab6, 0xbab7, 
+    0xbab8, 0xbab9, 0xbaba, 0xbabb, 0xbabc, 0xbabd, 0xbabe, 0xbabf, 
+    0xbac0, 0xbac1, 0xbac2, 0xbac3, 0xbac4, 0xbac5, 0xbac6, 0xbac7, 
+    0xbac8, 0xbac9, 0xbaca, 0xbacb, 0xbacc, 0xbacd, 0xbace, 0xbacf, 
+    0xbad0, 0xbad1, 0xbad2, 0xbad3, 0xbad4, 0xbad5, 0xbad6, 0xbad7, 
+    0xbad8, 0xbad9, 0xbada, 0xbadb, 0xbadc, 0xbadd, 0xbade, 0xbadf, 
+    0xbae0, 0xbae1, 0xbae2, 0xbae3, 0xbae4, 0xbae5, 0xbae6, 0xbae7, 
+    0xbae8, 0xbae9, 0xbaea, 0xbaeb, 0xbaec, 0xbaed, 0xbaee, 0xbaef, 
+    0xbaf0, 0xbaf1, 0xbaf2, 0xbaf3, 0xbaf4, 0xbaf5, 0xbaf6, 0xbaf7, 
+    0xbaf8, 0xbaf9, 0xbafa, 0xbafb, 0xbafc, 0xbafd, 0xbafe, 0xbaff, 
+    0xbb00, 0xbb01, 0xbb02, 0xbb03, 0xbb04, 0xbb05, 0xbb06, 0xbb07, 
+    0xbb08, 0xbb09, 0xbb0a, 0xbb0b, 0xbb0c, 0xbb0d, 0xbb0e, 0xbb0f, 
+    0xbb10, 0xbb11, 0xbb12, 0xbb13, 0xbb14, 0xbb15, 0xbb16, 0xbb17, 
+    0xbb18, 0xbb19, 0xbb1a, 0xbb1b, 0xbb1c, 0xbb1d, 0xbb1e, 0xbb1f, 
+    0xbb20, 0xbb21, 0xbb22, 0xbb23, 0xbb24, 0xbb25, 0xbb26, 0xbb27, 
+    0xbb28, 0xbb29, 0xbb2a, 0xbb2b, 0xbb2c, 0xbb2d, 0xbb2e, 0xbb2f, 
+    0xbb30, 0xbb31, 0xbb32, 0xbb33, 0xbb34, 0xbb35, 0xbb36, 0xbb37, 
+    0xbb38, 0xbb39, 0xbb3a, 0xbb3b, 0xbb3c, 0xbb3d, 0xbb3e, 0xbb3f, 
+    0xbb40, 0xbb41, 0xbb42, 0xbb43, 0xbb44, 0xbb45, 0xbb46, 0xbb47, 
+    0xbb48, 0xbb49, 0xbb4a, 0xbb4b, 0xbb4c, 0xbb4d, 0xbb4e, 0xbb4f, 
+    0xbb50, 0xbb51, 0xbb52, 0xbb53, 0xbb54, 0xbb55, 0xbb56, 0xbb57, 
+    0xbb58, 0xbb59, 0xbb5a, 0xbb5b, 0xbb5c, 0xbb5d, 0xbb5e, 0xbb5f, 
+    0xbb60, 0xbb61, 0xbb62, 0xbb63, 0xbb64, 0xbb65, 0xbb66, 0xbb67, 
+    0xbb68, 0xbb69, 0xbb6a, 0xbb6b, 0xbb6c, 0xbb6d, 0xbb6e, 0xbb6f, 
+    0xbb70, 0xbb71, 0xbb72, 0xbb73, 0xbb74, 0xbb75, 0xbb76, 0xbb77, 
+    0xbb78, 0xbb79, 0xbb7a, 0xbb7b, 0xbb7c, 0xbb7d, 0xbb7e, 0xbb7f, 
+    0xbb80, 0xbb81, 0xbb82, 0xbb83, 0xbb84, 0xbb85, 0xbb86, 0xbb87, 
+    0xbb88, 0xbb89, 0xbb8a, 0xbb8b, 0xbb8c, 0xbb8d, 0xbb8e, 0xbb8f, 
+    0xbb90, 0xbb91, 0xbb92, 0xbb93, 0xbb94, 0xbb95, 0xbb96, 0xbb97, 
+    0xbb98, 0xbb99, 0xbb9a, 0xbb9b, 0xbb9c, 0xbb9d, 0xbb9e, 0xbb9f, 
+    0xbba0, 0xbba1, 0xbba2, 0xbba3, 0xbba4, 0xbba5, 0xbba6, 0xbba7, 
+    0xbba8, 0xbba9, 0xbbaa, 0xbbab, 0xbbac, 0xbbad, 0xbbae, 0xbbaf, 
+    0xbbb0, 0xbbb1, 0xbbb2, 0xbbb3, 0xbbb4, 0xbbb5, 0xbbb6, 0xbbb7, 
+    0xbbb8, 0xbbb9, 0xbbba, 0xbbbb, 0xbbbc, 0xbbbd, 0xbbbe, 0xbbbf, 
+    0xbbc0, 0xbbc1, 0xbbc2, 0xbbc3, 0xbbc4, 0xbbc5, 0xbbc6, 0xbbc7, 
+    0xbbc8, 0xbbc9, 0xbbca, 0xbbcb, 0xbbcc, 0xbbcd, 0xbbce, 0xbbcf, 
+    0xbbd0, 0xbbd1, 0xbbd2, 0xbbd3, 0xbbd4, 0xbbd5, 0xbbd6, 0xbbd7, 
+    0xbbd8, 0xbbd9, 0xbbda, 0xbbdb, 0xbbdc, 0xbbdd, 0xbbde, 0xbbdf, 
+    0xbbe0, 0xbbe1, 0xbbe2, 0xbbe3, 0xbbe4, 0xbbe5, 0xbbe6, 0xbbe7, 
+    0xbbe8, 0xbbe9, 0xbbea, 0xbbeb, 0xbbec, 0xbbed, 0xbbee, 0xbbef, 
+    0xbbf0, 0xbbf1, 0xbbf2, 0xbbf3, 0xbbf4, 0xbbf5, 0xbbf6, 0xbbf7, 
+    0xbbf8, 0xbbf9, 0xbbfa, 0xbbfb, 0xbbfc, 0xbbfd, 0xbbfe, 0xbbff, 
+    0xbc00, 0xbc01, 0xbc02, 0xbc03, 0xbc04, 0xbc05, 0xbc06, 0xbc07, 
+    0xbc08, 0xbc09, 0xbc0a, 0xbc0b, 0xbc0c, 0xbc0d, 0xbc0e, 0xbc0f, 
+    0xbc10, 0xbc11, 0xbc12, 0xbc13, 0xbc14, 0xbc15, 0xbc16, 0xbc17, 
+    0xbc18, 0xbc19, 0xbc1a, 0xbc1b, 0xbc1c, 0xbc1d, 0xbc1e, 0xbc1f, 
+    0xbc20, 0xbc21, 0xbc22, 0xbc23, 0xbc24, 0xbc25, 0xbc26, 0xbc27, 
+    0xbc28, 0xbc29, 0xbc2a, 0xbc2b, 0xbc2c, 0xbc2d, 0xbc2e, 0xbc2f, 
+    0xbc30, 0xbc31, 0xbc32, 0xbc33, 0xbc34, 0xbc35, 0xbc36, 0xbc37, 
+    0xbc38, 0xbc39, 0xbc3a, 0xbc3b, 0xbc3c, 0xbc3d, 0xbc3e, 0xbc3f, 
+    0xbc40, 0xbc41, 0xbc42, 0xbc43, 0xbc44, 0xbc45, 0xbc46, 0xbc47, 
+    0xbc48, 0xbc49, 0xbc4a, 0xbc4b, 0xbc4c, 0xbc4d, 0xbc4e, 0xbc4f, 
+    0xbc50, 0xbc51, 0xbc52, 0xbc53, 0xbc54, 0xbc55, 0xbc56, 0xbc57, 
+    0xbc58, 0xbc59, 0xbc5a, 0xbc5b, 0xbc5c, 0xbc5d, 0xbc5e, 0xbc5f, 
+    0xbc60, 0xbc61, 0xbc62, 0xbc63, 0xbc64, 0xbc65, 0xbc66, 0xbc67, 
+    0xbc68, 0xbc69, 0xbc6a, 0xbc6b, 0xbc6c, 0xbc6d, 0xbc6e, 0xbc6f, 
+    0xbc70, 0xbc71, 0xbc72, 0xbc73, 0xbc74, 0xbc75, 0xbc76, 0xbc77, 
+    0xbc78, 0xbc79, 0xbc7a, 0xbc7b, 0xbc7c, 0xbc7d, 0xbc7e, 0xbc7f, 
+    0xbc80, 0xbc81, 0xbc82, 0xbc83, 0xbc84, 0xbc85, 0xbc86, 0xbc87, 
+    0xbc88, 0xbc89, 0xbc8a, 0xbc8b, 0xbc8c, 0xbc8d, 0xbc8e, 0xbc8f, 
+    0xbc90, 0xbc91, 0xbc92, 0xbc93, 0xbc94, 0xbc95, 0xbc96, 0xbc97, 
+    0xbc98, 0xbc99, 0xbc9a, 0xbc9b, 0xbc9c, 0xbc9d, 0xbc9e, 0xbc9f, 
+    0xbca0, 0xbca1, 0xbca2, 0xbca3, 0xbca4, 0xbca5, 0xbca6, 0xbca7, 
+    0xbca8, 0xbca9, 0xbcaa, 0xbcab, 0xbcac, 0xbcad, 0xbcae, 0xbcaf, 
+    0xbcb0, 0xbcb1, 0xbcb2, 0xbcb3, 0xbcb4, 0xbcb5, 0xbcb6, 0xbcb7, 
+    0xbcb8, 0xbcb9, 0xbcba, 0xbcbb, 0xbcbc, 0xbcbd, 0xbcbe, 0xbcbf, 
+    0xbcc0, 0xbcc1, 0xbcc2, 0xbcc3, 0xbcc4, 0xbcc5, 0xbcc6, 0xbcc7, 
+    0xbcc8, 0xbcc9, 0xbcca, 0xbccb, 0xbccc, 0xbccd, 0xbcce, 0xbccf, 
+    0xbcd0, 0xbcd1, 0xbcd2, 0xbcd3, 0xbcd4, 0xbcd5, 0xbcd6, 0xbcd7, 
+    0xbcd8, 0xbcd9, 0xbcda, 0xbcdb, 0xbcdc, 0xbcdd, 0xbcde, 0xbcdf, 
+    0xbce0, 0xbce1, 0xbce2, 0xbce3, 0xbce4, 0xbce5, 0xbce6, 0xbce7, 
+    0xbce8, 0xbce9, 0xbcea, 0xbceb, 0xbcec, 0xbced, 0xbcee, 0xbcef, 
+    0xbcf0, 0xbcf1, 0xbcf2, 0xbcf3, 0xbcf4, 0xbcf5, 0xbcf6, 0xbcf7, 
+    0xbcf8, 0xbcf9, 0xbcfa, 0xbcfb, 0xbcfc, 0xbcfd, 0xbcfe, 0xbcff, 
+    0xbd00, 0xbd01, 0xbd02, 0xbd03, 0xbd04, 0xbd05, 0xbd06, 0xbd07, 
+    0xbd08, 0xbd09, 0xbd0a, 0xbd0b, 0xbd0c, 0xbd0d, 0xbd0e, 0xbd0f, 
+    0xbd10, 0xbd11, 0xbd12, 0xbd13, 0xbd14, 0xbd15, 0xbd16, 0xbd17, 
+    0xbd18, 0xbd19, 0xbd1a, 0xbd1b, 0xbd1c, 0xbd1d, 0xbd1e, 0xbd1f, 
+    0xbd20, 0xbd21, 0xbd22, 0xbd23, 0xbd24, 0xbd25, 0xbd26, 0xbd27, 
+    0xbd28, 0xbd29, 0xbd2a, 0xbd2b, 0xbd2c, 0xbd2d, 0xbd2e, 0xbd2f, 
+    0xbd30, 0xbd31, 0xbd32, 0xbd33, 0xbd34, 0xbd35, 0xbd36, 0xbd37, 
+    0xbd38, 0xbd39, 0xbd3a, 0xbd3b, 0xbd3c, 0xbd3d, 0xbd3e, 0xbd3f, 
+    0xbd40, 0xbd41, 0xbd42, 0xbd43, 0xbd44, 0xbd45, 0xbd46, 0xbd47, 
+    0xbd48, 0xbd49, 0xbd4a, 0xbd4b, 0xbd4c, 0xbd4d, 0xbd4e, 0xbd4f, 
+    0xbd50, 0xbd51, 0xbd52, 0xbd53, 0xbd54, 0xbd55, 0xbd56, 0xbd57, 
+    0xbd58, 0xbd59, 0xbd5a, 0xbd5b, 0xbd5c, 0xbd5d, 0xbd5e, 0xbd5f, 
+    0xbd60, 0xbd61, 0xbd62, 0xbd63, 0xbd64, 0xbd65, 0xbd66, 0xbd67, 
+    0xbd68, 0xbd69, 0xbd6a, 0xbd6b, 0xbd6c, 0xbd6d, 0xbd6e, 0xbd6f, 
+    0xbd70, 0xbd71, 0xbd72, 0xbd73, 0xbd74, 0xbd75, 0xbd76, 0xbd77, 
+    0xbd78, 0xbd79, 0xbd7a, 0xbd7b, 0xbd7c, 0xbd7d, 0xbd7e, 0xbd7f, 
+    0xbd80, 0xbd81, 0xbd82, 0xbd83, 0xbd84, 0xbd85, 0xbd86, 0xbd87, 
+    0xbd88, 0xbd89, 0xbd8a, 0xbd8b, 0xbd8c, 0xbd8d, 0xbd8e, 0xbd8f, 
+    0xbd90, 0xbd91, 0xbd92, 0xbd93, 0xbd94, 0xbd95, 0xbd96, 0xbd97, 
+    0xbd98, 0xbd99, 0xbd9a, 0xbd9b, 0xbd9c, 0xbd9d, 0xbd9e, 0xbd9f, 
+    0xbda0, 0xbda1, 0xbda2, 0xbda3, 0xbda4, 0xbda5, 0xbda6, 0xbda7, 
+    0xbda8, 0xbda9, 0xbdaa, 0xbdab, 0xbdac, 0xbdad, 0xbdae, 0xbdaf, 
+    0xbdb0, 0xbdb1, 0xbdb2, 0xbdb3, 0xbdb4, 0xbdb5, 0xbdb6, 0xbdb7, 
+    0xbdb8, 0xbdb9, 0xbdba, 0xbdbb, 0xbdbc, 0xbdbd, 0xbdbe, 0xbdbf, 
+    0xbdc0, 0xbdc1, 0xbdc2, 0xbdc3, 0xbdc4, 0xbdc5, 0xbdc6, 0xbdc7, 
+    0xbdc8, 0xbdc9, 0xbdca, 0xbdcb, 0xbdcc, 0xbdcd, 0xbdce, 0xbdcf, 
+    0xbdd0, 0xbdd1, 0xbdd2, 0xbdd3, 0xbdd4, 0xbdd5, 0xbdd6, 0xbdd7, 
+    0xbdd8, 0xbdd9, 0xbdda, 0xbddb, 0xbddc, 0xbddd, 0xbdde, 0xbddf, 
+    0xbde0, 0xbde1, 0xbde2, 0xbde3, 0xbde4, 0xbde5, 0xbde6, 0xbde7, 
+    0xbde8, 0xbde9, 0xbdea, 0xbdeb, 0xbdec, 0xbded, 0xbdee, 0xbdef, 
+    0xbdf0, 0xbdf1, 0xbdf2, 0xbdf3, 0xbdf4, 0xbdf5, 0xbdf6, 0xbdf7, 
+    0xbdf8, 0xbdf9, 0xbdfa, 0xbdfb, 0xbdfc, 0xbdfd, 0xbdfe, 0xbdff, 
+    0xbe00, 0xbe01, 0xbe02, 0xbe03, 0xbe04, 0xbe05, 0xbe06, 0xbe07, 
+    0xbe08, 0xbe09, 0xbe0a, 0xbe0b, 0xbe0c, 0xbe0d, 0xbe0e, 0xbe0f, 
+    0xbe10, 0xbe11, 0xbe12, 0xbe13, 0xbe14, 0xbe15, 0xbe16, 0xbe17, 
+    0xbe18, 0xbe19, 0xbe1a, 0xbe1b, 0xbe1c, 0xbe1d, 0xbe1e, 0xbe1f, 
+    0xbe20, 0xbe21, 0xbe22, 0xbe23, 0xbe24, 0xbe25, 0xbe26, 0xbe27, 
+    0xbe28, 0xbe29, 0xbe2a, 0xbe2b, 0xbe2c, 0xbe2d, 0xbe2e, 0xbe2f, 
+    0xbe30, 0xbe31, 0xbe32, 0xbe33, 0xbe34, 0xbe35, 0xbe36, 0xbe37, 
+    0xbe38, 0xbe39, 0xbe3a, 0xbe3b, 0xbe3c, 0xbe3d, 0xbe3e, 0xbe3f, 
+    0xbe40, 0xbe41, 0xbe42, 0xbe43, 0xbe44, 0xbe45, 0xbe46, 0xbe47, 
+    0xbe48, 0xbe49, 0xbe4a, 0xbe4b, 0xbe4c, 0xbe4d, 0xbe4e, 0xbe4f, 
+    0xbe50, 0xbe51, 0xbe52, 0xbe53, 0xbe54, 0xbe55, 0xbe56, 0xbe57, 
+    0xbe58, 0xbe59, 0xbe5a, 0xbe5b, 0xbe5c, 0xbe5d, 0xbe5e, 0xbe5f, 
+    0xbe60, 0xbe61, 0xbe62, 0xbe63, 0xbe64, 0xbe65, 0xbe66, 0xbe67, 
+    0xbe68, 0xbe69, 0xbe6a, 0xbe6b, 0xbe6c, 0xbe6d, 0xbe6e, 0xbe6f, 
+    0xbe70, 0xbe71, 0xbe72, 0xbe73, 0xbe74, 0xbe75, 0xbe76, 0xbe77, 
+    0xbe78, 0xbe79, 0xbe7a, 0xbe7b, 0xbe7c, 0xbe7d, 0xbe7e, 0xbe7f, 
+    0xbe80, 0xbe81, 0xbe82, 0xbe83, 0xbe84, 0xbe85, 0xbe86, 0xbe87, 
+    0xbe88, 0xbe89, 0xbe8a, 0xbe8b, 0xbe8c, 0xbe8d, 0xbe8e, 0xbe8f, 
+    0xbe90, 0xbe91, 0xbe92, 0xbe93, 0xbe94, 0xbe95, 0xbe96, 0xbe97, 
+    0xbe98, 0xbe99, 0xbe9a, 0xbe9b, 0xbe9c, 0xbe9d, 0xbe9e, 0xbe9f, 
+    0xbea0, 0xbea1, 0xbea2, 0xbea3, 0xbea4, 0xbea5, 0xbea6, 0xbea7, 
+    0xbea8, 0xbea9, 0xbeaa, 0xbeab, 0xbeac, 0xbead, 0xbeae, 0xbeaf, 
+    0xbeb0, 0xbeb1, 0xbeb2, 0xbeb3, 0xbeb4, 0xbeb5, 0xbeb6, 0xbeb7, 
+    0xbeb8, 0xbeb9, 0xbeba, 0xbebb, 0xbebc, 0xbebd, 0xbebe, 0xbebf, 
+    0xbec0, 0xbec1, 0xbec2, 0xbec3, 0xbec4, 0xbec5, 0xbec6, 0xbec7, 
+    0xbec8, 0xbec9, 0xbeca, 0xbecb, 0xbecc, 0xbecd, 0xbece, 0xbecf, 
+    0xbed0, 0xbed1, 0xbed2, 0xbed3, 0xbed4, 0xbed5, 0xbed6, 0xbed7, 
+    0xbed8, 0xbed9, 0xbeda, 0xbedb, 0xbedc, 0xbedd, 0xbede, 0xbedf, 
+    0xbee0, 0xbee1, 0xbee2, 0xbee3, 0xbee4, 0xbee5, 0xbee6, 0xbee7, 
+    0xbee8, 0xbee9, 0xbeea, 0xbeeb, 0xbeec, 0xbeed, 0xbeee, 0xbeef, 
+    0xbef0, 0xbef1, 0xbef2, 0xbef3, 0xbef4, 0xbef5, 0xbef6, 0xbef7, 
+    0xbef8, 0xbef9, 0xbefa, 0xbefb, 0xbefc, 0xbefd, 0xbefe, 0xbeff, 
+    0xbf00, 0xbf01, 0xbf02, 0xbf03, 0xbf04, 0xbf05, 0xbf06, 0xbf07, 
+    0xbf08, 0xbf09, 0xbf0a, 0xbf0b, 0xbf0c, 0xbf0d, 0xbf0e, 0xbf0f, 
+    0xbf10, 0xbf11, 0xbf12, 0xbf13, 0xbf14, 0xbf15, 0xbf16, 0xbf17, 
+    0xbf18, 0xbf19, 0xbf1a, 0xbf1b, 0xbf1c, 0xbf1d, 0xbf1e, 0xbf1f, 
+    0xbf20, 0xbf21, 0xbf22, 0xbf23, 0xbf24, 0xbf25, 0xbf26, 0xbf27, 
+    0xbf28, 0xbf29, 0xbf2a, 0xbf2b, 0xbf2c, 0xbf2d, 0xbf2e, 0xbf2f, 
+    0xbf30, 0xbf31, 0xbf32, 0xbf33, 0xbf34, 0xbf35, 0xbf36, 0xbf37, 
+    0xbf38, 0xbf39, 0xbf3a, 0xbf3b, 0xbf3c, 0xbf3d, 0xbf3e, 0xbf3f, 
+    0xbf40, 0xbf41, 0xbf42, 0xbf43, 0xbf44, 0xbf45, 0xbf46, 0xbf47, 
+    0xbf48, 0xbf49, 0xbf4a, 0xbf4b, 0xbf4c, 0xbf4d, 0xbf4e, 0xbf4f, 
+    0xbf50, 0xbf51, 0xbf52, 0xbf53, 0xbf54, 0xbf55, 0xbf56, 0xbf57, 
+    0xbf58, 0xbf59, 0xbf5a, 0xbf5b, 0xbf5c, 0xbf5d, 0xbf5e, 0xbf5f, 
+    0xbf60, 0xbf61, 0xbf62, 0xbf63, 0xbf64, 0xbf65, 0xbf66, 0xbf67, 
+    0xbf68, 0xbf69, 0xbf6a, 0xbf6b, 0xbf6c, 0xbf6d, 0xbf6e, 0xbf6f, 
+    0xbf70, 0xbf71, 0xbf72, 0xbf73, 0xbf74, 0xbf75, 0xbf76, 0xbf77, 
+    0xbf78, 0xbf79, 0xbf7a, 0xbf7b, 0xbf7c, 0xbf7d, 0xbf7e, 0xbf7f, 
+    0xbf80, 0xbf81, 0xbf82, 0xbf83, 0xbf84, 0xbf85, 0xbf86, 0xbf87, 
+    0xbf88, 0xbf89, 0xbf8a, 0xbf8b, 0xbf8c, 0xbf8d, 0xbf8e, 0xbf8f, 
+    0xbf90, 0xbf91, 0xbf92, 0xbf93, 0xbf94, 0xbf95, 0xbf96, 0xbf97, 
+    0xbf98, 0xbf99, 0xbf9a, 0xbf9b, 0xbf9c, 0xbf9d, 0xbf9e, 0xbf9f, 
+    0xbfa0, 0xbfa1, 0xbfa2, 0xbfa3, 0xbfa4, 0xbfa5, 0xbfa6, 0xbfa7, 
+    0xbfa8, 0xbfa9, 0xbfaa, 0xbfab, 0xbfac, 0xbfad, 0xbfae, 0xbfaf, 
+    0xbfb0, 0xbfb1, 0xbfb2, 0xbfb3, 0xbfb4, 0xbfb5, 0xbfb6, 0xbfb7, 
+    0xbfb8, 0xbfb9, 0xbfba, 0xbfbb, 0xbfbc, 0xbfbd, 0xbfbe, 0xbfbf, 
+    0xbfc0, 0xbfc1, 0xbfc2, 0xbfc3, 0xbfc4, 0xbfc5, 0xbfc6, 0xbfc7, 
+    0xbfc8, 0xbfc9, 0xbfca, 0xbfcb, 0xbfcc, 0xbfcd, 0xbfce, 0xbfcf, 
+    0xbfd0, 0xbfd1, 0xbfd2, 0xbfd3, 0xbfd4, 0xbfd5, 0xbfd6, 0xbfd7, 
+    0xbfd8, 0xbfd9, 0xbfda, 0xbfdb, 0xbfdc, 0xbfdd, 0xbfde, 0xbfdf, 
+    0xbfe0, 0xbfe1, 0xbfe2, 0xbfe3, 0xbfe4, 0xbfe5, 0xbfe6, 0xbfe7, 
+    0xbfe8, 0xbfe9, 0xbfea, 0xbfeb, 0xbfec, 0xbfed, 0xbfee, 0xbfef, 
+    0xbff0, 0xbff1, 0xbff2, 0xbff3, 0xbff4, 0xbff5, 0xbff6, 0xbff7, 
+    0xbff8, 0xbff9, 0xbffa, 0xbffb, 0xbffc, 0xbffd, 0xbffe, 0xbfff, 
+    0xc000, 0xc001, 0xc002, 0xc003, 0xc004, 0xc005, 0xc006, 0xc007, 
+    0xc008, 0xc009, 0xc00a, 0xc00b, 0xc00c, 0xc00d, 0xc00e, 0xc00f, 
+    0xc010, 0xc011, 0xc012, 0xc013, 0xc014, 0xc015, 0xc016, 0xc017, 
+    0xc018, 0xc019, 0xc01a, 0xc01b, 0xc01c, 0xc01d, 0xc01e, 0xc01f, 
+    0xc020, 0xc021, 0xc022, 0xc023, 0xc024, 0xc025, 0xc026, 0xc027, 
+    0xc028, 0xc029, 0xc02a, 0xc02b, 0xc02c, 0xc02d, 0xc02e, 0xc02f, 
+    0xc030, 0xc031, 0xc032, 0xc033, 0xc034, 0xc035, 0xc036, 0xc037, 
+    0xc038, 0xc039, 0xc03a, 0xc03b, 0xc03c, 0xc03d, 0xc03e, 0xc03f, 
+    0xc040, 0xc041, 0xc042, 0xc043, 0xc044, 0xc045, 0xc046, 0xc047, 
+    0xc048, 0xc049, 0xc04a, 0xc04b, 0xc04c, 0xc04d, 0xc04e, 0xc04f, 
+    0xc050, 0xc051, 0xc052, 0xc053, 0xc054, 0xc055, 0xc056, 0xc057, 
+    0xc058, 0xc059, 0xc05a, 0xc05b, 0xc05c, 0xc05d, 0xc05e, 0xc05f, 
+    0xc060, 0xc061, 0xc062, 0xc063, 0xc064, 0xc065, 0xc066, 0xc067, 
+    0xc068, 0xc069, 0xc06a, 0xc06b, 0xc06c, 0xc06d, 0xc06e, 0xc06f, 
+    0xc070, 0xc071, 0xc072, 0xc073, 0xc074, 0xc075, 0xc076, 0xc077, 
+    0xc078, 0xc079, 0xc07a, 0xc07b, 0xc07c, 0xc07d, 0xc07e, 0xc07f, 
+    0xc080, 0xc081, 0xc082, 0xc083, 0xc084, 0xc085, 0xc086, 0xc087, 
+    0xc088, 0xc089, 0xc08a, 0xc08b, 0xc08c, 0xc08d, 0xc08e, 0xc08f, 
+    0xc090, 0xc091, 0xc092, 0xc093, 0xc094, 0xc095, 0xc096, 0xc097, 
+    0xc098, 0xc099, 0xc09a, 0xc09b, 0xc09c, 0xc09d, 0xc09e, 0xc09f, 
+    0xc0a0, 0xc0a1, 0xc0a2, 0xc0a3, 0xc0a4, 0xc0a5, 0xc0a6, 0xc0a7, 
+    0xc0a8, 0xc0a9, 0xc0aa, 0xc0ab, 0xc0ac, 0xc0ad, 0xc0ae, 0xc0af, 
+    0xc0b0, 0xc0b1, 0xc0b2, 0xc0b3, 0xc0b4, 0xc0b5, 0xc0b6, 0xc0b7, 
+    0xc0b8, 0xc0b9, 0xc0ba, 0xc0bb, 0xc0bc, 0xc0bd, 0xc0be, 0xc0bf, 
+    0xc0c0, 0xc0c1, 0xc0c2, 0xc0c3, 0xc0c4, 0xc0c5, 0xc0c6, 0xc0c7, 
+    0xc0c8, 0xc0c9, 0xc0ca, 0xc0cb, 0xc0cc, 0xc0cd, 0xc0ce, 0xc0cf, 
+    0xc0d0, 0xc0d1, 0xc0d2, 0xc0d3, 0xc0d4, 0xc0d5, 0xc0d6, 0xc0d7, 
+    0xc0d8, 0xc0d9, 0xc0da, 0xc0db, 0xc0dc, 0xc0dd, 0xc0de, 0xc0df, 
+    0xc0e0, 0xc0e1, 0xc0e2, 0xc0e3, 0xc0e4, 0xc0e5, 0xc0e6, 0xc0e7, 
+    0xc0e8, 0xc0e9, 0xc0ea, 0xc0eb, 0xc0ec, 0xc0ed, 0xc0ee, 0xc0ef, 
+    0xc0f0, 0xc0f1, 0xc0f2, 0xc0f3, 0xc0f4, 0xc0f5, 0xc0f6, 0xc0f7, 
+    0xc0f8, 0xc0f9, 0xc0fa, 0xc0fb, 0xc0fc, 0xc0fd, 0xc0fe, 0xc0ff, 
+    0xc100, 0xc101, 0xc102, 0xc103, 0xc104, 0xc105, 0xc106, 0xc107, 
+    0xc108, 0xc109, 0xc10a, 0xc10b, 0xc10c, 0xc10d, 0xc10e, 0xc10f, 
+    0xc110, 0xc111, 0xc112, 0xc113, 0xc114, 0xc115, 0xc116, 0xc117, 
+    0xc118, 0xc119, 0xc11a, 0xc11b, 0xc11c, 0xc11d, 0xc11e, 0xc11f, 
+    0xc120, 0xc121, 0xc122, 0xc123, 0xc124, 0xc125, 0xc126, 0xc127, 
+    0xc128, 0xc129, 0xc12a, 0xc12b, 0xc12c, 0xc12d, 0xc12e, 0xc12f, 
+    0xc130, 0xc131, 0xc132, 0xc133, 0xc134, 0xc135, 0xc136, 0xc137, 
+    0xc138, 0xc139, 0xc13a, 0xc13b, 0xc13c, 0xc13d, 0xc13e, 0xc13f, 
+    0xc140, 0xc141, 0xc142, 0xc143, 0xc144, 0xc145, 0xc146, 0xc147, 
+    0xc148, 0xc149, 0xc14a, 0xc14b, 0xc14c, 0xc14d, 0xc14e, 0xc14f, 
+    0xc150, 0xc151, 0xc152, 0xc153, 0xc154, 0xc155, 0xc156, 0xc157, 
+    0xc158, 0xc159, 0xc15a, 0xc15b, 0xc15c, 0xc15d, 0xc15e, 0xc15f, 
+    0xc160, 0xc161, 0xc162, 0xc163, 0xc164, 0xc165, 0xc166, 0xc167, 
+    0xc168, 0xc169, 0xc16a, 0xc16b, 0xc16c, 0xc16d, 0xc16e, 0xc16f, 
+    0xc170, 0xc171, 0xc172, 0xc173, 0xc174, 0xc175, 0xc176, 0xc177, 
+    0xc178, 0xc179, 0xc17a, 0xc17b, 0xc17c, 0xc17d, 0xc17e, 0xc17f, 
+    0xc180, 0xc181, 0xc182, 0xc183, 0xc184, 0xc185, 0xc186, 0xc187, 
+    0xc188, 0xc189, 0xc18a, 0xc18b, 0xc18c, 0xc18d, 0xc18e, 0xc18f, 
+    0xc190, 0xc191, 0xc192, 0xc193, 0xc194, 0xc195, 0xc196, 0xc197, 
+    0xc198, 0xc199, 0xc19a, 0xc19b, 0xc19c, 0xc19d, 0xc19e, 0xc19f, 
+    0xc1a0, 0xc1a1, 0xc1a2, 0xc1a3, 0xc1a4, 0xc1a5, 0xc1a6, 0xc1a7, 
+    0xc1a8, 0xc1a9, 0xc1aa, 0xc1ab, 0xc1ac, 0xc1ad, 0xc1ae, 0xc1af, 
+    0xc1b0, 0xc1b1, 0xc1b2, 0xc1b3, 0xc1b4, 0xc1b5, 0xc1b6, 0xc1b7, 
+    0xc1b8, 0xc1b9, 0xc1ba, 0xc1bb, 0xc1bc, 0xc1bd, 0xc1be, 0xc1bf, 
+    0xc1c0, 0xc1c1, 0xc1c2, 0xc1c3, 0xc1c4, 0xc1c5, 0xc1c6, 0xc1c7, 
+    0xc1c8, 0xc1c9, 0xc1ca, 0xc1cb, 0xc1cc, 0xc1cd, 0xc1ce, 0xc1cf, 
+    0xc1d0, 0xc1d1, 0xc1d2, 0xc1d3, 0xc1d4, 0xc1d5, 0xc1d6, 0xc1d7, 
+    0xc1d8, 0xc1d9, 0xc1da, 0xc1db, 0xc1dc, 0xc1dd, 0xc1de, 0xc1df, 
+    0xc1e0, 0xc1e1, 0xc1e2, 0xc1e3, 0xc1e4, 0xc1e5, 0xc1e6, 0xc1e7, 
+    0xc1e8, 0xc1e9, 0xc1ea, 0xc1eb, 0xc1ec, 0xc1ed, 0xc1ee, 0xc1ef, 
+    0xc1f0, 0xc1f1, 0xc1f2, 0xc1f3, 0xc1f4, 0xc1f5, 0xc1f6, 0xc1f7, 
+    0xc1f8, 0xc1f9, 0xc1fa, 0xc1fb, 0xc1fc, 0xc1fd, 0xc1fe, 0xc1ff, 
+    0xc200, 0xc201, 0xc202, 0xc203, 0xc204, 0xc205, 0xc206, 0xc207, 
+    0xc208, 0xc209, 0xc20a, 0xc20b, 0xc20c, 0xc20d, 0xc20e, 0xc20f, 
+    0xc210, 0xc211, 0xc212, 0xc213, 0xc214, 0xc215, 0xc216, 0xc217, 
+    0xc218, 0xc219, 0xc21a, 0xc21b, 0xc21c, 0xc21d, 0xc21e, 0xc21f, 
+    0xc220, 0xc221, 0xc222, 0xc223, 0xc224, 0xc225, 0xc226, 0xc227, 
+    0xc228, 0xc229, 0xc22a, 0xc22b, 0xc22c, 0xc22d, 0xc22e, 0xc22f, 
+    0xc230, 0xc231, 0xc232, 0xc233, 0xc234, 0xc235, 0xc236, 0xc237, 
+    0xc238, 0xc239, 0xc23a, 0xc23b, 0xc23c, 0xc23d, 0xc23e, 0xc23f, 
+    0xc240, 0xc241, 0xc242, 0xc243, 0xc244, 0xc245, 0xc246, 0xc247, 
+    0xc248, 0xc249, 0xc24a, 0xc24b, 0xc24c, 0xc24d, 0xc24e, 0xc24f, 
+    0xc250, 0xc251, 0xc252, 0xc253, 0xc254, 0xc255, 0xc256, 0xc257, 
+    0xc258, 0xc259, 0xc25a, 0xc25b, 0xc25c, 0xc25d, 0xc25e, 0xc25f, 
+    0xc260, 0xc261, 0xc262, 0xc263, 0xc264, 0xc265, 0xc266, 0xc267, 
+    0xc268, 0xc269, 0xc26a, 0xc26b, 0xc26c, 0xc26d, 0xc26e, 0xc26f, 
+    0xc270, 0xc271, 0xc272, 0xc273, 0xc274, 0xc275, 0xc276, 0xc277, 
+    0xc278, 0xc279, 0xc27a, 0xc27b, 0xc27c, 0xc27d, 0xc27e, 0xc27f, 
+    0xc280, 0xc281, 0xc282, 0xc283, 0xc284, 0xc285, 0xc286, 0xc287, 
+    0xc288, 0xc289, 0xc28a, 0xc28b, 0xc28c, 0xc28d, 0xc28e, 0xc28f, 
+    0xc290, 0xc291, 0xc292, 0xc293, 0xc294, 0xc295, 0xc296, 0xc297, 
+    0xc298, 0xc299, 0xc29a, 0xc29b, 0xc29c, 0xc29d, 0xc29e, 0xc29f, 
+    0xc2a0, 0xc2a1, 0xc2a2, 0xc2a3, 0xc2a4, 0xc2a5, 0xc2a6, 0xc2a7, 
+    0xc2a8, 0xc2a9, 0xc2aa, 0xc2ab, 0xc2ac, 0xc2ad, 0xc2ae, 0xc2af, 
+    0xc2b0, 0xc2b1, 0xc2b2, 0xc2b3, 0xc2b4, 0xc2b5, 0xc2b6, 0xc2b7, 
+    0xc2b8, 0xc2b9, 0xc2ba, 0xc2bb, 0xc2bc, 0xc2bd, 0xc2be, 0xc2bf, 
+    0xc2c0, 0xc2c1, 0xc2c2, 0xc2c3, 0xc2c4, 0xc2c5, 0xc2c6, 0xc2c7, 
+    0xc2c8, 0xc2c9, 0xc2ca, 0xc2cb, 0xc2cc, 0xc2cd, 0xc2ce, 0xc2cf, 
+    0xc2d0, 0xc2d1, 0xc2d2, 0xc2d3, 0xc2d4, 0xc2d5, 0xc2d6, 0xc2d7, 
+    0xc2d8, 0xc2d9, 0xc2da, 0xc2db, 0xc2dc, 0xc2dd, 0xc2de, 0xc2df, 
+    0xc2e0, 0xc2e1, 0xc2e2, 0xc2e3, 0xc2e4, 0xc2e5, 0xc2e6, 0xc2e7, 
+    0xc2e8, 0xc2e9, 0xc2ea, 0xc2eb, 0xc2ec, 0xc2ed, 0xc2ee, 0xc2ef, 
+    0xc2f0, 0xc2f1, 0xc2f2, 0xc2f3, 0xc2f4, 0xc2f5, 0xc2f6, 0xc2f7, 
+    0xc2f8, 0xc2f9, 0xc2fa, 0xc2fb, 0xc2fc, 0xc2fd, 0xc2fe, 0xc2ff, 
+    0xc300, 0xc301, 0xc302, 0xc303, 0xc304, 0xc305, 0xc306, 0xc307, 
+    0xc308, 0xc309, 0xc30a, 0xc30b, 0xc30c, 0xc30d, 0xc30e, 0xc30f, 
+    0xc310, 0xc311, 0xc312, 0xc313, 0xc314, 0xc315, 0xc316, 0xc317, 
+    0xc318, 0xc319, 0xc31a, 0xc31b, 0xc31c, 0xc31d, 0xc31e, 0xc31f, 
+    0xc320, 0xc321, 0xc322, 0xc323, 0xc324, 0xc325, 0xc326, 0xc327, 
+    0xc328, 0xc329, 0xc32a, 0xc32b, 0xc32c, 0xc32d, 0xc32e, 0xc32f, 
+    0xc330, 0xc331, 0xc332, 0xc333, 0xc334, 0xc335, 0xc336, 0xc337, 
+    0xc338, 0xc339, 0xc33a, 0xc33b, 0xc33c, 0xc33d, 0xc33e, 0xc33f, 
+    0xc340, 0xc341, 0xc342, 0xc343, 0xc344, 0xc345, 0xc346, 0xc347, 
+    0xc348, 0xc349, 0xc34a, 0xc34b, 0xc34c, 0xc34d, 0xc34e, 0xc34f, 
+    0xc350, 0xc351, 0xc352, 0xc353, 0xc354, 0xc355, 0xc356, 0xc357, 
+    0xc358, 0xc359, 0xc35a, 0xc35b, 0xc35c, 0xc35d, 0xc35e, 0xc35f, 
+    0xc360, 0xc361, 0xc362, 0xc363, 0xc364, 0xc365, 0xc366, 0xc367, 
+    0xc368, 0xc369, 0xc36a, 0xc36b, 0xc36c, 0xc36d, 0xc36e, 0xc36f, 
+    0xc370, 0xc371, 0xc372, 0xc373, 0xc374, 0xc375, 0xc376, 0xc377, 
+    0xc378, 0xc379, 0xc37a, 0xc37b, 0xc37c, 0xc37d, 0xc37e, 0xc37f, 
+    0xc380, 0xc381, 0xc382, 0xc383, 0xc384, 0xc385, 0xc386, 0xc387, 
+    0xc388, 0xc389, 0xc38a, 0xc38b, 0xc38c, 0xc38d, 0xc38e, 0xc38f, 
+    0xc390, 0xc391, 0xc392, 0xc393, 0xc394, 0xc395, 0xc396, 0xc397, 
+    0xc398, 0xc399, 0xc39a, 0xc39b, 0xc39c, 0xc39d, 0xc39e, 0xc39f, 
+    0xc3a0, 0xc3a1, 0xc3a2, 0xc3a3, 0xc3a4, 0xc3a5, 0xc3a6, 0xc3a7, 
+    0xc3a8, 0xc3a9, 0xc3aa, 0xc3ab, 0xc3ac, 0xc3ad, 0xc3ae, 0xc3af, 
+    0xc3b0, 0xc3b1, 0xc3b2, 0xc3b3, 0xc3b4, 0xc3b5, 0xc3b6, 0xc3b7, 
+    0xc3b8, 0xc3b9, 0xc3ba, 0xc3bb, 0xc3bc, 0xc3bd, 0xc3be, 0xc3bf, 
+    0xc3c0, 0xc3c1, 0xc3c2, 0xc3c3, 0xc3c4, 0xc3c5, 0xc3c6, 0xc3c7, 
+    0xc3c8, 0xc3c9, 0xc3ca, 0xc3cb, 0xc3cc, 0xc3cd, 0xc3ce, 0xc3cf, 
+    0xc3d0, 0xc3d1, 0xc3d2, 0xc3d3, 0xc3d4, 0xc3d5, 0xc3d6, 0xc3d7, 
+    0xc3d8, 0xc3d9, 0xc3da, 0xc3db, 0xc3dc, 0xc3dd, 0xc3de, 0xc3df, 
+    0xc3e0, 0xc3e1, 0xc3e2, 0xc3e3, 0xc3e4, 0xc3e5, 0xc3e6, 0xc3e7, 
+    0xc3e8, 0xc3e9, 0xc3ea, 0xc3eb, 0xc3ec, 0xc3ed, 0xc3ee, 0xc3ef, 
+    0xc3f0, 0xc3f1, 0xc3f2, 0xc3f3, 0xc3f4, 0xc3f5, 0xc3f6, 0xc3f7, 
+    0xc3f8, 0xc3f9, 0xc3fa, 0xc3fb, 0xc3fc, 0xc3fd, 0xc3fe, 0xc3ff, 
+    0xc400, 0xc401, 0xc402, 0xc403, 0xc404, 0xc405, 0xc406, 0xc407, 
+    0xc408, 0xc409, 0xc40a, 0xc40b, 0xc40c, 0xc40d, 0xc40e, 0xc40f, 
+    0xc410, 0xc411, 0xc412, 0xc413, 0xc414, 0xc415, 0xc416, 0xc417, 
+    0xc418, 0xc419, 0xc41a, 0xc41b, 0xc41c, 0xc41d, 0xc41e, 0xc41f, 
+    0xc420, 0xc421, 0xc422, 0xc423, 0xc424, 0xc425, 0xc426, 0xc427, 
+    0xc428, 0xc429, 0xc42a, 0xc42b, 0xc42c, 0xc42d, 0xc42e, 0xc42f, 
+    0xc430, 0xc431, 0xc432, 0xc433, 0xc434, 0xc435, 0xc436, 0xc437, 
+    0xc438, 0xc439, 0xc43a, 0xc43b, 0xc43c, 0xc43d, 0xc43e, 0xc43f, 
+    0xc440, 0xc441, 0xc442, 0xc443, 0xc444, 0xc445, 0xc446, 0xc447, 
+    0xc448, 0xc449, 0xc44a, 0xc44b, 0xc44c, 0xc44d, 0xc44e, 0xc44f, 
+    0xc450, 0xc451, 0xc452, 0xc453, 0xc454, 0xc455, 0xc456, 0xc457, 
+    0xc458, 0xc459, 0xc45a, 0xc45b, 0xc45c, 0xc45d, 0xc45e, 0xc45f, 
+    0xc460, 0xc461, 0xc462, 0xc463, 0xc464, 0xc465, 0xc466, 0xc467, 
+    0xc468, 0xc469, 0xc46a, 0xc46b, 0xc46c, 0xc46d, 0xc46e, 0xc46f, 
+    0xc470, 0xc471, 0xc472, 0xc473, 0xc474, 0xc475, 0xc476, 0xc477, 
+    0xc478, 0xc479, 0xc47a, 0xc47b, 0xc47c, 0xc47d, 0xc47e, 0xc47f, 
+    0xc480, 0xc481, 0xc482, 0xc483, 0xc484, 0xc485, 0xc486, 0xc487, 
+    0xc488, 0xc489, 0xc48a, 0xc48b, 0xc48c, 0xc48d, 0xc48e, 0xc48f, 
+    0xc490, 0xc491, 0xc492, 0xc493, 0xc494, 0xc495, 0xc496, 0xc497, 
+    0xc498, 0xc499, 0xc49a, 0xc49b, 0xc49c, 0xc49d, 0xc49e, 0xc49f, 
+    0xc4a0, 0xc4a1, 0xc4a2, 0xc4a3, 0xc4a4, 0xc4a5, 0xc4a6, 0xc4a7, 
+    0xc4a8, 0xc4a9, 0xc4aa, 0xc4ab, 0xc4ac, 0xc4ad, 0xc4ae, 0xc4af, 
+    0xc4b0, 0xc4b1, 0xc4b2, 0xc4b3, 0xc4b4, 0xc4b5, 0xc4b6, 0xc4b7, 
+    0xc4b8, 0xc4b9, 0xc4ba, 0xc4bb, 0xc4bc, 0xc4bd, 0xc4be, 0xc4bf, 
+    0xc4c0, 0xc4c1, 0xc4c2, 0xc4c3, 0xc4c4, 0xc4c5, 0xc4c6, 0xc4c7, 
+    0xc4c8, 0xc4c9, 0xc4ca, 0xc4cb, 0xc4cc, 0xc4cd, 0xc4ce, 0xc4cf, 
+    0xc4d0, 0xc4d1, 0xc4d2, 0xc4d3, 0xc4d4, 0xc4d5, 0xc4d6, 0xc4d7, 
+    0xc4d8, 0xc4d9, 0xc4da, 0xc4db, 0xc4dc, 0xc4dd, 0xc4de, 0xc4df, 
+    0xc4e0, 0xc4e1, 0xc4e2, 0xc4e3, 0xc4e4, 0xc4e5, 0xc4e6, 0xc4e7, 
+    0xc4e8, 0xc4e9, 0xc4ea, 0xc4eb, 0xc4ec, 0xc4ed, 0xc4ee, 0xc4ef, 
+    0xc4f0, 0xc4f1, 0xc4f2, 0xc4f3, 0xc4f4, 0xc4f5, 0xc4f6, 0xc4f7, 
+    0xc4f8, 0xc4f9, 0xc4fa, 0xc4fb, 0xc4fc, 0xc4fd, 0xc4fe, 0xc4ff, 
+    0xc500, 0xc501, 0xc502, 0xc503, 0xc504, 0xc505, 0xc506, 0xc507, 
+    0xc508, 0xc509, 0xc50a, 0xc50b, 0xc50c, 0xc50d, 0xc50e, 0xc50f, 
+    0xc510, 0xc511, 0xc512, 0xc513, 0xc514, 0xc515, 0xc516, 0xc517, 
+    0xc518, 0xc519, 0xc51a, 0xc51b, 0xc51c, 0xc51d, 0xc51e, 0xc51f, 
+    0xc520, 0xc521, 0xc522, 0xc523, 0xc524, 0xc525, 0xc526, 0xc527, 
+    0xc528, 0xc529, 0xc52a, 0xc52b, 0xc52c, 0xc52d, 0xc52e, 0xc52f, 
+    0xc530, 0xc531, 0xc532, 0xc533, 0xc534, 0xc535, 0xc536, 0xc537, 
+    0xc538, 0xc539, 0xc53a, 0xc53b, 0xc53c, 0xc53d, 0xc53e, 0xc53f, 
+    0xc540, 0xc541, 0xc542, 0xc543, 0xc544, 0xc545, 0xc546, 0xc547, 
+    0xc548, 0xc549, 0xc54a, 0xc54b, 0xc54c, 0xc54d, 0xc54e, 0xc54f, 
+    0xc550, 0xc551, 0xc552, 0xc553, 0xc554, 0xc555, 0xc556, 0xc557, 
+    0xc558, 0xc559, 0xc55a, 0xc55b, 0xc55c, 0xc55d, 0xc55e, 0xc55f, 
+    0xc560, 0xc561, 0xc562, 0xc563, 0xc564, 0xc565, 0xc566, 0xc567, 
+    0xc568, 0xc569, 0xc56a, 0xc56b, 0xc56c, 0xc56d, 0xc56e, 0xc56f, 
+    0xc570, 0xc571, 0xc572, 0xc573, 0xc574, 0xc575, 0xc576, 0xc577, 
+    0xc578, 0xc579, 0xc57a, 0xc57b, 0xc57c, 0xc57d, 0xc57e, 0xc57f, 
+    0xc580, 0xc581, 0xc582, 0xc583, 0xc584, 0xc585, 0xc586, 0xc587, 
+    0xc588, 0xc589, 0xc58a, 0xc58b, 0xc58c, 0xc58d, 0xc58e, 0xc58f, 
+    0xc590, 0xc591, 0xc592, 0xc593, 0xc594, 0xc595, 0xc596, 0xc597, 
+    0xc598, 0xc599, 0xc59a, 0xc59b, 0xc59c, 0xc59d, 0xc59e, 0xc59f, 
+    0xc5a0, 0xc5a1, 0xc5a2, 0xc5a3, 0xc5a4, 0xc5a5, 0xc5a6, 0xc5a7, 
+    0xc5a8, 0xc5a9, 0xc5aa, 0xc5ab, 0xc5ac, 0xc5ad, 0xc5ae, 0xc5af, 
+    0xc5b0, 0xc5b1, 0xc5b2, 0xc5b3, 0xc5b4, 0xc5b5, 0xc5b6, 0xc5b7, 
+    0xc5b8, 0xc5b9, 0xc5ba, 0xc5bb, 0xc5bc, 0xc5bd, 0xc5be, 0xc5bf, 
+    0xc5c0, 0xc5c1, 0xc5c2, 0xc5c3, 0xc5c4, 0xc5c5, 0xc5c6, 0xc5c7, 
+    0xc5c8, 0xc5c9, 0xc5ca, 0xc5cb, 0xc5cc, 0xc5cd, 0xc5ce, 0xc5cf, 
+    0xc5d0, 0xc5d1, 0xc5d2, 0xc5d3, 0xc5d4, 0xc5d5, 0xc5d6, 0xc5d7, 
+    0xc5d8, 0xc5d9, 0xc5da, 0xc5db, 0xc5dc, 0xc5dd, 0xc5de, 0xc5df, 
+    0xc5e0, 0xc5e1, 0xc5e2, 0xc5e3, 0xc5e4, 0xc5e5, 0xc5e6, 0xc5e7, 
+    0xc5e8, 0xc5e9, 0xc5ea, 0xc5eb, 0xc5ec, 0xc5ed, 0xc5ee, 0xc5ef, 
+    0xc5f0, 0xc5f1, 0xc5f2, 0xc5f3, 0xc5f4, 0xc5f5, 0xc5f6, 0xc5f7, 
+    0xc5f8, 0xc5f9, 0xc5fa, 0xc5fb, 0xc5fc, 0xc5fd, 0xc5fe, 0xc5ff, 
+    0xc600, 0xc601, 0xc602, 0xc603, 0xc604, 0xc605, 0xc606, 0xc607, 
+    0xc608, 0xc609, 0xc60a, 0xc60b, 0xc60c, 0xc60d, 0xc60e, 0xc60f, 
+    0xc610, 0xc611, 0xc612, 0xc613, 0xc614, 0xc615, 0xc616, 0xc617, 
+    0xc618, 0xc619, 0xc61a, 0xc61b, 0xc61c, 0xc61d, 0xc61e, 0xc61f, 
+    0xc620, 0xc621, 0xc622, 0xc623, 0xc624, 0xc625, 0xc626, 0xc627, 
+    0xc628, 0xc629, 0xc62a, 0xc62b, 0xc62c, 0xc62d, 0xc62e, 0xc62f, 
+    0xc630, 0xc631, 0xc632, 0xc633, 0xc634, 0xc635, 0xc636, 0xc637, 
+    0xc638, 0xc639, 0xc63a, 0xc63b, 0xc63c, 0xc63d, 0xc63e, 0xc63f, 
+    0xc640, 0xc641, 0xc642, 0xc643, 0xc644, 0xc645, 0xc646, 0xc647, 
+    0xc648, 0xc649, 0xc64a, 0xc64b, 0xc64c, 0xc64d, 0xc64e, 0xc64f, 
+    0xc650, 0xc651, 0xc652, 0xc653, 0xc654, 0xc655, 0xc656, 0xc657, 
+    0xc658, 0xc659, 0xc65a, 0xc65b, 0xc65c, 0xc65d, 0xc65e, 0xc65f, 
+    0xc660, 0xc661, 0xc662, 0xc663, 0xc664, 0xc665, 0xc666, 0xc667, 
+    0xc668, 0xc669, 0xc66a, 0xc66b, 0xc66c, 0xc66d, 0xc66e, 0xc66f, 
+    0xc670, 0xc671, 0xc672, 0xc673, 0xc674, 0xc675, 0xc676, 0xc677, 
+    0xc678, 0xc679, 0xc67a, 0xc67b, 0xc67c, 0xc67d, 0xc67e, 0xc67f, 
+    0xc680, 0xc681, 0xc682, 0xc683, 0xc684, 0xc685, 0xc686, 0xc687, 
+    0xc688, 0xc689, 0xc68a, 0xc68b, 0xc68c, 0xc68d, 0xc68e, 0xc68f, 
+    0xc690, 0xc691, 0xc692, 0xc693, 0xc694, 0xc695, 0xc696, 0xc697, 
+    0xc698, 0xc699, 0xc69a, 0xc69b, 0xc69c, 0xc69d, 0xc69e, 0xc69f, 
+    0xc6a0, 0xc6a1, 0xc6a2, 0xc6a3, 0xc6a4, 0xc6a5, 0xc6a6, 0xc6a7, 
+    0xc6a8, 0xc6a9, 0xc6aa, 0xc6ab, 0xc6ac, 0xc6ad, 0xc6ae, 0xc6af, 
+    0xc6b0, 0xc6b1, 0xc6b2, 0xc6b3, 0xc6b4, 0xc6b5, 0xc6b6, 0xc6b7, 
+    0xc6b8, 0xc6b9, 0xc6ba, 0xc6bb, 0xc6bc, 0xc6bd, 0xc6be, 0xc6bf, 
+    0xc6c0, 0xc6c1, 0xc6c2, 0xc6c3, 0xc6c4, 0xc6c5, 0xc6c6, 0xc6c7, 
+    0xc6c8, 0xc6c9, 0xc6ca, 0xc6cb, 0xc6cc, 0xc6cd, 0xc6ce, 0xc6cf, 
+    0xc6d0, 0xc6d1, 0xc6d2, 0xc6d3, 0xc6d4, 0xc6d5, 0xc6d6, 0xc6d7, 
+    0xc6d8, 0xc6d9, 0xc6da, 0xc6db, 0xc6dc, 0xc6dd, 0xc6de, 0xc6df, 
+    0xc6e0, 0xc6e1, 0xc6e2, 0xc6e3, 0xc6e4, 0xc6e5, 0xc6e6, 0xc6e7, 
+    0xc6e8, 0xc6e9, 0xc6ea, 0xc6eb, 0xc6ec, 0xc6ed, 0xc6ee, 0xc6ef, 
+    0xc6f0, 0xc6f1, 0xc6f2, 0xc6f3, 0xc6f4, 0xc6f5, 0xc6f6, 0xc6f7, 
+    0xc6f8, 0xc6f9, 0xc6fa, 0xc6fb, 0xc6fc, 0xc6fd, 0xc6fe, 0xc6ff, 
+    0xc700, 0xc701, 0xc702, 0xc703, 0xc704, 0xc705, 0xc706, 0xc707, 
+    0xc708, 0xc709, 0xc70a, 0xc70b, 0xc70c, 0xc70d, 0xc70e, 0xc70f, 
+    0xc710, 0xc711, 0xc712, 0xc713, 0xc714, 0xc715, 0xc716, 0xc717, 
+    0xc718, 0xc719, 0xc71a, 0xc71b, 0xc71c, 0xc71d, 0xc71e, 0xc71f, 
+    0xc720, 0xc721, 0xc722, 0xc723, 0xc724, 0xc725, 0xc726, 0xc727, 
+    0xc728, 0xc729, 0xc72a, 0xc72b, 0xc72c, 0xc72d, 0xc72e, 0xc72f, 
+    0xc730, 0xc731, 0xc732, 0xc733, 0xc734, 0xc735, 0xc736, 0xc737, 
+    0xc738, 0xc739, 0xc73a, 0xc73b, 0xc73c, 0xc73d, 0xc73e, 0xc73f, 
+    0xc740, 0xc741, 0xc742, 0xc743, 0xc744, 0xc745, 0xc746, 0xc747, 
+    0xc748, 0xc749, 0xc74a, 0xc74b, 0xc74c, 0xc74d, 0xc74e, 0xc74f, 
+    0xc750, 0xc751, 0xc752, 0xc753, 0xc754, 0xc755, 0xc756, 0xc757, 
+    0xc758, 0xc759, 0xc75a, 0xc75b, 0xc75c, 0xc75d, 0xc75e, 0xc75f, 
+    0xc760, 0xc761, 0xc762, 0xc763, 0xc764, 0xc765, 0xc766, 0xc767, 
+    0xc768, 0xc769, 0xc76a, 0xc76b, 0xc76c, 0xc76d, 0xc76e, 0xc76f, 
+    0xc770, 0xc771, 0xc772, 0xc773, 0xc774, 0xc775, 0xc776, 0xc777, 
+    0xc778, 0xc779, 0xc77a, 0xc77b, 0xc77c, 0xc77d, 0xc77e, 0xc77f, 
+    0xc780, 0xc781, 0xc782, 0xc783, 0xc784, 0xc785, 0xc786, 0xc787, 
+    0xc788, 0xc789, 0xc78a, 0xc78b, 0xc78c, 0xc78d, 0xc78e, 0xc78f, 
+    0xc790, 0xc791, 0xc792, 0xc793, 0xc794, 0xc795, 0xc796, 0xc797, 
+    0xc798, 0xc799, 0xc79a, 0xc79b, 0xc79c, 0xc79d, 0xc79e, 0xc79f, 
+    0xc7a0, 0xc7a1, 0xc7a2, 0xc7a3, 0xc7a4, 0xc7a5, 0xc7a6, 0xc7a7, 
+    0xc7a8, 0xc7a9, 0xc7aa, 0xc7ab, 0xc7ac, 0xc7ad, 0xc7ae, 0xc7af, 
+    0xc7b0, 0xc7b1, 0xc7b2, 0xc7b3, 0xc7b4, 0xc7b5, 0xc7b6, 0xc7b7, 
+    0xc7b8, 0xc7b9, 0xc7ba, 0xc7bb, 0xc7bc, 0xc7bd, 0xc7be, 0xc7bf, 
+    0xc7c0, 0xc7c1, 0xc7c2, 0xc7c3, 0xc7c4, 0xc7c5, 0xc7c6, 0xc7c7, 
+    0xc7c8, 0xc7c9, 0xc7ca, 0xc7cb, 0xc7cc, 0xc7cd, 0xc7ce, 0xc7cf, 
+    0xc7d0, 0xc7d1, 0xc7d2, 0xc7d3, 0xc7d4, 0xc7d5, 0xc7d6, 0xc7d7, 
+    0xc7d8, 0xc7d9, 0xc7da, 0xc7db, 0xc7dc, 0xc7dd, 0xc7de, 0xc7df, 
+    0xc7e0, 0xc7e1, 0xc7e2, 0xc7e3, 0xc7e4, 0xc7e5, 0xc7e6, 0xc7e7, 
+    0xc7e8, 0xc7e9, 0xc7ea, 0xc7eb, 0xc7ec, 0xc7ed, 0xc7ee, 0xc7ef, 
+    0xc7f0, 0xc7f1, 0xc7f2, 0xc7f3, 0xc7f4, 0xc7f5, 0xc7f6, 0xc7f7, 
+    0xc7f8, 0xc7f9, 0xc7fa, 0xc7fb, 0xc7fc, 0xc7fd, 0xc7fe, 0xc7ff, 
+    0xc800, 0xc801, 0xc802, 0xc803, 0xc804, 0xc805, 0xc806, 0xc807, 
+    0xc808, 0xc809, 0xc80a, 0xc80b, 0xc80c, 0xc80d, 0xc80e, 0xc80f, 
+    0xc810, 0xc811, 0xc812, 0xc813, 0xc814, 0xc815, 0xc816, 0xc817, 
+    0xc818, 0xc819, 0xc81a, 0xc81b, 0xc81c, 0xc81d, 0xc81e, 0xc81f, 
+    0xc820, 0xc821, 0xc822, 0xc823, 0xc824, 0xc825, 0xc826, 0xc827, 
+    0xc828, 0xc829, 0xc82a, 0xc82b, 0xc82c, 0xc82d, 0xc82e, 0xc82f, 
+    0xc830, 0xc831, 0xc832, 0xc833, 0xc834, 0xc835, 0xc836, 0xc837, 
+    0xc838, 0xc839, 0xc83a, 0xc83b, 0xc83c, 0xc83d, 0xc83e, 0xc83f, 
+    0xc840, 0xc841, 0xc842, 0xc843, 0xc844, 0xc845, 0xc846, 0xc847, 
+    0xc848, 0xc849, 0xc84a, 0xc84b, 0xc84c, 0xc84d, 0xc84e, 0xc84f, 
+    0xc850, 0xc851, 0xc852, 0xc853, 0xc854, 0xc855, 0xc856, 0xc857, 
+    0xc858, 0xc859, 0xc85a, 0xc85b, 0xc85c, 0xc85d, 0xc85e, 0xc85f, 
+    0xc860, 0xc861, 0xc862, 0xc863, 0xc864, 0xc865, 0xc866, 0xc867, 
+    0xc868, 0xc869, 0xc86a, 0xc86b, 0xc86c, 0xc86d, 0xc86e, 0xc86f, 
+    0xc870, 0xc871, 0xc872, 0xc873, 0xc874, 0xc875, 0xc876, 0xc877, 
+    0xc878, 0xc879, 0xc87a, 0xc87b, 0xc87c, 0xc87d, 0xc87e, 0xc87f, 
+    0xc880, 0xc881, 0xc882, 0xc883, 0xc884, 0xc885, 0xc886, 0xc887, 
+    0xc888, 0xc889, 0xc88a, 0xc88b, 0xc88c, 0xc88d, 0xc88e, 0xc88f, 
+    0xc890, 0xc891, 0xc892, 0xc893, 0xc894, 0xc895, 0xc896, 0xc897, 
+    0xc898, 0xc899, 0xc89a, 0xc89b, 0xc89c, 0xc89d, 0xc89e, 0xc89f, 
+    0xc8a0, 0xc8a1, 0xc8a2, 0xc8a3, 0xc8a4, 0xc8a5, 0xc8a6, 0xc8a7, 
+    0xc8a8, 0xc8a9, 0xc8aa, 0xc8ab, 0xc8ac, 0xc8ad, 0xc8ae, 0xc8af, 
+    0xc8b0, 0xc8b1, 0xc8b2, 0xc8b3, 0xc8b4, 0xc8b5, 0xc8b6, 0xc8b7, 
+    0xc8b8, 0xc8b9, 0xc8ba, 0xc8bb, 0xc8bc, 0xc8bd, 0xc8be, 0xc8bf, 
+    0xc8c0, 0xc8c1, 0xc8c2, 0xc8c3, 0xc8c4, 0xc8c5, 0xc8c6, 0xc8c7, 
+    0xc8c8, 0xc8c9, 0xc8ca, 0xc8cb, 0xc8cc, 0xc8cd, 0xc8ce, 0xc8cf, 
+    0xc8d0, 0xc8d1, 0xc8d2, 0xc8d3, 0xc8d4, 0xc8d5, 0xc8d6, 0xc8d7, 
+    0xc8d8, 0xc8d9, 0xc8da, 0xc8db, 0xc8dc, 0xc8dd, 0xc8de, 0xc8df, 
+    0xc8e0, 0xc8e1, 0xc8e2, 0xc8e3, 0xc8e4, 0xc8e5, 0xc8e6, 0xc8e7, 
+    0xc8e8, 0xc8e9, 0xc8ea, 0xc8eb, 0xc8ec, 0xc8ed, 0xc8ee, 0xc8ef, 
+    0xc8f0, 0xc8f1, 0xc8f2, 0xc8f3, 0xc8f4, 0xc8f5, 0xc8f6, 0xc8f7, 
+    0xc8f8, 0xc8f9, 0xc8fa, 0xc8fb, 0xc8fc, 0xc8fd, 0xc8fe, 0xc8ff, 
+    0xc900, 0xc901, 0xc902, 0xc903, 0xc904, 0xc905, 0xc906, 0xc907, 
+    0xc908, 0xc909, 0xc90a, 0xc90b, 0xc90c, 0xc90d, 0xc90e, 0xc90f, 
+    0xc910, 0xc911, 0xc912, 0xc913, 0xc914, 0xc915, 0xc916, 0xc917, 
+    0xc918, 0xc919, 0xc91a, 0xc91b, 0xc91c, 0xc91d, 0xc91e, 0xc91f, 
+    0xc920, 0xc921, 0xc922, 0xc923, 0xc924, 0xc925, 0xc926, 0xc927, 
+    0xc928, 0xc929, 0xc92a, 0xc92b, 0xc92c, 0xc92d, 0xc92e, 0xc92f, 
+    0xc930, 0xc931, 0xc932, 0xc933, 0xc934, 0xc935, 0xc936, 0xc937, 
+    0xc938, 0xc939, 0xc93a, 0xc93b, 0xc93c, 0xc93d, 0xc93e, 0xc93f, 
+    0xc940, 0xc941, 0xc942, 0xc943, 0xc944, 0xc945, 0xc946, 0xc947, 
+    0xc948, 0xc949, 0xc94a, 0xc94b, 0xc94c, 0xc94d, 0xc94e, 0xc94f, 
+    0xc950, 0xc951, 0xc952, 0xc953, 0xc954, 0xc955, 0xc956, 0xc957, 
+    0xc958, 0xc959, 0xc95a, 0xc95b, 0xc95c, 0xc95d, 0xc95e, 0xc95f, 
+    0xc960, 0xc961, 0xc962, 0xc963, 0xc964, 0xc965, 0xc966, 0xc967, 
+    0xc968, 0xc969, 0xc96a, 0xc96b, 0xc96c, 0xc96d, 0xc96e, 0xc96f, 
+    0xc970, 0xc971, 0xc972, 0xc973, 0xc974, 0xc975, 0xc976, 0xc977, 
+    0xc978, 0xc979, 0xc97a, 0xc97b, 0xc97c, 0xc97d, 0xc97e, 0xc97f, 
+    0xc980, 0xc981, 0xc982, 0xc983, 0xc984, 0xc985, 0xc986, 0xc987, 
+    0xc988, 0xc989, 0xc98a, 0xc98b, 0xc98c, 0xc98d, 0xc98e, 0xc98f, 
+    0xc990, 0xc991, 0xc992, 0xc993, 0xc994, 0xc995, 0xc996, 0xc997, 
+    0xc998, 0xc999, 0xc99a, 0xc99b, 0xc99c, 0xc99d, 0xc99e, 0xc99f, 
+    0xc9a0, 0xc9a1, 0xc9a2, 0xc9a3, 0xc9a4, 0xc9a5, 0xc9a6, 0xc9a7, 
+    0xc9a8, 0xc9a9, 0xc9aa, 0xc9ab, 0xc9ac, 0xc9ad, 0xc9ae, 0xc9af, 
+    0xc9b0, 0xc9b1, 0xc9b2, 0xc9b3, 0xc9b4, 0xc9b5, 0xc9b6, 0xc9b7, 
+    0xc9b8, 0xc9b9, 0xc9ba, 0xc9bb, 0xc9bc, 0xc9bd, 0xc9be, 0xc9bf, 
+    0xc9c0, 0xc9c1, 0xc9c2, 0xc9c3, 0xc9c4, 0xc9c5, 0xc9c6, 0xc9c7, 
+    0xc9c8, 0xc9c9, 0xc9ca, 0xc9cb, 0xc9cc, 0xc9cd, 0xc9ce, 0xc9cf, 
+    0xc9d0, 0xc9d1, 0xc9d2, 0xc9d3, 0xc9d4, 0xc9d5, 0xc9d6, 0xc9d7, 
+    0xc9d8, 0xc9d9, 0xc9da, 0xc9db, 0xc9dc, 0xc9dd, 0xc9de, 0xc9df, 
+    0xc9e0, 0xc9e1, 0xc9e2, 0xc9e3, 0xc9e4, 0xc9e5, 0xc9e6, 0xc9e7, 
+    0xc9e8, 0xc9e9, 0xc9ea, 0xc9eb, 0xc9ec, 0xc9ed, 0xc9ee, 0xc9ef, 
+    0xc9f0, 0xc9f1, 0xc9f2, 0xc9f3, 0xc9f4, 0xc9f5, 0xc9f6, 0xc9f7, 
+    0xc9f8, 0xc9f9, 0xc9fa, 0xc9fb, 0xc9fc, 0xc9fd, 0xc9fe, 0xc9ff, 
+    0xca00, 0xca01, 0xca02, 0xca03, 0xca04, 0xca05, 0xca06, 0xca07, 
+    0xca08, 0xca09, 0xca0a, 0xca0b, 0xca0c, 0xca0d, 0xca0e, 0xca0f, 
+    0xca10, 0xca11, 0xca12, 0xca13, 0xca14, 0xca15, 0xca16, 0xca17, 
+    0xca18, 0xca19, 0xca1a, 0xca1b, 0xca1c, 0xca1d, 0xca1e, 0xca1f, 
+    0xca20, 0xca21, 0xca22, 0xca23, 0xca24, 0xca25, 0xca26, 0xca27, 
+    0xca28, 0xca29, 0xca2a, 0xca2b, 0xca2c, 0xca2d, 0xca2e, 0xca2f, 
+    0xca30, 0xca31, 0xca32, 0xca33, 0xca34, 0xca35, 0xca36, 0xca37, 
+    0xca38, 0xca39, 0xca3a, 0xca3b, 0xca3c, 0xca3d, 0xca3e, 0xca3f, 
+    0xca40, 0xca41, 0xca42, 0xca43, 0xca44, 0xca45, 0xca46, 0xca47, 
+    0xca48, 0xca49, 0xca4a, 0xca4b, 0xca4c, 0xca4d, 0xca4e, 0xca4f, 
+    0xca50, 0xca51, 0xca52, 0xca53, 0xca54, 0xca55, 0xca56, 0xca57, 
+    0xca58, 0xca59, 0xca5a, 0xca5b, 0xca5c, 0xca5d, 0xca5e, 0xca5f, 
+    0xca60, 0xca61, 0xca62, 0xca63, 0xca64, 0xca65, 0xca66, 0xca67, 
+    0xca68, 0xca69, 0xca6a, 0xca6b, 0xca6c, 0xca6d, 0xca6e, 0xca6f, 
+    0xca70, 0xca71, 0xca72, 0xca73, 0xca74, 0xca75, 0xca76, 0xca77, 
+    0xca78, 0xca79, 0xca7a, 0xca7b, 0xca7c, 0xca7d, 0xca7e, 0xca7f, 
+    0xca80, 0xca81, 0xca82, 0xca83, 0xca84, 0xca85, 0xca86, 0xca87, 
+    0xca88, 0xca89, 0xca8a, 0xca8b, 0xca8c, 0xca8d, 0xca8e, 0xca8f, 
+    0xca90, 0xca91, 0xca92, 0xca93, 0xca94, 0xca95, 0xca96, 0xca97, 
+    0xca98, 0xca99, 0xca9a, 0xca9b, 0xca9c, 0xca9d, 0xca9e, 0xca9f, 
+    0xcaa0, 0xcaa1, 0xcaa2, 0xcaa3, 0xcaa4, 0xcaa5, 0xcaa6, 0xcaa7, 
+    0xcaa8, 0xcaa9, 0xcaaa, 0xcaab, 0xcaac, 0xcaad, 0xcaae, 0xcaaf, 
+    0xcab0, 0xcab1, 0xcab2, 0xcab3, 0xcab4, 0xcab5, 0xcab6, 0xcab7, 
+    0xcab8, 0xcab9, 0xcaba, 0xcabb, 0xcabc, 0xcabd, 0xcabe, 0xcabf, 
+    0xcac0, 0xcac1, 0xcac2, 0xcac3, 0xcac4, 0xcac5, 0xcac6, 0xcac7, 
+    0xcac8, 0xcac9, 0xcaca, 0xcacb, 0xcacc, 0xcacd, 0xcace, 0xcacf, 
+    0xcad0, 0xcad1, 0xcad2, 0xcad3, 0xcad4, 0xcad5, 0xcad6, 0xcad7, 
+    0xcad8, 0xcad9, 0xcada, 0xcadb, 0xcadc, 0xcadd, 0xcade, 0xcadf, 
+    0xcae0, 0xcae1, 0xcae2, 0xcae3, 0xcae4, 0xcae5, 0xcae6, 0xcae7, 
+    0xcae8, 0xcae9, 0xcaea, 0xcaeb, 0xcaec, 0xcaed, 0xcaee, 0xcaef, 
+    0xcaf0, 0xcaf1, 0xcaf2, 0xcaf3, 0xcaf4, 0xcaf5, 0xcaf6, 0xcaf7, 
+    0xcaf8, 0xcaf9, 0xcafa, 0xcafb, 0xcafc, 0xcafd, 0xcafe, 0xcaff, 
+    0xcb00, 0xcb01, 0xcb02, 0xcb03, 0xcb04, 0xcb05, 0xcb06, 0xcb07, 
+    0xcb08, 0xcb09, 0xcb0a, 0xcb0b, 0xcb0c, 0xcb0d, 0xcb0e, 0xcb0f, 
+    0xcb10, 0xcb11, 0xcb12, 0xcb13, 0xcb14, 0xcb15, 0xcb16, 0xcb17, 
+    0xcb18, 0xcb19, 0xcb1a, 0xcb1b, 0xcb1c, 0xcb1d, 0xcb1e, 0xcb1f, 
+    0xcb20, 0xcb21, 0xcb22, 0xcb23, 0xcb24, 0xcb25, 0xcb26, 0xcb27, 
+    0xcb28, 0xcb29, 0xcb2a, 0xcb2b, 0xcb2c, 0xcb2d, 0xcb2e, 0xcb2f, 
+    0xcb30, 0xcb31, 0xcb32, 0xcb33, 0xcb34, 0xcb35, 0xcb36, 0xcb37, 
+    0xcb38, 0xcb39, 0xcb3a, 0xcb3b, 0xcb3c, 0xcb3d, 0xcb3e, 0xcb3f, 
+    0xcb40, 0xcb41, 0xcb42, 0xcb43, 0xcb44, 0xcb45, 0xcb46, 0xcb47, 
+    0xcb48, 0xcb49, 0xcb4a, 0xcb4b, 0xcb4c, 0xcb4d, 0xcb4e, 0xcb4f, 
+    0xcb50, 0xcb51, 0xcb52, 0xcb53, 0xcb54, 0xcb55, 0xcb56, 0xcb57, 
+    0xcb58, 0xcb59, 0xcb5a, 0xcb5b, 0xcb5c, 0xcb5d, 0xcb5e, 0xcb5f, 
+    0xcb60, 0xcb61, 0xcb62, 0xcb63, 0xcb64, 0xcb65, 0xcb66, 0xcb67, 
+    0xcb68, 0xcb69, 0xcb6a, 0xcb6b, 0xcb6c, 0xcb6d, 0xcb6e, 0xcb6f, 
+    0xcb70, 0xcb71, 0xcb72, 0xcb73, 0xcb74, 0xcb75, 0xcb76, 0xcb77, 
+    0xcb78, 0xcb79, 0xcb7a, 0xcb7b, 0xcb7c, 0xcb7d, 0xcb7e, 0xcb7f, 
+    0xcb80, 0xcb81, 0xcb82, 0xcb83, 0xcb84, 0xcb85, 0xcb86, 0xcb87, 
+    0xcb88, 0xcb89, 0xcb8a, 0xcb8b, 0xcb8c, 0xcb8d, 0xcb8e, 0xcb8f, 
+    0xcb90, 0xcb91, 0xcb92, 0xcb93, 0xcb94, 0xcb95, 0xcb96, 0xcb97, 
+    0xcb98, 0xcb99, 0xcb9a, 0xcb9b, 0xcb9c, 0xcb9d, 0xcb9e, 0xcb9f, 
+    0xcba0, 0xcba1, 0xcba2, 0xcba3, 0xcba4, 0xcba5, 0xcba6, 0xcba7, 
+    0xcba8, 0xcba9, 0xcbaa, 0xcbab, 0xcbac, 0xcbad, 0xcbae, 0xcbaf, 
+    0xcbb0, 0xcbb1, 0xcbb2, 0xcbb3, 0xcbb4, 0xcbb5, 0xcbb6, 0xcbb7, 
+    0xcbb8, 0xcbb9, 0xcbba, 0xcbbb, 0xcbbc, 0xcbbd, 0xcbbe, 0xcbbf, 
+    0xcbc0, 0xcbc1, 0xcbc2, 0xcbc3, 0xcbc4, 0xcbc5, 0xcbc6, 0xcbc7, 
+    0xcbc8, 0xcbc9, 0xcbca, 0xcbcb, 0xcbcc, 0xcbcd, 0xcbce, 0xcbcf, 
+    0xcbd0, 0xcbd1, 0xcbd2, 0xcbd3, 0xcbd4, 0xcbd5, 0xcbd6, 0xcbd7, 
+    0xcbd8, 0xcbd9, 0xcbda, 0xcbdb, 0xcbdc, 0xcbdd, 0xcbde, 0xcbdf, 
+    0xcbe0, 0xcbe1, 0xcbe2, 0xcbe3, 0xcbe4, 0xcbe5, 0xcbe6, 0xcbe7, 
+    0xcbe8, 0xcbe9, 0xcbea, 0xcbeb, 0xcbec, 0xcbed, 0xcbee, 0xcbef, 
+    0xcbf0, 0xcbf1, 0xcbf2, 0xcbf3, 0xcbf4, 0xcbf5, 0xcbf6, 0xcbf7, 
+    0xcbf8, 0xcbf9, 0xcbfa, 0xcbfb, 0xcbfc, 0xcbfd, 0xcbfe, 0xcbff, 
+    0xcc00, 0xcc01, 0xcc02, 0xcc03, 0xcc04, 0xcc05, 0xcc06, 0xcc07, 
+    0xcc08, 0xcc09, 0xcc0a, 0xcc0b, 0xcc0c, 0xcc0d, 0xcc0e, 0xcc0f, 
+    0xcc10, 0xcc11, 0xcc12, 0xcc13, 0xcc14, 0xcc15, 0xcc16, 0xcc17, 
+    0xcc18, 0xcc19, 0xcc1a, 0xcc1b, 0xcc1c, 0xcc1d, 0xcc1e, 0xcc1f, 
+    0xcc20, 0xcc21, 0xcc22, 0xcc23, 0xcc24, 0xcc25, 0xcc26, 0xcc27, 
+    0xcc28, 0xcc29, 0xcc2a, 0xcc2b, 0xcc2c, 0xcc2d, 0xcc2e, 0xcc2f, 
+    0xcc30, 0xcc31, 0xcc32, 0xcc33, 0xcc34, 0xcc35, 0xcc36, 0xcc37, 
+    0xcc38, 0xcc39, 0xcc3a, 0xcc3b, 0xcc3c, 0xcc3d, 0xcc3e, 0xcc3f, 
+    0xcc40, 0xcc41, 0xcc42, 0xcc43, 0xcc44, 0xcc45, 0xcc46, 0xcc47, 
+    0xcc48, 0xcc49, 0xcc4a, 0xcc4b, 0xcc4c, 0xcc4d, 0xcc4e, 0xcc4f, 
+    0xcc50, 0xcc51, 0xcc52, 0xcc53, 0xcc54, 0xcc55, 0xcc56, 0xcc57, 
+    0xcc58, 0xcc59, 0xcc5a, 0xcc5b, 0xcc5c, 0xcc5d, 0xcc5e, 0xcc5f, 
+    0xcc60, 0xcc61, 0xcc62, 0xcc63, 0xcc64, 0xcc65, 0xcc66, 0xcc67, 
+    0xcc68, 0xcc69, 0xcc6a, 0xcc6b, 0xcc6c, 0xcc6d, 0xcc6e, 0xcc6f, 
+    0xcc70, 0xcc71, 0xcc72, 0xcc73, 0xcc74, 0xcc75, 0xcc76, 0xcc77, 
+    0xcc78, 0xcc79, 0xcc7a, 0xcc7b, 0xcc7c, 0xcc7d, 0xcc7e, 0xcc7f, 
+    0xcc80, 0xcc81, 0xcc82, 0xcc83, 0xcc84, 0xcc85, 0xcc86, 0xcc87, 
+    0xcc88, 0xcc89, 0xcc8a, 0xcc8b, 0xcc8c, 0xcc8d, 0xcc8e, 0xcc8f, 
+    0xcc90, 0xcc91, 0xcc92, 0xcc93, 0xcc94, 0xcc95, 0xcc96, 0xcc97, 
+    0xcc98, 0xcc99, 0xcc9a, 0xcc9b, 0xcc9c, 0xcc9d, 0xcc9e, 0xcc9f, 
+    0xcca0, 0xcca1, 0xcca2, 0xcca3, 0xcca4, 0xcca5, 0xcca6, 0xcca7, 
+    0xcca8, 0xcca9, 0xccaa, 0xccab, 0xccac, 0xccad, 0xccae, 0xccaf, 
+    0xccb0, 0xccb1, 0xccb2, 0xccb3, 0xccb4, 0xccb5, 0xccb6, 0xccb7, 
+    0xccb8, 0xccb9, 0xccba, 0xccbb, 0xccbc, 0xccbd, 0xccbe, 0xccbf, 
+    0xccc0, 0xccc1, 0xccc2, 0xccc3, 0xccc4, 0xccc5, 0xccc6, 0xccc7, 
+    0xccc8, 0xccc9, 0xccca, 0xcccb, 0xcccc, 0xcccd, 0xccce, 0xcccf, 
+    0xccd0, 0xccd1, 0xccd2, 0xccd3, 0xccd4, 0xccd5, 0xccd6, 0xccd7, 
+    0xccd8, 0xccd9, 0xccda, 0xccdb, 0xccdc, 0xccdd, 0xccde, 0xccdf, 
+    0xcce0, 0xcce1, 0xcce2, 0xcce3, 0xcce4, 0xcce5, 0xcce6, 0xcce7, 
+    0xcce8, 0xcce9, 0xccea, 0xcceb, 0xccec, 0xcced, 0xccee, 0xccef, 
+    0xccf0, 0xccf1, 0xccf2, 0xccf3, 0xccf4, 0xccf5, 0xccf6, 0xccf7, 
+    0xccf8, 0xccf9, 0xccfa, 0xccfb, 0xccfc, 0xccfd, 0xccfe, 0xccff, 
+    0xcd00, 0xcd01, 0xcd02, 0xcd03, 0xcd04, 0xcd05, 0xcd06, 0xcd07, 
+    0xcd08, 0xcd09, 0xcd0a, 0xcd0b, 0xcd0c, 0xcd0d, 0xcd0e, 0xcd0f, 
+    0xcd10, 0xcd11, 0xcd12, 0xcd13, 0xcd14, 0xcd15, 0xcd16, 0xcd17, 
+    0xcd18, 0xcd19, 0xcd1a, 0xcd1b, 0xcd1c, 0xcd1d, 0xcd1e, 0xcd1f, 
+    0xcd20, 0xcd21, 0xcd22, 0xcd23, 0xcd24, 0xcd25, 0xcd26, 0xcd27, 
+    0xcd28, 0xcd29, 0xcd2a, 0xcd2b, 0xcd2c, 0xcd2d, 0xcd2e, 0xcd2f, 
+    0xcd30, 0xcd31, 0xcd32, 0xcd33, 0xcd34, 0xcd35, 0xcd36, 0xcd37, 
+    0xcd38, 0xcd39, 0xcd3a, 0xcd3b, 0xcd3c, 0xcd3d, 0xcd3e, 0xcd3f, 
+    0xcd40, 0xcd41, 0xcd42, 0xcd43, 0xcd44, 0xcd45, 0xcd46, 0xcd47, 
+    0xcd48, 0xcd49, 0xcd4a, 0xcd4b, 0xcd4c, 0xcd4d, 0xcd4e, 0xcd4f, 
+    0xcd50, 0xcd51, 0xcd52, 0xcd53, 0xcd54, 0xcd55, 0xcd56, 0xcd57, 
+    0xcd58, 0xcd59, 0xcd5a, 0xcd5b, 0xcd5c, 0xcd5d, 0xcd5e, 0xcd5f, 
+    0xcd60, 0xcd61, 0xcd62, 0xcd63, 0xcd64, 0xcd65, 0xcd66, 0xcd67, 
+    0xcd68, 0xcd69, 0xcd6a, 0xcd6b, 0xcd6c, 0xcd6d, 0xcd6e, 0xcd6f, 
+    0xcd70, 0xcd71, 0xcd72, 0xcd73, 0xcd74, 0xcd75, 0xcd76, 0xcd77, 
+    0xcd78, 0xcd79, 0xcd7a, 0xcd7b, 0xcd7c, 0xcd7d, 0xcd7e, 0xcd7f, 
+    0xcd80, 0xcd81, 0xcd82, 0xcd83, 0xcd84, 0xcd85, 0xcd86, 0xcd87, 
+    0xcd88, 0xcd89, 0xcd8a, 0xcd8b, 0xcd8c, 0xcd8d, 0xcd8e, 0xcd8f, 
+    0xcd90, 0xcd91, 0xcd92, 0xcd93, 0xcd94, 0xcd95, 0xcd96, 0xcd97, 
+    0xcd98, 0xcd99, 0xcd9a, 0xcd9b, 0xcd9c, 0xcd9d, 0xcd9e, 0xcd9f, 
+    0xcda0, 0xcda1, 0xcda2, 0xcda3, 0xcda4, 0xcda5, 0xcda6, 0xcda7, 
+    0xcda8, 0xcda9, 0xcdaa, 0xcdab, 0xcdac, 0xcdad, 0xcdae, 0xcdaf, 
+    0xcdb0, 0xcdb1, 0xcdb2, 0xcdb3, 0xcdb4, 0xcdb5, 0xcdb6, 0xcdb7, 
+    0xcdb8, 0xcdb9, 0xcdba, 0xcdbb, 0xcdbc, 0xcdbd, 0xcdbe, 0xcdbf, 
+    0xcdc0, 0xcdc1, 0xcdc2, 0xcdc3, 0xcdc4, 0xcdc5, 0xcdc6, 0xcdc7, 
+    0xcdc8, 0xcdc9, 0xcdca, 0xcdcb, 0xcdcc, 0xcdcd, 0xcdce, 0xcdcf, 
+    0xcdd0, 0xcdd1, 0xcdd2, 0xcdd3, 0xcdd4, 0xcdd5, 0xcdd6, 0xcdd7, 
+    0xcdd8, 0xcdd9, 0xcdda, 0xcddb, 0xcddc, 0xcddd, 0xcdde, 0xcddf, 
+    0xcde0, 0xcde1, 0xcde2, 0xcde3, 0xcde4, 0xcde5, 0xcde6, 0xcde7, 
+    0xcde8, 0xcde9, 0xcdea, 0xcdeb, 0xcdec, 0xcded, 0xcdee, 0xcdef, 
+    0xcdf0, 0xcdf1, 0xcdf2, 0xcdf3, 0xcdf4, 0xcdf5, 0xcdf6, 0xcdf7, 
+    0xcdf8, 0xcdf9, 0xcdfa, 0xcdfb, 0xcdfc, 0xcdfd, 0xcdfe, 0xcdff, 
+    0xce00, 0xce01, 0xce02, 0xce03, 0xce04, 0xce05, 0xce06, 0xce07, 
+    0xce08, 0xce09, 0xce0a, 0xce0b, 0xce0c, 0xce0d, 0xce0e, 0xce0f, 
+    0xce10, 0xce11, 0xce12, 0xce13, 0xce14, 0xce15, 0xce16, 0xce17, 
+    0xce18, 0xce19, 0xce1a, 0xce1b, 0xce1c, 0xce1d, 0xce1e, 0xce1f, 
+    0xce20, 0xce21, 0xce22, 0xce23, 0xce24, 0xce25, 0xce26, 0xce27, 
+    0xce28, 0xce29, 0xce2a, 0xce2b, 0xce2c, 0xce2d, 0xce2e, 0xce2f, 
+    0xce30, 0xce31, 0xce32, 0xce33, 0xce34, 0xce35, 0xce36, 0xce37, 
+    0xce38, 0xce39, 0xce3a, 0xce3b, 0xce3c, 0xce3d, 0xce3e, 0xce3f, 
+    0xce40, 0xce41, 0xce42, 0xce43, 0xce44, 0xce45, 0xce46, 0xce47, 
+    0xce48, 0xce49, 0xce4a, 0xce4b, 0xce4c, 0xce4d, 0xce4e, 0xce4f, 
+    0xce50, 0xce51, 0xce52, 0xce53, 0xce54, 0xce55, 0xce56, 0xce57, 
+    0xce58, 0xce59, 0xce5a, 0xce5b, 0xce5c, 0xce5d, 0xce5e, 0xce5f, 
+    0xce60, 0xce61, 0xce62, 0xce63, 0xce64, 0xce65, 0xce66, 0xce67, 
+    0xce68, 0xce69, 0xce6a, 0xce6b, 0xce6c, 0xce6d, 0xce6e, 0xce6f, 
+    0xce70, 0xce71, 0xce72, 0xce73, 0xce74, 0xce75, 0xce76, 0xce77, 
+    0xce78, 0xce79, 0xce7a, 0xce7b, 0xce7c, 0xce7d, 0xce7e, 0xce7f, 
+    0xce80, 0xce81, 0xce82, 0xce83, 0xce84, 0xce85, 0xce86, 0xce87, 
+    0xce88, 0xce89, 0xce8a, 0xce8b, 0xce8c, 0xce8d, 0xce8e, 0xce8f, 
+    0xce90, 0xce91, 0xce92, 0xce93, 0xce94, 0xce95, 0xce96, 0xce97, 
+    0xce98, 0xce99, 0xce9a, 0xce9b, 0xce9c, 0xce9d, 0xce9e, 0xce9f, 
+    0xcea0, 0xcea1, 0xcea2, 0xcea3, 0xcea4, 0xcea5, 0xcea6, 0xcea7, 
+    0xcea8, 0xcea9, 0xceaa, 0xceab, 0xceac, 0xcead, 0xceae, 0xceaf, 
+    0xceb0, 0xceb1, 0xceb2, 0xceb3, 0xceb4, 0xceb5, 0xceb6, 0xceb7, 
+    0xceb8, 0xceb9, 0xceba, 0xcebb, 0xcebc, 0xcebd, 0xcebe, 0xcebf, 
+    0xcec0, 0xcec1, 0xcec2, 0xcec3, 0xcec4, 0xcec5, 0xcec6, 0xcec7, 
+    0xcec8, 0xcec9, 0xceca, 0xcecb, 0xcecc, 0xcecd, 0xcece, 0xcecf, 
+    0xced0, 0xced1, 0xced2, 0xced3, 0xced4, 0xced5, 0xced6, 0xced7, 
+    0xced8, 0xced9, 0xceda, 0xcedb, 0xcedc, 0xcedd, 0xcede, 0xcedf, 
+    0xcee0, 0xcee1, 0xcee2, 0xcee3, 0xcee4, 0xcee5, 0xcee6, 0xcee7, 
+    0xcee8, 0xcee9, 0xceea, 0xceeb, 0xceec, 0xceed, 0xceee, 0xceef, 
+    0xcef0, 0xcef1, 0xcef2, 0xcef3, 0xcef4, 0xcef5, 0xcef6, 0xcef7, 
+    0xcef8, 0xcef9, 0xcefa, 0xcefb, 0xcefc, 0xcefd, 0xcefe, 0xceff, 
+    0xcf00, 0xcf01, 0xcf02, 0xcf03, 0xcf04, 0xcf05, 0xcf06, 0xcf07, 
+    0xcf08, 0xcf09, 0xcf0a, 0xcf0b, 0xcf0c, 0xcf0d, 0xcf0e, 0xcf0f, 
+    0xcf10, 0xcf11, 0xcf12, 0xcf13, 0xcf14, 0xcf15, 0xcf16, 0xcf17, 
+    0xcf18, 0xcf19, 0xcf1a, 0xcf1b, 0xcf1c, 0xcf1d, 0xcf1e, 0xcf1f, 
+    0xcf20, 0xcf21, 0xcf22, 0xcf23, 0xcf24, 0xcf25, 0xcf26, 0xcf27, 
+    0xcf28, 0xcf29, 0xcf2a, 0xcf2b, 0xcf2c, 0xcf2d, 0xcf2e, 0xcf2f, 
+    0xcf30, 0xcf31, 0xcf32, 0xcf33, 0xcf34, 0xcf35, 0xcf36, 0xcf37, 
+    0xcf38, 0xcf39, 0xcf3a, 0xcf3b, 0xcf3c, 0xcf3d, 0xcf3e, 0xcf3f, 
+    0xcf40, 0xcf41, 0xcf42, 0xcf43, 0xcf44, 0xcf45, 0xcf46, 0xcf47, 
+    0xcf48, 0xcf49, 0xcf4a, 0xcf4b, 0xcf4c, 0xcf4d, 0xcf4e, 0xcf4f, 
+    0xcf50, 0xcf51, 0xcf52, 0xcf53, 0xcf54, 0xcf55, 0xcf56, 0xcf57, 
+    0xcf58, 0xcf59, 0xcf5a, 0xcf5b, 0xcf5c, 0xcf5d, 0xcf5e, 0xcf5f, 
+    0xcf60, 0xcf61, 0xcf62, 0xcf63, 0xcf64, 0xcf65, 0xcf66, 0xcf67, 
+    0xcf68, 0xcf69, 0xcf6a, 0xcf6b, 0xcf6c, 0xcf6d, 0xcf6e, 0xcf6f, 
+    0xcf70, 0xcf71, 0xcf72, 0xcf73, 0xcf74, 0xcf75, 0xcf76, 0xcf77, 
+    0xcf78, 0xcf79, 0xcf7a, 0xcf7b, 0xcf7c, 0xcf7d, 0xcf7e, 0xcf7f, 
+    0xcf80, 0xcf81, 0xcf82, 0xcf83, 0xcf84, 0xcf85, 0xcf86, 0xcf87, 
+    0xcf88, 0xcf89, 0xcf8a, 0xcf8b, 0xcf8c, 0xcf8d, 0xcf8e, 0xcf8f, 
+    0xcf90, 0xcf91, 0xcf92, 0xcf93, 0xcf94, 0xcf95, 0xcf96, 0xcf97, 
+    0xcf98, 0xcf99, 0xcf9a, 0xcf9b, 0xcf9c, 0xcf9d, 0xcf9e, 0xcf9f, 
+    0xcfa0, 0xcfa1, 0xcfa2, 0xcfa3, 0xcfa4, 0xcfa5, 0xcfa6, 0xcfa7, 
+    0xcfa8, 0xcfa9, 0xcfaa, 0xcfab, 0xcfac, 0xcfad, 0xcfae, 0xcfaf, 
+    0xcfb0, 0xcfb1, 0xcfb2, 0xcfb3, 0xcfb4, 0xcfb5, 0xcfb6, 0xcfb7, 
+    0xcfb8, 0xcfb9, 0xcfba, 0xcfbb, 0xcfbc, 0xcfbd, 0xcfbe, 0xcfbf, 
+    0xcfc0, 0xcfc1, 0xcfc2, 0xcfc3, 0xcfc4, 0xcfc5, 0xcfc6, 0xcfc7, 
+    0xcfc8, 0xcfc9, 0xcfca, 0xcfcb, 0xcfcc, 0xcfcd, 0xcfce, 0xcfcf, 
+    0xcfd0, 0xcfd1, 0xcfd2, 0xcfd3, 0xcfd4, 0xcfd5, 0xcfd6, 0xcfd7, 
+    0xcfd8, 0xcfd9, 0xcfda, 0xcfdb, 0xcfdc, 0xcfdd, 0xcfde, 0xcfdf, 
+    0xcfe0, 0xcfe1, 0xcfe2, 0xcfe3, 0xcfe4, 0xcfe5, 0xcfe6, 0xcfe7, 
+    0xcfe8, 0xcfe9, 0xcfea, 0xcfeb, 0xcfec, 0xcfed, 0xcfee, 0xcfef, 
+    0xcff0, 0xcff1, 0xcff2, 0xcff3, 0xcff4, 0xcff5, 0xcff6, 0xcff7, 
+    0xcff8, 0xcff9, 0xcffa, 0xcffb, 0xcffc, 0xcffd, 0xcffe, 0xcfff, 
+    0xd000, 0xd001, 0xd002, 0xd003, 0xd004, 0xd005, 0xd006, 0xd007, 
+    0xd008, 0xd009, 0xd00a, 0xd00b, 0xd00c, 0xd00d, 0xd00e, 0xd00f, 
+    0xd010, 0xd011, 0xd012, 0xd013, 0xd014, 0xd015, 0xd016, 0xd017, 
+    0xd018, 0xd019, 0xd01a, 0xd01b, 0xd01c, 0xd01d, 0xd01e, 0xd01f, 
+    0xd020, 0xd021, 0xd022, 0xd023, 0xd024, 0xd025, 0xd026, 0xd027, 
+    0xd028, 0xd029, 0xd02a, 0xd02b, 0xd02c, 0xd02d, 0xd02e, 0xd02f, 
+    0xd030, 0xd031, 0xd032, 0xd033, 0xd034, 0xd035, 0xd036, 0xd037, 
+    0xd038, 0xd039, 0xd03a, 0xd03b, 0xd03c, 0xd03d, 0xd03e, 0xd03f, 
+    0xd040, 0xd041, 0xd042, 0xd043, 0xd044, 0xd045, 0xd046, 0xd047, 
+    0xd048, 0xd049, 0xd04a, 0xd04b, 0xd04c, 0xd04d, 0xd04e, 0xd04f, 
+    0xd050, 0xd051, 0xd052, 0xd053, 0xd054, 0xd055, 0xd056, 0xd057, 
+    0xd058, 0xd059, 0xd05a, 0xd05b, 0xd05c, 0xd05d, 0xd05e, 0xd05f, 
+    0xd060, 0xd061, 0xd062, 0xd063, 0xd064, 0xd065, 0xd066, 0xd067, 
+    0xd068, 0xd069, 0xd06a, 0xd06b, 0xd06c, 0xd06d, 0xd06e, 0xd06f, 
+    0xd070, 0xd071, 0xd072, 0xd073, 0xd074, 0xd075, 0xd076, 0xd077, 
+    0xd078, 0xd079, 0xd07a, 0xd07b, 0xd07c, 0xd07d, 0xd07e, 0xd07f, 
+    0xd080, 0xd081, 0xd082, 0xd083, 0xd084, 0xd085, 0xd086, 0xd087, 
+    0xd088, 0xd089, 0xd08a, 0xd08b, 0xd08c, 0xd08d, 0xd08e, 0xd08f, 
+    0xd090, 0xd091, 0xd092, 0xd093, 0xd094, 0xd095, 0xd096, 0xd097, 
+    0xd098, 0xd099, 0xd09a, 0xd09b, 0xd09c, 0xd09d, 0xd09e, 0xd09f, 
+    0xd0a0, 0xd0a1, 0xd0a2, 0xd0a3, 0xd0a4, 0xd0a5, 0xd0a6, 0xd0a7, 
+    0xd0a8, 0xd0a9, 0xd0aa, 0xd0ab, 0xd0ac, 0xd0ad, 0xd0ae, 0xd0af, 
+    0xd0b0, 0xd0b1, 0xd0b2, 0xd0b3, 0xd0b4, 0xd0b5, 0xd0b6, 0xd0b7, 
+    0xd0b8, 0xd0b9, 0xd0ba, 0xd0bb, 0xd0bc, 0xd0bd, 0xd0be, 0xd0bf, 
+    0xd0c0, 0xd0c1, 0xd0c2, 0xd0c3, 0xd0c4, 0xd0c5, 0xd0c6, 0xd0c7, 
+    0xd0c8, 0xd0c9, 0xd0ca, 0xd0cb, 0xd0cc, 0xd0cd, 0xd0ce, 0xd0cf, 
+    0xd0d0, 0xd0d1, 0xd0d2, 0xd0d3, 0xd0d4, 0xd0d5, 0xd0d6, 0xd0d7, 
+    0xd0d8, 0xd0d9, 0xd0da, 0xd0db, 0xd0dc, 0xd0dd, 0xd0de, 0xd0df, 
+    0xd0e0, 0xd0e1, 0xd0e2, 0xd0e3, 0xd0e4, 0xd0e5, 0xd0e6, 0xd0e7, 
+    0xd0e8, 0xd0e9, 0xd0ea, 0xd0eb, 0xd0ec, 0xd0ed, 0xd0ee, 0xd0ef, 
+    0xd0f0, 0xd0f1, 0xd0f2, 0xd0f3, 0xd0f4, 0xd0f5, 0xd0f6, 0xd0f7, 
+    0xd0f8, 0xd0f9, 0xd0fa, 0xd0fb, 0xd0fc, 0xd0fd, 0xd0fe, 0xd0ff, 
+    0xd100, 0xd101, 0xd102, 0xd103, 0xd104, 0xd105, 0xd106, 0xd107, 
+    0xd108, 0xd109, 0xd10a, 0xd10b, 0xd10c, 0xd10d, 0xd10e, 0xd10f, 
+    0xd110, 0xd111, 0xd112, 0xd113, 0xd114, 0xd115, 0xd116, 0xd117, 
+    0xd118, 0xd119, 0xd11a, 0xd11b, 0xd11c, 0xd11d, 0xd11e, 0xd11f, 
+    0xd120, 0xd121, 0xd122, 0xd123, 0xd124, 0xd125, 0xd126, 0xd127, 
+    0xd128, 0xd129, 0xd12a, 0xd12b, 0xd12c, 0xd12d, 0xd12e, 0xd12f, 
+    0xd130, 0xd131, 0xd132, 0xd133, 0xd134, 0xd135, 0xd136, 0xd137, 
+    0xd138, 0xd139, 0xd13a, 0xd13b, 0xd13c, 0xd13d, 0xd13e, 0xd13f, 
+    0xd140, 0xd141, 0xd142, 0xd143, 0xd144, 0xd145, 0xd146, 0xd147, 
+    0xd148, 0xd149, 0xd14a, 0xd14b, 0xd14c, 0xd14d, 0xd14e, 0xd14f, 
+    0xd150, 0xd151, 0xd152, 0xd153, 0xd154, 0xd155, 0xd156, 0xd157, 
+    0xd158, 0xd159, 0xd15a, 0xd15b, 0xd15c, 0xd15d, 0xd15e, 0xd15f, 
+    0xd160, 0xd161, 0xd162, 0xd163, 0xd164, 0xd165, 0xd166, 0xd167, 
+    0xd168, 0xd169, 0xd16a, 0xd16b, 0xd16c, 0xd16d, 0xd16e, 0xd16f, 
+    0xd170, 0xd171, 0xd172, 0xd173, 0xd174, 0xd175, 0xd176, 0xd177, 
+    0xd178, 0xd179, 0xd17a, 0xd17b, 0xd17c, 0xd17d, 0xd17e, 0xd17f, 
+    0xd180, 0xd181, 0xd182, 0xd183, 0xd184, 0xd185, 0xd186, 0xd187, 
+    0xd188, 0xd189, 0xd18a, 0xd18b, 0xd18c, 0xd18d, 0xd18e, 0xd18f, 
+    0xd190, 0xd191, 0xd192, 0xd193, 0xd194, 0xd195, 0xd196, 0xd197, 
+    0xd198, 0xd199, 0xd19a, 0xd19b, 0xd19c, 0xd19d, 0xd19e, 0xd19f, 
+    0xd1a0, 0xd1a1, 0xd1a2, 0xd1a3, 0xd1a4, 0xd1a5, 0xd1a6, 0xd1a7, 
+    0xd1a8, 0xd1a9, 0xd1aa, 0xd1ab, 0xd1ac, 0xd1ad, 0xd1ae, 0xd1af, 
+    0xd1b0, 0xd1b1, 0xd1b2, 0xd1b3, 0xd1b4, 0xd1b5, 0xd1b6, 0xd1b7, 
+    0xd1b8, 0xd1b9, 0xd1ba, 0xd1bb, 0xd1bc, 0xd1bd, 0xd1be, 0xd1bf, 
+    0xd1c0, 0xd1c1, 0xd1c2, 0xd1c3, 0xd1c4, 0xd1c5, 0xd1c6, 0xd1c7, 
+    0xd1c8, 0xd1c9, 0xd1ca, 0xd1cb, 0xd1cc, 0xd1cd, 0xd1ce, 0xd1cf, 
+    0xd1d0, 0xd1d1, 0xd1d2, 0xd1d3, 0xd1d4, 0xd1d5, 0xd1d6, 0xd1d7, 
+    0xd1d8, 0xd1d9, 0xd1da, 0xd1db, 0xd1dc, 0xd1dd, 0xd1de, 0xd1df, 
+    0xd1e0, 0xd1e1, 0xd1e2, 0xd1e3, 0xd1e4, 0xd1e5, 0xd1e6, 0xd1e7, 
+    0xd1e8, 0xd1e9, 0xd1ea, 0xd1eb, 0xd1ec, 0xd1ed, 0xd1ee, 0xd1ef, 
+    0xd1f0, 0xd1f1, 0xd1f2, 0xd1f3, 0xd1f4, 0xd1f5, 0xd1f6, 0xd1f7, 
+    0xd1f8, 0xd1f9, 0xd1fa, 0xd1fb, 0xd1fc, 0xd1fd, 0xd1fe, 0xd1ff, 
+    0xd200, 0xd201, 0xd202, 0xd203, 0xd204, 0xd205, 0xd206, 0xd207, 
+    0xd208, 0xd209, 0xd20a, 0xd20b, 0xd20c, 0xd20d, 0xd20e, 0xd20f, 
+    0xd210, 0xd211, 0xd212, 0xd213, 0xd214, 0xd215, 0xd216, 0xd217, 
+    0xd218, 0xd219, 0xd21a, 0xd21b, 0xd21c, 0xd21d, 0xd21e, 0xd21f, 
+    0xd220, 0xd221, 0xd222, 0xd223, 0xd224, 0xd225, 0xd226, 0xd227, 
+    0xd228, 0xd229, 0xd22a, 0xd22b, 0xd22c, 0xd22d, 0xd22e, 0xd22f, 
+    0xd230, 0xd231, 0xd232, 0xd233, 0xd234, 0xd235, 0xd236, 0xd237, 
+    0xd238, 0xd239, 0xd23a, 0xd23b, 0xd23c, 0xd23d, 0xd23e, 0xd23f, 
+    0xd240, 0xd241, 0xd242, 0xd243, 0xd244, 0xd245, 0xd246, 0xd247, 
+    0xd248, 0xd249, 0xd24a, 0xd24b, 0xd24c, 0xd24d, 0xd24e, 0xd24f, 
+    0xd250, 0xd251, 0xd252, 0xd253, 0xd254, 0xd255, 0xd256, 0xd257, 
+    0xd258, 0xd259, 0xd25a, 0xd25b, 0xd25c, 0xd25d, 0xd25e, 0xd25f, 
+    0xd260, 0xd261, 0xd262, 0xd263, 0xd264, 0xd265, 0xd266, 0xd267, 
+    0xd268, 0xd269, 0xd26a, 0xd26b, 0xd26c, 0xd26d, 0xd26e, 0xd26f, 
+    0xd270, 0xd271, 0xd272, 0xd273, 0xd274, 0xd275, 0xd276, 0xd277, 
+    0xd278, 0xd279, 0xd27a, 0xd27b, 0xd27c, 0xd27d, 0xd27e, 0xd27f, 
+    0xd280, 0xd281, 0xd282, 0xd283, 0xd284, 0xd285, 0xd286, 0xd287, 
+    0xd288, 0xd289, 0xd28a, 0xd28b, 0xd28c, 0xd28d, 0xd28e, 0xd28f, 
+    0xd290, 0xd291, 0xd292, 0xd293, 0xd294, 0xd295, 0xd296, 0xd297, 
+    0xd298, 0xd299, 0xd29a, 0xd29b, 0xd29c, 0xd29d, 0xd29e, 0xd29f, 
+    0xd2a0, 0xd2a1, 0xd2a2, 0xd2a3, 0xd2a4, 0xd2a5, 0xd2a6, 0xd2a7, 
+    0xd2a8, 0xd2a9, 0xd2aa, 0xd2ab, 0xd2ac, 0xd2ad, 0xd2ae, 0xd2af, 
+    0xd2b0, 0xd2b1, 0xd2b2, 0xd2b3, 0xd2b4, 0xd2b5, 0xd2b6, 0xd2b7, 
+    0xd2b8, 0xd2b9, 0xd2ba, 0xd2bb, 0xd2bc, 0xd2bd, 0xd2be, 0xd2bf, 
+    0xd2c0, 0xd2c1, 0xd2c2, 0xd2c3, 0xd2c4, 0xd2c5, 0xd2c6, 0xd2c7, 
+    0xd2c8, 0xd2c9, 0xd2ca, 0xd2cb, 0xd2cc, 0xd2cd, 0xd2ce, 0xd2cf, 
+    0xd2d0, 0xd2d1, 0xd2d2, 0xd2d3, 0xd2d4, 0xd2d5, 0xd2d6, 0xd2d7, 
+    0xd2d8, 0xd2d9, 0xd2da, 0xd2db, 0xd2dc, 0xd2dd, 0xd2de, 0xd2df, 
+    0xd2e0, 0xd2e1, 0xd2e2, 0xd2e3, 0xd2e4, 0xd2e5, 0xd2e6, 0xd2e7, 
+    0xd2e8, 0xd2e9, 0xd2ea, 0xd2eb, 0xd2ec, 0xd2ed, 0xd2ee, 0xd2ef, 
+    0xd2f0, 0xd2f1, 0xd2f2, 0xd2f3, 0xd2f4, 0xd2f5, 0xd2f6, 0xd2f7, 
+    0xd2f8, 0xd2f9, 0xd2fa, 0xd2fb, 0xd2fc, 0xd2fd, 0xd2fe, 0xd2ff, 
+    0xd300, 0xd301, 0xd302, 0xd303, 0xd304, 0xd305, 0xd306, 0xd307, 
+    0xd308, 0xd309, 0xd30a, 0xd30b, 0xd30c, 0xd30d, 0xd30e, 0xd30f, 
+    0xd310, 0xd311, 0xd312, 0xd313, 0xd314, 0xd315, 0xd316, 0xd317, 
+    0xd318, 0xd319, 0xd31a, 0xd31b, 0xd31c, 0xd31d, 0xd31e, 0xd31f, 
+    0xd320, 0xd321, 0xd322, 0xd323, 0xd324, 0xd325, 0xd326, 0xd327, 
+    0xd328, 0xd329, 0xd32a, 0xd32b, 0xd32c, 0xd32d, 0xd32e, 0xd32f, 
+    0xd330, 0xd331, 0xd332, 0xd333, 0xd334, 0xd335, 0xd336, 0xd337, 
+    0xd338, 0xd339, 0xd33a, 0xd33b, 0xd33c, 0xd33d, 0xd33e, 0xd33f, 
+    0xd340, 0xd341, 0xd342, 0xd343, 0xd344, 0xd345, 0xd346, 0xd347, 
+    0xd348, 0xd349, 0xd34a, 0xd34b, 0xd34c, 0xd34d, 0xd34e, 0xd34f, 
+    0xd350, 0xd351, 0xd352, 0xd353, 0xd354, 0xd355, 0xd356, 0xd357, 
+    0xd358, 0xd359, 0xd35a, 0xd35b, 0xd35c, 0xd35d, 0xd35e, 0xd35f, 
+    0xd360, 0xd361, 0xd362, 0xd363, 0xd364, 0xd365, 0xd366, 0xd367, 
+    0xd368, 0xd369, 0xd36a, 0xd36b, 0xd36c, 0xd36d, 0xd36e, 0xd36f, 
+    0xd370, 0xd371, 0xd372, 0xd373, 0xd374, 0xd375, 0xd376, 0xd377, 
+    0xd378, 0xd379, 0xd37a, 0xd37b, 0xd37c, 0xd37d, 0xd37e, 0xd37f, 
+    0xd380, 0xd381, 0xd382, 0xd383, 0xd384, 0xd385, 0xd386, 0xd387, 
+    0xd388, 0xd389, 0xd38a, 0xd38b, 0xd38c, 0xd38d, 0xd38e, 0xd38f, 
+    0xd390, 0xd391, 0xd392, 0xd393, 0xd394, 0xd395, 0xd396, 0xd397, 
+    0xd398, 0xd399, 0xd39a, 0xd39b, 0xd39c, 0xd39d, 0xd39e, 0xd39f, 
+    0xd3a0, 0xd3a1, 0xd3a2, 0xd3a3, 0xd3a4, 0xd3a5, 0xd3a6, 0xd3a7, 
+    0xd3a8, 0xd3a9, 0xd3aa, 0xd3ab, 0xd3ac, 0xd3ad, 0xd3ae, 0xd3af, 
+    0xd3b0, 0xd3b1, 0xd3b2, 0xd3b3, 0xd3b4, 0xd3b5, 0xd3b6, 0xd3b7, 
+    0xd3b8, 0xd3b9, 0xd3ba, 0xd3bb, 0xd3bc, 0xd3bd, 0xd3be, 0xd3bf, 
+    0xd3c0, 0xd3c1, 0xd3c2, 0xd3c3, 0xd3c4, 0xd3c5, 0xd3c6, 0xd3c7, 
+    0xd3c8, 0xd3c9, 0xd3ca, 0xd3cb, 0xd3cc, 0xd3cd, 0xd3ce, 0xd3cf, 
+    0xd3d0, 0xd3d1, 0xd3d2, 0xd3d3, 0xd3d4, 0xd3d5, 0xd3d6, 0xd3d7, 
+    0xd3d8, 0xd3d9, 0xd3da, 0xd3db, 0xd3dc, 0xd3dd, 0xd3de, 0xd3df, 
+    0xd3e0, 0xd3e1, 0xd3e2, 0xd3e3, 0xd3e4, 0xd3e5, 0xd3e6, 0xd3e7, 
+    0xd3e8, 0xd3e9, 0xd3ea, 0xd3eb, 0xd3ec, 0xd3ed, 0xd3ee, 0xd3ef, 
+    0xd3f0, 0xd3f1, 0xd3f2, 0xd3f3, 0xd3f4, 0xd3f5, 0xd3f6, 0xd3f7, 
+    0xd3f8, 0xd3f9, 0xd3fa, 0xd3fb, 0xd3fc, 0xd3fd, 0xd3fe, 0xd3ff, 
+    0xd400, 0xd401, 0xd402, 0xd403, 0xd404, 0xd405, 0xd406, 0xd407, 
+    0xd408, 0xd409, 0xd40a, 0xd40b, 0xd40c, 0xd40d, 0xd40e, 0xd40f, 
+    0xd410, 0xd411, 0xd412, 0xd413, 0xd414, 0xd415, 0xd416, 0xd417, 
+    0xd418, 0xd419, 0xd41a, 0xd41b, 0xd41c, 0xd41d, 0xd41e, 0xd41f, 
+    0xd420, 0xd421, 0xd422, 0xd423, 0xd424, 0xd425, 0xd426, 0xd427, 
+    0xd428, 0xd429, 0xd42a, 0xd42b, 0xd42c, 0xd42d, 0xd42e, 0xd42f, 
+    0xd430, 0xd431, 0xd432, 0xd433, 0xd434, 0xd435, 0xd436, 0xd437, 
+    0xd438, 0xd439, 0xd43a, 0xd43b, 0xd43c, 0xd43d, 0xd43e, 0xd43f, 
+    0xd440, 0xd441, 0xd442, 0xd443, 0xd444, 0xd445, 0xd446, 0xd447, 
+    0xd448, 0xd449, 0xd44a, 0xd44b, 0xd44c, 0xd44d, 0xd44e, 0xd44f, 
+    0xd450, 0xd451, 0xd452, 0xd453, 0xd454, 0xd455, 0xd456, 0xd457, 
+    0xd458, 0xd459, 0xd45a, 0xd45b, 0xd45c, 0xd45d, 0xd45e, 0xd45f, 
+    0xd460, 0xd461, 0xd462, 0xd463, 0xd464, 0xd465, 0xd466, 0xd467, 
+    0xd468, 0xd469, 0xd46a, 0xd46b, 0xd46c, 0xd46d, 0xd46e, 0xd46f, 
+    0xd470, 0xd471, 0xd472, 0xd473, 0xd474, 0xd475, 0xd476, 0xd477, 
+    0xd478, 0xd479, 0xd47a, 0xd47b, 0xd47c, 0xd47d, 0xd47e, 0xd47f, 
+    0xd480, 0xd481, 0xd482, 0xd483, 0xd484, 0xd485, 0xd486, 0xd487, 
+    0xd488, 0xd489, 0xd48a, 0xd48b, 0xd48c, 0xd48d, 0xd48e, 0xd48f, 
+    0xd490, 0xd491, 0xd492, 0xd493, 0xd494, 0xd495, 0xd496, 0xd497, 
+    0xd498, 0xd499, 0xd49a, 0xd49b, 0xd49c, 0xd49d, 0xd49e, 0xd49f, 
+    0xd4a0, 0xd4a1, 0xd4a2, 0xd4a3, 0xd4a4, 0xd4a5, 0xd4a6, 0xd4a7, 
+    0xd4a8, 0xd4a9, 0xd4aa, 0xd4ab, 0xd4ac, 0xd4ad, 0xd4ae, 0xd4af, 
+    0xd4b0, 0xd4b1, 0xd4b2, 0xd4b3, 0xd4b4, 0xd4b5, 0xd4b6, 0xd4b7, 
+    0xd4b8, 0xd4b9, 0xd4ba, 0xd4bb, 0xd4bc, 0xd4bd, 0xd4be, 0xd4bf, 
+    0xd4c0, 0xd4c1, 0xd4c2, 0xd4c3, 0xd4c4, 0xd4c5, 0xd4c6, 0xd4c7, 
+    0xd4c8, 0xd4c9, 0xd4ca, 0xd4cb, 0xd4cc, 0xd4cd, 0xd4ce, 0xd4cf, 
+    0xd4d0, 0xd4d1, 0xd4d2, 0xd4d3, 0xd4d4, 0xd4d5, 0xd4d6, 0xd4d7, 
+    0xd4d8, 0xd4d9, 0xd4da, 0xd4db, 0xd4dc, 0xd4dd, 0xd4de, 0xd4df, 
+    0xd4e0, 0xd4e1, 0xd4e2, 0xd4e3, 0xd4e4, 0xd4e5, 0xd4e6, 0xd4e7, 
+    0xd4e8, 0xd4e9, 0xd4ea, 0xd4eb, 0xd4ec, 0xd4ed, 0xd4ee, 0xd4ef, 
+    0xd4f0, 0xd4f1, 0xd4f2, 0xd4f3, 0xd4f4, 0xd4f5, 0xd4f6, 0xd4f7, 
+    0xd4f8, 0xd4f9, 0xd4fa, 0xd4fb, 0xd4fc, 0xd4fd, 0xd4fe, 0xd4ff, 
+    0xd500, 0xd501, 0xd502, 0xd503, 0xd504, 0xd505, 0xd506, 0xd507, 
+    0xd508, 0xd509, 0xd50a, 0xd50b, 0xd50c, 0xd50d, 0xd50e, 0xd50f, 
+    0xd510, 0xd511, 0xd512, 0xd513, 0xd514, 0xd515, 0xd516, 0xd517, 
+    0xd518, 0xd519, 0xd51a, 0xd51b, 0xd51c, 0xd51d, 0xd51e, 0xd51f, 
+    0xd520, 0xd521, 0xd522, 0xd523, 0xd524, 0xd525, 0xd526, 0xd527, 
+    0xd528, 0xd529, 0xd52a, 0xd52b, 0xd52c, 0xd52d, 0xd52e, 0xd52f, 
+    0xd530, 0xd531, 0xd532, 0xd533, 0xd534, 0xd535, 0xd536, 0xd537, 
+    0xd538, 0xd539, 0xd53a, 0xd53b, 0xd53c, 0xd53d, 0xd53e, 0xd53f, 
+    0xd540, 0xd541, 0xd542, 0xd543, 0xd544, 0xd545, 0xd546, 0xd547, 
+    0xd548, 0xd549, 0xd54a, 0xd54b, 0xd54c, 0xd54d, 0xd54e, 0xd54f, 
+    0xd550, 0xd551, 0xd552, 0xd553, 0xd554, 0xd555, 0xd556, 0xd557, 
+    0xd558, 0xd559, 0xd55a, 0xd55b, 0xd55c, 0xd55d, 0xd55e, 0xd55f, 
+    0xd560, 0xd561, 0xd562, 0xd563, 0xd564, 0xd565, 0xd566, 0xd567, 
+    0xd568, 0xd569, 0xd56a, 0xd56b, 0xd56c, 0xd56d, 0xd56e, 0xd56f, 
+    0xd570, 0xd571, 0xd572, 0xd573, 0xd574, 0xd575, 0xd576, 0xd577, 
+    0xd578, 0xd579, 0xd57a, 0xd57b, 0xd57c, 0xd57d, 0xd57e, 0xd57f, 
+    0xd580, 0xd581, 0xd582, 0xd583, 0xd584, 0xd585, 0xd586, 0xd587, 
+    0xd588, 0xd589, 0xd58a, 0xd58b, 0xd58c, 0xd58d, 0xd58e, 0xd58f, 
+    0xd590, 0xd591, 0xd592, 0xd593, 0xd594, 0xd595, 0xd596, 0xd597, 
+    0xd598, 0xd599, 0xd59a, 0xd59b, 0xd59c, 0xd59d, 0xd59e, 0xd59f, 
+    0xd5a0, 0xd5a1, 0xd5a2, 0xd5a3, 0xd5a4, 0xd5a5, 0xd5a6, 0xd5a7, 
+    0xd5a8, 0xd5a9, 0xd5aa, 0xd5ab, 0xd5ac, 0xd5ad, 0xd5ae, 0xd5af, 
+    0xd5b0, 0xd5b1, 0xd5b2, 0xd5b3, 0xd5b4, 0xd5b5, 0xd5b6, 0xd5b7, 
+    0xd5b8, 0xd5b9, 0xd5ba, 0xd5bb, 0xd5bc, 0xd5bd, 0xd5be, 0xd5bf, 
+    0xd5c0, 0xd5c1, 0xd5c2, 0xd5c3, 0xd5c4, 0xd5c5, 0xd5c6, 0xd5c7, 
+    0xd5c8, 0xd5c9, 0xd5ca, 0xd5cb, 0xd5cc, 0xd5cd, 0xd5ce, 0xd5cf, 
+    0xd5d0, 0xd5d1, 0xd5d2, 0xd5d3, 0xd5d4, 0xd5d5, 0xd5d6, 0xd5d7, 
+    0xd5d8, 0xd5d9, 0xd5da, 0xd5db, 0xd5dc, 0xd5dd, 0xd5de, 0xd5df, 
+    0xd5e0, 0xd5e1, 0xd5e2, 0xd5e3, 0xd5e4, 0xd5e5, 0xd5e6, 0xd5e7, 
+    0xd5e8, 0xd5e9, 0xd5ea, 0xd5eb, 0xd5ec, 0xd5ed, 0xd5ee, 0xd5ef, 
+    0xd5f0, 0xd5f1, 0xd5f2, 0xd5f3, 0xd5f4, 0xd5f5, 0xd5f6, 0xd5f7, 
+    0xd5f8, 0xd5f9, 0xd5fa, 0xd5fb, 0xd5fc, 0xd5fd, 0xd5fe, 0xd5ff, 
+    0xd600, 0xd601, 0xd602, 0xd603, 0xd604, 0xd605, 0xd606, 0xd607, 
+    0xd608, 0xd609, 0xd60a, 0xd60b, 0xd60c, 0xd60d, 0xd60e, 0xd60f, 
+    0xd610, 0xd611, 0xd612, 0xd613, 0xd614, 0xd615, 0xd616, 0xd617, 
+    0xd618, 0xd619, 0xd61a, 0xd61b, 0xd61c, 0xd61d, 0xd61e, 0xd61f, 
+    0xd620, 0xd621, 0xd622, 0xd623, 0xd624, 0xd625, 0xd626, 0xd627, 
+    0xd628, 0xd629, 0xd62a, 0xd62b, 0xd62c, 0xd62d, 0xd62e, 0xd62f, 
+    0xd630, 0xd631, 0xd632, 0xd633, 0xd634, 0xd635, 0xd636, 0xd637, 
+    0xd638, 0xd639, 0xd63a, 0xd63b, 0xd63c, 0xd63d, 0xd63e, 0xd63f, 
+    0xd640, 0xd641, 0xd642, 0xd643, 0xd644, 0xd645, 0xd646, 0xd647, 
+    0xd648, 0xd649, 0xd64a, 0xd64b, 0xd64c, 0xd64d, 0xd64e, 0xd64f, 
+    0xd650, 0xd651, 0xd652, 0xd653, 0xd654, 0xd655, 0xd656, 0xd657, 
+    0xd658, 0xd659, 0xd65a, 0xd65b, 0xd65c, 0xd65d, 0xd65e, 0xd65f, 
+    0xd660, 0xd661, 0xd662, 0xd663, 0xd664, 0xd665, 0xd666, 0xd667, 
+    0xd668, 0xd669, 0xd66a, 0xd66b, 0xd66c, 0xd66d, 0xd66e, 0xd66f, 
+    0xd670, 0xd671, 0xd672, 0xd673, 0xd674, 0xd675, 0xd676, 0xd677, 
+    0xd678, 0xd679, 0xd67a, 0xd67b, 0xd67c, 0xd67d, 0xd67e, 0xd67f, 
+    0xd680, 0xd681, 0xd682, 0xd683, 0xd684, 0xd685, 0xd686, 0xd687, 
+    0xd688, 0xd689, 0xd68a, 0xd68b, 0xd68c, 0xd68d, 0xd68e, 0xd68f, 
+    0xd690, 0xd691, 0xd692, 0xd693, 0xd694, 0xd695, 0xd696, 0xd697, 
+    0xd698, 0xd699, 0xd69a, 0xd69b, 0xd69c, 0xd69d, 0xd69e, 0xd69f, 
+    0xd6a0, 0xd6a1, 0xd6a2, 0xd6a3, 0xd6a4, 0xd6a5, 0xd6a6, 0xd6a7, 
+    0xd6a8, 0xd6a9, 0xd6aa, 0xd6ab, 0xd6ac, 0xd6ad, 0xd6ae, 0xd6af, 
+    0xd6b0, 0xd6b1, 0xd6b2, 0xd6b3, 0xd6b4, 0xd6b5, 0xd6b6, 0xd6b7, 
+    0xd6b8, 0xd6b9, 0xd6ba, 0xd6bb, 0xd6bc, 0xd6bd, 0xd6be, 0xd6bf, 
+    0xd6c0, 0xd6c1, 0xd6c2, 0xd6c3, 0xd6c4, 0xd6c5, 0xd6c6, 0xd6c7, 
+    0xd6c8, 0xd6c9, 0xd6ca, 0xd6cb, 0xd6cc, 0xd6cd, 0xd6ce, 0xd6cf, 
+    0xd6d0, 0xd6d1, 0xd6d2, 0xd6d3, 0xd6d4, 0xd6d5, 0xd6d6, 0xd6d7, 
+    0xd6d8, 0xd6d9, 0xd6da, 0xd6db, 0xd6dc, 0xd6dd, 0xd6de, 0xd6df, 
+    0xd6e0, 0xd6e1, 0xd6e2, 0xd6e3, 0xd6e4, 0xd6e5, 0xd6e6, 0xd6e7, 
+    0xd6e8, 0xd6e9, 0xd6ea, 0xd6eb, 0xd6ec, 0xd6ed, 0xd6ee, 0xd6ef, 
+    0xd6f0, 0xd6f1, 0xd6f2, 0xd6f3, 0xd6f4, 0xd6f5, 0xd6f6, 0xd6f7, 
+    0xd6f8, 0xd6f9, 0xd6fa, 0xd6fb, 0xd6fc, 0xd6fd, 0xd6fe, 0xd6ff, 
+    0xd700, 0xd701, 0xd702, 0xd703, 0xd704, 0xd705, 0xd706, 0xd707, 
+    0xd708, 0xd709, 0xd70a, 0xd70b, 0xd70c, 0xd70d, 0xd70e, 0xd70f, 
+    0xd710, 0xd711, 0xd712, 0xd713, 0xd714, 0xd715, 0xd716, 0xd717, 
+    0xd718, 0xd719, 0xd71a, 0xd71b, 0xd71c, 0xd71d, 0xd71e, 0xd71f, 
+    0xd720, 0xd721, 0xd722, 0xd723, 0xd724, 0xd725, 0xd726, 0xd727, 
+    0xd728, 0xd729, 0xd72a, 0xd72b, 0xd72c, 0xd72d, 0xd72e, 0xd72f, 
+    0xd730, 0xd731, 0xd732, 0xd733, 0xd734, 0xd735, 0xd736, 0xd737, 
+    0xd738, 0xd739, 0xd73a, 0xd73b, 0xd73c, 0xd73d, 0xd73e, 0xd73f, 
+    0xd740, 0xd741, 0xd742, 0xd743, 0xd744, 0xd745, 0xd746, 0xd747, 
+    0xd748, 0xd749, 0xd74a, 0xd74b, 0xd74c, 0xd74d, 0xd74e, 0xd74f, 
+    0xd750, 0xd751, 0xd752, 0xd753, 0xd754, 0xd755, 0xd756, 0xd757, 
+    0xd758, 0xd759, 0xd75a, 0xd75b, 0xd75c, 0xd75d, 0xd75e, 0xd75f, 
+    0xd760, 0xd761, 0xd762, 0xd763, 0xd764, 0xd765, 0xd766, 0xd767, 
+    0xd768, 0xd769, 0xd76a, 0xd76b, 0xd76c, 0xd76d, 0xd76e, 0xd76f, 
+    0xd770, 0xd771, 0xd772, 0xd773, 0xd774, 0xd775, 0xd776, 0xd777, 
+    0xd778, 0xd779, 0xd77a, 0xd77b, 0xd77c, 0xd77d, 0xd77e, 0xd77f, 
+    0xd780, 0xd781, 0xd782, 0xd783, 0xd784, 0xd785, 0xd786, 0xd787, 
+    0xd788, 0xd789, 0xd78a, 0xd78b, 0xd78c, 0xd78d, 0xd78e, 0xd78f, 
+    0xd790, 0xd791, 0xd792, 0xd793, 0xd794, 0xd795, 0xd796, 0xd797, 
+    0xd798, 0xd799, 0xd79a, 0xd79b, 0xd79c, 0xd79d, 0xd79e, 0xd79f, 
+    0xd7a0, 0xd7a1, 0xd7a2, 0xd7a3, 0xd7a4, 0xd7a5, 0xd7a6, 0xd7a7, 
+    0xd7a8, 0xd7a9, 0xd7aa, 0xd7ab, 0xd7ac, 0xd7ad, 0xd7ae, 0xd7af, 
+    0xd7b0, 0xd7b1, 0xd7b2, 0xd7b3, 0xd7b4, 0xd7b5, 0xd7b6, 0xd7b7, 
+    0xd7b8, 0xd7b9, 0xd7ba, 0xd7bb, 0xd7bc, 0xd7bd, 0xd7be, 0xd7bf, 
+    0xd7c0, 0xd7c1, 0xd7c2, 0xd7c3, 0xd7c4, 0xd7c5, 0xd7c6, 0xd7c7, 
+    0xd7c8, 0xd7c9, 0xd7ca, 0xd7cb, 0xd7cc, 0xd7cd, 0xd7ce, 0xd7cf, 
+    0xd7d0, 0xd7d1, 0xd7d2, 0xd7d3, 0xd7d4, 0xd7d5, 0xd7d6, 0xd7d7, 
+    0xd7d8, 0xd7d9, 0xd7da, 0xd7db, 0xd7dc, 0xd7dd, 0xd7de, 0xd7df, 
+    0xd7e0, 0xd7e1, 0xd7e2, 0xd7e3, 0xd7e4, 0xd7e5, 0xd7e6, 0xd7e7, 
+    0xd7e8, 0xd7e9, 0xd7ea, 0xd7eb, 0xd7ec, 0xd7ed, 0xd7ee, 0xd7ef, 
+    0xd7f0, 0xd7f1, 0xd7f2, 0xd7f3, 0xd7f4, 0xd7f5, 0xd7f6, 0xd7f7, 
+    0xd7f8, 0xd7f9, 0xd7fa, 0xd7fb, 0xd7fc, 0xd7fd, 0xd7fe, 0xd7ff, 
+    0xd800, 0xd801, 0xd802, 0xd803, 0xd804, 0xd805, 0xd806, 0xd807, 
+    0xd808, 0xd809, 0xd80a, 0xd80b, 0xd80c, 0xd80d, 0xd80e, 0xd80f, 
+    0xd810, 0xd811, 0xd812, 0xd813, 0xd814, 0xd815, 0xd816, 0xd817, 
+    0xd818, 0xd819, 0xd81a, 0xd81b, 0xd81c, 0xd81d, 0xd81e, 0xd81f, 
+    0xd820, 0xd821, 0xd822, 0xd823, 0xd824, 0xd825, 0xd826, 0xd827, 
+    0xd828, 0xd829, 0xd82a, 0xd82b, 0xd82c, 0xd82d, 0xd82e, 0xd82f, 
+    0xd830, 0xd831, 0xd832, 0xd833, 0xd834, 0xd835, 0xd836, 0xd837, 
+    0xd838, 0xd839, 0xd83a, 0xd83b, 0xd83c, 0xd83d, 0xd83e, 0xd83f, 
+    0xd840, 0xd841, 0xd842, 0xd843, 0xd844, 0xd845, 0xd846, 0xd847, 
+    0xd848, 0xd849, 0xd84a, 0xd84b, 0xd84c, 0xd84d, 0xd84e, 0xd84f, 
+    0xd850, 0xd851, 0xd852, 0xd853, 0xd854, 0xd855, 0xd856, 0xd857, 
+    0xd858, 0xd859, 0xd85a, 0xd85b, 0xd85c, 0xd85d, 0xd85e, 0xd85f, 
+    0xd860, 0xd861, 0xd862, 0xd863, 0xd864, 0xd865, 0xd866, 0xd867, 
+    0xd868, 0xd869, 0xd86a, 0xd86b, 0xd86c, 0xd86d, 0xd86e, 0xd86f, 
+    0xd870, 0xd871, 0xd872, 0xd873, 0xd874, 0xd875, 0xd876, 0xd877, 
+    0xd878, 0xd879, 0xd87a, 0xd87b, 0xd87c, 0xd87d, 0xd87e, 0xd87f, 
+    0xd880, 0xd881, 0xd882, 0xd883, 0xd884, 0xd885, 0xd886, 0xd887, 
+    0xd888, 0xd889, 0xd88a, 0xd88b, 0xd88c, 0xd88d, 0xd88e, 0xd88f, 
+    0xd890, 0xd891, 0xd892, 0xd893, 0xd894, 0xd895, 0xd896, 0xd897, 
+    0xd898, 0xd899, 0xd89a, 0xd89b, 0xd89c, 0xd89d, 0xd89e, 0xd89f, 
+    0xd8a0, 0xd8a1, 0xd8a2, 0xd8a3, 0xd8a4, 0xd8a5, 0xd8a6, 0xd8a7, 
+    0xd8a8, 0xd8a9, 0xd8aa, 0xd8ab, 0xd8ac, 0xd8ad, 0xd8ae, 0xd8af, 
+    0xd8b0, 0xd8b1, 0xd8b2, 0xd8b3, 0xd8b4, 0xd8b5, 0xd8b6, 0xd8b7, 
+    0xd8b8, 0xd8b9, 0xd8ba, 0xd8bb, 0xd8bc, 0xd8bd, 0xd8be, 0xd8bf, 
+    0xd8c0, 0xd8c1, 0xd8c2, 0xd8c3, 0xd8c4, 0xd8c5, 0xd8c6, 0xd8c7, 
+    0xd8c8, 0xd8c9, 0xd8ca, 0xd8cb, 0xd8cc, 0xd8cd, 0xd8ce, 0xd8cf, 
+    0xd8d0, 0xd8d1, 0xd8d2, 0xd8d3, 0xd8d4, 0xd8d5, 0xd8d6, 0xd8d7, 
+    0xd8d8, 0xd8d9, 0xd8da, 0xd8db, 0xd8dc, 0xd8dd, 0xd8de, 0xd8df, 
+    0xd8e0, 0xd8e1, 0xd8e2, 0xd8e3, 0xd8e4, 0xd8e5, 0xd8e6, 0xd8e7, 
+    0xd8e8, 0xd8e9, 0xd8ea, 0xd8eb, 0xd8ec, 0xd8ed, 0xd8ee, 0xd8ef, 
+    0xd8f0, 0xd8f1, 0xd8f2, 0xd8f3, 0xd8f4, 0xd8f5, 0xd8f6, 0xd8f7, 
+    0xd8f8, 0xd8f9, 0xd8fa, 0xd8fb, 0xd8fc, 0xd8fd, 0xd8fe, 0xd8ff, 
+    0xd900, 0xd901, 0xd902, 0xd903, 0xd904, 0xd905, 0xd906, 0xd907, 
+    0xd908, 0xd909, 0xd90a, 0xd90b, 0xd90c, 0xd90d, 0xd90e, 0xd90f, 
+    0xd910, 0xd911, 0xd912, 0xd913, 0xd914, 0xd915, 0xd916, 0xd917, 
+    0xd918, 0xd919, 0xd91a, 0xd91b, 0xd91c, 0xd91d, 0xd91e, 0xd91f, 
+    0xd920, 0xd921, 0xd922, 0xd923, 0xd924, 0xd925, 0xd926, 0xd927, 
+    0xd928, 0xd929, 0xd92a, 0xd92b, 0xd92c, 0xd92d, 0xd92e, 0xd92f, 
+    0xd930, 0xd931, 0xd932, 0xd933, 0xd934, 0xd935, 0xd936, 0xd937, 
+    0xd938, 0xd939, 0xd93a, 0xd93b, 0xd93c, 0xd93d, 0xd93e, 0xd93f, 
+    0xd940, 0xd941, 0xd942, 0xd943, 0xd944, 0xd945, 0xd946, 0xd947, 
+    0xd948, 0xd949, 0xd94a, 0xd94b, 0xd94c, 0xd94d, 0xd94e, 0xd94f, 
+    0xd950, 0xd951, 0xd952, 0xd953, 0xd954, 0xd955, 0xd956, 0xd957, 
+    0xd958, 0xd959, 0xd95a, 0xd95b, 0xd95c, 0xd95d, 0xd95e, 0xd95f, 
+    0xd960, 0xd961, 0xd962, 0xd963, 0xd964, 0xd965, 0xd966, 0xd967, 
+    0xd968, 0xd969, 0xd96a, 0xd96b, 0xd96c, 0xd96d, 0xd96e, 0xd96f, 
+    0xd970, 0xd971, 0xd972, 0xd973, 0xd974, 0xd975, 0xd976, 0xd977, 
+    0xd978, 0xd979, 0xd97a, 0xd97b, 0xd97c, 0xd97d, 0xd97e, 0xd97f, 
+    0xd980, 0xd981, 0xd982, 0xd983, 0xd984, 0xd985, 0xd986, 0xd987, 
+    0xd988, 0xd989, 0xd98a, 0xd98b, 0xd98c, 0xd98d, 0xd98e, 0xd98f, 
+    0xd990, 0xd991, 0xd992, 0xd993, 0xd994, 0xd995, 0xd996, 0xd997, 
+    0xd998, 0xd999, 0xd99a, 0xd99b, 0xd99c, 0xd99d, 0xd99e, 0xd99f, 
+    0xd9a0, 0xd9a1, 0xd9a2, 0xd9a3, 0xd9a4, 0xd9a5, 0xd9a6, 0xd9a7, 
+    0xd9a8, 0xd9a9, 0xd9aa, 0xd9ab, 0xd9ac, 0xd9ad, 0xd9ae, 0xd9af, 
+    0xd9b0, 0xd9b1, 0xd9b2, 0xd9b3, 0xd9b4, 0xd9b5, 0xd9b6, 0xd9b7, 
+    0xd9b8, 0xd9b9, 0xd9ba, 0xd9bb, 0xd9bc, 0xd9bd, 0xd9be, 0xd9bf, 
+    0xd9c0, 0xd9c1, 0xd9c2, 0xd9c3, 0xd9c4, 0xd9c5, 0xd9c6, 0xd9c7, 
+    0xd9c8, 0xd9c9, 0xd9ca, 0xd9cb, 0xd9cc, 0xd9cd, 0xd9ce, 0xd9cf, 
+    0xd9d0, 0xd9d1, 0xd9d2, 0xd9d3, 0xd9d4, 0xd9d5, 0xd9d6, 0xd9d7, 
+    0xd9d8, 0xd9d9, 0xd9da, 0xd9db, 0xd9dc, 0xd9dd, 0xd9de, 0xd9df, 
+    0xd9e0, 0xd9e1, 0xd9e2, 0xd9e3, 0xd9e4, 0xd9e5, 0xd9e6, 0xd9e7, 
+    0xd9e8, 0xd9e9, 0xd9ea, 0xd9eb, 0xd9ec, 0xd9ed, 0xd9ee, 0xd9ef, 
+    0xd9f0, 0xd9f1, 0xd9f2, 0xd9f3, 0xd9f4, 0xd9f5, 0xd9f6, 0xd9f7, 
+    0xd9f8, 0xd9f9, 0xd9fa, 0xd9fb, 0xd9fc, 0xd9fd, 0xd9fe, 0xd9ff, 
+    0xda00, 0xda01, 0xda02, 0xda03, 0xda04, 0xda05, 0xda06, 0xda07, 
+    0xda08, 0xda09, 0xda0a, 0xda0b, 0xda0c, 0xda0d, 0xda0e, 0xda0f, 
+    0xda10, 0xda11, 0xda12, 0xda13, 0xda14, 0xda15, 0xda16, 0xda17, 
+    0xda18, 0xda19, 0xda1a, 0xda1b, 0xda1c, 0xda1d, 0xda1e, 0xda1f, 
+    0xda20, 0xda21, 0xda22, 0xda23, 0xda24, 0xda25, 0xda26, 0xda27, 
+    0xda28, 0xda29, 0xda2a, 0xda2b, 0xda2c, 0xda2d, 0xda2e, 0xda2f, 
+    0xda30, 0xda31, 0xda32, 0xda33, 0xda34, 0xda35, 0xda36, 0xda37, 
+    0xda38, 0xda39, 0xda3a, 0xda3b, 0xda3c, 0xda3d, 0xda3e, 0xda3f, 
+    0xda40, 0xda41, 0xda42, 0xda43, 0xda44, 0xda45, 0xda46, 0xda47, 
+    0xda48, 0xda49, 0xda4a, 0xda4b, 0xda4c, 0xda4d, 0xda4e, 0xda4f, 
+    0xda50, 0xda51, 0xda52, 0xda53, 0xda54, 0xda55, 0xda56, 0xda57, 
+    0xda58, 0xda59, 0xda5a, 0xda5b, 0xda5c, 0xda5d, 0xda5e, 0xda5f, 
+    0xda60, 0xda61, 0xda62, 0xda63, 0xda64, 0xda65, 0xda66, 0xda67, 
+    0xda68, 0xda69, 0xda6a, 0xda6b, 0xda6c, 0xda6d, 0xda6e, 0xda6f, 
+    0xda70, 0xda71, 0xda72, 0xda73, 0xda74, 0xda75, 0xda76, 0xda77, 
+    0xda78, 0xda79, 0xda7a, 0xda7b, 0xda7c, 0xda7d, 0xda7e, 0xda7f, 
+    0xda80, 0xda81, 0xda82, 0xda83, 0xda84, 0xda85, 0xda86, 0xda87, 
+    0xda88, 0xda89, 0xda8a, 0xda8b, 0xda8c, 0xda8d, 0xda8e, 0xda8f, 
+    0xda90, 0xda91, 0xda92, 0xda93, 0xda94, 0xda95, 0xda96, 0xda97, 
+    0xda98, 0xda99, 0xda9a, 0xda9b, 0xda9c, 0xda9d, 0xda9e, 0xda9f, 
+    0xdaa0, 0xdaa1, 0xdaa2, 0xdaa3, 0xdaa4, 0xdaa5, 0xdaa6, 0xdaa7, 
+    0xdaa8, 0xdaa9, 0xdaaa, 0xdaab, 0xdaac, 0xdaad, 0xdaae, 0xdaaf, 
+    0xdab0, 0xdab1, 0xdab2, 0xdab3, 0xdab4, 0xdab5, 0xdab6, 0xdab7, 
+    0xdab8, 0xdab9, 0xdaba, 0xdabb, 0xdabc, 0xdabd, 0xdabe, 0xdabf, 
+    0xdac0, 0xdac1, 0xdac2, 0xdac3, 0xdac4, 0xdac5, 0xdac6, 0xdac7, 
+    0xdac8, 0xdac9, 0xdaca, 0xdacb, 0xdacc, 0xdacd, 0xdace, 0xdacf, 
+    0xdad0, 0xdad1, 0xdad2, 0xdad3, 0xdad4, 0xdad5, 0xdad6, 0xdad7, 
+    0xdad8, 0xdad9, 0xdada, 0xdadb, 0xdadc, 0xdadd, 0xdade, 0xdadf, 
+    0xdae0, 0xdae1, 0xdae2, 0xdae3, 0xdae4, 0xdae5, 0xdae6, 0xdae7, 
+    0xdae8, 0xdae9, 0xdaea, 0xdaeb, 0xdaec, 0xdaed, 0xdaee, 0xdaef, 
+    0xdaf0, 0xdaf1, 0xdaf2, 0xdaf3, 0xdaf4, 0xdaf5, 0xdaf6, 0xdaf7, 
+    0xdaf8, 0xdaf9, 0xdafa, 0xdafb, 0xdafc, 0xdafd, 0xdafe, 0xdaff, 
+    0xdb00, 0xdb01, 0xdb02, 0xdb03, 0xdb04, 0xdb05, 0xdb06, 0xdb07, 
+    0xdb08, 0xdb09, 0xdb0a, 0xdb0b, 0xdb0c, 0xdb0d, 0xdb0e, 0xdb0f, 
+    0xdb10, 0xdb11, 0xdb12, 0xdb13, 0xdb14, 0xdb15, 0xdb16, 0xdb17, 
+    0xdb18, 0xdb19, 0xdb1a, 0xdb1b, 0xdb1c, 0xdb1d, 0xdb1e, 0xdb1f, 
+    0xdb20, 0xdb21, 0xdb22, 0xdb23, 0xdb24, 0xdb25, 0xdb26, 0xdb27, 
+    0xdb28, 0xdb29, 0xdb2a, 0xdb2b, 0xdb2c, 0xdb2d, 0xdb2e, 0xdb2f, 
+    0xdb30, 0xdb31, 0xdb32, 0xdb33, 0xdb34, 0xdb35, 0xdb36, 0xdb37, 
+    0xdb38, 0xdb39, 0xdb3a, 0xdb3b, 0xdb3c, 0xdb3d, 0xdb3e, 0xdb3f, 
+    0xdb40, 0xdb41, 0xdb42, 0xdb43, 0xdb44, 0xdb45, 0xdb46, 0xdb47, 
+    0xdb48, 0xdb49, 0xdb4a, 0xdb4b, 0xdb4c, 0xdb4d, 0xdb4e, 0xdb4f, 
+    0xdb50, 0xdb51, 0xdb52, 0xdb53, 0xdb54, 0xdb55, 0xdb56, 0xdb57, 
+    0xdb58, 0xdb59, 0xdb5a, 0xdb5b, 0xdb5c, 0xdb5d, 0xdb5e, 0xdb5f, 
+    0xdb60, 0xdb61, 0xdb62, 0xdb63, 0xdb64, 0xdb65, 0xdb66, 0xdb67, 
+    0xdb68, 0xdb69, 0xdb6a, 0xdb6b, 0xdb6c, 0xdb6d, 0xdb6e, 0xdb6f, 
+    0xdb70, 0xdb71, 0xdb72, 0xdb73, 0xdb74, 0xdb75, 0xdb76, 0xdb77, 
+    0xdb78, 0xdb79, 0xdb7a, 0xdb7b, 0xdb7c, 0xdb7d, 0xdb7e, 0xdb7f, 
+    0xdb80, 0xdb81, 0xdb82, 0xdb83, 0xdb84, 0xdb85, 0xdb86, 0xdb87, 
+    0xdb88, 0xdb89, 0xdb8a, 0xdb8b, 0xdb8c, 0xdb8d, 0xdb8e, 0xdb8f, 
+    0xdb90, 0xdb91, 0xdb92, 0xdb93, 0xdb94, 0xdb95, 0xdb96, 0xdb97, 
+    0xdb98, 0xdb99, 0xdb9a, 0xdb9b, 0xdb9c, 0xdb9d, 0xdb9e, 0xdb9f, 
+    0xdba0, 0xdba1, 0xdba2, 0xdba3, 0xdba4, 0xdba5, 0xdba6, 0xdba7, 
+    0xdba8, 0xdba9, 0xdbaa, 0xdbab, 0xdbac, 0xdbad, 0xdbae, 0xdbaf, 
+    0xdbb0, 0xdbb1, 0xdbb2, 0xdbb3, 0xdbb4, 0xdbb5, 0xdbb6, 0xdbb7, 
+    0xdbb8, 0xdbb9, 0xdbba, 0xdbbb, 0xdbbc, 0xdbbd, 0xdbbe, 0xdbbf, 
+    0xdbc0, 0xdbc1, 0xdbc2, 0xdbc3, 0xdbc4, 0xdbc5, 0xdbc6, 0xdbc7, 
+    0xdbc8, 0xdbc9, 0xdbca, 0xdbcb, 0xdbcc, 0xdbcd, 0xdbce, 0xdbcf, 
+    0xdbd0, 0xdbd1, 0xdbd2, 0xdbd3, 0xdbd4, 0xdbd5, 0xdbd6, 0xdbd7, 
+    0xdbd8, 0xdbd9, 0xdbda, 0xdbdb, 0xdbdc, 0xdbdd, 0xdbde, 0xdbdf, 
+    0xdbe0, 0xdbe1, 0xdbe2, 0xdbe3, 0xdbe4, 0xdbe5, 0xdbe6, 0xdbe7, 
+    0xdbe8, 0xdbe9, 0xdbea, 0xdbeb, 0xdbec, 0xdbed, 0xdbee, 0xdbef, 
+    0xdbf0, 0xdbf1, 0xdbf2, 0xdbf3, 0xdbf4, 0xdbf5, 0xdbf6, 0xdbf7, 
+    0xdbf8, 0xdbf9, 0xdbfa, 0xdbfb, 0xdbfc, 0xdbfd, 0xdbfe, 0xdbff, 
+    0xdc00, 0xdc01, 0xdc02, 0xdc03, 0xdc04, 0xdc05, 0xdc06, 0xdc07, 
+    0xdc08, 0xdc09, 0xdc0a, 0xdc0b, 0xdc0c, 0xdc0d, 0xdc0e, 0xdc0f, 
+    0xdc10, 0xdc11, 0xdc12, 0xdc13, 0xdc14, 0xdc15, 0xdc16, 0xdc17, 
+    0xdc18, 0xdc19, 0xdc1a, 0xdc1b, 0xdc1c, 0xdc1d, 0xdc1e, 0xdc1f, 
+    0xdc20, 0xdc21, 0xdc22, 0xdc23, 0xdc24, 0xdc25, 0xdc26, 0xdc27, 
+    0xdc28, 0xdc29, 0xdc2a, 0xdc2b, 0xdc2c, 0xdc2d, 0xdc2e, 0xdc2f, 
+    0xdc30, 0xdc31, 0xdc32, 0xdc33, 0xdc34, 0xdc35, 0xdc36, 0xdc37, 
+    0xdc38, 0xdc39, 0xdc3a, 0xdc3b, 0xdc3c, 0xdc3d, 0xdc3e, 0xdc3f, 
+    0xdc40, 0xdc41, 0xdc42, 0xdc43, 0xdc44, 0xdc45, 0xdc46, 0xdc47, 
+    0xdc48, 0xdc49, 0xdc4a, 0xdc4b, 0xdc4c, 0xdc4d, 0xdc4e, 0xdc4f, 
+    0xdc50, 0xdc51, 0xdc52, 0xdc53, 0xdc54, 0xdc55, 0xdc56, 0xdc57, 
+    0xdc58, 0xdc59, 0xdc5a, 0xdc5b, 0xdc5c, 0xdc5d, 0xdc5e, 0xdc5f, 
+    0xdc60, 0xdc61, 0xdc62, 0xdc63, 0xdc64, 0xdc65, 0xdc66, 0xdc67, 
+    0xdc68, 0xdc69, 0xdc6a, 0xdc6b, 0xdc6c, 0xdc6d, 0xdc6e, 0xdc6f, 
+    0xdc70, 0xdc71, 0xdc72, 0xdc73, 0xdc74, 0xdc75, 0xdc76, 0xdc77, 
+    0xdc78, 0xdc79, 0xdc7a, 0xdc7b, 0xdc7c, 0xdc7d, 0xdc7e, 0xdc7f, 
+    0xdc80, 0xdc81, 0xdc82, 0xdc83, 0xdc84, 0xdc85, 0xdc86, 0xdc87, 
+    0xdc88, 0xdc89, 0xdc8a, 0xdc8b, 0xdc8c, 0xdc8d, 0xdc8e, 0xdc8f, 
+    0xdc90, 0xdc91, 0xdc92, 0xdc93, 0xdc94, 0xdc95, 0xdc96, 0xdc97, 
+    0xdc98, 0xdc99, 0xdc9a, 0xdc9b, 0xdc9c, 0xdc9d, 0xdc9e, 0xdc9f, 
+    0xdca0, 0xdca1, 0xdca2, 0xdca3, 0xdca4, 0xdca5, 0xdca6, 0xdca7, 
+    0xdca8, 0xdca9, 0xdcaa, 0xdcab, 0xdcac, 0xdcad, 0xdcae, 0xdcaf, 
+    0xdcb0, 0xdcb1, 0xdcb2, 0xdcb3, 0xdcb4, 0xdcb5, 0xdcb6, 0xdcb7, 
+    0xdcb8, 0xdcb9, 0xdcba, 0xdcbb, 0xdcbc, 0xdcbd, 0xdcbe, 0xdcbf, 
+    0xdcc0, 0xdcc1, 0xdcc2, 0xdcc3, 0xdcc4, 0xdcc5, 0xdcc6, 0xdcc7, 
+    0xdcc8, 0xdcc9, 0xdcca, 0xdccb, 0xdccc, 0xdccd, 0xdcce, 0xdccf, 
+    0xdcd0, 0xdcd1, 0xdcd2, 0xdcd3, 0xdcd4, 0xdcd5, 0xdcd6, 0xdcd7, 
+    0xdcd8, 0xdcd9, 0xdcda, 0xdcdb, 0xdcdc, 0xdcdd, 0xdcde, 0xdcdf, 
+    0xdce0, 0xdce1, 0xdce2, 0xdce3, 0xdce4, 0xdce5, 0xdce6, 0xdce7, 
+    0xdce8, 0xdce9, 0xdcea, 0xdceb, 0xdcec, 0xdced, 0xdcee, 0xdcef, 
+    0xdcf0, 0xdcf1, 0xdcf2, 0xdcf3, 0xdcf4, 0xdcf5, 0xdcf6, 0xdcf7, 
+    0xdcf8, 0xdcf9, 0xdcfa, 0xdcfb, 0xdcfc, 0xdcfd, 0xdcfe, 0xdcff, 
+    0xdd00, 0xdd01, 0xdd02, 0xdd03, 0xdd04, 0xdd05, 0xdd06, 0xdd07, 
+    0xdd08, 0xdd09, 0xdd0a, 0xdd0b, 0xdd0c, 0xdd0d, 0xdd0e, 0xdd0f, 
+    0xdd10, 0xdd11, 0xdd12, 0xdd13, 0xdd14, 0xdd15, 0xdd16, 0xdd17, 
+    0xdd18, 0xdd19, 0xdd1a, 0xdd1b, 0xdd1c, 0xdd1d, 0xdd1e, 0xdd1f, 
+    0xdd20, 0xdd21, 0xdd22, 0xdd23, 0xdd24, 0xdd25, 0xdd26, 0xdd27, 
+    0xdd28, 0xdd29, 0xdd2a, 0xdd2b, 0xdd2c, 0xdd2d, 0xdd2e, 0xdd2f, 
+    0xdd30, 0xdd31, 0xdd32, 0xdd33, 0xdd34, 0xdd35, 0xdd36, 0xdd37, 
+    0xdd38, 0xdd39, 0xdd3a, 0xdd3b, 0xdd3c, 0xdd3d, 0xdd3e, 0xdd3f, 
+    0xdd40, 0xdd41, 0xdd42, 0xdd43, 0xdd44, 0xdd45, 0xdd46, 0xdd47, 
+    0xdd48, 0xdd49, 0xdd4a, 0xdd4b, 0xdd4c, 0xdd4d, 0xdd4e, 0xdd4f, 
+    0xdd50, 0xdd51, 0xdd52, 0xdd53, 0xdd54, 0xdd55, 0xdd56, 0xdd57, 
+    0xdd58, 0xdd59, 0xdd5a, 0xdd5b, 0xdd5c, 0xdd5d, 0xdd5e, 0xdd5f, 
+    0xdd60, 0xdd61, 0xdd62, 0xdd63, 0xdd64, 0xdd65, 0xdd66, 0xdd67, 
+    0xdd68, 0xdd69, 0xdd6a, 0xdd6b, 0xdd6c, 0xdd6d, 0xdd6e, 0xdd6f, 
+    0xdd70, 0xdd71, 0xdd72, 0xdd73, 0xdd74, 0xdd75, 0xdd76, 0xdd77, 
+    0xdd78, 0xdd79, 0xdd7a, 0xdd7b, 0xdd7c, 0xdd7d, 0xdd7e, 0xdd7f, 
+    0xdd80, 0xdd81, 0xdd82, 0xdd83, 0xdd84, 0xdd85, 0xdd86, 0xdd87, 
+    0xdd88, 0xdd89, 0xdd8a, 0xdd8b, 0xdd8c, 0xdd8d, 0xdd8e, 0xdd8f, 
+    0xdd90, 0xdd91, 0xdd92, 0xdd93, 0xdd94, 0xdd95, 0xdd96, 0xdd97, 
+    0xdd98, 0xdd99, 0xdd9a, 0xdd9b, 0xdd9c, 0xdd9d, 0xdd9e, 0xdd9f, 
+    0xdda0, 0xdda1, 0xdda2, 0xdda3, 0xdda4, 0xdda5, 0xdda6, 0xdda7, 
+    0xdda8, 0xdda9, 0xddaa, 0xddab, 0xddac, 0xddad, 0xddae, 0xddaf, 
+    0xddb0, 0xddb1, 0xddb2, 0xddb3, 0xddb4, 0xddb5, 0xddb6, 0xddb7, 
+    0xddb8, 0xddb9, 0xddba, 0xddbb, 0xddbc, 0xddbd, 0xddbe, 0xddbf, 
+    0xddc0, 0xddc1, 0xddc2, 0xddc3, 0xddc4, 0xddc5, 0xddc6, 0xddc7, 
+    0xddc8, 0xddc9, 0xddca, 0xddcb, 0xddcc, 0xddcd, 0xddce, 0xddcf, 
+    0xddd0, 0xddd1, 0xddd2, 0xddd3, 0xddd4, 0xddd5, 0xddd6, 0xddd7, 
+    0xddd8, 0xddd9, 0xddda, 0xdddb, 0xdddc, 0xdddd, 0xddde, 0xdddf, 
+    0xdde0, 0xdde1, 0xdde2, 0xdde3, 0xdde4, 0xdde5, 0xdde6, 0xdde7, 
+    0xdde8, 0xdde9, 0xddea, 0xddeb, 0xddec, 0xdded, 0xddee, 0xddef, 
+    0xddf0, 0xddf1, 0xddf2, 0xddf3, 0xddf4, 0xddf5, 0xddf6, 0xddf7, 
+    0xddf8, 0xddf9, 0xddfa, 0xddfb, 0xddfc, 0xddfd, 0xddfe, 0xddff, 
+    0xde00, 0xde01, 0xde02, 0xde03, 0xde04, 0xde05, 0xde06, 0xde07, 
+    0xde08, 0xde09, 0xde0a, 0xde0b, 0xde0c, 0xde0d, 0xde0e, 0xde0f, 
+    0xde10, 0xde11, 0xde12, 0xde13, 0xde14, 0xde15, 0xde16, 0xde17, 
+    0xde18, 0xde19, 0xde1a, 0xde1b, 0xde1c, 0xde1d, 0xde1e, 0xde1f, 
+    0xde20, 0xde21, 0xde22, 0xde23, 0xde24, 0xde25, 0xde26, 0xde27, 
+    0xde28, 0xde29, 0xde2a, 0xde2b, 0xde2c, 0xde2d, 0xde2e, 0xde2f, 
+    0xde30, 0xde31, 0xde32, 0xde33, 0xde34, 0xde35, 0xde36, 0xde37, 
+    0xde38, 0xde39, 0xde3a, 0xde3b, 0xde3c, 0xde3d, 0xde3e, 0xde3f, 
+    0xde40, 0xde41, 0xde42, 0xde43, 0xde44, 0xde45, 0xde46, 0xde47, 
+    0xde48, 0xde49, 0xde4a, 0xde4b, 0xde4c, 0xde4d, 0xde4e, 0xde4f, 
+    0xde50, 0xde51, 0xde52, 0xde53, 0xde54, 0xde55, 0xde56, 0xde57, 
+    0xde58, 0xde59, 0xde5a, 0xde5b, 0xde5c, 0xde5d, 0xde5e, 0xde5f, 
+    0xde60, 0xde61, 0xde62, 0xde63, 0xde64, 0xde65, 0xde66, 0xde67, 
+    0xde68, 0xde69, 0xde6a, 0xde6b, 0xde6c, 0xde6d, 0xde6e, 0xde6f, 
+    0xde70, 0xde71, 0xde72, 0xde73, 0xde74, 0xde75, 0xde76, 0xde77, 
+    0xde78, 0xde79, 0xde7a, 0xde7b, 0xde7c, 0xde7d, 0xde7e, 0xde7f, 
+    0xde80, 0xde81, 0xde82, 0xde83, 0xde84, 0xde85, 0xde86, 0xde87, 
+    0xde88, 0xde89, 0xde8a, 0xde8b, 0xde8c, 0xde8d, 0xde8e, 0xde8f, 
+    0xde90, 0xde91, 0xde92, 0xde93, 0xde94, 0xde95, 0xde96, 0xde97, 
+    0xde98, 0xde99, 0xde9a, 0xde9b, 0xde9c, 0xde9d, 0xde9e, 0xde9f, 
+    0xdea0, 0xdea1, 0xdea2, 0xdea3, 0xdea4, 0xdea5, 0xdea6, 0xdea7, 
+    0xdea8, 0xdea9, 0xdeaa, 0xdeab, 0xdeac, 0xdead, 0xdeae, 0xdeaf, 
+    0xdeb0, 0xdeb1, 0xdeb2, 0xdeb3, 0xdeb4, 0xdeb5, 0xdeb6, 0xdeb7, 
+    0xdeb8, 0xdeb9, 0xdeba, 0xdebb, 0xdebc, 0xdebd, 0xdebe, 0xdebf, 
+    0xdec0, 0xdec1, 0xdec2, 0xdec3, 0xdec4, 0xdec5, 0xdec6, 0xdec7, 
+    0xdec8, 0xdec9, 0xdeca, 0xdecb, 0xdecc, 0xdecd, 0xdece, 0xdecf, 
+    0xded0, 0xded1, 0xded2, 0xded3, 0xded4, 0xded5, 0xded6, 0xded7, 
+    0xded8, 0xded9, 0xdeda, 0xdedb, 0xdedc, 0xdedd, 0xdede, 0xdedf, 
+    0xdee0, 0xdee1, 0xdee2, 0xdee3, 0xdee4, 0xdee5, 0xdee6, 0xdee7, 
+    0xdee8, 0xdee9, 0xdeea, 0xdeeb, 0xdeec, 0xdeed, 0xdeee, 0xdeef, 
+    0xdef0, 0xdef1, 0xdef2, 0xdef3, 0xdef4, 0xdef5, 0xdef6, 0xdef7, 
+    0xdef8, 0xdef9, 0xdefa, 0xdefb, 0xdefc, 0xdefd, 0xdefe, 0xdeff, 
+    0xdf00, 0xdf01, 0xdf02, 0xdf03, 0xdf04, 0xdf05, 0xdf06, 0xdf07, 
+    0xdf08, 0xdf09, 0xdf0a, 0xdf0b, 0xdf0c, 0xdf0d, 0xdf0e, 0xdf0f, 
+    0xdf10, 0xdf11, 0xdf12, 0xdf13, 0xdf14, 0xdf15, 0xdf16, 0xdf17, 
+    0xdf18, 0xdf19, 0xdf1a, 0xdf1b, 0xdf1c, 0xdf1d, 0xdf1e, 0xdf1f, 
+    0xdf20, 0xdf21, 0xdf22, 0xdf23, 0xdf24, 0xdf25, 0xdf26, 0xdf27, 
+    0xdf28, 0xdf29, 0xdf2a, 0xdf2b, 0xdf2c, 0xdf2d, 0xdf2e, 0xdf2f, 
+    0xdf30, 0xdf31, 0xdf32, 0xdf33, 0xdf34, 0xdf35, 0xdf36, 0xdf37, 
+    0xdf38, 0xdf39, 0xdf3a, 0xdf3b, 0xdf3c, 0xdf3d, 0xdf3e, 0xdf3f, 
+    0xdf40, 0xdf41, 0xdf42, 0xdf43, 0xdf44, 0xdf45, 0xdf46, 0xdf47, 
+    0xdf48, 0xdf49, 0xdf4a, 0xdf4b, 0xdf4c, 0xdf4d, 0xdf4e, 0xdf4f, 
+    0xdf50, 0xdf51, 0xdf52, 0xdf53, 0xdf54, 0xdf55, 0xdf56, 0xdf57, 
+    0xdf58, 0xdf59, 0xdf5a, 0xdf5b, 0xdf5c, 0xdf5d, 0xdf5e, 0xdf5f, 
+    0xdf60, 0xdf61, 0xdf62, 0xdf63, 0xdf64, 0xdf65, 0xdf66, 0xdf67, 
+    0xdf68, 0xdf69, 0xdf6a, 0xdf6b, 0xdf6c, 0xdf6d, 0xdf6e, 0xdf6f, 
+    0xdf70, 0xdf71, 0xdf72, 0xdf73, 0xdf74, 0xdf75, 0xdf76, 0xdf77, 
+    0xdf78, 0xdf79, 0xdf7a, 0xdf7b, 0xdf7c, 0xdf7d, 0xdf7e, 0xdf7f, 
+    0xdf80, 0xdf81, 0xdf82, 0xdf83, 0xdf84, 0xdf85, 0xdf86, 0xdf87, 
+    0xdf88, 0xdf89, 0xdf8a, 0xdf8b, 0xdf8c, 0xdf8d, 0xdf8e, 0xdf8f, 
+    0xdf90, 0xdf91, 0xdf92, 0xdf93, 0xdf94, 0xdf95, 0xdf96, 0xdf97, 
+    0xdf98, 0xdf99, 0xdf9a, 0xdf9b, 0xdf9c, 0xdf9d, 0xdf9e, 0xdf9f, 
+    0xdfa0, 0xdfa1, 0xdfa2, 0xdfa3, 0xdfa4, 0xdfa5, 0xdfa6, 0xdfa7, 
+    0xdfa8, 0xdfa9, 0xdfaa, 0xdfab, 0xdfac, 0xdfad, 0xdfae, 0xdfaf, 
+    0xdfb0, 0xdfb1, 0xdfb2, 0xdfb3, 0xdfb4, 0xdfb5, 0xdfb6, 0xdfb7, 
+    0xdfb8, 0xdfb9, 0xdfba, 0xdfbb, 0xdfbc, 0xdfbd, 0xdfbe, 0xdfbf, 
+    0xdfc0, 0xdfc1, 0xdfc2, 0xdfc3, 0xdfc4, 0xdfc5, 0xdfc6, 0xdfc7, 
+    0xdfc8, 0xdfc9, 0xdfca, 0xdfcb, 0xdfcc, 0xdfcd, 0xdfce, 0xdfcf, 
+    0xdfd0, 0xdfd1, 0xdfd2, 0xdfd3, 0xdfd4, 0xdfd5, 0xdfd6, 0xdfd7, 
+    0xdfd8, 0xdfd9, 0xdfda, 0xdfdb, 0xdfdc, 0xdfdd, 0xdfde, 0xdfdf, 
+    0xdfe0, 0xdfe1, 0xdfe2, 0xdfe3, 0xdfe4, 0xdfe5, 0xdfe6, 0xdfe7, 
+    0xdfe8, 0xdfe9, 0xdfea, 0xdfeb, 0xdfec, 0xdfed, 0xdfee, 0xdfef, 
+    0xdff0, 0xdff1, 0xdff2, 0xdff3, 0xdff4, 0xdff5, 0xdff6, 0xdff7, 
+    0xdff8, 0xdff9, 0xdffa, 0xdffb, 0xdffc, 0xdffd, 0xdffe, 0xdfff, 
+    0xe000, 0xe001, 0xe002, 0xe003, 0xe004, 0xe005, 0xe006, 0xe007, 
+    0xe008, 0xe009, 0xe00a, 0xe00b, 0xe00c, 0xe00d, 0xe00e, 0xe00f, 
+    0xe010, 0xe011, 0xe012, 0xe013, 0xe014, 0xe015, 0xe016, 0xe017, 
+    0xe018, 0xe019, 0xe01a, 0xe01b, 0xe01c, 0xe01d, 0xe01e, 0xe01f, 
+    0xe020, 0xe021, 0xe022, 0xe023, 0xe024, 0xe025, 0xe026, 0xe027, 
+    0xe028, 0xe029, 0xe02a, 0xe02b, 0xe02c, 0xe02d, 0xe02e, 0xe02f, 
+    0xe030, 0xe031, 0xe032, 0xe033, 0xe034, 0xe035, 0xe036, 0xe037, 
+    0xe038, 0xe039, 0xe03a, 0xe03b, 0xe03c, 0xe03d, 0xe03e, 0xe03f, 
+    0xe040, 0xe041, 0xe042, 0xe043, 0xe044, 0xe045, 0xe046, 0xe047, 
+    0xe048, 0xe049, 0xe04a, 0xe04b, 0xe04c, 0xe04d, 0xe04e, 0xe04f, 
+    0xe050, 0xe051, 0xe052, 0xe053, 0xe054, 0xe055, 0xe056, 0xe057, 
+    0xe058, 0xe059, 0xe05a, 0xe05b, 0xe05c, 0xe05d, 0xe05e, 0xe05f, 
+    0xe060, 0xe061, 0xe062, 0xe063, 0xe064, 0xe065, 0xe066, 0xe067, 
+    0xe068, 0xe069, 0xe06a, 0xe06b, 0xe06c, 0xe06d, 0xe06e, 0xe06f, 
+    0xe070, 0xe071, 0xe072, 0xe073, 0xe074, 0xe075, 0xe076, 0xe077, 
+    0xe078, 0xe079, 0xe07a, 0xe07b, 0xe07c, 0xe07d, 0xe07e, 0xe07f, 
+    0xe080, 0xe081, 0xe082, 0xe083, 0xe084, 0xe085, 0xe086, 0xe087, 
+    0xe088, 0xe089, 0xe08a, 0xe08b, 0xe08c, 0xe08d, 0xe08e, 0xe08f, 
+    0xe090, 0xe091, 0xe092, 0xe093, 0xe094, 0xe095, 0xe096, 0xe097, 
+    0xe098, 0xe099, 0xe09a, 0xe09b, 0xe09c, 0xe09d, 0xe09e, 0xe09f, 
+    0xe0a0, 0xe0a1, 0xe0a2, 0xe0a3, 0xe0a4, 0xe0a5, 0xe0a6, 0xe0a7, 
+    0xe0a8, 0xe0a9, 0xe0aa, 0xe0ab, 0xe0ac, 0xe0ad, 0xe0ae, 0xe0af, 
+    0xe0b0, 0xe0b1, 0xe0b2, 0xe0b3, 0xe0b4, 0xe0b5, 0xe0b6, 0xe0b7, 
+    0xe0b8, 0xe0b9, 0xe0ba, 0xe0bb, 0xe0bc, 0xe0bd, 0xe0be, 0xe0bf, 
+    0xe0c0, 0xe0c1, 0xe0c2, 0xe0c3, 0xe0c4, 0xe0c5, 0xe0c6, 0xe0c7, 
+    0xe0c8, 0xe0c9, 0xe0ca, 0xe0cb, 0xe0cc, 0xe0cd, 0xe0ce, 0xe0cf, 
+    0xe0d0, 0xe0d1, 0xe0d2, 0xe0d3, 0xe0d4, 0xe0d5, 0xe0d6, 0xe0d7, 
+    0xe0d8, 0xe0d9, 0xe0da, 0xe0db, 0xe0dc, 0xe0dd, 0xe0de, 0xe0df, 
+    0xe0e0, 0xe0e1, 0xe0e2, 0xe0e3, 0xe0e4, 0xe0e5, 0xe0e6, 0xe0e7, 
+    0xe0e8, 0xe0e9, 0xe0ea, 0xe0eb, 0xe0ec, 0xe0ed, 0xe0ee, 0xe0ef, 
+    0xe0f0, 0xe0f1, 0xe0f2, 0xe0f3, 0xe0f4, 0xe0f5, 0xe0f6, 0xe0f7, 
+    0xe0f8, 0xe0f9, 0xe0fa, 0xe0fb, 0xe0fc, 0xe0fd, 0xe0fe, 0xe0ff, 
+    0xe100, 0xe101, 0xe102, 0xe103, 0xe104, 0xe105, 0xe106, 0xe107, 
+    0xe108, 0xe109, 0xe10a, 0xe10b, 0xe10c, 0xe10d, 0xe10e, 0xe10f, 
+    0xe110, 0xe111, 0xe112, 0xe113, 0xe114, 0xe115, 0xe116, 0xe117, 
+    0xe118, 0xe119, 0xe11a, 0xe11b, 0xe11c, 0xe11d, 0xe11e, 0xe11f, 
+    0xe120, 0xe121, 0xe122, 0xe123, 0xe124, 0xe125, 0xe126, 0xe127, 
+    0xe128, 0xe129, 0xe12a, 0xe12b, 0xe12c, 0xe12d, 0xe12e, 0xe12f, 
+    0xe130, 0xe131, 0xe132, 0xe133, 0xe134, 0xe135, 0xe136, 0xe137, 
+    0xe138, 0xe139, 0xe13a, 0xe13b, 0xe13c, 0xe13d, 0xe13e, 0xe13f, 
+    0xe140, 0xe141, 0xe142, 0xe143, 0xe144, 0xe145, 0xe146, 0xe147, 
+    0xe148, 0xe149, 0xe14a, 0xe14b, 0xe14c, 0xe14d, 0xe14e, 0xe14f, 
+    0xe150, 0xe151, 0xe152, 0xe153, 0xe154, 0xe155, 0xe156, 0xe157, 
+    0xe158, 0xe159, 0xe15a, 0xe15b, 0xe15c, 0xe15d, 0xe15e, 0xe15f, 
+    0xe160, 0xe161, 0xe162, 0xe163, 0xe164, 0xe165, 0xe166, 0xe167, 
+    0xe168, 0xe169, 0xe16a, 0xe16b, 0xe16c, 0xe16d, 0xe16e, 0xe16f, 
+    0xe170, 0xe171, 0xe172, 0xe173, 0xe174, 0xe175, 0xe176, 0xe177, 
+    0xe178, 0xe179, 0xe17a, 0xe17b, 0xe17c, 0xe17d, 0xe17e, 0xe17f, 
+    0xe180, 0xe181, 0xe182, 0xe183, 0xe184, 0xe185, 0xe186, 0xe187, 
+    0xe188, 0xe189, 0xe18a, 0xe18b, 0xe18c, 0xe18d, 0xe18e, 0xe18f, 
+    0xe190, 0xe191, 0xe192, 0xe193, 0xe194, 0xe195, 0xe196, 0xe197, 
+    0xe198, 0xe199, 0xe19a, 0xe19b, 0xe19c, 0xe19d, 0xe19e, 0xe19f, 
+    0xe1a0, 0xe1a1, 0xe1a2, 0xe1a3, 0xe1a4, 0xe1a5, 0xe1a6, 0xe1a7, 
+    0xe1a8, 0xe1a9, 0xe1aa, 0xe1ab, 0xe1ac, 0xe1ad, 0xe1ae, 0xe1af, 
+    0xe1b0, 0xe1b1, 0xe1b2, 0xe1b3, 0xe1b4, 0xe1b5, 0xe1b6, 0xe1b7, 
+    0xe1b8, 0xe1b9, 0xe1ba, 0xe1bb, 0xe1bc, 0xe1bd, 0xe1be, 0xe1bf, 
+    0xe1c0, 0xe1c1, 0xe1c2, 0xe1c3, 0xe1c4, 0xe1c5, 0xe1c6, 0xe1c7, 
+    0xe1c8, 0xe1c9, 0xe1ca, 0xe1cb, 0xe1cc, 0xe1cd, 0xe1ce, 0xe1cf, 
+    0xe1d0, 0xe1d1, 0xe1d2, 0xe1d3, 0xe1d4, 0xe1d5, 0xe1d6, 0xe1d7, 
+    0xe1d8, 0xe1d9, 0xe1da, 0xe1db, 0xe1dc, 0xe1dd, 0xe1de, 0xe1df, 
+    0xe1e0, 0xe1e1, 0xe1e2, 0xe1e3, 0xe1e4, 0xe1e5, 0xe1e6, 0xe1e7, 
+    0xe1e8, 0xe1e9, 0xe1ea, 0xe1eb, 0xe1ec, 0xe1ed, 0xe1ee, 0xe1ef, 
+    0xe1f0, 0xe1f1, 0xe1f2, 0xe1f3, 0xe1f4, 0xe1f5, 0xe1f6, 0xe1f7, 
+    0xe1f8, 0xe1f9, 0xe1fa, 0xe1fb, 0xe1fc, 0xe1fd, 0xe1fe, 0xe1ff, 
+    0xe200, 0xe201, 0xe202, 0xe203, 0xe204, 0xe205, 0xe206, 0xe207, 
+    0xe208, 0xe209, 0xe20a, 0xe20b, 0xe20c, 0xe20d, 0xe20e, 0xe20f, 
+    0xe210, 0xe211, 0xe212, 0xe213, 0xe214, 0xe215, 0xe216, 0xe217, 
+    0xe218, 0xe219, 0xe21a, 0xe21b, 0xe21c, 0xe21d, 0xe21e, 0xe21f, 
+    0xe220, 0xe221, 0xe222, 0xe223, 0xe224, 0xe225, 0xe226, 0xe227, 
+    0xe228, 0xe229, 0xe22a, 0xe22b, 0xe22c, 0xe22d, 0xe22e, 0xe22f, 
+    0xe230, 0xe231, 0xe232, 0xe233, 0xe234, 0xe235, 0xe236, 0xe237, 
+    0xe238, 0xe239, 0xe23a, 0xe23b, 0xe23c, 0xe23d, 0xe23e, 0xe23f, 
+    0xe240, 0xe241, 0xe242, 0xe243, 0xe244, 0xe245, 0xe246, 0xe247, 
+    0xe248, 0xe249, 0xe24a, 0xe24b, 0xe24c, 0xe24d, 0xe24e, 0xe24f, 
+    0xe250, 0xe251, 0xe252, 0xe253, 0xe254, 0xe255, 0xe256, 0xe257, 
+    0xe258, 0xe259, 0xe25a, 0xe25b, 0xe25c, 0xe25d, 0xe25e, 0xe25f, 
+    0xe260, 0xe261, 0xe262, 0xe263, 0xe264, 0xe265, 0xe266, 0xe267, 
+    0xe268, 0xe269, 0xe26a, 0xe26b, 0xe26c, 0xe26d, 0xe26e, 0xe26f, 
+    0xe270, 0xe271, 0xe272, 0xe273, 0xe274, 0xe275, 0xe276, 0xe277, 
+    0xe278, 0xe279, 0xe27a, 0xe27b, 0xe27c, 0xe27d, 0xe27e, 0xe27f, 
+    0xe280, 0xe281, 0xe282, 0xe283, 0xe284, 0xe285, 0xe286, 0xe287, 
+    0xe288, 0xe289, 0xe28a, 0xe28b, 0xe28c, 0xe28d, 0xe28e, 0xe28f, 
+    0xe290, 0xe291, 0xe292, 0xe293, 0xe294, 0xe295, 0xe296, 0xe297, 
+    0xe298, 0xe299, 0xe29a, 0xe29b, 0xe29c, 0xe29d, 0xe29e, 0xe29f, 
+    0xe2a0, 0xe2a1, 0xe2a2, 0xe2a3, 0xe2a4, 0xe2a5, 0xe2a6, 0xe2a7, 
+    0xe2a8, 0xe2a9, 0xe2aa, 0xe2ab, 0xe2ac, 0xe2ad, 0xe2ae, 0xe2af, 
+    0xe2b0, 0xe2b1, 0xe2b2, 0xe2b3, 0xe2b4, 0xe2b5, 0xe2b6, 0xe2b7, 
+    0xe2b8, 0xe2b9, 0xe2ba, 0xe2bb, 0xe2bc, 0xe2bd, 0xe2be, 0xe2bf, 
+    0xe2c0, 0xe2c1, 0xe2c2, 0xe2c3, 0xe2c4, 0xe2c5, 0xe2c6, 0xe2c7, 
+    0xe2c8, 0xe2c9, 0xe2ca, 0xe2cb, 0xe2cc, 0xe2cd, 0xe2ce, 0xe2cf, 
+    0xe2d0, 0xe2d1, 0xe2d2, 0xe2d3, 0xe2d4, 0xe2d5, 0xe2d6, 0xe2d7, 
+    0xe2d8, 0xe2d9, 0xe2da, 0xe2db, 0xe2dc, 0xe2dd, 0xe2de, 0xe2df, 
+    0xe2e0, 0xe2e1, 0xe2e2, 0xe2e3, 0xe2e4, 0xe2e5, 0xe2e6, 0xe2e7, 
+    0xe2e8, 0xe2e9, 0xe2ea, 0xe2eb, 0xe2ec, 0xe2ed, 0xe2ee, 0xe2ef, 
+    0xe2f0, 0xe2f1, 0xe2f2, 0xe2f3, 0xe2f4, 0xe2f5, 0xe2f6, 0xe2f7, 
+    0xe2f8, 0xe2f9, 0xe2fa, 0xe2fb, 0xe2fc, 0xe2fd, 0xe2fe, 0xe2ff, 
+    0xe300, 0xe301, 0xe302, 0xe303, 0xe304, 0xe305, 0xe306, 0xe307, 
+    0xe308, 0xe309, 0xe30a, 0xe30b, 0xe30c, 0xe30d, 0xe30e, 0xe30f, 
+    0xe310, 0xe311, 0xe312, 0xe313, 0xe314, 0xe315, 0xe316, 0xe317, 
+    0xe318, 0xe319, 0xe31a, 0xe31b, 0xe31c, 0xe31d, 0xe31e, 0xe31f, 
+    0xe320, 0xe321, 0xe322, 0xe323, 0xe324, 0xe325, 0xe326, 0xe327, 
+    0xe328, 0xe329, 0xe32a, 0xe32b, 0xe32c, 0xe32d, 0xe32e, 0xe32f, 
+    0xe330, 0xe331, 0xe332, 0xe333, 0xe334, 0xe335, 0xe336, 0xe337, 
+    0xe338, 0xe339, 0xe33a, 0xe33b, 0xe33c, 0xe33d, 0xe33e, 0xe33f, 
+    0xe340, 0xe341, 0xe342, 0xe343, 0xe344, 0xe345, 0xe346, 0xe347, 
+    0xe348, 0xe349, 0xe34a, 0xe34b, 0xe34c, 0xe34d, 0xe34e, 0xe34f, 
+    0xe350, 0xe351, 0xe352, 0xe353, 0xe354, 0xe355, 0xe356, 0xe357, 
+    0xe358, 0xe359, 0xe35a, 0xe35b, 0xe35c, 0xe35d, 0xe35e, 0xe35f, 
+    0xe360, 0xe361, 0xe362, 0xe363, 0xe364, 0xe365, 0xe366, 0xe367, 
+    0xe368, 0xe369, 0xe36a, 0xe36b, 0xe36c, 0xe36d, 0xe36e, 0xe36f, 
+    0xe370, 0xe371, 0xe372, 0xe373, 0xe374, 0xe375, 0xe376, 0xe377, 
+    0xe378, 0xe379, 0xe37a, 0xe37b, 0xe37c, 0xe37d, 0xe37e, 0xe37f, 
+    0xe380, 0xe381, 0xe382, 0xe383, 0xe384, 0xe385, 0xe386, 0xe387, 
+    0xe388, 0xe389, 0xe38a, 0xe38b, 0xe38c, 0xe38d, 0xe38e, 0xe38f, 
+    0xe390, 0xe391, 0xe392, 0xe393, 0xe394, 0xe395, 0xe396, 0xe397, 
+    0xe398, 0xe399, 0xe39a, 0xe39b, 0xe39c, 0xe39d, 0xe39e, 0xe39f, 
+    0xe3a0, 0xe3a1, 0xe3a2, 0xe3a3, 0xe3a4, 0xe3a5, 0xe3a6, 0xe3a7, 
+    0xe3a8, 0xe3a9, 0xe3aa, 0xe3ab, 0xe3ac, 0xe3ad, 0xe3ae, 0xe3af, 
+    0xe3b0, 0xe3b1, 0xe3b2, 0xe3b3, 0xe3b4, 0xe3b5, 0xe3b6, 0xe3b7, 
+    0xe3b8, 0xe3b9, 0xe3ba, 0xe3bb, 0xe3bc, 0xe3bd, 0xe3be, 0xe3bf, 
+    0xe3c0, 0xe3c1, 0xe3c2, 0xe3c3, 0xe3c4, 0xe3c5, 0xe3c6, 0xe3c7, 
+    0xe3c8, 0xe3c9, 0xe3ca, 0xe3cb, 0xe3cc, 0xe3cd, 0xe3ce, 0xe3cf, 
+    0xe3d0, 0xe3d1, 0xe3d2, 0xe3d3, 0xe3d4, 0xe3d5, 0xe3d6, 0xe3d7, 
+    0xe3d8, 0xe3d9, 0xe3da, 0xe3db, 0xe3dc, 0xe3dd, 0xe3de, 0xe3df, 
+    0xe3e0, 0xe3e1, 0xe3e2, 0xe3e3, 0xe3e4, 0xe3e5, 0xe3e6, 0xe3e7, 
+    0xe3e8, 0xe3e9, 0xe3ea, 0xe3eb, 0xe3ec, 0xe3ed, 0xe3ee, 0xe3ef, 
+    0xe3f0, 0xe3f1, 0xe3f2, 0xe3f3, 0xe3f4, 0xe3f5, 0xe3f6, 0xe3f7, 
+    0xe3f8, 0xe3f9, 0xe3fa, 0xe3fb, 0xe3fc, 0xe3fd, 0xe3fe, 0xe3ff, 
+    0xe400, 0xe401, 0xe402, 0xe403, 0xe404, 0xe405, 0xe406, 0xe407, 
+    0xe408, 0xe409, 0xe40a, 0xe40b, 0xe40c, 0xe40d, 0xe40e, 0xe40f, 
+    0xe410, 0xe411, 0xe412, 0xe413, 0xe414, 0xe415, 0xe416, 0xe417, 
+    0xe418, 0xe419, 0xe41a, 0xe41b, 0xe41c, 0xe41d, 0xe41e, 0xe41f, 
+    0xe420, 0xe421, 0xe422, 0xe423, 0xe424, 0xe425, 0xe426, 0xe427, 
+    0xe428, 0xe429, 0xe42a, 0xe42b, 0xe42c, 0xe42d, 0xe42e, 0xe42f, 
+    0xe430, 0xe431, 0xe432, 0xe433, 0xe434, 0xe435, 0xe436, 0xe437, 
+    0xe438, 0xe439, 0xe43a, 0xe43b, 0xe43c, 0xe43d, 0xe43e, 0xe43f, 
+    0xe440, 0xe441, 0xe442, 0xe443, 0xe444, 0xe445, 0xe446, 0xe447, 
+    0xe448, 0xe449, 0xe44a, 0xe44b, 0xe44c, 0xe44d, 0xe44e, 0xe44f, 
+    0xe450, 0xe451, 0xe452, 0xe453, 0xe454, 0xe455, 0xe456, 0xe457, 
+    0xe458, 0xe459, 0xe45a, 0xe45b, 0xe45c, 0xe45d, 0xe45e, 0xe45f, 
+    0xe460, 0xe461, 0xe462, 0xe463, 0xe464, 0xe465, 0xe466, 0xe467, 
+    0xe468, 0xe469, 0xe46a, 0xe46b, 0xe46c, 0xe46d, 0xe46e, 0xe46f, 
+    0xe470, 0xe471, 0xe472, 0xe473, 0xe474, 0xe475, 0xe476, 0xe477, 
+    0xe478, 0xe479, 0xe47a, 0xe47b, 0xe47c, 0xe47d, 0xe47e, 0xe47f, 
+    0xe480, 0xe481, 0xe482, 0xe483, 0xe484, 0xe485, 0xe486, 0xe487, 
+    0xe488, 0xe489, 0xe48a, 0xe48b, 0xe48c, 0xe48d, 0xe48e, 0xe48f, 
+    0xe490, 0xe491, 0xe492, 0xe493, 0xe494, 0xe495, 0xe496, 0xe497, 
+    0xe498, 0xe499, 0xe49a, 0xe49b, 0xe49c, 0xe49d, 0xe49e, 0xe49f, 
+    0xe4a0, 0xe4a1, 0xe4a2, 0xe4a3, 0xe4a4, 0xe4a5, 0xe4a6, 0xe4a7, 
+    0xe4a8, 0xe4a9, 0xe4aa, 0xe4ab, 0xe4ac, 0xe4ad, 0xe4ae, 0xe4af, 
+    0xe4b0, 0xe4b1, 0xe4b2, 0xe4b3, 0xe4b4, 0xe4b5, 0xe4b6, 0xe4b7, 
+    0xe4b8, 0xe4b9, 0xe4ba, 0xe4bb, 0xe4bc, 0xe4bd, 0xe4be, 0xe4bf, 
+    0xe4c0, 0xe4c1, 0xe4c2, 0xe4c3, 0xe4c4, 0xe4c5, 0xe4c6, 0xe4c7, 
+    0xe4c8, 0xe4c9, 0xe4ca, 0xe4cb, 0xe4cc, 0xe4cd, 0xe4ce, 0xe4cf, 
+    0xe4d0, 0xe4d1, 0xe4d2, 0xe4d3, 0xe4d4, 0xe4d5, 0xe4d6, 0xe4d7, 
+    0xe4d8, 0xe4d9, 0xe4da, 0xe4db, 0xe4dc, 0xe4dd, 0xe4de, 0xe4df, 
+    0xe4e0, 0xe4e1, 0xe4e2, 0xe4e3, 0xe4e4, 0xe4e5, 0xe4e6, 0xe4e7, 
+    0xe4e8, 0xe4e9, 0xe4ea, 0xe4eb, 0xe4ec, 0xe4ed, 0xe4ee, 0xe4ef, 
+    0xe4f0, 0xe4f1, 0xe4f2, 0xe4f3, 0xe4f4, 0xe4f5, 0xe4f6, 0xe4f7, 
+    0xe4f8, 0xe4f9, 0xe4fa, 0xe4fb, 0xe4fc, 0xe4fd, 0xe4fe, 0xe4ff, 
+    0xe500, 0xe501, 0xe502, 0xe503, 0xe504, 0xe505, 0xe506, 0xe507, 
+    0xe508, 0xe509, 0xe50a, 0xe50b, 0xe50c, 0xe50d, 0xe50e, 0xe50f, 
+    0xe510, 0xe511, 0xe512, 0xe513, 0xe514, 0xe515, 0xe516, 0xe517, 
+    0xe518, 0xe519, 0xe51a, 0xe51b, 0xe51c, 0xe51d, 0xe51e, 0xe51f, 
+    0xe520, 0xe521, 0xe522, 0xe523, 0xe524, 0xe525, 0xe526, 0xe527, 
+    0xe528, 0xe529, 0xe52a, 0xe52b, 0xe52c, 0xe52d, 0xe52e, 0xe52f, 
+    0xe530, 0xe531, 0xe532, 0xe533, 0xe534, 0xe535, 0xe536, 0xe537, 
+    0xe538, 0xe539, 0xe53a, 0xe53b, 0xe53c, 0xe53d, 0xe53e, 0xe53f, 
+    0xe540, 0xe541, 0xe542, 0xe543, 0xe544, 0xe545, 0xe546, 0xe547, 
+    0xe548, 0xe549, 0xe54a, 0xe54b, 0xe54c, 0xe54d, 0xe54e, 0xe54f, 
+    0xe550, 0xe551, 0xe552, 0xe553, 0xe554, 0xe555, 0xe556, 0xe557, 
+    0xe558, 0xe559, 0xe55a, 0xe55b, 0xe55c, 0xe55d, 0xe55e, 0xe55f, 
+    0xe560, 0xe561, 0xe562, 0xe563, 0xe564, 0xe565, 0xe566, 0xe567, 
+    0xe568, 0xe569, 0xe56a, 0xe56b, 0xe56c, 0xe56d, 0xe56e, 0xe56f, 
+    0xe570, 0xe571, 0xe572, 0xe573, 0xe574, 0xe575, 0xe576, 0xe577, 
+    0xe578, 0xe579, 0xe57a, 0xe57b, 0xe57c, 0xe57d, 0xe57e, 0xe57f, 
+    0xe580, 0xe581, 0xe582, 0xe583, 0xe584, 0xe585, 0xe586, 0xe587, 
+    0xe588, 0xe589, 0xe58a, 0xe58b, 0xe58c, 0xe58d, 0xe58e, 0xe58f, 
+    0xe590, 0xe591, 0xe592, 0xe593, 0xe594, 0xe595, 0xe596, 0xe597, 
+    0xe598, 0xe599, 0xe59a, 0xe59b, 0xe59c, 0xe59d, 0xe59e, 0xe59f, 
+    0xe5a0, 0xe5a1, 0xe5a2, 0xe5a3, 0xe5a4, 0xe5a5, 0xe5a6, 0xe5a7, 
+    0xe5a8, 0xe5a9, 0xe5aa, 0xe5ab, 0xe5ac, 0xe5ad, 0xe5ae, 0xe5af, 
+    0xe5b0, 0xe5b1, 0xe5b2, 0xe5b3, 0xe5b4, 0xe5b5, 0xe5b6, 0xe5b7, 
+    0xe5b8, 0xe5b9, 0xe5ba, 0xe5bb, 0xe5bc, 0xe5bd, 0xe5be, 0xe5bf, 
+    0xe5c0, 0xe5c1, 0xe5c2, 0xe5c3, 0xe5c4, 0xe5c5, 0xe5c6, 0xe5c7, 
+    0xe5c8, 0xe5c9, 0xe5ca, 0xe5cb, 0xe5cc, 0xe5cd, 0xe5ce, 0xe5cf, 
+    0xe5d0, 0xe5d1, 0xe5d2, 0xe5d3, 0xe5d4, 0xe5d5, 0xe5d6, 0xe5d7, 
+    0xe5d8, 0xe5d9, 0xe5da, 0xe5db, 0xe5dc, 0xe5dd, 0xe5de, 0xe5df, 
+    0xe5e0, 0xe5e1, 0xe5e2, 0xe5e3, 0xe5e4, 0xe5e5, 0xe5e6, 0xe5e7, 
+    0xe5e8, 0xe5e9, 0xe5ea, 0xe5eb, 0xe5ec, 0xe5ed, 0xe5ee, 0xe5ef, 
+    0xe5f0, 0xe5f1, 0xe5f2, 0xe5f3, 0xe5f4, 0xe5f5, 0xe5f6, 0xe5f7, 
+    0xe5f8, 0xe5f9, 0xe5fa, 0xe5fb, 0xe5fc, 0xe5fd, 0xe5fe, 0xe5ff, 
+    0xe600, 0xe601, 0xe602, 0xe603, 0xe604, 0xe605, 0xe606, 0xe607, 
+    0xe608, 0xe609, 0xe60a, 0xe60b, 0xe60c, 0xe60d, 0xe60e, 0xe60f, 
+    0xe610, 0xe611, 0xe612, 0xe613, 0xe614, 0xe615, 0xe616, 0xe617, 
+    0xe618, 0xe619, 0xe61a, 0xe61b, 0xe61c, 0xe61d, 0xe61e, 0xe61f, 
+    0xe620, 0xe621, 0xe622, 0xe623, 0xe624, 0xe625, 0xe626, 0xe627, 
+    0xe628, 0xe629, 0xe62a, 0xe62b, 0xe62c, 0xe62d, 0xe62e, 0xe62f, 
+    0xe630, 0xe631, 0xe632, 0xe633, 0xe634, 0xe635, 0xe636, 0xe637, 
+    0xe638, 0xe639, 0xe63a, 0xe63b, 0xe63c, 0xe63d, 0xe63e, 0xe63f, 
+    0xe640, 0xe641, 0xe642, 0xe643, 0xe644, 0xe645, 0xe646, 0xe647, 
+    0xe648, 0xe649, 0xe64a, 0xe64b, 0xe64c, 0xe64d, 0xe64e, 0xe64f, 
+    0xe650, 0xe651, 0xe652, 0xe653, 0xe654, 0xe655, 0xe656, 0xe657, 
+    0xe658, 0xe659, 0xe65a, 0xe65b, 0xe65c, 0xe65d, 0xe65e, 0xe65f, 
+    0xe660, 0xe661, 0xe662, 0xe663, 0xe664, 0xe665, 0xe666, 0xe667, 
+    0xe668, 0xe669, 0xe66a, 0xe66b, 0xe66c, 0xe66d, 0xe66e, 0xe66f, 
+    0xe670, 0xe671, 0xe672, 0xe673, 0xe674, 0xe675, 0xe676, 0xe677, 
+    0xe678, 0xe679, 0xe67a, 0xe67b, 0xe67c, 0xe67d, 0xe67e, 0xe67f, 
+    0xe680, 0xe681, 0xe682, 0xe683, 0xe684, 0xe685, 0xe686, 0xe687, 
+    0xe688, 0xe689, 0xe68a, 0xe68b, 0xe68c, 0xe68d, 0xe68e, 0xe68f, 
+    0xe690, 0xe691, 0xe692, 0xe693, 0xe694, 0xe695, 0xe696, 0xe697, 
+    0xe698, 0xe699, 0xe69a, 0xe69b, 0xe69c, 0xe69d, 0xe69e, 0xe69f, 
+    0xe6a0, 0xe6a1, 0xe6a2, 0xe6a3, 0xe6a4, 0xe6a5, 0xe6a6, 0xe6a7, 
+    0xe6a8, 0xe6a9, 0xe6aa, 0xe6ab, 0xe6ac, 0xe6ad, 0xe6ae, 0xe6af, 
+    0xe6b0, 0xe6b1, 0xe6b2, 0xe6b3, 0xe6b4, 0xe6b5, 0xe6b6, 0xe6b7, 
+    0xe6b8, 0xe6b9, 0xe6ba, 0xe6bb, 0xe6bc, 0xe6bd, 0xe6be, 0xe6bf, 
+    0xe6c0, 0xe6c1, 0xe6c2, 0xe6c3, 0xe6c4, 0xe6c5, 0xe6c6, 0xe6c7, 
+    0xe6c8, 0xe6c9, 0xe6ca, 0xe6cb, 0xe6cc, 0xe6cd, 0xe6ce, 0xe6cf, 
+    0xe6d0, 0xe6d1, 0xe6d2, 0xe6d3, 0xe6d4, 0xe6d5, 0xe6d6, 0xe6d7, 
+    0xe6d8, 0xe6d9, 0xe6da, 0xe6db, 0xe6dc, 0xe6dd, 0xe6de, 0xe6df, 
+    0xe6e0, 0xe6e1, 0xe6e2, 0xe6e3, 0xe6e4, 0xe6e5, 0xe6e6, 0xe6e7, 
+    0xe6e8, 0xe6e9, 0xe6ea, 0xe6eb, 0xe6ec, 0xe6ed, 0xe6ee, 0xe6ef, 
+    0xe6f0, 0xe6f1, 0xe6f2, 0xe6f3, 0xe6f4, 0xe6f5, 0xe6f6, 0xe6f7, 
+    0xe6f8, 0xe6f9, 0xe6fa, 0xe6fb, 0xe6fc, 0xe6fd, 0xe6fe, 0xe6ff, 
+    0xe700, 0xe701, 0xe702, 0xe703, 0xe704, 0xe705, 0xe706, 0xe707, 
+    0xe708, 0xe709, 0xe70a, 0xe70b, 0xe70c, 0xe70d, 0xe70e, 0xe70f, 
+    0xe710, 0xe711, 0xe712, 0xe713, 0xe714, 0xe715, 0xe716, 0xe717, 
+    0xe718, 0xe719, 0xe71a, 0xe71b, 0xe71c, 0xe71d, 0xe71e, 0xe71f, 
+    0xe720, 0xe721, 0xe722, 0xe723, 0xe724, 0xe725, 0xe726, 0xe727, 
+    0xe728, 0xe729, 0xe72a, 0xe72b, 0xe72c, 0xe72d, 0xe72e, 0xe72f, 
+    0xe730, 0xe731, 0xe732, 0xe733, 0xe734, 0xe735, 0xe736, 0xe737, 
+    0xe738, 0xe739, 0xe73a, 0xe73b, 0xe73c, 0xe73d, 0xe73e, 0xe73f, 
+    0xe740, 0xe741, 0xe742, 0xe743, 0xe744, 0xe745, 0xe746, 0xe747, 
+    0xe748, 0xe749, 0xe74a, 0xe74b, 0xe74c, 0xe74d, 0xe74e, 0xe74f, 
+    0xe750, 0xe751, 0xe752, 0xe753, 0xe754, 0xe755, 0xe756, 0xe757, 
+    0xe758, 0xe759, 0xe75a, 0xe75b, 0xe75c, 0xe75d, 0xe75e, 0xe75f, 
+    0xe760, 0xe761, 0xe762, 0xe763, 0xe764, 0xe765, 0xe766, 0xe767, 
+    0xe768, 0xe769, 0xe76a, 0xe76b, 0xe76c, 0xe76d, 0xe76e, 0xe76f, 
+    0xe770, 0xe771, 0xe772, 0xe773, 0xe774, 0xe775, 0xe776, 0xe777, 
+    0xe778, 0xe779, 0xe77a, 0xe77b, 0xe77c, 0xe77d, 0xe77e, 0xe77f, 
+    0xe780, 0xe781, 0xe782, 0xe783, 0xe784, 0xe785, 0xe786, 0xe787, 
+    0xe788, 0xe789, 0xe78a, 0xe78b, 0xe78c, 0xe78d, 0xe78e, 0xe78f, 
+    0xe790, 0xe791, 0xe792, 0xe793, 0xe794, 0xe795, 0xe796, 0xe797, 
+    0xe798, 0xe799, 0xe79a, 0xe79b, 0xe79c, 0xe79d, 0xe79e, 0xe79f, 
+    0xe7a0, 0xe7a1, 0xe7a2, 0xe7a3, 0xe7a4, 0xe7a5, 0xe7a6, 0xe7a7, 
+    0xe7a8, 0xe7a9, 0xe7aa, 0xe7ab, 0xe7ac, 0xe7ad, 0xe7ae, 0xe7af, 
+    0xe7b0, 0xe7b1, 0xe7b2, 0xe7b3, 0xe7b4, 0xe7b5, 0xe7b6, 0xe7b7, 
+    0xe7b8, 0xe7b9, 0xe7ba, 0xe7bb, 0xe7bc, 0xe7bd, 0xe7be, 0xe7bf, 
+    0xe7c0, 0xe7c1, 0xe7c2, 0xe7c3, 0xe7c4, 0xe7c5, 0xe7c6, 0xe7c7, 
+    0xe7c8, 0xe7c9, 0xe7ca, 0xe7cb, 0xe7cc, 0xe7cd, 0xe7ce, 0xe7cf, 
+    0xe7d0, 0xe7d1, 0xe7d2, 0xe7d3, 0xe7d4, 0xe7d5, 0xe7d6, 0xe7d7, 
+    0xe7d8, 0xe7d9, 0xe7da, 0xe7db, 0xe7dc, 0xe7dd, 0xe7de, 0xe7df, 
+    0xe7e0, 0xe7e1, 0xe7e2, 0xe7e3, 0xe7e4, 0xe7e5, 0xe7e6, 0xe7e7, 
+    0xe7e8, 0xe7e9, 0xe7ea, 0xe7eb, 0xe7ec, 0xe7ed, 0xe7ee, 0xe7ef, 
+    0xe7f0, 0xe7f1, 0xe7f2, 0xe7f3, 0xe7f4, 0xe7f5, 0xe7f6, 0xe7f7, 
+    0xe7f8, 0xe7f9, 0xe7fa, 0xe7fb, 0xe7fc, 0xe7fd, 0xe7fe, 0xe7ff, 
+    0xe800, 0xe801, 0xe802, 0xe803, 0xe804, 0xe805, 0xe806, 0xe807, 
+    0xe808, 0xe809, 0xe80a, 0xe80b, 0xe80c, 0xe80d, 0xe80e, 0xe80f, 
+    0xe810, 0xe811, 0xe812, 0xe813, 0xe814, 0xe815, 0xe816, 0xe817, 
+    0xe818, 0xe819, 0xe81a, 0xe81b, 0xe81c, 0xe81d, 0xe81e, 0xe81f, 
+    0xe820, 0xe821, 0xe822, 0xe823, 0xe824, 0xe825, 0xe826, 0xe827, 
+    0xe828, 0xe829, 0xe82a, 0xe82b, 0xe82c, 0xe82d, 0xe82e, 0xe82f, 
+    0xe830, 0xe831, 0xe832, 0xe833, 0xe834, 0xe835, 0xe836, 0xe837, 
+    0xe838, 0xe839, 0xe83a, 0xe83b, 0xe83c, 0xe83d, 0xe83e, 0xe83f, 
+    0xe840, 0xe841, 0xe842, 0xe843, 0xe844, 0xe845, 0xe846, 0xe847, 
+    0xe848, 0xe849, 0xe84a, 0xe84b, 0xe84c, 0xe84d, 0xe84e, 0xe84f, 
+    0xe850, 0xe851, 0xe852, 0xe853, 0xe854, 0xe855, 0xe856, 0xe857, 
+    0xe858, 0xe859, 0xe85a, 0xe85b, 0xe85c, 0xe85d, 0xe85e, 0xe85f, 
+    0xe860, 0xe861, 0xe862, 0xe863, 0xe864, 0xe865, 0xe866, 0xe867, 
+    0xe868, 0xe869, 0xe86a, 0xe86b, 0xe86c, 0xe86d, 0xe86e, 0xe86f, 
+    0xe870, 0xe871, 0xe872, 0xe873, 0xe874, 0xe875, 0xe876, 0xe877, 
+    0xe878, 0xe879, 0xe87a, 0xe87b, 0xe87c, 0xe87d, 0xe87e, 0xe87f, 
+    0xe880, 0xe881, 0xe882, 0xe883, 0xe884, 0xe885, 0xe886, 0xe887, 
+    0xe888, 0xe889, 0xe88a, 0xe88b, 0xe88c, 0xe88d, 0xe88e, 0xe88f, 
+    0xe890, 0xe891, 0xe892, 0xe893, 0xe894, 0xe895, 0xe896, 0xe897, 
+    0xe898, 0xe899, 0xe89a, 0xe89b, 0xe89c, 0xe89d, 0xe89e, 0xe89f, 
+    0xe8a0, 0xe8a1, 0xe8a2, 0xe8a3, 0xe8a4, 0xe8a5, 0xe8a6, 0xe8a7, 
+    0xe8a8, 0xe8a9, 0xe8aa, 0xe8ab, 0xe8ac, 0xe8ad, 0xe8ae, 0xe8af, 
+    0xe8b0, 0xe8b1, 0xe8b2, 0xe8b3, 0xe8b4, 0xe8b5, 0xe8b6, 0xe8b7, 
+    0xe8b8, 0xe8b9, 0xe8ba, 0xe8bb, 0xe8bc, 0xe8bd, 0xe8be, 0xe8bf, 
+    0xe8c0, 0xe8c1, 0xe8c2, 0xe8c3, 0xe8c4, 0xe8c5, 0xe8c6, 0xe8c7, 
+    0xe8c8, 0xe8c9, 0xe8ca, 0xe8cb, 0xe8cc, 0xe8cd, 0xe8ce, 0xe8cf, 
+    0xe8d0, 0xe8d1, 0xe8d2, 0xe8d3, 0xe8d4, 0xe8d5, 0xe8d6, 0xe8d7, 
+    0xe8d8, 0xe8d9, 0xe8da, 0xe8db, 0xe8dc, 0xe8dd, 0xe8de, 0xe8df, 
+    0xe8e0, 0xe8e1, 0xe8e2, 0xe8e3, 0xe8e4, 0xe8e5, 0xe8e6, 0xe8e7, 
+    0xe8e8, 0xe8e9, 0xe8ea, 0xe8eb, 0xe8ec, 0xe8ed, 0xe8ee, 0xe8ef, 
+    0xe8f0, 0xe8f1, 0xe8f2, 0xe8f3, 0xe8f4, 0xe8f5, 0xe8f6, 0xe8f7, 
+    0xe8f8, 0xe8f9, 0xe8fa, 0xe8fb, 0xe8fc, 0xe8fd, 0xe8fe, 0xe8ff, 
+    0xe900, 0xe901, 0xe902, 0xe903, 0xe904, 0xe905, 0xe906, 0xe907, 
+    0xe908, 0xe909, 0xe90a, 0xe90b, 0xe90c, 0xe90d, 0xe90e, 0xe90f, 
+    0xe910, 0xe911, 0xe912, 0xe913, 0xe914, 0xe915, 0xe916, 0xe917, 
+    0xe918, 0xe919, 0xe91a, 0xe91b, 0xe91c, 0xe91d, 0xe91e, 0xe91f, 
+    0xe920, 0xe921, 0xe922, 0xe923, 0xe924, 0xe925, 0xe926, 0xe927, 
+    0xe928, 0xe929, 0xe92a, 0xe92b, 0xe92c, 0xe92d, 0xe92e, 0xe92f, 
+    0xe930, 0xe931, 0xe932, 0xe933, 0xe934, 0xe935, 0xe936, 0xe937, 
+    0xe938, 0xe939, 0xe93a, 0xe93b, 0xe93c, 0xe93d, 0xe93e, 0xe93f, 
+    0xe940, 0xe941, 0xe942, 0xe943, 0xe944, 0xe945, 0xe946, 0xe947, 
+    0xe948, 0xe949, 0xe94a, 0xe94b, 0xe94c, 0xe94d, 0xe94e, 0xe94f, 
+    0xe950, 0xe951, 0xe952, 0xe953, 0xe954, 0xe955, 0xe956, 0xe957, 
+    0xe958, 0xe959, 0xe95a, 0xe95b, 0xe95c, 0xe95d, 0xe95e, 0xe95f, 
+    0xe960, 0xe961, 0xe962, 0xe963, 0xe964, 0xe965, 0xe966, 0xe967, 
+    0xe968, 0xe969, 0xe96a, 0xe96b, 0xe96c, 0xe96d, 0xe96e, 0xe96f, 
+    0xe970, 0xe971, 0xe972, 0xe973, 0xe974, 0xe975, 0xe976, 0xe977, 
+    0xe978, 0xe979, 0xe97a, 0xe97b, 0xe97c, 0xe97d, 0xe97e, 0xe97f, 
+    0xe980, 0xe981, 0xe982, 0xe983, 0xe984, 0xe985, 0xe986, 0xe987, 
+    0xe988, 0xe989, 0xe98a, 0xe98b, 0xe98c, 0xe98d, 0xe98e, 0xe98f, 
+    0xe990, 0xe991, 0xe992, 0xe993, 0xe994, 0xe995, 0xe996, 0xe997, 
+    0xe998, 0xe999, 0xe99a, 0xe99b, 0xe99c, 0xe99d, 0xe99e, 0xe99f, 
+    0xe9a0, 0xe9a1, 0xe9a2, 0xe9a3, 0xe9a4, 0xe9a5, 0xe9a6, 0xe9a7, 
+    0xe9a8, 0xe9a9, 0xe9aa, 0xe9ab, 0xe9ac, 0xe9ad, 0xe9ae, 0xe9af, 
+    0xe9b0, 0xe9b1, 0xe9b2, 0xe9b3, 0xe9b4, 0xe9b5, 0xe9b6, 0xe9b7, 
+    0xe9b8, 0xe9b9, 0xe9ba, 0xe9bb, 0xe9bc, 0xe9bd, 0xe9be, 0xe9bf, 
+    0xe9c0, 0xe9c1, 0xe9c2, 0xe9c3, 0xe9c4, 0xe9c5, 0xe9c6, 0xe9c7, 
+    0xe9c8, 0xe9c9, 0xe9ca, 0xe9cb, 0xe9cc, 0xe9cd, 0xe9ce, 0xe9cf, 
+    0xe9d0, 0xe9d1, 0xe9d2, 0xe9d3, 0xe9d4, 0xe9d5, 0xe9d6, 0xe9d7, 
+    0xe9d8, 0xe9d9, 0xe9da, 0xe9db, 0xe9dc, 0xe9dd, 0xe9de, 0xe9df, 
+    0xe9e0, 0xe9e1, 0xe9e2, 0xe9e3, 0xe9e4, 0xe9e5, 0xe9e6, 0xe9e7, 
+    0xe9e8, 0xe9e9, 0xe9ea, 0xe9eb, 0xe9ec, 0xe9ed, 0xe9ee, 0xe9ef, 
+    0xe9f0, 0xe9f1, 0xe9f2, 0xe9f3, 0xe9f4, 0xe9f5, 0xe9f6, 0xe9f7, 
+    0xe9f8, 0xe9f9, 0xe9fa, 0xe9fb, 0xe9fc, 0xe9fd, 0xe9fe, 0xe9ff, 
+    0xea00, 0xea01, 0xea02, 0xea03, 0xea04, 0xea05, 0xea06, 0xea07, 
+    0xea08, 0xea09, 0xea0a, 0xea0b, 0xea0c, 0xea0d, 0xea0e, 0xea0f, 
+    0xea10, 0xea11, 0xea12, 0xea13, 0xea14, 0xea15, 0xea16, 0xea17, 
+    0xea18, 0xea19, 0xea1a, 0xea1b, 0xea1c, 0xea1d, 0xea1e, 0xea1f, 
+    0xea20, 0xea21, 0xea22, 0xea23, 0xea24, 0xea25, 0xea26, 0xea27, 
+    0xea28, 0xea29, 0xea2a, 0xea2b, 0xea2c, 0xea2d, 0xea2e, 0xea2f, 
+    0xea30, 0xea31, 0xea32, 0xea33, 0xea34, 0xea35, 0xea36, 0xea37, 
+    0xea38, 0xea39, 0xea3a, 0xea3b, 0xea3c, 0xea3d, 0xea3e, 0xea3f, 
+    0xea40, 0xea41, 0xea42, 0xea43, 0xea44, 0xea45, 0xea46, 0xea47, 
+    0xea48, 0xea49, 0xea4a, 0xea4b, 0xea4c, 0xea4d, 0xea4e, 0xea4f, 
+    0xea50, 0xea51, 0xea52, 0xea53, 0xea54, 0xea55, 0xea56, 0xea57, 
+    0xea58, 0xea59, 0xea5a, 0xea5b, 0xea5c, 0xea5d, 0xea5e, 0xea5f, 
+    0xea60, 0xea61, 0xea62, 0xea63, 0xea64, 0xea65, 0xea66, 0xea67, 
+    0xea68, 0xea69, 0xea6a, 0xea6b, 0xea6c, 0xea6d, 0xea6e, 0xea6f, 
+    0xea70, 0xea71, 0xea72, 0xea73, 0xea74, 0xea75, 0xea76, 0xea77, 
+    0xea78, 0xea79, 0xea7a, 0xea7b, 0xea7c, 0xea7d, 0xea7e, 0xea7f, 
+    0xea80, 0xea81, 0xea82, 0xea83, 0xea84, 0xea85, 0xea86, 0xea87, 
+    0xea88, 0xea89, 0xea8a, 0xea8b, 0xea8c, 0xea8d, 0xea8e, 0xea8f, 
+    0xea90, 0xea91, 0xea92, 0xea93, 0xea94, 0xea95, 0xea96, 0xea97, 
+    0xea98, 0xea99, 0xea9a, 0xea9b, 0xea9c, 0xea9d, 0xea9e, 0xea9f, 
+    0xeaa0, 0xeaa1, 0xeaa2, 0xeaa3, 0xeaa4, 0xeaa5, 0xeaa6, 0xeaa7, 
+    0xeaa8, 0xeaa9, 0xeaaa, 0xeaab, 0xeaac, 0xeaad, 0xeaae, 0xeaaf, 
+    0xeab0, 0xeab1, 0xeab2, 0xeab3, 0xeab4, 0xeab5, 0xeab6, 0xeab7, 
+    0xeab8, 0xeab9, 0xeaba, 0xeabb, 0xeabc, 0xeabd, 0xeabe, 0xeabf, 
+    0xeac0, 0xeac1, 0xeac2, 0xeac3, 0xeac4, 0xeac5, 0xeac6, 0xeac7, 
+    0xeac8, 0xeac9, 0xeaca, 0xeacb, 0xeacc, 0xeacd, 0xeace, 0xeacf, 
+    0xead0, 0xead1, 0xead2, 0xead3, 0xead4, 0xead5, 0xead6, 0xead7, 
+    0xead8, 0xead9, 0xeada, 0xeadb, 0xeadc, 0xeadd, 0xeade, 0xeadf, 
+    0xeae0, 0xeae1, 0xeae2, 0xeae3, 0xeae4, 0xeae5, 0xeae6, 0xeae7, 
+    0xeae8, 0xeae9, 0xeaea, 0xeaeb, 0xeaec, 0xeaed, 0xeaee, 0xeaef, 
+    0xeaf0, 0xeaf1, 0xeaf2, 0xeaf3, 0xeaf4, 0xeaf5, 0xeaf6, 0xeaf7, 
+    0xeaf8, 0xeaf9, 0xeafa, 0xeafb, 0xeafc, 0xeafd, 0xeafe, 0xeaff, 
+    0xeb00, 0xeb01, 0xeb02, 0xeb03, 0xeb04, 0xeb05, 0xeb06, 0xeb07, 
+    0xeb08, 0xeb09, 0xeb0a, 0xeb0b, 0xeb0c, 0xeb0d, 0xeb0e, 0xeb0f, 
+    0xeb10, 0xeb11, 0xeb12, 0xeb13, 0xeb14, 0xeb15, 0xeb16, 0xeb17, 
+    0xeb18, 0xeb19, 0xeb1a, 0xeb1b, 0xeb1c, 0xeb1d, 0xeb1e, 0xeb1f, 
+    0xeb20, 0xeb21, 0xeb22, 0xeb23, 0xeb24, 0xeb25, 0xeb26, 0xeb27, 
+    0xeb28, 0xeb29, 0xeb2a, 0xeb2b, 0xeb2c, 0xeb2d, 0xeb2e, 0xeb2f, 
+    0xeb30, 0xeb31, 0xeb32, 0xeb33, 0xeb34, 0xeb35, 0xeb36, 0xeb37, 
+    0xeb38, 0xeb39, 0xeb3a, 0xeb3b, 0xeb3c, 0xeb3d, 0xeb3e, 0xeb3f, 
+    0xeb40, 0xeb41, 0xeb42, 0xeb43, 0xeb44, 0xeb45, 0xeb46, 0xeb47, 
+    0xeb48, 0xeb49, 0xeb4a, 0xeb4b, 0xeb4c, 0xeb4d, 0xeb4e, 0xeb4f, 
+    0xeb50, 0xeb51, 0xeb52, 0xeb53, 0xeb54, 0xeb55, 0xeb56, 0xeb57, 
+    0xeb58, 0xeb59, 0xeb5a, 0xeb5b, 0xeb5c, 0xeb5d, 0xeb5e, 0xeb5f, 
+    0xeb60, 0xeb61, 0xeb62, 0xeb63, 0xeb64, 0xeb65, 0xeb66, 0xeb67, 
+    0xeb68, 0xeb69, 0xeb6a, 0xeb6b, 0xeb6c, 0xeb6d, 0xeb6e, 0xeb6f, 
+    0xeb70, 0xeb71, 0xeb72, 0xeb73, 0xeb74, 0xeb75, 0xeb76, 0xeb77, 
+    0xeb78, 0xeb79, 0xeb7a, 0xeb7b, 0xeb7c, 0xeb7d, 0xeb7e, 0xeb7f, 
+    0xeb80, 0xeb81, 0xeb82, 0xeb83, 0xeb84, 0xeb85, 0xeb86, 0xeb87, 
+    0xeb88, 0xeb89, 0xeb8a, 0xeb8b, 0xeb8c, 0xeb8d, 0xeb8e, 0xeb8f, 
+    0xeb90, 0xeb91, 0xeb92, 0xeb93, 0xeb94, 0xeb95, 0xeb96, 0xeb97, 
+    0xeb98, 0xeb99, 0xeb9a, 0xeb9b, 0xeb9c, 0xeb9d, 0xeb9e, 0xeb9f, 
+    0xeba0, 0xeba1, 0xeba2, 0xeba3, 0xeba4, 0xeba5, 0xeba6, 0xeba7, 
+    0xeba8, 0xeba9, 0xebaa, 0xebab, 0xebac, 0xebad, 0xebae, 0xebaf, 
+    0xebb0, 0xebb1, 0xebb2, 0xebb3, 0xebb4, 0xebb5, 0xebb6, 0xebb7, 
+    0xebb8, 0xebb9, 0xebba, 0xebbb, 0xebbc, 0xebbd, 0xebbe, 0xebbf, 
+    0xebc0, 0xebc1, 0xebc2, 0xebc3, 0xebc4, 0xebc5, 0xebc6, 0xebc7, 
+    0xebc8, 0xebc9, 0xebca, 0xebcb, 0xebcc, 0xebcd, 0xebce, 0xebcf, 
+    0xebd0, 0xebd1, 0xebd2, 0xebd3, 0xebd4, 0xebd5, 0xebd6, 0xebd7, 
+    0xebd8, 0xebd9, 0xebda, 0xebdb, 0xebdc, 0xebdd, 0xebde, 0xebdf, 
+    0xebe0, 0xebe1, 0xebe2, 0xebe3, 0xebe4, 0xebe5, 0xebe6, 0xebe7, 
+    0xebe8, 0xebe9, 0xebea, 0xebeb, 0xebec, 0xebed, 0xebee, 0xebef, 
+    0xebf0, 0xebf1, 0xebf2, 0xebf3, 0xebf4, 0xebf5, 0xebf6, 0xebf7, 
+    0xebf8, 0xebf9, 0xebfa, 0xebfb, 0xebfc, 0xebfd, 0xebfe, 0xebff, 
+    0xec00, 0xec01, 0xec02, 0xec03, 0xec04, 0xec05, 0xec06, 0xec07, 
+    0xec08, 0xec09, 0xec0a, 0xec0b, 0xec0c, 0xec0d, 0xec0e, 0xec0f, 
+    0xec10, 0xec11, 0xec12, 0xec13, 0xec14, 0xec15, 0xec16, 0xec17, 
+    0xec18, 0xec19, 0xec1a, 0xec1b, 0xec1c, 0xec1d, 0xec1e, 0xec1f, 
+    0xec20, 0xec21, 0xec22, 0xec23, 0xec24, 0xec25, 0xec26, 0xec27, 
+    0xec28, 0xec29, 0xec2a, 0xec2b, 0xec2c, 0xec2d, 0xec2e, 0xec2f, 
+    0xec30, 0xec31, 0xec32, 0xec33, 0xec34, 0xec35, 0xec36, 0xec37, 
+    0xec38, 0xec39, 0xec3a, 0xec3b, 0xec3c, 0xec3d, 0xec3e, 0xec3f, 
+    0xec40, 0xec41, 0xec42, 0xec43, 0xec44, 0xec45, 0xec46, 0xec47, 
+    0xec48, 0xec49, 0xec4a, 0xec4b, 0xec4c, 0xec4d, 0xec4e, 0xec4f, 
+    0xec50, 0xec51, 0xec52, 0xec53, 0xec54, 0xec55, 0xec56, 0xec57, 
+    0xec58, 0xec59, 0xec5a, 0xec5b, 0xec5c, 0xec5d, 0xec5e, 0xec5f, 
+    0xec60, 0xec61, 0xec62, 0xec63, 0xec64, 0xec65, 0xec66, 0xec67, 
+    0xec68, 0xec69, 0xec6a, 0xec6b, 0xec6c, 0xec6d, 0xec6e, 0xec6f, 
+    0xec70, 0xec71, 0xec72, 0xec73, 0xec74, 0xec75, 0xec76, 0xec77, 
+    0xec78, 0xec79, 0xec7a, 0xec7b, 0xec7c, 0xec7d, 0xec7e, 0xec7f, 
+    0xec80, 0xec81, 0xec82, 0xec83, 0xec84, 0xec85, 0xec86, 0xec87, 
+    0xec88, 0xec89, 0xec8a, 0xec8b, 0xec8c, 0xec8d, 0xec8e, 0xec8f, 
+    0xec90, 0xec91, 0xec92, 0xec93, 0xec94, 0xec95, 0xec96, 0xec97, 
+    0xec98, 0xec99, 0xec9a, 0xec9b, 0xec9c, 0xec9d, 0xec9e, 0xec9f, 
+    0xeca0, 0xeca1, 0xeca2, 0xeca3, 0xeca4, 0xeca5, 0xeca6, 0xeca7, 
+    0xeca8, 0xeca9, 0xecaa, 0xecab, 0xecac, 0xecad, 0xecae, 0xecaf, 
+    0xecb0, 0xecb1, 0xecb2, 0xecb3, 0xecb4, 0xecb5, 0xecb6, 0xecb7, 
+    0xecb8, 0xecb9, 0xecba, 0xecbb, 0xecbc, 0xecbd, 0xecbe, 0xecbf, 
+    0xecc0, 0xecc1, 0xecc2, 0xecc3, 0xecc4, 0xecc5, 0xecc6, 0xecc7, 
+    0xecc8, 0xecc9, 0xecca, 0xeccb, 0xeccc, 0xeccd, 0xecce, 0xeccf, 
+    0xecd0, 0xecd1, 0xecd2, 0xecd3, 0xecd4, 0xecd5, 0xecd6, 0xecd7, 
+    0xecd8, 0xecd9, 0xecda, 0xecdb, 0xecdc, 0xecdd, 0xecde, 0xecdf, 
+    0xece0, 0xece1, 0xece2, 0xece3, 0xece4, 0xece5, 0xece6, 0xece7, 
+    0xece8, 0xece9, 0xecea, 0xeceb, 0xecec, 0xeced, 0xecee, 0xecef, 
+    0xecf0, 0xecf1, 0xecf2, 0xecf3, 0xecf4, 0xecf5, 0xecf6, 0xecf7, 
+    0xecf8, 0xecf9, 0xecfa, 0xecfb, 0xecfc, 0xecfd, 0xecfe, 0xecff, 
+    0xed00, 0xed01, 0xed02, 0xed03, 0xed04, 0xed05, 0xed06, 0xed07, 
+    0xed08, 0xed09, 0xed0a, 0xed0b, 0xed0c, 0xed0d, 0xed0e, 0xed0f, 
+    0xed10, 0xed11, 0xed12, 0xed13, 0xed14, 0xed15, 0xed16, 0xed17, 
+    0xed18, 0xed19, 0xed1a, 0xed1b, 0xed1c, 0xed1d, 0xed1e, 0xed1f, 
+    0xed20, 0xed21, 0xed22, 0xed23, 0xed24, 0xed25, 0xed26, 0xed27, 
+    0xed28, 0xed29, 0xed2a, 0xed2b, 0xed2c, 0xed2d, 0xed2e, 0xed2f, 
+    0xed30, 0xed31, 0xed32, 0xed33, 0xed34, 0xed35, 0xed36, 0xed37, 
+    0xed38, 0xed39, 0xed3a, 0xed3b, 0xed3c, 0xed3d, 0xed3e, 0xed3f, 
+    0xed40, 0xed41, 0xed42, 0xed43, 0xed44, 0xed45, 0xed46, 0xed47, 
+    0xed48, 0xed49, 0xed4a, 0xed4b, 0xed4c, 0xed4d, 0xed4e, 0xed4f, 
+    0xed50, 0xed51, 0xed52, 0xed53, 0xed54, 0xed55, 0xed56, 0xed57, 
+    0xed58, 0xed59, 0xed5a, 0xed5b, 0xed5c, 0xed5d, 0xed5e, 0xed5f, 
+    0xed60, 0xed61, 0xed62, 0xed63, 0xed64, 0xed65, 0xed66, 0xed67, 
+    0xed68, 0xed69, 0xed6a, 0xed6b, 0xed6c, 0xed6d, 0xed6e, 0xed6f, 
+    0xed70, 0xed71, 0xed72, 0xed73, 0xed74, 0xed75, 0xed76, 0xed77, 
+    0xed78, 0xed79, 0xed7a, 0xed7b, 0xed7c, 0xed7d, 0xed7e, 0xed7f, 
+    0xed80, 0xed81, 0xed82, 0xed83, 0xed84, 0xed85, 0xed86, 0xed87, 
+    0xed88, 0xed89, 0xed8a, 0xed8b, 0xed8c, 0xed8d, 0xed8e, 0xed8f, 
+    0xed90, 0xed91, 0xed92, 0xed93, 0xed94, 0xed95, 0xed96, 0xed97, 
+    0xed98, 0xed99, 0xed9a, 0xed9b, 0xed9c, 0xed9d, 0xed9e, 0xed9f, 
+    0xeda0, 0xeda1, 0xeda2, 0xeda3, 0xeda4, 0xeda5, 0xeda6, 0xeda7, 
+    0xeda8, 0xeda9, 0xedaa, 0xedab, 0xedac, 0xedad, 0xedae, 0xedaf, 
+    0xedb0, 0xedb1, 0xedb2, 0xedb3, 0xedb4, 0xedb5, 0xedb6, 0xedb7, 
+    0xedb8, 0xedb9, 0xedba, 0xedbb, 0xedbc, 0xedbd, 0xedbe, 0xedbf, 
+    0xedc0, 0xedc1, 0xedc2, 0xedc3, 0xedc4, 0xedc5, 0xedc6, 0xedc7, 
+    0xedc8, 0xedc9, 0xedca, 0xedcb, 0xedcc, 0xedcd, 0xedce, 0xedcf, 
+    0xedd0, 0xedd1, 0xedd2, 0xedd3, 0xedd4, 0xedd5, 0xedd6, 0xedd7, 
+    0xedd8, 0xedd9, 0xedda, 0xeddb, 0xeddc, 0xeddd, 0xedde, 0xeddf, 
+    0xede0, 0xede1, 0xede2, 0xede3, 0xede4, 0xede5, 0xede6, 0xede7, 
+    0xede8, 0xede9, 0xedea, 0xedeb, 0xedec, 0xeded, 0xedee, 0xedef, 
+    0xedf0, 0xedf1, 0xedf2, 0xedf3, 0xedf4, 0xedf5, 0xedf6, 0xedf7, 
+    0xedf8, 0xedf9, 0xedfa, 0xedfb, 0xedfc, 0xedfd, 0xedfe, 0xedff, 
+    0xee00, 0xee01, 0xee02, 0xee03, 0xee04, 0xee05, 0xee06, 0xee07, 
+    0xee08, 0xee09, 0xee0a, 0xee0b, 0xee0c, 0xee0d, 0xee0e, 0xee0f, 
+    0xee10, 0xee11, 0xee12, 0xee13, 0xee14, 0xee15, 0xee16, 0xee17, 
+    0xee18, 0xee19, 0xee1a, 0xee1b, 0xee1c, 0xee1d, 0xee1e, 0xee1f, 
+    0xee20, 0xee21, 0xee22, 0xee23, 0xee24, 0xee25, 0xee26, 0xee27, 
+    0xee28, 0xee29, 0xee2a, 0xee2b, 0xee2c, 0xee2d, 0xee2e, 0xee2f, 
+    0xee30, 0xee31, 0xee32, 0xee33, 0xee34, 0xee35, 0xee36, 0xee37, 
+    0xee38, 0xee39, 0xee3a, 0xee3b, 0xee3c, 0xee3d, 0xee3e, 0xee3f, 
+    0xee40, 0xee41, 0xee42, 0xee43, 0xee44, 0xee45, 0xee46, 0xee47, 
+    0xee48, 0xee49, 0xee4a, 0xee4b, 0xee4c, 0xee4d, 0xee4e, 0xee4f, 
+    0xee50, 0xee51, 0xee52, 0xee53, 0xee54, 0xee55, 0xee56, 0xee57, 
+    0xee58, 0xee59, 0xee5a, 0xee5b, 0xee5c, 0xee5d, 0xee5e, 0xee5f, 
+    0xee60, 0xee61, 0xee62, 0xee63, 0xee64, 0xee65, 0xee66, 0xee67, 
+    0xee68, 0xee69, 0xee6a, 0xee6b, 0xee6c, 0xee6d, 0xee6e, 0xee6f, 
+    0xee70, 0xee71, 0xee72, 0xee73, 0xee74, 0xee75, 0xee76, 0xee77, 
+    0xee78, 0xee79, 0xee7a, 0xee7b, 0xee7c, 0xee7d, 0xee7e, 0xee7f, 
+    0xee80, 0xee81, 0xee82, 0xee83, 0xee84, 0xee85, 0xee86, 0xee87, 
+    0xee88, 0xee89, 0xee8a, 0xee8b, 0xee8c, 0xee8d, 0xee8e, 0xee8f, 
+    0xee90, 0xee91, 0xee92, 0xee93, 0xee94, 0xee95, 0xee96, 0xee97, 
+    0xee98, 0xee99, 0xee9a, 0xee9b, 0xee9c, 0xee9d, 0xee9e, 0xee9f, 
+    0xeea0, 0xeea1, 0xeea2, 0xeea3, 0xeea4, 0xeea5, 0xeea6, 0xeea7, 
+    0xeea8, 0xeea9, 0xeeaa, 0xeeab, 0xeeac, 0xeead, 0xeeae, 0xeeaf, 
+    0xeeb0, 0xeeb1, 0xeeb2, 0xeeb3, 0xeeb4, 0xeeb5, 0xeeb6, 0xeeb7, 
+    0xeeb8, 0xeeb9, 0xeeba, 0xeebb, 0xeebc, 0xeebd, 0xeebe, 0xeebf, 
+    0xeec0, 0xeec1, 0xeec2, 0xeec3, 0xeec4, 0xeec5, 0xeec6, 0xeec7, 
+    0xeec8, 0xeec9, 0xeeca, 0xeecb, 0xeecc, 0xeecd, 0xeece, 0xeecf, 
+    0xeed0, 0xeed1, 0xeed2, 0xeed3, 0xeed4, 0xeed5, 0xeed6, 0xeed7, 
+    0xeed8, 0xeed9, 0xeeda, 0xeedb, 0xeedc, 0xeedd, 0xeede, 0xeedf, 
+    0xeee0, 0xeee1, 0xeee2, 0xeee3, 0xeee4, 0xeee5, 0xeee6, 0xeee7, 
+    0xeee8, 0xeee9, 0xeeea, 0xeeeb, 0xeeec, 0xeeed, 0xeeee, 0xeeef, 
+    0xeef0, 0xeef1, 0xeef2, 0xeef3, 0xeef4, 0xeef5, 0xeef6, 0xeef7, 
+    0xeef8, 0xeef9, 0xeefa, 0xeefb, 0xeefc, 0xeefd, 0xeefe, 0xeeff, 
+    0xef00, 0xef01, 0xef02, 0xef03, 0xef04, 0xef05, 0xef06, 0xef07, 
+    0xef08, 0xef09, 0xef0a, 0xef0b, 0xef0c, 0xef0d, 0xef0e, 0xef0f, 
+    0xef10, 0xef11, 0xef12, 0xef13, 0xef14, 0xef15, 0xef16, 0xef17, 
+    0xef18, 0xef19, 0xef1a, 0xef1b, 0xef1c, 0xef1d, 0xef1e, 0xef1f, 
+    0xef20, 0xef21, 0xef22, 0xef23, 0xef24, 0xef25, 0xef26, 0xef27, 
+    0xef28, 0xef29, 0xef2a, 0xef2b, 0xef2c, 0xef2d, 0xef2e, 0xef2f, 
+    0xef30, 0xef31, 0xef32, 0xef33, 0xef34, 0xef35, 0xef36, 0xef37, 
+    0xef38, 0xef39, 0xef3a, 0xef3b, 0xef3c, 0xef3d, 0xef3e, 0xef3f, 
+    0xef40, 0xef41, 0xef42, 0xef43, 0xef44, 0xef45, 0xef46, 0xef47, 
+    0xef48, 0xef49, 0xef4a, 0xef4b, 0xef4c, 0xef4d, 0xef4e, 0xef4f, 
+    0xef50, 0xef51, 0xef52, 0xef53, 0xef54, 0xef55, 0xef56, 0xef57, 
+    0xef58, 0xef59, 0xef5a, 0xef5b, 0xef5c, 0xef5d, 0xef5e, 0xef5f, 
+    0xef60, 0xef61, 0xef62, 0xef63, 0xef64, 0xef65, 0xef66, 0xef67, 
+    0xef68, 0xef69, 0xef6a, 0xef6b, 0xef6c, 0xef6d, 0xef6e, 0xef6f, 
+    0xef70, 0xef71, 0xef72, 0xef73, 0xef74, 0xef75, 0xef76, 0xef77, 
+    0xef78, 0xef79, 0xef7a, 0xef7b, 0xef7c, 0xef7d, 0xef7e, 0xef7f, 
+    0xef80, 0xef81, 0xef82, 0xef83, 0xef84, 0xef85, 0xef86, 0xef87, 
+    0xef88, 0xef89, 0xef8a, 0xef8b, 0xef8c, 0xef8d, 0xef8e, 0xef8f, 
+    0xef90, 0xef91, 0xef92, 0xef93, 0xef94, 0xef95, 0xef96, 0xef97, 
+    0xef98, 0xef99, 0xef9a, 0xef9b, 0xef9c, 0xef9d, 0xef9e, 0xef9f, 
+    0xefa0, 0xefa1, 0xefa2, 0xefa3, 0xefa4, 0xefa5, 0xefa6, 0xefa7, 
+    0xefa8, 0xefa9, 0xefaa, 0xefab, 0xefac, 0xefad, 0xefae, 0xefaf, 
+    0xefb0, 0xefb1, 0xefb2, 0xefb3, 0xefb4, 0xefb5, 0xefb6, 0xefb7, 
+    0xefb8, 0xefb9, 0xefba, 0xefbb, 0xefbc, 0xefbd, 0xefbe, 0xefbf, 
+    0xefc0, 0xefc1, 0xefc2, 0xefc3, 0xefc4, 0xefc5, 0xefc6, 0xefc7, 
+    0xefc8, 0xefc9, 0xefca, 0xefcb, 0xefcc, 0xefcd, 0xefce, 0xefcf, 
+    0xefd0, 0xefd1, 0xefd2, 0xefd3, 0xefd4, 0xefd5, 0xefd6, 0xefd7, 
+    0xefd8, 0xefd9, 0xefda, 0xefdb, 0xefdc, 0xefdd, 0xefde, 0xefdf, 
+    0xefe0, 0xefe1, 0xefe2, 0xefe3, 0xefe4, 0xefe5, 0xefe6, 0xefe7, 
+    0xefe8, 0xefe9, 0xefea, 0xefeb, 0xefec, 0xefed, 0xefee, 0xefef, 
+    0xeff0, 0xeff1, 0xeff2, 0xeff3, 0xeff4, 0xeff5, 0xeff6, 0xeff7, 
+    0xeff8, 0xeff9, 0xeffa, 0xeffb, 0xeffc, 0xeffd, 0xeffe, 0xefff, 
+    0xf000, 0xf001, 0xf002, 0xf003, 0xf004, 0xf005, 0xf006, 0xf007, 
+    0xf008, 0xf009, 0xf00a, 0xf00b, 0xf00c, 0xf00d, 0xf00e, 0xf00f, 
+    0xf010, 0xf011, 0xf012, 0xf013, 0xf014, 0xf015, 0xf016, 0xf017, 
+    0xf018, 0xf019, 0xf01a, 0xf01b, 0xf01c, 0xf01d, 0xf01e, 0xf01f, 
+    0xf020, 0xf021, 0xf022, 0xf023, 0xf024, 0xf025, 0xf026, 0xf027, 
+    0xf028, 0xf029, 0xf02a, 0xf02b, 0xf02c, 0xf02d, 0xf02e, 0xf02f, 
+    0xf030, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, 0xf037, 
+    0xf038, 0xf039, 0xf03a, 0xf03b, 0xf03c, 0xf03d, 0xf03e, 0xf03f, 
+    0xf040, 0xf041, 0xf042, 0xf043, 0xf044, 0xf045, 0xf046, 0xf047, 
+    0xf048, 0xf049, 0xf04a, 0xf04b, 0xf04c, 0xf04d, 0xf04e, 0xf04f, 
+    0xf050, 0xf051, 0xf052, 0xf053, 0xf054, 0xf055, 0xf056, 0xf057, 
+    0xf058, 0xf059, 0xf05a, 0xf05b, 0xf05c, 0xf05d, 0xf05e, 0xf05f, 
+    0xf060, 0xf061, 0xf062, 0xf063, 0xf064, 0xf065, 0xf066, 0xf067, 
+    0xf068, 0xf069, 0xf06a, 0xf06b, 0xf06c, 0xf06d, 0xf06e, 0xf06f, 
+    0xf070, 0xf071, 0xf072, 0xf073, 0xf074, 0xf075, 0xf076, 0xf077, 
+    0xf078, 0xf079, 0xf07a, 0xf07b, 0xf07c, 0xf07d, 0xf07e, 0xf07f, 
+    0xf080, 0xf081, 0xf082, 0xf083, 0xf084, 0xf085, 0xf086, 0xf087, 
+    0xf088, 0xf089, 0xf08a, 0xf08b, 0xf08c, 0xf08d, 0xf08e, 0xf08f, 
+    0xf090, 0xf091, 0xf092, 0xf093, 0xf094, 0xf095, 0xf096, 0xf097, 
+    0xf098, 0xf099, 0xf09a, 0xf09b, 0xf09c, 0xf09d, 0xf09e, 0xf09f, 
+    0xf0a0, 0xf0a1, 0xf0a2, 0xf0a3, 0xf0a4, 0xf0a5, 0xf0a6, 0xf0a7, 
+    0xf0a8, 0xf0a9, 0xf0aa, 0xf0ab, 0xf0ac, 0xf0ad, 0xf0ae, 0xf0af, 
+    0xf0b0, 0xf0b1, 0xf0b2, 0xf0b3, 0xf0b4, 0xf0b5, 0xf0b6, 0xf0b7, 
+    0xf0b8, 0xf0b9, 0xf0ba, 0xf0bb, 0xf0bc, 0xf0bd, 0xf0be, 0xf0bf, 
+    0xf0c0, 0xf0c1, 0xf0c2, 0xf0c3, 0xf0c4, 0xf0c5, 0xf0c6, 0xf0c7, 
+    0xf0c8, 0xf0c9, 0xf0ca, 0xf0cb, 0xf0cc, 0xf0cd, 0xf0ce, 0xf0cf, 
+    0xf0d0, 0xf0d1, 0xf0d2, 0xf0d3, 0xf0d4, 0xf0d5, 0xf0d6, 0xf0d7, 
+    0xf0d8, 0xf0d9, 0xf0da, 0xf0db, 0xf0dc, 0xf0dd, 0xf0de, 0xf0df, 
+    0xf0e0, 0xf0e1, 0xf0e2, 0xf0e3, 0xf0e4, 0xf0e5, 0xf0e6, 0xf0e7, 
+    0xf0e8, 0xf0e9, 0xf0ea, 0xf0eb, 0xf0ec, 0xf0ed, 0xf0ee, 0xf0ef, 
+    0xf0f0, 0xf0f1, 0xf0f2, 0xf0f3, 0xf0f4, 0xf0f5, 0xf0f6, 0xf0f7, 
+    0xf0f8, 0xf0f9, 0xf0fa, 0xf0fb, 0xf0fc, 0xf0fd, 0xf0fe, 0xf0ff, 
+    0xf100, 0xf101, 0xf102, 0xf103, 0xf104, 0xf105, 0xf106, 0xf107, 
+    0xf108, 0xf109, 0xf10a, 0xf10b, 0xf10c, 0xf10d, 0xf10e, 0xf10f, 
+    0xf110, 0xf111, 0xf112, 0xf113, 0xf114, 0xf115, 0xf116, 0xf117, 
+    0xf118, 0xf119, 0xf11a, 0xf11b, 0xf11c, 0xf11d, 0xf11e, 0xf11f, 
+    0xf120, 0xf121, 0xf122, 0xf123, 0xf124, 0xf125, 0xf126, 0xf127, 
+    0xf128, 0xf129, 0xf12a, 0xf12b, 0xf12c, 0xf12d, 0xf12e, 0xf12f, 
+    0xf130, 0xf131, 0xf132, 0xf133, 0xf134, 0xf135, 0xf136, 0xf137, 
+    0xf138, 0xf139, 0xf13a, 0xf13b, 0xf13c, 0xf13d, 0xf13e, 0xf13f, 
+    0xf140, 0xf141, 0xf142, 0xf143, 0xf144, 0xf145, 0xf146, 0xf147, 
+    0xf148, 0xf149, 0xf14a, 0xf14b, 0xf14c, 0xf14d, 0xf14e, 0xf14f, 
+    0xf150, 0xf151, 0xf152, 0xf153, 0xf154, 0xf155, 0xf156, 0xf157, 
+    0xf158, 0xf159, 0xf15a, 0xf15b, 0xf15c, 0xf15d, 0xf15e, 0xf15f, 
+    0xf160, 0xf161, 0xf162, 0xf163, 0xf164, 0xf165, 0xf166, 0xf167, 
+    0xf168, 0xf169, 0xf16a, 0xf16b, 0xf16c, 0xf16d, 0xf16e, 0xf16f, 
+    0xf170, 0xf171, 0xf172, 0xf173, 0xf174, 0xf175, 0xf176, 0xf177, 
+    0xf178, 0xf179, 0xf17a, 0xf17b, 0xf17c, 0xf17d, 0xf17e, 0xf17f, 
+    0xf180, 0xf181, 0xf182, 0xf183, 0xf184, 0xf185, 0xf186, 0xf187, 
+    0xf188, 0xf189, 0xf18a, 0xf18b, 0xf18c, 0xf18d, 0xf18e, 0xf18f, 
+    0xf190, 0xf191, 0xf192, 0xf193, 0xf194, 0xf195, 0xf196, 0xf197, 
+    0xf198, 0xf199, 0xf19a, 0xf19b, 0xf19c, 0xf19d, 0xf19e, 0xf19f, 
+    0xf1a0, 0xf1a1, 0xf1a2, 0xf1a3, 0xf1a4, 0xf1a5, 0xf1a6, 0xf1a7, 
+    0xf1a8, 0xf1a9, 0xf1aa, 0xf1ab, 0xf1ac, 0xf1ad, 0xf1ae, 0xf1af, 
+    0xf1b0, 0xf1b1, 0xf1b2, 0xf1b3, 0xf1b4, 0xf1b5, 0xf1b6, 0xf1b7, 
+    0xf1b8, 0xf1b9, 0xf1ba, 0xf1bb, 0xf1bc, 0xf1bd, 0xf1be, 0xf1bf, 
+    0xf1c0, 0xf1c1, 0xf1c2, 0xf1c3, 0xf1c4, 0xf1c5, 0xf1c6, 0xf1c7, 
+    0xf1c8, 0xf1c9, 0xf1ca, 0xf1cb, 0xf1cc, 0xf1cd, 0xf1ce, 0xf1cf, 
+    0xf1d0, 0xf1d1, 0xf1d2, 0xf1d3, 0xf1d4, 0xf1d5, 0xf1d6, 0xf1d7, 
+    0xf1d8, 0xf1d9, 0xf1da, 0xf1db, 0xf1dc, 0xf1dd, 0xf1de, 0xf1df, 
+    0xf1e0, 0xf1e1, 0xf1e2, 0xf1e3, 0xf1e4, 0xf1e5, 0xf1e6, 0xf1e7, 
+    0xf1e8, 0xf1e9, 0xf1ea, 0xf1eb, 0xf1ec, 0xf1ed, 0xf1ee, 0xf1ef, 
+    0xf1f0, 0xf1f1, 0xf1f2, 0xf1f3, 0xf1f4, 0xf1f5, 0xf1f6, 0xf1f7, 
+    0xf1f8, 0xf1f9, 0xf1fa, 0xf1fb, 0xf1fc, 0xf1fd, 0xf1fe, 0xf1ff, 
+    0xf200, 0xf201, 0xf202, 0xf203, 0xf204, 0xf205, 0xf206, 0xf207, 
+    0xf208, 0xf209, 0xf20a, 0xf20b, 0xf20c, 0xf20d, 0xf20e, 0xf20f, 
+    0xf210, 0xf211, 0xf212, 0xf213, 0xf214, 0xf215, 0xf216, 0xf217, 
+    0xf218, 0xf219, 0xf21a, 0xf21b, 0xf21c, 0xf21d, 0xf21e, 0xf21f, 
+    0xf220, 0xf221, 0xf222, 0xf223, 0xf224, 0xf225, 0xf226, 0xf227, 
+    0xf228, 0xf229, 0xf22a, 0xf22b, 0xf22c, 0xf22d, 0xf22e, 0xf22f, 
+    0xf230, 0xf231, 0xf232, 0xf233, 0xf234, 0xf235, 0xf236, 0xf237, 
+    0xf238, 0xf239, 0xf23a, 0xf23b, 0xf23c, 0xf23d, 0xf23e, 0xf23f, 
+    0xf240, 0xf241, 0xf242, 0xf243, 0xf244, 0xf245, 0xf246, 0xf247, 
+    0xf248, 0xf249, 0xf24a, 0xf24b, 0xf24c, 0xf24d, 0xf24e, 0xf24f, 
+    0xf250, 0xf251, 0xf252, 0xf253, 0xf254, 0xf255, 0xf256, 0xf257, 
+    0xf258, 0xf259, 0xf25a, 0xf25b, 0xf25c, 0xf25d, 0xf25e, 0xf25f, 
+    0xf260, 0xf261, 0xf262, 0xf263, 0xf264, 0xf265, 0xf266, 0xf267, 
+    0xf268, 0xf269, 0xf26a, 0xf26b, 0xf26c, 0xf26d, 0xf26e, 0xf26f, 
+    0xf270, 0xf271, 0xf272, 0xf273, 0xf274, 0xf275, 0xf276, 0xf277, 
+    0xf278, 0xf279, 0xf27a, 0xf27b, 0xf27c, 0xf27d, 0xf27e, 0xf27f, 
+    0xf280, 0xf281, 0xf282, 0xf283, 0xf284, 0xf285, 0xf286, 0xf287, 
+    0xf288, 0xf289, 0xf28a, 0xf28b, 0xf28c, 0xf28d, 0xf28e, 0xf28f, 
+    0xf290, 0xf291, 0xf292, 0xf293, 0xf294, 0xf295, 0xf296, 0xf297, 
+    0xf298, 0xf299, 0xf29a, 0xf29b, 0xf29c, 0xf29d, 0xf29e, 0xf29f, 
+    0xf2a0, 0xf2a1, 0xf2a2, 0xf2a3, 0xf2a4, 0xf2a5, 0xf2a6, 0xf2a7, 
+    0xf2a8, 0xf2a9, 0xf2aa, 0xf2ab, 0xf2ac, 0xf2ad, 0xf2ae, 0xf2af, 
+    0xf2b0, 0xf2b1, 0xf2b2, 0xf2b3, 0xf2b4, 0xf2b5, 0xf2b6, 0xf2b7, 
+    0xf2b8, 0xf2b9, 0xf2ba, 0xf2bb, 0xf2bc, 0xf2bd, 0xf2be, 0xf2bf, 
+    0xf2c0, 0xf2c1, 0xf2c2, 0xf2c3, 0xf2c4, 0xf2c5, 0xf2c6, 0xf2c7, 
+    0xf2c8, 0xf2c9, 0xf2ca, 0xf2cb, 0xf2cc, 0xf2cd, 0xf2ce, 0xf2cf, 
+    0xf2d0, 0xf2d1, 0xf2d2, 0xf2d3, 0xf2d4, 0xf2d5, 0xf2d6, 0xf2d7, 
+    0xf2d8, 0xf2d9, 0xf2da, 0xf2db, 0xf2dc, 0xf2dd, 0xf2de, 0xf2df, 
+    0xf2e0, 0xf2e1, 0xf2e2, 0xf2e3, 0xf2e4, 0xf2e5, 0xf2e6, 0xf2e7, 
+    0xf2e8, 0xf2e9, 0xf2ea, 0xf2eb, 0xf2ec, 0xf2ed, 0xf2ee, 0xf2ef, 
+    0xf2f0, 0xf2f1, 0xf2f2, 0xf2f3, 0xf2f4, 0xf2f5, 0xf2f6, 0xf2f7, 
+    0xf2f8, 0xf2f9, 0xf2fa, 0xf2fb, 0xf2fc, 0xf2fd, 0xf2fe, 0xf2ff, 
+    0xf300, 0xf301, 0xf302, 0xf303, 0xf304, 0xf305, 0xf306, 0xf307, 
+    0xf308, 0xf309, 0xf30a, 0xf30b, 0xf30c, 0xf30d, 0xf30e, 0xf30f, 
+    0xf310, 0xf311, 0xf312, 0xf313, 0xf314, 0xf315, 0xf316, 0xf317, 
+    0xf318, 0xf319, 0xf31a, 0xf31b, 0xf31c, 0xf31d, 0xf31e, 0xf31f, 
+    0xf320, 0xf321, 0xf322, 0xf323, 0xf324, 0xf325, 0xf326, 0xf327, 
+    0xf328, 0xf329, 0xf32a, 0xf32b, 0xf32c, 0xf32d, 0xf32e, 0xf32f, 
+    0xf330, 0xf331, 0xf332, 0xf333, 0xf334, 0xf335, 0xf336, 0xf337, 
+    0xf338, 0xf339, 0xf33a, 0xf33b, 0xf33c, 0xf33d, 0xf33e, 0xf33f, 
+    0xf340, 0xf341, 0xf342, 0xf343, 0xf344, 0xf345, 0xf346, 0xf347, 
+    0xf348, 0xf349, 0xf34a, 0xf34b, 0xf34c, 0xf34d, 0xf34e, 0xf34f, 
+    0xf350, 0xf351, 0xf352, 0xf353, 0xf354, 0xf355, 0xf356, 0xf357, 
+    0xf358, 0xf359, 0xf35a, 0xf35b, 0xf35c, 0xf35d, 0xf35e, 0xf35f, 
+    0xf360, 0xf361, 0xf362, 0xf363, 0xf364, 0xf365, 0xf366, 0xf367, 
+    0xf368, 0xf369, 0xf36a, 0xf36b, 0xf36c, 0xf36d, 0xf36e, 0xf36f, 
+    0xf370, 0xf371, 0xf372, 0xf373, 0xf374, 0xf375, 0xf376, 0xf377, 
+    0xf378, 0xf379, 0xf37a, 0xf37b, 0xf37c, 0xf37d, 0xf37e, 0xf37f, 
+    0xf380, 0xf381, 0xf382, 0xf383, 0xf384, 0xf385, 0xf386, 0xf387, 
+    0xf388, 0xf389, 0xf38a, 0xf38b, 0xf38c, 0xf38d, 0xf38e, 0xf38f, 
+    0xf390, 0xf391, 0xf392, 0xf393, 0xf394, 0xf395, 0xf396, 0xf397, 
+    0xf398, 0xf399, 0xf39a, 0xf39b, 0xf39c, 0xf39d, 0xf39e, 0xf39f, 
+    0xf3a0, 0xf3a1, 0xf3a2, 0xf3a3, 0xf3a4, 0xf3a5, 0xf3a6, 0xf3a7, 
+    0xf3a8, 0xf3a9, 0xf3aa, 0xf3ab, 0xf3ac, 0xf3ad, 0xf3ae, 0xf3af, 
+    0xf3b0, 0xf3b1, 0xf3b2, 0xf3b3, 0xf3b4, 0xf3b5, 0xf3b6, 0xf3b7, 
+    0xf3b8, 0xf3b9, 0xf3ba, 0xf3bb, 0xf3bc, 0xf3bd, 0xf3be, 0xf3bf, 
+    0xf3c0, 0xf3c1, 0xf3c2, 0xf3c3, 0xf3c4, 0xf3c5, 0xf3c6, 0xf3c7, 
+    0xf3c8, 0xf3c9, 0xf3ca, 0xf3cb, 0xf3cc, 0xf3cd, 0xf3ce, 0xf3cf, 
+    0xf3d0, 0xf3d1, 0xf3d2, 0xf3d3, 0xf3d4, 0xf3d5, 0xf3d6, 0xf3d7, 
+    0xf3d8, 0xf3d9, 0xf3da, 0xf3db, 0xf3dc, 0xf3dd, 0xf3de, 0xf3df, 
+    0xf3e0, 0xf3e1, 0xf3e2, 0xf3e3, 0xf3e4, 0xf3e5, 0xf3e6, 0xf3e7, 
+    0xf3e8, 0xf3e9, 0xf3ea, 0xf3eb, 0xf3ec, 0xf3ed, 0xf3ee, 0xf3ef, 
+    0xf3f0, 0xf3f1, 0xf3f2, 0xf3f3, 0xf3f4, 0xf3f5, 0xf3f6, 0xf3f7, 
+    0xf3f8, 0xf3f9, 0xf3fa, 0xf3fb, 0xf3fc, 0xf3fd, 0xf3fe, 0xf3ff, 
+    0xf400, 0xf401, 0xf402, 0xf403, 0xf404, 0xf405, 0xf406, 0xf407, 
+    0xf408, 0xf409, 0xf40a, 0xf40b, 0xf40c, 0xf40d, 0xf40e, 0xf40f, 
+    0xf410, 0xf411, 0xf412, 0xf413, 0xf414, 0xf415, 0xf416, 0xf417, 
+    0xf418, 0xf419, 0xf41a, 0xf41b, 0xf41c, 0xf41d, 0xf41e, 0xf41f, 
+    0xf420, 0xf421, 0xf422, 0xf423, 0xf424, 0xf425, 0xf426, 0xf427, 
+    0xf428, 0xf429, 0xf42a, 0xf42b, 0xf42c, 0xf42d, 0xf42e, 0xf42f, 
+    0xf430, 0xf431, 0xf432, 0xf433, 0xf434, 0xf435, 0xf436, 0xf437, 
+    0xf438, 0xf439, 0xf43a, 0xf43b, 0xf43c, 0xf43d, 0xf43e, 0xf43f, 
+    0xf440, 0xf441, 0xf442, 0xf443, 0xf444, 0xf445, 0xf446, 0xf447, 
+    0xf448, 0xf449, 0xf44a, 0xf44b, 0xf44c, 0xf44d, 0xf44e, 0xf44f, 
+    0xf450, 0xf451, 0xf452, 0xf453, 0xf454, 0xf455, 0xf456, 0xf457, 
+    0xf458, 0xf459, 0xf45a, 0xf45b, 0xf45c, 0xf45d, 0xf45e, 0xf45f, 
+    0xf460, 0xf461, 0xf462, 0xf463, 0xf464, 0xf465, 0xf466, 0xf467, 
+    0xf468, 0xf469, 0xf46a, 0xf46b, 0xf46c, 0xf46d, 0xf46e, 0xf46f, 
+    0xf470, 0xf471, 0xf472, 0xf473, 0xf474, 0xf475, 0xf476, 0xf477, 
+    0xf478, 0xf479, 0xf47a, 0xf47b, 0xf47c, 0xf47d, 0xf47e, 0xf47f, 
+    0xf480, 0xf481, 0xf482, 0xf483, 0xf484, 0xf485, 0xf486, 0xf487, 
+    0xf488, 0xf489, 0xf48a, 0xf48b, 0xf48c, 0xf48d, 0xf48e, 0xf48f, 
+    0xf490, 0xf491, 0xf492, 0xf493, 0xf494, 0xf495, 0xf496, 0xf497, 
+    0xf498, 0xf499, 0xf49a, 0xf49b, 0xf49c, 0xf49d, 0xf49e, 0xf49f, 
+    0xf4a0, 0xf4a1, 0xf4a2, 0xf4a3, 0xf4a4, 0xf4a5, 0xf4a6, 0xf4a7, 
+    0xf4a8, 0xf4a9, 0xf4aa, 0xf4ab, 0xf4ac, 0xf4ad, 0xf4ae, 0xf4af, 
+    0xf4b0, 0xf4b1, 0xf4b2, 0xf4b3, 0xf4b4, 0xf4b5, 0xf4b6, 0xf4b7, 
+    0xf4b8, 0xf4b9, 0xf4ba, 0xf4bb, 0xf4bc, 0xf4bd, 0xf4be, 0xf4bf, 
+    0xf4c0, 0xf4c1, 0xf4c2, 0xf4c3, 0xf4c4, 0xf4c5, 0xf4c6, 0xf4c7, 
+    0xf4c8, 0xf4c9, 0xf4ca, 0xf4cb, 0xf4cc, 0xf4cd, 0xf4ce, 0xf4cf, 
+    0xf4d0, 0xf4d1, 0xf4d2, 0xf4d3, 0xf4d4, 0xf4d5, 0xf4d6, 0xf4d7, 
+    0xf4d8, 0xf4d9, 0xf4da, 0xf4db, 0xf4dc, 0xf4dd, 0xf4de, 0xf4df, 
+    0xf4e0, 0xf4e1, 0xf4e2, 0xf4e3, 0xf4e4, 0xf4e5, 0xf4e6, 0xf4e7, 
+    0xf4e8, 0xf4e9, 0xf4ea, 0xf4eb, 0xf4ec, 0xf4ed, 0xf4ee, 0xf4ef, 
+    0xf4f0, 0xf4f1, 0xf4f2, 0xf4f3, 0xf4f4, 0xf4f5, 0xf4f6, 0xf4f7, 
+    0xf4f8, 0xf4f9, 0xf4fa, 0xf4fb, 0xf4fc, 0xf4fd, 0xf4fe, 0xf4ff, 
+    0xf500, 0xf501, 0xf502, 0xf503, 0xf504, 0xf505, 0xf506, 0xf507, 
+    0xf508, 0xf509, 0xf50a, 0xf50b, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 
+    0xf510, 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf516, 0xf517, 
+    0xf518, 0xf519, 0xf51a, 0xf51b, 0xf51c, 0xf51d, 0xf51e, 0xf51f, 
+    0xf520, 0xf521, 0xf522, 0xf523, 0xf524, 0xf525, 0xf526, 0xf527, 
+    0xf528, 0xf529, 0xf52a, 0xf52b, 0xf52c, 0xf52d, 0xf52e, 0xf52f, 
+    0xf530, 0xf531, 0xf532, 0xf533, 0xf534, 0xf535, 0xf536, 0xf537, 
+    0xf538, 0xf539, 0xf53a, 0xf53b, 0xf53c, 0xf53d, 0xf53e, 0xf53f, 
+    0xf540, 0xf541, 0xf542, 0xf543, 0xf544, 0xf545, 0xf546, 0xf547, 
+    0xf548, 0xf549, 0xf54a, 0xf54b, 0xf54c, 0xf54d, 0xf54e, 0xf54f, 
+    0xf550, 0xf551, 0xf552, 0xf553, 0xf554, 0xf555, 0xf556, 0xf557, 
+    0xf558, 0xf559, 0xf55a, 0xf55b, 0xf55c, 0xf55d, 0xf55e, 0xf55f, 
+    0xf560, 0xf561, 0xf562, 0xf563, 0xf564, 0xf565, 0xf566, 0xf567, 
+    0xf568, 0xf569, 0xf56a, 0xf56b, 0xf56c, 0xf56d, 0xf56e, 0xf56f, 
+    0xf570, 0xf571, 0xf572, 0xf573, 0xf574, 0xf575, 0xf576, 0xf577, 
+    0xf578, 0xf579, 0xf57a, 0xf57b, 0xf57c, 0xf57d, 0xf57e, 0xf57f, 
+    0xf580, 0xf581, 0xf582, 0xf583, 0xf584, 0xf585, 0xf586, 0xf587, 
+    0xf588, 0xf589, 0xf58a, 0xf58b, 0xf58c, 0xf58d, 0xf58e, 0xf58f, 
+    0xf590, 0xf591, 0xf592, 0xf593, 0xf594, 0xf595, 0xf596, 0xf597, 
+    0xf598, 0xf599, 0xf59a, 0xf59b, 0xf59c, 0xf59d, 0xf59e, 0xf59f, 
+    0xf5a0, 0xf5a1, 0xf5a2, 0xf5a3, 0xf5a4, 0xf5a5, 0xf5a6, 0xf5a7, 
+    0xf5a8, 0xf5a9, 0xf5aa, 0xf5ab, 0xf5ac, 0xf5ad, 0xf5ae, 0xf5af, 
+    0xf5b0, 0xf5b1, 0xf5b2, 0xf5b3, 0xf5b4, 0xf5b5, 0xf5b6, 0xf5b7, 
+    0xf5b8, 0xf5b9, 0xf5ba, 0xf5bb, 0xf5bc, 0xf5bd, 0xf5be, 0xf5bf, 
+    0xf5c0, 0xf5c1, 0xf5c2, 0xf5c3, 0xf5c4, 0xf5c5, 0xf5c6, 0xf5c7, 
+    0xf5c8, 0xf5c9, 0xf5ca, 0xf5cb, 0xf5cc, 0xf5cd, 0xf5ce, 0xf5cf, 
+    0xf5d0, 0xf5d1, 0xf5d2, 0xf5d3, 0xf5d4, 0xf5d5, 0xf5d6, 0xf5d7, 
+    0xf5d8, 0xf5d9, 0xf5da, 0xf5db, 0xf5dc, 0xf5dd, 0xf5de, 0xf5df, 
+    0xf5e0, 0xf5e1, 0xf5e2, 0xf5e3, 0xf5e4, 0xf5e5, 0xf5e6, 0xf5e7, 
+    0xf5e8, 0xf5e9, 0xf5ea, 0xf5eb, 0xf5ec, 0xf5ed, 0xf5ee, 0xf5ef, 
+    0xf5f0, 0xf5f1, 0xf5f2, 0xf5f3, 0xf5f4, 0xf5f5, 0xf5f6, 0xf5f7, 
+    0xf5f8, 0xf5f9, 0xf5fa, 0xf5fb, 0xf5fc, 0xf5fd, 0xf5fe, 0xf5ff, 
+    0xf600, 0xf601, 0xf602, 0xf603, 0xf604, 0xf605, 0xf606, 0xf607, 
+    0xf608, 0xf609, 0xf60a, 0xf60b, 0xf60c, 0xf60d, 0xf60e, 0xf60f, 
+    0xf610, 0xf611, 0xf612, 0xf613, 0xf614, 0xf615, 0xf616, 0xf617, 
+    0xf618, 0xf619, 0xf61a, 0xf61b, 0xf61c, 0xf61d, 0xf61e, 0xf61f, 
+    0xf620, 0xf621, 0xf622, 0xf623, 0xf624, 0xf625, 0xf626, 0xf627, 
+    0xf628, 0xf629, 0xf62a, 0xf62b, 0xf62c, 0xf62d, 0xf62e, 0xf62f, 
+    0xf630, 0xf631, 0xf632, 0xf633, 0xf634, 0xf635, 0xf636, 0xf637, 
+    0xf638, 0xf639, 0xf63a, 0xf63b, 0xf63c, 0xf63d, 0xf63e, 0xf63f, 
+    0xf640, 0xf641, 0xf642, 0xf643, 0xf644, 0xf645, 0xf646, 0xf647, 
+    0xf648, 0xf649, 0xf64a, 0xf64b, 0xf64c, 0xf64d, 0xf64e, 0xf64f, 
+    0xf650, 0xf651, 0xf652, 0xf653, 0xf654, 0xf655, 0xf656, 0xf657, 
+    0xf658, 0xf659, 0xf65a, 0xf65b, 0xf65c, 0xf65d, 0xf65e, 0xf65f, 
+    0xf660, 0xf661, 0xf662, 0xf663, 0xf664, 0xf665, 0xf666, 0xf667, 
+    0xf668, 0xf669, 0xf66a, 0xf66b, 0xf66c, 0xf66d, 0xf66e, 0xf66f, 
+    0xf670, 0xf671, 0xf672, 0xf673, 0xf674, 0xf675, 0xf676, 0xf677, 
+    0xf678, 0xf679, 0xf67a, 0xf67b, 0xf67c, 0xf67d, 0xf67e, 0xf67f, 
+    0xf680, 0xf681, 0xf682, 0xf683, 0xf684, 0xf685, 0xf686, 0xf687, 
+    0xf688, 0xf689, 0xf68a, 0xf68b, 0xf68c, 0xf68d, 0xf68e, 0xf68f, 
+    0xf690, 0xf691, 0xf692, 0xf693, 0xf694, 0xf695, 0xf696, 0xf697, 
+    0xf698, 0xf699, 0xf69a, 0xf69b, 0xf69c, 0xf69d, 0xf69e, 0xf69f, 
+    0xf6a0, 0xf6a1, 0xf6a2, 0xf6a3, 0xf6a4, 0xf6a5, 0xf6a6, 0xf6a7, 
+    0xf6a8, 0xf6a9, 0xf6aa, 0xf6ab, 0xf6ac, 0xf6ad, 0xf6ae, 0xf6af, 
+    0xf6b0, 0xf6b1, 0xf6b2, 0xf6b3, 0xf6b4, 0xf6b5, 0xf6b6, 0xf6b7, 
+    0xf6b8, 0xf6b9, 0xf6ba, 0xf6bb, 0xf6bc, 0xf6bd, 0xf6be, 0xf6bf, 
+    0xf6c0, 0xf6c1, 0xf6c2, 0xf6c3, 0xf6c4, 0xf6c5, 0xf6c6, 0xf6c7, 
+    0xf6c8, 0xf6c9, 0xf6ca, 0xf6cb, 0xf6cc, 0xf6cd, 0xf6ce, 0xf6cf, 
+    0xf6d0, 0xf6d1, 0xf6d2, 0xf6d3, 0xf6d4, 0xf6d5, 0xf6d6, 0xf6d7, 
+    0xf6d8, 0xf6d9, 0xf6da, 0xf6db, 0xf6dc, 0xf6dd, 0xf6de, 0xf6df, 
+    0xf6e0, 0xf6e1, 0xf6e2, 0xf6e3, 0xf6e4, 0xf6e5, 0xf6e6, 0xf6e7, 
+    0xf6e8, 0xf6e9, 0xf6ea, 0xf6eb, 0xf6ec, 0xf6ed, 0xf6ee, 0xf6ef, 
+    0xf6f0, 0xf6f1, 0xf6f2, 0xf6f3, 0xf6f4, 0xf6f5, 0xf6f6, 0xf6f7, 
+    0xf6f8, 0xf6f9, 0xf6fa, 0xf6fb, 0xf6fc, 0xf6fd, 0xf6fe, 0xf6ff, 
+    0xf700, 0xf701, 0xf702, 0xf703, 0xf704, 0xf705, 0xf706, 0xf707, 
+    0xf708, 0xf709, 0xf70a, 0xf70b, 0xf70c, 0xf70d, 0xf70e, 0xf70f, 
+    0xf710, 0xf711, 0xf712, 0xf713, 0xf714, 0xf715, 0xf716, 0xf717, 
+    0xf718, 0xf719, 0xf71a, 0xf71b, 0xf71c, 0xf71d, 0xf71e, 0xf71f, 
+    0xf720, 0xf721, 0xf722, 0xf723, 0xf724, 0xf725, 0xf726, 0xf727, 
+    0xf728, 0xf729, 0xf72a, 0xf72b, 0xf72c, 0xf72d, 0xf72e, 0xf72f, 
+    0xf730, 0xf731, 0xf732, 0xf733, 0xf734, 0xf735, 0xf736, 0xf737, 
+    0xf738, 0xf739, 0xf73a, 0xf73b, 0xf73c, 0xf73d, 0xf73e, 0xf73f, 
+    0xf740, 0xf741, 0xf742, 0xf743, 0xf744, 0xf745, 0xf746, 0xf747, 
+    0xf748, 0xf749, 0xf74a, 0xf74b, 0xf74c, 0xf74d, 0xf74e, 0xf74f, 
+    0xf750, 0xf751, 0xf752, 0xf753, 0xf754, 0xf755, 0xf756, 0xf757, 
+    0xf758, 0xf759, 0xf75a, 0xf75b, 0xf75c, 0xf75d, 0xf75e, 0xf75f, 
+    0xf760, 0xf761, 0xf762, 0xf763, 0xf764, 0xf765, 0xf766, 0xf767, 
+    0xf768, 0xf769, 0xf76a, 0xf76b, 0xf76c, 0xf76d, 0xf76e, 0xf76f, 
+    0xf770, 0xf771, 0xf772, 0xf773, 0xf774, 0xf775, 0xf776, 0xf777, 
+    0xf778, 0xf779, 0xf77a, 0xf77b, 0xf77c, 0xf77d, 0xf77e, 0xf77f, 
+    0xf780, 0xf781, 0xf782, 0xf783, 0xf784, 0xf785, 0xf786, 0xf787, 
+    0xf788, 0xf789, 0xf78a, 0xf78b, 0xf78c, 0xf78d, 0xf78e, 0xf78f, 
+    0xf790, 0xf791, 0xf792, 0xf793, 0xf794, 0xf795, 0xf796, 0xf797, 
+    0xf798, 0xf799, 0xf79a, 0xf79b, 0xf79c, 0xf79d, 0xf79e, 0xf79f, 
+    0xf7a0, 0xf7a1, 0xf7a2, 0xf7a3, 0xf7a4, 0xf7a5, 0xf7a6, 0xf7a7, 
+    0xf7a8, 0xf7a9, 0xf7aa, 0xf7ab, 0xf7ac, 0xf7ad, 0xf7ae, 0xf7af, 
+    0xf7b0, 0xf7b1, 0xf7b2, 0xf7b3, 0xf7b4, 0xf7b5, 0xf7b6, 0xf7b7, 
+    0xf7b8, 0xf7b9, 0xf7ba, 0xf7bb, 0xf7bc, 0xf7bd, 0xf7be, 0xf7bf, 
+    0xf7c0, 0xf7c1, 0xf7c2, 0xf7c3, 0xf7c4, 0xf7c5, 0xf7c6, 0xf7c7, 
+    0xf7c8, 0xf7c9, 0xf7ca, 0xf7cb, 0xf7cc, 0xf7cd, 0xf7ce, 0xf7cf, 
+    0xf7d0, 0xf7d1, 0xf7d2, 0xf7d3, 0xf7d4, 0xf7d5, 0xf7d6, 0xf7d7, 
+    0xf7d8, 0xf7d9, 0xf7da, 0xf7db, 0xf7dc, 0xf7dd, 0xf7de, 0xf7df, 
+    0xf7e0, 0xf7e1, 0xf7e2, 0xf7e3, 0xf7e4, 0xf7e5, 0xf7e6, 0xf7e7, 
+    0xf7e8, 0xf7e9, 0xf7ea, 0xf7eb, 0xf7ec, 0xf7ed, 0xf7ee, 0xf7ef, 
+    0xf7f0, 0xf7f1, 0xf7f2, 0xf7f3, 0xf7f4, 0xf7f5, 0xf7f6, 0xf7f7, 
+    0xf7f8, 0xf7f9, 0xf7fa, 0xf7fb, 0xf7fc, 0xf7fd, 0xf7fe, 0xf7ff, 
+    0xf800, 0xf801, 0xf802, 0xf803, 0xf804, 0xf805, 0xf806, 0xf807, 
+    0xf808, 0xf809, 0xf80a, 0xf80b, 0xf80c, 0xf80d, 0xf80e, 0xf80f, 
+    0xf810, 0xf811, 0xf812, 0xf813, 0xf814, 0xf815, 0xf816, 0xf817, 
+    0xf818, 0xf819, 0xf81a, 0xf81b, 0xf81c, 0xf81d, 0xf81e, 0xf81f, 
+    0xf820, 0xf821, 0xf822, 0xf823, 0xf824, 0xf825, 0xf826, 0xf827, 
+    0xf828, 0xf829, 0xf82a, 0xf82b, 0xf82c, 0xf82d, 0xf82e, 0xf82f, 
+    0xf830, 0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836, 0xf837, 
+    0xf838, 0xf839, 0xf83a, 0xf83b, 0xf83c, 0xf83d, 0xf83e, 0xf83f, 
+    0xf840, 0xf841, 0xf842, 0xf843, 0xf844, 0xf845, 0xf846, 0xf847, 
+    0xf848, 0xf849, 0xf84a, 0xf84b, 0xf84c, 0xf84d, 0xf84e, 0xf84f, 
+    0xf850, 0xf851, 0xf852, 0xf853, 0xf854, 0xf855, 0xf856, 0xf857, 
+    0xf858, 0xf859, 0xf85a, 0xf85b, 0xf85c, 0xf85d, 0xf85e, 0xf85f, 
+    0xf860, 0xf861, 0xf862, 0xf863, 0xf864, 0xf865, 0xf866, 0xf867, 
+    0xf868, 0xf869, 0xf86a, 0xf86b, 0xf86c, 0xf86d, 0xf86e, 0xf86f, 
+    0xf870, 0xf871, 0xf872, 0xf873, 0xf874, 0xf875, 0xf876, 0xf877, 
+    0xf878, 0xf879, 0xf87a, 0xf87b, 0xf87c, 0xf87d, 0xf87e, 0xf87f, 
+    0xf880, 0xf881, 0xf882, 0xf883, 0xf884, 0xf885, 0xf886, 0xf887, 
+    0xf888, 0xf889, 0xf88a, 0xf88b, 0xf88c, 0xf88d, 0xf88e, 0xf88f, 
+    0xf890, 0xf891, 0xf892, 0xf893, 0xf894, 0xf895, 0xf896, 0xf897, 
+    0xf898, 0xf899, 0xf89a, 0xf89b, 0xf89c, 0xf89d, 0xf89e, 0xf89f, 
+    0xf8a0, 0xf8a1, 0xf8a2, 0xf8a3, 0xf8a4, 0xf8a5, 0xf8a6, 0xf8a7, 
+    0xf8a8, 0xf8a9, 0xf8aa, 0xf8ab, 0xf8ac, 0xf8ad, 0xf8ae, 0xf8af, 
+    0xf8b0, 0xf8b1, 0xf8b2, 0xf8b3, 0xf8b4, 0xf8b5, 0xf8b6, 0xf8b7, 
+    0xf8b8, 0xf8b9, 0xf8ba, 0xf8bb, 0xf8bc, 0xf8bd, 0xf8be, 0xf8bf, 
+    0xf8c0, 0xf8c1, 0xf8c2, 0xf8c3, 0xf8c4, 0xf8c5, 0xf8c6, 0xf8c7, 
+    0xf8c8, 0xf8c9, 0xf8ca, 0xf8cb, 0xf8cc, 0xf8cd, 0xf8ce, 0xf8cf, 
+    0xf8d0, 0xf8d1, 0xf8d2, 0xf8d3, 0xf8d4, 0xf8d5, 0xf8d6, 0xf8d7, 
+    0xf8d8, 0xf8d9, 0xf8da, 0xf8db, 0xf8dc, 0xf8dd, 0xf8de, 0xf8df, 
+    0xf8e0, 0xf8e1, 0xf8e2, 0xf8e3, 0xf8e4, 0xf8e5, 0xf8e6, 0xf8e7, 
+    0xf8e8, 0xf8e9, 0xf8ea, 0xf8eb, 0xf8ec, 0xf8ed, 0xf8ee, 0xf8ef, 
+    0xf8f0, 0xf8f1, 0xf8f2, 0xf8f3, 0xf8f4, 0xf8f5, 0xf8f6, 0xf8f7, 
+    0xf8f8, 0xf8f9, 0xf8fa, 0xf8fb, 0xf8fc, 0xf8fd, 0xf8fe, 0xf8ff, 
+    0xf900, 0xf901, 0xf902, 0xf903, 0xf904, 0xf905, 0xf906, 0xf907, 
+    0xf908, 0xf909, 0xf90a, 0xf90b, 0xf90c, 0xf90d, 0xf90e, 0xf90f, 
+    0xf910, 0xf911, 0xf912, 0xf913, 0xf914, 0xf915, 0xf916, 0xf917, 
+    0xf918, 0xf919, 0xf91a, 0xf91b, 0xf91c, 0xf91d, 0xf91e, 0xf91f, 
+    0xf920, 0xf921, 0xf922, 0xf923, 0xf924, 0xf925, 0xf926, 0xf927, 
+    0xf928, 0xf929, 0xf92a, 0xf92b, 0xf92c, 0xf92d, 0xf92e, 0xf92f, 
+    0xf930, 0xf931, 0xf932, 0xf933, 0xf934, 0xf935, 0xf936, 0xf937, 
+    0xf938, 0xf939, 0xf93a, 0xf93b, 0xf93c, 0xf93d, 0xf93e, 0xf93f, 
+    0xf940, 0xf941, 0xf942, 0xf943, 0xf944, 0xf945, 0xf946, 0xf947, 
+    0xf948, 0xf949, 0xf94a, 0xf94b, 0xf94c, 0xf94d, 0xf94e, 0xf94f, 
+    0xf950, 0xf951, 0xf952, 0xf953, 0xf954, 0xf955, 0xf956, 0xf957, 
+    0xf958, 0xf959, 0xf95a, 0xf95b, 0xf95c, 0xf95d, 0xf95e, 0xf95f, 
+    0xf960, 0xf961, 0xf962, 0xf963, 0xf964, 0xf965, 0xf966, 0xf967, 
+    0xf968, 0xf969, 0xf96a, 0xf96b, 0xf96c, 0xf96d, 0xf96e, 0xf96f, 
+    0xf970, 0xf971, 0xf972, 0xf973, 0xf974, 0xf975, 0xf976, 0xf977, 
+    0xf978, 0xf979, 0xf97a, 0xf97b, 0xf97c, 0xf97d, 0xf97e, 0xf97f, 
+    0xf980, 0xf981, 0xf982, 0xf983, 0xf984, 0xf985, 0xf986, 0xf987, 
+    0xf988, 0xf989, 0xf98a, 0xf98b, 0xf98c, 0xf98d, 0xf98e, 0xf98f, 
+    0xf990, 0xf991, 0xf992, 0xf993, 0xf994, 0xf995, 0xf996, 0xf997, 
+    0xf998, 0xf999, 0xf99a, 0xf99b, 0xf99c, 0xf99d, 0xf99e, 0xf99f, 
+    0xf9a0, 0xf9a1, 0xf9a2, 0xf9a3, 0xf9a4, 0xf9a5, 0xf9a6, 0xf9a7, 
+    0xf9a8, 0xf9a9, 0xf9aa, 0xf9ab, 0xf9ac, 0xf9ad, 0xf9ae, 0xf9af, 
+    0xf9b0, 0xf9b1, 0xf9b2, 0xf9b3, 0xf9b4, 0xf9b5, 0xf9b6, 0xf9b7, 
+    0xf9b8, 0xf9b9, 0xf9ba, 0xf9bb, 0xf9bc, 0xf9bd, 0xf9be, 0xf9bf, 
+    0xf9c0, 0xf9c1, 0xf9c2, 0xf9c3, 0xf9c4, 0xf9c5, 0xf9c6, 0xf9c7, 
+    0xf9c8, 0xf9c9, 0xf9ca, 0xf9cb, 0xf9cc, 0xf9cd, 0xf9ce, 0xf9cf, 
+    0xf9d0, 0xf9d1, 0xf9d2, 0xf9d3, 0xf9d4, 0xf9d5, 0xf9d6, 0xf9d7, 
+    0xf9d8, 0xf9d9, 0xf9da, 0xf9db, 0xf9dc, 0xf9dd, 0xf9de, 0xf9df, 
+    0xf9e0, 0xf9e1, 0xf9e2, 0xf9e3, 0xf9e4, 0xf9e5, 0xf9e6, 0xf9e7, 
+    0xf9e8, 0xf9e9, 0xf9ea, 0xf9eb, 0xf9ec, 0xf9ed, 0xf9ee, 0xf9ef, 
+    0xf9f0, 0xf9f1, 0xf9f2, 0xf9f3, 0xf9f4, 0xf9f5, 0xf9f6, 0xf9f7, 
+    0xf9f8, 0xf9f9, 0xf9fa, 0xf9fb, 0xf9fc, 0xf9fd, 0xf9fe, 0xf9ff, 
+    0xfa00, 0xfa01, 0xfa02, 0xfa03, 0xfa04, 0xfa05, 0xfa06, 0xfa07, 
+    0xfa08, 0xfa09, 0xfa0a, 0xfa0b, 0xfa0c, 0xfa0d, 0xfa0e, 0xfa0f, 
+    0xfa10, 0xfa11, 0xfa12, 0xfa13, 0xfa14, 0xfa15, 0xfa16, 0xfa17, 
+    0xfa18, 0xfa19, 0xfa1a, 0xfa1b, 0xfa1c, 0xfa1d, 0xfa1e, 0xfa1f, 
+    0xfa20, 0xfa21, 0xfa22, 0xfa23, 0xfa24, 0xfa25, 0xfa26, 0xfa27, 
+    0xfa28, 0xfa29, 0xfa2a, 0xfa2b, 0xfa2c, 0xfa2d, 0xfa2e, 0xfa2f, 
+    0xfa30, 0xfa31, 0xfa32, 0xfa33, 0xfa34, 0xfa35, 0xfa36, 0xfa37, 
+    0xfa38, 0xfa39, 0xfa3a, 0xfa3b, 0xfa3c, 0xfa3d, 0xfa3e, 0xfa3f, 
+    0xfa40, 0xfa41, 0xfa42, 0xfa43, 0xfa44, 0xfa45, 0xfa46, 0xfa47, 
+    0xfa48, 0xfa49, 0xfa4a, 0xfa4b, 0xfa4c, 0xfa4d, 0xfa4e, 0xfa4f, 
+    0xfa50, 0xfa51, 0xfa52, 0xfa53, 0xfa54, 0xfa55, 0xfa56, 0xfa57, 
+    0xfa58, 0xfa59, 0xfa5a, 0xfa5b, 0xfa5c, 0xfa5d, 0xfa5e, 0xfa5f, 
+    0xfa60, 0xfa61, 0xfa62, 0xfa63, 0xfa64, 0xfa65, 0xfa66, 0xfa67, 
+    0xfa68, 0xfa69, 0xfa6a, 0xfa6b, 0xfa6c, 0xfa6d, 0xfa6e, 0xfa6f, 
+    0xfa70, 0xfa71, 0xfa72, 0xfa73, 0xfa74, 0xfa75, 0xfa76, 0xfa77, 
+    0xfa78, 0xfa79, 0xfa7a, 0xfa7b, 0xfa7c, 0xfa7d, 0xfa7e, 0xfa7f, 
+    0xfa80, 0xfa81, 0xfa82, 0xfa83, 0xfa84, 0xfa85, 0xfa86, 0xfa87, 
+    0xfa88, 0xfa89, 0xfa8a, 0xfa8b, 0xfa8c, 0xfa8d, 0xfa8e, 0xfa8f, 
+    0xfa90, 0xfa91, 0xfa92, 0xfa93, 0xfa94, 0xfa95, 0xfa96, 0xfa97, 
+    0xfa98, 0xfa99, 0xfa9a, 0xfa9b, 0xfa9c, 0xfa9d, 0xfa9e, 0xfa9f, 
+    0xfaa0, 0xfaa1, 0xfaa2, 0xfaa3, 0xfaa4, 0xfaa5, 0xfaa6, 0xfaa7, 
+    0xfaa8, 0xfaa9, 0xfaaa, 0xfaab, 0xfaac, 0xfaad, 0xfaae, 0xfaaf, 
+    0xfab0, 0xfab1, 0xfab2, 0xfab3, 0xfab4, 0xfab5, 0xfab6, 0xfab7, 
+    0xfab8, 0xfab9, 0xfaba, 0xfabb, 0xfabc, 0xfabd, 0xfabe, 0xfabf, 
+    0xfac0, 0xfac1, 0xfac2, 0xfac3, 0xfac4, 0xfac5, 0xfac6, 0xfac7, 
+    0xfac8, 0xfac9, 0xfaca, 0xfacb, 0xfacc, 0xfacd, 0xface, 0xfacf, 
+    0xfad0, 0xfad1, 0xfad2, 0xfad3, 0xfad4, 0xfad5, 0xfad6, 0xfad7, 
+    0xfad8, 0xfad9, 0xfada, 0xfadb, 0xfadc, 0xfadd, 0xfade, 0xfadf, 
+    0xfae0, 0xfae1, 0xfae2, 0xfae3, 0xfae4, 0xfae5, 0xfae6, 0xfae7, 
+    0xfae8, 0xfae9, 0xfaea, 0xfaeb, 0xfaec, 0xfaed, 0xfaee, 0xfaef, 
+    0xfaf0, 0xfaf1, 0xfaf2, 0xfaf3, 0xfaf4, 0xfaf5, 0xfaf6, 0xfaf7, 
+    0xfaf8, 0xfaf9, 0xfafa, 0xfafb, 0xfafc, 0xfafd, 0xfafe, 0xfaff, 
+    0xfb00, 0xfb01, 0xfb02, 0xfb03, 0xfb04, 0xfb05, 0xfb06, 0xfb07, 
+    0xfb08, 0xfb09, 0xfb0a, 0xfb0b, 0xfb0c, 0xfb0d, 0xfb0e, 0xfb0f, 
+    0xfb10, 0xfb11, 0xfb12, 0xfb13, 0xfb14, 0xfb15, 0xfb16, 0xfb17, 
+    0xfb18, 0xfb19, 0xfb1a, 0xfb1b, 0xfb1c, 0xfb1d, 0xfb1e, 0xfb1f, 
+    0xfb20, 0xfb21, 0xfb22, 0xfb23, 0xfb24, 0xfb25, 0xfb26, 0xfb27, 
+    0xfb28, 0xfb29, 0xfb2a, 0xfb2b, 0xfb2c, 0xfb2d, 0xfb2e, 0xfb2f, 
+    0xfb30, 0xfb31, 0xfb32, 0xfb33, 0xfb34, 0xfb35, 0xfb36, 0xfb37, 
+    0xfb38, 0xfb39, 0xfb3a, 0xfb3b, 0xfb3c, 0xfb3d, 0xfb3e, 0xfb3f, 
+    0xfb40, 0xfb41, 0xfb42, 0xfb43, 0xfb44, 0xfb45, 0xfb46, 0xfb47, 
+    0xfb48, 0xfb49, 0xfb4a, 0xfb4b, 0xfb4c, 0xfb4d, 0xfb4e, 0xfb4f, 
+    0xfb50, 0xfb51, 0xfb52, 0xfb53, 0xfb54, 0xfb55, 0xfb56, 0xfb57, 
+    0xfb58, 0xfb59, 0xfb5a, 0xfb5b, 0xfb5c, 0xfb5d, 0xfb5e, 0xfb5f, 
+    0xfb60, 0xfb61, 0xfb62, 0xfb63, 0xfb64, 0xfb65, 0xfb66, 0xfb67, 
+    0xfb68, 0xfb69, 0xfb6a, 0xfb6b, 0xfb6c, 0xfb6d, 0xfb6e, 0xfb6f, 
+    0xfb70, 0xfb71, 0xfb72, 0xfb73, 0xfb74, 0xfb75, 0xfb76, 0xfb77, 
+    0xfb78, 0xfb79, 0xfb7a, 0xfb7b, 0xfb7c, 0xfb7d, 0xfb7e, 0xfb7f, 
+    0xfb80, 0xfb81, 0xfb82, 0xfb83, 0xfb84, 0xfb85, 0xfb86, 0xfb87, 
+    0xfb88, 0xfb89, 0xfb8a, 0xfb8b, 0xfb8c, 0xfb8d, 0xfb8e, 0xfb8f, 
+    0xfb90, 0xfb91, 0xfb92, 0xfb93, 0xfb94, 0xfb95, 0xfb96, 0xfb97, 
+    0xfb98, 0xfb99, 0xfb9a, 0xfb9b, 0xfb9c, 0xfb9d, 0xfb9e, 0xfb9f, 
+    0xfba0, 0xfba1, 0xfba2, 0xfba3, 0xfba4, 0xfba5, 0xfba6, 0xfba7, 
+    0xfba8, 0xfba9, 0xfbaa, 0xfbab, 0xfbac, 0xfbad, 0xfbae, 0xfbaf, 
+    0xfbb0, 0xfbb1, 0xfbb2, 0xfbb3, 0xfbb4, 0xfbb5, 0xfbb6, 0xfbb7, 
+    0xfbb8, 0xfbb9, 0xfbba, 0xfbbb, 0xfbbc, 0xfbbd, 0xfbbe, 0xfbbf, 
+    0xfbc0, 0xfbc1, 0xfbc2, 0xfbc3, 0xfbc4, 0xfbc5, 0xfbc6, 0xfbc7, 
+    0xfbc8, 0xfbc9, 0xfbca, 0xfbcb, 0xfbcc, 0xfbcd, 0xfbce, 0xfbcf, 
+    0xfbd0, 0xfbd1, 0xfbd2, 0xfbd3, 0xfbd4, 0xfbd5, 0xfbd6, 0xfbd7, 
+    0xfbd8, 0xfbd9, 0xfbda, 0xfbdb, 0xfbdc, 0xfbdd, 0xfbde, 0xfbdf, 
+    0xfbe0, 0xfbe1, 0xfbe2, 0xfbe3, 0xfbe4, 0xfbe5, 0xfbe6, 0xfbe7, 
+    0xfbe8, 0xfbe9, 0xfbea, 0xfbeb, 0xfbec, 0xfbed, 0xfbee, 0xfbef, 
+    0xfbf0, 0xfbf1, 0xfbf2, 0xfbf3, 0xfbf4, 0xfbf5, 0xfbf6, 0xfbf7, 
+    0xfbf8, 0xfbf9, 0xfbfa, 0xfbfb, 0xfbfc, 0xfbfd, 0xfbfe, 0xfbff, 
+    0xfc00, 0xfc01, 0xfc02, 0xfc03, 0xfc04, 0xfc05, 0xfc06, 0xfc07, 
+    0xfc08, 0xfc09, 0xfc0a, 0xfc0b, 0xfc0c, 0xfc0d, 0xfc0e, 0xfc0f, 
+    0xfc10, 0xfc11, 0xfc12, 0xfc13, 0xfc14, 0xfc15, 0xfc16, 0xfc17, 
+    0xfc18, 0xfc19, 0xfc1a, 0xfc1b, 0xfc1c, 0xfc1d, 0xfc1e, 0xfc1f, 
+    0xfc20, 0xfc21, 0xfc22, 0xfc23, 0xfc24, 0xfc25, 0xfc26, 0xfc27, 
+    0xfc28, 0xfc29, 0xfc2a, 0xfc2b, 0xfc2c, 0xfc2d, 0xfc2e, 0xfc2f, 
+    0xfc30, 0xfc31, 0xfc32, 0xfc33, 0xfc34, 0xfc35, 0xfc36, 0xfc37, 
+    0xfc38, 0xfc39, 0xfc3a, 0xfc3b, 0xfc3c, 0xfc3d, 0xfc3e, 0xfc3f, 
+    0xfc40, 0xfc41, 0xfc42, 0xfc43, 0xfc44, 0xfc45, 0xfc46, 0xfc47, 
+    0xfc48, 0xfc49, 0xfc4a, 0xfc4b, 0xfc4c, 0xfc4d, 0xfc4e, 0xfc4f, 
+    0xfc50, 0xfc51, 0xfc52, 0xfc53, 0xfc54, 0xfc55, 0xfc56, 0xfc57, 
+    0xfc58, 0xfc59, 0xfc5a, 0xfc5b, 0xfc5c, 0xfc5d, 0xfc5e, 0xfc5f, 
+    0xfc60, 0xfc61, 0xfc62, 0xfc63, 0xfc64, 0xfc65, 0xfc66, 0xfc67, 
+    0xfc68, 0xfc69, 0xfc6a, 0xfc6b, 0xfc6c, 0xfc6d, 0xfc6e, 0xfc6f, 
+    0xfc70, 0xfc71, 0xfc72, 0xfc73, 0xfc74, 0xfc75, 0xfc76, 0xfc77, 
+    0xfc78, 0xfc79, 0xfc7a, 0xfc7b, 0xfc7c, 0xfc7d, 0xfc7e, 0xfc7f, 
+    0xfc80, 0xfc81, 0xfc82, 0xfc83, 0xfc84, 0xfc85, 0xfc86, 0xfc87, 
+    0xfc88, 0xfc89, 0xfc8a, 0xfc8b, 0xfc8c, 0xfc8d, 0xfc8e, 0xfc8f, 
+    0xfc90, 0xfc91, 0xfc92, 0xfc93, 0xfc94, 0xfc95, 0xfc96, 0xfc97, 
+    0xfc98, 0xfc99, 0xfc9a, 0xfc9b, 0xfc9c, 0xfc9d, 0xfc9e, 0xfc9f, 
+    0xfca0, 0xfca1, 0xfca2, 0xfca3, 0xfca4, 0xfca5, 0xfca6, 0xfca7, 
+    0xfca8, 0xfca9, 0xfcaa, 0xfcab, 0xfcac, 0xfcad, 0xfcae, 0xfcaf, 
+    0xfcb0, 0xfcb1, 0xfcb2, 0xfcb3, 0xfcb4, 0xfcb5, 0xfcb6, 0xfcb7, 
+    0xfcb8, 0xfcb9, 0xfcba, 0xfcbb, 0xfcbc, 0xfcbd, 0xfcbe, 0xfcbf, 
+    0xfcc0, 0xfcc1, 0xfcc2, 0xfcc3, 0xfcc4, 0xfcc5, 0xfcc6, 0xfcc7, 
+    0xfcc8, 0xfcc9, 0xfcca, 0xfccb, 0xfccc, 0xfccd, 0xfcce, 0xfccf, 
+    0xfcd0, 0xfcd1, 0xfcd2, 0xfcd3, 0xfcd4, 0xfcd5, 0xfcd6, 0xfcd7, 
+    0xfcd8, 0xfcd9, 0xfcda, 0xfcdb, 0xfcdc, 0xfcdd, 0xfcde, 0xfcdf, 
+    0xfce0, 0xfce1, 0xfce2, 0xfce3, 0xfce4, 0xfce5, 0xfce6, 0xfce7, 
+    0xfce8, 0xfce9, 0xfcea, 0xfceb, 0xfcec, 0xfced, 0xfcee, 0xfcef, 
+    0xfcf0, 0xfcf1, 0xfcf2, 0xfcf3, 0xfcf4, 0xfcf5, 0xfcf6, 0xfcf7, 
+    0xfcf8, 0xfcf9, 0xfcfa, 0xfcfb, 0xfcfc, 0xfcfd, 0xfcfe, 0xfcff, 
+    0xfd00, 0xfd01, 0xfd02, 0xfd03, 0xfd04, 0xfd05, 0xfd06, 0xfd07, 
+    0xfd08, 0xfd09, 0xfd0a, 0xfd0b, 0xfd0c, 0xfd0d, 0xfd0e, 0xfd0f, 
+    0xfd10, 0xfd11, 0xfd12, 0xfd13, 0xfd14, 0xfd15, 0xfd16, 0xfd17, 
+    0xfd18, 0xfd19, 0xfd1a, 0xfd1b, 0xfd1c, 0xfd1d, 0xfd1e, 0xfd1f, 
+    0xfd20, 0xfd21, 0xfd22, 0xfd23, 0xfd24, 0xfd25, 0xfd26, 0xfd27, 
+    0xfd28, 0xfd29, 0xfd2a, 0xfd2b, 0xfd2c, 0xfd2d, 0xfd2e, 0xfd2f, 
+    0xfd30, 0xfd31, 0xfd32, 0xfd33, 0xfd34, 0xfd35, 0xfd36, 0xfd37, 
+    0xfd38, 0xfd39, 0xfd3a, 0xfd3b, 0xfd3c, 0xfd3d, 0xfd3e, 0xfd3f, 
+    0xfd40, 0xfd41, 0xfd42, 0xfd43, 0xfd44, 0xfd45, 0xfd46, 0xfd47, 
+    0xfd48, 0xfd49, 0xfd4a, 0xfd4b, 0xfd4c, 0xfd4d, 0xfd4e, 0xfd4f, 
+    0xfd50, 0xfd51, 0xfd52, 0xfd53, 0xfd54, 0xfd55, 0xfd56, 0xfd57, 
+    0xfd58, 0xfd59, 0xfd5a, 0xfd5b, 0xfd5c, 0xfd5d, 0xfd5e, 0xfd5f, 
+    0xfd60, 0xfd61, 0xfd62, 0xfd63, 0xfd64, 0xfd65, 0xfd66, 0xfd67, 
+    0xfd68, 0xfd69, 0xfd6a, 0xfd6b, 0xfd6c, 0xfd6d, 0xfd6e, 0xfd6f, 
+    0xfd70, 0xfd71, 0xfd72, 0xfd73, 0xfd74, 0xfd75, 0xfd76, 0xfd77, 
+    0xfd78, 0xfd79, 0xfd7a, 0xfd7b, 0xfd7c, 0xfd7d, 0xfd7e, 0xfd7f, 
+    0xfd80, 0xfd81, 0xfd82, 0xfd83, 0xfd84, 0xfd85, 0xfd86, 0xfd87, 
+    0xfd88, 0xfd89, 0xfd8a, 0xfd8b, 0xfd8c, 0xfd8d, 0xfd8e, 0xfd8f, 
+    0xfd90, 0xfd91, 0xfd92, 0xfd93, 0xfd94, 0xfd95, 0xfd96, 0xfd97, 
+    0xfd98, 0xfd99, 0xfd9a, 0xfd9b, 0xfd9c, 0xfd9d, 0xfd9e, 0xfd9f, 
+    0xfda0, 0xfda1, 0xfda2, 0xfda3, 0xfda4, 0xfda5, 0xfda6, 0xfda7, 
+    0xfda8, 0xfda9, 0xfdaa, 0xfdab, 0xfdac, 0xfdad, 0xfdae, 0xfdaf, 
+    0xfdb0, 0xfdb1, 0xfdb2, 0xfdb3, 0xfdb4, 0xfdb5, 0xfdb6, 0xfdb7, 
+    0xfdb8, 0xfdb9, 0xfdba, 0xfdbb, 0xfdbc, 0xfdbd, 0xfdbe, 0xfdbf, 
+    0xfdc0, 0xfdc1, 0xfdc2, 0xfdc3, 0xfdc4, 0xfdc5, 0xfdc6, 0xfdc7, 
+    0xfdc8, 0xfdc9, 0xfdca, 0xfdcb, 0xfdcc, 0xfdcd, 0xfdce, 0xfdcf, 
+    0xfdd0, 0xfdd1, 0xfdd2, 0xfdd3, 0xfdd4, 0xfdd5, 0xfdd6, 0xfdd7, 
+    0xfdd8, 0xfdd9, 0xfdda, 0xfddb, 0xfddc, 0xfddd, 0xfdde, 0xfddf, 
+    0xfde0, 0xfde1, 0xfde2, 0xfde3, 0xfde4, 0xfde5, 0xfde6, 0xfde7, 
+    0xfde8, 0xfde9, 0xfdea, 0xfdeb, 0xfdec, 0xfded, 0xfdee, 0xfdef, 
+    0xfdf0, 0xfdf1, 0xfdf2, 0xfdf3, 0xfdf4, 0xfdf5, 0xfdf6, 0xfdf7, 
+    0xfdf8, 0xfdf9, 0xfdfa, 0xfdfb, 0xfdfc, 0xfdfd, 0xfdfe, 0xfdff, 
+    0xfe00, 0xfe01, 0xfe02, 0xfe03, 0xfe04, 0xfe05, 0xfe06, 0xfe07, 
+    0xfe08, 0xfe09, 0xfe0a, 0xfe0b, 0xfe0c, 0xfe0d, 0xfe0e, 0xfe0f, 
+    0xfe10, 0xfe11, 0xfe12, 0xfe13, 0xfe14, 0xfe15, 0xfe16, 0xfe17, 
+    0xfe18, 0xfe19, 0xfe1a, 0xfe1b, 0xfe1c, 0xfe1d, 0xfe1e, 0xfe1f, 
+    0xfe20, 0xfe21, 0xfe22, 0xfe23, 0xfe24, 0xfe25, 0xfe26, 0xfe27, 
+    0xfe28, 0xfe29, 0xfe2a, 0xfe2b, 0xfe2c, 0xfe2d, 0xfe2e, 0xfe2f, 
+    0xfe30, 0xfe31, 0xfe32, 0xfe33, 0xfe34, 0xfe35, 0xfe36, 0xfe37, 
+    0xfe38, 0xfe39, 0xfe3a, 0xfe3b, 0xfe3c, 0xfe3d, 0xfe3e, 0xfe3f, 
+    0xfe40, 0xfe41, 0xfe42, 0xfe43, 0xfe44, 0xfe45, 0xfe46, 0xfe47, 
+    0xfe48, 0xfe49, 0xfe4a, 0xfe4b, 0xfe4c, 0xfe4d, 0xfe4e, 0xfe4f, 
+    0xfe50, 0xfe51, 0xfe52, 0xfe53, 0xfe54, 0xfe55, 0xfe56, 0xfe57, 
+    0xfe58, 0xfe59, 0xfe5a, 0xfe5b, 0xfe5c, 0xfe5d, 0xfe5e, 0xfe5f, 
+    0xfe60, 0xfe61, 0xfe62, 0xfe63, 0xfe64, 0xfe65, 0xfe66, 0xfe67, 
+    0xfe68, 0xfe69, 0xfe6a, 0xfe6b, 0xfe6c, 0xfe6d, 0xfe6e, 0xfe6f, 
+    0xfe70, 0xfe71, 0xfe72, 0xfe73, 0xfe74, 0xfe75, 0xfe76, 0xfe77, 
+    0xfe78, 0xfe79, 0xfe7a, 0xfe7b, 0xfe7c, 0xfe7d, 0xfe7e, 0xfe7f, 
+    0xfe80, 0xfe81, 0xfe82, 0xfe83, 0xfe84, 0xfe85, 0xfe86, 0xfe87, 
+    0xfe88, 0xfe89, 0xfe8a, 0xfe8b, 0xfe8c, 0xfe8d, 0xfe8e, 0xfe8f, 
+    0xfe90, 0xfe91, 0xfe92, 0xfe93, 0xfe94, 0xfe95, 0xfe96, 0xfe97, 
+    0xfe98, 0xfe99, 0xfe9a, 0xfe9b, 0xfe9c, 0xfe9d, 0xfe9e, 0xfe9f, 
+    0xfea0, 0xfea1, 0xfea2, 0xfea3, 0xfea4, 0xfea5, 0xfea6, 0xfea7, 
+    0xfea8, 0xfea9, 0xfeaa, 0xfeab, 0xfeac, 0xfead, 0xfeae, 0xfeaf, 
+    0xfeb0, 0xfeb1, 0xfeb2, 0xfeb3, 0xfeb4, 0xfeb5, 0xfeb6, 0xfeb7, 
+    0xfeb8, 0xfeb9, 0xfeba, 0xfebb, 0xfebc, 0xfebd, 0xfebe, 0xfebf, 
+    0xfec0, 0xfec1, 0xfec2, 0xfec3, 0xfec4, 0xfec5, 0xfec6, 0xfec7, 
+    0xfec8, 0xfec9, 0xfeca, 0xfecb, 0xfecc, 0xfecd, 0xfece, 0xfecf, 
+    0xfed0, 0xfed1, 0xfed2, 0xfed3, 0xfed4, 0xfed5, 0xfed6, 0xfed7, 
+    0xfed8, 0xfed9, 0xfeda, 0xfedb, 0xfedc, 0xfedd, 0xfede, 0xfedf, 
+    0xfee0, 0xfee1, 0xfee2, 0xfee3, 0xfee4, 0xfee5, 0xfee6, 0xfee7, 
+    0xfee8, 0xfee9, 0xfeea, 0xfeeb, 0xfeec, 0xfeed, 0xfeee, 0xfeef, 
+    0xfef0, 0xfef1, 0xfef2, 0xfef3, 0xfef4, 0xfef5, 0xfef6, 0xfef7, 
+    0xfef8, 0xfef9, 0xfefa, 0xfefb, 0xfefc, 0xfefd, 0xfefe, 0xfeff, 
+    0xff00, 0xff01, 0xff02, 0xff03, 0xff04, 0xff05, 0xff06, 0xff07, 
+    0xff08, 0xff09, 0xff0a, 0xff0b, 0xff0c, 0xff0d, 0xff0e, 0xff0f, 
+    0xff10, 0xff11, 0xff12, 0xff13, 0xff14, 0xff15, 0xff16, 0xff17, 
+    0xff18, 0xff19, 0xff1a, 0xff1b, 0xff1c, 0xff1d, 0xff1e, 0xff1f, 
+    0xff20, 0xff21, 0xff22, 0xff23, 0xff24, 0xff25, 0xff26, 0xff27, 
+    0xff28, 0xff29, 0xff2a, 0xff2b, 0xff2c, 0xff2d, 0xff2e, 0xff2f, 
+    0xff30, 0xff31, 0xff32, 0xff33, 0xff34, 0xff35, 0xff36, 0xff37, 
+    0xff38, 0xff39, 0xff3a, 0xff3b, 0xff3c, 0xff3d, 0xff3e, 0xff3f, 
+    0xff40, 0xff41, 0xff42, 0xff43, 0xff44, 0xff45, 0xff46, 0xff47, 
+    0xff48, 0xff49, 0xff4a, 0xff4b, 0xff4c, 0xff4d, 0xff4e, 0xff4f, 
+    0xff50, 0xff51, 0xff52, 0xff53, 0xff54, 0xff55, 0xff56, 0xff57, 
+    0xff58, 0xff59, 0xff5a, 0xff5b, 0xff5c, 0xff5d, 0xff5e, 0xff5f, 
+    0xff60, 0xff61, 0xff62, 0xff63, 0xff64, 0xff65, 0xff66, 0xff67, 
+    0xff68, 0xff69, 0xff6a, 0xff6b, 0xff6c, 0xff6d, 0xff6e, 0xff6f, 
+    0xff70, 0xff71, 0xff72, 0xff73, 0xff74, 0xff75, 0xff76, 0xff77, 
+    0xff78, 0xff79, 0xff7a, 0xff7b, 0xff7c, 0xff7d, 0xff7e, 0xff7f, 
+    0xff80, 0xff81, 0xff82, 0xff83, 0xff84, 0xff85, 0xff86, 0xff87, 
+    0xff88, 0xff89, 0xff8a, 0xff8b, 0xff8c, 0xff8d, 0xff8e, 0xff8f, 
+    0xff90, 0xff91, 0xff92, 0xff93, 0xff94, 0xff95, 0xff96, 0xff97, 
+    0xff98, 0xff99, 0xff9a, 0xff9b, 0xff9c, 0xff9d, 0xff9e, 0xff9f, 
+    0xffa0, 0xffa1, 0xffa2, 0xffa3, 0xffa4, 0xffa5, 0xffa6, 0xffa7, 
+    0xffa8, 0xffa9, 0xffaa, 0xffab, 0xffac, 0xffad, 0xffae, 0xffaf, 
+    0xffb0, 0xffb1, 0xffb2, 0xffb3, 0xffb4, 0xffb5, 0xffb6, 0xffb7, 
+    0xffb8, 0xffb9, 0xffba, 0xffbb, 0xffbc, 0xffbd, 0xffbe, 0xffbf, 
+    0xffc0, 0xffc1, 0xffc2, 0xffc3, 0xffc4, 0xffc5, 0xffc6, 0xffc7, 
+    0xffc8, 0xffc9, 0xffca, 0xffcb, 0xffcc, 0xffcd, 0xffce, 0xffcf, 
+    0xffd0, 0xffd1, 0xffd2, 0xffd3, 0xffd4, 0xffd5, 0xffd6, 0xffd7, 
+    0xffd8, 0xffd9, 0xffda, 0xffdb, 0xffdc, 0xffdd, 0xffde, 0xffdf, 
+    0xffe0, 0xffe1, 0xffe2, 0xffe3, 0xffe4, 0xffe5, 0xffe6, 0xffe7, 
+    0xffe8, 0xffe9, 0xffea, 0xffeb, 0xffec, 0xffed, 0xffee, 0xffef, 
+    0xfff0, 0xfff1, 0xfff2, 0xfff3, 0xfff4, 0xfff5, 0xfff6, 0xfff7, 
+    0xfff8, 0xfff9, 0xfffa, 0xfffb, 0xfffc, 0xfffd, 0xfffe, 0xffff, 
+};
+
+
+
+const unsigned short dwaCompressorToLinear[] = 
+{
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0003, 
+    0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 
+    0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 
+    0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 
+    0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 
+    0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 
+    0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 
+    0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 
+    0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 
+    0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 
+    0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 
+    0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 
+    0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 
+    0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 
+    0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 
+    0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 
+    0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 
+    0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 
+    0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 
+    0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 
+    0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 
+    0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 
+    0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 
+    0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 
+    0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 
+    0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 
+    0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 
+    0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 
+    0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 
+    0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 
+    0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 
+    0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 
+    0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 
+    0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 
+    0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 
+    0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 
+    0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 
+    0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 
+    0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 
+    0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 
+    0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 
+    0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 
+    0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 
+    0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 
+    0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 
+    0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 
+    0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 
+    0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 
+    0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 
+    0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 
+    0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 
+    0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 
+    0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 
+    0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 
+    0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 
+    0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 
+    0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 
+    0x0004, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 
+    0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 
+    0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 
+    0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 
+    0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 
+    0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 
+    0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 
+    0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 
+    0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 
+    0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 
+    0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 
+    0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 
+    0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 
+    0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 
+    0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 
+    0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 
+    0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 
+    0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 
+    0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 
+    0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 
+    0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 
+    0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 
+    0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 
+    0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 
+    0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0007, 0x0007, 0x0007, 
+    0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 
+    0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 
+    0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 
+    0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 
+    0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 
+    0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 
+    0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 
+    0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 
+    0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 
+    0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 
+    0x0007, 0x0007, 0x0007, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 
+    0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 
+    0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 
+    0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 
+    0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 
+    0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 
+    0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 
+    0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 
+    0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 
+    0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 
+    0x0008, 0x0008, 0x0008, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 
+    0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 
+    0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 
+    0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 
+    0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 
+    0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 
+    0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 
+    0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 
+    0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 
+    0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x000a, 0x000a, 
+    0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 
+    0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 
+    0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 
+    0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 
+    0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 
+    0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 
+    0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 
+    0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 
+    0x000a, 0x000a, 0x000a, 0x000a, 0x000b, 0x000b, 0x000b, 0x000b, 
+    0x000b, 0x000b, 0x000b, 0x000b, 0x000b, 0x000b, 0x000b, 0x000b, 
+    0x000b, 0x000b, 0x000b, 0x000b, 0x000b, 0x000b, 0x000b, 0x000b, 
+    0x000b, 0x000b, 0x000b, 0x000b, 0x000b, 0x000b, 0x000b, 0x000b, 
+    0x000b, 0x000b, 0x000b, 0x000b, 0x000b, 0x000b, 0x000b, 0x000b, 
+    0x000b, 0x000b, 0x000b, 0x000b, 0x000b, 0x000b, 0x000b, 0x000b, 
+    0x000b, 0x000b, 0x000b, 0x000b, 0x000b, 0x000b, 0x000b, 0x000b, 
+    0x000b, 0x000b, 0x000b, 0x000b, 0x000b, 0x000b, 0x000b, 0x000b, 
+    0x000b, 0x000b, 0x000b, 0x000b, 0x000b, 0x000b, 0x000b, 0x000c, 
+    0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 
+    0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 
+    0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 
+    0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 
+    0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 
+    0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 
+    0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 
+    0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000d, 
+    0x000d, 0x000d, 0x000d, 0x000d, 0x000d, 0x000d, 0x000d, 0x000d, 
+    0x000d, 0x000d, 0x000d, 0x000d, 0x000d, 0x000d, 0x000d, 0x000d, 
+    0x000d, 0x000d, 0x000d, 0x000d, 0x000d, 0x000d, 0x000d, 0x000d, 
+    0x000d, 0x000d, 0x000d, 0x000d, 0x000d, 0x000d, 0x000d, 0x000d, 
+    0x000d, 0x000d, 0x000d, 0x000d, 0x000d, 0x000d, 0x000d, 0x000d, 
+    0x000d, 0x000d, 0x000d, 0x000d, 0x000d, 0x000d, 0x000d, 0x000d, 
+    0x000d, 0x000d, 0x000d, 0x000d, 0x000d, 0x000d, 0x000d, 0x000d, 
+    0x000d, 0x000d, 0x000d, 0x000d, 0x000d, 0x000e, 0x000e, 0x000e, 
+    0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 
+    0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 
+    0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 
+    0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 
+    0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 
+    0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 
+    0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000f, 
+    0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 
+    0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 
+    0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 
+    0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 
+    0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 
+    0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 
+    0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 
+    0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 
+    0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 
+    0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 
+    0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 
+    0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 
+    0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 
+    0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0011, 
+    0x0011, 0x0011, 0x0011, 0x0011, 0x0011, 0x0011, 0x0011, 0x0011, 
+    0x0011, 0x0011, 0x0011, 0x0011, 0x0011, 0x0011, 0x0011, 0x0011, 
+    0x0011, 0x0011, 0x0011, 0x0011, 0x0011, 0x0011, 0x0011, 0x0011, 
+    0x0011, 0x0011, 0x0011, 0x0011, 0x0011, 0x0011, 0x0011, 0x0011, 
+    0x0011, 0x0011, 0x0011, 0x0011, 0x0011, 0x0011, 0x0011, 0x0011, 
+    0x0011, 0x0011, 0x0011, 0x0011, 0x0011, 0x0011, 0x0011, 0x0011, 
+    0x0011, 0x0011, 0x0011, 0x0012, 0x0012, 0x0012, 0x0012, 0x0012, 
+    0x0012, 0x0012, 0x0012, 0x0012, 0x0012, 0x0012, 0x0012, 0x0012, 
+    0x0012, 0x0012, 0x0012, 0x0012, 0x0012, 0x0012, 0x0012, 0x0012, 
+    0x0012, 0x0012, 0x0012, 0x0012, 0x0012, 0x0012, 0x0012, 0x0012, 
+    0x0012, 0x0012, 0x0012, 0x0012, 0x0012, 0x0012, 0x0012, 0x0012, 
+    0x0012, 0x0012, 0x0012, 0x0012, 0x0012, 0x0012, 0x0012, 0x0012, 
+    0x0012, 0x0012, 0x0012, 0x0012, 0x0013, 0x0013, 0x0013, 0x0013, 
+    0x0013, 0x0013, 0x0013, 0x0013, 0x0013, 0x0013, 0x0013, 0x0013, 
+    0x0013, 0x0013, 0x0013, 0x0013, 0x0013, 0x0013, 0x0013, 0x0013, 
+    0x0013, 0x0013, 0x0013, 0x0013, 0x0014, 0x0014, 0x0014, 0x0014, 
+    0x0014, 0x0014, 0x0014, 0x0014, 0x0014, 0x0014, 0x0014, 0x0014, 
+    0x0014, 0x0014, 0x0014, 0x0014, 0x0014, 0x0014, 0x0014, 0x0014, 
+    0x0014, 0x0014, 0x0014, 0x0014, 0x0014, 0x0015, 0x0015, 0x0015, 
+    0x0015, 0x0015, 0x0015, 0x0015, 0x0015, 0x0015, 0x0015, 0x0015, 
+    0x0015, 0x0015, 0x0015, 0x0015, 0x0015, 0x0015, 0x0015, 0x0015, 
+    0x0015, 0x0015, 0x0015, 0x0015, 0x0016, 0x0016, 0x0016, 0x0016, 
+    0x0016, 0x0016, 0x0016, 0x0016, 0x0016, 0x0016, 0x0016, 0x0016, 
+    0x0016, 0x0016, 0x0016, 0x0016, 0x0016, 0x0016, 0x0016, 0x0016, 
+    0x0016, 0x0016, 0x0016, 0x0017, 0x0017, 0x0017, 0x0017, 0x0017, 
+    0x0017, 0x0017, 0x0017, 0x0017, 0x0017, 0x0017, 0x0017, 0x0017, 
+    0x0017, 0x0017, 0x0017, 0x0017, 0x0017, 0x0017, 0x0017, 0x0017, 
+    0x0017, 0x0017, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 
+    0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 
+    0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0019, 
+    0x0019, 0x0019, 0x0019, 0x0019, 0x0019, 0x0019, 0x0019, 0x0019, 
+    0x0019, 0x0019, 0x0019, 0x0019, 0x0019, 0x0019, 0x0019, 0x0019, 
+    0x0019, 0x0019, 0x0019, 0x0019, 0x0019, 0x001a, 0x001a, 0x001a, 
+    0x001a, 0x001a, 0x001a, 0x001a, 0x001a, 0x001a, 0x001a, 0x001a, 
+    0x001a, 0x001a, 0x001a, 0x001a, 0x001a, 0x001a, 0x001a, 0x001a, 
+    0x001a, 0x001a, 0x001b, 0x001b, 0x001b, 0x001b, 0x001b, 0x001b, 
+    0x001b, 0x001b, 0x001b, 0x001b, 0x001b, 0x001b, 0x001b, 0x001b, 
+    0x001b, 0x001b, 0x001b, 0x001b, 0x001b, 0x001b, 0x001c, 0x001c, 
+    0x001c, 0x001c, 0x001c, 0x001c, 0x001c, 0x001c, 0x001c, 0x001c, 
+    0x001c, 0x001c, 0x001c, 0x001c, 0x001c, 0x001c, 0x001c, 0x001c, 
+    0x001c, 0x001c, 0x001d, 0x001d, 0x001d, 0x001d, 0x001d, 0x001d, 
+    0x001d, 0x001d, 0x001d, 0x001d, 0x001d, 0x001d, 0x001d, 0x001d, 
+    0x001d, 0x001d, 0x001d, 0x001d, 0x001d, 0x001d, 0x001e, 0x001e, 
+    0x001e, 0x001e, 0x001e, 0x001e, 0x001e, 0x001e, 0x001e, 0x001e, 
+    0x001e, 0x001e, 0x001e, 0x001e, 0x001e, 0x001e, 0x001e, 0x001e, 
+    0x001e, 0x001e, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 
+    0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 
+    0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x0020, 0x0020, 0x0020, 
+    0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 
+    0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0021, 
+    0x0021, 0x0021, 0x0021, 0x0021, 0x0021, 0x0021, 0x0021, 0x0021, 
+    0x0021, 0x0021, 0x0021, 0x0021, 0x0021, 0x0021, 0x0021, 0x0021, 
+    0x0021, 0x0021, 0x0022, 0x0022, 0x0022, 0x0022, 0x0022, 0x0022, 
+    0x0022, 0x0022, 0x0022, 0x0022, 0x0022, 0x0022, 0x0022, 0x0022, 
+    0x0022, 0x0022, 0x0022, 0x0022, 0x0023, 0x0023, 0x0023, 0x0023, 
+    0x0023, 0x0023, 0x0023, 0x0023, 0x0023, 0x0023, 0x0023, 0x0023, 
+    0x0023, 0x0023, 0x0023, 0x0023, 0x0023, 0x0023, 0x0024, 0x0024, 
+    0x0024, 0x0024, 0x0024, 0x0024, 0x0024, 0x0024, 0x0024, 0x0024, 
+    0x0024, 0x0024, 0x0024, 0x0024, 0x0024, 0x0024, 0x0024, 0x0025, 
+    0x0025, 0x0025, 0x0025, 0x0025, 0x0025, 0x0025, 0x0025, 0x0025, 
+    0x0025, 0x0025, 0x0025, 0x0025, 0x0025, 0x0025, 0x0025, 0x0025, 
+    0x0025, 0x0026, 0x0026, 0x0026, 0x0026, 0x0026, 0x0026, 0x0026, 
+    0x0026, 0x0026, 0x0026, 0x0026, 0x0026, 0x0026, 0x0026, 0x0026, 
+    0x0026, 0x0026, 0x0027, 0x0027, 0x0027, 0x0027, 0x0027, 0x0027, 
+    0x0027, 0x0027, 0x0027, 0x0027, 0x0027, 0x0027, 0x0027, 0x0027, 
+    0x0027, 0x0027, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 
+    0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 
+    0x0028, 0x0028, 0x0028, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 
+    0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 
+    0x0029, 0x0029, 0x0029, 0x002a, 0x002a, 0x002a, 0x002a, 0x002a, 
+    0x002a, 0x002a, 0x002a, 0x002a, 0x002a, 0x002a, 0x002a, 0x002a, 
+    0x002a, 0x002a, 0x002a, 0x002b, 0x002b, 0x002b, 0x002b, 0x002b, 
+    0x002b, 0x002b, 0x002b, 0x002b, 0x002b, 0x002b, 0x002b, 0x002b, 
+    0x002b, 0x002b, 0x002b, 0x002c, 0x002c, 0x002c, 0x002c, 0x002c, 
+    0x002c, 0x002c, 0x002c, 0x002c, 0x002c, 0x002c, 0x002c, 0x002c, 
+    0x002c, 0x002c, 0x002c, 0x002d, 0x002d, 0x002d, 0x002d, 0x002d, 
+    0x002d, 0x002d, 0x002d, 0x002d, 0x002d, 0x002d, 0x002d, 0x002d, 
+    0x002d, 0x002d, 0x002d, 0x002e, 0x002e, 0x002e, 0x002e, 0x002e, 
+    0x002e, 0x002e, 0x002e, 0x002e, 0x002e, 0x002e, 0x002e, 0x002e, 
+    0x002e, 0x002e, 0x002f, 0x002f, 0x002f, 0x002f, 0x002f, 0x002f, 
+    0x002f, 0x002f, 0x002f, 0x002f, 0x002f, 0x002f, 0x002f, 0x002f, 
+    0x002f, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 
+    0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 
+    0x0031, 0x0031, 0x0031, 0x0031, 0x0031, 0x0031, 0x0031, 0x0031, 
+    0x0031, 0x0031, 0x0031, 0x0031, 0x0031, 0x0031, 0x0031, 0x0032, 
+    0x0032, 0x0032, 0x0032, 0x0032, 0x0032, 0x0032, 0x0032, 0x0032, 
+    0x0032, 0x0032, 0x0032, 0x0032, 0x0032, 0x0032, 0x0033, 0x0033, 
+    0x0033, 0x0033, 0x0033, 0x0033, 0x0033, 0x0033, 0x0033, 0x0033, 
+    0x0033, 0x0033, 0x0033, 0x0033, 0x0034, 0x0034, 0x0034, 0x0034, 
+    0x0034, 0x0034, 0x0034, 0x0034, 0x0034, 0x0034, 0x0034, 0x0034, 
+    0x0034, 0x0034, 0x0034, 0x0035, 0x0035, 0x0035, 0x0035, 0x0035, 
+    0x0035, 0x0035, 0x0035, 0x0035, 0x0035, 0x0035, 0x0035, 0x0035, 
+    0x0035, 0x0036, 0x0036, 0x0036, 0x0036, 0x0036, 0x0036, 0x0036, 
+    0x0036, 0x0036, 0x0036, 0x0036, 0x0036, 0x0036, 0x0036, 0x0037, 
+    0x0037, 0x0037, 0x0037, 0x0037, 0x0037, 0x0037, 0x0037, 0x0037, 
+    0x0037, 0x0037, 0x0037, 0x0037, 0x0037, 0x0038, 0x0038, 0x0038, 
+    0x0038, 0x0038, 0x0038, 0x0038, 0x0038, 0x0038, 0x0038, 0x0038, 
+    0x0038, 0x0038, 0x0038, 0x0039, 0x0039, 0x0039, 0x0039, 0x0039, 
+    0x0039, 0x0039, 0x0039, 0x0039, 0x0039, 0x0039, 0x0039, 0x0039, 
+    0x003a, 0x003a, 0x003a, 0x003a, 0x003a, 0x003a, 0x003a, 0x003a, 
+    0x003a, 0x003a, 0x003a, 0x003a, 0x003a, 0x003a, 0x003b, 0x003b, 
+    0x003b, 0x003b, 0x003b, 0x003b, 0x003b, 0x003b, 0x003b, 0x003b, 
+    0x003b, 0x003b, 0x003b, 0x003c, 0x003c, 0x003c, 0x003c, 0x003c, 
+    0x003c, 0x003c, 0x003c, 0x003c, 0x003c, 0x003c, 0x003c, 0x003c, 
+    0x003d, 0x003d, 0x003d, 0x003d, 0x003d, 0x003d, 0x003d, 0x003d, 
+    0x003d, 0x003d, 0x003d, 0x003d, 0x003d, 0x003d, 0x003e, 0x003e, 
+    0x003e, 0x003e, 0x003e, 0x003e, 0x003e, 0x003e, 0x003e, 0x003e, 
+    0x003e, 0x003e, 0x003e, 0x003f, 0x003f, 0x003f, 0x003f, 0x003f, 
+    0x003f, 0x003f, 0x003f, 0x003f, 0x003f, 0x003f, 0x003f, 0x003f, 
+    0x0040, 0x0040, 0x0040, 0x0040, 0x0040, 0x0040, 0x0040, 0x0040, 
+    0x0040, 0x0040, 0x0040, 0x0040, 0x0041, 0x0041, 0x0041, 0x0041, 
+    0x0041, 0x0041, 0x0041, 0x0041, 0x0041, 0x0041, 0x0041, 0x0041, 
+    0x0041, 0x0042, 0x0042, 0x0042, 0x0042, 0x0042, 0x0042, 0x0042, 
+    0x0042, 0x0042, 0x0042, 0x0042, 0x0042, 0x0042, 0x0043, 0x0043, 
+    0x0043, 0x0043, 0x0043, 0x0043, 0x0043, 0x0043, 0x0043, 0x0043, 
+    0x0043, 0x0043, 0x0044, 0x0044, 0x0044, 0x0044, 0x0044, 0x0044, 
+    0x0044, 0x0044, 0x0044, 0x0044, 0x0044, 0x0044, 0x0044, 0x0045, 
+    0x0045, 0x0045, 0x0045, 0x0045, 0x0045, 0x0045, 0x0045, 0x0045, 
+    0x0045, 0x0045, 0x0045, 0x0046, 0x0046, 0x0046, 0x0046, 0x0046, 
+    0x0046, 0x0046, 0x0046, 0x0046, 0x0046, 0x0046, 0x0046, 0x0047, 
+    0x0047, 0x0047, 0x0047, 0x0047, 0x0047, 0x0047, 0x0047, 0x0047, 
+    0x0047, 0x0047, 0x0047, 0x0048, 0x0048, 0x0048, 0x0048, 0x0048, 
+    0x0048, 0x0048, 0x0048, 0x0048, 0x0048, 0x0048, 0x0048, 0x0049, 
+    0x0049, 0x0049, 0x0049, 0x0049, 0x0049, 0x0049, 0x0049, 0x0049, 
+    0x0049, 0x0049, 0x0049, 0x004a, 0x004a, 0x004a, 0x004a, 0x004a, 
+    0x004a, 0x004a, 0x004a, 0x004a, 0x004a, 0x004a, 0x004a, 0x004b, 
+    0x004b, 0x004b, 0x004b, 0x004b, 0x004b, 0x004b, 0x004b, 0x004b, 
+    0x004b, 0x004b, 0x004b, 0x004c, 0x004c, 0x004c, 0x004c, 0x004c, 
+    0x004c, 0x004c, 0x004c, 0x004c, 0x004c, 0x004c, 0x004c, 0x004d, 
+    0x004d, 0x004d, 0x004d, 0x004d, 0x004d, 0x004d, 0x004d, 0x004d, 
+    0x004d, 0x004d, 0x004e, 0x004e, 0x004e, 0x004e, 0x004e, 0x004e, 
+    0x004e, 0x004e, 0x004e, 0x004e, 0x004e, 0x004e, 0x004f, 0x004f, 
+    0x004f, 0x004f, 0x004f, 0x004f, 0x004f, 0x004f, 0x004f, 0x004f, 
+    0x004f, 0x0050, 0x0050, 0x0050, 0x0050, 0x0050, 0x0050, 0x0050, 
+    0x0050, 0x0050, 0x0050, 0x0050, 0x0051, 0x0051, 0x0051, 0x0051, 
+    0x0051, 0x0051, 0x0051, 0x0051, 0x0051, 0x0051, 0x0051, 0x0051, 
+    0x0052, 0x0052, 0x0052, 0x0052, 0x0052, 0x0052, 0x0052, 0x0052, 
+    0x0052, 0x0052, 0x0052, 0x0053, 0x0053, 0x0053, 0x0053, 0x0053, 
+    0x0053, 0x0053, 0x0053, 0x0053, 0x0053, 0x0053, 0x0054, 0x0054, 
+    0x0054, 0x0054, 0x0054, 0x0054, 0x0054, 0x0054, 0x0054, 0x0054, 
+    0x0054, 0x0055, 0x0055, 0x0055, 0x0055, 0x0055, 0x0056, 0x0056, 
+    0x0056, 0x0056, 0x0056, 0x0056, 0x0057, 0x0057, 0x0057, 0x0057, 
+    0x0057, 0x0058, 0x0058, 0x0058, 0x0058, 0x0058, 0x0058, 0x0059, 
+    0x0059, 0x0059, 0x0059, 0x0059, 0x005a, 0x005a, 0x005a, 0x005a, 
+    0x005a, 0x005b, 0x005b, 0x005b, 0x005b, 0x005b, 0x005b, 0x005c, 
+    0x005c, 0x005c, 0x005c, 0x005c, 0x005d, 0x005d, 0x005d, 0x005d, 
+    0x005d, 0x005e, 0x005e, 0x005e, 0x005e, 0x005e, 0x005f, 0x005f, 
+    0x005f, 0x005f, 0x005f, 0x0060, 0x0060, 0x0060, 0x0060, 0x0060, 
+    0x0060, 0x0061, 0x0061, 0x0061, 0x0061, 0x0061, 0x0062, 0x0062, 
+    0x0062, 0x0062, 0x0062, 0x0063, 0x0063, 0x0063, 0x0063, 0x0063, 
+    0x0064, 0x0064, 0x0064, 0x0064, 0x0064, 0x0065, 0x0065, 0x0065, 
+    0x0065, 0x0065, 0x0066, 0x0066, 0x0066, 0x0066, 0x0066, 0x0067, 
+    0x0067, 0x0067, 0x0067, 0x0067, 0x0068, 0x0068, 0x0068, 0x0068, 
+    0x0068, 0x0069, 0x0069, 0x0069, 0x0069, 0x0069, 0x006a, 0x006a, 
+    0x006a, 0x006a, 0x006b, 0x006b, 0x006b, 0x006b, 0x006b, 0x006c, 
+    0x006c, 0x006c, 0x006c, 0x006c, 0x006d, 0x006d, 0x006d, 0x006d, 
+    0x006d, 0x006e, 0x006e, 0x006e, 0x006e, 0x006e, 0x006f, 0x006f, 
+    0x006f, 0x006f, 0x0070, 0x0070, 0x0070, 0x0070, 0x0070, 0x0071, 
+    0x0071, 0x0071, 0x0071, 0x0071, 0x0072, 0x0072, 0x0072, 0x0072, 
+    0x0073, 0x0073, 0x0073, 0x0073, 0x0073, 0x0074, 0x0074, 0x0074, 
+    0x0074, 0x0074, 0x0075, 0x0075, 0x0075, 0x0075, 0x0076, 0x0076, 
+    0x0076, 0x0076, 0x0076, 0x0077, 0x0077, 0x0077, 0x0077, 0x0077, 
+    0x0078, 0x0078, 0x0078, 0x0078, 0x0079, 0x0079, 0x0079, 0x0079, 
+    0x0079, 0x007a, 0x007a, 0x007a, 0x007a, 0x007b, 0x007b, 0x007b, 
+    0x007b, 0x007b, 0x007c, 0x007c, 0x007c, 0x007c, 0x007d, 0x007d, 
+    0x007d, 0x007d, 0x007d, 0x007e, 0x007e, 0x007e, 0x007e, 0x007f, 
+    0x007f, 0x007f, 0x007f, 0x0080, 0x0080, 0x0080, 0x0080, 0x0080, 
+    0x0081, 0x0081, 0x0081, 0x0081, 0x0082, 0x0082, 0x0082, 0x0082, 
+    0x0082, 0x0083, 0x0083, 0x0083, 0x0083, 0x0084, 0x0084, 0x0084, 
+    0x0084, 0x0085, 0x0085, 0x0085, 0x0085, 0x0086, 0x0086, 0x0086, 
+    0x0086, 0x0086, 0x0087, 0x0087, 0x0087, 0x0087, 0x0088, 0x0088, 
+    0x0088, 0x0088, 0x0089, 0x0089, 0x0089, 0x0089, 0x0089, 0x008a, 
+    0x008a, 0x008a, 0x008a, 0x008b, 0x008b, 0x008b, 0x008b, 0x008c, 
+    0x008c, 0x008c, 0x008c, 0x008d, 0x008d, 0x008d, 0x008d, 0x008e, 
+    0x008e, 0x008e, 0x008e, 0x008f, 0x008f, 0x008f, 0x008f, 0x008f, 
+    0x0090, 0x0090, 0x0090, 0x0090, 0x0091, 0x0091, 0x0091, 0x0091, 
+    0x0092, 0x0092, 0x0092, 0x0092, 0x0093, 0x0093, 0x0093, 0x0093, 
+    0x0094, 0x0094, 0x0094, 0x0094, 0x0095, 0x0095, 0x0095, 0x0095, 
+    0x0096, 0x0096, 0x0096, 0x0096, 0x0097, 0x0097, 0x0097, 0x0097, 
+    0x0098, 0x0098, 0x0098, 0x0098, 0x0099, 0x0099, 0x0099, 0x0099, 
+    0x009a, 0x009a, 0x009a, 0x009a, 0x009b, 0x009b, 0x009b, 0x009b, 
+    0x009c, 0x009c, 0x009c, 0x009c, 0x009d, 0x009d, 0x009d, 0x009d, 
+    0x009e, 0x009e, 0x009e, 0x009e, 0x009f, 0x009f, 0x009f, 0x009f, 
+    0x00a0, 0x00a0, 0x00a0, 0x00a0, 0x00a1, 0x00a1, 0x00a1, 0x00a2, 
+    0x00a2, 0x00a2, 0x00a2, 0x00a3, 0x00a3, 0x00a3, 0x00a3, 0x00a4, 
+    0x00a4, 0x00a4, 0x00a4, 0x00a5, 0x00a5, 0x00a5, 0x00a5, 0x00a6, 
+    0x00a6, 0x00a6, 0x00a6, 0x00a7, 0x00a7, 0x00a7, 0x00a8, 0x00a8, 
+    0x00a8, 0x00a8, 0x00a9, 0x00a9, 0x00a9, 0x00a9, 0x00aa, 0x00aa, 
+    0x00aa, 0x00aa, 0x00ab, 0x00ab, 0x00ab, 0x00ab, 0x00ac, 0x00ac, 
+    0x00ac, 0x00ad, 0x00ad, 0x00ad, 0x00ad, 0x00ae, 0x00ae, 0x00ae, 
+    0x00ae, 0x00af, 0x00af, 0x00af, 0x00b0, 0x00b0, 0x00b0, 0x00b0, 
+    0x00b1, 0x00b1, 0x00b1, 0x00b1, 0x00b2, 0x00b2, 0x00b2, 0x00b3, 
+    0x00b3, 0x00b3, 0x00b3, 0x00b4, 0x00b4, 0x00b4, 0x00b4, 0x00b5, 
+    0x00b5, 0x00b5, 0x00b6, 0x00b6, 0x00b6, 0x00b6, 0x00b7, 0x00b7, 
+    0x00b7, 0x00b7, 0x00b8, 0x00b8, 0x00b8, 0x00b9, 0x00b9, 0x00b9, 
+    0x00b9, 0x00ba, 0x00ba, 0x00ba, 0x00bb, 0x00bb, 0x00bb, 0x00bb, 
+    0x00bc, 0x00bc, 0x00bc, 0x00bc, 0x00bd, 0x00bd, 0x00bd, 0x00be, 
+    0x00be, 0x00be, 0x00be, 0x00bf, 0x00bf, 0x00bf, 0x00c0, 0x00c0, 
+    0x00c0, 0x00c0, 0x00c1, 0x00c1, 0x00c1, 0x00c2, 0x00c2, 0x00c2, 
+    0x00c2, 0x00c3, 0x00c3, 0x00c3, 0x00c4, 0x00c4, 0x00c4, 0x00c4, 
+    0x00c5, 0x00c5, 0x00c5, 0x00c6, 0x00c6, 0x00c6, 0x00c6, 0x00c7, 
+    0x00c7, 0x00c7, 0x00c8, 0x00c8, 0x00c8, 0x00c8, 0x00c9, 0x00c9, 
+    0x00c9, 0x00ca, 0x00ca, 0x00ca, 0x00cb, 0x00cb, 0x00cb, 0x00cb, 
+    0x00cc, 0x00cc, 0x00cc, 0x00cd, 0x00cd, 0x00cd, 0x00cd, 0x00ce, 
+    0x00ce, 0x00ce, 0x00cf, 0x00cf, 0x00cf, 0x00d0, 0x00d0, 0x00d0, 
+    0x00d0, 0x00d1, 0x00d1, 0x00d1, 0x00d2, 0x00d2, 0x00d2, 0x00d3, 
+    0x00d3, 0x00d3, 0x00d3, 0x00d4, 0x00d4, 0x00d4, 0x00d5, 0x00d5, 
+    0x00d5, 0x00d6, 0x00d6, 0x00d6, 0x00d6, 0x00d7, 0x00d7, 0x00d7, 
+    0x00d8, 0x00d8, 0x00d8, 0x00d9, 0x00d9, 0x00d9, 0x00d9, 0x00da, 
+    0x00da, 0x00da, 0x00db, 0x00db, 0x00db, 0x00dc, 0x00dc, 0x00dc, 
+    0x00dc, 0x00dd, 0x00dd, 0x00dd, 0x00de, 0x00de, 0x00de, 0x00df, 
+    0x00df, 0x00df, 0x00e0, 0x00e0, 0x00e0, 0x00e0, 0x00e1, 0x00e1, 
+    0x00e1, 0x00e2, 0x00e2, 0x00e2, 0x00e3, 0x00e3, 0x00e3, 0x00e4, 
+    0x00e4, 0x00e4, 0x00e5, 0x00e5, 0x00e5, 0x00e5, 0x00e6, 0x00e6, 
+    0x00e6, 0x00e7, 0x00e7, 0x00e7, 0x00e8, 0x00e8, 0x00e8, 0x00e9, 
+    0x00e9, 0x00e9, 0x00ea, 0x00ea, 0x00ea, 0x00eb, 0x00eb, 0x00eb, 
+    0x00eb, 0x00ec, 0x00ec, 0x00ec, 0x00ed, 0x00ed, 0x00ed, 0x00ee, 
+    0x00ee, 0x00ee, 0x00ef, 0x00ef, 0x00ef, 0x00f0, 0x00f0, 0x00f0, 
+    0x00f1, 0x00f1, 0x00f1, 0x00f2, 0x00f2, 0x00f2, 0x00f2, 0x00f3, 
+    0x00f3, 0x00f3, 0x00f4, 0x00f4, 0x00f4, 0x00f5, 0x00f5, 0x00f5, 
+    0x00f6, 0x00f6, 0x00f6, 0x00f7, 0x00f7, 0x00f7, 0x00f8, 0x00f8, 
+    0x00f8, 0x00f9, 0x00f9, 0x00f9, 0x00fa, 0x00fa, 0x00fa, 0x00fb, 
+    0x00fb, 0x00fb, 0x00fc, 0x00fc, 0x00fc, 0x00fd, 0x00fd, 0x00fd, 
+    0x00fe, 0x00fe, 0x00fe, 0x00ff, 0x00ff, 0x00ff, 0x0100, 0x0100, 
+    0x0100, 0x0101, 0x0101, 0x0101, 0x0102, 0x0102, 0x0102, 0x0103, 
+    0x0103, 0x0103, 0x0104, 0x0104, 0x0104, 0x0105, 0x0105, 0x0105, 
+    0x0106, 0x0106, 0x0106, 0x0107, 0x0107, 0x0107, 0x0108, 0x0108, 
+    0x0108, 0x0109, 0x0109, 0x0109, 0x010a, 0x010a, 0x010a, 0x010b, 
+    0x010b, 0x010b, 0x010c, 0x010c, 0x010c, 0x010d, 0x010d, 0x010d, 
+    0x010e, 0x010e, 0x010e, 0x010f, 0x010f, 0x010f, 0x0110, 0x0110, 
+    0x0110, 0x0111, 0x0111, 0x0112, 0x0112, 0x0112, 0x0113, 0x0113, 
+    0x0113, 0x0114, 0x0114, 0x0114, 0x0115, 0x0115, 0x0115, 0x0116, 
+    0x0116, 0x0116, 0x0117, 0x0117, 0x0117, 0x0118, 0x0118, 0x0118, 
+    0x0119, 0x0119, 0x0119, 0x011a, 0x011a, 0x011b, 0x011b, 0x011b, 
+    0x011c, 0x011c, 0x011c, 0x011d, 0x011d, 0x011d, 0x011e, 0x011e, 
+    0x011e, 0x011f, 0x011f, 0x011f, 0x0120, 0x0120, 0x0121, 0x0121, 
+    0x0121, 0x0122, 0x0122, 0x0122, 0x0123, 0x0123, 0x0123, 0x0124, 
+    0x0124, 0x0124, 0x0125, 0x0125, 0x0126, 0x0126, 0x0126, 0x0127, 
+    0x0127, 0x0127, 0x0128, 0x0128, 0x0128, 0x0129, 0x0129, 0x0129, 
+    0x012a, 0x012a, 0x012b, 0x012b, 0x012b, 0x012c, 0x012c, 0x012c, 
+    0x012d, 0x012d, 0x012d, 0x012e, 0x012e, 0x012f, 0x012f, 0x012f, 
+    0x0130, 0x0130, 0x0130, 0x0131, 0x0131, 0x0131, 0x0132, 0x0132, 
+    0x0133, 0x0133, 0x0133, 0x0134, 0x0134, 0x0134, 0x0135, 0x0135, 
+    0x0136, 0x0136, 0x0136, 0x0137, 0x0137, 0x0137, 0x0138, 0x0138, 
+    0x0138, 0x0139, 0x0139, 0x013a, 0x013a, 0x013a, 0x013b, 0x013b, 
+    0x013b, 0x013c, 0x013c, 0x013d, 0x013d, 0x013d, 0x013e, 0x013e, 
+    0x013e, 0x013f, 0x013f, 0x0140, 0x0140, 0x0140, 0x0141, 0x0141, 
+    0x0141, 0x0142, 0x0142, 0x0143, 0x0143, 0x0143, 0x0144, 0x0144, 
+    0x0144, 0x0145, 0x0145, 0x0146, 0x0146, 0x0146, 0x0147, 0x0147, 
+    0x0147, 0x0148, 0x0148, 0x0149, 0x0149, 0x0149, 0x014a, 0x014a, 
+    0x014b, 0x014b, 0x014b, 0x014c, 0x014c, 0x014c, 0x014d, 0x014d, 
+    0x014e, 0x014e, 0x014e, 0x014f, 0x014f, 0x0150, 0x0150, 0x0150, 
+    0x0151, 0x0151, 0x0151, 0x0152, 0x0152, 0x0153, 0x0153, 0x0153, 
+    0x0154, 0x0154, 0x0155, 0x0155, 0x0155, 0x0156, 0x0156, 0x0156, 
+    0x0157, 0x0157, 0x0158, 0x0158, 0x0158, 0x0159, 0x0159, 0x015a, 
+    0x015a, 0x015a, 0x015b, 0x015b, 0x015c, 0x015c, 0x015c, 0x015d, 
+    0x015d, 0x015e, 0x015e, 0x015e, 0x015f, 0x015f, 0x015f, 0x0160, 
+    0x0160, 0x0161, 0x0161, 0x0161, 0x0162, 0x0162, 0x0163, 0x0163, 
+    0x0163, 0x0164, 0x0164, 0x0165, 0x0165, 0x0165, 0x0166, 0x0166, 
+    0x0167, 0x0167, 0x0167, 0x0168, 0x0168, 0x0169, 0x0169, 0x0169, 
+    0x016a, 0x016a, 0x016b, 0x016b, 0x016b, 0x016c, 0x016c, 0x016d, 
+    0x016d, 0x016d, 0x016e, 0x016e, 0x016f, 0x016f, 0x016f, 0x0170, 
+    0x0170, 0x0171, 0x0171, 0x0172, 0x0172, 0x0172, 0x0173, 0x0173, 
+    0x0174, 0x0174, 0x0174, 0x0175, 0x0175, 0x0176, 0x0176, 0x0176, 
+    0x0177, 0x0177, 0x0178, 0x0178, 0x0178, 0x0179, 0x0179, 0x017a, 
+    0x017a, 0x017b, 0x017b, 0x017b, 0x017c, 0x017c, 0x017d, 0x017d, 
+    0x017d, 0x017e, 0x017e, 0x017f, 0x017f, 0x017f, 0x0180, 0x0180, 
+    0x0181, 0x0181, 0x0182, 0x0182, 0x0182, 0x0183, 0x0183, 0x0184, 
+    0x0184, 0x0185, 0x0186, 0x0187, 0x0187, 0x0188, 0x0189, 0x018a, 
+    0x018b, 0x018c, 0x018c, 0x018d, 0x018e, 0x018f, 0x0190, 0x0191, 
+    0x0191, 0x0192, 0x0193, 0x0194, 0x0195, 0x0196, 0x0197, 0x0197, 
+    0x0198, 0x0199, 0x019a, 0x019b, 0x019c, 0x019d, 0x019d, 0x019e, 
+    0x019f, 0x01a0, 0x01a1, 0x01a2, 0x01a3, 0x01a4, 0x01a4, 0x01a5, 
+    0x01a6, 0x01a7, 0x01a8, 0x01a9, 0x01aa, 0x01ab, 0x01ab, 0x01ac, 
+    0x01ad, 0x01ae, 0x01af, 0x01b0, 0x01b1, 0x01b2, 0x01b2, 0x01b3, 
+    0x01b4, 0x01b5, 0x01b6, 0x01b7, 0x01b8, 0x01b9, 0x01ba, 0x01ba, 
+    0x01bb, 0x01bc, 0x01bd, 0x01be, 0x01bf, 0x01c0, 0x01c1, 0x01c2, 
+    0x01c3, 0x01c3, 0x01c4, 0x01c5, 0x01c6, 0x01c7, 0x01c8, 0x01c9, 
+    0x01ca, 0x01cb, 0x01cc, 0x01cd, 0x01ce, 0x01ce, 0x01cf, 0x01d0, 
+    0x01d1, 0x01d2, 0x01d3, 0x01d4, 0x01d5, 0x01d6, 0x01d7, 0x01d8, 
+    0x01d9, 0x01da, 0x01da, 0x01db, 0x01dc, 0x01dd, 0x01de, 0x01df, 
+    0x01e0, 0x01e1, 0x01e2, 0x01e3, 0x01e4, 0x01e5, 0x01e6, 0x01e7, 
+    0x01e8, 0x01e9, 0x01e9, 0x01ea, 0x01eb, 0x01ec, 0x01ed, 0x01ee, 
+    0x01ef, 0x01f0, 0x01f1, 0x01f2, 0x01f3, 0x01f4, 0x01f5, 0x01f6, 
+    0x01f7, 0x01f8, 0x01f9, 0x01fa, 0x01fb, 0x01fc, 0x01fd, 0x01fe, 
+    0x01ff, 0x01ff, 0x0200, 0x0201, 0x0202, 0x0203, 0x0204, 0x0205, 
+    0x0206, 0x0207, 0x0208, 0x0209, 0x020a, 0x020b, 0x020c, 0x020d, 
+    0x020e, 0x020f, 0x0210, 0x0211, 0x0212, 0x0213, 0x0214, 0x0215, 
+    0x0216, 0x0217, 0x0218, 0x0219, 0x021a, 0x021b, 0x021c, 0x021d, 
+    0x021e, 0x021f, 0x0220, 0x0221, 0x0222, 0x0223, 0x0224, 0x0225, 
+    0x0226, 0x0227, 0x0228, 0x0229, 0x022a, 0x022b, 0x022c, 0x022d, 
+    0x022e, 0x022f, 0x0230, 0x0231, 0x0232, 0x0233, 0x0234, 0x0235, 
+    0x0236, 0x0237, 0x0238, 0x0239, 0x023a, 0x023b, 0x023c, 0x023e, 
+    0x023f, 0x0240, 0x0241, 0x0242, 0x0243, 0x0244, 0x0245, 0x0246, 
+    0x0247, 0x0248, 0x0249, 0x024a, 0x024b, 0x024c, 0x024d, 0x024e, 
+    0x024f, 0x0250, 0x0251, 0x0252, 0x0253, 0x0254, 0x0255, 0x0257, 
+    0x0258, 0x0259, 0x025a, 0x025b, 0x025c, 0x025d, 0x025e, 0x025f, 
+    0x0260, 0x0261, 0x0262, 0x0263, 0x0264, 0x0265, 0x0267, 0x0268, 
+    0x0269, 0x026a, 0x026b, 0x026c, 0x026d, 0x026e, 0x026f, 0x0270, 
+    0x0271, 0x0272, 0x0273, 0x0275, 0x0276, 0x0277, 0x0278, 0x0279, 
+    0x027a, 0x027b, 0x027c, 0x027d, 0x027e, 0x027f, 0x0281, 0x0282, 
+    0x0283, 0x0284, 0x0285, 0x0286, 0x0287, 0x0288, 0x0289, 0x028a, 
+    0x028c, 0x028d, 0x028e, 0x028f, 0x0290, 0x0291, 0x0292, 0x0293, 
+    0x0294, 0x0296, 0x0297, 0x0298, 0x0299, 0x029a, 0x029b, 0x029c, 
+    0x029d, 0x029e, 0x02a0, 0x02a1, 0x02a2, 0x02a3, 0x02a4, 0x02a5, 
+    0x02a6, 0x02a7, 0x02a9, 0x02aa, 0x02ab, 0x02ac, 0x02ad, 0x02ae, 
+    0x02af, 0x02b1, 0x02b2, 0x02b3, 0x02b4, 0x02b5, 0x02b6, 0x02b7, 
+    0x02b9, 0x02ba, 0x02bb, 0x02bc, 0x02bd, 0x02be, 0x02bf, 0x02c1, 
+    0x02c2, 0x02c3, 0x02c4, 0x02c5, 0x02c6, 0x02c8, 0x02c9, 0x02ca, 
+    0x02cb, 0x02cc, 0x02cd, 0x02cf, 0x02d0, 0x02d1, 0x02d2, 0x02d3, 
+    0x02d4, 0x02d6, 0x02d7, 0x02d8, 0x02d9, 0x02da, 0x02db, 0x02dd, 
+    0x02de, 0x02df, 0x02e0, 0x02e1, 0x02e3, 0x02e4, 0x02e5, 0x02e6, 
+    0x02e7, 0x02e8, 0x02ea, 0x02eb, 0x02ec, 0x02ed, 0x02ee, 0x02f0, 
+    0x02f1, 0x02f2, 0x02f3, 0x02f4, 0x02f6, 0x02f7, 0x02f8, 0x02f9, 
+    0x02fa, 0x02fc, 0x02fd, 0x02fe, 0x02ff, 0x0300, 0x0302, 0x0303, 
+    0x0304, 0x0305, 0x0307, 0x0308, 0x0309, 0x030a, 0x030b, 0x030d, 
+    0x030e, 0x030f, 0x0310, 0x0312, 0x0313, 0x0314, 0x0315, 0x0316, 
+    0x0318, 0x0319, 0x031a, 0x031b, 0x031d, 0x031e, 0x031f, 0x0320, 
+    0x0322, 0x0323, 0x0324, 0x0325, 0x0326, 0x0328, 0x0329, 0x032a, 
+    0x032b, 0x032d, 0x032e, 0x032f, 0x0330, 0x0332, 0x0333, 0x0334, 
+    0x0335, 0x0337, 0x0338, 0x0339, 0x033b, 0x033c, 0x033d, 0x033e, 
+    0x0340, 0x0341, 0x0342, 0x0343, 0x0345, 0x0346, 0x0347, 0x0348, 
+    0x034a, 0x034b, 0x034c, 0x034e, 0x034f, 0x0350, 0x0351, 0x0353, 
+    0x0354, 0x0355, 0x0356, 0x0358, 0x0359, 0x035a, 0x035c, 0x035d, 
+    0x035e, 0x035f, 0x0361, 0x0362, 0x0363, 0x0365, 0x0366, 0x0367, 
+    0x0369, 0x036a, 0x036b, 0x036c, 0x036e, 0x036f, 0x0370, 0x0372, 
+    0x0373, 0x0374, 0x0376, 0x0377, 0x0378, 0x0379, 0x037b, 0x037c, 
+    0x037d, 0x037f, 0x0380, 0x0381, 0x0383, 0x0384, 0x0385, 0x0387, 
+    0x0388, 0x0389, 0x038b, 0x038c, 0x038d, 0x038f, 0x0390, 0x0391, 
+    0x0393, 0x0394, 0x0395, 0x0397, 0x0398, 0x0399, 0x039b, 0x039c, 
+    0x039d, 0x039f, 0x03a0, 0x03a1, 0x03a3, 0x03a4, 0x03a5, 0x03a7, 
+    0x03a8, 0x03a9, 0x03ab, 0x03ac, 0x03ad, 0x03af, 0x03b0, 0x03b1, 
+    0x03b3, 0x03b4, 0x03b6, 0x03b7, 0x03b8, 0x03ba, 0x03bb, 0x03bc, 
+    0x03be, 0x03bf, 0x03c0, 0x03c2, 0x03c3, 0x03c5, 0x03c6, 0x03c7, 
+    0x03c9, 0x03ca, 0x03cb, 0x03cd, 0x03ce, 0x03d0, 0x03d1, 0x03d2, 
+    0x03d4, 0x03d5, 0x03d6, 0x03d8, 0x03d9, 0x03db, 0x03dc, 0x03dd, 
+    0x03df, 0x03e0, 0x03e2, 0x03e3, 0x03e4, 0x03e6, 0x03e7, 0x03e8, 
+    0x03ea, 0x03eb, 0x03ed, 0x03ee, 0x03ef, 0x03f1, 0x03f2, 0x03f4, 
+    0x03f5, 0x03f7, 0x03f8, 0x03f9, 0x03fb, 0x03fc, 0x03fe, 0x03ff, 
+    0x0400, 0x0402, 0x0403, 0x0405, 0x0406, 0x0407, 0x0409, 0x040a, 
+    0x040c, 0x040d, 0x040f, 0x0410, 0x0411, 0x0413, 0x0414, 0x0416, 
+    0x0417, 0x0419, 0x041a, 0x041b, 0x041d, 0x041e, 0x0420, 0x0421, 
+    0x0423, 0x0424, 0x0426, 0x0427, 0x0428, 0x042a, 0x042b, 0x042d, 
+    0x042e, 0x0430, 0x0431, 0x0433, 0x0434, 0x0436, 0x0437, 0x0438, 
+    0x043a, 0x043b, 0x043d, 0x043e, 0x0440, 0x0441, 0x0443, 0x0444, 
+    0x0446, 0x0447, 0x0449, 0x044a, 0x044b, 0x044d, 0x044e, 0x0450, 
+    0x0451, 0x0453, 0x0454, 0x0456, 0x0457, 0x0459, 0x045a, 0x045c, 
+    0x045d, 0x045f, 0x0460, 0x0462, 0x0463, 0x0465, 0x0466, 0x0468, 
+    0x0469, 0x046b, 0x046c, 0x046e, 0x046f, 0x0471, 0x0472, 0x0474, 
+    0x0475, 0x0477, 0x0478, 0x047a, 0x047b, 0x047d, 0x047e, 0x0480, 
+    0x0481, 0x0483, 0x0484, 0x0486, 0x0487, 0x0489, 0x048a, 0x048c, 
+    0x048d, 0x048f, 0x0490, 0x0492, 0x0493, 0x0495, 0x0496, 0x0498, 
+    0x0499, 0x049b, 0x049c, 0x049e, 0x04a0, 0x04a1, 0x04a3, 0x04a4, 
+    0x04a6, 0x04a7, 0x04a9, 0x04aa, 0x04ac, 0x04ad, 0x04af, 0x04b0, 
+    0x04b2, 0x04b4, 0x04b5, 0x04b7, 0x04b8, 0x04ba, 0x04bb, 0x04bd, 
+    0x04be, 0x04c0, 0x04c2, 0x04c3, 0x04c5, 0x04c6, 0x04c8, 0x04c9, 
+    0x04cb, 0x04cc, 0x04ce, 0x04d0, 0x04d1, 0x04d3, 0x04d4, 0x04d6, 
+    0x04d7, 0x04d9, 0x04db, 0x04dc, 0x04de, 0x04df, 0x04e1, 0x04e2, 
+    0x04e4, 0x04e6, 0x04e7, 0x04e9, 0x04ea, 0x04ec, 0x04ed, 0x04ef, 
+    0x04f1, 0x04f2, 0x04f4, 0x04f5, 0x04f7, 0x04f9, 0x04fa, 0x04fc, 
+    0x04fd, 0x04ff, 0x0501, 0x0502, 0x0504, 0x0505, 0x0507, 0x0509, 
+    0x050a, 0x050c, 0x050d, 0x050f, 0x0511, 0x0512, 0x0514, 0x0515, 
+    0x0517, 0x0519, 0x051a, 0x051c, 0x051e, 0x051f, 0x0521, 0x0522, 
+    0x0524, 0x0526, 0x0527, 0x0529, 0x052b, 0x052c, 0x052e, 0x052f, 
+    0x0531, 0x0533, 0x0534, 0x0536, 0x0538, 0x0539, 0x053b, 0x053c, 
+    0x053e, 0x0540, 0x0541, 0x0543, 0x0545, 0x0546, 0x0548, 0x054a, 
+    0x054b, 0x054d, 0x054f, 0x0550, 0x0552, 0x0554, 0x0555, 0x0557, 
+    0x0559, 0x055a, 0x055c, 0x055e, 0x055f, 0x0561, 0x0562, 0x0564, 
+    0x0566, 0x0567, 0x0569, 0x056b, 0x056c, 0x056e, 0x0570, 0x0572, 
+    0x0573, 0x0575, 0x0577, 0x0578, 0x057a, 0x057c, 0x057d, 0x057f, 
+    0x0581, 0x0582, 0x0584, 0x0586, 0x0587, 0x0589, 0x058b, 0x058c, 
+    0x058e, 0x0590, 0x0592, 0x0593, 0x0595, 0x0597, 0x0598, 0x059a, 
+    0x059c, 0x059d, 0x059f, 0x05a1, 0x05a3, 0x05a4, 0x05a6, 0x05a8, 
+    0x05a9, 0x05ab, 0x05ad, 0x05af, 0x05b0, 0x05b2, 0x05b4, 0x05b5, 
+    0x05b7, 0x05b9, 0x05bb, 0x05bc, 0x05be, 0x05c0, 0x05c1, 0x05c3, 
+    0x05c5, 0x05c7, 0x05c8, 0x05ca, 0x05cc, 0x05ce, 0x05cf, 0x05d1, 
+    0x05d3, 0x05d4, 0x05d6, 0x05d8, 0x05da, 0x05db, 0x05dd, 0x05df, 
+    0x05e1, 0x05e2, 0x05e4, 0x05e6, 0x05e8, 0x05e9, 0x05eb, 0x05ed, 
+    0x05ef, 0x05f0, 0x05f2, 0x05f4, 0x05f6, 0x05f7, 0x05f9, 0x05fb, 
+    0x05fd, 0x05ff, 0x0600, 0x0602, 0x0604, 0x0606, 0x0607, 0x0609, 
+    0x060b, 0x060d, 0x060e, 0x0610, 0x0612, 0x0614, 0x0616, 0x0617, 
+    0x0619, 0x061b, 0x061d, 0x061e, 0x0620, 0x0622, 0x0624, 0x0626, 
+    0x0627, 0x0629, 0x062b, 0x062d, 0x062f, 0x0630, 0x0632, 0x0634, 
+    0x0636, 0x0638, 0x0639, 0x063b, 0x063d, 0x063f, 0x0641, 0x0642, 
+    0x0644, 0x0646, 0x0648, 0x064a, 0x064b, 0x064d, 0x064f, 0x0651, 
+    0x0653, 0x0654, 0x0656, 0x0658, 0x065a, 0x065c, 0x065e, 0x065f, 
+    0x0661, 0x0663, 0x0665, 0x0667, 0x0669, 0x066a, 0x066c, 0x066e, 
+    0x0670, 0x0672, 0x0674, 0x0675, 0x0677, 0x0679, 0x067b, 0x067d, 
+    0x067f, 0x0680, 0x0682, 0x0684, 0x0686, 0x0688, 0x068a, 0x068c, 
+    0x068d, 0x068f, 0x0691, 0x0693, 0x0695, 0x0697, 0x0699, 0x069a, 
+    0x069c, 0x069e, 0x06a0, 0x06a2, 0x06a4, 0x06a6, 0x06a7, 0x06a9, 
+    0x06ab, 0x06ad, 0x06af, 0x06b1, 0x06b3, 0x06b5, 0x06b6, 0x06b8, 
+    0x06ba, 0x06bc, 0x06be, 0x06c0, 0x06c2, 0x06c4, 0x06c5, 0x06c7, 
+    0x06c9, 0x06cb, 0x06cd, 0x06cf, 0x06d1, 0x06d3, 0x06d5, 0x06d6, 
+    0x06d8, 0x06da, 0x06dc, 0x06de, 0x06e0, 0x06e2, 0x06e4, 0x06e6, 
+    0x06e8, 0x06ea, 0x06eb, 0x06ed, 0x06ef, 0x06f1, 0x06f3, 0x06f5, 
+    0x06f7, 0x06fb, 0x06ff, 0x0702, 0x0706, 0x070a, 0x070e, 0x0712, 
+    0x0716, 0x071a, 0x071d, 0x0721, 0x0725, 0x0729, 0x072d, 0x0731, 
+    0x0735, 0x0739, 0x073d, 0x0740, 0x0744, 0x0748, 0x074c, 0x0750, 
+    0x0754, 0x0758, 0x075c, 0x0760, 0x0764, 0x0768, 0x076c, 0x0770, 
+    0x0774, 0x0778, 0x077c, 0x0780, 0x0784, 0x0788, 0x078c, 0x0790, 
+    0x0794, 0x0798, 0x079c, 0x07a0, 0x07a4, 0x07a8, 0x07ac, 0x07b0, 
+    0x07b4, 0x07b8, 0x07bc, 0x07c0, 0x07c4, 0x07c8, 0x07cc, 0x07d0, 
+    0x07d4, 0x07d9, 0x07dd, 0x07e1, 0x07e5, 0x07e9, 0x07ed, 0x07f1, 
+    0x07f5, 0x07f9, 0x07fe, 0x0801, 0x0803, 0x0805, 0x0807, 0x0809, 
+    0x080b, 0x080d, 0x080f, 0x0811, 0x0814, 0x0816, 0x0818, 0x081a, 
+    0x081c, 0x081e, 0x0820, 0x0822, 0x0824, 0x0826, 0x0828, 0x082b, 
+    0x082d, 0x082f, 0x0831, 0x0833, 0x0835, 0x0837, 0x0839, 0x083c, 
+    0x083e, 0x0840, 0x0842, 0x0844, 0x0846, 0x0848, 0x084b, 0x084d, 
+    0x084f, 0x0851, 0x0853, 0x0855, 0x0857, 0x085a, 0x085c, 0x085e, 
+    0x0860, 0x0862, 0x0864, 0x0867, 0x0869, 0x086b, 0x086d, 0x086f, 
+    0x0872, 0x0874, 0x0876, 0x0878, 0x087a, 0x087d, 0x087f, 0x0881, 
+    0x0883, 0x0885, 0x0888, 0x088a, 0x088c, 0x088e, 0x0890, 0x0893, 
+    0x0895, 0x0897, 0x0899, 0x089c, 0x089e, 0x08a0, 0x08a2, 0x08a4, 
+    0x08a7, 0x08a9, 0x08ab, 0x08ad, 0x08b0, 0x08b2, 0x08b4, 0x08b6, 
+    0x08b9, 0x08bb, 0x08bd, 0x08c0, 0x08c2, 0x08c4, 0x08c6, 0x08c9, 
+    0x08cb, 0x08cd, 0x08cf, 0x08d2, 0x08d4, 0x08d6, 0x08d9, 0x08db, 
+    0x08dd, 0x08e0, 0x08e2, 0x08e4, 0x08e6, 0x08e9, 0x08eb, 0x08ed, 
+    0x08f0, 0x08f2, 0x08f4, 0x08f7, 0x08f9, 0x08fb, 0x08fe, 0x0900, 
+    0x0902, 0x0905, 0x0907, 0x0909, 0x090c, 0x090e, 0x0910, 0x0913, 
+    0x0915, 0x0917, 0x091a, 0x091c, 0x091e, 0x0921, 0x0923, 0x0926, 
+    0x0928, 0x092a, 0x092d, 0x092f, 0x0931, 0x0934, 0x0936, 0x0939, 
+    0x093b, 0x093d, 0x0940, 0x0942, 0x0945, 0x0947, 0x0949, 0x094c, 
+    0x094e, 0x0951, 0x0953, 0x0955, 0x0958, 0x095a, 0x095d, 0x095f, 
+    0x0962, 0x0964, 0x0966, 0x0969, 0x096b, 0x096e, 0x0970, 0x0973, 
+    0x0975, 0x0977, 0x097a, 0x097c, 0x097f, 0x0981, 0x0984, 0x0986, 
+    0x0989, 0x098b, 0x098e, 0x0990, 0x0993, 0x0995, 0x0998, 0x099a, 
+    0x099c, 0x099f, 0x09a1, 0x09a4, 0x09a6, 0x09a9, 0x09ab, 0x09ae, 
+    0x09b0, 0x09b3, 0x09b5, 0x09b8, 0x09ba, 0x09bd, 0x09c0, 0x09c2, 
+    0x09c5, 0x09c7, 0x09ca, 0x09cc, 0x09cf, 0x09d1, 0x09d4, 0x09d6, 
+    0x09d9, 0x09db, 0x09de, 0x09e0, 0x09e3, 0x09e6, 0x09e8, 0x09eb, 
+    0x09ed, 0x09f0, 0x09f2, 0x09f5, 0x09f7, 0x09fa, 0x09fd, 0x09ff, 
+    0x0a02, 0x0a04, 0x0a07, 0x0a0a, 0x0a0c, 0x0a0f, 0x0a11, 0x0a14, 
+    0x0a16, 0x0a19, 0x0a1c, 0x0a1e, 0x0a21, 0x0a23, 0x0a26, 0x0a29, 
+    0x0a2b, 0x0a2e, 0x0a31, 0x0a33, 0x0a36, 0x0a38, 0x0a3b, 0x0a3e, 
+    0x0a40, 0x0a43, 0x0a46, 0x0a48, 0x0a4b, 0x0a4e, 0x0a50, 0x0a53, 
+    0x0a55, 0x0a58, 0x0a5b, 0x0a5d, 0x0a60, 0x0a63, 0x0a65, 0x0a68, 
+    0x0a6b, 0x0a6d, 0x0a70, 0x0a73, 0x0a76, 0x0a78, 0x0a7b, 0x0a7e, 
+    0x0a80, 0x0a83, 0x0a86, 0x0a88, 0x0a8b, 0x0a8e, 0x0a90, 0x0a93, 
+    0x0a96, 0x0a99, 0x0a9b, 0x0a9e, 0x0aa1, 0x0aa3, 0x0aa6, 0x0aa9, 
+    0x0aac, 0x0aae, 0x0ab1, 0x0ab4, 0x0ab7, 0x0ab9, 0x0abc, 0x0abf, 
+    0x0ac2, 0x0ac4, 0x0ac7, 0x0aca, 0x0acd, 0x0acf, 0x0ad2, 0x0ad5, 
+    0x0ad8, 0x0ada, 0x0add, 0x0ae0, 0x0ae3, 0x0ae5, 0x0ae8, 0x0aeb, 
+    0x0aee, 0x0af1, 0x0af3, 0x0af6, 0x0af9, 0x0afc, 0x0aff, 0x0b01, 
+    0x0b04, 0x0b07, 0x0b0a, 0x0b0d, 0x0b0f, 0x0b12, 0x0b15, 0x0b18, 
+    0x0b1b, 0x0b1e, 0x0b20, 0x0b23, 0x0b26, 0x0b29, 0x0b2c, 0x0b2f, 
+    0x0b31, 0x0b34, 0x0b37, 0x0b3a, 0x0b3d, 0x0b40, 0x0b43, 0x0b45, 
+    0x0b48, 0x0b4b, 0x0b4e, 0x0b51, 0x0b54, 0x0b57, 0x0b59, 0x0b5c, 
+    0x0b5f, 0x0b62, 0x0b65, 0x0b68, 0x0b6b, 0x0b6e, 0x0b71, 0x0b74, 
+    0x0b76, 0x0b79, 0x0b7c, 0x0b7f, 0x0b82, 0x0b85, 0x0b88, 0x0b8b, 
+    0x0b8e, 0x0b91, 0x0b94, 0x0b96, 0x0b99, 0x0b9c, 0x0b9f, 0x0ba2, 
+    0x0ba5, 0x0ba8, 0x0bab, 0x0bae, 0x0bb1, 0x0bb4, 0x0bb7, 0x0bba, 
+    0x0bbd, 0x0bc0, 0x0bc3, 0x0bc6, 0x0bc9, 0x0bcc, 0x0bcf, 0x0bd2, 
+    0x0bd5, 0x0bd7, 0x0bda, 0x0bdd, 0x0be0, 0x0be3, 0x0be6, 0x0be9, 
+    0x0bec, 0x0bef, 0x0bf2, 0x0bf5, 0x0bf8, 0x0bfb, 0x0bfe, 0x0c01, 
+    0x0c02, 0x0c04, 0x0c05, 0x0c07, 0x0c08, 0x0c0a, 0x0c0b, 0x0c0d, 
+    0x0c0e, 0x0c10, 0x0c11, 0x0c13, 0x0c14, 0x0c16, 0x0c17, 0x0c19, 
+    0x0c1b, 0x0c1c, 0x0c1e, 0x0c1f, 0x0c21, 0x0c22, 0x0c24, 0x0c25, 
+    0x0c27, 0x0c28, 0x0c2a, 0x0c2b, 0x0c2d, 0x0c2f, 0x0c30, 0x0c32, 
+    0x0c33, 0x0c35, 0x0c36, 0x0c38, 0x0c39, 0x0c3b, 0x0c3c, 0x0c3e, 
+    0x0c40, 0x0c41, 0x0c43, 0x0c44, 0x0c46, 0x0c47, 0x0c49, 0x0c4b, 
+    0x0c4c, 0x0c4e, 0x0c4f, 0x0c51, 0x0c52, 0x0c54, 0x0c56, 0x0c57, 
+    0x0c59, 0x0c5a, 0x0c5c, 0x0c5d, 0x0c5f, 0x0c61, 0x0c62, 0x0c64, 
+    0x0c65, 0x0c67, 0x0c69, 0x0c6a, 0x0c6c, 0x0c6d, 0x0c6f, 0x0c70, 
+    0x0c72, 0x0c74, 0x0c75, 0x0c77, 0x0c78, 0x0c7a, 0x0c7c, 0x0c7d, 
+    0x0c7f, 0x0c80, 0x0c82, 0x0c84, 0x0c85, 0x0c87, 0x0c89, 0x0c8a, 
+    0x0c8c, 0x0c8d, 0x0c8f, 0x0c91, 0x0c92, 0x0c94, 0x0c95, 0x0c97, 
+    0x0c99, 0x0c9a, 0x0c9c, 0x0c9e, 0x0c9f, 0x0ca1, 0x0ca3, 0x0ca4, 
+    0x0ca6, 0x0ca7, 0x0ca9, 0x0cab, 0x0cac, 0x0cae, 0x0cb0, 0x0cb1, 
+    0x0cb3, 0x0cb5, 0x0cb6, 0x0cb8, 0x0cba, 0x0cbb, 0x0cbd, 0x0cbe, 
+    0x0cc0, 0x0cc2, 0x0cc3, 0x0cc5, 0x0cc7, 0x0cc8, 0x0cca, 0x0ccc, 
+    0x0ccd, 0x0ccf, 0x0cd1, 0x0cd2, 0x0cd4, 0x0cd6, 0x0cd7, 0x0cd9, 
+    0x0cdb, 0x0cdc, 0x0cde, 0x0ce0, 0x0ce1, 0x0ce3, 0x0ce5, 0x0ce7, 
+    0x0ce8, 0x0cea, 0x0cec, 0x0ced, 0x0cef, 0x0cf1, 0x0cf2, 0x0cf4, 
+    0x0cf6, 0x0cf7, 0x0cf9, 0x0cfb, 0x0cfd, 0x0cfe, 0x0d00, 0x0d02, 
+    0x0d03, 0x0d05, 0x0d07, 0x0d08, 0x0d0a, 0x0d0c, 0x0d0e, 0x0d0f, 
+    0x0d11, 0x0d13, 0x0d14, 0x0d16, 0x0d18, 0x0d1a, 0x0d1b, 0x0d1d, 
+    0x0d1f, 0x0d20, 0x0d22, 0x0d24, 0x0d26, 0x0d27, 0x0d29, 0x0d2b, 
+    0x0d2d, 0x0d2e, 0x0d30, 0x0d32, 0x0d34, 0x0d35, 0x0d37, 0x0d39, 
+    0x0d3b, 0x0d3c, 0x0d3e, 0x0d40, 0x0d42, 0x0d43, 0x0d45, 0x0d47, 
+    0x0d49, 0x0d4a, 0x0d4c, 0x0d4e, 0x0d50, 0x0d51, 0x0d53, 0x0d55, 
+    0x0d57, 0x0d58, 0x0d5a, 0x0d5c, 0x0d5e, 0x0d5f, 0x0d61, 0x0d63, 
+    0x0d65, 0x0d67, 0x0d68, 0x0d6a, 0x0d6c, 0x0d6e, 0x0d6f, 0x0d71, 
+    0x0d73, 0x0d75, 0x0d77, 0x0d78, 0x0d7a, 0x0d7c, 0x0d7e, 0x0d7f, 
+    0x0d81, 0x0d83, 0x0d85, 0x0d87, 0x0d88, 0x0d8a, 0x0d8c, 0x0d8e, 
+    0x0d90, 0x0d91, 0x0d93, 0x0d95, 0x0d97, 0x0d99, 0x0d9b, 0x0d9c, 
+    0x0d9e, 0x0da0, 0x0da2, 0x0da4, 0x0da5, 0x0da7, 0x0da9, 0x0dab, 
+    0x0dad, 0x0daf, 0x0db0, 0x0db2, 0x0db4, 0x0db6, 0x0db8, 0x0dba, 
+    0x0dbb, 0x0dbd, 0x0dbf, 0x0dc1, 0x0dc3, 0x0dc5, 0x0dc6, 0x0dc8, 
+    0x0dca, 0x0dcc, 0x0dce, 0x0dd0, 0x0dd1, 0x0dd3, 0x0dd5, 0x0dd7, 
+    0x0dd9, 0x0ddb, 0x0ddd, 0x0dde, 0x0de0, 0x0de2, 0x0de4, 0x0de6, 
+    0x0de8, 0x0dea, 0x0deb, 0x0ded, 0x0def, 0x0df1, 0x0df3, 0x0df5, 
+    0x0df7, 0x0df9, 0x0dfa, 0x0dfc, 0x0dfe, 0x0e00, 0x0e02, 0x0e04, 
+    0x0e06, 0x0e08, 0x0e09, 0x0e0b, 0x0e0d, 0x0e0f, 0x0e11, 0x0e13, 
+    0x0e15, 0x0e17, 0x0e19, 0x0e1b, 0x0e1c, 0x0e1e, 0x0e20, 0x0e22, 
+    0x0e24, 0x0e26, 0x0e28, 0x0e2a, 0x0e2c, 0x0e2e, 0x0e2f, 0x0e31, 
+    0x0e33, 0x0e35, 0x0e37, 0x0e39, 0x0e3b, 0x0e3d, 0x0e3f, 0x0e41, 
+    0x0e43, 0x0e45, 0x0e47, 0x0e48, 0x0e4a, 0x0e4c, 0x0e4e, 0x0e50, 
+    0x0e52, 0x0e54, 0x0e56, 0x0e58, 0x0e5a, 0x0e5c, 0x0e5e, 0x0e60, 
+    0x0e62, 0x0e64, 0x0e66, 0x0e67, 0x0e69, 0x0e6b, 0x0e6d, 0x0e6f, 
+    0x0e71, 0x0e73, 0x0e75, 0x0e77, 0x0e79, 0x0e7b, 0x0e7d, 0x0e7f, 
+    0x0e81, 0x0e83, 0x0e85, 0x0e87, 0x0e89, 0x0e8b, 0x0e8d, 0x0e8f, 
+    0x0e91, 0x0e93, 0x0e95, 0x0e97, 0x0e99, 0x0e9b, 0x0e9d, 0x0e9f, 
+    0x0ea0, 0x0ea2, 0x0ea4, 0x0ea6, 0x0ea8, 0x0eaa, 0x0eac, 0x0eae, 
+    0x0eb0, 0x0eb2, 0x0eb4, 0x0eb6, 0x0eb8, 0x0eba, 0x0ebc, 0x0ebe, 
+    0x0ec0, 0x0ec2, 0x0ec4, 0x0ec6, 0x0ec8, 0x0eca, 0x0ecc, 0x0ece, 
+    0x0ed1, 0x0ed3, 0x0ed5, 0x0ed7, 0x0ed9, 0x0edb, 0x0edd, 0x0edf, 
+    0x0ee1, 0x0ee3, 0x0ee5, 0x0ee7, 0x0ee9, 0x0eeb, 0x0eed, 0x0eef, 
+    0x0ef1, 0x0ef3, 0x0ef5, 0x0ef7, 0x0ef9, 0x0efb, 0x0efd, 0x0eff, 
+    0x0f01, 0x0f03, 0x0f05, 0x0f07, 0x0f09, 0x0f0b, 0x0f0e, 0x0f10, 
+    0x0f12, 0x0f14, 0x0f16, 0x0f18, 0x0f1a, 0x0f1c, 0x0f1e, 0x0f20, 
+    0x0f22, 0x0f24, 0x0f26, 0x0f28, 0x0f2a, 0x0f2c, 0x0f2f, 0x0f31, 
+    0x0f33, 0x0f35, 0x0f37, 0x0f39, 0x0f3b, 0x0f3d, 0x0f3f, 0x0f41, 
+    0x0f43, 0x0f45, 0x0f48, 0x0f4a, 0x0f4c, 0x0f4e, 0x0f50, 0x0f52, 
+    0x0f54, 0x0f56, 0x0f58, 0x0f5a, 0x0f5d, 0x0f5f, 0x0f61, 0x0f63, 
+    0x0f65, 0x0f67, 0x0f69, 0x0f6b, 0x0f6d, 0x0f6f, 0x0f72, 0x0f74, 
+    0x0f76, 0x0f78, 0x0f7a, 0x0f7c, 0x0f7e, 0x0f80, 0x0f83, 0x0f85, 
+    0x0f87, 0x0f89, 0x0f8b, 0x0f8d, 0x0f8f, 0x0f91, 0x0f94, 0x0f96, 
+    0x0f98, 0x0f9a, 0x0f9c, 0x0f9e, 0x0fa0, 0x0fa3, 0x0fa5, 0x0fa7, 
+    0x0fa9, 0x0fab, 0x0fad, 0x0faf, 0x0fb2, 0x0fb4, 0x0fb6, 0x0fb8, 
+    0x0fba, 0x0fbc, 0x0fbf, 0x0fc1, 0x0fc3, 0x0fc5, 0x0fc7, 0x0fc9, 
+    0x0fcc, 0x0fce, 0x0fd0, 0x0fd2, 0x0fd4, 0x0fd6, 0x0fd9, 0x0fdb, 
+    0x0fdd, 0x0fdf, 0x0fe1, 0x0fe4, 0x0fe6, 0x0fe8, 0x0fea, 0x0fec, 
+    0x0fee, 0x0ff1, 0x0ff3, 0x0ff5, 0x0ff7, 0x0ff9, 0x0ffc, 0x0ffe, 
+    0x1000, 0x1002, 0x1004, 0x1007, 0x1009, 0x100b, 0x100d, 0x100f, 
+    0x1012, 0x1014, 0x1016, 0x1018, 0x101b, 0x101d, 0x101f, 0x1021, 
+    0x1024, 0x1026, 0x1028, 0x102a, 0x102d, 0x102f, 0x1031, 0x1033, 
+    0x1036, 0x1038, 0x103a, 0x103c, 0x103f, 0x1041, 0x1043, 0x1045, 
+    0x1048, 0x104a, 0x104c, 0x104f, 0x1051, 0x1053, 0x1055, 0x1058, 
+    0x105a, 0x105c, 0x105f, 0x1061, 0x1063, 0x1066, 0x1068, 0x106a, 
+    0x106d, 0x106f, 0x1071, 0x1074, 0x1076, 0x1078, 0x107b, 0x107d, 
+    0x107f, 0x1082, 0x1084, 0x1086, 0x1089, 0x108b, 0x108d, 0x1090, 
+    0x1092, 0x1094, 0x1097, 0x1099, 0x109c, 0x109e, 0x10a0, 0x10a3, 
+    0x10a5, 0x10a8, 0x10aa, 0x10ac, 0x10af, 0x10b1, 0x10b3, 0x10b6, 
+    0x10b8, 0x10bb, 0x10bd, 0x10c0, 0x10c2, 0x10c4, 0x10c7, 0x10c9, 
+    0x10cc, 0x10ce, 0x10d1, 0x10d3, 0x10d5, 0x10d8, 0x10da, 0x10dd, 
+    0x10df, 0x10e2, 0x10e4, 0x10e7, 0x10e9, 0x10eb, 0x10ee, 0x10f0, 
+    0x10f3, 0x10f5, 0x10f8, 0x10fa, 0x10fd, 0x10ff, 0x1102, 0x1104, 
+    0x1107, 0x1109, 0x110c, 0x110e, 0x1111, 0x1113, 0x1116, 0x1118, 
+    0x111b, 0x111d, 0x1120, 0x1122, 0x1125, 0x1127, 0x112a, 0x112c, 
+    0x112f, 0x1131, 0x1134, 0x1137, 0x1139, 0x113c, 0x113e, 0x1141, 
+    0x1143, 0x1146, 0x1148, 0x114b, 0x114d, 0x1150, 0x1153, 0x1155, 
+    0x1158, 0x115a, 0x115d, 0x1160, 0x1162, 0x1165, 0x1167, 0x116a, 
+    0x116c, 0x116f, 0x1172, 0x1174, 0x1177, 0x1179, 0x117c, 0x117f, 
+    0x1181, 0x1184, 0x1187, 0x1189, 0x118c, 0x118e, 0x1191, 0x1194, 
+    0x1196, 0x1199, 0x119c, 0x119e, 0x11a1, 0x11a4, 0x11a6, 0x11a9, 
+    0x11ac, 0x11ae, 0x11b1, 0x11b4, 0x11b6, 0x11b9, 0x11bc, 0x11be, 
+    0x11c1, 0x11c4, 0x11c6, 0x11c9, 0x11cc, 0x11ce, 0x11d1, 0x11d4, 
+    0x11d6, 0x11d9, 0x11dc, 0x11df, 0x11e1, 0x11e4, 0x11e7, 0x11e9, 
+    0x11ec, 0x11ef, 0x11f2, 0x11f4, 0x11f7, 0x11fa, 0x11fd, 0x11ff, 
+    0x1202, 0x1205, 0x1208, 0x120a, 0x120d, 0x1210, 0x1213, 0x1215, 
+    0x1218, 0x121b, 0x121e, 0x1220, 0x1223, 0x1226, 0x1229, 0x122c, 
+    0x122e, 0x1231, 0x1234, 0x1237, 0x123a, 0x123c, 0x123f, 0x1242, 
+    0x1245, 0x1248, 0x124a, 0x124d, 0x1250, 0x1253, 0x1256, 0x1259, 
+    0x125b, 0x125e, 0x1261, 0x1264, 0x1267, 0x126a, 0x126c, 0x126f, 
+    0x1272, 0x1275, 0x1278, 0x127b, 0x127e, 0x1280, 0x1283, 0x1286, 
+    0x1289, 0x128c, 0x128f, 0x1292, 0x1295, 0x1297, 0x129a, 0x129d, 
+    0x12a0, 0x12a3, 0x12a6, 0x12a9, 0x12ac, 0x12af, 0x12b2, 0x12b4, 
+    0x12b7, 0x12ba, 0x12bd, 0x12c0, 0x12c3, 0x12c6, 0x12c9, 0x12cc, 
+    0x12cf, 0x12d2, 0x12d5, 0x12d8, 0x12db, 0x12de, 0x12e1, 0x12e3, 
+    0x12e6, 0x12e9, 0x12ec, 0x12ef, 0x12f2, 0x12f5, 0x12f8, 0x12fb, 
+    0x12fe, 0x1301, 0x1304, 0x1307, 0x130a, 0x130d, 0x1310, 0x1313, 
+    0x1316, 0x1319, 0x131c, 0x131f, 0x1322, 0x1325, 0x1328, 0x132b, 
+    0x132e, 0x1331, 0x1334, 0x1337, 0x133a, 0x133d, 0x1341, 0x1344, 
+    0x1347, 0x134a, 0x134d, 0x1350, 0x1353, 0x1356, 0x1359, 0x135c, 
+    0x135f, 0x1362, 0x1365, 0x1368, 0x136b, 0x136e, 0x1372, 0x1375, 
+    0x1378, 0x137b, 0x137e, 0x1381, 0x1384, 0x1387, 0x138a, 0x138d, 
+    0x1391, 0x1394, 0x1397, 0x139a, 0x139d, 0x13a0, 0x13a3, 0x13a6, 
+    0x13aa, 0x13ad, 0x13b0, 0x13b3, 0x13b6, 0x13b9, 0x13bc, 0x13c0, 
+    0x13c3, 0x13c6, 0x13c9, 0x13cc, 0x13cf, 0x13d3, 0x13d6, 0x13d9, 
+    0x13dc, 0x13df, 0x13e2, 0x13e6, 0x13e9, 0x13ec, 0x13ef, 0x13f2, 
+    0x13f6, 0x13f9, 0x13fc, 0x13ff, 0x1401, 0x1403, 0x1404, 0x1406, 
+    0x1408, 0x1409, 0x140b, 0x140d, 0x140e, 0x1410, 0x1411, 0x1413, 
+    0x1415, 0x1416, 0x1418, 0x1419, 0x141b, 0x141d, 0x141e, 0x1420, 
+    0x1422, 0x1423, 0x1425, 0x1427, 0x1428, 0x142a, 0x142b, 0x142d, 
+    0x142f, 0x1430, 0x1432, 0x1434, 0x1435, 0x1437, 0x1439, 0x143a, 
+    0x143c, 0x143e, 0x143f, 0x1441, 0x1443, 0x1444, 0x1446, 0x1448, 
+    0x1449, 0x144b, 0x144d, 0x144e, 0x1450, 0x1452, 0x1453, 0x1455, 
+    0x1457, 0x1458, 0x145a, 0x145c, 0x145d, 0x145f, 0x1461, 0x1462, 
+    0x1464, 0x1466, 0x1467, 0x1469, 0x146b, 0x146d, 0x146e, 0x1470, 
+    0x1472, 0x1473, 0x1475, 0x1477, 0x1478, 0x147a, 0x147c, 0x147e, 
+    0x147f, 0x1481, 0x1483, 0x1484, 0x1486, 0x1488, 0x148a, 0x148b, 
+    0x148d, 0x148f, 0x1490, 0x1492, 0x1494, 0x1496, 0x1497, 0x1499, 
+    0x149b, 0x149d, 0x149e, 0x14a0, 0x14a2, 0x14a4, 0x14a5, 0x14a7, 
+    0x14a9, 0x14ab, 0x14ac, 0x14ae, 0x14b0, 0x14b2, 0x14b3, 0x14b5, 
+    0x14b7, 0x14b9, 0x14ba, 0x14bc, 0x14be, 0x14c0, 0x14c1, 0x14c3, 
+    0x14c5, 0x14c7, 0x14c8, 0x14ca, 0x14cc, 0x14ce, 0x14cf, 0x14d1, 
+    0x14d3, 0x14d5, 0x14d7, 0x14d8, 0x14da, 0x14dc, 0x14de, 0x14e0, 
+    0x14e1, 0x14e3, 0x14e5, 0x14e7, 0x14e8, 0x14ea, 0x14ec, 0x14ee, 
+    0x14f0, 0x14f1, 0x14f3, 0x14f5, 0x14f7, 0x14f9, 0x14fa, 0x14fc, 
+    0x14fe, 0x1500, 0x1502, 0x1504, 0x1505, 0x1507, 0x1509, 0x150b, 
+    0x150d, 0x150e, 0x1510, 0x1512, 0x1514, 0x1516, 0x1518, 0x1519, 
+    0x151b, 0x151d, 0x151f, 0x1521, 0x1523, 0x1524, 0x1526, 0x1528, 
+    0x152a, 0x152c, 0x152e, 0x1530, 0x1531, 0x1533, 0x1535, 0x1537, 
+    0x1539, 0x153b, 0x153d, 0x153e, 0x1540, 0x1542, 0x1544, 0x1546, 
+    0x1548, 0x154a, 0x154b, 0x154d, 0x154f, 0x1551, 0x1553, 0x1555, 
+    0x1557, 0x1559, 0x155a, 0x155c, 0x155e, 0x1560, 0x1562, 0x1564, 
+    0x1566, 0x1568, 0x156a, 0x156b, 0x156d, 0x156f, 0x1571, 0x1573, 
+    0x1575, 0x1577, 0x1579, 0x157b, 0x157d, 0x157e, 0x1580, 0x1582, 
+    0x1584, 0x1586, 0x1588, 0x158a, 0x158c, 0x158e, 0x1590, 0x1592, 
+    0x1594, 0x1595, 0x1597, 0x1599, 0x159b, 0x159d, 0x159f, 0x15a1, 
+    0x15a3, 0x15a5, 0x15a7, 0x15a9, 0x15ab, 0x15ad, 0x15af, 0x15b1, 
+    0x15b3, 0x15b4, 0x15b6, 0x15b8, 0x15ba, 0x15bc, 0x15be, 0x15c0, 
+    0x15c2, 0x15c4, 0x15c6, 0x15c8, 0x15ca, 0x15cc, 0x15ce, 0x15d0, 
+    0x15d2, 0x15d4, 0x15d6, 0x15d8, 0x15da, 0x15dc, 0x15de, 0x15e0, 
+    0x15e2, 0x15e4, 0x15e6, 0x15e8, 0x15ea, 0x15ec, 0x15ee, 0x15f0, 
+    0x15f2, 0x15f4, 0x15f6, 0x15f8, 0x15fa, 0x15fc, 0x15fe, 0x1600, 
+    0x1602, 0x1604, 0x1606, 0x1608, 0x160a, 0x160c, 0x160e, 0x1610, 
+    0x1612, 0x1614, 0x1616, 0x1618, 0x161a, 0x161c, 0x161e, 0x1620, 
+    0x1622, 0x1624, 0x1626, 0x1628, 0x162a, 0x162c, 0x162e, 0x1630, 
+    0x1632, 0x1634, 0x1636, 0x1638, 0x163a, 0x163c, 0x163e, 0x1640, 
+    0x1642, 0x1644, 0x1647, 0x1649, 0x164b, 0x164d, 0x164f, 0x1651, 
+    0x1653, 0x1655, 0x1657, 0x1659, 0x165b, 0x165d, 0x165f, 0x1661, 
+    0x1663, 0x1665, 0x1668, 0x166a, 0x166c, 0x166e, 0x1670, 0x1672, 
+    0x1674, 0x1676, 0x1678, 0x167a, 0x167c, 0x167e, 0x1681, 0x1683, 
+    0x1685, 0x1687, 0x1689, 0x168b, 0x168d, 0x168f, 0x1691, 0x1693, 
+    0x1696, 0x1698, 0x169a, 0x169c, 0x169e, 0x16a0, 0x16a2, 0x16a4, 
+    0x16a6, 0x16a9, 0x16ab, 0x16ad, 0x16af, 0x16b1, 0x16b3, 0x16b5, 
+    0x16b7, 0x16ba, 0x16bc, 0x16be, 0x16c0, 0x16c2, 0x16c4, 0x16c6, 
+    0x16c9, 0x16cb, 0x16cd, 0x16cf, 0x16d1, 0x16d3, 0x16d5, 0x16d8, 
+    0x16da, 0x16dc, 0x16de, 0x16e0, 0x16e2, 0x16e4, 0x16e7, 0x16e9, 
+    0x16eb, 0x16ed, 0x16ef, 0x16f1, 0x16f4, 0x16f6, 0x16f8, 0x16fa, 
+    0x16fc, 0x16ff, 0x1701, 0x1703, 0x1705, 0x1707, 0x1709, 0x170c, 
+    0x170e, 0x1710, 0x1712, 0x1714, 0x1717, 0x1719, 0x171b, 0x171d, 
+    0x171f, 0x1722, 0x1724, 0x1726, 0x1728, 0x172a, 0x172d, 0x172f, 
+    0x1731, 0x1733, 0x1735, 0x1738, 0x173a, 0x173c, 0x173e, 0x1740, 
+    0x1743, 0x1745, 0x1747, 0x1749, 0x174c, 0x174e, 0x1750, 0x1752, 
+    0x1755, 0x1757, 0x1759, 0x175b, 0x175d, 0x1760, 0x1762, 0x1764, 
+    0x1766, 0x1769, 0x176b, 0x176d, 0x176f, 0x1772, 0x1774, 0x1776, 
+    0x1778, 0x177b, 0x177d, 0x177f, 0x1781, 0x1784, 0x1786, 0x1788, 
+    0x178b, 0x178d, 0x178f, 0x1791, 0x1794, 0x1796, 0x1798, 0x179a, 
+    0x179d, 0x179f, 0x17a1, 0x17a4, 0x17a6, 0x17a8, 0x17aa, 0x17ad, 
+    0x17af, 0x17b1, 0x17b4, 0x17b6, 0x17b8, 0x17bb, 0x17bd, 0x17bf, 
+    0x17c1, 0x17c4, 0x17c6, 0x17c8, 0x17cb, 0x17cd, 0x17cf, 0x17d2, 
+    0x17d4, 0x17d6, 0x17d9, 0x17db, 0x17dd, 0x17e0, 0x17e2, 0x17e4, 
+    0x17e6, 0x17e9, 0x17eb, 0x17ed, 0x17f0, 0x17f2, 0x17f4, 0x17f7, 
+    0x17f9, 0x17fb, 0x17fe, 0x1800, 0x1801, 0x1802, 0x1804, 0x1805, 
+    0x1806, 0x1807, 0x1808, 0x1809, 0x180b, 0x180c, 0x180d, 0x180e, 
+    0x180f, 0x1811, 0x1812, 0x1813, 0x1814, 0x1815, 0x1816, 0x1818, 
+    0x1819, 0x181a, 0x181b, 0x181c, 0x181e, 0x181f, 0x1820, 0x1821, 
+    0x1822, 0x1824, 0x1825, 0x1826, 0x1827, 0x1828, 0x182a, 0x182b, 
+    0x182c, 0x182d, 0x182e, 0x1830, 0x1831, 0x1832, 0x1833, 0x1834, 
+    0x1836, 0x1837, 0x1838, 0x1839, 0x183a, 0x183c, 0x183d, 0x183e, 
+    0x183f, 0x1840, 0x1842, 0x1843, 0x1844, 0x1845, 0x1846, 0x1848, 
+    0x1849, 0x184a, 0x184b, 0x184d, 0x184e, 0x184f, 0x1850, 0x1851, 
+    0x1853, 0x1854, 0x1855, 0x1856, 0x1858, 0x1859, 0x185a, 0x185b, 
+    0x185c, 0x185e, 0x185f, 0x1860, 0x1861, 0x1863, 0x1864, 0x1865, 
+    0x1866, 0x1868, 0x1869, 0x186a, 0x186b, 0x186c, 0x186e, 0x186f, 
+    0x1870, 0x1871, 0x1873, 0x1874, 0x1875, 0x1876, 0x1878, 0x1879, 
+    0x187a, 0x187b, 0x187d, 0x187e, 0x187f, 0x1880, 0x1882, 0x1883, 
+    0x1884, 0x1885, 0x1887, 0x1888, 0x1889, 0x188a, 0x188c, 0x188d, 
+    0x188e, 0x188f, 0x1891, 0x1892, 0x1893, 0x1894, 0x1896, 0x1897, 
+    0x1898, 0x189b, 0x189d, 0x18a0, 0x18a2, 0x18a5, 0x18a7, 0x18aa, 
+    0x18ad, 0x18af, 0x18b2, 0x18b4, 0x18b7, 0x18b9, 0x18bc, 0x18bf, 
+    0x18c1, 0x18c4, 0x18c6, 0x18c9, 0x18cb, 0x18ce, 0x18d1, 0x18d3, 
+    0x18d6, 0x18d8, 0x18db, 0x18de, 0x18e0, 0x18e3, 0x18e5, 0x18e8, 
+    0x18eb, 0x18ed, 0x18f0, 0x18f3, 0x18f5, 0x18f8, 0x18fa, 0x18fd, 
+    0x1900, 0x1902, 0x1905, 0x1908, 0x190a, 0x190d, 0x1910, 0x1912, 
+    0x1915, 0x1918, 0x191a, 0x191d, 0x1920, 0x1922, 0x1925, 0x1928, 
+    0x192a, 0x192d, 0x1930, 0x1933, 0x1935, 0x1938, 0x193b, 0x193d, 
+    0x1940, 0x1943, 0x1946, 0x1948, 0x194b, 0x194e, 0x1950, 0x1953, 
+    0x1956, 0x1959, 0x195b, 0x195e, 0x1961, 0x1964, 0x1966, 0x1969, 
+    0x196c, 0x196f, 0x1972, 0x1974, 0x1977, 0x197a, 0x197d, 0x197f, 
+    0x1982, 0x1985, 0x1988, 0x198b, 0x198d, 0x1990, 0x1993, 0x1996, 
+    0x1999, 0x199b, 0x199e, 0x19a1, 0x19a4, 0x19a7, 0x19aa, 0x19ac, 
+    0x19af, 0x19b2, 0x19b5, 0x19b8, 0x19bb, 0x19bd, 0x19c0, 0x19c3, 
+    0x19c6, 0x19c9, 0x19cc, 0x19cf, 0x19d1, 0x19d4, 0x19d7, 0x19da, 
+    0x19dd, 0x19e0, 0x19e3, 0x19e6, 0x19e9, 0x19eb, 0x19ee, 0x19f1, 
+    0x19f4, 0x19f7, 0x19fa, 0x19fd, 0x1a00, 0x1a03, 0x1a06, 0x1a09, 
+    0x1a0c, 0x1a0f, 0x1a11, 0x1a14, 0x1a17, 0x1a1a, 0x1a1d, 0x1a20, 
+    0x1a23, 0x1a26, 0x1a29, 0x1a2c, 0x1a2f, 0x1a32, 0x1a35, 0x1a38, 
+    0x1a3b, 0x1a3e, 0x1a41, 0x1a44, 0x1a47, 0x1a4a, 0x1a4d, 0x1a50, 
+    0x1a53, 0x1a56, 0x1a59, 0x1a5c, 0x1a5f, 0x1a62, 0x1a65, 0x1a68, 
+    0x1a6b, 0x1a6e, 0x1a71, 0x1a74, 0x1a77, 0x1a7a, 0x1a7d, 0x1a80, 
+    0x1a83, 0x1a86, 0x1a8a, 0x1a8d, 0x1a90, 0x1a93, 0x1a96, 0x1a99, 
+    0x1a9c, 0x1a9f, 0x1aa2, 0x1aa5, 0x1aa8, 0x1aab, 0x1aaf, 0x1ab2, 
+    0x1ab5, 0x1ab8, 0x1abb, 0x1abe, 0x1ac1, 0x1ac4, 0x1ac7, 0x1acb, 
+    0x1ace, 0x1ad1, 0x1ad4, 0x1ad7, 0x1ada, 0x1add, 0x1ae1, 0x1ae4, 
+    0x1ae7, 0x1aea, 0x1aed, 0x1af0, 0x1af3, 0x1af7, 0x1afa, 0x1afd, 
+    0x1b00, 0x1b03, 0x1b07, 0x1b0a, 0x1b0d, 0x1b10, 0x1b13, 0x1b16, 
+    0x1b1a, 0x1b1d, 0x1b20, 0x1b23, 0x1b27, 0x1b2a, 0x1b2d, 0x1b30, 
+    0x1b33, 0x1b37, 0x1b3a, 0x1b3d, 0x1b40, 0x1b44, 0x1b47, 0x1b4a, 
+    0x1b4d, 0x1b51, 0x1b54, 0x1b57, 0x1b5a, 0x1b5e, 0x1b61, 0x1b64, 
+    0x1b67, 0x1b6b, 0x1b6e, 0x1b71, 0x1b75, 0x1b78, 0x1b7b, 0x1b7e, 
+    0x1b82, 0x1b85, 0x1b88, 0x1b8c, 0x1b8f, 0x1b92, 0x1b96, 0x1b99, 
+    0x1b9c, 0x1ba0, 0x1ba3, 0x1ba6, 0x1baa, 0x1bad, 0x1bb0, 0x1bb4, 
+    0x1bb7, 0x1bba, 0x1bbe, 0x1bc1, 0x1bc4, 0x1bc8, 0x1bcb, 0x1bcf, 
+    0x1bd2, 0x1bd5, 0x1bd9, 0x1bdc, 0x1be0, 0x1be3, 0x1be6, 0x1bea, 
+    0x1bed, 0x1bf0, 0x1bf4, 0x1bf7, 0x1bfb, 0x1bfe, 0x1c01, 0x1c02, 
+    0x1c04, 0x1c06, 0x1c08, 0x1c09, 0x1c0b, 0x1c0d, 0x1c0f, 0x1c10, 
+    0x1c12, 0x1c14, 0x1c15, 0x1c17, 0x1c19, 0x1c1b, 0x1c1c, 0x1c1e, 
+    0x1c20, 0x1c22, 0x1c23, 0x1c25, 0x1c27, 0x1c29, 0x1c2a, 0x1c2c, 
+    0x1c2e, 0x1c30, 0x1c31, 0x1c33, 0x1c35, 0x1c37, 0x1c38, 0x1c3a, 
+    0x1c3c, 0x1c3e, 0x1c3f, 0x1c41, 0x1c43, 0x1c45, 0x1c46, 0x1c48, 
+    0x1c4a, 0x1c4c, 0x1c4e, 0x1c4f, 0x1c51, 0x1c53, 0x1c55, 0x1c56, 
+    0x1c58, 0x1c5a, 0x1c5c, 0x1c5e, 0x1c5f, 0x1c61, 0x1c63, 0x1c65, 
+    0x1c67, 0x1c68, 0x1c6a, 0x1c6c, 0x1c6e, 0x1c70, 0x1c71, 0x1c73, 
+    0x1c75, 0x1c77, 0x1c79, 0x1c7b, 0x1c7c, 0x1c7e, 0x1c80, 0x1c82, 
+    0x1c84, 0x1c85, 0x1c87, 0x1c89, 0x1c8b, 0x1c8d, 0x1c8f, 0x1c90, 
+    0x1c92, 0x1c94, 0x1c96, 0x1c98, 0x1c9a, 0x1c9c, 0x1c9d, 0x1c9f, 
+    0x1ca1, 0x1ca3, 0x1ca5, 0x1ca7, 0x1ca8, 0x1caa, 0x1cac, 0x1cae, 
+    0x1cb0, 0x1cb2, 0x1cb4, 0x1cb6, 0x1cb7, 0x1cb9, 0x1cbb, 0x1cbd, 
+    0x1cbf, 0x1cc1, 0x1cc3, 0x1cc5, 0x1cc6, 0x1cc8, 0x1cca, 0x1ccc, 
+    0x1cce, 0x1cd0, 0x1cd2, 0x1cd4, 0x1cd6, 0x1cd7, 0x1cd9, 0x1cdb, 
+    0x1cdd, 0x1cdf, 0x1ce1, 0x1ce3, 0x1ce5, 0x1ce7, 0x1ce9, 0x1cea, 
+    0x1cec, 0x1cee, 0x1cf0, 0x1cf2, 0x1cf4, 0x1cf6, 0x1cf8, 0x1cfa, 
+    0x1cfc, 0x1cfe, 0x1d00, 0x1d02, 0x1d03, 0x1d05, 0x1d07, 0x1d09, 
+    0x1d0b, 0x1d0d, 0x1d0f, 0x1d11, 0x1d13, 0x1d15, 0x1d17, 0x1d19, 
+    0x1d1b, 0x1d1d, 0x1d1f, 0x1d21, 0x1d23, 0x1d25, 0x1d27, 0x1d29, 
+    0x1d2a, 0x1d2c, 0x1d2e, 0x1d30, 0x1d32, 0x1d34, 0x1d36, 0x1d38, 
+    0x1d3a, 0x1d3c, 0x1d3e, 0x1d40, 0x1d42, 0x1d44, 0x1d46, 0x1d48, 
+    0x1d4a, 0x1d4c, 0x1d4e, 0x1d50, 0x1d52, 0x1d54, 0x1d56, 0x1d58, 
+    0x1d5a, 0x1d5c, 0x1d5e, 0x1d60, 0x1d62, 0x1d64, 0x1d66, 0x1d68, 
+    0x1d6a, 0x1d6c, 0x1d6e, 0x1d70, 0x1d72, 0x1d74, 0x1d76, 0x1d78, 
+    0x1d7a, 0x1d7c, 0x1d7e, 0x1d80, 0x1d83, 0x1d85, 0x1d87, 0x1d89, 
+    0x1d8b, 0x1d8d, 0x1d8f, 0x1d91, 0x1d93, 0x1d95, 0x1d97, 0x1d99, 
+    0x1d9b, 0x1d9d, 0x1d9f, 0x1da1, 0x1da3, 0x1da5, 0x1da7, 0x1daa, 
+    0x1dac, 0x1dae, 0x1db0, 0x1db2, 0x1db4, 0x1db6, 0x1db8, 0x1dba, 
+    0x1dbc, 0x1dbe, 0x1dc0, 0x1dc2, 0x1dc5, 0x1dc7, 0x1dc9, 0x1dcb, 
+    0x1dcd, 0x1dcf, 0x1dd1, 0x1dd3, 0x1dd5, 0x1dd7, 0x1dd9, 0x1ddc, 
+    0x1dde, 0x1de0, 0x1de2, 0x1de4, 0x1de6, 0x1de8, 0x1dea, 0x1dec, 
+    0x1def, 0x1df1, 0x1df3, 0x1df5, 0x1df7, 0x1df9, 0x1dfb, 0x1dfd, 
+    0x1e00, 0x1e02, 0x1e04, 0x1e06, 0x1e08, 0x1e0a, 0x1e0c, 0x1e0f, 
+    0x1e11, 0x1e13, 0x1e15, 0x1e17, 0x1e19, 0x1e1b, 0x1e1e, 0x1e20, 
+    0x1e22, 0x1e24, 0x1e26, 0x1e28, 0x1e2b, 0x1e2d, 0x1e2f, 0x1e31, 
+    0x1e33, 0x1e35, 0x1e38, 0x1e3a, 0x1e3c, 0x1e3e, 0x1e40, 0x1e42, 
+    0x1e45, 0x1e47, 0x1e49, 0x1e4b, 0x1e4d, 0x1e50, 0x1e52, 0x1e54, 
+    0x1e56, 0x1e58, 0x1e5b, 0x1e5d, 0x1e5f, 0x1e61, 0x1e63, 0x1e66, 
+    0x1e68, 0x1e6a, 0x1e6c, 0x1e6e, 0x1e71, 0x1e73, 0x1e75, 0x1e77, 
+    0x1e7a, 0x1e7c, 0x1e7e, 0x1e80, 0x1e82, 0x1e85, 0x1e87, 0x1e89, 
+    0x1e8b, 0x1e8e, 0x1e90, 0x1e92, 0x1e94, 0x1e97, 0x1e99, 0x1e9b, 
+    0x1e9d, 0x1ea0, 0x1ea2, 0x1ea4, 0x1ea6, 0x1ea9, 0x1eab, 0x1ead, 
+    0x1eaf, 0x1eb2, 0x1eb4, 0x1eb6, 0x1eb8, 0x1ebb, 0x1ebd, 0x1ebf, 
+    0x1ec2, 0x1ec4, 0x1ec6, 0x1ec8, 0x1ecb, 0x1ecd, 0x1ecf, 0x1ed2, 
+    0x1ed4, 0x1ed6, 0x1ed8, 0x1edb, 0x1edd, 0x1edf, 0x1ee2, 0x1ee4, 
+    0x1ee6, 0x1ee8, 0x1eeb, 0x1eed, 0x1eef, 0x1ef2, 0x1ef4, 0x1ef6, 
+    0x1ef9, 0x1efb, 0x1efd, 0x1f00, 0x1f02, 0x1f04, 0x1f07, 0x1f09, 
+    0x1f0b, 0x1f0e, 0x1f10, 0x1f12, 0x1f15, 0x1f17, 0x1f19, 0x1f1c, 
+    0x1f1e, 0x1f20, 0x1f23, 0x1f25, 0x1f27, 0x1f2a, 0x1f2c, 0x1f2e, 
+    0x1f31, 0x1f33, 0x1f35, 0x1f38, 0x1f3a, 0x1f3c, 0x1f3f, 0x1f41, 
+    0x1f44, 0x1f46, 0x1f48, 0x1f4b, 0x1f4d, 0x1f4f, 0x1f52, 0x1f54, 
+    0x1f57, 0x1f59, 0x1f5b, 0x1f5e, 0x1f60, 0x1f62, 0x1f65, 0x1f67, 
+    0x1f6a, 0x1f6c, 0x1f6e, 0x1f71, 0x1f73, 0x1f76, 0x1f78, 0x1f7a, 
+    0x1f7d, 0x1f7f, 0x1f82, 0x1f84, 0x1f87, 0x1f89, 0x1f8b, 0x1f8e, 
+    0x1f90, 0x1f93, 0x1f95, 0x1f97, 0x1f9a, 0x1f9c, 0x1f9f, 0x1fa1, 
+    0x1fa4, 0x1fa6, 0x1fa8, 0x1fab, 0x1fad, 0x1fb0, 0x1fb2, 0x1fb5, 
+    0x1fb7, 0x1fba, 0x1fbc, 0x1fbe, 0x1fc1, 0x1fc3, 0x1fc6, 0x1fc8, 
+    0x1fcb, 0x1fcd, 0x1fd0, 0x1fd2, 0x1fd5, 0x1fd7, 0x1fda, 0x1fdc, 
+    0x1fde, 0x1fe1, 0x1fe3, 0x1fe6, 0x1fe8, 0x1feb, 0x1fed, 0x1ff0, 
+    0x1ff2, 0x1ff5, 0x1ff7, 0x1ffa, 0x1ffc, 0x1fff, 0x2001, 0x2002, 
+    0x2003, 0x2004, 0x2006, 0x2007, 0x2008, 0x2009, 0x200b, 0x200c, 
+    0x200d, 0x200e, 0x2010, 0x2011, 0x2012, 0x2013, 0x2015, 0x2016, 
+    0x2017, 0x2018, 0x201a, 0x201b, 0x201c, 0x201e, 0x201f, 0x2020, 
+    0x2021, 0x2023, 0x2024, 0x2025, 0x2026, 0x2028, 0x2029, 0x202a, 
+    0x202c, 0x202d, 0x202e, 0x202f, 0x2031, 0x2032, 0x2033, 0x2034, 
+    0x2036, 0x2037, 0x2038, 0x203a, 0x203b, 0x203c, 0x203d, 0x203f, 
+    0x2040, 0x2041, 0x2043, 0x2044, 0x2045, 0x2047, 0x2048, 0x2049, 
+    0x204a, 0x204c, 0x204d, 0x204e, 0x2050, 0x2051, 0x2052, 0x2054, 
+    0x2055, 0x2056, 0x2057, 0x2059, 0x205a, 0x205b, 0x205d, 0x205e, 
+    0x205f, 0x2061, 0x2062, 0x2063, 0x2065, 0x2066, 0x2067, 0x2068, 
+    0x206a, 0x206b, 0x206c, 0x206e, 0x206f, 0x2070, 0x2072, 0x2073, 
+    0x2074, 0x2076, 0x2077, 0x2078, 0x207a, 0x207b, 0x207c, 0x207e, 
+    0x207f, 0x2080, 0x2082, 0x2083, 0x2084, 0x2086, 0x2087, 0x2088, 
+    0x208a, 0x208b, 0x208c, 0x208e, 0x208f, 0x2090, 0x2092, 0x2093, 
+    0x2094, 0x2096, 0x2097, 0x2098, 0x209a, 0x209b, 0x209c, 0x209e, 
+    0x209f, 0x20a0, 0x20a2, 0x20a3, 0x20a5, 0x20a6, 0x20a7, 0x20a9, 
+    0x20aa, 0x20ab, 0x20ad, 0x20ae, 0x20af, 0x20b1, 0x20b2, 0x20b3, 
+    0x20b5, 0x20b6, 0x20b8, 0x20b9, 0x20ba, 0x20bc, 0x20bd, 0x20be, 
+    0x20c0, 0x20c1, 0x20c2, 0x20c4, 0x20c5, 0x20c7, 0x20c8, 0x20c9, 
+    0x20cb, 0x20cc, 0x20cd, 0x20cf, 0x20d0, 0x20d2, 0x20d3, 0x20d4, 
+    0x20d6, 0x20d7, 0x20d9, 0x20da, 0x20db, 0x20dd, 0x20de, 0x20df, 
+    0x20e1, 0x20e2, 0x20e4, 0x20e5, 0x20e6, 0x20e8, 0x20e9, 0x20eb, 
+    0x20ec, 0x20ed, 0x20ef, 0x20f0, 0x20f2, 0x20f3, 0x20f4, 0x20f6, 
+    0x20f7, 0x20f9, 0x20fa, 0x20fb, 0x20fd, 0x20fe, 0x2100, 0x2101, 
+    0x2102, 0x2104, 0x2105, 0x2107, 0x2108, 0x210a, 0x210b, 0x210c, 
+    0x210e, 0x210f, 0x2111, 0x2112, 0x2113, 0x2115, 0x2116, 0x2118, 
+    0x2119, 0x211b, 0x211c, 0x211d, 0x211f, 0x2120, 0x2122, 0x2123, 
+    0x2125, 0x2126, 0x2127, 0x2129, 0x212a, 0x212c, 0x212d, 0x212f, 
+    0x2130, 0x2131, 0x2133, 0x2134, 0x2136, 0x2137, 0x2139, 0x213a, 
+    0x213c, 0x213d, 0x213e, 0x2140, 0x2141, 0x2143, 0x2144, 0x2146, 
+    0x2147, 0x214a, 0x214d, 0x2150, 0x2153, 0x2156, 0x2159, 0x215c, 
+    0x215f, 0x2161, 0x2164, 0x2167, 0x216a, 0x216d, 0x2170, 0x2173, 
+    0x2176, 0x2179, 0x217c, 0x217f, 0x2182, 0x2185, 0x2188, 0x218b, 
+    0x218e, 0x2191, 0x2194, 0x2197, 0x219a, 0x219d, 0x21a0, 0x21a3, 
+    0x21a6, 0x21a9, 0x21ac, 0x21af, 0x21b2, 0x21b5, 0x21b8, 0x21bb, 
+    0x21be, 0x21c1, 0x21c4, 0x21c7, 0x21ca, 0x21cd, 0x21d0, 0x21d3, 
+    0x21d6, 0x21da, 0x21dd, 0x21e0, 0x21e3, 0x21e6, 0x21e9, 0x21ec, 
+    0x21ef, 0x21f2, 0x21f5, 0x21f8, 0x21fb, 0x21ff, 0x2202, 0x2205, 
+    0x2208, 0x220b, 0x220e, 0x2211, 0x2214, 0x2218, 0x221b, 0x221e, 
+    0x2221, 0x2224, 0x2227, 0x222b, 0x222e, 0x2231, 0x2234, 0x2237, 
+    0x223a, 0x223e, 0x2241, 0x2244, 0x2247, 0x224a, 0x224d, 0x2251, 
+    0x2254, 0x2257, 0x225a, 0x225e, 0x2261, 0x2264, 0x2267, 0x226a, 
+    0x226e, 0x2271, 0x2274, 0x2277, 0x227b, 0x227e, 0x2281, 0x2284, 
+    0x2288, 0x228b, 0x228e, 0x2291, 0x2295, 0x2298, 0x229b, 0x229f, 
+    0x22a2, 0x22a5, 0x22a8, 0x22ac, 0x22af, 0x22b2, 0x22b6, 0x22b9, 
+    0x22bc, 0x22c0, 0x22c3, 0x22c6, 0x22c9, 0x22cd, 0x22d0, 0x22d4, 
+    0x22d7, 0x22da, 0x22de, 0x22e1, 0x22e4, 0x22e8, 0x22eb, 0x22ee, 
+    0x22f2, 0x22f5, 0x22f8, 0x22fc, 0x22ff, 0x2303, 0x2306, 0x2309, 
+    0x230d, 0x2310, 0x2314, 0x2317, 0x231a, 0x231e, 0x2321, 0x2325, 
+    0x2328, 0x232c, 0x232f, 0x2332, 0x2336, 0x2339, 0x233d, 0x2340, 
+    0x2344, 0x2347, 0x234b, 0x234e, 0x2351, 0x2355, 0x2358, 0x235c, 
+    0x235f, 0x2363, 0x2366, 0x236a, 0x236d, 0x2371, 0x2374, 0x2378, 
+    0x237b, 0x237f, 0x2382, 0x2386, 0x2389, 0x238d, 0x2390, 0x2394, 
+    0x2398, 0x239b, 0x239f, 0x23a2, 0x23a6, 0x23a9, 0x23ad, 0x23b0, 
+    0x23b4, 0x23b8, 0x23bb, 0x23bf, 0x23c2, 0x23c6, 0x23c9, 0x23cd, 
+    0x23d1, 0x23d4, 0x23d8, 0x23db, 0x23df, 0x23e3, 0x23e6, 0x23ea, 
+    0x23ee, 0x23f1, 0x23f5, 0x23f8, 0x23fc, 0x2400, 0x2402, 0x2403, 
+    0x2405, 0x2407, 0x2409, 0x240b, 0x240d, 0x240e, 0x2410, 0x2412, 
+    0x2414, 0x2416, 0x2418, 0x241a, 0x241b, 0x241d, 0x241f, 0x2421, 
+    0x2423, 0x2425, 0x2426, 0x2428, 0x242a, 0x242c, 0x242e, 0x2430, 
+    0x2432, 0x2434, 0x2435, 0x2437, 0x2439, 0x243b, 0x243d, 0x243f, 
+    0x2441, 0x2443, 0x2444, 0x2446, 0x2448, 0x244a, 0x244c, 0x244e, 
+    0x2450, 0x2452, 0x2454, 0x2455, 0x2457, 0x2459, 0x245b, 0x245d, 
+    0x245f, 0x2461, 0x2463, 0x2465, 0x2467, 0x2469, 0x246b, 0x246c, 
+    0x246e, 0x2470, 0x2472, 0x2474, 0x2476, 0x2478, 0x247a, 0x247c, 
+    0x247e, 0x2480, 0x2482, 0x2484, 0x2486, 0x2488, 0x2489, 0x248b, 
+    0x248d, 0x248f, 0x2491, 0x2493, 0x2495, 0x2497, 0x2499, 0x249b, 
+    0x249d, 0x249f, 0x24a1, 0x24a3, 0x24a5, 0x24a7, 0x24a9, 0x24ab, 
+    0x24ad, 0x24af, 0x24b1, 0x24b3, 0x24b5, 0x24b7, 0x24b9, 0x24bb, 
+    0x24bd, 0x24bf, 0x24c1, 0x24c3, 0x24c5, 0x24c7, 0x24c9, 0x24cb, 
+    0x24cd, 0x24cf, 0x24d1, 0x24d3, 0x24d5, 0x24d7, 0x24d9, 0x24db, 
+    0x24dd, 0x24df, 0x24e1, 0x24e3, 0x24e5, 0x24e7, 0x24e9, 0x24eb, 
+    0x24ed, 0x24ef, 0x24f1, 0x24f3, 0x24f5, 0x24f7, 0x24fa, 0x24fc, 
+    0x24fe, 0x2500, 0x2502, 0x2504, 0x2506, 0x2508, 0x250a, 0x250c, 
+    0x250e, 0x2510, 0x2512, 0x2514, 0x2516, 0x2519, 0x251b, 0x251d, 
+    0x251f, 0x2521, 0x2523, 0x2525, 0x2527, 0x2529, 0x252b, 0x252d, 
+    0x252f, 0x2532, 0x2534, 0x2536, 0x2538, 0x253a, 0x253c, 0x253e, 
+    0x2540, 0x2542, 0x2545, 0x2547, 0x2549, 0x254b, 0x254d, 0x254f, 
+    0x2551, 0x2553, 0x2556, 0x2558, 0x255a, 0x255c, 0x255e, 0x2560, 
+    0x2562, 0x2564, 0x2567, 0x2569, 0x256b, 0x256d, 0x256f, 0x2571, 
+    0x2574, 0x2576, 0x2578, 0x257a, 0x257c, 0x257e, 0x2581, 0x2583, 
+    0x2585, 0x2587, 0x2589, 0x258b, 0x258e, 0x2590, 0x2592, 0x2594, 
+    0x2596, 0x2598, 0x259b, 0x259d, 0x259f, 0x25a1, 0x25a3, 0x25a6, 
+    0x25a8, 0x25aa, 0x25ac, 0x25ae, 0x25b1, 0x25b3, 0x25b5, 0x25b7, 
+    0x25b9, 0x25bc, 0x25be, 0x25c0, 0x25c2, 0x25c5, 0x25c7, 0x25c9, 
+    0x25cb, 0x25cd, 0x25d0, 0x25d2, 0x25d4, 0x25d6, 0x25d9, 0x25db, 
+    0x25dd, 0x25df, 0x25e2, 0x25e4, 0x25e6, 0x25e8, 0x25eb, 0x25ed, 
+    0x25ef, 0x25f1, 0x25f4, 0x25f6, 0x25f8, 0x25fa, 0x25fd, 0x25ff, 
+    0x2601, 0x2604, 0x2606, 0x2608, 0x260a, 0x260d, 0x260f, 0x2611, 
+    0x2614, 0x2616, 0x2618, 0x261a, 0x261d, 0x261f, 0x2621, 0x2624, 
+    0x2626, 0x2628, 0x262a, 0x262d, 0x262f, 0x2631, 0x2634, 0x2636, 
+    0x2638, 0x263b, 0x263d, 0x263f, 0x2642, 0x2644, 0x2646, 0x2649, 
+    0x264b, 0x264d, 0x2650, 0x2652, 0x2654, 0x2657, 0x2659, 0x265b, 
+    0x265e, 0x2660, 0x2662, 0x2665, 0x2667, 0x2669, 0x266c, 0x266e, 
+    0x2670, 0x2673, 0x2675, 0x2678, 0x267a, 0x267c, 0x267f, 0x2681, 
+    0x2683, 0x2686, 0x2688, 0x268b, 0x268d, 0x268f, 0x2692, 0x2694, 
+    0x2696, 0x2699, 0x269b, 0x269e, 0x26a0, 0x26a2, 0x26a5, 0x26a7, 
+    0x26aa, 0x26ac, 0x26ae, 0x26b1, 0x26b3, 0x26b6, 0x26b8, 0x26bb, 
+    0x26bd, 0x26bf, 0x26c2, 0x26c4, 0x26c7, 0x26c9, 0x26cc, 0x26ce, 
+    0x26d0, 0x26d3, 0x26d5, 0x26d8, 0x26da, 0x26dd, 0x26df, 0x26e1, 
+    0x26e4, 0x26e6, 0x26e9, 0x26eb, 0x26ee, 0x26f0, 0x26f3, 0x26f5, 
+    0x26f8, 0x26fa, 0x26fd, 0x26ff, 0x2701, 0x2704, 0x2706, 0x2709, 
+    0x270b, 0x270e, 0x2710, 0x2713, 0x2715, 0x2718, 0x271a, 0x271d, 
+    0x271f, 0x2722, 0x2724, 0x2727, 0x2729, 0x272c, 0x272e, 0x2731, 
+    0x2733, 0x2736, 0x2738, 0x273b, 0x273d, 0x2740, 0x2742, 0x2745, 
+    0x2747, 0x274a, 0x274c, 0x274f, 0x2752, 0x2754, 0x2757, 0x2759, 
+    0x275c, 0x275e, 0x2761, 0x2763, 0x2766, 0x2768, 0x276b, 0x276d, 
+    0x2770, 0x2773, 0x2775, 0x2778, 0x277a, 0x277d, 0x277f, 0x2782, 
+    0x2785, 0x2787, 0x278a, 0x278c, 0x278f, 0x2791, 0x2794, 0x2797, 
+    0x2799, 0x279c, 0x279e, 0x27a1, 0x27a4, 0x27a6, 0x27a9, 0x27ab, 
+    0x27ae, 0x27b0, 0x27b3, 0x27b6, 0x27b8, 0x27bb, 0x27be, 0x27c0, 
+    0x27c3, 0x27c5, 0x27c8, 0x27cb, 0x27cd, 0x27d0, 0x27d2, 0x27d5, 
+    0x27d8, 0x27da, 0x27dd, 0x27e0, 0x27e2, 0x27e5, 0x27e8, 0x27ea, 
+    0x27ed, 0x27ef, 0x27f2, 0x27f5, 0x27f7, 0x27fa, 0x27fd, 0x27ff, 
+    0x2801, 0x2802, 0x2804, 0x2805, 0x2806, 0x2808, 0x2809, 0x280a, 
+    0x280c, 0x280d, 0x280e, 0x2810, 0x2811, 0x2812, 0x2814, 0x2815, 
+    0x2816, 0x2818, 0x2819, 0x281a, 0x281c, 0x281d, 0x281e, 0x2820, 
+    0x2821, 0x2823, 0x2824, 0x2825, 0x2827, 0x2828, 0x2829, 0x282b, 
+    0x282c, 0x282d, 0x282f, 0x2830, 0x2831, 0x2833, 0x2834, 0x2836, 
+    0x2837, 0x2838, 0x283a, 0x283b, 0x283c, 0x283e, 0x283f, 0x2841, 
+    0x2842, 0x2843, 0x2845, 0x2846, 0x2847, 0x2849, 0x284a, 0x284c, 
+    0x284d, 0x284e, 0x2850, 0x2851, 0x2852, 0x2854, 0x2855, 0x2857, 
+    0x2858, 0x2859, 0x285b, 0x285c, 0x285e, 0x285f, 0x2860, 0x2862, 
+    0x2863, 0x2865, 0x2866, 0x2867, 0x2869, 0x286a, 0x286c, 0x286d, 
+    0x286e, 0x2870, 0x2871, 0x2873, 0x2874, 0x2875, 0x2877, 0x2878, 
+    0x287a, 0x287b, 0x287d, 0x287e, 0x287f, 0x2881, 0x2882, 0x2884, 
+    0x2885, 0x2886, 0x2888, 0x2889, 0x288b, 0x288c, 0x288e, 0x288f, 
+    0x2890, 0x2892, 0x2893, 0x2895, 0x2896, 0x2898, 0x2899, 0x289a, 
+    0x289c, 0x289d, 0x289f, 0x28a0, 0x28a2, 0x28a3, 0x28a4, 0x28a6, 
+    0x28a7, 0x28a9, 0x28aa, 0x28ac, 0x28ad, 0x28af, 0x28b0, 0x28b1, 
+    0x28b3, 0x28b4, 0x28b6, 0x28b7, 0x28b9, 0x28ba, 0x28bc, 0x28bd, 
+    0x28bf, 0x28c0, 0x28c2, 0x28c3, 0x28c4, 0x28c6, 0x28c7, 0x28c9, 
+    0x28ca, 0x28cc, 0x28cd, 0x28cf, 0x28d0, 0x28d2, 0x28d3, 0x28d5, 
+    0x28d6, 0x28d8, 0x28d9, 0x28da, 0x28dc, 0x28dd, 0x28df, 0x28e0, 
+    0x28e2, 0x28e3, 0x28e5, 0x28e6, 0x28e8, 0x28e9, 0x28eb, 0x28ec, 
+    0x28ee, 0x28ef, 0x28f1, 0x28f2, 0x28f4, 0x28f5, 0x28f7, 0x28f8, 
+    0x28fa, 0x28fb, 0x28fd, 0x28fe, 0x2900, 0x2901, 0x2903, 0x2904, 
+    0x2906, 0x2907, 0x2909, 0x290a, 0x290c, 0x290d, 0x290f, 0x2910, 
+    0x2912, 0x2913, 0x2915, 0x2916, 0x2918, 0x2919, 0x291b, 0x291c, 
+    0x291e, 0x291f, 0x2921, 0x2922, 0x2924, 0x2926, 0x2927, 0x2929, 
+    0x292a, 0x292c, 0x292d, 0x292f, 0x2930, 0x2932, 0x2933, 0x2935, 
+    0x2936, 0x2938, 0x2939, 0x293b, 0x293c, 0x293e, 0x2940, 0x2941, 
+    0x2943, 0x2944, 0x2946, 0x2947, 0x2949, 0x294a, 0x294c, 0x294d, 
+    0x294f, 0x2951, 0x2952, 0x2954, 0x2955, 0x2957, 0x2958, 0x295a, 
+    0x295b, 0x295d, 0x295f, 0x2960, 0x2962, 0x2963, 0x2965, 0x2966, 
+    0x2968, 0x296a, 0x296b, 0x296d, 0x296e, 0x2970, 0x2971, 0x2973, 
+    0x2975, 0x2976, 0x2978, 0x2979, 0x297b, 0x297c, 0x297e, 0x2980, 
+    0x2981, 0x2983, 0x2984, 0x2986, 0x2987, 0x2989, 0x298b, 0x298c, 
+    0x298e, 0x298f, 0x2991, 0x2993, 0x2994, 0x2996, 0x2997, 0x2999, 
+    0x299b, 0x299c, 0x299e, 0x299f, 0x29a1, 0x29a3, 0x29a4, 0x29a6, 
+    0x29a7, 0x29a9, 0x29ab, 0x29ac, 0x29ae, 0x29af, 0x29b1, 0x29b3, 
+    0x29b4, 0x29b6, 0x29b7, 0x29b9, 0x29bb, 0x29bc, 0x29be, 0x29c0, 
+    0x29c1, 0x29c3, 0x29c4, 0x29c6, 0x29c8, 0x29c9, 0x29cb, 0x29cd, 
+    0x29ce, 0x29d0, 0x29d1, 0x29d3, 0x29d5, 0x29d6, 0x29d8, 0x29da, 
+    0x29db, 0x29dd, 0x29df, 0x29e0, 0x29e2, 0x29e3, 0x29e5, 0x29e7, 
+    0x29e8, 0x29ea, 0x29ec, 0x29ed, 0x29ef, 0x29f1, 0x29f2, 0x29f4, 
+    0x29f6, 0x29f7, 0x29f9, 0x29fb, 0x29fc, 0x29fe, 0x29ff, 0x2a01, 
+    0x2a03, 0x2a04, 0x2a06, 0x2a08, 0x2a09, 0x2a0b, 0x2a0d, 0x2a0e, 
+    0x2a10, 0x2a13, 0x2a17, 0x2a1a, 0x2a1d, 0x2a21, 0x2a24, 0x2a28, 
+    0x2a2b, 0x2a2e, 0x2a32, 0x2a35, 0x2a38, 0x2a3c, 0x2a3f, 0x2a43, 
+    0x2a46, 0x2a49, 0x2a4d, 0x2a50, 0x2a54, 0x2a57, 0x2a5a, 0x2a5e, 
+    0x2a61, 0x2a65, 0x2a68, 0x2a6c, 0x2a6f, 0x2a72, 0x2a76, 0x2a79, 
+    0x2a7d, 0x2a80, 0x2a84, 0x2a87, 0x2a8b, 0x2a8e, 0x2a92, 0x2a95, 
+    0x2a99, 0x2a9c, 0x2aa0, 0x2aa3, 0x2aa7, 0x2aaa, 0x2aae, 0x2ab1, 
+    0x2ab5, 0x2ab8, 0x2abc, 0x2abf, 0x2ac3, 0x2ac6, 0x2aca, 0x2acd, 
+    0x2ad1, 0x2ad5, 0x2ad8, 0x2adc, 0x2adf, 0x2ae3, 0x2ae6, 0x2aea, 
+    0x2aee, 0x2af1, 0x2af5, 0x2af8, 0x2afc, 0x2b00, 0x2b03, 0x2b07, 
+    0x2b0a, 0x2b0e, 0x2b12, 0x2b15, 0x2b19, 0x2b1c, 0x2b20, 0x2b24, 
+    0x2b27, 0x2b2b, 0x2b2f, 0x2b32, 0x2b36, 0x2b3a, 0x2b3d, 0x2b41, 
+    0x2b45, 0x2b48, 0x2b4c, 0x2b50, 0x2b54, 0x2b57, 0x2b5b, 0x2b5f, 
+    0x2b62, 0x2b66, 0x2b6a, 0x2b6d, 0x2b71, 0x2b75, 0x2b79, 0x2b7c, 
+    0x2b80, 0x2b84, 0x2b88, 0x2b8b, 0x2b8f, 0x2b93, 0x2b97, 0x2b9a, 
+    0x2b9e, 0x2ba2, 0x2ba6, 0x2baa, 0x2bad, 0x2bb1, 0x2bb5, 0x2bb9, 
+    0x2bbd, 0x2bc0, 0x2bc4, 0x2bc8, 0x2bcc, 0x2bd0, 0x2bd4, 0x2bd7, 
+    0x2bdb, 0x2bdf, 0x2be3, 0x2be7, 0x2beb, 0x2bee, 0x2bf2, 0x2bf6, 
+    0x2bfa, 0x2bfe, 0x2c01, 0x2c03, 0x2c05, 0x2c07, 0x2c09, 0x2c0b, 
+    0x2c0d, 0x2c0f, 0x2c10, 0x2c12, 0x2c14, 0x2c16, 0x2c18, 0x2c1a, 
+    0x2c1c, 0x2c1e, 0x2c20, 0x2c22, 0x2c24, 0x2c26, 0x2c28, 0x2c2a, 
+    0x2c2c, 0x2c2e, 0x2c30, 0x2c32, 0x2c34, 0x2c36, 0x2c38, 0x2c3a, 
+    0x2c3c, 0x2c3e, 0x2c40, 0x2c42, 0x2c44, 0x2c46, 0x2c48, 0x2c4a, 
+    0x2c4c, 0x2c4e, 0x2c50, 0x2c52, 0x2c54, 0x2c56, 0x2c58, 0x2c5a, 
+    0x2c5c, 0x2c5e, 0x2c60, 0x2c62, 0x2c64, 0x2c66, 0x2c69, 0x2c6b, 
+    0x2c6d, 0x2c6f, 0x2c71, 0x2c73, 0x2c75, 0x2c77, 0x2c79, 0x2c7b, 
+    0x2c7d, 0x2c7f, 0x2c81, 0x2c83, 0x2c85, 0x2c87, 0x2c8a, 0x2c8c, 
+    0x2c8e, 0x2c90, 0x2c92, 0x2c94, 0x2c96, 0x2c98, 0x2c9a, 0x2c9c, 
+    0x2c9e, 0x2ca0, 0x2ca3, 0x2ca5, 0x2ca7, 0x2ca9, 0x2cab, 0x2cad, 
+    0x2caf, 0x2cb1, 0x2cb3, 0x2cb6, 0x2cb8, 0x2cba, 0x2cbc, 0x2cbe, 
+    0x2cc0, 0x2cc2, 0x2cc4, 0x2cc7, 0x2cc9, 0x2ccb, 0x2ccd, 0x2ccf, 
+    0x2cd1, 0x2cd3, 0x2cd6, 0x2cd8, 0x2cda, 0x2cdc, 0x2cde, 0x2ce0, 
+    0x2ce3, 0x2ce5, 0x2ce7, 0x2ce9, 0x2ceb, 0x2ced, 0x2cf0, 0x2cf2, 
+    0x2cf4, 0x2cf6, 0x2cf8, 0x2cfa, 0x2cfd, 0x2cff, 0x2d01, 0x2d03, 
+    0x2d05, 0x2d08, 0x2d0a, 0x2d0c, 0x2d0e, 0x2d10, 0x2d13, 0x2d15, 
+    0x2d17, 0x2d19, 0x2d1b, 0x2d1e, 0x2d20, 0x2d22, 0x2d24, 0x2d27, 
+    0x2d29, 0x2d2b, 0x2d2d, 0x2d2f, 0x2d32, 0x2d34, 0x2d36, 0x2d38, 
+    0x2d3b, 0x2d3d, 0x2d3f, 0x2d41, 0x2d44, 0x2d46, 0x2d48, 0x2d4a, 
+    0x2d4d, 0x2d4f, 0x2d51, 0x2d54, 0x2d56, 0x2d58, 0x2d5a, 0x2d5d, 
+    0x2d5f, 0x2d61, 0x2d63, 0x2d66, 0x2d68, 0x2d6a, 0x2d6d, 0x2d6f, 
+    0x2d71, 0x2d73, 0x2d76, 0x2d78, 0x2d7a, 0x2d7d, 0x2d7f, 0x2d81, 
+    0x2d84, 0x2d86, 0x2d88, 0x2d8b, 0x2d8d, 0x2d8f, 0x2d91, 0x2d94, 
+    0x2d96, 0x2d98, 0x2d9b, 0x2d9d, 0x2d9f, 0x2da2, 0x2da4, 0x2da6, 
+    0x2da9, 0x2dab, 0x2dae, 0x2db0, 0x2db2, 0x2db5, 0x2db7, 0x2db9, 
+    0x2dbc, 0x2dbe, 0x2dc0, 0x2dc3, 0x2dc5, 0x2dc7, 0x2dca, 0x2dcc, 
+    0x2dcf, 0x2dd1, 0x2dd3, 0x2dd6, 0x2dd8, 0x2dda, 0x2ddd, 0x2ddf, 
+    0x2de2, 0x2de4, 0x2de6, 0x2de9, 0x2deb, 0x2dee, 0x2df0, 0x2df2, 
+    0x2df5, 0x2df7, 0x2dfa, 0x2dfc, 0x2dff, 0x2e01, 0x2e03, 0x2e06, 
+    0x2e08, 0x2e0b, 0x2e0d, 0x2e10, 0x2e12, 0x2e14, 0x2e17, 0x2e19, 
+    0x2e1c, 0x2e1e, 0x2e21, 0x2e23, 0x2e25, 0x2e28, 0x2e2a, 0x2e2d, 
+    0x2e2f, 0x2e32, 0x2e34, 0x2e37, 0x2e39, 0x2e3c, 0x2e3e, 0x2e41, 
+    0x2e43, 0x2e46, 0x2e48, 0x2e4b, 0x2e4d, 0x2e4f, 0x2e52, 0x2e54, 
+    0x2e57, 0x2e59, 0x2e5c, 0x2e5e, 0x2e61, 0x2e63, 0x2e66, 0x2e68, 
+    0x2e6b, 0x2e6d, 0x2e70, 0x2e72, 0x2e75, 0x2e78, 0x2e7a, 0x2e7d, 
+    0x2e7f, 0x2e82, 0x2e84, 0x2e87, 0x2e89, 0x2e8c, 0x2e8e, 0x2e91, 
+    0x2e93, 0x2e96, 0x2e98, 0x2e9b, 0x2e9e, 0x2ea0, 0x2ea3, 0x2ea5, 
+    0x2ea8, 0x2eaa, 0x2ead, 0x2eaf, 0x2eb2, 0x2eb5, 0x2eb7, 0x2eba, 
+    0x2ebc, 0x2ebf, 0x2ec2, 0x2ec4, 0x2ec7, 0x2ec9, 0x2ecc, 0x2ece, 
+    0x2ed1, 0x2ed4, 0x2ed6, 0x2ed9, 0x2edb, 0x2ede, 0x2ee1, 0x2ee3, 
+    0x2ee6, 0x2ee8, 0x2eeb, 0x2eee, 0x2ef0, 0x2ef3, 0x2ef6, 0x2ef8, 
+    0x2efb, 0x2efd, 0x2f00, 0x2f03, 0x2f05, 0x2f08, 0x2f0b, 0x2f0d, 
+    0x2f10, 0x2f13, 0x2f15, 0x2f18, 0x2f1a, 0x2f1d, 0x2f20, 0x2f22, 
+    0x2f25, 0x2f28, 0x2f2a, 0x2f2d, 0x2f30, 0x2f32, 0x2f35, 0x2f38, 
+    0x2f3a, 0x2f3d, 0x2f40, 0x2f43, 0x2f45, 0x2f48, 0x2f4b, 0x2f4d, 
+    0x2f50, 0x2f53, 0x2f55, 0x2f58, 0x2f5b, 0x2f5d, 0x2f60, 0x2f63, 
+    0x2f66, 0x2f68, 0x2f6b, 0x2f6e, 0x2f70, 0x2f73, 0x2f76, 0x2f79, 
+    0x2f7b, 0x2f7e, 0x2f81, 0x2f84, 0x2f86, 0x2f89, 0x2f8c, 0x2f8f, 
+    0x2f91, 0x2f94, 0x2f97, 0x2f9a, 0x2f9c, 0x2f9f, 0x2fa2, 0x2fa5, 
+    0x2fa7, 0x2faa, 0x2fad, 0x2fb0, 0x2fb2, 0x2fb5, 0x2fb8, 0x2fbb, 
+    0x2fbd, 0x2fc0, 0x2fc3, 0x2fc6, 0x2fc9, 0x2fcb, 0x2fce, 0x2fd1, 
+    0x2fd4, 0x2fd7, 0x2fd9, 0x2fdc, 0x2fdf, 0x2fe2, 0x2fe5, 0x2fe7, 
+    0x2fea, 0x2fed, 0x2ff0, 0x2ff3, 0x2ff6, 0x2ff8, 0x2ffb, 0x2ffe, 
+    0x3000, 0x3002, 0x3003, 0x3005, 0x3006, 0x3007, 0x3009, 0x300a, 
+    0x300c, 0x300d, 0x300f, 0x3010, 0x3011, 0x3013, 0x3014, 0x3016, 
+    0x3017, 0x3019, 0x301a, 0x301b, 0x301d, 0x301e, 0x3020, 0x3021, 
+    0x3023, 0x3024, 0x3026, 0x3027, 0x3028, 0x302a, 0x302b, 0x302d, 
+    0x302e, 0x3030, 0x3031, 0x3033, 0x3034, 0x3036, 0x3037, 0x3038, 
+    0x303a, 0x303b, 0x303d, 0x303e, 0x3040, 0x3041, 0x3043, 0x3044, 
+    0x3046, 0x3047, 0x3049, 0x304a, 0x304b, 0x304d, 0x304e, 0x3050, 
+    0x3051, 0x3053, 0x3054, 0x3056, 0x3057, 0x3059, 0x305a, 0x305c, 
+    0x305d, 0x305f, 0x3060, 0x3062, 0x3063, 0x3065, 0x3066, 0x3068, 
+    0x3069, 0x306b, 0x306c, 0x306e, 0x306f, 0x3071, 0x3072, 0x3074, 
+    0x3075, 0x3077, 0x3078, 0x307a, 0x307b, 0x307d, 0x307e, 0x3080, 
+    0x3081, 0x3083, 0x3084, 0x3086, 0x3087, 0x3089, 0x308a, 0x308c, 
+    0x308d, 0x308f, 0x3090, 0x3092, 0x3093, 0x3095, 0x3096, 0x3098, 
+    0x3099, 0x309b, 0x309c, 0x309e, 0x30a0, 0x30a1, 0x30a3, 0x30a4, 
+    0x30a6, 0x30a7, 0x30a9, 0x30aa, 0x30ac, 0x30ad, 0x30af, 0x30b0, 
+    0x30b2, 0x30b4, 0x30b5, 0x30b7, 0x30b8, 0x30ba, 0x30bb, 0x30bd, 
+    0x30be, 0x30c0, 0x30c2, 0x30c3, 0x30c5, 0x30c6, 0x30c8, 0x30c9, 
+    0x30cb, 0x30cc, 0x30ce, 0x30d0, 0x30d1, 0x30d3, 0x30d4, 0x30d6, 
+    0x30d7, 0x30d9, 0x30db, 0x30dc, 0x30de, 0x30df, 0x30e1, 0x30e2, 
+    0x30e4, 0x30e6, 0x30e7, 0x30e9, 0x30ea, 0x30ec, 0x30ed, 0x30ef, 
+    0x30f1, 0x30f2, 0x30f4, 0x30f5, 0x30f7, 0x30f9, 0x30fa, 0x30fc, 
+    0x30fd, 0x30ff, 0x3101, 0x3102, 0x3104, 0x3105, 0x3107, 0x3109, 
+    0x310a, 0x310c, 0x310d, 0x310f, 0x3111, 0x3112, 0x3114, 0x3115, 
+    0x3117, 0x3119, 0x311a, 0x311c, 0x311e, 0x311f, 0x3121, 0x3122, 
+    0x3124, 0x3126, 0x3127, 0x3129, 0x312b, 0x312c, 0x312e, 0x312f, 
+    0x3131, 0x3133, 0x3134, 0x3136, 0x3138, 0x3139, 0x313b, 0x313c, 
+    0x313e, 0x3140, 0x3141, 0x3143, 0x3145, 0x3146, 0x3148, 0x314a, 
+    0x314b, 0x314d, 0x314f, 0x3150, 0x3152, 0x3154, 0x3155, 0x3157, 
+    0x3159, 0x315a, 0x315c, 0x315e, 0x315f, 0x3161, 0x3162, 0x3164, 
+    0x3166, 0x3167, 0x3169, 0x316b, 0x316c, 0x316e, 0x3170, 0x3172, 
+    0x3173, 0x3175, 0x3177, 0x3178, 0x317a, 0x317c, 0x317d, 0x317f, 
+    0x3181, 0x3182, 0x3184, 0x3186, 0x3187, 0x3189, 0x318b, 0x318c, 
+    0x318e, 0x3190, 0x3192, 0x3193, 0x3195, 0x3197, 0x3198, 0x319a, 
+    0x319c, 0x319d, 0x319f, 0x31a1, 0x31a3, 0x31a4, 0x31a6, 0x31a8, 
+    0x31a9, 0x31ab, 0x31ad, 0x31af, 0x31b0, 0x31b2, 0x31b4, 0x31b5, 
+    0x31b7, 0x31b9, 0x31bb, 0x31bc, 0x31be, 0x31c0, 0x31c1, 0x31c3, 
+    0x31c5, 0x31c7, 0x31c8, 0x31ca, 0x31cc, 0x31ce, 0x31cf, 0x31d1, 
+    0x31d3, 0x31d4, 0x31d6, 0x31d8, 0x31da, 0x31db, 0x31dd, 0x31df, 
+    0x31e1, 0x31e2, 0x31e4, 0x31e6, 0x31e8, 0x31e9, 0x31eb, 0x31ed, 
+    0x31ef, 0x31f0, 0x31f2, 0x31f4, 0x31f6, 0x31f7, 0x31f9, 0x31fb, 
+    0x31fd, 0x31ff, 0x3200, 0x3202, 0x3204, 0x3206, 0x3207, 0x3209, 
+    0x320b, 0x320d, 0x320e, 0x3210, 0x3212, 0x3214, 0x3216, 0x3217, 
+    0x3219, 0x321b, 0x321d, 0x321e, 0x3220, 0x3222, 0x3224, 0x3226, 
+    0x3227, 0x3229, 0x322b, 0x322d, 0x322f, 0x3230, 0x3232, 0x3234, 
+    0x3236, 0x3238, 0x3239, 0x323b, 0x323d, 0x323f, 0x3241, 0x3242, 
+    0x3244, 0x3246, 0x3248, 0x324a, 0x324b, 0x324d, 0x324f, 0x3251, 
+    0x3253, 0x3254, 0x3256, 0x3258, 0x325a, 0x325c, 0x325e, 0x325f, 
+    0x3261, 0x3263, 0x3265, 0x3267, 0x3269, 0x326a, 0x326c, 0x326e, 
+    0x3270, 0x3272, 0x3274, 0x3275, 0x3277, 0x3279, 0x327b, 0x327d, 
+    0x327f, 0x3280, 0x3282, 0x3284, 0x3286, 0x3288, 0x328a, 0x328c, 
+    0x328d, 0x328f, 0x3291, 0x3293, 0x3295, 0x3297, 0x3299, 0x329a, 
+    0x329c, 0x329e, 0x32a0, 0x32a2, 0x32a4, 0x32a6, 0x32a7, 0x32a9, 
+    0x32ab, 0x32ad, 0x32af, 0x32b1, 0x32b3, 0x32b5, 0x32b6, 0x32b8, 
+    0x32ba, 0x32bc, 0x32be, 0x32c0, 0x32c2, 0x32c4, 0x32c5, 0x32c7, 
+    0x32c9, 0x32cb, 0x32cd, 0x32cf, 0x32d1, 0x32d3, 0x32d5, 0x32d6, 
+    0x32d8, 0x32da, 0x32dc, 0x32de, 0x32e0, 0x32e2, 0x32e4, 0x32e6, 
+    0x32e8, 0x32ea, 0x32eb, 0x32ed, 0x32ef, 0x32f1, 0x32f3, 0x32f5, 
+    0x32f7, 0x32fb, 0x32ff, 0x3302, 0x3306, 0x330a, 0x330e, 0x3312, 
+    0x3316, 0x331a, 0x331d, 0x3321, 0x3325, 0x3329, 0x332d, 0x3331, 
+    0x3335, 0x3339, 0x333d, 0x3340, 0x3344, 0x3348, 0x334c, 0x3350, 
+    0x3354, 0x3358, 0x335c, 0x3360, 0x3364, 0x3368, 0x336c, 0x3370, 
+    0x3374, 0x3378, 0x337c, 0x3380, 0x3384, 0x3388, 0x338c, 0x3390, 
+    0x3394, 0x3398, 0x339c, 0x33a0, 0x33a4, 0x33a8, 0x33ac, 0x33b0, 
+    0x33b4, 0x33b8, 0x33bc, 0x33c0, 0x33c4, 0x33c8, 0x33cc, 0x33d0, 
+    0x33d4, 0x33d9, 0x33dd, 0x33e1, 0x33e5, 0x33e9, 0x33ed, 0x33f1, 
+    0x33f5, 0x33f9, 0x33fe, 0x3401, 0x3403, 0x3405, 0x3407, 0x3409, 
+    0x340b, 0x340d, 0x340f, 0x3411, 0x3414, 0x3416, 0x3418, 0x341a, 
+    0x341c, 0x341e, 0x3420, 0x3422, 0x3424, 0x3426, 0x3428, 0x342b, 
+    0x342d, 0x342f, 0x3431, 0x3433, 0x3435, 0x3437, 0x3439, 0x343c, 
+    0x343e, 0x3440, 0x3442, 0x3444, 0x3446, 0x3448, 0x344b, 0x344d, 
+    0x344f, 0x3451, 0x3453, 0x3455, 0x3457, 0x345a, 0x345c, 0x345e, 
+    0x3460, 0x3462, 0x3464, 0x3467, 0x3469, 0x346b, 0x346d, 0x346f, 
+    0x3472, 0x3474, 0x3476, 0x3478, 0x347a, 0x347d, 0x347f, 0x3481, 
+    0x3483, 0x3485, 0x3488, 0x348a, 0x348c, 0x348e, 0x3490, 0x3493, 
+    0x3495, 0x3497, 0x3499, 0x349c, 0x349e, 0x34a0, 0x34a2, 0x34a4, 
+    0x34a7, 0x34a9, 0x34ab, 0x34ad, 0x34b0, 0x34b2, 0x34b4, 0x34b6, 
+    0x34b9, 0x34bb, 0x34bd, 0x34c0, 0x34c2, 0x34c4, 0x34c6, 0x34c9, 
+    0x34cb, 0x34cd, 0x34cf, 0x34d2, 0x34d4, 0x34d6, 0x34d9, 0x34db, 
+    0x34dd, 0x34e0, 0x34e2, 0x34e4, 0x34e6, 0x34e9, 0x34eb, 0x34ed, 
+    0x34f0, 0x34f2, 0x34f4, 0x34f7, 0x34f9, 0x34fb, 0x34fe, 0x3500, 
+    0x3502, 0x3505, 0x3507, 0x3509, 0x350c, 0x350e, 0x3510, 0x3513, 
+    0x3515, 0x3517, 0x351a, 0x351c, 0x351e, 0x3521, 0x3523, 0x3526, 
+    0x3528, 0x352a, 0x352d, 0x352f, 0x3531, 0x3534, 0x3536, 0x3539, 
+    0x353b, 0x353d, 0x3540, 0x3542, 0x3545, 0x3547, 0x3549, 0x354c, 
+    0x354e, 0x3551, 0x3553, 0x3555, 0x3558, 0x355a, 0x355d, 0x355f, 
+    0x3562, 0x3564, 0x3566, 0x3569, 0x356b, 0x356e, 0x3570, 0x3573, 
+    0x3575, 0x3577, 0x357a, 0x357c, 0x357f, 0x3581, 0x3584, 0x3586, 
+    0x3589, 0x358b, 0x358e, 0x3590, 0x3593, 0x3595, 0x3598, 0x359a, 
+    0x359d, 0x359f, 0x35a1, 0x35a4, 0x35a6, 0x35a9, 0x35ab, 0x35ae, 
+    0x35b0, 0x35b3, 0x35b5, 0x35b8, 0x35ba, 0x35bd, 0x35c0, 0x35c2, 
+    0x35c5, 0x35c7, 0x35ca, 0x35cc, 0x35cf, 0x35d1, 0x35d4, 0x35d6, 
+    0x35d9, 0x35db, 0x35de, 0x35e0, 0x35e3, 0x35e6, 0x35e8, 0x35eb, 
+    0x35ed, 0x35f0, 0x35f2, 0x35f5, 0x35f7, 0x35fa, 0x35fd, 0x35ff, 
+    0x3602, 0x3604, 0x3607, 0x360a, 0x360c, 0x360f, 0x3611, 0x3614, 
+    0x3616, 0x3619, 0x361c, 0x361e, 0x3621, 0x3623, 0x3626, 0x3629, 
+    0x362b, 0x362e, 0x3631, 0x3633, 0x3636, 0x3638, 0x363b, 0x363e, 
+    0x3640, 0x3643, 0x3646, 0x3648, 0x364b, 0x364e, 0x3650, 0x3653, 
+    0x3655, 0x3658, 0x365b, 0x365d, 0x3660, 0x3663, 0x3665, 0x3668, 
+    0x366b, 0x366d, 0x3670, 0x3673, 0x3676, 0x3678, 0x367b, 0x367e, 
+    0x3680, 0x3683, 0x3686, 0x3688, 0x368b, 0x368e, 0x3690, 0x3693, 
+    0x3696, 0x3699, 0x369b, 0x369e, 0x36a1, 0x36a3, 0x36a6, 0x36a9, 
+    0x36ac, 0x36ae, 0x36b1, 0x36b4, 0x36b7, 0x36b9, 0x36bc, 0x36bf, 
+    0x36c2, 0x36c4, 0x36c7, 0x36ca, 0x36cd, 0x36cf, 0x36d2, 0x36d5, 
+    0x36d8, 0x36da, 0x36dd, 0x36e0, 0x36e3, 0x36e5, 0x36e8, 0x36eb, 
+    0x36ee, 0x36f1, 0x36f3, 0x36f6, 0x36f9, 0x36fc, 0x36ff, 0x3701, 
+    0x3704, 0x3707, 0x370a, 0x370d, 0x370f, 0x3712, 0x3715, 0x3718, 
+    0x371b, 0x371e, 0x3720, 0x3723, 0x3726, 0x3729, 0x372c, 0x372f, 
+    0x3731, 0x3734, 0x3737, 0x373a, 0x373d, 0x3740, 0x3743, 0x3745, 
+    0x3748, 0x374b, 0x374e, 0x3751, 0x3754, 0x3757, 0x3759, 0x375c, 
+    0x375f, 0x3762, 0x3765, 0x3768, 0x376b, 0x376e, 0x3771, 0x3774, 
+    0x3776, 0x3779, 0x377c, 0x377f, 0x3782, 0x3785, 0x3788, 0x378b, 
+    0x378e, 0x3791, 0x3794, 0x3796, 0x3799, 0x379c, 0x379f, 0x37a2, 
+    0x37a5, 0x37a8, 0x37ab, 0x37ae, 0x37b1, 0x37b4, 0x37b7, 0x37ba, 
+    0x37bd, 0x37c0, 0x37c3, 0x37c6, 0x37c9, 0x37cc, 0x37cf, 0x37d2, 
+    0x37d5, 0x37d7, 0x37da, 0x37dd, 0x37e0, 0x37e3, 0x37e6, 0x37e9, 
+    0x37ec, 0x37ef, 0x37f2, 0x37f5, 0x37f8, 0x37fb, 0x37fe, 0x3801, 
+    0x3802, 0x3804, 0x3805, 0x3807, 0x3808, 0x380a, 0x380b, 0x380d, 
+    0x380e, 0x3810, 0x3811, 0x3813, 0x3814, 0x3816, 0x3817, 0x3819, 
+    0x381b, 0x381c, 0x381e, 0x381f, 0x3821, 0x3822, 0x3824, 0x3825, 
+    0x3827, 0x3828, 0x382a, 0x382b, 0x382d, 0x382f, 0x3830, 0x3832, 
+    0x3833, 0x3835, 0x3836, 0x3838, 0x3839, 0x383b, 0x383c, 0x383e, 
+    0x3840, 0x3841, 0x3843, 0x3844, 0x3846, 0x3847, 0x3849, 0x384b, 
+    0x384c, 0x384e, 0x384f, 0x3851, 0x3852, 0x3854, 0x3856, 0x3857, 
+    0x3859, 0x385a, 0x385c, 0x385d, 0x385f, 0x3861, 0x3862, 0x3864, 
+    0x3865, 0x3867, 0x3869, 0x386a, 0x386c, 0x386d, 0x386f, 0x3870, 
+    0x3872, 0x3874, 0x3875, 0x3877, 0x3878, 0x387a, 0x387c, 0x387d, 
+    0x387f, 0x3880, 0x3882, 0x3884, 0x3885, 0x3887, 0x3889, 0x388a, 
+    0x388c, 0x388d, 0x388f, 0x3891, 0x3892, 0x3894, 0x3895, 0x3897, 
+    0x3899, 0x389a, 0x389c, 0x389e, 0x389f, 0x38a1, 0x38a3, 0x38a4, 
+    0x38a6, 0x38a7, 0x38a9, 0x38ab, 0x38ac, 0x38ae, 0x38b0, 0x38b1, 
+    0x38b3, 0x38b5, 0x38b6, 0x38b8, 0x38ba, 0x38bb, 0x38bd, 0x38be, 
+    0x38c0, 0x38c2, 0x38c3, 0x38c5, 0x38c7, 0x38c8, 0x38ca, 0x38cc, 
+    0x38cd, 0x38cf, 0x38d1, 0x38d2, 0x38d4, 0x38d6, 0x38d7, 0x38d9, 
+    0x38db, 0x38dc, 0x38de, 0x38e0, 0x38e1, 0x38e3, 0x38e5, 0x38e7, 
+    0x38e8, 0x38ea, 0x38ec, 0x38ed, 0x38ef, 0x38f1, 0x38f2, 0x38f4, 
+    0x38f6, 0x38f7, 0x38f9, 0x38fb, 0x38fd, 0x38fe, 0x3900, 0x3902, 
+    0x3903, 0x3905, 0x3907, 0x3908, 0x390a, 0x390c, 0x390e, 0x390f, 
+    0x3911, 0x3913, 0x3914, 0x3916, 0x3918, 0x391a, 0x391b, 0x391d, 
+    0x391f, 0x3920, 0x3922, 0x3924, 0x3926, 0x3927, 0x3929, 0x392b, 
+    0x392d, 0x392e, 0x3930, 0x3932, 0x3934, 0x3935, 0x3937, 0x3939, 
+    0x393b, 0x393c, 0x393e, 0x3940, 0x3942, 0x3943, 0x3945, 0x3947, 
+    0x3949, 0x394a, 0x394c, 0x394e, 0x3950, 0x3951, 0x3953, 0x3955, 
+    0x3957, 0x3958, 0x395a, 0x395c, 0x395e, 0x395f, 0x3961, 0x3963, 
+    0x3965, 0x3967, 0x3968, 0x396a, 0x396c, 0x396e, 0x396f, 0x3971, 
+    0x3973, 0x3975, 0x3977, 0x3978, 0x397a, 0x397c, 0x397e, 0x397f, 
+    0x3981, 0x3983, 0x3985, 0x3987, 0x3988, 0x398a, 0x398c, 0x398e, 
+    0x3990, 0x3991, 0x3993, 0x3995, 0x3997, 0x3999, 0x399b, 0x399c, 
+    0x399e, 0x39a0, 0x39a2, 0x39a4, 0x39a5, 0x39a7, 0x39a9, 0x39ab, 
+    0x39ad, 0x39af, 0x39b0, 0x39b2, 0x39b4, 0x39b6, 0x39b8, 0x39ba, 
+    0x39bb, 0x39bd, 0x39bf, 0x39c1, 0x39c3, 0x39c5, 0x39c6, 0x39c8, 
+    0x39ca, 0x39cc, 0x39ce, 0x39d0, 0x39d1, 0x39d3, 0x39d5, 0x39d7, 
+    0x39d9, 0x39db, 0x39dd, 0x39de, 0x39e0, 0x39e2, 0x39e4, 0x39e6, 
+    0x39e8, 0x39ea, 0x39eb, 0x39ed, 0x39ef, 0x39f1, 0x39f3, 0x39f5, 
+    0x39f7, 0x39f9, 0x39fa, 0x39fc, 0x39fe, 0x3a00, 0x3a02, 0x3a04, 
+    0x3a06, 0x3a08, 0x3a09, 0x3a0b, 0x3a0d, 0x3a0f, 0x3a11, 0x3a13, 
+    0x3a15, 0x3a17, 0x3a19, 0x3a1b, 0x3a1c, 0x3a1e, 0x3a20, 0x3a22, 
+    0x3a24, 0x3a26, 0x3a28, 0x3a2a, 0x3a2c, 0x3a2e, 0x3a2f, 0x3a31, 
+    0x3a33, 0x3a35, 0x3a37, 0x3a39, 0x3a3b, 0x3a3d, 0x3a3f, 0x3a41, 
+    0x3a43, 0x3a45, 0x3a47, 0x3a48, 0x3a4a, 0x3a4c, 0x3a4e, 0x3a50, 
+    0x3a52, 0x3a54, 0x3a56, 0x3a58, 0x3a5a, 0x3a5c, 0x3a5e, 0x3a60, 
+    0x3a62, 0x3a64, 0x3a66, 0x3a67, 0x3a69, 0x3a6b, 0x3a6d, 0x3a6f, 
+    0x3a71, 0x3a73, 0x3a75, 0x3a77, 0x3a79, 0x3a7b, 0x3a7d, 0x3a7f, 
+    0x3a81, 0x3a83, 0x3a85, 0x3a87, 0x3a89, 0x3a8b, 0x3a8d, 0x3a8f, 
+    0x3a91, 0x3a93, 0x3a95, 0x3a97, 0x3a99, 0x3a9b, 0x3a9d, 0x3a9f, 
+    0x3aa0, 0x3aa2, 0x3aa4, 0x3aa6, 0x3aa8, 0x3aaa, 0x3aac, 0x3aae, 
+    0x3ab0, 0x3ab2, 0x3ab4, 0x3ab6, 0x3ab8, 0x3aba, 0x3abc, 0x3abe, 
+    0x3ac0, 0x3ac2, 0x3ac4, 0x3ac6, 0x3ac8, 0x3aca, 0x3acc, 0x3ace, 
+    0x3ad1, 0x3ad3, 0x3ad5, 0x3ad7, 0x3ad9, 0x3adb, 0x3add, 0x3adf, 
+    0x3ae1, 0x3ae3, 0x3ae5, 0x3ae7, 0x3ae9, 0x3aeb, 0x3aed, 0x3aef, 
+    0x3af1, 0x3af3, 0x3af5, 0x3af7, 0x3af9, 0x3afb, 0x3afd, 0x3aff, 
+    0x3b01, 0x3b03, 0x3b05, 0x3b07, 0x3b09, 0x3b0b, 0x3b0e, 0x3b10, 
+    0x3b12, 0x3b14, 0x3b16, 0x3b18, 0x3b1a, 0x3b1c, 0x3b1e, 0x3b20, 
+    0x3b22, 0x3b24, 0x3b26, 0x3b28, 0x3b2a, 0x3b2c, 0x3b2f, 0x3b31, 
+    0x3b33, 0x3b35, 0x3b37, 0x3b39, 0x3b3b, 0x3b3d, 0x3b3f, 0x3b41, 
+    0x3b43, 0x3b45, 0x3b48, 0x3b4a, 0x3b4c, 0x3b4e, 0x3b50, 0x3b52, 
+    0x3b54, 0x3b56, 0x3b58, 0x3b5a, 0x3b5d, 0x3b5f, 0x3b61, 0x3b63, 
+    0x3b65, 0x3b67, 0x3b69, 0x3b6b, 0x3b6d, 0x3b6f, 0x3b72, 0x3b74, 
+    0x3b76, 0x3b78, 0x3b7a, 0x3b7c, 0x3b7e, 0x3b80, 0x3b83, 0x3b85, 
+    0x3b87, 0x3b89, 0x3b8b, 0x3b8d, 0x3b8f, 0x3b91, 0x3b94, 0x3b96, 
+    0x3b98, 0x3b9a, 0x3b9c, 0x3b9e, 0x3ba0, 0x3ba3, 0x3ba5, 0x3ba7, 
+    0x3ba9, 0x3bab, 0x3bad, 0x3baf, 0x3bb2, 0x3bb4, 0x3bb6, 0x3bb8, 
+    0x3bba, 0x3bbc, 0x3bbf, 0x3bc1, 0x3bc3, 0x3bc5, 0x3bc7, 0x3bc9, 
+    0x3bcc, 0x3bce, 0x3bd0, 0x3bd2, 0x3bd4, 0x3bd6, 0x3bd9, 0x3bdb, 
+    0x3bdd, 0x3bdf, 0x3be1, 0x3be4, 0x3be6, 0x3be8, 0x3bea, 0x3bec, 
+    0x3bee, 0x3bf1, 0x3bf3, 0x3bf5, 0x3bf7, 0x3bf9, 0x3bfc, 0x3bfe, 
+    0x3c00, 0x3c02, 0x3c04, 0x3c07, 0x3c09, 0x3c0b, 0x3c0d, 0x3c10, 
+    0x3c12, 0x3c14, 0x3c16, 0x3c18, 0x3c1b, 0x3c1d, 0x3c1f, 0x3c22, 
+    0x3c24, 0x3c26, 0x3c28, 0x3c2b, 0x3c2d, 0x3c2f, 0x3c32, 0x3c34, 
+    0x3c36, 0x3c39, 0x3c3b, 0x3c3d, 0x3c3f, 0x3c42, 0x3c44, 0x3c47, 
+    0x3c49, 0x3c4b, 0x3c4e, 0x3c50, 0x3c52, 0x3c55, 0x3c57, 0x3c59, 
+    0x3c5c, 0x3c5e, 0x3c61, 0x3c63, 0x3c66, 0x3c68, 0x3c6a, 0x3c6d, 
+    0x3c6f, 0x3c72, 0x3c74, 0x3c77, 0x3c79, 0x3c7b, 0x3c7e, 0x3c80, 
+    0x3c83, 0x3c85, 0x3c88, 0x3c8a, 0x3c8d, 0x3c8f, 0x3c92, 0x3c94, 
+    0x3c97, 0x3c99, 0x3c9c, 0x3c9f, 0x3ca1, 0x3ca4, 0x3ca6, 0x3ca9, 
+    0x3cab, 0x3cae, 0x3cb0, 0x3cb3, 0x3cb6, 0x3cb8, 0x3cbb, 0x3cbd, 
+    0x3cc0, 0x3cc3, 0x3cc5, 0x3cc8, 0x3ccb, 0x3ccd, 0x3cd0, 0x3cd2, 
+    0x3cd5, 0x3cd8, 0x3cda, 0x3cdd, 0x3ce0, 0x3ce2, 0x3ce5, 0x3ce8, 
+    0x3ceb, 0x3ced, 0x3cf0, 0x3cf3, 0x3cf5, 0x3cf8, 0x3cfb, 0x3cfe, 
+    0x3d00, 0x3d03, 0x3d06, 0x3d09, 0x3d0b, 0x3d0e, 0x3d11, 0x3d14, 
+    0x3d17, 0x3d19, 0x3d1c, 0x3d1f, 0x3d22, 0x3d25, 0x3d27, 0x3d2a, 
+    0x3d2d, 0x3d30, 0x3d33, 0x3d36, 0x3d39, 0x3d3b, 0x3d3e, 0x3d41, 
+    0x3d44, 0x3d47, 0x3d4a, 0x3d4d, 0x3d50, 0x3d53, 0x3d56, 0x3d59, 
+    0x3d5b, 0x3d5e, 0x3d61, 0x3d64, 0x3d67, 0x3d6a, 0x3d6d, 0x3d70, 
+    0x3d73, 0x3d76, 0x3d79, 0x3d7c, 0x3d7f, 0x3d82, 0x3d85, 0x3d88, 
+    0x3d8b, 0x3d8f, 0x3d92, 0x3d95, 0x3d98, 0x3d9b, 0x3d9e, 0x3da1, 
+    0x3da4, 0x3da7, 0x3daa, 0x3dad, 0x3db1, 0x3db4, 0x3db7, 0x3dba, 
+    0x3dbd, 0x3dc0, 0x3dc3, 0x3dc7, 0x3dca, 0x3dcd, 0x3dd0, 0x3dd3, 
+    0x3dd7, 0x3dda, 0x3ddd, 0x3de0, 0x3de3, 0x3de7, 0x3dea, 0x3ded, 
+    0x3df0, 0x3df4, 0x3df7, 0x3dfa, 0x3dfe, 0x3e01, 0x3e04, 0x3e08, 
+    0x3e0b, 0x3e0e, 0x3e12, 0x3e15, 0x3e18, 0x3e1c, 0x3e1f, 0x3e22, 
+    0x3e26, 0x3e29, 0x3e2c, 0x3e30, 0x3e33, 0x3e37, 0x3e3a, 0x3e3e, 
+    0x3e41, 0x3e44, 0x3e48, 0x3e4b, 0x3e4f, 0x3e52, 0x3e56, 0x3e59, 
+    0x3e5d, 0x3e60, 0x3e64, 0x3e67, 0x3e6b, 0x3e6e, 0x3e72, 0x3e75, 
+    0x3e79, 0x3e7c, 0x3e80, 0x3e84, 0x3e87, 0x3e8b, 0x3e8e, 0x3e92, 
+    0x3e96, 0x3e99, 0x3e9d, 0x3ea1, 0x3ea4, 0x3ea8, 0x3eac, 0x3eaf, 
+    0x3eb3, 0x3eb7, 0x3eba, 0x3ebe, 0x3ec2, 0x3ec5, 0x3ec9, 0x3ecd, 
+    0x3ed1, 0x3ed4, 0x3ed8, 0x3edc, 0x3ee0, 0x3ee3, 0x3ee7, 0x3eeb, 
+    0x3eef, 0x3ef3, 0x3ef6, 0x3efa, 0x3efe, 0x3f02, 0x3f06, 0x3f0a, 
+    0x3f0e, 0x3f12, 0x3f15, 0x3f19, 0x3f1d, 0x3f21, 0x3f25, 0x3f29, 
+    0x3f2d, 0x3f31, 0x3f35, 0x3f39, 0x3f3d, 0x3f41, 0x3f45, 0x3f49, 
+    0x3f4d, 0x3f51, 0x3f55, 0x3f59, 0x3f5d, 0x3f61, 0x3f65, 0x3f69, 
+    0x3f6d, 0x3f71, 0x3f75, 0x3f79, 0x3f7e, 0x3f82, 0x3f86, 0x3f8a, 
+    0x3f8e, 0x3f92, 0x3f96, 0x3f9b, 0x3f9f, 0x3fa3, 0x3fa7, 0x3fab, 
+    0x3fb0, 0x3fb4, 0x3fb8, 0x3fbc, 0x3fc1, 0x3fc5, 0x3fc9, 0x3fcd, 
+    0x3fd2, 0x3fd6, 0x3fda, 0x3fdf, 0x3fe3, 0x3fe7, 0x3fec, 0x3ff0, 
+    0x3ff4, 0x3ff9, 0x3ffd, 0x4001, 0x4003, 0x4005, 0x4007, 0x400a, 
+    0x400c, 0x400e, 0x4010, 0x4013, 0x4015, 0x4017, 0x4019, 0x401c, 
+    0x401e, 0x4020, 0x4022, 0x4025, 0x4027, 0x4029, 0x402c, 0x402e, 
+    0x4030, 0x4032, 0x4035, 0x4037, 0x4039, 0x403c, 0x403e, 0x4040, 
+    0x4043, 0x4045, 0x4047, 0x404a, 0x404c, 0x404e, 0x4051, 0x4053, 
+    0x4056, 0x4058, 0x405a, 0x405d, 0x405f, 0x4062, 0x4064, 0x4066, 
+    0x4069, 0x406b, 0x406e, 0x4070, 0x4073, 0x4075, 0x4077, 0x407a, 
+    0x407c, 0x407f, 0x4081, 0x4084, 0x4086, 0x4089, 0x408b, 0x408e, 
+    0x4090, 0x4093, 0x4095, 0x4098, 0x409a, 0x409d, 0x409f, 0x40a2, 
+    0x40a5, 0x40a7, 0x40aa, 0x40ac, 0x40af, 0x40b1, 0x40b4, 0x40b7, 
+    0x40b9, 0x40bc, 0x40be, 0x40c1, 0x40c4, 0x40c6, 0x40c9, 0x40cc, 
+    0x40ce, 0x40d1, 0x40d3, 0x40d6, 0x40d9, 0x40db, 0x40de, 0x40e1, 
+    0x40e3, 0x40e6, 0x40e9, 0x40ec, 0x40ee, 0x40f1, 0x40f4, 0x40f6, 
+    0x40f9, 0x40fc, 0x40ff, 0x4101, 0x4104, 0x4107, 0x410a, 0x410c, 
+    0x410f, 0x4112, 0x4115, 0x4118, 0x411a, 0x411d, 0x4120, 0x4123, 
+    0x4126, 0x4129, 0x412b, 0x412e, 0x4131, 0x4134, 0x4137, 0x413a, 
+    0x413d, 0x413f, 0x4142, 0x4145, 0x4148, 0x414b, 0x414e, 0x4151, 
+    0x4154, 0x4157, 0x415a, 0x415d, 0x4160, 0x4163, 0x4165, 0x4168, 
+    0x416b, 0x416e, 0x4171, 0x4174, 0x4177, 0x417a, 0x417d, 0x4180, 
+    0x4183, 0x4187, 0x418a, 0x418d, 0x4190, 0x4193, 0x4196, 0x4199, 
+    0x419c, 0x419f, 0x41a2, 0x41a5, 0x41a8, 0x41ab, 0x41af, 0x41b2, 
+    0x41b5, 0x41b8, 0x41bb, 0x41be, 0x41c1, 0x41c5, 0x41c8, 0x41cb, 
+    0x41ce, 0x41d1, 0x41d5, 0x41d8, 0x41db, 0x41de, 0x41e1, 0x41e5, 
+    0x41e8, 0x41eb, 0x41ee, 0x41f2, 0x41f5, 0x41f8, 0x41fc, 0x41ff, 
+    0x4202, 0x4205, 0x4209, 0x420c, 0x420f, 0x4213, 0x4216, 0x4219, 
+    0x421d, 0x4220, 0x4224, 0x4227, 0x422a, 0x422e, 0x4231, 0x4235, 
+    0x4238, 0x423b, 0x423f, 0x4242, 0x4246, 0x4249, 0x424d, 0x4250, 
+    0x4254, 0x4257, 0x425a, 0x425e, 0x4262, 0x4265, 0x4269, 0x426c, 
+    0x4270, 0x4273, 0x4277, 0x427a, 0x427e, 0x4281, 0x4285, 0x4289, 
+    0x428c, 0x4290, 0x4293, 0x4297, 0x429b, 0x429e, 0x42a2, 0x42a6, 
+    0x42a9, 0x42ad, 0x42b1, 0x42b4, 0x42b8, 0x42bc, 0x42bf, 0x42c3, 
+    0x42c7, 0x42cb, 0x42ce, 0x42d2, 0x42d6, 0x42da, 0x42dd, 0x42e1, 
+    0x42e5, 0x42e9, 0x42ec, 0x42f0, 0x42f4, 0x42f8, 0x42fc, 0x4300, 
+    0x4303, 0x4307, 0x430b, 0x430f, 0x4313, 0x4317, 0x431b, 0x431f, 
+    0x4323, 0x4327, 0x432a, 0x432e, 0x4332, 0x4336, 0x433a, 0x433e, 
+    0x4342, 0x4346, 0x434a, 0x434e, 0x4352, 0x4356, 0x435a, 0x435e, 
+    0x4362, 0x4367, 0x436b, 0x436f, 0x4373, 0x4377, 0x437b, 0x437f, 
+    0x4383, 0x4387, 0x438c, 0x4390, 0x4394, 0x4398, 0x439c, 0x43a0, 
+    0x43a5, 0x43a9, 0x43ad, 0x43b1, 0x43b5, 0x43ba, 0x43be, 0x43c2, 
+    0x43c6, 0x43cb, 0x43cf, 0x43d3, 0x43d8, 0x43dc, 0x43e0, 0x43e5, 
+    0x43e9, 0x43ed, 0x43f2, 0x43f6, 0x43fa, 0x43ff, 0x4402, 0x4404, 
+    0x4406, 0x4408, 0x440a, 0x440d, 0x440f, 0x4411, 0x4413, 0x4416, 
+    0x4418, 0x441a, 0x441c, 0x441f, 0x4421, 0x4423, 0x4426, 0x4428, 
+    0x442a, 0x442c, 0x442f, 0x4431, 0x4433, 0x4436, 0x4438, 0x443a, 
+    0x443d, 0x443f, 0x4441, 0x4444, 0x4446, 0x4448, 0x444b, 0x444d, 
+    0x444f, 0x4452, 0x4454, 0x4456, 0x4459, 0x445b, 0x445e, 0x4460, 
+    0x4462, 0x4465, 0x4467, 0x446a, 0x446c, 0x446f, 0x4471, 0x4473, 
+    0x4476, 0x4478, 0x447b, 0x447d, 0x4480, 0x4482, 0x4485, 0x4487, 
+    0x448a, 0x448c, 0x448f, 0x4491, 0x4494, 0x4496, 0x4499, 0x449b, 
+    0x449e, 0x44a0, 0x44a3, 0x44a6, 0x44a8, 0x44ab, 0x44ad, 0x44b0, 
+    0x44b2, 0x44b5, 0x44b8, 0x44ba, 0x44bd, 0x44bf, 0x44c2, 0x44c5, 
+    0x44c7, 0x44ca, 0x44cc, 0x44cf, 0x44d2, 0x44d4, 0x44d7, 0x44da, 
+    0x44dc, 0x44df, 0x44e2, 0x44e4, 0x44e7, 0x44ea, 0x44ed, 0x44ef, 
+    0x44f2, 0x44f5, 0x44f7, 0x44fa, 0x44fd, 0x4500, 0x4502, 0x4505, 
+    0x4508, 0x450b, 0x450d, 0x4510, 0x4513, 0x4516, 0x4519, 0x451b, 
+    0x451e, 0x4521, 0x4524, 0x4527, 0x452a, 0x452c, 0x452f, 0x4532, 
+    0x4535, 0x4538, 0x453b, 0x453e, 0x4540, 0x4543, 0x4546, 0x4549, 
+    0x454c, 0x454f, 0x4552, 0x4555, 0x4558, 0x455b, 0x455e, 0x4561, 
+    0x4564, 0x4567, 0x456a, 0x456d, 0x4570, 0x4573, 0x4576, 0x4579, 
+    0x457c, 0x457f, 0x4582, 0x4585, 0x4588, 0x458b, 0x458e, 0x4591, 
+    0x4594, 0x4597, 0x459a, 0x459d, 0x45a0, 0x45a3, 0x45a6, 0x45a9, 
+    0x45ad, 0x45b0, 0x45b3, 0x45b6, 0x45b9, 0x45bc, 0x45bf, 0x45c3, 
+    0x45c6, 0x45c9, 0x45cc, 0x45cf, 0x45d3, 0x45d6, 0x45d9, 0x45dc, 
+    0x45df, 0x45e3, 0x45e6, 0x45e9, 0x45ec, 0x45f0, 0x45f3, 0x45f6, 
+    0x45f9, 0x45fd, 0x4600, 0x4603, 0x4607, 0x460a, 0x460d, 0x4611, 
+    0x4614, 0x4617, 0x461b, 0x461e, 0x4621, 0x4625, 0x4628, 0x462c, 
+    0x462f, 0x4632, 0x4636, 0x4639, 0x463d, 0x4640, 0x4643, 0x4647, 
+    0x464a, 0x464e, 0x4651, 0x4655, 0x4658, 0x465c, 0x465f, 0x4663, 
+    0x4666, 0x466a, 0x466d, 0x4671, 0x4674, 0x4678, 0x467c, 0x467f, 
+    0x4683, 0x4686, 0x468a, 0x468e, 0x4691, 0x4695, 0x4698, 0x469c, 
+    0x46a0, 0x46a3, 0x46a7, 0x46ab, 0x46ae, 0x46b2, 0x46b6, 0x46b9, 
+    0x46bd, 0x46c1, 0x46c4, 0x46c8, 0x46cc, 0x46d0, 0x46d3, 0x46d7, 
+    0x46db, 0x46df, 0x46e2, 0x46e6, 0x46ea, 0x46ee, 0x46f2, 0x46f6, 
+    0x46f9, 0x46fd, 0x4701, 0x4705, 0x4709, 0x470d, 0x4711, 0x4714, 
+    0x4718, 0x471c, 0x4720, 0x4724, 0x4728, 0x472c, 0x4730, 0x4734, 
+    0x4738, 0x473c, 0x4740, 0x4744, 0x4748, 0x474c, 0x4750, 0x4754, 
+    0x4758, 0x475c, 0x4760, 0x4764, 0x4768, 0x476c, 0x4770, 0x4774, 
+    0x4778, 0x477d, 0x4781, 0x4785, 0x4789, 0x478d, 0x4791, 0x4795, 
+    0x479a, 0x479e, 0x47a2, 0x47a6, 0x47aa, 0x47af, 0x47b3, 0x47b7, 
+    0x47bb, 0x47c0, 0x47c4, 0x47c8, 0x47cc, 0x47d1, 0x47d5, 0x47d9, 
+    0x47de, 0x47e2, 0x47e6, 0x47eb, 0x47ef, 0x47f3, 0x47f8, 0x47fc, 
+    0x4800, 0x4802, 0x4805, 0x4807, 0x4809, 0x480b, 0x480e, 0x4810, 
+    0x4812, 0x4814, 0x4816, 0x4819, 0x481b, 0x481d, 0x4820, 0x4822, 
+    0x4824, 0x4826, 0x4829, 0x482b, 0x482d, 0x4830, 0x4832, 0x4834, 
+    0x4836, 0x4839, 0x483b, 0x483d, 0x4840, 0x4842, 0x4844, 0x4847, 
+    0x4849, 0x484c, 0x484e, 0x4850, 0x4853, 0x4855, 0x4857, 0x485a, 
+    0x485c, 0x485f, 0x4861, 0x4863, 0x4866, 0x4868, 0x486b, 0x486d, 
+    0x4870, 0x4872, 0x4874, 0x4877, 0x4879, 0x487c, 0x487e, 0x4881, 
+    0x4883, 0x4888, 0x488d, 0x4892, 0x4897, 0x489c, 0x48a1, 0x48a6, 
+    0x48ac, 0x48b1, 0x48b6, 0x48bb, 0x48c0, 0x48c6, 0x48cb, 0x48d0, 
+    0x48d5, 0x48db, 0x48e0, 0x48e5, 0x48eb, 0x48f0, 0x48f6, 0x48fb, 
+    0x4901, 0x4906, 0x490c, 0x4911, 0x4917, 0x491d, 0x4922, 0x4928, 
+    0x492d, 0x4933, 0x4939, 0x493f, 0x4944, 0x494a, 0x4950, 0x4956, 
+    0x495c, 0x4962, 0x4968, 0x496e, 0x4974, 0x497a, 0x4980, 0x4986, 
+    0x498c, 0x4992, 0x4998, 0x499e, 0x49a4, 0x49ab, 0x49b1, 0x49b7, 
+    0x49bd, 0x49c4, 0x49ca, 0x49d1, 0x49d7, 0x49dd, 0x49e4, 0x49ea, 
+    0x49f1, 0x49f7, 0x49fe, 0x4a05, 0x4a0b, 0x4a12, 0x4a19, 0x4a1f, 
+    0x4a26, 0x4a2d, 0x4a34, 0x4a3a, 0x4a41, 0x4a48, 0x4a4f, 0x4a56, 
+    0x4a5d, 0x4a64, 0x4a6b, 0x4a72, 0x4a79, 0x4a80, 0x4a88, 0x4a8f, 
+    0x4a96, 0x4a9d, 0x4aa5, 0x4aac, 0x4ab3, 0x4abb, 0x4ac2, 0x4aca, 
+    0x4ad1, 0x4ad9, 0x4ae0, 0x4ae8, 0x4aef, 0x4af7, 0x4aff, 0x4b06, 
+    0x4b0e, 0x4b16, 0x4b1e, 0x4b25, 0x4b2d, 0x4b35, 0x4b3d, 0x4b45, 
+    0x4b4d, 0x4b55, 0x4b5d, 0x4b65, 0x4b6e, 0x4b76, 0x4b7e, 0x4b86, 
+    0x4b8f, 0x4b97, 0x4b9f, 0x4ba8, 0x4bb0, 0x4bb9, 0x4bc1, 0x4bca, 
+    0x4bd2, 0x4bdb, 0x4be4, 0x4bec, 0x4bf5, 0x4bfe, 0x4c03, 0x4c08, 
+    0x4c0c, 0x4c11, 0x4c15, 0x4c1a, 0x4c1e, 0x4c23, 0x4c27, 0x4c2c, 
+    0x4c30, 0x4c35, 0x4c3a, 0x4c3e, 0x4c43, 0x4c48, 0x4c4c, 0x4c51, 
+    0x4c56, 0x4c5b, 0x4c5f, 0x4c64, 0x4c69, 0x4c6e, 0x4c73, 0x4c78, 
+    0x4c7d, 0x4c82, 0x4c87, 0x4c8c, 0x4c91, 0x4c96, 0x4c9b, 0x4ca0, 
+    0x4ca5, 0x4caa, 0x4caf, 0x4cb4, 0x4cb9, 0x4cbf, 0x4cc4, 0x4cc9, 
+    0x4cce, 0x4cd4, 0x4cd9, 0x4cde, 0x4ce4, 0x4ce9, 0x4cef, 0x4cf4, 
+    0x4cf9, 0x4cff, 0x4d04, 0x4d0a, 0x4d10, 0x4d15, 0x4d1b, 0x4d20, 
+    0x4d26, 0x4d2c, 0x4d31, 0x4d37, 0x4d3d, 0x4d43, 0x4d48, 0x4d4e, 
+    0x4d54, 0x4d5a, 0x4d60, 0x4d66, 0x4d6c, 0x4d72, 0x4d78, 0x4d7e, 
+    0x4d84, 0x4d8a, 0x4d90, 0x4d96, 0x4d9c, 0x4da2, 0x4da9, 0x4daf, 
+    0x4db5, 0x4dbb, 0x4dc2, 0x4dc8, 0x4dcf, 0x4dd5, 0x4ddb, 0x4de2, 
+    0x4de8, 0x4def, 0x4df5, 0x4dfc, 0x4e03, 0x4e09, 0x4e10, 0x4e16, 
+    0x4e1d, 0x4e24, 0x4e2b, 0x4e31, 0x4e38, 0x4e3f, 0x4e46, 0x4e4d, 
+    0x4e54, 0x4e5b, 0x4e62, 0x4e69, 0x4e70, 0x4e77, 0x4e7e, 0x4e85, 
+    0x4e8d, 0x4e94, 0x4e9b, 0x4ea2, 0x4eaa, 0x4eb1, 0x4eb8, 0x4ec0, 
+    0x4ec7, 0x4ecf, 0x4ed6, 0x4ede, 0x4ee5, 0x4eed, 0x4ef5, 0x4efc, 
+    0x4f04, 0x4f0c, 0x4f13, 0x4f1b, 0x4f23, 0x4f2b, 0x4f33, 0x4f3b, 
+    0x4f43, 0x4f4b, 0x4f53, 0x4f5b, 0x4f63, 0x4f6b, 0x4f73, 0x4f7b, 
+    0x4f84, 0x4f8c, 0x4f94, 0x4f9d, 0x4fa5, 0x4fad, 0x4fb6, 0x4fbe, 
+    0x4fc7, 0x4fd0, 0x4fd8, 0x4fe1, 0x4fe9, 0x4ff2, 0x4ffb, 0x5002, 
+    0x5006, 0x500b, 0x500f, 0x5014, 0x5018, 0x501d, 0x5021, 0x5026, 
+    0x502a, 0x502f, 0x5034, 0x5038, 0x503d, 0x5041, 0x5046, 0x504b, 
+    0x5050, 0x5054, 0x5059, 0x505e, 0x5063, 0x5068, 0x506c, 0x5071, 
+    0x5076, 0x507b, 0x5080, 0x5085, 0x508a, 0x508f, 0x5094, 0x5099, 
+    0x509e, 0x50a3, 0x50a8, 0x50ae, 0x50b3, 0x50b8, 0x50bd, 0x50c2, 
+    0x50c8, 0x50cd, 0x50d2, 0x50d7, 0x50dd, 0x50e2, 0x50e7, 0x50ed, 
+    0x50f2, 0x50f8, 0x50fd, 0x5103, 0x5108, 0x510e, 0x5113, 0x5119, 
+    0x511f, 0x5124, 0x512a, 0x5130, 0x5135, 0x513b, 0x5141, 0x5147, 
+    0x514c, 0x5152, 0x5158, 0x515e, 0x5164, 0x516a, 0x5170, 0x5176, 
+    0x517c, 0x5182, 0x5188, 0x518e, 0x5194, 0x519a, 0x51a1, 0x51a7, 
+    0x51ad, 0x51b3, 0x51ba, 0x51c0, 0x51c6, 0x51cd, 0x51d3, 0x51d9, 
+    0x51e0, 0x51e6, 0x51ed, 0x51f3, 0x51fa, 0x5200, 0x5207, 0x520e, 
+    0x5214, 0x521b, 0x5222, 0x5229, 0x522f, 0x5236, 0x523d, 0x5244, 
+    0x524b, 0x5252, 0x5259, 0x5260, 0x5267, 0x526e, 0x5275, 0x527c, 
+    0x5283, 0x528a, 0x5292, 0x5299, 0x52a0, 0x52a7, 0x52af, 0x52b6, 
+    0x52bd, 0x52c5, 0x52cc, 0x52d4, 0x52db, 0x52e3, 0x52ea, 0x52f2, 
+    0x52fa, 0x5301, 0x5309, 0x5311, 0x5319, 0x5321, 0x5328, 0x5330, 
+    0x5338, 0x5340, 0x5348, 0x5350, 0x5358, 0x5360, 0x5369, 0x5371, 
+    0x5379, 0x5381, 0x5389, 0x5392, 0x539a, 0x53a2, 0x53ab, 0x53b3, 
+    0x53bc, 0x53c4, 0x53cd, 0x53d5, 0x53de, 0x53e7, 0x53ef, 0x53f8, 
+    0x5401, 0x5405, 0x5409, 0x540e, 0x5412, 0x5417, 0x541b, 0x5420, 
+    0x5424, 0x5429, 0x542d, 0x5432, 0x5437, 0x543b, 0x5440, 0x5445, 
+    0x5449, 0x544e, 0x5453, 0x5458, 0x545c, 0x5461, 0x5466, 0x546b, 
+    0x5470, 0x5475, 0x547a, 0x547f, 0x5483, 0x5488, 0x548d, 0x5492, 
+    0x5498, 0x549d, 0x54a2, 0x54a7, 0x54ac, 0x54b1, 0x54b6, 0x54bb, 
+    0x54c1, 0x54c6, 0x54cb, 0x54d0, 0x54d6, 0x54db, 0x54e0, 0x54e6, 
+    0x54eb, 0x54f1, 0x54f6, 0x54fc, 0x5501, 0x5507, 0x550c, 0x5512, 
+    0x5517, 0x551d, 0x5522, 0x5528, 0x552e, 0x5534, 0x5539, 0x553f, 
+    0x5545, 0x554b, 0x5550, 0x5556, 0x555c, 0x5562, 0x5568, 0x556e, 
+    0x5574, 0x557a, 0x5580, 0x5586, 0x558c, 0x5592, 0x5598, 0x559f, 
+    0x55a5, 0x55ab, 0x55b1, 0x55b8, 0x55be, 0x55c4, 0x55cb, 0x55d1, 
+    0x55d7, 0x55de, 0x55e4, 0x55eb, 0x55f1, 0x55f8, 0x55fe, 0x5605, 
+    0x560c, 0x5612, 0x5619, 0x5620, 0x5626, 0x562d, 0x5634, 0x563b, 
+    0x5642, 0x5649, 0x5650, 0x5657, 0x565d, 0x5665, 0x566c, 0x5673, 
+    0x567a, 0x5681, 0x5688, 0x568f, 0x5696, 0x569e, 0x56a5, 0x56ac, 
+    0x56b4, 0x56bb, 0x56c3, 0x56ca, 0x56d1, 0x56d9, 0x56e1, 0x56e8, 
+    0x56f0, 0x56f7, 0x56ff, 0x5707, 0x570f, 0x5716, 0x571e, 0x5726, 
+    0x572e, 0x5736, 0x573e, 0x5746, 0x574e, 0x5756, 0x575e, 0x5766, 
+    0x576e, 0x5776, 0x577f, 0x5787, 0x578f, 0x5797, 0x57a0, 0x57a8, 
+    0x57b1, 0x57b9, 0x57c2, 0x57ca, 0x57d3, 0x57db, 0x57e4, 0x57ed, 
+    0x57f5, 0x57fe, 0x5804, 0x5808, 0x580c, 0x5811, 0x5815, 0x581a, 
+    0x581e, 0x5823, 0x5827, 0x582c, 0x5831, 0x5835, 0x583a, 0x583f, 
+    0x5843, 0x5848, 0x584d, 0x5851, 0x5856, 0x585b, 0x5860, 0x5865, 
+    0x5869, 0x586e, 0x5873, 0x5878, 0x587d, 0x5882, 0x5887, 0x588c, 
+    0x5891, 0x5896, 0x589b, 0x58a0, 0x58a5, 0x58aa, 0x58af, 0x58b5, 
+    0x58ba, 0x58bf, 0x58c4, 0x58c9, 0x58cf, 0x58d4, 0x58d9, 0x58df, 
+    0x58e4, 0x58e9, 0x58ef, 0x58f4, 0x58fa, 0x58ff, 0x5905, 0x590a, 
+    0x5910, 0x5915, 0x591b, 0x5921, 0x5926, 0x592c, 0x5932, 0x5937, 
+    0x593d, 0x5943, 0x5949, 0x594f, 0x5954, 0x595a, 0x5960, 0x5966, 
+    0x596c, 0x5972, 0x5978, 0x597e, 0x5984, 0x598a, 0x5990, 0x5996, 
+    0x599d, 0x59a3, 0x59a9, 0x59af, 0x59b6, 0x59bc, 0x59c2, 0x59c9, 
+    0x59cf, 0x59d5, 0x59dc, 0x59e2, 0x59e9, 0x59ef, 0x59f6, 0x59fc, 
+    0x5a03, 0x5a0a, 0x5a10, 0x5a17, 0x5a1e, 0x5a24, 0x5a2b, 0x5a32, 
+    0x5a39, 0x5a40, 0x5a46, 0x5a4d, 0x5a54, 0x5a5b, 0x5a62, 0x5a69, 
+    0x5a70, 0x5a78, 0x5a7f, 0x5a86, 0x5a8d, 0x5a94, 0x5a9b, 0x5aa3, 
+    0x5aaa, 0x5ab1, 0x5ab9, 0x5ac0, 0x5ac8, 0x5acf, 0x5ad7, 0x5ade, 
+    0x5ae6, 0x5aed, 0x5af5, 0x5afd, 0x5b04, 0x5b0c, 0x5b14, 0x5b1c, 
+    0x5b23, 0x5b2b, 0x5b33, 0x5b3b, 0x5b43, 0x5b4b, 0x5b53, 0x5b5b, 
+    0x5b63, 0x5b6c, 0x5b74, 0x5b7c, 0x5b84, 0x5b8c, 0x5b95, 0x5b9d, 
+    0x5ba6, 0x5bae, 0x5bb6, 0x5bbf, 0x5bc7, 0x5bd0, 0x5bd9, 0x5be1, 
+    0x5bea, 0x5bf3, 0x5bfb, 0x5c02, 0x5c07, 0x5c0b, 0x5c0f, 0x5c14, 
+    0x5c18, 0x5c1d, 0x5c21, 0x5c26, 0x5c2b, 0x5c2f, 0x5c34, 0x5c38, 
+    0x5c3d, 0x5c42, 0x5c46, 0x5c4b, 0x5c50, 0x5c55, 0x5c59, 0x5c5e, 
+    0x5c63, 0x5c68, 0x5c6d, 0x5c72, 0x5c77, 0x5c7b, 0x5c80, 0x5c85, 
+    0x5c8a, 0x5c8f, 0x5c94, 0x5c99, 0x5c9e, 0x5ca4, 0x5ca9, 0x5cae, 
+    0x5cb3, 0x5cb8, 0x5cbd, 0x5cc3, 0x5cc8, 0x5ccd, 0x5cd2, 0x5cd8, 
+    0x5cdd, 0x5ce2, 0x5ce8, 0x5ced, 0x5cf3, 0x5cf8, 0x5cfe, 0x5d03, 
+    0x5d09, 0x5d0e, 0x5d14, 0x5d19, 0x5d1f, 0x5d25, 0x5d2a, 0x5d30, 
+    0x5d36, 0x5d3b, 0x5d41, 0x5d47, 0x5d4d, 0x5d53, 0x5d58, 0x5d5e, 
+    0x5d64, 0x5d6a, 0x5d70, 0x5d76, 0x5d7c, 0x5d82, 0x5d88, 0x5d8e, 
+    0x5d95, 0x5d9b, 0x5da1, 0x5da7, 0x5dad, 0x5db4, 0x5dba, 0x5dc0, 
+    0x5dc7, 0x5dcd, 0x5dd3, 0x5dda, 0x5de0, 0x5de7, 0x5ded, 0x5df4, 
+    0x5dfa, 0x5e01, 0x5e07, 0x5e0e, 0x5e15, 0x5e1b, 0x5e22, 0x5e29, 
+    0x5e30, 0x5e37, 0x5e3d, 0x5e44, 0x5e4b, 0x5e52, 0x5e59, 0x5e60, 
+    0x5e67, 0x5e6e, 0x5e75, 0x5e7c, 0x5e84, 0x5e8b, 0x5e92, 0x5e99, 
+    0x5ea0, 0x5ea8, 0x5eaf, 0x5eb6, 0x5ebe, 0x5ec5, 0x5ecd, 0x5ed4, 
+    0x5edc, 0x5ee3, 0x5eeb, 0x5ef3, 0x5efa, 0x5f02, 0x5f0a, 0x5f11, 
+    0x5f19, 0x5f21, 0x5f29, 0x5f31, 0x5f39, 0x5f41, 0x5f49, 0x5f51, 
+    0x5f59, 0x5f61, 0x5f69, 0x5f71, 0x5f79, 0x5f82, 0x5f8a, 0x5f92, 
+    0x5f9b, 0x5fa3, 0x5fab, 0x5fb4, 0x5fbc, 0x5fc5, 0x5fcd, 0x5fd6, 
+    0x5fdf, 0x5fe7, 0x5ff0, 0x5ff9, 0x6001, 0x6005, 0x600a, 0x600e, 
+    0x6013, 0x6017, 0x601c, 0x6020, 0x6025, 0x6029, 0x602e, 0x6032, 
+    0x6037, 0x603c, 0x6040, 0x6045, 0x604a, 0x604e, 0x6053, 0x6058, 
+    0x605d, 0x6062, 0x6066, 0x606b, 0x6070, 0x6075, 0x607a, 0x607f, 
+    0x6084, 0x6089, 0x608e, 0x6093, 0x6098, 0x609d, 0x60a2, 0x60a7, 
+    0x60ac, 0x60b1, 0x60b7, 0x60bc, 0x60c1, 0x60c6, 0x60cb, 0x60d1, 
+    0x60d6, 0x60db, 0x60e1, 0x60e6, 0x60eb, 0x60f1, 0x60f6, 0x60fc, 
+    0x6101, 0x6107, 0x610c, 0x6112, 0x6118, 0x611d, 0x6123, 0x6128, 
+    0x612e, 0x6134, 0x613a, 0x613f, 0x6145, 0x614b, 0x6151, 0x6157, 
+    0x615d, 0x6162, 0x6168, 0x616e, 0x6174, 0x617a, 0x6180, 0x6186, 
+    0x618d, 0x6193, 0x6199, 0x619f, 0x61a5, 0x61ab, 0x61b2, 0x61b8, 
+    0x61be, 0x61cb, 0x61d8, 0x61e5, 0x61f2, 0x61ff, 0x620c, 0x6219, 
+    0x6227, 0x6234, 0x6242, 0x6250, 0x625e, 0x626c, 0x627a, 0x6288, 
+    0x6297, 0x62a5, 0x62b4, 0x62c3, 0x62d2, 0x62e1, 0x62f0, 0x62ff, 
+    0x630f, 0x631f, 0x632e, 0x633e, 0x634e, 0x635e, 0x636f, 0x637f, 
+    0x6390, 0x63a0, 0x63b1, 0x63c2, 0x63d3, 0x63e5, 0x63f6, 0x6404, 
+    0x640d, 0x6416, 0x641f, 0x6428, 0x6431, 0x643a, 0x6444, 0x644d, 
+    0x6456, 0x6460, 0x646a, 0x6473, 0x647d, 0x6487, 0x6491, 0x649b, 
+    0x64a5, 0x64b0, 0x64ba, 0x64c5, 0x64cf, 0x64da, 0x64e4, 0x64ef, 
+    0x64fa, 0x6505, 0x6510, 0x651b, 0x6527, 0x6532, 0x653e, 0x6549, 
+    0x6555, 0x6561, 0x656c, 0x6578, 0x6585, 0x6591, 0x659d, 0x65a9, 
+    0x65b6, 0x65c3, 0x65cf, 0x65dc, 0x65e9, 0x65f6, 0x6603, 0x6611, 
+    0x661e, 0x662b, 0x6639, 0x6647, 0x6655, 0x6663, 0x6671, 0x667f, 
+    0x668d, 0x669c, 0x66aa, 0x66b9, 0x66c8, 0x66d7, 0x66e6, 0x66f5, 
+    0x6705, 0x6714, 0x6724, 0x6734, 0x6744, 0x6754, 0x6764, 0x6774, 
+    0x6785, 0x6795, 0x67a6, 0x67b7, 0x67c8, 0x67d9, 0x67ea, 0x67fc, 
+    0x6807, 0x6810, 0x6819, 0x6822, 0x682b, 0x6834, 0x683d, 0x6847, 
+    0x6850, 0x685a, 0x6863, 0x686d, 0x6877, 0x6881, 0x688b, 0x6895, 
+    0x689f, 0x68a9, 0x68b3, 0x68be, 0x68c8, 0x68d3, 0x68dd, 0x68e8, 
+    0x68f3, 0x68fe, 0x6909, 0x6914, 0x691f, 0x692b, 0x6936, 0x6941, 
+    0x694d, 0x6959, 0x6965, 0x6971, 0x697d, 0x6989, 0x6995, 0x69a1, 
+    0x69ae, 0x69ba, 0x69c7, 0x69d4, 0x69e1, 0x69ee, 0x69fb, 0x6a08, 
+    0x6a15, 0x6a23, 0x6a30, 0x6a3e, 0x6a4c, 0x6a5a, 0x6a68, 0x6a76, 
+    0x6a84, 0x6a92, 0x6aa1, 0x6ab0, 0x6abe, 0x6acd, 0x6adc, 0x6aeb, 
+    0x6afb, 0x6b0a, 0x6b1a, 0x6b29, 0x6b39, 0x6b49, 0x6b59, 0x6b69, 
+    0x6b7a, 0x6b8a, 0x6b9b, 0x6bac, 0x6bbd, 0x6bce, 0x6bdf, 0x6bf0, 
+    0x6c01, 0x6c0a, 0x6c13, 0x6c1c, 0x6c25, 0x6c2e, 0x6c37, 0x6c41, 
+    0x6c4a, 0x6c53, 0x6c5d, 0x6c67, 0x6c70, 0x6c7a, 0x6c84, 0x6c8e, 
+    0x6c98, 0x6ca2, 0x6cac, 0x6cb7, 0x6cc1, 0x6ccc, 0x6cd6, 0x6ce1, 
+    0x6cec, 0x6cf7, 0x6d02, 0x6d0d, 0x6d18, 0x6d23, 0x6d2e, 0x6d3a, 
+    0x6d45, 0x6d51, 0x6d5d, 0x6d69, 0x6d75, 0x6d81, 0x6d8d, 0x6d99, 
+    0x6da5, 0x6db2, 0x6dbf, 0x6dcb, 0x6dd8, 0x6de5, 0x6df2, 0x6dff, 
+    0x6e0c, 0x6e1a, 0x6e27, 0x6e35, 0x6e43, 0x6e50, 0x6e5e, 0x6e6c, 
+    0x6e7b, 0x6e89, 0x6e97, 0x6ea6, 0x6eb5, 0x6ec3, 0x6ed2, 0x6ee1, 
+    0x6ef1, 0x6f00, 0x6f0f, 0x6f1f, 0x6f2f, 0x6f3f, 0x6f4f, 0x6f5f, 
+    0x6f6f, 0x6f7f, 0x6f90, 0x6fa1, 0x6fb2, 0x6fc3, 0x6fd4, 0x6fe5, 
+    0x6ff6, 0x7004, 0x700d, 0x7016, 0x701f, 0x7028, 0x7031, 0x703a, 
+    0x7044, 0x704d, 0x7057, 0x7060, 0x706a, 0x7074, 0x707e, 0x7087, 
+    0x7091, 0x709c, 0x70a6, 0x70b0, 0x70ba, 0x70c5, 0x70cf, 0x70da, 
+    0x70e5, 0x70f0, 0x70fa, 0x7105, 0x7111, 0x711c, 0x7127, 0x7132, 
+    0x713e, 0x7149, 0x7155, 0x7161, 0x716d, 0x7179, 0x7185, 0x7191, 
+    0x719d, 0x71aa, 0x71b6, 0x71c3, 0x71d0, 0x71dc, 0x71e9, 0x71f6, 
+    0x7204, 0x7211, 0x721e, 0x722c, 0x7239, 0x7247, 0x7255, 0x7263, 
+    0x7271, 0x727f, 0x728e, 0x729c, 0x72ab, 0x72ba, 0x72c8, 0x72d7, 
+    0x72e7, 0x72f6, 0x7305, 0x7315, 0x7324, 0x7334, 0x7344, 0x7354, 
+    0x7364, 0x7375, 0x7385, 0x7396, 0x73a6, 0x73b7, 0x73c8, 0x73da, 
+    0x73eb, 0x73fc, 0x7407, 0x7410, 0x7419, 0x7422, 0x742b, 0x7434, 
+    0x743e, 0x7447, 0x7450, 0x745a, 0x7464, 0x746d, 0x7477, 0x7481, 
+    0x748b, 0x7495, 0x749f, 0x74a9, 0x74b4, 0x74be, 0x74c8, 0x74d3, 
+    0x74de, 0x74e8, 0x74f3, 0x74fe, 0x7509, 0x7514, 0x7520, 0x752b, 
+    0x7536, 0x7542, 0x754d, 0x7559, 0x7565, 0x7571, 0x757d, 0x7589, 
+    0x7595, 0x75a2, 0x75ae, 0x75bb, 0x75c7, 0x75d4, 0x75e1, 0x75ee, 
+    0x75fb, 0x7608, 0x7616, 0x7623, 0x7631, 0x763e, 0x764c, 0x765a, 
+    0x7668, 0x7676, 0x7684, 0x7693, 0x76a1, 0x76b0, 0x76bf, 0x76ce, 
+    0x76dd, 0x76ec, 0x76fb, 0x770b, 0x771a, 0x772a, 0x773a, 0x774a, 
+    0x775a, 0x776a, 0x777a, 0x778b, 0x779b, 0x77ac, 0x77bd, 0x77ce, 
+    0x77e0, 0x77f1, 0x7801, 0x780a, 0x7813, 0x781c, 0x7825, 0x782e, 
+    0x7838, 0x7841, 0x784a, 0x7854, 0x785d, 0x7867, 0x7871, 0x787a, 
+    0x7884, 0x788e, 0x7898, 0x78a3, 0x78ad, 0x78b7, 0x78c2, 0x78cc, 
+    0x78d7, 0x78e1, 0x78ec, 0x78f7, 0x7902, 0x790d, 0x7918, 0x7923, 
+    0x792f, 0x793a, 0x7946, 0x7951, 0x795d, 0x7969, 0x7975, 0x7981, 
+    0x798d, 0x7999, 0x79a6, 0x79b2, 0x79bf, 0x79cc, 0x79d8, 0x79e5, 
+    0x79f2, 0x79ff, 0x7a0d, 0x7a1a, 0x7a28, 0x7a35, 0x7a43, 0x7a51, 
+    0x7a5f, 0x7a6d, 0x7a7b, 0x7a89, 0x7a98, 0x7aa6, 0x7ab5, 0x7ac4, 
+    0x7ad3, 0x7ae2, 0x7af1, 0x7b00, 0x7b10, 0x7b1f, 0x7b2f, 0x7b3f, 
+    0x7b4f, 0x7b5f, 0x7b70, 0x7b80, 0x7b91, 0x7ba1, 0x7bb2, 0x7bc3, 
+    0x7bd4, 0x7be6, 0x7bf7, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 
+    0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0x8003, 
+    0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 
+    0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 
+    0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 
+    0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 
+    0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 
+    0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 
+    0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 
+    0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 
+    0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 
+    0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 
+    0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 
+    0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 
+    0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 
+    0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 
+    0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 
+    0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 
+    0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 
+    0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 
+    0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 
+    0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 
+    0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 
+    0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 
+    0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 
+    0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 
+    0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 
+    0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 
+    0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 
+    0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 
+    0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 
+    0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 
+    0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 
+    0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 
+    0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 
+    0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 0x8003, 
+    0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 
+    0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 
+    0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 
+    0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 
+    0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 
+    0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 
+    0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 
+    0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 
+    0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 
+    0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 
+    0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 
+    0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 
+    0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 
+    0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 
+    0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 
+    0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 
+    0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 
+    0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 
+    0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 
+    0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 
+    0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 
+    0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 
+    0x8004, 0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 
+    0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 
+    0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 
+    0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 
+    0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 
+    0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 
+    0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 
+    0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 
+    0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 
+    0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 
+    0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 
+    0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 
+    0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 0x8005, 
+    0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 
+    0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 
+    0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 
+    0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 
+    0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 
+    0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 
+    0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 
+    0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 
+    0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 
+    0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 
+    0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 
+    0x8006, 0x8006, 0x8006, 0x8006, 0x8006, 0x8007, 0x8007, 0x8007, 
+    0x8007, 0x8007, 0x8007, 0x8007, 0x8007, 0x8007, 0x8007, 0x8007, 
+    0x8007, 0x8007, 0x8007, 0x8007, 0x8007, 0x8007, 0x8007, 0x8007, 
+    0x8007, 0x8007, 0x8007, 0x8007, 0x8007, 0x8007, 0x8007, 0x8007, 
+    0x8007, 0x8007, 0x8007, 0x8007, 0x8007, 0x8007, 0x8007, 0x8007, 
+    0x8007, 0x8007, 0x8007, 0x8007, 0x8007, 0x8007, 0x8007, 0x8007, 
+    0x8007, 0x8007, 0x8007, 0x8007, 0x8007, 0x8007, 0x8007, 0x8007, 
+    0x8007, 0x8007, 0x8007, 0x8007, 0x8007, 0x8007, 0x8007, 0x8007, 
+    0x8007, 0x8007, 0x8007, 0x8007, 0x8007, 0x8007, 0x8007, 0x8007, 
+    0x8007, 0x8007, 0x8007, 0x8007, 0x8007, 0x8007, 0x8007, 0x8007, 
+    0x8007, 0x8007, 0x8007, 0x8007, 0x8007, 0x8007, 0x8007, 0x8007, 
+    0x8007, 0x8007, 0x8007, 0x8008, 0x8008, 0x8008, 0x8008, 0x8008, 
+    0x8008, 0x8008, 0x8008, 0x8008, 0x8008, 0x8008, 0x8008, 0x8008, 
+    0x8008, 0x8008, 0x8008, 0x8008, 0x8008, 0x8008, 0x8008, 0x8008, 
+    0x8008, 0x8008, 0x8008, 0x8008, 0x8008, 0x8008, 0x8008, 0x8008, 
+    0x8008, 0x8008, 0x8008, 0x8008, 0x8008, 0x8008, 0x8008, 0x8008, 
+    0x8008, 0x8008, 0x8008, 0x8008, 0x8008, 0x8008, 0x8008, 0x8008, 
+    0x8008, 0x8008, 0x8008, 0x8008, 0x8008, 0x8008, 0x8008, 0x8008, 
+    0x8008, 0x8008, 0x8008, 0x8008, 0x8008, 0x8008, 0x8008, 0x8008, 
+    0x8008, 0x8008, 0x8008, 0x8008, 0x8008, 0x8008, 0x8008, 0x8008, 
+    0x8008, 0x8008, 0x8008, 0x8008, 0x8008, 0x8008, 0x8008, 0x8008, 
+    0x8008, 0x8008, 0x8008, 0x8009, 0x8009, 0x8009, 0x8009, 0x8009, 
+    0x8009, 0x8009, 0x8009, 0x8009, 0x8009, 0x8009, 0x8009, 0x8009, 
+    0x8009, 0x8009, 0x8009, 0x8009, 0x8009, 0x8009, 0x8009, 0x8009, 
+    0x8009, 0x8009, 0x8009, 0x8009, 0x8009, 0x8009, 0x8009, 0x8009, 
+    0x8009, 0x8009, 0x8009, 0x8009, 0x8009, 0x8009, 0x8009, 0x8009, 
+    0x8009, 0x8009, 0x8009, 0x8009, 0x8009, 0x8009, 0x8009, 0x8009, 
+    0x8009, 0x8009, 0x8009, 0x8009, 0x8009, 0x8009, 0x8009, 0x8009, 
+    0x8009, 0x8009, 0x8009, 0x8009, 0x8009, 0x8009, 0x8009, 0x8009, 
+    0x8009, 0x8009, 0x8009, 0x8009, 0x8009, 0x8009, 0x8009, 0x8009, 
+    0x8009, 0x8009, 0x8009, 0x8009, 0x8009, 0x8009, 0x800a, 0x800a, 
+    0x800a, 0x800a, 0x800a, 0x800a, 0x800a, 0x800a, 0x800a, 0x800a, 
+    0x800a, 0x800a, 0x800a, 0x800a, 0x800a, 0x800a, 0x800a, 0x800a, 
+    0x800a, 0x800a, 0x800a, 0x800a, 0x800a, 0x800a, 0x800a, 0x800a, 
+    0x800a, 0x800a, 0x800a, 0x800a, 0x800a, 0x800a, 0x800a, 0x800a, 
+    0x800a, 0x800a, 0x800a, 0x800a, 0x800a, 0x800a, 0x800a, 0x800a, 
+    0x800a, 0x800a, 0x800a, 0x800a, 0x800a, 0x800a, 0x800a, 0x800a, 
+    0x800a, 0x800a, 0x800a, 0x800a, 0x800a, 0x800a, 0x800a, 0x800a, 
+    0x800a, 0x800a, 0x800a, 0x800a, 0x800a, 0x800a, 0x800a, 0x800a, 
+    0x800a, 0x800a, 0x800a, 0x800a, 0x800b, 0x800b, 0x800b, 0x800b, 
+    0x800b, 0x800b, 0x800b, 0x800b, 0x800b, 0x800b, 0x800b, 0x800b, 
+    0x800b, 0x800b, 0x800b, 0x800b, 0x800b, 0x800b, 0x800b, 0x800b, 
+    0x800b, 0x800b, 0x800b, 0x800b, 0x800b, 0x800b, 0x800b, 0x800b, 
+    0x800b, 0x800b, 0x800b, 0x800b, 0x800b, 0x800b, 0x800b, 0x800b, 
+    0x800b, 0x800b, 0x800b, 0x800b, 0x800b, 0x800b, 0x800b, 0x800b, 
+    0x800b, 0x800b, 0x800b, 0x800b, 0x800b, 0x800b, 0x800b, 0x800b, 
+    0x800b, 0x800b, 0x800b, 0x800b, 0x800b, 0x800b, 0x800b, 0x800b, 
+    0x800b, 0x800b, 0x800b, 0x800b, 0x800b, 0x800b, 0x800b, 0x800c, 
+    0x800c, 0x800c, 0x800c, 0x800c, 0x800c, 0x800c, 0x800c, 0x800c, 
+    0x800c, 0x800c, 0x800c, 0x800c, 0x800c, 0x800c, 0x800c, 0x800c, 
+    0x800c, 0x800c, 0x800c, 0x800c, 0x800c, 0x800c, 0x800c, 0x800c, 
+    0x800c, 0x800c, 0x800c, 0x800c, 0x800c, 0x800c, 0x800c, 0x800c, 
+    0x800c, 0x800c, 0x800c, 0x800c, 0x800c, 0x800c, 0x800c, 0x800c, 
+    0x800c, 0x800c, 0x800c, 0x800c, 0x800c, 0x800c, 0x800c, 0x800c, 
+    0x800c, 0x800c, 0x800c, 0x800c, 0x800c, 0x800c, 0x800c, 0x800c, 
+    0x800c, 0x800c, 0x800c, 0x800c, 0x800c, 0x800c, 0x800c, 0x800d, 
+    0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 
+    0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 
+    0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 
+    0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 
+    0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 
+    0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 
+    0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 
+    0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800e, 0x800e, 0x800e, 
+    0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 
+    0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 
+    0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 
+    0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 
+    0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 
+    0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 
+    0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800f, 
+    0x800f, 0x800f, 0x800f, 0x800f, 0x800f, 0x800f, 0x800f, 0x800f, 
+    0x800f, 0x800f, 0x800f, 0x800f, 0x800f, 0x800f, 0x800f, 0x800f, 
+    0x800f, 0x800f, 0x800f, 0x800f, 0x800f, 0x800f, 0x800f, 0x800f, 
+    0x800f, 0x800f, 0x800f, 0x800f, 0x800f, 0x800f, 0x800f, 0x800f, 
+    0x800f, 0x800f, 0x800f, 0x800f, 0x800f, 0x800f, 0x800f, 0x800f, 
+    0x800f, 0x800f, 0x800f, 0x800f, 0x800f, 0x800f, 0x800f, 0x800f, 
+    0x800f, 0x800f, 0x800f, 0x800f, 0x800f, 0x800f, 0x800f, 0x800f, 
+    0x8010, 0x8010, 0x8010, 0x8010, 0x8010, 0x8010, 0x8010, 0x8010, 
+    0x8010, 0x8010, 0x8010, 0x8010, 0x8010, 0x8010, 0x8010, 0x8010, 
+    0x8010, 0x8010, 0x8010, 0x8010, 0x8010, 0x8010, 0x8010, 0x8010, 
+    0x8010, 0x8010, 0x8010, 0x8010, 0x8010, 0x8010, 0x8010, 0x8010, 
+    0x8010, 0x8010, 0x8010, 0x8010, 0x8010, 0x8010, 0x8010, 0x8010, 
+    0x8010, 0x8010, 0x8010, 0x8010, 0x8010, 0x8010, 0x8010, 0x8010, 
+    0x8010, 0x8010, 0x8010, 0x8010, 0x8010, 0x8010, 0x8010, 0x8011, 
+    0x8011, 0x8011, 0x8011, 0x8011, 0x8011, 0x8011, 0x8011, 0x8011, 
+    0x8011, 0x8011, 0x8011, 0x8011, 0x8011, 0x8011, 0x8011, 0x8011, 
+    0x8011, 0x8011, 0x8011, 0x8011, 0x8011, 0x8011, 0x8011, 0x8011, 
+    0x8011, 0x8011, 0x8011, 0x8011, 0x8011, 0x8011, 0x8011, 0x8011, 
+    0x8011, 0x8011, 0x8011, 0x8011, 0x8011, 0x8011, 0x8011, 0x8011, 
+    0x8011, 0x8011, 0x8011, 0x8011, 0x8011, 0x8011, 0x8011, 0x8011, 
+    0x8011, 0x8011, 0x8011, 0x8012, 0x8012, 0x8012, 0x8012, 0x8012, 
+    0x8012, 0x8012, 0x8012, 0x8012, 0x8012, 0x8012, 0x8012, 0x8012, 
+    0x8012, 0x8012, 0x8012, 0x8012, 0x8012, 0x8012, 0x8012, 0x8012, 
+    0x8012, 0x8012, 0x8012, 0x8012, 0x8012, 0x8012, 0x8012, 0x8012, 
+    0x8012, 0x8012, 0x8012, 0x8012, 0x8012, 0x8012, 0x8012, 0x8012, 
+    0x8012, 0x8012, 0x8012, 0x8012, 0x8012, 0x8012, 0x8012, 0x8012, 
+    0x8012, 0x8012, 0x8012, 0x8012, 0x8013, 0x8013, 0x8013, 0x8013, 
+    0x8013, 0x8013, 0x8013, 0x8013, 0x8013, 0x8013, 0x8013, 0x8013, 
+    0x8013, 0x8013, 0x8013, 0x8013, 0x8013, 0x8013, 0x8013, 0x8013, 
+    0x8013, 0x8013, 0x8013, 0x8013, 0x8014, 0x8014, 0x8014, 0x8014, 
+    0x8014, 0x8014, 0x8014, 0x8014, 0x8014, 0x8014, 0x8014, 0x8014, 
+    0x8014, 0x8014, 0x8014, 0x8014, 0x8014, 0x8014, 0x8014, 0x8014, 
+    0x8014, 0x8014, 0x8014, 0x8014, 0x8014, 0x8015, 0x8015, 0x8015, 
+    0x8015, 0x8015, 0x8015, 0x8015, 0x8015, 0x8015, 0x8015, 0x8015, 
+    0x8015, 0x8015, 0x8015, 0x8015, 0x8015, 0x8015, 0x8015, 0x8015, 
+    0x8015, 0x8015, 0x8015, 0x8015, 0x8016, 0x8016, 0x8016, 0x8016, 
+    0x8016, 0x8016, 0x8016, 0x8016, 0x8016, 0x8016, 0x8016, 0x8016, 
+    0x8016, 0x8016, 0x8016, 0x8016, 0x8016, 0x8016, 0x8016, 0x8016, 
+    0x8016, 0x8016, 0x8016, 0x8017, 0x8017, 0x8017, 0x8017, 0x8017, 
+    0x8017, 0x8017, 0x8017, 0x8017, 0x8017, 0x8017, 0x8017, 0x8017, 
+    0x8017, 0x8017, 0x8017, 0x8017, 0x8017, 0x8017, 0x8017, 0x8017, 
+    0x8017, 0x8017, 0x8018, 0x8018, 0x8018, 0x8018, 0x8018, 0x8018, 
+    0x8018, 0x8018, 0x8018, 0x8018, 0x8018, 0x8018, 0x8018, 0x8018, 
+    0x8018, 0x8018, 0x8018, 0x8018, 0x8018, 0x8018, 0x8018, 0x8019, 
+    0x8019, 0x8019, 0x8019, 0x8019, 0x8019, 0x8019, 0x8019, 0x8019, 
+    0x8019, 0x8019, 0x8019, 0x8019, 0x8019, 0x8019, 0x8019, 0x8019, 
+    0x8019, 0x8019, 0x8019, 0x8019, 0x8019, 0x801a, 0x801a, 0x801a, 
+    0x801a, 0x801a, 0x801a, 0x801a, 0x801a, 0x801a, 0x801a, 0x801a, 
+    0x801a, 0x801a, 0x801a, 0x801a, 0x801a, 0x801a, 0x801a, 0x801a, 
+    0x801a, 0x801a, 0x801b, 0x801b, 0x801b, 0x801b, 0x801b, 0x801b, 
+    0x801b, 0x801b, 0x801b, 0x801b, 0x801b, 0x801b, 0x801b, 0x801b, 
+    0x801b, 0x801b, 0x801b, 0x801b, 0x801b, 0x801b, 0x801c, 0x801c, 
+    0x801c, 0x801c, 0x801c, 0x801c, 0x801c, 0x801c, 0x801c, 0x801c, 
+    0x801c, 0x801c, 0x801c, 0x801c, 0x801c, 0x801c, 0x801c, 0x801c, 
+    0x801c, 0x801c, 0x801d, 0x801d, 0x801d, 0x801d, 0x801d, 0x801d, 
+    0x801d, 0x801d, 0x801d, 0x801d, 0x801d, 0x801d, 0x801d, 0x801d, 
+    0x801d, 0x801d, 0x801d, 0x801d, 0x801d, 0x801d, 0x801e, 0x801e, 
+    0x801e, 0x801e, 0x801e, 0x801e, 0x801e, 0x801e, 0x801e, 0x801e, 
+    0x801e, 0x801e, 0x801e, 0x801e, 0x801e, 0x801e, 0x801e, 0x801e, 
+    0x801e, 0x801e, 0x801f, 0x801f, 0x801f, 0x801f, 0x801f, 0x801f, 
+    0x801f, 0x801f, 0x801f, 0x801f, 0x801f, 0x801f, 0x801f, 0x801f, 
+    0x801f, 0x801f, 0x801f, 0x801f, 0x801f, 0x8020, 0x8020, 0x8020, 
+    0x8020, 0x8020, 0x8020, 0x8020, 0x8020, 0x8020, 0x8020, 0x8020, 
+    0x8020, 0x8020, 0x8020, 0x8020, 0x8020, 0x8020, 0x8020, 0x8021, 
+    0x8021, 0x8021, 0x8021, 0x8021, 0x8021, 0x8021, 0x8021, 0x8021, 
+    0x8021, 0x8021, 0x8021, 0x8021, 0x8021, 0x8021, 0x8021, 0x8021, 
+    0x8021, 0x8021, 0x8022, 0x8022, 0x8022, 0x8022, 0x8022, 0x8022, 
+    0x8022, 0x8022, 0x8022, 0x8022, 0x8022, 0x8022, 0x8022, 0x8022, 
+    0x8022, 0x8022, 0x8022, 0x8022, 0x8023, 0x8023, 0x8023, 0x8023, 
+    0x8023, 0x8023, 0x8023, 0x8023, 0x8023, 0x8023, 0x8023, 0x8023, 
+    0x8023, 0x8023, 0x8023, 0x8023, 0x8023, 0x8023, 0x8024, 0x8024, 
+    0x8024, 0x8024, 0x8024, 0x8024, 0x8024, 0x8024, 0x8024, 0x8024, 
+    0x8024, 0x8024, 0x8024, 0x8024, 0x8024, 0x8024, 0x8024, 0x8025, 
+    0x8025, 0x8025, 0x8025, 0x8025, 0x8025, 0x8025, 0x8025, 0x8025, 
+    0x8025, 0x8025, 0x8025, 0x8025, 0x8025, 0x8025, 0x8025, 0x8025, 
+    0x8025, 0x8026, 0x8026, 0x8026, 0x8026, 0x8026, 0x8026, 0x8026, 
+    0x8026, 0x8026, 0x8026, 0x8026, 0x8026, 0x8026, 0x8026, 0x8026, 
+    0x8026, 0x8026, 0x8027, 0x8027, 0x8027, 0x8027, 0x8027, 0x8027, 
+    0x8027, 0x8027, 0x8027, 0x8027, 0x8027, 0x8027, 0x8027, 0x8027, 
+    0x8027, 0x8027, 0x8028, 0x8028, 0x8028, 0x8028, 0x8028, 0x8028, 
+    0x8028, 0x8028, 0x8028, 0x8028, 0x8028, 0x8028, 0x8028, 0x8028, 
+    0x8028, 0x8028, 0x8028, 0x8029, 0x8029, 0x8029, 0x8029, 0x8029, 
+    0x8029, 0x8029, 0x8029, 0x8029, 0x8029, 0x8029, 0x8029, 0x8029, 
+    0x8029, 0x8029, 0x8029, 0x802a, 0x802a, 0x802a, 0x802a, 0x802a, 
+    0x802a, 0x802a, 0x802a, 0x802a, 0x802a, 0x802a, 0x802a, 0x802a, 
+    0x802a, 0x802a, 0x802a, 0x802b, 0x802b, 0x802b, 0x802b, 0x802b, 
+    0x802b, 0x802b, 0x802b, 0x802b, 0x802b, 0x802b, 0x802b, 0x802b, 
+    0x802b, 0x802b, 0x802b, 0x802c, 0x802c, 0x802c, 0x802c, 0x802c, 
+    0x802c, 0x802c, 0x802c, 0x802c, 0x802c, 0x802c, 0x802c, 0x802c, 
+    0x802c, 0x802c, 0x802c, 0x802d, 0x802d, 0x802d, 0x802d, 0x802d, 
+    0x802d, 0x802d, 0x802d, 0x802d, 0x802d, 0x802d, 0x802d, 0x802d, 
+    0x802d, 0x802d, 0x802d, 0x802e, 0x802e, 0x802e, 0x802e, 0x802e, 
+    0x802e, 0x802e, 0x802e, 0x802e, 0x802e, 0x802e, 0x802e, 0x802e, 
+    0x802e, 0x802e, 0x802f, 0x802f, 0x802f, 0x802f, 0x802f, 0x802f, 
+    0x802f, 0x802f, 0x802f, 0x802f, 0x802f, 0x802f, 0x802f, 0x802f, 
+    0x802f, 0x8030, 0x8030, 0x8030, 0x8030, 0x8030, 0x8030, 0x8030, 
+    0x8030, 0x8030, 0x8030, 0x8030, 0x8030, 0x8030, 0x8030, 0x8030, 
+    0x8031, 0x8031, 0x8031, 0x8031, 0x8031, 0x8031, 0x8031, 0x8031, 
+    0x8031, 0x8031, 0x8031, 0x8031, 0x8031, 0x8031, 0x8031, 0x8032, 
+    0x8032, 0x8032, 0x8032, 0x8032, 0x8032, 0x8032, 0x8032, 0x8032, 
+    0x8032, 0x8032, 0x8032, 0x8032, 0x8032, 0x8032, 0x8033, 0x8033, 
+    0x8033, 0x8033, 0x8033, 0x8033, 0x8033, 0x8033, 0x8033, 0x8033, 
+    0x8033, 0x8033, 0x8033, 0x8033, 0x8034, 0x8034, 0x8034, 0x8034, 
+    0x8034, 0x8034, 0x8034, 0x8034, 0x8034, 0x8034, 0x8034, 0x8034, 
+    0x8034, 0x8034, 0x8034, 0x8035, 0x8035, 0x8035, 0x8035, 0x8035, 
+    0x8035, 0x8035, 0x8035, 0x8035, 0x8035, 0x8035, 0x8035, 0x8035, 
+    0x8035, 0x8036, 0x8036, 0x8036, 0x8036, 0x8036, 0x8036, 0x8036, 
+    0x8036, 0x8036, 0x8036, 0x8036, 0x8036, 0x8036, 0x8036, 0x8037, 
+    0x8037, 0x8037, 0x8037, 0x8037, 0x8037, 0x8037, 0x8037, 0x8037, 
+    0x8037, 0x8037, 0x8037, 0x8037, 0x8037, 0x8038, 0x8038, 0x8038, 
+    0x8038, 0x8038, 0x8038, 0x8038, 0x8038, 0x8038, 0x8038, 0x8038, 
+    0x8038, 0x8038, 0x8038, 0x8039, 0x8039, 0x8039, 0x8039, 0x8039, 
+    0x8039, 0x8039, 0x8039, 0x8039, 0x8039, 0x8039, 0x8039, 0x8039, 
+    0x803a, 0x803a, 0x803a, 0x803a, 0x803a, 0x803a, 0x803a, 0x803a, 
+    0x803a, 0x803a, 0x803a, 0x803a, 0x803a, 0x803a, 0x803b, 0x803b, 
+    0x803b, 0x803b, 0x803b, 0x803b, 0x803b, 0x803b, 0x803b, 0x803b, 
+    0x803b, 0x803b, 0x803b, 0x803c, 0x803c, 0x803c, 0x803c, 0x803c, 
+    0x803c, 0x803c, 0x803c, 0x803c, 0x803c, 0x803c, 0x803c, 0x803c, 
+    0x803d, 0x803d, 0x803d, 0x803d, 0x803d, 0x803d, 0x803d, 0x803d, 
+    0x803d, 0x803d, 0x803d, 0x803d, 0x803d, 0x803d, 0x803e, 0x803e, 
+    0x803e, 0x803e, 0x803e, 0x803e, 0x803e, 0x803e, 0x803e, 0x803e, 
+    0x803e, 0x803e, 0x803e, 0x803f, 0x803f, 0x803f, 0x803f, 0x803f, 
+    0x803f, 0x803f, 0x803f, 0x803f, 0x803f, 0x803f, 0x803f, 0x803f, 
+    0x8040, 0x8040, 0x8040, 0x8040, 0x8040, 0x8040, 0x8040, 0x8040, 
+    0x8040, 0x8040, 0x8040, 0x8040, 0x8041, 0x8041, 0x8041, 0x8041, 
+    0x8041, 0x8041, 0x8041, 0x8041, 0x8041, 0x8041, 0x8041, 0x8041, 
+    0x8041, 0x8042, 0x8042, 0x8042, 0x8042, 0x8042, 0x8042, 0x8042, 
+    0x8042, 0x8042, 0x8042, 0x8042, 0x8042, 0x8042, 0x8043, 0x8043, 
+    0x8043, 0x8043, 0x8043, 0x8043, 0x8043, 0x8043, 0x8043, 0x8043, 
+    0x8043, 0x8043, 0x8044, 0x8044, 0x8044, 0x8044, 0x8044, 0x8044, 
+    0x8044, 0x8044, 0x8044, 0x8044, 0x8044, 0x8044, 0x8044, 0x8045, 
+    0x8045, 0x8045, 0x8045, 0x8045, 0x8045, 0x8045, 0x8045, 0x8045, 
+    0x8045, 0x8045, 0x8045, 0x8046, 0x8046, 0x8046, 0x8046, 0x8046, 
+    0x8046, 0x8046, 0x8046, 0x8046, 0x8046, 0x8046, 0x8046, 0x8047, 
+    0x8047, 0x8047, 0x8047, 0x8047, 0x8047, 0x8047, 0x8047, 0x8047, 
+    0x8047, 0x8047, 0x8047, 0x8048, 0x8048, 0x8048, 0x8048, 0x8048, 
+    0x8048, 0x8048, 0x8048, 0x8048, 0x8048, 0x8048, 0x8048, 0x8049, 
+    0x8049, 0x8049, 0x8049, 0x8049, 0x8049, 0x8049, 0x8049, 0x8049, 
+    0x8049, 0x8049, 0x8049, 0x804a, 0x804a, 0x804a, 0x804a, 0x804a, 
+    0x804a, 0x804a, 0x804a, 0x804a, 0x804a, 0x804a, 0x804a, 0x804b, 
+    0x804b, 0x804b, 0x804b, 0x804b, 0x804b, 0x804b, 0x804b, 0x804b, 
+    0x804b, 0x804b, 0x804b, 0x804c, 0x804c, 0x804c, 0x804c, 0x804c, 
+    0x804c, 0x804c, 0x804c, 0x804c, 0x804c, 0x804c, 0x804c, 0x804d, 
+    0x804d, 0x804d, 0x804d, 0x804d, 0x804d, 0x804d, 0x804d, 0x804d, 
+    0x804d, 0x804d, 0x804e, 0x804e, 0x804e, 0x804e, 0x804e, 0x804e, 
+    0x804e, 0x804e, 0x804e, 0x804e, 0x804e, 0x804e, 0x804f, 0x804f, 
+    0x804f, 0x804f, 0x804f, 0x804f, 0x804f, 0x804f, 0x804f, 0x804f, 
+    0x804f, 0x8050, 0x8050, 0x8050, 0x8050, 0x8050, 0x8050, 0x8050, 
+    0x8050, 0x8050, 0x8050, 0x8050, 0x8051, 0x8051, 0x8051, 0x8051, 
+    0x8051, 0x8051, 0x8051, 0x8051, 0x8051, 0x8051, 0x8051, 0x8051, 
+    0x8052, 0x8052, 0x8052, 0x8052, 0x8052, 0x8052, 0x8052, 0x8052, 
+    0x8052, 0x8052, 0x8052, 0x8053, 0x8053, 0x8053, 0x8053, 0x8053, 
+    0x8053, 0x8053, 0x8053, 0x8053, 0x8053, 0x8053, 0x8054, 0x8054, 
+    0x8054, 0x8054, 0x8054, 0x8054, 0x8054, 0x8054, 0x8054, 0x8054, 
+    0x8054, 0x8055, 0x8055, 0x8055, 0x8055, 0x8055, 0x8056, 0x8056, 
+    0x8056, 0x8056, 0x8056, 0x8056, 0x8057, 0x8057, 0x8057, 0x8057, 
+    0x8057, 0x8058, 0x8058, 0x8058, 0x8058, 0x8058, 0x8058, 0x8059, 
+    0x8059, 0x8059, 0x8059, 0x8059, 0x805a, 0x805a, 0x805a, 0x805a, 
+    0x805a, 0x805b, 0x805b, 0x805b, 0x805b, 0x805b, 0x805b, 0x805c, 
+    0x805c, 0x805c, 0x805c, 0x805c, 0x805d, 0x805d, 0x805d, 0x805d, 
+    0x805d, 0x805e, 0x805e, 0x805e, 0x805e, 0x805e, 0x805f, 0x805f, 
+    0x805f, 0x805f, 0x805f, 0x8060, 0x8060, 0x8060, 0x8060, 0x8060, 
+    0x8060, 0x8061, 0x8061, 0x8061, 0x8061, 0x8061, 0x8062, 0x8062, 
+    0x8062, 0x8062, 0x8062, 0x8063, 0x8063, 0x8063, 0x8063, 0x8063, 
+    0x8064, 0x8064, 0x8064, 0x8064, 0x8064, 0x8065, 0x8065, 0x8065, 
+    0x8065, 0x8065, 0x8066, 0x8066, 0x8066, 0x8066, 0x8066, 0x8067, 
+    0x8067, 0x8067, 0x8067, 0x8067, 0x8068, 0x8068, 0x8068, 0x8068, 
+    0x8068, 0x8069, 0x8069, 0x8069, 0x8069, 0x8069, 0x806a, 0x806a, 
+    0x806a, 0x806a, 0x806b, 0x806b, 0x806b, 0x806b, 0x806b, 0x806c, 
+    0x806c, 0x806c, 0x806c, 0x806c, 0x806d, 0x806d, 0x806d, 0x806d, 
+    0x806d, 0x806e, 0x806e, 0x806e, 0x806e, 0x806e, 0x806f, 0x806f, 
+    0x806f, 0x806f, 0x8070, 0x8070, 0x8070, 0x8070, 0x8070, 0x8071, 
+    0x8071, 0x8071, 0x8071, 0x8071, 0x8072, 0x8072, 0x8072, 0x8072, 
+    0x8073, 0x8073, 0x8073, 0x8073, 0x8073, 0x8074, 0x8074, 0x8074, 
+    0x8074, 0x8074, 0x8075, 0x8075, 0x8075, 0x8075, 0x8076, 0x8076, 
+    0x8076, 0x8076, 0x8076, 0x8077, 0x8077, 0x8077, 0x8077, 0x8077, 
+    0x8078, 0x8078, 0x8078, 0x8078, 0x8079, 0x8079, 0x8079, 0x8079, 
+    0x8079, 0x807a, 0x807a, 0x807a, 0x807a, 0x807b, 0x807b, 0x807b, 
+    0x807b, 0x807b, 0x807c, 0x807c, 0x807c, 0x807c, 0x807d, 0x807d, 
+    0x807d, 0x807d, 0x807d, 0x807e, 0x807e, 0x807e, 0x807e, 0x807f, 
+    0x807f, 0x807f, 0x807f, 0x8080, 0x8080, 0x8080, 0x8080, 0x8080, 
+    0x8081, 0x8081, 0x8081, 0x8081, 0x8082, 0x8082, 0x8082, 0x8082, 
+    0x8082, 0x8083, 0x8083, 0x8083, 0x8083, 0x8084, 0x8084, 0x8084, 
+    0x8084, 0x8085, 0x8085, 0x8085, 0x8085, 0x8086, 0x8086, 0x8086, 
+    0x8086, 0x8086, 0x8087, 0x8087, 0x8087, 0x8087, 0x8088, 0x8088, 
+    0x8088, 0x8088, 0x8089, 0x8089, 0x8089, 0x8089, 0x8089, 0x808a, 
+    0x808a, 0x808a, 0x808a, 0x808b, 0x808b, 0x808b, 0x808b, 0x808c, 
+    0x808c, 0x808c, 0x808c, 0x808d, 0x808d, 0x808d, 0x808d, 0x808e, 
+    0x808e, 0x808e, 0x808e, 0x808f, 0x808f, 0x808f, 0x808f, 0x808f, 
+    0x8090, 0x8090, 0x8090, 0x8090, 0x8091, 0x8091, 0x8091, 0x8091, 
+    0x8092, 0x8092, 0x8092, 0x8092, 0x8093, 0x8093, 0x8093, 0x8093, 
+    0x8094, 0x8094, 0x8094, 0x8094, 0x8095, 0x8095, 0x8095, 0x8095, 
+    0x8096, 0x8096, 0x8096, 0x8096, 0x8097, 0x8097, 0x8097, 0x8097, 
+    0x8098, 0x8098, 0x8098, 0x8098, 0x8099, 0x8099, 0x8099, 0x8099, 
+    0x809a, 0x809a, 0x809a, 0x809a, 0x809b, 0x809b, 0x809b, 0x809b, 
+    0x809c, 0x809c, 0x809c, 0x809c, 0x809d, 0x809d, 0x809d, 0x809d, 
+    0x809e, 0x809e, 0x809e, 0x809e, 0x809f, 0x809f, 0x809f, 0x809f, 
+    0x80a0, 0x80a0, 0x80a0, 0x80a0, 0x80a1, 0x80a1, 0x80a1, 0x80a2, 
+    0x80a2, 0x80a2, 0x80a2, 0x80a3, 0x80a3, 0x80a3, 0x80a3, 0x80a4, 
+    0x80a4, 0x80a4, 0x80a4, 0x80a5, 0x80a5, 0x80a5, 0x80a5, 0x80a6, 
+    0x80a6, 0x80a6, 0x80a6, 0x80a7, 0x80a7, 0x80a7, 0x80a8, 0x80a8, 
+    0x80a8, 0x80a8, 0x80a9, 0x80a9, 0x80a9, 0x80a9, 0x80aa, 0x80aa, 
+    0x80aa, 0x80aa, 0x80ab, 0x80ab, 0x80ab, 0x80ab, 0x80ac, 0x80ac, 
+    0x80ac, 0x80ad, 0x80ad, 0x80ad, 0x80ad, 0x80ae, 0x80ae, 0x80ae, 
+    0x80ae, 0x80af, 0x80af, 0x80af, 0x80b0, 0x80b0, 0x80b0, 0x80b0, 
+    0x80b1, 0x80b1, 0x80b1, 0x80b1, 0x80b2, 0x80b2, 0x80b2, 0x80b3, 
+    0x80b3, 0x80b3, 0x80b3, 0x80b4, 0x80b4, 0x80b4, 0x80b4, 0x80b5, 
+    0x80b5, 0x80b5, 0x80b6, 0x80b6, 0x80b6, 0x80b6, 0x80b7, 0x80b7, 
+    0x80b7, 0x80b7, 0x80b8, 0x80b8, 0x80b8, 0x80b9, 0x80b9, 0x80b9, 
+    0x80b9, 0x80ba, 0x80ba, 0x80ba, 0x80bb, 0x80bb, 0x80bb, 0x80bb, 
+    0x80bc, 0x80bc, 0x80bc, 0x80bc, 0x80bd, 0x80bd, 0x80bd, 0x80be, 
+    0x80be, 0x80be, 0x80be, 0x80bf, 0x80bf, 0x80bf, 0x80c0, 0x80c0, 
+    0x80c0, 0x80c0, 0x80c1, 0x80c1, 0x80c1, 0x80c2, 0x80c2, 0x80c2, 
+    0x80c2, 0x80c3, 0x80c3, 0x80c3, 0x80c4, 0x80c4, 0x80c4, 0x80c4, 
+    0x80c5, 0x80c5, 0x80c5, 0x80c6, 0x80c6, 0x80c6, 0x80c6, 0x80c7, 
+    0x80c7, 0x80c7, 0x80c8, 0x80c8, 0x80c8, 0x80c8, 0x80c9, 0x80c9, 
+    0x80c9, 0x80ca, 0x80ca, 0x80ca, 0x80cb, 0x80cb, 0x80cb, 0x80cb, 
+    0x80cc, 0x80cc, 0x80cc, 0x80cd, 0x80cd, 0x80cd, 0x80cd, 0x80ce, 
+    0x80ce, 0x80ce, 0x80cf, 0x80cf, 0x80cf, 0x80d0, 0x80d0, 0x80d0, 
+    0x80d0, 0x80d1, 0x80d1, 0x80d1, 0x80d2, 0x80d2, 0x80d2, 0x80d3, 
+    0x80d3, 0x80d3, 0x80d3, 0x80d4, 0x80d4, 0x80d4, 0x80d5, 0x80d5, 
+    0x80d5, 0x80d6, 0x80d6, 0x80d6, 0x80d6, 0x80d7, 0x80d7, 0x80d7, 
+    0x80d8, 0x80d8, 0x80d8, 0x80d9, 0x80d9, 0x80d9, 0x80d9, 0x80da, 
+    0x80da, 0x80da, 0x80db, 0x80db, 0x80db, 0x80dc, 0x80dc, 0x80dc, 
+    0x80dc, 0x80dd, 0x80dd, 0x80dd, 0x80de, 0x80de, 0x80de, 0x80df, 
+    0x80df, 0x80df, 0x80e0, 0x80e0, 0x80e0, 0x80e0, 0x80e1, 0x80e1, 
+    0x80e1, 0x80e2, 0x80e2, 0x80e2, 0x80e3, 0x80e3, 0x80e3, 0x80e4, 
+    0x80e4, 0x80e4, 0x80e5, 0x80e5, 0x80e5, 0x80e5, 0x80e6, 0x80e6, 
+    0x80e6, 0x80e7, 0x80e7, 0x80e7, 0x80e8, 0x80e8, 0x80e8, 0x80e9, 
+    0x80e9, 0x80e9, 0x80ea, 0x80ea, 0x80ea, 0x80eb, 0x80eb, 0x80eb, 
+    0x80eb, 0x80ec, 0x80ec, 0x80ec, 0x80ed, 0x80ed, 0x80ed, 0x80ee, 
+    0x80ee, 0x80ee, 0x80ef, 0x80ef, 0x80ef, 0x80f0, 0x80f0, 0x80f0, 
+    0x80f1, 0x80f1, 0x80f1, 0x80f2, 0x80f2, 0x80f2, 0x80f2, 0x80f3, 
+    0x80f3, 0x80f3, 0x80f4, 0x80f4, 0x80f4, 0x80f5, 0x80f5, 0x80f5, 
+    0x80f6, 0x80f6, 0x80f6, 0x80f7, 0x80f7, 0x80f7, 0x80f8, 0x80f8, 
+    0x80f8, 0x80f9, 0x80f9, 0x80f9, 0x80fa, 0x80fa, 0x80fa, 0x80fb, 
+    0x80fb, 0x80fb, 0x80fc, 0x80fc, 0x80fc, 0x80fd, 0x80fd, 0x80fd, 
+    0x80fe, 0x80fe, 0x80fe, 0x80ff, 0x80ff, 0x80ff, 0x8100, 0x8100, 
+    0x8100, 0x8101, 0x8101, 0x8101, 0x8102, 0x8102, 0x8102, 0x8103, 
+    0x8103, 0x8103, 0x8104, 0x8104, 0x8104, 0x8105, 0x8105, 0x8105, 
+    0x8106, 0x8106, 0x8106, 0x8107, 0x8107, 0x8107, 0x8108, 0x8108, 
+    0x8108, 0x8109, 0x8109, 0x8109, 0x810a, 0x810a, 0x810a, 0x810b, 
+    0x810b, 0x810b, 0x810c, 0x810c, 0x810c, 0x810d, 0x810d, 0x810d, 
+    0x810e, 0x810e, 0x810e, 0x810f, 0x810f, 0x810f, 0x8110, 0x8110, 
+    0x8110, 0x8111, 0x8111, 0x8112, 0x8112, 0x8112, 0x8113, 0x8113, 
+    0x8113, 0x8114, 0x8114, 0x8114, 0x8115, 0x8115, 0x8115, 0x8116, 
+    0x8116, 0x8116, 0x8117, 0x8117, 0x8117, 0x8118, 0x8118, 0x8118, 
+    0x8119, 0x8119, 0x8119, 0x811a, 0x811a, 0x811b, 0x811b, 0x811b, 
+    0x811c, 0x811c, 0x811c, 0x811d, 0x811d, 0x811d, 0x811e, 0x811e, 
+    0x811e, 0x811f, 0x811f, 0x811f, 0x8120, 0x8120, 0x8121, 0x8121, 
+    0x8121, 0x8122, 0x8122, 0x8122, 0x8123, 0x8123, 0x8123, 0x8124, 
+    0x8124, 0x8124, 0x8125, 0x8125, 0x8126, 0x8126, 0x8126, 0x8127, 
+    0x8127, 0x8127, 0x8128, 0x8128, 0x8128, 0x8129, 0x8129, 0x8129, 
+    0x812a, 0x812a, 0x812b, 0x812b, 0x812b, 0x812c, 0x812c, 0x812c, 
+    0x812d, 0x812d, 0x812d, 0x812e, 0x812e, 0x812f, 0x812f, 0x812f, 
+    0x8130, 0x8130, 0x8130, 0x8131, 0x8131, 0x8131, 0x8132, 0x8132, 
+    0x8133, 0x8133, 0x8133, 0x8134, 0x8134, 0x8134, 0x8135, 0x8135, 
+    0x8136, 0x8136, 0x8136, 0x8137, 0x8137, 0x8137, 0x8138, 0x8138, 
+    0x8138, 0x8139, 0x8139, 0x813a, 0x813a, 0x813a, 0x813b, 0x813b, 
+    0x813b, 0x813c, 0x813c, 0x813d, 0x813d, 0x813d, 0x813e, 0x813e, 
+    0x813e, 0x813f, 0x813f, 0x8140, 0x8140, 0x8140, 0x8141, 0x8141, 
+    0x8141, 0x8142, 0x8142, 0x8143, 0x8143, 0x8143, 0x8144, 0x8144, 
+    0x8144, 0x8145, 0x8145, 0x8146, 0x8146, 0x8146, 0x8147, 0x8147, 
+    0x8147, 0x8148, 0x8148, 0x8149, 0x8149, 0x8149, 0x814a, 0x814a, 
+    0x814b, 0x814b, 0x814b, 0x814c, 0x814c, 0x814c, 0x814d, 0x814d, 
+    0x814e, 0x814e, 0x814e, 0x814f, 0x814f, 0x8150, 0x8150, 0x8150, 
+    0x8151, 0x8151, 0x8151, 0x8152, 0x8152, 0x8153, 0x8153, 0x8153, 
+    0x8154, 0x8154, 0x8155, 0x8155, 0x8155, 0x8156, 0x8156, 0x8156, 
+    0x8157, 0x8157, 0x8158, 0x8158, 0x8158, 0x8159, 0x8159, 0x815a, 
+    0x815a, 0x815a, 0x815b, 0x815b, 0x815c, 0x815c, 0x815c, 0x815d, 
+    0x815d, 0x815e, 0x815e, 0x815e, 0x815f, 0x815f, 0x815f, 0x8160, 
+    0x8160, 0x8161, 0x8161, 0x8161, 0x8162, 0x8162, 0x8163, 0x8163, 
+    0x8163, 0x8164, 0x8164, 0x8165, 0x8165, 0x8165, 0x8166, 0x8166, 
+    0x8167, 0x8167, 0x8167, 0x8168, 0x8168, 0x8169, 0x8169, 0x8169, 
+    0x816a, 0x816a, 0x816b, 0x816b, 0x816b, 0x816c, 0x816c, 0x816d, 
+    0x816d, 0x816d, 0x816e, 0x816e, 0x816f, 0x816f, 0x816f, 0x8170, 
+    0x8170, 0x8171, 0x8171, 0x8172, 0x8172, 0x8172, 0x8173, 0x8173, 
+    0x8174, 0x8174, 0x8174, 0x8175, 0x8175, 0x8176, 0x8176, 0x8176, 
+    0x8177, 0x8177, 0x8178, 0x8178, 0x8178, 0x8179, 0x8179, 0x817a, 
+    0x817a, 0x817b, 0x817b, 0x817b, 0x817c, 0x817c, 0x817d, 0x817d, 
+    0x817d, 0x817e, 0x817e, 0x817f, 0x817f, 0x817f, 0x8180, 0x8180, 
+    0x8181, 0x8181, 0x8182, 0x8182, 0x8182, 0x8183, 0x8183, 0x8184, 
+    0x8184, 0x8185, 0x8186, 0x8187, 0x8187, 0x8188, 0x8189, 0x818a, 
+    0x818b, 0x818c, 0x818c, 0x818d, 0x818e, 0x818f, 0x8190, 0x8191, 
+    0x8191, 0x8192, 0x8193, 0x8194, 0x8195, 0x8196, 0x8197, 0x8197, 
+    0x8198, 0x8199, 0x819a, 0x819b, 0x819c, 0x819d, 0x819d, 0x819e, 
+    0x819f, 0x81a0, 0x81a1, 0x81a2, 0x81a3, 0x81a4, 0x81a4, 0x81a5, 
+    0x81a6, 0x81a7, 0x81a8, 0x81a9, 0x81aa, 0x81ab, 0x81ab, 0x81ac, 
+    0x81ad, 0x81ae, 0x81af, 0x81b0, 0x81b1, 0x81b2, 0x81b2, 0x81b3, 
+    0x81b4, 0x81b5, 0x81b6, 0x81b7, 0x81b8, 0x81b9, 0x81ba, 0x81ba, 
+    0x81bb, 0x81bc, 0x81bd, 0x81be, 0x81bf, 0x81c0, 0x81c1, 0x81c2, 
+    0x81c3, 0x81c3, 0x81c4, 0x81c5, 0x81c6, 0x81c7, 0x81c8, 0x81c9, 
+    0x81ca, 0x81cb, 0x81cc, 0x81cd, 0x81ce, 0x81ce, 0x81cf, 0x81d0, 
+    0x81d1, 0x81d2, 0x81d3, 0x81d4, 0x81d5, 0x81d6, 0x81d7, 0x81d8, 
+    0x81d9, 0x81da, 0x81da, 0x81db, 0x81dc, 0x81dd, 0x81de, 0x81df, 
+    0x81e0, 0x81e1, 0x81e2, 0x81e3, 0x81e4, 0x81e5, 0x81e6, 0x81e7, 
+    0x81e8, 0x81e9, 0x81e9, 0x81ea, 0x81eb, 0x81ec, 0x81ed, 0x81ee, 
+    0x81ef, 0x81f0, 0x81f1, 0x81f2, 0x81f3, 0x81f4, 0x81f5, 0x81f6, 
+    0x81f7, 0x81f8, 0x81f9, 0x81fa, 0x81fb, 0x81fc, 0x81fd, 0x81fe, 
+    0x81ff, 0x81ff, 0x8200, 0x8201, 0x8202, 0x8203, 0x8204, 0x8205, 
+    0x8206, 0x8207, 0x8208, 0x8209, 0x820a, 0x820b, 0x820c, 0x820d, 
+    0x820e, 0x820f, 0x8210, 0x8211, 0x8212, 0x8213, 0x8214, 0x8215, 
+    0x8216, 0x8217, 0x8218, 0x8219, 0x821a, 0x821b, 0x821c, 0x821d, 
+    0x821e, 0x821f, 0x8220, 0x8221, 0x8222, 0x8223, 0x8224, 0x8225, 
+    0x8226, 0x8227, 0x8228, 0x8229, 0x822a, 0x822b, 0x822c, 0x822d, 
+    0x822e, 0x822f, 0x8230, 0x8231, 0x8232, 0x8233, 0x8234, 0x8235, 
+    0x8236, 0x8237, 0x8238, 0x8239, 0x823a, 0x823b, 0x823c, 0x823e, 
+    0x823f, 0x8240, 0x8241, 0x8242, 0x8243, 0x8244, 0x8245, 0x8246, 
+    0x8247, 0x8248, 0x8249, 0x824a, 0x824b, 0x824c, 0x824d, 0x824e, 
+    0x824f, 0x8250, 0x8251, 0x8252, 0x8253, 0x8254, 0x8255, 0x8257, 
+    0x8258, 0x8259, 0x825a, 0x825b, 0x825c, 0x825d, 0x825e, 0x825f, 
+    0x8260, 0x8261, 0x8262, 0x8263, 0x8264, 0x8265, 0x8267, 0x8268, 
+    0x8269, 0x826a, 0x826b, 0x826c, 0x826d, 0x826e, 0x826f, 0x8270, 
+    0x8271, 0x8272, 0x8273, 0x8275, 0x8276, 0x8277, 0x8278, 0x8279, 
+    0x827a, 0x827b, 0x827c, 0x827d, 0x827e, 0x827f, 0x8281, 0x8282, 
+    0x8283, 0x8284, 0x8285, 0x8286, 0x8287, 0x8288, 0x8289, 0x828a, 
+    0x828c, 0x828d, 0x828e, 0x828f, 0x8290, 0x8291, 0x8292, 0x8293, 
+    0x8294, 0x8296, 0x8297, 0x8298, 0x8299, 0x829a, 0x829b, 0x829c, 
+    0x829d, 0x829e, 0x82a0, 0x82a1, 0x82a2, 0x82a3, 0x82a4, 0x82a5, 
+    0x82a6, 0x82a7, 0x82a9, 0x82aa, 0x82ab, 0x82ac, 0x82ad, 0x82ae, 
+    0x82af, 0x82b1, 0x82b2, 0x82b3, 0x82b4, 0x82b5, 0x82b6, 0x82b7, 
+    0x82b9, 0x82ba, 0x82bb, 0x82bc, 0x82bd, 0x82be, 0x82bf, 0x82c1, 
+    0x82c2, 0x82c3, 0x82c4, 0x82c5, 0x82c6, 0x82c8, 0x82c9, 0x82ca, 
+    0x82cb, 0x82cc, 0x82cd, 0x82cf, 0x82d0, 0x82d1, 0x82d2, 0x82d3, 
+    0x82d4, 0x82d6, 0x82d7, 0x82d8, 0x82d9, 0x82da, 0x82db, 0x82dd, 
+    0x82de, 0x82df, 0x82e0, 0x82e1, 0x82e3, 0x82e4, 0x82e5, 0x82e6, 
+    0x82e7, 0x82e8, 0x82ea, 0x82eb, 0x82ec, 0x82ed, 0x82ee, 0x82f0, 
+    0x82f1, 0x82f2, 0x82f3, 0x82f4, 0x82f6, 0x82f7, 0x82f8, 0x82f9, 
+    0x82fa, 0x82fc, 0x82fd, 0x82fe, 0x82ff, 0x8300, 0x8302, 0x8303, 
+    0x8304, 0x8305, 0x8307, 0x8308, 0x8309, 0x830a, 0x830b, 0x830d, 
+    0x830e, 0x830f, 0x8310, 0x8312, 0x8313, 0x8314, 0x8315, 0x8316, 
+    0x8318, 0x8319, 0x831a, 0x831b, 0x831d, 0x831e, 0x831f, 0x8320, 
+    0x8322, 0x8323, 0x8324, 0x8325, 0x8326, 0x8328, 0x8329, 0x832a, 
+    0x832b, 0x832d, 0x832e, 0x832f, 0x8330, 0x8332, 0x8333, 0x8334, 
+    0x8335, 0x8337, 0x8338, 0x8339, 0x833b, 0x833c, 0x833d, 0x833e, 
+    0x8340, 0x8341, 0x8342, 0x8343, 0x8345, 0x8346, 0x8347, 0x8348, 
+    0x834a, 0x834b, 0x834c, 0x834e, 0x834f, 0x8350, 0x8351, 0x8353, 
+    0x8354, 0x8355, 0x8356, 0x8358, 0x8359, 0x835a, 0x835c, 0x835d, 
+    0x835e, 0x835f, 0x8361, 0x8362, 0x8363, 0x8365, 0x8366, 0x8367, 
+    0x8369, 0x836a, 0x836b, 0x836c, 0x836e, 0x836f, 0x8370, 0x8372, 
+    0x8373, 0x8374, 0x8376, 0x8377, 0x8378, 0x8379, 0x837b, 0x837c, 
+    0x837d, 0x837f, 0x8380, 0x8381, 0x8383, 0x8384, 0x8385, 0x8387, 
+    0x8388, 0x8389, 0x838b, 0x838c, 0x838d, 0x838f, 0x8390, 0x8391, 
+    0x8393, 0x8394, 0x8395, 0x8397, 0x8398, 0x8399, 0x839b, 0x839c, 
+    0x839d, 0x839f, 0x83a0, 0x83a1, 0x83a3, 0x83a4, 0x83a5, 0x83a7, 
+    0x83a8, 0x83a9, 0x83ab, 0x83ac, 0x83ad, 0x83af, 0x83b0, 0x83b1, 
+    0x83b3, 0x83b4, 0x83b6, 0x83b7, 0x83b8, 0x83ba, 0x83bb, 0x83bc, 
+    0x83be, 0x83bf, 0x83c0, 0x83c2, 0x83c3, 0x83c5, 0x83c6, 0x83c7, 
+    0x83c9, 0x83ca, 0x83cb, 0x83cd, 0x83ce, 0x83d0, 0x83d1, 0x83d2, 
+    0x83d4, 0x83d5, 0x83d6, 0x83d8, 0x83d9, 0x83db, 0x83dc, 0x83dd, 
+    0x83df, 0x83e0, 0x83e2, 0x83e3, 0x83e4, 0x83e6, 0x83e7, 0x83e8, 
+    0x83ea, 0x83eb, 0x83ed, 0x83ee, 0x83ef, 0x83f1, 0x83f2, 0x83f4, 
+    0x83f5, 0x83f7, 0x83f8, 0x83f9, 0x83fb, 0x83fc, 0x83fe, 0x83ff, 
+    0x8400, 0x8402, 0x8403, 0x8405, 0x8406, 0x8407, 0x8409, 0x840a, 
+    0x840c, 0x840d, 0x840f, 0x8410, 0x8411, 0x8413, 0x8414, 0x8416, 
+    0x8417, 0x8419, 0x841a, 0x841b, 0x841d, 0x841e, 0x8420, 0x8421, 
+    0x8423, 0x8424, 0x8426, 0x8427, 0x8428, 0x842a, 0x842b, 0x842d, 
+    0x842e, 0x8430, 0x8431, 0x8433, 0x8434, 0x8436, 0x8437, 0x8438, 
+    0x843a, 0x843b, 0x843d, 0x843e, 0x8440, 0x8441, 0x8443, 0x8444, 
+    0x8446, 0x8447, 0x8449, 0x844a, 0x844b, 0x844d, 0x844e, 0x8450, 
+    0x8451, 0x8453, 0x8454, 0x8456, 0x8457, 0x8459, 0x845a, 0x845c, 
+    0x845d, 0x845f, 0x8460, 0x8462, 0x8463, 0x8465, 0x8466, 0x8468, 
+    0x8469, 0x846b, 0x846c, 0x846e, 0x846f, 0x8471, 0x8472, 0x8474, 
+    0x8475, 0x8477, 0x8478, 0x847a, 0x847b, 0x847d, 0x847e, 0x8480, 
+    0x8481, 0x8483, 0x8484, 0x8486, 0x8487, 0x8489, 0x848a, 0x848c, 
+    0x848d, 0x848f, 0x8490, 0x8492, 0x8493, 0x8495, 0x8496, 0x8498, 
+    0x8499, 0x849b, 0x849c, 0x849e, 0x84a0, 0x84a1, 0x84a3, 0x84a4, 
+    0x84a6, 0x84a7, 0x84a9, 0x84aa, 0x84ac, 0x84ad, 0x84af, 0x84b0, 
+    0x84b2, 0x84b4, 0x84b5, 0x84b7, 0x84b8, 0x84ba, 0x84bb, 0x84bd, 
+    0x84be, 0x84c0, 0x84c2, 0x84c3, 0x84c5, 0x84c6, 0x84c8, 0x84c9, 
+    0x84cb, 0x84cc, 0x84ce, 0x84d0, 0x84d1, 0x84d3, 0x84d4, 0x84d6, 
+    0x84d7, 0x84d9, 0x84db, 0x84dc, 0x84de, 0x84df, 0x84e1, 0x84e2, 
+    0x84e4, 0x84e6, 0x84e7, 0x84e9, 0x84ea, 0x84ec, 0x84ed, 0x84ef, 
+    0x84f1, 0x84f2, 0x84f4, 0x84f5, 0x84f7, 0x84f9, 0x84fa, 0x84fc, 
+    0x84fd, 0x84ff, 0x8501, 0x8502, 0x8504, 0x8505, 0x8507, 0x8509, 
+    0x850a, 0x850c, 0x850d, 0x850f, 0x8511, 0x8512, 0x8514, 0x8515, 
+    0x8517, 0x8519, 0x851a, 0x851c, 0x851e, 0x851f, 0x8521, 0x8522, 
+    0x8524, 0x8526, 0x8527, 0x8529, 0x852b, 0x852c, 0x852e, 0x852f, 
+    0x8531, 0x8533, 0x8534, 0x8536, 0x8538, 0x8539, 0x853b, 0x853c, 
+    0x853e, 0x8540, 0x8541, 0x8543, 0x8545, 0x8546, 0x8548, 0x854a, 
+    0x854b, 0x854d, 0x854f, 0x8550, 0x8552, 0x8554, 0x8555, 0x8557, 
+    0x8559, 0x855a, 0x855c, 0x855e, 0x855f, 0x8561, 0x8562, 0x8564, 
+    0x8566, 0x8567, 0x8569, 0x856b, 0x856c, 0x856e, 0x8570, 0x8572, 
+    0x8573, 0x8575, 0x8577, 0x8578, 0x857a, 0x857c, 0x857d, 0x857f, 
+    0x8581, 0x8582, 0x8584, 0x8586, 0x8587, 0x8589, 0x858b, 0x858c, 
+    0x858e, 0x8590, 0x8592, 0x8593, 0x8595, 0x8597, 0x8598, 0x859a, 
+    0x859c, 0x859d, 0x859f, 0x85a1, 0x85a3, 0x85a4, 0x85a6, 0x85a8, 
+    0x85a9, 0x85ab, 0x85ad, 0x85af, 0x85b0, 0x85b2, 0x85b4, 0x85b5, 
+    0x85b7, 0x85b9, 0x85bb, 0x85bc, 0x85be, 0x85c0, 0x85c1, 0x85c3, 
+    0x85c5, 0x85c7, 0x85c8, 0x85ca, 0x85cc, 0x85ce, 0x85cf, 0x85d1, 
+    0x85d3, 0x85d4, 0x85d6, 0x85d8, 0x85da, 0x85db, 0x85dd, 0x85df, 
+    0x85e1, 0x85e2, 0x85e4, 0x85e6, 0x85e8, 0x85e9, 0x85eb, 0x85ed, 
+    0x85ef, 0x85f0, 0x85f2, 0x85f4, 0x85f6, 0x85f7, 0x85f9, 0x85fb, 
+    0x85fd, 0x85ff, 0x8600, 0x8602, 0x8604, 0x8606, 0x8607, 0x8609, 
+    0x860b, 0x860d, 0x860e, 0x8610, 0x8612, 0x8614, 0x8616, 0x8617, 
+    0x8619, 0x861b, 0x861d, 0x861e, 0x8620, 0x8622, 0x8624, 0x8626, 
+    0x8627, 0x8629, 0x862b, 0x862d, 0x862f, 0x8630, 0x8632, 0x8634, 
+    0x8636, 0x8638, 0x8639, 0x863b, 0x863d, 0x863f, 0x8641, 0x8642, 
+    0x8644, 0x8646, 0x8648, 0x864a, 0x864b, 0x864d, 0x864f, 0x8651, 
+    0x8653, 0x8654, 0x8656, 0x8658, 0x865a, 0x865c, 0x865e, 0x865f, 
+    0x8661, 0x8663, 0x8665, 0x8667, 0x8669, 0x866a, 0x866c, 0x866e, 
+    0x8670, 0x8672, 0x8674, 0x8675, 0x8677, 0x8679, 0x867b, 0x867d, 
+    0x867f, 0x8680, 0x8682, 0x8684, 0x8686, 0x8688, 0x868a, 0x868c, 
+    0x868d, 0x868f, 0x8691, 0x8693, 0x8695, 0x8697, 0x8699, 0x869a, 
+    0x869c, 0x869e, 0x86a0, 0x86a2, 0x86a4, 0x86a6, 0x86a7, 0x86a9, 
+    0x86ab, 0x86ad, 0x86af, 0x86b1, 0x86b3, 0x86b5, 0x86b6, 0x86b8, 
+    0x86ba, 0x86bc, 0x86be, 0x86c0, 0x86c2, 0x86c4, 0x86c5, 0x86c7, 
+    0x86c9, 0x86cb, 0x86cd, 0x86cf, 0x86d1, 0x86d3, 0x86d5, 0x86d6, 
+    0x86d8, 0x86da, 0x86dc, 0x86de, 0x86e0, 0x86e2, 0x86e4, 0x86e6, 
+    0x86e8, 0x86ea, 0x86eb, 0x86ed, 0x86ef, 0x86f1, 0x86f3, 0x86f5, 
+    0x86f7, 0x86fb, 0x86ff, 0x8702, 0x8706, 0x870a, 0x870e, 0x8712, 
+    0x8716, 0x871a, 0x871d, 0x8721, 0x8725, 0x8729, 0x872d, 0x8731, 
+    0x8735, 0x8739, 0x873d, 0x8740, 0x8744, 0x8748, 0x874c, 0x8750, 
+    0x8754, 0x8758, 0x875c, 0x8760, 0x8764, 0x8768, 0x876c, 0x8770, 
+    0x8774, 0x8778, 0x877c, 0x8780, 0x8784, 0x8788, 0x878c, 0x8790, 
+    0x8794, 0x8798, 0x879c, 0x87a0, 0x87a4, 0x87a8, 0x87ac, 0x87b0, 
+    0x87b4, 0x87b8, 0x87bc, 0x87c0, 0x87c4, 0x87c8, 0x87cc, 0x87d0, 
+    0x87d4, 0x87d9, 0x87dd, 0x87e1, 0x87e5, 0x87e9, 0x87ed, 0x87f1, 
+    0x87f5, 0x87f9, 0x87fe, 0x8801, 0x8803, 0x8805, 0x8807, 0x8809, 
+    0x880b, 0x880d, 0x880f, 0x8811, 0x8814, 0x8816, 0x8818, 0x881a, 
+    0x881c, 0x881e, 0x8820, 0x8822, 0x8824, 0x8826, 0x8828, 0x882b, 
+    0x882d, 0x882f, 0x8831, 0x8833, 0x8835, 0x8837, 0x8839, 0x883c, 
+    0x883e, 0x8840, 0x8842, 0x8844, 0x8846, 0x8848, 0x884b, 0x884d, 
+    0x884f, 0x8851, 0x8853, 0x8855, 0x8857, 0x885a, 0x885c, 0x885e, 
+    0x8860, 0x8862, 0x8864, 0x8867, 0x8869, 0x886b, 0x886d, 0x886f, 
+    0x8872, 0x8874, 0x8876, 0x8878, 0x887a, 0x887d, 0x887f, 0x8881, 
+    0x8883, 0x8885, 0x8888, 0x888a, 0x888c, 0x888e, 0x8890, 0x8893, 
+    0x8895, 0x8897, 0x8899, 0x889c, 0x889e, 0x88a0, 0x88a2, 0x88a4, 
+    0x88a7, 0x88a9, 0x88ab, 0x88ad, 0x88b0, 0x88b2, 0x88b4, 0x88b6, 
+    0x88b9, 0x88bb, 0x88bd, 0x88c0, 0x88c2, 0x88c4, 0x88c6, 0x88c9, 
+    0x88cb, 0x88cd, 0x88cf, 0x88d2, 0x88d4, 0x88d6, 0x88d9, 0x88db, 
+    0x88dd, 0x88e0, 0x88e2, 0x88e4, 0x88e6, 0x88e9, 0x88eb, 0x88ed, 
+    0x88f0, 0x88f2, 0x88f4, 0x88f7, 0x88f9, 0x88fb, 0x88fe, 0x8900, 
+    0x8902, 0x8905, 0x8907, 0x8909, 0x890c, 0x890e, 0x8910, 0x8913, 
+    0x8915, 0x8917, 0x891a, 0x891c, 0x891e, 0x8921, 0x8923, 0x8926, 
+    0x8928, 0x892a, 0x892d, 0x892f, 0x8931, 0x8934, 0x8936, 0x8939, 
+    0x893b, 0x893d, 0x8940, 0x8942, 0x8945, 0x8947, 0x8949, 0x894c, 
+    0x894e, 0x8951, 0x8953, 0x8955, 0x8958, 0x895a, 0x895d, 0x895f, 
+    0x8962, 0x8964, 0x8966, 0x8969, 0x896b, 0x896e, 0x8970, 0x8973, 
+    0x8975, 0x8977, 0x897a, 0x897c, 0x897f, 0x8981, 0x8984, 0x8986, 
+    0x8989, 0x898b, 0x898e, 0x8990, 0x8993, 0x8995, 0x8998, 0x899a, 
+    0x899c, 0x899f, 0x89a1, 0x89a4, 0x89a6, 0x89a9, 0x89ab, 0x89ae, 
+    0x89b0, 0x89b3, 0x89b5, 0x89b8, 0x89ba, 0x89bd, 0x89c0, 0x89c2, 
+    0x89c5, 0x89c7, 0x89ca, 0x89cc, 0x89cf, 0x89d1, 0x89d4, 0x89d6, 
+    0x89d9, 0x89db, 0x89de, 0x89e0, 0x89e3, 0x89e6, 0x89e8, 0x89eb, 
+    0x89ed, 0x89f0, 0x89f2, 0x89f5, 0x89f7, 0x89fa, 0x89fd, 0x89ff, 
+    0x8a02, 0x8a04, 0x8a07, 0x8a0a, 0x8a0c, 0x8a0f, 0x8a11, 0x8a14, 
+    0x8a16, 0x8a19, 0x8a1c, 0x8a1e, 0x8a21, 0x8a23, 0x8a26, 0x8a29, 
+    0x8a2b, 0x8a2e, 0x8a31, 0x8a33, 0x8a36, 0x8a38, 0x8a3b, 0x8a3e, 
+    0x8a40, 0x8a43, 0x8a46, 0x8a48, 0x8a4b, 0x8a4e, 0x8a50, 0x8a53, 
+    0x8a55, 0x8a58, 0x8a5b, 0x8a5d, 0x8a60, 0x8a63, 0x8a65, 0x8a68, 
+    0x8a6b, 0x8a6d, 0x8a70, 0x8a73, 0x8a76, 0x8a78, 0x8a7b, 0x8a7e, 
+    0x8a80, 0x8a83, 0x8a86, 0x8a88, 0x8a8b, 0x8a8e, 0x8a90, 0x8a93, 
+    0x8a96, 0x8a99, 0x8a9b, 0x8a9e, 0x8aa1, 0x8aa3, 0x8aa6, 0x8aa9, 
+    0x8aac, 0x8aae, 0x8ab1, 0x8ab4, 0x8ab7, 0x8ab9, 0x8abc, 0x8abf, 
+    0x8ac2, 0x8ac4, 0x8ac7, 0x8aca, 0x8acd, 0x8acf, 0x8ad2, 0x8ad5, 
+    0x8ad8, 0x8ada, 0x8add, 0x8ae0, 0x8ae3, 0x8ae5, 0x8ae8, 0x8aeb, 
+    0x8aee, 0x8af1, 0x8af3, 0x8af6, 0x8af9, 0x8afc, 0x8aff, 0x8b01, 
+    0x8b04, 0x8b07, 0x8b0a, 0x8b0d, 0x8b0f, 0x8b12, 0x8b15, 0x8b18, 
+    0x8b1b, 0x8b1e, 0x8b20, 0x8b23, 0x8b26, 0x8b29, 0x8b2c, 0x8b2f, 
+    0x8b31, 0x8b34, 0x8b37, 0x8b3a, 0x8b3d, 0x8b40, 0x8b43, 0x8b45, 
+    0x8b48, 0x8b4b, 0x8b4e, 0x8b51, 0x8b54, 0x8b57, 0x8b59, 0x8b5c, 
+    0x8b5f, 0x8b62, 0x8b65, 0x8b68, 0x8b6b, 0x8b6e, 0x8b71, 0x8b74, 
+    0x8b76, 0x8b79, 0x8b7c, 0x8b7f, 0x8b82, 0x8b85, 0x8b88, 0x8b8b, 
+    0x8b8e, 0x8b91, 0x8b94, 0x8b96, 0x8b99, 0x8b9c, 0x8b9f, 0x8ba2, 
+    0x8ba5, 0x8ba8, 0x8bab, 0x8bae, 0x8bb1, 0x8bb4, 0x8bb7, 0x8bba, 
+    0x8bbd, 0x8bc0, 0x8bc3, 0x8bc6, 0x8bc9, 0x8bcc, 0x8bcf, 0x8bd2, 
+    0x8bd5, 0x8bd7, 0x8bda, 0x8bdd, 0x8be0, 0x8be3, 0x8be6, 0x8be9, 
+    0x8bec, 0x8bef, 0x8bf2, 0x8bf5, 0x8bf8, 0x8bfb, 0x8bfe, 0x8c01, 
+    0x8c02, 0x8c04, 0x8c05, 0x8c07, 0x8c08, 0x8c0a, 0x8c0b, 0x8c0d, 
+    0x8c0e, 0x8c10, 0x8c11, 0x8c13, 0x8c14, 0x8c16, 0x8c17, 0x8c19, 
+    0x8c1b, 0x8c1c, 0x8c1e, 0x8c1f, 0x8c21, 0x8c22, 0x8c24, 0x8c25, 
+    0x8c27, 0x8c28, 0x8c2a, 0x8c2b, 0x8c2d, 0x8c2f, 0x8c30, 0x8c32, 
+    0x8c33, 0x8c35, 0x8c36, 0x8c38, 0x8c39, 0x8c3b, 0x8c3c, 0x8c3e, 
+    0x8c40, 0x8c41, 0x8c43, 0x8c44, 0x8c46, 0x8c47, 0x8c49, 0x8c4b, 
+    0x8c4c, 0x8c4e, 0x8c4f, 0x8c51, 0x8c52, 0x8c54, 0x8c56, 0x8c57, 
+    0x8c59, 0x8c5a, 0x8c5c, 0x8c5d, 0x8c5f, 0x8c61, 0x8c62, 0x8c64, 
+    0x8c65, 0x8c67, 0x8c69, 0x8c6a, 0x8c6c, 0x8c6d, 0x8c6f, 0x8c70, 
+    0x8c72, 0x8c74, 0x8c75, 0x8c77, 0x8c78, 0x8c7a, 0x8c7c, 0x8c7d, 
+    0x8c7f, 0x8c80, 0x8c82, 0x8c84, 0x8c85, 0x8c87, 0x8c89, 0x8c8a, 
+    0x8c8c, 0x8c8d, 0x8c8f, 0x8c91, 0x8c92, 0x8c94, 0x8c95, 0x8c97, 
+    0x8c99, 0x8c9a, 0x8c9c, 0x8c9e, 0x8c9f, 0x8ca1, 0x8ca3, 0x8ca4, 
+    0x8ca6, 0x8ca7, 0x8ca9, 0x8cab, 0x8cac, 0x8cae, 0x8cb0, 0x8cb1, 
+    0x8cb3, 0x8cb5, 0x8cb6, 0x8cb8, 0x8cba, 0x8cbb, 0x8cbd, 0x8cbe, 
+    0x8cc0, 0x8cc2, 0x8cc3, 0x8cc5, 0x8cc7, 0x8cc8, 0x8cca, 0x8ccc, 
+    0x8ccd, 0x8ccf, 0x8cd1, 0x8cd2, 0x8cd4, 0x8cd6, 0x8cd7, 0x8cd9, 
+    0x8cdb, 0x8cdc, 0x8cde, 0x8ce0, 0x8ce1, 0x8ce3, 0x8ce5, 0x8ce7, 
+    0x8ce8, 0x8cea, 0x8cec, 0x8ced, 0x8cef, 0x8cf1, 0x8cf2, 0x8cf4, 
+    0x8cf6, 0x8cf7, 0x8cf9, 0x8cfb, 0x8cfd, 0x8cfe, 0x8d00, 0x8d02, 
+    0x8d03, 0x8d05, 0x8d07, 0x8d08, 0x8d0a, 0x8d0c, 0x8d0e, 0x8d0f, 
+    0x8d11, 0x8d13, 0x8d14, 0x8d16, 0x8d18, 0x8d1a, 0x8d1b, 0x8d1d, 
+    0x8d1f, 0x8d20, 0x8d22, 0x8d24, 0x8d26, 0x8d27, 0x8d29, 0x8d2b, 
+    0x8d2d, 0x8d2e, 0x8d30, 0x8d32, 0x8d34, 0x8d35, 0x8d37, 0x8d39, 
+    0x8d3b, 0x8d3c, 0x8d3e, 0x8d40, 0x8d42, 0x8d43, 0x8d45, 0x8d47, 
+    0x8d49, 0x8d4a, 0x8d4c, 0x8d4e, 0x8d50, 0x8d51, 0x8d53, 0x8d55, 
+    0x8d57, 0x8d58, 0x8d5a, 0x8d5c, 0x8d5e, 0x8d5f, 0x8d61, 0x8d63, 
+    0x8d65, 0x8d67, 0x8d68, 0x8d6a, 0x8d6c, 0x8d6e, 0x8d6f, 0x8d71, 
+    0x8d73, 0x8d75, 0x8d77, 0x8d78, 0x8d7a, 0x8d7c, 0x8d7e, 0x8d7f, 
+    0x8d81, 0x8d83, 0x8d85, 0x8d87, 0x8d88, 0x8d8a, 0x8d8c, 0x8d8e, 
+    0x8d90, 0x8d91, 0x8d93, 0x8d95, 0x8d97, 0x8d99, 0x8d9b, 0x8d9c, 
+    0x8d9e, 0x8da0, 0x8da2, 0x8da4, 0x8da5, 0x8da7, 0x8da9, 0x8dab, 
+    0x8dad, 0x8daf, 0x8db0, 0x8db2, 0x8db4, 0x8db6, 0x8db8, 0x8dba, 
+    0x8dbb, 0x8dbd, 0x8dbf, 0x8dc1, 0x8dc3, 0x8dc5, 0x8dc6, 0x8dc8, 
+    0x8dca, 0x8dcc, 0x8dce, 0x8dd0, 0x8dd1, 0x8dd3, 0x8dd5, 0x8dd7, 
+    0x8dd9, 0x8ddb, 0x8ddd, 0x8dde, 0x8de0, 0x8de2, 0x8de4, 0x8de6, 
+    0x8de8, 0x8dea, 0x8deb, 0x8ded, 0x8def, 0x8df1, 0x8df3, 0x8df5, 
+    0x8df7, 0x8df9, 0x8dfa, 0x8dfc, 0x8dfe, 0x8e00, 0x8e02, 0x8e04, 
+    0x8e06, 0x8e08, 0x8e09, 0x8e0b, 0x8e0d, 0x8e0f, 0x8e11, 0x8e13, 
+    0x8e15, 0x8e17, 0x8e19, 0x8e1b, 0x8e1c, 0x8e1e, 0x8e20, 0x8e22, 
+    0x8e24, 0x8e26, 0x8e28, 0x8e2a, 0x8e2c, 0x8e2e, 0x8e2f, 0x8e31, 
+    0x8e33, 0x8e35, 0x8e37, 0x8e39, 0x8e3b, 0x8e3d, 0x8e3f, 0x8e41, 
+    0x8e43, 0x8e45, 0x8e47, 0x8e48, 0x8e4a, 0x8e4c, 0x8e4e, 0x8e50, 
+    0x8e52, 0x8e54, 0x8e56, 0x8e58, 0x8e5a, 0x8e5c, 0x8e5e, 0x8e60, 
+    0x8e62, 0x8e64, 0x8e66, 0x8e67, 0x8e69, 0x8e6b, 0x8e6d, 0x8e6f, 
+    0x8e71, 0x8e73, 0x8e75, 0x8e77, 0x8e79, 0x8e7b, 0x8e7d, 0x8e7f, 
+    0x8e81, 0x8e83, 0x8e85, 0x8e87, 0x8e89, 0x8e8b, 0x8e8d, 0x8e8f, 
+    0x8e91, 0x8e93, 0x8e95, 0x8e97, 0x8e99, 0x8e9b, 0x8e9d, 0x8e9f, 
+    0x8ea0, 0x8ea2, 0x8ea4, 0x8ea6, 0x8ea8, 0x8eaa, 0x8eac, 0x8eae, 
+    0x8eb0, 0x8eb2, 0x8eb4, 0x8eb6, 0x8eb8, 0x8eba, 0x8ebc, 0x8ebe, 
+    0x8ec0, 0x8ec2, 0x8ec4, 0x8ec6, 0x8ec8, 0x8eca, 0x8ecc, 0x8ece, 
+    0x8ed1, 0x8ed3, 0x8ed5, 0x8ed7, 0x8ed9, 0x8edb, 0x8edd, 0x8edf, 
+    0x8ee1, 0x8ee3, 0x8ee5, 0x8ee7, 0x8ee9, 0x8eeb, 0x8eed, 0x8eef, 
+    0x8ef1, 0x8ef3, 0x8ef5, 0x8ef7, 0x8ef9, 0x8efb, 0x8efd, 0x8eff, 
+    0x8f01, 0x8f03, 0x8f05, 0x8f07, 0x8f09, 0x8f0b, 0x8f0e, 0x8f10, 
+    0x8f12, 0x8f14, 0x8f16, 0x8f18, 0x8f1a, 0x8f1c, 0x8f1e, 0x8f20, 
+    0x8f22, 0x8f24, 0x8f26, 0x8f28, 0x8f2a, 0x8f2c, 0x8f2f, 0x8f31, 
+    0x8f33, 0x8f35, 0x8f37, 0x8f39, 0x8f3b, 0x8f3d, 0x8f3f, 0x8f41, 
+    0x8f43, 0x8f45, 0x8f48, 0x8f4a, 0x8f4c, 0x8f4e, 0x8f50, 0x8f52, 
+    0x8f54, 0x8f56, 0x8f58, 0x8f5a, 0x8f5d, 0x8f5f, 0x8f61, 0x8f63, 
+    0x8f65, 0x8f67, 0x8f69, 0x8f6b, 0x8f6d, 0x8f6f, 0x8f72, 0x8f74, 
+    0x8f76, 0x8f78, 0x8f7a, 0x8f7c, 0x8f7e, 0x8f80, 0x8f83, 0x8f85, 
+    0x8f87, 0x8f89, 0x8f8b, 0x8f8d, 0x8f8f, 0x8f91, 0x8f94, 0x8f96, 
+    0x8f98, 0x8f9a, 0x8f9c, 0x8f9e, 0x8fa0, 0x8fa3, 0x8fa5, 0x8fa7, 
+    0x8fa9, 0x8fab, 0x8fad, 0x8faf, 0x8fb2, 0x8fb4, 0x8fb6, 0x8fb8, 
+    0x8fba, 0x8fbc, 0x8fbf, 0x8fc1, 0x8fc3, 0x8fc5, 0x8fc7, 0x8fc9, 
+    0x8fcc, 0x8fce, 0x8fd0, 0x8fd2, 0x8fd4, 0x8fd6, 0x8fd9, 0x8fdb, 
+    0x8fdd, 0x8fdf, 0x8fe1, 0x8fe4, 0x8fe6, 0x8fe8, 0x8fea, 0x8fec, 
+    0x8fee, 0x8ff1, 0x8ff3, 0x8ff5, 0x8ff7, 0x8ff9, 0x8ffc, 0x8ffe, 
+    0x9000, 0x9002, 0x9004, 0x9007, 0x9009, 0x900b, 0x900d, 0x900f, 
+    0x9012, 0x9014, 0x9016, 0x9018, 0x901b, 0x901d, 0x901f, 0x9021, 
+    0x9024, 0x9026, 0x9028, 0x902a, 0x902d, 0x902f, 0x9031, 0x9033, 
+    0x9036, 0x9038, 0x903a, 0x903c, 0x903f, 0x9041, 0x9043, 0x9045, 
+    0x9048, 0x904a, 0x904c, 0x904f, 0x9051, 0x9053, 0x9055, 0x9058, 
+    0x905a, 0x905c, 0x905f, 0x9061, 0x9063, 0x9066, 0x9068, 0x906a, 
+    0x906d, 0x906f, 0x9071, 0x9074, 0x9076, 0x9078, 0x907b, 0x907d, 
+    0x907f, 0x9082, 0x9084, 0x9086, 0x9089, 0x908b, 0x908d, 0x9090, 
+    0x9092, 0x9094, 0x9097, 0x9099, 0x909c, 0x909e, 0x90a0, 0x90a3, 
+    0x90a5, 0x90a8, 0x90aa, 0x90ac, 0x90af, 0x90b1, 0x90b3, 0x90b6, 
+    0x90b8, 0x90bb, 0x90bd, 0x90c0, 0x90c2, 0x90c4, 0x90c7, 0x90c9, 
+    0x90cc, 0x90ce, 0x90d1, 0x90d3, 0x90d5, 0x90d8, 0x90da, 0x90dd, 
+    0x90df, 0x90e2, 0x90e4, 0x90e7, 0x90e9, 0x90eb, 0x90ee, 0x90f0, 
+    0x90f3, 0x90f5, 0x90f8, 0x90fa, 0x90fd, 0x90ff, 0x9102, 0x9104, 
+    0x9107, 0x9109, 0x910c, 0x910e, 0x9111, 0x9113, 0x9116, 0x9118, 
+    0x911b, 0x911d, 0x9120, 0x9122, 0x9125, 0x9127, 0x912a, 0x912c, 
+    0x912f, 0x9131, 0x9134, 0x9137, 0x9139, 0x913c, 0x913e, 0x9141, 
+    0x9143, 0x9146, 0x9148, 0x914b, 0x914d, 0x9150, 0x9153, 0x9155, 
+    0x9158, 0x915a, 0x915d, 0x9160, 0x9162, 0x9165, 0x9167, 0x916a, 
+    0x916c, 0x916f, 0x9172, 0x9174, 0x9177, 0x9179, 0x917c, 0x917f, 
+    0x9181, 0x9184, 0x9187, 0x9189, 0x918c, 0x918e, 0x9191, 0x9194, 
+    0x9196, 0x9199, 0x919c, 0x919e, 0x91a1, 0x91a4, 0x91a6, 0x91a9, 
+    0x91ac, 0x91ae, 0x91b1, 0x91b4, 0x91b6, 0x91b9, 0x91bc, 0x91be, 
+    0x91c1, 0x91c4, 0x91c6, 0x91c9, 0x91cc, 0x91ce, 0x91d1, 0x91d4, 
+    0x91d6, 0x91d9, 0x91dc, 0x91df, 0x91e1, 0x91e4, 0x91e7, 0x91e9, 
+    0x91ec, 0x91ef, 0x91f2, 0x91f4, 0x91f7, 0x91fa, 0x91fd, 0x91ff, 
+    0x9202, 0x9205, 0x9208, 0x920a, 0x920d, 0x9210, 0x9213, 0x9215, 
+    0x9218, 0x921b, 0x921e, 0x9220, 0x9223, 0x9226, 0x9229, 0x922c, 
+    0x922e, 0x9231, 0x9234, 0x9237, 0x923a, 0x923c, 0x923f, 0x9242, 
+    0x9245, 0x9248, 0x924a, 0x924d, 0x9250, 0x9253, 0x9256, 0x9259, 
+    0x925b, 0x925e, 0x9261, 0x9264, 0x9267, 0x926a, 0x926c, 0x926f, 
+    0x9272, 0x9275, 0x9278, 0x927b, 0x927e, 0x9280, 0x9283, 0x9286, 
+    0x9289, 0x928c, 0x928f, 0x9292, 0x9295, 0x9297, 0x929a, 0x929d, 
+    0x92a0, 0x92a3, 0x92a6, 0x92a9, 0x92ac, 0x92af, 0x92b2, 0x92b4, 
+    0x92b7, 0x92ba, 0x92bd, 0x92c0, 0x92c3, 0x92c6, 0x92c9, 0x92cc, 
+    0x92cf, 0x92d2, 0x92d5, 0x92d8, 0x92db, 0x92de, 0x92e1, 0x92e3, 
+    0x92e6, 0x92e9, 0x92ec, 0x92ef, 0x92f2, 0x92f5, 0x92f8, 0x92fb, 
+    0x92fe, 0x9301, 0x9304, 0x9307, 0x930a, 0x930d, 0x9310, 0x9313, 
+    0x9316, 0x9319, 0x931c, 0x931f, 0x9322, 0x9325, 0x9328, 0x932b, 
+    0x932e, 0x9331, 0x9334, 0x9337, 0x933a, 0x933d, 0x9341, 0x9344, 
+    0x9347, 0x934a, 0x934d, 0x9350, 0x9353, 0x9356, 0x9359, 0x935c, 
+    0x935f, 0x9362, 0x9365, 0x9368, 0x936b, 0x936e, 0x9372, 0x9375, 
+    0x9378, 0x937b, 0x937e, 0x9381, 0x9384, 0x9387, 0x938a, 0x938d, 
+    0x9391, 0x9394, 0x9397, 0x939a, 0x939d, 0x93a0, 0x93a3, 0x93a6, 
+    0x93aa, 0x93ad, 0x93b0, 0x93b3, 0x93b6, 0x93b9, 0x93bc, 0x93c0, 
+    0x93c3, 0x93c6, 0x93c9, 0x93cc, 0x93cf, 0x93d3, 0x93d6, 0x93d9, 
+    0x93dc, 0x93df, 0x93e2, 0x93e6, 0x93e9, 0x93ec, 0x93ef, 0x93f2, 
+    0x93f6, 0x93f9, 0x93fc, 0x93ff, 0x9401, 0x9403, 0x9404, 0x9406, 
+    0x9408, 0x9409, 0x940b, 0x940d, 0x940e, 0x9410, 0x9411, 0x9413, 
+    0x9415, 0x9416, 0x9418, 0x9419, 0x941b, 0x941d, 0x941e, 0x9420, 
+    0x9422, 0x9423, 0x9425, 0x9427, 0x9428, 0x942a, 0x942b, 0x942d, 
+    0x942f, 0x9430, 0x9432, 0x9434, 0x9435, 0x9437, 0x9439, 0x943a, 
+    0x943c, 0x943e, 0x943f, 0x9441, 0x9443, 0x9444, 0x9446, 0x9448, 
+    0x9449, 0x944b, 0x944d, 0x944e, 0x9450, 0x9452, 0x9453, 0x9455, 
+    0x9457, 0x9458, 0x945a, 0x945c, 0x945d, 0x945f, 0x9461, 0x9462, 
+    0x9464, 0x9466, 0x9467, 0x9469, 0x946b, 0x946d, 0x946e, 0x9470, 
+    0x9472, 0x9473, 0x9475, 0x9477, 0x9478, 0x947a, 0x947c, 0x947e, 
+    0x947f, 0x9481, 0x9483, 0x9484, 0x9486, 0x9488, 0x948a, 0x948b, 
+    0x948d, 0x948f, 0x9490, 0x9492, 0x9494, 0x9496, 0x9497, 0x9499, 
+    0x949b, 0x949d, 0x949e, 0x94a0, 0x94a2, 0x94a4, 0x94a5, 0x94a7, 
+    0x94a9, 0x94ab, 0x94ac, 0x94ae, 0x94b0, 0x94b2, 0x94b3, 0x94b5, 
+    0x94b7, 0x94b9, 0x94ba, 0x94bc, 0x94be, 0x94c0, 0x94c1, 0x94c3, 
+    0x94c5, 0x94c7, 0x94c8, 0x94ca, 0x94cc, 0x94ce, 0x94cf, 0x94d1, 
+    0x94d3, 0x94d5, 0x94d7, 0x94d8, 0x94da, 0x94dc, 0x94de, 0x94e0, 
+    0x94e1, 0x94e3, 0x94e5, 0x94e7, 0x94e8, 0x94ea, 0x94ec, 0x94ee, 
+    0x94f0, 0x94f1, 0x94f3, 0x94f5, 0x94f7, 0x94f9, 0x94fa, 0x94fc, 
+    0x94fe, 0x9500, 0x9502, 0x9504, 0x9505, 0x9507, 0x9509, 0x950b, 
+    0x950d, 0x950e, 0x9510, 0x9512, 0x9514, 0x9516, 0x9518, 0x9519, 
+    0x951b, 0x951d, 0x951f, 0x9521, 0x9523, 0x9524, 0x9526, 0x9528, 
+    0x952a, 0x952c, 0x952e, 0x9530, 0x9531, 0x9533, 0x9535, 0x9537, 
+    0x9539, 0x953b, 0x953d, 0x953e, 0x9540, 0x9542, 0x9544, 0x9546, 
+    0x9548, 0x954a, 0x954b, 0x954d, 0x954f, 0x9551, 0x9553, 0x9555, 
+    0x9557, 0x9559, 0x955a, 0x955c, 0x955e, 0x9560, 0x9562, 0x9564, 
+    0x9566, 0x9568, 0x956a, 0x956b, 0x956d, 0x956f, 0x9571, 0x9573, 
+    0x9575, 0x9577, 0x9579, 0x957b, 0x957d, 0x957e, 0x9580, 0x9582, 
+    0x9584, 0x9586, 0x9588, 0x958a, 0x958c, 0x958e, 0x9590, 0x9592, 
+    0x9594, 0x9595, 0x9597, 0x9599, 0x959b, 0x959d, 0x959f, 0x95a1, 
+    0x95a3, 0x95a5, 0x95a7, 0x95a9, 0x95ab, 0x95ad, 0x95af, 0x95b1, 
+    0x95b3, 0x95b4, 0x95b6, 0x95b8, 0x95ba, 0x95bc, 0x95be, 0x95c0, 
+    0x95c2, 0x95c4, 0x95c6, 0x95c8, 0x95ca, 0x95cc, 0x95ce, 0x95d0, 
+    0x95d2, 0x95d4, 0x95d6, 0x95d8, 0x95da, 0x95dc, 0x95de, 0x95e0, 
+    0x95e2, 0x95e4, 0x95e6, 0x95e8, 0x95ea, 0x95ec, 0x95ee, 0x95f0, 
+    0x95f2, 0x95f4, 0x95f6, 0x95f8, 0x95fa, 0x95fc, 0x95fe, 0x9600, 
+    0x9602, 0x9604, 0x9606, 0x9608, 0x960a, 0x960c, 0x960e, 0x9610, 
+    0x9612, 0x9614, 0x9616, 0x9618, 0x961a, 0x961c, 0x961e, 0x9620, 
+    0x9622, 0x9624, 0x9626, 0x9628, 0x962a, 0x962c, 0x962e, 0x9630, 
+    0x9632, 0x9634, 0x9636, 0x9638, 0x963a, 0x963c, 0x963e, 0x9640, 
+    0x9642, 0x9644, 0x9647, 0x9649, 0x964b, 0x964d, 0x964f, 0x9651, 
+    0x9653, 0x9655, 0x9657, 0x9659, 0x965b, 0x965d, 0x965f, 0x9661, 
+    0x9663, 0x9665, 0x9668, 0x966a, 0x966c, 0x966e, 0x9670, 0x9672, 
+    0x9674, 0x9676, 0x9678, 0x967a, 0x967c, 0x967e, 0x9681, 0x9683, 
+    0x9685, 0x9687, 0x9689, 0x968b, 0x968d, 0x968f, 0x9691, 0x9693, 
+    0x9696, 0x9698, 0x969a, 0x969c, 0x969e, 0x96a0, 0x96a2, 0x96a4, 
+    0x96a6, 0x96a9, 0x96ab, 0x96ad, 0x96af, 0x96b1, 0x96b3, 0x96b5, 
+    0x96b7, 0x96ba, 0x96bc, 0x96be, 0x96c0, 0x96c2, 0x96c4, 0x96c6, 
+    0x96c9, 0x96cb, 0x96cd, 0x96cf, 0x96d1, 0x96d3, 0x96d5, 0x96d8, 
+    0x96da, 0x96dc, 0x96de, 0x96e0, 0x96e2, 0x96e4, 0x96e7, 0x96e9, 
+    0x96eb, 0x96ed, 0x96ef, 0x96f1, 0x96f4, 0x96f6, 0x96f8, 0x96fa, 
+    0x96fc, 0x96ff, 0x9701, 0x9703, 0x9705, 0x9707, 0x9709, 0x970c, 
+    0x970e, 0x9710, 0x9712, 0x9714, 0x9717, 0x9719, 0x971b, 0x971d, 
+    0x971f, 0x9722, 0x9724, 0x9726, 0x9728, 0x972a, 0x972d, 0x972f, 
+    0x9731, 0x9733, 0x9735, 0x9738, 0x973a, 0x973c, 0x973e, 0x9740, 
+    0x9743, 0x9745, 0x9747, 0x9749, 0x974c, 0x974e, 0x9750, 0x9752, 
+    0x9755, 0x9757, 0x9759, 0x975b, 0x975d, 0x9760, 0x9762, 0x9764, 
+    0x9766, 0x9769, 0x976b, 0x976d, 0x976f, 0x9772, 0x9774, 0x9776, 
+    0x9778, 0x977b, 0x977d, 0x977f, 0x9781, 0x9784, 0x9786, 0x9788, 
+    0x978b, 0x978d, 0x978f, 0x9791, 0x9794, 0x9796, 0x9798, 0x979a, 
+    0x979d, 0x979f, 0x97a1, 0x97a4, 0x97a6, 0x97a8, 0x97aa, 0x97ad, 
+    0x97af, 0x97b1, 0x97b4, 0x97b6, 0x97b8, 0x97bb, 0x97bd, 0x97bf, 
+    0x97c1, 0x97c4, 0x97c6, 0x97c8, 0x97cb, 0x97cd, 0x97cf, 0x97d2, 
+    0x97d4, 0x97d6, 0x97d9, 0x97db, 0x97dd, 0x97e0, 0x97e2, 0x97e4, 
+    0x97e6, 0x97e9, 0x97eb, 0x97ed, 0x97f0, 0x97f2, 0x97f4, 0x97f7, 
+    0x97f9, 0x97fb, 0x97fe, 0x9800, 0x9801, 0x9802, 0x9804, 0x9805, 
+    0x9806, 0x9807, 0x9808, 0x9809, 0x980b, 0x980c, 0x980d, 0x980e, 
+    0x980f, 0x9811, 0x9812, 0x9813, 0x9814, 0x9815, 0x9816, 0x9818, 
+    0x9819, 0x981a, 0x981b, 0x981c, 0x981e, 0x981f, 0x9820, 0x9821, 
+    0x9822, 0x9824, 0x9825, 0x9826, 0x9827, 0x9828, 0x982a, 0x982b, 
+    0x982c, 0x982d, 0x982e, 0x9830, 0x9831, 0x9832, 0x9833, 0x9834, 
+    0x9836, 0x9837, 0x9838, 0x9839, 0x983a, 0x983c, 0x983d, 0x983e, 
+    0x983f, 0x9840, 0x9842, 0x9843, 0x9844, 0x9845, 0x9846, 0x9848, 
+    0x9849, 0x984a, 0x984b, 0x984d, 0x984e, 0x984f, 0x9850, 0x9851, 
+    0x9853, 0x9854, 0x9855, 0x9856, 0x9858, 0x9859, 0x985a, 0x985b, 
+    0x985c, 0x985e, 0x985f, 0x9860, 0x9861, 0x9863, 0x9864, 0x9865, 
+    0x9866, 0x9868, 0x9869, 0x986a, 0x986b, 0x986c, 0x986e, 0x986f, 
+    0x9870, 0x9871, 0x9873, 0x9874, 0x9875, 0x9876, 0x9878, 0x9879, 
+    0x987a, 0x987b, 0x987d, 0x987e, 0x987f, 0x9880, 0x9882, 0x9883, 
+    0x9884, 0x9885, 0x9887, 0x9888, 0x9889, 0x988a, 0x988c, 0x988d, 
+    0x988e, 0x988f, 0x9891, 0x9892, 0x9893, 0x9894, 0x9896, 0x9897, 
+    0x9898, 0x989b, 0x989d, 0x98a0, 0x98a2, 0x98a5, 0x98a7, 0x98aa, 
+    0x98ad, 0x98af, 0x98b2, 0x98b4, 0x98b7, 0x98b9, 0x98bc, 0x98bf, 
+    0x98c1, 0x98c4, 0x98c6, 0x98c9, 0x98cb, 0x98ce, 0x98d1, 0x98d3, 
+    0x98d6, 0x98d8, 0x98db, 0x98de, 0x98e0, 0x98e3, 0x98e5, 0x98e8, 
+    0x98eb, 0x98ed, 0x98f0, 0x98f3, 0x98f5, 0x98f8, 0x98fa, 0x98fd, 
+    0x9900, 0x9902, 0x9905, 0x9908, 0x990a, 0x990d, 0x9910, 0x9912, 
+    0x9915, 0x9918, 0x991a, 0x991d, 0x9920, 0x9922, 0x9925, 0x9928, 
+    0x992a, 0x992d, 0x9930, 0x9933, 0x9935, 0x9938, 0x993b, 0x993d, 
+    0x9940, 0x9943, 0x9946, 0x9948, 0x994b, 0x994e, 0x9950, 0x9953, 
+    0x9956, 0x9959, 0x995b, 0x995e, 0x9961, 0x9964, 0x9966, 0x9969, 
+    0x996c, 0x996f, 0x9972, 0x9974, 0x9977, 0x997a, 0x997d, 0x997f, 
+    0x9982, 0x9985, 0x9988, 0x998b, 0x998d, 0x9990, 0x9993, 0x9996, 
+    0x9999, 0x999b, 0x999e, 0x99a1, 0x99a4, 0x99a7, 0x99aa, 0x99ac, 
+    0x99af, 0x99b2, 0x99b5, 0x99b8, 0x99bb, 0x99bd, 0x99c0, 0x99c3, 
+    0x99c6, 0x99c9, 0x99cc, 0x99cf, 0x99d1, 0x99d4, 0x99d7, 0x99da, 
+    0x99dd, 0x99e0, 0x99e3, 0x99e6, 0x99e9, 0x99eb, 0x99ee, 0x99f1, 
+    0x99f4, 0x99f7, 0x99fa, 0x99fd, 0x9a00, 0x9a03, 0x9a06, 0x9a09, 
+    0x9a0c, 0x9a0f, 0x9a11, 0x9a14, 0x9a17, 0x9a1a, 0x9a1d, 0x9a20, 
+    0x9a23, 0x9a26, 0x9a29, 0x9a2c, 0x9a2f, 0x9a32, 0x9a35, 0x9a38, 
+    0x9a3b, 0x9a3e, 0x9a41, 0x9a44, 0x9a47, 0x9a4a, 0x9a4d, 0x9a50, 
+    0x9a53, 0x9a56, 0x9a59, 0x9a5c, 0x9a5f, 0x9a62, 0x9a65, 0x9a68, 
+    0x9a6b, 0x9a6e, 0x9a71, 0x9a74, 0x9a77, 0x9a7a, 0x9a7d, 0x9a80, 
+    0x9a83, 0x9a86, 0x9a8a, 0x9a8d, 0x9a90, 0x9a93, 0x9a96, 0x9a99, 
+    0x9a9c, 0x9a9f, 0x9aa2, 0x9aa5, 0x9aa8, 0x9aab, 0x9aaf, 0x9ab2, 
+    0x9ab5, 0x9ab8, 0x9abb, 0x9abe, 0x9ac1, 0x9ac4, 0x9ac7, 0x9acb, 
+    0x9ace, 0x9ad1, 0x9ad4, 0x9ad7, 0x9ada, 0x9add, 0x9ae1, 0x9ae4, 
+    0x9ae7, 0x9aea, 0x9aed, 0x9af0, 0x9af3, 0x9af7, 0x9afa, 0x9afd, 
+    0x9b00, 0x9b03, 0x9b07, 0x9b0a, 0x9b0d, 0x9b10, 0x9b13, 0x9b16, 
+    0x9b1a, 0x9b1d, 0x9b20, 0x9b23, 0x9b27, 0x9b2a, 0x9b2d, 0x9b30, 
+    0x9b33, 0x9b37, 0x9b3a, 0x9b3d, 0x9b40, 0x9b44, 0x9b47, 0x9b4a, 
+    0x9b4d, 0x9b51, 0x9b54, 0x9b57, 0x9b5a, 0x9b5e, 0x9b61, 0x9b64, 
+    0x9b67, 0x9b6b, 0x9b6e, 0x9b71, 0x9b75, 0x9b78, 0x9b7b, 0x9b7e, 
+    0x9b82, 0x9b85, 0x9b88, 0x9b8c, 0x9b8f, 0x9b92, 0x9b96, 0x9b99, 
+    0x9b9c, 0x9ba0, 0x9ba3, 0x9ba6, 0x9baa, 0x9bad, 0x9bb0, 0x9bb4, 
+    0x9bb7, 0x9bba, 0x9bbe, 0x9bc1, 0x9bc4, 0x9bc8, 0x9bcb, 0x9bcf, 
+    0x9bd2, 0x9bd5, 0x9bd9, 0x9bdc, 0x9be0, 0x9be3, 0x9be6, 0x9bea, 
+    0x9bed, 0x9bf0, 0x9bf4, 0x9bf7, 0x9bfb, 0x9bfe, 0x9c01, 0x9c02, 
+    0x9c04, 0x9c06, 0x9c08, 0x9c09, 0x9c0b, 0x9c0d, 0x9c0f, 0x9c10, 
+    0x9c12, 0x9c14, 0x9c15, 0x9c17, 0x9c19, 0x9c1b, 0x9c1c, 0x9c1e, 
+    0x9c20, 0x9c22, 0x9c23, 0x9c25, 0x9c27, 0x9c29, 0x9c2a, 0x9c2c, 
+    0x9c2e, 0x9c30, 0x9c31, 0x9c33, 0x9c35, 0x9c37, 0x9c38, 0x9c3a, 
+    0x9c3c, 0x9c3e, 0x9c3f, 0x9c41, 0x9c43, 0x9c45, 0x9c46, 0x9c48, 
+    0x9c4a, 0x9c4c, 0x9c4e, 0x9c4f, 0x9c51, 0x9c53, 0x9c55, 0x9c56, 
+    0x9c58, 0x9c5a, 0x9c5c, 0x9c5e, 0x9c5f, 0x9c61, 0x9c63, 0x9c65, 
+    0x9c67, 0x9c68, 0x9c6a, 0x9c6c, 0x9c6e, 0x9c70, 0x9c71, 0x9c73, 
+    0x9c75, 0x9c77, 0x9c79, 0x9c7b, 0x9c7c, 0x9c7e, 0x9c80, 0x9c82, 
+    0x9c84, 0x9c85, 0x9c87, 0x9c89, 0x9c8b, 0x9c8d, 0x9c8f, 0x9c90, 
+    0x9c92, 0x9c94, 0x9c96, 0x9c98, 0x9c9a, 0x9c9c, 0x9c9d, 0x9c9f, 
+    0x9ca1, 0x9ca3, 0x9ca5, 0x9ca7, 0x9ca8, 0x9caa, 0x9cac, 0x9cae, 
+    0x9cb0, 0x9cb2, 0x9cb4, 0x9cb6, 0x9cb7, 0x9cb9, 0x9cbb, 0x9cbd, 
+    0x9cbf, 0x9cc1, 0x9cc3, 0x9cc5, 0x9cc6, 0x9cc8, 0x9cca, 0x9ccc, 
+    0x9cce, 0x9cd0, 0x9cd2, 0x9cd4, 0x9cd6, 0x9cd7, 0x9cd9, 0x9cdb, 
+    0x9cdd, 0x9cdf, 0x9ce1, 0x9ce3, 0x9ce5, 0x9ce7, 0x9ce9, 0x9cea, 
+    0x9cec, 0x9cee, 0x9cf0, 0x9cf2, 0x9cf4, 0x9cf6, 0x9cf8, 0x9cfa, 
+    0x9cfc, 0x9cfe, 0x9d00, 0x9d02, 0x9d03, 0x9d05, 0x9d07, 0x9d09, 
+    0x9d0b, 0x9d0d, 0x9d0f, 0x9d11, 0x9d13, 0x9d15, 0x9d17, 0x9d19, 
+    0x9d1b, 0x9d1d, 0x9d1f, 0x9d21, 0x9d23, 0x9d25, 0x9d27, 0x9d29, 
+    0x9d2a, 0x9d2c, 0x9d2e, 0x9d30, 0x9d32, 0x9d34, 0x9d36, 0x9d38, 
+    0x9d3a, 0x9d3c, 0x9d3e, 0x9d40, 0x9d42, 0x9d44, 0x9d46, 0x9d48, 
+    0x9d4a, 0x9d4c, 0x9d4e, 0x9d50, 0x9d52, 0x9d54, 0x9d56, 0x9d58, 
+    0x9d5a, 0x9d5c, 0x9d5e, 0x9d60, 0x9d62, 0x9d64, 0x9d66, 0x9d68, 
+    0x9d6a, 0x9d6c, 0x9d6e, 0x9d70, 0x9d72, 0x9d74, 0x9d76, 0x9d78, 
+    0x9d7a, 0x9d7c, 0x9d7e, 0x9d80, 0x9d83, 0x9d85, 0x9d87, 0x9d89, 
+    0x9d8b, 0x9d8d, 0x9d8f, 0x9d91, 0x9d93, 0x9d95, 0x9d97, 0x9d99, 
+    0x9d9b, 0x9d9d, 0x9d9f, 0x9da1, 0x9da3, 0x9da5, 0x9da7, 0x9daa, 
+    0x9dac, 0x9dae, 0x9db0, 0x9db2, 0x9db4, 0x9db6, 0x9db8, 0x9dba, 
+    0x9dbc, 0x9dbe, 0x9dc0, 0x9dc2, 0x9dc5, 0x9dc7, 0x9dc9, 0x9dcb, 
+    0x9dcd, 0x9dcf, 0x9dd1, 0x9dd3, 0x9dd5, 0x9dd7, 0x9dd9, 0x9ddc, 
+    0x9dde, 0x9de0, 0x9de2, 0x9de4, 0x9de6, 0x9de8, 0x9dea, 0x9dec, 
+    0x9def, 0x9df1, 0x9df3, 0x9df5, 0x9df7, 0x9df9, 0x9dfb, 0x9dfd, 
+    0x9e00, 0x9e02, 0x9e04, 0x9e06, 0x9e08, 0x9e0a, 0x9e0c, 0x9e0f, 
+    0x9e11, 0x9e13, 0x9e15, 0x9e17, 0x9e19, 0x9e1b, 0x9e1e, 0x9e20, 
+    0x9e22, 0x9e24, 0x9e26, 0x9e28, 0x9e2b, 0x9e2d, 0x9e2f, 0x9e31, 
+    0x9e33, 0x9e35, 0x9e38, 0x9e3a, 0x9e3c, 0x9e3e, 0x9e40, 0x9e42, 
+    0x9e45, 0x9e47, 0x9e49, 0x9e4b, 0x9e4d, 0x9e50, 0x9e52, 0x9e54, 
+    0x9e56, 0x9e58, 0x9e5b, 0x9e5d, 0x9e5f, 0x9e61, 0x9e63, 0x9e66, 
+    0x9e68, 0x9e6a, 0x9e6c, 0x9e6e, 0x9e71, 0x9e73, 0x9e75, 0x9e77, 
+    0x9e7a, 0x9e7c, 0x9e7e, 0x9e80, 0x9e82, 0x9e85, 0x9e87, 0x9e89, 
+    0x9e8b, 0x9e8e, 0x9e90, 0x9e92, 0x9e94, 0x9e97, 0x9e99, 0x9e9b, 
+    0x9e9d, 0x9ea0, 0x9ea2, 0x9ea4, 0x9ea6, 0x9ea9, 0x9eab, 0x9ead, 
+    0x9eaf, 0x9eb2, 0x9eb4, 0x9eb6, 0x9eb8, 0x9ebb, 0x9ebd, 0x9ebf, 
+    0x9ec2, 0x9ec4, 0x9ec6, 0x9ec8, 0x9ecb, 0x9ecd, 0x9ecf, 0x9ed2, 
+    0x9ed4, 0x9ed6, 0x9ed8, 0x9edb, 0x9edd, 0x9edf, 0x9ee2, 0x9ee4, 
+    0x9ee6, 0x9ee8, 0x9eeb, 0x9eed, 0x9eef, 0x9ef2, 0x9ef4, 0x9ef6, 
+    0x9ef9, 0x9efb, 0x9efd, 0x9f00, 0x9f02, 0x9f04, 0x9f07, 0x9f09, 
+    0x9f0b, 0x9f0e, 0x9f10, 0x9f12, 0x9f15, 0x9f17, 0x9f19, 0x9f1c, 
+    0x9f1e, 0x9f20, 0x9f23, 0x9f25, 0x9f27, 0x9f2a, 0x9f2c, 0x9f2e, 
+    0x9f31, 0x9f33, 0x9f35, 0x9f38, 0x9f3a, 0x9f3c, 0x9f3f, 0x9f41, 
+    0x9f44, 0x9f46, 0x9f48, 0x9f4b, 0x9f4d, 0x9f4f, 0x9f52, 0x9f54, 
+    0x9f57, 0x9f59, 0x9f5b, 0x9f5e, 0x9f60, 0x9f62, 0x9f65, 0x9f67, 
+    0x9f6a, 0x9f6c, 0x9f6e, 0x9f71, 0x9f73, 0x9f76, 0x9f78, 0x9f7a, 
+    0x9f7d, 0x9f7f, 0x9f82, 0x9f84, 0x9f87, 0x9f89, 0x9f8b, 0x9f8e, 
+    0x9f90, 0x9f93, 0x9f95, 0x9f97, 0x9f9a, 0x9f9c, 0x9f9f, 0x9fa1, 
+    0x9fa4, 0x9fa6, 0x9fa8, 0x9fab, 0x9fad, 0x9fb0, 0x9fb2, 0x9fb5, 
+    0x9fb7, 0x9fba, 0x9fbc, 0x9fbe, 0x9fc1, 0x9fc3, 0x9fc6, 0x9fc8, 
+    0x9fcb, 0x9fcd, 0x9fd0, 0x9fd2, 0x9fd5, 0x9fd7, 0x9fda, 0x9fdc, 
+    0x9fde, 0x9fe1, 0x9fe3, 0x9fe6, 0x9fe8, 0x9feb, 0x9fed, 0x9ff0, 
+    0x9ff2, 0x9ff5, 0x9ff7, 0x9ffa, 0x9ffc, 0x9fff, 0xa001, 0xa002, 
+    0xa003, 0xa004, 0xa006, 0xa007, 0xa008, 0xa009, 0xa00b, 0xa00c, 
+    0xa00d, 0xa00e, 0xa010, 0xa011, 0xa012, 0xa013, 0xa015, 0xa016, 
+    0xa017, 0xa018, 0xa01a, 0xa01b, 0xa01c, 0xa01e, 0xa01f, 0xa020, 
+    0xa021, 0xa023, 0xa024, 0xa025, 0xa026, 0xa028, 0xa029, 0xa02a, 
+    0xa02c, 0xa02d, 0xa02e, 0xa02f, 0xa031, 0xa032, 0xa033, 0xa034, 
+    0xa036, 0xa037, 0xa038, 0xa03a, 0xa03b, 0xa03c, 0xa03d, 0xa03f, 
+    0xa040, 0xa041, 0xa043, 0xa044, 0xa045, 0xa047, 0xa048, 0xa049, 
+    0xa04a, 0xa04c, 0xa04d, 0xa04e, 0xa050, 0xa051, 0xa052, 0xa054, 
+    0xa055, 0xa056, 0xa057, 0xa059, 0xa05a, 0xa05b, 0xa05d, 0xa05e, 
+    0xa05f, 0xa061, 0xa062, 0xa063, 0xa065, 0xa066, 0xa067, 0xa068, 
+    0xa06a, 0xa06b, 0xa06c, 0xa06e, 0xa06f, 0xa070, 0xa072, 0xa073, 
+    0xa074, 0xa076, 0xa077, 0xa078, 0xa07a, 0xa07b, 0xa07c, 0xa07e, 
+    0xa07f, 0xa080, 0xa082, 0xa083, 0xa084, 0xa086, 0xa087, 0xa088, 
+    0xa08a, 0xa08b, 0xa08c, 0xa08e, 0xa08f, 0xa090, 0xa092, 0xa093, 
+    0xa094, 0xa096, 0xa097, 0xa098, 0xa09a, 0xa09b, 0xa09c, 0xa09e, 
+    0xa09f, 0xa0a0, 0xa0a2, 0xa0a3, 0xa0a5, 0xa0a6, 0xa0a7, 0xa0a9, 
+    0xa0aa, 0xa0ab, 0xa0ad, 0xa0ae, 0xa0af, 0xa0b1, 0xa0b2, 0xa0b3, 
+    0xa0b5, 0xa0b6, 0xa0b8, 0xa0b9, 0xa0ba, 0xa0bc, 0xa0bd, 0xa0be, 
+    0xa0c0, 0xa0c1, 0xa0c2, 0xa0c4, 0xa0c5, 0xa0c7, 0xa0c8, 0xa0c9, 
+    0xa0cb, 0xa0cc, 0xa0cd, 0xa0cf, 0xa0d0, 0xa0d2, 0xa0d3, 0xa0d4, 
+    0xa0d6, 0xa0d7, 0xa0d9, 0xa0da, 0xa0db, 0xa0dd, 0xa0de, 0xa0df, 
+    0xa0e1, 0xa0e2, 0xa0e4, 0xa0e5, 0xa0e6, 0xa0e8, 0xa0e9, 0xa0eb, 
+    0xa0ec, 0xa0ed, 0xa0ef, 0xa0f0, 0xa0f2, 0xa0f3, 0xa0f4, 0xa0f6, 
+    0xa0f7, 0xa0f9, 0xa0fa, 0xa0fb, 0xa0fd, 0xa0fe, 0xa100, 0xa101, 
+    0xa102, 0xa104, 0xa105, 0xa107, 0xa108, 0xa10a, 0xa10b, 0xa10c, 
+    0xa10e, 0xa10f, 0xa111, 0xa112, 0xa113, 0xa115, 0xa116, 0xa118, 
+    0xa119, 0xa11b, 0xa11c, 0xa11d, 0xa11f, 0xa120, 0xa122, 0xa123, 
+    0xa125, 0xa126, 0xa127, 0xa129, 0xa12a, 0xa12c, 0xa12d, 0xa12f, 
+    0xa130, 0xa131, 0xa133, 0xa134, 0xa136, 0xa137, 0xa139, 0xa13a, 
+    0xa13c, 0xa13d, 0xa13e, 0xa140, 0xa141, 0xa143, 0xa144, 0xa146, 
+    0xa147, 0xa14a, 0xa14d, 0xa150, 0xa153, 0xa156, 0xa159, 0xa15c, 
+    0xa15f, 0xa161, 0xa164, 0xa167, 0xa16a, 0xa16d, 0xa170, 0xa173, 
+    0xa176, 0xa179, 0xa17c, 0xa17f, 0xa182, 0xa185, 0xa188, 0xa18b, 
+    0xa18e, 0xa191, 0xa194, 0xa197, 0xa19a, 0xa19d, 0xa1a0, 0xa1a3, 
+    0xa1a6, 0xa1a9, 0xa1ac, 0xa1af, 0xa1b2, 0xa1b5, 0xa1b8, 0xa1bb, 
+    0xa1be, 0xa1c1, 0xa1c4, 0xa1c7, 0xa1ca, 0xa1cd, 0xa1d0, 0xa1d3, 
+    0xa1d6, 0xa1da, 0xa1dd, 0xa1e0, 0xa1e3, 0xa1e6, 0xa1e9, 0xa1ec, 
+    0xa1ef, 0xa1f2, 0xa1f5, 0xa1f8, 0xa1fb, 0xa1ff, 0xa202, 0xa205, 
+    0xa208, 0xa20b, 0xa20e, 0xa211, 0xa214, 0xa218, 0xa21b, 0xa21e, 
+    0xa221, 0xa224, 0xa227, 0xa22b, 0xa22e, 0xa231, 0xa234, 0xa237, 
+    0xa23a, 0xa23e, 0xa241, 0xa244, 0xa247, 0xa24a, 0xa24d, 0xa251, 
+    0xa254, 0xa257, 0xa25a, 0xa25e, 0xa261, 0xa264, 0xa267, 0xa26a, 
+    0xa26e, 0xa271, 0xa274, 0xa277, 0xa27b, 0xa27e, 0xa281, 0xa284, 
+    0xa288, 0xa28b, 0xa28e, 0xa291, 0xa295, 0xa298, 0xa29b, 0xa29f, 
+    0xa2a2, 0xa2a5, 0xa2a8, 0xa2ac, 0xa2af, 0xa2b2, 0xa2b6, 0xa2b9, 
+    0xa2bc, 0xa2c0, 0xa2c3, 0xa2c6, 0xa2c9, 0xa2cd, 0xa2d0, 0xa2d4, 
+    0xa2d7, 0xa2da, 0xa2de, 0xa2e1, 0xa2e4, 0xa2e8, 0xa2eb, 0xa2ee, 
+    0xa2f2, 0xa2f5, 0xa2f8, 0xa2fc, 0xa2ff, 0xa303, 0xa306, 0xa309, 
+    0xa30d, 0xa310, 0xa314, 0xa317, 0xa31a, 0xa31e, 0xa321, 0xa325, 
+    0xa328, 0xa32c, 0xa32f, 0xa332, 0xa336, 0xa339, 0xa33d, 0xa340, 
+    0xa344, 0xa347, 0xa34b, 0xa34e, 0xa351, 0xa355, 0xa358, 0xa35c, 
+    0xa35f, 0xa363, 0xa366, 0xa36a, 0xa36d, 0xa371, 0xa374, 0xa378, 
+    0xa37b, 0xa37f, 0xa382, 0xa386, 0xa389, 0xa38d, 0xa390, 0xa394, 
+    0xa398, 0xa39b, 0xa39f, 0xa3a2, 0xa3a6, 0xa3a9, 0xa3ad, 0xa3b0, 
+    0xa3b4, 0xa3b8, 0xa3bb, 0xa3bf, 0xa3c2, 0xa3c6, 0xa3c9, 0xa3cd, 
+    0xa3d1, 0xa3d4, 0xa3d8, 0xa3db, 0xa3df, 0xa3e3, 0xa3e6, 0xa3ea, 
+    0xa3ee, 0xa3f1, 0xa3f5, 0xa3f8, 0xa3fc, 0xa400, 0xa402, 0xa403, 
+    0xa405, 0xa407, 0xa409, 0xa40b, 0xa40d, 0xa40e, 0xa410, 0xa412, 
+    0xa414, 0xa416, 0xa418, 0xa41a, 0xa41b, 0xa41d, 0xa41f, 0xa421, 
+    0xa423, 0xa425, 0xa426, 0xa428, 0xa42a, 0xa42c, 0xa42e, 0xa430, 
+    0xa432, 0xa434, 0xa435, 0xa437, 0xa439, 0xa43b, 0xa43d, 0xa43f, 
+    0xa441, 0xa443, 0xa444, 0xa446, 0xa448, 0xa44a, 0xa44c, 0xa44e, 
+    0xa450, 0xa452, 0xa454, 0xa455, 0xa457, 0xa459, 0xa45b, 0xa45d, 
+    0xa45f, 0xa461, 0xa463, 0xa465, 0xa467, 0xa469, 0xa46b, 0xa46c, 
+    0xa46e, 0xa470, 0xa472, 0xa474, 0xa476, 0xa478, 0xa47a, 0xa47c, 
+    0xa47e, 0xa480, 0xa482, 0xa484, 0xa486, 0xa488, 0xa489, 0xa48b, 
+    0xa48d, 0xa48f, 0xa491, 0xa493, 0xa495, 0xa497, 0xa499, 0xa49b, 
+    0xa49d, 0xa49f, 0xa4a1, 0xa4a3, 0xa4a5, 0xa4a7, 0xa4a9, 0xa4ab, 
+    0xa4ad, 0xa4af, 0xa4b1, 0xa4b3, 0xa4b5, 0xa4b7, 0xa4b9, 0xa4bb, 
+    0xa4bd, 0xa4bf, 0xa4c1, 0xa4c3, 0xa4c5, 0xa4c7, 0xa4c9, 0xa4cb, 
+    0xa4cd, 0xa4cf, 0xa4d1, 0xa4d3, 0xa4d5, 0xa4d7, 0xa4d9, 0xa4db, 
+    0xa4dd, 0xa4df, 0xa4e1, 0xa4e3, 0xa4e5, 0xa4e7, 0xa4e9, 0xa4eb, 
+    0xa4ed, 0xa4ef, 0xa4f1, 0xa4f3, 0xa4f5, 0xa4f7, 0xa4fa, 0xa4fc, 
+    0xa4fe, 0xa500, 0xa502, 0xa504, 0xa506, 0xa508, 0xa50a, 0xa50c, 
+    0xa50e, 0xa510, 0xa512, 0xa514, 0xa516, 0xa519, 0xa51b, 0xa51d, 
+    0xa51f, 0xa521, 0xa523, 0xa525, 0xa527, 0xa529, 0xa52b, 0xa52d, 
+    0xa52f, 0xa532, 0xa534, 0xa536, 0xa538, 0xa53a, 0xa53c, 0xa53e, 
+    0xa540, 0xa542, 0xa545, 0xa547, 0xa549, 0xa54b, 0xa54d, 0xa54f, 
+    0xa551, 0xa553, 0xa556, 0xa558, 0xa55a, 0xa55c, 0xa55e, 0xa560, 
+    0xa562, 0xa564, 0xa567, 0xa569, 0xa56b, 0xa56d, 0xa56f, 0xa571, 
+    0xa574, 0xa576, 0xa578, 0xa57a, 0xa57c, 0xa57e, 0xa581, 0xa583, 
+    0xa585, 0xa587, 0xa589, 0xa58b, 0xa58e, 0xa590, 0xa592, 0xa594, 
+    0xa596, 0xa598, 0xa59b, 0xa59d, 0xa59f, 0xa5a1, 0xa5a3, 0xa5a6, 
+    0xa5a8, 0xa5aa, 0xa5ac, 0xa5ae, 0xa5b1, 0xa5b3, 0xa5b5, 0xa5b7, 
+    0xa5b9, 0xa5bc, 0xa5be, 0xa5c0, 0xa5c2, 0xa5c5, 0xa5c7, 0xa5c9, 
+    0xa5cb, 0xa5cd, 0xa5d0, 0xa5d2, 0xa5d4, 0xa5d6, 0xa5d9, 0xa5db, 
+    0xa5dd, 0xa5df, 0xa5e2, 0xa5e4, 0xa5e6, 0xa5e8, 0xa5eb, 0xa5ed, 
+    0xa5ef, 0xa5f1, 0xa5f4, 0xa5f6, 0xa5f8, 0xa5fa, 0xa5fd, 0xa5ff, 
+    0xa601, 0xa604, 0xa606, 0xa608, 0xa60a, 0xa60d, 0xa60f, 0xa611, 
+    0xa614, 0xa616, 0xa618, 0xa61a, 0xa61d, 0xa61f, 0xa621, 0xa624, 
+    0xa626, 0xa628, 0xa62a, 0xa62d, 0xa62f, 0xa631, 0xa634, 0xa636, 
+    0xa638, 0xa63b, 0xa63d, 0xa63f, 0xa642, 0xa644, 0xa646, 0xa649, 
+    0xa64b, 0xa64d, 0xa650, 0xa652, 0xa654, 0xa657, 0xa659, 0xa65b, 
+    0xa65e, 0xa660, 0xa662, 0xa665, 0xa667, 0xa669, 0xa66c, 0xa66e, 
+    0xa670, 0xa673, 0xa675, 0xa678, 0xa67a, 0xa67c, 0xa67f, 0xa681, 
+    0xa683, 0xa686, 0xa688, 0xa68b, 0xa68d, 0xa68f, 0xa692, 0xa694, 
+    0xa696, 0xa699, 0xa69b, 0xa69e, 0xa6a0, 0xa6a2, 0xa6a5, 0xa6a7, 
+    0xa6aa, 0xa6ac, 0xa6ae, 0xa6b1, 0xa6b3, 0xa6b6, 0xa6b8, 0xa6bb, 
+    0xa6bd, 0xa6bf, 0xa6c2, 0xa6c4, 0xa6c7, 0xa6c9, 0xa6cc, 0xa6ce, 
+    0xa6d0, 0xa6d3, 0xa6d5, 0xa6d8, 0xa6da, 0xa6dd, 0xa6df, 0xa6e1, 
+    0xa6e4, 0xa6e6, 0xa6e9, 0xa6eb, 0xa6ee, 0xa6f0, 0xa6f3, 0xa6f5, 
+    0xa6f8, 0xa6fa, 0xa6fd, 0xa6ff, 0xa701, 0xa704, 0xa706, 0xa709, 
+    0xa70b, 0xa70e, 0xa710, 0xa713, 0xa715, 0xa718, 0xa71a, 0xa71d, 
+    0xa71f, 0xa722, 0xa724, 0xa727, 0xa729, 0xa72c, 0xa72e, 0xa731, 
+    0xa733, 0xa736, 0xa738, 0xa73b, 0xa73d, 0xa740, 0xa742, 0xa745, 
+    0xa747, 0xa74a, 0xa74c, 0xa74f, 0xa752, 0xa754, 0xa757, 0xa759, 
+    0xa75c, 0xa75e, 0xa761, 0xa763, 0xa766, 0xa768, 0xa76b, 0xa76d, 
+    0xa770, 0xa773, 0xa775, 0xa778, 0xa77a, 0xa77d, 0xa77f, 0xa782, 
+    0xa785, 0xa787, 0xa78a, 0xa78c, 0xa78f, 0xa791, 0xa794, 0xa797, 
+    0xa799, 0xa79c, 0xa79e, 0xa7a1, 0xa7a4, 0xa7a6, 0xa7a9, 0xa7ab, 
+    0xa7ae, 0xa7b0, 0xa7b3, 0xa7b6, 0xa7b8, 0xa7bb, 0xa7be, 0xa7c0, 
+    0xa7c3, 0xa7c5, 0xa7c8, 0xa7cb, 0xa7cd, 0xa7d0, 0xa7d2, 0xa7d5, 
+    0xa7d8, 0xa7da, 0xa7dd, 0xa7e0, 0xa7e2, 0xa7e5, 0xa7e8, 0xa7ea, 
+    0xa7ed, 0xa7ef, 0xa7f2, 0xa7f5, 0xa7f7, 0xa7fa, 0xa7fd, 0xa7ff, 
+    0xa801, 0xa802, 0xa804, 0xa805, 0xa806, 0xa808, 0xa809, 0xa80a, 
+    0xa80c, 0xa80d, 0xa80e, 0xa810, 0xa811, 0xa812, 0xa814, 0xa815, 
+    0xa816, 0xa818, 0xa819, 0xa81a, 0xa81c, 0xa81d, 0xa81e, 0xa820, 
+    0xa821, 0xa823, 0xa824, 0xa825, 0xa827, 0xa828, 0xa829, 0xa82b, 
+    0xa82c, 0xa82d, 0xa82f, 0xa830, 0xa831, 0xa833, 0xa834, 0xa836, 
+    0xa837, 0xa838, 0xa83a, 0xa83b, 0xa83c, 0xa83e, 0xa83f, 0xa841, 
+    0xa842, 0xa843, 0xa845, 0xa846, 0xa847, 0xa849, 0xa84a, 0xa84c, 
+    0xa84d, 0xa84e, 0xa850, 0xa851, 0xa852, 0xa854, 0xa855, 0xa857, 
+    0xa858, 0xa859, 0xa85b, 0xa85c, 0xa85e, 0xa85f, 0xa860, 0xa862, 
+    0xa863, 0xa865, 0xa866, 0xa867, 0xa869, 0xa86a, 0xa86c, 0xa86d, 
+    0xa86e, 0xa870, 0xa871, 0xa873, 0xa874, 0xa875, 0xa877, 0xa878, 
+    0xa87a, 0xa87b, 0xa87d, 0xa87e, 0xa87f, 0xa881, 0xa882, 0xa884, 
+    0xa885, 0xa886, 0xa888, 0xa889, 0xa88b, 0xa88c, 0xa88e, 0xa88f, 
+    0xa890, 0xa892, 0xa893, 0xa895, 0xa896, 0xa898, 0xa899, 0xa89a, 
+    0xa89c, 0xa89d, 0xa89f, 0xa8a0, 0xa8a2, 0xa8a3, 0xa8a4, 0xa8a6, 
+    0xa8a7, 0xa8a9, 0xa8aa, 0xa8ac, 0xa8ad, 0xa8af, 0xa8b0, 0xa8b1, 
+    0xa8b3, 0xa8b4, 0xa8b6, 0xa8b7, 0xa8b9, 0xa8ba, 0xa8bc, 0xa8bd, 
+    0xa8bf, 0xa8c0, 0xa8c2, 0xa8c3, 0xa8c4, 0xa8c6, 0xa8c7, 0xa8c9, 
+    0xa8ca, 0xa8cc, 0xa8cd, 0xa8cf, 0xa8d0, 0xa8d2, 0xa8d3, 0xa8d5, 
+    0xa8d6, 0xa8d8, 0xa8d9, 0xa8da, 0xa8dc, 0xa8dd, 0xa8df, 0xa8e0, 
+    0xa8e2, 0xa8e3, 0xa8e5, 0xa8e6, 0xa8e8, 0xa8e9, 0xa8eb, 0xa8ec, 
+    0xa8ee, 0xa8ef, 0xa8f1, 0xa8f2, 0xa8f4, 0xa8f5, 0xa8f7, 0xa8f8, 
+    0xa8fa, 0xa8fb, 0xa8fd, 0xa8fe, 0xa900, 0xa901, 0xa903, 0xa904, 
+    0xa906, 0xa907, 0xa909, 0xa90a, 0xa90c, 0xa90d, 0xa90f, 0xa910, 
+    0xa912, 0xa913, 0xa915, 0xa916, 0xa918, 0xa919, 0xa91b, 0xa91c, 
+    0xa91e, 0xa91f, 0xa921, 0xa922, 0xa924, 0xa926, 0xa927, 0xa929, 
+    0xa92a, 0xa92c, 0xa92d, 0xa92f, 0xa930, 0xa932, 0xa933, 0xa935, 
+    0xa936, 0xa938, 0xa939, 0xa93b, 0xa93c, 0xa93e, 0xa940, 0xa941, 
+    0xa943, 0xa944, 0xa946, 0xa947, 0xa949, 0xa94a, 0xa94c, 0xa94d, 
+    0xa94f, 0xa951, 0xa952, 0xa954, 0xa955, 0xa957, 0xa958, 0xa95a, 
+    0xa95b, 0xa95d, 0xa95f, 0xa960, 0xa962, 0xa963, 0xa965, 0xa966, 
+    0xa968, 0xa96a, 0xa96b, 0xa96d, 0xa96e, 0xa970, 0xa971, 0xa973, 
+    0xa975, 0xa976, 0xa978, 0xa979, 0xa97b, 0xa97c, 0xa97e, 0xa980, 
+    0xa981, 0xa983, 0xa984, 0xa986, 0xa987, 0xa989, 0xa98b, 0xa98c, 
+    0xa98e, 0xa98f, 0xa991, 0xa993, 0xa994, 0xa996, 0xa997, 0xa999, 
+    0xa99b, 0xa99c, 0xa99e, 0xa99f, 0xa9a1, 0xa9a3, 0xa9a4, 0xa9a6, 
+    0xa9a7, 0xa9a9, 0xa9ab, 0xa9ac, 0xa9ae, 0xa9af, 0xa9b1, 0xa9b3, 
+    0xa9b4, 0xa9b6, 0xa9b7, 0xa9b9, 0xa9bb, 0xa9bc, 0xa9be, 0xa9c0, 
+    0xa9c1, 0xa9c3, 0xa9c4, 0xa9c6, 0xa9c8, 0xa9c9, 0xa9cb, 0xa9cd, 
+    0xa9ce, 0xa9d0, 0xa9d1, 0xa9d3, 0xa9d5, 0xa9d6, 0xa9d8, 0xa9da, 
+    0xa9db, 0xa9dd, 0xa9df, 0xa9e0, 0xa9e2, 0xa9e3, 0xa9e5, 0xa9e7, 
+    0xa9e8, 0xa9ea, 0xa9ec, 0xa9ed, 0xa9ef, 0xa9f1, 0xa9f2, 0xa9f4, 
+    0xa9f6, 0xa9f7, 0xa9f9, 0xa9fb, 0xa9fc, 0xa9fe, 0xa9ff, 0xaa01, 
+    0xaa03, 0xaa04, 0xaa06, 0xaa08, 0xaa09, 0xaa0b, 0xaa0d, 0xaa0e, 
+    0xaa10, 0xaa13, 0xaa17, 0xaa1a, 0xaa1d, 0xaa21, 0xaa24, 0xaa28, 
+    0xaa2b, 0xaa2e, 0xaa32, 0xaa35, 0xaa38, 0xaa3c, 0xaa3f, 0xaa43, 
+    0xaa46, 0xaa49, 0xaa4d, 0xaa50, 0xaa54, 0xaa57, 0xaa5a, 0xaa5e, 
+    0xaa61, 0xaa65, 0xaa68, 0xaa6c, 0xaa6f, 0xaa72, 0xaa76, 0xaa79, 
+    0xaa7d, 0xaa80, 0xaa84, 0xaa87, 0xaa8b, 0xaa8e, 0xaa92, 0xaa95, 
+    0xaa99, 0xaa9c, 0xaaa0, 0xaaa3, 0xaaa7, 0xaaaa, 0xaaae, 0xaab1, 
+    0xaab5, 0xaab8, 0xaabc, 0xaabf, 0xaac3, 0xaac6, 0xaaca, 0xaacd, 
+    0xaad1, 0xaad5, 0xaad8, 0xaadc, 0xaadf, 0xaae3, 0xaae6, 0xaaea, 
+    0xaaee, 0xaaf1, 0xaaf5, 0xaaf8, 0xaafc, 0xab00, 0xab03, 0xab07, 
+    0xab0a, 0xab0e, 0xab12, 0xab15, 0xab19, 0xab1c, 0xab20, 0xab24, 
+    0xab27, 0xab2b, 0xab2f, 0xab32, 0xab36, 0xab3a, 0xab3d, 0xab41, 
+    0xab45, 0xab48, 0xab4c, 0xab50, 0xab54, 0xab57, 0xab5b, 0xab5f, 
+    0xab62, 0xab66, 0xab6a, 0xab6d, 0xab71, 0xab75, 0xab79, 0xab7c, 
+    0xab80, 0xab84, 0xab88, 0xab8b, 0xab8f, 0xab93, 0xab97, 0xab9a, 
+    0xab9e, 0xaba2, 0xaba6, 0xabaa, 0xabad, 0xabb1, 0xabb5, 0xabb9, 
+    0xabbd, 0xabc0, 0xabc4, 0xabc8, 0xabcc, 0xabd0, 0xabd4, 0xabd7, 
+    0xabdb, 0xabdf, 0xabe3, 0xabe7, 0xabeb, 0xabee, 0xabf2, 0xabf6, 
+    0xabfa, 0xabfe, 0xac01, 0xac03, 0xac05, 0xac07, 0xac09, 0xac0b, 
+    0xac0d, 0xac0f, 0xac10, 0xac12, 0xac14, 0xac16, 0xac18, 0xac1a, 
+    0xac1c, 0xac1e, 0xac20, 0xac22, 0xac24, 0xac26, 0xac28, 0xac2a, 
+    0xac2c, 0xac2e, 0xac30, 0xac32, 0xac34, 0xac36, 0xac38, 0xac3a, 
+    0xac3c, 0xac3e, 0xac40, 0xac42, 0xac44, 0xac46, 0xac48, 0xac4a, 
+    0xac4c, 0xac4e, 0xac50, 0xac52, 0xac54, 0xac56, 0xac58, 0xac5a, 
+    0xac5c, 0xac5e, 0xac60, 0xac62, 0xac64, 0xac66, 0xac69, 0xac6b, 
+    0xac6d, 0xac6f, 0xac71, 0xac73, 0xac75, 0xac77, 0xac79, 0xac7b, 
+    0xac7d, 0xac7f, 0xac81, 0xac83, 0xac85, 0xac87, 0xac8a, 0xac8c, 
+    0xac8e, 0xac90, 0xac92, 0xac94, 0xac96, 0xac98, 0xac9a, 0xac9c, 
+    0xac9e, 0xaca0, 0xaca3, 0xaca5, 0xaca7, 0xaca9, 0xacab, 0xacad, 
+    0xacaf, 0xacb1, 0xacb3, 0xacb6, 0xacb8, 0xacba, 0xacbc, 0xacbe, 
+    0xacc0, 0xacc2, 0xacc4, 0xacc7, 0xacc9, 0xaccb, 0xaccd, 0xaccf, 
+    0xacd1, 0xacd3, 0xacd6, 0xacd8, 0xacda, 0xacdc, 0xacde, 0xace0, 
+    0xace3, 0xace5, 0xace7, 0xace9, 0xaceb, 0xaced, 0xacf0, 0xacf2, 
+    0xacf4, 0xacf6, 0xacf8, 0xacfa, 0xacfd, 0xacff, 0xad01, 0xad03, 
+    0xad05, 0xad08, 0xad0a, 0xad0c, 0xad0e, 0xad10, 0xad13, 0xad15, 
+    0xad17, 0xad19, 0xad1b, 0xad1e, 0xad20, 0xad22, 0xad24, 0xad27, 
+    0xad29, 0xad2b, 0xad2d, 0xad2f, 0xad32, 0xad34, 0xad36, 0xad38, 
+    0xad3b, 0xad3d, 0xad3f, 0xad41, 0xad44, 0xad46, 0xad48, 0xad4a, 
+    0xad4d, 0xad4f, 0xad51, 0xad54, 0xad56, 0xad58, 0xad5a, 0xad5d, 
+    0xad5f, 0xad61, 0xad63, 0xad66, 0xad68, 0xad6a, 0xad6d, 0xad6f, 
+    0xad71, 0xad73, 0xad76, 0xad78, 0xad7a, 0xad7d, 0xad7f, 0xad81, 
+    0xad84, 0xad86, 0xad88, 0xad8b, 0xad8d, 0xad8f, 0xad91, 0xad94, 
+    0xad96, 0xad98, 0xad9b, 0xad9d, 0xad9f, 0xada2, 0xada4, 0xada6, 
+    0xada9, 0xadab, 0xadae, 0xadb0, 0xadb2, 0xadb5, 0xadb7, 0xadb9, 
+    0xadbc, 0xadbe, 0xadc0, 0xadc3, 0xadc5, 0xadc7, 0xadca, 0xadcc, 
+    0xadcf, 0xadd1, 0xadd3, 0xadd6, 0xadd8, 0xadda, 0xaddd, 0xaddf, 
+    0xade2, 0xade4, 0xade6, 0xade9, 0xadeb, 0xadee, 0xadf0, 0xadf2, 
+    0xadf5, 0xadf7, 0xadfa, 0xadfc, 0xadff, 0xae01, 0xae03, 0xae06, 
+    0xae08, 0xae0b, 0xae0d, 0xae10, 0xae12, 0xae14, 0xae17, 0xae19, 
+    0xae1c, 0xae1e, 0xae21, 0xae23, 0xae25, 0xae28, 0xae2a, 0xae2d, 
+    0xae2f, 0xae32, 0xae34, 0xae37, 0xae39, 0xae3c, 0xae3e, 0xae41, 
+    0xae43, 0xae46, 0xae48, 0xae4b, 0xae4d, 0xae4f, 0xae52, 0xae54, 
+    0xae57, 0xae59, 0xae5c, 0xae5e, 0xae61, 0xae63, 0xae66, 0xae68, 
+    0xae6b, 0xae6d, 0xae70, 0xae72, 0xae75, 0xae78, 0xae7a, 0xae7d, 
+    0xae7f, 0xae82, 0xae84, 0xae87, 0xae89, 0xae8c, 0xae8e, 0xae91, 
+    0xae93, 0xae96, 0xae98, 0xae9b, 0xae9e, 0xaea0, 0xaea3, 0xaea5, 
+    0xaea8, 0xaeaa, 0xaead, 0xaeaf, 0xaeb2, 0xaeb5, 0xaeb7, 0xaeba, 
+    0xaebc, 0xaebf, 0xaec2, 0xaec4, 0xaec7, 0xaec9, 0xaecc, 0xaece, 
+    0xaed1, 0xaed4, 0xaed6, 0xaed9, 0xaedb, 0xaede, 0xaee1, 0xaee3, 
+    0xaee6, 0xaee8, 0xaeeb, 0xaeee, 0xaef0, 0xaef3, 0xaef6, 0xaef8, 
+    0xaefb, 0xaefd, 0xaf00, 0xaf03, 0xaf05, 0xaf08, 0xaf0b, 0xaf0d, 
+    0xaf10, 0xaf13, 0xaf15, 0xaf18, 0xaf1a, 0xaf1d, 0xaf20, 0xaf22, 
+    0xaf25, 0xaf28, 0xaf2a, 0xaf2d, 0xaf30, 0xaf32, 0xaf35, 0xaf38, 
+    0xaf3a, 0xaf3d, 0xaf40, 0xaf43, 0xaf45, 0xaf48, 0xaf4b, 0xaf4d, 
+    0xaf50, 0xaf53, 0xaf55, 0xaf58, 0xaf5b, 0xaf5d, 0xaf60, 0xaf63, 
+    0xaf66, 0xaf68, 0xaf6b, 0xaf6e, 0xaf70, 0xaf73, 0xaf76, 0xaf79, 
+    0xaf7b, 0xaf7e, 0xaf81, 0xaf84, 0xaf86, 0xaf89, 0xaf8c, 0xaf8f, 
+    0xaf91, 0xaf94, 0xaf97, 0xaf9a, 0xaf9c, 0xaf9f, 0xafa2, 0xafa5, 
+    0xafa7, 0xafaa, 0xafad, 0xafb0, 0xafb2, 0xafb5, 0xafb8, 0xafbb, 
+    0xafbd, 0xafc0, 0xafc3, 0xafc6, 0xafc9, 0xafcb, 0xafce, 0xafd1, 
+    0xafd4, 0xafd7, 0xafd9, 0xafdc, 0xafdf, 0xafe2, 0xafe5, 0xafe7, 
+    0xafea, 0xafed, 0xaff0, 0xaff3, 0xaff6, 0xaff8, 0xaffb, 0xaffe, 
+    0xb000, 0xb002, 0xb003, 0xb005, 0xb006, 0xb007, 0xb009, 0xb00a, 
+    0xb00c, 0xb00d, 0xb00f, 0xb010, 0xb011, 0xb013, 0xb014, 0xb016, 
+    0xb017, 0xb019, 0xb01a, 0xb01b, 0xb01d, 0xb01e, 0xb020, 0xb021, 
+    0xb023, 0xb024, 0xb026, 0xb027, 0xb028, 0xb02a, 0xb02b, 0xb02d, 
+    0xb02e, 0xb030, 0xb031, 0xb033, 0xb034, 0xb036, 0xb037, 0xb038, 
+    0xb03a, 0xb03b, 0xb03d, 0xb03e, 0xb040, 0xb041, 0xb043, 0xb044, 
+    0xb046, 0xb047, 0xb049, 0xb04a, 0xb04b, 0xb04d, 0xb04e, 0xb050, 
+    0xb051, 0xb053, 0xb054, 0xb056, 0xb057, 0xb059, 0xb05a, 0xb05c, 
+    0xb05d, 0xb05f, 0xb060, 0xb062, 0xb063, 0xb065, 0xb066, 0xb068, 
+    0xb069, 0xb06b, 0xb06c, 0xb06e, 0xb06f, 0xb071, 0xb072, 0xb074, 
+    0xb075, 0xb077, 0xb078, 0xb07a, 0xb07b, 0xb07d, 0xb07e, 0xb080, 
+    0xb081, 0xb083, 0xb084, 0xb086, 0xb087, 0xb089, 0xb08a, 0xb08c, 
+    0xb08d, 0xb08f, 0xb090, 0xb092, 0xb093, 0xb095, 0xb096, 0xb098, 
+    0xb099, 0xb09b, 0xb09c, 0xb09e, 0xb0a0, 0xb0a1, 0xb0a3, 0xb0a4, 
+    0xb0a6, 0xb0a7, 0xb0a9, 0xb0aa, 0xb0ac, 0xb0ad, 0xb0af, 0xb0b0, 
+    0xb0b2, 0xb0b4, 0xb0b5, 0xb0b7, 0xb0b8, 0xb0ba, 0xb0bb, 0xb0bd, 
+    0xb0be, 0xb0c0, 0xb0c2, 0xb0c3, 0xb0c5, 0xb0c6, 0xb0c8, 0xb0c9, 
+    0xb0cb, 0xb0cc, 0xb0ce, 0xb0d0, 0xb0d1, 0xb0d3, 0xb0d4, 0xb0d6, 
+    0xb0d7, 0xb0d9, 0xb0db, 0xb0dc, 0xb0de, 0xb0df, 0xb0e1, 0xb0e2, 
+    0xb0e4, 0xb0e6, 0xb0e7, 0xb0e9, 0xb0ea, 0xb0ec, 0xb0ed, 0xb0ef, 
+    0xb0f1, 0xb0f2, 0xb0f4, 0xb0f5, 0xb0f7, 0xb0f9, 0xb0fa, 0xb0fc, 
+    0xb0fd, 0xb0ff, 0xb101, 0xb102, 0xb104, 0xb105, 0xb107, 0xb109, 
+    0xb10a, 0xb10c, 0xb10d, 0xb10f, 0xb111, 0xb112, 0xb114, 0xb115, 
+    0xb117, 0xb119, 0xb11a, 0xb11c, 0xb11e, 0xb11f, 0xb121, 0xb122, 
+    0xb124, 0xb126, 0xb127, 0xb129, 0xb12b, 0xb12c, 0xb12e, 0xb12f, 
+    0xb131, 0xb133, 0xb134, 0xb136, 0xb138, 0xb139, 0xb13b, 0xb13c, 
+    0xb13e, 0xb140, 0xb141, 0xb143, 0xb145, 0xb146, 0xb148, 0xb14a, 
+    0xb14b, 0xb14d, 0xb14f, 0xb150, 0xb152, 0xb154, 0xb155, 0xb157, 
+    0xb159, 0xb15a, 0xb15c, 0xb15e, 0xb15f, 0xb161, 0xb162, 0xb164, 
+    0xb166, 0xb167, 0xb169, 0xb16b, 0xb16c, 0xb16e, 0xb170, 0xb172, 
+    0xb173, 0xb175, 0xb177, 0xb178, 0xb17a, 0xb17c, 0xb17d, 0xb17f, 
+    0xb181, 0xb182, 0xb184, 0xb186, 0xb187, 0xb189, 0xb18b, 0xb18c, 
+    0xb18e, 0xb190, 0xb192, 0xb193, 0xb195, 0xb197, 0xb198, 0xb19a, 
+    0xb19c, 0xb19d, 0xb19f, 0xb1a1, 0xb1a3, 0xb1a4, 0xb1a6, 0xb1a8, 
+    0xb1a9, 0xb1ab, 0xb1ad, 0xb1af, 0xb1b0, 0xb1b2, 0xb1b4, 0xb1b5, 
+    0xb1b7, 0xb1b9, 0xb1bb, 0xb1bc, 0xb1be, 0xb1c0, 0xb1c1, 0xb1c3, 
+    0xb1c5, 0xb1c7, 0xb1c8, 0xb1ca, 0xb1cc, 0xb1ce, 0xb1cf, 0xb1d1, 
+    0xb1d3, 0xb1d4, 0xb1d6, 0xb1d8, 0xb1da, 0xb1db, 0xb1dd, 0xb1df, 
+    0xb1e1, 0xb1e2, 0xb1e4, 0xb1e6, 0xb1e8, 0xb1e9, 0xb1eb, 0xb1ed, 
+    0xb1ef, 0xb1f0, 0xb1f2, 0xb1f4, 0xb1f6, 0xb1f7, 0xb1f9, 0xb1fb, 
+    0xb1fd, 0xb1ff, 0xb200, 0xb202, 0xb204, 0xb206, 0xb207, 0xb209, 
+    0xb20b, 0xb20d, 0xb20e, 0xb210, 0xb212, 0xb214, 0xb216, 0xb217, 
+    0xb219, 0xb21b, 0xb21d, 0xb21e, 0xb220, 0xb222, 0xb224, 0xb226, 
+    0xb227, 0xb229, 0xb22b, 0xb22d, 0xb22f, 0xb230, 0xb232, 0xb234, 
+    0xb236, 0xb238, 0xb239, 0xb23b, 0xb23d, 0xb23f, 0xb241, 0xb242, 
+    0xb244, 0xb246, 0xb248, 0xb24a, 0xb24b, 0xb24d, 0xb24f, 0xb251, 
+    0xb253, 0xb254, 0xb256, 0xb258, 0xb25a, 0xb25c, 0xb25e, 0xb25f, 
+    0xb261, 0xb263, 0xb265, 0xb267, 0xb269, 0xb26a, 0xb26c, 0xb26e, 
+    0xb270, 0xb272, 0xb274, 0xb275, 0xb277, 0xb279, 0xb27b, 0xb27d, 
+    0xb27f, 0xb280, 0xb282, 0xb284, 0xb286, 0xb288, 0xb28a, 0xb28c, 
+    0xb28d, 0xb28f, 0xb291, 0xb293, 0xb295, 0xb297, 0xb299, 0xb29a, 
+    0xb29c, 0xb29e, 0xb2a0, 0xb2a2, 0xb2a4, 0xb2a6, 0xb2a7, 0xb2a9, 
+    0xb2ab, 0xb2ad, 0xb2af, 0xb2b1, 0xb2b3, 0xb2b5, 0xb2b6, 0xb2b8, 
+    0xb2ba, 0xb2bc, 0xb2be, 0xb2c0, 0xb2c2, 0xb2c4, 0xb2c5, 0xb2c7, 
+    0xb2c9, 0xb2cb, 0xb2cd, 0xb2cf, 0xb2d1, 0xb2d3, 0xb2d5, 0xb2d6, 
+    0xb2d8, 0xb2da, 0xb2dc, 0xb2de, 0xb2e0, 0xb2e2, 0xb2e4, 0xb2e6, 
+    0xb2e8, 0xb2ea, 0xb2eb, 0xb2ed, 0xb2ef, 0xb2f1, 0xb2f3, 0xb2f5, 
+    0xb2f7, 0xb2fb, 0xb2ff, 0xb302, 0xb306, 0xb30a, 0xb30e, 0xb312, 
+    0xb316, 0xb31a, 0xb31d, 0xb321, 0xb325, 0xb329, 0xb32d, 0xb331, 
+    0xb335, 0xb339, 0xb33d, 0xb340, 0xb344, 0xb348, 0xb34c, 0xb350, 
+    0xb354, 0xb358, 0xb35c, 0xb360, 0xb364, 0xb368, 0xb36c, 0xb370, 
+    0xb374, 0xb378, 0xb37c, 0xb380, 0xb384, 0xb388, 0xb38c, 0xb390, 
+    0xb394, 0xb398, 0xb39c, 0xb3a0, 0xb3a4, 0xb3a8, 0xb3ac, 0xb3b0, 
+    0xb3b4, 0xb3b8, 0xb3bc, 0xb3c0, 0xb3c4, 0xb3c8, 0xb3cc, 0xb3d0, 
+    0xb3d4, 0xb3d9, 0xb3dd, 0xb3e1, 0xb3e5, 0xb3e9, 0xb3ed, 0xb3f1, 
+    0xb3f5, 0xb3f9, 0xb3fe, 0xb401, 0xb403, 0xb405, 0xb407, 0xb409, 
+    0xb40b, 0xb40d, 0xb40f, 0xb411, 0xb414, 0xb416, 0xb418, 0xb41a, 
+    0xb41c, 0xb41e, 0xb420, 0xb422, 0xb424, 0xb426, 0xb428, 0xb42b, 
+    0xb42d, 0xb42f, 0xb431, 0xb433, 0xb435, 0xb437, 0xb439, 0xb43c, 
+    0xb43e, 0xb440, 0xb442, 0xb444, 0xb446, 0xb448, 0xb44b, 0xb44d, 
+    0xb44f, 0xb451, 0xb453, 0xb455, 0xb457, 0xb45a, 0xb45c, 0xb45e, 
+    0xb460, 0xb462, 0xb464, 0xb467, 0xb469, 0xb46b, 0xb46d, 0xb46f, 
+    0xb472, 0xb474, 0xb476, 0xb478, 0xb47a, 0xb47d, 0xb47f, 0xb481, 
+    0xb483, 0xb485, 0xb488, 0xb48a, 0xb48c, 0xb48e, 0xb490, 0xb493, 
+    0xb495, 0xb497, 0xb499, 0xb49c, 0xb49e, 0xb4a0, 0xb4a2, 0xb4a4, 
+    0xb4a7, 0xb4a9, 0xb4ab, 0xb4ad, 0xb4b0, 0xb4b2, 0xb4b4, 0xb4b6, 
+    0xb4b9, 0xb4bb, 0xb4bd, 0xb4c0, 0xb4c2, 0xb4c4, 0xb4c6, 0xb4c9, 
+    0xb4cb, 0xb4cd, 0xb4cf, 0xb4d2, 0xb4d4, 0xb4d6, 0xb4d9, 0xb4db, 
+    0xb4dd, 0xb4e0, 0xb4e2, 0xb4e4, 0xb4e6, 0xb4e9, 0xb4eb, 0xb4ed, 
+    0xb4f0, 0xb4f2, 0xb4f4, 0xb4f7, 0xb4f9, 0xb4fb, 0xb4fe, 0xb500, 
+    0xb502, 0xb505, 0xb507, 0xb509, 0xb50c, 0xb50e, 0xb510, 0xb513, 
+    0xb515, 0xb517, 0xb51a, 0xb51c, 0xb51e, 0xb521, 0xb523, 0xb526, 
+    0xb528, 0xb52a, 0xb52d, 0xb52f, 0xb531, 0xb534, 0xb536, 0xb539, 
+    0xb53b, 0xb53d, 0xb540, 0xb542, 0xb545, 0xb547, 0xb549, 0xb54c, 
+    0xb54e, 0xb551, 0xb553, 0xb555, 0xb558, 0xb55a, 0xb55d, 0xb55f, 
+    0xb562, 0xb564, 0xb566, 0xb569, 0xb56b, 0xb56e, 0xb570, 0xb573, 
+    0xb575, 0xb577, 0xb57a, 0xb57c, 0xb57f, 0xb581, 0xb584, 0xb586, 
+    0xb589, 0xb58b, 0xb58e, 0xb590, 0xb593, 0xb595, 0xb598, 0xb59a, 
+    0xb59d, 0xb59f, 0xb5a1, 0xb5a4, 0xb5a6, 0xb5a9, 0xb5ab, 0xb5ae, 
+    0xb5b0, 0xb5b3, 0xb5b5, 0xb5b8, 0xb5ba, 0xb5bd, 0xb5c0, 0xb5c2, 
+    0xb5c5, 0xb5c7, 0xb5ca, 0xb5cc, 0xb5cf, 0xb5d1, 0xb5d4, 0xb5d6, 
+    0xb5d9, 0xb5db, 0xb5de, 0xb5e0, 0xb5e3, 0xb5e6, 0xb5e8, 0xb5eb, 
+    0xb5ed, 0xb5f0, 0xb5f2, 0xb5f5, 0xb5f7, 0xb5fa, 0xb5fd, 0xb5ff, 
+    0xb602, 0xb604, 0xb607, 0xb60a, 0xb60c, 0xb60f, 0xb611, 0xb614, 
+    0xb616, 0xb619, 0xb61c, 0xb61e, 0xb621, 0xb623, 0xb626, 0xb629, 
+    0xb62b, 0xb62e, 0xb631, 0xb633, 0xb636, 0xb638, 0xb63b, 0xb63e, 
+    0xb640, 0xb643, 0xb646, 0xb648, 0xb64b, 0xb64e, 0xb650, 0xb653, 
+    0xb655, 0xb658, 0xb65b, 0xb65d, 0xb660, 0xb663, 0xb665, 0xb668, 
+    0xb66b, 0xb66d, 0xb670, 0xb673, 0xb676, 0xb678, 0xb67b, 0xb67e, 
+    0xb680, 0xb683, 0xb686, 0xb688, 0xb68b, 0xb68e, 0xb690, 0xb693, 
+    0xb696, 0xb699, 0xb69b, 0xb69e, 0xb6a1, 0xb6a3, 0xb6a6, 0xb6a9, 
+    0xb6ac, 0xb6ae, 0xb6b1, 0xb6b4, 0xb6b7, 0xb6b9, 0xb6bc, 0xb6bf, 
+    0xb6c2, 0xb6c4, 0xb6c7, 0xb6ca, 0xb6cd, 0xb6cf, 0xb6d2, 0xb6d5, 
+    0xb6d8, 0xb6da, 0xb6dd, 0xb6e0, 0xb6e3, 0xb6e5, 0xb6e8, 0xb6eb, 
+    0xb6ee, 0xb6f1, 0xb6f3, 0xb6f6, 0xb6f9, 0xb6fc, 0xb6ff, 0xb701, 
+    0xb704, 0xb707, 0xb70a, 0xb70d, 0xb70f, 0xb712, 0xb715, 0xb718, 
+    0xb71b, 0xb71e, 0xb720, 0xb723, 0xb726, 0xb729, 0xb72c, 0xb72f, 
+    0xb731, 0xb734, 0xb737, 0xb73a, 0xb73d, 0xb740, 0xb743, 0xb745, 
+    0xb748, 0xb74b, 0xb74e, 0xb751, 0xb754, 0xb757, 0xb759, 0xb75c, 
+    0xb75f, 0xb762, 0xb765, 0xb768, 0xb76b, 0xb76e, 0xb771, 0xb774, 
+    0xb776, 0xb779, 0xb77c, 0xb77f, 0xb782, 0xb785, 0xb788, 0xb78b, 
+    0xb78e, 0xb791, 0xb794, 0xb796, 0xb799, 0xb79c, 0xb79f, 0xb7a2, 
+    0xb7a5, 0xb7a8, 0xb7ab, 0xb7ae, 0xb7b1, 0xb7b4, 0xb7b7, 0xb7ba, 
+    0xb7bd, 0xb7c0, 0xb7c3, 0xb7c6, 0xb7c9, 0xb7cc, 0xb7cf, 0xb7d2, 
+    0xb7d5, 0xb7d7, 0xb7da, 0xb7dd, 0xb7e0, 0xb7e3, 0xb7e6, 0xb7e9, 
+    0xb7ec, 0xb7ef, 0xb7f2, 0xb7f5, 0xb7f8, 0xb7fb, 0xb7fe, 0xb801, 
+    0xb802, 0xb804, 0xb805, 0xb807, 0xb808, 0xb80a, 0xb80b, 0xb80d, 
+    0xb80e, 0xb810, 0xb811, 0xb813, 0xb814, 0xb816, 0xb817, 0xb819, 
+    0xb81b, 0xb81c, 0xb81e, 0xb81f, 0xb821, 0xb822, 0xb824, 0xb825, 
+    0xb827, 0xb828, 0xb82a, 0xb82b, 0xb82d, 0xb82f, 0xb830, 0xb832, 
+    0xb833, 0xb835, 0xb836, 0xb838, 0xb839, 0xb83b, 0xb83c, 0xb83e, 
+    0xb840, 0xb841, 0xb843, 0xb844, 0xb846, 0xb847, 0xb849, 0xb84b, 
+    0xb84c, 0xb84e, 0xb84f, 0xb851, 0xb852, 0xb854, 0xb856, 0xb857, 
+    0xb859, 0xb85a, 0xb85c, 0xb85d, 0xb85f, 0xb861, 0xb862, 0xb864, 
+    0xb865, 0xb867, 0xb869, 0xb86a, 0xb86c, 0xb86d, 0xb86f, 0xb870, 
+    0xb872, 0xb874, 0xb875, 0xb877, 0xb878, 0xb87a, 0xb87c, 0xb87d, 
+    0xb87f, 0xb880, 0xb882, 0xb884, 0xb885, 0xb887, 0xb889, 0xb88a, 
+    0xb88c, 0xb88d, 0xb88f, 0xb891, 0xb892, 0xb894, 0xb895, 0xb897, 
+    0xb899, 0xb89a, 0xb89c, 0xb89e, 0xb89f, 0xb8a1, 0xb8a3, 0xb8a4, 
+    0xb8a6, 0xb8a7, 0xb8a9, 0xb8ab, 0xb8ac, 0xb8ae, 0xb8b0, 0xb8b1, 
+    0xb8b3, 0xb8b5, 0xb8b6, 0xb8b8, 0xb8ba, 0xb8bb, 0xb8bd, 0xb8be, 
+    0xb8c0, 0xb8c2, 0xb8c3, 0xb8c5, 0xb8c7, 0xb8c8, 0xb8ca, 0xb8cc, 
+    0xb8cd, 0xb8cf, 0xb8d1, 0xb8d2, 0xb8d4, 0xb8d6, 0xb8d7, 0xb8d9, 
+    0xb8db, 0xb8dc, 0xb8de, 0xb8e0, 0xb8e1, 0xb8e3, 0xb8e5, 0xb8e7, 
+    0xb8e8, 0xb8ea, 0xb8ec, 0xb8ed, 0xb8ef, 0xb8f1, 0xb8f2, 0xb8f4, 
+    0xb8f6, 0xb8f7, 0xb8f9, 0xb8fb, 0xb8fd, 0xb8fe, 0xb900, 0xb902, 
+    0xb903, 0xb905, 0xb907, 0xb908, 0xb90a, 0xb90c, 0xb90e, 0xb90f, 
+    0xb911, 0xb913, 0xb914, 0xb916, 0xb918, 0xb91a, 0xb91b, 0xb91d, 
+    0xb91f, 0xb920, 0xb922, 0xb924, 0xb926, 0xb927, 0xb929, 0xb92b, 
+    0xb92d, 0xb92e, 0xb930, 0xb932, 0xb934, 0xb935, 0xb937, 0xb939, 
+    0xb93b, 0xb93c, 0xb93e, 0xb940, 0xb942, 0xb943, 0xb945, 0xb947, 
+    0xb949, 0xb94a, 0xb94c, 0xb94e, 0xb950, 0xb951, 0xb953, 0xb955, 
+    0xb957, 0xb958, 0xb95a, 0xb95c, 0xb95e, 0xb95f, 0xb961, 0xb963, 
+    0xb965, 0xb967, 0xb968, 0xb96a, 0xb96c, 0xb96e, 0xb96f, 0xb971, 
+    0xb973, 0xb975, 0xb977, 0xb978, 0xb97a, 0xb97c, 0xb97e, 0xb97f, 
+    0xb981, 0xb983, 0xb985, 0xb987, 0xb988, 0xb98a, 0xb98c, 0xb98e, 
+    0xb990, 0xb991, 0xb993, 0xb995, 0xb997, 0xb999, 0xb99b, 0xb99c, 
+    0xb99e, 0xb9a0, 0xb9a2, 0xb9a4, 0xb9a5, 0xb9a7, 0xb9a9, 0xb9ab, 
+    0xb9ad, 0xb9af, 0xb9b0, 0xb9b2, 0xb9b4, 0xb9b6, 0xb9b8, 0xb9ba, 
+    0xb9bb, 0xb9bd, 0xb9bf, 0xb9c1, 0xb9c3, 0xb9c5, 0xb9c6, 0xb9c8, 
+    0xb9ca, 0xb9cc, 0xb9ce, 0xb9d0, 0xb9d1, 0xb9d3, 0xb9d5, 0xb9d7, 
+    0xb9d9, 0xb9db, 0xb9dd, 0xb9de, 0xb9e0, 0xb9e2, 0xb9e4, 0xb9e6, 
+    0xb9e8, 0xb9ea, 0xb9eb, 0xb9ed, 0xb9ef, 0xb9f1, 0xb9f3, 0xb9f5, 
+    0xb9f7, 0xb9f9, 0xb9fa, 0xb9fc, 0xb9fe, 0xba00, 0xba02, 0xba04, 
+    0xba06, 0xba08, 0xba09, 0xba0b, 0xba0d, 0xba0f, 0xba11, 0xba13, 
+    0xba15, 0xba17, 0xba19, 0xba1b, 0xba1c, 0xba1e, 0xba20, 0xba22, 
+    0xba24, 0xba26, 0xba28, 0xba2a, 0xba2c, 0xba2e, 0xba2f, 0xba31, 
+    0xba33, 0xba35, 0xba37, 0xba39, 0xba3b, 0xba3d, 0xba3f, 0xba41, 
+    0xba43, 0xba45, 0xba47, 0xba48, 0xba4a, 0xba4c, 0xba4e, 0xba50, 
+    0xba52, 0xba54, 0xba56, 0xba58, 0xba5a, 0xba5c, 0xba5e, 0xba60, 
+    0xba62, 0xba64, 0xba66, 0xba67, 0xba69, 0xba6b, 0xba6d, 0xba6f, 
+    0xba71, 0xba73, 0xba75, 0xba77, 0xba79, 0xba7b, 0xba7d, 0xba7f, 
+    0xba81, 0xba83, 0xba85, 0xba87, 0xba89, 0xba8b, 0xba8d, 0xba8f, 
+    0xba91, 0xba93, 0xba95, 0xba97, 0xba99, 0xba9b, 0xba9d, 0xba9f, 
+    0xbaa0, 0xbaa2, 0xbaa4, 0xbaa6, 0xbaa8, 0xbaaa, 0xbaac, 0xbaae, 
+    0xbab0, 0xbab2, 0xbab4, 0xbab6, 0xbab8, 0xbaba, 0xbabc, 0xbabe, 
+    0xbac0, 0xbac2, 0xbac4, 0xbac6, 0xbac8, 0xbaca, 0xbacc, 0xbace, 
+    0xbad1, 0xbad3, 0xbad5, 0xbad7, 0xbad9, 0xbadb, 0xbadd, 0xbadf, 
+    0xbae1, 0xbae3, 0xbae5, 0xbae7, 0xbae9, 0xbaeb, 0xbaed, 0xbaef, 
+    0xbaf1, 0xbaf3, 0xbaf5, 0xbaf7, 0xbaf9, 0xbafb, 0xbafd, 0xbaff, 
+    0xbb01, 0xbb03, 0xbb05, 0xbb07, 0xbb09, 0xbb0b, 0xbb0e, 0xbb10, 
+    0xbb12, 0xbb14, 0xbb16, 0xbb18, 0xbb1a, 0xbb1c, 0xbb1e, 0xbb20, 
+    0xbb22, 0xbb24, 0xbb26, 0xbb28, 0xbb2a, 0xbb2c, 0xbb2f, 0xbb31, 
+    0xbb33, 0xbb35, 0xbb37, 0xbb39, 0xbb3b, 0xbb3d, 0xbb3f, 0xbb41, 
+    0xbb43, 0xbb45, 0xbb48, 0xbb4a, 0xbb4c, 0xbb4e, 0xbb50, 0xbb52, 
+    0xbb54, 0xbb56, 0xbb58, 0xbb5a, 0xbb5d, 0xbb5f, 0xbb61, 0xbb63, 
+    0xbb65, 0xbb67, 0xbb69, 0xbb6b, 0xbb6d, 0xbb6f, 0xbb72, 0xbb74, 
+    0xbb76, 0xbb78, 0xbb7a, 0xbb7c, 0xbb7e, 0xbb80, 0xbb83, 0xbb85, 
+    0xbb87, 0xbb89, 0xbb8b, 0xbb8d, 0xbb8f, 0xbb91, 0xbb94, 0xbb96, 
+    0xbb98, 0xbb9a, 0xbb9c, 0xbb9e, 0xbba0, 0xbba3, 0xbba5, 0xbba7, 
+    0xbba9, 0xbbab, 0xbbad, 0xbbaf, 0xbbb2, 0xbbb4, 0xbbb6, 0xbbb8, 
+    0xbbba, 0xbbbc, 0xbbbf, 0xbbc1, 0xbbc3, 0xbbc5, 0xbbc7, 0xbbc9, 
+    0xbbcc, 0xbbce, 0xbbd0, 0xbbd2, 0xbbd4, 0xbbd6, 0xbbd9, 0xbbdb, 
+    0xbbdd, 0xbbdf, 0xbbe1, 0xbbe4, 0xbbe6, 0xbbe8, 0xbbea, 0xbbec, 
+    0xbbee, 0xbbf1, 0xbbf3, 0xbbf5, 0xbbf7, 0xbbf9, 0xbbfc, 0xbbfe, 
+    0xbc00, 0xbc02, 0xbc04, 0xbc07, 0xbc09, 0xbc0b, 0xbc0d, 0xbc10, 
+    0xbc12, 0xbc14, 0xbc16, 0xbc18, 0xbc1b, 0xbc1d, 0xbc1f, 0xbc22, 
+    0xbc24, 0xbc26, 0xbc28, 0xbc2b, 0xbc2d, 0xbc2f, 0xbc32, 0xbc34, 
+    0xbc36, 0xbc39, 0xbc3b, 0xbc3d, 0xbc3f, 0xbc42, 0xbc44, 0xbc47, 
+    0xbc49, 0xbc4b, 0xbc4e, 0xbc50, 0xbc52, 0xbc55, 0xbc57, 0xbc59, 
+    0xbc5c, 0xbc5e, 0xbc61, 0xbc63, 0xbc66, 0xbc68, 0xbc6a, 0xbc6d, 
+    0xbc6f, 0xbc72, 0xbc74, 0xbc77, 0xbc79, 0xbc7b, 0xbc7e, 0xbc80, 
+    0xbc83, 0xbc85, 0xbc88, 0xbc8a, 0xbc8d, 0xbc8f, 0xbc92, 0xbc94, 
+    0xbc97, 0xbc99, 0xbc9c, 0xbc9f, 0xbca1, 0xbca4, 0xbca6, 0xbca9, 
+    0xbcab, 0xbcae, 0xbcb0, 0xbcb3, 0xbcb6, 0xbcb8, 0xbcbb, 0xbcbd, 
+    0xbcc0, 0xbcc3, 0xbcc5, 0xbcc8, 0xbccb, 0xbccd, 0xbcd0, 0xbcd2, 
+    0xbcd5, 0xbcd8, 0xbcda, 0xbcdd, 0xbce0, 0xbce2, 0xbce5, 0xbce8, 
+    0xbceb, 0xbced, 0xbcf0, 0xbcf3, 0xbcf5, 0xbcf8, 0xbcfb, 0xbcfe, 
+    0xbd00, 0xbd03, 0xbd06, 0xbd09, 0xbd0b, 0xbd0e, 0xbd11, 0xbd14, 
+    0xbd17, 0xbd19, 0xbd1c, 0xbd1f, 0xbd22, 0xbd25, 0xbd27, 0xbd2a, 
+    0xbd2d, 0xbd30, 0xbd33, 0xbd36, 0xbd39, 0xbd3b, 0xbd3e, 0xbd41, 
+    0xbd44, 0xbd47, 0xbd4a, 0xbd4d, 0xbd50, 0xbd53, 0xbd56, 0xbd59, 
+    0xbd5b, 0xbd5e, 0xbd61, 0xbd64, 0xbd67, 0xbd6a, 0xbd6d, 0xbd70, 
+    0xbd73, 0xbd76, 0xbd79, 0xbd7c, 0xbd7f, 0xbd82, 0xbd85, 0xbd88, 
+    0xbd8b, 0xbd8f, 0xbd92, 0xbd95, 0xbd98, 0xbd9b, 0xbd9e, 0xbda1, 
+    0xbda4, 0xbda7, 0xbdaa, 0xbdad, 0xbdb1, 0xbdb4, 0xbdb7, 0xbdba, 
+    0xbdbd, 0xbdc0, 0xbdc3, 0xbdc7, 0xbdca, 0xbdcd, 0xbdd0, 0xbdd3, 
+    0xbdd7, 0xbdda, 0xbddd, 0xbde0, 0xbde3, 0xbde7, 0xbdea, 0xbded, 
+    0xbdf0, 0xbdf4, 0xbdf7, 0xbdfa, 0xbdfe, 0xbe01, 0xbe04, 0xbe08, 
+    0xbe0b, 0xbe0e, 0xbe12, 0xbe15, 0xbe18, 0xbe1c, 0xbe1f, 0xbe22, 
+    0xbe26, 0xbe29, 0xbe2c, 0xbe30, 0xbe33, 0xbe37, 0xbe3a, 0xbe3e, 
+    0xbe41, 0xbe44, 0xbe48, 0xbe4b, 0xbe4f, 0xbe52, 0xbe56, 0xbe59, 
+    0xbe5d, 0xbe60, 0xbe64, 0xbe67, 0xbe6b, 0xbe6e, 0xbe72, 0xbe75, 
+    0xbe79, 0xbe7c, 0xbe80, 0xbe84, 0xbe87, 0xbe8b, 0xbe8e, 0xbe92, 
+    0xbe96, 0xbe99, 0xbe9d, 0xbea1, 0xbea4, 0xbea8, 0xbeac, 0xbeaf, 
+    0xbeb3, 0xbeb7, 0xbeba, 0xbebe, 0xbec2, 0xbec5, 0xbec9, 0xbecd, 
+    0xbed1, 0xbed4, 0xbed8, 0xbedc, 0xbee0, 0xbee3, 0xbee7, 0xbeeb, 
+    0xbeef, 0xbef3, 0xbef6, 0xbefa, 0xbefe, 0xbf02, 0xbf06, 0xbf0a, 
+    0xbf0e, 0xbf12, 0xbf15, 0xbf19, 0xbf1d, 0xbf21, 0xbf25, 0xbf29, 
+    0xbf2d, 0xbf31, 0xbf35, 0xbf39, 0xbf3d, 0xbf41, 0xbf45, 0xbf49, 
+    0xbf4d, 0xbf51, 0xbf55, 0xbf59, 0xbf5d, 0xbf61, 0xbf65, 0xbf69, 
+    0xbf6d, 0xbf71, 0xbf75, 0xbf79, 0xbf7e, 0xbf82, 0xbf86, 0xbf8a, 
+    0xbf8e, 0xbf92, 0xbf96, 0xbf9b, 0xbf9f, 0xbfa3, 0xbfa7, 0xbfab, 
+    0xbfb0, 0xbfb4, 0xbfb8, 0xbfbc, 0xbfc1, 0xbfc5, 0xbfc9, 0xbfcd, 
+    0xbfd2, 0xbfd6, 0xbfda, 0xbfdf, 0xbfe3, 0xbfe7, 0xbfec, 0xbff0, 
+    0xbff4, 0xbff9, 0xbffd, 0xc001, 0xc003, 0xc005, 0xc007, 0xc00a, 
+    0xc00c, 0xc00e, 0xc010, 0xc013, 0xc015, 0xc017, 0xc019, 0xc01c, 
+    0xc01e, 0xc020, 0xc022, 0xc025, 0xc027, 0xc029, 0xc02c, 0xc02e, 
+    0xc030, 0xc032, 0xc035, 0xc037, 0xc039, 0xc03c, 0xc03e, 0xc040, 
+    0xc043, 0xc045, 0xc047, 0xc04a, 0xc04c, 0xc04e, 0xc051, 0xc053, 
+    0xc056, 0xc058, 0xc05a, 0xc05d, 0xc05f, 0xc062, 0xc064, 0xc066, 
+    0xc069, 0xc06b, 0xc06e, 0xc070, 0xc073, 0xc075, 0xc077, 0xc07a, 
+    0xc07c, 0xc07f, 0xc081, 0xc084, 0xc086, 0xc089, 0xc08b, 0xc08e, 
+    0xc090, 0xc093, 0xc095, 0xc098, 0xc09a, 0xc09d, 0xc09f, 0xc0a2, 
+    0xc0a5, 0xc0a7, 0xc0aa, 0xc0ac, 0xc0af, 0xc0b1, 0xc0b4, 0xc0b7, 
+    0xc0b9, 0xc0bc, 0xc0be, 0xc0c1, 0xc0c4, 0xc0c6, 0xc0c9, 0xc0cc, 
+    0xc0ce, 0xc0d1, 0xc0d3, 0xc0d6, 0xc0d9, 0xc0db, 0xc0de, 0xc0e1, 
+    0xc0e3, 0xc0e6, 0xc0e9, 0xc0ec, 0xc0ee, 0xc0f1, 0xc0f4, 0xc0f6, 
+    0xc0f9, 0xc0fc, 0xc0ff, 0xc101, 0xc104, 0xc107, 0xc10a, 0xc10c, 
+    0xc10f, 0xc112, 0xc115, 0xc118, 0xc11a, 0xc11d, 0xc120, 0xc123, 
+    0xc126, 0xc129, 0xc12b, 0xc12e, 0xc131, 0xc134, 0xc137, 0xc13a, 
+    0xc13d, 0xc13f, 0xc142, 0xc145, 0xc148, 0xc14b, 0xc14e, 0xc151, 
+    0xc154, 0xc157, 0xc15a, 0xc15d, 0xc160, 0xc163, 0xc165, 0xc168, 
+    0xc16b, 0xc16e, 0xc171, 0xc174, 0xc177, 0xc17a, 0xc17d, 0xc180, 
+    0xc183, 0xc187, 0xc18a, 0xc18d, 0xc190, 0xc193, 0xc196, 0xc199, 
+    0xc19c, 0xc19f, 0xc1a2, 0xc1a5, 0xc1a8, 0xc1ab, 0xc1af, 0xc1b2, 
+    0xc1b5, 0xc1b8, 0xc1bb, 0xc1be, 0xc1c1, 0xc1c5, 0xc1c8, 0xc1cb, 
+    0xc1ce, 0xc1d1, 0xc1d5, 0xc1d8, 0xc1db, 0xc1de, 0xc1e1, 0xc1e5, 
+    0xc1e8, 0xc1eb, 0xc1ee, 0xc1f2, 0xc1f5, 0xc1f8, 0xc1fc, 0xc1ff, 
+    0xc202, 0xc205, 0xc209, 0xc20c, 0xc20f, 0xc213, 0xc216, 0xc219, 
+    0xc21d, 0xc220, 0xc224, 0xc227, 0xc22a, 0xc22e, 0xc231, 0xc235, 
+    0xc238, 0xc23b, 0xc23f, 0xc242, 0xc246, 0xc249, 0xc24d, 0xc250, 
+    0xc254, 0xc257, 0xc25a, 0xc25e, 0xc262, 0xc265, 0xc269, 0xc26c, 
+    0xc270, 0xc273, 0xc277, 0xc27a, 0xc27e, 0xc281, 0xc285, 0xc289, 
+    0xc28c, 0xc290, 0xc293, 0xc297, 0xc29b, 0xc29e, 0xc2a2, 0xc2a6, 
+    0xc2a9, 0xc2ad, 0xc2b1, 0xc2b4, 0xc2b8, 0xc2bc, 0xc2bf, 0xc2c3, 
+    0xc2c7, 0xc2cb, 0xc2ce, 0xc2d2, 0xc2d6, 0xc2da, 0xc2dd, 0xc2e1, 
+    0xc2e5, 0xc2e9, 0xc2ec, 0xc2f0, 0xc2f4, 0xc2f8, 0xc2fc, 0xc300, 
+    0xc303, 0xc307, 0xc30b, 0xc30f, 0xc313, 0xc317, 0xc31b, 0xc31f, 
+    0xc323, 0xc327, 0xc32a, 0xc32e, 0xc332, 0xc336, 0xc33a, 0xc33e, 
+    0xc342, 0xc346, 0xc34a, 0xc34e, 0xc352, 0xc356, 0xc35a, 0xc35e, 
+    0xc362, 0xc367, 0xc36b, 0xc36f, 0xc373, 0xc377, 0xc37b, 0xc37f, 
+    0xc383, 0xc387, 0xc38c, 0xc390, 0xc394, 0xc398, 0xc39c, 0xc3a0, 
+    0xc3a5, 0xc3a9, 0xc3ad, 0xc3b1, 0xc3b5, 0xc3ba, 0xc3be, 0xc3c2, 
+    0xc3c6, 0xc3cb, 0xc3cf, 0xc3d3, 0xc3d8, 0xc3dc, 0xc3e0, 0xc3e5, 
+    0xc3e9, 0xc3ed, 0xc3f2, 0xc3f6, 0xc3fa, 0xc3ff, 0xc402, 0xc404, 
+    0xc406, 0xc408, 0xc40a, 0xc40d, 0xc40f, 0xc411, 0xc413, 0xc416, 
+    0xc418, 0xc41a, 0xc41c, 0xc41f, 0xc421, 0xc423, 0xc426, 0xc428, 
+    0xc42a, 0xc42c, 0xc42f, 0xc431, 0xc433, 0xc436, 0xc438, 0xc43a, 
+    0xc43d, 0xc43f, 0xc441, 0xc444, 0xc446, 0xc448, 0xc44b, 0xc44d, 
+    0xc44f, 0xc452, 0xc454, 0xc456, 0xc459, 0xc45b, 0xc45e, 0xc460, 
+    0xc462, 0xc465, 0xc467, 0xc46a, 0xc46c, 0xc46f, 0xc471, 0xc473, 
+    0xc476, 0xc478, 0xc47b, 0xc47d, 0xc480, 0xc482, 0xc485, 0xc487, 
+    0xc48a, 0xc48c, 0xc48f, 0xc491, 0xc494, 0xc496, 0xc499, 0xc49b, 
+    0xc49e, 0xc4a0, 0xc4a3, 0xc4a6, 0xc4a8, 0xc4ab, 0xc4ad, 0xc4b0, 
+    0xc4b2, 0xc4b5, 0xc4b8, 0xc4ba, 0xc4bd, 0xc4bf, 0xc4c2, 0xc4c5, 
+    0xc4c7, 0xc4ca, 0xc4cc, 0xc4cf, 0xc4d2, 0xc4d4, 0xc4d7, 0xc4da, 
+    0xc4dc, 0xc4df, 0xc4e2, 0xc4e4, 0xc4e7, 0xc4ea, 0xc4ed, 0xc4ef, 
+    0xc4f2, 0xc4f5, 0xc4f7, 0xc4fa, 0xc4fd, 0xc500, 0xc502, 0xc505, 
+    0xc508, 0xc50b, 0xc50d, 0xc510, 0xc513, 0xc516, 0xc519, 0xc51b, 
+    0xc51e, 0xc521, 0xc524, 0xc527, 0xc52a, 0xc52c, 0xc52f, 0xc532, 
+    0xc535, 0xc538, 0xc53b, 0xc53e, 0xc540, 0xc543, 0xc546, 0xc549, 
+    0xc54c, 0xc54f, 0xc552, 0xc555, 0xc558, 0xc55b, 0xc55e, 0xc561, 
+    0xc564, 0xc567, 0xc56a, 0xc56d, 0xc570, 0xc573, 0xc576, 0xc579, 
+    0xc57c, 0xc57f, 0xc582, 0xc585, 0xc588, 0xc58b, 0xc58e, 0xc591, 
+    0xc594, 0xc597, 0xc59a, 0xc59d, 0xc5a0, 0xc5a3, 0xc5a6, 0xc5a9, 
+    0xc5ad, 0xc5b0, 0xc5b3, 0xc5b6, 0xc5b9, 0xc5bc, 0xc5bf, 0xc5c3, 
+    0xc5c6, 0xc5c9, 0xc5cc, 0xc5cf, 0xc5d3, 0xc5d6, 0xc5d9, 0xc5dc, 
+    0xc5df, 0xc5e3, 0xc5e6, 0xc5e9, 0xc5ec, 0xc5f0, 0xc5f3, 0xc5f6, 
+    0xc5f9, 0xc5fd, 0xc600, 0xc603, 0xc607, 0xc60a, 0xc60d, 0xc611, 
+    0xc614, 0xc617, 0xc61b, 0xc61e, 0xc621, 0xc625, 0xc628, 0xc62c, 
+    0xc62f, 0xc632, 0xc636, 0xc639, 0xc63d, 0xc640, 0xc643, 0xc647, 
+    0xc64a, 0xc64e, 0xc651, 0xc655, 0xc658, 0xc65c, 0xc65f, 0xc663, 
+    0xc666, 0xc66a, 0xc66d, 0xc671, 0xc674, 0xc678, 0xc67c, 0xc67f, 
+    0xc683, 0xc686, 0xc68a, 0xc68e, 0xc691, 0xc695, 0xc698, 0xc69c, 
+    0xc6a0, 0xc6a3, 0xc6a7, 0xc6ab, 0xc6ae, 0xc6b2, 0xc6b6, 0xc6b9, 
+    0xc6bd, 0xc6c1, 0xc6c4, 0xc6c8, 0xc6cc, 0xc6d0, 0xc6d3, 0xc6d7, 
+    0xc6db, 0xc6df, 0xc6e2, 0xc6e6, 0xc6ea, 0xc6ee, 0xc6f2, 0xc6f6, 
+    0xc6f9, 0xc6fd, 0xc701, 0xc705, 0xc709, 0xc70d, 0xc711, 0xc714, 
+    0xc718, 0xc71c, 0xc720, 0xc724, 0xc728, 0xc72c, 0xc730, 0xc734, 
+    0xc738, 0xc73c, 0xc740, 0xc744, 0xc748, 0xc74c, 0xc750, 0xc754, 
+    0xc758, 0xc75c, 0xc760, 0xc764, 0xc768, 0xc76c, 0xc770, 0xc774, 
+    0xc778, 0xc77d, 0xc781, 0xc785, 0xc789, 0xc78d, 0xc791, 0xc795, 
+    0xc79a, 0xc79e, 0xc7a2, 0xc7a6, 0xc7aa, 0xc7af, 0xc7b3, 0xc7b7, 
+    0xc7bb, 0xc7c0, 0xc7c4, 0xc7c8, 0xc7cc, 0xc7d1, 0xc7d5, 0xc7d9, 
+    0xc7de, 0xc7e2, 0xc7e6, 0xc7eb, 0xc7ef, 0xc7f3, 0xc7f8, 0xc7fc, 
+    0xc800, 0xc802, 0xc805, 0xc807, 0xc809, 0xc80b, 0xc80e, 0xc810, 
+    0xc812, 0xc814, 0xc816, 0xc819, 0xc81b, 0xc81d, 0xc820, 0xc822, 
+    0xc824, 0xc826, 0xc829, 0xc82b, 0xc82d, 0xc830, 0xc832, 0xc834, 
+    0xc836, 0xc839, 0xc83b, 0xc83d, 0xc840, 0xc842, 0xc844, 0xc847, 
+    0xc849, 0xc84c, 0xc84e, 0xc850, 0xc853, 0xc855, 0xc857, 0xc85a, 
+    0xc85c, 0xc85f, 0xc861, 0xc863, 0xc866, 0xc868, 0xc86b, 0xc86d, 
+    0xc870, 0xc872, 0xc874, 0xc877, 0xc879, 0xc87c, 0xc87e, 0xc881, 
+    0xc883, 0xc888, 0xc88d, 0xc892, 0xc897, 0xc89c, 0xc8a1, 0xc8a6, 
+    0xc8ac, 0xc8b1, 0xc8b6, 0xc8bb, 0xc8c0, 0xc8c6, 0xc8cb, 0xc8d0, 
+    0xc8d5, 0xc8db, 0xc8e0, 0xc8e5, 0xc8eb, 0xc8f0, 0xc8f6, 0xc8fb, 
+    0xc901, 0xc906, 0xc90c, 0xc911, 0xc917, 0xc91d, 0xc922, 0xc928, 
+    0xc92d, 0xc933, 0xc939, 0xc93f, 0xc944, 0xc94a, 0xc950, 0xc956, 
+    0xc95c, 0xc962, 0xc968, 0xc96e, 0xc974, 0xc97a, 0xc980, 0xc986, 
+    0xc98c, 0xc992, 0xc998, 0xc99e, 0xc9a4, 0xc9ab, 0xc9b1, 0xc9b7, 
+    0xc9bd, 0xc9c4, 0xc9ca, 0xc9d1, 0xc9d7, 0xc9dd, 0xc9e4, 0xc9ea, 
+    0xc9f1, 0xc9f7, 0xc9fe, 0xca05, 0xca0b, 0xca12, 0xca19, 0xca1f, 
+    0xca26, 0xca2d, 0xca34, 0xca3a, 0xca41, 0xca48, 0xca4f, 0xca56, 
+    0xca5d, 0xca64, 0xca6b, 0xca72, 0xca79, 0xca80, 0xca88, 0xca8f, 
+    0xca96, 0xca9d, 0xcaa5, 0xcaac, 0xcab3, 0xcabb, 0xcac2, 0xcaca, 
+    0xcad1, 0xcad9, 0xcae0, 0xcae8, 0xcaef, 0xcaf7, 0xcaff, 0xcb06, 
+    0xcb0e, 0xcb16, 0xcb1e, 0xcb25, 0xcb2d, 0xcb35, 0xcb3d, 0xcb45, 
+    0xcb4d, 0xcb55, 0xcb5d, 0xcb65, 0xcb6e, 0xcb76, 0xcb7e, 0xcb86, 
+    0xcb8f, 0xcb97, 0xcb9f, 0xcba8, 0xcbb0, 0xcbb9, 0xcbc1, 0xcbca, 
+    0xcbd2, 0xcbdb, 0xcbe4, 0xcbec, 0xcbf5, 0xcbfe, 0xcc03, 0xcc08, 
+    0xcc0c, 0xcc11, 0xcc15, 0xcc1a, 0xcc1e, 0xcc23, 0xcc27, 0xcc2c, 
+    0xcc30, 0xcc35, 0xcc3a, 0xcc3e, 0xcc43, 0xcc48, 0xcc4c, 0xcc51, 
+    0xcc56, 0xcc5b, 0xcc5f, 0xcc64, 0xcc69, 0xcc6e, 0xcc73, 0xcc78, 
+    0xcc7d, 0xcc82, 0xcc87, 0xcc8c, 0xcc91, 0xcc96, 0xcc9b, 0xcca0, 
+    0xcca5, 0xccaa, 0xccaf, 0xccb4, 0xccb9, 0xccbf, 0xccc4, 0xccc9, 
+    0xccce, 0xccd4, 0xccd9, 0xccde, 0xcce4, 0xcce9, 0xccef, 0xccf4, 
+    0xccf9, 0xccff, 0xcd04, 0xcd0a, 0xcd10, 0xcd15, 0xcd1b, 0xcd20, 
+    0xcd26, 0xcd2c, 0xcd31, 0xcd37, 0xcd3d, 0xcd43, 0xcd48, 0xcd4e, 
+    0xcd54, 0xcd5a, 0xcd60, 0xcd66, 0xcd6c, 0xcd72, 0xcd78, 0xcd7e, 
+    0xcd84, 0xcd8a, 0xcd90, 0xcd96, 0xcd9c, 0xcda2, 0xcda9, 0xcdaf, 
+    0xcdb5, 0xcdbb, 0xcdc2, 0xcdc8, 0xcdcf, 0xcdd5, 0xcddb, 0xcde2, 
+    0xcde8, 0xcdef, 0xcdf5, 0xcdfc, 0xce03, 0xce09, 0xce10, 0xce16, 
+    0xce1d, 0xce24, 0xce2b, 0xce31, 0xce38, 0xce3f, 0xce46, 0xce4d, 
+    0xce54, 0xce5b, 0xce62, 0xce69, 0xce70, 0xce77, 0xce7e, 0xce85, 
+    0xce8d, 0xce94, 0xce9b, 0xcea2, 0xceaa, 0xceb1, 0xceb8, 0xcec0, 
+    0xcec7, 0xcecf, 0xced6, 0xcede, 0xcee5, 0xceed, 0xcef5, 0xcefc, 
+    0xcf04, 0xcf0c, 0xcf13, 0xcf1b, 0xcf23, 0xcf2b, 0xcf33, 0xcf3b, 
+    0xcf43, 0xcf4b, 0xcf53, 0xcf5b, 0xcf63, 0xcf6b, 0xcf73, 0xcf7b, 
+    0xcf84, 0xcf8c, 0xcf94, 0xcf9d, 0xcfa5, 0xcfad, 0xcfb6, 0xcfbe, 
+    0xcfc7, 0xcfd0, 0xcfd8, 0xcfe1, 0xcfe9, 0xcff2, 0xcffb, 0xd002, 
+    0xd006, 0xd00b, 0xd00f, 0xd014, 0xd018, 0xd01d, 0xd021, 0xd026, 
+    0xd02a, 0xd02f, 0xd034, 0xd038, 0xd03d, 0xd041, 0xd046, 0xd04b, 
+    0xd050, 0xd054, 0xd059, 0xd05e, 0xd063, 0xd068, 0xd06c, 0xd071, 
+    0xd076, 0xd07b, 0xd080, 0xd085, 0xd08a, 0xd08f, 0xd094, 0xd099, 
+    0xd09e, 0xd0a3, 0xd0a8, 0xd0ae, 0xd0b3, 0xd0b8, 0xd0bd, 0xd0c2, 
+    0xd0c8, 0xd0cd, 0xd0d2, 0xd0d7, 0xd0dd, 0xd0e2, 0xd0e7, 0xd0ed, 
+    0xd0f2, 0xd0f8, 0xd0fd, 0xd103, 0xd108, 0xd10e, 0xd113, 0xd119, 
+    0xd11f, 0xd124, 0xd12a, 0xd130, 0xd135, 0xd13b, 0xd141, 0xd147, 
+    0xd14c, 0xd152, 0xd158, 0xd15e, 0xd164, 0xd16a, 0xd170, 0xd176, 
+    0xd17c, 0xd182, 0xd188, 0xd18e, 0xd194, 0xd19a, 0xd1a1, 0xd1a7, 
+    0xd1ad, 0xd1b3, 0xd1ba, 0xd1c0, 0xd1c6, 0xd1cd, 0xd1d3, 0xd1d9, 
+    0xd1e0, 0xd1e6, 0xd1ed, 0xd1f3, 0xd1fa, 0xd200, 0xd207, 0xd20e, 
+    0xd214, 0xd21b, 0xd222, 0xd229, 0xd22f, 0xd236, 0xd23d, 0xd244, 
+    0xd24b, 0xd252, 0xd259, 0xd260, 0xd267, 0xd26e, 0xd275, 0xd27c, 
+    0xd283, 0xd28a, 0xd292, 0xd299, 0xd2a0, 0xd2a7, 0xd2af, 0xd2b6, 
+    0xd2bd, 0xd2c5, 0xd2cc, 0xd2d4, 0xd2db, 0xd2e3, 0xd2ea, 0xd2f2, 
+    0xd2fa, 0xd301, 0xd309, 0xd311, 0xd319, 0xd321, 0xd328, 0xd330, 
+    0xd338, 0xd340, 0xd348, 0xd350, 0xd358, 0xd360, 0xd369, 0xd371, 
+    0xd379, 0xd381, 0xd389, 0xd392, 0xd39a, 0xd3a2, 0xd3ab, 0xd3b3, 
+    0xd3bc, 0xd3c4, 0xd3cd, 0xd3d5, 0xd3de, 0xd3e7, 0xd3ef, 0xd3f8, 
+    0xd401, 0xd405, 0xd409, 0xd40e, 0xd412, 0xd417, 0xd41b, 0xd420, 
+    0xd424, 0xd429, 0xd42d, 0xd432, 0xd437, 0xd43b, 0xd440, 0xd445, 
+    0xd449, 0xd44e, 0xd453, 0xd458, 0xd45c, 0xd461, 0xd466, 0xd46b, 
+    0xd470, 0xd475, 0xd47a, 0xd47f, 0xd483, 0xd488, 0xd48d, 0xd492, 
+    0xd498, 0xd49d, 0xd4a2, 0xd4a7, 0xd4ac, 0xd4b1, 0xd4b6, 0xd4bb, 
+    0xd4c1, 0xd4c6, 0xd4cb, 0xd4d0, 0xd4d6, 0xd4db, 0xd4e0, 0xd4e6, 
+    0xd4eb, 0xd4f1, 0xd4f6, 0xd4fc, 0xd501, 0xd507, 0xd50c, 0xd512, 
+    0xd517, 0xd51d, 0xd522, 0xd528, 0xd52e, 0xd534, 0xd539, 0xd53f, 
+    0xd545, 0xd54b, 0xd550, 0xd556, 0xd55c, 0xd562, 0xd568, 0xd56e, 
+    0xd574, 0xd57a, 0xd580, 0xd586, 0xd58c, 0xd592, 0xd598, 0xd59f, 
+    0xd5a5, 0xd5ab, 0xd5b1, 0xd5b8, 0xd5be, 0xd5c4, 0xd5cb, 0xd5d1, 
+    0xd5d7, 0xd5de, 0xd5e4, 0xd5eb, 0xd5f1, 0xd5f8, 0xd5fe, 0xd605, 
+    0xd60c, 0xd612, 0xd619, 0xd620, 0xd626, 0xd62d, 0xd634, 0xd63b, 
+    0xd642, 0xd649, 0xd650, 0xd657, 0xd65d, 0xd665, 0xd66c, 0xd673, 
+    0xd67a, 0xd681, 0xd688, 0xd68f, 0xd696, 0xd69e, 0xd6a5, 0xd6ac, 
+    0xd6b4, 0xd6bb, 0xd6c3, 0xd6ca, 0xd6d1, 0xd6d9, 0xd6e1, 0xd6e8, 
+    0xd6f0, 0xd6f7, 0xd6ff, 0xd707, 0xd70f, 0xd716, 0xd71e, 0xd726, 
+    0xd72e, 0xd736, 0xd73e, 0xd746, 0xd74e, 0xd756, 0xd75e, 0xd766, 
+    0xd76e, 0xd776, 0xd77f, 0xd787, 0xd78f, 0xd797, 0xd7a0, 0xd7a8, 
+    0xd7b1, 0xd7b9, 0xd7c2, 0xd7ca, 0xd7d3, 0xd7db, 0xd7e4, 0xd7ed, 
+    0xd7f5, 0xd7fe, 0xd804, 0xd808, 0xd80c, 0xd811, 0xd815, 0xd81a, 
+    0xd81e, 0xd823, 0xd827, 0xd82c, 0xd831, 0xd835, 0xd83a, 0xd83f, 
+    0xd843, 0xd848, 0xd84d, 0xd851, 0xd856, 0xd85b, 0xd860, 0xd865, 
+    0xd869, 0xd86e, 0xd873, 0xd878, 0xd87d, 0xd882, 0xd887, 0xd88c, 
+    0xd891, 0xd896, 0xd89b, 0xd8a0, 0xd8a5, 0xd8aa, 0xd8af, 0xd8b5, 
+    0xd8ba, 0xd8bf, 0xd8c4, 0xd8c9, 0xd8cf, 0xd8d4, 0xd8d9, 0xd8df, 
+    0xd8e4, 0xd8e9, 0xd8ef, 0xd8f4, 0xd8fa, 0xd8ff, 0xd905, 0xd90a, 
+    0xd910, 0xd915, 0xd91b, 0xd921, 0xd926, 0xd92c, 0xd932, 0xd937, 
+    0xd93d, 0xd943, 0xd949, 0xd94f, 0xd954, 0xd95a, 0xd960, 0xd966, 
+    0xd96c, 0xd972, 0xd978, 0xd97e, 0xd984, 0xd98a, 0xd990, 0xd996, 
+    0xd99d, 0xd9a3, 0xd9a9, 0xd9af, 0xd9b6, 0xd9bc, 0xd9c2, 0xd9c9, 
+    0xd9cf, 0xd9d5, 0xd9dc, 0xd9e2, 0xd9e9, 0xd9ef, 0xd9f6, 0xd9fc, 
+    0xda03, 0xda0a, 0xda10, 0xda17, 0xda1e, 0xda24, 0xda2b, 0xda32, 
+    0xda39, 0xda40, 0xda46, 0xda4d, 0xda54, 0xda5b, 0xda62, 0xda69, 
+    0xda70, 0xda78, 0xda7f, 0xda86, 0xda8d, 0xda94, 0xda9b, 0xdaa3, 
+    0xdaaa, 0xdab1, 0xdab9, 0xdac0, 0xdac8, 0xdacf, 0xdad7, 0xdade, 
+    0xdae6, 0xdaed, 0xdaf5, 0xdafd, 0xdb04, 0xdb0c, 0xdb14, 0xdb1c, 
+    0xdb23, 0xdb2b, 0xdb33, 0xdb3b, 0xdb43, 0xdb4b, 0xdb53, 0xdb5b, 
+    0xdb63, 0xdb6c, 0xdb74, 0xdb7c, 0xdb84, 0xdb8c, 0xdb95, 0xdb9d, 
+    0xdba6, 0xdbae, 0xdbb6, 0xdbbf, 0xdbc7, 0xdbd0, 0xdbd9, 0xdbe1, 
+    0xdbea, 0xdbf3, 0xdbfb, 0xdc02, 0xdc07, 0xdc0b, 0xdc0f, 0xdc14, 
+    0xdc18, 0xdc1d, 0xdc21, 0xdc26, 0xdc2b, 0xdc2f, 0xdc34, 0xdc38, 
+    0xdc3d, 0xdc42, 0xdc46, 0xdc4b, 0xdc50, 0xdc55, 0xdc59, 0xdc5e, 
+    0xdc63, 0xdc68, 0xdc6d, 0xdc72, 0xdc77, 0xdc7b, 0xdc80, 0xdc85, 
+    0xdc8a, 0xdc8f, 0xdc94, 0xdc99, 0xdc9e, 0xdca4, 0xdca9, 0xdcae, 
+    0xdcb3, 0xdcb8, 0xdcbd, 0xdcc3, 0xdcc8, 0xdccd, 0xdcd2, 0xdcd8, 
+    0xdcdd, 0xdce2, 0xdce8, 0xdced, 0xdcf3, 0xdcf8, 0xdcfe, 0xdd03, 
+    0xdd09, 0xdd0e, 0xdd14, 0xdd19, 0xdd1f, 0xdd25, 0xdd2a, 0xdd30, 
+    0xdd36, 0xdd3b, 0xdd41, 0xdd47, 0xdd4d, 0xdd53, 0xdd58, 0xdd5e, 
+    0xdd64, 0xdd6a, 0xdd70, 0xdd76, 0xdd7c, 0xdd82, 0xdd88, 0xdd8e, 
+    0xdd95, 0xdd9b, 0xdda1, 0xdda7, 0xddad, 0xddb4, 0xddba, 0xddc0, 
+    0xddc7, 0xddcd, 0xddd3, 0xddda, 0xdde0, 0xdde7, 0xdded, 0xddf4, 
+    0xddfa, 0xde01, 0xde07, 0xde0e, 0xde15, 0xde1b, 0xde22, 0xde29, 
+    0xde30, 0xde37, 0xde3d, 0xde44, 0xde4b, 0xde52, 0xde59, 0xde60, 
+    0xde67, 0xde6e, 0xde75, 0xde7c, 0xde84, 0xde8b, 0xde92, 0xde99, 
+    0xdea0, 0xdea8, 0xdeaf, 0xdeb6, 0xdebe, 0xdec5, 0xdecd, 0xded4, 
+    0xdedc, 0xdee3, 0xdeeb, 0xdef3, 0xdefa, 0xdf02, 0xdf0a, 0xdf11, 
+    0xdf19, 0xdf21, 0xdf29, 0xdf31, 0xdf39, 0xdf41, 0xdf49, 0xdf51, 
+    0xdf59, 0xdf61, 0xdf69, 0xdf71, 0xdf79, 0xdf82, 0xdf8a, 0xdf92, 
+    0xdf9b, 0xdfa3, 0xdfab, 0xdfb4, 0xdfbc, 0xdfc5, 0xdfcd, 0xdfd6, 
+    0xdfdf, 0xdfe7, 0xdff0, 0xdff9, 0xe001, 0xe005, 0xe00a, 0xe00e, 
+    0xe013, 0xe017, 0xe01c, 0xe020, 0xe025, 0xe029, 0xe02e, 0xe032, 
+    0xe037, 0xe03c, 0xe040, 0xe045, 0xe04a, 0xe04e, 0xe053, 0xe058, 
+    0xe05d, 0xe062, 0xe066, 0xe06b, 0xe070, 0xe075, 0xe07a, 0xe07f, 
+    0xe084, 0xe089, 0xe08e, 0xe093, 0xe098, 0xe09d, 0xe0a2, 0xe0a7, 
+    0xe0ac, 0xe0b1, 0xe0b7, 0xe0bc, 0xe0c1, 0xe0c6, 0xe0cb, 0xe0d1, 
+    0xe0d6, 0xe0db, 0xe0e1, 0xe0e6, 0xe0eb, 0xe0f1, 0xe0f6, 0xe0fc, 
+    0xe101, 0xe107, 0xe10c, 0xe112, 0xe118, 0xe11d, 0xe123, 0xe128, 
+    0xe12e, 0xe134, 0xe13a, 0xe13f, 0xe145, 0xe14b, 0xe151, 0xe157, 
+    0xe15d, 0xe162, 0xe168, 0xe16e, 0xe174, 0xe17a, 0xe180, 0xe186, 
+    0xe18d, 0xe193, 0xe199, 0xe19f, 0xe1a5, 0xe1ab, 0xe1b2, 0xe1b8, 
+    0xe1be, 0xe1cb, 0xe1d8, 0xe1e5, 0xe1f2, 0xe1ff, 0xe20c, 0xe219, 
+    0xe227, 0xe234, 0xe242, 0xe250, 0xe25e, 0xe26c, 0xe27a, 0xe288, 
+    0xe297, 0xe2a5, 0xe2b4, 0xe2c3, 0xe2d2, 0xe2e1, 0xe2f0, 0xe2ff, 
+    0xe30f, 0xe31f, 0xe32e, 0xe33e, 0xe34e, 0xe35e, 0xe36f, 0xe37f, 
+    0xe390, 0xe3a0, 0xe3b1, 0xe3c2, 0xe3d3, 0xe3e5, 0xe3f6, 0xe404, 
+    0xe40d, 0xe416, 0xe41f, 0xe428, 0xe431, 0xe43a, 0xe444, 0xe44d, 
+    0xe456, 0xe460, 0xe46a, 0xe473, 0xe47d, 0xe487, 0xe491, 0xe49b, 
+    0xe4a5, 0xe4b0, 0xe4ba, 0xe4c5, 0xe4cf, 0xe4da, 0xe4e4, 0xe4ef, 
+    0xe4fa, 0xe505, 0xe510, 0xe51b, 0xe527, 0xe532, 0xe53e, 0xe549, 
+    0xe555, 0xe561, 0xe56c, 0xe578, 0xe585, 0xe591, 0xe59d, 0xe5a9, 
+    0xe5b6, 0xe5c3, 0xe5cf, 0xe5dc, 0xe5e9, 0xe5f6, 0xe603, 0xe611, 
+    0xe61e, 0xe62b, 0xe639, 0xe647, 0xe655, 0xe663, 0xe671, 0xe67f, 
+    0xe68d, 0xe69c, 0xe6aa, 0xe6b9, 0xe6c8, 0xe6d7, 0xe6e6, 0xe6f5, 
+    0xe705, 0xe714, 0xe724, 0xe734, 0xe744, 0xe754, 0xe764, 0xe774, 
+    0xe785, 0xe795, 0xe7a6, 0xe7b7, 0xe7c8, 0xe7d9, 0xe7ea, 0xe7fc, 
+    0xe807, 0xe810, 0xe819, 0xe822, 0xe82b, 0xe834, 0xe83d, 0xe847, 
+    0xe850, 0xe85a, 0xe863, 0xe86d, 0xe877, 0xe881, 0xe88b, 0xe895, 
+    0xe89f, 0xe8a9, 0xe8b3, 0xe8be, 0xe8c8, 0xe8d3, 0xe8dd, 0xe8e8, 
+    0xe8f3, 0xe8fe, 0xe909, 0xe914, 0xe91f, 0xe92b, 0xe936, 0xe941, 
+    0xe94d, 0xe959, 0xe965, 0xe971, 0xe97d, 0xe989, 0xe995, 0xe9a1, 
+    0xe9ae, 0xe9ba, 0xe9c7, 0xe9d4, 0xe9e1, 0xe9ee, 0xe9fb, 0xea08, 
+    0xea15, 0xea23, 0xea30, 0xea3e, 0xea4c, 0xea5a, 0xea68, 0xea76, 
+    0xea84, 0xea92, 0xeaa1, 0xeab0, 0xeabe, 0xeacd, 0xeadc, 0xeaeb, 
+    0xeafb, 0xeb0a, 0xeb1a, 0xeb29, 0xeb39, 0xeb49, 0xeb59, 0xeb69, 
+    0xeb7a, 0xeb8a, 0xeb9b, 0xebac, 0xebbd, 0xebce, 0xebdf, 0xebf0, 
+    0xec01, 0xec0a, 0xec13, 0xec1c, 0xec25, 0xec2e, 0xec37, 0xec41, 
+    0xec4a, 0xec53, 0xec5d, 0xec67, 0xec70, 0xec7a, 0xec84, 0xec8e, 
+    0xec98, 0xeca2, 0xecac, 0xecb7, 0xecc1, 0xeccc, 0xecd6, 0xece1, 
+    0xecec, 0xecf7, 0xed02, 0xed0d, 0xed18, 0xed23, 0xed2e, 0xed3a, 
+    0xed45, 0xed51, 0xed5d, 0xed69, 0xed75, 0xed81, 0xed8d, 0xed99, 
+    0xeda5, 0xedb2, 0xedbf, 0xedcb, 0xedd8, 0xede5, 0xedf2, 0xedff, 
+    0xee0c, 0xee1a, 0xee27, 0xee35, 0xee43, 0xee50, 0xee5e, 0xee6c, 
+    0xee7b, 0xee89, 0xee97, 0xeea6, 0xeeb5, 0xeec3, 0xeed2, 0xeee1, 
+    0xeef1, 0xef00, 0xef0f, 0xef1f, 0xef2f, 0xef3f, 0xef4f, 0xef5f, 
+    0xef6f, 0xef7f, 0xef90, 0xefa1, 0xefb2, 0xefc3, 0xefd4, 0xefe5, 
+    0xeff6, 0xf004, 0xf00d, 0xf016, 0xf01f, 0xf028, 0xf031, 0xf03a, 
+    0xf044, 0xf04d, 0xf057, 0xf060, 0xf06a, 0xf074, 0xf07e, 0xf087, 
+    0xf091, 0xf09c, 0xf0a6, 0xf0b0, 0xf0ba, 0xf0c5, 0xf0cf, 0xf0da, 
+    0xf0e5, 0xf0f0, 0xf0fa, 0xf105, 0xf111, 0xf11c, 0xf127, 0xf132, 
+    0xf13e, 0xf149, 0xf155, 0xf161, 0xf16d, 0xf179, 0xf185, 0xf191, 
+    0xf19d, 0xf1aa, 0xf1b6, 0xf1c3, 0xf1d0, 0xf1dc, 0xf1e9, 0xf1f6, 
+    0xf204, 0xf211, 0xf21e, 0xf22c, 0xf239, 0xf247, 0xf255, 0xf263, 
+    0xf271, 0xf27f, 0xf28e, 0xf29c, 0xf2ab, 0xf2ba, 0xf2c8, 0xf2d7, 
+    0xf2e7, 0xf2f6, 0xf305, 0xf315, 0xf324, 0xf334, 0xf344, 0xf354, 
+    0xf364, 0xf375, 0xf385, 0xf396, 0xf3a6, 0xf3b7, 0xf3c8, 0xf3da, 
+    0xf3eb, 0xf3fc, 0xf407, 0xf410, 0xf419, 0xf422, 0xf42b, 0xf434, 
+    0xf43e, 0xf447, 0xf450, 0xf45a, 0xf464, 0xf46d, 0xf477, 0xf481, 
+    0xf48b, 0xf495, 0xf49f, 0xf4a9, 0xf4b4, 0xf4be, 0xf4c8, 0xf4d3, 
+    0xf4de, 0xf4e8, 0xf4f3, 0xf4fe, 0xf509, 0xf514, 0xf520, 0xf52b, 
+    0xf536, 0xf542, 0xf54d, 0xf559, 0xf565, 0xf571, 0xf57d, 0xf589, 
+    0xf595, 0xf5a2, 0xf5ae, 0xf5bb, 0xf5c7, 0xf5d4, 0xf5e1, 0xf5ee, 
+    0xf5fb, 0xf608, 0xf616, 0xf623, 0xf631, 0xf63e, 0xf64c, 0xf65a, 
+    0xf668, 0xf676, 0xf684, 0xf693, 0xf6a1, 0xf6b0, 0xf6bf, 0xf6ce, 
+    0xf6dd, 0xf6ec, 0xf6fb, 0xf70b, 0xf71a, 0xf72a, 0xf73a, 0xf74a, 
+    0xf75a, 0xf76a, 0xf77a, 0xf78b, 0xf79b, 0xf7ac, 0xf7bd, 0xf7ce, 
+    0xf7e0, 0xf7f1, 0xf801, 0xf80a, 0xf813, 0xf81c, 0xf825, 0xf82e, 
+    0xf838, 0xf841, 0xf84a, 0xf854, 0xf85d, 0xf867, 0xf871, 0xf87a, 
+    0xf884, 0xf88e, 0xf898, 0xf8a3, 0xf8ad, 0xf8b7, 0xf8c2, 0xf8cc, 
+    0xf8d7, 0xf8e1, 0xf8ec, 0xf8f7, 0xf902, 0xf90d, 0xf918, 0xf923, 
+    0xf92f, 0xf93a, 0xf946, 0xf951, 0xf95d, 0xf969, 0xf975, 0xf981, 
+    0xf98d, 0xf999, 0xf9a6, 0xf9b2, 0xf9bf, 0xf9cc, 0xf9d8, 0xf9e5, 
+    0xf9f2, 0xf9ff, 0xfa0d, 0xfa1a, 0xfa28, 0xfa35, 0xfa43, 0xfa51, 
+    0xfa5f, 0xfa6d, 0xfa7b, 0xfa89, 0xfa98, 0xfaa6, 0xfab5, 0xfac4, 
+    0xfad3, 0xfae2, 0xfaf1, 0xfb00, 0xfb10, 0xfb1f, 0xfb2f, 0xfb3f, 
+    0xfb4f, 0xfb5f, 0xfb70, 0xfb80, 0xfb91, 0xfba1, 0xfbb2, 0xfbc3, 
+    0xfbd4, 0xfbe6, 0xfbf7, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+};
+
+
+
+const unsigned short dwaCompressorToNonlinear[] = 
+{
+    0x0000, 0x1043, 0x11d7, 0x1305, 0x1400, 0x146d, 0x14cf, 0x1529, 
+    0x157b, 0x15c8, 0x1611, 0x1656, 0x1697, 0x16d6, 0x1712, 0x174b, 
+    0x1783, 0x17b9, 0x17ed, 0x1810, 0x1828, 0x1840, 0x1857, 0x186e, 
+    0x1884, 0x189a, 0x18af, 0x18c4, 0x18d8, 0x18ec, 0x18ff, 0x1913, 
+    0x1926, 0x1938, 0x194a, 0x195c, 0x196e, 0x197f, 0x1991, 0x19a2, 
+    0x19b2, 0x19c3, 0x19d3, 0x19e3, 0x19f3, 0x1a02, 0x1a12, 0x1a21, 
+    0x1a30, 0x1a3f, 0x1a4e, 0x1a5c, 0x1a6b, 0x1a79, 0x1a87, 0x1a95, 
+    0x1aa3, 0x1ab1, 0x1abe, 0x1acc, 0x1ad9, 0x1ae7, 0x1af4, 0x1b01, 
+    0x1b0d, 0x1b1a, 0x1b27, 0x1b33, 0x1b40, 0x1b4c, 0x1b59, 0x1b65, 
+    0x1b71, 0x1b7d, 0x1b89, 0x1b94, 0x1ba0, 0x1bac, 0x1bb7, 0x1bc3, 
+    0x1bce, 0x1bda, 0x1be5, 0x1bf0, 0x1bfb, 0x1c03, 0x1c09, 0x1c0e, 
+    0x1c13, 0x1c19, 0x1c1e, 0x1c23, 0x1c29, 0x1c2e, 0x1c33, 0x1c38, 
+    0x1c3d, 0x1c43, 0x1c48, 0x1c4d, 0x1c52, 0x1c57, 0x1c5c, 0x1c61, 
+    0x1c66, 0x1c6b, 0x1c6f, 0x1c74, 0x1c79, 0x1c7e, 0x1c83, 0x1c87, 
+    0x1c8c, 0x1c91, 0x1c96, 0x1c9a, 0x1c9f, 0x1ca4, 0x1ca8, 0x1cad, 
+    0x1cb1, 0x1cb6, 0x1cba, 0x1cbf, 0x1cc3, 0x1cc8, 0x1ccc, 0x1cd1, 
+    0x1cd5, 0x1cd9, 0x1cde, 0x1ce2, 0x1ce7, 0x1ceb, 0x1cef, 0x1cf3, 
+    0x1cf8, 0x1cfc, 0x1d00, 0x1d04, 0x1d09, 0x1d0d, 0x1d11, 0x1d15, 
+    0x1d19, 0x1d1d, 0x1d21, 0x1d25, 0x1d29, 0x1d2e, 0x1d32, 0x1d36, 
+    0x1d3a, 0x1d3e, 0x1d42, 0x1d46, 0x1d49, 0x1d4d, 0x1d51, 0x1d55, 
+    0x1d59, 0x1d5d, 0x1d61, 0x1d65, 0x1d69, 0x1d6c, 0x1d70, 0x1d74, 
+    0x1d78, 0x1d7c, 0x1d7f, 0x1d83, 0x1d87, 0x1d8b, 0x1d8e, 0x1d92, 
+    0x1d96, 0x1d99, 0x1d9d, 0x1da1, 0x1da4, 0x1da8, 0x1dac, 0x1daf, 
+    0x1db3, 0x1db7, 0x1dba, 0x1dbe, 0x1dc1, 0x1dc5, 0x1dc8, 0x1dcc, 
+    0x1dcf, 0x1dd3, 0x1dd6, 0x1dda, 0x1ddd, 0x1de1, 0x1de4, 0x1de8, 
+    0x1deb, 0x1def, 0x1df2, 0x1df6, 0x1df9, 0x1dfc, 0x1e00, 0x1e03, 
+    0x1e07, 0x1e0a, 0x1e0d, 0x1e11, 0x1e14, 0x1e17, 0x1e1b, 0x1e1e, 
+    0x1e21, 0x1e25, 0x1e28, 0x1e2b, 0x1e2e, 0x1e32, 0x1e35, 0x1e38, 
+    0x1e3b, 0x1e3f, 0x1e42, 0x1e45, 0x1e48, 0x1e4b, 0x1e4f, 0x1e52, 
+    0x1e55, 0x1e58, 0x1e5b, 0x1e5f, 0x1e62, 0x1e65, 0x1e68, 0x1e6b, 
+    0x1e6e, 0x1e71, 0x1e74, 0x1e78, 0x1e7b, 0x1e7e, 0x1e81, 0x1e84, 
+    0x1e87, 0x1e8a, 0x1e8d, 0x1e90, 0x1e93, 0x1e96, 0x1e99, 0x1e9c, 
+    0x1e9f, 0x1ea2, 0x1ea5, 0x1ea8, 0x1eab, 0x1eae, 0x1eb1, 0x1eb4, 
+    0x1eb7, 0x1eba, 0x1ebd, 0x1ec0, 0x1ec3, 0x1ec6, 0x1ec9, 0x1ecc, 
+    0x1ecf, 0x1ed2, 0x1ed4, 0x1ed7, 0x1eda, 0x1edd, 0x1ee0, 0x1ee3, 
+    0x1ee6, 0x1ee9, 0x1eeb, 0x1eee, 0x1ef1, 0x1ef4, 0x1ef7, 0x1efa, 
+    0x1efc, 0x1eff, 0x1f02, 0x1f05, 0x1f08, 0x1f0b, 0x1f0d, 0x1f10, 
+    0x1f13, 0x1f16, 0x1f18, 0x1f1b, 0x1f1e, 0x1f21, 0x1f23, 0x1f26, 
+    0x1f29, 0x1f2c, 0x1f2e, 0x1f31, 0x1f34, 0x1f37, 0x1f39, 0x1f3c, 
+    0x1f3f, 0x1f41, 0x1f44, 0x1f47, 0x1f4a, 0x1f4c, 0x1f4f, 0x1f52, 
+    0x1f54, 0x1f57, 0x1f5a, 0x1f5c, 0x1f5f, 0x1f61, 0x1f64, 0x1f67, 
+    0x1f69, 0x1f6c, 0x1f6f, 0x1f71, 0x1f74, 0x1f76, 0x1f79, 0x1f7c, 
+    0x1f7e, 0x1f81, 0x1f83, 0x1f86, 0x1f89, 0x1f8b, 0x1f8e, 0x1f90, 
+    0x1f93, 0x1f95, 0x1f98, 0x1f9b, 0x1f9d, 0x1fa0, 0x1fa2, 0x1fa5, 
+    0x1fa7, 0x1faa, 0x1fac, 0x1faf, 0x1fb1, 0x1fb4, 0x1fb6, 0x1fb9, 
+    0x1fbb, 0x1fbe, 0x1fc0, 0x1fc3, 0x1fc5, 0x1fc8, 0x1fca, 0x1fcd, 
+    0x1fcf, 0x1fd2, 0x1fd4, 0x1fd7, 0x1fd9, 0x1fdc, 0x1fde, 0x1fe0, 
+    0x1fe3, 0x1fe5, 0x1fe8, 0x1fea, 0x1fed, 0x1fef, 0x1ff1, 0x1ff4, 
+    0x1ff6, 0x1ff9, 0x1ffb, 0x1ffe, 0x2000, 0x2001, 0x2002, 0x2004, 
+    0x2005, 0x2006, 0x2007, 0x2008, 0x200a, 0x200b, 0x200c, 0x200d, 
+    0x200e, 0x200f, 0x2011, 0x2012, 0x2013, 0x2014, 0x2015, 0x2016, 
+    0x2018, 0x2019, 0x201a, 0x201b, 0x201c, 0x201d, 0x201f, 0x2020, 
+    0x2021, 0x2022, 0x2023, 0x2024, 0x2026, 0x2027, 0x2028, 0x2029, 
+    0x202a, 0x202b, 0x202c, 0x202e, 0x202f, 0x2030, 0x2031, 0x2032, 
+    0x2033, 0x2034, 0x2035, 0x2037, 0x2038, 0x2039, 0x203a, 0x203b, 
+    0x203c, 0x203d, 0x203e, 0x2040, 0x2041, 0x2042, 0x2043, 0x2044, 
+    0x2045, 0x2046, 0x2047, 0x2048, 0x204a, 0x204b, 0x204c, 0x204d, 
+    0x204e, 0x204f, 0x2050, 0x2051, 0x2052, 0x2053, 0x2055, 0x2056, 
+    0x2057, 0x2058, 0x2059, 0x205a, 0x205b, 0x205c, 0x205d, 0x205e, 
+    0x205f, 0x2060, 0x2062, 0x2063, 0x2064, 0x2065, 0x2066, 0x2067, 
+    0x2068, 0x2069, 0x206a, 0x206b, 0x206c, 0x206d, 0x206e, 0x206f, 
+    0x2070, 0x2072, 0x2073, 0x2074, 0x2075, 0x2076, 0x2077, 0x2078, 
+    0x2079, 0x207a, 0x207b, 0x207c, 0x207d, 0x207e, 0x207f, 0x2080, 
+    0x2081, 0x2082, 0x2083, 0x2084, 0x2085, 0x2086, 0x2087, 0x2089, 
+    0x208a, 0x208b, 0x208c, 0x208d, 0x208e, 0x208f, 0x2090, 0x2091, 
+    0x2092, 0x2093, 0x2094, 0x2095, 0x2096, 0x2097, 0x2098, 0x2099, 
+    0x209a, 0x209b, 0x209c, 0x209d, 0x209e, 0x209f, 0x20a0, 0x20a1, 
+    0x20a2, 0x20a3, 0x20a4, 0x20a5, 0x20a6, 0x20a7, 0x20a8, 0x20a9, 
+    0x20aa, 0x20ab, 0x20ac, 0x20ad, 0x20ae, 0x20af, 0x20b0, 0x20b1, 
+    0x20b2, 0x20b3, 0x20b4, 0x20b5, 0x20b6, 0x20b7, 0x20b8, 0x20b9, 
+    0x20ba, 0x20bb, 0x20bc, 0x20bd, 0x20be, 0x20bf, 0x20c0, 0x20c1, 
+    0x20c2, 0x20c3, 0x20c4, 0x20c5, 0x20c6, 0x20c7, 0x20c7, 0x20c8, 
+    0x20c9, 0x20ca, 0x20cb, 0x20cc, 0x20cd, 0x20ce, 0x20cf, 0x20d0, 
+    0x20d1, 0x20d2, 0x20d3, 0x20d4, 0x20d5, 0x20d6, 0x20d7, 0x20d8, 
+    0x20d9, 0x20da, 0x20db, 0x20dc, 0x20dd, 0x20de, 0x20de, 0x20df, 
+    0x20e0, 0x20e1, 0x20e2, 0x20e3, 0x20e4, 0x20e5, 0x20e6, 0x20e7, 
+    0x20e8, 0x20e9, 0x20ea, 0x20eb, 0x20ec, 0x20ed, 0x20ee, 0x20ee, 
+    0x20ef, 0x20f0, 0x20f1, 0x20f2, 0x20f3, 0x20f4, 0x20f5, 0x20f6, 
+    0x20f7, 0x20f8, 0x20f9, 0x20fa, 0x20fb, 0x20fb, 0x20fc, 0x20fd, 
+    0x20fe, 0x20ff, 0x2100, 0x2101, 0x2102, 0x2103, 0x2104, 0x2105, 
+    0x2106, 0x2106, 0x2107, 0x2108, 0x2109, 0x210a, 0x210b, 0x210c, 
+    0x210d, 0x210e, 0x210f, 0x2110, 0x2110, 0x2111, 0x2112, 0x2113, 
+    0x2114, 0x2115, 0x2116, 0x2117, 0x2118, 0x2119, 0x2119, 0x211a, 
+    0x211b, 0x211c, 0x211d, 0x211e, 0x211f, 0x2120, 0x2121, 0x2121, 
+    0x2122, 0x2123, 0x2124, 0x2125, 0x2126, 0x2127, 0x2128, 0x2129, 
+    0x2129, 0x212a, 0x212b, 0x212c, 0x212d, 0x212e, 0x212f, 0x2130, 
+    0x2130, 0x2131, 0x2132, 0x2133, 0x2134, 0x2135, 0x2136, 0x2137, 
+    0x2137, 0x2138, 0x2139, 0x213a, 0x213b, 0x213c, 0x213d, 0x213e, 
+    0x213e, 0x213f, 0x2140, 0x2141, 0x2142, 0x2143, 0x2144, 0x2144, 
+    0x2145, 0x2146, 0x2147, 0x2148, 0x2149, 0x214a, 0x214b, 0x214b, 
+    0x214c, 0x214d, 0x214e, 0x214f, 0x2150, 0x2151, 0x2151, 0x2152, 
+    0x2153, 0x2154, 0x2155, 0x2156, 0x2156, 0x2157, 0x2158, 0x2159, 
+    0x215a, 0x215b, 0x215c, 0x215c, 0x215d, 0x215e, 0x215f, 0x2160, 
+    0x2161, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2166, 
+    0x2167, 0x2168, 0x2169, 0x216a, 0x216b, 0x216b, 0x216c, 0x216d, 
+    0x216e, 0x216f, 0x2170, 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 
+    0x2175, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x217a, 0x217a, 
+    0x217b, 0x217c, 0x217d, 0x217e, 0x217e, 0x217f, 0x2180, 0x2181, 
+    0x2182, 0x2183, 0x2183, 0x2184, 0x2185, 0x2186, 0x2187, 0x2187, 
+    0x2188, 0x2189, 0x218a, 0x218b, 0x218c, 0x218c, 0x218d, 0x218e, 
+    0x218f, 0x2190, 0x2190, 0x2191, 0x2192, 0x2193, 0x2194, 0x2194, 
+    0x2195, 0x2196, 0x2197, 0x2198, 0x2198, 0x2199, 0x219a, 0x219b, 
+    0x219c, 0x219c, 0x219d, 0x219e, 0x219f, 0x21a0, 0x21a0, 0x21a1, 
+    0x21a2, 0x21a3, 0x21a4, 0x21a4, 0x21a5, 0x21a6, 0x21a7, 0x21a8, 
+    0x21a8, 0x21a9, 0x21aa, 0x21ab, 0x21ac, 0x21ac, 0x21ad, 0x21ae, 
+    0x21af, 0x21af, 0x21b0, 0x21b1, 0x21b2, 0x21b3, 0x21b3, 0x21b4, 
+    0x21b5, 0x21b6, 0x21b7, 0x21b7, 0x21b8, 0x21b9, 0x21ba, 0x21ba, 
+    0x21bb, 0x21bc, 0x21bd, 0x21be, 0x21be, 0x21bf, 0x21c0, 0x21c1, 
+    0x21c1, 0x21c2, 0x21c3, 0x21c4, 0x21c5, 0x21c5, 0x21c6, 0x21c7, 
+    0x21c8, 0x21c8, 0x21c9, 0x21ca, 0x21cb, 0x21cb, 0x21cc, 0x21cd, 
+    0x21ce, 0x21cf, 0x21cf, 0x21d0, 0x21d1, 0x21d2, 0x21d2, 0x21d3, 
+    0x21d4, 0x21d5, 0x21d5, 0x21d6, 0x21d7, 0x21d8, 0x21d8, 0x21d9, 
+    0x21da, 0x21db, 0x21db, 0x21dc, 0x21dd, 0x21de, 0x21df, 0x21df, 
+    0x21e0, 0x21e1, 0x21e2, 0x21e2, 0x21e3, 0x21e4, 0x21e5, 0x21e5, 
+    0x21e6, 0x21e7, 0x21e8, 0x21e8, 0x21e9, 0x21ea, 0x21eb, 0x21eb, 
+    0x21ec, 0x21ed, 0x21ee, 0x21ee, 0x21ef, 0x21f0, 0x21f1, 0x21f1, 
+    0x21f2, 0x21f3, 0x21f4, 0x21f4, 0x21f5, 0x21f6, 0x21f7, 0x21f7, 
+    0x21f8, 0x21f9, 0x21f9, 0x21fa, 0x21fb, 0x21fc, 0x21fc, 0x21fd, 
+    0x21fe, 0x21ff, 0x21ff, 0x2200, 0x2201, 0x2202, 0x2202, 0x2203, 
+    0x2204, 0x2205, 0x2205, 0x2206, 0x2207, 0x2207, 0x2208, 0x2209, 
+    0x220a, 0x220a, 0x220b, 0x220c, 0x220d, 0x220d, 0x220e, 0x220f, 
+    0x2210, 0x2210, 0x2211, 0x2212, 0x2212, 0x2213, 0x2214, 0x2215, 
+    0x2215, 0x2216, 0x2217, 0x2218, 0x2218, 0x2219, 0x221a, 0x221a, 
+    0x221b, 0x221c, 0x221d, 0x221d, 0x221e, 0x221f, 0x221f, 0x2220, 
+    0x2221, 0x2222, 0x2222, 0x2223, 0x2224, 0x2224, 0x2225, 0x2226, 
+    0x2227, 0x2227, 0x2228, 0x2229, 0x222a, 0x222a, 0x222b, 0x222c, 
+    0x222c, 0x222d, 0x222e, 0x222e, 0x222f, 0x2230, 0x2231, 0x2231, 
+    0x2232, 0x2233, 0x2233, 0x2234, 0x2235, 0x2236, 0x2236, 0x2237, 
+    0x2238, 0x2238, 0x2239, 0x223a, 0x223b, 0x223b, 0x223c, 0x223d, 
+    0x223d, 0x223e, 0x223f, 0x223f, 0x2240, 0x2241, 0x2242, 0x2242, 
+    0x2243, 0x2244, 0x2244, 0x2245, 0x2246, 0x2246, 0x2247, 0x2248, 
+    0x2249, 0x2249, 0x224a, 0x224b, 0x224b, 0x224c, 0x224d, 0x224d, 
+    0x224e, 0x224f, 0x2250, 0x2250, 0x2251, 0x2252, 0x2252, 0x2253, 
+    0x2254, 0x2254, 0x2255, 0x2256, 0x2256, 0x2257, 0x2258, 0x2259, 
+    0x2259, 0x225a, 0x225b, 0x225b, 0x225c, 0x225d, 0x225d, 0x225e, 
+    0x225f, 0x225f, 0x2260, 0x2261, 0x2261, 0x2262, 0x2263, 0x2264, 
+    0x2264, 0x2265, 0x2266, 0x2266, 0x2267, 0x2268, 0x2268, 0x2269, 
+    0x226a, 0x226a, 0x226b, 0x226c, 0x226c, 0x226d, 0x226e, 0x226e, 
+    0x226f, 0x2270, 0x2270, 0x2271, 0x2272, 0x2272, 0x2273, 0x2274, 
+    0x2274, 0x2275, 0x2276, 0x2277, 0x2277, 0x2278, 0x2279, 0x2279, 
+    0x227a, 0x227b, 0x227b, 0x227c, 0x227d, 0x227d, 0x227e, 0x227f, 
+    0x227f, 0x2280, 0x2281, 0x2281, 0x2282, 0x2283, 0x2283, 0x2284, 
+    0x2285, 0x2285, 0x2286, 0x2287, 0x2287, 0x2288, 0x2289, 0x2289, 
+    0x228a, 0x228b, 0x228b, 0x228c, 0x228d, 0x228d, 0x228e, 0x228f, 
+    0x228f, 0x2290, 0x2291, 0x2291, 0x2292, 0x2293, 0x2293, 0x2294, 
+    0x2295, 0x2295, 0x2296, 0x2297, 0x2297, 0x2298, 0x2298, 0x2299, 
+    0x229a, 0x229a, 0x229b, 0x229c, 0x229c, 0x229d, 0x229e, 0x229e, 
+    0x229f, 0x22a0, 0x22a0, 0x22a1, 0x22a2, 0x22a2, 0x22a3, 0x22a4, 
+    0x22a4, 0x22a5, 0x22a6, 0x22a6, 0x22a7, 0x22a8, 0x22a8, 0x22a9, 
+    0x22aa, 0x22aa, 0x22ab, 0x22ab, 0x22ac, 0x22ad, 0x22ad, 0x22ae, 
+    0x22af, 0x22af, 0x22b0, 0x22b1, 0x22b1, 0x22b2, 0x22b3, 0x22b3, 
+    0x22b4, 0x22b5, 0x22b5, 0x22b6, 0x22b6, 0x22b7, 0x22b8, 0x22b8, 
+    0x22b9, 0x22ba, 0x22ba, 0x22bb, 0x22bc, 0x22bc, 0x22bd, 0x22be, 
+    0x22be, 0x22bf, 0x22bf, 0x22c0, 0x22c1, 0x22c1, 0x22c2, 0x22c3, 
+    0x22c3, 0x22c4, 0x22c5, 0x22c5, 0x22c6, 0x22c6, 0x22c7, 0x22c8, 
+    0x22c8, 0x22c9, 0x22ca, 0x22ca, 0x22cb, 0x22cc, 0x22cc, 0x22cd, 
+    0x22cd, 0x22ce, 0x22cf, 0x22cf, 0x22d0, 0x22d1, 0x22d1, 0x22d2, 
+    0x22d3, 0x22d3, 0x22d4, 0x22d4, 0x22d5, 0x22d6, 0x22d6, 0x22d7, 
+    0x22d8, 0x22d8, 0x22d9, 0x22d9, 0x22da, 0x22db, 0x22db, 0x22dc, 
+    0x22dd, 0x22dd, 0x22de, 0x22de, 0x22df, 0x22e0, 0x22e0, 0x22e1, 
+    0x22e2, 0x22e2, 0x22e3, 0x22e4, 0x22e4, 0x22e5, 0x22e5, 0x22e6, 
+    0x22e7, 0x22e7, 0x22e8, 0x22e8, 0x22e9, 0x22ea, 0x22ea, 0x22eb, 
+    0x22ec, 0x22ec, 0x22ed, 0x22ed, 0x22ee, 0x22ef, 0x22ef, 0x22f0, 
+    0x22f1, 0x22f1, 0x22f2, 0x22f2, 0x22f3, 0x22f4, 0x22f4, 0x22f5, 
+    0x22f6, 0x22f6, 0x22f7, 0x22f7, 0x22f8, 0x22f9, 0x22f9, 0x22fa, 
+    0x22fa, 0x22fb, 0x22fc, 0x22fc, 0x22fd, 0x22fe, 0x22fe, 0x22ff, 
+    0x22ff, 0x2300, 0x2301, 0x2301, 0x2302, 0x2302, 0x2303, 0x2304, 
+    0x2304, 0x2305, 0x2305, 0x2306, 0x2307, 0x2307, 0x2308, 0x2309, 
+    0x2309, 0x230a, 0x230a, 0x230b, 0x230c, 0x230c, 0x230d, 0x230d, 
+    0x230e, 0x230f, 0x230f, 0x2310, 0x2310, 0x2311, 0x2312, 0x2312, 
+    0x2313, 0x2313, 0x2314, 0x2315, 0x2315, 0x2316, 0x2316, 0x2317, 
+    0x2318, 0x2318, 0x2319, 0x2319, 0x231a, 0x231b, 0x231b, 0x231c, 
+    0x231d, 0x231d, 0x231e, 0x231e, 0x231f, 0x2320, 0x2320, 0x2321, 
+    0x2321, 0x2322, 0x2323, 0x2323, 0x2324, 0x2324, 0x2325, 0x2325, 
+    0x2326, 0x2327, 0x2327, 0x2328, 0x2328, 0x2329, 0x232a, 0x232a, 
+    0x232b, 0x232b, 0x232c, 0x232d, 0x232d, 0x232e, 0x232e, 0x232f, 
+    0x2330, 0x2330, 0x2331, 0x2331, 0x2332, 0x2333, 0x2333, 0x2334, 
+    0x2334, 0x2335, 0x2336, 0x2336, 0x2337, 0x2337, 0x2338, 0x2339, 
+    0x2339, 0x233a, 0x233a, 0x233b, 0x233b, 0x233c, 0x233d, 0x233d, 
+    0x233e, 0x233e, 0x233f, 0x2340, 0x2340, 0x2341, 0x2341, 0x2342, 
+    0x2343, 0x2343, 0x2344, 0x2344, 0x2345, 0x2345, 0x2346, 0x2347, 
+    0x2347, 0x2348, 0x2348, 0x2349, 0x234a, 0x234a, 0x234b, 0x234b, 
+    0x234c, 0x234c, 0x234d, 0x234e, 0x234e, 0x234f, 0x234f, 0x2350, 
+    0x2351, 0x2351, 0x2352, 0x2352, 0x2353, 0x2353, 0x2354, 0x2355, 
+    0x2355, 0x2356, 0x2356, 0x2357, 0x2357, 0x2358, 0x2359, 0x2359, 
+    0x235a, 0x235a, 0x235b, 0x235c, 0x235c, 0x235d, 0x235d, 0x235e, 
+    0x235e, 0x235f, 0x2360, 0x2360, 0x2361, 0x2361, 0x2362, 0x2362, 
+    0x2363, 0x2364, 0x2364, 0x2365, 0x2365, 0x2366, 0x2366, 0x2367, 
+    0x2368, 0x2368, 0x2369, 0x2369, 0x236a, 0x236a, 0x236b, 0x236c, 
+    0x236c, 0x236d, 0x236d, 0x236e, 0x236e, 0x236f, 0x2370, 0x2370, 
+    0x2371, 0x2371, 0x2372, 0x2372, 0x2373, 0x2374, 0x2374, 0x2375, 
+    0x2375, 0x2376, 0x2376, 0x2377, 0x2378, 0x2378, 0x2379, 0x2379, 
+    0x237a, 0x237a, 0x237b, 0x237c, 0x237c, 0x237d, 0x237d, 0x237e, 
+    0x237e, 0x237f, 0x237f, 0x2380, 0x2381, 0x2381, 0x2382, 0x2382, 
+    0x2383, 0x2383, 0x2384, 0x2385, 0x2385, 0x2386, 0x2386, 0x2387, 
+    0x2387, 0x2388, 0x2388, 0x2389, 0x238a, 0x238a, 0x238b, 0x238b, 
+    0x238c, 0x238c, 0x238d, 0x238e, 0x238e, 0x238f, 0x238f, 0x2390, 
+    0x2390, 0x2391, 0x2391, 0x2392, 0x2393, 0x2393, 0x2394, 0x2394, 
+    0x2395, 0x2395, 0x2396, 0x2396, 0x2397, 0x2398, 0x2398, 0x2399, 
+    0x2399, 0x239a, 0x239a, 0x239b, 0x239b, 0x239c, 0x239d, 0x239d, 
+    0x239e, 0x239e, 0x239f, 0x239f, 0x23a0, 0x23a0, 0x23a1, 0x23a2, 
+    0x23a2, 0x23a3, 0x23a3, 0x23a4, 0x23a4, 0x23a5, 0x23a5, 0x23a6, 
+    0x23a7, 0x23a7, 0x23a8, 0x23a8, 0x23a9, 0x23a9, 0x23aa, 0x23aa, 
+    0x23ab, 0x23ab, 0x23ac, 0x23ad, 0x23ad, 0x23ae, 0x23ae, 0x23af, 
+    0x23af, 0x23b0, 0x23b0, 0x23b1, 0x23b2, 0x23b2, 0x23b3, 0x23b3, 
+    0x23b4, 0x23b4, 0x23b5, 0x23b5, 0x23b6, 0x23b6, 0x23b7, 0x23b8, 
+    0x23b8, 0x23b9, 0x23b9, 0x23ba, 0x23ba, 0x23bb, 0x23bb, 0x23bc, 
+    0x23bc, 0x23bd, 0x23bd, 0x23be, 0x23bf, 0x23bf, 0x23c0, 0x23c0, 
+    0x23c1, 0x23c1, 0x23c2, 0x23c2, 0x23c3, 0x23c3, 0x23c4, 0x23c5, 
+    0x23c5, 0x23c6, 0x23c6, 0x23c7, 0x23c7, 0x23c8, 0x23c8, 0x23c9, 
+    0x23c9, 0x23ca, 0x23ca, 0x23cb, 0x23cc, 0x23cc, 0x23cd, 0x23cd, 
+    0x23ce, 0x23ce, 0x23cf, 0x23cf, 0x23d0, 0x23d0, 0x23d1, 0x23d1, 
+    0x23d2, 0x23d3, 0x23d3, 0x23d4, 0x23d4, 0x23d5, 0x23d5, 0x23d6, 
+    0x23d6, 0x23d7, 0x23d7, 0x23d8, 0x23d8, 0x23d9, 0x23da, 0x23da, 
+    0x23db, 0x23db, 0x23dc, 0x23dc, 0x23dd, 0x23dd, 0x23de, 0x23de, 
+    0x23df, 0x23df, 0x23e0, 0x23e0, 0x23e1, 0x23e2, 0x23e2, 0x23e3, 
+    0x23e3, 0x23e4, 0x23e4, 0x23e5, 0x23e5, 0x23e6, 0x23e6, 0x23e7, 
+    0x23e7, 0x23e8, 0x23e8, 0x23e9, 0x23e9, 0x23ea, 0x23eb, 0x23eb, 
+    0x23ec, 0x23ec, 0x23ed, 0x23ed, 0x23ee, 0x23ee, 0x23ef, 0x23ef, 
+    0x23f0, 0x23f0, 0x23f1, 0x23f1, 0x23f2, 0x23f2, 0x23f3, 0x23f3, 
+    0x23f4, 0x23f5, 0x23f5, 0x23f6, 0x23f6, 0x23f7, 0x23f7, 0x23f8, 
+    0x23f8, 0x23f9, 0x23f9, 0x23fa, 0x23fa, 0x23fb, 0x23fb, 0x23fc, 
+    0x23fc, 0x23fd, 0x23fd, 0x23fe, 0x23fe, 0x23ff, 0x2400, 0x2400, 
+    0x2400, 0x2401, 0x2401, 0x2401, 0x2401, 0x2402, 0x2402, 0x2402, 
+    0x2402, 0x2403, 0x2403, 0x2403, 0x2403, 0x2404, 0x2404, 0x2404, 
+    0x2404, 0x2405, 0x2405, 0x2405, 0x2405, 0x2406, 0x2406, 0x2406, 
+    0x2407, 0x2407, 0x2407, 0x2407, 0x2408, 0x2408, 0x2408, 0x2408, 
+    0x2409, 0x2409, 0x2409, 0x2409, 0x240a, 0x240a, 0x240a, 0x240a, 
+    0x240b, 0x240b, 0x240b, 0x240b, 0x240c, 0x240c, 0x240c, 0x240c, 
+    0x240d, 0x240d, 0x240d, 0x240d, 0x240e, 0x240e, 0x240e, 0x240f, 
+    0x240f, 0x240f, 0x240f, 0x2410, 0x2410, 0x2410, 0x2410, 0x2411, 
+    0x2411, 0x2411, 0x2411, 0x2412, 0x2412, 0x2412, 0x2412, 0x2413, 
+    0x2413, 0x2413, 0x2413, 0x2414, 0x2414, 0x2414, 0x2414, 0x2415, 
+    0x2415, 0x2415, 0x2415, 0x2416, 0x2416, 0x2416, 0x2416, 0x2417, 
+    0x2417, 0x2417, 0x2417, 0x2418, 0x2418, 0x2418, 0x2418, 0x2419, 
+    0x2419, 0x2419, 0x2419, 0x241a, 0x241a, 0x241a, 0x241b, 0x241b, 
+    0x241b, 0x241b, 0x241c, 0x241c, 0x241c, 0x241c, 0x241d, 0x241d, 
+    0x241d, 0x241d, 0x241e, 0x241e, 0x241e, 0x241e, 0x241f, 0x241f, 
+    0x241f, 0x241f, 0x2420, 0x2420, 0x2420, 0x2420, 0x2421, 0x2421, 
+    0x2421, 0x2421, 0x2422, 0x2422, 0x2422, 0x2422, 0x2423, 0x2423, 
+    0x2423, 0x2423, 0x2424, 0x2424, 0x2424, 0x2424, 0x2425, 0x2425, 
+    0x2425, 0x2425, 0x2426, 0x2426, 0x2426, 0x2426, 0x2427, 0x2427, 
+    0x2427, 0x2427, 0x2428, 0x2428, 0x2428, 0x2428, 0x2429, 0x2429, 
+    0x2429, 0x2429, 0x242a, 0x242a, 0x242a, 0x242a, 0x242b, 0x242b, 
+    0x242b, 0x242b, 0x242c, 0x242c, 0x242c, 0x242c, 0x242d, 0x242d, 
+    0x242d, 0x242d, 0x242e, 0x242e, 0x242e, 0x242e, 0x242f, 0x242f, 
+    0x242f, 0x242f, 0x2430, 0x2430, 0x2430, 0x2430, 0x2431, 0x2431, 
+    0x2431, 0x2431, 0x2431, 0x2432, 0x2432, 0x2432, 0x2432, 0x2433, 
+    0x2433, 0x2433, 0x2433, 0x2434, 0x2434, 0x2434, 0x2434, 0x2435, 
+    0x2435, 0x2435, 0x2435, 0x2436, 0x2436, 0x2436, 0x2436, 0x2437, 
+    0x2437, 0x2437, 0x2437, 0x2438, 0x2438, 0x2438, 0x2438, 0x2439, 
+    0x2439, 0x2439, 0x2439, 0x243a, 0x243a, 0x243a, 0x243a, 0x243b, 
+    0x243b, 0x243b, 0x243b, 0x243c, 0x243c, 0x243c, 0x243c, 0x243d, 
+    0x243d, 0x243d, 0x243d, 0x243e, 0x243e, 0x243e, 0x243e, 0x243e, 
+    0x243f, 0x243f, 0x243f, 0x243f, 0x2440, 0x2440, 0x2440, 0x2440, 
+    0x2441, 0x2441, 0x2441, 0x2441, 0x2442, 0x2442, 0x2442, 0x2442, 
+    0x2443, 0x2443, 0x2444, 0x2444, 0x2445, 0x2445, 0x2446, 0x2446, 
+    0x2446, 0x2447, 0x2447, 0x2448, 0x2448, 0x2449, 0x2449, 0x244a, 
+    0x244a, 0x244b, 0x244b, 0x244c, 0x244c, 0x244d, 0x244d, 0x244e, 
+    0x244e, 0x244f, 0x244f, 0x2450, 0x2450, 0x2451, 0x2451, 0x2451, 
+    0x2452, 0x2452, 0x2453, 0x2453, 0x2454, 0x2454, 0x2455, 0x2455, 
+    0x2456, 0x2456, 0x2457, 0x2457, 0x2458, 0x2458, 0x2459, 0x2459, 
+    0x245a, 0x245a, 0x245a, 0x245b, 0x245b, 0x245c, 0x245c, 0x245d, 
+    0x245d, 0x245e, 0x245e, 0x245f, 0x245f, 0x2460, 0x2460, 0x2461, 
+    0x2461, 0x2462, 0x2462, 0x2462, 0x2463, 0x2463, 0x2464, 0x2464, 
+    0x2465, 0x2465, 0x2466, 0x2466, 0x2467, 0x2467, 0x2468, 0x2468, 
+    0x2469, 0x2469, 0x2469, 0x246a, 0x246a, 0x246b, 0x246b, 0x246c, 
+    0x246c, 0x246d, 0x246d, 0x246e, 0x246e, 0x246f, 0x246f, 0x246f, 
+    0x2470, 0x2470, 0x2471, 0x2471, 0x2472, 0x2472, 0x2473, 0x2473, 
+    0x2474, 0x2474, 0x2475, 0x2475, 0x2475, 0x2476, 0x2476, 0x2477, 
+    0x2477, 0x2478, 0x2478, 0x2479, 0x2479, 0x247a, 0x247a, 0x247a, 
+    0x247b, 0x247b, 0x247c, 0x247c, 0x247d, 0x247d, 0x247e, 0x247e, 
+    0x247f, 0x247f, 0x247f, 0x2480, 0x2480, 0x2481, 0x2481, 0x2482, 
+    0x2482, 0x2483, 0x2483, 0x2484, 0x2484, 0x2484, 0x2485, 0x2485, 
+    0x2486, 0x2486, 0x2487, 0x2487, 0x2488, 0x2488, 0x2489, 0x2489, 
+    0x2489, 0x248a, 0x248a, 0x248b, 0x248b, 0x248c, 0x248c, 0x248d, 
+    0x248d, 0x248d, 0x248e, 0x248e, 0x248f, 0x248f, 0x2490, 0x2490, 
+    0x2491, 0x2491, 0x2491, 0x2492, 0x2492, 0x2493, 0x2493, 0x2494, 
+    0x2494, 0x2495, 0x2495, 0x2495, 0x2496, 0x2496, 0x2497, 0x2497, 
+    0x2498, 0x2498, 0x2499, 0x2499, 0x2499, 0x249a, 0x249a, 0x249b, 
+    0x249b, 0x249c, 0x249c, 0x249d, 0x249d, 0x249d, 0x249e, 0x249e, 
+    0x249f, 0x249f, 0x24a0, 0x24a0, 0x24a0, 0x24a1, 0x24a1, 0x24a2, 
+    0x24a2, 0x24a3, 0x24a3, 0x24a4, 0x24a4, 0x24a4, 0x24a5, 0x24a5, 
+    0x24a6, 0x24a6, 0x24a7, 0x24a7, 0x24a7, 0x24a8, 0x24a8, 0x24a9, 
+    0x24a9, 0x24aa, 0x24aa, 0x24ab, 0x24ab, 0x24ab, 0x24ac, 0x24ac, 
+    0x24ad, 0x24ad, 0x24ae, 0x24ae, 0x24ae, 0x24af, 0x24af, 0x24b0, 
+    0x24b0, 0x24b1, 0x24b1, 0x24b1, 0x24b2, 0x24b2, 0x24b3, 0x24b3, 
+    0x24b4, 0x24b4, 0x24b4, 0x24b5, 0x24b5, 0x24b6, 0x24b6, 0x24b7, 
+    0x24b7, 0x24b7, 0x24b8, 0x24b8, 0x24b9, 0x24b9, 0x24ba, 0x24ba, 
+    0x24ba, 0x24bb, 0x24bb, 0x24bc, 0x24bc, 0x24bd, 0x24bd, 0x24bd, 
+    0x24be, 0x24be, 0x24bf, 0x24bf, 0x24c0, 0x24c0, 0x24c0, 0x24c1, 
+    0x24c1, 0x24c2, 0x24c2, 0x24c3, 0x24c3, 0x24c3, 0x24c4, 0x24c4, 
+    0x24c5, 0x24c5, 0x24c5, 0x24c6, 0x24c6, 0x24c7, 0x24c7, 0x24c8, 
+    0x24c8, 0x24c8, 0x24c9, 0x24c9, 0x24ca, 0x24ca, 0x24cb, 0x24cb, 
+    0x24cb, 0x24cc, 0x24cc, 0x24cd, 0x24cd, 0x24cd, 0x24ce, 0x24ce, 
+    0x24cf, 0x24cf, 0x24d0, 0x24d0, 0x24d0, 0x24d1, 0x24d1, 0x24d2, 
+    0x24d2, 0x24d3, 0x24d3, 0x24d3, 0x24d4, 0x24d4, 0x24d5, 0x24d5, 
+    0x24d5, 0x24d6, 0x24d6, 0x24d7, 0x24d7, 0x24d8, 0x24d8, 0x24d8, 
+    0x24d9, 0x24d9, 0x24da, 0x24da, 0x24da, 0x24db, 0x24db, 0x24dc, 
+    0x24dc, 0x24dc, 0x24dd, 0x24dd, 0x24de, 0x24de, 0x24df, 0x24df, 
+    0x24df, 0x24e0, 0x24e0, 0x24e1, 0x24e1, 0x24e1, 0x24e2, 0x24e2, 
+    0x24e3, 0x24e3, 0x24e3, 0x24e4, 0x24e4, 0x24e5, 0x24e5, 0x24e6, 
+    0x24e6, 0x24e6, 0x24e7, 0x24e7, 0x24e8, 0x24e8, 0x24e8, 0x24e9, 
+    0x24e9, 0x24ea, 0x24ea, 0x24ea, 0x24eb, 0x24eb, 0x24ec, 0x24ec, 
+    0x24ec, 0x24ed, 0x24ed, 0x24ee, 0x24ee, 0x24ee, 0x24ef, 0x24ef, 
+    0x24f0, 0x24f0, 0x24f1, 0x24f1, 0x24f1, 0x24f2, 0x24f2, 0x24f3, 
+    0x24f3, 0x24f3, 0x24f4, 0x24f4, 0x24f5, 0x24f5, 0x24f5, 0x24f6, 
+    0x24f6, 0x24f7, 0x24f7, 0x24f7, 0x24f8, 0x24f8, 0x24f9, 0x24f9, 
+    0x24f9, 0x24fa, 0x24fa, 0x24fb, 0x24fb, 0x24fb, 0x24fc, 0x24fc, 
+    0x24fd, 0x24fd, 0x24fd, 0x24fe, 0x24fe, 0x24ff, 0x24ff, 0x24ff, 
+    0x2500, 0x2500, 0x2501, 0x2501, 0x2501, 0x2502, 0x2502, 0x2503, 
+    0x2503, 0x2503, 0x2504, 0x2504, 0x2505, 0x2505, 0x2505, 0x2506, 
+    0x2506, 0x2507, 0x2507, 0x2507, 0x2508, 0x2508, 0x2509, 0x2509, 
+    0x2509, 0x250a, 0x250a, 0x250b, 0x250b, 0x250b, 0x250c, 0x250c, 
+    0x250d, 0x250d, 0x250d, 0x250e, 0x250e, 0x250f, 0x250f, 0x250f, 
+    0x2510, 0x2510, 0x2510, 0x2511, 0x2511, 0x2512, 0x2512, 0x2512, 
+    0x2513, 0x2513, 0x2514, 0x2514, 0x2514, 0x2515, 0x2515, 0x2516, 
+    0x2516, 0x2516, 0x2517, 0x2517, 0x2518, 0x2518, 0x2518, 0x2519, 
+    0x2519, 0x2519, 0x251a, 0x251a, 0x251b, 0x251b, 0x251b, 0x251c, 
+    0x251c, 0x251d, 0x251d, 0x251d, 0x251e, 0x251e, 0x251f, 0x251f, 
+    0x251f, 0x2520, 0x2520, 0x2520, 0x2521, 0x2521, 0x2522, 0x2522, 
+    0x2522, 0x2523, 0x2523, 0x2524, 0x2524, 0x2524, 0x2525, 0x2525, 
+    0x2526, 0x2526, 0x2526, 0x2527, 0x2527, 0x2527, 0x2528, 0x2528, 
+    0x2529, 0x2529, 0x2529, 0x252a, 0x252a, 0x252b, 0x252b, 0x252b, 
+    0x252c, 0x252c, 0x252c, 0x252d, 0x252d, 0x252e, 0x252e, 0x252e, 
+    0x252f, 0x252f, 0x252f, 0x2530, 0x2530, 0x2531, 0x2531, 0x2531, 
+    0x2532, 0x2532, 0x2533, 0x2533, 0x2533, 0x2534, 0x2534, 0x2534, 
+    0x2535, 0x2535, 0x2536, 0x2536, 0x2536, 0x2537, 0x2537, 0x2537, 
+    0x2538, 0x2538, 0x2539, 0x2539, 0x2539, 0x253a, 0x253a, 0x253b, 
+    0x253b, 0x253b, 0x253c, 0x253c, 0x253c, 0x253d, 0x253d, 0x253e, 
+    0x253e, 0x253e, 0x253f, 0x253f, 0x253f, 0x2540, 0x2540, 0x2541, 
+    0x2541, 0x2541, 0x2542, 0x2542, 0x2542, 0x2543, 0x2543, 0x2544, 
+    0x2544, 0x2544, 0x2545, 0x2545, 0x2545, 0x2546, 0x2546, 0x2547, 
+    0x2547, 0x2547, 0x2548, 0x2548, 0x2548, 0x2549, 0x2549, 0x254a, 
+    0x254a, 0x254a, 0x254b, 0x254b, 0x254b, 0x254c, 0x254c, 0x254d, 
+    0x254d, 0x254d, 0x254e, 0x254e, 0x254e, 0x254f, 0x254f, 0x2550, 
+    0x2550, 0x2550, 0x2551, 0x2551, 0x2551, 0x2552, 0x2552, 0x2553, 
+    0x2553, 0x2553, 0x2554, 0x2554, 0x2554, 0x2555, 0x2555, 0x2555, 
+    0x2556, 0x2556, 0x2557, 0x2557, 0x2557, 0x2558, 0x2558, 0x2558, 
+    0x2559, 0x2559, 0x255a, 0x255a, 0x255a, 0x255b, 0x255b, 0x255b, 
+    0x255c, 0x255c, 0x255c, 0x255d, 0x255d, 0x255e, 0x255e, 0x255e, 
+    0x255f, 0x255f, 0x255f, 0x2560, 0x2560, 0x2561, 0x2561, 0x2561, 
+    0x2562, 0x2562, 0x2562, 0x2563, 0x2563, 0x2563, 0x2564, 0x2564, 
+    0x2565, 0x2565, 0x2565, 0x2566, 0x2566, 0x2566, 0x2567, 0x2567, 
+    0x2567, 0x2568, 0x2568, 0x2569, 0x2569, 0x2569, 0x256a, 0x256a, 
+    0x256a, 0x256b, 0x256b, 0x256b, 0x256c, 0x256c, 0x256d, 0x256d, 
+    0x256d, 0x256e, 0x256e, 0x256e, 0x256f, 0x256f, 0x256f, 0x2570, 
+    0x2570, 0x2570, 0x2571, 0x2571, 0x2572, 0x2572, 0x2572, 0x2573, 
+    0x2573, 0x2573, 0x2574, 0x2574, 0x2574, 0x2575, 0x2575, 0x2576, 
+    0x2576, 0x2576, 0x2577, 0x2577, 0x2577, 0x2578, 0x2578, 0x2578, 
+    0x2579, 0x2579, 0x2579, 0x257a, 0x257a, 0x257b, 0x257b, 0x257b, 
+    0x257c, 0x257c, 0x257c, 0x257d, 0x257d, 0x257d, 0x257e, 0x257e, 
+    0x257e, 0x257f, 0x257f, 0x2580, 0x2580, 0x2580, 0x2581, 0x2581, 
+    0x2581, 0x2582, 0x2582, 0x2582, 0x2583, 0x2583, 0x2583, 0x2584, 
+    0x2584, 0x2585, 0x2585, 0x2585, 0x2586, 0x2586, 0x2586, 0x2587, 
+    0x2587, 0x2587, 0x2588, 0x2588, 0x2588, 0x2589, 0x2589, 0x258a, 
+    0x258a, 0x258a, 0x258b, 0x258b, 0x258b, 0x258c, 0x258c, 0x258c, 
+    0x258d, 0x258d, 0x258d, 0x258e, 0x258e, 0x258e, 0x258f, 0x258f, 
+    0x258f, 0x2590, 0x2590, 0x2591, 0x2591, 0x2591, 0x2592, 0x2592, 
+    0x2592, 0x2593, 0x2593, 0x2593, 0x2594, 0x2594, 0x2594, 0x2595, 
+    0x2595, 0x2595, 0x2596, 0x2596, 0x2597, 0x2597, 0x2597, 0x2598, 
+    0x2598, 0x2598, 0x2599, 0x2599, 0x2599, 0x259a, 0x259a, 0x259a, 
+    0x259b, 0x259b, 0x259b, 0x259c, 0x259c, 0x259c, 0x259d, 0x259d, 
+    0x259d, 0x259e, 0x259e, 0x259f, 0x259f, 0x259f, 0x25a0, 0x25a0, 
+    0x25a0, 0x25a1, 0x25a1, 0x25a1, 0x25a2, 0x25a2, 0x25a2, 0x25a3, 
+    0x25a3, 0x25a3, 0x25a4, 0x25a4, 0x25a4, 0x25a5, 0x25a5, 0x25a5, 
+    0x25a6, 0x25a6, 0x25a6, 0x25a7, 0x25a7, 0x25a8, 0x25a8, 0x25a8, 
+    0x25a9, 0x25a9, 0x25a9, 0x25aa, 0x25aa, 0x25aa, 0x25ab, 0x25ab, 
+    0x25ab, 0x25ac, 0x25ac, 0x25ac, 0x25ad, 0x25ad, 0x25ad, 0x25ae, 
+    0x25ae, 0x25ae, 0x25af, 0x25af, 0x25af, 0x25b0, 0x25b0, 0x25b0, 
+    0x25b1, 0x25b1, 0x25b1, 0x25b2, 0x25b2, 0x25b2, 0x25b3, 0x25b3, 
+    0x25b4, 0x25b4, 0x25b4, 0x25b5, 0x25b5, 0x25b5, 0x25b6, 0x25b6, 
+    0x25b6, 0x25b7, 0x25b7, 0x25b7, 0x25b8, 0x25b8, 0x25b8, 0x25b9, 
+    0x25b9, 0x25b9, 0x25ba, 0x25ba, 0x25ba, 0x25bb, 0x25bb, 0x25bb, 
+    0x25bc, 0x25bc, 0x25bc, 0x25bd, 0x25bd, 0x25bd, 0x25be, 0x25be, 
+    0x25be, 0x25bf, 0x25bf, 0x25bf, 0x25c0, 0x25c0, 0x25c0, 0x25c1, 
+    0x25c1, 0x25c1, 0x25c2, 0x25c2, 0x25c2, 0x25c3, 0x25c3, 0x25c3, 
+    0x25c4, 0x25c4, 0x25c4, 0x25c5, 0x25c5, 0x25c5, 0x25c6, 0x25c6, 
+    0x25c6, 0x25c7, 0x25c7, 0x25c7, 0x25c8, 0x25c8, 0x25c8, 0x25c9, 
+    0x25c9, 0x25ca, 0x25ca, 0x25ca, 0x25cb, 0x25cb, 0x25cb, 0x25cc, 
+    0x25cc, 0x25cc, 0x25cd, 0x25cd, 0x25cd, 0x25ce, 0x25ce, 0x25ce, 
+    0x25cf, 0x25cf, 0x25cf, 0x25d0, 0x25d0, 0x25d0, 0x25d1, 0x25d1, 
+    0x25d1, 0x25d2, 0x25d2, 0x25d2, 0x25d3, 0x25d3, 0x25d3, 0x25d4, 
+    0x25d4, 0x25d4, 0x25d5, 0x25d5, 0x25d5, 0x25d6, 0x25d6, 0x25d6, 
+    0x25d7, 0x25d7, 0x25d8, 0x25d8, 0x25d9, 0x25da, 0x25da, 0x25db, 
+    0x25dc, 0x25dc, 0x25dd, 0x25de, 0x25de, 0x25df, 0x25e0, 0x25e0, 
+    0x25e1, 0x25e2, 0x25e2, 0x25e3, 0x25e4, 0x25e4, 0x25e5, 0x25e6, 
+    0x25e6, 0x25e7, 0x25e8, 0x25e8, 0x25e9, 0x25ea, 0x25ea, 0x25eb, 
+    0x25ec, 0x25ec, 0x25ed, 0x25ee, 0x25ee, 0x25ef, 0x25ef, 0x25f0, 
+    0x25f1, 0x25f1, 0x25f2, 0x25f3, 0x25f3, 0x25f4, 0x25f5, 0x25f5, 
+    0x25f6, 0x25f7, 0x25f7, 0x25f8, 0x25f9, 0x25f9, 0x25fa, 0x25fa, 
+    0x25fb, 0x25fc, 0x25fc, 0x25fd, 0x25fe, 0x25fe, 0x25ff, 0x2600, 
+    0x2600, 0x2601, 0x2602, 0x2602, 0x2603, 0x2603, 0x2604, 0x2605, 
+    0x2605, 0x2606, 0x2607, 0x2607, 0x2608, 0x2609, 0x2609, 0x260a, 
+    0x260a, 0x260b, 0x260c, 0x260c, 0x260d, 0x260e, 0x260e, 0x260f, 
+    0x2610, 0x2610, 0x2611, 0x2611, 0x2612, 0x2613, 0x2613, 0x2614, 
+    0x2615, 0x2615, 0x2616, 0x2617, 0x2617, 0x2618, 0x2618, 0x2619, 
+    0x261a, 0x261a, 0x261b, 0x261c, 0x261c, 0x261d, 0x261d, 0x261e, 
+    0x261f, 0x261f, 0x2620, 0x2621, 0x2621, 0x2622, 0x2622, 0x2623, 
+    0x2624, 0x2624, 0x2625, 0x2626, 0x2626, 0x2627, 0x2627, 0x2628, 
+    0x2629, 0x2629, 0x262a, 0x262b, 0x262b, 0x262c, 0x262c, 0x262d, 
+    0x262e, 0x262e, 0x262f, 0x2630, 0x2630, 0x2631, 0x2631, 0x2632, 
+    0x2633, 0x2633, 0x2634, 0x2634, 0x2635, 0x2636, 0x2636, 0x2637, 
+    0x2638, 0x2638, 0x2639, 0x2639, 0x263a, 0x263b, 0x263b, 0x263c, 
+    0x263c, 0x263d, 0x263e, 0x263e, 0x263f, 0x2640, 0x2640, 0x2641, 
+    0x2641, 0x2642, 0x2643, 0x2643, 0x2644, 0x2644, 0x2645, 0x2646, 
+    0x2646, 0x2647, 0x2647, 0x2648, 0x2649, 0x2649, 0x264a, 0x264a, 
+    0x264b, 0x264c, 0x264c, 0x264d, 0x264e, 0x264e, 0x264f, 0x264f, 
+    0x2650, 0x2651, 0x2651, 0x2652, 0x2652, 0x2653, 0x2654, 0x2654, 
+    0x2655, 0x2655, 0x2656, 0x2657, 0x2657, 0x2658, 0x2658, 0x2659, 
+    0x265a, 0x265a, 0x265b, 0x265b, 0x265c, 0x265d, 0x265d, 0x265e, 
+    0x265e, 0x265f, 0x2660, 0x2660, 0x2661, 0x2661, 0x2662, 0x2663, 
+    0x2663, 0x2664, 0x2664, 0x2665, 0x2666, 0x2666, 0x2667, 0x2667, 
+    0x2668, 0x2668, 0x2669, 0x266a, 0x266a, 0x266b, 0x266b, 0x266c, 
+    0x266d, 0x266d, 0x266e, 0x266e, 0x266f, 0x2670, 0x2670, 0x2671, 
+    0x2671, 0x2672, 0x2673, 0x2673, 0x2674, 0x2674, 0x2675, 0x2675, 
+    0x2676, 0x2677, 0x2677, 0x2678, 0x2678, 0x2679, 0x267a, 0x267a, 
+    0x267b, 0x267b, 0x267c, 0x267c, 0x267d, 0x267e, 0x267e, 0x267f, 
+    0x267f, 0x2680, 0x2681, 0x2681, 0x2682, 0x2682, 0x2683, 0x2683, 
+    0x2684, 0x2685, 0x2685, 0x2686, 0x2686, 0x2687, 0x2688, 0x2688, 
+    0x2689, 0x2689, 0x268a, 0x268a, 0x268b, 0x268c, 0x268c, 0x268d, 
+    0x268d, 0x268e, 0x268f, 0x268f, 0x2690, 0x2690, 0x2691, 0x2691, 
+    0x2692, 0x2693, 0x2693, 0x2694, 0x2694, 0x2695, 0x2695, 0x2696, 
+    0x2697, 0x2697, 0x2698, 0x2698, 0x2699, 0x2699, 0x269a, 0x269b, 
+    0x269b, 0x269c, 0x269c, 0x269d, 0x269d, 0x269e, 0x269f, 0x269f, 
+    0x26a0, 0x26a0, 0x26a1, 0x26a1, 0x26a2, 0x26a3, 0x26a3, 0x26a4, 
+    0x26a4, 0x26a5, 0x26a5, 0x26a6, 0x26a7, 0x26a7, 0x26a8, 0x26a8, 
+    0x26a9, 0x26a9, 0x26aa, 0x26aa, 0x26ab, 0x26ac, 0x26ac, 0x26ad, 
+    0x26ad, 0x26ae, 0x26ae, 0x26af, 0x26b0, 0x26b0, 0x26b1, 0x26b1, 
+    0x26b2, 0x26b2, 0x26b3, 0x26b4, 0x26b4, 0x26b5, 0x26b5, 0x26b6, 
+    0x26b6, 0x26b7, 0x26b7, 0x26b8, 0x26b9, 0x26b9, 0x26ba, 0x26ba, 
+    0x26bb, 0x26bb, 0x26bc, 0x26bc, 0x26bd, 0x26be, 0x26be, 0x26bf, 
+    0x26bf, 0x26c0, 0x26c0, 0x26c1, 0x26c2, 0x26c2, 0x26c3, 0x26c3, 
+    0x26c4, 0x26c4, 0x26c5, 0x26c5, 0x26c6, 0x26c7, 0x26c7, 0x26c8, 
+    0x26c8, 0x26c9, 0x26c9, 0x26ca, 0x26ca, 0x26cb, 0x26cb, 0x26cc, 
+    0x26cd, 0x26cd, 0x26ce, 0x26ce, 0x26cf, 0x26cf, 0x26d0, 0x26d0, 
+    0x26d1, 0x26d2, 0x26d2, 0x26d3, 0x26d3, 0x26d4, 0x26d4, 0x26d5, 
+    0x26d5, 0x26d6, 0x26d7, 0x26d7, 0x26d8, 0x26d8, 0x26d9, 0x26d9, 
+    0x26da, 0x26da, 0x26db, 0x26db, 0x26dc, 0x26dd, 0x26dd, 0x26de, 
+    0x26de, 0x26df, 0x26df, 0x26e0, 0x26e0, 0x26e1, 0x26e1, 0x26e2, 
+    0x26e3, 0x26e3, 0x26e4, 0x26e4, 0x26e5, 0x26e5, 0x26e6, 0x26e6, 
+    0x26e7, 0x26e7, 0x26e8, 0x26e9, 0x26e9, 0x26ea, 0x26ea, 0x26eb, 
+    0x26eb, 0x26ec, 0x26ec, 0x26ed, 0x26ed, 0x26ee, 0x26ee, 0x26ef, 
+    0x26f0, 0x26f0, 0x26f1, 0x26f1, 0x26f2, 0x26f2, 0x26f3, 0x26f3, 
+    0x26f4, 0x26f4, 0x26f5, 0x26f5, 0x26f6, 0x26f7, 0x26f7, 0x26f8, 
+    0x26f8, 0x26f9, 0x26f9, 0x26fa, 0x26fa, 0x26fb, 0x26fb, 0x26fc, 
+    0x26fc, 0x26fd, 0x26fe, 0x26fe, 0x26ff, 0x26ff, 0x2700, 0x2700, 
+    0x2701, 0x2701, 0x2702, 0x2702, 0x2703, 0x2703, 0x2704, 0x2704, 
+    0x2705, 0x2705, 0x2706, 0x2707, 0x2707, 0x2708, 0x2708, 0x2709, 
+    0x2709, 0x270a, 0x270a, 0x270b, 0x270b, 0x270c, 0x270c, 0x270d, 
+    0x270d, 0x270e, 0x270f, 0x270f, 0x2710, 0x2710, 0x2711, 0x2711, 
+    0x2712, 0x2712, 0x2713, 0x2713, 0x2714, 0x2714, 0x2715, 0x2715, 
+    0x2716, 0x2716, 0x2717, 0x2717, 0x2718, 0x2719, 0x2719, 0x271a, 
+    0x271a, 0x271b, 0x271b, 0x271c, 0x271c, 0x271d, 0x271d, 0x271e, 
+    0x271e, 0x271f, 0x271f, 0x2720, 0x2720, 0x2721, 0x2721, 0x2722, 
+    0x2722, 0x2723, 0x2723, 0x2724, 0x2725, 0x2725, 0x2726, 0x2726, 
+    0x2727, 0x2727, 0x2728, 0x2728, 0x2729, 0x2729, 0x272a, 0x272a, 
+    0x272b, 0x272b, 0x272c, 0x272c, 0x272d, 0x272d, 0x272e, 0x272e, 
+    0x272f, 0x272f, 0x2730, 0x2730, 0x2731, 0x2732, 0x2732, 0x2733, 
+    0x2733, 0x2734, 0x2734, 0x2735, 0x2735, 0x2736, 0x2736, 0x2737, 
+    0x2737, 0x2738, 0x2738, 0x2739, 0x2739, 0x273a, 0x273a, 0x273b, 
+    0x273b, 0x273c, 0x273c, 0x273d, 0x273d, 0x273e, 0x273e, 0x273f, 
+    0x273f, 0x2740, 0x2740, 0x2741, 0x2741, 0x2742, 0x2742, 0x2743, 
+    0x2743, 0x2744, 0x2744, 0x2745, 0x2746, 0x2746, 0x2747, 0x2747, 
+    0x2748, 0x2748, 0x2749, 0x2749, 0x274a, 0x274a, 0x274b, 0x274b, 
+    0x274c, 0x274c, 0x274d, 0x274d, 0x274e, 0x274e, 0x274f, 0x274f, 
+    0x2750, 0x2750, 0x2751, 0x2751, 0x2752, 0x2752, 0x2753, 0x2753, 
+    0x2754, 0x2754, 0x2755, 0x2755, 0x2756, 0x2756, 0x2757, 0x2757, 
+    0x2758, 0x2758, 0x2759, 0x2759, 0x275a, 0x275a, 0x275b, 0x275b, 
+    0x275c, 0x275c, 0x275d, 0x275d, 0x275e, 0x275e, 0x275f, 0x275f, 
+    0x2760, 0x2760, 0x2761, 0x2761, 0x2762, 0x2762, 0x2763, 0x2763, 
+    0x2764, 0x2764, 0x2765, 0x2765, 0x2766, 0x2766, 0x2767, 0x2767, 
+    0x2768, 0x2768, 0x2769, 0x2769, 0x276a, 0x276a, 0x276b, 0x276b, 
+    0x276c, 0x276c, 0x276d, 0x276d, 0x276e, 0x276e, 0x276f, 0x276f, 
+    0x2770, 0x2770, 0x2771, 0x2771, 0x2772, 0x2772, 0x2773, 0x2773, 
+    0x2774, 0x2774, 0x2775, 0x2775, 0x2776, 0x2776, 0x2777, 0x2777, 
+    0x2778, 0x2778, 0x2779, 0x2779, 0x277a, 0x277a, 0x277b, 0x277b, 
+    0x277c, 0x277c, 0x277d, 0x277d, 0x277e, 0x277e, 0x277f, 0x277f, 
+    0x2780, 0x2780, 0x2781, 0x2781, 0x2782, 0x2782, 0x2782, 0x2783, 
+    0x2783, 0x2784, 0x2784, 0x2785, 0x2785, 0x2786, 0x2786, 0x2787, 
+    0x2787, 0x2788, 0x2788, 0x2789, 0x2789, 0x278a, 0x278a, 0x278b, 
+    0x278b, 0x278c, 0x278c, 0x278d, 0x278d, 0x278e, 0x278e, 0x278f, 
+    0x278f, 0x2790, 0x2790, 0x2791, 0x2791, 0x2792, 0x2792, 0x2793, 
+    0x2793, 0x2794, 0x2794, 0x2795, 0x2795, 0x2796, 0x2796, 0x2796, 
+    0x2797, 0x2797, 0x2798, 0x2798, 0x2799, 0x2799, 0x279a, 0x279a, 
+    0x279b, 0x279b, 0x279c, 0x279c, 0x279d, 0x279d, 0x279e, 0x279e, 
+    0x279f, 0x279f, 0x27a0, 0x27a0, 0x27a1, 0x27a1, 0x27a2, 0x27a2, 
+    0x27a3, 0x27a3, 0x27a4, 0x27a4, 0x27a4, 0x27a5, 0x27a5, 0x27a6, 
+    0x27a6, 0x27a7, 0x27a7, 0x27a8, 0x27a8, 0x27a9, 0x27a9, 0x27aa, 
+    0x27aa, 0x27ab, 0x27ab, 0x27ac, 0x27ac, 0x27ad, 0x27ad, 0x27ae, 
+    0x27ae, 0x27af, 0x27af, 0x27af, 0x27b0, 0x27b0, 0x27b1, 0x27b1, 
+    0x27b2, 0x27b2, 0x27b3, 0x27b3, 0x27b4, 0x27b4, 0x27b5, 0x27b5, 
+    0x27b6, 0x27b6, 0x27b7, 0x27b7, 0x27b8, 0x27b8, 0x27b9, 0x27b9, 
+    0x27b9, 0x27ba, 0x27ba, 0x27bb, 0x27bb, 0x27bc, 0x27bc, 0x27bd, 
+    0x27bd, 0x27be, 0x27be, 0x27bf, 0x27bf, 0x27c0, 0x27c0, 0x27c1, 
+    0x27c1, 0x27c1, 0x27c2, 0x27c2, 0x27c3, 0x27c3, 0x27c4, 0x27c4, 
+    0x27c5, 0x27c5, 0x27c6, 0x27c6, 0x27c7, 0x27c7, 0x27c8, 0x27c8, 
+    0x27c9, 0x27c9, 0x27c9, 0x27ca, 0x27ca, 0x27cb, 0x27cb, 0x27cc, 
+    0x27cc, 0x27cd, 0x27cd, 0x27ce, 0x27ce, 0x27cf, 0x27cf, 0x27d0, 
+    0x27d0, 0x27d1, 0x27d1, 0x27d1, 0x27d2, 0x27d2, 0x27d3, 0x27d3, 
+    0x27d4, 0x27d4, 0x27d5, 0x27d5, 0x27d6, 0x27d6, 0x27d7, 0x27d7, 
+    0x27d8, 0x27d8, 0x27d8, 0x27d9, 0x27d9, 0x27da, 0x27da, 0x27db, 
+    0x27db, 0x27dc, 0x27dc, 0x27dd, 0x27dd, 0x27de, 0x27de, 0x27de, 
+    0x27df, 0x27df, 0x27e0, 0x27e0, 0x27e1, 0x27e1, 0x27e2, 0x27e2, 
+    0x27e3, 0x27e3, 0x27e4, 0x27e4, 0x27e5, 0x27e5, 0x27e5, 0x27e6, 
+    0x27e6, 0x27e7, 0x27e7, 0x27e8, 0x27e8, 0x27e9, 0x27e9, 0x27ea, 
+    0x27ea, 0x27eb, 0x27eb, 0x27eb, 0x27ec, 0x27ec, 0x27ed, 0x27ed, 
+    0x27ee, 0x27ee, 0x27ef, 0x27ef, 0x27f0, 0x27f0, 0x27f0, 0x27f1, 
+    0x27f1, 0x27f2, 0x27f2, 0x27f3, 0x27f3, 0x27f4, 0x27f4, 0x27f5, 
+    0x27f5, 0x27f6, 0x27f6, 0x27f6, 0x27f7, 0x27f7, 0x27f8, 0x27f8, 
+    0x27f9, 0x27f9, 0x27fa, 0x27fa, 0x27fb, 0x27fb, 0x27fb, 0x27fc, 
+    0x27fc, 0x27fd, 0x27fd, 0x27fe, 0x27fe, 0x27ff, 0x27ff, 0x2800, 
+    0x2800, 0x2800, 0x2801, 0x2801, 0x2802, 0x2802, 0x2803, 0x2803, 
+    0x2804, 0x2804, 0x2805, 0x2805, 0x2805, 0x2806, 0x2806, 0x2807, 
+    0x2807, 0x2808, 0x2808, 0x2809, 0x2809, 0x2809, 0x280a, 0x280a, 
+    0x280b, 0x280b, 0x280c, 0x280c, 0x280d, 0x280d, 0x280e, 0x280e, 
+    0x280e, 0x280f, 0x280f, 0x2810, 0x2810, 0x2811, 0x2811, 0x2812, 
+    0x2812, 0x2812, 0x2813, 0x2813, 0x2814, 0x2814, 0x2815, 0x2815, 
+    0x2816, 0x2816, 0x2816, 0x2817, 0x2817, 0x2818, 0x2818, 0x2819, 
+    0x2819, 0x281a, 0x281a, 0x281a, 0x281b, 0x281b, 0x281c, 0x281c, 
+    0x281d, 0x281d, 0x281d, 0x281e, 0x281e, 0x281f, 0x281f, 0x2820, 
+    0x2820, 0x2821, 0x2821, 0x2821, 0x2822, 0x2822, 0x2823, 0x2823, 
+    0x2824, 0x2824, 0x2824, 0x2825, 0x2825, 0x2826, 0x2826, 0x2827, 
+    0x2827, 0x2828, 0x2828, 0x2828, 0x2829, 0x2829, 0x282a, 0x282a, 
+    0x282b, 0x282b, 0x282b, 0x282c, 0x282c, 0x282d, 0x282d, 0x282e, 
+    0x282e, 0x282e, 0x282f, 0x282f, 0x2830, 0x2830, 0x2831, 0x2831, 
+    0x2831, 0x2832, 0x2832, 0x2833, 0x2833, 0x2834, 0x2834, 0x2834, 
+    0x2835, 0x2835, 0x2836, 0x2836, 0x2837, 0x2837, 0x2837, 0x2838, 
+    0x2838, 0x2839, 0x2839, 0x283a, 0x283a, 0x283a, 0x283b, 0x283b, 
+    0x283c, 0x283c, 0x283d, 0x283d, 0x283d, 0x283e, 0x283e, 0x283f, 
+    0x283f, 0x2840, 0x2840, 0x2840, 0x2841, 0x2841, 0x2842, 0x2842, 
+    0x2842, 0x2843, 0x2843, 0x2844, 0x2844, 0x2845, 0x2845, 0x2845, 
+    0x2846, 0x2846, 0x2847, 0x2847, 0x2848, 0x2848, 0x2848, 0x2849, 
+    0x2849, 0x284a, 0x284a, 0x284a, 0x284b, 0x284b, 0x284c, 0x284c, 
+    0x284d, 0x284d, 0x284d, 0x284e, 0x284e, 0x284f, 0x284f, 0x284f, 
+    0x2850, 0x2850, 0x2851, 0x2851, 0x2852, 0x2852, 0x2852, 0x2853, 
+    0x2853, 0x2854, 0x2854, 0x2854, 0x2855, 0x2855, 0x2856, 0x2856, 
+    0x2857, 0x2857, 0x2857, 0x2858, 0x2858, 0x2859, 0x2859, 0x2859, 
+    0x285a, 0x285a, 0x285b, 0x285b, 0x285b, 0x285c, 0x285c, 0x285d, 
+    0x285d, 0x285d, 0x285e, 0x285e, 0x285f, 0x285f, 0x2860, 0x2860, 
+    0x2860, 0x2861, 0x2861, 0x2862, 0x2862, 0x2862, 0x2863, 0x2863, 
+    0x2864, 0x2864, 0x2864, 0x2865, 0x2865, 0x2866, 0x2866, 0x2866, 
+    0x2867, 0x2867, 0x2868, 0x2868, 0x2868, 0x2869, 0x2869, 0x286a, 
+    0x286a, 0x286a, 0x286b, 0x286b, 0x286c, 0x286c, 0x286d, 0x286d, 
+    0x286d, 0x286e, 0x286e, 0x286f, 0x286f, 0x286f, 0x2870, 0x2870, 
+    0x2871, 0x2871, 0x2871, 0x2872, 0x2872, 0x2873, 0x2873, 0x2873, 
+    0x2874, 0x2874, 0x2875, 0x2875, 0x2875, 0x2876, 0x2876, 0x2877, 
+    0x2877, 0x2877, 0x2878, 0x2878, 0x2879, 0x2879, 0x2879, 0x287a, 
+    0x287a, 0x287b, 0x287b, 0x287b, 0x287c, 0x287c, 0x287c, 0x287d, 
+    0x287d, 0x287e, 0x287e, 0x287e, 0x287f, 0x287f, 0x2880, 0x2880, 
+    0x2880, 0x2881, 0x2881, 0x2882, 0x2882, 0x2882, 0x2883, 0x2883, 
+    0x2884, 0x2884, 0x2884, 0x2885, 0x2885, 0x2886, 0x2886, 0x2886, 
+    0x2887, 0x2887, 0x2888, 0x2888, 0x2888, 0x2889, 0x2889, 0x2889, 
+    0x288a, 0x288a, 0x288b, 0x288b, 0x288b, 0x288c, 0x288c, 0x288d, 
+    0x288d, 0x288d, 0x288e, 0x288e, 0x288f, 0x288f, 0x288f, 0x2890, 
+    0x2890, 0x2890, 0x2891, 0x2891, 0x2892, 0x2892, 0x2892, 0x2893, 
+    0x2893, 0x2894, 0x2894, 0x2894, 0x2895, 0x2895, 0x2896, 0x2896, 
+    0x2896, 0x2897, 0x2897, 0x2897, 0x2898, 0x2898, 0x2899, 0x2899, 
+    0x2899, 0x289a, 0x289a, 0x289b, 0x289b, 0x289b, 0x289c, 0x289c, 
+    0x289c, 0x289d, 0x289d, 0x289e, 0x289e, 0x289e, 0x289f, 0x289f, 
+    0x289f, 0x28a0, 0x28a0, 0x28a1, 0x28a1, 0x28a1, 0x28a2, 0x28a2, 
+    0x28a3, 0x28a3, 0x28a3, 0x28a4, 0x28a4, 0x28a4, 0x28a5, 0x28a5, 
+    0x28a6, 0x28a6, 0x28a6, 0x28a7, 0x28a7, 0x28a7, 0x28a8, 0x28a8, 
+    0x28a9, 0x28a9, 0x28a9, 0x28aa, 0x28aa, 0x28ab, 0x28ab, 0x28ab, 
+    0x28ac, 0x28ac, 0x28ac, 0x28ad, 0x28ad, 0x28ae, 0x28ae, 0x28ae, 
+    0x28af, 0x28af, 0x28af, 0x28b0, 0x28b0, 0x28b1, 0x28b1, 0x28b1, 
+    0x28b2, 0x28b2, 0x28b2, 0x28b3, 0x28b3, 0x28b4, 0x28b4, 0x28b4, 
+    0x28b5, 0x28b5, 0x28b5, 0x28b6, 0x28b6, 0x28b7, 0x28b7, 0x28b7, 
+    0x28b8, 0x28b8, 0x28b8, 0x28b9, 0x28b9, 0x28ba, 0x28ba, 0x28ba, 
+    0x28bb, 0x28bb, 0x28bb, 0x28bc, 0x28bc, 0x28bc, 0x28bd, 0x28bd, 
+    0x28be, 0x28be, 0x28be, 0x28bf, 0x28bf, 0x28bf, 0x28c0, 0x28c0, 
+    0x28c1, 0x28c1, 0x28c1, 0x28c2, 0x28c2, 0x28c2, 0x28c3, 0x28c3, 
+    0x28c4, 0x28c4, 0x28c4, 0x28c5, 0x28c5, 0x28c5, 0x28c6, 0x28c6, 
+    0x28c6, 0x28c7, 0x28c7, 0x28c8, 0x28c8, 0x28c8, 0x28c9, 0x28c9, 
+    0x28c9, 0x28ca, 0x28ca, 0x28ca, 0x28cb, 0x28cb, 0x28cc, 0x28cc, 
+    0x28cc, 0x28cd, 0x28cd, 0x28cd, 0x28ce, 0x28ce, 0x28cf, 0x28cf, 
+    0x28cf, 0x28d0, 0x28d0, 0x28d0, 0x28d1, 0x28d1, 0x28d1, 0x28d2, 
+    0x28d2, 0x28d3, 0x28d3, 0x28d3, 0x28d4, 0x28d4, 0x28d4, 0x28d5, 
+    0x28d5, 0x28d5, 0x28d6, 0x28d6, 0x28d6, 0x28d7, 0x28d7, 0x28d8, 
+    0x28d8, 0x28d8, 0x28d9, 0x28d9, 0x28d9, 0x28da, 0x28da, 0x28da, 
+    0x28db, 0x28db, 0x28dc, 0x28dc, 0x28dc, 0x28dd, 0x28dd, 0x28dd, 
+    0x28de, 0x28de, 0x28de, 0x28df, 0x28df, 0x28e0, 0x28e0, 0x28e0, 
+    0x28e1, 0x28e1, 0x28e1, 0x28e2, 0x28e2, 0x28e2, 0x28e3, 0x28e3, 
+    0x28e3, 0x28e4, 0x28e4, 0x28e5, 0x28e5, 0x28e5, 0x28e6, 0x28e6, 
+    0x28e6, 0x28e7, 0x28e7, 0x28e7, 0x28e8, 0x28e8, 0x28e8, 0x28e9, 
+    0x28e9, 0x28e9, 0x28ea, 0x28ea, 0x28eb, 0x28eb, 0x28eb, 0x28ec, 
+    0x28ec, 0x28ec, 0x28ed, 0x28ed, 0x28ed, 0x28ee, 0x28ee, 0x28ee, 
+    0x28ef, 0x28ef, 0x28f0, 0x28f0, 0x28f0, 0x28f1, 0x28f1, 0x28f1, 
+    0x28f2, 0x28f2, 0x28f2, 0x28f3, 0x28f3, 0x28f3, 0x28f4, 0x28f4, 
+    0x28f4, 0x28f5, 0x28f5, 0x28f6, 0x28f6, 0x28f6, 0x28f7, 0x28f7, 
+    0x28f7, 0x28f8, 0x28f8, 0x28f8, 0x28f9, 0x28f9, 0x28f9, 0x28fa, 
+    0x28fa, 0x28fa, 0x28fb, 0x28fb, 0x28fb, 0x28fc, 0x28fc, 0x28fd, 
+    0x28fd, 0x28fd, 0x28fe, 0x28fe, 0x28fe, 0x28ff, 0x28ff, 0x28ff, 
+    0x2900, 0x2900, 0x2900, 0x2901, 0x2901, 0x2901, 0x2902, 0x2902, 
+    0x2902, 0x2903, 0x2903, 0x2903, 0x2904, 0x2904, 0x2905, 0x2905, 
+    0x2905, 0x2906, 0x2906, 0x2906, 0x2907, 0x2907, 0x2907, 0x2908, 
+    0x2908, 0x2908, 0x2909, 0x2909, 0x2909, 0x290a, 0x290a, 0x290a, 
+    0x290b, 0x290b, 0x290b, 0x290c, 0x290c, 0x290c, 0x290d, 0x290d, 
+    0x290d, 0x290e, 0x290e, 0x290e, 0x290f, 0x290f, 0x2910, 0x2910, 
+    0x2910, 0x2911, 0x2911, 0x2911, 0x2912, 0x2912, 0x2912, 0x2913, 
+    0x2913, 0x2913, 0x2914, 0x2914, 0x2914, 0x2915, 0x2915, 0x2915, 
+    0x2916, 0x2916, 0x2916, 0x2917, 0x2917, 0x2917, 0x2918, 0x2918, 
+    0x2918, 0x2919, 0x2919, 0x2919, 0x291a, 0x291a, 0x291a, 0x291b, 
+    0x291b, 0x291b, 0x291c, 0x291c, 0x291c, 0x291d, 0x291d, 0x291d, 
+    0x291e, 0x291e, 0x291f, 0x291f, 0x291f, 0x2920, 0x2920, 0x2920, 
+    0x2921, 0x2921, 0x2921, 0x2922, 0x2922, 0x2922, 0x2923, 0x2923, 
+    0x2923, 0x2924, 0x2924, 0x2924, 0x2925, 0x2925, 0x2925, 0x2926, 
+    0x2926, 0x2926, 0x2927, 0x2927, 0x2927, 0x2928, 0x2928, 0x2928, 
+    0x2929, 0x2929, 0x2929, 0x292a, 0x292a, 0x292a, 0x292b, 0x292b, 
+    0x292b, 0x292c, 0x292c, 0x292c, 0x292d, 0x292d, 0x292d, 0x292e, 
+    0x292e, 0x292e, 0x292f, 0x292f, 0x292f, 0x2930, 0x2930, 0x2930, 
+    0x2931, 0x2931, 0x2931, 0x2932, 0x2932, 0x2932, 0x2933, 0x2933, 
+    0x2933, 0x2934, 0x2934, 0x2934, 0x2935, 0x2935, 0x2935, 0x2936, 
+    0x2936, 0x2936, 0x2937, 0x2937, 0x2937, 0x2938, 0x2938, 0x2938, 
+    0x2939, 0x2939, 0x2939, 0x293a, 0x293a, 0x293a, 0x293b, 0x293b, 
+    0x293b, 0x293c, 0x293c, 0x293c, 0x293d, 0x293d, 0x293d, 0x293e, 
+    0x293e, 0x293e, 0x293e, 0x293f, 0x293f, 0x293f, 0x2940, 0x2940, 
+    0x2940, 0x2941, 0x2941, 0x2941, 0x2942, 0x2942, 0x2942, 0x2943, 
+    0x2943, 0x2943, 0x2944, 0x2944, 0x2944, 0x2945, 0x2945, 0x2945, 
+    0x2946, 0x2946, 0x2946, 0x2947, 0x2947, 0x2947, 0x2948, 0x2948, 
+    0x2948, 0x2949, 0x2949, 0x2949, 0x294a, 0x294a, 0x294a, 0x294b, 
+    0x294b, 0x294b, 0x294c, 0x294c, 0x294c, 0x294d, 0x294d, 0x294d, 
+    0x294d, 0x294e, 0x294e, 0x294e, 0x294f, 0x294f, 0x294f, 0x2950, 
+    0x2950, 0x2950, 0x2951, 0x2951, 0x2951, 0x2952, 0x2952, 0x2952, 
+    0x2953, 0x2953, 0x2953, 0x2954, 0x2954, 0x2954, 0x2955, 0x2955, 
+    0x2955, 0x2956, 0x2956, 0x2956, 0x2957, 0x2957, 0x2957, 0x2958, 
+    0x2958, 0x2958, 0x2958, 0x2959, 0x2959, 0x2959, 0x295a, 0x295a, 
+    0x295a, 0x295b, 0x295b, 0x295b, 0x295c, 0x295c, 0x295c, 0x295d, 
+    0x295d, 0x295d, 0x295e, 0x295e, 0x295e, 0x295f, 0x295f, 0x295f, 
+    0x2960, 0x2960, 0x2960, 0x2960, 0x2961, 0x2961, 0x2961, 0x2962, 
+    0x2962, 0x2962, 0x2963, 0x2963, 0x2963, 0x2964, 0x2964, 0x2964, 
+    0x2965, 0x2965, 0x2965, 0x2966, 0x2966, 0x2966, 0x2967, 0x2967, 
+    0x2967, 0x2967, 0x2968, 0x2968, 0x2968, 0x2969, 0x2969, 0x2969, 
+    0x296a, 0x296a, 0x296a, 0x296b, 0x296b, 0x296b, 0x296c, 0x296c, 
+    0x296c, 0x296d, 0x296d, 0x296d, 0x296d, 0x296e, 0x296e, 0x296e, 
+    0x296f, 0x296f, 0x296f, 0x2970, 0x2970, 0x2970, 0x2971, 0x2971, 
+    0x2971, 0x2972, 0x2972, 0x2972, 0x2972, 0x2973, 0x2973, 0x2973, 
+    0x2974, 0x2974, 0x2974, 0x2975, 0x2975, 0x2975, 0x2976, 0x2976, 
+    0x2976, 0x2977, 0x2977, 0x2977, 0x2977, 0x2978, 0x2978, 0x2978, 
+    0x2979, 0x2979, 0x2979, 0x297a, 0x297a, 0x297a, 0x297b, 0x297b, 
+    0x297b, 0x297c, 0x297c, 0x297d, 0x297e, 0x297e, 0x297f, 0x2980, 
+    0x2980, 0x2981, 0x2981, 0x2982, 0x2983, 0x2983, 0x2984, 0x2985, 
+    0x2985, 0x2986, 0x2986, 0x2987, 0x2988, 0x2988, 0x2989, 0x2989, 
+    0x298a, 0x298b, 0x298b, 0x298c, 0x298d, 0x298d, 0x298e, 0x298e, 
+    0x298f, 0x2990, 0x2990, 0x2991, 0x2991, 0x2992, 0x2993, 0x2993, 
+    0x2994, 0x2995, 0x2995, 0x2996, 0x2996, 0x2997, 0x2998, 0x2998, 
+    0x2999, 0x2999, 0x299a, 0x299b, 0x299b, 0x299c, 0x299c, 0x299d, 
+    0x299e, 0x299e, 0x299f, 0x299f, 0x29a0, 0x29a1, 0x29a1, 0x29a2, 
+    0x29a2, 0x29a3, 0x29a4, 0x29a4, 0x29a5, 0x29a5, 0x29a6, 0x29a7, 
+    0x29a7, 0x29a8, 0x29a8, 0x29a9, 0x29aa, 0x29aa, 0x29ab, 0x29ab, 
+    0x29ac, 0x29ad, 0x29ad, 0x29ae, 0x29ae, 0x29af, 0x29b0, 0x29b0, 
+    0x29b1, 0x29b1, 0x29b2, 0x29b3, 0x29b3, 0x29b4, 0x29b4, 0x29b5, 
+    0x29b6, 0x29b6, 0x29b7, 0x29b7, 0x29b8, 0x29b9, 0x29b9, 0x29ba, 
+    0x29ba, 0x29bb, 0x29bb, 0x29bc, 0x29bd, 0x29bd, 0x29be, 0x29be, 
+    0x29bf, 0x29c0, 0x29c0, 0x29c1, 0x29c1, 0x29c2, 0x29c3, 0x29c3, 
+    0x29c4, 0x29c4, 0x29c5, 0x29c5, 0x29c6, 0x29c7, 0x29c7, 0x29c8, 
+    0x29c8, 0x29c9, 0x29ca, 0x29ca, 0x29cb, 0x29cb, 0x29cc, 0x29cc, 
+    0x29cd, 0x29ce, 0x29ce, 0x29cf, 0x29cf, 0x29d0, 0x29d1, 0x29d1, 
+    0x29d2, 0x29d2, 0x29d3, 0x29d3, 0x29d4, 0x29d5, 0x29d5, 0x29d6, 
+    0x29d6, 0x29d7, 0x29d8, 0x29d8, 0x29d9, 0x29d9, 0x29da, 0x29da, 
+    0x29db, 0x29dc, 0x29dc, 0x29dd, 0x29dd, 0x29de, 0x29de, 0x29df, 
+    0x29e0, 0x29e0, 0x29e1, 0x29e1, 0x29e2, 0x29e2, 0x29e3, 0x29e4, 
+    0x29e4, 0x29e5, 0x29e5, 0x29e6, 0x29e6, 0x29e7, 0x29e8, 0x29e8, 
+    0x29e9, 0x29e9, 0x29ea, 0x29ea, 0x29eb, 0x29ec, 0x29ec, 0x29ed, 
+    0x29ed, 0x29ee, 0x29ee, 0x29ef, 0x29f0, 0x29f0, 0x29f1, 0x29f1, 
+    0x29f2, 0x29f2, 0x29f3, 0x29f3, 0x29f4, 0x29f5, 0x29f5, 0x29f6, 
+    0x29f6, 0x29f7, 0x29f7, 0x29f8, 0x29f9, 0x29f9, 0x29fa, 0x29fa, 
+    0x29fb, 0x29fb, 0x29fc, 0x29fc, 0x29fd, 0x29fe, 0x29fe, 0x29ff, 
+    0x29ff, 0x2a00, 0x2a00, 0x2a01, 0x2a02, 0x2a02, 0x2a03, 0x2a03, 
+    0x2a04, 0x2a04, 0x2a05, 0x2a05, 0x2a06, 0x2a07, 0x2a07, 0x2a08, 
+    0x2a08, 0x2a09, 0x2a09, 0x2a0a, 0x2a0a, 0x2a0b, 0x2a0c, 0x2a0c, 
+    0x2a0d, 0x2a0d, 0x2a0e, 0x2a0e, 0x2a0f, 0x2a0f, 0x2a10, 0x2a10, 
+    0x2a11, 0x2a12, 0x2a12, 0x2a13, 0x2a13, 0x2a14, 0x2a14, 0x2a15, 
+    0x2a15, 0x2a16, 0x2a17, 0x2a17, 0x2a18, 0x2a18, 0x2a19, 0x2a19, 
+    0x2a1a, 0x2a1a, 0x2a1b, 0x2a1b, 0x2a1c, 0x2a1d, 0x2a1d, 0x2a1e, 
+    0x2a1e, 0x2a1f, 0x2a1f, 0x2a20, 0x2a20, 0x2a21, 0x2a21, 0x2a22, 
+    0x2a23, 0x2a23, 0x2a24, 0x2a24, 0x2a25, 0x2a25, 0x2a26, 0x2a26, 
+    0x2a27, 0x2a27, 0x2a28, 0x2a29, 0x2a29, 0x2a2a, 0x2a2a, 0x2a2b, 
+    0x2a2b, 0x2a2c, 0x2a2c, 0x2a2d, 0x2a2d, 0x2a2e, 0x2a2e, 0x2a2f, 
+    0x2a30, 0x2a30, 0x2a31, 0x2a31, 0x2a32, 0x2a32, 0x2a33, 0x2a33, 
+    0x2a34, 0x2a34, 0x2a35, 0x2a35, 0x2a36, 0x2a37, 0x2a37, 0x2a38, 
+    0x2a38, 0x2a39, 0x2a39, 0x2a3a, 0x2a3a, 0x2a3b, 0x2a3b, 0x2a3c, 
+    0x2a3c, 0x2a3d, 0x2a3d, 0x2a3e, 0x2a3f, 0x2a3f, 0x2a40, 0x2a40, 
+    0x2a41, 0x2a41, 0x2a42, 0x2a42, 0x2a43, 0x2a43, 0x2a44, 0x2a44, 
+    0x2a45, 0x2a45, 0x2a46, 0x2a47, 0x2a47, 0x2a48, 0x2a48, 0x2a49, 
+    0x2a49, 0x2a4a, 0x2a4a, 0x2a4b, 0x2a4b, 0x2a4c, 0x2a4c, 0x2a4d, 
+    0x2a4d, 0x2a4e, 0x2a4e, 0x2a4f, 0x2a50, 0x2a50, 0x2a51, 0x2a51, 
+    0x2a52, 0x2a52, 0x2a53, 0x2a53, 0x2a54, 0x2a54, 0x2a55, 0x2a55, 
+    0x2a56, 0x2a56, 0x2a57, 0x2a57, 0x2a58, 0x2a58, 0x2a59, 0x2a59, 
+    0x2a5a, 0x2a5b, 0x2a5b, 0x2a5c, 0x2a5c, 0x2a5d, 0x2a5d, 0x2a5e, 
+    0x2a5e, 0x2a5f, 0x2a5f, 0x2a60, 0x2a60, 0x2a61, 0x2a61, 0x2a62, 
+    0x2a62, 0x2a63, 0x2a63, 0x2a64, 0x2a64, 0x2a65, 0x2a65, 0x2a66, 
+    0x2a66, 0x2a67, 0x2a67, 0x2a68, 0x2a69, 0x2a69, 0x2a6a, 0x2a6a, 
+    0x2a6b, 0x2a6b, 0x2a6c, 0x2a6c, 0x2a6d, 0x2a6d, 0x2a6e, 0x2a6e, 
+    0x2a6f, 0x2a6f, 0x2a70, 0x2a70, 0x2a71, 0x2a71, 0x2a72, 0x2a72, 
+    0x2a73, 0x2a73, 0x2a74, 0x2a74, 0x2a75, 0x2a75, 0x2a76, 0x2a76, 
+    0x2a77, 0x2a77, 0x2a78, 0x2a78, 0x2a79, 0x2a79, 0x2a7a, 0x2a7a, 
+    0x2a7b, 0x2a7b, 0x2a7c, 0x2a7d, 0x2a7d, 0x2a7e, 0x2a7e, 0x2a7f, 
+    0x2a7f, 0x2a80, 0x2a80, 0x2a81, 0x2a81, 0x2a82, 0x2a82, 0x2a83, 
+    0x2a83, 0x2a84, 0x2a84, 0x2a85, 0x2a85, 0x2a86, 0x2a86, 0x2a87, 
+    0x2a87, 0x2a88, 0x2a88, 0x2a89, 0x2a89, 0x2a8a, 0x2a8a, 0x2a8b, 
+    0x2a8b, 0x2a8c, 0x2a8c, 0x2a8d, 0x2a8d, 0x2a8e, 0x2a8e, 0x2a8f, 
+    0x2a8f, 0x2a90, 0x2a90, 0x2a91, 0x2a91, 0x2a92, 0x2a92, 0x2a93, 
+    0x2a93, 0x2a94, 0x2a94, 0x2a95, 0x2a95, 0x2a96, 0x2a96, 0x2a97, 
+    0x2a97, 0x2a98, 0x2a98, 0x2a99, 0x2a99, 0x2a9a, 0x2a9a, 0x2a9b, 
+    0x2a9b, 0x2a9c, 0x2a9c, 0x2a9d, 0x2a9d, 0x2a9e, 0x2a9e, 0x2a9f, 
+    0x2a9f, 0x2aa0, 0x2aa0, 0x2aa1, 0x2aa1, 0x2aa2, 0x2aa2, 0x2aa3, 
+    0x2aa3, 0x2aa4, 0x2aa4, 0x2aa5, 0x2aa5, 0x2aa6, 0x2aa6, 0x2aa7, 
+    0x2aa7, 0x2aa8, 0x2aa8, 0x2aa9, 0x2aa9, 0x2aaa, 0x2aaa, 0x2aab, 
+    0x2aab, 0x2aac, 0x2aac, 0x2aad, 0x2aad, 0x2aae, 0x2aae, 0x2aaf, 
+    0x2aaf, 0x2aaf, 0x2ab0, 0x2ab0, 0x2ab1, 0x2ab1, 0x2ab2, 0x2ab2, 
+    0x2ab3, 0x2ab3, 0x2ab4, 0x2ab4, 0x2ab5, 0x2ab5, 0x2ab6, 0x2ab6, 
+    0x2ab7, 0x2ab7, 0x2ab8, 0x2ab8, 0x2ab9, 0x2ab9, 0x2aba, 0x2aba, 
+    0x2abb, 0x2abb, 0x2abc, 0x2abc, 0x2abd, 0x2abd, 0x2abe, 0x2abe, 
+    0x2abf, 0x2abf, 0x2ac0, 0x2ac0, 0x2ac1, 0x2ac1, 0x2ac2, 0x2ac2, 
+    0x2ac2, 0x2ac3, 0x2ac3, 0x2ac4, 0x2ac4, 0x2ac5, 0x2ac5, 0x2ac6, 
+    0x2ac6, 0x2ac7, 0x2ac7, 0x2ac8, 0x2ac8, 0x2ac9, 0x2ac9, 0x2aca, 
+    0x2aca, 0x2acb, 0x2acb, 0x2acc, 0x2acc, 0x2acd, 0x2acd, 0x2ace, 
+    0x2ace, 0x2acf, 0x2acf, 0x2ad0, 0x2ad0, 0x2ad0, 0x2ad1, 0x2ad1, 
+    0x2ad2, 0x2ad2, 0x2ad3, 0x2ad3, 0x2ad4, 0x2ad4, 0x2ad5, 0x2ad5, 
+    0x2ad6, 0x2ad6, 0x2ad7, 0x2ad7, 0x2ad8, 0x2ad8, 0x2ad9, 0x2ad9, 
+    0x2ada, 0x2ada, 0x2adb, 0x2adb, 0x2adb, 0x2adc, 0x2adc, 0x2add, 
+    0x2add, 0x2ade, 0x2ade, 0x2adf, 0x2adf, 0x2ae0, 0x2ae0, 0x2ae1, 
+    0x2ae1, 0x2ae2, 0x2ae2, 0x2ae3, 0x2ae3, 0x2ae4, 0x2ae4, 0x2ae4, 
+    0x2ae5, 0x2ae5, 0x2ae6, 0x2ae6, 0x2ae7, 0x2ae7, 0x2ae8, 0x2ae8, 
+    0x2ae9, 0x2ae9, 0x2aea, 0x2aea, 0x2aeb, 0x2aeb, 0x2aec, 0x2aec, 
+    0x2aed, 0x2aed, 0x2aed, 0x2aee, 0x2aee, 0x2aef, 0x2aef, 0x2af0, 
+    0x2af0, 0x2af1, 0x2af1, 0x2af2, 0x2af2, 0x2af3, 0x2af3, 0x2af4, 
+    0x2af4, 0x2af4, 0x2af5, 0x2af5, 0x2af6, 0x2af6, 0x2af7, 0x2af7, 
+    0x2af8, 0x2af8, 0x2af9, 0x2af9, 0x2afa, 0x2afa, 0x2afb, 0x2afb, 
+    0x2afb, 0x2afc, 0x2afc, 0x2afd, 0x2afd, 0x2afe, 0x2afe, 0x2aff, 
+    0x2aff, 0x2b00, 0x2b00, 0x2b01, 0x2b01, 0x2b02, 0x2b02, 0x2b02, 
+    0x2b03, 0x2b03, 0x2b04, 0x2b04, 0x2b05, 0x2b05, 0x2b06, 0x2b06, 
+    0x2b07, 0x2b07, 0x2b08, 0x2b08, 0x2b08, 0x2b09, 0x2b09, 0x2b0a, 
+    0x2b0a, 0x2b0b, 0x2b0b, 0x2b0c, 0x2b0c, 0x2b0d, 0x2b0d, 0x2b0e, 
+    0x2b0e, 0x2b0e, 0x2b0f, 0x2b0f, 0x2b10, 0x2b10, 0x2b11, 0x2b11, 
+    0x2b12, 0x2b12, 0x2b13, 0x2b13, 0x2b14, 0x2b14, 0x2b14, 0x2b15, 
+    0x2b15, 0x2b16, 0x2b16, 0x2b17, 0x2b17, 0x2b18, 0x2b18, 0x2b19, 
+    0x2b19, 0x2b19, 0x2b1a, 0x2b1a, 0x2b1b, 0x2b1b, 0x2b1c, 0x2b1c, 
+    0x2b1d, 0x2b1d, 0x2b1e, 0x2b1e, 0x2b1e, 0x2b1f, 0x2b1f, 0x2b20, 
+    0x2b20, 0x2b21, 0x2b21, 0x2b22, 0x2b22, 0x2b23, 0x2b23, 0x2b23, 
+    0x2b24, 0x2b24, 0x2b25, 0x2b25, 0x2b26, 0x2b26, 0x2b27, 0x2b27, 
+    0x2b28, 0x2b28, 0x2b28, 0x2b29, 0x2b29, 0x2b2a, 0x2b2a, 0x2b2b, 
+    0x2b2b, 0x2b2c, 0x2b2c, 0x2b2d, 0x2b2d, 0x2b2d, 0x2b2e, 0x2b2e, 
+    0x2b2f, 0x2b2f, 0x2b30, 0x2b30, 0x2b31, 0x2b31, 0x2b31, 0x2b32, 
+    0x2b32, 0x2b33, 0x2b33, 0x2b34, 0x2b34, 0x2b35, 0x2b35, 0x2b36, 
+    0x2b36, 0x2b36, 0x2b37, 0x2b37, 0x2b38, 0x2b38, 0x2b39, 0x2b39, 
+    0x2b3a, 0x2b3a, 0x2b3a, 0x2b3b, 0x2b3b, 0x2b3c, 0x2b3c, 0x2b3d, 
+    0x2b3d, 0x2b3e, 0x2b3e, 0x2b3e, 0x2b3f, 0x2b3f, 0x2b40, 0x2b40, 
+    0x2b41, 0x2b41, 0x2b42, 0x2b42, 0x2b42, 0x2b43, 0x2b43, 0x2b44, 
+    0x2b44, 0x2b45, 0x2b45, 0x2b46, 0x2b46, 0x2b46, 0x2b47, 0x2b47, 
+    0x2b48, 0x2b48, 0x2b49, 0x2b49, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4b, 
+    0x2b4b, 0x2b4c, 0x2b4c, 0x2b4d, 0x2b4d, 0x2b4e, 0x2b4e, 0x2b4e, 
+    0x2b4f, 0x2b4f, 0x2b50, 0x2b50, 0x2b51, 0x2b51, 0x2b52, 0x2b52, 
+    0x2b52, 0x2b53, 0x2b53, 0x2b54, 0x2b54, 0x2b55, 0x2b55, 0x2b55, 
+    0x2b56, 0x2b56, 0x2b57, 0x2b57, 0x2b58, 0x2b58, 0x2b59, 0x2b59, 
+    0x2b59, 0x2b5a, 0x2b5a, 0x2b5b, 0x2b5b, 0x2b5c, 0x2b5c, 0x2b5c, 
+    0x2b5d, 0x2b5d, 0x2b5e, 0x2b5e, 0x2b5f, 0x2b5f, 0x2b60, 0x2b60, 
+    0x2b60, 0x2b61, 0x2b61, 0x2b62, 0x2b62, 0x2b63, 0x2b63, 0x2b63, 
+    0x2b64, 0x2b64, 0x2b65, 0x2b65, 0x2b66, 0x2b66, 0x2b67, 0x2b67, 
+    0x2b67, 0x2b68, 0x2b68, 0x2b69, 0x2b69, 0x2b6a, 0x2b6a, 0x2b6a, 
+    0x2b6b, 0x2b6b, 0x2b6c, 0x2b6c, 0x2b6d, 0x2b6d, 0x2b6d, 0x2b6e, 
+    0x2b6e, 0x2b6f, 0x2b6f, 0x2b70, 0x2b70, 0x2b70, 0x2b71, 0x2b71, 
+    0x2b72, 0x2b72, 0x2b73, 0x2b73, 0x2b73, 0x2b74, 0x2b74, 0x2b75, 
+    0x2b75, 0x2b76, 0x2b76, 0x2b77, 0x2b77, 0x2b77, 0x2b78, 0x2b78, 
+    0x2b79, 0x2b79, 0x2b7a, 0x2b7a, 0x2b7a, 0x2b7b, 0x2b7b, 0x2b7c, 
+    0x2b7c, 0x2b7d, 0x2b7d, 0x2b7d, 0x2b7e, 0x2b7e, 0x2b7f, 0x2b7f, 
+    0x2b80, 0x2b80, 0x2b80, 0x2b81, 0x2b81, 0x2b82, 0x2b82, 0x2b83, 
+    0x2b83, 0x2b84, 0x2b85, 0x2b85, 0x2b86, 0x2b87, 0x2b88, 0x2b89, 
+    0x2b8a, 0x2b8b, 0x2b8b, 0x2b8c, 0x2b8d, 0x2b8e, 0x2b8f, 0x2b90, 
+    0x2b91, 0x2b91, 0x2b92, 0x2b93, 0x2b94, 0x2b95, 0x2b96, 0x2b96, 
+    0x2b97, 0x2b98, 0x2b99, 0x2b9a, 0x2b9b, 0x2b9b, 0x2b9c, 0x2b9d, 
+    0x2b9e, 0x2b9f, 0x2ba0, 0x2ba1, 0x2ba1, 0x2ba2, 0x2ba3, 0x2ba4, 
+    0x2ba5, 0x2ba6, 0x2ba6, 0x2ba7, 0x2ba8, 0x2ba9, 0x2baa, 0x2bab, 
+    0x2bab, 0x2bac, 0x2bad, 0x2bae, 0x2baf, 0x2bb0, 0x2bb0, 0x2bb1, 
+    0x2bb2, 0x2bb3, 0x2bb4, 0x2bb5, 0x2bb5, 0x2bb6, 0x2bb7, 0x2bb8, 
+    0x2bb9, 0x2bb9, 0x2bba, 0x2bbb, 0x2bbc, 0x2bbd, 0x2bbe, 0x2bbe, 
+    0x2bbf, 0x2bc0, 0x2bc1, 0x2bc2, 0x2bc3, 0x2bc3, 0x2bc4, 0x2bc5, 
+    0x2bc6, 0x2bc7, 0x2bc7, 0x2bc8, 0x2bc9, 0x2bca, 0x2bcb, 0x2bcc, 
+    0x2bcc, 0x2bcd, 0x2bce, 0x2bcf, 0x2bd0, 0x2bd0, 0x2bd1, 0x2bd2, 
+    0x2bd3, 0x2bd4, 0x2bd4, 0x2bd5, 0x2bd6, 0x2bd7, 0x2bd8, 0x2bd9, 
+    0x2bd9, 0x2bda, 0x2bdb, 0x2bdc, 0x2bdd, 0x2bdd, 0x2bde, 0x2bdf, 
+    0x2be0, 0x2be1, 0x2be1, 0x2be2, 0x2be3, 0x2be4, 0x2be5, 0x2be5, 
+    0x2be6, 0x2be7, 0x2be8, 0x2be9, 0x2be9, 0x2bea, 0x2beb, 0x2bec, 
+    0x2bed, 0x2bed, 0x2bee, 0x2bef, 0x2bf0, 0x2bf1, 0x2bf1, 0x2bf2, 
+    0x2bf3, 0x2bf4, 0x2bf5, 0x2bf5, 0x2bf6, 0x2bf7, 0x2bf8, 0x2bf9, 
+    0x2bf9, 0x2bfa, 0x2bfb, 0x2bfc, 0x2bfd, 0x2bfd, 0x2bfe, 0x2bff, 
+    0x2c00, 0x2c00, 0x2c01, 0x2c01, 0x2c01, 0x2c02, 0x2c02, 0x2c03, 
+    0x2c03, 0x2c03, 0x2c04, 0x2c04, 0x2c05, 0x2c05, 0x2c05, 0x2c06, 
+    0x2c06, 0x2c07, 0x2c07, 0x2c07, 0x2c08, 0x2c08, 0x2c09, 0x2c09, 
+    0x2c09, 0x2c0a, 0x2c0a, 0x2c0b, 0x2c0b, 0x2c0b, 0x2c0c, 0x2c0c, 
+    0x2c0c, 0x2c0d, 0x2c0d, 0x2c0e, 0x2c0e, 0x2c0e, 0x2c0f, 0x2c0f, 
+    0x2c10, 0x2c10, 0x2c10, 0x2c11, 0x2c11, 0x2c12, 0x2c12, 0x2c12, 
+    0x2c13, 0x2c13, 0x2c13, 0x2c14, 0x2c14, 0x2c15, 0x2c15, 0x2c15, 
+    0x2c16, 0x2c16, 0x2c17, 0x2c17, 0x2c17, 0x2c18, 0x2c18, 0x2c18, 
+    0x2c19, 0x2c19, 0x2c1a, 0x2c1a, 0x2c1a, 0x2c1b, 0x2c1b, 0x2c1c, 
+    0x2c1c, 0x2c1c, 0x2c1d, 0x2c1d, 0x2c1d, 0x2c1e, 0x2c1e, 0x2c1f, 
+    0x2c1f, 0x2c1f, 0x2c20, 0x2c20, 0x2c21, 0x2c21, 0x2c21, 0x2c22, 
+    0x2c22, 0x2c22, 0x2c23, 0x2c23, 0x2c24, 0x2c24, 0x2c24, 0x2c25, 
+    0x2c25, 0x2c25, 0x2c26, 0x2c26, 0x2c27, 0x2c27, 0x2c27, 0x2c28, 
+    0x2c28, 0x2c28, 0x2c29, 0x2c29, 0x2c2a, 0x2c2a, 0x2c2a, 0x2c2b, 
+    0x2c2b, 0x2c2b, 0x2c2c, 0x2c2c, 0x2c2d, 0x2c2d, 0x2c2d, 0x2c2e, 
+    0x2c2e, 0x2c2f, 0x2c2f, 0x2c2f, 0x2c30, 0x2c30, 0x2c30, 0x2c31, 
+    0x2c31, 0x2c32, 0x2c32, 0x2c32, 0x2c33, 0x2c33, 0x2c33, 0x2c34, 
+    0x2c34, 0x2c34, 0x2c35, 0x2c35, 0x2c36, 0x2c36, 0x2c36, 0x2c37, 
+    0x2c37, 0x2c37, 0x2c38, 0x2c38, 0x2c39, 0x2c39, 0x2c39, 0x2c3a, 
+    0x2c3a, 0x2c3a, 0x2c3b, 0x2c3b, 0x2c3c, 0x2c3c, 0x2c3c, 0x2c3d, 
+    0x2c3d, 0x2c3d, 0x2c3e, 0x2c3e, 0x2c3e, 0x2c3f, 0x2c3f, 0x2c40, 
+    0x2c40, 0x2c40, 0x2c41, 0x2c41, 0x2c41, 0x2c42, 0x2c42, 0x2c43, 
+    0x2c43, 0x2c43, 0x2c44, 0x2c44, 0x2c44, 0x2c45, 0x2c45, 0x2c45, 
+    0x2c46, 0x2c46, 0x2c47, 0x2c47, 0x2c47, 0x2c48, 0x2c48, 0x2c48, 
+    0x2c49, 0x2c49, 0x2c49, 0x2c4a, 0x2c4a, 0x2c4b, 0x2c4b, 0x2c4b, 
+    0x2c4c, 0x2c4c, 0x2c4c, 0x2c4d, 0x2c4d, 0x2c4d, 0x2c4e, 0x2c4e, 
+    0x2c4f, 0x2c4f, 0x2c4f, 0x2c50, 0x2c50, 0x2c50, 0x2c51, 0x2c51, 
+    0x2c51, 0x2c52, 0x2c52, 0x2c53, 0x2c53, 0x2c53, 0x2c54, 0x2c54, 
+    0x2c54, 0x2c55, 0x2c55, 0x2c55, 0x2c56, 0x2c56, 0x2c56, 0x2c57, 
+    0x2c57, 0x2c58, 0x2c58, 0x2c58, 0x2c59, 0x2c59, 0x2c59, 0x2c5a, 
+    0x2c5a, 0x2c5a, 0x2c5b, 0x2c5b, 0x2c5c, 0x2c5c, 0x2c5c, 0x2c5d, 
+    0x2c5d, 0x2c5d, 0x2c5e, 0x2c5e, 0x2c5e, 0x2c5f, 0x2c5f, 0x2c5f, 
+    0x2c60, 0x2c60, 0x2c60, 0x2c61, 0x2c61, 0x2c62, 0x2c62, 0x2c62, 
+    0x2c63, 0x2c63, 0x2c63, 0x2c64, 0x2c64, 0x2c64, 0x2c65, 0x2c65, 
+    0x2c65, 0x2c66, 0x2c66, 0x2c67, 0x2c67, 0x2c67, 0x2c68, 0x2c68, 
+    0x2c68, 0x2c69, 0x2c69, 0x2c69, 0x2c6a, 0x2c6a, 0x2c6a, 0x2c6b, 
+    0x2c6b, 0x2c6b, 0x2c6c, 0x2c6c, 0x2c6c, 0x2c6d, 0x2c6d, 0x2c6e, 
+    0x2c6e, 0x2c6e, 0x2c6f, 0x2c6f, 0x2c6f, 0x2c70, 0x2c70, 0x2c70, 
+    0x2c71, 0x2c71, 0x2c71, 0x2c72, 0x2c72, 0x2c72, 0x2c73, 0x2c73, 
+    0x2c73, 0x2c74, 0x2c74, 0x2c75, 0x2c75, 0x2c75, 0x2c76, 0x2c76, 
+    0x2c76, 0x2c77, 0x2c77, 0x2c77, 0x2c78, 0x2c78, 0x2c78, 0x2c79, 
+    0x2c79, 0x2c79, 0x2c7a, 0x2c7a, 0x2c7a, 0x2c7b, 0x2c7b, 0x2c7b, 
+    0x2c7c, 0x2c7c, 0x2c7c, 0x2c7d, 0x2c7d, 0x2c7e, 0x2c7e, 0x2c7e, 
+    0x2c7f, 0x2c7f, 0x2c7f, 0x2c80, 0x2c80, 0x2c80, 0x2c81, 0x2c81, 
+    0x2c81, 0x2c82, 0x2c82, 0x2c82, 0x2c83, 0x2c83, 0x2c83, 0x2c84, 
+    0x2c84, 0x2c84, 0x2c85, 0x2c85, 0x2c85, 0x2c86, 0x2c86, 0x2c86, 
+    0x2c87, 0x2c87, 0x2c87, 0x2c88, 0x2c88, 0x2c88, 0x2c89, 0x2c89, 
+    0x2c8a, 0x2c8a, 0x2c8a, 0x2c8b, 0x2c8b, 0x2c8b, 0x2c8c, 0x2c8c, 
+    0x2c8c, 0x2c8d, 0x2c8d, 0x2c8d, 0x2c8e, 0x2c8e, 0x2c8e, 0x2c8f, 
+    0x2c8f, 0x2c8f, 0x2c90, 0x2c90, 0x2c90, 0x2c91, 0x2c91, 0x2c91, 
+    0x2c92, 0x2c92, 0x2c92, 0x2c93, 0x2c93, 0x2c93, 0x2c94, 0x2c94, 
+    0x2c94, 0x2c95, 0x2c95, 0x2c95, 0x2c96, 0x2c96, 0x2c96, 0x2c97, 
+    0x2c97, 0x2c97, 0x2c98, 0x2c98, 0x2c98, 0x2c99, 0x2c99, 0x2c99, 
+    0x2c9a, 0x2c9a, 0x2c9a, 0x2c9b, 0x2c9b, 0x2c9b, 0x2c9c, 0x2c9c, 
+    0x2c9c, 0x2c9d, 0x2c9d, 0x2c9d, 0x2c9e, 0x2c9e, 0x2c9e, 0x2c9f, 
+    0x2c9f, 0x2c9f, 0x2ca0, 0x2ca0, 0x2ca0, 0x2ca1, 0x2ca1, 0x2ca1, 
+    0x2ca2, 0x2ca2, 0x2ca2, 0x2ca3, 0x2ca3, 0x2ca3, 0x2ca4, 0x2ca4, 
+    0x2ca4, 0x2ca5, 0x2ca5, 0x2ca5, 0x2ca6, 0x2ca6, 0x2ca6, 0x2ca7, 
+    0x2ca7, 0x2ca7, 0x2ca8, 0x2ca8, 0x2ca8, 0x2ca9, 0x2ca9, 0x2ca9, 
+    0x2caa, 0x2caa, 0x2caa, 0x2cab, 0x2cab, 0x2cab, 0x2cac, 0x2cac, 
+    0x2cac, 0x2cad, 0x2cad, 0x2cad, 0x2cae, 0x2cae, 0x2cae, 0x2caf, 
+    0x2caf, 0x2caf, 0x2cb0, 0x2cb0, 0x2cb0, 0x2cb1, 0x2cb1, 0x2cb1, 
+    0x2cb1, 0x2cb2, 0x2cb2, 0x2cb2, 0x2cb3, 0x2cb3, 0x2cb3, 0x2cb4, 
+    0x2cb4, 0x2cb4, 0x2cb5, 0x2cb5, 0x2cb5, 0x2cb6, 0x2cb6, 0x2cb6, 
+    0x2cb7, 0x2cb7, 0x2cb7, 0x2cb8, 0x2cb8, 0x2cb8, 0x2cb9, 0x2cb9, 
+    0x2cb9, 0x2cba, 0x2cba, 0x2cba, 0x2cbb, 0x2cbb, 0x2cbb, 0x2cbc, 
+    0x2cbc, 0x2cbc, 0x2cbd, 0x2cbd, 0x2cbd, 0x2cbe, 0x2cbe, 0x2cbe, 
+    0x2cbe, 0x2cbf, 0x2cbf, 0x2cbf, 0x2cc0, 0x2cc0, 0x2cc0, 0x2cc1, 
+    0x2cc1, 0x2cc1, 0x2cc2, 0x2cc2, 0x2cc2, 0x2cc3, 0x2cc3, 0x2cc3, 
+    0x2cc4, 0x2cc4, 0x2cc4, 0x2cc5, 0x2cc5, 0x2cc5, 0x2cc6, 0x2cc6, 
+    0x2cc6, 0x2cc7, 0x2cc7, 0x2cc7, 0x2cc7, 0x2cc8, 0x2cc8, 0x2cc8, 
+    0x2cc9, 0x2cc9, 0x2cc9, 0x2cca, 0x2cca, 0x2cca, 0x2ccb, 0x2ccb, 
+    0x2ccb, 0x2ccc, 0x2ccc, 0x2ccc, 0x2ccd, 0x2ccd, 0x2ccd, 0x2cce, 
+    0x2cce, 0x2cce, 0x2cce, 0x2ccf, 0x2ccf, 0x2ccf, 0x2cd0, 0x2cd0, 
+    0x2cd0, 0x2cd1, 0x2cd1, 0x2cd1, 0x2cd2, 0x2cd2, 0x2cd2, 0x2cd3, 
+    0x2cd3, 0x2cd3, 0x2cd4, 0x2cd4, 0x2cd4, 0x2cd4, 0x2cd5, 0x2cd5, 
+    0x2cd5, 0x2cd6, 0x2cd6, 0x2cd6, 0x2cd7, 0x2cd7, 0x2cd7, 0x2cd8, 
+    0x2cd8, 0x2cd8, 0x2cd9, 0x2cd9, 0x2cd9, 0x2cda, 0x2cda, 0x2cda, 
+    0x2cda, 0x2cdb, 0x2cdb, 0x2cdb, 0x2cdc, 0x2cdc, 0x2cdc, 0x2cdd, 
+    0x2cdd, 0x2cdd, 0x2cde, 0x2cde, 0x2cde, 0x2cdf, 0x2cdf, 0x2cdf, 
+    0x2cdf, 0x2ce0, 0x2ce0, 0x2ce0, 0x2ce1, 0x2ce1, 0x2ce1, 0x2ce2, 
+    0x2ce2, 0x2ce2, 0x2ce3, 0x2ce3, 0x2ce3, 0x2ce4, 0x2ce4, 0x2ce4, 
+    0x2ce4, 0x2ce5, 0x2ce5, 0x2ce5, 0x2ce6, 0x2ce6, 0x2ce6, 0x2ce7, 
+    0x2ce7, 0x2ce7, 0x2ce8, 0x2ce8, 0x2ce8, 0x2ce8, 0x2ce9, 0x2ce9, 
+    0x2ce9, 0x2cea, 0x2cea, 0x2cea, 0x2ceb, 0x2ceb, 0x2ceb, 0x2cec, 
+    0x2cec, 0x2cec, 0x2ced, 0x2ced, 0x2ced, 0x2ced, 0x2cee, 0x2cee, 
+    0x2cee, 0x2cef, 0x2cef, 0x2cef, 0x2cf0, 0x2cf0, 0x2cf0, 0x2cf1, 
+    0x2cf1, 0x2cf1, 0x2cf1, 0x2cf2, 0x2cf2, 0x2cf2, 0x2cf3, 0x2cf3, 
+    0x2cf3, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf5, 0x2cf5, 0x2cf5, 
+    0x2cf6, 0x2cf6, 0x2cf6, 0x2cf7, 0x2cf7, 0x2cf7, 0x2cf8, 0x2cf8, 
+    0x2cf8, 0x2cf8, 0x2cf9, 0x2cf9, 0x2cf9, 0x2cfa, 0x2cfa, 0x2cfa, 
+    0x2cfb, 0x2cfb, 0x2cfb, 0x2cfc, 0x2cfc, 0x2cfc, 0x2cfc, 0x2cfd, 
+    0x2cfd, 0x2cfd, 0x2cfe, 0x2cfe, 0x2cfe, 0x2cff, 0x2cff, 0x2cff, 
+    0x2cff, 0x2d00, 0x2d00, 0x2d00, 0x2d01, 0x2d01, 0x2d01, 0x2d02, 
+    0x2d02, 0x2d02, 0x2d02, 0x2d03, 0x2d03, 0x2d03, 0x2d04, 0x2d04, 
+    0x2d04, 0x2d05, 0x2d05, 0x2d05, 0x2d05, 0x2d06, 0x2d06, 0x2d06, 
+    0x2d07, 0x2d07, 0x2d07, 0x2d08, 0x2d08, 0x2d08, 0x2d09, 0x2d09, 
+    0x2d09, 0x2d09, 0x2d0a, 0x2d0a, 0x2d0a, 0x2d0b, 0x2d0b, 0x2d0b, 
+    0x2d0c, 0x2d0c, 0x2d0c, 0x2d0c, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0e, 
+    0x2d0e, 0x2d0e, 0x2d0e, 0x2d0f, 0x2d0f, 0x2d0f, 0x2d10, 0x2d10, 
+    0x2d10, 0x2d11, 0x2d11, 0x2d11, 0x2d11, 0x2d12, 0x2d12, 0x2d12, 
+    0x2d13, 0x2d13, 0x2d13, 0x2d14, 0x2d14, 0x2d14, 0x2d14, 0x2d15, 
+    0x2d15, 0x2d15, 0x2d16, 0x2d16, 0x2d16, 0x2d17, 0x2d17, 0x2d17, 
+    0x2d17, 0x2d18, 0x2d18, 0x2d18, 0x2d19, 0x2d19, 0x2d19, 0x2d19, 
+    0x2d1a, 0x2d1a, 0x2d1a, 0x2d1b, 0x2d1b, 0x2d1b, 0x2d1c, 0x2d1c, 
+    0x2d1c, 0x2d1c, 0x2d1d, 0x2d1d, 0x2d1d, 0x2d1e, 0x2d1e, 0x2d1e, 
+    0x2d1f, 0x2d1f, 0x2d1f, 0x2d1f, 0x2d20, 0x2d20, 0x2d20, 0x2d21, 
+    0x2d21, 0x2d21, 0x2d21, 0x2d22, 0x2d22, 0x2d22, 0x2d23, 0x2d23, 
+    0x2d23, 0x2d23, 0x2d24, 0x2d24, 0x2d24, 0x2d25, 0x2d25, 0x2d25, 
+    0x2d26, 0x2d26, 0x2d27, 0x2d27, 0x2d28, 0x2d28, 0x2d29, 0x2d2a, 
+    0x2d2a, 0x2d2b, 0x2d2b, 0x2d2c, 0x2d2d, 0x2d2d, 0x2d2e, 0x2d2e, 
+    0x2d2f, 0x2d2f, 0x2d30, 0x2d31, 0x2d31, 0x2d32, 0x2d32, 0x2d33, 
+    0x2d33, 0x2d34, 0x2d35, 0x2d35, 0x2d36, 0x2d36, 0x2d37, 0x2d38, 
+    0x2d38, 0x2d39, 0x2d39, 0x2d3a, 0x2d3a, 0x2d3b, 0x2d3c, 0x2d3c, 
+    0x2d3d, 0x2d3d, 0x2d3e, 0x2d3e, 0x2d3f, 0x2d40, 0x2d40, 0x2d41, 
+    0x2d41, 0x2d42, 0x2d42, 0x2d43, 0x2d44, 0x2d44, 0x2d45, 0x2d45, 
+    0x2d46, 0x2d46, 0x2d47, 0x2d48, 0x2d48, 0x2d49, 0x2d49, 0x2d4a, 
+    0x2d4a, 0x2d4b, 0x2d4b, 0x2d4c, 0x2d4d, 0x2d4d, 0x2d4e, 0x2d4e, 
+    0x2d4f, 0x2d4f, 0x2d50, 0x2d51, 0x2d51, 0x2d52, 0x2d52, 0x2d53, 
+    0x2d53, 0x2d54, 0x2d54, 0x2d55, 0x2d56, 0x2d56, 0x2d57, 0x2d57, 
+    0x2d58, 0x2d58, 0x2d59, 0x2d5a, 0x2d5a, 0x2d5b, 0x2d5b, 0x2d5c, 
+    0x2d5c, 0x2d5d, 0x2d5d, 0x2d5e, 0x2d5f, 0x2d5f, 0x2d60, 0x2d60, 
+    0x2d61, 0x2d61, 0x2d62, 0x2d62, 0x2d63, 0x2d64, 0x2d64, 0x2d65, 
+    0x2d65, 0x2d66, 0x2d66, 0x2d67, 0x2d67, 0x2d68, 0x2d69, 0x2d69, 
+    0x2d6a, 0x2d6a, 0x2d6b, 0x2d6b, 0x2d6c, 0x2d6c, 0x2d6d, 0x2d6d, 
+    0x2d6e, 0x2d6f, 0x2d6f, 0x2d70, 0x2d70, 0x2d71, 0x2d71, 0x2d72, 
+    0x2d72, 0x2d73, 0x2d73, 0x2d74, 0x2d75, 0x2d75, 0x2d76, 0x2d76, 
+    0x2d77, 0x2d77, 0x2d78, 0x2d78, 0x2d79, 0x2d79, 0x2d7a, 0x2d7b, 
+    0x2d7b, 0x2d7c, 0x2d7c, 0x2d7d, 0x2d7d, 0x2d7e, 0x2d7e, 0x2d7f, 
+    0x2d7f, 0x2d80, 0x2d81, 0x2d81, 0x2d82, 0x2d82, 0x2d83, 0x2d83, 
+    0x2d84, 0x2d84, 0x2d85, 0x2d85, 0x2d86, 0x2d86, 0x2d87, 0x2d88, 
+    0x2d88, 0x2d89, 0x2d89, 0x2d8a, 0x2d8a, 0x2d8b, 0x2d8b, 0x2d8c, 
+    0x2d8c, 0x2d8d, 0x2d8d, 0x2d8e, 0x2d8e, 0x2d8f, 0x2d90, 0x2d90, 
+    0x2d91, 0x2d91, 0x2d92, 0x2d92, 0x2d93, 0x2d93, 0x2d94, 0x2d94, 
+    0x2d95, 0x2d95, 0x2d96, 0x2d96, 0x2d97, 0x2d97, 0x2d98, 0x2d99, 
+    0x2d99, 0x2d9a, 0x2d9a, 0x2d9b, 0x2d9b, 0x2d9c, 0x2d9c, 0x2d9d, 
+    0x2d9d, 0x2d9e, 0x2d9e, 0x2d9f, 0x2d9f, 0x2da0, 0x2da0, 0x2da1, 
+    0x2da2, 0x2da2, 0x2da3, 0x2da3, 0x2da4, 0x2da4, 0x2da5, 0x2da5, 
+    0x2da6, 0x2da6, 0x2da7, 0x2da7, 0x2da8, 0x2da8, 0x2da9, 0x2da9, 
+    0x2daa, 0x2daa, 0x2dab, 0x2dab, 0x2dac, 0x2dac, 0x2dad, 0x2dae, 
+    0x2dae, 0x2daf, 0x2daf, 0x2db0, 0x2db0, 0x2db1, 0x2db1, 0x2db2, 
+    0x2db2, 0x2db3, 0x2db3, 0x2db4, 0x2db4, 0x2db5, 0x2db5, 0x2db6, 
+    0x2db6, 0x2db7, 0x2db7, 0x2db8, 0x2db8, 0x2db9, 0x2db9, 0x2dba, 
+    0x2dba, 0x2dbb, 0x2dbb, 0x2dbc, 0x2dbd, 0x2dbd, 0x2dbe, 0x2dbe, 
+    0x2dbf, 0x2dbf, 0x2dc0, 0x2dc0, 0x2dc1, 0x2dc1, 0x2dc2, 0x2dc2, 
+    0x2dc3, 0x2dc3, 0x2dc4, 0x2dc4, 0x2dc5, 0x2dc5, 0x2dc6, 0x2dc6, 
+    0x2dc7, 0x2dc7, 0x2dc8, 0x2dc8, 0x2dc9, 0x2dc9, 0x2dca, 0x2dca, 
+    0x2dcb, 0x2dcb, 0x2dcc, 0x2dcc, 0x2dcd, 0x2dcd, 0x2dce, 0x2dce, 
+    0x2dcf, 0x2dcf, 0x2dd0, 0x2dd0, 0x2dd1, 0x2dd1, 0x2dd2, 0x2dd2, 
+    0x2dd3, 0x2dd3, 0x2dd4, 0x2dd4, 0x2dd5, 0x2dd5, 0x2dd6, 0x2dd6, 
+    0x2dd7, 0x2dd7, 0x2dd8, 0x2dd8, 0x2dd9, 0x2dd9, 0x2dda, 0x2dda, 
+    0x2ddb, 0x2ddb, 0x2ddc, 0x2ddc, 0x2ddd, 0x2ddd, 0x2dde, 0x2dde, 
+    0x2ddf, 0x2ddf, 0x2de0, 0x2de0, 0x2de1, 0x2de1, 0x2de2, 0x2de2, 
+    0x2de3, 0x2de3, 0x2de4, 0x2de4, 0x2de5, 0x2de5, 0x2de6, 0x2de6, 
+    0x2de7, 0x2de7, 0x2de8, 0x2de8, 0x2de9, 0x2de9, 0x2dea, 0x2dea, 
+    0x2deb, 0x2deb, 0x2dec, 0x2dec, 0x2ded, 0x2ded, 0x2dee, 0x2dee, 
+    0x2def, 0x2def, 0x2df0, 0x2df0, 0x2df1, 0x2df1, 0x2df2, 0x2df2, 
+    0x2df3, 0x2df3, 0x2df4, 0x2df4, 0x2df5, 0x2df5, 0x2df6, 0x2df6, 
+    0x2df7, 0x2df7, 0x2df8, 0x2df8, 0x2df9, 0x2df9, 0x2dfa, 0x2dfa, 
+    0x2dfb, 0x2dfb, 0x2dfc, 0x2dfc, 0x2dfd, 0x2dfd, 0x2dfe, 0x2dfe, 
+    0x2dfe, 0x2dff, 0x2dff, 0x2e00, 0x2e00, 0x2e01, 0x2e01, 0x2e02, 
+    0x2e02, 0x2e03, 0x2e03, 0x2e04, 0x2e04, 0x2e05, 0x2e05, 0x2e06, 
+    0x2e06, 0x2e07, 0x2e07, 0x2e08, 0x2e08, 0x2e09, 0x2e09, 0x2e0a, 
+    0x2e0a, 0x2e0b, 0x2e0b, 0x2e0c, 0x2e0c, 0x2e0d, 0x2e0d, 0x2e0e, 
+    0x2e0e, 0x2e0e, 0x2e0f, 0x2e0f, 0x2e10, 0x2e10, 0x2e11, 0x2e11, 
+    0x2e12, 0x2e12, 0x2e13, 0x2e13, 0x2e14, 0x2e14, 0x2e15, 0x2e15, 
+    0x2e16, 0x2e16, 0x2e17, 0x2e17, 0x2e18, 0x2e18, 0x2e19, 0x2e19, 
+    0x2e19, 0x2e1a, 0x2e1a, 0x2e1b, 0x2e1b, 0x2e1c, 0x2e1c, 0x2e1d, 
+    0x2e1d, 0x2e1e, 0x2e1e, 0x2e1f, 0x2e1f, 0x2e20, 0x2e20, 0x2e21, 
+    0x2e21, 0x2e22, 0x2e22, 0x2e23, 0x2e23, 0x2e23, 0x2e24, 0x2e24, 
+    0x2e25, 0x2e25, 0x2e26, 0x2e26, 0x2e27, 0x2e27, 0x2e28, 0x2e28, 
+    0x2e29, 0x2e29, 0x2e2a, 0x2e2a, 0x2e2b, 0x2e2b, 0x2e2b, 0x2e2c, 
+    0x2e2c, 0x2e2d, 0x2e2d, 0x2e2e, 0x2e2e, 0x2e2f, 0x2e2f, 0x2e30, 
+    0x2e30, 0x2e31, 0x2e31, 0x2e32, 0x2e32, 0x2e33, 0x2e33, 0x2e33, 
+    0x2e34, 0x2e34, 0x2e35, 0x2e35, 0x2e36, 0x2e36, 0x2e37, 0x2e37, 
+    0x2e38, 0x2e38, 0x2e39, 0x2e39, 0x2e3a, 0x2e3a, 0x2e3a, 0x2e3b, 
+    0x2e3b, 0x2e3c, 0x2e3c, 0x2e3d, 0x2e3d, 0x2e3e, 0x2e3e, 0x2e3f, 
+    0x2e3f, 0x2e40, 0x2e40, 0x2e40, 0x2e41, 0x2e41, 0x2e42, 0x2e42, 
+    0x2e43, 0x2e43, 0x2e44, 0x2e44, 0x2e45, 0x2e45, 0x2e46, 0x2e46, 
+    0x2e47, 0x2e47, 0x2e47, 0x2e48, 0x2e48, 0x2e49, 0x2e49, 0x2e4a, 
+    0x2e4a, 0x2e4b, 0x2e4b, 0x2e4c, 0x2e4c, 0x2e4c, 0x2e4d, 0x2e4d, 
+    0x2e4e, 0x2e4e, 0x2e4f, 0x2e4f, 0x2e50, 0x2e50, 0x2e51, 0x2e51, 
+    0x2e52, 0x2e52, 0x2e52, 0x2e53, 0x2e53, 0x2e54, 0x2e54, 0x2e55, 
+    0x2e55, 0x2e56, 0x2e56, 0x2e57, 0x2e57, 0x2e57, 0x2e58, 0x2e58, 
+    0x2e59, 0x2e59, 0x2e5a, 0x2e5a, 0x2e5b, 0x2e5b, 0x2e5c, 0x2e5c, 
+    0x2e5c, 0x2e5d, 0x2e5d, 0x2e5e, 0x2e5e, 0x2e5f, 0x2e5f, 0x2e60, 
+    0x2e60, 0x2e61, 0x2e61, 0x2e61, 0x2e62, 0x2e62, 0x2e63, 0x2e63, 
+    0x2e64, 0x2e64, 0x2e65, 0x2e65, 0x2e65, 0x2e66, 0x2e66, 0x2e67, 
+    0x2e67, 0x2e68, 0x2e68, 0x2e69, 0x2e69, 0x2e6a, 0x2e6a, 0x2e6a, 
+    0x2e6b, 0x2e6b, 0x2e6c, 0x2e6c, 0x2e6d, 0x2e6d, 0x2e6e, 0x2e6e, 
+    0x2e6e, 0x2e6f, 0x2e6f, 0x2e70, 0x2e70, 0x2e71, 0x2e71, 0x2e72, 
+    0x2e72, 0x2e72, 0x2e73, 0x2e73, 0x2e74, 0x2e74, 0x2e75, 0x2e75, 
+    0x2e76, 0x2e76, 0x2e77, 0x2e77, 0x2e77, 0x2e78, 0x2e78, 0x2e79, 
+    0x2e79, 0x2e7a, 0x2e7a, 0x2e7b, 0x2e7b, 0x2e7b, 0x2e7c, 0x2e7c, 
+    0x2e7d, 0x2e7d, 0x2e7e, 0x2e7e, 0x2e7e, 0x2e7f, 0x2e7f, 0x2e80, 
+    0x2e80, 0x2e81, 0x2e81, 0x2e82, 0x2e82, 0x2e82, 0x2e83, 0x2e83, 
+    0x2e84, 0x2e84, 0x2e85, 0x2e85, 0x2e86, 0x2e86, 0x2e86, 0x2e87, 
+    0x2e87, 0x2e88, 0x2e88, 0x2e89, 0x2e89, 0x2e8a, 0x2e8a, 0x2e8a, 
+    0x2e8b, 0x2e8b, 0x2e8c, 0x2e8c, 0x2e8d, 0x2e8d, 0x2e8d, 0x2e8e, 
+    0x2e8e, 0x2e8f, 0x2e8f, 0x2e90, 0x2e90, 0x2e91, 0x2e91, 0x2e91, 
+    0x2e92, 0x2e92, 0x2e93, 0x2e93, 0x2e94, 0x2e94, 0x2e94, 0x2e95, 
+    0x2e95, 0x2e96, 0x2e96, 0x2e97, 0x2e97, 0x2e97, 0x2e98, 0x2e98, 
+    0x2e99, 0x2e99, 0x2e9a, 0x2e9a, 0x2e9b, 0x2e9b, 0x2e9b, 0x2e9c, 
+    0x2e9c, 0x2e9d, 0x2e9d, 0x2e9e, 0x2e9e, 0x2e9e, 0x2e9f, 0x2e9f, 
+    0x2ea0, 0x2ea0, 0x2ea1, 0x2ea1, 0x2ea1, 0x2ea2, 0x2ea2, 0x2ea3, 
+    0x2ea3, 0x2ea4, 0x2ea4, 0x2ea4, 0x2ea5, 0x2ea5, 0x2ea6, 0x2ea6, 
+    0x2ea7, 0x2ea7, 0x2ea7, 0x2ea8, 0x2ea8, 0x2ea9, 0x2ea9, 0x2eaa, 
+    0x2eaa, 0x2eaa, 0x2eab, 0x2eab, 0x2eac, 0x2eac, 0x2ead, 0x2ead, 
+    0x2ead, 0x2eae, 0x2eae, 0x2eaf, 0x2eaf, 0x2eb0, 0x2eb0, 0x2eb0, 
+    0x2eb1, 0x2eb1, 0x2eb2, 0x2eb2, 0x2eb3, 0x2eb3, 0x2eb3, 0x2eb4, 
+    0x2eb4, 0x2eb5, 0x2eb5, 0x2eb6, 0x2eb6, 0x2eb6, 0x2eb7, 0x2eb7, 
+    0x2eb8, 0x2eb8, 0x2eb9, 0x2eb9, 0x2eb9, 0x2eba, 0x2eba, 0x2ebb, 
+    0x2ebb, 0x2ebc, 0x2ebc, 0x2ebc, 0x2ebd, 0x2ebd, 0x2ebe, 0x2ebe, 
+    0x2ebe, 0x2ebf, 0x2ebf, 0x2ec0, 0x2ec0, 0x2ec1, 0x2ec1, 0x2ec1, 
+    0x2ec2, 0x2ec2, 0x2ec3, 0x2ec3, 0x2ec4, 0x2ec4, 0x2ec4, 0x2ec5, 
+    0x2ec5, 0x2ec6, 0x2ec6, 0x2ec7, 0x2ec7, 0x2ec7, 0x2ec8, 0x2ec8, 
+    0x2ec9, 0x2ec9, 0x2ec9, 0x2eca, 0x2eca, 0x2ecb, 0x2ecb, 0x2ecc, 
+    0x2ecc, 0x2ecc, 0x2ecd, 0x2ecd, 0x2ece, 0x2ece, 0x2ece, 0x2ecf, 
+    0x2ecf, 0x2ed0, 0x2ed0, 0x2ed1, 0x2ed1, 0x2ed1, 0x2ed2, 0x2ed2, 
+    0x2ed3, 0x2ed3, 0x2ed3, 0x2ed4, 0x2ed4, 0x2ed5, 0x2ed5, 0x2ed6, 
+    0x2ed6, 0x2ed6, 0x2ed7, 0x2ed7, 0x2ed8, 0x2ed8, 0x2ed8, 0x2ed9, 
+    0x2ed9, 0x2eda, 0x2eda, 0x2edb, 0x2edb, 0x2edb, 0x2edc, 0x2edc, 
+    0x2edd, 0x2edd, 0x2edd, 0x2ede, 0x2ede, 0x2edf, 0x2edf, 0x2ee0, 
+    0x2ee0, 0x2ee0, 0x2ee1, 0x2ee1, 0x2ee2, 0x2ee2, 0x2ee2, 0x2ee3, 
+    0x2ee3, 0x2ee4, 0x2ee4, 0x2ee4, 0x2ee5, 0x2ee5, 0x2ee6, 0x2ee6, 
+    0x2ee7, 0x2ee7, 0x2ee7, 0x2ee8, 0x2ee8, 0x2ee9, 0x2ee9, 0x2ee9, 
+    0x2eea, 0x2eea, 0x2eeb, 0x2eeb, 0x2eeb, 0x2eec, 0x2eec, 0x2eed, 
+    0x2eed, 0x2eee, 0x2eee, 0x2eee, 0x2eef, 0x2eef, 0x2ef0, 0x2ef0, 
+    0x2ef0, 0x2ef1, 0x2ef1, 0x2ef2, 0x2ef2, 0x2ef2, 0x2ef3, 0x2ef3, 
+    0x2ef4, 0x2ef4, 0x2ef4, 0x2ef5, 0x2ef5, 0x2ef6, 0x2ef6, 0x2ef6, 
+    0x2ef7, 0x2ef7, 0x2ef8, 0x2ef8, 0x2ef9, 0x2ef9, 0x2ef9, 0x2efa, 
+    0x2efa, 0x2efb, 0x2efb, 0x2efb, 0x2efc, 0x2efc, 0x2efd, 0x2efd, 
+    0x2efd, 0x2efe, 0x2efe, 0x2eff, 0x2eff, 0x2eff, 0x2f00, 0x2f00, 
+    0x2f01, 0x2f01, 0x2f01, 0x2f02, 0x2f02, 0x2f03, 0x2f03, 0x2f03, 
+    0x2f04, 0x2f04, 0x2f05, 0x2f05, 0x2f05, 0x2f06, 0x2f06, 0x2f07, 
+    0x2f07, 0x2f07, 0x2f08, 0x2f08, 0x2f09, 0x2f09, 0x2f09, 0x2f0a, 
+    0x2f0a, 0x2f0b, 0x2f0b, 0x2f0b, 0x2f0c, 0x2f0c, 0x2f0d, 0x2f0d, 
+    0x2f0d, 0x2f0e, 0x2f0f, 0x2f10, 0x2f11, 0x2f12, 0x2f12, 0x2f13, 
+    0x2f14, 0x2f15, 0x2f15, 0x2f16, 0x2f17, 0x2f18, 0x2f19, 0x2f19, 
+    0x2f1a, 0x2f1b, 0x2f1c, 0x2f1d, 0x2f1d, 0x2f1e, 0x2f1f, 0x2f20, 
+    0x2f21, 0x2f21, 0x2f22, 0x2f23, 0x2f24, 0x2f25, 0x2f25, 0x2f26, 
+    0x2f27, 0x2f28, 0x2f29, 0x2f29, 0x2f2a, 0x2f2b, 0x2f2c, 0x2f2c, 
+    0x2f2d, 0x2f2e, 0x2f2f, 0x2f30, 0x2f30, 0x2f31, 0x2f32, 0x2f33, 
+    0x2f33, 0x2f34, 0x2f35, 0x2f36, 0x2f37, 0x2f37, 0x2f38, 0x2f39, 
+    0x2f3a, 0x2f3b, 0x2f3b, 0x2f3c, 0x2f3d, 0x2f3e, 0x2f3e, 0x2f3f, 
+    0x2f40, 0x2f41, 0x2f41, 0x2f42, 0x2f43, 0x2f44, 0x2f45, 0x2f45, 
+    0x2f46, 0x2f47, 0x2f48, 0x2f48, 0x2f49, 0x2f4a, 0x2f4b, 0x2f4c, 
+    0x2f4c, 0x2f4d, 0x2f4e, 0x2f4f, 0x2f4f, 0x2f50, 0x2f51, 0x2f52, 
+    0x2f52, 0x2f53, 0x2f54, 0x2f55, 0x2f56, 0x2f56, 0x2f57, 0x2f58, 
+    0x2f59, 0x2f59, 0x2f5a, 0x2f5b, 0x2f5c, 0x2f5c, 0x2f5d, 0x2f5e, 
+    0x2f5f, 0x2f5f, 0x2f60, 0x2f61, 0x2f62, 0x2f62, 0x2f63, 0x2f64, 
+    0x2f65, 0x2f65, 0x2f66, 0x2f67, 0x2f68, 0x2f69, 0x2f69, 0x2f6a, 
+    0x2f6b, 0x2f6c, 0x2f6c, 0x2f6d, 0x2f6e, 0x2f6f, 0x2f6f, 0x2f70, 
+    0x2f71, 0x2f72, 0x2f72, 0x2f73, 0x2f74, 0x2f75, 0x2f75, 0x2f76, 
+    0x2f77, 0x2f78, 0x2f78, 0x2f79, 0x2f7a, 0x2f7b, 0x2f7b, 0x2f7c, 
+    0x2f7d, 0x2f7e, 0x2f7e, 0x2f7f, 0x2f80, 0x2f81, 0x2f81, 0x2f82, 
+    0x2f83, 0x2f83, 0x2f84, 0x2f85, 0x2f86, 0x2f86, 0x2f87, 0x2f88, 
+    0x2f89, 0x2f89, 0x2f8a, 0x2f8b, 0x2f8c, 0x2f8c, 0x2f8d, 0x2f8e, 
+    0x2f8f, 0x2f8f, 0x2f90, 0x2f91, 0x2f92, 0x2f92, 0x2f93, 0x2f94, 
+    0x2f94, 0x2f95, 0x2f96, 0x2f97, 0x2f97, 0x2f98, 0x2f99, 0x2f9a, 
+    0x2f9a, 0x2f9b, 0x2f9c, 0x2f9d, 0x2f9d, 0x2f9e, 0x2f9f, 0x2f9f, 
+    0x2fa0, 0x2fa1, 0x2fa2, 0x2fa2, 0x2fa3, 0x2fa4, 0x2fa5, 0x2fa5, 
+    0x2fa6, 0x2fa7, 0x2fa7, 0x2fa8, 0x2fa9, 0x2faa, 0x2faa, 0x2fab, 
+    0x2fac, 0x2fad, 0x2fad, 0x2fae, 0x2faf, 0x2faf, 0x2fb0, 0x2fb1, 
+    0x2fb2, 0x2fb2, 0x2fb3, 0x2fb4, 0x2fb4, 0x2fb5, 0x2fb6, 0x2fb7, 
+    0x2fb7, 0x2fb8, 0x2fb9, 0x2fba, 0x2fba, 0x2fbb, 0x2fbc, 0x2fbc, 
+    0x2fbd, 0x2fbe, 0x2fbf, 0x2fbf, 0x2fc0, 0x2fc1, 0x2fc1, 0x2fc2, 
+    0x2fc3, 0x2fc4, 0x2fc4, 0x2fc5, 0x2fc6, 0x2fc6, 0x2fc7, 0x2fc8, 
+    0x2fc9, 0x2fc9, 0x2fca, 0x2fcb, 0x2fcb, 0x2fcc, 0x2fcd, 0x2fce, 
+    0x2fce, 0x2fcf, 0x2fd0, 0x2fd0, 0x2fd1, 0x2fd2, 0x2fd2, 0x2fd3, 
+    0x2fd4, 0x2fd5, 0x2fd5, 0x2fd6, 0x2fd7, 0x2fd7, 0x2fd8, 0x2fd9, 
+    0x2fda, 0x2fda, 0x2fdb, 0x2fdc, 0x2fdc, 0x2fdd, 0x2fde, 0x2fde, 
+    0x2fdf, 0x2fe0, 0x2fe1, 0x2fe1, 0x2fe2, 0x2fe3, 0x2fe3, 0x2fe4, 
+    0x2fe5, 0x2fe5, 0x2fe6, 0x2fe7, 0x2fe8, 0x2fe8, 0x2fe9, 0x2fea, 
+    0x2fea, 0x2feb, 0x2fec, 0x2fec, 0x2fed, 0x2fee, 0x2fef, 0x2fef, 
+    0x2ff0, 0x2ff1, 0x2ff1, 0x2ff2, 0x2ff3, 0x2ff3, 0x2ff4, 0x2ff5, 
+    0x2ff6, 0x2ff6, 0x2ff7, 0x2ff8, 0x2ff8, 0x2ff9, 0x2ffa, 0x2ffa, 
+    0x2ffb, 0x2ffc, 0x2ffc, 0x2ffd, 0x2ffe, 0x2fff, 0x2fff, 0x3000, 
+    0x3000, 0x3001, 0x3001, 0x3001, 0x3002, 0x3002, 0x3002, 0x3003, 
+    0x3003, 0x3003, 0x3004, 0x3004, 0x3004, 0x3005, 0x3005, 0x3005, 
+    0x3006, 0x3006, 0x3006, 0x3007, 0x3007, 0x3007, 0x3008, 0x3008, 
+    0x3009, 0x3009, 0x3009, 0x300a, 0x300a, 0x300a, 0x300b, 0x300b, 
+    0x300b, 0x300c, 0x300c, 0x300c, 0x300d, 0x300d, 0x300d, 0x300e, 
+    0x300e, 0x300e, 0x300f, 0x300f, 0x300f, 0x3010, 0x3010, 0x3010, 
+    0x3011, 0x3011, 0x3011, 0x3012, 0x3012, 0x3012, 0x3013, 0x3013, 
+    0x3013, 0x3014, 0x3014, 0x3014, 0x3015, 0x3015, 0x3015, 0x3016, 
+    0x3016, 0x3016, 0x3017, 0x3017, 0x3017, 0x3018, 0x3018, 0x3018, 
+    0x3019, 0x3019, 0x3019, 0x301a, 0x301a, 0x301a, 0x301b, 0x301b, 
+    0x301b, 0x301c, 0x301c, 0x301c, 0x301d, 0x301d, 0x301d, 0x301e, 
+    0x301e, 0x301e, 0x301f, 0x301f, 0x301f, 0x3020, 0x3020, 0x3020, 
+    0x3021, 0x3021, 0x3021, 0x3022, 0x3022, 0x3022, 0x3023, 0x3023, 
+    0x3023, 0x3024, 0x3024, 0x3024, 0x3025, 0x3025, 0x3025, 0x3026, 
+    0x3026, 0x3026, 0x3027, 0x3027, 0x3027, 0x3028, 0x3028, 0x3028, 
+    0x3029, 0x3029, 0x3029, 0x302a, 0x302a, 0x302a, 0x302b, 0x302b, 
+    0x302b, 0x302c, 0x302c, 0x302c, 0x302d, 0x302d, 0x302d, 0x302e, 
+    0x302e, 0x302e, 0x302f, 0x302f, 0x302f, 0x3030, 0x3030, 0x3030, 
+    0x3031, 0x3031, 0x3031, 0x3031, 0x3032, 0x3032, 0x3032, 0x3033, 
+    0x3033, 0x3033, 0x3034, 0x3034, 0x3034, 0x3035, 0x3035, 0x3035, 
+    0x3036, 0x3036, 0x3036, 0x3037, 0x3037, 0x3037, 0x3038, 0x3038, 
+    0x3038, 0x3039, 0x3039, 0x3039, 0x303a, 0x303a, 0x303a, 0x303b, 
+    0x303b, 0x303b, 0x303c, 0x303c, 0x303c, 0x303c, 0x303d, 0x303d, 
+    0x303d, 0x303e, 0x303e, 0x303e, 0x303f, 0x303f, 0x303f, 0x3040, 
+    0x3040, 0x3040, 0x3041, 0x3041, 0x3041, 0x3042, 0x3042, 0x3042, 
+    0x3043, 0x3043, 0x3043, 0x3044, 0x3044, 0x3044, 0x3044, 0x3045, 
+    0x3045, 0x3045, 0x3046, 0x3046, 0x3046, 0x3047, 0x3047, 0x3047, 
+    0x3048, 0x3048, 0x3048, 0x3049, 0x3049, 0x3049, 0x304a, 0x304a, 
+    0x304a, 0x304b, 0x304b, 0x304b, 0x304b, 0x304c, 0x304c, 0x304c, 
+    0x304d, 0x304d, 0x304d, 0x304e, 0x304e, 0x304e, 0x304f, 0x304f, 
+    0x304f, 0x3050, 0x3050, 0x3050, 0x3051, 0x3051, 0x3051, 0x3051, 
+    0x3052, 0x3052, 0x3052, 0x3053, 0x3053, 0x3053, 0x3054, 0x3054, 
+    0x3054, 0x3055, 0x3055, 0x3055, 0x3056, 0x3056, 0x3056, 0x3056, 
+    0x3057, 0x3057, 0x3057, 0x3058, 0x3058, 0x3058, 0x3059, 0x3059, 
+    0x3059, 0x305a, 0x305a, 0x305a, 0x305b, 0x305b, 0x305b, 0x305b, 
+    0x305c, 0x305c, 0x305c, 0x305d, 0x305d, 0x305d, 0x305e, 0x305e, 
+    0x305e, 0x305f, 0x305f, 0x305f, 0x305f, 0x3060, 0x3060, 0x3060, 
+    0x3061, 0x3061, 0x3061, 0x3062, 0x3062, 0x3062, 0x3063, 0x3063, 
+    0x3063, 0x3064, 0x3064, 0x3064, 0x3064, 0x3065, 0x3065, 0x3065, 
+    0x3066, 0x3066, 0x3066, 0x3067, 0x3067, 0x3067, 0x3068, 0x3068, 
+    0x3068, 0x3068, 0x3069, 0x3069, 0x3069, 0x306a, 0x306a, 0x306a, 
+    0x306b, 0x306b, 0x306b, 0x306b, 0x306c, 0x306c, 0x306c, 0x306d, 
+    0x306d, 0x306d, 0x306e, 0x306e, 0x306e, 0x306f, 0x306f, 0x306f, 
+    0x306f, 0x3070, 0x3070, 0x3070, 0x3071, 0x3071, 0x3071, 0x3072, 
+    0x3072, 0x3072, 0x3072, 0x3073, 0x3073, 0x3073, 0x3074, 0x3074, 
+    0x3074, 0x3075, 0x3075, 0x3075, 0x3076, 0x3076, 0x3076, 0x3076, 
+    0x3077, 0x3077, 0x3077, 0x3078, 0x3078, 0x3078, 0x3079, 0x3079, 
+    0x3079, 0x3079, 0x307a, 0x307a, 0x307a, 0x307b, 0x307b, 0x307b, 
+    0x307c, 0x307c, 0x307c, 0x307c, 0x307d, 0x307d, 0x307d, 0x307e, 
+    0x307e, 0x307e, 0x307f, 0x307f, 0x307f, 0x307f, 0x3080, 0x3080, 
+    0x3080, 0x3081, 0x3081, 0x3081, 0x3082, 0x3082, 0x3082, 0x3082, 
+    0x3083, 0x3083, 0x3083, 0x3084, 0x3084, 0x3084, 0x3085, 0x3085, 
+    0x3085, 0x3085, 0x3086, 0x3086, 0x3086, 0x3087, 0x3087, 0x3087, 
+    0x3087, 0x3088, 0x3088, 0x3088, 0x3089, 0x3089, 0x3089, 0x308a, 
+    0x308a, 0x308a, 0x308a, 0x308b, 0x308b, 0x308b, 0x308c, 0x308c, 
+    0x308c, 0x308d, 0x308d, 0x308d, 0x308d, 0x308e, 0x308e, 0x308e, 
+    0x308f, 0x308f, 0x308f, 0x308f, 0x3090, 0x3090, 0x3090, 0x3091, 
+    0x3091, 0x3091, 0x3092, 0x3092, 0x3092, 0x3092, 0x3093, 0x3093, 
+    0x3093, 0x3094, 0x3094, 0x3094, 0x3094, 0x3095, 0x3095, 0x3095, 
+    0x3096, 0x3096, 0x3096, 0x3097, 0x3097, 0x3097, 0x3097, 0x3098, 
+    0x3098, 0x3098, 0x3099, 0x3099, 0x3099, 0x3099, 0x309a, 0x309a, 
+    0x309a, 0x309b, 0x309b, 0x309b, 0x309b, 0x309c, 0x309c, 0x309c, 
+    0x309d, 0x309d, 0x309d, 0x309e, 0x309e, 0x309e, 0x309e, 0x309f, 
+    0x309f, 0x309f, 0x30a0, 0x30a0, 0x30a0, 0x30a0, 0x30a1, 0x30a1, 
+    0x30a1, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a3, 0x30a3, 0x30a3, 
+    0x30a4, 0x30a4, 0x30a4, 0x30a4, 0x30a5, 0x30a5, 0x30a5, 0x30a6, 
+    0x30a6, 0x30a6, 0x30a6, 0x30a7, 0x30a7, 0x30a7, 0x30a8, 0x30a8, 
+    0x30a8, 0x30a8, 0x30a9, 0x30a9, 0x30a9, 0x30aa, 0x30aa, 0x30aa, 
+    0x30aa, 0x30ab, 0x30ab, 0x30ab, 0x30ac, 0x30ac, 0x30ac, 0x30ac, 
+    0x30ad, 0x30ad, 0x30ad, 0x30ae, 0x30ae, 0x30ae, 0x30ae, 0x30af, 
+    0x30af, 0x30af, 0x30b0, 0x30b0, 0x30b0, 0x30b0, 0x30b1, 0x30b1, 
+    0x30b1, 0x30b2, 0x30b2, 0x30b2, 0x30b2, 0x30b3, 0x30b3, 0x30b3, 
+    0x30b4, 0x30b4, 0x30b4, 0x30b4, 0x30b5, 0x30b5, 0x30b5, 0x30b6, 
+    0x30b6, 0x30b6, 0x30b6, 0x30b7, 0x30b7, 0x30b7, 0x30b8, 0x30b8, 
+    0x30b8, 0x30b8, 0x30b9, 0x30b9, 0x30b9, 0x30ba, 0x30ba, 0x30ba, 
+    0x30ba, 0x30bb, 0x30bb, 0x30bb, 0x30bc, 0x30bc, 0x30bc, 0x30bc, 
+    0x30bd, 0x30bd, 0x30bd, 0x30bd, 0x30be, 0x30be, 0x30be, 0x30bf, 
+    0x30bf, 0x30bf, 0x30bf, 0x30c0, 0x30c0, 0x30c0, 0x30c1, 0x30c1, 
+    0x30c1, 0x30c1, 0x30c2, 0x30c2, 0x30c2, 0x30c3, 0x30c3, 0x30c3, 
+    0x30c3, 0x30c4, 0x30c4, 0x30c4, 0x30c4, 0x30c5, 0x30c5, 0x30c5, 
+    0x30c6, 0x30c6, 0x30c6, 0x30c6, 0x30c7, 0x30c7, 0x30c7, 0x30c8, 
+    0x30c8, 0x30c8, 0x30c8, 0x30c9, 0x30c9, 0x30c9, 0x30c9, 0x30ca, 
+    0x30ca, 0x30ca, 0x30cb, 0x30cb, 0x30cb, 0x30cb, 0x30cc, 0x30cc, 
+    0x30cc, 0x30cd, 0x30cd, 0x30cd, 0x30cd, 0x30ce, 0x30ce, 0x30ce, 
+    0x30ce, 0x30cf, 0x30cf, 0x30cf, 0x30d0, 0x30d0, 0x30d0, 0x30d0, 
+    0x30d1, 0x30d1, 0x30d1, 0x30d2, 0x30d2, 0x30d2, 0x30d2, 0x30d3, 
+    0x30d3, 0x30d3, 0x30d3, 0x30d4, 0x30d4, 0x30d4, 0x30d5, 0x30d5, 
+    0x30d5, 0x30d6, 0x30d6, 0x30d7, 0x30d7, 0x30d8, 0x30d8, 0x30d9, 
+    0x30d9, 0x30da, 0x30db, 0x30db, 0x30dc, 0x30dc, 0x30dd, 0x30dd, 
+    0x30de, 0x30de, 0x30df, 0x30df, 0x30e0, 0x30e1, 0x30e1, 0x30e2, 
+    0x30e2, 0x30e3, 0x30e3, 0x30e4, 0x30e4, 0x30e5, 0x30e5, 0x30e6, 
+    0x30e7, 0x30e7, 0x30e8, 0x30e8, 0x30e9, 0x30e9, 0x30ea, 0x30ea, 
+    0x30eb, 0x30eb, 0x30ec, 0x30ec, 0x30ed, 0x30ee, 0x30ee, 0x30ef, 
+    0x30ef, 0x30f0, 0x30f0, 0x30f1, 0x30f1, 0x30f2, 0x30f2, 0x30f3, 
+    0x30f3, 0x30f4, 0x30f4, 0x30f5, 0x30f6, 0x30f6, 0x30f7, 0x30f7, 
+    0x30f8, 0x30f8, 0x30f9, 0x30f9, 0x30fa, 0x30fa, 0x30fb, 0x30fb, 
+    0x30fc, 0x30fc, 0x30fd, 0x30fd, 0x30fe, 0x30ff, 0x30ff, 0x3100, 
+    0x3100, 0x3101, 0x3101, 0x3102, 0x3102, 0x3103, 0x3103, 0x3104, 
+    0x3104, 0x3105, 0x3105, 0x3106, 0x3106, 0x3107, 0x3107, 0x3108, 
+    0x3109, 0x3109, 0x310a, 0x310a, 0x310b, 0x310b, 0x310c, 0x310c, 
+    0x310d, 0x310d, 0x310e, 0x310e, 0x310f, 0x310f, 0x3110, 0x3110, 
+    0x3111, 0x3111, 0x3112, 0x3112, 0x3113, 0x3113, 0x3114, 0x3114, 
+    0x3115, 0x3116, 0x3116, 0x3117, 0x3117, 0x3118, 0x3118, 0x3119, 
+    0x3119, 0x311a, 0x311a, 0x311b, 0x311b, 0x311c, 0x311c, 0x311d, 
+    0x311d, 0x311e, 0x311e, 0x311f, 0x311f, 0x3120, 0x3120, 0x3121, 
+    0x3121, 0x3122, 0x3122, 0x3123, 0x3123, 0x3124, 0x3124, 0x3125, 
+    0x3125, 0x3126, 0x3126, 0x3127, 0x3127, 0x3128, 0x3128, 0x3129, 
+    0x3129, 0x312a, 0x312a, 0x312b, 0x312c, 0x312c, 0x312d, 0x312d, 
+    0x312e, 0x312e, 0x312f, 0x312f, 0x3130, 0x3130, 0x3131, 0x3131, 
+    0x3132, 0x3132, 0x3133, 0x3133, 0x3134, 0x3134, 0x3135, 0x3135, 
+    0x3136, 0x3136, 0x3137, 0x3137, 0x3138, 0x3138, 0x3139, 0x3139, 
+    0x313a, 0x313a, 0x313b, 0x313b, 0x313c, 0x313c, 0x313d, 0x313d, 
+    0x313e, 0x313e, 0x313f, 0x313f, 0x3140, 0x3140, 0x3141, 0x3141, 
+    0x3142, 0x3142, 0x3143, 0x3143, 0x3144, 0x3144, 0x3145, 0x3145, 
+    0x3146, 0x3146, 0x3147, 0x3147, 0x3148, 0x3148, 0x3148, 0x3149, 
+    0x3149, 0x314a, 0x314a, 0x314b, 0x314b, 0x314c, 0x314c, 0x314d, 
+    0x314d, 0x314e, 0x314e, 0x314f, 0x314f, 0x3150, 0x3150, 0x3151, 
+    0x3151, 0x3152, 0x3152, 0x3153, 0x3153, 0x3154, 0x3154, 0x3155, 
+    0x3155, 0x3156, 0x3156, 0x3157, 0x3157, 0x3158, 0x3158, 0x3159, 
+    0x3159, 0x315a, 0x315a, 0x315b, 0x315b, 0x315c, 0x315c, 0x315d, 
+    0x315d, 0x315e, 0x315e, 0x315e, 0x315f, 0x315f, 0x3160, 0x3160, 
+    0x3161, 0x3161, 0x3162, 0x3162, 0x3163, 0x3163, 0x3164, 0x3164, 
+    0x3165, 0x3165, 0x3166, 0x3166, 0x3167, 0x3167, 0x3168, 0x3168, 
+    0x3169, 0x3169, 0x316a, 0x316a, 0x316b, 0x316b, 0x316b, 0x316c, 
+    0x316c, 0x316d, 0x316d, 0x316e, 0x316e, 0x316f, 0x316f, 0x3170, 
+    0x3170, 0x3171, 0x3171, 0x3172, 0x3172, 0x3173, 0x3173, 0x3174, 
+    0x3174, 0x3175, 0x3175, 0x3175, 0x3176, 0x3176, 0x3177, 0x3177, 
+    0x3178, 0x3178, 0x3179, 0x3179, 0x317a, 0x317a, 0x317b, 0x317b, 
+    0x317c, 0x317c, 0x317d, 0x317d, 0x317e, 0x317e, 0x317e, 0x317f, 
+    0x317f, 0x3180, 0x3180, 0x3181, 0x3181, 0x3182, 0x3182, 0x3183, 
+    0x3183, 0x3184, 0x3184, 0x3185, 0x3185, 0x3185, 0x3186, 0x3186, 
+    0x3187, 0x3187, 0x3188, 0x3188, 0x3189, 0x3189, 0x318a, 0x318a, 
+    0x318b, 0x318b, 0x318c, 0x318c, 0x318c, 0x318d, 0x318d, 0x318e, 
+    0x318e, 0x318f, 0x318f, 0x3190, 0x3190, 0x3191, 0x3191, 0x3192, 
+    0x3192, 0x3193, 0x3193, 0x3193, 0x3194, 0x3194, 0x3195, 0x3195, 
+    0x3196, 0x3196, 0x3197, 0x3197, 0x3198, 0x3198, 0x3199, 0x3199, 
+    0x3199, 0x319a, 0x319a, 0x319b, 0x319b, 0x319c, 0x319c, 0x319d, 
+    0x319d, 0x319e, 0x319e, 0x319f, 0x319f, 0x319f, 0x31a0, 0x31a0, 
+    0x31a1, 0x31a1, 0x31a2, 0x31a2, 0x31a3, 0x31a3, 0x31a4, 0x31a4, 
+    0x31a4, 0x31a5, 0x31a5, 0x31a6, 0x31a6, 0x31a7, 0x31a7, 0x31a8, 
+    0x31a8, 0x31a9, 0x31a9, 0x31a9, 0x31aa, 0x31aa, 0x31ab, 0x31ab, 
+    0x31ac, 0x31ac, 0x31ad, 0x31ad, 0x31ae, 0x31ae, 0x31ae, 0x31af, 
+    0x31af, 0x31b0, 0x31b0, 0x31b1, 0x31b1, 0x31b2, 0x31b2, 0x31b2, 
+    0x31b3, 0x31b3, 0x31b4, 0x31b4, 0x31b5, 0x31b5, 0x31b6, 0x31b6, 
+    0x31b7, 0x31b7, 0x31b7, 0x31b8, 0x31b8, 0x31b9, 0x31b9, 0x31ba, 
+    0x31ba, 0x31bb, 0x31bb, 0x31bb, 0x31bc, 0x31bc, 0x31bd, 0x31bd, 
+    0x31be, 0x31be, 0x31bf, 0x31bf, 0x31bf, 0x31c0, 0x31c0, 0x31c1, 
+    0x31c1, 0x31c2, 0x31c2, 0x31c3, 0x31c3, 0x31c4, 0x31c4, 0x31c4, 
+    0x31c5, 0x31c5, 0x31c6, 0x31c6, 0x31c7, 0x31c7, 0x31c7, 0x31c8, 
+    0x31c8, 0x31c9, 0x31c9, 0x31ca, 0x31ca, 0x31cb, 0x31cb, 0x31cb, 
+    0x31cc, 0x31cc, 0x31cd, 0x31cd, 0x31ce, 0x31ce, 0x31cf, 0x31cf, 
+    0x31cf, 0x31d0, 0x31d0, 0x31d1, 0x31d1, 0x31d2, 0x31d2, 0x31d3, 
+    0x31d3, 0x31d3, 0x31d4, 0x31d4, 0x31d5, 0x31d5, 0x31d6, 0x31d6, 
+    0x31d6, 0x31d7, 0x31d7, 0x31d8, 0x31d8, 0x31d9, 0x31d9, 0x31da, 
+    0x31da, 0x31da, 0x31db, 0x31db, 0x31dc, 0x31dc, 0x31dd, 0x31dd, 
+    0x31dd, 0x31de, 0x31de, 0x31df, 0x31df, 0x31e0, 0x31e0, 0x31e0, 
+    0x31e1, 0x31e1, 0x31e2, 0x31e2, 0x31e3, 0x31e3, 0x31e4, 0x31e4, 
+    0x31e4, 0x31e5, 0x31e5, 0x31e6, 0x31e6, 0x31e7, 0x31e7, 0x31e7, 
+    0x31e8, 0x31e8, 0x31e9, 0x31e9, 0x31ea, 0x31ea, 0x31ea, 0x31eb, 
+    0x31eb, 0x31ec, 0x31ec, 0x31ed, 0x31ed, 0x31ed, 0x31ee, 0x31ee, 
+    0x31ef, 0x31ef, 0x31f0, 0x31f0, 0x31f0, 0x31f1, 0x31f1, 0x31f2, 
+    0x31f2, 0x31f3, 0x31f3, 0x31f3, 0x31f4, 0x31f4, 0x31f5, 0x31f5, 
+    0x31f6, 0x31f6, 0x31f6, 0x31f7, 0x31f7, 0x31f8, 0x31f8, 0x31f9, 
+    0x31f9, 0x31f9, 0x31fa, 0x31fa, 0x31fb, 0x31fb, 0x31fc, 0x31fc, 
+    0x31fc, 0x31fd, 0x31fd, 0x31fe, 0x31fe, 0x31ff, 0x31ff, 0x31ff, 
+    0x3200, 0x3200, 0x3201, 0x3201, 0x3201, 0x3202, 0x3202, 0x3203, 
+    0x3203, 0x3204, 0x3204, 0x3204, 0x3205, 0x3205, 0x3206, 0x3206, 
+    0x3207, 0x3207, 0x3207, 0x3208, 0x3208, 0x3209, 0x3209, 0x320a, 
+    0x320a, 0x320a, 0x320b, 0x320b, 0x320c, 0x320c, 0x320c, 0x320d, 
+    0x320d, 0x320e, 0x320e, 0x320f, 0x320f, 0x320f, 0x3210, 0x3210, 
+    0x3211, 0x3211, 0x3211, 0x3212, 0x3212, 0x3213, 0x3213, 0x3214, 
+    0x3214, 0x3214, 0x3215, 0x3215, 0x3216, 0x3216, 0x3216, 0x3217, 
+    0x3217, 0x3218, 0x3218, 0x3219, 0x3219, 0x3219, 0x321a, 0x321a, 
+    0x321b, 0x321b, 0x321b, 0x321c, 0x321c, 0x321d, 0x321d, 0x321e, 
+    0x321e, 0x321e, 0x321f, 0x321f, 0x3220, 0x3220, 0x3220, 0x3221, 
+    0x3221, 0x3222, 0x3222, 0x3222, 0x3223, 0x3223, 0x3224, 0x3224, 
+    0x3225, 0x3225, 0x3225, 0x3226, 0x3226, 0x3227, 0x3227, 0x3227, 
+    0x3228, 0x3228, 0x3229, 0x3229, 0x3229, 0x322a, 0x322a, 0x322b, 
+    0x322b, 0x322c, 0x322c, 0x322c, 0x322d, 0x322d, 0x322e, 0x322e, 
+    0x322e, 0x322f, 0x322f, 0x3230, 0x3230, 0x3230, 0x3231, 0x3231, 
+    0x3232, 0x3232, 0x3232, 0x3233, 0x3233, 0x3234, 0x3234, 0x3235, 
+    0x3235, 0x3235, 0x3236, 0x3236, 0x3237, 0x3237, 0x3237, 0x3238, 
+    0x3238, 0x3239, 0x3239, 0x3239, 0x323a, 0x323a, 0x323b, 0x323b, 
+    0x323b, 0x323c, 0x323c, 0x323d, 0x323d, 0x323d, 0x323e, 0x323e, 
+    0x323f, 0x323f, 0x323f, 0x3240, 0x3240, 0x3241, 0x3241, 0x3241, 
+    0x3242, 0x3242, 0x3243, 0x3243, 0x3243, 0x3244, 0x3244, 0x3245, 
+    0x3245, 0x3245, 0x3246, 0x3246, 0x3247, 0x3247, 0x3247, 0x3248, 
+    0x3248, 0x3249, 0x3249, 0x3249, 0x324a, 0x324a, 0x324b, 0x324b, 
+    0x324b, 0x324c, 0x324c, 0x324d, 0x324d, 0x324d, 0x324e, 0x324e, 
+    0x324f, 0x324f, 0x324f, 0x3250, 0x3250, 0x3251, 0x3251, 0x3251, 
+    0x3252, 0x3252, 0x3253, 0x3253, 0x3253, 0x3254, 0x3254, 0x3255, 
+    0x3255, 0x3255, 0x3256, 0x3256, 0x3257, 0x3257, 0x3257, 0x3258, 
+    0x3258, 0x3259, 0x3259, 0x3259, 0x325a, 0x325a, 0x325b, 0x325b, 
+    0x325b, 0x325c, 0x325c, 0x325d, 0x325d, 0x325d, 0x325e, 0x325e, 
+    0x325f, 0x325f, 0x325f, 0x3260, 0x3260, 0x3261, 0x3261, 0x3261, 
+    0x3262, 0x3262, 0x3262, 0x3263, 0x3263, 0x3264, 0x3264, 0x3264, 
+    0x3265, 0x3265, 0x3266, 0x3266, 0x3266, 0x3267, 0x3267, 0x3268, 
+    0x3268, 0x3268, 0x3269, 0x3269, 0x326a, 0x326a, 0x326a, 0x326b, 
+    0x326b, 0x326b, 0x326c, 0x326c, 0x326d, 0x326d, 0x326d, 0x326e, 
+    0x326e, 0x326f, 0x326f, 0x326f, 0x3270, 0x3270, 0x3271, 0x3271, 
+    0x3271, 0x3272, 0x3272, 0x3273, 0x3273, 0x3273, 0x3274, 0x3274, 
+    0x3274, 0x3275, 0x3275, 0x3276, 0x3276, 0x3276, 0x3277, 0x3277, 
+    0x3278, 0x3278, 0x3278, 0x3279, 0x3279, 0x3279, 0x327a, 0x327a, 
+    0x327b, 0x327b, 0x327b, 0x327c, 0x327c, 0x327d, 0x327d, 0x327d, 
+    0x327e, 0x327e, 0x327f, 0x327f, 0x327f, 0x3280, 0x3280, 0x3280, 
+    0x3281, 0x3281, 0x3282, 0x3282, 0x3282, 0x3283, 0x3283, 0x3284, 
+    0x3284, 0x3284, 0x3285, 0x3285, 0x3285, 0x3286, 0x3286, 0x3287, 
+    0x3287, 0x3287, 0x3288, 0x3288, 0x3288, 0x3289, 0x3289, 0x328a, 
+    0x328a, 0x328a, 0x328b, 0x328b, 0x328c, 0x328c, 0x328c, 0x328d, 
+    0x328d, 0x328d, 0x328e, 0x328e, 0x328f, 0x328f, 0x328f, 0x3290, 
+    0x3290, 0x3290, 0x3291, 0x3291, 0x3292, 0x3292, 0x3292, 0x3293, 
+    0x3293, 0x3294, 0x3294, 0x3294, 0x3295, 0x3295, 0x3295, 0x3296, 
+    0x3296, 0x3297, 0x3297, 0x3297, 0x3298, 0x3298, 0x3298, 0x3299, 
+    0x3299, 0x329a, 0x329a, 0x329a, 0x329b, 0x329b, 0x329b, 0x329c, 
+    0x329c, 0x329d, 0x329d, 0x329d, 0x329e, 0x329e, 0x329e, 0x329f, 
+    0x329f, 0x32a0, 0x32a1, 0x32a1, 0x32a2, 0x32a3, 0x32a4, 0x32a4, 
+    0x32a5, 0x32a6, 0x32a7, 0x32a7, 0x32a8, 0x32a9, 0x32aa, 0x32aa, 
+    0x32ab, 0x32ac, 0x32ad, 0x32ad, 0x32ae, 0x32af, 0x32b0, 0x32b0, 
+    0x32b1, 0x32b2, 0x32b3, 0x32b3, 0x32b4, 0x32b5, 0x32b6, 0x32b6, 
+    0x32b7, 0x32b8, 0x32b9, 0x32b9, 0x32ba, 0x32bb, 0x32bc, 0x32bc, 
+    0x32bd, 0x32be, 0x32be, 0x32bf, 0x32c0, 0x32c1, 0x32c1, 0x32c2, 
+    0x32c3, 0x32c4, 0x32c4, 0x32c5, 0x32c6, 0x32c7, 0x32c7, 0x32c8, 
+    0x32c9, 0x32c9, 0x32ca, 0x32cb, 0x32cc, 0x32cc, 0x32cd, 0x32ce, 
+    0x32cf, 0x32cf, 0x32d0, 0x32d1, 0x32d2, 0x32d2, 0x32d3, 0x32d4, 
+    0x32d4, 0x32d5, 0x32d6, 0x32d7, 0x32d7, 0x32d8, 0x32d9, 0x32d9, 
+    0x32da, 0x32db, 0x32dc, 0x32dc, 0x32dd, 0x32de, 0x32df, 0x32df, 
+    0x32e0, 0x32e1, 0x32e1, 0x32e2, 0x32e3, 0x32e4, 0x32e4, 0x32e5, 
+    0x32e6, 0x32e6, 0x32e7, 0x32e8, 0x32e9, 0x32e9, 0x32ea, 0x32eb, 
+    0x32eb, 0x32ec, 0x32ed, 0x32ee, 0x32ee, 0x32ef, 0x32f0, 0x32f0, 
+    0x32f1, 0x32f2, 0x32f3, 0x32f3, 0x32f4, 0x32f5, 0x32f5, 0x32f6, 
+    0x32f7, 0x32f8, 0x32f8, 0x32f9, 0x32fa, 0x32fa, 0x32fb, 0x32fc, 
+    0x32fc, 0x32fd, 0x32fe, 0x32ff, 0x32ff, 0x3300, 0x3301, 0x3301, 
+    0x3302, 0x3303, 0x3304, 0x3304, 0x3305, 0x3306, 0x3306, 0x3307, 
+    0x3308, 0x3308, 0x3309, 0x330a, 0x330b, 0x330b, 0x330c, 0x330d, 
+    0x330d, 0x330e, 0x330f, 0x330f, 0x3310, 0x3311, 0x3311, 0x3312, 
+    0x3313, 0x3314, 0x3314, 0x3315, 0x3316, 0x3316, 0x3317, 0x3318, 
+    0x3318, 0x3319, 0x331a, 0x331b, 0x331b, 0x331c, 0x331d, 0x331d, 
+    0x331e, 0x331f, 0x331f, 0x3320, 0x3321, 0x3321, 0x3322, 0x3323, 
+    0x3323, 0x3324, 0x3325, 0x3326, 0x3326, 0x3327, 0x3328, 0x3328, 
+    0x3329, 0x332a, 0x332a, 0x332b, 0x332c, 0x332c, 0x332d, 0x332e, 
+    0x332e, 0x332f, 0x3330, 0x3330, 0x3331, 0x3332, 0x3333, 0x3333, 
+    0x3334, 0x3335, 0x3335, 0x3336, 0x3337, 0x3337, 0x3338, 0x3339, 
+    0x3339, 0x333a, 0x333b, 0x333b, 0x333c, 0x333d, 0x333d, 0x333e, 
+    0x333f, 0x333f, 0x3340, 0x3341, 0x3341, 0x3342, 0x3343, 0x3343, 
+    0x3344, 0x3345, 0x3345, 0x3346, 0x3347, 0x3347, 0x3348, 0x3349, 
+    0x334a, 0x334a, 0x334b, 0x334c, 0x334c, 0x334d, 0x334e, 0x334e, 
+    0x334f, 0x3350, 0x3350, 0x3351, 0x3352, 0x3352, 0x3353, 0x3354, 
+    0x3354, 0x3355, 0x3356, 0x3356, 0x3357, 0x3358, 0x3358, 0x3359, 
+    0x335a, 0x335a, 0x335b, 0x335c, 0x335c, 0x335d, 0x335e, 0x335e, 
+    0x335f, 0x335f, 0x3360, 0x3361, 0x3361, 0x3362, 0x3363, 0x3363, 
+    0x3364, 0x3365, 0x3365, 0x3366, 0x3367, 0x3367, 0x3368, 0x3369, 
+    0x3369, 0x336a, 0x336b, 0x336b, 0x336c, 0x336d, 0x336d, 0x336e, 
+    0x336f, 0x336f, 0x3370, 0x3371, 0x3371, 0x3372, 0x3373, 0x3373, 
+    0x3374, 0x3375, 0x3375, 0x3376, 0x3376, 0x3377, 0x3378, 0x3378, 
+    0x3379, 0x337a, 0x337a, 0x337b, 0x337c, 0x337c, 0x337d, 0x337e, 
+    0x337e, 0x337f, 0x3380, 0x3380, 0x3381, 0x3382, 0x3382, 0x3383, 
+    0x3383, 0x3384, 0x3385, 0x3385, 0x3386, 0x3387, 0x3387, 0x3388, 
+    0x3389, 0x3389, 0x338a, 0x338b, 0x338b, 0x338c, 0x338c, 0x338d, 
+    0x338e, 0x338e, 0x338f, 0x3390, 0x3390, 0x3391, 0x3392, 0x3392, 
+    0x3393, 0x3394, 0x3394, 0x3395, 0x3395, 0x3396, 0x3397, 0x3397, 
+    0x3398, 0x3399, 0x3399, 0x339a, 0x339b, 0x339b, 0x339c, 0x339c, 
+    0x339d, 0x339e, 0x339e, 0x339f, 0x33a0, 0x33a0, 0x33a1, 0x33a2, 
+    0x33a2, 0x33a3, 0x33a3, 0x33a4, 0x33a5, 0x33a5, 0x33a6, 0x33a7, 
+    0x33a7, 0x33a8, 0x33a9, 0x33a9, 0x33aa, 0x33aa, 0x33ab, 0x33ac, 
+    0x33ac, 0x33ad, 0x33ae, 0x33ae, 0x33af, 0x33af, 0x33b0, 0x33b1, 
+    0x33b1, 0x33b2, 0x33b3, 0x33b3, 0x33b4, 0x33b5, 0x33b5, 0x33b6, 
+    0x33b6, 0x33b7, 0x33b8, 0x33b8, 0x33b9, 0x33ba, 0x33ba, 0x33bb, 
+    0x33bb, 0x33bc, 0x33bd, 0x33bd, 0x33be, 0x33bf, 0x33bf, 0x33c0, 
+    0x33c0, 0x33c1, 0x33c2, 0x33c2, 0x33c3, 0x33c3, 0x33c4, 0x33c5, 
+    0x33c5, 0x33c6, 0x33c7, 0x33c7, 0x33c8, 0x33c8, 0x33c9, 0x33ca, 
+    0x33ca, 0x33cb, 0x33cc, 0x33cc, 0x33cd, 0x33cd, 0x33ce, 0x33cf, 
+    0x33cf, 0x33d0, 0x33d1, 0x33d1, 0x33d2, 0x33d2, 0x33d3, 0x33d4, 
+    0x33d4, 0x33d5, 0x33d5, 0x33d6, 0x33d7, 0x33d7, 0x33d8, 0x33d9, 
+    0x33d9, 0x33da, 0x33da, 0x33db, 0x33dc, 0x33dc, 0x33dd, 0x33dd, 
+    0x33de, 0x33df, 0x33df, 0x33e0, 0x33e0, 0x33e1, 0x33e2, 0x33e2, 
+    0x33e3, 0x33e4, 0x33e4, 0x33e5, 0x33e5, 0x33e6, 0x33e7, 0x33e7, 
+    0x33e8, 0x33e8, 0x33e9, 0x33ea, 0x33ea, 0x33eb, 0x33eb, 0x33ec, 
+    0x33ed, 0x33ed, 0x33ee, 0x33ee, 0x33ef, 0x33f0, 0x33f0, 0x33f1, 
+    0x33f1, 0x33f2, 0x33f3, 0x33f3, 0x33f4, 0x33f5, 0x33f5, 0x33f6, 
+    0x33f6, 0x33f7, 0x33f8, 0x33f8, 0x33f9, 0x33f9, 0x33fa, 0x33fb, 
+    0x33fb, 0x33fc, 0x33fc, 0x33fd, 0x33fe, 0x33fe, 0x33ff, 0x33ff, 
+    0x3400, 0x3400, 0x3401, 0x3401, 0x3401, 0x3401, 0x3402, 0x3402, 
+    0x3402, 0x3403, 0x3403, 0x3403, 0x3404, 0x3404, 0x3404, 0x3404, 
+    0x3405, 0x3405, 0x3405, 0x3406, 0x3406, 0x3406, 0x3407, 0x3407, 
+    0x3407, 0x3407, 0x3408, 0x3408, 0x3408, 0x3409, 0x3409, 0x3409, 
+    0x340a, 0x340a, 0x340a, 0x340a, 0x340b, 0x340b, 0x340b, 0x340c, 
+    0x340c, 0x340c, 0x340c, 0x340d, 0x340d, 0x340d, 0x340e, 0x340e, 
+    0x340e, 0x340f, 0x340f, 0x340f, 0x340f, 0x3410, 0x3410, 0x3410, 
+    0x3411, 0x3411, 0x3411, 0x3411, 0x3412, 0x3412, 0x3412, 0x3413, 
+    0x3413, 0x3413, 0x3414, 0x3414, 0x3414, 0x3414, 0x3415, 0x3415, 
+    0x3415, 0x3416, 0x3416, 0x3416, 0x3416, 0x3417, 0x3417, 0x3417, 
+    0x3418, 0x3418, 0x3418, 0x3419, 0x3419, 0x3419, 0x3419, 0x341a, 
+    0x341a, 0x341a, 0x341b, 0x341b, 0x341b, 0x341b, 0x341c, 0x341c, 
+    0x341c, 0x341d, 0x341d, 0x341d, 0x341d, 0x341e, 0x341e, 0x341e, 
+    0x341f, 0x341f, 0x341f, 0x341f, 0x3420, 0x3420, 0x3420, 0x3421, 
+    0x3421, 0x3421, 0x3422, 0x3422, 0x3422, 0x3422, 0x3423, 0x3423, 
+    0x3423, 0x3424, 0x3424, 0x3424, 0x3424, 0x3425, 0x3425, 0x3425, 
+    0x3426, 0x3426, 0x3426, 0x3426, 0x3427, 0x3427, 0x3427, 0x3428, 
+    0x3428, 0x3428, 0x3428, 0x3429, 0x3429, 0x3429, 0x342a, 0x342a, 
+    0x342a, 0x342a, 0x342b, 0x342b, 0x342b, 0x342c, 0x342c, 0x342c, 
+    0x342c, 0x342d, 0x342d, 0x342d, 0x342e, 0x342e, 0x342e, 0x342e, 
+    0x342f, 0x342f, 0x342f, 0x3430, 0x3430, 0x3430, 0x3430, 0x3431, 
+    0x3431, 0x3431, 0x3432, 0x3432, 0x3432, 0x3432, 0x3433, 0x3433, 
+    0x3433, 0x3433, 0x3434, 0x3434, 0x3434, 0x3435, 0x3435, 0x3435, 
+    0x3435, 0x3436, 0x3436, 0x3436, 0x3437, 0x3437, 0x3437, 0x3437, 
+    0x3438, 0x3438, 0x3438, 0x3439, 0x3439, 0x3439, 0x3439, 0x343a, 
+    0x343a, 0x343a, 0x343b, 0x343b, 0x343b, 0x343b, 0x343c, 0x343c, 
+    0x343c, 0x343c, 0x343d, 0x343d, 0x343d, 0x343e, 0x343e, 0x343e, 
+    0x343e, 0x343f, 0x343f, 0x343f, 0x3440, 0x3440, 0x3440, 0x3440, 
+    0x3441, 0x3441, 0x3441, 0x3442, 0x3442, 0x3442, 0x3442, 0x3443, 
+    0x3443, 0x3443, 0x3443, 0x3444, 0x3444, 0x3444, 0x3445, 0x3445, 
+    0x3445, 0x3445, 0x3446, 0x3446, 0x3446, 0x3447, 0x3447, 0x3447, 
+    0x3447, 0x3448, 0x3448, 0x3448, 0x3448, 0x3449, 0x3449, 0x3449, 
+    0x344a, 0x344a, 0x344a, 0x344a, 0x344b, 0x344b, 0x344b, 0x344b, 
+    0x344c, 0x344c, 0x344c, 0x344d, 0x344d, 0x344d, 0x344d, 0x344e, 
+    0x344e, 0x344e, 0x344f, 0x344f, 0x344f, 0x344f, 0x3450, 0x3450, 
+    0x3450, 0x3450, 0x3451, 0x3451, 0x3451, 0x3452, 0x3452, 0x3452, 
+    0x3452, 0x3453, 0x3453, 0x3453, 0x3453, 0x3454, 0x3454, 0x3454, 
+    0x3455, 0x3455, 0x3455, 0x3455, 0x3456, 0x3456, 0x3456, 0x3456, 
+    0x3457, 0x3457, 0x3457, 0x3458, 0x3458, 0x3458, 0x3458, 0x3459, 
+    0x3459, 0x3459, 0x3459, 0x345a, 0x345a, 0x345a, 0x345b, 0x345b, 
+    0x345b, 0x345b, 0x345c, 0x345c, 0x345c, 0x345c, 0x345d, 0x345d, 
+    0x345d, 0x345d, 0x345e, 0x345e, 0x345e, 0x345f, 0x345f, 0x345f, 
+    0x345f, 0x3460, 0x3460, 0x3460, 0x3460, 0x3461, 0x3461, 0x3461, 
+    0x3462, 0x3462, 0x3462, 0x3462, 0x3463, 0x3463, 0x3463, 0x3463, 
+    0x3464, 0x3464, 0x3464, 0x3464, 0x3465, 0x3465, 0x3465, 0x3466, 
+    0x3466, 0x3466, 0x3466, 0x3467, 0x3467, 0x3467, 0x3467, 0x3468, 
+    0x3468, 0x3468, 0x3468, 0x3469, 0x3469, 0x3469, 0x346a, 0x346a, 
+    0x346a, 0x346a, 0x346b, 0x346b, 0x346b, 0x346b, 0x346c, 0x346c, 
+    0x346c, 0x346c, 0x346d, 0x346d, 0x346d, 0x346e, 0x346e, 0x346e, 
+    0x346e, 0x346f, 0x346f, 0x346f, 0x346f, 0x3470, 0x3470, 0x3470, 
+    0x3470, 0x3471, 0x3471, 0x3471, 0x3472, 0x3472, 0x3472, 0x3472, 
+    0x3473, 0x3473, 0x3473, 0x3473, 0x3474, 0x3474, 0x3474, 0x3474, 
+    0x3475, 0x3475, 0x3475, 0x3475, 0x3476, 0x3476, 0x3476, 0x3477, 
+    0x3477, 0x3477, 0x3477, 0x3478, 0x3478, 0x3478, 0x3478, 0x3479, 
+    0x3479, 0x3479, 0x3479, 0x347a, 0x347a, 0x347a, 0x347a, 0x347b, 
+    0x347b, 0x347b, 0x347c, 0x347c, 0x347c, 0x347c, 0x347d, 0x347d, 
+    0x347d, 0x347d, 0x347e, 0x347e, 0x347e, 0x347e, 0x347f, 0x347f, 
+    0x347f, 0x347f, 0x3480, 0x3480, 0x3480, 0x3480, 0x3481, 0x3481, 
+    0x3481, 0x3482, 0x3482, 0x3482, 0x3482, 0x3483, 0x3483, 0x3483, 
+    0x3483, 0x3484, 0x3484, 0x3484, 0x3484, 0x3485, 0x3485, 0x3485, 
+    0x3485, 0x3486, 0x3486, 0x3486, 0x3486, 0x3487, 0x3487, 0x3487, 
+    0x3487, 0x3488, 0x3488, 0x3488, 0x3489, 0x3489, 0x3489, 0x3489, 
+    0x348a, 0x348a, 0x348b, 0x348b, 0x348c, 0x348c, 0x348d, 0x348d, 
+    0x348e, 0x348e, 0x348f, 0x348f, 0x3490, 0x3490, 0x3491, 0x3491, 
+    0x3492, 0x3492, 0x3493, 0x3493, 0x3494, 0x3494, 0x3495, 0x3495, 
+    0x3496, 0x3496, 0x3497, 0x3497, 0x3498, 0x3498, 0x3499, 0x3499, 
+    0x349a, 0x349a, 0x349b, 0x349b, 0x349c, 0x349c, 0x349d, 0x349d, 
+    0x349e, 0x349e, 0x349f, 0x349f, 0x34a0, 0x34a0, 0x34a1, 0x34a1, 
+    0x34a2, 0x34a2, 0x34a3, 0x34a3, 0x34a4, 0x34a4, 0x34a5, 0x34a5, 
+    0x34a6, 0x34a6, 0x34a7, 0x34a7, 0x34a8, 0x34a8, 0x34a9, 0x34a9, 
+    0x34aa, 0x34aa, 0x34ab, 0x34ab, 0x34ac, 0x34ac, 0x34ad, 0x34ad, 
+    0x34ae, 0x34ae, 0x34af, 0x34af, 0x34b0, 0x34b0, 0x34b1, 0x34b1, 
+    0x34b2, 0x34b2, 0x34b3, 0x34b3, 0x34b4, 0x34b4, 0x34b5, 0x34b5, 
+    0x34b6, 0x34b6, 0x34b7, 0x34b7, 0x34b8, 0x34b8, 0x34b9, 0x34b9, 
+    0x34ba, 0x34ba, 0x34bb, 0x34bb, 0x34bc, 0x34bc, 0x34bd, 0x34bd, 
+    0x34be, 0x34be, 0x34bf, 0x34bf, 0x34c0, 0x34c0, 0x34c1, 0x34c1, 
+    0x34c2, 0x34c2, 0x34c3, 0x34c3, 0x34c4, 0x34c4, 0x34c5, 0x34c5, 
+    0x34c6, 0x34c6, 0x34c7, 0x34c7, 0x34c7, 0x34c8, 0x34c8, 0x34c9, 
+    0x34c9, 0x34ca, 0x34ca, 0x34cb, 0x34cb, 0x34cc, 0x34cc, 0x34cd, 
+    0x34cd, 0x34ce, 0x34ce, 0x34cf, 0x34cf, 0x34d0, 0x34d0, 0x34d1, 
+    0x34d1, 0x34d2, 0x34d2, 0x34d3, 0x34d3, 0x34d4, 0x34d4, 0x34d4, 
+    0x34d5, 0x34d5, 0x34d6, 0x34d6, 0x34d7, 0x34d7, 0x34d8, 0x34d8, 
+    0x34d9, 0x34d9, 0x34da, 0x34da, 0x34db, 0x34db, 0x34dc, 0x34dc, 
+    0x34dd, 0x34dd, 0x34de, 0x34de, 0x34de, 0x34df, 0x34df, 0x34e0, 
+    0x34e0, 0x34e1, 0x34e1, 0x34e2, 0x34e2, 0x34e3, 0x34e3, 0x34e4, 
+    0x34e4, 0x34e5, 0x34e5, 0x34e6, 0x34e6, 0x34e6, 0x34e7, 0x34e7, 
+    0x34e8, 0x34e8, 0x34e9, 0x34e9, 0x34ea, 0x34ea, 0x34eb, 0x34eb, 
+    0x34ec, 0x34ec, 0x34ed, 0x34ed, 0x34ee, 0x34ee, 0x34ee, 0x34ef, 
+    0x34ef, 0x34f0, 0x34f0, 0x34f1, 0x34f1, 0x34f2, 0x34f2, 0x34f3, 
+    0x34f3, 0x34f4, 0x34f4, 0x34f5, 0x34f5, 0x34f5, 0x34f6, 0x34f6, 
+    0x34f7, 0x34f7, 0x34f8, 0x34f8, 0x34f9, 0x34f9, 0x34fa, 0x34fa, 
+    0x34fb, 0x34fb, 0x34fb, 0x34fc, 0x34fc, 0x34fd, 0x34fd, 0x34fe, 
+    0x34fe, 0x34ff, 0x34ff, 0x3500, 0x3500, 0x3500, 0x3501, 0x3501, 
+    0x3502, 0x3502, 0x3503, 0x3503, 0x3504, 0x3504, 0x3505, 0x3505, 
+    0x3506, 0x3506, 0x3506, 0x3507, 0x3507, 0x3508, 0x3508, 0x3509, 
+    0x3509, 0x350a, 0x350a, 0x350b, 0x350b, 0x350b, 0x350c, 0x350c, 
+    0x350d, 0x350d, 0x350e, 0x350e, 0x350f, 0x350f, 0x3510, 0x3510, 
+    0x3510, 0x3511, 0x3511, 0x3512, 0x3512, 0x3513, 0x3513, 0x3514, 
+    0x3514, 0x3514, 0x3515, 0x3515, 0x3516, 0x3516, 0x3517, 0x3517, 
+    0x3518, 0x3518, 0x3519, 0x3519, 0x3519, 0x351a, 0x351a, 0x351b, 
+    0x351b, 0x351c, 0x351c, 0x351d, 0x351d, 0x351d, 0x351e, 0x351e, 
+    0x351f, 0x351f, 0x3520, 0x3520, 0x3521, 0x3521, 0x3521, 0x3522, 
+    0x3522, 0x3523, 0x3523, 0x3524, 0x3524, 0x3525, 0x3525, 0x3525, 
+    0x3526, 0x3526, 0x3527, 0x3527, 0x3528, 0x3528, 0x3529, 0x3529, 
+    0x3529, 0x352a, 0x352a, 0x352b, 0x352b, 0x352c, 0x352c, 0x352d, 
+    0x352d, 0x352d, 0x352e, 0x352e, 0x352f, 0x352f, 0x3530, 0x3530, 
+    0x3530, 0x3531, 0x3531, 0x3532, 0x3532, 0x3533, 0x3533, 0x3534, 
+    0x3534, 0x3534, 0x3535, 0x3535, 0x3536, 0x3536, 0x3537, 0x3537, 
+    0x3537, 0x3538, 0x3538, 0x3539, 0x3539, 0x353a, 0x353a, 0x353b, 
+    0x353b, 0x353b, 0x353c, 0x353c, 0x353d, 0x353d, 0x353e, 0x353e, 
+    0x353e, 0x353f, 0x353f, 0x3540, 0x3540, 0x3541, 0x3541, 0x3541, 
+    0x3542, 0x3542, 0x3543, 0x3543, 0x3544, 0x3544, 0x3544, 0x3545, 
+    0x3545, 0x3546, 0x3546, 0x3547, 0x3547, 0x3548, 0x3548, 0x3548, 
+    0x3549, 0x3549, 0x354a, 0x354a, 0x354b, 0x354b, 0x354b, 0x354c, 
+    0x354c, 0x354d, 0x354d, 0x354e, 0x354e, 0x354e, 0x354f, 0x354f, 
+    0x3550, 0x3550, 0x3551, 0x3551, 0x3551, 0x3552, 0x3552, 0x3553, 
+    0x3553, 0x3553, 0x3554, 0x3554, 0x3555, 0x3555, 0x3556, 0x3556, 
+    0x3556, 0x3557, 0x3557, 0x3558, 0x3558, 0x3559, 0x3559, 0x3559, 
+    0x355a, 0x355a, 0x355b, 0x355b, 0x355c, 0x355c, 0x355c, 0x355d, 
+    0x355d, 0x355e, 0x355e, 0x355e, 0x355f, 0x355f, 0x3560, 0x3560, 
+    0x3561, 0x3561, 0x3561, 0x3562, 0x3562, 0x3563, 0x3563, 0x3564, 
+    0x3564, 0x3564, 0x3565, 0x3565, 0x3566, 0x3566, 0x3566, 0x3567, 
+    0x3567, 0x3568, 0x3568, 0x3569, 0x3569, 0x3569, 0x356a, 0x356a, 
+    0x356b, 0x356b, 0x356b, 0x356c, 0x356c, 0x356d, 0x356d, 0x356e, 
+    0x356e, 0x356e, 0x356f, 0x356f, 0x3570, 0x3570, 0x3570, 0x3571, 
+    0x3571, 0x3572, 0x3572, 0x3573, 0x3573, 0x3573, 0x3574, 0x3574, 
+    0x3575, 0x3575, 0x3575, 0x3576, 0x3576, 0x3577, 0x3577, 0x3577, 
+    0x3578, 0x3578, 0x3579, 0x3579, 0x357a, 0x357a, 0x357a, 0x357b, 
+    0x357b, 0x357c, 0x357c, 0x357c, 0x357d, 0x357d, 0x357e, 0x357e, 
+    0x357e, 0x357f, 0x357f, 0x3580, 0x3580, 0x3581, 0x3581, 0x3581, 
+    0x3582, 0x3582, 0x3583, 0x3583, 0x3583, 0x3584, 0x3584, 0x3585, 
+    0x3585, 0x3585, 0x3586, 0x3586, 0x3587, 0x3587, 0x3587, 0x3588, 
+    0x3588, 0x3589, 0x3589, 0x3589, 0x358a, 0x358a, 0x358b, 0x358b, 
+    0x358c, 0x358c, 0x358c, 0x358d, 0x358d, 0x358e, 0x358e, 0x358e, 
+    0x358f, 0x358f, 0x3590, 0x3590, 0x3590, 0x3591, 0x3591, 0x3592, 
+    0x3592, 0x3592, 0x3593, 0x3593, 0x3594, 0x3594, 0x3594, 0x3595, 
+    0x3595, 0x3596, 0x3596, 0x3596, 0x3597, 0x3597, 0x3598, 0x3598, 
+    0x3598, 0x3599, 0x3599, 0x359a, 0x359a, 0x359a, 0x359b, 0x359b, 
+    0x359c, 0x359c, 0x359c, 0x359d, 0x359d, 0x359e, 0x359e, 0x359e, 
+    0x359f, 0x359f, 0x35a0, 0x35a0, 0x35a0, 0x35a1, 0x35a1, 0x35a2, 
+    0x35a2, 0x35a2, 0x35a3, 0x35a3, 0x35a4, 0x35a4, 0x35a4, 0x35a5, 
+    0x35a5, 0x35a6, 0x35a6, 0x35a6, 0x35a7, 0x35a7, 0x35a8, 0x35a8, 
+    0x35a8, 0x35a9, 0x35a9, 0x35aa, 0x35aa, 0x35aa, 0x35ab, 0x35ab, 
+    0x35ac, 0x35ac, 0x35ac, 0x35ad, 0x35ad, 0x35ad, 0x35ae, 0x35ae, 
+    0x35af, 0x35af, 0x35af, 0x35b0, 0x35b0, 0x35b1, 0x35b1, 0x35b1, 
+    0x35b2, 0x35b2, 0x35b3, 0x35b3, 0x35b3, 0x35b4, 0x35b4, 0x35b5, 
+    0x35b5, 0x35b5, 0x35b6, 0x35b6, 0x35b7, 0x35b7, 0x35b7, 0x35b8, 
+    0x35b8, 0x35b8, 0x35b9, 0x35b9, 0x35ba, 0x35ba, 0x35ba, 0x35bb, 
+    0x35bb, 0x35bc, 0x35bc, 0x35bc, 0x35bd, 0x35bd, 0x35be, 0x35be, 
+    0x35be, 0x35bf, 0x35bf, 0x35bf, 0x35c0, 0x35c0, 0x35c1, 0x35c1, 
+    0x35c1, 0x35c2, 0x35c2, 0x35c3, 0x35c3, 0x35c3, 0x35c4, 0x35c4, 
+    0x35c5, 0x35c5, 0x35c5, 0x35c6, 0x35c6, 0x35c6, 0x35c7, 0x35c7, 
+    0x35c8, 0x35c8, 0x35c8, 0x35c9, 0x35c9, 0x35ca, 0x35ca, 0x35ca, 
+    0x35cb, 0x35cb, 0x35cb, 0x35cc, 0x35cc, 0x35cd, 0x35cd, 0x35cd, 
+    0x35ce, 0x35ce, 0x35cf, 0x35cf, 0x35cf, 0x35d0, 0x35d0, 0x35d0, 
+    0x35d1, 0x35d1, 0x35d2, 0x35d2, 0x35d2, 0x35d3, 0x35d3, 0x35d3, 
+    0x35d4, 0x35d4, 0x35d5, 0x35d5, 0x35d5, 0x35d6, 0x35d6, 0x35d7, 
+    0x35d7, 0x35d7, 0x35d8, 0x35d8, 0x35d8, 0x35d9, 0x35d9, 0x35da, 
+    0x35da, 0x35da, 0x35db, 0x35db, 0x35db, 0x35dc, 0x35dc, 0x35dd, 
+    0x35dd, 0x35dd, 0x35de, 0x35de, 0x35df, 0x35df, 0x35df, 0x35e0, 
+    0x35e0, 0x35e0, 0x35e1, 0x35e1, 0x35e2, 0x35e2, 0x35e2, 0x35e3, 
+    0x35e3, 0x35e3, 0x35e4, 0x35e4, 0x35e5, 0x35e5, 0x35e5, 0x35e6, 
+    0x35e6, 0x35e6, 0x35e7, 0x35e7, 0x35e8, 0x35e8, 0x35e8, 0x35e9, 
+    0x35e9, 0x35e9, 0x35ea, 0x35ea, 0x35eb, 0x35eb, 0x35eb, 0x35ec, 
+    0x35ec, 0x35ec, 0x35ed, 0x35ed, 0x35ee, 0x35ee, 0x35ee, 0x35ef, 
+    0x35ef, 0x35ef, 0x35f0, 0x35f0, 0x35f1, 0x35f1, 0x35f1, 0x35f2, 
+    0x35f2, 0x35f2, 0x35f3, 0x35f3, 0x35f4, 0x35f4, 0x35f4, 0x35f5, 
+    0x35f5, 0x35f5, 0x35f6, 0x35f6, 0x35f7, 0x35f7, 0x35f7, 0x35f8, 
+    0x35f8, 0x35f8, 0x35f9, 0x35f9, 0x35f9, 0x35fa, 0x35fa, 0x35fb, 
+    0x35fb, 0x35fb, 0x35fc, 0x35fc, 0x35fc, 0x35fd, 0x35fd, 0x35fe, 
+    0x35fe, 0x35fe, 0x35ff, 0x35ff, 0x35ff, 0x3600, 0x3600, 0x3601, 
+    0x3601, 0x3601, 0x3602, 0x3602, 0x3602, 0x3603, 0x3603, 0x3603, 
+    0x3604, 0x3604, 0x3605, 0x3605, 0x3605, 0x3606, 0x3606, 0x3606, 
+    0x3607, 0x3607, 0x3607, 0x3608, 0x3608, 0x3609, 0x3609, 0x3609, 
+    0x360a, 0x360a, 0x360a, 0x360b, 0x360b, 0x360c, 0x360c, 0x360c, 
+    0x360d, 0x360d, 0x360d, 0x360e, 0x360e, 0x360e, 0x360f, 0x360f, 
+    0x3610, 0x3610, 0x3610, 0x3611, 0x3611, 0x3611, 0x3612, 0x3612, 
+    0x3612, 0x3613, 0x3613, 0x3614, 0x3614, 0x3614, 0x3615, 0x3615, 
+    0x3615, 0x3616, 0x3616, 0x3616, 0x3617, 0x3617, 0x3618, 0x3618, 
+    0x3618, 0x3619, 0x3619, 0x3619, 0x361a, 0x361a, 0x361a, 0x361b, 
+    0x361b, 0x361c, 0x361c, 0x361c, 0x361d, 0x361d, 0x361d, 0x361e, 
+    0x361e, 0x361e, 0x361f, 0x361f, 0x361f, 0x3620, 0x3620, 0x3621, 
+    0x3621, 0x3621, 0x3622, 0x3622, 0x3622, 0x3623, 0x3623, 0x3623, 
+    0x3624, 0x3624, 0x3624, 0x3625, 0x3625, 0x3626, 0x3626, 0x3626, 
+    0x3627, 0x3627, 0x3627, 0x3628, 0x3628, 0x3628, 0x3629, 0x3629, 
+    0x362a, 0x362a, 0x362a, 0x362b, 0x362b, 0x362b, 0x362c, 0x362c, 
+    0x362c, 0x362d, 0x362d, 0x362d, 0x362e, 0x362e, 0x362e, 0x362f, 
+    0x362f, 0x3630, 0x3630, 0x3630, 0x3631, 0x3631, 0x3631, 0x3632, 
+    0x3632, 0x3632, 0x3633, 0x3633, 0x3633, 0x3634, 0x3634, 0x3635, 
+    0x3635, 0x3635, 0x3636, 0x3636, 0x3636, 0x3637, 0x3637, 0x3637, 
+    0x3638, 0x3638, 0x3639, 0x363a, 0x363b, 0x363b, 0x363c, 0x363d, 
+    0x363d, 0x363e, 0x363f, 0x363f, 0x3640, 0x3641, 0x3642, 0x3642, 
+    0x3643, 0x3644, 0x3644, 0x3645, 0x3646, 0x3646, 0x3647, 0x3648, 
+    0x3649, 0x3649, 0x364a, 0x364b, 0x364b, 0x364c, 0x364d, 0x364d, 
+    0x364e, 0x364f, 0x3650, 0x3650, 0x3651, 0x3652, 0x3652, 0x3653, 
+    0x3654, 0x3654, 0x3655, 0x3656, 0x3656, 0x3657, 0x3658, 0x3659, 
+    0x3659, 0x365a, 0x365b, 0x365b, 0x365c, 0x365d, 0x365d, 0x365e, 
+    0x365f, 0x365f, 0x3660, 0x3661, 0x3661, 0x3662, 0x3663, 0x3664, 
+    0x3664, 0x3665, 0x3666, 0x3666, 0x3667, 0x3668, 0x3668, 0x3669, 
+    0x366a, 0x366a, 0x366b, 0x366c, 0x366c, 0x366d, 0x366e, 0x366e, 
+    0x366f, 0x3670, 0x3670, 0x3671, 0x3672, 0x3672, 0x3673, 0x3674, 
+    0x3674, 0x3675, 0x3676, 0x3677, 0x3677, 0x3678, 0x3679, 0x3679, 
+    0x367a, 0x367b, 0x367b, 0x367c, 0x367d, 0x367d, 0x367e, 0x367f, 
+    0x367f, 0x3680, 0x3681, 0x3681, 0x3682, 0x3683, 0x3683, 0x3684, 
+    0x3685, 0x3685, 0x3686, 0x3687, 0x3687, 0x3688, 0x3689, 0x3689, 
+    0x368a, 0x368b, 0x368b, 0x368c, 0x368d, 0x368d, 0x368e, 0x368f, 
+    0x368f, 0x3690, 0x3691, 0x3691, 0x3692, 0x3693, 0x3693, 0x3694, 
+    0x3695, 0x3695, 0x3696, 0x3697, 0x3697, 0x3698, 0x3698, 0x3699, 
+    0x369a, 0x369a, 0x369b, 0x369c, 0x369c, 0x369d, 0x369e, 0x369e, 
+    0x369f, 0x36a0, 0x36a0, 0x36a1, 0x36a2, 0x36a2, 0x36a3, 0x36a4, 
+    0x36a4, 0x36a5, 0x36a6, 0x36a6, 0x36a7, 0x36a8, 0x36a8, 0x36a9, 
+    0x36aa, 0x36aa, 0x36ab, 0x36ab, 0x36ac, 0x36ad, 0x36ad, 0x36ae, 
+    0x36af, 0x36af, 0x36b0, 0x36b1, 0x36b1, 0x36b2, 0x36b3, 0x36b3, 
+    0x36b4, 0x36b5, 0x36b5, 0x36b6, 0x36b6, 0x36b7, 0x36b8, 0x36b8, 
+    0x36b9, 0x36ba, 0x36ba, 0x36bb, 0x36bc, 0x36bc, 0x36bd, 0x36be, 
+    0x36be, 0x36bf, 0x36bf, 0x36c0, 0x36c1, 0x36c1, 0x36c2, 0x36c3, 
+    0x36c3, 0x36c4, 0x36c5, 0x36c5, 0x36c6, 0x36c6, 0x36c7, 0x36c8, 
+    0x36c8, 0x36c9, 0x36ca, 0x36ca, 0x36cb, 0x36cc, 0x36cc, 0x36cd, 
+    0x36cd, 0x36ce, 0x36cf, 0x36cf, 0x36d0, 0x36d1, 0x36d1, 0x36d2, 
+    0x36d3, 0x36d3, 0x36d4, 0x36d4, 0x36d5, 0x36d6, 0x36d6, 0x36d7, 
+    0x36d8, 0x36d8, 0x36d9, 0x36d9, 0x36da, 0x36db, 0x36db, 0x36dc, 
+    0x36dd, 0x36dd, 0x36de, 0x36de, 0x36df, 0x36e0, 0x36e0, 0x36e1, 
+    0x36e2, 0x36e2, 0x36e3, 0x36e4, 0x36e4, 0x36e5, 0x36e5, 0x36e6, 
+    0x36e7, 0x36e7, 0x36e8, 0x36e8, 0x36e9, 0x36ea, 0x36ea, 0x36eb, 
+    0x36ec, 0x36ec, 0x36ed, 0x36ed, 0x36ee, 0x36ef, 0x36ef, 0x36f0, 
+    0x36f1, 0x36f1, 0x36f2, 0x36f2, 0x36f3, 0x36f4, 0x36f4, 0x36f5, 
+    0x36f6, 0x36f6, 0x36f7, 0x36f7, 0x36f8, 0x36f9, 0x36f9, 0x36fa, 
+    0x36fa, 0x36fb, 0x36fc, 0x36fc, 0x36fd, 0x36fe, 0x36fe, 0x36ff, 
+    0x36ff, 0x3700, 0x3701, 0x3701, 0x3702, 0x3702, 0x3703, 0x3704, 
+    0x3704, 0x3705, 0x3705, 0x3706, 0x3707, 0x3707, 0x3708, 0x3709, 
+    0x3709, 0x370a, 0x370a, 0x370b, 0x370c, 0x370c, 0x370d, 0x370d, 
+    0x370e, 0x370f, 0x370f, 0x3710, 0x3710, 0x3711, 0x3712, 0x3712, 
+    0x3713, 0x3713, 0x3714, 0x3715, 0x3715, 0x3716, 0x3716, 0x3717, 
+    0x3718, 0x3718, 0x3719, 0x3719, 0x371a, 0x371b, 0x371b, 0x371c, 
+    0x371d, 0x371d, 0x371e, 0x371e, 0x371f, 0x3720, 0x3720, 0x3721, 
+    0x3721, 0x3722, 0x3723, 0x3723, 0x3724, 0x3724, 0x3725, 0x3725, 
+    0x3726, 0x3727, 0x3727, 0x3728, 0x3728, 0x3729, 0x372a, 0x372a, 
+    0x372b, 0x372b, 0x372c, 0x372d, 0x372d, 0x372e, 0x372e, 0x372f, 
+    0x3730, 0x3730, 0x3731, 0x3731, 0x3732, 0x3733, 0x3733, 0x3734, 
+    0x3734, 0x3735, 0x3736, 0x3736, 0x3737, 0x3737, 0x3738, 0x3739, 
+    0x3739, 0x373a, 0x373a, 0x373b, 0x373b, 0x373c, 0x373d, 0x373d, 
+    0x373e, 0x373e, 0x373f, 0x3740, 0x3740, 0x3741, 0x3741, 0x3742, 
+    0x3743, 0x3743, 0x3744, 0x3744, 0x3745, 0x3745, 0x3746, 0x3747, 
+    0x3747, 0x3748, 0x3748, 0x3749, 0x374a, 0x374a, 0x374b, 0x374b, 
+    0x374c, 0x374c, 0x374d, 0x374e, 0x374e, 0x374f, 0x374f, 0x3750, 
+    0x3751, 0x3751, 0x3752, 0x3752, 0x3753, 0x3753, 0x3754, 0x3755, 
+    0x3755, 0x3756, 0x3756, 0x3757, 0x3757, 0x3758, 0x3759, 0x3759, 
+    0x375a, 0x375a, 0x375b, 0x375c, 0x375c, 0x375d, 0x375d, 0x375e, 
+    0x375e, 0x375f, 0x3760, 0x3760, 0x3761, 0x3761, 0x3762, 0x3762, 
+    0x3763, 0x3764, 0x3764, 0x3765, 0x3765, 0x3766, 0x3766, 0x3767, 
+    0x3768, 0x3768, 0x3769, 0x3769, 0x376a, 0x376a, 0x376b, 0x376c, 
+    0x376c, 0x376d, 0x376d, 0x376e, 0x376e, 0x376f, 0x3770, 0x3770, 
+    0x3771, 0x3771, 0x3772, 0x3772, 0x3773, 0x3774, 0x3774, 0x3775, 
+    0x3775, 0x3776, 0x3776, 0x3777, 0x3778, 0x3778, 0x3779, 0x3779, 
+    0x377a, 0x377a, 0x377b, 0x377c, 0x377c, 0x377d, 0x377d, 0x377e, 
+    0x377e, 0x377f, 0x377f, 0x3780, 0x3781, 0x3781, 0x3782, 0x3782, 
+    0x3783, 0x3783, 0x3784, 0x3785, 0x3785, 0x3786, 0x3786, 0x3787, 
+    0x3787, 0x3788, 0x3788, 0x3789, 0x378a, 0x378a, 0x378b, 0x378b, 
+    0x378c, 0x378c, 0x378d, 0x378e, 0x378e, 0x378f, 0x378f, 0x3790, 
+    0x3790, 0x3791, 0x3791, 0x3792, 0x3793, 0x3793, 0x3794, 0x3794, 
+    0x3795, 0x3795, 0x3796, 0x3796, 0x3797, 0x3798, 0x3798, 0x3799, 
+    0x3799, 0x379a, 0x379a, 0x379b, 0x379b, 0x379c, 0x379d, 0x379d, 
+    0x379e, 0x379e, 0x379f, 0x379f, 0x37a0, 0x37a0, 0x37a1, 0x37a2, 
+    0x37a2, 0x37a3, 0x37a3, 0x37a4, 0x37a4, 0x37a5, 0x37a5, 0x37a6, 
+    0x37a7, 0x37a7, 0x37a8, 0x37a8, 0x37a9, 0x37a9, 0x37aa, 0x37aa, 
+    0x37ab, 0x37ab, 0x37ac, 0x37ad, 0x37ad, 0x37ae, 0x37ae, 0x37af, 
+    0x37af, 0x37b0, 0x37b0, 0x37b1, 0x37b2, 0x37b2, 0x37b3, 0x37b3, 
+    0x37b4, 0x37b4, 0x37b5, 0x37b5, 0x37b6, 0x37b6, 0x37b7, 0x37b8, 
+    0x37b8, 0x37b9, 0x37b9, 0x37ba, 0x37ba, 0x37bb, 0x37bb, 0x37bc, 
+    0x37bc, 0x37bd, 0x37bd, 0x37be, 0x37bf, 0x37bf, 0x37c0, 0x37c0, 
+    0x37c1, 0x37c1, 0x37c2, 0x37c2, 0x37c3, 0x37c3, 0x37c4, 0x37c5, 
+    0x37c5, 0x37c6, 0x37c6, 0x37c7, 0x37c7, 0x37c8, 0x37c8, 0x37c9, 
+    0x37c9, 0x37ca, 0x37ca, 0x37cb, 0x37cc, 0x37cc, 0x37cd, 0x37cd, 
+    0x37ce, 0x37ce, 0x37cf, 0x37cf, 0x37d0, 0x37d0, 0x37d1, 0x37d1, 
+    0x37d2, 0x37d3, 0x37d3, 0x37d4, 0x37d4, 0x37d5, 0x37d5, 0x37d6, 
+    0x37d6, 0x37d7, 0x37d7, 0x37d8, 0x37d8, 0x37d9, 0x37da, 0x37da, 
+    0x37db, 0x37db, 0x37dc, 0x37dc, 0x37dd, 0x37dd, 0x37de, 0x37de, 
+    0x37df, 0x37df, 0x37e0, 0x37e0, 0x37e1, 0x37e2, 0x37e2, 0x37e3, 
+    0x37e3, 0x37e4, 0x37e4, 0x37e5, 0x37e5, 0x37e6, 0x37e6, 0x37e7, 
+    0x37e7, 0x37e8, 0x37e8, 0x37e9, 0x37e9, 0x37ea, 0x37eb, 0x37eb, 
+    0x37ec, 0x37ec, 0x37ed, 0x37ed, 0x37ee, 0x37ee, 0x37ef, 0x37ef, 
+    0x37f0, 0x37f0, 0x37f1, 0x37f1, 0x37f2, 0x37f2, 0x37f3, 0x37f3, 
+    0x37f4, 0x37f5, 0x37f5, 0x37f6, 0x37f6, 0x37f7, 0x37f7, 0x37f8, 
+    0x37f8, 0x37f9, 0x37f9, 0x37fa, 0x37fa, 0x37fb, 0x37fb, 0x37fc, 
+    0x37fc, 0x37fd, 0x37fd, 0x37fe, 0x37fe, 0x37ff, 0x3800, 0x3800, 
+    0x3800, 0x3801, 0x3801, 0x3801, 0x3801, 0x3802, 0x3802, 0x3802, 
+    0x3802, 0x3803, 0x3803, 0x3803, 0x3803, 0x3804, 0x3804, 0x3804, 
+    0x3804, 0x3805, 0x3805, 0x3805, 0x3805, 0x3806, 0x3806, 0x3806, 
+    0x3807, 0x3807, 0x3807, 0x3807, 0x3808, 0x3808, 0x3808, 0x3808, 
+    0x3809, 0x3809, 0x3809, 0x3809, 0x380a, 0x380a, 0x380a, 0x380a, 
+    0x380b, 0x380b, 0x380b, 0x380b, 0x380c, 0x380c, 0x380c, 0x380c, 
+    0x380d, 0x380d, 0x380d, 0x380d, 0x380e, 0x380e, 0x380e, 0x380f, 
+    0x380f, 0x380f, 0x380f, 0x3810, 0x3810, 0x3810, 0x3810, 0x3811, 
+    0x3811, 0x3811, 0x3811, 0x3812, 0x3812, 0x3812, 0x3812, 0x3813, 
+    0x3813, 0x3813, 0x3813, 0x3814, 0x3814, 0x3814, 0x3814, 0x3815, 
+    0x3815, 0x3815, 0x3815, 0x3816, 0x3816, 0x3816, 0x3816, 0x3817, 
+    0x3817, 0x3817, 0x3817, 0x3818, 0x3818, 0x3818, 0x3818, 0x3819, 
+    0x3819, 0x3819, 0x3819, 0x381a, 0x381a, 0x381a, 0x381b, 0x381b, 
+    0x381b, 0x381b, 0x381c, 0x381c, 0x381c, 0x381c, 0x381d, 0x381d, 
+    0x381d, 0x381d, 0x381e, 0x381e, 0x381e, 0x381e, 0x381f, 0x381f, 
+    0x381f, 0x381f, 0x3820, 0x3820, 0x3820, 0x3820, 0x3821, 0x3821, 
+    0x3821, 0x3821, 0x3822, 0x3822, 0x3822, 0x3822, 0x3823, 0x3823, 
+    0x3823, 0x3823, 0x3824, 0x3824, 0x3824, 0x3824, 0x3825, 0x3825, 
+    0x3825, 0x3825, 0x3826, 0x3826, 0x3826, 0x3826, 0x3827, 0x3827, 
+    0x3827, 0x3827, 0x3828, 0x3828, 0x3828, 0x3828, 0x3829, 0x3829, 
+    0x3829, 0x3829, 0x382a, 0x382a, 0x382a, 0x382a, 0x382b, 0x382b, 
+    0x382b, 0x382b, 0x382c, 0x382c, 0x382c, 0x382c, 0x382d, 0x382d, 
+    0x382d, 0x382d, 0x382e, 0x382e, 0x382e, 0x382e, 0x382f, 0x382f, 
+    0x382f, 0x382f, 0x3830, 0x3830, 0x3830, 0x3830, 0x3831, 0x3831, 
+    0x3831, 0x3831, 0x3831, 0x3832, 0x3832, 0x3832, 0x3832, 0x3833, 
+    0x3833, 0x3833, 0x3833, 0x3834, 0x3834, 0x3834, 0x3834, 0x3835, 
+    0x3835, 0x3835, 0x3835, 0x3836, 0x3836, 0x3836, 0x3836, 0x3837, 
+    0x3837, 0x3837, 0x3837, 0x3838, 0x3838, 0x3838, 0x3838, 0x3839, 
+    0x3839, 0x3839, 0x3839, 0x383a, 0x383a, 0x383a, 0x383a, 0x383b, 
+    0x383b, 0x383b, 0x383b, 0x383c, 0x383c, 0x383c, 0x383c, 0x383d, 
+    0x383d, 0x383d, 0x383d, 0x383e, 0x383e, 0x383e, 0x383e, 0x383e, 
+    0x383f, 0x383f, 0x383f, 0x383f, 0x3840, 0x3840, 0x3840, 0x3840, 
+    0x3841, 0x3841, 0x3841, 0x3841, 0x3842, 0x3842, 0x3842, 0x3842, 
+    0x3843, 0x3843, 0x3844, 0x3844, 0x3845, 0x3845, 0x3846, 0x3846, 
+    0x3846, 0x3847, 0x3847, 0x3848, 0x3848, 0x3849, 0x3849, 0x384a, 
+    0x384a, 0x384b, 0x384b, 0x384c, 0x384c, 0x384d, 0x384d, 0x384e, 
+    0x384e, 0x384f, 0x384f, 0x3850, 0x3850, 0x3851, 0x3851, 0x3851, 
+    0x3852, 0x3852, 0x3853, 0x3853, 0x3854, 0x3854, 0x3855, 0x3855, 
+    0x3856, 0x3856, 0x3857, 0x3857, 0x3858, 0x3858, 0x3859, 0x3859, 
+    0x385a, 0x385a, 0x385a, 0x385b, 0x385b, 0x385c, 0x385c, 0x385d, 
+    0x385d, 0x385e, 0x385e, 0x385f, 0x385f, 0x3860, 0x3860, 0x3861, 
+    0x3861, 0x3862, 0x3862, 0x3862, 0x3863, 0x3863, 0x3864, 0x3864, 
+    0x3865, 0x3865, 0x3866, 0x3866, 0x3867, 0x3867, 0x3868, 0x3868, 
+    0x3869, 0x3869, 0x3869, 0x386a, 0x386a, 0x386b, 0x386b, 0x386c, 
+    0x386c, 0x386d, 0x386d, 0x386e, 0x386e, 0x386f, 0x386f, 0x386f, 
+    0x3870, 0x3870, 0x3871, 0x3871, 0x3872, 0x3872, 0x3873, 0x3873, 
+    0x3874, 0x3874, 0x3875, 0x3875, 0x3875, 0x3876, 0x3876, 0x3877, 
+    0x3877, 0x3878, 0x3878, 0x3879, 0x3879, 0x387a, 0x387a, 0x387a, 
+    0x387b, 0x387b, 0x387c, 0x387c, 0x387d, 0x387d, 0x387e, 0x387e, 
+    0x387f, 0x387f, 0x387f, 0x3880, 0x3880, 0x3881, 0x3881, 0x3882, 
+    0x3882, 0x3883, 0x3883, 0x3884, 0x3884, 0x3884, 0x3885, 0x3885, 
+    0x3886, 0x3886, 0x3887, 0x3887, 0x3888, 0x3888, 0x3889, 0x3889, 
+    0x3889, 0x388a, 0x388a, 0x388b, 0x388b, 0x388c, 0x388c, 0x388d, 
+    0x388d, 0x388d, 0x388e, 0x388e, 0x388f, 0x388f, 0x3890, 0x3890, 
+    0x3891, 0x3891, 0x3891, 0x3892, 0x3892, 0x3893, 0x3893, 0x3894, 
+    0x3894, 0x3895, 0x3895, 0x3895, 0x3896, 0x3896, 0x3897, 0x3897, 
+    0x3898, 0x3898, 0x3899, 0x3899, 0x3899, 0x389a, 0x389a, 0x389b, 
+    0x389b, 0x389c, 0x389c, 0x389d, 0x389d, 0x389d, 0x389e, 0x389e, 
+    0x389f, 0x389f, 0x38a0, 0x38a0, 0x38a0, 0x38a1, 0x38a1, 0x38a2, 
+    0x38a2, 0x38a3, 0x38a3, 0x38a4, 0x38a4, 0x38a4, 0x38a5, 0x38a5, 
+    0x38a6, 0x38a6, 0x38a7, 0x38a7, 0x38a7, 0x38a8, 0x38a8, 0x38a9, 
+    0x38a9, 0x38aa, 0x38aa, 0x38ab, 0x38ab, 0x38ab, 0x38ac, 0x38ac, 
+    0x38ad, 0x38ad, 0x38ae, 0x38ae, 0x38ae, 0x38af, 0x38af, 0x38b0, 
+    0x38b0, 0x38b1, 0x38b1, 0x38b1, 0x38b2, 0x38b2, 0x38b3, 0x38b3, 
+    0x38b4, 0x38b4, 0x38b4, 0x38b5, 0x38b5, 0x38b6, 0x38b6, 0x38b7, 
+    0x38b7, 0x38b7, 0x38b8, 0x38b8, 0x38b9, 0x38b9, 0x38ba, 0x38ba, 
+    0x38ba, 0x38bb, 0x38bb, 0x38bc, 0x38bc, 0x38bd, 0x38bd, 0x38bd, 
+    0x38be, 0x38be, 0x38bf, 0x38bf, 0x38c0, 0x38c0, 0x38c0, 0x38c1, 
+    0x38c1, 0x38c2, 0x38c2, 0x38c3, 0x38c3, 0x38c3, 0x38c4, 0x38c4, 
+    0x38c5, 0x38c5, 0x38c5, 0x38c6, 0x38c6, 0x38c7, 0x38c7, 0x38c8, 
+    0x38c8, 0x38c8, 0x38c9, 0x38c9, 0x38ca, 0x38ca, 0x38cb, 0x38cb, 
+    0x38cb, 0x38cc, 0x38cc, 0x38cd, 0x38cd, 0x38cd, 0x38ce, 0x38ce, 
+    0x38cf, 0x38cf, 0x38d0, 0x38d0, 0x38d0, 0x38d1, 0x38d1, 0x38d2, 
+    0x38d2, 0x38d3, 0x38d3, 0x38d3, 0x38d4, 0x38d4, 0x38d5, 0x38d5, 
+    0x38d5, 0x38d6, 0x38d6, 0x38d7, 0x38d7, 0x38d8, 0x38d8, 0x38d8, 
+    0x38d9, 0x38d9, 0x38da, 0x38da, 0x38da, 0x38db, 0x38db, 0x38dc, 
+    0x38dc, 0x38dc, 0x38dd, 0x38dd, 0x38de, 0x38de, 0x38df, 0x38df, 
+    0x38df, 0x38e0, 0x38e0, 0x38e1, 0x38e1, 0x38e1, 0x38e2, 0x38e2, 
+    0x38e3, 0x38e3, 0x38e3, 0x38e4, 0x38e4, 0x38e5, 0x38e5, 0x38e6, 
+    0x38e6, 0x38e6, 0x38e7, 0x38e7, 0x38e8, 0x38e8, 0x38e8, 0x38e9, 
+    0x38e9, 0x38ea, 0x38ea, 0x38ea, 0x38eb, 0x38eb, 0x38ec, 0x38ec, 
+    0x38ec, 0x38ed, 0x38ed, 0x38ee, 0x38ee, 0x38ee, 0x38ef, 0x38ef, 
+    0x38f0, 0x38f0, 0x38f1, 0x38f1, 0x38f1, 0x38f2, 0x38f2, 0x38f3, 
+    0x38f3, 0x38f3, 0x38f4, 0x38f4, 0x38f5, 0x38f5, 0x38f5, 0x38f6, 
+    0x38f6, 0x38f7, 0x38f7, 0x38f7, 0x38f8, 0x38f8, 0x38f9, 0x38f9, 
+    0x38f9, 0x38fa, 0x38fa, 0x38fb, 0x38fb, 0x38fb, 0x38fc, 0x38fc, 
+    0x38fd, 0x38fd, 0x38fd, 0x38fe, 0x38fe, 0x38ff, 0x38ff, 0x38ff, 
+    0x3900, 0x3900, 0x3901, 0x3901, 0x3901, 0x3902, 0x3902, 0x3903, 
+    0x3903, 0x3903, 0x3904, 0x3904, 0x3905, 0x3905, 0x3905, 0x3906, 
+    0x3906, 0x3907, 0x3907, 0x3907, 0x3908, 0x3908, 0x3909, 0x3909, 
+    0x3909, 0x390a, 0x390a, 0x390b, 0x390b, 0x390b, 0x390c, 0x390c, 
+    0x390d, 0x390d, 0x390d, 0x390e, 0x390e, 0x390f, 0x390f, 0x390f, 
+    0x3910, 0x3910, 0x3910, 0x3911, 0x3911, 0x3912, 0x3912, 0x3912, 
+    0x3913, 0x3913, 0x3914, 0x3914, 0x3914, 0x3915, 0x3915, 0x3916, 
+    0x3916, 0x3916, 0x3917, 0x3917, 0x3918, 0x3918, 0x3918, 0x3919, 
+    0x3919, 0x3919, 0x391a, 0x391a, 0x391b, 0x391b, 0x391b, 0x391c, 
+    0x391c, 0x391d, 0x391d, 0x391d, 0x391e, 0x391e, 0x391f, 0x391f, 
+    0x391f, 0x3920, 0x3920, 0x3920, 0x3921, 0x3921, 0x3922, 0x3922, 
+    0x3922, 0x3923, 0x3923, 0x3924, 0x3924, 0x3924, 0x3925, 0x3925, 
+    0x3926, 0x3926, 0x3926, 0x3927, 0x3927, 0x3927, 0x3928, 0x3928, 
+    0x3929, 0x3929, 0x3929, 0x392a, 0x392a, 0x392b, 0x392b, 0x392b, 
+    0x392c, 0x392c, 0x392c, 0x392d, 0x392d, 0x392e, 0x392e, 0x392e, 
+    0x392f, 0x392f, 0x392f, 0x3930, 0x3930, 0x3931, 0x3931, 0x3931, 
+    0x3932, 0x3932, 0x3933, 0x3933, 0x3933, 0x3934, 0x3934, 0x3934, 
+    0x3935, 0x3935, 0x3936, 0x3936, 0x3936, 0x3937, 0x3937, 0x3937, 
+    0x3938, 0x3938, 0x3939, 0x3939, 0x3939, 0x393a, 0x393a, 0x393b, 
+    0x393b, 0x393b, 0x393c, 0x393c, 0x393c, 0x393d, 0x393d, 0x393e, 
+    0x393e, 0x393e, 0x393f, 0x393f, 0x393f, 0x3940, 0x3940, 0x3941, 
+    0x3941, 0x3941, 0x3942, 0x3942, 0x3942, 0x3943, 0x3943, 0x3944, 
+    0x3944, 0x3944, 0x3945, 0x3945, 0x3945, 0x3946, 0x3946, 0x3947, 
+    0x3947, 0x3947, 0x3948, 0x3948, 0x3948, 0x3949, 0x3949, 0x394a, 
+    0x394a, 0x394a, 0x394b, 0x394b, 0x394b, 0x394c, 0x394c, 0x394d, 
+    0x394d, 0x394d, 0x394e, 0x394e, 0x394e, 0x394f, 0x394f, 0x3950, 
+    0x3950, 0x3950, 0x3951, 0x3951, 0x3951, 0x3952, 0x3952, 0x3953, 
+    0x3953, 0x3953, 0x3954, 0x3954, 0x3954, 0x3955, 0x3955, 0x3955, 
+    0x3956, 0x3956, 0x3957, 0x3957, 0x3957, 0x3958, 0x3958, 0x3958, 
+    0x3959, 0x3959, 0x395a, 0x395a, 0x395a, 0x395b, 0x395b, 0x395b, 
+    0x395c, 0x395c, 0x395c, 0x395d, 0x395d, 0x395e, 0x395e, 0x395e, 
+    0x395f, 0x395f, 0x395f, 0x3960, 0x3960, 0x3961, 0x3961, 0x3961, 
+    0x3962, 0x3962, 0x3962, 0x3963, 0x3963, 0x3963, 0x3964, 0x3964, 
+    0x3965, 0x3965, 0x3965, 0x3966, 0x3966, 0x3966, 0x3967, 0x3967, 
+    0x3967, 0x3968, 0x3968, 0x3969, 0x3969, 0x3969, 0x396a, 0x396a, 
+    0x396a, 0x396b, 0x396b, 0x396b, 0x396c, 0x396c, 0x396d, 0x396d, 
+    0x396d, 0x396e, 0x396e, 0x396e, 0x396f, 0x396f, 0x396f, 0x3970, 
+    0x3970, 0x3970, 0x3971, 0x3971, 0x3972, 0x3972, 0x3972, 0x3973, 
+    0x3973, 0x3973, 0x3974, 0x3974, 0x3974, 0x3975, 0x3975, 0x3976, 
+    0x3976, 0x3976, 0x3977, 0x3977, 0x3977, 0x3978, 0x3978, 0x3978, 
+    0x3979, 0x3979, 0x3979, 0x397a, 0x397a, 0x397b, 0x397b, 0x397b, 
+    0x397c, 0x397c, 0x397c, 0x397d, 0x397d, 0x397d, 0x397e, 0x397e, 
+    0x397e, 0x397f, 0x397f, 0x3980, 0x3980, 0x3980, 0x3981, 0x3981, 
+    0x3981, 0x3982, 0x3982, 0x3982, 0x3983, 0x3983, 0x3983, 0x3984, 
+    0x3984, 0x3985, 0x3985, 0x3985, 0x3986, 0x3986, 0x3986, 0x3987, 
+    0x3987, 0x3987, 0x3988, 0x3988, 0x3988, 0x3989, 0x3989, 0x398a, 
+    0x398a, 0x398a, 0x398b, 0x398b, 0x398b, 0x398c, 0x398c, 0x398c, 
+    0x398d, 0x398d, 0x398d, 0x398e, 0x398e, 0x398e, 0x398f, 0x398f, 
+    0x398f, 0x3990, 0x3990, 0x3991, 0x3991, 0x3991, 0x3992, 0x3992, 
+    0x3992, 0x3993, 0x3993, 0x3993, 0x3994, 0x3994, 0x3994, 0x3995, 
+    0x3995, 0x3995, 0x3996, 0x3996, 0x3997, 0x3997, 0x3997, 0x3998, 
+    0x3998, 0x3998, 0x3999, 0x3999, 0x3999, 0x399a, 0x399a, 0x399a, 
+    0x399b, 0x399b, 0x399b, 0x399c, 0x399c, 0x399c, 0x399d, 0x399d, 
+    0x399d, 0x399e, 0x399e, 0x399f, 0x399f, 0x399f, 0x39a0, 0x39a0, 
+    0x39a0, 0x39a1, 0x39a1, 0x39a1, 0x39a2, 0x39a2, 0x39a2, 0x39a3, 
+    0x39a3, 0x39a3, 0x39a4, 0x39a4, 0x39a4, 0x39a5, 0x39a5, 0x39a5, 
+    0x39a6, 0x39a6, 0x39a6, 0x39a7, 0x39a7, 0x39a8, 0x39a8, 0x39a8, 
+    0x39a9, 0x39a9, 0x39a9, 0x39aa, 0x39aa, 0x39aa, 0x39ab, 0x39ab, 
+    0x39ab, 0x39ac, 0x39ac, 0x39ac, 0x39ad, 0x39ad, 0x39ad, 0x39ae, 
+    0x39ae, 0x39ae, 0x39af, 0x39af, 0x39af, 0x39b0, 0x39b0, 0x39b0, 
+    0x39b1, 0x39b1, 0x39b1, 0x39b2, 0x39b2, 0x39b2, 0x39b3, 0x39b3, 
+    0x39b4, 0x39b4, 0x39b4, 0x39b5, 0x39b5, 0x39b5, 0x39b6, 0x39b6, 
+    0x39b6, 0x39b7, 0x39b7, 0x39b7, 0x39b8, 0x39b8, 0x39b8, 0x39b9, 
+    0x39b9, 0x39b9, 0x39ba, 0x39ba, 0x39ba, 0x39bb, 0x39bb, 0x39bb, 
+    0x39bc, 0x39bc, 0x39bc, 0x39bd, 0x39bd, 0x39bd, 0x39be, 0x39be, 
+    0x39be, 0x39bf, 0x39bf, 0x39bf, 0x39c0, 0x39c0, 0x39c0, 0x39c1, 
+    0x39c1, 0x39c1, 0x39c2, 0x39c2, 0x39c2, 0x39c3, 0x39c3, 0x39c3, 
+    0x39c4, 0x39c4, 0x39c4, 0x39c5, 0x39c5, 0x39c5, 0x39c6, 0x39c6, 
+    0x39c6, 0x39c7, 0x39c7, 0x39c7, 0x39c8, 0x39c8, 0x39c8, 0x39c9, 
+    0x39c9, 0x39ca, 0x39ca, 0x39ca, 0x39cb, 0x39cb, 0x39cb, 0x39cc, 
+    0x39cc, 0x39cc, 0x39cd, 0x39cd, 0x39cd, 0x39ce, 0x39ce, 0x39ce, 
+    0x39cf, 0x39cf, 0x39cf, 0x39d0, 0x39d0, 0x39d0, 0x39d1, 0x39d1, 
+    0x39d1, 0x39d2, 0x39d2, 0x39d2, 0x39d3, 0x39d3, 0x39d3, 0x39d4, 
+    0x39d4, 0x39d4, 0x39d5, 0x39d5, 0x39d5, 0x39d6, 0x39d6, 0x39d6, 
+    0x39d7, 0x39d7, 0x39d8, 0x39d8, 0x39d9, 0x39da, 0x39da, 0x39db, 
+    0x39dc, 0x39dc, 0x39dd, 0x39de, 0x39de, 0x39df, 0x39e0, 0x39e0, 
+    0x39e1, 0x39e2, 0x39e2, 0x39e3, 0x39e4, 0x39e4, 0x39e5, 0x39e6, 
+    0x39e6, 0x39e7, 0x39e8, 0x39e8, 0x39e9, 0x39ea, 0x39ea, 0x39eb, 
+    0x39ec, 0x39ec, 0x39ed, 0x39ee, 0x39ee, 0x39ef, 0x39ef, 0x39f0, 
+    0x39f1, 0x39f1, 0x39f2, 0x39f3, 0x39f3, 0x39f4, 0x39f5, 0x39f5, 
+    0x39f6, 0x39f7, 0x39f7, 0x39f8, 0x39f9, 0x39f9, 0x39fa, 0x39fa, 
+    0x39fb, 0x39fc, 0x39fc, 0x39fd, 0x39fe, 0x39fe, 0x39ff, 0x3a00, 
+    0x3a00, 0x3a01, 0x3a02, 0x3a02, 0x3a03, 0x3a03, 0x3a04, 0x3a05, 
+    0x3a05, 0x3a06, 0x3a07, 0x3a07, 0x3a08, 0x3a09, 0x3a09, 0x3a0a, 
+    0x3a0a, 0x3a0b, 0x3a0c, 0x3a0c, 0x3a0d, 0x3a0e, 0x3a0e, 0x3a0f, 
+    0x3a10, 0x3a10, 0x3a11, 0x3a11, 0x3a12, 0x3a13, 0x3a13, 0x3a14, 
+    0x3a15, 0x3a15, 0x3a16, 0x3a17, 0x3a17, 0x3a18, 0x3a18, 0x3a19, 
+    0x3a1a, 0x3a1a, 0x3a1b, 0x3a1c, 0x3a1c, 0x3a1d, 0x3a1d, 0x3a1e, 
+    0x3a1f, 0x3a1f, 0x3a20, 0x3a21, 0x3a21, 0x3a22, 0x3a22, 0x3a23, 
+    0x3a24, 0x3a24, 0x3a25, 0x3a26, 0x3a26, 0x3a27, 0x3a27, 0x3a28, 
+    0x3a29, 0x3a29, 0x3a2a, 0x3a2b, 0x3a2b, 0x3a2c, 0x3a2c, 0x3a2d, 
+    0x3a2e, 0x3a2e, 0x3a2f, 0x3a30, 0x3a30, 0x3a31, 0x3a31, 0x3a32, 
+    0x3a33, 0x3a33, 0x3a34, 0x3a34, 0x3a35, 0x3a36, 0x3a36, 0x3a37, 
+    0x3a38, 0x3a38, 0x3a39, 0x3a39, 0x3a3a, 0x3a3b, 0x3a3b, 0x3a3c, 
+    0x3a3c, 0x3a3d, 0x3a3e, 0x3a3e, 0x3a3f, 0x3a40, 0x3a40, 0x3a41, 
+    0x3a41, 0x3a42, 0x3a43, 0x3a43, 0x3a44, 0x3a44, 0x3a45, 0x3a46, 
+    0x3a46, 0x3a47, 0x3a47, 0x3a48, 0x3a49, 0x3a49, 0x3a4a, 0x3a4a, 
+    0x3a4b, 0x3a4c, 0x3a4c, 0x3a4d, 0x3a4e, 0x3a4e, 0x3a4f, 0x3a4f, 
+    0x3a50, 0x3a51, 0x3a51, 0x3a52, 0x3a52, 0x3a53, 0x3a54, 0x3a54, 
+    0x3a55, 0x3a55, 0x3a56, 0x3a57, 0x3a57, 0x3a58, 0x3a58, 0x3a59, 
+    0x3a5a, 0x3a5a, 0x3a5b, 0x3a5b, 0x3a5c, 0x3a5d, 0x3a5d, 0x3a5e, 
+    0x3a5e, 0x3a5f, 0x3a60, 0x3a60, 0x3a61, 0x3a61, 0x3a62, 0x3a63, 
+    0x3a63, 0x3a64, 0x3a64, 0x3a65, 0x3a66, 0x3a66, 0x3a67, 0x3a67, 
+    0x3a68, 0x3a68, 0x3a69, 0x3a6a, 0x3a6a, 0x3a6b, 0x3a6b, 0x3a6c, 
+    0x3a6d, 0x3a6d, 0x3a6e, 0x3a6e, 0x3a6f, 0x3a70, 0x3a70, 0x3a71, 
+    0x3a71, 0x3a72, 0x3a73, 0x3a73, 0x3a74, 0x3a74, 0x3a75, 0x3a75, 
+    0x3a76, 0x3a77, 0x3a77, 0x3a78, 0x3a78, 0x3a79, 0x3a7a, 0x3a7a, 
+    0x3a7b, 0x3a7b, 0x3a7c, 0x3a7c, 0x3a7d, 0x3a7e, 0x3a7e, 0x3a7f, 
+    0x3a7f, 0x3a80, 0x3a81, 0x3a81, 0x3a82, 0x3a82, 0x3a83, 0x3a83, 
+    0x3a84, 0x3a85, 0x3a85, 0x3a86, 0x3a86, 0x3a87, 0x3a88, 0x3a88, 
+    0x3a89, 0x3a89, 0x3a8a, 0x3a8a, 0x3a8b, 0x3a8c, 0x3a8c, 0x3a8d, 
+    0x3a8d, 0x3a8e, 0x3a8f, 0x3a8f, 0x3a90, 0x3a90, 0x3a91, 0x3a91, 
+    0x3a92, 0x3a93, 0x3a93, 0x3a94, 0x3a94, 0x3a95, 0x3a95, 0x3a96, 
+    0x3a97, 0x3a97, 0x3a98, 0x3a98, 0x3a99, 0x3a99, 0x3a9a, 0x3a9b, 
+    0x3a9b, 0x3a9c, 0x3a9c, 0x3a9d, 0x3a9d, 0x3a9e, 0x3a9f, 0x3a9f, 
+    0x3aa0, 0x3aa0, 0x3aa1, 0x3aa1, 0x3aa2, 0x3aa3, 0x3aa3, 0x3aa4, 
+    0x3aa4, 0x3aa5, 0x3aa5, 0x3aa6, 0x3aa7, 0x3aa7, 0x3aa8, 0x3aa8, 
+    0x3aa9, 0x3aa9, 0x3aaa, 0x3aaa, 0x3aab, 0x3aac, 0x3aac, 0x3aad, 
+    0x3aad, 0x3aae, 0x3aae, 0x3aaf, 0x3ab0, 0x3ab0, 0x3ab1, 0x3ab1, 
+    0x3ab2, 0x3ab2, 0x3ab3, 0x3ab4, 0x3ab4, 0x3ab5, 0x3ab5, 0x3ab6, 
+    0x3ab6, 0x3ab7, 0x3ab7, 0x3ab8, 0x3ab9, 0x3ab9, 0x3aba, 0x3aba, 
+    0x3abb, 0x3abb, 0x3abc, 0x3abc, 0x3abd, 0x3abe, 0x3abe, 0x3abf, 
+    0x3abf, 0x3ac0, 0x3ac0, 0x3ac1, 0x3ac2, 0x3ac2, 0x3ac3, 0x3ac3, 
+    0x3ac4, 0x3ac4, 0x3ac5, 0x3ac5, 0x3ac6, 0x3ac7, 0x3ac7, 0x3ac8, 
+    0x3ac8, 0x3ac9, 0x3ac9, 0x3aca, 0x3aca, 0x3acb, 0x3acb, 0x3acc, 
+    0x3acd, 0x3acd, 0x3ace, 0x3ace, 0x3acf, 0x3acf, 0x3ad0, 0x3ad0, 
+    0x3ad1, 0x3ad2, 0x3ad2, 0x3ad3, 0x3ad3, 0x3ad4, 0x3ad4, 0x3ad5, 
+    0x3ad5, 0x3ad6, 0x3ad7, 0x3ad7, 0x3ad8, 0x3ad8, 0x3ad9, 0x3ad9, 
+    0x3ada, 0x3ada, 0x3adb, 0x3adb, 0x3adc, 0x3add, 0x3add, 0x3ade, 
+    0x3ade, 0x3adf, 0x3adf, 0x3ae0, 0x3ae0, 0x3ae1, 0x3ae1, 0x3ae2, 
+    0x3ae3, 0x3ae3, 0x3ae4, 0x3ae4, 0x3ae5, 0x3ae5, 0x3ae6, 0x3ae6, 
+    0x3ae7, 0x3ae7, 0x3ae8, 0x3ae9, 0x3ae9, 0x3aea, 0x3aea, 0x3aeb, 
+    0x3aeb, 0x3aec, 0x3aec, 0x3aed, 0x3aed, 0x3aee, 0x3aee, 0x3aef, 
+    0x3af0, 0x3af0, 0x3af1, 0x3af1, 0x3af2, 0x3af2, 0x3af3, 0x3af3, 
+    0x3af4, 0x3af4, 0x3af5, 0x3af5, 0x3af6, 0x3af7, 0x3af7, 0x3af8, 
+    0x3af8, 0x3af9, 0x3af9, 0x3afa, 0x3afa, 0x3afb, 0x3afb, 0x3afc, 
+    0x3afc, 0x3afd, 0x3afe, 0x3afe, 0x3aff, 0x3aff, 0x3b00, 0x3b00, 
+    0x3b01, 0x3b01, 0x3b02, 0x3b02, 0x3b03, 0x3b03, 0x3b04, 0x3b04, 
+    0x3b05, 0x3b05, 0x3b06, 0x3b07, 0x3b07, 0x3b08, 0x3b08, 0x3b09, 
+    0x3b09, 0x3b0a, 0x3b0a, 0x3b0b, 0x3b0b, 0x3b0c, 0x3b0c, 0x3b0d, 
+    0x3b0d, 0x3b0e, 0x3b0f, 0x3b0f, 0x3b10, 0x3b10, 0x3b11, 0x3b11, 
+    0x3b12, 0x3b12, 0x3b13, 0x3b13, 0x3b14, 0x3b14, 0x3b15, 0x3b15, 
+    0x3b16, 0x3b16, 0x3b17, 0x3b17, 0x3b18, 0x3b19, 0x3b19, 0x3b1a, 
+    0x3b1a, 0x3b1b, 0x3b1b, 0x3b1c, 0x3b1c, 0x3b1d, 0x3b1d, 0x3b1e, 
+    0x3b1e, 0x3b1f, 0x3b1f, 0x3b20, 0x3b20, 0x3b21, 0x3b21, 0x3b22, 
+    0x3b22, 0x3b23, 0x3b23, 0x3b24, 0x3b25, 0x3b25, 0x3b26, 0x3b26, 
+    0x3b27, 0x3b27, 0x3b28, 0x3b28, 0x3b29, 0x3b29, 0x3b2a, 0x3b2a, 
+    0x3b2b, 0x3b2b, 0x3b2c, 0x3b2c, 0x3b2d, 0x3b2d, 0x3b2e, 0x3b2e, 
+    0x3b2f, 0x3b2f, 0x3b30, 0x3b30, 0x3b31, 0x3b32, 0x3b32, 0x3b33, 
+    0x3b33, 0x3b34, 0x3b34, 0x3b35, 0x3b35, 0x3b36, 0x3b36, 0x3b37, 
+    0x3b37, 0x3b38, 0x3b38, 0x3b39, 0x3b39, 0x3b3a, 0x3b3a, 0x3b3b, 
+    0x3b3b, 0x3b3c, 0x3b3c, 0x3b3d, 0x3b3d, 0x3b3e, 0x3b3e, 0x3b3f, 
+    0x3b3f, 0x3b40, 0x3b40, 0x3b41, 0x3b41, 0x3b42, 0x3b42, 0x3b43, 
+    0x3b43, 0x3b44, 0x3b44, 0x3b45, 0x3b46, 0x3b46, 0x3b47, 0x3b47, 
+    0x3b48, 0x3b48, 0x3b49, 0x3b49, 0x3b4a, 0x3b4a, 0x3b4b, 0x3b4b, 
+    0x3b4c, 0x3b4c, 0x3b4d, 0x3b4d, 0x3b4e, 0x3b4e, 0x3b4f, 0x3b4f, 
+    0x3b50, 0x3b50, 0x3b51, 0x3b51, 0x3b52, 0x3b52, 0x3b53, 0x3b53, 
+    0x3b54, 0x3b54, 0x3b55, 0x3b55, 0x3b56, 0x3b56, 0x3b57, 0x3b57, 
+    0x3b58, 0x3b58, 0x3b59, 0x3b59, 0x3b5a, 0x3b5a, 0x3b5b, 0x3b5b, 
+    0x3b5c, 0x3b5c, 0x3b5d, 0x3b5d, 0x3b5e, 0x3b5e, 0x3b5f, 0x3b5f, 
+    0x3b60, 0x3b60, 0x3b61, 0x3b61, 0x3b62, 0x3b62, 0x3b63, 0x3b63, 
+    0x3b64, 0x3b64, 0x3b65, 0x3b65, 0x3b66, 0x3b66, 0x3b67, 0x3b67, 
+    0x3b68, 0x3b68, 0x3b69, 0x3b69, 0x3b6a, 0x3b6a, 0x3b6b, 0x3b6b, 
+    0x3b6c, 0x3b6c, 0x3b6d, 0x3b6d, 0x3b6e, 0x3b6e, 0x3b6f, 0x3b6f, 
+    0x3b70, 0x3b70, 0x3b71, 0x3b71, 0x3b72, 0x3b72, 0x3b73, 0x3b73, 
+    0x3b74, 0x3b74, 0x3b75, 0x3b75, 0x3b76, 0x3b76, 0x3b77, 0x3b77, 
+    0x3b78, 0x3b78, 0x3b79, 0x3b79, 0x3b7a, 0x3b7a, 0x3b7b, 0x3b7b, 
+    0x3b7c, 0x3b7c, 0x3b7d, 0x3b7d, 0x3b7e, 0x3b7e, 0x3b7f, 0x3b7f, 
+    0x3b80, 0x3b80, 0x3b81, 0x3b81, 0x3b82, 0x3b82, 0x3b82, 0x3b83, 
+    0x3b83, 0x3b84, 0x3b84, 0x3b85, 0x3b85, 0x3b86, 0x3b86, 0x3b87, 
+    0x3b87, 0x3b88, 0x3b88, 0x3b89, 0x3b89, 0x3b8a, 0x3b8a, 0x3b8b, 
+    0x3b8b, 0x3b8c, 0x3b8c, 0x3b8d, 0x3b8d, 0x3b8e, 0x3b8e, 0x3b8f, 
+    0x3b8f, 0x3b90, 0x3b90, 0x3b91, 0x3b91, 0x3b92, 0x3b92, 0x3b93, 
+    0x3b93, 0x3b94, 0x3b94, 0x3b95, 0x3b95, 0x3b96, 0x3b96, 0x3b96, 
+    0x3b97, 0x3b97, 0x3b98, 0x3b98, 0x3b99, 0x3b99, 0x3b9a, 0x3b9a, 
+    0x3b9b, 0x3b9b, 0x3b9c, 0x3b9c, 0x3b9d, 0x3b9d, 0x3b9e, 0x3b9e, 
+    0x3b9f, 0x3b9f, 0x3ba0, 0x3ba0, 0x3ba1, 0x3ba1, 0x3ba2, 0x3ba2, 
+    0x3ba3, 0x3ba3, 0x3ba4, 0x3ba4, 0x3ba4, 0x3ba5, 0x3ba5, 0x3ba6, 
+    0x3ba6, 0x3ba7, 0x3ba7, 0x3ba8, 0x3ba8, 0x3ba9, 0x3ba9, 0x3baa, 
+    0x3baa, 0x3bab, 0x3bab, 0x3bac, 0x3bac, 0x3bad, 0x3bad, 0x3bae, 
+    0x3bae, 0x3baf, 0x3baf, 0x3baf, 0x3bb0, 0x3bb0, 0x3bb1, 0x3bb1, 
+    0x3bb2, 0x3bb2, 0x3bb3, 0x3bb3, 0x3bb4, 0x3bb4, 0x3bb5, 0x3bb5, 
+    0x3bb6, 0x3bb6, 0x3bb7, 0x3bb7, 0x3bb8, 0x3bb8, 0x3bb9, 0x3bb9, 
+    0x3bb9, 0x3bba, 0x3bba, 0x3bbb, 0x3bbb, 0x3bbc, 0x3bbc, 0x3bbd, 
+    0x3bbd, 0x3bbe, 0x3bbe, 0x3bbf, 0x3bbf, 0x3bc0, 0x3bc0, 0x3bc1, 
+    0x3bc1, 0x3bc1, 0x3bc2, 0x3bc2, 0x3bc3, 0x3bc3, 0x3bc4, 0x3bc4, 
+    0x3bc5, 0x3bc5, 0x3bc6, 0x3bc6, 0x3bc7, 0x3bc7, 0x3bc8, 0x3bc8, 
+    0x3bc9, 0x3bc9, 0x3bc9, 0x3bca, 0x3bca, 0x3bcb, 0x3bcb, 0x3bcc, 
+    0x3bcc, 0x3bcd, 0x3bcd, 0x3bce, 0x3bce, 0x3bcf, 0x3bcf, 0x3bd0, 
+    0x3bd0, 0x3bd1, 0x3bd1, 0x3bd1, 0x3bd2, 0x3bd2, 0x3bd3, 0x3bd3, 
+    0x3bd4, 0x3bd4, 0x3bd5, 0x3bd5, 0x3bd6, 0x3bd6, 0x3bd7, 0x3bd7, 
+    0x3bd8, 0x3bd8, 0x3bd8, 0x3bd9, 0x3bd9, 0x3bda, 0x3bda, 0x3bdb, 
+    0x3bdb, 0x3bdc, 0x3bdc, 0x3bdd, 0x3bdd, 0x3bde, 0x3bde, 0x3bde, 
+    0x3bdf, 0x3bdf, 0x3be0, 0x3be0, 0x3be1, 0x3be1, 0x3be2, 0x3be2, 
+    0x3be3, 0x3be3, 0x3be4, 0x3be4, 0x3be5, 0x3be5, 0x3be5, 0x3be6, 
+    0x3be6, 0x3be7, 0x3be7, 0x3be8, 0x3be8, 0x3be9, 0x3be9, 0x3bea, 
+    0x3bea, 0x3beb, 0x3beb, 0x3beb, 0x3bec, 0x3bec, 0x3bed, 0x3bed, 
+    0x3bee, 0x3bee, 0x3bef, 0x3bef, 0x3bf0, 0x3bf0, 0x3bf0, 0x3bf1, 
+    0x3bf1, 0x3bf2, 0x3bf2, 0x3bf3, 0x3bf3, 0x3bf4, 0x3bf4, 0x3bf5, 
+    0x3bf5, 0x3bf6, 0x3bf6, 0x3bf6, 0x3bf7, 0x3bf7, 0x3bf8, 0x3bf8, 
+    0x3bf9, 0x3bf9, 0x3bfa, 0x3bfa, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfc, 
+    0x3bfc, 0x3bfd, 0x3bfd, 0x3bfe, 0x3bfe, 0x3bff, 0x3bff, 0x3c00, 
+    0x3c00, 0x3c00, 0x3c01, 0x3c01, 0x3c02, 0x3c02, 0x3c03, 0x3c03, 
+    0x3c04, 0x3c04, 0x3c05, 0x3c05, 0x3c05, 0x3c06, 0x3c06, 0x3c07, 
+    0x3c07, 0x3c08, 0x3c08, 0x3c09, 0x3c09, 0x3c09, 0x3c0a, 0x3c0a, 
+    0x3c0b, 0x3c0b, 0x3c0c, 0x3c0c, 0x3c0d, 0x3c0d, 0x3c0d, 0x3c0e, 
+    0x3c0e, 0x3c0f, 0x3c0f, 0x3c10, 0x3c10, 0x3c11, 0x3c11, 0x3c11, 
+    0x3c12, 0x3c12, 0x3c13, 0x3c13, 0x3c14, 0x3c14, 0x3c14, 0x3c15, 
+    0x3c15, 0x3c16, 0x3c16, 0x3c17, 0x3c17, 0x3c17, 0x3c18, 0x3c18, 
+    0x3c19, 0x3c19, 0x3c1a, 0x3c1a, 0x3c1b, 0x3c1b, 0x3c1b, 0x3c1c, 
+    0x3c1c, 0x3c1d, 0x3c1d, 0x3c1d, 0x3c1e, 0x3c1e, 0x3c1f, 0x3c1f, 
+    0x3c20, 0x3c20, 0x3c20, 0x3c21, 0x3c21, 0x3c22, 0x3c22, 0x3c23, 
+    0x3c23, 0x3c23, 0x3c24, 0x3c24, 0x3c25, 0x3c25, 0x3c26, 0x3c26, 
+    0x3c26, 0x3c27, 0x3c27, 0x3c28, 0x3c28, 0x3c28, 0x3c29, 0x3c29, 
+    0x3c2a, 0x3c2a, 0x3c2b, 0x3c2b, 0x3c2b, 0x3c2c, 0x3c2c, 0x3c2d, 
+    0x3c2d, 0x3c2d, 0x3c2e, 0x3c2e, 0x3c2f, 0x3c2f, 0x3c2f, 0x3c30, 
+    0x3c30, 0x3c31, 0x3c31, 0x3c32, 0x3c32, 0x3c32, 0x3c33, 0x3c33, 
+    0x3c34, 0x3c34, 0x3c34, 0x3c35, 0x3c35, 0x3c36, 0x3c36, 0x3c36, 
+    0x3c37, 0x3c37, 0x3c38, 0x3c38, 0x3c38, 0x3c39, 0x3c39, 0x3c3a, 
+    0x3c3a, 0x3c3a, 0x3c3b, 0x3c3b, 0x3c3c, 0x3c3c, 0x3c3c, 0x3c3d, 
+    0x3c3d, 0x3c3e, 0x3c3e, 0x3c3e, 0x3c3f, 0x3c3f, 0x3c40, 0x3c40, 
+    0x3c40, 0x3c41, 0x3c41, 0x3c42, 0x3c42, 0x3c42, 0x3c43, 0x3c43, 
+    0x3c44, 0x3c44, 0x3c44, 0x3c45, 0x3c45, 0x3c46, 0x3c46, 0x3c46, 
+    0x3c47, 0x3c47, 0x3c47, 0x3c48, 0x3c48, 0x3c49, 0x3c49, 0x3c49, 
+    0x3c4a, 0x3c4a, 0x3c4b, 0x3c4b, 0x3c4b, 0x3c4c, 0x3c4c, 0x3c4d, 
+    0x3c4d, 0x3c4d, 0x3c4e, 0x3c4e, 0x3c4e, 0x3c4f, 0x3c4f, 0x3c50, 
+    0x3c50, 0x3c50, 0x3c51, 0x3c51, 0x3c52, 0x3c52, 0x3c52, 0x3c53, 
+    0x3c53, 0x3c53, 0x3c54, 0x3c54, 0x3c55, 0x3c55, 0x3c55, 0x3c56, 
+    0x3c56, 0x3c56, 0x3c57, 0x3c57, 0x3c58, 0x3c58, 0x3c58, 0x3c59, 
+    0x3c59, 0x3c59, 0x3c5a, 0x3c5a, 0x3c5b, 0x3c5b, 0x3c5b, 0x3c5c, 
+    0x3c5c, 0x3c5c, 0x3c5d, 0x3c5d, 0x3c5e, 0x3c5e, 0x3c5e, 0x3c5f, 
+    0x3c5f, 0x3c5f, 0x3c60, 0x3c60, 0x3c61, 0x3c61, 0x3c61, 0x3c62, 
+    0x3c62, 0x3c62, 0x3c63, 0x3c63, 0x3c63, 0x3c64, 0x3c64, 0x3c65, 
+    0x3c65, 0x3c65, 0x3c66, 0x3c66, 0x3c66, 0x3c67, 0x3c67, 0x3c67, 
+    0x3c68, 0x3c68, 0x3c69, 0x3c69, 0x3c69, 0x3c6a, 0x3c6a, 0x3c6a, 
+    0x3c6b, 0x3c6b, 0x3c6b, 0x3c6c, 0x3c6c, 0x3c6d, 0x3c6d, 0x3c6d, 
+    0x3c6e, 0x3c6e, 0x3c6e, 0x3c6f, 0x3c6f, 0x3c6f, 0x3c70, 0x3c70, 
+    0x3c71, 0x3c71, 0x3c71, 0x3c72, 0x3c72, 0x3c72, 0x3c73, 0x3c73, 
+    0x3c73, 0x3c74, 0x3c74, 0x3c74, 0x3c75, 0x3c75, 0x3c75, 0x3c76, 
+    0x3c76, 0x3c77, 0x3c77, 0x3c77, 0x3c78, 0x3c78, 0x3c78, 0x3c79, 
+    0x3c79, 0x3c79, 0x3c7a, 0x3c7a, 0x3c7a, 0x3c7b, 0x3c7b, 0x3c7b, 
+    0x3c7c, 0x3c7c, 0x3c7c, 0x3c7d, 0x3c7d, 0x3c7e, 0x3c7e, 0x3c7e, 
+    0x3c7f, 0x3c7f, 0x3c7f, 0x3c80, 0x3c80, 0x3c80, 0x3c81, 0x3c81, 
+    0x3c81, 0x3c82, 0x3c82, 0x3c82, 0x3c83, 0x3c83, 0x3c83, 0x3c84, 
+    0x3c84, 0x3c84, 0x3c85, 0x3c85, 0x3c85, 0x3c86, 0x3c86, 0x3c86, 
+    0x3c87, 0x3c87, 0x3c87, 0x3c88, 0x3c88, 0x3c89, 0x3c89, 0x3c89, 
+    0x3c8a, 0x3c8a, 0x3c8a, 0x3c8b, 0x3c8b, 0x3c8b, 0x3c8c, 0x3c8c, 
+    0x3c8c, 0x3c8d, 0x3c8d, 0x3c8d, 0x3c8e, 0x3c8e, 0x3c8e, 0x3c8f, 
+    0x3c8f, 0x3c8f, 0x3c90, 0x3c90, 0x3c90, 0x3c91, 0x3c91, 0x3c91, 
+    0x3c92, 0x3c92, 0x3c92, 0x3c93, 0x3c93, 0x3c93, 0x3c94, 0x3c94, 
+    0x3c94, 0x3c95, 0x3c95, 0x3c95, 0x3c96, 0x3c96, 0x3c96, 0x3c97, 
+    0x3c97, 0x3c97, 0x3c98, 0x3c98, 0x3c98, 0x3c99, 0x3c99, 0x3c99, 
+    0x3c99, 0x3c9a, 0x3c9a, 0x3c9a, 0x3c9b, 0x3c9b, 0x3c9b, 0x3c9c, 
+    0x3c9c, 0x3c9c, 0x3c9d, 0x3c9d, 0x3c9d, 0x3c9e, 0x3c9e, 0x3c9e, 
+    0x3c9f, 0x3c9f, 0x3c9f, 0x3ca0, 0x3ca0, 0x3ca0, 0x3ca1, 0x3ca1, 
+    0x3ca1, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca3, 0x3ca3, 0x3ca3, 0x3ca4, 
+    0x3ca4, 0x3ca4, 0x3ca4, 0x3ca5, 0x3ca5, 0x3ca5, 0x3ca6, 0x3ca6, 
+    0x3ca6, 0x3ca7, 0x3ca7, 0x3ca7, 0x3ca8, 0x3ca8, 0x3ca8, 0x3ca9, 
+    0x3ca9, 0x3ca9, 0x3caa, 0x3caa, 0x3caa, 0x3caa, 0x3cab, 0x3cab, 
+    0x3cab, 0x3cac, 0x3cac, 0x3cac, 0x3cad, 0x3cad, 0x3cad, 0x3cae, 
+    0x3cae, 0x3cae, 0x3caf, 0x3caf, 0x3caf, 0x3cb0, 0x3cb0, 0x3cb0, 
+    0x3cb0, 0x3cb1, 0x3cb1, 0x3cb1, 0x3cb2, 0x3cb2, 0x3cb2, 0x3cb3, 
+    0x3cb3, 0x3cb3, 0x3cb4, 0x3cb4, 0x3cb4, 0x3cb4, 0x3cb5, 0x3cb5, 
+    0x3cb5, 0x3cb6, 0x3cb6, 0x3cb6, 0x3cb7, 0x3cb7, 0x3cb7, 0x3cb8, 
+    0x3cb8, 0x3cb8, 0x3cb8, 0x3cb9, 0x3cb9, 0x3cb9, 0x3cba, 0x3cba, 
+    0x3cba, 0x3cbb, 0x3cbb, 0x3cbb, 0x3cbc, 0x3cbc, 0x3cbc, 0x3cbc, 
+    0x3cbd, 0x3cbd, 0x3cbd, 0x3cbe, 0x3cbe, 0x3cbe, 0x3cbf, 0x3cbf, 
+    0x3cbf, 0x3cbf, 0x3cc0, 0x3cc0, 0x3cc0, 0x3cc1, 0x3cc1, 0x3cc1, 
+    0x3cc2, 0x3cc2, 0x3cc2, 0x3cc2, 0x3cc3, 0x3cc3, 0x3cc3, 0x3cc4, 
+    0x3cc4, 0x3cc4, 0x3cc5, 0x3cc5, 0x3cc5, 0x3cc5, 0x3cc6, 0x3cc6, 
+    0x3cc6, 0x3cc7, 0x3cc7, 0x3cc7, 0x3cc8, 0x3cc8, 0x3cc8, 0x3cc8, 
+    0x3cc9, 0x3cc9, 0x3cc9, 0x3cca, 0x3cca, 0x3cca, 0x3cca, 0x3ccb, 
+    0x3ccb, 0x3ccb, 0x3ccc, 0x3ccc, 0x3ccc, 0x3ccd, 0x3ccd, 0x3ccd, 
+    0x3ccd, 0x3cce, 0x3cce, 0x3cce, 0x3ccf, 0x3ccf, 0x3ccf, 0x3ccf, 
+    0x3cd0, 0x3cd0, 0x3cd0, 0x3cd1, 0x3cd1, 0x3cd1, 0x3cd1, 0x3cd2, 
+    0x3cd2, 0x3cd2, 0x3cd3, 0x3cd3, 0x3cd3, 0x3cd3, 0x3cd4, 0x3cd4, 
+    0x3cd4, 0x3cd5, 0x3cd5, 0x3cd5, 0x3cd6, 0x3cd6, 0x3cd6, 0x3cd6, 
+    0x3cd7, 0x3cd7, 0x3cd7, 0x3cd8, 0x3cd8, 0x3cd8, 0x3cd8, 0x3cd9, 
+    0x3cd9, 0x3cd9, 0x3cda, 0x3cda, 0x3cda, 0x3cda, 0x3cdb, 0x3cdb, 
+    0x3cdb, 0x3cdc, 0x3cdc, 0x3cdc, 0x3cdc, 0x3cdd, 0x3cdd, 0x3cdd, 
+    0x3cdd, 0x3cde, 0x3cde, 0x3cde, 0x3cdf, 0x3cdf, 0x3cdf, 0x3cdf, 
+    0x3ce0, 0x3ce0, 0x3ce0, 0x3ce1, 0x3ce1, 0x3ce1, 0x3ce1, 0x3ce2, 
+    0x3ce2, 0x3ce2, 0x3ce3, 0x3ce3, 0x3ce3, 0x3ce3, 0x3ce4, 0x3ce4, 
+    0x3ce4, 0x3ce4, 0x3ce5, 0x3ce5, 0x3ce5, 0x3ce6, 0x3ce6, 0x3ce6, 
+    0x3ce6, 0x3ce7, 0x3ce7, 0x3ce7, 0x3ce8, 0x3ce8, 0x3ce8, 0x3ce8, 
+    0x3ce9, 0x3ce9, 0x3ce9, 0x3ce9, 0x3cea, 0x3cea, 0x3cea, 0x3ceb, 
+    0x3ceb, 0x3ceb, 0x3ceb, 0x3cec, 0x3cec, 0x3cec, 0x3cec, 0x3ced, 
+    0x3ced, 0x3ced, 0x3cee, 0x3cee, 0x3cee, 0x3cee, 0x3cef, 0x3cef, 
+    0x3cef, 0x3cef, 0x3cf0, 0x3cf0, 0x3cf0, 0x3cf1, 0x3cf1, 0x3cf1, 
+    0x3cf1, 0x3cf2, 0x3cf2, 0x3cf2, 0x3cf2, 0x3cf3, 0x3cf3, 0x3cf3, 
+    0x3cf4, 0x3cf4, 0x3cf4, 0x3cf4, 0x3cf5, 0x3cf5, 0x3cf5, 0x3cf5, 
+    0x3cf6, 0x3cf6, 0x3cf6, 0x3cf7, 0x3cf7, 0x3cf7, 0x3cf7, 0x3cf8, 
+    0x3cf8, 0x3cf8, 0x3cf8, 0x3cf9, 0x3cf9, 0x3cf9, 0x3cf9, 0x3cfa, 
+    0x3cfa, 0x3cfa, 0x3cfa, 0x3cfb, 0x3cfb, 0x3cfb, 0x3cfc, 0x3cfc, 
+    0x3cfc, 0x3cfc, 0x3cfd, 0x3cfd, 0x3cfd, 0x3cfd, 0x3cfe, 0x3cfe, 
+    0x3cfe, 0x3cfe, 0x3cff, 0x3cff, 0x3cff, 0x3d00, 0x3d00, 0x3d00, 
+    0x3d00, 0x3d01, 0x3d01, 0x3d01, 0x3d01, 0x3d02, 0x3d02, 0x3d02, 
+    0x3d02, 0x3d03, 0x3d03, 0x3d03, 0x3d03, 0x3d04, 0x3d04, 0x3d04, 
+    0x3d04, 0x3d05, 0x3d05, 0x3d05, 0x3d06, 0x3d06, 0x3d06, 0x3d06, 
+    0x3d07, 0x3d07, 0x3d07, 0x3d07, 0x3d08, 0x3d08, 0x3d08, 0x3d08, 
+    0x3d09, 0x3d09, 0x3d09, 0x3d09, 0x3d0a, 0x3d0a, 0x3d0a, 0x3d0a, 
+    0x3d0b, 0x3d0b, 0x3d0b, 0x3d0b, 0x3d0c, 0x3d0c, 0x3d0c, 0x3d0c, 
+    0x3d0d, 0x3d0d, 0x3d0d, 0x3d0d, 0x3d0e, 0x3d0e, 0x3d0e, 0x3d0e, 
+    0x3d0f, 0x3d0f, 0x3d0f, 0x3d10, 0x3d10, 0x3d10, 0x3d10, 0x3d11, 
+    0x3d11, 0x3d11, 0x3d11, 0x3d12, 0x3d12, 0x3d12, 0x3d12, 0x3d13, 
+    0x3d13, 0x3d13, 0x3d13, 0x3d14, 0x3d14, 0x3d14, 0x3d14, 0x3d15, 
+    0x3d15, 0x3d15, 0x3d15, 0x3d16, 0x3d16, 0x3d16, 0x3d16, 0x3d17, 
+    0x3d17, 0x3d17, 0x3d17, 0x3d18, 0x3d18, 0x3d18, 0x3d18, 0x3d19, 
+    0x3d19, 0x3d19, 0x3d19, 0x3d1a, 0x3d1a, 0x3d1a, 0x3d1a, 0x3d1b, 
+    0x3d1b, 0x3d1b, 0x3d1b, 0x3d1c, 0x3d1c, 0x3d1c, 0x3d1c, 0x3d1d, 
+    0x3d1d, 0x3d1d, 0x3d1d, 0x3d1e, 0x3d1e, 0x3d1e, 0x3d1e, 0x3d1e, 
+    0x3d1f, 0x3d1f, 0x3d1f, 0x3d1f, 0x3d20, 0x3d20, 0x3d20, 0x3d20, 
+    0x3d21, 0x3d21, 0x3d21, 0x3d21, 0x3d22, 0x3d22, 0x3d22, 0x3d22, 
+    0x3d23, 0x3d23, 0x3d23, 0x3d23, 0x3d24, 0x3d24, 0x3d24, 0x3d24, 
+    0x3d25, 0x3d25, 0x3d25, 0x3d25, 0x3d26, 0x3d26, 0x3d26, 0x3d26, 
+    0x3d27, 0x3d27, 0x3d27, 0x3d27, 0x3d27, 0x3d28, 0x3d28, 0x3d28, 
+    0x3d28, 0x3d29, 0x3d29, 0x3d29, 0x3d29, 0x3d2a, 0x3d2a, 0x3d2a, 
+    0x3d2a, 0x3d2b, 0x3d2b, 0x3d2b, 0x3d2b, 0x3d2c, 0x3d2c, 0x3d2c, 
+    0x3d2c, 0x3d2d, 0x3d2d, 0x3d2d, 0x3d2d, 0x3d2d, 0x3d2e, 0x3d2e, 
+    0x3d2e, 0x3d2e, 0x3d2f, 0x3d2f, 0x3d2f, 0x3d2f, 0x3d30, 0x3d30, 
+    0x3d30, 0x3d30, 0x3d31, 0x3d31, 0x3d31, 0x3d31, 0x3d31, 0x3d32, 
+    0x3d32, 0x3d32, 0x3d32, 0x3d33, 0x3d33, 0x3d33, 0x3d33, 0x3d34, 
+    0x3d34, 0x3d34, 0x3d34, 0x3d35, 0x3d35, 0x3d35, 0x3d35, 0x3d35, 
+    0x3d36, 0x3d36, 0x3d36, 0x3d36, 0x3d37, 0x3d37, 0x3d37, 0x3d37, 
+    0x3d38, 0x3d38, 0x3d38, 0x3d38, 0x3d39, 0x3d39, 0x3d39, 0x3d39, 
+    0x3d39, 0x3d3a, 0x3d3a, 0x3d3a, 0x3d3a, 0x3d3b, 0x3d3b, 0x3d3b, 
+    0x3d3b, 0x3d3c, 0x3d3c, 0x3d3c, 0x3d3c, 0x3d3c, 0x3d3d, 0x3d3d, 
+    0x3d3d, 0x3d3d, 0x3d3e, 0x3d3e, 0x3d3e, 0x3d3e, 0x3d3f, 0x3d3f, 
+    0x3d3f, 0x3d3f, 0x3d3f, 0x3d40, 0x3d40, 0x3d40, 0x3d40, 0x3d41, 
+    0x3d41, 0x3d41, 0x3d41, 0x3d41, 0x3d42, 0x3d42, 0x3d42, 0x3d42, 
+    0x3d43, 0x3d43, 0x3d44, 0x3d44, 0x3d44, 0x3d45, 0x3d45, 0x3d46, 
+    0x3d46, 0x3d47, 0x3d47, 0x3d48, 0x3d48, 0x3d49, 0x3d49, 0x3d49, 
+    0x3d4a, 0x3d4a, 0x3d4b, 0x3d4b, 0x3d4c, 0x3d4c, 0x3d4d, 0x3d4d, 
+    0x3d4d, 0x3d4e, 0x3d4e, 0x3d4f, 0x3d4f, 0x3d50, 0x3d50, 0x3d51, 
+    0x3d51, 0x3d51, 0x3d52, 0x3d52, 0x3d53, 0x3d53, 0x3d54, 0x3d54, 
+    0x3d54, 0x3d55, 0x3d55, 0x3d56, 0x3d56, 0x3d57, 0x3d57, 0x3d58, 
+    0x3d58, 0x3d58, 0x3d59, 0x3d59, 0x3d5a, 0x3d5a, 0x3d5b, 0x3d5b, 
+    0x3d5b, 0x3d5c, 0x3d5c, 0x3d5d, 0x3d5d, 0x3d5e, 0x3d5e, 0x3d5e, 
+    0x3d5f, 0x3d5f, 0x3d60, 0x3d60, 0x3d61, 0x3d61, 0x3d61, 0x3d62, 
+    0x3d62, 0x3d63, 0x3d63, 0x3d64, 0x3d64, 0x3d64, 0x3d65, 0x3d65, 
+    0x3d66, 0x3d66, 0x3d66, 0x3d67, 0x3d67, 0x3d68, 0x3d68, 0x3d69, 
+    0x3d69, 0x3d69, 0x3d6a, 0x3d6a, 0x3d6b, 0x3d6b, 0x3d6c, 0x3d6c, 
+    0x3d6c, 0x3d6d, 0x3d6d, 0x3d6e, 0x3d6e, 0x3d6e, 0x3d6f, 0x3d6f, 
+    0x3d70, 0x3d70, 0x3d70, 0x3d71, 0x3d71, 0x3d72, 0x3d72, 0x3d73, 
+    0x3d73, 0x3d73, 0x3d74, 0x3d74, 0x3d75, 0x3d75, 0x3d75, 0x3d76, 
+    0x3d76, 0x3d77, 0x3d77, 0x3d77, 0x3d78, 0x3d78, 0x3d79, 0x3d79, 
+    0x3d79, 0x3d7a, 0x3d7a, 0x3d7b, 0x3d7b, 0x3d7b, 0x3d7c, 0x3d7c, 
+    0x3d7d, 0x3d7d, 0x3d7d, 0x3d7e, 0x3d7e, 0x3d7f, 0x3d7f, 0x3d7f, 
+    0x3d80, 0x3d80, 0x3d81, 0x3d81, 0x3d81, 0x3d82, 0x3d82, 0x3d83, 
+    0x3d83, 0x3d83, 0x3d84, 0x3d84, 0x3d85, 0x3d85, 0x3d85, 0x3d86, 
+    0x3d86, 0x3d87, 0x3d87, 0x3d87, 0x3d88, 0x3d88, 0x3d89, 0x3d89, 
+    0x3d89, 0x3d8a, 0x3d8a, 0x3d8b, 0x3d8b, 0x3d8b, 0x3d8c, 0x3d8c, 
+    0x3d8c, 0x3d8d, 0x3d8d, 0x3d8e, 0x3d8e, 0x3d8e, 0x3d8f, 0x3d8f, 
+    0x3d90, 0x3d90, 0x3d90, 0x3d91, 0x3d91, 0x3d91, 0x3d92, 0x3d92, 
+    0x3d93, 0x3d93, 0x3d93, 0x3d94, 0x3d94, 0x3d95, 0x3d95, 0x3d95, 
+    0x3d96, 0x3d96, 0x3d96, 0x3d97, 0x3d97, 0x3d98, 0x3d98, 0x3d98, 
+    0x3d99, 0x3d99, 0x3d99, 0x3d9a, 0x3d9a, 0x3d9b, 0x3d9b, 0x3d9b, 
+    0x3d9c, 0x3d9c, 0x3d9c, 0x3d9d, 0x3d9d, 0x3d9e, 0x3d9e, 0x3d9e, 
+    0x3d9f, 0x3d9f, 0x3d9f, 0x3da0, 0x3da0, 0x3da1, 0x3da1, 0x3da1, 
+    0x3da2, 0x3da2, 0x3da2, 0x3da3, 0x3da3, 0x3da4, 0x3da4, 0x3da4, 
+    0x3da5, 0x3da5, 0x3da5, 0x3da6, 0x3da6, 0x3da6, 0x3da7, 0x3da7, 
+    0x3da8, 0x3da8, 0x3da8, 0x3da9, 0x3da9, 0x3da9, 0x3daa, 0x3daa, 
+    0x3daa, 0x3dab, 0x3dab, 0x3dac, 0x3dac, 0x3dac, 0x3dad, 0x3dad, 
+    0x3dad, 0x3dae, 0x3dae, 0x3dae, 0x3daf, 0x3daf, 0x3db0, 0x3db0, 
+    0x3db0, 0x3db1, 0x3db1, 0x3db1, 0x3db2, 0x3db2, 0x3db2, 0x3db3, 
+    0x3db3, 0x3db3, 0x3db4, 0x3db4, 0x3db5, 0x3db5, 0x3db5, 0x3db6, 
+    0x3db6, 0x3db6, 0x3db7, 0x3db7, 0x3db7, 0x3db8, 0x3db8, 0x3db8, 
+    0x3db9, 0x3db9, 0x3dba, 0x3dba, 0x3dba, 0x3dbb, 0x3dbb, 0x3dbb, 
+    0x3dbc, 0x3dbc, 0x3dbc, 0x3dbd, 0x3dbd, 0x3dbd, 0x3dbe, 0x3dbe, 
+    0x3dbe, 0x3dbf, 0x3dbf, 0x3dbf, 0x3dc0, 0x3dc0, 0x3dc1, 0x3dc1, 
+    0x3dc1, 0x3dc2, 0x3dc2, 0x3dc2, 0x3dc3, 0x3dc3, 0x3dc3, 0x3dc4, 
+    0x3dc4, 0x3dc4, 0x3dc5, 0x3dc5, 0x3dc5, 0x3dc6, 0x3dc6, 0x3dc6, 
+    0x3dc7, 0x3dc7, 0x3dc7, 0x3dc8, 0x3dc8, 0x3dc8, 0x3dc9, 0x3dc9, 
+    0x3dc9, 0x3dca, 0x3dca, 0x3dca, 0x3dcb, 0x3dcb, 0x3dcb, 0x3dcc, 
+    0x3dcc, 0x3dcc, 0x3dcd, 0x3dcd, 0x3dce, 0x3dce, 0x3dce, 0x3dcf, 
+    0x3dcf, 0x3dcf, 0x3dd0, 0x3dd0, 0x3dd0, 0x3dd1, 0x3dd1, 0x3dd1, 
+    0x3dd2, 0x3dd2, 0x3dd2, 0x3dd3, 0x3dd3, 0x3dd3, 0x3dd4, 0x3dd4, 
+    0x3dd4, 0x3dd5, 0x3dd5, 0x3dd5, 0x3dd6, 0x3dd6, 0x3dd6, 0x3dd7, 
+    0x3dd7, 0x3dd7, 0x3dd8, 0x3dd8, 0x3dd8, 0x3dd9, 0x3dd9, 0x3dd9, 
+    0x3dd9, 0x3dda, 0x3dda, 0x3dda, 0x3ddb, 0x3ddb, 0x3ddb, 0x3ddc, 
+    0x3ddc, 0x3ddc, 0x3ddd, 0x3ddd, 0x3ddd, 0x3dde, 0x3dde, 0x3dde, 
+    0x3ddf, 0x3ddf, 0x3ddf, 0x3de0, 0x3de0, 0x3de0, 0x3de1, 0x3de1, 
+    0x3de1, 0x3de2, 0x3de2, 0x3de2, 0x3de3, 0x3de3, 0x3de3, 0x3de4, 
+    0x3de4, 0x3de4, 0x3de5, 0x3de5, 0x3de5, 0x3de5, 0x3de6, 0x3de6, 
+    0x3de6, 0x3de7, 0x3de7, 0x3de7, 0x3de8, 0x3de8, 0x3de8, 0x3de9, 
+    0x3de9, 0x3de9, 0x3dea, 0x3dea, 0x3dea, 0x3deb, 0x3deb, 0x3deb, 
+    0x3dec, 0x3dec, 0x3dec, 0x3dec, 0x3ded, 0x3ded, 0x3ded, 0x3dee, 
+    0x3dee, 0x3dee, 0x3def, 0x3def, 0x3def, 0x3df0, 0x3df0, 0x3df0, 
+    0x3df1, 0x3df1, 0x3df1, 0x3df2, 0x3df2, 0x3df2, 0x3df2, 0x3df3, 
+    0x3df3, 0x3df3, 0x3df4, 0x3df4, 0x3df4, 0x3df5, 0x3df5, 0x3df5, 
+    0x3df6, 0x3df6, 0x3df6, 0x3df6, 0x3df7, 0x3df7, 0x3df7, 0x3df8, 
+    0x3df8, 0x3df8, 0x3df9, 0x3df9, 0x3df9, 0x3dfa, 0x3dfa, 0x3dfa, 
+    0x3dfa, 0x3dfb, 0x3dfb, 0x3dfb, 0x3dfc, 0x3dfc, 0x3dfc, 0x3dfd, 
+    0x3dfd, 0x3dfd, 0x3dfe, 0x3dfe, 0x3dfe, 0x3dfe, 0x3dff, 0x3dff, 
+    0x3dff, 0x3e00, 0x3e00, 0x3e00, 0x3e01, 0x3e01, 0x3e01, 0x3e01, 
+    0x3e02, 0x3e02, 0x3e02, 0x3e03, 0x3e03, 0x3e03, 0x3e04, 0x3e04, 
+    0x3e04, 0x3e04, 0x3e05, 0x3e05, 0x3e05, 0x3e06, 0x3e06, 0x3e06, 
+    0x3e07, 0x3e07, 0x3e07, 0x3e07, 0x3e08, 0x3e08, 0x3e08, 0x3e09, 
+    0x3e09, 0x3e09, 0x3e0a, 0x3e0a, 0x3e0a, 0x3e0a, 0x3e0b, 0x3e0b, 
+    0x3e0b, 0x3e0c, 0x3e0c, 0x3e0c, 0x3e0c, 0x3e0d, 0x3e0d, 0x3e0d, 
+    0x3e0e, 0x3e0e, 0x3e0e, 0x3e0f, 0x3e0f, 0x3e0f, 0x3e0f, 0x3e10, 
+    0x3e10, 0x3e10, 0x3e11, 0x3e11, 0x3e11, 0x3e11, 0x3e12, 0x3e12, 
+    0x3e12, 0x3e13, 0x3e13, 0x3e13, 0x3e14, 0x3e14, 0x3e14, 0x3e14, 
+    0x3e15, 0x3e15, 0x3e15, 0x3e16, 0x3e16, 0x3e16, 0x3e16, 0x3e17, 
+    0x3e17, 0x3e17, 0x3e18, 0x3e18, 0x3e18, 0x3e18, 0x3e19, 0x3e19, 
+    0x3e19, 0x3e1a, 0x3e1a, 0x3e1a, 0x3e1a, 0x3e1b, 0x3e1b, 0x3e1b, 
+    0x3e1c, 0x3e1c, 0x3e1c, 0x3e1c, 0x3e1d, 0x3e1d, 0x3e1d, 0x3e1e, 
+    0x3e1e, 0x3e1e, 0x3e1e, 0x3e1f, 0x3e1f, 0x3e1f, 0x3e20, 0x3e20, 
+    0x3e20, 0x3e20, 0x3e21, 0x3e21, 0x3e21, 0x3e22, 0x3e22, 0x3e22, 
+    0x3e22, 0x3e23, 0x3e23, 0x3e23, 0x3e23, 0x3e24, 0x3e24, 0x3e24, 
+    0x3e25, 0x3e25, 0x3e25, 0x3e25, 0x3e26, 0x3e26, 0x3e26, 0x3e27, 
+    0x3e27, 0x3e27, 0x3e27, 0x3e28, 0x3e28, 0x3e28, 0x3e29, 0x3e29, 
+    0x3e29, 0x3e29, 0x3e2a, 0x3e2a, 0x3e2a, 0x3e2a, 0x3e2b, 0x3e2b, 
+    0x3e2b, 0x3e2c, 0x3e2c, 0x3e2c, 0x3e2c, 0x3e2d, 0x3e2d, 0x3e2d, 
+    0x3e2d, 0x3e2e, 0x3e2e, 0x3e2e, 0x3e2f, 0x3e2f, 0x3e2f, 0x3e2f, 
+    0x3e30, 0x3e30, 0x3e30, 0x3e30, 0x3e31, 0x3e31, 0x3e31, 0x3e32, 
+    0x3e32, 0x3e32, 0x3e32, 0x3e33, 0x3e33, 0x3e33, 0x3e33, 0x3e34, 
+    0x3e34, 0x3e34, 0x3e35, 0x3e35, 0x3e35, 0x3e35, 0x3e36, 0x3e36, 
+    0x3e36, 0x3e36, 0x3e37, 0x3e37, 0x3e37, 0x3e38, 0x3e38, 0x3e38, 
+    0x3e38, 0x3e39, 0x3e39, 0x3e39, 0x3e39, 0x3e3a, 0x3e3a, 0x3e3a, 
+    0x3e3a, 0x3e3b, 0x3e3b, 0x3e3b, 0x3e3c, 0x3e3c, 0x3e3c, 0x3e3c, 
+    0x3e3d, 0x3e3d, 0x3e3d, 0x3e3d, 0x3e3e, 0x3e3e, 0x3e3e, 0x3e3e, 
+    0x3e3f, 0x3e3f, 0x3e3f, 0x3e40, 0x3e40, 0x3e40, 0x3e40, 0x3e41, 
+    0x3e41, 0x3e41, 0x3e41, 0x3e42, 0x3e42, 0x3e42, 0x3e42, 0x3e43, 
+    0x3e43, 0x3e43, 0x3e43, 0x3e44, 0x3e44, 0x3e44, 0x3e44, 0x3e45, 
+    0x3e45, 0x3e45, 0x3e46, 0x3e46, 0x3e46, 0x3e46, 0x3e47, 0x3e47, 
+    0x3e47, 0x3e47, 0x3e48, 0x3e48, 0x3e48, 0x3e48, 0x3e49, 0x3e49, 
+    0x3e49, 0x3e49, 0x3e4a, 0x3e4a, 0x3e4a, 0x3e4a, 0x3e4b, 0x3e4b, 
+    0x3e4b, 0x3e4b, 0x3e4c, 0x3e4c, 0x3e4c, 0x3e4d, 0x3e4d, 0x3e4d, 
+    0x3e4d, 0x3e4e, 0x3e4e, 0x3e4e, 0x3e4e, 0x3e4f, 0x3e4f, 0x3e4f, 
+    0x3e4f, 0x3e50, 0x3e50, 0x3e50, 0x3e50, 0x3e51, 0x3e51, 0x3e51, 
+    0x3e51, 0x3e52, 0x3e52, 0x3e52, 0x3e52, 0x3e53, 0x3e53, 0x3e53, 
+    0x3e53, 0x3e54, 0x3e54, 0x3e54, 0x3e54, 0x3e55, 0x3e55, 0x3e55, 
+    0x3e55, 0x3e56, 0x3e56, 0x3e56, 0x3e56, 0x3e57, 0x3e57, 0x3e57, 
+    0x3e57, 0x3e58, 0x3e58, 0x3e58, 0x3e58, 0x3e59, 0x3e59, 0x3e59, 
+    0x3e59, 0x3e5a, 0x3e5a, 0x3e5a, 0x3e5a, 0x3e5b, 0x3e5b, 0x3e5b, 
+    0x3e5b, 0x3e5c, 0x3e5c, 0x3e5c, 0x3e5c, 0x3e5d, 0x3e5d, 0x3e5d, 
+    0x3e5d, 0x3e5e, 0x3e5e, 0x3e5e, 0x3e5e, 0x3e5f, 0x3e5f, 0x3e5f, 
+    0x3e5f, 0x3e60, 0x3e60, 0x3e60, 0x3e60, 0x3e61, 0x3e61, 0x3e61, 
+    0x3e61, 0x3e62, 0x3e62, 0x3e62, 0x3e62, 0x3e63, 0x3e63, 0x3e63, 
+    0x3e63, 0x3e64, 0x3e64, 0x3e64, 0x3e64, 0x3e65, 0x3e65, 0x3e65, 
+    0x3e65, 0x3e66, 0x3e66, 0x3e66, 0x3e66, 0x3e66, 0x3e67, 0x3e67, 
+    0x3e67, 0x3e67, 0x3e68, 0x3e68, 0x3e68, 0x3e68, 0x3e69, 0x3e69, 
+    0x3e69, 0x3e69, 0x3e6a, 0x3e6a, 0x3e6a, 0x3e6a, 0x3e6b, 0x3e6b, 
+    0x3e6b, 0x3e6b, 0x3e6c, 0x3e6c, 0x3e6c, 0x3e6c, 0x3e6d, 0x3e6d, 
+    0x3e6d, 0x3e6d, 0x3e6d, 0x3e6e, 0x3e6e, 0x3e6e, 0x3e6e, 0x3e6f, 
+    0x3e6f, 0x3e6f, 0x3e6f, 0x3e70, 0x3e70, 0x3e70, 0x3e70, 0x3e71, 
+    0x3e71, 0x3e71, 0x3e71, 0x3e72, 0x3e72, 0x3e72, 0x3e72, 0x3e72, 
+    0x3e73, 0x3e73, 0x3e73, 0x3e73, 0x3e74, 0x3e74, 0x3e74, 0x3e74, 
+    0x3e75, 0x3e75, 0x3e75, 0x3e75, 0x3e76, 0x3e76, 0x3e76, 0x3e76, 
+    0x3e76, 0x3e77, 0x3e77, 0x3e77, 0x3e77, 0x3e78, 0x3e78, 0x3e78, 
+    0x3e78, 0x3e79, 0x3e79, 0x3e79, 0x3e79, 0x3e7a, 0x3e7a, 0x3e7a, 
+    0x3e7a, 0x3e7a, 0x3e7b, 0x3e7b, 0x3e7b, 0x3e7b, 0x3e7c, 0x3e7c, 
+    0x3e7c, 0x3e7c, 0x3e7d, 0x3e7d, 0x3e7d, 0x3e7d, 0x3e7d, 0x3e7e, 
+    0x3e7e, 0x3e7e, 0x3e7e, 0x3e7f, 0x3e7f, 0x3e7f, 0x3e7f, 0x3e80, 
+    0x3e80, 0x3e80, 0x3e80, 0x3e80, 0x3e81, 0x3e81, 0x3e81, 0x3e81, 
+    0x3e82, 0x3e82, 0x3e82, 0x3e82, 0x3e83, 0x3e83, 0x3e83, 0x3e83, 
+    0x3e83, 0x3e84, 0x3e84, 0x3e84, 0x3e84, 0x3e85, 0x3e85, 0x3e85, 
+    0x3e85, 0x3e86, 0x3e86, 0x3e87, 0x3e87, 0x3e88, 0x3e88, 0x3e88, 
+    0x3e89, 0x3e89, 0x3e8a, 0x3e8a, 0x3e8b, 0x3e8b, 0x3e8c, 0x3e8c, 
+    0x3e8c, 0x3e8d, 0x3e8d, 0x3e8e, 0x3e8e, 0x3e8f, 0x3e8f, 0x3e90, 
+    0x3e90, 0x3e90, 0x3e91, 0x3e91, 0x3e92, 0x3e92, 0x3e93, 0x3e93, 
+    0x3e94, 0x3e94, 0x3e94, 0x3e95, 0x3e95, 0x3e96, 0x3e96, 0x3e97, 
+    0x3e97, 0x3e98, 0x3e98, 0x3e98, 0x3e99, 0x3e99, 0x3e9a, 0x3e9a, 
+    0x3e9b, 0x3e9b, 0x3e9b, 0x3e9c, 0x3e9c, 0x3e9d, 0x3e9d, 0x3e9e, 
+    0x3e9e, 0x3e9e, 0x3e9f, 0x3e9f, 0x3ea0, 0x3ea0, 0x3ea1, 0x3ea1, 
+    0x3ea1, 0x3ea2, 0x3ea2, 0x3ea3, 0x3ea3, 0x3ea4, 0x3ea4, 0x3ea4, 
+    0x3ea5, 0x3ea5, 0x3ea6, 0x3ea6, 0x3ea7, 0x3ea7, 0x3ea7, 0x3ea8, 
+    0x3ea8, 0x3ea9, 0x3ea9, 0x3eaa, 0x3eaa, 0x3eaa, 0x3eab, 0x3eab, 
+    0x3eac, 0x3eac, 0x3eac, 0x3ead, 0x3ead, 0x3eae, 0x3eae, 0x3eaf, 
+    0x3eaf, 0x3eaf, 0x3eb0, 0x3eb0, 0x3eb1, 0x3eb1, 0x3eb1, 0x3eb2, 
+    0x3eb2, 0x3eb3, 0x3eb3, 0x3eb4, 0x3eb4, 0x3eb4, 0x3eb5, 0x3eb5, 
+    0x3eb6, 0x3eb6, 0x3eb6, 0x3eb7, 0x3eb7, 0x3eb8, 0x3eb8, 0x3eb8, 
+    0x3eb9, 0x3eb9, 0x3eba, 0x3eba, 0x3eba, 0x3ebb, 0x3ebb, 0x3ebc, 
+    0x3ebc, 0x3ebc, 0x3ebd, 0x3ebd, 0x3ebe, 0x3ebe, 0x3ebe, 0x3ebf, 
+    0x3ebf, 0x3ec0, 0x3ec0, 0x3ec1, 0x3ec1, 0x3ec1, 0x3ec2, 0x3ec2, 
+    0x3ec2, 0x3ec3, 0x3ec3, 0x3ec4, 0x3ec4, 0x3ec4, 0x3ec5, 0x3ec5, 
+    0x3ec6, 0x3ec6, 0x3ec6, 0x3ec7, 0x3ec7, 0x3ec8, 0x3ec8, 0x3ec8, 
+    0x3ec9, 0x3ec9, 0x3eca, 0x3eca, 0x3eca, 0x3ecb, 0x3ecb, 0x3ecc, 
+    0x3ecc, 0x3ecc, 0x3ecd, 0x3ecd, 0x3ece, 0x3ece, 0x3ece, 0x3ecf, 
+    0x3ecf, 0x3ecf, 0x3ed0, 0x3ed0, 0x3ed1, 0x3ed1, 0x3ed1, 0x3ed2, 
+    0x3ed2, 0x3ed3, 0x3ed3, 0x3ed3, 0x3ed4, 0x3ed4, 0x3ed4, 0x3ed5, 
+    0x3ed5, 0x3ed6, 0x3ed6, 0x3ed6, 0x3ed7, 0x3ed7, 0x3ed8, 0x3ed8, 
+    0x3ed8, 0x3ed9, 0x3ed9, 0x3ed9, 0x3eda, 0x3eda, 0x3edb, 0x3edb, 
+    0x3edb, 0x3edc, 0x3edc, 0x3edc, 0x3edd, 0x3edd, 0x3ede, 0x3ede, 
+    0x3ede, 0x3edf, 0x3edf, 0x3edf, 0x3ee0, 0x3ee0, 0x3ee1, 0x3ee1, 
+    0x3ee1, 0x3ee2, 0x3ee2, 0x3ee2, 0x3ee3, 0x3ee3, 0x3ee4, 0x3ee4, 
+    0x3ee4, 0x3ee5, 0x3ee5, 0x3ee5, 0x3ee6, 0x3ee6, 0x3ee7, 0x3ee7, 
+    0x3ee7, 0x3ee8, 0x3ee8, 0x3ee8, 0x3ee9, 0x3ee9, 0x3ee9, 0x3eea, 
+    0x3eea, 0x3eeb, 0x3eeb, 0x3eeb, 0x3eec, 0x3eec, 0x3eec, 0x3eed, 
+    0x3eed, 0x3eed, 0x3eee, 0x3eee, 0x3eef, 0x3eef, 0x3eef, 0x3ef0, 
+    0x3ef0, 0x3ef0, 0x3ef1, 0x3ef1, 0x3ef1, 0x3ef2, 0x3ef2, 0x3ef3, 
+    0x3ef3, 0x3ef3, 0x3ef4, 0x3ef4, 0x3ef4, 0x3ef5, 0x3ef5, 0x3ef5, 
+    0x3ef6, 0x3ef6, 0x3ef6, 0x3ef7, 0x3ef7, 0x3ef8, 0x3ef8, 0x3ef8, 
+    0x3ef9, 0x3ef9, 0x3ef9, 0x3efa, 0x3efa, 0x3efa, 0x3efb, 0x3efb, 
+    0x3efb, 0x3efc, 0x3efc, 0x3efc, 0x3efd, 0x3efd, 0x3efe, 0x3efe, 
+    0x3efe, 0x3eff, 0x3eff, 0x3eff, 0x3f00, 0x3f00, 0x3f00, 0x3f01, 
+    0x3f01, 0x3f01, 0x3f02, 0x3f02, 0x3f02, 0x3f03, 0x3f03, 0x3f03, 
+    0x3f04, 0x3f04, 0x3f05, 0x3f05, 0x3f05, 0x3f06, 0x3f06, 0x3f06, 
+    0x3f07, 0x3f07, 0x3f07, 0x3f08, 0x3f08, 0x3f08, 0x3f09, 0x3f09, 
+    0x3f09, 0x3f0a, 0x3f0a, 0x3f0a, 0x3f0b, 0x3f0b, 0x3f0b, 0x3f0c, 
+    0x3f0c, 0x3f0c, 0x3f0d, 0x3f0d, 0x3f0d, 0x3f0e, 0x3f0e, 0x3f0e, 
+    0x3f0f, 0x3f0f, 0x3f0f, 0x3f10, 0x3f10, 0x3f10, 0x3f11, 0x3f11, 
+    0x3f11, 0x3f12, 0x3f12, 0x3f12, 0x3f13, 0x3f13, 0x3f13, 0x3f14, 
+    0x3f14, 0x3f14, 0x3f15, 0x3f15, 0x3f15, 0x3f16, 0x3f16, 0x3f16, 
+    0x3f17, 0x3f17, 0x3f17, 0x3f18, 0x3f18, 0x3f18, 0x3f19, 0x3f19, 
+    0x3f19, 0x3f1a, 0x3f1a, 0x3f1a, 0x3f1b, 0x3f1b, 0x3f1b, 0x3f1c, 
+    0x3f1c, 0x3f1c, 0x3f1d, 0x3f1d, 0x3f1d, 0x3f1e, 0x3f1e, 0x3f1e, 
+    0x3f1f, 0x3f1f, 0x3f1f, 0x3f20, 0x3f20, 0x3f20, 0x3f21, 0x3f21, 
+    0x3f21, 0x3f22, 0x3f22, 0x3f22, 0x3f23, 0x3f23, 0x3f23, 0x3f24, 
+    0x3f24, 0x3f24, 0x3f25, 0x3f25, 0x3f25, 0x3f26, 0x3f26, 0x3f26, 
+    0x3f27, 0x3f27, 0x3f27, 0x3f27, 0x3f28, 0x3f28, 0x3f28, 0x3f29, 
+    0x3f29, 0x3f29, 0x3f2a, 0x3f2a, 0x3f2a, 0x3f2b, 0x3f2b, 0x3f2b, 
+    0x3f2c, 0x3f2c, 0x3f2c, 0x3f2d, 0x3f2d, 0x3f2d, 0x3f2e, 0x3f2e, 
+    0x3f2e, 0x3f2e, 0x3f2f, 0x3f2f, 0x3f2f, 0x3f30, 0x3f30, 0x3f30, 
+    0x3f31, 0x3f31, 0x3f31, 0x3f32, 0x3f32, 0x3f32, 0x3f33, 0x3f33, 
+    0x3f33, 0x3f34, 0x3f34, 0x3f34, 0x3f34, 0x3f35, 0x3f35, 0x3f35, 
+    0x3f36, 0x3f36, 0x3f36, 0x3f37, 0x3f37, 0x3f37, 0x3f38, 0x3f38, 
+    0x3f38, 0x3f38, 0x3f39, 0x3f39, 0x3f39, 0x3f3a, 0x3f3a, 0x3f3a, 
+    0x3f3b, 0x3f3b, 0x3f3b, 0x3f3c, 0x3f3c, 0x3f3c, 0x3f3c, 0x3f3d, 
+    0x3f3d, 0x3f3d, 0x3f3e, 0x3f3e, 0x3f3e, 0x3f3f, 0x3f3f, 0x3f3f, 
+    0x3f40, 0x3f40, 0x3f40, 0x3f40, 0x3f41, 0x3f41, 0x3f41, 0x3f42, 
+    0x3f42, 0x3f42, 0x3f43, 0x3f43, 0x3f43, 0x3f43, 0x3f44, 0x3f44, 
+    0x3f44, 0x3f45, 0x3f45, 0x3f45, 0x3f46, 0x3f46, 0x3f46, 0x3f47, 
+    0x3f47, 0x3f47, 0x3f47, 0x3f48, 0x3f48, 0x3f48, 0x3f49, 0x3f49, 
+    0x3f49, 0x3f49, 0x3f4a, 0x3f4a, 0x3f4a, 0x3f4b, 0x3f4b, 0x3f4b, 
+    0x3f4c, 0x3f4c, 0x3f4c, 0x3f4c, 0x3f4d, 0x3f4d, 0x3f4d, 0x3f4e, 
+    0x3f4e, 0x3f4e, 0x3f4f, 0x3f4f, 0x3f4f, 0x3f4f, 0x3f50, 0x3f50, 
+    0x3f50, 0x3f51, 0x3f51, 0x3f51, 0x3f51, 0x3f52, 0x3f52, 0x3f52, 
+    0x3f53, 0x3f53, 0x3f53, 0x3f54, 0x3f54, 0x3f54, 0x3f54, 0x3f55, 
+    0x3f55, 0x3f55, 0x3f56, 0x3f56, 0x3f56, 0x3f56, 0x3f57, 0x3f57, 
+    0x3f57, 0x3f58, 0x3f58, 0x3f58, 0x3f58, 0x3f59, 0x3f59, 0x3f59, 
+    0x3f5a, 0x3f5a, 0x3f5a, 0x3f5a, 0x3f5b, 0x3f5b, 0x3f5b, 0x3f5c, 
+    0x3f5c, 0x3f5c, 0x3f5c, 0x3f5d, 0x3f5d, 0x3f5d, 0x3f5e, 0x3f5e, 
+    0x3f5e, 0x3f5e, 0x3f5f, 0x3f5f, 0x3f5f, 0x3f60, 0x3f60, 0x3f60, 
+    0x3f60, 0x3f61, 0x3f61, 0x3f61, 0x3f62, 0x3f62, 0x3f62, 0x3f62, 
+    0x3f63, 0x3f63, 0x3f63, 0x3f64, 0x3f64, 0x3f64, 0x3f64, 0x3f65, 
+    0x3f65, 0x3f65, 0x3f66, 0x3f66, 0x3f66, 0x3f66, 0x3f67, 0x3f67, 
+    0x3f67, 0x3f68, 0x3f68, 0x3f68, 0x3f68, 0x3f69, 0x3f69, 0x3f69, 
+    0x3f69, 0x3f6a, 0x3f6a, 0x3f6a, 0x3f6b, 0x3f6b, 0x3f6b, 0x3f6b, 
+    0x3f6c, 0x3f6c, 0x3f6c, 0x3f6d, 0x3f6d, 0x3f6d, 0x3f6d, 0x3f6e, 
+    0x3f6e, 0x3f6e, 0x3f6e, 0x3f6f, 0x3f6f, 0x3f6f, 0x3f70, 0x3f70, 
+    0x3f70, 0x3f70, 0x3f71, 0x3f71, 0x3f71, 0x3f71, 0x3f72, 0x3f72, 
+    0x3f72, 0x3f73, 0x3f73, 0x3f73, 0x3f73, 0x3f74, 0x3f74, 0x3f74, 
+    0x3f74, 0x3f75, 0x3f75, 0x3f75, 0x3f76, 0x3f76, 0x3f76, 0x3f76, 
+    0x3f77, 0x3f77, 0x3f77, 0x3f77, 0x3f78, 0x3f78, 0x3f78, 0x3f79, 
+    0x3f79, 0x3f79, 0x3f79, 0x3f7a, 0x3f7a, 0x3f7a, 0x3f7a, 0x3f7b, 
+    0x3f7b, 0x3f7b, 0x3f7b, 0x3f7c, 0x3f7c, 0x3f7c, 0x3f7d, 0x3f7d, 
+    0x3f7d, 0x3f7d, 0x3f7e, 0x3f7e, 0x3f7e, 0x3f7e, 0x3f7f, 0x3f7f, 
+    0x3f7f, 0x3f7f, 0x3f80, 0x3f80, 0x3f80, 0x3f81, 0x3f81, 0x3f81, 
+    0x3f81, 0x3f82, 0x3f82, 0x3f82, 0x3f82, 0x3f83, 0x3f83, 0x3f83, 
+    0x3f83, 0x3f84, 0x3f84, 0x3f84, 0x3f85, 0x3f85, 0x3f85, 0x3f85, 
+    0x3f86, 0x3f86, 0x3f86, 0x3f86, 0x3f87, 0x3f87, 0x3f87, 0x3f87, 
+    0x3f88, 0x3f88, 0x3f88, 0x3f88, 0x3f89, 0x3f89, 0x3f89, 0x3f89, 
+    0x3f8a, 0x3f8a, 0x3f8a, 0x3f8b, 0x3f8b, 0x3f8b, 0x3f8b, 0x3f8c, 
+    0x3f8c, 0x3f8c, 0x3f8c, 0x3f8d, 0x3f8d, 0x3f8d, 0x3f8d, 0x3f8e, 
+    0x3f8e, 0x3f8e, 0x3f8e, 0x3f8f, 0x3f8f, 0x3f8f, 0x3f8f, 0x3f90, 
+    0x3f90, 0x3f90, 0x3f90, 0x3f91, 0x3f91, 0x3f91, 0x3f91, 0x3f92, 
+    0x3f92, 0x3f92, 0x3f92, 0x3f93, 0x3f93, 0x3f93, 0x3f93, 0x3f94, 
+    0x3f94, 0x3f94, 0x3f95, 0x3f95, 0x3f95, 0x3f95, 0x3f96, 0x3f96, 
+    0x3f96, 0x3f96, 0x3f97, 0x3f97, 0x3f97, 0x3f97, 0x3f98, 0x3f98, 
+    0x3f98, 0x3f98, 0x3f99, 0x3f99, 0x3f99, 0x3f99, 0x3f9a, 0x3f9a, 
+    0x3f9a, 0x3f9a, 0x3f9b, 0x3f9b, 0x3f9b, 0x3f9b, 0x3f9c, 0x3f9c, 
+    0x3f9c, 0x3f9c, 0x3f9d, 0x3f9d, 0x3f9d, 0x3f9d, 0x3f9e, 0x3f9e, 
+    0x3f9e, 0x3f9e, 0x3f9f, 0x3f9f, 0x3f9f, 0x3f9f, 0x3fa0, 0x3fa0, 
+    0x3fa0, 0x3fa0, 0x3fa1, 0x3fa1, 0x3fa1, 0x3fa1, 0x3fa2, 0x3fa2, 
+    0x3fa2, 0x3fa2, 0x3fa3, 0x3fa3, 0x3fa3, 0x3fa3, 0x3fa3, 0x3fa4, 
+    0x3fa4, 0x3fa4, 0x3fa4, 0x3fa5, 0x3fa5, 0x3fa5, 0x3fa5, 0x3fa6, 
+    0x3fa6, 0x3fa6, 0x3fa6, 0x3fa7, 0x3fa7, 0x3fa7, 0x3fa7, 0x3fa8, 
+    0x3fa8, 0x3fa8, 0x3fa8, 0x3fa9, 0x3fa9, 0x3fa9, 0x3fa9, 0x3faa, 
+    0x3faa, 0x3faa, 0x3faa, 0x3fab, 0x3fab, 0x3fab, 0x3fab, 0x3fac, 
+    0x3fac, 0x3fac, 0x3fac, 0x3fad, 0x3fad, 0x3fad, 0x3fad, 0x3fad, 
+    0x3fae, 0x3fae, 0x3fae, 0x3fae, 0x3faf, 0x3faf, 0x3faf, 0x3faf, 
+    0x3fb0, 0x3fb0, 0x3fb0, 0x3fb0, 0x3fb1, 0x3fb1, 0x3fb1, 0x3fb1, 
+    0x3fb2, 0x3fb2, 0x3fb2, 0x3fb2, 0x3fb2, 0x3fb3, 0x3fb3, 0x3fb3, 
+    0x3fb3, 0x3fb4, 0x3fb4, 0x3fb4, 0x3fb4, 0x3fb5, 0x3fb5, 0x3fb5, 
+    0x3fb5, 0x3fb6, 0x3fb6, 0x3fb6, 0x3fb6, 0x3fb7, 0x3fb7, 0x3fb7, 
+    0x3fb7, 0x3fb7, 0x3fb8, 0x3fb8, 0x3fb8, 0x3fb8, 0x3fb9, 0x3fb9, 
+    0x3fb9, 0x3fb9, 0x3fba, 0x3fba, 0x3fba, 0x3fba, 0x3fbb, 0x3fbb, 
+    0x3fbb, 0x3fbb, 0x3fbb, 0x3fbc, 0x3fbc, 0x3fbc, 0x3fbc, 0x3fbd, 
+    0x3fbd, 0x3fbd, 0x3fbd, 0x3fbe, 0x3fbe, 0x3fbe, 0x3fbe, 0x3fbe, 
+    0x3fbf, 0x3fbf, 0x3fbf, 0x3fbf, 0x3fc0, 0x3fc0, 0x3fc0, 0x3fc0, 
+    0x3fc1, 0x3fc1, 0x3fc1, 0x3fc1, 0x3fc1, 0x3fc2, 0x3fc2, 0x3fc2, 
+    0x3fc2, 0x3fc3, 0x3fc3, 0x3fc3, 0x3fc3, 0x3fc4, 0x3fc4, 0x3fc4, 
+    0x3fc4, 0x3fc4, 0x3fc5, 0x3fc5, 0x3fc5, 0x3fc5, 0x3fc6, 0x3fc6, 
+    0x3fc6, 0x3fc6, 0x3fc7, 0x3fc7, 0x3fc7, 0x3fc7, 0x3fc7, 0x3fc8, 
+    0x3fc8, 0x3fc8, 0x3fc9, 0x3fc9, 0x3fca, 0x3fca, 0x3fcb, 0x3fcb, 
+    0x3fcc, 0x3fcc, 0x3fcc, 0x3fcd, 0x3fcd, 0x3fce, 0x3fce, 0x3fcf, 
+    0x3fcf, 0x3fd0, 0x3fd0, 0x3fd0, 0x3fd1, 0x3fd1, 0x3fd2, 0x3fd2, 
+    0x3fd3, 0x3fd3, 0x3fd4, 0x3fd4, 0x3fd4, 0x3fd5, 0x3fd5, 0x3fd6, 
+    0x3fd6, 0x3fd7, 0x3fd7, 0x3fd8, 0x3fd8, 0x3fd8, 0x3fd9, 0x3fd9, 
+    0x3fda, 0x3fda, 0x3fdb, 0x3fdb, 0x3fdb, 0x3fdc, 0x3fdc, 0x3fdd, 
+    0x3fdd, 0x3fde, 0x3fde, 0x3fdf, 0x3fdf, 0x3fdf, 0x3fe0, 0x3fe0, 
+    0x3fe1, 0x3fe1, 0x3fe2, 0x3fe2, 0x3fe2, 0x3fe3, 0x3fe3, 0x3fe4, 
+    0x3fe4, 0x3fe5, 0x3fe5, 0x3fe5, 0x3fe6, 0x3fe6, 0x3fe7, 0x3fe7, 
+    0x3fe8, 0x3fe8, 0x3fe8, 0x3fe9, 0x3fe9, 0x3fea, 0x3fea, 0x3fea, 
+    0x3feb, 0x3feb, 0x3fec, 0x3fec, 0x3fed, 0x3fed, 0x3fed, 0x3fee, 
+    0x3fee, 0x3fef, 0x3fef, 0x3ff0, 0x3ff0, 0x3ff0, 0x3ff1, 0x3ff1, 
+    0x3ff2, 0x3ff2, 0x3ff2, 0x3ff3, 0x3ff3, 0x3ff4, 0x3ff4, 0x3ff4, 
+    0x3ff5, 0x3ff5, 0x3ff6, 0x3ff6, 0x3ff7, 0x3ff7, 0x3ff7, 0x3ff8, 
+    0x3ff8, 0x3ff9, 0x3ff9, 0x3ff9, 0x3ffa, 0x3ffa, 0x3ffb, 0x3ffb, 
+    0x3ffb, 0x3ffc, 0x3ffc, 0x3ffd, 0x3ffd, 0x3ffd, 0x3ffe, 0x3ffe, 
+    0x3fff, 0x3fff, 0x4000, 0x4000, 0x4000, 0x4000, 0x4001, 0x4001, 
+    0x4001, 0x4001, 0x4001, 0x4002, 0x4002, 0x4002, 0x4002, 0x4002, 
+    0x4003, 0x4003, 0x4003, 0x4003, 0x4003, 0x4004, 0x4004, 0x4004, 
+    0x4004, 0x4004, 0x4005, 0x4005, 0x4005, 0x4005, 0x4005, 0x4006, 
+    0x4006, 0x4006, 0x4006, 0x4006, 0x4007, 0x4007, 0x4007, 0x4007, 
+    0x4007, 0x4007, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4009, 
+    0x4009, 0x4009, 0x4009, 0x4009, 0x400a, 0x400a, 0x400a, 0x400a, 
+    0x400a, 0x400b, 0x400b, 0x400b, 0x400b, 0x400b, 0x400c, 0x400c, 
+    0x400c, 0x400c, 0x400c, 0x400d, 0x400d, 0x400d, 0x400d, 0x400d, 
+    0x400d, 0x400e, 0x400e, 0x400e, 0x400e, 0x400e, 0x400f, 0x400f, 
+    0x400f, 0x400f, 0x400f, 0x4010, 0x4010, 0x4010, 0x4010, 0x4010, 
+    0x4010, 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, 0x4012, 0x4012, 
+    0x4012, 0x4012, 0x4012, 0x4013, 0x4013, 0x4013, 0x4013, 0x4013, 
+    0x4013, 0x4014, 0x4014, 0x4014, 0x4014, 0x4014, 0x4015, 0x4015, 
+    0x4015, 0x4015, 0x4015, 0x4015, 0x4016, 0x4016, 0x4016, 0x4016, 
+    0x4016, 0x4017, 0x4017, 0x4017, 0x4017, 0x4017, 0x4018, 0x4018, 
+    0x4018, 0x4018, 0x4018, 0x4018, 0x4019, 0x4019, 0x4019, 0x4019, 
+    0x4019, 0x401a, 0x401a, 0x401a, 0x401a, 0x401a, 0x401a, 0x401b, 
+    0x401b, 0x401b, 0x401b, 0x401b, 0x401b, 0x401c, 0x401c, 0x401c, 
+    0x401c, 0x401c, 0x401d, 0x401d, 0x401d, 0x401d, 0x401d, 0x401d, 
+    0x401e, 0x401e, 0x401e, 0x401e, 0x401e, 0x401f, 0x401f, 0x401f, 
+    0x401f, 0x401f, 0x401f, 0x4020, 0x4020, 0x4020, 0x4020, 0x4020, 
+    0x4020, 0x4021, 0x4021, 0x4021, 0x4021, 0x4021, 0x4021, 0x4022, 
+    0x4022, 0x4022, 0x4022, 0x4022, 0x4023, 0x4023, 0x4023, 0x4023, 
+    0x4023, 0x4023, 0x4024, 0x4024, 0x4024, 0x4024, 0x4024, 0x4024, 
+    0x4025, 0x4025, 0x4025, 0x4025, 0x4025, 0x4025, 0x4026, 0x4026, 
+    0x4026, 0x4026, 0x4026, 0x4026, 0x4027, 0x4027, 0x4027, 0x4027, 
+    0x4027, 0x4028, 0x4028, 0x4028, 0x4028, 0x4028, 0x4028, 0x4029, 
+    0x4029, 0x4029, 0x4029, 0x4029, 0x4029, 0x402a, 0x402a, 0x402a, 
+    0x402a, 0x402a, 0x402a, 0x402b, 0x402b, 0x402b, 0x402b, 0x402b, 
+    0x402b, 0x402c, 0x402c, 0x402c, 0x402c, 0x402c, 0x402c, 0x402d, 
+    0x402d, 0x402d, 0x402d, 0x402d, 0x402d, 0x402e, 0x402e, 0x402e, 
+    0x402e, 0x402e, 0x402e, 0x402f, 0x402f, 0x402f, 0x402f, 0x402f, 
+    0x402f, 0x4030, 0x4030, 0x4030, 0x4030, 0x4030, 0x4030, 0x4031, 
+    0x4031, 0x4031, 0x4031, 0x4031, 0x4031, 0x4032, 0x4032, 0x4032, 
+    0x4032, 0x4032, 0x4032, 0x4032, 0x4033, 0x4033, 0x4033, 0x4033, 
+    0x4033, 0x4033, 0x4034, 0x4034, 0x4034, 0x4034, 0x4034, 0x4034, 
+    0x4035, 0x4035, 0x4035, 0x4035, 0x4035, 0x4035, 0x4036, 0x4036, 
+    0x4036, 0x4036, 0x4036, 0x4036, 0x4036, 0x4037, 0x4037, 0x4037, 
+    0x4037, 0x4037, 0x4037, 0x4038, 0x4038, 0x4038, 0x4038, 0x4038, 
+    0x4038, 0x4039, 0x4039, 0x4039, 0x4039, 0x4039, 0x4039, 0x403a, 
+    0x403a, 0x403a, 0x403a, 0x403a, 0x403a, 0x403a, 0x403b, 0x403b, 
+    0x403b, 0x403b, 0x403b, 0x403b, 0x403c, 0x403c, 0x403c, 0x403c, 
+    0x403c, 0x403c, 0x403c, 0x403d, 0x403d, 0x403d, 0x403d, 0x403d, 
+    0x403d, 0x403e, 0x403e, 0x403e, 0x403e, 0x403e, 0x403e, 0x403e, 
+    0x403f, 0x403f, 0x403f, 0x403f, 0x403f, 0x403f, 0x4040, 0x4040, 
+    0x4040, 0x4040, 0x4040, 0x4040, 0x4040, 0x4041, 0x4041, 0x4041, 
+    0x4041, 0x4041, 0x4041, 0x4042, 0x4042, 0x4042, 0x4042, 0x4042, 
+    0x4042, 0x4042, 0x4043, 0x4043, 0x4043, 0x4043, 0x4043, 0x4043, 
+    0x4044, 0x4044, 0x4044, 0x4044, 0x4044, 0x4044, 0x4044, 0x4045, 
+    0x4045, 0x4045, 0x4045, 0x4045, 0x4045, 0x4045, 0x4046, 0x4046, 
+    0x4046, 0x4046, 0x4046, 0x4046, 0x4047, 0x4047, 0x4047, 0x4047, 
+    0x4047, 0x4047, 0x4047, 0x4048, 0x4048, 0x4048, 0x4048, 0x4048, 
+    0x4048, 0x4048, 0x4049, 0x4049, 0x4049, 0x4049, 0x4049, 0x4049, 
+    0x4049, 0x404a, 0x404a, 0x404a, 0x404a, 0x404a, 0x404a, 0x404a, 
+    0x404b, 0x404b, 0x404b, 0x404b, 0x404b, 0x404b, 0x404c, 0x404c, 
+    0x404c, 0x404c, 0x404c, 0x404c, 0x404c, 0x404d, 0x404d, 0x404d, 
+    0x404d, 0x404d, 0x404d, 0x404d, 0x404e, 0x404e, 0x404e, 0x404e, 
+    0x404e, 0x404e, 0x404e, 0x404f, 0x404f, 0x404f, 0x404f, 0x404f, 
+    0x404f, 0x404f, 0x4050, 0x4050, 0x4050, 0x4050, 0x4050, 0x4050, 
+    0x4050, 0x4051, 0x4051, 0x4051, 0x4051, 0x4051, 0x4051, 0x4051, 
+    0x4052, 0x4052, 0x4052, 0x4052, 0x4052, 0x4052, 0x4052, 0x4053, 
+    0x4053, 0x4053, 0x4053, 0x4053, 0x4053, 0x4053, 0x4054, 0x4054, 
+    0x4054, 0x4054, 0x4054, 0x4054, 0x4054, 0x4055, 0x4055, 0x4055, 
+    0x4055, 0x4055, 0x4055, 0x4055, 0x4055, 0x4056, 0x4056, 0x4056, 
+    0x4056, 0x4056, 0x4056, 0x4056, 0x4057, 0x4057, 0x4057, 0x4057, 
+    0x4057, 0x4057, 0x4057, 0x4058, 0x4058, 0x4058, 0x4058, 0x4058, 
+    0x4058, 0x4058, 0x4059, 0x4059, 0x4059, 0x4059, 0x4059, 0x4059, 
+    0x4059, 0x405a, 0x405a, 0x405a, 0x405a, 0x405a, 0x405a, 0x405a, 
+    0x405a, 0x405b, 0x405b, 0x405b, 0x405b, 0x405b, 0x405b, 0x405b, 
+    0x405c, 0x405c, 0x405c, 0x405c, 0x405c, 0x405c, 0x405c, 0x405d, 
+    0x405d, 0x405d, 0x405d, 0x405d, 0x405d, 0x405d, 0x405d, 0x405e, 
+    0x405e, 0x405e, 0x405e, 0x405e, 0x405e, 0x405e, 0x405f, 0x405f, 
+    0x405f, 0x405f, 0x405f, 0x405f, 0x405f, 0x405f, 0x4060, 0x4060, 
+    0x4060, 0x4060, 0x4060, 0x4060, 0x4060, 0x4061, 0x4061, 0x4061, 
+    0x4061, 0x4061, 0x4061, 0x4061, 0x4061, 0x4062, 0x4062, 0x4062, 
+    0x4062, 0x4062, 0x4062, 0x4062, 0x4063, 0x4063, 0x4063, 0x4063, 
+    0x4063, 0x4063, 0x4063, 0x4063, 0x4064, 0x4064, 0x4064, 0x4064, 
+    0x4064, 0x4064, 0x4064, 0x4064, 0x4065, 0x4065, 0x4065, 0x4065, 
+    0x4065, 0x4065, 0x4065, 0x4066, 0x4066, 0x4066, 0x4066, 0x4066, 
+    0x4066, 0x4066, 0x4066, 0x4067, 0x4067, 0x4067, 0x4067, 0x4067, 
+    0x4067, 0x4067, 0x4067, 0x4068, 0x4068, 0x4068, 0x4068, 0x4068, 
+    0x4068, 0x4068, 0x4069, 0x4069, 0x4069, 0x4069, 0x4069, 0x4069, 
+    0x4069, 0x4069, 0x406a, 0x406a, 0x406a, 0x406a, 0x406a, 0x406a, 
+    0x406a, 0x406a, 0x406b, 0x406b, 0x406b, 0x406b, 0x406b, 0x406b, 
+    0x406b, 0x406b, 0x406c, 0x406c, 0x406c, 0x406c, 0x406c, 0x406c, 
+    0x406c, 0x406c, 0x406d, 0x406d, 0x406d, 0x406d, 0x406d, 0x406d, 
+    0x406d, 0x406d, 0x406e, 0x406e, 0x406e, 0x406e, 0x406e, 0x406e, 
+    0x406e, 0x406e, 0x406f, 0x406f, 0x406f, 0x406f, 0x406f, 0x406f, 
+    0x406f, 0x406f, 0x4070, 0x4070, 0x4070, 0x4070, 0x4070, 0x4070, 
+    0x4070, 0x4070, 0x4071, 0x4071, 0x4071, 0x4071, 0x4071, 0x4071, 
+    0x4071, 0x4071, 0x4072, 0x4072, 0x4072, 0x4072, 0x4072, 0x4072, 
+    0x4072, 0x4072, 0x4073, 0x4073, 0x4073, 0x4073, 0x4073, 0x4073, 
+    0x4073, 0x4073, 0x4074, 0x4074, 0x4074, 0x4074, 0x4074, 0x4074, 
+    0x4074, 0x4074, 0x4075, 0x4075, 0x4075, 0x4075, 0x4075, 0x4075, 
+    0x4075, 0x4075, 0x4076, 0x4076, 0x4076, 0x4076, 0x4076, 0x4076, 
+    0x4076, 0x4076, 0x4076, 0x4077, 0x4077, 0x4077, 0x4077, 0x4077, 
+    0x4077, 0x4077, 0x4077, 0x4078, 0x4078, 0x4078, 0x4078, 0x4078, 
+    0x4078, 0x4078, 0x4078, 0x4079, 0x4079, 0x4079, 0x4079, 0x4079, 
+    0x4079, 0x4079, 0x4079, 0x4079, 0x407a, 0x407a, 0x407a, 0x407a, 
+    0x407a, 0x407a, 0x407a, 0x407a, 0x407b, 0x407b, 0x407b, 0x407b, 
+    0x407b, 0x407b, 0x407b, 0x407b, 0x407c, 0x407c, 0x407c, 0x407c, 
+    0x407c, 0x407c, 0x407c, 0x407c, 0x407c, 0x407d, 0x407d, 0x407d, 
+    0x407d, 0x407d, 0x407d, 0x407d, 0x407d, 0x407e, 0x407e, 0x407e, 
+    0x407e, 0x407e, 0x407e, 0x407e, 0x407e, 0x407e, 0x407f, 0x407f, 
+    0x407f, 0x407f, 0x407f, 0x407f, 0x407f, 0x407f, 0x4080, 0x4080, 
+    0x4080, 0x4080, 0x4080, 0x4080, 0x4080, 0x4080, 0x4080, 0x4081, 
+    0x4081, 0x4081, 0x4081, 0x4081, 0x4081, 0x4081, 0x4081, 0x4081, 
+    0x4082, 0x4082, 0x4082, 0x4082, 0x4082, 0x4082, 0x4082, 0x4082, 
+    0x4083, 0x4083, 0x4083, 0x4083, 0x4083, 0x4083, 0x4083, 0x4083, 
+    0x4083, 0x4084, 0x4084, 0x4084, 0x4084, 0x4084, 0x4084, 0x4084, 
+    0x4084, 0x4084, 0x4085, 0x4085, 0x4085, 0x4085, 0x4085, 0x4085, 
+    0x4085, 0x4085, 0x4086, 0x4086, 0x4086, 0x4086, 0x4087, 0x4087, 
+    0x4087, 0x4087, 0x4088, 0x4088, 0x4088, 0x4088, 0x4088, 0x4089, 
+    0x4089, 0x4089, 0x4089, 0x408a, 0x408a, 0x408a, 0x408a, 0x408a, 
+    0x408b, 0x408b, 0x408b, 0x408b, 0x408c, 0x408c, 0x408c, 0x408c, 
+    0x408c, 0x408d, 0x408d, 0x408d, 0x408d, 0x408e, 0x408e, 0x408e, 
+    0x408e, 0x408e, 0x408f, 0x408f, 0x408f, 0x408f, 0x408f, 0x4090, 
+    0x4090, 0x4090, 0x4090, 0x4091, 0x4091, 0x4091, 0x4091, 0x4091, 
+    0x4092, 0x4092, 0x4092, 0x4092, 0x4093, 0x4093, 0x4093, 0x4093, 
+    0x4093, 0x4094, 0x4094, 0x4094, 0x4094, 0x4094, 0x4095, 0x4095, 
+    0x4095, 0x4095, 0x4095, 0x4096, 0x4096, 0x4096, 0x4096, 0x4097, 
+    0x4097, 0x4097, 0x4097, 0x4097, 0x4098, 0x4098, 0x4098, 0x4098, 
+    0x4098, 0x4099, 0x4099, 0x4099, 0x4099, 0x4099, 0x409a, 0x409a, 
+    0x409a, 0x409a, 0x409b, 0x409b, 0x409b, 0x409b, 0x409b, 0x409c, 
+    0x409c, 0x409c, 0x409c, 0x409c, 0x409d, 0x409d, 0x409d, 0x409d, 
+    0x409d, 0x409e, 0x409e, 0x409e, 0x409e, 0x409e, 0x409f, 0x409f, 
+    0x409f, 0x409f, 0x409f, 0x40a0, 0x40a0, 0x40a0, 0x40a0, 0x40a0, 
+    0x40a1, 0x40a1, 0x40a1, 0x40a1, 0x40a1, 0x40a2, 0x40a2, 0x40a2, 
+    0x40a2, 0x40a2, 0x40a3, 0x40a3, 0x40a3, 0x40a3, 0x40a3, 0x40a4, 
+    0x40a4, 0x40a4, 0x40a4, 0x40a4, 0x40a5, 0x40a5, 0x40a5, 0x40a5, 
+    0x40a5, 0x40a6, 0x40a6, 0x40a6, 0x40a6, 0x40a6, 0x40a7, 0x40a7, 
+    0x40a7, 0x40a7, 0x40a7, 0x40a8, 0x40a8, 0x40a8, 0x40a8, 0x40a8, 
+    0x40a9, 0x40a9, 0x40a9, 0x40a9, 0x40a9, 0x40aa, 0x40aa, 0x40aa, 
+    0x40aa, 0x40aa, 0x40ab, 0x40ab, 0x40ab, 0x40ab, 0x40ab, 0x40ac, 
+    0x40ac, 0x40ac, 0x40ac, 0x40ac, 0x40ac, 0x40ad, 0x40ad, 0x40ad, 
+    0x40ad, 0x40ad, 0x40ae, 0x40ae, 0x40ae, 0x40ae, 0x40ae, 0x40af, 
+    0x40af, 0x40af, 0x40af, 0x40af, 0x40b0, 0x40b0, 0x40b0, 0x40b0, 
+    0x40b0, 0x40b0, 0x40b1, 0x40b1, 0x40b1, 0x40b1, 0x40b1, 0x40b2, 
+    0x40b2, 0x40b2, 0x40b2, 0x40b2, 0x40b3, 0x40b3, 0x40b3, 0x40b3, 
+    0x40b3, 0x40b3, 0x40b4, 0x40b4, 0x40b4, 0x40b4, 0x40b4, 0x40b5, 
+    0x40b5, 0x40b5, 0x40b5, 0x40b5, 0x40b6, 0x40b6, 0x40b6, 0x40b6, 
+    0x40b6, 0x40b6, 0x40b7, 0x40b7, 0x40b7, 0x40b7, 0x40b7, 0x40b8, 
+    0x40b8, 0x40b8, 0x40b8, 0x40b8, 0x40b8, 0x40b9, 0x40b9, 0x40b9, 
+    0x40b9, 0x40b9, 0x40ba, 0x40ba, 0x40ba, 0x40ba, 0x40ba, 0x40ba, 
+    0x40bb, 0x40bb, 0x40bb, 0x40bb, 0x40bb, 0x40bc, 0x40bc, 0x40bc, 
+    0x40bc, 0x40bc, 0x40bc, 0x40bd, 0x40bd, 0x40bd, 0x40bd, 0x40bd, 
+    0x40be, 0x40be, 0x40be, 0x40be, 0x40be, 0x40be, 0x40bf, 0x40bf, 
+    0x40bf, 0x40bf, 0x40bf, 0x40bf, 0x40c0, 0x40c0, 0x40c0, 0x40c0, 
+    0x40c0, 0x40c1, 0x40c1, 0x40c1, 0x40c1, 0x40c1, 0x40c1, 0x40c2, 
+    0x40c2, 0x40c2, 0x40c2, 0x40c2, 0x40c2, 0x40c3, 0x40c3, 0x40c3, 
+    0x40c3, 0x40c3, 0x40c4, 0x40c4, 0x40c4, 0x40c4, 0x40c4, 0x40c4, 
+    0x40c5, 0x40c5, 0x40c5, 0x40c5, 0x40c5, 0x40c5, 0x40c6, 0x40c6, 
+    0x40c6, 0x40c6, 0x40c6, 0x40c6, 0x40c7, 0x40c7, 0x40c7, 0x40c7, 
+    0x40c7, 0x40c7, 0x40c8, 0x40c8, 0x40c8, 0x40c8, 0x40c8, 0x40c8, 
+    0x40c9, 0x40c9, 0x40c9, 0x40c9, 0x40c9, 0x40ca, 0x40ca, 0x40ca, 
+    0x40ca, 0x40ca, 0x40ca, 0x40cb, 0x40cb, 0x40cb, 0x40cb, 0x40cb, 
+    0x40cb, 0x40cc, 0x40cc, 0x40cc, 0x40cc, 0x40cc, 0x40cc, 0x40cd, 
+    0x40cd, 0x40cd, 0x40cd, 0x40cd, 0x40cd, 0x40ce, 0x40ce, 0x40ce, 
+    0x40ce, 0x40ce, 0x40ce, 0x40cf, 0x40cf, 0x40cf, 0x40cf, 0x40cf, 
+    0x40cf, 0x40d0, 0x40d0, 0x40d0, 0x40d0, 0x40d0, 0x40d0, 0x40d1, 
+    0x40d1, 0x40d1, 0x40d1, 0x40d1, 0x40d1, 0x40d2, 0x40d2, 0x40d2, 
+    0x40d2, 0x40d2, 0x40d2, 0x40d2, 0x40d3, 0x40d3, 0x40d3, 0x40d3, 
+    0x40d3, 0x40d3, 0x40d4, 0x40d4, 0x40d4, 0x40d4, 0x40d4, 0x40d4, 
+    0x40d5, 0x40d5, 0x40d5, 0x40d5, 0x40d5, 0x40d5, 0x40d6, 0x40d6, 
+    0x40d6, 0x40d6, 0x40d6, 0x40d6, 0x40d7, 0x40d7, 0x40d7, 0x40d7, 
+    0x40d7, 0x40d7, 0x40d7, 0x40d8, 0x40d8, 0x40d8, 0x40d8, 0x40d8, 
+    0x40d8, 0x40d9, 0x40d9, 0x40d9, 0x40d9, 0x40d9, 0x40d9, 0x40da, 
+    0x40da, 0x40da, 0x40da, 0x40da, 0x40da, 0x40db, 0x40db, 0x40db, 
+    0x40db, 0x40db, 0x40db, 0x40db, 0x40dc, 0x40dc, 0x40dc, 0x40dc, 
+    0x40dc, 0x40dc, 0x40dd, 0x40dd, 0x40dd, 0x40dd, 0x40dd, 0x40dd, 
+    0x40dd, 0x40de, 0x40de, 0x40de, 0x40de, 0x40de, 0x40de, 0x40df, 
+    0x40df, 0x40df, 0x40df, 0x40df, 0x40df, 0x40df, 0x40e0, 0x40e0, 
+    0x40e0, 0x40e0, 0x40e0, 0x40e0, 0x40e1, 0x40e1, 0x40e1, 0x40e1, 
+    0x40e1, 0x40e1, 0x40e1, 0x40e2, 0x40e2, 0x40e2, 0x40e2, 0x40e2, 
+    0x40e2, 0x40e3, 0x40e3, 0x40e3, 0x40e3, 0x40e3, 0x40e3, 0x40e3, 
+    0x40e4, 0x40e4, 0x40e4, 0x40e4, 0x40e4, 0x40e4, 0x40e5, 0x40e5, 
+    0x40e5, 0x40e5, 0x40e5, 0x40e5, 0x40e5, 0x40e6, 0x40e6, 0x40e6, 
+    0x40e6, 0x40e6, 0x40e6, 0x40e6, 0x40e7, 0x40e7, 0x40e7, 0x40e7, 
+    0x40e7, 0x40e7, 0x40e8, 0x40e8, 0x40e8, 0x40e8, 0x40e8, 0x40e8, 
+    0x40e8, 0x40e9, 0x40e9, 0x40e9, 0x40e9, 0x40e9, 0x40e9, 0x40e9, 
+    0x40ea, 0x40ea, 0x40ea, 0x40ea, 0x40ea, 0x40ea, 0x40ea, 0x40eb, 
+    0x40eb, 0x40eb, 0x40eb, 0x40eb, 0x40eb, 0x40ec, 0x40ec, 0x40ec, 
+    0x40ec, 0x40ec, 0x40ec, 0x40ec, 0x40ed, 0x40ed, 0x40ed, 0x40ed, 
+    0x40ed, 0x40ed, 0x40ed, 0x40ee, 0x40ee, 0x40ee, 0x40ee, 0x40ee, 
+    0x40ee, 0x40ee, 0x40ef, 0x40ef, 0x40ef, 0x40ef, 0x40ef, 0x40ef, 
+    0x40ef, 0x40f0, 0x40f0, 0x40f0, 0x40f0, 0x40f0, 0x40f0, 0x40f0, 
+    0x40f1, 0x40f1, 0x40f1, 0x40f1, 0x40f1, 0x40f1, 0x40f1, 0x40f2, 
+    0x40f2, 0x40f2, 0x40f2, 0x40f2, 0x40f2, 0x40f2, 0x40f3, 0x40f3, 
+    0x40f3, 0x40f3, 0x40f3, 0x40f3, 0x40f3, 0x40f4, 0x40f4, 0x40f4, 
+    0x40f4, 0x40f4, 0x40f4, 0x40f4, 0x40f5, 0x40f5, 0x40f5, 0x40f5, 
+    0x40f5, 0x40f5, 0x40f5, 0x40f6, 0x40f6, 0x40f6, 0x40f6, 0x40f6, 
+    0x40f6, 0x40f6, 0x40f7, 0x40f7, 0x40f7, 0x40f7, 0x40f7, 0x40f7, 
+    0x40f7, 0x40f8, 0x40f8, 0x40f8, 0x40f8, 0x40f8, 0x40f8, 0x40f8, 
+    0x40f8, 0x40f9, 0x40f9, 0x40f9, 0x40f9, 0x40f9, 0x40f9, 0x40f9, 
+    0x40fa, 0x40fa, 0x40fa, 0x40fa, 0x40fa, 0x40fa, 0x40fa, 0x40fb, 
+    0x40fb, 0x40fb, 0x40fb, 0x40fb, 0x40fb, 0x40fb, 0x40fc, 0x40fc, 
+    0x40fc, 0x40fc, 0x40fc, 0x40fc, 0x40fc, 0x40fc, 0x40fd, 0x40fd, 
+    0x40fd, 0x40fd, 0x40fd, 0x40fd, 0x40fd, 0x40fe, 0x40fe, 0x40fe, 
+    0x40fe, 0x40fe, 0x40fe, 0x40fe, 0x40fe, 0x40ff, 0x40ff, 0x40ff, 
+    0x40ff, 0x40ff, 0x40ff, 0x40ff, 0x4100, 0x4100, 0x4100, 0x4100, 
+    0x4100, 0x4100, 0x4100, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 
+    0x4101, 0x4101, 0x4101, 0x4102, 0x4102, 0x4102, 0x4102, 0x4102, 
+    0x4102, 0x4102, 0x4103, 0x4103, 0x4103, 0x4103, 0x4103, 0x4103, 
+    0x4103, 0x4103, 0x4104, 0x4104, 0x4104, 0x4104, 0x4104, 0x4104, 
+    0x4104, 0x4104, 0x4105, 0x4105, 0x4105, 0x4105, 0x4105, 0x4105, 
+    0x4105, 0x4106, 0x4106, 0x4106, 0x4106, 0x4106, 0x4106, 0x4106, 
+    0x4106, 0x4107, 0x4107, 0x4107, 0x4107, 0x4107, 0x4107, 0x4107, 
+    0x4107, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 0x4108, 
+    0x4109, 0x4109, 0x4109, 0x4109, 0x4109, 0x4109, 0x4109, 0x4109, 
+    0x410a, 0x410a, 0x410a, 0x410a, 0x410a, 0x410a, 0x410a, 0x410a, 
+    0x410b, 0x410b, 0x410b, 0x410b, 0x410b, 0x410b, 0x410b, 0x410b, 
+    0x410c, 0x410c, 0x410c, 0x410c, 0x410c, 0x410c, 0x410c, 0x410d, 
+    0x410d, 0x410d, 0x410d, 0x410d, 0x410d, 0x410d, 0x410d, 0x410e, 
+    0x410e, 0x410e, 0x410e, 0x410e, 0x410e, 0x410e, 0x410e, 0x410f, 
+    0x410f, 0x410f, 0x410f, 0x410f, 0x410f, 0x410f, 0x410f, 0x4110, 
+    0x4110, 0x4110, 0x4110, 0x4110, 0x4110, 0x4110, 0x4110, 0x4111, 
+    0x4111, 0x4111, 0x4111, 0x4111, 0x4111, 0x4111, 0x4111, 0x4112, 
+    0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4113, 
+    0x4113, 0x4113, 0x4113, 0x4113, 0x4113, 0x4113, 0x4113, 0x4114, 
+    0x4114, 0x4114, 0x4114, 0x4114, 0x4114, 0x4114, 0x4114, 0x4115, 
+    0x4115, 0x4115, 0x4115, 0x4115, 0x4115, 0x4115, 0x4115, 0x4115, 
+    0x4116, 0x4116, 0x4116, 0x4116, 0x4116, 0x4116, 0x4116, 0x4116, 
+    0x4117, 0x4117, 0x4117, 0x4117, 0x4117, 0x4117, 0x4117, 0x4117, 
+    0x4118, 0x4118, 0x4118, 0x4118, 0x4118, 0x4118, 0x4118, 0x4118, 
+    0x4119, 0x4119, 0x4119, 0x4119, 0x4119, 0x4119, 0x4119, 0x4119, 
+    0x4119, 0x411a, 0x411a, 0x411a, 0x411a, 0x411a, 0x411a, 0x411a, 
+    0x411a, 0x411b, 0x411b, 0x411b, 0x411b, 0x411b, 0x411b, 0x411b, 
+    0x411b, 0x411c, 0x411c, 0x411c, 0x411c, 0x411c, 0x411c, 0x411c, 
+    0x411c, 0x411c, 0x411d, 0x411d, 0x411d, 0x411d, 0x411d, 0x411d, 
+    0x411d, 0x411d, 0x411e, 0x411e, 0x411e, 0x411e, 0x411e, 0x411e, 
+    0x411e, 0x411e, 0x411e, 0x411f, 0x411f, 0x411f, 0x411f, 0x411f, 
+    0x411f, 0x411f, 0x411f, 0x4120, 0x4120, 0x4120, 0x4120, 0x4120, 
+    0x4120, 0x4120, 0x4120, 0x4120, 0x4121, 0x4121, 0x4121, 0x4121, 
+    0x4121, 0x4121, 0x4121, 0x4121, 0x4122, 0x4122, 0x4122, 0x4122, 
+    0x4122, 0x4122, 0x4122, 0x4122, 0x4122, 0x4123, 0x4123, 0x4123, 
+    0x4123, 0x4123, 0x4123, 0x4123, 0x4123, 0x4123, 0x4124, 0x4124, 
+    0x4124, 0x4124, 0x4124, 0x4124, 0x4124, 0x4124, 0x4125, 0x4125, 
+    0x4125, 0x4125, 0x4125, 0x4125, 0x4125, 0x4125, 0x4125, 0x4126, 
+    0x4126, 0x4126, 0x4126, 0x4126, 0x4126, 0x4126, 0x4126, 0x4126, 
+    0x4127, 0x4127, 0x4127, 0x4127, 0x4127, 0x4128, 0x4128, 0x4128, 
+    0x4128, 0x4129, 0x4129, 0x4129, 0x4129, 0x412a, 0x412a, 0x412a, 
+    0x412a, 0x412a, 0x412b, 0x412b, 0x412b, 0x412b, 0x412c, 0x412c, 
+    0x412c, 0x412c, 0x412c, 0x412d, 0x412d, 0x412d, 0x412d, 0x412e, 
+    0x412e, 0x412e, 0x412e, 0x412e, 0x412f, 0x412f, 0x412f, 0x412f, 
+    0x412f, 0x4130, 0x4130, 0x4130, 0x4130, 0x4131, 0x4131, 0x4131, 
+    0x4131, 0x4131, 0x4132, 0x4132, 0x4132, 0x4132, 0x4133, 0x4133, 
+    0x4133, 0x4133, 0x4133, 0x4134, 0x4134, 0x4134, 0x4134, 0x4134, 
+    0x4135, 0x4135, 0x4135, 0x4135, 0x4136, 0x4136, 0x4136, 0x4136, 
+    0x4136, 0x4137, 0x4137, 0x4137, 0x4137, 0x4137, 0x4138, 0x4138, 
+    0x4138, 0x4138, 0x4138, 0x4139, 0x4139, 0x4139, 0x4139, 0x413a, 
+    0x413a, 0x413a, 0x413a, 0x413a, 0x413b, 0x413b, 0x413b, 0x413b, 
+    0x413b, 0x413c, 0x413c, 0x413c, 0x413c, 0x413c, 0x413d, 0x413d, 
+    0x413d, 0x413d, 0x413d, 0x413e, 0x413e, 0x413e, 0x413e, 0x413f, 
+    0x413f, 0x413f, 0x413f, 0x413f, 0x4140, 0x4140, 0x4140, 0x4140, 
+    0x4140, 0x4141, 0x4141, 0x4141, 0x4141, 0x4141, 0x4142, 0x4142, 
+    0x4142, 0x4142, 0x4142, 0x4143, 0x4143, 0x4143, 0x4143, 0x4143, 
+    0x4144, 0x4144, 0x4144, 0x4144, 0x4144, 0x4145, 0x4145, 0x4145, 
+    0x4145, 0x4145, 0x4146, 0x4146, 0x4146, 0x4146, 0x4146, 0x4147, 
+    0x4147, 0x4147, 0x4147, 0x4147, 0x4148, 0x4148, 0x4148, 0x4148, 
+    0x4148, 0x4149, 0x4149, 0x4149, 0x4149, 0x4149, 0x414a, 0x414a, 
+    0x414a, 0x414a, 0x414a, 0x414b, 0x414b, 0x414b, 0x414b, 0x414b, 
+    0x414b, 0x414c, 0x414c, 0x414c, 0x414c, 0x414c, 0x414d, 0x414d, 
+    0x414d, 0x414d, 0x414d, 0x414e, 0x414e, 0x414e, 0x414e, 0x414e, 
+    0x414f, 0x414f, 0x414f, 0x414f, 0x414f, 0x4150, 0x4150, 0x4150, 
+    0x4150, 0x4150, 0x4150, 0x4151, 0x4151, 0x4151, 0x4151, 0x4151, 
+    0x4152, 0x4152, 0x4152, 0x4152, 0x4152, 0x4153, 0x4153, 0x4153, 
+    0x4153, 0x4153, 0x4153, 0x4154, 0x4154, 0x4154, 0x4154, 0x4154, 
+    0x4155, 0x4155, 0x4155, 0x4155, 0x4155, 0x4156, 0x4156, 0x4156, 
+    0x4156, 0x4156, 0x4156, 0x4157, 0x4157, 0x4157, 0x4157, 0x4157, 
+    0x4158, 0x4158, 0x4158, 0x4158, 0x4158, 0x4158, 0x4159, 0x4159, 
+    0x4159, 0x4159, 0x4159, 0x415a, 0x415a, 0x415a, 0x415a, 0x415a, 
+    0x415b, 0x415b, 0x415b, 0x415b, 0x415b, 0x415b, 0x415c, 0x415c, 
+    0x415c, 0x415c, 0x415c, 0x415c, 0x415d, 0x415d, 0x415d, 0x415d, 
+    0x415d, 0x415e, 0x415e, 0x415e, 0x415e, 0x415e, 0x415e, 0x415f, 
+    0x415f, 0x415f, 0x415f, 0x415f, 0x4160, 0x4160, 0x4160, 0x4160, 
+    0x4160, 0x4160, 0x4161, 0x4161, 0x4161, 0x4161, 0x4161, 0x4161, 
+    0x4162, 0x4162, 0x4162, 0x4162, 0x4162, 0x4163, 0x4163, 0x4163, 
+    0x4163, 0x4163, 0x4163, 0x4164, 0x4164, 0x4164, 0x4164, 0x4164, 
+    0x4164, 0x4165, 0x4165, 0x4165, 0x4165, 0x4165, 0x4166, 0x4166, 
+    0x4166, 0x4166, 0x4166, 0x4166, 0x4167, 0x4167, 0x4167, 0x4167, 
+    0x4167, 0x4167, 0x4168, 0x4168, 0x4168, 0x4168, 0x4168, 0x4168, 
+    0x4169, 0x4169, 0x4169, 0x4169, 0x4169, 0x4169, 0x416a, 0x416a, 
+    0x416a, 0x416a, 0x416a, 0x416a, 0x416b, 0x416b, 0x416b, 0x416b, 
+    0x416b, 0x416c, 0x416c, 0x416c, 0x416c, 0x416c, 0x416c, 0x416d, 
+    0x416d, 0x416d, 0x416d, 0x416d, 0x416d, 0x416e, 0x416e, 0x416e, 
+    0x416e, 0x416e, 0x416e, 0x416f, 0x416f, 0x416f, 0x416f, 0x416f, 
+    0x416f, 0x4170, 0x4170, 0x4170, 0x4170, 0x4170, 0x4170, 0x4171, 
+    0x4171, 0x4171, 0x4171, 0x4171, 0x4171, 0x4172, 0x4172, 0x4172, 
+    0x4172, 0x4172, 0x4172, 0x4172, 0x4173, 0x4173, 0x4173, 0x4173, 
+    0x4173, 0x4173, 0x4174, 0x4174, 0x4174, 0x4174, 0x4174, 0x4174, 
+    0x4175, 0x4175, 0x4175, 0x4175, 0x4175, 0x4175, 0x4176, 0x4176, 
+    0x4176, 0x4176, 0x4176, 0x4176, 0x4177, 0x4177, 0x4177, 0x4177, 
+    0x4177, 0x4177, 0x4178, 0x4178, 0x4178, 0x4178, 0x4178, 0x4178, 
+    0x4178, 0x4179, 0x4179, 0x4179, 0x4179, 0x4179, 0x4179, 0x417a, 
+    0x417a, 0x417a, 0x417a, 0x417a, 0x417a, 0x417b, 0x417b, 0x417b, 
+    0x417b, 0x417b, 0x417b, 0x417c, 0x417c, 0x417c, 0x417c, 0x417c, 
+    0x417c, 0x417c, 0x417d, 0x417d, 0x417d, 0x417d, 0x417d, 0x417d, 
+    0x417e, 0x417e, 0x417e, 0x417e, 0x417e, 0x417e, 0x417e, 0x417f, 
+    0x417f, 0x417f, 0x417f, 0x417f, 0x417f, 0x4180, 0x4180, 0x4180, 
+    0x4180, 0x4180, 0x4180, 0x4180, 0x4181, 0x4181, 0x4181, 0x4181, 
+    0x4181, 0x4181, 0x4182, 0x4182, 0x4182, 0x4182, 0x4182, 0x4182, 
+    0x4182, 0x4183, 0x4183, 0x4183, 0x4183, 0x4183, 0x4183, 0x4184, 
+    0x4184, 0x4184, 0x4184, 0x4184, 0x4184, 0x4184, 0x4185, 0x4185, 
+    0x4185, 0x4185, 0x4185, 0x4185, 0x4186, 0x4186, 0x4186, 0x4186, 
+    0x4186, 0x4186, 0x4186, 0x4187, 0x4187, 0x4187, 0x4187, 0x4187, 
+    0x4187, 0x4187, 0x4188, 0x4188, 0x4188, 0x4188, 0x4188, 0x4188, 
+    0x4189, 0x4189, 0x4189, 0x4189, 0x4189, 0x4189, 0x4189, 0x418a, 
+    0x418a, 0x418a, 0x418a, 0x418a, 0x418a, 0x418a, 0x418b, 0x418b, 
+    0x418b, 0x418b, 0x418b, 0x418b, 0x418c, 0x418c, 0x418c, 0x418c, 
+    0x418c, 0x418c, 0x418c, 0x418d, 0x418d, 0x418d, 0x418d, 0x418d, 
+    0x418d, 0x418d, 0x418e, 0x418e, 0x418e, 0x418e, 0x418e, 0x418e, 
+    0x418e, 0x418f, 0x418f, 0x418f, 0x418f, 0x418f, 0x418f, 0x418f, 
+    0x4190, 0x4190, 0x4190, 0x4190, 0x4190, 0x4190, 0x4190, 0x4191, 
+    0x4191, 0x4191, 0x4191, 0x4191, 0x4191, 0x4191, 0x4192, 0x4192, 
+    0x4192, 0x4192, 0x4192, 0x4192, 0x4192, 0x4193, 0x4193, 0x4193, 
+    0x4193, 0x4193, 0x4193, 0x4193, 0x4194, 0x4194, 0x4194, 0x4194, 
+    0x4194, 0x4194, 0x4194, 0x4195, 0x4195, 0x4195, 0x4195, 0x4195, 
+    0x4195, 0x4195, 0x4196, 0x4196, 0x4196, 0x4196, 0x4196, 0x4196, 
+    0x4196, 0x4197, 0x4197, 0x4197, 0x4197, 0x4197, 0x4197, 0x4197, 
+    0x4198, 0x4198, 0x4198, 0x4198, 0x4198, 0x4198, 0x4198, 0x4199, 
+    0x4199, 0x4199, 0x4199, 0x4199, 0x4199, 0x4199, 0x419a, 0x419a, 
+    0x419a, 0x419a, 0x419a, 0x419a, 0x419a, 0x419a, 0x419b, 0x419b, 
+    0x419b, 0x419b, 0x419b, 0x419b, 0x419b, 0x419c, 0x419c, 0x419c, 
+    0x419c, 0x419c, 0x419c, 0x419c, 0x419d, 0x419d, 0x419d, 0x419d, 
+    0x419d, 0x419d, 0x419d, 0x419d, 0x419e, 0x419e, 0x419e, 0x419e, 
+    0x419e, 0x419e, 0x419e, 0x419f, 0x419f, 0x419f, 0x419f, 0x419f, 
+    0x419f, 0x419f, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 
+    0x41a0, 0x41a0, 0x41a1, 0x41a1, 0x41a1, 0x41a1, 0x41a1, 0x41a1, 
+    0x41a1, 0x41a2, 0x41a2, 0x41a2, 0x41a2, 0x41a2, 0x41a2, 0x41a2, 
+    0x41a2, 0x41a3, 0x41a3, 0x41a3, 0x41a3, 0x41a3, 0x41a3, 0x41a3, 
+    0x41a4, 0x41a4, 0x41a4, 0x41a4, 0x41a4, 0x41a4, 0x41a4, 0x41a4, 
+    0x41a5, 0x41a5, 0x41a5, 0x41a5, 0x41a5, 0x41a5, 0x41a5, 0x41a6, 
+    0x41a6, 0x41a6, 0x41a6, 0x41a6, 0x41a6, 0x41a6, 0x41a6, 0x41a7, 
+    0x41a7, 0x41a7, 0x41a7, 0x41a7, 0x41a7, 0x41a7, 0x41a8, 0x41a8, 
+    0x41a8, 0x41a8, 0x41a8, 0x41a8, 0x41a8, 0x41a8, 0x41a9, 0x41a9, 
+    0x41a9, 0x41a9, 0x41a9, 0x41a9, 0x41a9, 0x41a9, 0x41aa, 0x41aa, 
+    0x41aa, 0x41aa, 0x41aa, 0x41aa, 0x41aa, 0x41aa, 0x41ab, 0x41ab, 
+    0x41ab, 0x41ab, 0x41ab, 0x41ab, 0x41ab, 0x41ac, 0x41ac, 0x41ac, 
+    0x41ac, 0x41ac, 0x41ac, 0x41ac, 0x41ac, 0x41ad, 0x41ad, 0x41ad, 
+    0x41ad, 0x41ad, 0x41ad, 0x41ad, 0x41ad, 0x41ae, 0x41ae, 0x41ae, 
+    0x41ae, 0x41ae, 0x41ae, 0x41ae, 0x41ae, 0x41af, 0x41af, 0x41af, 
+    0x41af, 0x41af, 0x41af, 0x41af, 0x41af, 0x41b0, 0x41b0, 0x41b0, 
+    0x41b0, 0x41b0, 0x41b0, 0x41b0, 0x41b0, 0x41b1, 0x41b1, 0x41b1, 
+    0x41b1, 0x41b1, 0x41b1, 0x41b1, 0x41b1, 0x41b2, 0x41b2, 0x41b2, 
+    0x41b2, 0x41b2, 0x41b2, 0x41b2, 0x41b2, 0x41b3, 0x41b3, 0x41b3, 
+    0x41b3, 0x41b3, 0x41b3, 0x41b3, 0x41b3, 0x41b4, 0x41b4, 0x41b4, 
+    0x41b4, 0x41b4, 0x41b4, 0x41b4, 0x41b4, 0x41b5, 0x41b5, 0x41b5, 
+    0x41b5, 0x41b5, 0x41b5, 0x41b5, 0x41b5, 0x41b6, 0x41b6, 0x41b6, 
+    0x41b6, 0x41b6, 0x41b6, 0x41b6, 0x41b6, 0x41b7, 0x41b7, 0x41b7, 
+    0x41b7, 0x41b7, 0x41b7, 0x41b7, 0x41b7, 0x41b8, 0x41b8, 0x41b8, 
+    0x41b8, 0x41b8, 0x41b8, 0x41b8, 0x41b8, 0x41b9, 0x41b9, 0x41b9, 
+    0x41b9, 0x41b9, 0x41b9, 0x41b9, 0x41b9, 0x41b9, 0x41ba, 0x41ba, 
+    0x41ba, 0x41ba, 0x41ba, 0x41ba, 0x41ba, 0x41ba, 0x41bb, 0x41bb, 
+    0x41bb, 0x41bb, 0x41bb, 0x41bb, 0x41bb, 0x41bb, 0x41bc, 0x41bc, 
+    0x41bc, 0x41bc, 0x41bc, 0x41bc, 0x41bc, 0x41bc, 0x41bc, 0x41bd, 
+    0x41bd, 0x41bd, 0x41bd, 0x41bd, 0x41bd, 0x41bd, 0x41bd, 0x41be, 
+    0x41be, 0x41be, 0x41be, 0x41be, 0x41be, 0x41be, 0x41be, 0x41be, 
+    0x41bf, 0x41bf, 0x41bf, 0x41bf, 0x41bf, 0x41bf, 0x41bf, 0x41bf, 
+    0x41c0, 0x41c0, 0x41c0, 0x41c0, 0x41c0, 0x41c0, 0x41c0, 0x41c0, 
+    0x41c0, 0x41c1, 0x41c1, 0x41c1, 0x41c1, 0x41c1, 0x41c1, 0x41c1, 
+    0x41c1, 0x41c2, 0x41c2, 0x41c2, 0x41c2, 0x41c2, 0x41c2, 0x41c2, 
+    0x41c2, 0x41c2, 0x41c3, 0x41c3, 0x41c3, 0x41c3, 0x41c3, 0x41c3, 
+    0x41c3, 0x41c3, 0x41c4, 0x41c4, 0x41c4, 0x41c4, 0x41c4, 0x41c4, 
+    0x41c4, 0x41c4, 0x41c4, 0x41c5, 0x41c5, 0x41c5, 0x41c5, 0x41c5, 
+    0x41c5, 0x41c5, 0x41c5, 0x41c5, 0x41c6, 0x41c6, 0x41c6, 0x41c6, 
+    0x41c6, 0x41c6, 0x41c6, 0x41c6, 0x41c7, 0x41c7, 0x41c7, 0x41c7, 
+    0x41c7, 0x41c7, 0x41c7, 0x41c7, 0x41c7, 0x41c8, 0x41c8, 0x41c8, 
+    0x41c8, 0x41c8, 0x41c8, 0x41c9, 0x41c9, 0x41c9, 0x41c9, 0x41c9, 
+    0x41ca, 0x41ca, 0x41ca, 0x41ca, 0x41cb, 0x41cb, 0x41cb, 0x41cb, 
+    0x41cb, 0x41cc, 0x41cc, 0x41cc, 0x41cc, 0x41cd, 0x41cd, 0x41cd, 
+    0x41cd, 0x41cd, 0x41ce, 0x41ce, 0x41ce, 0x41ce, 0x41cf, 0x41cf, 
+    0x41cf, 0x41cf, 0x41cf, 0x41d0, 0x41d0, 0x41d0, 0x41d0, 0x41d1, 
+    0x41d1, 0x41d1, 0x41d1, 0x41d1, 0x41d2, 0x41d2, 0x41d2, 0x41d2, 
+    0x41d3, 0x41d3, 0x41d3, 0x41d3, 0x41d3, 0x41d4, 0x41d4, 0x41d4, 
+    0x41d4, 0x41d4, 0x41d5, 0x41d5, 0x41d5, 0x41d5, 0x41d6, 0x41d6, 
+    0x41d6, 0x41d6, 0x41d6, 0x41d7, 0x41d7, 0x41d7, 0x41d7, 0x41d7, 
+    0x41d8, 0x41d8, 0x41d8, 0x41d8, 0x41d9, 0x41d9, 0x41d9, 0x41d9, 
+    0x41d9, 0x41da, 0x41da, 0x41da, 0x41da, 0x41da, 0x41db, 0x41db, 
+    0x41db, 0x41db, 0x41db, 0x41dc, 0x41dc, 0x41dc, 0x41dc, 0x41dd, 
+    0x41dd, 0x41dd, 0x41dd, 0x41dd, 0x41de, 0x41de, 0x41de, 0x41de, 
+    0x41de, 0x41df, 0x41df, 0x41df, 0x41df, 0x41df, 0x41e0, 0x41e0, 
+    0x41e0, 0x41e0, 0x41e0, 0x41e1, 0x41e1, 0x41e1, 0x41e1, 0x41e1, 
+    0x41e2, 0x41e2, 0x41e2, 0x41e2, 0x41e2, 0x41e3, 0x41e3, 0x41e3, 
+    0x41e3, 0x41e3, 0x41e4, 0x41e4, 0x41e4, 0x41e4, 0x41e5, 0x41e5, 
+    0x41e5, 0x41e5, 0x41e5, 0x41e6, 0x41e6, 0x41e6, 0x41e6, 0x41e6, 
+    0x41e7, 0x41e7, 0x41e7, 0x41e7, 0x41e7, 0x41e8, 0x41e8, 0x41e8, 
+    0x41e8, 0x41e8, 0x41e8, 0x41e9, 0x41e9, 0x41e9, 0x41e9, 0x41e9, 
+    0x41ea, 0x41ea, 0x41ea, 0x41ea, 0x41ea, 0x41eb, 0x41eb, 0x41eb, 
+    0x41eb, 0x41eb, 0x41ec, 0x41ec, 0x41ec, 0x41ec, 0x41ec, 0x41ed, 
+    0x41ed, 0x41ed, 0x41ed, 0x41ed, 0x41ee, 0x41ee, 0x41ee, 0x41ee, 
+    0x41ee, 0x41ef, 0x41ef, 0x41ef, 0x41ef, 0x41ef, 0x41ef, 0x41f0, 
+    0x41f0, 0x41f0, 0x41f0, 0x41f0, 0x41f1, 0x41f1, 0x41f1, 0x41f1, 
+    0x41f1, 0x41f2, 0x41f2, 0x41f2, 0x41f2, 0x41f2, 0x41f3, 0x41f3, 
+    0x41f3, 0x41f3, 0x41f3, 0x41f3, 0x41f4, 0x41f4, 0x41f4, 0x41f4, 
+    0x41f4, 0x41f5, 0x41f5, 0x41f5, 0x41f5, 0x41f5, 0x41f6, 0x41f6, 
+    0x41f6, 0x41f6, 0x41f6, 0x41f6, 0x41f7, 0x41f7, 0x41f7, 0x41f7, 
+    0x41f7, 0x41f8, 0x41f8, 0x41f8, 0x41f8, 0x41f8, 0x41f9, 0x41f9, 
+    0x41f9, 0x41f9, 0x41f9, 0x41f9, 0x41fa, 0x41fa, 0x41fa, 0x41fa, 
+    0x41fa, 0x41fb, 0x41fb, 0x41fb, 0x41fb, 0x41fb, 0x41fb, 0x41fc, 
+    0x41fc, 0x41fc, 0x41fc, 0x41fc, 0x41fd, 0x41fd, 0x41fd, 0x41fd, 
+    0x41fd, 0x41fd, 0x41fe, 0x41fe, 0x41fe, 0x41fe, 0x41fe, 0x41ff, 
+    0x41ff, 0x41ff, 0x41ff, 0x41ff, 0x41ff, 0x4200, 0x4200, 0x4200, 
+    0x4200, 0x4200, 0x4200, 0x4201, 0x4201, 0x4201, 0x4201, 0x4201, 
+    0x4202, 0x4202, 0x4202, 0x4202, 0x4202, 0x4202, 0x4203, 0x4203, 
+    0x4203, 0x4203, 0x4203, 0x4204, 0x4204, 0x4204, 0x4204, 0x4204, 
+    0x4204, 0x4205, 0x4205, 0x4205, 0x4205, 0x4205, 0x4205, 0x4206, 
+    0x4206, 0x4206, 0x4206, 0x4206, 0x4206, 0x4207, 0x4207, 0x4207, 
+    0x4207, 0x4207, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 0x4208, 
+    0x4209, 0x4209, 0x4209, 0x4209, 0x4209, 0x4209, 0x420a, 0x420a, 
+    0x420a, 0x420a, 0x420a, 0x420a, 0x420b, 0x420b, 0x420b, 0x420b, 
+    0x420b, 0x420b, 0x420c, 0x420c, 0x420c, 0x420c, 0x420c, 0x420c, 
+    0x420d, 0x420d, 0x420d, 0x420d, 0x420d, 0x420d, 0x420e, 0x420e, 
+    0x420e, 0x420e, 0x420e, 0x420f, 0x420f, 0x420f, 0x420f, 0x420f, 
+    0x420f, 0x4210, 0x4210, 0x4210, 0x4210, 0x4210, 0x4210, 0x4211, 
+    0x4211, 0x4211, 0x4211, 0x4211, 0x4211, 0x4212, 0x4212, 0x4212, 
+    0x4212, 0x4212, 0x4212, 0x4212, 0x4213, 0x4213, 0x4213, 0x4213, 
+    0x4213, 0x4213, 0x4214, 0x4214, 0x4214, 0x4214, 0x4214, 0x4214, 
+    0x4215, 0x4215, 0x4215, 0x4215, 0x4215, 0x4215, 0x4216, 0x4216, 
+    0x4216, 0x4216, 0x4216, 0x4216, 0x4217, 0x4217, 0x4217, 0x4217, 
+    0x4217, 0x4217, 0x4218, 0x4218, 0x4218, 0x4218, 0x4218, 0x4218, 
+    0x4219, 0x4219, 0x4219, 0x4219, 0x4219, 0x4219, 0x4219, 0x421a, 
+    0x421a, 0x421a, 0x421a, 0x421a, 0x421a, 0x421b, 0x421b, 0x421b, 
+    0x421b, 0x421b, 0x421b, 0x421c, 0x421c, 0x421c, 0x421c, 0x421c, 
+    0x421c, 0x421d, 0x421d, 0x421d, 0x421d, 0x421d, 0x421d, 0x421d, 
+    0x421e, 0x421e, 0x421e, 0x421e, 0x421e, 0x421e, 0x421f, 0x421f, 
+    0x421f, 0x421f, 0x421f, 0x421f, 0x421f, 0x4220, 0x4220, 0x4220, 
+    0x4220, 0x4220, 0x4220, 0x4221, 0x4221, 0x4221, 0x4221, 0x4221, 
+    0x4221, 0x4222, 0x4222, 0x4222, 0x4222, 0x4222, 0x4222, 0x4222, 
+    0x4223, 0x4223, 0x4223, 0x4223, 0x4223, 0x4223, 0x4224, 0x4224, 
+    0x4224, 0x4224, 0x4224, 0x4224, 0x4224, 0x4225, 0x4225, 0x4225, 
+    0x4225, 0x4225, 0x4225, 0x4225, 0x4226, 0x4226, 0x4226, 0x4226, 
+    0x4226, 0x4226, 0x4227, 0x4227, 0x4227, 0x4227, 0x4227, 0x4227, 
+    0x4227, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4229, 
+    0x4229, 0x4229, 0x4229, 0x4229, 0x4229, 0x4229, 0x422a, 0x422a, 
+    0x422a, 0x422a, 0x422a, 0x422a, 0x422a, 0x422b, 0x422b, 0x422b, 
+    0x422b, 0x422b, 0x422b, 0x422b, 0x422c, 0x422c, 0x422c, 0x422c, 
+    0x422c, 0x422c, 0x422d, 0x422d, 0x422d, 0x422d, 0x422d, 0x422d, 
+    0x422d, 0x422e, 0x422e, 0x422e, 0x422e, 0x422e, 0x422e, 0x422e, 
+    0x422f, 0x422f, 0x422f, 0x422f, 0x422f, 0x422f, 0x422f, 0x4230, 
+    0x4230, 0x4230, 0x4230, 0x4230, 0x4230, 0x4230, 0x4231, 0x4231, 
+    0x4231, 0x4231, 0x4231, 0x4231, 0x4231, 0x4232, 0x4232, 0x4232, 
+    0x4232, 0x4232, 0x4232, 0x4232, 0x4233, 0x4233, 0x4233, 0x4233, 
+    0x4233, 0x4233, 0x4234, 0x4234, 0x4234, 0x4234, 0x4234, 0x4234, 
+    0x4234, 0x4234, 0x4235, 0x4235, 0x4235, 0x4235, 0x4235, 0x4235, 
+    0x4235, 0x4236, 0x4236, 0x4236, 0x4236, 0x4236, 0x4236, 0x4236, 
+    0x4237, 0x4237, 0x4237, 0x4237, 0x4237, 0x4237, 0x4237, 0x4238, 
+    0x4238, 0x4238, 0x4238, 0x4238, 0x4238, 0x4238, 0x4239, 0x4239, 
+    0x4239, 0x4239, 0x4239, 0x4239, 0x4239, 0x423a, 0x423a, 0x423a, 
+    0x423a, 0x423a, 0x423a, 0x423a, 0x423b, 0x423b, 0x423b, 0x423b, 
+    0x423b, 0x423b, 0x423b, 0x423c, 0x423c, 0x423c, 0x423c, 0x423c, 
+    0x423c, 0x423c, 0x423c, 0x423d, 0x423d, 0x423d, 0x423d, 0x423d, 
+    0x423d, 0x423d, 0x423e, 0x423e, 0x423e, 0x423e, 0x423e, 0x423e, 
+    0x423e, 0x423f, 0x423f, 0x423f, 0x423f, 0x423f, 0x423f, 0x423f, 
+    0x423f, 0x4240, 0x4240, 0x4240, 0x4240, 0x4240, 0x4240, 0x4240, 
+    0x4241, 0x4241, 0x4241, 0x4241, 0x4241, 0x4241, 0x4241, 0x4242, 
+    0x4242, 0x4242, 0x4242, 0x4242, 0x4242, 0x4242, 0x4242, 0x4243, 
+    0x4243, 0x4243, 0x4243, 0x4243, 0x4243, 0x4243, 0x4244, 0x4244, 
+    0x4244, 0x4244, 0x4244, 0x4244, 0x4244, 0x4244, 0x4245, 0x4245, 
+    0x4245, 0x4245, 0x4245, 0x4245, 0x4245, 0x4246, 0x4246, 0x4246, 
+    0x4246, 0x4246, 0x4246, 0x4246, 0x4246, 0x4247, 0x4247, 0x4247, 
+    0x4247, 0x4247, 0x4247, 0x4247, 0x4248, 0x4248, 0x4248, 0x4248, 
+    0x4248, 0x4248, 0x4248, 0x4248, 0x4249, 0x4249, 0x4249, 0x4249, 
+    0x4249, 0x4249, 0x4249, 0x4249, 0x424a, 0x424a, 0x424a, 0x424a, 
+    0x424a, 0x424a, 0x424a, 0x424b, 0x424b, 0x424b, 0x424b, 0x424b, 
+    0x424b, 0x424b, 0x424b, 0x424c, 0x424c, 0x424c, 0x424c, 0x424c, 
+    0x424c, 0x424c, 0x424c, 0x424d, 0x424d, 0x424d, 0x424d, 0x424d, 
+    0x424d, 0x424d, 0x424d, 0x424e, 0x424e, 0x424e, 0x424e, 0x424e, 
+    0x424e, 0x424e, 0x424e, 0x424f, 0x424f, 0x424f, 0x424f, 0x424f, 
+    0x424f, 0x424f, 0x4250, 0x4250, 0x4250, 0x4250, 0x4250, 0x4250, 
+    0x4250, 0x4250, 0x4251, 0x4251, 0x4251, 0x4251, 0x4251, 0x4251, 
+    0x4251, 0x4251, 0x4252, 0x4252, 0x4252, 0x4252, 0x4252, 0x4252, 
+    0x4252, 0x4252, 0x4253, 0x4253, 0x4253, 0x4253, 0x4253, 0x4253, 
+    0x4253, 0x4253, 0x4254, 0x4254, 0x4254, 0x4254, 0x4254, 0x4254, 
+    0x4254, 0x4254, 0x4255, 0x4255, 0x4255, 0x4255, 0x4255, 0x4255, 
+    0x4255, 0x4255, 0x4256, 0x4256, 0x4256, 0x4256, 0x4256, 0x4256, 
+    0x4256, 0x4256, 0x4257, 0x4257, 0x4257, 0x4257, 0x4257, 0x4257, 
+    0x4257, 0x4257, 0x4257, 0x4258, 0x4258, 0x4258, 0x4258, 0x4258, 
+    0x4258, 0x4258, 0x4258, 0x4259, 0x4259, 0x4259, 0x4259, 0x4259, 
+    0x4259, 0x4259, 0x4259, 0x425a, 0x425a, 0x425a, 0x425a, 0x425a, 
+    0x425a, 0x425a, 0x425a, 0x425b, 0x425b, 0x425b, 0x425b, 0x425b, 
+    0x425b, 0x425b, 0x425b, 0x425c, 0x425c, 0x425c, 0x425c, 0x425c, 
+    0x425c, 0x425c, 0x425c, 0x425c, 0x425d, 0x425d, 0x425d, 0x425d, 
+    0x425d, 0x425d, 0x425d, 0x425d, 0x425e, 0x425e, 0x425e, 0x425e, 
+    0x425e, 0x425e, 0x425e, 0x425e, 0x425f, 0x425f, 0x425f, 0x425f, 
+    0x425f, 0x425f, 0x425f, 0x425f, 0x425f, 0x4260, 0x4260, 0x4260, 
+    0x4260, 0x4260, 0x4260, 0x4260, 0x4260, 0x4261, 0x4261, 0x4261, 
+    0x4261, 0x4261, 0x4261, 0x4261, 0x4261, 0x4261, 0x4262, 0x4262, 
+    0x4262, 0x4262, 0x4262, 0x4262, 0x4262, 0x4262, 0x4263, 0x4263, 
+    0x4263, 0x4263, 0x4263, 0x4263, 0x4263, 0x4263, 0x4263, 0x4264, 
+    0x4264, 0x4264, 0x4264, 0x4264, 0x4264, 0x4264, 0x4264, 0x4264, 
+    0x4265, 0x4265, 0x4265, 0x4265, 0x4265, 0x4265, 0x4265, 0x4265, 
+    0x4266, 0x4266, 0x4266, 0x4266, 0x4266, 0x4266, 0x4266, 0x4266, 
+    0x4266, 0x4267, 0x4267, 0x4267, 0x4267, 0x4267, 0x4267, 0x4267, 
+    0x4267, 0x4267, 0x4268, 0x4268, 0x4268, 0x4268, 0x4268, 0x4268, 
+    0x4268, 0x4268, 0x4269, 0x4269, 0x4269, 0x4269, 0x4269, 0x4269, 
+    0x4269, 0x4269, 0x426a, 0x426a, 0x426a, 0x426a, 0x426b, 0x426b, 
+    0x426b, 0x426b, 0x426b, 0x426c, 0x426c, 0x426c, 0x426c, 0x426d, 
+    0x426d, 0x426d, 0x426d, 0x426d, 0x426e, 0x426e, 0x426e, 0x426e, 
+    0x426f, 0x426f, 0x426f, 0x426f, 0x426f, 0x4270, 0x4270, 0x4270, 
+    0x4270, 0x4271, 0x4271, 0x4271, 0x4271, 0x4271, 0x4272, 0x4272, 
+    0x4272, 0x4272, 0x4273, 0x4273, 0x4273, 0x4273, 0x4273, 0x4274, 
+    0x4274, 0x4274, 0x4274, 0x4275, 0x4275, 0x4275, 0x4275, 0x4275, 
+    0x4276, 0x4276, 0x4276, 0x4276, 0x4276, 0x4277, 0x4277, 0x4277, 
+    0x4277, 0x4278, 0x4278, 0x4278, 0x4278, 0x4278, 0x4279, 0x4279, 
+    0x4279, 0x4279, 0x4279, 0x427a, 0x427a, 0x427a, 0x427a, 0x427a, 
+    0x427b, 0x427b, 0x427b, 0x427b, 0x427c, 0x427c, 0x427c, 0x427c, 
+    0x427c, 0x427d, 0x427d, 0x427d, 0x427d, 0x427d, 0x427e, 0x427e, 
+    0x427e, 0x427e, 0x427e, 0x427f, 0x427f, 0x427f, 0x427f, 0x4280, 
+    0x4280, 0x4280, 0x4280, 0x4280, 0x4281, 0x4281, 0x4281, 0x4281, 
+    0x4281, 0x4282, 0x4282, 0x4282, 0x4282, 0x4282, 0x4283, 0x4283, 
+    0x4283, 0x4283, 0x4283, 0x4284, 0x4284, 0x4284, 0x4284, 0x4284, 
+    0x4285, 0x4285, 0x4285, 0x4285, 0x4285, 0x4286, 0x4286, 0x4286, 
+    0x4286, 0x4286, 0x4287, 0x4287, 0x4287, 0x4287, 0x4287, 0x4288, 
+    0x4288, 0x4288, 0x4288, 0x4288, 0x4289, 0x4289, 0x4289, 0x4289, 
+    0x4289, 0x428a, 0x428a, 0x428a, 0x428a, 0x428a, 0x428b, 0x428b, 
+    0x428b, 0x428b, 0x428b, 0x428c, 0x428c, 0x428c, 0x428c, 0x428c, 
+    0x428d, 0x428d, 0x428d, 0x428d, 0x428d, 0x428e, 0x428e, 0x428e, 
+    0x428e, 0x428e, 0x428e, 0x428f, 0x428f, 0x428f, 0x428f, 0x428f, 
+    0x4290, 0x4290, 0x4290, 0x4290, 0x4290, 0x4291, 0x4291, 0x4291, 
+    0x4291, 0x4291, 0x4292, 0x4292, 0x4292, 0x4292, 0x4292, 0x4293, 
+    0x4293, 0x4293, 0x4293, 0x4293, 0x4293, 0x4294, 0x4294, 0x4294, 
+    0x4294, 0x4294, 0x4295, 0x4295, 0x4295, 0x4295, 0x4295, 0x4296, 
+    0x4296, 0x4296, 0x4296, 0x4296, 0x4296, 0x4297, 0x4297, 0x4297, 
+    0x4297, 0x4297, 0x4298, 0x4298, 0x4298, 0x4298, 0x4298, 0x4299, 
+    0x4299, 0x4299, 0x4299, 0x4299, 0x4299, 0x429a, 0x429a, 0x429a, 
+    0x429a, 0x429a, 0x429b, 0x429b, 0x429b, 0x429b, 0x429b, 0x429b, 
+    0x429c, 0x429c, 0x429c, 0x429c, 0x429c, 0x429d, 0x429d, 0x429d, 
+    0x429d, 0x429d, 0x429d, 0x429e, 0x429e, 0x429e, 0x429e, 0x429e, 
+    0x429f, 0x429f, 0x429f, 0x429f, 0x429f, 0x429f, 0x42a0, 0x42a0, 
+    0x42a0, 0x42a0, 0x42a0, 0x42a1, 0x42a1, 0x42a1, 0x42a1, 0x42a1, 
+    0x42a1, 0x42a2, 0x42a2, 0x42a2, 0x42a2, 0x42a2, 0x42a3, 0x42a3, 
+    0x42a3, 0x42a3, 0x42a3, 0x42a3, 0x42a4, 0x42a4, 0x42a4, 0x42a4, 
+    0x42a4, 0x42a4, 0x42a5, 0x42a5, 0x42a5, 0x42a5, 0x42a5, 0x42a6, 
+    0x42a6, 0x42a6, 0x42a6, 0x42a6, 0x42a6, 0x42a7, 0x42a7, 0x42a7, 
+    0x42a7, 0x42a7, 0x42a7, 0x42a8, 0x42a8, 0x42a8, 0x42a8, 0x42a8, 
+    0x42a8, 0x42a9, 0x42a9, 0x42a9, 0x42a9, 0x42a9, 0x42aa, 0x42aa, 
+    0x42aa, 0x42aa, 0x42aa, 0x42aa, 0x42ab, 0x42ab, 0x42ab, 0x42ab, 
+    0x42ab, 0x42ab, 0x42ac, 0x42ac, 0x42ac, 0x42ac, 0x42ac, 0x42ac, 
+    0x42ad, 0x42ad, 0x42ad, 0x42ad, 0x42ad, 0x42ad, 0x42ae, 0x42ae, 
+    0x42ae, 0x42ae, 0x42ae, 0x42ae, 0x42af, 0x42af, 0x42af, 0x42af, 
+    0x42af, 0x42af, 0x42b0, 0x42b0, 0x42b0, 0x42b0, 0x42b0, 0x42b0, 
+    0x42b1, 0x42b1, 0x42b1, 0x42b1, 0x42b1, 0x42b1, 0x42b2, 0x42b2, 
+    0x42b2, 0x42b2, 0x42b2, 0x42b2, 0x42b3, 0x42b3, 0x42b3, 0x42b3, 
+    0x42b3, 0x42b3, 0x42b4, 0x42b4, 0x42b4, 0x42b4, 0x42b4, 0x42b4, 
+    0x42b5, 0x42b5, 0x42b5, 0x42b5, 0x42b5, 0x42b5, 0x42b6, 0x42b6, 
+    0x42b6, 0x42b6, 0x42b6, 0x42b6, 0x42b7, 0x42b7, 0x42b7, 0x42b7, 
+    0x42b7, 0x42b7, 0x42b8, 0x42b8, 0x42b8, 0x42b8, 0x42b8, 0x42b8, 
+    0x42b9, 0x42b9, 0x42b9, 0x42b9, 0x42b9, 0x42b9, 0x42ba, 0x42ba, 
+    0x42ba, 0x42ba, 0x42ba, 0x42ba, 0x42ba, 0x42bb, 0x42bb, 0x42bb, 
+    0x42bb, 0x42bb, 0x42bb, 0x42bc, 0x42bc, 0x42bc, 0x42bc, 0x42bc, 
+    0x42bc, 0x42bd, 0x42bd, 0x42bd, 0x42bd, 0x42bd, 0x42bd, 0x42bd, 
+    0x42be, 0x42be, 0x42be, 0x42be, 0x42be, 0x42be, 0x42bf, 0x42bf, 
+    0x42bf, 0x42bf, 0x42bf, 0x42bf, 0x42c0, 0x42c0, 0x42c0, 0x42c0, 
+    0x42c0, 0x42c0, 0x42c0, 0x42c1, 0x42c1, 0x42c1, 0x42c1, 0x42c1, 
+    0x42c1, 0x42c2, 0x42c2, 0x42c2, 0x42c2, 0x42c2, 0x42c2, 0x42c3, 
+    0x42c3, 0x42c3, 0x42c3, 0x42c3, 0x42c3, 0x42c3, 0x42c4, 0x42c4, 
+    0x42c4, 0x42c4, 0x42c4, 0x42c4, 0x42c5, 0x42c5, 0x42c5, 0x42c5, 
+    0x42c5, 0x42c5, 0x42c5, 0x42c6, 0x42c6, 0x42c6, 0x42c6, 0x42c6, 
+    0x42c6, 0x42c6, 0x42c7, 0x42c7, 0x42c7, 0x42c7, 0x42c7, 0x42c7, 
+    0x42c8, 0x42c8, 0x42c8, 0x42c8, 0x42c8, 0x42c8, 0x42c8, 0x42c9, 
+    0x42c9, 0x42c9, 0x42c9, 0x42c9, 0x42c9, 0x42ca, 0x42ca, 0x42ca, 
+    0x42ca, 0x42ca, 0x42ca, 0x42ca, 0x42cb, 0x42cb, 0x42cb, 0x42cb, 
+    0x42cb, 0x42cb, 0x42cb, 0x42cc, 0x42cc, 0x42cc, 0x42cc, 0x42cc, 
+    0x42cc, 0x42cd, 0x42cd, 0x42cd, 0x42cd, 0x42cd, 0x42cd, 0x42cd, 
+    0x42ce, 0x42ce, 0x42ce, 0x42ce, 0x42ce, 0x42ce, 0x42ce, 0x42cf, 
+    0x42cf, 0x42cf, 0x42cf, 0x42cf, 0x42cf, 0x42cf, 0x42d0, 0x42d0, 
+    0x42d0, 0x42d0, 0x42d0, 0x42d0, 0x42d0, 0x42d1, 0x42d1, 0x42d1, 
+    0x42d1, 0x42d1, 0x42d1, 0x42d1, 0x42d2, 0x42d2, 0x42d2, 0x42d2, 
+    0x42d2, 0x42d2, 0x42d3, 0x42d3, 0x42d3, 0x42d3, 0x42d3, 0x42d3, 
+    0x42d3, 0x42d4, 0x42d4, 0x42d4, 0x42d4, 0x42d4, 0x42d4, 0x42d4, 
+    0x42d5, 0x42d5, 0x42d5, 0x42d5, 0x42d5, 0x42d5, 0x42d5, 0x42d6, 
+    0x42d6, 0x42d6, 0x42d6, 0x42d6, 0x42d6, 0x42d6, 0x42d7, 0x42d7, 
+    0x42d7, 0x42d7, 0x42d7, 0x42d7, 0x42d7, 0x42d8, 0x42d8, 0x42d8, 
+    0x42d8, 0x42d8, 0x42d8, 0x42d8, 0x42d9, 0x42d9, 0x42d9, 0x42d9, 
+    0x42d9, 0x42d9, 0x42d9, 0x42d9, 0x42da, 0x42da, 0x42da, 0x42da, 
+    0x42da, 0x42da, 0x42da, 0x42db, 0x42db, 0x42db, 0x42db, 0x42db, 
+    0x42db, 0x42db, 0x42dc, 0x42dc, 0x42dc, 0x42dc, 0x42dc, 0x42dc, 
+    0x42dc, 0x42dd, 0x42dd, 0x42dd, 0x42dd, 0x42dd, 0x42dd, 0x42dd, 
+    0x42de, 0x42de, 0x42de, 0x42de, 0x42de, 0x42de, 0x42de, 0x42de, 
+    0x42df, 0x42df, 0x42df, 0x42df, 0x42df, 0x42df, 0x42df, 0x42e0, 
+    0x42e0, 0x42e0, 0x42e0, 0x42e0, 0x42e0, 0x42e0, 0x42e1, 0x42e1, 
+    0x42e1, 0x42e1, 0x42e1, 0x42e1, 0x42e1, 0x42e1, 0x42e2, 0x42e2, 
+    0x42e2, 0x42e2, 0x42e2, 0x42e2, 0x42e2, 0x42e3, 0x42e3, 0x42e3, 
+    0x42e3, 0x42e3, 0x42e3, 0x42e3, 0x42e4, 0x42e4, 0x42e4, 0x42e4, 
+    0x42e4, 0x42e4, 0x42e4, 0x42e4, 0x42e5, 0x42e5, 0x42e5, 0x42e5, 
+    0x42e5, 0x42e5, 0x42e5, 0x42e6, 0x42e6, 0x42e6, 0x42e6, 0x42e6, 
+    0x42e6, 0x42e6, 0x42e6, 0x42e7, 0x42e7, 0x42e7, 0x42e7, 0x42e7, 
+    0x42e7, 0x42e7, 0x42e8, 0x42e8, 0x42e8, 0x42e8, 0x42e8, 0x42e8, 
+    0x42e8, 0x42e8, 0x42e9, 0x42e9, 0x42e9, 0x42e9, 0x42e9, 0x42e9, 
+    0x42e9, 0x42e9, 0x42ea, 0x42ea, 0x42ea, 0x42ea, 0x42ea, 0x42ea, 
+    0x42ea, 0x42eb, 0x42eb, 0x42eb, 0x42eb, 0x42eb, 0x42eb, 0x42eb, 
+    0x42eb, 0x42ec, 0x42ec, 0x42ec, 0x42ec, 0x42ec, 0x42ec, 0x42ec, 
+    0x42ec, 0x42ed, 0x42ed, 0x42ed, 0x42ed, 0x42ed, 0x42ed, 0x42ed, 
+    0x42ee, 0x42ee, 0x42ee, 0x42ee, 0x42ee, 0x42ee, 0x42ee, 0x42ee, 
+    0x42ef, 0x42ef, 0x42ef, 0x42ef, 0x42ef, 0x42ef, 0x42ef, 0x42ef, 
+    0x42f0, 0x42f0, 0x42f0, 0x42f0, 0x42f0, 0x42f0, 0x42f0, 0x42f0, 
+    0x42f1, 0x42f1, 0x42f1, 0x42f1, 0x42f1, 0x42f1, 0x42f1, 0x42f1, 
+    0x42f2, 0x42f2, 0x42f2, 0x42f2, 0x42f2, 0x42f2, 0x42f2, 0x42f2, 
+    0x42f3, 0x42f3, 0x42f3, 0x42f3, 0x42f3, 0x42f3, 0x42f3, 0x42f3, 
+    0x42f4, 0x42f4, 0x42f4, 0x42f4, 0x42f4, 0x42f4, 0x42f4, 0x42f4, 
+    0x42f5, 0x42f5, 0x42f5, 0x42f5, 0x42f5, 0x42f5, 0x42f5, 0x42f5, 
+    0x42f6, 0x42f6, 0x42f6, 0x42f6, 0x42f6, 0x42f6, 0x42f6, 0x42f6, 
+    0x42f7, 0x42f7, 0x42f7, 0x42f7, 0x42f7, 0x42f7, 0x42f7, 0x42f7, 
+    0x42f8, 0x42f8, 0x42f8, 0x42f8, 0x42f8, 0x42f8, 0x42f8, 0x42f8, 
+    0x42f9, 0x42f9, 0x42f9, 0x42f9, 0x42f9, 0x42f9, 0x42f9, 0x42f9, 
+    0x42fa, 0x42fa, 0x42fa, 0x42fa, 0x42fa, 0x42fa, 0x42fa, 0x42fa, 
+    0x42fb, 0x42fb, 0x42fb, 0x42fb, 0x42fb, 0x42fb, 0x42fb, 0x42fb, 
+    0x42fb, 0x42fc, 0x42fc, 0x42fc, 0x42fc, 0x42fc, 0x42fc, 0x42fc, 
+    0x42fc, 0x42fd, 0x42fd, 0x42fd, 0x42fd, 0x42fd, 0x42fd, 0x42fd, 
+    0x42fd, 0x42fe, 0x42fe, 0x42fe, 0x42fe, 0x42fe, 0x42fe, 0x42fe, 
+    0x42fe, 0x42ff, 0x42ff, 0x42ff, 0x42ff, 0x42ff, 0x42ff, 0x42ff, 
+    0x42ff, 0x42ff, 0x4300, 0x4300, 0x4300, 0x4300, 0x4300, 0x4300, 
+    0x4300, 0x4300, 0x4301, 0x4301, 0x4301, 0x4301, 0x4301, 0x4301, 
+    0x4301, 0x4301, 0x4301, 0x4302, 0x4302, 0x4302, 0x4302, 0x4302, 
+    0x4302, 0x4302, 0x4302, 0x4303, 0x4303, 0x4303, 0x4303, 0x4303, 
+    0x4303, 0x4303, 0x4303, 0x4303, 0x4304, 0x4304, 0x4304, 0x4304, 
+    0x4304, 0x4304, 0x4304, 0x4304, 0x4305, 0x4305, 0x4305, 0x4305, 
+    0x4305, 0x4305, 0x4305, 0x4305, 0x4305, 0x4306, 0x4306, 0x4306, 
+    0x4306, 0x4306, 0x4306, 0x4306, 0x4306, 0x4307, 0x4307, 0x4307, 
+    0x4307, 0x4307, 0x4307, 0x4307, 0x4307, 0x4307, 0x4308, 0x4308, 
+    0x4308, 0x4308, 0x4308, 0x4308, 0x4308, 0x4308, 0x4308, 0x4309, 
+    0x4309, 0x4309, 0x4309, 0x4309, 0x4309, 0x4309, 0x4309, 0x4309, 
+    0x430a, 0x430a, 0x430a, 0x430a, 0x430a, 0x430a, 0x430a, 0x430a, 
+    0x430b, 0x430b, 0x430b, 0x430b, 0x430b, 0x430c, 0x430c, 0x430c, 
+    0x430c, 0x430d, 0x430d, 0x430d, 0x430d, 0x430d, 0x430e, 0x430e, 
+    0x430e, 0x430e, 0x430f, 0x430f, 0x430f, 0x430f, 0x430f, 0x4310, 
+    0x4310, 0x4310, 0x4310, 0x4311, 0x4311, 0x4311, 0x4311, 0x4311, 
+    0x4312, 0x4312, 0x4312, 0x4312, 0x4313, 0x4313, 0x4313, 0x4313, 
+    0x4313, 0x4314, 0x4314, 0x4314, 0x4314, 0x4315, 0x4315, 0x4315, 
+    0x4315, 0x4315, 0x4316, 0x4316, 0x4316, 0x4316, 0x4316, 0x4317, 
+    0x4317, 0x4317, 0x4317, 0x4318, 0x4318, 0x4318, 0x4318, 0x4318, 
+    0x4319, 0x4319, 0x4319, 0x4319, 0x4319, 0x431a, 0x431a, 0x431a, 
+    0x431a, 0x431b, 0x431b, 0x431b, 0x431b, 0x431b, 0x431c, 0x431c, 
+    0x431c, 0x431c, 0x431c, 0x431d, 0x431d, 0x431d, 0x431d, 0x431d, 
+    0x431e, 0x431e, 0x431e, 0x431e, 0x431f, 0x431f, 0x431f, 0x431f, 
+    0x431f, 0x4320, 0x4320, 0x4320, 0x4320, 0x4320, 0x4321, 0x4321, 
+    0x4321, 0x4321, 0x4321, 0x4322, 0x4322, 0x4322, 0x4322, 0x4322, 
+    0x4323, 0x4323, 0x4323, 0x4323, 0x4323, 0x4324, 0x4324, 0x4324, 
+    0x4324, 0x4325, 0x4325, 0x4325, 0x4325, 0x4325, 0x4326, 0x4326, 
+    0x4326, 0x4326, 0x4326, 0x4327, 0x4327, 0x4327, 0x4327, 0x4327, 
+    0x4328, 0x4328, 0x4328, 0x4328, 0x4328, 0x4329, 0x4329, 0x4329, 
+    0x4329, 0x4329, 0x432a, 0x432a, 0x432a, 0x432a, 0x432a, 0x432b, 
+    0x432b, 0x432b, 0x432b, 0x432b, 0x432c, 0x432c, 0x432c, 0x432c, 
+    0x432c, 0x432c, 0x432d, 0x432d, 0x432d, 0x432d, 0x432d, 0x432e, 
+    0x432e, 0x432e, 0x432e, 0x432e, 0x432f, 0x432f, 0x432f, 0x432f, 
+    0x432f, 0x4330, 0x4330, 0x4330, 0x4330, 0x4330, 0x4331, 0x4331, 
+    0x4331, 0x4331, 0x4331, 0x4332, 0x4332, 0x4332, 0x4332, 0x4332, 
+    0x4333, 0x4333, 0x4333, 0x4333, 0x4333, 0x4333, 0x4334, 0x4334, 
+    0x4334, 0x4334, 0x4334, 0x4335, 0x4335, 0x4335, 0x4335, 0x4335, 
+    0x4336, 0x4336, 0x4336, 0x4336, 0x4336, 0x4336, 0x4337, 0x4337, 
+    0x4337, 0x4337, 0x4337, 0x4338, 0x4338, 0x4338, 0x4338, 0x4338, 
+    0x4339, 0x4339, 0x4339, 0x4339, 0x4339, 0x4339, 0x433a, 0x433a, 
+    0x433a, 0x433a, 0x433a, 0x433b, 0x433b, 0x433b, 0x433b, 0x433b, 
+    0x433c, 0x433c, 0x433c, 0x433c, 0x433c, 0x433c, 0x433d, 0x433d, 
+    0x433d, 0x433d, 0x433d, 0x433e, 0x433e, 0x433e, 0x433e, 0x433e, 
+    0x433e, 0x433f, 0x433f, 0x433f, 0x433f, 0x433f, 0x4340, 0x4340, 
+    0x4340, 0x4340, 0x4340, 0x4340, 0x4341, 0x4341, 0x4341, 0x4341, 
+    0x4341, 0x4342, 0x4342, 0x4342, 0x4342, 0x4342, 0x4342, 0x4343, 
+    0x4343, 0x4343, 0x4343, 0x4343, 0x4343, 0x4344, 0x4344, 0x4344, 
+    0x4344, 0x4344, 0x4345, 0x4345, 0x4345, 0x4345, 0x4345, 0x4345, 
+    0x4346, 0x4346, 0x4346, 0x4346, 0x4346, 0x4346, 0x4347, 0x4347, 
+    0x4347, 0x4347, 0x4347, 0x4348, 0x4348, 0x4348, 0x4348, 0x4348, 
+    0x4348, 0x4349, 0x4349, 0x4349, 0x4349, 0x4349, 0x4349, 0x434a, 
+    0x434a, 0x434a, 0x434a, 0x434a, 0x434a, 0x434b, 0x434b, 0x434b, 
+    0x434b, 0x434b, 0x434c, 0x434c, 0x434c, 0x434c, 0x434c, 0x434c, 
+    0x434d, 0x434d, 0x434d, 0x434d, 0x434d, 0x434d, 0x434e, 0x434e, 
+    0x434e, 0x434e, 0x434e, 0x434e, 0x434f, 0x434f, 0x434f, 0x434f, 
+    0x434f, 0x434f, 0x4350, 0x4350, 0x4350, 0x4350, 0x4350, 0x4350, 
+    0x4351, 0x4351, 0x4351, 0x4351, 0x4351, 0x4351, 0x4352, 0x4352, 
+    0x4352, 0x4352, 0x4352, 0x4352, 0x4353, 0x4353, 0x4353, 0x4353, 
+    0x4353, 0x4353, 0x4354, 0x4354, 0x4354, 0x4354, 0x4354, 0x4354, 
+    0x4355, 0x4355, 0x4355, 0x4355, 0x4355, 0x4355, 0x4356, 0x4356, 
+    0x4356, 0x4356, 0x4356, 0x4356, 0x4357, 0x4357, 0x4357, 0x4357, 
+    0x4357, 0x4357, 0x4358, 0x4358, 0x4358, 0x4358, 0x4358, 0x4358, 
+    0x4359, 0x4359, 0x4359, 0x4359, 0x4359, 0x4359, 0x435a, 0x435a, 
+    0x435a, 0x435a, 0x435a, 0x435a, 0x435b, 0x435b, 0x435b, 0x435b, 
+    0x435b, 0x435b, 0x435b, 0x435c, 0x435c, 0x435c, 0x435c, 0x435c, 
+    0x435c, 0x435d, 0x435d, 0x435d, 0x435d, 0x435d, 0x435d, 0x435e, 
+    0x435e, 0x435e, 0x435e, 0x435e, 0x435e, 0x435e, 0x435f, 0x435f, 
+    0x435f, 0x435f, 0x435f, 0x435f, 0x4360, 0x4360, 0x4360, 0x4360, 
+    0x4360, 0x4360, 0x4361, 0x4361, 0x4361, 0x4361, 0x4361, 0x4361, 
+    0x4361, 0x4362, 0x4362, 0x4362, 0x4362, 0x4362, 0x4362, 0x4363, 
+    0x4363, 0x4363, 0x4363, 0x4363, 0x4363, 0x4364, 0x4364, 0x4364, 
+    0x4364, 0x4364, 0x4364, 0x4364, 0x4365, 0x4365, 0x4365, 0x4365, 
+    0x4365, 0x4365, 0x4366, 0x4366, 0x4366, 0x4366, 0x4366, 0x4366, 
+    0x4366, 0x4367, 0x4367, 0x4367, 0x4367, 0x4367, 0x4367, 0x4368, 
+    0x4368, 0x4368, 0x4368, 0x4368, 0x4368, 0x4368, 0x4369, 0x4369, 
+    0x4369, 0x4369, 0x4369, 0x4369, 0x4369, 0x436a, 0x436a, 0x436a, 
+    0x436a, 0x436a, 0x436a, 0x436b, 0x436b, 0x436b, 0x436b, 0x436b, 
+    0x436b, 0x436b, 0x436c, 0x436c, 0x436c, 0x436c, 0x436c, 0x436c, 
+    0x436c, 0x436d, 0x436d, 0x436d, 0x436d, 0x436d, 0x436d, 0x436e, 
+    0x436e, 0x436e, 0x436e, 0x436e, 0x436e, 0x436e, 0x436f, 0x436f, 
+    0x436f, 0x436f, 0x436f, 0x436f, 0x436f, 0x4370, 0x4370, 0x4370, 
+    0x4370, 0x4370, 0x4370, 0x4370, 0x4371, 0x4371, 0x4371, 0x4371, 
+    0x4371, 0x4371, 0x4372, 0x4372, 0x4372, 0x4372, 0x4372, 0x4372, 
+    0x4372, 0x4373, 0x4373, 0x4373, 0x4373, 0x4373, 0x4373, 0x4373, 
+    0x4374, 0x4374, 0x4374, 0x4374, 0x4374, 0x4374, 0x4374, 0x4375, 
+    0x4375, 0x4375, 0x4375, 0x4375, 0x4375, 0x4375, 0x4376, 0x4376, 
+    0x4376, 0x4376, 0x4376, 0x4376, 0x4376, 0x4377, 0x4377, 0x4377, 
+    0x4377, 0x4377, 0x4377, 0x4377, 0x4378, 0x4378, 0x4378, 0x4378, 
+    0x4378, 0x4378, 0x4378, 0x4379, 0x4379, 0x4379, 0x4379, 0x4379, 
+    0x4379, 0x4379, 0x437a, 0x437a, 0x437a, 0x437a, 0x437a, 0x437a, 
+    0x437a, 0x437b, 0x437b, 0x437b, 0x437b, 0x437b, 0x437b, 0x437b, 
+    0x437c, 0x437c, 0x437c, 0x437c, 0x437c, 0x437c, 0x437c, 0x437c, 
+    0x437d, 0x437d, 0x437d, 0x437d, 0x437d, 0x437d, 0x437d, 0x437e, 
+    0x437e, 0x437e, 0x437e, 0x437e, 0x437e, 0x437e, 0x437f, 0x437f, 
+    0x437f, 0x437f, 0x437f, 0x437f, 0x437f, 0x4380, 0x4380, 0x4380, 
+    0x4380, 0x4380, 0x4380, 0x4380, 0x4380, 0x4381, 0x4381, 0x4381, 
+    0x4381, 0x4381, 0x4381, 0x4381, 0x4382, 0x4382, 0x4382, 0x4382, 
+    0x4382, 0x4382, 0x4382, 0x4383, 0x4383, 0x4383, 0x4383, 0x4383, 
+    0x4383, 0x4383, 0x4383, 0x4384, 0x4384, 0x4384, 0x4384, 0x4384, 
+    0x4384, 0x4384, 0x4385, 0x4385, 0x4385, 0x4385, 0x4385, 0x4385, 
+    0x4385, 0x4385, 0x4386, 0x4386, 0x4386, 0x4386, 0x4386, 0x4386, 
+    0x4386, 0x4387, 0x4387, 0x4387, 0x4387, 0x4387, 0x4387, 0x4387, 
+    0x4387, 0x4388, 0x4388, 0x4388, 0x4388, 0x4388, 0x4388, 0x4388, 
+    0x4389, 0x4389, 0x4389, 0x4389, 0x4389, 0x4389, 0x4389, 0x4389, 
+    0x438a, 0x438a, 0x438a, 0x438a, 0x438a, 0x438a, 0x438a, 0x438b, 
+    0x438b, 0x438b, 0x438b, 0x438b, 0x438b, 0x438b, 0x438b, 0x438c, 
+    0x438c, 0x438c, 0x438c, 0x438c, 0x438c, 0x438c, 0x438c, 0x438d, 
+    0x438d, 0x438d, 0x438d, 0x438d, 0x438d, 0x438d, 0x438e, 0x438e, 
+    0x438e, 0x438e, 0x438e, 0x438e, 0x438e, 0x438e, 0x438f, 0x438f, 
+    0x438f, 0x438f, 0x438f, 0x438f, 0x438f, 0x438f, 0x4390, 0x4390, 
+    0x4390, 0x4390, 0x4390, 0x4390, 0x4390, 0x4390, 0x4391, 0x4391, 
+    0x4391, 0x4391, 0x4391, 0x4391, 0x4391, 0x4392, 0x4392, 0x4392, 
+    0x4392, 0x4392, 0x4392, 0x4392, 0x4392, 0x4393, 0x4393, 0x4393, 
+    0x4393, 0x4393, 0x4393, 0x4393, 0x4393, 0x4394, 0x4394, 0x4394, 
+    0x4394, 0x4394, 0x4394, 0x4394, 0x4394, 0x4395, 0x4395, 0x4395, 
+    0x4395, 0x4395, 0x4395, 0x4395, 0x4395, 0x4396, 0x4396, 0x4396, 
+    0x4396, 0x4396, 0x4396, 0x4396, 0x4396, 0x4397, 0x4397, 0x4397, 
+    0x4397, 0x4397, 0x4397, 0x4397, 0x4397, 0x4398, 0x4398, 0x4398, 
+    0x4398, 0x4398, 0x4398, 0x4398, 0x4398, 0x4399, 0x4399, 0x4399, 
+    0x4399, 0x4399, 0x4399, 0x4399, 0x4399, 0x439a, 0x439a, 0x439a, 
+    0x439a, 0x439a, 0x439a, 0x439a, 0x439a, 0x439a, 0x439b, 0x439b, 
+    0x439b, 0x439b, 0x439b, 0x439b, 0x439b, 0x439b, 0x439c, 0x439c, 
+    0x439c, 0x439c, 0x439c, 0x439c, 0x439c, 0x439c, 0x439d, 0x439d, 
+    0x439d, 0x439d, 0x439d, 0x439d, 0x439d, 0x439d, 0x439e, 0x439e, 
+    0x439e, 0x439e, 0x439e, 0x439e, 0x439e, 0x439e, 0x439e, 0x439f, 
+    0x439f, 0x439f, 0x439f, 0x439f, 0x439f, 0x439f, 0x439f, 0x43a0, 
+    0x43a0, 0x43a0, 0x43a0, 0x43a0, 0x43a0, 0x43a0, 0x43a0, 0x43a1, 
+    0x43a1, 0x43a1, 0x43a1, 0x43a1, 0x43a1, 0x43a1, 0x43a1, 0x43a1, 
+    0x43a2, 0x43a2, 0x43a2, 0x43a2, 0x43a2, 0x43a2, 0x43a2, 0x43a2, 
+    0x43a3, 0x43a3, 0x43a3, 0x43a3, 0x43a3, 0x43a3, 0x43a3, 0x43a3, 
+    0x43a3, 0x43a4, 0x43a4, 0x43a4, 0x43a4, 0x43a4, 0x43a4, 0x43a4, 
+    0x43a4, 0x43a5, 0x43a5, 0x43a5, 0x43a5, 0x43a5, 0x43a5, 0x43a5, 
+    0x43a5, 0x43a5, 0x43a6, 0x43a6, 0x43a6, 0x43a6, 0x43a6, 0x43a6, 
+    0x43a6, 0x43a6, 0x43a7, 0x43a7, 0x43a7, 0x43a7, 0x43a7, 0x43a7, 
+    0x43a7, 0x43a7, 0x43a7, 0x43a8, 0x43a8, 0x43a8, 0x43a8, 0x43a8, 
+    0x43a8, 0x43a8, 0x43a8, 0x43a9, 0x43a9, 0x43a9, 0x43a9, 0x43a9, 
+    0x43a9, 0x43a9, 0x43a9, 0x43a9, 0x43aa, 0x43aa, 0x43aa, 0x43aa, 
+    0x43aa, 0x43aa, 0x43aa, 0x43aa, 0x43aa, 0x43ab, 0x43ab, 0x43ab, 
+    0x43ab, 0x43ab, 0x43ab, 0x43ab, 0x43ab, 0x43ab, 0x43ac, 0x43ac, 
+    0x43ac, 0x43ac, 0x43ac, 0x43ad, 0x43ad, 0x43ad, 0x43ad, 0x43ad, 
+    0x43ae, 0x43ae, 0x43ae, 0x43ae, 0x43af, 0x43af, 0x43af, 0x43af, 
+    0x43af, 0x43b0, 0x43b0, 0x43b0, 0x43b0, 0x43b1, 0x43b1, 0x43b1, 
+    0x43b1, 0x43b1, 0x43b2, 0x43b2, 0x43b2, 0x43b2, 0x43b3, 0x43b3, 
+    0x43b3, 0x43b3, 0x43b3, 0x43b4, 0x43b4, 0x43b4, 0x43b4, 0x43b5, 
+    0x43b5, 0x43b5, 0x43b5, 0x43b5, 0x43b6, 0x43b6, 0x43b6, 0x43b6, 
+    0x43b6, 0x43b7, 0x43b7, 0x43b7, 0x43b7, 0x43b8, 0x43b8, 0x43b8, 
+    0x43b8, 0x43b8, 0x43b9, 0x43b9, 0x43b9, 0x43b9, 0x43ba, 0x43ba, 
+    0x43ba, 0x43ba, 0x43ba, 0x43bb, 0x43bb, 0x43bb, 0x43bb, 0x43bb, 
+    0x43bc, 0x43bc, 0x43bc, 0x43bc, 0x43bc, 0x43bd, 0x43bd, 0x43bd, 
+    0x43bd, 0x43be, 0x43be, 0x43be, 0x43be, 0x43be, 0x43bf, 0x43bf, 
+    0x43bf, 0x43bf, 0x43bf, 0x43c0, 0x43c0, 0x43c0, 0x43c0, 0x43c0, 
+    0x43c1, 0x43c1, 0x43c1, 0x43c1, 0x43c2, 0x43c2, 0x43c2, 0x43c2, 
+    0x43c2, 0x43c3, 0x43c3, 0x43c3, 0x43c3, 0x43c3, 0x43c4, 0x43c4, 
+    0x43c4, 0x43c4, 0x43c4, 0x43c5, 0x43c5, 0x43c5, 0x43c5, 0x43c5, 
+    0x43c6, 0x43c6, 0x43c6, 0x43c6, 0x43c6, 0x43c7, 0x43c7, 0x43c7, 
+    0x43c7, 0x43c7, 0x43c8, 0x43c8, 0x43c8, 0x43c8, 0x43c8, 0x43c9, 
+    0x43c9, 0x43c9, 0x43c9, 0x43c9, 0x43ca, 0x43ca, 0x43ca, 0x43ca, 
+    0x43ca, 0x43cb, 0x43cb, 0x43cb, 0x43cb, 0x43cb, 0x43cc, 0x43cc, 
+    0x43cc, 0x43cc, 0x43cc, 0x43cd, 0x43cd, 0x43cd, 0x43cd, 0x43cd, 
+    0x43ce, 0x43ce, 0x43ce, 0x43ce, 0x43ce, 0x43cf, 0x43cf, 0x43cf, 
+    0x43cf, 0x43cf, 0x43d0, 0x43d0, 0x43d0, 0x43d0, 0x43d0, 0x43d1, 
+    0x43d1, 0x43d1, 0x43d1, 0x43d1, 0x43d2, 0x43d2, 0x43d2, 0x43d2, 
+    0x43d2, 0x43d2, 0x43d3, 0x43d3, 0x43d3, 0x43d3, 0x43d3, 0x43d4, 
+    0x43d4, 0x43d4, 0x43d4, 0x43d4, 0x43d5, 0x43d5, 0x43d5, 0x43d5, 
+    0x43d5, 0x43d6, 0x43d6, 0x43d6, 0x43d6, 0x43d6, 0x43d6, 0x43d7, 
+    0x43d7, 0x43d7, 0x43d7, 0x43d7, 0x43d8, 0x43d8, 0x43d8, 0x43d8, 
+    0x43d8, 0x43d9, 0x43d9, 0x43d9, 0x43d9, 0x43d9, 0x43d9, 0x43da, 
+    0x43da, 0x43da, 0x43da, 0x43da, 0x43db, 0x43db, 0x43db, 0x43db, 
+    0x43db, 0x43dc, 0x43dc, 0x43dc, 0x43dc, 0x43dc, 0x43dc, 0x43dd, 
+    0x43dd, 0x43dd, 0x43dd, 0x43dd, 0x43de, 0x43de, 0x43de, 0x43de, 
+    0x43de, 0x43de, 0x43df, 0x43df, 0x43df, 0x43df, 0x43df, 0x43e0, 
+    0x43e0, 0x43e0, 0x43e0, 0x43e0, 0x43e0, 0x43e1, 0x43e1, 0x43e1, 
+    0x43e1, 0x43e1, 0x43e2, 0x43e2, 0x43e2, 0x43e2, 0x43e2, 0x43e2, 
+    0x43e3, 0x43e3, 0x43e3, 0x43e3, 0x43e3, 0x43e4, 0x43e4, 0x43e4, 
+    0x43e4, 0x43e4, 0x43e4, 0x43e5, 0x43e5, 0x43e5, 0x43e5, 0x43e5, 
+    0x43e6, 0x43e6, 0x43e6, 0x43e6, 0x43e6, 0x43e6, 0x43e7, 0x43e7, 
+    0x43e7, 0x43e7, 0x43e7, 0x43e7, 0x43e8, 0x43e8, 0x43e8, 0x43e8, 
+    0x43e8, 0x43e9, 0x43e9, 0x43e9, 0x43e9, 0x43e9, 0x43e9, 0x43ea, 
+    0x43ea, 0x43ea, 0x43ea, 0x43ea, 0x43ea, 0x43eb, 0x43eb, 0x43eb, 
+    0x43eb, 0x43eb, 0x43eb, 0x43ec, 0x43ec, 0x43ec, 0x43ec, 0x43ec, 
+    0x43ec, 0x43ed, 0x43ed, 0x43ed, 0x43ed, 0x43ed, 0x43ee, 0x43ee, 
+    0x43ee, 0x43ee, 0x43ee, 0x43ee, 0x43ef, 0x43ef, 0x43ef, 0x43ef, 
+    0x43ef, 0x43ef, 0x43f0, 0x43f0, 0x43f0, 0x43f0, 0x43f0, 0x43f0, 
+    0x43f1, 0x43f1, 0x43f1, 0x43f1, 0x43f1, 0x43f1, 0x43f2, 0x43f2, 
+    0x43f2, 0x43f2, 0x43f2, 0x43f2, 0x43f3, 0x43f3, 0x43f3, 0x43f3, 
+    0x43f3, 0x43f3, 0x43f4, 0x43f4, 0x43f4, 0x43f4, 0x43f4, 0x43f4, 
+    0x43f5, 0x43f5, 0x43f5, 0x43f5, 0x43f5, 0x43f5, 0x43f6, 0x43f6, 
+    0x43f6, 0x43f6, 0x43f6, 0x43f6, 0x43f7, 0x43f7, 0x43f7, 0x43f7, 
+    0x43f7, 0x43f7, 0x43f8, 0x43f8, 0x43f8, 0x43f8, 0x43f8, 0x43f8, 
+    0x43f9, 0x43f9, 0x43f9, 0x43f9, 0x43f9, 0x43f9, 0x43fa, 0x43fa, 
+    0x43fa, 0x43fa, 0x43fa, 0x43fa, 0x43fb, 0x43fb, 0x43fb, 0x43fb, 
+    0x43fb, 0x43fb, 0x43fb, 0x43fc, 0x43fc, 0x43fc, 0x43fc, 0x43fc, 
+    0x43fc, 0x43fd, 0x43fd, 0x43fd, 0x43fd, 0x43fd, 0x43fd, 0x43fe, 
+    0x43fe, 0x43fe, 0x43fe, 0x43fe, 0x43fe, 0x43ff, 0x43ff, 0x43ff, 
+    0x43ff, 0x43ff, 0x43ff, 0x43ff, 0x4400, 0x4400, 0x4400, 0x4400, 
+    0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x4401, 0x4401, 0x4401, 
+    0x4401, 0x4401, 0x4401, 0x4401, 0x4401, 0x4401, 0x4401, 0x4401, 
+    0x4401, 0x4401, 0x4402, 0x4402, 0x4402, 0x4402, 0x4402, 0x4402, 
+    0x4402, 0x4402, 0x4402, 0x4402, 0x4402, 0x4402, 0x4402, 0x4403, 
+    0x4403, 0x4403, 0x4403, 0x4403, 0x4403, 0x4403, 0x4403, 0x4403, 
+    0x4403, 0x4403, 0x4403, 0x4403, 0x4404, 0x4404, 0x4404, 0x4404, 
+    0x4404, 0x4404, 0x4404, 0x4404, 0x4404, 0x4404, 0x4404, 0x4404, 
+    0x4404, 0x4405, 0x4405, 0x4405, 0x4405, 0x4405, 0x4405, 0x4405, 
+    0x4405, 0x4405, 0x4405, 0x4405, 0x4405, 0x4405, 0x4406, 0x4406, 
+    0x4406, 0x4406, 0x4406, 0x4406, 0x4406, 0x4406, 0x4406, 0x4406, 
+    0x4406, 0x4406, 0x4406, 0x4407, 0x4407, 0x4407, 0x4407, 0x4407, 
+    0x4407, 0x4407, 0x4407, 0x4407, 0x4407, 0x4407, 0x4407, 0x4407, 
+    0x4407, 0x4408, 0x4408, 0x4408, 0x4408, 0x4408, 0x4408, 0x4408, 
+    0x4408, 0x4408, 0x4408, 0x4408, 0x4408, 0x4408, 0x4409, 0x4409, 
+    0x4409, 0x4409, 0x4409, 0x4409, 0x4409, 0x4409, 0x4409, 0x4409, 
+    0x4409, 0x4409, 0x4409, 0x4409, 0x440a, 0x440a, 0x440a, 0x440a, 
+    0x440a, 0x440a, 0x440a, 0x440a, 0x440a, 0x440a, 0x440a, 0x440a, 
+    0x440a, 0x440a, 0x440b, 0x440b, 0x440b, 0x440b, 0x440b, 0x440b, 
+    0x440b, 0x440b, 0x440b, 0x440b, 0x440b, 0x440b, 0x440b, 0x440c, 
+    0x440c, 0x440c, 0x440c, 0x440c, 0x440c, 0x440c, 0x440c, 0x440c, 
+    0x440c, 0x440c, 0x440c, 0x440c, 0x440c, 0x440d, 0x440d, 0x440d, 
+    0x440d, 0x440d, 0x440d, 0x440d, 0x440d, 0x440d, 0x440d, 0x440d, 
+    0x440d, 0x440d, 0x440d, 0x440d, 0x440e, 0x440e, 0x440e, 0x440e, 
+    0x440e, 0x440e, 0x440e, 0x440e, 0x440e, 0x440e, 0x440e, 0x440e, 
+    0x440e, 0x440e, 0x440f, 0x440f, 0x440f, 0x440f, 0x440f, 0x440f, 
+    0x440f, 0x440f, 0x440f, 0x440f, 0x440f, 0x440f, 0x440f, 0x440f, 
+    0x4410, 0x4410, 0x4410, 0x4410, 0x4410, 0x4410, 0x4410, 0x4410, 
+    0x4410, 0x4410, 0x4410, 0x4410, 0x4410, 0x4410, 0x4410, 0x4411, 
+    0x4411, 0x4411, 0x4411, 0x4411, 0x4411, 0x4411, 0x4411, 0x4411, 
+    0x4411, 0x4411, 0x4411, 0x4411, 0x4411, 0x4412, 0x4412, 0x4412, 
+    0x4412, 0x4412, 0x4412, 0x4412, 0x4412, 0x4412, 0x4412, 0x4412, 
+    0x4412, 0x4412, 0x4412, 0x4412, 0x4413, 0x4413, 0x4413, 0x4413, 
+    0x4413, 0x4413, 0x4413, 0x4413, 0x4413, 0x4413, 0x4413, 0x4413, 
+    0x4413, 0x4413, 0x4413, 0x4414, 0x4414, 0x4414, 0x4414, 0x4414, 
+    0x4414, 0x4414, 0x4414, 0x4414, 0x4414, 0x4414, 0x4414, 0x4414, 
+    0x4414, 0x4414, 0x4415, 0x4415, 0x4415, 0x4415, 0x4415, 0x4415, 
+    0x4415, 0x4415, 0x4415, 0x4415, 0x4415, 0x4415, 0x4415, 0x4415, 
+    0x4415, 0x4416, 0x4416, 0x4416, 0x4416, 0x4416, 0x4416, 0x4416, 
+    0x4416, 0x4416, 0x4416, 0x4416, 0x4416, 0x4416, 0x4416, 0x4416, 
+    0x4417, 0x4417, 0x4417, 0x4417, 0x4417, 0x4417, 0x4417, 0x4417, 
+    0x4417, 0x4417, 0x4417, 0x4417, 0x4417, 0x4417, 0x4417, 0x4417, 
+    0x4418, 0x4418, 0x4418, 0x4418, 0x4418, 0x4418, 0x4418, 0x4418, 
+    0x4418, 0x4418, 0x4418, 0x4418, 0x4418, 0x4418, 0x4418, 0x4419, 
+    0x4419, 0x4419, 0x4419, 0x4419, 0x4419, 0x4419, 0x4419, 0x4419, 
+    0x4419, 0x4419, 0x4419, 0x4419, 0x4419, 0x4419, 0x4419, 0x441a, 
+    0x441a, 0x441a, 0x441a, 0x441a, 0x441a, 0x441a, 0x441a, 0x441a, 
+    0x441a, 0x441a, 0x441a, 0x441a, 0x441a, 0x441a, 0x441a, 0x441b, 
+    0x441b, 0x441b, 0x441b, 0x441b, 0x441b, 0x441b, 0x441b, 0x441b, 
+    0x441b, 0x441b, 0x441b, 0x441b, 0x441b, 0x441b, 0x441b, 0x441c, 
+    0x441c, 0x441c, 0x441c, 0x441c, 0x441c, 0x441c, 0x441c, 0x441c, 
+    0x441c, 0x441c, 0x441c, 0x441c, 0x441c, 0x441c, 0x441c, 0x441d, 
+    0x441d, 0x441d, 0x441d, 0x441d, 0x441d, 0x441d, 0x441d, 0x441d, 
+    0x441d, 0x441d, 0x441d, 0x441d, 0x441d, 0x441d, 0x441d, 0x441e, 
+    0x441e, 0x441e, 0x441e, 0x441e, 0x441e, 0x441e, 0x441e, 0x441e, 
+    0x441e, 0x441e, 0x441e, 0x441e, 0x441e, 0x441e, 0x441e, 0x441f, 
+    0x441f, 0x441f, 0x441f, 0x441f, 0x441f, 0x441f, 0x441f, 0x441f, 
+    0x441f, 0x441f, 0x441f, 0x441f, 0x441f, 0x441f, 0x441f, 0x441f, 
+    0x4420, 0x4420, 0x4420, 0x4420, 0x4420, 0x4420, 0x4420, 0x4420, 
+    0x4420, 0x4420, 0x4420, 0x4420, 0x4420, 0x4420, 0x4420, 0x4420, 
+    0x4421, 0x4421, 0x4421, 0x4421, 0x4421, 0x4421, 0x4421, 0x4421, 
+    0x4421, 0x4421, 0x4421, 0x4421, 0x4421, 0x4421, 0x4421, 0x4421, 
+    0x4421, 0x4422, 0x4422, 0x4422, 0x4422, 0x4422, 0x4422, 0x4422, 
+    0x4422, 0x4422, 0x4422, 0x4422, 0x4422, 0x4422, 0x4422, 0x4422, 
+    0x4422, 0x4422, 0x4423, 0x4423, 0x4423, 0x4423, 0x4423, 0x4423, 
+    0x4423, 0x4423, 0x4423, 0x4423, 0x4423, 0x4423, 0x4423, 0x4423, 
+    0x4423, 0x4423, 0x4423, 0x4424, 0x4424, 0x4424, 0x4424, 0x4424, 
+    0x4424, 0x4424, 0x4424, 0x4424, 0x4424, 0x4424, 0x4424, 0x4424, 
+    0x4424, 0x4424, 0x4424, 0x4424, 0x4425, 0x4425, 0x4425, 0x4425, 
+    0x4425, 0x4425, 0x4425, 0x4425, 0x4425, 0x4425, 0x4425, 0x4425, 
+    0x4425, 0x4425, 0x4425, 0x4425, 0x4425, 0x4425, 0x4426, 0x4426, 
+    0x4426, 0x4426, 0x4426, 0x4426, 0x4426, 0x4426, 0x4426, 0x4426, 
+    0x4426, 0x4426, 0x4426, 0x4426, 0x4426, 0x4426, 0x4426, 0x4427, 
+    0x4427, 0x4427, 0x4427, 0x4427, 0x4427, 0x4427, 0x4427, 0x4427, 
+    0x4427, 0x4428, 0x4428, 0x4428, 0x4428, 0x4428, 0x4428, 0x4428, 
+    0x4428, 0x4428, 0x4429, 0x4429, 0x4429, 0x4429, 0x4429, 0x4429, 
+    0x4429, 0x4429, 0x4429, 0x442a, 0x442a, 0x442a, 0x442a, 0x442a, 
+    0x442a, 0x442a, 0x442a, 0x442a, 0x442b, 0x442b, 0x442b, 0x442b, 
+    0x442b, 0x442b, 0x442b, 0x442b, 0x442b, 0x442c, 0x442c, 0x442c, 
+    0x442c, 0x442c, 0x442c, 0x442c, 0x442c, 0x442c, 0x442d, 0x442d, 
+    0x442d, 0x442d, 0x442d, 0x442d, 0x442d, 0x442d, 0x442d, 0x442e, 
+    0x442e, 0x442e, 0x442e, 0x442e, 0x442e, 0x442e, 0x442e, 0x442e, 
+    0x442e, 0x442f, 0x442f, 0x442f, 0x442f, 0x442f, 0x442f, 0x442f, 
+    0x442f, 0x442f, 0x4430, 0x4430, 0x4430, 0x4430, 0x4430, 0x4430, 
+    0x4430, 0x4430, 0x4430, 0x4430, 0x4431, 0x4431, 0x4431, 0x4431, 
+    0x4431, 0x4431, 0x4431, 0x4431, 0x4431, 0x4432, 0x4432, 0x4432, 
+    0x4432, 0x4432, 0x4432, 0x4432, 0x4432, 0x4432, 0x4432, 0x4433, 
+    0x4433, 0x4433, 0x4433, 0x4433, 0x4433, 0x4433, 0x4433, 0x4433, 
+    0x4433, 0x4434, 0x4434, 0x4434, 0x4434, 0x4434, 0x4434, 0x4434, 
+    0x4434, 0x4434, 0x4434, 0x4435, 0x4435, 0x4435, 0x4435, 0x4435, 
+    0x4435, 0x4435, 0x4435, 0x4435, 0x4435, 0x4436, 0x4436, 0x4436, 
+    0x4436, 0x4436, 0x4436, 0x4436, 0x4436, 0x4436, 0x4436, 0x4437, 
+    0x4437, 0x4437, 0x4437, 0x4437, 0x4437, 0x4437, 0x4437, 0x4437, 
+    0x4437, 0x4438, 0x4438, 0x4438, 0x4438, 0x4438, 0x4438, 0x4438, 
+    0x4438, 0x4438, 0x4438, 0x4439, 0x4439, 0x4439, 0x4439, 0x4439, 
+    0x4439, 0x4439, 0x4439, 0x4439, 0x4439, 0x443a, 0x443a, 0x443a, 
+    0x443a, 0x443a, 0x443a, 0x443a, 0x443a, 0x443a, 0x443a, 0x443a, 
+    0x443b, 0x443b, 0x443b, 0x443b, 0x443b, 0x443b, 0x443b, 0x443b, 
+    0x443b, 0x443b, 0x443c, 0x443c, 0x443c, 0x443c, 0x443c, 0x443c, 
+    0x443c, 0x443c, 0x443c, 0x443c, 0x443c, 0x443d, 0x443d, 0x443d, 
+    0x443d, 0x443d, 0x443d, 0x443d, 0x443d, 0x443d, 0x443d, 0x443d, 
+    0x443e, 0x443e, 0x443e, 0x443e, 0x443e, 0x443e, 0x443e, 0x443e, 
+    0x443e, 0x443e, 0x443f, 0x443f, 0x443f, 0x443f, 0x443f, 0x443f, 
+    0x443f, 0x443f, 0x443f, 0x443f, 0x443f, 0x4440, 0x4440, 0x4440, 
+    0x4440, 0x4440, 0x4440, 0x4440, 0x4440, 0x4440, 0x4440, 0x4440, 
+    0x4441, 0x4441, 0x4441, 0x4441, 0x4441, 0x4441, 0x4441, 0x4441, 
+    0x4441, 0x4441, 0x4441, 0x4442, 0x4442, 0x4442, 0x4442, 0x4442, 
+    0x4442, 0x4442, 0x4442, 0x4442, 0x4442, 0x4442, 0x4443, 0x4443, 
+    0x4443, 0x4443, 0x4443, 0x4443, 0x4443, 0x4443, 0x4443, 0x4443, 
+    0x4443, 0x4443, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 
+    0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4445, 0x4445, 0x4445, 
+    0x4445, 0x4445, 0x4445, 0x4445, 0x4445, 0x4445, 0x4445, 0x4445, 
+    0x4446, 0x4446, 0x4446, 0x4446, 0x4446, 0x4446, 0x4446, 0x4446, 
+    0x4446, 0x4446, 0x4446, 0x4446, 0x4447, 0x4447, 0x4447, 0x4447, 
+    0x4447, 0x4447, 0x4447, 0x4447, 0x4447, 0x4447, 0x4447, 0x4448, 
+    0x4448, 0x4448, 0x4448, 0x4448, 0x4448, 0x4448, 0x4448, 0x4448, 
+    0x4448, 0x4448, 0x4448, 0x4449, 0x4449, 0x4449, 0x4449, 0x4449, 
+    0x4449, 0x4449, 0x4449, 0x4449, 0x4449, 0x4449, 0x4449, 0x444a, 
+    0x444a, 0x444a, 0x444a, 0x444a, 0x444a, 0x444a, 0x444a, 0x444a, 
+    0x444a, 0x444a, 0x444a, 0x444b, 0x444b, 0x444b, 0x444b, 0x444b, 
+    0x444b, 0x444b, 0x444b, 0x444b, 0x444b, 0x444b, 0x444b, 0x444c, 
+    0x444c, 0x444c, 0x444c, 0x444c, 0x444c, 0x444c, 0x444c, 0x444c, 
+    0x444c, 0x444c, 0x444c, 0x444d, 0x444d, 0x444d, 0x444d, 0x444d, 
+    0x444d, 0x444d, 0x444d, 0x444d, 0x444d, 0x444d, 0x444d, 0x444e, 
+    0x444e, 0x444e, 0x444e, 0x444e, 0x444e, 0x444e, 0x444e, 0x444e, 
+    0x444e, 0x444e, 0x444e, 0x444e, 0x444f, 0x444f, 0x444f, 0x444f, 
+    0x444f, 0x444f, 0x444f, 0x444f, 0x444f, 0x444f, 0x444f, 0x444f, 
+    0x4450, 0x4450, 0x4450, 0x4450, 0x4450, 0x4450, 0x4450, 0x4450, 
+    0x4450, 0x4450, 0x4450, 0x4450, 0x4450, 0x4451, 0x4451, 0x4451, 
+    0x4451, 0x4451, 0x4451, 0x4451, 0x4451, 0x4451, 0x4451, 0x4451, 
+    0x4451, 0x4452, 0x4452, 0x4452, 0x4452, 0x4452, 0x4452, 0x4452, 
+    0x4452, 0x4452, 0x4452, 0x4452, 0x4452, 0x4452, 0x4453, 0x4453, 
+    0x4453, 0x4453, 0x4453, 0x4453, 0x4453, 0x4453, 0x4453, 0x4453, 
+    0x4453, 0x4453, 0x4453, 0x4454, 0x4454, 0x4454, 0x4454, 0x4454, 
+    0x4454, 0x4454, 0x4454, 0x4454, 0x4454, 0x4454, 0x4454, 0x4454, 
+    0x4455, 0x4455, 0x4455, 0x4455, 0x4455, 0x4455, 0x4455, 0x4455, 
+    0x4455, 0x4455, 0x4455, 0x4455, 0x4455, 0x4456, 0x4456, 0x4456, 
+    0x4456, 0x4456, 0x4456, 0x4456, 0x4456, 0x4456, 0x4456, 0x4456, 
+    0x4456, 0x4456, 0x4457, 0x4457, 0x4457, 0x4457, 0x4457, 0x4457, 
+    0x4457, 0x4457, 0x4457, 0x4457, 0x4457, 0x4457, 0x4457, 0x4457, 
+    0x4458, 0x4458, 0x4458, 0x4458, 0x4458, 0x4458, 0x4458, 0x4458, 
+    0x4458, 0x4458, 0x4458, 0x4458, 0x4458, 0x4459, 0x4459, 0x4459, 
+    0x4459, 0x4459, 0x4459, 0x4459, 0x4459, 0x4459, 0x4459, 0x4459, 
+    0x4459, 0x4459, 0x4459, 0x445a, 0x445a, 0x445a, 0x445a, 0x445a, 
+    0x445a, 0x445a, 0x445a, 0x445a, 0x445a, 0x445a, 0x445a, 0x445a, 
+    0x445b, 0x445b, 0x445b, 0x445b, 0x445b, 0x445b, 0x445b, 0x445b, 
+    0x445b, 0x445b, 0x445b, 0x445b, 0x445b, 0x445b, 0x445c, 0x445c, 
+    0x445c, 0x445c, 0x445c, 0x445c, 0x445c, 0x445c, 0x445c, 0x445c, 
+    0x445c, 0x445c, 0x445c, 0x445c, 0x445d, 0x445d, 0x445d, 0x445d, 
+    0x445d, 0x445d, 0x445d, 0x445d, 0x445d, 0x445d, 0x445d, 0x445d, 
+    0x445d, 0x445d, 0x445e, 0x445e, 0x445e, 0x445e, 0x445e, 0x445e, 
+    0x445e, 0x445e, 0x445e, 0x445e, 0x445e, 0x445e, 0x445e, 0x445e, 
+    0x445f, 0x445f, 0x445f, 0x445f, 0x445f, 0x445f, 0x445f, 0x445f, 
+    0x445f, 0x445f, 0x445f, 0x445f, 0x445f, 0x445f, 0x445f, 0x4460, 
+    0x4460, 0x4460, 0x4460, 0x4460, 0x4460, 0x4460, 0x4460, 0x4460, 
+    0x4460, 0x4460, 0x4460, 0x4460, 0x4460, 0x4461, 0x4461, 0x4461, 
+    0x4461, 0x4461, 0x4461, 0x4461, 0x4461, 0x4461, 0x4461, 0x4461, 
+    0x4461, 0x4461, 0x4461, 0x4461, 0x4462, 0x4462, 0x4462, 0x4462, 
+    0x4462, 0x4462, 0x4462, 0x4462, 0x4462, 0x4462, 0x4462, 0x4462, 
+    0x4462, 0x4462, 0x4463, 0x4463, 0x4463, 0x4463, 0x4463, 0x4463, 
+    0x4463, 0x4463, 0x4463, 0x4463, 0x4463, 0x4463, 0x4463, 0x4463, 
+    0x4463, 0x4464, 0x4464, 0x4464, 0x4464, 0x4464, 0x4464, 0x4464, 
+    0x4464, 0x4464, 0x4464, 0x4464, 0x4464, 0x4464, 0x4464, 0x4464, 
+    0x4465, 0x4465, 0x4465, 0x4465, 0x4465, 0x4465, 0x4465, 0x4465, 
+    0x4465, 0x4465, 0x4465, 0x4465, 0x4465, 0x4465, 0x4465, 0x4466, 
+    0x4466, 0x4466, 0x4466, 0x4466, 0x4466, 0x4466, 0x4466, 0x4466, 
+    0x4466, 0x4466, 0x4466, 0x4466, 0x4466, 0x4466, 0x4467, 0x4467, 
+    0x4467, 0x4467, 0x4467, 0x4467, 0x4467, 0x4467, 0x4467, 0x4467, 
+    0x4467, 0x4467, 0x4467, 0x4467, 0x4467, 0x4467, 0x4468, 0x4468, 
+    0x4468, 0x4468, 0x4468, 0x4468, 0x4468, 0x4468, 0x4468, 0x4468, 
+    0x4468, 0x4468, 0x4468, 0x4468, 0x4468, 0x4469, 0x4469, 0x4469, 
+    0x4469, 0x4469, 0x4469, 0x4469, 0x4469, 0x4469, 0x4469, 0x4469, 
+    0x4469, 0x4469, 0x4469, 0x4469, 0x4469, 0x446a, 0x446a, 0x446a, 
+    0x446a, 0x446a, 0x446a, 0x446a, 0x446a, 0x446a, 0x446a, 0x446a, 
+    0x446a, 0x446a, 0x446a, 0x446a, 0x446b, 0x446b, 0x446b, 0x446b, 
+    0x446b, 0x446b, 0x446b, 0x446b, 0x446b, 0x446b, 0x446b, 0x446b, 
+    0x446b, 0x446b, 0x446b, 0x446b, 0x446c, 0x446c, 0x446c, 0x446c, 
+    0x446c, 0x446c, 0x446c, 0x446c, 0x446c, 0x446c, 0x446c, 0x446c, 
+    0x446c, 0x446c, 0x446c, 0x446c, 0x446d, 0x446d, 0x446d, 0x446d, 
+    0x446d, 0x446d, 0x446d, 0x446d, 0x446d, 0x446d, 0x446d, 0x446d, 
+    0x446d, 0x446d, 0x446d, 0x446d, 0x446e, 0x446e, 0x446e, 0x446e, 
+    0x446e, 0x446e, 0x446e, 0x446e, 0x446e, 0x446e, 0x446e, 0x446e, 
+    0x446e, 0x446e, 0x446e, 0x446e, 0x446e, 0x446f, 0x446f, 0x446f, 
+    0x446f, 0x446f, 0x446f, 0x446f, 0x446f, 0x446f, 0x446f, 0x446f, 
+    0x446f, 0x446f, 0x446f, 0x446f, 0x446f, 0x4470, 0x4470, 0x4470, 
+    0x4470, 0x4470, 0x4470, 0x4470, 0x4470, 0x4470, 0x4470, 0x4470, 
+    0x4470, 0x4470, 0x4470, 0x4470, 0x4470, 0x4471, 0x4471, 0x4471, 
+    0x4471, 0x4471, 0x4471, 0x4471, 0x4471, 0x4471, 0x4471, 0x4471, 
+    0x4471, 0x4471, 0x4471, 0x4471, 0x4471, 0x4471, 0x4472, 0x4472, 
+    0x4472, 0x4472, 0x4472, 0x4472, 0x4472, 0x4472, 0x4472, 0x4472, 
+    0x4472, 0x4472, 0x4472, 0x4472, 0x4472, 0x4472, 0x4472, 0x4473, 
+    0x4473, 0x4473, 0x4473, 0x4473, 0x4473, 0x4473, 0x4473, 0x4473, 
+    0x4473, 0x4473, 0x4473, 0x4473, 0x4473, 0x4473, 0x4473, 0x4473, 
+    0x4474, 0x4474, 0x4474, 0x4474, 0x4474, 0x4474, 0x4474, 0x4474, 
+    0x4474, 0x4474, 0x4474, 0x4474, 0x4474, 0x4474, 0x4474, 0x4474, 
+    0x4474, 0x4475, 0x4475, 0x4475, 0x4475, 0x4475, 0x4475, 0x4475, 
+    0x4475, 0x4475, 0x4475, 0x4475, 0x4475, 0x4475, 0x4475, 0x4475, 
+    0x4475, 0x4475, 0x4476, 0x4476, 0x4476, 0x4476, 0x4476, 0x4476, 
+    0x4476, 0x4476, 0x4476, 0x4476, 0x4476, 0x4476, 0x4476, 0x4476, 
+    0x4476, 0x4476, 0x4476, 0x4476, 0x4477, 0x4477, 0x4477, 0x4477, 
+    0x4477, 0x4477, 0x4477, 0x4477, 0x4477, 0x4477, 0x4477, 0x4477, 
+    0x4477, 0x4477, 0x4477, 0x4478, 0x4478, 0x4478, 0x4478, 0x4478, 
+    0x4478, 0x4478, 0x4478, 0x4478, 0x4479, 0x4479, 0x4479, 0x4479, 
+    0x4479, 0x4479, 0x4479, 0x4479, 0x4479, 0x447a, 0x447a, 0x447a, 
+    0x447a, 0x447a, 0x447a, 0x447a, 0x447a, 0x447a, 0x447b, 0x447b, 
+    0x447b, 0x447b, 0x447b, 0x447b, 0x447b, 0x447b, 0x447b, 0x447c, 
+    0x447c, 0x447c, 0x447c, 0x447c, 0x447c, 0x447c, 0x447c, 0x447c, 
+    0x447d, 0x447d, 0x447d, 0x447d, 0x447d, 0x447d, 0x447d, 0x447d, 
+    0x447d, 0x447e, 0x447e, 0x447e, 0x447e, 0x447e, 0x447e, 0x447e, 
+    0x447e, 0x447e, 0x447e, 0x447f, 0x447f, 0x447f, 0x447f, 0x447f, 
+    0x447f, 0x447f, 0x447f, 0x447f, 0x4480, 0x4480, 0x4480, 0x4480, 
+    0x4480, 0x4480, 0x4480, 0x4480, 0x4480, 0x4481, 0x4481, 0x4481, 
+    0x4481, 0x4481, 0x4481, 0x4481, 0x4481, 0x4481, 0x4481, 0x4482, 
+    0x4482, 0x4482, 0x4482, 0x4482, 0x4482, 0x4482, 0x4482, 0x4482, 
+    0x4482, 0x4483, 0x4483, 0x4483, 0x4483, 0x4483, 0x4483, 0x4483, 
+    0x4483, 0x4483, 0x4484, 0x4484, 0x4484, 0x4484, 0x4484, 0x4484, 
+    0x4484, 0x4484, 0x4484, 0x4484, 0x4485, 0x4485, 0x4485, 0x4485, 
+    0x4485, 0x4485, 0x4485, 0x4485, 0x4485, 0x4485, 0x4486, 0x4486, 
+    0x4486, 0x4486, 0x4486, 0x4486, 0x4486, 0x4486, 0x4486, 0x4486, 
+    0x4487, 0x4487, 0x4487, 0x4487, 0x4487, 0x4487, 0x4487, 0x4487, 
+    0x4487, 0x4487, 0x4488, 0x4488, 0x4488, 0x4488, 0x4488, 0x4488, 
+    0x4488, 0x4488, 0x4488, 0x4488, 0x4489, 0x4489, 0x4489, 0x4489, 
+    0x4489, 0x4489, 0x4489, 0x4489, 0x4489, 0x4489, 0x4489, 0x448a, 
+    0x448a, 0x448a, 0x448a, 0x448a, 0x448a, 0x448a, 0x448a, 0x448a, 
+    0x448a, 0x448b, 0x448b, 0x448b, 0x448b, 0x448b, 0x448b, 0x448b, 
+    0x448b, 0x448b, 0x448b, 0x448c, 0x448c, 0x448c, 0x448c, 0x448c, 
+    0x448c, 0x448c, 0x448c, 0x448c, 0x448c, 0x448c, 0x448d, 0x448d, 
+    0x448d, 0x448d, 0x448d, 0x448d, 0x448d, 0x448d, 0x448d, 0x448d, 
+    0x448d, 0x448e, 0x448e, 0x448e, 0x448e, 0x448e, 0x448e, 0x448e, 
+    0x448e, 0x448e, 0x448e, 0x448f, 0x448f, 0x448f, 0x448f, 0x448f, 
+    0x448f, 0x448f, 0x448f, 0x448f, 0x448f, 0x448f, 0x4490, 0x4490, 
+    0x4490, 0x4490, 0x4490, 0x4490, 0x4490, 0x4490, 0x4490, 0x4490, 
+    0x4490, 0x4491, 0x4491, 0x4491, 0x4491, 0x4491, 0x4491, 0x4491, 
+    0x4491, 0x4491, 0x4491, 0x4491, 0x4492, 0x4492, 0x4492, 0x4492, 
+    0x4492, 0x4492, 0x4492, 0x4492, 0x4492, 0x4492, 0x4492, 0x4493, 
+    0x4493, 0x4493, 0x4493, 0x4493, 0x4493, 0x4493, 0x4493, 0x4493, 
+    0x4493, 0x4493, 0x4494, 0x4494, 0x4494, 0x4494, 0x4494, 0x4494, 
+    0x4494, 0x4494, 0x4494, 0x4494, 0x4494, 0x4495, 0x4495, 0x4495, 
+    0x4495, 0x4495, 0x4495, 0x4495, 0x4495, 0x4495, 0x4495, 0x4495, 
+    0x4495, 0x4496, 0x4496, 0x4496, 0x4496, 0x4496, 0x4496, 0x4496, 
+    0x4496, 0x4496, 0x4496, 0x4496, 0x4497, 0x4497, 0x4497, 0x4497, 
+    0x4497, 0x4497, 0x4497, 0x4497, 0x4497, 0x4497, 0x4497, 0x4497, 
+    0x4498, 0x4498, 0x4498, 0x4498, 0x4498, 0x4498, 0x4498, 0x4498, 
+    0x4498, 0x4498, 0x4498, 0x4499, 0x4499, 0x4499, 0x4499, 0x4499, 
+    0x4499, 0x4499, 0x4499, 0x4499, 0x4499, 0x4499, 0x4499, 0x449a, 
+    0x449a, 0x449a, 0x449a, 0x449a, 0x449a, 0x449a, 0x449a, 0x449a, 
+    0x449a, 0x449a, 0x449a, 0x449b, 0x449b, 0x449b, 0x449b, 0x449b, 
+    0x449b, 0x449b, 0x449b, 0x449b, 0x449b, 0x449b, 0x449b, 0x449c, 
+    0x449c, 0x449c, 0x449c, 0x449c, 0x449c, 0x449c, 0x449c, 0x449c, 
+    0x449c, 0x449c, 0x449c, 0x449d, 0x449d, 0x449d, 0x449d, 0x449d, 
+    0x449d, 0x449d, 0x449d, 0x449d, 0x449d, 0x449d, 0x449d, 0x449e, 
+    0x449e, 0x449e, 0x449e, 0x449e, 0x449e, 0x449e, 0x449e, 0x449e, 
+    0x449e, 0x449e, 0x449e, 0x449e, 0x449f, 0x449f, 0x449f, 0x449f, 
+    0x449f, 0x449f, 0x449f, 0x449f, 0x449f, 0x449f, 0x449f, 0x449f, 
+    0x44a0, 0x44a0, 0x44a0, 0x44a0, 0x44a0, 0x44a0, 0x44a0, 0x44a0, 
+    0x44a0, 0x44a0, 0x44a0, 0x44a0, 0x44a1, 0x44a1, 0x44a1, 0x44a1, 
+    0x44a1, 0x44a1, 0x44a1, 0x44a1, 0x44a1, 0x44a1, 0x44a1, 0x44a1, 
+    0x44a1, 0x44a2, 0x44a2, 0x44a2, 0x44a2, 0x44a2, 0x44a2, 0x44a2, 
+    0x44a2, 0x44a2, 0x44a2, 0x44a2, 0x44a2, 0x44a2, 0x44a3, 0x44a3, 
+    0x44a3, 0x44a3, 0x44a3, 0x44a3, 0x44a3, 0x44a3, 0x44a3, 0x44a3, 
+    0x44a3, 0x44a3, 0x44a3, 0x44a4, 0x44a4, 0x44a4, 0x44a4, 0x44a4, 
+    0x44a4, 0x44a4, 0x44a4, 0x44a4, 0x44a4, 0x44a4, 0x44a4, 0x44a5, 
+    0x44a5, 0x44a5, 0x44a5, 0x44a5, 0x44a5, 0x44a5, 0x44a5, 0x44a5, 
+    0x44a5, 0x44a5, 0x44a5, 0x44a5, 0x44a5, 0x44a6, 0x44a6, 0x44a6, 
+    0x44a6, 0x44a6, 0x44a6, 0x44a6, 0x44a6, 0x44a6, 0x44a6, 0x44a6, 
+    0x44a6, 0x44a6, 0x44a7, 0x44a7, 0x44a7, 0x44a7, 0x44a7, 0x44a7, 
+    0x44a7, 0x44a7, 0x44a7, 0x44a7, 0x44a7, 0x44a7, 0x44a7, 0x44a8, 
+    0x44a8, 0x44a8, 0x44a8, 0x44a8, 0x44a8, 0x44a8, 0x44a8, 0x44a8, 
+    0x44a8, 0x44a8, 0x44a8, 0x44a8, 0x44a9, 0x44a9, 0x44a9, 0x44a9, 
+    0x44a9, 0x44a9, 0x44a9, 0x44a9, 0x44a9, 0x44a9, 0x44a9, 0x44a9, 
+    0x44a9, 0x44a9, 0x44aa, 0x44aa, 0x44aa, 0x44aa, 0x44aa, 0x44aa, 
+    0x44aa, 0x44aa, 0x44aa, 0x44aa, 0x44aa, 0x44aa, 0x44aa, 0x44ab, 
+    0x44ab, 0x44ab, 0x44ab, 0x44ab, 0x44ab, 0x44ab, 0x44ab, 0x44ab, 
+    0x44ab, 0x44ab, 0x44ab, 0x44ab, 0x44ab, 0x44ac, 0x44ac, 0x44ac, 
+    0x44ac, 0x44ac, 0x44ac, 0x44ac, 0x44ac, 0x44ac, 0x44ac, 0x44ac, 
+    0x44ac, 0x44ac, 0x44ac, 0x44ad, 0x44ad, 0x44ad, 0x44ad, 0x44ad, 
+    0x44ad, 0x44ad, 0x44ad, 0x44ad, 0x44ad, 0x44ad, 0x44ad, 0x44ad, 
+    0x44ad, 0x44ae, 0x44ae, 0x44ae, 0x44ae, 0x44ae, 0x44ae, 0x44ae, 
+    0x44ae, 0x44ae, 0x44ae, 0x44ae, 0x44ae, 0x44ae, 0x44ae, 0x44af, 
+    0x44af, 0x44af, 0x44af, 0x44af, 0x44af, 0x44af, 0x44af, 0x44af, 
+    0x44af, 0x44af, 0x44af, 0x44af, 0x44af, 0x44b0, 0x44b0, 0x44b0, 
+    0x44b0, 0x44b0, 0x44b0, 0x44b0, 0x44b0, 0x44b0, 0x44b0, 0x44b0, 
+    0x44b0, 0x44b0, 0x44b0, 0x44b0, 0x44b1, 0x44b1, 0x44b1, 0x44b1, 
+    0x44b1, 0x44b1, 0x44b1, 0x44b1, 0x44b1, 0x44b1, 0x44b1, 0x44b1, 
+    0x44b1, 0x44b1, 0x44b2, 0x44b2, 0x44b2, 0x44b2, 0x44b2, 0x44b2, 
+    0x44b2, 0x44b2, 0x44b2, 0x44b2, 0x44b2, 0x44b2, 0x44b2, 0x44b2, 
+    0x44b2, 0x44b3, 0x44b3, 0x44b3, 0x44b3, 0x44b3, 0x44b3, 0x44b3, 
+    0x44b3, 0x44b3, 0x44b3, 0x44b3, 0x44b3, 0x44b3, 0x44b3, 0x44b4, 
+    0x44b4, 0x44b4, 0x44b4, 0x44b4, 0x44b4, 0x44b4, 0x44b4, 0x44b4, 
+    0x44b4, 0x44b4, 0x44b4, 0x44b4, 0x44b4, 0x44b4, 0x44b5, 0x44b5, 
+    0x44b5, 0x44b5, 0x44b5, 0x44b5, 0x44b5, 0x44b5, 0x44b5, 0x44b5, 
+    0x44b5, 0x44b5, 0x44b5, 0x44b5, 0x44b5, 0x44b6, 0x44b6, 0x44b6, 
+    0x44b6, 0x44b6, 0x44b6, 0x44b6, 0x44b6, 0x44b6, 0x44b6, 0x44b6, 
+    0x44b6, 0x44b6, 0x44b6, 0x44b6, 0x44b7, 0x44b7, 0x44b7, 0x44b7, 
+    0x44b7, 0x44b7, 0x44b7, 0x44b7, 0x44b7, 0x44b7, 0x44b7, 0x44b7, 
+    0x44b7, 0x44b7, 0x44b7, 0x44b8, 0x44b8, 0x44b8, 0x44b8, 0x44b8, 
+    0x44b8, 0x44b8, 0x44b8, 0x44b8, 0x44b8, 0x44b8, 0x44b8, 0x44b8, 
+    0x44b8, 0x44b8, 0x44b8, 0x44b9, 0x44b9, 0x44b9, 0x44b9, 0x44b9, 
+    0x44b9, 0x44b9, 0x44b9, 0x44b9, 0x44b9, 0x44b9, 0x44b9, 0x44b9, 
+    0x44b9, 0x44b9, 0x44ba, 0x44ba, 0x44ba, 0x44ba, 0x44ba, 0x44ba, 
+    0x44ba, 0x44ba, 0x44ba, 0x44ba, 0x44ba, 0x44ba, 0x44ba, 0x44ba, 
+    0x44ba, 0x44ba, 0x44bb, 0x44bb, 0x44bb, 0x44bb, 0x44bb, 0x44bb, 
+    0x44bb, 0x44bb, 0x44bb, 0x44bb, 0x44bb, 0x44bb, 0x44bb, 0x44bb, 
+    0x44bb, 0x44bb, 0x44bc, 0x44bc, 0x44bc, 0x44bc, 0x44bc, 0x44bc, 
+    0x44bc, 0x44bc, 0x44bc, 0x44bc, 0x44bc, 0x44bc, 0x44bc, 0x44bc, 
+    0x44bc, 0x44bc, 0x44bd, 0x44bd, 0x44bd, 0x44bd, 0x44bd, 0x44bd, 
+    0x44bd, 0x44bd, 0x44bd, 0x44bd, 0x44bd, 0x44bd, 0x44bd, 0x44bd, 
+    0x44bd, 0x44bd, 0x44be, 0x44be, 0x44be, 0x44be, 0x44be, 0x44be, 
+    0x44be, 0x44be, 0x44be, 0x44be, 0x44be, 0x44be, 0x44be, 0x44be, 
+    0x44be, 0x44be, 0x44bf, 0x44bf, 0x44bf, 0x44bf, 0x44bf, 0x44bf, 
+    0x44bf, 0x44bf, 0x44bf, 0x44bf, 0x44bf, 0x44bf, 0x44bf, 0x44bf, 
+    0x44bf, 0x44bf, 0x44c0, 0x44c0, 0x44c0, 0x44c0, 0x44c0, 0x44c0, 
+    0x44c0, 0x44c0, 0x44c0, 0x44c0, 0x44c0, 0x44c0, 0x44c0, 0x44c0, 
+    0x44c0, 0x44c0, 0x44c0, 0x44c1, 0x44c1, 0x44c1, 0x44c1, 0x44c1, 
+    0x44c1, 0x44c1, 0x44c1, 0x44c1, 0x44c1, 0x44c1, 0x44c1, 0x44c1, 
+    0x44c1, 0x44c1, 0x44c1, 0x44c2, 0x44c2, 0x44c2, 0x44c2, 0x44c2, 
+    0x44c2, 0x44c2, 0x44c2, 0x44c2, 0x44c2, 0x44c2, 0x44c2, 0x44c2, 
+    0x44c2, 0x44c2, 0x44c2, 0x44c2, 0x44c3, 0x44c3, 0x44c3, 0x44c3, 
+    0x44c3, 0x44c3, 0x44c3, 0x44c3, 0x44c3, 0x44c3, 0x44c3, 0x44c3, 
+    0x44c3, 0x44c3, 0x44c3, 0x44c3, 0x44c3, 0x44c4, 0x44c4, 0x44c4, 
+    0x44c4, 0x44c4, 0x44c4, 0x44c4, 0x44c4, 0x44c4, 0x44c4, 0x44c4, 
+    0x44c4, 0x44c4, 0x44c4, 0x44c4, 0x44c4, 0x44c4, 0x44c5, 0x44c5, 
+    0x44c5, 0x44c5, 0x44c5, 0x44c5, 0x44c5, 0x44c5, 0x44c5, 0x44c5, 
+    0x44c5, 0x44c5, 0x44c5, 0x44c5, 0x44c5, 0x44c5, 0x44c5, 0x44c6, 
+    0x44c6, 0x44c6, 0x44c6, 0x44c6, 0x44c6, 0x44c6, 0x44c6, 0x44c6, 
+    0x44c6, 0x44c6, 0x44c6, 0x44c6, 0x44c6, 0x44c6, 0x44c6, 0x44c6, 
+    0x44c7, 0x44c7, 0x44c7, 0x44c7, 0x44c7, 0x44c7, 0x44c7, 0x44c7, 
+    0x44c7, 0x44c7, 0x44c7, 0x44c7, 0x44c7, 0x44c7, 0x44c7, 0x44c7, 
+    0x44c7, 0x44c7, 0x44c8, 0x44c8, 0x44c8, 0x44c8, 0x44c8, 0x44c8, 
+    0x44c8, 0x44c8, 0x44c8, 0x44c8, 0x44c8, 0x44c8, 0x44c9, 0x44c9, 
+    0x44c9, 0x44c9, 0x44c9, 0x44c9, 0x44c9, 0x44c9, 0x44c9, 0x44ca, 
+    0x44ca, 0x44ca, 0x44ca, 0x44ca, 0x44ca, 0x44ca, 0x44ca, 0x44ca, 
+    0x44cb, 0x44cb, 0x44cb, 0x44cb, 0x44cb, 0x44cb, 0x44cb, 0x44cb, 
+    0x44cb, 0x44cc, 0x44cc, 0x44cc, 0x44cc, 0x44cc, 0x44cc, 0x44cc, 
+    0x44cc, 0x44cc, 0x44cd, 0x44cd, 0x44cd, 0x44cd, 0x44cd, 0x44cd, 
+    0x44cd, 0x44cd, 0x44cd, 0x44ce, 0x44ce, 0x44ce, 0x44ce, 0x44ce, 
+    0x44ce, 0x44ce, 0x44ce, 0x44ce, 0x44cf, 0x44cf, 0x44cf, 0x44cf, 
+    0x44cf, 0x44cf, 0x44cf, 0x44cf, 0x44cf, 0x44cf, 0x44d0, 0x44d0, 
+    0x44d0, 0x44d0, 0x44d0, 0x44d0, 0x44d0, 0x44d0, 0x44d0, 0x44d1, 
+    0x44d1, 0x44d1, 0x44d1, 0x44d1, 0x44d1, 0x44d1, 0x44d1, 0x44d1, 
+    0x44d1, 0x44d2, 0x44d2, 0x44d2, 0x44d2, 0x44d2, 0x44d2, 0x44d2, 
+    0x44d2, 0x44d2, 0x44d3, 0x44d3, 0x44d3, 0x44d3, 0x44d3, 0x44d3, 
+    0x44d3, 0x44d3, 0x44d3, 0x44d3, 0x44d4, 0x44d4, 0x44d4, 0x44d4, 
+    0x44d4, 0x44d4, 0x44d4, 0x44d4, 0x44d4, 0x44d4, 0x44d5, 0x44d5, 
+    0x44d5, 0x44d5, 0x44d5, 0x44d5, 0x44d5, 0x44d5, 0x44d5, 0x44d5, 
+    0x44d6, 0x44d6, 0x44d6, 0x44d6, 0x44d6, 0x44d6, 0x44d6, 0x44d6, 
+    0x44d6, 0x44d6, 0x44d7, 0x44d7, 0x44d7, 0x44d7, 0x44d7, 0x44d7, 
+    0x44d7, 0x44d7, 0x44d7, 0x44d7, 0x44d8, 0x44d8, 0x44d8, 0x44d8, 
+    0x44d8, 0x44d8, 0x44d8, 0x44d8, 0x44d8, 0x44d8, 0x44d9, 0x44d9, 
+    0x44d9, 0x44d9, 0x44d9, 0x44d9, 0x44d9, 0x44d9, 0x44d9, 0x44d9, 
+    0x44da, 0x44da, 0x44da, 0x44da, 0x44da, 0x44da, 0x44da, 0x44da, 
+    0x44da, 0x44da, 0x44db, 0x44db, 0x44db, 0x44db, 0x44db, 0x44db, 
+    0x44db, 0x44db, 0x44db, 0x44db, 0x44db, 0x44dc, 0x44dc, 0x44dc, 
+    0x44dc, 0x44dc, 0x44dc, 0x44dc, 0x44dc, 0x44dc, 0x44dc, 0x44dd, 
+    0x44dd, 0x44dd, 0x44dd, 0x44dd, 0x44dd, 0x44dd, 0x44dd, 0x44dd, 
+    0x44dd, 0x44dd, 0x44de, 0x44de, 0x44de, 0x44de, 0x44de, 0x44de, 
+    0x44de, 0x44de, 0x44de, 0x44de, 0x44df, 0x44df, 0x44df, 0x44df, 
+    0x44df, 0x44df, 0x44df, 0x44df, 0x44df, 0x44df, 0x44df, 0x44e0, 
+    0x44e0, 0x44e0, 0x44e0, 0x44e0, 0x44e0, 0x44e0, 0x44e0, 0x44e0, 
+    0x44e0, 0x44e0, 0x44e1, 0x44e1, 0x44e1, 0x44e1, 0x44e1, 0x44e1, 
+    0x44e1, 0x44e1, 0x44e1, 0x44e1, 0x44e1, 0x44e2, 0x44e2, 0x44e2, 
+    0x44e2, 0x44e2, 0x44e2, 0x44e2, 0x44e2, 0x44e2, 0x44e2, 0x44e2, 
+    0x44e3, 0x44e3, 0x44e3, 0x44e3, 0x44e3, 0x44e3, 0x44e3, 0x44e3, 
+    0x44e3, 0x44e3, 0x44e3, 0x44e4, 0x44e4, 0x44e4, 0x44e4, 0x44e4, 
+    0x44e4, 0x44e4, 0x44e4, 0x44e4, 0x44e4, 0x44e4, 0x44e5, 0x44e5, 
+    0x44e5, 0x44e5, 0x44e5, 0x44e5, 0x44e5, 0x44e5, 0x44e5, 0x44e5, 
+    0x44e5, 0x44e6, 0x44e6, 0x44e6, 0x44e6, 0x44e6, 0x44e6, 0x44e6, 
+    0x44e6, 0x44e6, 0x44e6, 0x44e6, 0x44e6, 0x44e7, 0x44e7, 0x44e7, 
+    0x44e7, 0x44e7, 0x44e7, 0x44e7, 0x44e7, 0x44e7, 0x44e7, 0x44e7, 
+    0x44e8, 0x44e8, 0x44e8, 0x44e8, 0x44e8, 0x44e8, 0x44e8, 0x44e8, 
+    0x44e8, 0x44e8, 0x44e8, 0x44e8, 0x44e9, 0x44e9, 0x44e9, 0x44e9, 
+    0x44e9, 0x44e9, 0x44e9, 0x44e9, 0x44e9, 0x44e9, 0x44e9, 0x44ea, 
+    0x44ea, 0x44ea, 0x44ea, 0x44ea, 0x44ea, 0x44ea, 0x44ea, 0x44ea, 
+    0x44ea, 0x44ea, 0x44ea, 0x44eb, 0x44eb, 0x44eb, 0x44eb, 0x44eb, 
+    0x44eb, 0x44eb, 0x44eb, 0x44eb, 0x44eb, 0x44eb, 0x44eb, 0x44ec, 
+    0x44ec, 0x44ec, 0x44ec, 0x44ec, 0x44ec, 0x44ec, 0x44ec, 0x44ec, 
+    0x44ec, 0x44ec, 0x44ec, 0x44ed, 0x44ed, 0x44ed, 0x44ed, 0x44ed, 
+    0x44ed, 0x44ed, 0x44ed, 0x44ed, 0x44ed, 0x44ed, 0x44ed, 0x44ee, 
+    0x44ee, 0x44ee, 0x44ee, 0x44ee, 0x44ee, 0x44ee, 0x44ee, 0x44ee, 
+    0x44ee, 0x44ee, 0x44ee, 0x44ef, 0x44ef, 0x44ef, 0x44ef, 0x44ef, 
+    0x44ef, 0x44ef, 0x44ef, 0x44ef, 0x44ef, 0x44ef, 0x44ef, 0x44ef, 
+    0x44f0, 0x44f0, 0x44f0, 0x44f0, 0x44f0, 0x44f0, 0x44f0, 0x44f0, 
+    0x44f0, 0x44f0, 0x44f0, 0x44f0, 0x44f1, 0x44f1, 0x44f1, 0x44f1, 
+    0x44f1, 0x44f1, 0x44f1, 0x44f1, 0x44f1, 0x44f1, 0x44f1, 0x44f1, 
+    0x44f1, 0x44f2, 0x44f2, 0x44f2, 0x44f2, 0x44f2, 0x44f2, 0x44f2, 
+    0x44f2, 0x44f2, 0x44f2, 0x44f2, 0x44f2, 0x44f3, 0x44f3, 0x44f3, 
+    0x44f3, 0x44f3, 0x44f3, 0x44f3, 0x44f3, 0x44f3, 0x44f3, 0x44f3, 
+    0x44f3, 0x44f3, 0x44f4, 0x44f4, 0x44f4, 0x44f4, 0x44f4, 0x44f4, 
+    0x44f4, 0x44f4, 0x44f4, 0x44f4, 0x44f4, 0x44f4, 0x44f4, 0x44f5, 
+    0x44f5, 0x44f5, 0x44f5, 0x44f5, 0x44f5, 0x44f5, 0x44f5, 0x44f5, 
+    0x44f5, 0x44f5, 0x44f5, 0x44f5, 0x44f6, 0x44f6, 0x44f6, 0x44f6, 
+    0x44f6, 0x44f6, 0x44f6, 0x44f6, 0x44f6, 0x44f6, 0x44f6, 0x44f6, 
+    0x44f6, 0x44f7, 0x44f7, 0x44f7, 0x44f7, 0x44f7, 0x44f7, 0x44f7, 
+    0x44f7, 0x44f7, 0x44f7, 0x44f7, 0x44f7, 0x44f7, 0x44f8, 0x44f8, 
+    0x44f8, 0x44f8, 0x44f8, 0x44f8, 0x44f8, 0x44f8, 0x44f8, 0x44f8, 
+    0x44f8, 0x44f8, 0x44f8, 0x44f8, 0x44f9, 0x44f9, 0x44f9, 0x44f9, 
+    0x44f9, 0x44f9, 0x44f9, 0x44f9, 0x44f9, 0x44f9, 0x44f9, 0x44f9, 
+    0x44f9, 0x44fa, 0x44fa, 0x44fa, 0x44fa, 0x44fa, 0x44fa, 0x44fa, 
+    0x44fa, 0x44fa, 0x44fa, 0x44fa, 0x44fa, 0x44fa, 0x44fb, 0x44fb, 
+    0x44fb, 0x44fb, 0x44fb, 0x44fb, 0x44fb, 0x44fb, 0x44fb, 0x44fb, 
+    0x44fb, 0x44fb, 0x44fb, 0x44fb, 0x44fc, 0x44fc, 0x44fc, 0x44fc, 
+    0x44fc, 0x44fc, 0x44fc, 0x44fc, 0x44fc, 0x44fc, 0x44fc, 0x44fc, 
+    0x44fc, 0x44fc, 0x44fd, 0x44fd, 0x44fd, 0x44fd, 0x44fd, 0x44fd, 
+    0x44fd, 0x44fd, 0x44fd, 0x44fd, 0x44fd, 0x44fd, 0x44fd, 0x44fd, 
+    0x44fe, 0x44fe, 0x44fe, 0x44fe, 0x44fe, 0x44fe, 0x44fe, 0x44fe, 
+    0x44fe, 0x44fe, 0x44fe, 0x44fe, 0x44fe, 0x44fe, 0x44ff, 0x44ff, 
+    0x44ff, 0x44ff, 0x44ff, 0x44ff, 0x44ff, 0x44ff, 0x44ff, 0x44ff, 
+    0x44ff, 0x44ff, 0x44ff, 0x44ff, 0x4500, 0x4500, 0x4500, 0x4500, 
+    0x4500, 0x4500, 0x4500, 0x4500, 0x4500, 0x4500, 0x4500, 0x4500, 
+    0x4500, 0x4500, 0x4501, 0x4501, 0x4501, 0x4501, 0x4501, 0x4501, 
+    0x4501, 0x4501, 0x4501, 0x4501, 0x4501, 0x4501, 0x4501, 0x4501, 
+    0x4501, 0x4502, 0x4502, 0x4502, 0x4502, 0x4502, 0x4502, 0x4502, 
+    0x4502, 0x4502, 0x4502, 0x4502, 0x4502, 0x4502, 0x4502, 0x4503, 
+    0x4503, 0x4503, 0x4503, 0x4503, 0x4503, 0x4503, 0x4503, 0x4503, 
+    0x4503, 0x4503, 0x4503, 0x4503, 0x4503, 0x4503, 0x4504, 0x4504, 
+    0x4504, 0x4504, 0x4504, 0x4504, 0x4504, 0x4504, 0x4504, 0x4504, 
+    0x4504, 0x4504, 0x4504, 0x4504, 0x4505, 0x4505, 0x4505, 0x4505, 
+    0x4505, 0x4505, 0x4505, 0x4505, 0x4505, 0x4505, 0x4505, 0x4505, 
+    0x4505, 0x4505, 0x4505, 0x4506, 0x4506, 0x4506, 0x4506, 0x4506, 
+    0x4506, 0x4506, 0x4506, 0x4506, 0x4506, 0x4506, 0x4506, 0x4506, 
+    0x4506, 0x4506, 0x4507, 0x4507, 0x4507, 0x4507, 0x4507, 0x4507, 
+    0x4507, 0x4507, 0x4507, 0x4507, 0x4507, 0x4507, 0x4507, 0x4507, 
+    0x4507, 0x4508, 0x4508, 0x4508, 0x4508, 0x4508, 0x4508, 0x4508, 
+    0x4508, 0x4508, 0x4508, 0x4508, 0x4508, 0x4508, 0x4508, 0x4508, 
+    0x4508, 0x4509, 0x4509, 0x4509, 0x4509, 0x4509, 0x4509, 0x4509, 
+    0x4509, 0x4509, 0x4509, 0x4509, 0x4509, 0x4509, 0x4509, 0x4509, 
+    0x450a, 0x450a, 0x450a, 0x450a, 0x450a, 0x450a, 0x450a, 0x450a, 
+    0x450a, 0x450a, 0x450a, 0x450a, 0x450a, 0x450a, 0x450a, 0x450a, 
+    0x450b, 0x450b, 0x450b, 0x450b, 0x450b, 0x450b, 0x450b, 0x450b, 
+    0x450b, 0x450b, 0x450b, 0x450b, 0x450b, 0x450b, 0x450b, 0x450c, 
+    0x450c, 0x450c, 0x450c, 0x450c, 0x450c, 0x450c, 0x450c, 0x450c, 
+    0x450c, 0x450c, 0x450c, 0x450c, 0x450c, 0x450c, 0x450c, 0x450d, 
+    0x450d, 0x450d, 0x450d, 0x450d, 0x450d, 0x450d, 0x450d, 0x450d, 
+    0x450d, 0x450d, 0x450d, 0x450d, 0x450d, 0x450d, 0x450d, 0x450e, 
+    0x450e, 0x450e, 0x450e, 0x450e, 0x450e, 0x450e, 0x450e, 0x450e, 
+    0x450e, 0x450e, 0x450e, 0x450e, 0x450e, 0x450e, 0x450e, 0x450f, 
+    0x450f, 0x450f, 0x450f, 0x450f, 0x450f, 0x450f, 0x450f, 0x450f, 
+    0x450f, 0x450f, 0x450f, 0x450f, 0x450f, 0x450f, 0x450f, 0x4510, 
+    0x4510, 0x4510, 0x4510, 0x4510, 0x4510, 0x4510, 0x4510, 0x4510, 
+    0x4510, 0x4510, 0x4510, 0x4510, 0x4510, 0x4510, 0x4510, 0x4510, 
+    0x4511, 0x4511, 0x4511, 0x4511, 0x4511, 0x4511, 0x4511, 0x4511, 
+    0x4511, 0x4511, 0x4511, 0x4511, 0x4511, 0x4511, 0x4511, 0x4511, 
+    0x4512, 0x4512, 0x4512, 0x4512, 0x4512, 0x4512, 0x4512, 0x4512, 
+    0x4512, 0x4512, 0x4512, 0x4512, 0x4512, 0x4512, 0x4512, 0x4512, 
+    0x4512, 0x4513, 0x4513, 0x4513, 0x4513, 0x4513, 0x4513, 0x4513, 
+    0x4513, 0x4513, 0x4513, 0x4513, 0x4513, 0x4513, 0x4513, 0x4513, 
+    0x4513, 0x4513, 0x4514, 0x4514, 0x4514, 0x4514, 0x4514, 0x4514, 
+    0x4514, 0x4514, 0x4514, 0x4514, 0x4514, 0x4514, 0x4514, 0x4514, 
+    0x4514, 0x4514, 0x4514, 0x4515, 0x4515, 0x4515, 0x4515, 0x4515, 
+    0x4515, 0x4515, 0x4515, 0x4515, 0x4515, 0x4515, 0x4515, 0x4515, 
+    0x4515, 0x4515, 0x4515, 0x4515, 0x4516, 0x4516, 0x4516, 0x4516, 
+    0x4516, 0x4516, 0x4516, 0x4516, 0x4516, 0x4516, 0x4516, 0x4516, 
+    0x4516, 0x4516, 0x4516, 0x4516, 0x4516, 0x4517, 0x4517, 0x4517, 
+    0x4517, 0x4517, 0x4517, 0x4517, 0x4517, 0x4517, 0x4517, 0x4517, 
+    0x4517, 0x4517, 0x4517, 0x4517, 0x4517, 0x4517, 0x4518, 0x4518, 
+    0x4518, 0x4518, 0x4518, 0x4518, 0x4518, 0x4518, 0x4518, 0x4518, 
+    0x4518, 0x4518, 0x4518, 0x4518, 0x4518, 0x4518, 0x4518, 0x4518, 
+    0x4519, 0x4519, 0x4519, 0x4519, 0x4519, 0x4519, 0x4519, 0x4519, 
+    0x4519, 0x451a, 0x451a, 0x451a, 0x451a, 0x451a, 0x451a, 0x451a, 
+    0x451a, 0x451a, 0x451b, 0x451b, 0x451b, 0x451b, 0x451b, 0x451b, 
+    0x451b, 0x451b, 0x451b, 0x451c, 0x451c, 0x451c, 0x451c, 0x451c, 
+    0x451c, 0x451c, 0x451c, 0x451c, 0x451d, 0x451d, 0x451d, 0x451d, 
+    0x451d, 0x451d, 0x451d, 0x451d, 0x451d, 0x451e, 0x451e, 0x451e, 
+    0x451e, 0x451e, 0x451e, 0x451e, 0x451e, 0x451e, 0x451f, 0x451f, 
+    0x451f, 0x451f, 0x451f, 0x451f, 0x451f, 0x451f, 0x451f, 0x451f, 
+    0x4520, 0x4520, 0x4520, 0x4520, 0x4520, 0x4520, 0x4520, 0x4520, 
+    0x4520, 0x4521, 0x4521, 0x4521, 0x4521, 0x4521, 0x4521, 0x4521, 
+    0x4521, 0x4521, 0x4522, 0x4522, 0x4522, 0x4522, 0x4522, 0x4522, 
+    0x4522, 0x4522, 0x4522, 0x4522, 0x4523, 0x4523, 0x4523, 0x4523, 
+    0x4523, 0x4523, 0x4523, 0x4523, 0x4523, 0x4523, 0x4524, 0x4524, 
+    0x4524, 0x4524, 0x4524, 0x4524, 0x4524, 0x4524, 0x4524, 0x4525, 
+    0x4525, 0x4525, 0x4525, 0x4525, 0x4525, 0x4525, 0x4525, 0x4525, 
+    0x4525, 0x4526, 0x4526, 0x4526, 0x4526, 0x4526, 0x4526, 0x4526, 
+    0x4526, 0x4526, 0x4526, 0x4527, 0x4527, 0x4527, 0x4527, 0x4527, 
+    0x4527, 0x4527, 0x4527, 0x4527, 0x4527, 0x4528, 0x4528, 0x4528, 
+    0x4528, 0x4528, 0x4528, 0x4528, 0x4528, 0x4528, 0x4528, 0x4529, 
+    0x4529, 0x4529, 0x4529, 0x4529, 0x4529, 0x4529, 0x4529, 0x4529, 
+    0x4529, 0x452a, 0x452a, 0x452a, 0x452a, 0x452a, 0x452a, 0x452a, 
+    0x452a, 0x452a, 0x452a, 0x452b, 0x452b, 0x452b, 0x452b, 0x452b, 
+    0x452b, 0x452b, 0x452b, 0x452b, 0x452b, 0x452b, 0x452c, 0x452c, 
+    0x452c, 0x452c, 0x452c, 0x452c, 0x452c, 0x452c, 0x452c, 0x452c, 
+    0x452d, 0x452d, 0x452d, 0x452d, 0x452d, 0x452d, 0x452d, 0x452d, 
+    0x452d, 0x452d, 0x452d, 0x452e, 0x452e, 0x452e, 0x452e, 0x452e, 
+    0x452e, 0x452e, 0x452e, 0x452e, 0x452e, 0x452f, 0x452f, 0x452f, 
+    0x452f, 0x452f, 0x452f, 0x452f, 0x452f, 0x452f, 0x452f, 0x452f, 
+    0x4530, 0x4530, 0x4530, 0x4530, 0x4530, 0x4530, 0x4530, 0x4530, 
+    0x4530, 0x4530, 0x4530, 0x4531, 0x4531, 0x4531, 0x4531, 0x4531, 
+    0x4531, 0x4531, 0x4531, 0x4531, 0x4531, 0x4532, 0x4532, 0x4532, 
+    0x4532, 0x4532, 0x4532, 0x4532, 0x4532, 0x4532, 0x4532, 0x4532, 
+    0x4533, 0x4533, 0x4533, 0x4533, 0x4533, 0x4533, 0x4533, 0x4533, 
+    0x4533, 0x4533, 0x4533, 0x4534, 0x4534, 0x4534, 0x4534, 0x4534, 
+    0x4534, 0x4534, 0x4534, 0x4534, 0x4534, 0x4534, 0x4534, 0x4535, 
+    0x4535, 0x4535, 0x4535, 0x4535, 0x4535, 0x4535, 0x4535, 0x4535, 
+    0x4535, 0x4535, 0x4536, 0x4536, 0x4536, 0x4536, 0x4536, 0x4536, 
+    0x4536, 0x4536, 0x4536, 0x4536, 0x4536, 0x4537, 0x4537, 0x4537, 
+    0x4537, 0x4537, 0x4537, 0x4537, 0x4537, 0x4537, 0x4537, 0x4537, 
+    0x4537, 0x4538, 0x4538, 0x4538, 0x4538, 0x4538, 0x4538, 0x4538, 
+    0x4538, 0x4538, 0x4538, 0x4538, 0x4539, 0x4539, 0x4539, 0x4539, 
+    0x4539, 0x4539, 0x4539, 0x4539, 0x4539, 0x4539, 0x4539, 0x4539, 
+    0x453a, 0x453a, 0x453a, 0x453a, 0x453a, 0x453a, 0x453a, 0x453a, 
+    0x453a, 0x453a, 0x453a, 0x453b, 0x453b, 0x453b, 0x453b, 0x453b, 
+    0x453b, 0x453b, 0x453b, 0x453b, 0x453b, 0x453b, 0x453b, 0x453c, 
+    0x453c, 0x453c, 0x453c, 0x453c, 0x453c, 0x453c, 0x453c, 0x453c, 
+    0x453c, 0x453c, 0x453c, 0x453d, 0x453d, 0x453d, 0x453d, 0x453d, 
+    0x453d, 0x453d, 0x453d, 0x453d, 0x453d, 0x453d, 0x453d, 0x453e, 
+    0x453e, 0x453e, 0x453e, 0x453e, 0x453e, 0x453e, 0x453e, 0x453e, 
+    0x453e, 0x453e, 0x453e, 0x453f, 0x453f, 0x453f, 0x453f, 0x453f, 
+    0x453f, 0x453f, 0x453f, 0x453f, 0x453f, 0x453f, 0x453f, 0x453f, 
+    0x4540, 0x4540, 0x4540, 0x4540, 0x4540, 0x4540, 0x4540, 0x4540, 
+    0x4540, 0x4540, 0x4540, 0x4540, 0x4541, 0x4541, 0x4541, 0x4541, 
+    0x4541, 0x4541, 0x4541, 0x4541, 0x4541, 0x4541, 0x4541, 0x4541, 
+    0x4541, 0x4542, 0x4542, 0x4542, 0x4542, 0x4542, 0x4542, 0x4542, 
+    0x4542, 0x4542, 0x4542, 0x4542, 0x4542, 0x4543, 0x4543, 0x4543, 
+    0x4543, 0x4543, 0x4543, 0x4543, 0x4543, 0x4543, 0x4543, 0x4543, 
+    0x4543, 0x4543, 0x4544, 0x4544, 0x4544, 0x4544, 0x4544, 0x4544, 
+    0x4544, 0x4544, 0x4544, 0x4544, 0x4544, 0x4544, 0x4544, 0x4545, 
+    0x4545, 0x4545, 0x4545, 0x4545, 0x4545, 0x4545, 0x4545, 0x4545, 
+    0x4545, 0x4545, 0x4545, 0x4546, 0x4546, 0x4546, 0x4546, 0x4546, 
+    0x4546, 0x4546, 0x4546, 0x4546, 0x4546, 0x4546, 0x4546, 0x4546, 
+    0x4547, 0x4547, 0x4547, 0x4547, 0x4547, 0x4547, 0x4547, 0x4547, 
+    0x4547, 0x4547, 0x4547, 0x4547, 0x4547, 0x4547, 0x4548, 0x4548, 
+    0x4548, 0x4548, 0x4548, 0x4548, 0x4548, 0x4548, 0x4548, 0x4548, 
+    0x4548, 0x4548, 0x4548, 0x4549, 0x4549, 0x4549, 0x4549, 0x4549, 
+    0x4549, 0x4549, 0x4549, 0x4549, 0x4549, 0x4549, 0x4549, 0x4549, 
+    0x454a, 0x454a, 0x454a, 0x454a, 0x454a, 0x454a, 0x454a, 0x454a, 
+    0x454a, 0x454a, 0x454a, 0x454a, 0x454a, 0x454a, 0x454b, 0x454b, 
+    0x454b, 0x454b, 0x454b, 0x454b, 0x454b, 0x454b, 0x454b, 0x454b, 
+    0x454b, 0x454b, 0x454b, 0x454c, 0x454c, 0x454c, 0x454c, 0x454c, 
+    0x454c, 0x454c, 0x454c, 0x454c, 0x454c, 0x454c, 0x454c, 0x454c, 
+    0x454c, 0x454d, 0x454d, 0x454d, 0x454d, 0x454d, 0x454d, 0x454d, 
+    0x454d, 0x454d, 0x454d, 0x454d, 0x454d, 0x454d, 0x454d, 0x454e, 
+    0x454e, 0x454e, 0x454e, 0x454e, 0x454e, 0x454e, 0x454e, 0x454e, 
+    0x454e, 0x454e, 0x454e, 0x454e, 0x454e, 0x454f, 0x454f, 0x454f, 
+    0x454f, 0x454f, 0x454f, 0x454f, 0x454f, 0x454f, 0x454f, 0x454f, 
+    0x454f, 0x454f, 0x454f, 0x4550, 0x4550, 0x4550, 0x4550, 0x4550, 
+    0x4550, 0x4550, 0x4550, 0x4550, 0x4550, 0x4550, 0x4550, 0x4550, 
+    0x4550, 0x4551, 0x4551, 0x4551, 0x4551, 0x4551, 0x4551, 0x4551, 
+    0x4551, 0x4551, 0x4551, 0x4551, 0x4551, 0x4551, 0x4551, 0x4552, 
+    0x4552, 0x4552, 0x4552, 0x4552, 0x4552, 0x4552, 0x4552, 0x4552, 
+    0x4552, 0x4552, 0x4552, 0x4552, 0x4552, 0x4552, 0x4553, 0x4553, 
+    0x4553, 0x4553, 0x4553, 0x4553, 0x4553, 0x4553, 0x4553, 0x4553, 
+    0x4553, 0x4553, 0x4553, 0x4553, 0x4554, 0x4554, 0x4554, 0x4554, 
+    0x4554, 0x4554, 0x4554, 0x4554, 0x4554, 0x4554, 0x4554, 0x4554, 
+    0x4554, 0x4554, 0x4554, 0x4555, 0x4555, 0x4555, 0x4555, 0x4555, 
+    0x4555, 0x4555, 0x4555, 0x4555, 0x4555, 0x4555, 0x4555, 0x4555, 
+    0x4555, 0x4555, 0x4556, 0x4556, 0x4556, 0x4556, 0x4556, 0x4556, 
+    0x4556, 0x4556, 0x4556, 0x4556, 0x4556, 0x4556, 0x4556, 0x4556, 
+    0x4557, 0x4557, 0x4557, 0x4557, 0x4557, 0x4557, 0x4557, 0x4557, 
+    0x4557, 0x4557, 0x4557, 0x4557, 0x4557, 0x4557, 0x4557, 0x4557, 
+    0x4558, 0x4558, 0x4558, 0x4558, 0x4558, 0x4558, 0x4558, 0x4558, 
+    0x4558, 0x4558, 0x4558, 0x4558, 0x4558, 0x4558, 0x4558, 0x4559, 
+    0x4559, 0x4559, 0x4559, 0x4559, 0x4559, 0x4559, 0x4559, 0x4559, 
+    0x4559, 0x4559, 0x4559, 0x4559, 0x4559, 0x4559, 0x455a, 0x455a, 
+    0x455a, 0x455a, 0x455a, 0x455a, 0x455a, 0x455a, 0x455a, 0x455a, 
+    0x455a, 0x455a, 0x455a, 0x455a, 0x455a, 0x455b, 0x455b, 0x455b, 
+    0x455b, 0x455b, 0x455b, 0x455b, 0x455b, 0x455b, 0x455b, 0x455b, 
+    0x455b, 0x455b, 0x455b, 0x455b, 0x455b, 0x455c, 0x455c, 0x455c, 
+    0x455c, 0x455c, 0x455c, 0x455c, 0x455c, 0x455c, 0x455c, 0x455c, 
+    0x455c, 0x455c, 0x455c, 0x455c, 0x455c, 0x455d, 0x455d, 0x455d, 
+    0x455d, 0x455d, 0x455d, 0x455d, 0x455d, 0x455d, 0x455d, 0x455d, 
+    0x455d, 0x455d, 0x455d, 0x455d, 0x455d, 0x455e, 0x455e, 0x455e, 
+    0x455e, 0x455e, 0x455e, 0x455e, 0x455e, 0x455e, 0x455e, 0x455e, 
+    0x455e, 0x455e, 0x455e, 0x455e, 0x455e, 0x455f, 0x455f, 0x455f, 
+    0x455f, 0x455f, 0x455f, 0x455f, 0x455f, 0x455f, 0x455f, 0x455f, 
+    0x455f, 0x455f, 0x455f, 0x455f, 0x455f, 0x4560, 0x4560, 0x4560, 
+    0x4560, 0x4560, 0x4560, 0x4560, 0x4560, 0x4560, 0x4560, 0x4560, 
+    0x4560, 0x4560, 0x4560, 0x4560, 0x4560, 0x4561, 0x4561, 0x4561, 
+    0x4561, 0x4561, 0x4561, 0x4561, 0x4561, 0x4561, 0x4561, 0x4561, 
+    0x4561, 0x4561, 0x4561, 0x4561, 0x4561, 0x4562, 0x4562, 0x4562, 
+    0x4562, 0x4562, 0x4562, 0x4562, 0x4562, 0x4562, 0x4562, 0x4562, 
+    0x4562, 0x4562, 0x4562, 0x4562, 0x4562, 0x4562, 0x4563, 0x4563, 
+    0x4563, 0x4563, 0x4563, 0x4563, 0x4563, 0x4563, 0x4563, 0x4563, 
+    0x4563, 0x4563, 0x4563, 0x4563, 0x4563, 0x4563, 0x4563, 0x4564, 
+    0x4564, 0x4564, 0x4564, 0x4564, 0x4564, 0x4564, 0x4564, 0x4564, 
+    0x4564, 0x4564, 0x4564, 0x4564, 0x4564, 0x4564, 0x4564, 0x4565, 
+    0x4565, 0x4565, 0x4565, 0x4565, 0x4565, 0x4565, 0x4565, 0x4565, 
+    0x4565, 0x4565, 0x4565, 0x4565, 0x4565, 0x4565, 0x4565, 0x4565, 
+    0x4566, 0x4566, 0x4566, 0x4566, 0x4566, 0x4566, 0x4566, 0x4566, 
+    0x4566, 0x4566, 0x4566, 0x4566, 0x4566, 0x4566, 0x4566, 0x4566, 
+    0x4566, 0x4566, 0x4567, 0x4567, 0x4567, 0x4567, 0x4567, 0x4567, 
+    0x4567, 0x4567, 0x4567, 0x4567, 0x4567, 0x4567, 0x4567, 0x4567, 
+    0x4567, 0x4567, 0x4567, 0x4568, 0x4568, 0x4568, 0x4568, 0x4568, 
+    0x4568, 0x4568, 0x4568, 0x4568, 0x4568, 0x4568, 0x4568, 0x4568, 
+    0x4568, 0x4568, 0x4568, 0x4568, 0x4569, 0x4569, 0x4569, 0x4569, 
+    0x4569, 0x4569, 0x4569, 0x4569, 0x4569, 0x4569, 0x4569, 0x4569, 
+    0x4569, 0x4569, 0x4569, 0x456a, 0x456a, 0x456a, 0x456a, 0x456a, 
+    0x456a, 0x456a, 0x456a, 0x456a, 0x456b, 0x456b, 0x456b, 0x456b, 
+    0x456b, 0x456b, 0x456b, 0x456b, 0x456b, 0x456c, 0x456c, 0x456c, 
+    0x456c, 0x456c, 0x456c, 0x456c, 0x456c, 0x456c, 0x456d, 0x456d, 
+    0x456d, 0x456d, 0x456d, 0x456d, 0x456d, 0x456d, 0x456d, 0x456e, 
+    0x456e, 0x456e, 0x456e, 0x456e, 0x456e, 0x456e, 0x456e, 0x456e, 
+    0x456f, 0x456f, 0x456f, 0x456f, 0x456f, 0x456f, 0x456f, 0x456f, 
+    0x456f, 0x4570, 0x4570, 0x4570, 0x4570, 0x4570, 0x4570, 0x4570, 
+    0x4570, 0x4570, 0x4570, 0x4571, 0x4571, 0x4571, 0x4571, 0x4571, 
+    0x4571, 0x4571, 0x4571, 0x4571, 0x4572, 0x4572, 0x4572, 0x4572, 
+    0x4572, 0x4572, 0x4572, 0x4572, 0x4572, 0x4572, 0x4573, 0x4573, 
+    0x4573, 0x4573, 0x4573, 0x4573, 0x4573, 0x4573, 0x4573, 0x4574, 
+    0x4574, 0x4574, 0x4574, 0x4574, 0x4574, 0x4574, 0x4574, 0x4574, 
+    0x4574, 0x4575, 0x4575, 0x4575, 0x4575, 0x4575, 0x4575, 0x4575, 
+    0x4575, 0x4575, 0x4575, 0x4576, 0x4576, 0x4576, 0x4576, 0x4576, 
+    0x4576, 0x4576, 0x4576, 0x4576, 0x4577, 0x4577, 0x4577, 0x4577, 
+    0x4577, 0x4577, 0x4577, 0x4577, 0x4577, 0x4577, 0x4578, 0x4578, 
+    0x4578, 0x4578, 0x4578, 0x4578, 0x4578, 0x4578, 0x4578, 0x4578, 
+    0x4579, 0x4579, 0x4579, 0x4579, 0x4579, 0x4579, 0x4579, 0x4579, 
+    0x4579, 0x4579, 0x457a, 0x457a, 0x457a, 0x457a, 0x457a, 0x457a, 
+    0x457a, 0x457a, 0x457a, 0x457a, 0x457a, 0x457b, 0x457b, 0x457b, 
+    0x457b, 0x457b, 0x457b, 0x457b, 0x457b, 0x457b, 0x457b, 0x457c, 
+    0x457c, 0x457c, 0x457c, 0x457c, 0x457c, 0x457c, 0x457c, 0x457c, 
+    0x457c, 0x457d, 0x457d, 0x457d, 0x457d, 0x457d, 0x457d, 0x457d, 
+    0x457d, 0x457d, 0x457d, 0x457d, 0x457e, 0x457e, 0x457e, 0x457e, 
+    0x457e, 0x457e, 0x457e, 0x457e, 0x457e, 0x457e, 0x457f, 0x457f, 
+    0x457f, 0x457f, 0x457f, 0x457f, 0x457f, 0x457f, 0x457f, 0x457f, 
+    0x457f, 0x4580, 0x4580, 0x4580, 0x4580, 0x4580, 0x4580, 0x4580, 
+    0x4580, 0x4580, 0x4580, 0x4580, 0x4581, 0x4581, 0x4581, 0x4581, 
+    0x4581, 0x4581, 0x4581, 0x4581, 0x4581, 0x4581, 0x4582, 0x4582, 
+    0x4582, 0x4582, 0x4582, 0x4582, 0x4582, 0x4582, 0x4582, 0x4582, 
+    0x4582, 0x4583, 0x4583, 0x4583, 0x4583, 0x4583, 0x4583, 0x4583, 
+    0x4583, 0x4583, 0x4583, 0x4583, 0x4584, 0x4584, 0x4584, 0x4584, 
+    0x4584, 0x4584, 0x4584, 0x4584, 0x4584, 0x4584, 0x4584, 0x4585, 
+    0x4585, 0x4585, 0x4585, 0x4585, 0x4585, 0x4585, 0x4585, 0x4585, 
+    0x4585, 0x4585, 0x4586, 0x4586, 0x4586, 0x4586, 0x4586, 0x4586, 
+    0x4586, 0x4586, 0x4586, 0x4586, 0x4586, 0x4586, 0x4587, 0x4587, 
+    0x4587, 0x4587, 0x4587, 0x4587, 0x4587, 0x4587, 0x4587, 0x4587, 
+    0x4587, 0x4588, 0x4588, 0x4588, 0x4588, 0x4588, 0x4588, 0x4588, 
+    0x4588, 0x4588, 0x4588, 0x4588, 0x4588, 0x4589, 0x4589, 0x4589, 
+    0x4589, 0x4589, 0x4589, 0x4589, 0x4589, 0x4589, 0x4589, 0x4589, 
+    0x458a, 0x458a, 0x458a, 0x458a, 0x458a, 0x458a, 0x458a, 0x458a, 
+    0x458a, 0x458a, 0x458a, 0x458a, 0x458b, 0x458b, 0x458b, 0x458b, 
+    0x458b, 0x458b, 0x458b, 0x458b, 0x458b, 0x458b, 0x458b, 0x458b, 
+    0x458c, 0x458c, 0x458c, 0x458c, 0x458c, 0x458c, 0x458c, 0x458c, 
+    0x458c, 0x458c, 0x458c, 0x458d, 0x458d, 0x458d, 0x458d, 0x458d, 
+    0x458d, 0x458d, 0x458d, 0x458d, 0x458d, 0x458d, 0x458d, 0x458e, 
+    0x458e, 0x458e, 0x458e, 0x458e, 0x458e, 0x458e, 0x458e, 0x458e, 
+    0x458e, 0x458e, 0x458e, 0x458f, 0x458f, 0x458f, 0x458f, 0x458f, 
+    0x458f, 0x458f, 0x458f, 0x458f, 0x458f, 0x458f, 0x458f, 0x458f, 
+    0x4590, 0x4590, 0x4590, 0x4590, 0x4590, 0x4590, 0x4590, 0x4590, 
+    0x4590, 0x4590, 0x4590, 0x4590, 0x4591, 0x4591, 0x4591, 0x4591, 
+    0x4591, 0x4591, 0x4591, 0x4591, 0x4591, 0x4591, 0x4591, 0x4591, 
+    0x4592, 0x4592, 0x4592, 0x4592, 0x4592, 0x4592, 0x4592, 0x4592, 
+    0x4592, 0x4592, 0x4592, 0x4592, 0x4592, 0x4593, 0x4593, 0x4593, 
+    0x4593, 0x4593, 0x4593, 0x4593, 0x4593, 0x4593, 0x4593, 0x4593, 
+    0x4593, 0x4594, 0x4594, 0x4594, 0x4594, 0x4594, 0x4594, 0x4594, 
+    0x4594, 0x4594, 0x4594, 0x4594, 0x4594, 0x4594, 0x4595, 0x4595, 
+    0x4595, 0x4595, 0x4595, 0x4595, 0x4595, 0x4595, 0x4595, 0x4595, 
+    0x4595, 0x4595, 0x4595, 0x4596, 0x4596, 0x4596, 0x4596, 0x4596, 
+    0x4596, 0x4596, 0x4596, 0x4596, 0x4596, 0x4596, 0x4596, 0x4596, 
+    0x4597, 0x4597, 0x4597, 0x4597, 0x4597, 0x4597, 0x4597, 0x4597, 
+    0x4597, 0x4597, 0x4597, 0x4597, 0x4597, 0x4598, 0x4598, 0x4598, 
+    0x4598, 0x4598, 0x4598, 0x4598, 0x4598, 0x4598, 0x4598, 0x4598, 
+    0x4598, 0x4598, 0x4599, 0x4599, 0x4599, 0x4599, 0x4599, 0x4599, 
+    0x4599, 0x4599, 0x4599, 0x4599, 0x4599, 0x4599, 0x4599, 0x459a, 
+    0x459a, 0x459a, 0x459a, 0x459a, 0x459a, 0x459a, 0x459a, 0x459a, 
+    0x459a, 0x459a, 0x459a, 0x459a, 0x459a, 0x459b, 0x459b, 0x459b, 
+    0x459b, 0x459b, 0x459b, 0x459b, 0x459b, 0x459b, 0x459b, 0x459b, 
+    0x459b, 0x459b, 0x459c, 0x459c, 0x459c, 0x459c, 0x459c, 0x459c, 
+    0x459c, 0x459c, 0x459c, 0x459c, 0x459c, 0x459c, 0x459c, 0x459c, 
+    0x459d, 0x459d, 0x459d, 0x459d, 0x459d, 0x459d, 0x459d, 0x459d, 
+    0x459d, 0x459d, 0x459d, 0x459d, 0x459d, 0x459d, 0x459e, 0x459e, 
+    0x459e, 0x459e, 0x459e, 0x459e, 0x459e, 0x459e, 0x459e, 0x459e, 
+    0x459e, 0x459e, 0x459e, 0x459f, 0x459f, 0x459f, 0x459f, 0x459f, 
+    0x459f, 0x459f, 0x459f, 0x459f, 0x459f, 0x459f, 0x459f, 0x459f, 
+    0x459f, 0x45a0, 0x45a0, 0x45a0, 0x45a0, 0x45a0, 0x45a0, 0x45a0, 
+    0x45a0, 0x45a0, 0x45a0, 0x45a0, 0x45a0, 0x45a0, 0x45a0, 0x45a1, 
+    0x45a1, 0x45a1, 0x45a1, 0x45a1, 0x45a1, 0x45a1, 0x45a1, 0x45a1, 
+    0x45a1, 0x45a1, 0x45a1, 0x45a1, 0x45a1, 0x45a1, 0x45a2, 0x45a2, 
+    0x45a2, 0x45a2, 0x45a2, 0x45a2, 0x45a2, 0x45a2, 0x45a2, 0x45a2, 
+    0x45a2, 0x45a2, 0x45a2, 0x45a2, 0x45a3, 0x45a3, 0x45a3, 0x45a3, 
+    0x45a3, 0x45a3, 0x45a3, 0x45a3, 0x45a3, 0x45a3, 0x45a3, 0x45a3, 
+    0x45a3, 0x45a3, 0x45a3, 0x45a4, 0x45a4, 0x45a4, 0x45a4, 0x45a4, 
+    0x45a4, 0x45a4, 0x45a4, 0x45a4, 0x45a4, 0x45a4, 0x45a4, 0x45a4, 
+    0x45a4, 0x45a5, 0x45a5, 0x45a5, 0x45a5, 0x45a5, 0x45a5, 0x45a5, 
+    0x45a5, 0x45a5, 0x45a5, 0x45a5, 0x45a5, 0x45a5, 0x45a5, 0x45a5, 
+    0x45a6, 0x45a6, 0x45a6, 0x45a6, 0x45a6, 0x45a6, 0x45a6, 0x45a6, 
+    0x45a6, 0x45a6, 0x45a6, 0x45a6, 0x45a6, 0x45a6, 0x45a6, 0x45a7, 
+    0x45a7, 0x45a7, 0x45a7, 0x45a7, 0x45a7, 0x45a7, 0x45a7, 0x45a7, 
+    0x45a7, 0x45a7, 0x45a7, 0x45a7, 0x45a7, 0x45a7, 0x45a8, 0x45a8, 
+    0x45a8, 0x45a8, 0x45a8, 0x45a8, 0x45a8, 0x45a8, 0x45a8, 0x45a8, 
+    0x45a8, 0x45a8, 0x45a8, 0x45a8, 0x45a8, 0x45a9, 0x45a9, 0x45a9, 
+    0x45a9, 0x45a9, 0x45a9, 0x45a9, 0x45a9, 0x45a9, 0x45a9, 0x45a9, 
+    0x45a9, 0x45a9, 0x45a9, 0x45a9, 0x45aa, 0x45aa, 0x45aa, 0x45aa, 
+    0x45aa, 0x45aa, 0x45aa, 0x45aa, 0x45aa, 0x45aa, 0x45aa, 0x45aa, 
+    0x45aa, 0x45aa, 0x45aa, 0x45ab, 0x45ab, 0x45ab, 0x45ab, 0x45ab, 
+    0x45ab, 0x45ab, 0x45ab, 0x45ab, 0x45ab, 0x45ab, 0x45ab, 0x45ab, 
+    0x45ab, 0x45ab, 0x45ab, 0x45ac, 0x45ac, 0x45ac, 0x45ac, 0x45ac, 
+    0x45ac, 0x45ac, 0x45ac, 0x45ac, 0x45ac, 0x45ac, 0x45ac, 0x45ac, 
+    0x45ac, 0x45ac, 0x45ad, 0x45ad, 0x45ad, 0x45ad, 0x45ad, 0x45ad, 
+    0x45ad, 0x45ad, 0x45ad, 0x45ad, 0x45ad, 0x45ad, 0x45ad, 0x45ad, 
+    0x45ad, 0x45ad, 0x45ae, 0x45ae, 0x45ae, 0x45ae, 0x45ae, 0x45ae, 
+    0x45ae, 0x45ae, 0x45ae, 0x45ae, 0x45ae, 0x45ae, 0x45ae, 0x45ae, 
+    0x45ae, 0x45ae, 0x45af, 0x45af, 0x45af, 0x45af, 0x45af, 0x45af, 
+    0x45af, 0x45af, 0x45af, 0x45af, 0x45af, 0x45af, 0x45af, 0x45af, 
+    0x45af, 0x45af, 0x45b0, 0x45b0, 0x45b0, 0x45b0, 0x45b0, 0x45b0, 
+    0x45b0, 0x45b0, 0x45b0, 0x45b0, 0x45b0, 0x45b0, 0x45b0, 0x45b0, 
+    0x45b0, 0x45b0, 0x45b1, 0x45b1, 0x45b1, 0x45b1, 0x45b1, 0x45b1, 
+    0x45b1, 0x45b1, 0x45b1, 0x45b1, 0x45b1, 0x45b1, 0x45b1, 0x45b1, 
+    0x45b1, 0x45b1, 0x45b1, 0x45b2, 0x45b2, 0x45b2, 0x45b2, 0x45b2, 
+    0x45b2, 0x45b2, 0x45b2, 0x45b2, 0x45b2, 0x45b2, 0x45b2, 0x45b2, 
+    0x45b2, 0x45b2, 0x45b2, 0x45b3, 0x45b3, 0x45b3, 0x45b3, 0x45b3, 
+    0x45b3, 0x45b3, 0x45b3, 0x45b3, 0x45b3, 0x45b3, 0x45b3, 0x45b3, 
+    0x45b3, 0x45b3, 0x45b3, 0x45b3, 0x45b4, 0x45b4, 0x45b4, 0x45b4, 
+    0x45b4, 0x45b4, 0x45b4, 0x45b4, 0x45b4, 0x45b4, 0x45b4, 0x45b4, 
+    0x45b4, 0x45b4, 0x45b4, 0x45b4, 0x45b5, 0x45b5, 0x45b5, 0x45b5, 
+    0x45b5, 0x45b5, 0x45b5, 0x45b5, 0x45b5, 0x45b5, 0x45b5, 0x45b5, 
+    0x45b5, 0x45b5, 0x45b5, 0x45b5, 0x45b5, 0x45b6, 0x45b6, 0x45b6, 
+    0x45b6, 0x45b6, 0x45b6, 0x45b6, 0x45b6, 0x45b6, 0x45b6, 0x45b6, 
+    0x45b6, 0x45b6, 0x45b6, 0x45b6, 0x45b6, 0x45b6, 0x45b7, 0x45b7, 
+    0x45b7, 0x45b7, 0x45b7, 0x45b7, 0x45b7, 0x45b7, 0x45b7, 0x45b7, 
+    0x45b7, 0x45b7, 0x45b7, 0x45b7, 0x45b7, 0x45b7, 0x45b7, 0x45b8, 
+    0x45b8, 0x45b8, 0x45b8, 0x45b8, 0x45b8, 0x45b8, 0x45b8, 0x45b8, 
+    0x45b8, 0x45b8, 0x45b8, 0x45b8, 0x45b8, 0x45b8, 0x45b8, 0x45b8, 
+    0x45b8, 0x45b9, 0x45b9, 0x45b9, 0x45b9, 0x45b9, 0x45b9, 0x45b9, 
+    0x45b9, 0x45b9, 0x45b9, 0x45b9, 0x45b9, 0x45b9, 0x45b9, 0x45b9, 
+    0x45b9, 0x45b9, 0x45ba, 0x45ba, 0x45ba, 0x45ba, 0x45ba, 0x45ba, 
+    0x45ba, 0x45ba, 0x45ba, 0x45ba, 0x45ba, 0x45ba, 0x45bb, 0x45bb, 
+    0x45bb, 0x45bb, 0x45bb, 0x45bb, 0x45bb, 0x45bb, 0x45bb, 0x45bc, 
+    0x45bc, 0x45bc, 0x45bc, 0x45bc, 0x45bc, 0x45bc, 0x45bc, 0x45bc, 
+    0x45bd, 0x45bd, 0x45bd, 0x45bd, 0x45bd, 0x45bd, 0x45bd, 0x45bd, 
+    0x45bd, 0x45be, 0x45be, 0x45be, 0x45be, 0x45be, 0x45be, 0x45be, 
+    0x45be, 0x45be, 0x45bf, 0x45bf, 0x45bf, 0x45bf, 0x45bf, 0x45bf, 
+    0x45bf, 0x45bf, 0x45bf, 0x45c0, 0x45c0, 0x45c0, 0x45c0, 0x45c0, 
+    0x45c0, 0x45c0, 0x45c0, 0x45c0, 0x45c0, 0x45c1, 0x45c1, 0x45c1, 
+    0x45c1, 0x45c1, 0x45c1, 0x45c1, 0x45c1, 0x45c1, 0x45c2, 0x45c2, 
+    0x45c2, 0x45c2, 0x45c2, 0x45c2, 0x45c2, 0x45c2, 0x45c2, 0x45c3, 
+    0x45c3, 0x45c3, 0x45c3, 0x45c3, 0x45c3, 0x45c3, 0x45c3, 0x45c3, 
+    0x45c3, 0x45c4, 0x45c4, 0x45c4, 0x45c4, 0x45c4, 0x45c4, 0x45c4, 
+    0x45c4, 0x45c4, 0x45c4, 0x45c5, 0x45c5, 0x45c5, 0x45c5, 0x45c5, 
+    0x45c5, 0x45c5, 0x45c5, 0x45c5, 0x45c6, 0x45c6, 0x45c6, 0x45c6, 
+    0x45c6, 0x45c6, 0x45c6, 0x45c6, 0x45c6, 0x45c6, 0x45c7, 0x45c7, 
+    0x45c7, 0x45c7, 0x45c7, 0x45c7, 0x45c7, 0x45c7, 0x45c7, 0x45c7, 
+    0x45c8, 0x45c8, 0x45c8, 0x45c8, 0x45c8, 0x45c8, 0x45c8, 0x45c8, 
+    0x45c8, 0x45c8, 0x45c9, 0x45c9, 0x45c9, 0x45c9, 0x45c9, 0x45c9, 
+    0x45c9, 0x45c9, 0x45c9, 0x45c9, 0x45ca, 0x45ca, 0x45ca, 0x45ca, 
+    0x45ca, 0x45ca, 0x45ca, 0x45ca, 0x45ca, 0x45ca, 0x45cb, 0x45cb, 
+    0x45cb, 0x45cb, 0x45cb, 0x45cb, 0x45cb, 0x45cb, 0x45cb, 0x45cb, 
+    0x45cc, 0x45cc, 0x45cc, 0x45cc, 0x45cc, 0x45cc, 0x45cc, 0x45cc, 
+    0x45cc, 0x45cc, 0x45cd, 0x45cd, 0x45cd, 0x45cd, 0x45cd, 0x45cd, 
+    0x45cd, 0x45cd, 0x45cd, 0x45cd, 0x45cd, 0x45ce, 0x45ce, 0x45ce, 
+    0x45ce, 0x45ce, 0x45ce, 0x45ce, 0x45ce, 0x45ce, 0x45ce, 0x45cf, 
+    0x45cf, 0x45cf, 0x45cf, 0x45cf, 0x45cf, 0x45cf, 0x45cf, 0x45cf, 
+    0x45cf, 0x45cf, 0x45d0, 0x45d0, 0x45d0, 0x45d0, 0x45d0, 0x45d0, 
+    0x45d0, 0x45d0, 0x45d0, 0x45d0, 0x45d1, 0x45d1, 0x45d1, 0x45d1, 
+    0x45d1, 0x45d1, 0x45d1, 0x45d1, 0x45d1, 0x45d1, 0x45d1, 0x45d2, 
+    0x45d2, 0x45d2, 0x45d2, 0x45d2, 0x45d2, 0x45d2, 0x45d2, 0x45d2, 
+    0x45d2, 0x45d2, 0x45d3, 0x45d3, 0x45d3, 0x45d3, 0x45d3, 0x45d3, 
+    0x45d3, 0x45d3, 0x45d3, 0x45d3, 0x45d3, 0x45d4, 0x45d4, 0x45d4, 
+    0x45d4, 0x45d4, 0x45d4, 0x45d4, 0x45d4, 0x45d4, 0x45d4, 0x45d4, 
+    0x45d5, 0x45d5, 0x45d5, 0x45d5, 0x45d5, 0x45d5, 0x45d5, 0x45d5, 
+    0x45d5, 0x45d5, 0x45d5, 0x45d6, 0x45d6, 0x45d6, 0x45d6, 0x45d6, 
+    0x45d6, 0x45d6, 0x45d6, 0x45d6, 0x45d6, 0x45d6, 0x45d7, 0x45d7, 
+    0x45d7, 0x45d7, 0x45d7, 0x45d7, 0x45d7, 0x45d7, 0x45d7, 0x45d7, 
+    0x45d7, 0x45d7, 0x45d8, 0x45d8, 0x45d8, 0x45d8, 0x45d8, 0x45d8, 
+    0x45d8, 0x45d8, 0x45d8, 0x45d8, 0x45d8, 0x45d9, 0x45d9, 0x45d9, 
+    0x45d9, 0x45d9, 0x45d9, 0x45d9, 0x45d9, 0x45d9, 0x45d9, 0x45d9, 
+    0x45da, 0x45da, 0x45da, 0x45da, 0x45da, 0x45da, 0x45da, 0x45da, 
+    0x45da, 0x45da, 0x45da, 0x45da, 0x45db, 0x45db, 0x45db, 0x45db, 
+    0x45db, 0x45db, 0x45db, 0x45db, 0x45db, 0x45db, 0x45db, 0x45db, 
+    0x45dc, 0x45dc, 0x45dc, 0x45dc, 0x45dc, 0x45dc, 0x45dc, 0x45dc, 
+    0x45dc, 0x45dc, 0x45dc, 0x45dc, 0x45dd, 0x45dd, 0x45dd, 0x45dd, 
+    0x45dd, 0x45dd, 0x45dd, 0x45dd, 0x45dd, 0x45dd, 0x45dd, 0x45dd, 
+    0x45de, 0x45de, 0x45de, 0x45de, 0x45de, 0x45de, 0x45de, 0x45de, 
+    0x45de, 0x45de, 0x45de, 0x45de, 0x45df, 0x45df, 0x45df, 0x45df, 
+    0x45df, 0x45df, 0x45df, 0x45df, 0x45df, 0x45df, 0x45df, 0x45df, 
+    0x45e0, 0x45e0, 0x45e0, 0x45e0, 0x45e0, 0x45e0, 0x45e0, 0x45e0, 
+    0x45e0, 0x45e0, 0x45e0, 0x45e0, 0x45e1, 0x45e1, 0x45e1, 0x45e1, 
+    0x45e1, 0x45e1, 0x45e1, 0x45e1, 0x45e1, 0x45e1, 0x45e1, 0x45e1, 
+    0x45e2, 0x45e2, 0x45e2, 0x45e2, 0x45e2, 0x45e2, 0x45e2, 0x45e2, 
+    0x45e2, 0x45e2, 0x45e2, 0x45e2, 0x45e2, 0x45e3, 0x45e3, 0x45e3, 
+    0x45e3, 0x45e3, 0x45e3, 0x45e3, 0x45e3, 0x45e3, 0x45e3, 0x45e3, 
+    0x45e3, 0x45e4, 0x45e4, 0x45e4, 0x45e4, 0x45e4, 0x45e4, 0x45e4, 
+    0x45e4, 0x45e4, 0x45e4, 0x45e4, 0x45e4, 0x45e4, 0x45e5, 0x45e5, 
+    0x45e5, 0x45e5, 0x45e5, 0x45e5, 0x45e5, 0x45e5, 0x45e5, 0x45e5, 
+    0x45e5, 0x45e5, 0x45e6, 0x45e6, 0x45e6, 0x45e6, 0x45e6, 0x45e6, 
+    0x45e6, 0x45e6, 0x45e6, 0x45e6, 0x45e6, 0x45e6, 0x45e6, 0x45e7, 
+    0x45e7, 0x45e7, 0x45e7, 0x45e7, 0x45e7, 0x45e7, 0x45e7, 0x45e7, 
+    0x45e7, 0x45e7, 0x45e7, 0x45e7, 0x45e8, 0x45e8, 0x45e8, 0x45e8, 
+    0x45e8, 0x45e8, 0x45e8, 0x45e8, 0x45e8, 0x45e8, 0x45e8, 0x45e8, 
+    0x45e8, 0x45e9, 0x45e9, 0x45e9, 0x45e9, 0x45e9, 0x45e9, 0x45e9, 
+    0x45e9, 0x45e9, 0x45e9, 0x45e9, 0x45e9, 0x45e9, 0x45e9, 0x45ea, 
+    0x45ea, 0x45ea, 0x45ea, 0x45ea, 0x45ea, 0x45ea, 0x45ea, 0x45ea, 
+    0x45ea, 0x45ea, 0x45ea, 0x45ea, 0x45eb, 0x45eb, 0x45eb, 0x45eb, 
+    0x45eb, 0x45eb, 0x45eb, 0x45eb, 0x45eb, 0x45eb, 0x45eb, 0x45eb, 
+    0x45eb, 0x45ec, 0x45ec, 0x45ec, 0x45ec, 0x45ec, 0x45ec, 0x45ec, 
+    0x45ec, 0x45ec, 0x45ec, 0x45ec, 0x45ec, 0x45ec, 0x45ec, 0x45ed, 
+    0x45ed, 0x45ed, 0x45ed, 0x45ed, 0x45ed, 0x45ed, 0x45ed, 0x45ed, 
+    0x45ed, 0x45ed, 0x45ed, 0x45ed, 0x45ed, 0x45ee, 0x45ee, 0x45ee, 
+    0x45ee, 0x45ee, 0x45ee, 0x45ee, 0x45ee, 0x45ee, 0x45ee, 0x45ee, 
+    0x45ee, 0x45ee, 0x45ef, 0x45ef, 0x45ef, 0x45ef, 0x45ef, 0x45ef, 
+    0x45ef, 0x45ef, 0x45ef, 0x45ef, 0x45ef, 0x45ef, 0x45ef, 0x45ef, 
+    0x45f0, 0x45f0, 0x45f0, 0x45f0, 0x45f0, 0x45f0, 0x45f0, 0x45f0, 
+    0x45f0, 0x45f0, 0x45f0, 0x45f0, 0x45f0, 0x45f0, 0x45f1, 0x45f1, 
+    0x45f1, 0x45f1, 0x45f1, 0x45f1, 0x45f1, 0x45f1, 0x45f1, 0x45f1, 
+    0x45f1, 0x45f1, 0x45f1, 0x45f1, 0x45f2, 0x45f2, 0x45f2, 0x45f2, 
+    0x45f2, 0x45f2, 0x45f2, 0x45f2, 0x45f2, 0x45f2, 0x45f2, 0x45f2, 
+    0x45f2, 0x45f2, 0x45f2, 0x45f3, 0x45f3, 0x45f3, 0x45f3, 0x45f3, 
+    0x45f3, 0x45f3, 0x45f3, 0x45f3, 0x45f3, 0x45f3, 0x45f3, 0x45f3, 
+    0x45f3, 0x45f4, 0x45f4, 0x45f4, 0x45f4, 0x45f4, 0x45f4, 0x45f4, 
+    0x45f4, 0x45f4, 0x45f4, 0x45f4, 0x45f4, 0x45f4, 0x45f4, 0x45f5, 
+    0x45f5, 0x45f5, 0x45f5, 0x45f5, 0x45f5, 0x45f5, 0x45f5, 0x45f5, 
+    0x45f5, 0x45f5, 0x45f5, 0x45f5, 0x45f5, 0x45f5, 0x45f6, 0x45f6, 
+    0x45f6, 0x45f6, 0x45f6, 0x45f6, 0x45f6, 0x45f6, 0x45f6, 0x45f6, 
+    0x45f6, 0x45f6, 0x45f6, 0x45f6, 0x45f6, 0x45f7, 0x45f7, 0x45f7, 
+    0x45f7, 0x45f7, 0x45f7, 0x45f7, 0x45f7, 0x45f7, 0x45f7, 0x45f7, 
+    0x45f7, 0x45f7, 0x45f7, 0x45f7, 0x45f8, 0x45f8, 0x45f8, 0x45f8, 
+    0x45f8, 0x45f8, 0x45f8, 0x45f8, 0x45f8, 0x45f8, 0x45f8, 0x45f8, 
+    0x45f8, 0x45f8, 0x45f8, 0x45f9, 0x45f9, 0x45f9, 0x45f9, 0x45f9, 
+    0x45f9, 0x45f9, 0x45f9, 0x45f9, 0x45f9, 0x45f9, 0x45f9, 0x45f9, 
+    0x45f9, 0x45f9, 0x45fa, 0x45fa, 0x45fa, 0x45fa, 0x45fa, 0x45fa, 
+    0x45fa, 0x45fa, 0x45fa, 0x45fa, 0x45fa, 0x45fa, 0x45fa, 0x45fa, 
+    0x45fa, 0x45fb, 0x45fb, 0x45fb, 0x45fb, 0x45fb, 0x45fb, 0x45fb, 
+    0x45fb, 0x45fb, 0x45fb, 0x45fb, 0x45fb, 0x45fb, 0x45fb, 0x45fb, 
+    0x45fb, 0x45fc, 0x45fc, 0x45fc, 0x45fc, 0x45fc, 0x45fc, 0x45fc, 
+    0x45fc, 0x45fc, 0x45fc, 0x45fc, 0x45fc, 0x45fc, 0x45fc, 0x45fc, 
+    0x45fd, 0x45fd, 0x45fd, 0x45fd, 0x45fd, 0x45fd, 0x45fd, 0x45fd, 
+    0x45fd, 0x45fd, 0x45fd, 0x45fd, 0x45fd, 0x45fd, 0x45fd, 0x45fd, 
+    0x45fe, 0x45fe, 0x45fe, 0x45fe, 0x45fe, 0x45fe, 0x45fe, 0x45fe, 
+    0x45fe, 0x45fe, 0x45fe, 0x45fe, 0x45fe, 0x45fe, 0x45fe, 0x45fe, 
+    0x45ff, 0x45ff, 0x45ff, 0x45ff, 0x45ff, 0x45ff, 0x45ff, 0x45ff, 
+    0x45ff, 0x45ff, 0x45ff, 0x45ff, 0x45ff, 0x45ff, 0x45ff, 0x45ff, 
+    0x4600, 0x4600, 0x4600, 0x4600, 0x4600, 0x4600, 0x4600, 0x4600, 
+    0x4600, 0x4600, 0x4600, 0x4600, 0x4600, 0x4600, 0x4600, 0x4600, 
+    0x4601, 0x4601, 0x4601, 0x4601, 0x4601, 0x4601, 0x4601, 0x4601, 
+    0x4601, 0x4601, 0x4601, 0x4601, 0x4601, 0x4601, 0x4601, 0x4601, 
+    0x4602, 0x4602, 0x4602, 0x4602, 0x4602, 0x4602, 0x4602, 0x4602, 
+    0x4602, 0x4602, 0x4602, 0x4602, 0x4602, 0x4602, 0x4602, 0x4602, 
+    0x4603, 0x4603, 0x4603, 0x4603, 0x4603, 0x4603, 0x4603, 0x4603, 
+    0x4603, 0x4603, 0x4603, 0x4603, 0x4603, 0x4603, 0x4603, 0x4603, 
+    0x4603, 0x4604, 0x4604, 0x4604, 0x4604, 0x4604, 0x4604, 0x4604, 
+    0x4604, 0x4604, 0x4604, 0x4604, 0x4604, 0x4604, 0x4604, 0x4604, 
+    0x4604, 0x4605, 0x4605, 0x4605, 0x4605, 0x4605, 0x4605, 0x4605, 
+    0x4605, 0x4605, 0x4605, 0x4605, 0x4605, 0x4605, 0x4605, 0x4605, 
+    0x4605, 0x4605, 0x4606, 0x4606, 0x4606, 0x4606, 0x4606, 0x4606, 
+    0x4606, 0x4606, 0x4606, 0x4606, 0x4606, 0x4606, 0x4606, 0x4606, 
+    0x4606, 0x4606, 0x4606, 0x4607, 0x4607, 0x4607, 0x4607, 0x4607, 
+    0x4607, 0x4607, 0x4607, 0x4607, 0x4607, 0x4607, 0x4607, 0x4607, 
+    0x4607, 0x4607, 0x4607, 0x4607, 0x4608, 0x4608, 0x4608, 0x4608, 
+    0x4608, 0x4608, 0x4608, 0x4608, 0x4608, 0x4608, 0x4608, 0x4608, 
+    0x4608, 0x4608, 0x4608, 0x4608, 0x4608, 0x4609, 0x4609, 0x4609, 
+    0x4609, 0x4609, 0x4609, 0x4609, 0x4609, 0x4609, 0x4609, 0x4609, 
+    0x4609, 0x4609, 0x4609, 0x4609, 0x4609, 0x4609, 0x4609, 0x460a, 
+    0x460a, 0x460a, 0x460a, 0x460a, 0x460a, 0x460a, 0x460a, 0x460a, 
+    0x460a, 0x460a, 0x460a, 0x460a, 0x460a, 0x460a, 0x460a, 0x460a, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x9043, 0x91d7, 0x9305, 0x9400, 0x946d, 0x94cf, 0x9529, 
+    0x957b, 0x95c8, 0x9611, 0x9656, 0x9697, 0x96d6, 0x9712, 0x974b, 
+    0x9783, 0x97b9, 0x97ed, 0x9810, 0x9828, 0x9840, 0x9857, 0x986e, 
+    0x9884, 0x989a, 0x98af, 0x98c4, 0x98d8, 0x98ec, 0x98ff, 0x9913, 
+    0x9926, 0x9938, 0x994a, 0x995c, 0x996e, 0x997f, 0x9991, 0x99a2, 
+    0x99b2, 0x99c3, 0x99d3, 0x99e3, 0x99f3, 0x9a02, 0x9a12, 0x9a21, 
+    0x9a30, 0x9a3f, 0x9a4e, 0x9a5c, 0x9a6b, 0x9a79, 0x9a87, 0x9a95, 
+    0x9aa3, 0x9ab1, 0x9abe, 0x9acc, 0x9ad9, 0x9ae7, 0x9af4, 0x9b01, 
+    0x9b0d, 0x9b1a, 0x9b27, 0x9b33, 0x9b40, 0x9b4c, 0x9b59, 0x9b65, 
+    0x9b71, 0x9b7d, 0x9b89, 0x9b94, 0x9ba0, 0x9bac, 0x9bb7, 0x9bc3, 
+    0x9bce, 0x9bda, 0x9be5, 0x9bf0, 0x9bfb, 0x9c03, 0x9c09, 0x9c0e, 
+    0x9c13, 0x9c19, 0x9c1e, 0x9c23, 0x9c29, 0x9c2e, 0x9c33, 0x9c38, 
+    0x9c3d, 0x9c43, 0x9c48, 0x9c4d, 0x9c52, 0x9c57, 0x9c5c, 0x9c61, 
+    0x9c66, 0x9c6b, 0x9c6f, 0x9c74, 0x9c79, 0x9c7e, 0x9c83, 0x9c87, 
+    0x9c8c, 0x9c91, 0x9c96, 0x9c9a, 0x9c9f, 0x9ca4, 0x9ca8, 0x9cad, 
+    0x9cb1, 0x9cb6, 0x9cba, 0x9cbf, 0x9cc3, 0x9cc8, 0x9ccc, 0x9cd1, 
+    0x9cd5, 0x9cd9, 0x9cde, 0x9ce2, 0x9ce7, 0x9ceb, 0x9cef, 0x9cf3, 
+    0x9cf8, 0x9cfc, 0x9d00, 0x9d04, 0x9d09, 0x9d0d, 0x9d11, 0x9d15, 
+    0x9d19, 0x9d1d, 0x9d21, 0x9d25, 0x9d29, 0x9d2e, 0x9d32, 0x9d36, 
+    0x9d3a, 0x9d3e, 0x9d42, 0x9d46, 0x9d49, 0x9d4d, 0x9d51, 0x9d55, 
+    0x9d59, 0x9d5d, 0x9d61, 0x9d65, 0x9d69, 0x9d6c, 0x9d70, 0x9d74, 
+    0x9d78, 0x9d7c, 0x9d7f, 0x9d83, 0x9d87, 0x9d8b, 0x9d8e, 0x9d92, 
+    0x9d96, 0x9d99, 0x9d9d, 0x9da1, 0x9da4, 0x9da8, 0x9dac, 0x9daf, 
+    0x9db3, 0x9db7, 0x9dba, 0x9dbe, 0x9dc1, 0x9dc5, 0x9dc8, 0x9dcc, 
+    0x9dcf, 0x9dd3, 0x9dd6, 0x9dda, 0x9ddd, 0x9de1, 0x9de4, 0x9de8, 
+    0x9deb, 0x9def, 0x9df2, 0x9df6, 0x9df9, 0x9dfc, 0x9e00, 0x9e03, 
+    0x9e07, 0x9e0a, 0x9e0d, 0x9e11, 0x9e14, 0x9e17, 0x9e1b, 0x9e1e, 
+    0x9e21, 0x9e25, 0x9e28, 0x9e2b, 0x9e2e, 0x9e32, 0x9e35, 0x9e38, 
+    0x9e3b, 0x9e3f, 0x9e42, 0x9e45, 0x9e48, 0x9e4b, 0x9e4f, 0x9e52, 
+    0x9e55, 0x9e58, 0x9e5b, 0x9e5f, 0x9e62, 0x9e65, 0x9e68, 0x9e6b, 
+    0x9e6e, 0x9e71, 0x9e74, 0x9e78, 0x9e7b, 0x9e7e, 0x9e81, 0x9e84, 
+    0x9e87, 0x9e8a, 0x9e8d, 0x9e90, 0x9e93, 0x9e96, 0x9e99, 0x9e9c, 
+    0x9e9f, 0x9ea2, 0x9ea5, 0x9ea8, 0x9eab, 0x9eae, 0x9eb1, 0x9eb4, 
+    0x9eb7, 0x9eba, 0x9ebd, 0x9ec0, 0x9ec3, 0x9ec6, 0x9ec9, 0x9ecc, 
+    0x9ecf, 0x9ed2, 0x9ed4, 0x9ed7, 0x9eda, 0x9edd, 0x9ee0, 0x9ee3, 
+    0x9ee6, 0x9ee9, 0x9eeb, 0x9eee, 0x9ef1, 0x9ef4, 0x9ef7, 0x9efa, 
+    0x9efc, 0x9eff, 0x9f02, 0x9f05, 0x9f08, 0x9f0b, 0x9f0d, 0x9f10, 
+    0x9f13, 0x9f16, 0x9f18, 0x9f1b, 0x9f1e, 0x9f21, 0x9f23, 0x9f26, 
+    0x9f29, 0x9f2c, 0x9f2e, 0x9f31, 0x9f34, 0x9f37, 0x9f39, 0x9f3c, 
+    0x9f3f, 0x9f41, 0x9f44, 0x9f47, 0x9f4a, 0x9f4c, 0x9f4f, 0x9f52, 
+    0x9f54, 0x9f57, 0x9f5a, 0x9f5c, 0x9f5f, 0x9f61, 0x9f64, 0x9f67, 
+    0x9f69, 0x9f6c, 0x9f6f, 0x9f71, 0x9f74, 0x9f76, 0x9f79, 0x9f7c, 
+    0x9f7e, 0x9f81, 0x9f83, 0x9f86, 0x9f89, 0x9f8b, 0x9f8e, 0x9f90, 
+    0x9f93, 0x9f95, 0x9f98, 0x9f9b, 0x9f9d, 0x9fa0, 0x9fa2, 0x9fa5, 
+    0x9fa7, 0x9faa, 0x9fac, 0x9faf, 0x9fb1, 0x9fb4, 0x9fb6, 0x9fb9, 
+    0x9fbb, 0x9fbe, 0x9fc0, 0x9fc3, 0x9fc5, 0x9fc8, 0x9fca, 0x9fcd, 
+    0x9fcf, 0x9fd2, 0x9fd4, 0x9fd7, 0x9fd9, 0x9fdc, 0x9fde, 0x9fe0, 
+    0x9fe3, 0x9fe5, 0x9fe8, 0x9fea, 0x9fed, 0x9fef, 0x9ff1, 0x9ff4, 
+    0x9ff6, 0x9ff9, 0x9ffb, 0x9ffe, 0xa000, 0xa001, 0xa002, 0xa004, 
+    0xa005, 0xa006, 0xa007, 0xa008, 0xa00a, 0xa00b, 0xa00c, 0xa00d, 
+    0xa00e, 0xa00f, 0xa011, 0xa012, 0xa013, 0xa014, 0xa015, 0xa016, 
+    0xa018, 0xa019, 0xa01a, 0xa01b, 0xa01c, 0xa01d, 0xa01f, 0xa020, 
+    0xa021, 0xa022, 0xa023, 0xa024, 0xa026, 0xa027, 0xa028, 0xa029, 
+    0xa02a, 0xa02b, 0xa02c, 0xa02e, 0xa02f, 0xa030, 0xa031, 0xa032, 
+    0xa033, 0xa034, 0xa035, 0xa037, 0xa038, 0xa039, 0xa03a, 0xa03b, 
+    0xa03c, 0xa03d, 0xa03e, 0xa040, 0xa041, 0xa042, 0xa043, 0xa044, 
+    0xa045, 0xa046, 0xa047, 0xa048, 0xa04a, 0xa04b, 0xa04c, 0xa04d, 
+    0xa04e, 0xa04f, 0xa050, 0xa051, 0xa052, 0xa053, 0xa055, 0xa056, 
+    0xa057, 0xa058, 0xa059, 0xa05a, 0xa05b, 0xa05c, 0xa05d, 0xa05e, 
+    0xa05f, 0xa060, 0xa062, 0xa063, 0xa064, 0xa065, 0xa066, 0xa067, 
+    0xa068, 0xa069, 0xa06a, 0xa06b, 0xa06c, 0xa06d, 0xa06e, 0xa06f, 
+    0xa070, 0xa072, 0xa073, 0xa074, 0xa075, 0xa076, 0xa077, 0xa078, 
+    0xa079, 0xa07a, 0xa07b, 0xa07c, 0xa07d, 0xa07e, 0xa07f, 0xa080, 
+    0xa081, 0xa082, 0xa083, 0xa084, 0xa085, 0xa086, 0xa087, 0xa089, 
+    0xa08a, 0xa08b, 0xa08c, 0xa08d, 0xa08e, 0xa08f, 0xa090, 0xa091, 
+    0xa092, 0xa093, 0xa094, 0xa095, 0xa096, 0xa097, 0xa098, 0xa099, 
+    0xa09a, 0xa09b, 0xa09c, 0xa09d, 0xa09e, 0xa09f, 0xa0a0, 0xa0a1, 
+    0xa0a2, 0xa0a3, 0xa0a4, 0xa0a5, 0xa0a6, 0xa0a7, 0xa0a8, 0xa0a9, 
+    0xa0aa, 0xa0ab, 0xa0ac, 0xa0ad, 0xa0ae, 0xa0af, 0xa0b0, 0xa0b1, 
+    0xa0b2, 0xa0b3, 0xa0b4, 0xa0b5, 0xa0b6, 0xa0b7, 0xa0b8, 0xa0b9, 
+    0xa0ba, 0xa0bb, 0xa0bc, 0xa0bd, 0xa0be, 0xa0bf, 0xa0c0, 0xa0c1, 
+    0xa0c2, 0xa0c3, 0xa0c4, 0xa0c5, 0xa0c6, 0xa0c7, 0xa0c7, 0xa0c8, 
+    0xa0c9, 0xa0ca, 0xa0cb, 0xa0cc, 0xa0cd, 0xa0ce, 0xa0cf, 0xa0d0, 
+    0xa0d1, 0xa0d2, 0xa0d3, 0xa0d4, 0xa0d5, 0xa0d6, 0xa0d7, 0xa0d8, 
+    0xa0d9, 0xa0da, 0xa0db, 0xa0dc, 0xa0dd, 0xa0de, 0xa0de, 0xa0df, 
+    0xa0e0, 0xa0e1, 0xa0e2, 0xa0e3, 0xa0e4, 0xa0e5, 0xa0e6, 0xa0e7, 
+    0xa0e8, 0xa0e9, 0xa0ea, 0xa0eb, 0xa0ec, 0xa0ed, 0xa0ee, 0xa0ee, 
+    0xa0ef, 0xa0f0, 0xa0f1, 0xa0f2, 0xa0f3, 0xa0f4, 0xa0f5, 0xa0f6, 
+    0xa0f7, 0xa0f8, 0xa0f9, 0xa0fa, 0xa0fb, 0xa0fb, 0xa0fc, 0xa0fd, 
+    0xa0fe, 0xa0ff, 0xa100, 0xa101, 0xa102, 0xa103, 0xa104, 0xa105, 
+    0xa106, 0xa106, 0xa107, 0xa108, 0xa109, 0xa10a, 0xa10b, 0xa10c, 
+    0xa10d, 0xa10e, 0xa10f, 0xa110, 0xa110, 0xa111, 0xa112, 0xa113, 
+    0xa114, 0xa115, 0xa116, 0xa117, 0xa118, 0xa119, 0xa119, 0xa11a, 
+    0xa11b, 0xa11c, 0xa11d, 0xa11e, 0xa11f, 0xa120, 0xa121, 0xa121, 
+    0xa122, 0xa123, 0xa124, 0xa125, 0xa126, 0xa127, 0xa128, 0xa129, 
+    0xa129, 0xa12a, 0xa12b, 0xa12c, 0xa12d, 0xa12e, 0xa12f, 0xa130, 
+    0xa130, 0xa131, 0xa132, 0xa133, 0xa134, 0xa135, 0xa136, 0xa137, 
+    0xa137, 0xa138, 0xa139, 0xa13a, 0xa13b, 0xa13c, 0xa13d, 0xa13e, 
+    0xa13e, 0xa13f, 0xa140, 0xa141, 0xa142, 0xa143, 0xa144, 0xa144, 
+    0xa145, 0xa146, 0xa147, 0xa148, 0xa149, 0xa14a, 0xa14b, 0xa14b, 
+    0xa14c, 0xa14d, 0xa14e, 0xa14f, 0xa150, 0xa151, 0xa151, 0xa152, 
+    0xa153, 0xa154, 0xa155, 0xa156, 0xa156, 0xa157, 0xa158, 0xa159, 
+    0xa15a, 0xa15b, 0xa15c, 0xa15c, 0xa15d, 0xa15e, 0xa15f, 0xa160, 
+    0xa161, 0xa161, 0xa162, 0xa163, 0xa164, 0xa165, 0xa166, 0xa166, 
+    0xa167, 0xa168, 0xa169, 0xa16a, 0xa16b, 0xa16b, 0xa16c, 0xa16d, 
+    0xa16e, 0xa16f, 0xa170, 0xa170, 0xa171, 0xa172, 0xa173, 0xa174, 
+    0xa175, 0xa175, 0xa176, 0xa177, 0xa178, 0xa179, 0xa17a, 0xa17a, 
+    0xa17b, 0xa17c, 0xa17d, 0xa17e, 0xa17e, 0xa17f, 0xa180, 0xa181, 
+    0xa182, 0xa183, 0xa183, 0xa184, 0xa185, 0xa186, 0xa187, 0xa187, 
+    0xa188, 0xa189, 0xa18a, 0xa18b, 0xa18c, 0xa18c, 0xa18d, 0xa18e, 
+    0xa18f, 0xa190, 0xa190, 0xa191, 0xa192, 0xa193, 0xa194, 0xa194, 
+    0xa195, 0xa196, 0xa197, 0xa198, 0xa198, 0xa199, 0xa19a, 0xa19b, 
+    0xa19c, 0xa19c, 0xa19d, 0xa19e, 0xa19f, 0xa1a0, 0xa1a0, 0xa1a1, 
+    0xa1a2, 0xa1a3, 0xa1a4, 0xa1a4, 0xa1a5, 0xa1a6, 0xa1a7, 0xa1a8, 
+    0xa1a8, 0xa1a9, 0xa1aa, 0xa1ab, 0xa1ac, 0xa1ac, 0xa1ad, 0xa1ae, 
+    0xa1af, 0xa1af, 0xa1b0, 0xa1b1, 0xa1b2, 0xa1b3, 0xa1b3, 0xa1b4, 
+    0xa1b5, 0xa1b6, 0xa1b7, 0xa1b7, 0xa1b8, 0xa1b9, 0xa1ba, 0xa1ba, 
+    0xa1bb, 0xa1bc, 0xa1bd, 0xa1be, 0xa1be, 0xa1bf, 0xa1c0, 0xa1c1, 
+    0xa1c1, 0xa1c2, 0xa1c3, 0xa1c4, 0xa1c5, 0xa1c5, 0xa1c6, 0xa1c7, 
+    0xa1c8, 0xa1c8, 0xa1c9, 0xa1ca, 0xa1cb, 0xa1cb, 0xa1cc, 0xa1cd, 
+    0xa1ce, 0xa1cf, 0xa1cf, 0xa1d0, 0xa1d1, 0xa1d2, 0xa1d2, 0xa1d3, 
+    0xa1d4, 0xa1d5, 0xa1d5, 0xa1d6, 0xa1d7, 0xa1d8, 0xa1d8, 0xa1d9, 
+    0xa1da, 0xa1db, 0xa1db, 0xa1dc, 0xa1dd, 0xa1de, 0xa1df, 0xa1df, 
+    0xa1e0, 0xa1e1, 0xa1e2, 0xa1e2, 0xa1e3, 0xa1e4, 0xa1e5, 0xa1e5, 
+    0xa1e6, 0xa1e7, 0xa1e8, 0xa1e8, 0xa1e9, 0xa1ea, 0xa1eb, 0xa1eb, 
+    0xa1ec, 0xa1ed, 0xa1ee, 0xa1ee, 0xa1ef, 0xa1f0, 0xa1f1, 0xa1f1, 
+    0xa1f2, 0xa1f3, 0xa1f4, 0xa1f4, 0xa1f5, 0xa1f6, 0xa1f7, 0xa1f7, 
+    0xa1f8, 0xa1f9, 0xa1f9, 0xa1fa, 0xa1fb, 0xa1fc, 0xa1fc, 0xa1fd, 
+    0xa1fe, 0xa1ff, 0xa1ff, 0xa200, 0xa201, 0xa202, 0xa202, 0xa203, 
+    0xa204, 0xa205, 0xa205, 0xa206, 0xa207, 0xa207, 0xa208, 0xa209, 
+    0xa20a, 0xa20a, 0xa20b, 0xa20c, 0xa20d, 0xa20d, 0xa20e, 0xa20f, 
+    0xa210, 0xa210, 0xa211, 0xa212, 0xa212, 0xa213, 0xa214, 0xa215, 
+    0xa215, 0xa216, 0xa217, 0xa218, 0xa218, 0xa219, 0xa21a, 0xa21a, 
+    0xa21b, 0xa21c, 0xa21d, 0xa21d, 0xa21e, 0xa21f, 0xa21f, 0xa220, 
+    0xa221, 0xa222, 0xa222, 0xa223, 0xa224, 0xa224, 0xa225, 0xa226, 
+    0xa227, 0xa227, 0xa228, 0xa229, 0xa22a, 0xa22a, 0xa22b, 0xa22c, 
+    0xa22c, 0xa22d, 0xa22e, 0xa22e, 0xa22f, 0xa230, 0xa231, 0xa231, 
+    0xa232, 0xa233, 0xa233, 0xa234, 0xa235, 0xa236, 0xa236, 0xa237, 
+    0xa238, 0xa238, 0xa239, 0xa23a, 0xa23b, 0xa23b, 0xa23c, 0xa23d, 
+    0xa23d, 0xa23e, 0xa23f, 0xa23f, 0xa240, 0xa241, 0xa242, 0xa242, 
+    0xa243, 0xa244, 0xa244, 0xa245, 0xa246, 0xa246, 0xa247, 0xa248, 
+    0xa249, 0xa249, 0xa24a, 0xa24b, 0xa24b, 0xa24c, 0xa24d, 0xa24d, 
+    0xa24e, 0xa24f, 0xa250, 0xa250, 0xa251, 0xa252, 0xa252, 0xa253, 
+    0xa254, 0xa254, 0xa255, 0xa256, 0xa256, 0xa257, 0xa258, 0xa259, 
+    0xa259, 0xa25a, 0xa25b, 0xa25b, 0xa25c, 0xa25d, 0xa25d, 0xa25e, 
+    0xa25f, 0xa25f, 0xa260, 0xa261, 0xa261, 0xa262, 0xa263, 0xa264, 
+    0xa264, 0xa265, 0xa266, 0xa266, 0xa267, 0xa268, 0xa268, 0xa269, 
+    0xa26a, 0xa26a, 0xa26b, 0xa26c, 0xa26c, 0xa26d, 0xa26e, 0xa26e, 
+    0xa26f, 0xa270, 0xa270, 0xa271, 0xa272, 0xa272, 0xa273, 0xa274, 
+    0xa274, 0xa275, 0xa276, 0xa277, 0xa277, 0xa278, 0xa279, 0xa279, 
+    0xa27a, 0xa27b, 0xa27b, 0xa27c, 0xa27d, 0xa27d, 0xa27e, 0xa27f, 
+    0xa27f, 0xa280, 0xa281, 0xa281, 0xa282, 0xa283, 0xa283, 0xa284, 
+    0xa285, 0xa285, 0xa286, 0xa287, 0xa287, 0xa288, 0xa289, 0xa289, 
+    0xa28a, 0xa28b, 0xa28b, 0xa28c, 0xa28d, 0xa28d, 0xa28e, 0xa28f, 
+    0xa28f, 0xa290, 0xa291, 0xa291, 0xa292, 0xa293, 0xa293, 0xa294, 
+    0xa295, 0xa295, 0xa296, 0xa297, 0xa297, 0xa298, 0xa298, 0xa299, 
+    0xa29a, 0xa29a, 0xa29b, 0xa29c, 0xa29c, 0xa29d, 0xa29e, 0xa29e, 
+    0xa29f, 0xa2a0, 0xa2a0, 0xa2a1, 0xa2a2, 0xa2a2, 0xa2a3, 0xa2a4, 
+    0xa2a4, 0xa2a5, 0xa2a6, 0xa2a6, 0xa2a7, 0xa2a8, 0xa2a8, 0xa2a9, 
+    0xa2aa, 0xa2aa, 0xa2ab, 0xa2ab, 0xa2ac, 0xa2ad, 0xa2ad, 0xa2ae, 
+    0xa2af, 0xa2af, 0xa2b0, 0xa2b1, 0xa2b1, 0xa2b2, 0xa2b3, 0xa2b3, 
+    0xa2b4, 0xa2b5, 0xa2b5, 0xa2b6, 0xa2b6, 0xa2b7, 0xa2b8, 0xa2b8, 
+    0xa2b9, 0xa2ba, 0xa2ba, 0xa2bb, 0xa2bc, 0xa2bc, 0xa2bd, 0xa2be, 
+    0xa2be, 0xa2bf, 0xa2bf, 0xa2c0, 0xa2c1, 0xa2c1, 0xa2c2, 0xa2c3, 
+    0xa2c3, 0xa2c4, 0xa2c5, 0xa2c5, 0xa2c6, 0xa2c6, 0xa2c7, 0xa2c8, 
+    0xa2c8, 0xa2c9, 0xa2ca, 0xa2ca, 0xa2cb, 0xa2cc, 0xa2cc, 0xa2cd, 
+    0xa2cd, 0xa2ce, 0xa2cf, 0xa2cf, 0xa2d0, 0xa2d1, 0xa2d1, 0xa2d2, 
+    0xa2d3, 0xa2d3, 0xa2d4, 0xa2d4, 0xa2d5, 0xa2d6, 0xa2d6, 0xa2d7, 
+    0xa2d8, 0xa2d8, 0xa2d9, 0xa2d9, 0xa2da, 0xa2db, 0xa2db, 0xa2dc, 
+    0xa2dd, 0xa2dd, 0xa2de, 0xa2de, 0xa2df, 0xa2e0, 0xa2e0, 0xa2e1, 
+    0xa2e2, 0xa2e2, 0xa2e3, 0xa2e4, 0xa2e4, 0xa2e5, 0xa2e5, 0xa2e6, 
+    0xa2e7, 0xa2e7, 0xa2e8, 0xa2e8, 0xa2e9, 0xa2ea, 0xa2ea, 0xa2eb, 
+    0xa2ec, 0xa2ec, 0xa2ed, 0xa2ed, 0xa2ee, 0xa2ef, 0xa2ef, 0xa2f0, 
+    0xa2f1, 0xa2f1, 0xa2f2, 0xa2f2, 0xa2f3, 0xa2f4, 0xa2f4, 0xa2f5, 
+    0xa2f6, 0xa2f6, 0xa2f7, 0xa2f7, 0xa2f8, 0xa2f9, 0xa2f9, 0xa2fa, 
+    0xa2fa, 0xa2fb, 0xa2fc, 0xa2fc, 0xa2fd, 0xa2fe, 0xa2fe, 0xa2ff, 
+    0xa2ff, 0xa300, 0xa301, 0xa301, 0xa302, 0xa302, 0xa303, 0xa304, 
+    0xa304, 0xa305, 0xa305, 0xa306, 0xa307, 0xa307, 0xa308, 0xa309, 
+    0xa309, 0xa30a, 0xa30a, 0xa30b, 0xa30c, 0xa30c, 0xa30d, 0xa30d, 
+    0xa30e, 0xa30f, 0xa30f, 0xa310, 0xa310, 0xa311, 0xa312, 0xa312, 
+    0xa313, 0xa313, 0xa314, 0xa315, 0xa315, 0xa316, 0xa316, 0xa317, 
+    0xa318, 0xa318, 0xa319, 0xa319, 0xa31a, 0xa31b, 0xa31b, 0xa31c, 
+    0xa31d, 0xa31d, 0xa31e, 0xa31e, 0xa31f, 0xa320, 0xa320, 0xa321, 
+    0xa321, 0xa322, 0xa323, 0xa323, 0xa324, 0xa324, 0xa325, 0xa325, 
+    0xa326, 0xa327, 0xa327, 0xa328, 0xa328, 0xa329, 0xa32a, 0xa32a, 
+    0xa32b, 0xa32b, 0xa32c, 0xa32d, 0xa32d, 0xa32e, 0xa32e, 0xa32f, 
+    0xa330, 0xa330, 0xa331, 0xa331, 0xa332, 0xa333, 0xa333, 0xa334, 
+    0xa334, 0xa335, 0xa336, 0xa336, 0xa337, 0xa337, 0xa338, 0xa339, 
+    0xa339, 0xa33a, 0xa33a, 0xa33b, 0xa33b, 0xa33c, 0xa33d, 0xa33d, 
+    0xa33e, 0xa33e, 0xa33f, 0xa340, 0xa340, 0xa341, 0xa341, 0xa342, 
+    0xa343, 0xa343, 0xa344, 0xa344, 0xa345, 0xa345, 0xa346, 0xa347, 
+    0xa347, 0xa348, 0xa348, 0xa349, 0xa34a, 0xa34a, 0xa34b, 0xa34b, 
+    0xa34c, 0xa34c, 0xa34d, 0xa34e, 0xa34e, 0xa34f, 0xa34f, 0xa350, 
+    0xa351, 0xa351, 0xa352, 0xa352, 0xa353, 0xa353, 0xa354, 0xa355, 
+    0xa355, 0xa356, 0xa356, 0xa357, 0xa357, 0xa358, 0xa359, 0xa359, 
+    0xa35a, 0xa35a, 0xa35b, 0xa35c, 0xa35c, 0xa35d, 0xa35d, 0xa35e, 
+    0xa35e, 0xa35f, 0xa360, 0xa360, 0xa361, 0xa361, 0xa362, 0xa362, 
+    0xa363, 0xa364, 0xa364, 0xa365, 0xa365, 0xa366, 0xa366, 0xa367, 
+    0xa368, 0xa368, 0xa369, 0xa369, 0xa36a, 0xa36a, 0xa36b, 0xa36c, 
+    0xa36c, 0xa36d, 0xa36d, 0xa36e, 0xa36e, 0xa36f, 0xa370, 0xa370, 
+    0xa371, 0xa371, 0xa372, 0xa372, 0xa373, 0xa374, 0xa374, 0xa375, 
+    0xa375, 0xa376, 0xa376, 0xa377, 0xa378, 0xa378, 0xa379, 0xa379, 
+    0xa37a, 0xa37a, 0xa37b, 0xa37c, 0xa37c, 0xa37d, 0xa37d, 0xa37e, 
+    0xa37e, 0xa37f, 0xa37f, 0xa380, 0xa381, 0xa381, 0xa382, 0xa382, 
+    0xa383, 0xa383, 0xa384, 0xa385, 0xa385, 0xa386, 0xa386, 0xa387, 
+    0xa387, 0xa388, 0xa388, 0xa389, 0xa38a, 0xa38a, 0xa38b, 0xa38b, 
+    0xa38c, 0xa38c, 0xa38d, 0xa38e, 0xa38e, 0xa38f, 0xa38f, 0xa390, 
+    0xa390, 0xa391, 0xa391, 0xa392, 0xa393, 0xa393, 0xa394, 0xa394, 
+    0xa395, 0xa395, 0xa396, 0xa396, 0xa397, 0xa398, 0xa398, 0xa399, 
+    0xa399, 0xa39a, 0xa39a, 0xa39b, 0xa39b, 0xa39c, 0xa39d, 0xa39d, 
+    0xa39e, 0xa39e, 0xa39f, 0xa39f, 0xa3a0, 0xa3a0, 0xa3a1, 0xa3a2, 
+    0xa3a2, 0xa3a3, 0xa3a3, 0xa3a4, 0xa3a4, 0xa3a5, 0xa3a5, 0xa3a6, 
+    0xa3a7, 0xa3a7, 0xa3a8, 0xa3a8, 0xa3a9, 0xa3a9, 0xa3aa, 0xa3aa, 
+    0xa3ab, 0xa3ab, 0xa3ac, 0xa3ad, 0xa3ad, 0xa3ae, 0xa3ae, 0xa3af, 
+    0xa3af, 0xa3b0, 0xa3b0, 0xa3b1, 0xa3b2, 0xa3b2, 0xa3b3, 0xa3b3, 
+    0xa3b4, 0xa3b4, 0xa3b5, 0xa3b5, 0xa3b6, 0xa3b6, 0xa3b7, 0xa3b8, 
+    0xa3b8, 0xa3b9, 0xa3b9, 0xa3ba, 0xa3ba, 0xa3bb, 0xa3bb, 0xa3bc, 
+    0xa3bc, 0xa3bd, 0xa3bd, 0xa3be, 0xa3bf, 0xa3bf, 0xa3c0, 0xa3c0, 
+    0xa3c1, 0xa3c1, 0xa3c2, 0xa3c2, 0xa3c3, 0xa3c3, 0xa3c4, 0xa3c5, 
+    0xa3c5, 0xa3c6, 0xa3c6, 0xa3c7, 0xa3c7, 0xa3c8, 0xa3c8, 0xa3c9, 
+    0xa3c9, 0xa3ca, 0xa3ca, 0xa3cb, 0xa3cc, 0xa3cc, 0xa3cd, 0xa3cd, 
+    0xa3ce, 0xa3ce, 0xa3cf, 0xa3cf, 0xa3d0, 0xa3d0, 0xa3d1, 0xa3d1, 
+    0xa3d2, 0xa3d3, 0xa3d3, 0xa3d4, 0xa3d4, 0xa3d5, 0xa3d5, 0xa3d6, 
+    0xa3d6, 0xa3d7, 0xa3d7, 0xa3d8, 0xa3d8, 0xa3d9, 0xa3da, 0xa3da, 
+    0xa3db, 0xa3db, 0xa3dc, 0xa3dc, 0xa3dd, 0xa3dd, 0xa3de, 0xa3de, 
+    0xa3df, 0xa3df, 0xa3e0, 0xa3e0, 0xa3e1, 0xa3e2, 0xa3e2, 0xa3e3, 
+    0xa3e3, 0xa3e4, 0xa3e4, 0xa3e5, 0xa3e5, 0xa3e6, 0xa3e6, 0xa3e7, 
+    0xa3e7, 0xa3e8, 0xa3e8, 0xa3e9, 0xa3e9, 0xa3ea, 0xa3eb, 0xa3eb, 
+    0xa3ec, 0xa3ec, 0xa3ed, 0xa3ed, 0xa3ee, 0xa3ee, 0xa3ef, 0xa3ef, 
+    0xa3f0, 0xa3f0, 0xa3f1, 0xa3f1, 0xa3f2, 0xa3f2, 0xa3f3, 0xa3f3, 
+    0xa3f4, 0xa3f5, 0xa3f5, 0xa3f6, 0xa3f6, 0xa3f7, 0xa3f7, 0xa3f8, 
+    0xa3f8, 0xa3f9, 0xa3f9, 0xa3fa, 0xa3fa, 0xa3fb, 0xa3fb, 0xa3fc, 
+    0xa3fc, 0xa3fd, 0xa3fd, 0xa3fe, 0xa3fe, 0xa3ff, 0xa400, 0xa400, 
+    0xa400, 0xa401, 0xa401, 0xa401, 0xa401, 0xa402, 0xa402, 0xa402, 
+    0xa402, 0xa403, 0xa403, 0xa403, 0xa403, 0xa404, 0xa404, 0xa404, 
+    0xa404, 0xa405, 0xa405, 0xa405, 0xa405, 0xa406, 0xa406, 0xa406, 
+    0xa407, 0xa407, 0xa407, 0xa407, 0xa408, 0xa408, 0xa408, 0xa408, 
+    0xa409, 0xa409, 0xa409, 0xa409, 0xa40a, 0xa40a, 0xa40a, 0xa40a, 
+    0xa40b, 0xa40b, 0xa40b, 0xa40b, 0xa40c, 0xa40c, 0xa40c, 0xa40c, 
+    0xa40d, 0xa40d, 0xa40d, 0xa40d, 0xa40e, 0xa40e, 0xa40e, 0xa40f, 
+    0xa40f, 0xa40f, 0xa40f, 0xa410, 0xa410, 0xa410, 0xa410, 0xa411, 
+    0xa411, 0xa411, 0xa411, 0xa412, 0xa412, 0xa412, 0xa412, 0xa413, 
+    0xa413, 0xa413, 0xa413, 0xa414, 0xa414, 0xa414, 0xa414, 0xa415, 
+    0xa415, 0xa415, 0xa415, 0xa416, 0xa416, 0xa416, 0xa416, 0xa417, 
+    0xa417, 0xa417, 0xa417, 0xa418, 0xa418, 0xa418, 0xa418, 0xa419, 
+    0xa419, 0xa419, 0xa419, 0xa41a, 0xa41a, 0xa41a, 0xa41b, 0xa41b, 
+    0xa41b, 0xa41b, 0xa41c, 0xa41c, 0xa41c, 0xa41c, 0xa41d, 0xa41d, 
+    0xa41d, 0xa41d, 0xa41e, 0xa41e, 0xa41e, 0xa41e, 0xa41f, 0xa41f, 
+    0xa41f, 0xa41f, 0xa420, 0xa420, 0xa420, 0xa420, 0xa421, 0xa421, 
+    0xa421, 0xa421, 0xa422, 0xa422, 0xa422, 0xa422, 0xa423, 0xa423, 
+    0xa423, 0xa423, 0xa424, 0xa424, 0xa424, 0xa424, 0xa425, 0xa425, 
+    0xa425, 0xa425, 0xa426, 0xa426, 0xa426, 0xa426, 0xa427, 0xa427, 
+    0xa427, 0xa427, 0xa428, 0xa428, 0xa428, 0xa428, 0xa429, 0xa429, 
+    0xa429, 0xa429, 0xa42a, 0xa42a, 0xa42a, 0xa42a, 0xa42b, 0xa42b, 
+    0xa42b, 0xa42b, 0xa42c, 0xa42c, 0xa42c, 0xa42c, 0xa42d, 0xa42d, 
+    0xa42d, 0xa42d, 0xa42e, 0xa42e, 0xa42e, 0xa42e, 0xa42f, 0xa42f, 
+    0xa42f, 0xa42f, 0xa430, 0xa430, 0xa430, 0xa430, 0xa431, 0xa431, 
+    0xa431, 0xa431, 0xa431, 0xa432, 0xa432, 0xa432, 0xa432, 0xa433, 
+    0xa433, 0xa433, 0xa433, 0xa434, 0xa434, 0xa434, 0xa434, 0xa435, 
+    0xa435, 0xa435, 0xa435, 0xa436, 0xa436, 0xa436, 0xa436, 0xa437, 
+    0xa437, 0xa437, 0xa437, 0xa438, 0xa438, 0xa438, 0xa438, 0xa439, 
+    0xa439, 0xa439, 0xa439, 0xa43a, 0xa43a, 0xa43a, 0xa43a, 0xa43b, 
+    0xa43b, 0xa43b, 0xa43b, 0xa43c, 0xa43c, 0xa43c, 0xa43c, 0xa43d, 
+    0xa43d, 0xa43d, 0xa43d, 0xa43e, 0xa43e, 0xa43e, 0xa43e, 0xa43e, 
+    0xa43f, 0xa43f, 0xa43f, 0xa43f, 0xa440, 0xa440, 0xa440, 0xa440, 
+    0xa441, 0xa441, 0xa441, 0xa441, 0xa442, 0xa442, 0xa442, 0xa442, 
+    0xa443, 0xa443, 0xa444, 0xa444, 0xa445, 0xa445, 0xa446, 0xa446, 
+    0xa446, 0xa447, 0xa447, 0xa448, 0xa448, 0xa449, 0xa449, 0xa44a, 
+    0xa44a, 0xa44b, 0xa44b, 0xa44c, 0xa44c, 0xa44d, 0xa44d, 0xa44e, 
+    0xa44e, 0xa44f, 0xa44f, 0xa450, 0xa450, 0xa451, 0xa451, 0xa451, 
+    0xa452, 0xa452, 0xa453, 0xa453, 0xa454, 0xa454, 0xa455, 0xa455, 
+    0xa456, 0xa456, 0xa457, 0xa457, 0xa458, 0xa458, 0xa459, 0xa459, 
+    0xa45a, 0xa45a, 0xa45a, 0xa45b, 0xa45b, 0xa45c, 0xa45c, 0xa45d, 
+    0xa45d, 0xa45e, 0xa45e, 0xa45f, 0xa45f, 0xa460, 0xa460, 0xa461, 
+    0xa461, 0xa462, 0xa462, 0xa462, 0xa463, 0xa463, 0xa464, 0xa464, 
+    0xa465, 0xa465, 0xa466, 0xa466, 0xa467, 0xa467, 0xa468, 0xa468, 
+    0xa469, 0xa469, 0xa469, 0xa46a, 0xa46a, 0xa46b, 0xa46b, 0xa46c, 
+    0xa46c, 0xa46d, 0xa46d, 0xa46e, 0xa46e, 0xa46f, 0xa46f, 0xa46f, 
+    0xa470, 0xa470, 0xa471, 0xa471, 0xa472, 0xa472, 0xa473, 0xa473, 
+    0xa474, 0xa474, 0xa475, 0xa475, 0xa475, 0xa476, 0xa476, 0xa477, 
+    0xa477, 0xa478, 0xa478, 0xa479, 0xa479, 0xa47a, 0xa47a, 0xa47a, 
+    0xa47b, 0xa47b, 0xa47c, 0xa47c, 0xa47d, 0xa47d, 0xa47e, 0xa47e, 
+    0xa47f, 0xa47f, 0xa47f, 0xa480, 0xa480, 0xa481, 0xa481, 0xa482, 
+    0xa482, 0xa483, 0xa483, 0xa484, 0xa484, 0xa484, 0xa485, 0xa485, 
+    0xa486, 0xa486, 0xa487, 0xa487, 0xa488, 0xa488, 0xa489, 0xa489, 
+    0xa489, 0xa48a, 0xa48a, 0xa48b, 0xa48b, 0xa48c, 0xa48c, 0xa48d, 
+    0xa48d, 0xa48d, 0xa48e, 0xa48e, 0xa48f, 0xa48f, 0xa490, 0xa490, 
+    0xa491, 0xa491, 0xa491, 0xa492, 0xa492, 0xa493, 0xa493, 0xa494, 
+    0xa494, 0xa495, 0xa495, 0xa495, 0xa496, 0xa496, 0xa497, 0xa497, 
+    0xa498, 0xa498, 0xa499, 0xa499, 0xa499, 0xa49a, 0xa49a, 0xa49b, 
+    0xa49b, 0xa49c, 0xa49c, 0xa49d, 0xa49d, 0xa49d, 0xa49e, 0xa49e, 
+    0xa49f, 0xa49f, 0xa4a0, 0xa4a0, 0xa4a0, 0xa4a1, 0xa4a1, 0xa4a2, 
+    0xa4a2, 0xa4a3, 0xa4a3, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a5, 0xa4a5, 
+    0xa4a6, 0xa4a6, 0xa4a7, 0xa4a7, 0xa4a7, 0xa4a8, 0xa4a8, 0xa4a9, 
+    0xa4a9, 0xa4aa, 0xa4aa, 0xa4ab, 0xa4ab, 0xa4ab, 0xa4ac, 0xa4ac, 
+    0xa4ad, 0xa4ad, 0xa4ae, 0xa4ae, 0xa4ae, 0xa4af, 0xa4af, 0xa4b0, 
+    0xa4b0, 0xa4b1, 0xa4b1, 0xa4b1, 0xa4b2, 0xa4b2, 0xa4b3, 0xa4b3, 
+    0xa4b4, 0xa4b4, 0xa4b4, 0xa4b5, 0xa4b5, 0xa4b6, 0xa4b6, 0xa4b7, 
+    0xa4b7, 0xa4b7, 0xa4b8, 0xa4b8, 0xa4b9, 0xa4b9, 0xa4ba, 0xa4ba, 
+    0xa4ba, 0xa4bb, 0xa4bb, 0xa4bc, 0xa4bc, 0xa4bd, 0xa4bd, 0xa4bd, 
+    0xa4be, 0xa4be, 0xa4bf, 0xa4bf, 0xa4c0, 0xa4c0, 0xa4c0, 0xa4c1, 
+    0xa4c1, 0xa4c2, 0xa4c2, 0xa4c3, 0xa4c3, 0xa4c3, 0xa4c4, 0xa4c4, 
+    0xa4c5, 0xa4c5, 0xa4c5, 0xa4c6, 0xa4c6, 0xa4c7, 0xa4c7, 0xa4c8, 
+    0xa4c8, 0xa4c8, 0xa4c9, 0xa4c9, 0xa4ca, 0xa4ca, 0xa4cb, 0xa4cb, 
+    0xa4cb, 0xa4cc, 0xa4cc, 0xa4cd, 0xa4cd, 0xa4cd, 0xa4ce, 0xa4ce, 
+    0xa4cf, 0xa4cf, 0xa4d0, 0xa4d0, 0xa4d0, 0xa4d1, 0xa4d1, 0xa4d2, 
+    0xa4d2, 0xa4d3, 0xa4d3, 0xa4d3, 0xa4d4, 0xa4d4, 0xa4d5, 0xa4d5, 
+    0xa4d5, 0xa4d6, 0xa4d6, 0xa4d7, 0xa4d7, 0xa4d8, 0xa4d8, 0xa4d8, 
+    0xa4d9, 0xa4d9, 0xa4da, 0xa4da, 0xa4da, 0xa4db, 0xa4db, 0xa4dc, 
+    0xa4dc, 0xa4dc, 0xa4dd, 0xa4dd, 0xa4de, 0xa4de, 0xa4df, 0xa4df, 
+    0xa4df, 0xa4e0, 0xa4e0, 0xa4e1, 0xa4e1, 0xa4e1, 0xa4e2, 0xa4e2, 
+    0xa4e3, 0xa4e3, 0xa4e3, 0xa4e4, 0xa4e4, 0xa4e5, 0xa4e5, 0xa4e6, 
+    0xa4e6, 0xa4e6, 0xa4e7, 0xa4e7, 0xa4e8, 0xa4e8, 0xa4e8, 0xa4e9, 
+    0xa4e9, 0xa4ea, 0xa4ea, 0xa4ea, 0xa4eb, 0xa4eb, 0xa4ec, 0xa4ec, 
+    0xa4ec, 0xa4ed, 0xa4ed, 0xa4ee, 0xa4ee, 0xa4ee, 0xa4ef, 0xa4ef, 
+    0xa4f0, 0xa4f0, 0xa4f1, 0xa4f1, 0xa4f1, 0xa4f2, 0xa4f2, 0xa4f3, 
+    0xa4f3, 0xa4f3, 0xa4f4, 0xa4f4, 0xa4f5, 0xa4f5, 0xa4f5, 0xa4f6, 
+    0xa4f6, 0xa4f7, 0xa4f7, 0xa4f7, 0xa4f8, 0xa4f8, 0xa4f9, 0xa4f9, 
+    0xa4f9, 0xa4fa, 0xa4fa, 0xa4fb, 0xa4fb, 0xa4fb, 0xa4fc, 0xa4fc, 
+    0xa4fd, 0xa4fd, 0xa4fd, 0xa4fe, 0xa4fe, 0xa4ff, 0xa4ff, 0xa4ff, 
+    0xa500, 0xa500, 0xa501, 0xa501, 0xa501, 0xa502, 0xa502, 0xa503, 
+    0xa503, 0xa503, 0xa504, 0xa504, 0xa505, 0xa505, 0xa505, 0xa506, 
+    0xa506, 0xa507, 0xa507, 0xa507, 0xa508, 0xa508, 0xa509, 0xa509, 
+    0xa509, 0xa50a, 0xa50a, 0xa50b, 0xa50b, 0xa50b, 0xa50c, 0xa50c, 
+    0xa50d, 0xa50d, 0xa50d, 0xa50e, 0xa50e, 0xa50f, 0xa50f, 0xa50f, 
+    0xa510, 0xa510, 0xa510, 0xa511, 0xa511, 0xa512, 0xa512, 0xa512, 
+    0xa513, 0xa513, 0xa514, 0xa514, 0xa514, 0xa515, 0xa515, 0xa516, 
+    0xa516, 0xa516, 0xa517, 0xa517, 0xa518, 0xa518, 0xa518, 0xa519, 
+    0xa519, 0xa519, 0xa51a, 0xa51a, 0xa51b, 0xa51b, 0xa51b, 0xa51c, 
+    0xa51c, 0xa51d, 0xa51d, 0xa51d, 0xa51e, 0xa51e, 0xa51f, 0xa51f, 
+    0xa51f, 0xa520, 0xa520, 0xa520, 0xa521, 0xa521, 0xa522, 0xa522, 
+    0xa522, 0xa523, 0xa523, 0xa524, 0xa524, 0xa524, 0xa525, 0xa525, 
+    0xa526, 0xa526, 0xa526, 0xa527, 0xa527, 0xa527, 0xa528, 0xa528, 
+    0xa529, 0xa529, 0xa529, 0xa52a, 0xa52a, 0xa52b, 0xa52b, 0xa52b, 
+    0xa52c, 0xa52c, 0xa52c, 0xa52d, 0xa52d, 0xa52e, 0xa52e, 0xa52e, 
+    0xa52f, 0xa52f, 0xa52f, 0xa530, 0xa530, 0xa531, 0xa531, 0xa531, 
+    0xa532, 0xa532, 0xa533, 0xa533, 0xa533, 0xa534, 0xa534, 0xa534, 
+    0xa535, 0xa535, 0xa536, 0xa536, 0xa536, 0xa537, 0xa537, 0xa537, 
+    0xa538, 0xa538, 0xa539, 0xa539, 0xa539, 0xa53a, 0xa53a, 0xa53b, 
+    0xa53b, 0xa53b, 0xa53c, 0xa53c, 0xa53c, 0xa53d, 0xa53d, 0xa53e, 
+    0xa53e, 0xa53e, 0xa53f, 0xa53f, 0xa53f, 0xa540, 0xa540, 0xa541, 
+    0xa541, 0xa541, 0xa542, 0xa542, 0xa542, 0xa543, 0xa543, 0xa544, 
+    0xa544, 0xa544, 0xa545, 0xa545, 0xa545, 0xa546, 0xa546, 0xa547, 
+    0xa547, 0xa547, 0xa548, 0xa548, 0xa548, 0xa549, 0xa549, 0xa54a, 
+    0xa54a, 0xa54a, 0xa54b, 0xa54b, 0xa54b, 0xa54c, 0xa54c, 0xa54d, 
+    0xa54d, 0xa54d, 0xa54e, 0xa54e, 0xa54e, 0xa54f, 0xa54f, 0xa550, 
+    0xa550, 0xa550, 0xa551, 0xa551, 0xa551, 0xa552, 0xa552, 0xa553, 
+    0xa553, 0xa553, 0xa554, 0xa554, 0xa554, 0xa555, 0xa555, 0xa555, 
+    0xa556, 0xa556, 0xa557, 0xa557, 0xa557, 0xa558, 0xa558, 0xa558, 
+    0xa559, 0xa559, 0xa55a, 0xa55a, 0xa55a, 0xa55b, 0xa55b, 0xa55b, 
+    0xa55c, 0xa55c, 0xa55c, 0xa55d, 0xa55d, 0xa55e, 0xa55e, 0xa55e, 
+    0xa55f, 0xa55f, 0xa55f, 0xa560, 0xa560, 0xa561, 0xa561, 0xa561, 
+    0xa562, 0xa562, 0xa562, 0xa563, 0xa563, 0xa563, 0xa564, 0xa564, 
+    0xa565, 0xa565, 0xa565, 0xa566, 0xa566, 0xa566, 0xa567, 0xa567, 
+    0xa567, 0xa568, 0xa568, 0xa569, 0xa569, 0xa569, 0xa56a, 0xa56a, 
+    0xa56a, 0xa56b, 0xa56b, 0xa56b, 0xa56c, 0xa56c, 0xa56d, 0xa56d, 
+    0xa56d, 0xa56e, 0xa56e, 0xa56e, 0xa56f, 0xa56f, 0xa56f, 0xa570, 
+    0xa570, 0xa570, 0xa571, 0xa571, 0xa572, 0xa572, 0xa572, 0xa573, 
+    0xa573, 0xa573, 0xa574, 0xa574, 0xa574, 0xa575, 0xa575, 0xa576, 
+    0xa576, 0xa576, 0xa577, 0xa577, 0xa577, 0xa578, 0xa578, 0xa578, 
+    0xa579, 0xa579, 0xa579, 0xa57a, 0xa57a, 0xa57b, 0xa57b, 0xa57b, 
+    0xa57c, 0xa57c, 0xa57c, 0xa57d, 0xa57d, 0xa57d, 0xa57e, 0xa57e, 
+    0xa57e, 0xa57f, 0xa57f, 0xa580, 0xa580, 0xa580, 0xa581, 0xa581, 
+    0xa581, 0xa582, 0xa582, 0xa582, 0xa583, 0xa583, 0xa583, 0xa584, 
+    0xa584, 0xa585, 0xa585, 0xa585, 0xa586, 0xa586, 0xa586, 0xa587, 
+    0xa587, 0xa587, 0xa588, 0xa588, 0xa588, 0xa589, 0xa589, 0xa58a, 
+    0xa58a, 0xa58a, 0xa58b, 0xa58b, 0xa58b, 0xa58c, 0xa58c, 0xa58c, 
+    0xa58d, 0xa58d, 0xa58d, 0xa58e, 0xa58e, 0xa58e, 0xa58f, 0xa58f, 
+    0xa58f, 0xa590, 0xa590, 0xa591, 0xa591, 0xa591, 0xa592, 0xa592, 
+    0xa592, 0xa593, 0xa593, 0xa593, 0xa594, 0xa594, 0xa594, 0xa595, 
+    0xa595, 0xa595, 0xa596, 0xa596, 0xa597, 0xa597, 0xa597, 0xa598, 
+    0xa598, 0xa598, 0xa599, 0xa599, 0xa599, 0xa59a, 0xa59a, 0xa59a, 
+    0xa59b, 0xa59b, 0xa59b, 0xa59c, 0xa59c, 0xa59c, 0xa59d, 0xa59d, 
+    0xa59d, 0xa59e, 0xa59e, 0xa59f, 0xa59f, 0xa59f, 0xa5a0, 0xa5a0, 
+    0xa5a0, 0xa5a1, 0xa5a1, 0xa5a1, 0xa5a2, 0xa5a2, 0xa5a2, 0xa5a3, 
+    0xa5a3, 0xa5a3, 0xa5a4, 0xa5a4, 0xa5a4, 0xa5a5, 0xa5a5, 0xa5a5, 
+    0xa5a6, 0xa5a6, 0xa5a6, 0xa5a7, 0xa5a7, 0xa5a8, 0xa5a8, 0xa5a8, 
+    0xa5a9, 0xa5a9, 0xa5a9, 0xa5aa, 0xa5aa, 0xa5aa, 0xa5ab, 0xa5ab, 
+    0xa5ab, 0xa5ac, 0xa5ac, 0xa5ac, 0xa5ad, 0xa5ad, 0xa5ad, 0xa5ae, 
+    0xa5ae, 0xa5ae, 0xa5af, 0xa5af, 0xa5af, 0xa5b0, 0xa5b0, 0xa5b0, 
+    0xa5b1, 0xa5b1, 0xa5b1, 0xa5b2, 0xa5b2, 0xa5b2, 0xa5b3, 0xa5b3, 
+    0xa5b4, 0xa5b4, 0xa5b4, 0xa5b5, 0xa5b5, 0xa5b5, 0xa5b6, 0xa5b6, 
+    0xa5b6, 0xa5b7, 0xa5b7, 0xa5b7, 0xa5b8, 0xa5b8, 0xa5b8, 0xa5b9, 
+    0xa5b9, 0xa5b9, 0xa5ba, 0xa5ba, 0xa5ba, 0xa5bb, 0xa5bb, 0xa5bb, 
+    0xa5bc, 0xa5bc, 0xa5bc, 0xa5bd, 0xa5bd, 0xa5bd, 0xa5be, 0xa5be, 
+    0xa5be, 0xa5bf, 0xa5bf, 0xa5bf, 0xa5c0, 0xa5c0, 0xa5c0, 0xa5c1, 
+    0xa5c1, 0xa5c1, 0xa5c2, 0xa5c2, 0xa5c2, 0xa5c3, 0xa5c3, 0xa5c3, 
+    0xa5c4, 0xa5c4, 0xa5c4, 0xa5c5, 0xa5c5, 0xa5c5, 0xa5c6, 0xa5c6, 
+    0xa5c6, 0xa5c7, 0xa5c7, 0xa5c7, 0xa5c8, 0xa5c8, 0xa5c8, 0xa5c9, 
+    0xa5c9, 0xa5ca, 0xa5ca, 0xa5ca, 0xa5cb, 0xa5cb, 0xa5cb, 0xa5cc, 
+    0xa5cc, 0xa5cc, 0xa5cd, 0xa5cd, 0xa5cd, 0xa5ce, 0xa5ce, 0xa5ce, 
+    0xa5cf, 0xa5cf, 0xa5cf, 0xa5d0, 0xa5d0, 0xa5d0, 0xa5d1, 0xa5d1, 
+    0xa5d1, 0xa5d2, 0xa5d2, 0xa5d2, 0xa5d3, 0xa5d3, 0xa5d3, 0xa5d4, 
+    0xa5d4, 0xa5d4, 0xa5d5, 0xa5d5, 0xa5d5, 0xa5d6, 0xa5d6, 0xa5d6, 
+    0xa5d7, 0xa5d7, 0xa5d8, 0xa5d8, 0xa5d9, 0xa5da, 0xa5da, 0xa5db, 
+    0xa5dc, 0xa5dc, 0xa5dd, 0xa5de, 0xa5de, 0xa5df, 0xa5e0, 0xa5e0, 
+    0xa5e1, 0xa5e2, 0xa5e2, 0xa5e3, 0xa5e4, 0xa5e4, 0xa5e5, 0xa5e6, 
+    0xa5e6, 0xa5e7, 0xa5e8, 0xa5e8, 0xa5e9, 0xa5ea, 0xa5ea, 0xa5eb, 
+    0xa5ec, 0xa5ec, 0xa5ed, 0xa5ee, 0xa5ee, 0xa5ef, 0xa5ef, 0xa5f0, 
+    0xa5f1, 0xa5f1, 0xa5f2, 0xa5f3, 0xa5f3, 0xa5f4, 0xa5f5, 0xa5f5, 
+    0xa5f6, 0xa5f7, 0xa5f7, 0xa5f8, 0xa5f9, 0xa5f9, 0xa5fa, 0xa5fa, 
+    0xa5fb, 0xa5fc, 0xa5fc, 0xa5fd, 0xa5fe, 0xa5fe, 0xa5ff, 0xa600, 
+    0xa600, 0xa601, 0xa602, 0xa602, 0xa603, 0xa603, 0xa604, 0xa605, 
+    0xa605, 0xa606, 0xa607, 0xa607, 0xa608, 0xa609, 0xa609, 0xa60a, 
+    0xa60a, 0xa60b, 0xa60c, 0xa60c, 0xa60d, 0xa60e, 0xa60e, 0xa60f, 
+    0xa610, 0xa610, 0xa611, 0xa611, 0xa612, 0xa613, 0xa613, 0xa614, 
+    0xa615, 0xa615, 0xa616, 0xa617, 0xa617, 0xa618, 0xa618, 0xa619, 
+    0xa61a, 0xa61a, 0xa61b, 0xa61c, 0xa61c, 0xa61d, 0xa61d, 0xa61e, 
+    0xa61f, 0xa61f, 0xa620, 0xa621, 0xa621, 0xa622, 0xa622, 0xa623, 
+    0xa624, 0xa624, 0xa625, 0xa626, 0xa626, 0xa627, 0xa627, 0xa628, 
+    0xa629, 0xa629, 0xa62a, 0xa62b, 0xa62b, 0xa62c, 0xa62c, 0xa62d, 
+    0xa62e, 0xa62e, 0xa62f, 0xa630, 0xa630, 0xa631, 0xa631, 0xa632, 
+    0xa633, 0xa633, 0xa634, 0xa634, 0xa635, 0xa636, 0xa636, 0xa637, 
+    0xa638, 0xa638, 0xa639, 0xa639, 0xa63a, 0xa63b, 0xa63b, 0xa63c, 
+    0xa63c, 0xa63d, 0xa63e, 0xa63e, 0xa63f, 0xa640, 0xa640, 0xa641, 
+    0xa641, 0xa642, 0xa643, 0xa643, 0xa644, 0xa644, 0xa645, 0xa646, 
+    0xa646, 0xa647, 0xa647, 0xa648, 0xa649, 0xa649, 0xa64a, 0xa64a, 
+    0xa64b, 0xa64c, 0xa64c, 0xa64d, 0xa64e, 0xa64e, 0xa64f, 0xa64f, 
+    0xa650, 0xa651, 0xa651, 0xa652, 0xa652, 0xa653, 0xa654, 0xa654, 
+    0xa655, 0xa655, 0xa656, 0xa657, 0xa657, 0xa658, 0xa658, 0xa659, 
+    0xa65a, 0xa65a, 0xa65b, 0xa65b, 0xa65c, 0xa65d, 0xa65d, 0xa65e, 
+    0xa65e, 0xa65f, 0xa660, 0xa660, 0xa661, 0xa661, 0xa662, 0xa663, 
+    0xa663, 0xa664, 0xa664, 0xa665, 0xa666, 0xa666, 0xa667, 0xa667, 
+    0xa668, 0xa668, 0xa669, 0xa66a, 0xa66a, 0xa66b, 0xa66b, 0xa66c, 
+    0xa66d, 0xa66d, 0xa66e, 0xa66e, 0xa66f, 0xa670, 0xa670, 0xa671, 
+    0xa671, 0xa672, 0xa673, 0xa673, 0xa674, 0xa674, 0xa675, 0xa675, 
+    0xa676, 0xa677, 0xa677, 0xa678, 0xa678, 0xa679, 0xa67a, 0xa67a, 
+    0xa67b, 0xa67b, 0xa67c, 0xa67c, 0xa67d, 0xa67e, 0xa67e, 0xa67f, 
+    0xa67f, 0xa680, 0xa681, 0xa681, 0xa682, 0xa682, 0xa683, 0xa683, 
+    0xa684, 0xa685, 0xa685, 0xa686, 0xa686, 0xa687, 0xa688, 0xa688, 
+    0xa689, 0xa689, 0xa68a, 0xa68a, 0xa68b, 0xa68c, 0xa68c, 0xa68d, 
+    0xa68d, 0xa68e, 0xa68f, 0xa68f, 0xa690, 0xa690, 0xa691, 0xa691, 
+    0xa692, 0xa693, 0xa693, 0xa694, 0xa694, 0xa695, 0xa695, 0xa696, 
+    0xa697, 0xa697, 0xa698, 0xa698, 0xa699, 0xa699, 0xa69a, 0xa69b, 
+    0xa69b, 0xa69c, 0xa69c, 0xa69d, 0xa69d, 0xa69e, 0xa69f, 0xa69f, 
+    0xa6a0, 0xa6a0, 0xa6a1, 0xa6a1, 0xa6a2, 0xa6a3, 0xa6a3, 0xa6a4, 
+    0xa6a4, 0xa6a5, 0xa6a5, 0xa6a6, 0xa6a7, 0xa6a7, 0xa6a8, 0xa6a8, 
+    0xa6a9, 0xa6a9, 0xa6aa, 0xa6aa, 0xa6ab, 0xa6ac, 0xa6ac, 0xa6ad, 
+    0xa6ad, 0xa6ae, 0xa6ae, 0xa6af, 0xa6b0, 0xa6b0, 0xa6b1, 0xa6b1, 
+    0xa6b2, 0xa6b2, 0xa6b3, 0xa6b4, 0xa6b4, 0xa6b5, 0xa6b5, 0xa6b6, 
+    0xa6b6, 0xa6b7, 0xa6b7, 0xa6b8, 0xa6b9, 0xa6b9, 0xa6ba, 0xa6ba, 
+    0xa6bb, 0xa6bb, 0xa6bc, 0xa6bc, 0xa6bd, 0xa6be, 0xa6be, 0xa6bf, 
+    0xa6bf, 0xa6c0, 0xa6c0, 0xa6c1, 0xa6c2, 0xa6c2, 0xa6c3, 0xa6c3, 
+    0xa6c4, 0xa6c4, 0xa6c5, 0xa6c5, 0xa6c6, 0xa6c7, 0xa6c7, 0xa6c8, 
+    0xa6c8, 0xa6c9, 0xa6c9, 0xa6ca, 0xa6ca, 0xa6cb, 0xa6cb, 0xa6cc, 
+    0xa6cd, 0xa6cd, 0xa6ce, 0xa6ce, 0xa6cf, 0xa6cf, 0xa6d0, 0xa6d0, 
+    0xa6d1, 0xa6d2, 0xa6d2, 0xa6d3, 0xa6d3, 0xa6d4, 0xa6d4, 0xa6d5, 
+    0xa6d5, 0xa6d6, 0xa6d7, 0xa6d7, 0xa6d8, 0xa6d8, 0xa6d9, 0xa6d9, 
+    0xa6da, 0xa6da, 0xa6db, 0xa6db, 0xa6dc, 0xa6dd, 0xa6dd, 0xa6de, 
+    0xa6de, 0xa6df, 0xa6df, 0xa6e0, 0xa6e0, 0xa6e1, 0xa6e1, 0xa6e2, 
+    0xa6e3, 0xa6e3, 0xa6e4, 0xa6e4, 0xa6e5, 0xa6e5, 0xa6e6, 0xa6e6, 
+    0xa6e7, 0xa6e7, 0xa6e8, 0xa6e9, 0xa6e9, 0xa6ea, 0xa6ea, 0xa6eb, 
+    0xa6eb, 0xa6ec, 0xa6ec, 0xa6ed, 0xa6ed, 0xa6ee, 0xa6ee, 0xa6ef, 
+    0xa6f0, 0xa6f0, 0xa6f1, 0xa6f1, 0xa6f2, 0xa6f2, 0xa6f3, 0xa6f3, 
+    0xa6f4, 0xa6f4, 0xa6f5, 0xa6f5, 0xa6f6, 0xa6f7, 0xa6f7, 0xa6f8, 
+    0xa6f8, 0xa6f9, 0xa6f9, 0xa6fa, 0xa6fa, 0xa6fb, 0xa6fb, 0xa6fc, 
+    0xa6fc, 0xa6fd, 0xa6fe, 0xa6fe, 0xa6ff, 0xa6ff, 0xa700, 0xa700, 
+    0xa701, 0xa701, 0xa702, 0xa702, 0xa703, 0xa703, 0xa704, 0xa704, 
+    0xa705, 0xa705, 0xa706, 0xa707, 0xa707, 0xa708, 0xa708, 0xa709, 
+    0xa709, 0xa70a, 0xa70a, 0xa70b, 0xa70b, 0xa70c, 0xa70c, 0xa70d, 
+    0xa70d, 0xa70e, 0xa70f, 0xa70f, 0xa710, 0xa710, 0xa711, 0xa711, 
+    0xa712, 0xa712, 0xa713, 0xa713, 0xa714, 0xa714, 0xa715, 0xa715, 
+    0xa716, 0xa716, 0xa717, 0xa717, 0xa718, 0xa719, 0xa719, 0xa71a, 
+    0xa71a, 0xa71b, 0xa71b, 0xa71c, 0xa71c, 0xa71d, 0xa71d, 0xa71e, 
+    0xa71e, 0xa71f, 0xa71f, 0xa720, 0xa720, 0xa721, 0xa721, 0xa722, 
+    0xa722, 0xa723, 0xa723, 0xa724, 0xa725, 0xa725, 0xa726, 0xa726, 
+    0xa727, 0xa727, 0xa728, 0xa728, 0xa729, 0xa729, 0xa72a, 0xa72a, 
+    0xa72b, 0xa72b, 0xa72c, 0xa72c, 0xa72d, 0xa72d, 0xa72e, 0xa72e, 
+    0xa72f, 0xa72f, 0xa730, 0xa730, 0xa731, 0xa732, 0xa732, 0xa733, 
+    0xa733, 0xa734, 0xa734, 0xa735, 0xa735, 0xa736, 0xa736, 0xa737, 
+    0xa737, 0xa738, 0xa738, 0xa739, 0xa739, 0xa73a, 0xa73a, 0xa73b, 
+    0xa73b, 0xa73c, 0xa73c, 0xa73d, 0xa73d, 0xa73e, 0xa73e, 0xa73f, 
+    0xa73f, 0xa740, 0xa740, 0xa741, 0xa741, 0xa742, 0xa742, 0xa743, 
+    0xa743, 0xa744, 0xa744, 0xa745, 0xa746, 0xa746, 0xa747, 0xa747, 
+    0xa748, 0xa748, 0xa749, 0xa749, 0xa74a, 0xa74a, 0xa74b, 0xa74b, 
+    0xa74c, 0xa74c, 0xa74d, 0xa74d, 0xa74e, 0xa74e, 0xa74f, 0xa74f, 
+    0xa750, 0xa750, 0xa751, 0xa751, 0xa752, 0xa752, 0xa753, 0xa753, 
+    0xa754, 0xa754, 0xa755, 0xa755, 0xa756, 0xa756, 0xa757, 0xa757, 
+    0xa758, 0xa758, 0xa759, 0xa759, 0xa75a, 0xa75a, 0xa75b, 0xa75b, 
+    0xa75c, 0xa75c, 0xa75d, 0xa75d, 0xa75e, 0xa75e, 0xa75f, 0xa75f, 
+    0xa760, 0xa760, 0xa761, 0xa761, 0xa762, 0xa762, 0xa763, 0xa763, 
+    0xa764, 0xa764, 0xa765, 0xa765, 0xa766, 0xa766, 0xa767, 0xa767, 
+    0xa768, 0xa768, 0xa769, 0xa769, 0xa76a, 0xa76a, 0xa76b, 0xa76b, 
+    0xa76c, 0xa76c, 0xa76d, 0xa76d, 0xa76e, 0xa76e, 0xa76f, 0xa76f, 
+    0xa770, 0xa770, 0xa771, 0xa771, 0xa772, 0xa772, 0xa773, 0xa773, 
+    0xa774, 0xa774, 0xa775, 0xa775, 0xa776, 0xa776, 0xa777, 0xa777, 
+    0xa778, 0xa778, 0xa779, 0xa779, 0xa77a, 0xa77a, 0xa77b, 0xa77b, 
+    0xa77c, 0xa77c, 0xa77d, 0xa77d, 0xa77e, 0xa77e, 0xa77f, 0xa77f, 
+    0xa780, 0xa780, 0xa781, 0xa781, 0xa782, 0xa782, 0xa782, 0xa783, 
+    0xa783, 0xa784, 0xa784, 0xa785, 0xa785, 0xa786, 0xa786, 0xa787, 
+    0xa787, 0xa788, 0xa788, 0xa789, 0xa789, 0xa78a, 0xa78a, 0xa78b, 
+    0xa78b, 0xa78c, 0xa78c, 0xa78d, 0xa78d, 0xa78e, 0xa78e, 0xa78f, 
+    0xa78f, 0xa790, 0xa790, 0xa791, 0xa791, 0xa792, 0xa792, 0xa793, 
+    0xa793, 0xa794, 0xa794, 0xa795, 0xa795, 0xa796, 0xa796, 0xa796, 
+    0xa797, 0xa797, 0xa798, 0xa798, 0xa799, 0xa799, 0xa79a, 0xa79a, 
+    0xa79b, 0xa79b, 0xa79c, 0xa79c, 0xa79d, 0xa79d, 0xa79e, 0xa79e, 
+    0xa79f, 0xa79f, 0xa7a0, 0xa7a0, 0xa7a1, 0xa7a1, 0xa7a2, 0xa7a2, 
+    0xa7a3, 0xa7a3, 0xa7a4, 0xa7a4, 0xa7a4, 0xa7a5, 0xa7a5, 0xa7a6, 
+    0xa7a6, 0xa7a7, 0xa7a7, 0xa7a8, 0xa7a8, 0xa7a9, 0xa7a9, 0xa7aa, 
+    0xa7aa, 0xa7ab, 0xa7ab, 0xa7ac, 0xa7ac, 0xa7ad, 0xa7ad, 0xa7ae, 
+    0xa7ae, 0xa7af, 0xa7af, 0xa7af, 0xa7b0, 0xa7b0, 0xa7b1, 0xa7b1, 
+    0xa7b2, 0xa7b2, 0xa7b3, 0xa7b3, 0xa7b4, 0xa7b4, 0xa7b5, 0xa7b5, 
+    0xa7b6, 0xa7b6, 0xa7b7, 0xa7b7, 0xa7b8, 0xa7b8, 0xa7b9, 0xa7b9, 
+    0xa7b9, 0xa7ba, 0xa7ba, 0xa7bb, 0xa7bb, 0xa7bc, 0xa7bc, 0xa7bd, 
+    0xa7bd, 0xa7be, 0xa7be, 0xa7bf, 0xa7bf, 0xa7c0, 0xa7c0, 0xa7c1, 
+    0xa7c1, 0xa7c1, 0xa7c2, 0xa7c2, 0xa7c3, 0xa7c3, 0xa7c4, 0xa7c4, 
+    0xa7c5, 0xa7c5, 0xa7c6, 0xa7c6, 0xa7c7, 0xa7c7, 0xa7c8, 0xa7c8, 
+    0xa7c9, 0xa7c9, 0xa7c9, 0xa7ca, 0xa7ca, 0xa7cb, 0xa7cb, 0xa7cc, 
+    0xa7cc, 0xa7cd, 0xa7cd, 0xa7ce, 0xa7ce, 0xa7cf, 0xa7cf, 0xa7d0, 
+    0xa7d0, 0xa7d1, 0xa7d1, 0xa7d1, 0xa7d2, 0xa7d2, 0xa7d3, 0xa7d3, 
+    0xa7d4, 0xa7d4, 0xa7d5, 0xa7d5, 0xa7d6, 0xa7d6, 0xa7d7, 0xa7d7, 
+    0xa7d8, 0xa7d8, 0xa7d8, 0xa7d9, 0xa7d9, 0xa7da, 0xa7da, 0xa7db, 
+    0xa7db, 0xa7dc, 0xa7dc, 0xa7dd, 0xa7dd, 0xa7de, 0xa7de, 0xa7de, 
+    0xa7df, 0xa7df, 0xa7e0, 0xa7e0, 0xa7e1, 0xa7e1, 0xa7e2, 0xa7e2, 
+    0xa7e3, 0xa7e3, 0xa7e4, 0xa7e4, 0xa7e5, 0xa7e5, 0xa7e5, 0xa7e6, 
+    0xa7e6, 0xa7e7, 0xa7e7, 0xa7e8, 0xa7e8, 0xa7e9, 0xa7e9, 0xa7ea, 
+    0xa7ea, 0xa7eb, 0xa7eb, 0xa7eb, 0xa7ec, 0xa7ec, 0xa7ed, 0xa7ed, 
+    0xa7ee, 0xa7ee, 0xa7ef, 0xa7ef, 0xa7f0, 0xa7f0, 0xa7f0, 0xa7f1, 
+    0xa7f1, 0xa7f2, 0xa7f2, 0xa7f3, 0xa7f3, 0xa7f4, 0xa7f4, 0xa7f5, 
+    0xa7f5, 0xa7f6, 0xa7f6, 0xa7f6, 0xa7f7, 0xa7f7, 0xa7f8, 0xa7f8, 
+    0xa7f9, 0xa7f9, 0xa7fa, 0xa7fa, 0xa7fb, 0xa7fb, 0xa7fb, 0xa7fc, 
+    0xa7fc, 0xa7fd, 0xa7fd, 0xa7fe, 0xa7fe, 0xa7ff, 0xa7ff, 0xa800, 
+    0xa800, 0xa800, 0xa801, 0xa801, 0xa802, 0xa802, 0xa803, 0xa803, 
+    0xa804, 0xa804, 0xa805, 0xa805, 0xa805, 0xa806, 0xa806, 0xa807, 
+    0xa807, 0xa808, 0xa808, 0xa809, 0xa809, 0xa809, 0xa80a, 0xa80a, 
+    0xa80b, 0xa80b, 0xa80c, 0xa80c, 0xa80d, 0xa80d, 0xa80e, 0xa80e, 
+    0xa80e, 0xa80f, 0xa80f, 0xa810, 0xa810, 0xa811, 0xa811, 0xa812, 
+    0xa812, 0xa812, 0xa813, 0xa813, 0xa814, 0xa814, 0xa815, 0xa815, 
+    0xa816, 0xa816, 0xa816, 0xa817, 0xa817, 0xa818, 0xa818, 0xa819, 
+    0xa819, 0xa81a, 0xa81a, 0xa81a, 0xa81b, 0xa81b, 0xa81c, 0xa81c, 
+    0xa81d, 0xa81d, 0xa81d, 0xa81e, 0xa81e, 0xa81f, 0xa81f, 0xa820, 
+    0xa820, 0xa821, 0xa821, 0xa821, 0xa822, 0xa822, 0xa823, 0xa823, 
+    0xa824, 0xa824, 0xa824, 0xa825, 0xa825, 0xa826, 0xa826, 0xa827, 
+    0xa827, 0xa828, 0xa828, 0xa828, 0xa829, 0xa829, 0xa82a, 0xa82a, 
+    0xa82b, 0xa82b, 0xa82b, 0xa82c, 0xa82c, 0xa82d, 0xa82d, 0xa82e, 
+    0xa82e, 0xa82e, 0xa82f, 0xa82f, 0xa830, 0xa830, 0xa831, 0xa831, 
+    0xa831, 0xa832, 0xa832, 0xa833, 0xa833, 0xa834, 0xa834, 0xa834, 
+    0xa835, 0xa835, 0xa836, 0xa836, 0xa837, 0xa837, 0xa837, 0xa838, 
+    0xa838, 0xa839, 0xa839, 0xa83a, 0xa83a, 0xa83a, 0xa83b, 0xa83b, 
+    0xa83c, 0xa83c, 0xa83d, 0xa83d, 0xa83d, 0xa83e, 0xa83e, 0xa83f, 
+    0xa83f, 0xa840, 0xa840, 0xa840, 0xa841, 0xa841, 0xa842, 0xa842, 
+    0xa842, 0xa843, 0xa843, 0xa844, 0xa844, 0xa845, 0xa845, 0xa845, 
+    0xa846, 0xa846, 0xa847, 0xa847, 0xa848, 0xa848, 0xa848, 0xa849, 
+    0xa849, 0xa84a, 0xa84a, 0xa84a, 0xa84b, 0xa84b, 0xa84c, 0xa84c, 
+    0xa84d, 0xa84d, 0xa84d, 0xa84e, 0xa84e, 0xa84f, 0xa84f, 0xa84f, 
+    0xa850, 0xa850, 0xa851, 0xa851, 0xa852, 0xa852, 0xa852, 0xa853, 
+    0xa853, 0xa854, 0xa854, 0xa854, 0xa855, 0xa855, 0xa856, 0xa856, 
+    0xa857, 0xa857, 0xa857, 0xa858, 0xa858, 0xa859, 0xa859, 0xa859, 
+    0xa85a, 0xa85a, 0xa85b, 0xa85b, 0xa85b, 0xa85c, 0xa85c, 0xa85d, 
+    0xa85d, 0xa85d, 0xa85e, 0xa85e, 0xa85f, 0xa85f, 0xa860, 0xa860, 
+    0xa860, 0xa861, 0xa861, 0xa862, 0xa862, 0xa862, 0xa863, 0xa863, 
+    0xa864, 0xa864, 0xa864, 0xa865, 0xa865, 0xa866, 0xa866, 0xa866, 
+    0xa867, 0xa867, 0xa868, 0xa868, 0xa868, 0xa869, 0xa869, 0xa86a, 
+    0xa86a, 0xa86a, 0xa86b, 0xa86b, 0xa86c, 0xa86c, 0xa86d, 0xa86d, 
+    0xa86d, 0xa86e, 0xa86e, 0xa86f, 0xa86f, 0xa86f, 0xa870, 0xa870, 
+    0xa871, 0xa871, 0xa871, 0xa872, 0xa872, 0xa873, 0xa873, 0xa873, 
+    0xa874, 0xa874, 0xa875, 0xa875, 0xa875, 0xa876, 0xa876, 0xa877, 
+    0xa877, 0xa877, 0xa878, 0xa878, 0xa879, 0xa879, 0xa879, 0xa87a, 
+    0xa87a, 0xa87b, 0xa87b, 0xa87b, 0xa87c, 0xa87c, 0xa87c, 0xa87d, 
+    0xa87d, 0xa87e, 0xa87e, 0xa87e, 0xa87f, 0xa87f, 0xa880, 0xa880, 
+    0xa880, 0xa881, 0xa881, 0xa882, 0xa882, 0xa882, 0xa883, 0xa883, 
+    0xa884, 0xa884, 0xa884, 0xa885, 0xa885, 0xa886, 0xa886, 0xa886, 
+    0xa887, 0xa887, 0xa888, 0xa888, 0xa888, 0xa889, 0xa889, 0xa889, 
+    0xa88a, 0xa88a, 0xa88b, 0xa88b, 0xa88b, 0xa88c, 0xa88c, 0xa88d, 
+    0xa88d, 0xa88d, 0xa88e, 0xa88e, 0xa88f, 0xa88f, 0xa88f, 0xa890, 
+    0xa890, 0xa890, 0xa891, 0xa891, 0xa892, 0xa892, 0xa892, 0xa893, 
+    0xa893, 0xa894, 0xa894, 0xa894, 0xa895, 0xa895, 0xa896, 0xa896, 
+    0xa896, 0xa897, 0xa897, 0xa897, 0xa898, 0xa898, 0xa899, 0xa899, 
+    0xa899, 0xa89a, 0xa89a, 0xa89b, 0xa89b, 0xa89b, 0xa89c, 0xa89c, 
+    0xa89c, 0xa89d, 0xa89d, 0xa89e, 0xa89e, 0xa89e, 0xa89f, 0xa89f, 
+    0xa89f, 0xa8a0, 0xa8a0, 0xa8a1, 0xa8a1, 0xa8a1, 0xa8a2, 0xa8a2, 
+    0xa8a3, 0xa8a3, 0xa8a3, 0xa8a4, 0xa8a4, 0xa8a4, 0xa8a5, 0xa8a5, 
+    0xa8a6, 0xa8a6, 0xa8a6, 0xa8a7, 0xa8a7, 0xa8a7, 0xa8a8, 0xa8a8, 
+    0xa8a9, 0xa8a9, 0xa8a9, 0xa8aa, 0xa8aa, 0xa8ab, 0xa8ab, 0xa8ab, 
+    0xa8ac, 0xa8ac, 0xa8ac, 0xa8ad, 0xa8ad, 0xa8ae, 0xa8ae, 0xa8ae, 
+    0xa8af, 0xa8af, 0xa8af, 0xa8b0, 0xa8b0, 0xa8b1, 0xa8b1, 0xa8b1, 
+    0xa8b2, 0xa8b2, 0xa8b2, 0xa8b3, 0xa8b3, 0xa8b4, 0xa8b4, 0xa8b4, 
+    0xa8b5, 0xa8b5, 0xa8b5, 0xa8b6, 0xa8b6, 0xa8b7, 0xa8b7, 0xa8b7, 
+    0xa8b8, 0xa8b8, 0xa8b8, 0xa8b9, 0xa8b9, 0xa8ba, 0xa8ba, 0xa8ba, 
+    0xa8bb, 0xa8bb, 0xa8bb, 0xa8bc, 0xa8bc, 0xa8bc, 0xa8bd, 0xa8bd, 
+    0xa8be, 0xa8be, 0xa8be, 0xa8bf, 0xa8bf, 0xa8bf, 0xa8c0, 0xa8c0, 
+    0xa8c1, 0xa8c1, 0xa8c1, 0xa8c2, 0xa8c2, 0xa8c2, 0xa8c3, 0xa8c3, 
+    0xa8c4, 0xa8c4, 0xa8c4, 0xa8c5, 0xa8c5, 0xa8c5, 0xa8c6, 0xa8c6, 
+    0xa8c6, 0xa8c7, 0xa8c7, 0xa8c8, 0xa8c8, 0xa8c8, 0xa8c9, 0xa8c9, 
+    0xa8c9, 0xa8ca, 0xa8ca, 0xa8ca, 0xa8cb, 0xa8cb, 0xa8cc, 0xa8cc, 
+    0xa8cc, 0xa8cd, 0xa8cd, 0xa8cd, 0xa8ce, 0xa8ce, 0xa8cf, 0xa8cf, 
+    0xa8cf, 0xa8d0, 0xa8d0, 0xa8d0, 0xa8d1, 0xa8d1, 0xa8d1, 0xa8d2, 
+    0xa8d2, 0xa8d3, 0xa8d3, 0xa8d3, 0xa8d4, 0xa8d4, 0xa8d4, 0xa8d5, 
+    0xa8d5, 0xa8d5, 0xa8d6, 0xa8d6, 0xa8d6, 0xa8d7, 0xa8d7, 0xa8d8, 
+    0xa8d8, 0xa8d8, 0xa8d9, 0xa8d9, 0xa8d9, 0xa8da, 0xa8da, 0xa8da, 
+    0xa8db, 0xa8db, 0xa8dc, 0xa8dc, 0xa8dc, 0xa8dd, 0xa8dd, 0xa8dd, 
+    0xa8de, 0xa8de, 0xa8de, 0xa8df, 0xa8df, 0xa8e0, 0xa8e0, 0xa8e0, 
+    0xa8e1, 0xa8e1, 0xa8e1, 0xa8e2, 0xa8e2, 0xa8e2, 0xa8e3, 0xa8e3, 
+    0xa8e3, 0xa8e4, 0xa8e4, 0xa8e5, 0xa8e5, 0xa8e5, 0xa8e6, 0xa8e6, 
+    0xa8e6, 0xa8e7, 0xa8e7, 0xa8e7, 0xa8e8, 0xa8e8, 0xa8e8, 0xa8e9, 
+    0xa8e9, 0xa8e9, 0xa8ea, 0xa8ea, 0xa8eb, 0xa8eb, 0xa8eb, 0xa8ec, 
+    0xa8ec, 0xa8ec, 0xa8ed, 0xa8ed, 0xa8ed, 0xa8ee, 0xa8ee, 0xa8ee, 
+    0xa8ef, 0xa8ef, 0xa8f0, 0xa8f0, 0xa8f0, 0xa8f1, 0xa8f1, 0xa8f1, 
+    0xa8f2, 0xa8f2, 0xa8f2, 0xa8f3, 0xa8f3, 0xa8f3, 0xa8f4, 0xa8f4, 
+    0xa8f4, 0xa8f5, 0xa8f5, 0xa8f6, 0xa8f6, 0xa8f6, 0xa8f7, 0xa8f7, 
+    0xa8f7, 0xa8f8, 0xa8f8, 0xa8f8, 0xa8f9, 0xa8f9, 0xa8f9, 0xa8fa, 
+    0xa8fa, 0xa8fa, 0xa8fb, 0xa8fb, 0xa8fb, 0xa8fc, 0xa8fc, 0xa8fd, 
+    0xa8fd, 0xa8fd, 0xa8fe, 0xa8fe, 0xa8fe, 0xa8ff, 0xa8ff, 0xa8ff, 
+    0xa900, 0xa900, 0xa900, 0xa901, 0xa901, 0xa901, 0xa902, 0xa902, 
+    0xa902, 0xa903, 0xa903, 0xa903, 0xa904, 0xa904, 0xa905, 0xa905, 
+    0xa905, 0xa906, 0xa906, 0xa906, 0xa907, 0xa907, 0xa907, 0xa908, 
+    0xa908, 0xa908, 0xa909, 0xa909, 0xa909, 0xa90a, 0xa90a, 0xa90a, 
+    0xa90b, 0xa90b, 0xa90b, 0xa90c, 0xa90c, 0xa90c, 0xa90d, 0xa90d, 
+    0xa90d, 0xa90e, 0xa90e, 0xa90e, 0xa90f, 0xa90f, 0xa910, 0xa910, 
+    0xa910, 0xa911, 0xa911, 0xa911, 0xa912, 0xa912, 0xa912, 0xa913, 
+    0xa913, 0xa913, 0xa914, 0xa914, 0xa914, 0xa915, 0xa915, 0xa915, 
+    0xa916, 0xa916, 0xa916, 0xa917, 0xa917, 0xa917, 0xa918, 0xa918, 
+    0xa918, 0xa919, 0xa919, 0xa919, 0xa91a, 0xa91a, 0xa91a, 0xa91b, 
+    0xa91b, 0xa91b, 0xa91c, 0xa91c, 0xa91c, 0xa91d, 0xa91d, 0xa91d, 
+    0xa91e, 0xa91e, 0xa91f, 0xa91f, 0xa91f, 0xa920, 0xa920, 0xa920, 
+    0xa921, 0xa921, 0xa921, 0xa922, 0xa922, 0xa922, 0xa923, 0xa923, 
+    0xa923, 0xa924, 0xa924, 0xa924, 0xa925, 0xa925, 0xa925, 0xa926, 
+    0xa926, 0xa926, 0xa927, 0xa927, 0xa927, 0xa928, 0xa928, 0xa928, 
+    0xa929, 0xa929, 0xa929, 0xa92a, 0xa92a, 0xa92a, 0xa92b, 0xa92b, 
+    0xa92b, 0xa92c, 0xa92c, 0xa92c, 0xa92d, 0xa92d, 0xa92d, 0xa92e, 
+    0xa92e, 0xa92e, 0xa92f, 0xa92f, 0xa92f, 0xa930, 0xa930, 0xa930, 
+    0xa931, 0xa931, 0xa931, 0xa932, 0xa932, 0xa932, 0xa933, 0xa933, 
+    0xa933, 0xa934, 0xa934, 0xa934, 0xa935, 0xa935, 0xa935, 0xa936, 
+    0xa936, 0xa936, 0xa937, 0xa937, 0xa937, 0xa938, 0xa938, 0xa938, 
+    0xa939, 0xa939, 0xa939, 0xa93a, 0xa93a, 0xa93a, 0xa93b, 0xa93b, 
+    0xa93b, 0xa93c, 0xa93c, 0xa93c, 0xa93d, 0xa93d, 0xa93d, 0xa93e, 
+    0xa93e, 0xa93e, 0xa93e, 0xa93f, 0xa93f, 0xa93f, 0xa940, 0xa940, 
+    0xa940, 0xa941, 0xa941, 0xa941, 0xa942, 0xa942, 0xa942, 0xa943, 
+    0xa943, 0xa943, 0xa944, 0xa944, 0xa944, 0xa945, 0xa945, 0xa945, 
+    0xa946, 0xa946, 0xa946, 0xa947, 0xa947, 0xa947, 0xa948, 0xa948, 
+    0xa948, 0xa949, 0xa949, 0xa949, 0xa94a, 0xa94a, 0xa94a, 0xa94b, 
+    0xa94b, 0xa94b, 0xa94c, 0xa94c, 0xa94c, 0xa94d, 0xa94d, 0xa94d, 
+    0xa94d, 0xa94e, 0xa94e, 0xa94e, 0xa94f, 0xa94f, 0xa94f, 0xa950, 
+    0xa950, 0xa950, 0xa951, 0xa951, 0xa951, 0xa952, 0xa952, 0xa952, 
+    0xa953, 0xa953, 0xa953, 0xa954, 0xa954, 0xa954, 0xa955, 0xa955, 
+    0xa955, 0xa956, 0xa956, 0xa956, 0xa957, 0xa957, 0xa957, 0xa958, 
+    0xa958, 0xa958, 0xa958, 0xa959, 0xa959, 0xa959, 0xa95a, 0xa95a, 
+    0xa95a, 0xa95b, 0xa95b, 0xa95b, 0xa95c, 0xa95c, 0xa95c, 0xa95d, 
+    0xa95d, 0xa95d, 0xa95e, 0xa95e, 0xa95e, 0xa95f, 0xa95f, 0xa95f, 
+    0xa960, 0xa960, 0xa960, 0xa960, 0xa961, 0xa961, 0xa961, 0xa962, 
+    0xa962, 0xa962, 0xa963, 0xa963, 0xa963, 0xa964, 0xa964, 0xa964, 
+    0xa965, 0xa965, 0xa965, 0xa966, 0xa966, 0xa966, 0xa967, 0xa967, 
+    0xa967, 0xa967, 0xa968, 0xa968, 0xa968, 0xa969, 0xa969, 0xa969, 
+    0xa96a, 0xa96a, 0xa96a, 0xa96b, 0xa96b, 0xa96b, 0xa96c, 0xa96c, 
+    0xa96c, 0xa96d, 0xa96d, 0xa96d, 0xa96d, 0xa96e, 0xa96e, 0xa96e, 
+    0xa96f, 0xa96f, 0xa96f, 0xa970, 0xa970, 0xa970, 0xa971, 0xa971, 
+    0xa971, 0xa972, 0xa972, 0xa972, 0xa972, 0xa973, 0xa973, 0xa973, 
+    0xa974, 0xa974, 0xa974, 0xa975, 0xa975, 0xa975, 0xa976, 0xa976, 
+    0xa976, 0xa977, 0xa977, 0xa977, 0xa977, 0xa978, 0xa978, 0xa978, 
+    0xa979, 0xa979, 0xa979, 0xa97a, 0xa97a, 0xa97a, 0xa97b, 0xa97b, 
+    0xa97b, 0xa97c, 0xa97c, 0xa97d, 0xa97e, 0xa97e, 0xa97f, 0xa980, 
+    0xa980, 0xa981, 0xa981, 0xa982, 0xa983, 0xa983, 0xa984, 0xa985, 
+    0xa985, 0xa986, 0xa986, 0xa987, 0xa988, 0xa988, 0xa989, 0xa989, 
+    0xa98a, 0xa98b, 0xa98b, 0xa98c, 0xa98d, 0xa98d, 0xa98e, 0xa98e, 
+    0xa98f, 0xa990, 0xa990, 0xa991, 0xa991, 0xa992, 0xa993, 0xa993, 
+    0xa994, 0xa995, 0xa995, 0xa996, 0xa996, 0xa997, 0xa998, 0xa998, 
+    0xa999, 0xa999, 0xa99a, 0xa99b, 0xa99b, 0xa99c, 0xa99c, 0xa99d, 
+    0xa99e, 0xa99e, 0xa99f, 0xa99f, 0xa9a0, 0xa9a1, 0xa9a1, 0xa9a2, 
+    0xa9a2, 0xa9a3, 0xa9a4, 0xa9a4, 0xa9a5, 0xa9a5, 0xa9a6, 0xa9a7, 
+    0xa9a7, 0xa9a8, 0xa9a8, 0xa9a9, 0xa9aa, 0xa9aa, 0xa9ab, 0xa9ab, 
+    0xa9ac, 0xa9ad, 0xa9ad, 0xa9ae, 0xa9ae, 0xa9af, 0xa9b0, 0xa9b0, 
+    0xa9b1, 0xa9b1, 0xa9b2, 0xa9b3, 0xa9b3, 0xa9b4, 0xa9b4, 0xa9b5, 
+    0xa9b6, 0xa9b6, 0xa9b7, 0xa9b7, 0xa9b8, 0xa9b9, 0xa9b9, 0xa9ba, 
+    0xa9ba, 0xa9bb, 0xa9bb, 0xa9bc, 0xa9bd, 0xa9bd, 0xa9be, 0xa9be, 
+    0xa9bf, 0xa9c0, 0xa9c0, 0xa9c1, 0xa9c1, 0xa9c2, 0xa9c3, 0xa9c3, 
+    0xa9c4, 0xa9c4, 0xa9c5, 0xa9c5, 0xa9c6, 0xa9c7, 0xa9c7, 0xa9c8, 
+    0xa9c8, 0xa9c9, 0xa9ca, 0xa9ca, 0xa9cb, 0xa9cb, 0xa9cc, 0xa9cc, 
+    0xa9cd, 0xa9ce, 0xa9ce, 0xa9cf, 0xa9cf, 0xa9d0, 0xa9d1, 0xa9d1, 
+    0xa9d2, 0xa9d2, 0xa9d3, 0xa9d3, 0xa9d4, 0xa9d5, 0xa9d5, 0xa9d6, 
+    0xa9d6, 0xa9d7, 0xa9d8, 0xa9d8, 0xa9d9, 0xa9d9, 0xa9da, 0xa9da, 
+    0xa9db, 0xa9dc, 0xa9dc, 0xa9dd, 0xa9dd, 0xa9de, 0xa9de, 0xa9df, 
+    0xa9e0, 0xa9e0, 0xa9e1, 0xa9e1, 0xa9e2, 0xa9e2, 0xa9e3, 0xa9e4, 
+    0xa9e4, 0xa9e5, 0xa9e5, 0xa9e6, 0xa9e6, 0xa9e7, 0xa9e8, 0xa9e8, 
+    0xa9e9, 0xa9e9, 0xa9ea, 0xa9ea, 0xa9eb, 0xa9ec, 0xa9ec, 0xa9ed, 
+    0xa9ed, 0xa9ee, 0xa9ee, 0xa9ef, 0xa9f0, 0xa9f0, 0xa9f1, 0xa9f1, 
+    0xa9f2, 0xa9f2, 0xa9f3, 0xa9f3, 0xa9f4, 0xa9f5, 0xa9f5, 0xa9f6, 
+    0xa9f6, 0xa9f7, 0xa9f7, 0xa9f8, 0xa9f9, 0xa9f9, 0xa9fa, 0xa9fa, 
+    0xa9fb, 0xa9fb, 0xa9fc, 0xa9fc, 0xa9fd, 0xa9fe, 0xa9fe, 0xa9ff, 
+    0xa9ff, 0xaa00, 0xaa00, 0xaa01, 0xaa02, 0xaa02, 0xaa03, 0xaa03, 
+    0xaa04, 0xaa04, 0xaa05, 0xaa05, 0xaa06, 0xaa07, 0xaa07, 0xaa08, 
+    0xaa08, 0xaa09, 0xaa09, 0xaa0a, 0xaa0a, 0xaa0b, 0xaa0c, 0xaa0c, 
+    0xaa0d, 0xaa0d, 0xaa0e, 0xaa0e, 0xaa0f, 0xaa0f, 0xaa10, 0xaa10, 
+    0xaa11, 0xaa12, 0xaa12, 0xaa13, 0xaa13, 0xaa14, 0xaa14, 0xaa15, 
+    0xaa15, 0xaa16, 0xaa17, 0xaa17, 0xaa18, 0xaa18, 0xaa19, 0xaa19, 
+    0xaa1a, 0xaa1a, 0xaa1b, 0xaa1b, 0xaa1c, 0xaa1d, 0xaa1d, 0xaa1e, 
+    0xaa1e, 0xaa1f, 0xaa1f, 0xaa20, 0xaa20, 0xaa21, 0xaa21, 0xaa22, 
+    0xaa23, 0xaa23, 0xaa24, 0xaa24, 0xaa25, 0xaa25, 0xaa26, 0xaa26, 
+    0xaa27, 0xaa27, 0xaa28, 0xaa29, 0xaa29, 0xaa2a, 0xaa2a, 0xaa2b, 
+    0xaa2b, 0xaa2c, 0xaa2c, 0xaa2d, 0xaa2d, 0xaa2e, 0xaa2e, 0xaa2f, 
+    0xaa30, 0xaa30, 0xaa31, 0xaa31, 0xaa32, 0xaa32, 0xaa33, 0xaa33, 
+    0xaa34, 0xaa34, 0xaa35, 0xaa35, 0xaa36, 0xaa37, 0xaa37, 0xaa38, 
+    0xaa38, 0xaa39, 0xaa39, 0xaa3a, 0xaa3a, 0xaa3b, 0xaa3b, 0xaa3c, 
+    0xaa3c, 0xaa3d, 0xaa3d, 0xaa3e, 0xaa3f, 0xaa3f, 0xaa40, 0xaa40, 
+    0xaa41, 0xaa41, 0xaa42, 0xaa42, 0xaa43, 0xaa43, 0xaa44, 0xaa44, 
+    0xaa45, 0xaa45, 0xaa46, 0xaa47, 0xaa47, 0xaa48, 0xaa48, 0xaa49, 
+    0xaa49, 0xaa4a, 0xaa4a, 0xaa4b, 0xaa4b, 0xaa4c, 0xaa4c, 0xaa4d, 
+    0xaa4d, 0xaa4e, 0xaa4e, 0xaa4f, 0xaa50, 0xaa50, 0xaa51, 0xaa51, 
+    0xaa52, 0xaa52, 0xaa53, 0xaa53, 0xaa54, 0xaa54, 0xaa55, 0xaa55, 
+    0xaa56, 0xaa56, 0xaa57, 0xaa57, 0xaa58, 0xaa58, 0xaa59, 0xaa59, 
+    0xaa5a, 0xaa5b, 0xaa5b, 0xaa5c, 0xaa5c, 0xaa5d, 0xaa5d, 0xaa5e, 
+    0xaa5e, 0xaa5f, 0xaa5f, 0xaa60, 0xaa60, 0xaa61, 0xaa61, 0xaa62, 
+    0xaa62, 0xaa63, 0xaa63, 0xaa64, 0xaa64, 0xaa65, 0xaa65, 0xaa66, 
+    0xaa66, 0xaa67, 0xaa67, 0xaa68, 0xaa69, 0xaa69, 0xaa6a, 0xaa6a, 
+    0xaa6b, 0xaa6b, 0xaa6c, 0xaa6c, 0xaa6d, 0xaa6d, 0xaa6e, 0xaa6e, 
+    0xaa6f, 0xaa6f, 0xaa70, 0xaa70, 0xaa71, 0xaa71, 0xaa72, 0xaa72, 
+    0xaa73, 0xaa73, 0xaa74, 0xaa74, 0xaa75, 0xaa75, 0xaa76, 0xaa76, 
+    0xaa77, 0xaa77, 0xaa78, 0xaa78, 0xaa79, 0xaa79, 0xaa7a, 0xaa7a, 
+    0xaa7b, 0xaa7b, 0xaa7c, 0xaa7d, 0xaa7d, 0xaa7e, 0xaa7e, 0xaa7f, 
+    0xaa7f, 0xaa80, 0xaa80, 0xaa81, 0xaa81, 0xaa82, 0xaa82, 0xaa83, 
+    0xaa83, 0xaa84, 0xaa84, 0xaa85, 0xaa85, 0xaa86, 0xaa86, 0xaa87, 
+    0xaa87, 0xaa88, 0xaa88, 0xaa89, 0xaa89, 0xaa8a, 0xaa8a, 0xaa8b, 
+    0xaa8b, 0xaa8c, 0xaa8c, 0xaa8d, 0xaa8d, 0xaa8e, 0xaa8e, 0xaa8f, 
+    0xaa8f, 0xaa90, 0xaa90, 0xaa91, 0xaa91, 0xaa92, 0xaa92, 0xaa93, 
+    0xaa93, 0xaa94, 0xaa94, 0xaa95, 0xaa95, 0xaa96, 0xaa96, 0xaa97, 
+    0xaa97, 0xaa98, 0xaa98, 0xaa99, 0xaa99, 0xaa9a, 0xaa9a, 0xaa9b, 
+    0xaa9b, 0xaa9c, 0xaa9c, 0xaa9d, 0xaa9d, 0xaa9e, 0xaa9e, 0xaa9f, 
+    0xaa9f, 0xaaa0, 0xaaa0, 0xaaa1, 0xaaa1, 0xaaa2, 0xaaa2, 0xaaa3, 
+    0xaaa3, 0xaaa4, 0xaaa4, 0xaaa5, 0xaaa5, 0xaaa6, 0xaaa6, 0xaaa7, 
+    0xaaa7, 0xaaa8, 0xaaa8, 0xaaa9, 0xaaa9, 0xaaaa, 0xaaaa, 0xaaab, 
+    0xaaab, 0xaaac, 0xaaac, 0xaaad, 0xaaad, 0xaaae, 0xaaae, 0xaaaf, 
+    0xaaaf, 0xaaaf, 0xaab0, 0xaab0, 0xaab1, 0xaab1, 0xaab2, 0xaab2, 
+    0xaab3, 0xaab3, 0xaab4, 0xaab4, 0xaab5, 0xaab5, 0xaab6, 0xaab6, 
+    0xaab7, 0xaab7, 0xaab8, 0xaab8, 0xaab9, 0xaab9, 0xaaba, 0xaaba, 
+    0xaabb, 0xaabb, 0xaabc, 0xaabc, 0xaabd, 0xaabd, 0xaabe, 0xaabe, 
+    0xaabf, 0xaabf, 0xaac0, 0xaac0, 0xaac1, 0xaac1, 0xaac2, 0xaac2, 
+    0xaac2, 0xaac3, 0xaac3, 0xaac4, 0xaac4, 0xaac5, 0xaac5, 0xaac6, 
+    0xaac6, 0xaac7, 0xaac7, 0xaac8, 0xaac8, 0xaac9, 0xaac9, 0xaaca, 
+    0xaaca, 0xaacb, 0xaacb, 0xaacc, 0xaacc, 0xaacd, 0xaacd, 0xaace, 
+    0xaace, 0xaacf, 0xaacf, 0xaad0, 0xaad0, 0xaad0, 0xaad1, 0xaad1, 
+    0xaad2, 0xaad2, 0xaad3, 0xaad3, 0xaad4, 0xaad4, 0xaad5, 0xaad5, 
+    0xaad6, 0xaad6, 0xaad7, 0xaad7, 0xaad8, 0xaad8, 0xaad9, 0xaad9, 
+    0xaada, 0xaada, 0xaadb, 0xaadb, 0xaadb, 0xaadc, 0xaadc, 0xaadd, 
+    0xaadd, 0xaade, 0xaade, 0xaadf, 0xaadf, 0xaae0, 0xaae0, 0xaae1, 
+    0xaae1, 0xaae2, 0xaae2, 0xaae3, 0xaae3, 0xaae4, 0xaae4, 0xaae4, 
+    0xaae5, 0xaae5, 0xaae6, 0xaae6, 0xaae7, 0xaae7, 0xaae8, 0xaae8, 
+    0xaae9, 0xaae9, 0xaaea, 0xaaea, 0xaaeb, 0xaaeb, 0xaaec, 0xaaec, 
+    0xaaed, 0xaaed, 0xaaed, 0xaaee, 0xaaee, 0xaaef, 0xaaef, 0xaaf0, 
+    0xaaf0, 0xaaf1, 0xaaf1, 0xaaf2, 0xaaf2, 0xaaf3, 0xaaf3, 0xaaf4, 
+    0xaaf4, 0xaaf4, 0xaaf5, 0xaaf5, 0xaaf6, 0xaaf6, 0xaaf7, 0xaaf7, 
+    0xaaf8, 0xaaf8, 0xaaf9, 0xaaf9, 0xaafa, 0xaafa, 0xaafb, 0xaafb, 
+    0xaafb, 0xaafc, 0xaafc, 0xaafd, 0xaafd, 0xaafe, 0xaafe, 0xaaff, 
+    0xaaff, 0xab00, 0xab00, 0xab01, 0xab01, 0xab02, 0xab02, 0xab02, 
+    0xab03, 0xab03, 0xab04, 0xab04, 0xab05, 0xab05, 0xab06, 0xab06, 
+    0xab07, 0xab07, 0xab08, 0xab08, 0xab08, 0xab09, 0xab09, 0xab0a, 
+    0xab0a, 0xab0b, 0xab0b, 0xab0c, 0xab0c, 0xab0d, 0xab0d, 0xab0e, 
+    0xab0e, 0xab0e, 0xab0f, 0xab0f, 0xab10, 0xab10, 0xab11, 0xab11, 
+    0xab12, 0xab12, 0xab13, 0xab13, 0xab14, 0xab14, 0xab14, 0xab15, 
+    0xab15, 0xab16, 0xab16, 0xab17, 0xab17, 0xab18, 0xab18, 0xab19, 
+    0xab19, 0xab19, 0xab1a, 0xab1a, 0xab1b, 0xab1b, 0xab1c, 0xab1c, 
+    0xab1d, 0xab1d, 0xab1e, 0xab1e, 0xab1e, 0xab1f, 0xab1f, 0xab20, 
+    0xab20, 0xab21, 0xab21, 0xab22, 0xab22, 0xab23, 0xab23, 0xab23, 
+    0xab24, 0xab24, 0xab25, 0xab25, 0xab26, 0xab26, 0xab27, 0xab27, 
+    0xab28, 0xab28, 0xab28, 0xab29, 0xab29, 0xab2a, 0xab2a, 0xab2b, 
+    0xab2b, 0xab2c, 0xab2c, 0xab2d, 0xab2d, 0xab2d, 0xab2e, 0xab2e, 
+    0xab2f, 0xab2f, 0xab30, 0xab30, 0xab31, 0xab31, 0xab31, 0xab32, 
+    0xab32, 0xab33, 0xab33, 0xab34, 0xab34, 0xab35, 0xab35, 0xab36, 
+    0xab36, 0xab36, 0xab37, 0xab37, 0xab38, 0xab38, 0xab39, 0xab39, 
+    0xab3a, 0xab3a, 0xab3a, 0xab3b, 0xab3b, 0xab3c, 0xab3c, 0xab3d, 
+    0xab3d, 0xab3e, 0xab3e, 0xab3e, 0xab3f, 0xab3f, 0xab40, 0xab40, 
+    0xab41, 0xab41, 0xab42, 0xab42, 0xab42, 0xab43, 0xab43, 0xab44, 
+    0xab44, 0xab45, 0xab45, 0xab46, 0xab46, 0xab46, 0xab47, 0xab47, 
+    0xab48, 0xab48, 0xab49, 0xab49, 0xab4a, 0xab4a, 0xab4a, 0xab4b, 
+    0xab4b, 0xab4c, 0xab4c, 0xab4d, 0xab4d, 0xab4e, 0xab4e, 0xab4e, 
+    0xab4f, 0xab4f, 0xab50, 0xab50, 0xab51, 0xab51, 0xab52, 0xab52, 
+    0xab52, 0xab53, 0xab53, 0xab54, 0xab54, 0xab55, 0xab55, 0xab55, 
+    0xab56, 0xab56, 0xab57, 0xab57, 0xab58, 0xab58, 0xab59, 0xab59, 
+    0xab59, 0xab5a, 0xab5a, 0xab5b, 0xab5b, 0xab5c, 0xab5c, 0xab5c, 
+    0xab5d, 0xab5d, 0xab5e, 0xab5e, 0xab5f, 0xab5f, 0xab60, 0xab60, 
+    0xab60, 0xab61, 0xab61, 0xab62, 0xab62, 0xab63, 0xab63, 0xab63, 
+    0xab64, 0xab64, 0xab65, 0xab65, 0xab66, 0xab66, 0xab67, 0xab67, 
+    0xab67, 0xab68, 0xab68, 0xab69, 0xab69, 0xab6a, 0xab6a, 0xab6a, 
+    0xab6b, 0xab6b, 0xab6c, 0xab6c, 0xab6d, 0xab6d, 0xab6d, 0xab6e, 
+    0xab6e, 0xab6f, 0xab6f, 0xab70, 0xab70, 0xab70, 0xab71, 0xab71, 
+    0xab72, 0xab72, 0xab73, 0xab73, 0xab73, 0xab74, 0xab74, 0xab75, 
+    0xab75, 0xab76, 0xab76, 0xab77, 0xab77, 0xab77, 0xab78, 0xab78, 
+    0xab79, 0xab79, 0xab7a, 0xab7a, 0xab7a, 0xab7b, 0xab7b, 0xab7c, 
+    0xab7c, 0xab7d, 0xab7d, 0xab7d, 0xab7e, 0xab7e, 0xab7f, 0xab7f, 
+    0xab80, 0xab80, 0xab80, 0xab81, 0xab81, 0xab82, 0xab82, 0xab83, 
+    0xab83, 0xab84, 0xab85, 0xab85, 0xab86, 0xab87, 0xab88, 0xab89, 
+    0xab8a, 0xab8b, 0xab8b, 0xab8c, 0xab8d, 0xab8e, 0xab8f, 0xab90, 
+    0xab91, 0xab91, 0xab92, 0xab93, 0xab94, 0xab95, 0xab96, 0xab96, 
+    0xab97, 0xab98, 0xab99, 0xab9a, 0xab9b, 0xab9b, 0xab9c, 0xab9d, 
+    0xab9e, 0xab9f, 0xaba0, 0xaba1, 0xaba1, 0xaba2, 0xaba3, 0xaba4, 
+    0xaba5, 0xaba6, 0xaba6, 0xaba7, 0xaba8, 0xaba9, 0xabaa, 0xabab, 
+    0xabab, 0xabac, 0xabad, 0xabae, 0xabaf, 0xabb0, 0xabb0, 0xabb1, 
+    0xabb2, 0xabb3, 0xabb4, 0xabb5, 0xabb5, 0xabb6, 0xabb7, 0xabb8, 
+    0xabb9, 0xabb9, 0xabba, 0xabbb, 0xabbc, 0xabbd, 0xabbe, 0xabbe, 
+    0xabbf, 0xabc0, 0xabc1, 0xabc2, 0xabc3, 0xabc3, 0xabc4, 0xabc5, 
+    0xabc6, 0xabc7, 0xabc7, 0xabc8, 0xabc9, 0xabca, 0xabcb, 0xabcc, 
+    0xabcc, 0xabcd, 0xabce, 0xabcf, 0xabd0, 0xabd0, 0xabd1, 0xabd2, 
+    0xabd3, 0xabd4, 0xabd4, 0xabd5, 0xabd6, 0xabd7, 0xabd8, 0xabd9, 
+    0xabd9, 0xabda, 0xabdb, 0xabdc, 0xabdd, 0xabdd, 0xabde, 0xabdf, 
+    0xabe0, 0xabe1, 0xabe1, 0xabe2, 0xabe3, 0xabe4, 0xabe5, 0xabe5, 
+    0xabe6, 0xabe7, 0xabe8, 0xabe9, 0xabe9, 0xabea, 0xabeb, 0xabec, 
+    0xabed, 0xabed, 0xabee, 0xabef, 0xabf0, 0xabf1, 0xabf1, 0xabf2, 
+    0xabf3, 0xabf4, 0xabf5, 0xabf5, 0xabf6, 0xabf7, 0xabf8, 0xabf9, 
+    0xabf9, 0xabfa, 0xabfb, 0xabfc, 0xabfd, 0xabfd, 0xabfe, 0xabff, 
+    0xac00, 0xac00, 0xac01, 0xac01, 0xac01, 0xac02, 0xac02, 0xac03, 
+    0xac03, 0xac03, 0xac04, 0xac04, 0xac05, 0xac05, 0xac05, 0xac06, 
+    0xac06, 0xac07, 0xac07, 0xac07, 0xac08, 0xac08, 0xac09, 0xac09, 
+    0xac09, 0xac0a, 0xac0a, 0xac0b, 0xac0b, 0xac0b, 0xac0c, 0xac0c, 
+    0xac0c, 0xac0d, 0xac0d, 0xac0e, 0xac0e, 0xac0e, 0xac0f, 0xac0f, 
+    0xac10, 0xac10, 0xac10, 0xac11, 0xac11, 0xac12, 0xac12, 0xac12, 
+    0xac13, 0xac13, 0xac13, 0xac14, 0xac14, 0xac15, 0xac15, 0xac15, 
+    0xac16, 0xac16, 0xac17, 0xac17, 0xac17, 0xac18, 0xac18, 0xac18, 
+    0xac19, 0xac19, 0xac1a, 0xac1a, 0xac1a, 0xac1b, 0xac1b, 0xac1c, 
+    0xac1c, 0xac1c, 0xac1d, 0xac1d, 0xac1d, 0xac1e, 0xac1e, 0xac1f, 
+    0xac1f, 0xac1f, 0xac20, 0xac20, 0xac21, 0xac21, 0xac21, 0xac22, 
+    0xac22, 0xac22, 0xac23, 0xac23, 0xac24, 0xac24, 0xac24, 0xac25, 
+    0xac25, 0xac25, 0xac26, 0xac26, 0xac27, 0xac27, 0xac27, 0xac28, 
+    0xac28, 0xac28, 0xac29, 0xac29, 0xac2a, 0xac2a, 0xac2a, 0xac2b, 
+    0xac2b, 0xac2b, 0xac2c, 0xac2c, 0xac2d, 0xac2d, 0xac2d, 0xac2e, 
+    0xac2e, 0xac2f, 0xac2f, 0xac2f, 0xac30, 0xac30, 0xac30, 0xac31, 
+    0xac31, 0xac32, 0xac32, 0xac32, 0xac33, 0xac33, 0xac33, 0xac34, 
+    0xac34, 0xac34, 0xac35, 0xac35, 0xac36, 0xac36, 0xac36, 0xac37, 
+    0xac37, 0xac37, 0xac38, 0xac38, 0xac39, 0xac39, 0xac39, 0xac3a, 
+    0xac3a, 0xac3a, 0xac3b, 0xac3b, 0xac3c, 0xac3c, 0xac3c, 0xac3d, 
+    0xac3d, 0xac3d, 0xac3e, 0xac3e, 0xac3e, 0xac3f, 0xac3f, 0xac40, 
+    0xac40, 0xac40, 0xac41, 0xac41, 0xac41, 0xac42, 0xac42, 0xac43, 
+    0xac43, 0xac43, 0xac44, 0xac44, 0xac44, 0xac45, 0xac45, 0xac45, 
+    0xac46, 0xac46, 0xac47, 0xac47, 0xac47, 0xac48, 0xac48, 0xac48, 
+    0xac49, 0xac49, 0xac49, 0xac4a, 0xac4a, 0xac4b, 0xac4b, 0xac4b, 
+    0xac4c, 0xac4c, 0xac4c, 0xac4d, 0xac4d, 0xac4d, 0xac4e, 0xac4e, 
+    0xac4f, 0xac4f, 0xac4f, 0xac50, 0xac50, 0xac50, 0xac51, 0xac51, 
+    0xac51, 0xac52, 0xac52, 0xac53, 0xac53, 0xac53, 0xac54, 0xac54, 
+    0xac54, 0xac55, 0xac55, 0xac55, 0xac56, 0xac56, 0xac56, 0xac57, 
+    0xac57, 0xac58, 0xac58, 0xac58, 0xac59, 0xac59, 0xac59, 0xac5a, 
+    0xac5a, 0xac5a, 0xac5b, 0xac5b, 0xac5c, 0xac5c, 0xac5c, 0xac5d, 
+    0xac5d, 0xac5d, 0xac5e, 0xac5e, 0xac5e, 0xac5f, 0xac5f, 0xac5f, 
+    0xac60, 0xac60, 0xac60, 0xac61, 0xac61, 0xac62, 0xac62, 0xac62, 
+    0xac63, 0xac63, 0xac63, 0xac64, 0xac64, 0xac64, 0xac65, 0xac65, 
+    0xac65, 0xac66, 0xac66, 0xac67, 0xac67, 0xac67, 0xac68, 0xac68, 
+    0xac68, 0xac69, 0xac69, 0xac69, 0xac6a, 0xac6a, 0xac6a, 0xac6b, 
+    0xac6b, 0xac6b, 0xac6c, 0xac6c, 0xac6c, 0xac6d, 0xac6d, 0xac6e, 
+    0xac6e, 0xac6e, 0xac6f, 0xac6f, 0xac6f, 0xac70, 0xac70, 0xac70, 
+    0xac71, 0xac71, 0xac71, 0xac72, 0xac72, 0xac72, 0xac73, 0xac73, 
+    0xac73, 0xac74, 0xac74, 0xac75, 0xac75, 0xac75, 0xac76, 0xac76, 
+    0xac76, 0xac77, 0xac77, 0xac77, 0xac78, 0xac78, 0xac78, 0xac79, 
+    0xac79, 0xac79, 0xac7a, 0xac7a, 0xac7a, 0xac7b, 0xac7b, 0xac7b, 
+    0xac7c, 0xac7c, 0xac7c, 0xac7d, 0xac7d, 0xac7e, 0xac7e, 0xac7e, 
+    0xac7f, 0xac7f, 0xac7f, 0xac80, 0xac80, 0xac80, 0xac81, 0xac81, 
+    0xac81, 0xac82, 0xac82, 0xac82, 0xac83, 0xac83, 0xac83, 0xac84, 
+    0xac84, 0xac84, 0xac85, 0xac85, 0xac85, 0xac86, 0xac86, 0xac86, 
+    0xac87, 0xac87, 0xac87, 0xac88, 0xac88, 0xac88, 0xac89, 0xac89, 
+    0xac8a, 0xac8a, 0xac8a, 0xac8b, 0xac8b, 0xac8b, 0xac8c, 0xac8c, 
+    0xac8c, 0xac8d, 0xac8d, 0xac8d, 0xac8e, 0xac8e, 0xac8e, 0xac8f, 
+    0xac8f, 0xac8f, 0xac90, 0xac90, 0xac90, 0xac91, 0xac91, 0xac91, 
+    0xac92, 0xac92, 0xac92, 0xac93, 0xac93, 0xac93, 0xac94, 0xac94, 
+    0xac94, 0xac95, 0xac95, 0xac95, 0xac96, 0xac96, 0xac96, 0xac97, 
+    0xac97, 0xac97, 0xac98, 0xac98, 0xac98, 0xac99, 0xac99, 0xac99, 
+    0xac9a, 0xac9a, 0xac9a, 0xac9b, 0xac9b, 0xac9b, 0xac9c, 0xac9c, 
+    0xac9c, 0xac9d, 0xac9d, 0xac9d, 0xac9e, 0xac9e, 0xac9e, 0xac9f, 
+    0xac9f, 0xac9f, 0xaca0, 0xaca0, 0xaca0, 0xaca1, 0xaca1, 0xaca1, 
+    0xaca2, 0xaca2, 0xaca2, 0xaca3, 0xaca3, 0xaca3, 0xaca4, 0xaca4, 
+    0xaca4, 0xaca5, 0xaca5, 0xaca5, 0xaca6, 0xaca6, 0xaca6, 0xaca7, 
+    0xaca7, 0xaca7, 0xaca8, 0xaca8, 0xaca8, 0xaca9, 0xaca9, 0xaca9, 
+    0xacaa, 0xacaa, 0xacaa, 0xacab, 0xacab, 0xacab, 0xacac, 0xacac, 
+    0xacac, 0xacad, 0xacad, 0xacad, 0xacae, 0xacae, 0xacae, 0xacaf, 
+    0xacaf, 0xacaf, 0xacb0, 0xacb0, 0xacb0, 0xacb1, 0xacb1, 0xacb1, 
+    0xacb1, 0xacb2, 0xacb2, 0xacb2, 0xacb3, 0xacb3, 0xacb3, 0xacb4, 
+    0xacb4, 0xacb4, 0xacb5, 0xacb5, 0xacb5, 0xacb6, 0xacb6, 0xacb6, 
+    0xacb7, 0xacb7, 0xacb7, 0xacb8, 0xacb8, 0xacb8, 0xacb9, 0xacb9, 
+    0xacb9, 0xacba, 0xacba, 0xacba, 0xacbb, 0xacbb, 0xacbb, 0xacbc, 
+    0xacbc, 0xacbc, 0xacbd, 0xacbd, 0xacbd, 0xacbe, 0xacbe, 0xacbe, 
+    0xacbe, 0xacbf, 0xacbf, 0xacbf, 0xacc0, 0xacc0, 0xacc0, 0xacc1, 
+    0xacc1, 0xacc1, 0xacc2, 0xacc2, 0xacc2, 0xacc3, 0xacc3, 0xacc3, 
+    0xacc4, 0xacc4, 0xacc4, 0xacc5, 0xacc5, 0xacc5, 0xacc6, 0xacc6, 
+    0xacc6, 0xacc7, 0xacc7, 0xacc7, 0xacc7, 0xacc8, 0xacc8, 0xacc8, 
+    0xacc9, 0xacc9, 0xacc9, 0xacca, 0xacca, 0xacca, 0xaccb, 0xaccb, 
+    0xaccb, 0xaccc, 0xaccc, 0xaccc, 0xaccd, 0xaccd, 0xaccd, 0xacce, 
+    0xacce, 0xacce, 0xacce, 0xaccf, 0xaccf, 0xaccf, 0xacd0, 0xacd0, 
+    0xacd0, 0xacd1, 0xacd1, 0xacd1, 0xacd2, 0xacd2, 0xacd2, 0xacd3, 
+    0xacd3, 0xacd3, 0xacd4, 0xacd4, 0xacd4, 0xacd4, 0xacd5, 0xacd5, 
+    0xacd5, 0xacd6, 0xacd6, 0xacd6, 0xacd7, 0xacd7, 0xacd7, 0xacd8, 
+    0xacd8, 0xacd8, 0xacd9, 0xacd9, 0xacd9, 0xacda, 0xacda, 0xacda, 
+    0xacda, 0xacdb, 0xacdb, 0xacdb, 0xacdc, 0xacdc, 0xacdc, 0xacdd, 
+    0xacdd, 0xacdd, 0xacde, 0xacde, 0xacde, 0xacdf, 0xacdf, 0xacdf, 
+    0xacdf, 0xace0, 0xace0, 0xace0, 0xace1, 0xace1, 0xace1, 0xace2, 
+    0xace2, 0xace2, 0xace3, 0xace3, 0xace3, 0xace4, 0xace4, 0xace4, 
+    0xace4, 0xace5, 0xace5, 0xace5, 0xace6, 0xace6, 0xace6, 0xace7, 
+    0xace7, 0xace7, 0xace8, 0xace8, 0xace8, 0xace8, 0xace9, 0xace9, 
+    0xace9, 0xacea, 0xacea, 0xacea, 0xaceb, 0xaceb, 0xaceb, 0xacec, 
+    0xacec, 0xacec, 0xaced, 0xaced, 0xaced, 0xaced, 0xacee, 0xacee, 
+    0xacee, 0xacef, 0xacef, 0xacef, 0xacf0, 0xacf0, 0xacf0, 0xacf1, 
+    0xacf1, 0xacf1, 0xacf1, 0xacf2, 0xacf2, 0xacf2, 0xacf3, 0xacf3, 
+    0xacf3, 0xacf4, 0xacf4, 0xacf4, 0xacf4, 0xacf5, 0xacf5, 0xacf5, 
+    0xacf6, 0xacf6, 0xacf6, 0xacf7, 0xacf7, 0xacf7, 0xacf8, 0xacf8, 
+    0xacf8, 0xacf8, 0xacf9, 0xacf9, 0xacf9, 0xacfa, 0xacfa, 0xacfa, 
+    0xacfb, 0xacfb, 0xacfb, 0xacfc, 0xacfc, 0xacfc, 0xacfc, 0xacfd, 
+    0xacfd, 0xacfd, 0xacfe, 0xacfe, 0xacfe, 0xacff, 0xacff, 0xacff, 
+    0xacff, 0xad00, 0xad00, 0xad00, 0xad01, 0xad01, 0xad01, 0xad02, 
+    0xad02, 0xad02, 0xad02, 0xad03, 0xad03, 0xad03, 0xad04, 0xad04, 
+    0xad04, 0xad05, 0xad05, 0xad05, 0xad05, 0xad06, 0xad06, 0xad06, 
+    0xad07, 0xad07, 0xad07, 0xad08, 0xad08, 0xad08, 0xad09, 0xad09, 
+    0xad09, 0xad09, 0xad0a, 0xad0a, 0xad0a, 0xad0b, 0xad0b, 0xad0b, 
+    0xad0c, 0xad0c, 0xad0c, 0xad0c, 0xad0d, 0xad0d, 0xad0d, 0xad0e, 
+    0xad0e, 0xad0e, 0xad0e, 0xad0f, 0xad0f, 0xad0f, 0xad10, 0xad10, 
+    0xad10, 0xad11, 0xad11, 0xad11, 0xad11, 0xad12, 0xad12, 0xad12, 
+    0xad13, 0xad13, 0xad13, 0xad14, 0xad14, 0xad14, 0xad14, 0xad15, 
+    0xad15, 0xad15, 0xad16, 0xad16, 0xad16, 0xad17, 0xad17, 0xad17, 
+    0xad17, 0xad18, 0xad18, 0xad18, 0xad19, 0xad19, 0xad19, 0xad19, 
+    0xad1a, 0xad1a, 0xad1a, 0xad1b, 0xad1b, 0xad1b, 0xad1c, 0xad1c, 
+    0xad1c, 0xad1c, 0xad1d, 0xad1d, 0xad1d, 0xad1e, 0xad1e, 0xad1e, 
+    0xad1f, 0xad1f, 0xad1f, 0xad1f, 0xad20, 0xad20, 0xad20, 0xad21, 
+    0xad21, 0xad21, 0xad21, 0xad22, 0xad22, 0xad22, 0xad23, 0xad23, 
+    0xad23, 0xad23, 0xad24, 0xad24, 0xad24, 0xad25, 0xad25, 0xad25, 
+    0xad26, 0xad26, 0xad27, 0xad27, 0xad28, 0xad28, 0xad29, 0xad2a, 
+    0xad2a, 0xad2b, 0xad2b, 0xad2c, 0xad2d, 0xad2d, 0xad2e, 0xad2e, 
+    0xad2f, 0xad2f, 0xad30, 0xad31, 0xad31, 0xad32, 0xad32, 0xad33, 
+    0xad33, 0xad34, 0xad35, 0xad35, 0xad36, 0xad36, 0xad37, 0xad38, 
+    0xad38, 0xad39, 0xad39, 0xad3a, 0xad3a, 0xad3b, 0xad3c, 0xad3c, 
+    0xad3d, 0xad3d, 0xad3e, 0xad3e, 0xad3f, 0xad40, 0xad40, 0xad41, 
+    0xad41, 0xad42, 0xad42, 0xad43, 0xad44, 0xad44, 0xad45, 0xad45, 
+    0xad46, 0xad46, 0xad47, 0xad48, 0xad48, 0xad49, 0xad49, 0xad4a, 
+    0xad4a, 0xad4b, 0xad4b, 0xad4c, 0xad4d, 0xad4d, 0xad4e, 0xad4e, 
+    0xad4f, 0xad4f, 0xad50, 0xad51, 0xad51, 0xad52, 0xad52, 0xad53, 
+    0xad53, 0xad54, 0xad54, 0xad55, 0xad56, 0xad56, 0xad57, 0xad57, 
+    0xad58, 0xad58, 0xad59, 0xad5a, 0xad5a, 0xad5b, 0xad5b, 0xad5c, 
+    0xad5c, 0xad5d, 0xad5d, 0xad5e, 0xad5f, 0xad5f, 0xad60, 0xad60, 
+    0xad61, 0xad61, 0xad62, 0xad62, 0xad63, 0xad64, 0xad64, 0xad65, 
+    0xad65, 0xad66, 0xad66, 0xad67, 0xad67, 0xad68, 0xad69, 0xad69, 
+    0xad6a, 0xad6a, 0xad6b, 0xad6b, 0xad6c, 0xad6c, 0xad6d, 0xad6d, 
+    0xad6e, 0xad6f, 0xad6f, 0xad70, 0xad70, 0xad71, 0xad71, 0xad72, 
+    0xad72, 0xad73, 0xad73, 0xad74, 0xad75, 0xad75, 0xad76, 0xad76, 
+    0xad77, 0xad77, 0xad78, 0xad78, 0xad79, 0xad79, 0xad7a, 0xad7b, 
+    0xad7b, 0xad7c, 0xad7c, 0xad7d, 0xad7d, 0xad7e, 0xad7e, 0xad7f, 
+    0xad7f, 0xad80, 0xad81, 0xad81, 0xad82, 0xad82, 0xad83, 0xad83, 
+    0xad84, 0xad84, 0xad85, 0xad85, 0xad86, 0xad86, 0xad87, 0xad88, 
+    0xad88, 0xad89, 0xad89, 0xad8a, 0xad8a, 0xad8b, 0xad8b, 0xad8c, 
+    0xad8c, 0xad8d, 0xad8d, 0xad8e, 0xad8e, 0xad8f, 0xad90, 0xad90, 
+    0xad91, 0xad91, 0xad92, 0xad92, 0xad93, 0xad93, 0xad94, 0xad94, 
+    0xad95, 0xad95, 0xad96, 0xad96, 0xad97, 0xad97, 0xad98, 0xad99, 
+    0xad99, 0xad9a, 0xad9a, 0xad9b, 0xad9b, 0xad9c, 0xad9c, 0xad9d, 
+    0xad9d, 0xad9e, 0xad9e, 0xad9f, 0xad9f, 0xada0, 0xada0, 0xada1, 
+    0xada2, 0xada2, 0xada3, 0xada3, 0xada4, 0xada4, 0xada5, 0xada5, 
+    0xada6, 0xada6, 0xada7, 0xada7, 0xada8, 0xada8, 0xada9, 0xada9, 
+    0xadaa, 0xadaa, 0xadab, 0xadab, 0xadac, 0xadac, 0xadad, 0xadae, 
+    0xadae, 0xadaf, 0xadaf, 0xadb0, 0xadb0, 0xadb1, 0xadb1, 0xadb2, 
+    0xadb2, 0xadb3, 0xadb3, 0xadb4, 0xadb4, 0xadb5, 0xadb5, 0xadb6, 
+    0xadb6, 0xadb7, 0xadb7, 0xadb8, 0xadb8, 0xadb9, 0xadb9, 0xadba, 
+    0xadba, 0xadbb, 0xadbb, 0xadbc, 0xadbd, 0xadbd, 0xadbe, 0xadbe, 
+    0xadbf, 0xadbf, 0xadc0, 0xadc0, 0xadc1, 0xadc1, 0xadc2, 0xadc2, 
+    0xadc3, 0xadc3, 0xadc4, 0xadc4, 0xadc5, 0xadc5, 0xadc6, 0xadc6, 
+    0xadc7, 0xadc7, 0xadc8, 0xadc8, 0xadc9, 0xadc9, 0xadca, 0xadca, 
+    0xadcb, 0xadcb, 0xadcc, 0xadcc, 0xadcd, 0xadcd, 0xadce, 0xadce, 
+    0xadcf, 0xadcf, 0xadd0, 0xadd0, 0xadd1, 0xadd1, 0xadd2, 0xadd2, 
+    0xadd3, 0xadd3, 0xadd4, 0xadd4, 0xadd5, 0xadd5, 0xadd6, 0xadd6, 
+    0xadd7, 0xadd7, 0xadd8, 0xadd8, 0xadd9, 0xadd9, 0xadda, 0xadda, 
+    0xaddb, 0xaddb, 0xaddc, 0xaddc, 0xaddd, 0xaddd, 0xadde, 0xadde, 
+    0xaddf, 0xaddf, 0xade0, 0xade0, 0xade1, 0xade1, 0xade2, 0xade2, 
+    0xade3, 0xade3, 0xade4, 0xade4, 0xade5, 0xade5, 0xade6, 0xade6, 
+    0xade7, 0xade7, 0xade8, 0xade8, 0xade9, 0xade9, 0xadea, 0xadea, 
+    0xadeb, 0xadeb, 0xadec, 0xadec, 0xaded, 0xaded, 0xadee, 0xadee, 
+    0xadef, 0xadef, 0xadf0, 0xadf0, 0xadf1, 0xadf1, 0xadf2, 0xadf2, 
+    0xadf3, 0xadf3, 0xadf4, 0xadf4, 0xadf5, 0xadf5, 0xadf6, 0xadf6, 
+    0xadf7, 0xadf7, 0xadf8, 0xadf8, 0xadf9, 0xadf9, 0xadfa, 0xadfa, 
+    0xadfb, 0xadfb, 0xadfc, 0xadfc, 0xadfd, 0xadfd, 0xadfe, 0xadfe, 
+    0xadfe, 0xadff, 0xadff, 0xae00, 0xae00, 0xae01, 0xae01, 0xae02, 
+    0xae02, 0xae03, 0xae03, 0xae04, 0xae04, 0xae05, 0xae05, 0xae06, 
+    0xae06, 0xae07, 0xae07, 0xae08, 0xae08, 0xae09, 0xae09, 0xae0a, 
+    0xae0a, 0xae0b, 0xae0b, 0xae0c, 0xae0c, 0xae0d, 0xae0d, 0xae0e, 
+    0xae0e, 0xae0e, 0xae0f, 0xae0f, 0xae10, 0xae10, 0xae11, 0xae11, 
+    0xae12, 0xae12, 0xae13, 0xae13, 0xae14, 0xae14, 0xae15, 0xae15, 
+    0xae16, 0xae16, 0xae17, 0xae17, 0xae18, 0xae18, 0xae19, 0xae19, 
+    0xae19, 0xae1a, 0xae1a, 0xae1b, 0xae1b, 0xae1c, 0xae1c, 0xae1d, 
+    0xae1d, 0xae1e, 0xae1e, 0xae1f, 0xae1f, 0xae20, 0xae20, 0xae21, 
+    0xae21, 0xae22, 0xae22, 0xae23, 0xae23, 0xae23, 0xae24, 0xae24, 
+    0xae25, 0xae25, 0xae26, 0xae26, 0xae27, 0xae27, 0xae28, 0xae28, 
+    0xae29, 0xae29, 0xae2a, 0xae2a, 0xae2b, 0xae2b, 0xae2b, 0xae2c, 
+    0xae2c, 0xae2d, 0xae2d, 0xae2e, 0xae2e, 0xae2f, 0xae2f, 0xae30, 
+    0xae30, 0xae31, 0xae31, 0xae32, 0xae32, 0xae33, 0xae33, 0xae33, 
+    0xae34, 0xae34, 0xae35, 0xae35, 0xae36, 0xae36, 0xae37, 0xae37, 
+    0xae38, 0xae38, 0xae39, 0xae39, 0xae3a, 0xae3a, 0xae3a, 0xae3b, 
+    0xae3b, 0xae3c, 0xae3c, 0xae3d, 0xae3d, 0xae3e, 0xae3e, 0xae3f, 
+    0xae3f, 0xae40, 0xae40, 0xae40, 0xae41, 0xae41, 0xae42, 0xae42, 
+    0xae43, 0xae43, 0xae44, 0xae44, 0xae45, 0xae45, 0xae46, 0xae46, 
+    0xae47, 0xae47, 0xae47, 0xae48, 0xae48, 0xae49, 0xae49, 0xae4a, 
+    0xae4a, 0xae4b, 0xae4b, 0xae4c, 0xae4c, 0xae4c, 0xae4d, 0xae4d, 
+    0xae4e, 0xae4e, 0xae4f, 0xae4f, 0xae50, 0xae50, 0xae51, 0xae51, 
+    0xae52, 0xae52, 0xae52, 0xae53, 0xae53, 0xae54, 0xae54, 0xae55, 
+    0xae55, 0xae56, 0xae56, 0xae57, 0xae57, 0xae57, 0xae58, 0xae58, 
+    0xae59, 0xae59, 0xae5a, 0xae5a, 0xae5b, 0xae5b, 0xae5c, 0xae5c, 
+    0xae5c, 0xae5d, 0xae5d, 0xae5e, 0xae5e, 0xae5f, 0xae5f, 0xae60, 
+    0xae60, 0xae61, 0xae61, 0xae61, 0xae62, 0xae62, 0xae63, 0xae63, 
+    0xae64, 0xae64, 0xae65, 0xae65, 0xae65, 0xae66, 0xae66, 0xae67, 
+    0xae67, 0xae68, 0xae68, 0xae69, 0xae69, 0xae6a, 0xae6a, 0xae6a, 
+    0xae6b, 0xae6b, 0xae6c, 0xae6c, 0xae6d, 0xae6d, 0xae6e, 0xae6e, 
+    0xae6e, 0xae6f, 0xae6f, 0xae70, 0xae70, 0xae71, 0xae71, 0xae72, 
+    0xae72, 0xae72, 0xae73, 0xae73, 0xae74, 0xae74, 0xae75, 0xae75, 
+    0xae76, 0xae76, 0xae77, 0xae77, 0xae77, 0xae78, 0xae78, 0xae79, 
+    0xae79, 0xae7a, 0xae7a, 0xae7b, 0xae7b, 0xae7b, 0xae7c, 0xae7c, 
+    0xae7d, 0xae7d, 0xae7e, 0xae7e, 0xae7e, 0xae7f, 0xae7f, 0xae80, 
+    0xae80, 0xae81, 0xae81, 0xae82, 0xae82, 0xae82, 0xae83, 0xae83, 
+    0xae84, 0xae84, 0xae85, 0xae85, 0xae86, 0xae86, 0xae86, 0xae87, 
+    0xae87, 0xae88, 0xae88, 0xae89, 0xae89, 0xae8a, 0xae8a, 0xae8a, 
+    0xae8b, 0xae8b, 0xae8c, 0xae8c, 0xae8d, 0xae8d, 0xae8d, 0xae8e, 
+    0xae8e, 0xae8f, 0xae8f, 0xae90, 0xae90, 0xae91, 0xae91, 0xae91, 
+    0xae92, 0xae92, 0xae93, 0xae93, 0xae94, 0xae94, 0xae94, 0xae95, 
+    0xae95, 0xae96, 0xae96, 0xae97, 0xae97, 0xae97, 0xae98, 0xae98, 
+    0xae99, 0xae99, 0xae9a, 0xae9a, 0xae9b, 0xae9b, 0xae9b, 0xae9c, 
+    0xae9c, 0xae9d, 0xae9d, 0xae9e, 0xae9e, 0xae9e, 0xae9f, 0xae9f, 
+    0xaea0, 0xaea0, 0xaea1, 0xaea1, 0xaea1, 0xaea2, 0xaea2, 0xaea3, 
+    0xaea3, 0xaea4, 0xaea4, 0xaea4, 0xaea5, 0xaea5, 0xaea6, 0xaea6, 
+    0xaea7, 0xaea7, 0xaea7, 0xaea8, 0xaea8, 0xaea9, 0xaea9, 0xaeaa, 
+    0xaeaa, 0xaeaa, 0xaeab, 0xaeab, 0xaeac, 0xaeac, 0xaead, 0xaead, 
+    0xaead, 0xaeae, 0xaeae, 0xaeaf, 0xaeaf, 0xaeb0, 0xaeb0, 0xaeb0, 
+    0xaeb1, 0xaeb1, 0xaeb2, 0xaeb2, 0xaeb3, 0xaeb3, 0xaeb3, 0xaeb4, 
+    0xaeb4, 0xaeb5, 0xaeb5, 0xaeb6, 0xaeb6, 0xaeb6, 0xaeb7, 0xaeb7, 
+    0xaeb8, 0xaeb8, 0xaeb9, 0xaeb9, 0xaeb9, 0xaeba, 0xaeba, 0xaebb, 
+    0xaebb, 0xaebc, 0xaebc, 0xaebc, 0xaebd, 0xaebd, 0xaebe, 0xaebe, 
+    0xaebe, 0xaebf, 0xaebf, 0xaec0, 0xaec0, 0xaec1, 0xaec1, 0xaec1, 
+    0xaec2, 0xaec2, 0xaec3, 0xaec3, 0xaec4, 0xaec4, 0xaec4, 0xaec5, 
+    0xaec5, 0xaec6, 0xaec6, 0xaec7, 0xaec7, 0xaec7, 0xaec8, 0xaec8, 
+    0xaec9, 0xaec9, 0xaec9, 0xaeca, 0xaeca, 0xaecb, 0xaecb, 0xaecc, 
+    0xaecc, 0xaecc, 0xaecd, 0xaecd, 0xaece, 0xaece, 0xaece, 0xaecf, 
+    0xaecf, 0xaed0, 0xaed0, 0xaed1, 0xaed1, 0xaed1, 0xaed2, 0xaed2, 
+    0xaed3, 0xaed3, 0xaed3, 0xaed4, 0xaed4, 0xaed5, 0xaed5, 0xaed6, 
+    0xaed6, 0xaed6, 0xaed7, 0xaed7, 0xaed8, 0xaed8, 0xaed8, 0xaed9, 
+    0xaed9, 0xaeda, 0xaeda, 0xaedb, 0xaedb, 0xaedb, 0xaedc, 0xaedc, 
+    0xaedd, 0xaedd, 0xaedd, 0xaede, 0xaede, 0xaedf, 0xaedf, 0xaee0, 
+    0xaee0, 0xaee0, 0xaee1, 0xaee1, 0xaee2, 0xaee2, 0xaee2, 0xaee3, 
+    0xaee3, 0xaee4, 0xaee4, 0xaee4, 0xaee5, 0xaee5, 0xaee6, 0xaee6, 
+    0xaee7, 0xaee7, 0xaee7, 0xaee8, 0xaee8, 0xaee9, 0xaee9, 0xaee9, 
+    0xaeea, 0xaeea, 0xaeeb, 0xaeeb, 0xaeeb, 0xaeec, 0xaeec, 0xaeed, 
+    0xaeed, 0xaeee, 0xaeee, 0xaeee, 0xaeef, 0xaeef, 0xaef0, 0xaef0, 
+    0xaef0, 0xaef1, 0xaef1, 0xaef2, 0xaef2, 0xaef2, 0xaef3, 0xaef3, 
+    0xaef4, 0xaef4, 0xaef4, 0xaef5, 0xaef5, 0xaef6, 0xaef6, 0xaef6, 
+    0xaef7, 0xaef7, 0xaef8, 0xaef8, 0xaef9, 0xaef9, 0xaef9, 0xaefa, 
+    0xaefa, 0xaefb, 0xaefb, 0xaefb, 0xaefc, 0xaefc, 0xaefd, 0xaefd, 
+    0xaefd, 0xaefe, 0xaefe, 0xaeff, 0xaeff, 0xaeff, 0xaf00, 0xaf00, 
+    0xaf01, 0xaf01, 0xaf01, 0xaf02, 0xaf02, 0xaf03, 0xaf03, 0xaf03, 
+    0xaf04, 0xaf04, 0xaf05, 0xaf05, 0xaf05, 0xaf06, 0xaf06, 0xaf07, 
+    0xaf07, 0xaf07, 0xaf08, 0xaf08, 0xaf09, 0xaf09, 0xaf09, 0xaf0a, 
+    0xaf0a, 0xaf0b, 0xaf0b, 0xaf0b, 0xaf0c, 0xaf0c, 0xaf0d, 0xaf0d, 
+    0xaf0d, 0xaf0e, 0xaf0f, 0xaf10, 0xaf11, 0xaf12, 0xaf12, 0xaf13, 
+    0xaf14, 0xaf15, 0xaf15, 0xaf16, 0xaf17, 0xaf18, 0xaf19, 0xaf19, 
+    0xaf1a, 0xaf1b, 0xaf1c, 0xaf1d, 0xaf1d, 0xaf1e, 0xaf1f, 0xaf20, 
+    0xaf21, 0xaf21, 0xaf22, 0xaf23, 0xaf24, 0xaf25, 0xaf25, 0xaf26, 
+    0xaf27, 0xaf28, 0xaf29, 0xaf29, 0xaf2a, 0xaf2b, 0xaf2c, 0xaf2c, 
+    0xaf2d, 0xaf2e, 0xaf2f, 0xaf30, 0xaf30, 0xaf31, 0xaf32, 0xaf33, 
+    0xaf33, 0xaf34, 0xaf35, 0xaf36, 0xaf37, 0xaf37, 0xaf38, 0xaf39, 
+    0xaf3a, 0xaf3b, 0xaf3b, 0xaf3c, 0xaf3d, 0xaf3e, 0xaf3e, 0xaf3f, 
+    0xaf40, 0xaf41, 0xaf41, 0xaf42, 0xaf43, 0xaf44, 0xaf45, 0xaf45, 
+    0xaf46, 0xaf47, 0xaf48, 0xaf48, 0xaf49, 0xaf4a, 0xaf4b, 0xaf4c, 
+    0xaf4c, 0xaf4d, 0xaf4e, 0xaf4f, 0xaf4f, 0xaf50, 0xaf51, 0xaf52, 
+    0xaf52, 0xaf53, 0xaf54, 0xaf55, 0xaf56, 0xaf56, 0xaf57, 0xaf58, 
+    0xaf59, 0xaf59, 0xaf5a, 0xaf5b, 0xaf5c, 0xaf5c, 0xaf5d, 0xaf5e, 
+    0xaf5f, 0xaf5f, 0xaf60, 0xaf61, 0xaf62, 0xaf62, 0xaf63, 0xaf64, 
+    0xaf65, 0xaf65, 0xaf66, 0xaf67, 0xaf68, 0xaf69, 0xaf69, 0xaf6a, 
+    0xaf6b, 0xaf6c, 0xaf6c, 0xaf6d, 0xaf6e, 0xaf6f, 0xaf6f, 0xaf70, 
+    0xaf71, 0xaf72, 0xaf72, 0xaf73, 0xaf74, 0xaf75, 0xaf75, 0xaf76, 
+    0xaf77, 0xaf78, 0xaf78, 0xaf79, 0xaf7a, 0xaf7b, 0xaf7b, 0xaf7c, 
+    0xaf7d, 0xaf7e, 0xaf7e, 0xaf7f, 0xaf80, 0xaf81, 0xaf81, 0xaf82, 
+    0xaf83, 0xaf83, 0xaf84, 0xaf85, 0xaf86, 0xaf86, 0xaf87, 0xaf88, 
+    0xaf89, 0xaf89, 0xaf8a, 0xaf8b, 0xaf8c, 0xaf8c, 0xaf8d, 0xaf8e, 
+    0xaf8f, 0xaf8f, 0xaf90, 0xaf91, 0xaf92, 0xaf92, 0xaf93, 0xaf94, 
+    0xaf94, 0xaf95, 0xaf96, 0xaf97, 0xaf97, 0xaf98, 0xaf99, 0xaf9a, 
+    0xaf9a, 0xaf9b, 0xaf9c, 0xaf9d, 0xaf9d, 0xaf9e, 0xaf9f, 0xaf9f, 
+    0xafa0, 0xafa1, 0xafa2, 0xafa2, 0xafa3, 0xafa4, 0xafa5, 0xafa5, 
+    0xafa6, 0xafa7, 0xafa7, 0xafa8, 0xafa9, 0xafaa, 0xafaa, 0xafab, 
+    0xafac, 0xafad, 0xafad, 0xafae, 0xafaf, 0xafaf, 0xafb0, 0xafb1, 
+    0xafb2, 0xafb2, 0xafb3, 0xafb4, 0xafb4, 0xafb5, 0xafb6, 0xafb7, 
+    0xafb7, 0xafb8, 0xafb9, 0xafba, 0xafba, 0xafbb, 0xafbc, 0xafbc, 
+    0xafbd, 0xafbe, 0xafbf, 0xafbf, 0xafc0, 0xafc1, 0xafc1, 0xafc2, 
+    0xafc3, 0xafc4, 0xafc4, 0xafc5, 0xafc6, 0xafc6, 0xafc7, 0xafc8, 
+    0xafc9, 0xafc9, 0xafca, 0xafcb, 0xafcb, 0xafcc, 0xafcd, 0xafce, 
+    0xafce, 0xafcf, 0xafd0, 0xafd0, 0xafd1, 0xafd2, 0xafd2, 0xafd3, 
+    0xafd4, 0xafd5, 0xafd5, 0xafd6, 0xafd7, 0xafd7, 0xafd8, 0xafd9, 
+    0xafda, 0xafda, 0xafdb, 0xafdc, 0xafdc, 0xafdd, 0xafde, 0xafde, 
+    0xafdf, 0xafe0, 0xafe1, 0xafe1, 0xafe2, 0xafe3, 0xafe3, 0xafe4, 
+    0xafe5, 0xafe5, 0xafe6, 0xafe7, 0xafe8, 0xafe8, 0xafe9, 0xafea, 
+    0xafea, 0xafeb, 0xafec, 0xafec, 0xafed, 0xafee, 0xafef, 0xafef, 
+    0xaff0, 0xaff1, 0xaff1, 0xaff2, 0xaff3, 0xaff3, 0xaff4, 0xaff5, 
+    0xaff6, 0xaff6, 0xaff7, 0xaff8, 0xaff8, 0xaff9, 0xaffa, 0xaffa, 
+    0xaffb, 0xaffc, 0xaffc, 0xaffd, 0xaffe, 0xafff, 0xafff, 0xb000, 
+    0xb000, 0xb001, 0xb001, 0xb001, 0xb002, 0xb002, 0xb002, 0xb003, 
+    0xb003, 0xb003, 0xb004, 0xb004, 0xb004, 0xb005, 0xb005, 0xb005, 
+    0xb006, 0xb006, 0xb006, 0xb007, 0xb007, 0xb007, 0xb008, 0xb008, 
+    0xb009, 0xb009, 0xb009, 0xb00a, 0xb00a, 0xb00a, 0xb00b, 0xb00b, 
+    0xb00b, 0xb00c, 0xb00c, 0xb00c, 0xb00d, 0xb00d, 0xb00d, 0xb00e, 
+    0xb00e, 0xb00e, 0xb00f, 0xb00f, 0xb00f, 0xb010, 0xb010, 0xb010, 
+    0xb011, 0xb011, 0xb011, 0xb012, 0xb012, 0xb012, 0xb013, 0xb013, 
+    0xb013, 0xb014, 0xb014, 0xb014, 0xb015, 0xb015, 0xb015, 0xb016, 
+    0xb016, 0xb016, 0xb017, 0xb017, 0xb017, 0xb018, 0xb018, 0xb018, 
+    0xb019, 0xb019, 0xb019, 0xb01a, 0xb01a, 0xb01a, 0xb01b, 0xb01b, 
+    0xb01b, 0xb01c, 0xb01c, 0xb01c, 0xb01d, 0xb01d, 0xb01d, 0xb01e, 
+    0xb01e, 0xb01e, 0xb01f, 0xb01f, 0xb01f, 0xb020, 0xb020, 0xb020, 
+    0xb021, 0xb021, 0xb021, 0xb022, 0xb022, 0xb022, 0xb023, 0xb023, 
+    0xb023, 0xb024, 0xb024, 0xb024, 0xb025, 0xb025, 0xb025, 0xb026, 
+    0xb026, 0xb026, 0xb027, 0xb027, 0xb027, 0xb028, 0xb028, 0xb028, 
+    0xb029, 0xb029, 0xb029, 0xb02a, 0xb02a, 0xb02a, 0xb02b, 0xb02b, 
+    0xb02b, 0xb02c, 0xb02c, 0xb02c, 0xb02d, 0xb02d, 0xb02d, 0xb02e, 
+    0xb02e, 0xb02e, 0xb02f, 0xb02f, 0xb02f, 0xb030, 0xb030, 0xb030, 
+    0xb031, 0xb031, 0xb031, 0xb031, 0xb032, 0xb032, 0xb032, 0xb033, 
+    0xb033, 0xb033, 0xb034, 0xb034, 0xb034, 0xb035, 0xb035, 0xb035, 
+    0xb036, 0xb036, 0xb036, 0xb037, 0xb037, 0xb037, 0xb038, 0xb038, 
+    0xb038, 0xb039, 0xb039, 0xb039, 0xb03a, 0xb03a, 0xb03a, 0xb03b, 
+    0xb03b, 0xb03b, 0xb03c, 0xb03c, 0xb03c, 0xb03c, 0xb03d, 0xb03d, 
+    0xb03d, 0xb03e, 0xb03e, 0xb03e, 0xb03f, 0xb03f, 0xb03f, 0xb040, 
+    0xb040, 0xb040, 0xb041, 0xb041, 0xb041, 0xb042, 0xb042, 0xb042, 
+    0xb043, 0xb043, 0xb043, 0xb044, 0xb044, 0xb044, 0xb044, 0xb045, 
+    0xb045, 0xb045, 0xb046, 0xb046, 0xb046, 0xb047, 0xb047, 0xb047, 
+    0xb048, 0xb048, 0xb048, 0xb049, 0xb049, 0xb049, 0xb04a, 0xb04a, 
+    0xb04a, 0xb04b, 0xb04b, 0xb04b, 0xb04b, 0xb04c, 0xb04c, 0xb04c, 
+    0xb04d, 0xb04d, 0xb04d, 0xb04e, 0xb04e, 0xb04e, 0xb04f, 0xb04f, 
+    0xb04f, 0xb050, 0xb050, 0xb050, 0xb051, 0xb051, 0xb051, 0xb051, 
+    0xb052, 0xb052, 0xb052, 0xb053, 0xb053, 0xb053, 0xb054, 0xb054, 
+    0xb054, 0xb055, 0xb055, 0xb055, 0xb056, 0xb056, 0xb056, 0xb056, 
+    0xb057, 0xb057, 0xb057, 0xb058, 0xb058, 0xb058, 0xb059, 0xb059, 
+    0xb059, 0xb05a, 0xb05a, 0xb05a, 0xb05b, 0xb05b, 0xb05b, 0xb05b, 
+    0xb05c, 0xb05c, 0xb05c, 0xb05d, 0xb05d, 0xb05d, 0xb05e, 0xb05e, 
+    0xb05e, 0xb05f, 0xb05f, 0xb05f, 0xb05f, 0xb060, 0xb060, 0xb060, 
+    0xb061, 0xb061, 0xb061, 0xb062, 0xb062, 0xb062, 0xb063, 0xb063, 
+    0xb063, 0xb064, 0xb064, 0xb064, 0xb064, 0xb065, 0xb065, 0xb065, 
+    0xb066, 0xb066, 0xb066, 0xb067, 0xb067, 0xb067, 0xb068, 0xb068, 
+    0xb068, 0xb068, 0xb069, 0xb069, 0xb069, 0xb06a, 0xb06a, 0xb06a, 
+    0xb06b, 0xb06b, 0xb06b, 0xb06b, 0xb06c, 0xb06c, 0xb06c, 0xb06d, 
+    0xb06d, 0xb06d, 0xb06e, 0xb06e, 0xb06e, 0xb06f, 0xb06f, 0xb06f, 
+    0xb06f, 0xb070, 0xb070, 0xb070, 0xb071, 0xb071, 0xb071, 0xb072, 
+    0xb072, 0xb072, 0xb072, 0xb073, 0xb073, 0xb073, 0xb074, 0xb074, 
+    0xb074, 0xb075, 0xb075, 0xb075, 0xb076, 0xb076, 0xb076, 0xb076, 
+    0xb077, 0xb077, 0xb077, 0xb078, 0xb078, 0xb078, 0xb079, 0xb079, 
+    0xb079, 0xb079, 0xb07a, 0xb07a, 0xb07a, 0xb07b, 0xb07b, 0xb07b, 
+    0xb07c, 0xb07c, 0xb07c, 0xb07c, 0xb07d, 0xb07d, 0xb07d, 0xb07e, 
+    0xb07e, 0xb07e, 0xb07f, 0xb07f, 0xb07f, 0xb07f, 0xb080, 0xb080, 
+    0xb080, 0xb081, 0xb081, 0xb081, 0xb082, 0xb082, 0xb082, 0xb082, 
+    0xb083, 0xb083, 0xb083, 0xb084, 0xb084, 0xb084, 0xb085, 0xb085, 
+    0xb085, 0xb085, 0xb086, 0xb086, 0xb086, 0xb087, 0xb087, 0xb087, 
+    0xb087, 0xb088, 0xb088, 0xb088, 0xb089, 0xb089, 0xb089, 0xb08a, 
+    0xb08a, 0xb08a, 0xb08a, 0xb08b, 0xb08b, 0xb08b, 0xb08c, 0xb08c, 
+    0xb08c, 0xb08d, 0xb08d, 0xb08d, 0xb08d, 0xb08e, 0xb08e, 0xb08e, 
+    0xb08f, 0xb08f, 0xb08f, 0xb08f, 0xb090, 0xb090, 0xb090, 0xb091, 
+    0xb091, 0xb091, 0xb092, 0xb092, 0xb092, 0xb092, 0xb093, 0xb093, 
+    0xb093, 0xb094, 0xb094, 0xb094, 0xb094, 0xb095, 0xb095, 0xb095, 
+    0xb096, 0xb096, 0xb096, 0xb097, 0xb097, 0xb097, 0xb097, 0xb098, 
+    0xb098, 0xb098, 0xb099, 0xb099, 0xb099, 0xb099, 0xb09a, 0xb09a, 
+    0xb09a, 0xb09b, 0xb09b, 0xb09b, 0xb09b, 0xb09c, 0xb09c, 0xb09c, 
+    0xb09d, 0xb09d, 0xb09d, 0xb09e, 0xb09e, 0xb09e, 0xb09e, 0xb09f, 
+    0xb09f, 0xb09f, 0xb0a0, 0xb0a0, 0xb0a0, 0xb0a0, 0xb0a1, 0xb0a1, 
+    0xb0a1, 0xb0a2, 0xb0a2, 0xb0a2, 0xb0a2, 0xb0a3, 0xb0a3, 0xb0a3, 
+    0xb0a4, 0xb0a4, 0xb0a4, 0xb0a4, 0xb0a5, 0xb0a5, 0xb0a5, 0xb0a6, 
+    0xb0a6, 0xb0a6, 0xb0a6, 0xb0a7, 0xb0a7, 0xb0a7, 0xb0a8, 0xb0a8, 
+    0xb0a8, 0xb0a8, 0xb0a9, 0xb0a9, 0xb0a9, 0xb0aa, 0xb0aa, 0xb0aa, 
+    0xb0aa, 0xb0ab, 0xb0ab, 0xb0ab, 0xb0ac, 0xb0ac, 0xb0ac, 0xb0ac, 
+    0xb0ad, 0xb0ad, 0xb0ad, 0xb0ae, 0xb0ae, 0xb0ae, 0xb0ae, 0xb0af, 
+    0xb0af, 0xb0af, 0xb0b0, 0xb0b0, 0xb0b0, 0xb0b0, 0xb0b1, 0xb0b1, 
+    0xb0b1, 0xb0b2, 0xb0b2, 0xb0b2, 0xb0b2, 0xb0b3, 0xb0b3, 0xb0b3, 
+    0xb0b4, 0xb0b4, 0xb0b4, 0xb0b4, 0xb0b5, 0xb0b5, 0xb0b5, 0xb0b6, 
+    0xb0b6, 0xb0b6, 0xb0b6, 0xb0b7, 0xb0b7, 0xb0b7, 0xb0b8, 0xb0b8, 
+    0xb0b8, 0xb0b8, 0xb0b9, 0xb0b9, 0xb0b9, 0xb0ba, 0xb0ba, 0xb0ba, 
+    0xb0ba, 0xb0bb, 0xb0bb, 0xb0bb, 0xb0bc, 0xb0bc, 0xb0bc, 0xb0bc, 
+    0xb0bd, 0xb0bd, 0xb0bd, 0xb0bd, 0xb0be, 0xb0be, 0xb0be, 0xb0bf, 
+    0xb0bf, 0xb0bf, 0xb0bf, 0xb0c0, 0xb0c0, 0xb0c0, 0xb0c1, 0xb0c1, 
+    0xb0c1, 0xb0c1, 0xb0c2, 0xb0c2, 0xb0c2, 0xb0c3, 0xb0c3, 0xb0c3, 
+    0xb0c3, 0xb0c4, 0xb0c4, 0xb0c4, 0xb0c4, 0xb0c5, 0xb0c5, 0xb0c5, 
+    0xb0c6, 0xb0c6, 0xb0c6, 0xb0c6, 0xb0c7, 0xb0c7, 0xb0c7, 0xb0c8, 
+    0xb0c8, 0xb0c8, 0xb0c8, 0xb0c9, 0xb0c9, 0xb0c9, 0xb0c9, 0xb0ca, 
+    0xb0ca, 0xb0ca, 0xb0cb, 0xb0cb, 0xb0cb, 0xb0cb, 0xb0cc, 0xb0cc, 
+    0xb0cc, 0xb0cd, 0xb0cd, 0xb0cd, 0xb0cd, 0xb0ce, 0xb0ce, 0xb0ce, 
+    0xb0ce, 0xb0cf, 0xb0cf, 0xb0cf, 0xb0d0, 0xb0d0, 0xb0d0, 0xb0d0, 
+    0xb0d1, 0xb0d1, 0xb0d1, 0xb0d2, 0xb0d2, 0xb0d2, 0xb0d2, 0xb0d3, 
+    0xb0d3, 0xb0d3, 0xb0d3, 0xb0d4, 0xb0d4, 0xb0d4, 0xb0d5, 0xb0d5, 
+    0xb0d5, 0xb0d6, 0xb0d6, 0xb0d7, 0xb0d7, 0xb0d8, 0xb0d8, 0xb0d9, 
+    0xb0d9, 0xb0da, 0xb0db, 0xb0db, 0xb0dc, 0xb0dc, 0xb0dd, 0xb0dd, 
+    0xb0de, 0xb0de, 0xb0df, 0xb0df, 0xb0e0, 0xb0e1, 0xb0e1, 0xb0e2, 
+    0xb0e2, 0xb0e3, 0xb0e3, 0xb0e4, 0xb0e4, 0xb0e5, 0xb0e5, 0xb0e6, 
+    0xb0e7, 0xb0e7, 0xb0e8, 0xb0e8, 0xb0e9, 0xb0e9, 0xb0ea, 0xb0ea, 
+    0xb0eb, 0xb0eb, 0xb0ec, 0xb0ec, 0xb0ed, 0xb0ee, 0xb0ee, 0xb0ef, 
+    0xb0ef, 0xb0f0, 0xb0f0, 0xb0f1, 0xb0f1, 0xb0f2, 0xb0f2, 0xb0f3, 
+    0xb0f3, 0xb0f4, 0xb0f4, 0xb0f5, 0xb0f6, 0xb0f6, 0xb0f7, 0xb0f7, 
+    0xb0f8, 0xb0f8, 0xb0f9, 0xb0f9, 0xb0fa, 0xb0fa, 0xb0fb, 0xb0fb, 
+    0xb0fc, 0xb0fc, 0xb0fd, 0xb0fd, 0xb0fe, 0xb0ff, 0xb0ff, 0xb100, 
+    0xb100, 0xb101, 0xb101, 0xb102, 0xb102, 0xb103, 0xb103, 0xb104, 
+    0xb104, 0xb105, 0xb105, 0xb106, 0xb106, 0xb107, 0xb107, 0xb108, 
+    0xb109, 0xb109, 0xb10a, 0xb10a, 0xb10b, 0xb10b, 0xb10c, 0xb10c, 
+    0xb10d, 0xb10d, 0xb10e, 0xb10e, 0xb10f, 0xb10f, 0xb110, 0xb110, 
+    0xb111, 0xb111, 0xb112, 0xb112, 0xb113, 0xb113, 0xb114, 0xb114, 
+    0xb115, 0xb116, 0xb116, 0xb117, 0xb117, 0xb118, 0xb118, 0xb119, 
+    0xb119, 0xb11a, 0xb11a, 0xb11b, 0xb11b, 0xb11c, 0xb11c, 0xb11d, 
+    0xb11d, 0xb11e, 0xb11e, 0xb11f, 0xb11f, 0xb120, 0xb120, 0xb121, 
+    0xb121, 0xb122, 0xb122, 0xb123, 0xb123, 0xb124, 0xb124, 0xb125, 
+    0xb125, 0xb126, 0xb126, 0xb127, 0xb127, 0xb128, 0xb128, 0xb129, 
+    0xb129, 0xb12a, 0xb12a, 0xb12b, 0xb12c, 0xb12c, 0xb12d, 0xb12d, 
+    0xb12e, 0xb12e, 0xb12f, 0xb12f, 0xb130, 0xb130, 0xb131, 0xb131, 
+    0xb132, 0xb132, 0xb133, 0xb133, 0xb134, 0xb134, 0xb135, 0xb135, 
+    0xb136, 0xb136, 0xb137, 0xb137, 0xb138, 0xb138, 0xb139, 0xb139, 
+    0xb13a, 0xb13a, 0xb13b, 0xb13b, 0xb13c, 0xb13c, 0xb13d, 0xb13d, 
+    0xb13e, 0xb13e, 0xb13f, 0xb13f, 0xb140, 0xb140, 0xb141, 0xb141, 
+    0xb142, 0xb142, 0xb143, 0xb143, 0xb144, 0xb144, 0xb145, 0xb145, 
+    0xb146, 0xb146, 0xb147, 0xb147, 0xb148, 0xb148, 0xb148, 0xb149, 
+    0xb149, 0xb14a, 0xb14a, 0xb14b, 0xb14b, 0xb14c, 0xb14c, 0xb14d, 
+    0xb14d, 0xb14e, 0xb14e, 0xb14f, 0xb14f, 0xb150, 0xb150, 0xb151, 
+    0xb151, 0xb152, 0xb152, 0xb153, 0xb153, 0xb154, 0xb154, 0xb155, 
+    0xb155, 0xb156, 0xb156, 0xb157, 0xb157, 0xb158, 0xb158, 0xb159, 
+    0xb159, 0xb15a, 0xb15a, 0xb15b, 0xb15b, 0xb15c, 0xb15c, 0xb15d, 
+    0xb15d, 0xb15e, 0xb15e, 0xb15e, 0xb15f, 0xb15f, 0xb160, 0xb160, 
+    0xb161, 0xb161, 0xb162, 0xb162, 0xb163, 0xb163, 0xb164, 0xb164, 
+    0xb165, 0xb165, 0xb166, 0xb166, 0xb167, 0xb167, 0xb168, 0xb168, 
+    0xb169, 0xb169, 0xb16a, 0xb16a, 0xb16b, 0xb16b, 0xb16b, 0xb16c, 
+    0xb16c, 0xb16d, 0xb16d, 0xb16e, 0xb16e, 0xb16f, 0xb16f, 0xb170, 
+    0xb170, 0xb171, 0xb171, 0xb172, 0xb172, 0xb173, 0xb173, 0xb174, 
+    0xb174, 0xb175, 0xb175, 0xb175, 0xb176, 0xb176, 0xb177, 0xb177, 
+    0xb178, 0xb178, 0xb179, 0xb179, 0xb17a, 0xb17a, 0xb17b, 0xb17b, 
+    0xb17c, 0xb17c, 0xb17d, 0xb17d, 0xb17e, 0xb17e, 0xb17e, 0xb17f, 
+    0xb17f, 0xb180, 0xb180, 0xb181, 0xb181, 0xb182, 0xb182, 0xb183, 
+    0xb183, 0xb184, 0xb184, 0xb185, 0xb185, 0xb185, 0xb186, 0xb186, 
+    0xb187, 0xb187, 0xb188, 0xb188, 0xb189, 0xb189, 0xb18a, 0xb18a, 
+    0xb18b, 0xb18b, 0xb18c, 0xb18c, 0xb18c, 0xb18d, 0xb18d, 0xb18e, 
+    0xb18e, 0xb18f, 0xb18f, 0xb190, 0xb190, 0xb191, 0xb191, 0xb192, 
+    0xb192, 0xb193, 0xb193, 0xb193, 0xb194, 0xb194, 0xb195, 0xb195, 
+    0xb196, 0xb196, 0xb197, 0xb197, 0xb198, 0xb198, 0xb199, 0xb199, 
+    0xb199, 0xb19a, 0xb19a, 0xb19b, 0xb19b, 0xb19c, 0xb19c, 0xb19d, 
+    0xb19d, 0xb19e, 0xb19e, 0xb19f, 0xb19f, 0xb19f, 0xb1a0, 0xb1a0, 
+    0xb1a1, 0xb1a1, 0xb1a2, 0xb1a2, 0xb1a3, 0xb1a3, 0xb1a4, 0xb1a4, 
+    0xb1a4, 0xb1a5, 0xb1a5, 0xb1a6, 0xb1a6, 0xb1a7, 0xb1a7, 0xb1a8, 
+    0xb1a8, 0xb1a9, 0xb1a9, 0xb1a9, 0xb1aa, 0xb1aa, 0xb1ab, 0xb1ab, 
+    0xb1ac, 0xb1ac, 0xb1ad, 0xb1ad, 0xb1ae, 0xb1ae, 0xb1ae, 0xb1af, 
+    0xb1af, 0xb1b0, 0xb1b0, 0xb1b1, 0xb1b1, 0xb1b2, 0xb1b2, 0xb1b2, 
+    0xb1b3, 0xb1b3, 0xb1b4, 0xb1b4, 0xb1b5, 0xb1b5, 0xb1b6, 0xb1b6, 
+    0xb1b7, 0xb1b7, 0xb1b7, 0xb1b8, 0xb1b8, 0xb1b9, 0xb1b9, 0xb1ba, 
+    0xb1ba, 0xb1bb, 0xb1bb, 0xb1bb, 0xb1bc, 0xb1bc, 0xb1bd, 0xb1bd, 
+    0xb1be, 0xb1be, 0xb1bf, 0xb1bf, 0xb1bf, 0xb1c0, 0xb1c0, 0xb1c1, 
+    0xb1c1, 0xb1c2, 0xb1c2, 0xb1c3, 0xb1c3, 0xb1c4, 0xb1c4, 0xb1c4, 
+    0xb1c5, 0xb1c5, 0xb1c6, 0xb1c6, 0xb1c7, 0xb1c7, 0xb1c7, 0xb1c8, 
+    0xb1c8, 0xb1c9, 0xb1c9, 0xb1ca, 0xb1ca, 0xb1cb, 0xb1cb, 0xb1cb, 
+    0xb1cc, 0xb1cc, 0xb1cd, 0xb1cd, 0xb1ce, 0xb1ce, 0xb1cf, 0xb1cf, 
+    0xb1cf, 0xb1d0, 0xb1d0, 0xb1d1, 0xb1d1, 0xb1d2, 0xb1d2, 0xb1d3, 
+    0xb1d3, 0xb1d3, 0xb1d4, 0xb1d4, 0xb1d5, 0xb1d5, 0xb1d6, 0xb1d6, 
+    0xb1d6, 0xb1d7, 0xb1d7, 0xb1d8, 0xb1d8, 0xb1d9, 0xb1d9, 0xb1da, 
+    0xb1da, 0xb1da, 0xb1db, 0xb1db, 0xb1dc, 0xb1dc, 0xb1dd, 0xb1dd, 
+    0xb1dd, 0xb1de, 0xb1de, 0xb1df, 0xb1df, 0xb1e0, 0xb1e0, 0xb1e0, 
+    0xb1e1, 0xb1e1, 0xb1e2, 0xb1e2, 0xb1e3, 0xb1e3, 0xb1e4, 0xb1e4, 
+    0xb1e4, 0xb1e5, 0xb1e5, 0xb1e6, 0xb1e6, 0xb1e7, 0xb1e7, 0xb1e7, 
+    0xb1e8, 0xb1e8, 0xb1e9, 0xb1e9, 0xb1ea, 0xb1ea, 0xb1ea, 0xb1eb, 
+    0xb1eb, 0xb1ec, 0xb1ec, 0xb1ed, 0xb1ed, 0xb1ed, 0xb1ee, 0xb1ee, 
+    0xb1ef, 0xb1ef, 0xb1f0, 0xb1f0, 0xb1f0, 0xb1f1, 0xb1f1, 0xb1f2, 
+    0xb1f2, 0xb1f3, 0xb1f3, 0xb1f3, 0xb1f4, 0xb1f4, 0xb1f5, 0xb1f5, 
+    0xb1f6, 0xb1f6, 0xb1f6, 0xb1f7, 0xb1f7, 0xb1f8, 0xb1f8, 0xb1f9, 
+    0xb1f9, 0xb1f9, 0xb1fa, 0xb1fa, 0xb1fb, 0xb1fb, 0xb1fc, 0xb1fc, 
+    0xb1fc, 0xb1fd, 0xb1fd, 0xb1fe, 0xb1fe, 0xb1ff, 0xb1ff, 0xb1ff, 
+    0xb200, 0xb200, 0xb201, 0xb201, 0xb201, 0xb202, 0xb202, 0xb203, 
+    0xb203, 0xb204, 0xb204, 0xb204, 0xb205, 0xb205, 0xb206, 0xb206, 
+    0xb207, 0xb207, 0xb207, 0xb208, 0xb208, 0xb209, 0xb209, 0xb20a, 
+    0xb20a, 0xb20a, 0xb20b, 0xb20b, 0xb20c, 0xb20c, 0xb20c, 0xb20d, 
+    0xb20d, 0xb20e, 0xb20e, 0xb20f, 0xb20f, 0xb20f, 0xb210, 0xb210, 
+    0xb211, 0xb211, 0xb211, 0xb212, 0xb212, 0xb213, 0xb213, 0xb214, 
+    0xb214, 0xb214, 0xb215, 0xb215, 0xb216, 0xb216, 0xb216, 0xb217, 
+    0xb217, 0xb218, 0xb218, 0xb219, 0xb219, 0xb219, 0xb21a, 0xb21a, 
+    0xb21b, 0xb21b, 0xb21b, 0xb21c, 0xb21c, 0xb21d, 0xb21d, 0xb21e, 
+    0xb21e, 0xb21e, 0xb21f, 0xb21f, 0xb220, 0xb220, 0xb220, 0xb221, 
+    0xb221, 0xb222, 0xb222, 0xb222, 0xb223, 0xb223, 0xb224, 0xb224, 
+    0xb225, 0xb225, 0xb225, 0xb226, 0xb226, 0xb227, 0xb227, 0xb227, 
+    0xb228, 0xb228, 0xb229, 0xb229, 0xb229, 0xb22a, 0xb22a, 0xb22b, 
+    0xb22b, 0xb22c, 0xb22c, 0xb22c, 0xb22d, 0xb22d, 0xb22e, 0xb22e, 
+    0xb22e, 0xb22f, 0xb22f, 0xb230, 0xb230, 0xb230, 0xb231, 0xb231, 
+    0xb232, 0xb232, 0xb232, 0xb233, 0xb233, 0xb234, 0xb234, 0xb235, 
+    0xb235, 0xb235, 0xb236, 0xb236, 0xb237, 0xb237, 0xb237, 0xb238, 
+    0xb238, 0xb239, 0xb239, 0xb239, 0xb23a, 0xb23a, 0xb23b, 0xb23b, 
+    0xb23b, 0xb23c, 0xb23c, 0xb23d, 0xb23d, 0xb23d, 0xb23e, 0xb23e, 
+    0xb23f, 0xb23f, 0xb23f, 0xb240, 0xb240, 0xb241, 0xb241, 0xb241, 
+    0xb242, 0xb242, 0xb243, 0xb243, 0xb243, 0xb244, 0xb244, 0xb245, 
+    0xb245, 0xb245, 0xb246, 0xb246, 0xb247, 0xb247, 0xb247, 0xb248, 
+    0xb248, 0xb249, 0xb249, 0xb249, 0xb24a, 0xb24a, 0xb24b, 0xb24b, 
+    0xb24b, 0xb24c, 0xb24c, 0xb24d, 0xb24d, 0xb24d, 0xb24e, 0xb24e, 
+    0xb24f, 0xb24f, 0xb24f, 0xb250, 0xb250, 0xb251, 0xb251, 0xb251, 
+    0xb252, 0xb252, 0xb253, 0xb253, 0xb253, 0xb254, 0xb254, 0xb255, 
+    0xb255, 0xb255, 0xb256, 0xb256, 0xb257, 0xb257, 0xb257, 0xb258, 
+    0xb258, 0xb259, 0xb259, 0xb259, 0xb25a, 0xb25a, 0xb25b, 0xb25b, 
+    0xb25b, 0xb25c, 0xb25c, 0xb25d, 0xb25d, 0xb25d, 0xb25e, 0xb25e, 
+    0xb25f, 0xb25f, 0xb25f, 0xb260, 0xb260, 0xb261, 0xb261, 0xb261, 
+    0xb262, 0xb262, 0xb262, 0xb263, 0xb263, 0xb264, 0xb264, 0xb264, 
+    0xb265, 0xb265, 0xb266, 0xb266, 0xb266, 0xb267, 0xb267, 0xb268, 
+    0xb268, 0xb268, 0xb269, 0xb269, 0xb26a, 0xb26a, 0xb26a, 0xb26b, 
+    0xb26b, 0xb26b, 0xb26c, 0xb26c, 0xb26d, 0xb26d, 0xb26d, 0xb26e, 
+    0xb26e, 0xb26f, 0xb26f, 0xb26f, 0xb270, 0xb270, 0xb271, 0xb271, 
+    0xb271, 0xb272, 0xb272, 0xb273, 0xb273, 0xb273, 0xb274, 0xb274, 
+    0xb274, 0xb275, 0xb275, 0xb276, 0xb276, 0xb276, 0xb277, 0xb277, 
+    0xb278, 0xb278, 0xb278, 0xb279, 0xb279, 0xb279, 0xb27a, 0xb27a, 
+    0xb27b, 0xb27b, 0xb27b, 0xb27c, 0xb27c, 0xb27d, 0xb27d, 0xb27d, 
+    0xb27e, 0xb27e, 0xb27f, 0xb27f, 0xb27f, 0xb280, 0xb280, 0xb280, 
+    0xb281, 0xb281, 0xb282, 0xb282, 0xb282, 0xb283, 0xb283, 0xb284, 
+    0xb284, 0xb284, 0xb285, 0xb285, 0xb285, 0xb286, 0xb286, 0xb287, 
+    0xb287, 0xb287, 0xb288, 0xb288, 0xb288, 0xb289, 0xb289, 0xb28a, 
+    0xb28a, 0xb28a, 0xb28b, 0xb28b, 0xb28c, 0xb28c, 0xb28c, 0xb28d, 
+    0xb28d, 0xb28d, 0xb28e, 0xb28e, 0xb28f, 0xb28f, 0xb28f, 0xb290, 
+    0xb290, 0xb290, 0xb291, 0xb291, 0xb292, 0xb292, 0xb292, 0xb293, 
+    0xb293, 0xb294, 0xb294, 0xb294, 0xb295, 0xb295, 0xb295, 0xb296, 
+    0xb296, 0xb297, 0xb297, 0xb297, 0xb298, 0xb298, 0xb298, 0xb299, 
+    0xb299, 0xb29a, 0xb29a, 0xb29a, 0xb29b, 0xb29b, 0xb29b, 0xb29c, 
+    0xb29c, 0xb29d, 0xb29d, 0xb29d, 0xb29e, 0xb29e, 0xb29e, 0xb29f, 
+    0xb29f, 0xb2a0, 0xb2a1, 0xb2a1, 0xb2a2, 0xb2a3, 0xb2a4, 0xb2a4, 
+    0xb2a5, 0xb2a6, 0xb2a7, 0xb2a7, 0xb2a8, 0xb2a9, 0xb2aa, 0xb2aa, 
+    0xb2ab, 0xb2ac, 0xb2ad, 0xb2ad, 0xb2ae, 0xb2af, 0xb2b0, 0xb2b0, 
+    0xb2b1, 0xb2b2, 0xb2b3, 0xb2b3, 0xb2b4, 0xb2b5, 0xb2b6, 0xb2b6, 
+    0xb2b7, 0xb2b8, 0xb2b9, 0xb2b9, 0xb2ba, 0xb2bb, 0xb2bc, 0xb2bc, 
+    0xb2bd, 0xb2be, 0xb2be, 0xb2bf, 0xb2c0, 0xb2c1, 0xb2c1, 0xb2c2, 
+    0xb2c3, 0xb2c4, 0xb2c4, 0xb2c5, 0xb2c6, 0xb2c7, 0xb2c7, 0xb2c8, 
+    0xb2c9, 0xb2c9, 0xb2ca, 0xb2cb, 0xb2cc, 0xb2cc, 0xb2cd, 0xb2ce, 
+    0xb2cf, 0xb2cf, 0xb2d0, 0xb2d1, 0xb2d2, 0xb2d2, 0xb2d3, 0xb2d4, 
+    0xb2d4, 0xb2d5, 0xb2d6, 0xb2d7, 0xb2d7, 0xb2d8, 0xb2d9, 0xb2d9, 
+    0xb2da, 0xb2db, 0xb2dc, 0xb2dc, 0xb2dd, 0xb2de, 0xb2df, 0xb2df, 
+    0xb2e0, 0xb2e1, 0xb2e1, 0xb2e2, 0xb2e3, 0xb2e4, 0xb2e4, 0xb2e5, 
+    0xb2e6, 0xb2e6, 0xb2e7, 0xb2e8, 0xb2e9, 0xb2e9, 0xb2ea, 0xb2eb, 
+    0xb2eb, 0xb2ec, 0xb2ed, 0xb2ee, 0xb2ee, 0xb2ef, 0xb2f0, 0xb2f0, 
+    0xb2f1, 0xb2f2, 0xb2f3, 0xb2f3, 0xb2f4, 0xb2f5, 0xb2f5, 0xb2f6, 
+    0xb2f7, 0xb2f8, 0xb2f8, 0xb2f9, 0xb2fa, 0xb2fa, 0xb2fb, 0xb2fc, 
+    0xb2fc, 0xb2fd, 0xb2fe, 0xb2ff, 0xb2ff, 0xb300, 0xb301, 0xb301, 
+    0xb302, 0xb303, 0xb304, 0xb304, 0xb305, 0xb306, 0xb306, 0xb307, 
+    0xb308, 0xb308, 0xb309, 0xb30a, 0xb30b, 0xb30b, 0xb30c, 0xb30d, 
+    0xb30d, 0xb30e, 0xb30f, 0xb30f, 0xb310, 0xb311, 0xb311, 0xb312, 
+    0xb313, 0xb314, 0xb314, 0xb315, 0xb316, 0xb316, 0xb317, 0xb318, 
+    0xb318, 0xb319, 0xb31a, 0xb31b, 0xb31b, 0xb31c, 0xb31d, 0xb31d, 
+    0xb31e, 0xb31f, 0xb31f, 0xb320, 0xb321, 0xb321, 0xb322, 0xb323, 
+    0xb323, 0xb324, 0xb325, 0xb326, 0xb326, 0xb327, 0xb328, 0xb328, 
+    0xb329, 0xb32a, 0xb32a, 0xb32b, 0xb32c, 0xb32c, 0xb32d, 0xb32e, 
+    0xb32e, 0xb32f, 0xb330, 0xb330, 0xb331, 0xb332, 0xb333, 0xb333, 
+    0xb334, 0xb335, 0xb335, 0xb336, 0xb337, 0xb337, 0xb338, 0xb339, 
+    0xb339, 0xb33a, 0xb33b, 0xb33b, 0xb33c, 0xb33d, 0xb33d, 0xb33e, 
+    0xb33f, 0xb33f, 0xb340, 0xb341, 0xb341, 0xb342, 0xb343, 0xb343, 
+    0xb344, 0xb345, 0xb345, 0xb346, 0xb347, 0xb347, 0xb348, 0xb349, 
+    0xb34a, 0xb34a, 0xb34b, 0xb34c, 0xb34c, 0xb34d, 0xb34e, 0xb34e, 
+    0xb34f, 0xb350, 0xb350, 0xb351, 0xb352, 0xb352, 0xb353, 0xb354, 
+    0xb354, 0xb355, 0xb356, 0xb356, 0xb357, 0xb358, 0xb358, 0xb359, 
+    0xb35a, 0xb35a, 0xb35b, 0xb35c, 0xb35c, 0xb35d, 0xb35e, 0xb35e, 
+    0xb35f, 0xb35f, 0xb360, 0xb361, 0xb361, 0xb362, 0xb363, 0xb363, 
+    0xb364, 0xb365, 0xb365, 0xb366, 0xb367, 0xb367, 0xb368, 0xb369, 
+    0xb369, 0xb36a, 0xb36b, 0xb36b, 0xb36c, 0xb36d, 0xb36d, 0xb36e, 
+    0xb36f, 0xb36f, 0xb370, 0xb371, 0xb371, 0xb372, 0xb373, 0xb373, 
+    0xb374, 0xb375, 0xb375, 0xb376, 0xb376, 0xb377, 0xb378, 0xb378, 
+    0xb379, 0xb37a, 0xb37a, 0xb37b, 0xb37c, 0xb37c, 0xb37d, 0xb37e, 
+    0xb37e, 0xb37f, 0xb380, 0xb380, 0xb381, 0xb382, 0xb382, 0xb383, 
+    0xb383, 0xb384, 0xb385, 0xb385, 0xb386, 0xb387, 0xb387, 0xb388, 
+    0xb389, 0xb389, 0xb38a, 0xb38b, 0xb38b, 0xb38c, 0xb38c, 0xb38d, 
+    0xb38e, 0xb38e, 0xb38f, 0xb390, 0xb390, 0xb391, 0xb392, 0xb392, 
+    0xb393, 0xb394, 0xb394, 0xb395, 0xb395, 0xb396, 0xb397, 0xb397, 
+    0xb398, 0xb399, 0xb399, 0xb39a, 0xb39b, 0xb39b, 0xb39c, 0xb39c, 
+    0xb39d, 0xb39e, 0xb39e, 0xb39f, 0xb3a0, 0xb3a0, 0xb3a1, 0xb3a2, 
+    0xb3a2, 0xb3a3, 0xb3a3, 0xb3a4, 0xb3a5, 0xb3a5, 0xb3a6, 0xb3a7, 
+    0xb3a7, 0xb3a8, 0xb3a9, 0xb3a9, 0xb3aa, 0xb3aa, 0xb3ab, 0xb3ac, 
+    0xb3ac, 0xb3ad, 0xb3ae, 0xb3ae, 0xb3af, 0xb3af, 0xb3b0, 0xb3b1, 
+    0xb3b1, 0xb3b2, 0xb3b3, 0xb3b3, 0xb3b4, 0xb3b5, 0xb3b5, 0xb3b6, 
+    0xb3b6, 0xb3b7, 0xb3b8, 0xb3b8, 0xb3b9, 0xb3ba, 0xb3ba, 0xb3bb, 
+    0xb3bb, 0xb3bc, 0xb3bd, 0xb3bd, 0xb3be, 0xb3bf, 0xb3bf, 0xb3c0, 
+    0xb3c0, 0xb3c1, 0xb3c2, 0xb3c2, 0xb3c3, 0xb3c3, 0xb3c4, 0xb3c5, 
+    0xb3c5, 0xb3c6, 0xb3c7, 0xb3c7, 0xb3c8, 0xb3c8, 0xb3c9, 0xb3ca, 
+    0xb3ca, 0xb3cb, 0xb3cc, 0xb3cc, 0xb3cd, 0xb3cd, 0xb3ce, 0xb3cf, 
+    0xb3cf, 0xb3d0, 0xb3d1, 0xb3d1, 0xb3d2, 0xb3d2, 0xb3d3, 0xb3d4, 
+    0xb3d4, 0xb3d5, 0xb3d5, 0xb3d6, 0xb3d7, 0xb3d7, 0xb3d8, 0xb3d9, 
+    0xb3d9, 0xb3da, 0xb3da, 0xb3db, 0xb3dc, 0xb3dc, 0xb3dd, 0xb3dd, 
+    0xb3de, 0xb3df, 0xb3df, 0xb3e0, 0xb3e0, 0xb3e1, 0xb3e2, 0xb3e2, 
+    0xb3e3, 0xb3e4, 0xb3e4, 0xb3e5, 0xb3e5, 0xb3e6, 0xb3e7, 0xb3e7, 
+    0xb3e8, 0xb3e8, 0xb3e9, 0xb3ea, 0xb3ea, 0xb3eb, 0xb3eb, 0xb3ec, 
+    0xb3ed, 0xb3ed, 0xb3ee, 0xb3ee, 0xb3ef, 0xb3f0, 0xb3f0, 0xb3f1, 
+    0xb3f1, 0xb3f2, 0xb3f3, 0xb3f3, 0xb3f4, 0xb3f5, 0xb3f5, 0xb3f6, 
+    0xb3f6, 0xb3f7, 0xb3f8, 0xb3f8, 0xb3f9, 0xb3f9, 0xb3fa, 0xb3fb, 
+    0xb3fb, 0xb3fc, 0xb3fc, 0xb3fd, 0xb3fe, 0xb3fe, 0xb3ff, 0xb3ff, 
+    0xb400, 0xb400, 0xb401, 0xb401, 0xb401, 0xb401, 0xb402, 0xb402, 
+    0xb402, 0xb403, 0xb403, 0xb403, 0xb404, 0xb404, 0xb404, 0xb404, 
+    0xb405, 0xb405, 0xb405, 0xb406, 0xb406, 0xb406, 0xb407, 0xb407, 
+    0xb407, 0xb407, 0xb408, 0xb408, 0xb408, 0xb409, 0xb409, 0xb409, 
+    0xb40a, 0xb40a, 0xb40a, 0xb40a, 0xb40b, 0xb40b, 0xb40b, 0xb40c, 
+    0xb40c, 0xb40c, 0xb40c, 0xb40d, 0xb40d, 0xb40d, 0xb40e, 0xb40e, 
+    0xb40e, 0xb40f, 0xb40f, 0xb40f, 0xb40f, 0xb410, 0xb410, 0xb410, 
+    0xb411, 0xb411, 0xb411, 0xb411, 0xb412, 0xb412, 0xb412, 0xb413, 
+    0xb413, 0xb413, 0xb414, 0xb414, 0xb414, 0xb414, 0xb415, 0xb415, 
+    0xb415, 0xb416, 0xb416, 0xb416, 0xb416, 0xb417, 0xb417, 0xb417, 
+    0xb418, 0xb418, 0xb418, 0xb419, 0xb419, 0xb419, 0xb419, 0xb41a, 
+    0xb41a, 0xb41a, 0xb41b, 0xb41b, 0xb41b, 0xb41b, 0xb41c, 0xb41c, 
+    0xb41c, 0xb41d, 0xb41d, 0xb41d, 0xb41d, 0xb41e, 0xb41e, 0xb41e, 
+    0xb41f, 0xb41f, 0xb41f, 0xb41f, 0xb420, 0xb420, 0xb420, 0xb421, 
+    0xb421, 0xb421, 0xb422, 0xb422, 0xb422, 0xb422, 0xb423, 0xb423, 
+    0xb423, 0xb424, 0xb424, 0xb424, 0xb424, 0xb425, 0xb425, 0xb425, 
+    0xb426, 0xb426, 0xb426, 0xb426, 0xb427, 0xb427, 0xb427, 0xb428, 
+    0xb428, 0xb428, 0xb428, 0xb429, 0xb429, 0xb429, 0xb42a, 0xb42a, 
+    0xb42a, 0xb42a, 0xb42b, 0xb42b, 0xb42b, 0xb42c, 0xb42c, 0xb42c, 
+    0xb42c, 0xb42d, 0xb42d, 0xb42d, 0xb42e, 0xb42e, 0xb42e, 0xb42e, 
+    0xb42f, 0xb42f, 0xb42f, 0xb430, 0xb430, 0xb430, 0xb430, 0xb431, 
+    0xb431, 0xb431, 0xb432, 0xb432, 0xb432, 0xb432, 0xb433, 0xb433, 
+    0xb433, 0xb433, 0xb434, 0xb434, 0xb434, 0xb435, 0xb435, 0xb435, 
+    0xb435, 0xb436, 0xb436, 0xb436, 0xb437, 0xb437, 0xb437, 0xb437, 
+    0xb438, 0xb438, 0xb438, 0xb439, 0xb439, 0xb439, 0xb439, 0xb43a, 
+    0xb43a, 0xb43a, 0xb43b, 0xb43b, 0xb43b, 0xb43b, 0xb43c, 0xb43c, 
+    0xb43c, 0xb43c, 0xb43d, 0xb43d, 0xb43d, 0xb43e, 0xb43e, 0xb43e, 
+    0xb43e, 0xb43f, 0xb43f, 0xb43f, 0xb440, 0xb440, 0xb440, 0xb440, 
+    0xb441, 0xb441, 0xb441, 0xb442, 0xb442, 0xb442, 0xb442, 0xb443, 
+    0xb443, 0xb443, 0xb443, 0xb444, 0xb444, 0xb444, 0xb445, 0xb445, 
+    0xb445, 0xb445, 0xb446, 0xb446, 0xb446, 0xb447, 0xb447, 0xb447, 
+    0xb447, 0xb448, 0xb448, 0xb448, 0xb448, 0xb449, 0xb449, 0xb449, 
+    0xb44a, 0xb44a, 0xb44a, 0xb44a, 0xb44b, 0xb44b, 0xb44b, 0xb44b, 
+    0xb44c, 0xb44c, 0xb44c, 0xb44d, 0xb44d, 0xb44d, 0xb44d, 0xb44e, 
+    0xb44e, 0xb44e, 0xb44f, 0xb44f, 0xb44f, 0xb44f, 0xb450, 0xb450, 
+    0xb450, 0xb450, 0xb451, 0xb451, 0xb451, 0xb452, 0xb452, 0xb452, 
+    0xb452, 0xb453, 0xb453, 0xb453, 0xb453, 0xb454, 0xb454, 0xb454, 
+    0xb455, 0xb455, 0xb455, 0xb455, 0xb456, 0xb456, 0xb456, 0xb456, 
+    0xb457, 0xb457, 0xb457, 0xb458, 0xb458, 0xb458, 0xb458, 0xb459, 
+    0xb459, 0xb459, 0xb459, 0xb45a, 0xb45a, 0xb45a, 0xb45b, 0xb45b, 
+    0xb45b, 0xb45b, 0xb45c, 0xb45c, 0xb45c, 0xb45c, 0xb45d, 0xb45d, 
+    0xb45d, 0xb45d, 0xb45e, 0xb45e, 0xb45e, 0xb45f, 0xb45f, 0xb45f, 
+    0xb45f, 0xb460, 0xb460, 0xb460, 0xb460, 0xb461, 0xb461, 0xb461, 
+    0xb462, 0xb462, 0xb462, 0xb462, 0xb463, 0xb463, 0xb463, 0xb463, 
+    0xb464, 0xb464, 0xb464, 0xb464, 0xb465, 0xb465, 0xb465, 0xb466, 
+    0xb466, 0xb466, 0xb466, 0xb467, 0xb467, 0xb467, 0xb467, 0xb468, 
+    0xb468, 0xb468, 0xb468, 0xb469, 0xb469, 0xb469, 0xb46a, 0xb46a, 
+    0xb46a, 0xb46a, 0xb46b, 0xb46b, 0xb46b, 0xb46b, 0xb46c, 0xb46c, 
+    0xb46c, 0xb46c, 0xb46d, 0xb46d, 0xb46d, 0xb46e, 0xb46e, 0xb46e, 
+    0xb46e, 0xb46f, 0xb46f, 0xb46f, 0xb46f, 0xb470, 0xb470, 0xb470, 
+    0xb470, 0xb471, 0xb471, 0xb471, 0xb472, 0xb472, 0xb472, 0xb472, 
+    0xb473, 0xb473, 0xb473, 0xb473, 0xb474, 0xb474, 0xb474, 0xb474, 
+    0xb475, 0xb475, 0xb475, 0xb475, 0xb476, 0xb476, 0xb476, 0xb477, 
+    0xb477, 0xb477, 0xb477, 0xb478, 0xb478, 0xb478, 0xb478, 0xb479, 
+    0xb479, 0xb479, 0xb479, 0xb47a, 0xb47a, 0xb47a, 0xb47a, 0xb47b, 
+    0xb47b, 0xb47b, 0xb47c, 0xb47c, 0xb47c, 0xb47c, 0xb47d, 0xb47d, 
+    0xb47d, 0xb47d, 0xb47e, 0xb47e, 0xb47e, 0xb47e, 0xb47f, 0xb47f, 
+    0xb47f, 0xb47f, 0xb480, 0xb480, 0xb480, 0xb480, 0xb481, 0xb481, 
+    0xb481, 0xb482, 0xb482, 0xb482, 0xb482, 0xb483, 0xb483, 0xb483, 
+    0xb483, 0xb484, 0xb484, 0xb484, 0xb484, 0xb485, 0xb485, 0xb485, 
+    0xb485, 0xb486, 0xb486, 0xb486, 0xb486, 0xb487, 0xb487, 0xb487, 
+    0xb487, 0xb488, 0xb488, 0xb488, 0xb489, 0xb489, 0xb489, 0xb489, 
+    0xb48a, 0xb48a, 0xb48b, 0xb48b, 0xb48c, 0xb48c, 0xb48d, 0xb48d, 
+    0xb48e, 0xb48e, 0xb48f, 0xb48f, 0xb490, 0xb490, 0xb491, 0xb491, 
+    0xb492, 0xb492, 0xb493, 0xb493, 0xb494, 0xb494, 0xb495, 0xb495, 
+    0xb496, 0xb496, 0xb497, 0xb497, 0xb498, 0xb498, 0xb499, 0xb499, 
+    0xb49a, 0xb49a, 0xb49b, 0xb49b, 0xb49c, 0xb49c, 0xb49d, 0xb49d, 
+    0xb49e, 0xb49e, 0xb49f, 0xb49f, 0xb4a0, 0xb4a0, 0xb4a1, 0xb4a1, 
+    0xb4a2, 0xb4a2, 0xb4a3, 0xb4a3, 0xb4a4, 0xb4a4, 0xb4a5, 0xb4a5, 
+    0xb4a6, 0xb4a6, 0xb4a7, 0xb4a7, 0xb4a8, 0xb4a8, 0xb4a9, 0xb4a9, 
+    0xb4aa, 0xb4aa, 0xb4ab, 0xb4ab, 0xb4ac, 0xb4ac, 0xb4ad, 0xb4ad, 
+    0xb4ae, 0xb4ae, 0xb4af, 0xb4af, 0xb4b0, 0xb4b0, 0xb4b1, 0xb4b1, 
+    0xb4b2, 0xb4b2, 0xb4b3, 0xb4b3, 0xb4b4, 0xb4b4, 0xb4b5, 0xb4b5, 
+    0xb4b6, 0xb4b6, 0xb4b7, 0xb4b7, 0xb4b8, 0xb4b8, 0xb4b9, 0xb4b9, 
+    0xb4ba, 0xb4ba, 0xb4bb, 0xb4bb, 0xb4bc, 0xb4bc, 0xb4bd, 0xb4bd, 
+    0xb4be, 0xb4be, 0xb4bf, 0xb4bf, 0xb4c0, 0xb4c0, 0xb4c1, 0xb4c1, 
+    0xb4c2, 0xb4c2, 0xb4c3, 0xb4c3, 0xb4c4, 0xb4c4, 0xb4c5, 0xb4c5, 
+    0xb4c6, 0xb4c6, 0xb4c7, 0xb4c7, 0xb4c7, 0xb4c8, 0xb4c8, 0xb4c9, 
+    0xb4c9, 0xb4ca, 0xb4ca, 0xb4cb, 0xb4cb, 0xb4cc, 0xb4cc, 0xb4cd, 
+    0xb4cd, 0xb4ce, 0xb4ce, 0xb4cf, 0xb4cf, 0xb4d0, 0xb4d0, 0xb4d1, 
+    0xb4d1, 0xb4d2, 0xb4d2, 0xb4d3, 0xb4d3, 0xb4d4, 0xb4d4, 0xb4d4, 
+    0xb4d5, 0xb4d5, 0xb4d6, 0xb4d6, 0xb4d7, 0xb4d7, 0xb4d8, 0xb4d8, 
+    0xb4d9, 0xb4d9, 0xb4da, 0xb4da, 0xb4db, 0xb4db, 0xb4dc, 0xb4dc, 
+    0xb4dd, 0xb4dd, 0xb4de, 0xb4de, 0xb4de, 0xb4df, 0xb4df, 0xb4e0, 
+    0xb4e0, 0xb4e1, 0xb4e1, 0xb4e2, 0xb4e2, 0xb4e3, 0xb4e3, 0xb4e4, 
+    0xb4e4, 0xb4e5, 0xb4e5, 0xb4e6, 0xb4e6, 0xb4e6, 0xb4e7, 0xb4e7, 
+    0xb4e8, 0xb4e8, 0xb4e9, 0xb4e9, 0xb4ea, 0xb4ea, 0xb4eb, 0xb4eb, 
+    0xb4ec, 0xb4ec, 0xb4ed, 0xb4ed, 0xb4ee, 0xb4ee, 0xb4ee, 0xb4ef, 
+    0xb4ef, 0xb4f0, 0xb4f0, 0xb4f1, 0xb4f1, 0xb4f2, 0xb4f2, 0xb4f3, 
+    0xb4f3, 0xb4f4, 0xb4f4, 0xb4f5, 0xb4f5, 0xb4f5, 0xb4f6, 0xb4f6, 
+    0xb4f7, 0xb4f7, 0xb4f8, 0xb4f8, 0xb4f9, 0xb4f9, 0xb4fa, 0xb4fa, 
+    0xb4fb, 0xb4fb, 0xb4fb, 0xb4fc, 0xb4fc, 0xb4fd, 0xb4fd, 0xb4fe, 
+    0xb4fe, 0xb4ff, 0xb4ff, 0xb500, 0xb500, 0xb500, 0xb501, 0xb501, 
+    0xb502, 0xb502, 0xb503, 0xb503, 0xb504, 0xb504, 0xb505, 0xb505, 
+    0xb506, 0xb506, 0xb506, 0xb507, 0xb507, 0xb508, 0xb508, 0xb509, 
+    0xb509, 0xb50a, 0xb50a, 0xb50b, 0xb50b, 0xb50b, 0xb50c, 0xb50c, 
+    0xb50d, 0xb50d, 0xb50e, 0xb50e, 0xb50f, 0xb50f, 0xb510, 0xb510, 
+    0xb510, 0xb511, 0xb511, 0xb512, 0xb512, 0xb513, 0xb513, 0xb514, 
+    0xb514, 0xb514, 0xb515, 0xb515, 0xb516, 0xb516, 0xb517, 0xb517, 
+    0xb518, 0xb518, 0xb519, 0xb519, 0xb519, 0xb51a, 0xb51a, 0xb51b, 
+    0xb51b, 0xb51c, 0xb51c, 0xb51d, 0xb51d, 0xb51d, 0xb51e, 0xb51e, 
+    0xb51f, 0xb51f, 0xb520, 0xb520, 0xb521, 0xb521, 0xb521, 0xb522, 
+    0xb522, 0xb523, 0xb523, 0xb524, 0xb524, 0xb525, 0xb525, 0xb525, 
+    0xb526, 0xb526, 0xb527, 0xb527, 0xb528, 0xb528, 0xb529, 0xb529, 
+    0xb529, 0xb52a, 0xb52a, 0xb52b, 0xb52b, 0xb52c, 0xb52c, 0xb52d, 
+    0xb52d, 0xb52d, 0xb52e, 0xb52e, 0xb52f, 0xb52f, 0xb530, 0xb530, 
+    0xb530, 0xb531, 0xb531, 0xb532, 0xb532, 0xb533, 0xb533, 0xb534, 
+    0xb534, 0xb534, 0xb535, 0xb535, 0xb536, 0xb536, 0xb537, 0xb537, 
+    0xb537, 0xb538, 0xb538, 0xb539, 0xb539, 0xb53a, 0xb53a, 0xb53b, 
+    0xb53b, 0xb53b, 0xb53c, 0xb53c, 0xb53d, 0xb53d, 0xb53e, 0xb53e, 
+    0xb53e, 0xb53f, 0xb53f, 0xb540, 0xb540, 0xb541, 0xb541, 0xb541, 
+    0xb542, 0xb542, 0xb543, 0xb543, 0xb544, 0xb544, 0xb544, 0xb545, 
+    0xb545, 0xb546, 0xb546, 0xb547, 0xb547, 0xb548, 0xb548, 0xb548, 
+    0xb549, 0xb549, 0xb54a, 0xb54a, 0xb54b, 0xb54b, 0xb54b, 0xb54c, 
+    0xb54c, 0xb54d, 0xb54d, 0xb54e, 0xb54e, 0xb54e, 0xb54f, 0xb54f, 
+    0xb550, 0xb550, 0xb551, 0xb551, 0xb551, 0xb552, 0xb552, 0xb553, 
+    0xb553, 0xb553, 0xb554, 0xb554, 0xb555, 0xb555, 0xb556, 0xb556, 
+    0xb556, 0xb557, 0xb557, 0xb558, 0xb558, 0xb559, 0xb559, 0xb559, 
+    0xb55a, 0xb55a, 0xb55b, 0xb55b, 0xb55c, 0xb55c, 0xb55c, 0xb55d, 
+    0xb55d, 0xb55e, 0xb55e, 0xb55e, 0xb55f, 0xb55f, 0xb560, 0xb560, 
+    0xb561, 0xb561, 0xb561, 0xb562, 0xb562, 0xb563, 0xb563, 0xb564, 
+    0xb564, 0xb564, 0xb565, 0xb565, 0xb566, 0xb566, 0xb566, 0xb567, 
+    0xb567, 0xb568, 0xb568, 0xb569, 0xb569, 0xb569, 0xb56a, 0xb56a, 
+    0xb56b, 0xb56b, 0xb56b, 0xb56c, 0xb56c, 0xb56d, 0xb56d, 0xb56e, 
+    0xb56e, 0xb56e, 0xb56f, 0xb56f, 0xb570, 0xb570, 0xb570, 0xb571, 
+    0xb571, 0xb572, 0xb572, 0xb573, 0xb573, 0xb573, 0xb574, 0xb574, 
+    0xb575, 0xb575, 0xb575, 0xb576, 0xb576, 0xb577, 0xb577, 0xb577, 
+    0xb578, 0xb578, 0xb579, 0xb579, 0xb57a, 0xb57a, 0xb57a, 0xb57b, 
+    0xb57b, 0xb57c, 0xb57c, 0xb57c, 0xb57d, 0xb57d, 0xb57e, 0xb57e, 
+    0xb57e, 0xb57f, 0xb57f, 0xb580, 0xb580, 0xb581, 0xb581, 0xb581, 
+    0xb582, 0xb582, 0xb583, 0xb583, 0xb583, 0xb584, 0xb584, 0xb585, 
+    0xb585, 0xb585, 0xb586, 0xb586, 0xb587, 0xb587, 0xb587, 0xb588, 
+    0xb588, 0xb589, 0xb589, 0xb589, 0xb58a, 0xb58a, 0xb58b, 0xb58b, 
+    0xb58c, 0xb58c, 0xb58c, 0xb58d, 0xb58d, 0xb58e, 0xb58e, 0xb58e, 
+    0xb58f, 0xb58f, 0xb590, 0xb590, 0xb590, 0xb591, 0xb591, 0xb592, 
+    0xb592, 0xb592, 0xb593, 0xb593, 0xb594, 0xb594, 0xb594, 0xb595, 
+    0xb595, 0xb596, 0xb596, 0xb596, 0xb597, 0xb597, 0xb598, 0xb598, 
+    0xb598, 0xb599, 0xb599, 0xb59a, 0xb59a, 0xb59a, 0xb59b, 0xb59b, 
+    0xb59c, 0xb59c, 0xb59c, 0xb59d, 0xb59d, 0xb59e, 0xb59e, 0xb59e, 
+    0xb59f, 0xb59f, 0xb5a0, 0xb5a0, 0xb5a0, 0xb5a1, 0xb5a1, 0xb5a2, 
+    0xb5a2, 0xb5a2, 0xb5a3, 0xb5a3, 0xb5a4, 0xb5a4, 0xb5a4, 0xb5a5, 
+    0xb5a5, 0xb5a6, 0xb5a6, 0xb5a6, 0xb5a7, 0xb5a7, 0xb5a8, 0xb5a8, 
+    0xb5a8, 0xb5a9, 0xb5a9, 0xb5aa, 0xb5aa, 0xb5aa, 0xb5ab, 0xb5ab, 
+    0xb5ac, 0xb5ac, 0xb5ac, 0xb5ad, 0xb5ad, 0xb5ad, 0xb5ae, 0xb5ae, 
+    0xb5af, 0xb5af, 0xb5af, 0xb5b0, 0xb5b0, 0xb5b1, 0xb5b1, 0xb5b1, 
+    0xb5b2, 0xb5b2, 0xb5b3, 0xb5b3, 0xb5b3, 0xb5b4, 0xb5b4, 0xb5b5, 
+    0xb5b5, 0xb5b5, 0xb5b6, 0xb5b6, 0xb5b7, 0xb5b7, 0xb5b7, 0xb5b8, 
+    0xb5b8, 0xb5b8, 0xb5b9, 0xb5b9, 0xb5ba, 0xb5ba, 0xb5ba, 0xb5bb, 
+    0xb5bb, 0xb5bc, 0xb5bc, 0xb5bc, 0xb5bd, 0xb5bd, 0xb5be, 0xb5be, 
+    0xb5be, 0xb5bf, 0xb5bf, 0xb5bf, 0xb5c0, 0xb5c0, 0xb5c1, 0xb5c1, 
+    0xb5c1, 0xb5c2, 0xb5c2, 0xb5c3, 0xb5c3, 0xb5c3, 0xb5c4, 0xb5c4, 
+    0xb5c5, 0xb5c5, 0xb5c5, 0xb5c6, 0xb5c6, 0xb5c6, 0xb5c7, 0xb5c7, 
+    0xb5c8, 0xb5c8, 0xb5c8, 0xb5c9, 0xb5c9, 0xb5ca, 0xb5ca, 0xb5ca, 
+    0xb5cb, 0xb5cb, 0xb5cb, 0xb5cc, 0xb5cc, 0xb5cd, 0xb5cd, 0xb5cd, 
+    0xb5ce, 0xb5ce, 0xb5cf, 0xb5cf, 0xb5cf, 0xb5d0, 0xb5d0, 0xb5d0, 
+    0xb5d1, 0xb5d1, 0xb5d2, 0xb5d2, 0xb5d2, 0xb5d3, 0xb5d3, 0xb5d3, 
+    0xb5d4, 0xb5d4, 0xb5d5, 0xb5d5, 0xb5d5, 0xb5d6, 0xb5d6, 0xb5d7, 
+    0xb5d7, 0xb5d7, 0xb5d8, 0xb5d8, 0xb5d8, 0xb5d9, 0xb5d9, 0xb5da, 
+    0xb5da, 0xb5da, 0xb5db, 0xb5db, 0xb5db, 0xb5dc, 0xb5dc, 0xb5dd, 
+    0xb5dd, 0xb5dd, 0xb5de, 0xb5de, 0xb5df, 0xb5df, 0xb5df, 0xb5e0, 
+    0xb5e0, 0xb5e0, 0xb5e1, 0xb5e1, 0xb5e2, 0xb5e2, 0xb5e2, 0xb5e3, 
+    0xb5e3, 0xb5e3, 0xb5e4, 0xb5e4, 0xb5e5, 0xb5e5, 0xb5e5, 0xb5e6, 
+    0xb5e6, 0xb5e6, 0xb5e7, 0xb5e7, 0xb5e8, 0xb5e8, 0xb5e8, 0xb5e9, 
+    0xb5e9, 0xb5e9, 0xb5ea, 0xb5ea, 0xb5eb, 0xb5eb, 0xb5eb, 0xb5ec, 
+    0xb5ec, 0xb5ec, 0xb5ed, 0xb5ed, 0xb5ee, 0xb5ee, 0xb5ee, 0xb5ef, 
+    0xb5ef, 0xb5ef, 0xb5f0, 0xb5f0, 0xb5f1, 0xb5f1, 0xb5f1, 0xb5f2, 
+    0xb5f2, 0xb5f2, 0xb5f3, 0xb5f3, 0xb5f4, 0xb5f4, 0xb5f4, 0xb5f5, 
+    0xb5f5, 0xb5f5, 0xb5f6, 0xb5f6, 0xb5f7, 0xb5f7, 0xb5f7, 0xb5f8, 
+    0xb5f8, 0xb5f8, 0xb5f9, 0xb5f9, 0xb5f9, 0xb5fa, 0xb5fa, 0xb5fb, 
+    0xb5fb, 0xb5fb, 0xb5fc, 0xb5fc, 0xb5fc, 0xb5fd, 0xb5fd, 0xb5fe, 
+    0xb5fe, 0xb5fe, 0xb5ff, 0xb5ff, 0xb5ff, 0xb600, 0xb600, 0xb601, 
+    0xb601, 0xb601, 0xb602, 0xb602, 0xb602, 0xb603, 0xb603, 0xb603, 
+    0xb604, 0xb604, 0xb605, 0xb605, 0xb605, 0xb606, 0xb606, 0xb606, 
+    0xb607, 0xb607, 0xb607, 0xb608, 0xb608, 0xb609, 0xb609, 0xb609, 
+    0xb60a, 0xb60a, 0xb60a, 0xb60b, 0xb60b, 0xb60c, 0xb60c, 0xb60c, 
+    0xb60d, 0xb60d, 0xb60d, 0xb60e, 0xb60e, 0xb60e, 0xb60f, 0xb60f, 
+    0xb610, 0xb610, 0xb610, 0xb611, 0xb611, 0xb611, 0xb612, 0xb612, 
+    0xb612, 0xb613, 0xb613, 0xb614, 0xb614, 0xb614, 0xb615, 0xb615, 
+    0xb615, 0xb616, 0xb616, 0xb616, 0xb617, 0xb617, 0xb618, 0xb618, 
+    0xb618, 0xb619, 0xb619, 0xb619, 0xb61a, 0xb61a, 0xb61a, 0xb61b, 
+    0xb61b, 0xb61c, 0xb61c, 0xb61c, 0xb61d, 0xb61d, 0xb61d, 0xb61e, 
+    0xb61e, 0xb61e, 0xb61f, 0xb61f, 0xb61f, 0xb620, 0xb620, 0xb621, 
+    0xb621, 0xb621, 0xb622, 0xb622, 0xb622, 0xb623, 0xb623, 0xb623, 
+    0xb624, 0xb624, 0xb624, 0xb625, 0xb625, 0xb626, 0xb626, 0xb626, 
+    0xb627, 0xb627, 0xb627, 0xb628, 0xb628, 0xb628, 0xb629, 0xb629, 
+    0xb62a, 0xb62a, 0xb62a, 0xb62b, 0xb62b, 0xb62b, 0xb62c, 0xb62c, 
+    0xb62c, 0xb62d, 0xb62d, 0xb62d, 0xb62e, 0xb62e, 0xb62e, 0xb62f, 
+    0xb62f, 0xb630, 0xb630, 0xb630, 0xb631, 0xb631, 0xb631, 0xb632, 
+    0xb632, 0xb632, 0xb633, 0xb633, 0xb633, 0xb634, 0xb634, 0xb635, 
+    0xb635, 0xb635, 0xb636, 0xb636, 0xb636, 0xb637, 0xb637, 0xb637, 
+    0xb638, 0xb638, 0xb639, 0xb63a, 0xb63b, 0xb63b, 0xb63c, 0xb63d, 
+    0xb63d, 0xb63e, 0xb63f, 0xb63f, 0xb640, 0xb641, 0xb642, 0xb642, 
+    0xb643, 0xb644, 0xb644, 0xb645, 0xb646, 0xb646, 0xb647, 0xb648, 
+    0xb649, 0xb649, 0xb64a, 0xb64b, 0xb64b, 0xb64c, 0xb64d, 0xb64d, 
+    0xb64e, 0xb64f, 0xb650, 0xb650, 0xb651, 0xb652, 0xb652, 0xb653, 
+    0xb654, 0xb654, 0xb655, 0xb656, 0xb656, 0xb657, 0xb658, 0xb659, 
+    0xb659, 0xb65a, 0xb65b, 0xb65b, 0xb65c, 0xb65d, 0xb65d, 0xb65e, 
+    0xb65f, 0xb65f, 0xb660, 0xb661, 0xb661, 0xb662, 0xb663, 0xb664, 
+    0xb664, 0xb665, 0xb666, 0xb666, 0xb667, 0xb668, 0xb668, 0xb669, 
+    0xb66a, 0xb66a, 0xb66b, 0xb66c, 0xb66c, 0xb66d, 0xb66e, 0xb66e, 
+    0xb66f, 0xb670, 0xb670, 0xb671, 0xb672, 0xb672, 0xb673, 0xb674, 
+    0xb674, 0xb675, 0xb676, 0xb677, 0xb677, 0xb678, 0xb679, 0xb679, 
+    0xb67a, 0xb67b, 0xb67b, 0xb67c, 0xb67d, 0xb67d, 0xb67e, 0xb67f, 
+    0xb67f, 0xb680, 0xb681, 0xb681, 0xb682, 0xb683, 0xb683, 0xb684, 
+    0xb685, 0xb685, 0xb686, 0xb687, 0xb687, 0xb688, 0xb689, 0xb689, 
+    0xb68a, 0xb68b, 0xb68b, 0xb68c, 0xb68d, 0xb68d, 0xb68e, 0xb68f, 
+    0xb68f, 0xb690, 0xb691, 0xb691, 0xb692, 0xb693, 0xb693, 0xb694, 
+    0xb695, 0xb695, 0xb696, 0xb697, 0xb697, 0xb698, 0xb698, 0xb699, 
+    0xb69a, 0xb69a, 0xb69b, 0xb69c, 0xb69c, 0xb69d, 0xb69e, 0xb69e, 
+    0xb69f, 0xb6a0, 0xb6a0, 0xb6a1, 0xb6a2, 0xb6a2, 0xb6a3, 0xb6a4, 
+    0xb6a4, 0xb6a5, 0xb6a6, 0xb6a6, 0xb6a7, 0xb6a8, 0xb6a8, 0xb6a9, 
+    0xb6aa, 0xb6aa, 0xb6ab, 0xb6ab, 0xb6ac, 0xb6ad, 0xb6ad, 0xb6ae, 
+    0xb6af, 0xb6af, 0xb6b0, 0xb6b1, 0xb6b1, 0xb6b2, 0xb6b3, 0xb6b3, 
+    0xb6b4, 0xb6b5, 0xb6b5, 0xb6b6, 0xb6b6, 0xb6b7, 0xb6b8, 0xb6b8, 
+    0xb6b9, 0xb6ba, 0xb6ba, 0xb6bb, 0xb6bc, 0xb6bc, 0xb6bd, 0xb6be, 
+    0xb6be, 0xb6bf, 0xb6bf, 0xb6c0, 0xb6c1, 0xb6c1, 0xb6c2, 0xb6c3, 
+    0xb6c3, 0xb6c4, 0xb6c5, 0xb6c5, 0xb6c6, 0xb6c6, 0xb6c7, 0xb6c8, 
+    0xb6c8, 0xb6c9, 0xb6ca, 0xb6ca, 0xb6cb, 0xb6cc, 0xb6cc, 0xb6cd, 
+    0xb6cd, 0xb6ce, 0xb6cf, 0xb6cf, 0xb6d0, 0xb6d1, 0xb6d1, 0xb6d2, 
+    0xb6d3, 0xb6d3, 0xb6d4, 0xb6d4, 0xb6d5, 0xb6d6, 0xb6d6, 0xb6d7, 
+    0xb6d8, 0xb6d8, 0xb6d9, 0xb6d9, 0xb6da, 0xb6db, 0xb6db, 0xb6dc, 
+    0xb6dd, 0xb6dd, 0xb6de, 0xb6de, 0xb6df, 0xb6e0, 0xb6e0, 0xb6e1, 
+    0xb6e2, 0xb6e2, 0xb6e3, 0xb6e4, 0xb6e4, 0xb6e5, 0xb6e5, 0xb6e6, 
+    0xb6e7, 0xb6e7, 0xb6e8, 0xb6e8, 0xb6e9, 0xb6ea, 0xb6ea, 0xb6eb, 
+    0xb6ec, 0xb6ec, 0xb6ed, 0xb6ed, 0xb6ee, 0xb6ef, 0xb6ef, 0xb6f0, 
+    0xb6f1, 0xb6f1, 0xb6f2, 0xb6f2, 0xb6f3, 0xb6f4, 0xb6f4, 0xb6f5, 
+    0xb6f6, 0xb6f6, 0xb6f7, 0xb6f7, 0xb6f8, 0xb6f9, 0xb6f9, 0xb6fa, 
+    0xb6fa, 0xb6fb, 0xb6fc, 0xb6fc, 0xb6fd, 0xb6fe, 0xb6fe, 0xb6ff, 
+    0xb6ff, 0xb700, 0xb701, 0xb701, 0xb702, 0xb702, 0xb703, 0xb704, 
+    0xb704, 0xb705, 0xb705, 0xb706, 0xb707, 0xb707, 0xb708, 0xb709, 
+    0xb709, 0xb70a, 0xb70a, 0xb70b, 0xb70c, 0xb70c, 0xb70d, 0xb70d, 
+    0xb70e, 0xb70f, 0xb70f, 0xb710, 0xb710, 0xb711, 0xb712, 0xb712, 
+    0xb713, 0xb713, 0xb714, 0xb715, 0xb715, 0xb716, 0xb716, 0xb717, 
+    0xb718, 0xb718, 0xb719, 0xb719, 0xb71a, 0xb71b, 0xb71b, 0xb71c, 
+    0xb71d, 0xb71d, 0xb71e, 0xb71e, 0xb71f, 0xb720, 0xb720, 0xb721, 
+    0xb721, 0xb722, 0xb723, 0xb723, 0xb724, 0xb724, 0xb725, 0xb725, 
+    0xb726, 0xb727, 0xb727, 0xb728, 0xb728, 0xb729, 0xb72a, 0xb72a, 
+    0xb72b, 0xb72b, 0xb72c, 0xb72d, 0xb72d, 0xb72e, 0xb72e, 0xb72f, 
+    0xb730, 0xb730, 0xb731, 0xb731, 0xb732, 0xb733, 0xb733, 0xb734, 
+    0xb734, 0xb735, 0xb736, 0xb736, 0xb737, 0xb737, 0xb738, 0xb739, 
+    0xb739, 0xb73a, 0xb73a, 0xb73b, 0xb73b, 0xb73c, 0xb73d, 0xb73d, 
+    0xb73e, 0xb73e, 0xb73f, 0xb740, 0xb740, 0xb741, 0xb741, 0xb742, 
+    0xb743, 0xb743, 0xb744, 0xb744, 0xb745, 0xb745, 0xb746, 0xb747, 
+    0xb747, 0xb748, 0xb748, 0xb749, 0xb74a, 0xb74a, 0xb74b, 0xb74b, 
+    0xb74c, 0xb74c, 0xb74d, 0xb74e, 0xb74e, 0xb74f, 0xb74f, 0xb750, 
+    0xb751, 0xb751, 0xb752, 0xb752, 0xb753, 0xb753, 0xb754, 0xb755, 
+    0xb755, 0xb756, 0xb756, 0xb757, 0xb757, 0xb758, 0xb759, 0xb759, 
+    0xb75a, 0xb75a, 0xb75b, 0xb75c, 0xb75c, 0xb75d, 0xb75d, 0xb75e, 
+    0xb75e, 0xb75f, 0xb760, 0xb760, 0xb761, 0xb761, 0xb762, 0xb762, 
+    0xb763, 0xb764, 0xb764, 0xb765, 0xb765, 0xb766, 0xb766, 0xb767, 
+    0xb768, 0xb768, 0xb769, 0xb769, 0xb76a, 0xb76a, 0xb76b, 0xb76c, 
+    0xb76c, 0xb76d, 0xb76d, 0xb76e, 0xb76e, 0xb76f, 0xb770, 0xb770, 
+    0xb771, 0xb771, 0xb772, 0xb772, 0xb773, 0xb774, 0xb774, 0xb775, 
+    0xb775, 0xb776, 0xb776, 0xb777, 0xb778, 0xb778, 0xb779, 0xb779, 
+    0xb77a, 0xb77a, 0xb77b, 0xb77c, 0xb77c, 0xb77d, 0xb77d, 0xb77e, 
+    0xb77e, 0xb77f, 0xb77f, 0xb780, 0xb781, 0xb781, 0xb782, 0xb782, 
+    0xb783, 0xb783, 0xb784, 0xb785, 0xb785, 0xb786, 0xb786, 0xb787, 
+    0xb787, 0xb788, 0xb788, 0xb789, 0xb78a, 0xb78a, 0xb78b, 0xb78b, 
+    0xb78c, 0xb78c, 0xb78d, 0xb78e, 0xb78e, 0xb78f, 0xb78f, 0xb790, 
+    0xb790, 0xb791, 0xb791, 0xb792, 0xb793, 0xb793, 0xb794, 0xb794, 
+    0xb795, 0xb795, 0xb796, 0xb796, 0xb797, 0xb798, 0xb798, 0xb799, 
+    0xb799, 0xb79a, 0xb79a, 0xb79b, 0xb79b, 0xb79c, 0xb79d, 0xb79d, 
+    0xb79e, 0xb79e, 0xb79f, 0xb79f, 0xb7a0, 0xb7a0, 0xb7a1, 0xb7a2, 
+    0xb7a2, 0xb7a3, 0xb7a3, 0xb7a4, 0xb7a4, 0xb7a5, 0xb7a5, 0xb7a6, 
+    0xb7a7, 0xb7a7, 0xb7a8, 0xb7a8, 0xb7a9, 0xb7a9, 0xb7aa, 0xb7aa, 
+    0xb7ab, 0xb7ab, 0xb7ac, 0xb7ad, 0xb7ad, 0xb7ae, 0xb7ae, 0xb7af, 
+    0xb7af, 0xb7b0, 0xb7b0, 0xb7b1, 0xb7b2, 0xb7b2, 0xb7b3, 0xb7b3, 
+    0xb7b4, 0xb7b4, 0xb7b5, 0xb7b5, 0xb7b6, 0xb7b6, 0xb7b7, 0xb7b8, 
+    0xb7b8, 0xb7b9, 0xb7b9, 0xb7ba, 0xb7ba, 0xb7bb, 0xb7bb, 0xb7bc, 
+    0xb7bc, 0xb7bd, 0xb7bd, 0xb7be, 0xb7bf, 0xb7bf, 0xb7c0, 0xb7c0, 
+    0xb7c1, 0xb7c1, 0xb7c2, 0xb7c2, 0xb7c3, 0xb7c3, 0xb7c4, 0xb7c5, 
+    0xb7c5, 0xb7c6, 0xb7c6, 0xb7c7, 0xb7c7, 0xb7c8, 0xb7c8, 0xb7c9, 
+    0xb7c9, 0xb7ca, 0xb7ca, 0xb7cb, 0xb7cc, 0xb7cc, 0xb7cd, 0xb7cd, 
+    0xb7ce, 0xb7ce, 0xb7cf, 0xb7cf, 0xb7d0, 0xb7d0, 0xb7d1, 0xb7d1, 
+    0xb7d2, 0xb7d3, 0xb7d3, 0xb7d4, 0xb7d4, 0xb7d5, 0xb7d5, 0xb7d6, 
+    0xb7d6, 0xb7d7, 0xb7d7, 0xb7d8, 0xb7d8, 0xb7d9, 0xb7da, 0xb7da, 
+    0xb7db, 0xb7db, 0xb7dc, 0xb7dc, 0xb7dd, 0xb7dd, 0xb7de, 0xb7de, 
+    0xb7df, 0xb7df, 0xb7e0, 0xb7e0, 0xb7e1, 0xb7e2, 0xb7e2, 0xb7e3, 
+    0xb7e3, 0xb7e4, 0xb7e4, 0xb7e5, 0xb7e5, 0xb7e6, 0xb7e6, 0xb7e7, 
+    0xb7e7, 0xb7e8, 0xb7e8, 0xb7e9, 0xb7e9, 0xb7ea, 0xb7eb, 0xb7eb, 
+    0xb7ec, 0xb7ec, 0xb7ed, 0xb7ed, 0xb7ee, 0xb7ee, 0xb7ef, 0xb7ef, 
+    0xb7f0, 0xb7f0, 0xb7f1, 0xb7f1, 0xb7f2, 0xb7f2, 0xb7f3, 0xb7f3, 
+    0xb7f4, 0xb7f5, 0xb7f5, 0xb7f6, 0xb7f6, 0xb7f7, 0xb7f7, 0xb7f8, 
+    0xb7f8, 0xb7f9, 0xb7f9, 0xb7fa, 0xb7fa, 0xb7fb, 0xb7fb, 0xb7fc, 
+    0xb7fc, 0xb7fd, 0xb7fd, 0xb7fe, 0xb7fe, 0xb7ff, 0xb800, 0xb800, 
+    0xb800, 0xb801, 0xb801, 0xb801, 0xb801, 0xb802, 0xb802, 0xb802, 
+    0xb802, 0xb803, 0xb803, 0xb803, 0xb803, 0xb804, 0xb804, 0xb804, 
+    0xb804, 0xb805, 0xb805, 0xb805, 0xb805, 0xb806, 0xb806, 0xb806, 
+    0xb807, 0xb807, 0xb807, 0xb807, 0xb808, 0xb808, 0xb808, 0xb808, 
+    0xb809, 0xb809, 0xb809, 0xb809, 0xb80a, 0xb80a, 0xb80a, 0xb80a, 
+    0xb80b, 0xb80b, 0xb80b, 0xb80b, 0xb80c, 0xb80c, 0xb80c, 0xb80c, 
+    0xb80d, 0xb80d, 0xb80d, 0xb80d, 0xb80e, 0xb80e, 0xb80e, 0xb80f, 
+    0xb80f, 0xb80f, 0xb80f, 0xb810, 0xb810, 0xb810, 0xb810, 0xb811, 
+    0xb811, 0xb811, 0xb811, 0xb812, 0xb812, 0xb812, 0xb812, 0xb813, 
+    0xb813, 0xb813, 0xb813, 0xb814, 0xb814, 0xb814, 0xb814, 0xb815, 
+    0xb815, 0xb815, 0xb815, 0xb816, 0xb816, 0xb816, 0xb816, 0xb817, 
+    0xb817, 0xb817, 0xb817, 0xb818, 0xb818, 0xb818, 0xb818, 0xb819, 
+    0xb819, 0xb819, 0xb819, 0xb81a, 0xb81a, 0xb81a, 0xb81b, 0xb81b, 
+    0xb81b, 0xb81b, 0xb81c, 0xb81c, 0xb81c, 0xb81c, 0xb81d, 0xb81d, 
+    0xb81d, 0xb81d, 0xb81e, 0xb81e, 0xb81e, 0xb81e, 0xb81f, 0xb81f, 
+    0xb81f, 0xb81f, 0xb820, 0xb820, 0xb820, 0xb820, 0xb821, 0xb821, 
+    0xb821, 0xb821, 0xb822, 0xb822, 0xb822, 0xb822, 0xb823, 0xb823, 
+    0xb823, 0xb823, 0xb824, 0xb824, 0xb824, 0xb824, 0xb825, 0xb825, 
+    0xb825, 0xb825, 0xb826, 0xb826, 0xb826, 0xb826, 0xb827, 0xb827, 
+    0xb827, 0xb827, 0xb828, 0xb828, 0xb828, 0xb828, 0xb829, 0xb829, 
+    0xb829, 0xb829, 0xb82a, 0xb82a, 0xb82a, 0xb82a, 0xb82b, 0xb82b, 
+    0xb82b, 0xb82b, 0xb82c, 0xb82c, 0xb82c, 0xb82c, 0xb82d, 0xb82d, 
+    0xb82d, 0xb82d, 0xb82e, 0xb82e, 0xb82e, 0xb82e, 0xb82f, 0xb82f, 
+    0xb82f, 0xb82f, 0xb830, 0xb830, 0xb830, 0xb830, 0xb831, 0xb831, 
+    0xb831, 0xb831, 0xb831, 0xb832, 0xb832, 0xb832, 0xb832, 0xb833, 
+    0xb833, 0xb833, 0xb833, 0xb834, 0xb834, 0xb834, 0xb834, 0xb835, 
+    0xb835, 0xb835, 0xb835, 0xb836, 0xb836, 0xb836, 0xb836, 0xb837, 
+    0xb837, 0xb837, 0xb837, 0xb838, 0xb838, 0xb838, 0xb838, 0xb839, 
+    0xb839, 0xb839, 0xb839, 0xb83a, 0xb83a, 0xb83a, 0xb83a, 0xb83b, 
+    0xb83b, 0xb83b, 0xb83b, 0xb83c, 0xb83c, 0xb83c, 0xb83c, 0xb83d, 
+    0xb83d, 0xb83d, 0xb83d, 0xb83e, 0xb83e, 0xb83e, 0xb83e, 0xb83e, 
+    0xb83f, 0xb83f, 0xb83f, 0xb83f, 0xb840, 0xb840, 0xb840, 0xb840, 
+    0xb841, 0xb841, 0xb841, 0xb841, 0xb842, 0xb842, 0xb842, 0xb842, 
+    0xb843, 0xb843, 0xb844, 0xb844, 0xb845, 0xb845, 0xb846, 0xb846, 
+    0xb846, 0xb847, 0xb847, 0xb848, 0xb848, 0xb849, 0xb849, 0xb84a, 
+    0xb84a, 0xb84b, 0xb84b, 0xb84c, 0xb84c, 0xb84d, 0xb84d, 0xb84e, 
+    0xb84e, 0xb84f, 0xb84f, 0xb850, 0xb850, 0xb851, 0xb851, 0xb851, 
+    0xb852, 0xb852, 0xb853, 0xb853, 0xb854, 0xb854, 0xb855, 0xb855, 
+    0xb856, 0xb856, 0xb857, 0xb857, 0xb858, 0xb858, 0xb859, 0xb859, 
+    0xb85a, 0xb85a, 0xb85a, 0xb85b, 0xb85b, 0xb85c, 0xb85c, 0xb85d, 
+    0xb85d, 0xb85e, 0xb85e, 0xb85f, 0xb85f, 0xb860, 0xb860, 0xb861, 
+    0xb861, 0xb862, 0xb862, 0xb862, 0xb863, 0xb863, 0xb864, 0xb864, 
+    0xb865, 0xb865, 0xb866, 0xb866, 0xb867, 0xb867, 0xb868, 0xb868, 
+    0xb869, 0xb869, 0xb869, 0xb86a, 0xb86a, 0xb86b, 0xb86b, 0xb86c, 
+    0xb86c, 0xb86d, 0xb86d, 0xb86e, 0xb86e, 0xb86f, 0xb86f, 0xb86f, 
+    0xb870, 0xb870, 0xb871, 0xb871, 0xb872, 0xb872, 0xb873, 0xb873, 
+    0xb874, 0xb874, 0xb875, 0xb875, 0xb875, 0xb876, 0xb876, 0xb877, 
+    0xb877, 0xb878, 0xb878, 0xb879, 0xb879, 0xb87a, 0xb87a, 0xb87a, 
+    0xb87b, 0xb87b, 0xb87c, 0xb87c, 0xb87d, 0xb87d, 0xb87e, 0xb87e, 
+    0xb87f, 0xb87f, 0xb87f, 0xb880, 0xb880, 0xb881, 0xb881, 0xb882, 
+    0xb882, 0xb883, 0xb883, 0xb884, 0xb884, 0xb884, 0xb885, 0xb885, 
+    0xb886, 0xb886, 0xb887, 0xb887, 0xb888, 0xb888, 0xb889, 0xb889, 
+    0xb889, 0xb88a, 0xb88a, 0xb88b, 0xb88b, 0xb88c, 0xb88c, 0xb88d, 
+    0xb88d, 0xb88d, 0xb88e, 0xb88e, 0xb88f, 0xb88f, 0xb890, 0xb890, 
+    0xb891, 0xb891, 0xb891, 0xb892, 0xb892, 0xb893, 0xb893, 0xb894, 
+    0xb894, 0xb895, 0xb895, 0xb895, 0xb896, 0xb896, 0xb897, 0xb897, 
+    0xb898, 0xb898, 0xb899, 0xb899, 0xb899, 0xb89a, 0xb89a, 0xb89b, 
+    0xb89b, 0xb89c, 0xb89c, 0xb89d, 0xb89d, 0xb89d, 0xb89e, 0xb89e, 
+    0xb89f, 0xb89f, 0xb8a0, 0xb8a0, 0xb8a0, 0xb8a1, 0xb8a1, 0xb8a2, 
+    0xb8a2, 0xb8a3, 0xb8a3, 0xb8a4, 0xb8a4, 0xb8a4, 0xb8a5, 0xb8a5, 
+    0xb8a6, 0xb8a6, 0xb8a7, 0xb8a7, 0xb8a7, 0xb8a8, 0xb8a8, 0xb8a9, 
+    0xb8a9, 0xb8aa, 0xb8aa, 0xb8ab, 0xb8ab, 0xb8ab, 0xb8ac, 0xb8ac, 
+    0xb8ad, 0xb8ad, 0xb8ae, 0xb8ae, 0xb8ae, 0xb8af, 0xb8af, 0xb8b0, 
+    0xb8b0, 0xb8b1, 0xb8b1, 0xb8b1, 0xb8b2, 0xb8b2, 0xb8b3, 0xb8b3, 
+    0xb8b4, 0xb8b4, 0xb8b4, 0xb8b5, 0xb8b5, 0xb8b6, 0xb8b6, 0xb8b7, 
+    0xb8b7, 0xb8b7, 0xb8b8, 0xb8b8, 0xb8b9, 0xb8b9, 0xb8ba, 0xb8ba, 
+    0xb8ba, 0xb8bb, 0xb8bb, 0xb8bc, 0xb8bc, 0xb8bd, 0xb8bd, 0xb8bd, 
+    0xb8be, 0xb8be, 0xb8bf, 0xb8bf, 0xb8c0, 0xb8c0, 0xb8c0, 0xb8c1, 
+    0xb8c1, 0xb8c2, 0xb8c2, 0xb8c3, 0xb8c3, 0xb8c3, 0xb8c4, 0xb8c4, 
+    0xb8c5, 0xb8c5, 0xb8c5, 0xb8c6, 0xb8c6, 0xb8c7, 0xb8c7, 0xb8c8, 
+    0xb8c8, 0xb8c8, 0xb8c9, 0xb8c9, 0xb8ca, 0xb8ca, 0xb8cb, 0xb8cb, 
+    0xb8cb, 0xb8cc, 0xb8cc, 0xb8cd, 0xb8cd, 0xb8cd, 0xb8ce, 0xb8ce, 
+    0xb8cf, 0xb8cf, 0xb8d0, 0xb8d0, 0xb8d0, 0xb8d1, 0xb8d1, 0xb8d2, 
+    0xb8d2, 0xb8d3, 0xb8d3, 0xb8d3, 0xb8d4, 0xb8d4, 0xb8d5, 0xb8d5, 
+    0xb8d5, 0xb8d6, 0xb8d6, 0xb8d7, 0xb8d7, 0xb8d8, 0xb8d8, 0xb8d8, 
+    0xb8d9, 0xb8d9, 0xb8da, 0xb8da, 0xb8da, 0xb8db, 0xb8db, 0xb8dc, 
+    0xb8dc, 0xb8dc, 0xb8dd, 0xb8dd, 0xb8de, 0xb8de, 0xb8df, 0xb8df, 
+    0xb8df, 0xb8e0, 0xb8e0, 0xb8e1, 0xb8e1, 0xb8e1, 0xb8e2, 0xb8e2, 
+    0xb8e3, 0xb8e3, 0xb8e3, 0xb8e4, 0xb8e4, 0xb8e5, 0xb8e5, 0xb8e6, 
+    0xb8e6, 0xb8e6, 0xb8e7, 0xb8e7, 0xb8e8, 0xb8e8, 0xb8e8, 0xb8e9, 
+    0xb8e9, 0xb8ea, 0xb8ea, 0xb8ea, 0xb8eb, 0xb8eb, 0xb8ec, 0xb8ec, 
+    0xb8ec, 0xb8ed, 0xb8ed, 0xb8ee, 0xb8ee, 0xb8ee, 0xb8ef, 0xb8ef, 
+    0xb8f0, 0xb8f0, 0xb8f1, 0xb8f1, 0xb8f1, 0xb8f2, 0xb8f2, 0xb8f3, 
+    0xb8f3, 0xb8f3, 0xb8f4, 0xb8f4, 0xb8f5, 0xb8f5, 0xb8f5, 0xb8f6, 
+    0xb8f6, 0xb8f7, 0xb8f7, 0xb8f7, 0xb8f8, 0xb8f8, 0xb8f9, 0xb8f9, 
+    0xb8f9, 0xb8fa, 0xb8fa, 0xb8fb, 0xb8fb, 0xb8fb, 0xb8fc, 0xb8fc, 
+    0xb8fd, 0xb8fd, 0xb8fd, 0xb8fe, 0xb8fe, 0xb8ff, 0xb8ff, 0xb8ff, 
+    0xb900, 0xb900, 0xb901, 0xb901, 0xb901, 0xb902, 0xb902, 0xb903, 
+    0xb903, 0xb903, 0xb904, 0xb904, 0xb905, 0xb905, 0xb905, 0xb906, 
+    0xb906, 0xb907, 0xb907, 0xb907, 0xb908, 0xb908, 0xb909, 0xb909, 
+    0xb909, 0xb90a, 0xb90a, 0xb90b, 0xb90b, 0xb90b, 0xb90c, 0xb90c, 
+    0xb90d, 0xb90d, 0xb90d, 0xb90e, 0xb90e, 0xb90f, 0xb90f, 0xb90f, 
+    0xb910, 0xb910, 0xb910, 0xb911, 0xb911, 0xb912, 0xb912, 0xb912, 
+    0xb913, 0xb913, 0xb914, 0xb914, 0xb914, 0xb915, 0xb915, 0xb916, 
+    0xb916, 0xb916, 0xb917, 0xb917, 0xb918, 0xb918, 0xb918, 0xb919, 
+    0xb919, 0xb919, 0xb91a, 0xb91a, 0xb91b, 0xb91b, 0xb91b, 0xb91c, 
+    0xb91c, 0xb91d, 0xb91d, 0xb91d, 0xb91e, 0xb91e, 0xb91f, 0xb91f, 
+    0xb91f, 0xb920, 0xb920, 0xb920, 0xb921, 0xb921, 0xb922, 0xb922, 
+    0xb922, 0xb923, 0xb923, 0xb924, 0xb924, 0xb924, 0xb925, 0xb925, 
+    0xb926, 0xb926, 0xb926, 0xb927, 0xb927, 0xb927, 0xb928, 0xb928, 
+    0xb929, 0xb929, 0xb929, 0xb92a, 0xb92a, 0xb92b, 0xb92b, 0xb92b, 
+    0xb92c, 0xb92c, 0xb92c, 0xb92d, 0xb92d, 0xb92e, 0xb92e, 0xb92e, 
+    0xb92f, 0xb92f, 0xb92f, 0xb930, 0xb930, 0xb931, 0xb931, 0xb931, 
+    0xb932, 0xb932, 0xb933, 0xb933, 0xb933, 0xb934, 0xb934, 0xb934, 
+    0xb935, 0xb935, 0xb936, 0xb936, 0xb936, 0xb937, 0xb937, 0xb937, 
+    0xb938, 0xb938, 0xb939, 0xb939, 0xb939, 0xb93a, 0xb93a, 0xb93b, 
+    0xb93b, 0xb93b, 0xb93c, 0xb93c, 0xb93c, 0xb93d, 0xb93d, 0xb93e, 
+    0xb93e, 0xb93e, 0xb93f, 0xb93f, 0xb93f, 0xb940, 0xb940, 0xb941, 
+    0xb941, 0xb941, 0xb942, 0xb942, 0xb942, 0xb943, 0xb943, 0xb944, 
+    0xb944, 0xb944, 0xb945, 0xb945, 0xb945, 0xb946, 0xb946, 0xb947, 
+    0xb947, 0xb947, 0xb948, 0xb948, 0xb948, 0xb949, 0xb949, 0xb94a, 
+    0xb94a, 0xb94a, 0xb94b, 0xb94b, 0xb94b, 0xb94c, 0xb94c, 0xb94d, 
+    0xb94d, 0xb94d, 0xb94e, 0xb94e, 0xb94e, 0xb94f, 0xb94f, 0xb950, 
+    0xb950, 0xb950, 0xb951, 0xb951, 0xb951, 0xb952, 0xb952, 0xb953, 
+    0xb953, 0xb953, 0xb954, 0xb954, 0xb954, 0xb955, 0xb955, 0xb955, 
+    0xb956, 0xb956, 0xb957, 0xb957, 0xb957, 0xb958, 0xb958, 0xb958, 
+    0xb959, 0xb959, 0xb95a, 0xb95a, 0xb95a, 0xb95b, 0xb95b, 0xb95b, 
+    0xb95c, 0xb95c, 0xb95c, 0xb95d, 0xb95d, 0xb95e, 0xb95e, 0xb95e, 
+    0xb95f, 0xb95f, 0xb95f, 0xb960, 0xb960, 0xb961, 0xb961, 0xb961, 
+    0xb962, 0xb962, 0xb962, 0xb963, 0xb963, 0xb963, 0xb964, 0xb964, 
+    0xb965, 0xb965, 0xb965, 0xb966, 0xb966, 0xb966, 0xb967, 0xb967, 
+    0xb967, 0xb968, 0xb968, 0xb969, 0xb969, 0xb969, 0xb96a, 0xb96a, 
+    0xb96a, 0xb96b, 0xb96b, 0xb96b, 0xb96c, 0xb96c, 0xb96d, 0xb96d, 
+    0xb96d, 0xb96e, 0xb96e, 0xb96e, 0xb96f, 0xb96f, 0xb96f, 0xb970, 
+    0xb970, 0xb970, 0xb971, 0xb971, 0xb972, 0xb972, 0xb972, 0xb973, 
+    0xb973, 0xb973, 0xb974, 0xb974, 0xb974, 0xb975, 0xb975, 0xb976, 
+    0xb976, 0xb976, 0xb977, 0xb977, 0xb977, 0xb978, 0xb978, 0xb978, 
+    0xb979, 0xb979, 0xb979, 0xb97a, 0xb97a, 0xb97b, 0xb97b, 0xb97b, 
+    0xb97c, 0xb97c, 0xb97c, 0xb97d, 0xb97d, 0xb97d, 0xb97e, 0xb97e, 
+    0xb97e, 0xb97f, 0xb97f, 0xb980, 0xb980, 0xb980, 0xb981, 0xb981, 
+    0xb981, 0xb982, 0xb982, 0xb982, 0xb983, 0xb983, 0xb983, 0xb984, 
+    0xb984, 0xb985, 0xb985, 0xb985, 0xb986, 0xb986, 0xb986, 0xb987, 
+    0xb987, 0xb987, 0xb988, 0xb988, 0xb988, 0xb989, 0xb989, 0xb98a, 
+    0xb98a, 0xb98a, 0xb98b, 0xb98b, 0xb98b, 0xb98c, 0xb98c, 0xb98c, 
+    0xb98d, 0xb98d, 0xb98d, 0xb98e, 0xb98e, 0xb98e, 0xb98f, 0xb98f, 
+    0xb98f, 0xb990, 0xb990, 0xb991, 0xb991, 0xb991, 0xb992, 0xb992, 
+    0xb992, 0xb993, 0xb993, 0xb993, 0xb994, 0xb994, 0xb994, 0xb995, 
+    0xb995, 0xb995, 0xb996, 0xb996, 0xb997, 0xb997, 0xb997, 0xb998, 
+    0xb998, 0xb998, 0xb999, 0xb999, 0xb999, 0xb99a, 0xb99a, 0xb99a, 
+    0xb99b, 0xb99b, 0xb99b, 0xb99c, 0xb99c, 0xb99c, 0xb99d, 0xb99d, 
+    0xb99d, 0xb99e, 0xb99e, 0xb99f, 0xb99f, 0xb99f, 0xb9a0, 0xb9a0, 
+    0xb9a0, 0xb9a1, 0xb9a1, 0xb9a1, 0xb9a2, 0xb9a2, 0xb9a2, 0xb9a3, 
+    0xb9a3, 0xb9a3, 0xb9a4, 0xb9a4, 0xb9a4, 0xb9a5, 0xb9a5, 0xb9a5, 
+    0xb9a6, 0xb9a6, 0xb9a6, 0xb9a7, 0xb9a7, 0xb9a8, 0xb9a8, 0xb9a8, 
+    0xb9a9, 0xb9a9, 0xb9a9, 0xb9aa, 0xb9aa, 0xb9aa, 0xb9ab, 0xb9ab, 
+    0xb9ab, 0xb9ac, 0xb9ac, 0xb9ac, 0xb9ad, 0xb9ad, 0xb9ad, 0xb9ae, 
+    0xb9ae, 0xb9ae, 0xb9af, 0xb9af, 0xb9af, 0xb9b0, 0xb9b0, 0xb9b0, 
+    0xb9b1, 0xb9b1, 0xb9b1, 0xb9b2, 0xb9b2, 0xb9b2, 0xb9b3, 0xb9b3, 
+    0xb9b4, 0xb9b4, 0xb9b4, 0xb9b5, 0xb9b5, 0xb9b5, 0xb9b6, 0xb9b6, 
+    0xb9b6, 0xb9b7, 0xb9b7, 0xb9b7, 0xb9b8, 0xb9b8, 0xb9b8, 0xb9b9, 
+    0xb9b9, 0xb9b9, 0xb9ba, 0xb9ba, 0xb9ba, 0xb9bb, 0xb9bb, 0xb9bb, 
+    0xb9bc, 0xb9bc, 0xb9bc, 0xb9bd, 0xb9bd, 0xb9bd, 0xb9be, 0xb9be, 
+    0xb9be, 0xb9bf, 0xb9bf, 0xb9bf, 0xb9c0, 0xb9c0, 0xb9c0, 0xb9c1, 
+    0xb9c1, 0xb9c1, 0xb9c2, 0xb9c2, 0xb9c2, 0xb9c3, 0xb9c3, 0xb9c3, 
+    0xb9c4, 0xb9c4, 0xb9c4, 0xb9c5, 0xb9c5, 0xb9c5, 0xb9c6, 0xb9c6, 
+    0xb9c6, 0xb9c7, 0xb9c7, 0xb9c7, 0xb9c8, 0xb9c8, 0xb9c8, 0xb9c9, 
+    0xb9c9, 0xb9ca, 0xb9ca, 0xb9ca, 0xb9cb, 0xb9cb, 0xb9cb, 0xb9cc, 
+    0xb9cc, 0xb9cc, 0xb9cd, 0xb9cd, 0xb9cd, 0xb9ce, 0xb9ce, 0xb9ce, 
+    0xb9cf, 0xb9cf, 0xb9cf, 0xb9d0, 0xb9d0, 0xb9d0, 0xb9d1, 0xb9d1, 
+    0xb9d1, 0xb9d2, 0xb9d2, 0xb9d2, 0xb9d3, 0xb9d3, 0xb9d3, 0xb9d4, 
+    0xb9d4, 0xb9d4, 0xb9d5, 0xb9d5, 0xb9d5, 0xb9d6, 0xb9d6, 0xb9d6, 
+    0xb9d7, 0xb9d7, 0xb9d8, 0xb9d8, 0xb9d9, 0xb9da, 0xb9da, 0xb9db, 
+    0xb9dc, 0xb9dc, 0xb9dd, 0xb9de, 0xb9de, 0xb9df, 0xb9e0, 0xb9e0, 
+    0xb9e1, 0xb9e2, 0xb9e2, 0xb9e3, 0xb9e4, 0xb9e4, 0xb9e5, 0xb9e6, 
+    0xb9e6, 0xb9e7, 0xb9e8, 0xb9e8, 0xb9e9, 0xb9ea, 0xb9ea, 0xb9eb, 
+    0xb9ec, 0xb9ec, 0xb9ed, 0xb9ee, 0xb9ee, 0xb9ef, 0xb9ef, 0xb9f0, 
+    0xb9f1, 0xb9f1, 0xb9f2, 0xb9f3, 0xb9f3, 0xb9f4, 0xb9f5, 0xb9f5, 
+    0xb9f6, 0xb9f7, 0xb9f7, 0xb9f8, 0xb9f9, 0xb9f9, 0xb9fa, 0xb9fa, 
+    0xb9fb, 0xb9fc, 0xb9fc, 0xb9fd, 0xb9fe, 0xb9fe, 0xb9ff, 0xba00, 
+    0xba00, 0xba01, 0xba02, 0xba02, 0xba03, 0xba03, 0xba04, 0xba05, 
+    0xba05, 0xba06, 0xba07, 0xba07, 0xba08, 0xba09, 0xba09, 0xba0a, 
+    0xba0a, 0xba0b, 0xba0c, 0xba0c, 0xba0d, 0xba0e, 0xba0e, 0xba0f, 
+    0xba10, 0xba10, 0xba11, 0xba11, 0xba12, 0xba13, 0xba13, 0xba14, 
+    0xba15, 0xba15, 0xba16, 0xba17, 0xba17, 0xba18, 0xba18, 0xba19, 
+    0xba1a, 0xba1a, 0xba1b, 0xba1c, 0xba1c, 0xba1d, 0xba1d, 0xba1e, 
+    0xba1f, 0xba1f, 0xba20, 0xba21, 0xba21, 0xba22, 0xba22, 0xba23, 
+    0xba24, 0xba24, 0xba25, 0xba26, 0xba26, 0xba27, 0xba27, 0xba28, 
+    0xba29, 0xba29, 0xba2a, 0xba2b, 0xba2b, 0xba2c, 0xba2c, 0xba2d, 
+    0xba2e, 0xba2e, 0xba2f, 0xba30, 0xba30, 0xba31, 0xba31, 0xba32, 
+    0xba33, 0xba33, 0xba34, 0xba34, 0xba35, 0xba36, 0xba36, 0xba37, 
+    0xba38, 0xba38, 0xba39, 0xba39, 0xba3a, 0xba3b, 0xba3b, 0xba3c, 
+    0xba3c, 0xba3d, 0xba3e, 0xba3e, 0xba3f, 0xba40, 0xba40, 0xba41, 
+    0xba41, 0xba42, 0xba43, 0xba43, 0xba44, 0xba44, 0xba45, 0xba46, 
+    0xba46, 0xba47, 0xba47, 0xba48, 0xba49, 0xba49, 0xba4a, 0xba4a, 
+    0xba4b, 0xba4c, 0xba4c, 0xba4d, 0xba4e, 0xba4e, 0xba4f, 0xba4f, 
+    0xba50, 0xba51, 0xba51, 0xba52, 0xba52, 0xba53, 0xba54, 0xba54, 
+    0xba55, 0xba55, 0xba56, 0xba57, 0xba57, 0xba58, 0xba58, 0xba59, 
+    0xba5a, 0xba5a, 0xba5b, 0xba5b, 0xba5c, 0xba5d, 0xba5d, 0xba5e, 
+    0xba5e, 0xba5f, 0xba60, 0xba60, 0xba61, 0xba61, 0xba62, 0xba63, 
+    0xba63, 0xba64, 0xba64, 0xba65, 0xba66, 0xba66, 0xba67, 0xba67, 
+    0xba68, 0xba68, 0xba69, 0xba6a, 0xba6a, 0xba6b, 0xba6b, 0xba6c, 
+    0xba6d, 0xba6d, 0xba6e, 0xba6e, 0xba6f, 0xba70, 0xba70, 0xba71, 
+    0xba71, 0xba72, 0xba73, 0xba73, 0xba74, 0xba74, 0xba75, 0xba75, 
+    0xba76, 0xba77, 0xba77, 0xba78, 0xba78, 0xba79, 0xba7a, 0xba7a, 
+    0xba7b, 0xba7b, 0xba7c, 0xba7c, 0xba7d, 0xba7e, 0xba7e, 0xba7f, 
+    0xba7f, 0xba80, 0xba81, 0xba81, 0xba82, 0xba82, 0xba83, 0xba83, 
+    0xba84, 0xba85, 0xba85, 0xba86, 0xba86, 0xba87, 0xba88, 0xba88, 
+    0xba89, 0xba89, 0xba8a, 0xba8a, 0xba8b, 0xba8c, 0xba8c, 0xba8d, 
+    0xba8d, 0xba8e, 0xba8f, 0xba8f, 0xba90, 0xba90, 0xba91, 0xba91, 
+    0xba92, 0xba93, 0xba93, 0xba94, 0xba94, 0xba95, 0xba95, 0xba96, 
+    0xba97, 0xba97, 0xba98, 0xba98, 0xba99, 0xba99, 0xba9a, 0xba9b, 
+    0xba9b, 0xba9c, 0xba9c, 0xba9d, 0xba9d, 0xba9e, 0xba9f, 0xba9f, 
+    0xbaa0, 0xbaa0, 0xbaa1, 0xbaa1, 0xbaa2, 0xbaa3, 0xbaa3, 0xbaa4, 
+    0xbaa4, 0xbaa5, 0xbaa5, 0xbaa6, 0xbaa7, 0xbaa7, 0xbaa8, 0xbaa8, 
+    0xbaa9, 0xbaa9, 0xbaaa, 0xbaaa, 0xbaab, 0xbaac, 0xbaac, 0xbaad, 
+    0xbaad, 0xbaae, 0xbaae, 0xbaaf, 0xbab0, 0xbab0, 0xbab1, 0xbab1, 
+    0xbab2, 0xbab2, 0xbab3, 0xbab4, 0xbab4, 0xbab5, 0xbab5, 0xbab6, 
+    0xbab6, 0xbab7, 0xbab7, 0xbab8, 0xbab9, 0xbab9, 0xbaba, 0xbaba, 
+    0xbabb, 0xbabb, 0xbabc, 0xbabc, 0xbabd, 0xbabe, 0xbabe, 0xbabf, 
+    0xbabf, 0xbac0, 0xbac0, 0xbac1, 0xbac2, 0xbac2, 0xbac3, 0xbac3, 
+    0xbac4, 0xbac4, 0xbac5, 0xbac5, 0xbac6, 0xbac7, 0xbac7, 0xbac8, 
+    0xbac8, 0xbac9, 0xbac9, 0xbaca, 0xbaca, 0xbacb, 0xbacb, 0xbacc, 
+    0xbacd, 0xbacd, 0xbace, 0xbace, 0xbacf, 0xbacf, 0xbad0, 0xbad0, 
+    0xbad1, 0xbad2, 0xbad2, 0xbad3, 0xbad3, 0xbad4, 0xbad4, 0xbad5, 
+    0xbad5, 0xbad6, 0xbad7, 0xbad7, 0xbad8, 0xbad8, 0xbad9, 0xbad9, 
+    0xbada, 0xbada, 0xbadb, 0xbadb, 0xbadc, 0xbadd, 0xbadd, 0xbade, 
+    0xbade, 0xbadf, 0xbadf, 0xbae0, 0xbae0, 0xbae1, 0xbae1, 0xbae2, 
+    0xbae3, 0xbae3, 0xbae4, 0xbae4, 0xbae5, 0xbae5, 0xbae6, 0xbae6, 
+    0xbae7, 0xbae7, 0xbae8, 0xbae9, 0xbae9, 0xbaea, 0xbaea, 0xbaeb, 
+    0xbaeb, 0xbaec, 0xbaec, 0xbaed, 0xbaed, 0xbaee, 0xbaee, 0xbaef, 
+    0xbaf0, 0xbaf0, 0xbaf1, 0xbaf1, 0xbaf2, 0xbaf2, 0xbaf3, 0xbaf3, 
+    0xbaf4, 0xbaf4, 0xbaf5, 0xbaf5, 0xbaf6, 0xbaf7, 0xbaf7, 0xbaf8, 
+    0xbaf8, 0xbaf9, 0xbaf9, 0xbafa, 0xbafa, 0xbafb, 0xbafb, 0xbafc, 
+    0xbafc, 0xbafd, 0xbafe, 0xbafe, 0xbaff, 0xbaff, 0xbb00, 0xbb00, 
+    0xbb01, 0xbb01, 0xbb02, 0xbb02, 0xbb03, 0xbb03, 0xbb04, 0xbb04, 
+    0xbb05, 0xbb05, 0xbb06, 0xbb07, 0xbb07, 0xbb08, 0xbb08, 0xbb09, 
+    0xbb09, 0xbb0a, 0xbb0a, 0xbb0b, 0xbb0b, 0xbb0c, 0xbb0c, 0xbb0d, 
+    0xbb0d, 0xbb0e, 0xbb0f, 0xbb0f, 0xbb10, 0xbb10, 0xbb11, 0xbb11, 
+    0xbb12, 0xbb12, 0xbb13, 0xbb13, 0xbb14, 0xbb14, 0xbb15, 0xbb15, 
+    0xbb16, 0xbb16, 0xbb17, 0xbb17, 0xbb18, 0xbb19, 0xbb19, 0xbb1a, 
+    0xbb1a, 0xbb1b, 0xbb1b, 0xbb1c, 0xbb1c, 0xbb1d, 0xbb1d, 0xbb1e, 
+    0xbb1e, 0xbb1f, 0xbb1f, 0xbb20, 0xbb20, 0xbb21, 0xbb21, 0xbb22, 
+    0xbb22, 0xbb23, 0xbb23, 0xbb24, 0xbb25, 0xbb25, 0xbb26, 0xbb26, 
+    0xbb27, 0xbb27, 0xbb28, 0xbb28, 0xbb29, 0xbb29, 0xbb2a, 0xbb2a, 
+    0xbb2b, 0xbb2b, 0xbb2c, 0xbb2c, 0xbb2d, 0xbb2d, 0xbb2e, 0xbb2e, 
+    0xbb2f, 0xbb2f, 0xbb30, 0xbb30, 0xbb31, 0xbb32, 0xbb32, 0xbb33, 
+    0xbb33, 0xbb34, 0xbb34, 0xbb35, 0xbb35, 0xbb36, 0xbb36, 0xbb37, 
+    0xbb37, 0xbb38, 0xbb38, 0xbb39, 0xbb39, 0xbb3a, 0xbb3a, 0xbb3b, 
+    0xbb3b, 0xbb3c, 0xbb3c, 0xbb3d, 0xbb3d, 0xbb3e, 0xbb3e, 0xbb3f, 
+    0xbb3f, 0xbb40, 0xbb40, 0xbb41, 0xbb41, 0xbb42, 0xbb42, 0xbb43, 
+    0xbb43, 0xbb44, 0xbb44, 0xbb45, 0xbb46, 0xbb46, 0xbb47, 0xbb47, 
+    0xbb48, 0xbb48, 0xbb49, 0xbb49, 0xbb4a, 0xbb4a, 0xbb4b, 0xbb4b, 
+    0xbb4c, 0xbb4c, 0xbb4d, 0xbb4d, 0xbb4e, 0xbb4e, 0xbb4f, 0xbb4f, 
+    0xbb50, 0xbb50, 0xbb51, 0xbb51, 0xbb52, 0xbb52, 0xbb53, 0xbb53, 
+    0xbb54, 0xbb54, 0xbb55, 0xbb55, 0xbb56, 0xbb56, 0xbb57, 0xbb57, 
+    0xbb58, 0xbb58, 0xbb59, 0xbb59, 0xbb5a, 0xbb5a, 0xbb5b, 0xbb5b, 
+    0xbb5c, 0xbb5c, 0xbb5d, 0xbb5d, 0xbb5e, 0xbb5e, 0xbb5f, 0xbb5f, 
+    0xbb60, 0xbb60, 0xbb61, 0xbb61, 0xbb62, 0xbb62, 0xbb63, 0xbb63, 
+    0xbb64, 0xbb64, 0xbb65, 0xbb65, 0xbb66, 0xbb66, 0xbb67, 0xbb67, 
+    0xbb68, 0xbb68, 0xbb69, 0xbb69, 0xbb6a, 0xbb6a, 0xbb6b, 0xbb6b, 
+    0xbb6c, 0xbb6c, 0xbb6d, 0xbb6d, 0xbb6e, 0xbb6e, 0xbb6f, 0xbb6f, 
+    0xbb70, 0xbb70, 0xbb71, 0xbb71, 0xbb72, 0xbb72, 0xbb73, 0xbb73, 
+    0xbb74, 0xbb74, 0xbb75, 0xbb75, 0xbb76, 0xbb76, 0xbb77, 0xbb77, 
+    0xbb78, 0xbb78, 0xbb79, 0xbb79, 0xbb7a, 0xbb7a, 0xbb7b, 0xbb7b, 
+    0xbb7c, 0xbb7c, 0xbb7d, 0xbb7d, 0xbb7e, 0xbb7e, 0xbb7f, 0xbb7f, 
+    0xbb80, 0xbb80, 0xbb81, 0xbb81, 0xbb82, 0xbb82, 0xbb82, 0xbb83, 
+    0xbb83, 0xbb84, 0xbb84, 0xbb85, 0xbb85, 0xbb86, 0xbb86, 0xbb87, 
+    0xbb87, 0xbb88, 0xbb88, 0xbb89, 0xbb89, 0xbb8a, 0xbb8a, 0xbb8b, 
+    0xbb8b, 0xbb8c, 0xbb8c, 0xbb8d, 0xbb8d, 0xbb8e, 0xbb8e, 0xbb8f, 
+    0xbb8f, 0xbb90, 0xbb90, 0xbb91, 0xbb91, 0xbb92, 0xbb92, 0xbb93, 
+    0xbb93, 0xbb94, 0xbb94, 0xbb95, 0xbb95, 0xbb96, 0xbb96, 0xbb96, 
+    0xbb97, 0xbb97, 0xbb98, 0xbb98, 0xbb99, 0xbb99, 0xbb9a, 0xbb9a, 
+    0xbb9b, 0xbb9b, 0xbb9c, 0xbb9c, 0xbb9d, 0xbb9d, 0xbb9e, 0xbb9e, 
+    0xbb9f, 0xbb9f, 0xbba0, 0xbba0, 0xbba1, 0xbba1, 0xbba2, 0xbba2, 
+    0xbba3, 0xbba3, 0xbba4, 0xbba4, 0xbba4, 0xbba5, 0xbba5, 0xbba6, 
+    0xbba6, 0xbba7, 0xbba7, 0xbba8, 0xbba8, 0xbba9, 0xbba9, 0xbbaa, 
+    0xbbaa, 0xbbab, 0xbbab, 0xbbac, 0xbbac, 0xbbad, 0xbbad, 0xbbae, 
+    0xbbae, 0xbbaf, 0xbbaf, 0xbbaf, 0xbbb0, 0xbbb0, 0xbbb1, 0xbbb1, 
+    0xbbb2, 0xbbb2, 0xbbb3, 0xbbb3, 0xbbb4, 0xbbb4, 0xbbb5, 0xbbb5, 
+    0xbbb6, 0xbbb6, 0xbbb7, 0xbbb7, 0xbbb8, 0xbbb8, 0xbbb9, 0xbbb9, 
+    0xbbb9, 0xbbba, 0xbbba, 0xbbbb, 0xbbbb, 0xbbbc, 0xbbbc, 0xbbbd, 
+    0xbbbd, 0xbbbe, 0xbbbe, 0xbbbf, 0xbbbf, 0xbbc0, 0xbbc0, 0xbbc1, 
+    0xbbc1, 0xbbc1, 0xbbc2, 0xbbc2, 0xbbc3, 0xbbc3, 0xbbc4, 0xbbc4, 
+    0xbbc5, 0xbbc5, 0xbbc6, 0xbbc6, 0xbbc7, 0xbbc7, 0xbbc8, 0xbbc8, 
+    0xbbc9, 0xbbc9, 0xbbc9, 0xbbca, 0xbbca, 0xbbcb, 0xbbcb, 0xbbcc, 
+    0xbbcc, 0xbbcd, 0xbbcd, 0xbbce, 0xbbce, 0xbbcf, 0xbbcf, 0xbbd0, 
+    0xbbd0, 0xbbd1, 0xbbd1, 0xbbd1, 0xbbd2, 0xbbd2, 0xbbd3, 0xbbd3, 
+    0xbbd4, 0xbbd4, 0xbbd5, 0xbbd5, 0xbbd6, 0xbbd6, 0xbbd7, 0xbbd7, 
+    0xbbd8, 0xbbd8, 0xbbd8, 0xbbd9, 0xbbd9, 0xbbda, 0xbbda, 0xbbdb, 
+    0xbbdb, 0xbbdc, 0xbbdc, 0xbbdd, 0xbbdd, 0xbbde, 0xbbde, 0xbbde, 
+    0xbbdf, 0xbbdf, 0xbbe0, 0xbbe0, 0xbbe1, 0xbbe1, 0xbbe2, 0xbbe2, 
+    0xbbe3, 0xbbe3, 0xbbe4, 0xbbe4, 0xbbe5, 0xbbe5, 0xbbe5, 0xbbe6, 
+    0xbbe6, 0xbbe7, 0xbbe7, 0xbbe8, 0xbbe8, 0xbbe9, 0xbbe9, 0xbbea, 
+    0xbbea, 0xbbeb, 0xbbeb, 0xbbeb, 0xbbec, 0xbbec, 0xbbed, 0xbbed, 
+    0xbbee, 0xbbee, 0xbbef, 0xbbef, 0xbbf0, 0xbbf0, 0xbbf0, 0xbbf1, 
+    0xbbf1, 0xbbf2, 0xbbf2, 0xbbf3, 0xbbf3, 0xbbf4, 0xbbf4, 0xbbf5, 
+    0xbbf5, 0xbbf6, 0xbbf6, 0xbbf6, 0xbbf7, 0xbbf7, 0xbbf8, 0xbbf8, 
+    0xbbf9, 0xbbf9, 0xbbfa, 0xbbfa, 0xbbfb, 0xbbfb, 0xbbfb, 0xbbfc, 
+    0xbbfc, 0xbbfd, 0xbbfd, 0xbbfe, 0xbbfe, 0xbbff, 0xbbff, 0xbc00, 
+    0xbc00, 0xbc00, 0xbc01, 0xbc01, 0xbc02, 0xbc02, 0xbc03, 0xbc03, 
+    0xbc04, 0xbc04, 0xbc05, 0xbc05, 0xbc05, 0xbc06, 0xbc06, 0xbc07, 
+    0xbc07, 0xbc08, 0xbc08, 0xbc09, 0xbc09, 0xbc09, 0xbc0a, 0xbc0a, 
+    0xbc0b, 0xbc0b, 0xbc0c, 0xbc0c, 0xbc0d, 0xbc0d, 0xbc0d, 0xbc0e, 
+    0xbc0e, 0xbc0f, 0xbc0f, 0xbc10, 0xbc10, 0xbc11, 0xbc11, 0xbc11, 
+    0xbc12, 0xbc12, 0xbc13, 0xbc13, 0xbc14, 0xbc14, 0xbc14, 0xbc15, 
+    0xbc15, 0xbc16, 0xbc16, 0xbc17, 0xbc17, 0xbc17, 0xbc18, 0xbc18, 
+    0xbc19, 0xbc19, 0xbc1a, 0xbc1a, 0xbc1b, 0xbc1b, 0xbc1b, 0xbc1c, 
+    0xbc1c, 0xbc1d, 0xbc1d, 0xbc1d, 0xbc1e, 0xbc1e, 0xbc1f, 0xbc1f, 
+    0xbc20, 0xbc20, 0xbc20, 0xbc21, 0xbc21, 0xbc22, 0xbc22, 0xbc23, 
+    0xbc23, 0xbc23, 0xbc24, 0xbc24, 0xbc25, 0xbc25, 0xbc26, 0xbc26, 
+    0xbc26, 0xbc27, 0xbc27, 0xbc28, 0xbc28, 0xbc28, 0xbc29, 0xbc29, 
+    0xbc2a, 0xbc2a, 0xbc2b, 0xbc2b, 0xbc2b, 0xbc2c, 0xbc2c, 0xbc2d, 
+    0xbc2d, 0xbc2d, 0xbc2e, 0xbc2e, 0xbc2f, 0xbc2f, 0xbc2f, 0xbc30, 
+    0xbc30, 0xbc31, 0xbc31, 0xbc32, 0xbc32, 0xbc32, 0xbc33, 0xbc33, 
+    0xbc34, 0xbc34, 0xbc34, 0xbc35, 0xbc35, 0xbc36, 0xbc36, 0xbc36, 
+    0xbc37, 0xbc37, 0xbc38, 0xbc38, 0xbc38, 0xbc39, 0xbc39, 0xbc3a, 
+    0xbc3a, 0xbc3a, 0xbc3b, 0xbc3b, 0xbc3c, 0xbc3c, 0xbc3c, 0xbc3d, 
+    0xbc3d, 0xbc3e, 0xbc3e, 0xbc3e, 0xbc3f, 0xbc3f, 0xbc40, 0xbc40, 
+    0xbc40, 0xbc41, 0xbc41, 0xbc42, 0xbc42, 0xbc42, 0xbc43, 0xbc43, 
+    0xbc44, 0xbc44, 0xbc44, 0xbc45, 0xbc45, 0xbc46, 0xbc46, 0xbc46, 
+    0xbc47, 0xbc47, 0xbc47, 0xbc48, 0xbc48, 0xbc49, 0xbc49, 0xbc49, 
+    0xbc4a, 0xbc4a, 0xbc4b, 0xbc4b, 0xbc4b, 0xbc4c, 0xbc4c, 0xbc4d, 
+    0xbc4d, 0xbc4d, 0xbc4e, 0xbc4e, 0xbc4e, 0xbc4f, 0xbc4f, 0xbc50, 
+    0xbc50, 0xbc50, 0xbc51, 0xbc51, 0xbc52, 0xbc52, 0xbc52, 0xbc53, 
+    0xbc53, 0xbc53, 0xbc54, 0xbc54, 0xbc55, 0xbc55, 0xbc55, 0xbc56, 
+    0xbc56, 0xbc56, 0xbc57, 0xbc57, 0xbc58, 0xbc58, 0xbc58, 0xbc59, 
+    0xbc59, 0xbc59, 0xbc5a, 0xbc5a, 0xbc5b, 0xbc5b, 0xbc5b, 0xbc5c, 
+    0xbc5c, 0xbc5c, 0xbc5d, 0xbc5d, 0xbc5e, 0xbc5e, 0xbc5e, 0xbc5f, 
+    0xbc5f, 0xbc5f, 0xbc60, 0xbc60, 0xbc61, 0xbc61, 0xbc61, 0xbc62, 
+    0xbc62, 0xbc62, 0xbc63, 0xbc63, 0xbc63, 0xbc64, 0xbc64, 0xbc65, 
+    0xbc65, 0xbc65, 0xbc66, 0xbc66, 0xbc66, 0xbc67, 0xbc67, 0xbc67, 
+    0xbc68, 0xbc68, 0xbc69, 0xbc69, 0xbc69, 0xbc6a, 0xbc6a, 0xbc6a, 
+    0xbc6b, 0xbc6b, 0xbc6b, 0xbc6c, 0xbc6c, 0xbc6d, 0xbc6d, 0xbc6d, 
+    0xbc6e, 0xbc6e, 0xbc6e, 0xbc6f, 0xbc6f, 0xbc6f, 0xbc70, 0xbc70, 
+    0xbc71, 0xbc71, 0xbc71, 0xbc72, 0xbc72, 0xbc72, 0xbc73, 0xbc73, 
+    0xbc73, 0xbc74, 0xbc74, 0xbc74, 0xbc75, 0xbc75, 0xbc75, 0xbc76, 
+    0xbc76, 0xbc77, 0xbc77, 0xbc77, 0xbc78, 0xbc78, 0xbc78, 0xbc79, 
+    0xbc79, 0xbc79, 0xbc7a, 0xbc7a, 0xbc7a, 0xbc7b, 0xbc7b, 0xbc7b, 
+    0xbc7c, 0xbc7c, 0xbc7c, 0xbc7d, 0xbc7d, 0xbc7e, 0xbc7e, 0xbc7e, 
+    0xbc7f, 0xbc7f, 0xbc7f, 0xbc80, 0xbc80, 0xbc80, 0xbc81, 0xbc81, 
+    0xbc81, 0xbc82, 0xbc82, 0xbc82, 0xbc83, 0xbc83, 0xbc83, 0xbc84, 
+    0xbc84, 0xbc84, 0xbc85, 0xbc85, 0xbc85, 0xbc86, 0xbc86, 0xbc86, 
+    0xbc87, 0xbc87, 0xbc87, 0xbc88, 0xbc88, 0xbc89, 0xbc89, 0xbc89, 
+    0xbc8a, 0xbc8a, 0xbc8a, 0xbc8b, 0xbc8b, 0xbc8b, 0xbc8c, 0xbc8c, 
+    0xbc8c, 0xbc8d, 0xbc8d, 0xbc8d, 0xbc8e, 0xbc8e, 0xbc8e, 0xbc8f, 
+    0xbc8f, 0xbc8f, 0xbc90, 0xbc90, 0xbc90, 0xbc91, 0xbc91, 0xbc91, 
+    0xbc92, 0xbc92, 0xbc92, 0xbc93, 0xbc93, 0xbc93, 0xbc94, 0xbc94, 
+    0xbc94, 0xbc95, 0xbc95, 0xbc95, 0xbc96, 0xbc96, 0xbc96, 0xbc97, 
+    0xbc97, 0xbc97, 0xbc98, 0xbc98, 0xbc98, 0xbc99, 0xbc99, 0xbc99, 
+    0xbc99, 0xbc9a, 0xbc9a, 0xbc9a, 0xbc9b, 0xbc9b, 0xbc9b, 0xbc9c, 
+    0xbc9c, 0xbc9c, 0xbc9d, 0xbc9d, 0xbc9d, 0xbc9e, 0xbc9e, 0xbc9e, 
+    0xbc9f, 0xbc9f, 0xbc9f, 0xbca0, 0xbca0, 0xbca0, 0xbca1, 0xbca1, 
+    0xbca1, 0xbca2, 0xbca2, 0xbca2, 0xbca3, 0xbca3, 0xbca3, 0xbca4, 
+    0xbca4, 0xbca4, 0xbca4, 0xbca5, 0xbca5, 0xbca5, 0xbca6, 0xbca6, 
+    0xbca6, 0xbca7, 0xbca7, 0xbca7, 0xbca8, 0xbca8, 0xbca8, 0xbca9, 
+    0xbca9, 0xbca9, 0xbcaa, 0xbcaa, 0xbcaa, 0xbcaa, 0xbcab, 0xbcab, 
+    0xbcab, 0xbcac, 0xbcac, 0xbcac, 0xbcad, 0xbcad, 0xbcad, 0xbcae, 
+    0xbcae, 0xbcae, 0xbcaf, 0xbcaf, 0xbcaf, 0xbcb0, 0xbcb0, 0xbcb0, 
+    0xbcb0, 0xbcb1, 0xbcb1, 0xbcb1, 0xbcb2, 0xbcb2, 0xbcb2, 0xbcb3, 
+    0xbcb3, 0xbcb3, 0xbcb4, 0xbcb4, 0xbcb4, 0xbcb4, 0xbcb5, 0xbcb5, 
+    0xbcb5, 0xbcb6, 0xbcb6, 0xbcb6, 0xbcb7, 0xbcb7, 0xbcb7, 0xbcb8, 
+    0xbcb8, 0xbcb8, 0xbcb8, 0xbcb9, 0xbcb9, 0xbcb9, 0xbcba, 0xbcba, 
+    0xbcba, 0xbcbb, 0xbcbb, 0xbcbb, 0xbcbc, 0xbcbc, 0xbcbc, 0xbcbc, 
+    0xbcbd, 0xbcbd, 0xbcbd, 0xbcbe, 0xbcbe, 0xbcbe, 0xbcbf, 0xbcbf, 
+    0xbcbf, 0xbcbf, 0xbcc0, 0xbcc0, 0xbcc0, 0xbcc1, 0xbcc1, 0xbcc1, 
+    0xbcc2, 0xbcc2, 0xbcc2, 0xbcc2, 0xbcc3, 0xbcc3, 0xbcc3, 0xbcc4, 
+    0xbcc4, 0xbcc4, 0xbcc5, 0xbcc5, 0xbcc5, 0xbcc5, 0xbcc6, 0xbcc6, 
+    0xbcc6, 0xbcc7, 0xbcc7, 0xbcc7, 0xbcc8, 0xbcc8, 0xbcc8, 0xbcc8, 
+    0xbcc9, 0xbcc9, 0xbcc9, 0xbcca, 0xbcca, 0xbcca, 0xbcca, 0xbccb, 
+    0xbccb, 0xbccb, 0xbccc, 0xbccc, 0xbccc, 0xbccd, 0xbccd, 0xbccd, 
+    0xbccd, 0xbcce, 0xbcce, 0xbcce, 0xbccf, 0xbccf, 0xbccf, 0xbccf, 
+    0xbcd0, 0xbcd0, 0xbcd0, 0xbcd1, 0xbcd1, 0xbcd1, 0xbcd1, 0xbcd2, 
+    0xbcd2, 0xbcd2, 0xbcd3, 0xbcd3, 0xbcd3, 0xbcd3, 0xbcd4, 0xbcd4, 
+    0xbcd4, 0xbcd5, 0xbcd5, 0xbcd5, 0xbcd6, 0xbcd6, 0xbcd6, 0xbcd6, 
+    0xbcd7, 0xbcd7, 0xbcd7, 0xbcd8, 0xbcd8, 0xbcd8, 0xbcd8, 0xbcd9, 
+    0xbcd9, 0xbcd9, 0xbcda, 0xbcda, 0xbcda, 0xbcda, 0xbcdb, 0xbcdb, 
+    0xbcdb, 0xbcdc, 0xbcdc, 0xbcdc, 0xbcdc, 0xbcdd, 0xbcdd, 0xbcdd, 
+    0xbcdd, 0xbcde, 0xbcde, 0xbcde, 0xbcdf, 0xbcdf, 0xbcdf, 0xbcdf, 
+    0xbce0, 0xbce0, 0xbce0, 0xbce1, 0xbce1, 0xbce1, 0xbce1, 0xbce2, 
+    0xbce2, 0xbce2, 0xbce3, 0xbce3, 0xbce3, 0xbce3, 0xbce4, 0xbce4, 
+    0xbce4, 0xbce4, 0xbce5, 0xbce5, 0xbce5, 0xbce6, 0xbce6, 0xbce6, 
+    0xbce6, 0xbce7, 0xbce7, 0xbce7, 0xbce8, 0xbce8, 0xbce8, 0xbce8, 
+    0xbce9, 0xbce9, 0xbce9, 0xbce9, 0xbcea, 0xbcea, 0xbcea, 0xbceb, 
+    0xbceb, 0xbceb, 0xbceb, 0xbcec, 0xbcec, 0xbcec, 0xbcec, 0xbced, 
+    0xbced, 0xbced, 0xbcee, 0xbcee, 0xbcee, 0xbcee, 0xbcef, 0xbcef, 
+    0xbcef, 0xbcef, 0xbcf0, 0xbcf0, 0xbcf0, 0xbcf1, 0xbcf1, 0xbcf1, 
+    0xbcf1, 0xbcf2, 0xbcf2, 0xbcf2, 0xbcf2, 0xbcf3, 0xbcf3, 0xbcf3, 
+    0xbcf4, 0xbcf4, 0xbcf4, 0xbcf4, 0xbcf5, 0xbcf5, 0xbcf5, 0xbcf5, 
+    0xbcf6, 0xbcf6, 0xbcf6, 0xbcf7, 0xbcf7, 0xbcf7, 0xbcf7, 0xbcf8, 
+    0xbcf8, 0xbcf8, 0xbcf8, 0xbcf9, 0xbcf9, 0xbcf9, 0xbcf9, 0xbcfa, 
+    0xbcfa, 0xbcfa, 0xbcfa, 0xbcfb, 0xbcfb, 0xbcfb, 0xbcfc, 0xbcfc, 
+    0xbcfc, 0xbcfc, 0xbcfd, 0xbcfd, 0xbcfd, 0xbcfd, 0xbcfe, 0xbcfe, 
+    0xbcfe, 0xbcfe, 0xbcff, 0xbcff, 0xbcff, 0xbd00, 0xbd00, 0xbd00, 
+    0xbd00, 0xbd01, 0xbd01, 0xbd01, 0xbd01, 0xbd02, 0xbd02, 0xbd02, 
+    0xbd02, 0xbd03, 0xbd03, 0xbd03, 0xbd03, 0xbd04, 0xbd04, 0xbd04, 
+    0xbd04, 0xbd05, 0xbd05, 0xbd05, 0xbd06, 0xbd06, 0xbd06, 0xbd06, 
+    0xbd07, 0xbd07, 0xbd07, 0xbd07, 0xbd08, 0xbd08, 0xbd08, 0xbd08, 
+    0xbd09, 0xbd09, 0xbd09, 0xbd09, 0xbd0a, 0xbd0a, 0xbd0a, 0xbd0a, 
+    0xbd0b, 0xbd0b, 0xbd0b, 0xbd0b, 0xbd0c, 0xbd0c, 0xbd0c, 0xbd0c, 
+    0xbd0d, 0xbd0d, 0xbd0d, 0xbd0d, 0xbd0e, 0xbd0e, 0xbd0e, 0xbd0e, 
+    0xbd0f, 0xbd0f, 0xbd0f, 0xbd10, 0xbd10, 0xbd10, 0xbd10, 0xbd11, 
+    0xbd11, 0xbd11, 0xbd11, 0xbd12, 0xbd12, 0xbd12, 0xbd12, 0xbd13, 
+    0xbd13, 0xbd13, 0xbd13, 0xbd14, 0xbd14, 0xbd14, 0xbd14, 0xbd15, 
+    0xbd15, 0xbd15, 0xbd15, 0xbd16, 0xbd16, 0xbd16, 0xbd16, 0xbd17, 
+    0xbd17, 0xbd17, 0xbd17, 0xbd18, 0xbd18, 0xbd18, 0xbd18, 0xbd19, 
+    0xbd19, 0xbd19, 0xbd19, 0xbd1a, 0xbd1a, 0xbd1a, 0xbd1a, 0xbd1b, 
+    0xbd1b, 0xbd1b, 0xbd1b, 0xbd1c, 0xbd1c, 0xbd1c, 0xbd1c, 0xbd1d, 
+    0xbd1d, 0xbd1d, 0xbd1d, 0xbd1e, 0xbd1e, 0xbd1e, 0xbd1e, 0xbd1e, 
+    0xbd1f, 0xbd1f, 0xbd1f, 0xbd1f, 0xbd20, 0xbd20, 0xbd20, 0xbd20, 
+    0xbd21, 0xbd21, 0xbd21, 0xbd21, 0xbd22, 0xbd22, 0xbd22, 0xbd22, 
+    0xbd23, 0xbd23, 0xbd23, 0xbd23, 0xbd24, 0xbd24, 0xbd24, 0xbd24, 
+    0xbd25, 0xbd25, 0xbd25, 0xbd25, 0xbd26, 0xbd26, 0xbd26, 0xbd26, 
+    0xbd27, 0xbd27, 0xbd27, 0xbd27, 0xbd27, 0xbd28, 0xbd28, 0xbd28, 
+    0xbd28, 0xbd29, 0xbd29, 0xbd29, 0xbd29, 0xbd2a, 0xbd2a, 0xbd2a, 
+    0xbd2a, 0xbd2b, 0xbd2b, 0xbd2b, 0xbd2b, 0xbd2c, 0xbd2c, 0xbd2c, 
+    0xbd2c, 0xbd2d, 0xbd2d, 0xbd2d, 0xbd2d, 0xbd2d, 0xbd2e, 0xbd2e, 
+    0xbd2e, 0xbd2e, 0xbd2f, 0xbd2f, 0xbd2f, 0xbd2f, 0xbd30, 0xbd30, 
+    0xbd30, 0xbd30, 0xbd31, 0xbd31, 0xbd31, 0xbd31, 0xbd31, 0xbd32, 
+    0xbd32, 0xbd32, 0xbd32, 0xbd33, 0xbd33, 0xbd33, 0xbd33, 0xbd34, 
+    0xbd34, 0xbd34, 0xbd34, 0xbd35, 0xbd35, 0xbd35, 0xbd35, 0xbd35, 
+    0xbd36, 0xbd36, 0xbd36, 0xbd36, 0xbd37, 0xbd37, 0xbd37, 0xbd37, 
+    0xbd38, 0xbd38, 0xbd38, 0xbd38, 0xbd39, 0xbd39, 0xbd39, 0xbd39, 
+    0xbd39, 0xbd3a, 0xbd3a, 0xbd3a, 0xbd3a, 0xbd3b, 0xbd3b, 0xbd3b, 
+    0xbd3b, 0xbd3c, 0xbd3c, 0xbd3c, 0xbd3c, 0xbd3c, 0xbd3d, 0xbd3d, 
+    0xbd3d, 0xbd3d, 0xbd3e, 0xbd3e, 0xbd3e, 0xbd3e, 0xbd3f, 0xbd3f, 
+    0xbd3f, 0xbd3f, 0xbd3f, 0xbd40, 0xbd40, 0xbd40, 0xbd40, 0xbd41, 
+    0xbd41, 0xbd41, 0xbd41, 0xbd41, 0xbd42, 0xbd42, 0xbd42, 0xbd42, 
+    0xbd43, 0xbd43, 0xbd44, 0xbd44, 0xbd44, 0xbd45, 0xbd45, 0xbd46, 
+    0xbd46, 0xbd47, 0xbd47, 0xbd48, 0xbd48, 0xbd49, 0xbd49, 0xbd49, 
+    0xbd4a, 0xbd4a, 0xbd4b, 0xbd4b, 0xbd4c, 0xbd4c, 0xbd4d, 0xbd4d, 
+    0xbd4d, 0xbd4e, 0xbd4e, 0xbd4f, 0xbd4f, 0xbd50, 0xbd50, 0xbd51, 
+    0xbd51, 0xbd51, 0xbd52, 0xbd52, 0xbd53, 0xbd53, 0xbd54, 0xbd54, 
+    0xbd54, 0xbd55, 0xbd55, 0xbd56, 0xbd56, 0xbd57, 0xbd57, 0xbd58, 
+    0xbd58, 0xbd58, 0xbd59, 0xbd59, 0xbd5a, 0xbd5a, 0xbd5b, 0xbd5b, 
+    0xbd5b, 0xbd5c, 0xbd5c, 0xbd5d, 0xbd5d, 0xbd5e, 0xbd5e, 0xbd5e, 
+    0xbd5f, 0xbd5f, 0xbd60, 0xbd60, 0xbd61, 0xbd61, 0xbd61, 0xbd62, 
+    0xbd62, 0xbd63, 0xbd63, 0xbd64, 0xbd64, 0xbd64, 0xbd65, 0xbd65, 
+    0xbd66, 0xbd66, 0xbd66, 0xbd67, 0xbd67, 0xbd68, 0xbd68, 0xbd69, 
+    0xbd69, 0xbd69, 0xbd6a, 0xbd6a, 0xbd6b, 0xbd6b, 0xbd6c, 0xbd6c, 
+    0xbd6c, 0xbd6d, 0xbd6d, 0xbd6e, 0xbd6e, 0xbd6e, 0xbd6f, 0xbd6f, 
+    0xbd70, 0xbd70, 0xbd70, 0xbd71, 0xbd71, 0xbd72, 0xbd72, 0xbd73, 
+    0xbd73, 0xbd73, 0xbd74, 0xbd74, 0xbd75, 0xbd75, 0xbd75, 0xbd76, 
+    0xbd76, 0xbd77, 0xbd77, 0xbd77, 0xbd78, 0xbd78, 0xbd79, 0xbd79, 
+    0xbd79, 0xbd7a, 0xbd7a, 0xbd7b, 0xbd7b, 0xbd7b, 0xbd7c, 0xbd7c, 
+    0xbd7d, 0xbd7d, 0xbd7d, 0xbd7e, 0xbd7e, 0xbd7f, 0xbd7f, 0xbd7f, 
+    0xbd80, 0xbd80, 0xbd81, 0xbd81, 0xbd81, 0xbd82, 0xbd82, 0xbd83, 
+    0xbd83, 0xbd83, 0xbd84, 0xbd84, 0xbd85, 0xbd85, 0xbd85, 0xbd86, 
+    0xbd86, 0xbd87, 0xbd87, 0xbd87, 0xbd88, 0xbd88, 0xbd89, 0xbd89, 
+    0xbd89, 0xbd8a, 0xbd8a, 0xbd8b, 0xbd8b, 0xbd8b, 0xbd8c, 0xbd8c, 
+    0xbd8c, 0xbd8d, 0xbd8d, 0xbd8e, 0xbd8e, 0xbd8e, 0xbd8f, 0xbd8f, 
+    0xbd90, 0xbd90, 0xbd90, 0xbd91, 0xbd91, 0xbd91, 0xbd92, 0xbd92, 
+    0xbd93, 0xbd93, 0xbd93, 0xbd94, 0xbd94, 0xbd95, 0xbd95, 0xbd95, 
+    0xbd96, 0xbd96, 0xbd96, 0xbd97, 0xbd97, 0xbd98, 0xbd98, 0xbd98, 
+    0xbd99, 0xbd99, 0xbd99, 0xbd9a, 0xbd9a, 0xbd9b, 0xbd9b, 0xbd9b, 
+    0xbd9c, 0xbd9c, 0xbd9c, 0xbd9d, 0xbd9d, 0xbd9e, 0xbd9e, 0xbd9e, 
+    0xbd9f, 0xbd9f, 0xbd9f, 0xbda0, 0xbda0, 0xbda1, 0xbda1, 0xbda1, 
+    0xbda2, 0xbda2, 0xbda2, 0xbda3, 0xbda3, 0xbda4, 0xbda4, 0xbda4, 
+    0xbda5, 0xbda5, 0xbda5, 0xbda6, 0xbda6, 0xbda6, 0xbda7, 0xbda7, 
+    0xbda8, 0xbda8, 0xbda8, 0xbda9, 0xbda9, 0xbda9, 0xbdaa, 0xbdaa, 
+    0xbdaa, 0xbdab, 0xbdab, 0xbdac, 0xbdac, 0xbdac, 0xbdad, 0xbdad, 
+    0xbdad, 0xbdae, 0xbdae, 0xbdae, 0xbdaf, 0xbdaf, 0xbdb0, 0xbdb0, 
+    0xbdb0, 0xbdb1, 0xbdb1, 0xbdb1, 0xbdb2, 0xbdb2, 0xbdb2, 0xbdb3, 
+    0xbdb3, 0xbdb3, 0xbdb4, 0xbdb4, 0xbdb5, 0xbdb5, 0xbdb5, 0xbdb6, 
+    0xbdb6, 0xbdb6, 0xbdb7, 0xbdb7, 0xbdb7, 0xbdb8, 0xbdb8, 0xbdb8, 
+    0xbdb9, 0xbdb9, 0xbdba, 0xbdba, 0xbdba, 0xbdbb, 0xbdbb, 0xbdbb, 
+    0xbdbc, 0xbdbc, 0xbdbc, 0xbdbd, 0xbdbd, 0xbdbd, 0xbdbe, 0xbdbe, 
+    0xbdbe, 0xbdbf, 0xbdbf, 0xbdbf, 0xbdc0, 0xbdc0, 0xbdc1, 0xbdc1, 
+    0xbdc1, 0xbdc2, 0xbdc2, 0xbdc2, 0xbdc3, 0xbdc3, 0xbdc3, 0xbdc4, 
+    0xbdc4, 0xbdc4, 0xbdc5, 0xbdc5, 0xbdc5, 0xbdc6, 0xbdc6, 0xbdc6, 
+    0xbdc7, 0xbdc7, 0xbdc7, 0xbdc8, 0xbdc8, 0xbdc8, 0xbdc9, 0xbdc9, 
+    0xbdc9, 0xbdca, 0xbdca, 0xbdca, 0xbdcb, 0xbdcb, 0xbdcb, 0xbdcc, 
+    0xbdcc, 0xbdcc, 0xbdcd, 0xbdcd, 0xbdce, 0xbdce, 0xbdce, 0xbdcf, 
+    0xbdcf, 0xbdcf, 0xbdd0, 0xbdd0, 0xbdd0, 0xbdd1, 0xbdd1, 0xbdd1, 
+    0xbdd2, 0xbdd2, 0xbdd2, 0xbdd3, 0xbdd3, 0xbdd3, 0xbdd4, 0xbdd4, 
+    0xbdd4, 0xbdd5, 0xbdd5, 0xbdd5, 0xbdd6, 0xbdd6, 0xbdd6, 0xbdd7, 
+    0xbdd7, 0xbdd7, 0xbdd8, 0xbdd8, 0xbdd8, 0xbdd9, 0xbdd9, 0xbdd9, 
+    0xbdd9, 0xbdda, 0xbdda, 0xbdda, 0xbddb, 0xbddb, 0xbddb, 0xbddc, 
+    0xbddc, 0xbddc, 0xbddd, 0xbddd, 0xbddd, 0xbdde, 0xbdde, 0xbdde, 
+    0xbddf, 0xbddf, 0xbddf, 0xbde0, 0xbde0, 0xbde0, 0xbde1, 0xbde1, 
+    0xbde1, 0xbde2, 0xbde2, 0xbde2, 0xbde3, 0xbde3, 0xbde3, 0xbde4, 
+    0xbde4, 0xbde4, 0xbde5, 0xbde5, 0xbde5, 0xbde5, 0xbde6, 0xbde6, 
+    0xbde6, 0xbde7, 0xbde7, 0xbde7, 0xbde8, 0xbde8, 0xbde8, 0xbde9, 
+    0xbde9, 0xbde9, 0xbdea, 0xbdea, 0xbdea, 0xbdeb, 0xbdeb, 0xbdeb, 
+    0xbdec, 0xbdec, 0xbdec, 0xbdec, 0xbded, 0xbded, 0xbded, 0xbdee, 
+    0xbdee, 0xbdee, 0xbdef, 0xbdef, 0xbdef, 0xbdf0, 0xbdf0, 0xbdf0, 
+    0xbdf1, 0xbdf1, 0xbdf1, 0xbdf2, 0xbdf2, 0xbdf2, 0xbdf2, 0xbdf3, 
+    0xbdf3, 0xbdf3, 0xbdf4, 0xbdf4, 0xbdf4, 0xbdf5, 0xbdf5, 0xbdf5, 
+    0xbdf6, 0xbdf6, 0xbdf6, 0xbdf6, 0xbdf7, 0xbdf7, 0xbdf7, 0xbdf8, 
+    0xbdf8, 0xbdf8, 0xbdf9, 0xbdf9, 0xbdf9, 0xbdfa, 0xbdfa, 0xbdfa, 
+    0xbdfa, 0xbdfb, 0xbdfb, 0xbdfb, 0xbdfc, 0xbdfc, 0xbdfc, 0xbdfd, 
+    0xbdfd, 0xbdfd, 0xbdfe, 0xbdfe, 0xbdfe, 0xbdfe, 0xbdff, 0xbdff, 
+    0xbdff, 0xbe00, 0xbe00, 0xbe00, 0xbe01, 0xbe01, 0xbe01, 0xbe01, 
+    0xbe02, 0xbe02, 0xbe02, 0xbe03, 0xbe03, 0xbe03, 0xbe04, 0xbe04, 
+    0xbe04, 0xbe04, 0xbe05, 0xbe05, 0xbe05, 0xbe06, 0xbe06, 0xbe06, 
+    0xbe07, 0xbe07, 0xbe07, 0xbe07, 0xbe08, 0xbe08, 0xbe08, 0xbe09, 
+    0xbe09, 0xbe09, 0xbe0a, 0xbe0a, 0xbe0a, 0xbe0a, 0xbe0b, 0xbe0b, 
+    0xbe0b, 0xbe0c, 0xbe0c, 0xbe0c, 0xbe0c, 0xbe0d, 0xbe0d, 0xbe0d, 
+    0xbe0e, 0xbe0e, 0xbe0e, 0xbe0f, 0xbe0f, 0xbe0f, 0xbe0f, 0xbe10, 
+    0xbe10, 0xbe10, 0xbe11, 0xbe11, 0xbe11, 0xbe11, 0xbe12, 0xbe12, 
+    0xbe12, 0xbe13, 0xbe13, 0xbe13, 0xbe14, 0xbe14, 0xbe14, 0xbe14, 
+    0xbe15, 0xbe15, 0xbe15, 0xbe16, 0xbe16, 0xbe16, 0xbe16, 0xbe17, 
+    0xbe17, 0xbe17, 0xbe18, 0xbe18, 0xbe18, 0xbe18, 0xbe19, 0xbe19, 
+    0xbe19, 0xbe1a, 0xbe1a, 0xbe1a, 0xbe1a, 0xbe1b, 0xbe1b, 0xbe1b, 
+    0xbe1c, 0xbe1c, 0xbe1c, 0xbe1c, 0xbe1d, 0xbe1d, 0xbe1d, 0xbe1e, 
+    0xbe1e, 0xbe1e, 0xbe1e, 0xbe1f, 0xbe1f, 0xbe1f, 0xbe20, 0xbe20, 
+    0xbe20, 0xbe20, 0xbe21, 0xbe21, 0xbe21, 0xbe22, 0xbe22, 0xbe22, 
+    0xbe22, 0xbe23, 0xbe23, 0xbe23, 0xbe23, 0xbe24, 0xbe24, 0xbe24, 
+    0xbe25, 0xbe25, 0xbe25, 0xbe25, 0xbe26, 0xbe26, 0xbe26, 0xbe27, 
+    0xbe27, 0xbe27, 0xbe27, 0xbe28, 0xbe28, 0xbe28, 0xbe29, 0xbe29, 
+    0xbe29, 0xbe29, 0xbe2a, 0xbe2a, 0xbe2a, 0xbe2a, 0xbe2b, 0xbe2b, 
+    0xbe2b, 0xbe2c, 0xbe2c, 0xbe2c, 0xbe2c, 0xbe2d, 0xbe2d, 0xbe2d, 
+    0xbe2d, 0xbe2e, 0xbe2e, 0xbe2e, 0xbe2f, 0xbe2f, 0xbe2f, 0xbe2f, 
+    0xbe30, 0xbe30, 0xbe30, 0xbe30, 0xbe31, 0xbe31, 0xbe31, 0xbe32, 
+    0xbe32, 0xbe32, 0xbe32, 0xbe33, 0xbe33, 0xbe33, 0xbe33, 0xbe34, 
+    0xbe34, 0xbe34, 0xbe35, 0xbe35, 0xbe35, 0xbe35, 0xbe36, 0xbe36, 
+    0xbe36, 0xbe36, 0xbe37, 0xbe37, 0xbe37, 0xbe38, 0xbe38, 0xbe38, 
+    0xbe38, 0xbe39, 0xbe39, 0xbe39, 0xbe39, 0xbe3a, 0xbe3a, 0xbe3a, 
+    0xbe3a, 0xbe3b, 0xbe3b, 0xbe3b, 0xbe3c, 0xbe3c, 0xbe3c, 0xbe3c, 
+    0xbe3d, 0xbe3d, 0xbe3d, 0xbe3d, 0xbe3e, 0xbe3e, 0xbe3e, 0xbe3e, 
+    0xbe3f, 0xbe3f, 0xbe3f, 0xbe40, 0xbe40, 0xbe40, 0xbe40, 0xbe41, 
+    0xbe41, 0xbe41, 0xbe41, 0xbe42, 0xbe42, 0xbe42, 0xbe42, 0xbe43, 
+    0xbe43, 0xbe43, 0xbe43, 0xbe44, 0xbe44, 0xbe44, 0xbe44, 0xbe45, 
+    0xbe45, 0xbe45, 0xbe46, 0xbe46, 0xbe46, 0xbe46, 0xbe47, 0xbe47, 
+    0xbe47, 0xbe47, 0xbe48, 0xbe48, 0xbe48, 0xbe48, 0xbe49, 0xbe49, 
+    0xbe49, 0xbe49, 0xbe4a, 0xbe4a, 0xbe4a, 0xbe4a, 0xbe4b, 0xbe4b, 
+    0xbe4b, 0xbe4b, 0xbe4c, 0xbe4c, 0xbe4c, 0xbe4d, 0xbe4d, 0xbe4d, 
+    0xbe4d, 0xbe4e, 0xbe4e, 0xbe4e, 0xbe4e, 0xbe4f, 0xbe4f, 0xbe4f, 
+    0xbe4f, 0xbe50, 0xbe50, 0xbe50, 0xbe50, 0xbe51, 0xbe51, 0xbe51, 
+    0xbe51, 0xbe52, 0xbe52, 0xbe52, 0xbe52, 0xbe53, 0xbe53, 0xbe53, 
+    0xbe53, 0xbe54, 0xbe54, 0xbe54, 0xbe54, 0xbe55, 0xbe55, 0xbe55, 
+    0xbe55, 0xbe56, 0xbe56, 0xbe56, 0xbe56, 0xbe57, 0xbe57, 0xbe57, 
+    0xbe57, 0xbe58, 0xbe58, 0xbe58, 0xbe58, 0xbe59, 0xbe59, 0xbe59, 
+    0xbe59, 0xbe5a, 0xbe5a, 0xbe5a, 0xbe5a, 0xbe5b, 0xbe5b, 0xbe5b, 
+    0xbe5b, 0xbe5c, 0xbe5c, 0xbe5c, 0xbe5c, 0xbe5d, 0xbe5d, 0xbe5d, 
+    0xbe5d, 0xbe5e, 0xbe5e, 0xbe5e, 0xbe5e, 0xbe5f, 0xbe5f, 0xbe5f, 
+    0xbe5f, 0xbe60, 0xbe60, 0xbe60, 0xbe60, 0xbe61, 0xbe61, 0xbe61, 
+    0xbe61, 0xbe62, 0xbe62, 0xbe62, 0xbe62, 0xbe63, 0xbe63, 0xbe63, 
+    0xbe63, 0xbe64, 0xbe64, 0xbe64, 0xbe64, 0xbe65, 0xbe65, 0xbe65, 
+    0xbe65, 0xbe66, 0xbe66, 0xbe66, 0xbe66, 0xbe66, 0xbe67, 0xbe67, 
+    0xbe67, 0xbe67, 0xbe68, 0xbe68, 0xbe68, 0xbe68, 0xbe69, 0xbe69, 
+    0xbe69, 0xbe69, 0xbe6a, 0xbe6a, 0xbe6a, 0xbe6a, 0xbe6b, 0xbe6b, 
+    0xbe6b, 0xbe6b, 0xbe6c, 0xbe6c, 0xbe6c, 0xbe6c, 0xbe6d, 0xbe6d, 
+    0xbe6d, 0xbe6d, 0xbe6d, 0xbe6e, 0xbe6e, 0xbe6e, 0xbe6e, 0xbe6f, 
+    0xbe6f, 0xbe6f, 0xbe6f, 0xbe70, 0xbe70, 0xbe70, 0xbe70, 0xbe71, 
+    0xbe71, 0xbe71, 0xbe71, 0xbe72, 0xbe72, 0xbe72, 0xbe72, 0xbe72, 
+    0xbe73, 0xbe73, 0xbe73, 0xbe73, 0xbe74, 0xbe74, 0xbe74, 0xbe74, 
+    0xbe75, 0xbe75, 0xbe75, 0xbe75, 0xbe76, 0xbe76, 0xbe76, 0xbe76, 
+    0xbe76, 0xbe77, 0xbe77, 0xbe77, 0xbe77, 0xbe78, 0xbe78, 0xbe78, 
+    0xbe78, 0xbe79, 0xbe79, 0xbe79, 0xbe79, 0xbe7a, 0xbe7a, 0xbe7a, 
+    0xbe7a, 0xbe7a, 0xbe7b, 0xbe7b, 0xbe7b, 0xbe7b, 0xbe7c, 0xbe7c, 
+    0xbe7c, 0xbe7c, 0xbe7d, 0xbe7d, 0xbe7d, 0xbe7d, 0xbe7d, 0xbe7e, 
+    0xbe7e, 0xbe7e, 0xbe7e, 0xbe7f, 0xbe7f, 0xbe7f, 0xbe7f, 0xbe80, 
+    0xbe80, 0xbe80, 0xbe80, 0xbe80, 0xbe81, 0xbe81, 0xbe81, 0xbe81, 
+    0xbe82, 0xbe82, 0xbe82, 0xbe82, 0xbe83, 0xbe83, 0xbe83, 0xbe83, 
+    0xbe83, 0xbe84, 0xbe84, 0xbe84, 0xbe84, 0xbe85, 0xbe85, 0xbe85, 
+    0xbe85, 0xbe86, 0xbe86, 0xbe87, 0xbe87, 0xbe88, 0xbe88, 0xbe88, 
+    0xbe89, 0xbe89, 0xbe8a, 0xbe8a, 0xbe8b, 0xbe8b, 0xbe8c, 0xbe8c, 
+    0xbe8c, 0xbe8d, 0xbe8d, 0xbe8e, 0xbe8e, 0xbe8f, 0xbe8f, 0xbe90, 
+    0xbe90, 0xbe90, 0xbe91, 0xbe91, 0xbe92, 0xbe92, 0xbe93, 0xbe93, 
+    0xbe94, 0xbe94, 0xbe94, 0xbe95, 0xbe95, 0xbe96, 0xbe96, 0xbe97, 
+    0xbe97, 0xbe98, 0xbe98, 0xbe98, 0xbe99, 0xbe99, 0xbe9a, 0xbe9a, 
+    0xbe9b, 0xbe9b, 0xbe9b, 0xbe9c, 0xbe9c, 0xbe9d, 0xbe9d, 0xbe9e, 
+    0xbe9e, 0xbe9e, 0xbe9f, 0xbe9f, 0xbea0, 0xbea0, 0xbea1, 0xbea1, 
+    0xbea1, 0xbea2, 0xbea2, 0xbea3, 0xbea3, 0xbea4, 0xbea4, 0xbea4, 
+    0xbea5, 0xbea5, 0xbea6, 0xbea6, 0xbea7, 0xbea7, 0xbea7, 0xbea8, 
+    0xbea8, 0xbea9, 0xbea9, 0xbeaa, 0xbeaa, 0xbeaa, 0xbeab, 0xbeab, 
+    0xbeac, 0xbeac, 0xbeac, 0xbead, 0xbead, 0xbeae, 0xbeae, 0xbeaf, 
+    0xbeaf, 0xbeaf, 0xbeb0, 0xbeb0, 0xbeb1, 0xbeb1, 0xbeb1, 0xbeb2, 
+    0xbeb2, 0xbeb3, 0xbeb3, 0xbeb4, 0xbeb4, 0xbeb4, 0xbeb5, 0xbeb5, 
+    0xbeb6, 0xbeb6, 0xbeb6, 0xbeb7, 0xbeb7, 0xbeb8, 0xbeb8, 0xbeb8, 
+    0xbeb9, 0xbeb9, 0xbeba, 0xbeba, 0xbeba, 0xbebb, 0xbebb, 0xbebc, 
+    0xbebc, 0xbebc, 0xbebd, 0xbebd, 0xbebe, 0xbebe, 0xbebe, 0xbebf, 
+    0xbebf, 0xbec0, 0xbec0, 0xbec1, 0xbec1, 0xbec1, 0xbec2, 0xbec2, 
+    0xbec2, 0xbec3, 0xbec3, 0xbec4, 0xbec4, 0xbec4, 0xbec5, 0xbec5, 
+    0xbec6, 0xbec6, 0xbec6, 0xbec7, 0xbec7, 0xbec8, 0xbec8, 0xbec8, 
+    0xbec9, 0xbec9, 0xbeca, 0xbeca, 0xbeca, 0xbecb, 0xbecb, 0xbecc, 
+    0xbecc, 0xbecc, 0xbecd, 0xbecd, 0xbece, 0xbece, 0xbece, 0xbecf, 
+    0xbecf, 0xbecf, 0xbed0, 0xbed0, 0xbed1, 0xbed1, 0xbed1, 0xbed2, 
+    0xbed2, 0xbed3, 0xbed3, 0xbed3, 0xbed4, 0xbed4, 0xbed4, 0xbed5, 
+    0xbed5, 0xbed6, 0xbed6, 0xbed6, 0xbed7, 0xbed7, 0xbed8, 0xbed8, 
+    0xbed8, 0xbed9, 0xbed9, 0xbed9, 0xbeda, 0xbeda, 0xbedb, 0xbedb, 
+    0xbedb, 0xbedc, 0xbedc, 0xbedc, 0xbedd, 0xbedd, 0xbede, 0xbede, 
+    0xbede, 0xbedf, 0xbedf, 0xbedf, 0xbee0, 0xbee0, 0xbee1, 0xbee1, 
+    0xbee1, 0xbee2, 0xbee2, 0xbee2, 0xbee3, 0xbee3, 0xbee4, 0xbee4, 
+    0xbee4, 0xbee5, 0xbee5, 0xbee5, 0xbee6, 0xbee6, 0xbee7, 0xbee7, 
+    0xbee7, 0xbee8, 0xbee8, 0xbee8, 0xbee9, 0xbee9, 0xbee9, 0xbeea, 
+    0xbeea, 0xbeeb, 0xbeeb, 0xbeeb, 0xbeec, 0xbeec, 0xbeec, 0xbeed, 
+    0xbeed, 0xbeed, 0xbeee, 0xbeee, 0xbeef, 0xbeef, 0xbeef, 0xbef0, 
+    0xbef0, 0xbef0, 0xbef1, 0xbef1, 0xbef1, 0xbef2, 0xbef2, 0xbef3, 
+    0xbef3, 0xbef3, 0xbef4, 0xbef4, 0xbef4, 0xbef5, 0xbef5, 0xbef5, 
+    0xbef6, 0xbef6, 0xbef6, 0xbef7, 0xbef7, 0xbef8, 0xbef8, 0xbef8, 
+    0xbef9, 0xbef9, 0xbef9, 0xbefa, 0xbefa, 0xbefa, 0xbefb, 0xbefb, 
+    0xbefb, 0xbefc, 0xbefc, 0xbefc, 0xbefd, 0xbefd, 0xbefe, 0xbefe, 
+    0xbefe, 0xbeff, 0xbeff, 0xbeff, 0xbf00, 0xbf00, 0xbf00, 0xbf01, 
+    0xbf01, 0xbf01, 0xbf02, 0xbf02, 0xbf02, 0xbf03, 0xbf03, 0xbf03, 
+    0xbf04, 0xbf04, 0xbf05, 0xbf05, 0xbf05, 0xbf06, 0xbf06, 0xbf06, 
+    0xbf07, 0xbf07, 0xbf07, 0xbf08, 0xbf08, 0xbf08, 0xbf09, 0xbf09, 
+    0xbf09, 0xbf0a, 0xbf0a, 0xbf0a, 0xbf0b, 0xbf0b, 0xbf0b, 0xbf0c, 
+    0xbf0c, 0xbf0c, 0xbf0d, 0xbf0d, 0xbf0d, 0xbf0e, 0xbf0e, 0xbf0e, 
+    0xbf0f, 0xbf0f, 0xbf0f, 0xbf10, 0xbf10, 0xbf10, 0xbf11, 0xbf11, 
+    0xbf11, 0xbf12, 0xbf12, 0xbf12, 0xbf13, 0xbf13, 0xbf13, 0xbf14, 
+    0xbf14, 0xbf14, 0xbf15, 0xbf15, 0xbf15, 0xbf16, 0xbf16, 0xbf16, 
+    0xbf17, 0xbf17, 0xbf17, 0xbf18, 0xbf18, 0xbf18, 0xbf19, 0xbf19, 
+    0xbf19, 0xbf1a, 0xbf1a, 0xbf1a, 0xbf1b, 0xbf1b, 0xbf1b, 0xbf1c, 
+    0xbf1c, 0xbf1c, 0xbf1d, 0xbf1d, 0xbf1d, 0xbf1e, 0xbf1e, 0xbf1e, 
+    0xbf1f, 0xbf1f, 0xbf1f, 0xbf20, 0xbf20, 0xbf20, 0xbf21, 0xbf21, 
+    0xbf21, 0xbf22, 0xbf22, 0xbf22, 0xbf23, 0xbf23, 0xbf23, 0xbf24, 
+    0xbf24, 0xbf24, 0xbf25, 0xbf25, 0xbf25, 0xbf26, 0xbf26, 0xbf26, 
+    0xbf27, 0xbf27, 0xbf27, 0xbf27, 0xbf28, 0xbf28, 0xbf28, 0xbf29, 
+    0xbf29, 0xbf29, 0xbf2a, 0xbf2a, 0xbf2a, 0xbf2b, 0xbf2b, 0xbf2b, 
+    0xbf2c, 0xbf2c, 0xbf2c, 0xbf2d, 0xbf2d, 0xbf2d, 0xbf2e, 0xbf2e, 
+    0xbf2e, 0xbf2e, 0xbf2f, 0xbf2f, 0xbf2f, 0xbf30, 0xbf30, 0xbf30, 
+    0xbf31, 0xbf31, 0xbf31, 0xbf32, 0xbf32, 0xbf32, 0xbf33, 0xbf33, 
+    0xbf33, 0xbf34, 0xbf34, 0xbf34, 0xbf34, 0xbf35, 0xbf35, 0xbf35, 
+    0xbf36, 0xbf36, 0xbf36, 0xbf37, 0xbf37, 0xbf37, 0xbf38, 0xbf38, 
+    0xbf38, 0xbf38, 0xbf39, 0xbf39, 0xbf39, 0xbf3a, 0xbf3a, 0xbf3a, 
+    0xbf3b, 0xbf3b, 0xbf3b, 0xbf3c, 0xbf3c, 0xbf3c, 0xbf3c, 0xbf3d, 
+    0xbf3d, 0xbf3d, 0xbf3e, 0xbf3e, 0xbf3e, 0xbf3f, 0xbf3f, 0xbf3f, 
+    0xbf40, 0xbf40, 0xbf40, 0xbf40, 0xbf41, 0xbf41, 0xbf41, 0xbf42, 
+    0xbf42, 0xbf42, 0xbf43, 0xbf43, 0xbf43, 0xbf43, 0xbf44, 0xbf44, 
+    0xbf44, 0xbf45, 0xbf45, 0xbf45, 0xbf46, 0xbf46, 0xbf46, 0xbf47, 
+    0xbf47, 0xbf47, 0xbf47, 0xbf48, 0xbf48, 0xbf48, 0xbf49, 0xbf49, 
+    0xbf49, 0xbf49, 0xbf4a, 0xbf4a, 0xbf4a, 0xbf4b, 0xbf4b, 0xbf4b, 
+    0xbf4c, 0xbf4c, 0xbf4c, 0xbf4c, 0xbf4d, 0xbf4d, 0xbf4d, 0xbf4e, 
+    0xbf4e, 0xbf4e, 0xbf4f, 0xbf4f, 0xbf4f, 0xbf4f, 0xbf50, 0xbf50, 
+    0xbf50, 0xbf51, 0xbf51, 0xbf51, 0xbf51, 0xbf52, 0xbf52, 0xbf52, 
+    0xbf53, 0xbf53, 0xbf53, 0xbf54, 0xbf54, 0xbf54, 0xbf54, 0xbf55, 
+    0xbf55, 0xbf55, 0xbf56, 0xbf56, 0xbf56, 0xbf56, 0xbf57, 0xbf57, 
+    0xbf57, 0xbf58, 0xbf58, 0xbf58, 0xbf58, 0xbf59, 0xbf59, 0xbf59, 
+    0xbf5a, 0xbf5a, 0xbf5a, 0xbf5a, 0xbf5b, 0xbf5b, 0xbf5b, 0xbf5c, 
+    0xbf5c, 0xbf5c, 0xbf5c, 0xbf5d, 0xbf5d, 0xbf5d, 0xbf5e, 0xbf5e, 
+    0xbf5e, 0xbf5e, 0xbf5f, 0xbf5f, 0xbf5f, 0xbf60, 0xbf60, 0xbf60, 
+    0xbf60, 0xbf61, 0xbf61, 0xbf61, 0xbf62, 0xbf62, 0xbf62, 0xbf62, 
+    0xbf63, 0xbf63, 0xbf63, 0xbf64, 0xbf64, 0xbf64, 0xbf64, 0xbf65, 
+    0xbf65, 0xbf65, 0xbf66, 0xbf66, 0xbf66, 0xbf66, 0xbf67, 0xbf67, 
+    0xbf67, 0xbf68, 0xbf68, 0xbf68, 0xbf68, 0xbf69, 0xbf69, 0xbf69, 
+    0xbf69, 0xbf6a, 0xbf6a, 0xbf6a, 0xbf6b, 0xbf6b, 0xbf6b, 0xbf6b, 
+    0xbf6c, 0xbf6c, 0xbf6c, 0xbf6d, 0xbf6d, 0xbf6d, 0xbf6d, 0xbf6e, 
+    0xbf6e, 0xbf6e, 0xbf6e, 0xbf6f, 0xbf6f, 0xbf6f, 0xbf70, 0xbf70, 
+    0xbf70, 0xbf70, 0xbf71, 0xbf71, 0xbf71, 0xbf71, 0xbf72, 0xbf72, 
+    0xbf72, 0xbf73, 0xbf73, 0xbf73, 0xbf73, 0xbf74, 0xbf74, 0xbf74, 
+    0xbf74, 0xbf75, 0xbf75, 0xbf75, 0xbf76, 0xbf76, 0xbf76, 0xbf76, 
+    0xbf77, 0xbf77, 0xbf77, 0xbf77, 0xbf78, 0xbf78, 0xbf78, 0xbf79, 
+    0xbf79, 0xbf79, 0xbf79, 0xbf7a, 0xbf7a, 0xbf7a, 0xbf7a, 0xbf7b, 
+    0xbf7b, 0xbf7b, 0xbf7b, 0xbf7c, 0xbf7c, 0xbf7c, 0xbf7d, 0xbf7d, 
+    0xbf7d, 0xbf7d, 0xbf7e, 0xbf7e, 0xbf7e, 0xbf7e, 0xbf7f, 0xbf7f, 
+    0xbf7f, 0xbf7f, 0xbf80, 0xbf80, 0xbf80, 0xbf81, 0xbf81, 0xbf81, 
+    0xbf81, 0xbf82, 0xbf82, 0xbf82, 0xbf82, 0xbf83, 0xbf83, 0xbf83, 
+    0xbf83, 0xbf84, 0xbf84, 0xbf84, 0xbf85, 0xbf85, 0xbf85, 0xbf85, 
+    0xbf86, 0xbf86, 0xbf86, 0xbf86, 0xbf87, 0xbf87, 0xbf87, 0xbf87, 
+    0xbf88, 0xbf88, 0xbf88, 0xbf88, 0xbf89, 0xbf89, 0xbf89, 0xbf89, 
+    0xbf8a, 0xbf8a, 0xbf8a, 0xbf8b, 0xbf8b, 0xbf8b, 0xbf8b, 0xbf8c, 
+    0xbf8c, 0xbf8c, 0xbf8c, 0xbf8d, 0xbf8d, 0xbf8d, 0xbf8d, 0xbf8e, 
+    0xbf8e, 0xbf8e, 0xbf8e, 0xbf8f, 0xbf8f, 0xbf8f, 0xbf8f, 0xbf90, 
+    0xbf90, 0xbf90, 0xbf90, 0xbf91, 0xbf91, 0xbf91, 0xbf91, 0xbf92, 
+    0xbf92, 0xbf92, 0xbf92, 0xbf93, 0xbf93, 0xbf93, 0xbf93, 0xbf94, 
+    0xbf94, 0xbf94, 0xbf95, 0xbf95, 0xbf95, 0xbf95, 0xbf96, 0xbf96, 
+    0xbf96, 0xbf96, 0xbf97, 0xbf97, 0xbf97, 0xbf97, 0xbf98, 0xbf98, 
+    0xbf98, 0xbf98, 0xbf99, 0xbf99, 0xbf99, 0xbf99, 0xbf9a, 0xbf9a, 
+    0xbf9a, 0xbf9a, 0xbf9b, 0xbf9b, 0xbf9b, 0xbf9b, 0xbf9c, 0xbf9c, 
+    0xbf9c, 0xbf9c, 0xbf9d, 0xbf9d, 0xbf9d, 0xbf9d, 0xbf9e, 0xbf9e, 
+    0xbf9e, 0xbf9e, 0xbf9f, 0xbf9f, 0xbf9f, 0xbf9f, 0xbfa0, 0xbfa0, 
+    0xbfa0, 0xbfa0, 0xbfa1, 0xbfa1, 0xbfa1, 0xbfa1, 0xbfa2, 0xbfa2, 
+    0xbfa2, 0xbfa2, 0xbfa3, 0xbfa3, 0xbfa3, 0xbfa3, 0xbfa3, 0xbfa4, 
+    0xbfa4, 0xbfa4, 0xbfa4, 0xbfa5, 0xbfa5, 0xbfa5, 0xbfa5, 0xbfa6, 
+    0xbfa6, 0xbfa6, 0xbfa6, 0xbfa7, 0xbfa7, 0xbfa7, 0xbfa7, 0xbfa8, 
+    0xbfa8, 0xbfa8, 0xbfa8, 0xbfa9, 0xbfa9, 0xbfa9, 0xbfa9, 0xbfaa, 
+    0xbfaa, 0xbfaa, 0xbfaa, 0xbfab, 0xbfab, 0xbfab, 0xbfab, 0xbfac, 
+    0xbfac, 0xbfac, 0xbfac, 0xbfad, 0xbfad, 0xbfad, 0xbfad, 0xbfad, 
+    0xbfae, 0xbfae, 0xbfae, 0xbfae, 0xbfaf, 0xbfaf, 0xbfaf, 0xbfaf, 
+    0xbfb0, 0xbfb0, 0xbfb0, 0xbfb0, 0xbfb1, 0xbfb1, 0xbfb1, 0xbfb1, 
+    0xbfb2, 0xbfb2, 0xbfb2, 0xbfb2, 0xbfb2, 0xbfb3, 0xbfb3, 0xbfb3, 
+    0xbfb3, 0xbfb4, 0xbfb4, 0xbfb4, 0xbfb4, 0xbfb5, 0xbfb5, 0xbfb5, 
+    0xbfb5, 0xbfb6, 0xbfb6, 0xbfb6, 0xbfb6, 0xbfb7, 0xbfb7, 0xbfb7, 
+    0xbfb7, 0xbfb7, 0xbfb8, 0xbfb8, 0xbfb8, 0xbfb8, 0xbfb9, 0xbfb9, 
+    0xbfb9, 0xbfb9, 0xbfba, 0xbfba, 0xbfba, 0xbfba, 0xbfbb, 0xbfbb, 
+    0xbfbb, 0xbfbb, 0xbfbb, 0xbfbc, 0xbfbc, 0xbfbc, 0xbfbc, 0xbfbd, 
+    0xbfbd, 0xbfbd, 0xbfbd, 0xbfbe, 0xbfbe, 0xbfbe, 0xbfbe, 0xbfbe, 
+    0xbfbf, 0xbfbf, 0xbfbf, 0xbfbf, 0xbfc0, 0xbfc0, 0xbfc0, 0xbfc0, 
+    0xbfc1, 0xbfc1, 0xbfc1, 0xbfc1, 0xbfc1, 0xbfc2, 0xbfc2, 0xbfc2, 
+    0xbfc2, 0xbfc3, 0xbfc3, 0xbfc3, 0xbfc3, 0xbfc4, 0xbfc4, 0xbfc4, 
+    0xbfc4, 0xbfc4, 0xbfc5, 0xbfc5, 0xbfc5, 0xbfc5, 0xbfc6, 0xbfc6, 
+    0xbfc6, 0xbfc6, 0xbfc7, 0xbfc7, 0xbfc7, 0xbfc7, 0xbfc7, 0xbfc8, 
+    0xbfc8, 0xbfc8, 0xbfc9, 0xbfc9, 0xbfca, 0xbfca, 0xbfcb, 0xbfcb, 
+    0xbfcc, 0xbfcc, 0xbfcc, 0xbfcd, 0xbfcd, 0xbfce, 0xbfce, 0xbfcf, 
+    0xbfcf, 0xbfd0, 0xbfd0, 0xbfd0, 0xbfd1, 0xbfd1, 0xbfd2, 0xbfd2, 
+    0xbfd3, 0xbfd3, 0xbfd4, 0xbfd4, 0xbfd4, 0xbfd5, 0xbfd5, 0xbfd6, 
+    0xbfd6, 0xbfd7, 0xbfd7, 0xbfd8, 0xbfd8, 0xbfd8, 0xbfd9, 0xbfd9, 
+    0xbfda, 0xbfda, 0xbfdb, 0xbfdb, 0xbfdb, 0xbfdc, 0xbfdc, 0xbfdd, 
+    0xbfdd, 0xbfde, 0xbfde, 0xbfdf, 0xbfdf, 0xbfdf, 0xbfe0, 0xbfe0, 
+    0xbfe1, 0xbfe1, 0xbfe2, 0xbfe2, 0xbfe2, 0xbfe3, 0xbfe3, 0xbfe4, 
+    0xbfe4, 0xbfe5, 0xbfe5, 0xbfe5, 0xbfe6, 0xbfe6, 0xbfe7, 0xbfe7, 
+    0xbfe8, 0xbfe8, 0xbfe8, 0xbfe9, 0xbfe9, 0xbfea, 0xbfea, 0xbfea, 
+    0xbfeb, 0xbfeb, 0xbfec, 0xbfec, 0xbfed, 0xbfed, 0xbfed, 0xbfee, 
+    0xbfee, 0xbfef, 0xbfef, 0xbff0, 0xbff0, 0xbff0, 0xbff1, 0xbff1, 
+    0xbff2, 0xbff2, 0xbff2, 0xbff3, 0xbff3, 0xbff4, 0xbff4, 0xbff4, 
+    0xbff5, 0xbff5, 0xbff6, 0xbff6, 0xbff7, 0xbff7, 0xbff7, 0xbff8, 
+    0xbff8, 0xbff9, 0xbff9, 0xbff9, 0xbffa, 0xbffa, 0xbffb, 0xbffb, 
+    0xbffb, 0xbffc, 0xbffc, 0xbffd, 0xbffd, 0xbffd, 0xbffe, 0xbffe, 
+    0xbfff, 0xbfff, 0xc000, 0xc000, 0xc000, 0xc000, 0xc001, 0xc001, 
+    0xc001, 0xc001, 0xc001, 0xc002, 0xc002, 0xc002, 0xc002, 0xc002, 
+    0xc003, 0xc003, 0xc003, 0xc003, 0xc003, 0xc004, 0xc004, 0xc004, 
+    0xc004, 0xc004, 0xc005, 0xc005, 0xc005, 0xc005, 0xc005, 0xc006, 
+    0xc006, 0xc006, 0xc006, 0xc006, 0xc007, 0xc007, 0xc007, 0xc007, 
+    0xc007, 0xc007, 0xc008, 0xc008, 0xc008, 0xc008, 0xc008, 0xc009, 
+    0xc009, 0xc009, 0xc009, 0xc009, 0xc00a, 0xc00a, 0xc00a, 0xc00a, 
+    0xc00a, 0xc00b, 0xc00b, 0xc00b, 0xc00b, 0xc00b, 0xc00c, 0xc00c, 
+    0xc00c, 0xc00c, 0xc00c, 0xc00d, 0xc00d, 0xc00d, 0xc00d, 0xc00d, 
+    0xc00d, 0xc00e, 0xc00e, 0xc00e, 0xc00e, 0xc00e, 0xc00f, 0xc00f, 
+    0xc00f, 0xc00f, 0xc00f, 0xc010, 0xc010, 0xc010, 0xc010, 0xc010, 
+    0xc010, 0xc011, 0xc011, 0xc011, 0xc011, 0xc011, 0xc012, 0xc012, 
+    0xc012, 0xc012, 0xc012, 0xc013, 0xc013, 0xc013, 0xc013, 0xc013, 
+    0xc013, 0xc014, 0xc014, 0xc014, 0xc014, 0xc014, 0xc015, 0xc015, 
+    0xc015, 0xc015, 0xc015, 0xc015, 0xc016, 0xc016, 0xc016, 0xc016, 
+    0xc016, 0xc017, 0xc017, 0xc017, 0xc017, 0xc017, 0xc018, 0xc018, 
+    0xc018, 0xc018, 0xc018, 0xc018, 0xc019, 0xc019, 0xc019, 0xc019, 
+    0xc019, 0xc01a, 0xc01a, 0xc01a, 0xc01a, 0xc01a, 0xc01a, 0xc01b, 
+    0xc01b, 0xc01b, 0xc01b, 0xc01b, 0xc01b, 0xc01c, 0xc01c, 0xc01c, 
+    0xc01c, 0xc01c, 0xc01d, 0xc01d, 0xc01d, 0xc01d, 0xc01d, 0xc01d, 
+    0xc01e, 0xc01e, 0xc01e, 0xc01e, 0xc01e, 0xc01f, 0xc01f, 0xc01f, 
+    0xc01f, 0xc01f, 0xc01f, 0xc020, 0xc020, 0xc020, 0xc020, 0xc020, 
+    0xc020, 0xc021, 0xc021, 0xc021, 0xc021, 0xc021, 0xc021, 0xc022, 
+    0xc022, 0xc022, 0xc022, 0xc022, 0xc023, 0xc023, 0xc023, 0xc023, 
+    0xc023, 0xc023, 0xc024, 0xc024, 0xc024, 0xc024, 0xc024, 0xc024, 
+    0xc025, 0xc025, 0xc025, 0xc025, 0xc025, 0xc025, 0xc026, 0xc026, 
+    0xc026, 0xc026, 0xc026, 0xc026, 0xc027, 0xc027, 0xc027, 0xc027, 
+    0xc027, 0xc028, 0xc028, 0xc028, 0xc028, 0xc028, 0xc028, 0xc029, 
+    0xc029, 0xc029, 0xc029, 0xc029, 0xc029, 0xc02a, 0xc02a, 0xc02a, 
+    0xc02a, 0xc02a, 0xc02a, 0xc02b, 0xc02b, 0xc02b, 0xc02b, 0xc02b, 
+    0xc02b, 0xc02c, 0xc02c, 0xc02c, 0xc02c, 0xc02c, 0xc02c, 0xc02d, 
+    0xc02d, 0xc02d, 0xc02d, 0xc02d, 0xc02d, 0xc02e, 0xc02e, 0xc02e, 
+    0xc02e, 0xc02e, 0xc02e, 0xc02f, 0xc02f, 0xc02f, 0xc02f, 0xc02f, 
+    0xc02f, 0xc030, 0xc030, 0xc030, 0xc030, 0xc030, 0xc030, 0xc031, 
+    0xc031, 0xc031, 0xc031, 0xc031, 0xc031, 0xc032, 0xc032, 0xc032, 
+    0xc032, 0xc032, 0xc032, 0xc032, 0xc033, 0xc033, 0xc033, 0xc033, 
+    0xc033, 0xc033, 0xc034, 0xc034, 0xc034, 0xc034, 0xc034, 0xc034, 
+    0xc035, 0xc035, 0xc035, 0xc035, 0xc035, 0xc035, 0xc036, 0xc036, 
+    0xc036, 0xc036, 0xc036, 0xc036, 0xc036, 0xc037, 0xc037, 0xc037, 
+    0xc037, 0xc037, 0xc037, 0xc038, 0xc038, 0xc038, 0xc038, 0xc038, 
+    0xc038, 0xc039, 0xc039, 0xc039, 0xc039, 0xc039, 0xc039, 0xc03a, 
+    0xc03a, 0xc03a, 0xc03a, 0xc03a, 0xc03a, 0xc03a, 0xc03b, 0xc03b, 
+    0xc03b, 0xc03b, 0xc03b, 0xc03b, 0xc03c, 0xc03c, 0xc03c, 0xc03c, 
+    0xc03c, 0xc03c, 0xc03c, 0xc03d, 0xc03d, 0xc03d, 0xc03d, 0xc03d, 
+    0xc03d, 0xc03e, 0xc03e, 0xc03e, 0xc03e, 0xc03e, 0xc03e, 0xc03e, 
+    0xc03f, 0xc03f, 0xc03f, 0xc03f, 0xc03f, 0xc03f, 0xc040, 0xc040, 
+    0xc040, 0xc040, 0xc040, 0xc040, 0xc040, 0xc041, 0xc041, 0xc041, 
+    0xc041, 0xc041, 0xc041, 0xc042, 0xc042, 0xc042, 0xc042, 0xc042, 
+    0xc042, 0xc042, 0xc043, 0xc043, 0xc043, 0xc043, 0xc043, 0xc043, 
+    0xc044, 0xc044, 0xc044, 0xc044, 0xc044, 0xc044, 0xc044, 0xc045, 
+    0xc045, 0xc045, 0xc045, 0xc045, 0xc045, 0xc045, 0xc046, 0xc046, 
+    0xc046, 0xc046, 0xc046, 0xc046, 0xc047, 0xc047, 0xc047, 0xc047, 
+    0xc047, 0xc047, 0xc047, 0xc048, 0xc048, 0xc048, 0xc048, 0xc048, 
+    0xc048, 0xc048, 0xc049, 0xc049, 0xc049, 0xc049, 0xc049, 0xc049, 
+    0xc049, 0xc04a, 0xc04a, 0xc04a, 0xc04a, 0xc04a, 0xc04a, 0xc04a, 
+    0xc04b, 0xc04b, 0xc04b, 0xc04b, 0xc04b, 0xc04b, 0xc04c, 0xc04c, 
+    0xc04c, 0xc04c, 0xc04c, 0xc04c, 0xc04c, 0xc04d, 0xc04d, 0xc04d, 
+    0xc04d, 0xc04d, 0xc04d, 0xc04d, 0xc04e, 0xc04e, 0xc04e, 0xc04e, 
+    0xc04e, 0xc04e, 0xc04e, 0xc04f, 0xc04f, 0xc04f, 0xc04f, 0xc04f, 
+    0xc04f, 0xc04f, 0xc050, 0xc050, 0xc050, 0xc050, 0xc050, 0xc050, 
+    0xc050, 0xc051, 0xc051, 0xc051, 0xc051, 0xc051, 0xc051, 0xc051, 
+    0xc052, 0xc052, 0xc052, 0xc052, 0xc052, 0xc052, 0xc052, 0xc053, 
+    0xc053, 0xc053, 0xc053, 0xc053, 0xc053, 0xc053, 0xc054, 0xc054, 
+    0xc054, 0xc054, 0xc054, 0xc054, 0xc054, 0xc055, 0xc055, 0xc055, 
+    0xc055, 0xc055, 0xc055, 0xc055, 0xc055, 0xc056, 0xc056, 0xc056, 
+    0xc056, 0xc056, 0xc056, 0xc056, 0xc057, 0xc057, 0xc057, 0xc057, 
+    0xc057, 0xc057, 0xc057, 0xc058, 0xc058, 0xc058, 0xc058, 0xc058, 
+    0xc058, 0xc058, 0xc059, 0xc059, 0xc059, 0xc059, 0xc059, 0xc059, 
+    0xc059, 0xc05a, 0xc05a, 0xc05a, 0xc05a, 0xc05a, 0xc05a, 0xc05a, 
+    0xc05a, 0xc05b, 0xc05b, 0xc05b, 0xc05b, 0xc05b, 0xc05b, 0xc05b, 
+    0xc05c, 0xc05c, 0xc05c, 0xc05c, 0xc05c, 0xc05c, 0xc05c, 0xc05d, 
+    0xc05d, 0xc05d, 0xc05d, 0xc05d, 0xc05d, 0xc05d, 0xc05d, 0xc05e, 
+    0xc05e, 0xc05e, 0xc05e, 0xc05e, 0xc05e, 0xc05e, 0xc05f, 0xc05f, 
+    0xc05f, 0xc05f, 0xc05f, 0xc05f, 0xc05f, 0xc05f, 0xc060, 0xc060, 
+    0xc060, 0xc060, 0xc060, 0xc060, 0xc060, 0xc061, 0xc061, 0xc061, 
+    0xc061, 0xc061, 0xc061, 0xc061, 0xc061, 0xc062, 0xc062, 0xc062, 
+    0xc062, 0xc062, 0xc062, 0xc062, 0xc063, 0xc063, 0xc063, 0xc063, 
+    0xc063, 0xc063, 0xc063, 0xc063, 0xc064, 0xc064, 0xc064, 0xc064, 
+    0xc064, 0xc064, 0xc064, 0xc064, 0xc065, 0xc065, 0xc065, 0xc065, 
+    0xc065, 0xc065, 0xc065, 0xc066, 0xc066, 0xc066, 0xc066, 0xc066, 
+    0xc066, 0xc066, 0xc066, 0xc067, 0xc067, 0xc067, 0xc067, 0xc067, 
+    0xc067, 0xc067, 0xc067, 0xc068, 0xc068, 0xc068, 0xc068, 0xc068, 
+    0xc068, 0xc068, 0xc069, 0xc069, 0xc069, 0xc069, 0xc069, 0xc069, 
+    0xc069, 0xc069, 0xc06a, 0xc06a, 0xc06a, 0xc06a, 0xc06a, 0xc06a, 
+    0xc06a, 0xc06a, 0xc06b, 0xc06b, 0xc06b, 0xc06b, 0xc06b, 0xc06b, 
+    0xc06b, 0xc06b, 0xc06c, 0xc06c, 0xc06c, 0xc06c, 0xc06c, 0xc06c, 
+    0xc06c, 0xc06c, 0xc06d, 0xc06d, 0xc06d, 0xc06d, 0xc06d, 0xc06d, 
+    0xc06d, 0xc06d, 0xc06e, 0xc06e, 0xc06e, 0xc06e, 0xc06e, 0xc06e, 
+    0xc06e, 0xc06e, 0xc06f, 0xc06f, 0xc06f, 0xc06f, 0xc06f, 0xc06f, 
+    0xc06f, 0xc06f, 0xc070, 0xc070, 0xc070, 0xc070, 0xc070, 0xc070, 
+    0xc070, 0xc070, 0xc071, 0xc071, 0xc071, 0xc071, 0xc071, 0xc071, 
+    0xc071, 0xc071, 0xc072, 0xc072, 0xc072, 0xc072, 0xc072, 0xc072, 
+    0xc072, 0xc072, 0xc073, 0xc073, 0xc073, 0xc073, 0xc073, 0xc073, 
+    0xc073, 0xc073, 0xc074, 0xc074, 0xc074, 0xc074, 0xc074, 0xc074, 
+    0xc074, 0xc074, 0xc075, 0xc075, 0xc075, 0xc075, 0xc075, 0xc075, 
+    0xc075, 0xc075, 0xc076, 0xc076, 0xc076, 0xc076, 0xc076, 0xc076, 
+    0xc076, 0xc076, 0xc076, 0xc077, 0xc077, 0xc077, 0xc077, 0xc077, 
+    0xc077, 0xc077, 0xc077, 0xc078, 0xc078, 0xc078, 0xc078, 0xc078, 
+    0xc078, 0xc078, 0xc078, 0xc079, 0xc079, 0xc079, 0xc079, 0xc079, 
+    0xc079, 0xc079, 0xc079, 0xc079, 0xc07a, 0xc07a, 0xc07a, 0xc07a, 
+    0xc07a, 0xc07a, 0xc07a, 0xc07a, 0xc07b, 0xc07b, 0xc07b, 0xc07b, 
+    0xc07b, 0xc07b, 0xc07b, 0xc07b, 0xc07c, 0xc07c, 0xc07c, 0xc07c, 
+    0xc07c, 0xc07c, 0xc07c, 0xc07c, 0xc07c, 0xc07d, 0xc07d, 0xc07d, 
+    0xc07d, 0xc07d, 0xc07d, 0xc07d, 0xc07d, 0xc07e, 0xc07e, 0xc07e, 
+    0xc07e, 0xc07e, 0xc07e, 0xc07e, 0xc07e, 0xc07e, 0xc07f, 0xc07f, 
+    0xc07f, 0xc07f, 0xc07f, 0xc07f, 0xc07f, 0xc07f, 0xc080, 0xc080, 
+    0xc080, 0xc080, 0xc080, 0xc080, 0xc080, 0xc080, 0xc080, 0xc081, 
+    0xc081, 0xc081, 0xc081, 0xc081, 0xc081, 0xc081, 0xc081, 0xc081, 
+    0xc082, 0xc082, 0xc082, 0xc082, 0xc082, 0xc082, 0xc082, 0xc082, 
+    0xc083, 0xc083, 0xc083, 0xc083, 0xc083, 0xc083, 0xc083, 0xc083, 
+    0xc083, 0xc084, 0xc084, 0xc084, 0xc084, 0xc084, 0xc084, 0xc084, 
+    0xc084, 0xc084, 0xc085, 0xc085, 0xc085, 0xc085, 0xc085, 0xc085, 
+    0xc085, 0xc085, 0xc086, 0xc086, 0xc086, 0xc086, 0xc087, 0xc087, 
+    0xc087, 0xc087, 0xc088, 0xc088, 0xc088, 0xc088, 0xc088, 0xc089, 
+    0xc089, 0xc089, 0xc089, 0xc08a, 0xc08a, 0xc08a, 0xc08a, 0xc08a, 
+    0xc08b, 0xc08b, 0xc08b, 0xc08b, 0xc08c, 0xc08c, 0xc08c, 0xc08c, 
+    0xc08c, 0xc08d, 0xc08d, 0xc08d, 0xc08d, 0xc08e, 0xc08e, 0xc08e, 
+    0xc08e, 0xc08e, 0xc08f, 0xc08f, 0xc08f, 0xc08f, 0xc08f, 0xc090, 
+    0xc090, 0xc090, 0xc090, 0xc091, 0xc091, 0xc091, 0xc091, 0xc091, 
+    0xc092, 0xc092, 0xc092, 0xc092, 0xc093, 0xc093, 0xc093, 0xc093, 
+    0xc093, 0xc094, 0xc094, 0xc094, 0xc094, 0xc094, 0xc095, 0xc095, 
+    0xc095, 0xc095, 0xc095, 0xc096, 0xc096, 0xc096, 0xc096, 0xc097, 
+    0xc097, 0xc097, 0xc097, 0xc097, 0xc098, 0xc098, 0xc098, 0xc098, 
+    0xc098, 0xc099, 0xc099, 0xc099, 0xc099, 0xc099, 0xc09a, 0xc09a, 
+    0xc09a, 0xc09a, 0xc09b, 0xc09b, 0xc09b, 0xc09b, 0xc09b, 0xc09c, 
+    0xc09c, 0xc09c, 0xc09c, 0xc09c, 0xc09d, 0xc09d, 0xc09d, 0xc09d, 
+    0xc09d, 0xc09e, 0xc09e, 0xc09e, 0xc09e, 0xc09e, 0xc09f, 0xc09f, 
+    0xc09f, 0xc09f, 0xc09f, 0xc0a0, 0xc0a0, 0xc0a0, 0xc0a0, 0xc0a0, 
+    0xc0a1, 0xc0a1, 0xc0a1, 0xc0a1, 0xc0a1, 0xc0a2, 0xc0a2, 0xc0a2, 
+    0xc0a2, 0xc0a2, 0xc0a3, 0xc0a3, 0xc0a3, 0xc0a3, 0xc0a3, 0xc0a4, 
+    0xc0a4, 0xc0a4, 0xc0a4, 0xc0a4, 0xc0a5, 0xc0a5, 0xc0a5, 0xc0a5, 
+    0xc0a5, 0xc0a6, 0xc0a6, 0xc0a6, 0xc0a6, 0xc0a6, 0xc0a7, 0xc0a7, 
+    0xc0a7, 0xc0a7, 0xc0a7, 0xc0a8, 0xc0a8, 0xc0a8, 0xc0a8, 0xc0a8, 
+    0xc0a9, 0xc0a9, 0xc0a9, 0xc0a9, 0xc0a9, 0xc0aa, 0xc0aa, 0xc0aa, 
+    0xc0aa, 0xc0aa, 0xc0ab, 0xc0ab, 0xc0ab, 0xc0ab, 0xc0ab, 0xc0ac, 
+    0xc0ac, 0xc0ac, 0xc0ac, 0xc0ac, 0xc0ac, 0xc0ad, 0xc0ad, 0xc0ad, 
+    0xc0ad, 0xc0ad, 0xc0ae, 0xc0ae, 0xc0ae, 0xc0ae, 0xc0ae, 0xc0af, 
+    0xc0af, 0xc0af, 0xc0af, 0xc0af, 0xc0b0, 0xc0b0, 0xc0b0, 0xc0b0, 
+    0xc0b0, 0xc0b0, 0xc0b1, 0xc0b1, 0xc0b1, 0xc0b1, 0xc0b1, 0xc0b2, 
+    0xc0b2, 0xc0b2, 0xc0b2, 0xc0b2, 0xc0b3, 0xc0b3, 0xc0b3, 0xc0b3, 
+    0xc0b3, 0xc0b3, 0xc0b4, 0xc0b4, 0xc0b4, 0xc0b4, 0xc0b4, 0xc0b5, 
+    0xc0b5, 0xc0b5, 0xc0b5, 0xc0b5, 0xc0b6, 0xc0b6, 0xc0b6, 0xc0b6, 
+    0xc0b6, 0xc0b6, 0xc0b7, 0xc0b7, 0xc0b7, 0xc0b7, 0xc0b7, 0xc0b8, 
+    0xc0b8, 0xc0b8, 0xc0b8, 0xc0b8, 0xc0b8, 0xc0b9, 0xc0b9, 0xc0b9, 
+    0xc0b9, 0xc0b9, 0xc0ba, 0xc0ba, 0xc0ba, 0xc0ba, 0xc0ba, 0xc0ba, 
+    0xc0bb, 0xc0bb, 0xc0bb, 0xc0bb, 0xc0bb, 0xc0bc, 0xc0bc, 0xc0bc, 
+    0xc0bc, 0xc0bc, 0xc0bc, 0xc0bd, 0xc0bd, 0xc0bd, 0xc0bd, 0xc0bd, 
+    0xc0be, 0xc0be, 0xc0be, 0xc0be, 0xc0be, 0xc0be, 0xc0bf, 0xc0bf, 
+    0xc0bf, 0xc0bf, 0xc0bf, 0xc0bf, 0xc0c0, 0xc0c0, 0xc0c0, 0xc0c0, 
+    0xc0c0, 0xc0c1, 0xc0c1, 0xc0c1, 0xc0c1, 0xc0c1, 0xc0c1, 0xc0c2, 
+    0xc0c2, 0xc0c2, 0xc0c2, 0xc0c2, 0xc0c2, 0xc0c3, 0xc0c3, 0xc0c3, 
+    0xc0c3, 0xc0c3, 0xc0c4, 0xc0c4, 0xc0c4, 0xc0c4, 0xc0c4, 0xc0c4, 
+    0xc0c5, 0xc0c5, 0xc0c5, 0xc0c5, 0xc0c5, 0xc0c5, 0xc0c6, 0xc0c6, 
+    0xc0c6, 0xc0c6, 0xc0c6, 0xc0c6, 0xc0c7, 0xc0c7, 0xc0c7, 0xc0c7, 
+    0xc0c7, 0xc0c7, 0xc0c8, 0xc0c8, 0xc0c8, 0xc0c8, 0xc0c8, 0xc0c8, 
+    0xc0c9, 0xc0c9, 0xc0c9, 0xc0c9, 0xc0c9, 0xc0ca, 0xc0ca, 0xc0ca, 
+    0xc0ca, 0xc0ca, 0xc0ca, 0xc0cb, 0xc0cb, 0xc0cb, 0xc0cb, 0xc0cb, 
+    0xc0cb, 0xc0cc, 0xc0cc, 0xc0cc, 0xc0cc, 0xc0cc, 0xc0cc, 0xc0cd, 
+    0xc0cd, 0xc0cd, 0xc0cd, 0xc0cd, 0xc0cd, 0xc0ce, 0xc0ce, 0xc0ce, 
+    0xc0ce, 0xc0ce, 0xc0ce, 0xc0cf, 0xc0cf, 0xc0cf, 0xc0cf, 0xc0cf, 
+    0xc0cf, 0xc0d0, 0xc0d0, 0xc0d0, 0xc0d0, 0xc0d0, 0xc0d0, 0xc0d1, 
+    0xc0d1, 0xc0d1, 0xc0d1, 0xc0d1, 0xc0d1, 0xc0d2, 0xc0d2, 0xc0d2, 
+    0xc0d2, 0xc0d2, 0xc0d2, 0xc0d2, 0xc0d3, 0xc0d3, 0xc0d3, 0xc0d3, 
+    0xc0d3, 0xc0d3, 0xc0d4, 0xc0d4, 0xc0d4, 0xc0d4, 0xc0d4, 0xc0d4, 
+    0xc0d5, 0xc0d5, 0xc0d5, 0xc0d5, 0xc0d5, 0xc0d5, 0xc0d6, 0xc0d6, 
+    0xc0d6, 0xc0d6, 0xc0d6, 0xc0d6, 0xc0d7, 0xc0d7, 0xc0d7, 0xc0d7, 
+    0xc0d7, 0xc0d7, 0xc0d7, 0xc0d8, 0xc0d8, 0xc0d8, 0xc0d8, 0xc0d8, 
+    0xc0d8, 0xc0d9, 0xc0d9, 0xc0d9, 0xc0d9, 0xc0d9, 0xc0d9, 0xc0da, 
+    0xc0da, 0xc0da, 0xc0da, 0xc0da, 0xc0da, 0xc0db, 0xc0db, 0xc0db, 
+    0xc0db, 0xc0db, 0xc0db, 0xc0db, 0xc0dc, 0xc0dc, 0xc0dc, 0xc0dc, 
+    0xc0dc, 0xc0dc, 0xc0dd, 0xc0dd, 0xc0dd, 0xc0dd, 0xc0dd, 0xc0dd, 
+    0xc0dd, 0xc0de, 0xc0de, 0xc0de, 0xc0de, 0xc0de, 0xc0de, 0xc0df, 
+    0xc0df, 0xc0df, 0xc0df, 0xc0df, 0xc0df, 0xc0df, 0xc0e0, 0xc0e0, 
+    0xc0e0, 0xc0e0, 0xc0e0, 0xc0e0, 0xc0e1, 0xc0e1, 0xc0e1, 0xc0e1, 
+    0xc0e1, 0xc0e1, 0xc0e1, 0xc0e2, 0xc0e2, 0xc0e2, 0xc0e2, 0xc0e2, 
+    0xc0e2, 0xc0e3, 0xc0e3, 0xc0e3, 0xc0e3, 0xc0e3, 0xc0e3, 0xc0e3, 
+    0xc0e4, 0xc0e4, 0xc0e4, 0xc0e4, 0xc0e4, 0xc0e4, 0xc0e5, 0xc0e5, 
+    0xc0e5, 0xc0e5, 0xc0e5, 0xc0e5, 0xc0e5, 0xc0e6, 0xc0e6, 0xc0e6, 
+    0xc0e6, 0xc0e6, 0xc0e6, 0xc0e6, 0xc0e7, 0xc0e7, 0xc0e7, 0xc0e7, 
+    0xc0e7, 0xc0e7, 0xc0e8, 0xc0e8, 0xc0e8, 0xc0e8, 0xc0e8, 0xc0e8, 
+    0xc0e8, 0xc0e9, 0xc0e9, 0xc0e9, 0xc0e9, 0xc0e9, 0xc0e9, 0xc0e9, 
+    0xc0ea, 0xc0ea, 0xc0ea, 0xc0ea, 0xc0ea, 0xc0ea, 0xc0ea, 0xc0eb, 
+    0xc0eb, 0xc0eb, 0xc0eb, 0xc0eb, 0xc0eb, 0xc0ec, 0xc0ec, 0xc0ec, 
+    0xc0ec, 0xc0ec, 0xc0ec, 0xc0ec, 0xc0ed, 0xc0ed, 0xc0ed, 0xc0ed, 
+    0xc0ed, 0xc0ed, 0xc0ed, 0xc0ee, 0xc0ee, 0xc0ee, 0xc0ee, 0xc0ee, 
+    0xc0ee, 0xc0ee, 0xc0ef, 0xc0ef, 0xc0ef, 0xc0ef, 0xc0ef, 0xc0ef, 
+    0xc0ef, 0xc0f0, 0xc0f0, 0xc0f0, 0xc0f0, 0xc0f0, 0xc0f0, 0xc0f0, 
+    0xc0f1, 0xc0f1, 0xc0f1, 0xc0f1, 0xc0f1, 0xc0f1, 0xc0f1, 0xc0f2, 
+    0xc0f2, 0xc0f2, 0xc0f2, 0xc0f2, 0xc0f2, 0xc0f2, 0xc0f3, 0xc0f3, 
+    0xc0f3, 0xc0f3, 0xc0f3, 0xc0f3, 0xc0f3, 0xc0f4, 0xc0f4, 0xc0f4, 
+    0xc0f4, 0xc0f4, 0xc0f4, 0xc0f4, 0xc0f5, 0xc0f5, 0xc0f5, 0xc0f5, 
+    0xc0f5, 0xc0f5, 0xc0f5, 0xc0f6, 0xc0f6, 0xc0f6, 0xc0f6, 0xc0f6, 
+    0xc0f6, 0xc0f6, 0xc0f7, 0xc0f7, 0xc0f7, 0xc0f7, 0xc0f7, 0xc0f7, 
+    0xc0f7, 0xc0f8, 0xc0f8, 0xc0f8, 0xc0f8, 0xc0f8, 0xc0f8, 0xc0f8, 
+    0xc0f8, 0xc0f9, 0xc0f9, 0xc0f9, 0xc0f9, 0xc0f9, 0xc0f9, 0xc0f9, 
+    0xc0fa, 0xc0fa, 0xc0fa, 0xc0fa, 0xc0fa, 0xc0fa, 0xc0fa, 0xc0fb, 
+    0xc0fb, 0xc0fb, 0xc0fb, 0xc0fb, 0xc0fb, 0xc0fb, 0xc0fc, 0xc0fc, 
+    0xc0fc, 0xc0fc, 0xc0fc, 0xc0fc, 0xc0fc, 0xc0fc, 0xc0fd, 0xc0fd, 
+    0xc0fd, 0xc0fd, 0xc0fd, 0xc0fd, 0xc0fd, 0xc0fe, 0xc0fe, 0xc0fe, 
+    0xc0fe, 0xc0fe, 0xc0fe, 0xc0fe, 0xc0fe, 0xc0ff, 0xc0ff, 0xc0ff, 
+    0xc0ff, 0xc0ff, 0xc0ff, 0xc0ff, 0xc100, 0xc100, 0xc100, 0xc100, 
+    0xc100, 0xc100, 0xc100, 0xc101, 0xc101, 0xc101, 0xc101, 0xc101, 
+    0xc101, 0xc101, 0xc101, 0xc102, 0xc102, 0xc102, 0xc102, 0xc102, 
+    0xc102, 0xc102, 0xc103, 0xc103, 0xc103, 0xc103, 0xc103, 0xc103, 
+    0xc103, 0xc103, 0xc104, 0xc104, 0xc104, 0xc104, 0xc104, 0xc104, 
+    0xc104, 0xc104, 0xc105, 0xc105, 0xc105, 0xc105, 0xc105, 0xc105, 
+    0xc105, 0xc106, 0xc106, 0xc106, 0xc106, 0xc106, 0xc106, 0xc106, 
+    0xc106, 0xc107, 0xc107, 0xc107, 0xc107, 0xc107, 0xc107, 0xc107, 
+    0xc107, 0xc108, 0xc108, 0xc108, 0xc108, 0xc108, 0xc108, 0xc108, 
+    0xc109, 0xc109, 0xc109, 0xc109, 0xc109, 0xc109, 0xc109, 0xc109, 
+    0xc10a, 0xc10a, 0xc10a, 0xc10a, 0xc10a, 0xc10a, 0xc10a, 0xc10a, 
+    0xc10b, 0xc10b, 0xc10b, 0xc10b, 0xc10b, 0xc10b, 0xc10b, 0xc10b, 
+    0xc10c, 0xc10c, 0xc10c, 0xc10c, 0xc10c, 0xc10c, 0xc10c, 0xc10d, 
+    0xc10d, 0xc10d, 0xc10d, 0xc10d, 0xc10d, 0xc10d, 0xc10d, 0xc10e, 
+    0xc10e, 0xc10e, 0xc10e, 0xc10e, 0xc10e, 0xc10e, 0xc10e, 0xc10f, 
+    0xc10f, 0xc10f, 0xc10f, 0xc10f, 0xc10f, 0xc10f, 0xc10f, 0xc110, 
+    0xc110, 0xc110, 0xc110, 0xc110, 0xc110, 0xc110, 0xc110, 0xc111, 
+    0xc111, 0xc111, 0xc111, 0xc111, 0xc111, 0xc111, 0xc111, 0xc112, 
+    0xc112, 0xc112, 0xc112, 0xc112, 0xc112, 0xc112, 0xc112, 0xc113, 
+    0xc113, 0xc113, 0xc113, 0xc113, 0xc113, 0xc113, 0xc113, 0xc114, 
+    0xc114, 0xc114, 0xc114, 0xc114, 0xc114, 0xc114, 0xc114, 0xc115, 
+    0xc115, 0xc115, 0xc115, 0xc115, 0xc115, 0xc115, 0xc115, 0xc115, 
+    0xc116, 0xc116, 0xc116, 0xc116, 0xc116, 0xc116, 0xc116, 0xc116, 
+    0xc117, 0xc117, 0xc117, 0xc117, 0xc117, 0xc117, 0xc117, 0xc117, 
+    0xc118, 0xc118, 0xc118, 0xc118, 0xc118, 0xc118, 0xc118, 0xc118, 
+    0xc119, 0xc119, 0xc119, 0xc119, 0xc119, 0xc119, 0xc119, 0xc119, 
+    0xc119, 0xc11a, 0xc11a, 0xc11a, 0xc11a, 0xc11a, 0xc11a, 0xc11a, 
+    0xc11a, 0xc11b, 0xc11b, 0xc11b, 0xc11b, 0xc11b, 0xc11b, 0xc11b, 
+    0xc11b, 0xc11c, 0xc11c, 0xc11c, 0xc11c, 0xc11c, 0xc11c, 0xc11c, 
+    0xc11c, 0xc11c, 0xc11d, 0xc11d, 0xc11d, 0xc11d, 0xc11d, 0xc11d, 
+    0xc11d, 0xc11d, 0xc11e, 0xc11e, 0xc11e, 0xc11e, 0xc11e, 0xc11e, 
+    0xc11e, 0xc11e, 0xc11e, 0xc11f, 0xc11f, 0xc11f, 0xc11f, 0xc11f, 
+    0xc11f, 0xc11f, 0xc11f, 0xc120, 0xc120, 0xc120, 0xc120, 0xc120, 
+    0xc120, 0xc120, 0xc120, 0xc120, 0xc121, 0xc121, 0xc121, 0xc121, 
+    0xc121, 0xc121, 0xc121, 0xc121, 0xc122, 0xc122, 0xc122, 0xc122, 
+    0xc122, 0xc122, 0xc122, 0xc122, 0xc122, 0xc123, 0xc123, 0xc123, 
+    0xc123, 0xc123, 0xc123, 0xc123, 0xc123, 0xc123, 0xc124, 0xc124, 
+    0xc124, 0xc124, 0xc124, 0xc124, 0xc124, 0xc124, 0xc125, 0xc125, 
+    0xc125, 0xc125, 0xc125, 0xc125, 0xc125, 0xc125, 0xc125, 0xc126, 
+    0xc126, 0xc126, 0xc126, 0xc126, 0xc126, 0xc126, 0xc126, 0xc126, 
+    0xc127, 0xc127, 0xc127, 0xc127, 0xc127, 0xc128, 0xc128, 0xc128, 
+    0xc128, 0xc129, 0xc129, 0xc129, 0xc129, 0xc12a, 0xc12a, 0xc12a, 
+    0xc12a, 0xc12a, 0xc12b, 0xc12b, 0xc12b, 0xc12b, 0xc12c, 0xc12c, 
+    0xc12c, 0xc12c, 0xc12c, 0xc12d, 0xc12d, 0xc12d, 0xc12d, 0xc12e, 
+    0xc12e, 0xc12e, 0xc12e, 0xc12e, 0xc12f, 0xc12f, 0xc12f, 0xc12f, 
+    0xc12f, 0xc130, 0xc130, 0xc130, 0xc130, 0xc131, 0xc131, 0xc131, 
+    0xc131, 0xc131, 0xc132, 0xc132, 0xc132, 0xc132, 0xc133, 0xc133, 
+    0xc133, 0xc133, 0xc133, 0xc134, 0xc134, 0xc134, 0xc134, 0xc134, 
+    0xc135, 0xc135, 0xc135, 0xc135, 0xc136, 0xc136, 0xc136, 0xc136, 
+    0xc136, 0xc137, 0xc137, 0xc137, 0xc137, 0xc137, 0xc138, 0xc138, 
+    0xc138, 0xc138, 0xc138, 0xc139, 0xc139, 0xc139, 0xc139, 0xc13a, 
+    0xc13a, 0xc13a, 0xc13a, 0xc13a, 0xc13b, 0xc13b, 0xc13b, 0xc13b, 
+    0xc13b, 0xc13c, 0xc13c, 0xc13c, 0xc13c, 0xc13c, 0xc13d, 0xc13d, 
+    0xc13d, 0xc13d, 0xc13d, 0xc13e, 0xc13e, 0xc13e, 0xc13e, 0xc13f, 
+    0xc13f, 0xc13f, 0xc13f, 0xc13f, 0xc140, 0xc140, 0xc140, 0xc140, 
+    0xc140, 0xc141, 0xc141, 0xc141, 0xc141, 0xc141, 0xc142, 0xc142, 
+    0xc142, 0xc142, 0xc142, 0xc143, 0xc143, 0xc143, 0xc143, 0xc143, 
+    0xc144, 0xc144, 0xc144, 0xc144, 0xc144, 0xc145, 0xc145, 0xc145, 
+    0xc145, 0xc145, 0xc146, 0xc146, 0xc146, 0xc146, 0xc146, 0xc147, 
+    0xc147, 0xc147, 0xc147, 0xc147, 0xc148, 0xc148, 0xc148, 0xc148, 
+    0xc148, 0xc149, 0xc149, 0xc149, 0xc149, 0xc149, 0xc14a, 0xc14a, 
+    0xc14a, 0xc14a, 0xc14a, 0xc14b, 0xc14b, 0xc14b, 0xc14b, 0xc14b, 
+    0xc14b, 0xc14c, 0xc14c, 0xc14c, 0xc14c, 0xc14c, 0xc14d, 0xc14d, 
+    0xc14d, 0xc14d, 0xc14d, 0xc14e, 0xc14e, 0xc14e, 0xc14e, 0xc14e, 
+    0xc14f, 0xc14f, 0xc14f, 0xc14f, 0xc14f, 0xc150, 0xc150, 0xc150, 
+    0xc150, 0xc150, 0xc150, 0xc151, 0xc151, 0xc151, 0xc151, 0xc151, 
+    0xc152, 0xc152, 0xc152, 0xc152, 0xc152, 0xc153, 0xc153, 0xc153, 
+    0xc153, 0xc153, 0xc153, 0xc154, 0xc154, 0xc154, 0xc154, 0xc154, 
+    0xc155, 0xc155, 0xc155, 0xc155, 0xc155, 0xc156, 0xc156, 0xc156, 
+    0xc156, 0xc156, 0xc156, 0xc157, 0xc157, 0xc157, 0xc157, 0xc157, 
+    0xc158, 0xc158, 0xc158, 0xc158, 0xc158, 0xc158, 0xc159, 0xc159, 
+    0xc159, 0xc159, 0xc159, 0xc15a, 0xc15a, 0xc15a, 0xc15a, 0xc15a, 
+    0xc15b, 0xc15b, 0xc15b, 0xc15b, 0xc15b, 0xc15b, 0xc15c, 0xc15c, 
+    0xc15c, 0xc15c, 0xc15c, 0xc15c, 0xc15d, 0xc15d, 0xc15d, 0xc15d, 
+    0xc15d, 0xc15e, 0xc15e, 0xc15e, 0xc15e, 0xc15e, 0xc15e, 0xc15f, 
+    0xc15f, 0xc15f, 0xc15f, 0xc15f, 0xc160, 0xc160, 0xc160, 0xc160, 
+    0xc160, 0xc160, 0xc161, 0xc161, 0xc161, 0xc161, 0xc161, 0xc161, 
+    0xc162, 0xc162, 0xc162, 0xc162, 0xc162, 0xc163, 0xc163, 0xc163, 
+    0xc163, 0xc163, 0xc163, 0xc164, 0xc164, 0xc164, 0xc164, 0xc164, 
+    0xc164, 0xc165, 0xc165, 0xc165, 0xc165, 0xc165, 0xc166, 0xc166, 
+    0xc166, 0xc166, 0xc166, 0xc166, 0xc167, 0xc167, 0xc167, 0xc167, 
+    0xc167, 0xc167, 0xc168, 0xc168, 0xc168, 0xc168, 0xc168, 0xc168, 
+    0xc169, 0xc169, 0xc169, 0xc169, 0xc169, 0xc169, 0xc16a, 0xc16a, 
+    0xc16a, 0xc16a, 0xc16a, 0xc16a, 0xc16b, 0xc16b, 0xc16b, 0xc16b, 
+    0xc16b, 0xc16c, 0xc16c, 0xc16c, 0xc16c, 0xc16c, 0xc16c, 0xc16d, 
+    0xc16d, 0xc16d, 0xc16d, 0xc16d, 0xc16d, 0xc16e, 0xc16e, 0xc16e, 
+    0xc16e, 0xc16e, 0xc16e, 0xc16f, 0xc16f, 0xc16f, 0xc16f, 0xc16f, 
+    0xc16f, 0xc170, 0xc170, 0xc170, 0xc170, 0xc170, 0xc170, 0xc171, 
+    0xc171, 0xc171, 0xc171, 0xc171, 0xc171, 0xc172, 0xc172, 0xc172, 
+    0xc172, 0xc172, 0xc172, 0xc172, 0xc173, 0xc173, 0xc173, 0xc173, 
+    0xc173, 0xc173, 0xc174, 0xc174, 0xc174, 0xc174, 0xc174, 0xc174, 
+    0xc175, 0xc175, 0xc175, 0xc175, 0xc175, 0xc175, 0xc176, 0xc176, 
+    0xc176, 0xc176, 0xc176, 0xc176, 0xc177, 0xc177, 0xc177, 0xc177, 
+    0xc177, 0xc177, 0xc178, 0xc178, 0xc178, 0xc178, 0xc178, 0xc178, 
+    0xc178, 0xc179, 0xc179, 0xc179, 0xc179, 0xc179, 0xc179, 0xc17a, 
+    0xc17a, 0xc17a, 0xc17a, 0xc17a, 0xc17a, 0xc17b, 0xc17b, 0xc17b, 
+    0xc17b, 0xc17b, 0xc17b, 0xc17c, 0xc17c, 0xc17c, 0xc17c, 0xc17c, 
+    0xc17c, 0xc17c, 0xc17d, 0xc17d, 0xc17d, 0xc17d, 0xc17d, 0xc17d, 
+    0xc17e, 0xc17e, 0xc17e, 0xc17e, 0xc17e, 0xc17e, 0xc17e, 0xc17f, 
+    0xc17f, 0xc17f, 0xc17f, 0xc17f, 0xc17f, 0xc180, 0xc180, 0xc180, 
+    0xc180, 0xc180, 0xc180, 0xc180, 0xc181, 0xc181, 0xc181, 0xc181, 
+    0xc181, 0xc181, 0xc182, 0xc182, 0xc182, 0xc182, 0xc182, 0xc182, 
+    0xc182, 0xc183, 0xc183, 0xc183, 0xc183, 0xc183, 0xc183, 0xc184, 
+    0xc184, 0xc184, 0xc184, 0xc184, 0xc184, 0xc184, 0xc185, 0xc185, 
+    0xc185, 0xc185, 0xc185, 0xc185, 0xc186, 0xc186, 0xc186, 0xc186, 
+    0xc186, 0xc186, 0xc186, 0xc187, 0xc187, 0xc187, 0xc187, 0xc187, 
+    0xc187, 0xc187, 0xc188, 0xc188, 0xc188, 0xc188, 0xc188, 0xc188, 
+    0xc189, 0xc189, 0xc189, 0xc189, 0xc189, 0xc189, 0xc189, 0xc18a, 
+    0xc18a, 0xc18a, 0xc18a, 0xc18a, 0xc18a, 0xc18a, 0xc18b, 0xc18b, 
+    0xc18b, 0xc18b, 0xc18b, 0xc18b, 0xc18c, 0xc18c, 0xc18c, 0xc18c, 
+    0xc18c, 0xc18c, 0xc18c, 0xc18d, 0xc18d, 0xc18d, 0xc18d, 0xc18d, 
+    0xc18d, 0xc18d, 0xc18e, 0xc18e, 0xc18e, 0xc18e, 0xc18e, 0xc18e, 
+    0xc18e, 0xc18f, 0xc18f, 0xc18f, 0xc18f, 0xc18f, 0xc18f, 0xc18f, 
+    0xc190, 0xc190, 0xc190, 0xc190, 0xc190, 0xc190, 0xc190, 0xc191, 
+    0xc191, 0xc191, 0xc191, 0xc191, 0xc191, 0xc191, 0xc192, 0xc192, 
+    0xc192, 0xc192, 0xc192, 0xc192, 0xc192, 0xc193, 0xc193, 0xc193, 
+    0xc193, 0xc193, 0xc193, 0xc193, 0xc194, 0xc194, 0xc194, 0xc194, 
+    0xc194, 0xc194, 0xc194, 0xc195, 0xc195, 0xc195, 0xc195, 0xc195, 
+    0xc195, 0xc195, 0xc196, 0xc196, 0xc196, 0xc196, 0xc196, 0xc196, 
+    0xc196, 0xc197, 0xc197, 0xc197, 0xc197, 0xc197, 0xc197, 0xc197, 
+    0xc198, 0xc198, 0xc198, 0xc198, 0xc198, 0xc198, 0xc198, 0xc199, 
+    0xc199, 0xc199, 0xc199, 0xc199, 0xc199, 0xc199, 0xc19a, 0xc19a, 
+    0xc19a, 0xc19a, 0xc19a, 0xc19a, 0xc19a, 0xc19a, 0xc19b, 0xc19b, 
+    0xc19b, 0xc19b, 0xc19b, 0xc19b, 0xc19b, 0xc19c, 0xc19c, 0xc19c, 
+    0xc19c, 0xc19c, 0xc19c, 0xc19c, 0xc19d, 0xc19d, 0xc19d, 0xc19d, 
+    0xc19d, 0xc19d, 0xc19d, 0xc19d, 0xc19e, 0xc19e, 0xc19e, 0xc19e, 
+    0xc19e, 0xc19e, 0xc19e, 0xc19f, 0xc19f, 0xc19f, 0xc19f, 0xc19f, 
+    0xc19f, 0xc19f, 0xc1a0, 0xc1a0, 0xc1a0, 0xc1a0, 0xc1a0, 0xc1a0, 
+    0xc1a0, 0xc1a0, 0xc1a1, 0xc1a1, 0xc1a1, 0xc1a1, 0xc1a1, 0xc1a1, 
+    0xc1a1, 0xc1a2, 0xc1a2, 0xc1a2, 0xc1a2, 0xc1a2, 0xc1a2, 0xc1a2, 
+    0xc1a2, 0xc1a3, 0xc1a3, 0xc1a3, 0xc1a3, 0xc1a3, 0xc1a3, 0xc1a3, 
+    0xc1a4, 0xc1a4, 0xc1a4, 0xc1a4, 0xc1a4, 0xc1a4, 0xc1a4, 0xc1a4, 
+    0xc1a5, 0xc1a5, 0xc1a5, 0xc1a5, 0xc1a5, 0xc1a5, 0xc1a5, 0xc1a6, 
+    0xc1a6, 0xc1a6, 0xc1a6, 0xc1a6, 0xc1a6, 0xc1a6, 0xc1a6, 0xc1a7, 
+    0xc1a7, 0xc1a7, 0xc1a7, 0xc1a7, 0xc1a7, 0xc1a7, 0xc1a8, 0xc1a8, 
+    0xc1a8, 0xc1a8, 0xc1a8, 0xc1a8, 0xc1a8, 0xc1a8, 0xc1a9, 0xc1a9, 
+    0xc1a9, 0xc1a9, 0xc1a9, 0xc1a9, 0xc1a9, 0xc1a9, 0xc1aa, 0xc1aa, 
+    0xc1aa, 0xc1aa, 0xc1aa, 0xc1aa, 0xc1aa, 0xc1aa, 0xc1ab, 0xc1ab, 
+    0xc1ab, 0xc1ab, 0xc1ab, 0xc1ab, 0xc1ab, 0xc1ac, 0xc1ac, 0xc1ac, 
+    0xc1ac, 0xc1ac, 0xc1ac, 0xc1ac, 0xc1ac, 0xc1ad, 0xc1ad, 0xc1ad, 
+    0xc1ad, 0xc1ad, 0xc1ad, 0xc1ad, 0xc1ad, 0xc1ae, 0xc1ae, 0xc1ae, 
+    0xc1ae, 0xc1ae, 0xc1ae, 0xc1ae, 0xc1ae, 0xc1af, 0xc1af, 0xc1af, 
+    0xc1af, 0xc1af, 0xc1af, 0xc1af, 0xc1af, 0xc1b0, 0xc1b0, 0xc1b0, 
+    0xc1b0, 0xc1b0, 0xc1b0, 0xc1b0, 0xc1b0, 0xc1b1, 0xc1b1, 0xc1b1, 
+    0xc1b1, 0xc1b1, 0xc1b1, 0xc1b1, 0xc1b1, 0xc1b2, 0xc1b2, 0xc1b2, 
+    0xc1b2, 0xc1b2, 0xc1b2, 0xc1b2, 0xc1b2, 0xc1b3, 0xc1b3, 0xc1b3, 
+    0xc1b3, 0xc1b3, 0xc1b3, 0xc1b3, 0xc1b3, 0xc1b4, 0xc1b4, 0xc1b4, 
+    0xc1b4, 0xc1b4, 0xc1b4, 0xc1b4, 0xc1b4, 0xc1b5, 0xc1b5, 0xc1b5, 
+    0xc1b5, 0xc1b5, 0xc1b5, 0xc1b5, 0xc1b5, 0xc1b6, 0xc1b6, 0xc1b6, 
+    0xc1b6, 0xc1b6, 0xc1b6, 0xc1b6, 0xc1b6, 0xc1b7, 0xc1b7, 0xc1b7, 
+    0xc1b7, 0xc1b7, 0xc1b7, 0xc1b7, 0xc1b7, 0xc1b8, 0xc1b8, 0xc1b8, 
+    0xc1b8, 0xc1b8, 0xc1b8, 0xc1b8, 0xc1b8, 0xc1b9, 0xc1b9, 0xc1b9, 
+    0xc1b9, 0xc1b9, 0xc1b9, 0xc1b9, 0xc1b9, 0xc1b9, 0xc1ba, 0xc1ba, 
+    0xc1ba, 0xc1ba, 0xc1ba, 0xc1ba, 0xc1ba, 0xc1ba, 0xc1bb, 0xc1bb, 
+    0xc1bb, 0xc1bb, 0xc1bb, 0xc1bb, 0xc1bb, 0xc1bb, 0xc1bc, 0xc1bc, 
+    0xc1bc, 0xc1bc, 0xc1bc, 0xc1bc, 0xc1bc, 0xc1bc, 0xc1bc, 0xc1bd, 
+    0xc1bd, 0xc1bd, 0xc1bd, 0xc1bd, 0xc1bd, 0xc1bd, 0xc1bd, 0xc1be, 
+    0xc1be, 0xc1be, 0xc1be, 0xc1be, 0xc1be, 0xc1be, 0xc1be, 0xc1be, 
+    0xc1bf, 0xc1bf, 0xc1bf, 0xc1bf, 0xc1bf, 0xc1bf, 0xc1bf, 0xc1bf, 
+    0xc1c0, 0xc1c0, 0xc1c0, 0xc1c0, 0xc1c0, 0xc1c0, 0xc1c0, 0xc1c0, 
+    0xc1c0, 0xc1c1, 0xc1c1, 0xc1c1, 0xc1c1, 0xc1c1, 0xc1c1, 0xc1c1, 
+    0xc1c1, 0xc1c2, 0xc1c2, 0xc1c2, 0xc1c2, 0xc1c2, 0xc1c2, 0xc1c2, 
+    0xc1c2, 0xc1c2, 0xc1c3, 0xc1c3, 0xc1c3, 0xc1c3, 0xc1c3, 0xc1c3, 
+    0xc1c3, 0xc1c3, 0xc1c4, 0xc1c4, 0xc1c4, 0xc1c4, 0xc1c4, 0xc1c4, 
+    0xc1c4, 0xc1c4, 0xc1c4, 0xc1c5, 0xc1c5, 0xc1c5, 0xc1c5, 0xc1c5, 
+    0xc1c5, 0xc1c5, 0xc1c5, 0xc1c5, 0xc1c6, 0xc1c6, 0xc1c6, 0xc1c6, 
+    0xc1c6, 0xc1c6, 0xc1c6, 0xc1c6, 0xc1c7, 0xc1c7, 0xc1c7, 0xc1c7, 
+    0xc1c7, 0xc1c7, 0xc1c7, 0xc1c7, 0xc1c7, 0xc1c8, 0xc1c8, 0xc1c8, 
+    0xc1c8, 0xc1c8, 0xc1c8, 0xc1c9, 0xc1c9, 0xc1c9, 0xc1c9, 0xc1c9, 
+    0xc1ca, 0xc1ca, 0xc1ca, 0xc1ca, 0xc1cb, 0xc1cb, 0xc1cb, 0xc1cb, 
+    0xc1cb, 0xc1cc, 0xc1cc, 0xc1cc, 0xc1cc, 0xc1cd, 0xc1cd, 0xc1cd, 
+    0xc1cd, 0xc1cd, 0xc1ce, 0xc1ce, 0xc1ce, 0xc1ce, 0xc1cf, 0xc1cf, 
+    0xc1cf, 0xc1cf, 0xc1cf, 0xc1d0, 0xc1d0, 0xc1d0, 0xc1d0, 0xc1d1, 
+    0xc1d1, 0xc1d1, 0xc1d1, 0xc1d1, 0xc1d2, 0xc1d2, 0xc1d2, 0xc1d2, 
+    0xc1d3, 0xc1d3, 0xc1d3, 0xc1d3, 0xc1d3, 0xc1d4, 0xc1d4, 0xc1d4, 
+    0xc1d4, 0xc1d4, 0xc1d5, 0xc1d5, 0xc1d5, 0xc1d5, 0xc1d6, 0xc1d6, 
+    0xc1d6, 0xc1d6, 0xc1d6, 0xc1d7, 0xc1d7, 0xc1d7, 0xc1d7, 0xc1d7, 
+    0xc1d8, 0xc1d8, 0xc1d8, 0xc1d8, 0xc1d9, 0xc1d9, 0xc1d9, 0xc1d9, 
+    0xc1d9, 0xc1da, 0xc1da, 0xc1da, 0xc1da, 0xc1da, 0xc1db, 0xc1db, 
+    0xc1db, 0xc1db, 0xc1db, 0xc1dc, 0xc1dc, 0xc1dc, 0xc1dc, 0xc1dd, 
+    0xc1dd, 0xc1dd, 0xc1dd, 0xc1dd, 0xc1de, 0xc1de, 0xc1de, 0xc1de, 
+    0xc1de, 0xc1df, 0xc1df, 0xc1df, 0xc1df, 0xc1df, 0xc1e0, 0xc1e0, 
+    0xc1e0, 0xc1e0, 0xc1e0, 0xc1e1, 0xc1e1, 0xc1e1, 0xc1e1, 0xc1e1, 
+    0xc1e2, 0xc1e2, 0xc1e2, 0xc1e2, 0xc1e2, 0xc1e3, 0xc1e3, 0xc1e3, 
+    0xc1e3, 0xc1e3, 0xc1e4, 0xc1e4, 0xc1e4, 0xc1e4, 0xc1e5, 0xc1e5, 
+    0xc1e5, 0xc1e5, 0xc1e5, 0xc1e6, 0xc1e6, 0xc1e6, 0xc1e6, 0xc1e6, 
+    0xc1e7, 0xc1e7, 0xc1e7, 0xc1e7, 0xc1e7, 0xc1e8, 0xc1e8, 0xc1e8, 
+    0xc1e8, 0xc1e8, 0xc1e8, 0xc1e9, 0xc1e9, 0xc1e9, 0xc1e9, 0xc1e9, 
+    0xc1ea, 0xc1ea, 0xc1ea, 0xc1ea, 0xc1ea, 0xc1eb, 0xc1eb, 0xc1eb, 
+    0xc1eb, 0xc1eb, 0xc1ec, 0xc1ec, 0xc1ec, 0xc1ec, 0xc1ec, 0xc1ed, 
+    0xc1ed, 0xc1ed, 0xc1ed, 0xc1ed, 0xc1ee, 0xc1ee, 0xc1ee, 0xc1ee, 
+    0xc1ee, 0xc1ef, 0xc1ef, 0xc1ef, 0xc1ef, 0xc1ef, 0xc1ef, 0xc1f0, 
+    0xc1f0, 0xc1f0, 0xc1f0, 0xc1f0, 0xc1f1, 0xc1f1, 0xc1f1, 0xc1f1, 
+    0xc1f1, 0xc1f2, 0xc1f2, 0xc1f2, 0xc1f2, 0xc1f2, 0xc1f3, 0xc1f3, 
+    0xc1f3, 0xc1f3, 0xc1f3, 0xc1f3, 0xc1f4, 0xc1f4, 0xc1f4, 0xc1f4, 
+    0xc1f4, 0xc1f5, 0xc1f5, 0xc1f5, 0xc1f5, 0xc1f5, 0xc1f6, 0xc1f6, 
+    0xc1f6, 0xc1f6, 0xc1f6, 0xc1f6, 0xc1f7, 0xc1f7, 0xc1f7, 0xc1f7, 
+    0xc1f7, 0xc1f8, 0xc1f8, 0xc1f8, 0xc1f8, 0xc1f8, 0xc1f9, 0xc1f9, 
+    0xc1f9, 0xc1f9, 0xc1f9, 0xc1f9, 0xc1fa, 0xc1fa, 0xc1fa, 0xc1fa, 
+    0xc1fa, 0xc1fb, 0xc1fb, 0xc1fb, 0xc1fb, 0xc1fb, 0xc1fb, 0xc1fc, 
+    0xc1fc, 0xc1fc, 0xc1fc, 0xc1fc, 0xc1fd, 0xc1fd, 0xc1fd, 0xc1fd, 
+    0xc1fd, 0xc1fd, 0xc1fe, 0xc1fe, 0xc1fe, 0xc1fe, 0xc1fe, 0xc1ff, 
+    0xc1ff, 0xc1ff, 0xc1ff, 0xc1ff, 0xc1ff, 0xc200, 0xc200, 0xc200, 
+    0xc200, 0xc200, 0xc200, 0xc201, 0xc201, 0xc201, 0xc201, 0xc201, 
+    0xc202, 0xc202, 0xc202, 0xc202, 0xc202, 0xc202, 0xc203, 0xc203, 
+    0xc203, 0xc203, 0xc203, 0xc204, 0xc204, 0xc204, 0xc204, 0xc204, 
+    0xc204, 0xc205, 0xc205, 0xc205, 0xc205, 0xc205, 0xc205, 0xc206, 
+    0xc206, 0xc206, 0xc206, 0xc206, 0xc206, 0xc207, 0xc207, 0xc207, 
+    0xc207, 0xc207, 0xc208, 0xc208, 0xc208, 0xc208, 0xc208, 0xc208, 
+    0xc209, 0xc209, 0xc209, 0xc209, 0xc209, 0xc209, 0xc20a, 0xc20a, 
+    0xc20a, 0xc20a, 0xc20a, 0xc20a, 0xc20b, 0xc20b, 0xc20b, 0xc20b, 
+    0xc20b, 0xc20b, 0xc20c, 0xc20c, 0xc20c, 0xc20c, 0xc20c, 0xc20c, 
+    0xc20d, 0xc20d, 0xc20d, 0xc20d, 0xc20d, 0xc20d, 0xc20e, 0xc20e, 
+    0xc20e, 0xc20e, 0xc20e, 0xc20f, 0xc20f, 0xc20f, 0xc20f, 0xc20f, 
+    0xc20f, 0xc210, 0xc210, 0xc210, 0xc210, 0xc210, 0xc210, 0xc211, 
+    0xc211, 0xc211, 0xc211, 0xc211, 0xc211, 0xc212, 0xc212, 0xc212, 
+    0xc212, 0xc212, 0xc212, 0xc212, 0xc213, 0xc213, 0xc213, 0xc213, 
+    0xc213, 0xc213, 0xc214, 0xc214, 0xc214, 0xc214, 0xc214, 0xc214, 
+    0xc215, 0xc215, 0xc215, 0xc215, 0xc215, 0xc215, 0xc216, 0xc216, 
+    0xc216, 0xc216, 0xc216, 0xc216, 0xc217, 0xc217, 0xc217, 0xc217, 
+    0xc217, 0xc217, 0xc218, 0xc218, 0xc218, 0xc218, 0xc218, 0xc218, 
+    0xc219, 0xc219, 0xc219, 0xc219, 0xc219, 0xc219, 0xc219, 0xc21a, 
+    0xc21a, 0xc21a, 0xc21a, 0xc21a, 0xc21a, 0xc21b, 0xc21b, 0xc21b, 
+    0xc21b, 0xc21b, 0xc21b, 0xc21c, 0xc21c, 0xc21c, 0xc21c, 0xc21c, 
+    0xc21c, 0xc21d, 0xc21d, 0xc21d, 0xc21d, 0xc21d, 0xc21d, 0xc21d, 
+    0xc21e, 0xc21e, 0xc21e, 0xc21e, 0xc21e, 0xc21e, 0xc21f, 0xc21f, 
+    0xc21f, 0xc21f, 0xc21f, 0xc21f, 0xc21f, 0xc220, 0xc220, 0xc220, 
+    0xc220, 0xc220, 0xc220, 0xc221, 0xc221, 0xc221, 0xc221, 0xc221, 
+    0xc221, 0xc222, 0xc222, 0xc222, 0xc222, 0xc222, 0xc222, 0xc222, 
+    0xc223, 0xc223, 0xc223, 0xc223, 0xc223, 0xc223, 0xc224, 0xc224, 
+    0xc224, 0xc224, 0xc224, 0xc224, 0xc224, 0xc225, 0xc225, 0xc225, 
+    0xc225, 0xc225, 0xc225, 0xc225, 0xc226, 0xc226, 0xc226, 0xc226, 
+    0xc226, 0xc226, 0xc227, 0xc227, 0xc227, 0xc227, 0xc227, 0xc227, 
+    0xc227, 0xc228, 0xc228, 0xc228, 0xc228, 0xc228, 0xc228, 0xc229, 
+    0xc229, 0xc229, 0xc229, 0xc229, 0xc229, 0xc229, 0xc22a, 0xc22a, 
+    0xc22a, 0xc22a, 0xc22a, 0xc22a, 0xc22a, 0xc22b, 0xc22b, 0xc22b, 
+    0xc22b, 0xc22b, 0xc22b, 0xc22b, 0xc22c, 0xc22c, 0xc22c, 0xc22c, 
+    0xc22c, 0xc22c, 0xc22d, 0xc22d, 0xc22d, 0xc22d, 0xc22d, 0xc22d, 
+    0xc22d, 0xc22e, 0xc22e, 0xc22e, 0xc22e, 0xc22e, 0xc22e, 0xc22e, 
+    0xc22f, 0xc22f, 0xc22f, 0xc22f, 0xc22f, 0xc22f, 0xc22f, 0xc230, 
+    0xc230, 0xc230, 0xc230, 0xc230, 0xc230, 0xc230, 0xc231, 0xc231, 
+    0xc231, 0xc231, 0xc231, 0xc231, 0xc231, 0xc232, 0xc232, 0xc232, 
+    0xc232, 0xc232, 0xc232, 0xc232, 0xc233, 0xc233, 0xc233, 0xc233, 
+    0xc233, 0xc233, 0xc234, 0xc234, 0xc234, 0xc234, 0xc234, 0xc234, 
+    0xc234, 0xc234, 0xc235, 0xc235, 0xc235, 0xc235, 0xc235, 0xc235, 
+    0xc235, 0xc236, 0xc236, 0xc236, 0xc236, 0xc236, 0xc236, 0xc236, 
+    0xc237, 0xc237, 0xc237, 0xc237, 0xc237, 0xc237, 0xc237, 0xc238, 
+    0xc238, 0xc238, 0xc238, 0xc238, 0xc238, 0xc238, 0xc239, 0xc239, 
+    0xc239, 0xc239, 0xc239, 0xc239, 0xc239, 0xc23a, 0xc23a, 0xc23a, 
+    0xc23a, 0xc23a, 0xc23a, 0xc23a, 0xc23b, 0xc23b, 0xc23b, 0xc23b, 
+    0xc23b, 0xc23b, 0xc23b, 0xc23c, 0xc23c, 0xc23c, 0xc23c, 0xc23c, 
+    0xc23c, 0xc23c, 0xc23c, 0xc23d, 0xc23d, 0xc23d, 0xc23d, 0xc23d, 
+    0xc23d, 0xc23d, 0xc23e, 0xc23e, 0xc23e, 0xc23e, 0xc23e, 0xc23e, 
+    0xc23e, 0xc23f, 0xc23f, 0xc23f, 0xc23f, 0xc23f, 0xc23f, 0xc23f, 
+    0xc23f, 0xc240, 0xc240, 0xc240, 0xc240, 0xc240, 0xc240, 0xc240, 
+    0xc241, 0xc241, 0xc241, 0xc241, 0xc241, 0xc241, 0xc241, 0xc242, 
+    0xc242, 0xc242, 0xc242, 0xc242, 0xc242, 0xc242, 0xc242, 0xc243, 
+    0xc243, 0xc243, 0xc243, 0xc243, 0xc243, 0xc243, 0xc244, 0xc244, 
+    0xc244, 0xc244, 0xc244, 0xc244, 0xc244, 0xc244, 0xc245, 0xc245, 
+    0xc245, 0xc245, 0xc245, 0xc245, 0xc245, 0xc246, 0xc246, 0xc246, 
+    0xc246, 0xc246, 0xc246, 0xc246, 0xc246, 0xc247, 0xc247, 0xc247, 
+    0xc247, 0xc247, 0xc247, 0xc247, 0xc248, 0xc248, 0xc248, 0xc248, 
+    0xc248, 0xc248, 0xc248, 0xc248, 0xc249, 0xc249, 0xc249, 0xc249, 
+    0xc249, 0xc249, 0xc249, 0xc249, 0xc24a, 0xc24a, 0xc24a, 0xc24a, 
+    0xc24a, 0xc24a, 0xc24a, 0xc24b, 0xc24b, 0xc24b, 0xc24b, 0xc24b, 
+    0xc24b, 0xc24b, 0xc24b, 0xc24c, 0xc24c, 0xc24c, 0xc24c, 0xc24c, 
+    0xc24c, 0xc24c, 0xc24c, 0xc24d, 0xc24d, 0xc24d, 0xc24d, 0xc24d, 
+    0xc24d, 0xc24d, 0xc24d, 0xc24e, 0xc24e, 0xc24e, 0xc24e, 0xc24e, 
+    0xc24e, 0xc24e, 0xc24e, 0xc24f, 0xc24f, 0xc24f, 0xc24f, 0xc24f, 
+    0xc24f, 0xc24f, 0xc250, 0xc250, 0xc250, 0xc250, 0xc250, 0xc250, 
+    0xc250, 0xc250, 0xc251, 0xc251, 0xc251, 0xc251, 0xc251, 0xc251, 
+    0xc251, 0xc251, 0xc252, 0xc252, 0xc252, 0xc252, 0xc252, 0xc252, 
+    0xc252, 0xc252, 0xc253, 0xc253, 0xc253, 0xc253, 0xc253, 0xc253, 
+    0xc253, 0xc253, 0xc254, 0xc254, 0xc254, 0xc254, 0xc254, 0xc254, 
+    0xc254, 0xc254, 0xc255, 0xc255, 0xc255, 0xc255, 0xc255, 0xc255, 
+    0xc255, 0xc255, 0xc256, 0xc256, 0xc256, 0xc256, 0xc256, 0xc256, 
+    0xc256, 0xc256, 0xc257, 0xc257, 0xc257, 0xc257, 0xc257, 0xc257, 
+    0xc257, 0xc257, 0xc257, 0xc258, 0xc258, 0xc258, 0xc258, 0xc258, 
+    0xc258, 0xc258, 0xc258, 0xc259, 0xc259, 0xc259, 0xc259, 0xc259, 
+    0xc259, 0xc259, 0xc259, 0xc25a, 0xc25a, 0xc25a, 0xc25a, 0xc25a, 
+    0xc25a, 0xc25a, 0xc25a, 0xc25b, 0xc25b, 0xc25b, 0xc25b, 0xc25b, 
+    0xc25b, 0xc25b, 0xc25b, 0xc25c, 0xc25c, 0xc25c, 0xc25c, 0xc25c, 
+    0xc25c, 0xc25c, 0xc25c, 0xc25c, 0xc25d, 0xc25d, 0xc25d, 0xc25d, 
+    0xc25d, 0xc25d, 0xc25d, 0xc25d, 0xc25e, 0xc25e, 0xc25e, 0xc25e, 
+    0xc25e, 0xc25e, 0xc25e, 0xc25e, 0xc25f, 0xc25f, 0xc25f, 0xc25f, 
+    0xc25f, 0xc25f, 0xc25f, 0xc25f, 0xc25f, 0xc260, 0xc260, 0xc260, 
+    0xc260, 0xc260, 0xc260, 0xc260, 0xc260, 0xc261, 0xc261, 0xc261, 
+    0xc261, 0xc261, 0xc261, 0xc261, 0xc261, 0xc261, 0xc262, 0xc262, 
+    0xc262, 0xc262, 0xc262, 0xc262, 0xc262, 0xc262, 0xc263, 0xc263, 
+    0xc263, 0xc263, 0xc263, 0xc263, 0xc263, 0xc263, 0xc263, 0xc264, 
+    0xc264, 0xc264, 0xc264, 0xc264, 0xc264, 0xc264, 0xc264, 0xc264, 
+    0xc265, 0xc265, 0xc265, 0xc265, 0xc265, 0xc265, 0xc265, 0xc265, 
+    0xc266, 0xc266, 0xc266, 0xc266, 0xc266, 0xc266, 0xc266, 0xc266, 
+    0xc266, 0xc267, 0xc267, 0xc267, 0xc267, 0xc267, 0xc267, 0xc267, 
+    0xc267, 0xc267, 0xc268, 0xc268, 0xc268, 0xc268, 0xc268, 0xc268, 
+    0xc268, 0xc268, 0xc269, 0xc269, 0xc269, 0xc269, 0xc269, 0xc269, 
+    0xc269, 0xc269, 0xc26a, 0xc26a, 0xc26a, 0xc26a, 0xc26b, 0xc26b, 
+    0xc26b, 0xc26b, 0xc26b, 0xc26c, 0xc26c, 0xc26c, 0xc26c, 0xc26d, 
+    0xc26d, 0xc26d, 0xc26d, 0xc26d, 0xc26e, 0xc26e, 0xc26e, 0xc26e, 
+    0xc26f, 0xc26f, 0xc26f, 0xc26f, 0xc26f, 0xc270, 0xc270, 0xc270, 
+    0xc270, 0xc271, 0xc271, 0xc271, 0xc271, 0xc271, 0xc272, 0xc272, 
+    0xc272, 0xc272, 0xc273, 0xc273, 0xc273, 0xc273, 0xc273, 0xc274, 
+    0xc274, 0xc274, 0xc274, 0xc275, 0xc275, 0xc275, 0xc275, 0xc275, 
+    0xc276, 0xc276, 0xc276, 0xc276, 0xc276, 0xc277, 0xc277, 0xc277, 
+    0xc277, 0xc278, 0xc278, 0xc278, 0xc278, 0xc278, 0xc279, 0xc279, 
+    0xc279, 0xc279, 0xc279, 0xc27a, 0xc27a, 0xc27a, 0xc27a, 0xc27a, 
+    0xc27b, 0xc27b, 0xc27b, 0xc27b, 0xc27c, 0xc27c, 0xc27c, 0xc27c, 
+    0xc27c, 0xc27d, 0xc27d, 0xc27d, 0xc27d, 0xc27d, 0xc27e, 0xc27e, 
+    0xc27e, 0xc27e, 0xc27e, 0xc27f, 0xc27f, 0xc27f, 0xc27f, 0xc280, 
+    0xc280, 0xc280, 0xc280, 0xc280, 0xc281, 0xc281, 0xc281, 0xc281, 
+    0xc281, 0xc282, 0xc282, 0xc282, 0xc282, 0xc282, 0xc283, 0xc283, 
+    0xc283, 0xc283, 0xc283, 0xc284, 0xc284, 0xc284, 0xc284, 0xc284, 
+    0xc285, 0xc285, 0xc285, 0xc285, 0xc285, 0xc286, 0xc286, 0xc286, 
+    0xc286, 0xc286, 0xc287, 0xc287, 0xc287, 0xc287, 0xc287, 0xc288, 
+    0xc288, 0xc288, 0xc288, 0xc288, 0xc289, 0xc289, 0xc289, 0xc289, 
+    0xc289, 0xc28a, 0xc28a, 0xc28a, 0xc28a, 0xc28a, 0xc28b, 0xc28b, 
+    0xc28b, 0xc28b, 0xc28b, 0xc28c, 0xc28c, 0xc28c, 0xc28c, 0xc28c, 
+    0xc28d, 0xc28d, 0xc28d, 0xc28d, 0xc28d, 0xc28e, 0xc28e, 0xc28e, 
+    0xc28e, 0xc28e, 0xc28e, 0xc28f, 0xc28f, 0xc28f, 0xc28f, 0xc28f, 
+    0xc290, 0xc290, 0xc290, 0xc290, 0xc290, 0xc291, 0xc291, 0xc291, 
+    0xc291, 0xc291, 0xc292, 0xc292, 0xc292, 0xc292, 0xc292, 0xc293, 
+    0xc293, 0xc293, 0xc293, 0xc293, 0xc293, 0xc294, 0xc294, 0xc294, 
+    0xc294, 0xc294, 0xc295, 0xc295, 0xc295, 0xc295, 0xc295, 0xc296, 
+    0xc296, 0xc296, 0xc296, 0xc296, 0xc296, 0xc297, 0xc297, 0xc297, 
+    0xc297, 0xc297, 0xc298, 0xc298, 0xc298, 0xc298, 0xc298, 0xc299, 
+    0xc299, 0xc299, 0xc299, 0xc299, 0xc299, 0xc29a, 0xc29a, 0xc29a, 
+    0xc29a, 0xc29a, 0xc29b, 0xc29b, 0xc29b, 0xc29b, 0xc29b, 0xc29b, 
+    0xc29c, 0xc29c, 0xc29c, 0xc29c, 0xc29c, 0xc29d, 0xc29d, 0xc29d, 
+    0xc29d, 0xc29d, 0xc29d, 0xc29e, 0xc29e, 0xc29e, 0xc29e, 0xc29e, 
+    0xc29f, 0xc29f, 0xc29f, 0xc29f, 0xc29f, 0xc29f, 0xc2a0, 0xc2a0, 
+    0xc2a0, 0xc2a0, 0xc2a0, 0xc2a1, 0xc2a1, 0xc2a1, 0xc2a1, 0xc2a1, 
+    0xc2a1, 0xc2a2, 0xc2a2, 0xc2a2, 0xc2a2, 0xc2a2, 0xc2a3, 0xc2a3, 
+    0xc2a3, 0xc2a3, 0xc2a3, 0xc2a3, 0xc2a4, 0xc2a4, 0xc2a4, 0xc2a4, 
+    0xc2a4, 0xc2a4, 0xc2a5, 0xc2a5, 0xc2a5, 0xc2a5, 0xc2a5, 0xc2a6, 
+    0xc2a6, 0xc2a6, 0xc2a6, 0xc2a6, 0xc2a6, 0xc2a7, 0xc2a7, 0xc2a7, 
+    0xc2a7, 0xc2a7, 0xc2a7, 0xc2a8, 0xc2a8, 0xc2a8, 0xc2a8, 0xc2a8, 
+    0xc2a8, 0xc2a9, 0xc2a9, 0xc2a9, 0xc2a9, 0xc2a9, 0xc2aa, 0xc2aa, 
+    0xc2aa, 0xc2aa, 0xc2aa, 0xc2aa, 0xc2ab, 0xc2ab, 0xc2ab, 0xc2ab, 
+    0xc2ab, 0xc2ab, 0xc2ac, 0xc2ac, 0xc2ac, 0xc2ac, 0xc2ac, 0xc2ac, 
+    0xc2ad, 0xc2ad, 0xc2ad, 0xc2ad, 0xc2ad, 0xc2ad, 0xc2ae, 0xc2ae, 
+    0xc2ae, 0xc2ae, 0xc2ae, 0xc2ae, 0xc2af, 0xc2af, 0xc2af, 0xc2af, 
+    0xc2af, 0xc2af, 0xc2b0, 0xc2b0, 0xc2b0, 0xc2b0, 0xc2b0, 0xc2b0, 
+    0xc2b1, 0xc2b1, 0xc2b1, 0xc2b1, 0xc2b1, 0xc2b1, 0xc2b2, 0xc2b2, 
+    0xc2b2, 0xc2b2, 0xc2b2, 0xc2b2, 0xc2b3, 0xc2b3, 0xc2b3, 0xc2b3, 
+    0xc2b3, 0xc2b3, 0xc2b4, 0xc2b4, 0xc2b4, 0xc2b4, 0xc2b4, 0xc2b4, 
+    0xc2b5, 0xc2b5, 0xc2b5, 0xc2b5, 0xc2b5, 0xc2b5, 0xc2b6, 0xc2b6, 
+    0xc2b6, 0xc2b6, 0xc2b6, 0xc2b6, 0xc2b7, 0xc2b7, 0xc2b7, 0xc2b7, 
+    0xc2b7, 0xc2b7, 0xc2b8, 0xc2b8, 0xc2b8, 0xc2b8, 0xc2b8, 0xc2b8, 
+    0xc2b9, 0xc2b9, 0xc2b9, 0xc2b9, 0xc2b9, 0xc2b9, 0xc2ba, 0xc2ba, 
+    0xc2ba, 0xc2ba, 0xc2ba, 0xc2ba, 0xc2ba, 0xc2bb, 0xc2bb, 0xc2bb, 
+    0xc2bb, 0xc2bb, 0xc2bb, 0xc2bc, 0xc2bc, 0xc2bc, 0xc2bc, 0xc2bc, 
+    0xc2bc, 0xc2bd, 0xc2bd, 0xc2bd, 0xc2bd, 0xc2bd, 0xc2bd, 0xc2bd, 
+    0xc2be, 0xc2be, 0xc2be, 0xc2be, 0xc2be, 0xc2be, 0xc2bf, 0xc2bf, 
+    0xc2bf, 0xc2bf, 0xc2bf, 0xc2bf, 0xc2c0, 0xc2c0, 0xc2c0, 0xc2c0, 
+    0xc2c0, 0xc2c0, 0xc2c0, 0xc2c1, 0xc2c1, 0xc2c1, 0xc2c1, 0xc2c1, 
+    0xc2c1, 0xc2c2, 0xc2c2, 0xc2c2, 0xc2c2, 0xc2c2, 0xc2c2, 0xc2c3, 
+    0xc2c3, 0xc2c3, 0xc2c3, 0xc2c3, 0xc2c3, 0xc2c3, 0xc2c4, 0xc2c4, 
+    0xc2c4, 0xc2c4, 0xc2c4, 0xc2c4, 0xc2c5, 0xc2c5, 0xc2c5, 0xc2c5, 
+    0xc2c5, 0xc2c5, 0xc2c5, 0xc2c6, 0xc2c6, 0xc2c6, 0xc2c6, 0xc2c6, 
+    0xc2c6, 0xc2c6, 0xc2c7, 0xc2c7, 0xc2c7, 0xc2c7, 0xc2c7, 0xc2c7, 
+    0xc2c8, 0xc2c8, 0xc2c8, 0xc2c8, 0xc2c8, 0xc2c8, 0xc2c8, 0xc2c9, 
+    0xc2c9, 0xc2c9, 0xc2c9, 0xc2c9, 0xc2c9, 0xc2ca, 0xc2ca, 0xc2ca, 
+    0xc2ca, 0xc2ca, 0xc2ca, 0xc2ca, 0xc2cb, 0xc2cb, 0xc2cb, 0xc2cb, 
+    0xc2cb, 0xc2cb, 0xc2cb, 0xc2cc, 0xc2cc, 0xc2cc, 0xc2cc, 0xc2cc, 
+    0xc2cc, 0xc2cd, 0xc2cd, 0xc2cd, 0xc2cd, 0xc2cd, 0xc2cd, 0xc2cd, 
+    0xc2ce, 0xc2ce, 0xc2ce, 0xc2ce, 0xc2ce, 0xc2ce, 0xc2ce, 0xc2cf, 
+    0xc2cf, 0xc2cf, 0xc2cf, 0xc2cf, 0xc2cf, 0xc2cf, 0xc2d0, 0xc2d0, 
+    0xc2d0, 0xc2d0, 0xc2d0, 0xc2d0, 0xc2d0, 0xc2d1, 0xc2d1, 0xc2d1, 
+    0xc2d1, 0xc2d1, 0xc2d1, 0xc2d1, 0xc2d2, 0xc2d2, 0xc2d2, 0xc2d2, 
+    0xc2d2, 0xc2d2, 0xc2d3, 0xc2d3, 0xc2d3, 0xc2d3, 0xc2d3, 0xc2d3, 
+    0xc2d3, 0xc2d4, 0xc2d4, 0xc2d4, 0xc2d4, 0xc2d4, 0xc2d4, 0xc2d4, 
+    0xc2d5, 0xc2d5, 0xc2d5, 0xc2d5, 0xc2d5, 0xc2d5, 0xc2d5, 0xc2d6, 
+    0xc2d6, 0xc2d6, 0xc2d6, 0xc2d6, 0xc2d6, 0xc2d6, 0xc2d7, 0xc2d7, 
+    0xc2d7, 0xc2d7, 0xc2d7, 0xc2d7, 0xc2d7, 0xc2d8, 0xc2d8, 0xc2d8, 
+    0xc2d8, 0xc2d8, 0xc2d8, 0xc2d8, 0xc2d9, 0xc2d9, 0xc2d9, 0xc2d9, 
+    0xc2d9, 0xc2d9, 0xc2d9, 0xc2d9, 0xc2da, 0xc2da, 0xc2da, 0xc2da, 
+    0xc2da, 0xc2da, 0xc2da, 0xc2db, 0xc2db, 0xc2db, 0xc2db, 0xc2db, 
+    0xc2db, 0xc2db, 0xc2dc, 0xc2dc, 0xc2dc, 0xc2dc, 0xc2dc, 0xc2dc, 
+    0xc2dc, 0xc2dd, 0xc2dd, 0xc2dd, 0xc2dd, 0xc2dd, 0xc2dd, 0xc2dd, 
+    0xc2de, 0xc2de, 0xc2de, 0xc2de, 0xc2de, 0xc2de, 0xc2de, 0xc2de, 
+    0xc2df, 0xc2df, 0xc2df, 0xc2df, 0xc2df, 0xc2df, 0xc2df, 0xc2e0, 
+    0xc2e0, 0xc2e0, 0xc2e0, 0xc2e0, 0xc2e0, 0xc2e0, 0xc2e1, 0xc2e1, 
+    0xc2e1, 0xc2e1, 0xc2e1, 0xc2e1, 0xc2e1, 0xc2e1, 0xc2e2, 0xc2e2, 
+    0xc2e2, 0xc2e2, 0xc2e2, 0xc2e2, 0xc2e2, 0xc2e3, 0xc2e3, 0xc2e3, 
+    0xc2e3, 0xc2e3, 0xc2e3, 0xc2e3, 0xc2e4, 0xc2e4, 0xc2e4, 0xc2e4, 
+    0xc2e4, 0xc2e4, 0xc2e4, 0xc2e4, 0xc2e5, 0xc2e5, 0xc2e5, 0xc2e5, 
+    0xc2e5, 0xc2e5, 0xc2e5, 0xc2e6, 0xc2e6, 0xc2e6, 0xc2e6, 0xc2e6, 
+    0xc2e6, 0xc2e6, 0xc2e6, 0xc2e7, 0xc2e7, 0xc2e7, 0xc2e7, 0xc2e7, 
+    0xc2e7, 0xc2e7, 0xc2e8, 0xc2e8, 0xc2e8, 0xc2e8, 0xc2e8, 0xc2e8, 
+    0xc2e8, 0xc2e8, 0xc2e9, 0xc2e9, 0xc2e9, 0xc2e9, 0xc2e9, 0xc2e9, 
+    0xc2e9, 0xc2e9, 0xc2ea, 0xc2ea, 0xc2ea, 0xc2ea, 0xc2ea, 0xc2ea, 
+    0xc2ea, 0xc2eb, 0xc2eb, 0xc2eb, 0xc2eb, 0xc2eb, 0xc2eb, 0xc2eb, 
+    0xc2eb, 0xc2ec, 0xc2ec, 0xc2ec, 0xc2ec, 0xc2ec, 0xc2ec, 0xc2ec, 
+    0xc2ec, 0xc2ed, 0xc2ed, 0xc2ed, 0xc2ed, 0xc2ed, 0xc2ed, 0xc2ed, 
+    0xc2ee, 0xc2ee, 0xc2ee, 0xc2ee, 0xc2ee, 0xc2ee, 0xc2ee, 0xc2ee, 
+    0xc2ef, 0xc2ef, 0xc2ef, 0xc2ef, 0xc2ef, 0xc2ef, 0xc2ef, 0xc2ef, 
+    0xc2f0, 0xc2f0, 0xc2f0, 0xc2f0, 0xc2f0, 0xc2f0, 0xc2f0, 0xc2f0, 
+    0xc2f1, 0xc2f1, 0xc2f1, 0xc2f1, 0xc2f1, 0xc2f1, 0xc2f1, 0xc2f1, 
+    0xc2f2, 0xc2f2, 0xc2f2, 0xc2f2, 0xc2f2, 0xc2f2, 0xc2f2, 0xc2f2, 
+    0xc2f3, 0xc2f3, 0xc2f3, 0xc2f3, 0xc2f3, 0xc2f3, 0xc2f3, 0xc2f3, 
+    0xc2f4, 0xc2f4, 0xc2f4, 0xc2f4, 0xc2f4, 0xc2f4, 0xc2f4, 0xc2f4, 
+    0xc2f5, 0xc2f5, 0xc2f5, 0xc2f5, 0xc2f5, 0xc2f5, 0xc2f5, 0xc2f5, 
+    0xc2f6, 0xc2f6, 0xc2f6, 0xc2f6, 0xc2f6, 0xc2f6, 0xc2f6, 0xc2f6, 
+    0xc2f7, 0xc2f7, 0xc2f7, 0xc2f7, 0xc2f7, 0xc2f7, 0xc2f7, 0xc2f7, 
+    0xc2f8, 0xc2f8, 0xc2f8, 0xc2f8, 0xc2f8, 0xc2f8, 0xc2f8, 0xc2f8, 
+    0xc2f9, 0xc2f9, 0xc2f9, 0xc2f9, 0xc2f9, 0xc2f9, 0xc2f9, 0xc2f9, 
+    0xc2fa, 0xc2fa, 0xc2fa, 0xc2fa, 0xc2fa, 0xc2fa, 0xc2fa, 0xc2fa, 
+    0xc2fb, 0xc2fb, 0xc2fb, 0xc2fb, 0xc2fb, 0xc2fb, 0xc2fb, 0xc2fb, 
+    0xc2fb, 0xc2fc, 0xc2fc, 0xc2fc, 0xc2fc, 0xc2fc, 0xc2fc, 0xc2fc, 
+    0xc2fc, 0xc2fd, 0xc2fd, 0xc2fd, 0xc2fd, 0xc2fd, 0xc2fd, 0xc2fd, 
+    0xc2fd, 0xc2fe, 0xc2fe, 0xc2fe, 0xc2fe, 0xc2fe, 0xc2fe, 0xc2fe, 
+    0xc2fe, 0xc2ff, 0xc2ff, 0xc2ff, 0xc2ff, 0xc2ff, 0xc2ff, 0xc2ff, 
+    0xc2ff, 0xc2ff, 0xc300, 0xc300, 0xc300, 0xc300, 0xc300, 0xc300, 
+    0xc300, 0xc300, 0xc301, 0xc301, 0xc301, 0xc301, 0xc301, 0xc301, 
+    0xc301, 0xc301, 0xc301, 0xc302, 0xc302, 0xc302, 0xc302, 0xc302, 
+    0xc302, 0xc302, 0xc302, 0xc303, 0xc303, 0xc303, 0xc303, 0xc303, 
+    0xc303, 0xc303, 0xc303, 0xc303, 0xc304, 0xc304, 0xc304, 0xc304, 
+    0xc304, 0xc304, 0xc304, 0xc304, 0xc305, 0xc305, 0xc305, 0xc305, 
+    0xc305, 0xc305, 0xc305, 0xc305, 0xc305, 0xc306, 0xc306, 0xc306, 
+    0xc306, 0xc306, 0xc306, 0xc306, 0xc306, 0xc307, 0xc307, 0xc307, 
+    0xc307, 0xc307, 0xc307, 0xc307, 0xc307, 0xc307, 0xc308, 0xc308, 
+    0xc308, 0xc308, 0xc308, 0xc308, 0xc308, 0xc308, 0xc308, 0xc309, 
+    0xc309, 0xc309, 0xc309, 0xc309, 0xc309, 0xc309, 0xc309, 0xc309, 
+    0xc30a, 0xc30a, 0xc30a, 0xc30a, 0xc30a, 0xc30a, 0xc30a, 0xc30a, 
+    0xc30b, 0xc30b, 0xc30b, 0xc30b, 0xc30b, 0xc30c, 0xc30c, 0xc30c, 
+    0xc30c, 0xc30d, 0xc30d, 0xc30d, 0xc30d, 0xc30d, 0xc30e, 0xc30e, 
+    0xc30e, 0xc30e, 0xc30f, 0xc30f, 0xc30f, 0xc30f, 0xc30f, 0xc310, 
+    0xc310, 0xc310, 0xc310, 0xc311, 0xc311, 0xc311, 0xc311, 0xc311, 
+    0xc312, 0xc312, 0xc312, 0xc312, 0xc313, 0xc313, 0xc313, 0xc313, 
+    0xc313, 0xc314, 0xc314, 0xc314, 0xc314, 0xc315, 0xc315, 0xc315, 
+    0xc315, 0xc315, 0xc316, 0xc316, 0xc316, 0xc316, 0xc316, 0xc317, 
+    0xc317, 0xc317, 0xc317, 0xc318, 0xc318, 0xc318, 0xc318, 0xc318, 
+    0xc319, 0xc319, 0xc319, 0xc319, 0xc319, 0xc31a, 0xc31a, 0xc31a, 
+    0xc31a, 0xc31b, 0xc31b, 0xc31b, 0xc31b, 0xc31b, 0xc31c, 0xc31c, 
+    0xc31c, 0xc31c, 0xc31c, 0xc31d, 0xc31d, 0xc31d, 0xc31d, 0xc31d, 
+    0xc31e, 0xc31e, 0xc31e, 0xc31e, 0xc31f, 0xc31f, 0xc31f, 0xc31f, 
+    0xc31f, 0xc320, 0xc320, 0xc320, 0xc320, 0xc320, 0xc321, 0xc321, 
+    0xc321, 0xc321, 0xc321, 0xc322, 0xc322, 0xc322, 0xc322, 0xc322, 
+    0xc323, 0xc323, 0xc323, 0xc323, 0xc323, 0xc324, 0xc324, 0xc324, 
+    0xc324, 0xc325, 0xc325, 0xc325, 0xc325, 0xc325, 0xc326, 0xc326, 
+    0xc326, 0xc326, 0xc326, 0xc327, 0xc327, 0xc327, 0xc327, 0xc327, 
+    0xc328, 0xc328, 0xc328, 0xc328, 0xc328, 0xc329, 0xc329, 0xc329, 
+    0xc329, 0xc329, 0xc32a, 0xc32a, 0xc32a, 0xc32a, 0xc32a, 0xc32b, 
+    0xc32b, 0xc32b, 0xc32b, 0xc32b, 0xc32c, 0xc32c, 0xc32c, 0xc32c, 
+    0xc32c, 0xc32c, 0xc32d, 0xc32d, 0xc32d, 0xc32d, 0xc32d, 0xc32e, 
+    0xc32e, 0xc32e, 0xc32e, 0xc32e, 0xc32f, 0xc32f, 0xc32f, 0xc32f, 
+    0xc32f, 0xc330, 0xc330, 0xc330, 0xc330, 0xc330, 0xc331, 0xc331, 
+    0xc331, 0xc331, 0xc331, 0xc332, 0xc332, 0xc332, 0xc332, 0xc332, 
+    0xc333, 0xc333, 0xc333, 0xc333, 0xc333, 0xc333, 0xc334, 0xc334, 
+    0xc334, 0xc334, 0xc334, 0xc335, 0xc335, 0xc335, 0xc335, 0xc335, 
+    0xc336, 0xc336, 0xc336, 0xc336, 0xc336, 0xc336, 0xc337, 0xc337, 
+    0xc337, 0xc337, 0xc337, 0xc338, 0xc338, 0xc338, 0xc338, 0xc338, 
+    0xc339, 0xc339, 0xc339, 0xc339, 0xc339, 0xc339, 0xc33a, 0xc33a, 
+    0xc33a, 0xc33a, 0xc33a, 0xc33b, 0xc33b, 0xc33b, 0xc33b, 0xc33b, 
+    0xc33c, 0xc33c, 0xc33c, 0xc33c, 0xc33c, 0xc33c, 0xc33d, 0xc33d, 
+    0xc33d, 0xc33d, 0xc33d, 0xc33e, 0xc33e, 0xc33e, 0xc33e, 0xc33e, 
+    0xc33e, 0xc33f, 0xc33f, 0xc33f, 0xc33f, 0xc33f, 0xc340, 0xc340, 
+    0xc340, 0xc340, 0xc340, 0xc340, 0xc341, 0xc341, 0xc341, 0xc341, 
+    0xc341, 0xc342, 0xc342, 0xc342, 0xc342, 0xc342, 0xc342, 0xc343, 
+    0xc343, 0xc343, 0xc343, 0xc343, 0xc343, 0xc344, 0xc344, 0xc344, 
+    0xc344, 0xc344, 0xc345, 0xc345, 0xc345, 0xc345, 0xc345, 0xc345, 
+    0xc346, 0xc346, 0xc346, 0xc346, 0xc346, 0xc346, 0xc347, 0xc347, 
+    0xc347, 0xc347, 0xc347, 0xc348, 0xc348, 0xc348, 0xc348, 0xc348, 
+    0xc348, 0xc349, 0xc349, 0xc349, 0xc349, 0xc349, 0xc349, 0xc34a, 
+    0xc34a, 0xc34a, 0xc34a, 0xc34a, 0xc34a, 0xc34b, 0xc34b, 0xc34b, 
+    0xc34b, 0xc34b, 0xc34c, 0xc34c, 0xc34c, 0xc34c, 0xc34c, 0xc34c, 
+    0xc34d, 0xc34d, 0xc34d, 0xc34d, 0xc34d, 0xc34d, 0xc34e, 0xc34e, 
+    0xc34e, 0xc34e, 0xc34e, 0xc34e, 0xc34f, 0xc34f, 0xc34f, 0xc34f, 
+    0xc34f, 0xc34f, 0xc350, 0xc350, 0xc350, 0xc350, 0xc350, 0xc350, 
+    0xc351, 0xc351, 0xc351, 0xc351, 0xc351, 0xc351, 0xc352, 0xc352, 
+    0xc352, 0xc352, 0xc352, 0xc352, 0xc353, 0xc353, 0xc353, 0xc353, 
+    0xc353, 0xc353, 0xc354, 0xc354, 0xc354, 0xc354, 0xc354, 0xc354, 
+    0xc355, 0xc355, 0xc355, 0xc355, 0xc355, 0xc355, 0xc356, 0xc356, 
+    0xc356, 0xc356, 0xc356, 0xc356, 0xc357, 0xc357, 0xc357, 0xc357, 
+    0xc357, 0xc357, 0xc358, 0xc358, 0xc358, 0xc358, 0xc358, 0xc358, 
+    0xc359, 0xc359, 0xc359, 0xc359, 0xc359, 0xc359, 0xc35a, 0xc35a, 
+    0xc35a, 0xc35a, 0xc35a, 0xc35a, 0xc35b, 0xc35b, 0xc35b, 0xc35b, 
+    0xc35b, 0xc35b, 0xc35b, 0xc35c, 0xc35c, 0xc35c, 0xc35c, 0xc35c, 
+    0xc35c, 0xc35d, 0xc35d, 0xc35d, 0xc35d, 0xc35d, 0xc35d, 0xc35e, 
+    0xc35e, 0xc35e, 0xc35e, 0xc35e, 0xc35e, 0xc35e, 0xc35f, 0xc35f, 
+    0xc35f, 0xc35f, 0xc35f, 0xc35f, 0xc360, 0xc360, 0xc360, 0xc360, 
+    0xc360, 0xc360, 0xc361, 0xc361, 0xc361, 0xc361, 0xc361, 0xc361, 
+    0xc361, 0xc362, 0xc362, 0xc362, 0xc362, 0xc362, 0xc362, 0xc363, 
+    0xc363, 0xc363, 0xc363, 0xc363, 0xc363, 0xc364, 0xc364, 0xc364, 
+    0xc364, 0xc364, 0xc364, 0xc364, 0xc365, 0xc365, 0xc365, 0xc365, 
+    0xc365, 0xc365, 0xc366, 0xc366, 0xc366, 0xc366, 0xc366, 0xc366, 
+    0xc366, 0xc367, 0xc367, 0xc367, 0xc367, 0xc367, 0xc367, 0xc368, 
+    0xc368, 0xc368, 0xc368, 0xc368, 0xc368, 0xc368, 0xc369, 0xc369, 
+    0xc369, 0xc369, 0xc369, 0xc369, 0xc369, 0xc36a, 0xc36a, 0xc36a, 
+    0xc36a, 0xc36a, 0xc36a, 0xc36b, 0xc36b, 0xc36b, 0xc36b, 0xc36b, 
+    0xc36b, 0xc36b, 0xc36c, 0xc36c, 0xc36c, 0xc36c, 0xc36c, 0xc36c, 
+    0xc36c, 0xc36d, 0xc36d, 0xc36d, 0xc36d, 0xc36d, 0xc36d, 0xc36e, 
+    0xc36e, 0xc36e, 0xc36e, 0xc36e, 0xc36e, 0xc36e, 0xc36f, 0xc36f, 
+    0xc36f, 0xc36f, 0xc36f, 0xc36f, 0xc36f, 0xc370, 0xc370, 0xc370, 
+    0xc370, 0xc370, 0xc370, 0xc370, 0xc371, 0xc371, 0xc371, 0xc371, 
+    0xc371, 0xc371, 0xc372, 0xc372, 0xc372, 0xc372, 0xc372, 0xc372, 
+    0xc372, 0xc373, 0xc373, 0xc373, 0xc373, 0xc373, 0xc373, 0xc373, 
+    0xc374, 0xc374, 0xc374, 0xc374, 0xc374, 0xc374, 0xc374, 0xc375, 
+    0xc375, 0xc375, 0xc375, 0xc375, 0xc375, 0xc375, 0xc376, 0xc376, 
+    0xc376, 0xc376, 0xc376, 0xc376, 0xc376, 0xc377, 0xc377, 0xc377, 
+    0xc377, 0xc377, 0xc377, 0xc377, 0xc378, 0xc378, 0xc378, 0xc378, 
+    0xc378, 0xc378, 0xc378, 0xc379, 0xc379, 0xc379, 0xc379, 0xc379, 
+    0xc379, 0xc379, 0xc37a, 0xc37a, 0xc37a, 0xc37a, 0xc37a, 0xc37a, 
+    0xc37a, 0xc37b, 0xc37b, 0xc37b, 0xc37b, 0xc37b, 0xc37b, 0xc37b, 
+    0xc37c, 0xc37c, 0xc37c, 0xc37c, 0xc37c, 0xc37c, 0xc37c, 0xc37c, 
+    0xc37d, 0xc37d, 0xc37d, 0xc37d, 0xc37d, 0xc37d, 0xc37d, 0xc37e, 
+    0xc37e, 0xc37e, 0xc37e, 0xc37e, 0xc37e, 0xc37e, 0xc37f, 0xc37f, 
+    0xc37f, 0xc37f, 0xc37f, 0xc37f, 0xc37f, 0xc380, 0xc380, 0xc380, 
+    0xc380, 0xc380, 0xc380, 0xc380, 0xc380, 0xc381, 0xc381, 0xc381, 
+    0xc381, 0xc381, 0xc381, 0xc381, 0xc382, 0xc382, 0xc382, 0xc382, 
+    0xc382, 0xc382, 0xc382, 0xc383, 0xc383, 0xc383, 0xc383, 0xc383, 
+    0xc383, 0xc383, 0xc383, 0xc384, 0xc384, 0xc384, 0xc384, 0xc384, 
+    0xc384, 0xc384, 0xc385, 0xc385, 0xc385, 0xc385, 0xc385, 0xc385, 
+    0xc385, 0xc385, 0xc386, 0xc386, 0xc386, 0xc386, 0xc386, 0xc386, 
+    0xc386, 0xc387, 0xc387, 0xc387, 0xc387, 0xc387, 0xc387, 0xc387, 
+    0xc387, 0xc388, 0xc388, 0xc388, 0xc388, 0xc388, 0xc388, 0xc388, 
+    0xc389, 0xc389, 0xc389, 0xc389, 0xc389, 0xc389, 0xc389, 0xc389, 
+    0xc38a, 0xc38a, 0xc38a, 0xc38a, 0xc38a, 0xc38a, 0xc38a, 0xc38b, 
+    0xc38b, 0xc38b, 0xc38b, 0xc38b, 0xc38b, 0xc38b, 0xc38b, 0xc38c, 
+    0xc38c, 0xc38c, 0xc38c, 0xc38c, 0xc38c, 0xc38c, 0xc38c, 0xc38d, 
+    0xc38d, 0xc38d, 0xc38d, 0xc38d, 0xc38d, 0xc38d, 0xc38e, 0xc38e, 
+    0xc38e, 0xc38e, 0xc38e, 0xc38e, 0xc38e, 0xc38e, 0xc38f, 0xc38f, 
+    0xc38f, 0xc38f, 0xc38f, 0xc38f, 0xc38f, 0xc38f, 0xc390, 0xc390, 
+    0xc390, 0xc390, 0xc390, 0xc390, 0xc390, 0xc390, 0xc391, 0xc391, 
+    0xc391, 0xc391, 0xc391, 0xc391, 0xc391, 0xc392, 0xc392, 0xc392, 
+    0xc392, 0xc392, 0xc392, 0xc392, 0xc392, 0xc393, 0xc393, 0xc393, 
+    0xc393, 0xc393, 0xc393, 0xc393, 0xc393, 0xc394, 0xc394, 0xc394, 
+    0xc394, 0xc394, 0xc394, 0xc394, 0xc394, 0xc395, 0xc395, 0xc395, 
+    0xc395, 0xc395, 0xc395, 0xc395, 0xc395, 0xc396, 0xc396, 0xc396, 
+    0xc396, 0xc396, 0xc396, 0xc396, 0xc396, 0xc397, 0xc397, 0xc397, 
+    0xc397, 0xc397, 0xc397, 0xc397, 0xc397, 0xc398, 0xc398, 0xc398, 
+    0xc398, 0xc398, 0xc398, 0xc398, 0xc398, 0xc399, 0xc399, 0xc399, 
+    0xc399, 0xc399, 0xc399, 0xc399, 0xc399, 0xc39a, 0xc39a, 0xc39a, 
+    0xc39a, 0xc39a, 0xc39a, 0xc39a, 0xc39a, 0xc39a, 0xc39b, 0xc39b, 
+    0xc39b, 0xc39b, 0xc39b, 0xc39b, 0xc39b, 0xc39b, 0xc39c, 0xc39c, 
+    0xc39c, 0xc39c, 0xc39c, 0xc39c, 0xc39c, 0xc39c, 0xc39d, 0xc39d, 
+    0xc39d, 0xc39d, 0xc39d, 0xc39d, 0xc39d, 0xc39d, 0xc39e, 0xc39e, 
+    0xc39e, 0xc39e, 0xc39e, 0xc39e, 0xc39e, 0xc39e, 0xc39e, 0xc39f, 
+    0xc39f, 0xc39f, 0xc39f, 0xc39f, 0xc39f, 0xc39f, 0xc39f, 0xc3a0, 
+    0xc3a0, 0xc3a0, 0xc3a0, 0xc3a0, 0xc3a0, 0xc3a0, 0xc3a0, 0xc3a1, 
+    0xc3a1, 0xc3a1, 0xc3a1, 0xc3a1, 0xc3a1, 0xc3a1, 0xc3a1, 0xc3a1, 
+    0xc3a2, 0xc3a2, 0xc3a2, 0xc3a2, 0xc3a2, 0xc3a2, 0xc3a2, 0xc3a2, 
+    0xc3a3, 0xc3a3, 0xc3a3, 0xc3a3, 0xc3a3, 0xc3a3, 0xc3a3, 0xc3a3, 
+    0xc3a3, 0xc3a4, 0xc3a4, 0xc3a4, 0xc3a4, 0xc3a4, 0xc3a4, 0xc3a4, 
+    0xc3a4, 0xc3a5, 0xc3a5, 0xc3a5, 0xc3a5, 0xc3a5, 0xc3a5, 0xc3a5, 
+    0xc3a5, 0xc3a5, 0xc3a6, 0xc3a6, 0xc3a6, 0xc3a6, 0xc3a6, 0xc3a6, 
+    0xc3a6, 0xc3a6, 0xc3a7, 0xc3a7, 0xc3a7, 0xc3a7, 0xc3a7, 0xc3a7, 
+    0xc3a7, 0xc3a7, 0xc3a7, 0xc3a8, 0xc3a8, 0xc3a8, 0xc3a8, 0xc3a8, 
+    0xc3a8, 0xc3a8, 0xc3a8, 0xc3a9, 0xc3a9, 0xc3a9, 0xc3a9, 0xc3a9, 
+    0xc3a9, 0xc3a9, 0xc3a9, 0xc3a9, 0xc3aa, 0xc3aa, 0xc3aa, 0xc3aa, 
+    0xc3aa, 0xc3aa, 0xc3aa, 0xc3aa, 0xc3aa, 0xc3ab, 0xc3ab, 0xc3ab, 
+    0xc3ab, 0xc3ab, 0xc3ab, 0xc3ab, 0xc3ab, 0xc3ab, 0xc3ac, 0xc3ac, 
+    0xc3ac, 0xc3ac, 0xc3ac, 0xc3ad, 0xc3ad, 0xc3ad, 0xc3ad, 0xc3ad, 
+    0xc3ae, 0xc3ae, 0xc3ae, 0xc3ae, 0xc3af, 0xc3af, 0xc3af, 0xc3af, 
+    0xc3af, 0xc3b0, 0xc3b0, 0xc3b0, 0xc3b0, 0xc3b1, 0xc3b1, 0xc3b1, 
+    0xc3b1, 0xc3b1, 0xc3b2, 0xc3b2, 0xc3b2, 0xc3b2, 0xc3b3, 0xc3b3, 
+    0xc3b3, 0xc3b3, 0xc3b3, 0xc3b4, 0xc3b4, 0xc3b4, 0xc3b4, 0xc3b5, 
+    0xc3b5, 0xc3b5, 0xc3b5, 0xc3b5, 0xc3b6, 0xc3b6, 0xc3b6, 0xc3b6, 
+    0xc3b6, 0xc3b7, 0xc3b7, 0xc3b7, 0xc3b7, 0xc3b8, 0xc3b8, 0xc3b8, 
+    0xc3b8, 0xc3b8, 0xc3b9, 0xc3b9, 0xc3b9, 0xc3b9, 0xc3ba, 0xc3ba, 
+    0xc3ba, 0xc3ba, 0xc3ba, 0xc3bb, 0xc3bb, 0xc3bb, 0xc3bb, 0xc3bb, 
+    0xc3bc, 0xc3bc, 0xc3bc, 0xc3bc, 0xc3bc, 0xc3bd, 0xc3bd, 0xc3bd, 
+    0xc3bd, 0xc3be, 0xc3be, 0xc3be, 0xc3be, 0xc3be, 0xc3bf, 0xc3bf, 
+    0xc3bf, 0xc3bf, 0xc3bf, 0xc3c0, 0xc3c0, 0xc3c0, 0xc3c0, 0xc3c0, 
+    0xc3c1, 0xc3c1, 0xc3c1, 0xc3c1, 0xc3c2, 0xc3c2, 0xc3c2, 0xc3c2, 
+    0xc3c2, 0xc3c3, 0xc3c3, 0xc3c3, 0xc3c3, 0xc3c3, 0xc3c4, 0xc3c4, 
+    0xc3c4, 0xc3c4, 0xc3c4, 0xc3c5, 0xc3c5, 0xc3c5, 0xc3c5, 0xc3c5, 
+    0xc3c6, 0xc3c6, 0xc3c6, 0xc3c6, 0xc3c6, 0xc3c7, 0xc3c7, 0xc3c7, 
+    0xc3c7, 0xc3c7, 0xc3c8, 0xc3c8, 0xc3c8, 0xc3c8, 0xc3c8, 0xc3c9, 
+    0xc3c9, 0xc3c9, 0xc3c9, 0xc3c9, 0xc3ca, 0xc3ca, 0xc3ca, 0xc3ca, 
+    0xc3ca, 0xc3cb, 0xc3cb, 0xc3cb, 0xc3cb, 0xc3cb, 0xc3cc, 0xc3cc, 
+    0xc3cc, 0xc3cc, 0xc3cc, 0xc3cd, 0xc3cd, 0xc3cd, 0xc3cd, 0xc3cd, 
+    0xc3ce, 0xc3ce, 0xc3ce, 0xc3ce, 0xc3ce, 0xc3cf, 0xc3cf, 0xc3cf, 
+    0xc3cf, 0xc3cf, 0xc3d0, 0xc3d0, 0xc3d0, 0xc3d0, 0xc3d0, 0xc3d1, 
+    0xc3d1, 0xc3d1, 0xc3d1, 0xc3d1, 0xc3d2, 0xc3d2, 0xc3d2, 0xc3d2, 
+    0xc3d2, 0xc3d2, 0xc3d3, 0xc3d3, 0xc3d3, 0xc3d3, 0xc3d3, 0xc3d4, 
+    0xc3d4, 0xc3d4, 0xc3d4, 0xc3d4, 0xc3d5, 0xc3d5, 0xc3d5, 0xc3d5, 
+    0xc3d5, 0xc3d6, 0xc3d6, 0xc3d6, 0xc3d6, 0xc3d6, 0xc3d6, 0xc3d7, 
+    0xc3d7, 0xc3d7, 0xc3d7, 0xc3d7, 0xc3d8, 0xc3d8, 0xc3d8, 0xc3d8, 
+    0xc3d8, 0xc3d9, 0xc3d9, 0xc3d9, 0xc3d9, 0xc3d9, 0xc3d9, 0xc3da, 
+    0xc3da, 0xc3da, 0xc3da, 0xc3da, 0xc3db, 0xc3db, 0xc3db, 0xc3db, 
+    0xc3db, 0xc3dc, 0xc3dc, 0xc3dc, 0xc3dc, 0xc3dc, 0xc3dc, 0xc3dd, 
+    0xc3dd, 0xc3dd, 0xc3dd, 0xc3dd, 0xc3de, 0xc3de, 0xc3de, 0xc3de, 
+    0xc3de, 0xc3de, 0xc3df, 0xc3df, 0xc3df, 0xc3df, 0xc3df, 0xc3e0, 
+    0xc3e0, 0xc3e0, 0xc3e0, 0xc3e0, 0xc3e0, 0xc3e1, 0xc3e1, 0xc3e1, 
+    0xc3e1, 0xc3e1, 0xc3e2, 0xc3e2, 0xc3e2, 0xc3e2, 0xc3e2, 0xc3e2, 
+    0xc3e3, 0xc3e3, 0xc3e3, 0xc3e3, 0xc3e3, 0xc3e4, 0xc3e4, 0xc3e4, 
+    0xc3e4, 0xc3e4, 0xc3e4, 0xc3e5, 0xc3e5, 0xc3e5, 0xc3e5, 0xc3e5, 
+    0xc3e6, 0xc3e6, 0xc3e6, 0xc3e6, 0xc3e6, 0xc3e6, 0xc3e7, 0xc3e7, 
+    0xc3e7, 0xc3e7, 0xc3e7, 0xc3e7, 0xc3e8, 0xc3e8, 0xc3e8, 0xc3e8, 
+    0xc3e8, 0xc3e9, 0xc3e9, 0xc3e9, 0xc3e9, 0xc3e9, 0xc3e9, 0xc3ea, 
+    0xc3ea, 0xc3ea, 0xc3ea, 0xc3ea, 0xc3ea, 0xc3eb, 0xc3eb, 0xc3eb, 
+    0xc3eb, 0xc3eb, 0xc3eb, 0xc3ec, 0xc3ec, 0xc3ec, 0xc3ec, 0xc3ec, 
+    0xc3ec, 0xc3ed, 0xc3ed, 0xc3ed, 0xc3ed, 0xc3ed, 0xc3ee, 0xc3ee, 
+    0xc3ee, 0xc3ee, 0xc3ee, 0xc3ee, 0xc3ef, 0xc3ef, 0xc3ef, 0xc3ef, 
+    0xc3ef, 0xc3ef, 0xc3f0, 0xc3f0, 0xc3f0, 0xc3f0, 0xc3f0, 0xc3f0, 
+    0xc3f1, 0xc3f1, 0xc3f1, 0xc3f1, 0xc3f1, 0xc3f1, 0xc3f2, 0xc3f2, 
+    0xc3f2, 0xc3f2, 0xc3f2, 0xc3f2, 0xc3f3, 0xc3f3, 0xc3f3, 0xc3f3, 
+    0xc3f3, 0xc3f3, 0xc3f4, 0xc3f4, 0xc3f4, 0xc3f4, 0xc3f4, 0xc3f4, 
+    0xc3f5, 0xc3f5, 0xc3f5, 0xc3f5, 0xc3f5, 0xc3f5, 0xc3f6, 0xc3f6, 
+    0xc3f6, 0xc3f6, 0xc3f6, 0xc3f6, 0xc3f7, 0xc3f7, 0xc3f7, 0xc3f7, 
+    0xc3f7, 0xc3f7, 0xc3f8, 0xc3f8, 0xc3f8, 0xc3f8, 0xc3f8, 0xc3f8, 
+    0xc3f9, 0xc3f9, 0xc3f9, 0xc3f9, 0xc3f9, 0xc3f9, 0xc3fa, 0xc3fa, 
+    0xc3fa, 0xc3fa, 0xc3fa, 0xc3fa, 0xc3fb, 0xc3fb, 0xc3fb, 0xc3fb, 
+    0xc3fb, 0xc3fb, 0xc3fb, 0xc3fc, 0xc3fc, 0xc3fc, 0xc3fc, 0xc3fc, 
+    0xc3fc, 0xc3fd, 0xc3fd, 0xc3fd, 0xc3fd, 0xc3fd, 0xc3fd, 0xc3fe, 
+    0xc3fe, 0xc3fe, 0xc3fe, 0xc3fe, 0xc3fe, 0xc3ff, 0xc3ff, 0xc3ff, 
+    0xc3ff, 0xc3ff, 0xc3ff, 0xc3ff, 0xc400, 0xc400, 0xc400, 0xc400, 
+    0xc400, 0xc400, 0xc400, 0xc400, 0xc400, 0xc401, 0xc401, 0xc401, 
+    0xc401, 0xc401, 0xc401, 0xc401, 0xc401, 0xc401, 0xc401, 0xc401, 
+    0xc401, 0xc401, 0xc402, 0xc402, 0xc402, 0xc402, 0xc402, 0xc402, 
+    0xc402, 0xc402, 0xc402, 0xc402, 0xc402, 0xc402, 0xc402, 0xc403, 
+    0xc403, 0xc403, 0xc403, 0xc403, 0xc403, 0xc403, 0xc403, 0xc403, 
+    0xc403, 0xc403, 0xc403, 0xc403, 0xc404, 0xc404, 0xc404, 0xc404, 
+    0xc404, 0xc404, 0xc404, 0xc404, 0xc404, 0xc404, 0xc404, 0xc404, 
+    0xc404, 0xc405, 0xc405, 0xc405, 0xc405, 0xc405, 0xc405, 0xc405, 
+    0xc405, 0xc405, 0xc405, 0xc405, 0xc405, 0xc405, 0xc406, 0xc406, 
+    0xc406, 0xc406, 0xc406, 0xc406, 0xc406, 0xc406, 0xc406, 0xc406, 
+    0xc406, 0xc406, 0xc406, 0xc407, 0xc407, 0xc407, 0xc407, 0xc407, 
+    0xc407, 0xc407, 0xc407, 0xc407, 0xc407, 0xc407, 0xc407, 0xc407, 
+    0xc407, 0xc408, 0xc408, 0xc408, 0xc408, 0xc408, 0xc408, 0xc408, 
+    0xc408, 0xc408, 0xc408, 0xc408, 0xc408, 0xc408, 0xc409, 0xc409, 
+    0xc409, 0xc409, 0xc409, 0xc409, 0xc409, 0xc409, 0xc409, 0xc409, 
+    0xc409, 0xc409, 0xc409, 0xc409, 0xc40a, 0xc40a, 0xc40a, 0xc40a, 
+    0xc40a, 0xc40a, 0xc40a, 0xc40a, 0xc40a, 0xc40a, 0xc40a, 0xc40a, 
+    0xc40a, 0xc40a, 0xc40b, 0xc40b, 0xc40b, 0xc40b, 0xc40b, 0xc40b, 
+    0xc40b, 0xc40b, 0xc40b, 0xc40b, 0xc40b, 0xc40b, 0xc40b, 0xc40c, 
+    0xc40c, 0xc40c, 0xc40c, 0xc40c, 0xc40c, 0xc40c, 0xc40c, 0xc40c, 
+    0xc40c, 0xc40c, 0xc40c, 0xc40c, 0xc40c, 0xc40d, 0xc40d, 0xc40d, 
+    0xc40d, 0xc40d, 0xc40d, 0xc40d, 0xc40d, 0xc40d, 0xc40d, 0xc40d, 
+    0xc40d, 0xc40d, 0xc40d, 0xc40d, 0xc40e, 0xc40e, 0xc40e, 0xc40e, 
+    0xc40e, 0xc40e, 0xc40e, 0xc40e, 0xc40e, 0xc40e, 0xc40e, 0xc40e, 
+    0xc40e, 0xc40e, 0xc40f, 0xc40f, 0xc40f, 0xc40f, 0xc40f, 0xc40f, 
+    0xc40f, 0xc40f, 0xc40f, 0xc40f, 0xc40f, 0xc40f, 0xc40f, 0xc40f, 
+    0xc410, 0xc410, 0xc410, 0xc410, 0xc410, 0xc410, 0xc410, 0xc410, 
+    0xc410, 0xc410, 0xc410, 0xc410, 0xc410, 0xc410, 0xc410, 0xc411, 
+    0xc411, 0xc411, 0xc411, 0xc411, 0xc411, 0xc411, 0xc411, 0xc411, 
+    0xc411, 0xc411, 0xc411, 0xc411, 0xc411, 0xc412, 0xc412, 0xc412, 
+    0xc412, 0xc412, 0xc412, 0xc412, 0xc412, 0xc412, 0xc412, 0xc412, 
+    0xc412, 0xc412, 0xc412, 0xc412, 0xc413, 0xc413, 0xc413, 0xc413, 
+    0xc413, 0xc413, 0xc413, 0xc413, 0xc413, 0xc413, 0xc413, 0xc413, 
+    0xc413, 0xc413, 0xc413, 0xc414, 0xc414, 0xc414, 0xc414, 0xc414, 
+    0xc414, 0xc414, 0xc414, 0xc414, 0xc414, 0xc414, 0xc414, 0xc414, 
+    0xc414, 0xc414, 0xc415, 0xc415, 0xc415, 0xc415, 0xc415, 0xc415, 
+    0xc415, 0xc415, 0xc415, 0xc415, 0xc415, 0xc415, 0xc415, 0xc415, 
+    0xc415, 0xc416, 0xc416, 0xc416, 0xc416, 0xc416, 0xc416, 0xc416, 
+    0xc416, 0xc416, 0xc416, 0xc416, 0xc416, 0xc416, 0xc416, 0xc416, 
+    0xc417, 0xc417, 0xc417, 0xc417, 0xc417, 0xc417, 0xc417, 0xc417, 
+    0xc417, 0xc417, 0xc417, 0xc417, 0xc417, 0xc417, 0xc417, 0xc417, 
+    0xc418, 0xc418, 0xc418, 0xc418, 0xc418, 0xc418, 0xc418, 0xc418, 
+    0xc418, 0xc418, 0xc418, 0xc418, 0xc418, 0xc418, 0xc418, 0xc419, 
+    0xc419, 0xc419, 0xc419, 0xc419, 0xc419, 0xc419, 0xc419, 0xc419, 
+    0xc419, 0xc419, 0xc419, 0xc419, 0xc419, 0xc419, 0xc419, 0xc41a, 
+    0xc41a, 0xc41a, 0xc41a, 0xc41a, 0xc41a, 0xc41a, 0xc41a, 0xc41a, 
+    0xc41a, 0xc41a, 0xc41a, 0xc41a, 0xc41a, 0xc41a, 0xc41a, 0xc41b, 
+    0xc41b, 0xc41b, 0xc41b, 0xc41b, 0xc41b, 0xc41b, 0xc41b, 0xc41b, 
+    0xc41b, 0xc41b, 0xc41b, 0xc41b, 0xc41b, 0xc41b, 0xc41b, 0xc41c, 
+    0xc41c, 0xc41c, 0xc41c, 0xc41c, 0xc41c, 0xc41c, 0xc41c, 0xc41c, 
+    0xc41c, 0xc41c, 0xc41c, 0xc41c, 0xc41c, 0xc41c, 0xc41c, 0xc41d, 
+    0xc41d, 0xc41d, 0xc41d, 0xc41d, 0xc41d, 0xc41d, 0xc41d, 0xc41d, 
+    0xc41d, 0xc41d, 0xc41d, 0xc41d, 0xc41d, 0xc41d, 0xc41d, 0xc41e, 
+    0xc41e, 0xc41e, 0xc41e, 0xc41e, 0xc41e, 0xc41e, 0xc41e, 0xc41e, 
+    0xc41e, 0xc41e, 0xc41e, 0xc41e, 0xc41e, 0xc41e, 0xc41e, 0xc41f, 
+    0xc41f, 0xc41f, 0xc41f, 0xc41f, 0xc41f, 0xc41f, 0xc41f, 0xc41f, 
+    0xc41f, 0xc41f, 0xc41f, 0xc41f, 0xc41f, 0xc41f, 0xc41f, 0xc41f, 
+    0xc420, 0xc420, 0xc420, 0xc420, 0xc420, 0xc420, 0xc420, 0xc420, 
+    0xc420, 0xc420, 0xc420, 0xc420, 0xc420, 0xc420, 0xc420, 0xc420, 
+    0xc421, 0xc421, 0xc421, 0xc421, 0xc421, 0xc421, 0xc421, 0xc421, 
+    0xc421, 0xc421, 0xc421, 0xc421, 0xc421, 0xc421, 0xc421, 0xc421, 
+    0xc421, 0xc422, 0xc422, 0xc422, 0xc422, 0xc422, 0xc422, 0xc422, 
+    0xc422, 0xc422, 0xc422, 0xc422, 0xc422, 0xc422, 0xc422, 0xc422, 
+    0xc422, 0xc422, 0xc423, 0xc423, 0xc423, 0xc423, 0xc423, 0xc423, 
+    0xc423, 0xc423, 0xc423, 0xc423, 0xc423, 0xc423, 0xc423, 0xc423, 
+    0xc423, 0xc423, 0xc423, 0xc424, 0xc424, 0xc424, 0xc424, 0xc424, 
+    0xc424, 0xc424, 0xc424, 0xc424, 0xc424, 0xc424, 0xc424, 0xc424, 
+    0xc424, 0xc424, 0xc424, 0xc424, 0xc425, 0xc425, 0xc425, 0xc425, 
+    0xc425, 0xc425, 0xc425, 0xc425, 0xc425, 0xc425, 0xc425, 0xc425, 
+    0xc425, 0xc425, 0xc425, 0xc425, 0xc425, 0xc425, 0xc426, 0xc426, 
+    0xc426, 0xc426, 0xc426, 0xc426, 0xc426, 0xc426, 0xc426, 0xc426, 
+    0xc426, 0xc426, 0xc426, 0xc426, 0xc426, 0xc426, 0xc426, 0xc427, 
+    0xc427, 0xc427, 0xc427, 0xc427, 0xc427, 0xc427, 0xc427, 0xc427, 
+    0xc427, 0xc428, 0xc428, 0xc428, 0xc428, 0xc428, 0xc428, 0xc428, 
+    0xc428, 0xc428, 0xc429, 0xc429, 0xc429, 0xc429, 0xc429, 0xc429, 
+    0xc429, 0xc429, 0xc429, 0xc42a, 0xc42a, 0xc42a, 0xc42a, 0xc42a, 
+    0xc42a, 0xc42a, 0xc42a, 0xc42a, 0xc42b, 0xc42b, 0xc42b, 0xc42b, 
+    0xc42b, 0xc42b, 0xc42b, 0xc42b, 0xc42b, 0xc42c, 0xc42c, 0xc42c, 
+    0xc42c, 0xc42c, 0xc42c, 0xc42c, 0xc42c, 0xc42c, 0xc42d, 0xc42d, 
+    0xc42d, 0xc42d, 0xc42d, 0xc42d, 0xc42d, 0xc42d, 0xc42d, 0xc42e, 
+    0xc42e, 0xc42e, 0xc42e, 0xc42e, 0xc42e, 0xc42e, 0xc42e, 0xc42e, 
+    0xc42e, 0xc42f, 0xc42f, 0xc42f, 0xc42f, 0xc42f, 0xc42f, 0xc42f, 
+    0xc42f, 0xc42f, 0xc430, 0xc430, 0xc430, 0xc430, 0xc430, 0xc430, 
+    0xc430, 0xc430, 0xc430, 0xc430, 0xc431, 0xc431, 0xc431, 0xc431, 
+    0xc431, 0xc431, 0xc431, 0xc431, 0xc431, 0xc432, 0xc432, 0xc432, 
+    0xc432, 0xc432, 0xc432, 0xc432, 0xc432, 0xc432, 0xc432, 0xc433, 
+    0xc433, 0xc433, 0xc433, 0xc433, 0xc433, 0xc433, 0xc433, 0xc433, 
+    0xc433, 0xc434, 0xc434, 0xc434, 0xc434, 0xc434, 0xc434, 0xc434, 
+    0xc434, 0xc434, 0xc434, 0xc435, 0xc435, 0xc435, 0xc435, 0xc435, 
+    0xc435, 0xc435, 0xc435, 0xc435, 0xc435, 0xc436, 0xc436, 0xc436, 
+    0xc436, 0xc436, 0xc436, 0xc436, 0xc436, 0xc436, 0xc436, 0xc437, 
+    0xc437, 0xc437, 0xc437, 0xc437, 0xc437, 0xc437, 0xc437, 0xc437, 
+    0xc437, 0xc438, 0xc438, 0xc438, 0xc438, 0xc438, 0xc438, 0xc438, 
+    0xc438, 0xc438, 0xc438, 0xc439, 0xc439, 0xc439, 0xc439, 0xc439, 
+    0xc439, 0xc439, 0xc439, 0xc439, 0xc439, 0xc43a, 0xc43a, 0xc43a, 
+    0xc43a, 0xc43a, 0xc43a, 0xc43a, 0xc43a, 0xc43a, 0xc43a, 0xc43a, 
+    0xc43b, 0xc43b, 0xc43b, 0xc43b, 0xc43b, 0xc43b, 0xc43b, 0xc43b, 
+    0xc43b, 0xc43b, 0xc43c, 0xc43c, 0xc43c, 0xc43c, 0xc43c, 0xc43c, 
+    0xc43c, 0xc43c, 0xc43c, 0xc43c, 0xc43c, 0xc43d, 0xc43d, 0xc43d, 
+    0xc43d, 0xc43d, 0xc43d, 0xc43d, 0xc43d, 0xc43d, 0xc43d, 0xc43d, 
+    0xc43e, 0xc43e, 0xc43e, 0xc43e, 0xc43e, 0xc43e, 0xc43e, 0xc43e, 
+    0xc43e, 0xc43e, 0xc43f, 0xc43f, 0xc43f, 0xc43f, 0xc43f, 0xc43f, 
+    0xc43f, 0xc43f, 0xc43f, 0xc43f, 0xc43f, 0xc440, 0xc440, 0xc440, 
+    0xc440, 0xc440, 0xc440, 0xc440, 0xc440, 0xc440, 0xc440, 0xc440, 
+    0xc441, 0xc441, 0xc441, 0xc441, 0xc441, 0xc441, 0xc441, 0xc441, 
+    0xc441, 0xc441, 0xc441, 0xc442, 0xc442, 0xc442, 0xc442, 0xc442, 
+    0xc442, 0xc442, 0xc442, 0xc442, 0xc442, 0xc442, 0xc443, 0xc443, 
+    0xc443, 0xc443, 0xc443, 0xc443, 0xc443, 0xc443, 0xc443, 0xc443, 
+    0xc443, 0xc443, 0xc444, 0xc444, 0xc444, 0xc444, 0xc444, 0xc444, 
+    0xc444, 0xc444, 0xc444, 0xc444, 0xc444, 0xc445, 0xc445, 0xc445, 
+    0xc445, 0xc445, 0xc445, 0xc445, 0xc445, 0xc445, 0xc445, 0xc445, 
+    0xc446, 0xc446, 0xc446, 0xc446, 0xc446, 0xc446, 0xc446, 0xc446, 
+    0xc446, 0xc446, 0xc446, 0xc446, 0xc447, 0xc447, 0xc447, 0xc447, 
+    0xc447, 0xc447, 0xc447, 0xc447, 0xc447, 0xc447, 0xc447, 0xc448, 
+    0xc448, 0xc448, 0xc448, 0xc448, 0xc448, 0xc448, 0xc448, 0xc448, 
+    0xc448, 0xc448, 0xc448, 0xc449, 0xc449, 0xc449, 0xc449, 0xc449, 
+    0xc449, 0xc449, 0xc449, 0xc449, 0xc449, 0xc449, 0xc449, 0xc44a, 
+    0xc44a, 0xc44a, 0xc44a, 0xc44a, 0xc44a, 0xc44a, 0xc44a, 0xc44a, 
+    0xc44a, 0xc44a, 0xc44a, 0xc44b, 0xc44b, 0xc44b, 0xc44b, 0xc44b, 
+    0xc44b, 0xc44b, 0xc44b, 0xc44b, 0xc44b, 0xc44b, 0xc44b, 0xc44c, 
+    0xc44c, 0xc44c, 0xc44c, 0xc44c, 0xc44c, 0xc44c, 0xc44c, 0xc44c, 
+    0xc44c, 0xc44c, 0xc44c, 0xc44d, 0xc44d, 0xc44d, 0xc44d, 0xc44d, 
+    0xc44d, 0xc44d, 0xc44d, 0xc44d, 0xc44d, 0xc44d, 0xc44d, 0xc44e, 
+    0xc44e, 0xc44e, 0xc44e, 0xc44e, 0xc44e, 0xc44e, 0xc44e, 0xc44e, 
+    0xc44e, 0xc44e, 0xc44e, 0xc44e, 0xc44f, 0xc44f, 0xc44f, 0xc44f, 
+    0xc44f, 0xc44f, 0xc44f, 0xc44f, 0xc44f, 0xc44f, 0xc44f, 0xc44f, 
+    0xc450, 0xc450, 0xc450, 0xc450, 0xc450, 0xc450, 0xc450, 0xc450, 
+    0xc450, 0xc450, 0xc450, 0xc450, 0xc450, 0xc451, 0xc451, 0xc451, 
+    0xc451, 0xc451, 0xc451, 0xc451, 0xc451, 0xc451, 0xc451, 0xc451, 
+    0xc451, 0xc452, 0xc452, 0xc452, 0xc452, 0xc452, 0xc452, 0xc452, 
+    0xc452, 0xc452, 0xc452, 0xc452, 0xc452, 0xc452, 0xc453, 0xc453, 
+    0xc453, 0xc453, 0xc453, 0xc453, 0xc453, 0xc453, 0xc453, 0xc453, 
+    0xc453, 0xc453, 0xc453, 0xc454, 0xc454, 0xc454, 0xc454, 0xc454, 
+    0xc454, 0xc454, 0xc454, 0xc454, 0xc454, 0xc454, 0xc454, 0xc454, 
+    0xc455, 0xc455, 0xc455, 0xc455, 0xc455, 0xc455, 0xc455, 0xc455, 
+    0xc455, 0xc455, 0xc455, 0xc455, 0xc455, 0xc456, 0xc456, 0xc456, 
+    0xc456, 0xc456, 0xc456, 0xc456, 0xc456, 0xc456, 0xc456, 0xc456, 
+    0xc456, 0xc456, 0xc457, 0xc457, 0xc457, 0xc457, 0xc457, 0xc457, 
+    0xc457, 0xc457, 0xc457, 0xc457, 0xc457, 0xc457, 0xc457, 0xc457, 
+    0xc458, 0xc458, 0xc458, 0xc458, 0xc458, 0xc458, 0xc458, 0xc458, 
+    0xc458, 0xc458, 0xc458, 0xc458, 0xc458, 0xc459, 0xc459, 0xc459, 
+    0xc459, 0xc459, 0xc459, 0xc459, 0xc459, 0xc459, 0xc459, 0xc459, 
+    0xc459, 0xc459, 0xc459, 0xc45a, 0xc45a, 0xc45a, 0xc45a, 0xc45a, 
+    0xc45a, 0xc45a, 0xc45a, 0xc45a, 0xc45a, 0xc45a, 0xc45a, 0xc45a, 
+    0xc45b, 0xc45b, 0xc45b, 0xc45b, 0xc45b, 0xc45b, 0xc45b, 0xc45b, 
+    0xc45b, 0xc45b, 0xc45b, 0xc45b, 0xc45b, 0xc45b, 0xc45c, 0xc45c, 
+    0xc45c, 0xc45c, 0xc45c, 0xc45c, 0xc45c, 0xc45c, 0xc45c, 0xc45c, 
+    0xc45c, 0xc45c, 0xc45c, 0xc45c, 0xc45d, 0xc45d, 0xc45d, 0xc45d, 
+    0xc45d, 0xc45d, 0xc45d, 0xc45d, 0xc45d, 0xc45d, 0xc45d, 0xc45d, 
+    0xc45d, 0xc45d, 0xc45e, 0xc45e, 0xc45e, 0xc45e, 0xc45e, 0xc45e, 
+    0xc45e, 0xc45e, 0xc45e, 0xc45e, 0xc45e, 0xc45e, 0xc45e, 0xc45e, 
+    0xc45f, 0xc45f, 0xc45f, 0xc45f, 0xc45f, 0xc45f, 0xc45f, 0xc45f, 
+    0xc45f, 0xc45f, 0xc45f, 0xc45f, 0xc45f, 0xc45f, 0xc45f, 0xc460, 
+    0xc460, 0xc460, 0xc460, 0xc460, 0xc460, 0xc460, 0xc460, 0xc460, 
+    0xc460, 0xc460, 0xc460, 0xc460, 0xc460, 0xc461, 0xc461, 0xc461, 
+    0xc461, 0xc461, 0xc461, 0xc461, 0xc461, 0xc461, 0xc461, 0xc461, 
+    0xc461, 0xc461, 0xc461, 0xc461, 0xc462, 0xc462, 0xc462, 0xc462, 
+    0xc462, 0xc462, 0xc462, 0xc462, 0xc462, 0xc462, 0xc462, 0xc462, 
+    0xc462, 0xc462, 0xc463, 0xc463, 0xc463, 0xc463, 0xc463, 0xc463, 
+    0xc463, 0xc463, 0xc463, 0xc463, 0xc463, 0xc463, 0xc463, 0xc463, 
+    0xc463, 0xc464, 0xc464, 0xc464, 0xc464, 0xc464, 0xc464, 0xc464, 
+    0xc464, 0xc464, 0xc464, 0xc464, 0xc464, 0xc464, 0xc464, 0xc464, 
+    0xc465, 0xc465, 0xc465, 0xc465, 0xc465, 0xc465, 0xc465, 0xc465, 
+    0xc465, 0xc465, 0xc465, 0xc465, 0xc465, 0xc465, 0xc465, 0xc466, 
+    0xc466, 0xc466, 0xc466, 0xc466, 0xc466, 0xc466, 0xc466, 0xc466, 
+    0xc466, 0xc466, 0xc466, 0xc466, 0xc466, 0xc466, 0xc467, 0xc467, 
+    0xc467, 0xc467, 0xc467, 0xc467, 0xc467, 0xc467, 0xc467, 0xc467, 
+    0xc467, 0xc467, 0xc467, 0xc467, 0xc467, 0xc467, 0xc468, 0xc468, 
+    0xc468, 0xc468, 0xc468, 0xc468, 0xc468, 0xc468, 0xc468, 0xc468, 
+    0xc468, 0xc468, 0xc468, 0xc468, 0xc468, 0xc469, 0xc469, 0xc469, 
+    0xc469, 0xc469, 0xc469, 0xc469, 0xc469, 0xc469, 0xc469, 0xc469, 
+    0xc469, 0xc469, 0xc469, 0xc469, 0xc469, 0xc46a, 0xc46a, 0xc46a, 
+    0xc46a, 0xc46a, 0xc46a, 0xc46a, 0xc46a, 0xc46a, 0xc46a, 0xc46a, 
+    0xc46a, 0xc46a, 0xc46a, 0xc46a, 0xc46b, 0xc46b, 0xc46b, 0xc46b, 
+    0xc46b, 0xc46b, 0xc46b, 0xc46b, 0xc46b, 0xc46b, 0xc46b, 0xc46b, 
+    0xc46b, 0xc46b, 0xc46b, 0xc46b, 0xc46c, 0xc46c, 0xc46c, 0xc46c, 
+    0xc46c, 0xc46c, 0xc46c, 0xc46c, 0xc46c, 0xc46c, 0xc46c, 0xc46c, 
+    0xc46c, 0xc46c, 0xc46c, 0xc46c, 0xc46d, 0xc46d, 0xc46d, 0xc46d, 
+    0xc46d, 0xc46d, 0xc46d, 0xc46d, 0xc46d, 0xc46d, 0xc46d, 0xc46d, 
+    0xc46d, 0xc46d, 0xc46d, 0xc46d, 0xc46e, 0xc46e, 0xc46e, 0xc46e, 
+    0xc46e, 0xc46e, 0xc46e, 0xc46e, 0xc46e, 0xc46e, 0xc46e, 0xc46e, 
+    0xc46e, 0xc46e, 0xc46e, 0xc46e, 0xc46e, 0xc46f, 0xc46f, 0xc46f, 
+    0xc46f, 0xc46f, 0xc46f, 0xc46f, 0xc46f, 0xc46f, 0xc46f, 0xc46f, 
+    0xc46f, 0xc46f, 0xc46f, 0xc46f, 0xc46f, 0xc470, 0xc470, 0xc470, 
+    0xc470, 0xc470, 0xc470, 0xc470, 0xc470, 0xc470, 0xc470, 0xc470, 
+    0xc470, 0xc470, 0xc470, 0xc470, 0xc470, 0xc471, 0xc471, 0xc471, 
+    0xc471, 0xc471, 0xc471, 0xc471, 0xc471, 0xc471, 0xc471, 0xc471, 
+    0xc471, 0xc471, 0xc471, 0xc471, 0xc471, 0xc471, 0xc472, 0xc472, 
+    0xc472, 0xc472, 0xc472, 0xc472, 0xc472, 0xc472, 0xc472, 0xc472, 
+    0xc472, 0xc472, 0xc472, 0xc472, 0xc472, 0xc472, 0xc472, 0xc473, 
+    0xc473, 0xc473, 0xc473, 0xc473, 0xc473, 0xc473, 0xc473, 0xc473, 
+    0xc473, 0xc473, 0xc473, 0xc473, 0xc473, 0xc473, 0xc473, 0xc473, 
+    0xc474, 0xc474, 0xc474, 0xc474, 0xc474, 0xc474, 0xc474, 0xc474, 
+    0xc474, 0xc474, 0xc474, 0xc474, 0xc474, 0xc474, 0xc474, 0xc474, 
+    0xc474, 0xc475, 0xc475, 0xc475, 0xc475, 0xc475, 0xc475, 0xc475, 
+    0xc475, 0xc475, 0xc475, 0xc475, 0xc475, 0xc475, 0xc475, 0xc475, 
+    0xc475, 0xc475, 0xc476, 0xc476, 0xc476, 0xc476, 0xc476, 0xc476, 
+    0xc476, 0xc476, 0xc476, 0xc476, 0xc476, 0xc476, 0xc476, 0xc476, 
+    0xc476, 0xc476, 0xc476, 0xc476, 0xc477, 0xc477, 0xc477, 0xc477, 
+    0xc477, 0xc477, 0xc477, 0xc477, 0xc477, 0xc477, 0xc477, 0xc477, 
+    0xc477, 0xc477, 0xc477, 0xc478, 0xc478, 0xc478, 0xc478, 0xc478, 
+    0xc478, 0xc478, 0xc478, 0xc478, 0xc479, 0xc479, 0xc479, 0xc479, 
+    0xc479, 0xc479, 0xc479, 0xc479, 0xc479, 0xc47a, 0xc47a, 0xc47a, 
+    0xc47a, 0xc47a, 0xc47a, 0xc47a, 0xc47a, 0xc47a, 0xc47b, 0xc47b, 
+    0xc47b, 0xc47b, 0xc47b, 0xc47b, 0xc47b, 0xc47b, 0xc47b, 0xc47c, 
+    0xc47c, 0xc47c, 0xc47c, 0xc47c, 0xc47c, 0xc47c, 0xc47c, 0xc47c, 
+    0xc47d, 0xc47d, 0xc47d, 0xc47d, 0xc47d, 0xc47d, 0xc47d, 0xc47d, 
+    0xc47d, 0xc47e, 0xc47e, 0xc47e, 0xc47e, 0xc47e, 0xc47e, 0xc47e, 
+    0xc47e, 0xc47e, 0xc47e, 0xc47f, 0xc47f, 0xc47f, 0xc47f, 0xc47f, 
+    0xc47f, 0xc47f, 0xc47f, 0xc47f, 0xc480, 0xc480, 0xc480, 0xc480, 
+    0xc480, 0xc480, 0xc480, 0xc480, 0xc480, 0xc481, 0xc481, 0xc481, 
+    0xc481, 0xc481, 0xc481, 0xc481, 0xc481, 0xc481, 0xc481, 0xc482, 
+    0xc482, 0xc482, 0xc482, 0xc482, 0xc482, 0xc482, 0xc482, 0xc482, 
+    0xc482, 0xc483, 0xc483, 0xc483, 0xc483, 0xc483, 0xc483, 0xc483, 
+    0xc483, 0xc483, 0xc484, 0xc484, 0xc484, 0xc484, 0xc484, 0xc484, 
+    0xc484, 0xc484, 0xc484, 0xc484, 0xc485, 0xc485, 0xc485, 0xc485, 
+    0xc485, 0xc485, 0xc485, 0xc485, 0xc485, 0xc485, 0xc486, 0xc486, 
+    0xc486, 0xc486, 0xc486, 0xc486, 0xc486, 0xc486, 0xc486, 0xc486, 
+    0xc487, 0xc487, 0xc487, 0xc487, 0xc487, 0xc487, 0xc487, 0xc487, 
+    0xc487, 0xc487, 0xc488, 0xc488, 0xc488, 0xc488, 0xc488, 0xc488, 
+    0xc488, 0xc488, 0xc488, 0xc488, 0xc489, 0xc489, 0xc489, 0xc489, 
+    0xc489, 0xc489, 0xc489, 0xc489, 0xc489, 0xc489, 0xc489, 0xc48a, 
+    0xc48a, 0xc48a, 0xc48a, 0xc48a, 0xc48a, 0xc48a, 0xc48a, 0xc48a, 
+    0xc48a, 0xc48b, 0xc48b, 0xc48b, 0xc48b, 0xc48b, 0xc48b, 0xc48b, 
+    0xc48b, 0xc48b, 0xc48b, 0xc48c, 0xc48c, 0xc48c, 0xc48c, 0xc48c, 
+    0xc48c, 0xc48c, 0xc48c, 0xc48c, 0xc48c, 0xc48c, 0xc48d, 0xc48d, 
+    0xc48d, 0xc48d, 0xc48d, 0xc48d, 0xc48d, 0xc48d, 0xc48d, 0xc48d, 
+    0xc48d, 0xc48e, 0xc48e, 0xc48e, 0xc48e, 0xc48e, 0xc48e, 0xc48e, 
+    0xc48e, 0xc48e, 0xc48e, 0xc48f, 0xc48f, 0xc48f, 0xc48f, 0xc48f, 
+    0xc48f, 0xc48f, 0xc48f, 0xc48f, 0xc48f, 0xc48f, 0xc490, 0xc490, 
+    0xc490, 0xc490, 0xc490, 0xc490, 0xc490, 0xc490, 0xc490, 0xc490, 
+    0xc490, 0xc491, 0xc491, 0xc491, 0xc491, 0xc491, 0xc491, 0xc491, 
+    0xc491, 0xc491, 0xc491, 0xc491, 0xc492, 0xc492, 0xc492, 0xc492, 
+    0xc492, 0xc492, 0xc492, 0xc492, 0xc492, 0xc492, 0xc492, 0xc493, 
+    0xc493, 0xc493, 0xc493, 0xc493, 0xc493, 0xc493, 0xc493, 0xc493, 
+    0xc493, 0xc493, 0xc494, 0xc494, 0xc494, 0xc494, 0xc494, 0xc494, 
+    0xc494, 0xc494, 0xc494, 0xc494, 0xc494, 0xc495, 0xc495, 0xc495, 
+    0xc495, 0xc495, 0xc495, 0xc495, 0xc495, 0xc495, 0xc495, 0xc495, 
+    0xc495, 0xc496, 0xc496, 0xc496, 0xc496, 0xc496, 0xc496, 0xc496, 
+    0xc496, 0xc496, 0xc496, 0xc496, 0xc497, 0xc497, 0xc497, 0xc497, 
+    0xc497, 0xc497, 0xc497, 0xc497, 0xc497, 0xc497, 0xc497, 0xc497, 
+    0xc498, 0xc498, 0xc498, 0xc498, 0xc498, 0xc498, 0xc498, 0xc498, 
+    0xc498, 0xc498, 0xc498, 0xc499, 0xc499, 0xc499, 0xc499, 0xc499, 
+    0xc499, 0xc499, 0xc499, 0xc499, 0xc499, 0xc499, 0xc499, 0xc49a, 
+    0xc49a, 0xc49a, 0xc49a, 0xc49a, 0xc49a, 0xc49a, 0xc49a, 0xc49a, 
+    0xc49a, 0xc49a, 0xc49a, 0xc49b, 0xc49b, 0xc49b, 0xc49b, 0xc49b, 
+    0xc49b, 0xc49b, 0xc49b, 0xc49b, 0xc49b, 0xc49b, 0xc49b, 0xc49c, 
+    0xc49c, 0xc49c, 0xc49c, 0xc49c, 0xc49c, 0xc49c, 0xc49c, 0xc49c, 
+    0xc49c, 0xc49c, 0xc49c, 0xc49d, 0xc49d, 0xc49d, 0xc49d, 0xc49d, 
+    0xc49d, 0xc49d, 0xc49d, 0xc49d, 0xc49d, 0xc49d, 0xc49d, 0xc49e, 
+    0xc49e, 0xc49e, 0xc49e, 0xc49e, 0xc49e, 0xc49e, 0xc49e, 0xc49e, 
+    0xc49e, 0xc49e, 0xc49e, 0xc49e, 0xc49f, 0xc49f, 0xc49f, 0xc49f, 
+    0xc49f, 0xc49f, 0xc49f, 0xc49f, 0xc49f, 0xc49f, 0xc49f, 0xc49f, 
+    0xc4a0, 0xc4a0, 0xc4a0, 0xc4a0, 0xc4a0, 0xc4a0, 0xc4a0, 0xc4a0, 
+    0xc4a0, 0xc4a0, 0xc4a0, 0xc4a0, 0xc4a1, 0xc4a1, 0xc4a1, 0xc4a1, 
+    0xc4a1, 0xc4a1, 0xc4a1, 0xc4a1, 0xc4a1, 0xc4a1, 0xc4a1, 0xc4a1, 
+    0xc4a1, 0xc4a2, 0xc4a2, 0xc4a2, 0xc4a2, 0xc4a2, 0xc4a2, 0xc4a2, 
+    0xc4a2, 0xc4a2, 0xc4a2, 0xc4a2, 0xc4a2, 0xc4a2, 0xc4a3, 0xc4a3, 
+    0xc4a3, 0xc4a3, 0xc4a3, 0xc4a3, 0xc4a3, 0xc4a3, 0xc4a3, 0xc4a3, 
+    0xc4a3, 0xc4a3, 0xc4a3, 0xc4a4, 0xc4a4, 0xc4a4, 0xc4a4, 0xc4a4, 
+    0xc4a4, 0xc4a4, 0xc4a4, 0xc4a4, 0xc4a4, 0xc4a4, 0xc4a4, 0xc4a5, 
+    0xc4a5, 0xc4a5, 0xc4a5, 0xc4a5, 0xc4a5, 0xc4a5, 0xc4a5, 0xc4a5, 
+    0xc4a5, 0xc4a5, 0xc4a5, 0xc4a5, 0xc4a5, 0xc4a6, 0xc4a6, 0xc4a6, 
+    0xc4a6, 0xc4a6, 0xc4a6, 0xc4a6, 0xc4a6, 0xc4a6, 0xc4a6, 0xc4a6, 
+    0xc4a6, 0xc4a6, 0xc4a7, 0xc4a7, 0xc4a7, 0xc4a7, 0xc4a7, 0xc4a7, 
+    0xc4a7, 0xc4a7, 0xc4a7, 0xc4a7, 0xc4a7, 0xc4a7, 0xc4a7, 0xc4a8, 
+    0xc4a8, 0xc4a8, 0xc4a8, 0xc4a8, 0xc4a8, 0xc4a8, 0xc4a8, 0xc4a8, 
+    0xc4a8, 0xc4a8, 0xc4a8, 0xc4a8, 0xc4a9, 0xc4a9, 0xc4a9, 0xc4a9, 
+    0xc4a9, 0xc4a9, 0xc4a9, 0xc4a9, 0xc4a9, 0xc4a9, 0xc4a9, 0xc4a9, 
+    0xc4a9, 0xc4a9, 0xc4aa, 0xc4aa, 0xc4aa, 0xc4aa, 0xc4aa, 0xc4aa, 
+    0xc4aa, 0xc4aa, 0xc4aa, 0xc4aa, 0xc4aa, 0xc4aa, 0xc4aa, 0xc4ab, 
+    0xc4ab, 0xc4ab, 0xc4ab, 0xc4ab, 0xc4ab, 0xc4ab, 0xc4ab, 0xc4ab, 
+    0xc4ab, 0xc4ab, 0xc4ab, 0xc4ab, 0xc4ab, 0xc4ac, 0xc4ac, 0xc4ac, 
+    0xc4ac, 0xc4ac, 0xc4ac, 0xc4ac, 0xc4ac, 0xc4ac, 0xc4ac, 0xc4ac, 
+    0xc4ac, 0xc4ac, 0xc4ac, 0xc4ad, 0xc4ad, 0xc4ad, 0xc4ad, 0xc4ad, 
+    0xc4ad, 0xc4ad, 0xc4ad, 0xc4ad, 0xc4ad, 0xc4ad, 0xc4ad, 0xc4ad, 
+    0xc4ad, 0xc4ae, 0xc4ae, 0xc4ae, 0xc4ae, 0xc4ae, 0xc4ae, 0xc4ae, 
+    0xc4ae, 0xc4ae, 0xc4ae, 0xc4ae, 0xc4ae, 0xc4ae, 0xc4ae, 0xc4af, 
+    0xc4af, 0xc4af, 0xc4af, 0xc4af, 0xc4af, 0xc4af, 0xc4af, 0xc4af, 
+    0xc4af, 0xc4af, 0xc4af, 0xc4af, 0xc4af, 0xc4b0, 0xc4b0, 0xc4b0, 
+    0xc4b0, 0xc4b0, 0xc4b0, 0xc4b0, 0xc4b0, 0xc4b0, 0xc4b0, 0xc4b0, 
+    0xc4b0, 0xc4b0, 0xc4b0, 0xc4b0, 0xc4b1, 0xc4b1, 0xc4b1, 0xc4b1, 
+    0xc4b1, 0xc4b1, 0xc4b1, 0xc4b1, 0xc4b1, 0xc4b1, 0xc4b1, 0xc4b1, 
+    0xc4b1, 0xc4b1, 0xc4b2, 0xc4b2, 0xc4b2, 0xc4b2, 0xc4b2, 0xc4b2, 
+    0xc4b2, 0xc4b2, 0xc4b2, 0xc4b2, 0xc4b2, 0xc4b2, 0xc4b2, 0xc4b2, 
+    0xc4b2, 0xc4b3, 0xc4b3, 0xc4b3, 0xc4b3, 0xc4b3, 0xc4b3, 0xc4b3, 
+    0xc4b3, 0xc4b3, 0xc4b3, 0xc4b3, 0xc4b3, 0xc4b3, 0xc4b3, 0xc4b4, 
+    0xc4b4, 0xc4b4, 0xc4b4, 0xc4b4, 0xc4b4, 0xc4b4, 0xc4b4, 0xc4b4, 
+    0xc4b4, 0xc4b4, 0xc4b4, 0xc4b4, 0xc4b4, 0xc4b4, 0xc4b5, 0xc4b5, 
+    0xc4b5, 0xc4b5, 0xc4b5, 0xc4b5, 0xc4b5, 0xc4b5, 0xc4b5, 0xc4b5, 
+    0xc4b5, 0xc4b5, 0xc4b5, 0xc4b5, 0xc4b5, 0xc4b6, 0xc4b6, 0xc4b6, 
+    0xc4b6, 0xc4b6, 0xc4b6, 0xc4b6, 0xc4b6, 0xc4b6, 0xc4b6, 0xc4b6, 
+    0xc4b6, 0xc4b6, 0xc4b6, 0xc4b6, 0xc4b7, 0xc4b7, 0xc4b7, 0xc4b7, 
+    0xc4b7, 0xc4b7, 0xc4b7, 0xc4b7, 0xc4b7, 0xc4b7, 0xc4b7, 0xc4b7, 
+    0xc4b7, 0xc4b7, 0xc4b7, 0xc4b8, 0xc4b8, 0xc4b8, 0xc4b8, 0xc4b8, 
+    0xc4b8, 0xc4b8, 0xc4b8, 0xc4b8, 0xc4b8, 0xc4b8, 0xc4b8, 0xc4b8, 
+    0xc4b8, 0xc4b8, 0xc4b8, 0xc4b9, 0xc4b9, 0xc4b9, 0xc4b9, 0xc4b9, 
+    0xc4b9, 0xc4b9, 0xc4b9, 0xc4b9, 0xc4b9, 0xc4b9, 0xc4b9, 0xc4b9, 
+    0xc4b9, 0xc4b9, 0xc4ba, 0xc4ba, 0xc4ba, 0xc4ba, 0xc4ba, 0xc4ba, 
+    0xc4ba, 0xc4ba, 0xc4ba, 0xc4ba, 0xc4ba, 0xc4ba, 0xc4ba, 0xc4ba, 
+    0xc4ba, 0xc4ba, 0xc4bb, 0xc4bb, 0xc4bb, 0xc4bb, 0xc4bb, 0xc4bb, 
+    0xc4bb, 0xc4bb, 0xc4bb, 0xc4bb, 0xc4bb, 0xc4bb, 0xc4bb, 0xc4bb, 
+    0xc4bb, 0xc4bb, 0xc4bc, 0xc4bc, 0xc4bc, 0xc4bc, 0xc4bc, 0xc4bc, 
+    0xc4bc, 0xc4bc, 0xc4bc, 0xc4bc, 0xc4bc, 0xc4bc, 0xc4bc, 0xc4bc, 
+    0xc4bc, 0xc4bc, 0xc4bd, 0xc4bd, 0xc4bd, 0xc4bd, 0xc4bd, 0xc4bd, 
+    0xc4bd, 0xc4bd, 0xc4bd, 0xc4bd, 0xc4bd, 0xc4bd, 0xc4bd, 0xc4bd, 
+    0xc4bd, 0xc4bd, 0xc4be, 0xc4be, 0xc4be, 0xc4be, 0xc4be, 0xc4be, 
+    0xc4be, 0xc4be, 0xc4be, 0xc4be, 0xc4be, 0xc4be, 0xc4be, 0xc4be, 
+    0xc4be, 0xc4be, 0xc4bf, 0xc4bf, 0xc4bf, 0xc4bf, 0xc4bf, 0xc4bf, 
+    0xc4bf, 0xc4bf, 0xc4bf, 0xc4bf, 0xc4bf, 0xc4bf, 0xc4bf, 0xc4bf, 
+    0xc4bf, 0xc4bf, 0xc4c0, 0xc4c0, 0xc4c0, 0xc4c0, 0xc4c0, 0xc4c0, 
+    0xc4c0, 0xc4c0, 0xc4c0, 0xc4c0, 0xc4c0, 0xc4c0, 0xc4c0, 0xc4c0, 
+    0xc4c0, 0xc4c0, 0xc4c0, 0xc4c1, 0xc4c1, 0xc4c1, 0xc4c1, 0xc4c1, 
+    0xc4c1, 0xc4c1, 0xc4c1, 0xc4c1, 0xc4c1, 0xc4c1, 0xc4c1, 0xc4c1, 
+    0xc4c1, 0xc4c1, 0xc4c1, 0xc4c2, 0xc4c2, 0xc4c2, 0xc4c2, 0xc4c2, 
+    0xc4c2, 0xc4c2, 0xc4c2, 0xc4c2, 0xc4c2, 0xc4c2, 0xc4c2, 0xc4c2, 
+    0xc4c2, 0xc4c2, 0xc4c2, 0xc4c2, 0xc4c3, 0xc4c3, 0xc4c3, 0xc4c3, 
+    0xc4c3, 0xc4c3, 0xc4c3, 0xc4c3, 0xc4c3, 0xc4c3, 0xc4c3, 0xc4c3, 
+    0xc4c3, 0xc4c3, 0xc4c3, 0xc4c3, 0xc4c3, 0xc4c4, 0xc4c4, 0xc4c4, 
+    0xc4c4, 0xc4c4, 0xc4c4, 0xc4c4, 0xc4c4, 0xc4c4, 0xc4c4, 0xc4c4, 
+    0xc4c4, 0xc4c4, 0xc4c4, 0xc4c4, 0xc4c4, 0xc4c4, 0xc4c5, 0xc4c5, 
+    0xc4c5, 0xc4c5, 0xc4c5, 0xc4c5, 0xc4c5, 0xc4c5, 0xc4c5, 0xc4c5, 
+    0xc4c5, 0xc4c5, 0xc4c5, 0xc4c5, 0xc4c5, 0xc4c5, 0xc4c5, 0xc4c6, 
+    0xc4c6, 0xc4c6, 0xc4c6, 0xc4c6, 0xc4c6, 0xc4c6, 0xc4c6, 0xc4c6, 
+    0xc4c6, 0xc4c6, 0xc4c6, 0xc4c6, 0xc4c6, 0xc4c6, 0xc4c6, 0xc4c6, 
+    0xc4c7, 0xc4c7, 0xc4c7, 0xc4c7, 0xc4c7, 0xc4c7, 0xc4c7, 0xc4c7, 
+    0xc4c7, 0xc4c7, 0xc4c7, 0xc4c7, 0xc4c7, 0xc4c7, 0xc4c7, 0xc4c7, 
+    0xc4c7, 0xc4c7, 0xc4c8, 0xc4c8, 0xc4c8, 0xc4c8, 0xc4c8, 0xc4c8, 
+    0xc4c8, 0xc4c8, 0xc4c8, 0xc4c8, 0xc4c8, 0xc4c8, 0xc4c9, 0xc4c9, 
+    0xc4c9, 0xc4c9, 0xc4c9, 0xc4c9, 0xc4c9, 0xc4c9, 0xc4c9, 0xc4ca, 
+    0xc4ca, 0xc4ca, 0xc4ca, 0xc4ca, 0xc4ca, 0xc4ca, 0xc4ca, 0xc4ca, 
+    0xc4cb, 0xc4cb, 0xc4cb, 0xc4cb, 0xc4cb, 0xc4cb, 0xc4cb, 0xc4cb, 
+    0xc4cb, 0xc4cc, 0xc4cc, 0xc4cc, 0xc4cc, 0xc4cc, 0xc4cc, 0xc4cc, 
+    0xc4cc, 0xc4cc, 0xc4cd, 0xc4cd, 0xc4cd, 0xc4cd, 0xc4cd, 0xc4cd, 
+    0xc4cd, 0xc4cd, 0xc4cd, 0xc4ce, 0xc4ce, 0xc4ce, 0xc4ce, 0xc4ce, 
+    0xc4ce, 0xc4ce, 0xc4ce, 0xc4ce, 0xc4cf, 0xc4cf, 0xc4cf, 0xc4cf, 
+    0xc4cf, 0xc4cf, 0xc4cf, 0xc4cf, 0xc4cf, 0xc4cf, 0xc4d0, 0xc4d0, 
+    0xc4d0, 0xc4d0, 0xc4d0, 0xc4d0, 0xc4d0, 0xc4d0, 0xc4d0, 0xc4d1, 
+    0xc4d1, 0xc4d1, 0xc4d1, 0xc4d1, 0xc4d1, 0xc4d1, 0xc4d1, 0xc4d1, 
+    0xc4d1, 0xc4d2, 0xc4d2, 0xc4d2, 0xc4d2, 0xc4d2, 0xc4d2, 0xc4d2, 
+    0xc4d2, 0xc4d2, 0xc4d3, 0xc4d3, 0xc4d3, 0xc4d3, 0xc4d3, 0xc4d3, 
+    0xc4d3, 0xc4d3, 0xc4d3, 0xc4d3, 0xc4d4, 0xc4d4, 0xc4d4, 0xc4d4, 
+    0xc4d4, 0xc4d4, 0xc4d4, 0xc4d4, 0xc4d4, 0xc4d4, 0xc4d5, 0xc4d5, 
+    0xc4d5, 0xc4d5, 0xc4d5, 0xc4d5, 0xc4d5, 0xc4d5, 0xc4d5, 0xc4d5, 
+    0xc4d6, 0xc4d6, 0xc4d6, 0xc4d6, 0xc4d6, 0xc4d6, 0xc4d6, 0xc4d6, 
+    0xc4d6, 0xc4d6, 0xc4d7, 0xc4d7, 0xc4d7, 0xc4d7, 0xc4d7, 0xc4d7, 
+    0xc4d7, 0xc4d7, 0xc4d7, 0xc4d7, 0xc4d8, 0xc4d8, 0xc4d8, 0xc4d8, 
+    0xc4d8, 0xc4d8, 0xc4d8, 0xc4d8, 0xc4d8, 0xc4d8, 0xc4d9, 0xc4d9, 
+    0xc4d9, 0xc4d9, 0xc4d9, 0xc4d9, 0xc4d9, 0xc4d9, 0xc4d9, 0xc4d9, 
+    0xc4da, 0xc4da, 0xc4da, 0xc4da, 0xc4da, 0xc4da, 0xc4da, 0xc4da, 
+    0xc4da, 0xc4da, 0xc4db, 0xc4db, 0xc4db, 0xc4db, 0xc4db, 0xc4db, 
+    0xc4db, 0xc4db, 0xc4db, 0xc4db, 0xc4db, 0xc4dc, 0xc4dc, 0xc4dc, 
+    0xc4dc, 0xc4dc, 0xc4dc, 0xc4dc, 0xc4dc, 0xc4dc, 0xc4dc, 0xc4dd, 
+    0xc4dd, 0xc4dd, 0xc4dd, 0xc4dd, 0xc4dd, 0xc4dd, 0xc4dd, 0xc4dd, 
+    0xc4dd, 0xc4dd, 0xc4de, 0xc4de, 0xc4de, 0xc4de, 0xc4de, 0xc4de, 
+    0xc4de, 0xc4de, 0xc4de, 0xc4de, 0xc4df, 0xc4df, 0xc4df, 0xc4df, 
+    0xc4df, 0xc4df, 0xc4df, 0xc4df, 0xc4df, 0xc4df, 0xc4df, 0xc4e0, 
+    0xc4e0, 0xc4e0, 0xc4e0, 0xc4e0, 0xc4e0, 0xc4e0, 0xc4e0, 0xc4e0, 
+    0xc4e0, 0xc4e0, 0xc4e1, 0xc4e1, 0xc4e1, 0xc4e1, 0xc4e1, 0xc4e1, 
+    0xc4e1, 0xc4e1, 0xc4e1, 0xc4e1, 0xc4e1, 0xc4e2, 0xc4e2, 0xc4e2, 
+    0xc4e2, 0xc4e2, 0xc4e2, 0xc4e2, 0xc4e2, 0xc4e2, 0xc4e2, 0xc4e2, 
+    0xc4e3, 0xc4e3, 0xc4e3, 0xc4e3, 0xc4e3, 0xc4e3, 0xc4e3, 0xc4e3, 
+    0xc4e3, 0xc4e3, 0xc4e3, 0xc4e4, 0xc4e4, 0xc4e4, 0xc4e4, 0xc4e4, 
+    0xc4e4, 0xc4e4, 0xc4e4, 0xc4e4, 0xc4e4, 0xc4e4, 0xc4e5, 0xc4e5, 
+    0xc4e5, 0xc4e5, 0xc4e5, 0xc4e5, 0xc4e5, 0xc4e5, 0xc4e5, 0xc4e5, 
+    0xc4e5, 0xc4e6, 0xc4e6, 0xc4e6, 0xc4e6, 0xc4e6, 0xc4e6, 0xc4e6, 
+    0xc4e6, 0xc4e6, 0xc4e6, 0xc4e6, 0xc4e6, 0xc4e7, 0xc4e7, 0xc4e7, 
+    0xc4e7, 0xc4e7, 0xc4e7, 0xc4e7, 0xc4e7, 0xc4e7, 0xc4e7, 0xc4e7, 
+    0xc4e8, 0xc4e8, 0xc4e8, 0xc4e8, 0xc4e8, 0xc4e8, 0xc4e8, 0xc4e8, 
+    0xc4e8, 0xc4e8, 0xc4e8, 0xc4e8, 0xc4e9, 0xc4e9, 0xc4e9, 0xc4e9, 
+    0xc4e9, 0xc4e9, 0xc4e9, 0xc4e9, 0xc4e9, 0xc4e9, 0xc4e9, 0xc4ea, 
+    0xc4ea, 0xc4ea, 0xc4ea, 0xc4ea, 0xc4ea, 0xc4ea, 0xc4ea, 0xc4ea, 
+    0xc4ea, 0xc4ea, 0xc4ea, 0xc4eb, 0xc4eb, 0xc4eb, 0xc4eb, 0xc4eb, 
+    0xc4eb, 0xc4eb, 0xc4eb, 0xc4eb, 0xc4eb, 0xc4eb, 0xc4eb, 0xc4ec, 
+    0xc4ec, 0xc4ec, 0xc4ec, 0xc4ec, 0xc4ec, 0xc4ec, 0xc4ec, 0xc4ec, 
+    0xc4ec, 0xc4ec, 0xc4ec, 0xc4ed, 0xc4ed, 0xc4ed, 0xc4ed, 0xc4ed, 
+    0xc4ed, 0xc4ed, 0xc4ed, 0xc4ed, 0xc4ed, 0xc4ed, 0xc4ed, 0xc4ee, 
+    0xc4ee, 0xc4ee, 0xc4ee, 0xc4ee, 0xc4ee, 0xc4ee, 0xc4ee, 0xc4ee, 
+    0xc4ee, 0xc4ee, 0xc4ee, 0xc4ef, 0xc4ef, 0xc4ef, 0xc4ef, 0xc4ef, 
+    0xc4ef, 0xc4ef, 0xc4ef, 0xc4ef, 0xc4ef, 0xc4ef, 0xc4ef, 0xc4ef, 
+    0xc4f0, 0xc4f0, 0xc4f0, 0xc4f0, 0xc4f0, 0xc4f0, 0xc4f0, 0xc4f0, 
+    0xc4f0, 0xc4f0, 0xc4f0, 0xc4f0, 0xc4f1, 0xc4f1, 0xc4f1, 0xc4f1, 
+    0xc4f1, 0xc4f1, 0xc4f1, 0xc4f1, 0xc4f1, 0xc4f1, 0xc4f1, 0xc4f1, 
+    0xc4f1, 0xc4f2, 0xc4f2, 0xc4f2, 0xc4f2, 0xc4f2, 0xc4f2, 0xc4f2, 
+    0xc4f2, 0xc4f2, 0xc4f2, 0xc4f2, 0xc4f2, 0xc4f3, 0xc4f3, 0xc4f3, 
+    0xc4f3, 0xc4f3, 0xc4f3, 0xc4f3, 0xc4f3, 0xc4f3, 0xc4f3, 0xc4f3, 
+    0xc4f3, 0xc4f3, 0xc4f4, 0xc4f4, 0xc4f4, 0xc4f4, 0xc4f4, 0xc4f4, 
+    0xc4f4, 0xc4f4, 0xc4f4, 0xc4f4, 0xc4f4, 0xc4f4, 0xc4f4, 0xc4f5, 
+    0xc4f5, 0xc4f5, 0xc4f5, 0xc4f5, 0xc4f5, 0xc4f5, 0xc4f5, 0xc4f5, 
+    0xc4f5, 0xc4f5, 0xc4f5, 0xc4f5, 0xc4f6, 0xc4f6, 0xc4f6, 0xc4f6, 
+    0xc4f6, 0xc4f6, 0xc4f6, 0xc4f6, 0xc4f6, 0xc4f6, 0xc4f6, 0xc4f6, 
+    0xc4f6, 0xc4f7, 0xc4f7, 0xc4f7, 0xc4f7, 0xc4f7, 0xc4f7, 0xc4f7, 
+    0xc4f7, 0xc4f7, 0xc4f7, 0xc4f7, 0xc4f7, 0xc4f7, 0xc4f8, 0xc4f8, 
+    0xc4f8, 0xc4f8, 0xc4f8, 0xc4f8, 0xc4f8, 0xc4f8, 0xc4f8, 0xc4f8, 
+    0xc4f8, 0xc4f8, 0xc4f8, 0xc4f8, 0xc4f9, 0xc4f9, 0xc4f9, 0xc4f9, 
+    0xc4f9, 0xc4f9, 0xc4f9, 0xc4f9, 0xc4f9, 0xc4f9, 0xc4f9, 0xc4f9, 
+    0xc4f9, 0xc4fa, 0xc4fa, 0xc4fa, 0xc4fa, 0xc4fa, 0xc4fa, 0xc4fa, 
+    0xc4fa, 0xc4fa, 0xc4fa, 0xc4fa, 0xc4fa, 0xc4fa, 0xc4fb, 0xc4fb, 
+    0xc4fb, 0xc4fb, 0xc4fb, 0xc4fb, 0xc4fb, 0xc4fb, 0xc4fb, 0xc4fb, 
+    0xc4fb, 0xc4fb, 0xc4fb, 0xc4fb, 0xc4fc, 0xc4fc, 0xc4fc, 0xc4fc, 
+    0xc4fc, 0xc4fc, 0xc4fc, 0xc4fc, 0xc4fc, 0xc4fc, 0xc4fc, 0xc4fc, 
+    0xc4fc, 0xc4fc, 0xc4fd, 0xc4fd, 0xc4fd, 0xc4fd, 0xc4fd, 0xc4fd, 
+    0xc4fd, 0xc4fd, 0xc4fd, 0xc4fd, 0xc4fd, 0xc4fd, 0xc4fd, 0xc4fd, 
+    0xc4fe, 0xc4fe, 0xc4fe, 0xc4fe, 0xc4fe, 0xc4fe, 0xc4fe, 0xc4fe, 
+    0xc4fe, 0xc4fe, 0xc4fe, 0xc4fe, 0xc4fe, 0xc4fe, 0xc4ff, 0xc4ff, 
+    0xc4ff, 0xc4ff, 0xc4ff, 0xc4ff, 0xc4ff, 0xc4ff, 0xc4ff, 0xc4ff, 
+    0xc4ff, 0xc4ff, 0xc4ff, 0xc4ff, 0xc500, 0xc500, 0xc500, 0xc500, 
+    0xc500, 0xc500, 0xc500, 0xc500, 0xc500, 0xc500, 0xc500, 0xc500, 
+    0xc500, 0xc500, 0xc501, 0xc501, 0xc501, 0xc501, 0xc501, 0xc501, 
+    0xc501, 0xc501, 0xc501, 0xc501, 0xc501, 0xc501, 0xc501, 0xc501, 
+    0xc501, 0xc502, 0xc502, 0xc502, 0xc502, 0xc502, 0xc502, 0xc502, 
+    0xc502, 0xc502, 0xc502, 0xc502, 0xc502, 0xc502, 0xc502, 0xc503, 
+    0xc503, 0xc503, 0xc503, 0xc503, 0xc503, 0xc503, 0xc503, 0xc503, 
+    0xc503, 0xc503, 0xc503, 0xc503, 0xc503, 0xc503, 0xc504, 0xc504, 
+    0xc504, 0xc504, 0xc504, 0xc504, 0xc504, 0xc504, 0xc504, 0xc504, 
+    0xc504, 0xc504, 0xc504, 0xc504, 0xc505, 0xc505, 0xc505, 0xc505, 
+    0xc505, 0xc505, 0xc505, 0xc505, 0xc505, 0xc505, 0xc505, 0xc505, 
+    0xc505, 0xc505, 0xc505, 0xc506, 0xc506, 0xc506, 0xc506, 0xc506, 
+    0xc506, 0xc506, 0xc506, 0xc506, 0xc506, 0xc506, 0xc506, 0xc506, 
+    0xc506, 0xc506, 0xc507, 0xc507, 0xc507, 0xc507, 0xc507, 0xc507, 
+    0xc507, 0xc507, 0xc507, 0xc507, 0xc507, 0xc507, 0xc507, 0xc507, 
+    0xc507, 0xc508, 0xc508, 0xc508, 0xc508, 0xc508, 0xc508, 0xc508, 
+    0xc508, 0xc508, 0xc508, 0xc508, 0xc508, 0xc508, 0xc508, 0xc508, 
+    0xc508, 0xc509, 0xc509, 0xc509, 0xc509, 0xc509, 0xc509, 0xc509, 
+    0xc509, 0xc509, 0xc509, 0xc509, 0xc509, 0xc509, 0xc509, 0xc509, 
+    0xc50a, 0xc50a, 0xc50a, 0xc50a, 0xc50a, 0xc50a, 0xc50a, 0xc50a, 
+    0xc50a, 0xc50a, 0xc50a, 0xc50a, 0xc50a, 0xc50a, 0xc50a, 0xc50a, 
+    0xc50b, 0xc50b, 0xc50b, 0xc50b, 0xc50b, 0xc50b, 0xc50b, 0xc50b, 
+    0xc50b, 0xc50b, 0xc50b, 0xc50b, 0xc50b, 0xc50b, 0xc50b, 0xc50c, 
+    0xc50c, 0xc50c, 0xc50c, 0xc50c, 0xc50c, 0xc50c, 0xc50c, 0xc50c, 
+    0xc50c, 0xc50c, 0xc50c, 0xc50c, 0xc50c, 0xc50c, 0xc50c, 0xc50d, 
+    0xc50d, 0xc50d, 0xc50d, 0xc50d, 0xc50d, 0xc50d, 0xc50d, 0xc50d, 
+    0xc50d, 0xc50d, 0xc50d, 0xc50d, 0xc50d, 0xc50d, 0xc50d, 0xc50e, 
+    0xc50e, 0xc50e, 0xc50e, 0xc50e, 0xc50e, 0xc50e, 0xc50e, 0xc50e, 
+    0xc50e, 0xc50e, 0xc50e, 0xc50e, 0xc50e, 0xc50e, 0xc50e, 0xc50f, 
+    0xc50f, 0xc50f, 0xc50f, 0xc50f, 0xc50f, 0xc50f, 0xc50f, 0xc50f, 
+    0xc50f, 0xc50f, 0xc50f, 0xc50f, 0xc50f, 0xc50f, 0xc50f, 0xc510, 
+    0xc510, 0xc510, 0xc510, 0xc510, 0xc510, 0xc510, 0xc510, 0xc510, 
+    0xc510, 0xc510, 0xc510, 0xc510, 0xc510, 0xc510, 0xc510, 0xc510, 
+    0xc511, 0xc511, 0xc511, 0xc511, 0xc511, 0xc511, 0xc511, 0xc511, 
+    0xc511, 0xc511, 0xc511, 0xc511, 0xc511, 0xc511, 0xc511, 0xc511, 
+    0xc512, 0xc512, 0xc512, 0xc512, 0xc512, 0xc512, 0xc512, 0xc512, 
+    0xc512, 0xc512, 0xc512, 0xc512, 0xc512, 0xc512, 0xc512, 0xc512, 
+    0xc512, 0xc513, 0xc513, 0xc513, 0xc513, 0xc513, 0xc513, 0xc513, 
+    0xc513, 0xc513, 0xc513, 0xc513, 0xc513, 0xc513, 0xc513, 0xc513, 
+    0xc513, 0xc513, 0xc514, 0xc514, 0xc514, 0xc514, 0xc514, 0xc514, 
+    0xc514, 0xc514, 0xc514, 0xc514, 0xc514, 0xc514, 0xc514, 0xc514, 
+    0xc514, 0xc514, 0xc514, 0xc515, 0xc515, 0xc515, 0xc515, 0xc515, 
+    0xc515, 0xc515, 0xc515, 0xc515, 0xc515, 0xc515, 0xc515, 0xc515, 
+    0xc515, 0xc515, 0xc515, 0xc515, 0xc516, 0xc516, 0xc516, 0xc516, 
+    0xc516, 0xc516, 0xc516, 0xc516, 0xc516, 0xc516, 0xc516, 0xc516, 
+    0xc516, 0xc516, 0xc516, 0xc516, 0xc516, 0xc517, 0xc517, 0xc517, 
+    0xc517, 0xc517, 0xc517, 0xc517, 0xc517, 0xc517, 0xc517, 0xc517, 
+    0xc517, 0xc517, 0xc517, 0xc517, 0xc517, 0xc517, 0xc518, 0xc518, 
+    0xc518, 0xc518, 0xc518, 0xc518, 0xc518, 0xc518, 0xc518, 0xc518, 
+    0xc518, 0xc518, 0xc518, 0xc518, 0xc518, 0xc518, 0xc518, 0xc518, 
+    0xc519, 0xc519, 0xc519, 0xc519, 0xc519, 0xc519, 0xc519, 0xc519, 
+    0xc519, 0xc51a, 0xc51a, 0xc51a, 0xc51a, 0xc51a, 0xc51a, 0xc51a, 
+    0xc51a, 0xc51a, 0xc51b, 0xc51b, 0xc51b, 0xc51b, 0xc51b, 0xc51b, 
+    0xc51b, 0xc51b, 0xc51b, 0xc51c, 0xc51c, 0xc51c, 0xc51c, 0xc51c, 
+    0xc51c, 0xc51c, 0xc51c, 0xc51c, 0xc51d, 0xc51d, 0xc51d, 0xc51d, 
+    0xc51d, 0xc51d, 0xc51d, 0xc51d, 0xc51d, 0xc51e, 0xc51e, 0xc51e, 
+    0xc51e, 0xc51e, 0xc51e, 0xc51e, 0xc51e, 0xc51e, 0xc51f, 0xc51f, 
+    0xc51f, 0xc51f, 0xc51f, 0xc51f, 0xc51f, 0xc51f, 0xc51f, 0xc51f, 
+    0xc520, 0xc520, 0xc520, 0xc520, 0xc520, 0xc520, 0xc520, 0xc520, 
+    0xc520, 0xc521, 0xc521, 0xc521, 0xc521, 0xc521, 0xc521, 0xc521, 
+    0xc521, 0xc521, 0xc522, 0xc522, 0xc522, 0xc522, 0xc522, 0xc522, 
+    0xc522, 0xc522, 0xc522, 0xc522, 0xc523, 0xc523, 0xc523, 0xc523, 
+    0xc523, 0xc523, 0xc523, 0xc523, 0xc523, 0xc523, 0xc524, 0xc524, 
+    0xc524, 0xc524, 0xc524, 0xc524, 0xc524, 0xc524, 0xc524, 0xc525, 
+    0xc525, 0xc525, 0xc525, 0xc525, 0xc525, 0xc525, 0xc525, 0xc525, 
+    0xc525, 0xc526, 0xc526, 0xc526, 0xc526, 0xc526, 0xc526, 0xc526, 
+    0xc526, 0xc526, 0xc526, 0xc527, 0xc527, 0xc527, 0xc527, 0xc527, 
+    0xc527, 0xc527, 0xc527, 0xc527, 0xc527, 0xc528, 0xc528, 0xc528, 
+    0xc528, 0xc528, 0xc528, 0xc528, 0xc528, 0xc528, 0xc528, 0xc529, 
+    0xc529, 0xc529, 0xc529, 0xc529, 0xc529, 0xc529, 0xc529, 0xc529, 
+    0xc529, 0xc52a, 0xc52a, 0xc52a, 0xc52a, 0xc52a, 0xc52a, 0xc52a, 
+    0xc52a, 0xc52a, 0xc52a, 0xc52b, 0xc52b, 0xc52b, 0xc52b, 0xc52b, 
+    0xc52b, 0xc52b, 0xc52b, 0xc52b, 0xc52b, 0xc52b, 0xc52c, 0xc52c, 
+    0xc52c, 0xc52c, 0xc52c, 0xc52c, 0xc52c, 0xc52c, 0xc52c, 0xc52c, 
+    0xc52d, 0xc52d, 0xc52d, 0xc52d, 0xc52d, 0xc52d, 0xc52d, 0xc52d, 
+    0xc52d, 0xc52d, 0xc52d, 0xc52e, 0xc52e, 0xc52e, 0xc52e, 0xc52e, 
+    0xc52e, 0xc52e, 0xc52e, 0xc52e, 0xc52e, 0xc52f, 0xc52f, 0xc52f, 
+    0xc52f, 0xc52f, 0xc52f, 0xc52f, 0xc52f, 0xc52f, 0xc52f, 0xc52f, 
+    0xc530, 0xc530, 0xc530, 0xc530, 0xc530, 0xc530, 0xc530, 0xc530, 
+    0xc530, 0xc530, 0xc530, 0xc531, 0xc531, 0xc531, 0xc531, 0xc531, 
+    0xc531, 0xc531, 0xc531, 0xc531, 0xc531, 0xc532, 0xc532, 0xc532, 
+    0xc532, 0xc532, 0xc532, 0xc532, 0xc532, 0xc532, 0xc532, 0xc532, 
+    0xc533, 0xc533, 0xc533, 0xc533, 0xc533, 0xc533, 0xc533, 0xc533, 
+    0xc533, 0xc533, 0xc533, 0xc534, 0xc534, 0xc534, 0xc534, 0xc534, 
+    0xc534, 0xc534, 0xc534, 0xc534, 0xc534, 0xc534, 0xc534, 0xc535, 
+    0xc535, 0xc535, 0xc535, 0xc535, 0xc535, 0xc535, 0xc535, 0xc535, 
+    0xc535, 0xc535, 0xc536, 0xc536, 0xc536, 0xc536, 0xc536, 0xc536, 
+    0xc536, 0xc536, 0xc536, 0xc536, 0xc536, 0xc537, 0xc537, 0xc537, 
+    0xc537, 0xc537, 0xc537, 0xc537, 0xc537, 0xc537, 0xc537, 0xc537, 
+    0xc537, 0xc538, 0xc538, 0xc538, 0xc538, 0xc538, 0xc538, 0xc538, 
+    0xc538, 0xc538, 0xc538, 0xc538, 0xc539, 0xc539, 0xc539, 0xc539, 
+    0xc539, 0xc539, 0xc539, 0xc539, 0xc539, 0xc539, 0xc539, 0xc539, 
+    0xc53a, 0xc53a, 0xc53a, 0xc53a, 0xc53a, 0xc53a, 0xc53a, 0xc53a, 
+    0xc53a, 0xc53a, 0xc53a, 0xc53b, 0xc53b, 0xc53b, 0xc53b, 0xc53b, 
+    0xc53b, 0xc53b, 0xc53b, 0xc53b, 0xc53b, 0xc53b, 0xc53b, 0xc53c, 
+    0xc53c, 0xc53c, 0xc53c, 0xc53c, 0xc53c, 0xc53c, 0xc53c, 0xc53c, 
+    0xc53c, 0xc53c, 0xc53c, 0xc53d, 0xc53d, 0xc53d, 0xc53d, 0xc53d, 
+    0xc53d, 0xc53d, 0xc53d, 0xc53d, 0xc53d, 0xc53d, 0xc53d, 0xc53e, 
+    0xc53e, 0xc53e, 0xc53e, 0xc53e, 0xc53e, 0xc53e, 0xc53e, 0xc53e, 
+    0xc53e, 0xc53e, 0xc53e, 0xc53f, 0xc53f, 0xc53f, 0xc53f, 0xc53f, 
+    0xc53f, 0xc53f, 0xc53f, 0xc53f, 0xc53f, 0xc53f, 0xc53f, 0xc53f, 
+    0xc540, 0xc540, 0xc540, 0xc540, 0xc540, 0xc540, 0xc540, 0xc540, 
+    0xc540, 0xc540, 0xc540, 0xc540, 0xc541, 0xc541, 0xc541, 0xc541, 
+    0xc541, 0xc541, 0xc541, 0xc541, 0xc541, 0xc541, 0xc541, 0xc541, 
+    0xc541, 0xc542, 0xc542, 0xc542, 0xc542, 0xc542, 0xc542, 0xc542, 
+    0xc542, 0xc542, 0xc542, 0xc542, 0xc542, 0xc543, 0xc543, 0xc543, 
+    0xc543, 0xc543, 0xc543, 0xc543, 0xc543, 0xc543, 0xc543, 0xc543, 
+    0xc543, 0xc543, 0xc544, 0xc544, 0xc544, 0xc544, 0xc544, 0xc544, 
+    0xc544, 0xc544, 0xc544, 0xc544, 0xc544, 0xc544, 0xc544, 0xc545, 
+    0xc545, 0xc545, 0xc545, 0xc545, 0xc545, 0xc545, 0xc545, 0xc545, 
+    0xc545, 0xc545, 0xc545, 0xc546, 0xc546, 0xc546, 0xc546, 0xc546, 
+    0xc546, 0xc546, 0xc546, 0xc546, 0xc546, 0xc546, 0xc546, 0xc546, 
+    0xc547, 0xc547, 0xc547, 0xc547, 0xc547, 0xc547, 0xc547, 0xc547, 
+    0xc547, 0xc547, 0xc547, 0xc547, 0xc547, 0xc547, 0xc548, 0xc548, 
+    0xc548, 0xc548, 0xc548, 0xc548, 0xc548, 0xc548, 0xc548, 0xc548, 
+    0xc548, 0xc548, 0xc548, 0xc549, 0xc549, 0xc549, 0xc549, 0xc549, 
+    0xc549, 0xc549, 0xc549, 0xc549, 0xc549, 0xc549, 0xc549, 0xc549, 
+    0xc54a, 0xc54a, 0xc54a, 0xc54a, 0xc54a, 0xc54a, 0xc54a, 0xc54a, 
+    0xc54a, 0xc54a, 0xc54a, 0xc54a, 0xc54a, 0xc54a, 0xc54b, 0xc54b, 
+    0xc54b, 0xc54b, 0xc54b, 0xc54b, 0xc54b, 0xc54b, 0xc54b, 0xc54b, 
+    0xc54b, 0xc54b, 0xc54b, 0xc54c, 0xc54c, 0xc54c, 0xc54c, 0xc54c, 
+    0xc54c, 0xc54c, 0xc54c, 0xc54c, 0xc54c, 0xc54c, 0xc54c, 0xc54c, 
+    0xc54c, 0xc54d, 0xc54d, 0xc54d, 0xc54d, 0xc54d, 0xc54d, 0xc54d, 
+    0xc54d, 0xc54d, 0xc54d, 0xc54d, 0xc54d, 0xc54d, 0xc54d, 0xc54e, 
+    0xc54e, 0xc54e, 0xc54e, 0xc54e, 0xc54e, 0xc54e, 0xc54e, 0xc54e, 
+    0xc54e, 0xc54e, 0xc54e, 0xc54e, 0xc54e, 0xc54f, 0xc54f, 0xc54f, 
+    0xc54f, 0xc54f, 0xc54f, 0xc54f, 0xc54f, 0xc54f, 0xc54f, 0xc54f, 
+    0xc54f, 0xc54f, 0xc54f, 0xc550, 0xc550, 0xc550, 0xc550, 0xc550, 
+    0xc550, 0xc550, 0xc550, 0xc550, 0xc550, 0xc550, 0xc550, 0xc550, 
+    0xc550, 0xc551, 0xc551, 0xc551, 0xc551, 0xc551, 0xc551, 0xc551, 
+    0xc551, 0xc551, 0xc551, 0xc551, 0xc551, 0xc551, 0xc551, 0xc552, 
+    0xc552, 0xc552, 0xc552, 0xc552, 0xc552, 0xc552, 0xc552, 0xc552, 
+    0xc552, 0xc552, 0xc552, 0xc552, 0xc552, 0xc552, 0xc553, 0xc553, 
+    0xc553, 0xc553, 0xc553, 0xc553, 0xc553, 0xc553, 0xc553, 0xc553, 
+    0xc553, 0xc553, 0xc553, 0xc553, 0xc554, 0xc554, 0xc554, 0xc554, 
+    0xc554, 0xc554, 0xc554, 0xc554, 0xc554, 0xc554, 0xc554, 0xc554, 
+    0xc554, 0xc554, 0xc554, 0xc555, 0xc555, 0xc555, 0xc555, 0xc555, 
+    0xc555, 0xc555, 0xc555, 0xc555, 0xc555, 0xc555, 0xc555, 0xc555, 
+    0xc555, 0xc555, 0xc556, 0xc556, 0xc556, 0xc556, 0xc556, 0xc556, 
+    0xc556, 0xc556, 0xc556, 0xc556, 0xc556, 0xc556, 0xc556, 0xc556, 
+    0xc557, 0xc557, 0xc557, 0xc557, 0xc557, 0xc557, 0xc557, 0xc557, 
+    0xc557, 0xc557, 0xc557, 0xc557, 0xc557, 0xc557, 0xc557, 0xc557, 
+    0xc558, 0xc558, 0xc558, 0xc558, 0xc558, 0xc558, 0xc558, 0xc558, 
+    0xc558, 0xc558, 0xc558, 0xc558, 0xc558, 0xc558, 0xc558, 0xc559, 
+    0xc559, 0xc559, 0xc559, 0xc559, 0xc559, 0xc559, 0xc559, 0xc559, 
+    0xc559, 0xc559, 0xc559, 0xc559, 0xc559, 0xc559, 0xc55a, 0xc55a, 
+    0xc55a, 0xc55a, 0xc55a, 0xc55a, 0xc55a, 0xc55a, 0xc55a, 0xc55a, 
+    0xc55a, 0xc55a, 0xc55a, 0xc55a, 0xc55a, 0xc55b, 0xc55b, 0xc55b, 
+    0xc55b, 0xc55b, 0xc55b, 0xc55b, 0xc55b, 0xc55b, 0xc55b, 0xc55b, 
+    0xc55b, 0xc55b, 0xc55b, 0xc55b, 0xc55b, 0xc55c, 0xc55c, 0xc55c, 
+    0xc55c, 0xc55c, 0xc55c, 0xc55c, 0xc55c, 0xc55c, 0xc55c, 0xc55c, 
+    0xc55c, 0xc55c, 0xc55c, 0xc55c, 0xc55c, 0xc55d, 0xc55d, 0xc55d, 
+    0xc55d, 0xc55d, 0xc55d, 0xc55d, 0xc55d, 0xc55d, 0xc55d, 0xc55d, 
+    0xc55d, 0xc55d, 0xc55d, 0xc55d, 0xc55d, 0xc55e, 0xc55e, 0xc55e, 
+    0xc55e, 0xc55e, 0xc55e, 0xc55e, 0xc55e, 0xc55e, 0xc55e, 0xc55e, 
+    0xc55e, 0xc55e, 0xc55e, 0xc55e, 0xc55e, 0xc55f, 0xc55f, 0xc55f, 
+    0xc55f, 0xc55f, 0xc55f, 0xc55f, 0xc55f, 0xc55f, 0xc55f, 0xc55f, 
+    0xc55f, 0xc55f, 0xc55f, 0xc55f, 0xc55f, 0xc560, 0xc560, 0xc560, 
+    0xc560, 0xc560, 0xc560, 0xc560, 0xc560, 0xc560, 0xc560, 0xc560, 
+    0xc560, 0xc560, 0xc560, 0xc560, 0xc560, 0xc561, 0xc561, 0xc561, 
+    0xc561, 0xc561, 0xc561, 0xc561, 0xc561, 0xc561, 0xc561, 0xc561, 
+    0xc561, 0xc561, 0xc561, 0xc561, 0xc561, 0xc562, 0xc562, 0xc562, 
+    0xc562, 0xc562, 0xc562, 0xc562, 0xc562, 0xc562, 0xc562, 0xc562, 
+    0xc562, 0xc562, 0xc562, 0xc562, 0xc562, 0xc562, 0xc563, 0xc563, 
+    0xc563, 0xc563, 0xc563, 0xc563, 0xc563, 0xc563, 0xc563, 0xc563, 
+    0xc563, 0xc563, 0xc563, 0xc563, 0xc563, 0xc563, 0xc563, 0xc564, 
+    0xc564, 0xc564, 0xc564, 0xc564, 0xc564, 0xc564, 0xc564, 0xc564, 
+    0xc564, 0xc564, 0xc564, 0xc564, 0xc564, 0xc564, 0xc564, 0xc565, 
+    0xc565, 0xc565, 0xc565, 0xc565, 0xc565, 0xc565, 0xc565, 0xc565, 
+    0xc565, 0xc565, 0xc565, 0xc565, 0xc565, 0xc565, 0xc565, 0xc565, 
+    0xc566, 0xc566, 0xc566, 0xc566, 0xc566, 0xc566, 0xc566, 0xc566, 
+    0xc566, 0xc566, 0xc566, 0xc566, 0xc566, 0xc566, 0xc566, 0xc566, 
+    0xc566, 0xc566, 0xc567, 0xc567, 0xc567, 0xc567, 0xc567, 0xc567, 
+    0xc567, 0xc567, 0xc567, 0xc567, 0xc567, 0xc567, 0xc567, 0xc567, 
+    0xc567, 0xc567, 0xc567, 0xc568, 0xc568, 0xc568, 0xc568, 0xc568, 
+    0xc568, 0xc568, 0xc568, 0xc568, 0xc568, 0xc568, 0xc568, 0xc568, 
+    0xc568, 0xc568, 0xc568, 0xc568, 0xc569, 0xc569, 0xc569, 0xc569, 
+    0xc569, 0xc569, 0xc569, 0xc569, 0xc569, 0xc569, 0xc569, 0xc569, 
+    0xc569, 0xc569, 0xc569, 0xc56a, 0xc56a, 0xc56a, 0xc56a, 0xc56a, 
+    0xc56a, 0xc56a, 0xc56a, 0xc56a, 0xc56b, 0xc56b, 0xc56b, 0xc56b, 
+    0xc56b, 0xc56b, 0xc56b, 0xc56b, 0xc56b, 0xc56c, 0xc56c, 0xc56c, 
+    0xc56c, 0xc56c, 0xc56c, 0xc56c, 0xc56c, 0xc56c, 0xc56d, 0xc56d, 
+    0xc56d, 0xc56d, 0xc56d, 0xc56d, 0xc56d, 0xc56d, 0xc56d, 0xc56e, 
+    0xc56e, 0xc56e, 0xc56e, 0xc56e, 0xc56e, 0xc56e, 0xc56e, 0xc56e, 
+    0xc56f, 0xc56f, 0xc56f, 0xc56f, 0xc56f, 0xc56f, 0xc56f, 0xc56f, 
+    0xc56f, 0xc570, 0xc570, 0xc570, 0xc570, 0xc570, 0xc570, 0xc570, 
+    0xc570, 0xc570, 0xc570, 0xc571, 0xc571, 0xc571, 0xc571, 0xc571, 
+    0xc571, 0xc571, 0xc571, 0xc571, 0xc572, 0xc572, 0xc572, 0xc572, 
+    0xc572, 0xc572, 0xc572, 0xc572, 0xc572, 0xc572, 0xc573, 0xc573, 
+    0xc573, 0xc573, 0xc573, 0xc573, 0xc573, 0xc573, 0xc573, 0xc574, 
+    0xc574, 0xc574, 0xc574, 0xc574, 0xc574, 0xc574, 0xc574, 0xc574, 
+    0xc574, 0xc575, 0xc575, 0xc575, 0xc575, 0xc575, 0xc575, 0xc575, 
+    0xc575, 0xc575, 0xc575, 0xc576, 0xc576, 0xc576, 0xc576, 0xc576, 
+    0xc576, 0xc576, 0xc576, 0xc576, 0xc577, 0xc577, 0xc577, 0xc577, 
+    0xc577, 0xc577, 0xc577, 0xc577, 0xc577, 0xc577, 0xc578, 0xc578, 
+    0xc578, 0xc578, 0xc578, 0xc578, 0xc578, 0xc578, 0xc578, 0xc578, 
+    0xc579, 0xc579, 0xc579, 0xc579, 0xc579, 0xc579, 0xc579, 0xc579, 
+    0xc579, 0xc579, 0xc57a, 0xc57a, 0xc57a, 0xc57a, 0xc57a, 0xc57a, 
+    0xc57a, 0xc57a, 0xc57a, 0xc57a, 0xc57a, 0xc57b, 0xc57b, 0xc57b, 
+    0xc57b, 0xc57b, 0xc57b, 0xc57b, 0xc57b, 0xc57b, 0xc57b, 0xc57c, 
+    0xc57c, 0xc57c, 0xc57c, 0xc57c, 0xc57c, 0xc57c, 0xc57c, 0xc57c, 
+    0xc57c, 0xc57d, 0xc57d, 0xc57d, 0xc57d, 0xc57d, 0xc57d, 0xc57d, 
+    0xc57d, 0xc57d, 0xc57d, 0xc57d, 0xc57e, 0xc57e, 0xc57e, 0xc57e, 
+    0xc57e, 0xc57e, 0xc57e, 0xc57e, 0xc57e, 0xc57e, 0xc57f, 0xc57f, 
+    0xc57f, 0xc57f, 0xc57f, 0xc57f, 0xc57f, 0xc57f, 0xc57f, 0xc57f, 
+    0xc57f, 0xc580, 0xc580, 0xc580, 0xc580, 0xc580, 0xc580, 0xc580, 
+    0xc580, 0xc580, 0xc580, 0xc580, 0xc581, 0xc581, 0xc581, 0xc581, 
+    0xc581, 0xc581, 0xc581, 0xc581, 0xc581, 0xc581, 0xc582, 0xc582, 
+    0xc582, 0xc582, 0xc582, 0xc582, 0xc582, 0xc582, 0xc582, 0xc582, 
+    0xc582, 0xc583, 0xc583, 0xc583, 0xc583, 0xc583, 0xc583, 0xc583, 
+    0xc583, 0xc583, 0xc583, 0xc583, 0xc584, 0xc584, 0xc584, 0xc584, 
+    0xc584, 0xc584, 0xc584, 0xc584, 0xc584, 0xc584, 0xc584, 0xc585, 
+    0xc585, 0xc585, 0xc585, 0xc585, 0xc585, 0xc585, 0xc585, 0xc585, 
+    0xc585, 0xc585, 0xc586, 0xc586, 0xc586, 0xc586, 0xc586, 0xc586, 
+    0xc586, 0xc586, 0xc586, 0xc586, 0xc586, 0xc586, 0xc587, 0xc587, 
+    0xc587, 0xc587, 0xc587, 0xc587, 0xc587, 0xc587, 0xc587, 0xc587, 
+    0xc587, 0xc588, 0xc588, 0xc588, 0xc588, 0xc588, 0xc588, 0xc588, 
+    0xc588, 0xc588, 0xc588, 0xc588, 0xc588, 0xc589, 0xc589, 0xc589, 
+    0xc589, 0xc589, 0xc589, 0xc589, 0xc589, 0xc589, 0xc589, 0xc589, 
+    0xc58a, 0xc58a, 0xc58a, 0xc58a, 0xc58a, 0xc58a, 0xc58a, 0xc58a, 
+    0xc58a, 0xc58a, 0xc58a, 0xc58a, 0xc58b, 0xc58b, 0xc58b, 0xc58b, 
+    0xc58b, 0xc58b, 0xc58b, 0xc58b, 0xc58b, 0xc58b, 0xc58b, 0xc58b, 
+    0xc58c, 0xc58c, 0xc58c, 0xc58c, 0xc58c, 0xc58c, 0xc58c, 0xc58c, 
+    0xc58c, 0xc58c, 0xc58c, 0xc58d, 0xc58d, 0xc58d, 0xc58d, 0xc58d, 
+    0xc58d, 0xc58d, 0xc58d, 0xc58d, 0xc58d, 0xc58d, 0xc58d, 0xc58e, 
+    0xc58e, 0xc58e, 0xc58e, 0xc58e, 0xc58e, 0xc58e, 0xc58e, 0xc58e, 
+    0xc58e, 0xc58e, 0xc58e, 0xc58f, 0xc58f, 0xc58f, 0xc58f, 0xc58f, 
+    0xc58f, 0xc58f, 0xc58f, 0xc58f, 0xc58f, 0xc58f, 0xc58f, 0xc58f, 
+    0xc590, 0xc590, 0xc590, 0xc590, 0xc590, 0xc590, 0xc590, 0xc590, 
+    0xc590, 0xc590, 0xc590, 0xc590, 0xc591, 0xc591, 0xc591, 0xc591, 
+    0xc591, 0xc591, 0xc591, 0xc591, 0xc591, 0xc591, 0xc591, 0xc591, 
+    0xc592, 0xc592, 0xc592, 0xc592, 0xc592, 0xc592, 0xc592, 0xc592, 
+    0xc592, 0xc592, 0xc592, 0xc592, 0xc592, 0xc593, 0xc593, 0xc593, 
+    0xc593, 0xc593, 0xc593, 0xc593, 0xc593, 0xc593, 0xc593, 0xc593, 
+    0xc593, 0xc594, 0xc594, 0xc594, 0xc594, 0xc594, 0xc594, 0xc594, 
+    0xc594, 0xc594, 0xc594, 0xc594, 0xc594, 0xc594, 0xc595, 0xc595, 
+    0xc595, 0xc595, 0xc595, 0xc595, 0xc595, 0xc595, 0xc595, 0xc595, 
+    0xc595, 0xc595, 0xc595, 0xc596, 0xc596, 0xc596, 0xc596, 0xc596, 
+    0xc596, 0xc596, 0xc596, 0xc596, 0xc596, 0xc596, 0xc596, 0xc596, 
+    0xc597, 0xc597, 0xc597, 0xc597, 0xc597, 0xc597, 0xc597, 0xc597, 
+    0xc597, 0xc597, 0xc597, 0xc597, 0xc597, 0xc598, 0xc598, 0xc598, 
+    0xc598, 0xc598, 0xc598, 0xc598, 0xc598, 0xc598, 0xc598, 0xc598, 
+    0xc598, 0xc598, 0xc599, 0xc599, 0xc599, 0xc599, 0xc599, 0xc599, 
+    0xc599, 0xc599, 0xc599, 0xc599, 0xc599, 0xc599, 0xc599, 0xc59a, 
+    0xc59a, 0xc59a, 0xc59a, 0xc59a, 0xc59a, 0xc59a, 0xc59a, 0xc59a, 
+    0xc59a, 0xc59a, 0xc59a, 0xc59a, 0xc59a, 0xc59b, 0xc59b, 0xc59b, 
+    0xc59b, 0xc59b, 0xc59b, 0xc59b, 0xc59b, 0xc59b, 0xc59b, 0xc59b, 
+    0xc59b, 0xc59b, 0xc59c, 0xc59c, 0xc59c, 0xc59c, 0xc59c, 0xc59c, 
+    0xc59c, 0xc59c, 0xc59c, 0xc59c, 0xc59c, 0xc59c, 0xc59c, 0xc59c, 
+    0xc59d, 0xc59d, 0xc59d, 0xc59d, 0xc59d, 0xc59d, 0xc59d, 0xc59d, 
+    0xc59d, 0xc59d, 0xc59d, 0xc59d, 0xc59d, 0xc59d, 0xc59e, 0xc59e, 
+    0xc59e, 0xc59e, 0xc59e, 0xc59e, 0xc59e, 0xc59e, 0xc59e, 0xc59e, 
+    0xc59e, 0xc59e, 0xc59e, 0xc59f, 0xc59f, 0xc59f, 0xc59f, 0xc59f, 
+    0xc59f, 0xc59f, 0xc59f, 0xc59f, 0xc59f, 0xc59f, 0xc59f, 0xc59f, 
+    0xc59f, 0xc5a0, 0xc5a0, 0xc5a0, 0xc5a0, 0xc5a0, 0xc5a0, 0xc5a0, 
+    0xc5a0, 0xc5a0, 0xc5a0, 0xc5a0, 0xc5a0, 0xc5a0, 0xc5a0, 0xc5a1, 
+    0xc5a1, 0xc5a1, 0xc5a1, 0xc5a1, 0xc5a1, 0xc5a1, 0xc5a1, 0xc5a1, 
+    0xc5a1, 0xc5a1, 0xc5a1, 0xc5a1, 0xc5a1, 0xc5a1, 0xc5a2, 0xc5a2, 
+    0xc5a2, 0xc5a2, 0xc5a2, 0xc5a2, 0xc5a2, 0xc5a2, 0xc5a2, 0xc5a2, 
+    0xc5a2, 0xc5a2, 0xc5a2, 0xc5a2, 0xc5a3, 0xc5a3, 0xc5a3, 0xc5a3, 
+    0xc5a3, 0xc5a3, 0xc5a3, 0xc5a3, 0xc5a3, 0xc5a3, 0xc5a3, 0xc5a3, 
+    0xc5a3, 0xc5a3, 0xc5a3, 0xc5a4, 0xc5a4, 0xc5a4, 0xc5a4, 0xc5a4, 
+    0xc5a4, 0xc5a4, 0xc5a4, 0xc5a4, 0xc5a4, 0xc5a4, 0xc5a4, 0xc5a4, 
+    0xc5a4, 0xc5a5, 0xc5a5, 0xc5a5, 0xc5a5, 0xc5a5, 0xc5a5, 0xc5a5, 
+    0xc5a5, 0xc5a5, 0xc5a5, 0xc5a5, 0xc5a5, 0xc5a5, 0xc5a5, 0xc5a5, 
+    0xc5a6, 0xc5a6, 0xc5a6, 0xc5a6, 0xc5a6, 0xc5a6, 0xc5a6, 0xc5a6, 
+    0xc5a6, 0xc5a6, 0xc5a6, 0xc5a6, 0xc5a6, 0xc5a6, 0xc5a6, 0xc5a7, 
+    0xc5a7, 0xc5a7, 0xc5a7, 0xc5a7, 0xc5a7, 0xc5a7, 0xc5a7, 0xc5a7, 
+    0xc5a7, 0xc5a7, 0xc5a7, 0xc5a7, 0xc5a7, 0xc5a7, 0xc5a8, 0xc5a8, 
+    0xc5a8, 0xc5a8, 0xc5a8, 0xc5a8, 0xc5a8, 0xc5a8, 0xc5a8, 0xc5a8, 
+    0xc5a8, 0xc5a8, 0xc5a8, 0xc5a8, 0xc5a8, 0xc5a9, 0xc5a9, 0xc5a9, 
+    0xc5a9, 0xc5a9, 0xc5a9, 0xc5a9, 0xc5a9, 0xc5a9, 0xc5a9, 0xc5a9, 
+    0xc5a9, 0xc5a9, 0xc5a9, 0xc5a9, 0xc5aa, 0xc5aa, 0xc5aa, 0xc5aa, 
+    0xc5aa, 0xc5aa, 0xc5aa, 0xc5aa, 0xc5aa, 0xc5aa, 0xc5aa, 0xc5aa, 
+    0xc5aa, 0xc5aa, 0xc5aa, 0xc5ab, 0xc5ab, 0xc5ab, 0xc5ab, 0xc5ab, 
+    0xc5ab, 0xc5ab, 0xc5ab, 0xc5ab, 0xc5ab, 0xc5ab, 0xc5ab, 0xc5ab, 
+    0xc5ab, 0xc5ab, 0xc5ab, 0xc5ac, 0xc5ac, 0xc5ac, 0xc5ac, 0xc5ac, 
+    0xc5ac, 0xc5ac, 0xc5ac, 0xc5ac, 0xc5ac, 0xc5ac, 0xc5ac, 0xc5ac, 
+    0xc5ac, 0xc5ac, 0xc5ad, 0xc5ad, 0xc5ad, 0xc5ad, 0xc5ad, 0xc5ad, 
+    0xc5ad, 0xc5ad, 0xc5ad, 0xc5ad, 0xc5ad, 0xc5ad, 0xc5ad, 0xc5ad, 
+    0xc5ad, 0xc5ad, 0xc5ae, 0xc5ae, 0xc5ae, 0xc5ae, 0xc5ae, 0xc5ae, 
+    0xc5ae, 0xc5ae, 0xc5ae, 0xc5ae, 0xc5ae, 0xc5ae, 0xc5ae, 0xc5ae, 
+    0xc5ae, 0xc5ae, 0xc5af, 0xc5af, 0xc5af, 0xc5af, 0xc5af, 0xc5af, 
+    0xc5af, 0xc5af, 0xc5af, 0xc5af, 0xc5af, 0xc5af, 0xc5af, 0xc5af, 
+    0xc5af, 0xc5af, 0xc5b0, 0xc5b0, 0xc5b0, 0xc5b0, 0xc5b0, 0xc5b0, 
+    0xc5b0, 0xc5b0, 0xc5b0, 0xc5b0, 0xc5b0, 0xc5b0, 0xc5b0, 0xc5b0, 
+    0xc5b0, 0xc5b0, 0xc5b1, 0xc5b1, 0xc5b1, 0xc5b1, 0xc5b1, 0xc5b1, 
+    0xc5b1, 0xc5b1, 0xc5b1, 0xc5b1, 0xc5b1, 0xc5b1, 0xc5b1, 0xc5b1, 
+    0xc5b1, 0xc5b1, 0xc5b1, 0xc5b2, 0xc5b2, 0xc5b2, 0xc5b2, 0xc5b2, 
+    0xc5b2, 0xc5b2, 0xc5b2, 0xc5b2, 0xc5b2, 0xc5b2, 0xc5b2, 0xc5b2, 
+    0xc5b2, 0xc5b2, 0xc5b2, 0xc5b3, 0xc5b3, 0xc5b3, 0xc5b3, 0xc5b3, 
+    0xc5b3, 0xc5b3, 0xc5b3, 0xc5b3, 0xc5b3, 0xc5b3, 0xc5b3, 0xc5b3, 
+    0xc5b3, 0xc5b3, 0xc5b3, 0xc5b3, 0xc5b4, 0xc5b4, 0xc5b4, 0xc5b4, 
+    0xc5b4, 0xc5b4, 0xc5b4, 0xc5b4, 0xc5b4, 0xc5b4, 0xc5b4, 0xc5b4, 
+    0xc5b4, 0xc5b4, 0xc5b4, 0xc5b4, 0xc5b5, 0xc5b5, 0xc5b5, 0xc5b5, 
+    0xc5b5, 0xc5b5, 0xc5b5, 0xc5b5, 0xc5b5, 0xc5b5, 0xc5b5, 0xc5b5, 
+    0xc5b5, 0xc5b5, 0xc5b5, 0xc5b5, 0xc5b5, 0xc5b6, 0xc5b6, 0xc5b6, 
+    0xc5b6, 0xc5b6, 0xc5b6, 0xc5b6, 0xc5b6, 0xc5b6, 0xc5b6, 0xc5b6, 
+    0xc5b6, 0xc5b6, 0xc5b6, 0xc5b6, 0xc5b6, 0xc5b6, 0xc5b7, 0xc5b7, 
+    0xc5b7, 0xc5b7, 0xc5b7, 0xc5b7, 0xc5b7, 0xc5b7, 0xc5b7, 0xc5b7, 
+    0xc5b7, 0xc5b7, 0xc5b7, 0xc5b7, 0xc5b7, 0xc5b7, 0xc5b7, 0xc5b8, 
+    0xc5b8, 0xc5b8, 0xc5b8, 0xc5b8, 0xc5b8, 0xc5b8, 0xc5b8, 0xc5b8, 
+    0xc5b8, 0xc5b8, 0xc5b8, 0xc5b8, 0xc5b8, 0xc5b8, 0xc5b8, 0xc5b8, 
+    0xc5b8, 0xc5b9, 0xc5b9, 0xc5b9, 0xc5b9, 0xc5b9, 0xc5b9, 0xc5b9, 
+    0xc5b9, 0xc5b9, 0xc5b9, 0xc5b9, 0xc5b9, 0xc5b9, 0xc5b9, 0xc5b9, 
+    0xc5b9, 0xc5b9, 0xc5ba, 0xc5ba, 0xc5ba, 0xc5ba, 0xc5ba, 0xc5ba, 
+    0xc5ba, 0xc5ba, 0xc5ba, 0xc5ba, 0xc5ba, 0xc5ba, 0xc5bb, 0xc5bb, 
+    0xc5bb, 0xc5bb, 0xc5bb, 0xc5bb, 0xc5bb, 0xc5bb, 0xc5bb, 0xc5bc, 
+    0xc5bc, 0xc5bc, 0xc5bc, 0xc5bc, 0xc5bc, 0xc5bc, 0xc5bc, 0xc5bc, 
+    0xc5bd, 0xc5bd, 0xc5bd, 0xc5bd, 0xc5bd, 0xc5bd, 0xc5bd, 0xc5bd, 
+    0xc5bd, 0xc5be, 0xc5be, 0xc5be, 0xc5be, 0xc5be, 0xc5be, 0xc5be, 
+    0xc5be, 0xc5be, 0xc5bf, 0xc5bf, 0xc5bf, 0xc5bf, 0xc5bf, 0xc5bf, 
+    0xc5bf, 0xc5bf, 0xc5bf, 0xc5c0, 0xc5c0, 0xc5c0, 0xc5c0, 0xc5c0, 
+    0xc5c0, 0xc5c0, 0xc5c0, 0xc5c0, 0xc5c0, 0xc5c1, 0xc5c1, 0xc5c1, 
+    0xc5c1, 0xc5c1, 0xc5c1, 0xc5c1, 0xc5c1, 0xc5c1, 0xc5c2, 0xc5c2, 
+    0xc5c2, 0xc5c2, 0xc5c2, 0xc5c2, 0xc5c2, 0xc5c2, 0xc5c2, 0xc5c3, 
+    0xc5c3, 0xc5c3, 0xc5c3, 0xc5c3, 0xc5c3, 0xc5c3, 0xc5c3, 0xc5c3, 
+    0xc5c3, 0xc5c4, 0xc5c4, 0xc5c4, 0xc5c4, 0xc5c4, 0xc5c4, 0xc5c4, 
+    0xc5c4, 0xc5c4, 0xc5c4, 0xc5c5, 0xc5c5, 0xc5c5, 0xc5c5, 0xc5c5, 
+    0xc5c5, 0xc5c5, 0xc5c5, 0xc5c5, 0xc5c6, 0xc5c6, 0xc5c6, 0xc5c6, 
+    0xc5c6, 0xc5c6, 0xc5c6, 0xc5c6, 0xc5c6, 0xc5c6, 0xc5c7, 0xc5c7, 
+    0xc5c7, 0xc5c7, 0xc5c7, 0xc5c7, 0xc5c7, 0xc5c7, 0xc5c7, 0xc5c7, 
+    0xc5c8, 0xc5c8, 0xc5c8, 0xc5c8, 0xc5c8, 0xc5c8, 0xc5c8, 0xc5c8, 
+    0xc5c8, 0xc5c8, 0xc5c9, 0xc5c9, 0xc5c9, 0xc5c9, 0xc5c9, 0xc5c9, 
+    0xc5c9, 0xc5c9, 0xc5c9, 0xc5c9, 0xc5ca, 0xc5ca, 0xc5ca, 0xc5ca, 
+    0xc5ca, 0xc5ca, 0xc5ca, 0xc5ca, 0xc5ca, 0xc5ca, 0xc5cb, 0xc5cb, 
+    0xc5cb, 0xc5cb, 0xc5cb, 0xc5cb, 0xc5cb, 0xc5cb, 0xc5cb, 0xc5cb, 
+    0xc5cc, 0xc5cc, 0xc5cc, 0xc5cc, 0xc5cc, 0xc5cc, 0xc5cc, 0xc5cc, 
+    0xc5cc, 0xc5cc, 0xc5cd, 0xc5cd, 0xc5cd, 0xc5cd, 0xc5cd, 0xc5cd, 
+    0xc5cd, 0xc5cd, 0xc5cd, 0xc5cd, 0xc5cd, 0xc5ce, 0xc5ce, 0xc5ce, 
+    0xc5ce, 0xc5ce, 0xc5ce, 0xc5ce, 0xc5ce, 0xc5ce, 0xc5ce, 0xc5cf, 
+    0xc5cf, 0xc5cf, 0xc5cf, 0xc5cf, 0xc5cf, 0xc5cf, 0xc5cf, 0xc5cf, 
+    0xc5cf, 0xc5cf, 0xc5d0, 0xc5d0, 0xc5d0, 0xc5d0, 0xc5d0, 0xc5d0, 
+    0xc5d0, 0xc5d0, 0xc5d0, 0xc5d0, 0xc5d1, 0xc5d1, 0xc5d1, 0xc5d1, 
+    0xc5d1, 0xc5d1, 0xc5d1, 0xc5d1, 0xc5d1, 0xc5d1, 0xc5d1, 0xc5d2, 
+    0xc5d2, 0xc5d2, 0xc5d2, 0xc5d2, 0xc5d2, 0xc5d2, 0xc5d2, 0xc5d2, 
+    0xc5d2, 0xc5d2, 0xc5d3, 0xc5d3, 0xc5d3, 0xc5d3, 0xc5d3, 0xc5d3, 
+    0xc5d3, 0xc5d3, 0xc5d3, 0xc5d3, 0xc5d3, 0xc5d4, 0xc5d4, 0xc5d4, 
+    0xc5d4, 0xc5d4, 0xc5d4, 0xc5d4, 0xc5d4, 0xc5d4, 0xc5d4, 0xc5d4, 
+    0xc5d5, 0xc5d5, 0xc5d5, 0xc5d5, 0xc5d5, 0xc5d5, 0xc5d5, 0xc5d5, 
+    0xc5d5, 0xc5d5, 0xc5d5, 0xc5d6, 0xc5d6, 0xc5d6, 0xc5d6, 0xc5d6, 
+    0xc5d6, 0xc5d6, 0xc5d6, 0xc5d6, 0xc5d6, 0xc5d6, 0xc5d7, 0xc5d7, 
+    0xc5d7, 0xc5d7, 0xc5d7, 0xc5d7, 0xc5d7, 0xc5d7, 0xc5d7, 0xc5d7, 
+    0xc5d7, 0xc5d7, 0xc5d8, 0xc5d8, 0xc5d8, 0xc5d8, 0xc5d8, 0xc5d8, 
+    0xc5d8, 0xc5d8, 0xc5d8, 0xc5d8, 0xc5d8, 0xc5d9, 0xc5d9, 0xc5d9, 
+    0xc5d9, 0xc5d9, 0xc5d9, 0xc5d9, 0xc5d9, 0xc5d9, 0xc5d9, 0xc5d9, 
+    0xc5da, 0xc5da, 0xc5da, 0xc5da, 0xc5da, 0xc5da, 0xc5da, 0xc5da, 
+    0xc5da, 0xc5da, 0xc5da, 0xc5da, 0xc5db, 0xc5db, 0xc5db, 0xc5db, 
+    0xc5db, 0xc5db, 0xc5db, 0xc5db, 0xc5db, 0xc5db, 0xc5db, 0xc5db, 
+    0xc5dc, 0xc5dc, 0xc5dc, 0xc5dc, 0xc5dc, 0xc5dc, 0xc5dc, 0xc5dc, 
+    0xc5dc, 0xc5dc, 0xc5dc, 0xc5dc, 0xc5dd, 0xc5dd, 0xc5dd, 0xc5dd, 
+    0xc5dd, 0xc5dd, 0xc5dd, 0xc5dd, 0xc5dd, 0xc5dd, 0xc5dd, 0xc5dd, 
+    0xc5de, 0xc5de, 0xc5de, 0xc5de, 0xc5de, 0xc5de, 0xc5de, 0xc5de, 
+    0xc5de, 0xc5de, 0xc5de, 0xc5de, 0xc5df, 0xc5df, 0xc5df, 0xc5df, 
+    0xc5df, 0xc5df, 0xc5df, 0xc5df, 0xc5df, 0xc5df, 0xc5df, 0xc5df, 
+    0xc5e0, 0xc5e0, 0xc5e0, 0xc5e0, 0xc5e0, 0xc5e0, 0xc5e0, 0xc5e0, 
+    0xc5e0, 0xc5e0, 0xc5e0, 0xc5e0, 0xc5e1, 0xc5e1, 0xc5e1, 0xc5e1, 
+    0xc5e1, 0xc5e1, 0xc5e1, 0xc5e1, 0xc5e1, 0xc5e1, 0xc5e1, 0xc5e1, 
+    0xc5e2, 0xc5e2, 0xc5e2, 0xc5e2, 0xc5e2, 0xc5e2, 0xc5e2, 0xc5e2, 
+    0xc5e2, 0xc5e2, 0xc5e2, 0xc5e2, 0xc5e2, 0xc5e3, 0xc5e3, 0xc5e3, 
+    0xc5e3, 0xc5e3, 0xc5e3, 0xc5e3, 0xc5e3, 0xc5e3, 0xc5e3, 0xc5e3, 
+    0xc5e3, 0xc5e4, 0xc5e4, 0xc5e4, 0xc5e4, 0xc5e4, 0xc5e4, 0xc5e4, 
+    0xc5e4, 0xc5e4, 0xc5e4, 0xc5e4, 0xc5e4, 0xc5e4, 0xc5e5, 0xc5e5, 
+    0xc5e5, 0xc5e5, 0xc5e5, 0xc5e5, 0xc5e5, 0xc5e5, 0xc5e5, 0xc5e5, 
+    0xc5e5, 0xc5e5, 0xc5e6, 0xc5e6, 0xc5e6, 0xc5e6, 0xc5e6, 0xc5e6, 
+    0xc5e6, 0xc5e6, 0xc5e6, 0xc5e6, 0xc5e6, 0xc5e6, 0xc5e6, 0xc5e7, 
+    0xc5e7, 0xc5e7, 0xc5e7, 0xc5e7, 0xc5e7, 0xc5e7, 0xc5e7, 0xc5e7, 
+    0xc5e7, 0xc5e7, 0xc5e7, 0xc5e7, 0xc5e8, 0xc5e8, 0xc5e8, 0xc5e8, 
+    0xc5e8, 0xc5e8, 0xc5e8, 0xc5e8, 0xc5e8, 0xc5e8, 0xc5e8, 0xc5e8, 
+    0xc5e8, 0xc5e9, 0xc5e9, 0xc5e9, 0xc5e9, 0xc5e9, 0xc5e9, 0xc5e9, 
+    0xc5e9, 0xc5e9, 0xc5e9, 0xc5e9, 0xc5e9, 0xc5e9, 0xc5e9, 0xc5ea, 
+    0xc5ea, 0xc5ea, 0xc5ea, 0xc5ea, 0xc5ea, 0xc5ea, 0xc5ea, 0xc5ea, 
+    0xc5ea, 0xc5ea, 0xc5ea, 0xc5ea, 0xc5eb, 0xc5eb, 0xc5eb, 0xc5eb, 
+    0xc5eb, 0xc5eb, 0xc5eb, 0xc5eb, 0xc5eb, 0xc5eb, 0xc5eb, 0xc5eb, 
+    0xc5eb, 0xc5ec, 0xc5ec, 0xc5ec, 0xc5ec, 0xc5ec, 0xc5ec, 0xc5ec, 
+    0xc5ec, 0xc5ec, 0xc5ec, 0xc5ec, 0xc5ec, 0xc5ec, 0xc5ec, 0xc5ed, 
+    0xc5ed, 0xc5ed, 0xc5ed, 0xc5ed, 0xc5ed, 0xc5ed, 0xc5ed, 0xc5ed, 
+    0xc5ed, 0xc5ed, 0xc5ed, 0xc5ed, 0xc5ed, 0xc5ee, 0xc5ee, 0xc5ee, 
+    0xc5ee, 0xc5ee, 0xc5ee, 0xc5ee, 0xc5ee, 0xc5ee, 0xc5ee, 0xc5ee, 
+    0xc5ee, 0xc5ee, 0xc5ef, 0xc5ef, 0xc5ef, 0xc5ef, 0xc5ef, 0xc5ef, 
+    0xc5ef, 0xc5ef, 0xc5ef, 0xc5ef, 0xc5ef, 0xc5ef, 0xc5ef, 0xc5ef, 
+    0xc5f0, 0xc5f0, 0xc5f0, 0xc5f0, 0xc5f0, 0xc5f0, 0xc5f0, 0xc5f0, 
+    0xc5f0, 0xc5f0, 0xc5f0, 0xc5f0, 0xc5f0, 0xc5f0, 0xc5f1, 0xc5f1, 
+    0xc5f1, 0xc5f1, 0xc5f1, 0xc5f1, 0xc5f1, 0xc5f1, 0xc5f1, 0xc5f1, 
+    0xc5f1, 0xc5f1, 0xc5f1, 0xc5f1, 0xc5f2, 0xc5f2, 0xc5f2, 0xc5f2, 
+    0xc5f2, 0xc5f2, 0xc5f2, 0xc5f2, 0xc5f2, 0xc5f2, 0xc5f2, 0xc5f2, 
+    0xc5f2, 0xc5f2, 0xc5f2, 0xc5f3, 0xc5f3, 0xc5f3, 0xc5f3, 0xc5f3, 
+    0xc5f3, 0xc5f3, 0xc5f3, 0xc5f3, 0xc5f3, 0xc5f3, 0xc5f3, 0xc5f3, 
+    0xc5f3, 0xc5f4, 0xc5f4, 0xc5f4, 0xc5f4, 0xc5f4, 0xc5f4, 0xc5f4, 
+    0xc5f4, 0xc5f4, 0xc5f4, 0xc5f4, 0xc5f4, 0xc5f4, 0xc5f4, 0xc5f5, 
+    0xc5f5, 0xc5f5, 0xc5f5, 0xc5f5, 0xc5f5, 0xc5f5, 0xc5f5, 0xc5f5, 
+    0xc5f5, 0xc5f5, 0xc5f5, 0xc5f5, 0xc5f5, 0xc5f5, 0xc5f6, 0xc5f6, 
+    0xc5f6, 0xc5f6, 0xc5f6, 0xc5f6, 0xc5f6, 0xc5f6, 0xc5f6, 0xc5f6, 
+    0xc5f6, 0xc5f6, 0xc5f6, 0xc5f6, 0xc5f6, 0xc5f7, 0xc5f7, 0xc5f7, 
+    0xc5f7, 0xc5f7, 0xc5f7, 0xc5f7, 0xc5f7, 0xc5f7, 0xc5f7, 0xc5f7, 
+    0xc5f7, 0xc5f7, 0xc5f7, 0xc5f7, 0xc5f8, 0xc5f8, 0xc5f8, 0xc5f8, 
+    0xc5f8, 0xc5f8, 0xc5f8, 0xc5f8, 0xc5f8, 0xc5f8, 0xc5f8, 0xc5f8, 
+    0xc5f8, 0xc5f8, 0xc5f8, 0xc5f9, 0xc5f9, 0xc5f9, 0xc5f9, 0xc5f9, 
+    0xc5f9, 0xc5f9, 0xc5f9, 0xc5f9, 0xc5f9, 0xc5f9, 0xc5f9, 0xc5f9, 
+    0xc5f9, 0xc5f9, 0xc5fa, 0xc5fa, 0xc5fa, 0xc5fa, 0xc5fa, 0xc5fa, 
+    0xc5fa, 0xc5fa, 0xc5fa, 0xc5fa, 0xc5fa, 0xc5fa, 0xc5fa, 0xc5fa, 
+    0xc5fa, 0xc5fb, 0xc5fb, 0xc5fb, 0xc5fb, 0xc5fb, 0xc5fb, 0xc5fb, 
+    0xc5fb, 0xc5fb, 0xc5fb, 0xc5fb, 0xc5fb, 0xc5fb, 0xc5fb, 0xc5fb, 
+    0xc5fb, 0xc5fc, 0xc5fc, 0xc5fc, 0xc5fc, 0xc5fc, 0xc5fc, 0xc5fc, 
+    0xc5fc, 0xc5fc, 0xc5fc, 0xc5fc, 0xc5fc, 0xc5fc, 0xc5fc, 0xc5fc, 
+    0xc5fd, 0xc5fd, 0xc5fd, 0xc5fd, 0xc5fd, 0xc5fd, 0xc5fd, 0xc5fd, 
+    0xc5fd, 0xc5fd, 0xc5fd, 0xc5fd, 0xc5fd, 0xc5fd, 0xc5fd, 0xc5fd, 
+    0xc5fe, 0xc5fe, 0xc5fe, 0xc5fe, 0xc5fe, 0xc5fe, 0xc5fe, 0xc5fe, 
+    0xc5fe, 0xc5fe, 0xc5fe, 0xc5fe, 0xc5fe, 0xc5fe, 0xc5fe, 0xc5fe, 
+    0xc5ff, 0xc5ff, 0xc5ff, 0xc5ff, 0xc5ff, 0xc5ff, 0xc5ff, 0xc5ff, 
+    0xc5ff, 0xc5ff, 0xc5ff, 0xc5ff, 0xc5ff, 0xc5ff, 0xc5ff, 0xc5ff, 
+    0xc600, 0xc600, 0xc600, 0xc600, 0xc600, 0xc600, 0xc600, 0xc600, 
+    0xc600, 0xc600, 0xc600, 0xc600, 0xc600, 0xc600, 0xc600, 0xc600, 
+    0xc601, 0xc601, 0xc601, 0xc601, 0xc601, 0xc601, 0xc601, 0xc601, 
+    0xc601, 0xc601, 0xc601, 0xc601, 0xc601, 0xc601, 0xc601, 0xc601, 
+    0xc602, 0xc602, 0xc602, 0xc602, 0xc602, 0xc602, 0xc602, 0xc602, 
+    0xc602, 0xc602, 0xc602, 0xc602, 0xc602, 0xc602, 0xc602, 0xc602, 
+    0xc603, 0xc603, 0xc603, 0xc603, 0xc603, 0xc603, 0xc603, 0xc603, 
+    0xc603, 0xc603, 0xc603, 0xc603, 0xc603, 0xc603, 0xc603, 0xc603, 
+    0xc603, 0xc604, 0xc604, 0xc604, 0xc604, 0xc604, 0xc604, 0xc604, 
+    0xc604, 0xc604, 0xc604, 0xc604, 0xc604, 0xc604, 0xc604, 0xc604, 
+    0xc604, 0xc605, 0xc605, 0xc605, 0xc605, 0xc605, 0xc605, 0xc605, 
+    0xc605, 0xc605, 0xc605, 0xc605, 0xc605, 0xc605, 0xc605, 0xc605, 
+    0xc605, 0xc605, 0xc606, 0xc606, 0xc606, 0xc606, 0xc606, 0xc606, 
+    0xc606, 0xc606, 0xc606, 0xc606, 0xc606, 0xc606, 0xc606, 0xc606, 
+    0xc606, 0xc606, 0xc606, 0xc607, 0xc607, 0xc607, 0xc607, 0xc607, 
+    0xc607, 0xc607, 0xc607, 0xc607, 0xc607, 0xc607, 0xc607, 0xc607, 
+    0xc607, 0xc607, 0xc607, 0xc607, 0xc608, 0xc608, 0xc608, 0xc608, 
+    0xc608, 0xc608, 0xc608, 0xc608, 0xc608, 0xc608, 0xc608, 0xc608, 
+    0xc608, 0xc608, 0xc608, 0xc608, 0xc608, 0xc609, 0xc609, 0xc609, 
+    0xc609, 0xc609, 0xc609, 0xc609, 0xc609, 0xc609, 0xc609, 0xc609, 
+    0xc609, 0xc609, 0xc609, 0xc609, 0xc609, 0xc609, 0xc609, 0xc60a, 
+    0xc60a, 0xc60a, 0xc60a, 0xc60a, 0xc60a, 0xc60a, 0xc60a, 0xc60a, 
+    0xc60a, 0xc60a, 0xc60a, 0xc60a, 0xc60a, 0xc60a, 0xc60a, 0xc60a, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+};
+
+
+
+static unsigned int closestDataOffset[] = {
+         0,      0,      1,      2,      4,      5,      7,      9, 
+        12,     13,     15,     17,     20,     22,     25,     28, 
+        32,     33,     35,     37,     40,     42,     45,     48, 
+        52,     54,     57,     60,     64,     67,     71,     75, 
+        80,     81,     83,     85,     88,     90,     93,     96, 
+       100,    102,    105,    108,    112,    115,    119,    123, 
+       128,    130,    133,    136,    140,    143,    147,    151, 
+       156,    159,    163,    167,    172,    176,    181,    186, 
+       192,    193,    195,    197,    200,    202,    205,    208, 
+       212,    214,    217,    220,    224,    227,    231,    235, 
+       240,    242,    245,    248,    252,    255,    259,    263, 
+       268,    271,    275,    279,    284,    288,    293,    298, 
+       304,    306,    309,    312,    316,    319,    323,    327, 
+       332,    335,    339,    343,    348,    352,    357,    362, 
+       368,    371,    375,    379,    384,    388,    393,    398, 
+       404,    408,    413,    418,    424,    429,    435,    441, 
+       448,    449,    451,    453,    456,    458,    461,    464, 
+       468,    470,    473,    476,    480,    483,    487,    491, 
+       496,    498,    501,    504,    508,    511,    515,    519, 
+       524,    527,    531,    535,    540,    544,    549,    554, 
+       560,    562,    565,    568,    572,    575,    579,    583, 
+       588,    591,    595,    599,    604,    608,    613,    618, 
+       624,    627,    631,    635,    640,    644,    649,    654, 
+       660,    664,    669,    674,    680,    685,    691,    697, 
+       704,    706,    709,    712,    716,    719,    723,    727, 
+       732,    735,    739,    743,    748,    752,    757,    762, 
+       768,    771,    775,    779,    784,    788,    793,    798, 
+       804,    808,    813,    818,    824,    829,    835,    841, 
+       848,    851,    855,    859,    864,    868,    873,    878, 
+       884,    888,    893,    898,    904,    909,    915,    921, 
+       928,    932,    937,    942,    948,    953,    959,    965, 
+       972,    977,    983,    989,    996,   1002,   1009,   1016, 
+      1024,   1025,   1027,   1029,   1032,   1034,   1037,   1040, 
+      1044,   1046,   1049,   1052,   1056,   1059,   1063,   1067, 
+      1072,   1074,   1077,   1080,   1084,   1087,   1091,   1095, 
+      1100,   1103,   1107,   1111,   1116,   1120,   1125,   1130, 
+      1136,   1138,   1141,   1144,   1148,   1151,   1155,   1159, 
+      1164,   1167,   1171,   1175,   1180,   1184,   1189,   1194, 
+      1200,   1203,   1207,   1211,   1216,   1220,   1225,   1230, 
+      1236,   1240,   1245,   1250,   1256,   1261,   1267,   1273, 
+      1280,   1282,   1285,   1288,   1292,   1295,   1299,   1303, 
+      1308,   1311,   1315,   1319,   1324,   1328,   1333,   1338, 
+      1344,   1347,   1351,   1355,   1360,   1364,   1369,   1374, 
+      1380,   1384,   1389,   1394,   1400,   1405,   1411,   1417, 
+      1424,   1427,   1431,   1435,   1440,   1444,   1449,   1454, 
+      1460,   1464,   1469,   1474,   1480,   1485,   1491,   1497, 
+      1504,   1508,   1513,   1518,   1524,   1529,   1535,   1541, 
+      1548,   1553,   1559,   1565,   1572,   1578,   1585,   1592, 
+      1600,   1602,   1605,   1608,   1612,   1615,   1619,   1623, 
+      1628,   1631,   1635,   1639,   1644,   1648,   1653,   1658, 
+      1664,   1667,   1671,   1675,   1680,   1684,   1689,   1694, 
+      1700,   1704,   1709,   1714,   1720,   1725,   1731,   1737, 
+      1744,   1747,   1751,   1755,   1760,   1764,   1769,   1774, 
+      1780,   1784,   1789,   1794,   1800,   1805,   1811,   1817, 
+      1824,   1828,   1833,   1838,   1844,   1849,   1855,   1861, 
+      1868,   1873,   1879,   1885,   1892,   1898,   1905,   1912, 
+      1920,   1923,   1927,   1931,   1936,   1940,   1945,   1950, 
+      1956,   1960,   1965,   1970,   1976,   1981,   1987,   1993, 
+      2000,   2004,   2009,   2014,   2020,   2025,   2031,   2037, 
+      2044,   2049,   2055,   2061,   2068,   2074,   2081,   2088, 
+      2096,   2100,   2105,   2110,   2116,   2121,   2127,   2133, 
+      2140,   2145,   2151,   2157,   2164,   2170,   2177,   2184, 
+      2192,   2197,   2203,   2209,   2216,   2222,   2229,   2236, 
+      2244,   2250,   2257,   2264,   2272,   2279,   2287,   2295, 
+      2304,   2305,   2307,   2309,   2312,   2314,   2317,   2320, 
+      2324,   2326,   2329,   2332,   2336,   2339,   2343,   2347, 
+      2352,   2354,   2357,   2360,   2364,   2367,   2371,   2375, 
+      2380,   2383,   2387,   2391,   2396,   2400,   2405,   2410, 
+      2416,   2418,   2421,   2424,   2428,   2431,   2435,   2439, 
+      2444,   2447,   2451,   2455,   2460,   2464,   2469,   2474, 
+      2480,   2483,   2487,   2491,   2496,   2500,   2505,   2510, 
+      2516,   2520,   2525,   2530,   2536,   2541,   2547,   2553, 
+      2560,   2562,   2565,   2568,   2572,   2575,   2579,   2583, 
+      2588,   2591,   2595,   2599,   2604,   2608,   2613,   2618, 
+      2624,   2627,   2631,   2635,   2640,   2644,   2649,   2654, 
+      2660,   2664,   2669,   2674,   2680,   2685,   2691,   2697, 
+      2704,   2707,   2711,   2715,   2720,   2724,   2729,   2734, 
+      2740,   2744,   2749,   2754,   2760,   2765,   2771,   2777, 
+      2784,   2788,   2793,   2798,   2804,   2809,   2815,   2821, 
+      2828,   2833,   2839,   2845,   2852,   2858,   2865,   2872, 
+      2880,   2882,   2885,   2888,   2892,   2895,   2899,   2903, 
+      2908,   2911,   2915,   2919,   2924,   2928,   2933,   2938, 
+      2944,   2947,   2951,   2955,   2960,   2964,   2969,   2974, 
+      2980,   2984,   2989,   2994,   3000,   3005,   3011,   3017, 
+      3024,   3027,   3031,   3035,   3040,   3044,   3049,   3054, 
+      3060,   3064,   3069,   3074,   3080,   3085,   3091,   3097, 
+      3104,   3108,   3113,   3118,   3124,   3129,   3135,   3141, 
+      3148,   3153,   3159,   3165,   3172,   3178,   3185,   3192, 
+      3200,   3203,   3207,   3211,   3216,   3220,   3225,   3230, 
+      3236,   3240,   3245,   3250,   3256,   3261,   3267,   3273, 
+      3280,   3284,   3289,   3294,   3300,   3305,   3311,   3317, 
+      3324,   3329,   3335,   3341,   3348,   3354,   3361,   3368, 
+      3376,   3380,   3385,   3390,   3396,   3401,   3407,   3413, 
+      3420,   3425,   3431,   3437,   3444,   3450,   3457,   3464, 
+      3472,   3477,   3483,   3489,   3496,   3502,   3509,   3516, 
+      3524,   3530,   3537,   3544,   3552,   3559,   3567,   3575, 
+      3584,   3586,   3589,   3592,   3596,   3599,   3603,   3607, 
+      3612,   3615,   3619,   3623,   3628,   3632,   3637,   3642, 
+      3648,   3651,   3655,   3659,   3664,   3668,   3673,   3678, 
+      3684,   3688,   3693,   3698,   3704,   3709,   3715,   3721, 
+      3728,   3731,   3735,   3739,   3744,   3748,   3753,   3758, 
+      3764,   3768,   3773,   3778,   3784,   3789,   3795,   3801, 
+      3808,   3812,   3817,   3822,   3828,   3833,   3839,   3845, 
+      3852,   3857,   3863,   3869,   3876,   3882,   3889,   3896, 
+      3904,   3907,   3911,   3915,   3920,   3924,   3929,   3934, 
+      3940,   3944,   3949,   3954,   3960,   3965,   3971,   3977, 
+      3984,   3988,   3993,   3998,   4004,   4009,   4015,   4021, 
+      4028,   4033,   4039,   4045,   4052,   4058,   4065,   4072, 
+      4080,   4084,   4089,   4094,   4100,   4105,   4111,   4117, 
+      4124,   4129,   4135,   4141,   4148,   4154,   4161,   4168, 
+      4176,   4181,   4187,   4193,   4200,   4206,   4213,   4220, 
+      4228,   4234,   4241,   4248,   4256,   4263,   4271,   4279, 
+      4288,   4291,   4295,   4299,   4304,   4308,   4313,   4318, 
+      4324,   4328,   4333,   4338,   4344,   4349,   4355,   4361, 
+      4368,   4372,   4377,   4382,   4388,   4393,   4399,   4405, 
+      4412,   4417,   4423,   4429,   4436,   4442,   4449,   4456, 
+      4464,   4468,   4473,   4478,   4484,   4489,   4495,   4501, 
+      4508,   4513,   4519,   4525,   4532,   4538,   4545,   4552, 
+      4560,   4565,   4571,   4577,   4584,   4590,   4597,   4604, 
+      4612,   4618,   4625,   4632,   4640,   4647,   4655,   4663, 
+      4672,   4676,   4681,   4686,   4692,   4697,   4703,   4709, 
+      4716,   4721,   4727,   4733,   4740,   4746,   4753,   4760, 
+      4768,   4773,   4779,   4785,   4792,   4798,   4805,   4812, 
+      4820,   4826,   4833,   4840,   4848,   4855,   4863,   4871, 
+      4880,   4885,   4891,   4897,   4904,   4910,   4917,   4924, 
+      4932,   4938,   4945,   4952,   4960,   4967,   4975,   4983, 
+      4992,   4998,   5005,   5012,   5020,   5027,   5035,   5043, 
+      5052,   5059,   5067,   5075,   5084,   5092,   5101,   5110, 
+      5120,   5121,   5123,   5125,   5128,   5130,   5133,   5136, 
+      5140,   5142,   5145,   5148,   5152,   5155,   5159,   5163, 
+      5168,   5170,   5173,   5176,   5180,   5183,   5187,   5191, 
+      5196,   5199,   5203,   5207,   5212,   5216,   5221,   5226, 
+      5232,   5234,   5237,   5240,   5244,   5247,   5251,   5255, 
+      5260,   5263,   5267,   5271,   5276,   5280,   5285,   5290, 
+      5296,   5299,   5303,   5307,   5312,   5316,   5321,   5326, 
+      5332,   5336,   5341,   5346,   5352,   5357,   5363,   5369, 
+      5376,   5378,   5381,   5384,   5388,   5391,   5395,   5399, 
+      5404,   5407,   5411,   5415,   5420,   5424,   5429,   5434, 
+      5440,   5443,   5447,   5451,   5456,   5460,   5465,   5470, 
+      5476,   5480,   5485,   5490,   5496,   5501,   5507,   5513, 
+      5520,   5523,   5527,   5531,   5536,   5540,   5545,   5550, 
+      5556,   5560,   5565,   5570,   5576,   5581,   5587,   5593, 
+      5600,   5604,   5609,   5614,   5620,   5625,   5631,   5637, 
+      5644,   5649,   5655,   5661,   5668,   5674,   5681,   5688, 
+      5696,   5698,   5701,   5704,   5708,   5711,   5715,   5719, 
+      5724,   5727,   5731,   5735,   5740,   5744,   5749,   5754, 
+      5760,   5763,   5767,   5771,   5776,   5780,   5785,   5790, 
+      5796,   5800,   5805,   5810,   5816,   5821,   5827,   5833, 
+      5840,   5843,   5847,   5851,   5856,   5860,   5865,   5870, 
+      5876,   5880,   5885,   5890,   5896,   5901,   5907,   5913, 
+      5920,   5924,   5929,   5934,   5940,   5945,   5951,   5957, 
+      5964,   5969,   5975,   5981,   5988,   5994,   6001,   6008, 
+      6016,   6019,   6023,   6027,   6032,   6036,   6041,   6046, 
+      6052,   6056,   6061,   6066,   6072,   6077,   6083,   6089, 
+      6096,   6100,   6105,   6110,   6116,   6121,   6127,   6133, 
+      6140,   6145,   6151,   6157,   6164,   6170,   6177,   6184, 
+      6192,   6196,   6201,   6206,   6212,   6217,   6223,   6229, 
+      6236,   6241,   6247,   6253,   6260,   6266,   6273,   6280, 
+      6288,   6293,   6299,   6305,   6312,   6318,   6325,   6332, 
+      6340,   6346,   6353,   6360,   6368,   6375,   6383,   6391, 
+      6400,   6402,   6405,   6408,   6412,   6415,   6419,   6423, 
+      6428,   6431,   6435,   6439,   6444,   6448,   6453,   6458, 
+      6464,   6467,   6471,   6475,   6480,   6484,   6489,   6494, 
+      6500,   6504,   6509,   6514,   6520,   6525,   6531,   6537, 
+      6544,   6547,   6551,   6555,   6560,   6564,   6569,   6574, 
+      6580,   6584,   6589,   6594,   6600,   6605,   6611,   6617, 
+      6624,   6628,   6633,   6638,   6644,   6649,   6655,   6661, 
+      6668,   6673,   6679,   6685,   6692,   6698,   6705,   6712, 
+      6720,   6723,   6727,   6731,   6736,   6740,   6745,   6750, 
+      6756,   6760,   6765,   6770,   6776,   6781,   6787,   6793, 
+      6800,   6804,   6809,   6814,   6820,   6825,   6831,   6837, 
+      6844,   6849,   6855,   6861,   6868,   6874,   6881,   6888, 
+      6896,   6900,   6905,   6910,   6916,   6921,   6927,   6933, 
+      6940,   6945,   6951,   6957,   6964,   6970,   6977,   6984, 
+      6992,   6997,   7003,   7009,   7016,   7022,   7029,   7036, 
+      7044,   7050,   7057,   7064,   7072,   7079,   7087,   7095, 
+      7104,   7107,   7111,   7115,   7120,   7124,   7129,   7134, 
+      7140,   7144,   7149,   7154,   7160,   7165,   7171,   7177, 
+      7184,   7188,   7193,   7198,   7204,   7209,   7215,   7221, 
+      7228,   7233,   7239,   7245,   7252,   7258,   7265,   7272, 
+      7280,   7284,   7289,   7294,   7300,   7305,   7311,   7317, 
+      7324,   7329,   7335,   7341,   7348,   7354,   7361,   7368, 
+      7376,   7381,   7387,   7393,   7400,   7406,   7413,   7420, 
+      7428,   7434,   7441,   7448,   7456,   7463,   7471,   7479, 
+      7488,   7492,   7497,   7502,   7508,   7513,   7519,   7525, 
+      7532,   7537,   7543,   7549,   7556,   7562,   7569,   7576, 
+      7584,   7589,   7595,   7601,   7608,   7614,   7621,   7628, 
+      7636,   7642,   7649,   7656,   7664,   7671,   7679,   7687, 
+      7696,   7701,   7707,   7713,   7720,   7726,   7733,   7740, 
+      7748,   7754,   7761,   7768,   7776,   7783,   7791,   7799, 
+      7808,   7814,   7821,   7828,   7836,   7843,   7851,   7859, 
+      7868,   7875,   7883,   7891,   7900,   7908,   7917,   7926, 
+      7936,   7938,   7941,   7944,   7948,   7951,   7955,   7959, 
+      7964,   7967,   7971,   7975,   7980,   7984,   7989,   7994, 
+      8000,   8003,   8007,   8011,   8016,   8020,   8025,   8030, 
+      8036,   8040,   8045,   8050,   8056,   8061,   8067,   8073, 
+      8080,   8083,   8087,   8091,   8096,   8100,   8105,   8110, 
+      8116,   8120,   8125,   8130,   8136,   8141,   8147,   8153, 
+      8160,   8164,   8169,   8174,   8180,   8185,   8191,   8197, 
+      8204,   8209,   8215,   8221,   8228,   8234,   8241,   8248, 
+      8256,   8259,   8263,   8267,   8272,   8276,   8281,   8286, 
+      8292,   8296,   8301,   8306,   8312,   8317,   8323,   8329, 
+      8336,   8340,   8345,   8350,   8356,   8361,   8367,   8373, 
+      8380,   8385,   8391,   8397,   8404,   8410,   8417,   8424, 
+      8432,   8436,   8441,   8446,   8452,   8457,   8463,   8469, 
+      8476,   8481,   8487,   8493,   8500,   8506,   8513,   8520, 
+      8528,   8533,   8539,   8545,   8552,   8558,   8565,   8572, 
+      8580,   8586,   8593,   8600,   8608,   8615,   8623,   8631, 
+      8640,   8643,   8647,   8651,   8656,   8660,   8665,   8670, 
+      8676,   8680,   8685,   8690,   8696,   8701,   8707,   8713, 
+      8720,   8724,   8729,   8734,   8740,   8745,   8751,   8757, 
+      8764,   8769,   8775,   8781,   8788,   8794,   8801,   8808, 
+      8816,   8820,   8825,   8830,   8836,   8841,   8847,   8853, 
+      8860,   8865,   8871,   8877,   8884,   8890,   8897,   8904, 
+      8912,   8917,   8923,   8929,   8936,   8942,   8949,   8956, 
+      8964,   8970,   8977,   8984,   8992,   8999,   9007,   9015, 
+      9024,   9028,   9033,   9038,   9044,   9049,   9055,   9061, 
+      9068,   9073,   9079,   9085,   9092,   9098,   9105,   9112, 
+      9120,   9125,   9131,   9137,   9144,   9150,   9157,   9164, 
+      9172,   9178,   9185,   9192,   9200,   9207,   9215,   9223, 
+      9232,   9237,   9243,   9249,   9256,   9262,   9269,   9276, 
+      9284,   9290,   9297,   9304,   9312,   9319,   9327,   9335, 
+      9344,   9350,   9357,   9364,   9372,   9379,   9387,   9395, 
+      9404,   9411,   9419,   9427,   9436,   9444,   9453,   9462, 
+      9472,   9475,   9479,   9483,   9488,   9492,   9497,   9502, 
+      9508,   9512,   9517,   9522,   9528,   9533,   9539,   9545, 
+      9552,   9556,   9561,   9566,   9572,   9577,   9583,   9589, 
+      9596,   9601,   9607,   9613,   9620,   9626,   9633,   9640, 
+      9648,   9652,   9657,   9662,   9668,   9673,   9679,   9685, 
+      9692,   9697,   9703,   9709,   9716,   9722,   9729,   9736, 
+      9744,   9749,   9755,   9761,   9768,   9774,   9781,   9788, 
+      9796,   9802,   9809,   9816,   9824,   9831,   9839,   9847, 
+      9856,   9860,   9865,   9870,   9876,   9881,   9887,   9893, 
+      9900,   9905,   9911,   9917,   9924,   9930,   9937,   9944, 
+      9952,   9957,   9963,   9969,   9976,   9982,   9989,   9996, 
+     10004,  10010,  10017,  10024,  10032,  10039,  10047,  10055, 
+     10064,  10069,  10075,  10081,  10088,  10094,  10101,  10108, 
+     10116,  10122,  10129,  10136,  10144,  10151,  10159,  10167, 
+     10176,  10182,  10189,  10196,  10204,  10211,  10219,  10227, 
+     10236,  10243,  10251,  10259,  10268,  10276,  10285,  10294, 
+     10304,  10308,  10313,  10318,  10324,  10329,  10335,  10341, 
+     10348,  10353,  10359,  10365,  10372,  10378,  10385,  10392, 
+     10400,  10405,  10411,  10417,  10424,  10430,  10437,  10444, 
+     10452,  10458,  10465,  10472,  10480,  10487,  10495,  10503, 
+     10512,  10517,  10523,  10529,  10536,  10542,  10549,  10556, 
+     10564,  10570,  10577,  10584,  10592,  10599,  10607,  10615, 
+     10624,  10630,  10637,  10644,  10652,  10659,  10667,  10675, 
+     10684,  10691,  10699,  10707,  10716,  10724,  10733,  10742, 
+     10752,  10757,  10763,  10769,  10776,  10782,  10789,  10796, 
+     10804,  10810,  10817,  10824,  10832,  10839,  10847,  10855, 
+     10864,  10870,  10877,  10884,  10892,  10899,  10907,  10915, 
+     10924,  10931,  10939,  10947,  10956,  10964,  10973,  10982, 
+     10992,  10998,  11005,  11012,  11020,  11027,  11035,  11043, 
+     11052,  11059,  11067,  11075,  11084,  11092,  11101,  11110, 
+     11120,  11127,  11135,  11143,  11152,  11160,  11169,  11178, 
+     11188,  11196,  11205,  11214,  11224,  11233,  11243,  11253, 
+     11264,  11265,  11267,  11269,  11272,  11274,  11277,  11280, 
+     11284,  11286,  11289,  11292,  11296,  11299,  11303,  11307, 
+     11312,  11314,  11317,  11320,  11324,  11327,  11331,  11335, 
+     11340,  11343,  11347,  11351,  11356,  11360,  11365,  11370, 
+     11376,  11378,  11381,  11384,  11388,  11391,  11395,  11399, 
+     11404,  11407,  11411,  11415,  11420,  11424,  11429,  11434, 
+     11440,  11443,  11447,  11451,  11456,  11460,  11465,  11470, 
+     11476,  11480,  11485,  11490,  11496,  11501,  11507,  11513, 
+     11520,  11522,  11525,  11528,  11532,  11535,  11539,  11543, 
+     11548,  11551,  11555,  11559,  11564,  11568,  11573,  11578, 
+     11584,  11587,  11591,  11595,  11600,  11604,  11609,  11614, 
+     11620,  11624,  11629,  11634,  11640,  11645,  11651,  11657, 
+     11664,  11667,  11671,  11675,  11680,  11684,  11689,  11694, 
+     11700,  11704,  11709,  11714,  11720,  11725,  11731,  11737, 
+     11744,  11748,  11753,  11758,  11764,  11769,  11775,  11781, 
+     11788,  11793,  11799,  11805,  11812,  11818,  11825,  11832, 
+     11840,  11842,  11845,  11848,  11852,  11855,  11859,  11863, 
+     11868,  11871,  11875,  11879,  11884,  11888,  11893,  11898, 
+     11904,  11907,  11911,  11915,  11920,  11924,  11929,  11934, 
+     11940,  11944,  11949,  11954,  11960,  11965,  11971,  11977, 
+     11984,  11987,  11991,  11995,  12000,  12004,  12009,  12014, 
+     12020,  12024,  12029,  12034,  12040,  12045,  12051,  12057, 
+     12064,  12068,  12073,  12078,  12084,  12089,  12095,  12101, 
+     12108,  12113,  12119,  12125,  12132,  12138,  12145,  12152, 
+     12160,  12163,  12167,  12171,  12176,  12180,  12185,  12190, 
+     12196,  12200,  12205,  12210,  12216,  12221,  12227,  12233, 
+     12240,  12244,  12249,  12254,  12260,  12265,  12271,  12277, 
+     12284,  12289,  12295,  12301,  12308,  12314,  12321,  12328, 
+     12336,  12340,  12345,  12350,  12356,  12361,  12367,  12373, 
+     12380,  12385,  12391,  12397,  12404,  12410,  12417,  12424, 
+     12432,  12437,  12443,  12449,  12456,  12462,  12469,  12476, 
+     12484,  12490,  12497,  12504,  12512,  12519,  12527,  12535, 
+     12544,  12546,  12549,  12552,  12556,  12559,  12563,  12567, 
+     12572,  12575,  12579,  12583,  12588,  12592,  12597,  12602, 
+     12608,  12611,  12615,  12619,  12624,  12628,  12633,  12638, 
+     12644,  12648,  12653,  12658,  12664,  12669,  12675,  12681, 
+     12688,  12691,  12695,  12699,  12704,  12708,  12713,  12718, 
+     12724,  12728,  12733,  12738,  12744,  12749,  12755,  12761, 
+     12768,  12772,  12777,  12782,  12788,  12793,  12799,  12805, 
+     12812,  12817,  12823,  12829,  12836,  12842,  12849,  12856, 
+     12864,  12867,  12871,  12875,  12880,  12884,  12889,  12894, 
+     12900,  12904,  12909,  12914,  12920,  12925,  12931,  12937, 
+     12944,  12948,  12953,  12958,  12964,  12969,  12975,  12981, 
+     12988,  12993,  12999,  13005,  13012,  13018,  13025,  13032, 
+     13040,  13044,  13049,  13054,  13060,  13065,  13071,  13077, 
+     13084,  13089,  13095,  13101,  13108,  13114,  13121,  13128, 
+     13136,  13141,  13147,  13153,  13160,  13166,  13173,  13180, 
+     13188,  13194,  13201,  13208,  13216,  13223,  13231,  13239, 
+     13248,  13251,  13255,  13259,  13264,  13268,  13273,  13278, 
+     13284,  13288,  13293,  13298,  13304,  13309,  13315,  13321, 
+     13328,  13332,  13337,  13342,  13348,  13353,  13359,  13365, 
+     13372,  13377,  13383,  13389,  13396,  13402,  13409,  13416, 
+     13424,  13428,  13433,  13438,  13444,  13449,  13455,  13461, 
+     13468,  13473,  13479,  13485,  13492,  13498,  13505,  13512, 
+     13520,  13525,  13531,  13537,  13544,  13550,  13557,  13564, 
+     13572,  13578,  13585,  13592,  13600,  13607,  13615,  13623, 
+     13632,  13636,  13641,  13646,  13652,  13657,  13663,  13669, 
+     13676,  13681,  13687,  13693,  13700,  13706,  13713,  13720, 
+     13728,  13733,  13739,  13745,  13752,  13758,  13765,  13772, 
+     13780,  13786,  13793,  13800,  13808,  13815,  13823,  13831, 
+     13840,  13845,  13851,  13857,  13864,  13870,  13877,  13884, 
+     13892,  13898,  13905,  13912,  13920,  13927,  13935,  13943, 
+     13952,  13958,  13965,  13972,  13980,  13987,  13995,  14003, 
+     14012,  14019,  14027,  14035,  14044,  14052,  14061,  14070, 
+     14080,  14082,  14085,  14088,  14092,  14095,  14099,  14103, 
+     14108,  14111,  14115,  14119,  14124,  14128,  14133,  14138, 
+     14144,  14147,  14151,  14155,  14160,  14164,  14169,  14174, 
+     14180,  14184,  14189,  14194,  14200,  14205,  14211,  14217, 
+     14224,  14227,  14231,  14235,  14240,  14244,  14249,  14254, 
+     14260,  14264,  14269,  14274,  14280,  14285,  14291,  14297, 
+     14304,  14308,  14313,  14318,  14324,  14329,  14335,  14341, 
+     14348,  14353,  14359,  14365,  14372,  14378,  14385,  14392, 
+     14400,  14403,  14407,  14411,  14416,  14420,  14425,  14430, 
+     14436,  14440,  14445,  14450,  14456,  14461,  14467,  14473, 
+     14480,  14484,  14489,  14494,  14500,  14505,  14511,  14517, 
+     14524,  14529,  14535,  14541,  14548,  14554,  14561,  14568, 
+     14576,  14580,  14585,  14590,  14596,  14601,  14607,  14613, 
+     14620,  14625,  14631,  14637,  14644,  14650,  14657,  14664, 
+     14672,  14677,  14683,  14689,  14696,  14702,  14709,  14716, 
+     14724,  14730,  14737,  14744,  14752,  14759,  14767,  14775, 
+     14784,  14787,  14791,  14795,  14800,  14804,  14809,  14814, 
+     14820,  14824,  14829,  14834,  14840,  14845,  14851,  14857, 
+     14864,  14868,  14873,  14878,  14884,  14889,  14895,  14901, 
+     14908,  14913,  14919,  14925,  14932,  14938,  14945,  14952, 
+     14960,  14964,  14969,  14974,  14980,  14985,  14991,  14997, 
+     15004,  15009,  15015,  15021,  15028,  15034,  15041,  15048, 
+     15056,  15061,  15067,  15073,  15080,  15086,  15093,  15100, 
+     15108,  15114,  15121,  15128,  15136,  15143,  15151,  15159, 
+     15168,  15172,  15177,  15182,  15188,  15193,  15199,  15205, 
+     15212,  15217,  15223,  15229,  15236,  15242,  15249,  15256, 
+     15264,  15269,  15275,  15281,  15288,  15294,  15301,  15308, 
+     15316,  15322,  15329,  15336,  15344,  15351,  15359,  15367, 
+     15376,  15381,  15387,  15393,  15400,  15406,  15413,  15420, 
+     15428,  15434,  15441,  15448,  15456,  15463,  15471,  15479, 
+     15488,  15494,  15501,  15508,  15516,  15523,  15531,  15539, 
+     15548,  15555,  15563,  15571,  15580,  15588,  15597,  15606, 
+     15616,  15619,  15623,  15627,  15632,  15636,  15641,  15646, 
+     15652,  15656,  15661,  15666,  15672,  15677,  15683,  15689, 
+     15696,  15700,  15705,  15710,  15716,  15721,  15727,  15733, 
+     15740,  15745,  15751,  15757,  15764,  15770,  15777,  15784, 
+     15792,  15796,  15801,  15806,  15812,  15817,  15823,  15829, 
+     15836,  15841,  15847,  15853,  15860,  15866,  15873,  15880, 
+     15888,  15893,  15899,  15905,  15912,  15918,  15925,  15932, 
+     15940,  15946,  15953,  15960,  15968,  15975,  15983,  15991, 
+     16000,  16004,  16009,  16014,  16020,  16025,  16031,  16037, 
+     16044,  16049,  16055,  16061,  16068,  16074,  16081,  16088, 
+     16096,  16101,  16107,  16113,  16120,  16126,  16133,  16140, 
+     16148,  16154,  16161,  16168,  16176,  16183,  16191,  16199, 
+     16208,  16213,  16219,  16225,  16232,  16238,  16245,  16252, 
+     16260,  16266,  16273,  16280,  16288,  16295,  16303,  16311, 
+     16320,  16326,  16333,  16340,  16348,  16355,  16363,  16371, 
+     16380,  16387,  16395,  16403,  16412,  16420,  16429,  16438, 
+     16448,  16452,  16457,  16462,  16468,  16473,  16479,  16485, 
+     16492,  16497,  16503,  16509,  16516,  16522,  16529,  16536, 
+     16544,  16549,  16555,  16561,  16568,  16574,  16581,  16588, 
+     16596,  16602,  16609,  16616,  16624,  16631,  16639,  16647, 
+     16656,  16661,  16667,  16673,  16680,  16686,  16693,  16700, 
+     16708,  16714,  16721,  16728,  16736,  16743,  16751,  16759, 
+     16768,  16774,  16781,  16788,  16796,  16803,  16811,  16819, 
+     16828,  16835,  16843,  16851,  16860,  16868,  16877,  16886, 
+     16896,  16901,  16907,  16913,  16920,  16926,  16933,  16940, 
+     16948,  16954,  16961,  16968,  16976,  16983,  16991,  16999, 
+     17008,  17014,  17021,  17028,  17036,  17043,  17051,  17059, 
+     17068,  17075,  17083,  17091,  17100,  17108,  17117,  17126, 
+     17136,  17142,  17149,  17156,  17164,  17171,  17179,  17187, 
+     17196,  17203,  17211,  17219,  17228,  17236,  17245,  17254, 
+     17264,  17271,  17279,  17287,  17296,  17304,  17313,  17322, 
+     17332,  17340,  17349,  17358,  17368,  17377,  17387,  17397, 
+     17408,  17410,  17413,  17416,  17420,  17423,  17427,  17431, 
+     17436,  17439,  17443,  17447,  17452,  17456,  17461,  17466, 
+     17472,  17475,  17479,  17483,  17488,  17492,  17497,  17502, 
+     17508,  17512,  17517,  17522,  17528,  17533,  17539,  17545, 
+     17552,  17555,  17559,  17563,  17568,  17572,  17577,  17582, 
+     17588,  17592,  17597,  17602,  17608,  17613,  17619,  17625, 
+     17632,  17636,  17641,  17646,  17652,  17657,  17663,  17669, 
+     17676,  17681,  17687,  17693,  17700,  17706,  17713,  17720, 
+     17728,  17731,  17735,  17739,  17744,  17748,  17753,  17758, 
+     17764,  17768,  17773,  17778,  17784,  17789,  17795,  17801, 
+     17808,  17812,  17817,  17822,  17828,  17833,  17839,  17845, 
+     17852,  17857,  17863,  17869,  17876,  17882,  17889,  17896, 
+     17904,  17908,  17913,  17918,  17924,  17929,  17935,  17941, 
+     17948,  17953,  17959,  17965,  17972,  17978,  17985,  17992, 
+     18000,  18005,  18011,  18017,  18024,  18030,  18037,  18044, 
+     18052,  18058,  18065,  18072,  18080,  18087,  18095,  18103, 
+     18112,  18115,  18119,  18123,  18128,  18132,  18137,  18142, 
+     18148,  18152,  18157,  18162,  18168,  18173,  18179,  18185, 
+     18192,  18196,  18201,  18206,  18212,  18217,  18223,  18229, 
+     18236,  18241,  18247,  18253,  18260,  18266,  18273,  18280, 
+     18288,  18292,  18297,  18302,  18308,  18313,  18319,  18325, 
+     18332,  18337,  18343,  18349,  18356,  18362,  18369,  18376, 
+     18384,  18389,  18395,  18401,  18408,  18414,  18421,  18428, 
+     18436,  18442,  18449,  18456,  18464,  18471,  18479,  18487, 
+     18496,  18500,  18505,  18510,  18516,  18521,  18527,  18533, 
+     18540,  18545,  18551,  18557,  18564,  18570,  18577,  18584, 
+     18592,  18597,  18603,  18609,  18616,  18622,  18629,  18636, 
+     18644,  18650,  18657,  18664,  18672,  18679,  18687,  18695, 
+     18704,  18709,  18715,  18721,  18728,  18734,  18741,  18748, 
+     18756,  18762,  18769,  18776,  18784,  18791,  18799,  18807, 
+     18816,  18822,  18829,  18836,  18844,  18851,  18859,  18867, 
+     18876,  18883,  18891,  18899,  18908,  18916,  18925,  18934, 
+     18944,  18947,  18951,  18955,  18960,  18964,  18969,  18974, 
+     18980,  18984,  18989,  18994,  19000,  19005,  19011,  19017, 
+     19024,  19028,  19033,  19038,  19044,  19049,  19055,  19061, 
+     19068,  19073,  19079,  19085,  19092,  19098,  19105,  19112, 
+     19120,  19124,  19129,  19134,  19140,  19145,  19151,  19157, 
+     19164,  19169,  19175,  19181,  19188,  19194,  19201,  19208, 
+     19216,  19221,  19227,  19233,  19240,  19246,  19253,  19260, 
+     19268,  19274,  19281,  19288,  19296,  19303,  19311,  19319, 
+     19328,  19332,  19337,  19342,  19348,  19353,  19359,  19365, 
+     19372,  19377,  19383,  19389,  19396,  19402,  19409,  19416, 
+     19424,  19429,  19435,  19441,  19448,  19454,  19461,  19468, 
+     19476,  19482,  19489,  19496,  19504,  19511,  19519,  19527, 
+     19536,  19541,  19547,  19553,  19560,  19566,  19573,  19580, 
+     19588,  19594,  19601,  19608,  19616,  19623,  19631,  19639, 
+     19648,  19654,  19661,  19668,  19676,  19683,  19691,  19699, 
+     19708,  19715,  19723,  19731,  19740,  19748,  19757,  19766, 
+     19776,  19780,  19785,  19790,  19796,  19801,  19807,  19813, 
+     19820,  19825,  19831,  19837,  19844,  19850,  19857,  19864, 
+     19872,  19877,  19883,  19889,  19896,  19902,  19909,  19916, 
+     19924,  19930,  19937,  19944,  19952,  19959,  19967,  19975, 
+     19984,  19989,  19995,  20001,  20008,  20014,  20021,  20028, 
+     20036,  20042,  20049,  20056,  20064,  20071,  20079,  20087, 
+     20096,  20102,  20109,  20116,  20124,  20131,  20139,  20147, 
+     20156,  20163,  20171,  20179,  20188,  20196,  20205,  20214, 
+     20224,  20229,  20235,  20241,  20248,  20254,  20261,  20268, 
+     20276,  20282,  20289,  20296,  20304,  20311,  20319,  20327, 
+     20336,  20342,  20349,  20356,  20364,  20371,  20379,  20387, 
+     20396,  20403,  20411,  20419,  20428,  20436,  20445,  20454, 
+     20464,  20470,  20477,  20484,  20492,  20499,  20507,  20515, 
+     20524,  20531,  20539,  20547,  20556,  20564,  20573,  20582, 
+     20592,  20599,  20607,  20615,  20624,  20632,  20641,  20650, 
+     20660,  20668,  20677,  20686,  20696,  20705,  20715,  20725, 
+     20736,  20739,  20743,  20747,  20752,  20756,  20761,  20766, 
+     20772,  20776,  20781,  20786,  20792,  20797,  20803,  20809, 
+     20816,  20820,  20825,  20830,  20836,  20841,  20847,  20853, 
+     20860,  20865,  20871,  20877,  20884,  20890,  20897,  20904, 
+     20912,  20916,  20921,  20926,  20932,  20937,  20943,  20949, 
+     20956,  20961,  20967,  20973,  20980,  20986,  20993,  21000, 
+     21008,  21013,  21019,  21025,  21032,  21038,  21045,  21052, 
+     21060,  21066,  21073,  21080,  21088,  21095,  21103,  21111, 
+     21120,  21124,  21129,  21134,  21140,  21145,  21151,  21157, 
+     21164,  21169,  21175,  21181,  21188,  21194,  21201,  21208, 
+     21216,  21221,  21227,  21233,  21240,  21246,  21253,  21260, 
+     21268,  21274,  21281,  21288,  21296,  21303,  21311,  21319, 
+     21328,  21333,  21339,  21345,  21352,  21358,  21365,  21372, 
+     21380,  21386,  21393,  21400,  21408,  21415,  21423,  21431, 
+     21440,  21446,  21453,  21460,  21468,  21475,  21483,  21491, 
+     21500,  21507,  21515,  21523,  21532,  21540,  21549,  21558, 
+     21568,  21572,  21577,  21582,  21588,  21593,  21599,  21605, 
+     21612,  21617,  21623,  21629,  21636,  21642,  21649,  21656, 
+     21664,  21669,  21675,  21681,  21688,  21694,  21701,  21708, 
+     21716,  21722,  21729,  21736,  21744,  21751,  21759,  21767, 
+     21776,  21781,  21787,  21793,  21800,  21806,  21813,  21820, 
+     21828,  21834,  21841,  21848,  21856,  21863,  21871,  21879, 
+     21888,  21894,  21901,  21908,  21916,  21923,  21931,  21939, 
+     21948,  21955,  21963,  21971,  21980,  21988,  21997,  22006, 
+     22016,  22021,  22027,  22033,  22040,  22046,  22053,  22060, 
+     22068,  22074,  22081,  22088,  22096,  22103,  22111,  22119, 
+     22128,  22134,  22141,  22148,  22156,  22163,  22171,  22179, 
+     22188,  22195,  22203,  22211,  22220,  22228,  22237,  22246, 
+     22256,  22262,  22269,  22276,  22284,  22291,  22299,  22307, 
+     22316,  22323,  22331,  22339,  22348,  22356,  22365,  22374, 
+     22384,  22391,  22399,  22407,  22416,  22424,  22433,  22442, 
+     22452,  22460,  22469,  22478,  22488,  22497,  22507,  22517, 
+     22528,  22532,  22537,  22542,  22548,  22553,  22559,  22565, 
+     22572,  22577,  22583,  22589,  22596,  22602,  22609,  22616, 
+     22624,  22629,  22635,  22641,  22648,  22654,  22661,  22668, 
+     22676,  22682,  22689,  22696,  22704,  22711,  22719,  22727, 
+     22736,  22741,  22747,  22753,  22760,  22766,  22773,  22780, 
+     22788,  22794,  22801,  22808,  22816,  22823,  22831,  22839, 
+     22848,  22854,  22861,  22868,  22876,  22883,  22891,  22899, 
+     22908,  22915,  22923,  22931,  22940,  22948,  22957,  22966, 
+     22976,  22981,  22987,  22993,  23000,  23006,  23013,  23020, 
+     23028,  23034,  23041,  23048,  23056,  23063,  23071,  23079, 
+     23088,  23094,  23101,  23108,  23116,  23123,  23131,  23139, 
+     23148,  23155,  23163,  23171,  23180,  23188,  23197,  23206, 
+     23216,  23222,  23229,  23236,  23244,  23251,  23259,  23267, 
+     23276,  23283,  23291,  23299,  23308,  23316,  23325,  23334, 
+     23344,  23351,  23359,  23367,  23376,  23384,  23393,  23402, 
+     23412,  23420,  23429,  23438,  23448,  23457,  23467,  23477, 
+     23488,  23493,  23499,  23505,  23512,  23518,  23525,  23532, 
+     23540,  23546,  23553,  23560,  23568,  23575,  23583,  23591, 
+     23600,  23606,  23613,  23620,  23628,  23635,  23643,  23651, 
+     23660,  23667,  23675,  23683,  23692,  23700,  23709,  23718, 
+     23728,  23734,  23741,  23748,  23756,  23763,  23771,  23779, 
+     23788,  23795,  23803,  23811,  23820,  23828,  23837,  23846, 
+     23856,  23863,  23871,  23879,  23888,  23896,  23905,  23914, 
+     23924,  23932,  23941,  23950,  23960,  23969,  23979,  23989, 
+     24000,  24006,  24013,  24020,  24028,  24035,  24043,  24051, 
+     24060,  24067,  24075,  24083,  24092,  24100,  24109,  24118, 
+     24128,  24135,  24143,  24151,  24160,  24168,  24177,  24186, 
+     24196,  24204,  24213,  24222,  24232,  24241,  24251,  24261, 
+     24272,  24279,  24287,  24295,  24304,  24312,  24321,  24330, 
+     24340,  24348,  24357,  24366,  24376,  24385,  24395,  24405, 
+     24416,  24424,  24433,  24442,  24452,  24461,  24471,  24481, 
+     24492,  24501,  24511,  24521,  24532,  24542,  24553,  24564, 
+     24576,  24577,  24579,  24581,  24584,  24586,  24589,  24592, 
+     24596,  24598,  24601,  24604,  24608,  24611,  24615,  24619, 
+     24624,  24626,  24629,  24632,  24636,  24639,  24643,  24647, 
+     24652,  24655,  24659,  24663,  24668,  24672,  24677,  24682, 
+     24688,  24690,  24693,  24696,  24700,  24703,  24707,  24711, 
+     24716,  24719,  24723,  24727,  24732,  24736,  24741,  24746, 
+     24752,  24755,  24759,  24763,  24768,  24772,  24777,  24782, 
+     24788,  24792,  24797,  24802,  24808,  24813,  24819,  24825, 
+     24832,  24834,  24837,  24840,  24844,  24847,  24851,  24855, 
+     24860,  24863,  24867,  24871,  24876,  24880,  24885,  24890, 
+     24896,  24899,  24903,  24907,  24912,  24916,  24921,  24926, 
+     24932,  24936,  24941,  24946,  24952,  24957,  24963,  24969, 
+     24976,  24979,  24983,  24987,  24992,  24996,  25001,  25006, 
+     25012,  25016,  25021,  25026,  25032,  25037,  25043,  25049, 
+     25056,  25060,  25065,  25070,  25076,  25081,  25087,  25093, 
+     25100,  25105,  25111,  25117,  25124,  25130,  25137,  25144, 
+     25152,  25154,  25157,  25160,  25164,  25167,  25171,  25175, 
+     25180,  25183,  25187,  25191,  25196,  25200,  25205,  25210, 
+     25216,  25219,  25223,  25227,  25232,  25236,  25241,  25246, 
+     25252,  25256,  25261,  25266,  25272,  25277,  25283,  25289, 
+     25296,  25299,  25303,  25307,  25312,  25316,  25321,  25326, 
+     25332,  25336,  25341,  25346,  25352,  25357,  25363,  25369, 
+     25376,  25380,  25385,  25390,  25396,  25401,  25407,  25413, 
+     25420,  25425,  25431,  25437,  25444,  25450,  25457,  25464, 
+     25472,  25475,  25479,  25483,  25488,  25492,  25497,  25502, 
+     25508,  25512,  25517,  25522,  25528,  25533,  25539,  25545, 
+     25552,  25556,  25561,  25566,  25572,  25577,  25583,  25589, 
+     25596,  25601,  25607,  25613,  25620,  25626,  25633,  25640, 
+     25648,  25652,  25657,  25662,  25668,  25673,  25679,  25685, 
+     25692,  25697,  25703,  25709,  25716,  25722,  25729,  25736, 
+     25744,  25749,  25755,  25761,  25768,  25774,  25781,  25788, 
+     25796,  25802,  25809,  25816,  25824,  25831,  25839,  25847, 
+     25856,  25858,  25861,  25864,  25868,  25871,  25875,  25879, 
+     25884,  25887,  25891,  25895,  25900,  25904,  25909,  25914, 
+     25920,  25923,  25927,  25931,  25936,  25940,  25945,  25950, 
+     25956,  25960,  25965,  25970,  25976,  25981,  25987,  25993, 
+     26000,  26003,  26007,  26011,  26016,  26020,  26025,  26030, 
+     26036,  26040,  26045,  26050,  26056,  26061,  26067,  26073, 
+     26080,  26084,  26089,  26094,  26100,  26105,  26111,  26117, 
+     26124,  26129,  26135,  26141,  26148,  26154,  26161,  26168, 
+     26176,  26179,  26183,  26187,  26192,  26196,  26201,  26206, 
+     26212,  26216,  26221,  26226,  26232,  26237,  26243,  26249, 
+     26256,  26260,  26265,  26270,  26276,  26281,  26287,  26293, 
+     26300,  26305,  26311,  26317,  26324,  26330,  26337,  26344, 
+     26352,  26356,  26361,  26366,  26372,  26377,  26383,  26389, 
+     26396,  26401,  26407,  26413,  26420,  26426,  26433,  26440, 
+     26448,  26453,  26459,  26465,  26472,  26478,  26485,  26492, 
+     26500,  26506,  26513,  26520,  26528,  26535,  26543,  26551, 
+     26560,  26563,  26567,  26571,  26576,  26580,  26585,  26590, 
+     26596,  26600,  26605,  26610,  26616,  26621,  26627,  26633, 
+     26640,  26644,  26649,  26654,  26660,  26665,  26671,  26677, 
+     26684,  26689,  26695,  26701,  26708,  26714,  26721,  26728, 
+     26736,  26740,  26745,  26750,  26756,  26761,  26767,  26773, 
+     26780,  26785,  26791,  26797,  26804,  26810,  26817,  26824, 
+     26832,  26837,  26843,  26849,  26856,  26862,  26869,  26876, 
+     26884,  26890,  26897,  26904,  26912,  26919,  26927,  26935, 
+     26944,  26948,  26953,  26958,  26964,  26969,  26975,  26981, 
+     26988,  26993,  26999,  27005,  27012,  27018,  27025,  27032, 
+     27040,  27045,  27051,  27057,  27064,  27070,  27077,  27084, 
+     27092,  27098,  27105,  27112,  27120,  27127,  27135,  27143, 
+     27152,  27157,  27163,  27169,  27176,  27182,  27189,  27196, 
+     27204,  27210,  27217,  27224,  27232,  27239,  27247,  27255, 
+     27264,  27270,  27277,  27284,  27292,  27299,  27307,  27315, 
+     27324,  27331,  27339,  27347,  27356,  27364,  27373,  27382, 
+     27392,  27394,  27397,  27400,  27404,  27407,  27411,  27415, 
+     27420,  27423,  27427,  27431,  27436,  27440,  27445,  27450, 
+     27456,  27459,  27463,  27467,  27472,  27476,  27481,  27486, 
+     27492,  27496,  27501,  27506,  27512,  27517,  27523,  27529, 
+     27536,  27539,  27543,  27547,  27552,  27556,  27561,  27566, 
+     27572,  27576,  27581,  27586,  27592,  27597,  27603,  27609, 
+     27616,  27620,  27625,  27630,  27636,  27641,  27647,  27653, 
+     27660,  27665,  27671,  27677,  27684,  27690,  27697,  27704, 
+     27712,  27715,  27719,  27723,  27728,  27732,  27737,  27742, 
+     27748,  27752,  27757,  27762,  27768,  27773,  27779,  27785, 
+     27792,  27796,  27801,  27806,  27812,  27817,  27823,  27829, 
+     27836,  27841,  27847,  27853,  27860,  27866,  27873,  27880, 
+     27888,  27892,  27897,  27902,  27908,  27913,  27919,  27925, 
+     27932,  27937,  27943,  27949,  27956,  27962,  27969,  27976, 
+     27984,  27989,  27995,  28001,  28008,  28014,  28021,  28028, 
+     28036,  28042,  28049,  28056,  28064,  28071,  28079,  28087, 
+     28096,  28099,  28103,  28107,  28112,  28116,  28121,  28126, 
+     28132,  28136,  28141,  28146,  28152,  28157,  28163,  28169, 
+     28176,  28180,  28185,  28190,  28196,  28201,  28207,  28213, 
+     28220,  28225,  28231,  28237,  28244,  28250,  28257,  28264, 
+     28272,  28276,  28281,  28286,  28292,  28297,  28303,  28309, 
+     28316,  28321,  28327,  28333,  28340,  28346,  28353,  28360, 
+     28368,  28373,  28379,  28385,  28392,  28398,  28405,  28412, 
+     28420,  28426,  28433,  28440,  28448,  28455,  28463,  28471, 
+     28480,  28484,  28489,  28494,  28500,  28505,  28511,  28517, 
+     28524,  28529,  28535,  28541,  28548,  28554,  28561,  28568, 
+     28576,  28581,  28587,  28593,  28600,  28606,  28613,  28620, 
+     28628,  28634,  28641,  28648,  28656,  28663,  28671,  28679, 
+     28688,  28693,  28699,  28705,  28712,  28718,  28725,  28732, 
+     28740,  28746,  28753,  28760,  28768,  28775,  28783,  28791, 
+     28800,  28806,  28813,  28820,  28828,  28835,  28843,  28851, 
+     28860,  28867,  28875,  28883,  28892,  28900,  28909,  28918, 
+     28928,  28931,  28935,  28939,  28944,  28948,  28953,  28958, 
+     28964,  28968,  28973,  28978,  28984,  28989,  28995,  29001, 
+     29008,  29012,  29017,  29022,  29028,  29033,  29039,  29045, 
+     29052,  29057,  29063,  29069,  29076,  29082,  29089,  29096, 
+     29104,  29108,  29113,  29118,  29124,  29129,  29135,  29141, 
+     29148,  29153,  29159,  29165,  29172,  29178,  29185,  29192, 
+     29200,  29205,  29211,  29217,  29224,  29230,  29237,  29244, 
+     29252,  29258,  29265,  29272,  29280,  29287,  29295,  29303, 
+     29312,  29316,  29321,  29326,  29332,  29337,  29343,  29349, 
+     29356,  29361,  29367,  29373,  29380,  29386,  29393,  29400, 
+     29408,  29413,  29419,  29425,  29432,  29438,  29445,  29452, 
+     29460,  29466,  29473,  29480,  29488,  29495,  29503,  29511, 
+     29520,  29525,  29531,  29537,  29544,  29550,  29557,  29564, 
+     29572,  29578,  29585,  29592,  29600,  29607,  29615,  29623, 
+     29632,  29638,  29645,  29652,  29660,  29667,  29675,  29683, 
+     29692,  29699,  29707,  29715,  29724,  29732,  29741,  29750, 
+     29760,  29764,  29769,  29774,  29780,  29785,  29791,  29797, 
+     29804,  29809,  29815,  29821,  29828,  29834,  29841,  29848, 
+     29856,  29861,  29867,  29873,  29880,  29886,  29893,  29900, 
+     29908,  29914,  29921,  29928,  29936,  29943,  29951,  29959, 
+     29968,  29973,  29979,  29985,  29992,  29998,  30005,  30012, 
+     30020,  30026,  30033,  30040,  30048,  30055,  30063,  30071, 
+     30080,  30086,  30093,  30100,  30108,  30115,  30123,  30131, 
+     30140,  30147,  30155,  30163,  30172,  30180,  30189,  30198, 
+     30208,  30213,  30219,  30225,  30232,  30238,  30245,  30252, 
+     30260,  30266,  30273,  30280,  30288,  30295,  30303,  30311, 
+     30320,  30326,  30333,  30340,  30348,  30355,  30363,  30371, 
+     30380,  30387,  30395,  30403,  30412,  30420,  30429,  30438, 
+     30448,  30454,  30461,  30468,  30476,  30483,  30491,  30499, 
+     30508,  30515,  30523,  30531,  30540,  30548,  30557,  30566, 
+     30576,  30583,  30591,  30599,  30608,  30616,  30625,  30634, 
+     30644,  30652,  30661,  30670,  30680,  30689,  30699,  30709, 
+     30720,  30722,  30725,  30728,  30732,  30735,  30739,  30743, 
+     30748,  30751,  30755,  30759,  30764,  30768,  30773,  30778, 
+     30784,  30787,  30791,  30795,  30800,  30804,  30809,  30814, 
+     30820,  30824,  30829,  30834,  30840,  30845,  30851,  30857, 
+     30864,  30867,  30871,  30875,  30880,  30884,  30889,  30894, 
+     30900,  30904,  30909,  30914,  30920,  30925,  30931,  30937, 
+     30944,  30948,  30953,  30958,  30964,  30969,  30975,  30981, 
+     30988,  30993,  30999,  31005,  31012,  31018,  31025,  31032, 
+     31040,  31043,  31047,  31051,  31056,  31060,  31065,  31070, 
+     31076,  31080,  31085,  31090,  31096,  31101,  31107,  31113, 
+     31120,  31124,  31129,  31134,  31140,  31145,  31151,  31157, 
+     31164,  31169,  31175,  31181,  31188,  31194,  31201,  31208, 
+     31216,  31220,  31225,  31230,  31236,  31241,  31247,  31253, 
+     31260,  31265,  31271,  31277,  31284,  31290,  31297,  31304, 
+     31312,  31317,  31323,  31329,  31336,  31342,  31349,  31356, 
+     31364,  31370,  31377,  31384,  31392,  31399,  31407,  31415, 
+     31424,  31427,  31431,  31435,  31440,  31444,  31449,  31454, 
+     31460,  31464,  31469,  31474,  31480,  31485,  31491,  31497, 
+     31504,  31508,  31513,  31518,  31524,  31529,  31535,  31541, 
+     31548,  31553,  31559,  31565,  31572,  31578,  31585,  31592, 
+     31600,  31604,  31609,  31614,  31620,  31625,  31631,  31637, 
+     31644,  31649,  31655,  31661,  31668,  31674,  31681,  31688, 
+     31696,  31701,  31707,  31713,  31720,  31726,  31733,  31740, 
+     31748,  31754,  31761,  31768,  31776,  31783,  31791,  31799, 
+     31808,  31812,  31817,  31822,  31828,  31833,  31839,  31845, 
+     31852,  31857,  31863,  31869,  31876,  31882,  31889,  31896, 
+     31904,  31909,  31915,  31921,  31928,  31934,  31941,  31948, 
+     31956,  31962,  31969,  31976,  31984,  31991,  31999,  32007, 
+     32016,  32021,  32027,  32033,  32040,  32046,  32053,  32060, 
+     32068,  32074,  32081,  32088,  32096,  32103,  32111,  32119, 
+     32128,  32134,  32141,  32148,  32156,  32163,  32171,  32179, 
+     32188,  32195,  32203,  32211,  32220,  32228,  32237,  32246, 
+     32256,  32259,  32263,  32267,  32272,  32276,  32281,  32286, 
+     32292,  32296,  32301,  32306,  32312,  32317,  32323,  32329, 
+     32336,  32340,  32345,  32350,  32356,  32361,  32367,  32373, 
+     32380,  32385,  32391,  32397,  32404,  32410,  32417,  32424, 
+     32432,  32436,  32441,  32446,  32452,  32457,  32463,  32469, 
+     32476,  32481,  32487,  32493,  32500,  32506,  32513,  32520, 
+     32528,  32533,  32539,  32545,  32552,  32558,  32565,  32572, 
+     32580,  32586,  32593,  32600,  32608,  32615,  32623,  32631, 
+     32640,  32644,  32649,  32654,  32660,  32665,  32671,  32677, 
+     32684,  32689,  32695,  32701,  32708,  32714,  32721,  32728, 
+     32736,  32741,  32747,  32753,  32760,  32766,  32773,  32780, 
+     32788,  32794,  32801,  32808,  32816,  32823,  32831,  32839, 
+     32848,  32853,  32859,  32865,  32872,  32878,  32885,  32892, 
+     32900,  32906,  32913,  32920,  32928,  32935,  32943,  32951, 
+     32960,  32966,  32973,  32980,  32988,  32995,  33003,  33011, 
+     33020,  33027,  33035,  33043,  33052,  33060,  33069,  33078, 
+     33088,  33092,  33097,  33102,  33108,  33113,  33119,  33125, 
+     33132,  33137,  33143,  33149,  33156,  33162,  33169,  33176, 
+     33184,  33189,  33195,  33201,  33208,  33214,  33221,  33228, 
+     33236,  33242,  33249,  33256,  33264,  33271,  33279,  33287, 
+     33296,  33301,  33307,  33313,  33320,  33326,  33333,  33340, 
+     33348,  33354,  33361,  33368,  33376,  33383,  33391,  33399, 
+     33408,  33414,  33421,  33428,  33436,  33443,  33451,  33459, 
+     33468,  33475,  33483,  33491,  33500,  33508,  33517,  33526, 
+     33536,  33541,  33547,  33553,  33560,  33566,  33573,  33580, 
+     33588,  33594,  33601,  33608,  33616,  33623,  33631,  33639, 
+     33648,  33654,  33661,  33668,  33676,  33683,  33691,  33699, 
+     33708,  33715,  33723,  33731,  33740,  33748,  33757,  33766, 
+     33776,  33782,  33789,  33796,  33804,  33811,  33819,  33827, 
+     33836,  33843,  33851,  33859,  33868,  33876,  33885,  33894, 
+     33904,  33911,  33919,  33927,  33936,  33944,  33953,  33962, 
+     33972,  33980,  33989,  33998,  34008,  34017,  34027,  34037, 
+     34048,  34051,  34055,  34059,  34064,  34068,  34073,  34078, 
+     34084,  34088,  34093,  34098,  34104,  34109,  34115,  34121, 
+     34128,  34132,  34137,  34142,  34148,  34153,  34159,  34165, 
+     34172,  34177,  34183,  34189,  34196,  34202,  34209,  34216, 
+     34224,  34228,  34233,  34238,  34244,  34249,  34255,  34261, 
+     34268,  34273,  34279,  34285,  34292,  34298,  34305,  34312, 
+     34320,  34325,  34331,  34337,  34344,  34350,  34357,  34364, 
+     34372,  34378,  34385,  34392,  34400,  34407,  34415,  34423, 
+     34432,  34436,  34441,  34446,  34452,  34457,  34463,  34469, 
+     34476,  34481,  34487,  34493,  34500,  34506,  34513,  34520, 
+     34528,  34533,  34539,  34545,  34552,  34558,  34565,  34572, 
+     34580,  34586,  34593,  34600,  34608,  34615,  34623,  34631, 
+     34640,  34645,  34651,  34657,  34664,  34670,  34677,  34684, 
+     34692,  34698,  34705,  34712,  34720,  34727,  34735,  34743, 
+     34752,  34758,  34765,  34772,  34780,  34787,  34795,  34803, 
+     34812,  34819,  34827,  34835,  34844,  34852,  34861,  34870, 
+     34880,  34884,  34889,  34894,  34900,  34905,  34911,  34917, 
+     34924,  34929,  34935,  34941,  34948,  34954,  34961,  34968, 
+     34976,  34981,  34987,  34993,  35000,  35006,  35013,  35020, 
+     35028,  35034,  35041,  35048,  35056,  35063,  35071,  35079, 
+     35088,  35093,  35099,  35105,  35112,  35118,  35125,  35132, 
+     35140,  35146,  35153,  35160,  35168,  35175,  35183,  35191, 
+     35200,  35206,  35213,  35220,  35228,  35235,  35243,  35251, 
+     35260,  35267,  35275,  35283,  35292,  35300,  35309,  35318, 
+     35328,  35333,  35339,  35345,  35352,  35358,  35365,  35372, 
+     35380,  35386,  35393,  35400,  35408,  35415,  35423,  35431, 
+     35440,  35446,  35453,  35460,  35468,  35475,  35483,  35491, 
+     35500,  35507,  35515,  35523,  35532,  35540,  35549,  35558, 
+     35568,  35574,  35581,  35588,  35596,  35603,  35611,  35619, 
+     35628,  35635,  35643,  35651,  35660,  35668,  35677,  35686, 
+     35696,  35703,  35711,  35719,  35728,  35736,  35745,  35754, 
+     35764,  35772,  35781,  35790,  35800,  35809,  35819,  35829, 
+     35840,  35844,  35849,  35854,  35860,  35865,  35871,  35877, 
+     35884,  35889,  35895,  35901,  35908,  35914,  35921,  35928, 
+     35936,  35941,  35947,  35953,  35960,  35966,  35973,  35980, 
+     35988,  35994,  36001,  36008,  36016,  36023,  36031,  36039, 
+     36048,  36053,  36059,  36065,  36072,  36078,  36085,  36092, 
+     36100,  36106,  36113,  36120,  36128,  36135,  36143,  36151, 
+     36160,  36166,  36173,  36180,  36188,  36195,  36203,  36211, 
+     36220,  36227,  36235,  36243,  36252,  36260,  36269,  36278, 
+     36288,  36293,  36299,  36305,  36312,  36318,  36325,  36332, 
+     36340,  36346,  36353,  36360,  36368,  36375,  36383,  36391, 
+     36400,  36406,  36413,  36420,  36428,  36435,  36443,  36451, 
+     36460,  36467,  36475,  36483,  36492,  36500,  36509,  36518, 
+     36528,  36534,  36541,  36548,  36556,  36563,  36571,  36579, 
+     36588,  36595,  36603,  36611,  36620,  36628,  36637,  36646, 
+     36656,  36663,  36671,  36679,  36688,  36696,  36705,  36714, 
+     36724,  36732,  36741,  36750,  36760,  36769,  36779,  36789, 
+     36800,  36805,  36811,  36817,  36824,  36830,  36837,  36844, 
+     36852,  36858,  36865,  36872,  36880,  36887,  36895,  36903, 
+     36912,  36918,  36925,  36932,  36940,  36947,  36955,  36963, 
+     36972,  36979,  36987,  36995,  37004,  37012,  37021,  37030, 
+     37040,  37046,  37053,  37060,  37068,  37075,  37083,  37091, 
+     37100,  37107,  37115,  37123,  37132,  37140,  37149,  37158, 
+     37168,  37175,  37183,  37191,  37200,  37208,  37217,  37226, 
+     37236,  37244,  37253,  37262,  37272,  37281,  37291,  37301, 
+     37312,  37318,  37325,  37332,  37340,  37347,  37355,  37363, 
+     37372,  37379,  37387,  37395,  37404,  37412,  37421,  37430, 
+     37440,  37447,  37455,  37463,  37472,  37480,  37489,  37498, 
+     37508,  37516,  37525,  37534,  37544,  37553,  37563,  37573, 
+     37584,  37591,  37599,  37607,  37616,  37624,  37633,  37642, 
+     37652,  37660,  37669,  37678,  37688,  37697,  37707,  37717, 
+     37728,  37736,  37745,  37754,  37764,  37773,  37783,  37793, 
+     37804,  37813,  37823,  37833,  37844,  37854,  37865,  37876, 
+     37888,  37890,  37893,  37896,  37900,  37903,  37907,  37911, 
+     37916,  37919,  37923,  37927,  37932,  37936,  37941,  37946, 
+     37952,  37955,  37959,  37963,  37968,  37972,  37977,  37982, 
+     37988,  37992,  37997,  38002,  38008,  38013,  38019,  38025, 
+     38032,  38035,  38039,  38043,  38048,  38052,  38057,  38062, 
+     38068,  38072,  38077,  38082,  38088,  38093,  38099,  38105, 
+     38112,  38116,  38121,  38126,  38132,  38137,  38143,  38149, 
+     38156,  38161,  38167,  38173,  38180,  38186,  38193,  38200, 
+     38208,  38211,  38215,  38219,  38224,  38228,  38233,  38238, 
+     38244,  38248,  38253,  38258,  38264,  38269,  38275,  38281, 
+     38288,  38292,  38297,  38302,  38308,  38313,  38319,  38325, 
+     38332,  38337,  38343,  38349,  38356,  38362,  38369,  38376, 
+     38384,  38388,  38393,  38398,  38404,  38409,  38415,  38421, 
+     38428,  38433,  38439,  38445,  38452,  38458,  38465,  38472, 
+     38480,  38485,  38491,  38497,  38504,  38510,  38517,  38524, 
+     38532,  38538,  38545,  38552,  38560,  38567,  38575,  38583, 
+     38592,  38595,  38599,  38603,  38608,  38612,  38617,  38622, 
+     38628,  38632,  38637,  38642,  38648,  38653,  38659,  38665, 
+     38672,  38676,  38681,  38686,  38692,  38697,  38703,  38709, 
+     38716,  38721,  38727,  38733,  38740,  38746,  38753,  38760, 
+     38768,  38772,  38777,  38782,  38788,  38793,  38799,  38805, 
+     38812,  38817,  38823,  38829,  38836,  38842,  38849,  38856, 
+     38864,  38869,  38875,  38881,  38888,  38894,  38901,  38908, 
+     38916,  38922,  38929,  38936,  38944,  38951,  38959,  38967, 
+     38976,  38980,  38985,  38990,  38996,  39001,  39007,  39013, 
+     39020,  39025,  39031,  39037,  39044,  39050,  39057,  39064, 
+     39072,  39077,  39083,  39089,  39096,  39102,  39109,  39116, 
+     39124,  39130,  39137,  39144,  39152,  39159,  39167,  39175, 
+     39184,  39189,  39195,  39201,  39208,  39214,  39221,  39228, 
+     39236,  39242,  39249,  39256,  39264,  39271,  39279,  39287, 
+     39296,  39302,  39309,  39316,  39324,  39331,  39339,  39347, 
+     39356,  39363,  39371,  39379,  39388,  39396,  39405,  39414, 
+     39424,  39427,  39431,  39435,  39440,  39444,  39449,  39454, 
+     39460,  39464,  39469,  39474,  39480,  39485,  39491,  39497, 
+     39504,  39508,  39513,  39518,  39524,  39529,  39535,  39541, 
+     39548,  39553,  39559,  39565,  39572,  39578,  39585,  39592, 
+     39600,  39604,  39609,  39614,  39620,  39625,  39631,  39637, 
+     39644,  39649,  39655,  39661,  39668,  39674,  39681,  39688, 
+     39696,  39701,  39707,  39713,  39720,  39726,  39733,  39740, 
+     39748,  39754,  39761,  39768,  39776,  39783,  39791,  39799, 
+     39808,  39812,  39817,  39822,  39828,  39833,  39839,  39845, 
+     39852,  39857,  39863,  39869,  39876,  39882,  39889,  39896, 
+     39904,  39909,  39915,  39921,  39928,  39934,  39941,  39948, 
+     39956,  39962,  39969,  39976,  39984,  39991,  39999,  40007, 
+     40016,  40021,  40027,  40033,  40040,  40046,  40053,  40060, 
+     40068,  40074,  40081,  40088,  40096,  40103,  40111,  40119, 
+     40128,  40134,  40141,  40148,  40156,  40163,  40171,  40179, 
+     40188,  40195,  40203,  40211,  40220,  40228,  40237,  40246, 
+     40256,  40260,  40265,  40270,  40276,  40281,  40287,  40293, 
+     40300,  40305,  40311,  40317,  40324,  40330,  40337,  40344, 
+     40352,  40357,  40363,  40369,  40376,  40382,  40389,  40396, 
+     40404,  40410,  40417,  40424,  40432,  40439,  40447,  40455, 
+     40464,  40469,  40475,  40481,  40488,  40494,  40501,  40508, 
+     40516,  40522,  40529,  40536,  40544,  40551,  40559,  40567, 
+     40576,  40582,  40589,  40596,  40604,  40611,  40619,  40627, 
+     40636,  40643,  40651,  40659,  40668,  40676,  40685,  40694, 
+     40704,  40709,  40715,  40721,  40728,  40734,  40741,  40748, 
+     40756,  40762,  40769,  40776,  40784,  40791,  40799,  40807, 
+     40816,  40822,  40829,  40836,  40844,  40851,  40859,  40867, 
+     40876,  40883,  40891,  40899,  40908,  40916,  40925,  40934, 
+     40944,  40950,  40957,  40964,  40972,  40979,  40987,  40995, 
+     41004,  41011,  41019,  41027,  41036,  41044,  41053,  41062, 
+     41072,  41079,  41087,  41095,  41104,  41112,  41121,  41130, 
+     41140,  41148,  41157,  41166,  41176,  41185,  41195,  41205, 
+     41216,  41219,  41223,  41227,  41232,  41236,  41241,  41246, 
+     41252,  41256,  41261,  41266,  41272,  41277,  41283,  41289, 
+     41296,  41300,  41305,  41310,  41316,  41321,  41327,  41333, 
+     41340,  41345,  41351,  41357,  41364,  41370,  41377,  41384, 
+     41392,  41396,  41401,  41406,  41412,  41417,  41423,  41429, 
+     41436,  41441,  41447,  41453,  41460,  41466,  41473,  41480, 
+     41488,  41493,  41499,  41505,  41512,  41518,  41525,  41532, 
+     41540,  41546,  41553,  41560,  41568,  41575,  41583,  41591, 
+     41600,  41604,  41609,  41614,  41620,  41625,  41631,  41637, 
+     41644,  41649,  41655,  41661,  41668,  41674,  41681,  41688, 
+     41696,  41701,  41707,  41713,  41720,  41726,  41733,  41740, 
+     41748,  41754,  41761,  41768,  41776,  41783,  41791,  41799, 
+     41808,  41813,  41819,  41825,  41832,  41838,  41845,  41852, 
+     41860,  41866,  41873,  41880,  41888,  41895,  41903,  41911, 
+     41920,  41926,  41933,  41940,  41948,  41955,  41963,  41971, 
+     41980,  41987,  41995,  42003,  42012,  42020,  42029,  42038, 
+     42048,  42052,  42057,  42062,  42068,  42073,  42079,  42085, 
+     42092,  42097,  42103,  42109,  42116,  42122,  42129,  42136, 
+     42144,  42149,  42155,  42161,  42168,  42174,  42181,  42188, 
+     42196,  42202,  42209,  42216,  42224,  42231,  42239,  42247, 
+     42256,  42261,  42267,  42273,  42280,  42286,  42293,  42300, 
+     42308,  42314,  42321,  42328,  42336,  42343,  42351,  42359, 
+     42368,  42374,  42381,  42388,  42396,  42403,  42411,  42419, 
+     42428,  42435,  42443,  42451,  42460,  42468,  42477,  42486, 
+     42496,  42501,  42507,  42513,  42520,  42526,  42533,  42540, 
+     42548,  42554,  42561,  42568,  42576,  42583,  42591,  42599, 
+     42608,  42614,  42621,  42628,  42636,  42643,  42651,  42659, 
+     42668,  42675,  42683,  42691,  42700,  42708,  42717,  42726, 
+     42736,  42742,  42749,  42756,  42764,  42771,  42779,  42787, 
+     42796,  42803,  42811,  42819,  42828,  42836,  42845,  42854, 
+     42864,  42871,  42879,  42887,  42896,  42904,  42913,  42922, 
+     42932,  42940,  42949,  42958,  42968,  42977,  42987,  42997, 
+     43008,  43012,  43017,  43022,  43028,  43033,  43039,  43045, 
+     43052,  43057,  43063,  43069,  43076,  43082,  43089,  43096, 
+     43104,  43109,  43115,  43121,  43128,  43134,  43141,  43148, 
+     43156,  43162,  43169,  43176,  43184,  43191,  43199,  43207, 
+     43216,  43221,  43227,  43233,  43240,  43246,  43253,  43260, 
+     43268,  43274,  43281,  43288,  43296,  43303,  43311,  43319, 
+     43328,  43334,  43341,  43348,  43356,  43363,  43371,  43379, 
+     43388,  43395,  43403,  43411,  43420,  43428,  43437,  43446, 
+     43456,  43461,  43467,  43473,  43480,  43486,  43493,  43500, 
+     43508,  43514,  43521,  43528,  43536,  43543,  43551,  43559, 
+     43568,  43574,  43581,  43588,  43596,  43603,  43611,  43619, 
+     43628,  43635,  43643,  43651,  43660,  43668,  43677,  43686, 
+     43696,  43702,  43709,  43716,  43724,  43731,  43739,  43747, 
+     43756,  43763,  43771,  43779,  43788,  43796,  43805,  43814, 
+     43824,  43831,  43839,  43847,  43856,  43864,  43873,  43882, 
+     43892,  43900,  43909,  43918,  43928,  43937,  43947,  43957, 
+     43968,  43973,  43979,  43985,  43992,  43998,  44005,  44012, 
+     44020,  44026,  44033,  44040,  44048,  44055,  44063,  44071, 
+     44080,  44086,  44093,  44100,  44108,  44115,  44123,  44131, 
+     44140,  44147,  44155,  44163,  44172,  44180,  44189,  44198, 
+     44208,  44214,  44221,  44228,  44236,  44243,  44251,  44259, 
+     44268,  44275,  44283,  44291,  44300,  44308,  44317,  44326, 
+     44336,  44343,  44351,  44359,  44368,  44376,  44385,  44394, 
+     44404,  44412,  44421,  44430,  44440,  44449,  44459,  44469, 
+     44480,  44486,  44493,  44500,  44508,  44515,  44523,  44531, 
+     44540,  44547,  44555,  44563,  44572,  44580,  44589,  44598, 
+     44608,  44615,  44623,  44631,  44640,  44648,  44657,  44666, 
+     44676,  44684,  44693,  44702,  44712,  44721,  44731,  44741, 
+     44752,  44759,  44767,  44775,  44784,  44792,  44801,  44810, 
+     44820,  44828,  44837,  44846,  44856,  44865,  44875,  44885, 
+     44896,  44904,  44913,  44922,  44932,  44941,  44951,  44961, 
+     44972,  44981,  44991,  45001,  45012,  45022,  45033,  45044, 
+     45056,  45059,  45063,  45067,  45072,  45076,  45081,  45086, 
+     45092,  45096,  45101,  45106,  45112,  45117,  45123,  45129, 
+     45136,  45140,  45145,  45150,  45156,  45161,  45167,  45173, 
+     45180,  45185,  45191,  45197,  45204,  45210,  45217,  45224, 
+     45232,  45236,  45241,  45246,  45252,  45257,  45263,  45269, 
+     45276,  45281,  45287,  45293,  45300,  45306,  45313,  45320, 
+     45328,  45333,  45339,  45345,  45352,  45358,  45365,  45372, 
+     45380,  45386,  45393,  45400,  45408,  45415,  45423,  45431, 
+     45440,  45444,  45449,  45454,  45460,  45465,  45471,  45477, 
+     45484,  45489,  45495,  45501,  45508,  45514,  45521,  45528, 
+     45536,  45541,  45547,  45553,  45560,  45566,  45573,  45580, 
+     45588,  45594,  45601,  45608,  45616,  45623,  45631,  45639, 
+     45648,  45653,  45659,  45665,  45672,  45678,  45685,  45692, 
+     45700,  45706,  45713,  45720,  45728,  45735,  45743,  45751, 
+     45760,  45766,  45773,  45780,  45788,  45795,  45803,  45811, 
+     45820,  45827,  45835,  45843,  45852,  45860,  45869,  45878, 
+     45888,  45892,  45897,  45902,  45908,  45913,  45919,  45925, 
+     45932,  45937,  45943,  45949,  45956,  45962,  45969,  45976, 
+     45984,  45989,  45995,  46001,  46008,  46014,  46021,  46028, 
+     46036,  46042,  46049,  46056,  46064,  46071,  46079,  46087, 
+     46096,  46101,  46107,  46113,  46120,  46126,  46133,  46140, 
+     46148,  46154,  46161,  46168,  46176,  46183,  46191,  46199, 
+     46208,  46214,  46221,  46228,  46236,  46243,  46251,  46259, 
+     46268,  46275,  46283,  46291,  46300,  46308,  46317,  46326, 
+     46336,  46341,  46347,  46353,  46360,  46366,  46373,  46380, 
+     46388,  46394,  46401,  46408,  46416,  46423,  46431,  46439, 
+     46448,  46454,  46461,  46468,  46476,  46483,  46491,  46499, 
+     46508,  46515,  46523,  46531,  46540,  46548,  46557,  46566, 
+     46576,  46582,  46589,  46596,  46604,  46611,  46619,  46627, 
+     46636,  46643,  46651,  46659,  46668,  46676,  46685,  46694, 
+     46704,  46711,  46719,  46727,  46736,  46744,  46753,  46762, 
+     46772,  46780,  46789,  46798,  46808,  46817,  46827,  46837, 
+     46848,  46852,  46857,  46862,  46868,  46873,  46879,  46885, 
+     46892,  46897,  46903,  46909,  46916,  46922,  46929,  46936, 
+     46944,  46949,  46955,  46961,  46968,  46974,  46981,  46988, 
+     46996,  47002,  47009,  47016,  47024,  47031,  47039,  47047, 
+     47056,  47061,  47067,  47073,  47080,  47086,  47093,  47100, 
+     47108,  47114,  47121,  47128,  47136,  47143,  47151,  47159, 
+     47168,  47174,  47181,  47188,  47196,  47203,  47211,  47219, 
+     47228,  47235,  47243,  47251,  47260,  47268,  47277,  47286, 
+     47296,  47301,  47307,  47313,  47320,  47326,  47333,  47340, 
+     47348,  47354,  47361,  47368,  47376,  47383,  47391,  47399, 
+     47408,  47414,  47421,  47428,  47436,  47443,  47451,  47459, 
+     47468,  47475,  47483,  47491,  47500,  47508,  47517,  47526, 
+     47536,  47542,  47549,  47556,  47564,  47571,  47579,  47587, 
+     47596,  47603,  47611,  47619,  47628,  47636,  47645,  47654, 
+     47664,  47671,  47679,  47687,  47696,  47704,  47713,  47722, 
+     47732,  47740,  47749,  47758,  47768,  47777,  47787,  47797, 
+     47808,  47813,  47819,  47825,  47832,  47838,  47845,  47852, 
+     47860,  47866,  47873,  47880,  47888,  47895,  47903,  47911, 
+     47920,  47926,  47933,  47940,  47948,  47955,  47963,  47971, 
+     47980,  47987,  47995,  48003,  48012,  48020,  48029,  48038, 
+     48048,  48054,  48061,  48068,  48076,  48083,  48091,  48099, 
+     48108,  48115,  48123,  48131,  48140,  48148,  48157,  48166, 
+     48176,  48183,  48191,  48199,  48208,  48216,  48225,  48234, 
+     48244,  48252,  48261,  48270,  48280,  48289,  48299,  48309, 
+     48320,  48326,  48333,  48340,  48348,  48355,  48363,  48371, 
+     48380,  48387,  48395,  48403,  48412,  48420,  48429,  48438, 
+     48448,  48455,  48463,  48471,  48480,  48488,  48497,  48506, 
+     48516,  48524,  48533,  48542,  48552,  48561,  48571,  48581, 
+     48592,  48599,  48607,  48615,  48624,  48632,  48641,  48650, 
+     48660,  48668,  48677,  48686,  48696,  48705,  48715,  48725, 
+     48736,  48744,  48753,  48762,  48772,  48781,  48791,  48801, 
+     48812,  48821,  48831,  48841,  48852,  48862,  48873,  48884, 
+     48896,  48900,  48905,  48910,  48916,  48921,  48927,  48933, 
+     48940,  48945,  48951,  48957,  48964,  48970,  48977,  48984, 
+     48992,  48997,  49003,  49009,  49016,  49022,  49029,  49036, 
+     49044,  49050,  49057,  49064,  49072,  49079,  49087,  49095, 
+     49104,  49109,  49115,  49121,  49128,  49134,  49141,  49148, 
+     49156,  49162,  49169,  49176,  49184,  49191,  49199,  49207, 
+     49216,  49222,  49229,  49236,  49244,  49251,  49259,  49267, 
+     49276,  49283,  49291,  49299,  49308,  49316,  49325,  49334, 
+     49344,  49349,  49355,  49361,  49368,  49374,  49381,  49388, 
+     49396,  49402,  49409,  49416,  49424,  49431,  49439,  49447, 
+     49456,  49462,  49469,  49476,  49484,  49491,  49499,  49507, 
+     49516,  49523,  49531,  49539,  49548,  49556,  49565,  49574, 
+     49584,  49590,  49597,  49604,  49612,  49619,  49627,  49635, 
+     49644,  49651,  49659,  49667,  49676,  49684,  49693,  49702, 
+     49712,  49719,  49727,  49735,  49744,  49752,  49761,  49770, 
+     49780,  49788,  49797,  49806,  49816,  49825,  49835,  49845, 
+     49856,  49861,  49867,  49873,  49880,  49886,  49893,  49900, 
+     49908,  49914,  49921,  49928,  49936,  49943,  49951,  49959, 
+     49968,  49974,  49981,  49988,  49996,  50003,  50011,  50019, 
+     50028,  50035,  50043,  50051,  50060,  50068,  50077,  50086, 
+     50096,  50102,  50109,  50116,  50124,  50131,  50139,  50147, 
+     50156,  50163,  50171,  50179,  50188,  50196,  50205,  50214, 
+     50224,  50231,  50239,  50247,  50256,  50264,  50273,  50282, 
+     50292,  50300,  50309,  50318,  50328,  50337,  50347,  50357, 
+     50368,  50374,  50381,  50388,  50396,  50403,  50411,  50419, 
+     50428,  50435,  50443,  50451,  50460,  50468,  50477,  50486, 
+     50496,  50503,  50511,  50519,  50528,  50536,  50545,  50554, 
+     50564,  50572,  50581,  50590,  50600,  50609,  50619,  50629, 
+     50640,  50647,  50655,  50663,  50672,  50680,  50689,  50698, 
+     50708,  50716,  50725,  50734,  50744,  50753,  50763,  50773, 
+     50784,  50792,  50801,  50810,  50820,  50829,  50839,  50849, 
+     50860,  50869,  50879,  50889,  50900,  50910,  50921,  50932, 
+     50944,  50949,  50955,  50961,  50968,  50974,  50981,  50988, 
+     50996,  51002,  51009,  51016,  51024,  51031,  51039,  51047, 
+     51056,  51062,  51069,  51076,  51084,  51091,  51099,  51107, 
+     51116,  51123,  51131,  51139,  51148,  51156,  51165,  51174, 
+     51184,  51190,  51197,  51204,  51212,  51219,  51227,  51235, 
+     51244,  51251,  51259,  51267,  51276,  51284,  51293,  51302, 
+     51312,  51319,  51327,  51335,  51344,  51352,  51361,  51370, 
+     51380,  51388,  51397,  51406,  51416,  51425,  51435,  51445, 
+     51456,  51462,  51469,  51476,  51484,  51491,  51499,  51507, 
+     51516,  51523,  51531,  51539,  51548,  51556,  51565,  51574, 
+     51584,  51591,  51599,  51607,  51616,  51624,  51633,  51642, 
+     51652,  51660,  51669,  51678,  51688,  51697,  51707,  51717, 
+     51728,  51735,  51743,  51751,  51760,  51768,  51777,  51786, 
+     51796,  51804,  51813,  51822,  51832,  51841,  51851,  51861, 
+     51872,  51880,  51889,  51898,  51908,  51917,  51927,  51937, 
+     51948,  51957,  51967,  51977,  51988,  51998,  52009,  52020, 
+     52032,  52038,  52045,  52052,  52060,  52067,  52075,  52083, 
+     52092,  52099,  52107,  52115,  52124,  52132,  52141,  52150, 
+     52160,  52167,  52175,  52183,  52192,  52200,  52209,  52218, 
+     52228,  52236,  52245,  52254,  52264,  52273,  52283,  52293, 
+     52304,  52311,  52319,  52327,  52336,  52344,  52353,  52362, 
+     52372,  52380,  52389,  52398,  52408,  52417,  52427,  52437, 
+     52448,  52456,  52465,  52474,  52484,  52493,  52503,  52513, 
+     52524,  52533,  52543,  52553,  52564,  52574,  52585,  52596, 
+     52608,  52615,  52623,  52631,  52640,  52648,  52657,  52666, 
+     52676,  52684,  52693,  52702,  52712,  52721,  52731,  52741, 
+     52752,  52760,  52769,  52778,  52788,  52797,  52807,  52817, 
+     52828,  52837,  52847,  52857,  52868,  52878,  52889,  52900, 
+     52912,  52920,  52929,  52938,  52948,  52957,  52967,  52977, 
+     52988,  52997,  53007,  53017,  53028,  53038,  53049,  53060, 
+     53072,  53081,  53091,  53101,  53112,  53122,  53133,  53144, 
+     53156,  53166,  53177,  53188,  53200,  53211,  53223,  53235, 
+     53248,  53249,  53251,  53253,  53256,  53258,  53261,  53264, 
+     53268,  53270,  53273,  53276,  53280,  53283,  53287,  53291, 
+     53296,  53298,  53301,  53304,  53308,  53311,  53315,  53319, 
+     53324,  53327,  53331,  53335,  53340,  53344,  53349,  53354, 
+     53360,  53362,  53365,  53368,  53372,  53375,  53379,  53383, 
+     53388,  53391,  53395,  53399,  53404,  53408,  53413,  53418, 
+     53424,  53427,  53431,  53435,  53440,  53444,  53449,  53454, 
+     53460,  53464,  53469,  53474,  53480,  53485,  53491,  53497, 
+     53504,  53506,  53509,  53512,  53516,  53519,  53523,  53527, 
+     53532,  53535,  53539,  53543,  53548,  53552,  53557,  53562, 
+     53568,  53571,  53575,  53579,  53584,  53588,  53593,  53598, 
+     53604,  53608,  53613,  53618,  53624,  53629,  53635,  53641, 
+     53648,  53651,  53655,  53659,  53664,  53668,  53673,  53678, 
+     53684,  53688,  53693,  53698,  53704,  53709,  53715,  53721, 
+     53728,  53732,  53737,  53742,  53748,  53753,  53759,  53765, 
+     53772,  53777,  53783,  53789,  53796,  53802,  53809,  53816, 
+     53824,  53826,  53829,  53832,  53836,  53839,  53843,  53847, 
+     53852,  53855,  53859,  53863,  53868,  53872,  53877,  53882, 
+     53888,  53891,  53895,  53899,  53904,  53908,  53913,  53918, 
+     53924,  53928,  53933,  53938,  53944,  53949,  53955,  53961, 
+     53968,  53971,  53975,  53979,  53984,  53988,  53993,  53998, 
+     54004,  54008,  54013,  54018,  54024,  54029,  54035,  54041, 
+     54048,  54052,  54057,  54062,  54068,  54073,  54079,  54085, 
+     54092,  54097,  54103,  54109,  54116,  54122,  54129,  54136, 
+     54144,  54147,  54151,  54155,  54160,  54164,  54169,  54174, 
+     54180,  54184,  54189,  54194,  54200,  54205,  54211,  54217, 
+     54224,  54228,  54233,  54238,  54244,  54249,  54255,  54261, 
+     54268,  54273,  54279,  54285,  54292,  54298,  54305,  54312, 
+     54320,  54324,  54329,  54334,  54340,  54345,  54351,  54357, 
+     54364,  54369,  54375,  54381,  54388,  54394,  54401,  54408, 
+     54416,  54421,  54427,  54433,  54440,  54446,  54453,  54460, 
+     54468,  54474,  54481,  54488,  54496,  54503,  54511,  54519, 
+     54528,  54530,  54533,  54536,  54540,  54543,  54547,  54551, 
+     54556,  54559,  54563,  54567,  54572,  54576,  54581,  54586, 
+     54592,  54595,  54599,  54603,  54608,  54612,  54617,  54622, 
+     54628,  54632,  54637,  54642,  54648,  54653,  54659,  54665, 
+     54672,  54675,  54679,  54683,  54688,  54692,  54697,  54702, 
+     54708,  54712,  54717,  54722,  54728,  54733,  54739,  54745, 
+     54752,  54756,  54761,  54766,  54772,  54777,  54783,  54789, 
+     54796,  54801,  54807,  54813,  54820,  54826,  54833,  54840, 
+     54848,  54851,  54855,  54859,  54864,  54868,  54873,  54878, 
+     54884,  54888,  54893,  54898,  54904,  54909,  54915,  54921, 
+     54928,  54932,  54937,  54942,  54948,  54953,  54959,  54965, 
+     54972,  54977,  54983,  54989,  54996,  55002,  55009,  55016, 
+     55024,  55028,  55033,  55038,  55044,  55049,  55055,  55061, 
+     55068,  55073,  55079,  55085,  55092,  55098,  55105,  55112, 
+     55120,  55125,  55131,  55137,  55144,  55150,  55157,  55164, 
+     55172,  55178,  55185,  55192,  55200,  55207,  55215,  55223, 
+     55232,  55235,  55239,  55243,  55248,  55252,  55257,  55262, 
+     55268,  55272,  55277,  55282,  55288,  55293,  55299,  55305, 
+     55312,  55316,  55321,  55326,  55332,  55337,  55343,  55349, 
+     55356,  55361,  55367,  55373,  55380,  55386,  55393,  55400, 
+     55408,  55412,  55417,  55422,  55428,  55433,  55439,  55445, 
+     55452,  55457,  55463,  55469,  55476,  55482,  55489,  55496, 
+     55504,  55509,  55515,  55521,  55528,  55534,  55541,  55548, 
+     55556,  55562,  55569,  55576,  55584,  55591,  55599,  55607, 
+     55616,  55620,  55625,  55630,  55636,  55641,  55647,  55653, 
+     55660,  55665,  55671,  55677,  55684,  55690,  55697,  55704, 
+     55712,  55717,  55723,  55729,  55736,  55742,  55749,  55756, 
+     55764,  55770,  55777,  55784,  55792,  55799,  55807,  55815, 
+     55824,  55829,  55835,  55841,  55848,  55854,  55861,  55868, 
+     55876,  55882,  55889,  55896,  55904,  55911,  55919,  55927, 
+     55936,  55942,  55949,  55956,  55964,  55971,  55979,  55987, 
+     55996,  56003,  56011,  56019,  56028,  56036,  56045,  56054, 
+     56064,  56066,  56069,  56072,  56076,  56079,  56083,  56087, 
+     56092,  56095,  56099,  56103,  56108,  56112,  56117,  56122, 
+     56128,  56131,  56135,  56139,  56144,  56148,  56153,  56158, 
+     56164,  56168,  56173,  56178,  56184,  56189,  56195,  56201, 
+     56208,  56211,  56215,  56219,  56224,  56228,  56233,  56238, 
+     56244,  56248,  56253,  56258,  56264,  56269,  56275,  56281, 
+     56288,  56292,  56297,  56302,  56308,  56313,  56319,  56325, 
+     56332,  56337,  56343,  56349,  56356,  56362,  56369,  56376, 
+     56384,  56387,  56391,  56395,  56400,  56404,  56409,  56414, 
+     56420,  56424,  56429,  56434,  56440,  56445,  56451,  56457, 
+     56464,  56468,  56473,  56478,  56484,  56489,  56495,  56501, 
+     56508,  56513,  56519,  56525,  56532,  56538,  56545,  56552, 
+     56560,  56564,  56569,  56574,  56580,  56585,  56591,  56597, 
+     56604,  56609,  56615,  56621,  56628,  56634,  56641,  56648, 
+     56656,  56661,  56667,  56673,  56680,  56686,  56693,  56700, 
+     56708,  56714,  56721,  56728,  56736,  56743,  56751,  56759, 
+     56768,  56771,  56775,  56779,  56784,  56788,  56793,  56798, 
+     56804,  56808,  56813,  56818,  56824,  56829,  56835,  56841, 
+     56848,  56852,  56857,  56862,  56868,  56873,  56879,  56885, 
+     56892,  56897,  56903,  56909,  56916,  56922,  56929,  56936, 
+     56944,  56948,  56953,  56958,  56964,  56969,  56975,  56981, 
+     56988,  56993,  56999,  57005,  57012,  57018,  57025,  57032, 
+     57040,  57045,  57051,  57057,  57064,  57070,  57077,  57084, 
+     57092,  57098,  57105,  57112,  57120,  57127,  57135,  57143, 
+     57152,  57156,  57161,  57166,  57172,  57177,  57183,  57189, 
+     57196,  57201,  57207,  57213,  57220,  57226,  57233,  57240, 
+     57248,  57253,  57259,  57265,  57272,  57278,  57285,  57292, 
+     57300,  57306,  57313,  57320,  57328,  57335,  57343,  57351, 
+     57360,  57365,  57371,  57377,  57384,  57390,  57397,  57404, 
+     57412,  57418,  57425,  57432,  57440,  57447,  57455,  57463, 
+     57472,  57478,  57485,  57492,  57500,  57507,  57515,  57523, 
+     57532,  57539,  57547,  57555,  57564,  57572,  57581,  57590, 
+     57600,  57603,  57607,  57611,  57616,  57620,  57625,  57630, 
+     57636,  57640,  57645,  57650,  57656,  57661,  57667,  57673, 
+     57680,  57684,  57689,  57694,  57700,  57705,  57711,  57717, 
+     57724,  57729,  57735,  57741,  57748,  57754,  57761,  57768, 
+     57776,  57780,  57785,  57790,  57796,  57801,  57807,  57813, 
+     57820,  57825,  57831,  57837,  57844,  57850,  57857,  57864, 
+     57872,  57877,  57883,  57889,  57896,  57902,  57909,  57916, 
+     57924,  57930,  57937,  57944,  57952,  57959,  57967,  57975, 
+     57984,  57988,  57993,  57998,  58004,  58009,  58015,  58021, 
+     58028,  58033,  58039,  58045,  58052,  58058,  58065,  58072, 
+     58080,  58085,  58091,  58097,  58104,  58110,  58117,  58124, 
+     58132,  58138,  58145,  58152,  58160,  58167,  58175,  58183, 
+     58192,  58197,  58203,  58209,  58216,  58222,  58229,  58236, 
+     58244,  58250,  58257,  58264,  58272,  58279,  58287,  58295, 
+     58304,  58310,  58317,  58324,  58332,  58339,  58347,  58355, 
+     58364,  58371,  58379,  58387,  58396,  58404,  58413,  58422, 
+     58432,  58436,  58441,  58446,  58452,  58457,  58463,  58469, 
+     58476,  58481,  58487,  58493,  58500,  58506,  58513,  58520, 
+     58528,  58533,  58539,  58545,  58552,  58558,  58565,  58572, 
+     58580,  58586,  58593,  58600,  58608,  58615,  58623,  58631, 
+     58640,  58645,  58651,  58657,  58664,  58670,  58677,  58684, 
+     58692,  58698,  58705,  58712,  58720,  58727,  58735,  58743, 
+     58752,  58758,  58765,  58772,  58780,  58787,  58795,  58803, 
+     58812,  58819,  58827,  58835,  58844,  58852,  58861,  58870, 
+     58880,  58885,  58891,  58897,  58904,  58910,  58917,  58924, 
+     58932,  58938,  58945,  58952,  58960,  58967,  58975,  58983, 
+     58992,  58998,  59005,  59012,  59020,  59027,  59035,  59043, 
+     59052,  59059,  59067,  59075,  59084,  59092,  59101,  59110, 
+     59120,  59126,  59133,  59140,  59148,  59155,  59163,  59171, 
+     59180,  59187,  59195,  59203,  59212,  59220,  59229,  59238, 
+     59248,  59255,  59263,  59271,  59280,  59288,  59297,  59306, 
+     59316,  59324,  59333,  59342,  59352,  59361,  59371,  59381, 
+     59392,  59394,  59397,  59400,  59404,  59407,  59411,  59415, 
+     59420,  59423,  59427,  59431,  59436,  59440,  59445,  59450, 
+     59456,  59459,  59463,  59467,  59472,  59476,  59481,  59486, 
+     59492,  59496,  59501,  59506,  59512,  59517,  59523,  59529, 
+     59536,  59539,  59543,  59547,  59552,  59556,  59561,  59566, 
+     59572,  59576,  59581,  59586,  59592,  59597,  59603,  59609, 
+     59616,  59620,  59625,  59630,  59636,  59641,  59647,  59653, 
+     59660,  59665,  59671,  59677,  59684,  59690,  59697,  59704, 
+     59712,  59715,  59719,  59723,  59728,  59732,  59737,  59742, 
+     59748,  59752,  59757,  59762,  59768,  59773,  59779,  59785, 
+     59792,  59796,  59801,  59806,  59812,  59817,  59823,  59829, 
+     59836,  59841,  59847,  59853,  59860,  59866,  59873,  59880, 
+     59888,  59892,  59897,  59902,  59908,  59913,  59919,  59925, 
+     59932,  59937,  59943,  59949,  59956,  59962,  59969,  59976, 
+     59984,  59989,  59995,  60001,  60008,  60014,  60021,  60028, 
+     60036,  60042,  60049,  60056,  60064,  60071,  60079,  60087, 
+     60096,  60099,  60103,  60107,  60112,  60116,  60121,  60126, 
+     60132,  60136,  60141,  60146,  60152,  60157,  60163,  60169, 
+     60176,  60180,  60185,  60190,  60196,  60201,  60207,  60213, 
+     60220,  60225,  60231,  60237,  60244,  60250,  60257,  60264, 
+     60272,  60276,  60281,  60286,  60292,  60297,  60303,  60309, 
+     60316,  60321,  60327,  60333,  60340,  60346,  60353,  60360, 
+     60368,  60373,  60379,  60385,  60392,  60398,  60405,  60412, 
+     60420,  60426,  60433,  60440,  60448,  60455,  60463,  60471, 
+     60480,  60484,  60489,  60494,  60500,  60505,  60511,  60517, 
+     60524,  60529,  60535,  60541,  60548,  60554,  60561,  60568, 
+     60576,  60581,  60587,  60593,  60600,  60606,  60613,  60620, 
+     60628,  60634,  60641,  60648,  60656,  60663,  60671,  60679, 
+     60688,  60693,  60699,  60705,  60712,  60718,  60725,  60732, 
+     60740,  60746,  60753,  60760,  60768,  60775,  60783,  60791, 
+     60800,  60806,  60813,  60820,  60828,  60835,  60843,  60851, 
+     60860,  60867,  60875,  60883,  60892,  60900,  60909,  60918, 
+     60928,  60931,  60935,  60939,  60944,  60948,  60953,  60958, 
+     60964,  60968,  60973,  60978,  60984,  60989,  60995,  61001, 
+     61008,  61012,  61017,  61022,  61028,  61033,  61039,  61045, 
+     61052,  61057,  61063,  61069,  61076,  61082,  61089,  61096, 
+     61104,  61108,  61113,  61118,  61124,  61129,  61135,  61141, 
+     61148,  61153,  61159,  61165,  61172,  61178,  61185,  61192, 
+     61200,  61205,  61211,  61217,  61224,  61230,  61237,  61244, 
+     61252,  61258,  61265,  61272,  61280,  61287,  61295,  61303, 
+     61312,  61316,  61321,  61326,  61332,  61337,  61343,  61349, 
+     61356,  61361,  61367,  61373,  61380,  61386,  61393,  61400, 
+     61408,  61413,  61419,  61425,  61432,  61438,  61445,  61452, 
+     61460,  61466,  61473,  61480,  61488,  61495,  61503,  61511, 
+     61520,  61525,  61531,  61537,  61544,  61550,  61557,  61564, 
+     61572,  61578,  61585,  61592,  61600,  61607,  61615,  61623, 
+     61632,  61638,  61645,  61652,  61660,  61667,  61675,  61683, 
+     61692,  61699,  61707,  61715,  61724,  61732,  61741,  61750, 
+     61760,  61764,  61769,  61774,  61780,  61785,  61791,  61797, 
+     61804,  61809,  61815,  61821,  61828,  61834,  61841,  61848, 
+     61856,  61861,  61867,  61873,  61880,  61886,  61893,  61900, 
+     61908,  61914,  61921,  61928,  61936,  61943,  61951,  61959, 
+     61968,  61973,  61979,  61985,  61992,  61998,  62005,  62012, 
+     62020,  62026,  62033,  62040,  62048,  62055,  62063,  62071, 
+     62080,  62086,  62093,  62100,  62108,  62115,  62123,  62131, 
+     62140,  62147,  62155,  62163,  62172,  62180,  62189,  62198, 
+     62208,  62213,  62219,  62225,  62232,  62238,  62245,  62252, 
+     62260,  62266,  62273,  62280,  62288,  62295,  62303,  62311, 
+     62320,  62326,  62333,  62340,  62348,  62355,  62363,  62371, 
+     62380,  62387,  62395,  62403,  62412,  62420,  62429,  62438, 
+     62448,  62454,  62461,  62468,  62476,  62483,  62491,  62499, 
+     62508,  62515,  62523,  62531,  62540,  62548,  62557,  62566, 
+     62576,  62583,  62591,  62599,  62608,  62616,  62625,  62634, 
+     62644,  62652,  62661,  62670,  62680,  62689,  62699,  62709, 
+     62720,  62723,  62727,  62731,  62736,  62740,  62745,  62750, 
+     62756,  62760,  62765,  62770,  62776,  62781,  62787,  62793, 
+     62800,  62804,  62809,  62814,  62820,  62825,  62831,  62837, 
+     62844,  62849,  62855,  62861,  62868,  62874,  62881,  62888, 
+     62896,  62900,  62905,  62910,  62916,  62921,  62927,  62933, 
+     62940,  62945,  62951,  62957,  62964,  62970,  62977,  62984, 
+     62992,  62997,  63003,  63009,  63016,  63022,  63029,  63036, 
+     63044,  63050,  63057,  63064,  63072,  63079,  63087,  63095, 
+     63104,  63108,  63113,  63118,  63124,  63129,  63135,  63141, 
+     63148,  63153,  63159,  63165,  63172,  63178,  63185,  63192, 
+     63200,  63205,  63211,  63217,  63224,  63230,  63237,  63244, 
+     63252,  63258,  63265,  63272,  63280,  63287,  63295,  63303, 
+     63312,  63317,  63323,  63329,  63336,  63342,  63349,  63356, 
+     63364,  63370,  63377,  63384,  63392,  63399,  63407,  63415, 
+     63424,  63430,  63437,  63444,  63452,  63459,  63467,  63475, 
+     63484,  63491,  63499,  63507,  63516,  63524,  63533,  63542, 
+     63552,  63556,  63561,  63566,  63572,  63577,  63583,  63589, 
+     63596,  63601,  63607,  63613,  63620,  63626,  63633,  63640, 
+     63648,  63653,  63659,  63665,  63672,  63678,  63685,  63692, 
+     63700,  63706,  63713,  63720,  63728,  63735,  63743,  63751, 
+     63760,  63765,  63771,  63777,  63784,  63790,  63797,  63804, 
+     63812,  63818,  63825,  63832,  63840,  63847,  63855,  63863, 
+     63872,  63878,  63885,  63892,  63900,  63907,  63915,  63923, 
+     63932,  63939,  63947,  63955,  63964,  63972,  63981,  63990, 
+     64000,  64005,  64011,  64017,  64024,  64030,  64037,  64044, 
+     64052,  64058,  64065,  64072,  64080,  64087,  64095,  64103, 
+     64112,  64118,  64125,  64132,  64140,  64147,  64155,  64163, 
+     64172,  64179,  64187,  64195,  64204,  64212,  64221,  64230, 
+     64240,  64246,  64253,  64260,  64268,  64275,  64283,  64291, 
+     64300,  64307,  64315,  64323,  64332,  64340,  64349,  64358, 
+     64368,  64375,  64383,  64391,  64400,  64408,  64417,  64426, 
+     64436,  64444,  64453,  64462,  64472,  64481,  64491,  64501, 
+     64512,  64516,  64521,  64526,  64532,  64537,  64543,  64549, 
+     64556,  64561,  64567,  64573,  64580,  64586,  64593,  64600, 
+     64608,  64613,  64619,  64625,  64632,  64638,  64645,  64652, 
+     64660,  64666,  64673,  64680,  64688,  64695,  64703,  64711, 
+     64720,  64725,  64731,  64737,  64744,  64750,  64757,  64764, 
+     64772,  64778,  64785,  64792,  64800,  64807,  64815,  64823, 
+     64832,  64838,  64845,  64852,  64860,  64867,  64875,  64883, 
+     64892,  64899,  64907,  64915,  64924,  64932,  64941,  64950, 
+     64960,  64965,  64971,  64977,  64984,  64990,  64997,  65004, 
+     65012,  65018,  65025,  65032,  65040,  65047,  65055,  65063, 
+     65072,  65078,  65085,  65092,  65100,  65107,  65115,  65123, 
+     65132,  65139,  65147,  65155,  65164,  65172,  65181,  65190, 
+     65200,  65206,  65213,  65220,  65228,  65235,  65243,  65251, 
+     65260,  65267,  65275,  65283,  65292,  65300,  65309,  65318, 
+     65328,  65335,  65343,  65351,  65360,  65368,  65377,  65386, 
+     65396,  65404,  65413,  65422,  65432,  65441,  65451,  65461, 
+     65472,  65477,  65483,  65489,  65496,  65502,  65509,  65516, 
+     65524,  65530,  65537,  65544,  65552,  65559,  65567,  65575, 
+     65584,  65590,  65597,  65604,  65612,  65619,  65627,  65635, 
+     65644,  65651,  65659,  65667,  65676,  65684,  65693,  65702, 
+     65712,  65718,  65725,  65732,  65740,  65747,  65755,  65763, 
+     65772,  65779,  65787,  65795,  65804,  65812,  65821,  65830, 
+     65840,  65847,  65855,  65863,  65872,  65880,  65889,  65898, 
+     65908,  65916,  65925,  65934,  65944,  65953,  65963,  65973, 
+     65984,  65990,  65997,  66004,  66012,  66019,  66027,  66035, 
+     66044,  66051,  66059,  66067,  66076,  66084,  66093,  66102, 
+     66112,  66119,  66127,  66135,  66144,  66152,  66161,  66170, 
+     66180,  66188,  66197,  66206,  66216,  66225,  66235,  66245, 
+     66256,  66263,  66271,  66279,  66288,  66296,  66305,  66314, 
+     66324,  66332,  66341,  66350,  66360,  66369,  66379,  66389, 
+     66400,  66408,  66417,  66426,  66436,  66445,  66455,  66465, 
+     66476,  66485,  66495,  66505,  66516,  66526,  66537,  66548, 
+     66560,  66562,  66565,  66568,  66572,  66575,  66579,  66583, 
+     66588,  66591,  66595,  66599,  66604,  66608,  66613,  66618, 
+     66624,  66627,  66631,  66635,  66640,  66644,  66649,  66654, 
+     66660,  66664,  66669,  66674,  66680,  66685,  66691,  66697, 
+     66704,  66707,  66711,  66715,  66720,  66724,  66729,  66734, 
+     66740,  66744,  66749,  66754,  66760,  66765,  66771,  66777, 
+     66784,  66788,  66793,  66798,  66804,  66809,  66815,  66821, 
+     66828,  66833,  66839,  66845,  66852,  66858,  66865,  66872, 
+     66880,  66883,  66887,  66891,  66896,  66900,  66905,  66910, 
+     66916,  66920,  66925,  66930,  66936,  66941,  66947,  66953, 
+     66960,  66964,  66969,  66974,  66980,  66985,  66991,  66997, 
+     67004,  67009,  67015,  67021,  67028,  67034,  67041,  67048, 
+     67056,  67060,  67065,  67070,  67076,  67081,  67087,  67093, 
+     67100,  67105,  67111,  67117,  67124,  67130,  67137,  67144, 
+     67152,  67157,  67163,  67169,  67176,  67182,  67189,  67196, 
+     67204,  67210,  67217,  67224,  67232,  67239,  67247,  67255, 
+     67264,  67267,  67271,  67275,  67280,  67284,  67289,  67294, 
+     67300,  67304,  67309,  67314,  67320,  67325,  67331,  67337, 
+     67344,  67348,  67353,  67358,  67364,  67369,  67375,  67381, 
+     67388,  67393,  67399,  67405,  67412,  67418,  67425,  67432, 
+     67440,  67444,  67449,  67454,  67460,  67465,  67471,  67477, 
+     67484,  67489,  67495,  67501,  67508,  67514,  67521,  67528, 
+     67536,  67541,  67547,  67553,  67560,  67566,  67573,  67580, 
+     67588,  67594,  67601,  67608,  67616,  67623,  67631,  67639, 
+     67648,  67652,  67657,  67662,  67668,  67673,  67679,  67685, 
+     67692,  67697,  67703,  67709,  67716,  67722,  67729,  67736, 
+     67744,  67749,  67755,  67761,  67768,  67774,  67781,  67788, 
+     67796,  67802,  67809,  67816,  67824,  67831,  67839,  67847, 
+     67856,  67861,  67867,  67873,  67880,  67886,  67893,  67900, 
+     67908,  67914,  67921,  67928,  67936,  67943,  67951,  67959, 
+     67968,  67974,  67981,  67988,  67996,  68003,  68011,  68019, 
+     68028,  68035,  68043,  68051,  68060,  68068,  68077,  68086, 
+     68096,  68099,  68103,  68107,  68112,  68116,  68121,  68126, 
+     68132,  68136,  68141,  68146,  68152,  68157,  68163,  68169, 
+     68176,  68180,  68185,  68190,  68196,  68201,  68207,  68213, 
+     68220,  68225,  68231,  68237,  68244,  68250,  68257,  68264, 
+     68272,  68276,  68281,  68286,  68292,  68297,  68303,  68309, 
+     68316,  68321,  68327,  68333,  68340,  68346,  68353,  68360, 
+     68368,  68373,  68379,  68385,  68392,  68398,  68405,  68412, 
+     68420,  68426,  68433,  68440,  68448,  68455,  68463,  68471, 
+     68480,  68484,  68489,  68494,  68500,  68505,  68511,  68517, 
+     68524,  68529,  68535,  68541,  68548,  68554,  68561,  68568, 
+     68576,  68581,  68587,  68593,  68600,  68606,  68613,  68620, 
+     68628,  68634,  68641,  68648,  68656,  68663,  68671,  68679, 
+     68688,  68693,  68699,  68705,  68712,  68718,  68725,  68732, 
+     68740,  68746,  68753,  68760,  68768,  68775,  68783,  68791, 
+     68800,  68806,  68813,  68820,  68828,  68835,  68843,  68851, 
+     68860,  68867,  68875,  68883,  68892,  68900,  68909,  68918, 
+     68928,  68932,  68937,  68942,  68948,  68953,  68959,  68965, 
+     68972,  68977,  68983,  68989,  68996,  69002,  69009,  69016, 
+     69024,  69029,  69035,  69041,  69048,  69054,  69061,  69068, 
+     69076,  69082,  69089,  69096,  69104,  69111,  69119,  69127, 
+     69136,  69141,  69147,  69153,  69160,  69166,  69173,  69180, 
+     69188,  69194,  69201,  69208,  69216,  69223,  69231,  69239, 
+     69248,  69254,  69261,  69268,  69276,  69283,  69291,  69299, 
+     69308,  69315,  69323,  69331,  69340,  69348,  69357,  69366, 
+     69376,  69381,  69387,  69393,  69400,  69406,  69413,  69420, 
+     69428,  69434,  69441,  69448,  69456,  69463,  69471,  69479, 
+     69488,  69494,  69501,  69508,  69516,  69523,  69531,  69539, 
+     69548,  69555,  69563,  69571,  69580,  69588,  69597,  69606, 
+     69616,  69622,  69629,  69636,  69644,  69651,  69659,  69667, 
+     69676,  69683,  69691,  69699,  69708,  69716,  69725,  69734, 
+     69744,  69751,  69759,  69767,  69776,  69784,  69793,  69802, 
+     69812,  69820,  69829,  69838,  69848,  69857,  69867,  69877, 
+     69888,  69891,  69895,  69899,  69904,  69908,  69913,  69918, 
+     69924,  69928,  69933,  69938,  69944,  69949,  69955,  69961, 
+     69968,  69972,  69977,  69982,  69988,  69993,  69999,  70005, 
+     70012,  70017,  70023,  70029,  70036,  70042,  70049,  70056, 
+     70064,  70068,  70073,  70078,  70084,  70089,  70095,  70101, 
+     70108,  70113,  70119,  70125,  70132,  70138,  70145,  70152, 
+     70160,  70165,  70171,  70177,  70184,  70190,  70197,  70204, 
+     70212,  70218,  70225,  70232,  70240,  70247,  70255,  70263, 
+     70272,  70276,  70281,  70286,  70292,  70297,  70303,  70309, 
+     70316,  70321,  70327,  70333,  70340,  70346,  70353,  70360, 
+     70368,  70373,  70379,  70385,  70392,  70398,  70405,  70412, 
+     70420,  70426,  70433,  70440,  70448,  70455,  70463,  70471, 
+     70480,  70485,  70491,  70497,  70504,  70510,  70517,  70524, 
+     70532,  70538,  70545,  70552,  70560,  70567,  70575,  70583, 
+     70592,  70598,  70605,  70612,  70620,  70627,  70635,  70643, 
+     70652,  70659,  70667,  70675,  70684,  70692,  70701,  70710, 
+     70720,  70724,  70729,  70734,  70740,  70745,  70751,  70757, 
+     70764,  70769,  70775,  70781,  70788,  70794,  70801,  70808, 
+     70816,  70821,  70827,  70833,  70840,  70846,  70853,  70860, 
+     70868,  70874,  70881,  70888,  70896,  70903,  70911,  70919, 
+     70928,  70933,  70939,  70945,  70952,  70958,  70965,  70972, 
+     70980,  70986,  70993,  71000,  71008,  71015,  71023,  71031, 
+     71040,  71046,  71053,  71060,  71068,  71075,  71083,  71091, 
+     71100,  71107,  71115,  71123,  71132,  71140,  71149,  71158, 
+     71168,  71173,  71179,  71185,  71192,  71198,  71205,  71212, 
+     71220,  71226,  71233,  71240,  71248,  71255,  71263,  71271, 
+     71280,  71286,  71293,  71300,  71308,  71315,  71323,  71331, 
+     71340,  71347,  71355,  71363,  71372,  71380,  71389,  71398, 
+     71408,  71414,  71421,  71428,  71436,  71443,  71451,  71459, 
+     71468,  71475,  71483,  71491,  71500,  71508,  71517,  71526, 
+     71536,  71543,  71551,  71559,  71568,  71576,  71585,  71594, 
+     71604,  71612,  71621,  71630,  71640,  71649,  71659,  71669, 
+     71680,  71684,  71689,  71694,  71700,  71705,  71711,  71717, 
+     71724,  71729,  71735,  71741,  71748,  71754,  71761,  71768, 
+     71776,  71781,  71787,  71793,  71800,  71806,  71813,  71820, 
+     71828,  71834,  71841,  71848,  71856,  71863,  71871,  71879, 
+     71888,  71893,  71899,  71905,  71912,  71918,  71925,  71932, 
+     71940,  71946,  71953,  71960,  71968,  71975,  71983,  71991, 
+     72000,  72006,  72013,  72020,  72028,  72035,  72043,  72051, 
+     72060,  72067,  72075,  72083,  72092,  72100,  72109,  72118, 
+     72128,  72133,  72139,  72145,  72152,  72158,  72165,  72172, 
+     72180,  72186,  72193,  72200,  72208,  72215,  72223,  72231, 
+     72240,  72246,  72253,  72260,  72268,  72275,  72283,  72291, 
+     72300,  72307,  72315,  72323,  72332,  72340,  72349,  72358, 
+     72368,  72374,  72381,  72388,  72396,  72403,  72411,  72419, 
+     72428,  72435,  72443,  72451,  72460,  72468,  72477,  72486, 
+     72496,  72503,  72511,  72519,  72528,  72536,  72545,  72554, 
+     72564,  72572,  72581,  72590,  72600,  72609,  72619,  72629, 
+     72640,  72645,  72651,  72657,  72664,  72670,  72677,  72684, 
+     72692,  72698,  72705,  72712,  72720,  72727,  72735,  72743, 
+     72752,  72758,  72765,  72772,  72780,  72787,  72795,  72803, 
+     72812,  72819,  72827,  72835,  72844,  72852,  72861,  72870, 
+     72880,  72886,  72893,  72900,  72908,  72915,  72923,  72931, 
+     72940,  72947,  72955,  72963,  72972,  72980,  72989,  72998, 
+     73008,  73015,  73023,  73031,  73040,  73048,  73057,  73066, 
+     73076,  73084,  73093,  73102,  73112,  73121,  73131,  73141, 
+     73152,  73158,  73165,  73172,  73180,  73187,  73195,  73203, 
+     73212,  73219,  73227,  73235,  73244,  73252,  73261,  73270, 
+     73280,  73287,  73295,  73303,  73312,  73320,  73329,  73338, 
+     73348,  73356,  73365,  73374,  73384,  73393,  73403,  73413, 
+     73424,  73431,  73439,  73447,  73456,  73464,  73473,  73482, 
+     73492,  73500,  73509,  73518,  73528,  73537,  73547,  73557, 
+     73568,  73576,  73585,  73594,  73604,  73613,  73623,  73633, 
+     73644,  73653,  73663,  73673,  73684,  73694,  73705,  73716, 
+     73728,  73731,  73735,  73739,  73744,  73748,  73753,  73758, 
+     73764,  73768,  73773,  73778,  73784,  73789,  73795,  73801, 
+     73808,  73812,  73817,  73822,  73828,  73833,  73839,  73845, 
+     73852,  73857,  73863,  73869,  73876,  73882,  73889,  73896, 
+     73904,  73908,  73913,  73918,  73924,  73929,  73935,  73941, 
+     73948,  73953,  73959,  73965,  73972,  73978,  73985,  73992, 
+     74000,  74005,  74011,  74017,  74024,  74030,  74037,  74044, 
+     74052,  74058,  74065,  74072,  74080,  74087,  74095,  74103, 
+     74112,  74116,  74121,  74126,  74132,  74137,  74143,  74149, 
+     74156,  74161,  74167,  74173,  74180,  74186,  74193,  74200, 
+     74208,  74213,  74219,  74225,  74232,  74238,  74245,  74252, 
+     74260,  74266,  74273,  74280,  74288,  74295,  74303,  74311, 
+     74320,  74325,  74331,  74337,  74344,  74350,  74357,  74364, 
+     74372,  74378,  74385,  74392,  74400,  74407,  74415,  74423, 
+     74432,  74438,  74445,  74452,  74460,  74467,  74475,  74483, 
+     74492,  74499,  74507,  74515,  74524,  74532,  74541,  74550, 
+     74560,  74564,  74569,  74574,  74580,  74585,  74591,  74597, 
+     74604,  74609,  74615,  74621,  74628,  74634,  74641,  74648, 
+     74656,  74661,  74667,  74673,  74680,  74686,  74693,  74700, 
+     74708,  74714,  74721,  74728,  74736,  74743,  74751,  74759, 
+     74768,  74773,  74779,  74785,  74792,  74798,  74805,  74812, 
+     74820,  74826,  74833,  74840,  74848,  74855,  74863,  74871, 
+     74880,  74886,  74893,  74900,  74908,  74915,  74923,  74931, 
+     74940,  74947,  74955,  74963,  74972,  74980,  74989,  74998, 
+     75008,  75013,  75019,  75025,  75032,  75038,  75045,  75052, 
+     75060,  75066,  75073,  75080,  75088,  75095,  75103,  75111, 
+     75120,  75126,  75133,  75140,  75148,  75155,  75163,  75171, 
+     75180,  75187,  75195,  75203,  75212,  75220,  75229,  75238, 
+     75248,  75254,  75261,  75268,  75276,  75283,  75291,  75299, 
+     75308,  75315,  75323,  75331,  75340,  75348,  75357,  75366, 
+     75376,  75383,  75391,  75399,  75408,  75416,  75425,  75434, 
+     75444,  75452,  75461,  75470,  75480,  75489,  75499,  75509, 
+     75520,  75524,  75529,  75534,  75540,  75545,  75551,  75557, 
+     75564,  75569,  75575,  75581,  75588,  75594,  75601,  75608, 
+     75616,  75621,  75627,  75633,  75640,  75646,  75653,  75660, 
+     75668,  75674,  75681,  75688,  75696,  75703,  75711,  75719, 
+     75728,  75733,  75739,  75745,  75752,  75758,  75765,  75772, 
+     75780,  75786,  75793,  75800,  75808,  75815,  75823,  75831, 
+     75840,  75846,  75853,  75860,  75868,  75875,  75883,  75891, 
+     75900,  75907,  75915,  75923,  75932,  75940,  75949,  75958, 
+     75968,  75973,  75979,  75985,  75992,  75998,  76005,  76012, 
+     76020,  76026,  76033,  76040,  76048,  76055,  76063,  76071, 
+     76080,  76086,  76093,  76100,  76108,  76115,  76123,  76131, 
+     76140,  76147,  76155,  76163,  76172,  76180,  76189,  76198, 
+     76208,  76214,  76221,  76228,  76236,  76243,  76251,  76259, 
+     76268,  76275,  76283,  76291,  76300,  76308,  76317,  76326, 
+     76336,  76343,  76351,  76359,  76368,  76376,  76385,  76394, 
+     76404,  76412,  76421,  76430,  76440,  76449,  76459,  76469, 
+     76480,  76485,  76491,  76497,  76504,  76510,  76517,  76524, 
+     76532,  76538,  76545,  76552,  76560,  76567,  76575,  76583, 
+     76592,  76598,  76605,  76612,  76620,  76627,  76635,  76643, 
+     76652,  76659,  76667,  76675,  76684,  76692,  76701,  76710, 
+     76720,  76726,  76733,  76740,  76748,  76755,  76763,  76771, 
+     76780,  76787,  76795,  76803,  76812,  76820,  76829,  76838, 
+     76848,  76855,  76863,  76871,  76880,  76888,  76897,  76906, 
+     76916,  76924,  76933,  76942,  76952,  76961,  76971,  76981, 
+     76992,  76998,  77005,  77012,  77020,  77027,  77035,  77043, 
+     77052,  77059,  77067,  77075,  77084,  77092,  77101,  77110, 
+     77120,  77127,  77135,  77143,  77152,  77160,  77169,  77178, 
+     77188,  77196,  77205,  77214,  77224,  77233,  77243,  77253, 
+     77264,  77271,  77279,  77287,  77296,  77304,  77313,  77322, 
+     77332,  77340,  77349,  77358,  77368,  77377,  77387,  77397, 
+     77408,  77416,  77425,  77434,  77444,  77453,  77463,  77473, 
+     77484,  77493,  77503,  77513,  77524,  77534,  77545,  77556, 
+     77568,  77572,  77577,  77582,  77588,  77593,  77599,  77605, 
+     77612,  77617,  77623,  77629,  77636,  77642,  77649,  77656, 
+     77664,  77669,  77675,  77681,  77688,  77694,  77701,  77708, 
+     77716,  77722,  77729,  77736,  77744,  77751,  77759,  77767, 
+     77776,  77781,  77787,  77793,  77800,  77806,  77813,  77820, 
+     77828,  77834,  77841,  77848,  77856,  77863,  77871,  77879, 
+     77888,  77894,  77901,  77908,  77916,  77923,  77931,  77939, 
+     77948,  77955,  77963,  77971,  77980,  77988,  77997,  78006, 
+     78016,  78021,  78027,  78033,  78040,  78046,  78053,  78060, 
+     78068,  78074,  78081,  78088,  78096,  78103,  78111,  78119, 
+     78128,  78134,  78141,  78148,  78156,  78163,  78171,  78179, 
+     78188,  78195,  78203,  78211,  78220,  78228,  78237,  78246, 
+     78256,  78262,  78269,  78276,  78284,  78291,  78299,  78307, 
+     78316,  78323,  78331,  78339,  78348,  78356,  78365,  78374, 
+     78384,  78391,  78399,  78407,  78416,  78424,  78433,  78442, 
+     78452,  78460,  78469,  78478,  78488,  78497,  78507,  78517, 
+     78528,  78533,  78539,  78545,  78552,  78558,  78565,  78572, 
+     78580,  78586,  78593,  78600,  78608,  78615,  78623,  78631, 
+     78640,  78646,  78653,  78660,  78668,  78675,  78683,  78691, 
+     78700,  78707,  78715,  78723,  78732,  78740,  78749,  78758, 
+     78768,  78774,  78781,  78788,  78796,  78803,  78811,  78819, 
+     78828,  78835,  78843,  78851,  78860,  78868,  78877,  78886, 
+     78896,  78903,  78911,  78919,  78928,  78936,  78945,  78954, 
+     78964,  78972,  78981,  78990,  79000,  79009,  79019,  79029, 
+     79040,  79046,  79053,  79060,  79068,  79075,  79083,  79091, 
+     79100,  79107,  79115,  79123,  79132,  79140,  79149,  79158, 
+     79168,  79175,  79183,  79191,  79200,  79208,  79217,  79226, 
+     79236,  79244,  79253,  79262,  79272,  79281,  79291,  79301, 
+     79312,  79319,  79327,  79335,  79344,  79352,  79361,  79370, 
+     79380,  79388,  79397,  79406,  79416,  79425,  79435,  79445, 
+     79456,  79464,  79473,  79482,  79492,  79501,  79511,  79521, 
+     79532,  79541,  79551,  79561,  79572,  79582,  79593,  79604, 
+     79616,  79621,  79627,  79633,  79640,  79646,  79653,  79660, 
+     79668,  79674,  79681,  79688,  79696,  79703,  79711,  79719, 
+     79728,  79734,  79741,  79748,  79756,  79763,  79771,  79779, 
+     79788,  79795,  79803,  79811,  79820,  79828,  79837,  79846, 
+     79856,  79862,  79869,  79876,  79884,  79891,  79899,  79907, 
+     79916,  79923,  79931,  79939,  79948,  79956,  79965,  79974, 
+     79984,  79991,  79999,  80007,  80016,  80024,  80033,  80042, 
+     80052,  80060,  80069,  80078,  80088,  80097,  80107,  80117, 
+     80128,  80134,  80141,  80148,  80156,  80163,  80171,  80179, 
+     80188,  80195,  80203,  80211,  80220,  80228,  80237,  80246, 
+     80256,  80263,  80271,  80279,  80288,  80296,  80305,  80314, 
+     80324,  80332,  80341,  80350,  80360,  80369,  80379,  80389, 
+     80400,  80407,  80415,  80423,  80432,  80440,  80449,  80458, 
+     80468,  80476,  80485,  80494,  80504,  80513,  80523,  80533, 
+     80544,  80552,  80561,  80570,  80580,  80589,  80599,  80609, 
+     80620,  80629,  80639,  80649,  80660,  80670,  80681,  80692, 
+     80704,  80710,  80717,  80724,  80732,  80739,  80747,  80755, 
+     80764,  80771,  80779,  80787,  80796,  80804,  80813,  80822, 
+     80832,  80839,  80847,  80855,  80864,  80872,  80881,  80890, 
+     80900,  80908,  80917,  80926,  80936,  80945,  80955,  80965, 
+     80976,  80983,  80991,  80999,  81008,  81016,  81025,  81034, 
+     81044,  81052,  81061,  81070,  81080,  81089,  81099,  81109, 
+     81120,  81128,  81137,  81146,  81156,  81165,  81175,  81185, 
+     81196,  81205,  81215,  81225,  81236,  81246,  81257,  81268, 
+     81280,  81287,  81295,  81303,  81312,  81320,  81329,  81338, 
+     81348,  81356,  81365,  81374,  81384,  81393,  81403,  81413, 
+     81424,  81432,  81441,  81450,  81460,  81469,  81479,  81489, 
+     81500,  81509,  81519,  81529,  81540,  81550,  81561,  81572, 
+     81584,  81592,  81601,  81610,  81620,  81629,  81639,  81649, 
+     81660,  81669,  81679,  81689,  81700,  81710,  81721,  81732, 
+     81744,  81753,  81763,  81773,  81784,  81794,  81805,  81816, 
+     81828,  81838,  81849,  81860,  81872,  81883,  81895,  81907, 
+     81920,  81922,  81925,  81928,  81932,  81935,  81939,  81943, 
+     81948,  81951,  81955,  81959,  81964,  81968,  81973,  81978, 
+     81984,  81987,  81991,  81995,  82000,  82004,  82009,  82014, 
+     82020,  82024,  82029,  82034,  82040,  82045,  82051,  82057, 
+     82064,  82067,  82071,  82075,  82080,  82084,  82089,  82094, 
+     82100,  82104,  82109,  82114,  82120,  82125,  82131,  82137, 
+     82144,  82148,  82153,  82158,  82164,  82169,  82175,  82181, 
+     82188,  82193,  82199,  82205,  82212,  82218,  82225,  82232, 
+     82240,  82243,  82247,  82251,  82256,  82260,  82265,  82270, 
+     82276,  82280,  82285,  82290,  82296,  82301,  82307,  82313, 
+     82320,  82324,  82329,  82334,  82340,  82345,  82351,  82357, 
+     82364,  82369,  82375,  82381,  82388,  82394,  82401,  82408, 
+     82416,  82420,  82425,  82430,  82436,  82441,  82447,  82453, 
+     82460,  82465,  82471,  82477,  82484,  82490,  82497,  82504, 
+     82512,  82517,  82523,  82529,  82536,  82542,  82549,  82556, 
+     82564,  82570,  82577,  82584,  82592,  82599,  82607,  82615, 
+     82624,  82627,  82631,  82635,  82640,  82644,  82649,  82654, 
+     82660,  82664,  82669,  82674,  82680,  82685,  82691,  82697, 
+     82704,  82708,  82713,  82718,  82724,  82729,  82735,  82741, 
+     82748,  82753,  82759,  82765,  82772,  82778,  82785,  82792, 
+     82800,  82804,  82809,  82814,  82820,  82825,  82831,  82837, 
+     82844,  82849,  82855,  82861,  82868,  82874,  82881,  82888, 
+     82896,  82901,  82907,  82913,  82920,  82926,  82933,  82940, 
+     82948,  82954,  82961,  82968,  82976,  82983,  82991,  82999, 
+     83008,  83012,  83017,  83022,  83028,  83033,  83039,  83045, 
+     83052,  83057,  83063,  83069,  83076,  83082,  83089,  83096, 
+     83104,  83109,  83115,  83121,  83128,  83134,  83141,  83148, 
+     83156,  83162,  83169,  83176,  83184,  83191,  83199,  83207, 
+     83216,  83221,  83227,  83233,  83240,  83246,  83253,  83260, 
+     83268,  83274,  83281,  83288,  83296,  83303,  83311,  83319, 
+     83328,  83334,  83341,  83348,  83356,  83363,  83371,  83379, 
+     83388,  83395,  83403,  83411,  83420,  83428,  83437,  83446, 
+     83456,  83459,  83463,  83467,  83472,  83476,  83481,  83486, 
+     83492,  83496,  83501,  83506,  83512,  83517,  83523,  83529, 
+     83536,  83540,  83545,  83550,  83556,  83561,  83567,  83573, 
+     83580,  83585,  83591,  83597,  83604,  83610,  83617,  83624, 
+     83632,  83636,  83641,  83646,  83652,  83657,  83663,  83669, 
+     83676,  83681,  83687,  83693,  83700,  83706,  83713,  83720, 
+     83728,  83733,  83739,  83745,  83752,  83758,  83765,  83772, 
+     83780,  83786,  83793,  83800,  83808,  83815,  83823,  83831, 
+     83840,  83844,  83849,  83854,  83860,  83865,  83871,  83877, 
+     83884,  83889,  83895,  83901,  83908,  83914,  83921,  83928, 
+     83936,  83941,  83947,  83953,  83960,  83966,  83973,  83980, 
+     83988,  83994,  84001,  84008,  84016,  84023,  84031,  84039, 
+     84048,  84053,  84059,  84065,  84072,  84078,  84085,  84092, 
+     84100,  84106,  84113,  84120,  84128,  84135,  84143,  84151, 
+     84160,  84166,  84173,  84180,  84188,  84195,  84203,  84211, 
+     84220,  84227,  84235,  84243,  84252,  84260,  84269,  84278, 
+     84288,  84292,  84297,  84302,  84308,  84313,  84319,  84325, 
+     84332,  84337,  84343,  84349,  84356,  84362,  84369,  84376, 
+     84384,  84389,  84395,  84401,  84408,  84414,  84421,  84428, 
+     84436,  84442,  84449,  84456,  84464,  84471,  84479,  84487, 
+     84496,  84501,  84507,  84513,  84520,  84526,  84533,  84540, 
+     84548,  84554,  84561,  84568,  84576,  84583,  84591,  84599, 
+     84608,  84614,  84621,  84628,  84636,  84643,  84651,  84659, 
+     84668,  84675,  84683,  84691,  84700,  84708,  84717,  84726, 
+     84736,  84741,  84747,  84753,  84760,  84766,  84773,  84780, 
+     84788,  84794,  84801,  84808,  84816,  84823,  84831,  84839, 
+     84848,  84854,  84861,  84868,  84876,  84883,  84891,  84899, 
+     84908,  84915,  84923,  84931,  84940,  84948,  84957,  84966, 
+     84976,  84982,  84989,  84996,  85004,  85011,  85019,  85027, 
+     85036,  85043,  85051,  85059,  85068,  85076,  85085,  85094, 
+     85104,  85111,  85119,  85127,  85136,  85144,  85153,  85162, 
+     85172,  85180,  85189,  85198,  85208,  85217,  85227,  85237, 
+     85248,  85251,  85255,  85259,  85264,  85268,  85273,  85278, 
+     85284,  85288,  85293,  85298,  85304,  85309,  85315,  85321, 
+     85328,  85332,  85337,  85342,  85348,  85353,  85359,  85365, 
+     85372,  85377,  85383,  85389,  85396,  85402,  85409,  85416, 
+     85424,  85428,  85433,  85438,  85444,  85449,  85455,  85461, 
+     85468,  85473,  85479,  85485,  85492,  85498,  85505,  85512, 
+     85520,  85525,  85531,  85537,  85544,  85550,  85557,  85564, 
+     85572,  85578,  85585,  85592,  85600,  85607,  85615,  85623, 
+     85632,  85636,  85641,  85646,  85652,  85657,  85663,  85669, 
+     85676,  85681,  85687,  85693,  85700,  85706,  85713,  85720, 
+     85728,  85733,  85739,  85745,  85752,  85758,  85765,  85772, 
+     85780,  85786,  85793,  85800,  85808,  85815,  85823,  85831, 
+     85840,  85845,  85851,  85857,  85864,  85870,  85877,  85884, 
+     85892,  85898,  85905,  85912,  85920,  85927,  85935,  85943, 
+     85952,  85958,  85965,  85972,  85980,  85987,  85995,  86003, 
+     86012,  86019,  86027,  86035,  86044,  86052,  86061,  86070, 
+     86080,  86084,  86089,  86094,  86100,  86105,  86111,  86117, 
+     86124,  86129,  86135,  86141,  86148,  86154,  86161,  86168, 
+     86176,  86181,  86187,  86193,  86200,  86206,  86213,  86220, 
+     86228,  86234,  86241,  86248,  86256,  86263,  86271,  86279, 
+     86288,  86293,  86299,  86305,  86312,  86318,  86325,  86332, 
+     86340,  86346,  86353,  86360,  86368,  86375,  86383,  86391, 
+     86400,  86406,  86413,  86420,  86428,  86435,  86443,  86451, 
+     86460,  86467,  86475,  86483,  86492,  86500,  86509,  86518, 
+     86528,  86533,  86539,  86545,  86552,  86558,  86565,  86572, 
+     86580,  86586,  86593,  86600,  86608,  86615,  86623,  86631, 
+     86640,  86646,  86653,  86660,  86668,  86675,  86683,  86691, 
+     86700,  86707,  86715,  86723,  86732,  86740,  86749,  86758, 
+     86768,  86774,  86781,  86788,  86796,  86803,  86811,  86819, 
+     86828,  86835,  86843,  86851,  86860,  86868,  86877,  86886, 
+     86896,  86903,  86911,  86919,  86928,  86936,  86945,  86954, 
+     86964,  86972,  86981,  86990,  87000,  87009,  87019,  87029, 
+     87040,  87044,  87049,  87054,  87060,  87065,  87071,  87077, 
+     87084,  87089,  87095,  87101,  87108,  87114,  87121,  87128, 
+     87136,  87141,  87147,  87153,  87160,  87166,  87173,  87180, 
+     87188,  87194,  87201,  87208,  87216,  87223,  87231,  87239, 
+     87248,  87253,  87259,  87265,  87272,  87278,  87285,  87292, 
+     87300,  87306,  87313,  87320,  87328,  87335,  87343,  87351, 
+     87360,  87366,  87373,  87380,  87388,  87395,  87403,  87411, 
+     87420,  87427,  87435,  87443,  87452,  87460,  87469,  87478, 
+     87488,  87493,  87499,  87505,  87512,  87518,  87525,  87532, 
+     87540,  87546,  87553,  87560,  87568,  87575,  87583,  87591, 
+     87600,  87606,  87613,  87620,  87628,  87635,  87643,  87651, 
+     87660,  87667,  87675,  87683,  87692,  87700,  87709,  87718, 
+     87728,  87734,  87741,  87748,  87756,  87763,  87771,  87779, 
+     87788,  87795,  87803,  87811,  87820,  87828,  87837,  87846, 
+     87856,  87863,  87871,  87879,  87888,  87896,  87905,  87914, 
+     87924,  87932,  87941,  87950,  87960,  87969,  87979,  87989, 
+     88000,  88005,  88011,  88017,  88024,  88030,  88037,  88044, 
+     88052,  88058,  88065,  88072,  88080,  88087,  88095,  88103, 
+     88112,  88118,  88125,  88132,  88140,  88147,  88155,  88163, 
+     88172,  88179,  88187,  88195,  88204,  88212,  88221,  88230, 
+     88240,  88246,  88253,  88260,  88268,  88275,  88283,  88291, 
+     88300,  88307,  88315,  88323,  88332,  88340,  88349,  88358, 
+     88368,  88375,  88383,  88391,  88400,  88408,  88417,  88426, 
+     88436,  88444,  88453,  88462,  88472,  88481,  88491,  88501, 
+     88512,  88518,  88525,  88532,  88540,  88547,  88555,  88563, 
+     88572,  88579,  88587,  88595,  88604,  88612,  88621,  88630, 
+     88640,  88647,  88655,  88663,  88672,  88680,  88689,  88698, 
+     88708,  88716,  88725,  88734,  88744,  88753,  88763,  88773, 
+     88784,  88791,  88799,  88807,  88816,  88824,  88833,  88842, 
+     88852,  88860,  88869,  88878,  88888,  88897,  88907,  88917, 
+     88928,  88936,  88945,  88954,  88964,  88973,  88983,  88993, 
+     89004,  89013,  89023,  89033,  89044,  89054,  89065,  89076, 
+     89088,  89091,  89095,  89099,  89104,  89108,  89113,  89118, 
+     89124,  89128,  89133,  89138,  89144,  89149,  89155,  89161, 
+     89168,  89172,  89177,  89182,  89188,  89193,  89199,  89205, 
+     89212,  89217,  89223,  89229,  89236,  89242,  89249,  89256, 
+     89264,  89268,  89273,  89278,  89284,  89289,  89295,  89301, 
+     89308,  89313,  89319,  89325,  89332,  89338,  89345,  89352, 
+     89360,  89365,  89371,  89377,  89384,  89390,  89397,  89404, 
+     89412,  89418,  89425,  89432,  89440,  89447,  89455,  89463, 
+     89472,  89476,  89481,  89486,  89492,  89497,  89503,  89509, 
+     89516,  89521,  89527,  89533,  89540,  89546,  89553,  89560, 
+     89568,  89573,  89579,  89585,  89592,  89598,  89605,  89612, 
+     89620,  89626,  89633,  89640,  89648,  89655,  89663,  89671, 
+     89680,  89685,  89691,  89697,  89704,  89710,  89717,  89724, 
+     89732,  89738,  89745,  89752,  89760,  89767,  89775,  89783, 
+     89792,  89798,  89805,  89812,  89820,  89827,  89835,  89843, 
+     89852,  89859,  89867,  89875,  89884,  89892,  89901,  89910, 
+     89920,  89924,  89929,  89934,  89940,  89945,  89951,  89957, 
+     89964,  89969,  89975,  89981,  89988,  89994,  90001,  90008, 
+     90016,  90021,  90027,  90033,  90040,  90046,  90053,  90060, 
+     90068,  90074,  90081,  90088,  90096,  90103,  90111,  90119, 
+     90128,  90133,  90139,  90145,  90152,  90158,  90165,  90172, 
+     90180,  90186,  90193,  90200,  90208,  90215,  90223,  90231, 
+     90240,  90246,  90253,  90260,  90268,  90275,  90283,  90291, 
+     90300,  90307,  90315,  90323,  90332,  90340,  90349,  90358, 
+     90368,  90373,  90379,  90385,  90392,  90398,  90405,  90412, 
+     90420,  90426,  90433,  90440,  90448,  90455,  90463,  90471, 
+     90480,  90486,  90493,  90500,  90508,  90515,  90523,  90531, 
+     90540,  90547,  90555,  90563,  90572,  90580,  90589,  90598, 
+     90608,  90614,  90621,  90628,  90636,  90643,  90651,  90659, 
+     90668,  90675,  90683,  90691,  90700,  90708,  90717,  90726, 
+     90736,  90743,  90751,  90759,  90768,  90776,  90785,  90794, 
+     90804,  90812,  90821,  90830,  90840,  90849,  90859,  90869, 
+     90880,  90884,  90889,  90894,  90900,  90905,  90911,  90917, 
+     90924,  90929,  90935,  90941,  90948,  90954,  90961,  90968, 
+     90976,  90981,  90987,  90993,  91000,  91006,  91013,  91020, 
+     91028,  91034,  91041,  91048,  91056,  91063,  91071,  91079, 
+     91088,  91093,  91099,  91105,  91112,  91118,  91125,  91132, 
+     91140,  91146,  91153,  91160,  91168,  91175,  91183,  91191, 
+     91200,  91206,  91213,  91220,  91228,  91235,  91243,  91251, 
+     91260,  91267,  91275,  91283,  91292,  91300,  91309,  91318, 
+     91328,  91333,  91339,  91345,  91352,  91358,  91365,  91372, 
+     91380,  91386,  91393,  91400,  91408,  91415,  91423,  91431, 
+     91440,  91446,  91453,  91460,  91468,  91475,  91483,  91491, 
+     91500,  91507,  91515,  91523,  91532,  91540,  91549,  91558, 
+     91568,  91574,  91581,  91588,  91596,  91603,  91611,  91619, 
+     91628,  91635,  91643,  91651,  91660,  91668,  91677,  91686, 
+     91696,  91703,  91711,  91719,  91728,  91736,  91745,  91754, 
+     91764,  91772,  91781,  91790,  91800,  91809,  91819,  91829, 
+     91840,  91845,  91851,  91857,  91864,  91870,  91877,  91884, 
+     91892,  91898,  91905,  91912,  91920,  91927,  91935,  91943, 
+     91952,  91958,  91965,  91972,  91980,  91987,  91995,  92003, 
+     92012,  92019,  92027,  92035,  92044,  92052,  92061,  92070, 
+     92080,  92086,  92093,  92100,  92108,  92115,  92123,  92131, 
+     92140,  92147,  92155,  92163,  92172,  92180,  92189,  92198, 
+     92208,  92215,  92223,  92231,  92240,  92248,  92257,  92266, 
+     92276,  92284,  92293,  92302,  92312,  92321,  92331,  92341, 
+     92352,  92358,  92365,  92372,  92380,  92387,  92395,  92403, 
+     92412,  92419,  92427,  92435,  92444,  92452,  92461,  92470, 
+     92480,  92487,  92495,  92503,  92512,  92520,  92529,  92538, 
+     92548,  92556,  92565,  92574,  92584,  92593,  92603,  92613, 
+     92624,  92631,  92639,  92647,  92656,  92664,  92673,  92682, 
+     92692,  92700,  92709,  92718,  92728,  92737,  92747,  92757, 
+     92768,  92776,  92785,  92794,  92804,  92813,  92823,  92833, 
+     92844,  92853,  92863,  92873,  92884,  92894,  92905,  92916, 
+     92928,  92932,  92937,  92942,  92948,  92953,  92959,  92965, 
+     92972,  92977,  92983,  92989,  92996,  93002,  93009,  93016, 
+     93024,  93029,  93035,  93041,  93048,  93054,  93061,  93068, 
+     93076,  93082,  93089,  93096,  93104,  93111,  93119,  93127, 
+     93136,  93141,  93147,  93153,  93160,  93166,  93173,  93180, 
+     93188,  93194,  93201,  93208,  93216,  93223,  93231,  93239, 
+     93248,  93254,  93261,  93268,  93276,  93283,  93291,  93299, 
+     93308,  93315,  93323,  93331,  93340,  93348,  93357,  93366, 
+     93376,  93381,  93387,  93393,  93400,  93406,  93413,  93420, 
+     93428,  93434,  93441,  93448,  93456,  93463,  93471,  93479, 
+     93488,  93494,  93501,  93508,  93516,  93523,  93531,  93539, 
+     93548,  93555,  93563,  93571,  93580,  93588,  93597,  93606, 
+     93616,  93622,  93629,  93636,  93644,  93651,  93659,  93667, 
+     93676,  93683,  93691,  93699,  93708,  93716,  93725,  93734, 
+     93744,  93751,  93759,  93767,  93776,  93784,  93793,  93802, 
+     93812,  93820,  93829,  93838,  93848,  93857,  93867,  93877, 
+     93888,  93893,  93899,  93905,  93912,  93918,  93925,  93932, 
+     93940,  93946,  93953,  93960,  93968,  93975,  93983,  93991, 
+     94000,  94006,  94013,  94020,  94028,  94035,  94043,  94051, 
+     94060,  94067,  94075,  94083,  94092,  94100,  94109,  94118, 
+     94128,  94134,  94141,  94148,  94156,  94163,  94171,  94179, 
+     94188,  94195,  94203,  94211,  94220,  94228,  94237,  94246, 
+     94256,  94263,  94271,  94279,  94288,  94296,  94305,  94314, 
+     94324,  94332,  94341,  94350,  94360,  94369,  94379,  94389, 
+     94400,  94406,  94413,  94420,  94428,  94435,  94443,  94451, 
+     94460,  94467,  94475,  94483,  94492,  94500,  94509,  94518, 
+     94528,  94535,  94543,  94551,  94560,  94568,  94577,  94586, 
+     94596,  94604,  94613,  94622,  94632,  94641,  94651,  94661, 
+     94672,  94679,  94687,  94695,  94704,  94712,  94721,  94730, 
+     94740,  94748,  94757,  94766,  94776,  94785,  94795,  94805, 
+     94816,  94824,  94833,  94842,  94852,  94861,  94871,  94881, 
+     94892,  94901,  94911,  94921,  94932,  94942,  94953,  94964, 
+     94976,  94981,  94987,  94993,  95000,  95006,  95013,  95020, 
+     95028,  95034,  95041,  95048,  95056,  95063,  95071,  95079, 
+     95088,  95094,  95101,  95108,  95116,  95123,  95131,  95139, 
+     95148,  95155,  95163,  95171,  95180,  95188,  95197,  95206, 
+     95216,  95222,  95229,  95236,  95244,  95251,  95259,  95267, 
+     95276,  95283,  95291,  95299,  95308,  95316,  95325,  95334, 
+     95344,  95351,  95359,  95367,  95376,  95384,  95393,  95402, 
+     95412,  95420,  95429,  95438,  95448,  95457,  95467,  95477, 
+     95488,  95494,  95501,  95508,  95516,  95523,  95531,  95539, 
+     95548,  95555,  95563,  95571,  95580,  95588,  95597,  95606, 
+     95616,  95623,  95631,  95639,  95648,  95656,  95665,  95674, 
+     95684,  95692,  95701,  95710,  95720,  95729,  95739,  95749, 
+     95760,  95767,  95775,  95783,  95792,  95800,  95809,  95818, 
+     95828,  95836,  95845,  95854,  95864,  95873,  95883,  95893, 
+     95904,  95912,  95921,  95930,  95940,  95949,  95959,  95969, 
+     95980,  95989,  95999,  96009,  96020,  96030,  96041,  96052, 
+     96064,  96070,  96077,  96084,  96092,  96099,  96107,  96115, 
+     96124,  96131,  96139,  96147,  96156,  96164,  96173,  96182, 
+     96192,  96199,  96207,  96215,  96224,  96232,  96241,  96250, 
+     96260,  96268,  96277,  96286,  96296,  96305,  96315,  96325, 
+     96336,  96343,  96351,  96359,  96368,  96376,  96385,  96394, 
+     96404,  96412,  96421,  96430,  96440,  96449,  96459,  96469, 
+     96480,  96488,  96497,  96506,  96516,  96525,  96535,  96545, 
+     96556,  96565,  96575,  96585,  96596,  96606,  96617,  96628, 
+     96640,  96647,  96655,  96663,  96672,  96680,  96689,  96698, 
+     96708,  96716,  96725,  96734,  96744,  96753,  96763,  96773, 
+     96784,  96792,  96801,  96810,  96820,  96829,  96839,  96849, 
+     96860,  96869,  96879,  96889,  96900,  96910,  96921,  96932, 
+     96944,  96952,  96961,  96970,  96980,  96989,  96999,  97009, 
+     97020,  97029,  97039,  97049,  97060,  97070,  97081,  97092, 
+     97104,  97113,  97123,  97133,  97144,  97154,  97165,  97176, 
+     97188,  97198,  97209,  97220,  97232,  97243,  97255,  97267, 
+     97280,  97283,  97287,  97291,  97296,  97300,  97305,  97310, 
+     97316,  97320,  97325,  97330,  97336,  97341,  97347,  97353, 
+     97360,  97364,  97369,  97374,  97380,  97385,  97391,  97397, 
+     97404,  97409,  97415,  97421,  97428,  97434,  97441,  97448, 
+     97456,  97460,  97465,  97470,  97476,  97481,  97487,  97493, 
+     97500,  97505,  97511,  97517,  97524,  97530,  97537,  97544, 
+     97552,  97557,  97563,  97569,  97576,  97582,  97589,  97596, 
+     97604,  97610,  97617,  97624,  97632,  97639,  97647,  97655, 
+     97664,  97668,  97673,  97678,  97684,  97689,  97695,  97701, 
+     97708,  97713,  97719,  97725,  97732,  97738,  97745,  97752, 
+     97760,  97765,  97771,  97777,  97784,  97790,  97797,  97804, 
+     97812,  97818,  97825,  97832,  97840,  97847,  97855,  97863, 
+     97872,  97877,  97883,  97889,  97896,  97902,  97909,  97916, 
+     97924,  97930,  97937,  97944,  97952,  97959,  97967,  97975, 
+     97984,  97990,  97997,  98004,  98012,  98019,  98027,  98035, 
+     98044,  98051,  98059,  98067,  98076,  98084,  98093,  98102, 
+     98112,  98116,  98121,  98126,  98132,  98137,  98143,  98149, 
+     98156,  98161,  98167,  98173,  98180,  98186,  98193,  98200, 
+     98208,  98213,  98219,  98225,  98232,  98238,  98245,  98252, 
+     98260,  98266,  98273,  98280,  98288,  98295,  98303,  98311, 
+     98320,  98325,  98331,  98337,  98344,  98350,  98357,  98364, 
+     98372,  98378,  98385,  98392,  98400,  98407,  98415,  98423, 
+     98432,  98438,  98445,  98452,  98460,  98467,  98475,  98483, 
+     98492,  98499,  98507,  98515,  98524,  98532,  98541,  98550, 
+     98560,  98565,  98571,  98577,  98584,  98590,  98597,  98604, 
+     98612,  98618,  98625,  98632,  98640,  98647,  98655,  98663, 
+     98672,  98678,  98685,  98692,  98700,  98707,  98715,  98723, 
+     98732,  98739,  98747,  98755,  98764,  98772,  98781,  98790, 
+     98800,  98806,  98813,  98820,  98828,  98835,  98843,  98851, 
+     98860,  98867,  98875,  98883,  98892,  98900,  98909,  98918, 
+     98928,  98935,  98943,  98951,  98960,  98968,  98977,  98986, 
+     98996,  99004,  99013,  99022,  99032,  99041,  99051,  99061, 
+     99072,  99076,  99081,  99086,  99092,  99097,  99103,  99109, 
+     99116,  99121,  99127,  99133,  99140,  99146,  99153,  99160, 
+     99168,  99173,  99179,  99185,  99192,  99198,  99205,  99212, 
+     99220,  99226,  99233,  99240,  99248,  99255,  99263,  99271, 
+     99280,  99285,  99291,  99297,  99304,  99310,  99317,  99324, 
+     99332,  99338,  99345,  99352,  99360,  99367,  99375,  99383, 
+     99392,  99398,  99405,  99412,  99420,  99427,  99435,  99443, 
+     99452,  99459,  99467,  99475,  99484,  99492,  99501,  99510, 
+     99520,  99525,  99531,  99537,  99544,  99550,  99557,  99564, 
+     99572,  99578,  99585,  99592,  99600,  99607,  99615,  99623, 
+     99632,  99638,  99645,  99652,  99660,  99667,  99675,  99683, 
+     99692,  99699,  99707,  99715,  99724,  99732,  99741,  99750, 
+     99760,  99766,  99773,  99780,  99788,  99795,  99803,  99811, 
+     99820,  99827,  99835,  99843,  99852,  99860,  99869,  99878, 
+     99888,  99895,  99903,  99911,  99920,  99928,  99937,  99946, 
+     99956,  99964,  99973,  99982,  99992, 100001, 100011, 100021, 
+    100032, 100037, 100043, 100049, 100056, 100062, 100069, 100076, 
+    100084, 100090, 100097, 100104, 100112, 100119, 100127, 100135, 
+    100144, 100150, 100157, 100164, 100172, 100179, 100187, 100195, 
+    100204, 100211, 100219, 100227, 100236, 100244, 100253, 100262, 
+    100272, 100278, 100285, 100292, 100300, 100307, 100315, 100323, 
+    100332, 100339, 100347, 100355, 100364, 100372, 100381, 100390, 
+    100400, 100407, 100415, 100423, 100432, 100440, 100449, 100458, 
+    100468, 100476, 100485, 100494, 100504, 100513, 100523, 100533, 
+    100544, 100550, 100557, 100564, 100572, 100579, 100587, 100595, 
+    100604, 100611, 100619, 100627, 100636, 100644, 100653, 100662, 
+    100672, 100679, 100687, 100695, 100704, 100712, 100721, 100730, 
+    100740, 100748, 100757, 100766, 100776, 100785, 100795, 100805, 
+    100816, 100823, 100831, 100839, 100848, 100856, 100865, 100874, 
+    100884, 100892, 100901, 100910, 100920, 100929, 100939, 100949, 
+    100960, 100968, 100977, 100986, 100996, 101005, 101015, 101025, 
+    101036, 101045, 101055, 101065, 101076, 101086, 101097, 101108, 
+    101120, 101124, 101129, 101134, 101140, 101145, 101151, 101157, 
+    101164, 101169, 101175, 101181, 101188, 101194, 101201, 101208, 
+    101216, 101221, 101227, 101233, 101240, 101246, 101253, 101260, 
+    101268, 101274, 101281, 101288, 101296, 101303, 101311, 101319, 
+    101328, 101333, 101339, 101345, 101352, 101358, 101365, 101372, 
+    101380, 101386, 101393, 101400, 101408, 101415, 101423, 101431, 
+    101440, 101446, 101453, 101460, 101468, 101475, 101483, 101491, 
+    101500, 101507, 101515, 101523, 101532, 101540, 101549, 101558, 
+    101568, 101573, 101579, 101585, 101592, 101598, 101605, 101612, 
+    101620, 101626, 101633, 101640, 101648, 101655, 101663, 101671, 
+    101680, 101686, 101693, 101700, 101708, 101715, 101723, 101731, 
+    101740, 101747, 101755, 101763, 101772, 101780, 101789, 101798, 
+    101808, 101814, 101821, 101828, 101836, 101843, 101851, 101859, 
+    101868, 101875, 101883, 101891, 101900, 101908, 101917, 101926, 
+    101936, 101943, 101951, 101959, 101968, 101976, 101985, 101994, 
+    102004, 102012, 102021, 102030, 102040, 102049, 102059, 102069, 
+    102080, 102085, 102091, 102097, 102104, 102110, 102117, 102124, 
+    102132, 102138, 102145, 102152, 102160, 102167, 102175, 102183, 
+    102192, 102198, 102205, 102212, 102220, 102227, 102235, 102243, 
+    102252, 102259, 102267, 102275, 102284, 102292, 102301, 102310, 
+    102320, 102326, 102333, 102340, 102348, 102355, 102363, 102371, 
+    102380, 102387, 102395, 102403, 102412, 102420, 102429, 102438, 
+    102448, 102455, 102463, 102471, 102480, 102488, 102497, 102506, 
+    102516, 102524, 102533, 102542, 102552, 102561, 102571, 102581, 
+    102592, 102598, 102605, 102612, 102620, 102627, 102635, 102643, 
+    102652, 102659, 102667, 102675, 102684, 102692, 102701, 102710, 
+    102720, 102727, 102735, 102743, 102752, 102760, 102769, 102778, 
+    102788, 102796, 102805, 102814, 102824, 102833, 102843, 102853, 
+    102864, 102871, 102879, 102887, 102896, 102904, 102913, 102922, 
+    102932, 102940, 102949, 102958, 102968, 102977, 102987, 102997, 
+    103008, 103016, 103025, 103034, 103044, 103053, 103063, 103073, 
+    103084, 103093, 103103, 103113, 103124, 103134, 103145, 103156, 
+    103168, 103173, 103179, 103185, 103192, 103198, 103205, 103212, 
+    103220, 103226, 103233, 103240, 103248, 103255, 103263, 103271, 
+    103280, 103286, 103293, 103300, 103308, 103315, 103323, 103331, 
+    103340, 103347, 103355, 103363, 103372, 103380, 103389, 103398, 
+    103408, 103414, 103421, 103428, 103436, 103443, 103451, 103459, 
+    103468, 103475, 103483, 103491, 103500, 103508, 103517, 103526, 
+    103536, 103543, 103551, 103559, 103568, 103576, 103585, 103594, 
+    103604, 103612, 103621, 103630, 103640, 103649, 103659, 103669, 
+    103680, 103686, 103693, 103700, 103708, 103715, 103723, 103731, 
+    103740, 103747, 103755, 103763, 103772, 103780, 103789, 103798, 
+    103808, 103815, 103823, 103831, 103840, 103848, 103857, 103866, 
+    103876, 103884, 103893, 103902, 103912, 103921, 103931, 103941, 
+    103952, 103959, 103967, 103975, 103984, 103992, 104001, 104010, 
+    104020, 104028, 104037, 104046, 104056, 104065, 104075, 104085, 
+    104096, 104104, 104113, 104122, 104132, 104141, 104151, 104161, 
+    104172, 104181, 104191, 104201, 104212, 104222, 104233, 104244, 
+    104256, 104262, 104269, 104276, 104284, 104291, 104299, 104307, 
+    104316, 104323, 104331, 104339, 104348, 104356, 104365, 104374, 
+    104384, 104391, 104399, 104407, 104416, 104424, 104433, 104442, 
+    104452, 104460, 104469, 104478, 104488, 104497, 104507, 104517, 
+    104528, 104535, 104543, 104551, 104560, 104568, 104577, 104586, 
+    104596, 104604, 104613, 104622, 104632, 104641, 104651, 104661, 
+    104672, 104680, 104689, 104698, 104708, 104717, 104727, 104737, 
+    104748, 104757, 104767, 104777, 104788, 104798, 104809, 104820, 
+    104832, 104839, 104847, 104855, 104864, 104872, 104881, 104890, 
+    104900, 104908, 104917, 104926, 104936, 104945, 104955, 104965, 
+    104976, 104984, 104993, 105002, 105012, 105021, 105031, 105041, 
+    105052, 105061, 105071, 105081, 105092, 105102, 105113, 105124, 
+    105136, 105144, 105153, 105162, 105172, 105181, 105191, 105201, 
+    105212, 105221, 105231, 105241, 105252, 105262, 105273, 105284, 
+    105296, 105305, 105315, 105325, 105336, 105346, 105357, 105368, 
+    105380, 105390, 105401, 105412, 105424, 105435, 105447, 105459, 
+    105472, 105476, 105481, 105486, 105492, 105497, 105503, 105509, 
+    105516, 105521, 105527, 105533, 105540, 105546, 105553, 105560, 
+    105568, 105573, 105579, 105585, 105592, 105598, 105605, 105612, 
+    105620, 105626, 105633, 105640, 105648, 105655, 105663, 105671, 
+    105680, 105685, 105691, 105697, 105704, 105710, 105717, 105724, 
+    105732, 105738, 105745, 105752, 105760, 105767, 105775, 105783, 
+    105792, 105798, 105805, 105812, 105820, 105827, 105835, 105843, 
+    105852, 105859, 105867, 105875, 105884, 105892, 105901, 105910, 
+    105920, 105925, 105931, 105937, 105944, 105950, 105957, 105964, 
+    105972, 105978, 105985, 105992, 106000, 106007, 106015, 106023, 
+    106032, 106038, 106045, 106052, 106060, 106067, 106075, 106083, 
+    106092, 106099, 106107, 106115, 106124, 106132, 106141, 106150, 
+    106160, 106166, 106173, 106180, 106188, 106195, 106203, 106211, 
+    106220, 106227, 106235, 106243, 106252, 106260, 106269, 106278, 
+    106288, 106295, 106303, 106311, 106320, 106328, 106337, 106346, 
+    106356, 106364, 106373, 106382, 106392, 106401, 106411, 106421, 
+    106432, 106437, 106443, 106449, 106456, 106462, 106469, 106476, 
+    106484, 106490, 106497, 106504, 106512, 106519, 106527, 106535, 
+    106544, 106550, 106557, 106564, 106572, 106579, 106587, 106595, 
+    106604, 106611, 106619, 106627, 106636, 106644, 106653, 106662, 
+    106672, 106678, 106685, 106692, 106700, 106707, 106715, 106723, 
+    106732, 106739, 106747, 106755, 106764, 106772, 106781, 106790, 
+    106800, 106807, 106815, 106823, 106832, 106840, 106849, 106858, 
+    106868, 106876, 106885, 106894, 106904, 106913, 106923, 106933, 
+    106944, 106950, 106957, 106964, 106972, 106979, 106987, 106995, 
+    107004, 107011, 107019, 107027, 107036, 107044, 107053, 107062, 
+    107072, 107079, 107087, 107095, 107104, 107112, 107121, 107130, 
+    107140, 107148, 107157, 107166, 107176, 107185, 107195, 107205, 
+    107216, 107223, 107231, 107239, 107248, 107256, 107265, 107274, 
+    107284, 107292, 107301, 107310, 107320, 107329, 107339, 107349, 
+    107360, 107368, 107377, 107386, 107396, 107405, 107415, 107425, 
+    107436, 107445, 107455, 107465, 107476, 107486, 107497, 107508, 
+    107520, 107525, 107531, 107537, 107544, 107550, 107557, 107564, 
+    107572, 107578, 107585, 107592, 107600, 107607, 107615, 107623, 
+    107632, 107638, 107645, 107652, 107660, 107667, 107675, 107683, 
+    107692, 107699, 107707, 107715, 107724, 107732, 107741, 107750, 
+    107760, 107766, 107773, 107780, 107788, 107795, 107803, 107811, 
+    107820, 107827, 107835, 107843, 107852, 107860, 107869, 107878, 
+    107888, 107895, 107903, 107911, 107920, 107928, 107937, 107946, 
+    107956, 107964, 107973, 107982, 107992, 108001, 108011, 108021, 
+    108032, 108038, 108045, 108052, 108060, 108067, 108075, 108083, 
+    108092, 108099, 108107, 108115, 108124, 108132, 108141, 108150, 
+    108160, 108167, 108175, 108183, 108192, 108200, 108209, 108218, 
+    108228, 108236, 108245, 108254, 108264, 108273, 108283, 108293, 
+    108304, 108311, 108319, 108327, 108336, 108344, 108353, 108362, 
+    108372, 108380, 108389, 108398, 108408, 108417, 108427, 108437, 
+    108448, 108456, 108465, 108474, 108484, 108493, 108503, 108513, 
+    108524, 108533, 108543, 108553, 108564, 108574, 108585, 108596, 
+    108608, 108614, 108621, 108628, 108636, 108643, 108651, 108659, 
+    108668, 108675, 108683, 108691, 108700, 108708, 108717, 108726, 
+    108736, 108743, 108751, 108759, 108768, 108776, 108785, 108794, 
+    108804, 108812, 108821, 108830, 108840, 108849, 108859, 108869, 
+    108880, 108887, 108895, 108903, 108912, 108920, 108929, 108938, 
+    108948, 108956, 108965, 108974, 108984, 108993, 109003, 109013, 
+    109024, 109032, 109041, 109050, 109060, 109069, 109079, 109089, 
+    109100, 109109, 109119, 109129, 109140, 109150, 109161, 109172, 
+    109184, 109191, 109199, 109207, 109216, 109224, 109233, 109242, 
+    109252, 109260, 109269, 109278, 109288, 109297, 109307, 109317, 
+    109328, 109336, 109345, 109354, 109364, 109373, 109383, 109393, 
+    109404, 109413, 109423, 109433, 109444, 109454, 109465, 109476, 
+    109488, 109496, 109505, 109514, 109524, 109533, 109543, 109553, 
+    109564, 109573, 109583, 109593, 109604, 109614, 109625, 109636, 
+    109648, 109657, 109667, 109677, 109688, 109698, 109709, 109720, 
+    109732, 109742, 109753, 109764, 109776, 109787, 109799, 109811, 
+    109824, 109829, 109835, 109841, 109848, 109854, 109861, 109868, 
+    109876, 109882, 109889, 109896, 109904, 109911, 109919, 109927, 
+    109936, 109942, 109949, 109956, 109964, 109971, 109979, 109987, 
+    109996, 110003, 110011, 110019, 110028, 110036, 110045, 110054, 
+    110064, 110070, 110077, 110084, 110092, 110099, 110107, 110115, 
+    110124, 110131, 110139, 110147, 110156, 110164, 110173, 110182, 
+    110192, 110199, 110207, 110215, 110224, 110232, 110241, 110250, 
+    110260, 110268, 110277, 110286, 110296, 110305, 110315, 110325, 
+    110336, 110342, 110349, 110356, 110364, 110371, 110379, 110387, 
+    110396, 110403, 110411, 110419, 110428, 110436, 110445, 110454, 
+    110464, 110471, 110479, 110487, 110496, 110504, 110513, 110522, 
+    110532, 110540, 110549, 110558, 110568, 110577, 110587, 110597, 
+    110608, 110615, 110623, 110631, 110640, 110648, 110657, 110666, 
+    110676, 110684, 110693, 110702, 110712, 110721, 110731, 110741, 
+    110752, 110760, 110769, 110778, 110788, 110797, 110807, 110817, 
+    110828, 110837, 110847, 110857, 110868, 110878, 110889, 110900, 
+    110912, 110918, 110925, 110932, 110940, 110947, 110955, 110963, 
+    110972, 110979, 110987, 110995, 111004, 111012, 111021, 111030, 
+    111040, 111047, 111055, 111063, 111072, 111080, 111089, 111098, 
+    111108, 111116, 111125, 111134, 111144, 111153, 111163, 111173, 
+    111184, 111191, 111199, 111207, 111216, 111224, 111233, 111242, 
+    111252, 111260, 111269, 111278, 111288, 111297, 111307, 111317, 
+    111328, 111336, 111345, 111354, 111364, 111373, 111383, 111393, 
+    111404, 111413, 111423, 111433, 111444, 111454, 111465, 111476, 
+    111488, 111495, 111503, 111511, 111520, 111528, 111537, 111546, 
+    111556, 111564, 111573, 111582, 111592, 111601, 111611, 111621, 
+    111632, 111640, 111649, 111658, 111668, 111677, 111687, 111697, 
+    111708, 111717, 111727, 111737, 111748, 111758, 111769, 111780, 
+    111792, 111800, 111809, 111818, 111828, 111837, 111847, 111857, 
+    111868, 111877, 111887, 111897, 111908, 111918, 111929, 111940, 
+    111952, 111961, 111971, 111981, 111992, 112002, 112013, 112024, 
+    112036, 112046, 112057, 112068, 112080, 112091, 112103, 112115, 
+    112128, 112134, 112141, 112148, 112156, 112163, 112171, 112179, 
+    112188, 112195, 112203, 112211, 112220, 112228, 112237, 112246, 
+    112256, 112263, 112271, 112279, 112288, 112296, 112305, 112314, 
+    112324, 112332, 112341, 112350, 112360, 112369, 112379, 112389, 
+    112400, 112407, 112415, 112423, 112432, 112440, 112449, 112458, 
+    112468, 112476, 112485, 112494, 112504, 112513, 112523, 112533, 
+    112544, 112552, 112561, 112570, 112580, 112589, 112599, 112609, 
+    112620, 112629, 112639, 112649, 112660, 112670, 112681, 112692, 
+    112704, 112711, 112719, 112727, 112736, 112744, 112753, 112762, 
+    112772, 112780, 112789, 112798, 112808, 112817, 112827, 112837, 
+    112848, 112856, 112865, 112874, 112884, 112893, 112903, 112913, 
+    112924, 112933, 112943, 112953, 112964, 112974, 112985, 112996, 
+    113008, 113016, 113025, 113034, 113044, 113053, 113063, 113073, 
+    113084, 113093, 113103, 113113, 113124, 113134, 113145, 113156, 
+    113168, 113177, 113187, 113197, 113208, 113218, 113229, 113240, 
+    113252, 113262, 113273, 113284, 113296, 113307, 113319, 113331, 
+    113344, 113351, 113359, 113367, 113376, 113384, 113393, 113402, 
+    113412, 113420, 113429, 113438, 113448, 113457, 113467, 113477, 
+    113488, 113496, 113505, 113514, 113524, 113533, 113543, 113553, 
+    113564, 113573, 113583, 113593, 113604, 113614, 113625, 113636, 
+    113648, 113656, 113665, 113674, 113684, 113693, 113703, 113713, 
+    113724, 113733, 113743, 113753, 113764, 113774, 113785, 113796, 
+    113808, 113817, 113827, 113837, 113848, 113858, 113869, 113880, 
+    113892, 113902, 113913, 113924, 113936, 113947, 113959, 113971, 
+    113984, 113992, 114001, 114010, 114020, 114029, 114039, 114049, 
+    114060, 114069, 114079, 114089, 114100, 114110, 114121, 114132, 
+    114144, 114153, 114163, 114173, 114184, 114194, 114205, 114216, 
+    114228, 114238, 114249, 114260, 114272, 114283, 114295, 114307, 
+    114320, 114329, 114339, 114349, 114360, 114370, 114381, 114392, 
+    114404, 114414, 114425, 114436, 114448, 114459, 114471, 114483, 
+    114496, 114506, 114517, 114528, 114540, 114551, 114563, 114575, 
+    114588, 114599, 114611, 114623, 114636, 114648, 114661, 114674, 
+    114688, 114689, 114691, 114693, 114696, 114698, 114701, 114704, 
+    114708, 114710, 114713, 114716, 114720, 114723, 114727, 114731, 
+    114736, 114738, 114741, 114744, 114748, 114751, 114755, 114759, 
+    114764, 114767, 114771, 114775, 114780, 114784, 114789, 114794, 
+    114800, 114802, 114805, 114808, 114812, 114815, 114819, 114823, 
+    114828, 114831, 114835, 114839, 114844, 114848, 114853, 114858, 
+    114864, 114867, 114871, 114875, 114880, 114884, 114889, 114894, 
+    114900, 114904, 114909, 114914, 114920, 114925, 114931, 114937, 
+    114944, 114946, 114949, 114952, 114956, 114959, 114963, 114967, 
+    114972, 114975, 114979, 114983, 114988, 114992, 114997, 115002, 
+    115008, 115011, 115015, 115019, 115024, 115028, 115033, 115038, 
+    115044, 115048, 115053, 115058, 115064, 115069, 115075, 115081, 
+    115088, 115091, 115095, 115099, 115104, 115108, 115113, 115118, 
+    115124, 115128, 115133, 115138, 115144, 115149, 115155, 115161, 
+    115168, 115172, 115177, 115182, 115188, 115193, 115199, 115205, 
+    115212, 115217, 115223, 115229, 115236, 115242, 115249, 115256, 
+    115264, 115266, 115269, 115272, 115276, 115279, 115283, 115287, 
+    115292, 115295, 115299, 115303, 115308, 115312, 115317, 115322, 
+    115328, 115331, 115335, 115339, 115344, 115348, 115353, 115358, 
+    115364, 115368, 115373, 115378, 115384, 115389, 115395, 115401, 
+    115408, 115411, 115415, 115419, 115424, 115428, 115433, 115438, 
+    115444, 115448, 115453, 115458, 115464, 115469, 115475, 115481, 
+    115488, 115492, 115497, 115502, 115508, 115513, 115519, 115525, 
+    115532, 115537, 115543, 115549, 115556, 115562, 115569, 115576, 
+    115584, 115587, 115591, 115595, 115600, 115604, 115609, 115614, 
+    115620, 115624, 115629, 115634, 115640, 115645, 115651, 115657, 
+    115664, 115668, 115673, 115678, 115684, 115689, 115695, 115701, 
+    115708, 115713, 115719, 115725, 115732, 115738, 115745, 115752, 
+    115760, 115764, 115769, 115774, 115780, 115785, 115791, 115797, 
+    115804, 115809, 115815, 115821, 115828, 115834, 115841, 115848, 
+    115856, 115861, 115867, 115873, 115880, 115886, 115893, 115900, 
+    115908, 115914, 115921, 115928, 115936, 115943, 115951, 115959, 
+    115968, 115970, 115973, 115976, 115980, 115983, 115987, 115991, 
+    115996, 115999, 116003, 116007, 116012, 116016, 116021, 116026, 
+    116032, 116035, 116039, 116043, 116048, 116052, 116057, 116062, 
+    116068, 116072, 116077, 116082, 116088, 116093, 116099, 116105, 
+    116112, 116115, 116119, 116123, 116128, 116132, 116137, 116142, 
+    116148, 116152, 116157, 116162, 116168, 116173, 116179, 116185, 
+    116192, 116196, 116201, 116206, 116212, 116217, 116223, 116229, 
+    116236, 116241, 116247, 116253, 116260, 116266, 116273, 116280, 
+    116288, 116291, 116295, 116299, 116304, 116308, 116313, 116318, 
+    116324, 116328, 116333, 116338, 116344, 116349, 116355, 116361, 
+    116368, 116372, 116377, 116382, 116388, 116393, 116399, 116405, 
+    116412, 116417, 116423, 116429, 116436, 116442, 116449, 116456, 
+    116464, 116468, 116473, 116478, 116484, 116489, 116495, 116501, 
+    116508, 116513, 116519, 116525, 116532, 116538, 116545, 116552, 
+    116560, 116565, 116571, 116577, 116584, 116590, 116597, 116604, 
+    116612, 116618, 116625, 116632, 116640, 116647, 116655, 116663, 
+    116672, 116675, 116679, 116683, 116688, 116692, 116697, 116702, 
+    116708, 116712, 116717, 116722, 116728, 116733, 116739, 116745, 
+    116752, 116756, 116761, 116766, 116772, 116777, 116783, 116789, 
+    116796, 116801, 116807, 116813, 116820, 116826, 116833, 116840, 
+    116848, 116852, 116857, 116862, 116868, 116873, 116879, 116885, 
+    116892, 116897, 116903, 116909, 116916, 116922, 116929, 116936, 
+    116944, 116949, 116955, 116961, 116968, 116974, 116981, 116988, 
+    116996, 117002, 117009, 117016, 117024, 117031, 117039, 117047, 
+    117056, 117060, 117065, 117070, 117076, 117081, 117087, 117093, 
+    117100, 117105, 117111, 117117, 117124, 117130, 117137, 117144, 
+    117152, 117157, 117163, 117169, 117176, 117182, 117189, 117196, 
+    117204, 117210, 117217, 117224, 117232, 117239, 117247, 117255, 
+    117264, 117269, 117275, 117281, 117288, 117294, 117301, 117308, 
+    117316, 117322, 117329, 117336, 117344, 117351, 117359, 117367, 
+    117376, 117382, 117389, 117396, 117404, 117411, 117419, 117427, 
+    117436, 117443, 117451, 117459, 117468, 117476, 117485, 117494, 
+    117504, 117506, 117509, 117512, 117516, 117519, 117523, 117527, 
+    117532, 117535, 117539, 117543, 117548, 117552, 117557, 117562, 
+    117568, 117571, 117575, 117579, 117584, 117588, 117593, 117598, 
+    117604, 117608, 117613, 117618, 117624, 117629, 117635, 117641, 
+    117648, 117651, 117655, 117659, 117664, 117668, 117673, 117678, 
+    117684, 117688, 117693, 117698, 117704, 117709, 117715, 117721, 
+    117728, 117732, 117737, 117742, 117748, 117753, 117759, 117765, 
+    117772, 117777, 117783, 117789, 117796, 117802, 117809, 117816, 
+    117824, 117827, 117831, 117835, 117840, 117844, 117849, 117854, 
+    117860, 117864, 117869, 117874, 117880, 117885, 117891, 117897, 
+    117904, 117908, 117913, 117918, 117924, 117929, 117935, 117941, 
+    117948, 117953, 117959, 117965, 117972, 117978, 117985, 117992, 
+    118000, 118004, 118009, 118014, 118020, 118025, 118031, 118037, 
+    118044, 118049, 118055, 118061, 118068, 118074, 118081, 118088, 
+    118096, 118101, 118107, 118113, 118120, 118126, 118133, 118140, 
+    118148, 118154, 118161, 118168, 118176, 118183, 118191, 118199, 
+    118208, 118211, 118215, 118219, 118224, 118228, 118233, 118238, 
+    118244, 118248, 118253, 118258, 118264, 118269, 118275, 118281, 
+    118288, 118292, 118297, 118302, 118308, 118313, 118319, 118325, 
+    118332, 118337, 118343, 118349, 118356, 118362, 118369, 118376, 
+    118384, 118388, 118393, 118398, 118404, 118409, 118415, 118421, 
+    118428, 118433, 118439, 118445, 118452, 118458, 118465, 118472, 
+    118480, 118485, 118491, 118497, 118504, 118510, 118517, 118524, 
+    118532, 118538, 118545, 118552, 118560, 118567, 118575, 118583, 
+    118592, 118596, 118601, 118606, 118612, 118617, 118623, 118629, 
+    118636, 118641, 118647, 118653, 118660, 118666, 118673, 118680, 
+    118688, 118693, 118699, 118705, 118712, 118718, 118725, 118732, 
+    118740, 118746, 118753, 118760, 118768, 118775, 118783, 118791, 
+    118800, 118805, 118811, 118817, 118824, 118830, 118837, 118844, 
+    118852, 118858, 118865, 118872, 118880, 118887, 118895, 118903, 
+    118912, 118918, 118925, 118932, 118940, 118947, 118955, 118963, 
+    118972, 118979, 118987, 118995, 119004, 119012, 119021, 119030, 
+    119040, 119043, 119047, 119051, 119056, 119060, 119065, 119070, 
+    119076, 119080, 119085, 119090, 119096, 119101, 119107, 119113, 
+    119120, 119124, 119129, 119134, 119140, 119145, 119151, 119157, 
+    119164, 119169, 119175, 119181, 119188, 119194, 119201, 119208, 
+    119216, 119220, 119225, 119230, 119236, 119241, 119247, 119253, 
+    119260, 119265, 119271, 119277, 119284, 119290, 119297, 119304, 
+    119312, 119317, 119323, 119329, 119336, 119342, 119349, 119356, 
+    119364, 119370, 119377, 119384, 119392, 119399, 119407, 119415, 
+    119424, 119428, 119433, 119438, 119444, 119449, 119455, 119461, 
+    119468, 119473, 119479, 119485, 119492, 119498, 119505, 119512, 
+    119520, 119525, 119531, 119537, 119544, 119550, 119557, 119564, 
+    119572, 119578, 119585, 119592, 119600, 119607, 119615, 119623, 
+    119632, 119637, 119643, 119649, 119656, 119662, 119669, 119676, 
+    119684, 119690, 119697, 119704, 119712, 119719, 119727, 119735, 
+    119744, 119750, 119757, 119764, 119772, 119779, 119787, 119795, 
+    119804, 119811, 119819, 119827, 119836, 119844, 119853, 119862, 
+    119872, 119876, 119881, 119886, 119892, 119897, 119903, 119909, 
+    119916, 119921, 119927, 119933, 119940, 119946, 119953, 119960, 
+    119968, 119973, 119979, 119985, 119992, 119998, 120005, 120012, 
+    120020, 120026, 120033, 120040, 120048, 120055, 120063, 120071, 
+    120080, 120085, 120091, 120097, 120104, 120110, 120117, 120124, 
+    120132, 120138, 120145, 120152, 120160, 120167, 120175, 120183, 
+    120192, 120198, 120205, 120212, 120220, 120227, 120235, 120243, 
+    120252, 120259, 120267, 120275, 120284, 120292, 120301, 120310, 
+    120320, 120325, 120331, 120337, 120344, 120350, 120357, 120364, 
+    120372, 120378, 120385, 120392, 120400, 120407, 120415, 120423, 
+    120432, 120438, 120445, 120452, 120460, 120467, 120475, 120483, 
+    120492, 120499, 120507, 120515, 120524, 120532, 120541, 120550, 
+    120560, 120566, 120573, 120580, 120588, 120595, 120603, 120611, 
+    120620, 120627, 120635, 120643, 120652, 120660, 120669, 120678, 
+    120688, 120695, 120703, 120711, 120720, 120728, 120737, 120746, 
+    120756, 120764, 120773, 120782, 120792, 120801, 120811, 120821, 
+    120832, 120834, 120837, 120840, 120844, 120847, 120851, 120855, 
+    120860, 120863, 120867, 120871, 120876, 120880, 120885, 120890, 
+    120896, 120899, 120903, 120907, 120912, 120916, 120921, 120926, 
+    120932, 120936, 120941, 120946, 120952, 120957, 120963, 120969, 
+    120976, 120979, 120983, 120987, 120992, 120996, 121001, 121006, 
+    121012, 121016, 121021, 121026, 121032, 121037, 121043, 121049, 
+    121056, 121060, 121065, 121070, 121076, 121081, 121087, 121093, 
+    121100, 121105, 121111, 121117, 121124, 121130, 121137, 121144, 
+    121152, 121155, 121159, 121163, 121168, 121172, 121177, 121182, 
+    121188, 121192, 121197, 121202, 121208, 121213, 121219, 121225, 
+    121232, 121236, 121241, 121246, 121252, 121257, 121263, 121269, 
+    121276, 121281, 121287, 121293, 121300, 121306, 121313, 121320, 
+    121328, 121332, 121337, 121342, 121348, 121353, 121359, 121365, 
+    121372, 121377, 121383, 121389, 121396, 121402, 121409, 121416, 
+    121424, 121429, 121435, 121441, 121448, 121454, 121461, 121468, 
+    121476, 121482, 121489, 121496, 121504, 121511, 121519, 121527, 
+    121536, 121539, 121543, 121547, 121552, 121556, 121561, 121566, 
+    121572, 121576, 121581, 121586, 121592, 121597, 121603, 121609, 
+    121616, 121620, 121625, 121630, 121636, 121641, 121647, 121653, 
+    121660, 121665, 121671, 121677, 121684, 121690, 121697, 121704, 
+    121712, 121716, 121721, 121726, 121732, 121737, 121743, 121749, 
+    121756, 121761, 121767, 121773, 121780, 121786, 121793, 121800, 
+    121808, 121813, 121819, 121825, 121832, 121838, 121845, 121852, 
+    121860, 121866, 121873, 121880, 121888, 121895, 121903, 121911, 
+    121920, 121924, 121929, 121934, 121940, 121945, 121951, 121957, 
+    121964, 121969, 121975, 121981, 121988, 121994, 122001, 122008, 
+    122016, 122021, 122027, 122033, 122040, 122046, 122053, 122060, 
+    122068, 122074, 122081, 122088, 122096, 122103, 122111, 122119, 
+    122128, 122133, 122139, 122145, 122152, 122158, 122165, 122172, 
+    122180, 122186, 122193, 122200, 122208, 122215, 122223, 122231, 
+    122240, 122246, 122253, 122260, 122268, 122275, 122283, 122291, 
+    122300, 122307, 122315, 122323, 122332, 122340, 122349, 122358, 
+    122368, 122371, 122375, 122379, 122384, 122388, 122393, 122398, 
+    122404, 122408, 122413, 122418, 122424, 122429, 122435, 122441, 
+    122448, 122452, 122457, 122462, 122468, 122473, 122479, 122485, 
+    122492, 122497, 122503, 122509, 122516, 122522, 122529, 122536, 
+    122544, 122548, 122553, 122558, 122564, 122569, 122575, 122581, 
+    122588, 122593, 122599, 122605, 122612, 122618, 122625, 122632, 
+    122640, 122645, 122651, 122657, 122664, 122670, 122677, 122684, 
+    122692, 122698, 122705, 122712, 122720, 122727, 122735, 122743, 
+    122752, 122756, 122761, 122766, 122772, 122777, 122783, 122789, 
+    122796, 122801, 122807, 122813, 122820, 122826, 122833, 122840, 
+    122848, 122853, 122859, 122865, 122872, 122878, 122885, 122892, 
+    122900, 122906, 122913, 122920, 122928, 122935, 122943, 122951, 
+    122960, 122965, 122971, 122977, 122984, 122990, 122997, 123004, 
+    123012, 123018, 123025, 123032, 123040, 123047, 123055, 123063, 
+    123072, 123078, 123085, 123092, 123100, 123107, 123115, 123123, 
+    123132, 123139, 123147, 123155, 123164, 123172, 123181, 123190, 
+    123200, 123204, 123209, 123214, 123220, 123225, 123231, 123237, 
+    123244, 123249, 123255, 123261, 123268, 123274, 123281, 123288, 
+    123296, 123301, 123307, 123313, 123320, 123326, 123333, 123340, 
+    123348, 123354, 123361, 123368, 123376, 123383, 123391, 123399, 
+    123408, 123413, 123419, 123425, 123432, 123438, 123445, 123452, 
+    123460, 123466, 123473, 123480, 123488, 123495, 123503, 123511, 
+    123520, 123526, 123533, 123540, 123548, 123555, 123563, 123571, 
+    123580, 123587, 123595, 123603, 123612, 123620, 123629, 123638, 
+    123648, 123653, 123659, 123665, 123672, 123678, 123685, 123692, 
+    123700, 123706, 123713, 123720, 123728, 123735, 123743, 123751, 
+    123760, 123766, 123773, 123780, 123788, 123795, 123803, 123811, 
+    123820, 123827, 123835, 123843, 123852, 123860, 123869, 123878, 
+    123888, 123894, 123901, 123908, 123916, 123923, 123931, 123939, 
+    123948, 123955, 123963, 123971, 123980, 123988, 123997, 124006, 
+    124016, 124023, 124031, 124039, 124048, 124056, 124065, 124074, 
+    124084, 124092, 124101, 124110, 124120, 124129, 124139, 124149, 
+    124160, 124163, 124167, 124171, 124176, 124180, 124185, 124190, 
+    124196, 124200, 124205, 124210, 124216, 124221, 124227, 124233, 
+    124240, 124244, 124249, 124254, 124260, 124265, 124271, 124277, 
+    124284, 124289, 124295, 124301, 124308, 124314, 124321, 124328, 
+    124336, 124340, 124345, 124350, 124356, 124361, 124367, 124373, 
+    124380, 124385, 124391, 124397, 124404, 124410, 124417, 124424, 
+    124432, 124437, 124443, 124449, 124456, 124462, 124469, 124476, 
+    124484, 124490, 124497, 124504, 124512, 124519, 124527, 124535, 
+    124544, 124548, 124553, 124558, 124564, 124569, 124575, 124581, 
+    124588, 124593, 124599, 124605, 124612, 124618, 124625, 124632, 
+    124640, 124645, 124651, 124657, 124664, 124670, 124677, 124684, 
+    124692, 124698, 124705, 124712, 124720, 124727, 124735, 124743, 
+    124752, 124757, 124763, 124769, 124776, 124782, 124789, 124796, 
+    124804, 124810, 124817, 124824, 124832, 124839, 124847, 124855, 
+    124864, 124870, 124877, 124884, 124892, 124899, 124907, 124915, 
+    124924, 124931, 124939, 124947, 124956, 124964, 124973, 124982, 
+    124992, 124996, 125001, 125006, 125012, 125017, 125023, 125029, 
+    125036, 125041, 125047, 125053, 125060, 125066, 125073, 125080, 
+    125088, 125093, 125099, 125105, 125112, 125118, 125125, 125132, 
+    125140, 125146, 125153, 125160, 125168, 125175, 125183, 125191, 
+    125200, 125205, 125211, 125217, 125224, 125230, 125237, 125244, 
+    125252, 125258, 125265, 125272, 125280, 125287, 125295, 125303, 
+    125312, 125318, 125325, 125332, 125340, 125347, 125355, 125363, 
+    125372, 125379, 125387, 125395, 125404, 125412, 125421, 125430, 
+    125440, 125445, 125451, 125457, 125464, 125470, 125477, 125484, 
+    125492, 125498, 125505, 125512, 125520, 125527, 125535, 125543, 
+    125552, 125558, 125565, 125572, 125580, 125587, 125595, 125603, 
+    125612, 125619, 125627, 125635, 125644, 125652, 125661, 125670, 
+    125680, 125686, 125693, 125700, 125708, 125715, 125723, 125731, 
+    125740, 125747, 125755, 125763, 125772, 125780, 125789, 125798, 
+    125808, 125815, 125823, 125831, 125840, 125848, 125857, 125866, 
+    125876, 125884, 125893, 125902, 125912, 125921, 125931, 125941, 
+    125952, 125956, 125961, 125966, 125972, 125977, 125983, 125989, 
+    125996, 126001, 126007, 126013, 126020, 126026, 126033, 126040, 
+    126048, 126053, 126059, 126065, 126072, 126078, 126085, 126092, 
+    126100, 126106, 126113, 126120, 126128, 126135, 126143, 126151, 
+    126160, 126165, 126171, 126177, 126184, 126190, 126197, 126204, 
+    126212, 126218, 126225, 126232, 126240, 126247, 126255, 126263, 
+    126272, 126278, 126285, 126292, 126300, 126307, 126315, 126323, 
+    126332, 126339, 126347, 126355, 126364, 126372, 126381, 126390, 
+    126400, 126405, 126411, 126417, 126424, 126430, 126437, 126444, 
+    126452, 126458, 126465, 126472, 126480, 126487, 126495, 126503, 
+    126512, 126518, 126525, 126532, 126540, 126547, 126555, 126563, 
+    126572, 126579, 126587, 126595, 126604, 126612, 126621, 126630, 
+    126640, 126646, 126653, 126660, 126668, 126675, 126683, 126691, 
+    126700, 126707, 126715, 126723, 126732, 126740, 126749, 126758, 
+    126768, 126775, 126783, 126791, 126800, 126808, 126817, 126826, 
+    126836, 126844, 126853, 126862, 126872, 126881, 126891, 126901, 
+    126912, 126917, 126923, 126929, 126936, 126942, 126949, 126956, 
+    126964, 126970, 126977, 126984, 126992, 126999, 127007, 127015, 
+    127024, 127030, 127037, 127044, 127052, 127059, 127067, 127075, 
+    127084, 127091, 127099, 127107, 127116, 127124, 127133, 127142, 
+    127152, 127158, 127165, 127172, 127180, 127187, 127195, 127203, 
+    127212, 127219, 127227, 127235, 127244, 127252, 127261, 127270, 
+    127280, 127287, 127295, 127303, 127312, 127320, 127329, 127338, 
+    127348, 127356, 127365, 127374, 127384, 127393, 127403, 127413, 
+    127424, 127430, 127437, 127444, 127452, 127459, 127467, 127475, 
+    127484, 127491, 127499, 127507, 127516, 127524, 127533, 127542, 
+    127552, 127559, 127567, 127575, 127584, 127592, 127601, 127610, 
+    127620, 127628, 127637, 127646, 127656, 127665, 127675, 127685, 
+    127696, 127703, 127711, 127719, 127728, 127736, 127745, 127754, 
+    127764, 127772, 127781, 127790, 127800, 127809, 127819, 127829, 
+    127840, 127848, 127857, 127866, 127876, 127885, 127895, 127905, 
+    127916, 127925, 127935, 127945, 127956, 127966, 127977, 127988, 
+    128000, 128002, 128005, 128008, 128012, 128015, 128019, 128023, 
+    128028, 128031, 128035, 128039, 128044, 128048, 128053, 128058, 
+    128064, 128067, 128071, 128075, 128080, 128084, 128089, 128094, 
+    128100, 128104, 128109, 128114, 128120, 128125, 128131, 128137, 
+    128144, 128147, 128151, 128155, 128160, 128164, 128169, 128174, 
+    128180, 128184, 128189, 128194, 128200, 128205, 128211, 128217, 
+    128224, 128228, 128233, 128238, 128244, 128249, 128255, 128261, 
+    128268, 128273, 128279, 128285, 128292, 128298, 128305, 128312, 
+    128320, 128323, 128327, 128331, 128336, 128340, 128345, 128350, 
+    128356, 128360, 128365, 128370, 128376, 128381, 128387, 128393, 
+    128400, 128404, 128409, 128414, 128420, 128425, 128431, 128437, 
+    128444, 128449, 128455, 128461, 128468, 128474, 128481, 128488, 
+    128496, 128500, 128505, 128510, 128516, 128521, 128527, 128533, 
+    128540, 128545, 128551, 128557, 128564, 128570, 128577, 128584, 
+    128592, 128597, 128603, 128609, 128616, 128622, 128629, 128636, 
+    128644, 128650, 128657, 128664, 128672, 128679, 128687, 128695, 
+    128704, 128707, 128711, 128715, 128720, 128724, 128729, 128734, 
+    128740, 128744, 128749, 128754, 128760, 128765, 128771, 128777, 
+    128784, 128788, 128793, 128798, 128804, 128809, 128815, 128821, 
+    128828, 128833, 128839, 128845, 128852, 128858, 128865, 128872, 
+    128880, 128884, 128889, 128894, 128900, 128905, 128911, 128917, 
+    128924, 128929, 128935, 128941, 128948, 128954, 128961, 128968, 
+    128976, 128981, 128987, 128993, 129000, 129006, 129013, 129020, 
+    129028, 129034, 129041, 129048, 129056, 129063, 129071, 129079, 
+    129088, 129092, 129097, 129102, 129108, 129113, 129119, 129125, 
+    129132, 129137, 129143, 129149, 129156, 129162, 129169, 129176, 
+    129184, 129189, 129195, 129201, 129208, 129214, 129221, 129228, 
+    129236, 129242, 129249, 129256, 129264, 129271, 129279, 129287, 
+    129296, 129301, 129307, 129313, 129320, 129326, 129333, 129340, 
+    129348, 129354, 129361, 129368, 129376, 129383, 129391, 129399, 
+    129408, 129414, 129421, 129428, 129436, 129443, 129451, 129459, 
+    129468, 129475, 129483, 129491, 129500, 129508, 129517, 129526, 
+    129536, 129539, 129543, 129547, 129552, 129556, 129561, 129566, 
+    129572, 129576, 129581, 129586, 129592, 129597, 129603, 129609, 
+    129616, 129620, 129625, 129630, 129636, 129641, 129647, 129653, 
+    129660, 129665, 129671, 129677, 129684, 129690, 129697, 129704, 
+    129712, 129716, 129721, 129726, 129732, 129737, 129743, 129749, 
+    129756, 129761, 129767, 129773, 129780, 129786, 129793, 129800, 
+    129808, 129813, 129819, 129825, 129832, 129838, 129845, 129852, 
+    129860, 129866, 129873, 129880, 129888, 129895, 129903, 129911, 
+    129920, 129924, 129929, 129934, 129940, 129945, 129951, 129957, 
+    129964, 129969, 129975, 129981, 129988, 129994, 130001, 130008, 
+    130016, 130021, 130027, 130033, 130040, 130046, 130053, 130060, 
+    130068, 130074, 130081, 130088, 130096, 130103, 130111, 130119, 
+    130128, 130133, 130139, 130145, 130152, 130158, 130165, 130172, 
+    130180, 130186, 130193, 130200, 130208, 130215, 130223, 130231, 
+    130240, 130246, 130253, 130260, 130268, 130275, 130283, 130291, 
+    130300, 130307, 130315, 130323, 130332, 130340, 130349, 130358, 
+    130368, 130372, 130377, 130382, 130388, 130393, 130399, 130405, 
+    130412, 130417, 130423, 130429, 130436, 130442, 130449, 130456, 
+    130464, 130469, 130475, 130481, 130488, 130494, 130501, 130508, 
+    130516, 130522, 130529, 130536, 130544, 130551, 130559, 130567, 
+    130576, 130581, 130587, 130593, 130600, 130606, 130613, 130620, 
+    130628, 130634, 130641, 130648, 130656, 130663, 130671, 130679, 
+    130688, 130694, 130701, 130708, 130716, 130723, 130731, 130739, 
+    130748, 130755, 130763, 130771, 130780, 130788, 130797, 130806, 
+    130816, 130821, 130827, 130833, 130840, 130846, 130853, 130860, 
+    130868, 130874, 130881, 130888, 130896, 130903, 130911, 130919, 
+    130928, 130934, 130941, 130948, 130956, 130963, 130971, 130979, 
+    130988, 130995, 131003, 131011, 131020, 131028, 131037, 131046, 
+    131056, 131062, 131069, 131076, 131084, 131091, 131099, 131107, 
+    131116, 131123, 131131, 131139, 131148, 131156, 131165, 131174, 
+    131184, 131191, 131199, 131207, 131216, 131224, 131233, 131242, 
+    131252, 131260, 131269, 131278, 131288, 131297, 131307, 131317, 
+    131328, 131331, 131335, 131339, 131344, 131348, 131353, 131358, 
+    131364, 131368, 131373, 131378, 131384, 131389, 131395, 131401, 
+    131408, 131412, 131417, 131422, 131428, 131433, 131439, 131445, 
+    131452, 131457, 131463, 131469, 131476, 131482, 131489, 131496, 
+    131504, 131508, 131513, 131518, 131524, 131529, 131535, 131541, 
+    131548, 131553, 131559, 131565, 131572, 131578, 131585, 131592, 
+    131600, 131605, 131611, 131617, 131624, 131630, 131637, 131644, 
+    131652, 131658, 131665, 131672, 131680, 131687, 131695, 131703, 
+    131712, 131716, 131721, 131726, 131732, 131737, 131743, 131749, 
+    131756, 131761, 131767, 131773, 131780, 131786, 131793, 131800, 
+    131808, 131813, 131819, 131825, 131832, 131838, 131845, 131852, 
+    131860, 131866, 131873, 131880, 131888, 131895, 131903, 131911, 
+    131920, 131925, 131931, 131937, 131944, 131950, 131957, 131964, 
+    131972, 131978, 131985, 131992, 132000, 132007, 132015, 132023, 
+    132032, 132038, 132045, 132052, 132060, 132067, 132075, 132083, 
+    132092, 132099, 132107, 132115, 132124, 132132, 132141, 132150, 
+    132160, 132164, 132169, 132174, 132180, 132185, 132191, 132197, 
+    132204, 132209, 132215, 132221, 132228, 132234, 132241, 132248, 
+    132256, 132261, 132267, 132273, 132280, 132286, 132293, 132300, 
+    132308, 132314, 132321, 132328, 132336, 132343, 132351, 132359, 
+    132368, 132373, 132379, 132385, 132392, 132398, 132405, 132412, 
+    132420, 132426, 132433, 132440, 132448, 132455, 132463, 132471, 
+    132480, 132486, 132493, 132500, 132508, 132515, 132523, 132531, 
+    132540, 132547, 132555, 132563, 132572, 132580, 132589, 132598, 
+    132608, 132613, 132619, 132625, 132632, 132638, 132645, 132652, 
+    132660, 132666, 132673, 132680, 132688, 132695, 132703, 132711, 
+    132720, 132726, 132733, 132740, 132748, 132755, 132763, 132771, 
+    132780, 132787, 132795, 132803, 132812, 132820, 132829, 132838, 
+    132848, 132854, 132861, 132868, 132876, 132883, 132891, 132899, 
+    132908, 132915, 132923, 132931, 132940, 132948, 132957, 132966, 
+    132976, 132983, 132991, 132999, 133008, 133016, 133025, 133034, 
+    133044, 133052, 133061, 133070, 133080, 133089, 133099, 133109, 
+    133120, 133124, 133129, 133134, 133140, 133145, 133151, 133157, 
+    133164, 133169, 133175, 133181, 133188, 133194, 133201, 133208, 
+    133216, 133221, 133227, 133233, 133240, 133246, 133253, 133260, 
+    133268, 133274, 133281, 133288, 133296, 133303, 133311, 133319, 
+    133328, 133333, 133339, 133345, 133352, 133358, 133365, 133372, 
+    133380, 133386, 133393, 133400, 133408, 133415, 133423, 133431, 
+    133440, 133446, 133453, 133460, 133468, 133475, 133483, 133491, 
+    133500, 133507, 133515, 133523, 133532, 133540, 133549, 133558, 
+    133568, 133573, 133579, 133585, 133592, 133598, 133605, 133612, 
+    133620, 133626, 133633, 133640, 133648, 133655, 133663, 133671, 
+    133680, 133686, 133693, 133700, 133708, 133715, 133723, 133731, 
+    133740, 133747, 133755, 133763, 133772, 133780, 133789, 133798, 
+    133808, 133814, 133821, 133828, 133836, 133843, 133851, 133859, 
+    133868, 133875, 133883, 133891, 133900, 133908, 133917, 133926, 
+    133936, 133943, 133951, 133959, 133968, 133976, 133985, 133994, 
+    134004, 134012, 134021, 134030, 134040, 134049, 134059, 134069, 
+    134080, 134085, 134091, 134097, 134104, 134110, 134117, 134124, 
+    134132, 134138, 134145, 134152, 134160, 134167, 134175, 134183, 
+    134192, 134198, 134205, 134212, 134220, 134227, 134235, 134243, 
+    134252, 134259, 134267, 134275, 134284, 134292, 134301, 134310, 
+    134320, 134326, 134333, 134340, 134348, 134355, 134363, 134371, 
+    134380, 134387, 134395, 134403, 134412, 134420, 134429, 134438, 
+    134448, 134455, 134463, 134471, 134480, 134488, 134497, 134506, 
+    134516, 134524, 134533, 134542, 134552, 134561, 134571, 134581, 
+    134592, 134598, 134605, 134612, 134620, 134627, 134635, 134643, 
+    134652, 134659, 134667, 134675, 134684, 134692, 134701, 134710, 
+    134720, 134727, 134735, 134743, 134752, 134760, 134769, 134778, 
+    134788, 134796, 134805, 134814, 134824, 134833, 134843, 134853, 
+    134864, 134871, 134879, 134887, 134896, 134904, 134913, 134922, 
+    134932, 134940, 134949, 134958, 134968, 134977, 134987, 134997, 
+    135008, 135016, 135025, 135034, 135044, 135053, 135063, 135073, 
+    135084, 135093, 135103, 135113, 135124, 135134, 135145, 135156, 
+    135168, 135171, 135175, 135179, 135184, 135188, 135193, 135198, 
+    135204, 135208, 135213, 135218, 135224, 135229, 135235, 135241, 
+    135248, 135252, 135257, 135262, 135268, 135273, 135279, 135285, 
+    135292, 135297, 135303, 135309, 135316, 135322, 135329, 135336, 
+    135344, 135348, 135353, 135358, 135364, 135369, 135375, 135381, 
+    135388, 135393, 135399, 135405, 135412, 135418, 135425, 135432, 
+    135440, 135445, 135451, 135457, 135464, 135470, 135477, 135484, 
+    135492, 135498, 135505, 135512, 135520, 135527, 135535, 135543, 
+    135552, 135556, 135561, 135566, 135572, 135577, 135583, 135589, 
+    135596, 135601, 135607, 135613, 135620, 135626, 135633, 135640, 
+    135648, 135653, 135659, 135665, 135672, 135678, 135685, 135692, 
+    135700, 135706, 135713, 135720, 135728, 135735, 135743, 135751, 
+    135760, 135765, 135771, 135777, 135784, 135790, 135797, 135804, 
+    135812, 135818, 135825, 135832, 135840, 135847, 135855, 135863, 
+    135872, 135878, 135885, 135892, 135900, 135907, 135915, 135923, 
+    135932, 135939, 135947, 135955, 135964, 135972, 135981, 135990, 
+    136000, 136004, 136009, 136014, 136020, 136025, 136031, 136037, 
+    136044, 136049, 136055, 136061, 136068, 136074, 136081, 136088, 
+    136096, 136101, 136107, 136113, 136120, 136126, 136133, 136140, 
+    136148, 136154, 136161, 136168, 136176, 136183, 136191, 136199, 
+    136208, 136213, 136219, 136225, 136232, 136238, 136245, 136252, 
+    136260, 136266, 136273, 136280, 136288, 136295, 136303, 136311, 
+    136320, 136326, 136333, 136340, 136348, 136355, 136363, 136371, 
+    136380, 136387, 136395, 136403, 136412, 136420, 136429, 136438, 
+    136448, 136453, 136459, 136465, 136472, 136478, 136485, 136492, 
+    136500, 136506, 136513, 136520, 136528, 136535, 136543, 136551, 
+    136560, 136566, 136573, 136580, 136588, 136595, 136603, 136611, 
+    136620, 136627, 136635, 136643, 136652, 136660, 136669, 136678, 
+    136688, 136694, 136701, 136708, 136716, 136723, 136731, 136739, 
+    136748, 136755, 136763, 136771, 136780, 136788, 136797, 136806, 
+    136816, 136823, 136831, 136839, 136848, 136856, 136865, 136874, 
+    136884, 136892, 136901, 136910, 136920, 136929, 136939, 136949, 
+    136960, 136964, 136969, 136974, 136980, 136985, 136991, 136997, 
+    137004, 137009, 137015, 137021, 137028, 137034, 137041, 137048, 
+    137056, 137061, 137067, 137073, 137080, 137086, 137093, 137100, 
+    137108, 137114, 137121, 137128, 137136, 137143, 137151, 137159, 
+    137168, 137173, 137179, 137185, 137192, 137198, 137205, 137212, 
+    137220, 137226, 137233, 137240, 137248, 137255, 137263, 137271, 
+    137280, 137286, 137293, 137300, 137308, 137315, 137323, 137331, 
+    137340, 137347, 137355, 137363, 137372, 137380, 137389, 137398, 
+    137408, 137413, 137419, 137425, 137432, 137438, 137445, 137452, 
+    137460, 137466, 137473, 137480, 137488, 137495, 137503, 137511, 
+    137520, 137526, 137533, 137540, 137548, 137555, 137563, 137571, 
+    137580, 137587, 137595, 137603, 137612, 137620, 137629, 137638, 
+    137648, 137654, 137661, 137668, 137676, 137683, 137691, 137699, 
+    137708, 137715, 137723, 137731, 137740, 137748, 137757, 137766, 
+    137776, 137783, 137791, 137799, 137808, 137816, 137825, 137834, 
+    137844, 137852, 137861, 137870, 137880, 137889, 137899, 137909, 
+    137920, 137925, 137931, 137937, 137944, 137950, 137957, 137964, 
+    137972, 137978, 137985, 137992, 138000, 138007, 138015, 138023, 
+    138032, 138038, 138045, 138052, 138060, 138067, 138075, 138083, 
+    138092, 138099, 138107, 138115, 138124, 138132, 138141, 138150, 
+    138160, 138166, 138173, 138180, 138188, 138195, 138203, 138211, 
+    138220, 138227, 138235, 138243, 138252, 138260, 138269, 138278, 
+    138288, 138295, 138303, 138311, 138320, 138328, 138337, 138346, 
+    138356, 138364, 138373, 138382, 138392, 138401, 138411, 138421, 
+    138432, 138438, 138445, 138452, 138460, 138467, 138475, 138483, 
+    138492, 138499, 138507, 138515, 138524, 138532, 138541, 138550, 
+    138560, 138567, 138575, 138583, 138592, 138600, 138609, 138618, 
+    138628, 138636, 138645, 138654, 138664, 138673, 138683, 138693, 
+    138704, 138711, 138719, 138727, 138736, 138744, 138753, 138762, 
+    138772, 138780, 138789, 138798, 138808, 138817, 138827, 138837, 
+    138848, 138856, 138865, 138874, 138884, 138893, 138903, 138913, 
+    138924, 138933, 138943, 138953, 138964, 138974, 138985, 138996, 
+    139008, 139012, 139017, 139022, 139028, 139033, 139039, 139045, 
+    139052, 139057, 139063, 139069, 139076, 139082, 139089, 139096, 
+    139104, 139109, 139115, 139121, 139128, 139134, 139141, 139148, 
+    139156, 139162, 139169, 139176, 139184, 139191, 139199, 139207, 
+    139216, 139221, 139227, 139233, 139240, 139246, 139253, 139260, 
+    139268, 139274, 139281, 139288, 139296, 139303, 139311, 139319, 
+    139328, 139334, 139341, 139348, 139356, 139363, 139371, 139379, 
+    139388, 139395, 139403, 139411, 139420, 139428, 139437, 139446, 
+    139456, 139461, 139467, 139473, 139480, 139486, 139493, 139500, 
+    139508, 139514, 139521, 139528, 139536, 139543, 139551, 139559, 
+    139568, 139574, 139581, 139588, 139596, 139603, 139611, 139619, 
+    139628, 139635, 139643, 139651, 139660, 139668, 139677, 139686, 
+    139696, 139702, 139709, 139716, 139724, 139731, 139739, 139747, 
+    139756, 139763, 139771, 139779, 139788, 139796, 139805, 139814, 
+    139824, 139831, 139839, 139847, 139856, 139864, 139873, 139882, 
+    139892, 139900, 139909, 139918, 139928, 139937, 139947, 139957, 
+    139968, 139973, 139979, 139985, 139992, 139998, 140005, 140012, 
+    140020, 140026, 140033, 140040, 140048, 140055, 140063, 140071, 
+    140080, 140086, 140093, 140100, 140108, 140115, 140123, 140131, 
+    140140, 140147, 140155, 140163, 140172, 140180, 140189, 140198, 
+    140208, 140214, 140221, 140228, 140236, 140243, 140251, 140259, 
+    140268, 140275, 140283, 140291, 140300, 140308, 140317, 140326, 
+    140336, 140343, 140351, 140359, 140368, 140376, 140385, 140394, 
+    140404, 140412, 140421, 140430, 140440, 140449, 140459, 140469, 
+    140480, 140486, 140493, 140500, 140508, 140515, 140523, 140531, 
+    140540, 140547, 140555, 140563, 140572, 140580, 140589, 140598, 
+    140608, 140615, 140623, 140631, 140640, 140648, 140657, 140666, 
+    140676, 140684, 140693, 140702, 140712, 140721, 140731, 140741, 
+    140752, 140759, 140767, 140775, 140784, 140792, 140801, 140810, 
+    140820, 140828, 140837, 140846, 140856, 140865, 140875, 140885, 
+    140896, 140904, 140913, 140922, 140932, 140941, 140951, 140961, 
+    140972, 140981, 140991, 141001, 141012, 141022, 141033, 141044, 
+    141056, 141061, 141067, 141073, 141080, 141086, 141093, 141100, 
+    141108, 141114, 141121, 141128, 141136, 141143, 141151, 141159, 
+    141168, 141174, 141181, 141188, 141196, 141203, 141211, 141219, 
+    141228, 141235, 141243, 141251, 141260, 141268, 141277, 141286, 
+    141296, 141302, 141309, 141316, 141324, 141331, 141339, 141347, 
+    141356, 141363, 141371, 141379, 141388, 141396, 141405, 141414, 
+    141424, 141431, 141439, 141447, 141456, 141464, 141473, 141482, 
+    141492, 141500, 141509, 141518, 141528, 141537, 141547, 141557, 
+    141568, 141574, 141581, 141588, 141596, 141603, 141611, 141619, 
+    141628, 141635, 141643, 141651, 141660, 141668, 141677, 141686, 
+    141696, 141703, 141711, 141719, 141728, 141736, 141745, 141754, 
+    141764, 141772, 141781, 141790, 141800, 141809, 141819, 141829, 
+    141840, 141847, 141855, 141863, 141872, 141880, 141889, 141898, 
+    141908, 141916, 141925, 141934, 141944, 141953, 141963, 141973, 
+    141984, 141992, 142001, 142010, 142020, 142029, 142039, 142049, 
+    142060, 142069, 142079, 142089, 142100, 142110, 142121, 142132, 
+    142144, 142150, 142157, 142164, 142172, 142179, 142187, 142195, 
+    142204, 142211, 142219, 142227, 142236, 142244, 142253, 142262, 
+    142272, 142279, 142287, 142295, 142304, 142312, 142321, 142330, 
+    142340, 142348, 142357, 142366, 142376, 142385, 142395, 142405, 
+    142416, 142423, 142431, 142439, 142448, 142456, 142465, 142474, 
+    142484, 142492, 142501, 142510, 142520, 142529, 142539, 142549, 
+    142560, 142568, 142577, 142586, 142596, 142605, 142615, 142625, 
+    142636, 142645, 142655, 142665, 142676, 142686, 142697, 142708, 
+    142720, 142727, 142735, 142743, 142752, 142760, 142769, 142778, 
+    142788, 142796, 142805, 142814, 142824, 142833, 142843, 142853, 
+    142864, 142872, 142881, 142890, 142900, 142909, 142919, 142929, 
+    142940, 142949, 142959, 142969, 142980, 142990, 143001, 143012, 
+    143024, 143032, 143041, 143050, 143060, 143069, 143079, 143089, 
+    143100, 143109, 143119, 143129, 143140, 143150, 143161, 143172, 
+    143184, 143193, 143203, 143213, 143224, 143234, 143245, 143256, 
+    143268, 143278, 143289, 143300, 143312, 143323, 143335, 143347, 
+    143360, 143362, 143365, 143368, 143372, 143375, 143379, 143383, 
+    143388, 143391, 143395, 143399, 143404, 143408, 143413, 143418, 
+    143424, 143427, 143431, 143435, 143440, 143444, 143449, 143454, 
+    143460, 143464, 143469, 143474, 143480, 143485, 143491, 143497, 
+    143504, 143507, 143511, 143515, 143520, 143524, 143529, 143534, 
+    143540, 143544, 143549, 143554, 143560, 143565, 143571, 143577, 
+    143584, 143588, 143593, 143598, 143604, 143609, 143615, 143621, 
+    143628, 143633, 143639, 143645, 143652, 143658, 143665, 143672, 
+    143680, 143683, 143687, 143691, 143696, 143700, 143705, 143710, 
+    143716, 143720, 143725, 143730, 143736, 143741, 143747, 143753, 
+    143760, 143764, 143769, 143774, 143780, 143785, 143791, 143797, 
+    143804, 143809, 143815, 143821, 143828, 143834, 143841, 143848, 
+    143856, 143860, 143865, 143870, 143876, 143881, 143887, 143893, 
+    143900, 143905, 143911, 143917, 143924, 143930, 143937, 143944, 
+    143952, 143957, 143963, 143969, 143976, 143982, 143989, 143996, 
+    144004, 144010, 144017, 144024, 144032, 144039, 144047, 144055, 
+    144064, 144067, 144071, 144075, 144080, 144084, 144089, 144094, 
+    144100, 144104, 144109, 144114, 144120, 144125, 144131, 144137, 
+    144144, 144148, 144153, 144158, 144164, 144169, 144175, 144181, 
+    144188, 144193, 144199, 144205, 144212, 144218, 144225, 144232, 
+    144240, 144244, 144249, 144254, 144260, 144265, 144271, 144277, 
+    144284, 144289, 144295, 144301, 144308, 144314, 144321, 144328, 
+    144336, 144341, 144347, 144353, 144360, 144366, 144373, 144380, 
+    144388, 144394, 144401, 144408, 144416, 144423, 144431, 144439, 
+    144448, 144452, 144457, 144462, 144468, 144473, 144479, 144485, 
+    144492, 144497, 144503, 144509, 144516, 144522, 144529, 144536, 
+    144544, 144549, 144555, 144561, 144568, 144574, 144581, 144588, 
+    144596, 144602, 144609, 144616, 144624, 144631, 144639, 144647, 
+    144656, 144661, 144667, 144673, 144680, 144686, 144693, 144700, 
+    144708, 144714, 144721, 144728, 144736, 144743, 144751, 144759, 
+    144768, 144774, 144781, 144788, 144796, 144803, 144811, 144819, 
+    144828, 144835, 144843, 144851, 144860, 144868, 144877, 144886, 
+    144896, 144899, 144903, 144907, 144912, 144916, 144921, 144926, 
+    144932, 144936, 144941, 144946, 144952, 144957, 144963, 144969, 
+    144976, 144980, 144985, 144990, 144996, 145001, 145007, 145013, 
+    145020, 145025, 145031, 145037, 145044, 145050, 145057, 145064, 
+    145072, 145076, 145081, 145086, 145092, 145097, 145103, 145109, 
+    145116, 145121, 145127, 145133, 145140, 145146, 145153, 145160, 
+    145168, 145173, 145179, 145185, 145192, 145198, 145205, 145212, 
+    145220, 145226, 145233, 145240, 145248, 145255, 145263, 145271, 
+    145280, 145284, 145289, 145294, 145300, 145305, 145311, 145317, 
+    145324, 145329, 145335, 145341, 145348, 145354, 145361, 145368, 
+    145376, 145381, 145387, 145393, 145400, 145406, 145413, 145420, 
+    145428, 145434, 145441, 145448, 145456, 145463, 145471, 145479, 
+    145488, 145493, 145499, 145505, 145512, 145518, 145525, 145532, 
+    145540, 145546, 145553, 145560, 145568, 145575, 145583, 145591, 
+    145600, 145606, 145613, 145620, 145628, 145635, 145643, 145651, 
+    145660, 145667, 145675, 145683, 145692, 145700, 145709, 145718, 
+    145728, 145732, 145737, 145742, 145748, 145753, 145759, 145765, 
+    145772, 145777, 145783, 145789, 145796, 145802, 145809, 145816, 
+    145824, 145829, 145835, 145841, 145848, 145854, 145861, 145868, 
+    145876, 145882, 145889, 145896, 145904, 145911, 145919, 145927, 
+    145936, 145941, 145947, 145953, 145960, 145966, 145973, 145980, 
+    145988, 145994, 146001, 146008, 146016, 146023, 146031, 146039, 
+    146048, 146054, 146061, 146068, 146076, 146083, 146091, 146099, 
+    146108, 146115, 146123, 146131, 146140, 146148, 146157, 146166, 
+    146176, 146181, 146187, 146193, 146200, 146206, 146213, 146220, 
+    146228, 146234, 146241, 146248, 146256, 146263, 146271, 146279, 
+    146288, 146294, 146301, 146308, 146316, 146323, 146331, 146339, 
+    146348, 146355, 146363, 146371, 146380, 146388, 146397, 146406, 
+    146416, 146422, 146429, 146436, 146444, 146451, 146459, 146467, 
+    146476, 146483, 146491, 146499, 146508, 146516, 146525, 146534, 
+    146544, 146551, 146559, 146567, 146576, 146584, 146593, 146602, 
+    146612, 146620, 146629, 146638, 146648, 146657, 146667, 146677, 
+    146688, 146691, 146695, 146699, 146704, 146708, 146713, 146718, 
+    146724, 146728, 146733, 146738, 146744, 146749, 146755, 146761, 
+    146768, 146772, 146777, 146782, 146788, 146793, 146799, 146805, 
+    146812, 146817, 146823, 146829, 146836, 146842, 146849, 146856, 
+    146864, 146868, 146873, 146878, 146884, 146889, 146895, 146901, 
+    146908, 146913, 146919, 146925, 146932, 146938, 146945, 146952, 
+    146960, 146965, 146971, 146977, 146984, 146990, 146997, 147004, 
+    147012, 147018, 147025, 147032, 147040, 147047, 147055, 147063, 
+    147072, 147076, 147081, 147086, 147092, 147097, 147103, 147109, 
+    147116, 147121, 147127, 147133, 147140, 147146, 147153, 147160, 
+    147168, 147173, 147179, 147185, 147192, 147198, 147205, 147212, 
+    147220, 147226, 147233, 147240, 147248, 147255, 147263, 147271, 
+    147280, 147285, 147291, 147297, 147304, 147310, 147317, 147324, 
+    147332, 147338, 147345, 147352, 147360, 147367, 147375, 147383, 
+    147392, 147398, 147405, 147412, 147420, 147427, 147435, 147443, 
+    147452, 147459, 147467, 147475, 147484, 147492, 147501, 147510, 
+    147520, 147524, 147529, 147534, 147540, 147545, 147551, 147557, 
+    147564, 147569, 147575, 147581, 147588, 147594, 147601, 147608, 
+    147616, 147621, 147627, 147633, 147640, 147646, 147653, 147660, 
+    147668, 147674, 147681, 147688, 147696, 147703, 147711, 147719, 
+    147728, 147733, 147739, 147745, 147752, 147758, 147765, 147772, 
+    147780, 147786, 147793, 147800, 147808, 147815, 147823, 147831, 
+    147840, 147846, 147853, 147860, 147868, 147875, 147883, 147891, 
+    147900, 147907, 147915, 147923, 147932, 147940, 147949, 147958, 
+    147968, 147973, 147979, 147985, 147992, 147998, 148005, 148012, 
+    148020, 148026, 148033, 148040, 148048, 148055, 148063, 148071, 
+    148080, 148086, 148093, 148100, 148108, 148115, 148123, 148131, 
+    148140, 148147, 148155, 148163, 148172, 148180, 148189, 148198, 
+    148208, 148214, 148221, 148228, 148236, 148243, 148251, 148259, 
+    148268, 148275, 148283, 148291, 148300, 148308, 148317, 148326, 
+    148336, 148343, 148351, 148359, 148368, 148376, 148385, 148394, 
+    148404, 148412, 148421, 148430, 148440, 148449, 148459, 148469, 
+    148480, 148484, 148489, 148494, 148500, 148505, 148511, 148517, 
+    148524, 148529, 148535, 148541, 148548, 148554, 148561, 148568, 
+    148576, 148581, 148587, 148593, 148600, 148606, 148613, 148620, 
+    148628, 148634, 148641, 148648, 148656, 148663, 148671, 148679, 
+    148688, 148693, 148699, 148705, 148712, 148718, 148725, 148732, 
+    148740, 148746, 148753, 148760, 148768, 148775, 148783, 148791, 
+    148800, 148806, 148813, 148820, 148828, 148835, 148843, 148851, 
+    148860, 148867, 148875, 148883, 148892, 148900, 148909, 148918, 
+    148928, 148933, 148939, 148945, 148952, 148958, 148965, 148972, 
+    148980, 148986, 148993, 149000, 149008, 149015, 149023, 149031, 
+    149040, 149046, 149053, 149060, 149068, 149075, 149083, 149091, 
+    149100, 149107, 149115, 149123, 149132, 149140, 149149, 149158, 
+    149168, 149174, 149181, 149188, 149196, 149203, 149211, 149219, 
+    149228, 149235, 149243, 149251, 149260, 149268, 149277, 149286, 
+    149296, 149303, 149311, 149319, 149328, 149336, 149345, 149354, 
+    149364, 149372, 149381, 149390, 149400, 149409, 149419, 149429, 
+    149440, 149445, 149451, 149457, 149464, 149470, 149477, 149484, 
+    149492, 149498, 149505, 149512, 149520, 149527, 149535, 149543, 
+    149552, 149558, 149565, 149572, 149580, 149587, 149595, 149603, 
+    149612, 149619, 149627, 149635, 149644, 149652, 149661, 149670, 
+    149680, 149686, 149693, 149700, 149708, 149715, 149723, 149731, 
+    149740, 149747, 149755, 149763, 149772, 149780, 149789, 149798, 
+    149808, 149815, 149823, 149831, 149840, 149848, 149857, 149866, 
+    149876, 149884, 149893, 149902, 149912, 149921, 149931, 149941, 
+    149952, 149958, 149965, 149972, 149980, 149987, 149995, 150003, 
+    150012, 150019, 150027, 150035, 150044, 150052, 150061, 150070, 
+    150080, 150087, 150095, 150103, 150112, 150120, 150129, 150138, 
+    150148, 150156, 150165, 150174, 150184, 150193, 150203, 150213, 
+    150224, 150231, 150239, 150247, 150256, 150264, 150273, 150282, 
+    150292, 150300, 150309, 150318, 150328, 150337, 150347, 150357, 
+    150368, 150376, 150385, 150394, 150404, 150413, 150423, 150433, 
+    150444, 150453, 150463, 150473, 150484, 150494, 150505, 150516, 
+    150528, 150531, 150535, 150539, 150544, 150548, 150553, 150558, 
+    150564, 150568, 150573, 150578, 150584, 150589, 150595, 150601, 
+    150608, 150612, 150617, 150622, 150628, 150633, 150639, 150645, 
+    150652, 150657, 150663, 150669, 150676, 150682, 150689, 150696, 
+    150704, 150708, 150713, 150718, 150724, 150729, 150735, 150741, 
+    150748, 150753, 150759, 150765, 150772, 150778, 150785, 150792, 
+    150800, 150805, 150811, 150817, 150824, 150830, 150837, 150844, 
+    150852, 150858, 150865, 150872, 150880, 150887, 150895, 150903, 
+    150912, 150916, 150921, 150926, 150932, 150937, 150943, 150949, 
+    150956, 150961, 150967, 150973, 150980, 150986, 150993, 151000, 
+    151008, 151013, 151019, 151025, 151032, 151038, 151045, 151052, 
+    151060, 151066, 151073, 151080, 151088, 151095, 151103, 151111, 
+    151120, 151125, 151131, 151137, 151144, 151150, 151157, 151164, 
+    151172, 151178, 151185, 151192, 151200, 151207, 151215, 151223, 
+    151232, 151238, 151245, 151252, 151260, 151267, 151275, 151283, 
+    151292, 151299, 151307, 151315, 151324, 151332, 151341, 151350, 
+    151360, 151364, 151369, 151374, 151380, 151385, 151391, 151397, 
+    151404, 151409, 151415, 151421, 151428, 151434, 151441, 151448, 
+    151456, 151461, 151467, 151473, 151480, 151486, 151493, 151500, 
+    151508, 151514, 151521, 151528, 151536, 151543, 151551, 151559, 
+    151568, 151573, 151579, 151585, 151592, 151598, 151605, 151612, 
+    151620, 151626, 151633, 151640, 151648, 151655, 151663, 151671, 
+    151680, 151686, 151693, 151700, 151708, 151715, 151723, 151731, 
+    151740, 151747, 151755, 151763, 151772, 151780, 151789, 151798, 
+    151808, 151813, 151819, 151825, 151832, 151838, 151845, 151852, 
+    151860, 151866, 151873, 151880, 151888, 151895, 151903, 151911, 
+    151920, 151926, 151933, 151940, 151948, 151955, 151963, 151971, 
+    151980, 151987, 151995, 152003, 152012, 152020, 152029, 152038, 
+    152048, 152054, 152061, 152068, 152076, 152083, 152091, 152099, 
+    152108, 152115, 152123, 152131, 152140, 152148, 152157, 152166, 
+    152176, 152183, 152191, 152199, 152208, 152216, 152225, 152234, 
+    152244, 152252, 152261, 152270, 152280, 152289, 152299, 152309, 
+    152320, 152324, 152329, 152334, 152340, 152345, 152351, 152357, 
+    152364, 152369, 152375, 152381, 152388, 152394, 152401, 152408, 
+    152416, 152421, 152427, 152433, 152440, 152446, 152453, 152460, 
+    152468, 152474, 152481, 152488, 152496, 152503, 152511, 152519, 
+    152528, 152533, 152539, 152545, 152552, 152558, 152565, 152572, 
+    152580, 152586, 152593, 152600, 152608, 152615, 152623, 152631, 
+    152640, 152646, 152653, 152660, 152668, 152675, 152683, 152691, 
+    152700, 152707, 152715, 152723, 152732, 152740, 152749, 152758, 
+    152768, 152773, 152779, 152785, 152792, 152798, 152805, 152812, 
+    152820, 152826, 152833, 152840, 152848, 152855, 152863, 152871, 
+    152880, 152886, 152893, 152900, 152908, 152915, 152923, 152931, 
+    152940, 152947, 152955, 152963, 152972, 152980, 152989, 152998, 
+    153008, 153014, 153021, 153028, 153036, 153043, 153051, 153059, 
+    153068, 153075, 153083, 153091, 153100, 153108, 153117, 153126, 
+    153136, 153143, 153151, 153159, 153168, 153176, 153185, 153194, 
+    153204, 153212, 153221, 153230, 153240, 153249, 153259, 153269, 
+    153280, 153285, 153291, 153297, 153304, 153310, 153317, 153324, 
+    153332, 153338, 153345, 153352, 153360, 153367, 153375, 153383, 
+    153392, 153398, 153405, 153412, 153420, 153427, 153435, 153443, 
+    153452, 153459, 153467, 153475, 153484, 153492, 153501, 153510, 
+    153520, 153526, 153533, 153540, 153548, 153555, 153563, 153571, 
+    153580, 153587, 153595, 153603, 153612, 153620, 153629, 153638, 
+    153648, 153655, 153663, 153671, 153680, 153688, 153697, 153706, 
+    153716, 153724, 153733, 153742, 153752, 153761, 153771, 153781, 
+    153792, 153798, 153805, 153812, 153820, 153827, 153835, 153843, 
+    153852, 153859, 153867, 153875, 153884, 153892, 153901, 153910, 
+    153920, 153927, 153935, 153943, 153952, 153960, 153969, 153978, 
+    153988, 153996, 154005, 154014, 154024, 154033, 154043, 154053, 
+    154064, 154071, 154079, 154087, 154096, 154104, 154113, 154122, 
+    154132, 154140, 154149, 154158, 154168, 154177, 154187, 154197, 
+    154208, 154216, 154225, 154234, 154244, 154253, 154263, 154273, 
+    154284, 154293, 154303, 154313, 154324, 154334, 154345, 154356, 
+    154368, 154372, 154377, 154382, 154388, 154393, 154399, 154405, 
+    154412, 154417, 154423, 154429, 154436, 154442, 154449, 154456, 
+    154464, 154469, 154475, 154481, 154488, 154494, 154501, 154508, 
+    154516, 154522, 154529, 154536, 154544, 154551, 154559, 154567, 
+    154576, 154581, 154587, 154593, 154600, 154606, 154613, 154620, 
+    154628, 154634, 154641, 154648, 154656, 154663, 154671, 154679, 
+    154688, 154694, 154701, 154708, 154716, 154723, 154731, 154739, 
+    154748, 154755, 154763, 154771, 154780, 154788, 154797, 154806, 
+    154816, 154821, 154827, 154833, 154840, 154846, 154853, 154860, 
+    154868, 154874, 154881, 154888, 154896, 154903, 154911, 154919, 
+    154928, 154934, 154941, 154948, 154956, 154963, 154971, 154979, 
+    154988, 154995, 155003, 155011, 155020, 155028, 155037, 155046, 
+    155056, 155062, 155069, 155076, 155084, 155091, 155099, 155107, 
+    155116, 155123, 155131, 155139, 155148, 155156, 155165, 155174, 
+    155184, 155191, 155199, 155207, 155216, 155224, 155233, 155242, 
+    155252, 155260, 155269, 155278, 155288, 155297, 155307, 155317, 
+    155328, 155333, 155339, 155345, 155352, 155358, 155365, 155372, 
+    155380, 155386, 155393, 155400, 155408, 155415, 155423, 155431, 
+    155440, 155446, 155453, 155460, 155468, 155475, 155483, 155491, 
+    155500, 155507, 155515, 155523, 155532, 155540, 155549, 155558, 
+    155568, 155574, 155581, 155588, 155596, 155603, 155611, 155619, 
+    155628, 155635, 155643, 155651, 155660, 155668, 155677, 155686, 
+    155696, 155703, 155711, 155719, 155728, 155736, 155745, 155754, 
+    155764, 155772, 155781, 155790, 155800, 155809, 155819, 155829, 
+    155840, 155846, 155853, 155860, 155868, 155875, 155883, 155891, 
+    155900, 155907, 155915, 155923, 155932, 155940, 155949, 155958, 
+    155968, 155975, 155983, 155991, 156000, 156008, 156017, 156026, 
+    156036, 156044, 156053, 156062, 156072, 156081, 156091, 156101, 
+    156112, 156119, 156127, 156135, 156144, 156152, 156161, 156170, 
+    156180, 156188, 156197, 156206, 156216, 156225, 156235, 156245, 
+    156256, 156264, 156273, 156282, 156292, 156301, 156311, 156321, 
+    156332, 156341, 156351, 156361, 156372, 156382, 156393, 156404, 
+    156416, 156421, 156427, 156433, 156440, 156446, 156453, 156460, 
+    156468, 156474, 156481, 156488, 156496, 156503, 156511, 156519, 
+    156528, 156534, 156541, 156548, 156556, 156563, 156571, 156579, 
+    156588, 156595, 156603, 156611, 156620, 156628, 156637, 156646, 
+    156656, 156662, 156669, 156676, 156684, 156691, 156699, 156707, 
+    156716, 156723, 156731, 156739, 156748, 156756, 156765, 156774, 
+    156784, 156791, 156799, 156807, 156816, 156824, 156833, 156842, 
+    156852, 156860, 156869, 156878, 156888, 156897, 156907, 156917, 
+    156928, 156934, 156941, 156948, 156956, 156963, 156971, 156979, 
+    156988, 156995, 157003, 157011, 157020, 157028, 157037, 157046, 
+    157056, 157063, 157071, 157079, 157088, 157096, 157105, 157114, 
+    157124, 157132, 157141, 157150, 157160, 157169, 157179, 157189, 
+    157200, 157207, 157215, 157223, 157232, 157240, 157249, 157258, 
+    157268, 157276, 157285, 157294, 157304, 157313, 157323, 157333, 
+    157344, 157352, 157361, 157370, 157380, 157389, 157399, 157409, 
+    157420, 157429, 157439, 157449, 157460, 157470, 157481, 157492, 
+    157504, 157510, 157517, 157524, 157532, 157539, 157547, 157555, 
+    157564, 157571, 157579, 157587, 157596, 157604, 157613, 157622, 
+    157632, 157639, 157647, 157655, 157664, 157672, 157681, 157690, 
+    157700, 157708, 157717, 157726, 157736, 157745, 157755, 157765, 
+    157776, 157783, 157791, 157799, 157808, 157816, 157825, 157834, 
+    157844, 157852, 157861, 157870, 157880, 157889, 157899, 157909, 
+    157920, 157928, 157937, 157946, 157956, 157965, 157975, 157985, 
+    157996, 158005, 158015, 158025, 158036, 158046, 158057, 158068, 
+    158080, 158087, 158095, 158103, 158112, 158120, 158129, 158138, 
+    158148, 158156, 158165, 158174, 158184, 158193, 158203, 158213, 
+    158224, 158232, 158241, 158250, 158260, 158269, 158279, 158289, 
+    158300, 158309, 158319, 158329, 158340, 158350, 158361, 158372, 
+    158384, 158392, 158401, 158410, 158420, 158429, 158439, 158449, 
+    158460, 158469, 158479, 158489, 158500, 158510, 158521, 158532, 
+    158544, 158553, 158563, 158573, 158584, 158594, 158605, 158616, 
+    158628, 158638, 158649, 158660, 158672, 158683, 158695, 158707, 
+    158720, 158723, 158727, 158731, 158736, 158740, 158745, 158750, 
+    158756, 158760, 158765, 158770, 158776, 158781, 158787, 158793, 
+    158800, 158804, 158809, 158814, 158820, 158825, 158831, 158837, 
+    158844, 158849, 158855, 158861, 158868, 158874, 158881, 158888, 
+    158896, 158900, 158905, 158910, 158916, 158921, 158927, 158933, 
+    158940, 158945, 158951, 158957, 158964, 158970, 158977, 158984, 
+    158992, 158997, 159003, 159009, 159016, 159022, 159029, 159036, 
+    159044, 159050, 159057, 159064, 159072, 159079, 159087, 159095, 
+    159104, 159108, 159113, 159118, 159124, 159129, 159135, 159141, 
+    159148, 159153, 159159, 159165, 159172, 159178, 159185, 159192, 
+    159200, 159205, 159211, 159217, 159224, 159230, 159237, 159244, 
+    159252, 159258, 159265, 159272, 159280, 159287, 159295, 159303, 
+    159312, 159317, 159323, 159329, 159336, 159342, 159349, 159356, 
+    159364, 159370, 159377, 159384, 159392, 159399, 159407, 159415, 
+    159424, 159430, 159437, 159444, 159452, 159459, 159467, 159475, 
+    159484, 159491, 159499, 159507, 159516, 159524, 159533, 159542, 
+    159552, 159556, 159561, 159566, 159572, 159577, 159583, 159589, 
+    159596, 159601, 159607, 159613, 159620, 159626, 159633, 159640, 
+    159648, 159653, 159659, 159665, 159672, 159678, 159685, 159692, 
+    159700, 159706, 159713, 159720, 159728, 159735, 159743, 159751, 
+    159760, 159765, 159771, 159777, 159784, 159790, 159797, 159804, 
+    159812, 159818, 159825, 159832, 159840, 159847, 159855, 159863, 
+    159872, 159878, 159885, 159892, 159900, 159907, 159915, 159923, 
+    159932, 159939, 159947, 159955, 159964, 159972, 159981, 159990, 
+    160000, 160005, 160011, 160017, 160024, 160030, 160037, 160044, 
+    160052, 160058, 160065, 160072, 160080, 160087, 160095, 160103, 
+    160112, 160118, 160125, 160132, 160140, 160147, 160155, 160163, 
+    160172, 160179, 160187, 160195, 160204, 160212, 160221, 160230, 
+    160240, 160246, 160253, 160260, 160268, 160275, 160283, 160291, 
+    160300, 160307, 160315, 160323, 160332, 160340, 160349, 160358, 
+    160368, 160375, 160383, 160391, 160400, 160408, 160417, 160426, 
+    160436, 160444, 160453, 160462, 160472, 160481, 160491, 160501, 
+    160512, 160516, 160521, 160526, 160532, 160537, 160543, 160549, 
+    160556, 160561, 160567, 160573, 160580, 160586, 160593, 160600, 
+    160608, 160613, 160619, 160625, 160632, 160638, 160645, 160652, 
+    160660, 160666, 160673, 160680, 160688, 160695, 160703, 160711, 
+    160720, 160725, 160731, 160737, 160744, 160750, 160757, 160764, 
+    160772, 160778, 160785, 160792, 160800, 160807, 160815, 160823, 
+    160832, 160838, 160845, 160852, 160860, 160867, 160875, 160883, 
+    160892, 160899, 160907, 160915, 160924, 160932, 160941, 160950, 
+    160960, 160965, 160971, 160977, 160984, 160990, 160997, 161004, 
+    161012, 161018, 161025, 161032, 161040, 161047, 161055, 161063, 
+    161072, 161078, 161085, 161092, 161100, 161107, 161115, 161123, 
+    161132, 161139, 161147, 161155, 161164, 161172, 161181, 161190, 
+    161200, 161206, 161213, 161220, 161228, 161235, 161243, 161251, 
+    161260, 161267, 161275, 161283, 161292, 161300, 161309, 161318, 
+    161328, 161335, 161343, 161351, 161360, 161368, 161377, 161386, 
+    161396, 161404, 161413, 161422, 161432, 161441, 161451, 161461, 
+    161472, 161477, 161483, 161489, 161496, 161502, 161509, 161516, 
+    161524, 161530, 161537, 161544, 161552, 161559, 161567, 161575, 
+    161584, 161590, 161597, 161604, 161612, 161619, 161627, 161635, 
+    161644, 161651, 161659, 161667, 161676, 161684, 161693, 161702, 
+    161712, 161718, 161725, 161732, 161740, 161747, 161755, 161763, 
+    161772, 161779, 161787, 161795, 161804, 161812, 161821, 161830, 
+    161840, 161847, 161855, 161863, 161872, 161880, 161889, 161898, 
+    161908, 161916, 161925, 161934, 161944, 161953, 161963, 161973, 
+    161984, 161990, 161997, 162004, 162012, 162019, 162027, 162035, 
+    162044, 162051, 162059, 162067, 162076, 162084, 162093, 162102, 
+    162112, 162119, 162127, 162135, 162144, 162152, 162161, 162170, 
+    162180, 162188, 162197, 162206, 162216, 162225, 162235, 162245, 
+    162256, 162263, 162271, 162279, 162288, 162296, 162305, 162314, 
+    162324, 162332, 162341, 162350, 162360, 162369, 162379, 162389, 
+    162400, 162408, 162417, 162426, 162436, 162445, 162455, 162465, 
+    162476, 162485, 162495, 162505, 162516, 162526, 162537, 162548, 
+    162560, 162564, 162569, 162574, 162580, 162585, 162591, 162597, 
+    162604, 162609, 162615, 162621, 162628, 162634, 162641, 162648, 
+    162656, 162661, 162667, 162673, 162680, 162686, 162693, 162700, 
+    162708, 162714, 162721, 162728, 162736, 162743, 162751, 162759, 
+    162768, 162773, 162779, 162785, 162792, 162798, 162805, 162812, 
+    162820, 162826, 162833, 162840, 162848, 162855, 162863, 162871, 
+    162880, 162886, 162893, 162900, 162908, 162915, 162923, 162931, 
+    162940, 162947, 162955, 162963, 162972, 162980, 162989, 162998, 
+    163008, 163013, 163019, 163025, 163032, 163038, 163045, 163052, 
+    163060, 163066, 163073, 163080, 163088, 163095, 163103, 163111, 
+    163120, 163126, 163133, 163140, 163148, 163155, 163163, 163171, 
+    163180, 163187, 163195, 163203, 163212, 163220, 163229, 163238, 
+    163248, 163254, 163261, 163268, 163276, 163283, 163291, 163299, 
+    163308, 163315, 163323, 163331, 163340, 163348, 163357, 163366, 
+    163376, 163383, 163391, 163399, 163408, 163416, 163425, 163434, 
+    163444, 163452, 163461, 163470, 163480, 163489, 163499, 163509, 
+    163520, 163525, 163531, 163537, 163544, 163550, 163557, 163564, 
+    163572, 163578, 163585, 163592, 163600, 163607, 163615, 163623, 
+    163632, 163638, 163645, 163652, 163660, 163667, 163675, 163683, 
+    163692, 163699, 163707, 163715, 163724, 163732, 163741, 163750, 
+    163760, 163766, 163773, 163780, 163788, 163795, 163803, 163811, 
+    163820, 163827, 163835, 163843, 163852, 163860, 163869, 163878, 
+    163888, 163895, 163903, 163911, 163920, 163928, 163937, 163946, 
+    163956, 163964, 163973, 163982, 163992, 164001, 164011, 164021, 
+    164032, 164038, 164045, 164052, 164060, 164067, 164075, 164083, 
+    164092, 164099, 164107, 164115, 164124, 164132, 164141, 164150, 
+    164160, 164167, 164175, 164183, 164192, 164200, 164209, 164218, 
+    164228, 164236, 164245, 164254, 164264, 164273, 164283, 164293, 
+    164304, 164311, 164319, 164327, 164336, 164344, 164353, 164362, 
+    164372, 164380, 164389, 164398, 164408, 164417, 164427, 164437, 
+    164448, 164456, 164465, 164474, 164484, 164493, 164503, 164513, 
+    164524, 164533, 164543, 164553, 164564, 164574, 164585, 164596, 
+    164608, 164613, 164619, 164625, 164632, 164638, 164645, 164652, 
+    164660, 164666, 164673, 164680, 164688, 164695, 164703, 164711, 
+    164720, 164726, 164733, 164740, 164748, 164755, 164763, 164771, 
+    164780, 164787, 164795, 164803, 164812, 164820, 164829, 164838, 
+    164848, 164854, 164861, 164868, 164876, 164883, 164891, 164899, 
+    164908, 164915, 164923, 164931, 164940, 164948, 164957, 164966, 
+    164976, 164983, 164991, 164999, 165008, 165016, 165025, 165034, 
+    165044, 165052, 165061, 165070, 165080, 165089, 165099, 165109, 
+    165120, 165126, 165133, 165140, 165148, 165155, 165163, 165171, 
+    165180, 165187, 165195, 165203, 165212, 165220, 165229, 165238, 
+    165248, 165255, 165263, 165271, 165280, 165288, 165297, 165306, 
+    165316, 165324, 165333, 165342, 165352, 165361, 165371, 165381, 
+    165392, 165399, 165407, 165415, 165424, 165432, 165441, 165450, 
+    165460, 165468, 165477, 165486, 165496, 165505, 165515, 165525, 
+    165536, 165544, 165553, 165562, 165572, 165581, 165591, 165601, 
+    165612, 165621, 165631, 165641, 165652, 165662, 165673, 165684, 
+    165696, 165702, 165709, 165716, 165724, 165731, 165739, 165747, 
+    165756, 165763, 165771, 165779, 165788, 165796, 165805, 165814, 
+    165824, 165831, 165839, 165847, 165856, 165864, 165873, 165882, 
+    165892, 165900, 165909, 165918, 165928, 165937, 165947, 165957, 
+    165968, 165975, 165983, 165991, 166000, 166008, 166017, 166026, 
+    166036, 166044, 166053, 166062, 166072, 166081, 166091, 166101, 
+    166112, 166120, 166129, 166138, 166148, 166157, 166167, 166177, 
+    166188, 166197, 166207, 166217, 166228, 166238, 166249, 166260, 
+    166272, 166279, 166287, 166295, 166304, 166312, 166321, 166330, 
+    166340, 166348, 166357, 166366, 166376, 166385, 166395, 166405, 
+    166416, 166424, 166433, 166442, 166452, 166461, 166471, 166481, 
+    166492, 166501, 166511, 166521, 166532, 166542, 166553, 166564, 
+    166576, 166584, 166593, 166602, 166612, 166621, 166631, 166641, 
+    166652, 166661, 166671, 166681, 166692, 166702, 166713, 166724, 
+    166736, 166745, 166755, 166765, 166776, 166786, 166797, 166808, 
+    166820, 166830, 166841, 166852, 166864, 166875, 166887, 166899, 
+    166912, 166916, 166921, 166926, 166932, 166937, 166943, 166949, 
+    166956, 166961, 166967, 166973, 166980, 166986, 166993, 167000, 
+    167008, 167013, 167019, 167025, 167032, 167038, 167045, 167052, 
+    167060, 167066, 167073, 167080, 167088, 167095, 167103, 167111, 
+    167120, 167125, 167131, 167137, 167144, 167150, 167157, 167164, 
+    167172, 167178, 167185, 167192, 167200, 167207, 167215, 167223, 
+    167232, 167238, 167245, 167252, 167260, 167267, 167275, 167283, 
+    167292, 167299, 167307, 167315, 167324, 167332, 167341, 167350, 
+    167360, 167365, 167371, 167377, 167384, 167390, 167397, 167404, 
+    167412, 167418, 167425, 167432, 167440, 167447, 167455, 167463, 
+    167472, 167478, 167485, 167492, 167500, 167507, 167515, 167523, 
+    167532, 167539, 167547, 167555, 167564, 167572, 167581, 167590, 
+    167600, 167606, 167613, 167620, 167628, 167635, 167643, 167651, 
+    167660, 167667, 167675, 167683, 167692, 167700, 167709, 167718, 
+    167728, 167735, 167743, 167751, 167760, 167768, 167777, 167786, 
+    167796, 167804, 167813, 167822, 167832, 167841, 167851, 167861, 
+    167872, 167877, 167883, 167889, 167896, 167902, 167909, 167916, 
+    167924, 167930, 167937, 167944, 167952, 167959, 167967, 167975, 
+    167984, 167990, 167997, 168004, 168012, 168019, 168027, 168035, 
+    168044, 168051, 168059, 168067, 168076, 168084, 168093, 168102, 
+    168112, 168118, 168125, 168132, 168140, 168147, 168155, 168163, 
+    168172, 168179, 168187, 168195, 168204, 168212, 168221, 168230, 
+    168240, 168247, 168255, 168263, 168272, 168280, 168289, 168298, 
+    168308, 168316, 168325, 168334, 168344, 168353, 168363, 168373, 
+    168384, 168390, 168397, 168404, 168412, 168419, 168427, 168435, 
+    168444, 168451, 168459, 168467, 168476, 168484, 168493, 168502, 
+    168512, 168519, 168527, 168535, 168544, 168552, 168561, 168570, 
+    168580, 168588, 168597, 168606, 168616, 168625, 168635, 168645, 
+    168656, 168663, 168671, 168679, 168688, 168696, 168705, 168714, 
+    168724, 168732, 168741, 168750, 168760, 168769, 168779, 168789, 
+    168800, 168808, 168817, 168826, 168836, 168845, 168855, 168865, 
+    168876, 168885, 168895, 168905, 168916, 168926, 168937, 168948, 
+    168960, 168965, 168971, 168977, 168984, 168990, 168997, 169004, 
+    169012, 169018, 169025, 169032, 169040, 169047, 169055, 169063, 
+    169072, 169078, 169085, 169092, 169100, 169107, 169115, 169123, 
+    169132, 169139, 169147, 169155, 169164, 169172, 169181, 169190, 
+    169200, 169206, 169213, 169220, 169228, 169235, 169243, 169251, 
+    169260, 169267, 169275, 169283, 169292, 169300, 169309, 169318, 
+    169328, 169335, 169343, 169351, 169360, 169368, 169377, 169386, 
+    169396, 169404, 169413, 169422, 169432, 169441, 169451, 169461, 
+    169472, 169478, 169485, 169492, 169500, 169507, 169515, 169523, 
+    169532, 169539, 169547, 169555, 169564, 169572, 169581, 169590, 
+    169600, 169607, 169615, 169623, 169632, 169640, 169649, 169658, 
+    169668, 169676, 169685, 169694, 169704, 169713, 169723, 169733, 
+    169744, 169751, 169759, 169767, 169776, 169784, 169793, 169802, 
+    169812, 169820, 169829, 169838, 169848, 169857, 169867, 169877, 
+    169888, 169896, 169905, 169914, 169924, 169933, 169943, 169953, 
+    169964, 169973, 169983, 169993, 170004, 170014, 170025, 170036, 
+    170048, 170054, 170061, 170068, 170076, 170083, 170091, 170099, 
+    170108, 170115, 170123, 170131, 170140, 170148, 170157, 170166, 
+    170176, 170183, 170191, 170199, 170208, 170216, 170225, 170234, 
+    170244, 170252, 170261, 170270, 170280, 170289, 170299, 170309, 
+    170320, 170327, 170335, 170343, 170352, 170360, 170369, 170378, 
+    170388, 170396, 170405, 170414, 170424, 170433, 170443, 170453, 
+    170464, 170472, 170481, 170490, 170500, 170509, 170519, 170529, 
+    170540, 170549, 170559, 170569, 170580, 170590, 170601, 170612, 
+    170624, 170631, 170639, 170647, 170656, 170664, 170673, 170682, 
+    170692, 170700, 170709, 170718, 170728, 170737, 170747, 170757, 
+    170768, 170776, 170785, 170794, 170804, 170813, 170823, 170833, 
+    170844, 170853, 170863, 170873, 170884, 170894, 170905, 170916, 
+    170928, 170936, 170945, 170954, 170964, 170973, 170983, 170993, 
+    171004, 171013, 171023, 171033, 171044, 171054, 171065, 171076, 
+    171088, 171097, 171107, 171117, 171128, 171138, 171149, 171160, 
+    171172, 171182, 171193, 171204, 171216, 171227, 171239, 171251, 
+    171264, 171269, 171275, 171281, 171288, 171294, 171301, 171308, 
+    171316, 171322, 171329, 171336, 171344, 171351, 171359, 171367, 
+    171376, 171382, 171389, 171396, 171404, 171411, 171419, 171427, 
+    171436, 171443, 171451, 171459, 171468, 171476, 171485, 171494, 
+    171504, 171510, 171517, 171524, 171532, 171539, 171547, 171555, 
+    171564, 171571, 171579, 171587, 171596, 171604, 171613, 171622, 
+    171632, 171639, 171647, 171655, 171664, 171672, 171681, 171690, 
+    171700, 171708, 171717, 171726, 171736, 171745, 171755, 171765, 
+    171776, 171782, 171789, 171796, 171804, 171811, 171819, 171827, 
+    171836, 171843, 171851, 171859, 171868, 171876, 171885, 171894, 
+    171904, 171911, 171919, 171927, 171936, 171944, 171953, 171962, 
+    171972, 171980, 171989, 171998, 172008, 172017, 172027, 172037, 
+    172048, 172055, 172063, 172071, 172080, 172088, 172097, 172106, 
+    172116, 172124, 172133, 172142, 172152, 172161, 172171, 172181, 
+    172192, 172200, 172209, 172218, 172228, 172237, 172247, 172257, 
+    172268, 172277, 172287, 172297, 172308, 172318, 172329, 172340, 
+    172352, 172358, 172365, 172372, 172380, 172387, 172395, 172403, 
+    172412, 172419, 172427, 172435, 172444, 172452, 172461, 172470, 
+    172480, 172487, 172495, 172503, 172512, 172520, 172529, 172538, 
+    172548, 172556, 172565, 172574, 172584, 172593, 172603, 172613, 
+    172624, 172631, 172639, 172647, 172656, 172664, 172673, 172682, 
+    172692, 172700, 172709, 172718, 172728, 172737, 172747, 172757, 
+    172768, 172776, 172785, 172794, 172804, 172813, 172823, 172833, 
+    172844, 172853, 172863, 172873, 172884, 172894, 172905, 172916, 
+    172928, 172935, 172943, 172951, 172960, 172968, 172977, 172986, 
+    172996, 173004, 173013, 173022, 173032, 173041, 173051, 173061, 
+    173072, 173080, 173089, 173098, 173108, 173117, 173127, 173137, 
+    173148, 173157, 173167, 173177, 173188, 173198, 173209, 173220, 
+    173232, 173240, 173249, 173258, 173268, 173277, 173287, 173297, 
+    173308, 173317, 173327, 173337, 173348, 173358, 173369, 173380, 
+    173392, 173401, 173411, 173421, 173432, 173442, 173453, 173464, 
+    173476, 173486, 173497, 173508, 173520, 173531, 173543, 173555, 
+    173568, 173574, 173581, 173588, 173596, 173603, 173611, 173619, 
+    173628, 173635, 173643, 173651, 173660, 173668, 173677, 173686, 
+    173696, 173703, 173711, 173719, 173728, 173736, 173745, 173754, 
+    173764, 173772, 173781, 173790, 173800, 173809, 173819, 173829, 
+    173840, 173847, 173855, 173863, 173872, 173880, 173889, 173898, 
+    173908, 173916, 173925, 173934, 173944, 173953, 173963, 173973, 
+    173984, 173992, 174001, 174010, 174020, 174029, 174039, 174049, 
+    174060, 174069, 174079, 174089, 174100, 174110, 174121, 174132, 
+    174144, 174151, 174159, 174167, 174176, 174184, 174193, 174202, 
+    174212, 174220, 174229, 174238, 174248, 174257, 174267, 174277, 
+    174288, 174296, 174305, 174314, 174324, 174333, 174343, 174353, 
+    174364, 174373, 174383, 174393, 174404, 174414, 174425, 174436, 
+    174448, 174456, 174465, 174474, 174484, 174493, 174503, 174513, 
+    174524, 174533, 174543, 174553, 174564, 174574, 174585, 174596, 
+    174608, 174617, 174627, 174637, 174648, 174658, 174669, 174680, 
+    174692, 174702, 174713, 174724, 174736, 174747, 174759, 174771, 
+    174784, 174791, 174799, 174807, 174816, 174824, 174833, 174842, 
+    174852, 174860, 174869, 174878, 174888, 174897, 174907, 174917, 
+    174928, 174936, 174945, 174954, 174964, 174973, 174983, 174993, 
+    175004, 175013, 175023, 175033, 175044, 175054, 175065, 175076, 
+    175088, 175096, 175105, 175114, 175124, 175133, 175143, 175153, 
+    175164, 175173, 175183, 175193, 175204, 175214, 175225, 175236, 
+    175248, 175257, 175267, 175277, 175288, 175298, 175309, 175320, 
+    175332, 175342, 175353, 175364, 175376, 175387, 175399, 175411, 
+    175424, 175432, 175441, 175450, 175460, 175469, 175479, 175489, 
+    175500, 175509, 175519, 175529, 175540, 175550, 175561, 175572, 
+    175584, 175593, 175603, 175613, 175624, 175634, 175645, 175656, 
+    175668, 175678, 175689, 175700, 175712, 175723, 175735, 175747, 
+    175760, 175769, 175779, 175789, 175800, 175810, 175821, 175832, 
+    175844, 175854, 175865, 175876, 175888, 175899, 175911, 175923, 
+    175936, 175946, 175957, 175968, 175980, 175991, 176003, 176015, 
+    176028, 176039, 176051, 176063, 176076, 176088, 176101, 176114, 
+    176128, 176130, 176133, 176136, 176140, 176143, 176147, 176151, 
+    176156, 176159, 176163, 176167, 176172, 176176, 176181, 176186, 
+    176192, 176195, 176199, 176203, 176208, 176212, 176217, 176222, 
+    176228, 176232, 176237, 176242, 176248, 176253, 176259, 176265, 
+    176272, 176275, 176279, 176283, 176288, 176292, 176297, 176302, 
+    176308, 176312, 176317, 176322, 176328, 176333, 176339, 176345, 
+    176352, 176356, 176361, 176366, 176372, 176377, 176383, 176389, 
+    176396, 176401, 176407, 176413, 176420, 176426, 176433, 176440, 
+    176448, 176451, 176455, 176459, 176464, 176468, 176473, 176478, 
+    176484, 176488, 176493, 176498, 176504, 176509, 176515, 176521, 
+    176528, 176532, 176537, 176542, 176548, 176553, 176559, 176565, 
+    176572, 176577, 176583, 176589, 176596, 176602, 176609, 176616, 
+    176624, 176628, 176633, 176638, 176644, 176649, 176655, 176661, 
+    176668, 176673, 176679, 176685, 176692, 176698, 176705, 176712, 
+    176720, 176725, 176731, 176737, 176744, 176750, 176757, 176764, 
+    176772, 176778, 176785, 176792, 176800, 176807, 176815, 176823, 
+    176832, 176835, 176839, 176843, 176848, 176852, 176857, 176862, 
+    176868, 176872, 176877, 176882, 176888, 176893, 176899, 176905, 
+    176912, 176916, 176921, 176926, 176932, 176937, 176943, 176949, 
+    176956, 176961, 176967, 176973, 176980, 176986, 176993, 177000, 
+    177008, 177012, 177017, 177022, 177028, 177033, 177039, 177045, 
+    177052, 177057, 177063, 177069, 177076, 177082, 177089, 177096, 
+    177104, 177109, 177115, 177121, 177128, 177134, 177141, 177148, 
+    177156, 177162, 177169, 177176, 177184, 177191, 177199, 177207, 
+    177216, 177220, 177225, 177230, 177236, 177241, 177247, 177253, 
+    177260, 177265, 177271, 177277, 177284, 177290, 177297, 177304, 
+    177312, 177317, 177323, 177329, 177336, 177342, 177349, 177356, 
+    177364, 177370, 177377, 177384, 177392, 177399, 177407, 177415, 
+    177424, 177429, 177435, 177441, 177448, 177454, 177461, 177468, 
+    177476, 177482, 177489, 177496, 177504, 177511, 177519, 177527, 
+    177536, 177542, 177549, 177556, 177564, 177571, 177579, 177587, 
+    177596, 177603, 177611, 177619, 177628, 177636, 177645, 177654, 
+    177664, 177667, 177671, 177675, 177680, 177684, 177689, 177694, 
+    177700, 177704, 177709, 177714, 177720, 177725, 177731, 177737, 
+    177744, 177748, 177753, 177758, 177764, 177769, 177775, 177781, 
+    177788, 177793, 177799, 177805, 177812, 177818, 177825, 177832, 
+    177840, 177844, 177849, 177854, 177860, 177865, 177871, 177877, 
+    177884, 177889, 177895, 177901, 177908, 177914, 177921, 177928, 
+    177936, 177941, 177947, 177953, 177960, 177966, 177973, 177980, 
+    177988, 177994, 178001, 178008, 178016, 178023, 178031, 178039, 
+    178048, 178052, 178057, 178062, 178068, 178073, 178079, 178085, 
+    178092, 178097, 178103, 178109, 178116, 178122, 178129, 178136, 
+    178144, 178149, 178155, 178161, 178168, 178174, 178181, 178188, 
+    178196, 178202, 178209, 178216, 178224, 178231, 178239, 178247, 
+    178256, 178261, 178267, 178273, 178280, 178286, 178293, 178300, 
+    178308, 178314, 178321, 178328, 178336, 178343, 178351, 178359, 
+    178368, 178374, 178381, 178388, 178396, 178403, 178411, 178419, 
+    178428, 178435, 178443, 178451, 178460, 178468, 178477, 178486, 
+    178496, 178500, 178505, 178510, 178516, 178521, 178527, 178533, 
+    178540, 178545, 178551, 178557, 178564, 178570, 178577, 178584, 
+    178592, 178597, 178603, 178609, 178616, 178622, 178629, 178636, 
+    178644, 178650, 178657, 178664, 178672, 178679, 178687, 178695, 
+    178704, 178709, 178715, 178721, 178728, 178734, 178741, 178748, 
+    178756, 178762, 178769, 178776, 178784, 178791, 178799, 178807, 
+    178816, 178822, 178829, 178836, 178844, 178851, 178859, 178867, 
+    178876, 178883, 178891, 178899, 178908, 178916, 178925, 178934, 
+    178944, 178949, 178955, 178961, 178968, 178974, 178981, 178988, 
+    178996, 179002, 179009, 179016, 179024, 179031, 179039, 179047, 
+    179056, 179062, 179069, 179076, 179084, 179091, 179099, 179107, 
+    179116, 179123, 179131, 179139, 179148, 179156, 179165, 179174, 
+    179184, 179190, 179197, 179204, 179212, 179219, 179227, 179235, 
+    179244, 179251, 179259, 179267, 179276, 179284, 179293, 179302, 
+    179312, 179319, 179327, 179335, 179344, 179352, 179361, 179370, 
+    179380, 179388, 179397, 179406, 179416, 179425, 179435, 179445, 
+    179456, 179459, 179463, 179467, 179472, 179476, 179481, 179486, 
+    179492, 179496, 179501, 179506, 179512, 179517, 179523, 179529, 
+    179536, 179540, 179545, 179550, 179556, 179561, 179567, 179573, 
+    179580, 179585, 179591, 179597, 179604, 179610, 179617, 179624, 
+    179632, 179636, 179641, 179646, 179652, 179657, 179663, 179669, 
+    179676, 179681, 179687, 179693, 179700, 179706, 179713, 179720, 
+    179728, 179733, 179739, 179745, 179752, 179758, 179765, 179772, 
+    179780, 179786, 179793, 179800, 179808, 179815, 179823, 179831, 
+    179840, 179844, 179849, 179854, 179860, 179865, 179871, 179877, 
+    179884, 179889, 179895, 179901, 179908, 179914, 179921, 179928, 
+    179936, 179941, 179947, 179953, 179960, 179966, 179973, 179980, 
+    179988, 179994, 180001, 180008, 180016, 180023, 180031, 180039, 
+    180048, 180053, 180059, 180065, 180072, 180078, 180085, 180092, 
+    180100, 180106, 180113, 180120, 180128, 180135, 180143, 180151, 
+    180160, 180166, 180173, 180180, 180188, 180195, 180203, 180211, 
+    180220, 180227, 180235, 180243, 180252, 180260, 180269, 180278, 
+    180288, 180292, 180297, 180302, 180308, 180313, 180319, 180325, 
+    180332, 180337, 180343, 180349, 180356, 180362, 180369, 180376, 
+    180384, 180389, 180395, 180401, 180408, 180414, 180421, 180428, 
+    180436, 180442, 180449, 180456, 180464, 180471, 180479, 180487, 
+    180496, 180501, 180507, 180513, 180520, 180526, 180533, 180540, 
+    180548, 180554, 180561, 180568, 180576, 180583, 180591, 180599, 
+    180608, 180614, 180621, 180628, 180636, 180643, 180651, 180659, 
+    180668, 180675, 180683, 180691, 180700, 180708, 180717, 180726, 
+    180736, 180741, 180747, 180753, 180760, 180766, 180773, 180780, 
+    180788, 180794, 180801, 180808, 180816, 180823, 180831, 180839, 
+    180848, 180854, 180861, 180868, 180876, 180883, 180891, 180899, 
+    180908, 180915, 180923, 180931, 180940, 180948, 180957, 180966, 
+    180976, 180982, 180989, 180996, 181004, 181011, 181019, 181027, 
+    181036, 181043, 181051, 181059, 181068, 181076, 181085, 181094, 
+    181104, 181111, 181119, 181127, 181136, 181144, 181153, 181162, 
+    181172, 181180, 181189, 181198, 181208, 181217, 181227, 181237, 
+    181248, 181252, 181257, 181262, 181268, 181273, 181279, 181285, 
+    181292, 181297, 181303, 181309, 181316, 181322, 181329, 181336, 
+    181344, 181349, 181355, 181361, 181368, 181374, 181381, 181388, 
+    181396, 181402, 181409, 181416, 181424, 181431, 181439, 181447, 
+    181456, 181461, 181467, 181473, 181480, 181486, 181493, 181500, 
+    181508, 181514, 181521, 181528, 181536, 181543, 181551, 181559, 
+    181568, 181574, 181581, 181588, 181596, 181603, 181611, 181619, 
+    181628, 181635, 181643, 181651, 181660, 181668, 181677, 181686, 
+    181696, 181701, 181707, 181713, 181720, 181726, 181733, 181740, 
+    181748, 181754, 181761, 181768, 181776, 181783, 181791, 181799, 
+    181808, 181814, 181821, 181828, 181836, 181843, 181851, 181859, 
+    181868, 181875, 181883, 181891, 181900, 181908, 181917, 181926, 
+    181936, 181942, 181949, 181956, 181964, 181971, 181979, 181987, 
+    181996, 182003, 182011, 182019, 182028, 182036, 182045, 182054, 
+    182064, 182071, 182079, 182087, 182096, 182104, 182113, 182122, 
+    182132, 182140, 182149, 182158, 182168, 182177, 182187, 182197, 
+    182208, 182213, 182219, 182225, 182232, 182238, 182245, 182252, 
+    182260, 182266, 182273, 182280, 182288, 182295, 182303, 182311, 
+    182320, 182326, 182333, 182340, 182348, 182355, 182363, 182371, 
+    182380, 182387, 182395, 182403, 182412, 182420, 182429, 182438, 
+    182448, 182454, 182461, 182468, 182476, 182483, 182491, 182499, 
+    182508, 182515, 182523, 182531, 182540, 182548, 182557, 182566, 
+    182576, 182583, 182591, 182599, 182608, 182616, 182625, 182634, 
+    182644, 182652, 182661, 182670, 182680, 182689, 182699, 182709, 
+    182720, 182726, 182733, 182740, 182748, 182755, 182763, 182771, 
+    182780, 182787, 182795, 182803, 182812, 182820, 182829, 182838, 
+    182848, 182855, 182863, 182871, 182880, 182888, 182897, 182906, 
+    182916, 182924, 182933, 182942, 182952, 182961, 182971, 182981, 
+    182992, 182999, 183007, 183015, 183024, 183032, 183041, 183050, 
+    183060, 183068, 183077, 183086, 183096, 183105, 183115, 183125, 
+    183136, 183144, 183153, 183162, 183172, 183181, 183191, 183201, 
+    183212, 183221, 183231, 183241, 183252, 183262, 183273, 183284, 
+    183296, 183299, 183303, 183307, 183312, 183316, 183321, 183326, 
+    183332, 183336, 183341, 183346, 183352, 183357, 183363, 183369, 
+    183376, 183380, 183385, 183390, 183396, 183401, 183407, 183413, 
+    183420, 183425, 183431, 183437, 183444, 183450, 183457, 183464, 
+    183472, 183476, 183481, 183486, 183492, 183497, 183503, 183509, 
+    183516, 183521, 183527, 183533, 183540, 183546, 183553, 183560, 
+    183568, 183573, 183579, 183585, 183592, 183598, 183605, 183612, 
+    183620, 183626, 183633, 183640, 183648, 183655, 183663, 183671, 
+    183680, 183684, 183689, 183694, 183700, 183705, 183711, 183717, 
+    183724, 183729, 183735, 183741, 183748, 183754, 183761, 183768, 
+    183776, 183781, 183787, 183793, 183800, 183806, 183813, 183820, 
+    183828, 183834, 183841, 183848, 183856, 183863, 183871, 183879, 
+    183888, 183893, 183899, 183905, 183912, 183918, 183925, 183932, 
+    183940, 183946, 183953, 183960, 183968, 183975, 183983, 183991, 
+    184000, 184006, 184013, 184020, 184028, 184035, 184043, 184051, 
+    184060, 184067, 184075, 184083, 184092, 184100, 184109, 184118, 
+    184128, 184132, 184137, 184142, 184148, 184153, 184159, 184165, 
+    184172, 184177, 184183, 184189, 184196, 184202, 184209, 184216, 
+    184224, 184229, 184235, 184241, 184248, 184254, 184261, 184268, 
+    184276, 184282, 184289, 184296, 184304, 184311, 184319, 184327, 
+    184336, 184341, 184347, 184353, 184360, 184366, 184373, 184380, 
+    184388, 184394, 184401, 184408, 184416, 184423, 184431, 184439, 
+    184448, 184454, 184461, 184468, 184476, 184483, 184491, 184499, 
+    184508, 184515, 184523, 184531, 184540, 184548, 184557, 184566, 
+    184576, 184581, 184587, 184593, 184600, 184606, 184613, 184620, 
+    184628, 184634, 184641, 184648, 184656, 184663, 184671, 184679, 
+    184688, 184694, 184701, 184708, 184716, 184723, 184731, 184739, 
+    184748, 184755, 184763, 184771, 184780, 184788, 184797, 184806, 
+    184816, 184822, 184829, 184836, 184844, 184851, 184859, 184867, 
+    184876, 184883, 184891, 184899, 184908, 184916, 184925, 184934, 
+    184944, 184951, 184959, 184967, 184976, 184984, 184993, 185002, 
+    185012, 185020, 185029, 185038, 185048, 185057, 185067, 185077, 
+    185088, 185092, 185097, 185102, 185108, 185113, 185119, 185125, 
+    185132, 185137, 185143, 185149, 185156, 185162, 185169, 185176, 
+    185184, 185189, 185195, 185201, 185208, 185214, 185221, 185228, 
+    185236, 185242, 185249, 185256, 185264, 185271, 185279, 185287, 
+    185296, 185301, 185307, 185313, 185320, 185326, 185333, 185340, 
+    185348, 185354, 185361, 185368, 185376, 185383, 185391, 185399, 
+    185408, 185414, 185421, 185428, 185436, 185443, 185451, 185459, 
+    185468, 185475, 185483, 185491, 185500, 185508, 185517, 185526, 
+    185536, 185541, 185547, 185553, 185560, 185566, 185573, 185580, 
+    185588, 185594, 185601, 185608, 185616, 185623, 185631, 185639, 
+    185648, 185654, 185661, 185668, 185676, 185683, 185691, 185699, 
+    185708, 185715, 185723, 185731, 185740, 185748, 185757, 185766, 
+    185776, 185782, 185789, 185796, 185804, 185811, 185819, 185827, 
+    185836, 185843, 185851, 185859, 185868, 185876, 185885, 185894, 
+    185904, 185911, 185919, 185927, 185936, 185944, 185953, 185962, 
+    185972, 185980, 185989, 185998, 186008, 186017, 186027, 186037, 
+    186048, 186053, 186059, 186065, 186072, 186078, 186085, 186092, 
+    186100, 186106, 186113, 186120, 186128, 186135, 186143, 186151, 
+    186160, 186166, 186173, 186180, 186188, 186195, 186203, 186211, 
+    186220, 186227, 186235, 186243, 186252, 186260, 186269, 186278, 
+    186288, 186294, 186301, 186308, 186316, 186323, 186331, 186339, 
+    186348, 186355, 186363, 186371, 186380, 186388, 186397, 186406, 
+    186416, 186423, 186431, 186439, 186448, 186456, 186465, 186474, 
+    186484, 186492, 186501, 186510, 186520, 186529, 186539, 186549, 
+    186560, 186566, 186573, 186580, 186588, 186595, 186603, 186611, 
+    186620, 186627, 186635, 186643, 186652, 186660, 186669, 186678, 
+    186688, 186695, 186703, 186711, 186720, 186728, 186737, 186746, 
+    186756, 186764, 186773, 186782, 186792, 186801, 186811, 186821, 
+    186832, 186839, 186847, 186855, 186864, 186872, 186881, 186890, 
+    186900, 186908, 186917, 186926, 186936, 186945, 186955, 186965, 
+    186976, 186984, 186993, 187002, 187012, 187021, 187031, 187041, 
+    187052, 187061, 187071, 187081, 187092, 187102, 187113, 187124, 
+    187136, 187140, 187145, 187150, 187156, 187161, 187167, 187173, 
+    187180, 187185, 187191, 187197, 187204, 187210, 187217, 187224, 
+    187232, 187237, 187243, 187249, 187256, 187262, 187269, 187276, 
+    187284, 187290, 187297, 187304, 187312, 187319, 187327, 187335, 
+    187344, 187349, 187355, 187361, 187368, 187374, 187381, 187388, 
+    187396, 187402, 187409, 187416, 187424, 187431, 187439, 187447, 
+    187456, 187462, 187469, 187476, 187484, 187491, 187499, 187507, 
+    187516, 187523, 187531, 187539, 187548, 187556, 187565, 187574, 
+    187584, 187589, 187595, 187601, 187608, 187614, 187621, 187628, 
+    187636, 187642, 187649, 187656, 187664, 187671, 187679, 187687, 
+    187696, 187702, 187709, 187716, 187724, 187731, 187739, 187747, 
+    187756, 187763, 187771, 187779, 187788, 187796, 187805, 187814, 
+    187824, 187830, 187837, 187844, 187852, 187859, 187867, 187875, 
+    187884, 187891, 187899, 187907, 187916, 187924, 187933, 187942, 
+    187952, 187959, 187967, 187975, 187984, 187992, 188001, 188010, 
+    188020, 188028, 188037, 188046, 188056, 188065, 188075, 188085, 
+    188096, 188101, 188107, 188113, 188120, 188126, 188133, 188140, 
+    188148, 188154, 188161, 188168, 188176, 188183, 188191, 188199, 
+    188208, 188214, 188221, 188228, 188236, 188243, 188251, 188259, 
+    188268, 188275, 188283, 188291, 188300, 188308, 188317, 188326, 
+    188336, 188342, 188349, 188356, 188364, 188371, 188379, 188387, 
+    188396, 188403, 188411, 188419, 188428, 188436, 188445, 188454, 
+    188464, 188471, 188479, 188487, 188496, 188504, 188513, 188522, 
+    188532, 188540, 188549, 188558, 188568, 188577, 188587, 188597, 
+    188608, 188614, 188621, 188628, 188636, 188643, 188651, 188659, 
+    188668, 188675, 188683, 188691, 188700, 188708, 188717, 188726, 
+    188736, 188743, 188751, 188759, 188768, 188776, 188785, 188794, 
+    188804, 188812, 188821, 188830, 188840, 188849, 188859, 188869, 
+    188880, 188887, 188895, 188903, 188912, 188920, 188929, 188938, 
+    188948, 188956, 188965, 188974, 188984, 188993, 189003, 189013, 
+    189024, 189032, 189041, 189050, 189060, 189069, 189079, 189089, 
+    189100, 189109, 189119, 189129, 189140, 189150, 189161, 189172, 
+    189184, 189189, 189195, 189201, 189208, 189214, 189221, 189228, 
+    189236, 189242, 189249, 189256, 189264, 189271, 189279, 189287, 
+    189296, 189302, 189309, 189316, 189324, 189331, 189339, 189347, 
+    189356, 189363, 189371, 189379, 189388, 189396, 189405, 189414, 
+    189424, 189430, 189437, 189444, 189452, 189459, 189467, 189475, 
+    189484, 189491, 189499, 189507, 189516, 189524, 189533, 189542, 
+    189552, 189559, 189567, 189575, 189584, 189592, 189601, 189610, 
+    189620, 189628, 189637, 189646, 189656, 189665, 189675, 189685, 
+    189696, 189702, 189709, 189716, 189724, 189731, 189739, 189747, 
+    189756, 189763, 189771, 189779, 189788, 189796, 189805, 189814, 
+    189824, 189831, 189839, 189847, 189856, 189864, 189873, 189882, 
+    189892, 189900, 189909, 189918, 189928, 189937, 189947, 189957, 
+    189968, 189975, 189983, 189991, 190000, 190008, 190017, 190026, 
+    190036, 190044, 190053, 190062, 190072, 190081, 190091, 190101, 
+    190112, 190120, 190129, 190138, 190148, 190157, 190167, 190177, 
+    190188, 190197, 190207, 190217, 190228, 190238, 190249, 190260, 
+    190272, 190278, 190285, 190292, 190300, 190307, 190315, 190323, 
+    190332, 190339, 190347, 190355, 190364, 190372, 190381, 190390, 
+    190400, 190407, 190415, 190423, 190432, 190440, 190449, 190458, 
+    190468, 190476, 190485, 190494, 190504, 190513, 190523, 190533, 
+    190544, 190551, 190559, 190567, 190576, 190584, 190593, 190602, 
+    190612, 190620, 190629, 190638, 190648, 190657, 190667, 190677, 
+    190688, 190696, 190705, 190714, 190724, 190733, 190743, 190753, 
+    190764, 190773, 190783, 190793, 190804, 190814, 190825, 190836, 
+    190848, 190855, 190863, 190871, 190880, 190888, 190897, 190906, 
+    190916, 190924, 190933, 190942, 190952, 190961, 190971, 190981, 
+    190992, 191000, 191009, 191018, 191028, 191037, 191047, 191057, 
+    191068, 191077, 191087, 191097, 191108, 191118, 191129, 191140, 
+    191152, 191160, 191169, 191178, 191188, 191197, 191207, 191217, 
+    191228, 191237, 191247, 191257, 191268, 191278, 191289, 191300, 
+    191312, 191321, 191331, 191341, 191352, 191362, 191373, 191384, 
+    191396, 191406, 191417, 191428, 191440, 191451, 191463, 191475, 
+    191488, 191491, 191495, 191499, 191504, 191508, 191513, 191518, 
+    191524, 191528, 191533, 191538, 191544, 191549, 191555, 191561, 
+    191568, 191572, 191577, 191582, 191588, 191593, 191599, 191605, 
+    191612, 191617, 191623, 191629, 191636, 191642, 191649, 191656, 
+    191664, 191668, 191673, 191678, 191684, 191689, 191695, 191701, 
+    191708, 191713, 191719, 191725, 191732, 191738, 191745, 191752, 
+    191760, 191765, 191771, 191777, 191784, 191790, 191797, 191804, 
+    191812, 191818, 191825, 191832, 191840, 191847, 191855, 191863, 
+    191872, 191876, 191881, 191886, 191892, 191897, 191903, 191909, 
+    191916, 191921, 191927, 191933, 191940, 191946, 191953, 191960, 
+    191968, 191973, 191979, 191985, 191992, 191998, 192005, 192012, 
+    192020, 192026, 192033, 192040, 192048, 192055, 192063, 192071, 
+    192080, 192085, 192091, 192097, 192104, 192110, 192117, 192124, 
+    192132, 192138, 192145, 192152, 192160, 192167, 192175, 192183, 
+    192192, 192198, 192205, 192212, 192220, 192227, 192235, 192243, 
+    192252, 192259, 192267, 192275, 192284, 192292, 192301, 192310, 
+    192320, 192324, 192329, 192334, 192340, 192345, 192351, 192357, 
+    192364, 192369, 192375, 192381, 192388, 192394, 192401, 192408, 
+    192416, 192421, 192427, 192433, 192440, 192446, 192453, 192460, 
+    192468, 192474, 192481, 192488, 192496, 192503, 192511, 192519, 
+    192528, 192533, 192539, 192545, 192552, 192558, 192565, 192572, 
+    192580, 192586, 192593, 192600, 192608, 192615, 192623, 192631, 
+    192640, 192646, 192653, 192660, 192668, 192675, 192683, 192691, 
+    192700, 192707, 192715, 192723, 192732, 192740, 192749, 192758, 
+    192768, 192773, 192779, 192785, 192792, 192798, 192805, 192812, 
+    192820, 192826, 192833, 192840, 192848, 192855, 192863, 192871, 
+    192880, 192886, 192893, 192900, 192908, 192915, 192923, 192931, 
+    192940, 192947, 192955, 192963, 192972, 192980, 192989, 192998, 
+    193008, 193014, 193021, 193028, 193036, 193043, 193051, 193059, 
+    193068, 193075, 193083, 193091, 193100, 193108, 193117, 193126, 
+    193136, 193143, 193151, 193159, 193168, 193176, 193185, 193194, 
+    193204, 193212, 193221, 193230, 193240, 193249, 193259, 193269, 
+    193280, 193284, 193289, 193294, 193300, 193305, 193311, 193317, 
+    193324, 193329, 193335, 193341, 193348, 193354, 193361, 193368, 
+    193376, 193381, 193387, 193393, 193400, 193406, 193413, 193420, 
+    193428, 193434, 193441, 193448, 193456, 193463, 193471, 193479, 
+    193488, 193493, 193499, 193505, 193512, 193518, 193525, 193532, 
+    193540, 193546, 193553, 193560, 193568, 193575, 193583, 193591, 
+    193600, 193606, 193613, 193620, 193628, 193635, 193643, 193651, 
+    193660, 193667, 193675, 193683, 193692, 193700, 193709, 193718, 
+    193728, 193733, 193739, 193745, 193752, 193758, 193765, 193772, 
+    193780, 193786, 193793, 193800, 193808, 193815, 193823, 193831, 
+    193840, 193846, 193853, 193860, 193868, 193875, 193883, 193891, 
+    193900, 193907, 193915, 193923, 193932, 193940, 193949, 193958, 
+    193968, 193974, 193981, 193988, 193996, 194003, 194011, 194019, 
+    194028, 194035, 194043, 194051, 194060, 194068, 194077, 194086, 
+    194096, 194103, 194111, 194119, 194128, 194136, 194145, 194154, 
+    194164, 194172, 194181, 194190, 194200, 194209, 194219, 194229, 
+    194240, 194245, 194251, 194257, 194264, 194270, 194277, 194284, 
+    194292, 194298, 194305, 194312, 194320, 194327, 194335, 194343, 
+    194352, 194358, 194365, 194372, 194380, 194387, 194395, 194403, 
+    194412, 194419, 194427, 194435, 194444, 194452, 194461, 194470, 
+    194480, 194486, 194493, 194500, 194508, 194515, 194523, 194531, 
+    194540, 194547, 194555, 194563, 194572, 194580, 194589, 194598, 
+    194608, 194615, 194623, 194631, 194640, 194648, 194657, 194666, 
+    194676, 194684, 194693, 194702, 194712, 194721, 194731, 194741, 
+    194752, 194758, 194765, 194772, 194780, 194787, 194795, 194803, 
+    194812, 194819, 194827, 194835, 194844, 194852, 194861, 194870, 
+    194880, 194887, 194895, 194903, 194912, 194920, 194929, 194938, 
+    194948, 194956, 194965, 194974, 194984, 194993, 195003, 195013, 
+    195024, 195031, 195039, 195047, 195056, 195064, 195073, 195082, 
+    195092, 195100, 195109, 195118, 195128, 195137, 195147, 195157, 
+    195168, 195176, 195185, 195194, 195204, 195213, 195223, 195233, 
+    195244, 195253, 195263, 195273, 195284, 195294, 195305, 195316, 
+    195328, 195332, 195337, 195342, 195348, 195353, 195359, 195365, 
+    195372, 195377, 195383, 195389, 195396, 195402, 195409, 195416, 
+    195424, 195429, 195435, 195441, 195448, 195454, 195461, 195468, 
+    195476, 195482, 195489, 195496, 195504, 195511, 195519, 195527, 
+    195536, 195541, 195547, 195553, 195560, 195566, 195573, 195580, 
+    195588, 195594, 195601, 195608, 195616, 195623, 195631, 195639, 
+    195648, 195654, 195661, 195668, 195676, 195683, 195691, 195699, 
+    195708, 195715, 195723, 195731, 195740, 195748, 195757, 195766, 
+    195776, 195781, 195787, 195793, 195800, 195806, 195813, 195820, 
+    195828, 195834, 195841, 195848, 195856, 195863, 195871, 195879, 
+    195888, 195894, 195901, 195908, 195916, 195923, 195931, 195939, 
+    195948, 195955, 195963, 195971, 195980, 195988, 195997, 196006, 
+    196016, 196022, 196029, 196036, 196044, 196051, 196059, 196067, 
+    196076, 196083, 196091, 196099, 196108, 196116, 196125, 196134, 
+    196144, 196151, 196159, 196167, 196176, 196184, 196193, 196202, 
+    196212, 196220, 196229, 196238, 196248, 196257, 196267, 196277, 
+    196288, 196293, 196299, 196305, 196312, 196318, 196325, 196332, 
+    196340, 196346, 196353, 196360, 196368, 196375, 196383, 196391, 
+    196400, 196406, 196413, 196420, 196428, 196435, 196443, 196451, 
+    196460, 196467, 196475, 196483, 196492, 196500, 196509, 196518, 
+    196528, 196534, 196541, 196548, 196556, 196563, 196571, 196579, 
+    196588, 196595, 196603, 196611, 196620, 196628, 196637, 196646, 
+    196656, 196663, 196671, 196679, 196688, 196696, 196705, 196714, 
+    196724, 196732, 196741, 196750, 196760, 196769, 196779, 196789, 
+    196800, 196806, 196813, 196820, 196828, 196835, 196843, 196851, 
+    196860, 196867, 196875, 196883, 196892, 196900, 196909, 196918, 
+    196928, 196935, 196943, 196951, 196960, 196968, 196977, 196986, 
+    196996, 197004, 197013, 197022, 197032, 197041, 197051, 197061, 
+    197072, 197079, 197087, 197095, 197104, 197112, 197121, 197130, 
+    197140, 197148, 197157, 197166, 197176, 197185, 197195, 197205, 
+    197216, 197224, 197233, 197242, 197252, 197261, 197271, 197281, 
+    197292, 197301, 197311, 197321, 197332, 197342, 197353, 197364, 
+    197376, 197381, 197387, 197393, 197400, 197406, 197413, 197420, 
+    197428, 197434, 197441, 197448, 197456, 197463, 197471, 197479, 
+    197488, 197494, 197501, 197508, 197516, 197523, 197531, 197539, 
+    197548, 197555, 197563, 197571, 197580, 197588, 197597, 197606, 
+    197616, 197622, 197629, 197636, 197644, 197651, 197659, 197667, 
+    197676, 197683, 197691, 197699, 197708, 197716, 197725, 197734, 
+    197744, 197751, 197759, 197767, 197776, 197784, 197793, 197802, 
+    197812, 197820, 197829, 197838, 197848, 197857, 197867, 197877, 
+    197888, 197894, 197901, 197908, 197916, 197923, 197931, 197939, 
+    197948, 197955, 197963, 197971, 197980, 197988, 197997, 198006, 
+    198016, 198023, 198031, 198039, 198048, 198056, 198065, 198074, 
+    198084, 198092, 198101, 198110, 198120, 198129, 198139, 198149, 
+    198160, 198167, 198175, 198183, 198192, 198200, 198209, 198218, 
+    198228, 198236, 198245, 198254, 198264, 198273, 198283, 198293, 
+    198304, 198312, 198321, 198330, 198340, 198349, 198359, 198369, 
+    198380, 198389, 198399, 198409, 198420, 198430, 198441, 198452, 
+    198464, 198470, 198477, 198484, 198492, 198499, 198507, 198515, 
+    198524, 198531, 198539, 198547, 198556, 198564, 198573, 198582, 
+    198592, 198599, 198607, 198615, 198624, 198632, 198641, 198650, 
+    198660, 198668, 198677, 198686, 198696, 198705, 198715, 198725, 
+    198736, 198743, 198751, 198759, 198768, 198776, 198785, 198794, 
+    198804, 198812, 198821, 198830, 198840, 198849, 198859, 198869, 
+    198880, 198888, 198897, 198906, 198916, 198925, 198935, 198945, 
+    198956, 198965, 198975, 198985, 198996, 199006, 199017, 199028, 
+    199040, 199047, 199055, 199063, 199072, 199080, 199089, 199098, 
+    199108, 199116, 199125, 199134, 199144, 199153, 199163, 199173, 
+    199184, 199192, 199201, 199210, 199220, 199229, 199239, 199249, 
+    199260, 199269, 199279, 199289, 199300, 199310, 199321, 199332, 
+    199344, 199352, 199361, 199370, 199380, 199389, 199399, 199409, 
+    199420, 199429, 199439, 199449, 199460, 199470, 199481, 199492, 
+    199504, 199513, 199523, 199533, 199544, 199554, 199565, 199576, 
+    199588, 199598, 199609, 199620, 199632, 199643, 199655, 199667, 
+    199680, 199684, 199689, 199694, 199700, 199705, 199711, 199717, 
+    199724, 199729, 199735, 199741, 199748, 199754, 199761, 199768, 
+    199776, 199781, 199787, 199793, 199800, 199806, 199813, 199820, 
+    199828, 199834, 199841, 199848, 199856, 199863, 199871, 199879, 
+    199888, 199893, 199899, 199905, 199912, 199918, 199925, 199932, 
+    199940, 199946, 199953, 199960, 199968, 199975, 199983, 199991, 
+    200000, 200006, 200013, 200020, 200028, 200035, 200043, 200051, 
+    200060, 200067, 200075, 200083, 200092, 200100, 200109, 200118, 
+    200128, 200133, 200139, 200145, 200152, 200158, 200165, 200172, 
+    200180, 200186, 200193, 200200, 200208, 200215, 200223, 200231, 
+    200240, 200246, 200253, 200260, 200268, 200275, 200283, 200291, 
+    200300, 200307, 200315, 200323, 200332, 200340, 200349, 200358, 
+    200368, 200374, 200381, 200388, 200396, 200403, 200411, 200419, 
+    200428, 200435, 200443, 200451, 200460, 200468, 200477, 200486, 
+    200496, 200503, 200511, 200519, 200528, 200536, 200545, 200554, 
+    200564, 200572, 200581, 200590, 200600, 200609, 200619, 200629, 
+    200640, 200645, 200651, 200657, 200664, 200670, 200677, 200684, 
+    200692, 200698, 200705, 200712, 200720, 200727, 200735, 200743, 
+    200752, 200758, 200765, 200772, 200780, 200787, 200795, 200803, 
+    200812, 200819, 200827, 200835, 200844, 200852, 200861, 200870, 
+    200880, 200886, 200893, 200900, 200908, 200915, 200923, 200931, 
+    200940, 200947, 200955, 200963, 200972, 200980, 200989, 200998, 
+    201008, 201015, 201023, 201031, 201040, 201048, 201057, 201066, 
+    201076, 201084, 201093, 201102, 201112, 201121, 201131, 201141, 
+    201152, 201158, 201165, 201172, 201180, 201187, 201195, 201203, 
+    201212, 201219, 201227, 201235, 201244, 201252, 201261, 201270, 
+    201280, 201287, 201295, 201303, 201312, 201320, 201329, 201338, 
+    201348, 201356, 201365, 201374, 201384, 201393, 201403, 201413, 
+    201424, 201431, 201439, 201447, 201456, 201464, 201473, 201482, 
+    201492, 201500, 201509, 201518, 201528, 201537, 201547, 201557, 
+    201568, 201576, 201585, 201594, 201604, 201613, 201623, 201633, 
+    201644, 201653, 201663, 201673, 201684, 201694, 201705, 201716, 
+    201728, 201733, 201739, 201745, 201752, 201758, 201765, 201772, 
+    201780, 201786, 201793, 201800, 201808, 201815, 201823, 201831, 
+    201840, 201846, 201853, 201860, 201868, 201875, 201883, 201891, 
+    201900, 201907, 201915, 201923, 201932, 201940, 201949, 201958, 
+    201968, 201974, 201981, 201988, 201996, 202003, 202011, 202019, 
+    202028, 202035, 202043, 202051, 202060, 202068, 202077, 202086, 
+    202096, 202103, 202111, 202119, 202128, 202136, 202145, 202154, 
+    202164, 202172, 202181, 202190, 202200, 202209, 202219, 202229, 
+    202240, 202246, 202253, 202260, 202268, 202275, 202283, 202291, 
+    202300, 202307, 202315, 202323, 202332, 202340, 202349, 202358, 
+    202368, 202375, 202383, 202391, 202400, 202408, 202417, 202426, 
+    202436, 202444, 202453, 202462, 202472, 202481, 202491, 202501, 
+    202512, 202519, 202527, 202535, 202544, 202552, 202561, 202570, 
+    202580, 202588, 202597, 202606, 202616, 202625, 202635, 202645, 
+    202656, 202664, 202673, 202682, 202692, 202701, 202711, 202721, 
+    202732, 202741, 202751, 202761, 202772, 202782, 202793, 202804, 
+    202816, 202822, 202829, 202836, 202844, 202851, 202859, 202867, 
+    202876, 202883, 202891, 202899, 202908, 202916, 202925, 202934, 
+    202944, 202951, 202959, 202967, 202976, 202984, 202993, 203002, 
+    203012, 203020, 203029, 203038, 203048, 203057, 203067, 203077, 
+    203088, 203095, 203103, 203111, 203120, 203128, 203137, 203146, 
+    203156, 203164, 203173, 203182, 203192, 203201, 203211, 203221, 
+    203232, 203240, 203249, 203258, 203268, 203277, 203287, 203297, 
+    203308, 203317, 203327, 203337, 203348, 203358, 203369, 203380, 
+    203392, 203399, 203407, 203415, 203424, 203432, 203441, 203450, 
+    203460, 203468, 203477, 203486, 203496, 203505, 203515, 203525, 
+    203536, 203544, 203553, 203562, 203572, 203581, 203591, 203601, 
+    203612, 203621, 203631, 203641, 203652, 203662, 203673, 203684, 
+    203696, 203704, 203713, 203722, 203732, 203741, 203751, 203761, 
+    203772, 203781, 203791, 203801, 203812, 203822, 203833, 203844, 
+    203856, 203865, 203875, 203885, 203896, 203906, 203917, 203928, 
+    203940, 203950, 203961, 203972, 203984, 203995, 204007, 204019, 
+    204032, 204037, 204043, 204049, 204056, 204062, 204069, 204076, 
+    204084, 204090, 204097, 204104, 204112, 204119, 204127, 204135, 
+    204144, 204150, 204157, 204164, 204172, 204179, 204187, 204195, 
+    204204, 204211, 204219, 204227, 204236, 204244, 204253, 204262, 
+    204272, 204278, 204285, 204292, 204300, 204307, 204315, 204323, 
+    204332, 204339, 204347, 204355, 204364, 204372, 204381, 204390, 
+    204400, 204407, 204415, 204423, 204432, 204440, 204449, 204458, 
+    204468, 204476, 204485, 204494, 204504, 204513, 204523, 204533, 
+    204544, 204550, 204557, 204564, 204572, 204579, 204587, 204595, 
+    204604, 204611, 204619, 204627, 204636, 204644, 204653, 204662, 
+    204672, 204679, 204687, 204695, 204704, 204712, 204721, 204730, 
+    204740, 204748, 204757, 204766, 204776, 204785, 204795, 204805, 
+    204816, 204823, 204831, 204839, 204848, 204856, 204865, 204874, 
+    204884, 204892, 204901, 204910, 204920, 204929, 204939, 204949, 
+    204960, 204968, 204977, 204986, 204996, 205005, 205015, 205025, 
+    205036, 205045, 205055, 205065, 205076, 205086, 205097, 205108, 
+    205120, 205126, 205133, 205140, 205148, 205155, 205163, 205171, 
+    205180, 205187, 205195, 205203, 205212, 205220, 205229, 205238, 
+    205248, 205255, 205263, 205271, 205280, 205288, 205297, 205306, 
+    205316, 205324, 205333, 205342, 205352, 205361, 205371, 205381, 
+    205392, 205399, 205407, 205415, 205424, 205432, 205441, 205450, 
+    205460, 205468, 205477, 205486, 205496, 205505, 205515, 205525, 
+    205536, 205544, 205553, 205562, 205572, 205581, 205591, 205601, 
+    205612, 205621, 205631, 205641, 205652, 205662, 205673, 205684, 
+    205696, 205703, 205711, 205719, 205728, 205736, 205745, 205754, 
+    205764, 205772, 205781, 205790, 205800, 205809, 205819, 205829, 
+    205840, 205848, 205857, 205866, 205876, 205885, 205895, 205905, 
+    205916, 205925, 205935, 205945, 205956, 205966, 205977, 205988, 
+    206000, 206008, 206017, 206026, 206036, 206045, 206055, 206065, 
+    206076, 206085, 206095, 206105, 206116, 206126, 206137, 206148, 
+    206160, 206169, 206179, 206189, 206200, 206210, 206221, 206232, 
+    206244, 206254, 206265, 206276, 206288, 206299, 206311, 206323, 
+    206336, 206342, 206349, 206356, 206364, 206371, 206379, 206387, 
+    206396, 206403, 206411, 206419, 206428, 206436, 206445, 206454, 
+    206464, 206471, 206479, 206487, 206496, 206504, 206513, 206522, 
+    206532, 206540, 206549, 206558, 206568, 206577, 206587, 206597, 
+    206608, 206615, 206623, 206631, 206640, 206648, 206657, 206666, 
+    206676, 206684, 206693, 206702, 206712, 206721, 206731, 206741, 
+    206752, 206760, 206769, 206778, 206788, 206797, 206807, 206817, 
+    206828, 206837, 206847, 206857, 206868, 206878, 206889, 206900, 
+    206912, 206919, 206927, 206935, 206944, 206952, 206961, 206970, 
+    206980, 206988, 206997, 207006, 207016, 207025, 207035, 207045, 
+    207056, 207064, 207073, 207082, 207092, 207101, 207111, 207121, 
+    207132, 207141, 207151, 207161, 207172, 207182, 207193, 207204, 
+    207216, 207224, 207233, 207242, 207252, 207261, 207271, 207281, 
+    207292, 207301, 207311, 207321, 207332, 207342, 207353, 207364, 
+    207376, 207385, 207395, 207405, 207416, 207426, 207437, 207448, 
+    207460, 207470, 207481, 207492, 207504, 207515, 207527, 207539, 
+    207552, 207559, 207567, 207575, 207584, 207592, 207601, 207610, 
+    207620, 207628, 207637, 207646, 207656, 207665, 207675, 207685, 
+    207696, 207704, 207713, 207722, 207732, 207741, 207751, 207761, 
+    207772, 207781, 207791, 207801, 207812, 207822, 207833, 207844, 
+    207856, 207864, 207873, 207882, 207892, 207901, 207911, 207921, 
+    207932, 207941, 207951, 207961, 207972, 207982, 207993, 208004, 
+    208016, 208025, 208035, 208045, 208056, 208066, 208077, 208088, 
+    208100, 208110, 208121, 208132, 208144, 208155, 208167, 208179, 
+    208192, 208200, 208209, 208218, 208228, 208237, 208247, 208257, 
+    208268, 208277, 208287, 208297, 208308, 208318, 208329, 208340, 
+    208352, 208361, 208371, 208381, 208392, 208402, 208413, 208424, 
+    208436, 208446, 208457, 208468, 208480, 208491, 208503, 208515, 
+    208528, 208537, 208547, 208557, 208568, 208578, 208589, 208600, 
+    208612, 208622, 208633, 208644, 208656, 208667, 208679, 208691, 
+    208704, 208714, 208725, 208736, 208748, 208759, 208771, 208783, 
+    208796, 208807, 208819, 208831, 208844, 208856, 208869, 208882, 
+    208896, 208899, 208903, 208907, 208912, 208916, 208921, 208926, 
+    208932, 208936, 208941, 208946, 208952, 208957, 208963, 208969, 
+    208976, 208980, 208985, 208990, 208996, 209001, 209007, 209013, 
+    209020, 209025, 209031, 209037, 209044, 209050, 209057, 209064, 
+    209072, 209076, 209081, 209086, 209092, 209097, 209103, 209109, 
+    209116, 209121, 209127, 209133, 209140, 209146, 209153, 209160, 
+    209168, 209173, 209179, 209185, 209192, 209198, 209205, 209212, 
+    209220, 209226, 209233, 209240, 209248, 209255, 209263, 209271, 
+    209280, 209284, 209289, 209294, 209300, 209305, 209311, 209317, 
+    209324, 209329, 209335, 209341, 209348, 209354, 209361, 209368, 
+    209376, 209381, 209387, 209393, 209400, 209406, 209413, 209420, 
+    209428, 209434, 209441, 209448, 209456, 209463, 209471, 209479, 
+    209488, 209493, 209499, 209505, 209512, 209518, 209525, 209532, 
+    209540, 209546, 209553, 209560, 209568, 209575, 209583, 209591, 
+    209600, 209606, 209613, 209620, 209628, 209635, 209643, 209651, 
+    209660, 209667, 209675, 209683, 209692, 209700, 209709, 209718, 
+    209728, 209732, 209737, 209742, 209748, 209753, 209759, 209765, 
+    209772, 209777, 209783, 209789, 209796, 209802, 209809, 209816, 
+    209824, 209829, 209835, 209841, 209848, 209854, 209861, 209868, 
+    209876, 209882, 209889, 209896, 209904, 209911, 209919, 209927, 
+    209936, 209941, 209947, 209953, 209960, 209966, 209973, 209980, 
+    209988, 209994, 210001, 210008, 210016, 210023, 210031, 210039, 
+    210048, 210054, 210061, 210068, 210076, 210083, 210091, 210099, 
+    210108, 210115, 210123, 210131, 210140, 210148, 210157, 210166, 
+    210176, 210181, 210187, 210193, 210200, 210206, 210213, 210220, 
+    210228, 210234, 210241, 210248, 210256, 210263, 210271, 210279, 
+    210288, 210294, 210301, 210308, 210316, 210323, 210331, 210339, 
+    210348, 210355, 210363, 210371, 210380, 210388, 210397, 210406, 
+    210416, 210422, 210429, 210436, 210444, 210451, 210459, 210467, 
+    210476, 210483, 210491, 210499, 210508, 210516, 210525, 210534, 
+    210544, 210551, 210559, 210567, 210576, 210584, 210593, 210602, 
+    210612, 210620, 210629, 210638, 210648, 210657, 210667, 210677, 
+    210688, 210692, 210697, 210702, 210708, 210713, 210719, 210725, 
+    210732, 210737, 210743, 210749, 210756, 210762, 210769, 210776, 
+    210784, 210789, 210795, 210801, 210808, 210814, 210821, 210828, 
+    210836, 210842, 210849, 210856, 210864, 210871, 210879, 210887, 
+    210896, 210901, 210907, 210913, 210920, 210926, 210933, 210940, 
+    210948, 210954, 210961, 210968, 210976, 210983, 210991, 210999, 
+    211008, 211014, 211021, 211028, 211036, 211043, 211051, 211059, 
+    211068, 211075, 211083, 211091, 211100, 211108, 211117, 211126, 
+    211136, 211141, 211147, 211153, 211160, 211166, 211173, 211180, 
+    211188, 211194, 211201, 211208, 211216, 211223, 211231, 211239, 
+    211248, 211254, 211261, 211268, 211276, 211283, 211291, 211299, 
+    211308, 211315, 211323, 211331, 211340, 211348, 211357, 211366, 
+    211376, 211382, 211389, 211396, 211404, 211411, 211419, 211427, 
+    211436, 211443, 211451, 211459, 211468, 211476, 211485, 211494, 
+    211504, 211511, 211519, 211527, 211536, 211544, 211553, 211562, 
+    211572, 211580, 211589, 211598, 211608, 211617, 211627, 211637, 
+    211648, 211653, 211659, 211665, 211672, 211678, 211685, 211692, 
+    211700, 211706, 211713, 211720, 211728, 211735, 211743, 211751, 
+    211760, 211766, 211773, 211780, 211788, 211795, 211803, 211811, 
+    211820, 211827, 211835, 211843, 211852, 211860, 211869, 211878, 
+    211888, 211894, 211901, 211908, 211916, 211923, 211931, 211939, 
+    211948, 211955, 211963, 211971, 211980, 211988, 211997, 212006, 
+    212016, 212023, 212031, 212039, 212048, 212056, 212065, 212074, 
+    212084, 212092, 212101, 212110, 212120, 212129, 212139, 212149, 
+    212160, 212166, 212173, 212180, 212188, 212195, 212203, 212211, 
+    212220, 212227, 212235, 212243, 212252, 212260, 212269, 212278, 
+    212288, 212295, 212303, 212311, 212320, 212328, 212337, 212346, 
+    212356, 212364, 212373, 212382, 212392, 212401, 212411, 212421, 
+    212432, 212439, 212447, 212455, 212464, 212472, 212481, 212490, 
+    212500, 212508, 212517, 212526, 212536, 212545, 212555, 212565, 
+    212576, 212584, 212593, 212602, 212612, 212621, 212631, 212641, 
+    212652, 212661, 212671, 212681, 212692, 212702, 212713, 212724, 
+    212736, 212740, 212745, 212750, 212756, 212761, 212767, 212773, 
+    212780, 212785, 212791, 212797, 212804, 212810, 212817, 212824, 
+    212832, 212837, 212843, 212849, 212856, 212862, 212869, 212876, 
+    212884, 212890, 212897, 212904, 212912, 212919, 212927, 212935, 
+    212944, 212949, 212955, 212961, 212968, 212974, 212981, 212988, 
+    212996, 213002, 213009, 213016, 213024, 213031, 213039, 213047, 
+    213056, 213062, 213069, 213076, 213084, 213091, 213099, 213107, 
+    213116, 213123, 213131, 213139, 213148, 213156, 213165, 213174, 
+    213184, 213189, 213195, 213201, 213208, 213214, 213221, 213228, 
+    213236, 213242, 213249, 213256, 213264, 213271, 213279, 213287, 
+    213296, 213302, 213309, 213316, 213324, 213331, 213339, 213347, 
+    213356, 213363, 213371, 213379, 213388, 213396, 213405, 213414, 
+    213424, 213430, 213437, 213444, 213452, 213459, 213467, 213475, 
+    213484, 213491, 213499, 213507, 213516, 213524, 213533, 213542, 
+    213552, 213559, 213567, 213575, 213584, 213592, 213601, 213610, 
+    213620, 213628, 213637, 213646, 213656, 213665, 213675, 213685, 
+    213696, 213701, 213707, 213713, 213720, 213726, 213733, 213740, 
+    213748, 213754, 213761, 213768, 213776, 213783, 213791, 213799, 
+    213808, 213814, 213821, 213828, 213836, 213843, 213851, 213859, 
+    213868, 213875, 213883, 213891, 213900, 213908, 213917, 213926, 
+    213936, 213942, 213949, 213956, 213964, 213971, 213979, 213987, 
+    213996, 214003, 214011, 214019, 214028, 214036, 214045, 214054, 
+    214064, 214071, 214079, 214087, 214096, 214104, 214113, 214122, 
+    214132, 214140, 214149, 214158, 214168, 214177, 214187, 214197, 
+    214208, 214214, 214221, 214228, 214236, 214243, 214251, 214259, 
+    214268, 214275, 214283, 214291, 214300, 214308, 214317, 214326, 
+    214336, 214343, 214351, 214359, 214368, 214376, 214385, 214394, 
+    214404, 214412, 214421, 214430, 214440, 214449, 214459, 214469, 
+    214480, 214487, 214495, 214503, 214512, 214520, 214529, 214538, 
+    214548, 214556, 214565, 214574, 214584, 214593, 214603, 214613, 
+    214624, 214632, 214641, 214650, 214660, 214669, 214679, 214689, 
+    214700, 214709, 214719, 214729, 214740, 214750, 214761, 214772, 
+    214784, 214789, 214795, 214801, 214808, 214814, 214821, 214828, 
+    214836, 214842, 214849, 214856, 214864, 214871, 214879, 214887, 
+    214896, 214902, 214909, 214916, 214924, 214931, 214939, 214947, 
+    214956, 214963, 214971, 214979, 214988, 214996, 215005, 215014, 
+    215024, 215030, 215037, 215044, 215052, 215059, 215067, 215075, 
+    215084, 215091, 215099, 215107, 215116, 215124, 215133, 215142, 
+    215152, 215159, 215167, 215175, 215184, 215192, 215201, 215210, 
+    215220, 215228, 215237, 215246, 215256, 215265, 215275, 215285, 
+    215296, 215302, 215309, 215316, 215324, 215331, 215339, 215347, 
+    215356, 215363, 215371, 215379, 215388, 215396, 215405, 215414, 
+    215424, 215431, 215439, 215447, 215456, 215464, 215473, 215482, 
+    215492, 215500, 215509, 215518, 215528, 215537, 215547, 215557, 
+    215568, 215575, 215583, 215591, 215600, 215608, 215617, 215626, 
+    215636, 215644, 215653, 215662, 215672, 215681, 215691, 215701, 
+    215712, 215720, 215729, 215738, 215748, 215757, 215767, 215777, 
+    215788, 215797, 215807, 215817, 215828, 215838, 215849, 215860, 
+    215872, 215878, 215885, 215892, 215900, 215907, 215915, 215923, 
+    215932, 215939, 215947, 215955, 215964, 215972, 215981, 215990, 
+    216000, 216007, 216015, 216023, 216032, 216040, 216049, 216058, 
+    216068, 216076, 216085, 216094, 216104, 216113, 216123, 216133, 
+    216144, 216151, 216159, 216167, 216176, 216184, 216193, 216202, 
+    216212, 216220, 216229, 216238, 216248, 216257, 216267, 216277, 
+    216288, 216296, 216305, 216314, 216324, 216333, 216343, 216353, 
+    216364, 216373, 216383, 216393, 216404, 216414, 216425, 216436, 
+    216448, 216455, 216463, 216471, 216480, 216488, 216497, 216506, 
+    216516, 216524, 216533, 216542, 216552, 216561, 216571, 216581, 
+    216592, 216600, 216609, 216618, 216628, 216637, 216647, 216657, 
+    216668, 216677, 216687, 216697, 216708, 216718, 216729, 216740, 
+    216752, 216760, 216769, 216778, 216788, 216797, 216807, 216817, 
+    216828, 216837, 216847, 216857, 216868, 216878, 216889, 216900, 
+    216912, 216921, 216931, 216941, 216952, 216962, 216973, 216984, 
+    216996, 217006, 217017, 217028, 217040, 217051, 217063, 217075, 
+    217088, 217092, 217097, 217102, 217108, 217113, 217119, 217125, 
+    217132, 217137, 217143, 217149, 217156, 217162, 217169, 217176, 
+    217184, 217189, 217195, 217201, 217208, 217214, 217221, 217228, 
+    217236, 217242, 217249, 217256, 217264, 217271, 217279, 217287, 
+    217296, 217301, 217307, 217313, 217320, 217326, 217333, 217340, 
+    217348, 217354, 217361, 217368, 217376, 217383, 217391, 217399, 
+    217408, 217414, 217421, 217428, 217436, 217443, 217451, 217459, 
+    217468, 217475, 217483, 217491, 217500, 217508, 217517, 217526, 
+    217536, 217541, 217547, 217553, 217560, 217566, 217573, 217580, 
+    217588, 217594, 217601, 217608, 217616, 217623, 217631, 217639, 
+    217648, 217654, 217661, 217668, 217676, 217683, 217691, 217699, 
+    217708, 217715, 217723, 217731, 217740, 217748, 217757, 217766, 
+    217776, 217782, 217789, 217796, 217804, 217811, 217819, 217827, 
+    217836, 217843, 217851, 217859, 217868, 217876, 217885, 217894, 
+    217904, 217911, 217919, 217927, 217936, 217944, 217953, 217962, 
+    217972, 217980, 217989, 217998, 218008, 218017, 218027, 218037, 
+    218048, 218053, 218059, 218065, 218072, 218078, 218085, 218092, 
+    218100, 218106, 218113, 218120, 218128, 218135, 218143, 218151, 
+    218160, 218166, 218173, 218180, 218188, 218195, 218203, 218211, 
+    218220, 218227, 218235, 218243, 218252, 218260, 218269, 218278, 
+    218288, 218294, 218301, 218308, 218316, 218323, 218331, 218339, 
+    218348, 218355, 218363, 218371, 218380, 218388, 218397, 218406, 
+    218416, 218423, 218431, 218439, 218448, 218456, 218465, 218474, 
+    218484, 218492, 218501, 218510, 218520, 218529, 218539, 218549, 
+    218560, 218566, 218573, 218580, 218588, 218595, 218603, 218611, 
+    218620, 218627, 218635, 218643, 218652, 218660, 218669, 218678, 
+    218688, 218695, 218703, 218711, 218720, 218728, 218737, 218746, 
+    218756, 218764, 218773, 218782, 218792, 218801, 218811, 218821, 
+    218832, 218839, 218847, 218855, 218864, 218872, 218881, 218890, 
+    218900, 218908, 218917, 218926, 218936, 218945, 218955, 218965, 
+    218976, 218984, 218993, 219002, 219012, 219021, 219031, 219041, 
+    219052, 219061, 219071, 219081, 219092, 219102, 219113, 219124, 
+    219136, 219141, 219147, 219153, 219160, 219166, 219173, 219180, 
+    219188, 219194, 219201, 219208, 219216, 219223, 219231, 219239, 
+    219248, 219254, 219261, 219268, 219276, 219283, 219291, 219299, 
+    219308, 219315, 219323, 219331, 219340, 219348, 219357, 219366, 
+    219376, 219382, 219389, 219396, 219404, 219411, 219419, 219427, 
+    219436, 219443, 219451, 219459, 219468, 219476, 219485, 219494, 
+    219504, 219511, 219519, 219527, 219536, 219544, 219553, 219562, 
+    219572, 219580, 219589, 219598, 219608, 219617, 219627, 219637, 
+    219648, 219654, 219661, 219668, 219676, 219683, 219691, 219699, 
+    219708, 219715, 219723, 219731, 219740, 219748, 219757, 219766, 
+    219776, 219783, 219791, 219799, 219808, 219816, 219825, 219834, 
+    219844, 219852, 219861, 219870, 219880, 219889, 219899, 219909, 
+    219920, 219927, 219935, 219943, 219952, 219960, 219969, 219978, 
+    219988, 219996, 220005, 220014, 220024, 220033, 220043, 220053, 
+    220064, 220072, 220081, 220090, 220100, 220109, 220119, 220129, 
+    220140, 220149, 220159, 220169, 220180, 220190, 220201, 220212, 
+    220224, 220230, 220237, 220244, 220252, 220259, 220267, 220275, 
+    220284, 220291, 220299, 220307, 220316, 220324, 220333, 220342, 
+    220352, 220359, 220367, 220375, 220384, 220392, 220401, 220410, 
+    220420, 220428, 220437, 220446, 220456, 220465, 220475, 220485, 
+    220496, 220503, 220511, 220519, 220528, 220536, 220545, 220554, 
+    220564, 220572, 220581, 220590, 220600, 220609, 220619, 220629, 
+    220640, 220648, 220657, 220666, 220676, 220685, 220695, 220705, 
+    220716, 220725, 220735, 220745, 220756, 220766, 220777, 220788, 
+    220800, 220807, 220815, 220823, 220832, 220840, 220849, 220858, 
+    220868, 220876, 220885, 220894, 220904, 220913, 220923, 220933, 
+    220944, 220952, 220961, 220970, 220980, 220989, 220999, 221009, 
+    221020, 221029, 221039, 221049, 221060, 221070, 221081, 221092, 
+    221104, 221112, 221121, 221130, 221140, 221149, 221159, 221169, 
+    221180, 221189, 221199, 221209, 221220, 221230, 221241, 221252, 
+    221264, 221273, 221283, 221293, 221304, 221314, 221325, 221336, 
+    221348, 221358, 221369, 221380, 221392, 221403, 221415, 221427, 
+    221440, 221445, 221451, 221457, 221464, 221470, 221477, 221484, 
+    221492, 221498, 221505, 221512, 221520, 221527, 221535, 221543, 
+    221552, 221558, 221565, 221572, 221580, 221587, 221595, 221603, 
+    221612, 221619, 221627, 221635, 221644, 221652, 221661, 221670, 
+    221680, 221686, 221693, 221700, 221708, 221715, 221723, 221731, 
+    221740, 221747, 221755, 221763, 221772, 221780, 221789, 221798, 
+    221808, 221815, 221823, 221831, 221840, 221848, 221857, 221866, 
+    221876, 221884, 221893, 221902, 221912, 221921, 221931, 221941, 
+    221952, 221958, 221965, 221972, 221980, 221987, 221995, 222003, 
+    222012, 222019, 222027, 222035, 222044, 222052, 222061, 222070, 
+    222080, 222087, 222095, 222103, 222112, 222120, 222129, 222138, 
+    222148, 222156, 222165, 222174, 222184, 222193, 222203, 222213, 
+    222224, 222231, 222239, 222247, 222256, 222264, 222273, 222282, 
+    222292, 222300, 222309, 222318, 222328, 222337, 222347, 222357, 
+    222368, 222376, 222385, 222394, 222404, 222413, 222423, 222433, 
+    222444, 222453, 222463, 222473, 222484, 222494, 222505, 222516, 
+    222528, 222534, 222541, 222548, 222556, 222563, 222571, 222579, 
+    222588, 222595, 222603, 222611, 222620, 222628, 222637, 222646, 
+    222656, 222663, 222671, 222679, 222688, 222696, 222705, 222714, 
+    222724, 222732, 222741, 222750, 222760, 222769, 222779, 222789, 
+    222800, 222807, 222815, 222823, 222832, 222840, 222849, 222858, 
+    222868, 222876, 222885, 222894, 222904, 222913, 222923, 222933, 
+    222944, 222952, 222961, 222970, 222980, 222989, 222999, 223009, 
+    223020, 223029, 223039, 223049, 223060, 223070, 223081, 223092, 
+    223104, 223111, 223119, 223127, 223136, 223144, 223153, 223162, 
+    223172, 223180, 223189, 223198, 223208, 223217, 223227, 223237, 
+    223248, 223256, 223265, 223274, 223284, 223293, 223303, 223313, 
+    223324, 223333, 223343, 223353, 223364, 223374, 223385, 223396, 
+    223408, 223416, 223425, 223434, 223444, 223453, 223463, 223473, 
+    223484, 223493, 223503, 223513, 223524, 223534, 223545, 223556, 
+    223568, 223577, 223587, 223597, 223608, 223618, 223629, 223640, 
+    223652, 223662, 223673, 223684, 223696, 223707, 223719, 223731, 
+    223744, 223750, 223757, 223764, 223772, 223779, 223787, 223795, 
+    223804, 223811, 223819, 223827, 223836, 223844, 223853, 223862, 
+    223872, 223879, 223887, 223895, 223904, 223912, 223921, 223930, 
+    223940, 223948, 223957, 223966, 223976, 223985, 223995, 224005, 
+    224016, 224023, 224031, 224039, 224048, 224056, 224065, 224074, 
+    224084, 224092, 224101, 224110, 224120, 224129, 224139, 224149, 
+    224160, 224168, 224177, 224186, 224196, 224205, 224215, 224225, 
+    224236, 224245, 224255, 224265, 224276, 224286, 224297, 224308, 
+    224320, 224327, 224335, 224343, 224352, 224360, 224369, 224378, 
+    224388, 224396, 224405, 224414, 224424, 224433, 224443, 224453, 
+    224464, 224472, 224481, 224490, 224500, 224509, 224519, 224529, 
+    224540, 224549, 224559, 224569, 224580, 224590, 224601, 224612, 
+    224624, 224632, 224641, 224650, 224660, 224669, 224679, 224689, 
+    224700, 224709, 224719, 224729, 224740, 224750, 224761, 224772, 
+    224784, 224793, 224803, 224813, 224824, 224834, 224845, 224856, 
+    224868, 224878, 224889, 224900, 224912, 224923, 224935, 224947, 
+    224960, 224967, 224975, 224983, 224992, 225000, 225009, 225018, 
+    225028, 225036, 225045, 225054, 225064, 225073, 225083, 225093, 
+    225104, 225112, 225121, 225130, 225140, 225149, 225159, 225169, 
+    225180, 225189, 225199, 225209, 225220, 225230, 225241, 225252, 
+    225264, 225272, 225281, 225290, 225300, 225309, 225319, 225329, 
+    225340, 225349, 225359, 225369, 225380, 225390, 225401, 225412, 
+    225424, 225433, 225443, 225453, 225464, 225474, 225485, 225496, 
+    225508, 225518, 225529, 225540, 225552, 225563, 225575, 225587, 
+    225600, 225608, 225617, 225626, 225636, 225645, 225655, 225665, 
+    225676, 225685, 225695, 225705, 225716, 225726, 225737, 225748, 
+    225760, 225769, 225779, 225789, 225800, 225810, 225821, 225832, 
+    225844, 225854, 225865, 225876, 225888, 225899, 225911, 225923, 
+    225936, 225945, 225955, 225965, 225976, 225986, 225997, 226008, 
+    226020, 226030, 226041, 226052, 226064, 226075, 226087, 226099, 
+    226112, 226122, 226133, 226144, 226156, 226167, 226179, 226191, 
+    226204, 226215, 226227, 226239, 226252, 226264, 226277, 226290, 
+    226304, 226308, 226313, 226318, 226324, 226329, 226335, 226341, 
+    226348, 226353, 226359, 226365, 226372, 226378, 226385, 226392, 
+    226400, 226405, 226411, 226417, 226424, 226430, 226437, 226444, 
+    226452, 226458, 226465, 226472, 226480, 226487, 226495, 226503, 
+    226512, 226517, 226523, 226529, 226536, 226542, 226549, 226556, 
+    226564, 226570, 226577, 226584, 226592, 226599, 226607, 226615, 
+    226624, 226630, 226637, 226644, 226652, 226659, 226667, 226675, 
+    226684, 226691, 226699, 226707, 226716, 226724, 226733, 226742, 
+    226752, 226757, 226763, 226769, 226776, 226782, 226789, 226796, 
+    226804, 226810, 226817, 226824, 226832, 226839, 226847, 226855, 
+    226864, 226870, 226877, 226884, 226892, 226899, 226907, 226915, 
+    226924, 226931, 226939, 226947, 226956, 226964, 226973, 226982, 
+    226992, 226998, 227005, 227012, 227020, 227027, 227035, 227043, 
+    227052, 227059, 227067, 227075, 227084, 227092, 227101, 227110, 
+    227120, 227127, 227135, 227143, 227152, 227160, 227169, 227178, 
+    227188, 227196, 227205, 227214, 227224, 227233, 227243, 227253, 
+    227264, 227269, 227275, 227281, 227288, 227294, 227301, 227308, 
+    227316, 227322, 227329, 227336, 227344, 227351, 227359, 227367, 
+    227376, 227382, 227389, 227396, 227404, 227411, 227419, 227427, 
+    227436, 227443, 227451, 227459, 227468, 227476, 227485, 227494, 
+    227504, 227510, 227517, 227524, 227532, 227539, 227547, 227555, 
+    227564, 227571, 227579, 227587, 227596, 227604, 227613, 227622, 
+    227632, 227639, 227647, 227655, 227664, 227672, 227681, 227690, 
+    227700, 227708, 227717, 227726, 227736, 227745, 227755, 227765, 
+    227776, 227782, 227789, 227796, 227804, 227811, 227819, 227827, 
+    227836, 227843, 227851, 227859, 227868, 227876, 227885, 227894, 
+    227904, 227911, 227919, 227927, 227936, 227944, 227953, 227962, 
+    227972, 227980, 227989, 227998, 228008, 228017, 228027, 228037, 
+    228048, 228055, 228063, 228071, 228080, 228088, 228097, 228106, 
+    228116, 228124, 228133, 228142, 228152, 228161, 228171, 228181, 
+    228192, 228200, 228209, 228218, 228228, 228237, 228247, 228257, 
+    228268, 228277, 228287, 228297, 228308, 228318, 228329, 228340, 
+    228352, 228357, 228363, 228369, 228376, 228382, 228389, 228396, 
+    228404, 228410, 228417, 228424, 228432, 228439, 228447, 228455, 
+    228464, 228470, 228477, 228484, 228492, 228499, 228507, 228515, 
+    228524, 228531, 228539, 228547, 228556, 228564, 228573, 228582, 
+    228592, 228598, 228605, 228612, 228620, 228627, 228635, 228643, 
+    228652, 228659, 228667, 228675, 228684, 228692, 228701, 228710, 
+    228720, 228727, 228735, 228743, 228752, 228760, 228769, 228778, 
+    228788, 228796, 228805, 228814, 228824, 228833, 228843, 228853, 
+    228864, 228870, 228877, 228884, 228892, 228899, 228907, 228915, 
+    228924, 228931, 228939, 228947, 228956, 228964, 228973, 228982, 
+    228992, 228999, 229007, 229015, 229024, 229032, 229041, 229050, 
+    229060, 229068, 229077, 229086, 229096, 229105, 229115, 229125, 
+    229136, 229143, 229151, 229159, 229168, 229176, 229185, 229194, 
+    229204, 229212, 229221, 229230, 229240, 229249, 229259, 229269, 
+    229280, 229288, 229297, 229306, 229316, 229325, 229335, 229345, 
+    229356, 229365, 229375, 229385, 229396, 229406, 229417, 229428, 
+    229440, 229446, 229453, 229460, 229468, 229475, 229483, 229491, 
+    229500, 229507, 229515, 229523, 229532, 229540, 229549, 229558, 
+    229568, 229575, 229583, 229591, 229600, 229608, 229617, 229626, 
+    229636, 229644, 229653, 229662, 229672, 229681, 229691, 229701, 
+    229712, 229719, 229727, 229735, 229744, 229752, 229761, 229770, 
+    229780, 229788, 229797, 229806, 229816, 229825, 229835, 229845, 
+    229856, 229864, 229873, 229882, 229892, 229901, 229911, 229921, 
+    229932, 229941, 229951, 229961, 229972, 229982, 229993, 230004, 
+    230016, 230023, 230031, 230039, 230048, 230056, 230065, 230074, 
+    230084, 230092, 230101, 230110, 230120, 230129, 230139, 230149, 
+    230160, 230168, 230177, 230186, 230196, 230205, 230215, 230225, 
+    230236, 230245, 230255, 230265, 230276, 230286, 230297, 230308, 
+    230320, 230328, 230337, 230346, 230356, 230365, 230375, 230385, 
+    230396, 230405, 230415, 230425, 230436, 230446, 230457, 230468, 
+    230480, 230489, 230499, 230509, 230520, 230530, 230541, 230552, 
+    230564, 230574, 230585, 230596, 230608, 230619, 230631, 230643, 
+    230656, 230661, 230667, 230673, 230680, 230686, 230693, 230700, 
+    230708, 230714, 230721, 230728, 230736, 230743, 230751, 230759, 
+    230768, 230774, 230781, 230788, 230796, 230803, 230811, 230819, 
+    230828, 230835, 230843, 230851, 230860, 230868, 230877, 230886, 
+    230896, 230902, 230909, 230916, 230924, 230931, 230939, 230947, 
+    230956, 230963, 230971, 230979, 230988, 230996, 231005, 231014, 
+    231024, 231031, 231039, 231047, 231056, 231064, 231073, 231082, 
+    231092, 231100, 231109, 231118, 231128, 231137, 231147, 231157, 
+    231168, 231174, 231181, 231188, 231196, 231203, 231211, 231219, 
+    231228, 231235, 231243, 231251, 231260, 231268, 231277, 231286, 
+    231296, 231303, 231311, 231319, 231328, 231336, 231345, 231354, 
+    231364, 231372, 231381, 231390, 231400, 231409, 231419, 231429, 
+    231440, 231447, 231455, 231463, 231472, 231480, 231489, 231498, 
+    231508, 231516, 231525, 231534, 231544, 231553, 231563, 231573, 
+    231584, 231592, 231601, 231610, 231620, 231629, 231639, 231649, 
+    231660, 231669, 231679, 231689, 231700, 231710, 231721, 231732, 
+    231744, 231750, 231757, 231764, 231772, 231779, 231787, 231795, 
+    231804, 231811, 231819, 231827, 231836, 231844, 231853, 231862, 
+    231872, 231879, 231887, 231895, 231904, 231912, 231921, 231930, 
+    231940, 231948, 231957, 231966, 231976, 231985, 231995, 232005, 
+    232016, 232023, 232031, 232039, 232048, 232056, 232065, 232074, 
+    232084, 232092, 232101, 232110, 232120, 232129, 232139, 232149, 
+    232160, 232168, 232177, 232186, 232196, 232205, 232215, 232225, 
+    232236, 232245, 232255, 232265, 232276, 232286, 232297, 232308, 
+    232320, 232327, 232335, 232343, 232352, 232360, 232369, 232378, 
+    232388, 232396, 232405, 232414, 232424, 232433, 232443, 232453, 
+    232464, 232472, 232481, 232490, 232500, 232509, 232519, 232529, 
+    232540, 232549, 232559, 232569, 232580, 232590, 232601, 232612, 
+    232624, 232632, 232641, 232650, 232660, 232669, 232679, 232689, 
+    232700, 232709, 232719, 232729, 232740, 232750, 232761, 232772, 
+    232784, 232793, 232803, 232813, 232824, 232834, 232845, 232856, 
+    232868, 232878, 232889, 232900, 232912, 232923, 232935, 232947, 
+    232960, 232966, 232973, 232980, 232988, 232995, 233003, 233011, 
+    233020, 233027, 233035, 233043, 233052, 233060, 233069, 233078, 
+    233088, 233095, 233103, 233111, 233120, 233128, 233137, 233146, 
+    233156, 233164, 233173, 233182, 233192, 233201, 233211, 233221, 
+    233232, 233239, 233247, 233255, 233264, 233272, 233281, 233290, 
+    233300, 233308, 233317, 233326, 233336, 233345, 233355, 233365, 
+    233376, 233384, 233393, 233402, 233412, 233421, 233431, 233441, 
+    233452, 233461, 233471, 233481, 233492, 233502, 233513, 233524, 
+    233536, 233543, 233551, 233559, 233568, 233576, 233585, 233594, 
+    233604, 233612, 233621, 233630, 233640, 233649, 233659, 233669, 
+    233680, 233688, 233697, 233706, 233716, 233725, 233735, 233745, 
+    233756, 233765, 233775, 233785, 233796, 233806, 233817, 233828, 
+    233840, 233848, 233857, 233866, 233876, 233885, 233895, 233905, 
+    233916, 233925, 233935, 233945, 233956, 233966, 233977, 233988, 
+    234000, 234009, 234019, 234029, 234040, 234050, 234061, 234072, 
+    234084, 234094, 234105, 234116, 234128, 234139, 234151, 234163, 
+    234176, 234183, 234191, 234199, 234208, 234216, 234225, 234234, 
+    234244, 234252, 234261, 234270, 234280, 234289, 234299, 234309, 
+    234320, 234328, 234337, 234346, 234356, 234365, 234375, 234385, 
+    234396, 234405, 234415, 234425, 234436, 234446, 234457, 234468, 
+    234480, 234488, 234497, 234506, 234516, 234525, 234535, 234545, 
+    234556, 234565, 234575, 234585, 234596, 234606, 234617, 234628, 
+    234640, 234649, 234659, 234669, 234680, 234690, 234701, 234712, 
+    234724, 234734, 234745, 234756, 234768, 234779, 234791, 234803, 
+    234816, 234824, 234833, 234842, 234852, 234861, 234871, 234881, 
+    234892, 234901, 234911, 234921, 234932, 234942, 234953, 234964, 
+    234976, 234985, 234995, 235005, 235016, 235026, 235037, 235048, 
+    235060, 235070, 235081, 235092, 235104, 235115, 235127, 235139, 
+    235152, 235161, 235171, 235181, 235192, 235202, 235213, 235224, 
+    235236, 235246, 235257, 235268, 235280, 235291, 235303, 235315, 
+    235328, 235338, 235349, 235360, 235372, 235383, 235395, 235407, 
+    235420, 235431, 235443, 235455, 235468, 235480, 235493, 235506, 
+    235520, 235525, 235531, 235537, 235544, 235550, 235557, 235564, 
+    235572, 235578, 235585, 235592, 235600, 235607, 235615, 235623, 
+    235632, 235638, 235645, 235652, 235660, 235667, 235675, 235683, 
+    235692, 235699, 235707, 235715, 235724, 235732, 235741, 235750, 
+    235760, 235766, 235773, 235780, 235788, 235795, 235803, 235811, 
+    235820, 235827, 235835, 235843, 235852, 235860, 235869, 235878, 
+    235888, 235895, 235903, 235911, 235920, 235928, 235937, 235946, 
+    235956, 235964, 235973, 235982, 235992, 236001, 236011, 236021, 
+    236032, 236038, 236045, 236052, 236060, 236067, 236075, 236083, 
+    236092, 236099, 236107, 236115, 236124, 236132, 236141, 236150, 
+    236160, 236167, 236175, 236183, 236192, 236200, 236209, 236218, 
+    236228, 236236, 236245, 236254, 236264, 236273, 236283, 236293, 
+    236304, 236311, 236319, 236327, 236336, 236344, 236353, 236362, 
+    236372, 236380, 236389, 236398, 236408, 236417, 236427, 236437, 
+    236448, 236456, 236465, 236474, 236484, 236493, 236503, 236513, 
+    236524, 236533, 236543, 236553, 236564, 236574, 236585, 236596, 
+    236608, 236614, 236621, 236628, 236636, 236643, 236651, 236659, 
+    236668, 236675, 236683, 236691, 236700, 236708, 236717, 236726, 
+    236736, 236743, 236751, 236759, 236768, 236776, 236785, 236794, 
+    236804, 236812, 236821, 236830, 236840, 236849, 236859, 236869, 
+    236880, 236887, 236895, 236903, 236912, 236920, 236929, 236938, 
+    236948, 236956, 236965, 236974, 236984, 236993, 237003, 237013, 
+    237024, 237032, 237041, 237050, 237060, 237069, 237079, 237089, 
+    237100, 237109, 237119, 237129, 237140, 237150, 237161, 237172, 
+    237184, 237191, 237199, 237207, 237216, 237224, 237233, 237242, 
+    237252, 237260, 237269, 237278, 237288, 237297, 237307, 237317, 
+    237328, 237336, 237345, 237354, 237364, 237373, 237383, 237393, 
+    237404, 237413, 237423, 237433, 237444, 237454, 237465, 237476, 
+    237488, 237496, 237505, 237514, 237524, 237533, 237543, 237553, 
+    237564, 237573, 237583, 237593, 237604, 237614, 237625, 237636, 
+    237648, 237657, 237667, 237677, 237688, 237698, 237709, 237720, 
+    237732, 237742, 237753, 237764, 237776, 237787, 237799, 237811, 
+    237824, 237830, 237837, 237844, 237852, 237859, 237867, 237875, 
+    237884, 237891, 237899, 237907, 237916, 237924, 237933, 237942, 
+    237952, 237959, 237967, 237975, 237984, 237992, 238001, 238010, 
+    238020, 238028, 238037, 238046, 238056, 238065, 238075, 238085, 
+    238096, 238103, 238111, 238119, 238128, 238136, 238145, 238154, 
+    238164, 238172, 238181, 238190, 238200, 238209, 238219, 238229, 
+    238240, 238248, 238257, 238266, 238276, 238285, 238295, 238305, 
+    238316, 238325, 238335, 238345, 238356, 238366, 238377, 238388, 
+    238400, 238407, 238415, 238423, 238432, 238440, 238449, 238458, 
+    238468, 238476, 238485, 238494, 238504, 238513, 238523, 238533, 
+    238544, 238552, 238561, 238570, 238580, 238589, 238599, 238609, 
+    238620, 238629, 238639, 238649, 238660, 238670, 238681, 238692, 
+    238704, 238712, 238721, 238730, 238740, 238749, 238759, 238769, 
+    238780, 238789, 238799, 238809, 238820, 238830, 238841, 238852, 
+    238864, 238873, 238883, 238893, 238904, 238914, 238925, 238936, 
+    238948, 238958, 238969, 238980, 238992, 239003, 239015, 239027, 
+    239040, 239047, 239055, 239063, 239072, 239080, 239089, 239098, 
+    239108, 239116, 239125, 239134, 239144, 239153, 239163, 239173, 
+    239184, 239192, 239201, 239210, 239220, 239229, 239239, 239249, 
+    239260, 239269, 239279, 239289, 239300, 239310, 239321, 239332, 
+    239344, 239352, 239361, 239370, 239380, 239389, 239399, 239409, 
+    239420, 239429, 239439, 239449, 239460, 239470, 239481, 239492, 
+    239504, 239513, 239523, 239533, 239544, 239554, 239565, 239576, 
+    239588, 239598, 239609, 239620, 239632, 239643, 239655, 239667, 
+    239680, 239688, 239697, 239706, 239716, 239725, 239735, 239745, 
+    239756, 239765, 239775, 239785, 239796, 239806, 239817, 239828, 
+    239840, 239849, 239859, 239869, 239880, 239890, 239901, 239912, 
+    239924, 239934, 239945, 239956, 239968, 239979, 239991, 240003, 
+    240016, 240025, 240035, 240045, 240056, 240066, 240077, 240088, 
+    240100, 240110, 240121, 240132, 240144, 240155, 240167, 240179, 
+    240192, 240202, 240213, 240224, 240236, 240247, 240259, 240271, 
+    240284, 240295, 240307, 240319, 240332, 240344, 240357, 240370, 
+    240384, 240390, 240397, 240404, 240412, 240419, 240427, 240435, 
+    240444, 240451, 240459, 240467, 240476, 240484, 240493, 240502, 
+    240512, 240519, 240527, 240535, 240544, 240552, 240561, 240570, 
+    240580, 240588, 240597, 240606, 240616, 240625, 240635, 240645, 
+    240656, 240663, 240671, 240679, 240688, 240696, 240705, 240714, 
+    240724, 240732, 240741, 240750, 240760, 240769, 240779, 240789, 
+    240800, 240808, 240817, 240826, 240836, 240845, 240855, 240865, 
+    240876, 240885, 240895, 240905, 240916, 240926, 240937, 240948, 
+    240960, 240967, 240975, 240983, 240992, 241000, 241009, 241018, 
+    241028, 241036, 241045, 241054, 241064, 241073, 241083, 241093, 
+    241104, 241112, 241121, 241130, 241140, 241149, 241159, 241169, 
+    241180, 241189, 241199, 241209, 241220, 241230, 241241, 241252, 
+    241264, 241272, 241281, 241290, 241300, 241309, 241319, 241329, 
+    241340, 241349, 241359, 241369, 241380, 241390, 241401, 241412, 
+    241424, 241433, 241443, 241453, 241464, 241474, 241485, 241496, 
+    241508, 241518, 241529, 241540, 241552, 241563, 241575, 241587, 
+    241600, 241607, 241615, 241623, 241632, 241640, 241649, 241658, 
+    241668, 241676, 241685, 241694, 241704, 241713, 241723, 241733, 
+    241744, 241752, 241761, 241770, 241780, 241789, 241799, 241809, 
+    241820, 241829, 241839, 241849, 241860, 241870, 241881, 241892, 
+    241904, 241912, 241921, 241930, 241940, 241949, 241959, 241969, 
+    241980, 241989, 241999, 242009, 242020, 242030, 242041, 242052, 
+    242064, 242073, 242083, 242093, 242104, 242114, 242125, 242136, 
+    242148, 242158, 242169, 242180, 242192, 242203, 242215, 242227, 
+    242240, 242248, 242257, 242266, 242276, 242285, 242295, 242305, 
+    242316, 242325, 242335, 242345, 242356, 242366, 242377, 242388, 
+    242400, 242409, 242419, 242429, 242440, 242450, 242461, 242472, 
+    242484, 242494, 242505, 242516, 242528, 242539, 242551, 242563, 
+    242576, 242585, 242595, 242605, 242616, 242626, 242637, 242648, 
+    242660, 242670, 242681, 242692, 242704, 242715, 242727, 242739, 
+    242752, 242762, 242773, 242784, 242796, 242807, 242819, 242831, 
+    242844, 242855, 242867, 242879, 242892, 242904, 242917, 242930, 
+    242944, 242951, 242959, 242967, 242976, 242984, 242993, 243002, 
+    243012, 243020, 243029, 243038, 243048, 243057, 243067, 243077, 
+    243088, 243096, 243105, 243114, 243124, 243133, 243143, 243153, 
+    243164, 243173, 243183, 243193, 243204, 243214, 243225, 243236, 
+    243248, 243256, 243265, 243274, 243284, 243293, 243303, 243313, 
+    243324, 243333, 243343, 243353, 243364, 243374, 243385, 243396, 
+    243408, 243417, 243427, 243437, 243448, 243458, 243469, 243480, 
+    243492, 243502, 243513, 243524, 243536, 243547, 243559, 243571, 
+    243584, 243592, 243601, 243610, 243620, 243629, 243639, 243649, 
+    243660, 243669, 243679, 243689, 243700, 243710, 243721, 243732, 
+    243744, 243753, 243763, 243773, 243784, 243794, 243805, 243816, 
+    243828, 243838, 243849, 243860, 243872, 243883, 243895, 243907, 
+    243920, 243929, 243939, 243949, 243960, 243970, 243981, 243992, 
+    244004, 244014, 244025, 244036, 244048, 244059, 244071, 244083, 
+    244096, 244106, 244117, 244128, 244140, 244151, 244163, 244175, 
+    244188, 244199, 244211, 244223, 244236, 244248, 244261, 244274, 
+    244288, 244296, 244305, 244314, 244324, 244333, 244343, 244353, 
+    244364, 244373, 244383, 244393, 244404, 244414, 244425, 244436, 
+    244448, 244457, 244467, 244477, 244488, 244498, 244509, 244520, 
+    244532, 244542, 244553, 244564, 244576, 244587, 244599, 244611, 
+    244624, 244633, 244643, 244653, 244664, 244674, 244685, 244696, 
+    244708, 244718, 244729, 244740, 244752, 244763, 244775, 244787, 
+    244800, 244810, 244821, 244832, 244844, 244855, 244867, 244879, 
+    244892, 244903, 244915, 244927, 244940, 244952, 244965, 244978, 
+    244992, 245001, 245011, 245021, 245032, 245042, 245053, 245064, 
+    245076, 245086, 245097, 245108, 245120, 245131, 245143, 245155, 
+    245168, 245178, 245189, 245200, 245212, 245223, 245235, 245247, 
+    245260, 245271, 245283, 245295, 245308, 245320, 245333, 245346, 
+    245360, 245370, 245381, 245392, 245404, 245415, 245427, 245439, 
+    245452, 245463, 245475, 245487, 245500, 245512, 245525, 245538, 
+    245552, 245563, 245575, 245587, 245600, 245612, 245625, 245638, 
+    245652, 245664, 245677, 245690, 245704, 245717, 245731, 245745, 
+    245760, 245761, 245763, 245765, 245768, 245770, 245773, 245776, 
+    245780, 245782, 245785, 245788, 245792, 245795, 245799, 245803, 
+    245808, 245810, 245813, 245816, 245820, 245823, 245827, 245831, 
+    245836, 245839, 245843, 245847, 245852, 245856, 245861, 245866, 
+    245872, 245874, 245877, 245880, 245884, 245887, 245891, 245895, 
+    245900, 245903, 245907, 245911, 245916, 245920, 245925, 245930, 
+    245936, 245939, 245943, 245947, 245952, 245956, 245961, 245966, 
+    245972, 245976, 245981, 245986, 245992, 245997, 246003, 246009, 
+    246016, 246018, 246021, 246024, 246028, 246031, 246035, 246039, 
+    246044, 246047, 246051, 246055, 246060, 246064, 246069, 246074, 
+    246080, 246083, 246087, 246091, 246096, 246100, 246105, 246110, 
+    246116, 246120, 246125, 246130, 246136, 246141, 246147, 246153, 
+    246160, 246163, 246167, 246171, 246176, 246180, 246185, 246190, 
+    246196, 246200, 246205, 246210, 246216, 246221, 246227, 246233, 
+    246240, 246244, 246249, 246254, 246260, 246265, 246271, 246277, 
+    246284, 246289, 246295, 246301, 246308, 246314, 246321, 246328, 
+    246336, 246338, 246341, 246344, 246348, 246351, 246355, 246359, 
+    246364, 246367, 246371, 246375, 246380, 246384, 246389, 246394, 
+    246400, 246403, 246407, 246411, 246416, 246420, 246425, 246430, 
+    246436, 246440, 246445, 246450, 246456, 246461, 246467, 246473, 
+    246480, 246483, 246487, 246491, 246496, 246500, 246505, 246510, 
+    246516, 246520, 246525, 246530, 246536, 246541, 246547, 246553, 
+    246560, 246564, 246569, 246574, 246580, 246585, 246591, 246597, 
+    246604, 246609, 246615, 246621, 246628, 246634, 246641, 246648, 
+    246656, 246659, 246663, 246667, 246672, 246676, 246681, 246686, 
+    246692, 246696, 246701, 246706, 246712, 246717, 246723, 246729, 
+    246736, 246740, 246745, 246750, 246756, 246761, 246767, 246773, 
+    246780, 246785, 246791, 246797, 246804, 246810, 246817, 246824, 
+    246832, 246836, 246841, 246846, 246852, 246857, 246863, 246869, 
+    246876, 246881, 246887, 246893, 246900, 246906, 246913, 246920, 
+    246928, 246933, 246939, 246945, 246952, 246958, 246965, 246972, 
+    246980, 246986, 246993, 247000, 247008, 247015, 247023, 247031, 
+    247040, 247042, 247045, 247048, 247052, 247055, 247059, 247063, 
+    247068, 247071, 247075, 247079, 247084, 247088, 247093, 247098, 
+    247104, 247107, 247111, 247115, 247120, 247124, 247129, 247134, 
+    247140, 247144, 247149, 247154, 247160, 247165, 247171, 247177, 
+    247184, 247187, 247191, 247195, 247200, 247204, 247209, 247214, 
+    247220, 247224, 247229, 247234, 247240, 247245, 247251, 247257, 
+    247264, 247268, 247273, 247278, 247284, 247289, 247295, 247301, 
+    247308, 247313, 247319, 247325, 247332, 247338, 247345, 247352, 
+    247360, 247363, 247367, 247371, 247376, 247380, 247385, 247390, 
+    247396, 247400, 247405, 247410, 247416, 247421, 247427, 247433, 
+    247440, 247444, 247449, 247454, 247460, 247465, 247471, 247477, 
+    247484, 247489, 247495, 247501, 247508, 247514, 247521, 247528, 
+    247536, 247540, 247545, 247550, 247556, 247561, 247567, 247573, 
+    247580, 247585, 247591, 247597, 247604, 247610, 247617, 247624, 
+    247632, 247637, 247643, 247649, 247656, 247662, 247669, 247676, 
+    247684, 247690, 247697, 247704, 247712, 247719, 247727, 247735, 
+    247744, 247747, 247751, 247755, 247760, 247764, 247769, 247774, 
+    247780, 247784, 247789, 247794, 247800, 247805, 247811, 247817, 
+    247824, 247828, 247833, 247838, 247844, 247849, 247855, 247861, 
+    247868, 247873, 247879, 247885, 247892, 247898, 247905, 247912, 
+    247920, 247924, 247929, 247934, 247940, 247945, 247951, 247957, 
+    247964, 247969, 247975, 247981, 247988, 247994, 248001, 248008, 
+    248016, 248021, 248027, 248033, 248040, 248046, 248053, 248060, 
+    248068, 248074, 248081, 248088, 248096, 248103, 248111, 248119, 
+    248128, 248132, 248137, 248142, 248148, 248153, 248159, 248165, 
+    248172, 248177, 248183, 248189, 248196, 248202, 248209, 248216, 
+    248224, 248229, 248235, 248241, 248248, 248254, 248261, 248268, 
+    248276, 248282, 248289, 248296, 248304, 248311, 248319, 248327, 
+    248336, 248341, 248347, 248353, 248360, 248366, 248373, 248380, 
+    248388, 248394, 248401, 248408, 248416, 248423, 248431, 248439, 
+    248448, 248454, 248461, 248468, 248476, 248483, 248491, 248499, 
+    248508, 248515, 248523, 248531, 248540, 248548, 248557, 248566, 
+    248576, 248578, 248581, 248584, 248588, 248591, 248595, 248599, 
+    248604, 248607, 248611, 248615, 248620, 248624, 248629, 248634, 
+    248640, 248643, 248647, 248651, 248656, 248660, 248665, 248670, 
+    248676, 248680, 248685, 248690, 248696, 248701, 248707, 248713, 
+    248720, 248723, 248727, 248731, 248736, 248740, 248745, 248750, 
+    248756, 248760, 248765, 248770, 248776, 248781, 248787, 248793, 
+    248800, 248804, 248809, 248814, 248820, 248825, 248831, 248837, 
+    248844, 248849, 248855, 248861, 248868, 248874, 248881, 248888, 
+    248896, 248899, 248903, 248907, 248912, 248916, 248921, 248926, 
+    248932, 248936, 248941, 248946, 248952, 248957, 248963, 248969, 
+    248976, 248980, 248985, 248990, 248996, 249001, 249007, 249013, 
+    249020, 249025, 249031, 249037, 249044, 249050, 249057, 249064, 
+    249072, 249076, 249081, 249086, 249092, 249097, 249103, 249109, 
+    249116, 249121, 249127, 249133, 249140, 249146, 249153, 249160, 
+    249168, 249173, 249179, 249185, 249192, 249198, 249205, 249212, 
+    249220, 249226, 249233, 249240, 249248, 249255, 249263, 249271, 
+    249280, 249283, 249287, 249291, 249296, 249300, 249305, 249310, 
+    249316, 249320, 249325, 249330, 249336, 249341, 249347, 249353, 
+    249360, 249364, 249369, 249374, 249380, 249385, 249391, 249397, 
+    249404, 249409, 249415, 249421, 249428, 249434, 249441, 249448, 
+    249456, 249460, 249465, 249470, 249476, 249481, 249487, 249493, 
+    249500, 249505, 249511, 249517, 249524, 249530, 249537, 249544, 
+    249552, 249557, 249563, 249569, 249576, 249582, 249589, 249596, 
+    249604, 249610, 249617, 249624, 249632, 249639, 249647, 249655, 
+    249664, 249668, 249673, 249678, 249684, 249689, 249695, 249701, 
+    249708, 249713, 249719, 249725, 249732, 249738, 249745, 249752, 
+    249760, 249765, 249771, 249777, 249784, 249790, 249797, 249804, 
+    249812, 249818, 249825, 249832, 249840, 249847, 249855, 249863, 
+    249872, 249877, 249883, 249889, 249896, 249902, 249909, 249916, 
+    249924, 249930, 249937, 249944, 249952, 249959, 249967, 249975, 
+    249984, 249990, 249997, 250004, 250012, 250019, 250027, 250035, 
+    250044, 250051, 250059, 250067, 250076, 250084, 250093, 250102, 
+    250112, 250115, 250119, 250123, 250128, 250132, 250137, 250142, 
+    250148, 250152, 250157, 250162, 250168, 250173, 250179, 250185, 
+    250192, 250196, 250201, 250206, 250212, 250217, 250223, 250229, 
+    250236, 250241, 250247, 250253, 250260, 250266, 250273, 250280, 
+    250288, 250292, 250297, 250302, 250308, 250313, 250319, 250325, 
+    250332, 250337, 250343, 250349, 250356, 250362, 250369, 250376, 
+    250384, 250389, 250395, 250401, 250408, 250414, 250421, 250428, 
+    250436, 250442, 250449, 250456, 250464, 250471, 250479, 250487, 
+    250496, 250500, 250505, 250510, 250516, 250521, 250527, 250533, 
+    250540, 250545, 250551, 250557, 250564, 250570, 250577, 250584, 
+    250592, 250597, 250603, 250609, 250616, 250622, 250629, 250636, 
+    250644, 250650, 250657, 250664, 250672, 250679, 250687, 250695, 
+    250704, 250709, 250715, 250721, 250728, 250734, 250741, 250748, 
+    250756, 250762, 250769, 250776, 250784, 250791, 250799, 250807, 
+    250816, 250822, 250829, 250836, 250844, 250851, 250859, 250867, 
+    250876, 250883, 250891, 250899, 250908, 250916, 250925, 250934, 
+    250944, 250948, 250953, 250958, 250964, 250969, 250975, 250981, 
+    250988, 250993, 250999, 251005, 251012, 251018, 251025, 251032, 
+    251040, 251045, 251051, 251057, 251064, 251070, 251077, 251084, 
+    251092, 251098, 251105, 251112, 251120, 251127, 251135, 251143, 
+    251152, 251157, 251163, 251169, 251176, 251182, 251189, 251196, 
+    251204, 251210, 251217, 251224, 251232, 251239, 251247, 251255, 
+    251264, 251270, 251277, 251284, 251292, 251299, 251307, 251315, 
+    251324, 251331, 251339, 251347, 251356, 251364, 251373, 251382, 
+    251392, 251397, 251403, 251409, 251416, 251422, 251429, 251436, 
+    251444, 251450, 251457, 251464, 251472, 251479, 251487, 251495, 
+    251504, 251510, 251517, 251524, 251532, 251539, 251547, 251555, 
+    251564, 251571, 251579, 251587, 251596, 251604, 251613, 251622, 
+    251632, 251638, 251645, 251652, 251660, 251667, 251675, 251683, 
+    251692, 251699, 251707, 251715, 251724, 251732, 251741, 251750, 
+    251760, 251767, 251775, 251783, 251792, 251800, 251809, 251818, 
+    251828, 251836, 251845, 251854, 251864, 251873, 251883, 251893, 
+    251904, 251906, 251909, 251912, 251916, 251919, 251923, 251927, 
+    251932, 251935, 251939, 251943, 251948, 251952, 251957, 251962, 
+    251968, 251971, 251975, 251979, 251984, 251988, 251993, 251998, 
+    252004, 252008, 252013, 252018, 252024, 252029, 252035, 252041, 
+    252048, 252051, 252055, 252059, 252064, 252068, 252073, 252078, 
+    252084, 252088, 252093, 252098, 252104, 252109, 252115, 252121, 
+    252128, 252132, 252137, 252142, 252148, 252153, 252159, 252165, 
+    252172, 252177, 252183, 252189, 252196, 252202, 252209, 252216, 
+    252224, 252227, 252231, 252235, 252240, 252244, 252249, 252254, 
+    252260, 252264, 252269, 252274, 252280, 252285, 252291, 252297, 
+    252304, 252308, 252313, 252318, 252324, 252329, 252335, 252341, 
+    252348, 252353, 252359, 252365, 252372, 252378, 252385, 252392, 
+    252400, 252404, 252409, 252414, 252420, 252425, 252431, 252437, 
+    252444, 252449, 252455, 252461, 252468, 252474, 252481, 252488, 
+    252496, 252501, 252507, 252513, 252520, 252526, 252533, 252540, 
+    252548, 252554, 252561, 252568, 252576, 252583, 252591, 252599, 
+    252608, 252611, 252615, 252619, 252624, 252628, 252633, 252638, 
+    252644, 252648, 252653, 252658, 252664, 252669, 252675, 252681, 
+    252688, 252692, 252697, 252702, 252708, 252713, 252719, 252725, 
+    252732, 252737, 252743, 252749, 252756, 252762, 252769, 252776, 
+    252784, 252788, 252793, 252798, 252804, 252809, 252815, 252821, 
+    252828, 252833, 252839, 252845, 252852, 252858, 252865, 252872, 
+    252880, 252885, 252891, 252897, 252904, 252910, 252917, 252924, 
+    252932, 252938, 252945, 252952, 252960, 252967, 252975, 252983, 
+    252992, 252996, 253001, 253006, 253012, 253017, 253023, 253029, 
+    253036, 253041, 253047, 253053, 253060, 253066, 253073, 253080, 
+    253088, 253093, 253099, 253105, 253112, 253118, 253125, 253132, 
+    253140, 253146, 253153, 253160, 253168, 253175, 253183, 253191, 
+    253200, 253205, 253211, 253217, 253224, 253230, 253237, 253244, 
+    253252, 253258, 253265, 253272, 253280, 253287, 253295, 253303, 
+    253312, 253318, 253325, 253332, 253340, 253347, 253355, 253363, 
+    253372, 253379, 253387, 253395, 253404, 253412, 253421, 253430, 
+    253440, 253443, 253447, 253451, 253456, 253460, 253465, 253470, 
+    253476, 253480, 253485, 253490, 253496, 253501, 253507, 253513, 
+    253520, 253524, 253529, 253534, 253540, 253545, 253551, 253557, 
+    253564, 253569, 253575, 253581, 253588, 253594, 253601, 253608, 
+    253616, 253620, 253625, 253630, 253636, 253641, 253647, 253653, 
+    253660, 253665, 253671, 253677, 253684, 253690, 253697, 253704, 
+    253712, 253717, 253723, 253729, 253736, 253742, 253749, 253756, 
+    253764, 253770, 253777, 253784, 253792, 253799, 253807, 253815, 
+    253824, 253828, 253833, 253838, 253844, 253849, 253855, 253861, 
+    253868, 253873, 253879, 253885, 253892, 253898, 253905, 253912, 
+    253920, 253925, 253931, 253937, 253944, 253950, 253957, 253964, 
+    253972, 253978, 253985, 253992, 254000, 254007, 254015, 254023, 
+    254032, 254037, 254043, 254049, 254056, 254062, 254069, 254076, 
+    254084, 254090, 254097, 254104, 254112, 254119, 254127, 254135, 
+    254144, 254150, 254157, 254164, 254172, 254179, 254187, 254195, 
+    254204, 254211, 254219, 254227, 254236, 254244, 254253, 254262, 
+    254272, 254276, 254281, 254286, 254292, 254297, 254303, 254309, 
+    254316, 254321, 254327, 254333, 254340, 254346, 254353, 254360, 
+    254368, 254373, 254379, 254385, 254392, 254398, 254405, 254412, 
+    254420, 254426, 254433, 254440, 254448, 254455, 254463, 254471, 
+    254480, 254485, 254491, 254497, 254504, 254510, 254517, 254524, 
+    254532, 254538, 254545, 254552, 254560, 254567, 254575, 254583, 
+    254592, 254598, 254605, 254612, 254620, 254627, 254635, 254643, 
+    254652, 254659, 254667, 254675, 254684, 254692, 254701, 254710, 
+    254720, 254725, 254731, 254737, 254744, 254750, 254757, 254764, 
+    254772, 254778, 254785, 254792, 254800, 254807, 254815, 254823, 
+    254832, 254838, 254845, 254852, 254860, 254867, 254875, 254883, 
+    254892, 254899, 254907, 254915, 254924, 254932, 254941, 254950, 
+    254960, 254966, 254973, 254980, 254988, 254995, 255003, 255011, 
+    255020, 255027, 255035, 255043, 255052, 255060, 255069, 255078, 
+    255088, 255095, 255103, 255111, 255120, 255128, 255137, 255146, 
+    255156, 255164, 255173, 255182, 255192, 255201, 255211, 255221, 
+    255232, 255235, 255239, 255243, 255248, 255252, 255257, 255262, 
+    255268, 255272, 255277, 255282, 255288, 255293, 255299, 255305, 
+    255312, 255316, 255321, 255326, 255332, 255337, 255343, 255349, 
+    255356, 255361, 255367, 255373, 255380, 255386, 255393, 255400, 
+    255408, 255412, 255417, 255422, 255428, 255433, 255439, 255445, 
+    255452, 255457, 255463, 255469, 255476, 255482, 255489, 255496, 
+    255504, 255509, 255515, 255521, 255528, 255534, 255541, 255548, 
+    255556, 255562, 255569, 255576, 255584, 255591, 255599, 255607, 
+    255616, 255620, 255625, 255630, 255636, 255641, 255647, 255653, 
+    255660, 255665, 255671, 255677, 255684, 255690, 255697, 255704, 
+    255712, 255717, 255723, 255729, 255736, 255742, 255749, 255756, 
+    255764, 255770, 255777, 255784, 255792, 255799, 255807, 255815, 
+    255824, 255829, 255835, 255841, 255848, 255854, 255861, 255868, 
+    255876, 255882, 255889, 255896, 255904, 255911, 255919, 255927, 
+    255936, 255942, 255949, 255956, 255964, 255971, 255979, 255987, 
+    255996, 256003, 256011, 256019, 256028, 256036, 256045, 256054, 
+    256064, 256068, 256073, 256078, 256084, 256089, 256095, 256101, 
+    256108, 256113, 256119, 256125, 256132, 256138, 256145, 256152, 
+    256160, 256165, 256171, 256177, 256184, 256190, 256197, 256204, 
+    256212, 256218, 256225, 256232, 256240, 256247, 256255, 256263, 
+    256272, 256277, 256283, 256289, 256296, 256302, 256309, 256316, 
+    256324, 256330, 256337, 256344, 256352, 256359, 256367, 256375, 
+    256384, 256390, 256397, 256404, 256412, 256419, 256427, 256435, 
+    256444, 256451, 256459, 256467, 256476, 256484, 256493, 256502, 
+    256512, 256517, 256523, 256529, 256536, 256542, 256549, 256556, 
+    256564, 256570, 256577, 256584, 256592, 256599, 256607, 256615, 
+    256624, 256630, 256637, 256644, 256652, 256659, 256667, 256675, 
+    256684, 256691, 256699, 256707, 256716, 256724, 256733, 256742, 
+    256752, 256758, 256765, 256772, 256780, 256787, 256795, 256803, 
+    256812, 256819, 256827, 256835, 256844, 256852, 256861, 256870, 
+    256880, 256887, 256895, 256903, 256912, 256920, 256929, 256938, 
+    256948, 256956, 256965, 256974, 256984, 256993, 257003, 257013, 
+    257024, 257028, 257033, 257038, 257044, 257049, 257055, 257061, 
+    257068, 257073, 257079, 257085, 257092, 257098, 257105, 257112, 
+    257120, 257125, 257131, 257137, 257144, 257150, 257157, 257164, 
+    257172, 257178, 257185, 257192, 257200, 257207, 257215, 257223, 
+    257232, 257237, 257243, 257249, 257256, 257262, 257269, 257276, 
+    257284, 257290, 257297, 257304, 257312, 257319, 257327, 257335, 
+    257344, 257350, 257357, 257364, 257372, 257379, 257387, 257395, 
+    257404, 257411, 257419, 257427, 257436, 257444, 257453, 257462, 
+    257472, 257477, 257483, 257489, 257496, 257502, 257509, 257516, 
+    257524, 257530, 257537, 257544, 257552, 257559, 257567, 257575, 
+    257584, 257590, 257597, 257604, 257612, 257619, 257627, 257635, 
+    257644, 257651, 257659, 257667, 257676, 257684, 257693, 257702, 
+    257712, 257718, 257725, 257732, 257740, 257747, 257755, 257763, 
+    257772, 257779, 257787, 257795, 257804, 257812, 257821, 257830, 
+    257840, 257847, 257855, 257863, 257872, 257880, 257889, 257898, 
+    257908, 257916, 257925, 257934, 257944, 257953, 257963, 257973, 
+    257984, 257989, 257995, 258001, 258008, 258014, 258021, 258028, 
+    258036, 258042, 258049, 258056, 258064, 258071, 258079, 258087, 
+    258096, 258102, 258109, 258116, 258124, 258131, 258139, 258147, 
+    258156, 258163, 258171, 258179, 258188, 258196, 258205, 258214, 
+    258224, 258230, 258237, 258244, 258252, 258259, 258267, 258275, 
+    258284, 258291, 258299, 258307, 258316, 258324, 258333, 258342, 
+    258352, 258359, 258367, 258375, 258384, 258392, 258401, 258410, 
+    258420, 258428, 258437, 258446, 258456, 258465, 258475, 258485, 
+    258496, 258502, 258509, 258516, 258524, 258531, 258539, 258547, 
+    258556, 258563, 258571, 258579, 258588, 258596, 258605, 258614, 
+    258624, 258631, 258639, 258647, 258656, 258664, 258673, 258682, 
+    258692, 258700, 258709, 258718, 258728, 258737, 258747, 258757, 
+    258768, 258775, 258783, 258791, 258800, 258808, 258817, 258826, 
+    258836, 258844, 258853, 258862, 258872, 258881, 258891, 258901, 
+    258912, 258920, 258929, 258938, 258948, 258957, 258967, 258977, 
+    258988, 258997, 259007, 259017, 259028, 259038, 259049, 259060, 
+    259072, 259074, 259077, 259080, 259084, 259087, 259091, 259095, 
+    259100, 259103, 259107, 259111, 259116, 259120, 259125, 259130, 
+    259136, 259139, 259143, 259147, 259152, 259156, 259161, 259166, 
+    259172, 259176, 259181, 259186, 259192, 259197, 259203, 259209, 
+    259216, 259219, 259223, 259227, 259232, 259236, 259241, 259246, 
+    259252, 259256, 259261, 259266, 259272, 259277, 259283, 259289, 
+    259296, 259300, 259305, 259310, 259316, 259321, 259327, 259333, 
+    259340, 259345, 259351, 259357, 259364, 259370, 259377, 259384, 
+    259392, 259395, 259399, 259403, 259408, 259412, 259417, 259422, 
+    259428, 259432, 259437, 259442, 259448, 259453, 259459, 259465, 
+    259472, 259476, 259481, 259486, 259492, 259497, 259503, 259509, 
+    259516, 259521, 259527, 259533, 259540, 259546, 259553, 259560, 
+    259568, 259572, 259577, 259582, 259588, 259593, 259599, 259605, 
+    259612, 259617, 259623, 259629, 259636, 259642, 259649, 259656, 
+    259664, 259669, 259675, 259681, 259688, 259694, 259701, 259708, 
+    259716, 259722, 259729, 259736, 259744, 259751, 259759, 259767, 
+    259776, 259779, 259783, 259787, 259792, 259796, 259801, 259806, 
+    259812, 259816, 259821, 259826, 259832, 259837, 259843, 259849, 
+    259856, 259860, 259865, 259870, 259876, 259881, 259887, 259893, 
+    259900, 259905, 259911, 259917, 259924, 259930, 259937, 259944, 
+    259952, 259956, 259961, 259966, 259972, 259977, 259983, 259989, 
+    259996, 260001, 260007, 260013, 260020, 260026, 260033, 260040, 
+    260048, 260053, 260059, 260065, 260072, 260078, 260085, 260092, 
+    260100, 260106, 260113, 260120, 260128, 260135, 260143, 260151, 
+    260160, 260164, 260169, 260174, 260180, 260185, 260191, 260197, 
+    260204, 260209, 260215, 260221, 260228, 260234, 260241, 260248, 
+    260256, 260261, 260267, 260273, 260280, 260286, 260293, 260300, 
+    260308, 260314, 260321, 260328, 260336, 260343, 260351, 260359, 
+    260368, 260373, 260379, 260385, 260392, 260398, 260405, 260412, 
+    260420, 260426, 260433, 260440, 260448, 260455, 260463, 260471, 
+    260480, 260486, 260493, 260500, 260508, 260515, 260523, 260531, 
+    260540, 260547, 260555, 260563, 260572, 260580, 260589, 260598, 
+    260608, 260611, 260615, 260619, 260624, 260628, 260633, 260638, 
+    260644, 260648, 260653, 260658, 260664, 260669, 260675, 260681, 
+    260688, 260692, 260697, 260702, 260708, 260713, 260719, 260725, 
+    260732, 260737, 260743, 260749, 260756, 260762, 260769, 260776, 
+    260784, 260788, 260793, 260798, 260804, 260809, 260815, 260821, 
+    260828, 260833, 260839, 260845, 260852, 260858, 260865, 260872, 
+    260880, 260885, 260891, 260897, 260904, 260910, 260917, 260924, 
+    260932, 260938, 260945, 260952, 260960, 260967, 260975, 260983, 
+    260992, 260996, 261001, 261006, 261012, 261017, 261023, 261029, 
+    261036, 261041, 261047, 261053, 261060, 261066, 261073, 261080, 
+    261088, 261093, 261099, 261105, 261112, 261118, 261125, 261132, 
+    261140, 261146, 261153, 261160, 261168, 261175, 261183, 261191, 
+    261200, 261205, 261211, 261217, 261224, 261230, 261237, 261244, 
+    261252, 261258, 261265, 261272, 261280, 261287, 261295, 261303, 
+    261312, 261318, 261325, 261332, 261340, 261347, 261355, 261363, 
+    261372, 261379, 261387, 261395, 261404, 261412, 261421, 261430, 
+    261440, 261444, 261449, 261454, 261460, 261465, 261471, 261477, 
+    261484, 261489, 261495, 261501, 261508, 261514, 261521, 261528, 
+    261536, 261541, 261547, 261553, 261560, 261566, 261573, 261580, 
+    261588, 261594, 261601, 261608, 261616, 261623, 261631, 261639, 
+    261648, 261653, 261659, 261665, 261672, 261678, 261685, 261692, 
+    261700, 261706, 261713, 261720, 261728, 261735, 261743, 261751, 
+    261760, 261766, 261773, 261780, 261788, 261795, 261803, 261811, 
+    261820, 261827, 261835, 261843, 261852, 261860, 261869, 261878, 
+    261888, 261893, 261899, 261905, 261912, 261918, 261925, 261932, 
+    261940, 261946, 261953, 261960, 261968, 261975, 261983, 261991, 
+    262000, 262006, 262013, 262020, 262028, 262035, 262043, 262051, 
+    262060, 262067, 262075, 262083, 262092, 262100, 262109, 262118, 
+    262128, 262134, 262141, 262148, 262156, 262163, 262171, 262179, 
+    262188, 262195, 262203, 262211, 262220, 262228, 262237, 262246, 
+    262256, 262263, 262271, 262279, 262288, 262296, 262305, 262314, 
+    262324, 262332, 262341, 262350, 262360, 262369, 262379, 262389, 
+    262400, 262403, 262407, 262411, 262416, 262420, 262425, 262430, 
+    262436, 262440, 262445, 262450, 262456, 262461, 262467, 262473, 
+    262480, 262484, 262489, 262494, 262500, 262505, 262511, 262517, 
+    262524, 262529, 262535, 262541, 262548, 262554, 262561, 262568, 
+    262576, 262580, 262585, 262590, 262596, 262601, 262607, 262613, 
+    262620, 262625, 262631, 262637, 262644, 262650, 262657, 262664, 
+    262672, 262677, 262683, 262689, 262696, 262702, 262709, 262716, 
+    262724, 262730, 262737, 262744, 262752, 262759, 262767, 262775, 
+    262784, 262788, 262793, 262798, 262804, 262809, 262815, 262821, 
+    262828, 262833, 262839, 262845, 262852, 262858, 262865, 262872, 
+    262880, 262885, 262891, 262897, 262904, 262910, 262917, 262924, 
+    262932, 262938, 262945, 262952, 262960, 262967, 262975, 262983, 
+    262992, 262997, 263003, 263009, 263016, 263022, 263029, 263036, 
+    263044, 263050, 263057, 263064, 263072, 263079, 263087, 263095, 
+    263104, 263110, 263117, 263124, 263132, 263139, 263147, 263155, 
+    263164, 263171, 263179, 263187, 263196, 263204, 263213, 263222, 
+    263232, 263236, 263241, 263246, 263252, 263257, 263263, 263269, 
+    263276, 263281, 263287, 263293, 263300, 263306, 263313, 263320, 
+    263328, 263333, 263339, 263345, 263352, 263358, 263365, 263372, 
+    263380, 263386, 263393, 263400, 263408, 263415, 263423, 263431, 
+    263440, 263445, 263451, 263457, 263464, 263470, 263477, 263484, 
+    263492, 263498, 263505, 263512, 263520, 263527, 263535, 263543, 
+    263552, 263558, 263565, 263572, 263580, 263587, 263595, 263603, 
+    263612, 263619, 263627, 263635, 263644, 263652, 263661, 263670, 
+    263680, 263685, 263691, 263697, 263704, 263710, 263717, 263724, 
+    263732, 263738, 263745, 263752, 263760, 263767, 263775, 263783, 
+    263792, 263798, 263805, 263812, 263820, 263827, 263835, 263843, 
+    263852, 263859, 263867, 263875, 263884, 263892, 263901, 263910, 
+    263920, 263926, 263933, 263940, 263948, 263955, 263963, 263971, 
+    263980, 263987, 263995, 264003, 264012, 264020, 264029, 264038, 
+    264048, 264055, 264063, 264071, 264080, 264088, 264097, 264106, 
+    264116, 264124, 264133, 264142, 264152, 264161, 264171, 264181, 
+    264192, 264196, 264201, 264206, 264212, 264217, 264223, 264229, 
+    264236, 264241, 264247, 264253, 264260, 264266, 264273, 264280, 
+    264288, 264293, 264299, 264305, 264312, 264318, 264325, 264332, 
+    264340, 264346, 264353, 264360, 264368, 264375, 264383, 264391, 
+    264400, 264405, 264411, 264417, 264424, 264430, 264437, 264444, 
+    264452, 264458, 264465, 264472, 264480, 264487, 264495, 264503, 
+    264512, 264518, 264525, 264532, 264540, 264547, 264555, 264563, 
+    264572, 264579, 264587, 264595, 264604, 264612, 264621, 264630, 
+    264640, 264645, 264651, 264657, 264664, 264670, 264677, 264684, 
+    264692, 264698, 264705, 264712, 264720, 264727, 264735, 264743, 
+    264752, 264758, 264765, 264772, 264780, 264787, 264795, 264803, 
+    264812, 264819, 264827, 264835, 264844, 264852, 264861, 264870, 
+    264880, 264886, 264893, 264900, 264908, 264915, 264923, 264931, 
+    264940, 264947, 264955, 264963, 264972, 264980, 264989, 264998, 
+    265008, 265015, 265023, 265031, 265040, 265048, 265057, 265066, 
+    265076, 265084, 265093, 265102, 265112, 265121, 265131, 265141, 
+    265152, 265157, 265163, 265169, 265176, 265182, 265189, 265196, 
+    265204, 265210, 265217, 265224, 265232, 265239, 265247, 265255, 
+    265264, 265270, 265277, 265284, 265292, 265299, 265307, 265315, 
+    265324, 265331, 265339, 265347, 265356, 265364, 265373, 265382, 
+    265392, 265398, 265405, 265412, 265420, 265427, 265435, 265443, 
+    265452, 265459, 265467, 265475, 265484, 265492, 265501, 265510, 
+    265520, 265527, 265535, 265543, 265552, 265560, 265569, 265578, 
+    265588, 265596, 265605, 265614, 265624, 265633, 265643, 265653, 
+    265664, 265670, 265677, 265684, 265692, 265699, 265707, 265715, 
+    265724, 265731, 265739, 265747, 265756, 265764, 265773, 265782, 
+    265792, 265799, 265807, 265815, 265824, 265832, 265841, 265850, 
+    265860, 265868, 265877, 265886, 265896, 265905, 265915, 265925, 
+    265936, 265943, 265951, 265959, 265968, 265976, 265985, 265994, 
+    266004, 266012, 266021, 266030, 266040, 266049, 266059, 266069, 
+    266080, 266088, 266097, 266106, 266116, 266125, 266135, 266145, 
+    266156, 266165, 266175, 266185, 266196, 266206, 266217, 266228, 
+    266240, 266243, 266247, 266251, 266256, 266260, 266265, 266270, 
+    266276, 266280, 266285, 266290, 266296, 266301, 266307, 266313, 
+    266320, 266324, 266329, 266334, 266340, 266345, 266351, 266357, 
+    266364, 266369, 266375, 266381, 266388, 266394, 266401, 266408, 
+    266416, 266420, 266425, 266430, 266436, 266441, 266447, 266453, 
+    266460, 266465, 266471, 266477, 266484, 266490, 266497, 266504, 
+    266512, 266517, 266523, 266529, 266536, 266542, 266549, 266556, 
+    266564, 266570, 266577, 266584, 266592, 266599, 266607, 266615, 
+    266624, 266628, 266633, 266638, 266644, 266649, 266655, 266661, 
+    266668, 266673, 266679, 266685, 266692, 266698, 266705, 266712, 
+    266720, 266725, 266731, 266737, 266744, 266750, 266757, 266764, 
+    266772, 266778, 266785, 266792, 266800, 266807, 266815, 266823, 
+    266832, 266837, 266843, 266849, 266856, 266862, 266869, 266876, 
+    266884, 266890, 266897, 266904, 266912, 266919, 266927, 266935, 
+    266944, 266950, 266957, 266964, 266972, 266979, 266987, 266995, 
+    267004, 267011, 267019, 267027, 267036, 267044, 267053, 267062, 
+    267072, 267076, 267081, 267086, 267092, 267097, 267103, 267109, 
+    267116, 267121, 267127, 267133, 267140, 267146, 267153, 267160, 
+    267168, 267173, 267179, 267185, 267192, 267198, 267205, 267212, 
+    267220, 267226, 267233, 267240, 267248, 267255, 267263, 267271, 
+    267280, 267285, 267291, 267297, 267304, 267310, 267317, 267324, 
+    267332, 267338, 267345, 267352, 267360, 267367, 267375, 267383, 
+    267392, 267398, 267405, 267412, 267420, 267427, 267435, 267443, 
+    267452, 267459, 267467, 267475, 267484, 267492, 267501, 267510, 
+    267520, 267525, 267531, 267537, 267544, 267550, 267557, 267564, 
+    267572, 267578, 267585, 267592, 267600, 267607, 267615, 267623, 
+    267632, 267638, 267645, 267652, 267660, 267667, 267675, 267683, 
+    267692, 267699, 267707, 267715, 267724, 267732, 267741, 267750, 
+    267760, 267766, 267773, 267780, 267788, 267795, 267803, 267811, 
+    267820, 267827, 267835, 267843, 267852, 267860, 267869, 267878, 
+    267888, 267895, 267903, 267911, 267920, 267928, 267937, 267946, 
+    267956, 267964, 267973, 267982, 267992, 268001, 268011, 268021, 
+    268032, 268036, 268041, 268046, 268052, 268057, 268063, 268069, 
+    268076, 268081, 268087, 268093, 268100, 268106, 268113, 268120, 
+    268128, 268133, 268139, 268145, 268152, 268158, 268165, 268172, 
+    268180, 268186, 268193, 268200, 268208, 268215, 268223, 268231, 
+    268240, 268245, 268251, 268257, 268264, 268270, 268277, 268284, 
+    268292, 268298, 268305, 268312, 268320, 268327, 268335, 268343, 
+    268352, 268358, 268365, 268372, 268380, 268387, 268395, 268403, 
+    268412, 268419, 268427, 268435, 268444, 268452, 268461, 268470, 
+    268480, 268485, 268491, 268497, 268504, 268510, 268517, 268524, 
+    268532, 268538, 268545, 268552, 268560, 268567, 268575, 268583, 
+    268592, 268598, 268605, 268612, 268620, 268627, 268635, 268643, 
+    268652, 268659, 268667, 268675, 268684, 268692, 268701, 268710, 
+    268720, 268726, 268733, 268740, 268748, 268755, 268763, 268771, 
+    268780, 268787, 268795, 268803, 268812, 268820, 268829, 268838, 
+    268848, 268855, 268863, 268871, 268880, 268888, 268897, 268906, 
+    268916, 268924, 268933, 268942, 268952, 268961, 268971, 268981, 
+    268992, 268997, 269003, 269009, 269016, 269022, 269029, 269036, 
+    269044, 269050, 269057, 269064, 269072, 269079, 269087, 269095, 
+    269104, 269110, 269117, 269124, 269132, 269139, 269147, 269155, 
+    269164, 269171, 269179, 269187, 269196, 269204, 269213, 269222, 
+    269232, 269238, 269245, 269252, 269260, 269267, 269275, 269283, 
+    269292, 269299, 269307, 269315, 269324, 269332, 269341, 269350, 
+    269360, 269367, 269375, 269383, 269392, 269400, 269409, 269418, 
+    269428, 269436, 269445, 269454, 269464, 269473, 269483, 269493, 
+    269504, 269510, 269517, 269524, 269532, 269539, 269547, 269555, 
+    269564, 269571, 269579, 269587, 269596, 269604, 269613, 269622, 
+    269632, 269639, 269647, 269655, 269664, 269672, 269681, 269690, 
+    269700, 269708, 269717, 269726, 269736, 269745, 269755, 269765, 
+    269776, 269783, 269791, 269799, 269808, 269816, 269825, 269834, 
+    269844, 269852, 269861, 269870, 269880, 269889, 269899, 269909, 
+    269920, 269928, 269937, 269946, 269956, 269965, 269975, 269985, 
+    269996, 270005, 270015, 270025, 270036, 270046, 270057, 270068, 
+    270080, 270084, 270089, 270094, 270100, 270105, 270111, 270117, 
+    270124, 270129, 270135, 270141, 270148, 270154, 270161, 270168, 
+    270176, 270181, 270187, 270193, 270200, 270206, 270213, 270220, 
+    270228, 270234, 270241, 270248, 270256, 270263, 270271, 270279, 
+    270288, 270293, 270299, 270305, 270312, 270318, 270325, 270332, 
+    270340, 270346, 270353, 270360, 270368, 270375, 270383, 270391, 
+    270400, 270406, 270413, 270420, 270428, 270435, 270443, 270451, 
+    270460, 270467, 270475, 270483, 270492, 270500, 270509, 270518, 
+    270528, 270533, 270539, 270545, 270552, 270558, 270565, 270572, 
+    270580, 270586, 270593, 270600, 270608, 270615, 270623, 270631, 
+    270640, 270646, 270653, 270660, 270668, 270675, 270683, 270691, 
+    270700, 270707, 270715, 270723, 270732, 270740, 270749, 270758, 
+    270768, 270774, 270781, 270788, 270796, 270803, 270811, 270819, 
+    270828, 270835, 270843, 270851, 270860, 270868, 270877, 270886, 
+    270896, 270903, 270911, 270919, 270928, 270936, 270945, 270954, 
+    270964, 270972, 270981, 270990, 271000, 271009, 271019, 271029, 
+    271040, 271045, 271051, 271057, 271064, 271070, 271077, 271084, 
+    271092, 271098, 271105, 271112, 271120, 271127, 271135, 271143, 
+    271152, 271158, 271165, 271172, 271180, 271187, 271195, 271203, 
+    271212, 271219, 271227, 271235, 271244, 271252, 271261, 271270, 
+    271280, 271286, 271293, 271300, 271308, 271315, 271323, 271331, 
+    271340, 271347, 271355, 271363, 271372, 271380, 271389, 271398, 
+    271408, 271415, 271423, 271431, 271440, 271448, 271457, 271466, 
+    271476, 271484, 271493, 271502, 271512, 271521, 271531, 271541, 
+    271552, 271558, 271565, 271572, 271580, 271587, 271595, 271603, 
+    271612, 271619, 271627, 271635, 271644, 271652, 271661, 271670, 
+    271680, 271687, 271695, 271703, 271712, 271720, 271729, 271738, 
+    271748, 271756, 271765, 271774, 271784, 271793, 271803, 271813, 
+    271824, 271831, 271839, 271847, 271856, 271864, 271873, 271882, 
+    271892, 271900, 271909, 271918, 271928, 271937, 271947, 271957, 
+    271968, 271976, 271985, 271994, 272004, 272013, 272023, 272033, 
+    272044, 272053, 272063, 272073, 272084, 272094, 272105, 272116, 
+    272128, 272133, 272139, 272145, 272152, 272158, 272165, 272172, 
+    272180, 272186, 272193, 272200, 272208, 272215, 272223, 272231, 
+    272240, 272246, 272253, 272260, 272268, 272275, 272283, 272291, 
+    272300, 272307, 272315, 272323, 272332, 272340, 272349, 272358, 
+    272368, 272374, 272381, 272388, 272396, 272403, 272411, 272419, 
+    272428, 272435, 272443, 272451, 272460, 272468, 272477, 272486, 
+    272496, 272503, 272511, 272519, 272528, 272536, 272545, 272554, 
+    272564, 272572, 272581, 272590, 272600, 272609, 272619, 272629, 
+    272640, 272646, 272653, 272660, 272668, 272675, 272683, 272691, 
+    272700, 272707, 272715, 272723, 272732, 272740, 272749, 272758, 
+    272768, 272775, 272783, 272791, 272800, 272808, 272817, 272826, 
+    272836, 272844, 272853, 272862, 272872, 272881, 272891, 272901, 
+    272912, 272919, 272927, 272935, 272944, 272952, 272961, 272970, 
+    272980, 272988, 272997, 273006, 273016, 273025, 273035, 273045, 
+    273056, 273064, 273073, 273082, 273092, 273101, 273111, 273121, 
+    273132, 273141, 273151, 273161, 273172, 273182, 273193, 273204, 
+    273216, 273222, 273229, 273236, 273244, 273251, 273259, 273267, 
+    273276, 273283, 273291, 273299, 273308, 273316, 273325, 273334, 
+    273344, 273351, 273359, 273367, 273376, 273384, 273393, 273402, 
+    273412, 273420, 273429, 273438, 273448, 273457, 273467, 273477, 
+    273488, 273495, 273503, 273511, 273520, 273528, 273537, 273546, 
+    273556, 273564, 273573, 273582, 273592, 273601, 273611, 273621, 
+    273632, 273640, 273649, 273658, 273668, 273677, 273687, 273697, 
+    273708, 273717, 273727, 273737, 273748, 273758, 273769, 273780, 
+    273792, 273799, 273807, 273815, 273824, 273832, 273841, 273850, 
+    273860, 273868, 273877, 273886, 273896, 273905, 273915, 273925, 
+    273936, 273944, 273953, 273962, 273972, 273981, 273991, 274001, 
+    274012, 274021, 274031, 274041, 274052, 274062, 274073, 274084, 
+    274096, 274104, 274113, 274122, 274132, 274141, 274151, 274161, 
+    274172, 274181, 274191, 274201, 274212, 274222, 274233, 274244, 
+    274256, 274265, 274275, 274285, 274296, 274306, 274317, 274328, 
+    274340, 274350, 274361, 274372, 274384, 274395, 274407, 274419, 
+    274432, 274434, 274437, 274440, 274444, 274447, 274451, 274455, 
+    274460, 274463, 274467, 274471, 274476, 274480, 274485, 274490, 
+    274496, 274499, 274503, 274507, 274512, 274516, 274521, 274526, 
+    274532, 274536, 274541, 274546, 274552, 274557, 274563, 274569, 
+    274576, 274579, 274583, 274587, 274592, 274596, 274601, 274606, 
+    274612, 274616, 274621, 274626, 274632, 274637, 274643, 274649, 
+    274656, 274660, 274665, 274670, 274676, 274681, 274687, 274693, 
+    274700, 274705, 274711, 274717, 274724, 274730, 274737, 274744, 
+    274752, 274755, 274759, 274763, 274768, 274772, 274777, 274782, 
+    274788, 274792, 274797, 274802, 274808, 274813, 274819, 274825, 
+    274832, 274836, 274841, 274846, 274852, 274857, 274863, 274869, 
+    274876, 274881, 274887, 274893, 274900, 274906, 274913, 274920, 
+    274928, 274932, 274937, 274942, 274948, 274953, 274959, 274965, 
+    274972, 274977, 274983, 274989, 274996, 275002, 275009, 275016, 
+    275024, 275029, 275035, 275041, 275048, 275054, 275061, 275068, 
+    275076, 275082, 275089, 275096, 275104, 275111, 275119, 275127, 
+    275136, 275139, 275143, 275147, 275152, 275156, 275161, 275166, 
+    275172, 275176, 275181, 275186, 275192, 275197, 275203, 275209, 
+    275216, 275220, 275225, 275230, 275236, 275241, 275247, 275253, 
+    275260, 275265, 275271, 275277, 275284, 275290, 275297, 275304, 
+    275312, 275316, 275321, 275326, 275332, 275337, 275343, 275349, 
+    275356, 275361, 275367, 275373, 275380, 275386, 275393, 275400, 
+    275408, 275413, 275419, 275425, 275432, 275438, 275445, 275452, 
+    275460, 275466, 275473, 275480, 275488, 275495, 275503, 275511, 
+    275520, 275524, 275529, 275534, 275540, 275545, 275551, 275557, 
+    275564, 275569, 275575, 275581, 275588, 275594, 275601, 275608, 
+    275616, 275621, 275627, 275633, 275640, 275646, 275653, 275660, 
+    275668, 275674, 275681, 275688, 275696, 275703, 275711, 275719, 
+    275728, 275733, 275739, 275745, 275752, 275758, 275765, 275772, 
+    275780, 275786, 275793, 275800, 275808, 275815, 275823, 275831, 
+    275840, 275846, 275853, 275860, 275868, 275875, 275883, 275891, 
+    275900, 275907, 275915, 275923, 275932, 275940, 275949, 275958, 
+    275968, 275971, 275975, 275979, 275984, 275988, 275993, 275998, 
+    276004, 276008, 276013, 276018, 276024, 276029, 276035, 276041, 
+    276048, 276052, 276057, 276062, 276068, 276073, 276079, 276085, 
+    276092, 276097, 276103, 276109, 276116, 276122, 276129, 276136, 
+    276144, 276148, 276153, 276158, 276164, 276169, 276175, 276181, 
+    276188, 276193, 276199, 276205, 276212, 276218, 276225, 276232, 
+    276240, 276245, 276251, 276257, 276264, 276270, 276277, 276284, 
+    276292, 276298, 276305, 276312, 276320, 276327, 276335, 276343, 
+    276352, 276356, 276361, 276366, 276372, 276377, 276383, 276389, 
+    276396, 276401, 276407, 276413, 276420, 276426, 276433, 276440, 
+    276448, 276453, 276459, 276465, 276472, 276478, 276485, 276492, 
+    276500, 276506, 276513, 276520, 276528, 276535, 276543, 276551, 
+    276560, 276565, 276571, 276577, 276584, 276590, 276597, 276604, 
+    276612, 276618, 276625, 276632, 276640, 276647, 276655, 276663, 
+    276672, 276678, 276685, 276692, 276700, 276707, 276715, 276723, 
+    276732, 276739, 276747, 276755, 276764, 276772, 276781, 276790, 
+    276800, 276804, 276809, 276814, 276820, 276825, 276831, 276837, 
+    276844, 276849, 276855, 276861, 276868, 276874, 276881, 276888, 
+    276896, 276901, 276907, 276913, 276920, 276926, 276933, 276940, 
+    276948, 276954, 276961, 276968, 276976, 276983, 276991, 276999, 
+    277008, 277013, 277019, 277025, 277032, 277038, 277045, 277052, 
+    277060, 277066, 277073, 277080, 277088, 277095, 277103, 277111, 
+    277120, 277126, 277133, 277140, 277148, 277155, 277163, 277171, 
+    277180, 277187, 277195, 277203, 277212, 277220, 277229, 277238, 
+    277248, 277253, 277259, 277265, 277272, 277278, 277285, 277292, 
+    277300, 277306, 277313, 277320, 277328, 277335, 277343, 277351, 
+    277360, 277366, 277373, 277380, 277388, 277395, 277403, 277411, 
+    277420, 277427, 277435, 277443, 277452, 277460, 277469, 277478, 
+    277488, 277494, 277501, 277508, 277516, 277523, 277531, 277539, 
+    277548, 277555, 277563, 277571, 277580, 277588, 277597, 277606, 
+    277616, 277623, 277631, 277639, 277648, 277656, 277665, 277674, 
+    277684, 277692, 277701, 277710, 277720, 277729, 277739, 277749, 
+    277760, 277763, 277767, 277771, 277776, 277780, 277785, 277790, 
+    277796, 277800, 277805, 277810, 277816, 277821, 277827, 277833, 
+    277840, 277844, 277849, 277854, 277860, 277865, 277871, 277877, 
+    277884, 277889, 277895, 277901, 277908, 277914, 277921, 277928, 
+    277936, 277940, 277945, 277950, 277956, 277961, 277967, 277973, 
+    277980, 277985, 277991, 277997, 278004, 278010, 278017, 278024, 
+    278032, 278037, 278043, 278049, 278056, 278062, 278069, 278076, 
+    278084, 278090, 278097, 278104, 278112, 278119, 278127, 278135, 
+    278144, 278148, 278153, 278158, 278164, 278169, 278175, 278181, 
+    278188, 278193, 278199, 278205, 278212, 278218, 278225, 278232, 
+    278240, 278245, 278251, 278257, 278264, 278270, 278277, 278284, 
+    278292, 278298, 278305, 278312, 278320, 278327, 278335, 278343, 
+    278352, 278357, 278363, 278369, 278376, 278382, 278389, 278396, 
+    278404, 278410, 278417, 278424, 278432, 278439, 278447, 278455, 
+    278464, 278470, 278477, 278484, 278492, 278499, 278507, 278515, 
+    278524, 278531, 278539, 278547, 278556, 278564, 278573, 278582, 
+    278592, 278596, 278601, 278606, 278612, 278617, 278623, 278629, 
+    278636, 278641, 278647, 278653, 278660, 278666, 278673, 278680, 
+    278688, 278693, 278699, 278705, 278712, 278718, 278725, 278732, 
+    278740, 278746, 278753, 278760, 278768, 278775, 278783, 278791, 
+    278800, 278805, 278811, 278817, 278824, 278830, 278837, 278844, 
+    278852, 278858, 278865, 278872, 278880, 278887, 278895, 278903, 
+    278912, 278918, 278925, 278932, 278940, 278947, 278955, 278963, 
+    278972, 278979, 278987, 278995, 279004, 279012, 279021, 279030, 
+    279040, 279045, 279051, 279057, 279064, 279070, 279077, 279084, 
+    279092, 279098, 279105, 279112, 279120, 279127, 279135, 279143, 
+    279152, 279158, 279165, 279172, 279180, 279187, 279195, 279203, 
+    279212, 279219, 279227, 279235, 279244, 279252, 279261, 279270, 
+    279280, 279286, 279293, 279300, 279308, 279315, 279323, 279331, 
+    279340, 279347, 279355, 279363, 279372, 279380, 279389, 279398, 
+    279408, 279415, 279423, 279431, 279440, 279448, 279457, 279466, 
+    279476, 279484, 279493, 279502, 279512, 279521, 279531, 279541, 
+    279552, 279556, 279561, 279566, 279572, 279577, 279583, 279589, 
+    279596, 279601, 279607, 279613, 279620, 279626, 279633, 279640, 
+    279648, 279653, 279659, 279665, 279672, 279678, 279685, 279692, 
+    279700, 279706, 279713, 279720, 279728, 279735, 279743, 279751, 
+    279760, 279765, 279771, 279777, 279784, 279790, 279797, 279804, 
+    279812, 279818, 279825, 279832, 279840, 279847, 279855, 279863, 
+    279872, 279878, 279885, 279892, 279900, 279907, 279915, 279923, 
+    279932, 279939, 279947, 279955, 279964, 279972, 279981, 279990, 
+    280000, 280005, 280011, 280017, 280024, 280030, 280037, 280044, 
+    280052, 280058, 280065, 280072, 280080, 280087, 280095, 280103, 
+    280112, 280118, 280125, 280132, 280140, 280147, 280155, 280163, 
+    280172, 280179, 280187, 280195, 280204, 280212, 280221, 280230, 
+    280240, 280246, 280253, 280260, 280268, 280275, 280283, 280291, 
+    280300, 280307, 280315, 280323, 280332, 280340, 280349, 280358, 
+    280368, 280375, 280383, 280391, 280400, 280408, 280417, 280426, 
+    280436, 280444, 280453, 280462, 280472, 280481, 280491, 280501, 
+    280512, 280517, 280523, 280529, 280536, 280542, 280549, 280556, 
+    280564, 280570, 280577, 280584, 280592, 280599, 280607, 280615, 
+    280624, 280630, 280637, 280644, 280652, 280659, 280667, 280675, 
+    280684, 280691, 280699, 280707, 280716, 280724, 280733, 280742, 
+    280752, 280758, 280765, 280772, 280780, 280787, 280795, 280803, 
+    280812, 280819, 280827, 280835, 280844, 280852, 280861, 280870, 
+    280880, 280887, 280895, 280903, 280912, 280920, 280929, 280938, 
+    280948, 280956, 280965, 280974, 280984, 280993, 281003, 281013, 
+    281024, 281030, 281037, 281044, 281052, 281059, 281067, 281075, 
+    281084, 281091, 281099, 281107, 281116, 281124, 281133, 281142, 
+    281152, 281159, 281167, 281175, 281184, 281192, 281201, 281210, 
+    281220, 281228, 281237, 281246, 281256, 281265, 281275, 281285, 
+    281296, 281303, 281311, 281319, 281328, 281336, 281345, 281354, 
+    281364, 281372, 281381, 281390, 281400, 281409, 281419, 281429, 
+    281440, 281448, 281457, 281466, 281476, 281485, 281495, 281505, 
+    281516, 281525, 281535, 281545, 281556, 281566, 281577, 281588, 
+    281600, 281603, 281607, 281611, 281616, 281620, 281625, 281630, 
+    281636, 281640, 281645, 281650, 281656, 281661, 281667, 281673, 
+    281680, 281684, 281689, 281694, 281700, 281705, 281711, 281717, 
+    281724, 281729, 281735, 281741, 281748, 281754, 281761, 281768, 
+    281776, 281780, 281785, 281790, 281796, 281801, 281807, 281813, 
+    281820, 281825, 281831, 281837, 281844, 281850, 281857, 281864, 
+    281872, 281877, 281883, 281889, 281896, 281902, 281909, 281916, 
+    281924, 281930, 281937, 281944, 281952, 281959, 281967, 281975, 
+    281984, 281988, 281993, 281998, 282004, 282009, 282015, 282021, 
+    282028, 282033, 282039, 282045, 282052, 282058, 282065, 282072, 
+    282080, 282085, 282091, 282097, 282104, 282110, 282117, 282124, 
+    282132, 282138, 282145, 282152, 282160, 282167, 282175, 282183, 
+    282192, 282197, 282203, 282209, 282216, 282222, 282229, 282236, 
+    282244, 282250, 282257, 282264, 282272, 282279, 282287, 282295, 
+    282304, 282310, 282317, 282324, 282332, 282339, 282347, 282355, 
+    282364, 282371, 282379, 282387, 282396, 282404, 282413, 282422, 
+    282432, 282436, 282441, 282446, 282452, 282457, 282463, 282469, 
+    282476, 282481, 282487, 282493, 282500, 282506, 282513, 282520, 
+    282528, 282533, 282539, 282545, 282552, 282558, 282565, 282572, 
+    282580, 282586, 282593, 282600, 282608, 282615, 282623, 282631, 
+    282640, 282645, 282651, 282657, 282664, 282670, 282677, 282684, 
+    282692, 282698, 282705, 282712, 282720, 282727, 282735, 282743, 
+    282752, 282758, 282765, 282772, 282780, 282787, 282795, 282803, 
+    282812, 282819, 282827, 282835, 282844, 282852, 282861, 282870, 
+    282880, 282885, 282891, 282897, 282904, 282910, 282917, 282924, 
+    282932, 282938, 282945, 282952, 282960, 282967, 282975, 282983, 
+    282992, 282998, 283005, 283012, 283020, 283027, 283035, 283043, 
+    283052, 283059, 283067, 283075, 283084, 283092, 283101, 283110, 
+    283120, 283126, 283133, 283140, 283148, 283155, 283163, 283171, 
+    283180, 283187, 283195, 283203, 283212, 283220, 283229, 283238, 
+    283248, 283255, 283263, 283271, 283280, 283288, 283297, 283306, 
+    283316, 283324, 283333, 283342, 283352, 283361, 283371, 283381, 
+    283392, 283396, 283401, 283406, 283412, 283417, 283423, 283429, 
+    283436, 283441, 283447, 283453, 283460, 283466, 283473, 283480, 
+    283488, 283493, 283499, 283505, 283512, 283518, 283525, 283532, 
+    283540, 283546, 283553, 283560, 283568, 283575, 283583, 283591, 
+    283600, 283605, 283611, 283617, 283624, 283630, 283637, 283644, 
+    283652, 283658, 283665, 283672, 283680, 283687, 283695, 283703, 
+    283712, 283718, 283725, 283732, 283740, 283747, 283755, 283763, 
+    283772, 283779, 283787, 283795, 283804, 283812, 283821, 283830, 
+    283840, 283845, 283851, 283857, 283864, 283870, 283877, 283884, 
+    283892, 283898, 283905, 283912, 283920, 283927, 283935, 283943, 
+    283952, 283958, 283965, 283972, 283980, 283987, 283995, 284003, 
+    284012, 284019, 284027, 284035, 284044, 284052, 284061, 284070, 
+    284080, 284086, 284093, 284100, 284108, 284115, 284123, 284131, 
+    284140, 284147, 284155, 284163, 284172, 284180, 284189, 284198, 
+    284208, 284215, 284223, 284231, 284240, 284248, 284257, 284266, 
+    284276, 284284, 284293, 284302, 284312, 284321, 284331, 284341, 
+    284352, 284357, 284363, 284369, 284376, 284382, 284389, 284396, 
+    284404, 284410, 284417, 284424, 284432, 284439, 284447, 284455, 
+    284464, 284470, 284477, 284484, 284492, 284499, 284507, 284515, 
+    284524, 284531, 284539, 284547, 284556, 284564, 284573, 284582, 
+    284592, 284598, 284605, 284612, 284620, 284627, 284635, 284643, 
+    284652, 284659, 284667, 284675, 284684, 284692, 284701, 284710, 
+    284720, 284727, 284735, 284743, 284752, 284760, 284769, 284778, 
+    284788, 284796, 284805, 284814, 284824, 284833, 284843, 284853, 
+    284864, 284870, 284877, 284884, 284892, 284899, 284907, 284915, 
+    284924, 284931, 284939, 284947, 284956, 284964, 284973, 284982, 
+    284992, 284999, 285007, 285015, 285024, 285032, 285041, 285050, 
+    285060, 285068, 285077, 285086, 285096, 285105, 285115, 285125, 
+    285136, 285143, 285151, 285159, 285168, 285176, 285185, 285194, 
+    285204, 285212, 285221, 285230, 285240, 285249, 285259, 285269, 
+    285280, 285288, 285297, 285306, 285316, 285325, 285335, 285345, 
+    285356, 285365, 285375, 285385, 285396, 285406, 285417, 285428, 
+    285440, 285444, 285449, 285454, 285460, 285465, 285471, 285477, 
+    285484, 285489, 285495, 285501, 285508, 285514, 285521, 285528, 
+    285536, 285541, 285547, 285553, 285560, 285566, 285573, 285580, 
+    285588, 285594, 285601, 285608, 285616, 285623, 285631, 285639, 
+    285648, 285653, 285659, 285665, 285672, 285678, 285685, 285692, 
+    285700, 285706, 285713, 285720, 285728, 285735, 285743, 285751, 
+    285760, 285766, 285773, 285780, 285788, 285795, 285803, 285811, 
+    285820, 285827, 285835, 285843, 285852, 285860, 285869, 285878, 
+    285888, 285893, 285899, 285905, 285912, 285918, 285925, 285932, 
+    285940, 285946, 285953, 285960, 285968, 285975, 285983, 285991, 
+    286000, 286006, 286013, 286020, 286028, 286035, 286043, 286051, 
+    286060, 286067, 286075, 286083, 286092, 286100, 286109, 286118, 
+    286128, 286134, 286141, 286148, 286156, 286163, 286171, 286179, 
+    286188, 286195, 286203, 286211, 286220, 286228, 286237, 286246, 
+    286256, 286263, 286271, 286279, 286288, 286296, 286305, 286314, 
+    286324, 286332, 286341, 286350, 286360, 286369, 286379, 286389, 
+    286400, 286405, 286411, 286417, 286424, 286430, 286437, 286444, 
+    286452, 286458, 286465, 286472, 286480, 286487, 286495, 286503, 
+    286512, 286518, 286525, 286532, 286540, 286547, 286555, 286563, 
+    286572, 286579, 286587, 286595, 286604, 286612, 286621, 286630, 
+    286640, 286646, 286653, 286660, 286668, 286675, 286683, 286691, 
+    286700, 286707, 286715, 286723, 286732, 286740, 286749, 286758, 
+    286768, 286775, 286783, 286791, 286800, 286808, 286817, 286826, 
+    286836, 286844, 286853, 286862, 286872, 286881, 286891, 286901, 
+    286912, 286918, 286925, 286932, 286940, 286947, 286955, 286963, 
+    286972, 286979, 286987, 286995, 287004, 287012, 287021, 287030, 
+    287040, 287047, 287055, 287063, 287072, 287080, 287089, 287098, 
+    287108, 287116, 287125, 287134, 287144, 287153, 287163, 287173, 
+    287184, 287191, 287199, 287207, 287216, 287224, 287233, 287242, 
+    287252, 287260, 287269, 287278, 287288, 287297, 287307, 287317, 
+    287328, 287336, 287345, 287354, 287364, 287373, 287383, 287393, 
+    287404, 287413, 287423, 287433, 287444, 287454, 287465, 287476, 
+    287488, 287493, 287499, 287505, 287512, 287518, 287525, 287532, 
+    287540, 287546, 287553, 287560, 287568, 287575, 287583, 287591, 
+    287600, 287606, 287613, 287620, 287628, 287635, 287643, 287651, 
+    287660, 287667, 287675, 287683, 287692, 287700, 287709, 287718, 
+    287728, 287734, 287741, 287748, 287756, 287763, 287771, 287779, 
+    287788, 287795, 287803, 287811, 287820, 287828, 287837, 287846, 
+    287856, 287863, 287871, 287879, 287888, 287896, 287905, 287914, 
+    287924, 287932, 287941, 287950, 287960, 287969, 287979, 287989, 
+    288000, 288006, 288013, 288020, 288028, 288035, 288043, 288051, 
+    288060, 288067, 288075, 288083, 288092, 288100, 288109, 288118, 
+    288128, 288135, 288143, 288151, 288160, 288168, 288177, 288186, 
+    288196, 288204, 288213, 288222, 288232, 288241, 288251, 288261, 
+    288272, 288279, 288287, 288295, 288304, 288312, 288321, 288330, 
+    288340, 288348, 288357, 288366, 288376, 288385, 288395, 288405, 
+    288416, 288424, 288433, 288442, 288452, 288461, 288471, 288481, 
+    288492, 288501, 288511, 288521, 288532, 288542, 288553, 288564, 
+    288576, 288582, 288589, 288596, 288604, 288611, 288619, 288627, 
+    288636, 288643, 288651, 288659, 288668, 288676, 288685, 288694, 
+    288704, 288711, 288719, 288727, 288736, 288744, 288753, 288762, 
+    288772, 288780, 288789, 288798, 288808, 288817, 288827, 288837, 
+    288848, 288855, 288863, 288871, 288880, 288888, 288897, 288906, 
+    288916, 288924, 288933, 288942, 288952, 288961, 288971, 288981, 
+    288992, 289000, 289009, 289018, 289028, 289037, 289047, 289057, 
+    289068, 289077, 289087, 289097, 289108, 289118, 289129, 289140, 
+    289152, 289159, 289167, 289175, 289184, 289192, 289201, 289210, 
+    289220, 289228, 289237, 289246, 289256, 289265, 289275, 289285, 
+    289296, 289304, 289313, 289322, 289332, 289341, 289351, 289361, 
+    289372, 289381, 289391, 289401, 289412, 289422, 289433, 289444, 
+    289456, 289464, 289473, 289482, 289492, 289501, 289511, 289521, 
+    289532, 289541, 289551, 289561, 289572, 289582, 289593, 289604, 
+    289616, 289625, 289635, 289645, 289656, 289666, 289677, 289688, 
+    289700, 289710, 289721, 289732, 289744, 289755, 289767, 289779, 
+    289792, 289795, 289799, 289803, 289808, 289812, 289817, 289822, 
+    289828, 289832, 289837, 289842, 289848, 289853, 289859, 289865, 
+    289872, 289876, 289881, 289886, 289892, 289897, 289903, 289909, 
+    289916, 289921, 289927, 289933, 289940, 289946, 289953, 289960, 
+    289968, 289972, 289977, 289982, 289988, 289993, 289999, 290005, 
+    290012, 290017, 290023, 290029, 290036, 290042, 290049, 290056, 
+    290064, 290069, 290075, 290081, 290088, 290094, 290101, 290108, 
+    290116, 290122, 290129, 290136, 290144, 290151, 290159, 290167, 
+    290176, 290180, 290185, 290190, 290196, 290201, 290207, 290213, 
+    290220, 290225, 290231, 290237, 290244, 290250, 290257, 290264, 
+    290272, 290277, 290283, 290289, 290296, 290302, 290309, 290316, 
+    290324, 290330, 290337, 290344, 290352, 290359, 290367, 290375, 
+    290384, 290389, 290395, 290401, 290408, 290414, 290421, 290428, 
+    290436, 290442, 290449, 290456, 290464, 290471, 290479, 290487, 
+    290496, 290502, 290509, 290516, 290524, 290531, 290539, 290547, 
+    290556, 290563, 290571, 290579, 290588, 290596, 290605, 290614, 
+    290624, 290628, 290633, 290638, 290644, 290649, 290655, 290661, 
+    290668, 290673, 290679, 290685, 290692, 290698, 290705, 290712, 
+    290720, 290725, 290731, 290737, 290744, 290750, 290757, 290764, 
+    290772, 290778, 290785, 290792, 290800, 290807, 290815, 290823, 
+    290832, 290837, 290843, 290849, 290856, 290862, 290869, 290876, 
+    290884, 290890, 290897, 290904, 290912, 290919, 290927, 290935, 
+    290944, 290950, 290957, 290964, 290972, 290979, 290987, 290995, 
+    291004, 291011, 291019, 291027, 291036, 291044, 291053, 291062, 
+    291072, 291077, 291083, 291089, 291096, 291102, 291109, 291116, 
+    291124, 291130, 291137, 291144, 291152, 291159, 291167, 291175, 
+    291184, 291190, 291197, 291204, 291212, 291219, 291227, 291235, 
+    291244, 291251, 291259, 291267, 291276, 291284, 291293, 291302, 
+    291312, 291318, 291325, 291332, 291340, 291347, 291355, 291363, 
+    291372, 291379, 291387, 291395, 291404, 291412, 291421, 291430, 
+    291440, 291447, 291455, 291463, 291472, 291480, 291489, 291498, 
+    291508, 291516, 291525, 291534, 291544, 291553, 291563, 291573, 
+    291584, 291588, 291593, 291598, 291604, 291609, 291615, 291621, 
+    291628, 291633, 291639, 291645, 291652, 291658, 291665, 291672, 
+    291680, 291685, 291691, 291697, 291704, 291710, 291717, 291724, 
+    291732, 291738, 291745, 291752, 291760, 291767, 291775, 291783, 
+    291792, 291797, 291803, 291809, 291816, 291822, 291829, 291836, 
+    291844, 291850, 291857, 291864, 291872, 291879, 291887, 291895, 
+    291904, 291910, 291917, 291924, 291932, 291939, 291947, 291955, 
+    291964, 291971, 291979, 291987, 291996, 292004, 292013, 292022, 
+    292032, 292037, 292043, 292049, 292056, 292062, 292069, 292076, 
+    292084, 292090, 292097, 292104, 292112, 292119, 292127, 292135, 
+    292144, 292150, 292157, 292164, 292172, 292179, 292187, 292195, 
+    292204, 292211, 292219, 292227, 292236, 292244, 292253, 292262, 
+    292272, 292278, 292285, 292292, 292300, 292307, 292315, 292323, 
+    292332, 292339, 292347, 292355, 292364, 292372, 292381, 292390, 
+    292400, 292407, 292415, 292423, 292432, 292440, 292449, 292458, 
+    292468, 292476, 292485, 292494, 292504, 292513, 292523, 292533, 
+    292544, 292549, 292555, 292561, 292568, 292574, 292581, 292588, 
+    292596, 292602, 292609, 292616, 292624, 292631, 292639, 292647, 
+    292656, 292662, 292669, 292676, 292684, 292691, 292699, 292707, 
+    292716, 292723, 292731, 292739, 292748, 292756, 292765, 292774, 
+    292784, 292790, 292797, 292804, 292812, 292819, 292827, 292835, 
+    292844, 292851, 292859, 292867, 292876, 292884, 292893, 292902, 
+    292912, 292919, 292927, 292935, 292944, 292952, 292961, 292970, 
+    292980, 292988, 292997, 293006, 293016, 293025, 293035, 293045, 
+    293056, 293062, 293069, 293076, 293084, 293091, 293099, 293107, 
+    293116, 293123, 293131, 293139, 293148, 293156, 293165, 293174, 
+    293184, 293191, 293199, 293207, 293216, 293224, 293233, 293242, 
+    293252, 293260, 293269, 293278, 293288, 293297, 293307, 293317, 
+    293328, 293335, 293343, 293351, 293360, 293368, 293377, 293386, 
+    293396, 293404, 293413, 293422, 293432, 293441, 293451, 293461, 
+    293472, 293480, 293489, 293498, 293508, 293517, 293527, 293537, 
+    293548, 293557, 293567, 293577, 293588, 293598, 293609, 293620, 
+    293632, 293636, 293641, 293646, 293652, 293657, 293663, 293669, 
+    293676, 293681, 293687, 293693, 293700, 293706, 293713, 293720, 
+    293728, 293733, 293739, 293745, 293752, 293758, 293765, 293772, 
+    293780, 293786, 293793, 293800, 293808, 293815, 293823, 293831, 
+    293840, 293845, 293851, 293857, 293864, 293870, 293877, 293884, 
+    293892, 293898, 293905, 293912, 293920, 293927, 293935, 293943, 
+    293952, 293958, 293965, 293972, 293980, 293987, 293995, 294003, 
+    294012, 294019, 294027, 294035, 294044, 294052, 294061, 294070, 
+    294080, 294085, 294091, 294097, 294104, 294110, 294117, 294124, 
+    294132, 294138, 294145, 294152, 294160, 294167, 294175, 294183, 
+    294192, 294198, 294205, 294212, 294220, 294227, 294235, 294243, 
+    294252, 294259, 294267, 294275, 294284, 294292, 294301, 294310, 
+    294320, 294326, 294333, 294340, 294348, 294355, 294363, 294371, 
+    294380, 294387, 294395, 294403, 294412, 294420, 294429, 294438, 
+    294448, 294455, 294463, 294471, 294480, 294488, 294497, 294506, 
+    294516, 294524, 294533, 294542, 294552, 294561, 294571, 294581, 
+    294592, 294597, 294603, 294609, 294616, 294622, 294629, 294636, 
+    294644, 294650, 294657, 294664, 294672, 294679, 294687, 294695, 
+    294704, 294710, 294717, 294724, 294732, 294739, 294747, 294755, 
+    294764, 294771, 294779, 294787, 294796, 294804, 294813, 294822, 
+    294832, 294838, 294845, 294852, 294860, 294867, 294875, 294883, 
+    294892, 294899, 294907, 294915, 294924, 294932, 294941, 294950, 
+    294960, 294967, 294975, 294983, 294992, 295000, 295009, 295018, 
+    295028, 295036, 295045, 295054, 295064, 295073, 295083, 295093, 
+    295104, 295110, 295117, 295124, 295132, 295139, 295147, 295155, 
+    295164, 295171, 295179, 295187, 295196, 295204, 295213, 295222, 
+    295232, 295239, 295247, 295255, 295264, 295272, 295281, 295290, 
+    295300, 295308, 295317, 295326, 295336, 295345, 295355, 295365, 
+    295376, 295383, 295391, 295399, 295408, 295416, 295425, 295434, 
+    295444, 295452, 295461, 295470, 295480, 295489, 295499, 295509, 
+    295520, 295528, 295537, 295546, 295556, 295565, 295575, 295585, 
+    295596, 295605, 295615, 295625, 295636, 295646, 295657, 295668, 
+    295680, 295685, 295691, 295697, 295704, 295710, 295717, 295724, 
+    295732, 295738, 295745, 295752, 295760, 295767, 295775, 295783, 
+    295792, 295798, 295805, 295812, 295820, 295827, 295835, 295843, 
+    295852, 295859, 295867, 295875, 295884, 295892, 295901, 295910, 
+    295920, 295926, 295933, 295940, 295948, 295955, 295963, 295971, 
+    295980, 295987, 295995, 296003, 296012, 296020, 296029, 296038, 
+    296048, 296055, 296063, 296071, 296080, 296088, 296097, 296106, 
+    296116, 296124, 296133, 296142, 296152, 296161, 296171, 296181, 
+    296192, 296198, 296205, 296212, 296220, 296227, 296235, 296243, 
+    296252, 296259, 296267, 296275, 296284, 296292, 296301, 296310, 
+    296320, 296327, 296335, 296343, 296352, 296360, 296369, 296378, 
+    296388, 296396, 296405, 296414, 296424, 296433, 296443, 296453, 
+    296464, 296471, 296479, 296487, 296496, 296504, 296513, 296522, 
+    296532, 296540, 296549, 296558, 296568, 296577, 296587, 296597, 
+    296608, 296616, 296625, 296634, 296644, 296653, 296663, 296673, 
+    296684, 296693, 296703, 296713, 296724, 296734, 296745, 296756, 
+    296768, 296774, 296781, 296788, 296796, 296803, 296811, 296819, 
+    296828, 296835, 296843, 296851, 296860, 296868, 296877, 296886, 
+    296896, 296903, 296911, 296919, 296928, 296936, 296945, 296954, 
+    296964, 296972, 296981, 296990, 297000, 297009, 297019, 297029, 
+    297040, 297047, 297055, 297063, 297072, 297080, 297089, 297098, 
+    297108, 297116, 297125, 297134, 297144, 297153, 297163, 297173, 
+    297184, 297192, 297201, 297210, 297220, 297229, 297239, 297249, 
+    297260, 297269, 297279, 297289, 297300, 297310, 297321, 297332, 
+    297344, 297351, 297359, 297367, 297376, 297384, 297393, 297402, 
+    297412, 297420, 297429, 297438, 297448, 297457, 297467, 297477, 
+    297488, 297496, 297505, 297514, 297524, 297533, 297543, 297553, 
+    297564, 297573, 297583, 297593, 297604, 297614, 297625, 297636, 
+    297648, 297656, 297665, 297674, 297684, 297693, 297703, 297713, 
+    297724, 297733, 297743, 297753, 297764, 297774, 297785, 297796, 
+    297808, 297817, 297827, 297837, 297848, 297858, 297869, 297880, 
+    297892, 297902, 297913, 297924, 297936, 297947, 297959, 297971, 
+    297984, 297988, 297993, 297998, 298004, 298009, 298015, 298021, 
+    298028, 298033, 298039, 298045, 298052, 298058, 298065, 298072, 
+    298080, 298085, 298091, 298097, 298104, 298110, 298117, 298124, 
+    298132, 298138, 298145, 298152, 298160, 298167, 298175, 298183, 
+    298192, 298197, 298203, 298209, 298216, 298222, 298229, 298236, 
+    298244, 298250, 298257, 298264, 298272, 298279, 298287, 298295, 
+    298304, 298310, 298317, 298324, 298332, 298339, 298347, 298355, 
+    298364, 298371, 298379, 298387, 298396, 298404, 298413, 298422, 
+    298432, 298437, 298443, 298449, 298456, 298462, 298469, 298476, 
+    298484, 298490, 298497, 298504, 298512, 298519, 298527, 298535, 
+    298544, 298550, 298557, 298564, 298572, 298579, 298587, 298595, 
+    298604, 298611, 298619, 298627, 298636, 298644, 298653, 298662, 
+    298672, 298678, 298685, 298692, 298700, 298707, 298715, 298723, 
+    298732, 298739, 298747, 298755, 298764, 298772, 298781, 298790, 
+    298800, 298807, 298815, 298823, 298832, 298840, 298849, 298858, 
+    298868, 298876, 298885, 298894, 298904, 298913, 298923, 298933, 
+    298944, 298949, 298955, 298961, 298968, 298974, 298981, 298988, 
+    298996, 299002, 299009, 299016, 299024, 299031, 299039, 299047, 
+    299056, 299062, 299069, 299076, 299084, 299091, 299099, 299107, 
+    299116, 299123, 299131, 299139, 299148, 299156, 299165, 299174, 
+    299184, 299190, 299197, 299204, 299212, 299219, 299227, 299235, 
+    299244, 299251, 299259, 299267, 299276, 299284, 299293, 299302, 
+    299312, 299319, 299327, 299335, 299344, 299352, 299361, 299370, 
+    299380, 299388, 299397, 299406, 299416, 299425, 299435, 299445, 
+    299456, 299462, 299469, 299476, 299484, 299491, 299499, 299507, 
+    299516, 299523, 299531, 299539, 299548, 299556, 299565, 299574, 
+    299584, 299591, 299599, 299607, 299616, 299624, 299633, 299642, 
+    299652, 299660, 299669, 299678, 299688, 299697, 299707, 299717, 
+    299728, 299735, 299743, 299751, 299760, 299768, 299777, 299786, 
+    299796, 299804, 299813, 299822, 299832, 299841, 299851, 299861, 
+    299872, 299880, 299889, 299898, 299908, 299917, 299927, 299937, 
+    299948, 299957, 299967, 299977, 299988, 299998, 300009, 300020, 
+    300032, 300037, 300043, 300049, 300056, 300062, 300069, 300076, 
+    300084, 300090, 300097, 300104, 300112, 300119, 300127, 300135, 
+    300144, 300150, 300157, 300164, 300172, 300179, 300187, 300195, 
+    300204, 300211, 300219, 300227, 300236, 300244, 300253, 300262, 
+    300272, 300278, 300285, 300292, 300300, 300307, 300315, 300323, 
+    300332, 300339, 300347, 300355, 300364, 300372, 300381, 300390, 
+    300400, 300407, 300415, 300423, 300432, 300440, 300449, 300458, 
+    300468, 300476, 300485, 300494, 300504, 300513, 300523, 300533, 
+    300544, 300550, 300557, 300564, 300572, 300579, 300587, 300595, 
+    300604, 300611, 300619, 300627, 300636, 300644, 300653, 300662, 
+    300672, 300679, 300687, 300695, 300704, 300712, 300721, 300730, 
+    300740, 300748, 300757, 300766, 300776, 300785, 300795, 300805, 
+    300816, 300823, 300831, 300839, 300848, 300856, 300865, 300874, 
+    300884, 300892, 300901, 300910, 300920, 300929, 300939, 300949, 
+    300960, 300968, 300977, 300986, 300996, 301005, 301015, 301025, 
+    301036, 301045, 301055, 301065, 301076, 301086, 301097, 301108, 
+    301120, 301126, 301133, 301140, 301148, 301155, 301163, 301171, 
+    301180, 301187, 301195, 301203, 301212, 301220, 301229, 301238, 
+    301248, 301255, 301263, 301271, 301280, 301288, 301297, 301306, 
+    301316, 301324, 301333, 301342, 301352, 301361, 301371, 301381, 
+    301392, 301399, 301407, 301415, 301424, 301432, 301441, 301450, 
+    301460, 301468, 301477, 301486, 301496, 301505, 301515, 301525, 
+    301536, 301544, 301553, 301562, 301572, 301581, 301591, 301601, 
+    301612, 301621, 301631, 301641, 301652, 301662, 301673, 301684, 
+    301696, 301703, 301711, 301719, 301728, 301736, 301745, 301754, 
+    301764, 301772, 301781, 301790, 301800, 301809, 301819, 301829, 
+    301840, 301848, 301857, 301866, 301876, 301885, 301895, 301905, 
+    301916, 301925, 301935, 301945, 301956, 301966, 301977, 301988, 
+    302000, 302008, 302017, 302026, 302036, 302045, 302055, 302065, 
+    302076, 302085, 302095, 302105, 302116, 302126, 302137, 302148, 
+    302160, 302169, 302179, 302189, 302200, 302210, 302221, 302232, 
+    302244, 302254, 302265, 302276, 302288, 302299, 302311, 302323, 
+    302336, 302341, 302347, 302353, 302360, 302366, 302373, 302380, 
+    302388, 302394, 302401, 302408, 302416, 302423, 302431, 302439, 
+    302448, 302454, 302461, 302468, 302476, 302483, 302491, 302499, 
+    302508, 302515, 302523, 302531, 302540, 302548, 302557, 302566, 
+    302576, 302582, 302589, 302596, 302604, 302611, 302619, 302627, 
+    302636, 302643, 302651, 302659, 302668, 302676, 302685, 302694, 
+    302704, 302711, 302719, 302727, 302736, 302744, 302753, 302762, 
+    302772, 302780, 302789, 302798, 302808, 302817, 302827, 302837, 
+    302848, 302854, 302861, 302868, 302876, 302883, 302891, 302899, 
+    302908, 302915, 302923, 302931, 302940, 302948, 302957, 302966, 
+    302976, 302983, 302991, 302999, 303008, 303016, 303025, 303034, 
+    303044, 303052, 303061, 303070, 303080, 303089, 303099, 303109, 
+    303120, 303127, 303135, 303143, 303152, 303160, 303169, 303178, 
+    303188, 303196, 303205, 303214, 303224, 303233, 303243, 303253, 
+    303264, 303272, 303281, 303290, 303300, 303309, 303319, 303329, 
+    303340, 303349, 303359, 303369, 303380, 303390, 303401, 303412, 
+    303424, 303430, 303437, 303444, 303452, 303459, 303467, 303475, 
+    303484, 303491, 303499, 303507, 303516, 303524, 303533, 303542, 
+    303552, 303559, 303567, 303575, 303584, 303592, 303601, 303610, 
+    303620, 303628, 303637, 303646, 303656, 303665, 303675, 303685, 
+    303696, 303703, 303711, 303719, 303728, 303736, 303745, 303754, 
+    303764, 303772, 303781, 303790, 303800, 303809, 303819, 303829, 
+    303840, 303848, 303857, 303866, 303876, 303885, 303895, 303905, 
+    303916, 303925, 303935, 303945, 303956, 303966, 303977, 303988, 
+    304000, 304007, 304015, 304023, 304032, 304040, 304049, 304058, 
+    304068, 304076, 304085, 304094, 304104, 304113, 304123, 304133, 
+    304144, 304152, 304161, 304170, 304180, 304189, 304199, 304209, 
+    304220, 304229, 304239, 304249, 304260, 304270, 304281, 304292, 
+    304304, 304312, 304321, 304330, 304340, 304349, 304359, 304369, 
+    304380, 304389, 304399, 304409, 304420, 304430, 304441, 304452, 
+    304464, 304473, 304483, 304493, 304504, 304514, 304525, 304536, 
+    304548, 304558, 304569, 304580, 304592, 304603, 304615, 304627, 
+    304640, 304646, 304653, 304660, 304668, 304675, 304683, 304691, 
+    304700, 304707, 304715, 304723, 304732, 304740, 304749, 304758, 
+    304768, 304775, 304783, 304791, 304800, 304808, 304817, 304826, 
+    304836, 304844, 304853, 304862, 304872, 304881, 304891, 304901, 
+    304912, 304919, 304927, 304935, 304944, 304952, 304961, 304970, 
+    304980, 304988, 304997, 305006, 305016, 305025, 305035, 305045, 
+    305056, 305064, 305073, 305082, 305092, 305101, 305111, 305121, 
+    305132, 305141, 305151, 305161, 305172, 305182, 305193, 305204, 
+    305216, 305223, 305231, 305239, 305248, 305256, 305265, 305274, 
+    305284, 305292, 305301, 305310, 305320, 305329, 305339, 305349, 
+    305360, 305368, 305377, 305386, 305396, 305405, 305415, 305425, 
+    305436, 305445, 305455, 305465, 305476, 305486, 305497, 305508, 
+    305520, 305528, 305537, 305546, 305556, 305565, 305575, 305585, 
+    305596, 305605, 305615, 305625, 305636, 305646, 305657, 305668, 
+    305680, 305689, 305699, 305709, 305720, 305730, 305741, 305752, 
+    305764, 305774, 305785, 305796, 305808, 305819, 305831, 305843, 
+    305856, 305863, 305871, 305879, 305888, 305896, 305905, 305914, 
+    305924, 305932, 305941, 305950, 305960, 305969, 305979, 305989, 
+    306000, 306008, 306017, 306026, 306036, 306045, 306055, 306065, 
+    306076, 306085, 306095, 306105, 306116, 306126, 306137, 306148, 
+    306160, 306168, 306177, 306186, 306196, 306205, 306215, 306225, 
+    306236, 306245, 306255, 306265, 306276, 306286, 306297, 306308, 
+    306320, 306329, 306339, 306349, 306360, 306370, 306381, 306392, 
+    306404, 306414, 306425, 306436, 306448, 306459, 306471, 306483, 
+    306496, 306504, 306513, 306522, 306532, 306541, 306551, 306561, 
+    306572, 306581, 306591, 306601, 306612, 306622, 306633, 306644, 
+    306656, 306665, 306675, 306685, 306696, 306706, 306717, 306728, 
+    306740, 306750, 306761, 306772, 306784, 306795, 306807, 306819, 
+    306832, 306841, 306851, 306861, 306872, 306882, 306893, 306904, 
+    306916, 306926, 306937, 306948, 306960, 306971, 306983, 306995, 
+    307008, 307018, 307029, 307040, 307052, 307063, 307075, 307087, 
+    307100, 307111, 307123, 307135, 307148, 307160, 307173, 307186, 
+    307200, 307202, 307205, 307208, 307212, 307215, 307219, 307223, 
+    307228, 307231, 307235, 307239, 307244, 307248, 307253, 307258, 
+    307264, 307267, 307271, 307275, 307280, 307284, 307289, 307294, 
+    307300, 307304, 307309, 307314, 307320, 307325, 307331, 307337, 
+    307344, 307347, 307351, 307355, 307360, 307364, 307369, 307374, 
+    307380, 307384, 307389, 307394, 307400, 307405, 307411, 307417, 
+    307424, 307428, 307433, 307438, 307444, 307449, 307455, 307461, 
+    307468, 307473, 307479, 307485, 307492, 307498, 307505, 307512, 
+    307520, 307523, 307527, 307531, 307536, 307540, 307545, 307550, 
+    307556, 307560, 307565, 307570, 307576, 307581, 307587, 307593, 
+    307600, 307604, 307609, 307614, 307620, 307625, 307631, 307637, 
+    307644, 307649, 307655, 307661, 307668, 307674, 307681, 307688, 
+    307696, 307700, 307705, 307710, 307716, 307721, 307727, 307733, 
+    307740, 307745, 307751, 307757, 307764, 307770, 307777, 307784, 
+    307792, 307797, 307803, 307809, 307816, 307822, 307829, 307836, 
+    307844, 307850, 307857, 307864, 307872, 307879, 307887, 307895, 
+    307904, 307907, 307911, 307915, 307920, 307924, 307929, 307934, 
+    307940, 307944, 307949, 307954, 307960, 307965, 307971, 307977, 
+    307984, 307988, 307993, 307998, 308004, 308009, 308015, 308021, 
+    308028, 308033, 308039, 308045, 308052, 308058, 308065, 308072, 
+    308080, 308084, 308089, 308094, 308100, 308105, 308111, 308117, 
+    308124, 308129, 308135, 308141, 308148, 308154, 308161, 308168, 
+    308176, 308181, 308187, 308193, 308200, 308206, 308213, 308220, 
+    308228, 308234, 308241, 308248, 308256, 308263, 308271, 308279, 
+    308288, 308292, 308297, 308302, 308308, 308313, 308319, 308325, 
+    308332, 308337, 308343, 308349, 308356, 308362, 308369, 308376, 
+    308384, 308389, 308395, 308401, 308408, 308414, 308421, 308428, 
+    308436, 308442, 308449, 308456, 308464, 308471, 308479, 308487, 
+    308496, 308501, 308507, 308513, 308520, 308526, 308533, 308540, 
+    308548, 308554, 308561, 308568, 308576, 308583, 308591, 308599, 
+    308608, 308614, 308621, 308628, 308636, 308643, 308651, 308659, 
+    308668, 308675, 308683, 308691, 308700, 308708, 308717, 308726, 
+    308736, 308739, 308743, 308747, 308752, 308756, 308761, 308766, 
+    308772, 308776, 308781, 308786, 308792, 308797, 308803, 308809, 
+    308816, 308820, 308825, 308830, 308836, 308841, 308847, 308853, 
+    308860, 308865, 308871, 308877, 308884, 308890, 308897, 308904, 
+    308912, 308916, 308921, 308926, 308932, 308937, 308943, 308949, 
+    308956, 308961, 308967, 308973, 308980, 308986, 308993, 309000, 
+    309008, 309013, 309019, 309025, 309032, 309038, 309045, 309052, 
+    309060, 309066, 309073, 309080, 309088, 309095, 309103, 309111, 
+    309120, 309124, 309129, 309134, 309140, 309145, 309151, 309157, 
+    309164, 309169, 309175, 309181, 309188, 309194, 309201, 309208, 
+    309216, 309221, 309227, 309233, 309240, 309246, 309253, 309260, 
+    309268, 309274, 309281, 309288, 309296, 309303, 309311, 309319, 
+    309328, 309333, 309339, 309345, 309352, 309358, 309365, 309372, 
+    309380, 309386, 309393, 309400, 309408, 309415, 309423, 309431, 
+    309440, 309446, 309453, 309460, 309468, 309475, 309483, 309491, 
+    309500, 309507, 309515, 309523, 309532, 309540, 309549, 309558, 
+    309568, 309572, 309577, 309582, 309588, 309593, 309599, 309605, 
+    309612, 309617, 309623, 309629, 309636, 309642, 309649, 309656, 
+    309664, 309669, 309675, 309681, 309688, 309694, 309701, 309708, 
+    309716, 309722, 309729, 309736, 309744, 309751, 309759, 309767, 
+    309776, 309781, 309787, 309793, 309800, 309806, 309813, 309820, 
+    309828, 309834, 309841, 309848, 309856, 309863, 309871, 309879, 
+    309888, 309894, 309901, 309908, 309916, 309923, 309931, 309939, 
+    309948, 309955, 309963, 309971, 309980, 309988, 309997, 310006, 
+    310016, 310021, 310027, 310033, 310040, 310046, 310053, 310060, 
+    310068, 310074, 310081, 310088, 310096, 310103, 310111, 310119, 
+    310128, 310134, 310141, 310148, 310156, 310163, 310171, 310179, 
+    310188, 310195, 310203, 310211, 310220, 310228, 310237, 310246, 
+    310256, 310262, 310269, 310276, 310284, 310291, 310299, 310307, 
+    310316, 310323, 310331, 310339, 310348, 310356, 310365, 310374, 
+    310384, 310391, 310399, 310407, 310416, 310424, 310433, 310442, 
+    310452, 310460, 310469, 310478, 310488, 310497, 310507, 310517, 
+    310528, 310531, 310535, 310539, 310544, 310548, 310553, 310558, 
+    310564, 310568, 310573, 310578, 310584, 310589, 310595, 310601, 
+    310608, 310612, 310617, 310622, 310628, 310633, 310639, 310645, 
+    310652, 310657, 310663, 310669, 310676, 310682, 310689, 310696, 
+    310704, 310708, 310713, 310718, 310724, 310729, 310735, 310741, 
+    310748, 310753, 310759, 310765, 310772, 310778, 310785, 310792, 
+    310800, 310805, 310811, 310817, 310824, 310830, 310837, 310844, 
+    310852, 310858, 310865, 310872, 310880, 310887, 310895, 310903, 
+    310912, 310916, 310921, 310926, 310932, 310937, 310943, 310949, 
+    310956, 310961, 310967, 310973, 310980, 310986, 310993, 311000, 
+    311008, 311013, 311019, 311025, 311032, 311038, 311045, 311052, 
+    311060, 311066, 311073, 311080, 311088, 311095, 311103, 311111, 
+    311120, 311125, 311131, 311137, 311144, 311150, 311157, 311164, 
+    311172, 311178, 311185, 311192, 311200, 311207, 311215, 311223, 
+    311232, 311238, 311245, 311252, 311260, 311267, 311275, 311283, 
+    311292, 311299, 311307, 311315, 311324, 311332, 311341, 311350, 
+    311360, 311364, 311369, 311374, 311380, 311385, 311391, 311397, 
+    311404, 311409, 311415, 311421, 311428, 311434, 311441, 311448, 
+    311456, 311461, 311467, 311473, 311480, 311486, 311493, 311500, 
+    311508, 311514, 311521, 311528, 311536, 311543, 311551, 311559, 
+    311568, 311573, 311579, 311585, 311592, 311598, 311605, 311612, 
+    311620, 311626, 311633, 311640, 311648, 311655, 311663, 311671, 
+    311680, 311686, 311693, 311700, 311708, 311715, 311723, 311731, 
+    311740, 311747, 311755, 311763, 311772, 311780, 311789, 311798, 
+    311808, 311813, 311819, 311825, 311832, 311838, 311845, 311852, 
+    311860, 311866, 311873, 311880, 311888, 311895, 311903, 311911, 
+    311920, 311926, 311933, 311940, 311948, 311955, 311963, 311971, 
+    311980, 311987, 311995, 312003, 312012, 312020, 312029, 312038, 
+    312048, 312054, 312061, 312068, 312076, 312083, 312091, 312099, 
+    312108, 312115, 312123, 312131, 312140, 312148, 312157, 312166, 
+    312176, 312183, 312191, 312199, 312208, 312216, 312225, 312234, 
+    312244, 312252, 312261, 312270, 312280, 312289, 312299, 312309, 
+    312320, 312324, 312329, 312334, 312340, 312345, 312351, 312357, 
+    312364, 312369, 312375, 312381, 312388, 312394, 312401, 312408, 
+    312416, 312421, 312427, 312433, 312440, 312446, 312453, 312460, 
+    312468, 312474, 312481, 312488, 312496, 312503, 312511, 312519, 
+    312528, 312533, 312539, 312545, 312552, 312558, 312565, 312572, 
+    312580, 312586, 312593, 312600, 312608, 312615, 312623, 312631, 
+    312640, 312646, 312653, 312660, 312668, 312675, 312683, 312691, 
+    312700, 312707, 312715, 312723, 312732, 312740, 312749, 312758, 
+    312768, 312773, 312779, 312785, 312792, 312798, 312805, 312812, 
+    312820, 312826, 312833, 312840, 312848, 312855, 312863, 312871, 
+    312880, 312886, 312893, 312900, 312908, 312915, 312923, 312931, 
+    312940, 312947, 312955, 312963, 312972, 312980, 312989, 312998, 
+    313008, 313014, 313021, 313028, 313036, 313043, 313051, 313059, 
+    313068, 313075, 313083, 313091, 313100, 313108, 313117, 313126, 
+    313136, 313143, 313151, 313159, 313168, 313176, 313185, 313194, 
+    313204, 313212, 313221, 313230, 313240, 313249, 313259, 313269, 
+    313280, 313285, 313291, 313297, 313304, 313310, 313317, 313324, 
+    313332, 313338, 313345, 313352, 313360, 313367, 313375, 313383, 
+    313392, 313398, 313405, 313412, 313420, 313427, 313435, 313443, 
+    313452, 313459, 313467, 313475, 313484, 313492, 313501, 313510, 
+    313520, 313526, 313533, 313540, 313548, 313555, 313563, 313571, 
+    313580, 313587, 313595, 313603, 313612, 313620, 313629, 313638, 
+    313648, 313655, 313663, 313671, 313680, 313688, 313697, 313706, 
+    313716, 313724, 313733, 313742, 313752, 313761, 313771, 313781, 
+    313792, 313798, 313805, 313812, 313820, 313827, 313835, 313843, 
+    313852, 313859, 313867, 313875, 313884, 313892, 313901, 313910, 
+    313920, 313927, 313935, 313943, 313952, 313960, 313969, 313978, 
+    313988, 313996, 314005, 314014, 314024, 314033, 314043, 314053, 
+    314064, 314071, 314079, 314087, 314096, 314104, 314113, 314122, 
+    314132, 314140, 314149, 314158, 314168, 314177, 314187, 314197, 
+    314208, 314216, 314225, 314234, 314244, 314253, 314263, 314273, 
+    314284, 314293, 314303, 314313, 314324, 314334, 314345, 314356, 
+    314368, 314371, 314375, 314379, 314384, 314388, 314393, 314398, 
+    314404, 314408, 314413, 314418, 314424, 314429, 314435, 314441, 
+    314448, 314452, 314457, 314462, 314468, 314473, 314479, 314485, 
+    314492, 314497, 314503, 314509, 314516, 314522, 314529, 314536, 
+    314544, 314548, 314553, 314558, 314564, 314569, 314575, 314581, 
+    314588, 314593, 314599, 314605, 314612, 314618, 314625, 314632, 
+    314640, 314645, 314651, 314657, 314664, 314670, 314677, 314684, 
+    314692, 314698, 314705, 314712, 314720, 314727, 314735, 314743, 
+    314752, 314756, 314761, 314766, 314772, 314777, 314783, 314789, 
+    314796, 314801, 314807, 314813, 314820, 314826, 314833, 314840, 
+    314848, 314853, 314859, 314865, 314872, 314878, 314885, 314892, 
+    314900, 314906, 314913, 314920, 314928, 314935, 314943, 314951, 
+    314960, 314965, 314971, 314977, 314984, 314990, 314997, 315004, 
+    315012, 315018, 315025, 315032, 315040, 315047, 315055, 315063, 
+    315072, 315078, 315085, 315092, 315100, 315107, 315115, 315123, 
+    315132, 315139, 315147, 315155, 315164, 315172, 315181, 315190, 
+    315200, 315204, 315209, 315214, 315220, 315225, 315231, 315237, 
+    315244, 315249, 315255, 315261, 315268, 315274, 315281, 315288, 
+    315296, 315301, 315307, 315313, 315320, 315326, 315333, 315340, 
+    315348, 315354, 315361, 315368, 315376, 315383, 315391, 315399, 
+    315408, 315413, 315419, 315425, 315432, 315438, 315445, 315452, 
+    315460, 315466, 315473, 315480, 315488, 315495, 315503, 315511, 
+    315520, 315526, 315533, 315540, 315548, 315555, 315563, 315571, 
+    315580, 315587, 315595, 315603, 315612, 315620, 315629, 315638, 
+    315648, 315653, 315659, 315665, 315672, 315678, 315685, 315692, 
+    315700, 315706, 315713, 315720, 315728, 315735, 315743, 315751, 
+    315760, 315766, 315773, 315780, 315788, 315795, 315803, 315811, 
+    315820, 315827, 315835, 315843, 315852, 315860, 315869, 315878, 
+    315888, 315894, 315901, 315908, 315916, 315923, 315931, 315939, 
+    315948, 315955, 315963, 315971, 315980, 315988, 315997, 316006, 
+    316016, 316023, 316031, 316039, 316048, 316056, 316065, 316074, 
+    316084, 316092, 316101, 316110, 316120, 316129, 316139, 316149, 
+    316160, 316164, 316169, 316174, 316180, 316185, 316191, 316197, 
+    316204, 316209, 316215, 316221, 316228, 316234, 316241, 316248, 
+    316256, 316261, 316267, 316273, 316280, 316286, 316293, 316300, 
+    316308, 316314, 316321, 316328, 316336, 316343, 316351, 316359, 
+    316368, 316373, 316379, 316385, 316392, 316398, 316405, 316412, 
+    316420, 316426, 316433, 316440, 316448, 316455, 316463, 316471, 
+    316480, 316486, 316493, 316500, 316508, 316515, 316523, 316531, 
+    316540, 316547, 316555, 316563, 316572, 316580, 316589, 316598, 
+    316608, 316613, 316619, 316625, 316632, 316638, 316645, 316652, 
+    316660, 316666, 316673, 316680, 316688, 316695, 316703, 316711, 
+    316720, 316726, 316733, 316740, 316748, 316755, 316763, 316771, 
+    316780, 316787, 316795, 316803, 316812, 316820, 316829, 316838, 
+    316848, 316854, 316861, 316868, 316876, 316883, 316891, 316899, 
+    316908, 316915, 316923, 316931, 316940, 316948, 316957, 316966, 
+    316976, 316983, 316991, 316999, 317008, 317016, 317025, 317034, 
+    317044, 317052, 317061, 317070, 317080, 317089, 317099, 317109, 
+    317120, 317125, 317131, 317137, 317144, 317150, 317157, 317164, 
+    317172, 317178, 317185, 317192, 317200, 317207, 317215, 317223, 
+    317232, 317238, 317245, 317252, 317260, 317267, 317275, 317283, 
+    317292, 317299, 317307, 317315, 317324, 317332, 317341, 317350, 
+    317360, 317366, 317373, 317380, 317388, 317395, 317403, 317411, 
+    317420, 317427, 317435, 317443, 317452, 317460, 317469, 317478, 
+    317488, 317495, 317503, 317511, 317520, 317528, 317537, 317546, 
+    317556, 317564, 317573, 317582, 317592, 317601, 317611, 317621, 
+    317632, 317638, 317645, 317652, 317660, 317667, 317675, 317683, 
+    317692, 317699, 317707, 317715, 317724, 317732, 317741, 317750, 
+    317760, 317767, 317775, 317783, 317792, 317800, 317809, 317818, 
+    317828, 317836, 317845, 317854, 317864, 317873, 317883, 317893, 
+    317904, 317911, 317919, 317927, 317936, 317944, 317953, 317962, 
+    317972, 317980, 317989, 317998, 318008, 318017, 318027, 318037, 
+    318048, 318056, 318065, 318074, 318084, 318093, 318103, 318113, 
+    318124, 318133, 318143, 318153, 318164, 318174, 318185, 318196, 
+    318208, 318212, 318217, 318222, 318228, 318233, 318239, 318245, 
+    318252, 318257, 318263, 318269, 318276, 318282, 318289, 318296, 
+    318304, 318309, 318315, 318321, 318328, 318334, 318341, 318348, 
+    318356, 318362, 318369, 318376, 318384, 318391, 318399, 318407, 
+    318416, 318421, 318427, 318433, 318440, 318446, 318453, 318460, 
+    318468, 318474, 318481, 318488, 318496, 318503, 318511, 318519, 
+    318528, 318534, 318541, 318548, 318556, 318563, 318571, 318579, 
+    318588, 318595, 318603, 318611, 318620, 318628, 318637, 318646, 
+    318656, 318661, 318667, 318673, 318680, 318686, 318693, 318700, 
+    318708, 318714, 318721, 318728, 318736, 318743, 318751, 318759, 
+    318768, 318774, 318781, 318788, 318796, 318803, 318811, 318819, 
+    318828, 318835, 318843, 318851, 318860, 318868, 318877, 318886, 
+    318896, 318902, 318909, 318916, 318924, 318931, 318939, 318947, 
+    318956, 318963, 318971, 318979, 318988, 318996, 319005, 319014, 
+    319024, 319031, 319039, 319047, 319056, 319064, 319073, 319082, 
+    319092, 319100, 319109, 319118, 319128, 319137, 319147, 319157, 
+    319168, 319173, 319179, 319185, 319192, 319198, 319205, 319212, 
+    319220, 319226, 319233, 319240, 319248, 319255, 319263, 319271, 
+    319280, 319286, 319293, 319300, 319308, 319315, 319323, 319331, 
+    319340, 319347, 319355, 319363, 319372, 319380, 319389, 319398, 
+    319408, 319414, 319421, 319428, 319436, 319443, 319451, 319459, 
+    319468, 319475, 319483, 319491, 319500, 319508, 319517, 319526, 
+    319536, 319543, 319551, 319559, 319568, 319576, 319585, 319594, 
+    319604, 319612, 319621, 319630, 319640, 319649, 319659, 319669, 
+    319680, 319686, 319693, 319700, 319708, 319715, 319723, 319731, 
+    319740, 319747, 319755, 319763, 319772, 319780, 319789, 319798, 
+    319808, 319815, 319823, 319831, 319840, 319848, 319857, 319866, 
+    319876, 319884, 319893, 319902, 319912, 319921, 319931, 319941, 
+    319952, 319959, 319967, 319975, 319984, 319992, 320001, 320010, 
+    320020, 320028, 320037, 320046, 320056, 320065, 320075, 320085, 
+    320096, 320104, 320113, 320122, 320132, 320141, 320151, 320161, 
+    320172, 320181, 320191, 320201, 320212, 320222, 320233, 320244, 
+    320256, 320261, 320267, 320273, 320280, 320286, 320293, 320300, 
+    320308, 320314, 320321, 320328, 320336, 320343, 320351, 320359, 
+    320368, 320374, 320381, 320388, 320396, 320403, 320411, 320419, 
+    320428, 320435, 320443, 320451, 320460, 320468, 320477, 320486, 
+    320496, 320502, 320509, 320516, 320524, 320531, 320539, 320547, 
+    320556, 320563, 320571, 320579, 320588, 320596, 320605, 320614, 
+    320624, 320631, 320639, 320647, 320656, 320664, 320673, 320682, 
+    320692, 320700, 320709, 320718, 320728, 320737, 320747, 320757, 
+    320768, 320774, 320781, 320788, 320796, 320803, 320811, 320819, 
+    320828, 320835, 320843, 320851, 320860, 320868, 320877, 320886, 
+    320896, 320903, 320911, 320919, 320928, 320936, 320945, 320954, 
+    320964, 320972, 320981, 320990, 321000, 321009, 321019, 321029, 
+    321040, 321047, 321055, 321063, 321072, 321080, 321089, 321098, 
+    321108, 321116, 321125, 321134, 321144, 321153, 321163, 321173, 
+    321184, 321192, 321201, 321210, 321220, 321229, 321239, 321249, 
+    321260, 321269, 321279, 321289, 321300, 321310, 321321, 321332, 
+    321344, 321350, 321357, 321364, 321372, 321379, 321387, 321395, 
+    321404, 321411, 321419, 321427, 321436, 321444, 321453, 321462, 
+    321472, 321479, 321487, 321495, 321504, 321512, 321521, 321530, 
+    321540, 321548, 321557, 321566, 321576, 321585, 321595, 321605, 
+    321616, 321623, 321631, 321639, 321648, 321656, 321665, 321674, 
+    321684, 321692, 321701, 321710, 321720, 321729, 321739, 321749, 
+    321760, 321768, 321777, 321786, 321796, 321805, 321815, 321825, 
+    321836, 321845, 321855, 321865, 321876, 321886, 321897, 321908, 
+    321920, 321927, 321935, 321943, 321952, 321960, 321969, 321978, 
+    321988, 321996, 322005, 322014, 322024, 322033, 322043, 322053, 
+    322064, 322072, 322081, 322090, 322100, 322109, 322119, 322129, 
+    322140, 322149, 322159, 322169, 322180, 322190, 322201, 322212, 
+    322224, 322232, 322241, 322250, 322260, 322269, 322279, 322289, 
+    322300, 322309, 322319, 322329, 322340, 322350, 322361, 322372, 
+    322384, 322393, 322403, 322413, 322424, 322434, 322445, 322456, 
+    322468, 322478, 322489, 322500, 322512, 322523, 322535, 322547, 
+    322560, 322563, 322567, 322571, 322576, 322580, 322585, 322590, 
+    322596, 322600, 322605, 322610, 322616, 322621, 322627, 322633, 
+    322640, 322644, 322649, 322654, 322660, 322665, 322671, 322677, 
+    322684, 322689, 322695, 322701, 322708, 322714, 322721, 322728, 
+    322736, 322740, 322745, 322750, 322756, 322761, 322767, 322773, 
+    322780, 322785, 322791, 322797, 322804, 322810, 322817, 322824, 
+    322832, 322837, 322843, 322849, 322856, 322862, 322869, 322876, 
+    322884, 322890, 322897, 322904, 322912, 322919, 322927, 322935, 
+    322944, 322948, 322953, 322958, 322964, 322969, 322975, 322981, 
+    322988, 322993, 322999, 323005, 323012, 323018, 323025, 323032, 
+    323040, 323045, 323051, 323057, 323064, 323070, 323077, 323084, 
+    323092, 323098, 323105, 323112, 323120, 323127, 323135, 323143, 
+    323152, 323157, 323163, 323169, 323176, 323182, 323189, 323196, 
+    323204, 323210, 323217, 323224, 323232, 323239, 323247, 323255, 
+    323264, 323270, 323277, 323284, 323292, 323299, 323307, 323315, 
+    323324, 323331, 323339, 323347, 323356, 323364, 323373, 323382, 
+    323392, 323396, 323401, 323406, 323412, 323417, 323423, 323429, 
+    323436, 323441, 323447, 323453, 323460, 323466, 323473, 323480, 
+    323488, 323493, 323499, 323505, 323512, 323518, 323525, 323532, 
+    323540, 323546, 323553, 323560, 323568, 323575, 323583, 323591, 
+    323600, 323605, 323611, 323617, 323624, 323630, 323637, 323644, 
+    323652, 323658, 323665, 323672, 323680, 323687, 323695, 323703, 
+    323712, 323718, 323725, 323732, 323740, 323747, 323755, 323763, 
+    323772, 323779, 323787, 323795, 323804, 323812, 323821, 323830, 
+    323840, 323845, 323851, 323857, 323864, 323870, 323877, 323884, 
+    323892, 323898, 323905, 323912, 323920, 323927, 323935, 323943, 
+    323952, 323958, 323965, 323972, 323980, 323987, 323995, 324003, 
+    324012, 324019, 324027, 324035, 324044, 324052, 324061, 324070, 
+    324080, 324086, 324093, 324100, 324108, 324115, 324123, 324131, 
+    324140, 324147, 324155, 324163, 324172, 324180, 324189, 324198, 
+    324208, 324215, 324223, 324231, 324240, 324248, 324257, 324266, 
+    324276, 324284, 324293, 324302, 324312, 324321, 324331, 324341, 
+    324352, 324356, 324361, 324366, 324372, 324377, 324383, 324389, 
+    324396, 324401, 324407, 324413, 324420, 324426, 324433, 324440, 
+    324448, 324453, 324459, 324465, 324472, 324478, 324485, 324492, 
+    324500, 324506, 324513, 324520, 324528, 324535, 324543, 324551, 
+    324560, 324565, 324571, 324577, 324584, 324590, 324597, 324604, 
+    324612, 324618, 324625, 324632, 324640, 324647, 324655, 324663, 
+    324672, 324678, 324685, 324692, 324700, 324707, 324715, 324723, 
+    324732, 324739, 324747, 324755, 324764, 324772, 324781, 324790, 
+    324800, 324805, 324811, 324817, 324824, 324830, 324837, 324844, 
+    324852, 324858, 324865, 324872, 324880, 324887, 324895, 324903, 
+    324912, 324918, 324925, 324932, 324940, 324947, 324955, 324963, 
+    324972, 324979, 324987, 324995, 325004, 325012, 325021, 325030, 
+    325040, 325046, 325053, 325060, 325068, 325075, 325083, 325091, 
+    325100, 325107, 325115, 325123, 325132, 325140, 325149, 325158, 
+    325168, 325175, 325183, 325191, 325200, 325208, 325217, 325226, 
+    325236, 325244, 325253, 325262, 325272, 325281, 325291, 325301, 
+    325312, 325317, 325323, 325329, 325336, 325342, 325349, 325356, 
+    325364, 325370, 325377, 325384, 325392, 325399, 325407, 325415, 
+    325424, 325430, 325437, 325444, 325452, 325459, 325467, 325475, 
+    325484, 325491, 325499, 325507, 325516, 325524, 325533, 325542, 
+    325552, 325558, 325565, 325572, 325580, 325587, 325595, 325603, 
+    325612, 325619, 325627, 325635, 325644, 325652, 325661, 325670, 
+    325680, 325687, 325695, 325703, 325712, 325720, 325729, 325738, 
+    325748, 325756, 325765, 325774, 325784, 325793, 325803, 325813, 
+    325824, 325830, 325837, 325844, 325852, 325859, 325867, 325875, 
+    325884, 325891, 325899, 325907, 325916, 325924, 325933, 325942, 
+    325952, 325959, 325967, 325975, 325984, 325992, 326001, 326010, 
+    326020, 326028, 326037, 326046, 326056, 326065, 326075, 326085, 
+    326096, 326103, 326111, 326119, 326128, 326136, 326145, 326154, 
+    326164, 326172, 326181, 326190, 326200, 326209, 326219, 326229, 
+    326240, 326248, 326257, 326266, 326276, 326285, 326295, 326305, 
+    326316, 326325, 326335, 326345, 326356, 326366, 326377, 326388, 
+    326400, 326404, 326409, 326414, 326420, 326425, 326431, 326437, 
+    326444, 326449, 326455, 326461, 326468, 326474, 326481, 326488, 
+    326496, 326501, 326507, 326513, 326520, 326526, 326533, 326540, 
+    326548, 326554, 326561, 326568, 326576, 326583, 326591, 326599, 
+    326608, 326613, 326619, 326625, 326632, 326638, 326645, 326652, 
+    326660, 326666, 326673, 326680, 326688, 326695, 326703, 326711, 
+    326720, 326726, 326733, 326740, 326748, 326755, 326763, 326771, 
+    326780, 326787, 326795, 326803, 326812, 326820, 326829, 326838, 
+    326848, 326853, 326859, 326865, 326872, 326878, 326885, 326892, 
+    326900, 326906, 326913, 326920, 326928, 326935, 326943, 326951, 
+    326960, 326966, 326973, 326980, 326988, 326995, 327003, 327011, 
+    327020, 327027, 327035, 327043, 327052, 327060, 327069, 327078, 
+    327088, 327094, 327101, 327108, 327116, 327123, 327131, 327139, 
+    327148, 327155, 327163, 327171, 327180, 327188, 327197, 327206, 
+    327216, 327223, 327231, 327239, 327248, 327256, 327265, 327274, 
+    327284, 327292, 327301, 327310, 327320, 327329, 327339, 327349, 
+    327360, 327365, 327371, 327377, 327384, 327390, 327397, 327404, 
+    327412, 327418, 327425, 327432, 327440, 327447, 327455, 327463, 
+    327472, 327478, 327485, 327492, 327500, 327507, 327515, 327523, 
+    327532, 327539, 327547, 327555, 327564, 327572, 327581, 327590, 
+    327600, 327606, 327613, 327620, 327628, 327635, 327643, 327651, 
+    327660, 327667, 327675, 327683, 327692, 327700, 327709, 327718, 
+    327728, 327735, 327743, 327751, 327760, 327768, 327777, 327786, 
+    327796, 327804, 327813, 327822, 327832, 327841, 327851, 327861, 
+    327872, 327878, 327885, 327892, 327900, 327907, 327915, 327923, 
+    327932, 327939, 327947, 327955, 327964, 327972, 327981, 327990, 
+    328000, 328007, 328015, 328023, 328032, 328040, 328049, 328058, 
+    328068, 328076, 328085, 328094, 328104, 328113, 328123, 328133, 
+    328144, 328151, 328159, 328167, 328176, 328184, 328193, 328202, 
+    328212, 328220, 328229, 328238, 328248, 328257, 328267, 328277, 
+    328288, 328296, 328305, 328314, 328324, 328333, 328343, 328353, 
+    328364, 328373, 328383, 328393, 328404, 328414, 328425, 328436, 
+    328448, 328453, 328459, 328465, 328472, 328478, 328485, 328492, 
+    328500, 328506, 328513, 328520, 328528, 328535, 328543, 328551, 
+    328560, 328566, 328573, 328580, 328588, 328595, 328603, 328611, 
+    328620, 328627, 328635, 328643, 328652, 328660, 328669, 328678, 
+    328688, 328694, 328701, 328708, 328716, 328723, 328731, 328739, 
+    328748, 328755, 328763, 328771, 328780, 328788, 328797, 328806, 
+    328816, 328823, 328831, 328839, 328848, 328856, 328865, 328874, 
+    328884, 328892, 328901, 328910, 328920, 328929, 328939, 328949, 
+    328960, 328966, 328973, 328980, 328988, 328995, 329003, 329011, 
+    329020, 329027, 329035, 329043, 329052, 329060, 329069, 329078, 
+    329088, 329095, 329103, 329111, 329120, 329128, 329137, 329146, 
+    329156, 329164, 329173, 329182, 329192, 329201, 329211, 329221, 
+    329232, 329239, 329247, 329255, 329264, 329272, 329281, 329290, 
+    329300, 329308, 329317, 329326, 329336, 329345, 329355, 329365, 
+    329376, 329384, 329393, 329402, 329412, 329421, 329431, 329441, 
+    329452, 329461, 329471, 329481, 329492, 329502, 329513, 329524, 
+    329536, 329542, 329549, 329556, 329564, 329571, 329579, 329587, 
+    329596, 329603, 329611, 329619, 329628, 329636, 329645, 329654, 
+    329664, 329671, 329679, 329687, 329696, 329704, 329713, 329722, 
+    329732, 329740, 329749, 329758, 329768, 329777, 329787, 329797, 
+    329808, 329815, 329823, 329831, 329840, 329848, 329857, 329866, 
+    329876, 329884, 329893, 329902, 329912, 329921, 329931, 329941, 
+    329952, 329960, 329969, 329978, 329988, 329997, 330007, 330017, 
+    330028, 330037, 330047, 330057, 330068, 330078, 330089, 330100, 
+    330112, 330119, 330127, 330135, 330144, 330152, 330161, 330170, 
+    330180, 330188, 330197, 330206, 330216, 330225, 330235, 330245, 
+    330256, 330264, 330273, 330282, 330292, 330301, 330311, 330321, 
+    330332, 330341, 330351, 330361, 330372, 330382, 330393, 330404, 
+    330416, 330424, 330433, 330442, 330452, 330461, 330471, 330481, 
+    330492, 330501, 330511, 330521, 330532, 330542, 330553, 330564, 
+    330576, 330585, 330595, 330605, 330616, 330626, 330637, 330648, 
+    330660, 330670, 330681, 330692, 330704, 330715, 330727, 330739, 
+    330752, 330756, 330761, 330766, 330772, 330777, 330783, 330789, 
+    330796, 330801, 330807, 330813, 330820, 330826, 330833, 330840, 
+    330848, 330853, 330859, 330865, 330872, 330878, 330885, 330892, 
+    330900, 330906, 330913, 330920, 330928, 330935, 330943, 330951, 
+    330960, 330965, 330971, 330977, 330984, 330990, 330997, 331004, 
+    331012, 331018, 331025, 331032, 331040, 331047, 331055, 331063, 
+    331072, 331078, 331085, 331092, 331100, 331107, 331115, 331123, 
+    331132, 331139, 331147, 331155, 331164, 331172, 331181, 331190, 
+    331200, 331205, 331211, 331217, 331224, 331230, 331237, 331244, 
+    331252, 331258, 331265, 331272, 331280, 331287, 331295, 331303, 
+    331312, 331318, 331325, 331332, 331340, 331347, 331355, 331363, 
+    331372, 331379, 331387, 331395, 331404, 331412, 331421, 331430, 
+    331440, 331446, 331453, 331460, 331468, 331475, 331483, 331491, 
+    331500, 331507, 331515, 331523, 331532, 331540, 331549, 331558, 
+    331568, 331575, 331583, 331591, 331600, 331608, 331617, 331626, 
+    331636, 331644, 331653, 331662, 331672, 331681, 331691, 331701, 
+    331712, 331717, 331723, 331729, 331736, 331742, 331749, 331756, 
+    331764, 331770, 331777, 331784, 331792, 331799, 331807, 331815, 
+    331824, 331830, 331837, 331844, 331852, 331859, 331867, 331875, 
+    331884, 331891, 331899, 331907, 331916, 331924, 331933, 331942, 
+    331952, 331958, 331965, 331972, 331980, 331987, 331995, 332003, 
+    332012, 332019, 332027, 332035, 332044, 332052, 332061, 332070, 
+    332080, 332087, 332095, 332103, 332112, 332120, 332129, 332138, 
+    332148, 332156, 332165, 332174, 332184, 332193, 332203, 332213, 
+    332224, 332230, 332237, 332244, 332252, 332259, 332267, 332275, 
+    332284, 332291, 332299, 332307, 332316, 332324, 332333, 332342, 
+    332352, 332359, 332367, 332375, 332384, 332392, 332401, 332410, 
+    332420, 332428, 332437, 332446, 332456, 332465, 332475, 332485, 
+    332496, 332503, 332511, 332519, 332528, 332536, 332545, 332554, 
+    332564, 332572, 332581, 332590, 332600, 332609, 332619, 332629, 
+    332640, 332648, 332657, 332666, 332676, 332685, 332695, 332705, 
+    332716, 332725, 332735, 332745, 332756, 332766, 332777, 332788, 
+    332800, 332805, 332811, 332817, 332824, 332830, 332837, 332844, 
+    332852, 332858, 332865, 332872, 332880, 332887, 332895, 332903, 
+    332912, 332918, 332925, 332932, 332940, 332947, 332955, 332963, 
+    332972, 332979, 332987, 332995, 333004, 333012, 333021, 333030, 
+    333040, 333046, 333053, 333060, 333068, 333075, 333083, 333091, 
+    333100, 333107, 333115, 333123, 333132, 333140, 333149, 333158, 
+    333168, 333175, 333183, 333191, 333200, 333208, 333217, 333226, 
+    333236, 333244, 333253, 333262, 333272, 333281, 333291, 333301, 
+    333312, 333318, 333325, 333332, 333340, 333347, 333355, 333363, 
+    333372, 333379, 333387, 333395, 333404, 333412, 333421, 333430, 
+    333440, 333447, 333455, 333463, 333472, 333480, 333489, 333498, 
+    333508, 333516, 333525, 333534, 333544, 333553, 333563, 333573, 
+    333584, 333591, 333599, 333607, 333616, 333624, 333633, 333642, 
+    333652, 333660, 333669, 333678, 333688, 333697, 333707, 333717, 
+    333728, 333736, 333745, 333754, 333764, 333773, 333783, 333793, 
+    333804, 333813, 333823, 333833, 333844, 333854, 333865, 333876, 
+    333888, 333894, 333901, 333908, 333916, 333923, 333931, 333939, 
+    333948, 333955, 333963, 333971, 333980, 333988, 333997, 334006, 
+    334016, 334023, 334031, 334039, 334048, 334056, 334065, 334074, 
+    334084, 334092, 334101, 334110, 334120, 334129, 334139, 334149, 
+    334160, 334167, 334175, 334183, 334192, 334200, 334209, 334218, 
+    334228, 334236, 334245, 334254, 334264, 334273, 334283, 334293, 
+    334304, 334312, 334321, 334330, 334340, 334349, 334359, 334369, 
+    334380, 334389, 334399, 334409, 334420, 334430, 334441, 334452, 
+    334464, 334471, 334479, 334487, 334496, 334504, 334513, 334522, 
+    334532, 334540, 334549, 334558, 334568, 334577, 334587, 334597, 
+    334608, 334616, 334625, 334634, 334644, 334653, 334663, 334673, 
+    334684, 334693, 334703, 334713, 334724, 334734, 334745, 334756, 
+    334768, 334776, 334785, 334794, 334804, 334813, 334823, 334833, 
+    334844, 334853, 334863, 334873, 334884, 334894, 334905, 334916, 
+    334928, 334937, 334947, 334957, 334968, 334978, 334989, 335000, 
+    335012, 335022, 335033, 335044, 335056, 335067, 335079, 335091, 
+    335104, 335109, 335115, 335121, 335128, 335134, 335141, 335148, 
+    335156, 335162, 335169, 335176, 335184, 335191, 335199, 335207, 
+    335216, 335222, 335229, 335236, 335244, 335251, 335259, 335267, 
+    335276, 335283, 335291, 335299, 335308, 335316, 335325, 335334, 
+    335344, 335350, 335357, 335364, 335372, 335379, 335387, 335395, 
+    335404, 335411, 335419, 335427, 335436, 335444, 335453, 335462, 
+    335472, 335479, 335487, 335495, 335504, 335512, 335521, 335530, 
+    335540, 335548, 335557, 335566, 335576, 335585, 335595, 335605, 
+    335616, 335622, 335629, 335636, 335644, 335651, 335659, 335667, 
+    335676, 335683, 335691, 335699, 335708, 335716, 335725, 335734, 
+    335744, 335751, 335759, 335767, 335776, 335784, 335793, 335802, 
+    335812, 335820, 335829, 335838, 335848, 335857, 335867, 335877, 
+    335888, 335895, 335903, 335911, 335920, 335928, 335937, 335946, 
+    335956, 335964, 335973, 335982, 335992, 336001, 336011, 336021, 
+    336032, 336040, 336049, 336058, 336068, 336077, 336087, 336097, 
+    336108, 336117, 336127, 336137, 336148, 336158, 336169, 336180, 
+    336192, 336198, 336205, 336212, 336220, 336227, 336235, 336243, 
+    336252, 336259, 336267, 336275, 336284, 336292, 336301, 336310, 
+    336320, 336327, 336335, 336343, 336352, 336360, 336369, 336378, 
+    336388, 336396, 336405, 336414, 336424, 336433, 336443, 336453, 
+    336464, 336471, 336479, 336487, 336496, 336504, 336513, 336522, 
+    336532, 336540, 336549, 336558, 336568, 336577, 336587, 336597, 
+    336608, 336616, 336625, 336634, 336644, 336653, 336663, 336673, 
+    336684, 336693, 336703, 336713, 336724, 336734, 336745, 336756, 
+    336768, 336775, 336783, 336791, 336800, 336808, 336817, 336826, 
+    336836, 336844, 336853, 336862, 336872, 336881, 336891, 336901, 
+    336912, 336920, 336929, 336938, 336948, 336957, 336967, 336977, 
+    336988, 336997, 337007, 337017, 337028, 337038, 337049, 337060, 
+    337072, 337080, 337089, 337098, 337108, 337117, 337127, 337137, 
+    337148, 337157, 337167, 337177, 337188, 337198, 337209, 337220, 
+    337232, 337241, 337251, 337261, 337272, 337282, 337293, 337304, 
+    337316, 337326, 337337, 337348, 337360, 337371, 337383, 337395, 
+    337408, 337414, 337421, 337428, 337436, 337443, 337451, 337459, 
+    337468, 337475, 337483, 337491, 337500, 337508, 337517, 337526, 
+    337536, 337543, 337551, 337559, 337568, 337576, 337585, 337594, 
+    337604, 337612, 337621, 337630, 337640, 337649, 337659, 337669, 
+    337680, 337687, 337695, 337703, 337712, 337720, 337729, 337738, 
+    337748, 337756, 337765, 337774, 337784, 337793, 337803, 337813, 
+    337824, 337832, 337841, 337850, 337860, 337869, 337879, 337889, 
+    337900, 337909, 337919, 337929, 337940, 337950, 337961, 337972, 
+    337984, 337991, 337999, 338007, 338016, 338024, 338033, 338042, 
+    338052, 338060, 338069, 338078, 338088, 338097, 338107, 338117, 
+    338128, 338136, 338145, 338154, 338164, 338173, 338183, 338193, 
+    338204, 338213, 338223, 338233, 338244, 338254, 338265, 338276, 
+    338288, 338296, 338305, 338314, 338324, 338333, 338343, 338353, 
+    338364, 338373, 338383, 338393, 338404, 338414, 338425, 338436, 
+    338448, 338457, 338467, 338477, 338488, 338498, 338509, 338520, 
+    338532, 338542, 338553, 338564, 338576, 338587, 338599, 338611, 
+    338624, 338631, 338639, 338647, 338656, 338664, 338673, 338682, 
+    338692, 338700, 338709, 338718, 338728, 338737, 338747, 338757, 
+    338768, 338776, 338785, 338794, 338804, 338813, 338823, 338833, 
+    338844, 338853, 338863, 338873, 338884, 338894, 338905, 338916, 
+    338928, 338936, 338945, 338954, 338964, 338973, 338983, 338993, 
+    339004, 339013, 339023, 339033, 339044, 339054, 339065, 339076, 
+    339088, 339097, 339107, 339117, 339128, 339138, 339149, 339160, 
+    339172, 339182, 339193, 339204, 339216, 339227, 339239, 339251, 
+    339264, 339272, 339281, 339290, 339300, 339309, 339319, 339329, 
+    339340, 339349, 339359, 339369, 339380, 339390, 339401, 339412, 
+    339424, 339433, 339443, 339453, 339464, 339474, 339485, 339496, 
+    339508, 339518, 339529, 339540, 339552, 339563, 339575, 339587, 
+    339600, 339609, 339619, 339629, 339640, 339650, 339661, 339672, 
+    339684, 339694, 339705, 339716, 339728, 339739, 339751, 339763, 
+    339776, 339786, 339797, 339808, 339820, 339831, 339843, 339855, 
+    339868, 339879, 339891, 339903, 339916, 339928, 339941, 339954, 
+    339968, 339971, 339975, 339979, 339984, 339988, 339993, 339998, 
+    340004, 340008, 340013, 340018, 340024, 340029, 340035, 340041, 
+    340048, 340052, 340057, 340062, 340068, 340073, 340079, 340085, 
+    340092, 340097, 340103, 340109, 340116, 340122, 340129, 340136, 
+    340144, 340148, 340153, 340158, 340164, 340169, 340175, 340181, 
+    340188, 340193, 340199, 340205, 340212, 340218, 340225, 340232, 
+    340240, 340245, 340251, 340257, 340264, 340270, 340277, 340284, 
+    340292, 340298, 340305, 340312, 340320, 340327, 340335, 340343, 
+    340352, 340356, 340361, 340366, 340372, 340377, 340383, 340389, 
+    340396, 340401, 340407, 340413, 340420, 340426, 340433, 340440, 
+    340448, 340453, 340459, 340465, 340472, 340478, 340485, 340492, 
+    340500, 340506, 340513, 340520, 340528, 340535, 340543, 340551, 
+    340560, 340565, 340571, 340577, 340584, 340590, 340597, 340604, 
+    340612, 340618, 340625, 340632, 340640, 340647, 340655, 340663, 
+    340672, 340678, 340685, 340692, 340700, 340707, 340715, 340723, 
+    340732, 340739, 340747, 340755, 340764, 340772, 340781, 340790, 
+    340800, 340804, 340809, 340814, 340820, 340825, 340831, 340837, 
+    340844, 340849, 340855, 340861, 340868, 340874, 340881, 340888, 
+    340896, 340901, 340907, 340913, 340920, 340926, 340933, 340940, 
+    340948, 340954, 340961, 340968, 340976, 340983, 340991, 340999, 
+    341008, 341013, 341019, 341025, 341032, 341038, 341045, 341052, 
+    341060, 341066, 341073, 341080, 341088, 341095, 341103, 341111, 
+    341120, 341126, 341133, 341140, 341148, 341155, 341163, 341171, 
+    341180, 341187, 341195, 341203, 341212, 341220, 341229, 341238, 
+    341248, 341253, 341259, 341265, 341272, 341278, 341285, 341292, 
+    341300, 341306, 341313, 341320, 341328, 341335, 341343, 341351, 
+    341360, 341366, 341373, 341380, 341388, 341395, 341403, 341411, 
+    341420, 341427, 341435, 341443, 341452, 341460, 341469, 341478, 
+    341488, 341494, 341501, 341508, 341516, 341523, 341531, 341539, 
+    341548, 341555, 341563, 341571, 341580, 341588, 341597, 341606, 
+    341616, 341623, 341631, 341639, 341648, 341656, 341665, 341674, 
+    341684, 341692, 341701, 341710, 341720, 341729, 341739, 341749, 
+    341760, 341764, 341769, 341774, 341780, 341785, 341791, 341797, 
+    341804, 341809, 341815, 341821, 341828, 341834, 341841, 341848, 
+    341856, 341861, 341867, 341873, 341880, 341886, 341893, 341900, 
+    341908, 341914, 341921, 341928, 341936, 341943, 341951, 341959, 
+    341968, 341973, 341979, 341985, 341992, 341998, 342005, 342012, 
+    342020, 342026, 342033, 342040, 342048, 342055, 342063, 342071, 
+    342080, 342086, 342093, 342100, 342108, 342115, 342123, 342131, 
+    342140, 342147, 342155, 342163, 342172, 342180, 342189, 342198, 
+    342208, 342213, 342219, 342225, 342232, 342238, 342245, 342252, 
+    342260, 342266, 342273, 342280, 342288, 342295, 342303, 342311, 
+    342320, 342326, 342333, 342340, 342348, 342355, 342363, 342371, 
+    342380, 342387, 342395, 342403, 342412, 342420, 342429, 342438, 
+    342448, 342454, 342461, 342468, 342476, 342483, 342491, 342499, 
+    342508, 342515, 342523, 342531, 342540, 342548, 342557, 342566, 
+    342576, 342583, 342591, 342599, 342608, 342616, 342625, 342634, 
+    342644, 342652, 342661, 342670, 342680, 342689, 342699, 342709, 
+    342720, 342725, 342731, 342737, 342744, 342750, 342757, 342764, 
+    342772, 342778, 342785, 342792, 342800, 342807, 342815, 342823, 
+    342832, 342838, 342845, 342852, 342860, 342867, 342875, 342883, 
+    342892, 342899, 342907, 342915, 342924, 342932, 342941, 342950, 
+    342960, 342966, 342973, 342980, 342988, 342995, 343003, 343011, 
+    343020, 343027, 343035, 343043, 343052, 343060, 343069, 343078, 
+    343088, 343095, 343103, 343111, 343120, 343128, 343137, 343146, 
+    343156, 343164, 343173, 343182, 343192, 343201, 343211, 343221, 
+    343232, 343238, 343245, 343252, 343260, 343267, 343275, 343283, 
+    343292, 343299, 343307, 343315, 343324, 343332, 343341, 343350, 
+    343360, 343367, 343375, 343383, 343392, 343400, 343409, 343418, 
+    343428, 343436, 343445, 343454, 343464, 343473, 343483, 343493, 
+    343504, 343511, 343519, 343527, 343536, 343544, 343553, 343562, 
+    343572, 343580, 343589, 343598, 343608, 343617, 343627, 343637, 
+    343648, 343656, 343665, 343674, 343684, 343693, 343703, 343713, 
+    343724, 343733, 343743, 343753, 343764, 343774, 343785, 343796, 
+    343808, 343812, 343817, 343822, 343828, 343833, 343839, 343845, 
+    343852, 343857, 343863, 343869, 343876, 343882, 343889, 343896, 
+    343904, 343909, 343915, 343921, 343928, 343934, 343941, 343948, 
+    343956, 343962, 343969, 343976, 343984, 343991, 343999, 344007, 
+    344016, 344021, 344027, 344033, 344040, 344046, 344053, 344060, 
+    344068, 344074, 344081, 344088, 344096, 344103, 344111, 344119, 
+    344128, 344134, 344141, 344148, 344156, 344163, 344171, 344179, 
+    344188, 344195, 344203, 344211, 344220, 344228, 344237, 344246, 
+    344256, 344261, 344267, 344273, 344280, 344286, 344293, 344300, 
+    344308, 344314, 344321, 344328, 344336, 344343, 344351, 344359, 
+    344368, 344374, 344381, 344388, 344396, 344403, 344411, 344419, 
+    344428, 344435, 344443, 344451, 344460, 344468, 344477, 344486, 
+    344496, 344502, 344509, 344516, 344524, 344531, 344539, 344547, 
+    344556, 344563, 344571, 344579, 344588, 344596, 344605, 344614, 
+    344624, 344631, 344639, 344647, 344656, 344664, 344673, 344682, 
+    344692, 344700, 344709, 344718, 344728, 344737, 344747, 344757, 
+    344768, 344773, 344779, 344785, 344792, 344798, 344805, 344812, 
+    344820, 344826, 344833, 344840, 344848, 344855, 344863, 344871, 
+    344880, 344886, 344893, 344900, 344908, 344915, 344923, 344931, 
+    344940, 344947, 344955, 344963, 344972, 344980, 344989, 344998, 
+    345008, 345014, 345021, 345028, 345036, 345043, 345051, 345059, 
+    345068, 345075, 345083, 345091, 345100, 345108, 345117, 345126, 
+    345136, 345143, 345151, 345159, 345168, 345176, 345185, 345194, 
+    345204, 345212, 345221, 345230, 345240, 345249, 345259, 345269, 
+    345280, 345286, 345293, 345300, 345308, 345315, 345323, 345331, 
+    345340, 345347, 345355, 345363, 345372, 345380, 345389, 345398, 
+    345408, 345415, 345423, 345431, 345440, 345448, 345457, 345466, 
+    345476, 345484, 345493, 345502, 345512, 345521, 345531, 345541, 
+    345552, 345559, 345567, 345575, 345584, 345592, 345601, 345610, 
+    345620, 345628, 345637, 345646, 345656, 345665, 345675, 345685, 
+    345696, 345704, 345713, 345722, 345732, 345741, 345751, 345761, 
+    345772, 345781, 345791, 345801, 345812, 345822, 345833, 345844, 
+    345856, 345861, 345867, 345873, 345880, 345886, 345893, 345900, 
+    345908, 345914, 345921, 345928, 345936, 345943, 345951, 345959, 
+    345968, 345974, 345981, 345988, 345996, 346003, 346011, 346019, 
+    346028, 346035, 346043, 346051, 346060, 346068, 346077, 346086, 
+    346096, 346102, 346109, 346116, 346124, 346131, 346139, 346147, 
+    346156, 346163, 346171, 346179, 346188, 346196, 346205, 346214, 
+    346224, 346231, 346239, 346247, 346256, 346264, 346273, 346282, 
+    346292, 346300, 346309, 346318, 346328, 346337, 346347, 346357, 
+    346368, 346374, 346381, 346388, 346396, 346403, 346411, 346419, 
+    346428, 346435, 346443, 346451, 346460, 346468, 346477, 346486, 
+    346496, 346503, 346511, 346519, 346528, 346536, 346545, 346554, 
+    346564, 346572, 346581, 346590, 346600, 346609, 346619, 346629, 
+    346640, 346647, 346655, 346663, 346672, 346680, 346689, 346698, 
+    346708, 346716, 346725, 346734, 346744, 346753, 346763, 346773, 
+    346784, 346792, 346801, 346810, 346820, 346829, 346839, 346849, 
+    346860, 346869, 346879, 346889, 346900, 346910, 346921, 346932, 
+    346944, 346950, 346957, 346964, 346972, 346979, 346987, 346995, 
+    347004, 347011, 347019, 347027, 347036, 347044, 347053, 347062, 
+    347072, 347079, 347087, 347095, 347104, 347112, 347121, 347130, 
+    347140, 347148, 347157, 347166, 347176, 347185, 347195, 347205, 
+    347216, 347223, 347231, 347239, 347248, 347256, 347265, 347274, 
+    347284, 347292, 347301, 347310, 347320, 347329, 347339, 347349, 
+    347360, 347368, 347377, 347386, 347396, 347405, 347415, 347425, 
+    347436, 347445, 347455, 347465, 347476, 347486, 347497, 347508, 
+    347520, 347527, 347535, 347543, 347552, 347560, 347569, 347578, 
+    347588, 347596, 347605, 347614, 347624, 347633, 347643, 347653, 
+    347664, 347672, 347681, 347690, 347700, 347709, 347719, 347729, 
+    347740, 347749, 347759, 347769, 347780, 347790, 347801, 347812, 
+    347824, 347832, 347841, 347850, 347860, 347869, 347879, 347889, 
+    347900, 347909, 347919, 347929, 347940, 347950, 347961, 347972, 
+    347984, 347993, 348003, 348013, 348024, 348034, 348045, 348056, 
+    348068, 348078, 348089, 348100, 348112, 348123, 348135, 348147, 
+    348160, 348164, 348169, 348174, 348180, 348185, 348191, 348197, 
+    348204, 348209, 348215, 348221, 348228, 348234, 348241, 348248, 
+    348256, 348261, 348267, 348273, 348280, 348286, 348293, 348300, 
+    348308, 348314, 348321, 348328, 348336, 348343, 348351, 348359, 
+    348368, 348373, 348379, 348385, 348392, 348398, 348405, 348412, 
+    348420, 348426, 348433, 348440, 348448, 348455, 348463, 348471, 
+    348480, 348486, 348493, 348500, 348508, 348515, 348523, 348531, 
+    348540, 348547, 348555, 348563, 348572, 348580, 348589, 348598, 
+    348608, 348613, 348619, 348625, 348632, 348638, 348645, 348652, 
+    348660, 348666, 348673, 348680, 348688, 348695, 348703, 348711, 
+    348720, 348726, 348733, 348740, 348748, 348755, 348763, 348771, 
+    348780, 348787, 348795, 348803, 348812, 348820, 348829, 348838, 
+    348848, 348854, 348861, 348868, 348876, 348883, 348891, 348899, 
+    348908, 348915, 348923, 348931, 348940, 348948, 348957, 348966, 
+    348976, 348983, 348991, 348999, 349008, 349016, 349025, 349034, 
+    349044, 349052, 349061, 349070, 349080, 349089, 349099, 349109, 
+    349120, 349125, 349131, 349137, 349144, 349150, 349157, 349164, 
+    349172, 349178, 349185, 349192, 349200, 349207, 349215, 349223, 
+    349232, 349238, 349245, 349252, 349260, 349267, 349275, 349283, 
+    349292, 349299, 349307, 349315, 349324, 349332, 349341, 349350, 
+    349360, 349366, 349373, 349380, 349388, 349395, 349403, 349411, 
+    349420, 349427, 349435, 349443, 349452, 349460, 349469, 349478, 
+    349488, 349495, 349503, 349511, 349520, 349528, 349537, 349546, 
+    349556, 349564, 349573, 349582, 349592, 349601, 349611, 349621, 
+    349632, 349638, 349645, 349652, 349660, 349667, 349675, 349683, 
+    349692, 349699, 349707, 349715, 349724, 349732, 349741, 349750, 
+    349760, 349767, 349775, 349783, 349792, 349800, 349809, 349818, 
+    349828, 349836, 349845, 349854, 349864, 349873, 349883, 349893, 
+    349904, 349911, 349919, 349927, 349936, 349944, 349953, 349962, 
+    349972, 349980, 349989, 349998, 350008, 350017, 350027, 350037, 
+    350048, 350056, 350065, 350074, 350084, 350093, 350103, 350113, 
+    350124, 350133, 350143, 350153, 350164, 350174, 350185, 350196, 
+    350208, 350213, 350219, 350225, 350232, 350238, 350245, 350252, 
+    350260, 350266, 350273, 350280, 350288, 350295, 350303, 350311, 
+    350320, 350326, 350333, 350340, 350348, 350355, 350363, 350371, 
+    350380, 350387, 350395, 350403, 350412, 350420, 350429, 350438, 
+    350448, 350454, 350461, 350468, 350476, 350483, 350491, 350499, 
+    350508, 350515, 350523, 350531, 350540, 350548, 350557, 350566, 
+    350576, 350583, 350591, 350599, 350608, 350616, 350625, 350634, 
+    350644, 350652, 350661, 350670, 350680, 350689, 350699, 350709, 
+    350720, 350726, 350733, 350740, 350748, 350755, 350763, 350771, 
+    350780, 350787, 350795, 350803, 350812, 350820, 350829, 350838, 
+    350848, 350855, 350863, 350871, 350880, 350888, 350897, 350906, 
+    350916, 350924, 350933, 350942, 350952, 350961, 350971, 350981, 
+    350992, 350999, 351007, 351015, 351024, 351032, 351041, 351050, 
+    351060, 351068, 351077, 351086, 351096, 351105, 351115, 351125, 
+    351136, 351144, 351153, 351162, 351172, 351181, 351191, 351201, 
+    351212, 351221, 351231, 351241, 351252, 351262, 351273, 351284, 
+    351296, 351302, 351309, 351316, 351324, 351331, 351339, 351347, 
+    351356, 351363, 351371, 351379, 351388, 351396, 351405, 351414, 
+    351424, 351431, 351439, 351447, 351456, 351464, 351473, 351482, 
+    351492, 351500, 351509, 351518, 351528, 351537, 351547, 351557, 
+    351568, 351575, 351583, 351591, 351600, 351608, 351617, 351626, 
+    351636, 351644, 351653, 351662, 351672, 351681, 351691, 351701, 
+    351712, 351720, 351729, 351738, 351748, 351757, 351767, 351777, 
+    351788, 351797, 351807, 351817, 351828, 351838, 351849, 351860, 
+    351872, 351879, 351887, 351895, 351904, 351912, 351921, 351930, 
+    351940, 351948, 351957, 351966, 351976, 351985, 351995, 352005, 
+    352016, 352024, 352033, 352042, 352052, 352061, 352071, 352081, 
+    352092, 352101, 352111, 352121, 352132, 352142, 352153, 352164, 
+    352176, 352184, 352193, 352202, 352212, 352221, 352231, 352241, 
+    352252, 352261, 352271, 352281, 352292, 352302, 352313, 352324, 
+    352336, 352345, 352355, 352365, 352376, 352386, 352397, 352408, 
+    352420, 352430, 352441, 352452, 352464, 352475, 352487, 352499, 
+    352512, 352517, 352523, 352529, 352536, 352542, 352549, 352556, 
+    352564, 352570, 352577, 352584, 352592, 352599, 352607, 352615, 
+    352624, 352630, 352637, 352644, 352652, 352659, 352667, 352675, 
+    352684, 352691, 352699, 352707, 352716, 352724, 352733, 352742, 
+    352752, 352758, 352765, 352772, 352780, 352787, 352795, 352803, 
+    352812, 352819, 352827, 352835, 352844, 352852, 352861, 352870, 
+    352880, 352887, 352895, 352903, 352912, 352920, 352929, 352938, 
+    352948, 352956, 352965, 352974, 352984, 352993, 353003, 353013, 
+    353024, 353030, 353037, 353044, 353052, 353059, 353067, 353075, 
+    353084, 353091, 353099, 353107, 353116, 353124, 353133, 353142, 
+    353152, 353159, 353167, 353175, 353184, 353192, 353201, 353210, 
+    353220, 353228, 353237, 353246, 353256, 353265, 353275, 353285, 
+    353296, 353303, 353311, 353319, 353328, 353336, 353345, 353354, 
+    353364, 353372, 353381, 353390, 353400, 353409, 353419, 353429, 
+    353440, 353448, 353457, 353466, 353476, 353485, 353495, 353505, 
+    353516, 353525, 353535, 353545, 353556, 353566, 353577, 353588, 
+    353600, 353606, 353613, 353620, 353628, 353635, 353643, 353651, 
+    353660, 353667, 353675, 353683, 353692, 353700, 353709, 353718, 
+    353728, 353735, 353743, 353751, 353760, 353768, 353777, 353786, 
+    353796, 353804, 353813, 353822, 353832, 353841, 353851, 353861, 
+    353872, 353879, 353887, 353895, 353904, 353912, 353921, 353930, 
+    353940, 353948, 353957, 353966, 353976, 353985, 353995, 354005, 
+    354016, 354024, 354033, 354042, 354052, 354061, 354071, 354081, 
+    354092, 354101, 354111, 354121, 354132, 354142, 354153, 354164, 
+    354176, 354183, 354191, 354199, 354208, 354216, 354225, 354234, 
+    354244, 354252, 354261, 354270, 354280, 354289, 354299, 354309, 
+    354320, 354328, 354337, 354346, 354356, 354365, 354375, 354385, 
+    354396, 354405, 354415, 354425, 354436, 354446, 354457, 354468, 
+    354480, 354488, 354497, 354506, 354516, 354525, 354535, 354545, 
+    354556, 354565, 354575, 354585, 354596, 354606, 354617, 354628, 
+    354640, 354649, 354659, 354669, 354680, 354690, 354701, 354712, 
+    354724, 354734, 354745, 354756, 354768, 354779, 354791, 354803, 
+    354816, 354822, 354829, 354836, 354844, 354851, 354859, 354867, 
+    354876, 354883, 354891, 354899, 354908, 354916, 354925, 354934, 
+    354944, 354951, 354959, 354967, 354976, 354984, 354993, 355002, 
+    355012, 355020, 355029, 355038, 355048, 355057, 355067, 355077, 
+    355088, 355095, 355103, 355111, 355120, 355128, 355137, 355146, 
+    355156, 355164, 355173, 355182, 355192, 355201, 355211, 355221, 
+    355232, 355240, 355249, 355258, 355268, 355277, 355287, 355297, 
+    355308, 355317, 355327, 355337, 355348, 355358, 355369, 355380, 
+    355392, 355399, 355407, 355415, 355424, 355432, 355441, 355450, 
+    355460, 355468, 355477, 355486, 355496, 355505, 355515, 355525, 
+    355536, 355544, 355553, 355562, 355572, 355581, 355591, 355601, 
+    355612, 355621, 355631, 355641, 355652, 355662, 355673, 355684, 
+    355696, 355704, 355713, 355722, 355732, 355741, 355751, 355761, 
+    355772, 355781, 355791, 355801, 355812, 355822, 355833, 355844, 
+    355856, 355865, 355875, 355885, 355896, 355906, 355917, 355928, 
+    355940, 355950, 355961, 355972, 355984, 355995, 356007, 356019, 
+    356032, 356039, 356047, 356055, 356064, 356072, 356081, 356090, 
+    356100, 356108, 356117, 356126, 356136, 356145, 356155, 356165, 
+    356176, 356184, 356193, 356202, 356212, 356221, 356231, 356241, 
+    356252, 356261, 356271, 356281, 356292, 356302, 356313, 356324, 
+    356336, 356344, 356353, 356362, 356372, 356381, 356391, 356401, 
+    356412, 356421, 356431, 356441, 356452, 356462, 356473, 356484, 
+    356496, 356505, 356515, 356525, 356536, 356546, 356557, 356568, 
+    356580, 356590, 356601, 356612, 356624, 356635, 356647, 356659, 
+    356672, 356680, 356689, 356698, 356708, 356717, 356727, 356737, 
+    356748, 356757, 356767, 356777, 356788, 356798, 356809, 356820, 
+    356832, 356841, 356851, 356861, 356872, 356882, 356893, 356904, 
+    356916, 356926, 356937, 356948, 356960, 356971, 356983, 356995, 
+    357008, 357017, 357027, 357037, 357048, 357058, 357069, 357080, 
+    357092, 357102, 357113, 357124, 357136, 357147, 357159, 357171, 
+    357184, 357194, 357205, 357216, 357228, 357239, 357251, 357263, 
+    357276, 357287, 357299, 357311, 357324, 357336, 357349, 357362, 
+    357376, 357380, 357385, 357390, 357396, 357401, 357407, 357413, 
+    357420, 357425, 357431, 357437, 357444, 357450, 357457, 357464, 
+    357472, 357477, 357483, 357489, 357496, 357502, 357509, 357516, 
+    357524, 357530, 357537, 357544, 357552, 357559, 357567, 357575, 
+    357584, 357589, 357595, 357601, 357608, 357614, 357621, 357628, 
+    357636, 357642, 357649, 357656, 357664, 357671, 357679, 357687, 
+    357696, 357702, 357709, 357716, 357724, 357731, 357739, 357747, 
+    357756, 357763, 357771, 357779, 357788, 357796, 357805, 357814, 
+    357824, 357829, 357835, 357841, 357848, 357854, 357861, 357868, 
+    357876, 357882, 357889, 357896, 357904, 357911, 357919, 357927, 
+    357936, 357942, 357949, 357956, 357964, 357971, 357979, 357987, 
+    357996, 358003, 358011, 358019, 358028, 358036, 358045, 358054, 
+    358064, 358070, 358077, 358084, 358092, 358099, 358107, 358115, 
+    358124, 358131, 358139, 358147, 358156, 358164, 358173, 358182, 
+    358192, 358199, 358207, 358215, 358224, 358232, 358241, 358250, 
+    358260, 358268, 358277, 358286, 358296, 358305, 358315, 358325, 
+    358336, 358341, 358347, 358353, 358360, 358366, 358373, 358380, 
+    358388, 358394, 358401, 358408, 358416, 358423, 358431, 358439, 
+    358448, 358454, 358461, 358468, 358476, 358483, 358491, 358499, 
+    358508, 358515, 358523, 358531, 358540, 358548, 358557, 358566, 
+    358576, 358582, 358589, 358596, 358604, 358611, 358619, 358627, 
+    358636, 358643, 358651, 358659, 358668, 358676, 358685, 358694, 
+    358704, 358711, 358719, 358727, 358736, 358744, 358753, 358762, 
+    358772, 358780, 358789, 358798, 358808, 358817, 358827, 358837, 
+    358848, 358854, 358861, 358868, 358876, 358883, 358891, 358899, 
+    358908, 358915, 358923, 358931, 358940, 358948, 358957, 358966, 
+    358976, 358983, 358991, 358999, 359008, 359016, 359025, 359034, 
+    359044, 359052, 359061, 359070, 359080, 359089, 359099, 359109, 
+    359120, 359127, 359135, 359143, 359152, 359160, 359169, 359178, 
+    359188, 359196, 359205, 359214, 359224, 359233, 359243, 359253, 
+    359264, 359272, 359281, 359290, 359300, 359309, 359319, 359329, 
+    359340, 359349, 359359, 359369, 359380, 359390, 359401, 359412, 
+    359424, 359429, 359435, 359441, 359448, 359454, 359461, 359468, 
+    359476, 359482, 359489, 359496, 359504, 359511, 359519, 359527, 
+    359536, 359542, 359549, 359556, 359564, 359571, 359579, 359587, 
+    359596, 359603, 359611, 359619, 359628, 359636, 359645, 359654, 
+    359664, 359670, 359677, 359684, 359692, 359699, 359707, 359715, 
+    359724, 359731, 359739, 359747, 359756, 359764, 359773, 359782, 
+    359792, 359799, 359807, 359815, 359824, 359832, 359841, 359850, 
+    359860, 359868, 359877, 359886, 359896, 359905, 359915, 359925, 
+    359936, 359942, 359949, 359956, 359964, 359971, 359979, 359987, 
+    359996, 360003, 360011, 360019, 360028, 360036, 360045, 360054, 
+    360064, 360071, 360079, 360087, 360096, 360104, 360113, 360122, 
+    360132, 360140, 360149, 360158, 360168, 360177, 360187, 360197, 
+    360208, 360215, 360223, 360231, 360240, 360248, 360257, 360266, 
+    360276, 360284, 360293, 360302, 360312, 360321, 360331, 360341, 
+    360352, 360360, 360369, 360378, 360388, 360397, 360407, 360417, 
+    360428, 360437, 360447, 360457, 360468, 360478, 360489, 360500, 
+    360512, 360518, 360525, 360532, 360540, 360547, 360555, 360563, 
+    360572, 360579, 360587, 360595, 360604, 360612, 360621, 360630, 
+    360640, 360647, 360655, 360663, 360672, 360680, 360689, 360698, 
+    360708, 360716, 360725, 360734, 360744, 360753, 360763, 360773, 
+    360784, 360791, 360799, 360807, 360816, 360824, 360833, 360842, 
+    360852, 360860, 360869, 360878, 360888, 360897, 360907, 360917, 
+    360928, 360936, 360945, 360954, 360964, 360973, 360983, 360993, 
+    361004, 361013, 361023, 361033, 361044, 361054, 361065, 361076, 
+    361088, 361095, 361103, 361111, 361120, 361128, 361137, 361146, 
+    361156, 361164, 361173, 361182, 361192, 361201, 361211, 361221, 
+    361232, 361240, 361249, 361258, 361268, 361277, 361287, 361297, 
+    361308, 361317, 361327, 361337, 361348, 361358, 361369, 361380, 
+    361392, 361400, 361409, 361418, 361428, 361437, 361447, 361457, 
+    361468, 361477, 361487, 361497, 361508, 361518, 361529, 361540, 
+    361552, 361561, 361571, 361581, 361592, 361602, 361613, 361624, 
+    361636, 361646, 361657, 361668, 361680, 361691, 361703, 361715, 
+    361728, 361733, 361739, 361745, 361752, 361758, 361765, 361772, 
+    361780, 361786, 361793, 361800, 361808, 361815, 361823, 361831, 
+    361840, 361846, 361853, 361860, 361868, 361875, 361883, 361891, 
+    361900, 361907, 361915, 361923, 361932, 361940, 361949, 361958, 
+    361968, 361974, 361981, 361988, 361996, 362003, 362011, 362019, 
+    362028, 362035, 362043, 362051, 362060, 362068, 362077, 362086, 
+    362096, 362103, 362111, 362119, 362128, 362136, 362145, 362154, 
+    362164, 362172, 362181, 362190, 362200, 362209, 362219, 362229, 
+    362240, 362246, 362253, 362260, 362268, 362275, 362283, 362291, 
+    362300, 362307, 362315, 362323, 362332, 362340, 362349, 362358, 
+    362368, 362375, 362383, 362391, 362400, 362408, 362417, 362426, 
+    362436, 362444, 362453, 362462, 362472, 362481, 362491, 362501, 
+    362512, 362519, 362527, 362535, 362544, 362552, 362561, 362570, 
+    362580, 362588, 362597, 362606, 362616, 362625, 362635, 362645, 
+    362656, 362664, 362673, 362682, 362692, 362701, 362711, 362721, 
+    362732, 362741, 362751, 362761, 362772, 362782, 362793, 362804, 
+    362816, 362822, 362829, 362836, 362844, 362851, 362859, 362867, 
+    362876, 362883, 362891, 362899, 362908, 362916, 362925, 362934, 
+    362944, 362951, 362959, 362967, 362976, 362984, 362993, 363002, 
+    363012, 363020, 363029, 363038, 363048, 363057, 363067, 363077, 
+    363088, 363095, 363103, 363111, 363120, 363128, 363137, 363146, 
+    363156, 363164, 363173, 363182, 363192, 363201, 363211, 363221, 
+    363232, 363240, 363249, 363258, 363268, 363277, 363287, 363297, 
+    363308, 363317, 363327, 363337, 363348, 363358, 363369, 363380, 
+    363392, 363399, 363407, 363415, 363424, 363432, 363441, 363450, 
+    363460, 363468, 363477, 363486, 363496, 363505, 363515, 363525, 
+    363536, 363544, 363553, 363562, 363572, 363581, 363591, 363601, 
+    363612, 363621, 363631, 363641, 363652, 363662, 363673, 363684, 
+    363696, 363704, 363713, 363722, 363732, 363741, 363751, 363761, 
+    363772, 363781, 363791, 363801, 363812, 363822, 363833, 363844, 
+    363856, 363865, 363875, 363885, 363896, 363906, 363917, 363928, 
+    363940, 363950, 363961, 363972, 363984, 363995, 364007, 364019, 
+    364032, 364038, 364045, 364052, 364060, 364067, 364075, 364083, 
+    364092, 364099, 364107, 364115, 364124, 364132, 364141, 364150, 
+    364160, 364167, 364175, 364183, 364192, 364200, 364209, 364218, 
+    364228, 364236, 364245, 364254, 364264, 364273, 364283, 364293, 
+    364304, 364311, 364319, 364327, 364336, 364344, 364353, 364362, 
+    364372, 364380, 364389, 364398, 364408, 364417, 364427, 364437, 
+    364448, 364456, 364465, 364474, 364484, 364493, 364503, 364513, 
+    364524, 364533, 364543, 364553, 364564, 364574, 364585, 364596, 
+    364608, 364615, 364623, 364631, 364640, 364648, 364657, 364666, 
+    364676, 364684, 364693, 364702, 364712, 364721, 364731, 364741, 
+    364752, 364760, 364769, 364778, 364788, 364797, 364807, 364817, 
+    364828, 364837, 364847, 364857, 364868, 364878, 364889, 364900, 
+    364912, 364920, 364929, 364938, 364948, 364957, 364967, 364977, 
+    364988, 364997, 365007, 365017, 365028, 365038, 365049, 365060, 
+    365072, 365081, 365091, 365101, 365112, 365122, 365133, 365144, 
+    365156, 365166, 365177, 365188, 365200, 365211, 365223, 365235, 
+    365248, 365255, 365263, 365271, 365280, 365288, 365297, 365306, 
+    365316, 365324, 365333, 365342, 365352, 365361, 365371, 365381, 
+    365392, 365400, 365409, 365418, 365428, 365437, 365447, 365457, 
+    365468, 365477, 365487, 365497, 365508, 365518, 365529, 365540, 
+    365552, 365560, 365569, 365578, 365588, 365597, 365607, 365617, 
+    365628, 365637, 365647, 365657, 365668, 365678, 365689, 365700, 
+    365712, 365721, 365731, 365741, 365752, 365762, 365773, 365784, 
+    365796, 365806, 365817, 365828, 365840, 365851, 365863, 365875, 
+    365888, 365896, 365905, 365914, 365924, 365933, 365943, 365953, 
+    365964, 365973, 365983, 365993, 366004, 366014, 366025, 366036, 
+    366048, 366057, 366067, 366077, 366088, 366098, 366109, 366120, 
+    366132, 366142, 366153, 366164, 366176, 366187, 366199, 366211, 
+    366224, 366233, 366243, 366253, 366264, 366274, 366285, 366296, 
+    366308, 366318, 366329, 366340, 366352, 366363, 366375, 366387, 
+    366400, 366410, 366421, 366432, 366444, 366455, 366467, 366479, 
+    366492, 366503, 366515, 366527, 366540, 366552, 366565, 366578, 
+    366592, 366597, 366603, 366609, 366616, 366622, 366629, 366636, 
+    366644, 366650, 366657, 366664, 366672, 366679, 366687, 366695, 
+    366704, 366710, 366717, 366724, 366732, 366739, 366747, 366755, 
+    366764, 366771, 366779, 366787, 366796, 366804, 366813, 366822, 
+    366832, 366838, 366845, 366852, 366860, 366867, 366875, 366883, 
+    366892, 366899, 366907, 366915, 366924, 366932, 366941, 366950, 
+    366960, 366967, 366975, 366983, 366992, 367000, 367009, 367018, 
+    367028, 367036, 367045, 367054, 367064, 367073, 367083, 367093, 
+    367104, 367110, 367117, 367124, 367132, 367139, 367147, 367155, 
+    367164, 367171, 367179, 367187, 367196, 367204, 367213, 367222, 
+    367232, 367239, 367247, 367255, 367264, 367272, 367281, 367290, 
+    367300, 367308, 367317, 367326, 367336, 367345, 367355, 367365, 
+    367376, 367383, 367391, 367399, 367408, 367416, 367425, 367434, 
+    367444, 367452, 367461, 367470, 367480, 367489, 367499, 367509, 
+    367520, 367528, 367537, 367546, 367556, 367565, 367575, 367585, 
+    367596, 367605, 367615, 367625, 367636, 367646, 367657, 367668, 
+    367680, 367686, 367693, 367700, 367708, 367715, 367723, 367731, 
+    367740, 367747, 367755, 367763, 367772, 367780, 367789, 367798, 
+    367808, 367815, 367823, 367831, 367840, 367848, 367857, 367866, 
+    367876, 367884, 367893, 367902, 367912, 367921, 367931, 367941, 
+    367952, 367959, 367967, 367975, 367984, 367992, 368001, 368010, 
+    368020, 368028, 368037, 368046, 368056, 368065, 368075, 368085, 
+    368096, 368104, 368113, 368122, 368132, 368141, 368151, 368161, 
+    368172, 368181, 368191, 368201, 368212, 368222, 368233, 368244, 
+    368256, 368263, 368271, 368279, 368288, 368296, 368305, 368314, 
+    368324, 368332, 368341, 368350, 368360, 368369, 368379, 368389, 
+    368400, 368408, 368417, 368426, 368436, 368445, 368455, 368465, 
+    368476, 368485, 368495, 368505, 368516, 368526, 368537, 368548, 
+    368560, 368568, 368577, 368586, 368596, 368605, 368615, 368625, 
+    368636, 368645, 368655, 368665, 368676, 368686, 368697, 368708, 
+    368720, 368729, 368739, 368749, 368760, 368770, 368781, 368792, 
+    368804, 368814, 368825, 368836, 368848, 368859, 368871, 368883, 
+    368896, 368902, 368909, 368916, 368924, 368931, 368939, 368947, 
+    368956, 368963, 368971, 368979, 368988, 368996, 369005, 369014, 
+    369024, 369031, 369039, 369047, 369056, 369064, 369073, 369082, 
+    369092, 369100, 369109, 369118, 369128, 369137, 369147, 369157, 
+    369168, 369175, 369183, 369191, 369200, 369208, 369217, 369226, 
+    369236, 369244, 369253, 369262, 369272, 369281, 369291, 369301, 
+    369312, 369320, 369329, 369338, 369348, 369357, 369367, 369377, 
+    369388, 369397, 369407, 369417, 369428, 369438, 369449, 369460, 
+    369472, 369479, 369487, 369495, 369504, 369512, 369521, 369530, 
+    369540, 369548, 369557, 369566, 369576, 369585, 369595, 369605, 
+    369616, 369624, 369633, 369642, 369652, 369661, 369671, 369681, 
+    369692, 369701, 369711, 369721, 369732, 369742, 369753, 369764, 
+    369776, 369784, 369793, 369802, 369812, 369821, 369831, 369841, 
+    369852, 369861, 369871, 369881, 369892, 369902, 369913, 369924, 
+    369936, 369945, 369955, 369965, 369976, 369986, 369997, 370008, 
+    370020, 370030, 370041, 370052, 370064, 370075, 370087, 370099, 
+    370112, 370119, 370127, 370135, 370144, 370152, 370161, 370170, 
+    370180, 370188, 370197, 370206, 370216, 370225, 370235, 370245, 
+    370256, 370264, 370273, 370282, 370292, 370301, 370311, 370321, 
+    370332, 370341, 370351, 370361, 370372, 370382, 370393, 370404, 
+    370416, 370424, 370433, 370442, 370452, 370461, 370471, 370481, 
+    370492, 370501, 370511, 370521, 370532, 370542, 370553, 370564, 
+    370576, 370585, 370595, 370605, 370616, 370626, 370637, 370648, 
+    370660, 370670, 370681, 370692, 370704, 370715, 370727, 370739, 
+    370752, 370760, 370769, 370778, 370788, 370797, 370807, 370817, 
+    370828, 370837, 370847, 370857, 370868, 370878, 370889, 370900, 
+    370912, 370921, 370931, 370941, 370952, 370962, 370973, 370984, 
+    370996, 371006, 371017, 371028, 371040, 371051, 371063, 371075, 
+    371088, 371097, 371107, 371117, 371128, 371138, 371149, 371160, 
+    371172, 371182, 371193, 371204, 371216, 371227, 371239, 371251, 
+    371264, 371274, 371285, 371296, 371308, 371319, 371331, 371343, 
+    371356, 371367, 371379, 371391, 371404, 371416, 371429, 371442, 
+    371456, 371462, 371469, 371476, 371484, 371491, 371499, 371507, 
+    371516, 371523, 371531, 371539, 371548, 371556, 371565, 371574, 
+    371584, 371591, 371599, 371607, 371616, 371624, 371633, 371642, 
+    371652, 371660, 371669, 371678, 371688, 371697, 371707, 371717, 
+    371728, 371735, 371743, 371751, 371760, 371768, 371777, 371786, 
+    371796, 371804, 371813, 371822, 371832, 371841, 371851, 371861, 
+    371872, 371880, 371889, 371898, 371908, 371917, 371927, 371937, 
+    371948, 371957, 371967, 371977, 371988, 371998, 372009, 372020, 
+    372032, 372039, 372047, 372055, 372064, 372072, 372081, 372090, 
+    372100, 372108, 372117, 372126, 372136, 372145, 372155, 372165, 
+    372176, 372184, 372193, 372202, 372212, 372221, 372231, 372241, 
+    372252, 372261, 372271, 372281, 372292, 372302, 372313, 372324, 
+    372336, 372344, 372353, 372362, 372372, 372381, 372391, 372401, 
+    372412, 372421, 372431, 372441, 372452, 372462, 372473, 372484, 
+    372496, 372505, 372515, 372525, 372536, 372546, 372557, 372568, 
+    372580, 372590, 372601, 372612, 372624, 372635, 372647, 372659, 
+    372672, 372679, 372687, 372695, 372704, 372712, 372721, 372730, 
+    372740, 372748, 372757, 372766, 372776, 372785, 372795, 372805, 
+    372816, 372824, 372833, 372842, 372852, 372861, 372871, 372881, 
+    372892, 372901, 372911, 372921, 372932, 372942, 372953, 372964, 
+    372976, 372984, 372993, 373002, 373012, 373021, 373031, 373041, 
+    373052, 373061, 373071, 373081, 373092, 373102, 373113, 373124, 
+    373136, 373145, 373155, 373165, 373176, 373186, 373197, 373208, 
+    373220, 373230, 373241, 373252, 373264, 373275, 373287, 373299, 
+    373312, 373320, 373329, 373338, 373348, 373357, 373367, 373377, 
+    373388, 373397, 373407, 373417, 373428, 373438, 373449, 373460, 
+    373472, 373481, 373491, 373501, 373512, 373522, 373533, 373544, 
+    373556, 373566, 373577, 373588, 373600, 373611, 373623, 373635, 
+    373648, 373657, 373667, 373677, 373688, 373698, 373709, 373720, 
+    373732, 373742, 373753, 373764, 373776, 373787, 373799, 373811, 
+    373824, 373834, 373845, 373856, 373868, 373879, 373891, 373903, 
+    373916, 373927, 373939, 373951, 373964, 373976, 373989, 374002, 
+    374016, 374023, 374031, 374039, 374048, 374056, 374065, 374074, 
+    374084, 374092, 374101, 374110, 374120, 374129, 374139, 374149, 
+    374160, 374168, 374177, 374186, 374196, 374205, 374215, 374225, 
+    374236, 374245, 374255, 374265, 374276, 374286, 374297, 374308, 
+    374320, 374328, 374337, 374346, 374356, 374365, 374375, 374385, 
+    374396, 374405, 374415, 374425, 374436, 374446, 374457, 374468, 
+    374480, 374489, 374499, 374509, 374520, 374530, 374541, 374552, 
+    374564, 374574, 374585, 374596, 374608, 374619, 374631, 374643, 
+    374656, 374664, 374673, 374682, 374692, 374701, 374711, 374721, 
+    374732, 374741, 374751, 374761, 374772, 374782, 374793, 374804, 
+    374816, 374825, 374835, 374845, 374856, 374866, 374877, 374888, 
+    374900, 374910, 374921, 374932, 374944, 374955, 374967, 374979, 
+    374992, 375001, 375011, 375021, 375032, 375042, 375053, 375064, 
+    375076, 375086, 375097, 375108, 375120, 375131, 375143, 375155, 
+    375168, 375178, 375189, 375200, 375212, 375223, 375235, 375247, 
+    375260, 375271, 375283, 375295, 375308, 375320, 375333, 375346, 
+    375360, 375368, 375377, 375386, 375396, 375405, 375415, 375425, 
+    375436, 375445, 375455, 375465, 375476, 375486, 375497, 375508, 
+    375520, 375529, 375539, 375549, 375560, 375570, 375581, 375592, 
+    375604, 375614, 375625, 375636, 375648, 375659, 375671, 375683, 
+    375696, 375705, 375715, 375725, 375736, 375746, 375757, 375768, 
+    375780, 375790, 375801, 375812, 375824, 375835, 375847, 375859, 
+    375872, 375882, 375893, 375904, 375916, 375927, 375939, 375951, 
+    375964, 375975, 375987, 375999, 376012, 376024, 376037, 376050, 
+    376064, 376073, 376083, 376093, 376104, 376114, 376125, 376136, 
+    376148, 376158, 376169, 376180, 376192, 376203, 376215, 376227, 
+    376240, 376250, 376261, 376272, 376284, 376295, 376307, 376319, 
+    376332, 376343, 376355, 376367, 376380, 376392, 376405, 376418, 
+    376432, 376442, 376453, 376464, 376476, 376487, 376499, 376511, 
+    376524, 376535, 376547, 376559, 376572, 376584, 376597, 376610, 
+    376624, 376635, 376647, 376659, 376672, 376684, 376697, 376710, 
+    376724, 376736, 376749, 376762, 376776, 376789, 376803, 376817, 
+    376832, 376834, 376837, 376840, 376844, 376847, 376851, 376855, 
+    376860, 376863, 376867, 376871, 376876, 376880, 376885, 376890, 
+    376896, 376899, 376903, 376907, 376912, 376916, 376921, 376926, 
+    376932, 376936, 376941, 376946, 376952, 376957, 376963, 376969, 
+    376976, 376979, 376983, 376987, 376992, 376996, 377001, 377006, 
+    377012, 377016, 377021, 377026, 377032, 377037, 377043, 377049, 
+    377056, 377060, 377065, 377070, 377076, 377081, 377087, 377093, 
+    377100, 377105, 377111, 377117, 377124, 377130, 377137, 377144, 
+    377152, 377155, 377159, 377163, 377168, 377172, 377177, 377182, 
+    377188, 377192, 377197, 377202, 377208, 377213, 377219, 377225, 
+    377232, 377236, 377241, 377246, 377252, 377257, 377263, 377269, 
+    377276, 377281, 377287, 377293, 377300, 377306, 377313, 377320, 
+    377328, 377332, 377337, 377342, 377348, 377353, 377359, 377365, 
+    377372, 377377, 377383, 377389, 377396, 377402, 377409, 377416, 
+    377424, 377429, 377435, 377441, 377448, 377454, 377461, 377468, 
+    377476, 377482, 377489, 377496, 377504, 377511, 377519, 377527, 
+    377536, 377539, 377543, 377547, 377552, 377556, 377561, 377566, 
+    377572, 377576, 377581, 377586, 377592, 377597, 377603, 377609, 
+    377616, 377620, 377625, 377630, 377636, 377641, 377647, 377653, 
+    377660, 377665, 377671, 377677, 377684, 377690, 377697, 377704, 
+    377712, 377716, 377721, 377726, 377732, 377737, 377743, 377749, 
+    377756, 377761, 377767, 377773, 377780, 377786, 377793, 377800, 
+    377808, 377813, 377819, 377825, 377832, 377838, 377845, 377852, 
+    377860, 377866, 377873, 377880, 377888, 377895, 377903, 377911, 
+    377920, 377924, 377929, 377934, 377940, 377945, 377951, 377957, 
+    377964, 377969, 377975, 377981, 377988, 377994, 378001, 378008, 
+    378016, 378021, 378027, 378033, 378040, 378046, 378053, 378060, 
+    378068, 378074, 378081, 378088, 378096, 378103, 378111, 378119, 
+    378128, 378133, 378139, 378145, 378152, 378158, 378165, 378172, 
+    378180, 378186, 378193, 378200, 378208, 378215, 378223, 378231, 
+    378240, 378246, 378253, 378260, 378268, 378275, 378283, 378291, 
+    378300, 378307, 378315, 378323, 378332, 378340, 378349, 378358, 
+    378368, 378371, 378375, 378379, 378384, 378388, 378393, 378398, 
+    378404, 378408, 378413, 378418, 378424, 378429, 378435, 378441, 
+    378448, 378452, 378457, 378462, 378468, 378473, 378479, 378485, 
+    378492, 378497, 378503, 378509, 378516, 378522, 378529, 378536, 
+    378544, 378548, 378553, 378558, 378564, 378569, 378575, 378581, 
+    378588, 378593, 378599, 378605, 378612, 378618, 378625, 378632, 
+    378640, 378645, 378651, 378657, 378664, 378670, 378677, 378684, 
+    378692, 378698, 378705, 378712, 378720, 378727, 378735, 378743, 
+    378752, 378756, 378761, 378766, 378772, 378777, 378783, 378789, 
+    378796, 378801, 378807, 378813, 378820, 378826, 378833, 378840, 
+    378848, 378853, 378859, 378865, 378872, 378878, 378885, 378892, 
+    378900, 378906, 378913, 378920, 378928, 378935, 378943, 378951, 
+    378960, 378965, 378971, 378977, 378984, 378990, 378997, 379004, 
+    379012, 379018, 379025, 379032, 379040, 379047, 379055, 379063, 
+    379072, 379078, 379085, 379092, 379100, 379107, 379115, 379123, 
+    379132, 379139, 379147, 379155, 379164, 379172, 379181, 379190, 
+    379200, 379204, 379209, 379214, 379220, 379225, 379231, 379237, 
+    379244, 379249, 379255, 379261, 379268, 379274, 379281, 379288, 
+    379296, 379301, 379307, 379313, 379320, 379326, 379333, 379340, 
+    379348, 379354, 379361, 379368, 379376, 379383, 379391, 379399, 
+    379408, 379413, 379419, 379425, 379432, 379438, 379445, 379452, 
+    379460, 379466, 379473, 379480, 379488, 379495, 379503, 379511, 
+    379520, 379526, 379533, 379540, 379548, 379555, 379563, 379571, 
+    379580, 379587, 379595, 379603, 379612, 379620, 379629, 379638, 
+    379648, 379653, 379659, 379665, 379672, 379678, 379685, 379692, 
+    379700, 379706, 379713, 379720, 379728, 379735, 379743, 379751, 
+    379760, 379766, 379773, 379780, 379788, 379795, 379803, 379811, 
+    379820, 379827, 379835, 379843, 379852, 379860, 379869, 379878, 
+    379888, 379894, 379901, 379908, 379916, 379923, 379931, 379939, 
+    379948, 379955, 379963, 379971, 379980, 379988, 379997, 380006, 
+    380016, 380023, 380031, 380039, 380048, 380056, 380065, 380074, 
+    380084, 380092, 380101, 380110, 380120, 380129, 380139, 380149, 
+    380160, 380163, 380167, 380171, 380176, 380180, 380185, 380190, 
+    380196, 380200, 380205, 380210, 380216, 380221, 380227, 380233, 
+    380240, 380244, 380249, 380254, 380260, 380265, 380271, 380277, 
+    380284, 380289, 380295, 380301, 380308, 380314, 380321, 380328, 
+    380336, 380340, 380345, 380350, 380356, 380361, 380367, 380373, 
+    380380, 380385, 380391, 380397, 380404, 380410, 380417, 380424, 
+    380432, 380437, 380443, 380449, 380456, 380462, 380469, 380476, 
+    380484, 380490, 380497, 380504, 380512, 380519, 380527, 380535, 
+    380544, 380548, 380553, 380558, 380564, 380569, 380575, 380581, 
+    380588, 380593, 380599, 380605, 380612, 380618, 380625, 380632, 
+    380640, 380645, 380651, 380657, 380664, 380670, 380677, 380684, 
+    380692, 380698, 380705, 380712, 380720, 380727, 380735, 380743, 
+    380752, 380757, 380763, 380769, 380776, 380782, 380789, 380796, 
+    380804, 380810, 380817, 380824, 380832, 380839, 380847, 380855, 
+    380864, 380870, 380877, 380884, 380892, 380899, 380907, 380915, 
+    380924, 380931, 380939, 380947, 380956, 380964, 380973, 380982, 
+    380992, 380996, 381001, 381006, 381012, 381017, 381023, 381029, 
+    381036, 381041, 381047, 381053, 381060, 381066, 381073, 381080, 
+    381088, 381093, 381099, 381105, 381112, 381118, 381125, 381132, 
+    381140, 381146, 381153, 381160, 381168, 381175, 381183, 381191, 
+    381200, 381205, 381211, 381217, 381224, 381230, 381237, 381244, 
+    381252, 381258, 381265, 381272, 381280, 381287, 381295, 381303, 
+    381312, 381318, 381325, 381332, 381340, 381347, 381355, 381363, 
+    381372, 381379, 381387, 381395, 381404, 381412, 381421, 381430, 
+    381440, 381445, 381451, 381457, 381464, 381470, 381477, 381484, 
+    381492, 381498, 381505, 381512, 381520, 381527, 381535, 381543, 
+    381552, 381558, 381565, 381572, 381580, 381587, 381595, 381603, 
+    381612, 381619, 381627, 381635, 381644, 381652, 381661, 381670, 
+    381680, 381686, 381693, 381700, 381708, 381715, 381723, 381731, 
+    381740, 381747, 381755, 381763, 381772, 381780, 381789, 381798, 
+    381808, 381815, 381823, 381831, 381840, 381848, 381857, 381866, 
+    381876, 381884, 381893, 381902, 381912, 381921, 381931, 381941, 
+    381952, 381956, 381961, 381966, 381972, 381977, 381983, 381989, 
+    381996, 382001, 382007, 382013, 382020, 382026, 382033, 382040, 
+    382048, 382053, 382059, 382065, 382072, 382078, 382085, 382092, 
+    382100, 382106, 382113, 382120, 382128, 382135, 382143, 382151, 
+    382160, 382165, 382171, 382177, 382184, 382190, 382197, 382204, 
+    382212, 382218, 382225, 382232, 382240, 382247, 382255, 382263, 
+    382272, 382278, 382285, 382292, 382300, 382307, 382315, 382323, 
+    382332, 382339, 382347, 382355, 382364, 382372, 382381, 382390, 
+    382400, 382405, 382411, 382417, 382424, 382430, 382437, 382444, 
+    382452, 382458, 382465, 382472, 382480, 382487, 382495, 382503, 
+    382512, 382518, 382525, 382532, 382540, 382547, 382555, 382563, 
+    382572, 382579, 382587, 382595, 382604, 382612, 382621, 382630, 
+    382640, 382646, 382653, 382660, 382668, 382675, 382683, 382691, 
+    382700, 382707, 382715, 382723, 382732, 382740, 382749, 382758, 
+    382768, 382775, 382783, 382791, 382800, 382808, 382817, 382826, 
+    382836, 382844, 382853, 382862, 382872, 382881, 382891, 382901, 
+    382912, 382917, 382923, 382929, 382936, 382942, 382949, 382956, 
+    382964, 382970, 382977, 382984, 382992, 382999, 383007, 383015, 
+    383024, 383030, 383037, 383044, 383052, 383059, 383067, 383075, 
+    383084, 383091, 383099, 383107, 383116, 383124, 383133, 383142, 
+    383152, 383158, 383165, 383172, 383180, 383187, 383195, 383203, 
+    383212, 383219, 383227, 383235, 383244, 383252, 383261, 383270, 
+    383280, 383287, 383295, 383303, 383312, 383320, 383329, 383338, 
+    383348, 383356, 383365, 383374, 383384, 383393, 383403, 383413, 
+    383424, 383430, 383437, 383444, 383452, 383459, 383467, 383475, 
+    383484, 383491, 383499, 383507, 383516, 383524, 383533, 383542, 
+    383552, 383559, 383567, 383575, 383584, 383592, 383601, 383610, 
+    383620, 383628, 383637, 383646, 383656, 383665, 383675, 383685, 
+    383696, 383703, 383711, 383719, 383728, 383736, 383745, 383754, 
+    383764, 383772, 383781, 383790, 383800, 383809, 383819, 383829, 
+    383840, 383848, 383857, 383866, 383876, 383885, 383895, 383905, 
+    383916, 383925, 383935, 383945, 383956, 383966, 383977, 383988, 
+    384000, 384003, 384007, 384011, 384016, 384020, 384025, 384030, 
+    384036, 384040, 384045, 384050, 384056, 384061, 384067, 384073, 
+    384080, 384084, 384089, 384094, 384100, 384105, 384111, 384117, 
+    384124, 384129, 384135, 384141, 384148, 384154, 384161, 384168, 
+    384176, 384180, 384185, 384190, 384196, 384201, 384207, 384213, 
+    384220, 384225, 384231, 384237, 384244, 384250, 384257, 384264, 
+    384272, 384277, 384283, 384289, 384296, 384302, 384309, 384316, 
+    384324, 384330, 384337, 384344, 384352, 384359, 384367, 384375, 
+    384384, 384388, 384393, 384398, 384404, 384409, 384415, 384421, 
+    384428, 384433, 384439, 384445, 384452, 384458, 384465, 384472, 
+    384480, 384485, 384491, 384497, 384504, 384510, 384517, 384524, 
+    384532, 384538, 384545, 384552, 384560, 384567, 384575, 384583, 
+    384592, 384597, 384603, 384609, 384616, 384622, 384629, 384636, 
+    384644, 384650, 384657, 384664, 384672, 384679, 384687, 384695, 
+    384704, 384710, 384717, 384724, 384732, 384739, 384747, 384755, 
+    384764, 384771, 384779, 384787, 384796, 384804, 384813, 384822, 
+    384832, 384836, 384841, 384846, 384852, 384857, 384863, 384869, 
+    384876, 384881, 384887, 384893, 384900, 384906, 384913, 384920, 
+    384928, 384933, 384939, 384945, 384952, 384958, 384965, 384972, 
+    384980, 384986, 384993, 385000, 385008, 385015, 385023, 385031, 
+    385040, 385045, 385051, 385057, 385064, 385070, 385077, 385084, 
+    385092, 385098, 385105, 385112, 385120, 385127, 385135, 385143, 
+    385152, 385158, 385165, 385172, 385180, 385187, 385195, 385203, 
+    385212, 385219, 385227, 385235, 385244, 385252, 385261, 385270, 
+    385280, 385285, 385291, 385297, 385304, 385310, 385317, 385324, 
+    385332, 385338, 385345, 385352, 385360, 385367, 385375, 385383, 
+    385392, 385398, 385405, 385412, 385420, 385427, 385435, 385443, 
+    385452, 385459, 385467, 385475, 385484, 385492, 385501, 385510, 
+    385520, 385526, 385533, 385540, 385548, 385555, 385563, 385571, 
+    385580, 385587, 385595, 385603, 385612, 385620, 385629, 385638, 
+    385648, 385655, 385663, 385671, 385680, 385688, 385697, 385706, 
+    385716, 385724, 385733, 385742, 385752, 385761, 385771, 385781, 
+    385792, 385796, 385801, 385806, 385812, 385817, 385823, 385829, 
+    385836, 385841, 385847, 385853, 385860, 385866, 385873, 385880, 
+    385888, 385893, 385899, 385905, 385912, 385918, 385925, 385932, 
+    385940, 385946, 385953, 385960, 385968, 385975, 385983, 385991, 
+    386000, 386005, 386011, 386017, 386024, 386030, 386037, 386044, 
+    386052, 386058, 386065, 386072, 386080, 386087, 386095, 386103, 
+    386112, 386118, 386125, 386132, 386140, 386147, 386155, 386163, 
+    386172, 386179, 386187, 386195, 386204, 386212, 386221, 386230, 
+    386240, 386245, 386251, 386257, 386264, 386270, 386277, 386284, 
+    386292, 386298, 386305, 386312, 386320, 386327, 386335, 386343, 
+    386352, 386358, 386365, 386372, 386380, 386387, 386395, 386403, 
+    386412, 386419, 386427, 386435, 386444, 386452, 386461, 386470, 
+    386480, 386486, 386493, 386500, 386508, 386515, 386523, 386531, 
+    386540, 386547, 386555, 386563, 386572, 386580, 386589, 386598, 
+    386608, 386615, 386623, 386631, 386640, 386648, 386657, 386666, 
+    386676, 386684, 386693, 386702, 386712, 386721, 386731, 386741, 
+    386752, 386757, 386763, 386769, 386776, 386782, 386789, 386796, 
+    386804, 386810, 386817, 386824, 386832, 386839, 386847, 386855, 
+    386864, 386870, 386877, 386884, 386892, 386899, 386907, 386915, 
+    386924, 386931, 386939, 386947, 386956, 386964, 386973, 386982, 
+    386992, 386998, 387005, 387012, 387020, 387027, 387035, 387043, 
+    387052, 387059, 387067, 387075, 387084, 387092, 387101, 387110, 
+    387120, 387127, 387135, 387143, 387152, 387160, 387169, 387178, 
+    387188, 387196, 387205, 387214, 387224, 387233, 387243, 387253, 
+    387264, 387270, 387277, 387284, 387292, 387299, 387307, 387315, 
+    387324, 387331, 387339, 387347, 387356, 387364, 387373, 387382, 
+    387392, 387399, 387407, 387415, 387424, 387432, 387441, 387450, 
+    387460, 387468, 387477, 387486, 387496, 387505, 387515, 387525, 
+    387536, 387543, 387551, 387559, 387568, 387576, 387585, 387594, 
+    387604, 387612, 387621, 387630, 387640, 387649, 387659, 387669, 
+    387680, 387688, 387697, 387706, 387716, 387725, 387735, 387745, 
+    387756, 387765, 387775, 387785, 387796, 387806, 387817, 387828, 
+    387840, 387844, 387849, 387854, 387860, 387865, 387871, 387877, 
+    387884, 387889, 387895, 387901, 387908, 387914, 387921, 387928, 
+    387936, 387941, 387947, 387953, 387960, 387966, 387973, 387980, 
+    387988, 387994, 388001, 388008, 388016, 388023, 388031, 388039, 
+    388048, 388053, 388059, 388065, 388072, 388078, 388085, 388092, 
+    388100, 388106, 388113, 388120, 388128, 388135, 388143, 388151, 
+    388160, 388166, 388173, 388180, 388188, 388195, 388203, 388211, 
+    388220, 388227, 388235, 388243, 388252, 388260, 388269, 388278, 
+    388288, 388293, 388299, 388305, 388312, 388318, 388325, 388332, 
+    388340, 388346, 388353, 388360, 388368, 388375, 388383, 388391, 
+    388400, 388406, 388413, 388420, 388428, 388435, 388443, 388451, 
+    388460, 388467, 388475, 388483, 388492, 388500, 388509, 388518, 
+    388528, 388534, 388541, 388548, 388556, 388563, 388571, 388579, 
+    388588, 388595, 388603, 388611, 388620, 388628, 388637, 388646, 
+    388656, 388663, 388671, 388679, 388688, 388696, 388705, 388714, 
+    388724, 388732, 388741, 388750, 388760, 388769, 388779, 388789, 
+    388800, 388805, 388811, 388817, 388824, 388830, 388837, 388844, 
+    388852, 388858, 388865, 388872, 388880, 388887, 388895, 388903, 
+    388912, 388918, 388925, 388932, 388940, 388947, 388955, 388963, 
+    388972, 388979, 388987, 388995, 389004, 389012, 389021, 389030, 
+    389040, 389046, 389053, 389060, 389068, 389075, 389083, 389091, 
+    389100, 389107, 389115, 389123, 389132, 389140, 389149, 389158, 
+    389168, 389175, 389183, 389191, 389200, 389208, 389217, 389226, 
+    389236, 389244, 389253, 389262, 389272, 389281, 389291, 389301, 
+    389312, 389318, 389325, 389332, 389340, 389347, 389355, 389363, 
+    389372, 389379, 389387, 389395, 389404, 389412, 389421, 389430, 
+    389440, 389447, 389455, 389463, 389472, 389480, 389489, 389498, 
+    389508, 389516, 389525, 389534, 389544, 389553, 389563, 389573, 
+    389584, 389591, 389599, 389607, 389616, 389624, 389633, 389642, 
+    389652, 389660, 389669, 389678, 389688, 389697, 389707, 389717, 
+    389728, 389736, 389745, 389754, 389764, 389773, 389783, 389793, 
+    389804, 389813, 389823, 389833, 389844, 389854, 389865, 389876, 
+    389888, 389893, 389899, 389905, 389912, 389918, 389925, 389932, 
+    389940, 389946, 389953, 389960, 389968, 389975, 389983, 389991, 
+    390000, 390006, 390013, 390020, 390028, 390035, 390043, 390051, 
+    390060, 390067, 390075, 390083, 390092, 390100, 390109, 390118, 
+    390128, 390134, 390141, 390148, 390156, 390163, 390171, 390179, 
+    390188, 390195, 390203, 390211, 390220, 390228, 390237, 390246, 
+    390256, 390263, 390271, 390279, 390288, 390296, 390305, 390314, 
+    390324, 390332, 390341, 390350, 390360, 390369, 390379, 390389, 
+    390400, 390406, 390413, 390420, 390428, 390435, 390443, 390451, 
+    390460, 390467, 390475, 390483, 390492, 390500, 390509, 390518, 
+    390528, 390535, 390543, 390551, 390560, 390568, 390577, 390586, 
+    390596, 390604, 390613, 390622, 390632, 390641, 390651, 390661, 
+    390672, 390679, 390687, 390695, 390704, 390712, 390721, 390730, 
+    390740, 390748, 390757, 390766, 390776, 390785, 390795, 390805, 
+    390816, 390824, 390833, 390842, 390852, 390861, 390871, 390881, 
+    390892, 390901, 390911, 390921, 390932, 390942, 390953, 390964, 
+    390976, 390982, 390989, 390996, 391004, 391011, 391019, 391027, 
+    391036, 391043, 391051, 391059, 391068, 391076, 391085, 391094, 
+    391104, 391111, 391119, 391127, 391136, 391144, 391153, 391162, 
+    391172, 391180, 391189, 391198, 391208, 391217, 391227, 391237, 
+    391248, 391255, 391263, 391271, 391280, 391288, 391297, 391306, 
+    391316, 391324, 391333, 391342, 391352, 391361, 391371, 391381, 
+    391392, 391400, 391409, 391418, 391428, 391437, 391447, 391457, 
+    391468, 391477, 391487, 391497, 391508, 391518, 391529, 391540, 
+    391552, 391559, 391567, 391575, 391584, 391592, 391601, 391610, 
+    391620, 391628, 391637, 391646, 391656, 391665, 391675, 391685, 
+    391696, 391704, 391713, 391722, 391732, 391741, 391751, 391761, 
+    391772, 391781, 391791, 391801, 391812, 391822, 391833, 391844, 
+    391856, 391864, 391873, 391882, 391892, 391901, 391911, 391921, 
+    391932, 391941, 391951, 391961, 391972, 391982, 391993, 392004, 
+    392016, 392025, 392035, 392045, 392056, 392066, 392077, 392088, 
+    392100, 392110, 392121, 392132, 392144, 392155, 392167, 392179, 
+    392192, 392195, 392199, 392203, 392208, 392212, 392217, 392222, 
+    392228, 392232, 392237, 392242, 392248, 392253, 392259, 392265, 
+    392272, 392276, 392281, 392286, 392292, 392297, 392303, 392309, 
+    392316, 392321, 392327, 392333, 392340, 392346, 392353, 392360, 
+    392368, 392372, 392377, 392382, 392388, 392393, 392399, 392405, 
+    392412, 392417, 392423, 392429, 392436, 392442, 392449, 392456, 
+    392464, 392469, 392475, 392481, 392488, 392494, 392501, 392508, 
+    392516, 392522, 392529, 392536, 392544, 392551, 392559, 392567, 
+    392576, 392580, 392585, 392590, 392596, 392601, 392607, 392613, 
+    392620, 392625, 392631, 392637, 392644, 392650, 392657, 392664, 
+    392672, 392677, 392683, 392689, 392696, 392702, 392709, 392716, 
+    392724, 392730, 392737, 392744, 392752, 392759, 392767, 392775, 
+    392784, 392789, 392795, 392801, 392808, 392814, 392821, 392828, 
+    392836, 392842, 392849, 392856, 392864, 392871, 392879, 392887, 
+    392896, 392902, 392909, 392916, 392924, 392931, 392939, 392947, 
+    392956, 392963, 392971, 392979, 392988, 392996, 393005, 393014, 
+    393024, 393028, 393033, 393038, 393044, 393049, 393055, 393061, 
+    393068, 393073, 393079, 393085, 393092, 393098, 393105, 393112, 
+    393120, 393125, 393131, 393137, 393144, 393150, 393157, 393164, 
+    393172, 393178, 393185, 393192, 393200, 393207, 393215, 393223, 
+    393232, 393237, 393243, 393249, 393256, 393262, 393269, 393276, 
+    393284, 393290, 393297, 393304, 393312, 393319, 393327, 393335, 
+    393344, 393350, 393357, 393364, 393372, 393379, 393387, 393395, 
+    393404, 393411, 393419, 393427, 393436, 393444, 393453, 393462, 
+    393472, 393477, 393483, 393489, 393496, 393502, 393509, 393516, 
+    393524, 393530, 393537, 393544, 393552, 393559, 393567, 393575, 
+    393584, 393590, 393597, 393604, 393612, 393619, 393627, 393635, 
+    393644, 393651, 393659, 393667, 393676, 393684, 393693, 393702, 
+    393712, 393718, 393725, 393732, 393740, 393747, 393755, 393763, 
+    393772, 393779, 393787, 393795, 393804, 393812, 393821, 393830, 
+    393840, 393847, 393855, 393863, 393872, 393880, 393889, 393898, 
+    393908, 393916, 393925, 393934, 393944, 393953, 393963, 393973, 
+    393984, 393988, 393993, 393998, 394004, 394009, 394015, 394021, 
+    394028, 394033, 394039, 394045, 394052, 394058, 394065, 394072, 
+    394080, 394085, 394091, 394097, 394104, 394110, 394117, 394124, 
+    394132, 394138, 394145, 394152, 394160, 394167, 394175, 394183, 
+    394192, 394197, 394203, 394209, 394216, 394222, 394229, 394236, 
+    394244, 394250, 394257, 394264, 394272, 394279, 394287, 394295, 
+    394304, 394310, 394317, 394324, 394332, 394339, 394347, 394355, 
+    394364, 394371, 394379, 394387, 394396, 394404, 394413, 394422, 
+    394432, 394437, 394443, 394449, 394456, 394462, 394469, 394476, 
+    394484, 394490, 394497, 394504, 394512, 394519, 394527, 394535, 
+    394544, 394550, 394557, 394564, 394572, 394579, 394587, 394595, 
+    394604, 394611, 394619, 394627, 394636, 394644, 394653, 394662, 
+    394672, 394678, 394685, 394692, 394700, 394707, 394715, 394723, 
+    394732, 394739, 394747, 394755, 394764, 394772, 394781, 394790, 
+    394800, 394807, 394815, 394823, 394832, 394840, 394849, 394858, 
+    394868, 394876, 394885, 394894, 394904, 394913, 394923, 394933, 
+    394944, 394949, 394955, 394961, 394968, 394974, 394981, 394988, 
+    394996, 395002, 395009, 395016, 395024, 395031, 395039, 395047, 
+    395056, 395062, 395069, 395076, 395084, 395091, 395099, 395107, 
+    395116, 395123, 395131, 395139, 395148, 395156, 395165, 395174, 
+    395184, 395190, 395197, 395204, 395212, 395219, 395227, 395235, 
+    395244, 395251, 395259, 395267, 395276, 395284, 395293, 395302, 
+    395312, 395319, 395327, 395335, 395344, 395352, 395361, 395370, 
+    395380, 395388, 395397, 395406, 395416, 395425, 395435, 395445, 
+    395456, 395462, 395469, 395476, 395484, 395491, 395499, 395507, 
+    395516, 395523, 395531, 395539, 395548, 395556, 395565, 395574, 
+    395584, 395591, 395599, 395607, 395616, 395624, 395633, 395642, 
+    395652, 395660, 395669, 395678, 395688, 395697, 395707, 395717, 
+    395728, 395735, 395743, 395751, 395760, 395768, 395777, 395786, 
+    395796, 395804, 395813, 395822, 395832, 395841, 395851, 395861, 
+    395872, 395880, 395889, 395898, 395908, 395917, 395927, 395937, 
+    395948, 395957, 395967, 395977, 395988, 395998, 396009, 396020, 
+    396032, 396036, 396041, 396046, 396052, 396057, 396063, 396069, 
+    396076, 396081, 396087, 396093, 396100, 396106, 396113, 396120, 
+    396128, 396133, 396139, 396145, 396152, 396158, 396165, 396172, 
+    396180, 396186, 396193, 396200, 396208, 396215, 396223, 396231, 
+    396240, 396245, 396251, 396257, 396264, 396270, 396277, 396284, 
+    396292, 396298, 396305, 396312, 396320, 396327, 396335, 396343, 
+    396352, 396358, 396365, 396372, 396380, 396387, 396395, 396403, 
+    396412, 396419, 396427, 396435, 396444, 396452, 396461, 396470, 
+    396480, 396485, 396491, 396497, 396504, 396510, 396517, 396524, 
+    396532, 396538, 396545, 396552, 396560, 396567, 396575, 396583, 
+    396592, 396598, 396605, 396612, 396620, 396627, 396635, 396643, 
+    396652, 396659, 396667, 396675, 396684, 396692, 396701, 396710, 
+    396720, 396726, 396733, 396740, 396748, 396755, 396763, 396771, 
+    396780, 396787, 396795, 396803, 396812, 396820, 396829, 396838, 
+    396848, 396855, 396863, 396871, 396880, 396888, 396897, 396906, 
+    396916, 396924, 396933, 396942, 396952, 396961, 396971, 396981, 
+    396992, 396997, 397003, 397009, 397016, 397022, 397029, 397036, 
+    397044, 397050, 397057, 397064, 397072, 397079, 397087, 397095, 
+    397104, 397110, 397117, 397124, 397132, 397139, 397147, 397155, 
+    397164, 397171, 397179, 397187, 397196, 397204, 397213, 397222, 
+    397232, 397238, 397245, 397252, 397260, 397267, 397275, 397283, 
+    397292, 397299, 397307, 397315, 397324, 397332, 397341, 397350, 
+    397360, 397367, 397375, 397383, 397392, 397400, 397409, 397418, 
+    397428, 397436, 397445, 397454, 397464, 397473, 397483, 397493, 
+    397504, 397510, 397517, 397524, 397532, 397539, 397547, 397555, 
+    397564, 397571, 397579, 397587, 397596, 397604, 397613, 397622, 
+    397632, 397639, 397647, 397655, 397664, 397672, 397681, 397690, 
+    397700, 397708, 397717, 397726, 397736, 397745, 397755, 397765, 
+    397776, 397783, 397791, 397799, 397808, 397816, 397825, 397834, 
+    397844, 397852, 397861, 397870, 397880, 397889, 397899, 397909, 
+    397920, 397928, 397937, 397946, 397956, 397965, 397975, 397985, 
+    397996, 398005, 398015, 398025, 398036, 398046, 398057, 398068, 
+    398080, 398085, 398091, 398097, 398104, 398110, 398117, 398124, 
+    398132, 398138, 398145, 398152, 398160, 398167, 398175, 398183, 
+    398192, 398198, 398205, 398212, 398220, 398227, 398235, 398243, 
+    398252, 398259, 398267, 398275, 398284, 398292, 398301, 398310, 
+    398320, 398326, 398333, 398340, 398348, 398355, 398363, 398371, 
+    398380, 398387, 398395, 398403, 398412, 398420, 398429, 398438, 
+    398448, 398455, 398463, 398471, 398480, 398488, 398497, 398506, 
+    398516, 398524, 398533, 398542, 398552, 398561, 398571, 398581, 
+    398592, 398598, 398605, 398612, 398620, 398627, 398635, 398643, 
+    398652, 398659, 398667, 398675, 398684, 398692, 398701, 398710, 
+    398720, 398727, 398735, 398743, 398752, 398760, 398769, 398778, 
+    398788, 398796, 398805, 398814, 398824, 398833, 398843, 398853, 
+    398864, 398871, 398879, 398887, 398896, 398904, 398913, 398922, 
+    398932, 398940, 398949, 398958, 398968, 398977, 398987, 398997, 
+    399008, 399016, 399025, 399034, 399044, 399053, 399063, 399073, 
+    399084, 399093, 399103, 399113, 399124, 399134, 399145, 399156, 
+    399168, 399174, 399181, 399188, 399196, 399203, 399211, 399219, 
+    399228, 399235, 399243, 399251, 399260, 399268, 399277, 399286, 
+    399296, 399303, 399311, 399319, 399328, 399336, 399345, 399354, 
+    399364, 399372, 399381, 399390, 399400, 399409, 399419, 399429, 
+    399440, 399447, 399455, 399463, 399472, 399480, 399489, 399498, 
+    399508, 399516, 399525, 399534, 399544, 399553, 399563, 399573, 
+    399584, 399592, 399601, 399610, 399620, 399629, 399639, 399649, 
+    399660, 399669, 399679, 399689, 399700, 399710, 399721, 399732, 
+    399744, 399751, 399759, 399767, 399776, 399784, 399793, 399802, 
+    399812, 399820, 399829, 399838, 399848, 399857, 399867, 399877, 
+    399888, 399896, 399905, 399914, 399924, 399933, 399943, 399953, 
+    399964, 399973, 399983, 399993, 400004, 400014, 400025, 400036, 
+    400048, 400056, 400065, 400074, 400084, 400093, 400103, 400113, 
+    400124, 400133, 400143, 400153, 400164, 400174, 400185, 400196, 
+    400208, 400217, 400227, 400237, 400248, 400258, 400269, 400280, 
+    400292, 400302, 400313, 400324, 400336, 400347, 400359, 400371, 
+    400384, 400388, 400393, 400398, 400404, 400409, 400415, 400421, 
+    400428, 400433, 400439, 400445, 400452, 400458, 400465, 400472, 
+    400480, 400485, 400491, 400497, 400504, 400510, 400517, 400524, 
+    400532, 400538, 400545, 400552, 400560, 400567, 400575, 400583, 
+    400592, 400597, 400603, 400609, 400616, 400622, 400629, 400636, 
+    400644, 400650, 400657, 400664, 400672, 400679, 400687, 400695, 
+    400704, 400710, 400717, 400724, 400732, 400739, 400747, 400755, 
+    400764, 400771, 400779, 400787, 400796, 400804, 400813, 400822, 
+    400832, 400837, 400843, 400849, 400856, 400862, 400869, 400876, 
+    400884, 400890, 400897, 400904, 400912, 400919, 400927, 400935, 
+    400944, 400950, 400957, 400964, 400972, 400979, 400987, 400995, 
+    401004, 401011, 401019, 401027, 401036, 401044, 401053, 401062, 
+    401072, 401078, 401085, 401092, 401100, 401107, 401115, 401123, 
+    401132, 401139, 401147, 401155, 401164, 401172, 401181, 401190, 
+    401200, 401207, 401215, 401223, 401232, 401240, 401249, 401258, 
+    401268, 401276, 401285, 401294, 401304, 401313, 401323, 401333, 
+    401344, 401349, 401355, 401361, 401368, 401374, 401381, 401388, 
+    401396, 401402, 401409, 401416, 401424, 401431, 401439, 401447, 
+    401456, 401462, 401469, 401476, 401484, 401491, 401499, 401507, 
+    401516, 401523, 401531, 401539, 401548, 401556, 401565, 401574, 
+    401584, 401590, 401597, 401604, 401612, 401619, 401627, 401635, 
+    401644, 401651, 401659, 401667, 401676, 401684, 401693, 401702, 
+    401712, 401719, 401727, 401735, 401744, 401752, 401761, 401770, 
+    401780, 401788, 401797, 401806, 401816, 401825, 401835, 401845, 
+    401856, 401862, 401869, 401876, 401884, 401891, 401899, 401907, 
+    401916, 401923, 401931, 401939, 401948, 401956, 401965, 401974, 
+    401984, 401991, 401999, 402007, 402016, 402024, 402033, 402042, 
+    402052, 402060, 402069, 402078, 402088, 402097, 402107, 402117, 
+    402128, 402135, 402143, 402151, 402160, 402168, 402177, 402186, 
+    402196, 402204, 402213, 402222, 402232, 402241, 402251, 402261, 
+    402272, 402280, 402289, 402298, 402308, 402317, 402327, 402337, 
+    402348, 402357, 402367, 402377, 402388, 402398, 402409, 402420, 
+    402432, 402437, 402443, 402449, 402456, 402462, 402469, 402476, 
+    402484, 402490, 402497, 402504, 402512, 402519, 402527, 402535, 
+    402544, 402550, 402557, 402564, 402572, 402579, 402587, 402595, 
+    402604, 402611, 402619, 402627, 402636, 402644, 402653, 402662, 
+    402672, 402678, 402685, 402692, 402700, 402707, 402715, 402723, 
+    402732, 402739, 402747, 402755, 402764, 402772, 402781, 402790, 
+    402800, 402807, 402815, 402823, 402832, 402840, 402849, 402858, 
+    402868, 402876, 402885, 402894, 402904, 402913, 402923, 402933, 
+    402944, 402950, 402957, 402964, 402972, 402979, 402987, 402995, 
+    403004, 403011, 403019, 403027, 403036, 403044, 403053, 403062, 
+    403072, 403079, 403087, 403095, 403104, 403112, 403121, 403130, 
+    403140, 403148, 403157, 403166, 403176, 403185, 403195, 403205, 
+    403216, 403223, 403231, 403239, 403248, 403256, 403265, 403274, 
+    403284, 403292, 403301, 403310, 403320, 403329, 403339, 403349, 
+    403360, 403368, 403377, 403386, 403396, 403405, 403415, 403425, 
+    403436, 403445, 403455, 403465, 403476, 403486, 403497, 403508, 
+    403520, 403526, 403533, 403540, 403548, 403555, 403563, 403571, 
+    403580, 403587, 403595, 403603, 403612, 403620, 403629, 403638, 
+    403648, 403655, 403663, 403671, 403680, 403688, 403697, 403706, 
+    403716, 403724, 403733, 403742, 403752, 403761, 403771, 403781, 
+    403792, 403799, 403807, 403815, 403824, 403832, 403841, 403850, 
+    403860, 403868, 403877, 403886, 403896, 403905, 403915, 403925, 
+    403936, 403944, 403953, 403962, 403972, 403981, 403991, 404001, 
+    404012, 404021, 404031, 404041, 404052, 404062, 404073, 404084, 
+    404096, 404103, 404111, 404119, 404128, 404136, 404145, 404154, 
+    404164, 404172, 404181, 404190, 404200, 404209, 404219, 404229, 
+    404240, 404248, 404257, 404266, 404276, 404285, 404295, 404305, 
+    404316, 404325, 404335, 404345, 404356, 404366, 404377, 404388, 
+    404400, 404408, 404417, 404426, 404436, 404445, 404455, 404465, 
+    404476, 404485, 404495, 404505, 404516, 404526, 404537, 404548, 
+    404560, 404569, 404579, 404589, 404600, 404610, 404621, 404632, 
+    404644, 404654, 404665, 404676, 404688, 404699, 404711, 404723, 
+    404736, 404741, 404747, 404753, 404760, 404766, 404773, 404780, 
+    404788, 404794, 404801, 404808, 404816, 404823, 404831, 404839, 
+    404848, 404854, 404861, 404868, 404876, 404883, 404891, 404899, 
+    404908, 404915, 404923, 404931, 404940, 404948, 404957, 404966, 
+    404976, 404982, 404989, 404996, 405004, 405011, 405019, 405027, 
+    405036, 405043, 405051, 405059, 405068, 405076, 405085, 405094, 
+    405104, 405111, 405119, 405127, 405136, 405144, 405153, 405162, 
+    405172, 405180, 405189, 405198, 405208, 405217, 405227, 405237, 
+    405248, 405254, 405261, 405268, 405276, 405283, 405291, 405299, 
+    405308, 405315, 405323, 405331, 405340, 405348, 405357, 405366, 
+    405376, 405383, 405391, 405399, 405408, 405416, 405425, 405434, 
+    405444, 405452, 405461, 405470, 405480, 405489, 405499, 405509, 
+    405520, 405527, 405535, 405543, 405552, 405560, 405569, 405578, 
+    405588, 405596, 405605, 405614, 405624, 405633, 405643, 405653, 
+    405664, 405672, 405681, 405690, 405700, 405709, 405719, 405729, 
+    405740, 405749, 405759, 405769, 405780, 405790, 405801, 405812, 
+    405824, 405830, 405837, 405844, 405852, 405859, 405867, 405875, 
+    405884, 405891, 405899, 405907, 405916, 405924, 405933, 405942, 
+    405952, 405959, 405967, 405975, 405984, 405992, 406001, 406010, 
+    406020, 406028, 406037, 406046, 406056, 406065, 406075, 406085, 
+    406096, 406103, 406111, 406119, 406128, 406136, 406145, 406154, 
+    406164, 406172, 406181, 406190, 406200, 406209, 406219, 406229, 
+    406240, 406248, 406257, 406266, 406276, 406285, 406295, 406305, 
+    406316, 406325, 406335, 406345, 406356, 406366, 406377, 406388, 
+    406400, 406407, 406415, 406423, 406432, 406440, 406449, 406458, 
+    406468, 406476, 406485, 406494, 406504, 406513, 406523, 406533, 
+    406544, 406552, 406561, 406570, 406580, 406589, 406599, 406609, 
+    406620, 406629, 406639, 406649, 406660, 406670, 406681, 406692, 
+    406704, 406712, 406721, 406730, 406740, 406749, 406759, 406769, 
+    406780, 406789, 406799, 406809, 406820, 406830, 406841, 406852, 
+    406864, 406873, 406883, 406893, 406904, 406914, 406925, 406936, 
+    406948, 406958, 406969, 406980, 406992, 407003, 407015, 407027, 
+    407040, 407046, 407053, 407060, 407068, 407075, 407083, 407091, 
+    407100, 407107, 407115, 407123, 407132, 407140, 407149, 407158, 
+    407168, 407175, 407183, 407191, 407200, 407208, 407217, 407226, 
+    407236, 407244, 407253, 407262, 407272, 407281, 407291, 407301, 
+    407312, 407319, 407327, 407335, 407344, 407352, 407361, 407370, 
+    407380, 407388, 407397, 407406, 407416, 407425, 407435, 407445, 
+    407456, 407464, 407473, 407482, 407492, 407501, 407511, 407521, 
+    407532, 407541, 407551, 407561, 407572, 407582, 407593, 407604, 
+    407616, 407623, 407631, 407639, 407648, 407656, 407665, 407674, 
+    407684, 407692, 407701, 407710, 407720, 407729, 407739, 407749, 
+    407760, 407768, 407777, 407786, 407796, 407805, 407815, 407825, 
+    407836, 407845, 407855, 407865, 407876, 407886, 407897, 407908, 
+    407920, 407928, 407937, 407946, 407956, 407965, 407975, 407985, 
+    407996, 408005, 408015, 408025, 408036, 408046, 408057, 408068, 
+    408080, 408089, 408099, 408109, 408120, 408130, 408141, 408152, 
+    408164, 408174, 408185, 408196, 408208, 408219, 408231, 408243, 
+    408256, 408263, 408271, 408279, 408288, 408296, 408305, 408314, 
+    408324, 408332, 408341, 408350, 408360, 408369, 408379, 408389, 
+    408400, 408408, 408417, 408426, 408436, 408445, 408455, 408465, 
+    408476, 408485, 408495, 408505, 408516, 408526, 408537, 408548, 
+    408560, 408568, 408577, 408586, 408596, 408605, 408615, 408625, 
+    408636, 408645, 408655, 408665, 408676, 408686, 408697, 408708, 
+    408720, 408729, 408739, 408749, 408760, 408770, 408781, 408792, 
+    408804, 408814, 408825, 408836, 408848, 408859, 408871, 408883, 
+    408896, 408904, 408913, 408922, 408932, 408941, 408951, 408961, 
+    408972, 408981, 408991, 409001, 409012, 409022, 409033, 409044, 
+    409056, 409065, 409075, 409085, 409096, 409106, 409117, 409128, 
+    409140, 409150, 409161, 409172, 409184, 409195, 409207, 409219, 
+    409232, 409241, 409251, 409261, 409272, 409282, 409293, 409304, 
+    409316, 409326, 409337, 409348, 409360, 409371, 409383, 409395, 
+    409408, 409418, 409429, 409440, 409452, 409463, 409475, 409487, 
+    409500, 409511, 409523, 409535, 409548, 409560, 409573, 409586, 
+    409600, 409603, 409607, 409611, 409616, 409620, 409625, 409630, 
+    409636, 409640, 409645, 409650, 409656, 409661, 409667, 409673, 
+    409680, 409684, 409689, 409694, 409700, 409705, 409711, 409717, 
+    409724, 409729, 409735, 409741, 409748, 409754, 409761, 409768, 
+    409776, 409780, 409785, 409790, 409796, 409801, 409807, 409813, 
+    409820, 409825, 409831, 409837, 409844, 409850, 409857, 409864, 
+    409872, 409877, 409883, 409889, 409896, 409902, 409909, 409916, 
+    409924, 409930, 409937, 409944, 409952, 409959, 409967, 409975, 
+    409984, 409988, 409993, 409998, 410004, 410009, 410015, 410021, 
+    410028, 410033, 410039, 410045, 410052, 410058, 410065, 410072, 
+    410080, 410085, 410091, 410097, 410104, 410110, 410117, 410124, 
+    410132, 410138, 410145, 410152, 410160, 410167, 410175, 410183, 
+    410192, 410197, 410203, 410209, 410216, 410222, 410229, 410236, 
+    410244, 410250, 410257, 410264, 410272, 410279, 410287, 410295, 
+    410304, 410310, 410317, 410324, 410332, 410339, 410347, 410355, 
+    410364, 410371, 410379, 410387, 410396, 410404, 410413, 410422, 
+    410432, 410436, 410441, 410446, 410452, 410457, 410463, 410469, 
+    410476, 410481, 410487, 410493, 410500, 410506, 410513, 410520, 
+    410528, 410533, 410539, 410545, 410552, 410558, 410565, 410572, 
+    410580, 410586, 410593, 410600, 410608, 410615, 410623, 410631, 
+    410640, 410645, 410651, 410657, 410664, 410670, 410677, 410684, 
+    410692, 410698, 410705, 410712, 410720, 410727, 410735, 410743, 
+    410752, 410758, 410765, 410772, 410780, 410787, 410795, 410803, 
+    410812, 410819, 410827, 410835, 410844, 410852, 410861, 410870, 
+    410880, 410885, 410891, 410897, 410904, 410910, 410917, 410924, 
+    410932, 410938, 410945, 410952, 410960, 410967, 410975, 410983, 
+    410992, 410998, 411005, 411012, 411020, 411027, 411035, 411043, 
+    411052, 411059, 411067, 411075, 411084, 411092, 411101, 411110, 
+    411120, 411126, 411133, 411140, 411148, 411155, 411163, 411171, 
+    411180, 411187, 411195, 411203, 411212, 411220, 411229, 411238, 
+    411248, 411255, 411263, 411271, 411280, 411288, 411297, 411306, 
+    411316, 411324, 411333, 411342, 411352, 411361, 411371, 411381, 
+    411392, 411396, 411401, 411406, 411412, 411417, 411423, 411429, 
+    411436, 411441, 411447, 411453, 411460, 411466, 411473, 411480, 
+    411488, 411493, 411499, 411505, 411512, 411518, 411525, 411532, 
+    411540, 411546, 411553, 411560, 411568, 411575, 411583, 411591, 
+    411600, 411605, 411611, 411617, 411624, 411630, 411637, 411644, 
+    411652, 411658, 411665, 411672, 411680, 411687, 411695, 411703, 
+    411712, 411718, 411725, 411732, 411740, 411747, 411755, 411763, 
+    411772, 411779, 411787, 411795, 411804, 411812, 411821, 411830, 
+    411840, 411845, 411851, 411857, 411864, 411870, 411877, 411884, 
+    411892, 411898, 411905, 411912, 411920, 411927, 411935, 411943, 
+    411952, 411958, 411965, 411972, 411980, 411987, 411995, 412003, 
+    412012, 412019, 412027, 412035, 412044, 412052, 412061, 412070, 
+    412080, 412086, 412093, 412100, 412108, 412115, 412123, 412131, 
+    412140, 412147, 412155, 412163, 412172, 412180, 412189, 412198, 
+    412208, 412215, 412223, 412231, 412240, 412248, 412257, 412266, 
+    412276, 412284, 412293, 412302, 412312, 412321, 412331, 412341, 
+    412352, 412357, 412363, 412369, 412376, 412382, 412389, 412396, 
+    412404, 412410, 412417, 412424, 412432, 412439, 412447, 412455, 
+    412464, 412470, 412477, 412484, 412492, 412499, 412507, 412515, 
+    412524, 412531, 412539, 412547, 412556, 412564, 412573, 412582, 
+    412592, 412598, 412605, 412612, 412620, 412627, 412635, 412643, 
+    412652, 412659, 412667, 412675, 412684, 412692, 412701, 412710, 
+    412720, 412727, 412735, 412743, 412752, 412760, 412769, 412778, 
+    412788, 412796, 412805, 412814, 412824, 412833, 412843, 412853, 
+    412864, 412870, 412877, 412884, 412892, 412899, 412907, 412915, 
+    412924, 412931, 412939, 412947, 412956, 412964, 412973, 412982, 
+    412992, 412999, 413007, 413015, 413024, 413032, 413041, 413050, 
+    413060, 413068, 413077, 413086, 413096, 413105, 413115, 413125, 
+    413136, 413143, 413151, 413159, 413168, 413176, 413185, 413194, 
+    413204, 413212, 413221, 413230, 413240, 413249, 413259, 413269, 
+    413280, 413288, 413297, 413306, 413316, 413325, 413335, 413345, 
+    413356, 413365, 413375, 413385, 413396, 413406, 413417, 413428, 
+    413440, 413444, 413449, 413454, 413460, 413465, 413471, 413477, 
+    413484, 413489, 413495, 413501, 413508, 413514, 413521, 413528, 
+    413536, 413541, 413547, 413553, 413560, 413566, 413573, 413580, 
+    413588, 413594, 413601, 413608, 413616, 413623, 413631, 413639, 
+    413648, 413653, 413659, 413665, 413672, 413678, 413685, 413692, 
+    413700, 413706, 413713, 413720, 413728, 413735, 413743, 413751, 
+    413760, 413766, 413773, 413780, 413788, 413795, 413803, 413811, 
+    413820, 413827, 413835, 413843, 413852, 413860, 413869, 413878, 
+    413888, 413893, 413899, 413905, 413912, 413918, 413925, 413932, 
+    413940, 413946, 413953, 413960, 413968, 413975, 413983, 413991, 
+    414000, 414006, 414013, 414020, 414028, 414035, 414043, 414051, 
+    414060, 414067, 414075, 414083, 414092, 414100, 414109, 414118, 
+    414128, 414134, 414141, 414148, 414156, 414163, 414171, 414179, 
+    414188, 414195, 414203, 414211, 414220, 414228, 414237, 414246, 
+    414256, 414263, 414271, 414279, 414288, 414296, 414305, 414314, 
+    414324, 414332, 414341, 414350, 414360, 414369, 414379, 414389, 
+    414400, 414405, 414411, 414417, 414424, 414430, 414437, 414444, 
+    414452, 414458, 414465, 414472, 414480, 414487, 414495, 414503, 
+    414512, 414518, 414525, 414532, 414540, 414547, 414555, 414563, 
+    414572, 414579, 414587, 414595, 414604, 414612, 414621, 414630, 
+    414640, 414646, 414653, 414660, 414668, 414675, 414683, 414691, 
+    414700, 414707, 414715, 414723, 414732, 414740, 414749, 414758, 
+    414768, 414775, 414783, 414791, 414800, 414808, 414817, 414826, 
+    414836, 414844, 414853, 414862, 414872, 414881, 414891, 414901, 
+    414912, 414918, 414925, 414932, 414940, 414947, 414955, 414963, 
+    414972, 414979, 414987, 414995, 415004, 415012, 415021, 415030, 
+    415040, 415047, 415055, 415063, 415072, 415080, 415089, 415098, 
+    415108, 415116, 415125, 415134, 415144, 415153, 415163, 415173, 
+    415184, 415191, 415199, 415207, 415216, 415224, 415233, 415242, 
+    415252, 415260, 415269, 415278, 415288, 415297, 415307, 415317, 
+    415328, 415336, 415345, 415354, 415364, 415373, 415383, 415393, 
+    415404, 415413, 415423, 415433, 415444, 415454, 415465, 415476, 
+    415488, 415493, 415499, 415505, 415512, 415518, 415525, 415532, 
+    415540, 415546, 415553, 415560, 415568, 415575, 415583, 415591, 
+    415600, 415606, 415613, 415620, 415628, 415635, 415643, 415651, 
+    415660, 415667, 415675, 415683, 415692, 415700, 415709, 415718, 
+    415728, 415734, 415741, 415748, 415756, 415763, 415771, 415779, 
+    415788, 415795, 415803, 415811, 415820, 415828, 415837, 415846, 
+    415856, 415863, 415871, 415879, 415888, 415896, 415905, 415914, 
+    415924, 415932, 415941, 415950, 415960, 415969, 415979, 415989, 
+    416000, 416006, 416013, 416020, 416028, 416035, 416043, 416051, 
+    416060, 416067, 416075, 416083, 416092, 416100, 416109, 416118, 
+    416128, 416135, 416143, 416151, 416160, 416168, 416177, 416186, 
+    416196, 416204, 416213, 416222, 416232, 416241, 416251, 416261, 
+    416272, 416279, 416287, 416295, 416304, 416312, 416321, 416330, 
+    416340, 416348, 416357, 416366, 416376, 416385, 416395, 416405, 
+    416416, 416424, 416433, 416442, 416452, 416461, 416471, 416481, 
+    416492, 416501, 416511, 416521, 416532, 416542, 416553, 416564, 
+    416576, 416582, 416589, 416596, 416604, 416611, 416619, 416627, 
+    416636, 416643, 416651, 416659, 416668, 416676, 416685, 416694, 
+    416704, 416711, 416719, 416727, 416736, 416744, 416753, 416762, 
+    416772, 416780, 416789, 416798, 416808, 416817, 416827, 416837, 
+    416848, 416855, 416863, 416871, 416880, 416888, 416897, 416906, 
+    416916, 416924, 416933, 416942, 416952, 416961, 416971, 416981, 
+    416992, 417000, 417009, 417018, 417028, 417037, 417047, 417057, 
+    417068, 417077, 417087, 417097, 417108, 417118, 417129, 417140, 
+    417152, 417159, 417167, 417175, 417184, 417192, 417201, 417210, 
+    417220, 417228, 417237, 417246, 417256, 417265, 417275, 417285, 
+    417296, 417304, 417313, 417322, 417332, 417341, 417351, 417361, 
+    417372, 417381, 417391, 417401, 417412, 417422, 417433, 417444, 
+    417456, 417464, 417473, 417482, 417492, 417501, 417511, 417521, 
+    417532, 417541, 417551, 417561, 417572, 417582, 417593, 417604, 
+    417616, 417625, 417635, 417645, 417656, 417666, 417677, 417688, 
+    417700, 417710, 417721, 417732, 417744, 417755, 417767, 417779, 
+    417792, 417796, 417801, 417806, 417812, 417817, 417823, 417829, 
+    417836, 417841, 417847, 417853, 417860, 417866, 417873, 417880, 
+    417888, 417893, 417899, 417905, 417912, 417918, 417925, 417932, 
+    417940, 417946, 417953, 417960, 417968, 417975, 417983, 417991, 
+    418000, 418005, 418011, 418017, 418024, 418030, 418037, 418044, 
+    418052, 418058, 418065, 418072, 418080, 418087, 418095, 418103, 
+    418112, 418118, 418125, 418132, 418140, 418147, 418155, 418163, 
+    418172, 418179, 418187, 418195, 418204, 418212, 418221, 418230, 
+    418240, 418245, 418251, 418257, 418264, 418270, 418277, 418284, 
+    418292, 418298, 418305, 418312, 418320, 418327, 418335, 418343, 
+    418352, 418358, 418365, 418372, 418380, 418387, 418395, 418403, 
+    418412, 418419, 418427, 418435, 418444, 418452, 418461, 418470, 
+    418480, 418486, 418493, 418500, 418508, 418515, 418523, 418531, 
+    418540, 418547, 418555, 418563, 418572, 418580, 418589, 418598, 
+    418608, 418615, 418623, 418631, 418640, 418648, 418657, 418666, 
+    418676, 418684, 418693, 418702, 418712, 418721, 418731, 418741, 
+    418752, 418757, 418763, 418769, 418776, 418782, 418789, 418796, 
+    418804, 418810, 418817, 418824, 418832, 418839, 418847, 418855, 
+    418864, 418870, 418877, 418884, 418892, 418899, 418907, 418915, 
+    418924, 418931, 418939, 418947, 418956, 418964, 418973, 418982, 
+    418992, 418998, 419005, 419012, 419020, 419027, 419035, 419043, 
+    419052, 419059, 419067, 419075, 419084, 419092, 419101, 419110, 
+    419120, 419127, 419135, 419143, 419152, 419160, 419169, 419178, 
+    419188, 419196, 419205, 419214, 419224, 419233, 419243, 419253, 
+    419264, 419270, 419277, 419284, 419292, 419299, 419307, 419315, 
+    419324, 419331, 419339, 419347, 419356, 419364, 419373, 419382, 
+    419392, 419399, 419407, 419415, 419424, 419432, 419441, 419450, 
+    419460, 419468, 419477, 419486, 419496, 419505, 419515, 419525, 
+    419536, 419543, 419551, 419559, 419568, 419576, 419585, 419594, 
+    419604, 419612, 419621, 419630, 419640, 419649, 419659, 419669, 
+    419680, 419688, 419697, 419706, 419716, 419725, 419735, 419745, 
+    419756, 419765, 419775, 419785, 419796, 419806, 419817, 419828, 
+    419840, 419845, 419851, 419857, 419864, 419870, 419877, 419884, 
+    419892, 419898, 419905, 419912, 419920, 419927, 419935, 419943, 
+    419952, 419958, 419965, 419972, 419980, 419987, 419995, 420003, 
+    420012, 420019, 420027, 420035, 420044, 420052, 420061, 420070, 
+    420080, 420086, 420093, 420100, 420108, 420115, 420123, 420131, 
+    420140, 420147, 420155, 420163, 420172, 420180, 420189, 420198, 
+    420208, 420215, 420223, 420231, 420240, 420248, 420257, 420266, 
+    420276, 420284, 420293, 420302, 420312, 420321, 420331, 420341, 
+    420352, 420358, 420365, 420372, 420380, 420387, 420395, 420403, 
+    420412, 420419, 420427, 420435, 420444, 420452, 420461, 420470, 
+    420480, 420487, 420495, 420503, 420512, 420520, 420529, 420538, 
+    420548, 420556, 420565, 420574, 420584, 420593, 420603, 420613, 
+    420624, 420631, 420639, 420647, 420656, 420664, 420673, 420682, 
+    420692, 420700, 420709, 420718, 420728, 420737, 420747, 420757, 
+    420768, 420776, 420785, 420794, 420804, 420813, 420823, 420833, 
+    420844, 420853, 420863, 420873, 420884, 420894, 420905, 420916, 
+    420928, 420934, 420941, 420948, 420956, 420963, 420971, 420979, 
+    420988, 420995, 421003, 421011, 421020, 421028, 421037, 421046, 
+    421056, 421063, 421071, 421079, 421088, 421096, 421105, 421114, 
+    421124, 421132, 421141, 421150, 421160, 421169, 421179, 421189, 
+    421200, 421207, 421215, 421223, 421232, 421240, 421249, 421258, 
+    421268, 421276, 421285, 421294, 421304, 421313, 421323, 421333, 
+    421344, 421352, 421361, 421370, 421380, 421389, 421399, 421409, 
+    421420, 421429, 421439, 421449, 421460, 421470, 421481, 421492, 
+    421504, 421511, 421519, 421527, 421536, 421544, 421553, 421562, 
+    421572, 421580, 421589, 421598, 421608, 421617, 421627, 421637, 
+    421648, 421656, 421665, 421674, 421684, 421693, 421703, 421713, 
+    421724, 421733, 421743, 421753, 421764, 421774, 421785, 421796, 
+    421808, 421816, 421825, 421834, 421844, 421853, 421863, 421873, 
+    421884, 421893, 421903, 421913, 421924, 421934, 421945, 421956, 
+    421968, 421977, 421987, 421997, 422008, 422018, 422029, 422040, 
+    422052, 422062, 422073, 422084, 422096, 422107, 422119, 422131, 
+    422144, 422149, 422155, 422161, 422168, 422174, 422181, 422188, 
+    422196, 422202, 422209, 422216, 422224, 422231, 422239, 422247, 
+    422256, 422262, 422269, 422276, 422284, 422291, 422299, 422307, 
+    422316, 422323, 422331, 422339, 422348, 422356, 422365, 422374, 
+    422384, 422390, 422397, 422404, 422412, 422419, 422427, 422435, 
+    422444, 422451, 422459, 422467, 422476, 422484, 422493, 422502, 
+    422512, 422519, 422527, 422535, 422544, 422552, 422561, 422570, 
+    422580, 422588, 422597, 422606, 422616, 422625, 422635, 422645, 
+    422656, 422662, 422669, 422676, 422684, 422691, 422699, 422707, 
+    422716, 422723, 422731, 422739, 422748, 422756, 422765, 422774, 
+    422784, 422791, 422799, 422807, 422816, 422824, 422833, 422842, 
+    422852, 422860, 422869, 422878, 422888, 422897, 422907, 422917, 
+    422928, 422935, 422943, 422951, 422960, 422968, 422977, 422986, 
+    422996, 423004, 423013, 423022, 423032, 423041, 423051, 423061, 
+    423072, 423080, 423089, 423098, 423108, 423117, 423127, 423137, 
+    423148, 423157, 423167, 423177, 423188, 423198, 423209, 423220, 
+    423232, 423238, 423245, 423252, 423260, 423267, 423275, 423283, 
+    423292, 423299, 423307, 423315, 423324, 423332, 423341, 423350, 
+    423360, 423367, 423375, 423383, 423392, 423400, 423409, 423418, 
+    423428, 423436, 423445, 423454, 423464, 423473, 423483, 423493, 
+    423504, 423511, 423519, 423527, 423536, 423544, 423553, 423562, 
+    423572, 423580, 423589, 423598, 423608, 423617, 423627, 423637, 
+    423648, 423656, 423665, 423674, 423684, 423693, 423703, 423713, 
+    423724, 423733, 423743, 423753, 423764, 423774, 423785, 423796, 
+    423808, 423815, 423823, 423831, 423840, 423848, 423857, 423866, 
+    423876, 423884, 423893, 423902, 423912, 423921, 423931, 423941, 
+    423952, 423960, 423969, 423978, 423988, 423997, 424007, 424017, 
+    424028, 424037, 424047, 424057, 424068, 424078, 424089, 424100, 
+    424112, 424120, 424129, 424138, 424148, 424157, 424167, 424177, 
+    424188, 424197, 424207, 424217, 424228, 424238, 424249, 424260, 
+    424272, 424281, 424291, 424301, 424312, 424322, 424333, 424344, 
+    424356, 424366, 424377, 424388, 424400, 424411, 424423, 424435, 
+    424448, 424454, 424461, 424468, 424476, 424483, 424491, 424499, 
+    424508, 424515, 424523, 424531, 424540, 424548, 424557, 424566, 
+    424576, 424583, 424591, 424599, 424608, 424616, 424625, 424634, 
+    424644, 424652, 424661, 424670, 424680, 424689, 424699, 424709, 
+    424720, 424727, 424735, 424743, 424752, 424760, 424769, 424778, 
+    424788, 424796, 424805, 424814, 424824, 424833, 424843, 424853, 
+    424864, 424872, 424881, 424890, 424900, 424909, 424919, 424929, 
+    424940, 424949, 424959, 424969, 424980, 424990, 425001, 425012, 
+    425024, 425031, 425039, 425047, 425056, 425064, 425073, 425082, 
+    425092, 425100, 425109, 425118, 425128, 425137, 425147, 425157, 
+    425168, 425176, 425185, 425194, 425204, 425213, 425223, 425233, 
+    425244, 425253, 425263, 425273, 425284, 425294, 425305, 425316, 
+    425328, 425336, 425345, 425354, 425364, 425373, 425383, 425393, 
+    425404, 425413, 425423, 425433, 425444, 425454, 425465, 425476, 
+    425488, 425497, 425507, 425517, 425528, 425538, 425549, 425560, 
+    425572, 425582, 425593, 425604, 425616, 425627, 425639, 425651, 
+    425664, 425671, 425679, 425687, 425696, 425704, 425713, 425722, 
+    425732, 425740, 425749, 425758, 425768, 425777, 425787, 425797, 
+    425808, 425816, 425825, 425834, 425844, 425853, 425863, 425873, 
+    425884, 425893, 425903, 425913, 425924, 425934, 425945, 425956, 
+    425968, 425976, 425985, 425994, 426004, 426013, 426023, 426033, 
+    426044, 426053, 426063, 426073, 426084, 426094, 426105, 426116, 
+    426128, 426137, 426147, 426157, 426168, 426178, 426189, 426200, 
+    426212, 426222, 426233, 426244, 426256, 426267, 426279, 426291, 
+    426304, 426312, 426321, 426330, 426340, 426349, 426359, 426369, 
+    426380, 426389, 426399, 426409, 426420, 426430, 426441, 426452, 
+    426464, 426473, 426483, 426493, 426504, 426514, 426525, 426536, 
+    426548, 426558, 426569, 426580, 426592, 426603, 426615, 426627, 
+    426640, 426649, 426659, 426669, 426680, 426690, 426701, 426712, 
+    426724, 426734, 426745, 426756, 426768, 426779, 426791, 426803, 
+    426816, 426826, 426837, 426848, 426860, 426871, 426883, 426895, 
+    426908, 426919, 426931, 426943, 426956, 426968, 426981, 426994, 
+    427008, 427012, 427017, 427022, 427028, 427033, 427039, 427045, 
+    427052, 427057, 427063, 427069, 427076, 427082, 427089, 427096, 
+    427104, 427109, 427115, 427121, 427128, 427134, 427141, 427148, 
+    427156, 427162, 427169, 427176, 427184, 427191, 427199, 427207, 
+    427216, 427221, 427227, 427233, 427240, 427246, 427253, 427260, 
+    427268, 427274, 427281, 427288, 427296, 427303, 427311, 427319, 
+    427328, 427334, 427341, 427348, 427356, 427363, 427371, 427379, 
+    427388, 427395, 427403, 427411, 427420, 427428, 427437, 427446, 
+    427456, 427461, 427467, 427473, 427480, 427486, 427493, 427500, 
+    427508, 427514, 427521, 427528, 427536, 427543, 427551, 427559, 
+    427568, 427574, 427581, 427588, 427596, 427603, 427611, 427619, 
+    427628, 427635, 427643, 427651, 427660, 427668, 427677, 427686, 
+    427696, 427702, 427709, 427716, 427724, 427731, 427739, 427747, 
+    427756, 427763, 427771, 427779, 427788, 427796, 427805, 427814, 
+    427824, 427831, 427839, 427847, 427856, 427864, 427873, 427882, 
+    427892, 427900, 427909, 427918, 427928, 427937, 427947, 427957, 
+    427968, 427973, 427979, 427985, 427992, 427998, 428005, 428012, 
+    428020, 428026, 428033, 428040, 428048, 428055, 428063, 428071, 
+    428080, 428086, 428093, 428100, 428108, 428115, 428123, 428131, 
+    428140, 428147, 428155, 428163, 428172, 428180, 428189, 428198, 
+    428208, 428214, 428221, 428228, 428236, 428243, 428251, 428259, 
+    428268, 428275, 428283, 428291, 428300, 428308, 428317, 428326, 
+    428336, 428343, 428351, 428359, 428368, 428376, 428385, 428394, 
+    428404, 428412, 428421, 428430, 428440, 428449, 428459, 428469, 
+    428480, 428486, 428493, 428500, 428508, 428515, 428523, 428531, 
+    428540, 428547, 428555, 428563, 428572, 428580, 428589, 428598, 
+    428608, 428615, 428623, 428631, 428640, 428648, 428657, 428666, 
+    428676, 428684, 428693, 428702, 428712, 428721, 428731, 428741, 
+    428752, 428759, 428767, 428775, 428784, 428792, 428801, 428810, 
+    428820, 428828, 428837, 428846, 428856, 428865, 428875, 428885, 
+    428896, 428904, 428913, 428922, 428932, 428941, 428951, 428961, 
+    428972, 428981, 428991, 429001, 429012, 429022, 429033, 429044, 
+    429056, 429061, 429067, 429073, 429080, 429086, 429093, 429100, 
+    429108, 429114, 429121, 429128, 429136, 429143, 429151, 429159, 
+    429168, 429174, 429181, 429188, 429196, 429203, 429211, 429219, 
+    429228, 429235, 429243, 429251, 429260, 429268, 429277, 429286, 
+    429296, 429302, 429309, 429316, 429324, 429331, 429339, 429347, 
+    429356, 429363, 429371, 429379, 429388, 429396, 429405, 429414, 
+    429424, 429431, 429439, 429447, 429456, 429464, 429473, 429482, 
+    429492, 429500, 429509, 429518, 429528, 429537, 429547, 429557, 
+    429568, 429574, 429581, 429588, 429596, 429603, 429611, 429619, 
+    429628, 429635, 429643, 429651, 429660, 429668, 429677, 429686, 
+    429696, 429703, 429711, 429719, 429728, 429736, 429745, 429754, 
+    429764, 429772, 429781, 429790, 429800, 429809, 429819, 429829, 
+    429840, 429847, 429855, 429863, 429872, 429880, 429889, 429898, 
+    429908, 429916, 429925, 429934, 429944, 429953, 429963, 429973, 
+    429984, 429992, 430001, 430010, 430020, 430029, 430039, 430049, 
+    430060, 430069, 430079, 430089, 430100, 430110, 430121, 430132, 
+    430144, 430150, 430157, 430164, 430172, 430179, 430187, 430195, 
+    430204, 430211, 430219, 430227, 430236, 430244, 430253, 430262, 
+    430272, 430279, 430287, 430295, 430304, 430312, 430321, 430330, 
+    430340, 430348, 430357, 430366, 430376, 430385, 430395, 430405, 
+    430416, 430423, 430431, 430439, 430448, 430456, 430465, 430474, 
+    430484, 430492, 430501, 430510, 430520, 430529, 430539, 430549, 
+    430560, 430568, 430577, 430586, 430596, 430605, 430615, 430625, 
+    430636, 430645, 430655, 430665, 430676, 430686, 430697, 430708, 
+    430720, 430727, 430735, 430743, 430752, 430760, 430769, 430778, 
+    430788, 430796, 430805, 430814, 430824, 430833, 430843, 430853, 
+    430864, 430872, 430881, 430890, 430900, 430909, 430919, 430929, 
+    430940, 430949, 430959, 430969, 430980, 430990, 431001, 431012, 
+    431024, 431032, 431041, 431050, 431060, 431069, 431079, 431089, 
+    431100, 431109, 431119, 431129, 431140, 431150, 431161, 431172, 
+    431184, 431193, 431203, 431213, 431224, 431234, 431245, 431256, 
+    431268, 431278, 431289, 431300, 431312, 431323, 431335, 431347, 
+    431360, 431365, 431371, 431377, 431384, 431390, 431397, 431404, 
+    431412, 431418, 431425, 431432, 431440, 431447, 431455, 431463, 
+    431472, 431478, 431485, 431492, 431500, 431507, 431515, 431523, 
+    431532, 431539, 431547, 431555, 431564, 431572, 431581, 431590, 
+    431600, 431606, 431613, 431620, 431628, 431635, 431643, 431651, 
+    431660, 431667, 431675, 431683, 431692, 431700, 431709, 431718, 
+    431728, 431735, 431743, 431751, 431760, 431768, 431777, 431786, 
+    431796, 431804, 431813, 431822, 431832, 431841, 431851, 431861, 
+    431872, 431878, 431885, 431892, 431900, 431907, 431915, 431923, 
+    431932, 431939, 431947, 431955, 431964, 431972, 431981, 431990, 
+    432000, 432007, 432015, 432023, 432032, 432040, 432049, 432058, 
+    432068, 432076, 432085, 432094, 432104, 432113, 432123, 432133, 
+    432144, 432151, 432159, 432167, 432176, 432184, 432193, 432202, 
+    432212, 432220, 432229, 432238, 432248, 432257, 432267, 432277, 
+    432288, 432296, 432305, 432314, 432324, 432333, 432343, 432353, 
+    432364, 432373, 432383, 432393, 432404, 432414, 432425, 432436, 
+    432448, 432454, 432461, 432468, 432476, 432483, 432491, 432499, 
+    432508, 432515, 432523, 432531, 432540, 432548, 432557, 432566, 
+    432576, 432583, 432591, 432599, 432608, 432616, 432625, 432634, 
+    432644, 432652, 432661, 432670, 432680, 432689, 432699, 432709, 
+    432720, 432727, 432735, 432743, 432752, 432760, 432769, 432778, 
+    432788, 432796, 432805, 432814, 432824, 432833, 432843, 432853, 
+    432864, 432872, 432881, 432890, 432900, 432909, 432919, 432929, 
+    432940, 432949, 432959, 432969, 432980, 432990, 433001, 433012, 
+    433024, 433031, 433039, 433047, 433056, 433064, 433073, 433082, 
+    433092, 433100, 433109, 433118, 433128, 433137, 433147, 433157, 
+    433168, 433176, 433185, 433194, 433204, 433213, 433223, 433233, 
+    433244, 433253, 433263, 433273, 433284, 433294, 433305, 433316, 
+    433328, 433336, 433345, 433354, 433364, 433373, 433383, 433393, 
+    433404, 433413, 433423, 433433, 433444, 433454, 433465, 433476, 
+    433488, 433497, 433507, 433517, 433528, 433538, 433549, 433560, 
+    433572, 433582, 433593, 433604, 433616, 433627, 433639, 433651, 
+    433664, 433670, 433677, 433684, 433692, 433699, 433707, 433715, 
+    433724, 433731, 433739, 433747, 433756, 433764, 433773, 433782, 
+    433792, 433799, 433807, 433815, 433824, 433832, 433841, 433850, 
+    433860, 433868, 433877, 433886, 433896, 433905, 433915, 433925, 
+    433936, 433943, 433951, 433959, 433968, 433976, 433985, 433994, 
+    434004, 434012, 434021, 434030, 434040, 434049, 434059, 434069, 
+    434080, 434088, 434097, 434106, 434116, 434125, 434135, 434145, 
+    434156, 434165, 434175, 434185, 434196, 434206, 434217, 434228, 
+    434240, 434247, 434255, 434263, 434272, 434280, 434289, 434298, 
+    434308, 434316, 434325, 434334, 434344, 434353, 434363, 434373, 
+    434384, 434392, 434401, 434410, 434420, 434429, 434439, 434449, 
+    434460, 434469, 434479, 434489, 434500, 434510, 434521, 434532, 
+    434544, 434552, 434561, 434570, 434580, 434589, 434599, 434609, 
+    434620, 434629, 434639, 434649, 434660, 434670, 434681, 434692, 
+    434704, 434713, 434723, 434733, 434744, 434754, 434765, 434776, 
+    434788, 434798, 434809, 434820, 434832, 434843, 434855, 434867, 
+    434880, 434887, 434895, 434903, 434912, 434920, 434929, 434938, 
+    434948, 434956, 434965, 434974, 434984, 434993, 435003, 435013, 
+    435024, 435032, 435041, 435050, 435060, 435069, 435079, 435089, 
+    435100, 435109, 435119, 435129, 435140, 435150, 435161, 435172, 
+    435184, 435192, 435201, 435210, 435220, 435229, 435239, 435249, 
+    435260, 435269, 435279, 435289, 435300, 435310, 435321, 435332, 
+    435344, 435353, 435363, 435373, 435384, 435394, 435405, 435416, 
+    435428, 435438, 435449, 435460, 435472, 435483, 435495, 435507, 
+    435520, 435528, 435537, 435546, 435556, 435565, 435575, 435585, 
+    435596, 435605, 435615, 435625, 435636, 435646, 435657, 435668, 
+    435680, 435689, 435699, 435709, 435720, 435730, 435741, 435752, 
+    435764, 435774, 435785, 435796, 435808, 435819, 435831, 435843, 
+    435856, 435865, 435875, 435885, 435896, 435906, 435917, 435928, 
+    435940, 435950, 435961, 435972, 435984, 435995, 436007, 436019, 
+    436032, 436042, 436053, 436064, 436076, 436087, 436099, 436111, 
+    436124, 436135, 436147, 436159, 436172, 436184, 436197, 436210, 
+    436224, 436229, 436235, 436241, 436248, 436254, 436261, 436268, 
+    436276, 436282, 436289, 436296, 436304, 436311, 436319, 436327, 
+    436336, 436342, 436349, 436356, 436364, 436371, 436379, 436387, 
+    436396, 436403, 436411, 436419, 436428, 436436, 436445, 436454, 
+    436464, 436470, 436477, 436484, 436492, 436499, 436507, 436515, 
+    436524, 436531, 436539, 436547, 436556, 436564, 436573, 436582, 
+    436592, 436599, 436607, 436615, 436624, 436632, 436641, 436650, 
+    436660, 436668, 436677, 436686, 436696, 436705, 436715, 436725, 
+    436736, 436742, 436749, 436756, 436764, 436771, 436779, 436787, 
+    436796, 436803, 436811, 436819, 436828, 436836, 436845, 436854, 
+    436864, 436871, 436879, 436887, 436896, 436904, 436913, 436922, 
+    436932, 436940, 436949, 436958, 436968, 436977, 436987, 436997, 
+    437008, 437015, 437023, 437031, 437040, 437048, 437057, 437066, 
+    437076, 437084, 437093, 437102, 437112, 437121, 437131, 437141, 
+    437152, 437160, 437169, 437178, 437188, 437197, 437207, 437217, 
+    437228, 437237, 437247, 437257, 437268, 437278, 437289, 437300, 
+    437312, 437318, 437325, 437332, 437340, 437347, 437355, 437363, 
+    437372, 437379, 437387, 437395, 437404, 437412, 437421, 437430, 
+    437440, 437447, 437455, 437463, 437472, 437480, 437489, 437498, 
+    437508, 437516, 437525, 437534, 437544, 437553, 437563, 437573, 
+    437584, 437591, 437599, 437607, 437616, 437624, 437633, 437642, 
+    437652, 437660, 437669, 437678, 437688, 437697, 437707, 437717, 
+    437728, 437736, 437745, 437754, 437764, 437773, 437783, 437793, 
+    437804, 437813, 437823, 437833, 437844, 437854, 437865, 437876, 
+    437888, 437895, 437903, 437911, 437920, 437928, 437937, 437946, 
+    437956, 437964, 437973, 437982, 437992, 438001, 438011, 438021, 
+    438032, 438040, 438049, 438058, 438068, 438077, 438087, 438097, 
+    438108, 438117, 438127, 438137, 438148, 438158, 438169, 438180, 
+    438192, 438200, 438209, 438218, 438228, 438237, 438247, 438257, 
+    438268, 438277, 438287, 438297, 438308, 438318, 438329, 438340, 
+    438352, 438361, 438371, 438381, 438392, 438402, 438413, 438424, 
+    438436, 438446, 438457, 438468, 438480, 438491, 438503, 438515, 
+    438528, 438534, 438541, 438548, 438556, 438563, 438571, 438579, 
+    438588, 438595, 438603, 438611, 438620, 438628, 438637, 438646, 
+    438656, 438663, 438671, 438679, 438688, 438696, 438705, 438714, 
+    438724, 438732, 438741, 438750, 438760, 438769, 438779, 438789, 
+    438800, 438807, 438815, 438823, 438832, 438840, 438849, 438858, 
+    438868, 438876, 438885, 438894, 438904, 438913, 438923, 438933, 
+    438944, 438952, 438961, 438970, 438980, 438989, 438999, 439009, 
+    439020, 439029, 439039, 439049, 439060, 439070, 439081, 439092, 
+    439104, 439111, 439119, 439127, 439136, 439144, 439153, 439162, 
+    439172, 439180, 439189, 439198, 439208, 439217, 439227, 439237, 
+    439248, 439256, 439265, 439274, 439284, 439293, 439303, 439313, 
+    439324, 439333, 439343, 439353, 439364, 439374, 439385, 439396, 
+    439408, 439416, 439425, 439434, 439444, 439453, 439463, 439473, 
+    439484, 439493, 439503, 439513, 439524, 439534, 439545, 439556, 
+    439568, 439577, 439587, 439597, 439608, 439618, 439629, 439640, 
+    439652, 439662, 439673, 439684, 439696, 439707, 439719, 439731, 
+    439744, 439751, 439759, 439767, 439776, 439784, 439793, 439802, 
+    439812, 439820, 439829, 439838, 439848, 439857, 439867, 439877, 
+    439888, 439896, 439905, 439914, 439924, 439933, 439943, 439953, 
+    439964, 439973, 439983, 439993, 440004, 440014, 440025, 440036, 
+    440048, 440056, 440065, 440074, 440084, 440093, 440103, 440113, 
+    440124, 440133, 440143, 440153, 440164, 440174, 440185, 440196, 
+    440208, 440217, 440227, 440237, 440248, 440258, 440269, 440280, 
+    440292, 440302, 440313, 440324, 440336, 440347, 440359, 440371, 
+    440384, 440392, 440401, 440410, 440420, 440429, 440439, 440449, 
+    440460, 440469, 440479, 440489, 440500, 440510, 440521, 440532, 
+    440544, 440553, 440563, 440573, 440584, 440594, 440605, 440616, 
+    440628, 440638, 440649, 440660, 440672, 440683, 440695, 440707, 
+    440720, 440729, 440739, 440749, 440760, 440770, 440781, 440792, 
+    440804, 440814, 440825, 440836, 440848, 440859, 440871, 440883, 
+    440896, 440906, 440917, 440928, 440940, 440951, 440963, 440975, 
+    440988, 440999, 441011, 441023, 441036, 441048, 441061, 441074, 
+    441088, 441094, 441101, 441108, 441116, 441123, 441131, 441139, 
+    441148, 441155, 441163, 441171, 441180, 441188, 441197, 441206, 
+    441216, 441223, 441231, 441239, 441248, 441256, 441265, 441274, 
+    441284, 441292, 441301, 441310, 441320, 441329, 441339, 441349, 
+    441360, 441367, 441375, 441383, 441392, 441400, 441409, 441418, 
+    441428, 441436, 441445, 441454, 441464, 441473, 441483, 441493, 
+    441504, 441512, 441521, 441530, 441540, 441549, 441559, 441569, 
+    441580, 441589, 441599, 441609, 441620, 441630, 441641, 441652, 
+    441664, 441671, 441679, 441687, 441696, 441704, 441713, 441722, 
+    441732, 441740, 441749, 441758, 441768, 441777, 441787, 441797, 
+    441808, 441816, 441825, 441834, 441844, 441853, 441863, 441873, 
+    441884, 441893, 441903, 441913, 441924, 441934, 441945, 441956, 
+    441968, 441976, 441985, 441994, 442004, 442013, 442023, 442033, 
+    442044, 442053, 442063, 442073, 442084, 442094, 442105, 442116, 
+    442128, 442137, 442147, 442157, 442168, 442178, 442189, 442200, 
+    442212, 442222, 442233, 442244, 442256, 442267, 442279, 442291, 
+    442304, 442311, 442319, 442327, 442336, 442344, 442353, 442362, 
+    442372, 442380, 442389, 442398, 442408, 442417, 442427, 442437, 
+    442448, 442456, 442465, 442474, 442484, 442493, 442503, 442513, 
+    442524, 442533, 442543, 442553, 442564, 442574, 442585, 442596, 
+    442608, 442616, 442625, 442634, 442644, 442653, 442663, 442673, 
+    442684, 442693, 442703, 442713, 442724, 442734, 442745, 442756, 
+    442768, 442777, 442787, 442797, 442808, 442818, 442829, 442840, 
+    442852, 442862, 442873, 442884, 442896, 442907, 442919, 442931, 
+    442944, 442952, 442961, 442970, 442980, 442989, 442999, 443009, 
+    443020, 443029, 443039, 443049, 443060, 443070, 443081, 443092, 
+    443104, 443113, 443123, 443133, 443144, 443154, 443165, 443176, 
+    443188, 443198, 443209, 443220, 443232, 443243, 443255, 443267, 
+    443280, 443289, 443299, 443309, 443320, 443330, 443341, 443352, 
+    443364, 443374, 443385, 443396, 443408, 443419, 443431, 443443, 
+    443456, 443466, 443477, 443488, 443500, 443511, 443523, 443535, 
+    443548, 443559, 443571, 443583, 443596, 443608, 443621, 443634, 
+    443648, 443655, 443663, 443671, 443680, 443688, 443697, 443706, 
+    443716, 443724, 443733, 443742, 443752, 443761, 443771, 443781, 
+    443792, 443800, 443809, 443818, 443828, 443837, 443847, 443857, 
+    443868, 443877, 443887, 443897, 443908, 443918, 443929, 443940, 
+    443952, 443960, 443969, 443978, 443988, 443997, 444007, 444017, 
+    444028, 444037, 444047, 444057, 444068, 444078, 444089, 444100, 
+    444112, 444121, 444131, 444141, 444152, 444162, 444173, 444184, 
+    444196, 444206, 444217, 444228, 444240, 444251, 444263, 444275, 
+    444288, 444296, 444305, 444314, 444324, 444333, 444343, 444353, 
+    444364, 444373, 444383, 444393, 444404, 444414, 444425, 444436, 
+    444448, 444457, 444467, 444477, 444488, 444498, 444509, 444520, 
+    444532, 444542, 444553, 444564, 444576, 444587, 444599, 444611, 
+    444624, 444633, 444643, 444653, 444664, 444674, 444685, 444696, 
+    444708, 444718, 444729, 444740, 444752, 444763, 444775, 444787, 
+    444800, 444810, 444821, 444832, 444844, 444855, 444867, 444879, 
+    444892, 444903, 444915, 444927, 444940, 444952, 444965, 444978, 
+    444992, 445000, 445009, 445018, 445028, 445037, 445047, 445057, 
+    445068, 445077, 445087, 445097, 445108, 445118, 445129, 445140, 
+    445152, 445161, 445171, 445181, 445192, 445202, 445213, 445224, 
+    445236, 445246, 445257, 445268, 445280, 445291, 445303, 445315, 
+    445328, 445337, 445347, 445357, 445368, 445378, 445389, 445400, 
+    445412, 445422, 445433, 445444, 445456, 445467, 445479, 445491, 
+    445504, 445514, 445525, 445536, 445548, 445559, 445571, 445583, 
+    445596, 445607, 445619, 445631, 445644, 445656, 445669, 445682, 
+    445696, 445705, 445715, 445725, 445736, 445746, 445757, 445768, 
+    445780, 445790, 445801, 445812, 445824, 445835, 445847, 445859, 
+    445872, 445882, 445893, 445904, 445916, 445927, 445939, 445951, 
+    445964, 445975, 445987, 445999, 446012, 446024, 446037, 446050, 
+    446064, 446074, 446085, 446096, 446108, 446119, 446131, 446143, 
+    446156, 446167, 446179, 446191, 446204, 446216, 446229, 446242, 
+    446256, 446267, 446279, 446291, 446304, 446316, 446329, 446342, 
+    446356, 446368, 446381, 446394, 446408, 446421, 446435, 446449, 
+    446464, 446467, 446471, 446475, 446480, 446484, 446489, 446494, 
+    446500, 446504, 446509, 446514, 446520, 446525, 446531, 446537, 
+    446544, 446548, 446553, 446558, 446564, 446569, 446575, 446581, 
+    446588, 446593, 446599, 446605, 446612, 446618, 446625, 446632, 
+    446640, 446644, 446649, 446654, 446660, 446665, 446671, 446677, 
+    446684, 446689, 446695, 446701, 446708, 446714, 446721, 446728, 
+    446736, 446741, 446747, 446753, 446760, 446766, 446773, 446780, 
+    446788, 446794, 446801, 446808, 446816, 446823, 446831, 446839, 
+    446848, 446852, 446857, 446862, 446868, 446873, 446879, 446885, 
+    446892, 446897, 446903, 446909, 446916, 446922, 446929, 446936, 
+    446944, 446949, 446955, 446961, 446968, 446974, 446981, 446988, 
+    446996, 447002, 447009, 447016, 447024, 447031, 447039, 447047, 
+    447056, 447061, 447067, 447073, 447080, 447086, 447093, 447100, 
+    447108, 447114, 447121, 447128, 447136, 447143, 447151, 447159, 
+    447168, 447174, 447181, 447188, 447196, 447203, 447211, 447219, 
+    447228, 447235, 447243, 447251, 447260, 447268, 447277, 447286, 
+    447296, 447300, 447305, 447310, 447316, 447321, 447327, 447333, 
+    447340, 447345, 447351, 447357, 447364, 447370, 447377, 447384, 
+    447392, 447397, 447403, 447409, 447416, 447422, 447429, 447436, 
+    447444, 447450, 447457, 447464, 447472, 447479, 447487, 447495, 
+    447504, 447509, 447515, 447521, 447528, 447534, 447541, 447548, 
+    447556, 447562, 447569, 447576, 447584, 447591, 447599, 447607, 
+    447616, 447622, 447629, 447636, 447644, 447651, 447659, 447667, 
+    447676, 447683, 447691, 447699, 447708, 447716, 447725, 447734, 
+    447744, 447749, 447755, 447761, 447768, 447774, 447781, 447788, 
+    447796, 447802, 447809, 447816, 447824, 447831, 447839, 447847, 
+    447856, 447862, 447869, 447876, 447884, 447891, 447899, 447907, 
+    447916, 447923, 447931, 447939, 447948, 447956, 447965, 447974, 
+    447984, 447990, 447997, 448004, 448012, 448019, 448027, 448035, 
+    448044, 448051, 448059, 448067, 448076, 448084, 448093, 448102, 
+    448112, 448119, 448127, 448135, 448144, 448152, 448161, 448170, 
+    448180, 448188, 448197, 448206, 448216, 448225, 448235, 448245, 
+    448256, 448260, 448265, 448270, 448276, 448281, 448287, 448293, 
+    448300, 448305, 448311, 448317, 448324, 448330, 448337, 448344, 
+    448352, 448357, 448363, 448369, 448376, 448382, 448389, 448396, 
+    448404, 448410, 448417, 448424, 448432, 448439, 448447, 448455, 
+    448464, 448469, 448475, 448481, 448488, 448494, 448501, 448508, 
+    448516, 448522, 448529, 448536, 448544, 448551, 448559, 448567, 
+    448576, 448582, 448589, 448596, 448604, 448611, 448619, 448627, 
+    448636, 448643, 448651, 448659, 448668, 448676, 448685, 448694, 
+    448704, 448709, 448715, 448721, 448728, 448734, 448741, 448748, 
+    448756, 448762, 448769, 448776, 448784, 448791, 448799, 448807, 
+    448816, 448822, 448829, 448836, 448844, 448851, 448859, 448867, 
+    448876, 448883, 448891, 448899, 448908, 448916, 448925, 448934, 
+    448944, 448950, 448957, 448964, 448972, 448979, 448987, 448995, 
+    449004, 449011, 449019, 449027, 449036, 449044, 449053, 449062, 
+    449072, 449079, 449087, 449095, 449104, 449112, 449121, 449130, 
+    449140, 449148, 449157, 449166, 449176, 449185, 449195, 449205, 
+    449216, 449221, 449227, 449233, 449240, 449246, 449253, 449260, 
+    449268, 449274, 449281, 449288, 449296, 449303, 449311, 449319, 
+    449328, 449334, 449341, 449348, 449356, 449363, 449371, 449379, 
+    449388, 449395, 449403, 449411, 449420, 449428, 449437, 449446, 
+    449456, 449462, 449469, 449476, 449484, 449491, 449499, 449507, 
+    449516, 449523, 449531, 449539, 449548, 449556, 449565, 449574, 
+    449584, 449591, 449599, 449607, 449616, 449624, 449633, 449642, 
+    449652, 449660, 449669, 449678, 449688, 449697, 449707, 449717, 
+    449728, 449734, 449741, 449748, 449756, 449763, 449771, 449779, 
+    449788, 449795, 449803, 449811, 449820, 449828, 449837, 449846, 
+    449856, 449863, 449871, 449879, 449888, 449896, 449905, 449914, 
+    449924, 449932, 449941, 449950, 449960, 449969, 449979, 449989, 
+    450000, 450007, 450015, 450023, 450032, 450040, 450049, 450058, 
+    450068, 450076, 450085, 450094, 450104, 450113, 450123, 450133, 
+    450144, 450152, 450161, 450170, 450180, 450189, 450199, 450209, 
+    450220, 450229, 450239, 450249, 450260, 450270, 450281, 450292, 
+    450304, 450308, 450313, 450318, 450324, 450329, 450335, 450341, 
+    450348, 450353, 450359, 450365, 450372, 450378, 450385, 450392, 
+    450400, 450405, 450411, 450417, 450424, 450430, 450437, 450444, 
+    450452, 450458, 450465, 450472, 450480, 450487, 450495, 450503, 
+    450512, 450517, 450523, 450529, 450536, 450542, 450549, 450556, 
+    450564, 450570, 450577, 450584, 450592, 450599, 450607, 450615, 
+    450624, 450630, 450637, 450644, 450652, 450659, 450667, 450675, 
+    450684, 450691, 450699, 450707, 450716, 450724, 450733, 450742, 
+    450752, 450757, 450763, 450769, 450776, 450782, 450789, 450796, 
+    450804, 450810, 450817, 450824, 450832, 450839, 450847, 450855, 
+    450864, 450870, 450877, 450884, 450892, 450899, 450907, 450915, 
+    450924, 450931, 450939, 450947, 450956, 450964, 450973, 450982, 
+    450992, 450998, 451005, 451012, 451020, 451027, 451035, 451043, 
+    451052, 451059, 451067, 451075, 451084, 451092, 451101, 451110, 
+    451120, 451127, 451135, 451143, 451152, 451160, 451169, 451178, 
+    451188, 451196, 451205, 451214, 451224, 451233, 451243, 451253, 
+    451264, 451269, 451275, 451281, 451288, 451294, 451301, 451308, 
+    451316, 451322, 451329, 451336, 451344, 451351, 451359, 451367, 
+    451376, 451382, 451389, 451396, 451404, 451411, 451419, 451427, 
+    451436, 451443, 451451, 451459, 451468, 451476, 451485, 451494, 
+    451504, 451510, 451517, 451524, 451532, 451539, 451547, 451555, 
+    451564, 451571, 451579, 451587, 451596, 451604, 451613, 451622, 
+    451632, 451639, 451647, 451655, 451664, 451672, 451681, 451690, 
+    451700, 451708, 451717, 451726, 451736, 451745, 451755, 451765, 
+    451776, 451782, 451789, 451796, 451804, 451811, 451819, 451827, 
+    451836, 451843, 451851, 451859, 451868, 451876, 451885, 451894, 
+    451904, 451911, 451919, 451927, 451936, 451944, 451953, 451962, 
+    451972, 451980, 451989, 451998, 452008, 452017, 452027, 452037, 
+    452048, 452055, 452063, 452071, 452080, 452088, 452097, 452106, 
+    452116, 452124, 452133, 452142, 452152, 452161, 452171, 452181, 
+    452192, 452200, 452209, 452218, 452228, 452237, 452247, 452257, 
+    452268, 452277, 452287, 452297, 452308, 452318, 452329, 452340, 
+    452352, 452357, 452363, 452369, 452376, 452382, 452389, 452396, 
+    452404, 452410, 452417, 452424, 452432, 452439, 452447, 452455, 
+    452464, 452470, 452477, 452484, 452492, 452499, 452507, 452515, 
+    452524, 452531, 452539, 452547, 452556, 452564, 452573, 452582, 
+    452592, 452598, 452605, 452612, 452620, 452627, 452635, 452643, 
+    452652, 452659, 452667, 452675, 452684, 452692, 452701, 452710, 
+    452720, 452727, 452735, 452743, 452752, 452760, 452769, 452778, 
+    452788, 452796, 452805, 452814, 452824, 452833, 452843, 452853, 
+    452864, 452870, 452877, 452884, 452892, 452899, 452907, 452915, 
+    452924, 452931, 452939, 452947, 452956, 452964, 452973, 452982, 
+    452992, 452999, 453007, 453015, 453024, 453032, 453041, 453050, 
+    453060, 453068, 453077, 453086, 453096, 453105, 453115, 453125, 
+    453136, 453143, 453151, 453159, 453168, 453176, 453185, 453194, 
+    453204, 453212, 453221, 453230, 453240, 453249, 453259, 453269, 
+    453280, 453288, 453297, 453306, 453316, 453325, 453335, 453345, 
+    453356, 453365, 453375, 453385, 453396, 453406, 453417, 453428, 
+    453440, 453446, 453453, 453460, 453468, 453475, 453483, 453491, 
+    453500, 453507, 453515, 453523, 453532, 453540, 453549, 453558, 
+    453568, 453575, 453583, 453591, 453600, 453608, 453617, 453626, 
+    453636, 453644, 453653, 453662, 453672, 453681, 453691, 453701, 
+    453712, 453719, 453727, 453735, 453744, 453752, 453761, 453770, 
+    453780, 453788, 453797, 453806, 453816, 453825, 453835, 453845, 
+    453856, 453864, 453873, 453882, 453892, 453901, 453911, 453921, 
+    453932, 453941, 453951, 453961, 453972, 453982, 453993, 454004, 
+    454016, 454023, 454031, 454039, 454048, 454056, 454065, 454074, 
+    454084, 454092, 454101, 454110, 454120, 454129, 454139, 454149, 
+    454160, 454168, 454177, 454186, 454196, 454205, 454215, 454225, 
+    454236, 454245, 454255, 454265, 454276, 454286, 454297, 454308, 
+    454320, 454328, 454337, 454346, 454356, 454365, 454375, 454385, 
+    454396, 454405, 454415, 454425, 454436, 454446, 454457, 454468, 
+    454480, 454489, 454499, 454509, 454520, 454530, 454541, 454552, 
+    454564, 454574, 454585, 454596, 454608, 454619, 454631, 454643, 
+    454656, 454660, 454665, 454670, 454676, 454681, 454687, 454693, 
+    454700, 454705, 454711, 454717, 454724, 454730, 454737, 454744, 
+    454752, 454757, 454763, 454769, 454776, 454782, 454789, 454796, 
+    454804, 454810, 454817, 454824, 454832, 454839, 454847, 454855, 
+    454864, 454869, 454875, 454881, 454888, 454894, 454901, 454908, 
+    454916, 454922, 454929, 454936, 454944, 454951, 454959, 454967, 
+    454976, 454982, 454989, 454996, 455004, 455011, 455019, 455027, 
+    455036, 455043, 455051, 455059, 455068, 455076, 455085, 455094, 
+    455104, 455109, 455115, 455121, 455128, 455134, 455141, 455148, 
+    455156, 455162, 455169, 455176, 455184, 455191, 455199, 455207, 
+    455216, 455222, 455229, 455236, 455244, 455251, 455259, 455267, 
+    455276, 455283, 455291, 455299, 455308, 455316, 455325, 455334, 
+    455344, 455350, 455357, 455364, 455372, 455379, 455387, 455395, 
+    455404, 455411, 455419, 455427, 455436, 455444, 455453, 455462, 
+    455472, 455479, 455487, 455495, 455504, 455512, 455521, 455530, 
+    455540, 455548, 455557, 455566, 455576, 455585, 455595, 455605, 
+    455616, 455621, 455627, 455633, 455640, 455646, 455653, 455660, 
+    455668, 455674, 455681, 455688, 455696, 455703, 455711, 455719, 
+    455728, 455734, 455741, 455748, 455756, 455763, 455771, 455779, 
+    455788, 455795, 455803, 455811, 455820, 455828, 455837, 455846, 
+    455856, 455862, 455869, 455876, 455884, 455891, 455899, 455907, 
+    455916, 455923, 455931, 455939, 455948, 455956, 455965, 455974, 
+    455984, 455991, 455999, 456007, 456016, 456024, 456033, 456042, 
+    456052, 456060, 456069, 456078, 456088, 456097, 456107, 456117, 
+    456128, 456134, 456141, 456148, 456156, 456163, 456171, 456179, 
+    456188, 456195, 456203, 456211, 456220, 456228, 456237, 456246, 
+    456256, 456263, 456271, 456279, 456288, 456296, 456305, 456314, 
+    456324, 456332, 456341, 456350, 456360, 456369, 456379, 456389, 
+    456400, 456407, 456415, 456423, 456432, 456440, 456449, 456458, 
+    456468, 456476, 456485, 456494, 456504, 456513, 456523, 456533, 
+    456544, 456552, 456561, 456570, 456580, 456589, 456599, 456609, 
+    456620, 456629, 456639, 456649, 456660, 456670, 456681, 456692, 
+    456704, 456709, 456715, 456721, 456728, 456734, 456741, 456748, 
+    456756, 456762, 456769, 456776, 456784, 456791, 456799, 456807, 
+    456816, 456822, 456829, 456836, 456844, 456851, 456859, 456867, 
+    456876, 456883, 456891, 456899, 456908, 456916, 456925, 456934, 
+    456944, 456950, 456957, 456964, 456972, 456979, 456987, 456995, 
+    457004, 457011, 457019, 457027, 457036, 457044, 457053, 457062, 
+    457072, 457079, 457087, 457095, 457104, 457112, 457121, 457130, 
+    457140, 457148, 457157, 457166, 457176, 457185, 457195, 457205, 
+    457216, 457222, 457229, 457236, 457244, 457251, 457259, 457267, 
+    457276, 457283, 457291, 457299, 457308, 457316, 457325, 457334, 
+    457344, 457351, 457359, 457367, 457376, 457384, 457393, 457402, 
+    457412, 457420, 457429, 457438, 457448, 457457, 457467, 457477, 
+    457488, 457495, 457503, 457511, 457520, 457528, 457537, 457546, 
+    457556, 457564, 457573, 457582, 457592, 457601, 457611, 457621, 
+    457632, 457640, 457649, 457658, 457668, 457677, 457687, 457697, 
+    457708, 457717, 457727, 457737, 457748, 457758, 457769, 457780, 
+    457792, 457798, 457805, 457812, 457820, 457827, 457835, 457843, 
+    457852, 457859, 457867, 457875, 457884, 457892, 457901, 457910, 
+    457920, 457927, 457935, 457943, 457952, 457960, 457969, 457978, 
+    457988, 457996, 458005, 458014, 458024, 458033, 458043, 458053, 
+    458064, 458071, 458079, 458087, 458096, 458104, 458113, 458122, 
+    458132, 458140, 458149, 458158, 458168, 458177, 458187, 458197, 
+    458208, 458216, 458225, 458234, 458244, 458253, 458263, 458273, 
+    458284, 458293, 458303, 458313, 458324, 458334, 458345, 458356, 
+    458368, 458375, 458383, 458391, 458400, 458408, 458417, 458426, 
+    458436, 458444, 458453, 458462, 458472, 458481, 458491, 458501, 
+    458512, 458520, 458529, 458538, 458548, 458557, 458567, 458577, 
+    458588, 458597, 458607, 458617, 458628, 458638, 458649, 458660, 
+    458672, 458680, 458689, 458698, 458708, 458717, 458727, 458737, 
+    458748, 458757, 458767, 458777, 458788, 458798, 458809, 458820, 
+    458832, 458841, 458851, 458861, 458872, 458882, 458893, 458904, 
+    458916, 458926, 458937, 458948, 458960, 458971, 458983, 458995, 
+    459008, 459013, 459019, 459025, 459032, 459038, 459045, 459052, 
+    459060, 459066, 459073, 459080, 459088, 459095, 459103, 459111, 
+    459120, 459126, 459133, 459140, 459148, 459155, 459163, 459171, 
+    459180, 459187, 459195, 459203, 459212, 459220, 459229, 459238, 
+    459248, 459254, 459261, 459268, 459276, 459283, 459291, 459299, 
+    459308, 459315, 459323, 459331, 459340, 459348, 459357, 459366, 
+    459376, 459383, 459391, 459399, 459408, 459416, 459425, 459434, 
+    459444, 459452, 459461, 459470, 459480, 459489, 459499, 459509, 
+    459520, 459526, 459533, 459540, 459548, 459555, 459563, 459571, 
+    459580, 459587, 459595, 459603, 459612, 459620, 459629, 459638, 
+    459648, 459655, 459663, 459671, 459680, 459688, 459697, 459706, 
+    459716, 459724, 459733, 459742, 459752, 459761, 459771, 459781, 
+    459792, 459799, 459807, 459815, 459824, 459832, 459841, 459850, 
+    459860, 459868, 459877, 459886, 459896, 459905, 459915, 459925, 
+    459936, 459944, 459953, 459962, 459972, 459981, 459991, 460001, 
+    460012, 460021, 460031, 460041, 460052, 460062, 460073, 460084, 
+    460096, 460102, 460109, 460116, 460124, 460131, 460139, 460147, 
+    460156, 460163, 460171, 460179, 460188, 460196, 460205, 460214, 
+    460224, 460231, 460239, 460247, 460256, 460264, 460273, 460282, 
+    460292, 460300, 460309, 460318, 460328, 460337, 460347, 460357, 
+    460368, 460375, 460383, 460391, 460400, 460408, 460417, 460426, 
+    460436, 460444, 460453, 460462, 460472, 460481, 460491, 460501, 
+    460512, 460520, 460529, 460538, 460548, 460557, 460567, 460577, 
+    460588, 460597, 460607, 460617, 460628, 460638, 460649, 460660, 
+    460672, 460679, 460687, 460695, 460704, 460712, 460721, 460730, 
+    460740, 460748, 460757, 460766, 460776, 460785, 460795, 460805, 
+    460816, 460824, 460833, 460842, 460852, 460861, 460871, 460881, 
+    460892, 460901, 460911, 460921, 460932, 460942, 460953, 460964, 
+    460976, 460984, 460993, 461002, 461012, 461021, 461031, 461041, 
+    461052, 461061, 461071, 461081, 461092, 461102, 461113, 461124, 
+    461136, 461145, 461155, 461165, 461176, 461186, 461197, 461208, 
+    461220, 461230, 461241, 461252, 461264, 461275, 461287, 461299, 
+    461312, 461318, 461325, 461332, 461340, 461347, 461355, 461363, 
+    461372, 461379, 461387, 461395, 461404, 461412, 461421, 461430, 
+    461440, 461447, 461455, 461463, 461472, 461480, 461489, 461498, 
+    461508, 461516, 461525, 461534, 461544, 461553, 461563, 461573, 
+    461584, 461591, 461599, 461607, 461616, 461624, 461633, 461642, 
+    461652, 461660, 461669, 461678, 461688, 461697, 461707, 461717, 
+    461728, 461736, 461745, 461754, 461764, 461773, 461783, 461793, 
+    461804, 461813, 461823, 461833, 461844, 461854, 461865, 461876, 
+    461888, 461895, 461903, 461911, 461920, 461928, 461937, 461946, 
+    461956, 461964, 461973, 461982, 461992, 462001, 462011, 462021, 
+    462032, 462040, 462049, 462058, 462068, 462077, 462087, 462097, 
+    462108, 462117, 462127, 462137, 462148, 462158, 462169, 462180, 
+    462192, 462200, 462209, 462218, 462228, 462237, 462247, 462257, 
+    462268, 462277, 462287, 462297, 462308, 462318, 462329, 462340, 
+    462352, 462361, 462371, 462381, 462392, 462402, 462413, 462424, 
+    462436, 462446, 462457, 462468, 462480, 462491, 462503, 462515, 
+    462528, 462535, 462543, 462551, 462560, 462568, 462577, 462586, 
+    462596, 462604, 462613, 462622, 462632, 462641, 462651, 462661, 
+    462672, 462680, 462689, 462698, 462708, 462717, 462727, 462737, 
+    462748, 462757, 462767, 462777, 462788, 462798, 462809, 462820, 
+    462832, 462840, 462849, 462858, 462868, 462877, 462887, 462897, 
+    462908, 462917, 462927, 462937, 462948, 462958, 462969, 462980, 
+    462992, 463001, 463011, 463021, 463032, 463042, 463053, 463064, 
+    463076, 463086, 463097, 463108, 463120, 463131, 463143, 463155, 
+    463168, 463176, 463185, 463194, 463204, 463213, 463223, 463233, 
+    463244, 463253, 463263, 463273, 463284, 463294, 463305, 463316, 
+    463328, 463337, 463347, 463357, 463368, 463378, 463389, 463400, 
+    463412, 463422, 463433, 463444, 463456, 463467, 463479, 463491, 
+    463504, 463513, 463523, 463533, 463544, 463554, 463565, 463576, 
+    463588, 463598, 463609, 463620, 463632, 463643, 463655, 463667, 
+    463680, 463690, 463701, 463712, 463724, 463735, 463747, 463759, 
+    463772, 463783, 463795, 463807, 463820, 463832, 463845, 463858, 
+    463872, 463876, 463881, 463886, 463892, 463897, 463903, 463909, 
+    463916, 463921, 463927, 463933, 463940, 463946, 463953, 463960, 
+    463968, 463973, 463979, 463985, 463992, 463998, 464005, 464012, 
+    464020, 464026, 464033, 464040, 464048, 464055, 464063, 464071, 
+    464080, 464085, 464091, 464097, 464104, 464110, 464117, 464124, 
+    464132, 464138, 464145, 464152, 464160, 464167, 464175, 464183, 
+    464192, 464198, 464205, 464212, 464220, 464227, 464235, 464243, 
+    464252, 464259, 464267, 464275, 464284, 464292, 464301, 464310, 
+    464320, 464325, 464331, 464337, 464344, 464350, 464357, 464364, 
+    464372, 464378, 464385, 464392, 464400, 464407, 464415, 464423, 
+    464432, 464438, 464445, 464452, 464460, 464467, 464475, 464483, 
+    464492, 464499, 464507, 464515, 464524, 464532, 464541, 464550, 
+    464560, 464566, 464573, 464580, 464588, 464595, 464603, 464611, 
+    464620, 464627, 464635, 464643, 464652, 464660, 464669, 464678, 
+    464688, 464695, 464703, 464711, 464720, 464728, 464737, 464746, 
+    464756, 464764, 464773, 464782, 464792, 464801, 464811, 464821, 
+    464832, 464837, 464843, 464849, 464856, 464862, 464869, 464876, 
+    464884, 464890, 464897, 464904, 464912, 464919, 464927, 464935, 
+    464944, 464950, 464957, 464964, 464972, 464979, 464987, 464995, 
+    465004, 465011, 465019, 465027, 465036, 465044, 465053, 465062, 
+    465072, 465078, 465085, 465092, 465100, 465107, 465115, 465123, 
+    465132, 465139, 465147, 465155, 465164, 465172, 465181, 465190, 
+    465200, 465207, 465215, 465223, 465232, 465240, 465249, 465258, 
+    465268, 465276, 465285, 465294, 465304, 465313, 465323, 465333, 
+    465344, 465350, 465357, 465364, 465372, 465379, 465387, 465395, 
+    465404, 465411, 465419, 465427, 465436, 465444, 465453, 465462, 
+    465472, 465479, 465487, 465495, 465504, 465512, 465521, 465530, 
+    465540, 465548, 465557, 465566, 465576, 465585, 465595, 465605, 
+    465616, 465623, 465631, 465639, 465648, 465656, 465665, 465674, 
+    465684, 465692, 465701, 465710, 465720, 465729, 465739, 465749, 
+    465760, 465768, 465777, 465786, 465796, 465805, 465815, 465825, 
+    465836, 465845, 465855, 465865, 465876, 465886, 465897, 465908, 
+    465920, 465925, 465931, 465937, 465944, 465950, 465957, 465964, 
+    465972, 465978, 465985, 465992, 466000, 466007, 466015, 466023, 
+    466032, 466038, 466045, 466052, 466060, 466067, 466075, 466083, 
+    466092, 466099, 466107, 466115, 466124, 466132, 466141, 466150, 
+    466160, 466166, 466173, 466180, 466188, 466195, 466203, 466211, 
+    466220, 466227, 466235, 466243, 466252, 466260, 466269, 466278, 
+    466288, 466295, 466303, 466311, 466320, 466328, 466337, 466346, 
+    466356, 466364, 466373, 466382, 466392, 466401, 466411, 466421, 
+    466432, 466438, 466445, 466452, 466460, 466467, 466475, 466483, 
+    466492, 466499, 466507, 466515, 466524, 466532, 466541, 466550, 
+    466560, 466567, 466575, 466583, 466592, 466600, 466609, 466618, 
+    466628, 466636, 466645, 466654, 466664, 466673, 466683, 466693, 
+    466704, 466711, 466719, 466727, 466736, 466744, 466753, 466762, 
+    466772, 466780, 466789, 466798, 466808, 466817, 466827, 466837, 
+    466848, 466856, 466865, 466874, 466884, 466893, 466903, 466913, 
+    466924, 466933, 466943, 466953, 466964, 466974, 466985, 466996, 
+    467008, 467014, 467021, 467028, 467036, 467043, 467051, 467059, 
+    467068, 467075, 467083, 467091, 467100, 467108, 467117, 467126, 
+    467136, 467143, 467151, 467159, 467168, 467176, 467185, 467194, 
+    467204, 467212, 467221, 467230, 467240, 467249, 467259, 467269, 
+    467280, 467287, 467295, 467303, 467312, 467320, 467329, 467338, 
+    467348, 467356, 467365, 467374, 467384, 467393, 467403, 467413, 
+    467424, 467432, 467441, 467450, 467460, 467469, 467479, 467489, 
+    467500, 467509, 467519, 467529, 467540, 467550, 467561, 467572, 
+    467584, 467591, 467599, 467607, 467616, 467624, 467633, 467642, 
+    467652, 467660, 467669, 467678, 467688, 467697, 467707, 467717, 
+    467728, 467736, 467745, 467754, 467764, 467773, 467783, 467793, 
+    467804, 467813, 467823, 467833, 467844, 467854, 467865, 467876, 
+    467888, 467896, 467905, 467914, 467924, 467933, 467943, 467953, 
+    467964, 467973, 467983, 467993, 468004, 468014, 468025, 468036, 
+    468048, 468057, 468067, 468077, 468088, 468098, 468109, 468120, 
+    468132, 468142, 468153, 468164, 468176, 468187, 468199, 468211, 
+    468224, 468229, 468235, 468241, 468248, 468254, 468261, 468268, 
+    468276, 468282, 468289, 468296, 468304, 468311, 468319, 468327, 
+    468336, 468342, 468349, 468356, 468364, 468371, 468379, 468387, 
+    468396, 468403, 468411, 468419, 468428, 468436, 468445, 468454, 
+    468464, 468470, 468477, 468484, 468492, 468499, 468507, 468515, 
+    468524, 468531, 468539, 468547, 468556, 468564, 468573, 468582, 
+    468592, 468599, 468607, 468615, 468624, 468632, 468641, 468650, 
+    468660, 468668, 468677, 468686, 468696, 468705, 468715, 468725, 
+    468736, 468742, 468749, 468756, 468764, 468771, 468779, 468787, 
+    468796, 468803, 468811, 468819, 468828, 468836, 468845, 468854, 
+    468864, 468871, 468879, 468887, 468896, 468904, 468913, 468922, 
+    468932, 468940, 468949, 468958, 468968, 468977, 468987, 468997, 
+    469008, 469015, 469023, 469031, 469040, 469048, 469057, 469066, 
+    469076, 469084, 469093, 469102, 469112, 469121, 469131, 469141, 
+    469152, 469160, 469169, 469178, 469188, 469197, 469207, 469217, 
+    469228, 469237, 469247, 469257, 469268, 469278, 469289, 469300, 
+    469312, 469318, 469325, 469332, 469340, 469347, 469355, 469363, 
+    469372, 469379, 469387, 469395, 469404, 469412, 469421, 469430, 
+    469440, 469447, 469455, 469463, 469472, 469480, 469489, 469498, 
+    469508, 469516, 469525, 469534, 469544, 469553, 469563, 469573, 
+    469584, 469591, 469599, 469607, 469616, 469624, 469633, 469642, 
+    469652, 469660, 469669, 469678, 469688, 469697, 469707, 469717, 
+    469728, 469736, 469745, 469754, 469764, 469773, 469783, 469793, 
+    469804, 469813, 469823, 469833, 469844, 469854, 469865, 469876, 
+    469888, 469895, 469903, 469911, 469920, 469928, 469937, 469946, 
+    469956, 469964, 469973, 469982, 469992, 470001, 470011, 470021, 
+    470032, 470040, 470049, 470058, 470068, 470077, 470087, 470097, 
+    470108, 470117, 470127, 470137, 470148, 470158, 470169, 470180, 
+    470192, 470200, 470209, 470218, 470228, 470237, 470247, 470257, 
+    470268, 470277, 470287, 470297, 470308, 470318, 470329, 470340, 
+    470352, 470361, 470371, 470381, 470392, 470402, 470413, 470424, 
+    470436, 470446, 470457, 470468, 470480, 470491, 470503, 470515, 
+    470528, 470534, 470541, 470548, 470556, 470563, 470571, 470579, 
+    470588, 470595, 470603, 470611, 470620, 470628, 470637, 470646, 
+    470656, 470663, 470671, 470679, 470688, 470696, 470705, 470714, 
+    470724, 470732, 470741, 470750, 470760, 470769, 470779, 470789, 
+    470800, 470807, 470815, 470823, 470832, 470840, 470849, 470858, 
+    470868, 470876, 470885, 470894, 470904, 470913, 470923, 470933, 
+    470944, 470952, 470961, 470970, 470980, 470989, 470999, 471009, 
+    471020, 471029, 471039, 471049, 471060, 471070, 471081, 471092, 
+    471104, 471111, 471119, 471127, 471136, 471144, 471153, 471162, 
+    471172, 471180, 471189, 471198, 471208, 471217, 471227, 471237, 
+    471248, 471256, 471265, 471274, 471284, 471293, 471303, 471313, 
+    471324, 471333, 471343, 471353, 471364, 471374, 471385, 471396, 
+    471408, 471416, 471425, 471434, 471444, 471453, 471463, 471473, 
+    471484, 471493, 471503, 471513, 471524, 471534, 471545, 471556, 
+    471568, 471577, 471587, 471597, 471608, 471618, 471629, 471640, 
+    471652, 471662, 471673, 471684, 471696, 471707, 471719, 471731, 
+    471744, 471751, 471759, 471767, 471776, 471784, 471793, 471802, 
+    471812, 471820, 471829, 471838, 471848, 471857, 471867, 471877, 
+    471888, 471896, 471905, 471914, 471924, 471933, 471943, 471953, 
+    471964, 471973, 471983, 471993, 472004, 472014, 472025, 472036, 
+    472048, 472056, 472065, 472074, 472084, 472093, 472103, 472113, 
+    472124, 472133, 472143, 472153, 472164, 472174, 472185, 472196, 
+    472208, 472217, 472227, 472237, 472248, 472258, 472269, 472280, 
+    472292, 472302, 472313, 472324, 472336, 472347, 472359, 472371, 
+    472384, 472392, 472401, 472410, 472420, 472429, 472439, 472449, 
+    472460, 472469, 472479, 472489, 472500, 472510, 472521, 472532, 
+    472544, 472553, 472563, 472573, 472584, 472594, 472605, 472616, 
+    472628, 472638, 472649, 472660, 472672, 472683, 472695, 472707, 
+    472720, 472729, 472739, 472749, 472760, 472770, 472781, 472792, 
+    472804, 472814, 472825, 472836, 472848, 472859, 472871, 472883, 
+    472896, 472906, 472917, 472928, 472940, 472951, 472963, 472975, 
+    472988, 472999, 473011, 473023, 473036, 473048, 473061, 473074, 
+    473088, 473093, 473099, 473105, 473112, 473118, 473125, 473132, 
+    473140, 473146, 473153, 473160, 473168, 473175, 473183, 473191, 
+    473200, 473206, 473213, 473220, 473228, 473235, 473243, 473251, 
+    473260, 473267, 473275, 473283, 473292, 473300, 473309, 473318, 
+    473328, 473334, 473341, 473348, 473356, 473363, 473371, 473379, 
+    473388, 473395, 473403, 473411, 473420, 473428, 473437, 473446, 
+    473456, 473463, 473471, 473479, 473488, 473496, 473505, 473514, 
+    473524, 473532, 473541, 473550, 473560, 473569, 473579, 473589, 
+    473600, 473606, 473613, 473620, 473628, 473635, 473643, 473651, 
+    473660, 473667, 473675, 473683, 473692, 473700, 473709, 473718, 
+    473728, 473735, 473743, 473751, 473760, 473768, 473777, 473786, 
+    473796, 473804, 473813, 473822, 473832, 473841, 473851, 473861, 
+    473872, 473879, 473887, 473895, 473904, 473912, 473921, 473930, 
+    473940, 473948, 473957, 473966, 473976, 473985, 473995, 474005, 
+    474016, 474024, 474033, 474042, 474052, 474061, 474071, 474081, 
+    474092, 474101, 474111, 474121, 474132, 474142, 474153, 474164, 
+    474176, 474182, 474189, 474196, 474204, 474211, 474219, 474227, 
+    474236, 474243, 474251, 474259, 474268, 474276, 474285, 474294, 
+    474304, 474311, 474319, 474327, 474336, 474344, 474353, 474362, 
+    474372, 474380, 474389, 474398, 474408, 474417, 474427, 474437, 
+    474448, 474455, 474463, 474471, 474480, 474488, 474497, 474506, 
+    474516, 474524, 474533, 474542, 474552, 474561, 474571, 474581, 
+    474592, 474600, 474609, 474618, 474628, 474637, 474647, 474657, 
+    474668, 474677, 474687, 474697, 474708, 474718, 474729, 474740, 
+    474752, 474759, 474767, 474775, 474784, 474792, 474801, 474810, 
+    474820, 474828, 474837, 474846, 474856, 474865, 474875, 474885, 
+    474896, 474904, 474913, 474922, 474932, 474941, 474951, 474961, 
+    474972, 474981, 474991, 475001, 475012, 475022, 475033, 475044, 
+    475056, 475064, 475073, 475082, 475092, 475101, 475111, 475121, 
+    475132, 475141, 475151, 475161, 475172, 475182, 475193, 475204, 
+    475216, 475225, 475235, 475245, 475256, 475266, 475277, 475288, 
+    475300, 475310, 475321, 475332, 475344, 475355, 475367, 475379, 
+    475392, 475398, 475405, 475412, 475420, 475427, 475435, 475443, 
+    475452, 475459, 475467, 475475, 475484, 475492, 475501, 475510, 
+    475520, 475527, 475535, 475543, 475552, 475560, 475569, 475578, 
+    475588, 475596, 475605, 475614, 475624, 475633, 475643, 475653, 
+    475664, 475671, 475679, 475687, 475696, 475704, 475713, 475722, 
+    475732, 475740, 475749, 475758, 475768, 475777, 475787, 475797, 
+    475808, 475816, 475825, 475834, 475844, 475853, 475863, 475873, 
+    475884, 475893, 475903, 475913, 475924, 475934, 475945, 475956, 
+    475968, 475975, 475983, 475991, 476000, 476008, 476017, 476026, 
+    476036, 476044, 476053, 476062, 476072, 476081, 476091, 476101, 
+    476112, 476120, 476129, 476138, 476148, 476157, 476167, 476177, 
+    476188, 476197, 476207, 476217, 476228, 476238, 476249, 476260, 
+    476272, 476280, 476289, 476298, 476308, 476317, 476327, 476337, 
+    476348, 476357, 476367, 476377, 476388, 476398, 476409, 476420, 
+    476432, 476441, 476451, 476461, 476472, 476482, 476493, 476504, 
+    476516, 476526, 476537, 476548, 476560, 476571, 476583, 476595, 
+    476608, 476615, 476623, 476631, 476640, 476648, 476657, 476666, 
+    476676, 476684, 476693, 476702, 476712, 476721, 476731, 476741, 
+    476752, 476760, 476769, 476778, 476788, 476797, 476807, 476817, 
+    476828, 476837, 476847, 476857, 476868, 476878, 476889, 476900, 
+    476912, 476920, 476929, 476938, 476948, 476957, 476967, 476977, 
+    476988, 476997, 477007, 477017, 477028, 477038, 477049, 477060, 
+    477072, 477081, 477091, 477101, 477112, 477122, 477133, 477144, 
+    477156, 477166, 477177, 477188, 477200, 477211, 477223, 477235, 
+    477248, 477256, 477265, 477274, 477284, 477293, 477303, 477313, 
+    477324, 477333, 477343, 477353, 477364, 477374, 477385, 477396, 
+    477408, 477417, 477427, 477437, 477448, 477458, 477469, 477480, 
+    477492, 477502, 477513, 477524, 477536, 477547, 477559, 477571, 
+    477584, 477593, 477603, 477613, 477624, 477634, 477645, 477656, 
+    477668, 477678, 477689, 477700, 477712, 477723, 477735, 477747, 
+    477760, 477770, 477781, 477792, 477804, 477815, 477827, 477839, 
+    477852, 477863, 477875, 477887, 477900, 477912, 477925, 477938, 
+    477952, 477958, 477965, 477972, 477980, 477987, 477995, 478003, 
+    478012, 478019, 478027, 478035, 478044, 478052, 478061, 478070, 
+    478080, 478087, 478095, 478103, 478112, 478120, 478129, 478138, 
+    478148, 478156, 478165, 478174, 478184, 478193, 478203, 478213, 
+    478224, 478231, 478239, 478247, 478256, 478264, 478273, 478282, 
+    478292, 478300, 478309, 478318, 478328, 478337, 478347, 478357, 
+    478368, 478376, 478385, 478394, 478404, 478413, 478423, 478433, 
+    478444, 478453, 478463, 478473, 478484, 478494, 478505, 478516, 
+    478528, 478535, 478543, 478551, 478560, 478568, 478577, 478586, 
+    478596, 478604, 478613, 478622, 478632, 478641, 478651, 478661, 
+    478672, 478680, 478689, 478698, 478708, 478717, 478727, 478737, 
+    478748, 478757, 478767, 478777, 478788, 478798, 478809, 478820, 
+    478832, 478840, 478849, 478858, 478868, 478877, 478887, 478897, 
+    478908, 478917, 478927, 478937, 478948, 478958, 478969, 478980, 
+    478992, 479001, 479011, 479021, 479032, 479042, 479053, 479064, 
+    479076, 479086, 479097, 479108, 479120, 479131, 479143, 479155, 
+    479168, 479175, 479183, 479191, 479200, 479208, 479217, 479226, 
+    479236, 479244, 479253, 479262, 479272, 479281, 479291, 479301, 
+    479312, 479320, 479329, 479338, 479348, 479357, 479367, 479377, 
+    479388, 479397, 479407, 479417, 479428, 479438, 479449, 479460, 
+    479472, 479480, 479489, 479498, 479508, 479517, 479527, 479537, 
+    479548, 479557, 479567, 479577, 479588, 479598, 479609, 479620, 
+    479632, 479641, 479651, 479661, 479672, 479682, 479693, 479704, 
+    479716, 479726, 479737, 479748, 479760, 479771, 479783, 479795, 
+    479808, 479816, 479825, 479834, 479844, 479853, 479863, 479873, 
+    479884, 479893, 479903, 479913, 479924, 479934, 479945, 479956, 
+    479968, 479977, 479987, 479997, 480008, 480018, 480029, 480040, 
+    480052, 480062, 480073, 480084, 480096, 480107, 480119, 480131, 
+    480144, 480153, 480163, 480173, 480184, 480194, 480205, 480216, 
+    480228, 480238, 480249, 480260, 480272, 480283, 480295, 480307, 
+    480320, 480330, 480341, 480352, 480364, 480375, 480387, 480399, 
+    480412, 480423, 480435, 480447, 480460, 480472, 480485, 480498, 
+    480512, 480519, 480527, 480535, 480544, 480552, 480561, 480570, 
+    480580, 480588, 480597, 480606, 480616, 480625, 480635, 480645, 
+    480656, 480664, 480673, 480682, 480692, 480701, 480711, 480721, 
+    480732, 480741, 480751, 480761, 480772, 480782, 480793, 480804, 
+    480816, 480824, 480833, 480842, 480852, 480861, 480871, 480881, 
+    480892, 480901, 480911, 480921, 480932, 480942, 480953, 480964, 
+    480976, 480985, 480995, 481005, 481016, 481026, 481037, 481048, 
+    481060, 481070, 481081, 481092, 481104, 481115, 481127, 481139, 
+    481152, 481160, 481169, 481178, 481188, 481197, 481207, 481217, 
+    481228, 481237, 481247, 481257, 481268, 481278, 481289, 481300, 
+    481312, 481321, 481331, 481341, 481352, 481362, 481373, 481384, 
+    481396, 481406, 481417, 481428, 481440, 481451, 481463, 481475, 
+    481488, 481497, 481507, 481517, 481528, 481538, 481549, 481560, 
+    481572, 481582, 481593, 481604, 481616, 481627, 481639, 481651, 
+    481664, 481674, 481685, 481696, 481708, 481719, 481731, 481743, 
+    481756, 481767, 481779, 481791, 481804, 481816, 481829, 481842, 
+    481856, 481864, 481873, 481882, 481892, 481901, 481911, 481921, 
+    481932, 481941, 481951, 481961, 481972, 481982, 481993, 482004, 
+    482016, 482025, 482035, 482045, 482056, 482066, 482077, 482088, 
+    482100, 482110, 482121, 482132, 482144, 482155, 482167, 482179, 
+    482192, 482201, 482211, 482221, 482232, 482242, 482253, 482264, 
+    482276, 482286, 482297, 482308, 482320, 482331, 482343, 482355, 
+    482368, 482378, 482389, 482400, 482412, 482423, 482435, 482447, 
+    482460, 482471, 482483, 482495, 482508, 482520, 482533, 482546, 
+    482560, 482569, 482579, 482589, 482600, 482610, 482621, 482632, 
+    482644, 482654, 482665, 482676, 482688, 482699, 482711, 482723, 
+    482736, 482746, 482757, 482768, 482780, 482791, 482803, 482815, 
+    482828, 482839, 482851, 482863, 482876, 482888, 482901, 482914, 
+    482928, 482938, 482949, 482960, 482972, 482983, 482995, 483007, 
+    483020, 483031, 483043, 483055, 483068, 483080, 483093, 483106, 
+    483120, 483131, 483143, 483155, 483168, 483180, 483193, 483206, 
+    483220, 483232, 483245, 483258, 483272, 483285, 483299, 483313, 
+    483328, 483332, 483337, 483342, 483348, 483353, 483359, 483365, 
+    483372, 483377, 483383, 483389, 483396, 483402, 483409, 483416, 
+    483424, 483429, 483435, 483441, 483448, 483454, 483461, 483468, 
+    483476, 483482, 483489, 483496, 483504, 483511, 483519, 483527, 
+    483536, 483541, 483547, 483553, 483560, 483566, 483573, 483580, 
+    483588, 483594, 483601, 483608, 483616, 483623, 483631, 483639, 
+    483648, 483654, 483661, 483668, 483676, 483683, 483691, 483699, 
+    483708, 483715, 483723, 483731, 483740, 483748, 483757, 483766, 
+    483776, 483781, 483787, 483793, 483800, 483806, 483813, 483820, 
+    483828, 483834, 483841, 483848, 483856, 483863, 483871, 483879, 
+    483888, 483894, 483901, 483908, 483916, 483923, 483931, 483939, 
+    483948, 483955, 483963, 483971, 483980, 483988, 483997, 484006, 
+    484016, 484022, 484029, 484036, 484044, 484051, 484059, 484067, 
+    484076, 484083, 484091, 484099, 484108, 484116, 484125, 484134, 
+    484144, 484151, 484159, 484167, 484176, 484184, 484193, 484202, 
+    484212, 484220, 484229, 484238, 484248, 484257, 484267, 484277, 
+    484288, 484293, 484299, 484305, 484312, 484318, 484325, 484332, 
+    484340, 484346, 484353, 484360, 484368, 484375, 484383, 484391, 
+    484400, 484406, 484413, 484420, 484428, 484435, 484443, 484451, 
+    484460, 484467, 484475, 484483, 484492, 484500, 484509, 484518, 
+    484528, 484534, 484541, 484548, 484556, 484563, 484571, 484579, 
+    484588, 484595, 484603, 484611, 484620, 484628, 484637, 484646, 
+    484656, 484663, 484671, 484679, 484688, 484696, 484705, 484714, 
+    484724, 484732, 484741, 484750, 484760, 484769, 484779, 484789, 
+    484800, 484806, 484813, 484820, 484828, 484835, 484843, 484851, 
+    484860, 484867, 484875, 484883, 484892, 484900, 484909, 484918, 
+    484928, 484935, 484943, 484951, 484960, 484968, 484977, 484986, 
+    484996, 485004, 485013, 485022, 485032, 485041, 485051, 485061, 
+    485072, 485079, 485087, 485095, 485104, 485112, 485121, 485130, 
+    485140, 485148, 485157, 485166, 485176, 485185, 485195, 485205, 
+    485216, 485224, 485233, 485242, 485252, 485261, 485271, 485281, 
+    485292, 485301, 485311, 485321, 485332, 485342, 485353, 485364, 
+    485376, 485381, 485387, 485393, 485400, 485406, 485413, 485420, 
+    485428, 485434, 485441, 485448, 485456, 485463, 485471, 485479, 
+    485488, 485494, 485501, 485508, 485516, 485523, 485531, 485539, 
+    485548, 485555, 485563, 485571, 485580, 485588, 485597, 485606, 
+    485616, 485622, 485629, 485636, 485644, 485651, 485659, 485667, 
+    485676, 485683, 485691, 485699, 485708, 485716, 485725, 485734, 
+    485744, 485751, 485759, 485767, 485776, 485784, 485793, 485802, 
+    485812, 485820, 485829, 485838, 485848, 485857, 485867, 485877, 
+    485888, 485894, 485901, 485908, 485916, 485923, 485931, 485939, 
+    485948, 485955, 485963, 485971, 485980, 485988, 485997, 486006, 
+    486016, 486023, 486031, 486039, 486048, 486056, 486065, 486074, 
+    486084, 486092, 486101, 486110, 486120, 486129, 486139, 486149, 
+    486160, 486167, 486175, 486183, 486192, 486200, 486209, 486218, 
+    486228, 486236, 486245, 486254, 486264, 486273, 486283, 486293, 
+    486304, 486312, 486321, 486330, 486340, 486349, 486359, 486369, 
+    486380, 486389, 486399, 486409, 486420, 486430, 486441, 486452, 
+    486464, 486470, 486477, 486484, 486492, 486499, 486507, 486515, 
+    486524, 486531, 486539, 486547, 486556, 486564, 486573, 486582, 
+    486592, 486599, 486607, 486615, 486624, 486632, 486641, 486650, 
+    486660, 486668, 486677, 486686, 486696, 486705, 486715, 486725, 
+    486736, 486743, 486751, 486759, 486768, 486776, 486785, 486794, 
+    486804, 486812, 486821, 486830, 486840, 486849, 486859, 486869, 
+    486880, 486888, 486897, 486906, 486916, 486925, 486935, 486945, 
+    486956, 486965, 486975, 486985, 486996, 487006, 487017, 487028, 
+    487040, 487047, 487055, 487063, 487072, 487080, 487089, 487098, 
+    487108, 487116, 487125, 487134, 487144, 487153, 487163, 487173, 
+    487184, 487192, 487201, 487210, 487220, 487229, 487239, 487249, 
+    487260, 487269, 487279, 487289, 487300, 487310, 487321, 487332, 
+    487344, 487352, 487361, 487370, 487380, 487389, 487399, 487409, 
+    487420, 487429, 487439, 487449, 487460, 487470, 487481, 487492, 
+    487504, 487513, 487523, 487533, 487544, 487554, 487565, 487576, 
+    487588, 487598, 487609, 487620, 487632, 487643, 487655, 487667, 
+    487680, 487685, 487691, 487697, 487704, 487710, 487717, 487724, 
+    487732, 487738, 487745, 487752, 487760, 487767, 487775, 487783, 
+    487792, 487798, 487805, 487812, 487820, 487827, 487835, 487843, 
+    487852, 487859, 487867, 487875, 487884, 487892, 487901, 487910, 
+    487920, 487926, 487933, 487940, 487948, 487955, 487963, 487971, 
+    487980, 487987, 487995, 488003, 488012, 488020, 488029, 488038, 
+    488048, 488055, 488063, 488071, 488080, 488088, 488097, 488106, 
+    488116, 488124, 488133, 488142, 488152, 488161, 488171, 488181, 
+    488192, 488198, 488205, 488212, 488220, 488227, 488235, 488243, 
+    488252, 488259, 488267, 488275, 488284, 488292, 488301, 488310, 
+    488320, 488327, 488335, 488343, 488352, 488360, 488369, 488378, 
+    488388, 488396, 488405, 488414, 488424, 488433, 488443, 488453, 
+    488464, 488471, 488479, 488487, 488496, 488504, 488513, 488522, 
+    488532, 488540, 488549, 488558, 488568, 488577, 488587, 488597, 
+    488608, 488616, 488625, 488634, 488644, 488653, 488663, 488673, 
+    488684, 488693, 488703, 488713, 488724, 488734, 488745, 488756, 
+    488768, 488774, 488781, 488788, 488796, 488803, 488811, 488819, 
+    488828, 488835, 488843, 488851, 488860, 488868, 488877, 488886, 
+    488896, 488903, 488911, 488919, 488928, 488936, 488945, 488954, 
+    488964, 488972, 488981, 488990, 489000, 489009, 489019, 489029, 
+    489040, 489047, 489055, 489063, 489072, 489080, 489089, 489098, 
+    489108, 489116, 489125, 489134, 489144, 489153, 489163, 489173, 
+    489184, 489192, 489201, 489210, 489220, 489229, 489239, 489249, 
+    489260, 489269, 489279, 489289, 489300, 489310, 489321, 489332, 
+    489344, 489351, 489359, 489367, 489376, 489384, 489393, 489402, 
+    489412, 489420, 489429, 489438, 489448, 489457, 489467, 489477, 
+    489488, 489496, 489505, 489514, 489524, 489533, 489543, 489553, 
+    489564, 489573, 489583, 489593, 489604, 489614, 489625, 489636, 
+    489648, 489656, 489665, 489674, 489684, 489693, 489703, 489713, 
+    489724, 489733, 489743, 489753, 489764, 489774, 489785, 489796, 
+    489808, 489817, 489827, 489837, 489848, 489858, 489869, 489880, 
+    489892, 489902, 489913, 489924, 489936, 489947, 489959, 489971, 
+    489984, 489990, 489997, 490004, 490012, 490019, 490027, 490035, 
+    490044, 490051, 490059, 490067, 490076, 490084, 490093, 490102, 
+    490112, 490119, 490127, 490135, 490144, 490152, 490161, 490170, 
+    490180, 490188, 490197, 490206, 490216, 490225, 490235, 490245, 
+    490256, 490263, 490271, 490279, 490288, 490296, 490305, 490314, 
+    490324, 490332, 490341, 490350, 490360, 490369, 490379, 490389, 
+    490400, 490408, 490417, 490426, 490436, 490445, 490455, 490465, 
+    490476, 490485, 490495, 490505, 490516, 490526, 490537, 490548, 
+    490560, 490567, 490575, 490583, 490592, 490600, 490609, 490618, 
+    490628, 490636, 490645, 490654, 490664, 490673, 490683, 490693, 
+    490704, 490712, 490721, 490730, 490740, 490749, 490759, 490769, 
+    490780, 490789, 490799, 490809, 490820, 490830, 490841, 490852, 
+    490864, 490872, 490881, 490890, 490900, 490909, 490919, 490929, 
+    490940, 490949, 490959, 490969, 490980, 490990, 491001, 491012, 
+    491024, 491033, 491043, 491053, 491064, 491074, 491085, 491096, 
+    491108, 491118, 491129, 491140, 491152, 491163, 491175, 491187, 
+    491200, 491207, 491215, 491223, 491232, 491240, 491249, 491258, 
+    491268, 491276, 491285, 491294, 491304, 491313, 491323, 491333, 
+    491344, 491352, 491361, 491370, 491380, 491389, 491399, 491409, 
+    491420, 491429, 491439, 491449, 491460, 491470, 491481, 491492, 
+    491504, 491512, 491521, 491530, 491540, 491549, 491559, 491569, 
+    491580, 491589, 491599, 491609, 491620, 491630, 491641, 491652, 
+    491664, 491673, 491683, 491693, 491704, 491714, 491725, 491736, 
+    491748, 491758, 491769, 491780, 491792, 491803, 491815, 491827, 
+    491840, 491848, 491857, 491866, 491876, 491885, 491895, 491905, 
+    491916, 491925, 491935, 491945, 491956, 491966, 491977, 491988, 
+    492000, 492009, 492019, 492029, 492040, 492050, 492061, 492072, 
+    492084, 492094, 492105, 492116, 492128, 492139, 492151, 492163, 
+    492176, 492185, 492195, 492205, 492216, 492226, 492237, 492248, 
+    492260, 492270, 492281, 492292, 492304, 492315, 492327, 492339, 
+    492352, 492362, 492373, 492384, 492396, 492407, 492419, 492431, 
+    492444, 492455, 492467, 492479, 492492, 492504, 492517, 492530, 
+    492544, 492549, 492555, 492561, 492568, 492574, 492581, 492588, 
+    492596, 492602, 492609, 492616, 492624, 492631, 492639, 492647, 
+    492656, 492662, 492669, 492676, 492684, 492691, 492699, 492707, 
+    492716, 492723, 492731, 492739, 492748, 492756, 492765, 492774, 
+    492784, 492790, 492797, 492804, 492812, 492819, 492827, 492835, 
+    492844, 492851, 492859, 492867, 492876, 492884, 492893, 492902, 
+    492912, 492919, 492927, 492935, 492944, 492952, 492961, 492970, 
+    492980, 492988, 492997, 493006, 493016, 493025, 493035, 493045, 
+    493056, 493062, 493069, 493076, 493084, 493091, 493099, 493107, 
+    493116, 493123, 493131, 493139, 493148, 493156, 493165, 493174, 
+    493184, 493191, 493199, 493207, 493216, 493224, 493233, 493242, 
+    493252, 493260, 493269, 493278, 493288, 493297, 493307, 493317, 
+    493328, 493335, 493343, 493351, 493360, 493368, 493377, 493386, 
+    493396, 493404, 493413, 493422, 493432, 493441, 493451, 493461, 
+    493472, 493480, 493489, 493498, 493508, 493517, 493527, 493537, 
+    493548, 493557, 493567, 493577, 493588, 493598, 493609, 493620, 
+    493632, 493638, 493645, 493652, 493660, 493667, 493675, 493683, 
+    493692, 493699, 493707, 493715, 493724, 493732, 493741, 493750, 
+    493760, 493767, 493775, 493783, 493792, 493800, 493809, 493818, 
+    493828, 493836, 493845, 493854, 493864, 493873, 493883, 493893, 
+    493904, 493911, 493919, 493927, 493936, 493944, 493953, 493962, 
+    493972, 493980, 493989, 493998, 494008, 494017, 494027, 494037, 
+    494048, 494056, 494065, 494074, 494084, 494093, 494103, 494113, 
+    494124, 494133, 494143, 494153, 494164, 494174, 494185, 494196, 
+    494208, 494215, 494223, 494231, 494240, 494248, 494257, 494266, 
+    494276, 494284, 494293, 494302, 494312, 494321, 494331, 494341, 
+    494352, 494360, 494369, 494378, 494388, 494397, 494407, 494417, 
+    494428, 494437, 494447, 494457, 494468, 494478, 494489, 494500, 
+    494512, 494520, 494529, 494538, 494548, 494557, 494567, 494577, 
+    494588, 494597, 494607, 494617, 494628, 494638, 494649, 494660, 
+    494672, 494681, 494691, 494701, 494712, 494722, 494733, 494744, 
+    494756, 494766, 494777, 494788, 494800, 494811, 494823, 494835, 
+    494848, 494854, 494861, 494868, 494876, 494883, 494891, 494899, 
+    494908, 494915, 494923, 494931, 494940, 494948, 494957, 494966, 
+    494976, 494983, 494991, 494999, 495008, 495016, 495025, 495034, 
+    495044, 495052, 495061, 495070, 495080, 495089, 495099, 495109, 
+    495120, 495127, 495135, 495143, 495152, 495160, 495169, 495178, 
+    495188, 495196, 495205, 495214, 495224, 495233, 495243, 495253, 
+    495264, 495272, 495281, 495290, 495300, 495309, 495319, 495329, 
+    495340, 495349, 495359, 495369, 495380, 495390, 495401, 495412, 
+    495424, 495431, 495439, 495447, 495456, 495464, 495473, 495482, 
+    495492, 495500, 495509, 495518, 495528, 495537, 495547, 495557, 
+    495568, 495576, 495585, 495594, 495604, 495613, 495623, 495633, 
+    495644, 495653, 495663, 495673, 495684, 495694, 495705, 495716, 
+    495728, 495736, 495745, 495754, 495764, 495773, 495783, 495793, 
+    495804, 495813, 495823, 495833, 495844, 495854, 495865, 495876, 
+    495888, 495897, 495907, 495917, 495928, 495938, 495949, 495960, 
+    495972, 495982, 495993, 496004, 496016, 496027, 496039, 496051, 
+    496064, 496071, 496079, 496087, 496096, 496104, 496113, 496122, 
+    496132, 496140, 496149, 496158, 496168, 496177, 496187, 496197, 
+    496208, 496216, 496225, 496234, 496244, 496253, 496263, 496273, 
+    496284, 496293, 496303, 496313, 496324, 496334, 496345, 496356, 
+    496368, 496376, 496385, 496394, 496404, 496413, 496423, 496433, 
+    496444, 496453, 496463, 496473, 496484, 496494, 496505, 496516, 
+    496528, 496537, 496547, 496557, 496568, 496578, 496589, 496600, 
+    496612, 496622, 496633, 496644, 496656, 496667, 496679, 496691, 
+    496704, 496712, 496721, 496730, 496740, 496749, 496759, 496769, 
+    496780, 496789, 496799, 496809, 496820, 496830, 496841, 496852, 
+    496864, 496873, 496883, 496893, 496904, 496914, 496925, 496936, 
+    496948, 496958, 496969, 496980, 496992, 497003, 497015, 497027, 
+    497040, 497049, 497059, 497069, 497080, 497090, 497101, 497112, 
+    497124, 497134, 497145, 497156, 497168, 497179, 497191, 497203, 
+    497216, 497226, 497237, 497248, 497260, 497271, 497283, 497295, 
+    497308, 497319, 497331, 497343, 497356, 497368, 497381, 497394, 
+    497408, 497414, 497421, 497428, 497436, 497443, 497451, 497459, 
+    497468, 497475, 497483, 497491, 497500, 497508, 497517, 497526, 
+    497536, 497543, 497551, 497559, 497568, 497576, 497585, 497594, 
+    497604, 497612, 497621, 497630, 497640, 497649, 497659, 497669, 
+    497680, 497687, 497695, 497703, 497712, 497720, 497729, 497738, 
+    497748, 497756, 497765, 497774, 497784, 497793, 497803, 497813, 
+    497824, 497832, 497841, 497850, 497860, 497869, 497879, 497889, 
+    497900, 497909, 497919, 497929, 497940, 497950, 497961, 497972, 
+    497984, 497991, 497999, 498007, 498016, 498024, 498033, 498042, 
+    498052, 498060, 498069, 498078, 498088, 498097, 498107, 498117, 
+    498128, 498136, 498145, 498154, 498164, 498173, 498183, 498193, 
+    498204, 498213, 498223, 498233, 498244, 498254, 498265, 498276, 
+    498288, 498296, 498305, 498314, 498324, 498333, 498343, 498353, 
+    498364, 498373, 498383, 498393, 498404, 498414, 498425, 498436, 
+    498448, 498457, 498467, 498477, 498488, 498498, 498509, 498520, 
+    498532, 498542, 498553, 498564, 498576, 498587, 498599, 498611, 
+    498624, 498631, 498639, 498647, 498656, 498664, 498673, 498682, 
+    498692, 498700, 498709, 498718, 498728, 498737, 498747, 498757, 
+    498768, 498776, 498785, 498794, 498804, 498813, 498823, 498833, 
+    498844, 498853, 498863, 498873, 498884, 498894, 498905, 498916, 
+    498928, 498936, 498945, 498954, 498964, 498973, 498983, 498993, 
+    499004, 499013, 499023, 499033, 499044, 499054, 499065, 499076, 
+    499088, 499097, 499107, 499117, 499128, 499138, 499149, 499160, 
+    499172, 499182, 499193, 499204, 499216, 499227, 499239, 499251, 
+    499264, 499272, 499281, 499290, 499300, 499309, 499319, 499329, 
+    499340, 499349, 499359, 499369, 499380, 499390, 499401, 499412, 
+    499424, 499433, 499443, 499453, 499464, 499474, 499485, 499496, 
+    499508, 499518, 499529, 499540, 499552, 499563, 499575, 499587, 
+    499600, 499609, 499619, 499629, 499640, 499650, 499661, 499672, 
+    499684, 499694, 499705, 499716, 499728, 499739, 499751, 499763, 
+    499776, 499786, 499797, 499808, 499820, 499831, 499843, 499855, 
+    499868, 499879, 499891, 499903, 499916, 499928, 499941, 499954, 
+    499968, 499975, 499983, 499991, 500000, 500008, 500017, 500026, 
+    500036, 500044, 500053, 500062, 500072, 500081, 500091, 500101, 
+    500112, 500120, 500129, 500138, 500148, 500157, 500167, 500177, 
+    500188, 500197, 500207, 500217, 500228, 500238, 500249, 500260, 
+    500272, 500280, 500289, 500298, 500308, 500317, 500327, 500337, 
+    500348, 500357, 500367, 500377, 500388, 500398, 500409, 500420, 
+    500432, 500441, 500451, 500461, 500472, 500482, 500493, 500504, 
+    500516, 500526, 500537, 500548, 500560, 500571, 500583, 500595, 
+    500608, 500616, 500625, 500634, 500644, 500653, 500663, 500673, 
+    500684, 500693, 500703, 500713, 500724, 500734, 500745, 500756, 
+    500768, 500777, 500787, 500797, 500808, 500818, 500829, 500840, 
+    500852, 500862, 500873, 500884, 500896, 500907, 500919, 500931, 
+    500944, 500953, 500963, 500973, 500984, 500994, 501005, 501016, 
+    501028, 501038, 501049, 501060, 501072, 501083, 501095, 501107, 
+    501120, 501130, 501141, 501152, 501164, 501175, 501187, 501199, 
+    501212, 501223, 501235, 501247, 501260, 501272, 501285, 501298, 
+    501312, 501320, 501329, 501338, 501348, 501357, 501367, 501377, 
+    501388, 501397, 501407, 501417, 501428, 501438, 501449, 501460, 
+    501472, 501481, 501491, 501501, 501512, 501522, 501533, 501544, 
+    501556, 501566, 501577, 501588, 501600, 501611, 501623, 501635, 
+    501648, 501657, 501667, 501677, 501688, 501698, 501709, 501720, 
+    501732, 501742, 501753, 501764, 501776, 501787, 501799, 501811, 
+    501824, 501834, 501845, 501856, 501868, 501879, 501891, 501903, 
+    501916, 501927, 501939, 501951, 501964, 501976, 501989, 502002, 
+    502016, 502025, 502035, 502045, 502056, 502066, 502077, 502088, 
+    502100, 502110, 502121, 502132, 502144, 502155, 502167, 502179, 
+    502192, 502202, 502213, 502224, 502236, 502247, 502259, 502271, 
+    502284, 502295, 502307, 502319, 502332, 502344, 502357, 502370, 
+    502384, 502394, 502405, 502416, 502428, 502439, 502451, 502463, 
+    502476, 502487, 502499, 502511, 502524, 502536, 502549, 502562, 
+    502576, 502587, 502599, 502611, 502624, 502636, 502649, 502662, 
+    502676, 502688, 502701, 502714, 502728, 502741, 502755, 502769, 
+    502784, 502789, 502795, 502801, 502808, 502814, 502821, 502828, 
+    502836, 502842, 502849, 502856, 502864, 502871, 502879, 502887, 
+    502896, 502902, 502909, 502916, 502924, 502931, 502939, 502947, 
+    502956, 502963, 502971, 502979, 502988, 502996, 503005, 503014, 
+    503024, 503030, 503037, 503044, 503052, 503059, 503067, 503075, 
+    503084, 503091, 503099, 503107, 503116, 503124, 503133, 503142, 
+    503152, 503159, 503167, 503175, 503184, 503192, 503201, 503210, 
+    503220, 503228, 503237, 503246, 503256, 503265, 503275, 503285, 
+    503296, 503302, 503309, 503316, 503324, 503331, 503339, 503347, 
+    503356, 503363, 503371, 503379, 503388, 503396, 503405, 503414, 
+    503424, 503431, 503439, 503447, 503456, 503464, 503473, 503482, 
+    503492, 503500, 503509, 503518, 503528, 503537, 503547, 503557, 
+    503568, 503575, 503583, 503591, 503600, 503608, 503617, 503626, 
+    503636, 503644, 503653, 503662, 503672, 503681, 503691, 503701, 
+    503712, 503720, 503729, 503738, 503748, 503757, 503767, 503777, 
+    503788, 503797, 503807, 503817, 503828, 503838, 503849, 503860, 
+    503872, 503878, 503885, 503892, 503900, 503907, 503915, 503923, 
+    503932, 503939, 503947, 503955, 503964, 503972, 503981, 503990, 
+    504000, 504007, 504015, 504023, 504032, 504040, 504049, 504058, 
+    504068, 504076, 504085, 504094, 504104, 504113, 504123, 504133, 
+    504144, 504151, 504159, 504167, 504176, 504184, 504193, 504202, 
+    504212, 504220, 504229, 504238, 504248, 504257, 504267, 504277, 
+    504288, 504296, 504305, 504314, 504324, 504333, 504343, 504353, 
+    504364, 504373, 504383, 504393, 504404, 504414, 504425, 504436, 
+    504448, 504455, 504463, 504471, 504480, 504488, 504497, 504506, 
+    504516, 504524, 504533, 504542, 504552, 504561, 504571, 504581, 
+    504592, 504600, 504609, 504618, 504628, 504637, 504647, 504657, 
+    504668, 504677, 504687, 504697, 504708, 504718, 504729, 504740, 
+    504752, 504760, 504769, 504778, 504788, 504797, 504807, 504817, 
+    504828, 504837, 504847, 504857, 504868, 504878, 504889, 504900, 
+    504912, 504921, 504931, 504941, 504952, 504962, 504973, 504984, 
+    504996, 505006, 505017, 505028, 505040, 505051, 505063, 505075, 
+    505088, 505094, 505101, 505108, 505116, 505123, 505131, 505139, 
+    505148, 505155, 505163, 505171, 505180, 505188, 505197, 505206, 
+    505216, 505223, 505231, 505239, 505248, 505256, 505265, 505274, 
+    505284, 505292, 505301, 505310, 505320, 505329, 505339, 505349, 
+    505360, 505367, 505375, 505383, 505392, 505400, 505409, 505418, 
+    505428, 505436, 505445, 505454, 505464, 505473, 505483, 505493, 
+    505504, 505512, 505521, 505530, 505540, 505549, 505559, 505569, 
+    505580, 505589, 505599, 505609, 505620, 505630, 505641, 505652, 
+    505664, 505671, 505679, 505687, 505696, 505704, 505713, 505722, 
+    505732, 505740, 505749, 505758, 505768, 505777, 505787, 505797, 
+    505808, 505816, 505825, 505834, 505844, 505853, 505863, 505873, 
+    505884, 505893, 505903, 505913, 505924, 505934, 505945, 505956, 
+    505968, 505976, 505985, 505994, 506004, 506013, 506023, 506033, 
+    506044, 506053, 506063, 506073, 506084, 506094, 506105, 506116, 
+    506128, 506137, 506147, 506157, 506168, 506178, 506189, 506200, 
+    506212, 506222, 506233, 506244, 506256, 506267, 506279, 506291, 
+    506304, 506311, 506319, 506327, 506336, 506344, 506353, 506362, 
+    506372, 506380, 506389, 506398, 506408, 506417, 506427, 506437, 
+    506448, 506456, 506465, 506474, 506484, 506493, 506503, 506513, 
+    506524, 506533, 506543, 506553, 506564, 506574, 506585, 506596, 
+    506608, 506616, 506625, 506634, 506644, 506653, 506663, 506673, 
+    506684, 506693, 506703, 506713, 506724, 506734, 506745, 506756, 
+    506768, 506777, 506787, 506797, 506808, 506818, 506829, 506840, 
+    506852, 506862, 506873, 506884, 506896, 506907, 506919, 506931, 
+    506944, 506952, 506961, 506970, 506980, 506989, 506999, 507009, 
+    507020, 507029, 507039, 507049, 507060, 507070, 507081, 507092, 
+    507104, 507113, 507123, 507133, 507144, 507154, 507165, 507176, 
+    507188, 507198, 507209, 507220, 507232, 507243, 507255, 507267, 
+    507280, 507289, 507299, 507309, 507320, 507330, 507341, 507352, 
+    507364, 507374, 507385, 507396, 507408, 507419, 507431, 507443, 
+    507456, 507466, 507477, 507488, 507500, 507511, 507523, 507535, 
+    507548, 507559, 507571, 507583, 507596, 507608, 507621, 507634, 
+    507648, 507654, 507661, 507668, 507676, 507683, 507691, 507699, 
+    507708, 507715, 507723, 507731, 507740, 507748, 507757, 507766, 
+    507776, 507783, 507791, 507799, 507808, 507816, 507825, 507834, 
+    507844, 507852, 507861, 507870, 507880, 507889, 507899, 507909, 
+    507920, 507927, 507935, 507943, 507952, 507960, 507969, 507978, 
+    507988, 507996, 508005, 508014, 508024, 508033, 508043, 508053, 
+    508064, 508072, 508081, 508090, 508100, 508109, 508119, 508129, 
+    508140, 508149, 508159, 508169, 508180, 508190, 508201, 508212, 
+    508224, 508231, 508239, 508247, 508256, 508264, 508273, 508282, 
+    508292, 508300, 508309, 508318, 508328, 508337, 508347, 508357, 
+    508368, 508376, 508385, 508394, 508404, 508413, 508423, 508433, 
+    508444, 508453, 508463, 508473, 508484, 508494, 508505, 508516, 
+    508528, 508536, 508545, 508554, 508564, 508573, 508583, 508593, 
+    508604, 508613, 508623, 508633, 508644, 508654, 508665, 508676, 
+    508688, 508697, 508707, 508717, 508728, 508738, 508749, 508760, 
+    508772, 508782, 508793, 508804, 508816, 508827, 508839, 508851, 
+    508864, 508871, 508879, 508887, 508896, 508904, 508913, 508922, 
+    508932, 508940, 508949, 508958, 508968, 508977, 508987, 508997, 
+    509008, 509016, 509025, 509034, 509044, 509053, 509063, 509073, 
+    509084, 509093, 509103, 509113, 509124, 509134, 509145, 509156, 
+    509168, 509176, 509185, 509194, 509204, 509213, 509223, 509233, 
+    509244, 509253, 509263, 509273, 509284, 509294, 509305, 509316, 
+    509328, 509337, 509347, 509357, 509368, 509378, 509389, 509400, 
+    509412, 509422, 509433, 509444, 509456, 509467, 509479, 509491, 
+    509504, 509512, 509521, 509530, 509540, 509549, 509559, 509569, 
+    509580, 509589, 509599, 509609, 509620, 509630, 509641, 509652, 
+    509664, 509673, 509683, 509693, 509704, 509714, 509725, 509736, 
+    509748, 509758, 509769, 509780, 509792, 509803, 509815, 509827, 
+    509840, 509849, 509859, 509869, 509880, 509890, 509901, 509912, 
+    509924, 509934, 509945, 509956, 509968, 509979, 509991, 510003, 
+    510016, 510026, 510037, 510048, 510060, 510071, 510083, 510095, 
+    510108, 510119, 510131, 510143, 510156, 510168, 510181, 510194, 
+    510208, 510215, 510223, 510231, 510240, 510248, 510257, 510266, 
+    510276, 510284, 510293, 510302, 510312, 510321, 510331, 510341, 
+    510352, 510360, 510369, 510378, 510388, 510397, 510407, 510417, 
+    510428, 510437, 510447, 510457, 510468, 510478, 510489, 510500, 
+    510512, 510520, 510529, 510538, 510548, 510557, 510567, 510577, 
+    510588, 510597, 510607, 510617, 510628, 510638, 510649, 510660, 
+    510672, 510681, 510691, 510701, 510712, 510722, 510733, 510744, 
+    510756, 510766, 510777, 510788, 510800, 510811, 510823, 510835, 
+    510848, 510856, 510865, 510874, 510884, 510893, 510903, 510913, 
+    510924, 510933, 510943, 510953, 510964, 510974, 510985, 510996, 
+    511008, 511017, 511027, 511037, 511048, 511058, 511069, 511080, 
+    511092, 511102, 511113, 511124, 511136, 511147, 511159, 511171, 
+    511184, 511193, 511203, 511213, 511224, 511234, 511245, 511256, 
+    511268, 511278, 511289, 511300, 511312, 511323, 511335, 511347, 
+    511360, 511370, 511381, 511392, 511404, 511415, 511427, 511439, 
+    511452, 511463, 511475, 511487, 511500, 511512, 511525, 511538, 
+    511552, 511560, 511569, 511578, 511588, 511597, 511607, 511617, 
+    511628, 511637, 511647, 511657, 511668, 511678, 511689, 511700, 
+    511712, 511721, 511731, 511741, 511752, 511762, 511773, 511784, 
+    511796, 511806, 511817, 511828, 511840, 511851, 511863, 511875, 
+    511888, 511897, 511907, 511917, 511928, 511938, 511949, 511960, 
+    511972, 511982, 511993, 512004, 512016, 512027, 512039, 512051, 
+    512064, 512074, 512085, 512096, 512108, 512119, 512131, 512143, 
+    512156, 512167, 512179, 512191, 512204, 512216, 512229, 512242, 
+    512256, 512265, 512275, 512285, 512296, 512306, 512317, 512328, 
+    512340, 512350, 512361, 512372, 512384, 512395, 512407, 512419, 
+    512432, 512442, 512453, 512464, 512476, 512487, 512499, 512511, 
+    512524, 512535, 512547, 512559, 512572, 512584, 512597, 512610, 
+    512624, 512634, 512645, 512656, 512668, 512679, 512691, 512703, 
+    512716, 512727, 512739, 512751, 512764, 512776, 512789, 512802, 
+    512816, 512827, 512839, 512851, 512864, 512876, 512889, 512902, 
+    512916, 512928, 512941, 512954, 512968, 512981, 512995, 513009, 
+    513024, 513030, 513037, 513044, 513052, 513059, 513067, 513075, 
+    513084, 513091, 513099, 513107, 513116, 513124, 513133, 513142, 
+    513152, 513159, 513167, 513175, 513184, 513192, 513201, 513210, 
+    513220, 513228, 513237, 513246, 513256, 513265, 513275, 513285, 
+    513296, 513303, 513311, 513319, 513328, 513336, 513345, 513354, 
+    513364, 513372, 513381, 513390, 513400, 513409, 513419, 513429, 
+    513440, 513448, 513457, 513466, 513476, 513485, 513495, 513505, 
+    513516, 513525, 513535, 513545, 513556, 513566, 513577, 513588, 
+    513600, 513607, 513615, 513623, 513632, 513640, 513649, 513658, 
+    513668, 513676, 513685, 513694, 513704, 513713, 513723, 513733, 
+    513744, 513752, 513761, 513770, 513780, 513789, 513799, 513809, 
+    513820, 513829, 513839, 513849, 513860, 513870, 513881, 513892, 
+    513904, 513912, 513921, 513930, 513940, 513949, 513959, 513969, 
+    513980, 513989, 513999, 514009, 514020, 514030, 514041, 514052, 
+    514064, 514073, 514083, 514093, 514104, 514114, 514125, 514136, 
+    514148, 514158, 514169, 514180, 514192, 514203, 514215, 514227, 
+    514240, 514247, 514255, 514263, 514272, 514280, 514289, 514298, 
+    514308, 514316, 514325, 514334, 514344, 514353, 514363, 514373, 
+    514384, 514392, 514401, 514410, 514420, 514429, 514439, 514449, 
+    514460, 514469, 514479, 514489, 514500, 514510, 514521, 514532, 
+    514544, 514552, 514561, 514570, 514580, 514589, 514599, 514609, 
+    514620, 514629, 514639, 514649, 514660, 514670, 514681, 514692, 
+    514704, 514713, 514723, 514733, 514744, 514754, 514765, 514776, 
+    514788, 514798, 514809, 514820, 514832, 514843, 514855, 514867, 
+    514880, 514888, 514897, 514906, 514916, 514925, 514935, 514945, 
+    514956, 514965, 514975, 514985, 514996, 515006, 515017, 515028, 
+    515040, 515049, 515059, 515069, 515080, 515090, 515101, 515112, 
+    515124, 515134, 515145, 515156, 515168, 515179, 515191, 515203, 
+    515216, 515225, 515235, 515245, 515256, 515266, 515277, 515288, 
+    515300, 515310, 515321, 515332, 515344, 515355, 515367, 515379, 
+    515392, 515402, 515413, 515424, 515436, 515447, 515459, 515471, 
+    515484, 515495, 515507, 515519, 515532, 515544, 515557, 515570, 
+    515584, 515591, 515599, 515607, 515616, 515624, 515633, 515642, 
+    515652, 515660, 515669, 515678, 515688, 515697, 515707, 515717, 
+    515728, 515736, 515745, 515754, 515764, 515773, 515783, 515793, 
+    515804, 515813, 515823, 515833, 515844, 515854, 515865, 515876, 
+    515888, 515896, 515905, 515914, 515924, 515933, 515943, 515953, 
+    515964, 515973, 515983, 515993, 516004, 516014, 516025, 516036, 
+    516048, 516057, 516067, 516077, 516088, 516098, 516109, 516120, 
+    516132, 516142, 516153, 516164, 516176, 516187, 516199, 516211, 
+    516224, 516232, 516241, 516250, 516260, 516269, 516279, 516289, 
+    516300, 516309, 516319, 516329, 516340, 516350, 516361, 516372, 
+    516384, 516393, 516403, 516413, 516424, 516434, 516445, 516456, 
+    516468, 516478, 516489, 516500, 516512, 516523, 516535, 516547, 
+    516560, 516569, 516579, 516589, 516600, 516610, 516621, 516632, 
+    516644, 516654, 516665, 516676, 516688, 516699, 516711, 516723, 
+    516736, 516746, 516757, 516768, 516780, 516791, 516803, 516815, 
+    516828, 516839, 516851, 516863, 516876, 516888, 516901, 516914, 
+    516928, 516936, 516945, 516954, 516964, 516973, 516983, 516993, 
+    517004, 517013, 517023, 517033, 517044, 517054, 517065, 517076, 
+    517088, 517097, 517107, 517117, 517128, 517138, 517149, 517160, 
+    517172, 517182, 517193, 517204, 517216, 517227, 517239, 517251, 
+    517264, 517273, 517283, 517293, 517304, 517314, 517325, 517336, 
+    517348, 517358, 517369, 517380, 517392, 517403, 517415, 517427, 
+    517440, 517450, 517461, 517472, 517484, 517495, 517507, 517519, 
+    517532, 517543, 517555, 517567, 517580, 517592, 517605, 517618, 
+    517632, 517641, 517651, 517661, 517672, 517682, 517693, 517704, 
+    517716, 517726, 517737, 517748, 517760, 517771, 517783, 517795, 
+    517808, 517818, 517829, 517840, 517852, 517863, 517875, 517887, 
+    517900, 517911, 517923, 517935, 517948, 517960, 517973, 517986, 
+    518000, 518010, 518021, 518032, 518044, 518055, 518067, 518079, 
+    518092, 518103, 518115, 518127, 518140, 518152, 518165, 518178, 
+    518192, 518203, 518215, 518227, 518240, 518252, 518265, 518278, 
+    518292, 518304, 518317, 518330, 518344, 518357, 518371, 518385, 
+    518400, 518407, 518415, 518423, 518432, 518440, 518449, 518458, 
+    518468, 518476, 518485, 518494, 518504, 518513, 518523, 518533, 
+    518544, 518552, 518561, 518570, 518580, 518589, 518599, 518609, 
+    518620, 518629, 518639, 518649, 518660, 518670, 518681, 518692, 
+    518704, 518712, 518721, 518730, 518740, 518749, 518759, 518769, 
+    518780, 518789, 518799, 518809, 518820, 518830, 518841, 518852, 
+    518864, 518873, 518883, 518893, 518904, 518914, 518925, 518936, 
+    518948, 518958, 518969, 518980, 518992, 519003, 519015, 519027, 
+    519040, 519048, 519057, 519066, 519076, 519085, 519095, 519105, 
+    519116, 519125, 519135, 519145, 519156, 519166, 519177, 519188, 
+    519200, 519209, 519219, 519229, 519240, 519250, 519261, 519272, 
+    519284, 519294, 519305, 519316, 519328, 519339, 519351, 519363, 
+    519376, 519385, 519395, 519405, 519416, 519426, 519437, 519448, 
+    519460, 519470, 519481, 519492, 519504, 519515, 519527, 519539, 
+    519552, 519562, 519573, 519584, 519596, 519607, 519619, 519631, 
+    519644, 519655, 519667, 519679, 519692, 519704, 519717, 519730, 
+    519744, 519752, 519761, 519770, 519780, 519789, 519799, 519809, 
+    519820, 519829, 519839, 519849, 519860, 519870, 519881, 519892, 
+    519904, 519913, 519923, 519933, 519944, 519954, 519965, 519976, 
+    519988, 519998, 520009, 520020, 520032, 520043, 520055, 520067, 
+    520080, 520089, 520099, 520109, 520120, 520130, 520141, 520152, 
+    520164, 520174, 520185, 520196, 520208, 520219, 520231, 520243, 
+    520256, 520266, 520277, 520288, 520300, 520311, 520323, 520335, 
+    520348, 520359, 520371, 520383, 520396, 520408, 520421, 520434, 
+    520448, 520457, 520467, 520477, 520488, 520498, 520509, 520520, 
+    520532, 520542, 520553, 520564, 520576, 520587, 520599, 520611, 
+    520624, 520634, 520645, 520656, 520668, 520679, 520691, 520703, 
+    520716, 520727, 520739, 520751, 520764, 520776, 520789, 520802, 
+    520816, 520826, 520837, 520848, 520860, 520871, 520883, 520895, 
+    520908, 520919, 520931, 520943, 520956, 520968, 520981, 520994, 
+    521008, 521019, 521031, 521043, 521056, 521068, 521081, 521094, 
+    521108, 521120, 521133, 521146, 521160, 521173, 521187, 521201, 
+    521216, 521224, 521233, 521242, 521252, 521261, 521271, 521281, 
+    521292, 521301, 521311, 521321, 521332, 521342, 521353, 521364, 
+    521376, 521385, 521395, 521405, 521416, 521426, 521437, 521448, 
+    521460, 521470, 521481, 521492, 521504, 521515, 521527, 521539, 
+    521552, 521561, 521571, 521581, 521592, 521602, 521613, 521624, 
+    521636, 521646, 521657, 521668, 521680, 521691, 521703, 521715, 
+    521728, 521738, 521749, 521760, 521772, 521783, 521795, 521807, 
+    521820, 521831, 521843, 521855, 521868, 521880, 521893, 521906, 
+    521920, 521929, 521939, 521949, 521960, 521970, 521981, 521992, 
+    522004, 522014, 522025, 522036, 522048, 522059, 522071, 522083, 
+    522096, 522106, 522117, 522128, 522140, 522151, 522163, 522175, 
+    522188, 522199, 522211, 522223, 522236, 522248, 522261, 522274, 
+    522288, 522298, 522309, 522320, 522332, 522343, 522355, 522367, 
+    522380, 522391, 522403, 522415, 522428, 522440, 522453, 522466, 
+    522480, 522491, 522503, 522515, 522528, 522540, 522553, 522566, 
+    522580, 522592, 522605, 522618, 522632, 522645, 522659, 522673, 
+    522688, 522697, 522707, 522717, 522728, 522738, 522749, 522760, 
+    522772, 522782, 522793, 522804, 522816, 522827, 522839, 522851, 
+    522864, 522874, 522885, 522896, 522908, 522919, 522931, 522943, 
+    522956, 522967, 522979, 522991, 523004, 523016, 523029, 523042, 
+    523056, 523066, 523077, 523088, 523100, 523111, 523123, 523135, 
+    523148, 523159, 523171, 523183, 523196, 523208, 523221, 523234, 
+    523248, 523259, 523271, 523283, 523296, 523308, 523321, 523334, 
+    523348, 523360, 523373, 523386, 523400, 523413, 523427, 523441, 
+    523456, 523466, 523477, 523488, 523500, 523511, 523523, 523535, 
+    523548, 523559, 523571, 523583, 523596, 523608, 523621, 523634, 
+    523648, 523659, 523671, 523683, 523696, 523708, 523721, 523734, 
+    523748, 523760, 523773, 523786, 523800, 523813, 523827, 523841, 
+    523856, 523867, 523879, 523891, 523904, 523916, 523929, 523942, 
+    523956, 523968, 523981, 523994, 524008, 524021, 524035, 524049, 
+    524064, 524076, 524089, 524102, 524116, 524129, 524143, 524157, 
+    524172, 524185, 524199, 524213, 524228, 524242, 524257, 524272, 
+};
+
+
+static unsigned short closestData[] = {
+        0,     0,     0,     2,     0,     0,     4,     0, 
+        4,     0,     8,     6,     0,     0,     8,     0, 
+        8,     0,     8,    10,     0,     8,     0,    16, 
+       12,     0,    16,    12,     0,    16,    17,    14, 
+        0,     0,    16,     0,    16,     0,    16,    18, 
+        0,    16,     0,    16,    20,     0,    16,    20, 
+        0,    16,    24,    22,     0,    16,     0,    32, 
+       24,     0,    32,    24,     0,    32,    24,    26, 
+        0,    32,    24,     0,    32,    33,    28,     0, 
+       32,    33,    28,     0,    32,    33,    28,    30, 
+        0,     0,    32,     0,    32,     0,    32,    34, 
+        0,    32,     0,    32,    36,     0,    32,    36, 
+        0,    32,    40,    38,     0,    32,     0,    32, 
+       40,     0,    32,    40,     0,    32,    40,    42, 
+        0,    32,    40,     0,    32,    48,    44,     0, 
+       32,    48,    44,     0,    32,    48,    49,    46, 
+        0,    32,     0,    64,    48,     0,    64,    48, 
+        0,    64,    48,    50,     0,    64,    48,     0, 
+       64,    48,    52,     0,    64,    48,    52,     0, 
+       64,    48,    56,    54,     0,    64,    48,     0, 
+       64,    65,    56,     0,    64,    65,    56,     0, 
+       64,    65,    56,    58,     0,    64,    65,    56, 
+        0,    64,    65,    56,    60,     0,    64,    65, 
+       67,    60,     0,    64,    65,    67,    60,    62, 
+        0,     0,    64,     0,    64,     0,    64,    66, 
+        0,    64,     0,    64,    68,     0,    64,    68, 
+        0,    64,    72,    70,     0,    64,     0,    64, 
+       72,     0,    64,    72,     0,    64,    72,    74, 
+        0,    64,    72,     0,    64,    80,    76,     0, 
+       64,    80,    76,     0,    64,    80,    81,    78, 
+        0,    64,     0,    64,    80,     0,    64,    80, 
+        0,    64,    80,    82,     0,    64,    80,     0, 
+       64,    80,    84,     0,    64,    80,    84,     0, 
+       64,    80,    88,    86,     0,    64,    80,     0, 
+       64,    96,    88,     0,    64,    96,    88,     0, 
+       64,    96,    88,    90,     0,    64,    96,    88, 
+        0,    64,    96,    97,    92,     0,    64,    96, 
+       97,    92,     0,    64,    96,    97,    92,    94, 
+        0,    64,     0,   128,    96,     0,   128,    96, 
+        0,   128,    96,    98,     0,   128,    96,     0, 
+      128,    96,   100,     0,   128,    96,   100,     0, 
+      128,    96,   104,   102,     0,   128,    96,     0, 
+      128,    96,   104,     0,   128,    96,   104,     0, 
+      128,    96,   104,   106,     0,   128,    96,   104, 
+        0,   128,    96,   112,   108,     0,   128,    96, 
+      112,   108,     0,   128,    96,   112,   113,   110, 
+        0,   128,    96,     0,   128,   129,   112,     0, 
+      128,   129,   112,     0,   128,   129,   112,   114, 
+        0,   128,   129,   112,     0,   128,   129,   112, 
+      116,     0,   128,   129,   112,   116,     0,   128, 
+      129,   112,   120,   118,     0,   128,   129,   112, 
+        0,   128,   129,   112,   120,     0,   128,   129, 
+      131,   120,     0,   128,   129,   131,   120,   122, 
+        0,   128,   129,   131,   120,     0,   128,   129, 
+      131,   120,   124,     0,   128,   129,   131,   120, 
+      124,     0,   128,   129,   131,   120,   124,   126, 
+        0,     0,   128,     0,   128,     0,   128,   130, 
+        0,   128,     0,   128,   132,     0,   128,   132, 
+        0,   128,   136,   134,     0,   128,     0,   128, 
+      136,     0,   128,   136,     0,   128,   136,   138, 
+        0,   128,   136,     0,   128,   144,   140,     0, 
+      128,   144,   140,     0,   128,   144,   145,   142, 
+        0,   128,     0,   128,   144,     0,   128,   144, 
+        0,   128,   144,   146,     0,   128,   144,     0, 
+      128,   144,   148,     0,   128,   144,   148,     0, 
+      128,   144,   152,   150,     0,   128,   144,     0, 
+      128,   160,   152,     0,   128,   160,   152,     0, 
+      128,   160,   152,   154,     0,   128,   160,   152, 
+        0,   128,   160,   161,   156,     0,   128,   160, 
+      161,   156,     0,   128,   160,   161,   156,   158, 
+        0,   128,     0,   128,   160,     0,   128,   160, 
+        0,   128,   160,   162,     0,   128,   160,     0, 
+      128,   160,   164,     0,   128,   160,   164,     0, 
+      128,   160,   168,   166,     0,   128,   160,     0, 
+      128,   160,   168,     0,   128,   160,   168,     0, 
+      128,   160,   168,   170,     0,   128,   160,   168, 
+        0,   128,   160,   176,   172,     0,   128,   160, 
+      176,   172,     0,   128,   160,   176,   177,   174, 
+        0,   128,   160,     0,   128,   192,   176,     0, 
+      128,   192,   176,     0,   128,   192,   176,   178, 
+        0,   128,   192,   176,     0,   128,   192,   176, 
+      180,     0,   128,   192,   176,   180,     0,   128, 
+      192,   176,   184,   182,     0,   128,   192,   176, 
+        0,   128,   192,   193,   184,     0,   128,   192, 
+      193,   184,     0,   128,   192,   193,   184,   186, 
+        0,   128,   192,   193,   184,     0,   128,   192, 
+      193,   184,   188,     0,   128,   192,   193,   195, 
+      188,     0,   128,   192,   193,   195,   188,   190, 
+        0,   128,     0,   256,   192,     0,   256,   192, 
+        0,   256,   192,   194,     0,   256,   192,     0, 
+      256,   192,   196,     0,   256,   192,   196,     0, 
+      256,   192,   200,   198,     0,   256,   192,     0, 
+      256,   192,   200,     0,   256,   192,   200,     0, 
+      256,   192,   200,   202,     0,   256,   192,   200, 
+        0,   256,   192,   208,   204,     0,   256,   192, 
+      208,   204,     0,   256,   192,   208,   209,   206, 
+        0,   256,   192,     0,   256,   192,   208,     0, 
+      256,   192,   208,     0,   256,   192,   208,   210, 
+        0,   256,   192,   208,     0,   256,   192,   208, 
+      212,     0,   256,   192,   208,   212,     0,   256, 
+      192,   208,   216,   214,     0,   256,   192,   208, 
+        0,   256,   192,   224,   216,     0,   256,   192, 
+      224,   216,     0,   256,   192,   224,   216,   218, 
+        0,   256,   192,   224,   216,     0,   256,   192, 
+      224,   225,   220,     0,   256,   192,   224,   225, 
+      220,     0,   256,   192,   224,   225,   220,   222, 
+        0,   256,   192,     0,   256,   257,   224,     0, 
+      256,   257,   224,     0,   256,   257,   224,   226, 
+        0,   256,   257,   224,     0,   256,   257,   224, 
+      228,     0,   256,   257,   224,   228,     0,   256, 
+      257,   224,   232,   230,     0,   256,   257,   224, 
+        0,   256,   257,   224,   232,     0,   256,   257, 
+      224,   232,     0,   256,   257,   224,   232,   234, 
+        0,   256,   257,   224,   232,     0,   256,   257, 
+      224,   240,   236,     0,   256,   257,   224,   240, 
+      236,     0,   256,   257,   224,   240,   241,   238, 
+        0,   256,   257,   224,     0,   256,   257,   224, 
+      240,     0,   256,   257,   259,   240,     0,   256, 
+      257,   259,   240,   242,     0,   256,   257,   259, 
+      240,     0,   256,   257,   259,   240,   244,     0, 
+      256,   257,   259,   240,   244,     0,   256,   257, 
+      259,   240,   248,   246,     0,   256,   257,   259, 
+      240,     0,   256,   257,   259,   240,   248,     0, 
+      256,   257,   259,   240,   248,     0,   256,   257, 
+      259,   240,   248,   250,     0,   256,   257,   259, 
+      263,   248,     0,   256,   257,   259,   263,   248, 
+      252,     0,   256,   257,   259,   263,   248,   252, 
+        0,   256,   257,   259,   263,   248,   252,   254, 
+        0,     0,   256,     0,   256,     0,   256,   258, 
+        0,   256,     0,   256,   260,     0,   256,   260, 
+        0,   256,   264,   262,     0,   256,     0,   256, 
+      264,     0,   256,   264,     0,   256,   264,   266, 
+        0,   256,   264,     0,   256,   272,   268,     0, 
+      256,   272,   268,     0,   256,   272,   273,   270, 
+        0,   256,     0,   256,   272,     0,   256,   272, 
+        0,   256,   272,   274,     0,   256,   272,     0, 
+      256,   272,   276,     0,   256,   272,   276,     0, 
+      256,   272,   280,   278,     0,   256,   272,     0, 
+      256,   288,   280,     0,   256,   288,   280,     0, 
+      256,   288,   280,   282,     0,   256,   288,   280, 
+        0,   256,   288,   289,   284,     0,   256,   288, 
+      289,   284,     0,   256,   288,   289,   284,   286, 
+        0,   256,     0,   256,   288,     0,   256,   288, 
+        0,   256,   288,   290,     0,   256,   288,     0, 
+      256,   288,   292,     0,   256,   288,   292,     0, 
+      256,   288,   296,   294,     0,   256,   288,     0, 
+      256,   288,   296,     0,   256,   288,   296,     0, 
+      256,   288,   296,   298,     0,   256,   288,   296, 
+        0,   256,   288,   304,   300,     0,   256,   288, 
+      304,   300,     0,   256,   288,   304,   305,   302, 
+        0,   256,   288,     0,   256,   320,   304,     0, 
+      256,   320,   304,     0,   256,   320,   304,   306, 
+        0,   256,   320,   304,     0,   256,   320,   304, 
+      308,     0,   256,   320,   304,   308,     0,   256, 
+      320,   304,   312,   310,     0,   256,   320,   304, 
+        0,   256,   320,   321,   312,     0,   256,   320, 
+      321,   312,     0,   256,   320,   321,   312,   314, 
+        0,   256,   320,   321,   312,     0,   256,   320, 
+      321,   312,   316,     0,   256,   320,   321,   323, 
+      316,     0,   256,   320,   321,   323,   316,   318, 
+        0,   256,     0,   256,   320,     0,   256,   320, 
+        0,   256,   320,   322,     0,   256,   320,     0, 
+      256,   320,   324,     0,   256,   320,   324,     0, 
+      256,   320,   328,   326,     0,   256,   320,     0, 
+      256,   320,   328,     0,   256,   320,   328,     0, 
+      256,   320,   328,   330,     0,   256,   320,   328, 
+        0,   256,   320,   336,   332,     0,   256,   320, 
+      336,   332,     0,   256,   320,   336,   337,   334, 
+        0,   256,   320,     0,   256,   320,   336,     0, 
+      256,   320,   336,     0,   256,   320,   336,   338, 
+        0,   256,   320,   336,     0,   256,   320,   336, 
+      340,     0,   256,   320,   336,   340,     0,   256, 
+      320,   336,   344,   342,     0,   256,   320,   336, 
+        0,   256,   320,   352,   344,     0,   256,   320, 
+      352,   344,     0,   256,   320,   352,   344,   346, 
+        0,   256,   320,   352,   344,     0,   256,   320, 
+      352,   353,   348,     0,   256,   320,   352,   353, 
+      348,     0,   256,   320,   352,   353,   348,   350, 
+        0,   256,   320,     0,   256,   384,   352,     0, 
+      256,   384,   352,     0,   256,   384,   352,   354, 
+        0,   256,   384,   352,     0,   256,   384,   352, 
+      356,     0,   256,   384,   352,   356,     0,   256, 
+      384,   352,   360,   358,     0,   256,   384,   352, 
+        0,   256,   384,   352,   360,     0,   256,   384, 
+      352,   360,     0,   256,   384,   352,   360,   362, 
+        0,   256,   384,   352,   360,     0,   256,   384, 
+      352,   368,   364,     0,   256,   384,   352,   368, 
+      364,     0,   256,   384,   352,   368,   369,   366, 
+        0,   256,   384,   352,     0,   256,   384,   385, 
+      368,     0,   256,   384,   385,   368,     0,   256, 
+      384,   385,   368,   370,     0,   256,   384,   385, 
+      368,     0,   256,   384,   385,   368,   372,     0, 
+      256,   384,   385,   368,   372,     0,   256,   384, 
+      385,   368,   376,   374,     0,   256,   384,   385, 
+      368,     0,   256,   384,   385,   368,   376,     0, 
+      256,   384,   385,   387,   376,     0,   256,   384, 
+      385,   387,   376,   378,     0,   256,   384,   385, 
+      387,   376,     0,   256,   384,   385,   387,   376, 
+      380,     0,   256,   384,   385,   387,   376,   380, 
+        0,   256,   384,   385,   387,   376,   380,   382, 
+        0,   256,     0,   512,   384,     0,   512,   384, 
+        0,   512,   384,   386,     0,   512,   384,     0, 
+      512,   384,   388,     0,   512,   384,   388,     0, 
+      512,   384,   392,   390,     0,   512,   384,     0, 
+      512,   384,   392,     0,   512,   384,   392,     0, 
+      512,   384,   392,   394,     0,   512,   384,   392, 
+        0,   512,   384,   400,   396,     0,   512,   384, 
+      400,   396,     0,   512,   384,   400,   401,   398, 
+        0,   512,   384,     0,   512,   384,   400,     0, 
+      512,   384,   400,     0,   512,   384,   400,   402, 
+        0,   512,   384,   400,     0,   512,   384,   400, 
+      404,     0,   512,   384,   400,   404,     0,   512, 
+      384,   400,   408,   406,     0,   512,   384,   400, 
+        0,   512,   384,   416,   408,     0,   512,   384, 
+      416,   408,     0,   512,   384,   416,   408,   410, 
+        0,   512,   384,   416,   408,     0,   512,   384, 
+      416,   417,   412,     0,   512,   384,   416,   417, 
+      412,     0,   512,   384,   416,   417,   412,   414, 
+        0,   512,   384,     0,   512,   384,   416,     0, 
+      512,   384,   416,     0,   512,   384,   416,   418, 
+        0,   512,   384,   416,     0,   512,   384,   416, 
+      420,     0,   512,   384,   416,   420,     0,   512, 
+      384,   416,   424,   422,     0,   512,   384,   416, 
+        0,   512,   384,   416,   424,     0,   512,   384, 
+      416,   424,     0,   512,   384,   416,   424,   426, 
+        0,   512,   384,   416,   424,     0,   512,   384, 
+      416,   432,   428,     0,   512,   384,   416,   432, 
+      428,     0,   512,   384,   416,   432,   433,   430, 
+        0,   512,   384,   416,     0,   512,   384,   448, 
+      432,     0,   512,   384,   448,   432,     0,   512, 
+      384,   448,   432,   434,     0,   512,   384,   448, 
+      432,     0,   512,   384,   448,   432,   436,     0, 
+      512,   384,   448,   432,   436,     0,   512,   384, 
+      448,   432,   440,   438,     0,   512,   384,   448, 
+      432,     0,   512,   384,   448,   449,   440,     0, 
+      512,   384,   448,   449,   440,     0,   512,   384, 
+      448,   449,   440,   442,     0,   512,   384,   448, 
+      449,   440,     0,   512,   384,   448,   449,   440, 
+      444,     0,   512,   384,   448,   449,   451,   444, 
+        0,   512,   384,   448,   449,   451,   444,   446, 
+        0,   512,   384,     0,   512,   513,   448,     0, 
+      512,   513,   448,     0,   512,   513,   448,   450, 
+        0,   512,   513,   448,     0,   512,   513,   448, 
+      452,     0,   512,   513,   448,   452,     0,   512, 
+      513,   448,   456,   454,     0,   512,   513,   448, 
+        0,   512,   513,   448,   456,     0,   512,   513, 
+      448,   456,     0,   512,   513,   448,   456,   458, 
+        0,   512,   513,   448,   456,     0,   512,   513, 
+      448,   464,   460,     0,   512,   513,   448,   464, 
+      460,     0,   512,   513,   448,   464,   465,   462, 
+        0,   512,   513,   448,     0,   512,   513,   448, 
+      464,     0,   512,   513,   448,   464,     0,   512, 
+      513,   448,   464,   466,     0,   512,   513,   448, 
+      464,     0,   512,   513,   448,   464,   468,     0, 
+      512,   513,   448,   464,   468,     0,   512,   513, 
+      448,   464,   472,   470,     0,   512,   513,   448, 
+      464,     0,   512,   513,   448,   480,   472,     0, 
+      512,   513,   448,   480,   472,     0,   512,   513, 
+      448,   480,   472,   474,     0,   512,   513,   448, 
+      480,   472,     0,   512,   513,   448,   480,   481, 
+      476,     0,   512,   513,   448,   480,   481,   476, 
+        0,   512,   513,   448,   480,   481,   476,   478, 
+        0,   512,   513,   448,     0,   512,   513,   448, 
+      480,     0,   512,   513,   515,   480,     0,   512, 
+      513,   515,   480,   482,     0,   512,   513,   515, 
+      480,     0,   512,   513,   515,   480,   484,     0, 
+      512,   513,   515,   480,   484,     0,   512,   513, 
+      515,   480,   488,   486,     0,   512,   513,   515, 
+      480,     0,   512,   513,   515,   480,   488,     0, 
+      512,   513,   515,   480,   488,     0,   512,   513, 
+      515,   480,   488,   490,     0,   512,   513,   515, 
+      480,   488,     0,   512,   513,   515,   480,   496, 
+      492,     0,   512,   513,   515,   480,   496,   492, 
+        0,   512,   513,   515,   480,   496,   497,   494, 
+        0,   512,   513,   515,   480,     0,   512,   513, 
+      515,   480,   496,     0,   512,   513,   515,   480, 
+      496,     0,   512,   513,   515,   480,   496,   498, 
+        0,   512,   513,   515,   519,   496,     0,   512, 
+      513,   515,   519,   496,   500,     0,   512,   513, 
+      515,   519,   496,   500,     0,   512,   513,   515, 
+      519,   496,   504,   502,     0,   512,   513,   515, 
+      519,   496,     0,   512,   513,   515,   519,   496, 
+      504,     0,   512,   513,   515,   519,   496,   504, 
+        0,   512,   513,   515,   519,   496,   504,   506, 
+        0,   512,   513,   515,   519,   496,   504,     0, 
+      512,   513,   515,   519,   496,   504,   508,     0, 
+      512,   513,   515,   519,   496,   504,   508,     0, 
+      512,   513,   515,   519,   496,   504,   508,   510, 
+        0,     0,   512,     0,   512,     0,   512,   514, 
+        0,   512,     0,   512,   516,     0,   512,   516, 
+        0,   512,   520,   518,     0,   512,     0,   512, 
+      520,     0,   512,   520,     0,   512,   520,   522, 
+        0,   512,   520,     0,   512,   528,   524,     0, 
+      512,   528,   524,     0,   512,   528,   529,   526, 
+        0,   512,     0,   512,   528,     0,   512,   528, 
+        0,   512,   528,   530,     0,   512,   528,     0, 
+      512,   528,   532,     0,   512,   528,   532,     0, 
+      512,   528,   536,   534,     0,   512,   528,     0, 
+      512,   544,   536,     0,   512,   544,   536,     0, 
+      512,   544,   536,   538,     0,   512,   544,   536, 
+        0,   512,   544,   545,   540,     0,   512,   544, 
+      545,   540,     0,   512,   544,   545,   540,   542, 
+        0,   512,     0,   512,   544,     0,   512,   544, 
+        0,   512,   544,   546,     0,   512,   544,     0, 
+      512,   544,   548,     0,   512,   544,   548,     0, 
+      512,   544,   552,   550,     0,   512,   544,     0, 
+      512,   544,   552,     0,   512,   544,   552,     0, 
+      512,   544,   552,   554,     0,   512,   544,   552, 
+        0,   512,   544,   560,   556,     0,   512,   544, 
+      560,   556,     0,   512,   544,   560,   561,   558, 
+        0,   512,   544,     0,   512,   576,   560,     0, 
+      512,   576,   560,     0,   512,   576,   560,   562, 
+        0,   512,   576,   560,     0,   512,   576,   560, 
+      564,     0,   512,   576,   560,   564,     0,   512, 
+      576,   560,   568,   566,     0,   512,   576,   560, 
+        0,   512,   576,   577,   568,     0,   512,   576, 
+      577,   568,     0,   512,   576,   577,   568,   570, 
+        0,   512,   576,   577,   568,     0,   512,   576, 
+      577,   568,   572,     0,   512,   576,   577,   579, 
+      572,     0,   512,   576,   577,   579,   572,   574, 
+        0,   512,     0,   512,   576,     0,   512,   576, 
+        0,   512,   576,   578,     0,   512,   576,     0, 
+      512,   576,   580,     0,   512,   576,   580,     0, 
+      512,   576,   584,   582,     0,   512,   576,     0, 
+      512,   576,   584,     0,   512,   576,   584,     0, 
+      512,   576,   584,   586,     0,   512,   576,   584, 
+        0,   512,   576,   592,   588,     0,   512,   576, 
+      592,   588,     0,   512,   576,   592,   593,   590, 
+        0,   512,   576,     0,   512,   576,   592,     0, 
+      512,   576,   592,     0,   512,   576,   592,   594, 
+        0,   512,   576,   592,     0,   512,   576,   592, 
+      596,     0,   512,   576,   592,   596,     0,   512, 
+      576,   592,   600,   598,     0,   512,   576,   592, 
+        0,   512,   576,   608,   600,     0,   512,   576, 
+      608,   600,     0,   512,   576,   608,   600,   602, 
+        0,   512,   576,   608,   600,     0,   512,   576, 
+      608,   609,   604,     0,   512,   576,   608,   609, 
+      604,     0,   512,   576,   608,   609,   604,   606, 
+        0,   512,   576,     0,   512,   640,   608,     0, 
+      512,   640,   608,     0,   512,   640,   608,   610, 
+        0,   512,   640,   608,     0,   512,   640,   608, 
+      612,     0,   512,   640,   608,   612,     0,   512, 
+      640,   608,   616,   614,     0,   512,   640,   608, 
+        0,   512,   640,   608,   616,     0,   512,   640, 
+      608,   616,     0,   512,   640,   608,   616,   618, 
+        0,   512,   640,   608,   616,     0,   512,   640, 
+      608,   624,   620,     0,   512,   640,   608,   624, 
+      620,     0,   512,   640,   608,   624,   625,   622, 
+        0,   512,   640,   608,     0,   512,   640,   641, 
+      624,     0,   512,   640,   641,   624,     0,   512, 
+      640,   641,   624,   626,     0,   512,   640,   641, 
+      624,     0,   512,   640,   641,   624,   628,     0, 
+      512,   640,   641,   624,   628,     0,   512,   640, 
+      641,   624,   632,   630,     0,   512,   640,   641, 
+      624,     0,   512,   640,   641,   624,   632,     0, 
+      512,   640,   641,   643,   632,     0,   512,   640, 
+      641,   643,   632,   634,     0,   512,   640,   641, 
+      643,   632,     0,   512,   640,   641,   643,   632, 
+      636,     0,   512,   640,   641,   643,   632,   636, 
+        0,   512,   640,   641,   643,   632,   636,   638, 
+        0,   512,     0,   512,   640,     0,   512,   640, 
+        0,   512,   640,   642,     0,   512,   640,     0, 
+      512,   640,   644,     0,   512,   640,   644,     0, 
+      512,   640,   648,   646,     0,   512,   640,     0, 
+      512,   640,   648,     0,   512,   640,   648,     0, 
+      512,   640,   648,   650,     0,   512,   640,   648, 
+        0,   512,   640,   656,   652,     0,   512,   640, 
+      656,   652,     0,   512,   640,   656,   657,   654, 
+        0,   512,   640,     0,   512,   640,   656,     0, 
+      512,   640,   656,     0,   512,   640,   656,   658, 
+        0,   512,   640,   656,     0,   512,   640,   656, 
+      660,     0,   512,   640,   656,   660,     0,   512, 
+      640,   656,   664,   662,     0,   512,   640,   656, 
+        0,   512,   640,   672,   664,     0,   512,   640, 
+      672,   664,     0,   512,   640,   672,   664,   666, 
+        0,   512,   640,   672,   664,     0,   512,   640, 
+      672,   673,   668,     0,   512,   640,   672,   673, 
+      668,     0,   512,   640,   672,   673,   668,   670, 
+        0,   512,   640,     0,   512,   640,   672,     0, 
+      512,   640,   672,     0,   512,   640,   672,   674, 
+        0,   512,   640,   672,     0,   512,   640,   672, 
+      676,     0,   512,   640,   672,   676,     0,   512, 
+      640,   672,   680,   678,     0,   512,   640,   672, 
+        0,   512,   640,   672,   680,     0,   512,   640, 
+      672,   680,     0,   512,   640,   672,   680,   682, 
+        0,   512,   640,   672,   680,     0,   512,   640, 
+      672,   688,   684,     0,   512,   640,   672,   688, 
+      684,     0,   512,   640,   672,   688,   689,   686, 
+        0,   512,   640,   672,     0,   512,   640,   704, 
+      688,     0,   512,   640,   704,   688,     0,   512, 
+      640,   704,   688,   690,     0,   512,   640,   704, 
+      688,     0,   512,   640,   704,   688,   692,     0, 
+      512,   640,   704,   688,   692,     0,   512,   640, 
+      704,   688,   696,   694,     0,   512,   640,   704, 
+      688,     0,   512,   640,   704,   705,   696,     0, 
+      512,   640,   704,   705,   696,     0,   512,   640, 
+      704,   705,   696,   698,     0,   512,   640,   704, 
+      705,   696,     0,   512,   640,   704,   705,   696, 
+      700,     0,   512,   640,   704,   705,   707,   700, 
+        0,   512,   640,   704,   705,   707,   700,   702, 
+        0,   512,   640,     0,   512,   768,   704,     0, 
+      512,   768,   704,     0,   512,   768,   704,   706, 
+        0,   512,   768,   704,     0,   512,   768,   704, 
+      708,     0,   512,   768,   704,   708,     0,   512, 
+      768,   704,   712,   710,     0,   512,   768,   704, 
+        0,   512,   768,   704,   712,     0,   512,   768, 
+      704,   712,     0,   512,   768,   704,   712,   714, 
+        0,   512,   768,   704,   712,     0,   512,   768, 
+      704,   720,   716,     0,   512,   768,   704,   720, 
+      716,     0,   512,   768,   704,   720,   721,   718, 
+        0,   512,   768,   704,     0,   512,   768,   704, 
+      720,     0,   512,   768,   704,   720,     0,   512, 
+      768,   704,   720,   722,     0,   512,   768,   704, 
+      720,     0,   512,   768,   704,   720,   724,     0, 
+      512,   768,   704,   720,   724,     0,   512,   768, 
+      704,   720,   728,   726,     0,   512,   768,   704, 
+      720,     0,   512,   768,   704,   736,   728,     0, 
+      512,   768,   704,   736,   728,     0,   512,   768, 
+      704,   736,   728,   730,     0,   512,   768,   704, 
+      736,   728,     0,   512,   768,   704,   736,   737, 
+      732,     0,   512,   768,   704,   736,   737,   732, 
+        0,   512,   768,   704,   736,   737,   732,   734, 
+        0,   512,   768,   704,     0,   512,   768,   769, 
+      736,     0,   512,   768,   769,   736,     0,   512, 
+      768,   769,   736,   738,     0,   512,   768,   769, 
+      736,     0,   512,   768,   769,   736,   740,     0, 
+      512,   768,   769,   736,   740,     0,   512,   768, 
+      769,   736,   744,   742,     0,   512,   768,   769, 
+      736,     0,   512,   768,   769,   736,   744,     0, 
+      512,   768,   769,   736,   744,     0,   512,   768, 
+      769,   736,   744,   746,     0,   512,   768,   769, 
+      736,   744,     0,   512,   768,   769,   736,   752, 
+      748,     0,   512,   768,   769,   736,   752,   748, 
+        0,   512,   768,   769,   736,   752,   753,   750, 
+        0,   512,   768,   769,   736,     0,   512,   768, 
+      769,   736,   752,     0,   512,   768,   769,   771, 
+      752,     0,   512,   768,   769,   771,   752,   754, 
+        0,   512,   768,   769,   771,   752,     0,   512, 
+      768,   769,   771,   752,   756,     0,   512,   768, 
+      769,   771,   752,   756,     0,   512,   768,   769, 
+      771,   752,   760,   758,     0,   512,   768,   769, 
+      771,   752,     0,   512,   768,   769,   771,   752, 
+      760,     0,   512,   768,   769,   771,   752,   760, 
+        0,   512,   768,   769,   771,   752,   760,   762, 
+        0,   512,   768,   769,   771,   775,   760,     0, 
+      512,   768,   769,   771,   775,   760,   764,     0, 
+      512,   768,   769,   771,   775,   760,   764,     0, 
+      512,   768,   769,   771,   775,   760,   764,   766, 
+        0,   512,     0,  1024,   768,     0,  1024,   768, 
+        0,  1024,   768,   770,     0,  1024,   768,     0, 
+     1024,   768,   772,     0,  1024,   768,   772,     0, 
+     1024,   768,   776,   774,     0,  1024,   768,     0, 
+     1024,   768,   776,     0,  1024,   768,   776,     0, 
+     1024,   768,   776,   778,     0,  1024,   768,   776, 
+        0,  1024,   768,   784,   780,     0,  1024,   768, 
+      784,   780,     0,  1024,   768,   784,   785,   782, 
+        0,  1024,   768,     0,  1024,   768,   784,     0, 
+     1024,   768,   784,     0,  1024,   768,   784,   786, 
+        0,  1024,   768,   784,     0,  1024,   768,   784, 
+      788,     0,  1024,   768,   784,   788,     0,  1024, 
+      768,   784,   792,   790,     0,  1024,   768,   784, 
+        0,  1024,   768,   800,   792,     0,  1024,   768, 
+      800,   792,     0,  1024,   768,   800,   792,   794, 
+        0,  1024,   768,   800,   792,     0,  1024,   768, 
+      800,   801,   796,     0,  1024,   768,   800,   801, 
+      796,     0,  1024,   768,   800,   801,   796,   798, 
+        0,  1024,   768,     0,  1024,   768,   800,     0, 
+     1024,   768,   800,     0,  1024,   768,   800,   802, 
+        0,  1024,   768,   800,     0,  1024,   768,   800, 
+      804,     0,  1024,   768,   800,   804,     0,  1024, 
+      768,   800,   808,   806,     0,  1024,   768,   800, 
+        0,  1024,   768,   800,   808,     0,  1024,   768, 
+      800,   808,     0,  1024,   768,   800,   808,   810, 
+        0,  1024,   768,   800,   808,     0,  1024,   768, 
+      800,   816,   812,     0,  1024,   768,   800,   816, 
+      812,     0,  1024,   768,   800,   816,   817,   814, 
+        0,  1024,   768,   800,     0,  1024,   768,   832, 
+      816,     0,  1024,   768,   832,   816,     0,  1024, 
+      768,   832,   816,   818,     0,  1024,   768,   832, 
+      816,     0,  1024,   768,   832,   816,   820,     0, 
+     1024,   768,   832,   816,   820,     0,  1024,   768, 
+      832,   816,   824,   822,     0,  1024,   768,   832, 
+      816,     0,  1024,   768,   832,   833,   824,     0, 
+     1024,   768,   832,   833,   824,     0,  1024,   768, 
+      832,   833,   824,   826,     0,  1024,   768,   832, 
+      833,   824,     0,  1024,   768,   832,   833,   824, 
+      828,     0,  1024,   768,   832,   833,   835,   828, 
+        0,  1024,   768,   832,   833,   835,   828,   830, 
+        0,  1024,   768,     0,  1024,   768,   832,     0, 
+     1024,   768,   832,     0,  1024,   768,   832,   834, 
+        0,  1024,   768,   832,     0,  1024,   768,   832, 
+      836,     0,  1024,   768,   832,   836,     0,  1024, 
+      768,   832,   840,   838,     0,  1024,   768,   832, 
+        0,  1024,   768,   832,   840,     0,  1024,   768, 
+      832,   840,     0,  1024,   768,   832,   840,   842, 
+        0,  1024,   768,   832,   840,     0,  1024,   768, 
+      832,   848,   844,     0,  1024,   768,   832,   848, 
+      844,     0,  1024,   768,   832,   848,   849,   846, 
+        0,  1024,   768,   832,     0,  1024,   768,   832, 
+      848,     0,  1024,   768,   832,   848,     0,  1024, 
+      768,   832,   848,   850,     0,  1024,   768,   832, 
+      848,     0,  1024,   768,   832,   848,   852,     0, 
+     1024,   768,   832,   848,   852,     0,  1024,   768, 
+      832,   848,   856,   854,     0,  1024,   768,   832, 
+      848,     0,  1024,   768,   832,   864,   856,     0, 
+     1024,   768,   832,   864,   856,     0,  1024,   768, 
+      832,   864,   856,   858,     0,  1024,   768,   832, 
+      864,   856,     0,  1024,   768,   832,   864,   865, 
+      860,     0,  1024,   768,   832,   864,   865,   860, 
+        0,  1024,   768,   832,   864,   865,   860,   862, 
+        0,  1024,   768,   832,     0,  1024,   768,   896, 
+      864,     0,  1024,   768,   896,   864,     0,  1024, 
+      768,   896,   864,   866,     0,  1024,   768,   896, 
+      864,     0,  1024,   768,   896,   864,   868,     0, 
+     1024,   768,   896,   864,   868,     0,  1024,   768, 
+      896,   864,   872,   870,     0,  1024,   768,   896, 
+      864,     0,  1024,   768,   896,   864,   872,     0, 
+     1024,   768,   896,   864,   872,     0,  1024,   768, 
+      896,   864,   872,   874,     0,  1024,   768,   896, 
+      864,   872,     0,  1024,   768,   896,   864,   880, 
+      876,     0,  1024,   768,   896,   864,   880,   876, 
+        0,  1024,   768,   896,   864,   880,   881,   878, 
+        0,  1024,   768,   896,   864,     0,  1024,   768, 
+      896,   897,   880,     0,  1024,   768,   896,   897, 
+      880,     0,  1024,   768,   896,   897,   880,   882, 
+        0,  1024,   768,   896,   897,   880,     0,  1024, 
+      768,   896,   897,   880,   884,     0,  1024,   768, 
+      896,   897,   880,   884,     0,  1024,   768,   896, 
+      897,   880,   888,   886,     0,  1024,   768,   896, 
+      897,   880,     0,  1024,   768,   896,   897,   880, 
+      888,     0,  1024,   768,   896,   897,   899,   888, 
+        0,  1024,   768,   896,   897,   899,   888,   890, 
+        0,  1024,   768,   896,   897,   899,   888,     0, 
+     1024,   768,   896,   897,   899,   888,   892,     0, 
+     1024,   768,   896,   897,   899,   888,   892,     0, 
+     1024,   768,   896,   897,   899,   888,   892,   894, 
+        0,  1024,   768,     0,  1024,  1025,   896,     0, 
+     1024,  1025,   896,     0,  1024,  1025,   896,   898, 
+        0,  1024,  1025,   896,     0,  1024,  1025,   896, 
+      900,     0,  1024,  1025,   896,   900,     0,  1024, 
+     1025,   896,   904,   902,     0,  1024,  1025,   896, 
+        0,  1024,  1025,   896,   904,     0,  1024,  1025, 
+      896,   904,     0,  1024,  1025,   896,   904,   906, 
+        0,  1024,  1025,   896,   904,     0,  1024,  1025, 
+      896,   912,   908,     0,  1024,  1025,   896,   912, 
+      908,     0,  1024,  1025,   896,   912,   913,   910, 
+        0,  1024,  1025,   896,     0,  1024,  1025,   896, 
+      912,     0,  1024,  1025,   896,   912,     0,  1024, 
+     1025,   896,   912,   914,     0,  1024,  1025,   896, 
+      912,     0,  1024,  1025,   896,   912,   916,     0, 
+     1024,  1025,   896,   912,   916,     0,  1024,  1025, 
+      896,   912,   920,   918,     0,  1024,  1025,   896, 
+      912,     0,  1024,  1025,   896,   928,   920,     0, 
+     1024,  1025,   896,   928,   920,     0,  1024,  1025, 
+      896,   928,   920,   922,     0,  1024,  1025,   896, 
+      928,   920,     0,  1024,  1025,   896,   928,   929, 
+      924,     0,  1024,  1025,   896,   928,   929,   924, 
+        0,  1024,  1025,   896,   928,   929,   924,   926, 
+        0,  1024,  1025,   896,     0,  1024,  1025,   896, 
+      928,     0,  1024,  1025,   896,   928,     0,  1024, 
+     1025,   896,   928,   930,     0,  1024,  1025,   896, 
+      928,     0,  1024,  1025,   896,   928,   932,     0, 
+     1024,  1025,   896,   928,   932,     0,  1024,  1025, 
+      896,   928,   936,   934,     0,  1024,  1025,   896, 
+      928,     0,  1024,  1025,   896,   928,   936,     0, 
+     1024,  1025,   896,   928,   936,     0,  1024,  1025, 
+      896,   928,   936,   938,     0,  1024,  1025,   896, 
+      928,   936,     0,  1024,  1025,   896,   928,   944, 
+      940,     0,  1024,  1025,   896,   928,   944,   940, 
+        0,  1024,  1025,   896,   928,   944,   945,   942, 
+        0,  1024,  1025,   896,   928,     0,  1024,  1025, 
+      896,   960,   944,     0,  1024,  1025,   896,   960, 
+      944,     0,  1024,  1025,   896,   960,   944,   946, 
+        0,  1024,  1025,   896,   960,   944,     0,  1024, 
+     1025,   896,   960,   944,   948,     0,  1024,  1025, 
+      896,   960,   944,   948,     0,  1024,  1025,   896, 
+      960,   944,   952,   950,     0,  1024,  1025,   896, 
+      960,   944,     0,  1024,  1025,   896,   960,   961, 
+      952,     0,  1024,  1025,   896,   960,   961,   952, 
+        0,  1024,  1025,   896,   960,   961,   952,   954, 
+        0,  1024,  1025,   896,   960,   961,   952,     0, 
+     1024,  1025,   896,   960,   961,   952,   956,     0, 
+     1024,  1025,   896,   960,   961,   963,   956,     0, 
+     1024,  1025,   896,   960,   961,   963,   956,   958, 
+        0,  1024,  1025,   896,     0,  1024,  1025,   896, 
+      960,     0,  1024,  1025,  1027,   960,     0,  1024, 
+     1025,  1027,   960,   962,     0,  1024,  1025,  1027, 
+      960,     0,  1024,  1025,  1027,   960,   964,     0, 
+     1024,  1025,  1027,   960,   964,     0,  1024,  1025, 
+     1027,   960,   968,   966,     0,  1024,  1025,  1027, 
+      960,     0,  1024,  1025,  1027,   960,   968,     0, 
+     1024,  1025,  1027,   960,   968,     0,  1024,  1025, 
+     1027,   960,   968,   970,     0,  1024,  1025,  1027, 
+      960,   968,     0,  1024,  1025,  1027,   960,   976, 
+      972,     0,  1024,  1025,  1027,   960,   976,   972, 
+        0,  1024,  1025,  1027,   960,   976,   977,   974, 
+        0,  1024,  1025,  1027,   960,     0,  1024,  1025, 
+     1027,   960,   976,     0,  1024,  1025,  1027,   960, 
+      976,     0,  1024,  1025,  1027,   960,   976,   978, 
+        0,  1024,  1025,  1027,   960,   976,     0,  1024, 
+     1025,  1027,   960,   976,   980,     0,  1024,  1025, 
+     1027,   960,   976,   980,     0,  1024,  1025,  1027, 
+      960,   976,   984,   982,     0,  1024,  1025,  1027, 
+      960,   976,     0,  1024,  1025,  1027,   960,   992, 
+      984,     0,  1024,  1025,  1027,   960,   992,   984, 
+        0,  1024,  1025,  1027,   960,   992,   984,   986, 
+        0,  1024,  1025,  1027,   960,   992,   984,     0, 
+     1024,  1025,  1027,   960,   992,   993,   988,     0, 
+     1024,  1025,  1027,   960,   992,   993,   988,     0, 
+     1024,  1025,  1027,   960,   992,   993,   988,   990, 
+        0,  1024,  1025,  1027,   960,     0,  1024,  1025, 
+     1027,   960,   992,     0,  1024,  1025,  1027,   960, 
+      992,     0,  1024,  1025,  1027,   960,   992,   994, 
+        0,  1024,  1025,  1027,  1031,   992,     0,  1024, 
+     1025,  1027,  1031,   992,   996,     0,  1024,  1025, 
+     1027,  1031,   992,   996,     0,  1024,  1025,  1027, 
+     1031,   992,  1000,   998,     0,  1024,  1025,  1027, 
+     1031,   992,     0,  1024,  1025,  1027,  1031,   992, 
+     1000,     0,  1024,  1025,  1027,  1031,   992,  1000, 
+        0,  1024,  1025,  1027,  1031,   992,  1000,  1002, 
+        0,  1024,  1025,  1027,  1031,   992,  1000,     0, 
+     1024,  1025,  1027,  1031,   992,  1008,  1004,     0, 
+     1024,  1025,  1027,  1031,   992,  1008,  1004,     0, 
+     1024,  1025,  1027,  1031,   992,  1008,  1009,  1006, 
+        0,  1024,  1025,  1027,  1031,   992,     0,  1024, 
+     1025,  1027,  1031,   992,  1008,     0,  1024,  1025, 
+     1027,  1031,   992,  1008,     0,  1024,  1025,  1027, 
+     1031,   992,  1008,  1010,     0,  1024,  1025,  1027, 
+     1031,   992,  1008,     0,  1024,  1025,  1027,  1031, 
+      992,  1008,  1012,     0,  1024,  1025,  1027,  1031, 
+      992,  1008,  1012,     0,  1024,  1025,  1027,  1031, 
+      992,  1008,  1016,  1014,     0,  1024,  1025,  1027, 
+     1031,  1039,  1008,     0,  1024,  1025,  1027,  1031, 
+     1039,  1008,  1016,     0,  1024,  1025,  1027,  1031, 
+     1039,  1008,  1016,     0,  1024,  1025,  1027,  1031, 
+     1039,  1008,  1016,  1018,     0,  1024,  1025,  1027, 
+     1031,  1039,  1008,  1016,     0,  1024,  1025,  1027, 
+     1031,  1039,  1008,  1016,  1020,     0,  1024,  1025, 
+     1027,  1031,  1039,  1008,  1016,  1020,     0,  1024, 
+     1025,  1027,  1031,  1039,  1008,  1016,  1020,  1022, 
+        0,     0,  1024,     0,  1024,     0,  1024,  1026, 
+        0,  1024,     0,  1024,  1028,     0,  1024,  1028, 
+        0,  1024,  1032,  1030,     0,  1024,     0,  1024, 
+     1032,     0,  1024,  1032,     0,  1024,  1032,  1034, 
+        0,  1024,  1032,     0,  1024,  1040,  1036,     0, 
+     1024,  1040,  1036,     0,  1024,  1040,  1041,  1038, 
+        0,  1024,     0,  1024,  1040,     0,  1024,  1040, 
+        0,  1024,  1040,  1042,     0,  1024,  1040,     0, 
+     1024,  1040,  1044,     0,  1024,  1040,  1044,     0, 
+     1024,  1040,  1048,  1046,     0,  1024,  1040,     0, 
+     1024,  1056,  1048,     0,  1024,  1056,  1048,     0, 
+     1024,  1056,  1048,  1050,     0,  1024,  1056,  1048, 
+        0,  1024,  1056,  1057,  1052,     0,  1024,  1056, 
+     1057,  1052,     0,  1024,  1056,  1057,  1052,  1054, 
+        0,  1024,     0,  1024,  1056,     0,  1024,  1056, 
+        0,  1024,  1056,  1058,     0,  1024,  1056,     0, 
+     1024,  1056,  1060,     0,  1024,  1056,  1060,     0, 
+     1024,  1056,  1064,  1062,     0,  1024,  1056,     0, 
+     1024,  1056,  1064,     0,  1024,  1056,  1064,     0, 
+     1024,  1056,  1064,  1066,     0,  1024,  1056,  1064, 
+        0,  1024,  1056,  1072,  1068,     0,  1024,  1056, 
+     1072,  1068,     0,  1024,  1056,  1072,  1073,  1070, 
+        0,  1024,  1056,     0,  1024,  1088,  1072,     0, 
+     1024,  1088,  1072,     0,  1024,  1088,  1072,  1074, 
+        0,  1024,  1088,  1072,     0,  1024,  1088,  1072, 
+     1076,     0,  1024,  1088,  1072,  1076,     0,  1024, 
+     1088,  1072,  1080,  1078,     0,  1024,  1088,  1072, 
+        0,  1024,  1088,  1089,  1080,     0,  1024,  1088, 
+     1089,  1080,     0,  1024,  1088,  1089,  1080,  1082, 
+        0,  1024,  1088,  1089,  1080,     0,  1024,  1088, 
+     1089,  1080,  1084,     0,  1024,  1088,  1089,  1091, 
+     1084,     0,  1024,  1088,  1089,  1091,  1084,  1086, 
+        0,  1024,     0,  1024,  1088,     0,  1024,  1088, 
+        0,  1024,  1088,  1090,     0,  1024,  1088,     0, 
+     1024,  1088,  1092,     0,  1024,  1088,  1092,     0, 
+     1024,  1088,  1096,  1094,     0,  1024,  1088,     0, 
+     1024,  1088,  1096,     0,  1024,  1088,  1096,     0, 
+     1024,  1088,  1096,  1098,     0,  1024,  1088,  1096, 
+        0,  1024,  1088,  1104,  1100,     0,  1024,  1088, 
+     1104,  1100,     0,  1024,  1088,  1104,  1105,  1102, 
+        0,  1024,  1088,     0,  1024,  1088,  1104,     0, 
+     1024,  1088,  1104,     0,  1024,  1088,  1104,  1106, 
+        0,  1024,  1088,  1104,     0,  1024,  1088,  1104, 
+     1108,     0,  1024,  1088,  1104,  1108,     0,  1024, 
+     1088,  1104,  1112,  1110,     0,  1024,  1088,  1104, 
+        0,  1024,  1088,  1120,  1112,     0,  1024,  1088, 
+     1120,  1112,     0,  1024,  1088,  1120,  1112,  1114, 
+        0,  1024,  1088,  1120,  1112,     0,  1024,  1088, 
+     1120,  1121,  1116,     0,  1024,  1088,  1120,  1121, 
+     1116,     0,  1024,  1088,  1120,  1121,  1116,  1118, 
+        0,  1024,  1088,     0,  1024,  1152,  1120,     0, 
+     1024,  1152,  1120,     0,  1024,  1152,  1120,  1122, 
+        0,  1024,  1152,  1120,     0,  1024,  1152,  1120, 
+     1124,     0,  1024,  1152,  1120,  1124,     0,  1024, 
+     1152,  1120,  1128,  1126,     0,  1024,  1152,  1120, 
+        0,  1024,  1152,  1120,  1128,     0,  1024,  1152, 
+     1120,  1128,     0,  1024,  1152,  1120,  1128,  1130, 
+        0,  1024,  1152,  1120,  1128,     0,  1024,  1152, 
+     1120,  1136,  1132,     0,  1024,  1152,  1120,  1136, 
+     1132,     0,  1024,  1152,  1120,  1136,  1137,  1134, 
+        0,  1024,  1152,  1120,     0,  1024,  1152,  1153, 
+     1136,     0,  1024,  1152,  1153,  1136,     0,  1024, 
+     1152,  1153,  1136,  1138,     0,  1024,  1152,  1153, 
+     1136,     0,  1024,  1152,  1153,  1136,  1140,     0, 
+     1024,  1152,  1153,  1136,  1140,     0,  1024,  1152, 
+     1153,  1136,  1144,  1142,     0,  1024,  1152,  1153, 
+     1136,     0,  1024,  1152,  1153,  1136,  1144,     0, 
+     1024,  1152,  1153,  1155,  1144,     0,  1024,  1152, 
+     1153,  1155,  1144,  1146,     0,  1024,  1152,  1153, 
+     1155,  1144,     0,  1024,  1152,  1153,  1155,  1144, 
+     1148,     0,  1024,  1152,  1153,  1155,  1144,  1148, 
+        0,  1024,  1152,  1153,  1155,  1144,  1148,  1150, 
+        0,  1024,     0,  1024,  1152,     0,  1024,  1152, 
+        0,  1024,  1152,  1154,     0,  1024,  1152,     0, 
+     1024,  1152,  1156,     0,  1024,  1152,  1156,     0, 
+     1024,  1152,  1160,  1158,     0,  1024,  1152,     0, 
+     1024,  1152,  1160,     0,  1024,  1152,  1160,     0, 
+     1024,  1152,  1160,  1162,     0,  1024,  1152,  1160, 
+        0,  1024,  1152,  1168,  1164,     0,  1024,  1152, 
+     1168,  1164,     0,  1024,  1152,  1168,  1169,  1166, 
+        0,  1024,  1152,     0,  1024,  1152,  1168,     0, 
+     1024,  1152,  1168,     0,  1024,  1152,  1168,  1170, 
+        0,  1024,  1152,  1168,     0,  1024,  1152,  1168, 
+     1172,     0,  1024,  1152,  1168,  1172,     0,  1024, 
+     1152,  1168,  1176,  1174,     0,  1024,  1152,  1168, 
+        0,  1024,  1152,  1184,  1176,     0,  1024,  1152, 
+     1184,  1176,     0,  1024,  1152,  1184,  1176,  1178, 
+        0,  1024,  1152,  1184,  1176,     0,  1024,  1152, 
+     1184,  1185,  1180,     0,  1024,  1152,  1184,  1185, 
+     1180,     0,  1024,  1152,  1184,  1185,  1180,  1182, 
+        0,  1024,  1152,     0,  1024,  1152,  1184,     0, 
+     1024,  1152,  1184,     0,  1024,  1152,  1184,  1186, 
+        0,  1024,  1152,  1184,     0,  1024,  1152,  1184, 
+     1188,     0,  1024,  1152,  1184,  1188,     0,  1024, 
+     1152,  1184,  1192,  1190,     0,  1024,  1152,  1184, 
+        0,  1024,  1152,  1184,  1192,     0,  1024,  1152, 
+     1184,  1192,     0,  1024,  1152,  1184,  1192,  1194, 
+        0,  1024,  1152,  1184,  1192,     0,  1024,  1152, 
+     1184,  1200,  1196,     0,  1024,  1152,  1184,  1200, 
+     1196,     0,  1024,  1152,  1184,  1200,  1201,  1198, 
+        0,  1024,  1152,  1184,     0,  1024,  1152,  1216, 
+     1200,     0,  1024,  1152,  1216,  1200,     0,  1024, 
+     1152,  1216,  1200,  1202,     0,  1024,  1152,  1216, 
+     1200,     0,  1024,  1152,  1216,  1200,  1204,     0, 
+     1024,  1152,  1216,  1200,  1204,     0,  1024,  1152, 
+     1216,  1200,  1208,  1206,     0,  1024,  1152,  1216, 
+     1200,     0,  1024,  1152,  1216,  1217,  1208,     0, 
+     1024,  1152,  1216,  1217,  1208,     0,  1024,  1152, 
+     1216,  1217,  1208,  1210,     0,  1024,  1152,  1216, 
+     1217,  1208,     0,  1024,  1152,  1216,  1217,  1208, 
+     1212,     0,  1024,  1152,  1216,  1217,  1219,  1212, 
+        0,  1024,  1152,  1216,  1217,  1219,  1212,  1214, 
+        0,  1024,  1152,     0,  1024,  1280,  1216,     0, 
+     1024,  1280,  1216,     0,  1024,  1280,  1216,  1218, 
+        0,  1024,  1280,  1216,     0,  1024,  1280,  1216, 
+     1220,     0,  1024,  1280,  1216,  1220,     0,  1024, 
+     1280,  1216,  1224,  1222,     0,  1024,  1280,  1216, 
+        0,  1024,  1280,  1216,  1224,     0,  1024,  1280, 
+     1216,  1224,     0,  1024,  1280,  1216,  1224,  1226, 
+        0,  1024,  1280,  1216,  1224,     0,  1024,  1280, 
+     1216,  1232,  1228,     0,  1024,  1280,  1216,  1232, 
+     1228,     0,  1024,  1280,  1216,  1232,  1233,  1230, 
+        0,  1024,  1280,  1216,     0,  1024,  1280,  1216, 
+     1232,     0,  1024,  1280,  1216,  1232,     0,  1024, 
+     1280,  1216,  1232,  1234,     0,  1024,  1280,  1216, 
+     1232,     0,  1024,  1280,  1216,  1232,  1236,     0, 
+     1024,  1280,  1216,  1232,  1236,     0,  1024,  1280, 
+     1216,  1232,  1240,  1238,     0,  1024,  1280,  1216, 
+     1232,     0,  1024,  1280,  1216,  1248,  1240,     0, 
+     1024,  1280,  1216,  1248,  1240,     0,  1024,  1280, 
+     1216,  1248,  1240,  1242,     0,  1024,  1280,  1216, 
+     1248,  1240,     0,  1024,  1280,  1216,  1248,  1249, 
+     1244,     0,  1024,  1280,  1216,  1248,  1249,  1244, 
+        0,  1024,  1280,  1216,  1248,  1249,  1244,  1246, 
+        0,  1024,  1280,  1216,     0,  1024,  1280,  1281, 
+     1248,     0,  1024,  1280,  1281,  1248,     0,  1024, 
+     1280,  1281,  1248,  1250,     0,  1024,  1280,  1281, 
+     1248,     0,  1024,  1280,  1281,  1248,  1252,     0, 
+     1024,  1280,  1281,  1248,  1252,     0,  1024,  1280, 
+     1281,  1248,  1256,  1254,     0,  1024,  1280,  1281, 
+     1248,     0,  1024,  1280,  1281,  1248,  1256,     0, 
+     1024,  1280,  1281,  1248,  1256,     0,  1024,  1280, 
+     1281,  1248,  1256,  1258,     0,  1024,  1280,  1281, 
+     1248,  1256,     0,  1024,  1280,  1281,  1248,  1264, 
+     1260,     0,  1024,  1280,  1281,  1248,  1264,  1260, 
+        0,  1024,  1280,  1281,  1248,  1264,  1265,  1262, 
+        0,  1024,  1280,  1281,  1248,     0,  1024,  1280, 
+     1281,  1248,  1264,     0,  1024,  1280,  1281,  1283, 
+     1264,     0,  1024,  1280,  1281,  1283,  1264,  1266, 
+        0,  1024,  1280,  1281,  1283,  1264,     0,  1024, 
+     1280,  1281,  1283,  1264,  1268,     0,  1024,  1280, 
+     1281,  1283,  1264,  1268,     0,  1024,  1280,  1281, 
+     1283,  1264,  1272,  1270,     0,  1024,  1280,  1281, 
+     1283,  1264,     0,  1024,  1280,  1281,  1283,  1264, 
+     1272,     0,  1024,  1280,  1281,  1283,  1264,  1272, 
+        0,  1024,  1280,  1281,  1283,  1264,  1272,  1274, 
+        0,  1024,  1280,  1281,  1283,  1287,  1272,     0, 
+     1024,  1280,  1281,  1283,  1287,  1272,  1276,     0, 
+     1024,  1280,  1281,  1283,  1287,  1272,  1276,     0, 
+     1024,  1280,  1281,  1283,  1287,  1272,  1276,  1278, 
+        0,  1024,     0,  1024,  1280,     0,  1024,  1280, 
+        0,  1024,  1280,  1282,     0,  1024,  1280,     0, 
+     1024,  1280,  1284,     0,  1024,  1280,  1284,     0, 
+     1024,  1280,  1288,  1286,     0,  1024,  1280,     0, 
+     1024,  1280,  1288,     0,  1024,  1280,  1288,     0, 
+     1024,  1280,  1288,  1290,     0,  1024,  1280,  1288, 
+        0,  1024,  1280,  1296,  1292,     0,  1024,  1280, 
+     1296,  1292,     0,  1024,  1280,  1296,  1297,  1294, 
+        0,  1024,  1280,     0,  1024,  1280,  1296,     0, 
+     1024,  1280,  1296,     0,  1024,  1280,  1296,  1298, 
+        0,  1024,  1280,  1296,     0,  1024,  1280,  1296, 
+     1300,     0,  1024,  1280,  1296,  1300,     0,  1024, 
+     1280,  1296,  1304,  1302,     0,  1024,  1280,  1296, 
+        0,  1024,  1280,  1312,  1304,     0,  1024,  1280, 
+     1312,  1304,     0,  1024,  1280,  1312,  1304,  1306, 
+        0,  1024,  1280,  1312,  1304,     0,  1024,  1280, 
+     1312,  1313,  1308,     0,  1024,  1280,  1312,  1313, 
+     1308,     0,  1024,  1280,  1312,  1313,  1308,  1310, 
+        0,  1024,  1280,     0,  1024,  1280,  1312,     0, 
+     1024,  1280,  1312,     0,  1024,  1280,  1312,  1314, 
+        0,  1024,  1280,  1312,     0,  1024,  1280,  1312, 
+     1316,     0,  1024,  1280,  1312,  1316,     0,  1024, 
+     1280,  1312,  1320,  1318,     0,  1024,  1280,  1312, 
+        0,  1024,  1280,  1312,  1320,     0,  1024,  1280, 
+     1312,  1320,     0,  1024,  1280,  1312,  1320,  1322, 
+        0,  1024,  1280,  1312,  1320,     0,  1024,  1280, 
+     1312,  1328,  1324,     0,  1024,  1280,  1312,  1328, 
+     1324,     0,  1024,  1280,  1312,  1328,  1329,  1326, 
+        0,  1024,  1280,  1312,     0,  1024,  1280,  1344, 
+     1328,     0,  1024,  1280,  1344,  1328,     0,  1024, 
+     1280,  1344,  1328,  1330,     0,  1024,  1280,  1344, 
+     1328,     0,  1024,  1280,  1344,  1328,  1332,     0, 
+     1024,  1280,  1344,  1328,  1332,     0,  1024,  1280, 
+     1344,  1328,  1336,  1334,     0,  1024,  1280,  1344, 
+     1328,     0,  1024,  1280,  1344,  1345,  1336,     0, 
+     1024,  1280,  1344,  1345,  1336,     0,  1024,  1280, 
+     1344,  1345,  1336,  1338,     0,  1024,  1280,  1344, 
+     1345,  1336,     0,  1024,  1280,  1344,  1345,  1336, 
+     1340,     0,  1024,  1280,  1344,  1345,  1347,  1340, 
+        0,  1024,  1280,  1344,  1345,  1347,  1340,  1342, 
+        0,  1024,  1280,     0,  1024,  1280,  1344,     0, 
+     1024,  1280,  1344,     0,  1024,  1280,  1344,  1346, 
+        0,  1024,  1280,  1344,     0,  1024,  1280,  1344, 
+     1348,     0,  1024,  1280,  1344,  1348,     0,  1024, 
+     1280,  1344,  1352,  1350,     0,  1024,  1280,  1344, 
+        0,  1024,  1280,  1344,  1352,     0,  1024,  1280, 
+     1344,  1352,     0,  1024,  1280,  1344,  1352,  1354, 
+        0,  1024,  1280,  1344,  1352,     0,  1024,  1280, 
+     1344,  1360,  1356,     0,  1024,  1280,  1344,  1360, 
+     1356,     0,  1024,  1280,  1344,  1360,  1361,  1358, 
+        0,  1024,  1280,  1344,     0,  1024,  1280,  1344, 
+     1360,     0,  1024,  1280,  1344,  1360,     0,  1024, 
+     1280,  1344,  1360,  1362,     0,  1024,  1280,  1344, 
+     1360,     0,  1024,  1280,  1344,  1360,  1364,     0, 
+     1024,  1280,  1344,  1360,  1364,     0,  1024,  1280, 
+     1344,  1360,  1368,  1366,     0,  1024,  1280,  1344, 
+     1360,     0,  1024,  1280,  1344,  1376,  1368,     0, 
+     1024,  1280,  1344,  1376,  1368,     0,  1024,  1280, 
+     1344,  1376,  1368,  1370,     0,  1024,  1280,  1344, 
+     1376,  1368,     0,  1024,  1280,  1344,  1376,  1377, 
+     1372,     0,  1024,  1280,  1344,  1376,  1377,  1372, 
+        0,  1024,  1280,  1344,  1376,  1377,  1372,  1374, 
+        0,  1024,  1280,  1344,     0,  1024,  1280,  1408, 
+     1376,     0,  1024,  1280,  1408,  1376,     0,  1024, 
+     1280,  1408,  1376,  1378,     0,  1024,  1280,  1408, 
+     1376,     0,  1024,  1280,  1408,  1376,  1380,     0, 
+     1024,  1280,  1408,  1376,  1380,     0,  1024,  1280, 
+     1408,  1376,  1384,  1382,     0,  1024,  1280,  1408, 
+     1376,     0,  1024,  1280,  1408,  1376,  1384,     0, 
+     1024,  1280,  1408,  1376,  1384,     0,  1024,  1280, 
+     1408,  1376,  1384,  1386,     0,  1024,  1280,  1408, 
+     1376,  1384,     0,  1024,  1280,  1408,  1376,  1392, 
+     1388,     0,  1024,  1280,  1408,  1376,  1392,  1388, 
+        0,  1024,  1280,  1408,  1376,  1392,  1393,  1390, 
+        0,  1024,  1280,  1408,  1376,     0,  1024,  1280, 
+     1408,  1409,  1392,     0,  1024,  1280,  1408,  1409, 
+     1392,     0,  1024,  1280,  1408,  1409,  1392,  1394, 
+        0,  1024,  1280,  1408,  1409,  1392,     0,  1024, 
+     1280,  1408,  1409,  1392,  1396,     0,  1024,  1280, 
+     1408,  1409,  1392,  1396,     0,  1024,  1280,  1408, 
+     1409,  1392,  1400,  1398,     0,  1024,  1280,  1408, 
+     1409,  1392,     0,  1024,  1280,  1408,  1409,  1392, 
+     1400,     0,  1024,  1280,  1408,  1409,  1411,  1400, 
+        0,  1024,  1280,  1408,  1409,  1411,  1400,  1402, 
+        0,  1024,  1280,  1408,  1409,  1411,  1400,     0, 
+     1024,  1280,  1408,  1409,  1411,  1400,  1404,     0, 
+     1024,  1280,  1408,  1409,  1411,  1400,  1404,     0, 
+     1024,  1280,  1408,  1409,  1411,  1400,  1404,  1406, 
+        0,  1024,  1280,     0,  1024,  1536,  1408,     0, 
+     1024,  1536,  1408,     0,  1024,  1536,  1408,  1410, 
+        0,  1024,  1536,  1408,     0,  1024,  1536,  1408, 
+     1412,     0,  1024,  1536,  1408,  1412,     0,  1024, 
+     1536,  1408,  1416,  1414,     0,  1024,  1536,  1408, 
+        0,  1024,  1536,  1408,  1416,     0,  1024,  1536, 
+     1408,  1416,     0,  1024,  1536,  1408,  1416,  1418, 
+        0,  1024,  1536,  1408,  1416,     0,  1024,  1536, 
+     1408,  1424,  1420,     0,  1024,  1536,  1408,  1424, 
+     1420,     0,  1024,  1536,  1408,  1424,  1425,  1422, 
+        0,  1024,  1536,  1408,     0,  1024,  1536,  1408, 
+     1424,     0,  1024,  1536,  1408,  1424,     0,  1024, 
+     1536,  1408,  1424,  1426,     0,  1024,  1536,  1408, 
+     1424,     0,  1024,  1536,  1408,  1424,  1428,     0, 
+     1024,  1536,  1408,  1424,  1428,     0,  1024,  1536, 
+     1408,  1424,  1432,  1430,     0,  1024,  1536,  1408, 
+     1424,     0,  1024,  1536,  1408,  1440,  1432,     0, 
+     1024,  1536,  1408,  1440,  1432,     0,  1024,  1536, 
+     1408,  1440,  1432,  1434,     0,  1024,  1536,  1408, 
+     1440,  1432,     0,  1024,  1536,  1408,  1440,  1441, 
+     1436,     0,  1024,  1536,  1408,  1440,  1441,  1436, 
+        0,  1024,  1536,  1408,  1440,  1441,  1436,  1438, 
+        0,  1024,  1536,  1408,     0,  1024,  1536,  1408, 
+     1440,     0,  1024,  1536,  1408,  1440,     0,  1024, 
+     1536,  1408,  1440,  1442,     0,  1024,  1536,  1408, 
+     1440,     0,  1024,  1536,  1408,  1440,  1444,     0, 
+     1024,  1536,  1408,  1440,  1444,     0,  1024,  1536, 
+     1408,  1440,  1448,  1446,     0,  1024,  1536,  1408, 
+     1440,     0,  1024,  1536,  1408,  1440,  1448,     0, 
+     1024,  1536,  1408,  1440,  1448,     0,  1024,  1536, 
+     1408,  1440,  1448,  1450,     0,  1024,  1536,  1408, 
+     1440,  1448,     0,  1024,  1536,  1408,  1440,  1456, 
+     1452,     0,  1024,  1536,  1408,  1440,  1456,  1452, 
+        0,  1024,  1536,  1408,  1440,  1456,  1457,  1454, 
+        0,  1024,  1536,  1408,  1440,     0,  1024,  1536, 
+     1408,  1472,  1456,     0,  1024,  1536,  1408,  1472, 
+     1456,     0,  1024,  1536,  1408,  1472,  1456,  1458, 
+        0,  1024,  1536,  1408,  1472,  1456,     0,  1024, 
+     1536,  1408,  1472,  1456,  1460,     0,  1024,  1536, 
+     1408,  1472,  1456,  1460,     0,  1024,  1536,  1408, 
+     1472,  1456,  1464,  1462,     0,  1024,  1536,  1408, 
+     1472,  1456,     0,  1024,  1536,  1408,  1472,  1473, 
+     1464,     0,  1024,  1536,  1408,  1472,  1473,  1464, 
+        0,  1024,  1536,  1408,  1472,  1473,  1464,  1466, 
+        0,  1024,  1536,  1408,  1472,  1473,  1464,     0, 
+     1024,  1536,  1408,  1472,  1473,  1464,  1468,     0, 
+     1024,  1536,  1408,  1472,  1473,  1475,  1468,     0, 
+     1024,  1536,  1408,  1472,  1473,  1475,  1468,  1470, 
+        0,  1024,  1536,  1408,     0,  1024,  1536,  1537, 
+     1472,     0,  1024,  1536,  1537,  1472,     0,  1024, 
+     1536,  1537,  1472,  1474,     0,  1024,  1536,  1537, 
+     1472,     0,  1024,  1536,  1537,  1472,  1476,     0, 
+     1024,  1536,  1537,  1472,  1476,     0,  1024,  1536, 
+     1537,  1472,  1480,  1478,     0,  1024,  1536,  1537, 
+     1472,     0,  1024,  1536,  1537,  1472,  1480,     0, 
+     1024,  1536,  1537,  1472,  1480,     0,  1024,  1536, 
+     1537,  1472,  1480,  1482,     0,  1024,  1536,  1537, 
+     1472,  1480,     0,  1024,  1536,  1537,  1472,  1488, 
+     1484,     0,  1024,  1536,  1537,  1472,  1488,  1484, 
+        0,  1024,  1536,  1537,  1472,  1488,  1489,  1486, 
+        0,  1024,  1536,  1537,  1472,     0,  1024,  1536, 
+     1537,  1472,  1488,     0,  1024,  1536,  1537,  1472, 
+     1488,     0,  1024,  1536,  1537,  1472,  1488,  1490, 
+        0,  1024,  1536,  1537,  1472,  1488,     0,  1024, 
+     1536,  1537,  1472,  1488,  1492,     0,  1024,  1536, 
+     1537,  1472,  1488,  1492,     0,  1024,  1536,  1537, 
+     1472,  1488,  1496,  1494,     0,  1024,  1536,  1537, 
+     1472,  1488,     0,  1024,  1536,  1537,  1472,  1504, 
+     1496,     0,  1024,  1536,  1537,  1472,  1504,  1496, 
+        0,  1024,  1536,  1537,  1472,  1504,  1496,  1498, 
+        0,  1024,  1536,  1537,  1472,  1504,  1496,     0, 
+     1024,  1536,  1537,  1472,  1504,  1505,  1500,     0, 
+     1024,  1536,  1537,  1472,  1504,  1505,  1500,     0, 
+     1024,  1536,  1537,  1472,  1504,  1505,  1500,  1502, 
+        0,  1024,  1536,  1537,  1472,     0,  1024,  1536, 
+     1537,  1472,  1504,     0,  1024,  1536,  1537,  1539, 
+     1504,     0,  1024,  1536,  1537,  1539,  1504,  1506, 
+        0,  1024,  1536,  1537,  1539,  1504,     0,  1024, 
+     1536,  1537,  1539,  1504,  1508,     0,  1024,  1536, 
+     1537,  1539,  1504,  1508,     0,  1024,  1536,  1537, 
+     1539,  1504,  1512,  1510,     0,  1024,  1536,  1537, 
+     1539,  1504,     0,  1024,  1536,  1537,  1539,  1504, 
+     1512,     0,  1024,  1536,  1537,  1539,  1504,  1512, 
+        0,  1024,  1536,  1537,  1539,  1504,  1512,  1514, 
+        0,  1024,  1536,  1537,  1539,  1504,  1512,     0, 
+     1024,  1536,  1537,  1539,  1504,  1520,  1516,     0, 
+     1024,  1536,  1537,  1539,  1504,  1520,  1516,     0, 
+     1024,  1536,  1537,  1539,  1504,  1520,  1521,  1518, 
+        0,  1024,  1536,  1537,  1539,  1504,     0,  1024, 
+     1536,  1537,  1539,  1504,  1520,     0,  1024,  1536, 
+     1537,  1539,  1504,  1520,     0,  1024,  1536,  1537, 
+     1539,  1504,  1520,  1522,     0,  1024,  1536,  1537, 
+     1539,  1543,  1520,     0,  1024,  1536,  1537,  1539, 
+     1543,  1520,  1524,     0,  1024,  1536,  1537,  1539, 
+     1543,  1520,  1524,     0,  1024,  1536,  1537,  1539, 
+     1543,  1520,  1528,  1526,     0,  1024,  1536,  1537, 
+     1539,  1543,  1520,     0,  1024,  1536,  1537,  1539, 
+     1543,  1520,  1528,     0,  1024,  1536,  1537,  1539, 
+     1543,  1520,  1528,     0,  1024,  1536,  1537,  1539, 
+     1543,  1520,  1528,  1530,     0,  1024,  1536,  1537, 
+     1539,  1543,  1520,  1528,     0,  1024,  1536,  1537, 
+     1539,  1543,  1520,  1528,  1532,     0,  1024,  1536, 
+     1537,  1539,  1543,  1520,  1528,  1532,     0,  1024, 
+     1536,  1537,  1539,  1543,  1520,  1528,  1532,  1534, 
+        0,  1024,     0,  2048,  1536,     0,  2048,  1536, 
+        0,  2048,  1536,  1538,     0,  2048,  1536,     0, 
+     2048,  1536,  1540,     0,  2048,  1536,  1540,     0, 
+     2048,  1536,  1544,  1542,     0,  2048,  1536,     0, 
+     2048,  1536,  1544,     0,  2048,  1536,  1544,     0, 
+     2048,  1536,  1544,  1546,     0,  2048,  1536,  1544, 
+        0,  2048,  1536,  1552,  1548,     0,  2048,  1536, 
+     1552,  1548,     0,  2048,  1536,  1552,  1553,  1550, 
+        0,  2048,  1536,     0,  2048,  1536,  1552,     0, 
+     2048,  1536,  1552,     0,  2048,  1536,  1552,  1554, 
+        0,  2048,  1536,  1552,     0,  2048,  1536,  1552, 
+     1556,     0,  2048,  1536,  1552,  1556,     0,  2048, 
+     1536,  1552,  1560,  1558,     0,  2048,  1536,  1552, 
+        0,  2048,  1536,  1568,  1560,     0,  2048,  1536, 
+     1568,  1560,     0,  2048,  1536,  1568,  1560,  1562, 
+        0,  2048,  1536,  1568,  1560,     0,  2048,  1536, 
+     1568,  1569,  1564,     0,  2048,  1536,  1568,  1569, 
+     1564,     0,  2048,  1536,  1568,  1569,  1564,  1566, 
+        0,  2048,  1536,     0,  2048,  1536,  1568,     0, 
+     2048,  1536,  1568,     0,  2048,  1536,  1568,  1570, 
+        0,  2048,  1536,  1568,     0,  2048,  1536,  1568, 
+     1572,     0,  2048,  1536,  1568,  1572,     0,  2048, 
+     1536,  1568,  1576,  1574,     0,  2048,  1536,  1568, 
+        0,  2048,  1536,  1568,  1576,     0,  2048,  1536, 
+     1568,  1576,     0,  2048,  1536,  1568,  1576,  1578, 
+        0,  2048,  1536,  1568,  1576,     0,  2048,  1536, 
+     1568,  1584,  1580,     0,  2048,  1536,  1568,  1584, 
+     1580,     0,  2048,  1536,  1568,  1584,  1585,  1582, 
+        0,  2048,  1536,  1568,     0,  2048,  1536,  1600, 
+     1584,     0,  2048,  1536,  1600,  1584,     0,  2048, 
+     1536,  1600,  1584,  1586,     0,  2048,  1536,  1600, 
+     1584,     0,  2048,  1536,  1600,  1584,  1588,     0, 
+     2048,  1536,  1600,  1584,  1588,     0,  2048,  1536, 
+     1600,  1584,  1592,  1590,     0,  2048,  1536,  1600, 
+     1584,     0,  2048,  1536,  1600,  1601,  1592,     0, 
+     2048,  1536,  1600,  1601,  1592,     0,  2048,  1536, 
+     1600,  1601,  1592,  1594,     0,  2048,  1536,  1600, 
+     1601,  1592,     0,  2048,  1536,  1600,  1601,  1592, 
+     1596,     0,  2048,  1536,  1600,  1601,  1603,  1596, 
+        0,  2048,  1536,  1600,  1601,  1603,  1596,  1598, 
+        0,  2048,  1536,     0,  2048,  1536,  1600,     0, 
+     2048,  1536,  1600,     0,  2048,  1536,  1600,  1602, 
+        0,  2048,  1536,  1600,     0,  2048,  1536,  1600, 
+     1604,     0,  2048,  1536,  1600,  1604,     0,  2048, 
+     1536,  1600,  1608,  1606,     0,  2048,  1536,  1600, 
+        0,  2048,  1536,  1600,  1608,     0,  2048,  1536, 
+     1600,  1608,     0,  2048,  1536,  1600,  1608,  1610, 
+        0,  2048,  1536,  1600,  1608,     0,  2048,  1536, 
+     1600,  1616,  1612,     0,  2048,  1536,  1600,  1616, 
+     1612,     0,  2048,  1536,  1600,  1616,  1617,  1614, 
+        0,  2048,  1536,  1600,     0,  2048,  1536,  1600, 
+     1616,     0,  2048,  1536,  1600,  1616,     0,  2048, 
+     1536,  1600,  1616,  1618,     0,  2048,  1536,  1600, 
+     1616,     0,  2048,  1536,  1600,  1616,  1620,     0, 
+     2048,  1536,  1600,  1616,  1620,     0,  2048,  1536, 
+     1600,  1616,  1624,  1622,     0,  2048,  1536,  1600, 
+     1616,     0,  2048,  1536,  1600,  1632,  1624,     0, 
+     2048,  1536,  1600,  1632,  1624,     0,  2048,  1536, 
+     1600,  1632,  1624,  1626,     0,  2048,  1536,  1600, 
+     1632,  1624,     0,  2048,  1536,  1600,  1632,  1633, 
+     1628,     0,  2048,  1536,  1600,  1632,  1633,  1628, 
+        0,  2048,  1536,  1600,  1632,  1633,  1628,  1630, 
+        0,  2048,  1536,  1600,     0,  2048,  1536,  1664, 
+     1632,     0,  2048,  1536,  1664,  1632,     0,  2048, 
+     1536,  1664,  1632,  1634,     0,  2048,  1536,  1664, 
+     1632,     0,  2048,  1536,  1664,  1632,  1636,     0, 
+     2048,  1536,  1664,  1632,  1636,     0,  2048,  1536, 
+     1664,  1632,  1640,  1638,     0,  2048,  1536,  1664, 
+     1632,     0,  2048,  1536,  1664,  1632,  1640,     0, 
+     2048,  1536,  1664,  1632,  1640,     0,  2048,  1536, 
+     1664,  1632,  1640,  1642,     0,  2048,  1536,  1664, 
+     1632,  1640,     0,  2048,  1536,  1664,  1632,  1648, 
+     1644,     0,  2048,  1536,  1664,  1632,  1648,  1644, 
+        0,  2048,  1536,  1664,  1632,  1648,  1649,  1646, 
+        0,  2048,  1536,  1664,  1632,     0,  2048,  1536, 
+     1664,  1665,  1648,     0,  2048,  1536,  1664,  1665, 
+     1648,     0,  2048,  1536,  1664,  1665,  1648,  1650, 
+        0,  2048,  1536,  1664,  1665,  1648,     0,  2048, 
+     1536,  1664,  1665,  1648,  1652,     0,  2048,  1536, 
+     1664,  1665,  1648,  1652,     0,  2048,  1536,  1664, 
+     1665,  1648,  1656,  1654,     0,  2048,  1536,  1664, 
+     1665,  1648,     0,  2048,  1536,  1664,  1665,  1648, 
+     1656,     0,  2048,  1536,  1664,  1665,  1667,  1656, 
+        0,  2048,  1536,  1664,  1665,  1667,  1656,  1658, 
+        0,  2048,  1536,  1664,  1665,  1667,  1656,     0, 
+     2048,  1536,  1664,  1665,  1667,  1656,  1660,     0, 
+     2048,  1536,  1664,  1665,  1667,  1656,  1660,     0, 
+     2048,  1536,  1664,  1665,  1667,  1656,  1660,  1662, 
+        0,  2048,  1536,     0,  2048,  1536,  1664,     0, 
+     2048,  1536,  1664,     0,  2048,  1536,  1664,  1666, 
+        0,  2048,  1536,  1664,     0,  2048,  1536,  1664, 
+     1668,     0,  2048,  1536,  1664,  1668,     0,  2048, 
+     1536,  1664,  1672,  1670,     0,  2048,  1536,  1664, 
+        0,  2048,  1536,  1664,  1672,     0,  2048,  1536, 
+     1664,  1672,     0,  2048,  1536,  1664,  1672,  1674, 
+        0,  2048,  1536,  1664,  1672,     0,  2048,  1536, 
+     1664,  1680,  1676,     0,  2048,  1536,  1664,  1680, 
+     1676,     0,  2048,  1536,  1664,  1680,  1681,  1678, 
+        0,  2048,  1536,  1664,     0,  2048,  1536,  1664, 
+     1680,     0,  2048,  1536,  1664,  1680,     0,  2048, 
+     1536,  1664,  1680,  1682,     0,  2048,  1536,  1664, 
+     1680,     0,  2048,  1536,  1664,  1680,  1684,     0, 
+     2048,  1536,  1664,  1680,  1684,     0,  2048,  1536, 
+     1664,  1680,  1688,  1686,     0,  2048,  1536,  1664, 
+     1680,     0,  2048,  1536,  1664,  1696,  1688,     0, 
+     2048,  1536,  1664,  1696,  1688,     0,  2048,  1536, 
+     1664,  1696,  1688,  1690,     0,  2048,  1536,  1664, 
+     1696,  1688,     0,  2048,  1536,  1664,  1696,  1697, 
+     1692,     0,  2048,  1536,  1664,  1696,  1697,  1692, 
+        0,  2048,  1536,  1664,  1696,  1697,  1692,  1694, 
+        0,  2048,  1536,  1664,     0,  2048,  1536,  1664, 
+     1696,     0,  2048,  1536,  1664,  1696,     0,  2048, 
+     1536,  1664,  1696,  1698,     0,  2048,  1536,  1664, 
+     1696,     0,  2048,  1536,  1664,  1696,  1700,     0, 
+     2048,  1536,  1664,  1696,  1700,     0,  2048,  1536, 
+     1664,  1696,  1704,  1702,     0,  2048,  1536,  1664, 
+     1696,     0,  2048,  1536,  1664,  1696,  1704,     0, 
+     2048,  1536,  1664,  1696,  1704,     0,  2048,  1536, 
+     1664,  1696,  1704,  1706,     0,  2048,  1536,  1664, 
+     1696,  1704,     0,  2048,  1536,  1664,  1696,  1712, 
+     1708,     0,  2048,  1536,  1664,  1696,  1712,  1708, 
+        0,  2048,  1536,  1664,  1696,  1712,  1713,  1710, 
+        0,  2048,  1536,  1664,  1696,     0,  2048,  1536, 
+     1664,  1728,  1712,     0,  2048,  1536,  1664,  1728, 
+     1712,     0,  2048,  1536,  1664,  1728,  1712,  1714, 
+        0,  2048,  1536,  1664,  1728,  1712,     0,  2048, 
+     1536,  1664,  1728,  1712,  1716,     0,  2048,  1536, 
+     1664,  1728,  1712,  1716,     0,  2048,  1536,  1664, 
+     1728,  1712,  1720,  1718,     0,  2048,  1536,  1664, 
+     1728,  1712,     0,  2048,  1536,  1664,  1728,  1729, 
+     1720,     0,  2048,  1536,  1664,  1728,  1729,  1720, 
+        0,  2048,  1536,  1664,  1728,  1729,  1720,  1722, 
+        0,  2048,  1536,  1664,  1728,  1729,  1720,     0, 
+     2048,  1536,  1664,  1728,  1729,  1720,  1724,     0, 
+     2048,  1536,  1664,  1728,  1729,  1731,  1724,     0, 
+     2048,  1536,  1664,  1728,  1729,  1731,  1724,  1726, 
+        0,  2048,  1536,  1664,     0,  2048,  1536,  1792, 
+     1728,     0,  2048,  1536,  1792,  1728,     0,  2048, 
+     1536,  1792,  1728,  1730,     0,  2048,  1536,  1792, 
+     1728,     0,  2048,  1536,  1792,  1728,  1732,     0, 
+     2048,  1536,  1792,  1728,  1732,     0,  2048,  1536, 
+     1792,  1728,  1736,  1734,     0,  2048,  1536,  1792, 
+     1728,     0,  2048,  1536,  1792,  1728,  1736,     0, 
+     2048,  1536,  1792,  1728,  1736,     0,  2048,  1536, 
+     1792,  1728,  1736,  1738,     0,  2048,  1536,  1792, 
+     1728,  1736,     0,  2048,  1536,  1792,  1728,  1744, 
+     1740,     0,  2048,  1536,  1792,  1728,  1744,  1740, 
+        0,  2048,  1536,  1792,  1728,  1744,  1745,  1742, 
+        0,  2048,  1536,  1792,  1728,     0,  2048,  1536, 
+     1792,  1728,  1744,     0,  2048,  1536,  1792,  1728, 
+     1744,     0,  2048,  1536,  1792,  1728,  1744,  1746, 
+        0,  2048,  1536,  1792,  1728,  1744,     0,  2048, 
+     1536,  1792,  1728,  1744,  1748,     0,  2048,  1536, 
+     1792,  1728,  1744,  1748,     0,  2048,  1536,  1792, 
+     1728,  1744,  1752,  1750,     0,  2048,  1536,  1792, 
+     1728,  1744,     0,  2048,  1536,  1792,  1728,  1760, 
+     1752,     0,  2048,  1536,  1792,  1728,  1760,  1752, 
+        0,  2048,  1536,  1792,  1728,  1760,  1752,  1754, 
+        0,  2048,  1536,  1792,  1728,  1760,  1752,     0, 
+     2048,  1536,  1792,  1728,  1760,  1761,  1756,     0, 
+     2048,  1536,  1792,  1728,  1760,  1761,  1756,     0, 
+     2048,  1536,  1792,  1728,  1760,  1761,  1756,  1758, 
+        0,  2048,  1536,  1792,  1728,     0,  2048,  1536, 
+     1792,  1793,  1760,     0,  2048,  1536,  1792,  1793, 
+     1760,     0,  2048,  1536,  1792,  1793,  1760,  1762, 
+        0,  2048,  1536,  1792,  1793,  1760,     0,  2048, 
+     1536,  1792,  1793,  1760,  1764,     0,  2048,  1536, 
+     1792,  1793,  1760,  1764,     0,  2048,  1536,  1792, 
+     1793,  1760,  1768,  1766,     0,  2048,  1536,  1792, 
+     1793,  1760,     0,  2048,  1536,  1792,  1793,  1760, 
+     1768,     0,  2048,  1536,  1792,  1793,  1760,  1768, 
+        0,  2048,  1536,  1792,  1793,  1760,  1768,  1770, 
+        0,  2048,  1536,  1792,  1793,  1760,  1768,     0, 
+     2048,  1536,  1792,  1793,  1760,  1776,  1772,     0, 
+     2048,  1536,  1792,  1793,  1760,  1776,  1772,     0, 
+     2048,  1536,  1792,  1793,  1760,  1776,  1777,  1774, 
+        0,  2048,  1536,  1792,  1793,  1760,     0,  2048, 
+     1536,  1792,  1793,  1760,  1776,     0,  2048,  1536, 
+     1792,  1793,  1795,  1776,     0,  2048,  1536,  1792, 
+     1793,  1795,  1776,  1778,     0,  2048,  1536,  1792, 
+     1793,  1795,  1776,     0,  2048,  1536,  1792,  1793, 
+     1795,  1776,  1780,     0,  2048,  1536,  1792,  1793, 
+     1795,  1776,  1780,     0,  2048,  1536,  1792,  1793, 
+     1795,  1776,  1784,  1782,     0,  2048,  1536,  1792, 
+     1793,  1795,  1776,     0,  2048,  1536,  1792,  1793, 
+     1795,  1776,  1784,     0,  2048,  1536,  1792,  1793, 
+     1795,  1776,  1784,     0,  2048,  1536,  1792,  1793, 
+     1795,  1776,  1784,  1786,     0,  2048,  1536,  1792, 
+     1793,  1795,  1799,  1784,     0,  2048,  1536,  1792, 
+     1793,  1795,  1799,  1784,  1788,     0,  2048,  1536, 
+     1792,  1793,  1795,  1799,  1784,  1788,     0,  2048, 
+     1536,  1792,  1793,  1795,  1799,  1784,  1788,  1790, 
+        0,  2048,  1536,     0,  2048,  1536,  1792,     0, 
+     2048,  2049,  1792,     0,  2048,  2049,  1792,  1794, 
+        0,  2048,  2049,  1792,     0,  2048,  2049,  1792, 
+     1796,     0,  2048,  2049,  1792,  1796,     0,  2048, 
+     2049,  1792,  1800,  1798,     0,  2048,  2049,  1792, 
+        0,  2048,  2049,  1792,  1800,     0,  2048,  2049, 
+     1792,  1800,     0,  2048,  2049,  1792,  1800,  1802, 
+        0,  2048,  2049,  1792,  1800,     0,  2048,  2049, 
+     1792,  1808,  1804,     0,  2048,  2049,  1792,  1808, 
+     1804,     0,  2048,  2049,  1792,  1808,  1809,  1806, 
+        0,  2048,  2049,  1792,     0,  2048,  2049,  1792, 
+     1808,     0,  2048,  2049,  1792,  1808,     0,  2048, 
+     2049,  1792,  1808,  1810,     0,  2048,  2049,  1792, 
+     1808,     0,  2048,  2049,  1792,  1808,  1812,     0, 
+     2048,  2049,  1792,  1808,  1812,     0,  2048,  2049, 
+     1792,  1808,  1816,  1814,     0,  2048,  2049,  1792, 
+     1808,     0,  2048,  2049,  1792,  1824,  1816,     0, 
+     2048,  2049,  1792,  1824,  1816,     0,  2048,  2049, 
+     1792,  1824,  1816,  1818,     0,  2048,  2049,  1792, 
+     1824,  1816,     0,  2048,  2049,  1792,  1824,  1825, 
+     1820,     0,  2048,  2049,  1792,  1824,  1825,  1820, 
+        0,  2048,  2049,  1792,  1824,  1825,  1820,  1822, 
+        0,  2048,  2049,  1792,     0,  2048,  2049,  1792, 
+     1824,     0,  2048,  2049,  1792,  1824,     0,  2048, 
+     2049,  1792,  1824,  1826,     0,  2048,  2049,  1792, 
+     1824,     0,  2048,  2049,  1792,  1824,  1828,     0, 
+     2048,  2049,  1792,  1824,  1828,     0,  2048,  2049, 
+     1792,  1824,  1832,  1830,     0,  2048,  2049,  1792, 
+     1824,     0,  2048,  2049,  1792,  1824,  1832,     0, 
+     2048,  2049,  1792,  1824,  1832,     0,  2048,  2049, 
+     1792,  1824,  1832,  1834,     0,  2048,  2049,  1792, 
+     1824,  1832,     0,  2048,  2049,  1792,  1824,  1840, 
+     1836,     0,  2048,  2049,  1792,  1824,  1840,  1836, 
+        0,  2048,  2049,  1792,  1824,  1840,  1841,  1838, 
+        0,  2048,  2049,  1792,  1824,     0,  2048,  2049, 
+     1792,  1856,  1840,     0,  2048,  2049,  1792,  1856, 
+     1840,     0,  2048,  2049,  1792,  1856,  1840,  1842, 
+        0,  2048,  2049,  1792,  1856,  1840,     0,  2048, 
+     2049,  1792,  1856,  1840,  1844,     0,  2048,  2049, 
+     1792,  1856,  1840,  1844,     0,  2048,  2049,  1792, 
+     1856,  1840,  1848,  1846,     0,  2048,  2049,  1792, 
+     1856,  1840,     0,  2048,  2049,  1792,  1856,  1857, 
+     1848,     0,  2048,  2049,  1792,  1856,  1857,  1848, 
+        0,  2048,  2049,  1792,  1856,  1857,  1848,  1850, 
+        0,  2048,  2049,  1792,  1856,  1857,  1848,     0, 
+     2048,  2049,  1792,  1856,  1857,  1848,  1852,     0, 
+     2048,  2049,  1792,  1856,  1857,  1859,  1852,     0, 
+     2048,  2049,  1792,  1856,  1857,  1859,  1852,  1854, 
+        0,  2048,  2049,  1792,     0,  2048,  2049,  1792, 
+     1856,     0,  2048,  2049,  1792,  1856,     0,  2048, 
+     2049,  1792,  1856,  1858,     0,  2048,  2049,  1792, 
+     1856,     0,  2048,  2049,  1792,  1856,  1860,     0, 
+     2048,  2049,  1792,  1856,  1860,     0,  2048,  2049, 
+     1792,  1856,  1864,  1862,     0,  2048,  2049,  1792, 
+     1856,     0,  2048,  2049,  1792,  1856,  1864,     0, 
+     2048,  2049,  1792,  1856,  1864,     0,  2048,  2049, 
+     1792,  1856,  1864,  1866,     0,  2048,  2049,  1792, 
+     1856,  1864,     0,  2048,  2049,  1792,  1856,  1872, 
+     1868,     0,  2048,  2049,  1792,  1856,  1872,  1868, 
+        0,  2048,  2049,  1792,  1856,  1872,  1873,  1870, 
+        0,  2048,  2049,  1792,  1856,     0,  2048,  2049, 
+     1792,  1856,  1872,     0,  2048,  2049,  1792,  1856, 
+     1872,     0,  2048,  2049,  1792,  1856,  1872,  1874, 
+        0,  2048,  2049,  1792,  1856,  1872,     0,  2048, 
+     2049,  1792,  1856,  1872,  1876,     0,  2048,  2049, 
+     1792,  1856,  1872,  1876,     0,  2048,  2049,  1792, 
+     1856,  1872,  1880,  1878,     0,  2048,  2049,  1792, 
+     1856,  1872,     0,  2048,  2049,  1792,  1856,  1888, 
+     1880,     0,  2048,  2049,  1792,  1856,  1888,  1880, 
+        0,  2048,  2049,  1792,  1856,  1888,  1880,  1882, 
+        0,  2048,  2049,  1792,  1856,  1888,  1880,     0, 
+     2048,  2049,  1792,  1856,  1888,  1889,  1884,     0, 
+     2048,  2049,  1792,  1856,  1888,  1889,  1884,     0, 
+     2048,  2049,  1792,  1856,  1888,  1889,  1884,  1886, 
+        0,  2048,  2049,  1792,  1856,     0,  2048,  2049, 
+     1792,  1920,  1888,     0,  2048,  2049,  1792,  1920, 
+     1888,     0,  2048,  2049,  1792,  1920,  1888,  1890, 
+        0,  2048,  2049,  1792,  1920,  1888,     0,  2048, 
+     2049,  1792,  1920,  1888,  1892,     0,  2048,  2049, 
+     1792,  1920,  1888,  1892,     0,  2048,  2049,  1792, 
+     1920,  1888,  1896,  1894,     0,  2048,  2049,  1792, 
+     1920,  1888,     0,  2048,  2049,  1792,  1920,  1888, 
+     1896,     0,  2048,  2049,  1792,  1920,  1888,  1896, 
+        0,  2048,  2049,  1792,  1920,  1888,  1896,  1898, 
+        0,  2048,  2049,  1792,  1920,  1888,  1896,     0, 
+     2048,  2049,  1792,  1920,  1888,  1904,  1900,     0, 
+     2048,  2049,  1792,  1920,  1888,  1904,  1900,     0, 
+     2048,  2049,  1792,  1920,  1888,  1904,  1905,  1902, 
+        0,  2048,  2049,  1792,  1920,  1888,     0,  2048, 
+     2049,  1792,  1920,  1921,  1904,     0,  2048,  2049, 
+     1792,  1920,  1921,  1904,     0,  2048,  2049,  1792, 
+     1920,  1921,  1904,  1906,     0,  2048,  2049,  1792, 
+     1920,  1921,  1904,     0,  2048,  2049,  1792,  1920, 
+     1921,  1904,  1908,     0,  2048,  2049,  1792,  1920, 
+     1921,  1904,  1908,     0,  2048,  2049,  1792,  1920, 
+     1921,  1904,  1912,  1910,     0,  2048,  2049,  1792, 
+     1920,  1921,  1904,     0,  2048,  2049,  1792,  1920, 
+     1921,  1904,  1912,     0,  2048,  2049,  1792,  1920, 
+     1921,  1923,  1912,     0,  2048,  2049,  1792,  1920, 
+     1921,  1923,  1912,  1914,     0,  2048,  2049,  1792, 
+     1920,  1921,  1923,  1912,     0,  2048,  2049,  1792, 
+     1920,  1921,  1923,  1912,  1916,     0,  2048,  2049, 
+     1792,  1920,  1921,  1923,  1912,  1916,     0,  2048, 
+     2049,  1792,  1920,  1921,  1923,  1912,  1916,  1918, 
+        0,  2048,  2049,  1792,     0,  2048,  2049,  1792, 
+     1920,     0,  2048,  2049,  1792,  1920,     0,  2048, 
+     2049,  1792,  1920,  1922,     0,  2048,  2049,  2051, 
+     1920,     0,  2048,  2049,  2051,  1920,  1924,     0, 
+     2048,  2049,  2051,  1920,  1924,     0,  2048,  2049, 
+     2051,  1920,  1928,  1926,     0,  2048,  2049,  2051, 
+     1920,     0,  2048,  2049,  2051,  1920,  1928,     0, 
+     2048,  2049,  2051,  1920,  1928,     0,  2048,  2049, 
+     2051,  1920,  1928,  1930,     0,  2048,  2049,  2051, 
+     1920,  1928,     0,  2048,  2049,  2051,  1920,  1936, 
+     1932,     0,  2048,  2049,  2051,  1920,  1936,  1932, 
+        0,  2048,  2049,  2051,  1920,  1936,  1937,  1934, 
+        0,  2048,  2049,  2051,  1920,     0,  2048,  2049, 
+     2051,  1920,  1936,     0,  2048,  2049,  2051,  1920, 
+     1936,     0,  2048,  2049,  2051,  1920,  1936,  1938, 
+        0,  2048,  2049,  2051,  1920,  1936,     0,  2048, 
+     2049,  2051,  1920,  1936,  1940,     0,  2048,  2049, 
+     2051,  1920,  1936,  1940,     0,  2048,  2049,  2051, 
+     1920,  1936,  1944,  1942,     0,  2048,  2049,  2051, 
+     1920,  1936,     0,  2048,  2049,  2051,  1920,  1952, 
+     1944,     0,  2048,  2049,  2051,  1920,  1952,  1944, 
+        0,  2048,  2049,  2051,  1920,  1952,  1944,  1946, 
+        0,  2048,  2049,  2051,  1920,  1952,  1944,     0, 
+     2048,  2049,  2051,  1920,  1952,  1953,  1948,     0, 
+     2048,  2049,  2051,  1920,  1952,  1953,  1948,     0, 
+     2048,  2049,  2051,  1920,  1952,  1953,  1948,  1950, 
+        0,  2048,  2049,  2051,  1920,     0,  2048,  2049, 
+     2051,  1920,  1952,     0,  2048,  2049,  2051,  1920, 
+     1952,     0,  2048,  2049,  2051,  1920,  1952,  1954, 
+        0,  2048,  2049,  2051,  1920,  1952,     0,  2048, 
+     2049,  2051,  1920,  1952,  1956,     0,  2048,  2049, 
+     2051,  1920,  1952,  1956,     0,  2048,  2049,  2051, 
+     1920,  1952,  1960,  1958,     0,  2048,  2049,  2051, 
+     1920,  1952,     0,  2048,  2049,  2051,  1920,  1952, 
+     1960,     0,  2048,  2049,  2051,  1920,  1952,  1960, 
+        0,  2048,  2049,  2051,  1920,  1952,  1960,  1962, 
+        0,  2048,  2049,  2051,  1920,  1952,  1960,     0, 
+     2048,  2049,  2051,  1920,  1952,  1968,  1964,     0, 
+     2048,  2049,  2051,  1920,  1952,  1968,  1964,     0, 
+     2048,  2049,  2051,  1920,  1952,  1968,  1969,  1966, 
+        0,  2048,  2049,  2051,  1920,  1952,     0,  2048, 
+     2049,  2051,  1920,  1984,  1968,     0,  2048,  2049, 
+     2051,  1920,  1984,  1968,     0,  2048,  2049,  2051, 
+     1920,  1984,  1968,  1970,     0,  2048,  2049,  2051, 
+     1920,  1984,  1968,     0,  2048,  2049,  2051,  1920, 
+     1984,  1968,  1972,     0,  2048,  2049,  2051,  1920, 
+     1984,  1968,  1972,     0,  2048,  2049,  2051,  1920, 
+     1984,  1968,  1976,  1974,     0,  2048,  2049,  2051, 
+     1920,  1984,  1968,     0,  2048,  2049,  2051,  1920, 
+     1984,  1985,  1976,     0,  2048,  2049,  2051,  1920, 
+     1984,  1985,  1976,     0,  2048,  2049,  2051,  1920, 
+     1984,  1985,  1976,  1978,     0,  2048,  2049,  2051, 
+     1920,  1984,  1985,  1976,     0,  2048,  2049,  2051, 
+     1920,  1984,  1985,  1976,  1980,     0,  2048,  2049, 
+     2051,  1920,  1984,  1985,  1987,  1980,     0,  2048, 
+     2049,  2051,  1920,  1984,  1985,  1987,  1980,  1982, 
+        0,  2048,  2049,  2051,  1920,     0,  2048,  2049, 
+     2051,  1920,  1984,     0,  2048,  2049,  2051,  1920, 
+     1984,     0,  2048,  2049,  2051,  1920,  1984,  1986, 
+        0,  2048,  2049,  2051,  1920,  1984,     0,  2048, 
+     2049,  2051,  1920,  1984,  1988,     0,  2048,  2049, 
+     2051,  1920,  1984,  1988,     0,  2048,  2049,  2051, 
+     1920,  1984,  1992,  1990,     0,  2048,  2049,  2051, 
+     2055,  1984,     0,  2048,  2049,  2051,  2055,  1984, 
+     1992,     0,  2048,  2049,  2051,  2055,  1984,  1992, 
+        0,  2048,  2049,  2051,  2055,  1984,  1992,  1994, 
+        0,  2048,  2049,  2051,  2055,  1984,  1992,     0, 
+     2048,  2049,  2051,  2055,  1984,  2000,  1996,     0, 
+     2048,  2049,  2051,  2055,  1984,  2000,  1996,     0, 
+     2048,  2049,  2051,  2055,  1984,  2000,  2001,  1998, 
+        0,  2048,  2049,  2051,  2055,  1984,     0,  2048, 
+     2049,  2051,  2055,  1984,  2000,     0,  2048,  2049, 
+     2051,  2055,  1984,  2000,     0,  2048,  2049,  2051, 
+     2055,  1984,  2000,  2002,     0,  2048,  2049,  2051, 
+     2055,  1984,  2000,     0,  2048,  2049,  2051,  2055, 
+     1984,  2000,  2004,     0,  2048,  2049,  2051,  2055, 
+     1984,  2000,  2004,     0,  2048,  2049,  2051,  2055, 
+     1984,  2000,  2008,  2006,     0,  2048,  2049,  2051, 
+     2055,  1984,  2000,     0,  2048,  2049,  2051,  2055, 
+     1984,  2016,  2008,     0,  2048,  2049,  2051,  2055, 
+     1984,  2016,  2008,     0,  2048,  2049,  2051,  2055, 
+     1984,  2016,  2008,  2010,     0,  2048,  2049,  2051, 
+     2055,  1984,  2016,  2008,     0,  2048,  2049,  2051, 
+     2055,  1984,  2016,  2017,  2012,     0,  2048,  2049, 
+     2051,  2055,  1984,  2016,  2017,  2012,     0,  2048, 
+     2049,  2051,  2055,  1984,  2016,  2017,  2012,  2014, 
+        0,  2048,  2049,  2051,  2055,  1984,     0,  2048, 
+     2049,  2051,  2055,  1984,  2016,     0,  2048,  2049, 
+     2051,  2055,  1984,  2016,     0,  2048,  2049,  2051, 
+     2055,  1984,  2016,  2018,     0,  2048,  2049,  2051, 
+     2055,  1984,  2016,     0,  2048,  2049,  2051,  2055, 
+     1984,  2016,  2020,     0,  2048,  2049,  2051,  2055, 
+     1984,  2016,  2020,     0,  2048,  2049,  2051,  2055, 
+     1984,  2016,  2024,  2022,     0,  2048,  2049,  2051, 
+     2055,  1984,  2016,     0,  2048,  2049,  2051,  2055, 
+     1984,  2016,  2024,     0,  2048,  2049,  2051,  2055, 
+     1984,  2016,  2024,     0,  2048,  2049,  2051,  2055, 
+     1984,  2016,  2024,  2026,     0,  2048,  2049,  2051, 
+     2055,  1984,  2016,  2024,     0,  2048,  2049,  2051, 
+     2055,  1984,  2016,  2032,  2028,     0,  2048,  2049, 
+     2051,  2055,  1984,  2016,  2032,  2028,     0,  2048, 
+     2049,  2051,  2055,  1984,  2016,  2032,  2033,  2030, 
+        0,  2048,  2049,  2051,  2055,  2063,  2016,     0, 
+     2048,  2049,  2051,  2055,  2063,  2016,  2032,     0, 
+     2048,  2049,  2051,  2055,  2063,  2016,  2032,     0, 
+     2048,  2049,  2051,  2055,  2063,  2016,  2032,  2034, 
+        0,  2048,  2049,  2051,  2055,  2063,  2016,  2032, 
+        0,  2048,  2049,  2051,  2055,  2063,  2016,  2032, 
+     2036,     0,  2048,  2049,  2051,  2055,  2063,  2016, 
+     2032,  2036,     0,  2048,  2049,  2051,  2055,  2063, 
+     2016,  2032,  2040,  2038,     0,  2048,  2049,  2051, 
+     2055,  2063,  2016,  2032,     0,  2048,  2049,  2051, 
+     2055,  2063,  2016,  2032,  2040,     0,  2048,  2049, 
+     2051,  2055,  2063,  2016,  2032,  2040,     0,  2048, 
+     2049,  2051,  2055,  2063,  2016,  2032,  2040,  2042, 
+        0,  2048,  2049,  2051,  2055,  2063,  2016,  2032, 
+     2040,     0,  2048,  2049,  2051,  2055,  2063,  2016, 
+     2032,  2040,  2044,     0,  2048,  2049,  2051,  2055, 
+     2063,  2016,  2032,  2040,  2044,     0,  2048,  2049, 
+     2051,  2055,  2063,  2016,  2032,  2040,  2044,  2046, 
+        0,     0,  2048,     0,  2048,     0,  2048,  2050, 
+        0,  2048,     0,  2048,  2052,     0,  2048,  2052, 
+        0,  2048,  2056,  2054,     0,  2048,     0,  2048, 
+     2056,     0,  2048,  2056,     0,  2048,  2056,  2058, 
+        0,  2048,  2056,     0,  2048,  2064,  2060,     0, 
+     2048,  2064,  2060,     0,  2048,  2064,  2065,  2062, 
+        0,  2048,     0,  2048,  2064,     0,  2048,  2064, 
+        0,  2048,  2064,  2066,     0,  2048,  2064,     0, 
+     2048,  2064,  2068,     0,  2048,  2064,  2068,     0, 
+     2048,  2064,  2072,  2070,     0,  2048,  2064,     0, 
+     2048,  2080,  2072,     0,  2048,  2080,  2072,     0, 
+     2048,  2080,  2072,  2074,     0,  2048,  2080,  2072, 
+        0,  2048,  2080,  2081,  2076,     0,  2048,  2080, 
+     2081,  2076,     0,  2048,  2080,  2081,  2076,  2078, 
+        0,  2048,     0,  2048,  2080,     0,  2048,  2080, 
+        0,  2048,  2080,  2082,     0,  2048,  2080,     0, 
+     2048,  2080,  2084,     0,  2048,  2080,  2084,     0, 
+     2048,  2080,  2088,  2086,     0,  2048,  2080,     0, 
+     2048,  2080,  2088,     0,  2048,  2080,  2088,     0, 
+     2048,  2080,  2088,  2090,     0,  2048,  2080,  2088, 
+        0,  2048,  2080,  2096,  2092,     0,  2048,  2080, 
+     2096,  2092,     0,  2048,  2080,  2096,  2097,  2094, 
+        0,  2048,  2080,     0,  2048,  2112,  2096,     0, 
+     2048,  2112,  2096,     0,  2048,  2112,  2096,  2098, 
+        0,  2048,  2112,  2096,     0,  2048,  2112,  2096, 
+     2100,     0,  2048,  2112,  2096,  2100,     0,  2048, 
+     2112,  2096,  2104,  2102,     0,  2048,  2112,  2096, 
+        0,  2048,  2112,  2113,  2104,     0,  2048,  2112, 
+     2113,  2104,     0,  2048,  2112,  2113,  2104,  2106, 
+        0,  2048,  2112,  2113,  2104,     0,  2048,  2112, 
+     2113,  2104,  2108,     0,  2048,  2112,  2113,  2115, 
+     2108,     0,  2048,  2112,  2113,  2115,  2108,  2110, 
+        0,  2048,     0,  2048,  2112,     0,  2048,  2112, 
+        0,  2048,  2112,  2114,     0,  2048,  2112,     0, 
+     2048,  2112,  2116,     0,  2048,  2112,  2116,     0, 
+     2048,  2112,  2120,  2118,     0,  2048,  2112,     0, 
+     2048,  2112,  2120,     0,  2048,  2112,  2120,     0, 
+     2048,  2112,  2120,  2122,     0,  2048,  2112,  2120, 
+        0,  2048,  2112,  2128,  2124,     0,  2048,  2112, 
+     2128,  2124,     0,  2048,  2112,  2128,  2129,  2126, 
+        0,  2048,  2112,     0,  2048,  2112,  2128,     0, 
+     2048,  2112,  2128,     0,  2048,  2112,  2128,  2130, 
+        0,  2048,  2112,  2128,     0,  2048,  2112,  2128, 
+     2132,     0,  2048,  2112,  2128,  2132,     0,  2048, 
+     2112,  2128,  2136,  2134,     0,  2048,  2112,  2128, 
+        0,  2048,  2112,  2144,  2136,     0,  2048,  2112, 
+     2144,  2136,     0,  2048,  2112,  2144,  2136,  2138, 
+        0,  2048,  2112,  2144,  2136,     0,  2048,  2112, 
+     2144,  2145,  2140,     0,  2048,  2112,  2144,  2145, 
+     2140,     0,  2048,  2112,  2144,  2145,  2140,  2142, 
+        0,  2048,  2112,     0,  2048,  2176,  2144,     0, 
+     2048,  2176,  2144,     0,  2048,  2176,  2144,  2146, 
+        0,  2048,  2176,  2144,     0,  2048,  2176,  2144, 
+     2148,     0,  2048,  2176,  2144,  2148,     0,  2048, 
+     2176,  2144,  2152,  2150,     0,  2048,  2176,  2144, 
+        0,  2048,  2176,  2144,  2152,     0,  2048,  2176, 
+     2144,  2152,     0,  2048,  2176,  2144,  2152,  2154, 
+        0,  2048,  2176,  2144,  2152,     0,  2048,  2176, 
+     2144,  2160,  2156,     0,  2048,  2176,  2144,  2160, 
+     2156,     0,  2048,  2176,  2144,  2160,  2161,  2158, 
+        0,  2048,  2176,  2144,     0,  2048,  2176,  2177, 
+     2160,     0,  2048,  2176,  2177,  2160,     0,  2048, 
+     2176,  2177,  2160,  2162,     0,  2048,  2176,  2177, 
+     2160,     0,  2048,  2176,  2177,  2160,  2164,     0, 
+     2048,  2176,  2177,  2160,  2164,     0,  2048,  2176, 
+     2177,  2160,  2168,  2166,     0,  2048,  2176,  2177, 
+     2160,     0,  2048,  2176,  2177,  2160,  2168,     0, 
+     2048,  2176,  2177,  2179,  2168,     0,  2048,  2176, 
+     2177,  2179,  2168,  2170,     0,  2048,  2176,  2177, 
+     2179,  2168,     0,  2048,  2176,  2177,  2179,  2168, 
+     2172,     0,  2048,  2176,  2177,  2179,  2168,  2172, 
+        0,  2048,  2176,  2177,  2179,  2168,  2172,  2174, 
+        0,  2048,     0,  2048,  2176,     0,  2048,  2176, 
+        0,  2048,  2176,  2178,     0,  2048,  2176,     0, 
+     2048,  2176,  2180,     0,  2048,  2176,  2180,     0, 
+     2048,  2176,  2184,  2182,     0,  2048,  2176,     0, 
+     2048,  2176,  2184,     0,  2048,  2176,  2184,     0, 
+     2048,  2176,  2184,  2186,     0,  2048,  2176,  2184, 
+        0,  2048,  2176,  2192,  2188,     0,  2048,  2176, 
+     2192,  2188,     0,  2048,  2176,  2192,  2193,  2190, 
+        0,  2048,  2176,     0,  2048,  2176,  2192,     0, 
+     2048,  2176,  2192,     0,  2048,  2176,  2192,  2194, 
+        0,  2048,  2176,  2192,     0,  2048,  2176,  2192, 
+     2196,     0,  2048,  2176,  2192,  2196,     0,  2048, 
+     2176,  2192,  2200,  2198,     0,  2048,  2176,  2192, 
+        0,  2048,  2176,  2208,  2200,     0,  2048,  2176, 
+     2208,  2200,     0,  2048,  2176,  2208,  2200,  2202, 
+        0,  2048,  2176,  2208,  2200,     0,  2048,  2176, 
+     2208,  2209,  2204,     0,  2048,  2176,  2208,  2209, 
+     2204,     0,  2048,  2176,  2208,  2209,  2204,  2206, 
+        0,  2048,  2176,     0,  2048,  2176,  2208,     0, 
+     2048,  2176,  2208,     0,  2048,  2176,  2208,  2210, 
+        0,  2048,  2176,  2208,     0,  2048,  2176,  2208, 
+     2212,     0,  2048,  2176,  2208,  2212,     0,  2048, 
+     2176,  2208,  2216,  2214,     0,  2048,  2176,  2208, 
+        0,  2048,  2176,  2208,  2216,     0,  2048,  2176, 
+     2208,  2216,     0,  2048,  2176,  2208,  2216,  2218, 
+        0,  2048,  2176,  2208,  2216,     0,  2048,  2176, 
+     2208,  2224,  2220,     0,  2048,  2176,  2208,  2224, 
+     2220,     0,  2048,  2176,  2208,  2224,  2225,  2222, 
+        0,  2048,  2176,  2208,     0,  2048,  2176,  2240, 
+     2224,     0,  2048,  2176,  2240,  2224,     0,  2048, 
+     2176,  2240,  2224,  2226,     0,  2048,  2176,  2240, 
+     2224,     0,  2048,  2176,  2240,  2224,  2228,     0, 
+     2048,  2176,  2240,  2224,  2228,     0,  2048,  2176, 
+     2240,  2224,  2232,  2230,     0,  2048,  2176,  2240, 
+     2224,     0,  2048,  2176,  2240,  2241,  2232,     0, 
+     2048,  2176,  2240,  2241,  2232,     0,  2048,  2176, 
+     2240,  2241,  2232,  2234,     0,  2048,  2176,  2240, 
+     2241,  2232,     0,  2048,  2176,  2240,  2241,  2232, 
+     2236,     0,  2048,  2176,  2240,  2241,  2243,  2236, 
+        0,  2048,  2176,  2240,  2241,  2243,  2236,  2238, 
+        0,  2048,  2176,     0,  2048,  2304,  2240,     0, 
+     2048,  2304,  2240,     0,  2048,  2304,  2240,  2242, 
+        0,  2048,  2304,  2240,     0,  2048,  2304,  2240, 
+     2244,     0,  2048,  2304,  2240,  2244,     0,  2048, 
+     2304,  2240,  2248,  2246,     0,  2048,  2304,  2240, 
+        0,  2048,  2304,  2240,  2248,     0,  2048,  2304, 
+     2240,  2248,     0,  2048,  2304,  2240,  2248,  2250, 
+        0,  2048,  2304,  2240,  2248,     0,  2048,  2304, 
+     2240,  2256,  2252,     0,  2048,  2304,  2240,  2256, 
+     2252,     0,  2048,  2304,  2240,  2256,  2257,  2254, 
+        0,  2048,  2304,  2240,     0,  2048,  2304,  2240, 
+     2256,     0,  2048,  2304,  2240,  2256,     0,  2048, 
+     2304,  2240,  2256,  2258,     0,  2048,  2304,  2240, 
+     2256,     0,  2048,  2304,  2240,  2256,  2260,     0, 
+     2048,  2304,  2240,  2256,  2260,     0,  2048,  2304, 
+     2240,  2256,  2264,  2262,     0,  2048,  2304,  2240, 
+     2256,     0,  2048,  2304,  2240,  2272,  2264,     0, 
+     2048,  2304,  2240,  2272,  2264,     0,  2048,  2304, 
+     2240,  2272,  2264,  2266,     0,  2048,  2304,  2240, 
+     2272,  2264,     0,  2048,  2304,  2240,  2272,  2273, 
+     2268,     0,  2048,  2304,  2240,  2272,  2273,  2268, 
+        0,  2048,  2304,  2240,  2272,  2273,  2268,  2270, 
+        0,  2048,  2304,  2240,     0,  2048,  2304,  2305, 
+     2272,     0,  2048,  2304,  2305,  2272,     0,  2048, 
+     2304,  2305,  2272,  2274,     0,  2048,  2304,  2305, 
+     2272,     0,  2048,  2304,  2305,  2272,  2276,     0, 
+     2048,  2304,  2305,  2272,  2276,     0,  2048,  2304, 
+     2305,  2272,  2280,  2278,     0,  2048,  2304,  2305, 
+     2272,     0,  2048,  2304,  2305,  2272,  2280,     0, 
+     2048,  2304,  2305,  2272,  2280,     0,  2048,  2304, 
+     2305,  2272,  2280,  2282,     0,  2048,  2304,  2305, 
+     2272,  2280,     0,  2048,  2304,  2305,  2272,  2288, 
+     2284,     0,  2048,  2304,  2305,  2272,  2288,  2284, 
+        0,  2048,  2304,  2305,  2272,  2288,  2289,  2286, 
+        0,  2048,  2304,  2305,  2272,     0,  2048,  2304, 
+     2305,  2272,  2288,     0,  2048,  2304,  2305,  2307, 
+     2288,     0,  2048,  2304,  2305,  2307,  2288,  2290, 
+        0,  2048,  2304,  2305,  2307,  2288,     0,  2048, 
+     2304,  2305,  2307,  2288,  2292,     0,  2048,  2304, 
+     2305,  2307,  2288,  2292,     0,  2048,  2304,  2305, 
+     2307,  2288,  2296,  2294,     0,  2048,  2304,  2305, 
+     2307,  2288,     0,  2048,  2304,  2305,  2307,  2288, 
+     2296,     0,  2048,  2304,  2305,  2307,  2288,  2296, 
+        0,  2048,  2304,  2305,  2307,  2288,  2296,  2298, 
+        0,  2048,  2304,  2305,  2307,  2311,  2296,     0, 
+     2048,  2304,  2305,  2307,  2311,  2296,  2300,     0, 
+     2048,  2304,  2305,  2307,  2311,  2296,  2300,     0, 
+     2048,  2304,  2305,  2307,  2311,  2296,  2300,  2302, 
+        0,  2048,     0,  2048,  2304,     0,  2048,  2304, 
+        0,  2048,  2304,  2306,     0,  2048,  2304,     0, 
+     2048,  2304,  2308,     0,  2048,  2304,  2308,     0, 
+     2048,  2304,  2312,  2310,     0,  2048,  2304,     0, 
+     2048,  2304,  2312,     0,  2048,  2304,  2312,     0, 
+     2048,  2304,  2312,  2314,     0,  2048,  2304,  2312, 
+        0,  2048,  2304,  2320,  2316,     0,  2048,  2304, 
+     2320,  2316,     0,  2048,  2304,  2320,  2321,  2318, 
+        0,  2048,  2304,     0,  2048,  2304,  2320,     0, 
+     2048,  2304,  2320,     0,  2048,  2304,  2320,  2322, 
+        0,  2048,  2304,  2320,     0,  2048,  2304,  2320, 
+     2324,     0,  2048,  2304,  2320,  2324,     0,  2048, 
+     2304,  2320,  2328,  2326,     0,  2048,  2304,  2320, 
+        0,  2048,  2304,  2336,  2328,     0,  2048,  2304, 
+     2336,  2328,     0,  2048,  2304,  2336,  2328,  2330, 
+        0,  2048,  2304,  2336,  2328,     0,  2048,  2304, 
+     2336,  2337,  2332,     0,  2048,  2304,  2336,  2337, 
+     2332,     0,  2048,  2304,  2336,  2337,  2332,  2334, 
+        0,  2048,  2304,     0,  2048,  2304,  2336,     0, 
+     2048,  2304,  2336,     0,  2048,  2304,  2336,  2338, 
+        0,  2048,  2304,  2336,     0,  2048,  2304,  2336, 
+     2340,     0,  2048,  2304,  2336,  2340,     0,  2048, 
+     2304,  2336,  2344,  2342,     0,  2048,  2304,  2336, 
+        0,  2048,  2304,  2336,  2344,     0,  2048,  2304, 
+     2336,  2344,     0,  2048,  2304,  2336,  2344,  2346, 
+        0,  2048,  2304,  2336,  2344,     0,  2048,  2304, 
+     2336,  2352,  2348,     0,  2048,  2304,  2336,  2352, 
+     2348,     0,  2048,  2304,  2336,  2352,  2353,  2350, 
+        0,  2048,  2304,  2336,     0,  2048,  2304,  2368, 
+     2352,     0,  2048,  2304,  2368,  2352,     0,  2048, 
+     2304,  2368,  2352,  2354,     0,  2048,  2304,  2368, 
+     2352,     0,  2048,  2304,  2368,  2352,  2356,     0, 
+     2048,  2304,  2368,  2352,  2356,     0,  2048,  2304, 
+     2368,  2352,  2360,  2358,     0,  2048,  2304,  2368, 
+     2352,     0,  2048,  2304,  2368,  2369,  2360,     0, 
+     2048,  2304,  2368,  2369,  2360,     0,  2048,  2304, 
+     2368,  2369,  2360,  2362,     0,  2048,  2304,  2368, 
+     2369,  2360,     0,  2048,  2304,  2368,  2369,  2360, 
+     2364,     0,  2048,  2304,  2368,  2369,  2371,  2364, 
+        0,  2048,  2304,  2368,  2369,  2371,  2364,  2366, 
+        0,  2048,  2304,     0,  2048,  2304,  2368,     0, 
+     2048,  2304,  2368,     0,  2048,  2304,  2368,  2370, 
+        0,  2048,  2304,  2368,     0,  2048,  2304,  2368, 
+     2372,     0,  2048,  2304,  2368,  2372,     0,  2048, 
+     2304,  2368,  2376,  2374,     0,  2048,  2304,  2368, 
+        0,  2048,  2304,  2368,  2376,     0,  2048,  2304, 
+     2368,  2376,     0,  2048,  2304,  2368,  2376,  2378, 
+        0,  2048,  2304,  2368,  2376,     0,  2048,  2304, 
+     2368,  2384,  2380,     0,  2048,  2304,  2368,  2384, 
+     2380,     0,  2048,  2304,  2368,  2384,  2385,  2382, 
+        0,  2048,  2304,  2368,     0,  2048,  2304,  2368, 
+     2384,     0,  2048,  2304,  2368,  2384,     0,  2048, 
+     2304,  2368,  2384,  2386,     0,  2048,  2304,  2368, 
+     2384,     0,  2048,  2304,  2368,  2384,  2388,     0, 
+     2048,  2304,  2368,  2384,  2388,     0,  2048,  2304, 
+     2368,  2384,  2392,  2390,     0,  2048,  2304,  2368, 
+     2384,     0,  2048,  2304,  2368,  2400,  2392,     0, 
+     2048,  2304,  2368,  2400,  2392,     0,  2048,  2304, 
+     2368,  2400,  2392,  2394,     0,  2048,  2304,  2368, 
+     2400,  2392,     0,  2048,  2304,  2368,  2400,  2401, 
+     2396,     0,  2048,  2304,  2368,  2400,  2401,  2396, 
+        0,  2048,  2304,  2368,  2400,  2401,  2396,  2398, 
+        0,  2048,  2304,  2368,     0,  2048,  2304,  2432, 
+     2400,     0,  2048,  2304,  2432,  2400,     0,  2048, 
+     2304,  2432,  2400,  2402,     0,  2048,  2304,  2432, 
+     2400,     0,  2048,  2304,  2432,  2400,  2404,     0, 
+     2048,  2304,  2432,  2400,  2404,     0,  2048,  2304, 
+     2432,  2400,  2408,  2406,     0,  2048,  2304,  2432, 
+     2400,     0,  2048,  2304,  2432,  2400,  2408,     0, 
+     2048,  2304,  2432,  2400,  2408,     0,  2048,  2304, 
+     2432,  2400,  2408,  2410,     0,  2048,  2304,  2432, 
+     2400,  2408,     0,  2048,  2304,  2432,  2400,  2416, 
+     2412,     0,  2048,  2304,  2432,  2400,  2416,  2412, 
+        0,  2048,  2304,  2432,  2400,  2416,  2417,  2414, 
+        0,  2048,  2304,  2432,  2400,     0,  2048,  2304, 
+     2432,  2433,  2416,     0,  2048,  2304,  2432,  2433, 
+     2416,     0,  2048,  2304,  2432,  2433,  2416,  2418, 
+        0,  2048,  2304,  2432,  2433,  2416,     0,  2048, 
+     2304,  2432,  2433,  2416,  2420,     0,  2048,  2304, 
+     2432,  2433,  2416,  2420,     0,  2048,  2304,  2432, 
+     2433,  2416,  2424,  2422,     0,  2048,  2304,  2432, 
+     2433,  2416,     0,  2048,  2304,  2432,  2433,  2416, 
+     2424,     0,  2048,  2304,  2432,  2433,  2435,  2424, 
+        0,  2048,  2304,  2432,  2433,  2435,  2424,  2426, 
+        0,  2048,  2304,  2432,  2433,  2435,  2424,     0, 
+     2048,  2304,  2432,  2433,  2435,  2424,  2428,     0, 
+     2048,  2304,  2432,  2433,  2435,  2424,  2428,     0, 
+     2048,  2304,  2432,  2433,  2435,  2424,  2428,  2430, 
+        0,  2048,  2304,     0,  2048,  2560,  2432,     0, 
+     2048,  2560,  2432,     0,  2048,  2560,  2432,  2434, 
+        0,  2048,  2560,  2432,     0,  2048,  2560,  2432, 
+     2436,     0,  2048,  2560,  2432,  2436,     0,  2048, 
+     2560,  2432,  2440,  2438,     0,  2048,  2560,  2432, 
+        0,  2048,  2560,  2432,  2440,     0,  2048,  2560, 
+     2432,  2440,     0,  2048,  2560,  2432,  2440,  2442, 
+        0,  2048,  2560,  2432,  2440,     0,  2048,  2560, 
+     2432,  2448,  2444,     0,  2048,  2560,  2432,  2448, 
+     2444,     0,  2048,  2560,  2432,  2448,  2449,  2446, 
+        0,  2048,  2560,  2432,     0,  2048,  2560,  2432, 
+     2448,     0,  2048,  2560,  2432,  2448,     0,  2048, 
+     2560,  2432,  2448,  2450,     0,  2048,  2560,  2432, 
+     2448,     0,  2048,  2560,  2432,  2448,  2452,     0, 
+     2048,  2560,  2432,  2448,  2452,     0,  2048,  2560, 
+     2432,  2448,  2456,  2454,     0,  2048,  2560,  2432, 
+     2448,     0,  2048,  2560,  2432,  2464,  2456,     0, 
+     2048,  2560,  2432,  2464,  2456,     0,  2048,  2560, 
+     2432,  2464,  2456,  2458,     0,  2048,  2560,  2432, 
+     2464,  2456,     0,  2048,  2560,  2432,  2464,  2465, 
+     2460,     0,  2048,  2560,  2432,  2464,  2465,  2460, 
+        0,  2048,  2560,  2432,  2464,  2465,  2460,  2462, 
+        0,  2048,  2560,  2432,     0,  2048,  2560,  2432, 
+     2464,     0,  2048,  2560,  2432,  2464,     0,  2048, 
+     2560,  2432,  2464,  2466,     0,  2048,  2560,  2432, 
+     2464,     0,  2048,  2560,  2432,  2464,  2468,     0, 
+     2048,  2560,  2432,  2464,  2468,     0,  2048,  2560, 
+     2432,  2464,  2472,  2470,     0,  2048,  2560,  2432, 
+     2464,     0,  2048,  2560,  2432,  2464,  2472,     0, 
+     2048,  2560,  2432,  2464,  2472,     0,  2048,  2560, 
+     2432,  2464,  2472,  2474,     0,  2048,  2560,  2432, 
+     2464,  2472,     0,  2048,  2560,  2432,  2464,  2480, 
+     2476,     0,  2048,  2560,  2432,  2464,  2480,  2476, 
+        0,  2048,  2560,  2432,  2464,  2480,  2481,  2478, 
+        0,  2048,  2560,  2432,  2464,     0,  2048,  2560, 
+     2432,  2496,  2480,     0,  2048,  2560,  2432,  2496, 
+     2480,     0,  2048,  2560,  2432,  2496,  2480,  2482, 
+        0,  2048,  2560,  2432,  2496,  2480,     0,  2048, 
+     2560,  2432,  2496,  2480,  2484,     0,  2048,  2560, 
+     2432,  2496,  2480,  2484,     0,  2048,  2560,  2432, 
+     2496,  2480,  2488,  2486,     0,  2048,  2560,  2432, 
+     2496,  2480,     0,  2048,  2560,  2432,  2496,  2497, 
+     2488,     0,  2048,  2560,  2432,  2496,  2497,  2488, 
+        0,  2048,  2560,  2432,  2496,  2497,  2488,  2490, 
+        0,  2048,  2560,  2432,  2496,  2497,  2488,     0, 
+     2048,  2560,  2432,  2496,  2497,  2488,  2492,     0, 
+     2048,  2560,  2432,  2496,  2497,  2499,  2492,     0, 
+     2048,  2560,  2432,  2496,  2497,  2499,  2492,  2494, 
+        0,  2048,  2560,  2432,     0,  2048,  2560,  2561, 
+     2496,     0,  2048,  2560,  2561,  2496,     0,  2048, 
+     2560,  2561,  2496,  2498,     0,  2048,  2560,  2561, 
+     2496,     0,  2048,  2560,  2561,  2496,  2500,     0, 
+     2048,  2560,  2561,  2496,  2500,     0,  2048,  2560, 
+     2561,  2496,  2504,  2502,     0,  2048,  2560,  2561, 
+     2496,     0,  2048,  2560,  2561,  2496,  2504,     0, 
+     2048,  2560,  2561,  2496,  2504,     0,  2048,  2560, 
+     2561,  2496,  2504,  2506,     0,  2048,  2560,  2561, 
+     2496,  2504,     0,  2048,  2560,  2561,  2496,  2512, 
+     2508,     0,  2048,  2560,  2561,  2496,  2512,  2508, 
+        0,  2048,  2560,  2561,  2496,  2512,  2513,  2510, 
+        0,  2048,  2560,  2561,  2496,     0,  2048,  2560, 
+     2561,  2496,  2512,     0,  2048,  2560,  2561,  2496, 
+     2512,     0,  2048,  2560,  2561,  2496,  2512,  2514, 
+        0,  2048,  2560,  2561,  2496,  2512,     0,  2048, 
+     2560,  2561,  2496,  2512,  2516,     0,  2048,  2560, 
+     2561,  2496,  2512,  2516,     0,  2048,  2560,  2561, 
+     2496,  2512,  2520,  2518,     0,  2048,  2560,  2561, 
+     2496,  2512,     0,  2048,  2560,  2561,  2496,  2528, 
+     2520,     0,  2048,  2560,  2561,  2496,  2528,  2520, 
+        0,  2048,  2560,  2561,  2496,  2528,  2520,  2522, 
+        0,  2048,  2560,  2561,  2496,  2528,  2520,     0, 
+     2048,  2560,  2561,  2496,  2528,  2529,  2524,     0, 
+     2048,  2560,  2561,  2496,  2528,  2529,  2524,     0, 
+     2048,  2560,  2561,  2496,  2528,  2529,  2524,  2526, 
+        0,  2048,  2560,  2561,  2496,     0,  2048,  2560, 
+     2561,  2496,  2528,     0,  2048,  2560,  2561,  2563, 
+     2528,     0,  2048,  2560,  2561,  2563,  2528,  2530, 
+        0,  2048,  2560,  2561,  2563,  2528,     0,  2048, 
+     2560,  2561,  2563,  2528,  2532,     0,  2048,  2560, 
+     2561,  2563,  2528,  2532,     0,  2048,  2560,  2561, 
+     2563,  2528,  2536,  2534,     0,  2048,  2560,  2561, 
+     2563,  2528,     0,  2048,  2560,  2561,  2563,  2528, 
+     2536,     0,  2048,  2560,  2561,  2563,  2528,  2536, 
+        0,  2048,  2560,  2561,  2563,  2528,  2536,  2538, 
+        0,  2048,  2560,  2561,  2563,  2528,  2536,     0, 
+     2048,  2560,  2561,  2563,  2528,  2544,  2540,     0, 
+     2048,  2560,  2561,  2563,  2528,  2544,  2540,     0, 
+     2048,  2560,  2561,  2563,  2528,  2544,  2545,  2542, 
+        0,  2048,  2560,  2561,  2563,  2528,     0,  2048, 
+     2560,  2561,  2563,  2528,  2544,     0,  2048,  2560, 
+     2561,  2563,  2528,  2544,     0,  2048,  2560,  2561, 
+     2563,  2528,  2544,  2546,     0,  2048,  2560,  2561, 
+     2563,  2567,  2544,     0,  2048,  2560,  2561,  2563, 
+     2567,  2544,  2548,     0,  2048,  2560,  2561,  2563, 
+     2567,  2544,  2548,     0,  2048,  2560,  2561,  2563, 
+     2567,  2544,  2552,  2550,     0,  2048,  2560,  2561, 
+     2563,  2567,  2544,     0,  2048,  2560,  2561,  2563, 
+     2567,  2544,  2552,     0,  2048,  2560,  2561,  2563, 
+     2567,  2544,  2552,     0,  2048,  2560,  2561,  2563, 
+     2567,  2544,  2552,  2554,     0,  2048,  2560,  2561, 
+     2563,  2567,  2544,  2552,     0,  2048,  2560,  2561, 
+     2563,  2567,  2544,  2552,  2556,     0,  2048,  2560, 
+     2561,  2563,  2567,  2544,  2552,  2556,     0,  2048, 
+     2560,  2561,  2563,  2567,  2544,  2552,  2556,  2558, 
+        0,  2048,     0,  2048,  2560,     0,  2048,  2560, 
+        0,  2048,  2560,  2562,     0,  2048,  2560,     0, 
+     2048,  2560,  2564,     0,  2048,  2560,  2564,     0, 
+     2048,  2560,  2568,  2566,     0,  2048,  2560,     0, 
+     2048,  2560,  2568,     0,  2048,  2560,  2568,     0, 
+     2048,  2560,  2568,  2570,     0,  2048,  2560,  2568, 
+        0,  2048,  2560,  2576,  2572,     0,  2048,  2560, 
+     2576,  2572,     0,  2048,  2560,  2576,  2577,  2574, 
+        0,  2048,  2560,     0,  2048,  2560,  2576,     0, 
+     2048,  2560,  2576,     0,  2048,  2560,  2576,  2578, 
+        0,  2048,  2560,  2576,     0,  2048,  2560,  2576, 
+     2580,     0,  2048,  2560,  2576,  2580,     0,  2048, 
+     2560,  2576,  2584,  2582,     0,  2048,  2560,  2576, 
+        0,  2048,  2560,  2592,  2584,     0,  2048,  2560, 
+     2592,  2584,     0,  2048,  2560,  2592,  2584,  2586, 
+        0,  2048,  2560,  2592,  2584,     0,  2048,  2560, 
+     2592,  2593,  2588,     0,  2048,  2560,  2592,  2593, 
+     2588,     0,  2048,  2560,  2592,  2593,  2588,  2590, 
+        0,  2048,  2560,     0,  2048,  2560,  2592,     0, 
+     2048,  2560,  2592,     0,  2048,  2560,  2592,  2594, 
+        0,  2048,  2560,  2592,     0,  2048,  2560,  2592, 
+     2596,     0,  2048,  2560,  2592,  2596,     0,  2048, 
+     2560,  2592,  2600,  2598,     0,  2048,  2560,  2592, 
+        0,  2048,  2560,  2592,  2600,     0,  2048,  2560, 
+     2592,  2600,     0,  2048,  2560,  2592,  2600,  2602, 
+        0,  2048,  2560,  2592,  2600,     0,  2048,  2560, 
+     2592,  2608,  2604,     0,  2048,  2560,  2592,  2608, 
+     2604,     0,  2048,  2560,  2592,  2608,  2609,  2606, 
+        0,  2048,  2560,  2592,     0,  2048,  2560,  2624, 
+     2608,     0,  2048,  2560,  2624,  2608,     0,  2048, 
+     2560,  2624,  2608,  2610,     0,  2048,  2560,  2624, 
+     2608,     0,  2048,  2560,  2624,  2608,  2612,     0, 
+     2048,  2560,  2624,  2608,  2612,     0,  2048,  2560, 
+     2624,  2608,  2616,  2614,     0,  2048,  2560,  2624, 
+     2608,     0,  2048,  2560,  2624,  2625,  2616,     0, 
+     2048,  2560,  2624,  2625,  2616,     0,  2048,  2560, 
+     2624,  2625,  2616,  2618,     0,  2048,  2560,  2624, 
+     2625,  2616,     0,  2048,  2560,  2624,  2625,  2616, 
+     2620,     0,  2048,  2560,  2624,  2625,  2627,  2620, 
+        0,  2048,  2560,  2624,  2625,  2627,  2620,  2622, 
+        0,  2048,  2560,     0,  2048,  2560,  2624,     0, 
+     2048,  2560,  2624,     0,  2048,  2560,  2624,  2626, 
+        0,  2048,  2560,  2624,     0,  2048,  2560,  2624, 
+     2628,     0,  2048,  2560,  2624,  2628,     0,  2048, 
+     2560,  2624,  2632,  2630,     0,  2048,  2560,  2624, 
+        0,  2048,  2560,  2624,  2632,     0,  2048,  2560, 
+     2624,  2632,     0,  2048,  2560,  2624,  2632,  2634, 
+        0,  2048,  2560,  2624,  2632,     0,  2048,  2560, 
+     2624,  2640,  2636,     0,  2048,  2560,  2624,  2640, 
+     2636,     0,  2048,  2560,  2624,  2640,  2641,  2638, 
+        0,  2048,  2560,  2624,     0,  2048,  2560,  2624, 
+     2640,     0,  2048,  2560,  2624,  2640,     0,  2048, 
+     2560,  2624,  2640,  2642,     0,  2048,  2560,  2624, 
+     2640,     0,  2048,  2560,  2624,  2640,  2644,     0, 
+     2048,  2560,  2624,  2640,  2644,     0,  2048,  2560, 
+     2624,  2640,  2648,  2646,     0,  2048,  2560,  2624, 
+     2640,     0,  2048,  2560,  2624,  2656,  2648,     0, 
+     2048,  2560,  2624,  2656,  2648,     0,  2048,  2560, 
+     2624,  2656,  2648,  2650,     0,  2048,  2560,  2624, 
+     2656,  2648,     0,  2048,  2560,  2624,  2656,  2657, 
+     2652,     0,  2048,  2560,  2624,  2656,  2657,  2652, 
+        0,  2048,  2560,  2624,  2656,  2657,  2652,  2654, 
+        0,  2048,  2560,  2624,     0,  2048,  2560,  2688, 
+     2656,     0,  2048,  2560,  2688,  2656,     0,  2048, 
+     2560,  2688,  2656,  2658,     0,  2048,  2560,  2688, 
+     2656,     0,  2048,  2560,  2688,  2656,  2660,     0, 
+     2048,  2560,  2688,  2656,  2660,     0,  2048,  2560, 
+     2688,  2656,  2664,  2662,     0,  2048,  2560,  2688, 
+     2656,     0,  2048,  2560,  2688,  2656,  2664,     0, 
+     2048,  2560,  2688,  2656,  2664,     0,  2048,  2560, 
+     2688,  2656,  2664,  2666,     0,  2048,  2560,  2688, 
+     2656,  2664,     0,  2048,  2560,  2688,  2656,  2672, 
+     2668,     0,  2048,  2560,  2688,  2656,  2672,  2668, 
+        0,  2048,  2560,  2688,  2656,  2672,  2673,  2670, 
+        0,  2048,  2560,  2688,  2656,     0,  2048,  2560, 
+     2688,  2689,  2672,     0,  2048,  2560,  2688,  2689, 
+     2672,     0,  2048,  2560,  2688,  2689,  2672,  2674, 
+        0,  2048,  2560,  2688,  2689,  2672,     0,  2048, 
+     2560,  2688,  2689,  2672,  2676,     0,  2048,  2560, 
+     2688,  2689,  2672,  2676,     0,  2048,  2560,  2688, 
+     2689,  2672,  2680,  2678,     0,  2048,  2560,  2688, 
+     2689,  2672,     0,  2048,  2560,  2688,  2689,  2672, 
+     2680,     0,  2048,  2560,  2688,  2689,  2691,  2680, 
+        0,  2048,  2560,  2688,  2689,  2691,  2680,  2682, 
+        0,  2048,  2560,  2688,  2689,  2691,  2680,     0, 
+     2048,  2560,  2688,  2689,  2691,  2680,  2684,     0, 
+     2048,  2560,  2688,  2689,  2691,  2680,  2684,     0, 
+     2048,  2560,  2688,  2689,  2691,  2680,  2684,  2686, 
+        0,  2048,  2560,     0,  2048,  2560,  2688,     0, 
+     2048,  2560,  2688,     0,  2048,  2560,  2688,  2690, 
+        0,  2048,  2560,  2688,     0,  2048,  2560,  2688, 
+     2692,     0,  2048,  2560,  2688,  2692,     0,  2048, 
+     2560,  2688,  2696,  2694,     0,  2048,  2560,  2688, 
+        0,  2048,  2560,  2688,  2696,     0,  2048,  2560, 
+     2688,  2696,     0,  2048,  2560,  2688,  2696,  2698, 
+        0,  2048,  2560,  2688,  2696,     0,  2048,  2560, 
+     2688,  2704,  2700,     0,  2048,  2560,  2688,  2704, 
+     2700,     0,  2048,  2560,  2688,  2704,  2705,  2702, 
+        0,  2048,  2560,  2688,     0,  2048,  2560,  2688, 
+     2704,     0,  2048,  2560,  2688,  2704,     0,  2048, 
+     2560,  2688,  2704,  2706,     0,  2048,  2560,  2688, 
+     2704,     0,  2048,  2560,  2688,  2704,  2708,     0, 
+     2048,  2560,  2688,  2704,  2708,     0,  2048,  2560, 
+     2688,  2704,  2712,  2710,     0,  2048,  2560,  2688, 
+     2704,     0,  2048,  2560,  2688,  2720,  2712,     0, 
+     2048,  2560,  2688,  2720,  2712,     0,  2048,  2560, 
+     2688,  2720,  2712,  2714,     0,  2048,  2560,  2688, 
+     2720,  2712,     0,  2048,  2560,  2688,  2720,  2721, 
+     2716,     0,  2048,  2560,  2688,  2720,  2721,  2716, 
+        0,  2048,  2560,  2688,  2720,  2721,  2716,  2718, 
+        0,  2048,  2560,  2688,     0,  2048,  2560,  2688, 
+     2720,     0,  2048,  2560,  2688,  2720,     0,  2048, 
+     2560,  2688,  2720,  2722,     0,  2048,  2560,  2688, 
+     2720,     0,  2048,  2560,  2688,  2720,  2724,     0, 
+     2048,  2560,  2688,  2720,  2724,     0,  2048,  2560, 
+     2688,  2720,  2728,  2726,     0,  2048,  2560,  2688, 
+     2720,     0,  2048,  2560,  2688,  2720,  2728,     0, 
+     2048,  2560,  2688,  2720,  2728,     0,  2048,  2560, 
+     2688,  2720,  2728,  2730,     0,  2048,  2560,  2688, 
+     2720,  2728,     0,  2048,  2560,  2688,  2720,  2736, 
+     2732,     0,  2048,  2560,  2688,  2720,  2736,  2732, 
+        0,  2048,  2560,  2688,  2720,  2736,  2737,  2734, 
+        0,  2048,  2560,  2688,  2720,     0,  2048,  2560, 
+     2688,  2752,  2736,     0,  2048,  2560,  2688,  2752, 
+     2736,     0,  2048,  2560,  2688,  2752,  2736,  2738, 
+        0,  2048,  2560,  2688,  2752,  2736,     0,  2048, 
+     2560,  2688,  2752,  2736,  2740,     0,  2048,  2560, 
+     2688,  2752,  2736,  2740,     0,  2048,  2560,  2688, 
+     2752,  2736,  2744,  2742,     0,  2048,  2560,  2688, 
+     2752,  2736,     0,  2048,  2560,  2688,  2752,  2753, 
+     2744,     0,  2048,  2560,  2688,  2752,  2753,  2744, 
+        0,  2048,  2560,  2688,  2752,  2753,  2744,  2746, 
+        0,  2048,  2560,  2688,  2752,  2753,  2744,     0, 
+     2048,  2560,  2688,  2752,  2753,  2744,  2748,     0, 
+     2048,  2560,  2688,  2752,  2753,  2755,  2748,     0, 
+     2048,  2560,  2688,  2752,  2753,  2755,  2748,  2750, 
+        0,  2048,  2560,  2688,     0,  2048,  2560,  2816, 
+     2752,     0,  2048,  2560,  2816,  2752,     0,  2048, 
+     2560,  2816,  2752,  2754,     0,  2048,  2560,  2816, 
+     2752,     0,  2048,  2560,  2816,  2752,  2756,     0, 
+     2048,  2560,  2816,  2752,  2756,     0,  2048,  2560, 
+     2816,  2752,  2760,  2758,     0,  2048,  2560,  2816, 
+     2752,     0,  2048,  2560,  2816,  2752,  2760,     0, 
+     2048,  2560,  2816,  2752,  2760,     0,  2048,  2560, 
+     2816,  2752,  2760,  2762,     0,  2048,  2560,  2816, 
+     2752,  2760,     0,  2048,  2560,  2816,  2752,  2768, 
+     2764,     0,  2048,  2560,  2816,  2752,  2768,  2764, 
+        0,  2048,  2560,  2816,  2752,  2768,  2769,  2766, 
+        0,  2048,  2560,  2816,  2752,     0,  2048,  2560, 
+     2816,  2752,  2768,     0,  2048,  2560,  2816,  2752, 
+     2768,     0,  2048,  2560,  2816,  2752,  2768,  2770, 
+        0,  2048,  2560,  2816,  2752,  2768,     0,  2048, 
+     2560,  2816,  2752,  2768,  2772,     0,  2048,  2560, 
+     2816,  2752,  2768,  2772,     0,  2048,  2560,  2816, 
+     2752,  2768,  2776,  2774,     0,  2048,  2560,  2816, 
+     2752,  2768,     0,  2048,  2560,  2816,  2752,  2784, 
+     2776,     0,  2048,  2560,  2816,  2752,  2784,  2776, 
+        0,  2048,  2560,  2816,  2752,  2784,  2776,  2778, 
+        0,  2048,  2560,  2816,  2752,  2784,  2776,     0, 
+     2048,  2560,  2816,  2752,  2784,  2785,  2780,     0, 
+     2048,  2560,  2816,  2752,  2784,  2785,  2780,     0, 
+     2048,  2560,  2816,  2752,  2784,  2785,  2780,  2782, 
+        0,  2048,  2560,  2816,  2752,     0,  2048,  2560, 
+     2816,  2817,  2784,     0,  2048,  2560,  2816,  2817, 
+     2784,     0,  2048,  2560,  2816,  2817,  2784,  2786, 
+        0,  2048,  2560,  2816,  2817,  2784,     0,  2048, 
+     2560,  2816,  2817,  2784,  2788,     0,  2048,  2560, 
+     2816,  2817,  2784,  2788,     0,  2048,  2560,  2816, 
+     2817,  2784,  2792,  2790,     0,  2048,  2560,  2816, 
+     2817,  2784,     0,  2048,  2560,  2816,  2817,  2784, 
+     2792,     0,  2048,  2560,  2816,  2817,  2784,  2792, 
+        0,  2048,  2560,  2816,  2817,  2784,  2792,  2794, 
+        0,  2048,  2560,  2816,  2817,  2784,  2792,     0, 
+     2048,  2560,  2816,  2817,  2784,  2800,  2796,     0, 
+     2048,  2560,  2816,  2817,  2784,  2800,  2796,     0, 
+     2048,  2560,  2816,  2817,  2784,  2800,  2801,  2798, 
+        0,  2048,  2560,  2816,  2817,  2784,     0,  2048, 
+     2560,  2816,  2817,  2784,  2800,     0,  2048,  2560, 
+     2816,  2817,  2819,  2800,     0,  2048,  2560,  2816, 
+     2817,  2819,  2800,  2802,     0,  2048,  2560,  2816, 
+     2817,  2819,  2800,     0,  2048,  2560,  2816,  2817, 
+     2819,  2800,  2804,     0,  2048,  2560,  2816,  2817, 
+     2819,  2800,  2804,     0,  2048,  2560,  2816,  2817, 
+     2819,  2800,  2808,  2806,     0,  2048,  2560,  2816, 
+     2817,  2819,  2800,     0,  2048,  2560,  2816,  2817, 
+     2819,  2800,  2808,     0,  2048,  2560,  2816,  2817, 
+     2819,  2800,  2808,     0,  2048,  2560,  2816,  2817, 
+     2819,  2800,  2808,  2810,     0,  2048,  2560,  2816, 
+     2817,  2819,  2823,  2808,     0,  2048,  2560,  2816, 
+     2817,  2819,  2823,  2808,  2812,     0,  2048,  2560, 
+     2816,  2817,  2819,  2823,  2808,  2812,     0,  2048, 
+     2560,  2816,  2817,  2819,  2823,  2808,  2812,  2814, 
+        0,  2048,  2560,     0,  2048,  3072,  2816,     0, 
+     2048,  3072,  2816,     0,  2048,  3072,  2816,  2818, 
+        0,  2048,  3072,  2816,     0,  2048,  3072,  2816, 
+     2820,     0,  2048,  3072,  2816,  2820,     0,  2048, 
+     3072,  2816,  2824,  2822,     0,  2048,  3072,  2816, 
+        0,  2048,  3072,  2816,  2824,     0,  2048,  3072, 
+     2816,  2824,     0,  2048,  3072,  2816,  2824,  2826, 
+        0,  2048,  3072,  2816,  2824,     0,  2048,  3072, 
+     2816,  2832,  2828,     0,  2048,  3072,  2816,  2832, 
+     2828,     0,  2048,  3072,  2816,  2832,  2833,  2830, 
+        0,  2048,  3072,  2816,     0,  2048,  3072,  2816, 
+     2832,     0,  2048,  3072,  2816,  2832,     0,  2048, 
+     3072,  2816,  2832,  2834,     0,  2048,  3072,  2816, 
+     2832,     0,  2048,  3072,  2816,  2832,  2836,     0, 
+     2048,  3072,  2816,  2832,  2836,     0,  2048,  3072, 
+     2816,  2832,  2840,  2838,     0,  2048,  3072,  2816, 
+     2832,     0,  2048,  3072,  2816,  2848,  2840,     0, 
+     2048,  3072,  2816,  2848,  2840,     0,  2048,  3072, 
+     2816,  2848,  2840,  2842,     0,  2048,  3072,  2816, 
+     2848,  2840,     0,  2048,  3072,  2816,  2848,  2849, 
+     2844,     0,  2048,  3072,  2816,  2848,  2849,  2844, 
+        0,  2048,  3072,  2816,  2848,  2849,  2844,  2846, 
+        0,  2048,  3072,  2816,     0,  2048,  3072,  2816, 
+     2848,     0,  2048,  3072,  2816,  2848,     0,  2048, 
+     3072,  2816,  2848,  2850,     0,  2048,  3072,  2816, 
+     2848,     0,  2048,  3072,  2816,  2848,  2852,     0, 
+     2048,  3072,  2816,  2848,  2852,     0,  2048,  3072, 
+     2816,  2848,  2856,  2854,     0,  2048,  3072,  2816, 
+     2848,     0,  2048,  3072,  2816,  2848,  2856,     0, 
+     2048,  3072,  2816,  2848,  2856,     0,  2048,  3072, 
+     2816,  2848,  2856,  2858,     0,  2048,  3072,  2816, 
+     2848,  2856,     0,  2048,  3072,  2816,  2848,  2864, 
+     2860,     0,  2048,  3072,  2816,  2848,  2864,  2860, 
+        0,  2048,  3072,  2816,  2848,  2864,  2865,  2862, 
+        0,  2048,  3072,  2816,  2848,     0,  2048,  3072, 
+     2816,  2880,  2864,     0,  2048,  3072,  2816,  2880, 
+     2864,     0,  2048,  3072,  2816,  2880,  2864,  2866, 
+        0,  2048,  3072,  2816,  2880,  2864,     0,  2048, 
+     3072,  2816,  2880,  2864,  2868,     0,  2048,  3072, 
+     2816,  2880,  2864,  2868,     0,  2048,  3072,  2816, 
+     2880,  2864,  2872,  2870,     0,  2048,  3072,  2816, 
+     2880,  2864,     0,  2048,  3072,  2816,  2880,  2881, 
+     2872,     0,  2048,  3072,  2816,  2880,  2881,  2872, 
+        0,  2048,  3072,  2816,  2880,  2881,  2872,  2874, 
+        0,  2048,  3072,  2816,  2880,  2881,  2872,     0, 
+     2048,  3072,  2816,  2880,  2881,  2872,  2876,     0, 
+     2048,  3072,  2816,  2880,  2881,  2883,  2876,     0, 
+     2048,  3072,  2816,  2880,  2881,  2883,  2876,  2878, 
+        0,  2048,  3072,  2816,     0,  2048,  3072,  2816, 
+     2880,     0,  2048,  3072,  2816,  2880,     0,  2048, 
+     3072,  2816,  2880,  2882,     0,  2048,  3072,  2816, 
+     2880,     0,  2048,  3072,  2816,  2880,  2884,     0, 
+     2048,  3072,  2816,  2880,  2884,     0,  2048,  3072, 
+     2816,  2880,  2888,  2886,     0,  2048,  3072,  2816, 
+     2880,     0,  2048,  3072,  2816,  2880,  2888,     0, 
+     2048,  3072,  2816,  2880,  2888,     0,  2048,  3072, 
+     2816,  2880,  2888,  2890,     0,  2048,  3072,  2816, 
+     2880,  2888,     0,  2048,  3072,  2816,  2880,  2896, 
+     2892,     0,  2048,  3072,  2816,  2880,  2896,  2892, 
+        0,  2048,  3072,  2816,  2880,  2896,  2897,  2894, 
+        0,  2048,  3072,  2816,  2880,     0,  2048,  3072, 
+     2816,  2880,  2896,     0,  2048,  3072,  2816,  2880, 
+     2896,     0,  2048,  3072,  2816,  2880,  2896,  2898, 
+        0,  2048,  3072,  2816,  2880,  2896,     0,  2048, 
+     3072,  2816,  2880,  2896,  2900,     0,  2048,  3072, 
+     2816,  2880,  2896,  2900,     0,  2048,  3072,  2816, 
+     2880,  2896,  2904,  2902,     0,  2048,  3072,  2816, 
+     2880,  2896,     0,  2048,  3072,  2816,  2880,  2912, 
+     2904,     0,  2048,  3072,  2816,  2880,  2912,  2904, 
+        0,  2048,  3072,  2816,  2880,  2912,  2904,  2906, 
+        0,  2048,  3072,  2816,  2880,  2912,  2904,     0, 
+     2048,  3072,  2816,  2880,  2912,  2913,  2908,     0, 
+     2048,  3072,  2816,  2880,  2912,  2913,  2908,     0, 
+     2048,  3072,  2816,  2880,  2912,  2913,  2908,  2910, 
+        0,  2048,  3072,  2816,  2880,     0,  2048,  3072, 
+     2816,  2944,  2912,     0,  2048,  3072,  2816,  2944, 
+     2912,     0,  2048,  3072,  2816,  2944,  2912,  2914, 
+        0,  2048,  3072,  2816,  2944,  2912,     0,  2048, 
+     3072,  2816,  2944,  2912,  2916,     0,  2048,  3072, 
+     2816,  2944,  2912,  2916,     0,  2048,  3072,  2816, 
+     2944,  2912,  2920,  2918,     0,  2048,  3072,  2816, 
+     2944,  2912,     0,  2048,  3072,  2816,  2944,  2912, 
+     2920,     0,  2048,  3072,  2816,  2944,  2912,  2920, 
+        0,  2048,  3072,  2816,  2944,  2912,  2920,  2922, 
+        0,  2048,  3072,  2816,  2944,  2912,  2920,     0, 
+     2048,  3072,  2816,  2944,  2912,  2928,  2924,     0, 
+     2048,  3072,  2816,  2944,  2912,  2928,  2924,     0, 
+     2048,  3072,  2816,  2944,  2912,  2928,  2929,  2926, 
+        0,  2048,  3072,  2816,  2944,  2912,     0,  2048, 
+     3072,  2816,  2944,  2945,  2928,     0,  2048,  3072, 
+     2816,  2944,  2945,  2928,     0,  2048,  3072,  2816, 
+     2944,  2945,  2928,  2930,     0,  2048,  3072,  2816, 
+     2944,  2945,  2928,     0,  2048,  3072,  2816,  2944, 
+     2945,  2928,  2932,     0,  2048,  3072,  2816,  2944, 
+     2945,  2928,  2932,     0,  2048,  3072,  2816,  2944, 
+     2945,  2928,  2936,  2934,     0,  2048,  3072,  2816, 
+     2944,  2945,  2928,     0,  2048,  3072,  2816,  2944, 
+     2945,  2928,  2936,     0,  2048,  3072,  2816,  2944, 
+     2945,  2947,  2936,     0,  2048,  3072,  2816,  2944, 
+     2945,  2947,  2936,  2938,     0,  2048,  3072,  2816, 
+     2944,  2945,  2947,  2936,     0,  2048,  3072,  2816, 
+     2944,  2945,  2947,  2936,  2940,     0,  2048,  3072, 
+     2816,  2944,  2945,  2947,  2936,  2940,     0,  2048, 
+     3072,  2816,  2944,  2945,  2947,  2936,  2940,  2942, 
+        0,  2048,  3072,  2816,     0,  2048,  3072,  2816, 
+     2944,     0,  2048,  3072,  3073,  2944,     0,  2048, 
+     3072,  3073,  2944,  2946,     0,  2048,  3072,  3073, 
+     2944,     0,  2048,  3072,  3073,  2944,  2948,     0, 
+     2048,  3072,  3073,  2944,  2948,     0,  2048,  3072, 
+     3073,  2944,  2952,  2950,     0,  2048,  3072,  3073, 
+     2944,     0,  2048,  3072,  3073,  2944,  2952,     0, 
+     2048,  3072,  3073,  2944,  2952,     0,  2048,  3072, 
+     3073,  2944,  2952,  2954,     0,  2048,  3072,  3073, 
+     2944,  2952,     0,  2048,  3072,  3073,  2944,  2960, 
+     2956,     0,  2048,  3072,  3073,  2944,  2960,  2956, 
+        0,  2048,  3072,  3073,  2944,  2960,  2961,  2958, 
+        0,  2048,  3072,  3073,  2944,     0,  2048,  3072, 
+     3073,  2944,  2960,     0,  2048,  3072,  3073,  2944, 
+     2960,     0,  2048,  3072,  3073,  2944,  2960,  2962, 
+        0,  2048,  3072,  3073,  2944,  2960,     0,  2048, 
+     3072,  3073,  2944,  2960,  2964,     0,  2048,  3072, 
+     3073,  2944,  2960,  2964,     0,  2048,  3072,  3073, 
+     2944,  2960,  2968,  2966,     0,  2048,  3072,  3073, 
+     2944,  2960,     0,  2048,  3072,  3073,  2944,  2976, 
+     2968,     0,  2048,  3072,  3073,  2944,  2976,  2968, 
+        0,  2048,  3072,  3073,  2944,  2976,  2968,  2970, 
+        0,  2048,  3072,  3073,  2944,  2976,  2968,     0, 
+     2048,  3072,  3073,  2944,  2976,  2977,  2972,     0, 
+     2048,  3072,  3073,  2944,  2976,  2977,  2972,     0, 
+     2048,  3072,  3073,  2944,  2976,  2977,  2972,  2974, 
+        0,  2048,  3072,  3073,  2944,     0,  2048,  3072, 
+     3073,  2944,  2976,     0,  2048,  3072,  3073,  2944, 
+     2976,     0,  2048,  3072,  3073,  2944,  2976,  2978, 
+        0,  2048,  3072,  3073,  2944,  2976,     0,  2048, 
+     3072,  3073,  2944,  2976,  2980,     0,  2048,  3072, 
+     3073,  2944,  2976,  2980,     0,  2048,  3072,  3073, 
+     2944,  2976,  2984,  2982,     0,  2048,  3072,  3073, 
+     2944,  2976,     0,  2048,  3072,  3073,  2944,  2976, 
+     2984,     0,  2048,  3072,  3073,  2944,  2976,  2984, 
+        0,  2048,  3072,  3073,  2944,  2976,  2984,  2986, 
+        0,  2048,  3072,  3073,  2944,  2976,  2984,     0, 
+     2048,  3072,  3073,  2944,  2976,  2992,  2988,     0, 
+     2048,  3072,  3073,  2944,  2976,  2992,  2988,     0, 
+     2048,  3072,  3073,  2944,  2976,  2992,  2993,  2990, 
+        0,  2048,  3072,  3073,  2944,  2976,     0,  2048, 
+     3072,  3073,  2944,  3008,  2992,     0,  2048,  3072, 
+     3073,  2944,  3008,  2992,     0,  2048,  3072,  3073, 
+     2944,  3008,  2992,  2994,     0,  2048,  3072,  3073, 
+     2944,  3008,  2992,     0,  2048,  3072,  3073,  2944, 
+     3008,  2992,  2996,     0,  2048,  3072,  3073,  2944, 
+     3008,  2992,  2996,     0,  2048,  3072,  3073,  2944, 
+     3008,  2992,  3000,  2998,     0,  2048,  3072,  3073, 
+     2944,  3008,  2992,     0,  2048,  3072,  3073,  2944, 
+     3008,  3009,  3000,     0,  2048,  3072,  3073,  2944, 
+     3008,  3009,  3000,     0,  2048,  3072,  3073,  2944, 
+     3008,  3009,  3000,  3002,     0,  2048,  3072,  3073, 
+     2944,  3008,  3009,  3000,     0,  2048,  3072,  3073, 
+     2944,  3008,  3009,  3000,  3004,     0,  2048,  3072, 
+     3073,  2944,  3008,  3009,  3011,  3004,     0,  2048, 
+     3072,  3073,  2944,  3008,  3009,  3011,  3004,  3006, 
+        0,  2048,  3072,  3073,  2944,     0,  2048,  3072, 
+     3073,  2944,  3008,     0,  2048,  3072,  3073,  2944, 
+     3008,     0,  2048,  3072,  3073,  2944,  3008,  3010, 
+        0,  2048,  3072,  3073,  3075,  3008,     0,  2048, 
+     3072,  3073,  3075,  3008,  3012,     0,  2048,  3072, 
+     3073,  3075,  3008,  3012,     0,  2048,  3072,  3073, 
+     3075,  3008,  3016,  3014,     0,  2048,  3072,  3073, 
+     3075,  3008,     0,  2048,  3072,  3073,  3075,  3008, 
+     3016,     0,  2048,  3072,  3073,  3075,  3008,  3016, 
+        0,  2048,  3072,  3073,  3075,  3008,  3016,  3018, 
+        0,  2048,  3072,  3073,  3075,  3008,  3016,     0, 
+     2048,  3072,  3073,  3075,  3008,  3024,  3020,     0, 
+     2048,  3072,  3073,  3075,  3008,  3024,  3020,     0, 
+     2048,  3072,  3073,  3075,  3008,  3024,  3025,  3022, 
+        0,  2048,  3072,  3073,  3075,  3008,     0,  2048, 
+     3072,  3073,  3075,  3008,  3024,     0,  2048,  3072, 
+     3073,  3075,  3008,  3024,     0,  2048,  3072,  3073, 
+     3075,  3008,  3024,  3026,     0,  2048,  3072,  3073, 
+     3075,  3008,  3024,     0,  2048,  3072,  3073,  3075, 
+     3008,  3024,  3028,     0,  2048,  3072,  3073,  3075, 
+     3008,  3024,  3028,     0,  2048,  3072,  3073,  3075, 
+     3008,  3024,  3032,  3030,     0,  2048,  3072,  3073, 
+     3075,  3008,  3024,     0,  2048,  3072,  3073,  3075, 
+     3008,  3040,  3032,     0,  2048,  3072,  3073,  3075, 
+     3008,  3040,  3032,     0,  2048,  3072,  3073,  3075, 
+     3008,  3040,  3032,  3034,     0,  2048,  3072,  3073, 
+     3075,  3008,  3040,  3032,     0,  2048,  3072,  3073, 
+     3075,  3008,  3040,  3041,  3036,     0,  2048,  3072, 
+     3073,  3075,  3008,  3040,  3041,  3036,     0,  2048, 
+     3072,  3073,  3075,  3008,  3040,  3041,  3036,  3038, 
+        0,  2048,  3072,  3073,  3075,  3008,     0,  2048, 
+     3072,  3073,  3075,  3008,  3040,     0,  2048,  3072, 
+     3073,  3075,  3008,  3040,     0,  2048,  3072,  3073, 
+     3075,  3008,  3040,  3042,     0,  2048,  3072,  3073, 
+     3075,  3008,  3040,     0,  2048,  3072,  3073,  3075, 
+     3008,  3040,  3044,     0,  2048,  3072,  3073,  3075, 
+     3008,  3040,  3044,     0,  2048,  3072,  3073,  3075, 
+     3008,  3040,  3048,  3046,     0,  2048,  3072,  3073, 
+     3075,  3079,  3040,     0,  2048,  3072,  3073,  3075, 
+     3079,  3040,  3048,     0,  2048,  3072,  3073,  3075, 
+     3079,  3040,  3048,     0,  2048,  3072,  3073,  3075, 
+     3079,  3040,  3048,  3050,     0,  2048,  3072,  3073, 
+     3075,  3079,  3040,  3048,     0,  2048,  3072,  3073, 
+     3075,  3079,  3040,  3056,  3052,     0,  2048,  3072, 
+     3073,  3075,  3079,  3040,  3056,  3052,     0,  2048, 
+     3072,  3073,  3075,  3079,  3040,  3056,  3057,  3054, 
+        0,  2048,  3072,  3073,  3075,  3079,  3040,     0, 
+     2048,  3072,  3073,  3075,  3079,  3040,  3056,     0, 
+     2048,  3072,  3073,  3075,  3079,  3040,  3056,     0, 
+     2048,  3072,  3073,  3075,  3079,  3040,  3056,  3058, 
+        0,  2048,  3072,  3073,  3075,  3079,  3040,  3056, 
+        0,  2048,  3072,  3073,  3075,  3079,  3040,  3056, 
+     3060,     0,  2048,  3072,  3073,  3075,  3079,  3040, 
+     3056,  3060,     0,  2048,  3072,  3073,  3075,  3079, 
+     3040,  3056,  3064,  3062,     0,  2048,  3072,  3073, 
+     3075,  3079,  3040,  3056,     0,  2048,  3072,  3073, 
+     3075,  3079,  3040,  3056,  3064,     0,  2048,  3072, 
+     3073,  3075,  3079,  3040,  3056,  3064,     0,  2048, 
+     3072,  3073,  3075,  3079,  3040,  3056,  3064,  3066, 
+        0,  2048,  3072,  3073,  3075,  3079,  3040,  3056, 
+     3064,     0,  2048,  3072,  3073,  3075,  3079,  3040, 
+     3056,  3064,  3068,     0,  2048,  3072,  3073,  3075, 
+     3079,  3040,  3056,  3064,  3068,     0,  2048,  3072, 
+     3073,  3075,  3079,  3040,  3056,  3064,  3068,  3070, 
+        0,  2048,     0,  2048,  3072,     0,  2048,  3072, 
+        0,  2048,  3072,  3074,     0,  2048,  3072,     0, 
+     2048,  3072,  3076,     0,  2048,  3072,  3076,     0, 
+     2048,  3072,  3080,  3078,     0,  2048,  3072,     0, 
+     2048,  3072,  3080,     0,  2048,  3072,  3080,     0, 
+     2048,  3072,  3080,  3082,     0,  2048,  3072,  3080, 
+        0,  2048,  3072,  3088,  3084,     0,  2048,  3072, 
+     3088,  3084,     0,  2048,  3072,  3088,  3089,  3086, 
+        0,  2048,  3072,     0,  2048,  3072,  3088,     0, 
+     2048,  3072,  3088,     0,  2048,  3072,  3088,  3090, 
+        0,  2048,  3072,  3088,     0,  2048,  3072,  3088, 
+     3092,     0,  2048,  3072,  3088,  3092,     0,  2048, 
+     3072,  3088,  3096,  3094,     0,  2048,  3072,  3088, 
+        0,  2048,  3072,  3104,  3096,     0,  2048,  3072, 
+     3104,  3096,     0,  2048,  3072,  3104,  3096,  3098, 
+        0,  2048,  3072,  3104,  3096,     0,  2048,  3072, 
+     3104,  3105,  3100,     0,  2048,  3072,  3104,  3105, 
+     3100,     0,  2048,  3072,  3104,  3105,  3100,  3102, 
+        0,  2048,  3072,     0,  2048,  3072,  3104,     0, 
+     2048,  3072,  3104,     0,  2048,  3072,  3104,  3106, 
+        0,  2048,  3072,  3104,     0,  2048,  3072,  3104, 
+     3108,     0,  2048,  3072,  3104,  3108,     0,  2048, 
+     3072,  3104,  3112,  3110,     0,  2048,  3072,  3104, 
+        0,  2048,  3072,  3104,  3112,     0,  2048,  3072, 
+     3104,  3112,     0,  2048,  3072,  3104,  3112,  3114, 
+        0,  2048,  3072,  3104,  3112,     0,  2048,  3072, 
+     3104,  3120,  3116,     0,  2048,  3072,  3104,  3120, 
+     3116,     0,  2048,  3072,  3104,  3120,  3121,  3118, 
+        0,  2048,  3072,  3104,     0,  2048,  3072,  3136, 
+     3120,     0,  2048,  3072,  3136,  3120,     0,  2048, 
+     3072,  3136,  3120,  3122,     0,  2048,  3072,  3136, 
+     3120,     0,  2048,  3072,  3136,  3120,  3124,     0, 
+     2048,  3072,  3136,  3120,  3124,     0,  2048,  3072, 
+     3136,  3120,  3128,  3126,     0,  2048,  3072,  3136, 
+     3120,     0,  2048,  3072,  3136,  3137,  3128,     0, 
+     2048,  3072,  3136,  3137,  3128,     0,  2048,  3072, 
+     3136,  3137,  3128,  3130,     0,  2048,  3072,  3136, 
+     3137,  3128,     0,  2048,  3072,  3136,  3137,  3128, 
+     3132,     0,  2048,  3072,  3136,  3137,  3139,  3132, 
+        0,  2048,  3072,  3136,  3137,  3139,  3132,  3134, 
+        0,  2048,  3072,     0,  2048,  3072,  3136,     0, 
+     2048,  3072,  3136,     0,  2048,  3072,  3136,  3138, 
+        0,  2048,  3072,  3136,     0,  2048,  3072,  3136, 
+     3140,     0,  2048,  3072,  3136,  3140,     0,  2048, 
+     3072,  3136,  3144,  3142,     0,  2048,  3072,  3136, 
+        0,  2048,  3072,  3136,  3144,     0,  2048,  3072, 
+     3136,  3144,     0,  2048,  3072,  3136,  3144,  3146, 
+        0,  2048,  3072,  3136,  3144,     0,  2048,  3072, 
+     3136,  3152,  3148,     0,  2048,  3072,  3136,  3152, 
+     3148,     0,  2048,  3072,  3136,  3152,  3153,  3150, 
+        0,  2048,  3072,  3136,     0,  2048,  3072,  3136, 
+     3152,     0,  2048,  3072,  3136,  3152,     0,  2048, 
+     3072,  3136,  3152,  3154,     0,  2048,  3072,  3136, 
+     3152,     0,  2048,  3072,  3136,  3152,  3156,     0, 
+     2048,  3072,  3136,  3152,  3156,     0,  2048,  3072, 
+     3136,  3152,  3160,  3158,     0,  2048,  3072,  3136, 
+     3152,     0,  2048,  3072,  3136,  3168,  3160,     0, 
+     2048,  3072,  3136,  3168,  3160,     0,  2048,  3072, 
+     3136,  3168,  3160,  3162,     0,  2048,  3072,  3136, 
+     3168,  3160,     0,  2048,  3072,  3136,  3168,  3169, 
+     3164,     0,  2048,  3072,  3136,  3168,  3169,  3164, 
+        0,  2048,  3072,  3136,  3168,  3169,  3164,  3166, 
+        0,  2048,  3072,  3136,     0,  2048,  3072,  3200, 
+     3168,     0,  2048,  3072,  3200,  3168,     0,  2048, 
+     3072,  3200,  3168,  3170,     0,  2048,  3072,  3200, 
+     3168,     0,  2048,  3072,  3200,  3168,  3172,     0, 
+     2048,  3072,  3200,  3168,  3172,     0,  2048,  3072, 
+     3200,  3168,  3176,  3174,     0,  2048,  3072,  3200, 
+     3168,     0,  2048,  3072,  3200,  3168,  3176,     0, 
+     2048,  3072,  3200,  3168,  3176,     0,  2048,  3072, 
+     3200,  3168,  3176,  3178,     0,  2048,  3072,  3200, 
+     3168,  3176,     0,  2048,  3072,  3200,  3168,  3184, 
+     3180,     0,  2048,  3072,  3200,  3168,  3184,  3180, 
+        0,  2048,  3072,  3200,  3168,  3184,  3185,  3182, 
+        0,  2048,  3072,  3200,  3168,     0,  2048,  3072, 
+     3200,  3201,  3184,     0,  2048,  3072,  3200,  3201, 
+     3184,     0,  2048,  3072,  3200,  3201,  3184,  3186, 
+        0,  2048,  3072,  3200,  3201,  3184,     0,  2048, 
+     3072,  3200,  3201,  3184,  3188,     0,  2048,  3072, 
+     3200,  3201,  3184,  3188,     0,  2048,  3072,  3200, 
+     3201,  3184,  3192,  3190,     0,  2048,  3072,  3200, 
+     3201,  3184,     0,  2048,  3072,  3200,  3201,  3184, 
+     3192,     0,  2048,  3072,  3200,  3201,  3203,  3192, 
+        0,  2048,  3072,  3200,  3201,  3203,  3192,  3194, 
+        0,  2048,  3072,  3200,  3201,  3203,  3192,     0, 
+     2048,  3072,  3200,  3201,  3203,  3192,  3196,     0, 
+     2048,  3072,  3200,  3201,  3203,  3192,  3196,     0, 
+     2048,  3072,  3200,  3201,  3203,  3192,  3196,  3198, 
+        0,  2048,  3072,     0,  2048,  3072,  3200,     0, 
+     2048,  3072,  3200,     0,  2048,  3072,  3200,  3202, 
+        0,  2048,  3072,  3200,     0,  2048,  3072,  3200, 
+     3204,     0,  2048,  3072,  3200,  3204,     0,  2048, 
+     3072,  3200,  3208,  3206,     0,  2048,  3072,  3200, 
+        0,  2048,  3072,  3200,  3208,     0,  2048,  3072, 
+     3200,  3208,     0,  2048,  3072,  3200,  3208,  3210, 
+        0,  2048,  3072,  3200,  3208,     0,  2048,  3072, 
+     3200,  3216,  3212,     0,  2048,  3072,  3200,  3216, 
+     3212,     0,  2048,  3072,  3200,  3216,  3217,  3214, 
+        0,  2048,  3072,  3200,     0,  2048,  3072,  3200, 
+     3216,     0,  2048,  3072,  3200,  3216,     0,  2048, 
+     3072,  3200,  3216,  3218,     0,  2048,  3072,  3200, 
+     3216,     0,  2048,  3072,  3200,  3216,  3220,     0, 
+     2048,  3072,  3200,  3216,  3220,     0,  2048,  3072, 
+     3200,  3216,  3224,  3222,     0,  2048,  3072,  3200, 
+     3216,     0,  2048,  3072,  3200,  3232,  3224,     0, 
+     2048,  3072,  3200,  3232,  3224,     0,  2048,  3072, 
+     3200,  3232,  3224,  3226,     0,  2048,  3072,  3200, 
+     3232,  3224,     0,  2048,  3072,  3200,  3232,  3233, 
+     3228,     0,  2048,  3072,  3200,  3232,  3233,  3228, 
+        0,  2048,  3072,  3200,  3232,  3233,  3228,  3230, 
+        0,  2048,  3072,  3200,     0,  2048,  3072,  3200, 
+     3232,     0,  2048,  3072,  3200,  3232,     0,  2048, 
+     3072,  3200,  3232,  3234,     0,  2048,  3072,  3200, 
+     3232,     0,  2048,  3072,  3200,  3232,  3236,     0, 
+     2048,  3072,  3200,  3232,  3236,     0,  2048,  3072, 
+     3200,  3232,  3240,  3238,     0,  2048,  3072,  3200, 
+     3232,     0,  2048,  3072,  3200,  3232,  3240,     0, 
+     2048,  3072,  3200,  3232,  3240,     0,  2048,  3072, 
+     3200,  3232,  3240,  3242,     0,  2048,  3072,  3200, 
+     3232,  3240,     0,  2048,  3072,  3200,  3232,  3248, 
+     3244,     0,  2048,  3072,  3200,  3232,  3248,  3244, 
+        0,  2048,  3072,  3200,  3232,  3248,  3249,  3246, 
+        0,  2048,  3072,  3200,  3232,     0,  2048,  3072, 
+     3200,  3264,  3248,     0,  2048,  3072,  3200,  3264, 
+     3248,     0,  2048,  3072,  3200,  3264,  3248,  3250, 
+        0,  2048,  3072,  3200,  3264,  3248,     0,  2048, 
+     3072,  3200,  3264,  3248,  3252,     0,  2048,  3072, 
+     3200,  3264,  3248,  3252,     0,  2048,  3072,  3200, 
+     3264,  3248,  3256,  3254,     0,  2048,  3072,  3200, 
+     3264,  3248,     0,  2048,  3072,  3200,  3264,  3265, 
+     3256,     0,  2048,  3072,  3200,  3264,  3265,  3256, 
+        0,  2048,  3072,  3200,  3264,  3265,  3256,  3258, 
+        0,  2048,  3072,  3200,  3264,  3265,  3256,     0, 
+     2048,  3072,  3200,  3264,  3265,  3256,  3260,     0, 
+     2048,  3072,  3200,  3264,  3265,  3267,  3260,     0, 
+     2048,  3072,  3200,  3264,  3265,  3267,  3260,  3262, 
+        0,  2048,  3072,  3200,     0,  2048,  3072,  3328, 
+     3264,     0,  2048,  3072,  3328,  3264,     0,  2048, 
+     3072,  3328,  3264,  3266,     0,  2048,  3072,  3328, 
+     3264,     0,  2048,  3072,  3328,  3264,  3268,     0, 
+     2048,  3072,  3328,  3264,  3268,     0,  2048,  3072, 
+     3328,  3264,  3272,  3270,     0,  2048,  3072,  3328, 
+     3264,     0,  2048,  3072,  3328,  3264,  3272,     0, 
+     2048,  3072,  3328,  3264,  3272,     0,  2048,  3072, 
+     3328,  3264,  3272,  3274,     0,  2048,  3072,  3328, 
+     3264,  3272,     0,  2048,  3072,  3328,  3264,  3280, 
+     3276,     0,  2048,  3072,  3328,  3264,  3280,  3276, 
+        0,  2048,  3072,  3328,  3264,  3280,  3281,  3278, 
+        0,  2048,  3072,  3328,  3264,     0,  2048,  3072, 
+     3328,  3264,  3280,     0,  2048,  3072,  3328,  3264, 
+     3280,     0,  2048,  3072,  3328,  3264,  3280,  3282, 
+        0,  2048,  3072,  3328,  3264,  3280,     0,  2048, 
+     3072,  3328,  3264,  3280,  3284,     0,  2048,  3072, 
+     3328,  3264,  3280,  3284,     0,  2048,  3072,  3328, 
+     3264,  3280,  3288,  3286,     0,  2048,  3072,  3328, 
+     3264,  3280,     0,  2048,  3072,  3328,  3264,  3296, 
+     3288,     0,  2048,  3072,  3328,  3264,  3296,  3288, 
+        0,  2048,  3072,  3328,  3264,  3296,  3288,  3290, 
+        0,  2048,  3072,  3328,  3264,  3296,  3288,     0, 
+     2048,  3072,  3328,  3264,  3296,  3297,  3292,     0, 
+     2048,  3072,  3328,  3264,  3296,  3297,  3292,     0, 
+     2048,  3072,  3328,  3264,  3296,  3297,  3292,  3294, 
+        0,  2048,  3072,  3328,  3264,     0,  2048,  3072, 
+     3328,  3329,  3296,     0,  2048,  3072,  3328,  3329, 
+     3296,     0,  2048,  3072,  3328,  3329,  3296,  3298, 
+        0,  2048,  3072,  3328,  3329,  3296,     0,  2048, 
+     3072,  3328,  3329,  3296,  3300,     0,  2048,  3072, 
+     3328,  3329,  3296,  3300,     0,  2048,  3072,  3328, 
+     3329,  3296,  3304,  3302,     0,  2048,  3072,  3328, 
+     3329,  3296,     0,  2048,  3072,  3328,  3329,  3296, 
+     3304,     0,  2048,  3072,  3328,  3329,  3296,  3304, 
+        0,  2048,  3072,  3328,  3329,  3296,  3304,  3306, 
+        0,  2048,  3072,  3328,  3329,  3296,  3304,     0, 
+     2048,  3072,  3328,  3329,  3296,  3312,  3308,     0, 
+     2048,  3072,  3328,  3329,  3296,  3312,  3308,     0, 
+     2048,  3072,  3328,  3329,  3296,  3312,  3313,  3310, 
+        0,  2048,  3072,  3328,  3329,  3296,     0,  2048, 
+     3072,  3328,  3329,  3296,  3312,     0,  2048,  3072, 
+     3328,  3329,  3331,  3312,     0,  2048,  3072,  3328, 
+     3329,  3331,  3312,  3314,     0,  2048,  3072,  3328, 
+     3329,  3331,  3312,     0,  2048,  3072,  3328,  3329, 
+     3331,  3312,  3316,     0,  2048,  3072,  3328,  3329, 
+     3331,  3312,  3316,     0,  2048,  3072,  3328,  3329, 
+     3331,  3312,  3320,  3318,     0,  2048,  3072,  3328, 
+     3329,  3331,  3312,     0,  2048,  3072,  3328,  3329, 
+     3331,  3312,  3320,     0,  2048,  3072,  3328,  3329, 
+     3331,  3312,  3320,     0,  2048,  3072,  3328,  3329, 
+     3331,  3312,  3320,  3322,     0,  2048,  3072,  3328, 
+     3329,  3331,  3335,  3320,     0,  2048,  3072,  3328, 
+     3329,  3331,  3335,  3320,  3324,     0,  2048,  3072, 
+     3328,  3329,  3331,  3335,  3320,  3324,     0,  2048, 
+     3072,  3328,  3329,  3331,  3335,  3320,  3324,  3326, 
+        0,  2048,  3072,     0,  4096,  3072,  3328,     0, 
+     4096,  3072,  3328,     0,  4096,  3072,  3328,  3330, 
+        0,  4096,  3072,  3328,     0,  4096,  3072,  3328, 
+     3332,     0,  4096,  3072,  3328,  3332,     0,  4096, 
+     3072,  3328,  3336,  3334,     0,  4096,  3072,  3328, 
+        0,  4096,  3072,  3328,  3336,     0,  4096,  3072, 
+     3328,  3336,     0,  4096,  3072,  3328,  3336,  3338, 
+        0,  4096,  3072,  3328,  3336,     0,  4096,  3072, 
+     3328,  3344,  3340,     0,  4096,  3072,  3328,  3344, 
+     3340,     0,  4096,  3072,  3328,  3344,  3345,  3342, 
+        0,  4096,  3072,  3328,     0,  4096,  3072,  3328, 
+     3344,     0,  4096,  3072,  3328,  3344,     0,  4096, 
+     3072,  3328,  3344,  3346,     0,  4096,  3072,  3328, 
+     3344,     0,  4096,  3072,  3328,  3344,  3348,     0, 
+     4096,  3072,  3328,  3344,  3348,     0,  4096,  3072, 
+     3328,  3344,  3352,  3350,     0,  4096,  3072,  3328, 
+     3344,     0,  4096,  3072,  3328,  3360,  3352,     0, 
+     4096,  3072,  3328,  3360,  3352,     0,  4096,  3072, 
+     3328,  3360,  3352,  3354,     0,  4096,  3072,  3328, 
+     3360,  3352,     0,  4096,  3072,  3328,  3360,  3361, 
+     3356,     0,  4096,  3072,  3328,  3360,  3361,  3356, 
+        0,  4096,  3072,  3328,  3360,  3361,  3356,  3358, 
+        0,  4096,  3072,  3328,     0,  4096,  3072,  3328, 
+     3360,     0,  4096,  3072,  3328,  3360,     0,  4096, 
+     3072,  3328,  3360,  3362,     0,  4096,  3072,  3328, 
+     3360,     0,  4096,  3072,  3328,  3360,  3364,     0, 
+     4096,  3072,  3328,  3360,  3364,     0,  4096,  3072, 
+     3328,  3360,  3368,  3366,     0,  4096,  3072,  3328, 
+     3360,     0,  4096,  3072,  3328,  3360,  3368,     0, 
+     4096,  3072,  3328,  3360,  3368,     0,  4096,  3072, 
+     3328,  3360,  3368,  3370,     0,  4096,  3072,  3328, 
+     3360,  3368,     0,  4096,  3072,  3328,  3360,  3376, 
+     3372,     0,  4096,  3072,  3328,  3360,  3376,  3372, 
+        0,  4096,  3072,  3328,  3360,  3376,  3377,  3374, 
+        0,  4096,  3072,  3328,  3360,     0,  4096,  3072, 
+     3328,  3392,  3376,     0,  4096,  3072,  3328,  3392, 
+     3376,     0,  4096,  3072,  3328,  3392,  3376,  3378, 
+        0,  4096,  3072,  3328,  3392,  3376,     0,  4096, 
+     3072,  3328,  3392,  3376,  3380,     0,  4096,  3072, 
+     3328,  3392,  3376,  3380,     0,  4096,  3072,  3328, 
+     3392,  3376,  3384,  3382,     0,  4096,  3072,  3328, 
+     3392,  3376,     0,  4096,  3072,  3328,  3392,  3393, 
+     3384,     0,  4096,  3072,  3328,  3392,  3393,  3384, 
+        0,  4096,  3072,  3328,  3392,  3393,  3384,  3386, 
+        0,  4096,  3072,  3328,  3392,  3393,  3384,     0, 
+     4096,  3072,  3328,  3392,  3393,  3384,  3388,     0, 
+     4096,  3072,  3328,  3392,  3393,  3395,  3388,     0, 
+     4096,  3072,  3328,  3392,  3393,  3395,  3388,  3390, 
+        0,  4096,  3072,  3328,     0,  4096,  3072,  3328, 
+     3392,     0,  4096,  3072,  3328,  3392,     0,  4096, 
+     3072,  3328,  3392,  3394,     0,  4096,  3072,  3328, 
+     3392,     0,  4096,  3072,  3328,  3392,  3396,     0, 
+     4096,  3072,  3328,  3392,  3396,     0,  4096,  3072, 
+     3328,  3392,  3400,  3398,     0,  4096,  3072,  3328, 
+     3392,     0,  4096,  3072,  3328,  3392,  3400,     0, 
+     4096,  3072,  3328,  3392,  3400,     0,  4096,  3072, 
+     3328,  3392,  3400,  3402,     0,  4096,  3072,  3328, 
+     3392,  3400,     0,  4096,  3072,  3328,  3392,  3408, 
+     3404,     0,  4096,  3072,  3328,  3392,  3408,  3404, 
+        0,  4096,  3072,  3328,  3392,  3408,  3409,  3406, 
+        0,  4096,  3072,  3328,  3392,     0,  4096,  3072, 
+     3328,  3392,  3408,     0,  4096,  3072,  3328,  3392, 
+     3408,     0,  4096,  3072,  3328,  3392,  3408,  3410, 
+        0,  4096,  3072,  3328,  3392,  3408,     0,  4096, 
+     3072,  3328,  3392,  3408,  3412,     0,  4096,  3072, 
+     3328,  3392,  3408,  3412,     0,  4096,  3072,  3328, 
+     3392,  3408,  3416,  3414,     0,  4096,  3072,  3328, 
+     3392,  3408,     0,  4096,  3072,  3328,  3392,  3424, 
+     3416,     0,  4096,  3072,  3328,  3392,  3424,  3416, 
+        0,  4096,  3072,  3328,  3392,  3424,  3416,  3418, 
+        0,  4096,  3072,  3328,  3392,  3424,  3416,     0, 
+     4096,  3072,  3328,  3392,  3424,  3425,  3420,     0, 
+     4096,  3072,  3328,  3392,  3424,  3425,  3420,     0, 
+     4096,  3072,  3328,  3392,  3424,  3425,  3420,  3422, 
+        0,  4096,  3072,  3328,  3392,     0,  4096,  3072, 
+     3328,  3456,  3424,     0,  4096,  3072,  3328,  3456, 
+     3424,     0,  4096,  3072,  3328,  3456,  3424,  3426, 
+        0,  4096,  3072,  3328,  3456,  3424,     0,  4096, 
+     3072,  3328,  3456,  3424,  3428,     0,  4096,  3072, 
+     3328,  3456,  3424,  3428,     0,  4096,  3072,  3328, 
+     3456,  3424,  3432,  3430,     0,  4096,  3072,  3328, 
+     3456,  3424,     0,  4096,  3072,  3328,  3456,  3424, 
+     3432,     0,  4096,  3072,  3328,  3456,  3424,  3432, 
+        0,  4096,  3072,  3328,  3456,  3424,  3432,  3434, 
+        0,  4096,  3072,  3328,  3456,  3424,  3432,     0, 
+     4096,  3072,  3328,  3456,  3424,  3440,  3436,     0, 
+     4096,  3072,  3328,  3456,  3424,  3440,  3436,     0, 
+     4096,  3072,  3328,  3456,  3424,  3440,  3441,  3438, 
+        0,  4096,  3072,  3328,  3456,  3424,     0,  4096, 
+     3072,  3328,  3456,  3457,  3440,     0,  4096,  3072, 
+     3328,  3456,  3457,  3440,     0,  4096,  3072,  3328, 
+     3456,  3457,  3440,  3442,     0,  4096,  3072,  3328, 
+     3456,  3457,  3440,     0,  4096,  3072,  3328,  3456, 
+     3457,  3440,  3444,     0,  4096,  3072,  3328,  3456, 
+     3457,  3440,  3444,     0,  4096,  3072,  3328,  3456, 
+     3457,  3440,  3448,  3446,     0,  4096,  3072,  3328, 
+     3456,  3457,  3440,     0,  4096,  3072,  3328,  3456, 
+     3457,  3440,  3448,     0,  4096,  3072,  3328,  3456, 
+     3457,  3459,  3448,     0,  4096,  3072,  3328,  3456, 
+     3457,  3459,  3448,  3450,     0,  4096,  3072,  3328, 
+     3456,  3457,  3459,  3448,     0,  4096,  3072,  3328, 
+     3456,  3457,  3459,  3448,  3452,     0,  4096,  3072, 
+     3328,  3456,  3457,  3459,  3448,  3452,     0,  4096, 
+     3072,  3328,  3456,  3457,  3459,  3448,  3452,  3454, 
+        0,  4096,  3072,  3328,     0,  4096,  3072,  3584, 
+     3456,     0,  4096,  3072,  3584,  3456,     0,  4096, 
+     3072,  3584,  3456,  3458,     0,  4096,  3072,  3584, 
+     3456,     0,  4096,  3072,  3584,  3456,  3460,     0, 
+     4096,  3072,  3584,  3456,  3460,     0,  4096,  3072, 
+     3584,  3456,  3464,  3462,     0,  4096,  3072,  3584, 
+     3456,     0,  4096,  3072,  3584,  3456,  3464,     0, 
+     4096,  3072,  3584,  3456,  3464,     0,  4096,  3072, 
+     3584,  3456,  3464,  3466,     0,  4096,  3072,  3584, 
+     3456,  3464,     0,  4096,  3072,  3584,  3456,  3472, 
+     3468,     0,  4096,  3072,  3584,  3456,  3472,  3468, 
+        0,  4096,  3072,  3584,  3456,  3472,  3473,  3470, 
+        0,  4096,  3072,  3584,  3456,     0,  4096,  3072, 
+     3584,  3456,  3472,     0,  4096,  3072,  3584,  3456, 
+     3472,     0,  4096,  3072,  3584,  3456,  3472,  3474, 
+        0,  4096,  3072,  3584,  3456,  3472,     0,  4096, 
+     3072,  3584,  3456,  3472,  3476,     0,  4096,  3072, 
+     3584,  3456,  3472,  3476,     0,  4096,  3072,  3584, 
+     3456,  3472,  3480,  3478,     0,  4096,  3072,  3584, 
+     3456,  3472,     0,  4096,  3072,  3584,  3456,  3488, 
+     3480,     0,  4096,  3072,  3584,  3456,  3488,  3480, 
+        0,  4096,  3072,  3584,  3456,  3488,  3480,  3482, 
+        0,  4096,  3072,  3584,  3456,  3488,  3480,     0, 
+     4096,  3072,  3584,  3456,  3488,  3489,  3484,     0, 
+     4096,  3072,  3584,  3456,  3488,  3489,  3484,     0, 
+     4096,  3072,  3584,  3456,  3488,  3489,  3484,  3486, 
+        0,  4096,  3072,  3584,  3456,     0,  4096,  3072, 
+     3584,  3456,  3488,     0,  4096,  3072,  3584,  3456, 
+     3488,     0,  4096,  3072,  3584,  3456,  3488,  3490, 
+        0,  4096,  3072,  3584,  3456,  3488,     0,  4096, 
+     3072,  3584,  3456,  3488,  3492,     0,  4096,  3072, 
+     3584,  3456,  3488,  3492,     0,  4096,  3072,  3584, 
+     3456,  3488,  3496,  3494,     0,  4096,  3072,  3584, 
+     3456,  3488,     0,  4096,  3072,  3584,  3456,  3488, 
+     3496,     0,  4096,  3072,  3584,  3456,  3488,  3496, 
+        0,  4096,  3072,  3584,  3456,  3488,  3496,  3498, 
+        0,  4096,  3072,  3584,  3456,  3488,  3496,     0, 
+     4096,  3072,  3584,  3456,  3488,  3504,  3500,     0, 
+     4096,  3072,  3584,  3456,  3488,  3504,  3500,     0, 
+     4096,  3072,  3584,  3456,  3488,  3504,  3505,  3502, 
+        0,  4096,  3072,  3584,  3456,  3488,     0,  4096, 
+     3072,  3584,  3456,  3520,  3504,     0,  4096,  3072, 
+     3584,  3456,  3520,  3504,     0,  4096,  3072,  3584, 
+     3456,  3520,  3504,  3506,     0,  4096,  3072,  3584, 
+     3456,  3520,  3504,     0,  4096,  3072,  3584,  3456, 
+     3520,  3504,  3508,     0,  4096,  3072,  3584,  3456, 
+     3520,  3504,  3508,     0,  4096,  3072,  3584,  3456, 
+     3520,  3504,  3512,  3510,     0,  4096,  3072,  3584, 
+     3456,  3520,  3504,     0,  4096,  3072,  3584,  3456, 
+     3520,  3521,  3512,     0,  4096,  3072,  3584,  3456, 
+     3520,  3521,  3512,     0,  4096,  3072,  3584,  3456, 
+     3520,  3521,  3512,  3514,     0,  4096,  3072,  3584, 
+     3456,  3520,  3521,  3512,     0,  4096,  3072,  3584, 
+     3456,  3520,  3521,  3512,  3516,     0,  4096,  3072, 
+     3584,  3456,  3520,  3521,  3523,  3516,     0,  4096, 
+     3072,  3584,  3456,  3520,  3521,  3523,  3516,  3518, 
+        0,  4096,  3072,  3584,  3456,     0,  4096,  3072, 
+     3584,  3585,  3520,     0,  4096,  3072,  3584,  3585, 
+     3520,     0,  4096,  3072,  3584,  3585,  3520,  3522, 
+        0,  4096,  3072,  3584,  3585,  3520,     0,  4096, 
+     3072,  3584,  3585,  3520,  3524,     0,  4096,  3072, 
+     3584,  3585,  3520,  3524,     0,  4096,  3072,  3584, 
+     3585,  3520,  3528,  3526,     0,  4096,  3072,  3584, 
+     3585,  3520,     0,  4096,  3072,  3584,  3585,  3520, 
+     3528,     0,  4096,  3072,  3584,  3585,  3520,  3528, 
+        0,  4096,  3072,  3584,  3585,  3520,  3528,  3530, 
+        0,  4096,  3072,  3584,  3585,  3520,  3528,     0, 
+     4096,  3072,  3584,  3585,  3520,  3536,  3532,     0, 
+     4096,  3072,  3584,  3585,  3520,  3536,  3532,     0, 
+     4096,  3072,  3584,  3585,  3520,  3536,  3537,  3534, 
+        0,  4096,  3072,  3584,  3585,  3520,     0,  4096, 
+     3072,  3584,  3585,  3520,  3536,     0,  4096,  3072, 
+     3584,  3585,  3520,  3536,     0,  4096,  3072,  3584, 
+     3585,  3520,  3536,  3538,     0,  4096,  3072,  3584, 
+     3585,  3520,  3536,     0,  4096,  3072,  3584,  3585, 
+     3520,  3536,  3540,     0,  4096,  3072,  3584,  3585, 
+     3520,  3536,  3540,     0,  4096,  3072,  3584,  3585, 
+     3520,  3536,  3544,  3542,     0,  4096,  3072,  3584, 
+     3585,  3520,  3536,     0,  4096,  3072,  3584,  3585, 
+     3520,  3552,  3544,     0,  4096,  3072,  3584,  3585, 
+     3520,  3552,  3544,     0,  4096,  3072,  3584,  3585, 
+     3520,  3552,  3544,  3546,     0,  4096,  3072,  3584, 
+     3585,  3520,  3552,  3544,     0,  4096,  3072,  3584, 
+     3585,  3520,  3552,  3553,  3548,     0,  4096,  3072, 
+     3584,  3585,  3520,  3552,  3553,  3548,     0,  4096, 
+     3072,  3584,  3585,  3520,  3552,  3553,  3548,  3550, 
+        0,  4096,  3072,  3584,  3585,  3520,     0,  4096, 
+     3072,  3584,  3585,  3520,  3552,     0,  4096,  3072, 
+     3584,  3585,  3587,  3552,     0,  4096,  3072,  3584, 
+     3585,  3587,  3552,  3554,     0,  4096,  3072,  3584, 
+     3585,  3587,  3552,     0,  4096,  3072,  3584,  3585, 
+     3587,  3552,  3556,     0,  4096,  3072,  3584,  3585, 
+     3587,  3552,  3556,     0,  4096,  3072,  3584,  3585, 
+     3587,  3552,  3560,  3558,     0,  4096,  3072,  3584, 
+     3585,  3587,  3552,     0,  4096,  3072,  3584,  3585, 
+     3587,  3552,  3560,     0,  4096,  3072,  3584,  3585, 
+     3587,  3552,  3560,     0,  4096,  3072,  3584,  3585, 
+     3587,  3552,  3560,  3562,     0,  4096,  3072,  3584, 
+     3585,  3587,  3552,  3560,     0,  4096,  3072,  3584, 
+     3585,  3587,  3552,  3568,  3564,     0,  4096,  3072, 
+     3584,  3585,  3587,  3552,  3568,  3564,     0,  4096, 
+     3072,  3584,  3585,  3587,  3552,  3568,  3569,  3566, 
+        0,  4096,  3072,  3584,  3585,  3587,  3552,     0, 
+     4096,  3072,  3584,  3585,  3587,  3552,  3568,     0, 
+     4096,  3072,  3584,  3585,  3587,  3552,  3568,     0, 
+     4096,  3072,  3584,  3585,  3587,  3552,  3568,  3570, 
+        0,  4096,  3072,  3584,  3585,  3587,  3591,  3568, 
+        0,  4096,  3072,  3584,  3585,  3587,  3591,  3568, 
+     3572,     0,  4096,  3072,  3584,  3585,  3587,  3591, 
+     3568,  3572,     0,  4096,  3072,  3584,  3585,  3587, 
+     3591,  3568,  3576,  3574,     0,  4096,  3072,  3584, 
+     3585,  3587,  3591,  3568,     0,  4096,  3072,  3584, 
+     3585,  3587,  3591,  3568,  3576,     0,  4096,  3072, 
+     3584,  3585,  3587,  3591,  3568,  3576,     0,  4096, 
+     3072,  3584,  3585,  3587,  3591,  3568,  3576,  3578, 
+        0,  4096,  3072,  3584,  3585,  3587,  3591,  3568, 
+     3576,     0,  4096,  3072,  3584,  3585,  3587,  3591, 
+     3568,  3576,  3580,     0,  4096,  3072,  3584,  3585, 
+     3587,  3591,  3568,  3576,  3580,     0,  4096,  3072, 
+     3584,  3585,  3587,  3591,  3568,  3576,  3580,  3582, 
+        0,  4096,  3072,     0,  4096,  3072,  3584,     0, 
+     4096,  4097,  3584,     0,  4096,  4097,  3584,  3586, 
+        0,  4096,  4097,  3584,     0,  4096,  4097,  3584, 
+     3588,     0,  4096,  4097,  3584,  3588,     0,  4096, 
+     4097,  3584,  3592,  3590,     0,  4096,  4097,  3584, 
+        0,  4096,  4097,  3584,  3592,     0,  4096,  4097, 
+     3584,  3592,     0,  4096,  4097,  3584,  3592,  3594, 
+        0,  4096,  4097,  3584,  3592,     0,  4096,  4097, 
+     3584,  3600,  3596,     0,  4096,  4097,  3584,  3600, 
+     3596,     0,  4096,  4097,  3584,  3600,  3601,  3598, 
+        0,  4096,  4097,  3584,     0,  4096,  4097,  3584, 
+     3600,     0,  4096,  4097,  3584,  3600,     0,  4096, 
+     4097,  3584,  3600,  3602,     0,  4096,  4097,  3584, 
+     3600,     0,  4096,  4097,  3584,  3600,  3604,     0, 
+     4096,  4097,  3584,  3600,  3604,     0,  4096,  4097, 
+     3584,  3600,  3608,  3606,     0,  4096,  4097,  3584, 
+     3600,     0,  4096,  4097,  3584,  3616,  3608,     0, 
+     4096,  4097,  3584,  3616,  3608,     0,  4096,  4097, 
+     3584,  3616,  3608,  3610,     0,  4096,  4097,  3584, 
+     3616,  3608,     0,  4096,  4097,  3584,  3616,  3617, 
+     3612,     0,  4096,  4097,  3584,  3616,  3617,  3612, 
+        0,  4096,  4097,  3584,  3616,  3617,  3612,  3614, 
+        0,  4096,  4097,  3584,     0,  4096,  4097,  3584, 
+     3616,     0,  4096,  4097,  3584,  3616,     0,  4096, 
+     4097,  3584,  3616,  3618,     0,  4096,  4097,  3584, 
+     3616,     0,  4096,  4097,  3584,  3616,  3620,     0, 
+     4096,  4097,  3584,  3616,  3620,     0,  4096,  4097, 
+     3584,  3616,  3624,  3622,     0,  4096,  4097,  3584, 
+     3616,     0,  4096,  4097,  3584,  3616,  3624,     0, 
+     4096,  4097,  3584,  3616,  3624,     0,  4096,  4097, 
+     3584,  3616,  3624,  3626,     0,  4096,  4097,  3584, 
+     3616,  3624,     0,  4096,  4097,  3584,  3616,  3632, 
+     3628,     0,  4096,  4097,  3584,  3616,  3632,  3628, 
+        0,  4096,  4097,  3584,  3616,  3632,  3633,  3630, 
+        0,  4096,  4097,  3584,  3616,     0,  4096,  4097, 
+     3584,  3648,  3632,     0,  4096,  4097,  3584,  3648, 
+     3632,     0,  4096,  4097,  3584,  3648,  3632,  3634, 
+        0,  4096,  4097,  3584,  3648,  3632,     0,  4096, 
+     4097,  3584,  3648,  3632,  3636,     0,  4096,  4097, 
+     3584,  3648,  3632,  3636,     0,  4096,  4097,  3584, 
+     3648,  3632,  3640,  3638,     0,  4096,  4097,  3584, 
+     3648,  3632,     0,  4096,  4097,  3584,  3648,  3649, 
+     3640,     0,  4096,  4097,  3584,  3648,  3649,  3640, 
+        0,  4096,  4097,  3584,  3648,  3649,  3640,  3642, 
+        0,  4096,  4097,  3584,  3648,  3649,  3640,     0, 
+     4096,  4097,  3584,  3648,  3649,  3640,  3644,     0, 
+     4096,  4097,  3584,  3648,  3649,  3651,  3644,     0, 
+     4096,  4097,  3584,  3648,  3649,  3651,  3644,  3646, 
+        0,  4096,  4097,  3584,     0,  4096,  4097,  3584, 
+     3648,     0,  4096,  4097,  3584,  3648,     0,  4096, 
+     4097,  3584,  3648,  3650,     0,  4096,  4097,  3584, 
+     3648,     0,  4096,  4097,  3584,  3648,  3652,     0, 
+     4096,  4097,  3584,  3648,  3652,     0,  4096,  4097, 
+     3584,  3648,  3656,  3654,     0,  4096,  4097,  3584, 
+     3648,     0,  4096,  4097,  3584,  3648,  3656,     0, 
+     4096,  4097,  3584,  3648,  3656,     0,  4096,  4097, 
+     3584,  3648,  3656,  3658,     0,  4096,  4097,  3584, 
+     3648,  3656,     0,  4096,  4097,  3584,  3648,  3664, 
+     3660,     0,  4096,  4097,  3584,  3648,  3664,  3660, 
+        0,  4096,  4097,  3584,  3648,  3664,  3665,  3662, 
+        0,  4096,  4097,  3584,  3648,     0,  4096,  4097, 
+     3584,  3648,  3664,     0,  4096,  4097,  3584,  3648, 
+     3664,     0,  4096,  4097,  3584,  3648,  3664,  3666, 
+        0,  4096,  4097,  3584,  3648,  3664,     0,  4096, 
+     4097,  3584,  3648,  3664,  3668,     0,  4096,  4097, 
+     3584,  3648,  3664,  3668,     0,  4096,  4097,  3584, 
+     3648,  3664,  3672,  3670,     0,  4096,  4097,  3584, 
+     3648,  3664,     0,  4096,  4097,  3584,  3648,  3680, 
+     3672,     0,  4096,  4097,  3584,  3648,  3680,  3672, 
+        0,  4096,  4097,  3584,  3648,  3680,  3672,  3674, 
+        0,  4096,  4097,  3584,  3648,  3680,  3672,     0, 
+     4096,  4097,  3584,  3648,  3680,  3681,  3676,     0, 
+     4096,  4097,  3584,  3648,  3680,  3681,  3676,     0, 
+     4096,  4097,  3584,  3648,  3680,  3681,  3676,  3678, 
+        0,  4096,  4097,  3584,  3648,     0,  4096,  4097, 
+     3584,  3712,  3680,     0,  4096,  4097,  3584,  3712, 
+     3680,     0,  4096,  4097,  3584,  3712,  3680,  3682, 
+        0,  4096,  4097,  3584,  3712,  3680,     0,  4096, 
+     4097,  3584,  3712,  3680,  3684,     0,  4096,  4097, 
+     3584,  3712,  3680,  3684,     0,  4096,  4097,  3584, 
+     3712,  3680,  3688,  3686,     0,  4096,  4097,  3584, 
+     3712,  3680,     0,  4096,  4097,  3584,  3712,  3680, 
+     3688,     0,  4096,  4097,  3584,  3712,  3680,  3688, 
+        0,  4096,  4097,  3584,  3712,  3680,  3688,  3690, 
+        0,  4096,  4097,  3584,  3712,  3680,  3688,     0, 
+     4096,  4097,  3584,  3712,  3680,  3696,  3692,     0, 
+     4096,  4097,  3584,  3712,  3680,  3696,  3692,     0, 
+     4096,  4097,  3584,  3712,  3680,  3696,  3697,  3694, 
+        0,  4096,  4097,  3584,  3712,  3680,     0,  4096, 
+     4097,  3584,  3712,  3713,  3696,     0,  4096,  4097, 
+     3584,  3712,  3713,  3696,     0,  4096,  4097,  3584, 
+     3712,  3713,  3696,  3698,     0,  4096,  4097,  3584, 
+     3712,  3713,  3696,     0,  4096,  4097,  3584,  3712, 
+     3713,  3696,  3700,     0,  4096,  4097,  3584,  3712, 
+     3713,  3696,  3700,     0,  4096,  4097,  3584,  3712, 
+     3713,  3696,  3704,  3702,     0,  4096,  4097,  3584, 
+     3712,  3713,  3696,     0,  4096,  4097,  3584,  3712, 
+     3713,  3696,  3704,     0,  4096,  4097,  3584,  3712, 
+     3713,  3715,  3704,     0,  4096,  4097,  3584,  3712, 
+     3713,  3715,  3704,  3706,     0,  4096,  4097,  3584, 
+     3712,  3713,  3715,  3704,     0,  4096,  4097,  3584, 
+     3712,  3713,  3715,  3704,  3708,     0,  4096,  4097, 
+     3584,  3712,  3713,  3715,  3704,  3708,     0,  4096, 
+     4097,  3584,  3712,  3713,  3715,  3704,  3708,  3710, 
+        0,  4096,  4097,  3584,     0,  4096,  4097,  3584, 
+     3712,     0,  4096,  4097,  3584,  3712,     0,  4096, 
+     4097,  3584,  3712,  3714,     0,  4096,  4097,  3584, 
+     3712,     0,  4096,  4097,  3584,  3712,  3716,     0, 
+     4096,  4097,  3584,  3712,  3716,     0,  4096,  4097, 
+     3584,  3712,  3720,  3718,     0,  4096,  4097,  3584, 
+     3712,     0,  4096,  4097,  3584,  3712,  3720,     0, 
+     4096,  4097,  3584,  3712,  3720,     0,  4096,  4097, 
+     3584,  3712,  3720,  3722,     0,  4096,  4097,  3584, 
+     3712,  3720,     0,  4096,  4097,  3584,  3712,  3728, 
+     3724,     0,  4096,  4097,  3584,  3712,  3728,  3724, 
+        0,  4096,  4097,  3584,  3712,  3728,  3729,  3726, 
+        0,  4096,  4097,  3584,  3712,     0,  4096,  4097, 
+     3584,  3712,  3728,     0,  4096,  4097,  3584,  3712, 
+     3728,     0,  4096,  4097,  3584,  3712,  3728,  3730, 
+        0,  4096,  4097,  3584,  3712,  3728,     0,  4096, 
+     4097,  3584,  3712,  3728,  3732,     0,  4096,  4097, 
+     3584,  3712,  3728,  3732,     0,  4096,  4097,  3584, 
+     3712,  3728,  3736,  3734,     0,  4096,  4097,  3584, 
+     3712,  3728,     0,  4096,  4097,  3584,  3712,  3744, 
+     3736,     0,  4096,  4097,  3584,  3712,  3744,  3736, 
+        0,  4096,  4097,  3584,  3712,  3744,  3736,  3738, 
+        0,  4096,  4097,  3584,  3712,  3744,  3736,     0, 
+     4096,  4097,  3584,  3712,  3744,  3745,  3740,     0, 
+     4096,  4097,  3584,  3712,  3744,  3745,  3740,     0, 
+     4096,  4097,  3584,  3712,  3744,  3745,  3740,  3742, 
+        0,  4096,  4097,  3584,  3712,     0,  4096,  4097, 
+     3584,  3712,  3744,     0,  4096,  4097,  3584,  3712, 
+     3744,     0,  4096,  4097,  3584,  3712,  3744,  3746, 
+        0,  4096,  4097,  3584,  3712,  3744,     0,  4096, 
+     4097,  3584,  3712,  3744,  3748,     0,  4096,  4097, 
+     3584,  3712,  3744,  3748,     0,  4096,  4097,  3584, 
+     3712,  3744,  3752,  3750,     0,  4096,  4097,  3584, 
+     3712,  3744,     0,  4096,  4097,  3584,  3712,  3744, 
+     3752,     0,  4096,  4097,  3584,  3712,  3744,  3752, 
+        0,  4096,  4097,  3584,  3712,  3744,  3752,  3754, 
+        0,  4096,  4097,  3584,  3712,  3744,  3752,     0, 
+     4096,  4097,  3584,  3712,  3744,  3760,  3756,     0, 
+     4096,  4097,  3584,  3712,  3744,  3760,  3756,     0, 
+     4096,  4097,  3584,  3712,  3744,  3760,  3761,  3758, 
+        0,  4096,  4097,  3584,  3712,  3744,     0,  4096, 
+     4097,  3584,  3712,  3776,  3760,     0,  4096,  4097, 
+     3584,  3712,  3776,  3760,     0,  4096,  4097,  3584, 
+     3712,  3776,  3760,  3762,     0,  4096,  4097,  3584, 
+     3712,  3776,  3760,     0,  4096,  4097,  3584,  3712, 
+     3776,  3760,  3764,     0,  4096,  4097,  3584,  3712, 
+     3776,  3760,  3764,     0,  4096,  4097,  3584,  3712, 
+     3776,  3760,  3768,  3766,     0,  4096,  4097,  3584, 
+     3712,  3776,  3760,     0,  4096,  4097,  3584,  3712, 
+     3776,  3777,  3768,     0,  4096,  4097,  3584,  3712, 
+     3776,  3777,  3768,     0,  4096,  4097,  3584,  3712, 
+     3776,  3777,  3768,  3770,     0,  4096,  4097,  3584, 
+     3712,  3776,  3777,  3768,     0,  4096,  4097,  3584, 
+     3712,  3776,  3777,  3768,  3772,     0,  4096,  4097, 
+     3584,  3712,  3776,  3777,  3779,  3772,     0,  4096, 
+     4097,  3584,  3712,  3776,  3777,  3779,  3772,  3774, 
+        0,  4096,  4097,  3584,  3712,     0,  4096,  4097, 
+     3584,  3840,  3776,     0,  4096,  4097,  3584,  3840, 
+     3776,     0,  4096,  4097,  3584,  3840,  3776,  3778, 
+        0,  4096,  4097,  3584,  3840,  3776,     0,  4096, 
+     4097,  3584,  3840,  3776,  3780,     0,  4096,  4097, 
+     3584,  3840,  3776,  3780,     0,  4096,  4097,  3584, 
+     3840,  3776,  3784,  3782,     0,  4096,  4097,  3584, 
+     3840,  3776,     0,  4096,  4097,  3584,  3840,  3776, 
+     3784,     0,  4096,  4097,  3584,  3840,  3776,  3784, 
+        0,  4096,  4097,  3584,  3840,  3776,  3784,  3786, 
+        0,  4096,  4097,  3584,  3840,  3776,  3784,     0, 
+     4096,  4097,  3584,  3840,  3776,  3792,  3788,     0, 
+     4096,  4097,  3584,  3840,  3776,  3792,  3788,     0, 
+     4096,  4097,  3584,  3840,  3776,  3792,  3793,  3790, 
+        0,  4096,  4097,  3584,  3840,  3776,     0,  4096, 
+     4097,  3584,  3840,  3776,  3792,     0,  4096,  4097, 
+     3584,  3840,  3776,  3792,     0,  4096,  4097,  3584, 
+     3840,  3776,  3792,  3794,     0,  4096,  4097,  3584, 
+     3840,  3776,  3792,     0,  4096,  4097,  3584,  3840, 
+     3776,  3792,  3796,     0,  4096,  4097,  3584,  3840, 
+     3776,  3792,  3796,     0,  4096,  4097,  3584,  3840, 
+     3776,  3792,  3800,  3798,     0,  4096,  4097,  3584, 
+     3840,  3776,  3792,     0,  4096,  4097,  3584,  3840, 
+     3776,  3808,  3800,     0,  4096,  4097,  3584,  3840, 
+     3776,  3808,  3800,     0,  4096,  4097,  3584,  3840, 
+     3776,  3808,  3800,  3802,     0,  4096,  4097,  3584, 
+     3840,  3776,  3808,  3800,     0,  4096,  4097,  3584, 
+     3840,  3776,  3808,  3809,  3804,     0,  4096,  4097, 
+     3584,  3840,  3776,  3808,  3809,  3804,     0,  4096, 
+     4097,  3584,  3840,  3776,  3808,  3809,  3804,  3806, 
+        0,  4096,  4097,  3584,  3840,  3776,     0,  4096, 
+     4097,  3584,  3840,  3841,  3808,     0,  4096,  4097, 
+     3584,  3840,  3841,  3808,     0,  4096,  4097,  3584, 
+     3840,  3841,  3808,  3810,     0,  4096,  4097,  3584, 
+     3840,  3841,  3808,     0,  4096,  4097,  3584,  3840, 
+     3841,  3808,  3812,     0,  4096,  4097,  3584,  3840, 
+     3841,  3808,  3812,     0,  4096,  4097,  3584,  3840, 
+     3841,  3808,  3816,  3814,     0,  4096,  4097,  3584, 
+     3840,  3841,  3808,     0,  4096,  4097,  3584,  3840, 
+     3841,  3808,  3816,     0,  4096,  4097,  3584,  3840, 
+     3841,  3808,  3816,     0,  4096,  4097,  3584,  3840, 
+     3841,  3808,  3816,  3818,     0,  4096,  4097,  3584, 
+     3840,  3841,  3808,  3816,     0,  4096,  4097,  3584, 
+     3840,  3841,  3808,  3824,  3820,     0,  4096,  4097, 
+     3584,  3840,  3841,  3808,  3824,  3820,     0,  4096, 
+     4097,  3584,  3840,  3841,  3808,  3824,  3825,  3822, 
+        0,  4096,  4097,  3584,  3840,  3841,  3808,     0, 
+     4096,  4097,  3584,  3840,  3841,  3808,  3824,     0, 
+     4096,  4097,  3584,  3840,  3841,  3843,  3824,     0, 
+     4096,  4097,  3584,  3840,  3841,  3843,  3824,  3826, 
+        0,  4096,  4097,  3584,  3840,  3841,  3843,  3824, 
+        0,  4096,  4097,  3584,  3840,  3841,  3843,  3824, 
+     3828,     0,  4096,  4097,  3584,  3840,  3841,  3843, 
+     3824,  3828,     0,  4096,  4097,  3584,  3840,  3841, 
+     3843,  3824,  3832,  3830,     0,  4096,  4097,  3584, 
+     3840,  3841,  3843,  3824,     0,  4096,  4097,  3584, 
+     3840,  3841,  3843,  3824,  3832,     0,  4096,  4097, 
+     3584,  3840,  3841,  3843,  3824,  3832,     0,  4096, 
+     4097,  3584,  3840,  3841,  3843,  3824,  3832,  3834, 
+        0,  4096,  4097,  3584,  3840,  3841,  3843,  3847, 
+     3832,     0,  4096,  4097,  3584,  3840,  3841,  3843, 
+     3847,  3832,  3836,     0,  4096,  4097,  3584,  3840, 
+     3841,  3843,  3847,  3832,  3836,     0,  4096,  4097, 
+     3584,  3840,  3841,  3843,  3847,  3832,  3836,  3838, 
+        0,  4096,  4097,  3584,     0,  4096,  4097,  3584, 
+     3840,     0,  4096,  4097,  3584,  3840,     0,  4096, 
+     4097,  3584,  3840,  3842,     0,  4096,  4097,  4099, 
+     3840,     0,  4096,  4097,  4099,  3840,  3844,     0, 
+     4096,  4097,  4099,  3840,  3844,     0,  4096,  4097, 
+     4099,  3840,  3848,  3846,     0,  4096,  4097,  4099, 
+     3840,     0,  4096,  4097,  4099,  3840,  3848,     0, 
+     4096,  4097,  4099,  3840,  3848,     0,  4096,  4097, 
+     4099,  3840,  3848,  3850,     0,  4096,  4097,  4099, 
+     3840,  3848,     0,  4096,  4097,  4099,  3840,  3856, 
+     3852,     0,  4096,  4097,  4099,  3840,  3856,  3852, 
+        0,  4096,  4097,  4099,  3840,  3856,  3857,  3854, 
+        0,  4096,  4097,  4099,  3840,     0,  4096,  4097, 
+     4099,  3840,  3856,     0,  4096,  4097,  4099,  3840, 
+     3856,     0,  4096,  4097,  4099,  3840,  3856,  3858, 
+        0,  4096,  4097,  4099,  3840,  3856,     0,  4096, 
+     4097,  4099,  3840,  3856,  3860,     0,  4096,  4097, 
+     4099,  3840,  3856,  3860,     0,  4096,  4097,  4099, 
+     3840,  3856,  3864,  3862,     0,  4096,  4097,  4099, 
+     3840,  3856,     0,  4096,  4097,  4099,  3840,  3872, 
+     3864,     0,  4096,  4097,  4099,  3840,  3872,  3864, 
+        0,  4096,  4097,  4099,  3840,  3872,  3864,  3866, 
+        0,  4096,  4097,  4099,  3840,  3872,  3864,     0, 
+     4096,  4097,  4099,  3840,  3872,  3873,  3868,     0, 
+     4096,  4097,  4099,  3840,  3872,  3873,  3868,     0, 
+     4096,  4097,  4099,  3840,  3872,  3873,  3868,  3870, 
+        0,  4096,  4097,  4099,  3840,     0,  4096,  4097, 
+     4099,  3840,  3872,     0,  4096,  4097,  4099,  3840, 
+     3872,     0,  4096,  4097,  4099,  3840,  3872,  3874, 
+        0,  4096,  4097,  4099,  3840,  3872,     0,  4096, 
+     4097,  4099,  3840,  3872,  3876,     0,  4096,  4097, 
+     4099,  3840,  3872,  3876,     0,  4096,  4097,  4099, 
+     3840,  3872,  3880,  3878,     0,  4096,  4097,  4099, 
+     3840,  3872,     0,  4096,  4097,  4099,  3840,  3872, 
+     3880,     0,  4096,  4097,  4099,  3840,  3872,  3880, 
+        0,  4096,  4097,  4099,  3840,  3872,  3880,  3882, 
+        0,  4096,  4097,  4099,  3840,  3872,  3880,     0, 
+     4096,  4097,  4099,  3840,  3872,  3888,  3884,     0, 
+     4096,  4097,  4099,  3840,  3872,  3888,  3884,     0, 
+     4096,  4097,  4099,  3840,  3872,  3888,  3889,  3886, 
+        0,  4096,  4097,  4099,  3840,  3872,     0,  4096, 
+     4097,  4099,  3840,  3904,  3888,     0,  4096,  4097, 
+     4099,  3840,  3904,  3888,     0,  4096,  4097,  4099, 
+     3840,  3904,  3888,  3890,     0,  4096,  4097,  4099, 
+     3840,  3904,  3888,     0,  4096,  4097,  4099,  3840, 
+     3904,  3888,  3892,     0,  4096,  4097,  4099,  3840, 
+     3904,  3888,  3892,     0,  4096,  4097,  4099,  3840, 
+     3904,  3888,  3896,  3894,     0,  4096,  4097,  4099, 
+     3840,  3904,  3888,     0,  4096,  4097,  4099,  3840, 
+     3904,  3905,  3896,     0,  4096,  4097,  4099,  3840, 
+     3904,  3905,  3896,     0,  4096,  4097,  4099,  3840, 
+     3904,  3905,  3896,  3898,     0,  4096,  4097,  4099, 
+     3840,  3904,  3905,  3896,     0,  4096,  4097,  4099, 
+     3840,  3904,  3905,  3896,  3900,     0,  4096,  4097, 
+     4099,  3840,  3904,  3905,  3907,  3900,     0,  4096, 
+     4097,  4099,  3840,  3904,  3905,  3907,  3900,  3902, 
+        0,  4096,  4097,  4099,  3840,     0,  4096,  4097, 
+     4099,  3840,  3904,     0,  4096,  4097,  4099,  3840, 
+     3904,     0,  4096,  4097,  4099,  3840,  3904,  3906, 
+        0,  4096,  4097,  4099,  3840,  3904,     0,  4096, 
+     4097,  4099,  3840,  3904,  3908,     0,  4096,  4097, 
+     4099,  3840,  3904,  3908,     0,  4096,  4097,  4099, 
+     3840,  3904,  3912,  3910,     0,  4096,  4097,  4099, 
+     3840,  3904,     0,  4096,  4097,  4099,  3840,  3904, 
+     3912,     0,  4096,  4097,  4099,  3840,  3904,  3912, 
+        0,  4096,  4097,  4099,  3840,  3904,  3912,  3914, 
+        0,  4096,  4097,  4099,  3840,  3904,  3912,     0, 
+     4096,  4097,  4099,  3840,  3904,  3920,  3916,     0, 
+     4096,  4097,  4099,  3840,  3904,  3920,  3916,     0, 
+     4096,  4097,  4099,  3840,  3904,  3920,  3921,  3918, 
+        0,  4096,  4097,  4099,  3840,  3904,     0,  4096, 
+     4097,  4099,  3840,  3904,  3920,     0,  4096,  4097, 
+     4099,  3840,  3904,  3920,     0,  4096,  4097,  4099, 
+     3840,  3904,  3920,  3922,     0,  4096,  4097,  4099, 
+     3840,  3904,  3920,     0,  4096,  4097,  4099,  3840, 
+     3904,  3920,  3924,     0,  4096,  4097,  4099,  3840, 
+     3904,  3920,  3924,     0,  4096,  4097,  4099,  3840, 
+     3904,  3920,  3928,  3926,     0,  4096,  4097,  4099, 
+     3840,  3904,  3920,     0,  4096,  4097,  4099,  3840, 
+     3904,  3936,  3928,     0,  4096,  4097,  4099,  3840, 
+     3904,  3936,  3928,     0,  4096,  4097,  4099,  3840, 
+     3904,  3936,  3928,  3930,     0,  4096,  4097,  4099, 
+     3840,  3904,  3936,  3928,     0,  4096,  4097,  4099, 
+     3840,  3904,  3936,  3937,  3932,     0,  4096,  4097, 
+     4099,  3840,  3904,  3936,  3937,  3932,     0,  4096, 
+     4097,  4099,  3840,  3904,  3936,  3937,  3932,  3934, 
+        0,  4096,  4097,  4099,  3840,  3904,     0,  4096, 
+     4097,  4099,  3840,  3968,  3936,     0,  4096,  4097, 
+     4099,  3840,  3968,  3936,     0,  4096,  4097,  4099, 
+     3840,  3968,  3936,  3938,     0,  4096,  4097,  4099, 
+     3840,  3968,  3936,     0,  4096,  4097,  4099,  3840, 
+     3968,  3936,  3940,     0,  4096,  4097,  4099,  3840, 
+     3968,  3936,  3940,     0,  4096,  4097,  4099,  3840, 
+     3968,  3936,  3944,  3942,     0,  4096,  4097,  4099, 
+     3840,  3968,  3936,     0,  4096,  4097,  4099,  3840, 
+     3968,  3936,  3944,     0,  4096,  4097,  4099,  3840, 
+     3968,  3936,  3944,     0,  4096,  4097,  4099,  3840, 
+     3968,  3936,  3944,  3946,     0,  4096,  4097,  4099, 
+     3840,  3968,  3936,  3944,     0,  4096,  4097,  4099, 
+     3840,  3968,  3936,  3952,  3948,     0,  4096,  4097, 
+     4099,  3840,  3968,  3936,  3952,  3948,     0,  4096, 
+     4097,  4099,  3840,  3968,  3936,  3952,  3953,  3950, 
+        0,  4096,  4097,  4099,  3840,  3968,  3936,     0, 
+     4096,  4097,  4099,  3840,  3968,  3969,  3952,     0, 
+     4096,  4097,  4099,  3840,  3968,  3969,  3952,     0, 
+     4096,  4097,  4099,  3840,  3968,  3969,  3952,  3954, 
+        0,  4096,  4097,  4099,  3840,  3968,  3969,  3952, 
+        0,  4096,  4097,  4099,  3840,  3968,  3969,  3952, 
+     3956,     0,  4096,  4097,  4099,  3840,  3968,  3969, 
+     3952,  3956,     0,  4096,  4097,  4099,  3840,  3968, 
+     3969,  3952,  3960,  3958,     0,  4096,  4097,  4099, 
+     3840,  3968,  3969,  3952,     0,  4096,  4097,  4099, 
+     3840,  3968,  3969,  3952,  3960,     0,  4096,  4097, 
+     4099,  3840,  3968,  3969,  3971,  3960,     0,  4096, 
+     4097,  4099,  3840,  3968,  3969,  3971,  3960,  3962, 
+        0,  4096,  4097,  4099,  3840,  3968,  3969,  3971, 
+     3960,     0,  4096,  4097,  4099,  3840,  3968,  3969, 
+     3971,  3960,  3964,     0,  4096,  4097,  4099,  3840, 
+     3968,  3969,  3971,  3960,  3964,     0,  4096,  4097, 
+     4099,  3840,  3968,  3969,  3971,  3960,  3964,  3966, 
+        0,  4096,  4097,  4099,  3840,     0,  4096,  4097, 
+     4099,  3840,  3968,     0,  4096,  4097,  4099,  3840, 
+     3968,     0,  4096,  4097,  4099,  3840,  3968,  3970, 
+        0,  4096,  4097,  4099,  3840,  3968,     0,  4096, 
+     4097,  4099,  3840,  3968,  3972,     0,  4096,  4097, 
+     4099,  3840,  3968,  3972,     0,  4096,  4097,  4099, 
+     3840,  3968,  3976,  3974,     0,  4096,  4097,  4099, 
+     4103,  3968,     0,  4096,  4097,  4099,  4103,  3968, 
+     3976,     0,  4096,  4097,  4099,  4103,  3968,  3976, 
+        0,  4096,  4097,  4099,  4103,  3968,  3976,  3978, 
+        0,  4096,  4097,  4099,  4103,  3968,  3976,     0, 
+     4096,  4097,  4099,  4103,  3968,  3984,  3980,     0, 
+     4096,  4097,  4099,  4103,  3968,  3984,  3980,     0, 
+     4096,  4097,  4099,  4103,  3968,  3984,  3985,  3982, 
+        0,  4096,  4097,  4099,  4103,  3968,     0,  4096, 
+     4097,  4099,  4103,  3968,  3984,     0,  4096,  4097, 
+     4099,  4103,  3968,  3984,     0,  4096,  4097,  4099, 
+     4103,  3968,  3984,  3986,     0,  4096,  4097,  4099, 
+     4103,  3968,  3984,     0,  4096,  4097,  4099,  4103, 
+     3968,  3984,  3988,     0,  4096,  4097,  4099,  4103, 
+     3968,  3984,  3988,     0,  4096,  4097,  4099,  4103, 
+     3968,  3984,  3992,  3990,     0,  4096,  4097,  4099, 
+     4103,  3968,  3984,     0,  4096,  4097,  4099,  4103, 
+     3968,  4000,  3992,     0,  4096,  4097,  4099,  4103, 
+     3968,  4000,  3992,     0,  4096,  4097,  4099,  4103, 
+     3968,  4000,  3992,  3994,     0,  4096,  4097,  4099, 
+     4103,  3968,  4000,  3992,     0,  4096,  4097,  4099, 
+     4103,  3968,  4000,  4001,  3996,     0,  4096,  4097, 
+     4099,  4103,  3968,  4000,  4001,  3996,     0,  4096, 
+     4097,  4099,  4103,  3968,  4000,  4001,  3996,  3998, 
+        0,  4096,  4097,  4099,  4103,  3968,     0,  4096, 
+     4097,  4099,  4103,  3968,  4000,     0,  4096,  4097, 
+     4099,  4103,  3968,  4000,     0,  4096,  4097,  4099, 
+     4103,  3968,  4000,  4002,     0,  4096,  4097,  4099, 
+     4103,  3968,  4000,     0,  4096,  4097,  4099,  4103, 
+     3968,  4000,  4004,     0,  4096,  4097,  4099,  4103, 
+     3968,  4000,  4004,     0,  4096,  4097,  4099,  4103, 
+     3968,  4000,  4008,  4006,     0,  4096,  4097,  4099, 
+     4103,  3968,  4000,     0,  4096,  4097,  4099,  4103, 
+     3968,  4000,  4008,     0,  4096,  4097,  4099,  4103, 
+     3968,  4000,  4008,     0,  4096,  4097,  4099,  4103, 
+     3968,  4000,  4008,  4010,     0,  4096,  4097,  4099, 
+     4103,  3968,  4000,  4008,     0,  4096,  4097,  4099, 
+     4103,  3968,  4000,  4016,  4012,     0,  4096,  4097, 
+     4099,  4103,  3968,  4000,  4016,  4012,     0,  4096, 
+     4097,  4099,  4103,  3968,  4000,  4016,  4017,  4014, 
+        0,  4096,  4097,  4099,  4103,  3968,  4000,     0, 
+     4096,  4097,  4099,  4103,  3968,  4032,  4016,     0, 
+     4096,  4097,  4099,  4103,  3968,  4032,  4016,     0, 
+     4096,  4097,  4099,  4103,  3968,  4032,  4016,  4018, 
+        0,  4096,  4097,  4099,  4103,  3968,  4032,  4016, 
+        0,  4096,  4097,  4099,  4103,  3968,  4032,  4016, 
+     4020,     0,  4096,  4097,  4099,  4103,  3968,  4032, 
+     4016,  4020,     0,  4096,  4097,  4099,  4103,  3968, 
+     4032,  4016,  4024,  4022,     0,  4096,  4097,  4099, 
+     4103,  3968,  4032,  4016,     0,  4096,  4097,  4099, 
+     4103,  3968,  4032,  4033,  4024,     0,  4096,  4097, 
+     4099,  4103,  3968,  4032,  4033,  4024,     0,  4096, 
+     4097,  4099,  4103,  3968,  4032,  4033,  4024,  4026, 
+        0,  4096,  4097,  4099,  4103,  3968,  4032,  4033, 
+     4024,     0,  4096,  4097,  4099,  4103,  3968,  4032, 
+     4033,  4024,  4028,     0,  4096,  4097,  4099,  4103, 
+     3968,  4032,  4033,  4035,  4028,     0,  4096,  4097, 
+     4099,  4103,  3968,  4032,  4033,  4035,  4028,  4030, 
+        0,  4096,  4097,  4099,  4103,  3968,     0,  4096, 
+     4097,  4099,  4103,  3968,  4032,     0,  4096,  4097, 
+     4099,  4103,  3968,  4032,     0,  4096,  4097,  4099, 
+     4103,  3968,  4032,  4034,     0,  4096,  4097,  4099, 
+     4103,  3968,  4032,     0,  4096,  4097,  4099,  4103, 
+     3968,  4032,  4036,     0,  4096,  4097,  4099,  4103, 
+     3968,  4032,  4036,     0,  4096,  4097,  4099,  4103, 
+     3968,  4032,  4040,  4038,     0,  4096,  4097,  4099, 
+     4103,  3968,  4032,     0,  4096,  4097,  4099,  4103, 
+     3968,  4032,  4040,     0,  4096,  4097,  4099,  4103, 
+     3968,  4032,  4040,     0,  4096,  4097,  4099,  4103, 
+     3968,  4032,  4040,  4042,     0,  4096,  4097,  4099, 
+     4103,  3968,  4032,  4040,     0,  4096,  4097,  4099, 
+     4103,  3968,  4032,  4048,  4044,     0,  4096,  4097, 
+     4099,  4103,  3968,  4032,  4048,  4044,     0,  4096, 
+     4097,  4099,  4103,  3968,  4032,  4048,  4049,  4046, 
+        0,  4096,  4097,  4099,  4103,  4111,  4032,     0, 
+     4096,  4097,  4099,  4103,  4111,  4032,  4048,     0, 
+     4096,  4097,  4099,  4103,  4111,  4032,  4048,     0, 
+     4096,  4097,  4099,  4103,  4111,  4032,  4048,  4050, 
+        0,  4096,  4097,  4099,  4103,  4111,  4032,  4048, 
+        0,  4096,  4097,  4099,  4103,  4111,  4032,  4048, 
+     4052,     0,  4096,  4097,  4099,  4103,  4111,  4032, 
+     4048,  4052,     0,  4096,  4097,  4099,  4103,  4111, 
+     4032,  4048,  4056,  4054,     0,  4096,  4097,  4099, 
+     4103,  4111,  4032,  4048,     0,  4096,  4097,  4099, 
+     4103,  4111,  4032,  4064,  4056,     0,  4096,  4097, 
+     4099,  4103,  4111,  4032,  4064,  4056,     0,  4096, 
+     4097,  4099,  4103,  4111,  4032,  4064,  4056,  4058, 
+        0,  4096,  4097,  4099,  4103,  4111,  4032,  4064, 
+     4056,     0,  4096,  4097,  4099,  4103,  4111,  4032, 
+     4064,  4065,  4060,     0,  4096,  4097,  4099,  4103, 
+     4111,  4032,  4064,  4065,  4060,     0,  4096,  4097, 
+     4099,  4103,  4111,  4032,  4064,  4065,  4060,  4062, 
+        0,  4096,  4097,  4099,  4103,  4111,  4032,     0, 
+     4096,  4097,  4099,  4103,  4111,  4032,  4064,     0, 
+     4096,  4097,  4099,  4103,  4111,  4032,  4064,     0, 
+     4096,  4097,  4099,  4103,  4111,  4032,  4064,  4066, 
+        0,  4096,  4097,  4099,  4103,  4111,  4032,  4064, 
+        0,  4096,  4097,  4099,  4103,  4111,  4032,  4064, 
+     4068,     0,  4096,  4097,  4099,  4103,  4111,  4032, 
+     4064,  4068,     0,  4096,  4097,  4099,  4103,  4111, 
+     4032,  4064,  4072,  4070,     0,  4096,  4097,  4099, 
+     4103,  4111,  4032,  4064,     0,  4096,  4097,  4099, 
+     4103,  4111,  4032,  4064,  4072,     0,  4096,  4097, 
+     4099,  4103,  4111,  4032,  4064,  4072,     0,  4096, 
+     4097,  4099,  4103,  4111,  4032,  4064,  4072,  4074, 
+        0,  4096,  4097,  4099,  4103,  4111,  4032,  4064, 
+     4072,     0,  4096,  4097,  4099,  4103,  4111,  4032, 
+     4064,  4080,  4076,     0,  4096,  4097,  4099,  4103, 
+     4111,  4032,  4064,  4080,  4076,     0,  4096,  4097, 
+     4099,  4103,  4111,  4032,  4064,  4080,  4081,  4078, 
+        0,  4096,  4097,  4099,  4103,  4111,  4032,  4064, 
+        0,  4096,  4097,  4099,  4103,  4111,  4032,  4064, 
+     4080,     0,  4096,  4097,  4099,  4103,  4111,  4032, 
+     4064,  4080,     0,  4096,  4097,  4099,  4103,  4111, 
+     4032,  4064,  4080,  4082,     0,  4096,  4097,  4099, 
+     4103,  4111,  4032,  4064,  4080,     0,  4096,  4097, 
+     4099,  4103,  4111,  4032,  4064,  4080,  4084,     0, 
+     4096,  4097,  4099,  4103,  4111,  4032,  4064,  4080, 
+     4084,     0,  4096,  4097,  4099,  4103,  4111,  4032, 
+     4064,  4080,  4088,  4086,     0,  4096,  4097,  4099, 
+     4103,  4111,  4032,  4064,  4080,     0,  4096,  4097, 
+     4099,  4103,  4111,  4032,  4064,  4080,  4088,     0, 
+     4096,  4097,  4099,  4103,  4111,  4032,  4064,  4080, 
+     4088,     0,  4096,  4097,  4099,  4103,  4111,  4032, 
+     4064,  4080,  4088,  4090,     0,  4096,  4097,  4099, 
+     4103,  4111,  4032,  4064,  4080,  4088,     0,  4096, 
+     4097,  4099,  4103,  4111,  4032,  4064,  4080,  4088, 
+     4092,     0,  4096,  4097,  4099,  4103,  4111,  4032, 
+     4064,  4080,  4088,  4092,     0,  4096,  4097,  4099, 
+     4103,  4111,  4032,  4064,  4080,  4088,  4092,  4094, 
+        0,     0,  4096,     0,  4096,     0,  4096,  4098, 
+        0,  4096,     0,  4096,  4100,     0,  4096,  4100, 
+        0,  4096,  4104,  4102,     0,  4096,     0,  4096, 
+     4104,     0,  4096,  4104,     0,  4096,  4104,  4106, 
+        0,  4096,  4104,     0,  4096,  4112,  4108,     0, 
+     4096,  4112,  4108,     0,  4096,  4112,  4113,  4110, 
+        0,  4096,     0,  4096,  4112,     0,  4096,  4112, 
+        0,  4096,  4112,  4114,     0,  4096,  4112,     0, 
+     4096,  4112,  4116,     0,  4096,  4112,  4116,     0, 
+     4096,  4112,  4120,  4118,     0,  4096,  4112,     0, 
+     4096,  4128,  4120,     0,  4096,  4128,  4120,     0, 
+     4096,  4128,  4120,  4122,     0,  4096,  4128,  4120, 
+        0,  4096,  4128,  4129,  4124,     0,  4096,  4128, 
+     4129,  4124,     0,  4096,  4128,  4129,  4124,  4126, 
+        0,  4096,     0,  4096,  4128,     0,  4096,  4128, 
+        0,  4096,  4128,  4130,     0,  4096,  4128,     0, 
+     4096,  4128,  4132,     0,  4096,  4128,  4132,     0, 
+     4096,  4128,  4136,  4134,     0,  4096,  4128,     0, 
+     4096,  4128,  4136,     0,  4096,  4128,  4136,     0, 
+     4096,  4128,  4136,  4138,     0,  4096,  4128,  4136, 
+        0,  4096,  4128,  4144,  4140,     0,  4096,  4128, 
+     4144,  4140,     0,  4096,  4128,  4144,  4145,  4142, 
+        0,  4096,  4128,     0,  4096,  4160,  4144,     0, 
+     4096,  4160,  4144,     0,  4096,  4160,  4144,  4146, 
+        0,  4096,  4160,  4144,     0,  4096,  4160,  4144, 
+     4148,     0,  4096,  4160,  4144,  4148,     0,  4096, 
+     4160,  4144,  4152,  4150,     0,  4096,  4160,  4144, 
+        0,  4096,  4160,  4161,  4152,     0,  4096,  4160, 
+     4161,  4152,     0,  4096,  4160,  4161,  4152,  4154, 
+        0,  4096,  4160,  4161,  4152,     0,  4096,  4160, 
+     4161,  4152,  4156,     0,  4096,  4160,  4161,  4163, 
+     4156,     0,  4096,  4160,  4161,  4163,  4156,  4158, 
+        0,  4096,     0,  4096,  4160,     0,  4096,  4160, 
+        0,  4096,  4160,  4162,     0,  4096,  4160,     0, 
+     4096,  4160,  4164,     0,  4096,  4160,  4164,     0, 
+     4096,  4160,  4168,  4166,     0,  4096,  4160,     0, 
+     4096,  4160,  4168,     0,  4096,  4160,  4168,     0, 
+     4096,  4160,  4168,  4170,     0,  4096,  4160,  4168, 
+        0,  4096,  4160,  4176,  4172,     0,  4096,  4160, 
+     4176,  4172,     0,  4096,  4160,  4176,  4177,  4174, 
+        0,  4096,  4160,     0,  4096,  4160,  4176,     0, 
+     4096,  4160,  4176,     0,  4096,  4160,  4176,  4178, 
+        0,  4096,  4160,  4176,     0,  4096,  4160,  4176, 
+     4180,     0,  4096,  4160,  4176,  4180,     0,  4096, 
+     4160,  4176,  4184,  4182,     0,  4096,  4160,  4176, 
+        0,  4096,  4160,  4192,  4184,     0,  4096,  4160, 
+     4192,  4184,     0,  4096,  4160,  4192,  4184,  4186, 
+        0,  4096,  4160,  4192,  4184,     0,  4096,  4160, 
+     4192,  4193,  4188,     0,  4096,  4160,  4192,  4193, 
+     4188,     0,  4096,  4160,  4192,  4193,  4188,  4190, 
+        0,  4096,  4160,     0,  4096,  4224,  4192,     0, 
+     4096,  4224,  4192,     0,  4096,  4224,  4192,  4194, 
+        0,  4096,  4224,  4192,     0,  4096,  4224,  4192, 
+     4196,     0,  4096,  4224,  4192,  4196,     0,  4096, 
+     4224,  4192,  4200,  4198,     0,  4096,  4224,  4192, 
+        0,  4096,  4224,  4192,  4200,     0,  4096,  4224, 
+     4192,  4200,     0,  4096,  4224,  4192,  4200,  4202, 
+        0,  4096,  4224,  4192,  4200,     0,  4096,  4224, 
+     4192,  4208,  4204,     0,  4096,  4224,  4192,  4208, 
+     4204,     0,  4096,  4224,  4192,  4208,  4209,  4206, 
+        0,  4096,  4224,  4192,     0,  4096,  4224,  4225, 
+     4208,     0,  4096,  4224,  4225,  4208,     0,  4096, 
+     4224,  4225,  4208,  4210,     0,  4096,  4224,  4225, 
+     4208,     0,  4096,  4224,  4225,  4208,  4212,     0, 
+     4096,  4224,  4225,  4208,  4212,     0,  4096,  4224, 
+     4225,  4208,  4216,  4214,     0,  4096,  4224,  4225, 
+     4208,     0,  4096,  4224,  4225,  4208,  4216,     0, 
+     4096,  4224,  4225,  4227,  4216,     0,  4096,  4224, 
+     4225,  4227,  4216,  4218,     0,  4096,  4224,  4225, 
+     4227,  4216,     0,  4096,  4224,  4225,  4227,  4216, 
+     4220,     0,  4096,  4224,  4225,  4227,  4216,  4220, 
+        0,  4096,  4224,  4225,  4227,  4216,  4220,  4222, 
+        0,  4096,     0,  4096,  4224,     0,  4096,  4224, 
+        0,  4096,  4224,  4226,     0,  4096,  4224,     0, 
+     4096,  4224,  4228,     0,  4096,  4224,  4228,     0, 
+     4096,  4224,  4232,  4230,     0,  4096,  4224,     0, 
+     4096,  4224,  4232,     0,  4096,  4224,  4232,     0, 
+     4096,  4224,  4232,  4234,     0,  4096,  4224,  4232, 
+        0,  4096,  4224,  4240,  4236,     0,  4096,  4224, 
+     4240,  4236,     0,  4096,  4224,  4240,  4241,  4238, 
+        0,  4096,  4224,     0,  4096,  4224,  4240,     0, 
+     4096,  4224,  4240,     0,  4096,  4224,  4240,  4242, 
+        0,  4096,  4224,  4240,     0,  4096,  4224,  4240, 
+     4244,     0,  4096,  4224,  4240,  4244,     0,  4096, 
+     4224,  4240,  4248,  4246,     0,  4096,  4224,  4240, 
+        0,  4096,  4224,  4256,  4248,     0,  4096,  4224, 
+     4256,  4248,     0,  4096,  4224,  4256,  4248,  4250, 
+        0,  4096,  4224,  4256,  4248,     0,  4096,  4224, 
+     4256,  4257,  4252,     0,  4096,  4224,  4256,  4257, 
+     4252,     0,  4096,  4224,  4256,  4257,  4252,  4254, 
+        0,  4096,  4224,     0,  4096,  4224,  4256,     0, 
+     4096,  4224,  4256,     0,  4096,  4224,  4256,  4258, 
+        0,  4096,  4224,  4256,     0,  4096,  4224,  4256, 
+     4260,     0,  4096,  4224,  4256,  4260,     0,  4096, 
+     4224,  4256,  4264,  4262,     0,  4096,  4224,  4256, 
+        0,  4096,  4224,  4256,  4264,     0,  4096,  4224, 
+     4256,  4264,     0,  4096,  4224,  4256,  4264,  4266, 
+        0,  4096,  4224,  4256,  4264,     0,  4096,  4224, 
+     4256,  4272,  4268,     0,  4096,  4224,  4256,  4272, 
+     4268,     0,  4096,  4224,  4256,  4272,  4273,  4270, 
+        0,  4096,  4224,  4256,     0,  4096,  4224,  4288, 
+     4272,     0,  4096,  4224,  4288,  4272,     0,  4096, 
+     4224,  4288,  4272,  4274,     0,  4096,  4224,  4288, 
+     4272,     0,  4096,  4224,  4288,  4272,  4276,     0, 
+     4096,  4224,  4288,  4272,  4276,     0,  4096,  4224, 
+     4288,  4272,  4280,  4278,     0,  4096,  4224,  4288, 
+     4272,     0,  4096,  4224,  4288,  4289,  4280,     0, 
+     4096,  4224,  4288,  4289,  4280,     0,  4096,  4224, 
+     4288,  4289,  4280,  4282,     0,  4096,  4224,  4288, 
+     4289,  4280,     0,  4096,  4224,  4288,  4289,  4280, 
+     4284,     0,  4096,  4224,  4288,  4289,  4291,  4284, 
+        0,  4096,  4224,  4288,  4289,  4291,  4284,  4286, 
+        0,  4096,  4224,     0,  4096,  4352,  4288,     0, 
+     4096,  4352,  4288,     0,  4096,  4352,  4288,  4290, 
+        0,  4096,  4352,  4288,     0,  4096,  4352,  4288, 
+     4292,     0,  4096,  4352,  4288,  4292,     0,  4096, 
+     4352,  4288,  4296,  4294,     0,  4096,  4352,  4288, 
+        0,  4096,  4352,  4288,  4296,     0,  4096,  4352, 
+     4288,  4296,     0,  4096,  4352,  4288,  4296,  4298, 
+        0,  4096,  4352,  4288,  4296,     0,  4096,  4352, 
+     4288,  4304,  4300,     0,  4096,  4352,  4288,  4304, 
+     4300,     0,  4096,  4352,  4288,  4304,  4305,  4302, 
+        0,  4096,  4352,  4288,     0,  4096,  4352,  4288, 
+     4304,     0,  4096,  4352,  4288,  4304,     0,  4096, 
+     4352,  4288,  4304,  4306,     0,  4096,  4352,  4288, 
+     4304,     0,  4096,  4352,  4288,  4304,  4308,     0, 
+     4096,  4352,  4288,  4304,  4308,     0,  4096,  4352, 
+     4288,  4304,  4312,  4310,     0,  4096,  4352,  4288, 
+     4304,     0,  4096,  4352,  4288,  4320,  4312,     0, 
+     4096,  4352,  4288,  4320,  4312,     0,  4096,  4352, 
+     4288,  4320,  4312,  4314,     0,  4096,  4352,  4288, 
+     4320,  4312,     0,  4096,  4352,  4288,  4320,  4321, 
+     4316,     0,  4096,  4352,  4288,  4320,  4321,  4316, 
+        0,  4096,  4352,  4288,  4320,  4321,  4316,  4318, 
+        0,  4096,  4352,  4288,     0,  4096,  4352,  4353, 
+     4320,     0,  4096,  4352,  4353,  4320,     0,  4096, 
+     4352,  4353,  4320,  4322,     0,  4096,  4352,  4353, 
+     4320,     0,  4096,  4352,  4353,  4320,  4324,     0, 
+     4096,  4352,  4353,  4320,  4324,     0,  4096,  4352, 
+     4353,  4320,  4328,  4326,     0,  4096,  4352,  4353, 
+     4320,     0,  4096,  4352,  4353,  4320,  4328,     0, 
+     4096,  4352,  4353,  4320,  4328,     0,  4096,  4352, 
+     4353,  4320,  4328,  4330,     0,  4096,  4352,  4353, 
+     4320,  4328,     0,  4096,  4352,  4353,  4320,  4336, 
+     4332,     0,  4096,  4352,  4353,  4320,  4336,  4332, 
+        0,  4096,  4352,  4353,  4320,  4336,  4337,  4334, 
+        0,  4096,  4352,  4353,  4320,     0,  4096,  4352, 
+     4353,  4320,  4336,     0,  4096,  4352,  4353,  4355, 
+     4336,     0,  4096,  4352,  4353,  4355,  4336,  4338, 
+        0,  4096,  4352,  4353,  4355,  4336,     0,  4096, 
+     4352,  4353,  4355,  4336,  4340,     0,  4096,  4352, 
+     4353,  4355,  4336,  4340,     0,  4096,  4352,  4353, 
+     4355,  4336,  4344,  4342,     0,  4096,  4352,  4353, 
+     4355,  4336,     0,  4096,  4352,  4353,  4355,  4336, 
+     4344,     0,  4096,  4352,  4353,  4355,  4336,  4344, 
+        0,  4096,  4352,  4353,  4355,  4336,  4344,  4346, 
+        0,  4096,  4352,  4353,  4355,  4359,  4344,     0, 
+     4096,  4352,  4353,  4355,  4359,  4344,  4348,     0, 
+     4096,  4352,  4353,  4355,  4359,  4344,  4348,     0, 
+     4096,  4352,  4353,  4355,  4359,  4344,  4348,  4350, 
+        0,  4096,     0,  4096,  4352,     0,  4096,  4352, 
+        0,  4096,  4352,  4354,     0,  4096,  4352,     0, 
+     4096,  4352,  4356,     0,  4096,  4352,  4356,     0, 
+     4096,  4352,  4360,  4358,     0,  4096,  4352,     0, 
+     4096,  4352,  4360,     0,  4096,  4352,  4360,     0, 
+     4096,  4352,  4360,  4362,     0,  4096,  4352,  4360, 
+        0,  4096,  4352,  4368,  4364,     0,  4096,  4352, 
+     4368,  4364,     0,  4096,  4352,  4368,  4369,  4366, 
+        0,  4096,  4352,     0,  4096,  4352,  4368,     0, 
+     4096,  4352,  4368,     0,  4096,  4352,  4368,  4370, 
+        0,  4096,  4352,  4368,     0,  4096,  4352,  4368, 
+     4372,     0,  4096,  4352,  4368,  4372,     0,  4096, 
+     4352,  4368,  4376,  4374,     0,  4096,  4352,  4368, 
+        0,  4096,  4352,  4384,  4376,     0,  4096,  4352, 
+     4384,  4376,     0,  4096,  4352,  4384,  4376,  4378, 
+        0,  4096,  4352,  4384,  4376,     0,  4096,  4352, 
+     4384,  4385,  4380,     0,  4096,  4352,  4384,  4385, 
+     4380,     0,  4096,  4352,  4384,  4385,  4380,  4382, 
+        0,  4096,  4352,     0,  4096,  4352,  4384,     0, 
+     4096,  4352,  4384,     0,  4096,  4352,  4384,  4386, 
+        0,  4096,  4352,  4384,     0,  4096,  4352,  4384, 
+     4388,     0,  4096,  4352,  4384,  4388,     0,  4096, 
+     4352,  4384,  4392,  4390,     0,  4096,  4352,  4384, 
+        0,  4096,  4352,  4384,  4392,     0,  4096,  4352, 
+     4384,  4392,     0,  4096,  4352,  4384,  4392,  4394, 
+        0,  4096,  4352,  4384,  4392,     0,  4096,  4352, 
+     4384,  4400,  4396,     0,  4096,  4352,  4384,  4400, 
+     4396,     0,  4096,  4352,  4384,  4400,  4401,  4398, 
+        0,  4096,  4352,  4384,     0,  4096,  4352,  4416, 
+     4400,     0,  4096,  4352,  4416,  4400,     0,  4096, 
+     4352,  4416,  4400,  4402,     0,  4096,  4352,  4416, 
+     4400,     0,  4096,  4352,  4416,  4400,  4404,     0, 
+     4096,  4352,  4416,  4400,  4404,     0,  4096,  4352, 
+     4416,  4400,  4408,  4406,     0,  4096,  4352,  4416, 
+     4400,     0,  4096,  4352,  4416,  4417,  4408,     0, 
+     4096,  4352,  4416,  4417,  4408,     0,  4096,  4352, 
+     4416,  4417,  4408,  4410,     0,  4096,  4352,  4416, 
+     4417,  4408,     0,  4096,  4352,  4416,  4417,  4408, 
+     4412,     0,  4096,  4352,  4416,  4417,  4419,  4412, 
+        0,  4096,  4352,  4416,  4417,  4419,  4412,  4414, 
+        0,  4096,  4352,     0,  4096,  4352,  4416,     0, 
+     4096,  4352,  4416,     0,  4096,  4352,  4416,  4418, 
+        0,  4096,  4352,  4416,     0,  4096,  4352,  4416, 
+     4420,     0,  4096,  4352,  4416,  4420,     0,  4096, 
+     4352,  4416,  4424,  4422,     0,  4096,  4352,  4416, 
+        0,  4096,  4352,  4416,  4424,     0,  4096,  4352, 
+     4416,  4424,     0,  4096,  4352,  4416,  4424,  4426, 
+        0,  4096,  4352,  4416,  4424,     0,  4096,  4352, 
+     4416,  4432,  4428,     0,  4096,  4352,  4416,  4432, 
+     4428,     0,  4096,  4352,  4416,  4432,  4433,  4430, 
+        0,  4096,  4352,  4416,     0,  4096,  4352,  4416, 
+     4432,     0,  4096,  4352,  4416,  4432,     0,  4096, 
+     4352,  4416,  4432,  4434,     0,  4096,  4352,  4416, 
+     4432,     0,  4096,  4352,  4416,  4432,  4436,     0, 
+     4096,  4352,  4416,  4432,  4436,     0,  4096,  4352, 
+     4416,  4432,  4440,  4438,     0,  4096,  4352,  4416, 
+     4432,     0,  4096,  4352,  4416,  4448,  4440,     0, 
+     4096,  4352,  4416,  4448,  4440,     0,  4096,  4352, 
+     4416,  4448,  4440,  4442,     0,  4096,  4352,  4416, 
+     4448,  4440,     0,  4096,  4352,  4416,  4448,  4449, 
+     4444,     0,  4096,  4352,  4416,  4448,  4449,  4444, 
+        0,  4096,  4352,  4416,  4448,  4449,  4444,  4446, 
+        0,  4096,  4352,  4416,     0,  4096,  4352,  4480, 
+     4448,     0,  4096,  4352,  4480,  4448,     0,  4096, 
+     4352,  4480,  4448,  4450,     0,  4096,  4352,  4480, 
+     4448,     0,  4096,  4352,  4480,  4448,  4452,     0, 
+     4096,  4352,  4480,  4448,  4452,     0,  4096,  4352, 
+     4480,  4448,  4456,  4454,     0,  4096,  4352,  4480, 
+     4448,     0,  4096,  4352,  4480,  4448,  4456,     0, 
+     4096,  4352,  4480,  4448,  4456,     0,  4096,  4352, 
+     4480,  4448,  4456,  4458,     0,  4096,  4352,  4480, 
+     4448,  4456,     0,  4096,  4352,  4480,  4448,  4464, 
+     4460,     0,  4096,  4352,  4480,  4448,  4464,  4460, 
+        0,  4096,  4352,  4480,  4448,  4464,  4465,  4462, 
+        0,  4096,  4352,  4480,  4448,     0,  4096,  4352, 
+     4480,  4481,  4464,     0,  4096,  4352,  4480,  4481, 
+     4464,     0,  4096,  4352,  4480,  4481,  4464,  4466, 
+        0,  4096,  4352,  4480,  4481,  4464,     0,  4096, 
+     4352,  4480,  4481,  4464,  4468,     0,  4096,  4352, 
+     4480,  4481,  4464,  4468,     0,  4096,  4352,  4480, 
+     4481,  4464,  4472,  4470,     0,  4096,  4352,  4480, 
+     4481,  4464,     0,  4096,  4352,  4480,  4481,  4464, 
+     4472,     0,  4096,  4352,  4480,  4481,  4483,  4472, 
+        0,  4096,  4352,  4480,  4481,  4483,  4472,  4474, 
+        0,  4096,  4352,  4480,  4481,  4483,  4472,     0, 
+     4096,  4352,  4480,  4481,  4483,  4472,  4476,     0, 
+     4096,  4352,  4480,  4481,  4483,  4472,  4476,     0, 
+     4096,  4352,  4480,  4481,  4483,  4472,  4476,  4478, 
+        0,  4096,  4352,     0,  4096,  4608,  4480,     0, 
+     4096,  4608,  4480,     0,  4096,  4608,  4480,  4482, 
+        0,  4096,  4608,  4480,     0,  4096,  4608,  4480, 
+     4484,     0,  4096,  4608,  4480,  4484,     0,  4096, 
+     4608,  4480,  4488,  4486,     0,  4096,  4608,  4480, 
+        0,  4096,  4608,  4480,  4488,     0,  4096,  4608, 
+     4480,  4488,     0,  4096,  4608,  4480,  4488,  4490, 
+        0,  4096,  4608,  4480,  4488,     0,  4096,  4608, 
+     4480,  4496,  4492,     0,  4096,  4608,  4480,  4496, 
+     4492,     0,  4096,  4608,  4480,  4496,  4497,  4494, 
+        0,  4096,  4608,  4480,     0,  4096,  4608,  4480, 
+     4496,     0,  4096,  4608,  4480,  4496,     0,  4096, 
+     4608,  4480,  4496,  4498,     0,  4096,  4608,  4480, 
+     4496,     0,  4096,  4608,  4480,  4496,  4500,     0, 
+     4096,  4608,  4480,  4496,  4500,     0,  4096,  4608, 
+     4480,  4496,  4504,  4502,     0,  4096,  4608,  4480, 
+     4496,     0,  4096,  4608,  4480,  4512,  4504,     0, 
+     4096,  4608,  4480,  4512,  4504,     0,  4096,  4608, 
+     4480,  4512,  4504,  4506,     0,  4096,  4608,  4480, 
+     4512,  4504,     0,  4096,  4608,  4480,  4512,  4513, 
+     4508,     0,  4096,  4608,  4480,  4512,  4513,  4508, 
+        0,  4096,  4608,  4480,  4512,  4513,  4508,  4510, 
+        0,  4096,  4608,  4480,     0,  4096,  4608,  4480, 
+     4512,     0,  4096,  4608,  4480,  4512,     0,  4096, 
+     4608,  4480,  4512,  4514,     0,  4096,  4608,  4480, 
+     4512,     0,  4096,  4608,  4480,  4512,  4516,     0, 
+     4096,  4608,  4480,  4512,  4516,     0,  4096,  4608, 
+     4480,  4512,  4520,  4518,     0,  4096,  4608,  4480, 
+     4512,     0,  4096,  4608,  4480,  4512,  4520,     0, 
+     4096,  4608,  4480,  4512,  4520,     0,  4096,  4608, 
+     4480,  4512,  4520,  4522,     0,  4096,  4608,  4480, 
+     4512,  4520,     0,  4096,  4608,  4480,  4512,  4528, 
+     4524,     0,  4096,  4608,  4480,  4512,  4528,  4524, 
+        0,  4096,  4608,  4480,  4512,  4528,  4529,  4526, 
+        0,  4096,  4608,  4480,  4512,     0,  4096,  4608, 
+     4480,  4544,  4528,     0,  4096,  4608,  4480,  4544, 
+     4528,     0,  4096,  4608,  4480,  4544,  4528,  4530, 
+        0,  4096,  4608,  4480,  4544,  4528,     0,  4096, 
+     4608,  4480,  4544,  4528,  4532,     0,  4096,  4608, 
+     4480,  4544,  4528,  4532,     0,  4096,  4608,  4480, 
+     4544,  4528,  4536,  4534,     0,  4096,  4608,  4480, 
+     4544,  4528,     0,  4096,  4608,  4480,  4544,  4545, 
+     4536,     0,  4096,  4608,  4480,  4544,  4545,  4536, 
+        0,  4096,  4608,  4480,  4544,  4545,  4536,  4538, 
+        0,  4096,  4608,  4480,  4544,  4545,  4536,     0, 
+     4096,  4608,  4480,  4544,  4545,  4536,  4540,     0, 
+     4096,  4608,  4480,  4544,  4545,  4547,  4540,     0, 
+     4096,  4608,  4480,  4544,  4545,  4547,  4540,  4542, 
+        0,  4096,  4608,  4480,     0,  4096,  4608,  4609, 
+     4544,     0,  4096,  4608,  4609,  4544,     0,  4096, 
+     4608,  4609,  4544,  4546,     0,  4096,  4608,  4609, 
+     4544,     0,  4096,  4608,  4609,  4544,  4548,     0, 
+     4096,  4608,  4609,  4544,  4548,     0,  4096,  4608, 
+     4609,  4544,  4552,  4550,     0,  4096,  4608,  4609, 
+     4544,     0,  4096,  4608,  4609,  4544,  4552,     0, 
+     4096,  4608,  4609,  4544,  4552,     0,  4096,  4608, 
+     4609,  4544,  4552,  4554,     0,  4096,  4608,  4609, 
+     4544,  4552,     0,  4096,  4608,  4609,  4544,  4560, 
+     4556,     0,  4096,  4608,  4609,  4544,  4560,  4556, 
+        0,  4096,  4608,  4609,  4544,  4560,  4561,  4558, 
+        0,  4096,  4608,  4609,  4544,     0,  4096,  4608, 
+     4609,  4544,  4560,     0,  4096,  4608,  4609,  4544, 
+     4560,     0,  4096,  4608,  4609,  4544,  4560,  4562, 
+        0,  4096,  4608,  4609,  4544,  4560,     0,  4096, 
+     4608,  4609,  4544,  4560,  4564,     0,  4096,  4608, 
+     4609,  4544,  4560,  4564,     0,  4096,  4608,  4609, 
+     4544,  4560,  4568,  4566,     0,  4096,  4608,  4609, 
+     4544,  4560,     0,  4096,  4608,  4609,  4544,  4576, 
+     4568,     0,  4096,  4608,  4609,  4544,  4576,  4568, 
+        0,  4096,  4608,  4609,  4544,  4576,  4568,  4570, 
+        0,  4096,  4608,  4609,  4544,  4576,  4568,     0, 
+     4096,  4608,  4609,  4544,  4576,  4577,  4572,     0, 
+     4096,  4608,  4609,  4544,  4576,  4577,  4572,     0, 
+     4096,  4608,  4609,  4544,  4576,  4577,  4572,  4574, 
+        0,  4096,  4608,  4609,  4544,     0,  4096,  4608, 
+     4609,  4544,  4576,     0,  4096,  4608,  4609,  4611, 
+     4576,     0,  4096,  4608,  4609,  4611,  4576,  4578, 
+        0,  4096,  4608,  4609,  4611,  4576,     0,  4096, 
+     4608,  4609,  4611,  4576,  4580,     0,  4096,  4608, 
+     4609,  4611,  4576,  4580,     0,  4096,  4608,  4609, 
+     4611,  4576,  4584,  4582,     0,  4096,  4608,  4609, 
+     4611,  4576,     0,  4096,  4608,  4609,  4611,  4576, 
+     4584,     0,  4096,  4608,  4609,  4611,  4576,  4584, 
+        0,  4096,  4608,  4609,  4611,  4576,  4584,  4586, 
+        0,  4096,  4608,  4609,  4611,  4576,  4584,     0, 
+     4096,  4608,  4609,  4611,  4576,  4592,  4588,     0, 
+     4096,  4608,  4609,  4611,  4576,  4592,  4588,     0, 
+     4096,  4608,  4609,  4611,  4576,  4592,  4593,  4590, 
+        0,  4096,  4608,  4609,  4611,  4576,     0,  4096, 
+     4608,  4609,  4611,  4576,  4592,     0,  4096,  4608, 
+     4609,  4611,  4576,  4592,     0,  4096,  4608,  4609, 
+     4611,  4576,  4592,  4594,     0,  4096,  4608,  4609, 
+     4611,  4615,  4592,     0,  4096,  4608,  4609,  4611, 
+     4615,  4592,  4596,     0,  4096,  4608,  4609,  4611, 
+     4615,  4592,  4596,     0,  4096,  4608,  4609,  4611, 
+     4615,  4592,  4600,  4598,     0,  4096,  4608,  4609, 
+     4611,  4615,  4592,     0,  4096,  4608,  4609,  4611, 
+     4615,  4592,  4600,     0,  4096,  4608,  4609,  4611, 
+     4615,  4592,  4600,     0,  4096,  4608,  4609,  4611, 
+     4615,  4592,  4600,  4602,     0,  4096,  4608,  4609, 
+     4611,  4615,  4592,  4600,     0,  4096,  4608,  4609, 
+     4611,  4615,  4592,  4600,  4604,     0,  4096,  4608, 
+     4609,  4611,  4615,  4592,  4600,  4604,     0,  4096, 
+     4608,  4609,  4611,  4615,  4592,  4600,  4604,  4606, 
+        0,  4096,     0,  4096,  4608,     0,  4096,  4608, 
+        0,  4096,  4608,  4610,     0,  4096,  4608,     0, 
+     4096,  4608,  4612,     0,  4096,  4608,  4612,     0, 
+     4096,  4608,  4616,  4614,     0,  4096,  4608,     0, 
+     4096,  4608,  4616,     0,  4096,  4608,  4616,     0, 
+     4096,  4608,  4616,  4618,     0,  4096,  4608,  4616, 
+        0,  4096,  4608,  4624,  4620,     0,  4096,  4608, 
+     4624,  4620,     0,  4096,  4608,  4624,  4625,  4622, 
+        0,  4096,  4608,     0,  4096,  4608,  4624,     0, 
+     4096,  4608,  4624,     0,  4096,  4608,  4624,  4626, 
+        0,  4096,  4608,  4624,     0,  4096,  4608,  4624, 
+     4628,     0,  4096,  4608,  4624,  4628,     0,  4096, 
+     4608,  4624,  4632,  4630,     0,  4096,  4608,  4624, 
+        0,  4096,  4608,  4640,  4632,     0,  4096,  4608, 
+     4640,  4632,     0,  4096,  4608,  4640,  4632,  4634, 
+        0,  4096,  4608,  4640,  4632,     0,  4096,  4608, 
+     4640,  4641,  4636,     0,  4096,  4608,  4640,  4641, 
+     4636,     0,  4096,  4608,  4640,  4641,  4636,  4638, 
+        0,  4096,  4608,     0,  4096,  4608,  4640,     0, 
+     4096,  4608,  4640,     0,  4096,  4608,  4640,  4642, 
+        0,  4096,  4608,  4640,     0,  4096,  4608,  4640, 
+     4644,     0,  4096,  4608,  4640,  4644,     0,  4096, 
+     4608,  4640,  4648,  4646,     0,  4096,  4608,  4640, 
+        0,  4096,  4608,  4640,  4648,     0,  4096,  4608, 
+     4640,  4648,     0,  4096,  4608,  4640,  4648,  4650, 
+        0,  4096,  4608,  4640,  4648,     0,  4096,  4608, 
+     4640,  4656,  4652,     0,  4096,  4608,  4640,  4656, 
+     4652,     0,  4096,  4608,  4640,  4656,  4657,  4654, 
+        0,  4096,  4608,  4640,     0,  4096,  4608,  4672, 
+     4656,     0,  4096,  4608,  4672,  4656,     0,  4096, 
+     4608,  4672,  4656,  4658,     0,  4096,  4608,  4672, 
+     4656,     0,  4096,  4608,  4672,  4656,  4660,     0, 
+     4096,  4608,  4672,  4656,  4660,     0,  4096,  4608, 
+     4672,  4656,  4664,  4662,     0,  4096,  4608,  4672, 
+     4656,     0,  4096,  4608,  4672,  4673,  4664,     0, 
+     4096,  4608,  4672,  4673,  4664,     0,  4096,  4608, 
+     4672,  4673,  4664,  4666,     0,  4096,  4608,  4672, 
+     4673,  4664,     0,  4096,  4608,  4672,  4673,  4664, 
+     4668,     0,  4096,  4608,  4672,  4673,  4675,  4668, 
+        0,  4096,  4608,  4672,  4673,  4675,  4668,  4670, 
+        0,  4096,  4608,     0,  4096,  4608,  4672,     0, 
+     4096,  4608,  4672,     0,  4096,  4608,  4672,  4674, 
+        0,  4096,  4608,  4672,     0,  4096,  4608,  4672, 
+     4676,     0,  4096,  4608,  4672,  4676,     0,  4096, 
+     4608,  4672,  4680,  4678,     0,  4096,  4608,  4672, 
+        0,  4096,  4608,  4672,  4680,     0,  4096,  4608, 
+     4672,  4680,     0,  4096,  4608,  4672,  4680,  4682, 
+        0,  4096,  4608,  4672,  4680,     0,  4096,  4608, 
+     4672,  4688,  4684,     0,  4096,  4608,  4672,  4688, 
+     4684,     0,  4096,  4608,  4672,  4688,  4689,  4686, 
+        0,  4096,  4608,  4672,     0,  4096,  4608,  4672, 
+     4688,     0,  4096,  4608,  4672,  4688,     0,  4096, 
+     4608,  4672,  4688,  4690,     0,  4096,  4608,  4672, 
+     4688,     0,  4096,  4608,  4672,  4688,  4692,     0, 
+     4096,  4608,  4672,  4688,  4692,     0,  4096,  4608, 
+     4672,  4688,  4696,  4694,     0,  4096,  4608,  4672, 
+     4688,     0,  4096,  4608,  4672,  4704,  4696,     0, 
+     4096,  4608,  4672,  4704,  4696,     0,  4096,  4608, 
+     4672,  4704,  4696,  4698,     0,  4096,  4608,  4672, 
+     4704,  4696,     0,  4096,  4608,  4672,  4704,  4705, 
+     4700,     0,  4096,  4608,  4672,  4704,  4705,  4700, 
+        0,  4096,  4608,  4672,  4704,  4705,  4700,  4702, 
+        0,  4096,  4608,  4672,     0,  4096,  4608,  4736, 
+     4704,     0,  4096,  4608,  4736,  4704,     0,  4096, 
+     4608,  4736,  4704,  4706,     0,  4096,  4608,  4736, 
+     4704,     0,  4096,  4608,  4736,  4704,  4708,     0, 
+     4096,  4608,  4736,  4704,  4708,     0,  4096,  4608, 
+     4736,  4704,  4712,  4710,     0,  4096,  4608,  4736, 
+     4704,     0,  4096,  4608,  4736,  4704,  4712,     0, 
+     4096,  4608,  4736,  4704,  4712,     0,  4096,  4608, 
+     4736,  4704,  4712,  4714,     0,  4096,  4608,  4736, 
+     4704,  4712,     0,  4096,  4608,  4736,  4704,  4720, 
+     4716,     0,  4096,  4608,  4736,  4704,  4720,  4716, 
+        0,  4096,  4608,  4736,  4704,  4720,  4721,  4718, 
+        0,  4096,  4608,  4736,  4704,     0,  4096,  4608, 
+     4736,  4737,  4720,     0,  4096,  4608,  4736,  4737, 
+     4720,     0,  4096,  4608,  4736,  4737,  4720,  4722, 
+        0,  4096,  4608,  4736,  4737,  4720,     0,  4096, 
+     4608,  4736,  4737,  4720,  4724,     0,  4096,  4608, 
+     4736,  4737,  4720,  4724,     0,  4096,  4608,  4736, 
+     4737,  4720,  4728,  4726,     0,  4096,  4608,  4736, 
+     4737,  4720,     0,  4096,  4608,  4736,  4737,  4720, 
+     4728,     0,  4096,  4608,  4736,  4737,  4739,  4728, 
+        0,  4096,  4608,  4736,  4737,  4739,  4728,  4730, 
+        0,  4096,  4608,  4736,  4737,  4739,  4728,     0, 
+     4096,  4608,  4736,  4737,  4739,  4728,  4732,     0, 
+     4096,  4608,  4736,  4737,  4739,  4728,  4732,     0, 
+     4096,  4608,  4736,  4737,  4739,  4728,  4732,  4734, 
+        0,  4096,  4608,     0,  4096,  4608,  4736,     0, 
+     4096,  4608,  4736,     0,  4096,  4608,  4736,  4738, 
+        0,  4096,  4608,  4736,     0,  4096,  4608,  4736, 
+     4740,     0,  4096,  4608,  4736,  4740,     0,  4096, 
+     4608,  4736,  4744,  4742,     0,  4096,  4608,  4736, 
+        0,  4096,  4608,  4736,  4744,     0,  4096,  4608, 
+     4736,  4744,     0,  4096,  4608,  4736,  4744,  4746, 
+        0,  4096,  4608,  4736,  4744,     0,  4096,  4608, 
+     4736,  4752,  4748,     0,  4096,  4608,  4736,  4752, 
+     4748,     0,  4096,  4608,  4736,  4752,  4753,  4750, 
+        0,  4096,  4608,  4736,     0,  4096,  4608,  4736, 
+     4752,     0,  4096,  4608,  4736,  4752,     0,  4096, 
+     4608,  4736,  4752,  4754,     0,  4096,  4608,  4736, 
+     4752,     0,  4096,  4608,  4736,  4752,  4756,     0, 
+     4096,  4608,  4736,  4752,  4756,     0,  4096,  4608, 
+     4736,  4752,  4760,  4758,     0,  4096,  4608,  4736, 
+     4752,     0,  4096,  4608,  4736,  4768,  4760,     0, 
+     4096,  4608,  4736,  4768,  4760,     0,  4096,  4608, 
+     4736,  4768,  4760,  4762,     0,  4096,  4608,  4736, 
+     4768,  4760,     0,  4096,  4608,  4736,  4768,  4769, 
+     4764,     0,  4096,  4608,  4736,  4768,  4769,  4764, 
+        0,  4096,  4608,  4736,  4768,  4769,  4764,  4766, 
+        0,  4096,  4608,  4736,     0,  4096,  4608,  4736, 
+     4768,     0,  4096,  4608,  4736,  4768,     0,  4096, 
+     4608,  4736,  4768,  4770,     0,  4096,  4608,  4736, 
+     4768,     0,  4096,  4608,  4736,  4768,  4772,     0, 
+     4096,  4608,  4736,  4768,  4772,     0,  4096,  4608, 
+     4736,  4768,  4776,  4774,     0,  4096,  4608,  4736, 
+     4768,     0,  4096,  4608,  4736,  4768,  4776,     0, 
+     4096,  4608,  4736,  4768,  4776,     0,  4096,  4608, 
+     4736,  4768,  4776,  4778,     0,  4096,  4608,  4736, 
+     4768,  4776,     0,  4096,  4608,  4736,  4768,  4784, 
+     4780,     0,  4096,  4608,  4736,  4768,  4784,  4780, 
+        0,  4096,  4608,  4736,  4768,  4784,  4785,  4782, 
+        0,  4096,  4608,  4736,  4768,     0,  4096,  4608, 
+     4736,  4800,  4784,     0,  4096,  4608,  4736,  4800, 
+     4784,     0,  4096,  4608,  4736,  4800,  4784,  4786, 
+        0,  4096,  4608,  4736,  4800,  4784,     0,  4096, 
+     4608,  4736,  4800,  4784,  4788,     0,  4096,  4608, 
+     4736,  4800,  4784,  4788,     0,  4096,  4608,  4736, 
+     4800,  4784,  4792,  4790,     0,  4096,  4608,  4736, 
+     4800,  4784,     0,  4096,  4608,  4736,  4800,  4801, 
+     4792,     0,  4096,  4608,  4736,  4800,  4801,  4792, 
+        0,  4096,  4608,  4736,  4800,  4801,  4792,  4794, 
+        0,  4096,  4608,  4736,  4800,  4801,  4792,     0, 
+     4096,  4608,  4736,  4800,  4801,  4792,  4796,     0, 
+     4096,  4608,  4736,  4800,  4801,  4803,  4796,     0, 
+     4096,  4608,  4736,  4800,  4801,  4803,  4796,  4798, 
+        0,  4096,  4608,  4736,     0,  4096,  4608,  4864, 
+     4800,     0,  4096,  4608,  4864,  4800,     0,  4096, 
+     4608,  4864,  4800,  4802,     0,  4096,  4608,  4864, 
+     4800,     0,  4096,  4608,  4864,  4800,  4804,     0, 
+     4096,  4608,  4864,  4800,  4804,     0,  4096,  4608, 
+     4864,  4800,  4808,  4806,     0,  4096,  4608,  4864, 
+     4800,     0,  4096,  4608,  4864,  4800,  4808,     0, 
+     4096,  4608,  4864,  4800,  4808,     0,  4096,  4608, 
+     4864,  4800,  4808,  4810,     0,  4096,  4608,  4864, 
+     4800,  4808,     0,  4096,  4608,  4864,  4800,  4816, 
+     4812,     0,  4096,  4608,  4864,  4800,  4816,  4812, 
+        0,  4096,  4608,  4864,  4800,  4816,  4817,  4814, 
+        0,  4096,  4608,  4864,  4800,     0,  4096,  4608, 
+     4864,  4800,  4816,     0,  4096,  4608,  4864,  4800, 
+     4816,     0,  4096,  4608,  4864,  4800,  4816,  4818, 
+        0,  4096,  4608,  4864,  4800,  4816,     0,  4096, 
+     4608,  4864,  4800,  4816,  4820,     0,  4096,  4608, 
+     4864,  4800,  4816,  4820,     0,  4096,  4608,  4864, 
+     4800,  4816,  4824,  4822,     0,  4096,  4608,  4864, 
+     4800,  4816,     0,  4096,  4608,  4864,  4800,  4832, 
+     4824,     0,  4096,  4608,  4864,  4800,  4832,  4824, 
+        0,  4096,  4608,  4864,  4800,  4832,  4824,  4826, 
+        0,  4096,  4608,  4864,  4800,  4832,  4824,     0, 
+     4096,  4608,  4864,  4800,  4832,  4833,  4828,     0, 
+     4096,  4608,  4864,  4800,  4832,  4833,  4828,     0, 
+     4096,  4608,  4864,  4800,  4832,  4833,  4828,  4830, 
+        0,  4096,  4608,  4864,  4800,     0,  4096,  4608, 
+     4864,  4865,  4832,     0,  4096,  4608,  4864,  4865, 
+     4832,     0,  4096,  4608,  4864,  4865,  4832,  4834, 
+        0,  4096,  4608,  4864,  4865,  4832,     0,  4096, 
+     4608,  4864,  4865,  4832,  4836,     0,  4096,  4608, 
+     4864,  4865,  4832,  4836,     0,  4096,  4608,  4864, 
+     4865,  4832,  4840,  4838,     0,  4096,  4608,  4864, 
+     4865,  4832,     0,  4096,  4608,  4864,  4865,  4832, 
+     4840,     0,  4096,  4608,  4864,  4865,  4832,  4840, 
+        0,  4096,  4608,  4864,  4865,  4832,  4840,  4842, 
+        0,  4096,  4608,  4864,  4865,  4832,  4840,     0, 
+     4096,  4608,  4864,  4865,  4832,  4848,  4844,     0, 
+     4096,  4608,  4864,  4865,  4832,  4848,  4844,     0, 
+     4096,  4608,  4864,  4865,  4832,  4848,  4849,  4846, 
+        0,  4096,  4608,  4864,  4865,  4832,     0,  4096, 
+     4608,  4864,  4865,  4832,  4848,     0,  4096,  4608, 
+     4864,  4865,  4867,  4848,     0,  4096,  4608,  4864, 
+     4865,  4867,  4848,  4850,     0,  4096,  4608,  4864, 
+     4865,  4867,  4848,     0,  4096,  4608,  4864,  4865, 
+     4867,  4848,  4852,     0,  4096,  4608,  4864,  4865, 
+     4867,  4848,  4852,     0,  4096,  4608,  4864,  4865, 
+     4867,  4848,  4856,  4854,     0,  4096,  4608,  4864, 
+     4865,  4867,  4848,     0,  4096,  4608,  4864,  4865, 
+     4867,  4848,  4856,     0,  4096,  4608,  4864,  4865, 
+     4867,  4848,  4856,     0,  4096,  4608,  4864,  4865, 
+     4867,  4848,  4856,  4858,     0,  4096,  4608,  4864, 
+     4865,  4867,  4871,  4856,     0,  4096,  4608,  4864, 
+     4865,  4867,  4871,  4856,  4860,     0,  4096,  4608, 
+     4864,  4865,  4867,  4871,  4856,  4860,     0,  4096, 
+     4608,  4864,  4865,  4867,  4871,  4856,  4860,  4862, 
+        0,  4096,  4608,     0,  4096,  5120,  4864,     0, 
+     4096,  5120,  4864,     0,  4096,  5120,  4864,  4866, 
+        0,  4096,  5120,  4864,     0,  4096,  5120,  4864, 
+     4868,     0,  4096,  5120,  4864,  4868,     0,  4096, 
+     5120,  4864,  4872,  4870,     0,  4096,  5120,  4864, 
+        0,  4096,  5120,  4864,  4872,     0,  4096,  5120, 
+     4864,  4872,     0,  4096,  5120,  4864,  4872,  4874, 
+        0,  4096,  5120,  4864,  4872,     0,  4096,  5120, 
+     4864,  4880,  4876,     0,  4096,  5120,  4864,  4880, 
+     4876,     0,  4096,  5120,  4864,  4880,  4881,  4878, 
+        0,  4096,  5120,  4864,     0,  4096,  5120,  4864, 
+     4880,     0,  4096,  5120,  4864,  4880,     0,  4096, 
+     5120,  4864,  4880,  4882,     0,  4096,  5120,  4864, 
+     4880,     0,  4096,  5120,  4864,  4880,  4884,     0, 
+     4096,  5120,  4864,  4880,  4884,     0,  4096,  5120, 
+     4864,  4880,  4888,  4886,     0,  4096,  5120,  4864, 
+     4880,     0,  4096,  5120,  4864,  4896,  4888,     0, 
+     4096,  5120,  4864,  4896,  4888,     0,  4096,  5120, 
+     4864,  4896,  4888,  4890,     0,  4096,  5120,  4864, 
+     4896,  4888,     0,  4096,  5120,  4864,  4896,  4897, 
+     4892,     0,  4096,  5120,  4864,  4896,  4897,  4892, 
+        0,  4096,  5120,  4864,  4896,  4897,  4892,  4894, 
+        0,  4096,  5120,  4864,     0,  4096,  5120,  4864, 
+     4896,     0,  4096,  5120,  4864,  4896,     0,  4096, 
+     5120,  4864,  4896,  4898,     0,  4096,  5120,  4864, 
+     4896,     0,  4096,  5120,  4864,  4896,  4900,     0, 
+     4096,  5120,  4864,  4896,  4900,     0,  4096,  5120, 
+     4864,  4896,  4904,  4902,     0,  4096,  5120,  4864, 
+     4896,     0,  4096,  5120,  4864,  4896,  4904,     0, 
+     4096,  5120,  4864,  4896,  4904,     0,  4096,  5120, 
+     4864,  4896,  4904,  4906,     0,  4096,  5120,  4864, 
+     4896,  4904,     0,  4096,  5120,  4864,  4896,  4912, 
+     4908,     0,  4096,  5120,  4864,  4896,  4912,  4908, 
+        0,  4096,  5120,  4864,  4896,  4912,  4913,  4910, 
+        0,  4096,  5120,  4864,  4896,     0,  4096,  5120, 
+     4864,  4928,  4912,     0,  4096,  5120,  4864,  4928, 
+     4912,     0,  4096,  5120,  4864,  4928,  4912,  4914, 
+        0,  4096,  5120,  4864,  4928,  4912,     0,  4096, 
+     5120,  4864,  4928,  4912,  4916,     0,  4096,  5120, 
+     4864,  4928,  4912,  4916,     0,  4096,  5120,  4864, 
+     4928,  4912,  4920,  4918,     0,  4096,  5120,  4864, 
+     4928,  4912,     0,  4096,  5120,  4864,  4928,  4929, 
+     4920,     0,  4096,  5120,  4864,  4928,  4929,  4920, 
+        0,  4096,  5120,  4864,  4928,  4929,  4920,  4922, 
+        0,  4096,  5120,  4864,  4928,  4929,  4920,     0, 
+     4096,  5120,  4864,  4928,  4929,  4920,  4924,     0, 
+     4096,  5120,  4864,  4928,  4929,  4931,  4924,     0, 
+     4096,  5120,  4864,  4928,  4929,  4931,  4924,  4926, 
+        0,  4096,  5120,  4864,     0,  4096,  5120,  4864, 
+     4928,     0,  4096,  5120,  4864,  4928,     0,  4096, 
+     5120,  4864,  4928,  4930,     0,  4096,  5120,  4864, 
+     4928,     0,  4096,  5120,  4864,  4928,  4932,     0, 
+     4096,  5120,  4864,  4928,  4932,     0,  4096,  5120, 
+     4864,  4928,  4936,  4934,     0,  4096,  5120,  4864, 
+     4928,     0,  4096,  5120,  4864,  4928,  4936,     0, 
+     4096,  5120,  4864,  4928,  4936,     0,  4096,  5120, 
+     4864,  4928,  4936,  4938,     0,  4096,  5120,  4864, 
+     4928,  4936,     0,  4096,  5120,  4864,  4928,  4944, 
+     4940,     0,  4096,  5120,  4864,  4928,  4944,  4940, 
+        0,  4096,  5120,  4864,  4928,  4944,  4945,  4942, 
+        0,  4096,  5120,  4864,  4928,     0,  4096,  5120, 
+     4864,  4928,  4944,     0,  4096,  5120,  4864,  4928, 
+     4944,     0,  4096,  5120,  4864,  4928,  4944,  4946, 
+        0,  4096,  5120,  4864,  4928,  4944,     0,  4096, 
+     5120,  4864,  4928,  4944,  4948,     0,  4096,  5120, 
+     4864,  4928,  4944,  4948,     0,  4096,  5120,  4864, 
+     4928,  4944,  4952,  4950,     0,  4096,  5120,  4864, 
+     4928,  4944,     0,  4096,  5120,  4864,  4928,  4960, 
+     4952,     0,  4096,  5120,  4864,  4928,  4960,  4952, 
+        0,  4096,  5120,  4864,  4928,  4960,  4952,  4954, 
+        0,  4096,  5120,  4864,  4928,  4960,  4952,     0, 
+     4096,  5120,  4864,  4928,  4960,  4961,  4956,     0, 
+     4096,  5120,  4864,  4928,  4960,  4961,  4956,     0, 
+     4096,  5120,  4864,  4928,  4960,  4961,  4956,  4958, 
+        0,  4096,  5120,  4864,  4928,     0,  4096,  5120, 
+     4864,  4992,  4960,     0,  4096,  5120,  4864,  4992, 
+     4960,     0,  4096,  5120,  4864,  4992,  4960,  4962, 
+        0,  4096,  5120,  4864,  4992,  4960,     0,  4096, 
+     5120,  4864,  4992,  4960,  4964,     0,  4096,  5120, 
+     4864,  4992,  4960,  4964,     0,  4096,  5120,  4864, 
+     4992,  4960,  4968,  4966,     0,  4096,  5120,  4864, 
+     4992,  4960,     0,  4096,  5120,  4864,  4992,  4960, 
+     4968,     0,  4096,  5120,  4864,  4992,  4960,  4968, 
+        0,  4096,  5120,  4864,  4992,  4960,  4968,  4970, 
+        0,  4096,  5120,  4864,  4992,  4960,  4968,     0, 
+     4096,  5120,  4864,  4992,  4960,  4976,  4972,     0, 
+     4096,  5120,  4864,  4992,  4960,  4976,  4972,     0, 
+     4096,  5120,  4864,  4992,  4960,  4976,  4977,  4974, 
+        0,  4096,  5120,  4864,  4992,  4960,     0,  4096, 
+     5120,  4864,  4992,  4993,  4976,     0,  4096,  5120, 
+     4864,  4992,  4993,  4976,     0,  4096,  5120,  4864, 
+     4992,  4993,  4976,  4978,     0,  4096,  5120,  4864, 
+     4992,  4993,  4976,     0,  4096,  5120,  4864,  4992, 
+     4993,  4976,  4980,     0,  4096,  5120,  4864,  4992, 
+     4993,  4976,  4980,     0,  4096,  5120,  4864,  4992, 
+     4993,  4976,  4984,  4982,     0,  4096,  5120,  4864, 
+     4992,  4993,  4976,     0,  4096,  5120,  4864,  4992, 
+     4993,  4976,  4984,     0,  4096,  5120,  4864,  4992, 
+     4993,  4995,  4984,     0,  4096,  5120,  4864,  4992, 
+     4993,  4995,  4984,  4986,     0,  4096,  5120,  4864, 
+     4992,  4993,  4995,  4984,     0,  4096,  5120,  4864, 
+     4992,  4993,  4995,  4984,  4988,     0,  4096,  5120, 
+     4864,  4992,  4993,  4995,  4984,  4988,     0,  4096, 
+     5120,  4864,  4992,  4993,  4995,  4984,  4988,  4990, 
+        0,  4096,  5120,  4864,     0,  4096,  5120,  4864, 
+     4992,     0,  4096,  5120,  5121,  4992,     0,  4096, 
+     5120,  5121,  4992,  4994,     0,  4096,  5120,  5121, 
+     4992,     0,  4096,  5120,  5121,  4992,  4996,     0, 
+     4096,  5120,  5121,  4992,  4996,     0,  4096,  5120, 
+     5121,  4992,  5000,  4998,     0,  4096,  5120,  5121, 
+     4992,     0,  4096,  5120,  5121,  4992,  5000,     0, 
+     4096,  5120,  5121,  4992,  5000,     0,  4096,  5120, 
+     5121,  4992,  5000,  5002,     0,  4096,  5120,  5121, 
+     4992,  5000,     0,  4096,  5120,  5121,  4992,  5008, 
+     5004,     0,  4096,  5120,  5121,  4992,  5008,  5004, 
+        0,  4096,  5120,  5121,  4992,  5008,  5009,  5006, 
+        0,  4096,  5120,  5121,  4992,     0,  4096,  5120, 
+     5121,  4992,  5008,     0,  4096,  5120,  5121,  4992, 
+     5008,     0,  4096,  5120,  5121,  4992,  5008,  5010, 
+        0,  4096,  5120,  5121,  4992,  5008,     0,  4096, 
+     5120,  5121,  4992,  5008,  5012,     0,  4096,  5120, 
+     5121,  4992,  5008,  5012,     0,  4096,  5120,  5121, 
+     4992,  5008,  5016,  5014,     0,  4096,  5120,  5121, 
+     4992,  5008,     0,  4096,  5120,  5121,  4992,  5024, 
+     5016,     0,  4096,  5120,  5121,  4992,  5024,  5016, 
+        0,  4096,  5120,  5121,  4992,  5024,  5016,  5018, 
+        0,  4096,  5120,  5121,  4992,  5024,  5016,     0, 
+     4096,  5120,  5121,  4992,  5024,  5025,  5020,     0, 
+     4096,  5120,  5121,  4992,  5024,  5025,  5020,     0, 
+     4096,  5120,  5121,  4992,  5024,  5025,  5020,  5022, 
+        0,  4096,  5120,  5121,  4992,     0,  4096,  5120, 
+     5121,  4992,  5024,     0,  4096,  5120,  5121,  4992, 
+     5024,     0,  4096,  5120,  5121,  4992,  5024,  5026, 
+        0,  4096,  5120,  5121,  4992,  5024,     0,  4096, 
+     5120,  5121,  4992,  5024,  5028,     0,  4096,  5120, 
+     5121,  4992,  5024,  5028,     0,  4096,  5120,  5121, 
+     4992,  5024,  5032,  5030,     0,  4096,  5120,  5121, 
+     4992,  5024,     0,  4096,  5120,  5121,  4992,  5024, 
+     5032,     0,  4096,  5120,  5121,  4992,  5024,  5032, 
+        0,  4096,  5120,  5121,  4992,  5024,  5032,  5034, 
+        0,  4096,  5120,  5121,  4992,  5024,  5032,     0, 
+     4096,  5120,  5121,  4992,  5024,  5040,  5036,     0, 
+     4096,  5120,  5121,  4992,  5024,  5040,  5036,     0, 
+     4096,  5120,  5121,  4992,  5024,  5040,  5041,  5038, 
+        0,  4096,  5120,  5121,  4992,  5024,     0,  4096, 
+     5120,  5121,  4992,  5056,  5040,     0,  4096,  5120, 
+     5121,  4992,  5056,  5040,     0,  4096,  5120,  5121, 
+     4992,  5056,  5040,  5042,     0,  4096,  5120,  5121, 
+     4992,  5056,  5040,     0,  4096,  5120,  5121,  4992, 
+     5056,  5040,  5044,     0,  4096,  5120,  5121,  4992, 
+     5056,  5040,  5044,     0,  4096,  5120,  5121,  4992, 
+     5056,  5040,  5048,  5046,     0,  4096,  5120,  5121, 
+     4992,  5056,  5040,     0,  4096,  5120,  5121,  4992, 
+     5056,  5057,  5048,     0,  4096,  5120,  5121,  4992, 
+     5056,  5057,  5048,     0,  4096,  5120,  5121,  4992, 
+     5056,  5057,  5048,  5050,     0,  4096,  5120,  5121, 
+     4992,  5056,  5057,  5048,     0,  4096,  5120,  5121, 
+     4992,  5056,  5057,  5048,  5052,     0,  4096,  5120, 
+     5121,  4992,  5056,  5057,  5059,  5052,     0,  4096, 
+     5120,  5121,  4992,  5056,  5057,  5059,  5052,  5054, 
+        0,  4096,  5120,  5121,  4992,     0,  4096,  5120, 
+     5121,  4992,  5056,     0,  4096,  5120,  5121,  4992, 
+     5056,     0,  4096,  5120,  5121,  4992,  5056,  5058, 
+        0,  4096,  5120,  5121,  5123,  5056,     0,  4096, 
+     5120,  5121,  5123,  5056,  5060,     0,  4096,  5120, 
+     5121,  5123,  5056,  5060,     0,  4096,  5120,  5121, 
+     5123,  5056,  5064,  5062,     0,  4096,  5120,  5121, 
+     5123,  5056,     0,  4096,  5120,  5121,  5123,  5056, 
+     5064,     0,  4096,  5120,  5121,  5123,  5056,  5064, 
+        0,  4096,  5120,  5121,  5123,  5056,  5064,  5066, 
+        0,  4096,  5120,  5121,  5123,  5056,  5064,     0, 
+     4096,  5120,  5121,  5123,  5056,  5072,  5068,     0, 
+     4096,  5120,  5121,  5123,  5056,  5072,  5068,     0, 
+     4096,  5120,  5121,  5123,  5056,  5072,  5073,  5070, 
+        0,  4096,  5120,  5121,  5123,  5056,     0,  4096, 
+     5120,  5121,  5123,  5056,  5072,     0,  4096,  5120, 
+     5121,  5123,  5056,  5072,     0,  4096,  5120,  5121, 
+     5123,  5056,  5072,  5074,     0,  4096,  5120,  5121, 
+     5123,  5056,  5072,     0,  4096,  5120,  5121,  5123, 
+     5056,  5072,  5076,     0,  4096,  5120,  5121,  5123, 
+     5056,  5072,  5076,     0,  4096,  5120,  5121,  5123, 
+     5056,  5072,  5080,  5078,     0,  4096,  5120,  5121, 
+     5123,  5056,  5072,     0,  4096,  5120,  5121,  5123, 
+     5056,  5088,  5080,     0,  4096,  5120,  5121,  5123, 
+     5056,  5088,  5080,     0,  4096,  5120,  5121,  5123, 
+     5056,  5088,  5080,  5082,     0,  4096,  5120,  5121, 
+     5123,  5056,  5088,  5080,     0,  4096,  5120,  5121, 
+     5123,  5056,  5088,  5089,  5084,     0,  4096,  5120, 
+     5121,  5123,  5056,  5088,  5089,  5084,     0,  4096, 
+     5120,  5121,  5123,  5056,  5088,  5089,  5084,  5086, 
+        0,  4096,  5120,  5121,  5123,  5056,     0,  4096, 
+     5120,  5121,  5123,  5056,  5088,     0,  4096,  5120, 
+     5121,  5123,  5056,  5088,     0,  4096,  5120,  5121, 
+     5123,  5056,  5088,  5090,     0,  4096,  5120,  5121, 
+     5123,  5056,  5088,     0,  4096,  5120,  5121,  5123, 
+     5056,  5088,  5092,     0,  4096,  5120,  5121,  5123, 
+     5056,  5088,  5092,     0,  4096,  5120,  5121,  5123, 
+     5056,  5088,  5096,  5094,     0,  4096,  5120,  5121, 
+     5123,  5127,  5088,     0,  4096,  5120,  5121,  5123, 
+     5127,  5088,  5096,     0,  4096,  5120,  5121,  5123, 
+     5127,  5088,  5096,     0,  4096,  5120,  5121,  5123, 
+     5127,  5088,  5096,  5098,     0,  4096,  5120,  5121, 
+     5123,  5127,  5088,  5096,     0,  4096,  5120,  5121, 
+     5123,  5127,  5088,  5104,  5100,     0,  4096,  5120, 
+     5121,  5123,  5127,  5088,  5104,  5100,     0,  4096, 
+     5120,  5121,  5123,  5127,  5088,  5104,  5105,  5102, 
+        0,  4096,  5120,  5121,  5123,  5127,  5088,     0, 
+     4096,  5120,  5121,  5123,  5127,  5088,  5104,     0, 
+     4096,  5120,  5121,  5123,  5127,  5088,  5104,     0, 
+     4096,  5120,  5121,  5123,  5127,  5088,  5104,  5106, 
+        0,  4096,  5120,  5121,  5123,  5127,  5088,  5104, 
+        0,  4096,  5120,  5121,  5123,  5127,  5088,  5104, 
+     5108,     0,  4096,  5120,  5121,  5123,  5127,  5088, 
+     5104,  5108,     0,  4096,  5120,  5121,  5123,  5127, 
+     5088,  5104,  5112,  5110,     0,  4096,  5120,  5121, 
+     5123,  5127,  5088,  5104,     0,  4096,  5120,  5121, 
+     5123,  5127,  5088,  5104,  5112,     0,  4096,  5120, 
+     5121,  5123,  5127,  5088,  5104,  5112,     0,  4096, 
+     5120,  5121,  5123,  5127,  5088,  5104,  5112,  5114, 
+        0,  4096,  5120,  5121,  5123,  5127,  5088,  5104, 
+     5112,     0,  4096,  5120,  5121,  5123,  5127,  5088, 
+     5104,  5112,  5116,     0,  4096,  5120,  5121,  5123, 
+     5127,  5088,  5104,  5112,  5116,     0,  4096,  5120, 
+     5121,  5123,  5127,  5088,  5104,  5112,  5116,  5118, 
+        0,  4096,     0,  4096,  5120,     0,  4096,  5120, 
+        0,  4096,  5120,  5122,     0,  4096,  5120,     0, 
+     4096,  5120,  5124,     0,  4096,  5120,  5124,     0, 
+     4096,  5120,  5128,  5126,     0,  4096,  5120,     0, 
+     4096,  5120,  5128,     0,  4096,  5120,  5128,     0, 
+     4096,  5120,  5128,  5130,     0,  4096,  5120,  5128, 
+        0,  4096,  5120,  5136,  5132,     0,  4096,  5120, 
+     5136,  5132,     0,  4096,  5120,  5136,  5137,  5134, 
+        0,  4096,  5120,     0,  4096,  5120,  5136,     0, 
+     4096,  5120,  5136,     0,  4096,  5120,  5136,  5138, 
+        0,  4096,  5120,  5136,     0,  4096,  5120,  5136, 
+     5140,     0,  4096,  5120,  5136,  5140,     0,  4096, 
+     5120,  5136,  5144,  5142,     0,  4096,  5120,  5136, 
+        0,  4096,  5120,  5152,  5144,     0,  4096,  5120, 
+     5152,  5144,     0,  4096,  5120,  5152,  5144,  5146, 
+        0,  4096,  5120,  5152,  5144,     0,  4096,  5120, 
+     5152,  5153,  5148,     0,  4096,  5120,  5152,  5153, 
+     5148,     0,  4096,  5120,  5152,  5153,  5148,  5150, 
+        0,  4096,  5120,     0,  4096,  5120,  5152,     0, 
+     4096,  5120,  5152,     0,  4096,  5120,  5152,  5154, 
+        0,  4096,  5120,  5152,     0,  4096,  5120,  5152, 
+     5156,     0,  4096,  5120,  5152,  5156,     0,  4096, 
+     5120,  5152,  5160,  5158,     0,  4096,  5120,  5152, 
+        0,  4096,  5120,  5152,  5160,     0,  4096,  5120, 
+     5152,  5160,     0,  4096,  5120,  5152,  5160,  5162, 
+        0,  4096,  5120,  5152,  5160,     0,  4096,  5120, 
+     5152,  5168,  5164,     0,  4096,  5120,  5152,  5168, 
+     5164,     0,  4096,  5120,  5152,  5168,  5169,  5166, 
+        0,  4096,  5120,  5152,     0,  4096,  5120,  5184, 
+     5168,     0,  4096,  5120,  5184,  5168,     0,  4096, 
+     5120,  5184,  5168,  5170,     0,  4096,  5120,  5184, 
+     5168,     0,  4096,  5120,  5184,  5168,  5172,     0, 
+     4096,  5120,  5184,  5168,  5172,     0,  4096,  5120, 
+     5184,  5168,  5176,  5174,     0,  4096,  5120,  5184, 
+     5168,     0,  4096,  5120,  5184,  5185,  5176,     0, 
+     4096,  5120,  5184,  5185,  5176,     0,  4096,  5120, 
+     5184,  5185,  5176,  5178,     0,  4096,  5120,  5184, 
+     5185,  5176,     0,  4096,  5120,  5184,  5185,  5176, 
+     5180,     0,  4096,  5120,  5184,  5185,  5187,  5180, 
+        0,  4096,  5120,  5184,  5185,  5187,  5180,  5182, 
+        0,  4096,  5120,     0,  4096,  5120,  5184,     0, 
+     4096,  5120,  5184,     0,  4096,  5120,  5184,  5186, 
+        0,  4096,  5120,  5184,     0,  4096,  5120,  5184, 
+     5188,     0,  4096,  5120,  5184,  5188,     0,  4096, 
+     5120,  5184,  5192,  5190,     0,  4096,  5120,  5184, 
+        0,  4096,  5120,  5184,  5192,     0,  4096,  5120, 
+     5184,  5192,     0,  4096,  5120,  5184,  5192,  5194, 
+        0,  4096,  5120,  5184,  5192,     0,  4096,  5120, 
+     5184,  5200,  5196,     0,  4096,  5120,  5184,  5200, 
+     5196,     0,  4096,  5120,  5184,  5200,  5201,  5198, 
+        0,  4096,  5120,  5184,     0,  4096,  5120,  5184, 
+     5200,     0,  4096,  5120,  5184,  5200,     0,  4096, 
+     5120,  5184,  5200,  5202,     0,  4096,  5120,  5184, 
+     5200,     0,  4096,  5120,  5184,  5200,  5204,     0, 
+     4096,  5120,  5184,  5200,  5204,     0,  4096,  5120, 
+     5184,  5200,  5208,  5206,     0,  4096,  5120,  5184, 
+     5200,     0,  4096,  5120,  5184,  5216,  5208,     0, 
+     4096,  5120,  5184,  5216,  5208,     0,  4096,  5120, 
+     5184,  5216,  5208,  5210,     0,  4096,  5120,  5184, 
+     5216,  5208,     0,  4096,  5120,  5184,  5216,  5217, 
+     5212,     0,  4096,  5120,  5184,  5216,  5217,  5212, 
+        0,  4096,  5120,  5184,  5216,  5217,  5212,  5214, 
+        0,  4096,  5120,  5184,     0,  4096,  5120,  5248, 
+     5216,     0,  4096,  5120,  5248,  5216,     0,  4096, 
+     5120,  5248,  5216,  5218,     0,  4096,  5120,  5248, 
+     5216,     0,  4096,  5120,  5248,  5216,  5220,     0, 
+     4096,  5120,  5248,  5216,  5220,     0,  4096,  5120, 
+     5248,  5216,  5224,  5222,     0,  4096,  5120,  5248, 
+     5216,     0,  4096,  5120,  5248,  5216,  5224,     0, 
+     4096,  5120,  5248,  5216,  5224,     0,  4096,  5120, 
+     5248,  5216,  5224,  5226,     0,  4096,  5120,  5248, 
+     5216,  5224,     0,  4096,  5120,  5248,  5216,  5232, 
+     5228,     0,  4096,  5120,  5248,  5216,  5232,  5228, 
+        0,  4096,  5120,  5248,  5216,  5232,  5233,  5230, 
+        0,  4096,  5120,  5248,  5216,     0,  4096,  5120, 
+     5248,  5249,  5232,     0,  4096,  5120,  5248,  5249, 
+     5232,     0,  4096,  5120,  5248,  5249,  5232,  5234, 
+        0,  4096,  5120,  5248,  5249,  5232,     0,  4096, 
+     5120,  5248,  5249,  5232,  5236,     0,  4096,  5120, 
+     5248,  5249,  5232,  5236,     0,  4096,  5120,  5248, 
+     5249,  5232,  5240,  5238,     0,  4096,  5120,  5248, 
+     5249,  5232,     0,  4096,  5120,  5248,  5249,  5232, 
+     5240,     0,  4096,  5120,  5248,  5249,  5251,  5240, 
+        0,  4096,  5120,  5248,  5249,  5251,  5240,  5242, 
+        0,  4096,  5120,  5248,  5249,  5251,  5240,     0, 
+     4096,  5120,  5248,  5249,  5251,  5240,  5244,     0, 
+     4096,  5120,  5248,  5249,  5251,  5240,  5244,     0, 
+     4096,  5120,  5248,  5249,  5251,  5240,  5244,  5246, 
+        0,  4096,  5120,     0,  4096,  5120,  5248,     0, 
+     4096,  5120,  5248,     0,  4096,  5120,  5248,  5250, 
+        0,  4096,  5120,  5248,     0,  4096,  5120,  5248, 
+     5252,     0,  4096,  5120,  5248,  5252,     0,  4096, 
+     5120,  5248,  5256,  5254,     0,  4096,  5120,  5248, 
+        0,  4096,  5120,  5248,  5256,     0,  4096,  5120, 
+     5248,  5256,     0,  4096,  5120,  5248,  5256,  5258, 
+        0,  4096,  5120,  5248,  5256,     0,  4096,  5120, 
+     5248,  5264,  5260,     0,  4096,  5120,  5248,  5264, 
+     5260,     0,  4096,  5120,  5248,  5264,  5265,  5262, 
+        0,  4096,  5120,  5248,     0,  4096,  5120,  5248, 
+     5264,     0,  4096,  5120,  5248,  5264,     0,  4096, 
+     5120,  5248,  5264,  5266,     0,  4096,  5120,  5248, 
+     5264,     0,  4096,  5120,  5248,  5264,  5268,     0, 
+     4096,  5120,  5248,  5264,  5268,     0,  4096,  5120, 
+     5248,  5264,  5272,  5270,     0,  4096,  5120,  5248, 
+     5264,     0,  4096,  5120,  5248,  5280,  5272,     0, 
+     4096,  5120,  5248,  5280,  5272,     0,  4096,  5120, 
+     5248,  5280,  5272,  5274,     0,  4096,  5120,  5248, 
+     5280,  5272,     0,  4096,  5120,  5248,  5280,  5281, 
+     5276,     0,  4096,  5120,  5248,  5280,  5281,  5276, 
+        0,  4096,  5120,  5248,  5280,  5281,  5276,  5278, 
+        0,  4096,  5120,  5248,     0,  4096,  5120,  5248, 
+     5280,     0,  4096,  5120,  5248,  5280,     0,  4096, 
+     5120,  5248,  5280,  5282,     0,  4096,  5120,  5248, 
+     5280,     0,  4096,  5120,  5248,  5280,  5284,     0, 
+     4096,  5120,  5248,  5280,  5284,     0,  4096,  5120, 
+     5248,  5280,  5288,  5286,     0,  4096,  5120,  5248, 
+     5280,     0,  4096,  5120,  5248,  5280,  5288,     0, 
+     4096,  5120,  5248,  5280,  5288,     0,  4096,  5120, 
+     5248,  5280,  5288,  5290,     0,  4096,  5120,  5248, 
+     5280,  5288,     0,  4096,  5120,  5248,  5280,  5296, 
+     5292,     0,  4096,  5120,  5248,  5280,  5296,  5292, 
+        0,  4096,  5120,  5248,  5280,  5296,  5297,  5294, 
+        0,  4096,  5120,  5248,  5280,     0,  4096,  5120, 
+     5248,  5312,  5296,     0,  4096,  5120,  5248,  5312, 
+     5296,     0,  4096,  5120,  5248,  5312,  5296,  5298, 
+        0,  4096,  5120,  5248,  5312,  5296,     0,  4096, 
+     5120,  5248,  5312,  5296,  5300,     0,  4096,  5120, 
+     5248,  5312,  5296,  5300,     0,  4096,  5120,  5248, 
+     5312,  5296,  5304,  5302,     0,  4096,  5120,  5248, 
+     5312,  5296,     0,  4096,  5120,  5248,  5312,  5313, 
+     5304,     0,  4096,  5120,  5248,  5312,  5313,  5304, 
+        0,  4096,  5120,  5248,  5312,  5313,  5304,  5306, 
+        0,  4096,  5120,  5248,  5312,  5313,  5304,     0, 
+     4096,  5120,  5248,  5312,  5313,  5304,  5308,     0, 
+     4096,  5120,  5248,  5312,  5313,  5315,  5308,     0, 
+     4096,  5120,  5248,  5312,  5313,  5315,  5308,  5310, 
+        0,  4096,  5120,  5248,     0,  4096,  5120,  5376, 
+     5312,     0,  4096,  5120,  5376,  5312,     0,  4096, 
+     5120,  5376,  5312,  5314,     0,  4096,  5120,  5376, 
+     5312,     0,  4096,  5120,  5376,  5312,  5316,     0, 
+     4096,  5120,  5376,  5312,  5316,     0,  4096,  5120, 
+     5376,  5312,  5320,  5318,     0,  4096,  5120,  5376, 
+     5312,     0,  4096,  5120,  5376,  5312,  5320,     0, 
+     4096,  5120,  5376,  5312,  5320,     0,  4096,  5120, 
+     5376,  5312,  5320,  5322,     0,  4096,  5120,  5376, 
+     5312,  5320,     0,  4096,  5120,  5376,  5312,  5328, 
+     5324,     0,  4096,  5120,  5376,  5312,  5328,  5324, 
+        0,  4096,  5120,  5376,  5312,  5328,  5329,  5326, 
+        0,  4096,  5120,  5376,  5312,     0,  4096,  5120, 
+     5376,  5312,  5328,     0,  4096,  5120,  5376,  5312, 
+     5328,     0,  4096,  5120,  5376,  5312,  5328,  5330, 
+        0,  4096,  5120,  5376,  5312,  5328,     0,  4096, 
+     5120,  5376,  5312,  5328,  5332,     0,  4096,  5120, 
+     5376,  5312,  5328,  5332,     0,  4096,  5120,  5376, 
+     5312,  5328,  5336,  5334,     0,  4096,  5120,  5376, 
+     5312,  5328,     0,  4096,  5120,  5376,  5312,  5344, 
+     5336,     0,  4096,  5120,  5376,  5312,  5344,  5336, 
+        0,  4096,  5120,  5376,  5312,  5344,  5336,  5338, 
+        0,  4096,  5120,  5376,  5312,  5344,  5336,     0, 
+     4096,  5120,  5376,  5312,  5344,  5345,  5340,     0, 
+     4096,  5120,  5376,  5312,  5344,  5345,  5340,     0, 
+     4096,  5120,  5376,  5312,  5344,  5345,  5340,  5342, 
+        0,  4096,  5120,  5376,  5312,     0,  4096,  5120, 
+     5376,  5377,  5344,     0,  4096,  5120,  5376,  5377, 
+     5344,     0,  4096,  5120,  5376,  5377,  5344,  5346, 
+        0,  4096,  5120,  5376,  5377,  5344,     0,  4096, 
+     5120,  5376,  5377,  5344,  5348,     0,  4096,  5120, 
+     5376,  5377,  5344,  5348,     0,  4096,  5120,  5376, 
+     5377,  5344,  5352,  5350,     0,  4096,  5120,  5376, 
+     5377,  5344,     0,  4096,  5120,  5376,  5377,  5344, 
+     5352,     0,  4096,  5120,  5376,  5377,  5344,  5352, 
+        0,  4096,  5120,  5376,  5377,  5344,  5352,  5354, 
+        0,  4096,  5120,  5376,  5377,  5344,  5352,     0, 
+     4096,  5120,  5376,  5377,  5344,  5360,  5356,     0, 
+     4096,  5120,  5376,  5377,  5344,  5360,  5356,     0, 
+     4096,  5120,  5376,  5377,  5344,  5360,  5361,  5358, 
+        0,  4096,  5120,  5376,  5377,  5344,     0,  4096, 
+     5120,  5376,  5377,  5344,  5360,     0,  4096,  5120, 
+     5376,  5377,  5379,  5360,     0,  4096,  5120,  5376, 
+     5377,  5379,  5360,  5362,     0,  4096,  5120,  5376, 
+     5377,  5379,  5360,     0,  4096,  5120,  5376,  5377, 
+     5379,  5360,  5364,     0,  4096,  5120,  5376,  5377, 
+     5379,  5360,  5364,     0,  4096,  5120,  5376,  5377, 
+     5379,  5360,  5368,  5366,     0,  4096,  5120,  5376, 
+     5377,  5379,  5360,     0,  4096,  5120,  5376,  5377, 
+     5379,  5360,  5368,     0,  4096,  5120,  5376,  5377, 
+     5379,  5360,  5368,     0,  4096,  5120,  5376,  5377, 
+     5379,  5360,  5368,  5370,     0,  4096,  5120,  5376, 
+     5377,  5379,  5383,  5368,     0,  4096,  5120,  5376, 
+     5377,  5379,  5383,  5368,  5372,     0,  4096,  5120, 
+     5376,  5377,  5379,  5383,  5368,  5372,     0,  4096, 
+     5120,  5376,  5377,  5379,  5383,  5368,  5372,  5374, 
+        0,  4096,  5120,     0,  4096,  5120,  5376,     0, 
+     4096,  5120,  5376,     0,  4096,  5120,  5376,  5378, 
+        0,  4096,  5120,  5376,     0,  4096,  5120,  5376, 
+     5380,     0,  4096,  5120,  5376,  5380,     0,  4096, 
+     5120,  5376,  5384,  5382,     0,  4096,  5120,  5376, 
+        0,  4096,  5120,  5376,  5384,     0,  4096,  5120, 
+     5376,  5384,     0,  4096,  5120,  5376,  5384,  5386, 
+        0,  4096,  5120,  5376,  5384,     0,  4096,  5120, 
+     5376,  5392,  5388,     0,  4096,  5120,  5376,  5392, 
+     5388,     0,  4096,  5120,  5376,  5392,  5393,  5390, 
+        0,  4096,  5120,  5376,     0,  4096,  5120,  5376, 
+     5392,     0,  4096,  5120,  5376,  5392,     0,  4096, 
+     5120,  5376,  5392,  5394,     0,  4096,  5120,  5376, 
+     5392,     0,  4096,  5120,  5376,  5392,  5396,     0, 
+     4096,  5120,  5376,  5392,  5396,     0,  4096,  5120, 
+     5376,  5392,  5400,  5398,     0,  4096,  5120,  5376, 
+     5392,     0,  4096,  5120,  5376,  5408,  5400,     0, 
+     4096,  5120,  5376,  5408,  5400,     0,  4096,  5120, 
+     5376,  5408,  5400,  5402,     0,  4096,  5120,  5376, 
+     5408,  5400,     0,  4096,  5120,  5376,  5408,  5409, 
+     5404,     0,  4096,  5120,  5376,  5408,  5409,  5404, 
+        0,  4096,  5120,  5376,  5408,  5409,  5404,  5406, 
+        0,  4096,  5120,  5376,     0,  4096,  5120,  5376, 
+     5408,     0,  4096,  5120,  5376,  5408,     0,  4096, 
+     5120,  5376,  5408,  5410,     0,  4096,  5120,  5376, 
+     5408,     0,  4096,  5120,  5376,  5408,  5412,     0, 
+     4096,  5120,  5376,  5408,  5412,     0,  4096,  5120, 
+     5376,  5408,  5416,  5414,     0,  4096,  5120,  5376, 
+     5408,     0,  4096,  5120,  5376,  5408,  5416,     0, 
+     4096,  5120,  5376,  5408,  5416,     0,  4096,  5120, 
+     5376,  5408,  5416,  5418,     0,  4096,  5120,  5376, 
+     5408,  5416,     0,  4096,  5120,  5376,  5408,  5424, 
+     5420,     0,  4096,  5120,  5376,  5408,  5424,  5420, 
+        0,  4096,  5120,  5376,  5408,  5424,  5425,  5422, 
+        0,  4096,  5120,  5376,  5408,     0,  4096,  5120, 
+     5376,  5440,  5424,     0,  4096,  5120,  5376,  5440, 
+     5424,     0,  4096,  5120,  5376,  5440,  5424,  5426, 
+        0,  4096,  5120,  5376,  5440,  5424,     0,  4096, 
+     5120,  5376,  5440,  5424,  5428,     0,  4096,  5120, 
+     5376,  5440,  5424,  5428,     0,  4096,  5120,  5376, 
+     5440,  5424,  5432,  5430,     0,  4096,  5120,  5376, 
+     5440,  5424,     0,  4096,  5120,  5376,  5440,  5441, 
+     5432,     0,  4096,  5120,  5376,  5440,  5441,  5432, 
+        0,  4096,  5120,  5376,  5440,  5441,  5432,  5434, 
+        0,  4096,  5120,  5376,  5440,  5441,  5432,     0, 
+     4096,  5120,  5376,  5440,  5441,  5432,  5436,     0, 
+     4096,  5120,  5376,  5440,  5441,  5443,  5436,     0, 
+     4096,  5120,  5376,  5440,  5441,  5443,  5436,  5438, 
+        0,  4096,  5120,  5376,     0,  4096,  5120,  5376, 
+     5440,     0,  4096,  5120,  5376,  5440,     0,  4096, 
+     5120,  5376,  5440,  5442,     0,  4096,  5120,  5376, 
+     5440,     0,  4096,  5120,  5376,  5440,  5444,     0, 
+     4096,  5120,  5376,  5440,  5444,     0,  4096,  5120, 
+     5376,  5440,  5448,  5446,     0,  4096,  5120,  5376, 
+     5440,     0,  4096,  5120,  5376,  5440,  5448,     0, 
+     4096,  5120,  5376,  5440,  5448,     0,  4096,  5120, 
+     5376,  5440,  5448,  5450,     0,  4096,  5120,  5376, 
+     5440,  5448,     0,  4096,  5120,  5376,  5440,  5456, 
+     5452,     0,  4096,  5120,  5376,  5440,  5456,  5452, 
+        0,  4096,  5120,  5376,  5440,  5456,  5457,  5454, 
+        0,  4096,  5120,  5376,  5440,     0,  4096,  5120, 
+     5376,  5440,  5456,     0,  4096,  5120,  5376,  5440, 
+     5456,     0,  4096,  5120,  5376,  5440,  5456,  5458, 
+        0,  4096,  5120,  5376,  5440,  5456,     0,  4096, 
+     5120,  5376,  5440,  5456,  5460,     0,  4096,  5120, 
+     5376,  5440,  5456,  5460,     0,  4096,  5120,  5376, 
+     5440,  5456,  5464,  5462,     0,  4096,  5120,  5376, 
+     5440,  5456,     0,  4096,  5120,  5376,  5440,  5472, 
+     5464,     0,  4096,  5120,  5376,  5440,  5472,  5464, 
+        0,  4096,  5120,  5376,  5440,  5472,  5464,  5466, 
+        0,  4096,  5120,  5376,  5440,  5472,  5464,     0, 
+     4096,  5120,  5376,  5440,  5472,  5473,  5468,     0, 
+     4096,  5120,  5376,  5440,  5472,  5473,  5468,     0, 
+     4096,  5120,  5376,  5440,  5472,  5473,  5468,  5470, 
+        0,  4096,  5120,  5376,  5440,     0,  4096,  5120, 
+     5376,  5504,  5472,     0,  4096,  5120,  5376,  5504, 
+     5472,     0,  4096,  5120,  5376,  5504,  5472,  5474, 
+        0,  4096,  5120,  5376,  5504,  5472,     0,  4096, 
+     5120,  5376,  5504,  5472,  5476,     0,  4096,  5120, 
+     5376,  5504,  5472,  5476,     0,  4096,  5120,  5376, 
+     5504,  5472,  5480,  5478,     0,  4096,  5120,  5376, 
+     5504,  5472,     0,  4096,  5120,  5376,  5504,  5472, 
+     5480,     0,  4096,  5120,  5376,  5504,  5472,  5480, 
+        0,  4096,  5120,  5376,  5504,  5472,  5480,  5482, 
+        0,  4096,  5120,  5376,  5504,  5472,  5480,     0, 
+     4096,  5120,  5376,  5504,  5472,  5488,  5484,     0, 
+     4096,  5120,  5376,  5504,  5472,  5488,  5484,     0, 
+     4096,  5120,  5376,  5504,  5472,  5488,  5489,  5486, 
+        0,  4096,  5120,  5376,  5504,  5472,     0,  4096, 
+     5120,  5376,  5504,  5505,  5488,     0,  4096,  5120, 
+     5376,  5504,  5505,  5488,     0,  4096,  5120,  5376, 
+     5504,  5505,  5488,  5490,     0,  4096,  5120,  5376, 
+     5504,  5505,  5488,     0,  4096,  5120,  5376,  5504, 
+     5505,  5488,  5492,     0,  4096,  5120,  5376,  5504, 
+     5505,  5488,  5492,     0,  4096,  5120,  5376,  5504, 
+     5505,  5488,  5496,  5494,     0,  4096,  5120,  5376, 
+     5504,  5505,  5488,     0,  4096,  5120,  5376,  5504, 
+     5505,  5488,  5496,     0,  4096,  5120,  5376,  5504, 
+     5505,  5507,  5496,     0,  4096,  5120,  5376,  5504, 
+     5505,  5507,  5496,  5498,     0,  4096,  5120,  5376, 
+     5504,  5505,  5507,  5496,     0,  4096,  5120,  5376, 
+     5504,  5505,  5507,  5496,  5500,     0,  4096,  5120, 
+     5376,  5504,  5505,  5507,  5496,  5500,     0,  4096, 
+     5120,  5376,  5504,  5505,  5507,  5496,  5500,  5502, 
+        0,  4096,  5120,  5376,     0,  4096,  5120,  5632, 
+     5504,     0,  4096,  5120,  5632,  5504,     0,  4096, 
+     5120,  5632,  5504,  5506,     0,  4096,  5120,  5632, 
+     5504,     0,  4096,  5120,  5632,  5504,  5508,     0, 
+     4096,  5120,  5632,  5504,  5508,     0,  4096,  5120, 
+     5632,  5504,  5512,  5510,     0,  4096,  5120,  5632, 
+     5504,     0,  4096,  5120,  5632,  5504,  5512,     0, 
+     4096,  5120,  5632,  5504,  5512,     0,  4096,  5120, 
+     5632,  5504,  5512,  5514,     0,  4096,  5120,  5632, 
+     5504,  5512,     0,  4096,  5120,  5632,  5504,  5520, 
+     5516,     0,  4096,  5120,  5632,  5504,  5520,  5516, 
+        0,  4096,  5120,  5632,  5504,  5520,  5521,  5518, 
+        0,  4096,  5120,  5632,  5504,     0,  4096,  5120, 
+     5632,  5504,  5520,     0,  4096,  5120,  5632,  5504, 
+     5520,     0,  4096,  5120,  5632,  5504,  5520,  5522, 
+        0,  4096,  5120,  5632,  5504,  5520,     0,  4096, 
+     5120,  5632,  5504,  5520,  5524,     0,  4096,  5120, 
+     5632,  5504,  5520,  5524,     0,  4096,  5120,  5632, 
+     5504,  5520,  5528,  5526,     0,  4096,  5120,  5632, 
+     5504,  5520,     0,  4096,  5120,  5632,  5504,  5536, 
+     5528,     0,  4096,  5120,  5632,  5504,  5536,  5528, 
+        0,  4096,  5120,  5632,  5504,  5536,  5528,  5530, 
+        0,  4096,  5120,  5632,  5504,  5536,  5528,     0, 
+     4096,  5120,  5632,  5504,  5536,  5537,  5532,     0, 
+     4096,  5120,  5632,  5504,  5536,  5537,  5532,     0, 
+     4096,  5120,  5632,  5504,  5536,  5537,  5532,  5534, 
+        0,  4096,  5120,  5632,  5504,     0,  4096,  5120, 
+     5632,  5504,  5536,     0,  4096,  5120,  5632,  5504, 
+     5536,     0,  4096,  5120,  5632,  5504,  5536,  5538, 
+        0,  4096,  5120,  5632,  5504,  5536,     0,  4096, 
+     5120,  5632,  5504,  5536,  5540,     0,  4096,  5120, 
+     5632,  5504,  5536,  5540,     0,  4096,  5120,  5632, 
+     5504,  5536,  5544,  5542,     0,  4096,  5120,  5632, 
+     5504,  5536,     0,  4096,  5120,  5632,  5504,  5536, 
+     5544,     0,  4096,  5120,  5632,  5504,  5536,  5544, 
+        0,  4096,  5120,  5632,  5504,  5536,  5544,  5546, 
+        0,  4096,  5120,  5632,  5504,  5536,  5544,     0, 
+     4096,  5120,  5632,  5504,  5536,  5552,  5548,     0, 
+     4096,  5120,  5632,  5504,  5536,  5552,  5548,     0, 
+     4096,  5120,  5632,  5504,  5536,  5552,  5553,  5550, 
+        0,  4096,  5120,  5632,  5504,  5536,     0,  4096, 
+     5120,  5632,  5504,  5568,  5552,     0,  4096,  5120, 
+     5632,  5504,  5568,  5552,     0,  4096,  5120,  5632, 
+     5504,  5568,  5552,  5554,     0,  4096,  5120,  5632, 
+     5504,  5568,  5552,     0,  4096,  5120,  5632,  5504, 
+     5568,  5552,  5556,     0,  4096,  5120,  5632,  5504, 
+     5568,  5552,  5556,     0,  4096,  5120,  5632,  5504, 
+     5568,  5552,  5560,  5558,     0,  4096,  5120,  5632, 
+     5504,  5568,  5552,     0,  4096,  5120,  5632,  5504, 
+     5568,  5569,  5560,     0,  4096,  5120,  5632,  5504, 
+     5568,  5569,  5560,     0,  4096,  5120,  5632,  5504, 
+     5568,  5569,  5560,  5562,     0,  4096,  5120,  5632, 
+     5504,  5568,  5569,  5560,     0,  4096,  5120,  5632, 
+     5504,  5568,  5569,  5560,  5564,     0,  4096,  5120, 
+     5632,  5504,  5568,  5569,  5571,  5564,     0,  4096, 
+     5120,  5632,  5504,  5568,  5569,  5571,  5564,  5566, 
+        0,  4096,  5120,  5632,  5504,     0,  4096,  5120, 
+     5632,  5633,  5568,     0,  4096,  5120,  5632,  5633, 
+     5568,     0,  4096,  5120,  5632,  5633,  5568,  5570, 
+        0,  4096,  5120,  5632,  5633,  5568,     0,  4096, 
+     5120,  5632,  5633,  5568,  5572,     0,  4096,  5120, 
+     5632,  5633,  5568,  5572,     0,  4096,  5120,  5632, 
+     5633,  5568,  5576,  5574,     0,  4096,  5120,  5632, 
+     5633,  5568,     0,  4096,  5120,  5632,  5633,  5568, 
+     5576,     0,  4096,  5120,  5632,  5633,  5568,  5576, 
+        0,  4096,  5120,  5632,  5633,  5568,  5576,  5578, 
+        0,  4096,  5120,  5632,  5633,  5568,  5576,     0, 
+     4096,  5120,  5632,  5633,  5568,  5584,  5580,     0, 
+     4096,  5120,  5632,  5633,  5568,  5584,  5580,     0, 
+     4096,  5120,  5632,  5633,  5568,  5584,  5585,  5582, 
+        0,  4096,  5120,  5632,  5633,  5568,     0,  4096, 
+     5120,  5632,  5633,  5568,  5584,     0,  4096,  5120, 
+     5632,  5633,  5568,  5584,     0,  4096,  5120,  5632, 
+     5633,  5568,  5584,  5586,     0,  4096,  5120,  5632, 
+     5633,  5568,  5584,     0,  4096,  5120,  5632,  5633, 
+     5568,  5584,  5588,     0,  4096,  5120,  5632,  5633, 
+     5568,  5584,  5588,     0,  4096,  5120,  5632,  5633, 
+     5568,  5584,  5592,  5590,     0,  4096,  5120,  5632, 
+     5633,  5568,  5584,     0,  4096,  5120,  5632,  5633, 
+     5568,  5600,  5592,     0,  4096,  5120,  5632,  5633, 
+     5568,  5600,  5592,     0,  4096,  5120,  5632,  5633, 
+     5568,  5600,  5592,  5594,     0,  4096,  5120,  5632, 
+     5633,  5568,  5600,  5592,     0,  4096,  5120,  5632, 
+     5633,  5568,  5600,  5601,  5596,     0,  4096,  5120, 
+     5632,  5633,  5568,  5600,  5601,  5596,     0,  4096, 
+     5120,  5632,  5633,  5568,  5600,  5601,  5596,  5598, 
+        0,  4096,  5120,  5632,  5633,  5568,     0,  4096, 
+     5120,  5632,  5633,  5568,  5600,     0,  4096,  5120, 
+     5632,  5633,  5635,  5600,     0,  4096,  5120,  5632, 
+     5633,  5635,  5600,  5602,     0,  4096,  5120,  5632, 
+     5633,  5635,  5600,     0,  4096,  5120,  5632,  5633, 
+     5635,  5600,  5604,     0,  4096,  5120,  5632,  5633, 
+     5635,  5600,  5604,     0,  4096,  5120,  5632,  5633, 
+     5635,  5600,  5608,  5606,     0,  4096,  5120,  5632, 
+     5633,  5635,  5600,     0,  4096,  5120,  5632,  5633, 
+     5635,  5600,  5608,     0,  4096,  5120,  5632,  5633, 
+     5635,  5600,  5608,     0,  4096,  5120,  5632,  5633, 
+     5635,  5600,  5608,  5610,     0,  4096,  5120,  5632, 
+     5633,  5635,  5600,  5608,     0,  4096,  5120,  5632, 
+     5633,  5635,  5600,  5616,  5612,     0,  4096,  5120, 
+     5632,  5633,  5635,  5600,  5616,  5612,     0,  4096, 
+     5120,  5632,  5633,  5635,  5600,  5616,  5617,  5614, 
+        0,  4096,  5120,  5632,  5633,  5635,  5600,     0, 
+     4096,  5120,  5632,  5633,  5635,  5600,  5616,     0, 
+     4096,  5120,  5632,  5633,  5635,  5600,  5616,     0, 
+     4096,  5120,  5632,  5633,  5635,  5600,  5616,  5618, 
+        0,  4096,  5120,  5632,  5633,  5635,  5639,  5616, 
+        0,  4096,  5120,  5632,  5633,  5635,  5639,  5616, 
+     5620,     0,  4096,  5120,  5632,  5633,  5635,  5639, 
+     5616,  5620,     0,  4096,  5120,  5632,  5633,  5635, 
+     5639,  5616,  5624,  5622,     0,  4096,  5120,  5632, 
+     5633,  5635,  5639,  5616,     0,  4096,  5120,  5632, 
+     5633,  5635,  5639,  5616,  5624,     0,  4096,  5120, 
+     5632,  5633,  5635,  5639,  5616,  5624,     0,  4096, 
+     5120,  5632,  5633,  5635,  5639,  5616,  5624,  5626, 
+        0,  4096,  5120,  5632,  5633,  5635,  5639,  5616, 
+     5624,     0,  4096,  5120,  5632,  5633,  5635,  5639, 
+     5616,  5624,  5628,     0,  4096,  5120,  5632,  5633, 
+     5635,  5639,  5616,  5624,  5628,     0,  4096,  5120, 
+     5632,  5633,  5635,  5639,  5616,  5624,  5628,  5630, 
+        0,  4096,  5120,     0,  4096,  6144,  5632,     0, 
+     4096,  6144,  5632,     0,  4096,  6144,  5632,  5634, 
+        0,  4096,  6144,  5632,     0,  4096,  6144,  5632, 
+     5636,     0,  4096,  6144,  5632,  5636,     0,  4096, 
+     6144,  5632,  5640,  5638,     0,  4096,  6144,  5632, 
+        0,  4096,  6144,  5632,  5640,     0,  4096,  6144, 
+     5632,  5640,     0,  4096,  6144,  5632,  5640,  5642, 
+        0,  4096,  6144,  5632,  5640,     0,  4096,  6144, 
+     5632,  5648,  5644,     0,  4096,  6144,  5632,  5648, 
+     5644,     0,  4096,  6144,  5632,  5648,  5649,  5646, 
+        0,  4096,  6144,  5632,     0,  4096,  6144,  5632, 
+     5648,     0,  4096,  6144,  5632,  5648,     0,  4096, 
+     6144,  5632,  5648,  5650,     0,  4096,  6144,  5632, 
+     5648,     0,  4096,  6144,  5632,  5648,  5652,     0, 
+     4096,  6144,  5632,  5648,  5652,     0,  4096,  6144, 
+     5632,  5648,  5656,  5654,     0,  4096,  6144,  5632, 
+     5648,     0,  4096,  6144,  5632,  5664,  5656,     0, 
+     4096,  6144,  5632,  5664,  5656,     0,  4096,  6144, 
+     5632,  5664,  5656,  5658,     0,  4096,  6144,  5632, 
+     5664,  5656,     0,  4096,  6144,  5632,  5664,  5665, 
+     5660,     0,  4096,  6144,  5632,  5664,  5665,  5660, 
+        0,  4096,  6144,  5632,  5664,  5665,  5660,  5662, 
+        0,  4096,  6144,  5632,     0,  4096,  6144,  5632, 
+     5664,     0,  4096,  6144,  5632,  5664,     0,  4096, 
+     6144,  5632,  5664,  5666,     0,  4096,  6144,  5632, 
+     5664,     0,  4096,  6144,  5632,  5664,  5668,     0, 
+     4096,  6144,  5632,  5664,  5668,     0,  4096,  6144, 
+     5632,  5664,  5672,  5670,     0,  4096,  6144,  5632, 
+     5664,     0,  4096,  6144,  5632,  5664,  5672,     0, 
+     4096,  6144,  5632,  5664,  5672,     0,  4096,  6144, 
+     5632,  5664,  5672,  5674,     0,  4096,  6144,  5632, 
+     5664,  5672,     0,  4096,  6144,  5632,  5664,  5680, 
+     5676,     0,  4096,  6144,  5632,  5664,  5680,  5676, 
+        0,  4096,  6144,  5632,  5664,  5680,  5681,  5678, 
+        0,  4096,  6144,  5632,  5664,     0,  4096,  6144, 
+     5632,  5696,  5680,     0,  4096,  6144,  5632,  5696, 
+     5680,     0,  4096,  6144,  5632,  5696,  5680,  5682, 
+        0,  4096,  6144,  5632,  5696,  5680,     0,  4096, 
+     6144,  5632,  5696,  5680,  5684,     0,  4096,  6144, 
+     5632,  5696,  5680,  5684,     0,  4096,  6144,  5632, 
+     5696,  5680,  5688,  5686,     0,  4096,  6144,  5632, 
+     5696,  5680,     0,  4096,  6144,  5632,  5696,  5697, 
+     5688,     0,  4096,  6144,  5632,  5696,  5697,  5688, 
+        0,  4096,  6144,  5632,  5696,  5697,  5688,  5690, 
+        0,  4096,  6144,  5632,  5696,  5697,  5688,     0, 
+     4096,  6144,  5632,  5696,  5697,  5688,  5692,     0, 
+     4096,  6144,  5632,  5696,  5697,  5699,  5692,     0, 
+     4096,  6144,  5632,  5696,  5697,  5699,  5692,  5694, 
+        0,  4096,  6144,  5632,     0,  4096,  6144,  5632, 
+     5696,     0,  4096,  6144,  5632,  5696,     0,  4096, 
+     6144,  5632,  5696,  5698,     0,  4096,  6144,  5632, 
+     5696,     0,  4096,  6144,  5632,  5696,  5700,     0, 
+     4096,  6144,  5632,  5696,  5700,     0,  4096,  6144, 
+     5632,  5696,  5704,  5702,     0,  4096,  6144,  5632, 
+     5696,     0,  4096,  6144,  5632,  5696,  5704,     0, 
+     4096,  6144,  5632,  5696,  5704,     0,  4096,  6144, 
+     5632,  5696,  5704,  5706,     0,  4096,  6144,  5632, 
+     5696,  5704,     0,  4096,  6144,  5632,  5696,  5712, 
+     5708,     0,  4096,  6144,  5632,  5696,  5712,  5708, 
+        0,  4096,  6144,  5632,  5696,  5712,  5713,  5710, 
+        0,  4096,  6144,  5632,  5696,     0,  4096,  6144, 
+     5632,  5696,  5712,     0,  4096,  6144,  5632,  5696, 
+     5712,     0,  4096,  6144,  5632,  5696,  5712,  5714, 
+        0,  4096,  6144,  5632,  5696,  5712,     0,  4096, 
+     6144,  5632,  5696,  5712,  5716,     0,  4096,  6144, 
+     5632,  5696,  5712,  5716,     0,  4096,  6144,  5632, 
+     5696,  5712,  5720,  5718,     0,  4096,  6144,  5632, 
+     5696,  5712,     0,  4096,  6144,  5632,  5696,  5728, 
+     5720,     0,  4096,  6144,  5632,  5696,  5728,  5720, 
+        0,  4096,  6144,  5632,  5696,  5728,  5720,  5722, 
+        0,  4096,  6144,  5632,  5696,  5728,  5720,     0, 
+     4096,  6144,  5632,  5696,  5728,  5729,  5724,     0, 
+     4096,  6144,  5632,  5696,  5728,  5729,  5724,     0, 
+     4096,  6144,  5632,  5696,  5728,  5729,  5724,  5726, 
+        0,  4096,  6144,  5632,  5696,     0,  4096,  6144, 
+     5632,  5760,  5728,     0,  4096,  6144,  5632,  5760, 
+     5728,     0,  4096,  6144,  5632,  5760,  5728,  5730, 
+        0,  4096,  6144,  5632,  5760,  5728,     0,  4096, 
+     6144,  5632,  5760,  5728,  5732,     0,  4096,  6144, 
+     5632,  5760,  5728,  5732,     0,  4096,  6144,  5632, 
+     5760,  5728,  5736,  5734,     0,  4096,  6144,  5632, 
+     5760,  5728,     0,  4096,  6144,  5632,  5760,  5728, 
+     5736,     0,  4096,  6144,  5632,  5760,  5728,  5736, 
+        0,  4096,  6144,  5632,  5760,  5728,  5736,  5738, 
+        0,  4096,  6144,  5632,  5760,  5728,  5736,     0, 
+     4096,  6144,  5632,  5760,  5728,  5744,  5740,     0, 
+     4096,  6144,  5632,  5760,  5728,  5744,  5740,     0, 
+     4096,  6144,  5632,  5760,  5728,  5744,  5745,  5742, 
+        0,  4096,  6144,  5632,  5760,  5728,     0,  4096, 
+     6144,  5632,  5760,  5761,  5744,     0,  4096,  6144, 
+     5632,  5760,  5761,  5744,     0,  4096,  6144,  5632, 
+     5760,  5761,  5744,  5746,     0,  4096,  6144,  5632, 
+     5760,  5761,  5744,     0,  4096,  6144,  5632,  5760, 
+     5761,  5744,  5748,     0,  4096,  6144,  5632,  5760, 
+     5761,  5744,  5748,     0,  4096,  6144,  5632,  5760, 
+     5761,  5744,  5752,  5750,     0,  4096,  6144,  5632, 
+     5760,  5761,  5744,     0,  4096,  6144,  5632,  5760, 
+     5761,  5744,  5752,     0,  4096,  6144,  5632,  5760, 
+     5761,  5763,  5752,     0,  4096,  6144,  5632,  5760, 
+     5761,  5763,  5752,  5754,     0,  4096,  6144,  5632, 
+     5760,  5761,  5763,  5752,     0,  4096,  6144,  5632, 
+     5760,  5761,  5763,  5752,  5756,     0,  4096,  6144, 
+     5632,  5760,  5761,  5763,  5752,  5756,     0,  4096, 
+     6144,  5632,  5760,  5761,  5763,  5752,  5756,  5758, 
+        0,  4096,  6144,  5632,     0,  4096,  6144,  5632, 
+     5760,     0,  4096,  6144,  5632,  5760,     0,  4096, 
+     6144,  5632,  5760,  5762,     0,  4096,  6144,  5632, 
+     5760,     0,  4096,  6144,  5632,  5760,  5764,     0, 
+     4096,  6144,  5632,  5760,  5764,     0,  4096,  6144, 
+     5632,  5760,  5768,  5766,     0,  4096,  6144,  5632, 
+     5760,     0,  4096,  6144,  5632,  5760,  5768,     0, 
+     4096,  6144,  5632,  5760,  5768,     0,  4096,  6144, 
+     5632,  5760,  5768,  5770,     0,  4096,  6144,  5632, 
+     5760,  5768,     0,  4096,  6144,  5632,  5760,  5776, 
+     5772,     0,  4096,  6144,  5632,  5760,  5776,  5772, 
+        0,  4096,  6144,  5632,  5760,  5776,  5777,  5774, 
+        0,  4096,  6144,  5632,  5760,     0,  4096,  6144, 
+     5632,  5760,  5776,     0,  4096,  6144,  5632,  5760, 
+     5776,     0,  4096,  6144,  5632,  5760,  5776,  5778, 
+        0,  4096,  6144,  5632,  5760,  5776,     0,  4096, 
+     6144,  5632,  5760,  5776,  5780,     0,  4096,  6144, 
+     5632,  5760,  5776,  5780,     0,  4096,  6144,  5632, 
+     5760,  5776,  5784,  5782,     0,  4096,  6144,  5632, 
+     5760,  5776,     0,  4096,  6144,  5632,  5760,  5792, 
+     5784,     0,  4096,  6144,  5632,  5760,  5792,  5784, 
+        0,  4096,  6144,  5632,  5760,  5792,  5784,  5786, 
+        0,  4096,  6144,  5632,  5760,  5792,  5784,     0, 
+     4096,  6144,  5632,  5760,  5792,  5793,  5788,     0, 
+     4096,  6144,  5632,  5760,  5792,  5793,  5788,     0, 
+     4096,  6144,  5632,  5760,  5792,  5793,  5788,  5790, 
+        0,  4096,  6144,  5632,  5760,     0,  4096,  6144, 
+     5632,  5760,  5792,     0,  4096,  6144,  5632,  5760, 
+     5792,     0,  4096,  6144,  5632,  5760,  5792,  5794, 
+        0,  4096,  6144,  5632,  5760,  5792,     0,  4096, 
+     6144,  5632,  5760,  5792,  5796,     0,  4096,  6144, 
+     5632,  5760,  5792,  5796,     0,  4096,  6144,  5632, 
+     5760,  5792,  5800,  5798,     0,  4096,  6144,  5632, 
+     5760,  5792,     0,  4096,  6144,  5632,  5760,  5792, 
+     5800,     0,  4096,  6144,  5632,  5760,  5792,  5800, 
+        0,  4096,  6144,  5632,  5760,  5792,  5800,  5802, 
+        0,  4096,  6144,  5632,  5760,  5792,  5800,     0, 
+     4096,  6144,  5632,  5760,  5792,  5808,  5804,     0, 
+     4096,  6144,  5632,  5760,  5792,  5808,  5804,     0, 
+     4096,  6144,  5632,  5760,  5792,  5808,  5809,  5806, 
+        0,  4096,  6144,  5632,  5760,  5792,     0,  4096, 
+     6144,  5632,  5760,  5824,  5808,     0,  4096,  6144, 
+     5632,  5760,  5824,  5808,     0,  4096,  6144,  5632, 
+     5760,  5824,  5808,  5810,     0,  4096,  6144,  5632, 
+     5760,  5824,  5808,     0,  4096,  6144,  5632,  5760, 
+     5824,  5808,  5812,     0,  4096,  6144,  5632,  5760, 
+     5824,  5808,  5812,     0,  4096,  6144,  5632,  5760, 
+     5824,  5808,  5816,  5814,     0,  4096,  6144,  5632, 
+     5760,  5824,  5808,     0,  4096,  6144,  5632,  5760, 
+     5824,  5825,  5816,     0,  4096,  6144,  5632,  5760, 
+     5824,  5825,  5816,     0,  4096,  6144,  5632,  5760, 
+     5824,  5825,  5816,  5818,     0,  4096,  6144,  5632, 
+     5760,  5824,  5825,  5816,     0,  4096,  6144,  5632, 
+     5760,  5824,  5825,  5816,  5820,     0,  4096,  6144, 
+     5632,  5760,  5824,  5825,  5827,  5820,     0,  4096, 
+     6144,  5632,  5760,  5824,  5825,  5827,  5820,  5822, 
+        0,  4096,  6144,  5632,  5760,     0,  4096,  6144, 
+     5632,  5888,  5824,     0,  4096,  6144,  5632,  5888, 
+     5824,     0,  4096,  6144,  5632,  5888,  5824,  5826, 
+        0,  4096,  6144,  5632,  5888,  5824,     0,  4096, 
+     6144,  5632,  5888,  5824,  5828,     0,  4096,  6144, 
+     5632,  5888,  5824,  5828,     0,  4096,  6144,  5632, 
+     5888,  5824,  5832,  5830,     0,  4096,  6144,  5632, 
+     5888,  5824,     0,  4096,  6144,  5632,  5888,  5824, 
+     5832,     0,  4096,  6144,  5632,  5888,  5824,  5832, 
+        0,  4096,  6144,  5632,  5888,  5824,  5832,  5834, 
+        0,  4096,  6144,  5632,  5888,  5824,  5832,     0, 
+     4096,  6144,  5632,  5888,  5824,  5840,  5836,     0, 
+     4096,  6144,  5632,  5888,  5824,  5840,  5836,     0, 
+     4096,  6144,  5632,  5888,  5824,  5840,  5841,  5838, 
+        0,  4096,  6144,  5632,  5888,  5824,     0,  4096, 
+     6144,  5632,  5888,  5824,  5840,     0,  4096,  6144, 
+     5632,  5888,  5824,  5840,     0,  4096,  6144,  5632, 
+     5888,  5824,  5840,  5842,     0,  4096,  6144,  5632, 
+     5888,  5824,  5840,     0,  4096,  6144,  5632,  5888, 
+     5824,  5840,  5844,     0,  4096,  6144,  5632,  5888, 
+     5824,  5840,  5844,     0,  4096,  6144,  5632,  5888, 
+     5824,  5840,  5848,  5846,     0,  4096,  6144,  5632, 
+     5888,  5824,  5840,     0,  4096,  6144,  5632,  5888, 
+     5824,  5856,  5848,     0,  4096,  6144,  5632,  5888, 
+     5824,  5856,  5848,     0,  4096,  6144,  5632,  5888, 
+     5824,  5856,  5848,  5850,     0,  4096,  6144,  5632, 
+     5888,  5824,  5856,  5848,     0,  4096,  6144,  5632, 
+     5888,  5824,  5856,  5857,  5852,     0,  4096,  6144, 
+     5632,  5888,  5824,  5856,  5857,  5852,     0,  4096, 
+     6144,  5632,  5888,  5824,  5856,  5857,  5852,  5854, 
+        0,  4096,  6144,  5632,  5888,  5824,     0,  4096, 
+     6144,  5632,  5888,  5889,  5856,     0,  4096,  6144, 
+     5632,  5888,  5889,  5856,     0,  4096,  6144,  5632, 
+     5888,  5889,  5856,  5858,     0,  4096,  6144,  5632, 
+     5888,  5889,  5856,     0,  4096,  6144,  5632,  5888, 
+     5889,  5856,  5860,     0,  4096,  6144,  5632,  5888, 
+     5889,  5856,  5860,     0,  4096,  6144,  5632,  5888, 
+     5889,  5856,  5864,  5862,     0,  4096,  6144,  5632, 
+     5888,  5889,  5856,     0,  4096,  6144,  5632,  5888, 
+     5889,  5856,  5864,     0,  4096,  6144,  5632,  5888, 
+     5889,  5856,  5864,     0,  4096,  6144,  5632,  5888, 
+     5889,  5856,  5864,  5866,     0,  4096,  6144,  5632, 
+     5888,  5889,  5856,  5864,     0,  4096,  6144,  5632, 
+     5888,  5889,  5856,  5872,  5868,     0,  4096,  6144, 
+     5632,  5888,  5889,  5856,  5872,  5868,     0,  4096, 
+     6144,  5632,  5888,  5889,  5856,  5872,  5873,  5870, 
+        0,  4096,  6144,  5632,  5888,  5889,  5856,     0, 
+     4096,  6144,  5632,  5888,  5889,  5856,  5872,     0, 
+     4096,  6144,  5632,  5888,  5889,  5891,  5872,     0, 
+     4096,  6144,  5632,  5888,  5889,  5891,  5872,  5874, 
+        0,  4096,  6144,  5632,  5888,  5889,  5891,  5872, 
+        0,  4096,  6144,  5632,  5888,  5889,  5891,  5872, 
+     5876,     0,  4096,  6144,  5632,  5888,  5889,  5891, 
+     5872,  5876,     0,  4096,  6144,  5632,  5888,  5889, 
+     5891,  5872,  5880,  5878,     0,  4096,  6144,  5632, 
+     5888,  5889,  5891,  5872,     0,  4096,  6144,  5632, 
+     5888,  5889,  5891,  5872,  5880,     0,  4096,  6144, 
+     5632,  5888,  5889,  5891,  5872,  5880,     0,  4096, 
+     6144,  5632,  5888,  5889,  5891,  5872,  5880,  5882, 
+        0,  4096,  6144,  5632,  5888,  5889,  5891,  5895, 
+     5880,     0,  4096,  6144,  5632,  5888,  5889,  5891, 
+     5895,  5880,  5884,     0,  4096,  6144,  5632,  5888, 
+     5889,  5891,  5895,  5880,  5884,     0,  4096,  6144, 
+     5632,  5888,  5889,  5891,  5895,  5880,  5884,  5886, 
+        0,  4096,  6144,  5632,     0,  4096,  6144,  5632, 
+     5888,     0,  4096,  6144,  6145,  5888,     0,  4096, 
+     6144,  6145,  5888,  5890,     0,  4096,  6144,  6145, 
+     5888,     0,  4096,  6144,  6145,  5888,  5892,     0, 
+     4096,  6144,  6145,  5888,  5892,     0,  4096,  6144, 
+     6145,  5888,  5896,  5894,     0,  4096,  6144,  6145, 
+     5888,     0,  4096,  6144,  6145,  5888,  5896,     0, 
+     4096,  6144,  6145,  5888,  5896,     0,  4096,  6144, 
+     6145,  5888,  5896,  5898,     0,  4096,  6144,  6145, 
+     5888,  5896,     0,  4096,  6144,  6145,  5888,  5904, 
+     5900,     0,  4096,  6144,  6145,  5888,  5904,  5900, 
+        0,  4096,  6144,  6145,  5888,  5904,  5905,  5902, 
+        0,  4096,  6144,  6145,  5888,     0,  4096,  6144, 
+     6145,  5888,  5904,     0,  4096,  6144,  6145,  5888, 
+     5904,     0,  4096,  6144,  6145,  5888,  5904,  5906, 
+        0,  4096,  6144,  6145,  5888,  5904,     0,  4096, 
+     6144,  6145,  5888,  5904,  5908,     0,  4096,  6144, 
+     6145,  5888,  5904,  5908,     0,  4096,  6144,  6145, 
+     5888,  5904,  5912,  5910,     0,  4096,  6144,  6145, 
+     5888,  5904,     0,  4096,  6144,  6145,  5888,  5920, 
+     5912,     0,  4096,  6144,  6145,  5888,  5920,  5912, 
+        0,  4096,  6144,  6145,  5888,  5920,  5912,  5914, 
+        0,  4096,  6144,  6145,  5888,  5920,  5912,     0, 
+     4096,  6144,  6145,  5888,  5920,  5921,  5916,     0, 
+     4096,  6144,  6145,  5888,  5920,  5921,  5916,     0, 
+     4096,  6144,  6145,  5888,  5920,  5921,  5916,  5918, 
+        0,  4096,  6144,  6145,  5888,     0,  4096,  6144, 
+     6145,  5888,  5920,     0,  4096,  6144,  6145,  5888, 
+     5920,     0,  4096,  6144,  6145,  5888,  5920,  5922, 
+        0,  4096,  6144,  6145,  5888,  5920,     0,  4096, 
+     6144,  6145,  5888,  5920,  5924,     0,  4096,  6144, 
+     6145,  5888,  5920,  5924,     0,  4096,  6144,  6145, 
+     5888,  5920,  5928,  5926,     0,  4096,  6144,  6145, 
+     5888,  5920,     0,  4096,  6144,  6145,  5888,  5920, 
+     5928,     0,  4096,  6144,  6145,  5888,  5920,  5928, 
+        0,  4096,  6144,  6145,  5888,  5920,  5928,  5930, 
+        0,  4096,  6144,  6145,  5888,  5920,  5928,     0, 
+     4096,  6144,  6145,  5888,  5920,  5936,  5932,     0, 
+     4096,  6144,  6145,  5888,  5920,  5936,  5932,     0, 
+     4096,  6144,  6145,  5888,  5920,  5936,  5937,  5934, 
+        0,  4096,  6144,  6145,  5888,  5920,     0,  4096, 
+     6144,  6145,  5888,  5952,  5936,     0,  4096,  6144, 
+     6145,  5888,  5952,  5936,     0,  4096,  6144,  6145, 
+     5888,  5952,  5936,  5938,     0,  4096,  6144,  6145, 
+     5888,  5952,  5936,     0,  4096,  6144,  6145,  5888, 
+     5952,  5936,  5940,     0,  4096,  6144,  6145,  5888, 
+     5952,  5936,  5940,     0,  4096,  6144,  6145,  5888, 
+     5952,  5936,  5944,  5942,     0,  4096,  6144,  6145, 
+     5888,  5952,  5936,     0,  4096,  6144,  6145,  5888, 
+     5952,  5953,  5944,     0,  4096,  6144,  6145,  5888, 
+     5952,  5953,  5944,     0,  4096,  6144,  6145,  5888, 
+     5952,  5953,  5944,  5946,     0,  4096,  6144,  6145, 
+     5888,  5952,  5953,  5944,     0,  4096,  6144,  6145, 
+     5888,  5952,  5953,  5944,  5948,     0,  4096,  6144, 
+     6145,  5888,  5952,  5953,  5955,  5948,     0,  4096, 
+     6144,  6145,  5888,  5952,  5953,  5955,  5948,  5950, 
+        0,  4096,  6144,  6145,  5888,     0,  4096,  6144, 
+     6145,  5888,  5952,     0,  4096,  6144,  6145,  5888, 
+     5952,     0,  4096,  6144,  6145,  5888,  5952,  5954, 
+        0,  4096,  6144,  6145,  5888,  5952,     0,  4096, 
+     6144,  6145,  5888,  5952,  5956,     0,  4096,  6144, 
+     6145,  5888,  5952,  5956,     0,  4096,  6144,  6145, 
+     5888,  5952,  5960,  5958,     0,  4096,  6144,  6145, 
+     5888,  5952,     0,  4096,  6144,  6145,  5888,  5952, 
+     5960,     0,  4096,  6144,  6145,  5888,  5952,  5960, 
+        0,  4096,  6144,  6145,  5888,  5952,  5960,  5962, 
+        0,  4096,  6144,  6145,  5888,  5952,  5960,     0, 
+     4096,  6144,  6145,  5888,  5952,  5968,  5964,     0, 
+     4096,  6144,  6145,  5888,  5952,  5968,  5964,     0, 
+     4096,  6144,  6145,  5888,  5952,  5968,  5969,  5966, 
+        0,  4096,  6144,  6145,  5888,  5952,     0,  4096, 
+     6144,  6145,  5888,  5952,  5968,     0,  4096,  6144, 
+     6145,  5888,  5952,  5968,     0,  4096,  6144,  6145, 
+     5888,  5952,  5968,  5970,     0,  4096,  6144,  6145, 
+     5888,  5952,  5968,     0,  4096,  6144,  6145,  5888, 
+     5952,  5968,  5972,     0,  4096,  6144,  6145,  5888, 
+     5952,  5968,  5972,     0,  4096,  6144,  6145,  5888, 
+     5952,  5968,  5976,  5974,     0,  4096,  6144,  6145, 
+     5888,  5952,  5968,     0,  4096,  6144,  6145,  5888, 
+     5952,  5984,  5976,     0,  4096,  6144,  6145,  5888, 
+     5952,  5984,  5976,     0,  4096,  6144,  6145,  5888, 
+     5952,  5984,  5976,  5978,     0,  4096,  6144,  6145, 
+     5888,  5952,  5984,  5976,     0,  4096,  6144,  6145, 
+     5888,  5952,  5984,  5985,  5980,     0,  4096,  6144, 
+     6145,  5888,  5952,  5984,  5985,  5980,     0,  4096, 
+     6144,  6145,  5888,  5952,  5984,  5985,  5980,  5982, 
+        0,  4096,  6144,  6145,  5888,  5952,     0,  4096, 
+     6144,  6145,  5888,  6016,  5984,     0,  4096,  6144, 
+     6145,  5888,  6016,  5984,     0,  4096,  6144,  6145, 
+     5888,  6016,  5984,  5986,     0,  4096,  6144,  6145, 
+     5888,  6016,  5984,     0,  4096,  6144,  6145,  5888, 
+     6016,  5984,  5988,     0,  4096,  6144,  6145,  5888, 
+     6016,  5984,  5988,     0,  4096,  6144,  6145,  5888, 
+     6016,  5984,  5992,  5990,     0,  4096,  6144,  6145, 
+     5888,  6016,  5984,     0,  4096,  6144,  6145,  5888, 
+     6016,  5984,  5992,     0,  4096,  6144,  6145,  5888, 
+     6016,  5984,  5992,     0,  4096,  6144,  6145,  5888, 
+     6016,  5984,  5992,  5994,     0,  4096,  6144,  6145, 
+     5888,  6016,  5984,  5992,     0,  4096,  6144,  6145, 
+     5888,  6016,  5984,  6000,  5996,     0,  4096,  6144, 
+     6145,  5888,  6016,  5984,  6000,  5996,     0,  4096, 
+     6144,  6145,  5888,  6016,  5984,  6000,  6001,  5998, 
+        0,  4096,  6144,  6145,  5888,  6016,  5984,     0, 
+     4096,  6144,  6145,  5888,  6016,  6017,  6000,     0, 
+     4096,  6144,  6145,  5888,  6016,  6017,  6000,     0, 
+     4096,  6144,  6145,  5888,  6016,  6017,  6000,  6002, 
+        0,  4096,  6144,  6145,  5888,  6016,  6017,  6000, 
+        0,  4096,  6144,  6145,  5888,  6016,  6017,  6000, 
+     6004,     0,  4096,  6144,  6145,  5888,  6016,  6017, 
+     6000,  6004,     0,  4096,  6144,  6145,  5888,  6016, 
+     6017,  6000,  6008,  6006,     0,  4096,  6144,  6145, 
+     5888,  6016,  6017,  6000,     0,  4096,  6144,  6145, 
+     5888,  6016,  6017,  6000,  6008,     0,  4096,  6144, 
+     6145,  5888,  6016,  6017,  6019,  6008,     0,  4096, 
+     6144,  6145,  5888,  6016,  6017,  6019,  6008,  6010, 
+        0,  4096,  6144,  6145,  5888,  6016,  6017,  6019, 
+     6008,     0,  4096,  6144,  6145,  5888,  6016,  6017, 
+     6019,  6008,  6012,     0,  4096,  6144,  6145,  5888, 
+     6016,  6017,  6019,  6008,  6012,     0,  4096,  6144, 
+     6145,  5888,  6016,  6017,  6019,  6008,  6012,  6014, 
+        0,  4096,  6144,  6145,  5888,     0,  4096,  6144, 
+     6145,  5888,  6016,     0,  4096,  6144,  6145,  5888, 
+     6016,     0,  4096,  6144,  6145,  5888,  6016,  6018, 
+        0,  4096,  6144,  6145,  6147,  6016,     0,  4096, 
+     6144,  6145,  6147,  6016,  6020,     0,  4096,  6144, 
+     6145,  6147,  6016,  6020,     0,  4096,  6144,  6145, 
+     6147,  6016,  6024,  6022,     0,  4096,  6144,  6145, 
+     6147,  6016,     0,  4096,  6144,  6145,  6147,  6016, 
+     6024,     0,  4096,  6144,  6145,  6147,  6016,  6024, 
+        0,  4096,  6144,  6145,  6147,  6016,  6024,  6026, 
+        0,  4096,  6144,  6145,  6147,  6016,  6024,     0, 
+     4096,  6144,  6145,  6147,  6016,  6032,  6028,     0, 
+     4096,  6144,  6145,  6147,  6016,  6032,  6028,     0, 
+     4096,  6144,  6145,  6147,  6016,  6032,  6033,  6030, 
+        0,  4096,  6144,  6145,  6147,  6016,     0,  4096, 
+     6144,  6145,  6147,  6016,  6032,     0,  4096,  6144, 
+     6145,  6147,  6016,  6032,     0,  4096,  6144,  6145, 
+     6147,  6016,  6032,  6034,     0,  4096,  6144,  6145, 
+     6147,  6016,  6032,     0,  4096,  6144,  6145,  6147, 
+     6016,  6032,  6036,     0,  4096,  6144,  6145,  6147, 
+     6016,  6032,  6036,     0,  4096,  6144,  6145,  6147, 
+     6016,  6032,  6040,  6038,     0,  4096,  6144,  6145, 
+     6147,  6016,  6032,     0,  4096,  6144,  6145,  6147, 
+     6016,  6048,  6040,     0,  4096,  6144,  6145,  6147, 
+     6016,  6048,  6040,     0,  4096,  6144,  6145,  6147, 
+     6016,  6048,  6040,  6042,     0,  4096,  6144,  6145, 
+     6147,  6016,  6048,  6040,     0,  4096,  6144,  6145, 
+     6147,  6016,  6048,  6049,  6044,     0,  4096,  6144, 
+     6145,  6147,  6016,  6048,  6049,  6044,     0,  4096, 
+     6144,  6145,  6147,  6016,  6048,  6049,  6044,  6046, 
+        0,  4096,  6144,  6145,  6147,  6016,     0,  4096, 
+     6144,  6145,  6147,  6016,  6048,     0,  4096,  6144, 
+     6145,  6147,  6016,  6048,     0,  4096,  6144,  6145, 
+     6147,  6016,  6048,  6050,     0,  4096,  6144,  6145, 
+     6147,  6016,  6048,     0,  4096,  6144,  6145,  6147, 
+     6016,  6048,  6052,     0,  4096,  6144,  6145,  6147, 
+     6016,  6048,  6052,     0,  4096,  6144,  6145,  6147, 
+     6016,  6048,  6056,  6054,     0,  4096,  6144,  6145, 
+     6147,  6016,  6048,     0,  4096,  6144,  6145,  6147, 
+     6016,  6048,  6056,     0,  4096,  6144,  6145,  6147, 
+     6016,  6048,  6056,     0,  4096,  6144,  6145,  6147, 
+     6016,  6048,  6056,  6058,     0,  4096,  6144,  6145, 
+     6147,  6016,  6048,  6056,     0,  4096,  6144,  6145, 
+     6147,  6016,  6048,  6064,  6060,     0,  4096,  6144, 
+     6145,  6147,  6016,  6048,  6064,  6060,     0,  4096, 
+     6144,  6145,  6147,  6016,  6048,  6064,  6065,  6062, 
+        0,  4096,  6144,  6145,  6147,  6016,  6048,     0, 
+     4096,  6144,  6145,  6147,  6016,  6080,  6064,     0, 
+     4096,  6144,  6145,  6147,  6016,  6080,  6064,     0, 
+     4096,  6144,  6145,  6147,  6016,  6080,  6064,  6066, 
+        0,  4096,  6144,  6145,  6147,  6016,  6080,  6064, 
+        0,  4096,  6144,  6145,  6147,  6016,  6080,  6064, 
+     6068,     0,  4096,  6144,  6145,  6147,  6016,  6080, 
+     6064,  6068,     0,  4096,  6144,  6145,  6147,  6016, 
+     6080,  6064,  6072,  6070,     0,  4096,  6144,  6145, 
+     6147,  6016,  6080,  6064,     0,  4096,  6144,  6145, 
+     6147,  6016,  6080,  6081,  6072,     0,  4096,  6144, 
+     6145,  6147,  6016,  6080,  6081,  6072,     0,  4096, 
+     6144,  6145,  6147,  6016,  6080,  6081,  6072,  6074, 
+        0,  4096,  6144,  6145,  6147,  6016,  6080,  6081, 
+     6072,     0,  4096,  6144,  6145,  6147,  6016,  6080, 
+     6081,  6072,  6076,     0,  4096,  6144,  6145,  6147, 
+     6016,  6080,  6081,  6083,  6076,     0,  4096,  6144, 
+     6145,  6147,  6016,  6080,  6081,  6083,  6076,  6078, 
+        0,  4096,  6144,  6145,  6147,  6016,     0,  4096, 
+     6144,  6145,  6147,  6016,  6080,     0,  4096,  6144, 
+     6145,  6147,  6016,  6080,     0,  4096,  6144,  6145, 
+     6147,  6016,  6080,  6082,     0,  4096,  6144,  6145, 
+     6147,  6016,  6080,     0,  4096,  6144,  6145,  6147, 
+     6016,  6080,  6084,     0,  4096,  6144,  6145,  6147, 
+     6016,  6080,  6084,     0,  4096,  6144,  6145,  6147, 
+     6016,  6080,  6088,  6086,     0,  4096,  6144,  6145, 
+     6147,  6151,  6080,     0,  4096,  6144,  6145,  6147, 
+     6151,  6080,  6088,     0,  4096,  6144,  6145,  6147, 
+     6151,  6080,  6088,     0,  4096,  6144,  6145,  6147, 
+     6151,  6080,  6088,  6090,     0,  4096,  6144,  6145, 
+     6147,  6151,  6080,  6088,     0,  4096,  6144,  6145, 
+     6147,  6151,  6080,  6096,  6092,     0,  4096,  6144, 
+     6145,  6147,  6151,  6080,  6096,  6092,     0,  4096, 
+     6144,  6145,  6147,  6151,  6080,  6096,  6097,  6094, 
+        0,  4096,  6144,  6145,  6147,  6151,  6080,     0, 
+     4096,  6144,  6145,  6147,  6151,  6080,  6096,     0, 
+     4096,  6144,  6145,  6147,  6151,  6080,  6096,     0, 
+     4096,  6144,  6145,  6147,  6151,  6080,  6096,  6098, 
+        0,  4096,  6144,  6145,  6147,  6151,  6080,  6096, 
+        0,  4096,  6144,  6145,  6147,  6151,  6080,  6096, 
+     6100,     0,  4096,  6144,  6145,  6147,  6151,  6080, 
+     6096,  6100,     0,  4096,  6144,  6145,  6147,  6151, 
+     6080,  6096,  6104,  6102,     0,  4096,  6144,  6145, 
+     6147,  6151,  6080,  6096,     0,  4096,  6144,  6145, 
+     6147,  6151,  6080,  6112,  6104,     0,  4096,  6144, 
+     6145,  6147,  6151,  6080,  6112,  6104,     0,  4096, 
+     6144,  6145,  6147,  6151,  6080,  6112,  6104,  6106, 
+        0,  4096,  6144,  6145,  6147,  6151,  6080,  6112, 
+     6104,     0,  4096,  6144,  6145,  6147,  6151,  6080, 
+     6112,  6113,  6108,     0,  4096,  6144,  6145,  6147, 
+     6151,  6080,  6112,  6113,  6108,     0,  4096,  6144, 
+     6145,  6147,  6151,  6080,  6112,  6113,  6108,  6110, 
+        0,  4096,  6144,  6145,  6147,  6151,  6080,     0, 
+     4096,  6144,  6145,  6147,  6151,  6080,  6112,     0, 
+     4096,  6144,  6145,  6147,  6151,  6080,  6112,     0, 
+     4096,  6144,  6145,  6147,  6151,  6080,  6112,  6114, 
+        0,  4096,  6144,  6145,  6147,  6151,  6080,  6112, 
+        0,  4096,  6144,  6145,  6147,  6151,  6080,  6112, 
+     6116,     0,  4096,  6144,  6145,  6147,  6151,  6080, 
+     6112,  6116,     0,  4096,  6144,  6145,  6147,  6151, 
+     6080,  6112,  6120,  6118,     0,  4096,  6144,  6145, 
+     6147,  6151,  6080,  6112,     0,  4096,  6144,  6145, 
+     6147,  6151,  6080,  6112,  6120,     0,  4096,  6144, 
+     6145,  6147,  6151,  6080,  6112,  6120,     0,  4096, 
+     6144,  6145,  6147,  6151,  6080,  6112,  6120,  6122, 
+        0,  4096,  6144,  6145,  6147,  6151,  6080,  6112, 
+     6120,     0,  4096,  6144,  6145,  6147,  6151,  6080, 
+     6112,  6128,  6124,     0,  4096,  6144,  6145,  6147, 
+     6151,  6080,  6112,  6128,  6124,     0,  4096,  6144, 
+     6145,  6147,  6151,  6080,  6112,  6128,  6129,  6126, 
+        0,  4096,  6144,  6145,  6147,  6151,  6159,  6112, 
+        0,  4096,  6144,  6145,  6147,  6151,  6159,  6112, 
+     6128,     0,  4096,  6144,  6145,  6147,  6151,  6159, 
+     6112,  6128,     0,  4096,  6144,  6145,  6147,  6151, 
+     6159,  6112,  6128,  6130,     0,  4096,  6144,  6145, 
+     6147,  6151,  6159,  6112,  6128,     0,  4096,  6144, 
+     6145,  6147,  6151,  6159,  6112,  6128,  6132,     0, 
+     4096,  6144,  6145,  6147,  6151,  6159,  6112,  6128, 
+     6132,     0,  4096,  6144,  6145,  6147,  6151,  6159, 
+     6112,  6128,  6136,  6134,     0,  4096,  6144,  6145, 
+     6147,  6151,  6159,  6112,  6128,     0,  4096,  6144, 
+     6145,  6147,  6151,  6159,  6112,  6128,  6136,     0, 
+     4096,  6144,  6145,  6147,  6151,  6159,  6112,  6128, 
+     6136,     0,  4096,  6144,  6145,  6147,  6151,  6159, 
+     6112,  6128,  6136,  6138,     0,  4096,  6144,  6145, 
+     6147,  6151,  6159,  6112,  6128,  6136,     0,  4096, 
+     6144,  6145,  6147,  6151,  6159,  6112,  6128,  6136, 
+     6140,     0,  4096,  6144,  6145,  6147,  6151,  6159, 
+     6112,  6128,  6136,  6140,     0,  4096,  6144,  6145, 
+     6147,  6151,  6159,  6112,  6128,  6136,  6140,  6142, 
+        0,  4096,     0,  4096,  6144,     0,  4096,  6144, 
+        0,  4096,  6144,  6146,     0,  4096,  6144,     0, 
+     4096,  6144,  6148,     0,  4096,  6144,  6148,     0, 
+     4096,  6144,  6152,  6150,     0,  4096,  6144,     0, 
+     4096,  6144,  6152,     0,  4096,  6144,  6152,     0, 
+     4096,  6144,  6152,  6154,     0,  4096,  6144,  6152, 
+        0,  4096,  6144,  6160,  6156,     0,  4096,  6144, 
+     6160,  6156,     0,  4096,  6144,  6160,  6161,  6158, 
+        0,  4096,  6144,     0,  4096,  6144,  6160,     0, 
+     4096,  6144,  6160,     0,  4096,  6144,  6160,  6162, 
+        0,  4096,  6144,  6160,     0,  4096,  6144,  6160, 
+     6164,     0,  4096,  6144,  6160,  6164,     0,  4096, 
+     6144,  6160,  6168,  6166,     0,  4096,  6144,  6160, 
+        0,  4096,  6144,  6176,  6168,     0,  4096,  6144, 
+     6176,  6168,     0,  4096,  6144,  6176,  6168,  6170, 
+        0,  4096,  6144,  6176,  6168,     0,  4096,  6144, 
+     6176,  6177,  6172,     0,  4096,  6144,  6176,  6177, 
+     6172,     0,  4096,  6144,  6176,  6177,  6172,  6174, 
+        0,  4096,  6144,     0,  4096,  6144,  6176,     0, 
+     4096,  6144,  6176,     0,  4096,  6144,  6176,  6178, 
+        0,  4096,  6144,  6176,     0,  4096,  6144,  6176, 
+     6180,     0,  4096,  6144,  6176,  6180,     0,  4096, 
+     6144,  6176,  6184,  6182,     0,  4096,  6144,  6176, 
+        0,  4096,  6144,  6176,  6184,     0,  4096,  6144, 
+     6176,  6184,     0,  4096,  6144,  6176,  6184,  6186, 
+        0,  4096,  6144,  6176,  6184,     0,  4096,  6144, 
+     6176,  6192,  6188,     0,  4096,  6144,  6176,  6192, 
+     6188,     0,  4096,  6144,  6176,  6192,  6193,  6190, 
+        0,  4096,  6144,  6176,     0,  4096,  6144,  6208, 
+     6192,     0,  4096,  6144,  6208,  6192,     0,  4096, 
+     6144,  6208,  6192,  6194,     0,  4096,  6144,  6208, 
+     6192,     0,  4096,  6144,  6208,  6192,  6196,     0, 
+     4096,  6144,  6208,  6192,  6196,     0,  4096,  6144, 
+     6208,  6192,  6200,  6198,     0,  4096,  6144,  6208, 
+     6192,     0,  4096,  6144,  6208,  6209,  6200,     0, 
+     4096,  6144,  6208,  6209,  6200,     0,  4096,  6144, 
+     6208,  6209,  6200,  6202,     0,  4096,  6144,  6208, 
+     6209,  6200,     0,  4096,  6144,  6208,  6209,  6200, 
+     6204,     0,  4096,  6144,  6208,  6209,  6211,  6204, 
+        0,  4096,  6144,  6208,  6209,  6211,  6204,  6206, 
+        0,  4096,  6144,     0,  4096,  6144,  6208,     0, 
+     4096,  6144,  6208,     0,  4096,  6144,  6208,  6210, 
+        0,  4096,  6144,  6208,     0,  4096,  6144,  6208, 
+     6212,     0,  4096,  6144,  6208,  6212,     0,  4096, 
+     6144,  6208,  6216,  6214,     0,  4096,  6144,  6208, 
+        0,  4096,  6144,  6208,  6216,     0,  4096,  6144, 
+     6208,  6216,     0,  4096,  6144,  6208,  6216,  6218, 
+        0,  4096,  6144,  6208,  6216,     0,  4096,  6144, 
+     6208,  6224,  6220,     0,  4096,  6144,  6208,  6224, 
+     6220,     0,  4096,  6144,  6208,  6224,  6225,  6222, 
+        0,  4096,  6144,  6208,     0,  4096,  6144,  6208, 
+     6224,     0,  4096,  6144,  6208,  6224,     0,  4096, 
+     6144,  6208,  6224,  6226,     0,  4096,  6144,  6208, 
+     6224,     0,  4096,  6144,  6208,  6224,  6228,     0, 
+     4096,  6144,  6208,  6224,  6228,     0,  4096,  6144, 
+     6208,  6224,  6232,  6230,     0,  4096,  6144,  6208, 
+     6224,     0,  4096,  6144,  6208,  6240,  6232,     0, 
+     4096,  6144,  6208,  6240,  6232,     0,  4096,  6144, 
+     6208,  6240,  6232,  6234,     0,  4096,  6144,  6208, 
+     6240,  6232,     0,  4096,  6144,  6208,  6240,  6241, 
+     6236,     0,  4096,  6144,  6208,  6240,  6241,  6236, 
+        0,  4096,  6144,  6208,  6240,  6241,  6236,  6238, 
+        0,  4096,  6144,  6208,     0,  4096,  6144,  6272, 
+     6240,     0,  4096,  6144,  6272,  6240,     0,  4096, 
+     6144,  6272,  6240,  6242,     0,  4096,  6144,  6272, 
+     6240,     0,  4096,  6144,  6272,  6240,  6244,     0, 
+     4096,  6144,  6272,  6240,  6244,     0,  4096,  6144, 
+     6272,  6240,  6248,  6246,     0,  4096,  6144,  6272, 
+     6240,     0,  4096,  6144,  6272,  6240,  6248,     0, 
+     4096,  6144,  6272,  6240,  6248,     0,  4096,  6144, 
+     6272,  6240,  6248,  6250,     0,  4096,  6144,  6272, 
+     6240,  6248,     0,  4096,  6144,  6272,  6240,  6256, 
+     6252,     0,  4096,  6144,  6272,  6240,  6256,  6252, 
+        0,  4096,  6144,  6272,  6240,  6256,  6257,  6254, 
+        0,  4096,  6144,  6272,  6240,     0,  4096,  6144, 
+     6272,  6273,  6256,     0,  4096,  6144,  6272,  6273, 
+     6256,     0,  4096,  6144,  6272,  6273,  6256,  6258, 
+        0,  4096,  6144,  6272,  6273,  6256,     0,  4096, 
+     6144,  6272,  6273,  6256,  6260,     0,  4096,  6144, 
+     6272,  6273,  6256,  6260,     0,  4096,  6144,  6272, 
+     6273,  6256,  6264,  6262,     0,  4096,  6144,  6272, 
+     6273,  6256,     0,  4096,  6144,  6272,  6273,  6256, 
+     6264,     0,  4096,  6144,  6272,  6273,  6275,  6264, 
+        0,  4096,  6144,  6272,  6273,  6275,  6264,  6266, 
+        0,  4096,  6144,  6272,  6273,  6275,  6264,     0, 
+     4096,  6144,  6272,  6273,  6275,  6264,  6268,     0, 
+     4096,  6144,  6272,  6273,  6275,  6264,  6268,     0, 
+     4096,  6144,  6272,  6273,  6275,  6264,  6268,  6270, 
+        0,  4096,  6144,     0,  4096,  6144,  6272,     0, 
+     4096,  6144,  6272,     0,  4096,  6144,  6272,  6274, 
+        0,  4096,  6144,  6272,     0,  4096,  6144,  6272, 
+     6276,     0,  4096,  6144,  6272,  6276,     0,  4096, 
+     6144,  6272,  6280,  6278,     0,  4096,  6144,  6272, 
+        0,  4096,  6144,  6272,  6280,     0,  4096,  6144, 
+     6272,  6280,     0,  4096,  6144,  6272,  6280,  6282, 
+        0,  4096,  6144,  6272,  6280,     0,  4096,  6144, 
+     6272,  6288,  6284,     0,  4096,  6144,  6272,  6288, 
+     6284,     0,  4096,  6144,  6272,  6288,  6289,  6286, 
+        0,  4096,  6144,  6272,     0,  4096,  6144,  6272, 
+     6288,     0,  4096,  6144,  6272,  6288,     0,  4096, 
+     6144,  6272,  6288,  6290,     0,  4096,  6144,  6272, 
+     6288,     0,  4096,  6144,  6272,  6288,  6292,     0, 
+     4096,  6144,  6272,  6288,  6292,     0,  4096,  6144, 
+     6272,  6288,  6296,  6294,     0,  4096,  6144,  6272, 
+     6288,     0,  4096,  6144,  6272,  6304,  6296,     0, 
+     4096,  6144,  6272,  6304,  6296,     0,  4096,  6144, 
+     6272,  6304,  6296,  6298,     0,  4096,  6144,  6272, 
+     6304,  6296,     0,  4096,  6144,  6272,  6304,  6305, 
+     6300,     0,  4096,  6144,  6272,  6304,  6305,  6300, 
+        0,  4096,  6144,  6272,  6304,  6305,  6300,  6302, 
+        0,  4096,  6144,  6272,     0,  4096,  6144,  6272, 
+     6304,     0,  4096,  6144,  6272,  6304,     0,  4096, 
+     6144,  6272,  6304,  6306,     0,  4096,  6144,  6272, 
+     6304,     0,  4096,  6144,  6272,  6304,  6308,     0, 
+     4096,  6144,  6272,  6304,  6308,     0,  4096,  6144, 
+     6272,  6304,  6312,  6310,     0,  4096,  6144,  6272, 
+     6304,     0,  4096,  6144,  6272,  6304,  6312,     0, 
+     4096,  6144,  6272,  6304,  6312,     0,  4096,  6144, 
+     6272,  6304,  6312,  6314,     0,  4096,  6144,  6272, 
+     6304,  6312,     0,  4096,  6144,  6272,  6304,  6320, 
+     6316,     0,  4096,  6144,  6272,  6304,  6320,  6316, 
+        0,  4096,  6144,  6272,  6304,  6320,  6321,  6318, 
+        0,  4096,  6144,  6272,  6304,     0,  4096,  6144, 
+     6272,  6336,  6320,     0,  4096,  6144,  6272,  6336, 
+     6320,     0,  4096,  6144,  6272,  6336,  6320,  6322, 
+        0,  4096,  6144,  6272,  6336,  6320,     0,  4096, 
+     6144,  6272,  6336,  6320,  6324,     0,  4096,  6144, 
+     6272,  6336,  6320,  6324,     0,  4096,  6144,  6272, 
+     6336,  6320,  6328,  6326,     0,  4096,  6144,  6272, 
+     6336,  6320,     0,  4096,  6144,  6272,  6336,  6337, 
+     6328,     0,  4096,  6144,  6272,  6336,  6337,  6328, 
+        0,  4096,  6144,  6272,  6336,  6337,  6328,  6330, 
+        0,  4096,  6144,  6272,  6336,  6337,  6328,     0, 
+     4096,  6144,  6272,  6336,  6337,  6328,  6332,     0, 
+     4096,  6144,  6272,  6336,  6337,  6339,  6332,     0, 
+     4096,  6144,  6272,  6336,  6337,  6339,  6332,  6334, 
+        0,  4096,  6144,  6272,     0,  4096,  6144,  6400, 
+     6336,     0,  4096,  6144,  6400,  6336,     0,  4096, 
+     6144,  6400,  6336,  6338,     0,  4096,  6144,  6400, 
+     6336,     0,  4096,  6144,  6400,  6336,  6340,     0, 
+     4096,  6144,  6400,  6336,  6340,     0,  4096,  6144, 
+     6400,  6336,  6344,  6342,     0,  4096,  6144,  6400, 
+     6336,     0,  4096,  6144,  6400,  6336,  6344,     0, 
+     4096,  6144,  6400,  6336,  6344,     0,  4096,  6144, 
+     6400,  6336,  6344,  6346,     0,  4096,  6144,  6400, 
+     6336,  6344,     0,  4096,  6144,  6400,  6336,  6352, 
+     6348,     0,  4096,  6144,  6400,  6336,  6352,  6348, 
+        0,  4096,  6144,  6400,  6336,  6352,  6353,  6350, 
+        0,  4096,  6144,  6400,  6336,     0,  4096,  6144, 
+     6400,  6336,  6352,     0,  4096,  6144,  6400,  6336, 
+     6352,     0,  4096,  6144,  6400,  6336,  6352,  6354, 
+        0,  4096,  6144,  6400,  6336,  6352,     0,  4096, 
+     6144,  6400,  6336,  6352,  6356,     0,  4096,  6144, 
+     6400,  6336,  6352,  6356,     0,  4096,  6144,  6400, 
+     6336,  6352,  6360,  6358,     0,  4096,  6144,  6400, 
+     6336,  6352,     0,  4096,  6144,  6400,  6336,  6368, 
+     6360,     0,  4096,  6144,  6400,  6336,  6368,  6360, 
+        0,  4096,  6144,  6400,  6336,  6368,  6360,  6362, 
+        0,  4096,  6144,  6400,  6336,  6368,  6360,     0, 
+     4096,  6144,  6400,  6336,  6368,  6369,  6364,     0, 
+     4096,  6144,  6400,  6336,  6368,  6369,  6364,     0, 
+     4096,  6144,  6400,  6336,  6368,  6369,  6364,  6366, 
+        0,  4096,  6144,  6400,  6336,     0,  4096,  6144, 
+     6400,  6401,  6368,     0,  4096,  6144,  6400,  6401, 
+     6368,     0,  4096,  6144,  6400,  6401,  6368,  6370, 
+        0,  4096,  6144,  6400,  6401,  6368,     0,  4096, 
+     6144,  6400,  6401,  6368,  6372,     0,  4096,  6144, 
+     6400,  6401,  6368,  6372,     0,  4096,  6144,  6400, 
+     6401,  6368,  6376,  6374,     0,  4096,  6144,  6400, 
+     6401,  6368,     0,  4096,  6144,  6400,  6401,  6368, 
+     6376,     0,  4096,  6144,  6400,  6401,  6368,  6376, 
+        0,  4096,  6144,  6400,  6401,  6368,  6376,  6378, 
+        0,  4096,  6144,  6400,  6401,  6368,  6376,     0, 
+     4096,  6144,  6400,  6401,  6368,  6384,  6380,     0, 
+     4096,  6144,  6400,  6401,  6368,  6384,  6380,     0, 
+     4096,  6144,  6400,  6401,  6368,  6384,  6385,  6382, 
+        0,  4096,  6144,  6400,  6401,  6368,     0,  4096, 
+     6144,  6400,  6401,  6368,  6384,     0,  4096,  6144, 
+     6400,  6401,  6403,  6384,     0,  4096,  6144,  6400, 
+     6401,  6403,  6384,  6386,     0,  4096,  6144,  6400, 
+     6401,  6403,  6384,     0,  4096,  6144,  6400,  6401, 
+     6403,  6384,  6388,     0,  4096,  6144,  6400,  6401, 
+     6403,  6384,  6388,     0,  4096,  6144,  6400,  6401, 
+     6403,  6384,  6392,  6390,     0,  4096,  6144,  6400, 
+     6401,  6403,  6384,     0,  4096,  6144,  6400,  6401, 
+     6403,  6384,  6392,     0,  4096,  6144,  6400,  6401, 
+     6403,  6384,  6392,     0,  4096,  6144,  6400,  6401, 
+     6403,  6384,  6392,  6394,     0,  4096,  6144,  6400, 
+     6401,  6403,  6407,  6392,     0,  4096,  6144,  6400, 
+     6401,  6403,  6407,  6392,  6396,     0,  4096,  6144, 
+     6400,  6401,  6403,  6407,  6392,  6396,     0,  4096, 
+     6144,  6400,  6401,  6403,  6407,  6392,  6396,  6398, 
+        0,  4096,  6144,     0,  4096,  6144,  6400,     0, 
+     4096,  6144,  6400,     0,  4096,  6144,  6400,  6402, 
+        0,  4096,  6144,  6400,     0,  4096,  6144,  6400, 
+     6404,     0,  4096,  6144,  6400,  6404,     0,  4096, 
+     6144,  6400,  6408,  6406,     0,  4096,  6144,  6400, 
+        0,  4096,  6144,  6400,  6408,     0,  4096,  6144, 
+     6400,  6408,     0,  4096,  6144,  6400,  6408,  6410, 
+        0,  4096,  6144,  6400,  6408,     0,  4096,  6144, 
+     6400,  6416,  6412,     0,  4096,  6144,  6400,  6416, 
+     6412,     0,  4096,  6144,  6400,  6416,  6417,  6414, 
+        0,  4096,  6144,  6400,     0,  4096,  6144,  6400, 
+     6416,     0,  4096,  6144,  6400,  6416,     0,  4096, 
+     6144,  6400,  6416,  6418,     0,  4096,  6144,  6400, 
+     6416,     0,  4096,  6144,  6400,  6416,  6420,     0, 
+     4096,  6144,  6400,  6416,  6420,     0,  4096,  6144, 
+     6400,  6416,  6424,  6422,     0,  4096,  6144,  6400, 
+     6416,     0,  4096,  6144,  6400,  6432,  6424,     0, 
+     4096,  6144,  6400,  6432,  6424,     0,  4096,  6144, 
+     6400,  6432,  6424,  6426,     0,  4096,  6144,  6400, 
+     6432,  6424,     0,  4096,  6144,  6400,  6432,  6433, 
+     6428,     0,  4096,  6144,  6400,  6432,  6433,  6428, 
+        0,  4096,  6144,  6400,  6432,  6433,  6428,  6430, 
+        0,  4096,  6144,  6400,     0,  4096,  6144,  6400, 
+     6432,     0,  4096,  6144,  6400,  6432,     0,  4096, 
+     6144,  6400,  6432,  6434,     0,  4096,  6144,  6400, 
+     6432,     0,  4096,  6144,  6400,  6432,  6436,     0, 
+     4096,  6144,  6400,  6432,  6436,     0,  4096,  6144, 
+     6400,  6432,  6440,  6438,     0,  4096,  6144,  6400, 
+     6432,     0,  4096,  6144,  6400,  6432,  6440,     0, 
+     4096,  6144,  6400,  6432,  6440,     0,  4096,  6144, 
+     6400,  6432,  6440,  6442,     0,  4096,  6144,  6400, 
+     6432,  6440,     0,  4096,  6144,  6400,  6432,  6448, 
+     6444,     0,  4096,  6144,  6400,  6432,  6448,  6444, 
+        0,  4096,  6144,  6400,  6432,  6448,  6449,  6446, 
+        0,  4096,  6144,  6400,  6432,     0,  4096,  6144, 
+     6400,  6464,  6448,     0,  4096,  6144,  6400,  6464, 
+     6448,     0,  4096,  6144,  6400,  6464,  6448,  6450, 
+        0,  4096,  6144,  6400,  6464,  6448,     0,  4096, 
+     6144,  6400,  6464,  6448,  6452,     0,  4096,  6144, 
+     6400,  6464,  6448,  6452,     0,  4096,  6144,  6400, 
+     6464,  6448,  6456,  6454,     0,  4096,  6144,  6400, 
+     6464,  6448,     0,  4096,  6144,  6400,  6464,  6465, 
+     6456,     0,  4096,  6144,  6400,  6464,  6465,  6456, 
+        0,  4096,  6144,  6400,  6464,  6465,  6456,  6458, 
+        0,  4096,  6144,  6400,  6464,  6465,  6456,     0, 
+     4096,  6144,  6400,  6464,  6465,  6456,  6460,     0, 
+     4096,  6144,  6400,  6464,  6465,  6467,  6460,     0, 
+     4096,  6144,  6400,  6464,  6465,  6467,  6460,  6462, 
+        0,  4096,  6144,  6400,     0,  4096,  6144,  6400, 
+     6464,     0,  4096,  6144,  6400,  6464,     0,  4096, 
+     6144,  6400,  6464,  6466,     0,  4096,  6144,  6400, 
+     6464,     0,  4096,  6144,  6400,  6464,  6468,     0, 
+     4096,  6144,  6400,  6464,  6468,     0,  4096,  6144, 
+     6400,  6464,  6472,  6470,     0,  4096,  6144,  6400, 
+     6464,     0,  4096,  6144,  6400,  6464,  6472,     0, 
+     4096,  6144,  6400,  6464,  6472,     0,  4096,  6144, 
+     6400,  6464,  6472,  6474,     0,  4096,  6144,  6400, 
+     6464,  6472,     0,  4096,  6144,  6400,  6464,  6480, 
+     6476,     0,  4096,  6144,  6400,  6464,  6480,  6476, 
+        0,  4096,  6144,  6400,  6464,  6480,  6481,  6478, 
+        0,  4096,  6144,  6400,  6464,     0,  4096,  6144, 
+     6400,  6464,  6480,     0,  4096,  6144,  6400,  6464, 
+     6480,     0,  4096,  6144,  6400,  6464,  6480,  6482, 
+        0,  4096,  6144,  6400,  6464,  6480,     0,  4096, 
+     6144,  6400,  6464,  6480,  6484,     0,  4096,  6144, 
+     6400,  6464,  6480,  6484,     0,  4096,  6144,  6400, 
+     6464,  6480,  6488,  6486,     0,  4096,  6144,  6400, 
+     6464,  6480,     0,  4096,  6144,  6400,  6464,  6496, 
+     6488,     0,  4096,  6144,  6400,  6464,  6496,  6488, 
+        0,  4096,  6144,  6400,  6464,  6496,  6488,  6490, 
+        0,  4096,  6144,  6400,  6464,  6496,  6488,     0, 
+     4096,  6144,  6400,  6464,  6496,  6497,  6492,     0, 
+     4096,  6144,  6400,  6464,  6496,  6497,  6492,     0, 
+     4096,  6144,  6400,  6464,  6496,  6497,  6492,  6494, 
+        0,  4096,  6144,  6400,  6464,     0,  4096,  6144, 
+     6400,  6528,  6496,     0,  4096,  6144,  6400,  6528, 
+     6496,     0,  4096,  6144,  6400,  6528,  6496,  6498, 
+        0,  4096,  6144,  6400,  6528,  6496,     0,  4096, 
+     6144,  6400,  6528,  6496,  6500,     0,  4096,  6144, 
+     6400,  6528,  6496,  6500,     0,  4096,  6144,  6400, 
+     6528,  6496,  6504,  6502,     0,  4096,  6144,  6400, 
+     6528,  6496,     0,  4096,  6144,  6400,  6528,  6496, 
+     6504,     0,  4096,  6144,  6400,  6528,  6496,  6504, 
+        0,  4096,  6144,  6400,  6528,  6496,  6504,  6506, 
+        0,  4096,  6144,  6400,  6528,  6496,  6504,     0, 
+     4096,  6144,  6400,  6528,  6496,  6512,  6508,     0, 
+     4096,  6144,  6400,  6528,  6496,  6512,  6508,     0, 
+     4096,  6144,  6400,  6528,  6496,  6512,  6513,  6510, 
+        0,  4096,  6144,  6400,  6528,  6496,     0,  4096, 
+     6144,  6400,  6528,  6529,  6512,     0,  4096,  6144, 
+     6400,  6528,  6529,  6512,     0,  4096,  6144,  6400, 
+     6528,  6529,  6512,  6514,     0,  4096,  6144,  6400, 
+     6528,  6529,  6512,     0,  4096,  6144,  6400,  6528, 
+     6529,  6512,  6516,     0,  4096,  6144,  6400,  6528, 
+     6529,  6512,  6516,     0,  4096,  6144,  6400,  6528, 
+     6529,  6512,  6520,  6518,     0,  4096,  6144,  6400, 
+     6528,  6529,  6512,     0,  4096,  6144,  6400,  6528, 
+     6529,  6512,  6520,     0,  4096,  6144,  6400,  6528, 
+     6529,  6531,  6520,     0,  4096,  6144,  6400,  6528, 
+     6529,  6531,  6520,  6522,     0,  4096,  6144,  6400, 
+     6528,  6529,  6531,  6520,     0,  4096,  6144,  6400, 
+     6528,  6529,  6531,  6520,  6524,     0,  4096,  6144, 
+     6400,  6528,  6529,  6531,  6520,  6524,     0,  4096, 
+     6144,  6400,  6528,  6529,  6531,  6520,  6524,  6526, 
+        0,  4096,  6144,  6400,     0,  4096,  6144,  6656, 
+     6528,     0,  4096,  6144,  6656,  6528,     0,  4096, 
+     6144,  6656,  6528,  6530,     0,  4096,  6144,  6656, 
+     6528,     0,  4096,  6144,  6656,  6528,  6532,     0, 
+     4096,  6144,  6656,  6528,  6532,     0,  4096,  6144, 
+     6656,  6528,  6536,  6534,     0,  4096,  6144,  6656, 
+     6528,     0,  4096,  6144,  6656,  6528,  6536,     0, 
+     4096,  6144,  6656,  6528,  6536,     0,  4096,  6144, 
+     6656,  6528,  6536,  6538,     0,  4096,  6144,  6656, 
+     6528,  6536,     0,  4096,  6144,  6656,  6528,  6544, 
+     6540,     0,  4096,  6144,  6656,  6528,  6544,  6540, 
+        0,  4096,  6144,  6656,  6528,  6544,  6545,  6542, 
+        0,  4096,  6144,  6656,  6528,     0,  4096,  6144, 
+     6656,  6528,  6544,     0,  4096,  6144,  6656,  6528, 
+     6544,     0,  4096,  6144,  6656,  6528,  6544,  6546, 
+        0,  4096,  6144,  6656,  6528,  6544,     0,  4096, 
+     6144,  6656,  6528,  6544,  6548,     0,  4096,  6144, 
+     6656,  6528,  6544,  6548,     0,  4096,  6144,  6656, 
+     6528,  6544,  6552,  6550,     0,  4096,  6144,  6656, 
+     6528,  6544,     0,  4096,  6144,  6656,  6528,  6560, 
+     6552,     0,  4096,  6144,  6656,  6528,  6560,  6552, 
+        0,  4096,  6144,  6656,  6528,  6560,  6552,  6554, 
+        0,  4096,  6144,  6656,  6528,  6560,  6552,     0, 
+     4096,  6144,  6656,  6528,  6560,  6561,  6556,     0, 
+     4096,  6144,  6656,  6528,  6560,  6561,  6556,     0, 
+     4096,  6144,  6656,  6528,  6560,  6561,  6556,  6558, 
+        0,  4096,  6144,  6656,  6528,     0,  4096,  6144, 
+     6656,  6528,  6560,     0,  4096,  6144,  6656,  6528, 
+     6560,     0,  4096,  6144,  6656,  6528,  6560,  6562, 
+        0,  4096,  6144,  6656,  6528,  6560,     0,  4096, 
+     6144,  6656,  6528,  6560,  6564,     0,  4096,  6144, 
+     6656,  6528,  6560,  6564,     0,  4096,  6144,  6656, 
+     6528,  6560,  6568,  6566,     0,  4096,  6144,  6656, 
+     6528,  6560,     0,  4096,  6144,  6656,  6528,  6560, 
+     6568,     0,  4096,  6144,  6656,  6528,  6560,  6568, 
+        0,  4096,  6144,  6656,  6528,  6560,  6568,  6570, 
+        0,  4096,  6144,  6656,  6528,  6560,  6568,     0, 
+     4096,  6144,  6656,  6528,  6560,  6576,  6572,     0, 
+     4096,  6144,  6656,  6528,  6560,  6576,  6572,     0, 
+     4096,  6144,  6656,  6528,  6560,  6576,  6577,  6574, 
+        0,  4096,  6144,  6656,  6528,  6560,     0,  4096, 
+     6144,  6656,  6528,  6592,  6576,     0,  4096,  6144, 
+     6656,  6528,  6592,  6576,     0,  4096,  6144,  6656, 
+     6528,  6592,  6576,  6578,     0,  4096,  6144,  6656, 
+     6528,  6592,  6576,     0,  4096,  6144,  6656,  6528, 
+     6592,  6576,  6580,     0,  4096,  6144,  6656,  6528, 
+     6592,  6576,  6580,     0,  4096,  6144,  6656,  6528, 
+     6592,  6576,  6584,  6582,     0,  4096,  6144,  6656, 
+     6528,  6592,  6576,     0,  4096,  6144,  6656,  6528, 
+     6592,  6593,  6584,     0,  4096,  6144,  6656,  6528, 
+     6592,  6593,  6584,     0,  4096,  6144,  6656,  6528, 
+     6592,  6593,  6584,  6586,     0,  4096,  6144,  6656, 
+     6528,  6592,  6593,  6584,     0,  4096,  6144,  6656, 
+     6528,  6592,  6593,  6584,  6588,     0,  4096,  6144, 
+     6656,  6528,  6592,  6593,  6595,  6588,     0,  4096, 
+     6144,  6656,  6528,  6592,  6593,  6595,  6588,  6590, 
+        0,  4096,  6144,  6656,  6528,     0,  4096,  6144, 
+     6656,  6657,  6592,     0,  4096,  6144,  6656,  6657, 
+     6592,     0,  4096,  6144,  6656,  6657,  6592,  6594, 
+        0,  4096,  6144,  6656,  6657,  6592,     0,  4096, 
+     6144,  6656,  6657,  6592,  6596,     0,  4096,  6144, 
+     6656,  6657,  6592,  6596,     0,  4096,  6144,  6656, 
+     6657,  6592,  6600,  6598,     0,  4096,  6144,  6656, 
+     6657,  6592,     0,  4096,  6144,  6656,  6657,  6592, 
+     6600,     0,  4096,  6144,  6656,  6657,  6592,  6600, 
+        0,  4096,  6144,  6656,  6657,  6592,  6600,  6602, 
+        0,  4096,  6144,  6656,  6657,  6592,  6600,     0, 
+     4096,  6144,  6656,  6657,  6592,  6608,  6604,     0, 
+     4096,  6144,  6656,  6657,  6592,  6608,  6604,     0, 
+     4096,  6144,  6656,  6657,  6592,  6608,  6609,  6606, 
+        0,  4096,  6144,  6656,  6657,  6592,     0,  4096, 
+     6144,  6656,  6657,  6592,  6608,     0,  4096,  6144, 
+     6656,  6657,  6592,  6608,     0,  4096,  6144,  6656, 
+     6657,  6592,  6608,  6610,     0,  4096,  6144,  6656, 
+     6657,  6592,  6608,     0,  4096,  6144,  6656,  6657, 
+     6592,  6608,  6612,     0,  4096,  6144,  6656,  6657, 
+     6592,  6608,  6612,     0,  4096,  6144,  6656,  6657, 
+     6592,  6608,  6616,  6614,     0,  4096,  6144,  6656, 
+     6657,  6592,  6608,     0,  4096,  6144,  6656,  6657, 
+     6592,  6624,  6616,     0,  4096,  6144,  6656,  6657, 
+     6592,  6624,  6616,     0,  4096,  6144,  6656,  6657, 
+     6592,  6624,  6616,  6618,     0,  4096,  6144,  6656, 
+     6657,  6592,  6624,  6616,     0,  4096,  6144,  6656, 
+     6657,  6592,  6624,  6625,  6620,     0,  4096,  6144, 
+     6656,  6657,  6592,  6624,  6625,  6620,     0,  4096, 
+     6144,  6656,  6657,  6592,  6624,  6625,  6620,  6622, 
+        0,  4096,  6144,  6656,  6657,  6592,     0,  4096, 
+     6144,  6656,  6657,  6592,  6624,     0,  4096,  6144, 
+     6656,  6657,  6659,  6624,     0,  4096,  6144,  6656, 
+     6657,  6659,  6624,  6626,     0,  4096,  6144,  6656, 
+     6657,  6659,  6624,     0,  4096,  6144,  6656,  6657, 
+     6659,  6624,  6628,     0,  4096,  6144,  6656,  6657, 
+     6659,  6624,  6628,     0,  4096,  6144,  6656,  6657, 
+     6659,  6624,  6632,  6630,     0,  4096,  6144,  6656, 
+     6657,  6659,  6624,     0,  4096,  6144,  6656,  6657, 
+     6659,  6624,  6632,     0,  4096,  6144,  6656,  6657, 
+     6659,  6624,  6632,     0,  4096,  6144,  6656,  6657, 
+     6659,  6624,  6632,  6634,     0,  4096,  6144,  6656, 
+     6657,  6659,  6624,  6632,     0,  4096,  6144,  6656, 
+     6657,  6659,  6624,  6640,  6636,     0,  4096,  6144, 
+     6656,  6657,  6659,  6624,  6640,  6636,     0,  4096, 
+     6144,  6656,  6657,  6659,  6624,  6640,  6641,  6638, 
+        0,  4096,  6144,  6656,  6657,  6659,  6624,     0, 
+     4096,  6144,  6656,  6657,  6659,  6624,  6640,     0, 
+     4096,  6144,  6656,  6657,  6659,  6624,  6640,     0, 
+     4096,  6144,  6656,  6657,  6659,  6624,  6640,  6642, 
+        0,  4096,  6144,  6656,  6657,  6659,  6663,  6640, 
+        0,  4096,  6144,  6656,  6657,  6659,  6663,  6640, 
+     6644,     0,  4096,  6144,  6656,  6657,  6659,  6663, 
+     6640,  6644,     0,  4096,  6144,  6656,  6657,  6659, 
+     6663,  6640,  6648,  6646,     0,  4096,  6144,  6656, 
+     6657,  6659,  6663,  6640,     0,  4096,  6144,  6656, 
+     6657,  6659,  6663,  6640,  6648,     0,  4096,  6144, 
+     6656,  6657,  6659,  6663,  6640,  6648,     0,  4096, 
+     6144,  6656,  6657,  6659,  6663,  6640,  6648,  6650, 
+        0,  4096,  6144,  6656,  6657,  6659,  6663,  6640, 
+     6648,     0,  4096,  6144,  6656,  6657,  6659,  6663, 
+     6640,  6648,  6652,     0,  4096,  6144,  6656,  6657, 
+     6659,  6663,  6640,  6648,  6652,     0,  4096,  6144, 
+     6656,  6657,  6659,  6663,  6640,  6648,  6652,  6654, 
+        0,  4096,  6144,     0,  4096,  6144,  6656,     0, 
+     4096,  6144,  6656,     0,  4096,  6144,  6656,  6658, 
+        0,  4096,  6144,  6656,     0,  4096,  6144,  6656, 
+     6660,     0,  4096,  6144,  6656,  6660,     0,  4096, 
+     6144,  6656,  6664,  6662,     0,  4096,  6144,  6656, 
+        0,  4096,  6144,  6656,  6664,     0,  4096,  6144, 
+     6656,  6664,     0,  4096,  6144,  6656,  6664,  6666, 
+        0,  4096,  6144,  6656,  6664,     0,  4096,  6144, 
+     6656,  6672,  6668,     0,  4096,  6144,  6656,  6672, 
+     6668,     0,  4096,  6144,  6656,  6672,  6673,  6670, 
+        0,  4096,  6144,  6656,     0,  4096,  6144,  6656, 
+     6672,     0,  4096,  6144,  6656,  6672,     0,  4096, 
+     6144,  6656,  6672,  6674,     0,  4096,  6144,  6656, 
+     6672,     0,  4096,  6144,  6656,  6672,  6676,     0, 
+     4096,  6144,  6656,  6672,  6676,     0,  4096,  6144, 
+     6656,  6672,  6680,  6678,     0,  4096,  6144,  6656, 
+     6672,     0,  4096,  6144,  6656,  6688,  6680,     0, 
+     4096,  6144,  6656,  6688,  6680,     0,  4096,  6144, 
+     6656,  6688,  6680,  6682,     0,  4096,  6144,  6656, 
+     6688,  6680,     0,  4096,  6144,  6656,  6688,  6689, 
+     6684,     0,  4096,  6144,  6656,  6688,  6689,  6684, 
+        0,  4096,  6144,  6656,  6688,  6689,  6684,  6686, 
+        0,  4096,  6144,  6656,     0,  4096,  6144,  6656, 
+     6688,     0,  4096,  6144,  6656,  6688,     0,  4096, 
+     6144,  6656,  6688,  6690,     0,  4096,  6144,  6656, 
+     6688,     0,  4096,  6144,  6656,  6688,  6692,     0, 
+     4096,  6144,  6656,  6688,  6692,     0,  4096,  6144, 
+     6656,  6688,  6696,  6694,     0,  4096,  6144,  6656, 
+     6688,     0,  4096,  6144,  6656,  6688,  6696,     0, 
+     4096,  6144,  6656,  6688,  6696,     0,  4096,  6144, 
+     6656,  6688,  6696,  6698,     0,  4096,  6144,  6656, 
+     6688,  6696,     0,  4096,  6144,  6656,  6688,  6704, 
+     6700,     0,  4096,  6144,  6656,  6688,  6704,  6700, 
+        0,  4096,  6144,  6656,  6688,  6704,  6705,  6702, 
+        0,  4096,  6144,  6656,  6688,     0,  4096,  6144, 
+     6656,  6720,  6704,     0,  4096,  6144,  6656,  6720, 
+     6704,     0,  4096,  6144,  6656,  6720,  6704,  6706, 
+        0,  4096,  6144,  6656,  6720,  6704,     0,  4096, 
+     6144,  6656,  6720,  6704,  6708,     0,  4096,  6144, 
+     6656,  6720,  6704,  6708,     0,  4096,  6144,  6656, 
+     6720,  6704,  6712,  6710,     0,  4096,  6144,  6656, 
+     6720,  6704,     0,  4096,  6144,  6656,  6720,  6721, 
+     6712,     0,  4096,  6144,  6656,  6720,  6721,  6712, 
+        0,  4096,  6144,  6656,  6720,  6721,  6712,  6714, 
+        0,  4096,  6144,  6656,  6720,  6721,  6712,     0, 
+     4096,  6144,  6656,  6720,  6721,  6712,  6716,     0, 
+     4096,  6144,  6656,  6720,  6721,  6723,  6716,     0, 
+     4096,  6144,  6656,  6720,  6721,  6723,  6716,  6718, 
+        0,  4096,  6144,  6656,     0,  4096,  6144,  6656, 
+     6720,     0,  4096,  6144,  6656,  6720,     0,  4096, 
+     6144,  6656,  6720,  6722,     0,  4096,  6144,  6656, 
+     6720,     0,  4096,  6144,  6656,  6720,  6724,     0, 
+     4096,  6144,  6656,  6720,  6724,     0,  4096,  6144, 
+     6656,  6720,  6728,  6726,     0,  4096,  6144,  6656, 
+     6720,     0,  4096,  6144,  6656,  6720,  6728,     0, 
+     4096,  6144,  6656,  6720,  6728,     0,  4096,  6144, 
+     6656,  6720,  6728,  6730,     0,  4096,  6144,  6656, 
+     6720,  6728,     0,  4096,  6144,  6656,  6720,  6736, 
+     6732,     0,  4096,  6144,  6656,  6720,  6736,  6732, 
+        0,  4096,  6144,  6656,  6720,  6736,  6737,  6734, 
+        0,  4096,  6144,  6656,  6720,     0,  4096,  6144, 
+     6656,  6720,  6736,     0,  4096,  6144,  6656,  6720, 
+     6736,     0,  4096,  6144,  6656,  6720,  6736,  6738, 
+        0,  4096,  6144,  6656,  6720,  6736,     0,  4096, 
+     6144,  6656,  6720,  6736,  6740,     0,  4096,  6144, 
+     6656,  6720,  6736,  6740,     0,  4096,  6144,  6656, 
+     6720,  6736,  6744,  6742,     0,  4096,  6144,  6656, 
+     6720,  6736,     0,  4096,  6144,  6656,  6720,  6752, 
+     6744,     0,  4096,  6144,  6656,  6720,  6752,  6744, 
+        0,  4096,  6144,  6656,  6720,  6752,  6744,  6746, 
+        0,  4096,  6144,  6656,  6720,  6752,  6744,     0, 
+     4096,  6144,  6656,  6720,  6752,  6753,  6748,     0, 
+     4096,  6144,  6656,  6720,  6752,  6753,  6748,     0, 
+     4096,  6144,  6656,  6720,  6752,  6753,  6748,  6750, 
+        0,  4096,  6144,  6656,  6720,     0,  4096,  6144, 
+     6656,  6784,  6752,     0,  4096,  6144,  6656,  6784, 
+     6752,     0,  4096,  6144,  6656,  6784,  6752,  6754, 
+        0,  4096,  6144,  6656,  6784,  6752,     0,  4096, 
+     6144,  6656,  6784,  6752,  6756,     0,  4096,  6144, 
+     6656,  6784,  6752,  6756,     0,  4096,  6144,  6656, 
+     6784,  6752,  6760,  6758,     0,  4096,  6144,  6656, 
+     6784,  6752,     0,  4096,  6144,  6656,  6784,  6752, 
+     6760,     0,  4096,  6144,  6656,  6784,  6752,  6760, 
+        0,  4096,  6144,  6656,  6784,  6752,  6760,  6762, 
+        0,  4096,  6144,  6656,  6784,  6752,  6760,     0, 
+     4096,  6144,  6656,  6784,  6752,  6768,  6764,     0, 
+     4096,  6144,  6656,  6784,  6752,  6768,  6764,     0, 
+     4096,  6144,  6656,  6784,  6752,  6768,  6769,  6766, 
+        0,  4096,  6144,  6656,  6784,  6752,     0,  4096, 
+     6144,  6656,  6784,  6785,  6768,     0,  4096,  6144, 
+     6656,  6784,  6785,  6768,     0,  4096,  6144,  6656, 
+     6784,  6785,  6768,  6770,     0,  4096,  6144,  6656, 
+     6784,  6785,  6768,     0,  4096,  6144,  6656,  6784, 
+     6785,  6768,  6772,     0,  4096,  6144,  6656,  6784, 
+     6785,  6768,  6772,     0,  4096,  6144,  6656,  6784, 
+     6785,  6768,  6776,  6774,     0,  4096,  6144,  6656, 
+     6784,  6785,  6768,     0,  4096,  6144,  6656,  6784, 
+     6785,  6768,  6776,     0,  4096,  6144,  6656,  6784, 
+     6785,  6787,  6776,     0,  4096,  6144,  6656,  6784, 
+     6785,  6787,  6776,  6778,     0,  4096,  6144,  6656, 
+     6784,  6785,  6787,  6776,     0,  4096,  6144,  6656, 
+     6784,  6785,  6787,  6776,  6780,     0,  4096,  6144, 
+     6656,  6784,  6785,  6787,  6776,  6780,     0,  4096, 
+     6144,  6656,  6784,  6785,  6787,  6776,  6780,  6782, 
+        0,  4096,  6144,  6656,     0,  4096,  6144,  6656, 
+     6784,     0,  4096,  6144,  6656,  6784,     0,  4096, 
+     6144,  6656,  6784,  6786,     0,  4096,  6144,  6656, 
+     6784,     0,  4096,  6144,  6656,  6784,  6788,     0, 
+     4096,  6144,  6656,  6784,  6788,     0,  4096,  6144, 
+     6656,  6784,  6792,  6790,     0,  4096,  6144,  6656, 
+     6784,     0,  4096,  6144,  6656,  6784,  6792,     0, 
+     4096,  6144,  6656,  6784,  6792,     0,  4096,  6144, 
+     6656,  6784,  6792,  6794,     0,  4096,  6144,  6656, 
+     6784,  6792,     0,  4096,  6144,  6656,  6784,  6800, 
+     6796,     0,  4096,  6144,  6656,  6784,  6800,  6796, 
+        0,  4096,  6144,  6656,  6784,  6800,  6801,  6798, 
+        0,  4096,  6144,  6656,  6784,     0,  4096,  6144, 
+     6656,  6784,  6800,     0,  4096,  6144,  6656,  6784, 
+     6800,     0,  4096,  6144,  6656,  6784,  6800,  6802, 
+        0,  4096,  6144,  6656,  6784,  6800,     0,  4096, 
+     6144,  6656,  6784,  6800,  6804,     0,  4096,  6144, 
+     6656,  6784,  6800,  6804,     0,  4096,  6144,  6656, 
+     6784,  6800,  6808,  6806,     0,  4096,  6144,  6656, 
+     6784,  6800,     0,  4096,  6144,  6656,  6784,  6816, 
+     6808,     0,  4096,  6144,  6656,  6784,  6816,  6808, 
+        0,  4096,  6144,  6656,  6784,  6816,  6808,  6810, 
+        0,  4096,  6144,  6656,  6784,  6816,  6808,     0, 
+     4096,  6144,  6656,  6784,  6816,  6817,  6812,     0, 
+     4096,  6144,  6656,  6784,  6816,  6817,  6812,     0, 
+     4096,  6144,  6656,  6784,  6816,  6817,  6812,  6814, 
+        0,  4096,  6144,  6656,  6784,     0,  4096,  6144, 
+     6656,  6784,  6816,     0,  4096,  6144,  6656,  6784, 
+     6816,     0,  4096,  6144,  6656,  6784,  6816,  6818, 
+        0,  4096,  6144,  6656,  6784,  6816,     0,  4096, 
+     6144,  6656,  6784,  6816,  6820,     0,  4096,  6144, 
+     6656,  6784,  6816,  6820,     0,  4096,  6144,  6656, 
+     6784,  6816,  6824,  6822,     0,  4096,  6144,  6656, 
+     6784,  6816,     0,  4096,  6144,  6656,  6784,  6816, 
+     6824,     0,  4096,  6144,  6656,  6784,  6816,  6824, 
+        0,  4096,  6144,  6656,  6784,  6816,  6824,  6826, 
+        0,  4096,  6144,  6656,  6784,  6816,  6824,     0, 
+     4096,  6144,  6656,  6784,  6816,  6832,  6828,     0, 
+     4096,  6144,  6656,  6784,  6816,  6832,  6828,     0, 
+     4096,  6144,  6656,  6784,  6816,  6832,  6833,  6830, 
+        0,  4096,  6144,  6656,  6784,  6816,     0,  4096, 
+     6144,  6656,  6784,  6848,  6832,     0,  4096,  6144, 
+     6656,  6784,  6848,  6832,     0,  4096,  6144,  6656, 
+     6784,  6848,  6832,  6834,     0,  4096,  6144,  6656, 
+     6784,  6848,  6832,     0,  4096,  6144,  6656,  6784, 
+     6848,  6832,  6836,     0,  4096,  6144,  6656,  6784, 
+     6848,  6832,  6836,     0,  4096,  6144,  6656,  6784, 
+     6848,  6832,  6840,  6838,     0,  4096,  6144,  6656, 
+     6784,  6848,  6832,     0,  4096,  6144,  6656,  6784, 
+     6848,  6849,  6840,     0,  4096,  6144,  6656,  6784, 
+     6848,  6849,  6840,     0,  4096,  6144,  6656,  6784, 
+     6848,  6849,  6840,  6842,     0,  4096,  6144,  6656, 
+     6784,  6848,  6849,  6840,     0,  4096,  6144,  6656, 
+     6784,  6848,  6849,  6840,  6844,     0,  4096,  6144, 
+     6656,  6784,  6848,  6849,  6851,  6844,     0,  4096, 
+     6144,  6656,  6784,  6848,  6849,  6851,  6844,  6846, 
+        0,  4096,  6144,  6656,  6784,     0,  4096,  6144, 
+     6656,  6912,  6848,     0,  4096,  6144,  6656,  6912, 
+     6848,     0,  4096,  6144,  6656,  6912,  6848,  6850, 
+        0,  4096,  6144,  6656,  6912,  6848,     0,  4096, 
+     6144,  6656,  6912,  6848,  6852,     0,  4096,  6144, 
+     6656,  6912,  6848,  6852,     0,  4096,  6144,  6656, 
+     6912,  6848,  6856,  6854,     0,  4096,  6144,  6656, 
+     6912,  6848,     0,  4096,  6144,  6656,  6912,  6848, 
+     6856,     0,  4096,  6144,  6656,  6912,  6848,  6856, 
+        0,  4096,  6144,  6656,  6912,  6848,  6856,  6858, 
+        0,  4096,  6144,  6656,  6912,  6848,  6856,     0, 
+     4096,  6144,  6656,  6912,  6848,  6864,  6860,     0, 
+     4096,  6144,  6656,  6912,  6848,  6864,  6860,     0, 
+     4096,  6144,  6656,  6912,  6848,  6864,  6865,  6862, 
+        0,  4096,  6144,  6656,  6912,  6848,     0,  4096, 
+     6144,  6656,  6912,  6848,  6864,     0,  4096,  6144, 
+     6656,  6912,  6848,  6864,     0,  4096,  6144,  6656, 
+     6912,  6848,  6864,  6866,     0,  4096,  6144,  6656, 
+     6912,  6848,  6864,     0,  4096,  6144,  6656,  6912, 
+     6848,  6864,  6868,     0,  4096,  6144,  6656,  6912, 
+     6848,  6864,  6868,     0,  4096,  6144,  6656,  6912, 
+     6848,  6864,  6872,  6870,     0,  4096,  6144,  6656, 
+     6912,  6848,  6864,     0,  4096,  6144,  6656,  6912, 
+     6848,  6880,  6872,     0,  4096,  6144,  6656,  6912, 
+     6848,  6880,  6872,     0,  4096,  6144,  6656,  6912, 
+     6848,  6880,  6872,  6874,     0,  4096,  6144,  6656, 
+     6912,  6848,  6880,  6872,     0,  4096,  6144,  6656, 
+     6912,  6848,  6880,  6881,  6876,     0,  4096,  6144, 
+     6656,  6912,  6848,  6880,  6881,  6876,     0,  4096, 
+     6144,  6656,  6912,  6848,  6880,  6881,  6876,  6878, 
+        0,  4096,  6144,  6656,  6912,  6848,     0,  4096, 
+     6144,  6656,  6912,  6913,  6880,     0,  4096,  6144, 
+     6656,  6912,  6913,  6880,     0,  4096,  6144,  6656, 
+     6912,  6913,  6880,  6882,     0,  4096,  6144,  6656, 
+     6912,  6913,  6880,     0,  4096,  6144,  6656,  6912, 
+     6913,  6880,  6884,     0,  4096,  6144,  6656,  6912, 
+     6913,  6880,  6884,     0,  4096,  6144,  6656,  6912, 
+     6913,  6880,  6888,  6886,     0,  4096,  6144,  6656, 
+     6912,  6913,  6880,     0,  4096,  6144,  6656,  6912, 
+     6913,  6880,  6888,     0,  4096,  6144,  6656,  6912, 
+     6913,  6880,  6888,     0,  4096,  6144,  6656,  6912, 
+     6913,  6880,  6888,  6890,     0,  4096,  6144,  6656, 
+     6912,  6913,  6880,  6888,     0,  4096,  6144,  6656, 
+     6912,  6913,  6880,  6896,  6892,     0,  4096,  6144, 
+     6656,  6912,  6913,  6880,  6896,  6892,     0,  4096, 
+     6144,  6656,  6912,  6913,  6880,  6896,  6897,  6894, 
+        0,  4096,  6144,  6656,  6912,  6913,  6880,     0, 
+     4096,  6144,  6656,  6912,  6913,  6880,  6896,     0, 
+     4096,  6144,  6656,  6912,  6913,  6915,  6896,     0, 
+     4096,  6144,  6656,  6912,  6913,  6915,  6896,  6898, 
+        0,  4096,  6144,  6656,  6912,  6913,  6915,  6896, 
+        0,  4096,  6144,  6656,  6912,  6913,  6915,  6896, 
+     6900,     0,  4096,  6144,  6656,  6912,  6913,  6915, 
+     6896,  6900,     0,  4096,  6144,  6656,  6912,  6913, 
+     6915,  6896,  6904,  6902,     0,  4096,  6144,  6656, 
+     6912,  6913,  6915,  6896,     0,  4096,  6144,  6656, 
+     6912,  6913,  6915,  6896,  6904,     0,  4096,  6144, 
+     6656,  6912,  6913,  6915,  6896,  6904,     0,  4096, 
+     6144,  6656,  6912,  6913,  6915,  6896,  6904,  6906, 
+        0,  4096,  6144,  6656,  6912,  6913,  6915,  6919, 
+     6904,     0,  4096,  6144,  6656,  6912,  6913,  6915, 
+     6919,  6904,  6908,     0,  4096,  6144,  6656,  6912, 
+     6913,  6915,  6919,  6904,  6908,     0,  4096,  6144, 
+     6656,  6912,  6913,  6915,  6919,  6904,  6908,  6910, 
+        0,  4096,  6144,  6656,     0,  4096,  6144,  7168, 
+     6912,     0,  4096,  6144,  7168,  6912,     0,  4096, 
+     6144,  7168,  6912,  6914,     0,  4096,  6144,  7168, 
+     6912,     0,  4096,  6144,  7168,  6912,  6916,     0, 
+     4096,  6144,  7168,  6912,  6916,     0,  4096,  6144, 
+     7168,  6912,  6920,  6918,     0,  4096,  6144,  7168, 
+     6912,     0,  4096,  6144,  7168,  6912,  6920,     0, 
+     4096,  6144,  7168,  6912,  6920,     0,  4096,  6144, 
+     7168,  6912,  6920,  6922,     0,  4096,  6144,  7168, 
+     6912,  6920,     0,  4096,  6144,  7168,  6912,  6928, 
+     6924,     0,  4096,  6144,  7168,  6912,  6928,  6924, 
+        0,  4096,  6144,  7168,  6912,  6928,  6929,  6926, 
+        0,  4096,  6144,  7168,  6912,     0,  4096,  6144, 
+     7168,  6912,  6928,     0,  4096,  6144,  7168,  6912, 
+     6928,     0,  4096,  6144,  7168,  6912,  6928,  6930, 
+        0,  4096,  6144,  7168,  6912,  6928,     0,  4096, 
+     6144,  7168,  6912,  6928,  6932,     0,  4096,  6144, 
+     7168,  6912,  6928,  6932,     0,  4096,  6144,  7168, 
+     6912,  6928,  6936,  6934,     0,  4096,  6144,  7168, 
+     6912,  6928,     0,  4096,  6144,  7168,  6912,  6944, 
+     6936,     0,  4096,  6144,  7168,  6912,  6944,  6936, 
+        0,  4096,  6144,  7168,  6912,  6944,  6936,  6938, 
+        0,  4096,  6144,  7168,  6912,  6944,  6936,     0, 
+     4096,  6144,  7168,  6912,  6944,  6945,  6940,     0, 
+     4096,  6144,  7168,  6912,  6944,  6945,  6940,     0, 
+     4096,  6144,  7168,  6912,  6944,  6945,  6940,  6942, 
+        0,  4096,  6144,  7168,  6912,     0,  4096,  6144, 
+     7168,  6912,  6944,     0,  4096,  6144,  7168,  6912, 
+     6944,     0,  4096,  6144,  7168,  6912,  6944,  6946, 
+        0,  4096,  6144,  7168,  6912,  6944,     0,  4096, 
+     6144,  7168,  6912,  6944,  6948,     0,  4096,  6144, 
+     7168,  6912,  6944,  6948,     0,  4096,  6144,  7168, 
+     6912,  6944,  6952,  6950,     0,  4096,  6144,  7168, 
+     6912,  6944,     0,  4096,  6144,  7168,  6912,  6944, 
+     6952,     0,  4096,  6144,  7168,  6912,  6944,  6952, 
+        0,  4096,  6144,  7168,  6912,  6944,  6952,  6954, 
+        0,  4096,  6144,  7168,  6912,  6944,  6952,     0, 
+     4096,  6144,  7168,  6912,  6944,  6960,  6956,     0, 
+     4096,  6144,  7168,  6912,  6944,  6960,  6956,     0, 
+     4096,  6144,  7168,  6912,  6944,  6960,  6961,  6958, 
+        0,  4096,  6144,  7168,  6912,  6944,     0,  4096, 
+     6144,  7168,  6912,  6976,  6960,     0,  4096,  6144, 
+     7168,  6912,  6976,  6960,     0,  4096,  6144,  7168, 
+     6912,  6976,  6960,  6962,     0,  4096,  6144,  7168, 
+     6912,  6976,  6960,     0,  4096,  6144,  7168,  6912, 
+     6976,  6960,  6964,     0,  4096,  6144,  7168,  6912, 
+     6976,  6960,  6964,     0,  4096,  6144,  7168,  6912, 
+     6976,  6960,  6968,  6966,     0,  4096,  6144,  7168, 
+     6912,  6976,  6960,     0,  4096,  6144,  7168,  6912, 
+     6976,  6977,  6968,     0,  4096,  6144,  7168,  6912, 
+     6976,  6977,  6968,     0,  4096,  6144,  7168,  6912, 
+     6976,  6977,  6968,  6970,     0,  4096,  6144,  7168, 
+     6912,  6976,  6977,  6968,     0,  4096,  6144,  7168, 
+     6912,  6976,  6977,  6968,  6972,     0,  4096,  6144, 
+     7168,  6912,  6976,  6977,  6979,  6972,     0,  4096, 
+     6144,  7168,  6912,  6976,  6977,  6979,  6972,  6974, 
+        0,  4096,  6144,  7168,  6912,     0,  4096,  6144, 
+     7168,  6912,  6976,     0,  4096,  6144,  7168,  6912, 
+     6976,     0,  4096,  6144,  7168,  6912,  6976,  6978, 
+        0,  4096,  6144,  7168,  6912,  6976,     0,  4096, 
+     6144,  7168,  6912,  6976,  6980,     0,  4096,  6144, 
+     7168,  6912,  6976,  6980,     0,  4096,  6144,  7168, 
+     6912,  6976,  6984,  6982,     0,  4096,  6144,  7168, 
+     6912,  6976,     0,  4096,  6144,  7168,  6912,  6976, 
+     6984,     0,  4096,  6144,  7168,  6912,  6976,  6984, 
+        0,  4096,  6144,  7168,  6912,  6976,  6984,  6986, 
+        0,  4096,  6144,  7168,  6912,  6976,  6984,     0, 
+     4096,  6144,  7168,  6912,  6976,  6992,  6988,     0, 
+     4096,  6144,  7168,  6912,  6976,  6992,  6988,     0, 
+     4096,  6144,  7168,  6912,  6976,  6992,  6993,  6990, 
+        0,  4096,  6144,  7168,  6912,  6976,     0,  4096, 
+     6144,  7168,  6912,  6976,  6992,     0,  4096,  6144, 
+     7168,  6912,  6976,  6992,     0,  4096,  6144,  7168, 
+     6912,  6976,  6992,  6994,     0,  4096,  6144,  7168, 
+     6912,  6976,  6992,     0,  4096,  6144,  7168,  6912, 
+     6976,  6992,  6996,     0,  4096,  6144,  7168,  6912, 
+     6976,  6992,  6996,     0,  4096,  6144,  7168,  6912, 
+     6976,  6992,  7000,  6998,     0,  4096,  6144,  7168, 
+     6912,  6976,  6992,     0,  4096,  6144,  7168,  6912, 
+     6976,  7008,  7000,     0,  4096,  6144,  7168,  6912, 
+     6976,  7008,  7000,     0,  4096,  6144,  7168,  6912, 
+     6976,  7008,  7000,  7002,     0,  4096,  6144,  7168, 
+     6912,  6976,  7008,  7000,     0,  4096,  6144,  7168, 
+     6912,  6976,  7008,  7009,  7004,     0,  4096,  6144, 
+     7168,  6912,  6976,  7008,  7009,  7004,     0,  4096, 
+     6144,  7168,  6912,  6976,  7008,  7009,  7004,  7006, 
+        0,  4096,  6144,  7168,  6912,  6976,     0,  4096, 
+     6144,  7168,  6912,  7040,  7008,     0,  4096,  6144, 
+     7168,  6912,  7040,  7008,     0,  4096,  6144,  7168, 
+     6912,  7040,  7008,  7010,     0,  4096,  6144,  7168, 
+     6912,  7040,  7008,     0,  4096,  6144,  7168,  6912, 
+     7040,  7008,  7012,     0,  4096,  6144,  7168,  6912, 
+     7040,  7008,  7012,     0,  4096,  6144,  7168,  6912, 
+     7040,  7008,  7016,  7014,     0,  4096,  6144,  7168, 
+     6912,  7040,  7008,     0,  4096,  6144,  7168,  6912, 
+     7040,  7008,  7016,     0,  4096,  6144,  7168,  6912, 
+     7040,  7008,  7016,     0,  4096,  6144,  7168,  6912, 
+     7040,  7008,  7016,  7018,     0,  4096,  6144,  7168, 
+     6912,  7040,  7008,  7016,     0,  4096,  6144,  7168, 
+     6912,  7040,  7008,  7024,  7020,     0,  4096,  6144, 
+     7168,  6912,  7040,  7008,  7024,  7020,     0,  4096, 
+     6144,  7168,  6912,  7040,  7008,  7024,  7025,  7022, 
+        0,  4096,  6144,  7168,  6912,  7040,  7008,     0, 
+     4096,  6144,  7168,  6912,  7040,  7041,  7024,     0, 
+     4096,  6144,  7168,  6912,  7040,  7041,  7024,     0, 
+     4096,  6144,  7168,  6912,  7040,  7041,  7024,  7026, 
+        0,  4096,  6144,  7168,  6912,  7040,  7041,  7024, 
+        0,  4096,  6144,  7168,  6912,  7040,  7041,  7024, 
+     7028,     0,  4096,  6144,  7168,  6912,  7040,  7041, 
+     7024,  7028,     0,  4096,  6144,  7168,  6912,  7040, 
+     7041,  7024,  7032,  7030,     0,  4096,  6144,  7168, 
+     6912,  7040,  7041,  7024,     0,  4096,  6144,  7168, 
+     6912,  7040,  7041,  7024,  7032,     0,  4096,  6144, 
+     7168,  6912,  7040,  7041,  7043,  7032,     0,  4096, 
+     6144,  7168,  6912,  7040,  7041,  7043,  7032,  7034, 
+        0,  4096,  6144,  7168,  6912,  7040,  7041,  7043, 
+     7032,     0,  4096,  6144,  7168,  6912,  7040,  7041, 
+     7043,  7032,  7036,     0,  4096,  6144,  7168,  6912, 
+     7040,  7041,  7043,  7032,  7036,     0,  4096,  6144, 
+     7168,  6912,  7040,  7041,  7043,  7032,  7036,  7038, 
+        0,  4096,  6144,  7168,  6912,     0,  4096,  6144, 
+     7168,  6912,  7040,     0,  4096,  6144,  7168,  7169, 
+     7040,     0,  4096,  6144,  7168,  7169,  7040,  7042, 
+        0,  4096,  6144,  7168,  7169,  7040,     0,  4096, 
+     6144,  7168,  7169,  7040,  7044,     0,  4096,  6144, 
+     7168,  7169,  7040,  7044,     0,  4096,  6144,  7168, 
+     7169,  7040,  7048,  7046,     0,  4096,  6144,  7168, 
+     7169,  7040,     0,  4096,  6144,  7168,  7169,  7040, 
+     7048,     0,  4096,  6144,  7168,  7169,  7040,  7048, 
+        0,  4096,  6144,  7168,  7169,  7040,  7048,  7050, 
+        0,  4096,  6144,  7168,  7169,  7040,  7048,     0, 
+     4096,  6144,  7168,  7169,  7040,  7056,  7052,     0, 
+     4096,  6144,  7168,  7169,  7040,  7056,  7052,     0, 
+     4096,  6144,  7168,  7169,  7040,  7056,  7057,  7054, 
+        0,  4096,  6144,  7168,  7169,  7040,     0,  4096, 
+     6144,  7168,  7169,  7040,  7056,     0,  4096,  6144, 
+     7168,  7169,  7040,  7056,     0,  4096,  6144,  7168, 
+     7169,  7040,  7056,  7058,     0,  4096,  6144,  7168, 
+     7169,  7040,  7056,     0,  4096,  6144,  7168,  7169, 
+     7040,  7056,  7060,     0,  4096,  6144,  7168,  7169, 
+     7040,  7056,  7060,     0,  4096,  6144,  7168,  7169, 
+     7040,  7056,  7064,  7062,     0,  4096,  6144,  7168, 
+     7169,  7040,  7056,     0,  4096,  6144,  7168,  7169, 
+     7040,  7072,  7064,     0,  4096,  6144,  7168,  7169, 
+     7040,  7072,  7064,     0,  4096,  6144,  7168,  7169, 
+     7040,  7072,  7064,  7066,     0,  4096,  6144,  7168, 
+     7169,  7040,  7072,  7064,     0,  4096,  6144,  7168, 
+     7169,  7040,  7072,  7073,  7068,     0,  4096,  6144, 
+     7168,  7169,  7040,  7072,  7073,  7068,     0,  4096, 
+     6144,  7168,  7169,  7040,  7072,  7073,  7068,  7070, 
+        0,  4096,  6144,  7168,  7169,  7040,     0,  4096, 
+     6144,  7168,  7169,  7040,  7072,     0,  4096,  6144, 
+     7168,  7169,  7040,  7072,     0,  4096,  6144,  7168, 
+     7169,  7040,  7072,  7074,     0,  4096,  6144,  7168, 
+     7169,  7040,  7072,     0,  4096,  6144,  7168,  7169, 
+     7040,  7072,  7076,     0,  4096,  6144,  7168,  7169, 
+     7040,  7072,  7076,     0,  4096,  6144,  7168,  7169, 
+     7040,  7072,  7080,  7078,     0,  4096,  6144,  7168, 
+     7169,  7040,  7072,     0,  4096,  6144,  7168,  7169, 
+     7040,  7072,  7080,     0,  4096,  6144,  7168,  7169, 
+     7040,  7072,  7080,     0,  4096,  6144,  7168,  7169, 
+     7040,  7072,  7080,  7082,     0,  4096,  6144,  7168, 
+     7169,  7040,  7072,  7080,     0,  4096,  6144,  7168, 
+     7169,  7040,  7072,  7088,  7084,     0,  4096,  6144, 
+     7168,  7169,  7040,  7072,  7088,  7084,     0,  4096, 
+     6144,  7168,  7169,  7040,  7072,  7088,  7089,  7086, 
+        0,  4096,  6144,  7168,  7169,  7040,  7072,     0, 
+     4096,  6144,  7168,  7169,  7040,  7104,  7088,     0, 
+     4096,  6144,  7168,  7169,  7040,  7104,  7088,     0, 
+     4096,  6144,  7168,  7169,  7040,  7104,  7088,  7090, 
+        0,  4096,  6144,  7168,  7169,  7040,  7104,  7088, 
+        0,  4096,  6144,  7168,  7169,  7040,  7104,  7088, 
+     7092,     0,  4096,  6144,  7168,  7169,  7040,  7104, 
+     7088,  7092,     0,  4096,  6144,  7168,  7169,  7040, 
+     7104,  7088,  7096,  7094,     0,  4096,  6144,  7168, 
+     7169,  7040,  7104,  7088,     0,  4096,  6144,  7168, 
+     7169,  7040,  7104,  7105,  7096,     0,  4096,  6144, 
+     7168,  7169,  7040,  7104,  7105,  7096,     0,  4096, 
+     6144,  7168,  7169,  7040,  7104,  7105,  7096,  7098, 
+        0,  4096,  6144,  7168,  7169,  7040,  7104,  7105, 
+     7096,     0,  4096,  6144,  7168,  7169,  7040,  7104, 
+     7105,  7096,  7100,     0,  4096,  6144,  7168,  7169, 
+     7040,  7104,  7105,  7107,  7100,     0,  4096,  6144, 
+     7168,  7169,  7040,  7104,  7105,  7107,  7100,  7102, 
+        0,  4096,  6144,  7168,  7169,  7040,     0,  4096, 
+     6144,  7168,  7169,  7040,  7104,     0,  4096,  6144, 
+     7168,  7169,  7040,  7104,     0,  4096,  6144,  7168, 
+     7169,  7040,  7104,  7106,     0,  4096,  6144,  7168, 
+     7169,  7171,  7104,     0,  4096,  6144,  7168,  7169, 
+     7171,  7104,  7108,     0,  4096,  6144,  7168,  7169, 
+     7171,  7104,  7108,     0,  4096,  6144,  7168,  7169, 
+     7171,  7104,  7112,  7110,     0,  4096,  6144,  7168, 
+     7169,  7171,  7104,     0,  4096,  6144,  7168,  7169, 
+     7171,  7104,  7112,     0,  4096,  6144,  7168,  7169, 
+     7171,  7104,  7112,     0,  4096,  6144,  7168,  7169, 
+     7171,  7104,  7112,  7114,     0,  4096,  6144,  7168, 
+     7169,  7171,  7104,  7112,     0,  4096,  6144,  7168, 
+     7169,  7171,  7104,  7120,  7116,     0,  4096,  6144, 
+     7168,  7169,  7171,  7104,  7120,  7116,     0,  4096, 
+     6144,  7168,  7169,  7171,  7104,  7120,  7121,  7118, 
+        0,  4096,  6144,  7168,  7169,  7171,  7104,     0, 
+     4096,  6144,  7168,  7169,  7171,  7104,  7120,     0, 
+     4096,  6144,  7168,  7169,  7171,  7104,  7120,     0, 
+     4096,  6144,  7168,  7169,  7171,  7104,  7120,  7122, 
+        0,  4096,  6144,  7168,  7169,  7171,  7104,  7120, 
+        0,  4096,  6144,  7168,  7169,  7171,  7104,  7120, 
+     7124,     0,  4096,  6144,  7168,  7169,  7171,  7104, 
+     7120,  7124,     0,  4096,  6144,  7168,  7169,  7171, 
+     7104,  7120,  7128,  7126,     0,  4096,  6144,  7168, 
+     7169,  7171,  7104,  7120,     0,  4096,  6144,  7168, 
+     7169,  7171,  7104,  7136,  7128,     0,  4096,  6144, 
+     7168,  7169,  7171,  7104,  7136,  7128,     0,  4096, 
+     6144,  7168,  7169,  7171,  7104,  7136,  7128,  7130, 
+        0,  4096,  6144,  7168,  7169,  7171,  7104,  7136, 
+     7128,     0,  4096,  6144,  7168,  7169,  7171,  7104, 
+     7136,  7137,  7132,     0,  4096,  6144,  7168,  7169, 
+     7171,  7104,  7136,  7137,  7132,     0,  4096,  6144, 
+     7168,  7169,  7171,  7104,  7136,  7137,  7132,  7134, 
+        0,  4096,  6144,  7168,  7169,  7171,  7104,     0, 
+     4096,  6144,  7168,  7169,  7171,  7104,  7136,     0, 
+     4096,  6144,  7168,  7169,  7171,  7104,  7136,     0, 
+     4096,  6144,  7168,  7169,  7171,  7104,  7136,  7138, 
+        0,  4096,  6144,  7168,  7169,  7171,  7104,  7136, 
+        0,  4096,  6144,  7168,  7169,  7171,  7104,  7136, 
+     7140,     0,  4096,  6144,  7168,  7169,  7171,  7104, 
+     7136,  7140,     0,  4096,  6144,  7168,  7169,  7171, 
+     7104,  7136,  7144,  7142,     0,  4096,  6144,  7168, 
+     7169,  7171,  7175,  7136,     0,  4096,  6144,  7168, 
+     7169,  7171,  7175,  7136,  7144,     0,  4096,  6144, 
+     7168,  7169,  7171,  7175,  7136,  7144,     0,  4096, 
+     6144,  7168,  7169,  7171,  7175,  7136,  7144,  7146, 
+        0,  4096,  6144,  7168,  7169,  7171,  7175,  7136, 
+     7144,     0,  4096,  6144,  7168,  7169,  7171,  7175, 
+     7136,  7152,  7148,     0,  4096,  6144,  7168,  7169, 
+     7171,  7175,  7136,  7152,  7148,     0,  4096,  6144, 
+     7168,  7169,  7171,  7175,  7136,  7152,  7153,  7150, 
+        0,  4096,  6144,  7168,  7169,  7171,  7175,  7136, 
+        0,  4096,  6144,  7168,  7169,  7171,  7175,  7136, 
+     7152,     0,  4096,  6144,  7168,  7169,  7171,  7175, 
+     7136,  7152,     0,  4096,  6144,  7168,  7169,  7171, 
+     7175,  7136,  7152,  7154,     0,  4096,  6144,  7168, 
+     7169,  7171,  7175,  7136,  7152,     0,  4096,  6144, 
+     7168,  7169,  7171,  7175,  7136,  7152,  7156,     0, 
+     4096,  6144,  7168,  7169,  7171,  7175,  7136,  7152, 
+     7156,     0,  4096,  6144,  7168,  7169,  7171,  7175, 
+     7136,  7152,  7160,  7158,     0,  4096,  6144,  7168, 
+     7169,  7171,  7175,  7136,  7152,     0,  4096,  6144, 
+     7168,  7169,  7171,  7175,  7136,  7152,  7160,     0, 
+     4096,  6144,  7168,  7169,  7171,  7175,  7136,  7152, 
+     7160,     0,  4096,  6144,  7168,  7169,  7171,  7175, 
+     7136,  7152,  7160,  7162,     0,  4096,  6144,  7168, 
+     7169,  7171,  7175,  7136,  7152,  7160,     0,  4096, 
+     6144,  7168,  7169,  7171,  7175,  7136,  7152,  7160, 
+     7164,     0,  4096,  6144,  7168,  7169,  7171,  7175, 
+     7136,  7152,  7160,  7164,     0,  4096,  6144,  7168, 
+     7169,  7171,  7175,  7136,  7152,  7160,  7164,  7166, 
+        0,  4096,  6144,     0,  4096,  6144,  7168,     0, 
+     4096,  6144,  7168,     0,  4096,  6144,  7168,  7170, 
+        0,  4096,  6144,  7168,     0,  4096,  6144,  7168, 
+     7172,     0,  4096,  6144,  7168,  7172,     0,  4096, 
+     6144,  7168,  7176,  7174,     0,  4096,  6144,  7168, 
+        0,  4096,  6144,  7168,  7176,     0,  4096,  6144, 
+     7168,  7176,     0,  4096,  6144,  7168,  7176,  7178, 
+        0,  4096,  6144,  7168,  7176,     0,  4096,  6144, 
+     7168,  7184,  7180,     0,  4096,  6144,  7168,  7184, 
+     7180,     0,  4096,  6144,  7168,  7184,  7185,  7182, 
+        0,  4096,  6144,  7168,     0,  4096,  6144,  7168, 
+     7184,     0,  4096,  6144,  7168,  7184,     0,  4096, 
+     6144,  7168,  7184,  7186,     0,  4096,  6144,  7168, 
+     7184,     0,  4096,  6144,  7168,  7184,  7188,     0, 
+     4096,  6144,  7168,  7184,  7188,     0,  4096,  6144, 
+     7168,  7184,  7192,  7190,     0,  4096,  6144,  7168, 
+     7184,     0,  4096,  6144,  7168,  7200,  7192,     0, 
+     4096,  6144,  7168,  7200,  7192,     0,  4096,  6144, 
+     7168,  7200,  7192,  7194,     0,  4096,  6144,  7168, 
+     7200,  7192,     0,  4096,  6144,  7168,  7200,  7201, 
+     7196,     0,  4096,  6144,  7168,  7200,  7201,  7196, 
+        0,  4096,  6144,  7168,  7200,  7201,  7196,  7198, 
+        0,  4096,  6144,  7168,     0,  4096,  6144,  7168, 
+     7200,     0,  4096,  6144,  7168,  7200,     0,  4096, 
+     6144,  7168,  7200,  7202,     0,  4096,  6144,  7168, 
+     7200,     0,  4096,  6144,  7168,  7200,  7204,     0, 
+     4096,  6144,  7168,  7200,  7204,     0,  4096,  6144, 
+     7168,  7200,  7208,  7206,     0,  4096,  6144,  7168, 
+     7200,     0,  4096,  6144,  7168,  7200,  7208,     0, 
+     4096,  6144,  7168,  7200,  7208,     0,  4096,  6144, 
+     7168,  7200,  7208,  7210,     0,  4096,  6144,  7168, 
+     7200,  7208,     0,  4096,  6144,  7168,  7200,  7216, 
+     7212,     0,  4096,  6144,  7168,  7200,  7216,  7212, 
+        0,  4096,  6144,  7168,  7200,  7216,  7217,  7214, 
+        0,  4096,  6144,  7168,  7200,     0,  4096,  6144, 
+     7168,  7232,  7216,     0,  4096,  6144,  7168,  7232, 
+     7216,     0,  4096,  6144,  7168,  7232,  7216,  7218, 
+        0,  4096,  6144,  7168,  7232,  7216,     0,  4096, 
+     6144,  7168,  7232,  7216,  7220,     0,  4096,  6144, 
+     7168,  7232,  7216,  7220,     0,  4096,  6144,  7168, 
+     7232,  7216,  7224,  7222,     0,  4096,  6144,  7168, 
+     7232,  7216,     0,  4096,  6144,  7168,  7232,  7233, 
+     7224,     0,  4096,  6144,  7168,  7232,  7233,  7224, 
+        0,  4096,  6144,  7168,  7232,  7233,  7224,  7226, 
+        0,  4096,  6144,  7168,  7232,  7233,  7224,     0, 
+     4096,  6144,  7168,  7232,  7233,  7224,  7228,     0, 
+     4096,  6144,  7168,  7232,  7233,  7235,  7228,     0, 
+     4096,  6144,  7168,  7232,  7233,  7235,  7228,  7230, 
+        0,  4096,  6144,  7168,     0,  8192,  6144,  7168, 
+     7232,     0,  8192,  6144,  7168,  7232,     0,  8192, 
+     6144,  7168,  7232,  7234,     0,  8192,  6144,  7168, 
+     7232,     0,  8192,  6144,  7168,  7232,  7236,     0, 
+     8192,  6144,  7168,  7232,  7236,     0,  8192,  6144, 
+     7168,  7232,  7240,  7238,     0,  8192,  6144,  7168, 
+     7232,     0,  8192,  6144,  7168,  7232,  7240,     0, 
+     8192,  6144,  7168,  7232,  7240,     0,  8192,  6144, 
+     7168,  7232,  7240,  7242,     0,  8192,  6144,  7168, 
+     7232,  7240,     0,  8192,  6144,  7168,  7232,  7248, 
+     7244,     0,  8192,  6144,  7168,  7232,  7248,  7244, 
+        0,  8192,  6144,  7168,  7232,  7248,  7249,  7246, 
+        0,  8192,  6144,  7168,  7232,     0,  8192,  6144, 
+     7168,  7232,  7248,     0,  8192,  6144,  7168,  7232, 
+     7248,     0,  8192,  6144,  7168,  7232,  7248,  7250, 
+        0,  8192,  6144,  7168,  7232,  7248,     0,  8192, 
+     6144,  7168,  7232,  7248,  7252,     0,  8192,  6144, 
+     7168,  7232,  7248,  7252,     0,  8192,  6144,  7168, 
+     7232,  7248,  7256,  7254,     0,  8192,  6144,  7168, 
+     7232,  7248,     0,  8192,  6144,  7168,  7232,  7264, 
+     7256,     0,  8192,  6144,  7168,  7232,  7264,  7256, 
+        0,  8192,  6144,  7168,  7232,  7264,  7256,  7258, 
+        0,  8192,  6144,  7168,  7232,  7264,  7256,     0, 
+     8192,  6144,  7168,  7232,  7264,  7265,  7260,     0, 
+     8192,  6144,  7168,  7232,  7264,  7265,  7260,     0, 
+     8192,  6144,  7168,  7232,  7264,  7265,  7260,  7262, 
+        0,  8192,  6144,  7168,  7232,     0,  8192,  6144, 
+     7168,  7296,  7264,     0,  8192,  6144,  7168,  7296, 
+     7264,     0,  8192,  6144,  7168,  7296,  7264,  7266, 
+        0,  8192,  6144,  7168,  7296,  7264,     0,  8192, 
+     6144,  7168,  7296,  7264,  7268,     0,  8192,  6144, 
+     7168,  7296,  7264,  7268,     0,  8192,  6144,  7168, 
+     7296,  7264,  7272,  7270,     0,  8192,  6144,  7168, 
+     7296,  7264,     0,  8192,  6144,  7168,  7296,  7264, 
+     7272,     0,  8192,  6144,  7168,  7296,  7264,  7272, 
+        0,  8192,  6144,  7168,  7296,  7264,  7272,  7274, 
+        0,  8192,  6144,  7168,  7296,  7264,  7272,     0, 
+     8192,  6144,  7168,  7296,  7264,  7280,  7276,     0, 
+     8192,  6144,  7168,  7296,  7264,  7280,  7276,     0, 
+     8192,  6144,  7168,  7296,  7264,  7280,  7281,  7278, 
+        0,  8192,  6144,  7168,  7296,  7264,     0,  8192, 
+     6144,  7168,  7296,  7297,  7280,     0,  8192,  6144, 
+     7168,  7296,  7297,  7280,     0,  8192,  6144,  7168, 
+     7296,  7297,  7280,  7282,     0,  8192,  6144,  7168, 
+     7296,  7297,  7280,     0,  8192,  6144,  7168,  7296, 
+     7297,  7280,  7284,     0,  8192,  6144,  7168,  7296, 
+     7297,  7280,  7284,     0,  8192,  6144,  7168,  7296, 
+     7297,  7280,  7288,  7286,     0,  8192,  6144,  7168, 
+     7296,  7297,  7280,     0,  8192,  6144,  7168,  7296, 
+     7297,  7280,  7288,     0,  8192,  6144,  7168,  7296, 
+     7297,  7299,  7288,     0,  8192,  6144,  7168,  7296, 
+     7297,  7299,  7288,  7290,     0,  8192,  6144,  7168, 
+     7296,  7297,  7299,  7288,     0,  8192,  6144,  7168, 
+     7296,  7297,  7299,  7288,  7292,     0,  8192,  6144, 
+     7168,  7296,  7297,  7299,  7288,  7292,     0,  8192, 
+     6144,  7168,  7296,  7297,  7299,  7288,  7292,  7294, 
+        0,  8192,  6144,  7168,     0,  8192,  6144,  7168, 
+     7296,     0,  8192,  6144,  7168,  7296,     0,  8192, 
+     6144,  7168,  7296,  7298,     0,  8192,  6144,  7168, 
+     7296,     0,  8192,  6144,  7168,  7296,  7300,     0, 
+     8192,  6144,  7168,  7296,  7300,     0,  8192,  6144, 
+     7168,  7296,  7304,  7302,     0,  8192,  6144,  7168, 
+     7296,     0,  8192,  6144,  7168,  7296,  7304,     0, 
+     8192,  6144,  7168,  7296,  7304,     0,  8192,  6144, 
+     7168,  7296,  7304,  7306,     0,  8192,  6144,  7168, 
+     7296,  7304,     0,  8192,  6144,  7168,  7296,  7312, 
+     7308,     0,  8192,  6144,  7168,  7296,  7312,  7308, 
+        0,  8192,  6144,  7168,  7296,  7312,  7313,  7310, 
+        0,  8192,  6144,  7168,  7296,     0,  8192,  6144, 
+     7168,  7296,  7312,     0,  8192,  6144,  7168,  7296, 
+     7312,     0,  8192,  6144,  7168,  7296,  7312,  7314, 
+        0,  8192,  6144,  7168,  7296,  7312,     0,  8192, 
+     6144,  7168,  7296,  7312,  7316,     0,  8192,  6144, 
+     7168,  7296,  7312,  7316,     0,  8192,  6144,  7168, 
+     7296,  7312,  7320,  7318,     0,  8192,  6144,  7168, 
+     7296,  7312,     0,  8192,  6144,  7168,  7296,  7328, 
+     7320,     0,  8192,  6144,  7168,  7296,  7328,  7320, 
+        0,  8192,  6144,  7168,  7296,  7328,  7320,  7322, 
+        0,  8192,  6144,  7168,  7296,  7328,  7320,     0, 
+     8192,  6144,  7168,  7296,  7328,  7329,  7324,     0, 
+     8192,  6144,  7168,  7296,  7328,  7329,  7324,     0, 
+     8192,  6144,  7168,  7296,  7328,  7329,  7324,  7326, 
+        0,  8192,  6144,  7168,  7296,     0,  8192,  6144, 
+     7168,  7296,  7328,     0,  8192,  6144,  7168,  7296, 
+     7328,     0,  8192,  6144,  7168,  7296,  7328,  7330, 
+        0,  8192,  6144,  7168,  7296,  7328,     0,  8192, 
+     6144,  7168,  7296,  7328,  7332,     0,  8192,  6144, 
+     7168,  7296,  7328,  7332,     0,  8192,  6144,  7168, 
+     7296,  7328,  7336,  7334,     0,  8192,  6144,  7168, 
+     7296,  7328,     0,  8192,  6144,  7168,  7296,  7328, 
+     7336,     0,  8192,  6144,  7168,  7296,  7328,  7336, 
+        0,  8192,  6144,  7168,  7296,  7328,  7336,  7338, 
+        0,  8192,  6144,  7168,  7296,  7328,  7336,     0, 
+     8192,  6144,  7168,  7296,  7328,  7344,  7340,     0, 
+     8192,  6144,  7168,  7296,  7328,  7344,  7340,     0, 
+     8192,  6144,  7168,  7296,  7328,  7344,  7345,  7342, 
+        0,  8192,  6144,  7168,  7296,  7328,     0,  8192, 
+     6144,  7168,  7296,  7360,  7344,     0,  8192,  6144, 
+     7168,  7296,  7360,  7344,     0,  8192,  6144,  7168, 
+     7296,  7360,  7344,  7346,     0,  8192,  6144,  7168, 
+     7296,  7360,  7344,     0,  8192,  6144,  7168,  7296, 
+     7360,  7344,  7348,     0,  8192,  6144,  7168,  7296, 
+     7360,  7344,  7348,     0,  8192,  6144,  7168,  7296, 
+     7360,  7344,  7352,  7350,     0,  8192,  6144,  7168, 
+     7296,  7360,  7344,     0,  8192,  6144,  7168,  7296, 
+     7360,  7361,  7352,     0,  8192,  6144,  7168,  7296, 
+     7360,  7361,  7352,     0,  8192,  6144,  7168,  7296, 
+     7360,  7361,  7352,  7354,     0,  8192,  6144,  7168, 
+     7296,  7360,  7361,  7352,     0,  8192,  6144,  7168, 
+     7296,  7360,  7361,  7352,  7356,     0,  8192,  6144, 
+     7168,  7296,  7360,  7361,  7363,  7356,     0,  8192, 
+     6144,  7168,  7296,  7360,  7361,  7363,  7356,  7358, 
+        0,  8192,  6144,  7168,  7296,     0,  8192,  6144, 
+     7168,  7424,  7360,     0,  8192,  6144,  7168,  7424, 
+     7360,     0,  8192,  6144,  7168,  7424,  7360,  7362, 
+        0,  8192,  6144,  7168,  7424,  7360,     0,  8192, 
+     6144,  7168,  7424,  7360,  7364,     0,  8192,  6144, 
+     7168,  7424,  7360,  7364,     0,  8192,  6144,  7168, 
+     7424,  7360,  7368,  7366,     0,  8192,  6144,  7168, 
+     7424,  7360,     0,  8192,  6144,  7168,  7424,  7360, 
+     7368,     0,  8192,  6144,  7168,  7424,  7360,  7368, 
+        0,  8192,  6144,  7168,  7424,  7360,  7368,  7370, 
+        0,  8192,  6144,  7168,  7424,  7360,  7368,     0, 
+     8192,  6144,  7168,  7424,  7360,  7376,  7372,     0, 
+     8192,  6144,  7168,  7424,  7360,  7376,  7372,     0, 
+     8192,  6144,  7168,  7424,  7360,  7376,  7377,  7374, 
+        0,  8192,  6144,  7168,  7424,  7360,     0,  8192, 
+     6144,  7168,  7424,  7360,  7376,     0,  8192,  6144, 
+     7168,  7424,  7360,  7376,     0,  8192,  6144,  7168, 
+     7424,  7360,  7376,  7378,     0,  8192,  6144,  7168, 
+     7424,  7360,  7376,     0,  8192,  6144,  7168,  7424, 
+     7360,  7376,  7380,     0,  8192,  6144,  7168,  7424, 
+     7360,  7376,  7380,     0,  8192,  6144,  7168,  7424, 
+     7360,  7376,  7384,  7382,     0,  8192,  6144,  7168, 
+     7424,  7360,  7376,     0,  8192,  6144,  7168,  7424, 
+     7360,  7392,  7384,     0,  8192,  6144,  7168,  7424, 
+     7360,  7392,  7384,     0,  8192,  6144,  7168,  7424, 
+     7360,  7392,  7384,  7386,     0,  8192,  6144,  7168, 
+     7424,  7360,  7392,  7384,     0,  8192,  6144,  7168, 
+     7424,  7360,  7392,  7393,  7388,     0,  8192,  6144, 
+     7168,  7424,  7360,  7392,  7393,  7388,     0,  8192, 
+     6144,  7168,  7424,  7360,  7392,  7393,  7388,  7390, 
+        0,  8192,  6144,  7168,  7424,  7360,     0,  8192, 
+     6144,  7168,  7424,  7425,  7392,     0,  8192,  6144, 
+     7168,  7424,  7425,  7392,     0,  8192,  6144,  7168, 
+     7424,  7425,  7392,  7394,     0,  8192,  6144,  7168, 
+     7424,  7425,  7392,     0,  8192,  6144,  7168,  7424, 
+     7425,  7392,  7396,     0,  8192,  6144,  7168,  7424, 
+     7425,  7392,  7396,     0,  8192,  6144,  7168,  7424, 
+     7425,  7392,  7400,  7398,     0,  8192,  6144,  7168, 
+     7424,  7425,  7392,     0,  8192,  6144,  7168,  7424, 
+     7425,  7392,  7400,     0,  8192,  6144,  7168,  7424, 
+     7425,  7392,  7400,     0,  8192,  6144,  7168,  7424, 
+     7425,  7392,  7400,  7402,     0,  8192,  6144,  7168, 
+     7424,  7425,  7392,  7400,     0,  8192,  6144,  7168, 
+     7424,  7425,  7392,  7408,  7404,     0,  8192,  6144, 
+     7168,  7424,  7425,  7392,  7408,  7404,     0,  8192, 
+     6144,  7168,  7424,  7425,  7392,  7408,  7409,  7406, 
+        0,  8192,  6144,  7168,  7424,  7425,  7392,     0, 
+     8192,  6144,  7168,  7424,  7425,  7392,  7408,     0, 
+     8192,  6144,  7168,  7424,  7425,  7427,  7408,     0, 
+     8192,  6144,  7168,  7424,  7425,  7427,  7408,  7410, 
+        0,  8192,  6144,  7168,  7424,  7425,  7427,  7408, 
+        0,  8192,  6144,  7168,  7424,  7425,  7427,  7408, 
+     7412,     0,  8192,  6144,  7168,  7424,  7425,  7427, 
+     7408,  7412,     0,  8192,  6144,  7168,  7424,  7425, 
+     7427,  7408,  7416,  7414,     0,  8192,  6144,  7168, 
+     7424,  7425,  7427,  7408,     0,  8192,  6144,  7168, 
+     7424,  7425,  7427,  7408,  7416,     0,  8192,  6144, 
+     7168,  7424,  7425,  7427,  7408,  7416,     0,  8192, 
+     6144,  7168,  7424,  7425,  7427,  7408,  7416,  7418, 
+        0,  8192,  6144,  7168,  7424,  7425,  7427,  7431, 
+     7416,     0,  8192,  6144,  7168,  7424,  7425,  7427, 
+     7431,  7416,  7420,     0,  8192,  6144,  7168,  7424, 
+     7425,  7427,  7431,  7416,  7420,     0,  8192,  6144, 
+     7168,  7424,  7425,  7427,  7431,  7416,  7420,  7422, 
+        0,  8192,  6144,  7168,     0,  8192,  6144,  7168, 
+     7424,     0,  8192,  8193,  7168,  7424,     0,  8192, 
+     8193,  7168,  7424,  7426,     0,  8192,  8193,  7168, 
+     7424,     0,  8192,  8193,  7168,  7424,  7428,     0, 
+     8192,  8193,  7168,  7424,  7428,     0,  8192,  8193, 
+     7168,  7424,  7432,  7430,     0,  8192,  8193,  7168, 
+     7424,     0,  8192,  8193,  7168,  7424,  7432,     0, 
+     8192,  8193,  7168,  7424,  7432,     0,  8192,  8193, 
+     7168,  7424,  7432,  7434,     0,  8192,  8193,  7168, 
+     7424,  7432,     0,  8192,  8193,  7168,  7424,  7440, 
+     7436,     0,  8192,  8193,  7168,  7424,  7440,  7436, 
+        0,  8192,  8193,  7168,  7424,  7440,  7441,  7438, 
+        0,  8192,  8193,  7168,  7424,     0,  8192,  8193, 
+     7168,  7424,  7440,     0,  8192,  8193,  7168,  7424, 
+     7440,     0,  8192,  8193,  7168,  7424,  7440,  7442, 
+        0,  8192,  8193,  7168,  7424,  7440,     0,  8192, 
+     8193,  7168,  7424,  7440,  7444,     0,  8192,  8193, 
+     7168,  7424,  7440,  7444,     0,  8192,  8193,  7168, 
+     7424,  7440,  7448,  7446,     0,  8192,  8193,  7168, 
+     7424,  7440,     0,  8192,  8193,  7168,  7424,  7456, 
+     7448,     0,  8192,  8193,  7168,  7424,  7456,  7448, 
+        0,  8192,  8193,  7168,  7424,  7456,  7448,  7450, 
+        0,  8192,  8193,  7168,  7424,  7456,  7448,     0, 
+     8192,  8193,  7168,  7424,  7456,  7457,  7452,     0, 
+     8192,  8193,  7168,  7424,  7456,  7457,  7452,     0, 
+     8192,  8193,  7168,  7424,  7456,  7457,  7452,  7454, 
+        0,  8192,  8193,  7168,  7424,     0,  8192,  8193, 
+     7168,  7424,  7456,     0,  8192,  8193,  7168,  7424, 
+     7456,     0,  8192,  8193,  7168,  7424,  7456,  7458, 
+        0,  8192,  8193,  7168,  7424,  7456,     0,  8192, 
+     8193,  7168,  7424,  7456,  7460,     0,  8192,  8193, 
+     7168,  7424,  7456,  7460,     0,  8192,  8193,  7168, 
+     7424,  7456,  7464,  7462,     0,  8192,  8193,  7168, 
+     7424,  7456,     0,  8192,  8193,  7168,  7424,  7456, 
+     7464,     0,  8192,  8193,  7168,  7424,  7456,  7464, 
+        0,  8192,  8193,  7168,  7424,  7456,  7464,  7466, 
+        0,  8192,  8193,  7168,  7424,  7456,  7464,     0, 
+     8192,  8193,  7168,  7424,  7456,  7472,  7468,     0, 
+     8192,  8193,  7168,  7424,  7456,  7472,  7468,     0, 
+     8192,  8193,  7168,  7424,  7456,  7472,  7473,  7470, 
+        0,  8192,  8193,  7168,  7424,  7456,     0,  8192, 
+     8193,  7168,  7424,  7488,  7472,     0,  8192,  8193, 
+     7168,  7424,  7488,  7472,     0,  8192,  8193,  7168, 
+     7424,  7488,  7472,  7474,     0,  8192,  8193,  7168, 
+     7424,  7488,  7472,     0,  8192,  8193,  7168,  7424, 
+     7488,  7472,  7476,     0,  8192,  8193,  7168,  7424, 
+     7488,  7472,  7476,     0,  8192,  8193,  7168,  7424, 
+     7488,  7472,  7480,  7478,     0,  8192,  8193,  7168, 
+     7424,  7488,  7472,     0,  8192,  8193,  7168,  7424, 
+     7488,  7489,  7480,     0,  8192,  8193,  7168,  7424, 
+     7488,  7489,  7480,     0,  8192,  8193,  7168,  7424, 
+     7488,  7489,  7480,  7482,     0,  8192,  8193,  7168, 
+     7424,  7488,  7489,  7480,     0,  8192,  8193,  7168, 
+     7424,  7488,  7489,  7480,  7484,     0,  8192,  8193, 
+     7168,  7424,  7488,  7489,  7491,  7484,     0,  8192, 
+     8193,  7168,  7424,  7488,  7489,  7491,  7484,  7486, 
+        0,  8192,  8193,  7168,  7424,     0,  8192,  8193, 
+     7168,  7424,  7488,     0,  8192,  8193,  7168,  7424, 
+     7488,     0,  8192,  8193,  7168,  7424,  7488,  7490, 
+        0,  8192,  8193,  7168,  7424,  7488,     0,  8192, 
+     8193,  7168,  7424,  7488,  7492,     0,  8192,  8193, 
+     7168,  7424,  7488,  7492,     0,  8192,  8193,  7168, 
+     7424,  7488,  7496,  7494,     0,  8192,  8193,  7168, 
+     7424,  7488,     0,  8192,  8193,  7168,  7424,  7488, 
+     7496,     0,  8192,  8193,  7168,  7424,  7488,  7496, 
+        0,  8192,  8193,  7168,  7424,  7488,  7496,  7498, 
+        0,  8192,  8193,  7168,  7424,  7488,  7496,     0, 
+     8192,  8193,  7168,  7424,  7488,  7504,  7500,     0, 
+     8192,  8193,  7168,  7424,  7488,  7504,  7500,     0, 
+     8192,  8193,  7168,  7424,  7488,  7504,  7505,  7502, 
+        0,  8192,  8193,  7168,  7424,  7488,     0,  8192, 
+     8193,  7168,  7424,  7488,  7504,     0,  8192,  8193, 
+     7168,  7424,  7488,  7504,     0,  8192,  8193,  7168, 
+     7424,  7488,  7504,  7506,     0,  8192,  8193,  7168, 
+     7424,  7488,  7504,     0,  8192,  8193,  7168,  7424, 
+     7488,  7504,  7508,     0,  8192,  8193,  7168,  7424, 
+     7488,  7504,  7508,     0,  8192,  8193,  7168,  7424, 
+     7488,  7504,  7512,  7510,     0,  8192,  8193,  7168, 
+     7424,  7488,  7504,     0,  8192,  8193,  7168,  7424, 
+     7488,  7520,  7512,     0,  8192,  8193,  7168,  7424, 
+     7488,  7520,  7512,     0,  8192,  8193,  7168,  7424, 
+     7488,  7520,  7512,  7514,     0,  8192,  8193,  7168, 
+     7424,  7488,  7520,  7512,     0,  8192,  8193,  7168, 
+     7424,  7488,  7520,  7521,  7516,     0,  8192,  8193, 
+     7168,  7424,  7488,  7520,  7521,  7516,     0,  8192, 
+     8193,  7168,  7424,  7488,  7520,  7521,  7516,  7518, 
+        0,  8192,  8193,  7168,  7424,  7488,     0,  8192, 
+     8193,  7168,  7424,  7552,  7520,     0,  8192,  8193, 
+     7168,  7424,  7552,  7520,     0,  8192,  8193,  7168, 
+     7424,  7552,  7520,  7522,     0,  8192,  8193,  7168, 
+     7424,  7552,  7520,     0,  8192,  8193,  7168,  7424, 
+     7552,  7520,  7524,     0,  8192,  8193,  7168,  7424, 
+     7552,  7520,  7524,     0,  8192,  8193,  7168,  7424, 
+     7552,  7520,  7528,  7526,     0,  8192,  8193,  7168, 
+     7424,  7552,  7520,     0,  8192,  8193,  7168,  7424, 
+     7552,  7520,  7528,     0,  8192,  8193,  7168,  7424, 
+     7552,  7520,  7528,     0,  8192,  8193,  7168,  7424, 
+     7552,  7520,  7528,  7530,     0,  8192,  8193,  7168, 
+     7424,  7552,  7520,  7528,     0,  8192,  8193,  7168, 
+     7424,  7552,  7520,  7536,  7532,     0,  8192,  8193, 
+     7168,  7424,  7552,  7520,  7536,  7532,     0,  8192, 
+     8193,  7168,  7424,  7552,  7520,  7536,  7537,  7534, 
+        0,  8192,  8193,  7168,  7424,  7552,  7520,     0, 
+     8192,  8193,  7168,  7424,  7552,  7553,  7536,     0, 
+     8192,  8193,  7168,  7424,  7552,  7553,  7536,     0, 
+     8192,  8193,  7168,  7424,  7552,  7553,  7536,  7538, 
+        0,  8192,  8193,  7168,  7424,  7552,  7553,  7536, 
+        0,  8192,  8193,  7168,  7424,  7552,  7553,  7536, 
+     7540,     0,  8192,  8193,  7168,  7424,  7552,  7553, 
+     7536,  7540,     0,  8192,  8193,  7168,  7424,  7552, 
+     7553,  7536,  7544,  7542,     0,  8192,  8193,  7168, 
+     7424,  7552,  7553,  7536,     0,  8192,  8193,  7168, 
+     7424,  7552,  7553,  7536,  7544,     0,  8192,  8193, 
+     7168,  7424,  7552,  7553,  7555,  7544,     0,  8192, 
+     8193,  7168,  7424,  7552,  7553,  7555,  7544,  7546, 
+        0,  8192,  8193,  7168,  7424,  7552,  7553,  7555, 
+     7544,     0,  8192,  8193,  7168,  7424,  7552,  7553, 
+     7555,  7544,  7548,     0,  8192,  8193,  7168,  7424, 
+     7552,  7553,  7555,  7544,  7548,     0,  8192,  8193, 
+     7168,  7424,  7552,  7553,  7555,  7544,  7548,  7550, 
+        0,  8192,  8193,  7168,  7424,     0,  8192,  8193, 
+     7168,  7680,  7552,     0,  8192,  8193,  7168,  7680, 
+     7552,     0,  8192,  8193,  7168,  7680,  7552,  7554, 
+        0,  8192,  8193,  7168,  7680,  7552,     0,  8192, 
+     8193,  7168,  7680,  7552,  7556,     0,  8192,  8193, 
+     7168,  7680,  7552,  7556,     0,  8192,  8193,  7168, 
+     7680,  7552,  7560,  7558,     0,  8192,  8193,  7168, 
+     7680,  7552,     0,  8192,  8193,  7168,  7680,  7552, 
+     7560,     0,  8192,  8193,  7168,  7680,  7552,  7560, 
+        0,  8192,  8193,  7168,  7680,  7552,  7560,  7562, 
+        0,  8192,  8193,  7168,  7680,  7552,  7560,     0, 
+     8192,  8193,  7168,  7680,  7552,  7568,  7564,     0, 
+     8192,  8193,  7168,  7680,  7552,  7568,  7564,     0, 
+     8192,  8193,  7168,  7680,  7552,  7568,  7569,  7566, 
+        0,  8192,  8193,  7168,  7680,  7552,     0,  8192, 
+     8193,  7168,  7680,  7552,  7568,     0,  8192,  8193, 
+     7168,  7680,  7552,  7568,     0,  8192,  8193,  7168, 
+     7680,  7552,  7568,  7570,     0,  8192,  8193,  7168, 
+     7680,  7552,  7568,     0,  8192,  8193,  7168,  7680, 
+     7552,  7568,  7572,     0,  8192,  8193,  7168,  7680, 
+     7552,  7568,  7572,     0,  8192,  8193,  7168,  7680, 
+     7552,  7568,  7576,  7574,     0,  8192,  8193,  7168, 
+     7680,  7552,  7568,     0,  8192,  8193,  7168,  7680, 
+     7552,  7584,  7576,     0,  8192,  8193,  7168,  7680, 
+     7552,  7584,  7576,     0,  8192,  8193,  7168,  7680, 
+     7552,  7584,  7576,  7578,     0,  8192,  8193,  7168, 
+     7680,  7552,  7584,  7576,     0,  8192,  8193,  7168, 
+     7680,  7552,  7584,  7585,  7580,     0,  8192,  8193, 
+     7168,  7680,  7552,  7584,  7585,  7580,     0,  8192, 
+     8193,  7168,  7680,  7552,  7584,  7585,  7580,  7582, 
+        0,  8192,  8193,  7168,  7680,  7552,     0,  8192, 
+     8193,  7168,  7680,  7552,  7584,     0,  8192,  8193, 
+     7168,  7680,  7552,  7584,     0,  8192,  8193,  7168, 
+     7680,  7552,  7584,  7586,     0,  8192,  8193,  7168, 
+     7680,  7552,  7584,     0,  8192,  8193,  7168,  7680, 
+     7552,  7584,  7588,     0,  8192,  8193,  7168,  7680, 
+     7552,  7584,  7588,     0,  8192,  8193,  7168,  7680, 
+     7552,  7584,  7592,  7590,     0,  8192,  8193,  7168, 
+     7680,  7552,  7584,     0,  8192,  8193,  7168,  7680, 
+     7552,  7584,  7592,     0,  8192,  8193,  7168,  7680, 
+     7552,  7584,  7592,     0,  8192,  8193,  7168,  7680, 
+     7552,  7584,  7592,  7594,     0,  8192,  8193,  7168, 
+     7680,  7552,  7584,  7592,     0,  8192,  8193,  7168, 
+     7680,  7552,  7584,  7600,  7596,     0,  8192,  8193, 
+     7168,  7680,  7552,  7584,  7600,  7596,     0,  8192, 
+     8193,  7168,  7680,  7552,  7584,  7600,  7601,  7598, 
+        0,  8192,  8193,  7168,  7680,  7552,  7584,     0, 
+     8192,  8193,  7168,  7680,  7552,  7616,  7600,     0, 
+     8192,  8193,  7168,  7680,  7552,  7616,  7600,     0, 
+     8192,  8193,  7168,  7680,  7552,  7616,  7600,  7602, 
+        0,  8192,  8193,  7168,  7680,  7552,  7616,  7600, 
+        0,  8192,  8193,  7168,  7680,  7552,  7616,  7600, 
+     7604,     0,  8192,  8193,  7168,  7680,  7552,  7616, 
+     7600,  7604,     0,  8192,  8193,  7168,  7680,  7552, 
+     7616,  7600,  7608,  7606,     0,  8192,  8193,  7168, 
+     7680,  7552,  7616,  7600,     0,  8192,  8193,  7168, 
+     7680,  7552,  7616,  7617,  7608,     0,  8192,  8193, 
+     7168,  7680,  7552,  7616,  7617,  7608,     0,  8192, 
+     8193,  7168,  7680,  7552,  7616,  7617,  7608,  7610, 
+        0,  8192,  8193,  7168,  7680,  7552,  7616,  7617, 
+     7608,     0,  8192,  8193,  7168,  7680,  7552,  7616, 
+     7617,  7608,  7612,     0,  8192,  8193,  7168,  7680, 
+     7552,  7616,  7617,  7619,  7612,     0,  8192,  8193, 
+     7168,  7680,  7552,  7616,  7617,  7619,  7612,  7614, 
+        0,  8192,  8193,  7168,  7680,  7552,     0,  8192, 
+     8193,  7168,  7680,  7681,  7616,     0,  8192,  8193, 
+     7168,  7680,  7681,  7616,     0,  8192,  8193,  7168, 
+     7680,  7681,  7616,  7618,     0,  8192,  8193,  7168, 
+     7680,  7681,  7616,     0,  8192,  8193,  7168,  7680, 
+     7681,  7616,  7620,     0,  8192,  8193,  7168,  7680, 
+     7681,  7616,  7620,     0,  8192,  8193,  7168,  7680, 
+     7681,  7616,  7624,  7622,     0,  8192,  8193,  7168, 
+     7680,  7681,  7616,     0,  8192,  8193,  7168,  7680, 
+     7681,  7616,  7624,     0,  8192,  8193,  7168,  7680, 
+     7681,  7616,  7624,     0,  8192,  8193,  7168,  7680, 
+     7681,  7616,  7624,  7626,     0,  8192,  8193,  7168, 
+     7680,  7681,  7616,  7624,     0,  8192,  8193,  7168, 
+     7680,  7681,  7616,  7632,  7628,     0,  8192,  8193, 
+     7168,  7680,  7681,  7616,  7632,  7628,     0,  8192, 
+     8193,  7168,  7680,  7681,  7616,  7632,  7633,  7630, 
+        0,  8192,  8193,  7168,  7680,  7681,  7616,     0, 
+     8192,  8193,  7168,  7680,  7681,  7616,  7632,     0, 
+     8192,  8193,  7168,  7680,  7681,  7616,  7632,     0, 
+     8192,  8193,  7168,  7680,  7681,  7616,  7632,  7634, 
+        0,  8192,  8193,  7168,  7680,  7681,  7616,  7632, 
+        0,  8192,  8193,  7168,  7680,  7681,  7616,  7632, 
+     7636,     0,  8192,  8193,  7168,  7680,  7681,  7616, 
+     7632,  7636,     0,  8192,  8193,  7168,  7680,  7681, 
+     7616,  7632,  7640,  7638,     0,  8192,  8193,  7168, 
+     7680,  7681,  7616,  7632,     0,  8192,  8193,  7168, 
+     7680,  7681,  7616,  7648,  7640,     0,  8192,  8193, 
+     7168,  7680,  7681,  7616,  7648,  7640,     0,  8192, 
+     8193,  7168,  7680,  7681,  7616,  7648,  7640,  7642, 
+        0,  8192,  8193,  7168,  7680,  7681,  7616,  7648, 
+     7640,     0,  8192,  8193,  7168,  7680,  7681,  7616, 
+     7648,  7649,  7644,     0,  8192,  8193,  7168,  7680, 
+     7681,  7616,  7648,  7649,  7644,     0,  8192,  8193, 
+     7168,  7680,  7681,  7616,  7648,  7649,  7644,  7646, 
+        0,  8192,  8193,  7168,  7680,  7681,  7616,     0, 
+     8192,  8193,  7168,  7680,  7681,  7616,  7648,     0, 
+     8192,  8193,  7168,  7680,  7681,  7683,  7648,     0, 
+     8192,  8193,  7168,  7680,  7681,  7683,  7648,  7650, 
+        0,  8192,  8193,  7168,  7680,  7681,  7683,  7648, 
+        0,  8192,  8193,  7168,  7680,  7681,  7683,  7648, 
+     7652,     0,  8192,  8193,  7168,  7680,  7681,  7683, 
+     7648,  7652,     0,  8192,  8193,  7168,  7680,  7681, 
+     7683,  7648,  7656,  7654,     0,  8192,  8193,  7168, 
+     7680,  7681,  7683,  7648,     0,  8192,  8193,  7168, 
+     7680,  7681,  7683,  7648,  7656,     0,  8192,  8193, 
+     7168,  7680,  7681,  7683,  7648,  7656,     0,  8192, 
+     8193,  7168,  7680,  7681,  7683,  7648,  7656,  7658, 
+        0,  8192,  8193,  7168,  7680,  7681,  7683,  7648, 
+     7656,     0,  8192,  8193,  7168,  7680,  7681,  7683, 
+     7648,  7664,  7660,     0,  8192,  8193,  7168,  7680, 
+     7681,  7683,  7648,  7664,  7660,     0,  8192,  8193, 
+     7168,  7680,  7681,  7683,  7648,  7664,  7665,  7662, 
+        0,  8192,  8193,  7168,  7680,  7681,  7683,  7648, 
+        0,  8192,  8193,  7168,  7680,  7681,  7683,  7648, 
+     7664,     0,  8192,  8193,  7168,  7680,  7681,  7683, 
+     7648,  7664,     0,  8192,  8193,  7168,  7680,  7681, 
+     7683,  7648,  7664,  7666,     0,  8192,  8193,  7168, 
+     7680,  7681,  7683,  7687,  7664,     0,  8192,  8193, 
+     7168,  7680,  7681,  7683,  7687,  7664,  7668,     0, 
+     8192,  8193,  7168,  7680,  7681,  7683,  7687,  7664, 
+     7668,     0,  8192,  8193,  7168,  7680,  7681,  7683, 
+     7687,  7664,  7672,  7670,     0,  8192,  8193,  7168, 
+     7680,  7681,  7683,  7687,  7664,     0,  8192,  8193, 
+     7168,  7680,  7681,  7683,  7687,  7664,  7672,     0, 
+     8192,  8193,  7168,  7680,  7681,  7683,  7687,  7664, 
+     7672,     0,  8192,  8193,  7168,  7680,  7681,  7683, 
+     7687,  7664,  7672,  7674,     0,  8192,  8193,  7168, 
+     7680,  7681,  7683,  7687,  7664,  7672,     0,  8192, 
+     8193,  7168,  7680,  7681,  7683,  7687,  7664,  7672, 
+     7676,     0,  8192,  8193,  7168,  7680,  7681,  7683, 
+     7687,  7664,  7672,  7676,     0,  8192,  8193,  7168, 
+     7680,  7681,  7683,  7687,  7664,  7672,  7676,  7678, 
+        0,  8192,  8193,  7168,     0,  8192,  8193,  7168, 
+     7680,     0,  8192,  8193,  7168,  7680,     0,  8192, 
+     8193,  7168,  7680,  7682,     0,  8192,  8193,  8195, 
+     7680,     0,  8192,  8193,  8195,  7680,  7684,     0, 
+     8192,  8193,  8195,  7680,  7684,     0,  8192,  8193, 
+     8195,  7680,  7688,  7686,     0,  8192,  8193,  8195, 
+     7680,     0,  8192,  8193,  8195,  7680,  7688,     0, 
+     8192,  8193,  8195,  7680,  7688,     0,  8192,  8193, 
+     8195,  7680,  7688,  7690,     0,  8192,  8193,  8195, 
+     7680,  7688,     0,  8192,  8193,  8195,  7680,  7696, 
+     7692,     0,  8192,  8193,  8195,  7680,  7696,  7692, 
+        0,  8192,  8193,  8195,  7680,  7696,  7697,  7694, 
+        0,  8192,  8193,  8195,  7680,     0,  8192,  8193, 
+     8195,  7680,  7696,     0,  8192,  8193,  8195,  7680, 
+     7696,     0,  8192,  8193,  8195,  7680,  7696,  7698, 
+        0,  8192,  8193,  8195,  7680,  7696,     0,  8192, 
+     8193,  8195,  7680,  7696,  7700,     0,  8192,  8193, 
+     8195,  7680,  7696,  7700,     0,  8192,  8193,  8195, 
+     7680,  7696,  7704,  7702,     0,  8192,  8193,  8195, 
+     7680,  7696,     0,  8192,  8193,  8195,  7680,  7712, 
+     7704,     0,  8192,  8193,  8195,  7680,  7712,  7704, 
+        0,  8192,  8193,  8195,  7680,  7712,  7704,  7706, 
+        0,  8192,  8193,  8195,  7680,  7712,  7704,     0, 
+     8192,  8193,  8195,  7680,  7712,  7713,  7708,     0, 
+     8192,  8193,  8195,  7680,  7712,  7713,  7708,     0, 
+     8192,  8193,  8195,  7680,  7712,  7713,  7708,  7710, 
+        0,  8192,  8193,  8195,  7680,     0,  8192,  8193, 
+     8195,  7680,  7712,     0,  8192,  8193,  8195,  7680, 
+     7712,     0,  8192,  8193,  8195,  7680,  7712,  7714, 
+        0,  8192,  8193,  8195,  7680,  7712,     0,  8192, 
+     8193,  8195,  7680,  7712,  7716,     0,  8192,  8193, 
+     8195,  7680,  7712,  7716,     0,  8192,  8193,  8195, 
+     7680,  7712,  7720,  7718,     0,  8192,  8193,  8195, 
+     7680,  7712,     0,  8192,  8193,  8195,  7680,  7712, 
+     7720,     0,  8192,  8193,  8195,  7680,  7712,  7720, 
+        0,  8192,  8193,  8195,  7680,  7712,  7720,  7722, 
+        0,  8192,  8193,  8195,  7680,  7712,  7720,     0, 
+     8192,  8193,  8195,  7680,  7712,  7728,  7724,     0, 
+     8192,  8193,  8195,  7680,  7712,  7728,  7724,     0, 
+     8192,  8193,  8195,  7680,  7712,  7728,  7729,  7726, 
+        0,  8192,  8193,  8195,  7680,  7712,     0,  8192, 
+     8193,  8195,  7680,  7744,  7728,     0,  8192,  8193, 
+     8195,  7680,  7744,  7728,     0,  8192,  8193,  8195, 
+     7680,  7744,  7728,  7730,     0,  8192,  8193,  8195, 
+     7680,  7744,  7728,     0,  8192,  8193,  8195,  7680, 
+     7744,  7728,  7732,     0,  8192,  8193,  8195,  7680, 
+     7744,  7728,  7732,     0,  8192,  8193,  8195,  7680, 
+     7744,  7728,  7736,  7734,     0,  8192,  8193,  8195, 
+     7680,  7744,  7728,     0,  8192,  8193,  8195,  7680, 
+     7744,  7745,  7736,     0,  8192,  8193,  8195,  7680, 
+     7744,  7745,  7736,     0,  8192,  8193,  8195,  7680, 
+     7744,  7745,  7736,  7738,     0,  8192,  8193,  8195, 
+     7680,  7744,  7745,  7736,     0,  8192,  8193,  8195, 
+     7680,  7744,  7745,  7736,  7740,     0,  8192,  8193, 
+     8195,  7680,  7744,  7745,  7747,  7740,     0,  8192, 
+     8193,  8195,  7680,  7744,  7745,  7747,  7740,  7742, 
+        0,  8192,  8193,  8195,  7680,     0,  8192,  8193, 
+     8195,  7680,  7744,     0,  8192,  8193,  8195,  7680, 
+     7744,     0,  8192,  8193,  8195,  7680,  7744,  7746, 
+        0,  8192,  8193,  8195,  7680,  7744,     0,  8192, 
+     8193,  8195,  7680,  7744,  7748,     0,  8192,  8193, 
+     8195,  7680,  7744,  7748,     0,  8192,  8193,  8195, 
+     7680,  7744,  7752,  7750,     0,  8192,  8193,  8195, 
+     7680,  7744,     0,  8192,  8193,  8195,  7680,  7744, 
+     7752,     0,  8192,  8193,  8195,  7680,  7744,  7752, 
+        0,  8192,  8193,  8195,  7680,  7744,  7752,  7754, 
+        0,  8192,  8193,  8195,  7680,  7744,  7752,     0, 
+     8192,  8193,  8195,  7680,  7744,  7760,  7756,     0, 
+     8192,  8193,  8195,  7680,  7744,  7760,  7756,     0, 
+     8192,  8193,  8195,  7680,  7744,  7760,  7761,  7758, 
+        0,  8192,  8193,  8195,  7680,  7744,     0,  8192, 
+     8193,  8195,  7680,  7744,  7760,     0,  8192,  8193, 
+     8195,  7680,  7744,  7760,     0,  8192,  8193,  8195, 
+     7680,  7744,  7760,  7762,     0,  8192,  8193,  8195, 
+     7680,  7744,  7760,     0,  8192,  8193,  8195,  7680, 
+     7744,  7760,  7764,     0,  8192,  8193,  8195,  7680, 
+     7744,  7760,  7764,     0,  8192,  8193,  8195,  7680, 
+     7744,  7760,  7768,  7766,     0,  8192,  8193,  8195, 
+     7680,  7744,  7760,     0,  8192,  8193,  8195,  7680, 
+     7744,  7776,  7768,     0,  8192,  8193,  8195,  7680, 
+     7744,  7776,  7768,     0,  8192,  8193,  8195,  7680, 
+     7744,  7776,  7768,  7770,     0,  8192,  8193,  8195, 
+     7680,  7744,  7776,  7768,     0,  8192,  8193,  8195, 
+     7680,  7744,  7776,  7777,  7772,     0,  8192,  8193, 
+     8195,  7680,  7744,  7776,  7777,  7772,     0,  8192, 
+     8193,  8195,  7680,  7744,  7776,  7777,  7772,  7774, 
+        0,  8192,  8193,  8195,  7680,  7744,     0,  8192, 
+     8193,  8195,  7680,  7808,  7776,     0,  8192,  8193, 
+     8195,  7680,  7808,  7776,     0,  8192,  8193,  8195, 
+     7680,  7808,  7776,  7778,     0,  8192,  8193,  8195, 
+     7680,  7808,  7776,     0,  8192,  8193,  8195,  7680, 
+     7808,  7776,  7780,     0,  8192,  8193,  8195,  7680, 
+     7808,  7776,  7780,     0,  8192,  8193,  8195,  7680, 
+     7808,  7776,  7784,  7782,     0,  8192,  8193,  8195, 
+     7680,  7808,  7776,     0,  8192,  8193,  8195,  7680, 
+     7808,  7776,  7784,     0,  8192,  8193,  8195,  7680, 
+     7808,  7776,  7784,     0,  8192,  8193,  8195,  7680, 
+     7808,  7776,  7784,  7786,     0,  8192,  8193,  8195, 
+     7680,  7808,  7776,  7784,     0,  8192,  8193,  8195, 
+     7680,  7808,  7776,  7792,  7788,     0,  8192,  8193, 
+     8195,  7680,  7808,  7776,  7792,  7788,     0,  8192, 
+     8193,  8195,  7680,  7808,  7776,  7792,  7793,  7790, 
+        0,  8192,  8193,  8195,  7680,  7808,  7776,     0, 
+     8192,  8193,  8195,  7680,  7808,  7809,  7792,     0, 
+     8192,  8193,  8195,  7680,  7808,  7809,  7792,     0, 
+     8192,  8193,  8195,  7680,  7808,  7809,  7792,  7794, 
+        0,  8192,  8193,  8195,  7680,  7808,  7809,  7792, 
+        0,  8192,  8193,  8195,  7680,  7808,  7809,  7792, 
+     7796,     0,  8192,  8193,  8195,  7680,  7808,  7809, 
+     7792,  7796,     0,  8192,  8193,  8195,  7680,  7808, 
+     7809,  7792,  7800,  7798,     0,  8192,  8193,  8195, 
+     7680,  7808,  7809,  7792,     0,  8192,  8193,  8195, 
+     7680,  7808,  7809,  7792,  7800,     0,  8192,  8193, 
+     8195,  7680,  7808,  7809,  7811,  7800,     0,  8192, 
+     8193,  8195,  7680,  7808,  7809,  7811,  7800,  7802, 
+        0,  8192,  8193,  8195,  7680,  7808,  7809,  7811, 
+     7800,     0,  8192,  8193,  8195,  7680,  7808,  7809, 
+     7811,  7800,  7804,     0,  8192,  8193,  8195,  7680, 
+     7808,  7809,  7811,  7800,  7804,     0,  8192,  8193, 
+     8195,  7680,  7808,  7809,  7811,  7800,  7804,  7806, 
+        0,  8192,  8193,  8195,  7680,     0,  8192,  8193, 
+     8195,  7680,  7808,     0,  8192,  8193,  8195,  7680, 
+     7808,     0,  8192,  8193,  8195,  7680,  7808,  7810, 
+        0,  8192,  8193,  8195,  7680,  7808,     0,  8192, 
+     8193,  8195,  7680,  7808,  7812,     0,  8192,  8193, 
+     8195,  7680,  7808,  7812,     0,  8192,  8193,  8195, 
+     7680,  7808,  7816,  7814,     0,  8192,  8193,  8195, 
+     7680,  7808,     0,  8192,  8193,  8195,  7680,  7808, 
+     7816,     0,  8192,  8193,  8195,  7680,  7808,  7816, 
+        0,  8192,  8193,  8195,  7680,  7808,  7816,  7818, 
+        0,  8192,  8193,  8195,  7680,  7808,  7816,     0, 
+     8192,  8193,  8195,  7680,  7808,  7824,  7820,     0, 
+     8192,  8193,  8195,  7680,  7808,  7824,  7820,     0, 
+     8192,  8193,  8195,  7680,  7808,  7824,  7825,  7822, 
+        0,  8192,  8193,  8195,  7680,  7808,     0,  8192, 
+     8193,  8195,  7680,  7808,  7824,     0,  8192,  8193, 
+     8195,  7680,  7808,  7824,     0,  8192,  8193,  8195, 
+     7680,  7808,  7824,  7826,     0,  8192,  8193,  8195, 
+     7680,  7808,  7824,     0,  8192,  8193,  8195,  7680, 
+     7808,  7824,  7828,     0,  8192,  8193,  8195,  7680, 
+     7808,  7824,  7828,     0,  8192,  8193,  8195,  7680, 
+     7808,  7824,  7832,  7830,     0,  8192,  8193,  8195, 
+     7680,  7808,  7824,     0,  8192,  8193,  8195,  7680, 
+     7808,  7840,  7832,     0,  8192,  8193,  8195,  7680, 
+     7808,  7840,  7832,     0,  8192,  8193,  8195,  7680, 
+     7808,  7840,  7832,  7834,     0,  8192,  8193,  8195, 
+     7680,  7808,  7840,  7832,     0,  8192,  8193,  8195, 
+     7680,  7808,  7840,  7841,  7836,     0,  8192,  8193, 
+     8195,  7680,  7808,  7840,  7841,  7836,     0,  8192, 
+     8193,  8195,  7680,  7808,  7840,  7841,  7836,  7838, 
+        0,  8192,  8193,  8195,  7680,  7808,     0,  8192, 
+     8193,  8195,  7680,  7808,  7840,     0,  8192,  8193, 
+     8195,  7680,  7808,  7840,     0,  8192,  8193,  8195, 
+     7680,  7808,  7840,  7842,     0,  8192,  8193,  8195, 
+     7680,  7808,  7840,     0,  8192,  8193,  8195,  7680, 
+     7808,  7840,  7844,     0,  8192,  8193,  8195,  7680, 
+     7808,  7840,  7844,     0,  8192,  8193,  8195,  7680, 
+     7808,  7840,  7848,  7846,     0,  8192,  8193,  8195, 
+     7680,  7808,  7840,     0,  8192,  8193,  8195,  7680, 
+     7808,  7840,  7848,     0,  8192,  8193,  8195,  7680, 
+     7808,  7840,  7848,     0,  8192,  8193,  8195,  7680, 
+     7808,  7840,  7848,  7850,     0,  8192,  8193,  8195, 
+     7680,  7808,  7840,  7848,     0,  8192,  8193,  8195, 
+     7680,  7808,  7840,  7856,  7852,     0,  8192,  8193, 
+     8195,  7680,  7808,  7840,  7856,  7852,     0,  8192, 
+     8193,  8195,  7680,  7808,  7840,  7856,  7857,  7854, 
+        0,  8192,  8193,  8195,  7680,  7808,  7840,     0, 
+     8192,  8193,  8195,  7680,  7808,  7872,  7856,     0, 
+     8192,  8193,  8195,  7680,  7808,  7872,  7856,     0, 
+     8192,  8193,  8195,  7680,  7808,  7872,  7856,  7858, 
+        0,  8192,  8193,  8195,  7680,  7808,  7872,  7856, 
+        0,  8192,  8193,  8195,  7680,  7808,  7872,  7856, 
+     7860,     0,  8192,  8193,  8195,  7680,  7808,  7872, 
+     7856,  7860,     0,  8192,  8193,  8195,  7680,  7808, 
+     7872,  7856,  7864,  7862,     0,  8192,  8193,  8195, 
+     7680,  7808,  7872,  7856,     0,  8192,  8193,  8195, 
+     7680,  7808,  7872,  7873,  7864,     0,  8192,  8193, 
+     8195,  7680,  7808,  7872,  7873,  7864,     0,  8192, 
+     8193,  8195,  7680,  7808,  7872,  7873,  7864,  7866, 
+        0,  8192,  8193,  8195,  7680,  7808,  7872,  7873, 
+     7864,     0,  8192,  8193,  8195,  7680,  7808,  7872, 
+     7873,  7864,  7868,     0,  8192,  8193,  8195,  7680, 
+     7808,  7872,  7873,  7875,  7868,     0,  8192,  8193, 
+     8195,  7680,  7808,  7872,  7873,  7875,  7868,  7870, 
+        0,  8192,  8193,  8195,  7680,  7808,     0,  8192, 
+     8193,  8195,  7680,  7936,  7872,     0,  8192,  8193, 
+     8195,  7680,  7936,  7872,     0,  8192,  8193,  8195, 
+     7680,  7936,  7872,  7874,     0,  8192,  8193,  8195, 
+     7680,  7936,  7872,     0,  8192,  8193,  8195,  7680, 
+     7936,  7872,  7876,     0,  8192,  8193,  8195,  7680, 
+     7936,  7872,  7876,     0,  8192,  8193,  8195,  7680, 
+     7936,  7872,  7880,  7878,     0,  8192,  8193,  8195, 
+     7680,  7936,  7872,     0,  8192,  8193,  8195,  7680, 
+     7936,  7872,  7880,     0,  8192,  8193,  8195,  7680, 
+     7936,  7872,  7880,     0,  8192,  8193,  8195,  7680, 
+     7936,  7872,  7880,  7882,     0,  8192,  8193,  8195, 
+     7680,  7936,  7872,  7880,     0,  8192,  8193,  8195, 
+     7680,  7936,  7872,  7888,  7884,     0,  8192,  8193, 
+     8195,  7680,  7936,  7872,  7888,  7884,     0,  8192, 
+     8193,  8195,  7680,  7936,  7872,  7888,  7889,  7886, 
+        0,  8192,  8193,  8195,  7680,  7936,  7872,     0, 
+     8192,  8193,  8195,  7680,  7936,  7872,  7888,     0, 
+     8192,  8193,  8195,  7680,  7936,  7872,  7888,     0, 
+     8192,  8193,  8195,  7680,  7936,  7872,  7888,  7890, 
+        0,  8192,  8193,  8195,  7680,  7936,  7872,  7888, 
+        0,  8192,  8193,  8195,  7680,  7936,  7872,  7888, 
+     7892,     0,  8192,  8193,  8195,  7680,  7936,  7872, 
+     7888,  7892,     0,  8192,  8193,  8195,  7680,  7936, 
+     7872,  7888,  7896,  7894,     0,  8192,  8193,  8195, 
+     7680,  7936,  7872,  7888,     0,  8192,  8193,  8195, 
+     7680,  7936,  7872,  7904,  7896,     0,  8192,  8193, 
+     8195,  7680,  7936,  7872,  7904,  7896,     0,  8192, 
+     8193,  8195,  7680,  7936,  7872,  7904,  7896,  7898, 
+        0,  8192,  8193,  8195,  7680,  7936,  7872,  7904, 
+     7896,     0,  8192,  8193,  8195,  7680,  7936,  7872, 
+     7904,  7905,  7900,     0,  8192,  8193,  8195,  7680, 
+     7936,  7872,  7904,  7905,  7900,     0,  8192,  8193, 
+     8195,  7680,  7936,  7872,  7904,  7905,  7900,  7902, 
+        0,  8192,  8193,  8195,  7680,  7936,  7872,     0, 
+     8192,  8193,  8195,  7680,  7936,  7937,  7904,     0, 
+     8192,  8193,  8195,  7680,  7936,  7937,  7904,     0, 
+     8192,  8193,  8195,  7680,  7936,  7937,  7904,  7906, 
+        0,  8192,  8193,  8195,  7680,  7936,  7937,  7904, 
+        0,  8192,  8193,  8195,  7680,  7936,  7937,  7904, 
+     7908,     0,  8192,  8193,  8195,  7680,  7936,  7937, 
+     7904,  7908,     0,  8192,  8193,  8195,  7680,  7936, 
+     7937,  7904,  7912,  7910,     0,  8192,  8193,  8195, 
+     7680,  7936,  7937,  7904,     0,  8192,  8193,  8195, 
+     7680,  7936,  7937,  7904,  7912,     0,  8192,  8193, 
+     8195,  7680,  7936,  7937,  7904,  7912,     0,  8192, 
+     8193,  8195,  7680,  7936,  7937,  7904,  7912,  7914, 
+        0,  8192,  8193,  8195,  7680,  7936,  7937,  7904, 
+     7912,     0,  8192,  8193,  8195,  7680,  7936,  7937, 
+     7904,  7920,  7916,     0,  8192,  8193,  8195,  7680, 
+     7936,  7937,  7904,  7920,  7916,     0,  8192,  8193, 
+     8195,  7680,  7936,  7937,  7904,  7920,  7921,  7918, 
+        0,  8192,  8193,  8195,  7680,  7936,  7937,  7904, 
+        0,  8192,  8193,  8195,  7680,  7936,  7937,  7904, 
+     7920,     0,  8192,  8193,  8195,  7680,  7936,  7937, 
+     7939,  7920,     0,  8192,  8193,  8195,  7680,  7936, 
+     7937,  7939,  7920,  7922,     0,  8192,  8193,  8195, 
+     7680,  7936,  7937,  7939,  7920,     0,  8192,  8193, 
+     8195,  7680,  7936,  7937,  7939,  7920,  7924,     0, 
+     8192,  8193,  8195,  7680,  7936,  7937,  7939,  7920, 
+     7924,     0,  8192,  8193,  8195,  7680,  7936,  7937, 
+     7939,  7920,  7928,  7926,     0,  8192,  8193,  8195, 
+     7680,  7936,  7937,  7939,  7920,     0,  8192,  8193, 
+     8195,  7680,  7936,  7937,  7939,  7920,  7928,     0, 
+     8192,  8193,  8195,  7680,  7936,  7937,  7939,  7920, 
+     7928,     0,  8192,  8193,  8195,  7680,  7936,  7937, 
+     7939,  7920,  7928,  7930,     0,  8192,  8193,  8195, 
+     7680,  7936,  7937,  7939,  7943,  7928,     0,  8192, 
+     8193,  8195,  7680,  7936,  7937,  7939,  7943,  7928, 
+     7932,     0,  8192,  8193,  8195,  7680,  7936,  7937, 
+     7939,  7943,  7928,  7932,     0,  8192,  8193,  8195, 
+     7680,  7936,  7937,  7939,  7943,  7928,  7932,  7934, 
+        0,  8192,  8193,  8195,  7680,     0,  8192,  8193, 
+     8195,  7680,  7936,     0,  8192,  8193,  8195,  7680, 
+     7936,     0,  8192,  8193,  8195,  7680,  7936,  7938, 
+        0,  8192,  8193,  8195,  7680,  7936,     0,  8192, 
+     8193,  8195,  7680,  7936,  7940,     0,  8192,  8193, 
+     8195,  7680,  7936,  7940,     0,  8192,  8193,  8195, 
+     7680,  7936,  7944,  7942,     0,  8192,  8193,  8195, 
+     8199,  7936,     0,  8192,  8193,  8195,  8199,  7936, 
+     7944,     0,  8192,  8193,  8195,  8199,  7936,  7944, 
+        0,  8192,  8193,  8195,  8199,  7936,  7944,  7946, 
+        0,  8192,  8193,  8195,  8199,  7936,  7944,     0, 
+     8192,  8193,  8195,  8199,  7936,  7952,  7948,     0, 
+     8192,  8193,  8195,  8199,  7936,  7952,  7948,     0, 
+     8192,  8193,  8195,  8199,  7936,  7952,  7953,  7950, 
+        0,  8192,  8193,  8195,  8199,  7936,     0,  8192, 
+     8193,  8195,  8199,  7936,  7952,     0,  8192,  8193, 
+     8195,  8199,  7936,  7952,     0,  8192,  8193,  8195, 
+     8199,  7936,  7952,  7954,     0,  8192,  8193,  8195, 
+     8199,  7936,  7952,     0,  8192,  8193,  8195,  8199, 
+     7936,  7952,  7956,     0,  8192,  8193,  8195,  8199, 
+     7936,  7952,  7956,     0,  8192,  8193,  8195,  8199, 
+     7936,  7952,  7960,  7958,     0,  8192,  8193,  8195, 
+     8199,  7936,  7952,     0,  8192,  8193,  8195,  8199, 
+     7936,  7968,  7960,     0,  8192,  8193,  8195,  8199, 
+     7936,  7968,  7960,     0,  8192,  8193,  8195,  8199, 
+     7936,  7968,  7960,  7962,     0,  8192,  8193,  8195, 
+     8199,  7936,  7968,  7960,     0,  8192,  8193,  8195, 
+     8199,  7936,  7968,  7969,  7964,     0,  8192,  8193, 
+     8195,  8199,  7936,  7968,  7969,  7964,     0,  8192, 
+     8193,  8195,  8199,  7936,  7968,  7969,  7964,  7966, 
+        0,  8192,  8193,  8195,  8199,  7936,     0,  8192, 
+     8193,  8195,  8199,  7936,  7968,     0,  8192,  8193, 
+     8195,  8199,  7936,  7968,     0,  8192,  8193,  8195, 
+     8199,  7936,  7968,  7970,     0,  8192,  8193,  8195, 
+     8199,  7936,  7968,     0,  8192,  8193,  8195,  8199, 
+     7936,  7968,  7972,     0,  8192,  8193,  8195,  8199, 
+     7936,  7968,  7972,     0,  8192,  8193,  8195,  8199, 
+     7936,  7968,  7976,  7974,     0,  8192,  8193,  8195, 
+     8199,  7936,  7968,     0,  8192,  8193,  8195,  8199, 
+     7936,  7968,  7976,     0,  8192,  8193,  8195,  8199, 
+     7936,  7968,  7976,     0,  8192,  8193,  8195,  8199, 
+     7936,  7968,  7976,  7978,     0,  8192,  8193,  8195, 
+     8199,  7936,  7968,  7976,     0,  8192,  8193,  8195, 
+     8199,  7936,  7968,  7984,  7980,     0,  8192,  8193, 
+     8195,  8199,  7936,  7968,  7984,  7980,     0,  8192, 
+     8193,  8195,  8199,  7936,  7968,  7984,  7985,  7982, 
+        0,  8192,  8193,  8195,  8199,  7936,  7968,     0, 
+     8192,  8193,  8195,  8199,  7936,  8000,  7984,     0, 
+     8192,  8193,  8195,  8199,  7936,  8000,  7984,     0, 
+     8192,  8193,  8195,  8199,  7936,  8000,  7984,  7986, 
+        0,  8192,  8193,  8195,  8199,  7936,  8000,  7984, 
+        0,  8192,  8193,  8195,  8199,  7936,  8000,  7984, 
+     7988,     0,  8192,  8193,  8195,  8199,  7936,  8000, 
+     7984,  7988,     0,  8192,  8193,  8195,  8199,  7936, 
+     8000,  7984,  7992,  7990,     0,  8192,  8193,  8195, 
+     8199,  7936,  8000,  7984,     0,  8192,  8193,  8195, 
+     8199,  7936,  8000,  8001,  7992,     0,  8192,  8193, 
+     8195,  8199,  7936,  8000,  8001,  7992,     0,  8192, 
+     8193,  8195,  8199,  7936,  8000,  8001,  7992,  7994, 
+        0,  8192,  8193,  8195,  8199,  7936,  8000,  8001, 
+     7992,     0,  8192,  8193,  8195,  8199,  7936,  8000, 
+     8001,  7992,  7996,     0,  8192,  8193,  8195,  8199, 
+     7936,  8000,  8001,  8003,  7996,     0,  8192,  8193, 
+     8195,  8199,  7936,  8000,  8001,  8003,  7996,  7998, 
+        0,  8192,  8193,  8195,  8199,  7936,     0,  8192, 
+     8193,  8195,  8199,  7936,  8000,     0,  8192,  8193, 
+     8195,  8199,  7936,  8000,     0,  8192,  8193,  8195, 
+     8199,  7936,  8000,  8002,     0,  8192,  8193,  8195, 
+     8199,  7936,  8000,     0,  8192,  8193,  8195,  8199, 
+     7936,  8000,  8004,     0,  8192,  8193,  8195,  8199, 
+     7936,  8000,  8004,     0,  8192,  8193,  8195,  8199, 
+     7936,  8000,  8008,  8006,     0,  8192,  8193,  8195, 
+     8199,  7936,  8000,     0,  8192,  8193,  8195,  8199, 
+     7936,  8000,  8008,     0,  8192,  8193,  8195,  8199, 
+     7936,  8000,  8008,     0,  8192,  8193,  8195,  8199, 
+     7936,  8000,  8008,  8010,     0,  8192,  8193,  8195, 
+     8199,  7936,  8000,  8008,     0,  8192,  8193,  8195, 
+     8199,  7936,  8000,  8016,  8012,     0,  8192,  8193, 
+     8195,  8199,  7936,  8000,  8016,  8012,     0,  8192, 
+     8193,  8195,  8199,  7936,  8000,  8016,  8017,  8014, 
+        0,  8192,  8193,  8195,  8199,  7936,  8000,     0, 
+     8192,  8193,  8195,  8199,  7936,  8000,  8016,     0, 
+     8192,  8193,  8195,  8199,  7936,  8000,  8016,     0, 
+     8192,  8193,  8195,  8199,  7936,  8000,  8016,  8018, 
+        0,  8192,  8193,  8195,  8199,  7936,  8000,  8016, 
+        0,  8192,  8193,  8195,  8199,  7936,  8000,  8016, 
+     8020,     0,  8192,  8193,  8195,  8199,  7936,  8000, 
+     8016,  8020,     0,  8192,  8193,  8195,  8199,  7936, 
+     8000,  8016,  8024,  8022,     0,  8192,  8193,  8195, 
+     8199,  7936,  8000,  8016,     0,  8192,  8193,  8195, 
+     8199,  7936,  8000,  8032,  8024,     0,  8192,  8193, 
+     8195,  8199,  7936,  8000,  8032,  8024,     0,  8192, 
+     8193,  8195,  8199,  7936,  8000,  8032,  8024,  8026, 
+        0,  8192,  8193,  8195,  8199,  7936,  8000,  8032, 
+     8024,     0,  8192,  8193,  8195,  8199,  7936,  8000, 
+     8032,  8033,  8028,     0,  8192,  8193,  8195,  8199, 
+     7936,  8000,  8032,  8033,  8028,     0,  8192,  8193, 
+     8195,  8199,  7936,  8000,  8032,  8033,  8028,  8030, 
+        0,  8192,  8193,  8195,  8199,  7936,  8000,     0, 
+     8192,  8193,  8195,  8199,  7936,  8064,  8032,     0, 
+     8192,  8193,  8195,  8199,  7936,  8064,  8032,     0, 
+     8192,  8193,  8195,  8199,  7936,  8064,  8032,  8034, 
+        0,  8192,  8193,  8195,  8199,  7936,  8064,  8032, 
+        0,  8192,  8193,  8195,  8199,  7936,  8064,  8032, 
+     8036,     0,  8192,  8193,  8195,  8199,  7936,  8064, 
+     8032,  8036,     0,  8192,  8193,  8195,  8199,  7936, 
+     8064,  8032,  8040,  8038,     0,  8192,  8193,  8195, 
+     8199,  7936,  8064,  8032,     0,  8192,  8193,  8195, 
+     8199,  7936,  8064,  8032,  8040,     0,  8192,  8193, 
+     8195,  8199,  7936,  8064,  8032,  8040,     0,  8192, 
+     8193,  8195,  8199,  7936,  8064,  8032,  8040,  8042, 
+        0,  8192,  8193,  8195,  8199,  7936,  8064,  8032, 
+     8040,     0,  8192,  8193,  8195,  8199,  7936,  8064, 
+     8032,  8048,  8044,     0,  8192,  8193,  8195,  8199, 
+     7936,  8064,  8032,  8048,  8044,     0,  8192,  8193, 
+     8195,  8199,  7936,  8064,  8032,  8048,  8049,  8046, 
+        0,  8192,  8193,  8195,  8199,  7936,  8064,  8032, 
+        0,  8192,  8193,  8195,  8199,  7936,  8064,  8065, 
+     8048,     0,  8192,  8193,  8195,  8199,  7936,  8064, 
+     8065,  8048,     0,  8192,  8193,  8195,  8199,  7936, 
+     8064,  8065,  8048,  8050,     0,  8192,  8193,  8195, 
+     8199,  7936,  8064,  8065,  8048,     0,  8192,  8193, 
+     8195,  8199,  7936,  8064,  8065,  8048,  8052,     0, 
+     8192,  8193,  8195,  8199,  7936,  8064,  8065,  8048, 
+     8052,     0,  8192,  8193,  8195,  8199,  7936,  8064, 
+     8065,  8048,  8056,  8054,     0,  8192,  8193,  8195, 
+     8199,  7936,  8064,  8065,  8048,     0,  8192,  8193, 
+     8195,  8199,  7936,  8064,  8065,  8048,  8056,     0, 
+     8192,  8193,  8195,  8199,  7936,  8064,  8065,  8067, 
+     8056,     0,  8192,  8193,  8195,  8199,  7936,  8064, 
+     8065,  8067,  8056,  8058,     0,  8192,  8193,  8195, 
+     8199,  7936,  8064,  8065,  8067,  8056,     0,  8192, 
+     8193,  8195,  8199,  7936,  8064,  8065,  8067,  8056, 
+     8060,     0,  8192,  8193,  8195,  8199,  7936,  8064, 
+     8065,  8067,  8056,  8060,     0,  8192,  8193,  8195, 
+     8199,  7936,  8064,  8065,  8067,  8056,  8060,  8062, 
+        0,  8192,  8193,  8195,  8199,  7936,     0,  8192, 
+     8193,  8195,  8199,  7936,  8064,     0,  8192,  8193, 
+     8195,  8199,  7936,  8064,     0,  8192,  8193,  8195, 
+     8199,  7936,  8064,  8066,     0,  8192,  8193,  8195, 
+     8199,  7936,  8064,     0,  8192,  8193,  8195,  8199, 
+     7936,  8064,  8068,     0,  8192,  8193,  8195,  8199, 
+     7936,  8064,  8068,     0,  8192,  8193,  8195,  8199, 
+     7936,  8064,  8072,  8070,     0,  8192,  8193,  8195, 
+     8199,  7936,  8064,     0,  8192,  8193,  8195,  8199, 
+     7936,  8064,  8072,     0,  8192,  8193,  8195,  8199, 
+     7936,  8064,  8072,     0,  8192,  8193,  8195,  8199, 
+     7936,  8064,  8072,  8074,     0,  8192,  8193,  8195, 
+     8199,  7936,  8064,  8072,     0,  8192,  8193,  8195, 
+     8199,  7936,  8064,  8080,  8076,     0,  8192,  8193, 
+     8195,  8199,  7936,  8064,  8080,  8076,     0,  8192, 
+     8193,  8195,  8199,  7936,  8064,  8080,  8081,  8078, 
+        0,  8192,  8193,  8195,  8199,  8207,  8064,     0, 
+     8192,  8193,  8195,  8199,  8207,  8064,  8080,     0, 
+     8192,  8193,  8195,  8199,  8207,  8064,  8080,     0, 
+     8192,  8193,  8195,  8199,  8207,  8064,  8080,  8082, 
+        0,  8192,  8193,  8195,  8199,  8207,  8064,  8080, 
+        0,  8192,  8193,  8195,  8199,  8207,  8064,  8080, 
+     8084,     0,  8192,  8193,  8195,  8199,  8207,  8064, 
+     8080,  8084,     0,  8192,  8193,  8195,  8199,  8207, 
+     8064,  8080,  8088,  8086,     0,  8192,  8193,  8195, 
+     8199,  8207,  8064,  8080,     0,  8192,  8193,  8195, 
+     8199,  8207,  8064,  8096,  8088,     0,  8192,  8193, 
+     8195,  8199,  8207,  8064,  8096,  8088,     0,  8192, 
+     8193,  8195,  8199,  8207,  8064,  8096,  8088,  8090, 
+        0,  8192,  8193,  8195,  8199,  8207,  8064,  8096, 
+     8088,     0,  8192,  8193,  8195,  8199,  8207,  8064, 
+     8096,  8097,  8092,     0,  8192,  8193,  8195,  8199, 
+     8207,  8064,  8096,  8097,  8092,     0,  8192,  8193, 
+     8195,  8199,  8207,  8064,  8096,  8097,  8092,  8094, 
+        0,  8192,  8193,  8195,  8199,  8207,  8064,     0, 
+     8192,  8193,  8195,  8199,  8207,  8064,  8096,     0, 
+     8192,  8193,  8195,  8199,  8207,  8064,  8096,     0, 
+     8192,  8193,  8195,  8199,  8207,  8064,  8096,  8098, 
+        0,  8192,  8193,  8195,  8199,  8207,  8064,  8096, 
+        0,  8192,  8193,  8195,  8199,  8207,  8064,  8096, 
+     8100,     0,  8192,  8193,  8195,  8199,  8207,  8064, 
+     8096,  8100,     0,  8192,  8193,  8195,  8199,  8207, 
+     8064,  8096,  8104,  8102,     0,  8192,  8193,  8195, 
+     8199,  8207,  8064,  8096,     0,  8192,  8193,  8195, 
+     8199,  8207,  8064,  8096,  8104,     0,  8192,  8193, 
+     8195,  8199,  8207,  8064,  8096,  8104,     0,  8192, 
+     8193,  8195,  8199,  8207,  8064,  8096,  8104,  8106, 
+        0,  8192,  8193,  8195,  8199,  8207,  8064,  8096, 
+     8104,     0,  8192,  8193,  8195,  8199,  8207,  8064, 
+     8096,  8112,  8108,     0,  8192,  8193,  8195,  8199, 
+     8207,  8064,  8096,  8112,  8108,     0,  8192,  8193, 
+     8195,  8199,  8207,  8064,  8096,  8112,  8113,  8110, 
+        0,  8192,  8193,  8195,  8199,  8207,  8064,  8096, 
+        0,  8192,  8193,  8195,  8199,  8207,  8064,  8128, 
+     8112,     0,  8192,  8193,  8195,  8199,  8207,  8064, 
+     8128,  8112,     0,  8192,  8193,  8195,  8199,  8207, 
+     8064,  8128,  8112,  8114,     0,  8192,  8193,  8195, 
+     8199,  8207,  8064,  8128,  8112,     0,  8192,  8193, 
+     8195,  8199,  8207,  8064,  8128,  8112,  8116,     0, 
+     8192,  8193,  8195,  8199,  8207,  8064,  8128,  8112, 
+     8116,     0,  8192,  8193,  8195,  8199,  8207,  8064, 
+     8128,  8112,  8120,  8118,     0,  8192,  8193,  8195, 
+     8199,  8207,  8064,  8128,  8112,     0,  8192,  8193, 
+     8195,  8199,  8207,  8064,  8128,  8129,  8120,     0, 
+     8192,  8193,  8195,  8199,  8207,  8064,  8128,  8129, 
+     8120,     0,  8192,  8193,  8195,  8199,  8207,  8064, 
+     8128,  8129,  8120,  8122,     0,  8192,  8193,  8195, 
+     8199,  8207,  8064,  8128,  8129,  8120,     0,  8192, 
+     8193,  8195,  8199,  8207,  8064,  8128,  8129,  8120, 
+     8124,     0,  8192,  8193,  8195,  8199,  8207,  8064, 
+     8128,  8129,  8131,  8124,     0,  8192,  8193,  8195, 
+     8199,  8207,  8064,  8128,  8129,  8131,  8124,  8126, 
+        0,  8192,  8193,  8195,  8199,  8207,  8064,     0, 
+     8192,  8193,  8195,  8199,  8207,  8064,  8128,     0, 
+     8192,  8193,  8195,  8199,  8207,  8064,  8128,     0, 
+     8192,  8193,  8195,  8199,  8207,  8064,  8128,  8130, 
+        0,  8192,  8193,  8195,  8199,  8207,  8064,  8128, 
+        0,  8192,  8193,  8195,  8199,  8207,  8064,  8128, 
+     8132,     0,  8192,  8193,  8195,  8199,  8207,  8064, 
+     8128,  8132,     0,  8192,  8193,  8195,  8199,  8207, 
+     8064,  8128,  8136,  8134,     0,  8192,  8193,  8195, 
+     8199,  8207,  8064,  8128,     0,  8192,  8193,  8195, 
+     8199,  8207,  8064,  8128,  8136,     0,  8192,  8193, 
+     8195,  8199,  8207,  8064,  8128,  8136,     0,  8192, 
+     8193,  8195,  8199,  8207,  8064,  8128,  8136,  8138, 
+        0,  8192,  8193,  8195,  8199,  8207,  8064,  8128, 
+     8136,     0,  8192,  8193,  8195,  8199,  8207,  8064, 
+     8128,  8144,  8140,     0,  8192,  8193,  8195,  8199, 
+     8207,  8064,  8128,  8144,  8140,     0,  8192,  8193, 
+     8195,  8199,  8207,  8064,  8128,  8144,  8145,  8142, 
+        0,  8192,  8193,  8195,  8199,  8207,  8064,  8128, 
+        0,  8192,  8193,  8195,  8199,  8207,  8064,  8128, 
+     8144,     0,  8192,  8193,  8195,  8199,  8207,  8064, 
+     8128,  8144,     0,  8192,  8193,  8195,  8199,  8207, 
+     8064,  8128,  8144,  8146,     0,  8192,  8193,  8195, 
+     8199,  8207,  8064,  8128,  8144,     0,  8192,  8193, 
+     8195,  8199,  8207,  8064,  8128,  8144,  8148,     0, 
+     8192,  8193,  8195,  8199,  8207,  8064,  8128,  8144, 
+     8148,     0,  8192,  8193,  8195,  8199,  8207,  8064, 
+     8128,  8144,  8152,  8150,     0,  8192,  8193,  8195, 
+     8199,  8207,  8064,  8128,  8144,     0,  8192,  8193, 
+     8195,  8199,  8207,  8064,  8128,  8160,  8152,     0, 
+     8192,  8193,  8195,  8199,  8207,  8064,  8128,  8160, 
+     8152,     0,  8192,  8193,  8195,  8199,  8207,  8064, 
+     8128,  8160,  8152,  8154,     0,  8192,  8193,  8195, 
+     8199,  8207,  8064,  8128,  8160,  8152,     0,  8192, 
+     8193,  8195,  8199,  8207,  8064,  8128,  8160,  8161, 
+     8156,     0,  8192,  8193,  8195,  8199,  8207,  8064, 
+     8128,  8160,  8161,  8156,     0,  8192,  8193,  8195, 
+     8199,  8207,  8064,  8128,  8160,  8161,  8156,  8158, 
+        0,  8192,  8193,  8195,  8199,  8207,  8223,  8128, 
+        0,  8192,  8193,  8195,  8199,  8207,  8223,  8128, 
+     8160,     0,  8192,  8193,  8195,  8199,  8207,  8223, 
+     8128,  8160,     0,  8192,  8193,  8195,  8199,  8207, 
+     8223,  8128,  8160,  8162,     0,  8192,  8193,  8195, 
+     8199,  8207,  8223,  8128,  8160,     0,  8192,  8193, 
+     8195,  8199,  8207,  8223,  8128,  8160,  8164,     0, 
+     8192,  8193,  8195,  8199,  8207,  8223,  8128,  8160, 
+     8164,     0,  8192,  8193,  8195,  8199,  8207,  8223, 
+     8128,  8160,  8168,  8166,     0,  8192,  8193,  8195, 
+     8199,  8207,  8223,  8128,  8160,     0,  8192,  8193, 
+     8195,  8199,  8207,  8223,  8128,  8160,  8168,     0, 
+     8192,  8193,  8195,  8199,  8207,  8223,  8128,  8160, 
+     8168,     0,  8192,  8193,  8195,  8199,  8207,  8223, 
+     8128,  8160,  8168,  8170,     0,  8192,  8193,  8195, 
+     8199,  8207,  8223,  8128,  8160,  8168,     0,  8192, 
+     8193,  8195,  8199,  8207,  8223,  8128,  8160,  8176, 
+     8172,     0,  8192,  8193,  8195,  8199,  8207,  8223, 
+     8128,  8160,  8176,  8172,     0,  8192,  8193,  8195, 
+     8199,  8207,  8223,  8128,  8160,  8176,  8177,  8174, 
+        0,  8192,  8193,  8195,  8199,  8207,  8223,  8128, 
+     8160,     0,  8192,  8193,  8195,  8199,  8207,  8223, 
+     8128,  8160,  8176,     0,  8192,  8193,  8195,  8199, 
+     8207,  8223,  8128,  8160,  8176,     0,  8192,  8193, 
+     8195,  8199,  8207,  8223,  8128,  8160,  8176,  8178, 
+        0,  8192,  8193,  8195,  8199,  8207,  8223,  8128, 
+     8160,  8176,     0,  8192,  8193,  8195,  8199,  8207, 
+     8223,  8128,  8160,  8176,  8180,     0,  8192,  8193, 
+     8195,  8199,  8207,  8223,  8128,  8160,  8176,  8180, 
+        0,  8192,  8193,  8195,  8199,  8207,  8223,  8128, 
+     8160,  8176,  8184,  8182,     0,  8192,  8193,  8195, 
+     8199,  8207,  8223,  8128,  8160,  8176,     0,  8192, 
+     8193,  8195,  8199,  8207,  8223,  8128,  8160,  8176, 
+     8184,     0,  8192,  8193,  8195,  8199,  8207,  8223, 
+     8128,  8160,  8176,  8184,     0,  8192,  8193,  8195, 
+     8199,  8207,  8223,  8128,  8160,  8176,  8184,  8186, 
+        0,  8192,  8193,  8195,  8199,  8207,  8223,  8128, 
+     8160,  8176,  8184,     0,  8192,  8193,  8195,  8199, 
+     8207,  8223,  8128,  8160,  8176,  8184,  8188,     0, 
+     8192,  8193,  8195,  8199,  8207,  8223,  8128,  8160, 
+     8176,  8184,  8188,     0,  8192,  8193,  8195,  8199, 
+     8207,  8223,  8128,  8160,  8176,  8184,  8188,  8190, 
+        0,     0,  8192,     0,  8192,     0,  8192,  8194, 
+        0,  8192,     0,  8192,  8196,     0,  8192,  8196, 
+        0,  8192,  8200,  8198,     0,  8192,     0,  8192, 
+     8200,     0,  8192,  8200,     0,  8192,  8200,  8202, 
+        0,  8192,  8200,     0,  8192,  8208,  8204,     0, 
+     8192,  8208,  8204,     0,  8192,  8208,  8209,  8206, 
+        0,  8192,     0,  8192,  8208,     0,  8192,  8208, 
+        0,  8192,  8208,  8210,     0,  8192,  8208,     0, 
+     8192,  8208,  8212,     0,  8192,  8208,  8212,     0, 
+     8192,  8208,  8216,  8214,     0,  8192,  8208,     0, 
+     8192,  8224,  8216,     0,  8192,  8224,  8216,     0, 
+     8192,  8224,  8216,  8218,     0,  8192,  8224,  8216, 
+        0,  8192,  8224,  8225,  8220,     0,  8192,  8224, 
+     8225,  8220,     0,  8192,  8224,  8225,  8220,  8222, 
+        0,  8192,     0,  8192,  8224,     0,  8192,  8224, 
+        0,  8192,  8224,  8226,     0,  8192,  8224,     0, 
+     8192,  8224,  8228,     0,  8192,  8224,  8228,     0, 
+     8192,  8224,  8232,  8230,     0,  8192,  8224,     0, 
+     8192,  8224,  8232,     0,  8192,  8224,  8232,     0, 
+     8192,  8224,  8232,  8234,     0,  8192,  8224,  8232, 
+        0,  8192,  8224,  8240,  8236,     0,  8192,  8224, 
+     8240,  8236,     0,  8192,  8224,  8240,  8241,  8238, 
+        0,  8192,  8224,     0,  8192,  8256,  8240,     0, 
+     8192,  8256,  8240,     0,  8192,  8256,  8240,  8242, 
+        0,  8192,  8256,  8240,     0,  8192,  8256,  8240, 
+     8244,     0,  8192,  8256,  8240,  8244,     0,  8192, 
+     8256,  8240,  8248,  8246,     0,  8192,  8256,  8240, 
+        0,  8192,  8256,  8257,  8248,     0,  8192,  8256, 
+     8257,  8248,     0,  8192,  8256,  8257,  8248,  8250, 
+        0,  8192,  8256,  8257,  8248,     0,  8192,  8256, 
+     8257,  8248,  8252,     0,  8192,  8256,  8257,  8259, 
+     8252,     0,  8192,  8256,  8257,  8259,  8252,  8254, 
+        0,  8192,     0,  8192,  8256,     0,  8192,  8256, 
+        0,  8192,  8256,  8258,     0,  8192,  8256,     0, 
+     8192,  8256,  8260,     0,  8192,  8256,  8260,     0, 
+     8192,  8256,  8264,  8262,     0,  8192,  8256,     0, 
+     8192,  8256,  8264,     0,  8192,  8256,  8264,     0, 
+     8192,  8256,  8264,  8266,     0,  8192,  8256,  8264, 
+        0,  8192,  8256,  8272,  8268,     0,  8192,  8256, 
+     8272,  8268,     0,  8192,  8256,  8272,  8273,  8270, 
+        0,  8192,  8256,     0,  8192,  8256,  8272,     0, 
+     8192,  8256,  8272,     0,  8192,  8256,  8272,  8274, 
+        0,  8192,  8256,  8272,     0,  8192,  8256,  8272, 
+     8276,     0,  8192,  8256,  8272,  8276,     0,  8192, 
+     8256,  8272,  8280,  8278,     0,  8192,  8256,  8272, 
+        0,  8192,  8256,  8288,  8280,     0,  8192,  8256, 
+     8288,  8280,     0,  8192,  8256,  8288,  8280,  8282, 
+        0,  8192,  8256,  8288,  8280,     0,  8192,  8256, 
+     8288,  8289,  8284,     0,  8192,  8256,  8288,  8289, 
+     8284,     0,  8192,  8256,  8288,  8289,  8284,  8286, 
+        0,  8192,  8256,     0,  8192,  8320,  8288,     0, 
+     8192,  8320,  8288,     0,  8192,  8320,  8288,  8290, 
+        0,  8192,  8320,  8288,     0,  8192,  8320,  8288, 
+     8292,     0,  8192,  8320,  8288,  8292,     0,  8192, 
+     8320,  8288,  8296,  8294,     0,  8192,  8320,  8288, 
+        0,  8192,  8320,  8288,  8296,     0,  8192,  8320, 
+     8288,  8296,     0,  8192,  8320,  8288,  8296,  8298, 
+        0,  8192,  8320,  8288,  8296,     0,  8192,  8320, 
+     8288,  8304,  8300,     0,  8192,  8320,  8288,  8304, 
+     8300,     0,  8192,  8320,  8288,  8304,  8305,  8302, 
+        0,  8192,  8320,  8288,     0,  8192,  8320,  8321, 
+     8304,     0,  8192,  8320,  8321,  8304,     0,  8192, 
+     8320,  8321,  8304,  8306,     0,  8192,  8320,  8321, 
+     8304,     0,  8192,  8320,  8321,  8304,  8308,     0, 
+     8192,  8320,  8321,  8304,  8308,     0,  8192,  8320, 
+     8321,  8304,  8312,  8310,     0,  8192,  8320,  8321, 
+     8304,     0,  8192,  8320,  8321,  8304,  8312,     0, 
+     8192,  8320,  8321,  8323,  8312,     0,  8192,  8320, 
+     8321,  8323,  8312,  8314,     0,  8192,  8320,  8321, 
+     8323,  8312,     0,  8192,  8320,  8321,  8323,  8312, 
+     8316,     0,  8192,  8320,  8321,  8323,  8312,  8316, 
+        0,  8192,  8320,  8321,  8323,  8312,  8316,  8318, 
+        0,  8192,     0,  8192,  8320,     0,  8192,  8320, 
+        0,  8192,  8320,  8322,     0,  8192,  8320,     0, 
+     8192,  8320,  8324,     0,  8192,  8320,  8324,     0, 
+     8192,  8320,  8328,  8326,     0,  8192,  8320,     0, 
+     8192,  8320,  8328,     0,  8192,  8320,  8328,     0, 
+     8192,  8320,  8328,  8330,     0,  8192,  8320,  8328, 
+        0,  8192,  8320,  8336,  8332,     0,  8192,  8320, 
+     8336,  8332,     0,  8192,  8320,  8336,  8337,  8334, 
+        0,  8192,  8320,     0,  8192,  8320,  8336,     0, 
+     8192,  8320,  8336,     0,  8192,  8320,  8336,  8338, 
+        0,  8192,  8320,  8336,     0,  8192,  8320,  8336, 
+     8340,     0,  8192,  8320,  8336,  8340,     0,  8192, 
+     8320,  8336,  8344,  8342,     0,  8192,  8320,  8336, 
+        0,  8192,  8320,  8352,  8344,     0,  8192,  8320, 
+     8352,  8344,     0,  8192,  8320,  8352,  8344,  8346, 
+        0,  8192,  8320,  8352,  8344,     0,  8192,  8320, 
+     8352,  8353,  8348,     0,  8192,  8320,  8352,  8353, 
+     8348,     0,  8192,  8320,  8352,  8353,  8348,  8350, 
+        0,  8192,  8320,     0,  8192,  8320,  8352,     0, 
+     8192,  8320,  8352,     0,  8192,  8320,  8352,  8354, 
+        0,  8192,  8320,  8352,     0,  8192,  8320,  8352, 
+     8356,     0,  8192,  8320,  8352,  8356,     0,  8192, 
+     8320,  8352,  8360,  8358,     0,  8192,  8320,  8352, 
+        0,  8192,  8320,  8352,  8360,     0,  8192,  8320, 
+     8352,  8360,     0,  8192,  8320,  8352,  8360,  8362, 
+        0,  8192,  8320,  8352,  8360,     0,  8192,  8320, 
+     8352,  8368,  8364,     0,  8192,  8320,  8352,  8368, 
+     8364,     0,  8192,  8320,  8352,  8368,  8369,  8366, 
+        0,  8192,  8320,  8352,     0,  8192,  8320,  8384, 
+     8368,     0,  8192,  8320,  8384,  8368,     0,  8192, 
+     8320,  8384,  8368,  8370,     0,  8192,  8320,  8384, 
+     8368,     0,  8192,  8320,  8384,  8368,  8372,     0, 
+     8192,  8320,  8384,  8368,  8372,     0,  8192,  8320, 
+     8384,  8368,  8376,  8374,     0,  8192,  8320,  8384, 
+     8368,     0,  8192,  8320,  8384,  8385,  8376,     0, 
+     8192,  8320,  8384,  8385,  8376,     0,  8192,  8320, 
+     8384,  8385,  8376,  8378,     0,  8192,  8320,  8384, 
+     8385,  8376,     0,  8192,  8320,  8384,  8385,  8376, 
+     8380,     0,  8192,  8320,  8384,  8385,  8387,  8380, 
+        0,  8192,  8320,  8384,  8385,  8387,  8380,  8382, 
+        0,  8192,  8320,     0,  8192,  8448,  8384,     0, 
+     8192,  8448,  8384,     0,  8192,  8448,  8384,  8386, 
+        0,  8192,  8448,  8384,     0,  8192,  8448,  8384, 
+     8388,     0,  8192,  8448,  8384,  8388,     0,  8192, 
+     8448,  8384,  8392,  8390,     0,  8192,  8448,  8384, 
+        0,  8192,  8448,  8384,  8392,     0,  8192,  8448, 
+     8384,  8392,     0,  8192,  8448,  8384,  8392,  8394, 
+        0,  8192,  8448,  8384,  8392,     0,  8192,  8448, 
+     8384,  8400,  8396,     0,  8192,  8448,  8384,  8400, 
+     8396,     0,  8192,  8448,  8384,  8400,  8401,  8398, 
+        0,  8192,  8448,  8384,     0,  8192,  8448,  8384, 
+     8400,     0,  8192,  8448,  8384,  8400,     0,  8192, 
+     8448,  8384,  8400,  8402,     0,  8192,  8448,  8384, 
+     8400,     0,  8192,  8448,  8384,  8400,  8404,     0, 
+     8192,  8448,  8384,  8400,  8404,     0,  8192,  8448, 
+     8384,  8400,  8408,  8406,     0,  8192,  8448,  8384, 
+     8400,     0,  8192,  8448,  8384,  8416,  8408,     0, 
+     8192,  8448,  8384,  8416,  8408,     0,  8192,  8448, 
+     8384,  8416,  8408,  8410,     0,  8192,  8448,  8384, 
+     8416,  8408,     0,  8192,  8448,  8384,  8416,  8417, 
+     8412,     0,  8192,  8448,  8384,  8416,  8417,  8412, 
+        0,  8192,  8448,  8384,  8416,  8417,  8412,  8414, 
+        0,  8192,  8448,  8384,     0,  8192,  8448,  8449, 
+     8416,     0,  8192,  8448,  8449,  8416,     0,  8192, 
+     8448,  8449,  8416,  8418,     0,  8192,  8448,  8449, 
+     8416,     0,  8192,  8448,  8449,  8416,  8420,     0, 
+     8192,  8448,  8449,  8416,  8420,     0,  8192,  8448, 
+     8449,  8416,  8424,  8422,     0,  8192,  8448,  8449, 
+     8416,     0,  8192,  8448,  8449,  8416,  8424,     0, 
+     8192,  8448,  8449,  8416,  8424,     0,  8192,  8448, 
+     8449,  8416,  8424,  8426,     0,  8192,  8448,  8449, 
+     8416,  8424,     0,  8192,  8448,  8449,  8416,  8432, 
+     8428,     0,  8192,  8448,  8449,  8416,  8432,  8428, 
+        0,  8192,  8448,  8449,  8416,  8432,  8433,  8430, 
+        0,  8192,  8448,  8449,  8416,     0,  8192,  8448, 
+     8449,  8416,  8432,     0,  8192,  8448,  8449,  8451, 
+     8432,     0,  8192,  8448,  8449,  8451,  8432,  8434, 
+        0,  8192,  8448,  8449,  8451,  8432,     0,  8192, 
+     8448,  8449,  8451,  8432,  8436,     0,  8192,  8448, 
+     8449,  8451,  8432,  8436,     0,  8192,  8448,  8449, 
+     8451,  8432,  8440,  8438,     0,  8192,  8448,  8449, 
+     8451,  8432,     0,  8192,  8448,  8449,  8451,  8432, 
+     8440,     0,  8192,  8448,  8449,  8451,  8432,  8440, 
+        0,  8192,  8448,  8449,  8451,  8432,  8440,  8442, 
+        0,  8192,  8448,  8449,  8451,  8455,  8440,     0, 
+     8192,  8448,  8449,  8451,  8455,  8440,  8444,     0, 
+     8192,  8448,  8449,  8451,  8455,  8440,  8444,     0, 
+     8192,  8448,  8449,  8451,  8455,  8440,  8444,  8446, 
+        0,  8192,     0,  8192,  8448,     0,  8192,  8448, 
+        0,  8192,  8448,  8450,     0,  8192,  8448,     0, 
+     8192,  8448,  8452,     0,  8192,  8448,  8452,     0, 
+     8192,  8448,  8456,  8454,     0,  8192,  8448,     0, 
+     8192,  8448,  8456,     0,  8192,  8448,  8456,     0, 
+     8192,  8448,  8456,  8458,     0,  8192,  8448,  8456, 
+        0,  8192,  8448,  8464,  8460,     0,  8192,  8448, 
+     8464,  8460,     0,  8192,  8448,  8464,  8465,  8462, 
+        0,  8192,  8448,     0,  8192,  8448,  8464,     0, 
+     8192,  8448,  8464,     0,  8192,  8448,  8464,  8466, 
+        0,  8192,  8448,  8464,     0,  8192,  8448,  8464, 
+     8468,     0,  8192,  8448,  8464,  8468,     0,  8192, 
+     8448,  8464,  8472,  8470,     0,  8192,  8448,  8464, 
+        0,  8192,  8448,  8480,  8472,     0,  8192,  8448, 
+     8480,  8472,     0,  8192,  8448,  8480,  8472,  8474, 
+        0,  8192,  8448,  8480,  8472,     0,  8192,  8448, 
+     8480,  8481,  8476,     0,  8192,  8448,  8480,  8481, 
+     8476,     0,  8192,  8448,  8480,  8481,  8476,  8478, 
+        0,  8192,  8448,     0,  8192,  8448,  8480,     0, 
+     8192,  8448,  8480,     0,  8192,  8448,  8480,  8482, 
+        0,  8192,  8448,  8480,     0,  8192,  8448,  8480, 
+     8484,     0,  8192,  8448,  8480,  8484,     0,  8192, 
+     8448,  8480,  8488,  8486,     0,  8192,  8448,  8480, 
+        0,  8192,  8448,  8480,  8488,     0,  8192,  8448, 
+     8480,  8488,     0,  8192,  8448,  8480,  8488,  8490, 
+        0,  8192,  8448,  8480,  8488,     0,  8192,  8448, 
+     8480,  8496,  8492,     0,  8192,  8448,  8480,  8496, 
+     8492,     0,  8192,  8448,  8480,  8496,  8497,  8494, 
+        0,  8192,  8448,  8480,     0,  8192,  8448,  8512, 
+     8496,     0,  8192,  8448,  8512,  8496,     0,  8192, 
+     8448,  8512,  8496,  8498,     0,  8192,  8448,  8512, 
+     8496,     0,  8192,  8448,  8512,  8496,  8500,     0, 
+     8192,  8448,  8512,  8496,  8500,     0,  8192,  8448, 
+     8512,  8496,  8504,  8502,     0,  8192,  8448,  8512, 
+     8496,     0,  8192,  8448,  8512,  8513,  8504,     0, 
+     8192,  8448,  8512,  8513,  8504,     0,  8192,  8448, 
+     8512,  8513,  8504,  8506,     0,  8192,  8448,  8512, 
+     8513,  8504,     0,  8192,  8448,  8512,  8513,  8504, 
+     8508,     0,  8192,  8448,  8512,  8513,  8515,  8508, 
+        0,  8192,  8448,  8512,  8513,  8515,  8508,  8510, 
+        0,  8192,  8448,     0,  8192,  8448,  8512,     0, 
+     8192,  8448,  8512,     0,  8192,  8448,  8512,  8514, 
+        0,  8192,  8448,  8512,     0,  8192,  8448,  8512, 
+     8516,     0,  8192,  8448,  8512,  8516,     0,  8192, 
+     8448,  8512,  8520,  8518,     0,  8192,  8448,  8512, 
+        0,  8192,  8448,  8512,  8520,     0,  8192,  8448, 
+     8512,  8520,     0,  8192,  8448,  8512,  8520,  8522, 
+        0,  8192,  8448,  8512,  8520,     0,  8192,  8448, 
+     8512,  8528,  8524,     0,  8192,  8448,  8512,  8528, 
+     8524,     0,  8192,  8448,  8512,  8528,  8529,  8526, 
+        0,  8192,  8448,  8512,     0,  8192,  8448,  8512, 
+     8528,     0,  8192,  8448,  8512,  8528,     0,  8192, 
+     8448,  8512,  8528,  8530,     0,  8192,  8448,  8512, 
+     8528,     0,  8192,  8448,  8512,  8528,  8532,     0, 
+     8192,  8448,  8512,  8528,  8532,     0,  8192,  8448, 
+     8512,  8528,  8536,  8534,     0,  8192,  8448,  8512, 
+     8528,     0,  8192,  8448,  8512,  8544,  8536,     0, 
+     8192,  8448,  8512,  8544,  8536,     0,  8192,  8448, 
+     8512,  8544,  8536,  8538,     0,  8192,  8448,  8512, 
+     8544,  8536,     0,  8192,  8448,  8512,  8544,  8545, 
+     8540,     0,  8192,  8448,  8512,  8544,  8545,  8540, 
+        0,  8192,  8448,  8512,  8544,  8545,  8540,  8542, 
+        0,  8192,  8448,  8512,     0,  8192,  8448,  8576, 
+     8544,     0,  8192,  8448,  8576,  8544,     0,  8192, 
+     8448,  8576,  8544,  8546,     0,  8192,  8448,  8576, 
+     8544,     0,  8192,  8448,  8576,  8544,  8548,     0, 
+     8192,  8448,  8576,  8544,  8548,     0,  8192,  8448, 
+     8576,  8544,  8552,  8550,     0,  8192,  8448,  8576, 
+     8544,     0,  8192,  8448,  8576,  8544,  8552,     0, 
+     8192,  8448,  8576,  8544,  8552,     0,  8192,  8448, 
+     8576,  8544,  8552,  8554,     0,  8192,  8448,  8576, 
+     8544,  8552,     0,  8192,  8448,  8576,  8544,  8560, 
+     8556,     0,  8192,  8448,  8576,  8544,  8560,  8556, 
+        0,  8192,  8448,  8576,  8544,  8560,  8561,  8558, 
+        0,  8192,  8448,  8576,  8544,     0,  8192,  8448, 
+     8576,  8577,  8560,     0,  8192,  8448,  8576,  8577, 
+     8560,     0,  8192,  8448,  8576,  8577,  8560,  8562, 
+        0,  8192,  8448,  8576,  8577,  8560,     0,  8192, 
+     8448,  8576,  8577,  8560,  8564,     0,  8192,  8448, 
+     8576,  8577,  8560,  8564,     0,  8192,  8448,  8576, 
+     8577,  8560,  8568,  8566,     0,  8192,  8448,  8576, 
+     8577,  8560,     0,  8192,  8448,  8576,  8577,  8560, 
+     8568,     0,  8192,  8448,  8576,  8577,  8579,  8568, 
+        0,  8192,  8448,  8576,  8577,  8579,  8568,  8570, 
+        0,  8192,  8448,  8576,  8577,  8579,  8568,     0, 
+     8192,  8448,  8576,  8577,  8579,  8568,  8572,     0, 
+     8192,  8448,  8576,  8577,  8579,  8568,  8572,     0, 
+     8192,  8448,  8576,  8577,  8579,  8568,  8572,  8574, 
+        0,  8192,  8448,     0,  8192,  8704,  8576,     0, 
+     8192,  8704,  8576,     0,  8192,  8704,  8576,  8578, 
+        0,  8192,  8704,  8576,     0,  8192,  8704,  8576, 
+     8580,     0,  8192,  8704,  8576,  8580,     0,  8192, 
+     8704,  8576,  8584,  8582,     0,  8192,  8704,  8576, 
+        0,  8192,  8704,  8576,  8584,     0,  8192,  8704, 
+     8576,  8584,     0,  8192,  8704,  8576,  8584,  8586, 
+        0,  8192,  8704,  8576,  8584,     0,  8192,  8704, 
+     8576,  8592,  8588,     0,  8192,  8704,  8576,  8592, 
+     8588,     0,  8192,  8704,  8576,  8592,  8593,  8590, 
+        0,  8192,  8704,  8576,     0,  8192,  8704,  8576, 
+     8592,     0,  8192,  8704,  8576,  8592,     0,  8192, 
+     8704,  8576,  8592,  8594,     0,  8192,  8704,  8576, 
+     8592,     0,  8192,  8704,  8576,  8592,  8596,     0, 
+     8192,  8704,  8576,  8592,  8596,     0,  8192,  8704, 
+     8576,  8592,  8600,  8598,     0,  8192,  8704,  8576, 
+     8592,     0,  8192,  8704,  8576,  8608,  8600,     0, 
+     8192,  8704,  8576,  8608,  8600,     0,  8192,  8704, 
+     8576,  8608,  8600,  8602,     0,  8192,  8704,  8576, 
+     8608,  8600,     0,  8192,  8704,  8576,  8608,  8609, 
+     8604,     0,  8192,  8704,  8576,  8608,  8609,  8604, 
+        0,  8192,  8704,  8576,  8608,  8609,  8604,  8606, 
+        0,  8192,  8704,  8576,     0,  8192,  8704,  8576, 
+     8608,     0,  8192,  8704,  8576,  8608,     0,  8192, 
+     8704,  8576,  8608,  8610,     0,  8192,  8704,  8576, 
+     8608,     0,  8192,  8704,  8576,  8608,  8612,     0, 
+     8192,  8704,  8576,  8608,  8612,     0,  8192,  8704, 
+     8576,  8608,  8616,  8614,     0,  8192,  8704,  8576, 
+     8608,     0,  8192,  8704,  8576,  8608,  8616,     0, 
+     8192,  8704,  8576,  8608,  8616,     0,  8192,  8704, 
+     8576,  8608,  8616,  8618,     0,  8192,  8704,  8576, 
+     8608,  8616,     0,  8192,  8704,  8576,  8608,  8624, 
+     8620,     0,  8192,  8704,  8576,  8608,  8624,  8620, 
+        0,  8192,  8704,  8576,  8608,  8624,  8625,  8622, 
+        0,  8192,  8704,  8576,  8608,     0,  8192,  8704, 
+     8576,  8640,  8624,     0,  8192,  8704,  8576,  8640, 
+     8624,     0,  8192,  8704,  8576,  8640,  8624,  8626, 
+        0,  8192,  8704,  8576,  8640,  8624,     0,  8192, 
+     8704,  8576,  8640,  8624,  8628,     0,  8192,  8704, 
+     8576,  8640,  8624,  8628,     0,  8192,  8704,  8576, 
+     8640,  8624,  8632,  8630,     0,  8192,  8704,  8576, 
+     8640,  8624,     0,  8192,  8704,  8576,  8640,  8641, 
+     8632,     0,  8192,  8704,  8576,  8640,  8641,  8632, 
+        0,  8192,  8704,  8576,  8640,  8641,  8632,  8634, 
+        0,  8192,  8704,  8576,  8640,  8641,  8632,     0, 
+     8192,  8704,  8576,  8640,  8641,  8632,  8636,     0, 
+     8192,  8704,  8576,  8640,  8641,  8643,  8636,     0, 
+     8192,  8704,  8576,  8640,  8641,  8643,  8636,  8638, 
+        0,  8192,  8704,  8576,     0,  8192,  8704,  8705, 
+     8640,     0,  8192,  8704,  8705,  8640,     0,  8192, 
+     8704,  8705,  8640,  8642,     0,  8192,  8704,  8705, 
+     8640,     0,  8192,  8704,  8705,  8640,  8644,     0, 
+     8192,  8704,  8705,  8640,  8644,     0,  8192,  8704, 
+     8705,  8640,  8648,  8646,     0,  8192,  8704,  8705, 
+     8640,     0,  8192,  8704,  8705,  8640,  8648,     0, 
+     8192,  8704,  8705,  8640,  8648,     0,  8192,  8704, 
+     8705,  8640,  8648,  8650,     0,  8192,  8704,  8705, 
+     8640,  8648,     0,  8192,  8704,  8705,  8640,  8656, 
+     8652,     0,  8192,  8704,  8705,  8640,  8656,  8652, 
+        0,  8192,  8704,  8705,  8640,  8656,  8657,  8654, 
+        0,  8192,  8704,  8705,  8640,     0,  8192,  8704, 
+     8705,  8640,  8656,     0,  8192,  8704,  8705,  8640, 
+     8656,     0,  8192,  8704,  8705,  8640,  8656,  8658, 
+        0,  8192,  8704,  8705,  8640,  8656,     0,  8192, 
+     8704,  8705,  8640,  8656,  8660,     0,  8192,  8704, 
+     8705,  8640,  8656,  8660,     0,  8192,  8704,  8705, 
+     8640,  8656,  8664,  8662,     0,  8192,  8704,  8705, 
+     8640,  8656,     0,  8192,  8704,  8705,  8640,  8672, 
+     8664,     0,  8192,  8704,  8705,  8640,  8672,  8664, 
+        0,  8192,  8704,  8705,  8640,  8672,  8664,  8666, 
+        0,  8192,  8704,  8705,  8640,  8672,  8664,     0, 
+     8192,  8704,  8705,  8640,  8672,  8673,  8668,     0, 
+     8192,  8704,  8705,  8640,  8672,  8673,  8668,     0, 
+     8192,  8704,  8705,  8640,  8672,  8673,  8668,  8670, 
+        0,  8192,  8704,  8705,  8640,     0,  8192,  8704, 
+     8705,  8640,  8672,     0,  8192,  8704,  8705,  8707, 
+     8672,     0,  8192,  8704,  8705,  8707,  8672,  8674, 
+        0,  8192,  8704,  8705,  8707,  8672,     0,  8192, 
+     8704,  8705,  8707,  8672,  8676,     0,  8192,  8704, 
+     8705,  8707,  8672,  8676,     0,  8192,  8704,  8705, 
+     8707,  8672,  8680,  8678,     0,  8192,  8704,  8705, 
+     8707,  8672,     0,  8192,  8704,  8705,  8707,  8672, 
+     8680,     0,  8192,  8704,  8705,  8707,  8672,  8680, 
+        0,  8192,  8704,  8705,  8707,  8672,  8680,  8682, 
+        0,  8192,  8704,  8705,  8707,  8672,  8680,     0, 
+     8192,  8704,  8705,  8707,  8672,  8688,  8684,     0, 
+     8192,  8704,  8705,  8707,  8672,  8688,  8684,     0, 
+     8192,  8704,  8705,  8707,  8672,  8688,  8689,  8686, 
+        0,  8192,  8704,  8705,  8707,  8672,     0,  8192, 
+     8704,  8705,  8707,  8672,  8688,     0,  8192,  8704, 
+     8705,  8707,  8672,  8688,     0,  8192,  8704,  8705, 
+     8707,  8672,  8688,  8690,     0,  8192,  8704,  8705, 
+     8707,  8711,  8688,     0,  8192,  8704,  8705,  8707, 
+     8711,  8688,  8692,     0,  8192,  8704,  8705,  8707, 
+     8711,  8688,  8692,     0,  8192,  8704,  8705,  8707, 
+     8711,  8688,  8696,  8694,     0,  8192,  8704,  8705, 
+     8707,  8711,  8688,     0,  8192,  8704,  8705,  8707, 
+     8711,  8688,  8696,     0,  8192,  8704,  8705,  8707, 
+     8711,  8688,  8696,     0,  8192,  8704,  8705,  8707, 
+     8711,  8688,  8696,  8698,     0,  8192,  8704,  8705, 
+     8707,  8711,  8688,  8696,     0,  8192,  8704,  8705, 
+     8707,  8711,  8688,  8696,  8700,     0,  8192,  8704, 
+     8705,  8707,  8711,  8688,  8696,  8700,     0,  8192, 
+     8704,  8705,  8707,  8711,  8688,  8696,  8700,  8702, 
+        0,  8192,     0,  8192,  8704,     0,  8192,  8704, 
+        0,  8192,  8704,  8706,     0,  8192,  8704,     0, 
+     8192,  8704,  8708,     0,  8192,  8704,  8708,     0, 
+     8192,  8704,  8712,  8710,     0,  8192,  8704,     0, 
+     8192,  8704,  8712,     0,  8192,  8704,  8712,     0, 
+     8192,  8704,  8712,  8714,     0,  8192,  8704,  8712, 
+        0,  8192,  8704,  8720,  8716,     0,  8192,  8704, 
+     8720,  8716,     0,  8192,  8704,  8720,  8721,  8718, 
+        0,  8192,  8704,     0,  8192,  8704,  8720,     0, 
+     8192,  8704,  8720,     0,  8192,  8704,  8720,  8722, 
+        0,  8192,  8704,  8720,     0,  8192,  8704,  8720, 
+     8724,     0,  8192,  8704,  8720,  8724,     0,  8192, 
+     8704,  8720,  8728,  8726,     0,  8192,  8704,  8720, 
+        0,  8192,  8704,  8736,  8728,     0,  8192,  8704, 
+     8736,  8728,     0,  8192,  8704,  8736,  8728,  8730, 
+        0,  8192,  8704,  8736,  8728,     0,  8192,  8704, 
+     8736,  8737,  8732,     0,  8192,  8704,  8736,  8737, 
+     8732,     0,  8192,  8704,  8736,  8737,  8732,  8734, 
+        0,  8192,  8704,     0,  8192,  8704,  8736,     0, 
+     8192,  8704,  8736,     0,  8192,  8704,  8736,  8738, 
+        0,  8192,  8704,  8736,     0,  8192,  8704,  8736, 
+     8740,     0,  8192,  8704,  8736,  8740,     0,  8192, 
+     8704,  8736,  8744,  8742,     0,  8192,  8704,  8736, 
+        0,  8192,  8704,  8736,  8744,     0,  8192,  8704, 
+     8736,  8744,     0,  8192,  8704,  8736,  8744,  8746, 
+        0,  8192,  8704,  8736,  8744,     0,  8192,  8704, 
+     8736,  8752,  8748,     0,  8192,  8704,  8736,  8752, 
+     8748,     0,  8192,  8704,  8736,  8752,  8753,  8750, 
+        0,  8192,  8704,  8736,     0,  8192,  8704,  8768, 
+     8752,     0,  8192,  8704,  8768,  8752,     0,  8192, 
+     8704,  8768,  8752,  8754,     0,  8192,  8704,  8768, 
+     8752,     0,  8192,  8704,  8768,  8752,  8756,     0, 
+     8192,  8704,  8768,  8752,  8756,     0,  8192,  8704, 
+     8768,  8752,  8760,  8758,     0,  8192,  8704,  8768, 
+     8752,     0,  8192,  8704,  8768,  8769,  8760,     0, 
+     8192,  8704,  8768,  8769,  8760,     0,  8192,  8704, 
+     8768,  8769,  8760,  8762,     0,  8192,  8704,  8768, 
+     8769,  8760,     0,  8192,  8704,  8768,  8769,  8760, 
+     8764,     0,  8192,  8704,  8768,  8769,  8771,  8764, 
+        0,  8192,  8704,  8768,  8769,  8771,  8764,  8766, 
+        0,  8192,  8704,     0,  8192,  8704,  8768,     0, 
+     8192,  8704,  8768,     0,  8192,  8704,  8768,  8770, 
+        0,  8192,  8704,  8768,     0,  8192,  8704,  8768, 
+     8772,     0,  8192,  8704,  8768,  8772,     0,  8192, 
+     8704,  8768,  8776,  8774,     0,  8192,  8704,  8768, 
+        0,  8192,  8704,  8768,  8776,     0,  8192,  8704, 
+     8768,  8776,     0,  8192,  8704,  8768,  8776,  8778, 
+        0,  8192,  8704,  8768,  8776,     0,  8192,  8704, 
+     8768,  8784,  8780,     0,  8192,  8704,  8768,  8784, 
+     8780,     0,  8192,  8704,  8768,  8784,  8785,  8782, 
+        0,  8192,  8704,  8768,     0,  8192,  8704,  8768, 
+     8784,     0,  8192,  8704,  8768,  8784,     0,  8192, 
+     8704,  8768,  8784,  8786,     0,  8192,  8704,  8768, 
+     8784,     0,  8192,  8704,  8768,  8784,  8788,     0, 
+     8192,  8704,  8768,  8784,  8788,     0,  8192,  8704, 
+     8768,  8784,  8792,  8790,     0,  8192,  8704,  8768, 
+     8784,     0,  8192,  8704,  8768,  8800,  8792,     0, 
+     8192,  8704,  8768,  8800,  8792,     0,  8192,  8704, 
+     8768,  8800,  8792,  8794,     0,  8192,  8704,  8768, 
+     8800,  8792,     0,  8192,  8704,  8768,  8800,  8801, 
+     8796,     0,  8192,  8704,  8768,  8800,  8801,  8796, 
+        0,  8192,  8704,  8768,  8800,  8801,  8796,  8798, 
+        0,  8192,  8704,  8768,     0,  8192,  8704,  8832, 
+     8800,     0,  8192,  8704,  8832,  8800,     0,  8192, 
+     8704,  8832,  8800,  8802,     0,  8192,  8704,  8832, 
+     8800,     0,  8192,  8704,  8832,  8800,  8804,     0, 
+     8192,  8704,  8832,  8800,  8804,     0,  8192,  8704, 
+     8832,  8800,  8808,  8806,     0,  8192,  8704,  8832, 
+     8800,     0,  8192,  8704,  8832,  8800,  8808,     0, 
+     8192,  8704,  8832,  8800,  8808,     0,  8192,  8704, 
+     8832,  8800,  8808,  8810,     0,  8192,  8704,  8832, 
+     8800,  8808,     0,  8192,  8704,  8832,  8800,  8816, 
+     8812,     0,  8192,  8704,  8832,  8800,  8816,  8812, 
+        0,  8192,  8704,  8832,  8800,  8816,  8817,  8814, 
+        0,  8192,  8704,  8832,  8800,     0,  8192,  8704, 
+     8832,  8833,  8816,     0,  8192,  8704,  8832,  8833, 
+     8816,     0,  8192,  8704,  8832,  8833,  8816,  8818, 
+        0,  8192,  8704,  8832,  8833,  8816,     0,  8192, 
+     8704,  8832,  8833,  8816,  8820,     0,  8192,  8704, 
+     8832,  8833,  8816,  8820,     0,  8192,  8704,  8832, 
+     8833,  8816,  8824,  8822,     0,  8192,  8704,  8832, 
+     8833,  8816,     0,  8192,  8704,  8832,  8833,  8816, 
+     8824,     0,  8192,  8704,  8832,  8833,  8835,  8824, 
+        0,  8192,  8704,  8832,  8833,  8835,  8824,  8826, 
+        0,  8192,  8704,  8832,  8833,  8835,  8824,     0, 
+     8192,  8704,  8832,  8833,  8835,  8824,  8828,     0, 
+     8192,  8704,  8832,  8833,  8835,  8824,  8828,     0, 
+     8192,  8704,  8832,  8833,  8835,  8824,  8828,  8830, 
+        0,  8192,  8704,     0,  8192,  8704,  8832,     0, 
+     8192,  8704,  8832,     0,  8192,  8704,  8832,  8834, 
+        0,  8192,  8704,  8832,     0,  8192,  8704,  8832, 
+     8836,     0,  8192,  8704,  8832,  8836,     0,  8192, 
+     8704,  8832,  8840,  8838,     0,  8192,  8704,  8832, 
+        0,  8192,  8704,  8832,  8840,     0,  8192,  8704, 
+     8832,  8840,     0,  8192,  8704,  8832,  8840,  8842, 
+        0,  8192,  8704,  8832,  8840,     0,  8192,  8704, 
+     8832,  8848,  8844,     0,  8192,  8704,  8832,  8848, 
+     8844,     0,  8192,  8704,  8832,  8848,  8849,  8846, 
+        0,  8192,  8704,  8832,     0,  8192,  8704,  8832, 
+     8848,     0,  8192,  8704,  8832,  8848,     0,  8192, 
+     8704,  8832,  8848,  8850,     0,  8192,  8704,  8832, 
+     8848,     0,  8192,  8704,  8832,  8848,  8852,     0, 
+     8192,  8704,  8832,  8848,  8852,     0,  8192,  8704, 
+     8832,  8848,  8856,  8854,     0,  8192,  8704,  8832, 
+     8848,     0,  8192,  8704,  8832,  8864,  8856,     0, 
+     8192,  8704,  8832,  8864,  8856,     0,  8192,  8704, 
+     8832,  8864,  8856,  8858,     0,  8192,  8704,  8832, 
+     8864,  8856,     0,  8192,  8704,  8832,  8864,  8865, 
+     8860,     0,  8192,  8704,  8832,  8864,  8865,  8860, 
+        0,  8192,  8704,  8832,  8864,  8865,  8860,  8862, 
+        0,  8192,  8704,  8832,     0,  8192,  8704,  8832, 
+     8864,     0,  8192,  8704,  8832,  8864,     0,  8192, 
+     8704,  8832,  8864,  8866,     0,  8192,  8704,  8832, 
+     8864,     0,  8192,  8704,  8832,  8864,  8868,     0, 
+     8192,  8704,  8832,  8864,  8868,     0,  8192,  8704, 
+     8832,  8864,  8872,  8870,     0,  8192,  8704,  8832, 
+     8864,     0,  8192,  8704,  8832,  8864,  8872,     0, 
+     8192,  8704,  8832,  8864,  8872,     0,  8192,  8704, 
+     8832,  8864,  8872,  8874,     0,  8192,  8704,  8832, 
+     8864,  8872,     0,  8192,  8704,  8832,  8864,  8880, 
+     8876,     0,  8192,  8704,  8832,  8864,  8880,  8876, 
+        0,  8192,  8704,  8832,  8864,  8880,  8881,  8878, 
+        0,  8192,  8704,  8832,  8864,     0,  8192,  8704, 
+     8832,  8896,  8880,     0,  8192,  8704,  8832,  8896, 
+     8880,     0,  8192,  8704,  8832,  8896,  8880,  8882, 
+        0,  8192,  8704,  8832,  8896,  8880,     0,  8192, 
+     8704,  8832,  8896,  8880,  8884,     0,  8192,  8704, 
+     8832,  8896,  8880,  8884,     0,  8192,  8704,  8832, 
+     8896,  8880,  8888,  8886,     0,  8192,  8704,  8832, 
+     8896,  8880,     0,  8192,  8704,  8832,  8896,  8897, 
+     8888,     0,  8192,  8704,  8832,  8896,  8897,  8888, 
+        0,  8192,  8704,  8832,  8896,  8897,  8888,  8890, 
+        0,  8192,  8704,  8832,  8896,  8897,  8888,     0, 
+     8192,  8704,  8832,  8896,  8897,  8888,  8892,     0, 
+     8192,  8704,  8832,  8896,  8897,  8899,  8892,     0, 
+     8192,  8704,  8832,  8896,  8897,  8899,  8892,  8894, 
+        0,  8192,  8704,  8832,     0,  8192,  8704,  8960, 
+     8896,     0,  8192,  8704,  8960,  8896,     0,  8192, 
+     8704,  8960,  8896,  8898,     0,  8192,  8704,  8960, 
+     8896,     0,  8192,  8704,  8960,  8896,  8900,     0, 
+     8192,  8704,  8960,  8896,  8900,     0,  8192,  8704, 
+     8960,  8896,  8904,  8902,     0,  8192,  8704,  8960, 
+     8896,     0,  8192,  8704,  8960,  8896,  8904,     0, 
+     8192,  8704,  8960,  8896,  8904,     0,  8192,  8704, 
+     8960,  8896,  8904,  8906,     0,  8192,  8704,  8960, 
+     8896,  8904,     0,  8192,  8704,  8960,  8896,  8912, 
+     8908,     0,  8192,  8704,  8960,  8896,  8912,  8908, 
+        0,  8192,  8704,  8960,  8896,  8912,  8913,  8910, 
+        0,  8192,  8704,  8960,  8896,     0,  8192,  8704, 
+     8960,  8896,  8912,     0,  8192,  8704,  8960,  8896, 
+     8912,     0,  8192,  8704,  8960,  8896,  8912,  8914, 
+        0,  8192,  8704,  8960,  8896,  8912,     0,  8192, 
+     8704,  8960,  8896,  8912,  8916,     0,  8192,  8704, 
+     8960,  8896,  8912,  8916,     0,  8192,  8704,  8960, 
+     8896,  8912,  8920,  8918,     0,  8192,  8704,  8960, 
+     8896,  8912,     0,  8192,  8704,  8960,  8896,  8928, 
+     8920,     0,  8192,  8704,  8960,  8896,  8928,  8920, 
+        0,  8192,  8704,  8960,  8896,  8928,  8920,  8922, 
+        0,  8192,  8704,  8960,  8896,  8928,  8920,     0, 
+     8192,  8704,  8960,  8896,  8928,  8929,  8924,     0, 
+     8192,  8704,  8960,  8896,  8928,  8929,  8924,     0, 
+     8192,  8704,  8960,  8896,  8928,  8929,  8924,  8926, 
+        0,  8192,  8704,  8960,  8896,     0,  8192,  8704, 
+     8960,  8961,  8928,     0,  8192,  8704,  8960,  8961, 
+     8928,     0,  8192,  8704,  8960,  8961,  8928,  8930, 
+        0,  8192,  8704,  8960,  8961,  8928,     0,  8192, 
+     8704,  8960,  8961,  8928,  8932,     0,  8192,  8704, 
+     8960,  8961,  8928,  8932,     0,  8192,  8704,  8960, 
+     8961,  8928,  8936,  8934,     0,  8192,  8704,  8960, 
+     8961,  8928,     0,  8192,  8704,  8960,  8961,  8928, 
+     8936,     0,  8192,  8704,  8960,  8961,  8928,  8936, 
+        0,  8192,  8704,  8960,  8961,  8928,  8936,  8938, 
+        0,  8192,  8704,  8960,  8961,  8928,  8936,     0, 
+     8192,  8704,  8960,  8961,  8928,  8944,  8940,     0, 
+     8192,  8704,  8960,  8961,  8928,  8944,  8940,     0, 
+     8192,  8704,  8960,  8961,  8928,  8944,  8945,  8942, 
+        0,  8192,  8704,  8960,  8961,  8928,     0,  8192, 
+     8704,  8960,  8961,  8928,  8944,     0,  8192,  8704, 
+     8960,  8961,  8963,  8944,     0,  8192,  8704,  8960, 
+     8961,  8963,  8944,  8946,     0,  8192,  8704,  8960, 
+     8961,  8963,  8944,     0,  8192,  8704,  8960,  8961, 
+     8963,  8944,  8948,     0,  8192,  8704,  8960,  8961, 
+     8963,  8944,  8948,     0,  8192,  8704,  8960,  8961, 
+     8963,  8944,  8952,  8950,     0,  8192,  8704,  8960, 
+     8961,  8963,  8944,     0,  8192,  8704,  8960,  8961, 
+     8963,  8944,  8952,     0,  8192,  8704,  8960,  8961, 
+     8963,  8944,  8952,     0,  8192,  8704,  8960,  8961, 
+     8963,  8944,  8952,  8954,     0,  8192,  8704,  8960, 
+     8961,  8963,  8967,  8952,     0,  8192,  8704,  8960, 
+     8961,  8963,  8967,  8952,  8956,     0,  8192,  8704, 
+     8960,  8961,  8963,  8967,  8952,  8956,     0,  8192, 
+     8704,  8960,  8961,  8963,  8967,  8952,  8956,  8958, 
+        0,  8192,  8704,     0,  8192,  9216,  8960,     0, 
+     8192,  9216,  8960,     0,  8192,  9216,  8960,  8962, 
+        0,  8192,  9216,  8960,     0,  8192,  9216,  8960, 
+     8964,     0,  8192,  9216,  8960,  8964,     0,  8192, 
+     9216,  8960,  8968,  8966,     0,  8192,  9216,  8960, 
+        0,  8192,  9216,  8960,  8968,     0,  8192,  9216, 
+     8960,  8968,     0,  8192,  9216,  8960,  8968,  8970, 
+        0,  8192,  9216,  8960,  8968,     0,  8192,  9216, 
+     8960,  8976,  8972,     0,  8192,  9216,  8960,  8976, 
+     8972,     0,  8192,  9216,  8960,  8976,  8977,  8974, 
+        0,  8192,  9216,  8960,     0,  8192,  9216,  8960, 
+     8976,     0,  8192,  9216,  8960,  8976,     0,  8192, 
+     9216,  8960,  8976,  8978,     0,  8192,  9216,  8960, 
+     8976,     0,  8192,  9216,  8960,  8976,  8980,     0, 
+     8192,  9216,  8960,  8976,  8980,     0,  8192,  9216, 
+     8960,  8976,  8984,  8982,     0,  8192,  9216,  8960, 
+     8976,     0,  8192,  9216,  8960,  8992,  8984,     0, 
+     8192,  9216,  8960,  8992,  8984,     0,  8192,  9216, 
+     8960,  8992,  8984,  8986,     0,  8192,  9216,  8960, 
+     8992,  8984,     0,  8192,  9216,  8960,  8992,  8993, 
+     8988,     0,  8192,  9216,  8960,  8992,  8993,  8988, 
+        0,  8192,  9216,  8960,  8992,  8993,  8988,  8990, 
+        0,  8192,  9216,  8960,     0,  8192,  9216,  8960, 
+     8992,     0,  8192,  9216,  8960,  8992,     0,  8192, 
+     9216,  8960,  8992,  8994,     0,  8192,  9216,  8960, 
+     8992,     0,  8192,  9216,  8960,  8992,  8996,     0, 
+     8192,  9216,  8960,  8992,  8996,     0,  8192,  9216, 
+     8960,  8992,  9000,  8998,     0,  8192,  9216,  8960, 
+     8992,     0,  8192,  9216,  8960,  8992,  9000,     0, 
+     8192,  9216,  8960,  8992,  9000,     0,  8192,  9216, 
+     8960,  8992,  9000,  9002,     0,  8192,  9216,  8960, 
+     8992,  9000,     0,  8192,  9216,  8960,  8992,  9008, 
+     9004,     0,  8192,  9216,  8960,  8992,  9008,  9004, 
+        0,  8192,  9216,  8960,  8992,  9008,  9009,  9006, 
+        0,  8192,  9216,  8960,  8992,     0,  8192,  9216, 
+     8960,  9024,  9008,     0,  8192,  9216,  8960,  9024, 
+     9008,     0,  8192,  9216,  8960,  9024,  9008,  9010, 
+        0,  8192,  9216,  8960,  9024,  9008,     0,  8192, 
+     9216,  8960,  9024,  9008,  9012,     0,  8192,  9216, 
+     8960,  9024,  9008,  9012,     0,  8192,  9216,  8960, 
+     9024,  9008,  9016,  9014,     0,  8192,  9216,  8960, 
+     9024,  9008,     0,  8192,  9216,  8960,  9024,  9025, 
+     9016,     0,  8192,  9216,  8960,  9024,  9025,  9016, 
+        0,  8192,  9216,  8960,  9024,  9025,  9016,  9018, 
+        0,  8192,  9216,  8960,  9024,  9025,  9016,     0, 
+     8192,  9216,  8960,  9024,  9025,  9016,  9020,     0, 
+     8192,  9216,  8960,  9024,  9025,  9027,  9020,     0, 
+     8192,  9216,  8960,  9024,  9025,  9027,  9020,  9022, 
+        0,  8192,  9216,  8960,     0,  8192,  9216,  8960, 
+     9024,     0,  8192,  9216,  8960,  9024,     0,  8192, 
+     9216,  8960,  9024,  9026,     0,  8192,  9216,  8960, 
+     9024,     0,  8192,  9216,  8960,  9024,  9028,     0, 
+     8192,  9216,  8960,  9024,  9028,     0,  8192,  9216, 
+     8960,  9024,  9032,  9030,     0,  8192,  9216,  8960, 
+     9024,     0,  8192,  9216,  8960,  9024,  9032,     0, 
+     8192,  9216,  8960,  9024,  9032,     0,  8192,  9216, 
+     8960,  9024,  9032,  9034,     0,  8192,  9216,  8960, 
+     9024,  9032,     0,  8192,  9216,  8960,  9024,  9040, 
+     9036,     0,  8192,  9216,  8960,  9024,  9040,  9036, 
+        0,  8192,  9216,  8960,  9024,  9040,  9041,  9038, 
+        0,  8192,  9216,  8960,  9024,     0,  8192,  9216, 
+     8960,  9024,  9040,     0,  8192,  9216,  8960,  9024, 
+     9040,     0,  8192,  9216,  8960,  9024,  9040,  9042, 
+        0,  8192,  9216,  8960,  9024,  9040,     0,  8192, 
+     9216,  8960,  9024,  9040,  9044,     0,  8192,  9216, 
+     8960,  9024,  9040,  9044,     0,  8192,  9216,  8960, 
+     9024,  9040,  9048,  9046,     0,  8192,  9216,  8960, 
+     9024,  9040,     0,  8192,  9216,  8960,  9024,  9056, 
+     9048,     0,  8192,  9216,  8960,  9024,  9056,  9048, 
+        0,  8192,  9216,  8960,  9024,  9056,  9048,  9050, 
+        0,  8192,  9216,  8960,  9024,  9056,  9048,     0, 
+     8192,  9216,  8960,  9024,  9056,  9057,  9052,     0, 
+     8192,  9216,  8960,  9024,  9056,  9057,  9052,     0, 
+     8192,  9216,  8960,  9024,  9056,  9057,  9052,  9054, 
+        0,  8192,  9216,  8960,  9024,     0,  8192,  9216, 
+     8960,  9088,  9056,     0,  8192,  9216,  8960,  9088, 
+     9056,     0,  8192,  9216,  8960,  9088,  9056,  9058, 
+        0,  8192,  9216,  8960,  9088,  9056,     0,  8192, 
+     9216,  8960,  9088,  9056,  9060,     0,  8192,  9216, 
+     8960,  9088,  9056,  9060,     0,  8192,  9216,  8960, 
+     9088,  9056,  9064,  9062,     0,  8192,  9216,  8960, 
+     9088,  9056,     0,  8192,  9216,  8960,  9088,  9056, 
+     9064,     0,  8192,  9216,  8960,  9088,  9056,  9064, 
+        0,  8192,  9216,  8960,  9088,  9056,  9064,  9066, 
+        0,  8192,  9216,  8960,  9088,  9056,  9064,     0, 
+     8192,  9216,  8960,  9088,  9056,  9072,  9068,     0, 
+     8192,  9216,  8960,  9088,  9056,  9072,  9068,     0, 
+     8192,  9216,  8960,  9088,  9056,  9072,  9073,  9070, 
+        0,  8192,  9216,  8960,  9088,  9056,     0,  8192, 
+     9216,  8960,  9088,  9089,  9072,     0,  8192,  9216, 
+     8960,  9088,  9089,  9072,     0,  8192,  9216,  8960, 
+     9088,  9089,  9072,  9074,     0,  8192,  9216,  8960, 
+     9088,  9089,  9072,     0,  8192,  9216,  8960,  9088, 
+     9089,  9072,  9076,     0,  8192,  9216,  8960,  9088, 
+     9089,  9072,  9076,     0,  8192,  9216,  8960,  9088, 
+     9089,  9072,  9080,  9078,     0,  8192,  9216,  8960, 
+     9088,  9089,  9072,     0,  8192,  9216,  8960,  9088, 
+     9089,  9072,  9080,     0,  8192,  9216,  8960,  9088, 
+     9089,  9091,  9080,     0,  8192,  9216,  8960,  9088, 
+     9089,  9091,  9080,  9082,     0,  8192,  9216,  8960, 
+     9088,  9089,  9091,  9080,     0,  8192,  9216,  8960, 
+     9088,  9089,  9091,  9080,  9084,     0,  8192,  9216, 
+     8960,  9088,  9089,  9091,  9080,  9084,     0,  8192, 
+     9216,  8960,  9088,  9089,  9091,  9080,  9084,  9086, 
+        0,  8192,  9216,  8960,     0,  8192,  9216,  8960, 
+     9088,     0,  8192,  9216,  9217,  9088,     0,  8192, 
+     9216,  9217,  9088,  9090,     0,  8192,  9216,  9217, 
+     9088,     0,  8192,  9216,  9217,  9088,  9092,     0, 
+     8192,  9216,  9217,  9088,  9092,     0,  8192,  9216, 
+     9217,  9088,  9096,  9094,     0,  8192,  9216,  9217, 
+     9088,     0,  8192,  9216,  9217,  9088,  9096,     0, 
+     8192,  9216,  9217,  9088,  9096,     0,  8192,  9216, 
+     9217,  9088,  9096,  9098,     0,  8192,  9216,  9217, 
+     9088,  9096,     0,  8192,  9216,  9217,  9088,  9104, 
+     9100,     0,  8192,  9216,  9217,  9088,  9104,  9100, 
+        0,  8192,  9216,  9217,  9088,  9104,  9105,  9102, 
+        0,  8192,  9216,  9217,  9088,     0,  8192,  9216, 
+     9217,  9088,  9104,     0,  8192,  9216,  9217,  9088, 
+     9104,     0,  8192,  9216,  9217,  9088,  9104,  9106, 
+        0,  8192,  9216,  9217,  9088,  9104,     0,  8192, 
+     9216,  9217,  9088,  9104,  9108,     0,  8192,  9216, 
+     9217,  9088,  9104,  9108,     0,  8192,  9216,  9217, 
+     9088,  9104,  9112,  9110,     0,  8192,  9216,  9217, 
+     9088,  9104,     0,  8192,  9216,  9217,  9088,  9120, 
+     9112,     0,  8192,  9216,  9217,  9088,  9120,  9112, 
+        0,  8192,  9216,  9217,  9088,  9120,  9112,  9114, 
+        0,  8192,  9216,  9217,  9088,  9120,  9112,     0, 
+     8192,  9216,  9217,  9088,  9120,  9121,  9116,     0, 
+     8192,  9216,  9217,  9088,  9120,  9121,  9116,     0, 
+     8192,  9216,  9217,  9088,  9120,  9121,  9116,  9118, 
+        0,  8192,  9216,  9217,  9088,     0,  8192,  9216, 
+     9217,  9088,  9120,     0,  8192,  9216,  9217,  9088, 
+     9120,     0,  8192,  9216,  9217,  9088,  9120,  9122, 
+        0,  8192,  9216,  9217,  9088,  9120,     0,  8192, 
+     9216,  9217,  9088,  9120,  9124,     0,  8192,  9216, 
+     9217,  9088,  9120,  9124,     0,  8192,  9216,  9217, 
+     9088,  9120,  9128,  9126,     0,  8192,  9216,  9217, 
+     9088,  9120,     0,  8192,  9216,  9217,  9088,  9120, 
+     9128,     0,  8192,  9216,  9217,  9088,  9120,  9128, 
+        0,  8192,  9216,  9217,  9088,  9120,  9128,  9130, 
+        0,  8192,  9216,  9217,  9088,  9120,  9128,     0, 
+     8192,  9216,  9217,  9088,  9120,  9136,  9132,     0, 
+     8192,  9216,  9217,  9088,  9120,  9136,  9132,     0, 
+     8192,  9216,  9217,  9088,  9120,  9136,  9137,  9134, 
+        0,  8192,  9216,  9217,  9088,  9120,     0,  8192, 
+     9216,  9217,  9088,  9152,  9136,     0,  8192,  9216, 
+     9217,  9088,  9152,  9136,     0,  8192,  9216,  9217, 
+     9088,  9152,  9136,  9138,     0,  8192,  9216,  9217, 
+     9088,  9152,  9136,     0,  8192,  9216,  9217,  9088, 
+     9152,  9136,  9140,     0,  8192,  9216,  9217,  9088, 
+     9152,  9136,  9140,     0,  8192,  9216,  9217,  9088, 
+     9152,  9136,  9144,  9142,     0,  8192,  9216,  9217, 
+     9088,  9152,  9136,     0,  8192,  9216,  9217,  9088, 
+     9152,  9153,  9144,     0,  8192,  9216,  9217,  9088, 
+     9152,  9153,  9144,     0,  8192,  9216,  9217,  9088, 
+     9152,  9153,  9144,  9146,     0,  8192,  9216,  9217, 
+     9088,  9152,  9153,  9144,     0,  8192,  9216,  9217, 
+     9088,  9152,  9153,  9144,  9148,     0,  8192,  9216, 
+     9217,  9088,  9152,  9153,  9155,  9148,     0,  8192, 
+     9216,  9217,  9088,  9152,  9153,  9155,  9148,  9150, 
+        0,  8192,  9216,  9217,  9088,     0,  8192,  9216, 
+     9217,  9088,  9152,     0,  8192,  9216,  9217,  9088, 
+     9152,     0,  8192,  9216,  9217,  9088,  9152,  9154, 
+        0,  8192,  9216,  9217,  9219,  9152,     0,  8192, 
+     9216,  9217,  9219,  9152,  9156,     0,  8192,  9216, 
+     9217,  9219,  9152,  9156,     0,  8192,  9216,  9217, 
+     9219,  9152,  9160,  9158,     0,  8192,  9216,  9217, 
+     9219,  9152,     0,  8192,  9216,  9217,  9219,  9152, 
+     9160,     0,  8192,  9216,  9217,  9219,  9152,  9160, 
+        0,  8192,  9216,  9217,  9219,  9152,  9160,  9162, 
+        0,  8192,  9216,  9217,  9219,  9152,  9160,     0, 
+     8192,  9216,  9217,  9219,  9152,  9168,  9164,     0, 
+     8192,  9216,  9217,  9219,  9152,  9168,  9164,     0, 
+     8192,  9216,  9217,  9219,  9152,  9168,  9169,  9166, 
+        0,  8192,  9216,  9217,  9219,  9152,     0,  8192, 
+     9216,  9217,  9219,  9152,  9168,     0,  8192,  9216, 
+     9217,  9219,  9152,  9168,     0,  8192,  9216,  9217, 
+     9219,  9152,  9168,  9170,     0,  8192,  9216,  9217, 
+     9219,  9152,  9168,     0,  8192,  9216,  9217,  9219, 
+     9152,  9168,  9172,     0,  8192,  9216,  9217,  9219, 
+     9152,  9168,  9172,     0,  8192,  9216,  9217,  9219, 
+     9152,  9168,  9176,  9174,     0,  8192,  9216,  9217, 
+     9219,  9152,  9168,     0,  8192,  9216,  9217,  9219, 
+     9152,  9184,  9176,     0,  8192,  9216,  9217,  9219, 
+     9152,  9184,  9176,     0,  8192,  9216,  9217,  9219, 
+     9152,  9184,  9176,  9178,     0,  8192,  9216,  9217, 
+     9219,  9152,  9184,  9176,     0,  8192,  9216,  9217, 
+     9219,  9152,  9184,  9185,  9180,     0,  8192,  9216, 
+     9217,  9219,  9152,  9184,  9185,  9180,     0,  8192, 
+     9216,  9217,  9219,  9152,  9184,  9185,  9180,  9182, 
+        0,  8192,  9216,  9217,  9219,  9152,     0,  8192, 
+     9216,  9217,  9219,  9152,  9184,     0,  8192,  9216, 
+     9217,  9219,  9152,  9184,     0,  8192,  9216,  9217, 
+     9219,  9152,  9184,  9186,     0,  8192,  9216,  9217, 
+     9219,  9152,  9184,     0,  8192,  9216,  9217,  9219, 
+     9152,  9184,  9188,     0,  8192,  9216,  9217,  9219, 
+     9152,  9184,  9188,     0,  8192,  9216,  9217,  9219, 
+     9152,  9184,  9192,  9190,     0,  8192,  9216,  9217, 
+     9219,  9223,  9184,     0,  8192,  9216,  9217,  9219, 
+     9223,  9184,  9192,     0,  8192,  9216,  9217,  9219, 
+     9223,  9184,  9192,     0,  8192,  9216,  9217,  9219, 
+     9223,  9184,  9192,  9194,     0,  8192,  9216,  9217, 
+     9219,  9223,  9184,  9192,     0,  8192,  9216,  9217, 
+     9219,  9223,  9184,  9200,  9196,     0,  8192,  9216, 
+     9217,  9219,  9223,  9184,  9200,  9196,     0,  8192, 
+     9216,  9217,  9219,  9223,  9184,  9200,  9201,  9198, 
+        0,  8192,  9216,  9217,  9219,  9223,  9184,     0, 
+     8192,  9216,  9217,  9219,  9223,  9184,  9200,     0, 
+     8192,  9216,  9217,  9219,  9223,  9184,  9200,     0, 
+     8192,  9216,  9217,  9219,  9223,  9184,  9200,  9202, 
+        0,  8192,  9216,  9217,  9219,  9223,  9184,  9200, 
+        0,  8192,  9216,  9217,  9219,  9223,  9184,  9200, 
+     9204,     0,  8192,  9216,  9217,  9219,  9223,  9184, 
+     9200,  9204,     0,  8192,  9216,  9217,  9219,  9223, 
+     9184,  9200,  9208,  9206,     0,  8192,  9216,  9217, 
+     9219,  9223,  9184,  9200,     0,  8192,  9216,  9217, 
+     9219,  9223,  9184,  9200,  9208,     0,  8192,  9216, 
+     9217,  9219,  9223,  9184,  9200,  9208,     0,  8192, 
+     9216,  9217,  9219,  9223,  9184,  9200,  9208,  9210, 
+        0,  8192,  9216,  9217,  9219,  9223,  9184,  9200, 
+     9208,     0,  8192,  9216,  9217,  9219,  9223,  9184, 
+     9200,  9208,  9212,     0,  8192,  9216,  9217,  9219, 
+     9223,  9184,  9200,  9208,  9212,     0,  8192,  9216, 
+     9217,  9219,  9223,  9184,  9200,  9208,  9212,  9214, 
+        0,  8192,     0,  8192,  9216,     0,  8192,  9216, 
+        0,  8192,  9216,  9218,     0,  8192,  9216,     0, 
+     8192,  9216,  9220,     0,  8192,  9216,  9220,     0, 
+     8192,  9216,  9224,  9222,     0,  8192,  9216,     0, 
+     8192,  9216,  9224,     0,  8192,  9216,  9224,     0, 
+     8192,  9216,  9224,  9226,     0,  8192,  9216,  9224, 
+        0,  8192,  9216,  9232,  9228,     0,  8192,  9216, 
+     9232,  9228,     0,  8192,  9216,  9232,  9233,  9230, 
+        0,  8192,  9216,     0,  8192,  9216,  9232,     0, 
+     8192,  9216,  9232,     0,  8192,  9216,  9232,  9234, 
+        0,  8192,  9216,  9232,     0,  8192,  9216,  9232, 
+     9236,     0,  8192,  9216,  9232,  9236,     0,  8192, 
+     9216,  9232,  9240,  9238,     0,  8192,  9216,  9232, 
+        0,  8192,  9216,  9248,  9240,     0,  8192,  9216, 
+     9248,  9240,     0,  8192,  9216,  9248,  9240,  9242, 
+        0,  8192,  9216,  9248,  9240,     0,  8192,  9216, 
+     9248,  9249,  9244,     0,  8192,  9216,  9248,  9249, 
+     9244,     0,  8192,  9216,  9248,  9249,  9244,  9246, 
+        0,  8192,  9216,     0,  8192,  9216,  9248,     0, 
+     8192,  9216,  9248,     0,  8192,  9216,  9248,  9250, 
+        0,  8192,  9216,  9248,     0,  8192,  9216,  9248, 
+     9252,     0,  8192,  9216,  9248,  9252,     0,  8192, 
+     9216,  9248,  9256,  9254,     0,  8192,  9216,  9248, 
+        0,  8192,  9216,  9248,  9256,     0,  8192,  9216, 
+     9248,  9256,     0,  8192,  9216,  9248,  9256,  9258, 
+        0,  8192,  9216,  9248,  9256,     0,  8192,  9216, 
+     9248,  9264,  9260,     0,  8192,  9216,  9248,  9264, 
+     9260,     0,  8192,  9216,  9248,  9264,  9265,  9262, 
+        0,  8192,  9216,  9248,     0,  8192,  9216,  9280, 
+     9264,     0,  8192,  9216,  9280,  9264,     0,  8192, 
+     9216,  9280,  9264,  9266,     0,  8192,  9216,  9280, 
+     9264,     0,  8192,  9216,  9280,  9264,  9268,     0, 
+     8192,  9216,  9280,  9264,  9268,     0,  8192,  9216, 
+     9280,  9264,  9272,  9270,     0,  8192,  9216,  9280, 
+     9264,     0,  8192,  9216,  9280,  9281,  9272,     0, 
+     8192,  9216,  9280,  9281,  9272,     0,  8192,  9216, 
+     9280,  9281,  9272,  9274,     0,  8192,  9216,  9280, 
+     9281,  9272,     0,  8192,  9216,  9280,  9281,  9272, 
+     9276,     0,  8192,  9216,  9280,  9281,  9283,  9276, 
+        0,  8192,  9216,  9280,  9281,  9283,  9276,  9278, 
+        0,  8192,  9216,     0,  8192,  9216,  9280,     0, 
+     8192,  9216,  9280,     0,  8192,  9216,  9280,  9282, 
+        0,  8192,  9216,  9280,     0,  8192,  9216,  9280, 
+     9284,     0,  8192,  9216,  9280,  9284,     0,  8192, 
+     9216,  9280,  9288,  9286,     0,  8192,  9216,  9280, 
+        0,  8192,  9216,  9280,  9288,     0,  8192,  9216, 
+     9280,  9288,     0,  8192,  9216,  9280,  9288,  9290, 
+        0,  8192,  9216,  9280,  9288,     0,  8192,  9216, 
+     9280,  9296,  9292,     0,  8192,  9216,  9280,  9296, 
+     9292,     0,  8192,  9216,  9280,  9296,  9297,  9294, 
+        0,  8192,  9216,  9280,     0,  8192,  9216,  9280, 
+     9296,     0,  8192,  9216,  9280,  9296,     0,  8192, 
+     9216,  9280,  9296,  9298,     0,  8192,  9216,  9280, 
+     9296,     0,  8192,  9216,  9280,  9296,  9300,     0, 
+     8192,  9216,  9280,  9296,  9300,     0,  8192,  9216, 
+     9280,  9296,  9304,  9302,     0,  8192,  9216,  9280, 
+     9296,     0,  8192,  9216,  9280,  9312,  9304,     0, 
+     8192,  9216,  9280,  9312,  9304,     0,  8192,  9216, 
+     9280,  9312,  9304,  9306,     0,  8192,  9216,  9280, 
+     9312,  9304,     0,  8192,  9216,  9280,  9312,  9313, 
+     9308,     0,  8192,  9216,  9280,  9312,  9313,  9308, 
+        0,  8192,  9216,  9280,  9312,  9313,  9308,  9310, 
+        0,  8192,  9216,  9280,     0,  8192,  9216,  9344, 
+     9312,     0,  8192,  9216,  9344,  9312,     0,  8192, 
+     9216,  9344,  9312,  9314,     0,  8192,  9216,  9344, 
+     9312,     0,  8192,  9216,  9344,  9312,  9316,     0, 
+     8192,  9216,  9344,  9312,  9316,     0,  8192,  9216, 
+     9344,  9312,  9320,  9318,     0,  8192,  9216,  9344, 
+     9312,     0,  8192,  9216,  9344,  9312,  9320,     0, 
+     8192,  9216,  9344,  9312,  9320,     0,  8192,  9216, 
+     9344,  9312,  9320,  9322,     0,  8192,  9216,  9344, 
+     9312,  9320,     0,  8192,  9216,  9344,  9312,  9328, 
+     9324,     0,  8192,  9216,  9344,  9312,  9328,  9324, 
+        0,  8192,  9216,  9344,  9312,  9328,  9329,  9326, 
+        0,  8192,  9216,  9344,  9312,     0,  8192,  9216, 
+     9344,  9345,  9328,     0,  8192,  9216,  9344,  9345, 
+     9328,     0,  8192,  9216,  9344,  9345,  9328,  9330, 
+        0,  8192,  9216,  9344,  9345,  9328,     0,  8192, 
+     9216,  9344,  9345,  9328,  9332,     0,  8192,  9216, 
+     9344,  9345,  9328,  9332,     0,  8192,  9216,  9344, 
+     9345,  9328,  9336,  9334,     0,  8192,  9216,  9344, 
+     9345,  9328,     0,  8192,  9216,  9344,  9345,  9328, 
+     9336,     0,  8192,  9216,  9344,  9345,  9347,  9336, 
+        0,  8192,  9216,  9344,  9345,  9347,  9336,  9338, 
+        0,  8192,  9216,  9344,  9345,  9347,  9336,     0, 
+     8192,  9216,  9344,  9345,  9347,  9336,  9340,     0, 
+     8192,  9216,  9344,  9345,  9347,  9336,  9340,     0, 
+     8192,  9216,  9344,  9345,  9347,  9336,  9340,  9342, 
+        0,  8192,  9216,     0,  8192,  9216,  9344,     0, 
+     8192,  9216,  9344,     0,  8192,  9216,  9344,  9346, 
+        0,  8192,  9216,  9344,     0,  8192,  9216,  9344, 
+     9348,     0,  8192,  9216,  9344,  9348,     0,  8192, 
+     9216,  9344,  9352,  9350,     0,  8192,  9216,  9344, 
+        0,  8192,  9216,  9344,  9352,     0,  8192,  9216, 
+     9344,  9352,     0,  8192,  9216,  9344,  9352,  9354, 
+        0,  8192,  9216,  9344,  9352,     0,  8192,  9216, 
+     9344,  9360,  9356,     0,  8192,  9216,  9344,  9360, 
+     9356,     0,  8192,  9216,  9344,  9360,  9361,  9358, 
+        0,  8192,  9216,  9344,     0,  8192,  9216,  9344, 
+     9360,     0,  8192,  9216,  9344,  9360,     0,  8192, 
+     9216,  9344,  9360,  9362,     0,  8192,  9216,  9344, 
+     9360,     0,  8192,  9216,  9344,  9360,  9364,     0, 
+     8192,  9216,  9344,  9360,  9364,     0,  8192,  9216, 
+     9344,  9360,  9368,  9366,     0,  8192,  9216,  9344, 
+     9360,     0,  8192,  9216,  9344,  9376,  9368,     0, 
+     8192,  9216,  9344,  9376,  9368,     0,  8192,  9216, 
+     9344,  9376,  9368,  9370,     0,  8192,  9216,  9344, 
+     9376,  9368,     0,  8192,  9216,  9344,  9376,  9377, 
+     9372,     0,  8192,  9216,  9344,  9376,  9377,  9372, 
+        0,  8192,  9216,  9344,  9376,  9377,  9372,  9374, 
+        0,  8192,  9216,  9344,     0,  8192,  9216,  9344, 
+     9376,     0,  8192,  9216,  9344,  9376,     0,  8192, 
+     9216,  9344,  9376,  9378,     0,  8192,  9216,  9344, 
+     9376,     0,  8192,  9216,  9344,  9376,  9380,     0, 
+     8192,  9216,  9344,  9376,  9380,     0,  8192,  9216, 
+     9344,  9376,  9384,  9382,     0,  8192,  9216,  9344, 
+     9376,     0,  8192,  9216,  9344,  9376,  9384,     0, 
+     8192,  9216,  9344,  9376,  9384,     0,  8192,  9216, 
+     9344,  9376,  9384,  9386,     0,  8192,  9216,  9344, 
+     9376,  9384,     0,  8192,  9216,  9344,  9376,  9392, 
+     9388,     0,  8192,  9216,  9344,  9376,  9392,  9388, 
+        0,  8192,  9216,  9344,  9376,  9392,  9393,  9390, 
+        0,  8192,  9216,  9344,  9376,     0,  8192,  9216, 
+     9344,  9408,  9392,     0,  8192,  9216,  9344,  9408, 
+     9392,     0,  8192,  9216,  9344,  9408,  9392,  9394, 
+        0,  8192,  9216,  9344,  9408,  9392,     0,  8192, 
+     9216,  9344,  9408,  9392,  9396,     0,  8192,  9216, 
+     9344,  9408,  9392,  9396,     0,  8192,  9216,  9344, 
+     9408,  9392,  9400,  9398,     0,  8192,  9216,  9344, 
+     9408,  9392,     0,  8192,  9216,  9344,  9408,  9409, 
+     9400,     0,  8192,  9216,  9344,  9408,  9409,  9400, 
+        0,  8192,  9216,  9344,  9408,  9409,  9400,  9402, 
+        0,  8192,  9216,  9344,  9408,  9409,  9400,     0, 
+     8192,  9216,  9344,  9408,  9409,  9400,  9404,     0, 
+     8192,  9216,  9344,  9408,  9409,  9411,  9404,     0, 
+     8192,  9216,  9344,  9408,  9409,  9411,  9404,  9406, 
+        0,  8192,  9216,  9344,     0,  8192,  9216,  9472, 
+     9408,     0,  8192,  9216,  9472,  9408,     0,  8192, 
+     9216,  9472,  9408,  9410,     0,  8192,  9216,  9472, 
+     9408,     0,  8192,  9216,  9472,  9408,  9412,     0, 
+     8192,  9216,  9472,  9408,  9412,     0,  8192,  9216, 
+     9472,  9408,  9416,  9414,     0,  8192,  9216,  9472, 
+     9408,     0,  8192,  9216,  9472,  9408,  9416,     0, 
+     8192,  9216,  9472,  9408,  9416,     0,  8192,  9216, 
+     9472,  9408,  9416,  9418,     0,  8192,  9216,  9472, 
+     9408,  9416,     0,  8192,  9216,  9472,  9408,  9424, 
+     9420,     0,  8192,  9216,  9472,  9408,  9424,  9420, 
+        0,  8192,  9216,  9472,  9408,  9424,  9425,  9422, 
+        0,  8192,  9216,  9472,  9408,     0,  8192,  9216, 
+     9472,  9408,  9424,     0,  8192,  9216,  9472,  9408, 
+     9424,     0,  8192,  9216,  9472,  9408,  9424,  9426, 
+        0,  8192,  9216,  9472,  9408,  9424,     0,  8192, 
+     9216,  9472,  9408,  9424,  9428,     0,  8192,  9216, 
+     9472,  9408,  9424,  9428,     0,  8192,  9216,  9472, 
+     9408,  9424,  9432,  9430,     0,  8192,  9216,  9472, 
+     9408,  9424,     0,  8192,  9216,  9472,  9408,  9440, 
+     9432,     0,  8192,  9216,  9472,  9408,  9440,  9432, 
+        0,  8192,  9216,  9472,  9408,  9440,  9432,  9434, 
+        0,  8192,  9216,  9472,  9408,  9440,  9432,     0, 
+     8192,  9216,  9472,  9408,  9440,  9441,  9436,     0, 
+     8192,  9216,  9472,  9408,  9440,  9441,  9436,     0, 
+     8192,  9216,  9472,  9408,  9440,  9441,  9436,  9438, 
+        0,  8192,  9216,  9472,  9408,     0,  8192,  9216, 
+     9472,  9473,  9440,     0,  8192,  9216,  9472,  9473, 
+     9440,     0,  8192,  9216,  9472,  9473,  9440,  9442, 
+        0,  8192,  9216,  9472,  9473,  9440,     0,  8192, 
+     9216,  9472,  9473,  9440,  9444,     0,  8192,  9216, 
+     9472,  9473,  9440,  9444,     0,  8192,  9216,  9472, 
+     9473,  9440,  9448,  9446,     0,  8192,  9216,  9472, 
+     9473,  9440,     0,  8192,  9216,  9472,  9473,  9440, 
+     9448,     0,  8192,  9216,  9472,  9473,  9440,  9448, 
+        0,  8192,  9216,  9472,  9473,  9440,  9448,  9450, 
+        0,  8192,  9216,  9472,  9473,  9440,  9448,     0, 
+     8192,  9216,  9472,  9473,  9440,  9456,  9452,     0, 
+     8192,  9216,  9472,  9473,  9440,  9456,  9452,     0, 
+     8192,  9216,  9472,  9473,  9440,  9456,  9457,  9454, 
+        0,  8192,  9216,  9472,  9473,  9440,     0,  8192, 
+     9216,  9472,  9473,  9440,  9456,     0,  8192,  9216, 
+     9472,  9473,  9475,  9456,     0,  8192,  9216,  9472, 
+     9473,  9475,  9456,  9458,     0,  8192,  9216,  9472, 
+     9473,  9475,  9456,     0,  8192,  9216,  9472,  9473, 
+     9475,  9456,  9460,     0,  8192,  9216,  9472,  9473, 
+     9475,  9456,  9460,     0,  8192,  9216,  9472,  9473, 
+     9475,  9456,  9464,  9462,     0,  8192,  9216,  9472, 
+     9473,  9475,  9456,     0,  8192,  9216,  9472,  9473, 
+     9475,  9456,  9464,     0,  8192,  9216,  9472,  9473, 
+     9475,  9456,  9464,     0,  8192,  9216,  9472,  9473, 
+     9475,  9456,  9464,  9466,     0,  8192,  9216,  9472, 
+     9473,  9475,  9479,  9464,     0,  8192,  9216,  9472, 
+     9473,  9475,  9479,  9464,  9468,     0,  8192,  9216, 
+     9472,  9473,  9475,  9479,  9464,  9468,     0,  8192, 
+     9216,  9472,  9473,  9475,  9479,  9464,  9468,  9470, 
+        0,  8192,  9216,     0,  8192,  9216,  9472,     0, 
+     8192,  9216,  9472,     0,  8192,  9216,  9472,  9474, 
+        0,  8192,  9216,  9472,     0,  8192,  9216,  9472, 
+     9476,     0,  8192,  9216,  9472,  9476,     0,  8192, 
+     9216,  9472,  9480,  9478,     0,  8192,  9216,  9472, 
+        0,  8192,  9216,  9472,  9480,     0,  8192,  9216, 
+     9472,  9480,     0,  8192,  9216,  9472,  9480,  9482, 
+        0,  8192,  9216,  9472,  9480,     0,  8192,  9216, 
+     9472,  9488,  9484,     0,  8192,  9216,  9472,  9488, 
+     9484,     0,  8192,  9216,  9472,  9488,  9489,  9486, 
+        0,  8192,  9216,  9472,     0,  8192,  9216,  9472, 
+     9488,     0,  8192,  9216,  9472,  9488,     0,  8192, 
+     9216,  9472,  9488,  9490,     0,  8192,  9216,  9472, 
+     9488,     0,  8192,  9216,  9472,  9488,  9492,     0, 
+     8192,  9216,  9472,  9488,  9492,     0,  8192,  9216, 
+     9472,  9488,  9496,  9494,     0,  8192,  9216,  9472, 
+     9488,     0,  8192,  9216,  9472,  9504,  9496,     0, 
+     8192,  9216,  9472,  9504,  9496,     0,  8192,  9216, 
+     9472,  9504,  9496,  9498,     0,  8192,  9216,  9472, 
+     9504,  9496,     0,  8192,  9216,  9472,  9504,  9505, 
+     9500,     0,  8192,  9216,  9472,  9504,  9505,  9500, 
+        0,  8192,  9216,  9472,  9504,  9505,  9500,  9502, 
+        0,  8192,  9216,  9472,     0,  8192,  9216,  9472, 
+     9504,     0,  8192,  9216,  9472,  9504,     0,  8192, 
+     9216,  9472,  9504,  9506,     0,  8192,  9216,  9472, 
+     9504,     0,  8192,  9216,  9472,  9504,  9508,     0, 
+     8192,  9216,  9472,  9504,  9508,     0,  8192,  9216, 
+     9472,  9504,  9512,  9510,     0,  8192,  9216,  9472, 
+     9504,     0,  8192,  9216,  9472,  9504,  9512,     0, 
+     8192,  9216,  9472,  9504,  9512,     0,  8192,  9216, 
+     9472,  9504,  9512,  9514,     0,  8192,  9216,  9472, 
+     9504,  9512,     0,  8192,  9216,  9472,  9504,  9520, 
+     9516,     0,  8192,  9216,  9472,  9504,  9520,  9516, 
+        0,  8192,  9216,  9472,  9504,  9520,  9521,  9518, 
+        0,  8192,  9216,  9472,  9504,     0,  8192,  9216, 
+     9472,  9536,  9520,     0,  8192,  9216,  9472,  9536, 
+     9520,     0,  8192,  9216,  9472,  9536,  9520,  9522, 
+        0,  8192,  9216,  9472,  9536,  9520,     0,  8192, 
+     9216,  9472,  9536,  9520,  9524,     0,  8192,  9216, 
+     9472,  9536,  9520,  9524,     0,  8192,  9216,  9472, 
+     9536,  9520,  9528,  9526,     0,  8192,  9216,  9472, 
+     9536,  9520,     0,  8192,  9216,  9472,  9536,  9537, 
+     9528,     0,  8192,  9216,  9472,  9536,  9537,  9528, 
+        0,  8192,  9216,  9472,  9536,  9537,  9528,  9530, 
+        0,  8192,  9216,  9472,  9536,  9537,  9528,     0, 
+     8192,  9216,  9472,  9536,  9537,  9528,  9532,     0, 
+     8192,  9216,  9472,  9536,  9537,  9539,  9532,     0, 
+     8192,  9216,  9472,  9536,  9537,  9539,  9532,  9534, 
+        0,  8192,  9216,  9472,     0,  8192,  9216,  9472, 
+     9536,     0,  8192,  9216,  9472,  9536,     0,  8192, 
+     9216,  9472,  9536,  9538,     0,  8192,  9216,  9472, 
+     9536,     0,  8192,  9216,  9472,  9536,  9540,     0, 
+     8192,  9216,  9472,  9536,  9540,     0,  8192,  9216, 
+     9472,  9536,  9544,  9542,     0,  8192,  9216,  9472, 
+     9536,     0,  8192,  9216,  9472,  9536,  9544,     0, 
+     8192,  9216,  9472,  9536,  9544,     0,  8192,  9216, 
+     9472,  9536,  9544,  9546,     0,  8192,  9216,  9472, 
+     9536,  9544,     0,  8192,  9216,  9472,  9536,  9552, 
+     9548,     0,  8192,  9216,  9472,  9536,  9552,  9548, 
+        0,  8192,  9216,  9472,  9536,  9552,  9553,  9550, 
+        0,  8192,  9216,  9472,  9536,     0,  8192,  9216, 
+     9472,  9536,  9552,     0,  8192,  9216,  9472,  9536, 
+     9552,     0,  8192,  9216,  9472,  9536,  9552,  9554, 
+        0,  8192,  9216,  9472,  9536,  9552,     0,  8192, 
+     9216,  9472,  9536,  9552,  9556,     0,  8192,  9216, 
+     9472,  9536,  9552,  9556,     0,  8192,  9216,  9472, 
+     9536,  9552,  9560,  9558,     0,  8192,  9216,  9472, 
+     9536,  9552,     0,  8192,  9216,  9472,  9536,  9568, 
+     9560,     0,  8192,  9216,  9472,  9536,  9568,  9560, 
+        0,  8192,  9216,  9472,  9536,  9568,  9560,  9562, 
+        0,  8192,  9216,  9472,  9536,  9568,  9560,     0, 
+     8192,  9216,  9472,  9536,  9568,  9569,  9564,     0, 
+     8192,  9216,  9472,  9536,  9568,  9569,  9564,     0, 
+     8192,  9216,  9472,  9536,  9568,  9569,  9564,  9566, 
+        0,  8192,  9216,  9472,  9536,     0,  8192,  9216, 
+     9472,  9600,  9568,     0,  8192,  9216,  9472,  9600, 
+     9568,     0,  8192,  9216,  9472,  9600,  9568,  9570, 
+        0,  8192,  9216,  9472,  9600,  9568,     0,  8192, 
+     9216,  9472,  9600,  9568,  9572,     0,  8192,  9216, 
+     9472,  9600,  9568,  9572,     0,  8192,  9216,  9472, 
+     9600,  9568,  9576,  9574,     0,  8192,  9216,  9472, 
+     9600,  9568,     0,  8192,  9216,  9472,  9600,  9568, 
+     9576,     0,  8192,  9216,  9472,  9600,  9568,  9576, 
+        0,  8192,  9216,  9472,  9600,  9568,  9576,  9578, 
+        0,  8192,  9216,  9472,  9600,  9568,  9576,     0, 
+     8192,  9216,  9472,  9600,  9568,  9584,  9580,     0, 
+     8192,  9216,  9472,  9600,  9568,  9584,  9580,     0, 
+     8192,  9216,  9472,  9600,  9568,  9584,  9585,  9582, 
+        0,  8192,  9216,  9472,  9600,  9568,     0,  8192, 
+     9216,  9472,  9600,  9601,  9584,     0,  8192,  9216, 
+     9472,  9600,  9601,  9584,     0,  8192,  9216,  9472, 
+     9600,  9601,  9584,  9586,     0,  8192,  9216,  9472, 
+     9600,  9601,  9584,     0,  8192,  9216,  9472,  9600, 
+     9601,  9584,  9588,     0,  8192,  9216,  9472,  9600, 
+     9601,  9584,  9588,     0,  8192,  9216,  9472,  9600, 
+     9601,  9584,  9592,  9590,     0,  8192,  9216,  9472, 
+     9600,  9601,  9584,     0,  8192,  9216,  9472,  9600, 
+     9601,  9584,  9592,     0,  8192,  9216,  9472,  9600, 
+     9601,  9603,  9592,     0,  8192,  9216,  9472,  9600, 
+     9601,  9603,  9592,  9594,     0,  8192,  9216,  9472, 
+     9600,  9601,  9603,  9592,     0,  8192,  9216,  9472, 
+     9600,  9601,  9603,  9592,  9596,     0,  8192,  9216, 
+     9472,  9600,  9601,  9603,  9592,  9596,     0,  8192, 
+     9216,  9472,  9600,  9601,  9603,  9592,  9596,  9598, 
+        0,  8192,  9216,  9472,     0,  8192,  9216,  9728, 
+     9600,     0,  8192,  9216,  9728,  9600,     0,  8192, 
+     9216,  9728,  9600,  9602,     0,  8192,  9216,  9728, 
+     9600,     0,  8192,  9216,  9728,  9600,  9604,     0, 
+     8192,  9216,  9728,  9600,  9604,     0,  8192,  9216, 
+     9728,  9600,  9608,  9606,     0,  8192,  9216,  9728, 
+     9600,     0,  8192,  9216,  9728,  9600,  9608,     0, 
+     8192,  9216,  9728,  9600,  9608,     0,  8192,  9216, 
+     9728,  9600,  9608,  9610,     0,  8192,  9216,  9728, 
+     9600,  9608,     0,  8192,  9216,  9728,  9600,  9616, 
+     9612,     0,  8192,  9216,  9728,  9600,  9616,  9612, 
+        0,  8192,  9216,  9728,  9600,  9616,  9617,  9614, 
+        0,  8192,  9216,  9728,  9600,     0,  8192,  9216, 
+     9728,  9600,  9616,     0,  8192,  9216,  9728,  9600, 
+     9616,     0,  8192,  9216,  9728,  9600,  9616,  9618, 
+        0,  8192,  9216,  9728,  9600,  9616,     0,  8192, 
+     9216,  9728,  9600,  9616,  9620,     0,  8192,  9216, 
+     9728,  9600,  9616,  9620,     0,  8192,  9216,  9728, 
+     9600,  9616,  9624,  9622,     0,  8192,  9216,  9728, 
+     9600,  9616,     0,  8192,  9216,  9728,  9600,  9632, 
+     9624,     0,  8192,  9216,  9728,  9600,  9632,  9624, 
+        0,  8192,  9216,  9728,  9600,  9632,  9624,  9626, 
+        0,  8192,  9216,  9728,  9600,  9632,  9624,     0, 
+     8192,  9216,  9728,  9600,  9632,  9633,  9628,     0, 
+     8192,  9216,  9728,  9600,  9632,  9633,  9628,     0, 
+     8192,  9216,  9728,  9600,  9632,  9633,  9628,  9630, 
+        0,  8192,  9216,  9728,  9600,     0,  8192,  9216, 
+     9728,  9600,  9632,     0,  8192,  9216,  9728,  9600, 
+     9632,     0,  8192,  9216,  9728,  9600,  9632,  9634, 
+        0,  8192,  9216,  9728,  9600,  9632,     0,  8192, 
+     9216,  9728,  9600,  9632,  9636,     0,  8192,  9216, 
+     9728,  9600,  9632,  9636,     0,  8192,  9216,  9728, 
+     9600,  9632,  9640,  9638,     0,  8192,  9216,  9728, 
+     9600,  9632,     0,  8192,  9216,  9728,  9600,  9632, 
+     9640,     0,  8192,  9216,  9728,  9600,  9632,  9640, 
+        0,  8192,  9216,  9728,  9600,  9632,  9640,  9642, 
+        0,  8192,  9216,  9728,  9600,  9632,  9640,     0, 
+     8192,  9216,  9728,  9600,  9632,  9648,  9644,     0, 
+     8192,  9216,  9728,  9600,  9632,  9648,  9644,     0, 
+     8192,  9216,  9728,  9600,  9632,  9648,  9649,  9646, 
+        0,  8192,  9216,  9728,  9600,  9632,     0,  8192, 
+     9216,  9728,  9600,  9664,  9648,     0,  8192,  9216, 
+     9728,  9600,  9664,  9648,     0,  8192,  9216,  9728, 
+     9600,  9664,  9648,  9650,     0,  8192,  9216,  9728, 
+     9600,  9664,  9648,     0,  8192,  9216,  9728,  9600, 
+     9664,  9648,  9652,     0,  8192,  9216,  9728,  9600, 
+     9664,  9648,  9652,     0,  8192,  9216,  9728,  9600, 
+     9664,  9648,  9656,  9654,     0,  8192,  9216,  9728, 
+     9600,  9664,  9648,     0,  8192,  9216,  9728,  9600, 
+     9664,  9665,  9656,     0,  8192,  9216,  9728,  9600, 
+     9664,  9665,  9656,     0,  8192,  9216,  9728,  9600, 
+     9664,  9665,  9656,  9658,     0,  8192,  9216,  9728, 
+     9600,  9664,  9665,  9656,     0,  8192,  9216,  9728, 
+     9600,  9664,  9665,  9656,  9660,     0,  8192,  9216, 
+     9728,  9600,  9664,  9665,  9667,  9660,     0,  8192, 
+     9216,  9728,  9600,  9664,  9665,  9667,  9660,  9662, 
+        0,  8192,  9216,  9728,  9600,     0,  8192,  9216, 
+     9728,  9729,  9664,     0,  8192,  9216,  9728,  9729, 
+     9664,     0,  8192,  9216,  9728,  9729,  9664,  9666, 
+        0,  8192,  9216,  9728,  9729,  9664,     0,  8192, 
+     9216,  9728,  9729,  9664,  9668,     0,  8192,  9216, 
+     9728,  9729,  9664,  9668,     0,  8192,  9216,  9728, 
+     9729,  9664,  9672,  9670,     0,  8192,  9216,  9728, 
+     9729,  9664,     0,  8192,  9216,  9728,  9729,  9664, 
+     9672,     0,  8192,  9216,  9728,  9729,  9664,  9672, 
+        0,  8192,  9216,  9728,  9729,  9664,  9672,  9674, 
+        0,  8192,  9216,  9728,  9729,  9664,  9672,     0, 
+     8192,  9216,  9728,  9729,  9664,  9680,  9676,     0, 
+     8192,  9216,  9728,  9729,  9664,  9680,  9676,     0, 
+     8192,  9216,  9728,  9729,  9664,  9680,  9681,  9678, 
+        0,  8192,  9216,  9728,  9729,  9664,     0,  8192, 
+     9216,  9728,  9729,  9664,  9680,     0,  8192,  9216, 
+     9728,  9729,  9664,  9680,     0,  8192,  9216,  9728, 
+     9729,  9664,  9680,  9682,     0,  8192,  9216,  9728, 
+     9729,  9664,  9680,     0,  8192,  9216,  9728,  9729, 
+     9664,  9680,  9684,     0,  8192,  9216,  9728,  9729, 
+     9664,  9680,  9684,     0,  8192,  9216,  9728,  9729, 
+     9664,  9680,  9688,  9686,     0,  8192,  9216,  9728, 
+     9729,  9664,  9680,     0,  8192,  9216,  9728,  9729, 
+     9664,  9696,  9688,     0,  8192,  9216,  9728,  9729, 
+     9664,  9696,  9688,     0,  8192,  9216,  9728,  9729, 
+     9664,  9696,  9688,  9690,     0,  8192,  9216,  9728, 
+     9729,  9664,  9696,  9688,     0,  8192,  9216,  9728, 
+     9729,  9664,  9696,  9697,  9692,     0,  8192,  9216, 
+     9728,  9729,  9664,  9696,  9697,  9692,     0,  8192, 
+     9216,  9728,  9729,  9664,  9696,  9697,  9692,  9694, 
+        0,  8192,  9216,  9728,  9729,  9664,     0,  8192, 
+     9216,  9728,  9729,  9664,  9696,     0,  8192,  9216, 
+     9728,  9729,  9731,  9696,     0,  8192,  9216,  9728, 
+     9729,  9731,  9696,  9698,     0,  8192,  9216,  9728, 
+     9729,  9731,  9696,     0,  8192,  9216,  9728,  9729, 
+     9731,  9696,  9700,     0,  8192,  9216,  9728,  9729, 
+     9731,  9696,  9700,     0,  8192,  9216,  9728,  9729, 
+     9731,  9696,  9704,  9702,     0,  8192,  9216,  9728, 
+     9729,  9731,  9696,     0,  8192,  9216,  9728,  9729, 
+     9731,  9696,  9704,     0,  8192,  9216,  9728,  9729, 
+     9731,  9696,  9704,     0,  8192,  9216,  9728,  9729, 
+     9731,  9696,  9704,  9706,     0,  8192,  9216,  9728, 
+     9729,  9731,  9696,  9704,     0,  8192,  9216,  9728, 
+     9729,  9731,  9696,  9712,  9708,     0,  8192,  9216, 
+     9728,  9729,  9731,  9696,  9712,  9708,     0,  8192, 
+     9216,  9728,  9729,  9731,  9696,  9712,  9713,  9710, 
+        0,  8192,  9216,  9728,  9729,  9731,  9696,     0, 
+     8192,  9216,  9728,  9729,  9731,  9696,  9712,     0, 
+     8192,  9216,  9728,  9729,  9731,  9696,  9712,     0, 
+     8192,  9216,  9728,  9729,  9731,  9696,  9712,  9714, 
+        0,  8192,  9216,  9728,  9729,  9731,  9735,  9712, 
+        0,  8192,  9216,  9728,  9729,  9731,  9735,  9712, 
+     9716,     0,  8192,  9216,  9728,  9729,  9731,  9735, 
+     9712,  9716,     0,  8192,  9216,  9728,  9729,  9731, 
+     9735,  9712,  9720,  9718,     0,  8192,  9216,  9728, 
+     9729,  9731,  9735,  9712,     0,  8192,  9216,  9728, 
+     9729,  9731,  9735,  9712,  9720,     0,  8192,  9216, 
+     9728,  9729,  9731,  9735,  9712,  9720,     0,  8192, 
+     9216,  9728,  9729,  9731,  9735,  9712,  9720,  9722, 
+        0,  8192,  9216,  9728,  9729,  9731,  9735,  9712, 
+     9720,     0,  8192,  9216,  9728,  9729,  9731,  9735, 
+     9712,  9720,  9724,     0,  8192,  9216,  9728,  9729, 
+     9731,  9735,  9712,  9720,  9724,     0,  8192,  9216, 
+     9728,  9729,  9731,  9735,  9712,  9720,  9724,  9726, 
+        0,  8192,  9216,     0,  8192, 10240,  9728,     0, 
+     8192, 10240,  9728,     0,  8192, 10240,  9728,  9730, 
+        0,  8192, 10240,  9728,     0,  8192, 10240,  9728, 
+     9732,     0,  8192, 10240,  9728,  9732,     0,  8192, 
+    10240,  9728,  9736,  9734,     0,  8192, 10240,  9728, 
+        0,  8192, 10240,  9728,  9736,     0,  8192, 10240, 
+     9728,  9736,     0,  8192, 10240,  9728,  9736,  9738, 
+        0,  8192, 10240,  9728,  9736,     0,  8192, 10240, 
+     9728,  9744,  9740,     0,  8192, 10240,  9728,  9744, 
+     9740,     0,  8192, 10240,  9728,  9744,  9745,  9742, 
+        0,  8192, 10240,  9728,     0,  8192, 10240,  9728, 
+     9744,     0,  8192, 10240,  9728,  9744,     0,  8192, 
+    10240,  9728,  9744,  9746,     0,  8192, 10240,  9728, 
+     9744,     0,  8192, 10240,  9728,  9744,  9748,     0, 
+     8192, 10240,  9728,  9744,  9748,     0,  8192, 10240, 
+     9728,  9744,  9752,  9750,     0,  8192, 10240,  9728, 
+     9744,     0,  8192, 10240,  9728,  9760,  9752,     0, 
+     8192, 10240,  9728,  9760,  9752,     0,  8192, 10240, 
+     9728,  9760,  9752,  9754,     0,  8192, 10240,  9728, 
+     9760,  9752,     0,  8192, 10240,  9728,  9760,  9761, 
+     9756,     0,  8192, 10240,  9728,  9760,  9761,  9756, 
+        0,  8192, 10240,  9728,  9760,  9761,  9756,  9758, 
+        0,  8192, 10240,  9728,     0,  8192, 10240,  9728, 
+     9760,     0,  8192, 10240,  9728,  9760,     0,  8192, 
+    10240,  9728,  9760,  9762,     0,  8192, 10240,  9728, 
+     9760,     0,  8192, 10240,  9728,  9760,  9764,     0, 
+     8192, 10240,  9728,  9760,  9764,     0,  8192, 10240, 
+     9728,  9760,  9768,  9766,     0,  8192, 10240,  9728, 
+     9760,     0,  8192, 10240,  9728,  9760,  9768,     0, 
+     8192, 10240,  9728,  9760,  9768,     0,  8192, 10240, 
+     9728,  9760,  9768,  9770,     0,  8192, 10240,  9728, 
+     9760,  9768,     0,  8192, 10240,  9728,  9760,  9776, 
+     9772,     0,  8192, 10240,  9728,  9760,  9776,  9772, 
+        0,  8192, 10240,  9728,  9760,  9776,  9777,  9774, 
+        0,  8192, 10240,  9728,  9760,     0,  8192, 10240, 
+     9728,  9792,  9776,     0,  8192, 10240,  9728,  9792, 
+     9776,     0,  8192, 10240,  9728,  9792,  9776,  9778, 
+        0,  8192, 10240,  9728,  9792,  9776,     0,  8192, 
+    10240,  9728,  9792,  9776,  9780,     0,  8192, 10240, 
+     9728,  9792,  9776,  9780,     0,  8192, 10240,  9728, 
+     9792,  9776,  9784,  9782,     0,  8192, 10240,  9728, 
+     9792,  9776,     0,  8192, 10240,  9728,  9792,  9793, 
+     9784,     0,  8192, 10240,  9728,  9792,  9793,  9784, 
+        0,  8192, 10240,  9728,  9792,  9793,  9784,  9786, 
+        0,  8192, 10240,  9728,  9792,  9793,  9784,     0, 
+     8192, 10240,  9728,  9792,  9793,  9784,  9788,     0, 
+     8192, 10240,  9728,  9792,  9793,  9795,  9788,     0, 
+     8192, 10240,  9728,  9792,  9793,  9795,  9788,  9790, 
+        0,  8192, 10240,  9728,     0,  8192, 10240,  9728, 
+     9792,     0,  8192, 10240,  9728,  9792,     0,  8192, 
+    10240,  9728,  9792,  9794,     0,  8192, 10240,  9728, 
+     9792,     0,  8192, 10240,  9728,  9792,  9796,     0, 
+     8192, 10240,  9728,  9792,  9796,     0,  8192, 10240, 
+     9728,  9792,  9800,  9798,     0,  8192, 10240,  9728, 
+     9792,     0,  8192, 10240,  9728,  9792,  9800,     0, 
+     8192, 10240,  9728,  9792,  9800,     0,  8192, 10240, 
+     9728,  9792,  9800,  9802,     0,  8192, 10240,  9728, 
+     9792,  9800,     0,  8192, 10240,  9728,  9792,  9808, 
+     9804,     0,  8192, 10240,  9728,  9792,  9808,  9804, 
+        0,  8192, 10240,  9728,  9792,  9808,  9809,  9806, 
+        0,  8192, 10240,  9728,  9792,     0,  8192, 10240, 
+     9728,  9792,  9808,     0,  8192, 10240,  9728,  9792, 
+     9808,     0,  8192, 10240,  9728,  9792,  9808,  9810, 
+        0,  8192, 10240,  9728,  9792,  9808,     0,  8192, 
+    10240,  9728,  9792,  9808,  9812,     0,  8192, 10240, 
+     9728,  9792,  9808,  9812,     0,  8192, 10240,  9728, 
+     9792,  9808,  9816,  9814,     0,  8192, 10240,  9728, 
+     9792,  9808,     0,  8192, 10240,  9728,  9792,  9824, 
+     9816,     0,  8192, 10240,  9728,  9792,  9824,  9816, 
+        0,  8192, 10240,  9728,  9792,  9824,  9816,  9818, 
+        0,  8192, 10240,  9728,  9792,  9824,  9816,     0, 
+     8192, 10240,  9728,  9792,  9824,  9825,  9820,     0, 
+     8192, 10240,  9728,  9792,  9824,  9825,  9820,     0, 
+     8192, 10240,  9728,  9792,  9824,  9825,  9820,  9822, 
+        0,  8192, 10240,  9728,  9792,     0,  8192, 10240, 
+     9728,  9856,  9824,     0,  8192, 10240,  9728,  9856, 
+     9824,     0,  8192, 10240,  9728,  9856,  9824,  9826, 
+        0,  8192, 10240,  9728,  9856,  9824,     0,  8192, 
+    10240,  9728,  9856,  9824,  9828,     0,  8192, 10240, 
+     9728,  9856,  9824,  9828,     0,  8192, 10240,  9728, 
+     9856,  9824,  9832,  9830,     0,  8192, 10240,  9728, 
+     9856,  9824,     0,  8192, 10240,  9728,  9856,  9824, 
+     9832,     0,  8192, 10240,  9728,  9856,  9824,  9832, 
+        0,  8192, 10240,  9728,  9856,  9824,  9832,  9834, 
+        0,  8192, 10240,  9728,  9856,  9824,  9832,     0, 
+     8192, 10240,  9728,  9856,  9824,  9840,  9836,     0, 
+     8192, 10240,  9728,  9856,  9824,  9840,  9836,     0, 
+     8192, 10240,  9728,  9856,  9824,  9840,  9841,  9838, 
+        0,  8192, 10240,  9728,  9856,  9824,     0,  8192, 
+    10240,  9728,  9856,  9857,  9840,     0,  8192, 10240, 
+     9728,  9856,  9857,  9840,     0,  8192, 10240,  9728, 
+     9856,  9857,  9840,  9842,     0,  8192, 10240,  9728, 
+     9856,  9857,  9840,     0,  8192, 10240,  9728,  9856, 
+     9857,  9840,  9844,     0,  8192, 10240,  9728,  9856, 
+     9857,  9840,  9844,     0,  8192, 10240,  9728,  9856, 
+     9857,  9840,  9848,  9846,     0,  8192, 10240,  9728, 
+     9856,  9857,  9840,     0,  8192, 10240,  9728,  9856, 
+     9857,  9840,  9848,     0,  8192, 10240,  9728,  9856, 
+     9857,  9859,  9848,     0,  8192, 10240,  9728,  9856, 
+     9857,  9859,  9848,  9850,     0,  8192, 10240,  9728, 
+     9856,  9857,  9859,  9848,     0,  8192, 10240,  9728, 
+     9856,  9857,  9859,  9848,  9852,     0,  8192, 10240, 
+     9728,  9856,  9857,  9859,  9848,  9852,     0,  8192, 
+    10240,  9728,  9856,  9857,  9859,  9848,  9852,  9854, 
+        0,  8192, 10240,  9728,     0,  8192, 10240,  9728, 
+     9856,     0,  8192, 10240,  9728,  9856,     0,  8192, 
+    10240,  9728,  9856,  9858,     0,  8192, 10240,  9728, 
+     9856,     0,  8192, 10240,  9728,  9856,  9860,     0, 
+     8192, 10240,  9728,  9856,  9860,     0,  8192, 10240, 
+     9728,  9856,  9864,  9862,     0,  8192, 10240,  9728, 
+     9856,     0,  8192, 10240,  9728,  9856,  9864,     0, 
+     8192, 10240,  9728,  9856,  9864,     0,  8192, 10240, 
+     9728,  9856,  9864,  9866,     0,  8192, 10240,  9728, 
+     9856,  9864,     0,  8192, 10240,  9728,  9856,  9872, 
+     9868,     0,  8192, 10240,  9728,  9856,  9872,  9868, 
+        0,  8192, 10240,  9728,  9856,  9872,  9873,  9870, 
+        0,  8192, 10240,  9728,  9856,     0,  8192, 10240, 
+     9728,  9856,  9872,     0,  8192, 10240,  9728,  9856, 
+     9872,     0,  8192, 10240,  9728,  9856,  9872,  9874, 
+        0,  8192, 10240,  9728,  9856,  9872,     0,  8192, 
+    10240,  9728,  9856,  9872,  9876,     0,  8192, 10240, 
+     9728,  9856,  9872,  9876,     0,  8192, 10240,  9728, 
+     9856,  9872,  9880,  9878,     0,  8192, 10240,  9728, 
+     9856,  9872,     0,  8192, 10240,  9728,  9856,  9888, 
+     9880,     0,  8192, 10240,  9728,  9856,  9888,  9880, 
+        0,  8192, 10240,  9728,  9856,  9888,  9880,  9882, 
+        0,  8192, 10240,  9728,  9856,  9888,  9880,     0, 
+     8192, 10240,  9728,  9856,  9888,  9889,  9884,     0, 
+     8192, 10240,  9728,  9856,  9888,  9889,  9884,     0, 
+     8192, 10240,  9728,  9856,  9888,  9889,  9884,  9886, 
+        0,  8192, 10240,  9728,  9856,     0,  8192, 10240, 
+     9728,  9856,  9888,     0,  8192, 10240,  9728,  9856, 
+     9888,     0,  8192, 10240,  9728,  9856,  9888,  9890, 
+        0,  8192, 10240,  9728,  9856,  9888,     0,  8192, 
+    10240,  9728,  9856,  9888,  9892,     0,  8192, 10240, 
+     9728,  9856,  9888,  9892,     0,  8192, 10240,  9728, 
+     9856,  9888,  9896,  9894,     0,  8192, 10240,  9728, 
+     9856,  9888,     0,  8192, 10240,  9728,  9856,  9888, 
+     9896,     0,  8192, 10240,  9728,  9856,  9888,  9896, 
+        0,  8192, 10240,  9728,  9856,  9888,  9896,  9898, 
+        0,  8192, 10240,  9728,  9856,  9888,  9896,     0, 
+     8192, 10240,  9728,  9856,  9888,  9904,  9900,     0, 
+     8192, 10240,  9728,  9856,  9888,  9904,  9900,     0, 
+     8192, 10240,  9728,  9856,  9888,  9904,  9905,  9902, 
+        0,  8192, 10240,  9728,  9856,  9888,     0,  8192, 
+    10240,  9728,  9856,  9920,  9904,     0,  8192, 10240, 
+     9728,  9856,  9920,  9904,     0,  8192, 10240,  9728, 
+     9856,  9920,  9904,  9906,     0,  8192, 10240,  9728, 
+     9856,  9920,  9904,     0,  8192, 10240,  9728,  9856, 
+     9920,  9904,  9908,     0,  8192, 10240,  9728,  9856, 
+     9920,  9904,  9908,     0,  8192, 10240,  9728,  9856, 
+     9920,  9904,  9912,  9910,     0,  8192, 10240,  9728, 
+     9856,  9920,  9904,     0,  8192, 10240,  9728,  9856, 
+     9920,  9921,  9912,     0,  8192, 10240,  9728,  9856, 
+     9920,  9921,  9912,     0,  8192, 10240,  9728,  9856, 
+     9920,  9921,  9912,  9914,     0,  8192, 10240,  9728, 
+     9856,  9920,  9921,  9912,     0,  8192, 10240,  9728, 
+     9856,  9920,  9921,  9912,  9916,     0,  8192, 10240, 
+     9728,  9856,  9920,  9921,  9923,  9916,     0,  8192, 
+    10240,  9728,  9856,  9920,  9921,  9923,  9916,  9918, 
+        0,  8192, 10240,  9728,  9856,     0,  8192, 10240, 
+     9728,  9984,  9920,     0,  8192, 10240,  9728,  9984, 
+     9920,     0,  8192, 10240,  9728,  9984,  9920,  9922, 
+        0,  8192, 10240,  9728,  9984,  9920,     0,  8192, 
+    10240,  9728,  9984,  9920,  9924,     0,  8192, 10240, 
+     9728,  9984,  9920,  9924,     0,  8192, 10240,  9728, 
+     9984,  9920,  9928,  9926,     0,  8192, 10240,  9728, 
+     9984,  9920,     0,  8192, 10240,  9728,  9984,  9920, 
+     9928,     0,  8192, 10240,  9728,  9984,  9920,  9928, 
+        0,  8192, 10240,  9728,  9984,  9920,  9928,  9930, 
+        0,  8192, 10240,  9728,  9984,  9920,  9928,     0, 
+     8192, 10240,  9728,  9984,  9920,  9936,  9932,     0, 
+     8192, 10240,  9728,  9984,  9920,  9936,  9932,     0, 
+     8192, 10240,  9728,  9984,  9920,  9936,  9937,  9934, 
+        0,  8192, 10240,  9728,  9984,  9920,     0,  8192, 
+    10240,  9728,  9984,  9920,  9936,     0,  8192, 10240, 
+     9728,  9984,  9920,  9936,     0,  8192, 10240,  9728, 
+     9984,  9920,  9936,  9938,     0,  8192, 10240,  9728, 
+     9984,  9920,  9936,     0,  8192, 10240,  9728,  9984, 
+     9920,  9936,  9940,     0,  8192, 10240,  9728,  9984, 
+     9920,  9936,  9940,     0,  8192, 10240,  9728,  9984, 
+     9920,  9936,  9944,  9942,     0,  8192, 10240,  9728, 
+     9984,  9920,  9936,     0,  8192, 10240,  9728,  9984, 
+     9920,  9952,  9944,     0,  8192, 10240,  9728,  9984, 
+     9920,  9952,  9944,     0,  8192, 10240,  9728,  9984, 
+     9920,  9952,  9944,  9946,     0,  8192, 10240,  9728, 
+     9984,  9920,  9952,  9944,     0,  8192, 10240,  9728, 
+     9984,  9920,  9952,  9953,  9948,     0,  8192, 10240, 
+     9728,  9984,  9920,  9952,  9953,  9948,     0,  8192, 
+    10240,  9728,  9984,  9920,  9952,  9953,  9948,  9950, 
+        0,  8192, 10240,  9728,  9984,  9920,     0,  8192, 
+    10240,  9728,  9984,  9985,  9952,     0,  8192, 10240, 
+     9728,  9984,  9985,  9952,     0,  8192, 10240,  9728, 
+     9984,  9985,  9952,  9954,     0,  8192, 10240,  9728, 
+     9984,  9985,  9952,     0,  8192, 10240,  9728,  9984, 
+     9985,  9952,  9956,     0,  8192, 10240,  9728,  9984, 
+     9985,  9952,  9956,     0,  8192, 10240,  9728,  9984, 
+     9985,  9952,  9960,  9958,     0,  8192, 10240,  9728, 
+     9984,  9985,  9952,     0,  8192, 10240,  9728,  9984, 
+     9985,  9952,  9960,     0,  8192, 10240,  9728,  9984, 
+     9985,  9952,  9960,     0,  8192, 10240,  9728,  9984, 
+     9985,  9952,  9960,  9962,     0,  8192, 10240,  9728, 
+     9984,  9985,  9952,  9960,     0,  8192, 10240,  9728, 
+     9984,  9985,  9952,  9968,  9964,     0,  8192, 10240, 
+     9728,  9984,  9985,  9952,  9968,  9964,     0,  8192, 
+    10240,  9728,  9984,  9985,  9952,  9968,  9969,  9966, 
+        0,  8192, 10240,  9728,  9984,  9985,  9952,     0, 
+     8192, 10240,  9728,  9984,  9985,  9952,  9968,     0, 
+     8192, 10240,  9728,  9984,  9985,  9987,  9968,     0, 
+     8192, 10240,  9728,  9984,  9985,  9987,  9968,  9970, 
+        0,  8192, 10240,  9728,  9984,  9985,  9987,  9968, 
+        0,  8192, 10240,  9728,  9984,  9985,  9987,  9968, 
+     9972,     0,  8192, 10240,  9728,  9984,  9985,  9987, 
+     9968,  9972,     0,  8192, 10240,  9728,  9984,  9985, 
+     9987,  9968,  9976,  9974,     0,  8192, 10240,  9728, 
+     9984,  9985,  9987,  9968,     0,  8192, 10240,  9728, 
+     9984,  9985,  9987,  9968,  9976,     0,  8192, 10240, 
+     9728,  9984,  9985,  9987,  9968,  9976,     0,  8192, 
+    10240,  9728,  9984,  9985,  9987,  9968,  9976,  9978, 
+        0,  8192, 10240,  9728,  9984,  9985,  9987,  9991, 
+     9976,     0,  8192, 10240,  9728,  9984,  9985,  9987, 
+     9991,  9976,  9980,     0,  8192, 10240,  9728,  9984, 
+     9985,  9987,  9991,  9976,  9980,     0,  8192, 10240, 
+     9728,  9984,  9985,  9987,  9991,  9976,  9980,  9982, 
+        0,  8192, 10240,  9728,     0,  8192, 10240,  9728, 
+     9984,     0,  8192, 10240, 10241,  9984,     0,  8192, 
+    10240, 10241,  9984,  9986,     0,  8192, 10240, 10241, 
+     9984,     0,  8192, 10240, 10241,  9984,  9988,     0, 
+     8192, 10240, 10241,  9984,  9988,     0,  8192, 10240, 
+    10241,  9984,  9992,  9990,     0,  8192, 10240, 10241, 
+     9984,     0,  8192, 10240, 10241,  9984,  9992,     0, 
+     8192, 10240, 10241,  9984,  9992,     0,  8192, 10240, 
+    10241,  9984,  9992,  9994,     0,  8192, 10240, 10241, 
+     9984,  9992,     0,  8192, 10240, 10241,  9984, 10000, 
+     9996,     0,  8192, 10240, 10241,  9984, 10000,  9996, 
+        0,  8192, 10240, 10241,  9984, 10000, 10001,  9998, 
+        0,  8192, 10240, 10241,  9984,     0,  8192, 10240, 
+    10241,  9984, 10000,     0,  8192, 10240, 10241,  9984, 
+    10000,     0,  8192, 10240, 10241,  9984, 10000, 10002, 
+        0,  8192, 10240, 10241,  9984, 10000,     0,  8192, 
+    10240, 10241,  9984, 10000, 10004,     0,  8192, 10240, 
+    10241,  9984, 10000, 10004,     0,  8192, 10240, 10241, 
+     9984, 10000, 10008, 10006,     0,  8192, 10240, 10241, 
+     9984, 10000,     0,  8192, 10240, 10241,  9984, 10016, 
+    10008,     0,  8192, 10240, 10241,  9984, 10016, 10008, 
+        0,  8192, 10240, 10241,  9984, 10016, 10008, 10010, 
+        0,  8192, 10240, 10241,  9984, 10016, 10008,     0, 
+     8192, 10240, 10241,  9984, 10016, 10017, 10012,     0, 
+     8192, 10240, 10241,  9984, 10016, 10017, 10012,     0, 
+     8192, 10240, 10241,  9984, 10016, 10017, 10012, 10014, 
+        0,  8192, 10240, 10241,  9984,     0,  8192, 10240, 
+    10241,  9984, 10016,     0,  8192, 10240, 10241,  9984, 
+    10016,     0,  8192, 10240, 10241,  9984, 10016, 10018, 
+        0,  8192, 10240, 10241,  9984, 10016,     0,  8192, 
+    10240, 10241,  9984, 10016, 10020,     0,  8192, 10240, 
+    10241,  9984, 10016, 10020,     0,  8192, 10240, 10241, 
+     9984, 10016, 10024, 10022,     0,  8192, 10240, 10241, 
+     9984, 10016,     0,  8192, 10240, 10241,  9984, 10016, 
+    10024,     0,  8192, 10240, 10241,  9984, 10016, 10024, 
+        0,  8192, 10240, 10241,  9984, 10016, 10024, 10026, 
+        0,  8192, 10240, 10241,  9984, 10016, 10024,     0, 
+     8192, 10240, 10241,  9984, 10016, 10032, 10028,     0, 
+     8192, 10240, 10241,  9984, 10016, 10032, 10028,     0, 
+     8192, 10240, 10241,  9984, 10016, 10032, 10033, 10030, 
+        0,  8192, 10240, 10241,  9984, 10016,     0,  8192, 
+    10240, 10241,  9984, 10048, 10032,     0,  8192, 10240, 
+    10241,  9984, 10048, 10032,     0,  8192, 10240, 10241, 
+     9984, 10048, 10032, 10034,     0,  8192, 10240, 10241, 
+     9984, 10048, 10032,     0,  8192, 10240, 10241,  9984, 
+    10048, 10032, 10036,     0,  8192, 10240, 10241,  9984, 
+    10048, 10032, 10036,     0,  8192, 10240, 10241,  9984, 
+    10048, 10032, 10040, 10038,     0,  8192, 10240, 10241, 
+     9984, 10048, 10032,     0,  8192, 10240, 10241,  9984, 
+    10048, 10049, 10040,     0,  8192, 10240, 10241,  9984, 
+    10048, 10049, 10040,     0,  8192, 10240, 10241,  9984, 
+    10048, 10049, 10040, 10042,     0,  8192, 10240, 10241, 
+     9984, 10048, 10049, 10040,     0,  8192, 10240, 10241, 
+     9984, 10048, 10049, 10040, 10044,     0,  8192, 10240, 
+    10241,  9984, 10048, 10049, 10051, 10044,     0,  8192, 
+    10240, 10241,  9984, 10048, 10049, 10051, 10044, 10046, 
+        0,  8192, 10240, 10241,  9984,     0,  8192, 10240, 
+    10241,  9984, 10048,     0,  8192, 10240, 10241,  9984, 
+    10048,     0,  8192, 10240, 10241,  9984, 10048, 10050, 
+        0,  8192, 10240, 10241,  9984, 10048,     0,  8192, 
+    10240, 10241,  9984, 10048, 10052,     0,  8192, 10240, 
+    10241,  9984, 10048, 10052,     0,  8192, 10240, 10241, 
+     9984, 10048, 10056, 10054,     0,  8192, 10240, 10241, 
+     9984, 10048,     0,  8192, 10240, 10241,  9984, 10048, 
+    10056,     0,  8192, 10240, 10241,  9984, 10048, 10056, 
+        0,  8192, 10240, 10241,  9984, 10048, 10056, 10058, 
+        0,  8192, 10240, 10241,  9984, 10048, 10056,     0, 
+     8192, 10240, 10241,  9984, 10048, 10064, 10060,     0, 
+     8192, 10240, 10241,  9984, 10048, 10064, 10060,     0, 
+     8192, 10240, 10241,  9984, 10048, 10064, 10065, 10062, 
+        0,  8192, 10240, 10241,  9984, 10048,     0,  8192, 
+    10240, 10241,  9984, 10048, 10064,     0,  8192, 10240, 
+    10241,  9984, 10048, 10064,     0,  8192, 10240, 10241, 
+     9984, 10048, 10064, 10066,     0,  8192, 10240, 10241, 
+     9984, 10048, 10064,     0,  8192, 10240, 10241,  9984, 
+    10048, 10064, 10068,     0,  8192, 10240, 10241,  9984, 
+    10048, 10064, 10068,     0,  8192, 10240, 10241,  9984, 
+    10048, 10064, 10072, 10070,     0,  8192, 10240, 10241, 
+     9984, 10048, 10064,     0,  8192, 10240, 10241,  9984, 
+    10048, 10080, 10072,     0,  8192, 10240, 10241,  9984, 
+    10048, 10080, 10072,     0,  8192, 10240, 10241,  9984, 
+    10048, 10080, 10072, 10074,     0,  8192, 10240, 10241, 
+     9984, 10048, 10080, 10072,     0,  8192, 10240, 10241, 
+     9984, 10048, 10080, 10081, 10076,     0,  8192, 10240, 
+    10241,  9984, 10048, 10080, 10081, 10076,     0,  8192, 
+    10240, 10241,  9984, 10048, 10080, 10081, 10076, 10078, 
+        0,  8192, 10240, 10241,  9984, 10048,     0,  8192, 
+    10240, 10241,  9984, 10112, 10080,     0,  8192, 10240, 
+    10241,  9984, 10112, 10080,     0,  8192, 10240, 10241, 
+     9984, 10112, 10080, 10082,     0,  8192, 10240, 10241, 
+     9984, 10112, 10080,     0,  8192, 10240, 10241,  9984, 
+    10112, 10080, 10084,     0,  8192, 10240, 10241,  9984, 
+    10112, 10080, 10084,     0,  8192, 10240, 10241,  9984, 
+    10112, 10080, 10088, 10086,     0,  8192, 10240, 10241, 
+     9984, 10112, 10080,     0,  8192, 10240, 10241,  9984, 
+    10112, 10080, 10088,     0,  8192, 10240, 10241,  9984, 
+    10112, 10080, 10088,     0,  8192, 10240, 10241,  9984, 
+    10112, 10080, 10088, 10090,     0,  8192, 10240, 10241, 
+     9984, 10112, 10080, 10088,     0,  8192, 10240, 10241, 
+     9984, 10112, 10080, 10096, 10092,     0,  8192, 10240, 
+    10241,  9984, 10112, 10080, 10096, 10092,     0,  8192, 
+    10240, 10241,  9984, 10112, 10080, 10096, 10097, 10094, 
+        0,  8192, 10240, 10241,  9984, 10112, 10080,     0, 
+     8192, 10240, 10241,  9984, 10112, 10113, 10096,     0, 
+     8192, 10240, 10241,  9984, 10112, 10113, 10096,     0, 
+     8192, 10240, 10241,  9984, 10112, 10113, 10096, 10098, 
+        0,  8192, 10240, 10241,  9984, 10112, 10113, 10096, 
+        0,  8192, 10240, 10241,  9984, 10112, 10113, 10096, 
+    10100,     0,  8192, 10240, 10241,  9984, 10112, 10113, 
+    10096, 10100,     0,  8192, 10240, 10241,  9984, 10112, 
+    10113, 10096, 10104, 10102,     0,  8192, 10240, 10241, 
+     9984, 10112, 10113, 10096,     0,  8192, 10240, 10241, 
+     9984, 10112, 10113, 10096, 10104,     0,  8192, 10240, 
+    10241,  9984, 10112, 10113, 10115, 10104,     0,  8192, 
+    10240, 10241,  9984, 10112, 10113, 10115, 10104, 10106, 
+        0,  8192, 10240, 10241,  9984, 10112, 10113, 10115, 
+    10104,     0,  8192, 10240, 10241,  9984, 10112, 10113, 
+    10115, 10104, 10108,     0,  8192, 10240, 10241,  9984, 
+    10112, 10113, 10115, 10104, 10108,     0,  8192, 10240, 
+    10241,  9984, 10112, 10113, 10115, 10104, 10108, 10110, 
+        0,  8192, 10240, 10241,  9984,     0,  8192, 10240, 
+    10241,  9984, 10112,     0,  8192, 10240, 10241,  9984, 
+    10112,     0,  8192, 10240, 10241,  9984, 10112, 10114, 
+        0,  8192, 10240, 10241, 10243, 10112,     0,  8192, 
+    10240, 10241, 10243, 10112, 10116,     0,  8192, 10240, 
+    10241, 10243, 10112, 10116,     0,  8192, 10240, 10241, 
+    10243, 10112, 10120, 10118,     0,  8192, 10240, 10241, 
+    10243, 10112,     0,  8192, 10240, 10241, 10243, 10112, 
+    10120,     0,  8192, 10240, 10241, 10243, 10112, 10120, 
+        0,  8192, 10240, 10241, 10243, 10112, 10120, 10122, 
+        0,  8192, 10240, 10241, 10243, 10112, 10120,     0, 
+     8192, 10240, 10241, 10243, 10112, 10128, 10124,     0, 
+     8192, 10240, 10241, 10243, 10112, 10128, 10124,     0, 
+     8192, 10240, 10241, 10243, 10112, 10128, 10129, 10126, 
+        0,  8192, 10240, 10241, 10243, 10112,     0,  8192, 
+    10240, 10241, 10243, 10112, 10128,     0,  8192, 10240, 
+    10241, 10243, 10112, 10128,     0,  8192, 10240, 10241, 
+    10243, 10112, 10128, 10130,     0,  8192, 10240, 10241, 
+    10243, 10112, 10128,     0,  8192, 10240, 10241, 10243, 
+    10112, 10128, 10132,     0,  8192, 10240, 10241, 10243, 
+    10112, 10128, 10132,     0,  8192, 10240, 10241, 10243, 
+    10112, 10128, 10136, 10134,     0,  8192, 10240, 10241, 
+    10243, 10112, 10128,     0,  8192, 10240, 10241, 10243, 
+    10112, 10144, 10136,     0,  8192, 10240, 10241, 10243, 
+    10112, 10144, 10136,     0,  8192, 10240, 10241, 10243, 
+    10112, 10144, 10136, 10138,     0,  8192, 10240, 10241, 
+    10243, 10112, 10144, 10136,     0,  8192, 10240, 10241, 
+    10243, 10112, 10144, 10145, 10140,     0,  8192, 10240, 
+    10241, 10243, 10112, 10144, 10145, 10140,     0,  8192, 
+    10240, 10241, 10243, 10112, 10144, 10145, 10140, 10142, 
+        0,  8192, 10240, 10241, 10243, 10112,     0,  8192, 
+    10240, 10241, 10243, 10112, 10144,     0,  8192, 10240, 
+    10241, 10243, 10112, 10144,     0,  8192, 10240, 10241, 
+    10243, 10112, 10144, 10146,     0,  8192, 10240, 10241, 
+    10243, 10112, 10144,     0,  8192, 10240, 10241, 10243, 
+    10112, 10144, 10148,     0,  8192, 10240, 10241, 10243, 
+    10112, 10144, 10148,     0,  8192, 10240, 10241, 10243, 
+    10112, 10144, 10152, 10150,     0,  8192, 10240, 10241, 
+    10243, 10112, 10144,     0,  8192, 10240, 10241, 10243, 
+    10112, 10144, 10152,     0,  8192, 10240, 10241, 10243, 
+    10112, 10144, 10152,     0,  8192, 10240, 10241, 10243, 
+    10112, 10144, 10152, 10154,     0,  8192, 10240, 10241, 
+    10243, 10112, 10144, 10152,     0,  8192, 10240, 10241, 
+    10243, 10112, 10144, 10160, 10156,     0,  8192, 10240, 
+    10241, 10243, 10112, 10144, 10160, 10156,     0,  8192, 
+    10240, 10241, 10243, 10112, 10144, 10160, 10161, 10158, 
+        0,  8192, 10240, 10241, 10243, 10112, 10144,     0, 
+     8192, 10240, 10241, 10243, 10112, 10176, 10160,     0, 
+     8192, 10240, 10241, 10243, 10112, 10176, 10160,     0, 
+     8192, 10240, 10241, 10243, 10112, 10176, 10160, 10162, 
+        0,  8192, 10240, 10241, 10243, 10112, 10176, 10160, 
+        0,  8192, 10240, 10241, 10243, 10112, 10176, 10160, 
+    10164,     0,  8192, 10240, 10241, 10243, 10112, 10176, 
+    10160, 10164,     0,  8192, 10240, 10241, 10243, 10112, 
+    10176, 10160, 10168, 10166,     0,  8192, 10240, 10241, 
+    10243, 10112, 10176, 10160,     0,  8192, 10240, 10241, 
+    10243, 10112, 10176, 10177, 10168,     0,  8192, 10240, 
+    10241, 10243, 10112, 10176, 10177, 10168,     0,  8192, 
+    10240, 10241, 10243, 10112, 10176, 10177, 10168, 10170, 
+        0,  8192, 10240, 10241, 10243, 10112, 10176, 10177, 
+    10168,     0,  8192, 10240, 10241, 10243, 10112, 10176, 
+    10177, 10168, 10172,     0,  8192, 10240, 10241, 10243, 
+    10112, 10176, 10177, 10179, 10172,     0,  8192, 10240, 
+    10241, 10243, 10112, 10176, 10177, 10179, 10172, 10174, 
+        0,  8192, 10240, 10241, 10243, 10112,     0,  8192, 
+    10240, 10241, 10243, 10112, 10176,     0,  8192, 10240, 
+    10241, 10243, 10112, 10176,     0,  8192, 10240, 10241, 
+    10243, 10112, 10176, 10178,     0,  8192, 10240, 10241, 
+    10243, 10112, 10176,     0,  8192, 10240, 10241, 10243, 
+    10112, 10176, 10180,     0,  8192, 10240, 10241, 10243, 
+    10112, 10176, 10180,     0,  8192, 10240, 10241, 10243, 
+    10112, 10176, 10184, 10182,     0,  8192, 10240, 10241, 
+    10243, 10247, 10176,     0,  8192, 10240, 10241, 10243, 
+    10247, 10176, 10184,     0,  8192, 10240, 10241, 10243, 
+    10247, 10176, 10184,     0,  8192, 10240, 10241, 10243, 
+    10247, 10176, 10184, 10186,     0,  8192, 10240, 10241, 
+    10243, 10247, 10176, 10184,     0,  8192, 10240, 10241, 
+    10243, 10247, 10176, 10192, 10188,     0,  8192, 10240, 
+    10241, 10243, 10247, 10176, 10192, 10188,     0,  8192, 
+    10240, 10241, 10243, 10247, 10176, 10192, 10193, 10190, 
+        0,  8192, 10240, 10241, 10243, 10247, 10176,     0, 
+     8192, 10240, 10241, 10243, 10247, 10176, 10192,     0, 
+     8192, 10240, 10241, 10243, 10247, 10176, 10192,     0, 
+     8192, 10240, 10241, 10243, 10247, 10176, 10192, 10194, 
+        0,  8192, 10240, 10241, 10243, 10247, 10176, 10192, 
+        0,  8192, 10240, 10241, 10243, 10247, 10176, 10192, 
+    10196,     0,  8192, 10240, 10241, 10243, 10247, 10176, 
+    10192, 10196,     0,  8192, 10240, 10241, 10243, 10247, 
+    10176, 10192, 10200, 10198,     0,  8192, 10240, 10241, 
+    10243, 10247, 10176, 10192,     0,  8192, 10240, 10241, 
+    10243, 10247, 10176, 10208, 10200,     0,  8192, 10240, 
+    10241, 10243, 10247, 10176, 10208, 10200,     0,  8192, 
+    10240, 10241, 10243, 10247, 10176, 10208, 10200, 10202, 
+        0,  8192, 10240, 10241, 10243, 10247, 10176, 10208, 
+    10200,     0,  8192, 10240, 10241, 10243, 10247, 10176, 
+    10208, 10209, 10204,     0,  8192, 10240, 10241, 10243, 
+    10247, 10176, 10208, 10209, 10204,     0,  8192, 10240, 
+    10241, 10243, 10247, 10176, 10208, 10209, 10204, 10206, 
+        0,  8192, 10240, 10241, 10243, 10247, 10176,     0, 
+     8192, 10240, 10241, 10243, 10247, 10176, 10208,     0, 
+     8192, 10240, 10241, 10243, 10247, 10176, 10208,     0, 
+     8192, 10240, 10241, 10243, 10247, 10176, 10208, 10210, 
+        0,  8192, 10240, 10241, 10243, 10247, 10176, 10208, 
+        0,  8192, 10240, 10241, 10243, 10247, 10176, 10208, 
+    10212,     0,  8192, 10240, 10241, 10243, 10247, 10176, 
+    10208, 10212,     0,  8192, 10240, 10241, 10243, 10247, 
+    10176, 10208, 10216, 10214,     0,  8192, 10240, 10241, 
+    10243, 10247, 10176, 10208,     0,  8192, 10240, 10241, 
+    10243, 10247, 10176, 10208, 10216,     0,  8192, 10240, 
+    10241, 10243, 10247, 10176, 10208, 10216,     0,  8192, 
+    10240, 10241, 10243, 10247, 10176, 10208, 10216, 10218, 
+        0,  8192, 10240, 10241, 10243, 10247, 10176, 10208, 
+    10216,     0,  8192, 10240, 10241, 10243, 10247, 10176, 
+    10208, 10224, 10220,     0,  8192, 10240, 10241, 10243, 
+    10247, 10176, 10208, 10224, 10220,     0,  8192, 10240, 
+    10241, 10243, 10247, 10176, 10208, 10224, 10225, 10222, 
+        0,  8192, 10240, 10241, 10243, 10247, 10255, 10208, 
+        0,  8192, 10240, 10241, 10243, 10247, 10255, 10208, 
+    10224,     0,  8192, 10240, 10241, 10243, 10247, 10255, 
+    10208, 10224,     0,  8192, 10240, 10241, 10243, 10247, 
+    10255, 10208, 10224, 10226,     0,  8192, 10240, 10241, 
+    10243, 10247, 10255, 10208, 10224,     0,  8192, 10240, 
+    10241, 10243, 10247, 10255, 10208, 10224, 10228,     0, 
+     8192, 10240, 10241, 10243, 10247, 10255, 10208, 10224, 
+    10228,     0,  8192, 10240, 10241, 10243, 10247, 10255, 
+    10208, 10224, 10232, 10230,     0,  8192, 10240, 10241, 
+    10243, 10247, 10255, 10208, 10224,     0,  8192, 10240, 
+    10241, 10243, 10247, 10255, 10208, 10224, 10232,     0, 
+     8192, 10240, 10241, 10243, 10247, 10255, 10208, 10224, 
+    10232,     0,  8192, 10240, 10241, 10243, 10247, 10255, 
+    10208, 10224, 10232, 10234,     0,  8192, 10240, 10241, 
+    10243, 10247, 10255, 10208, 10224, 10232,     0,  8192, 
+    10240, 10241, 10243, 10247, 10255, 10208, 10224, 10232, 
+    10236,     0,  8192, 10240, 10241, 10243, 10247, 10255, 
+    10208, 10224, 10232, 10236,     0,  8192, 10240, 10241, 
+    10243, 10247, 10255, 10208, 10224, 10232, 10236, 10238, 
+        0,  8192,     0,  8192, 10240,     0,  8192, 10240, 
+        0,  8192, 10240, 10242,     0,  8192, 10240,     0, 
+     8192, 10240, 10244,     0,  8192, 10240, 10244,     0, 
+     8192, 10240, 10248, 10246,     0,  8192, 10240,     0, 
+     8192, 10240, 10248,     0,  8192, 10240, 10248,     0, 
+     8192, 10240, 10248, 10250,     0,  8192, 10240, 10248, 
+        0,  8192, 10240, 10256, 10252,     0,  8192, 10240, 
+    10256, 10252,     0,  8192, 10240, 10256, 10257, 10254, 
+        0,  8192, 10240,     0,  8192, 10240, 10256,     0, 
+     8192, 10240, 10256,     0,  8192, 10240, 10256, 10258, 
+        0,  8192, 10240, 10256,     0,  8192, 10240, 10256, 
+    10260,     0,  8192, 10240, 10256, 10260,     0,  8192, 
+    10240, 10256, 10264, 10262,     0,  8192, 10240, 10256, 
+        0,  8192, 10240, 10272, 10264,     0,  8192, 10240, 
+    10272, 10264,     0,  8192, 10240, 10272, 10264, 10266, 
+        0,  8192, 10240, 10272, 10264,     0,  8192, 10240, 
+    10272, 10273, 10268,     0,  8192, 10240, 10272, 10273, 
+    10268,     0,  8192, 10240, 10272, 10273, 10268, 10270, 
+        0,  8192, 10240,     0,  8192, 10240, 10272,     0, 
+     8192, 10240, 10272,     0,  8192, 10240, 10272, 10274, 
+        0,  8192, 10240, 10272,     0,  8192, 10240, 10272, 
+    10276,     0,  8192, 10240, 10272, 10276,     0,  8192, 
+    10240, 10272, 10280, 10278,     0,  8192, 10240, 10272, 
+        0,  8192, 10240, 10272, 10280,     0,  8192, 10240, 
+    10272, 10280,     0,  8192, 10240, 10272, 10280, 10282, 
+        0,  8192, 10240, 10272, 10280,     0,  8192, 10240, 
+    10272, 10288, 10284,     0,  8192, 10240, 10272, 10288, 
+    10284,     0,  8192, 10240, 10272, 10288, 10289, 10286, 
+        0,  8192, 10240, 10272,     0,  8192, 10240, 10304, 
+    10288,     0,  8192, 10240, 10304, 10288,     0,  8192, 
+    10240, 10304, 10288, 10290,     0,  8192, 10240, 10304, 
+    10288,     0,  8192, 10240, 10304, 10288, 10292,     0, 
+     8192, 10240, 10304, 10288, 10292,     0,  8192, 10240, 
+    10304, 10288, 10296, 10294,     0,  8192, 10240, 10304, 
+    10288,     0,  8192, 10240, 10304, 10305, 10296,     0, 
+     8192, 10240, 10304, 10305, 10296,     0,  8192, 10240, 
+    10304, 10305, 10296, 10298,     0,  8192, 10240, 10304, 
+    10305, 10296,     0,  8192, 10240, 10304, 10305, 10296, 
+    10300,     0,  8192, 10240, 10304, 10305, 10307, 10300, 
+        0,  8192, 10240, 10304, 10305, 10307, 10300, 10302, 
+        0,  8192, 10240,     0,  8192, 10240, 10304,     0, 
+     8192, 10240, 10304,     0,  8192, 10240, 10304, 10306, 
+        0,  8192, 10240, 10304,     0,  8192, 10240, 10304, 
+    10308,     0,  8192, 10240, 10304, 10308,     0,  8192, 
+    10240, 10304, 10312, 10310,     0,  8192, 10240, 10304, 
+        0,  8192, 10240, 10304, 10312,     0,  8192, 10240, 
+    10304, 10312,     0,  8192, 10240, 10304, 10312, 10314, 
+        0,  8192, 10240, 10304, 10312,     0,  8192, 10240, 
+    10304, 10320, 10316,     0,  8192, 10240, 10304, 10320, 
+    10316,     0,  8192, 10240, 10304, 10320, 10321, 10318, 
+        0,  8192, 10240, 10304,     0,  8192, 10240, 10304, 
+    10320,     0,  8192, 10240, 10304, 10320,     0,  8192, 
+    10240, 10304, 10320, 10322,     0,  8192, 10240, 10304, 
+    10320,     0,  8192, 10240, 10304, 10320, 10324,     0, 
+     8192, 10240, 10304, 10320, 10324,     0,  8192, 10240, 
+    10304, 10320, 10328, 10326,     0,  8192, 10240, 10304, 
+    10320,     0,  8192, 10240, 10304, 10336, 10328,     0, 
+     8192, 10240, 10304, 10336, 10328,     0,  8192, 10240, 
+    10304, 10336, 10328, 10330,     0,  8192, 10240, 10304, 
+    10336, 10328,     0,  8192, 10240, 10304, 10336, 10337, 
+    10332,     0,  8192, 10240, 10304, 10336, 10337, 10332, 
+        0,  8192, 10240, 10304, 10336, 10337, 10332, 10334, 
+        0,  8192, 10240, 10304,     0,  8192, 10240, 10368, 
+    10336,     0,  8192, 10240, 10368, 10336,     0,  8192, 
+    10240, 10368, 10336, 10338,     0,  8192, 10240, 10368, 
+    10336,     0,  8192, 10240, 10368, 10336, 10340,     0, 
+     8192, 10240, 10368, 10336, 10340,     0,  8192, 10240, 
+    10368, 10336, 10344, 10342,     0,  8192, 10240, 10368, 
+    10336,     0,  8192, 10240, 10368, 10336, 10344,     0, 
+     8192, 10240, 10368, 10336, 10344,     0,  8192, 10240, 
+    10368, 10336, 10344, 10346,     0,  8192, 10240, 10368, 
+    10336, 10344,     0,  8192, 10240, 10368, 10336, 10352, 
+    10348,     0,  8192, 10240, 10368, 10336, 10352, 10348, 
+        0,  8192, 10240, 10368, 10336, 10352, 10353, 10350, 
+        0,  8192, 10240, 10368, 10336,     0,  8192, 10240, 
+    10368, 10369, 10352,     0,  8192, 10240, 10368, 10369, 
+    10352,     0,  8192, 10240, 10368, 10369, 10352, 10354, 
+        0,  8192, 10240, 10368, 10369, 10352,     0,  8192, 
+    10240, 10368, 10369, 10352, 10356,     0,  8192, 10240, 
+    10368, 10369, 10352, 10356,     0,  8192, 10240, 10368, 
+    10369, 10352, 10360, 10358,     0,  8192, 10240, 10368, 
+    10369, 10352,     0,  8192, 10240, 10368, 10369, 10352, 
+    10360,     0,  8192, 10240, 10368, 10369, 10371, 10360, 
+        0,  8192, 10240, 10368, 10369, 10371, 10360, 10362, 
+        0,  8192, 10240, 10368, 10369, 10371, 10360,     0, 
+     8192, 10240, 10368, 10369, 10371, 10360, 10364,     0, 
+     8192, 10240, 10368, 10369, 10371, 10360, 10364,     0, 
+     8192, 10240, 10368, 10369, 10371, 10360, 10364, 10366, 
+        0,  8192, 10240,     0,  8192, 10240, 10368,     0, 
+     8192, 10240, 10368,     0,  8192, 10240, 10368, 10370, 
+        0,  8192, 10240, 10368,     0,  8192, 10240, 10368, 
+    10372,     0,  8192, 10240, 10368, 10372,     0,  8192, 
+    10240, 10368, 10376, 10374,     0,  8192, 10240, 10368, 
+        0,  8192, 10240, 10368, 10376,     0,  8192, 10240, 
+    10368, 10376,     0,  8192, 10240, 10368, 10376, 10378, 
+        0,  8192, 10240, 10368, 10376,     0,  8192, 10240, 
+    10368, 10384, 10380,     0,  8192, 10240, 10368, 10384, 
+    10380,     0,  8192, 10240, 10368, 10384, 10385, 10382, 
+        0,  8192, 10240, 10368,     0,  8192, 10240, 10368, 
+    10384,     0,  8192, 10240, 10368, 10384,     0,  8192, 
+    10240, 10368, 10384, 10386,     0,  8192, 10240, 10368, 
+    10384,     0,  8192, 10240, 10368, 10384, 10388,     0, 
+     8192, 10240, 10368, 10384, 10388,     0,  8192, 10240, 
+    10368, 10384, 10392, 10390,     0,  8192, 10240, 10368, 
+    10384,     0,  8192, 10240, 10368, 10400, 10392,     0, 
+     8192, 10240, 10368, 10400, 10392,     0,  8192, 10240, 
+    10368, 10400, 10392, 10394,     0,  8192, 10240, 10368, 
+    10400, 10392,     0,  8192, 10240, 10368, 10400, 10401, 
+    10396,     0,  8192, 10240, 10368, 10400, 10401, 10396, 
+        0,  8192, 10240, 10368, 10400, 10401, 10396, 10398, 
+        0,  8192, 10240, 10368,     0,  8192, 10240, 10368, 
+    10400,     0,  8192, 10240, 10368, 10400,     0,  8192, 
+    10240, 10368, 10400, 10402,     0,  8192, 10240, 10368, 
+    10400,     0,  8192, 10240, 10368, 10400, 10404,     0, 
+     8192, 10240, 10368, 10400, 10404,     0,  8192, 10240, 
+    10368, 10400, 10408, 10406,     0,  8192, 10240, 10368, 
+    10400,     0,  8192, 10240, 10368, 10400, 10408,     0, 
+     8192, 10240, 10368, 10400, 10408,     0,  8192, 10240, 
+    10368, 10400, 10408, 10410,     0,  8192, 10240, 10368, 
+    10400, 10408,     0,  8192, 10240, 10368, 10400, 10416, 
+    10412,     0,  8192, 10240, 10368, 10400, 10416, 10412, 
+        0,  8192, 10240, 10368, 10400, 10416, 10417, 10414, 
+        0,  8192, 10240, 10368, 10400,     0,  8192, 10240, 
+    10368, 10432, 10416,     0,  8192, 10240, 10368, 10432, 
+    10416,     0,  8192, 10240, 10368, 10432, 10416, 10418, 
+        0,  8192, 10240, 10368, 10432, 10416,     0,  8192, 
+    10240, 10368, 10432, 10416, 10420,     0,  8192, 10240, 
+    10368, 10432, 10416, 10420,     0,  8192, 10240, 10368, 
+    10432, 10416, 10424, 10422,     0,  8192, 10240, 10368, 
+    10432, 10416,     0,  8192, 10240, 10368, 10432, 10433, 
+    10424,     0,  8192, 10240, 10368, 10432, 10433, 10424, 
+        0,  8192, 10240, 10368, 10432, 10433, 10424, 10426, 
+        0,  8192, 10240, 10368, 10432, 10433, 10424,     0, 
+     8192, 10240, 10368, 10432, 10433, 10424, 10428,     0, 
+     8192, 10240, 10368, 10432, 10433, 10435, 10428,     0, 
+     8192, 10240, 10368, 10432, 10433, 10435, 10428, 10430, 
+        0,  8192, 10240, 10368,     0,  8192, 10240, 10496, 
+    10432,     0,  8192, 10240, 10496, 10432,     0,  8192, 
+    10240, 10496, 10432, 10434,     0,  8192, 10240, 10496, 
+    10432,     0,  8192, 10240, 10496, 10432, 10436,     0, 
+     8192, 10240, 10496, 10432, 10436,     0,  8192, 10240, 
+    10496, 10432, 10440, 10438,     0,  8192, 10240, 10496, 
+    10432,     0,  8192, 10240, 10496, 10432, 10440,     0, 
+     8192, 10240, 10496, 10432, 10440,     0,  8192, 10240, 
+    10496, 10432, 10440, 10442,     0,  8192, 10240, 10496, 
+    10432, 10440,     0,  8192, 10240, 10496, 10432, 10448, 
+    10444,     0,  8192, 10240, 10496, 10432, 10448, 10444, 
+        0,  8192, 10240, 10496, 10432, 10448, 10449, 10446, 
+        0,  8192, 10240, 10496, 10432,     0,  8192, 10240, 
+    10496, 10432, 10448,     0,  8192, 10240, 10496, 10432, 
+    10448,     0,  8192, 10240, 10496, 10432, 10448, 10450, 
+        0,  8192, 10240, 10496, 10432, 10448,     0,  8192, 
+    10240, 10496, 10432, 10448, 10452,     0,  8192, 10240, 
+    10496, 10432, 10448, 10452,     0,  8192, 10240, 10496, 
+    10432, 10448, 10456, 10454,     0,  8192, 10240, 10496, 
+    10432, 10448,     0,  8192, 10240, 10496, 10432, 10464, 
+    10456,     0,  8192, 10240, 10496, 10432, 10464, 10456, 
+        0,  8192, 10240, 10496, 10432, 10464, 10456, 10458, 
+        0,  8192, 10240, 10496, 10432, 10464, 10456,     0, 
+     8192, 10240, 10496, 10432, 10464, 10465, 10460,     0, 
+     8192, 10240, 10496, 10432, 10464, 10465, 10460,     0, 
+     8192, 10240, 10496, 10432, 10464, 10465, 10460, 10462, 
+        0,  8192, 10240, 10496, 10432,     0,  8192, 10240, 
+    10496, 10497, 10464,     0,  8192, 10240, 10496, 10497, 
+    10464,     0,  8192, 10240, 10496, 10497, 10464, 10466, 
+        0,  8192, 10240, 10496, 10497, 10464,     0,  8192, 
+    10240, 10496, 10497, 10464, 10468,     0,  8192, 10240, 
+    10496, 10497, 10464, 10468,     0,  8192, 10240, 10496, 
+    10497, 10464, 10472, 10470,     0,  8192, 10240, 10496, 
+    10497, 10464,     0,  8192, 10240, 10496, 10497, 10464, 
+    10472,     0,  8192, 10240, 10496, 10497, 10464, 10472, 
+        0,  8192, 10240, 10496, 10497, 10464, 10472, 10474, 
+        0,  8192, 10240, 10496, 10497, 10464, 10472,     0, 
+     8192, 10240, 10496, 10497, 10464, 10480, 10476,     0, 
+     8192, 10240, 10496, 10497, 10464, 10480, 10476,     0, 
+     8192, 10240, 10496, 10497, 10464, 10480, 10481, 10478, 
+        0,  8192, 10240, 10496, 10497, 10464,     0,  8192, 
+    10240, 10496, 10497, 10464, 10480,     0,  8192, 10240, 
+    10496, 10497, 10499, 10480,     0,  8192, 10240, 10496, 
+    10497, 10499, 10480, 10482,     0,  8192, 10240, 10496, 
+    10497, 10499, 10480,     0,  8192, 10240, 10496, 10497, 
+    10499, 10480, 10484,     0,  8192, 10240, 10496, 10497, 
+    10499, 10480, 10484,     0,  8192, 10240, 10496, 10497, 
+    10499, 10480, 10488, 10486,     0,  8192, 10240, 10496, 
+    10497, 10499, 10480,     0,  8192, 10240, 10496, 10497, 
+    10499, 10480, 10488,     0,  8192, 10240, 10496, 10497, 
+    10499, 10480, 10488,     0,  8192, 10240, 10496, 10497, 
+    10499, 10480, 10488, 10490,     0,  8192, 10240, 10496, 
+    10497, 10499, 10503, 10488,     0,  8192, 10240, 10496, 
+    10497, 10499, 10503, 10488, 10492,     0,  8192, 10240, 
+    10496, 10497, 10499, 10503, 10488, 10492,     0,  8192, 
+    10240, 10496, 10497, 10499, 10503, 10488, 10492, 10494, 
+        0,  8192, 10240,     0,  8192, 10240, 10496,     0, 
+     8192, 10240, 10496,     0,  8192, 10240, 10496, 10498, 
+        0,  8192, 10240, 10496,     0,  8192, 10240, 10496, 
+    10500,     0,  8192, 10240, 10496, 10500,     0,  8192, 
+    10240, 10496, 10504, 10502,     0,  8192, 10240, 10496, 
+        0,  8192, 10240, 10496, 10504,     0,  8192, 10240, 
+    10496, 10504,     0,  8192, 10240, 10496, 10504, 10506, 
+        0,  8192, 10240, 10496, 10504,     0,  8192, 10240, 
+    10496, 10512, 10508,     0,  8192, 10240, 10496, 10512, 
+    10508,     0,  8192, 10240, 10496, 10512, 10513, 10510, 
+        0,  8192, 10240, 10496,     0,  8192, 10240, 10496, 
+    10512,     0,  8192, 10240, 10496, 10512,     0,  8192, 
+    10240, 10496, 10512, 10514,     0,  8192, 10240, 10496, 
+    10512,     0,  8192, 10240, 10496, 10512, 10516,     0, 
+     8192, 10240, 10496, 10512, 10516,     0,  8192, 10240, 
+    10496, 10512, 10520, 10518,     0,  8192, 10240, 10496, 
+    10512,     0,  8192, 10240, 10496, 10528, 10520,     0, 
+     8192, 10240, 10496, 10528, 10520,     0,  8192, 10240, 
+    10496, 10528, 10520, 10522,     0,  8192, 10240, 10496, 
+    10528, 10520,     0,  8192, 10240, 10496, 10528, 10529, 
+    10524,     0,  8192, 10240, 10496, 10528, 10529, 10524, 
+        0,  8192, 10240, 10496, 10528, 10529, 10524, 10526, 
+        0,  8192, 10240, 10496,     0,  8192, 10240, 10496, 
+    10528,     0,  8192, 10240, 10496, 10528,     0,  8192, 
+    10240, 10496, 10528, 10530,     0,  8192, 10240, 10496, 
+    10528,     0,  8192, 10240, 10496, 10528, 10532,     0, 
+     8192, 10240, 10496, 10528, 10532,     0,  8192, 10240, 
+    10496, 10528, 10536, 10534,     0,  8192, 10240, 10496, 
+    10528,     0,  8192, 10240, 10496, 10528, 10536,     0, 
+     8192, 10240, 10496, 10528, 10536,     0,  8192, 10240, 
+    10496, 10528, 10536, 10538,     0,  8192, 10240, 10496, 
+    10528, 10536,     0,  8192, 10240, 10496, 10528, 10544, 
+    10540,     0,  8192, 10240, 10496, 10528, 10544, 10540, 
+        0,  8192, 10240, 10496, 10528, 10544, 10545, 10542, 
+        0,  8192, 10240, 10496, 10528,     0,  8192, 10240, 
+    10496, 10560, 10544,     0,  8192, 10240, 10496, 10560, 
+    10544,     0,  8192, 10240, 10496, 10560, 10544, 10546, 
+        0,  8192, 10240, 10496, 10560, 10544,     0,  8192, 
+    10240, 10496, 10560, 10544, 10548,     0,  8192, 10240, 
+    10496, 10560, 10544, 10548,     0,  8192, 10240, 10496, 
+    10560, 10544, 10552, 10550,     0,  8192, 10240, 10496, 
+    10560, 10544,     0,  8192, 10240, 10496, 10560, 10561, 
+    10552,     0,  8192, 10240, 10496, 10560, 10561, 10552, 
+        0,  8192, 10240, 10496, 10560, 10561, 10552, 10554, 
+        0,  8192, 10240, 10496, 10560, 10561, 10552,     0, 
+     8192, 10240, 10496, 10560, 10561, 10552, 10556,     0, 
+     8192, 10240, 10496, 10560, 10561, 10563, 10556,     0, 
+     8192, 10240, 10496, 10560, 10561, 10563, 10556, 10558, 
+        0,  8192, 10240, 10496,     0,  8192, 10240, 10496, 
+    10560,     0,  8192, 10240, 10496, 10560,     0,  8192, 
+    10240, 10496, 10560, 10562,     0,  8192, 10240, 10496, 
+    10560,     0,  8192, 10240, 10496, 10560, 10564,     0, 
+     8192, 10240, 10496, 10560, 10564,     0,  8192, 10240, 
+    10496, 10560, 10568, 10566,     0,  8192, 10240, 10496, 
+    10560,     0,  8192, 10240, 10496, 10560, 10568,     0, 
+     8192, 10240, 10496, 10560, 10568,     0,  8192, 10240, 
+    10496, 10560, 10568, 10570,     0,  8192, 10240, 10496, 
+    10560, 10568,     0,  8192, 10240, 10496, 10560, 10576, 
+    10572,     0,  8192, 10240, 10496, 10560, 10576, 10572, 
+        0,  8192, 10240, 10496, 10560, 10576, 10577, 10574, 
+        0,  8192, 10240, 10496, 10560,     0,  8192, 10240, 
+    10496, 10560, 10576,     0,  8192, 10240, 10496, 10560, 
+    10576,     0,  8192, 10240, 10496, 10560, 10576, 10578, 
+        0,  8192, 10240, 10496, 10560, 10576,     0,  8192, 
+    10240, 10496, 10560, 10576, 10580,     0,  8192, 10240, 
+    10496, 10560, 10576, 10580,     0,  8192, 10240, 10496, 
+    10560, 10576, 10584, 10582,     0,  8192, 10240, 10496, 
+    10560, 10576,     0,  8192, 10240, 10496, 10560, 10592, 
+    10584,     0,  8192, 10240, 10496, 10560, 10592, 10584, 
+        0,  8192, 10240, 10496, 10560, 10592, 10584, 10586, 
+        0,  8192, 10240, 10496, 10560, 10592, 10584,     0, 
+     8192, 10240, 10496, 10560, 10592, 10593, 10588,     0, 
+     8192, 10240, 10496, 10560, 10592, 10593, 10588,     0, 
+     8192, 10240, 10496, 10560, 10592, 10593, 10588, 10590, 
+        0,  8192, 10240, 10496, 10560,     0,  8192, 10240, 
+    10496, 10624, 10592,     0,  8192, 10240, 10496, 10624, 
+    10592,     0,  8192, 10240, 10496, 10624, 10592, 10594, 
+        0,  8192, 10240, 10496, 10624, 10592,     0,  8192, 
+    10240, 10496, 10624, 10592, 10596,     0,  8192, 10240, 
+    10496, 10624, 10592, 10596,     0,  8192, 10240, 10496, 
+    10624, 10592, 10600, 10598,     0,  8192, 10240, 10496, 
+    10624, 10592,     0,  8192, 10240, 10496, 10624, 10592, 
+    10600,     0,  8192, 10240, 10496, 10624, 10592, 10600, 
+        0,  8192, 10240, 10496, 10624, 10592, 10600, 10602, 
+        0,  8192, 10240, 10496, 10624, 10592, 10600,     0, 
+     8192, 10240, 10496, 10624, 10592, 10608, 10604,     0, 
+     8192, 10240, 10496, 10624, 10592, 10608, 10604,     0, 
+     8192, 10240, 10496, 10624, 10592, 10608, 10609, 10606, 
+        0,  8192, 10240, 10496, 10624, 10592,     0,  8192, 
+    10240, 10496, 10624, 10625, 10608,     0,  8192, 10240, 
+    10496, 10624, 10625, 10608,     0,  8192, 10240, 10496, 
+    10624, 10625, 10608, 10610,     0,  8192, 10240, 10496, 
+    10624, 10625, 10608,     0,  8192, 10240, 10496, 10624, 
+    10625, 10608, 10612,     0,  8192, 10240, 10496, 10624, 
+    10625, 10608, 10612,     0,  8192, 10240, 10496, 10624, 
+    10625, 10608, 10616, 10614,     0,  8192, 10240, 10496, 
+    10624, 10625, 10608,     0,  8192, 10240, 10496, 10624, 
+    10625, 10608, 10616,     0,  8192, 10240, 10496, 10624, 
+    10625, 10627, 10616,     0,  8192, 10240, 10496, 10624, 
+    10625, 10627, 10616, 10618,     0,  8192, 10240, 10496, 
+    10624, 10625, 10627, 10616,     0,  8192, 10240, 10496, 
+    10624, 10625, 10627, 10616, 10620,     0,  8192, 10240, 
+    10496, 10624, 10625, 10627, 10616, 10620,     0,  8192, 
+    10240, 10496, 10624, 10625, 10627, 10616, 10620, 10622, 
+        0,  8192, 10240, 10496,     0,  8192, 10240, 10752, 
+    10624,     0,  8192, 10240, 10752, 10624,     0,  8192, 
+    10240, 10752, 10624, 10626,     0,  8192, 10240, 10752, 
+    10624,     0,  8192, 10240, 10752, 10624, 10628,     0, 
+     8192, 10240, 10752, 10624, 10628,     0,  8192, 10240, 
+    10752, 10624, 10632, 10630,     0,  8192, 10240, 10752, 
+    10624,     0,  8192, 10240, 10752, 10624, 10632,     0, 
+     8192, 10240, 10752, 10624, 10632,     0,  8192, 10240, 
+    10752, 10624, 10632, 10634,     0,  8192, 10240, 10752, 
+    10624, 10632,     0,  8192, 10240, 10752, 10624, 10640, 
+    10636,     0,  8192, 10240, 10752, 10624, 10640, 10636, 
+        0,  8192, 10240, 10752, 10624, 10640, 10641, 10638, 
+        0,  8192, 10240, 10752, 10624,     0,  8192, 10240, 
+    10752, 10624, 10640,     0,  8192, 10240, 10752, 10624, 
+    10640,     0,  8192, 10240, 10752, 10624, 10640, 10642, 
+        0,  8192, 10240, 10752, 10624, 10640,     0,  8192, 
+    10240, 10752, 10624, 10640, 10644,     0,  8192, 10240, 
+    10752, 10624, 10640, 10644,     0,  8192, 10240, 10752, 
+    10624, 10640, 10648, 10646,     0,  8192, 10240, 10752, 
+    10624, 10640,     0,  8192, 10240, 10752, 10624, 10656, 
+    10648,     0,  8192, 10240, 10752, 10624, 10656, 10648, 
+        0,  8192, 10240, 10752, 10624, 10656, 10648, 10650, 
+        0,  8192, 10240, 10752, 10624, 10656, 10648,     0, 
+     8192, 10240, 10752, 10624, 10656, 10657, 10652,     0, 
+     8192, 10240, 10752, 10624, 10656, 10657, 10652,     0, 
+     8192, 10240, 10752, 10624, 10656, 10657, 10652, 10654, 
+        0,  8192, 10240, 10752, 10624,     0,  8192, 10240, 
+    10752, 10624, 10656,     0,  8192, 10240, 10752, 10624, 
+    10656,     0,  8192, 10240, 10752, 10624, 10656, 10658, 
+        0,  8192, 10240, 10752, 10624, 10656,     0,  8192, 
+    10240, 10752, 10624, 10656, 10660,     0,  8192, 10240, 
+    10752, 10624, 10656, 10660,     0,  8192, 10240, 10752, 
+    10624, 10656, 10664, 10662,     0,  8192, 10240, 10752, 
+    10624, 10656,     0,  8192, 10240, 10752, 10624, 10656, 
+    10664,     0,  8192, 10240, 10752, 10624, 10656, 10664, 
+        0,  8192, 10240, 10752, 10624, 10656, 10664, 10666, 
+        0,  8192, 10240, 10752, 10624, 10656, 10664,     0, 
+     8192, 10240, 10752, 10624, 10656, 10672, 10668,     0, 
+     8192, 10240, 10752, 10624, 10656, 10672, 10668,     0, 
+     8192, 10240, 10752, 10624, 10656, 10672, 10673, 10670, 
+        0,  8192, 10240, 10752, 10624, 10656,     0,  8192, 
+    10240, 10752, 10624, 10688, 10672,     0,  8192, 10240, 
+    10752, 10624, 10688, 10672,     0,  8192, 10240, 10752, 
+    10624, 10688, 10672, 10674,     0,  8192, 10240, 10752, 
+    10624, 10688, 10672,     0,  8192, 10240, 10752, 10624, 
+    10688, 10672, 10676,     0,  8192, 10240, 10752, 10624, 
+    10688, 10672, 10676,     0,  8192, 10240, 10752, 10624, 
+    10688, 10672, 10680, 10678,     0,  8192, 10240, 10752, 
+    10624, 10688, 10672,     0,  8192, 10240, 10752, 10624, 
+    10688, 10689, 10680,     0,  8192, 10240, 10752, 10624, 
+    10688, 10689, 10680,     0,  8192, 10240, 10752, 10624, 
+    10688, 10689, 10680, 10682,     0,  8192, 10240, 10752, 
+    10624, 10688, 10689, 10680,     0,  8192, 10240, 10752, 
+    10624, 10688, 10689, 10680, 10684,     0,  8192, 10240, 
+    10752, 10624, 10688, 10689, 10691, 10684,     0,  8192, 
+    10240, 10752, 10624, 10688, 10689, 10691, 10684, 10686, 
+        0,  8192, 10240, 10752, 10624,     0,  8192, 10240, 
+    10752, 10753, 10688,     0,  8192, 10240, 10752, 10753, 
+    10688,     0,  8192, 10240, 10752, 10753, 10688, 10690, 
+        0,  8192, 10240, 10752, 10753, 10688,     0,  8192, 
+    10240, 10752, 10753, 10688, 10692,     0,  8192, 10240, 
+    10752, 10753, 10688, 10692,     0,  8192, 10240, 10752, 
+    10753, 10688, 10696, 10694,     0,  8192, 10240, 10752, 
+    10753, 10688,     0,  8192, 10240, 10752, 10753, 10688, 
+    10696,     0,  8192, 10240, 10752, 10753, 10688, 10696, 
+        0,  8192, 10240, 10752, 10753, 10688, 10696, 10698, 
+        0,  8192, 10240, 10752, 10753, 10688, 10696,     0, 
+     8192, 10240, 10752, 10753, 10688, 10704, 10700,     0, 
+     8192, 10240, 10752, 10753, 10688, 10704, 10700,     0, 
+     8192, 10240, 10752, 10753, 10688, 10704, 10705, 10702, 
+        0,  8192, 10240, 10752, 10753, 10688,     0,  8192, 
+    10240, 10752, 10753, 10688, 10704,     0,  8192, 10240, 
+    10752, 10753, 10688, 10704,     0,  8192, 10240, 10752, 
+    10753, 10688, 10704, 10706,     0,  8192, 10240, 10752, 
+    10753, 10688, 10704,     0,  8192, 10240, 10752, 10753, 
+    10688, 10704, 10708,     0,  8192, 10240, 10752, 10753, 
+    10688, 10704, 10708,     0,  8192, 10240, 10752, 10753, 
+    10688, 10704, 10712, 10710,     0,  8192, 10240, 10752, 
+    10753, 10688, 10704,     0,  8192, 10240, 10752, 10753, 
+    10688, 10720, 10712,     0,  8192, 10240, 10752, 10753, 
+    10688, 10720, 10712,     0,  8192, 10240, 10752, 10753, 
+    10688, 10720, 10712, 10714,     0,  8192, 10240, 10752, 
+    10753, 10688, 10720, 10712,     0,  8192, 10240, 10752, 
+    10753, 10688, 10720, 10721, 10716,     0,  8192, 10240, 
+    10752, 10753, 10688, 10720, 10721, 10716,     0,  8192, 
+    10240, 10752, 10753, 10688, 10720, 10721, 10716, 10718, 
+        0,  8192, 10240, 10752, 10753, 10688,     0,  8192, 
+    10240, 10752, 10753, 10688, 10720,     0,  8192, 10240, 
+    10752, 10753, 10755, 10720,     0,  8192, 10240, 10752, 
+    10753, 10755, 10720, 10722,     0,  8192, 10240, 10752, 
+    10753, 10755, 10720,     0,  8192, 10240, 10752, 10753, 
+    10755, 10720, 10724,     0,  8192, 10240, 10752, 10753, 
+    10755, 10720, 10724,     0,  8192, 10240, 10752, 10753, 
+    10755, 10720, 10728, 10726,     0,  8192, 10240, 10752, 
+    10753, 10755, 10720,     0,  8192, 10240, 10752, 10753, 
+    10755, 10720, 10728,     0,  8192, 10240, 10752, 10753, 
+    10755, 10720, 10728,     0,  8192, 10240, 10752, 10753, 
+    10755, 10720, 10728, 10730,     0,  8192, 10240, 10752, 
+    10753, 10755, 10720, 10728,     0,  8192, 10240, 10752, 
+    10753, 10755, 10720, 10736, 10732,     0,  8192, 10240, 
+    10752, 10753, 10755, 10720, 10736, 10732,     0,  8192, 
+    10240, 10752, 10753, 10755, 10720, 10736, 10737, 10734, 
+        0,  8192, 10240, 10752, 10753, 10755, 10720,     0, 
+     8192, 10240, 10752, 10753, 10755, 10720, 10736,     0, 
+     8192, 10240, 10752, 10753, 10755, 10720, 10736,     0, 
+     8192, 10240, 10752, 10753, 10755, 10720, 10736, 10738, 
+        0,  8192, 10240, 10752, 10753, 10755, 10759, 10736, 
+        0,  8192, 10240, 10752, 10753, 10755, 10759, 10736, 
+    10740,     0,  8192, 10240, 10752, 10753, 10755, 10759, 
+    10736, 10740,     0,  8192, 10240, 10752, 10753, 10755, 
+    10759, 10736, 10744, 10742,     0,  8192, 10240, 10752, 
+    10753, 10755, 10759, 10736,     0,  8192, 10240, 10752, 
+    10753, 10755, 10759, 10736, 10744,     0,  8192, 10240, 
+    10752, 10753, 10755, 10759, 10736, 10744,     0,  8192, 
+    10240, 10752, 10753, 10755, 10759, 10736, 10744, 10746, 
+        0,  8192, 10240, 10752, 10753, 10755, 10759, 10736, 
+    10744,     0,  8192, 10240, 10752, 10753, 10755, 10759, 
+    10736, 10744, 10748,     0,  8192, 10240, 10752, 10753, 
+    10755, 10759, 10736, 10744, 10748,     0,  8192, 10240, 
+    10752, 10753, 10755, 10759, 10736, 10744, 10748, 10750, 
+        0,  8192, 10240,     0,  8192, 10240, 10752,     0, 
+     8192, 10240, 10752,     0,  8192, 10240, 10752, 10754, 
+        0,  8192, 10240, 10752,     0,  8192, 10240, 10752, 
+    10756,     0,  8192, 10240, 10752, 10756,     0,  8192, 
+    10240, 10752, 10760, 10758,     0,  8192, 10240, 10752, 
+        0,  8192, 10240, 10752, 10760,     0,  8192, 10240, 
+    10752, 10760,     0,  8192, 10240, 10752, 10760, 10762, 
+        0,  8192, 10240, 10752, 10760,     0,  8192, 10240, 
+    10752, 10768, 10764,     0,  8192, 10240, 10752, 10768, 
+    10764,     0,  8192, 10240, 10752, 10768, 10769, 10766, 
+        0,  8192, 10240, 10752,     0,  8192, 10240, 10752, 
+    10768,     0,  8192, 10240, 10752, 10768,     0,  8192, 
+    10240, 10752, 10768, 10770,     0,  8192, 10240, 10752, 
+    10768,     0,  8192, 10240, 10752, 10768, 10772,     0, 
+     8192, 10240, 10752, 10768, 10772,     0,  8192, 10240, 
+    10752, 10768, 10776, 10774,     0,  8192, 10240, 10752, 
+    10768,     0,  8192, 10240, 10752, 10784, 10776,     0, 
+     8192, 10240, 10752, 10784, 10776,     0,  8192, 10240, 
+    10752, 10784, 10776, 10778,     0,  8192, 10240, 10752, 
+    10784, 10776,     0,  8192, 10240, 10752, 10784, 10785, 
+    10780,     0,  8192, 10240, 10752, 10784, 10785, 10780, 
+        0,  8192, 10240, 10752, 10784, 10785, 10780, 10782, 
+        0,  8192, 10240, 10752,     0,  8192, 10240, 10752, 
+    10784,     0,  8192, 10240, 10752, 10784,     0,  8192, 
+    10240, 10752, 10784, 10786,     0,  8192, 10240, 10752, 
+    10784,     0,  8192, 10240, 10752, 10784, 10788,     0, 
+     8192, 10240, 10752, 10784, 10788,     0,  8192, 10240, 
+    10752, 10784, 10792, 10790,     0,  8192, 10240, 10752, 
+    10784,     0,  8192, 10240, 10752, 10784, 10792,     0, 
+     8192, 10240, 10752, 10784, 10792,     0,  8192, 10240, 
+    10752, 10784, 10792, 10794,     0,  8192, 10240, 10752, 
+    10784, 10792,     0,  8192, 10240, 10752, 10784, 10800, 
+    10796,     0,  8192, 10240, 10752, 10784, 10800, 10796, 
+        0,  8192, 10240, 10752, 10784, 10800, 10801, 10798, 
+        0,  8192, 10240, 10752, 10784,     0,  8192, 10240, 
+    10752, 10816, 10800,     0,  8192, 10240, 10752, 10816, 
+    10800,     0,  8192, 10240, 10752, 10816, 10800, 10802, 
+        0,  8192, 10240, 10752, 10816, 10800,     0,  8192, 
+    10240, 10752, 10816, 10800, 10804,     0,  8192, 10240, 
+    10752, 10816, 10800, 10804,     0,  8192, 10240, 10752, 
+    10816, 10800, 10808, 10806,     0,  8192, 10240, 10752, 
+    10816, 10800,     0,  8192, 10240, 10752, 10816, 10817, 
+    10808,     0,  8192, 10240, 10752, 10816, 10817, 10808, 
+        0,  8192, 10240, 10752, 10816, 10817, 10808, 10810, 
+        0,  8192, 10240, 10752, 10816, 10817, 10808,     0, 
+     8192, 10240, 10752, 10816, 10817, 10808, 10812,     0, 
+     8192, 10240, 10752, 10816, 10817, 10819, 10812,     0, 
+     8192, 10240, 10752, 10816, 10817, 10819, 10812, 10814, 
+        0,  8192, 10240, 10752,     0,  8192, 10240, 10752, 
+    10816,     0,  8192, 10240, 10752, 10816,     0,  8192, 
+    10240, 10752, 10816, 10818,     0,  8192, 10240, 10752, 
+    10816,     0,  8192, 10240, 10752, 10816, 10820,     0, 
+     8192, 10240, 10752, 10816, 10820,     0,  8192, 10240, 
+    10752, 10816, 10824, 10822,     0,  8192, 10240, 10752, 
+    10816,     0,  8192, 10240, 10752, 10816, 10824,     0, 
+     8192, 10240, 10752, 10816, 10824,     0,  8192, 10240, 
+    10752, 10816, 10824, 10826,     0,  8192, 10240, 10752, 
+    10816, 10824,     0,  8192, 10240, 10752, 10816, 10832, 
+    10828,     0,  8192, 10240, 10752, 10816, 10832, 10828, 
+        0,  8192, 10240, 10752, 10816, 10832, 10833, 10830, 
+        0,  8192, 10240, 10752, 10816,     0,  8192, 10240, 
+    10752, 10816, 10832,     0,  8192, 10240, 10752, 10816, 
+    10832,     0,  8192, 10240, 10752, 10816, 10832, 10834, 
+        0,  8192, 10240, 10752, 10816, 10832,     0,  8192, 
+    10240, 10752, 10816, 10832, 10836,     0,  8192, 10240, 
+    10752, 10816, 10832, 10836,     0,  8192, 10240, 10752, 
+    10816, 10832, 10840, 10838,     0,  8192, 10240, 10752, 
+    10816, 10832,     0,  8192, 10240, 10752, 10816, 10848, 
+    10840,     0,  8192, 10240, 10752, 10816, 10848, 10840, 
+        0,  8192, 10240, 10752, 10816, 10848, 10840, 10842, 
+        0,  8192, 10240, 10752, 10816, 10848, 10840,     0, 
+     8192, 10240, 10752, 10816, 10848, 10849, 10844,     0, 
+     8192, 10240, 10752, 10816, 10848, 10849, 10844,     0, 
+     8192, 10240, 10752, 10816, 10848, 10849, 10844, 10846, 
+        0,  8192, 10240, 10752, 10816,     0,  8192, 10240, 
+    10752, 10880, 10848,     0,  8192, 10240, 10752, 10880, 
+    10848,     0,  8192, 10240, 10752, 10880, 10848, 10850, 
+        0,  8192, 10240, 10752, 10880, 10848,     0,  8192, 
+    10240, 10752, 10880, 10848, 10852,     0,  8192, 10240, 
+    10752, 10880, 10848, 10852,     0,  8192, 10240, 10752, 
+    10880, 10848, 10856, 10854,     0,  8192, 10240, 10752, 
+    10880, 10848,     0,  8192, 10240, 10752, 10880, 10848, 
+    10856,     0,  8192, 10240, 10752, 10880, 10848, 10856, 
+        0,  8192, 10240, 10752, 10880, 10848, 10856, 10858, 
+        0,  8192, 10240, 10752, 10880, 10848, 10856,     0, 
+     8192, 10240, 10752, 10880, 10848, 10864, 10860,     0, 
+     8192, 10240, 10752, 10880, 10848, 10864, 10860,     0, 
+     8192, 10240, 10752, 10880, 10848, 10864, 10865, 10862, 
+        0,  8192, 10240, 10752, 10880, 10848,     0,  8192, 
+    10240, 10752, 10880, 10881, 10864,     0,  8192, 10240, 
+    10752, 10880, 10881, 10864,     0,  8192, 10240, 10752, 
+    10880, 10881, 10864, 10866,     0,  8192, 10240, 10752, 
+    10880, 10881, 10864,     0,  8192, 10240, 10752, 10880, 
+    10881, 10864, 10868,     0,  8192, 10240, 10752, 10880, 
+    10881, 10864, 10868,     0,  8192, 10240, 10752, 10880, 
+    10881, 10864, 10872, 10870,     0,  8192, 10240, 10752, 
+    10880, 10881, 10864,     0,  8192, 10240, 10752, 10880, 
+    10881, 10864, 10872,     0,  8192, 10240, 10752, 10880, 
+    10881, 10883, 10872,     0,  8192, 10240, 10752, 10880, 
+    10881, 10883, 10872, 10874,     0,  8192, 10240, 10752, 
+    10880, 10881, 10883, 10872,     0,  8192, 10240, 10752, 
+    10880, 10881, 10883, 10872, 10876,     0,  8192, 10240, 
+    10752, 10880, 10881, 10883, 10872, 10876,     0,  8192, 
+    10240, 10752, 10880, 10881, 10883, 10872, 10876, 10878, 
+        0,  8192, 10240, 10752,     0,  8192, 10240, 10752, 
+    10880,     0,  8192, 10240, 10752, 10880,     0,  8192, 
+    10240, 10752, 10880, 10882,     0,  8192, 10240, 10752, 
+    10880,     0,  8192, 10240, 10752, 10880, 10884,     0, 
+     8192, 10240, 10752, 10880, 10884,     0,  8192, 10240, 
+    10752, 10880, 10888, 10886,     0,  8192, 10240, 10752, 
+    10880,     0,  8192, 10240, 10752, 10880, 10888,     0, 
+     8192, 10240, 10752, 10880, 10888,     0,  8192, 10240, 
+    10752, 10880, 10888, 10890,     0,  8192, 10240, 10752, 
+    10880, 10888,     0,  8192, 10240, 10752, 10880, 10896, 
+    10892,     0,  8192, 10240, 10752, 10880, 10896, 10892, 
+        0,  8192, 10240, 10752, 10880, 10896, 10897, 10894, 
+        0,  8192, 10240, 10752, 10880,     0,  8192, 10240, 
+    10752, 10880, 10896,     0,  8192, 10240, 10752, 10880, 
+    10896,     0,  8192, 10240, 10752, 10880, 10896, 10898, 
+        0,  8192, 10240, 10752, 10880, 10896,     0,  8192, 
+    10240, 10752, 10880, 10896, 10900,     0,  8192, 10240, 
+    10752, 10880, 10896, 10900,     0,  8192, 10240, 10752, 
+    10880, 10896, 10904, 10902,     0,  8192, 10240, 10752, 
+    10880, 10896,     0,  8192, 10240, 10752, 10880, 10912, 
+    10904,     0,  8192, 10240, 10752, 10880, 10912, 10904, 
+        0,  8192, 10240, 10752, 10880, 10912, 10904, 10906, 
+        0,  8192, 10240, 10752, 10880, 10912, 10904,     0, 
+     8192, 10240, 10752, 10880, 10912, 10913, 10908,     0, 
+     8192, 10240, 10752, 10880, 10912, 10913, 10908,     0, 
+     8192, 10240, 10752, 10880, 10912, 10913, 10908, 10910, 
+        0,  8192, 10240, 10752, 10880,     0,  8192, 10240, 
+    10752, 10880, 10912,     0,  8192, 10240, 10752, 10880, 
+    10912,     0,  8192, 10240, 10752, 10880, 10912, 10914, 
+        0,  8192, 10240, 10752, 10880, 10912,     0,  8192, 
+    10240, 10752, 10880, 10912, 10916,     0,  8192, 10240, 
+    10752, 10880, 10912, 10916,     0,  8192, 10240, 10752, 
+    10880, 10912, 10920, 10918,     0,  8192, 10240, 10752, 
+    10880, 10912,     0,  8192, 10240, 10752, 10880, 10912, 
+    10920,     0,  8192, 10240, 10752, 10880, 10912, 10920, 
+        0,  8192, 10240, 10752, 10880, 10912, 10920, 10922, 
+        0,  8192, 10240, 10752, 10880, 10912, 10920,     0, 
+     8192, 10240, 10752, 10880, 10912, 10928, 10924,     0, 
+     8192, 10240, 10752, 10880, 10912, 10928, 10924,     0, 
+     8192, 10240, 10752, 10880, 10912, 10928, 10929, 10926, 
+        0,  8192, 10240, 10752, 10880, 10912,     0,  8192, 
+    10240, 10752, 10880, 10944, 10928,     0,  8192, 10240, 
+    10752, 10880, 10944, 10928,     0,  8192, 10240, 10752, 
+    10880, 10944, 10928, 10930,     0,  8192, 10240, 10752, 
+    10880, 10944, 10928,     0,  8192, 10240, 10752, 10880, 
+    10944, 10928, 10932,     0,  8192, 10240, 10752, 10880, 
+    10944, 10928, 10932,     0,  8192, 10240, 10752, 10880, 
+    10944, 10928, 10936, 10934,     0,  8192, 10240, 10752, 
+    10880, 10944, 10928,     0,  8192, 10240, 10752, 10880, 
+    10944, 10945, 10936,     0,  8192, 10240, 10752, 10880, 
+    10944, 10945, 10936,     0,  8192, 10240, 10752, 10880, 
+    10944, 10945, 10936, 10938,     0,  8192, 10240, 10752, 
+    10880, 10944, 10945, 10936,     0,  8192, 10240, 10752, 
+    10880, 10944, 10945, 10936, 10940,     0,  8192, 10240, 
+    10752, 10880, 10944, 10945, 10947, 10940,     0,  8192, 
+    10240, 10752, 10880, 10944, 10945, 10947, 10940, 10942, 
+        0,  8192, 10240, 10752, 10880,     0,  8192, 10240, 
+    10752, 11008, 10944,     0,  8192, 10240, 10752, 11008, 
+    10944,     0,  8192, 10240, 10752, 11008, 10944, 10946, 
+        0,  8192, 10240, 10752, 11008, 10944,     0,  8192, 
+    10240, 10752, 11008, 10944, 10948,     0,  8192, 10240, 
+    10752, 11008, 10944, 10948,     0,  8192, 10240, 10752, 
+    11008, 10944, 10952, 10950,     0,  8192, 10240, 10752, 
+    11008, 10944,     0,  8192, 10240, 10752, 11008, 10944, 
+    10952,     0,  8192, 10240, 10752, 11008, 10944, 10952, 
+        0,  8192, 10240, 10752, 11008, 10944, 10952, 10954, 
+        0,  8192, 10240, 10752, 11008, 10944, 10952,     0, 
+     8192, 10240, 10752, 11008, 10944, 10960, 10956,     0, 
+     8192, 10240, 10752, 11008, 10944, 10960, 10956,     0, 
+     8192, 10240, 10752, 11008, 10944, 10960, 10961, 10958, 
+        0,  8192, 10240, 10752, 11008, 10944,     0,  8192, 
+    10240, 10752, 11008, 10944, 10960,     0,  8192, 10240, 
+    10752, 11008, 10944, 10960,     0,  8192, 10240, 10752, 
+    11008, 10944, 10960, 10962,     0,  8192, 10240, 10752, 
+    11008, 10944, 10960,     0,  8192, 10240, 10752, 11008, 
+    10944, 10960, 10964,     0,  8192, 10240, 10752, 11008, 
+    10944, 10960, 10964,     0,  8192, 10240, 10752, 11008, 
+    10944, 10960, 10968, 10966,     0,  8192, 10240, 10752, 
+    11008, 10944, 10960,     0,  8192, 10240, 10752, 11008, 
+    10944, 10976, 10968,     0,  8192, 10240, 10752, 11008, 
+    10944, 10976, 10968,     0,  8192, 10240, 10752, 11008, 
+    10944, 10976, 10968, 10970,     0,  8192, 10240, 10752, 
+    11008, 10944, 10976, 10968,     0,  8192, 10240, 10752, 
+    11008, 10944, 10976, 10977, 10972,     0,  8192, 10240, 
+    10752, 11008, 10944, 10976, 10977, 10972,     0,  8192, 
+    10240, 10752, 11008, 10944, 10976, 10977, 10972, 10974, 
+        0,  8192, 10240, 10752, 11008, 10944,     0,  8192, 
+    10240, 10752, 11008, 11009, 10976,     0,  8192, 10240, 
+    10752, 11008, 11009, 10976,     0,  8192, 10240, 10752, 
+    11008, 11009, 10976, 10978,     0,  8192, 10240, 10752, 
+    11008, 11009, 10976,     0,  8192, 10240, 10752, 11008, 
+    11009, 10976, 10980,     0,  8192, 10240, 10752, 11008, 
+    11009, 10976, 10980,     0,  8192, 10240, 10752, 11008, 
+    11009, 10976, 10984, 10982,     0,  8192, 10240, 10752, 
+    11008, 11009, 10976,     0,  8192, 10240, 10752, 11008, 
+    11009, 10976, 10984,     0,  8192, 10240, 10752, 11008, 
+    11009, 10976, 10984,     0,  8192, 10240, 10752, 11008, 
+    11009, 10976, 10984, 10986,     0,  8192, 10240, 10752, 
+    11008, 11009, 10976, 10984,     0,  8192, 10240, 10752, 
+    11008, 11009, 10976, 10992, 10988,     0,  8192, 10240, 
+    10752, 11008, 11009, 10976, 10992, 10988,     0,  8192, 
+    10240, 10752, 11008, 11009, 10976, 10992, 10993, 10990, 
+        0,  8192, 10240, 10752, 11008, 11009, 10976,     0, 
+     8192, 10240, 10752, 11008, 11009, 10976, 10992,     0, 
+     8192, 10240, 10752, 11008, 11009, 11011, 10992,     0, 
+     8192, 10240, 10752, 11008, 11009, 11011, 10992, 10994, 
+        0,  8192, 10240, 10752, 11008, 11009, 11011, 10992, 
+        0,  8192, 10240, 10752, 11008, 11009, 11011, 10992, 
+    10996,     0,  8192, 10240, 10752, 11008, 11009, 11011, 
+    10992, 10996,     0,  8192, 10240, 10752, 11008, 11009, 
+    11011, 10992, 11000, 10998,     0,  8192, 10240, 10752, 
+    11008, 11009, 11011, 10992,     0,  8192, 10240, 10752, 
+    11008, 11009, 11011, 10992, 11000,     0,  8192, 10240, 
+    10752, 11008, 11009, 11011, 10992, 11000,     0,  8192, 
+    10240, 10752, 11008, 11009, 11011, 10992, 11000, 11002, 
+        0,  8192, 10240, 10752, 11008, 11009, 11011, 11015, 
+    11000,     0,  8192, 10240, 10752, 11008, 11009, 11011, 
+    11015, 11000, 11004,     0,  8192, 10240, 10752, 11008, 
+    11009, 11011, 11015, 11000, 11004,     0,  8192, 10240, 
+    10752, 11008, 11009, 11011, 11015, 11000, 11004, 11006, 
+        0,  8192, 10240, 10752,     0,  8192, 10240, 11264, 
+    11008,     0,  8192, 10240, 11264, 11008,     0,  8192, 
+    10240, 11264, 11008, 11010,     0,  8192, 10240, 11264, 
+    11008,     0,  8192, 10240, 11264, 11008, 11012,     0, 
+     8192, 10240, 11264, 11008, 11012,     0,  8192, 10240, 
+    11264, 11008, 11016, 11014,     0,  8192, 10240, 11264, 
+    11008,     0,  8192, 10240, 11264, 11008, 11016,     0, 
+     8192, 10240, 11264, 11008, 11016,     0,  8192, 10240, 
+    11264, 11008, 11016, 11018,     0,  8192, 10240, 11264, 
+    11008, 11016,     0,  8192, 10240, 11264, 11008, 11024, 
+    11020,     0,  8192, 10240, 11264, 11008, 11024, 11020, 
+        0,  8192, 10240, 11264, 11008, 11024, 11025, 11022, 
+        0,  8192, 10240, 11264, 11008,     0,  8192, 10240, 
+    11264, 11008, 11024,     0,  8192, 10240, 11264, 11008, 
+    11024,     0,  8192, 10240, 11264, 11008, 11024, 11026, 
+        0,  8192, 10240, 11264, 11008, 11024,     0,  8192, 
+    10240, 11264, 11008, 11024, 11028,     0,  8192, 10240, 
+    11264, 11008, 11024, 11028,     0,  8192, 10240, 11264, 
+    11008, 11024, 11032, 11030,     0,  8192, 10240, 11264, 
+    11008, 11024,     0,  8192, 10240, 11264, 11008, 11040, 
+    11032,     0,  8192, 10240, 11264, 11008, 11040, 11032, 
+        0,  8192, 10240, 11264, 11008, 11040, 11032, 11034, 
+        0,  8192, 10240, 11264, 11008, 11040, 11032,     0, 
+     8192, 10240, 11264, 11008, 11040, 11041, 11036,     0, 
+     8192, 10240, 11264, 11008, 11040, 11041, 11036,     0, 
+     8192, 10240, 11264, 11008, 11040, 11041, 11036, 11038, 
+        0,  8192, 10240, 11264, 11008,     0,  8192, 10240, 
+    11264, 11008, 11040,     0,  8192, 10240, 11264, 11008, 
+    11040,     0,  8192, 10240, 11264, 11008, 11040, 11042, 
+        0,  8192, 10240, 11264, 11008, 11040,     0,  8192, 
+    10240, 11264, 11008, 11040, 11044,     0,  8192, 10240, 
+    11264, 11008, 11040, 11044,     0,  8192, 10240, 11264, 
+    11008, 11040, 11048, 11046,     0,  8192, 10240, 11264, 
+    11008, 11040,     0,  8192, 10240, 11264, 11008, 11040, 
+    11048,     0,  8192, 10240, 11264, 11008, 11040, 11048, 
+        0,  8192, 10240, 11264, 11008, 11040, 11048, 11050, 
+        0,  8192, 10240, 11264, 11008, 11040, 11048,     0, 
+     8192, 10240, 11264, 11008, 11040, 11056, 11052,     0, 
+     8192, 10240, 11264, 11008, 11040, 11056, 11052,     0, 
+     8192, 10240, 11264, 11008, 11040, 11056, 11057, 11054, 
+        0,  8192, 10240, 11264, 11008, 11040,     0,  8192, 
+    10240, 11264, 11008, 11072, 11056,     0,  8192, 10240, 
+    11264, 11008, 11072, 11056,     0,  8192, 10240, 11264, 
+    11008, 11072, 11056, 11058,     0,  8192, 10240, 11264, 
+    11008, 11072, 11056,     0,  8192, 10240, 11264, 11008, 
+    11072, 11056, 11060,     0,  8192, 10240, 11264, 11008, 
+    11072, 11056, 11060,     0,  8192, 10240, 11264, 11008, 
+    11072, 11056, 11064, 11062,     0,  8192, 10240, 11264, 
+    11008, 11072, 11056,     0,  8192, 10240, 11264, 11008, 
+    11072, 11073, 11064,     0,  8192, 10240, 11264, 11008, 
+    11072, 11073, 11064,     0,  8192, 10240, 11264, 11008, 
+    11072, 11073, 11064, 11066,     0,  8192, 10240, 11264, 
+    11008, 11072, 11073, 11064,     0,  8192, 10240, 11264, 
+    11008, 11072, 11073, 11064, 11068,     0,  8192, 10240, 
+    11264, 11008, 11072, 11073, 11075, 11068,     0,  8192, 
+    10240, 11264, 11008, 11072, 11073, 11075, 11068, 11070, 
+        0,  8192, 10240, 11264, 11008,     0,  8192, 10240, 
+    11264, 11008, 11072,     0,  8192, 10240, 11264, 11008, 
+    11072,     0,  8192, 10240, 11264, 11008, 11072, 11074, 
+        0,  8192, 10240, 11264, 11008, 11072,     0,  8192, 
+    10240, 11264, 11008, 11072, 11076,     0,  8192, 10240, 
+    11264, 11008, 11072, 11076,     0,  8192, 10240, 11264, 
+    11008, 11072, 11080, 11078,     0,  8192, 10240, 11264, 
+    11008, 11072,     0,  8192, 10240, 11264, 11008, 11072, 
+    11080,     0,  8192, 10240, 11264, 11008, 11072, 11080, 
+        0,  8192, 10240, 11264, 11008, 11072, 11080, 11082, 
+        0,  8192, 10240, 11264, 11008, 11072, 11080,     0, 
+     8192, 10240, 11264, 11008, 11072, 11088, 11084,     0, 
+     8192, 10240, 11264, 11008, 11072, 11088, 11084,     0, 
+     8192, 10240, 11264, 11008, 11072, 11088, 11089, 11086, 
+        0,  8192, 10240, 11264, 11008, 11072,     0,  8192, 
+    10240, 11264, 11008, 11072, 11088,     0,  8192, 10240, 
+    11264, 11008, 11072, 11088,     0,  8192, 10240, 11264, 
+    11008, 11072, 11088, 11090,     0,  8192, 10240, 11264, 
+    11008, 11072, 11088,     0,  8192, 10240, 11264, 11008, 
+    11072, 11088, 11092,     0,  8192, 10240, 11264, 11008, 
+    11072, 11088, 11092,     0,  8192, 10240, 11264, 11008, 
+    11072, 11088, 11096, 11094,     0,  8192, 10240, 11264, 
+    11008, 11072, 11088,     0,  8192, 10240, 11264, 11008, 
+    11072, 11104, 11096,     0,  8192, 10240, 11264, 11008, 
+    11072, 11104, 11096,     0,  8192, 10240, 11264, 11008, 
+    11072, 11104, 11096, 11098,     0,  8192, 10240, 11264, 
+    11008, 11072, 11104, 11096,     0,  8192, 10240, 11264, 
+    11008, 11072, 11104, 11105, 11100,     0,  8192, 10240, 
+    11264, 11008, 11072, 11104, 11105, 11100,     0,  8192, 
+    10240, 11264, 11008, 11072, 11104, 11105, 11100, 11102, 
+        0,  8192, 10240, 11264, 11008, 11072,     0,  8192, 
+    10240, 11264, 11008, 11136, 11104,     0,  8192, 10240, 
+    11264, 11008, 11136, 11104,     0,  8192, 10240, 11264, 
+    11008, 11136, 11104, 11106,     0,  8192, 10240, 11264, 
+    11008, 11136, 11104,     0,  8192, 10240, 11264, 11008, 
+    11136, 11104, 11108,     0,  8192, 10240, 11264, 11008, 
+    11136, 11104, 11108,     0,  8192, 10240, 11264, 11008, 
+    11136, 11104, 11112, 11110,     0,  8192, 10240, 11264, 
+    11008, 11136, 11104,     0,  8192, 10240, 11264, 11008, 
+    11136, 11104, 11112,     0,  8192, 10240, 11264, 11008, 
+    11136, 11104, 11112,     0,  8192, 10240, 11264, 11008, 
+    11136, 11104, 11112, 11114,     0,  8192, 10240, 11264, 
+    11008, 11136, 11104, 11112,     0,  8192, 10240, 11264, 
+    11008, 11136, 11104, 11120, 11116,     0,  8192, 10240, 
+    11264, 11008, 11136, 11104, 11120, 11116,     0,  8192, 
+    10240, 11264, 11008, 11136, 11104, 11120, 11121, 11118, 
+        0,  8192, 10240, 11264, 11008, 11136, 11104,     0, 
+     8192, 10240, 11264, 11008, 11136, 11137, 11120,     0, 
+     8192, 10240, 11264, 11008, 11136, 11137, 11120,     0, 
+     8192, 10240, 11264, 11008, 11136, 11137, 11120, 11122, 
+        0,  8192, 10240, 11264, 11008, 11136, 11137, 11120, 
+        0,  8192, 10240, 11264, 11008, 11136, 11137, 11120, 
+    11124,     0,  8192, 10240, 11264, 11008, 11136, 11137, 
+    11120, 11124,     0,  8192, 10240, 11264, 11008, 11136, 
+    11137, 11120, 11128, 11126,     0,  8192, 10240, 11264, 
+    11008, 11136, 11137, 11120,     0,  8192, 10240, 11264, 
+    11008, 11136, 11137, 11120, 11128,     0,  8192, 10240, 
+    11264, 11008, 11136, 11137, 11139, 11128,     0,  8192, 
+    10240, 11264, 11008, 11136, 11137, 11139, 11128, 11130, 
+        0,  8192, 10240, 11264, 11008, 11136, 11137, 11139, 
+    11128,     0,  8192, 10240, 11264, 11008, 11136, 11137, 
+    11139, 11128, 11132,     0,  8192, 10240, 11264, 11008, 
+    11136, 11137, 11139, 11128, 11132,     0,  8192, 10240, 
+    11264, 11008, 11136, 11137, 11139, 11128, 11132, 11134, 
+        0,  8192, 10240, 11264, 11008,     0,  8192, 10240, 
+    11264, 11008, 11136,     0,  8192, 10240, 11264, 11265, 
+    11136,     0,  8192, 10240, 11264, 11265, 11136, 11138, 
+        0,  8192, 10240, 11264, 11265, 11136,     0,  8192, 
+    10240, 11264, 11265, 11136, 11140,     0,  8192, 10240, 
+    11264, 11265, 11136, 11140,     0,  8192, 10240, 11264, 
+    11265, 11136, 11144, 11142,     0,  8192, 10240, 11264, 
+    11265, 11136,     0,  8192, 10240, 11264, 11265, 11136, 
+    11144,     0,  8192, 10240, 11264, 11265, 11136, 11144, 
+        0,  8192, 10240, 11264, 11265, 11136, 11144, 11146, 
+        0,  8192, 10240, 11264, 11265, 11136, 11144,     0, 
+     8192, 10240, 11264, 11265, 11136, 11152, 11148,     0, 
+     8192, 10240, 11264, 11265, 11136, 11152, 11148,     0, 
+     8192, 10240, 11264, 11265, 11136, 11152, 11153, 11150, 
+        0,  8192, 10240, 11264, 11265, 11136,     0,  8192, 
+    10240, 11264, 11265, 11136, 11152,     0,  8192, 10240, 
+    11264, 11265, 11136, 11152,     0,  8192, 10240, 11264, 
+    11265, 11136, 11152, 11154,     0,  8192, 10240, 11264, 
+    11265, 11136, 11152,     0,  8192, 10240, 11264, 11265, 
+    11136, 11152, 11156,     0,  8192, 10240, 11264, 11265, 
+    11136, 11152, 11156,     0,  8192, 10240, 11264, 11265, 
+    11136, 11152, 11160, 11158,     0,  8192, 10240, 11264, 
+    11265, 11136, 11152,     0,  8192, 10240, 11264, 11265, 
+    11136, 11168, 11160,     0,  8192, 10240, 11264, 11265, 
+    11136, 11168, 11160,     0,  8192, 10240, 11264, 11265, 
+    11136, 11168, 11160, 11162,     0,  8192, 10240, 11264, 
+    11265, 11136, 11168, 11160,     0,  8192, 10240, 11264, 
+    11265, 11136, 11168, 11169, 11164,     0,  8192, 10240, 
+    11264, 11265, 11136, 11168, 11169, 11164,     0,  8192, 
+    10240, 11264, 11265, 11136, 11168, 11169, 11164, 11166, 
+        0,  8192, 10240, 11264, 11265, 11136,     0,  8192, 
+    10240, 11264, 11265, 11136, 11168,     0,  8192, 10240, 
+    11264, 11265, 11136, 11168,     0,  8192, 10240, 11264, 
+    11265, 11136, 11168, 11170,     0,  8192, 10240, 11264, 
+    11265, 11136, 11168,     0,  8192, 10240, 11264, 11265, 
+    11136, 11168, 11172,     0,  8192, 10240, 11264, 11265, 
+    11136, 11168, 11172,     0,  8192, 10240, 11264, 11265, 
+    11136, 11168, 11176, 11174,     0,  8192, 10240, 11264, 
+    11265, 11136, 11168,     0,  8192, 10240, 11264, 11265, 
+    11136, 11168, 11176,     0,  8192, 10240, 11264, 11265, 
+    11136, 11168, 11176,     0,  8192, 10240, 11264, 11265, 
+    11136, 11168, 11176, 11178,     0,  8192, 10240, 11264, 
+    11265, 11136, 11168, 11176,     0,  8192, 10240, 11264, 
+    11265, 11136, 11168, 11184, 11180,     0,  8192, 10240, 
+    11264, 11265, 11136, 11168, 11184, 11180,     0,  8192, 
+    10240, 11264, 11265, 11136, 11168, 11184, 11185, 11182, 
+        0,  8192, 10240, 11264, 11265, 11136, 11168,     0, 
+     8192, 10240, 11264, 11265, 11136, 11200, 11184,     0, 
+     8192, 10240, 11264, 11265, 11136, 11200, 11184,     0, 
+     8192, 10240, 11264, 11265, 11136, 11200, 11184, 11186, 
+        0,  8192, 10240, 11264, 11265, 11136, 11200, 11184, 
+        0,  8192, 10240, 11264, 11265, 11136, 11200, 11184, 
+    11188,     0,  8192, 10240, 11264, 11265, 11136, 11200, 
+    11184, 11188,     0,  8192, 10240, 11264, 11265, 11136, 
+    11200, 11184, 11192, 11190,     0,  8192, 10240, 11264, 
+    11265, 11136, 11200, 11184,     0,  8192, 10240, 11264, 
+    11265, 11136, 11200, 11201, 11192,     0,  8192, 10240, 
+    11264, 11265, 11136, 11200, 11201, 11192,     0,  8192, 
+    10240, 11264, 11265, 11136, 11200, 11201, 11192, 11194, 
+        0,  8192, 10240, 11264, 11265, 11136, 11200, 11201, 
+    11192,     0,  8192, 10240, 11264, 11265, 11136, 11200, 
+    11201, 11192, 11196,     0,  8192, 10240, 11264, 11265, 
+    11136, 11200, 11201, 11203, 11196,     0,  8192, 10240, 
+    11264, 11265, 11136, 11200, 11201, 11203, 11196, 11198, 
+        0,  8192, 10240, 11264, 11265, 11136,     0,  8192, 
+    10240, 11264, 11265, 11136, 11200,     0,  8192, 10240, 
+    11264, 11265, 11136, 11200,     0,  8192, 10240, 11264, 
+    11265, 11136, 11200, 11202,     0,  8192, 10240, 11264, 
+    11265, 11267, 11200,     0,  8192, 10240, 11264, 11265, 
+    11267, 11200, 11204,     0,  8192, 10240, 11264, 11265, 
+    11267, 11200, 11204,     0,  8192, 10240, 11264, 11265, 
+    11267, 11200, 11208, 11206,     0,  8192, 10240, 11264, 
+    11265, 11267, 11200,     0,  8192, 10240, 11264, 11265, 
+    11267, 11200, 11208,     0,  8192, 10240, 11264, 11265, 
+    11267, 11200, 11208,     0,  8192, 10240, 11264, 11265, 
+    11267, 11200, 11208, 11210,     0,  8192, 10240, 11264, 
+    11265, 11267, 11200, 11208,     0,  8192, 10240, 11264, 
+    11265, 11267, 11200, 11216, 11212,     0,  8192, 10240, 
+    11264, 11265, 11267, 11200, 11216, 11212,     0,  8192, 
+    10240, 11264, 11265, 11267, 11200, 11216, 11217, 11214, 
+        0,  8192, 10240, 11264, 11265, 11267, 11200,     0, 
+     8192, 10240, 11264, 11265, 11267, 11200, 11216,     0, 
+     8192, 10240, 11264, 11265, 11267, 11200, 11216,     0, 
+     8192, 10240, 11264, 11265, 11267, 11200, 11216, 11218, 
+        0,  8192, 10240, 11264, 11265, 11267, 11200, 11216, 
+        0,  8192, 10240, 11264, 11265, 11267, 11200, 11216, 
+    11220,     0,  8192, 10240, 11264, 11265, 11267, 11200, 
+    11216, 11220,     0,  8192, 10240, 11264, 11265, 11267, 
+    11200, 11216, 11224, 11222,     0,  8192, 10240, 11264, 
+    11265, 11267, 11200, 11216,     0,  8192, 10240, 11264, 
+    11265, 11267, 11200, 11232, 11224,     0,  8192, 10240, 
+    11264, 11265, 11267, 11200, 11232, 11224,     0,  8192, 
+    10240, 11264, 11265, 11267, 11200, 11232, 11224, 11226, 
+        0,  8192, 10240, 11264, 11265, 11267, 11200, 11232, 
+    11224,     0,  8192, 10240, 11264, 11265, 11267, 11200, 
+    11232, 11233, 11228,     0,  8192, 10240, 11264, 11265, 
+    11267, 11200, 11232, 11233, 11228,     0,  8192, 10240, 
+    11264, 11265, 11267, 11200, 11232, 11233, 11228, 11230, 
+        0,  8192, 10240, 11264, 11265, 11267, 11200,     0, 
+     8192, 10240, 11264, 11265, 11267, 11200, 11232,     0, 
+     8192, 10240, 11264, 11265, 11267, 11200, 11232,     0, 
+     8192, 10240, 11264, 11265, 11267, 11200, 11232, 11234, 
+        0,  8192, 10240, 11264, 11265, 11267, 11200, 11232, 
+        0,  8192, 10240, 11264, 11265, 11267, 11200, 11232, 
+    11236,     0,  8192, 10240, 11264, 11265, 11267, 11200, 
+    11232, 11236,     0,  8192, 10240, 11264, 11265, 11267, 
+    11200, 11232, 11240, 11238,     0,  8192, 10240, 11264, 
+    11265, 11267, 11271, 11232,     0,  8192, 10240, 11264, 
+    11265, 11267, 11271, 11232, 11240,     0,  8192, 10240, 
+    11264, 11265, 11267, 11271, 11232, 11240,     0,  8192, 
+    10240, 11264, 11265, 11267, 11271, 11232, 11240, 11242, 
+        0,  8192, 10240, 11264, 11265, 11267, 11271, 11232, 
+    11240,     0,  8192, 10240, 11264, 11265, 11267, 11271, 
+    11232, 11248, 11244,     0,  8192, 10240, 11264, 11265, 
+    11267, 11271, 11232, 11248, 11244,     0,  8192, 10240, 
+    11264, 11265, 11267, 11271, 11232, 11248, 11249, 11246, 
+        0,  8192, 10240, 11264, 11265, 11267, 11271, 11232, 
+        0,  8192, 10240, 11264, 11265, 11267, 11271, 11232, 
+    11248,     0,  8192, 10240, 11264, 11265, 11267, 11271, 
+    11232, 11248,     0,  8192, 10240, 11264, 11265, 11267, 
+    11271, 11232, 11248, 11250,     0,  8192, 10240, 11264, 
+    11265, 11267, 11271, 11232, 11248,     0,  8192, 10240, 
+    11264, 11265, 11267, 11271, 11232, 11248, 11252,     0, 
+     8192, 10240, 11264, 11265, 11267, 11271, 11232, 11248, 
+    11252,     0,  8192, 10240, 11264, 11265, 11267, 11271, 
+    11232, 11248, 11256, 11254,     0,  8192, 10240, 11264, 
+    11265, 11267, 11271, 11232, 11248,     0,  8192, 10240, 
+    11264, 11265, 11267, 11271, 11232, 11248, 11256,     0, 
+     8192, 10240, 11264, 11265, 11267, 11271, 11232, 11248, 
+    11256,     0,  8192, 10240, 11264, 11265, 11267, 11271, 
+    11232, 11248, 11256, 11258,     0,  8192, 10240, 11264, 
+    11265, 11267, 11271, 11232, 11248, 11256,     0,  8192, 
+    10240, 11264, 11265, 11267, 11271, 11232, 11248, 11256, 
+    11260,     0,  8192, 10240, 11264, 11265, 11267, 11271, 
+    11232, 11248, 11256, 11260,     0,  8192, 10240, 11264, 
+    11265, 11267, 11271, 11232, 11248, 11256, 11260, 11262, 
+        0,  8192, 10240,     0,  8192, 10240, 11264,     0, 
+     8192, 10240, 11264,     0,  8192, 10240, 11264, 11266, 
+        0,  8192, 10240, 11264,     0,  8192, 10240, 11264, 
+    11268,     0,  8192, 10240, 11264, 11268,     0,  8192, 
+    10240, 11264, 11272, 11270,     0,  8192, 10240, 11264, 
+        0,  8192, 10240, 11264, 11272,     0,  8192, 10240, 
+    11264, 11272,     0,  8192, 10240, 11264, 11272, 11274, 
+        0,  8192, 10240, 11264, 11272,     0,  8192, 10240, 
+    11264, 11280, 11276,     0,  8192, 10240, 11264, 11280, 
+    11276,     0,  8192, 10240, 11264, 11280, 11281, 11278, 
+        0,  8192, 10240, 11264,     0,  8192, 10240, 11264, 
+    11280,     0,  8192, 10240, 11264, 11280,     0,  8192, 
+    10240, 11264, 11280, 11282,     0,  8192, 10240, 11264, 
+    11280,     0,  8192, 10240, 11264, 11280, 11284,     0, 
+     8192, 10240, 11264, 11280, 11284,     0,  8192, 10240, 
+    11264, 11280, 11288, 11286,     0,  8192, 10240, 11264, 
+    11280,     0,  8192, 10240, 11264, 11296, 11288,     0, 
+     8192, 10240, 11264, 11296, 11288,     0,  8192, 10240, 
+    11264, 11296, 11288, 11290,     0,  8192, 10240, 11264, 
+    11296, 11288,     0,  8192, 10240, 11264, 11296, 11297, 
+    11292,     0,  8192, 10240, 11264, 11296, 11297, 11292, 
+        0,  8192, 10240, 11264, 11296, 11297, 11292, 11294, 
+        0,  8192, 10240, 11264,     0,  8192, 10240, 11264, 
+    11296,     0,  8192, 10240, 11264, 11296,     0,  8192, 
+    10240, 11264, 11296, 11298,     0,  8192, 10240, 11264, 
+    11296,     0,  8192, 10240, 11264, 11296, 11300,     0, 
+     8192, 10240, 11264, 11296, 11300,     0,  8192, 10240, 
+    11264, 11296, 11304, 11302,     0,  8192, 10240, 11264, 
+    11296,     0,  8192, 10240, 11264, 11296, 11304,     0, 
+     8192, 10240, 11264, 11296, 11304,     0,  8192, 10240, 
+    11264, 11296, 11304, 11306,     0,  8192, 10240, 11264, 
+    11296, 11304,     0,  8192, 10240, 11264, 11296, 11312, 
+    11308,     0,  8192, 10240, 11264, 11296, 11312, 11308, 
+        0,  8192, 10240, 11264, 11296, 11312, 11313, 11310, 
+        0,  8192, 10240, 11264, 11296,     0,  8192, 10240, 
+    11264, 11328, 11312,     0,  8192, 10240, 11264, 11328, 
+    11312,     0,  8192, 10240, 11264, 11328, 11312, 11314, 
+        0,  8192, 10240, 11264, 11328, 11312,     0,  8192, 
+    10240, 11264, 11328, 11312, 11316,     0,  8192, 10240, 
+    11264, 11328, 11312, 11316,     0,  8192, 10240, 11264, 
+    11328, 11312, 11320, 11318,     0,  8192, 10240, 11264, 
+    11328, 11312,     0,  8192, 10240, 11264, 11328, 11329, 
+    11320,     0,  8192, 10240, 11264, 11328, 11329, 11320, 
+        0,  8192, 10240, 11264, 11328, 11329, 11320, 11322, 
+        0,  8192, 10240, 11264, 11328, 11329, 11320,     0, 
+     8192, 10240, 11264, 11328, 11329, 11320, 11324,     0, 
+     8192, 10240, 11264, 11328, 11329, 11331, 11324,     0, 
+     8192, 10240, 11264, 11328, 11329, 11331, 11324, 11326, 
+        0,  8192, 10240, 11264,     0,  8192, 10240, 11264, 
+    11328,     0,  8192, 10240, 11264, 11328,     0,  8192, 
+    10240, 11264, 11328, 11330,     0,  8192, 10240, 11264, 
+    11328,     0,  8192, 10240, 11264, 11328, 11332,     0, 
+     8192, 10240, 11264, 11328, 11332,     0,  8192, 10240, 
+    11264, 11328, 11336, 11334,     0,  8192, 10240, 11264, 
+    11328,     0,  8192, 10240, 11264, 11328, 11336,     0, 
+     8192, 10240, 11264, 11328, 11336,     0,  8192, 10240, 
+    11264, 11328, 11336, 11338,     0,  8192, 10240, 11264, 
+    11328, 11336,     0,  8192, 10240, 11264, 11328, 11344, 
+    11340,     0,  8192, 10240, 11264, 11328, 11344, 11340, 
+        0,  8192, 10240, 11264, 11328, 11344, 11345, 11342, 
+        0,  8192, 10240, 11264, 11328,     0,  8192, 10240, 
+    11264, 11328, 11344,     0,  8192, 10240, 11264, 11328, 
+    11344,     0,  8192, 10240, 11264, 11328, 11344, 11346, 
+        0,  8192, 10240, 11264, 11328, 11344,     0,  8192, 
+    10240, 11264, 11328, 11344, 11348,     0,  8192, 10240, 
+    11264, 11328, 11344, 11348,     0,  8192, 10240, 11264, 
+    11328, 11344, 11352, 11350,     0,  8192, 10240, 11264, 
+    11328, 11344,     0,  8192, 10240, 11264, 11328, 11360, 
+    11352,     0,  8192, 10240, 11264, 11328, 11360, 11352, 
+        0,  8192, 10240, 11264, 11328, 11360, 11352, 11354, 
+        0,  8192, 10240, 11264, 11328, 11360, 11352,     0, 
+     8192, 10240, 11264, 11328, 11360, 11361, 11356,     0, 
+     8192, 10240, 11264, 11328, 11360, 11361, 11356,     0, 
+     8192, 10240, 11264, 11328, 11360, 11361, 11356, 11358, 
+        0,  8192, 10240, 11264, 11328,     0,  8192, 10240, 
+    11264, 11392, 11360,     0,  8192, 10240, 11264, 11392, 
+    11360,     0,  8192, 10240, 11264, 11392, 11360, 11362, 
+        0,  8192, 10240, 11264, 11392, 11360,     0,  8192, 
+    10240, 11264, 11392, 11360, 11364,     0,  8192, 10240, 
+    11264, 11392, 11360, 11364,     0,  8192, 10240, 11264, 
+    11392, 11360, 11368, 11366,     0,  8192, 10240, 11264, 
+    11392, 11360,     0,  8192, 10240, 11264, 11392, 11360, 
+    11368,     0,  8192, 10240, 11264, 11392, 11360, 11368, 
+        0,  8192, 10240, 11264, 11392, 11360, 11368, 11370, 
+        0,  8192, 10240, 11264, 11392, 11360, 11368,     0, 
+     8192, 10240, 11264, 11392, 11360, 11376, 11372,     0, 
+     8192, 10240, 11264, 11392, 11360, 11376, 11372,     0, 
+     8192, 10240, 11264, 11392, 11360, 11376, 11377, 11374, 
+        0,  8192, 10240, 11264, 11392, 11360,     0,  8192, 
+    10240, 11264, 11392, 11393, 11376,     0,  8192, 10240, 
+    11264, 11392, 11393, 11376,     0,  8192, 10240, 11264, 
+    11392, 11393, 11376, 11378,     0,  8192, 10240, 11264, 
+    11392, 11393, 11376,     0,  8192, 10240, 11264, 11392, 
+    11393, 11376, 11380,     0,  8192, 10240, 11264, 11392, 
+    11393, 11376, 11380,     0,  8192, 10240, 11264, 11392, 
+    11393, 11376, 11384, 11382,     0,  8192, 10240, 11264, 
+    11392, 11393, 11376,     0,  8192, 10240, 11264, 11392, 
+    11393, 11376, 11384,     0,  8192, 10240, 11264, 11392, 
+    11393, 11395, 11384,     0,  8192, 10240, 11264, 11392, 
+    11393, 11395, 11384, 11386,     0,  8192, 10240, 11264, 
+    11392, 11393, 11395, 11384,     0,  8192, 10240, 11264, 
+    11392, 11393, 11395, 11384, 11388,     0,  8192, 10240, 
+    11264, 11392, 11393, 11395, 11384, 11388,     0,  8192, 
+    10240, 11264, 11392, 11393, 11395, 11384, 11388, 11390, 
+        0,  8192, 10240, 11264,     0,  8192, 10240, 11264, 
+    11392,     0,  8192, 10240, 11264, 11392,     0,  8192, 
+    10240, 11264, 11392, 11394,     0,  8192, 10240, 11264, 
+    11392,     0,  8192, 10240, 11264, 11392, 11396,     0, 
+     8192, 10240, 11264, 11392, 11396,     0,  8192, 10240, 
+    11264, 11392, 11400, 11398,     0,  8192, 10240, 11264, 
+    11392,     0,  8192, 10240, 11264, 11392, 11400,     0, 
+     8192, 10240, 11264, 11392, 11400,     0,  8192, 10240, 
+    11264, 11392, 11400, 11402,     0,  8192, 10240, 11264, 
+    11392, 11400,     0,  8192, 10240, 11264, 11392, 11408, 
+    11404,     0,  8192, 10240, 11264, 11392, 11408, 11404, 
+        0,  8192, 10240, 11264, 11392, 11408, 11409, 11406, 
+        0,  8192, 10240, 11264, 11392,     0,  8192, 10240, 
+    11264, 11392, 11408,     0,  8192, 10240, 11264, 11392, 
+    11408,     0,  8192, 10240, 11264, 11392, 11408, 11410, 
+        0,  8192, 10240, 11264, 11392, 11408,     0,  8192, 
+    10240, 11264, 11392, 11408, 11412,     0,  8192, 10240, 
+    11264, 11392, 11408, 11412,     0,  8192, 10240, 11264, 
+    11392, 11408, 11416, 11414,     0,  8192, 10240, 11264, 
+    11392, 11408,     0,  8192, 10240, 11264, 11392, 11424, 
+    11416,     0,  8192, 10240, 11264, 11392, 11424, 11416, 
+        0,  8192, 10240, 11264, 11392, 11424, 11416, 11418, 
+        0,  8192, 10240, 11264, 11392, 11424, 11416,     0, 
+     8192, 10240, 11264, 11392, 11424, 11425, 11420,     0, 
+     8192, 10240, 11264, 11392, 11424, 11425, 11420,     0, 
+     8192, 10240, 11264, 11392, 11424, 11425, 11420, 11422, 
+        0,  8192, 10240, 11264, 11392,     0,  8192, 10240, 
+    11264, 11392, 11424,     0,  8192, 10240, 11264, 11392, 
+    11424,     0,  8192, 10240, 11264, 11392, 11424, 11426, 
+        0,  8192, 10240, 11264, 11392, 11424,     0,  8192, 
+    10240, 11264, 11392, 11424, 11428,     0,  8192, 10240, 
+    11264, 11392, 11424, 11428,     0,  8192, 10240, 11264, 
+    11392, 11424, 11432, 11430,     0,  8192, 10240, 11264, 
+    11392, 11424,     0,  8192, 10240, 11264, 11392, 11424, 
+    11432,     0,  8192, 10240, 11264, 11392, 11424, 11432, 
+        0,  8192, 10240, 11264, 11392, 11424, 11432, 11434, 
+        0,  8192, 10240, 11264, 11392, 11424, 11432,     0, 
+     8192, 10240, 11264, 11392, 11424, 11440, 11436,     0, 
+     8192, 10240, 11264, 11392, 11424, 11440, 11436,     0, 
+     8192, 10240, 11264, 11392, 11424, 11440, 11441, 11438, 
+        0,  8192, 10240, 11264, 11392, 11424,     0,  8192, 
+    10240, 11264, 11392, 11456, 11440,     0,  8192, 10240, 
+    11264, 11392, 11456, 11440,     0,  8192, 10240, 11264, 
+    11392, 11456, 11440, 11442,     0,  8192, 10240, 11264, 
+    11392, 11456, 11440,     0,  8192, 10240, 11264, 11392, 
+    11456, 11440, 11444,     0,  8192, 10240, 11264, 11392, 
+    11456, 11440, 11444,     0,  8192, 10240, 11264, 11392, 
+    11456, 11440, 11448, 11446,     0,  8192, 10240, 11264, 
+    11392, 11456, 11440,     0,  8192, 10240, 11264, 11392, 
+    11456, 11457, 11448,     0,  8192, 10240, 11264, 11392, 
+    11456, 11457, 11448,     0,  8192, 10240, 11264, 11392, 
+    11456, 11457, 11448, 11450,     0,  8192, 10240, 11264, 
+    11392, 11456, 11457, 11448,     0,  8192, 10240, 11264, 
+    11392, 11456, 11457, 11448, 11452,     0,  8192, 10240, 
+    11264, 11392, 11456, 11457, 11459, 11452,     0,  8192, 
+    10240, 11264, 11392, 11456, 11457, 11459, 11452, 11454, 
+        0,  8192, 10240, 11264, 11392,     0,  8192, 10240, 
+    11264, 11520, 11456,     0,  8192, 10240, 11264, 11520, 
+    11456,     0,  8192, 10240, 11264, 11520, 11456, 11458, 
+        0,  8192, 10240, 11264, 11520, 11456,     0,  8192, 
+    10240, 11264, 11520, 11456, 11460,     0,  8192, 10240, 
+    11264, 11520, 11456, 11460,     0,  8192, 10240, 11264, 
+    11520, 11456, 11464, 11462,     0,  8192, 10240, 11264, 
+    11520, 11456,     0,  8192, 10240, 11264, 11520, 11456, 
+    11464,     0,  8192, 10240, 11264, 11520, 11456, 11464, 
+        0,  8192, 10240, 11264, 11520, 11456, 11464, 11466, 
+        0,  8192, 10240, 11264, 11520, 11456, 11464,     0, 
+     8192, 10240, 11264, 11520, 11456, 11472, 11468,     0, 
+     8192, 10240, 11264, 11520, 11456, 11472, 11468,     0, 
+     8192, 10240, 11264, 11520, 11456, 11472, 11473, 11470, 
+        0,  8192, 10240, 11264, 11520, 11456,     0,  8192, 
+    10240, 11264, 11520, 11456, 11472,     0,  8192, 10240, 
+    11264, 11520, 11456, 11472,     0,  8192, 10240, 11264, 
+    11520, 11456, 11472, 11474,     0,  8192, 10240, 11264, 
+    11520, 11456, 11472,     0,  8192, 10240, 11264, 11520, 
+    11456, 11472, 11476,     0,  8192, 10240, 11264, 11520, 
+    11456, 11472, 11476,     0,  8192, 10240, 11264, 11520, 
+    11456, 11472, 11480, 11478,     0,  8192, 10240, 11264, 
+    11520, 11456, 11472,     0,  8192, 10240, 11264, 11520, 
+    11456, 11488, 11480,     0,  8192, 10240, 11264, 11520, 
+    11456, 11488, 11480,     0,  8192, 10240, 11264, 11520, 
+    11456, 11488, 11480, 11482,     0,  8192, 10240, 11264, 
+    11520, 11456, 11488, 11480,     0,  8192, 10240, 11264, 
+    11520, 11456, 11488, 11489, 11484,     0,  8192, 10240, 
+    11264, 11520, 11456, 11488, 11489, 11484,     0,  8192, 
+    10240, 11264, 11520, 11456, 11488, 11489, 11484, 11486, 
+        0,  8192, 10240, 11264, 11520, 11456,     0,  8192, 
+    10240, 11264, 11520, 11521, 11488,     0,  8192, 10240, 
+    11264, 11520, 11521, 11488,     0,  8192, 10240, 11264, 
+    11520, 11521, 11488, 11490,     0,  8192, 10240, 11264, 
+    11520, 11521, 11488,     0,  8192, 10240, 11264, 11520, 
+    11521, 11488, 11492,     0,  8192, 10240, 11264, 11520, 
+    11521, 11488, 11492,     0,  8192, 10240, 11264, 11520, 
+    11521, 11488, 11496, 11494,     0,  8192, 10240, 11264, 
+    11520, 11521, 11488,     0,  8192, 10240, 11264, 11520, 
+    11521, 11488, 11496,     0,  8192, 10240, 11264, 11520, 
+    11521, 11488, 11496,     0,  8192, 10240, 11264, 11520, 
+    11521, 11488, 11496, 11498,     0,  8192, 10240, 11264, 
+    11520, 11521, 11488, 11496,     0,  8192, 10240, 11264, 
+    11520, 11521, 11488, 11504, 11500,     0,  8192, 10240, 
+    11264, 11520, 11521, 11488, 11504, 11500,     0,  8192, 
+    10240, 11264, 11520, 11521, 11488, 11504, 11505, 11502, 
+        0,  8192, 10240, 11264, 11520, 11521, 11488,     0, 
+     8192, 10240, 11264, 11520, 11521, 11488, 11504,     0, 
+     8192, 10240, 11264, 11520, 11521, 11523, 11504,     0, 
+     8192, 10240, 11264, 11520, 11521, 11523, 11504, 11506, 
+        0,  8192, 10240, 11264, 11520, 11521, 11523, 11504, 
+        0,  8192, 10240, 11264, 11520, 11521, 11523, 11504, 
+    11508,     0,  8192, 10240, 11264, 11520, 11521, 11523, 
+    11504, 11508,     0,  8192, 10240, 11264, 11520, 11521, 
+    11523, 11504, 11512, 11510,     0,  8192, 10240, 11264, 
+    11520, 11521, 11523, 11504,     0,  8192, 10240, 11264, 
+    11520, 11521, 11523, 11504, 11512,     0,  8192, 10240, 
+    11264, 11520, 11521, 11523, 11504, 11512,     0,  8192, 
+    10240, 11264, 11520, 11521, 11523, 11504, 11512, 11514, 
+        0,  8192, 10240, 11264, 11520, 11521, 11523, 11527, 
+    11512,     0,  8192, 10240, 11264, 11520, 11521, 11523, 
+    11527, 11512, 11516,     0,  8192, 10240, 11264, 11520, 
+    11521, 11523, 11527, 11512, 11516,     0,  8192, 10240, 
+    11264, 11520, 11521, 11523, 11527, 11512, 11516, 11518, 
+        0,  8192, 10240, 11264,     0,  8192, 12288, 11264, 
+    11520,     0,  8192, 12288, 11264, 11520,     0,  8192, 
+    12288, 11264, 11520, 11522,     0,  8192, 12288, 11264, 
+    11520,     0,  8192, 12288, 11264, 11520, 11524,     0, 
+     8192, 12288, 11264, 11520, 11524,     0,  8192, 12288, 
+    11264, 11520, 11528, 11526,     0,  8192, 12288, 11264, 
+    11520,     0,  8192, 12288, 11264, 11520, 11528,     0, 
+     8192, 12288, 11264, 11520, 11528,     0,  8192, 12288, 
+    11264, 11520, 11528, 11530,     0,  8192, 12288, 11264, 
+    11520, 11528,     0,  8192, 12288, 11264, 11520, 11536, 
+    11532,     0,  8192, 12288, 11264, 11520, 11536, 11532, 
+        0,  8192, 12288, 11264, 11520, 11536, 11537, 11534, 
+        0,  8192, 12288, 11264, 11520,     0,  8192, 12288, 
+    11264, 11520, 11536,     0,  8192, 12288, 11264, 11520, 
+    11536,     0,  8192, 12288, 11264, 11520, 11536, 11538, 
+        0,  8192, 12288, 11264, 11520, 11536,     0,  8192, 
+    12288, 11264, 11520, 11536, 11540,     0,  8192, 12288, 
+    11264, 11520, 11536, 11540,     0,  8192, 12288, 11264, 
+    11520, 11536, 11544, 11542,     0,  8192, 12288, 11264, 
+    11520, 11536,     0,  8192, 12288, 11264, 11520, 11552, 
+    11544,     0,  8192, 12288, 11264, 11520, 11552, 11544, 
+        0,  8192, 12288, 11264, 11520, 11552, 11544, 11546, 
+        0,  8192, 12288, 11264, 11520, 11552, 11544,     0, 
+     8192, 12288, 11264, 11520, 11552, 11553, 11548,     0, 
+     8192, 12288, 11264, 11520, 11552, 11553, 11548,     0, 
+     8192, 12288, 11264, 11520, 11552, 11553, 11548, 11550, 
+        0,  8192, 12288, 11264, 11520,     0,  8192, 12288, 
+    11264, 11520, 11552,     0,  8192, 12288, 11264, 11520, 
+    11552,     0,  8192, 12288, 11264, 11520, 11552, 11554, 
+        0,  8192, 12288, 11264, 11520, 11552,     0,  8192, 
+    12288, 11264, 11520, 11552, 11556,     0,  8192, 12288, 
+    11264, 11520, 11552, 11556,     0,  8192, 12288, 11264, 
+    11520, 11552, 11560, 11558,     0,  8192, 12288, 11264, 
+    11520, 11552,     0,  8192, 12288, 11264, 11520, 11552, 
+    11560,     0,  8192, 12288, 11264, 11520, 11552, 11560, 
+        0,  8192, 12288, 11264, 11520, 11552, 11560, 11562, 
+        0,  8192, 12288, 11264, 11520, 11552, 11560,     0, 
+     8192, 12288, 11264, 11520, 11552, 11568, 11564,     0, 
+     8192, 12288, 11264, 11520, 11552, 11568, 11564,     0, 
+     8192, 12288, 11264, 11520, 11552, 11568, 11569, 11566, 
+        0,  8192, 12288, 11264, 11520, 11552,     0,  8192, 
+    12288, 11264, 11520, 11584, 11568,     0,  8192, 12288, 
+    11264, 11520, 11584, 11568,     0,  8192, 12288, 11264, 
+    11520, 11584, 11568, 11570,     0,  8192, 12288, 11264, 
+    11520, 11584, 11568,     0,  8192, 12288, 11264, 11520, 
+    11584, 11568, 11572,     0,  8192, 12288, 11264, 11520, 
+    11584, 11568, 11572,     0,  8192, 12288, 11264, 11520, 
+    11584, 11568, 11576, 11574,     0,  8192, 12288, 11264, 
+    11520, 11584, 11568,     0,  8192, 12288, 11264, 11520, 
+    11584, 11585, 11576,     0,  8192, 12288, 11264, 11520, 
+    11584, 11585, 11576,     0,  8192, 12288, 11264, 11520, 
+    11584, 11585, 11576, 11578,     0,  8192, 12288, 11264, 
+    11520, 11584, 11585, 11576,     0,  8192, 12288, 11264, 
+    11520, 11584, 11585, 11576, 11580,     0,  8192, 12288, 
+    11264, 11520, 11584, 11585, 11587, 11580,     0,  8192, 
+    12288, 11264, 11520, 11584, 11585, 11587, 11580, 11582, 
+        0,  8192, 12288, 11264, 11520,     0,  8192, 12288, 
+    11264, 11520, 11584,     0,  8192, 12288, 11264, 11520, 
+    11584,     0,  8192, 12288, 11264, 11520, 11584, 11586, 
+        0,  8192, 12288, 11264, 11520, 11584,     0,  8192, 
+    12288, 11264, 11520, 11584, 11588,     0,  8192, 12288, 
+    11264, 11520, 11584, 11588,     0,  8192, 12288, 11264, 
+    11520, 11584, 11592, 11590,     0,  8192, 12288, 11264, 
+    11520, 11584,     0,  8192, 12288, 11264, 11520, 11584, 
+    11592,     0,  8192, 12288, 11264, 11520, 11584, 11592, 
+        0,  8192, 12288, 11264, 11520, 11584, 11592, 11594, 
+        0,  8192, 12288, 11264, 11520, 11584, 11592,     0, 
+     8192, 12288, 11264, 11520, 11584, 11600, 11596,     0, 
+     8192, 12288, 11264, 11520, 11584, 11600, 11596,     0, 
+     8192, 12288, 11264, 11520, 11584, 11600, 11601, 11598, 
+        0,  8192, 12288, 11264, 11520, 11584,     0,  8192, 
+    12288, 11264, 11520, 11584, 11600,     0,  8192, 12288, 
+    11264, 11520, 11584, 11600,     0,  8192, 12288, 11264, 
+    11520, 11584, 11600, 11602,     0,  8192, 12288, 11264, 
+    11520, 11584, 11600,     0,  8192, 12288, 11264, 11520, 
+    11584, 11600, 11604,     0,  8192, 12288, 11264, 11520, 
+    11584, 11600, 11604,     0,  8192, 12288, 11264, 11520, 
+    11584, 11600, 11608, 11606,     0,  8192, 12288, 11264, 
+    11520, 11584, 11600,     0,  8192, 12288, 11264, 11520, 
+    11584, 11616, 11608,     0,  8192, 12288, 11264, 11520, 
+    11584, 11616, 11608,     0,  8192, 12288, 11264, 11520, 
+    11584, 11616, 11608, 11610,     0,  8192, 12288, 11264, 
+    11520, 11584, 11616, 11608,     0,  8192, 12288, 11264, 
+    11520, 11584, 11616, 11617, 11612,     0,  8192, 12288, 
+    11264, 11520, 11584, 11616, 11617, 11612,     0,  8192, 
+    12288, 11264, 11520, 11584, 11616, 11617, 11612, 11614, 
+        0,  8192, 12288, 11264, 11520, 11584,     0,  8192, 
+    12288, 11264, 11520, 11648, 11616,     0,  8192, 12288, 
+    11264, 11520, 11648, 11616,     0,  8192, 12288, 11264, 
+    11520, 11648, 11616, 11618,     0,  8192, 12288, 11264, 
+    11520, 11648, 11616,     0,  8192, 12288, 11264, 11520, 
+    11648, 11616, 11620,     0,  8192, 12288, 11264, 11520, 
+    11648, 11616, 11620,     0,  8192, 12288, 11264, 11520, 
+    11648, 11616, 11624, 11622,     0,  8192, 12288, 11264, 
+    11520, 11648, 11616,     0,  8192, 12288, 11264, 11520, 
+    11648, 11616, 11624,     0,  8192, 12288, 11264, 11520, 
+    11648, 11616, 11624,     0,  8192, 12288, 11264, 11520, 
+    11648, 11616, 11624, 11626,     0,  8192, 12288, 11264, 
+    11520, 11648, 11616, 11624,     0,  8192, 12288, 11264, 
+    11520, 11648, 11616, 11632, 11628,     0,  8192, 12288, 
+    11264, 11520, 11648, 11616, 11632, 11628,     0,  8192, 
+    12288, 11264, 11520, 11648, 11616, 11632, 11633, 11630, 
+        0,  8192, 12288, 11264, 11520, 11648, 11616,     0, 
+     8192, 12288, 11264, 11520, 11648, 11649, 11632,     0, 
+     8192, 12288, 11264, 11520, 11648, 11649, 11632,     0, 
+     8192, 12288, 11264, 11520, 11648, 11649, 11632, 11634, 
+        0,  8192, 12288, 11264, 11520, 11648, 11649, 11632, 
+        0,  8192, 12288, 11264, 11520, 11648, 11649, 11632, 
+    11636,     0,  8192, 12288, 11264, 11520, 11648, 11649, 
+    11632, 11636,     0,  8192, 12288, 11264, 11520, 11648, 
+    11649, 11632, 11640, 11638,     0,  8192, 12288, 11264, 
+    11520, 11648, 11649, 11632,     0,  8192, 12288, 11264, 
+    11520, 11648, 11649, 11632, 11640,     0,  8192, 12288, 
+    11264, 11520, 11648, 11649, 11651, 11640,     0,  8192, 
+    12288, 11264, 11520, 11648, 11649, 11651, 11640, 11642, 
+        0,  8192, 12288, 11264, 11520, 11648, 11649, 11651, 
+    11640,     0,  8192, 12288, 11264, 11520, 11648, 11649, 
+    11651, 11640, 11644,     0,  8192, 12288, 11264, 11520, 
+    11648, 11649, 11651, 11640, 11644,     0,  8192, 12288, 
+    11264, 11520, 11648, 11649, 11651, 11640, 11644, 11646, 
+        0,  8192, 12288, 11264, 11520,     0,  8192, 12288, 
+    11264, 11776, 11648,     0,  8192, 12288, 11264, 11776, 
+    11648,     0,  8192, 12288, 11264, 11776, 11648, 11650, 
+        0,  8192, 12288, 11264, 11776, 11648,     0,  8192, 
+    12288, 11264, 11776, 11648, 11652,     0,  8192, 12288, 
+    11264, 11776, 11648, 11652,     0,  8192, 12288, 11264, 
+    11776, 11648, 11656, 11654,     0,  8192, 12288, 11264, 
+    11776, 11648,     0,  8192, 12288, 11264, 11776, 11648, 
+    11656,     0,  8192, 12288, 11264, 11776, 11648, 11656, 
+        0,  8192, 12288, 11264, 11776, 11648, 11656, 11658, 
+        0,  8192, 12288, 11264, 11776, 11648, 11656,     0, 
+     8192, 12288, 11264, 11776, 11648, 11664, 11660,     0, 
+     8192, 12288, 11264, 11776, 11648, 11664, 11660,     0, 
+     8192, 12288, 11264, 11776, 11648, 11664, 11665, 11662, 
+        0,  8192, 12288, 11264, 11776, 11648,     0,  8192, 
+    12288, 11264, 11776, 11648, 11664,     0,  8192, 12288, 
+    11264, 11776, 11648, 11664,     0,  8192, 12288, 11264, 
+    11776, 11648, 11664, 11666,     0,  8192, 12288, 11264, 
+    11776, 11648, 11664,     0,  8192, 12288, 11264, 11776, 
+    11648, 11664, 11668,     0,  8192, 12288, 11264, 11776, 
+    11648, 11664, 11668,     0,  8192, 12288, 11264, 11776, 
+    11648, 11664, 11672, 11670,     0,  8192, 12288, 11264, 
+    11776, 11648, 11664,     0,  8192, 12288, 11264, 11776, 
+    11648, 11680, 11672,     0,  8192, 12288, 11264, 11776, 
+    11648, 11680, 11672,     0,  8192, 12288, 11264, 11776, 
+    11648, 11680, 11672, 11674,     0,  8192, 12288, 11264, 
+    11776, 11648, 11680, 11672,     0,  8192, 12288, 11264, 
+    11776, 11648, 11680, 11681, 11676,     0,  8192, 12288, 
+    11264, 11776, 11648, 11680, 11681, 11676,     0,  8192, 
+    12288, 11264, 11776, 11648, 11680, 11681, 11676, 11678, 
+        0,  8192, 12288, 11264, 11776, 11648,     0,  8192, 
+    12288, 11264, 11776, 11648, 11680,     0,  8192, 12288, 
+    11264, 11776, 11648, 11680,     0,  8192, 12288, 11264, 
+    11776, 11648, 11680, 11682,     0,  8192, 12288, 11264, 
+    11776, 11648, 11680,     0,  8192, 12288, 11264, 11776, 
+    11648, 11680, 11684,     0,  8192, 12288, 11264, 11776, 
+    11648, 11680, 11684,     0,  8192, 12288, 11264, 11776, 
+    11648, 11680, 11688, 11686,     0,  8192, 12288, 11264, 
+    11776, 11648, 11680,     0,  8192, 12288, 11264, 11776, 
+    11648, 11680, 11688,     0,  8192, 12288, 11264, 11776, 
+    11648, 11680, 11688,     0,  8192, 12288, 11264, 11776, 
+    11648, 11680, 11688, 11690,     0,  8192, 12288, 11264, 
+    11776, 11648, 11680, 11688,     0,  8192, 12288, 11264, 
+    11776, 11648, 11680, 11696, 11692,     0,  8192, 12288, 
+    11264, 11776, 11648, 11680, 11696, 11692,     0,  8192, 
+    12288, 11264, 11776, 11648, 11680, 11696, 11697, 11694, 
+        0,  8192, 12288, 11264, 11776, 11648, 11680,     0, 
+     8192, 12288, 11264, 11776, 11648, 11712, 11696,     0, 
+     8192, 12288, 11264, 11776, 11648, 11712, 11696,     0, 
+     8192, 12288, 11264, 11776, 11648, 11712, 11696, 11698, 
+        0,  8192, 12288, 11264, 11776, 11648, 11712, 11696, 
+        0,  8192, 12288, 11264, 11776, 11648, 11712, 11696, 
+    11700,     0,  8192, 12288, 11264, 11776, 11648, 11712, 
+    11696, 11700,     0,  8192, 12288, 11264, 11776, 11648, 
+    11712, 11696, 11704, 11702,     0,  8192, 12288, 11264, 
+    11776, 11648, 11712, 11696,     0,  8192, 12288, 11264, 
+    11776, 11648, 11712, 11713, 11704,     0,  8192, 12288, 
+    11264, 11776, 11648, 11712, 11713, 11704,     0,  8192, 
+    12288, 11264, 11776, 11648, 11712, 11713, 11704, 11706, 
+        0,  8192, 12288, 11264, 11776, 11648, 11712, 11713, 
+    11704,     0,  8192, 12288, 11264, 11776, 11648, 11712, 
+    11713, 11704, 11708,     0,  8192, 12288, 11264, 11776, 
+    11648, 11712, 11713, 11715, 11708,     0,  8192, 12288, 
+    11264, 11776, 11648, 11712, 11713, 11715, 11708, 11710, 
+        0,  8192, 12288, 11264, 11776, 11648,     0,  8192, 
+    12288, 11264, 11776, 11777, 11712,     0,  8192, 12288, 
+    11264, 11776, 11777, 11712,     0,  8192, 12288, 11264, 
+    11776, 11777, 11712, 11714,     0,  8192, 12288, 11264, 
+    11776, 11777, 11712,     0,  8192, 12288, 11264, 11776, 
+    11777, 11712, 11716,     0,  8192, 12288, 11264, 11776, 
+    11777, 11712, 11716,     0,  8192, 12288, 11264, 11776, 
+    11777, 11712, 11720, 11718,     0,  8192, 12288, 11264, 
+    11776, 11777, 11712,     0,  8192, 12288, 11264, 11776, 
+    11777, 11712, 11720,     0,  8192, 12288, 11264, 11776, 
+    11777, 11712, 11720,     0,  8192, 12288, 11264, 11776, 
+    11777, 11712, 11720, 11722,     0,  8192, 12288, 11264, 
+    11776, 11777, 11712, 11720,     0,  8192, 12288, 11264, 
+    11776, 11777, 11712, 11728, 11724,     0,  8192, 12288, 
+    11264, 11776, 11777, 11712, 11728, 11724,     0,  8192, 
+    12288, 11264, 11776, 11777, 11712, 11728, 11729, 11726, 
+        0,  8192, 12288, 11264, 11776, 11777, 11712,     0, 
+     8192, 12288, 11264, 11776, 11777, 11712, 11728,     0, 
+     8192, 12288, 11264, 11776, 11777, 11712, 11728,     0, 
+     8192, 12288, 11264, 11776, 11777, 11712, 11728, 11730, 
+        0,  8192, 12288, 11264, 11776, 11777, 11712, 11728, 
+        0,  8192, 12288, 11264, 11776, 11777, 11712, 11728, 
+    11732,     0,  8192, 12288, 11264, 11776, 11777, 11712, 
+    11728, 11732,     0,  8192, 12288, 11264, 11776, 11777, 
+    11712, 11728, 11736, 11734,     0,  8192, 12288, 11264, 
+    11776, 11777, 11712, 11728,     0,  8192, 12288, 11264, 
+    11776, 11777, 11712, 11744, 11736,     0,  8192, 12288, 
+    11264, 11776, 11777, 11712, 11744, 11736,     0,  8192, 
+    12288, 11264, 11776, 11777, 11712, 11744, 11736, 11738, 
+        0,  8192, 12288, 11264, 11776, 11777, 11712, 11744, 
+    11736,     0,  8192, 12288, 11264, 11776, 11777, 11712, 
+    11744, 11745, 11740,     0,  8192, 12288, 11264, 11776, 
+    11777, 11712, 11744, 11745, 11740,     0,  8192, 12288, 
+    11264, 11776, 11777, 11712, 11744, 11745, 11740, 11742, 
+        0,  8192, 12288, 11264, 11776, 11777, 11712,     0, 
+     8192, 12288, 11264, 11776, 11777, 11712, 11744,     0, 
+     8192, 12288, 11264, 11776, 11777, 11779, 11744,     0, 
+     8192, 12288, 11264, 11776, 11777, 11779, 11744, 11746, 
+        0,  8192, 12288, 11264, 11776, 11777, 11779, 11744, 
+        0,  8192, 12288, 11264, 11776, 11777, 11779, 11744, 
+    11748,     0,  8192, 12288, 11264, 11776, 11777, 11779, 
+    11744, 11748,     0,  8192, 12288, 11264, 11776, 11777, 
+    11779, 11744, 11752, 11750,     0,  8192, 12288, 11264, 
+    11776, 11777, 11779, 11744,     0,  8192, 12288, 11264, 
+    11776, 11777, 11779, 11744, 11752,     0,  8192, 12288, 
+    11264, 11776, 11777, 11779, 11744, 11752,     0,  8192, 
+    12288, 11264, 11776, 11777, 11779, 11744, 11752, 11754, 
+        0,  8192, 12288, 11264, 11776, 11777, 11779, 11744, 
+    11752,     0,  8192, 12288, 11264, 11776, 11777, 11779, 
+    11744, 11760, 11756,     0,  8192, 12288, 11264, 11776, 
+    11777, 11779, 11744, 11760, 11756,     0,  8192, 12288, 
+    11264, 11776, 11777, 11779, 11744, 11760, 11761, 11758, 
+        0,  8192, 12288, 11264, 11776, 11777, 11779, 11744, 
+        0,  8192, 12288, 11264, 11776, 11777, 11779, 11744, 
+    11760,     0,  8192, 12288, 11264, 11776, 11777, 11779, 
+    11744, 11760,     0,  8192, 12288, 11264, 11776, 11777, 
+    11779, 11744, 11760, 11762,     0,  8192, 12288, 11264, 
+    11776, 11777, 11779, 11783, 11760,     0,  8192, 12288, 
+    11264, 11776, 11777, 11779, 11783, 11760, 11764,     0, 
+     8192, 12288, 11264, 11776, 11777, 11779, 11783, 11760, 
+    11764,     0,  8192, 12288, 11264, 11776, 11777, 11779, 
+    11783, 11760, 11768, 11766,     0,  8192, 12288, 11264, 
+    11776, 11777, 11779, 11783, 11760,     0,  8192, 12288, 
+    11264, 11776, 11777, 11779, 11783, 11760, 11768,     0, 
+     8192, 12288, 11264, 11776, 11777, 11779, 11783, 11760, 
+    11768,     0,  8192, 12288, 11264, 11776, 11777, 11779, 
+    11783, 11760, 11768, 11770,     0,  8192, 12288, 11264, 
+    11776, 11777, 11779, 11783, 11760, 11768,     0,  8192, 
+    12288, 11264, 11776, 11777, 11779, 11783, 11760, 11768, 
+    11772,     0,  8192, 12288, 11264, 11776, 11777, 11779, 
+    11783, 11760, 11768, 11772,     0,  8192, 12288, 11264, 
+    11776, 11777, 11779, 11783, 11760, 11768, 11772, 11774, 
+        0,  8192, 12288, 11264,     0,  8192, 12288, 11264, 
+    11776,     0,  8192, 12288, 12289, 11776,     0,  8192, 
+    12288, 12289, 11776, 11778,     0,  8192, 12288, 12289, 
+    11776,     0,  8192, 12288, 12289, 11776, 11780,     0, 
+     8192, 12288, 12289, 11776, 11780,     0,  8192, 12288, 
+    12289, 11776, 11784, 11782,     0,  8192, 12288, 12289, 
+    11776,     0,  8192, 12288, 12289, 11776, 11784,     0, 
+     8192, 12288, 12289, 11776, 11784,     0,  8192, 12288, 
+    12289, 11776, 11784, 11786,     0,  8192, 12288, 12289, 
+    11776, 11784,     0,  8192, 12288, 12289, 11776, 11792, 
+    11788,     0,  8192, 12288, 12289, 11776, 11792, 11788, 
+        0,  8192, 12288, 12289, 11776, 11792, 11793, 11790, 
+        0,  8192, 12288, 12289, 11776,     0,  8192, 12288, 
+    12289, 11776, 11792,     0,  8192, 12288, 12289, 11776, 
+    11792,     0,  8192, 12288, 12289, 11776, 11792, 11794, 
+        0,  8192, 12288, 12289, 11776, 11792,     0,  8192, 
+    12288, 12289, 11776, 11792, 11796,     0,  8192, 12288, 
+    12289, 11776, 11792, 11796,     0,  8192, 12288, 12289, 
+    11776, 11792, 11800, 11798,     0,  8192, 12288, 12289, 
+    11776, 11792,     0,  8192, 12288, 12289, 11776, 11808, 
+    11800,     0,  8192, 12288, 12289, 11776, 11808, 11800, 
+        0,  8192, 12288, 12289, 11776, 11808, 11800, 11802, 
+        0,  8192, 12288, 12289, 11776, 11808, 11800,     0, 
+     8192, 12288, 12289, 11776, 11808, 11809, 11804,     0, 
+     8192, 12288, 12289, 11776, 11808, 11809, 11804,     0, 
+     8192, 12288, 12289, 11776, 11808, 11809, 11804, 11806, 
+        0,  8192, 12288, 12289, 11776,     0,  8192, 12288, 
+    12289, 11776, 11808,     0,  8192, 12288, 12289, 11776, 
+    11808,     0,  8192, 12288, 12289, 11776, 11808, 11810, 
+        0,  8192, 12288, 12289, 11776, 11808,     0,  8192, 
+    12288, 12289, 11776, 11808, 11812,     0,  8192, 12288, 
+    12289, 11776, 11808, 11812,     0,  8192, 12288, 12289, 
+    11776, 11808, 11816, 11814,     0,  8192, 12288, 12289, 
+    11776, 11808,     0,  8192, 12288, 12289, 11776, 11808, 
+    11816,     0,  8192, 12288, 12289, 11776, 11808, 11816, 
+        0,  8192, 12288, 12289, 11776, 11808, 11816, 11818, 
+        0,  8192, 12288, 12289, 11776, 11808, 11816,     0, 
+     8192, 12288, 12289, 11776, 11808, 11824, 11820,     0, 
+     8192, 12288, 12289, 11776, 11808, 11824, 11820,     0, 
+     8192, 12288, 12289, 11776, 11808, 11824, 11825, 11822, 
+        0,  8192, 12288, 12289, 11776, 11808,     0,  8192, 
+    12288, 12289, 11776, 11840, 11824,     0,  8192, 12288, 
+    12289, 11776, 11840, 11824,     0,  8192, 12288, 12289, 
+    11776, 11840, 11824, 11826,     0,  8192, 12288, 12289, 
+    11776, 11840, 11824,     0,  8192, 12288, 12289, 11776, 
+    11840, 11824, 11828,     0,  8192, 12288, 12289, 11776, 
+    11840, 11824, 11828,     0,  8192, 12288, 12289, 11776, 
+    11840, 11824, 11832, 11830,     0,  8192, 12288, 12289, 
+    11776, 11840, 11824,     0,  8192, 12288, 12289, 11776, 
+    11840, 11841, 11832,     0,  8192, 12288, 12289, 11776, 
+    11840, 11841, 11832,     0,  8192, 12288, 12289, 11776, 
+    11840, 11841, 11832, 11834,     0,  8192, 12288, 12289, 
+    11776, 11840, 11841, 11832,     0,  8192, 12288, 12289, 
+    11776, 11840, 11841, 11832, 11836,     0,  8192, 12288, 
+    12289, 11776, 11840, 11841, 11843, 11836,     0,  8192, 
+    12288, 12289, 11776, 11840, 11841, 11843, 11836, 11838, 
+        0,  8192, 12288, 12289, 11776,     0,  8192, 12288, 
+    12289, 11776, 11840,     0,  8192, 12288, 12289, 11776, 
+    11840,     0,  8192, 12288, 12289, 11776, 11840, 11842, 
+        0,  8192, 12288, 12289, 11776, 11840,     0,  8192, 
+    12288, 12289, 11776, 11840, 11844,     0,  8192, 12288, 
+    12289, 11776, 11840, 11844,     0,  8192, 12288, 12289, 
+    11776, 11840, 11848, 11846,     0,  8192, 12288, 12289, 
+    11776, 11840,     0,  8192, 12288, 12289, 11776, 11840, 
+    11848,     0,  8192, 12288, 12289, 11776, 11840, 11848, 
+        0,  8192, 12288, 12289, 11776, 11840, 11848, 11850, 
+        0,  8192, 12288, 12289, 11776, 11840, 11848,     0, 
+     8192, 12288, 12289, 11776, 11840, 11856, 11852,     0, 
+     8192, 12288, 12289, 11776, 11840, 11856, 11852,     0, 
+     8192, 12288, 12289, 11776, 11840, 11856, 11857, 11854, 
+        0,  8192, 12288, 12289, 11776, 11840,     0,  8192, 
+    12288, 12289, 11776, 11840, 11856,     0,  8192, 12288, 
+    12289, 11776, 11840, 11856,     0,  8192, 12288, 12289, 
+    11776, 11840, 11856, 11858,     0,  8192, 12288, 12289, 
+    11776, 11840, 11856,     0,  8192, 12288, 12289, 11776, 
+    11840, 11856, 11860,     0,  8192, 12288, 12289, 11776, 
+    11840, 11856, 11860,     0,  8192, 12288, 12289, 11776, 
+    11840, 11856, 11864, 11862,     0,  8192, 12288, 12289, 
+    11776, 11840, 11856,     0,  8192, 12288, 12289, 11776, 
+    11840, 11872, 11864,     0,  8192, 12288, 12289, 11776, 
+    11840, 11872, 11864,     0,  8192, 12288, 12289, 11776, 
+    11840, 11872, 11864, 11866,     0,  8192, 12288, 12289, 
+    11776, 11840, 11872, 11864,     0,  8192, 12288, 12289, 
+    11776, 11840, 11872, 11873, 11868,     0,  8192, 12288, 
+    12289, 11776, 11840, 11872, 11873, 11868,     0,  8192, 
+    12288, 12289, 11776, 11840, 11872, 11873, 11868, 11870, 
+        0,  8192, 12288, 12289, 11776, 11840,     0,  8192, 
+    12288, 12289, 11776, 11904, 11872,     0,  8192, 12288, 
+    12289, 11776, 11904, 11872,     0,  8192, 12288, 12289, 
+    11776, 11904, 11872, 11874,     0,  8192, 12288, 12289, 
+    11776, 11904, 11872,     0,  8192, 12288, 12289, 11776, 
+    11904, 11872, 11876,     0,  8192, 12288, 12289, 11776, 
+    11904, 11872, 11876,     0,  8192, 12288, 12289, 11776, 
+    11904, 11872, 11880, 11878,     0,  8192, 12288, 12289, 
+    11776, 11904, 11872,     0,  8192, 12288, 12289, 11776, 
+    11904, 11872, 11880,     0,  8192, 12288, 12289, 11776, 
+    11904, 11872, 11880,     0,  8192, 12288, 12289, 11776, 
+    11904, 11872, 11880, 11882,     0,  8192, 12288, 12289, 
+    11776, 11904, 11872, 11880,     0,  8192, 12288, 12289, 
+    11776, 11904, 11872, 11888, 11884,     0,  8192, 12288, 
+    12289, 11776, 11904, 11872, 11888, 11884,     0,  8192, 
+    12288, 12289, 11776, 11904, 11872, 11888, 11889, 11886, 
+        0,  8192, 12288, 12289, 11776, 11904, 11872,     0, 
+     8192, 12288, 12289, 11776, 11904, 11905, 11888,     0, 
+     8192, 12288, 12289, 11776, 11904, 11905, 11888,     0, 
+     8192, 12288, 12289, 11776, 11904, 11905, 11888, 11890, 
+        0,  8192, 12288, 12289, 11776, 11904, 11905, 11888, 
+        0,  8192, 12288, 12289, 11776, 11904, 11905, 11888, 
+    11892,     0,  8192, 12288, 12289, 11776, 11904, 11905, 
+    11888, 11892,     0,  8192, 12288, 12289, 11776, 11904, 
+    11905, 11888, 11896, 11894,     0,  8192, 12288, 12289, 
+    11776, 11904, 11905, 11888,     0,  8192, 12288, 12289, 
+    11776, 11904, 11905, 11888, 11896,     0,  8192, 12288, 
+    12289, 11776, 11904, 11905, 11907, 11896,     0,  8192, 
+    12288, 12289, 11776, 11904, 11905, 11907, 11896, 11898, 
+        0,  8192, 12288, 12289, 11776, 11904, 11905, 11907, 
+    11896,     0,  8192, 12288, 12289, 11776, 11904, 11905, 
+    11907, 11896, 11900,     0,  8192, 12288, 12289, 11776, 
+    11904, 11905, 11907, 11896, 11900,     0,  8192, 12288, 
+    12289, 11776, 11904, 11905, 11907, 11896, 11900, 11902, 
+        0,  8192, 12288, 12289, 11776,     0,  8192, 12288, 
+    12289, 11776, 11904,     0,  8192, 12288, 12289, 11776, 
+    11904,     0,  8192, 12288, 12289, 11776, 11904, 11906, 
+        0,  8192, 12288, 12289, 11776, 11904,     0,  8192, 
+    12288, 12289, 11776, 11904, 11908,     0,  8192, 12288, 
+    12289, 11776, 11904, 11908,     0,  8192, 12288, 12289, 
+    11776, 11904, 11912, 11910,     0,  8192, 12288, 12289, 
+    11776, 11904,     0,  8192, 12288, 12289, 11776, 11904, 
+    11912,     0,  8192, 12288, 12289, 11776, 11904, 11912, 
+        0,  8192, 12288, 12289, 11776, 11904, 11912, 11914, 
+        0,  8192, 12288, 12289, 11776, 11904, 11912,     0, 
+     8192, 12288, 12289, 11776, 11904, 11920, 11916,     0, 
+     8192, 12288, 12289, 11776, 11904, 11920, 11916,     0, 
+     8192, 12288, 12289, 11776, 11904, 11920, 11921, 11918, 
+        0,  8192, 12288, 12289, 11776, 11904,     0,  8192, 
+    12288, 12289, 11776, 11904, 11920,     0,  8192, 12288, 
+    12289, 11776, 11904, 11920,     0,  8192, 12288, 12289, 
+    11776, 11904, 11920, 11922,     0,  8192, 12288, 12289, 
+    11776, 11904, 11920,     0,  8192, 12288, 12289, 11776, 
+    11904, 11920, 11924,     0,  8192, 12288, 12289, 11776, 
+    11904, 11920, 11924,     0,  8192, 12288, 12289, 11776, 
+    11904, 11920, 11928, 11926,     0,  8192, 12288, 12289, 
+    11776, 11904, 11920,     0,  8192, 12288, 12289, 11776, 
+    11904, 11936, 11928,     0,  8192, 12288, 12289, 11776, 
+    11904, 11936, 11928,     0,  8192, 12288, 12289, 11776, 
+    11904, 11936, 11928, 11930,     0,  8192, 12288, 12289, 
+    11776, 11904, 11936, 11928,     0,  8192, 12288, 12289, 
+    11776, 11904, 11936, 11937, 11932,     0,  8192, 12288, 
+    12289, 11776, 11904, 11936, 11937, 11932,     0,  8192, 
+    12288, 12289, 11776, 11904, 11936, 11937, 11932, 11934, 
+        0,  8192, 12288, 12289, 11776, 11904,     0,  8192, 
+    12288, 12289, 11776, 11904, 11936,     0,  8192, 12288, 
+    12289, 11776, 11904, 11936,     0,  8192, 12288, 12289, 
+    11776, 11904, 11936, 11938,     0,  8192, 12288, 12289, 
+    11776, 11904, 11936,     0,  8192, 12288, 12289, 11776, 
+    11904, 11936, 11940,     0,  8192, 12288, 12289, 11776, 
+    11904, 11936, 11940,     0,  8192, 12288, 12289, 11776, 
+    11904, 11936, 11944, 11942,     0,  8192, 12288, 12289, 
+    11776, 11904, 11936,     0,  8192, 12288, 12289, 11776, 
+    11904, 11936, 11944,     0,  8192, 12288, 12289, 11776, 
+    11904, 11936, 11944,     0,  8192, 12288, 12289, 11776, 
+    11904, 11936, 11944, 11946,     0,  8192, 12288, 12289, 
+    11776, 11904, 11936, 11944,     0,  8192, 12288, 12289, 
+    11776, 11904, 11936, 11952, 11948,     0,  8192, 12288, 
+    12289, 11776, 11904, 11936, 11952, 11948,     0,  8192, 
+    12288, 12289, 11776, 11904, 11936, 11952, 11953, 11950, 
+        0,  8192, 12288, 12289, 11776, 11904, 11936,     0, 
+     8192, 12288, 12289, 11776, 11904, 11968, 11952,     0, 
+     8192, 12288, 12289, 11776, 11904, 11968, 11952,     0, 
+     8192, 12288, 12289, 11776, 11904, 11968, 11952, 11954, 
+        0,  8192, 12288, 12289, 11776, 11904, 11968, 11952, 
+        0,  8192, 12288, 12289, 11776, 11904, 11968, 11952, 
+    11956,     0,  8192, 12288, 12289, 11776, 11904, 11968, 
+    11952, 11956,     0,  8192, 12288, 12289, 11776, 11904, 
+    11968, 11952, 11960, 11958,     0,  8192, 12288, 12289, 
+    11776, 11904, 11968, 11952,     0,  8192, 12288, 12289, 
+    11776, 11904, 11968, 11969, 11960,     0,  8192, 12288, 
+    12289, 11776, 11904, 11968, 11969, 11960,     0,  8192, 
+    12288, 12289, 11776, 11904, 11968, 11969, 11960, 11962, 
+        0,  8192, 12288, 12289, 11776, 11904, 11968, 11969, 
+    11960,     0,  8192, 12288, 12289, 11776, 11904, 11968, 
+    11969, 11960, 11964,     0,  8192, 12288, 12289, 11776, 
+    11904, 11968, 11969, 11971, 11964,     0,  8192, 12288, 
+    12289, 11776, 11904, 11968, 11969, 11971, 11964, 11966, 
+        0,  8192, 12288, 12289, 11776, 11904,     0,  8192, 
+    12288, 12289, 11776, 12032, 11968,     0,  8192, 12288, 
+    12289, 11776, 12032, 11968,     0,  8192, 12288, 12289, 
+    11776, 12032, 11968, 11970,     0,  8192, 12288, 12289, 
+    11776, 12032, 11968,     0,  8192, 12288, 12289, 11776, 
+    12032, 11968, 11972,     0,  8192, 12288, 12289, 11776, 
+    12032, 11968, 11972,     0,  8192, 12288, 12289, 11776, 
+    12032, 11968, 11976, 11974,     0,  8192, 12288, 12289, 
+    11776, 12032, 11968,     0,  8192, 12288, 12289, 11776, 
+    12032, 11968, 11976,     0,  8192, 12288, 12289, 11776, 
+    12032, 11968, 11976,     0,  8192, 12288, 12289, 11776, 
+    12032, 11968, 11976, 11978,     0,  8192, 12288, 12289, 
+    11776, 12032, 11968, 11976,     0,  8192, 12288, 12289, 
+    11776, 12032, 11968, 11984, 11980,     0,  8192, 12288, 
+    12289, 11776, 12032, 11968, 11984, 11980,     0,  8192, 
+    12288, 12289, 11776, 12032, 11968, 11984, 11985, 11982, 
+        0,  8192, 12288, 12289, 11776, 12032, 11968,     0, 
+     8192, 12288, 12289, 11776, 12032, 11968, 11984,     0, 
+     8192, 12288, 12289, 11776, 12032, 11968, 11984,     0, 
+     8192, 12288, 12289, 11776, 12032, 11968, 11984, 11986, 
+        0,  8192, 12288, 12289, 11776, 12032, 11968, 11984, 
+        0,  8192, 12288, 12289, 11776, 12032, 11968, 11984, 
+    11988,     0,  8192, 12288, 12289, 11776, 12032, 11968, 
+    11984, 11988,     0,  8192, 12288, 12289, 11776, 12032, 
+    11968, 11984, 11992, 11990,     0,  8192, 12288, 12289, 
+    11776, 12032, 11968, 11984,     0,  8192, 12288, 12289, 
+    11776, 12032, 11968, 12000, 11992,     0,  8192, 12288, 
+    12289, 11776, 12032, 11968, 12000, 11992,     0,  8192, 
+    12288, 12289, 11776, 12032, 11968, 12000, 11992, 11994, 
+        0,  8192, 12288, 12289, 11776, 12032, 11968, 12000, 
+    11992,     0,  8192, 12288, 12289, 11776, 12032, 11968, 
+    12000, 12001, 11996,     0,  8192, 12288, 12289, 11776, 
+    12032, 11968, 12000, 12001, 11996,     0,  8192, 12288, 
+    12289, 11776, 12032, 11968, 12000, 12001, 11996, 11998, 
+        0,  8192, 12288, 12289, 11776, 12032, 11968,     0, 
+     8192, 12288, 12289, 11776, 12032, 12033, 12000,     0, 
+     8192, 12288, 12289, 11776, 12032, 12033, 12000,     0, 
+     8192, 12288, 12289, 11776, 12032, 12033, 12000, 12002, 
+        0,  8192, 12288, 12289, 11776, 12032, 12033, 12000, 
+        0,  8192, 12288, 12289, 11776, 12032, 12033, 12000, 
+    12004,     0,  8192, 12288, 12289, 11776, 12032, 12033, 
+    12000, 12004,     0,  8192, 12288, 12289, 11776, 12032, 
+    12033, 12000, 12008, 12006,     0,  8192, 12288, 12289, 
+    11776, 12032, 12033, 12000,     0,  8192, 12288, 12289, 
+    11776, 12032, 12033, 12000, 12008,     0,  8192, 12288, 
+    12289, 11776, 12032, 12033, 12000, 12008,     0,  8192, 
+    12288, 12289, 11776, 12032, 12033, 12000, 12008, 12010, 
+        0,  8192, 12288, 12289, 11776, 12032, 12033, 12000, 
+    12008,     0,  8192, 12288, 12289, 11776, 12032, 12033, 
+    12000, 12016, 12012,     0,  8192, 12288, 12289, 11776, 
+    12032, 12033, 12000, 12016, 12012,     0,  8192, 12288, 
+    12289, 11776, 12032, 12033, 12000, 12016, 12017, 12014, 
+        0,  8192, 12288, 12289, 11776, 12032, 12033, 12000, 
+        0,  8192, 12288, 12289, 11776, 12032, 12033, 12000, 
+    12016,     0,  8192, 12288, 12289, 11776, 12032, 12033, 
+    12035, 12016,     0,  8192, 12288, 12289, 11776, 12032, 
+    12033, 12035, 12016, 12018,     0,  8192, 12288, 12289, 
+    11776, 12032, 12033, 12035, 12016,     0,  8192, 12288, 
+    12289, 11776, 12032, 12033, 12035, 12016, 12020,     0, 
+     8192, 12288, 12289, 11776, 12032, 12033, 12035, 12016, 
+    12020,     0,  8192, 12288, 12289, 11776, 12032, 12033, 
+    12035, 12016, 12024, 12022,     0,  8192, 12288, 12289, 
+    11776, 12032, 12033, 12035, 12016,     0,  8192, 12288, 
+    12289, 11776, 12032, 12033, 12035, 12016, 12024,     0, 
+     8192, 12288, 12289, 11776, 12032, 12033, 12035, 12016, 
+    12024,     0,  8192, 12288, 12289, 11776, 12032, 12033, 
+    12035, 12016, 12024, 12026,     0,  8192, 12288, 12289, 
+    11776, 12032, 12033, 12035, 12039, 12024,     0,  8192, 
+    12288, 12289, 11776, 12032, 12033, 12035, 12039, 12024, 
+    12028,     0,  8192, 12288, 12289, 11776, 12032, 12033, 
+    12035, 12039, 12024, 12028,     0,  8192, 12288, 12289, 
+    11776, 12032, 12033, 12035, 12039, 12024, 12028, 12030, 
+        0,  8192, 12288, 12289, 11776,     0,  8192, 12288, 
+    12289, 11776, 12032,     0,  8192, 12288, 12289, 11776, 
+    12032,     0,  8192, 12288, 12289, 11776, 12032, 12034, 
+        0,  8192, 12288, 12289, 12291, 12032,     0,  8192, 
+    12288, 12289, 12291, 12032, 12036,     0,  8192, 12288, 
+    12289, 12291, 12032, 12036,     0,  8192, 12288, 12289, 
+    12291, 12032, 12040, 12038,     0,  8192, 12288, 12289, 
+    12291, 12032,     0,  8192, 12288, 12289, 12291, 12032, 
+    12040,     0,  8192, 12288, 12289, 12291, 12032, 12040, 
+        0,  8192, 12288, 12289, 12291, 12032, 12040, 12042, 
+        0,  8192, 12288, 12289, 12291, 12032, 12040,     0, 
+     8192, 12288, 12289, 12291, 12032, 12048, 12044,     0, 
+     8192, 12288, 12289, 12291, 12032, 12048, 12044,     0, 
+     8192, 12288, 12289, 12291, 12032, 12048, 12049, 12046, 
+        0,  8192, 12288, 12289, 12291, 12032,     0,  8192, 
+    12288, 12289, 12291, 12032, 12048,     0,  8192, 12288, 
+    12289, 12291, 12032, 12048,     0,  8192, 12288, 12289, 
+    12291, 12032, 12048, 12050,     0,  8192, 12288, 12289, 
+    12291, 12032, 12048,     0,  8192, 12288, 12289, 12291, 
+    12032, 12048, 12052,     0,  8192, 12288, 12289, 12291, 
+    12032, 12048, 12052,     0,  8192, 12288, 12289, 12291, 
+    12032, 12048, 12056, 12054,     0,  8192, 12288, 12289, 
+    12291, 12032, 12048,     0,  8192, 12288, 12289, 12291, 
+    12032, 12064, 12056,     0,  8192, 12288, 12289, 12291, 
+    12032, 12064, 12056,     0,  8192, 12288, 12289, 12291, 
+    12032, 12064, 12056, 12058,     0,  8192, 12288, 12289, 
+    12291, 12032, 12064, 12056,     0,  8192, 12288, 12289, 
+    12291, 12032, 12064, 12065, 12060,     0,  8192, 12288, 
+    12289, 12291, 12032, 12064, 12065, 12060,     0,  8192, 
+    12288, 12289, 12291, 12032, 12064, 12065, 12060, 12062, 
+        0,  8192, 12288, 12289, 12291, 12032,     0,  8192, 
+    12288, 12289, 12291, 12032, 12064,     0,  8192, 12288, 
+    12289, 12291, 12032, 12064,     0,  8192, 12288, 12289, 
+    12291, 12032, 12064, 12066,     0,  8192, 12288, 12289, 
+    12291, 12032, 12064,     0,  8192, 12288, 12289, 12291, 
+    12032, 12064, 12068,     0,  8192, 12288, 12289, 12291, 
+    12032, 12064, 12068,     0,  8192, 12288, 12289, 12291, 
+    12032, 12064, 12072, 12070,     0,  8192, 12288, 12289, 
+    12291, 12032, 12064,     0,  8192, 12288, 12289, 12291, 
+    12032, 12064, 12072,     0,  8192, 12288, 12289, 12291, 
+    12032, 12064, 12072,     0,  8192, 12288, 12289, 12291, 
+    12032, 12064, 12072, 12074,     0,  8192, 12288, 12289, 
+    12291, 12032, 12064, 12072,     0,  8192, 12288, 12289, 
+    12291, 12032, 12064, 12080, 12076,     0,  8192, 12288, 
+    12289, 12291, 12032, 12064, 12080, 12076,     0,  8192, 
+    12288, 12289, 12291, 12032, 12064, 12080, 12081, 12078, 
+        0,  8192, 12288, 12289, 12291, 12032, 12064,     0, 
+     8192, 12288, 12289, 12291, 12032, 12096, 12080,     0, 
+     8192, 12288, 12289, 12291, 12032, 12096, 12080,     0, 
+     8192, 12288, 12289, 12291, 12032, 12096, 12080, 12082, 
+        0,  8192, 12288, 12289, 12291, 12032, 12096, 12080, 
+        0,  8192, 12288, 12289, 12291, 12032, 12096, 12080, 
+    12084,     0,  8192, 12288, 12289, 12291, 12032, 12096, 
+    12080, 12084,     0,  8192, 12288, 12289, 12291, 12032, 
+    12096, 12080, 12088, 12086,     0,  8192, 12288, 12289, 
+    12291, 12032, 12096, 12080,     0,  8192, 12288, 12289, 
+    12291, 12032, 12096, 12097, 12088,     0,  8192, 12288, 
+    12289, 12291, 12032, 12096, 12097, 12088,     0,  8192, 
+    12288, 12289, 12291, 12032, 12096, 12097, 12088, 12090, 
+        0,  8192, 12288, 12289, 12291, 12032, 12096, 12097, 
+    12088,     0,  8192, 12288, 12289, 12291, 12032, 12096, 
+    12097, 12088, 12092,     0,  8192, 12288, 12289, 12291, 
+    12032, 12096, 12097, 12099, 12092,     0,  8192, 12288, 
+    12289, 12291, 12032, 12096, 12097, 12099, 12092, 12094, 
+        0,  8192, 12288, 12289, 12291, 12032,     0,  8192, 
+    12288, 12289, 12291, 12032, 12096,     0,  8192, 12288, 
+    12289, 12291, 12032, 12096,     0,  8192, 12288, 12289, 
+    12291, 12032, 12096, 12098,     0,  8192, 12288, 12289, 
+    12291, 12032, 12096,     0,  8192, 12288, 12289, 12291, 
+    12032, 12096, 12100,     0,  8192, 12288, 12289, 12291, 
+    12032, 12096, 12100,     0,  8192, 12288, 12289, 12291, 
+    12032, 12096, 12104, 12102,     0,  8192, 12288, 12289, 
+    12291, 12032, 12096,     0,  8192, 12288, 12289, 12291, 
+    12032, 12096, 12104,     0,  8192, 12288, 12289, 12291, 
+    12032, 12096, 12104,     0,  8192, 12288, 12289, 12291, 
+    12032, 12096, 12104, 12106,     0,  8192, 12288, 12289, 
+    12291, 12032, 12096, 12104,     0,  8192, 12288, 12289, 
+    12291, 12032, 12096, 12112, 12108,     0,  8192, 12288, 
+    12289, 12291, 12032, 12096, 12112, 12108,     0,  8192, 
+    12288, 12289, 12291, 12032, 12096, 12112, 12113, 12110, 
+        0,  8192, 12288, 12289, 12291, 12032, 12096,     0, 
+     8192, 12288, 12289, 12291, 12032, 12096, 12112,     0, 
+     8192, 12288, 12289, 12291, 12032, 12096, 12112,     0, 
+     8192, 12288, 12289, 12291, 12032, 12096, 12112, 12114, 
+        0,  8192, 12288, 12289, 12291, 12032, 12096, 12112, 
+        0,  8192, 12288, 12289, 12291, 12032, 12096, 12112, 
+    12116,     0,  8192, 12288, 12289, 12291, 12032, 12096, 
+    12112, 12116,     0,  8192, 12288, 12289, 12291, 12032, 
+    12096, 12112, 12120, 12118,     0,  8192, 12288, 12289, 
+    12291, 12032, 12096, 12112,     0,  8192, 12288, 12289, 
+    12291, 12032, 12096, 12128, 12120,     0,  8192, 12288, 
+    12289, 12291, 12032, 12096, 12128, 12120,     0,  8192, 
+    12288, 12289, 12291, 12032, 12096, 12128, 12120, 12122, 
+        0,  8192, 12288, 12289, 12291, 12032, 12096, 12128, 
+    12120,     0,  8192, 12288, 12289, 12291, 12032, 12096, 
+    12128, 12129, 12124,     0,  8192, 12288, 12289, 12291, 
+    12032, 12096, 12128, 12129, 12124,     0,  8192, 12288, 
+    12289, 12291, 12032, 12096, 12128, 12129, 12124, 12126, 
+        0,  8192, 12288, 12289, 12291, 12032, 12096,     0, 
+     8192, 12288, 12289, 12291, 12032, 12160, 12128,     0, 
+     8192, 12288, 12289, 12291, 12032, 12160, 12128,     0, 
+     8192, 12288, 12289, 12291, 12032, 12160, 12128, 12130, 
+        0,  8192, 12288, 12289, 12291, 12032, 12160, 12128, 
+        0,  8192, 12288, 12289, 12291, 12032, 12160, 12128, 
+    12132,     0,  8192, 12288, 12289, 12291, 12032, 12160, 
+    12128, 12132,     0,  8192, 12288, 12289, 12291, 12032, 
+    12160, 12128, 12136, 12134,     0,  8192, 12288, 12289, 
+    12291, 12032, 12160, 12128,     0,  8192, 12288, 12289, 
+    12291, 12032, 12160, 12128, 12136,     0,  8192, 12288, 
+    12289, 12291, 12032, 12160, 12128, 12136,     0,  8192, 
+    12288, 12289, 12291, 12032, 12160, 12128, 12136, 12138, 
+        0,  8192, 12288, 12289, 12291, 12032, 12160, 12128, 
+    12136,     0,  8192, 12288, 12289, 12291, 12032, 12160, 
+    12128, 12144, 12140,     0,  8192, 12288, 12289, 12291, 
+    12032, 12160, 12128, 12144, 12140,     0,  8192, 12288, 
+    12289, 12291, 12032, 12160, 12128, 12144, 12145, 12142, 
+        0,  8192, 12288, 12289, 12291, 12032, 12160, 12128, 
+        0,  8192, 12288, 12289, 12291, 12032, 12160, 12161, 
+    12144,     0,  8192, 12288, 12289, 12291, 12032, 12160, 
+    12161, 12144,     0,  8192, 12288, 12289, 12291, 12032, 
+    12160, 12161, 12144, 12146,     0,  8192, 12288, 12289, 
+    12291, 12032, 12160, 12161, 12144,     0,  8192, 12288, 
+    12289, 12291, 12032, 12160, 12161, 12144, 12148,     0, 
+     8192, 12288, 12289, 12291, 12032, 12160, 12161, 12144, 
+    12148,     0,  8192, 12288, 12289, 12291, 12032, 12160, 
+    12161, 12144, 12152, 12150,     0,  8192, 12288, 12289, 
+    12291, 12032, 12160, 12161, 12144,     0,  8192, 12288, 
+    12289, 12291, 12032, 12160, 12161, 12144, 12152,     0, 
+     8192, 12288, 12289, 12291, 12032, 12160, 12161, 12163, 
+    12152,     0,  8192, 12288, 12289, 12291, 12032, 12160, 
+    12161, 12163, 12152, 12154,     0,  8192, 12288, 12289, 
+    12291, 12032, 12160, 12161, 12163, 12152,     0,  8192, 
+    12288, 12289, 12291, 12032, 12160, 12161, 12163, 12152, 
+    12156,     0,  8192, 12288, 12289, 12291, 12032, 12160, 
+    12161, 12163, 12152, 12156,     0,  8192, 12288, 12289, 
+    12291, 12032, 12160, 12161, 12163, 12152, 12156, 12158, 
+        0,  8192, 12288, 12289, 12291, 12032,     0,  8192, 
+    12288, 12289, 12291, 12032, 12160,     0,  8192, 12288, 
+    12289, 12291, 12032, 12160,     0,  8192, 12288, 12289, 
+    12291, 12032, 12160, 12162,     0,  8192, 12288, 12289, 
+    12291, 12032, 12160,     0,  8192, 12288, 12289, 12291, 
+    12032, 12160, 12164,     0,  8192, 12288, 12289, 12291, 
+    12032, 12160, 12164,     0,  8192, 12288, 12289, 12291, 
+    12032, 12160, 12168, 12166,     0,  8192, 12288, 12289, 
+    12291, 12295, 12160,     0,  8192, 12288, 12289, 12291, 
+    12295, 12160, 12168,     0,  8192, 12288, 12289, 12291, 
+    12295, 12160, 12168,     0,  8192, 12288, 12289, 12291, 
+    12295, 12160, 12168, 12170,     0,  8192, 12288, 12289, 
+    12291, 12295, 12160, 12168,     0,  8192, 12288, 12289, 
+    12291, 12295, 12160, 12176, 12172,     0,  8192, 12288, 
+    12289, 12291, 12295, 12160, 12176, 12172,     0,  8192, 
+    12288, 12289, 12291, 12295, 12160, 12176, 12177, 12174, 
+        0,  8192, 12288, 12289, 12291, 12295, 12160,     0, 
+     8192, 12288, 12289, 12291, 12295, 12160, 12176,     0, 
+     8192, 12288, 12289, 12291, 12295, 12160, 12176,     0, 
+     8192, 12288, 12289, 12291, 12295, 12160, 12176, 12178, 
+        0,  8192, 12288, 12289, 12291, 12295, 12160, 12176, 
+        0,  8192, 12288, 12289, 12291, 12295, 12160, 12176, 
+    12180,     0,  8192, 12288, 12289, 12291, 12295, 12160, 
+    12176, 12180,     0,  8192, 12288, 12289, 12291, 12295, 
+    12160, 12176, 12184, 12182,     0,  8192, 12288, 12289, 
+    12291, 12295, 12160, 12176,     0,  8192, 12288, 12289, 
+    12291, 12295, 12160, 12192, 12184,     0,  8192, 12288, 
+    12289, 12291, 12295, 12160, 12192, 12184,     0,  8192, 
+    12288, 12289, 12291, 12295, 12160, 12192, 12184, 12186, 
+        0,  8192, 12288, 12289, 12291, 12295, 12160, 12192, 
+    12184,     0,  8192, 12288, 12289, 12291, 12295, 12160, 
+    12192, 12193, 12188,     0,  8192, 12288, 12289, 12291, 
+    12295, 12160, 12192, 12193, 12188,     0,  8192, 12288, 
+    12289, 12291, 12295, 12160, 12192, 12193, 12188, 12190, 
+        0,  8192, 12288, 12289, 12291, 12295, 12160,     0, 
+     8192, 12288, 12289, 12291, 12295, 12160, 12192,     0, 
+     8192, 12288, 12289, 12291, 12295, 12160, 12192,     0, 
+     8192, 12288, 12289, 12291, 12295, 12160, 12192, 12194, 
+        0,  8192, 12288, 12289, 12291, 12295, 12160, 12192, 
+        0,  8192, 12288, 12289, 12291, 12295, 12160, 12192, 
+    12196,     0,  8192, 12288, 12289, 12291, 12295, 12160, 
+    12192, 12196,     0,  8192, 12288, 12289, 12291, 12295, 
+    12160, 12192, 12200, 12198,     0,  8192, 12288, 12289, 
+    12291, 12295, 12160, 12192,     0,  8192, 12288, 12289, 
+    12291, 12295, 12160, 12192, 12200,     0,  8192, 12288, 
+    12289, 12291, 12295, 12160, 12192, 12200,     0,  8192, 
+    12288, 12289, 12291, 12295, 12160, 12192, 12200, 12202, 
+        0,  8192, 12288, 12289, 12291, 12295, 12160, 12192, 
+    12200,     0,  8192, 12288, 12289, 12291, 12295, 12160, 
+    12192, 12208, 12204,     0,  8192, 12288, 12289, 12291, 
+    12295, 12160, 12192, 12208, 12204,     0,  8192, 12288, 
+    12289, 12291, 12295, 12160, 12192, 12208, 12209, 12206, 
+        0,  8192, 12288, 12289, 12291, 12295, 12160, 12192, 
+        0,  8192, 12288, 12289, 12291, 12295, 12160, 12224, 
+    12208,     0,  8192, 12288, 12289, 12291, 12295, 12160, 
+    12224, 12208,     0,  8192, 12288, 12289, 12291, 12295, 
+    12160, 12224, 12208, 12210,     0,  8192, 12288, 12289, 
+    12291, 12295, 12160, 12224, 12208,     0,  8192, 12288, 
+    12289, 12291, 12295, 12160, 12224, 12208, 12212,     0, 
+     8192, 12288, 12289, 12291, 12295, 12160, 12224, 12208, 
+    12212,     0,  8192, 12288, 12289, 12291, 12295, 12160, 
+    12224, 12208, 12216, 12214,     0,  8192, 12288, 12289, 
+    12291, 12295, 12160, 12224, 12208,     0,  8192, 12288, 
+    12289, 12291, 12295, 12160, 12224, 12225, 12216,     0, 
+     8192, 12288, 12289, 12291, 12295, 12160, 12224, 12225, 
+    12216,     0,  8192, 12288, 12289, 12291, 12295, 12160, 
+    12224, 12225, 12216, 12218,     0,  8192, 12288, 12289, 
+    12291, 12295, 12160, 12224, 12225, 12216,     0,  8192, 
+    12288, 12289, 12291, 12295, 12160, 12224, 12225, 12216, 
+    12220,     0,  8192, 12288, 12289, 12291, 12295, 12160, 
+    12224, 12225, 12227, 12220,     0,  8192, 12288, 12289, 
+    12291, 12295, 12160, 12224, 12225, 12227, 12220, 12222, 
+        0,  8192, 12288, 12289, 12291, 12295, 12160,     0, 
+     8192, 12288, 12289, 12291, 12295, 12160, 12224,     0, 
+     8192, 12288, 12289, 12291, 12295, 12160, 12224,     0, 
+     8192, 12288, 12289, 12291, 12295, 12160, 12224, 12226, 
+        0,  8192, 12288, 12289, 12291, 12295, 12160, 12224, 
+        0,  8192, 12288, 12289, 12291, 12295, 12160, 12224, 
+    12228,     0,  8192, 12288, 12289, 12291, 12295, 12160, 
+    12224, 12228,     0,  8192, 12288, 12289, 12291, 12295, 
+    12160, 12224, 12232, 12230,     0,  8192, 12288, 12289, 
+    12291, 12295, 12160, 12224,     0,  8192, 12288, 12289, 
+    12291, 12295, 12160, 12224, 12232,     0,  8192, 12288, 
+    12289, 12291, 12295, 12160, 12224, 12232,     0,  8192, 
+    12288, 12289, 12291, 12295, 12160, 12224, 12232, 12234, 
+        0,  8192, 12288, 12289, 12291, 12295, 12160, 12224, 
+    12232,     0,  8192, 12288, 12289, 12291, 12295, 12160, 
+    12224, 12240, 12236,     0,  8192, 12288, 12289, 12291, 
+    12295, 12160, 12224, 12240, 12236,     0,  8192, 12288, 
+    12289, 12291, 12295, 12160, 12224, 12240, 12241, 12238, 
+        0,  8192, 12288, 12289, 12291, 12295, 12303, 12224, 
+        0,  8192, 12288, 12289, 12291, 12295, 12303, 12224, 
+    12240,     0,  8192, 12288, 12289, 12291, 12295, 12303, 
+    12224, 12240,     0,  8192, 12288, 12289, 12291, 12295, 
+    12303, 12224, 12240, 12242,     0,  8192, 12288, 12289, 
+    12291, 12295, 12303, 12224, 12240,     0,  8192, 12288, 
+    12289, 12291, 12295, 12303, 12224, 12240, 12244,     0, 
+     8192, 12288, 12289, 12291, 12295, 12303, 12224, 12240, 
+    12244,     0,  8192, 12288, 12289, 12291, 12295, 12303, 
+    12224, 12240, 12248, 12246,     0,  8192, 12288, 12289, 
+    12291, 12295, 12303, 12224, 12240,     0,  8192, 12288, 
+    12289, 12291, 12295, 12303, 12224, 12256, 12248,     0, 
+     8192, 12288, 12289, 12291, 12295, 12303, 12224, 12256, 
+    12248,     0,  8192, 12288, 12289, 12291, 12295, 12303, 
+    12224, 12256, 12248, 12250,     0,  8192, 12288, 12289, 
+    12291, 12295, 12303, 12224, 12256, 12248,     0,  8192, 
+    12288, 12289, 12291, 12295, 12303, 12224, 12256, 12257, 
+    12252,     0,  8192, 12288, 12289, 12291, 12295, 12303, 
+    12224, 12256, 12257, 12252,     0,  8192, 12288, 12289, 
+    12291, 12295, 12303, 12224, 12256, 12257, 12252, 12254, 
+        0,  8192, 12288, 12289, 12291, 12295, 12303, 12224, 
+        0,  8192, 12288, 12289, 12291, 12295, 12303, 12224, 
+    12256,     0,  8192, 12288, 12289, 12291, 12295, 12303, 
+    12224, 12256,     0,  8192, 12288, 12289, 12291, 12295, 
+    12303, 12224, 12256, 12258,     0,  8192, 12288, 12289, 
+    12291, 12295, 12303, 12224, 12256,     0,  8192, 12288, 
+    12289, 12291, 12295, 12303, 12224, 12256, 12260,     0, 
+     8192, 12288, 12289, 12291, 12295, 12303, 12224, 12256, 
+    12260,     0,  8192, 12288, 12289, 12291, 12295, 12303, 
+    12224, 12256, 12264, 12262,     0,  8192, 12288, 12289, 
+    12291, 12295, 12303, 12224, 12256,     0,  8192, 12288, 
+    12289, 12291, 12295, 12303, 12224, 12256, 12264,     0, 
+     8192, 12288, 12289, 12291, 12295, 12303, 12224, 12256, 
+    12264,     0,  8192, 12288, 12289, 12291, 12295, 12303, 
+    12224, 12256, 12264, 12266,     0,  8192, 12288, 12289, 
+    12291, 12295, 12303, 12224, 12256, 12264,     0,  8192, 
+    12288, 12289, 12291, 12295, 12303, 12224, 12256, 12272, 
+    12268,     0,  8192, 12288, 12289, 12291, 12295, 12303, 
+    12224, 12256, 12272, 12268,     0,  8192, 12288, 12289, 
+    12291, 12295, 12303, 12224, 12256, 12272, 12273, 12270, 
+        0,  8192, 12288, 12289, 12291, 12295, 12303, 12224, 
+    12256,     0,  8192, 12288, 12289, 12291, 12295, 12303, 
+    12224, 12256, 12272,     0,  8192, 12288, 12289, 12291, 
+    12295, 12303, 12224, 12256, 12272,     0,  8192, 12288, 
+    12289, 12291, 12295, 12303, 12224, 12256, 12272, 12274, 
+        0,  8192, 12288, 12289, 12291, 12295, 12303, 12224, 
+    12256, 12272,     0,  8192, 12288, 12289, 12291, 12295, 
+    12303, 12224, 12256, 12272, 12276,     0,  8192, 12288, 
+    12289, 12291, 12295, 12303, 12224, 12256, 12272, 12276, 
+        0,  8192, 12288, 12289, 12291, 12295, 12303, 12224, 
+    12256, 12272, 12280, 12278,     0,  8192, 12288, 12289, 
+    12291, 12295, 12303, 12224, 12256, 12272,     0,  8192, 
+    12288, 12289, 12291, 12295, 12303, 12224, 12256, 12272, 
+    12280,     0,  8192, 12288, 12289, 12291, 12295, 12303, 
+    12224, 12256, 12272, 12280,     0,  8192, 12288, 12289, 
+    12291, 12295, 12303, 12224, 12256, 12272, 12280, 12282, 
+        0,  8192, 12288, 12289, 12291, 12295, 12303, 12224, 
+    12256, 12272, 12280,     0,  8192, 12288, 12289, 12291, 
+    12295, 12303, 12224, 12256, 12272, 12280, 12284,     0, 
+     8192, 12288, 12289, 12291, 12295, 12303, 12224, 12256, 
+    12272, 12280, 12284,     0,  8192, 12288, 12289, 12291, 
+    12295, 12303, 12224, 12256, 12272, 12280, 12284, 12286, 
+        0,  8192,     0,  8192, 12288,     0,  8192, 12288, 
+        0,  8192, 12288, 12290,     0,  8192, 12288,     0, 
+     8192, 12288, 12292,     0,  8192, 12288, 12292,     0, 
+     8192, 12288, 12296, 12294,     0,  8192, 12288,     0, 
+     8192, 12288, 12296,     0,  8192, 12288, 12296,     0, 
+     8192, 12288, 12296, 12298,     0,  8192, 12288, 12296, 
+        0,  8192, 12288, 12304, 12300,     0,  8192, 12288, 
+    12304, 12300,     0,  8192, 12288, 12304, 12305, 12302, 
+        0,  8192, 12288,     0,  8192, 12288, 12304,     0, 
+     8192, 12288, 12304,     0,  8192, 12288, 12304, 12306, 
+        0,  8192, 12288, 12304,     0,  8192, 12288, 12304, 
+    12308,     0,  8192, 12288, 12304, 12308,     0,  8192, 
+    12288, 12304, 12312, 12310,     0,  8192, 12288, 12304, 
+        0,  8192, 12288, 12320, 12312,     0,  8192, 12288, 
+    12320, 12312,     0,  8192, 12288, 12320, 12312, 12314, 
+        0,  8192, 12288, 12320, 12312,     0,  8192, 12288, 
+    12320, 12321, 12316,     0,  8192, 12288, 12320, 12321, 
+    12316,     0,  8192, 12288, 12320, 12321, 12316, 12318, 
+        0,  8192, 12288,     0,  8192, 12288, 12320,     0, 
+     8192, 12288, 12320,     0,  8192, 12288, 12320, 12322, 
+        0,  8192, 12288, 12320,     0,  8192, 12288, 12320, 
+    12324,     0,  8192, 12288, 12320, 12324,     0,  8192, 
+    12288, 12320, 12328, 12326,     0,  8192, 12288, 12320, 
+        0,  8192, 12288, 12320, 12328,     0,  8192, 12288, 
+    12320, 12328,     0,  8192, 12288, 12320, 12328, 12330, 
+        0,  8192, 12288, 12320, 12328,     0,  8192, 12288, 
+    12320, 12336, 12332,     0,  8192, 12288, 12320, 12336, 
+    12332,     0,  8192, 12288, 12320, 12336, 12337, 12334, 
+        0,  8192, 12288, 12320,     0,  8192, 12288, 12352, 
+    12336,     0,  8192, 12288, 12352, 12336,     0,  8192, 
+    12288, 12352, 12336, 12338,     0,  8192, 12288, 12352, 
+    12336,     0,  8192, 12288, 12352, 12336, 12340,     0, 
+     8192, 12288, 12352, 12336, 12340,     0,  8192, 12288, 
+    12352, 12336, 12344, 12342,     0,  8192, 12288, 12352, 
+    12336,     0,  8192, 12288, 12352, 12353, 12344,     0, 
+     8192, 12288, 12352, 12353, 12344,     0,  8192, 12288, 
+    12352, 12353, 12344, 12346,     0,  8192, 12288, 12352, 
+    12353, 12344,     0,  8192, 12288, 12352, 12353, 12344, 
+    12348,     0,  8192, 12288, 12352, 12353, 12355, 12348, 
+        0,  8192, 12288, 12352, 12353, 12355, 12348, 12350, 
+        0,  8192, 12288,     0,  8192, 12288, 12352,     0, 
+     8192, 12288, 12352,     0,  8192, 12288, 12352, 12354, 
+        0,  8192, 12288, 12352,     0,  8192, 12288, 12352, 
+    12356,     0,  8192, 12288, 12352, 12356,     0,  8192, 
+    12288, 12352, 12360, 12358,     0,  8192, 12288, 12352, 
+        0,  8192, 12288, 12352, 12360,     0,  8192, 12288, 
+    12352, 12360,     0,  8192, 12288, 12352, 12360, 12362, 
+        0,  8192, 12288, 12352, 12360,     0,  8192, 12288, 
+    12352, 12368, 12364,     0,  8192, 12288, 12352, 12368, 
+    12364,     0,  8192, 12288, 12352, 12368, 12369, 12366, 
+        0,  8192, 12288, 12352,     0,  8192, 12288, 12352, 
+    12368,     0,  8192, 12288, 12352, 12368,     0,  8192, 
+    12288, 12352, 12368, 12370,     0,  8192, 12288, 12352, 
+    12368,     0,  8192, 12288, 12352, 12368, 12372,     0, 
+     8192, 12288, 12352, 12368, 12372,     0,  8192, 12288, 
+    12352, 12368, 12376, 12374,     0,  8192, 12288, 12352, 
+    12368,     0,  8192, 12288, 12352, 12384, 12376,     0, 
+     8192, 12288, 12352, 12384, 12376,     0,  8192, 12288, 
+    12352, 12384, 12376, 12378,     0,  8192, 12288, 12352, 
+    12384, 12376,     0,  8192, 12288, 12352, 12384, 12385, 
+    12380,     0,  8192, 12288, 12352, 12384, 12385, 12380, 
+        0,  8192, 12288, 12352, 12384, 12385, 12380, 12382, 
+        0,  8192, 12288, 12352,     0,  8192, 12288, 12416, 
+    12384,     0,  8192, 12288, 12416, 12384,     0,  8192, 
+    12288, 12416, 12384, 12386,     0,  8192, 12288, 12416, 
+    12384,     0,  8192, 12288, 12416, 12384, 12388,     0, 
+     8192, 12288, 12416, 12384, 12388,     0,  8192, 12288, 
+    12416, 12384, 12392, 12390,     0,  8192, 12288, 12416, 
+    12384,     0,  8192, 12288, 12416, 12384, 12392,     0, 
+     8192, 12288, 12416, 12384, 12392,     0,  8192, 12288, 
+    12416, 12384, 12392, 12394,     0,  8192, 12288, 12416, 
+    12384, 12392,     0,  8192, 12288, 12416, 12384, 12400, 
+    12396,     0,  8192, 12288, 12416, 12384, 12400, 12396, 
+        0,  8192, 12288, 12416, 12384, 12400, 12401, 12398, 
+        0,  8192, 12288, 12416, 12384,     0,  8192, 12288, 
+    12416, 12417, 12400,     0,  8192, 12288, 12416, 12417, 
+    12400,     0,  8192, 12288, 12416, 12417, 12400, 12402, 
+        0,  8192, 12288, 12416, 12417, 12400,     0,  8192, 
+    12288, 12416, 12417, 12400, 12404,     0,  8192, 12288, 
+    12416, 12417, 12400, 12404,     0,  8192, 12288, 12416, 
+    12417, 12400, 12408, 12406,     0,  8192, 12288, 12416, 
+    12417, 12400,     0,  8192, 12288, 12416, 12417, 12400, 
+    12408,     0,  8192, 12288, 12416, 12417, 12419, 12408, 
+        0,  8192, 12288, 12416, 12417, 12419, 12408, 12410, 
+        0,  8192, 12288, 12416, 12417, 12419, 12408,     0, 
+     8192, 12288, 12416, 12417, 12419, 12408, 12412,     0, 
+     8192, 12288, 12416, 12417, 12419, 12408, 12412,     0, 
+     8192, 12288, 12416, 12417, 12419, 12408, 12412, 12414, 
+        0,  8192, 12288,     0,  8192, 12288, 12416,     0, 
+     8192, 12288, 12416,     0,  8192, 12288, 12416, 12418, 
+        0,  8192, 12288, 12416,     0,  8192, 12288, 12416, 
+    12420,     0,  8192, 12288, 12416, 12420,     0,  8192, 
+    12288, 12416, 12424, 12422,     0,  8192, 12288, 12416, 
+        0,  8192, 12288, 12416, 12424,     0,  8192, 12288, 
+    12416, 12424,     0,  8192, 12288, 12416, 12424, 12426, 
+        0,  8192, 12288, 12416, 12424,     0,  8192, 12288, 
+    12416, 12432, 12428,     0,  8192, 12288, 12416, 12432, 
+    12428,     0,  8192, 12288, 12416, 12432, 12433, 12430, 
+        0,  8192, 12288, 12416,     0,  8192, 12288, 12416, 
+    12432,     0,  8192, 12288, 12416, 12432,     0,  8192, 
+    12288, 12416, 12432, 12434,     0,  8192, 12288, 12416, 
+    12432,     0,  8192, 12288, 12416, 12432, 12436,     0, 
+     8192, 12288, 12416, 12432, 12436,     0,  8192, 12288, 
+    12416, 12432, 12440, 12438,     0,  8192, 12288, 12416, 
+    12432,     0,  8192, 12288, 12416, 12448, 12440,     0, 
+     8192, 12288, 12416, 12448, 12440,     0,  8192, 12288, 
+    12416, 12448, 12440, 12442,     0,  8192, 12288, 12416, 
+    12448, 12440,     0,  8192, 12288, 12416, 12448, 12449, 
+    12444,     0,  8192, 12288, 12416, 12448, 12449, 12444, 
+        0,  8192, 12288, 12416, 12448, 12449, 12444, 12446, 
+        0,  8192, 12288, 12416,     0,  8192, 12288, 12416, 
+    12448,     0,  8192, 12288, 12416, 12448,     0,  8192, 
+    12288, 12416, 12448, 12450,     0,  8192, 12288, 12416, 
+    12448,     0,  8192, 12288, 12416, 12448, 12452,     0, 
+     8192, 12288, 12416, 12448, 12452,     0,  8192, 12288, 
+    12416, 12448, 12456, 12454,     0,  8192, 12288, 12416, 
+    12448,     0,  8192, 12288, 12416, 12448, 12456,     0, 
+     8192, 12288, 12416, 12448, 12456,     0,  8192, 12288, 
+    12416, 12448, 12456, 12458,     0,  8192, 12288, 12416, 
+    12448, 12456,     0,  8192, 12288, 12416, 12448, 12464, 
+    12460,     0,  8192, 12288, 12416, 12448, 12464, 12460, 
+        0,  8192, 12288, 12416, 12448, 12464, 12465, 12462, 
+        0,  8192, 12288, 12416, 12448,     0,  8192, 12288, 
+    12416, 12480, 12464,     0,  8192, 12288, 12416, 12480, 
+    12464,     0,  8192, 12288, 12416, 12480, 12464, 12466, 
+        0,  8192, 12288, 12416, 12480, 12464,     0,  8192, 
+    12288, 12416, 12480, 12464, 12468,     0,  8192, 12288, 
+    12416, 12480, 12464, 12468,     0,  8192, 12288, 12416, 
+    12480, 12464, 12472, 12470,     0,  8192, 12288, 12416, 
+    12480, 12464,     0,  8192, 12288, 12416, 12480, 12481, 
+    12472,     0,  8192, 12288, 12416, 12480, 12481, 12472, 
+        0,  8192, 12288, 12416, 12480, 12481, 12472, 12474, 
+        0,  8192, 12288, 12416, 12480, 12481, 12472,     0, 
+     8192, 12288, 12416, 12480, 12481, 12472, 12476,     0, 
+     8192, 12288, 12416, 12480, 12481, 12483, 12476,     0, 
+     8192, 12288, 12416, 12480, 12481, 12483, 12476, 12478, 
+        0,  8192, 12288, 12416,     0,  8192, 12288, 12544, 
+    12480,     0,  8192, 12288, 12544, 12480,     0,  8192, 
+    12288, 12544, 12480, 12482,     0,  8192, 12288, 12544, 
+    12480,     0,  8192, 12288, 12544, 12480, 12484,     0, 
+     8192, 12288, 12544, 12480, 12484,     0,  8192, 12288, 
+    12544, 12480, 12488, 12486,     0,  8192, 12288, 12544, 
+    12480,     0,  8192, 12288, 12544, 12480, 12488,     0, 
+     8192, 12288, 12544, 12480, 12488,     0,  8192, 12288, 
+    12544, 12480, 12488, 12490,     0,  8192, 12288, 12544, 
+    12480, 12488,     0,  8192, 12288, 12544, 12480, 12496, 
+    12492,     0,  8192, 12288, 12544, 12480, 12496, 12492, 
+        0,  8192, 12288, 12544, 12480, 12496, 12497, 12494, 
+        0,  8192, 12288, 12544, 12480,     0,  8192, 12288, 
+    12544, 12480, 12496,     0,  8192, 12288, 12544, 12480, 
+    12496,     0,  8192, 12288, 12544, 12480, 12496, 12498, 
+        0,  8192, 12288, 12544, 12480, 12496,     0,  8192, 
+    12288, 12544, 12480, 12496, 12500,     0,  8192, 12288, 
+    12544, 12480, 12496, 12500,     0,  8192, 12288, 12544, 
+    12480, 12496, 12504, 12502,     0,  8192, 12288, 12544, 
+    12480, 12496,     0,  8192, 12288, 12544, 12480, 12512, 
+    12504,     0,  8192, 12288, 12544, 12480, 12512, 12504, 
+        0,  8192, 12288, 12544, 12480, 12512, 12504, 12506, 
+        0,  8192, 12288, 12544, 12480, 12512, 12504,     0, 
+     8192, 12288, 12544, 12480, 12512, 12513, 12508,     0, 
+     8192, 12288, 12544, 12480, 12512, 12513, 12508,     0, 
+     8192, 12288, 12544, 12480, 12512, 12513, 12508, 12510, 
+        0,  8192, 12288, 12544, 12480,     0,  8192, 12288, 
+    12544, 12545, 12512,     0,  8192, 12288, 12544, 12545, 
+    12512,     0,  8192, 12288, 12544, 12545, 12512, 12514, 
+        0,  8192, 12288, 12544, 12545, 12512,     0,  8192, 
+    12288, 12544, 12545, 12512, 12516,     0,  8192, 12288, 
+    12544, 12545, 12512, 12516,     0,  8192, 12288, 12544, 
+    12545, 12512, 12520, 12518,     0,  8192, 12288, 12544, 
+    12545, 12512,     0,  8192, 12288, 12544, 12545, 12512, 
+    12520,     0,  8192, 12288, 12544, 12545, 12512, 12520, 
+        0,  8192, 12288, 12544, 12545, 12512, 12520, 12522, 
+        0,  8192, 12288, 12544, 12545, 12512, 12520,     0, 
+     8192, 12288, 12544, 12545, 12512, 12528, 12524,     0, 
+     8192, 12288, 12544, 12545, 12512, 12528, 12524,     0, 
+     8192, 12288, 12544, 12545, 12512, 12528, 12529, 12526, 
+        0,  8192, 12288, 12544, 12545, 12512,     0,  8192, 
+    12288, 12544, 12545, 12512, 12528,     0,  8192, 12288, 
+    12544, 12545, 12547, 12528,     0,  8192, 12288, 12544, 
+    12545, 12547, 12528, 12530,     0,  8192, 12288, 12544, 
+    12545, 12547, 12528,     0,  8192, 12288, 12544, 12545, 
+    12547, 12528, 12532,     0,  8192, 12288, 12544, 12545, 
+    12547, 12528, 12532,     0,  8192, 12288, 12544, 12545, 
+    12547, 12528, 12536, 12534,     0,  8192, 12288, 12544, 
+    12545, 12547, 12528,     0,  8192, 12288, 12544, 12545, 
+    12547, 12528, 12536,     0,  8192, 12288, 12544, 12545, 
+    12547, 12528, 12536,     0,  8192, 12288, 12544, 12545, 
+    12547, 12528, 12536, 12538,     0,  8192, 12288, 12544, 
+    12545, 12547, 12551, 12536,     0,  8192, 12288, 12544, 
+    12545, 12547, 12551, 12536, 12540,     0,  8192, 12288, 
+    12544, 12545, 12547, 12551, 12536, 12540,     0,  8192, 
+    12288, 12544, 12545, 12547, 12551, 12536, 12540, 12542, 
+        0,  8192, 12288,     0,  8192, 12288, 12544,     0, 
+     8192, 12288, 12544,     0,  8192, 12288, 12544, 12546, 
+        0,  8192, 12288, 12544,     0,  8192, 12288, 12544, 
+    12548,     0,  8192, 12288, 12544, 12548,     0,  8192, 
+    12288, 12544, 12552, 12550,     0,  8192, 12288, 12544, 
+        0,  8192, 12288, 12544, 12552,     0,  8192, 12288, 
+    12544, 12552,     0,  8192, 12288, 12544, 12552, 12554, 
+        0,  8192, 12288, 12544, 12552,     0,  8192, 12288, 
+    12544, 12560, 12556,     0,  8192, 12288, 12544, 12560, 
+    12556,     0,  8192, 12288, 12544, 12560, 12561, 12558, 
+        0,  8192, 12288, 12544,     0,  8192, 12288, 12544, 
+    12560,     0,  8192, 12288, 12544, 12560,     0,  8192, 
+    12288, 12544, 12560, 12562,     0,  8192, 12288, 12544, 
+    12560,     0,  8192, 12288, 12544, 12560, 12564,     0, 
+     8192, 12288, 12544, 12560, 12564,     0,  8192, 12288, 
+    12544, 12560, 12568, 12566,     0,  8192, 12288, 12544, 
+    12560,     0,  8192, 12288, 12544, 12576, 12568,     0, 
+     8192, 12288, 12544, 12576, 12568,     0,  8192, 12288, 
+    12544, 12576, 12568, 12570,     0,  8192, 12288, 12544, 
+    12576, 12568,     0,  8192, 12288, 12544, 12576, 12577, 
+    12572,     0,  8192, 12288, 12544, 12576, 12577, 12572, 
+        0,  8192, 12288, 12544, 12576, 12577, 12572, 12574, 
+        0,  8192, 12288, 12544,     0,  8192, 12288, 12544, 
+    12576,     0,  8192, 12288, 12544, 12576,     0,  8192, 
+    12288, 12544, 12576, 12578,     0,  8192, 12288, 12544, 
+    12576,     0,  8192, 12288, 12544, 12576, 12580,     0, 
+     8192, 12288, 12544, 12576, 12580,     0,  8192, 12288, 
+    12544, 12576, 12584, 12582,     0,  8192, 12288, 12544, 
+    12576,     0,  8192, 12288, 12544, 12576, 12584,     0, 
+     8192, 12288, 12544, 12576, 12584,     0,  8192, 12288, 
+    12544, 12576, 12584, 12586,     0,  8192, 12288, 12544, 
+    12576, 12584,     0,  8192, 12288, 12544, 12576, 12592, 
+    12588,     0,  8192, 12288, 12544, 12576, 12592, 12588, 
+        0,  8192, 12288, 12544, 12576, 12592, 12593, 12590, 
+        0,  8192, 12288, 12544, 12576,     0,  8192, 12288, 
+    12544, 12608, 12592,     0,  8192, 12288, 12544, 12608, 
+    12592,     0,  8192, 12288, 12544, 12608, 12592, 12594, 
+        0,  8192, 12288, 12544, 12608, 12592,     0,  8192, 
+    12288, 12544, 12608, 12592, 12596,     0,  8192, 12288, 
+    12544, 12608, 12592, 12596,     0,  8192, 12288, 12544, 
+    12608, 12592, 12600, 12598,     0,  8192, 12288, 12544, 
+    12608, 12592,     0,  8192, 12288, 12544, 12608, 12609, 
+    12600,     0,  8192, 12288, 12544, 12608, 12609, 12600, 
+        0,  8192, 12288, 12544, 12608, 12609, 12600, 12602, 
+        0,  8192, 12288, 12544, 12608, 12609, 12600,     0, 
+     8192, 12288, 12544, 12608, 12609, 12600, 12604,     0, 
+     8192, 12288, 12544, 12608, 12609, 12611, 12604,     0, 
+     8192, 12288, 12544, 12608, 12609, 12611, 12604, 12606, 
+        0,  8192, 12288, 12544,     0,  8192, 12288, 12544, 
+    12608,     0,  8192, 12288, 12544, 12608,     0,  8192, 
+    12288, 12544, 12608, 12610,     0,  8192, 12288, 12544, 
+    12608,     0,  8192, 12288, 12544, 12608, 12612,     0, 
+     8192, 12288, 12544, 12608, 12612,     0,  8192, 12288, 
+    12544, 12608, 12616, 12614,     0,  8192, 12288, 12544, 
+    12608,     0,  8192, 12288, 12544, 12608, 12616,     0, 
+     8192, 12288, 12544, 12608, 12616,     0,  8192, 12288, 
+    12544, 12608, 12616, 12618,     0,  8192, 12288, 12544, 
+    12608, 12616,     0,  8192, 12288, 12544, 12608, 12624, 
+    12620,     0,  8192, 12288, 12544, 12608, 12624, 12620, 
+        0,  8192, 12288, 12544, 12608, 12624, 12625, 12622, 
+        0,  8192, 12288, 12544, 12608,     0,  8192, 12288, 
+    12544, 12608, 12624,     0,  8192, 12288, 12544, 12608, 
+    12624,     0,  8192, 12288, 12544, 12608, 12624, 12626, 
+        0,  8192, 12288, 12544, 12608, 12624,     0,  8192, 
+    12288, 12544, 12608, 12624, 12628,     0,  8192, 12288, 
+    12544, 12608, 12624, 12628,     0,  8192, 12288, 12544, 
+    12608, 12624, 12632, 12630,     0,  8192, 12288, 12544, 
+    12608, 12624,     0,  8192, 12288, 12544, 12608, 12640, 
+    12632,     0,  8192, 12288, 12544, 12608, 12640, 12632, 
+        0,  8192, 12288, 12544, 12608, 12640, 12632, 12634, 
+        0,  8192, 12288, 12544, 12608, 12640, 12632,     0, 
+     8192, 12288, 12544, 12608, 12640, 12641, 12636,     0, 
+     8192, 12288, 12544, 12608, 12640, 12641, 12636,     0, 
+     8192, 12288, 12544, 12608, 12640, 12641, 12636, 12638, 
+        0,  8192, 12288, 12544, 12608,     0,  8192, 12288, 
+    12544, 12672, 12640,     0,  8192, 12288, 12544, 12672, 
+    12640,     0,  8192, 12288, 12544, 12672, 12640, 12642, 
+        0,  8192, 12288, 12544, 12672, 12640,     0,  8192, 
+    12288, 12544, 12672, 12640, 12644,     0,  8192, 12288, 
+    12544, 12672, 12640, 12644,     0,  8192, 12288, 12544, 
+    12672, 12640, 12648, 12646,     0,  8192, 12288, 12544, 
+    12672, 12640,     0,  8192, 12288, 12544, 12672, 12640, 
+    12648,     0,  8192, 12288, 12544, 12672, 12640, 12648, 
+        0,  8192, 12288, 12544, 12672, 12640, 12648, 12650, 
+        0,  8192, 12288, 12544, 12672, 12640, 12648,     0, 
+     8192, 12288, 12544, 12672, 12640, 12656, 12652,     0, 
+     8192, 12288, 12544, 12672, 12640, 12656, 12652,     0, 
+     8192, 12288, 12544, 12672, 12640, 12656, 12657, 12654, 
+        0,  8192, 12288, 12544, 12672, 12640,     0,  8192, 
+    12288, 12544, 12672, 12673, 12656,     0,  8192, 12288, 
+    12544, 12672, 12673, 12656,     0,  8192, 12288, 12544, 
+    12672, 12673, 12656, 12658,     0,  8192, 12288, 12544, 
+    12672, 12673, 12656,     0,  8192, 12288, 12544, 12672, 
+    12673, 12656, 12660,     0,  8192, 12288, 12544, 12672, 
+    12673, 12656, 12660,     0,  8192, 12288, 12544, 12672, 
+    12673, 12656, 12664, 12662,     0,  8192, 12288, 12544, 
+    12672, 12673, 12656,     0,  8192, 12288, 12544, 12672, 
+    12673, 12656, 12664,     0,  8192, 12288, 12544, 12672, 
+    12673, 12675, 12664,     0,  8192, 12288, 12544, 12672, 
+    12673, 12675, 12664, 12666,     0,  8192, 12288, 12544, 
+    12672, 12673, 12675, 12664,     0,  8192, 12288, 12544, 
+    12672, 12673, 12675, 12664, 12668,     0,  8192, 12288, 
+    12544, 12672, 12673, 12675, 12664, 12668,     0,  8192, 
+    12288, 12544, 12672, 12673, 12675, 12664, 12668, 12670, 
+        0,  8192, 12288, 12544,     0,  8192, 12288, 12800, 
+    12672,     0,  8192, 12288, 12800, 12672,     0,  8192, 
+    12288, 12800, 12672, 12674,     0,  8192, 12288, 12800, 
+    12672,     0,  8192, 12288, 12800, 12672, 12676,     0, 
+     8192, 12288, 12800, 12672, 12676,     0,  8192, 12288, 
+    12800, 12672, 12680, 12678,     0,  8192, 12288, 12800, 
+    12672,     0,  8192, 12288, 12800, 12672, 12680,     0, 
+     8192, 12288, 12800, 12672, 12680,     0,  8192, 12288, 
+    12800, 12672, 12680, 12682,     0,  8192, 12288, 12800, 
+    12672, 12680,     0,  8192, 12288, 12800, 12672, 12688, 
+    12684,     0,  8192, 12288, 12800, 12672, 12688, 12684, 
+        0,  8192, 12288, 12800, 12672, 12688, 12689, 12686, 
+        0,  8192, 12288, 12800, 12672,     0,  8192, 12288, 
+    12800, 12672, 12688,     0,  8192, 12288, 12800, 12672, 
+    12688,     0,  8192, 12288, 12800, 12672, 12688, 12690, 
+        0,  8192, 12288, 12800, 12672, 12688,     0,  8192, 
+    12288, 12800, 12672, 12688, 12692,     0,  8192, 12288, 
+    12800, 12672, 12688, 12692,     0,  8192, 12288, 12800, 
+    12672, 12688, 12696, 12694,     0,  8192, 12288, 12800, 
+    12672, 12688,     0,  8192, 12288, 12800, 12672, 12704, 
+    12696,     0,  8192, 12288, 12800, 12672, 12704, 12696, 
+        0,  8192, 12288, 12800, 12672, 12704, 12696, 12698, 
+        0,  8192, 12288, 12800, 12672, 12704, 12696,     0, 
+     8192, 12288, 12800, 12672, 12704, 12705, 12700,     0, 
+     8192, 12288, 12800, 12672, 12704, 12705, 12700,     0, 
+     8192, 12288, 12800, 12672, 12704, 12705, 12700, 12702, 
+        0,  8192, 12288, 12800, 12672,     0,  8192, 12288, 
+    12800, 12672, 12704,     0,  8192, 12288, 12800, 12672, 
+    12704,     0,  8192, 12288, 12800, 12672, 12704, 12706, 
+        0,  8192, 12288, 12800, 12672, 12704,     0,  8192, 
+    12288, 12800, 12672, 12704, 12708,     0,  8192, 12288, 
+    12800, 12672, 12704, 12708,     0,  8192, 12288, 12800, 
+    12672, 12704, 12712, 12710,     0,  8192, 12288, 12800, 
+    12672, 12704,     0,  8192, 12288, 12800, 12672, 12704, 
+    12712,     0,  8192, 12288, 12800, 12672, 12704, 12712, 
+        0,  8192, 12288, 12800, 12672, 12704, 12712, 12714, 
+        0,  8192, 12288, 12800, 12672, 12704, 12712,     0, 
+     8192, 12288, 12800, 12672, 12704, 12720, 12716,     0, 
+     8192, 12288, 12800, 12672, 12704, 12720, 12716,     0, 
+     8192, 12288, 12800, 12672, 12704, 12720, 12721, 12718, 
+        0,  8192, 12288, 12800, 12672, 12704,     0,  8192, 
+    12288, 12800, 12672, 12736, 12720,     0,  8192, 12288, 
+    12800, 12672, 12736, 12720,     0,  8192, 12288, 12800, 
+    12672, 12736, 12720, 12722,     0,  8192, 12288, 12800, 
+    12672, 12736, 12720,     0,  8192, 12288, 12800, 12672, 
+    12736, 12720, 12724,     0,  8192, 12288, 12800, 12672, 
+    12736, 12720, 12724,     0,  8192, 12288, 12800, 12672, 
+    12736, 12720, 12728, 12726,     0,  8192, 12288, 12800, 
+    12672, 12736, 12720,     0,  8192, 12288, 12800, 12672, 
+    12736, 12737, 12728,     0,  8192, 12288, 12800, 12672, 
+    12736, 12737, 12728,     0,  8192, 12288, 12800, 12672, 
+    12736, 12737, 12728, 12730,     0,  8192, 12288, 12800, 
+    12672, 12736, 12737, 12728,     0,  8192, 12288, 12800, 
+    12672, 12736, 12737, 12728, 12732,     0,  8192, 12288, 
+    12800, 12672, 12736, 12737, 12739, 12732,     0,  8192, 
+    12288, 12800, 12672, 12736, 12737, 12739, 12732, 12734, 
+        0,  8192, 12288, 12800, 12672,     0,  8192, 12288, 
+    12800, 12801, 12736,     0,  8192, 12288, 12800, 12801, 
+    12736,     0,  8192, 12288, 12800, 12801, 12736, 12738, 
+        0,  8192, 12288, 12800, 12801, 12736,     0,  8192, 
+    12288, 12800, 12801, 12736, 12740,     0,  8192, 12288, 
+    12800, 12801, 12736, 12740,     0,  8192, 12288, 12800, 
+    12801, 12736, 12744, 12742,     0,  8192, 12288, 12800, 
+    12801, 12736,     0,  8192, 12288, 12800, 12801, 12736, 
+    12744,     0,  8192, 12288, 12800, 12801, 12736, 12744, 
+        0,  8192, 12288, 12800, 12801, 12736, 12744, 12746, 
+        0,  8192, 12288, 12800, 12801, 12736, 12744,     0, 
+     8192, 12288, 12800, 12801, 12736, 12752, 12748,     0, 
+     8192, 12288, 12800, 12801, 12736, 12752, 12748,     0, 
+     8192, 12288, 12800, 12801, 12736, 12752, 12753, 12750, 
+        0,  8192, 12288, 12800, 12801, 12736,     0,  8192, 
+    12288, 12800, 12801, 12736, 12752,     0,  8192, 12288, 
+    12800, 12801, 12736, 12752,     0,  8192, 12288, 12800, 
+    12801, 12736, 12752, 12754,     0,  8192, 12288, 12800, 
+    12801, 12736, 12752,     0,  8192, 12288, 12800, 12801, 
+    12736, 12752, 12756,     0,  8192, 12288, 12800, 12801, 
+    12736, 12752, 12756,     0,  8192, 12288, 12800, 12801, 
+    12736, 12752, 12760, 12758,     0,  8192, 12288, 12800, 
+    12801, 12736, 12752,     0,  8192, 12288, 12800, 12801, 
+    12736, 12768, 12760,     0,  8192, 12288, 12800, 12801, 
+    12736, 12768, 12760,     0,  8192, 12288, 12800, 12801, 
+    12736, 12768, 12760, 12762,     0,  8192, 12288, 12800, 
+    12801, 12736, 12768, 12760,     0,  8192, 12288, 12800, 
+    12801, 12736, 12768, 12769, 12764,     0,  8192, 12288, 
+    12800, 12801, 12736, 12768, 12769, 12764,     0,  8192, 
+    12288, 12800, 12801, 12736, 12768, 12769, 12764, 12766, 
+        0,  8192, 12288, 12800, 12801, 12736,     0,  8192, 
+    12288, 12800, 12801, 12736, 12768,     0,  8192, 12288, 
+    12800, 12801, 12803, 12768,     0,  8192, 12288, 12800, 
+    12801, 12803, 12768, 12770,     0,  8192, 12288, 12800, 
+    12801, 12803, 12768,     0,  8192, 12288, 12800, 12801, 
+    12803, 12768, 12772,     0,  8192, 12288, 12800, 12801, 
+    12803, 12768, 12772,     0,  8192, 12288, 12800, 12801, 
+    12803, 12768, 12776, 12774,     0,  8192, 12288, 12800, 
+    12801, 12803, 12768,     0,  8192, 12288, 12800, 12801, 
+    12803, 12768, 12776,     0,  8192, 12288, 12800, 12801, 
+    12803, 12768, 12776,     0,  8192, 12288, 12800, 12801, 
+    12803, 12768, 12776, 12778,     0,  8192, 12288, 12800, 
+    12801, 12803, 12768, 12776,     0,  8192, 12288, 12800, 
+    12801, 12803, 12768, 12784, 12780,     0,  8192, 12288, 
+    12800, 12801, 12803, 12768, 12784, 12780,     0,  8192, 
+    12288, 12800, 12801, 12803, 12768, 12784, 12785, 12782, 
+        0,  8192, 12288, 12800, 12801, 12803, 12768,     0, 
+     8192, 12288, 12800, 12801, 12803, 12768, 12784,     0, 
+     8192, 12288, 12800, 12801, 12803, 12768, 12784,     0, 
+     8192, 12288, 12800, 12801, 12803, 12768, 12784, 12786, 
+        0,  8192, 12288, 12800, 12801, 12803, 12807, 12784, 
+        0,  8192, 12288, 12800, 12801, 12803, 12807, 12784, 
+    12788,     0,  8192, 12288, 12800, 12801, 12803, 12807, 
+    12784, 12788,     0,  8192, 12288, 12800, 12801, 12803, 
+    12807, 12784, 12792, 12790,     0,  8192, 12288, 12800, 
+    12801, 12803, 12807, 12784,     0,  8192, 12288, 12800, 
+    12801, 12803, 12807, 12784, 12792,     0,  8192, 12288, 
+    12800, 12801, 12803, 12807, 12784, 12792,     0,  8192, 
+    12288, 12800, 12801, 12803, 12807, 12784, 12792, 12794, 
+        0,  8192, 12288, 12800, 12801, 12803, 12807, 12784, 
+    12792,     0,  8192, 12288, 12800, 12801, 12803, 12807, 
+    12784, 12792, 12796,     0,  8192, 12288, 12800, 12801, 
+    12803, 12807, 12784, 12792, 12796,     0,  8192, 12288, 
+    12800, 12801, 12803, 12807, 12784, 12792, 12796, 12798, 
+        0,  8192, 12288,     0,  8192, 12288, 12800,     0, 
+     8192, 12288, 12800,     0,  8192, 12288, 12800, 12802, 
+        0,  8192, 12288, 12800,     0,  8192, 12288, 12800, 
+    12804,     0,  8192, 12288, 12800, 12804,     0,  8192, 
+    12288, 12800, 12808, 12806,     0,  8192, 12288, 12800, 
+        0,  8192, 12288, 12800, 12808,     0,  8192, 12288, 
+    12800, 12808,     0,  8192, 12288, 12800, 12808, 12810, 
+        0,  8192, 12288, 12800, 12808,     0,  8192, 12288, 
+    12800, 12816, 12812,     0,  8192, 12288, 12800, 12816, 
+    12812,     0,  8192, 12288, 12800, 12816, 12817, 12814, 
+        0,  8192, 12288, 12800,     0,  8192, 12288, 12800, 
+    12816,     0,  8192, 12288, 12800, 12816,     0,  8192, 
+    12288, 12800, 12816, 12818,     0,  8192, 12288, 12800, 
+    12816,     0,  8192, 12288, 12800, 12816, 12820,     0, 
+     8192, 12288, 12800, 12816, 12820,     0,  8192, 12288, 
+    12800, 12816, 12824, 12822,     0,  8192, 12288, 12800, 
+    12816,     0,  8192, 12288, 12800, 12832, 12824,     0, 
+     8192, 12288, 12800, 12832, 12824,     0,  8192, 12288, 
+    12800, 12832, 12824, 12826,     0,  8192, 12288, 12800, 
+    12832, 12824,     0,  8192, 12288, 12800, 12832, 12833, 
+    12828,     0,  8192, 12288, 12800, 12832, 12833, 12828, 
+        0,  8192, 12288, 12800, 12832, 12833, 12828, 12830, 
+        0,  8192, 12288, 12800,     0,  8192, 12288, 12800, 
+    12832,     0,  8192, 12288, 12800, 12832,     0,  8192, 
+    12288, 12800, 12832, 12834,     0,  8192, 12288, 12800, 
+    12832,     0,  8192, 12288, 12800, 12832, 12836,     0, 
+     8192, 12288, 12800, 12832, 12836,     0,  8192, 12288, 
+    12800, 12832, 12840, 12838,     0,  8192, 12288, 12800, 
+    12832,     0,  8192, 12288, 12800, 12832, 12840,     0, 
+     8192, 12288, 12800, 12832, 12840,     0,  8192, 12288, 
+    12800, 12832, 12840, 12842,     0,  8192, 12288, 12800, 
+    12832, 12840,     0,  8192, 12288, 12800, 12832, 12848, 
+    12844,     0,  8192, 12288, 12800, 12832, 12848, 12844, 
+        0,  8192, 12288, 12800, 12832, 12848, 12849, 12846, 
+        0,  8192, 12288, 12800, 12832,     0,  8192, 12288, 
+    12800, 12864, 12848,     0,  8192, 12288, 12800, 12864, 
+    12848,     0,  8192, 12288, 12800, 12864, 12848, 12850, 
+        0,  8192, 12288, 12800, 12864, 12848,     0,  8192, 
+    12288, 12800, 12864, 12848, 12852,     0,  8192, 12288, 
+    12800, 12864, 12848, 12852,     0,  8192, 12288, 12800, 
+    12864, 12848, 12856, 12854,     0,  8192, 12288, 12800, 
+    12864, 12848,     0,  8192, 12288, 12800, 12864, 12865, 
+    12856,     0,  8192, 12288, 12800, 12864, 12865, 12856, 
+        0,  8192, 12288, 12800, 12864, 12865, 12856, 12858, 
+        0,  8192, 12288, 12800, 12864, 12865, 12856,     0, 
+     8192, 12288, 12800, 12864, 12865, 12856, 12860,     0, 
+     8192, 12288, 12800, 12864, 12865, 12867, 12860,     0, 
+     8192, 12288, 12800, 12864, 12865, 12867, 12860, 12862, 
+        0,  8192, 12288, 12800,     0,  8192, 12288, 12800, 
+    12864,     0,  8192, 12288, 12800, 12864,     0,  8192, 
+    12288, 12800, 12864, 12866,     0,  8192, 12288, 12800, 
+    12864,     0,  8192, 12288, 12800, 12864, 12868,     0, 
+     8192, 12288, 12800, 12864, 12868,     0,  8192, 12288, 
+    12800, 12864, 12872, 12870,     0,  8192, 12288, 12800, 
+    12864,     0,  8192, 12288, 12800, 12864, 12872,     0, 
+     8192, 12288, 12800, 12864, 12872,     0,  8192, 12288, 
+    12800, 12864, 12872, 12874,     0,  8192, 12288, 12800, 
+    12864, 12872,     0,  8192, 12288, 12800, 12864, 12880, 
+    12876,     0,  8192, 12288, 12800, 12864, 12880, 12876, 
+        0,  8192, 12288, 12800, 12864, 12880, 12881, 12878, 
+        0,  8192, 12288, 12800, 12864,     0,  8192, 12288, 
+    12800, 12864, 12880,     0,  8192, 12288, 12800, 12864, 
+    12880,     0,  8192, 12288, 12800, 12864, 12880, 12882, 
+        0,  8192, 12288, 12800, 12864, 12880,     0,  8192, 
+    12288, 12800, 12864, 12880, 12884,     0,  8192, 12288, 
+    12800, 12864, 12880, 12884,     0,  8192, 12288, 12800, 
+    12864, 12880, 12888, 12886,     0,  8192, 12288, 12800, 
+    12864, 12880,     0,  8192, 12288, 12800, 12864, 12896, 
+    12888,     0,  8192, 12288, 12800, 12864, 12896, 12888, 
+        0,  8192, 12288, 12800, 12864, 12896, 12888, 12890, 
+        0,  8192, 12288, 12800, 12864, 12896, 12888,     0, 
+     8192, 12288, 12800, 12864, 12896, 12897, 12892,     0, 
+     8192, 12288, 12800, 12864, 12896, 12897, 12892,     0, 
+     8192, 12288, 12800, 12864, 12896, 12897, 12892, 12894, 
+        0,  8192, 12288, 12800, 12864,     0,  8192, 12288, 
+    12800, 12928, 12896,     0,  8192, 12288, 12800, 12928, 
+    12896,     0,  8192, 12288, 12800, 12928, 12896, 12898, 
+        0,  8192, 12288, 12800, 12928, 12896,     0,  8192, 
+    12288, 12800, 12928, 12896, 12900,     0,  8192, 12288, 
+    12800, 12928, 12896, 12900,     0,  8192, 12288, 12800, 
+    12928, 12896, 12904, 12902,     0,  8192, 12288, 12800, 
+    12928, 12896,     0,  8192, 12288, 12800, 12928, 12896, 
+    12904,     0,  8192, 12288, 12800, 12928, 12896, 12904, 
+        0,  8192, 12288, 12800, 12928, 12896, 12904, 12906, 
+        0,  8192, 12288, 12800, 12928, 12896, 12904,     0, 
+     8192, 12288, 12800, 12928, 12896, 12912, 12908,     0, 
+     8192, 12288, 12800, 12928, 12896, 12912, 12908,     0, 
+     8192, 12288, 12800, 12928, 12896, 12912, 12913, 12910, 
+        0,  8192, 12288, 12800, 12928, 12896,     0,  8192, 
+    12288, 12800, 12928, 12929, 12912,     0,  8192, 12288, 
+    12800, 12928, 12929, 12912,     0,  8192, 12288, 12800, 
+    12928, 12929, 12912, 12914,     0,  8192, 12288, 12800, 
+    12928, 12929, 12912,     0,  8192, 12288, 12800, 12928, 
+    12929, 12912, 12916,     0,  8192, 12288, 12800, 12928, 
+    12929, 12912, 12916,     0,  8192, 12288, 12800, 12928, 
+    12929, 12912, 12920, 12918,     0,  8192, 12288, 12800, 
+    12928, 12929, 12912,     0,  8192, 12288, 12800, 12928, 
+    12929, 12912, 12920,     0,  8192, 12288, 12800, 12928, 
+    12929, 12931, 12920,     0,  8192, 12288, 12800, 12928, 
+    12929, 12931, 12920, 12922,     0,  8192, 12288, 12800, 
+    12928, 12929, 12931, 12920,     0,  8192, 12288, 12800, 
+    12928, 12929, 12931, 12920, 12924,     0,  8192, 12288, 
+    12800, 12928, 12929, 12931, 12920, 12924,     0,  8192, 
+    12288, 12800, 12928, 12929, 12931, 12920, 12924, 12926, 
+        0,  8192, 12288, 12800,     0,  8192, 12288, 12800, 
+    12928,     0,  8192, 12288, 12800, 12928,     0,  8192, 
+    12288, 12800, 12928, 12930,     0,  8192, 12288, 12800, 
+    12928,     0,  8192, 12288, 12800, 12928, 12932,     0, 
+     8192, 12288, 12800, 12928, 12932,     0,  8192, 12288, 
+    12800, 12928, 12936, 12934,     0,  8192, 12288, 12800, 
+    12928,     0,  8192, 12288, 12800, 12928, 12936,     0, 
+     8192, 12288, 12800, 12928, 12936,     0,  8192, 12288, 
+    12800, 12928, 12936, 12938,     0,  8192, 12288, 12800, 
+    12928, 12936,     0,  8192, 12288, 12800, 12928, 12944, 
+    12940,     0,  8192, 12288, 12800, 12928, 12944, 12940, 
+        0,  8192, 12288, 12800, 12928, 12944, 12945, 12942, 
+        0,  8192, 12288, 12800, 12928,     0,  8192, 12288, 
+    12800, 12928, 12944,     0,  8192, 12288, 12800, 12928, 
+    12944,     0,  8192, 12288, 12800, 12928, 12944, 12946, 
+        0,  8192, 12288, 12800, 12928, 12944,     0,  8192, 
+    12288, 12800, 12928, 12944, 12948,     0,  8192, 12288, 
+    12800, 12928, 12944, 12948,     0,  8192, 12288, 12800, 
+    12928, 12944, 12952, 12950,     0,  8192, 12288, 12800, 
+    12928, 12944,     0,  8192, 12288, 12800, 12928, 12960, 
+    12952,     0,  8192, 12288, 12800, 12928, 12960, 12952, 
+        0,  8192, 12288, 12800, 12928, 12960, 12952, 12954, 
+        0,  8192, 12288, 12800, 12928, 12960, 12952,     0, 
+     8192, 12288, 12800, 12928, 12960, 12961, 12956,     0, 
+     8192, 12288, 12800, 12928, 12960, 12961, 12956,     0, 
+     8192, 12288, 12800, 12928, 12960, 12961, 12956, 12958, 
+        0,  8192, 12288, 12800, 12928,     0,  8192, 12288, 
+    12800, 12928, 12960,     0,  8192, 12288, 12800, 12928, 
+    12960,     0,  8192, 12288, 12800, 12928, 12960, 12962, 
+        0,  8192, 12288, 12800, 12928, 12960,     0,  8192, 
+    12288, 12800, 12928, 12960, 12964,     0,  8192, 12288, 
+    12800, 12928, 12960, 12964,     0,  8192, 12288, 12800, 
+    12928, 12960, 12968, 12966,     0,  8192, 12288, 12800, 
+    12928, 12960,     0,  8192, 12288, 12800, 12928, 12960, 
+    12968,     0,  8192, 12288, 12800, 12928, 12960, 12968, 
+        0,  8192, 12288, 12800, 12928, 12960, 12968, 12970, 
+        0,  8192, 12288, 12800, 12928, 12960, 12968,     0, 
+     8192, 12288, 12800, 12928, 12960, 12976, 12972,     0, 
+     8192, 12288, 12800, 12928, 12960, 12976, 12972,     0, 
+     8192, 12288, 12800, 12928, 12960, 12976, 12977, 12974, 
+        0,  8192, 12288, 12800, 12928, 12960,     0,  8192, 
+    12288, 12800, 12928, 12992, 12976,     0,  8192, 12288, 
+    12800, 12928, 12992, 12976,     0,  8192, 12288, 12800, 
+    12928, 12992, 12976, 12978,     0,  8192, 12288, 12800, 
+    12928, 12992, 12976,     0,  8192, 12288, 12800, 12928, 
+    12992, 12976, 12980,     0,  8192, 12288, 12800, 12928, 
+    12992, 12976, 12980,     0,  8192, 12288, 12800, 12928, 
+    12992, 12976, 12984, 12982,     0,  8192, 12288, 12800, 
+    12928, 12992, 12976,     0,  8192, 12288, 12800, 12928, 
+    12992, 12993, 12984,     0,  8192, 12288, 12800, 12928, 
+    12992, 12993, 12984,     0,  8192, 12288, 12800, 12928, 
+    12992, 12993, 12984, 12986,     0,  8192, 12288, 12800, 
+    12928, 12992, 12993, 12984,     0,  8192, 12288, 12800, 
+    12928, 12992, 12993, 12984, 12988,     0,  8192, 12288, 
+    12800, 12928, 12992, 12993, 12995, 12988,     0,  8192, 
+    12288, 12800, 12928, 12992, 12993, 12995, 12988, 12990, 
+        0,  8192, 12288, 12800, 12928,     0,  8192, 12288, 
+    12800, 13056, 12992,     0,  8192, 12288, 12800, 13056, 
+    12992,     0,  8192, 12288, 12800, 13056, 12992, 12994, 
+        0,  8192, 12288, 12800, 13056, 12992,     0,  8192, 
+    12288, 12800, 13056, 12992, 12996,     0,  8192, 12288, 
+    12800, 13056, 12992, 12996,     0,  8192, 12288, 12800, 
+    13056, 12992, 13000, 12998,     0,  8192, 12288, 12800, 
+    13056, 12992,     0,  8192, 12288, 12800, 13056, 12992, 
+    13000,     0,  8192, 12288, 12800, 13056, 12992, 13000, 
+        0,  8192, 12288, 12800, 13056, 12992, 13000, 13002, 
+        0,  8192, 12288, 12800, 13056, 12992, 13000,     0, 
+     8192, 12288, 12800, 13056, 12992, 13008, 13004,     0, 
+     8192, 12288, 12800, 13056, 12992, 13008, 13004,     0, 
+     8192, 12288, 12800, 13056, 12992, 13008, 13009, 13006, 
+        0,  8192, 12288, 12800, 13056, 12992,     0,  8192, 
+    12288, 12800, 13056, 12992, 13008,     0,  8192, 12288, 
+    12800, 13056, 12992, 13008,     0,  8192, 12288, 12800, 
+    13056, 12992, 13008, 13010,     0,  8192, 12288, 12800, 
+    13056, 12992, 13008,     0,  8192, 12288, 12800, 13056, 
+    12992, 13008, 13012,     0,  8192, 12288, 12800, 13056, 
+    12992, 13008, 13012,     0,  8192, 12288, 12800, 13056, 
+    12992, 13008, 13016, 13014,     0,  8192, 12288, 12800, 
+    13056, 12992, 13008,     0,  8192, 12288, 12800, 13056, 
+    12992, 13024, 13016,     0,  8192, 12288, 12800, 13056, 
+    12992, 13024, 13016,     0,  8192, 12288, 12800, 13056, 
+    12992, 13024, 13016, 13018,     0,  8192, 12288, 12800, 
+    13056, 12992, 13024, 13016,     0,  8192, 12288, 12800, 
+    13056, 12992, 13024, 13025, 13020,     0,  8192, 12288, 
+    12800, 13056, 12992, 13024, 13025, 13020,     0,  8192, 
+    12288, 12800, 13056, 12992, 13024, 13025, 13020, 13022, 
+        0,  8192, 12288, 12800, 13056, 12992,     0,  8192, 
+    12288, 12800, 13056, 13057, 13024,     0,  8192, 12288, 
+    12800, 13056, 13057, 13024,     0,  8192, 12288, 12800, 
+    13056, 13057, 13024, 13026,     0,  8192, 12288, 12800, 
+    13056, 13057, 13024,     0,  8192, 12288, 12800, 13056, 
+    13057, 13024, 13028,     0,  8192, 12288, 12800, 13056, 
+    13057, 13024, 13028,     0,  8192, 12288, 12800, 13056, 
+    13057, 13024, 13032, 13030,     0,  8192, 12288, 12800, 
+    13056, 13057, 13024,     0,  8192, 12288, 12800, 13056, 
+    13057, 13024, 13032,     0,  8192, 12288, 12800, 13056, 
+    13057, 13024, 13032,     0,  8192, 12288, 12800, 13056, 
+    13057, 13024, 13032, 13034,     0,  8192, 12288, 12800, 
+    13056, 13057, 13024, 13032,     0,  8192, 12288, 12800, 
+    13056, 13057, 13024, 13040, 13036,     0,  8192, 12288, 
+    12800, 13056, 13057, 13024, 13040, 13036,     0,  8192, 
+    12288, 12800, 13056, 13057, 13024, 13040, 13041, 13038, 
+        0,  8192, 12288, 12800, 13056, 13057, 13024,     0, 
+     8192, 12288, 12800, 13056, 13057, 13024, 13040,     0, 
+     8192, 12288, 12800, 13056, 13057, 13059, 13040,     0, 
+     8192, 12288, 12800, 13056, 13057, 13059, 13040, 13042, 
+        0,  8192, 12288, 12800, 13056, 13057, 13059, 13040, 
+        0,  8192, 12288, 12800, 13056, 13057, 13059, 13040, 
+    13044,     0,  8192, 12288, 12800, 13056, 13057, 13059, 
+    13040, 13044,     0,  8192, 12288, 12800, 13056, 13057, 
+    13059, 13040, 13048, 13046,     0,  8192, 12288, 12800, 
+    13056, 13057, 13059, 13040,     0,  8192, 12288, 12800, 
+    13056, 13057, 13059, 13040, 13048,     0,  8192, 12288, 
+    12800, 13056, 13057, 13059, 13040, 13048,     0,  8192, 
+    12288, 12800, 13056, 13057, 13059, 13040, 13048, 13050, 
+        0,  8192, 12288, 12800, 13056, 13057, 13059, 13063, 
+    13048,     0,  8192, 12288, 12800, 13056, 13057, 13059, 
+    13063, 13048, 13052,     0,  8192, 12288, 12800, 13056, 
+    13057, 13059, 13063, 13048, 13052,     0,  8192, 12288, 
+    12800, 13056, 13057, 13059, 13063, 13048, 13052, 13054, 
+        0,  8192, 12288, 12800,     0,  8192, 12288, 13312, 
+    13056,     0,  8192, 12288, 13312, 13056,     0,  8192, 
+    12288, 13312, 13056, 13058,     0,  8192, 12288, 13312, 
+    13056,     0,  8192, 12288, 13312, 13056, 13060,     0, 
+     8192, 12288, 13312, 13056, 13060,     0,  8192, 12288, 
+    13312, 13056, 13064, 13062,     0,  8192, 12288, 13312, 
+    13056,     0,  8192, 12288, 13312, 13056, 13064,     0, 
+     8192, 12288, 13312, 13056, 13064,     0,  8192, 12288, 
+    13312, 13056, 13064, 13066,     0,  8192, 12288, 13312, 
+    13056, 13064,     0,  8192, 12288, 13312, 13056, 13072, 
+    13068,     0,  8192, 12288, 13312, 13056, 13072, 13068, 
+        0,  8192, 12288, 13312, 13056, 13072, 13073, 13070, 
+        0,  8192, 12288, 13312, 13056,     0,  8192, 12288, 
+    13312, 13056, 13072,     0,  8192, 12288, 13312, 13056, 
+    13072,     0,  8192, 12288, 13312, 13056, 13072, 13074, 
+        0,  8192, 12288, 13312, 13056, 13072,     0,  8192, 
+    12288, 13312, 13056, 13072, 13076,     0,  8192, 12288, 
+    13312, 13056, 13072, 13076,     0,  8192, 12288, 13312, 
+    13056, 13072, 13080, 13078,     0,  8192, 12288, 13312, 
+    13056, 13072,     0,  8192, 12288, 13312, 13056, 13088, 
+    13080,     0,  8192, 12288, 13312, 13056, 13088, 13080, 
+        0,  8192, 12288, 13312, 13056, 13088, 13080, 13082, 
+        0,  8192, 12288, 13312, 13056, 13088, 13080,     0, 
+     8192, 12288, 13312, 13056, 13088, 13089, 13084,     0, 
+     8192, 12288, 13312, 13056, 13088, 13089, 13084,     0, 
+     8192, 12288, 13312, 13056, 13088, 13089, 13084, 13086, 
+        0,  8192, 12288, 13312, 13056,     0,  8192, 12288, 
+    13312, 13056, 13088,     0,  8192, 12288, 13312, 13056, 
+    13088,     0,  8192, 12288, 13312, 13056, 13088, 13090, 
+        0,  8192, 12288, 13312, 13056, 13088,     0,  8192, 
+    12288, 13312, 13056, 13088, 13092,     0,  8192, 12288, 
+    13312, 13056, 13088, 13092,     0,  8192, 12288, 13312, 
+    13056, 13088, 13096, 13094,     0,  8192, 12288, 13312, 
+    13056, 13088,     0,  8192, 12288, 13312, 13056, 13088, 
+    13096,     0,  8192, 12288, 13312, 13056, 13088, 13096, 
+        0,  8192, 12288, 13312, 13056, 13088, 13096, 13098, 
+        0,  8192, 12288, 13312, 13056, 13088, 13096,     0, 
+     8192, 12288, 13312, 13056, 13088, 13104, 13100,     0, 
+     8192, 12288, 13312, 13056, 13088, 13104, 13100,     0, 
+     8192, 12288, 13312, 13056, 13088, 13104, 13105, 13102, 
+        0,  8192, 12288, 13312, 13056, 13088,     0,  8192, 
+    12288, 13312, 13056, 13120, 13104,     0,  8192, 12288, 
+    13312, 13056, 13120, 13104,     0,  8192, 12288, 13312, 
+    13056, 13120, 13104, 13106,     0,  8192, 12288, 13312, 
+    13056, 13120, 13104,     0,  8192, 12288, 13312, 13056, 
+    13120, 13104, 13108,     0,  8192, 12288, 13312, 13056, 
+    13120, 13104, 13108,     0,  8192, 12288, 13312, 13056, 
+    13120, 13104, 13112, 13110,     0,  8192, 12288, 13312, 
+    13056, 13120, 13104,     0,  8192, 12288, 13312, 13056, 
+    13120, 13121, 13112,     0,  8192, 12288, 13312, 13056, 
+    13120, 13121, 13112,     0,  8192, 12288, 13312, 13056, 
+    13120, 13121, 13112, 13114,     0,  8192, 12288, 13312, 
+    13056, 13120, 13121, 13112,     0,  8192, 12288, 13312, 
+    13056, 13120, 13121, 13112, 13116,     0,  8192, 12288, 
+    13312, 13056, 13120, 13121, 13123, 13116,     0,  8192, 
+    12288, 13312, 13056, 13120, 13121, 13123, 13116, 13118, 
+        0,  8192, 12288, 13312, 13056,     0,  8192, 12288, 
+    13312, 13056, 13120,     0,  8192, 12288, 13312, 13056, 
+    13120,     0,  8192, 12288, 13312, 13056, 13120, 13122, 
+        0,  8192, 12288, 13312, 13056, 13120,     0,  8192, 
+    12288, 13312, 13056, 13120, 13124,     0,  8192, 12288, 
+    13312, 13056, 13120, 13124,     0,  8192, 12288, 13312, 
+    13056, 13120, 13128, 13126,     0,  8192, 12288, 13312, 
+    13056, 13120,     0,  8192, 12288, 13312, 13056, 13120, 
+    13128,     0,  8192, 12288, 13312, 13056, 13120, 13128, 
+        0,  8192, 12288, 13312, 13056, 13120, 13128, 13130, 
+        0,  8192, 12288, 13312, 13056, 13120, 13128,     0, 
+     8192, 12288, 13312, 13056, 13120, 13136, 13132,     0, 
+     8192, 12288, 13312, 13056, 13120, 13136, 13132,     0, 
+     8192, 12288, 13312, 13056, 13120, 13136, 13137, 13134, 
+        0,  8192, 12288, 13312, 13056, 13120,     0,  8192, 
+    12288, 13312, 13056, 13120, 13136,     0,  8192, 12288, 
+    13312, 13056, 13120, 13136,     0,  8192, 12288, 13312, 
+    13056, 13120, 13136, 13138,     0,  8192, 12288, 13312, 
+    13056, 13120, 13136,     0,  8192, 12288, 13312, 13056, 
+    13120, 13136, 13140,     0,  8192, 12288, 13312, 13056, 
+    13120, 13136, 13140,     0,  8192, 12288, 13312, 13056, 
+    13120, 13136, 13144, 13142,     0,  8192, 12288, 13312, 
+    13056, 13120, 13136,     0,  8192, 12288, 13312, 13056, 
+    13120, 13152, 13144,     0,  8192, 12288, 13312, 13056, 
+    13120, 13152, 13144,     0,  8192, 12288, 13312, 13056, 
+    13120, 13152, 13144, 13146,     0,  8192, 12288, 13312, 
+    13056, 13120, 13152, 13144,     0,  8192, 12288, 13312, 
+    13056, 13120, 13152, 13153, 13148,     0,  8192, 12288, 
+    13312, 13056, 13120, 13152, 13153, 13148,     0,  8192, 
+    12288, 13312, 13056, 13120, 13152, 13153, 13148, 13150, 
+        0,  8192, 12288, 13312, 13056, 13120,     0,  8192, 
+    12288, 13312, 13056, 13184, 13152,     0,  8192, 12288, 
+    13312, 13056, 13184, 13152,     0,  8192, 12288, 13312, 
+    13056, 13184, 13152, 13154,     0,  8192, 12288, 13312, 
+    13056, 13184, 13152,     0,  8192, 12288, 13312, 13056, 
+    13184, 13152, 13156,     0,  8192, 12288, 13312, 13056, 
+    13184, 13152, 13156,     0,  8192, 12288, 13312, 13056, 
+    13184, 13152, 13160, 13158,     0,  8192, 12288, 13312, 
+    13056, 13184, 13152,     0,  8192, 12288, 13312, 13056, 
+    13184, 13152, 13160,     0,  8192, 12288, 13312, 13056, 
+    13184, 13152, 13160,     0,  8192, 12288, 13312, 13056, 
+    13184, 13152, 13160, 13162,     0,  8192, 12288, 13312, 
+    13056, 13184, 13152, 13160,     0,  8192, 12288, 13312, 
+    13056, 13184, 13152, 13168, 13164,     0,  8192, 12288, 
+    13312, 13056, 13184, 13152, 13168, 13164,     0,  8192, 
+    12288, 13312, 13056, 13184, 13152, 13168, 13169, 13166, 
+        0,  8192, 12288, 13312, 13056, 13184, 13152,     0, 
+     8192, 12288, 13312, 13056, 13184, 13185, 13168,     0, 
+     8192, 12288, 13312, 13056, 13184, 13185, 13168,     0, 
+     8192, 12288, 13312, 13056, 13184, 13185, 13168, 13170, 
+        0,  8192, 12288, 13312, 13056, 13184, 13185, 13168, 
+        0,  8192, 12288, 13312, 13056, 13184, 13185, 13168, 
+    13172,     0,  8192, 12288, 13312, 13056, 13184, 13185, 
+    13168, 13172,     0,  8192, 12288, 13312, 13056, 13184, 
+    13185, 13168, 13176, 13174,     0,  8192, 12288, 13312, 
+    13056, 13184, 13185, 13168,     0,  8192, 12288, 13312, 
+    13056, 13184, 13185, 13168, 13176,     0,  8192, 12288, 
+    13312, 13056, 13184, 13185, 13187, 13176,     0,  8192, 
+    12288, 13312, 13056, 13184, 13185, 13187, 13176, 13178, 
+        0,  8192, 12288, 13312, 13056, 13184, 13185, 13187, 
+    13176,     0,  8192, 12288, 13312, 13056, 13184, 13185, 
+    13187, 13176, 13180,     0,  8192, 12288, 13312, 13056, 
+    13184, 13185, 13187, 13176, 13180,     0,  8192, 12288, 
+    13312, 13056, 13184, 13185, 13187, 13176, 13180, 13182, 
+        0,  8192, 12288, 13312, 13056,     0,  8192, 12288, 
+    13312, 13056, 13184,     0,  8192, 12288, 13312, 13313, 
+    13184,     0,  8192, 12288, 13312, 13313, 13184, 13186, 
+        0,  8192, 12288, 13312, 13313, 13184,     0,  8192, 
+    12288, 13312, 13313, 13184, 13188,     0,  8192, 12288, 
+    13312, 13313, 13184, 13188,     0,  8192, 12288, 13312, 
+    13313, 13184, 13192, 13190,     0,  8192, 12288, 13312, 
+    13313, 13184,     0,  8192, 12288, 13312, 13313, 13184, 
+    13192,     0,  8192, 12288, 13312, 13313, 13184, 13192, 
+        0,  8192, 12288, 13312, 13313, 13184, 13192, 13194, 
+        0,  8192, 12288, 13312, 13313, 13184, 13192,     0, 
+     8192, 12288, 13312, 13313, 13184, 13200, 13196,     0, 
+     8192, 12288, 13312, 13313, 13184, 13200, 13196,     0, 
+     8192, 12288, 13312, 13313, 13184, 13200, 13201, 13198, 
+        0,  8192, 12288, 13312, 13313, 13184,     0,  8192, 
+    12288, 13312, 13313, 13184, 13200,     0,  8192, 12288, 
+    13312, 13313, 13184, 13200,     0,  8192, 12288, 13312, 
+    13313, 13184, 13200, 13202,     0,  8192, 12288, 13312, 
+    13313, 13184, 13200,     0,  8192, 12288, 13312, 13313, 
+    13184, 13200, 13204,     0,  8192, 12288, 13312, 13313, 
+    13184, 13200, 13204,     0,  8192, 12288, 13312, 13313, 
+    13184, 13200, 13208, 13206,     0,  8192, 12288, 13312, 
+    13313, 13184, 13200,     0,  8192, 12288, 13312, 13313, 
+    13184, 13216, 13208,     0,  8192, 12288, 13312, 13313, 
+    13184, 13216, 13208,     0,  8192, 12288, 13312, 13313, 
+    13184, 13216, 13208, 13210,     0,  8192, 12288, 13312, 
+    13313, 13184, 13216, 13208,     0,  8192, 12288, 13312, 
+    13313, 13184, 13216, 13217, 13212,     0,  8192, 12288, 
+    13312, 13313, 13184, 13216, 13217, 13212,     0,  8192, 
+    12288, 13312, 13313, 13184, 13216, 13217, 13212, 13214, 
+        0,  8192, 12288, 13312, 13313, 13184,     0,  8192, 
+    12288, 13312, 13313, 13184, 13216,     0,  8192, 12288, 
+    13312, 13313, 13184, 13216,     0,  8192, 12288, 13312, 
+    13313, 13184, 13216, 13218,     0,  8192, 12288, 13312, 
+    13313, 13184, 13216,     0,  8192, 12288, 13312, 13313, 
+    13184, 13216, 13220,     0,  8192, 12288, 13312, 13313, 
+    13184, 13216, 13220,     0,  8192, 12288, 13312, 13313, 
+    13184, 13216, 13224, 13222,     0,  8192, 12288, 13312, 
+    13313, 13184, 13216,     0,  8192, 12288, 13312, 13313, 
+    13184, 13216, 13224,     0,  8192, 12288, 13312, 13313, 
+    13184, 13216, 13224,     0,  8192, 12288, 13312, 13313, 
+    13184, 13216, 13224, 13226,     0,  8192, 12288, 13312, 
+    13313, 13184, 13216, 13224,     0,  8192, 12288, 13312, 
+    13313, 13184, 13216, 13232, 13228,     0,  8192, 12288, 
+    13312, 13313, 13184, 13216, 13232, 13228,     0,  8192, 
+    12288, 13312, 13313, 13184, 13216, 13232, 13233, 13230, 
+        0,  8192, 12288, 13312, 13313, 13184, 13216,     0, 
+     8192, 12288, 13312, 13313, 13184, 13248, 13232,     0, 
+     8192, 12288, 13312, 13313, 13184, 13248, 13232,     0, 
+     8192, 12288, 13312, 13313, 13184, 13248, 13232, 13234, 
+        0,  8192, 12288, 13312, 13313, 13184, 13248, 13232, 
+        0,  8192, 12288, 13312, 13313, 13184, 13248, 13232, 
+    13236,     0,  8192, 12288, 13312, 13313, 13184, 13248, 
+    13232, 13236,     0,  8192, 12288, 13312, 13313, 13184, 
+    13248, 13232, 13240, 13238,     0,  8192, 12288, 13312, 
+    13313, 13184, 13248, 13232,     0,  8192, 12288, 13312, 
+    13313, 13184, 13248, 13249, 13240,     0,  8192, 12288, 
+    13312, 13313, 13184, 13248, 13249, 13240,     0,  8192, 
+    12288, 13312, 13313, 13184, 13248, 13249, 13240, 13242, 
+        0,  8192, 12288, 13312, 13313, 13184, 13248, 13249, 
+    13240,     0,  8192, 12288, 13312, 13313, 13184, 13248, 
+    13249, 13240, 13244,     0,  8192, 12288, 13312, 13313, 
+    13184, 13248, 13249, 13251, 13244,     0,  8192, 12288, 
+    13312, 13313, 13184, 13248, 13249, 13251, 13244, 13246, 
+        0,  8192, 12288, 13312, 13313, 13184,     0,  8192, 
+    12288, 13312, 13313, 13184, 13248,     0,  8192, 12288, 
+    13312, 13313, 13184, 13248,     0,  8192, 12288, 13312, 
+    13313, 13184, 13248, 13250,     0,  8192, 12288, 13312, 
+    13313, 13315, 13248,     0,  8192, 12288, 13312, 13313, 
+    13315, 13248, 13252,     0,  8192, 12288, 13312, 13313, 
+    13315, 13248, 13252,     0,  8192, 12288, 13312, 13313, 
+    13315, 13248, 13256, 13254,     0,  8192, 12288, 13312, 
+    13313, 13315, 13248,     0,  8192, 12288, 13312, 13313, 
+    13315, 13248, 13256,     0,  8192, 12288, 13312, 13313, 
+    13315, 13248, 13256,     0,  8192, 12288, 13312, 13313, 
+    13315, 13248, 13256, 13258,     0,  8192, 12288, 13312, 
+    13313, 13315, 13248, 13256,     0,  8192, 12288, 13312, 
+    13313, 13315, 13248, 13264, 13260,     0,  8192, 12288, 
+    13312, 13313, 13315, 13248, 13264, 13260,     0,  8192, 
+    12288, 13312, 13313, 13315, 13248, 13264, 13265, 13262, 
+        0,  8192, 12288, 13312, 13313, 13315, 13248,     0, 
+     8192, 12288, 13312, 13313, 13315, 13248, 13264,     0, 
+     8192, 12288, 13312, 13313, 13315, 13248, 13264,     0, 
+     8192, 12288, 13312, 13313, 13315, 13248, 13264, 13266, 
+        0,  8192, 12288, 13312, 13313, 13315, 13248, 13264, 
+        0,  8192, 12288, 13312, 13313, 13315, 13248, 13264, 
+    13268,     0,  8192, 12288, 13312, 13313, 13315, 13248, 
+    13264, 13268,     0,  8192, 12288, 13312, 13313, 13315, 
+    13248, 13264, 13272, 13270,     0,  8192, 12288, 13312, 
+    13313, 13315, 13248, 13264,     0,  8192, 12288, 13312, 
+    13313, 13315, 13248, 13280, 13272,     0,  8192, 12288, 
+    13312, 13313, 13315, 13248, 13280, 13272,     0,  8192, 
+    12288, 13312, 13313, 13315, 13248, 13280, 13272, 13274, 
+        0,  8192, 12288, 13312, 13313, 13315, 13248, 13280, 
+    13272,     0,  8192, 12288, 13312, 13313, 13315, 13248, 
+    13280, 13281, 13276,     0,  8192, 12288, 13312, 13313, 
+    13315, 13248, 13280, 13281, 13276,     0,  8192, 12288, 
+    13312, 13313, 13315, 13248, 13280, 13281, 13276, 13278, 
+        0,  8192, 12288, 13312, 13313, 13315, 13248,     0, 
+     8192, 12288, 13312, 13313, 13315, 13248, 13280,     0, 
+     8192, 12288, 13312, 13313, 13315, 13248, 13280,     0, 
+     8192, 12288, 13312, 13313, 13315, 13248, 13280, 13282, 
+        0,  8192, 12288, 13312, 13313, 13315, 13248, 13280, 
+        0,  8192, 12288, 13312, 13313, 13315, 13248, 13280, 
+    13284,     0,  8192, 12288, 13312, 13313, 13315, 13248, 
+    13280, 13284,     0,  8192, 12288, 13312, 13313, 13315, 
+    13248, 13280, 13288, 13286,     0,  8192, 12288, 13312, 
+    13313, 13315, 13319, 13280,     0,  8192, 12288, 13312, 
+    13313, 13315, 13319, 13280, 13288,     0,  8192, 12288, 
+    13312, 13313, 13315, 13319, 13280, 13288,     0,  8192, 
+    12288, 13312, 13313, 13315, 13319, 13280, 13288, 13290, 
+        0,  8192, 12288, 13312, 13313, 13315, 13319, 13280, 
+    13288,     0,  8192, 12288, 13312, 13313, 13315, 13319, 
+    13280, 13296, 13292,     0,  8192, 12288, 13312, 13313, 
+    13315, 13319, 13280, 13296, 13292,     0,  8192, 12288, 
+    13312, 13313, 13315, 13319, 13280, 13296, 13297, 13294, 
+        0,  8192, 12288, 13312, 13313, 13315, 13319, 13280, 
+        0,  8192, 12288, 13312, 13313, 13315, 13319, 13280, 
+    13296,     0,  8192, 12288, 13312, 13313, 13315, 13319, 
+    13280, 13296,     0,  8192, 12288, 13312, 13313, 13315, 
+    13319, 13280, 13296, 13298,     0,  8192, 12288, 13312, 
+    13313, 13315, 13319, 13280, 13296,     0,  8192, 12288, 
+    13312, 13313, 13315, 13319, 13280, 13296, 13300,     0, 
+     8192, 12288, 13312, 13313, 13315, 13319, 13280, 13296, 
+    13300,     0,  8192, 12288, 13312, 13313, 13315, 13319, 
+    13280, 13296, 13304, 13302,     0,  8192, 12288, 13312, 
+    13313, 13315, 13319, 13280, 13296,     0,  8192, 12288, 
+    13312, 13313, 13315, 13319, 13280, 13296, 13304,     0, 
+     8192, 12288, 13312, 13313, 13315, 13319, 13280, 13296, 
+    13304,     0,  8192, 12288, 13312, 13313, 13315, 13319, 
+    13280, 13296, 13304, 13306,     0,  8192, 12288, 13312, 
+    13313, 13315, 13319, 13280, 13296, 13304,     0,  8192, 
+    12288, 13312, 13313, 13315, 13319, 13280, 13296, 13304, 
+    13308,     0,  8192, 12288, 13312, 13313, 13315, 13319, 
+    13280, 13296, 13304, 13308,     0,  8192, 12288, 13312, 
+    13313, 13315, 13319, 13280, 13296, 13304, 13308, 13310, 
+        0,  8192, 12288,     0,  8192, 12288, 13312,     0, 
+     8192, 12288, 13312,     0,  8192, 12288, 13312, 13314, 
+        0,  8192, 12288, 13312,     0,  8192, 12288, 13312, 
+    13316,     0,  8192, 12288, 13312, 13316,     0,  8192, 
+    12288, 13312, 13320, 13318,     0,  8192, 12288, 13312, 
+        0,  8192, 12288, 13312, 13320,     0,  8192, 12288, 
+    13312, 13320,     0,  8192, 12288, 13312, 13320, 13322, 
+        0,  8192, 12288, 13312, 13320,     0,  8192, 12288, 
+    13312, 13328, 13324,     0,  8192, 12288, 13312, 13328, 
+    13324,     0,  8192, 12288, 13312, 13328, 13329, 13326, 
+        0,  8192, 12288, 13312,     0,  8192, 12288, 13312, 
+    13328,     0,  8192, 12288, 13312, 13328,     0,  8192, 
+    12288, 13312, 13328, 13330,     0,  8192, 12288, 13312, 
+    13328,     0,  8192, 12288, 13312, 13328, 13332,     0, 
+     8192, 12288, 13312, 13328, 13332,     0,  8192, 12288, 
+    13312, 13328, 13336, 13334,     0,  8192, 12288, 13312, 
+    13328,     0,  8192, 12288, 13312, 13344, 13336,     0, 
+     8192, 12288, 13312, 13344, 13336,     0,  8192, 12288, 
+    13312, 13344, 13336, 13338,     0,  8192, 12288, 13312, 
+    13344, 13336,     0,  8192, 12288, 13312, 13344, 13345, 
+    13340,     0,  8192, 12288, 13312, 13344, 13345, 13340, 
+        0,  8192, 12288, 13312, 13344, 13345, 13340, 13342, 
+        0,  8192, 12288, 13312,     0,  8192, 12288, 13312, 
+    13344,     0,  8192, 12288, 13312, 13344,     0,  8192, 
+    12288, 13312, 13344, 13346,     0,  8192, 12288, 13312, 
+    13344,     0,  8192, 12288, 13312, 13344, 13348,     0, 
+     8192, 12288, 13312, 13344, 13348,     0,  8192, 12288, 
+    13312, 13344, 13352, 13350,     0,  8192, 12288, 13312, 
+    13344,     0,  8192, 12288, 13312, 13344, 13352,     0, 
+     8192, 12288, 13312, 13344, 13352,     0,  8192, 12288, 
+    13312, 13344, 13352, 13354,     0,  8192, 12288, 13312, 
+    13344, 13352,     0,  8192, 12288, 13312, 13344, 13360, 
+    13356,     0,  8192, 12288, 13312, 13344, 13360, 13356, 
+        0,  8192, 12288, 13312, 13344, 13360, 13361, 13358, 
+        0,  8192, 12288, 13312, 13344,     0,  8192, 12288, 
+    13312, 13376, 13360,     0,  8192, 12288, 13312, 13376, 
+    13360,     0,  8192, 12288, 13312, 13376, 13360, 13362, 
+        0,  8192, 12288, 13312, 13376, 13360,     0,  8192, 
+    12288, 13312, 13376, 13360, 13364,     0,  8192, 12288, 
+    13312, 13376, 13360, 13364,     0,  8192, 12288, 13312, 
+    13376, 13360, 13368, 13366,     0,  8192, 12288, 13312, 
+    13376, 13360,     0,  8192, 12288, 13312, 13376, 13377, 
+    13368,     0,  8192, 12288, 13312, 13376, 13377, 13368, 
+        0,  8192, 12288, 13312, 13376, 13377, 13368, 13370, 
+        0,  8192, 12288, 13312, 13376, 13377, 13368,     0, 
+     8192, 12288, 13312, 13376, 13377, 13368, 13372,     0, 
+     8192, 12288, 13312, 13376, 13377, 13379, 13372,     0, 
+     8192, 12288, 13312, 13376, 13377, 13379, 13372, 13374, 
+        0,  8192, 12288, 13312,     0,  8192, 12288, 13312, 
+    13376,     0,  8192, 12288, 13312, 13376,     0,  8192, 
+    12288, 13312, 13376, 13378,     0,  8192, 12288, 13312, 
+    13376,     0,  8192, 12288, 13312, 13376, 13380,     0, 
+     8192, 12288, 13312, 13376, 13380,     0,  8192, 12288, 
+    13312, 13376, 13384, 13382,     0,  8192, 12288, 13312, 
+    13376,     0,  8192, 12288, 13312, 13376, 13384,     0, 
+     8192, 12288, 13312, 13376, 13384,     0,  8192, 12288, 
+    13312, 13376, 13384, 13386,     0,  8192, 12288, 13312, 
+    13376, 13384,     0,  8192, 12288, 13312, 13376, 13392, 
+    13388,     0,  8192, 12288, 13312, 13376, 13392, 13388, 
+        0,  8192, 12288, 13312, 13376, 13392, 13393, 13390, 
+        0,  8192, 12288, 13312, 13376,     0,  8192, 12288, 
+    13312, 13376, 13392,     0,  8192, 12288, 13312, 13376, 
+    13392,     0,  8192, 12288, 13312, 13376, 13392, 13394, 
+        0,  8192, 12288, 13312, 13376, 13392,     0,  8192, 
+    12288, 13312, 13376, 13392, 13396,     0,  8192, 12288, 
+    13312, 13376, 13392, 13396,     0,  8192, 12288, 13312, 
+    13376, 13392, 13400, 13398,     0,  8192, 12288, 13312, 
+    13376, 13392,     0,  8192, 12288, 13312, 13376, 13408, 
+    13400,     0,  8192, 12288, 13312, 13376, 13408, 13400, 
+        0,  8192, 12288, 13312, 13376, 13408, 13400, 13402, 
+        0,  8192, 12288, 13312, 13376, 13408, 13400,     0, 
+     8192, 12288, 13312, 13376, 13408, 13409, 13404,     0, 
+     8192, 12288, 13312, 13376, 13408, 13409, 13404,     0, 
+     8192, 12288, 13312, 13376, 13408, 13409, 13404, 13406, 
+        0,  8192, 12288, 13312, 13376,     0,  8192, 12288, 
+    13312, 13440, 13408,     0,  8192, 12288, 13312, 13440, 
+    13408,     0,  8192, 12288, 13312, 13440, 13408, 13410, 
+        0,  8192, 12288, 13312, 13440, 13408,     0,  8192, 
+    12288, 13312, 13440, 13408, 13412,     0,  8192, 12288, 
+    13312, 13440, 13408, 13412,     0,  8192, 12288, 13312, 
+    13440, 13408, 13416, 13414,     0,  8192, 12288, 13312, 
+    13440, 13408,     0,  8192, 12288, 13312, 13440, 13408, 
+    13416,     0,  8192, 12288, 13312, 13440, 13408, 13416, 
+        0,  8192, 12288, 13312, 13440, 13408, 13416, 13418, 
+        0,  8192, 12288, 13312, 13440, 13408, 13416,     0, 
+     8192, 12288, 13312, 13440, 13408, 13424, 13420,     0, 
+     8192, 12288, 13312, 13440, 13408, 13424, 13420,     0, 
+     8192, 12288, 13312, 13440, 13408, 13424, 13425, 13422, 
+        0,  8192, 12288, 13312, 13440, 13408,     0,  8192, 
+    12288, 13312, 13440, 13441, 13424,     0,  8192, 12288, 
+    13312, 13440, 13441, 13424,     0,  8192, 12288, 13312, 
+    13440, 13441, 13424, 13426,     0,  8192, 12288, 13312, 
+    13440, 13441, 13424,     0,  8192, 12288, 13312, 13440, 
+    13441, 13424, 13428,     0,  8192, 12288, 13312, 13440, 
+    13441, 13424, 13428,     0,  8192, 12288, 13312, 13440, 
+    13441, 13424, 13432, 13430,     0,  8192, 12288, 13312, 
+    13440, 13441, 13424,     0,  8192, 12288, 13312, 13440, 
+    13441, 13424, 13432,     0,  8192, 12288, 13312, 13440, 
+    13441, 13443, 13432,     0,  8192, 12288, 13312, 13440, 
+    13441, 13443, 13432, 13434,     0,  8192, 12288, 13312, 
+    13440, 13441, 13443, 13432,     0,  8192, 12288, 13312, 
+    13440, 13441, 13443, 13432, 13436,     0,  8192, 12288, 
+    13312, 13440, 13441, 13443, 13432, 13436,     0,  8192, 
+    12288, 13312, 13440, 13441, 13443, 13432, 13436, 13438, 
+        0,  8192, 12288, 13312,     0,  8192, 12288, 13312, 
+    13440,     0,  8192, 12288, 13312, 13440,     0,  8192, 
+    12288, 13312, 13440, 13442,     0,  8192, 12288, 13312, 
+    13440,     0,  8192, 12288, 13312, 13440, 13444,     0, 
+     8192, 12288, 13312, 13440, 13444,     0,  8192, 12288, 
+    13312, 13440, 13448, 13446,     0,  8192, 12288, 13312, 
+    13440,     0,  8192, 12288, 13312, 13440, 13448,     0, 
+     8192, 12288, 13312, 13440, 13448,     0,  8192, 12288, 
+    13312, 13440, 13448, 13450,     0,  8192, 12288, 13312, 
+    13440, 13448,     0,  8192, 12288, 13312, 13440, 13456, 
+    13452,     0,  8192, 12288, 13312, 13440, 13456, 13452, 
+        0,  8192, 12288, 13312, 13440, 13456, 13457, 13454, 
+        0,  8192, 12288, 13312, 13440,     0,  8192, 12288, 
+    13312, 13440, 13456,     0,  8192, 12288, 13312, 13440, 
+    13456,     0,  8192, 12288, 13312, 13440, 13456, 13458, 
+        0,  8192, 12288, 13312, 13440, 13456,     0,  8192, 
+    12288, 13312, 13440, 13456, 13460,     0,  8192, 12288, 
+    13312, 13440, 13456, 13460,     0,  8192, 12288, 13312, 
+    13440, 13456, 13464, 13462,     0,  8192, 12288, 13312, 
+    13440, 13456,     0,  8192, 12288, 13312, 13440, 13472, 
+    13464,     0,  8192, 12288, 13312, 13440, 13472, 13464, 
+        0,  8192, 12288, 13312, 13440, 13472, 13464, 13466, 
+        0,  8192, 12288, 13312, 13440, 13472, 13464,     0, 
+     8192, 12288, 13312, 13440, 13472, 13473, 13468,     0, 
+     8192, 12288, 13312, 13440, 13472, 13473, 13468,     0, 
+     8192, 12288, 13312, 13440, 13472, 13473, 13468, 13470, 
+        0,  8192, 12288, 13312, 13440,     0,  8192, 12288, 
+    13312, 13440, 13472,     0,  8192, 12288, 13312, 13440, 
+    13472,     0,  8192, 12288, 13312, 13440, 13472, 13474, 
+        0,  8192, 12288, 13312, 13440, 13472,     0,  8192, 
+    12288, 13312, 13440, 13472, 13476,     0,  8192, 12288, 
+    13312, 13440, 13472, 13476,     0,  8192, 12288, 13312, 
+    13440, 13472, 13480, 13478,     0,  8192, 12288, 13312, 
+    13440, 13472,     0,  8192, 12288, 13312, 13440, 13472, 
+    13480,     0,  8192, 12288, 13312, 13440, 13472, 13480, 
+        0,  8192, 12288, 13312, 13440, 13472, 13480, 13482, 
+        0,  8192, 12288, 13312, 13440, 13472, 13480,     0, 
+     8192, 12288, 13312, 13440, 13472, 13488, 13484,     0, 
+     8192, 12288, 13312, 13440, 13472, 13488, 13484,     0, 
+     8192, 12288, 13312, 13440, 13472, 13488, 13489, 13486, 
+        0,  8192, 12288, 13312, 13440, 13472,     0,  8192, 
+    12288, 13312, 13440, 13504, 13488,     0,  8192, 12288, 
+    13312, 13440, 13504, 13488,     0,  8192, 12288, 13312, 
+    13440, 13504, 13488, 13490,     0,  8192, 12288, 13312, 
+    13440, 13504, 13488,     0,  8192, 12288, 13312, 13440, 
+    13504, 13488, 13492,     0,  8192, 12288, 13312, 13440, 
+    13504, 13488, 13492,     0,  8192, 12288, 13312, 13440, 
+    13504, 13488, 13496, 13494,     0,  8192, 12288, 13312, 
+    13440, 13504, 13488,     0,  8192, 12288, 13312, 13440, 
+    13504, 13505, 13496,     0,  8192, 12288, 13312, 13440, 
+    13504, 13505, 13496,     0,  8192, 12288, 13312, 13440, 
+    13504, 13505, 13496, 13498,     0,  8192, 12288, 13312, 
+    13440, 13504, 13505, 13496,     0,  8192, 12288, 13312, 
+    13440, 13504, 13505, 13496, 13500,     0,  8192, 12288, 
+    13312, 13440, 13504, 13505, 13507, 13500,     0,  8192, 
+    12288, 13312, 13440, 13504, 13505, 13507, 13500, 13502, 
+        0,  8192, 12288, 13312, 13440,     0,  8192, 12288, 
+    13312, 13568, 13504,     0,  8192, 12288, 13312, 13568, 
+    13504,     0,  8192, 12288, 13312, 13568, 13504, 13506, 
+        0,  8192, 12288, 13312, 13568, 13504,     0,  8192, 
+    12288, 13312, 13568, 13504, 13508,     0,  8192, 12288, 
+    13312, 13568, 13504, 13508,     0,  8192, 12288, 13312, 
+    13568, 13504, 13512, 13510,     0,  8192, 12288, 13312, 
+    13568, 13504,     0,  8192, 12288, 13312, 13568, 13504, 
+    13512,     0,  8192, 12288, 13312, 13568, 13504, 13512, 
+        0,  8192, 12288, 13312, 13568, 13504, 13512, 13514, 
+        0,  8192, 12288, 13312, 13568, 13504, 13512,     0, 
+     8192, 12288, 13312, 13568, 13504, 13520, 13516,     0, 
+     8192, 12288, 13312, 13568, 13504, 13520, 13516,     0, 
+     8192, 12288, 13312, 13568, 13504, 13520, 13521, 13518, 
+        0,  8192, 12288, 13312, 13568, 13504,     0,  8192, 
+    12288, 13312, 13568, 13504, 13520,     0,  8192, 12288, 
+    13312, 13568, 13504, 13520,     0,  8192, 12288, 13312, 
+    13568, 13504, 13520, 13522,     0,  8192, 12288, 13312, 
+    13568, 13504, 13520,     0,  8192, 12288, 13312, 13568, 
+    13504, 13520, 13524,     0,  8192, 12288, 13312, 13568, 
+    13504, 13520, 13524,     0,  8192, 12288, 13312, 13568, 
+    13504, 13520, 13528, 13526,     0,  8192, 12288, 13312, 
+    13568, 13504, 13520,     0,  8192, 12288, 13312, 13568, 
+    13504, 13536, 13528,     0,  8192, 12288, 13312, 13568, 
+    13504, 13536, 13528,     0,  8192, 12288, 13312, 13568, 
+    13504, 13536, 13528, 13530,     0,  8192, 12288, 13312, 
+    13568, 13504, 13536, 13528,     0,  8192, 12288, 13312, 
+    13568, 13504, 13536, 13537, 13532,     0,  8192, 12288, 
+    13312, 13568, 13504, 13536, 13537, 13532,     0,  8192, 
+    12288, 13312, 13568, 13504, 13536, 13537, 13532, 13534, 
+        0,  8192, 12288, 13312, 13568, 13504,     0,  8192, 
+    12288, 13312, 13568, 13569, 13536,     0,  8192, 12288, 
+    13312, 13568, 13569, 13536,     0,  8192, 12288, 13312, 
+    13568, 13569, 13536, 13538,     0,  8192, 12288, 13312, 
+    13568, 13569, 13536,     0,  8192, 12288, 13312, 13568, 
+    13569, 13536, 13540,     0,  8192, 12288, 13312, 13568, 
+    13569, 13536, 13540,     0,  8192, 12288, 13312, 13568, 
+    13569, 13536, 13544, 13542,     0,  8192, 12288, 13312, 
+    13568, 13569, 13536,     0,  8192, 12288, 13312, 13568, 
+    13569, 13536, 13544,     0,  8192, 12288, 13312, 13568, 
+    13569, 13536, 13544,     0,  8192, 12288, 13312, 13568, 
+    13569, 13536, 13544, 13546,     0,  8192, 12288, 13312, 
+    13568, 13569, 13536, 13544,     0,  8192, 12288, 13312, 
+    13568, 13569, 13536, 13552, 13548,     0,  8192, 12288, 
+    13312, 13568, 13569, 13536, 13552, 13548,     0,  8192, 
+    12288, 13312, 13568, 13569, 13536, 13552, 13553, 13550, 
+        0,  8192, 12288, 13312, 13568, 13569, 13536,     0, 
+     8192, 12288, 13312, 13568, 13569, 13536, 13552,     0, 
+     8192, 12288, 13312, 13568, 13569, 13571, 13552,     0, 
+     8192, 12288, 13312, 13568, 13569, 13571, 13552, 13554, 
+        0,  8192, 12288, 13312, 13568, 13569, 13571, 13552, 
+        0,  8192, 12288, 13312, 13568, 13569, 13571, 13552, 
+    13556,     0,  8192, 12288, 13312, 13568, 13569, 13571, 
+    13552, 13556,     0,  8192, 12288, 13312, 13568, 13569, 
+    13571, 13552, 13560, 13558,     0,  8192, 12288, 13312, 
+    13568, 13569, 13571, 13552,     0,  8192, 12288, 13312, 
+    13568, 13569, 13571, 13552, 13560,     0,  8192, 12288, 
+    13312, 13568, 13569, 13571, 13552, 13560,     0,  8192, 
+    12288, 13312, 13568, 13569, 13571, 13552, 13560, 13562, 
+        0,  8192, 12288, 13312, 13568, 13569, 13571, 13575, 
+    13560,     0,  8192, 12288, 13312, 13568, 13569, 13571, 
+    13575, 13560, 13564,     0,  8192, 12288, 13312, 13568, 
+    13569, 13571, 13575, 13560, 13564,     0,  8192, 12288, 
+    13312, 13568, 13569, 13571, 13575, 13560, 13564, 13566, 
+        0,  8192, 12288, 13312,     0,  8192, 12288, 13312, 
+    13568,     0,  8192, 12288, 13312, 13568,     0,  8192, 
+    12288, 13312, 13568, 13570,     0,  8192, 12288, 13312, 
+    13568,     0,  8192, 12288, 13312, 13568, 13572,     0, 
+     8192, 12288, 13312, 13568, 13572,     0,  8192, 12288, 
+    13312, 13568, 13576, 13574,     0,  8192, 12288, 13312, 
+    13568,     0,  8192, 12288, 13312, 13568, 13576,     0, 
+     8192, 12288, 13312, 13568, 13576,     0,  8192, 12288, 
+    13312, 13568, 13576, 13578,     0,  8192, 12288, 13312, 
+    13568, 13576,     0,  8192, 12288, 13312, 13568, 13584, 
+    13580,     0,  8192, 12288, 13312, 13568, 13584, 13580, 
+        0,  8192, 12288, 13312, 13568, 13584, 13585, 13582, 
+        0,  8192, 12288, 13312, 13568,     0,  8192, 12288, 
+    13312, 13568, 13584,     0,  8192, 12288, 13312, 13568, 
+    13584,     0,  8192, 12288, 13312, 13568, 13584, 13586, 
+        0,  8192, 12288, 13312, 13568, 13584,     0,  8192, 
+    12288, 13312, 13568, 13584, 13588,     0,  8192, 12288, 
+    13312, 13568, 13584, 13588,     0,  8192, 12288, 13312, 
+    13568, 13584, 13592, 13590,     0,  8192, 12288, 13312, 
+    13568, 13584,     0,  8192, 12288, 13312, 13568, 13600, 
+    13592,     0,  8192, 12288, 13312, 13568, 13600, 13592, 
+        0,  8192, 12288, 13312, 13568, 13600, 13592, 13594, 
+        0,  8192, 12288, 13312, 13568, 13600, 13592,     0, 
+     8192, 12288, 13312, 13568, 13600, 13601, 13596,     0, 
+     8192, 12288, 13312, 13568, 13600, 13601, 13596,     0, 
+     8192, 12288, 13312, 13568, 13600, 13601, 13596, 13598, 
+        0,  8192, 12288, 13312, 13568,     0,  8192, 12288, 
+    13312, 13568, 13600,     0,  8192, 12288, 13312, 13568, 
+    13600,     0,  8192, 12288, 13312, 13568, 13600, 13602, 
+        0,  8192, 12288, 13312, 13568, 13600,     0,  8192, 
+    12288, 13312, 13568, 13600, 13604,     0,  8192, 12288, 
+    13312, 13568, 13600, 13604,     0,  8192, 12288, 13312, 
+    13568, 13600, 13608, 13606,     0,  8192, 12288, 13312, 
+    13568, 13600,     0,  8192, 12288, 13312, 13568, 13600, 
+    13608,     0,  8192, 12288, 13312, 13568, 13600, 13608, 
+        0,  8192, 12288, 13312, 13568, 13600, 13608, 13610, 
+        0,  8192, 12288, 13312, 13568, 13600, 13608,     0, 
+     8192, 12288, 13312, 13568, 13600, 13616, 13612,     0, 
+     8192, 12288, 13312, 13568, 13600, 13616, 13612,     0, 
+     8192, 12288, 13312, 13568, 13600, 13616, 13617, 13614, 
+        0,  8192, 12288, 13312, 13568, 13600,     0,  8192, 
+    12288, 13312, 13568, 13632, 13616,     0,  8192, 12288, 
+    13312, 13568, 13632, 13616,     0,  8192, 12288, 13312, 
+    13568, 13632, 13616, 13618,     0,  8192, 12288, 13312, 
+    13568, 13632, 13616,     0,  8192, 12288, 13312, 13568, 
+    13632, 13616, 13620,     0,  8192, 12288, 13312, 13568, 
+    13632, 13616, 13620,     0,  8192, 12288, 13312, 13568, 
+    13632, 13616, 13624, 13622,     0,  8192, 12288, 13312, 
+    13568, 13632, 13616,     0,  8192, 12288, 13312, 13568, 
+    13632, 13633, 13624,     0,  8192, 12288, 13312, 13568, 
+    13632, 13633, 13624,     0,  8192, 12288, 13312, 13568, 
+    13632, 13633, 13624, 13626,     0,  8192, 12288, 13312, 
+    13568, 13632, 13633, 13624,     0,  8192, 12288, 13312, 
+    13568, 13632, 13633, 13624, 13628,     0,  8192, 12288, 
+    13312, 13568, 13632, 13633, 13635, 13628,     0,  8192, 
+    12288, 13312, 13568, 13632, 13633, 13635, 13628, 13630, 
+        0,  8192, 12288, 13312, 13568,     0,  8192, 12288, 
+    13312, 13568, 13632,     0,  8192, 12288, 13312, 13568, 
+    13632,     0,  8192, 12288, 13312, 13568, 13632, 13634, 
+        0,  8192, 12288, 13312, 13568, 13632,     0,  8192, 
+    12288, 13312, 13568, 13632, 13636,     0,  8192, 12288, 
+    13312, 13568, 13632, 13636,     0,  8192, 12288, 13312, 
+    13568, 13632, 13640, 13638,     0,  8192, 12288, 13312, 
+    13568, 13632,     0,  8192, 12288, 13312, 13568, 13632, 
+    13640,     0,  8192, 12288, 13312, 13568, 13632, 13640, 
+        0,  8192, 12288, 13312, 13568, 13632, 13640, 13642, 
+        0,  8192, 12288, 13312, 13568, 13632, 13640,     0, 
+     8192, 12288, 13312, 13568, 13632, 13648, 13644,     0, 
+     8192, 12288, 13312, 13568, 13632, 13648, 13644,     0, 
+     8192, 12288, 13312, 13568, 13632, 13648, 13649, 13646, 
+        0,  8192, 12288, 13312, 13568, 13632,     0,  8192, 
+    12288, 13312, 13568, 13632, 13648,     0,  8192, 12288, 
+    13312, 13568, 13632, 13648,     0,  8192, 12288, 13312, 
+    13568, 13632, 13648, 13650,     0,  8192, 12288, 13312, 
+    13568, 13632, 13648,     0,  8192, 12288, 13312, 13568, 
+    13632, 13648, 13652,     0,  8192, 12288, 13312, 13568, 
+    13632, 13648, 13652,     0,  8192, 12288, 13312, 13568, 
+    13632, 13648, 13656, 13654,     0,  8192, 12288, 13312, 
+    13568, 13632, 13648,     0,  8192, 12288, 13312, 13568, 
+    13632, 13664, 13656,     0,  8192, 12288, 13312, 13568, 
+    13632, 13664, 13656,     0,  8192, 12288, 13312, 13568, 
+    13632, 13664, 13656, 13658,     0,  8192, 12288, 13312, 
+    13568, 13632, 13664, 13656,     0,  8192, 12288, 13312, 
+    13568, 13632, 13664, 13665, 13660,     0,  8192, 12288, 
+    13312, 13568, 13632, 13664, 13665, 13660,     0,  8192, 
+    12288, 13312, 13568, 13632, 13664, 13665, 13660, 13662, 
+        0,  8192, 12288, 13312, 13568, 13632,     0,  8192, 
+    12288, 13312, 13568, 13696, 13664,     0,  8192, 12288, 
+    13312, 13568, 13696, 13664,     0,  8192, 12288, 13312, 
+    13568, 13696, 13664, 13666,     0,  8192, 12288, 13312, 
+    13568, 13696, 13664,     0,  8192, 12288, 13312, 13568, 
+    13696, 13664, 13668,     0,  8192, 12288, 13312, 13568, 
+    13696, 13664, 13668,     0,  8192, 12288, 13312, 13568, 
+    13696, 13664, 13672, 13670,     0,  8192, 12288, 13312, 
+    13568, 13696, 13664,     0,  8192, 12288, 13312, 13568, 
+    13696, 13664, 13672,     0,  8192, 12288, 13312, 13568, 
+    13696, 13664, 13672,     0,  8192, 12288, 13312, 13568, 
+    13696, 13664, 13672, 13674,     0,  8192, 12288, 13312, 
+    13568, 13696, 13664, 13672,     0,  8192, 12288, 13312, 
+    13568, 13696, 13664, 13680, 13676,     0,  8192, 12288, 
+    13312, 13568, 13696, 13664, 13680, 13676,     0,  8192, 
+    12288, 13312, 13568, 13696, 13664, 13680, 13681, 13678, 
+        0,  8192, 12288, 13312, 13568, 13696, 13664,     0, 
+     8192, 12288, 13312, 13568, 13696, 13697, 13680,     0, 
+     8192, 12288, 13312, 13568, 13696, 13697, 13680,     0, 
+     8192, 12288, 13312, 13568, 13696, 13697, 13680, 13682, 
+        0,  8192, 12288, 13312, 13568, 13696, 13697, 13680, 
+        0,  8192, 12288, 13312, 13568, 13696, 13697, 13680, 
+    13684,     0,  8192, 12288, 13312, 13568, 13696, 13697, 
+    13680, 13684,     0,  8192, 12288, 13312, 13568, 13696, 
+    13697, 13680, 13688, 13686,     0,  8192, 12288, 13312, 
+    13568, 13696, 13697, 13680,     0,  8192, 12288, 13312, 
+    13568, 13696, 13697, 13680, 13688,     0,  8192, 12288, 
+    13312, 13568, 13696, 13697, 13699, 13688,     0,  8192, 
+    12288, 13312, 13568, 13696, 13697, 13699, 13688, 13690, 
+        0,  8192, 12288, 13312, 13568, 13696, 13697, 13699, 
+    13688,     0,  8192, 12288, 13312, 13568, 13696, 13697, 
+    13699, 13688, 13692,     0,  8192, 12288, 13312, 13568, 
+    13696, 13697, 13699, 13688, 13692,     0,  8192, 12288, 
+    13312, 13568, 13696, 13697, 13699, 13688, 13692, 13694, 
+        0,  8192, 12288, 13312, 13568,     0,  8192, 12288, 
+    13312, 13824, 13696,     0,  8192, 12288, 13312, 13824, 
+    13696,     0,  8192, 12288, 13312, 13824, 13696, 13698, 
+        0,  8192, 12288, 13312, 13824, 13696,     0,  8192, 
+    12288, 13312, 13824, 13696, 13700,     0,  8192, 12288, 
+    13312, 13824, 13696, 13700,     0,  8192, 12288, 13312, 
+    13824, 13696, 13704, 13702,     0,  8192, 12288, 13312, 
+    13824, 13696,     0,  8192, 12288, 13312, 13824, 13696, 
+    13704,     0,  8192, 12288, 13312, 13824, 13696, 13704, 
+        0,  8192, 12288, 13312, 13824, 13696, 13704, 13706, 
+        0,  8192, 12288, 13312, 13824, 13696, 13704,     0, 
+     8192, 12288, 13312, 13824, 13696, 13712, 13708,     0, 
+     8192, 12288, 13312, 13824, 13696, 13712, 13708,     0, 
+     8192, 12288, 13312, 13824, 13696, 13712, 13713, 13710, 
+        0,  8192, 12288, 13312, 13824, 13696,     0,  8192, 
+    12288, 13312, 13824, 13696, 13712,     0,  8192, 12288, 
+    13312, 13824, 13696, 13712,     0,  8192, 12288, 13312, 
+    13824, 13696, 13712, 13714,     0,  8192, 12288, 13312, 
+    13824, 13696, 13712,     0,  8192, 12288, 13312, 13824, 
+    13696, 13712, 13716,     0,  8192, 12288, 13312, 13824, 
+    13696, 13712, 13716,     0,  8192, 12288, 13312, 13824, 
+    13696, 13712, 13720, 13718,     0,  8192, 12288, 13312, 
+    13824, 13696, 13712,     0,  8192, 12288, 13312, 13824, 
+    13696, 13728, 13720,     0,  8192, 12288, 13312, 13824, 
+    13696, 13728, 13720,     0,  8192, 12288, 13312, 13824, 
+    13696, 13728, 13720, 13722,     0,  8192, 12288, 13312, 
+    13824, 13696, 13728, 13720,     0,  8192, 12288, 13312, 
+    13824, 13696, 13728, 13729, 13724,     0,  8192, 12288, 
+    13312, 13824, 13696, 13728, 13729, 13724,     0,  8192, 
+    12288, 13312, 13824, 13696, 13728, 13729, 13724, 13726, 
+        0,  8192, 12288, 13312, 13824, 13696,     0,  8192, 
+    12288, 13312, 13824, 13696, 13728,     0,  8192, 12288, 
+    13312, 13824, 13696, 13728,     0,  8192, 12288, 13312, 
+    13824, 13696, 13728, 13730,     0,  8192, 12288, 13312, 
+    13824, 13696, 13728,     0,  8192, 12288, 13312, 13824, 
+    13696, 13728, 13732,     0,  8192, 12288, 13312, 13824, 
+    13696, 13728, 13732,     0,  8192, 12288, 13312, 13824, 
+    13696, 13728, 13736, 13734,     0,  8192, 12288, 13312, 
+    13824, 13696, 13728,     0,  8192, 12288, 13312, 13824, 
+    13696, 13728, 13736,     0,  8192, 12288, 13312, 13824, 
+    13696, 13728, 13736,     0,  8192, 12288, 13312, 13824, 
+    13696, 13728, 13736, 13738,     0,  8192, 12288, 13312, 
+    13824, 13696, 13728, 13736,     0,  8192, 12288, 13312, 
+    13824, 13696, 13728, 13744, 13740,     0,  8192, 12288, 
+    13312, 13824, 13696, 13728, 13744, 13740,     0,  8192, 
+    12288, 13312, 13824, 13696, 13728, 13744, 13745, 13742, 
+        0,  8192, 12288, 13312, 13824, 13696, 13728,     0, 
+     8192, 12288, 13312, 13824, 13696, 13760, 13744,     0, 
+     8192, 12288, 13312, 13824, 13696, 13760, 13744,     0, 
+     8192, 12288, 13312, 13824, 13696, 13760, 13744, 13746, 
+        0,  8192, 12288, 13312, 13824, 13696, 13760, 13744, 
+        0,  8192, 12288, 13312, 13824, 13696, 13760, 13744, 
+    13748,     0,  8192, 12288, 13312, 13824, 13696, 13760, 
+    13744, 13748,     0,  8192, 12288, 13312, 13824, 13696, 
+    13760, 13744, 13752, 13750,     0,  8192, 12288, 13312, 
+    13824, 13696, 13760, 13744,     0,  8192, 12288, 13312, 
+    13824, 13696, 13760, 13761, 13752,     0,  8192, 12288, 
+    13312, 13824, 13696, 13760, 13761, 13752,     0,  8192, 
+    12288, 13312, 13824, 13696, 13760, 13761, 13752, 13754, 
+        0,  8192, 12288, 13312, 13824, 13696, 13760, 13761, 
+    13752,     0,  8192, 12288, 13312, 13824, 13696, 13760, 
+    13761, 13752, 13756,     0,  8192, 12288, 13312, 13824, 
+    13696, 13760, 13761, 13763, 13756,     0,  8192, 12288, 
+    13312, 13824, 13696, 13760, 13761, 13763, 13756, 13758, 
+        0,  8192, 12288, 13312, 13824, 13696,     0,  8192, 
+    12288, 13312, 13824, 13825, 13760,     0,  8192, 12288, 
+    13312, 13824, 13825, 13760,     0,  8192, 12288, 13312, 
+    13824, 13825, 13760, 13762,     0,  8192, 12288, 13312, 
+    13824, 13825, 13760,     0,  8192, 12288, 13312, 13824, 
+    13825, 13760, 13764,     0,  8192, 12288, 13312, 13824, 
+    13825, 13760, 13764,     0,  8192, 12288, 13312, 13824, 
+    13825, 13760, 13768, 13766,     0,  8192, 12288, 13312, 
+    13824, 13825, 13760,     0,  8192, 12288, 13312, 13824, 
+    13825, 13760, 13768,     0,  8192, 12288, 13312, 13824, 
+    13825, 13760, 13768,     0,  8192, 12288, 13312, 13824, 
+    13825, 13760, 13768, 13770,     0,  8192, 12288, 13312, 
+    13824, 13825, 13760, 13768,     0,  8192, 12288, 13312, 
+    13824, 13825, 13760, 13776, 13772,     0,  8192, 12288, 
+    13312, 13824, 13825, 13760, 13776, 13772,     0,  8192, 
+    12288, 13312, 13824, 13825, 13760, 13776, 13777, 13774, 
+        0,  8192, 12288, 13312, 13824, 13825, 13760,     0, 
+     8192, 12288, 13312, 13824, 13825, 13760, 13776,     0, 
+     8192, 12288, 13312, 13824, 13825, 13760, 13776,     0, 
+     8192, 12288, 13312, 13824, 13825, 13760, 13776, 13778, 
+        0,  8192, 12288, 13312, 13824, 13825, 13760, 13776, 
+        0,  8192, 12288, 13312, 13824, 13825, 13760, 13776, 
+    13780,     0,  8192, 12288, 13312, 13824, 13825, 13760, 
+    13776, 13780,     0,  8192, 12288, 13312, 13824, 13825, 
+    13760, 13776, 13784, 13782,     0,  8192, 12288, 13312, 
+    13824, 13825, 13760, 13776,     0,  8192, 12288, 13312, 
+    13824, 13825, 13760, 13792, 13784,     0,  8192, 12288, 
+    13312, 13824, 13825, 13760, 13792, 13784,     0,  8192, 
+    12288, 13312, 13824, 13825, 13760, 13792, 13784, 13786, 
+        0,  8192, 12288, 13312, 13824, 13825, 13760, 13792, 
+    13784,     0,  8192, 12288, 13312, 13824, 13825, 13760, 
+    13792, 13793, 13788,     0,  8192, 12288, 13312, 13824, 
+    13825, 13760, 13792, 13793, 13788,     0,  8192, 12288, 
+    13312, 13824, 13825, 13760, 13792, 13793, 13788, 13790, 
+        0,  8192, 12288, 13312, 13824, 13825, 13760,     0, 
+     8192, 12288, 13312, 13824, 13825, 13760, 13792,     0, 
+     8192, 12288, 13312, 13824, 13825, 13827, 13792,     0, 
+     8192, 12288, 13312, 13824, 13825, 13827, 13792, 13794, 
+        0,  8192, 12288, 13312, 13824, 13825, 13827, 13792, 
+        0,  8192, 12288, 13312, 13824, 13825, 13827, 13792, 
+    13796,     0,  8192, 12288, 13312, 13824, 13825, 13827, 
+    13792, 13796,     0,  8192, 12288, 13312, 13824, 13825, 
+    13827, 13792, 13800, 13798,     0,  8192, 12288, 13312, 
+    13824, 13825, 13827, 13792,     0,  8192, 12288, 13312, 
+    13824, 13825, 13827, 13792, 13800,     0,  8192, 12288, 
+    13312, 13824, 13825, 13827, 13792, 13800,     0,  8192, 
+    12288, 13312, 13824, 13825, 13827, 13792, 13800, 13802, 
+        0,  8192, 12288, 13312, 13824, 13825, 13827, 13792, 
+    13800,     0,  8192, 12288, 13312, 13824, 13825, 13827, 
+    13792, 13808, 13804,     0,  8192, 12288, 13312, 13824, 
+    13825, 13827, 13792, 13808, 13804,     0,  8192, 12288, 
+    13312, 13824, 13825, 13827, 13792, 13808, 13809, 13806, 
+        0,  8192, 12288, 13312, 13824, 13825, 13827, 13792, 
+        0,  8192, 12288, 13312, 13824, 13825, 13827, 13792, 
+    13808,     0,  8192, 12288, 13312, 13824, 13825, 13827, 
+    13792, 13808,     0,  8192, 12288, 13312, 13824, 13825, 
+    13827, 13792, 13808, 13810,     0,  8192, 12288, 13312, 
+    13824, 13825, 13827, 13831, 13808,     0,  8192, 12288, 
+    13312, 13824, 13825, 13827, 13831, 13808, 13812,     0, 
+     8192, 12288, 13312, 13824, 13825, 13827, 13831, 13808, 
+    13812,     0,  8192, 12288, 13312, 13824, 13825, 13827, 
+    13831, 13808, 13816, 13814,     0,  8192, 12288, 13312, 
+    13824, 13825, 13827, 13831, 13808,     0,  8192, 12288, 
+    13312, 13824, 13825, 13827, 13831, 13808, 13816,     0, 
+     8192, 12288, 13312, 13824, 13825, 13827, 13831, 13808, 
+    13816,     0,  8192, 12288, 13312, 13824, 13825, 13827, 
+    13831, 13808, 13816, 13818,     0,  8192, 12288, 13312, 
+    13824, 13825, 13827, 13831, 13808, 13816,     0,  8192, 
+    12288, 13312, 13824, 13825, 13827, 13831, 13808, 13816, 
+    13820,     0,  8192, 12288, 13312, 13824, 13825, 13827, 
+    13831, 13808, 13816, 13820,     0,  8192, 12288, 13312, 
+    13824, 13825, 13827, 13831, 13808, 13816, 13820, 13822, 
+        0,  8192, 12288, 13312,     0,  8192, 12288, 14336, 
+    13824,     0,  8192, 12288, 14336, 13824,     0,  8192, 
+    12288, 14336, 13824, 13826,     0,  8192, 12288, 14336, 
+    13824,     0,  8192, 12288, 14336, 13824, 13828,     0, 
+     8192, 12288, 14336, 13824, 13828,     0,  8192, 12288, 
+    14336, 13824, 13832, 13830,     0,  8192, 12288, 14336, 
+    13824,     0,  8192, 12288, 14336, 13824, 13832,     0, 
+     8192, 12288, 14336, 13824, 13832,     0,  8192, 12288, 
+    14336, 13824, 13832, 13834,     0,  8192, 12288, 14336, 
+    13824, 13832,     0,  8192, 12288, 14336, 13824, 13840, 
+    13836,     0,  8192, 12288, 14336, 13824, 13840, 13836, 
+        0,  8192, 12288, 14336, 13824, 13840, 13841, 13838, 
+        0,  8192, 12288, 14336, 13824,     0,  8192, 12288, 
+    14336, 13824, 13840,     0,  8192, 12288, 14336, 13824, 
+    13840,     0,  8192, 12288, 14336, 13824, 13840, 13842, 
+        0,  8192, 12288, 14336, 13824, 13840,     0,  8192, 
+    12288, 14336, 13824, 13840, 13844,     0,  8192, 12288, 
+    14336, 13824, 13840, 13844,     0,  8192, 12288, 14336, 
+    13824, 13840, 13848, 13846,     0,  8192, 12288, 14336, 
+    13824, 13840,     0,  8192, 12288, 14336, 13824, 13856, 
+    13848,     0,  8192, 12288, 14336, 13824, 13856, 13848, 
+        0,  8192, 12288, 14336, 13824, 13856, 13848, 13850, 
+        0,  8192, 12288, 14336, 13824, 13856, 13848,     0, 
+     8192, 12288, 14336, 13824, 13856, 13857, 13852,     0, 
+     8192, 12288, 14336, 13824, 13856, 13857, 13852,     0, 
+     8192, 12288, 14336, 13824, 13856, 13857, 13852, 13854, 
+        0,  8192, 12288, 14336, 13824,     0,  8192, 12288, 
+    14336, 13824, 13856,     0,  8192, 12288, 14336, 13824, 
+    13856,     0,  8192, 12288, 14336, 13824, 13856, 13858, 
+        0,  8192, 12288, 14336, 13824, 13856,     0,  8192, 
+    12288, 14336, 13824, 13856, 13860,     0,  8192, 12288, 
+    14336, 13824, 13856, 13860,     0,  8192, 12288, 14336, 
+    13824, 13856, 13864, 13862,     0,  8192, 12288, 14336, 
+    13824, 13856,     0,  8192, 12288, 14336, 13824, 13856, 
+    13864,     0,  8192, 12288, 14336, 13824, 13856, 13864, 
+        0,  8192, 12288, 14336, 13824, 13856, 13864, 13866, 
+        0,  8192, 12288, 14336, 13824, 13856, 13864,     0, 
+     8192, 12288, 14336, 13824, 13856, 13872, 13868,     0, 
+     8192, 12288, 14336, 13824, 13856, 13872, 13868,     0, 
+     8192, 12288, 14336, 13824, 13856, 13872, 13873, 13870, 
+        0,  8192, 12288, 14336, 13824, 13856,     0,  8192, 
+    12288, 14336, 13824, 13888, 13872,     0,  8192, 12288, 
+    14336, 13824, 13888, 13872,     0,  8192, 12288, 14336, 
+    13824, 13888, 13872, 13874,     0,  8192, 12288, 14336, 
+    13824, 13888, 13872,     0,  8192, 12288, 14336, 13824, 
+    13888, 13872, 13876,     0,  8192, 12288, 14336, 13824, 
+    13888, 13872, 13876,     0,  8192, 12288, 14336, 13824, 
+    13888, 13872, 13880, 13878,     0,  8192, 12288, 14336, 
+    13824, 13888, 13872,     0,  8192, 12288, 14336, 13824, 
+    13888, 13889, 13880,     0,  8192, 12288, 14336, 13824, 
+    13888, 13889, 13880,     0,  8192, 12288, 14336, 13824, 
+    13888, 13889, 13880, 13882,     0,  8192, 12288, 14336, 
+    13824, 13888, 13889, 13880,     0,  8192, 12288, 14336, 
+    13824, 13888, 13889, 13880, 13884,     0,  8192, 12288, 
+    14336, 13824, 13888, 13889, 13891, 13884,     0,  8192, 
+    12288, 14336, 13824, 13888, 13889, 13891, 13884, 13886, 
+        0,  8192, 12288, 14336, 13824,     0,  8192, 12288, 
+    14336, 13824, 13888,     0,  8192, 12288, 14336, 13824, 
+    13888,     0,  8192, 12288, 14336, 13824, 13888, 13890, 
+        0,  8192, 12288, 14336, 13824, 13888,     0,  8192, 
+    12288, 14336, 13824, 13888, 13892,     0,  8192, 12288, 
+    14336, 13824, 13888, 13892,     0,  8192, 12288, 14336, 
+    13824, 13888, 13896, 13894,     0,  8192, 12288, 14336, 
+    13824, 13888,     0,  8192, 12288, 14336, 13824, 13888, 
+    13896,     0,  8192, 12288, 14336, 13824, 13888, 13896, 
+        0,  8192, 12288, 14336, 13824, 13888, 13896, 13898, 
+        0,  8192, 12288, 14336, 13824, 13888, 13896,     0, 
+     8192, 12288, 14336, 13824, 13888, 13904, 13900,     0, 
+     8192, 12288, 14336, 13824, 13888, 13904, 13900,     0, 
+     8192, 12288, 14336, 13824, 13888, 13904, 13905, 13902, 
+        0,  8192, 12288, 14336, 13824, 13888,     0,  8192, 
+    12288, 14336, 13824, 13888, 13904,     0,  8192, 12288, 
+    14336, 13824, 13888, 13904,     0,  8192, 12288, 14336, 
+    13824, 13888, 13904, 13906,     0,  8192, 12288, 14336, 
+    13824, 13888, 13904,     0,  8192, 12288, 14336, 13824, 
+    13888, 13904, 13908,     0,  8192, 12288, 14336, 13824, 
+    13888, 13904, 13908,     0,  8192, 12288, 14336, 13824, 
+    13888, 13904, 13912, 13910,     0,  8192, 12288, 14336, 
+    13824, 13888, 13904,     0,  8192, 12288, 14336, 13824, 
+    13888, 13920, 13912,     0,  8192, 12288, 14336, 13824, 
+    13888, 13920, 13912,     0,  8192, 12288, 14336, 13824, 
+    13888, 13920, 13912, 13914,     0,  8192, 12288, 14336, 
+    13824, 13888, 13920, 13912,     0,  8192, 12288, 14336, 
+    13824, 13888, 13920, 13921, 13916,     0,  8192, 12288, 
+    14336, 13824, 13888, 13920, 13921, 13916,     0,  8192, 
+    12288, 14336, 13824, 13888, 13920, 13921, 13916, 13918, 
+        0,  8192, 12288, 14336, 13824, 13888,     0,  8192, 
+    12288, 14336, 13824, 13952, 13920,     0,  8192, 12288, 
+    14336, 13824, 13952, 13920,     0,  8192, 12288, 14336, 
+    13824, 13952, 13920, 13922,     0,  8192, 12288, 14336, 
+    13824, 13952, 13920,     0,  8192, 12288, 14336, 13824, 
+    13952, 13920, 13924,     0,  8192, 12288, 14336, 13824, 
+    13952, 13920, 13924,     0,  8192, 12288, 14336, 13824, 
+    13952, 13920, 13928, 13926,     0,  8192, 12288, 14336, 
+    13824, 13952, 13920,     0,  8192, 12288, 14336, 13824, 
+    13952, 13920, 13928,     0,  8192, 12288, 14336, 13824, 
+    13952, 13920, 13928,     0,  8192, 12288, 14336, 13824, 
+    13952, 13920, 13928, 13930,     0,  8192, 12288, 14336, 
+    13824, 13952, 13920, 13928,     0,  8192, 12288, 14336, 
+    13824, 13952, 13920, 13936, 13932,     0,  8192, 12288, 
+    14336, 13824, 13952, 13920, 13936, 13932,     0,  8192, 
+    12288, 14336, 13824, 13952, 13920, 13936, 13937, 13934, 
+        0,  8192, 12288, 14336, 13824, 13952, 13920,     0, 
+     8192, 12288, 14336, 13824, 13952, 13953, 13936,     0, 
+     8192, 12288, 14336, 13824, 13952, 13953, 13936,     0, 
+     8192, 12288, 14336, 13824, 13952, 13953, 13936, 13938, 
+        0,  8192, 12288, 14336, 13824, 13952, 13953, 13936, 
+        0,  8192, 12288, 14336, 13824, 13952, 13953, 13936, 
+    13940,     0,  8192, 12288, 14336, 13824, 13952, 13953, 
+    13936, 13940,     0,  8192, 12288, 14336, 13824, 13952, 
+    13953, 13936, 13944, 13942,     0,  8192, 12288, 14336, 
+    13824, 13952, 13953, 13936,     0,  8192, 12288, 14336, 
+    13824, 13952, 13953, 13936, 13944,     0,  8192, 12288, 
+    14336, 13824, 13952, 13953, 13955, 13944,     0,  8192, 
+    12288, 14336, 13824, 13952, 13953, 13955, 13944, 13946, 
+        0,  8192, 12288, 14336, 13824, 13952, 13953, 13955, 
+    13944,     0,  8192, 12288, 14336, 13824, 13952, 13953, 
+    13955, 13944, 13948,     0,  8192, 12288, 14336, 13824, 
+    13952, 13953, 13955, 13944, 13948,     0,  8192, 12288, 
+    14336, 13824, 13952, 13953, 13955, 13944, 13948, 13950, 
+        0,  8192, 12288, 14336, 13824,     0,  8192, 12288, 
+    14336, 13824, 13952,     0,  8192, 12288, 14336, 13824, 
+    13952,     0,  8192, 12288, 14336, 13824, 13952, 13954, 
+        0,  8192, 12288, 14336, 13824, 13952,     0,  8192, 
+    12288, 14336, 13824, 13952, 13956,     0,  8192, 12288, 
+    14336, 13824, 13952, 13956,     0,  8192, 12288, 14336, 
+    13824, 13952, 13960, 13958,     0,  8192, 12288, 14336, 
+    13824, 13952,     0,  8192, 12288, 14336, 13824, 13952, 
+    13960,     0,  8192, 12288, 14336, 13824, 13952, 13960, 
+        0,  8192, 12288, 14336, 13824, 13952, 13960, 13962, 
+        0,  8192, 12288, 14336, 13824, 13952, 13960,     0, 
+     8192, 12288, 14336, 13824, 13952, 13968, 13964,     0, 
+     8192, 12288, 14336, 13824, 13952, 13968, 13964,     0, 
+     8192, 12288, 14336, 13824, 13952, 13968, 13969, 13966, 
+        0,  8192, 12288, 14336, 13824, 13952,     0,  8192, 
+    12288, 14336, 13824, 13952, 13968,     0,  8192, 12288, 
+    14336, 13824, 13952, 13968,     0,  8192, 12288, 14336, 
+    13824, 13952, 13968, 13970,     0,  8192, 12288, 14336, 
+    13824, 13952, 13968,     0,  8192, 12288, 14336, 13824, 
+    13952, 13968, 13972,     0,  8192, 12288, 14336, 13824, 
+    13952, 13968, 13972,     0,  8192, 12288, 14336, 13824, 
+    13952, 13968, 13976, 13974,     0,  8192, 12288, 14336, 
+    13824, 13952, 13968,     0,  8192, 12288, 14336, 13824, 
+    13952, 13984, 13976,     0,  8192, 12288, 14336, 13824, 
+    13952, 13984, 13976,     0,  8192, 12288, 14336, 13824, 
+    13952, 13984, 13976, 13978,     0,  8192, 12288, 14336, 
+    13824, 13952, 13984, 13976,     0,  8192, 12288, 14336, 
+    13824, 13952, 13984, 13985, 13980,     0,  8192, 12288, 
+    14336, 13824, 13952, 13984, 13985, 13980,     0,  8192, 
+    12288, 14336, 13824, 13952, 13984, 13985, 13980, 13982, 
+        0,  8192, 12288, 14336, 13824, 13952,     0,  8192, 
+    12288, 14336, 13824, 13952, 13984,     0,  8192, 12288, 
+    14336, 13824, 13952, 13984,     0,  8192, 12288, 14336, 
+    13824, 13952, 13984, 13986,     0,  8192, 12288, 14336, 
+    13824, 13952, 13984,     0,  8192, 12288, 14336, 13824, 
+    13952, 13984, 13988,     0,  8192, 12288, 14336, 13824, 
+    13952, 13984, 13988,     0,  8192, 12288, 14336, 13824, 
+    13952, 13984, 13992, 13990,     0,  8192, 12288, 14336, 
+    13824, 13952, 13984,     0,  8192, 12288, 14336, 13824, 
+    13952, 13984, 13992,     0,  8192, 12288, 14336, 13824, 
+    13952, 13984, 13992,     0,  8192, 12288, 14336, 13824, 
+    13952, 13984, 13992, 13994,     0,  8192, 12288, 14336, 
+    13824, 13952, 13984, 13992,     0,  8192, 12288, 14336, 
+    13824, 13952, 13984, 14000, 13996,     0,  8192, 12288, 
+    14336, 13824, 13952, 13984, 14000, 13996,     0,  8192, 
+    12288, 14336, 13824, 13952, 13984, 14000, 14001, 13998, 
+        0,  8192, 12288, 14336, 13824, 13952, 13984,     0, 
+     8192, 12288, 14336, 13824, 13952, 14016, 14000,     0, 
+     8192, 12288, 14336, 13824, 13952, 14016, 14000,     0, 
+     8192, 12288, 14336, 13824, 13952, 14016, 14000, 14002, 
+        0,  8192, 12288, 14336, 13824, 13952, 14016, 14000, 
+        0,  8192, 12288, 14336, 13824, 13952, 14016, 14000, 
+    14004,     0,  8192, 12288, 14336, 13824, 13952, 14016, 
+    14000, 14004,     0,  8192, 12288, 14336, 13824, 13952, 
+    14016, 14000, 14008, 14006,     0,  8192, 12288, 14336, 
+    13824, 13952, 14016, 14000,     0,  8192, 12288, 14336, 
+    13824, 13952, 14016, 14017, 14008,     0,  8192, 12288, 
+    14336, 13824, 13952, 14016, 14017, 14008,     0,  8192, 
+    12288, 14336, 13824, 13952, 14016, 14017, 14008, 14010, 
+        0,  8192, 12288, 14336, 13824, 13952, 14016, 14017, 
+    14008,     0,  8192, 12288, 14336, 13824, 13952, 14016, 
+    14017, 14008, 14012,     0,  8192, 12288, 14336, 13824, 
+    13952, 14016, 14017, 14019, 14012,     0,  8192, 12288, 
+    14336, 13824, 13952, 14016, 14017, 14019, 14012, 14014, 
+        0,  8192, 12288, 14336, 13824, 13952,     0,  8192, 
+    12288, 14336, 13824, 14080, 14016,     0,  8192, 12288, 
+    14336, 13824, 14080, 14016,     0,  8192, 12288, 14336, 
+    13824, 14080, 14016, 14018,     0,  8192, 12288, 14336, 
+    13824, 14080, 14016,     0,  8192, 12288, 14336, 13824, 
+    14080, 14016, 14020,     0,  8192, 12288, 14336, 13824, 
+    14080, 14016, 14020,     0,  8192, 12288, 14336, 13824, 
+    14080, 14016, 14024, 14022,     0,  8192, 12288, 14336, 
+    13824, 14080, 14016,     0,  8192, 12288, 14336, 13824, 
+    14080, 14016, 14024,     0,  8192, 12288, 14336, 13824, 
+    14080, 14016, 14024,     0,  8192, 12288, 14336, 13824, 
+    14080, 14016, 14024, 14026,     0,  8192, 12288, 14336, 
+    13824, 14080, 14016, 14024,     0,  8192, 12288, 14336, 
+    13824, 14080, 14016, 14032, 14028,     0,  8192, 12288, 
+    14336, 13824, 14080, 14016, 14032, 14028,     0,  8192, 
+    12288, 14336, 13824, 14080, 14016, 14032, 14033, 14030, 
+        0,  8192, 12288, 14336, 13824, 14080, 14016,     0, 
+     8192, 12288, 14336, 13824, 14080, 14016, 14032,     0, 
+     8192, 12288, 14336, 13824, 14080, 14016, 14032,     0, 
+     8192, 12288, 14336, 13824, 14080, 14016, 14032, 14034, 
+        0,  8192, 12288, 14336, 13824, 14080, 14016, 14032, 
+        0,  8192, 12288, 14336, 13824, 14080, 14016, 14032, 
+    14036,     0,  8192, 12288, 14336, 13824, 14080, 14016, 
+    14032, 14036,     0,  8192, 12288, 14336, 13824, 14080, 
+    14016, 14032, 14040, 14038,     0,  8192, 12288, 14336, 
+    13824, 14080, 14016, 14032,     0,  8192, 12288, 14336, 
+    13824, 14080, 14016, 14048, 14040,     0,  8192, 12288, 
+    14336, 13824, 14080, 14016, 14048, 14040,     0,  8192, 
+    12288, 14336, 13824, 14080, 14016, 14048, 14040, 14042, 
+        0,  8192, 12288, 14336, 13824, 14080, 14016, 14048, 
+    14040,     0,  8192, 12288, 14336, 13824, 14080, 14016, 
+    14048, 14049, 14044,     0,  8192, 12288, 14336, 13824, 
+    14080, 14016, 14048, 14049, 14044,     0,  8192, 12288, 
+    14336, 13824, 14080, 14016, 14048, 14049, 14044, 14046, 
+        0,  8192, 12288, 14336, 13824, 14080, 14016,     0, 
+     8192, 12288, 14336, 13824, 14080, 14081, 14048,     0, 
+     8192, 12288, 14336, 13824, 14080, 14081, 14048,     0, 
+     8192, 12288, 14336, 13824, 14080, 14081, 14048, 14050, 
+        0,  8192, 12288, 14336, 13824, 14080, 14081, 14048, 
+        0,  8192, 12288, 14336, 13824, 14080, 14081, 14048, 
+    14052,     0,  8192, 12288, 14336, 13824, 14080, 14081, 
+    14048, 14052,     0,  8192, 12288, 14336, 13824, 14080, 
+    14081, 14048, 14056, 14054,     0,  8192, 12288, 14336, 
+    13824, 14080, 14081, 14048,     0,  8192, 12288, 14336, 
+    13824, 14080, 14081, 14048, 14056,     0,  8192, 12288, 
+    14336, 13824, 14080, 14081, 14048, 14056,     0,  8192, 
+    12288, 14336, 13824, 14080, 14081, 14048, 14056, 14058, 
+        0,  8192, 12288, 14336, 13824, 14080, 14081, 14048, 
+    14056,     0,  8192, 12288, 14336, 13824, 14080, 14081, 
+    14048, 14064, 14060,     0,  8192, 12288, 14336, 13824, 
+    14080, 14081, 14048, 14064, 14060,     0,  8192, 12288, 
+    14336, 13824, 14080, 14081, 14048, 14064, 14065, 14062, 
+        0,  8192, 12288, 14336, 13824, 14080, 14081, 14048, 
+        0,  8192, 12288, 14336, 13824, 14080, 14081, 14048, 
+    14064,     0,  8192, 12288, 14336, 13824, 14080, 14081, 
+    14083, 14064,     0,  8192, 12288, 14336, 13824, 14080, 
+    14081, 14083, 14064, 14066,     0,  8192, 12288, 14336, 
+    13824, 14080, 14081, 14083, 14064,     0,  8192, 12288, 
+    14336, 13824, 14080, 14081, 14083, 14064, 14068,     0, 
+     8192, 12288, 14336, 13824, 14080, 14081, 14083, 14064, 
+    14068,     0,  8192, 12288, 14336, 13824, 14080, 14081, 
+    14083, 14064, 14072, 14070,     0,  8192, 12288, 14336, 
+    13824, 14080, 14081, 14083, 14064,     0,  8192, 12288, 
+    14336, 13824, 14080, 14081, 14083, 14064, 14072,     0, 
+     8192, 12288, 14336, 13824, 14080, 14081, 14083, 14064, 
+    14072,     0,  8192, 12288, 14336, 13824, 14080, 14081, 
+    14083, 14064, 14072, 14074,     0,  8192, 12288, 14336, 
+    13824, 14080, 14081, 14083, 14087, 14072,     0,  8192, 
+    12288, 14336, 13824, 14080, 14081, 14083, 14087, 14072, 
+    14076,     0,  8192, 12288, 14336, 13824, 14080, 14081, 
+    14083, 14087, 14072, 14076,     0,  8192, 12288, 14336, 
+    13824, 14080, 14081, 14083, 14087, 14072, 14076, 14078, 
+        0,  8192, 12288, 14336, 13824,     0,  8192, 12288, 
+    14336, 13824, 14080,     0,  8192, 12288, 14336, 14337, 
+    14080,     0,  8192, 12288, 14336, 14337, 14080, 14082, 
+        0,  8192, 12288, 14336, 14337, 14080,     0,  8192, 
+    12288, 14336, 14337, 14080, 14084,     0,  8192, 12288, 
+    14336, 14337, 14080, 14084,     0,  8192, 12288, 14336, 
+    14337, 14080, 14088, 14086,     0,  8192, 12288, 14336, 
+    14337, 14080,     0,  8192, 12288, 14336, 14337, 14080, 
+    14088,     0,  8192, 12288, 14336, 14337, 14080, 14088, 
+        0,  8192, 12288, 14336, 14337, 14080, 14088, 14090, 
+        0,  8192, 12288, 14336, 14337, 14080, 14088,     0, 
+     8192, 12288, 14336, 14337, 14080, 14096, 14092,     0, 
+     8192, 12288, 14336, 14337, 14080, 14096, 14092,     0, 
+     8192, 12288, 14336, 14337, 14080, 14096, 14097, 14094, 
+        0,  8192, 12288, 14336, 14337, 14080,     0,  8192, 
+    12288, 14336, 14337, 14080, 14096,     0,  8192, 12288, 
+    14336, 14337, 14080, 14096,     0,  8192, 12288, 14336, 
+    14337, 14080, 14096, 14098,     0,  8192, 12288, 14336, 
+    14337, 14080, 14096,     0,  8192, 12288, 14336, 14337, 
+    14080, 14096, 14100,     0,  8192, 12288, 14336, 14337, 
+    14080, 14096, 14100,     0,  8192, 12288, 14336, 14337, 
+    14080, 14096, 14104, 14102,     0,  8192, 12288, 14336, 
+    14337, 14080, 14096,     0,  8192, 12288, 14336, 14337, 
+    14080, 14112, 14104,     0,  8192, 12288, 14336, 14337, 
+    14080, 14112, 14104,     0,  8192, 12288, 14336, 14337, 
+    14080, 14112, 14104, 14106,     0,  8192, 12288, 14336, 
+    14337, 14080, 14112, 14104,     0,  8192, 12288, 14336, 
+    14337, 14080, 14112, 14113, 14108,     0,  8192, 12288, 
+    14336, 14337, 14080, 14112, 14113, 14108,     0,  8192, 
+    12288, 14336, 14337, 14080, 14112, 14113, 14108, 14110, 
+        0,  8192, 12288, 14336, 14337, 14080,     0,  8192, 
+    12288, 14336, 14337, 14080, 14112,     0,  8192, 12288, 
+    14336, 14337, 14080, 14112,     0,  8192, 12288, 14336, 
+    14337, 14080, 14112, 14114,     0,  8192, 12288, 14336, 
+    14337, 14080, 14112,     0,  8192, 12288, 14336, 14337, 
+    14080, 14112, 14116,     0,  8192, 12288, 14336, 14337, 
+    14080, 14112, 14116,     0,  8192, 12288, 14336, 14337, 
+    14080, 14112, 14120, 14118,     0,  8192, 12288, 14336, 
+    14337, 14080, 14112,     0,  8192, 12288, 14336, 14337, 
+    14080, 14112, 14120,     0,  8192, 12288, 14336, 14337, 
+    14080, 14112, 14120,     0,  8192, 12288, 14336, 14337, 
+    14080, 14112, 14120, 14122,     0,  8192, 12288, 14336, 
+    14337, 14080, 14112, 14120,     0,  8192, 12288, 14336, 
+    14337, 14080, 14112, 14128, 14124,     0,  8192, 12288, 
+    14336, 14337, 14080, 14112, 14128, 14124,     0,  8192, 
+    12288, 14336, 14337, 14080, 14112, 14128, 14129, 14126, 
+        0,  8192, 12288, 14336, 14337, 14080, 14112,     0, 
+     8192, 12288, 14336, 14337, 14080, 14144, 14128,     0, 
+     8192, 12288, 14336, 14337, 14080, 14144, 14128,     0, 
+     8192, 12288, 14336, 14337, 14080, 14144, 14128, 14130, 
+        0,  8192, 12288, 14336, 14337, 14080, 14144, 14128, 
+        0,  8192, 12288, 14336, 14337, 14080, 14144, 14128, 
+    14132,     0,  8192, 12288, 14336, 14337, 14080, 14144, 
+    14128, 14132,     0,  8192, 12288, 14336, 14337, 14080, 
+    14144, 14128, 14136, 14134,     0,  8192, 12288, 14336, 
+    14337, 14080, 14144, 14128,     0,  8192, 12288, 14336, 
+    14337, 14080, 14144, 14145, 14136,     0,  8192, 12288, 
+    14336, 14337, 14080, 14144, 14145, 14136,     0,  8192, 
+    12288, 14336, 14337, 14080, 14144, 14145, 14136, 14138, 
+        0,  8192, 12288, 14336, 14337, 14080, 14144, 14145, 
+    14136,     0,  8192, 12288, 14336, 14337, 14080, 14144, 
+    14145, 14136, 14140,     0,  8192, 12288, 14336, 14337, 
+    14080, 14144, 14145, 14147, 14140,     0,  8192, 12288, 
+    14336, 14337, 14080, 14144, 14145, 14147, 14140, 14142, 
+        0,  8192, 12288, 14336, 14337, 14080,     0,  8192, 
+    12288, 14336, 14337, 14080, 14144,     0,  8192, 12288, 
+    14336, 14337, 14080, 14144,     0,  8192, 12288, 14336, 
+    14337, 14080, 14144, 14146,     0,  8192, 12288, 14336, 
+    14337, 14080, 14144,     0,  8192, 12288, 14336, 14337, 
+    14080, 14144, 14148,     0,  8192, 12288, 14336, 14337, 
+    14080, 14144, 14148,     0,  8192, 12288, 14336, 14337, 
+    14080, 14144, 14152, 14150,     0,  8192, 12288, 14336, 
+    14337, 14080, 14144,     0,  8192, 12288, 14336, 14337, 
+    14080, 14144, 14152,     0,  8192, 12288, 14336, 14337, 
+    14080, 14144, 14152,     0,  8192, 12288, 14336, 14337, 
+    14080, 14144, 14152, 14154,     0,  8192, 12288, 14336, 
+    14337, 14080, 14144, 14152,     0,  8192, 12288, 14336, 
+    14337, 14080, 14144, 14160, 14156,     0,  8192, 12288, 
+    14336, 14337, 14080, 14144, 14160, 14156,     0,  8192, 
+    12288, 14336, 14337, 14080, 14144, 14160, 14161, 14158, 
+        0,  8192, 12288, 14336, 14337, 14080, 14144,     0, 
+     8192, 12288, 14336, 14337, 14080, 14144, 14160,     0, 
+     8192, 12288, 14336, 14337, 14080, 14144, 14160,     0, 
+     8192, 12288, 14336, 14337, 14080, 14144, 14160, 14162, 
+        0,  8192, 12288, 14336, 14337, 14080, 14144, 14160, 
+        0,  8192, 12288, 14336, 14337, 14080, 14144, 14160, 
+    14164,     0,  8192, 12288, 14336, 14337, 14080, 14144, 
+    14160, 14164,     0,  8192, 12288, 14336, 14337, 14080, 
+    14144, 14160, 14168, 14166,     0,  8192, 12288, 14336, 
+    14337, 14080, 14144, 14160,     0,  8192, 12288, 14336, 
+    14337, 14080, 14144, 14176, 14168,     0,  8192, 12288, 
+    14336, 14337, 14080, 14144, 14176, 14168,     0,  8192, 
+    12288, 14336, 14337, 14080, 14144, 14176, 14168, 14170, 
+        0,  8192, 12288, 14336, 14337, 14080, 14144, 14176, 
+    14168,     0,  8192, 12288, 14336, 14337, 14080, 14144, 
+    14176, 14177, 14172,     0,  8192, 12288, 14336, 14337, 
+    14080, 14144, 14176, 14177, 14172,     0,  8192, 12288, 
+    14336, 14337, 14080, 14144, 14176, 14177, 14172, 14174, 
+        0,  8192, 12288, 14336, 14337, 14080, 14144,     0, 
+     8192, 12288, 14336, 14337, 14080, 14208, 14176,     0, 
+     8192, 12288, 14336, 14337, 14080, 14208, 14176,     0, 
+     8192, 12288, 14336, 14337, 14080, 14208, 14176, 14178, 
+        0,  8192, 12288, 14336, 14337, 14080, 14208, 14176, 
+        0,  8192, 12288, 14336, 14337, 14080, 14208, 14176, 
+    14180,     0,  8192, 12288, 14336, 14337, 14080, 14208, 
+    14176, 14180,     0,  8192, 12288, 14336, 14337, 14080, 
+    14208, 14176, 14184, 14182,     0,  8192, 12288, 14336, 
+    14337, 14080, 14208, 14176,     0,  8192, 12288, 14336, 
+    14337, 14080, 14208, 14176, 14184,     0,  8192, 12288, 
+    14336, 14337, 14080, 14208, 14176, 14184,     0,  8192, 
+    12288, 14336, 14337, 14080, 14208, 14176, 14184, 14186, 
+        0,  8192, 12288, 14336, 14337, 14080, 14208, 14176, 
+    14184,     0,  8192, 12288, 14336, 14337, 14080, 14208, 
+    14176, 14192, 14188,     0,  8192, 12288, 14336, 14337, 
+    14080, 14208, 14176, 14192, 14188,     0,  8192, 12288, 
+    14336, 14337, 14080, 14208, 14176, 14192, 14193, 14190, 
+        0,  8192, 12288, 14336, 14337, 14080, 14208, 14176, 
+        0,  8192, 12288, 14336, 14337, 14080, 14208, 14209, 
+    14192,     0,  8192, 12288, 14336, 14337, 14080, 14208, 
+    14209, 14192,     0,  8192, 12288, 14336, 14337, 14080, 
+    14208, 14209, 14192, 14194,     0,  8192, 12288, 14336, 
+    14337, 14080, 14208, 14209, 14192,     0,  8192, 12288, 
+    14336, 14337, 14080, 14208, 14209, 14192, 14196,     0, 
+     8192, 12288, 14336, 14337, 14080, 14208, 14209, 14192, 
+    14196,     0,  8192, 12288, 14336, 14337, 14080, 14208, 
+    14209, 14192, 14200, 14198,     0,  8192, 12288, 14336, 
+    14337, 14080, 14208, 14209, 14192,     0,  8192, 12288, 
+    14336, 14337, 14080, 14208, 14209, 14192, 14200,     0, 
+     8192, 12288, 14336, 14337, 14080, 14208, 14209, 14211, 
+    14200,     0,  8192, 12288, 14336, 14337, 14080, 14208, 
+    14209, 14211, 14200, 14202,     0,  8192, 12288, 14336, 
+    14337, 14080, 14208, 14209, 14211, 14200,     0,  8192, 
+    12288, 14336, 14337, 14080, 14208, 14209, 14211, 14200, 
+    14204,     0,  8192, 12288, 14336, 14337, 14080, 14208, 
+    14209, 14211, 14200, 14204,     0,  8192, 12288, 14336, 
+    14337, 14080, 14208, 14209, 14211, 14200, 14204, 14206, 
+        0,  8192, 12288, 14336, 14337, 14080,     0,  8192, 
+    12288, 14336, 14337, 14080, 14208,     0,  8192, 12288, 
+    14336, 14337, 14080, 14208,     0,  8192, 12288, 14336, 
+    14337, 14080, 14208, 14210,     0,  8192, 12288, 14336, 
+    14337, 14339, 14208,     0,  8192, 12288, 14336, 14337, 
+    14339, 14208, 14212,     0,  8192, 12288, 14336, 14337, 
+    14339, 14208, 14212,     0,  8192, 12288, 14336, 14337, 
+    14339, 14208, 14216, 14214,     0,  8192, 12288, 14336, 
+    14337, 14339, 14208,     0,  8192, 12288, 14336, 14337, 
+    14339, 14208, 14216,     0,  8192, 12288, 14336, 14337, 
+    14339, 14208, 14216,     0,  8192, 12288, 14336, 14337, 
+    14339, 14208, 14216, 14218,     0,  8192, 12288, 14336, 
+    14337, 14339, 14208, 14216,     0,  8192, 12288, 14336, 
+    14337, 14339, 14208, 14224, 14220,     0,  8192, 12288, 
+    14336, 14337, 14339, 14208, 14224, 14220,     0,  8192, 
+    12288, 14336, 14337, 14339, 14208, 14224, 14225, 14222, 
+        0,  8192, 12288, 14336, 14337, 14339, 14208,     0, 
+     8192, 12288, 14336, 14337, 14339, 14208, 14224,     0, 
+     8192, 12288, 14336, 14337, 14339, 14208, 14224,     0, 
+     8192, 12288, 14336, 14337, 14339, 14208, 14224, 14226, 
+        0,  8192, 12288, 14336, 14337, 14339, 14208, 14224, 
+        0,  8192, 12288, 14336, 14337, 14339, 14208, 14224, 
+    14228,     0,  8192, 12288, 14336, 14337, 14339, 14208, 
+    14224, 14228,     0,  8192, 12288, 14336, 14337, 14339, 
+    14208, 14224, 14232, 14230,     0,  8192, 12288, 14336, 
+    14337, 14339, 14208, 14224,     0,  8192, 12288, 14336, 
+    14337, 14339, 14208, 14240, 14232,     0,  8192, 12288, 
+    14336, 14337, 14339, 14208, 14240, 14232,     0,  8192, 
+    12288, 14336, 14337, 14339, 14208, 14240, 14232, 14234, 
+        0,  8192, 12288, 14336, 14337, 14339, 14208, 14240, 
+    14232,     0,  8192, 12288, 14336, 14337, 14339, 14208, 
+    14240, 14241, 14236,     0,  8192, 12288, 14336, 14337, 
+    14339, 14208, 14240, 14241, 14236,     0,  8192, 12288, 
+    14336, 14337, 14339, 14208, 14240, 14241, 14236, 14238, 
+        0,  8192, 12288, 14336, 14337, 14339, 14208,     0, 
+     8192, 12288, 14336, 14337, 14339, 14208, 14240,     0, 
+     8192, 12288, 14336, 14337, 14339, 14208, 14240,     0, 
+     8192, 12288, 14336, 14337, 14339, 14208, 14240, 14242, 
+        0,  8192, 12288, 14336, 14337, 14339, 14208, 14240, 
+        0,  8192, 12288, 14336, 14337, 14339, 14208, 14240, 
+    14244,     0,  8192, 12288, 14336, 14337, 14339, 14208, 
+    14240, 14244,     0,  8192, 12288, 14336, 14337, 14339, 
+    14208, 14240, 14248, 14246,     0,  8192, 12288, 14336, 
+    14337, 14339, 14208, 14240,     0,  8192, 12288, 14336, 
+    14337, 14339, 14208, 14240, 14248,     0,  8192, 12288, 
+    14336, 14337, 14339, 14208, 14240, 14248,     0,  8192, 
+    12288, 14336, 14337, 14339, 14208, 14240, 14248, 14250, 
+        0,  8192, 12288, 14336, 14337, 14339, 14208, 14240, 
+    14248,     0,  8192, 12288, 14336, 14337, 14339, 14208, 
+    14240, 14256, 14252,     0,  8192, 12288, 14336, 14337, 
+    14339, 14208, 14240, 14256, 14252,     0,  8192, 12288, 
+    14336, 14337, 14339, 14208, 14240, 14256, 14257, 14254, 
+        0,  8192, 12288, 14336, 14337, 14339, 14208, 14240, 
+        0,  8192, 12288, 14336, 14337, 14339, 14208, 14272, 
+    14256,     0,  8192, 12288, 14336, 14337, 14339, 14208, 
+    14272, 14256,     0,  8192, 12288, 14336, 14337, 14339, 
+    14208, 14272, 14256, 14258,     0,  8192, 12288, 14336, 
+    14337, 14339, 14208, 14272, 14256,     0,  8192, 12288, 
+    14336, 14337, 14339, 14208, 14272, 14256, 14260,     0, 
+     8192, 12288, 14336, 14337, 14339, 14208, 14272, 14256, 
+    14260,     0,  8192, 12288, 14336, 14337, 14339, 14208, 
+    14272, 14256, 14264, 14262,     0,  8192, 12288, 14336, 
+    14337, 14339, 14208, 14272, 14256,     0,  8192, 12288, 
+    14336, 14337, 14339, 14208, 14272, 14273, 14264,     0, 
+     8192, 12288, 14336, 14337, 14339, 14208, 14272, 14273, 
+    14264,     0,  8192, 12288, 14336, 14337, 14339, 14208, 
+    14272, 14273, 14264, 14266,     0,  8192, 12288, 14336, 
+    14337, 14339, 14208, 14272, 14273, 14264,     0,  8192, 
+    12288, 14336, 14337, 14339, 14208, 14272, 14273, 14264, 
+    14268,     0,  8192, 12288, 14336, 14337, 14339, 14208, 
+    14272, 14273, 14275, 14268,     0,  8192, 12288, 14336, 
+    14337, 14339, 14208, 14272, 14273, 14275, 14268, 14270, 
+        0,  8192, 12288, 14336, 14337, 14339, 14208,     0, 
+     8192, 12288, 14336, 14337, 14339, 14208, 14272,     0, 
+     8192, 12288, 14336, 14337, 14339, 14208, 14272,     0, 
+     8192, 12288, 14336, 14337, 14339, 14208, 14272, 14274, 
+        0,  8192, 12288, 14336, 14337, 14339, 14208, 14272, 
+        0,  8192, 12288, 14336, 14337, 14339, 14208, 14272, 
+    14276,     0,  8192, 12288, 14336, 14337, 14339, 14208, 
+    14272, 14276,     0,  8192, 12288, 14336, 14337, 14339, 
+    14208, 14272, 14280, 14278,     0,  8192, 12288, 14336, 
+    14337, 14339, 14343, 14272,     0,  8192, 12288, 14336, 
+    14337, 14339, 14343, 14272, 14280,     0,  8192, 12288, 
+    14336, 14337, 14339, 14343, 14272, 14280,     0,  8192, 
+    12288, 14336, 14337, 14339, 14343, 14272, 14280, 14282, 
+        0,  8192, 12288, 14336, 14337, 14339, 14343, 14272, 
+    14280,     0,  8192, 12288, 14336, 14337, 14339, 14343, 
+    14272, 14288, 14284,     0,  8192, 12288, 14336, 14337, 
+    14339, 14343, 14272, 14288, 14284,     0,  8192, 12288, 
+    14336, 14337, 14339, 14343, 14272, 14288, 14289, 14286, 
+        0,  8192, 12288, 14336, 14337, 14339, 14343, 14272, 
+        0,  8192, 12288, 14336, 14337, 14339, 14343, 14272, 
+    14288,     0,  8192, 12288, 14336, 14337, 14339, 14343, 
+    14272, 14288,     0,  8192, 12288, 14336, 14337, 14339, 
+    14343, 14272, 14288, 14290,     0,  8192, 12288, 14336, 
+    14337, 14339, 14343, 14272, 14288,     0,  8192, 12288, 
+    14336, 14337, 14339, 14343, 14272, 14288, 14292,     0, 
+     8192, 12288, 14336, 14337, 14339, 14343, 14272, 14288, 
+    14292,     0,  8192, 12288, 14336, 14337, 14339, 14343, 
+    14272, 14288, 14296, 14294,     0,  8192, 12288, 14336, 
+    14337, 14339, 14343, 14272, 14288,     0,  8192, 12288, 
+    14336, 14337, 14339, 14343, 14272, 14304, 14296,     0, 
+     8192, 12288, 14336, 14337, 14339, 14343, 14272, 14304, 
+    14296,     0,  8192, 12288, 14336, 14337, 14339, 14343, 
+    14272, 14304, 14296, 14298,     0,  8192, 12288, 14336, 
+    14337, 14339, 14343, 14272, 14304, 14296,     0,  8192, 
+    12288, 14336, 14337, 14339, 14343, 14272, 14304, 14305, 
+    14300,     0,  8192, 12288, 14336, 14337, 14339, 14343, 
+    14272, 14304, 14305, 14300,     0,  8192, 12288, 14336, 
+    14337, 14339, 14343, 14272, 14304, 14305, 14300, 14302, 
+        0,  8192, 12288, 14336, 14337, 14339, 14343, 14272, 
+        0,  8192, 12288, 14336, 14337, 14339, 14343, 14272, 
+    14304,     0,  8192, 12288, 14336, 14337, 14339, 14343, 
+    14272, 14304,     0,  8192, 12288, 14336, 14337, 14339, 
+    14343, 14272, 14304, 14306,     0,  8192, 12288, 14336, 
+    14337, 14339, 14343, 14272, 14304,     0,  8192, 12288, 
+    14336, 14337, 14339, 14343, 14272, 14304, 14308,     0, 
+     8192, 12288, 14336, 14337, 14339, 14343, 14272, 14304, 
+    14308,     0,  8192, 12288, 14336, 14337, 14339, 14343, 
+    14272, 14304, 14312, 14310,     0,  8192, 12288, 14336, 
+    14337, 14339, 14343, 14272, 14304,     0,  8192, 12288, 
+    14336, 14337, 14339, 14343, 14272, 14304, 14312,     0, 
+     8192, 12288, 14336, 14337, 14339, 14343, 14272, 14304, 
+    14312,     0,  8192, 12288, 14336, 14337, 14339, 14343, 
+    14272, 14304, 14312, 14314,     0,  8192, 12288, 14336, 
+    14337, 14339, 14343, 14272, 14304, 14312,     0,  8192, 
+    12288, 14336, 14337, 14339, 14343, 14272, 14304, 14320, 
+    14316,     0,  8192, 12288, 14336, 14337, 14339, 14343, 
+    14272, 14304, 14320, 14316,     0,  8192, 12288, 14336, 
+    14337, 14339, 14343, 14272, 14304, 14320, 14321, 14318, 
+        0,  8192, 12288, 14336, 14337, 14339, 14343, 14351, 
+    14304,     0,  8192, 12288, 14336, 14337, 14339, 14343, 
+    14351, 14304, 14320,     0,  8192, 12288, 14336, 14337, 
+    14339, 14343, 14351, 14304, 14320,     0,  8192, 12288, 
+    14336, 14337, 14339, 14343, 14351, 14304, 14320, 14322, 
+        0,  8192, 12288, 14336, 14337, 14339, 14343, 14351, 
+    14304, 14320,     0,  8192, 12288, 14336, 14337, 14339, 
+    14343, 14351, 14304, 14320, 14324,     0,  8192, 12288, 
+    14336, 14337, 14339, 14343, 14351, 14304, 14320, 14324, 
+        0,  8192, 12288, 14336, 14337, 14339, 14343, 14351, 
+    14304, 14320, 14328, 14326,     0,  8192, 12288, 14336, 
+    14337, 14339, 14343, 14351, 14304, 14320,     0,  8192, 
+    12288, 14336, 14337, 14339, 14343, 14351, 14304, 14320, 
+    14328,     0,  8192, 12288, 14336, 14337, 14339, 14343, 
+    14351, 14304, 14320, 14328,     0,  8192, 12288, 14336, 
+    14337, 14339, 14343, 14351, 14304, 14320, 14328, 14330, 
+        0,  8192, 12288, 14336, 14337, 14339, 14343, 14351, 
+    14304, 14320, 14328,     0,  8192, 12288, 14336, 14337, 
+    14339, 14343, 14351, 14304, 14320, 14328, 14332,     0, 
+     8192, 12288, 14336, 14337, 14339, 14343, 14351, 14304, 
+    14320, 14328, 14332,     0,  8192, 12288, 14336, 14337, 
+    14339, 14343, 14351, 14304, 14320, 14328, 14332, 14334, 
+        0,  8192, 12288,     0,  8192, 12288, 14336,     0, 
+     8192, 12288, 14336,     0,  8192, 12288, 14336, 14338, 
+        0,  8192, 12288, 14336,     0,  8192, 12288, 14336, 
+    14340,     0,  8192, 12288, 14336, 14340,     0,  8192, 
+    12288, 14336, 14344, 14342,     0,  8192, 12288, 14336, 
+        0,  8192, 12288, 14336, 14344,     0,  8192, 12288, 
+    14336, 14344,     0,  8192, 12288, 14336, 14344, 14346, 
+        0,  8192, 12288, 14336, 14344,     0,  8192, 12288, 
+    14336, 14352, 14348,     0,  8192, 12288, 14336, 14352, 
+    14348,     0,  8192, 12288, 14336, 14352, 14353, 14350, 
+        0,  8192, 12288, 14336,     0,  8192, 12288, 14336, 
+    14352,     0,  8192, 12288, 14336, 14352,     0,  8192, 
+    12288, 14336, 14352, 14354,     0,  8192, 12288, 14336, 
+    14352,     0,  8192, 12288, 14336, 14352, 14356,     0, 
+     8192, 12288, 14336, 14352, 14356,     0,  8192, 12288, 
+    14336, 14352, 14360, 14358,     0,  8192, 12288, 14336, 
+    14352,     0,  8192, 12288, 14336, 14368, 14360,     0, 
+     8192, 12288, 14336, 14368, 14360,     0,  8192, 12288, 
+    14336, 14368, 14360, 14362,     0,  8192, 12288, 14336, 
+    14368, 14360,     0,  8192, 12288, 14336, 14368, 14369, 
+    14364,     0,  8192, 12288, 14336, 14368, 14369, 14364, 
+        0,  8192, 12288, 14336, 14368, 14369, 14364, 14366, 
+        0,  8192, 12288, 14336,     0,  8192, 12288, 14336, 
+    14368,     0,  8192, 12288, 14336, 14368,     0,  8192, 
+    12288, 14336, 14368, 14370,     0,  8192, 12288, 14336, 
+    14368,     0,  8192, 12288, 14336, 14368, 14372,     0, 
+     8192, 12288, 14336, 14368, 14372,     0,  8192, 12288, 
+    14336, 14368, 14376, 14374,     0,  8192, 12288, 14336, 
+    14368,     0,  8192, 12288, 14336, 14368, 14376,     0, 
+     8192, 12288, 14336, 14368, 14376,     0,  8192, 12288, 
+    14336, 14368, 14376, 14378,     0,  8192, 12288, 14336, 
+    14368, 14376,     0,  8192, 12288, 14336, 14368, 14384, 
+    14380,     0,  8192, 12288, 14336, 14368, 14384, 14380, 
+        0,  8192, 12288, 14336, 14368, 14384, 14385, 14382, 
+        0,  8192, 12288, 14336, 14368,     0,  8192, 12288, 
+    14336, 14400, 14384,     0,  8192, 12288, 14336, 14400, 
+    14384,     0,  8192, 12288, 14336, 14400, 14384, 14386, 
+        0,  8192, 12288, 14336, 14400, 14384,     0,  8192, 
+    12288, 14336, 14400, 14384, 14388,     0,  8192, 12288, 
+    14336, 14400, 14384, 14388,     0,  8192, 12288, 14336, 
+    14400, 14384, 14392, 14390,     0,  8192, 12288, 14336, 
+    14400, 14384,     0,  8192, 12288, 14336, 14400, 14401, 
+    14392,     0,  8192, 12288, 14336, 14400, 14401, 14392, 
+        0,  8192, 12288, 14336, 14400, 14401, 14392, 14394, 
+        0,  8192, 12288, 14336, 14400, 14401, 14392,     0, 
+     8192, 12288, 14336, 14400, 14401, 14392, 14396,     0, 
+     8192, 12288, 14336, 14400, 14401, 14403, 14396,     0, 
+     8192, 12288, 14336, 14400, 14401, 14403, 14396, 14398, 
+        0,  8192, 12288, 14336,     0,  8192, 12288, 14336, 
+    14400,     0,  8192, 12288, 14336, 14400,     0,  8192, 
+    12288, 14336, 14400, 14402,     0,  8192, 12288, 14336, 
+    14400,     0,  8192, 12288, 14336, 14400, 14404,     0, 
+     8192, 12288, 14336, 14400, 14404,     0,  8192, 12288, 
+    14336, 14400, 14408, 14406,     0,  8192, 12288, 14336, 
+    14400,     0,  8192, 12288, 14336, 14400, 14408,     0, 
+     8192, 12288, 14336, 14400, 14408,     0,  8192, 12288, 
+    14336, 14400, 14408, 14410,     0,  8192, 12288, 14336, 
+    14400, 14408,     0,  8192, 12288, 14336, 14400, 14416, 
+    14412,     0,  8192, 12288, 14336, 14400, 14416, 14412, 
+        0,  8192, 12288, 14336, 14400, 14416, 14417, 14414, 
+        0,  8192, 12288, 14336, 14400,     0,  8192, 12288, 
+    14336, 14400, 14416,     0,  8192, 12288, 14336, 14400, 
+    14416,     0,  8192, 12288, 14336, 14400, 14416, 14418, 
+        0,  8192, 12288, 14336, 14400, 14416,     0,  8192, 
+    12288, 14336, 14400, 14416, 14420,     0,  8192, 12288, 
+    14336, 14400, 14416, 14420,     0,  8192, 12288, 14336, 
+    14400, 14416, 14424, 14422,     0,  8192, 12288, 14336, 
+    14400, 14416,     0,  8192, 12288, 14336, 14400, 14432, 
+    14424,     0,  8192, 12288, 14336, 14400, 14432, 14424, 
+        0,  8192, 12288, 14336, 14400, 14432, 14424, 14426, 
+        0,  8192, 12288, 14336, 14400, 14432, 14424,     0, 
+     8192, 12288, 14336, 14400, 14432, 14433, 14428,     0, 
+     8192, 12288, 14336, 14400, 14432, 14433, 14428,     0, 
+     8192, 12288, 14336, 14400, 14432, 14433, 14428, 14430, 
+        0,  8192, 12288, 14336, 14400,     0,  8192, 12288, 
+    14336, 14464, 14432,     0,  8192, 12288, 14336, 14464, 
+    14432,     0,  8192, 12288, 14336, 14464, 14432, 14434, 
+        0,  8192, 12288, 14336, 14464, 14432,     0,  8192, 
+    12288, 14336, 14464, 14432, 14436,     0,  8192, 12288, 
+    14336, 14464, 14432, 14436,     0,  8192, 12288, 14336, 
+    14464, 14432, 14440, 14438,     0,  8192, 12288, 14336, 
+    14464, 14432,     0,  8192, 12288, 14336, 14464, 14432, 
+    14440,     0,  8192, 12288, 14336, 14464, 14432, 14440, 
+        0,  8192, 12288, 14336, 14464, 14432, 14440, 14442, 
+        0,  8192, 12288, 14336, 14464, 14432, 14440,     0, 
+     8192, 12288, 14336, 14464, 14432, 14448, 14444,     0, 
+     8192, 12288, 14336, 14464, 14432, 14448, 14444,     0, 
+     8192, 12288, 14336, 14464, 14432, 14448, 14449, 14446, 
+        0,  8192, 12288, 14336, 14464, 14432,     0,  8192, 
+    12288, 14336, 14464, 14465, 14448,     0,  8192, 12288, 
+    14336, 14464, 14465, 14448,     0,  8192, 12288, 14336, 
+    14464, 14465, 14448, 14450,     0,  8192, 12288, 14336, 
+    14464, 14465, 14448,     0,  8192, 12288, 14336, 14464, 
+    14465, 14448, 14452,     0,  8192, 12288, 14336, 14464, 
+    14465, 14448, 14452,     0,  8192, 12288, 14336, 14464, 
+    14465, 14448, 14456, 14454,     0,  8192, 12288, 14336, 
+    14464, 14465, 14448,     0,  8192, 12288, 14336, 14464, 
+    14465, 14448, 14456,     0,  8192, 12288, 14336, 14464, 
+    14465, 14467, 14456,     0,  8192, 12288, 14336, 14464, 
+    14465, 14467, 14456, 14458,     0,  8192, 12288, 14336, 
+    14464, 14465, 14467, 14456,     0,  8192, 12288, 14336, 
+    14464, 14465, 14467, 14456, 14460,     0,  8192, 12288, 
+    14336, 14464, 14465, 14467, 14456, 14460,     0,  8192, 
+    12288, 14336, 14464, 14465, 14467, 14456, 14460, 14462, 
+        0,  8192, 12288, 14336,     0,  8192, 12288, 14336, 
+    14464,     0,  8192, 12288, 14336, 14464,     0,  8192, 
+    12288, 14336, 14464, 14466,     0,  8192, 12288, 14336, 
+    14464,     0,  8192, 12288, 14336, 14464, 14468,     0, 
+     8192, 12288, 14336, 14464, 14468,     0,  8192, 12288, 
+    14336, 14464, 14472, 14470,     0,  8192, 12288, 14336, 
+    14464,     0,  8192, 12288, 14336, 14464, 14472,     0, 
+     8192, 12288, 14336, 14464, 14472,     0,  8192, 12288, 
+    14336, 14464, 14472, 14474,     0,  8192, 12288, 14336, 
+    14464, 14472,     0,  8192, 12288, 14336, 14464, 14480, 
+    14476,     0,  8192, 12288, 14336, 14464, 14480, 14476, 
+        0,  8192, 12288, 14336, 14464, 14480, 14481, 14478, 
+        0,  8192, 12288, 14336, 14464,     0,  8192, 12288, 
+    14336, 14464, 14480,     0,  8192, 12288, 14336, 14464, 
+    14480,     0,  8192, 12288, 14336, 14464, 14480, 14482, 
+        0,  8192, 12288, 14336, 14464, 14480,     0,  8192, 
+    12288, 14336, 14464, 14480, 14484,     0,  8192, 12288, 
+    14336, 14464, 14480, 14484,     0,  8192, 12288, 14336, 
+    14464, 14480, 14488, 14486,     0,  8192, 12288, 14336, 
+    14464, 14480,     0,  8192, 12288, 14336, 14464, 14496, 
+    14488,     0,  8192, 12288, 14336, 14464, 14496, 14488, 
+        0,  8192, 12288, 14336, 14464, 14496, 14488, 14490, 
+        0,  8192, 12288, 14336, 14464, 14496, 14488,     0, 
+     8192, 12288, 14336, 14464, 14496, 14497, 14492,     0, 
+     8192, 12288, 14336, 14464, 14496, 14497, 14492,     0, 
+     8192, 12288, 14336, 14464, 14496, 14497, 14492, 14494, 
+        0,  8192, 12288, 14336, 14464,     0,  8192, 12288, 
+    14336, 14464, 14496,     0,  8192, 12288, 14336, 14464, 
+    14496,     0,  8192, 12288, 14336, 14464, 14496, 14498, 
+        0,  8192, 12288, 14336, 14464, 14496,     0,  8192, 
+    12288, 14336, 14464, 14496, 14500,     0,  8192, 12288, 
+    14336, 14464, 14496, 14500,     0,  8192, 12288, 14336, 
+    14464, 14496, 14504, 14502,     0,  8192, 12288, 14336, 
+    14464, 14496,     0,  8192, 12288, 14336, 14464, 14496, 
+    14504,     0,  8192, 12288, 14336, 14464, 14496, 14504, 
+        0,  8192, 12288, 14336, 14464, 14496, 14504, 14506, 
+        0,  8192, 12288, 14336, 14464, 14496, 14504,     0, 
+     8192, 12288, 14336, 14464, 14496, 14512, 14508,     0, 
+     8192, 12288, 14336, 14464, 14496, 14512, 14508,     0, 
+     8192, 12288, 14336, 14464, 14496, 14512, 14513, 14510, 
+        0,  8192, 12288, 14336, 14464, 14496,     0,  8192, 
+    12288, 14336, 14464, 14528, 14512,     0,  8192, 12288, 
+    14336, 14464, 14528, 14512,     0,  8192, 12288, 14336, 
+    14464, 14528, 14512, 14514,     0,  8192, 12288, 14336, 
+    14464, 14528, 14512,     0,  8192, 12288, 14336, 14464, 
+    14528, 14512, 14516,     0,  8192, 12288, 14336, 14464, 
+    14528, 14512, 14516,     0,  8192, 12288, 14336, 14464, 
+    14528, 14512, 14520, 14518,     0,  8192, 12288, 14336, 
+    14464, 14528, 14512,     0,  8192, 12288, 14336, 14464, 
+    14528, 14529, 14520,     0,  8192, 12288, 14336, 14464, 
+    14528, 14529, 14520,     0,  8192, 12288, 14336, 14464, 
+    14528, 14529, 14520, 14522,     0,  8192, 12288, 14336, 
+    14464, 14528, 14529, 14520,     0,  8192, 12288, 14336, 
+    14464, 14528, 14529, 14520, 14524,     0,  8192, 12288, 
+    14336, 14464, 14528, 14529, 14531, 14524,     0,  8192, 
+    12288, 14336, 14464, 14528, 14529, 14531, 14524, 14526, 
+        0,  8192, 12288, 14336, 14464,     0,  8192, 12288, 
+    14336, 14592, 14528,     0,  8192, 12288, 14336, 14592, 
+    14528,     0,  8192, 12288, 14336, 14592, 14528, 14530, 
+        0,  8192, 12288, 14336, 14592, 14528,     0,  8192, 
+    12288, 14336, 14592, 14528, 14532,     0,  8192, 12288, 
+    14336, 14592, 14528, 14532,     0,  8192, 12288, 14336, 
+    14592, 14528, 14536, 14534,     0,  8192, 12288, 14336, 
+    14592, 14528,     0,  8192, 12288, 14336, 14592, 14528, 
+    14536,     0,  8192, 12288, 14336, 14592, 14528, 14536, 
+        0,  8192, 12288, 14336, 14592, 14528, 14536, 14538, 
+        0,  8192, 12288, 14336, 14592, 14528, 14536,     0, 
+     8192, 12288, 14336, 14592, 14528, 14544, 14540,     0, 
+     8192, 12288, 14336, 14592, 14528, 14544, 14540,     0, 
+     8192, 12288, 14336, 14592, 14528, 14544, 14545, 14542, 
+        0,  8192, 12288, 14336, 14592, 14528,     0,  8192, 
+    12288, 14336, 14592, 14528, 14544,     0,  8192, 12288, 
+    14336, 14592, 14528, 14544,     0,  8192, 12288, 14336, 
+    14592, 14528, 14544, 14546,     0,  8192, 12288, 14336, 
+    14592, 14528, 14544,     0,  8192, 12288, 14336, 14592, 
+    14528, 14544, 14548,     0,  8192, 12288, 14336, 14592, 
+    14528, 14544, 14548,     0,  8192, 12288, 14336, 14592, 
+    14528, 14544, 14552, 14550,     0,  8192, 12288, 14336, 
+    14592, 14528, 14544,     0,  8192, 12288, 14336, 14592, 
+    14528, 14560, 14552,     0,  8192, 12288, 14336, 14592, 
+    14528, 14560, 14552,     0,  8192, 12288, 14336, 14592, 
+    14528, 14560, 14552, 14554,     0,  8192, 12288, 14336, 
+    14592, 14528, 14560, 14552,     0,  8192, 12288, 14336, 
+    14592, 14528, 14560, 14561, 14556,     0,  8192, 12288, 
+    14336, 14592, 14528, 14560, 14561, 14556,     0,  8192, 
+    12288, 14336, 14592, 14528, 14560, 14561, 14556, 14558, 
+        0,  8192, 12288, 14336, 14592, 14528,     0,  8192, 
+    12288, 14336, 14592, 14593, 14560,     0,  8192, 12288, 
+    14336, 14592, 14593, 14560,     0,  8192, 12288, 14336, 
+    14592, 14593, 14560, 14562,     0,  8192, 12288, 14336, 
+    14592, 14593, 14560,     0,  8192, 12288, 14336, 14592, 
+    14593, 14560, 14564,     0,  8192, 12288, 14336, 14592, 
+    14593, 14560, 14564,     0,  8192, 12288, 14336, 14592, 
+    14593, 14560, 14568, 14566,     0,  8192, 12288, 14336, 
+    14592, 14593, 14560,     0,  8192, 12288, 14336, 14592, 
+    14593, 14560, 14568,     0,  8192, 12288, 14336, 14592, 
+    14593, 14560, 14568,     0,  8192, 12288, 14336, 14592, 
+    14593, 14560, 14568, 14570,     0,  8192, 12288, 14336, 
+    14592, 14593, 14560, 14568,     0,  8192, 12288, 14336, 
+    14592, 14593, 14560, 14576, 14572,     0,  8192, 12288, 
+    14336, 14592, 14593, 14560, 14576, 14572,     0,  8192, 
+    12288, 14336, 14592, 14593, 14560, 14576, 14577, 14574, 
+        0,  8192, 12288, 14336, 14592, 14593, 14560,     0, 
+     8192, 12288, 14336, 14592, 14593, 14560, 14576,     0, 
+     8192, 12288, 14336, 14592, 14593, 14595, 14576,     0, 
+     8192, 12288, 14336, 14592, 14593, 14595, 14576, 14578, 
+        0,  8192, 12288, 14336, 14592, 14593, 14595, 14576, 
+        0,  8192, 12288, 14336, 14592, 14593, 14595, 14576, 
+    14580,     0,  8192, 12288, 14336, 14592, 14593, 14595, 
+    14576, 14580,     0,  8192, 12288, 14336, 14592, 14593, 
+    14595, 14576, 14584, 14582,     0,  8192, 12288, 14336, 
+    14592, 14593, 14595, 14576,     0,  8192, 12288, 14336, 
+    14592, 14593, 14595, 14576, 14584,     0,  8192, 12288, 
+    14336, 14592, 14593, 14595, 14576, 14584,     0,  8192, 
+    12288, 14336, 14592, 14593, 14595, 14576, 14584, 14586, 
+        0,  8192, 12288, 14336, 14592, 14593, 14595, 14599, 
+    14584,     0,  8192, 12288, 14336, 14592, 14593, 14595, 
+    14599, 14584, 14588,     0,  8192, 12288, 14336, 14592, 
+    14593, 14595, 14599, 14584, 14588,     0,  8192, 12288, 
+    14336, 14592, 14593, 14595, 14599, 14584, 14588, 14590, 
+        0,  8192, 12288, 14336,     0,  8192, 12288, 14336, 
+    14592,     0,  8192, 12288, 14336, 14592,     0,  8192, 
+    12288, 14336, 14592, 14594,     0,  8192, 12288, 14336, 
+    14592,     0,  8192, 12288, 14336, 14592, 14596,     0, 
+     8192, 12288, 14336, 14592, 14596,     0,  8192, 12288, 
+    14336, 14592, 14600, 14598,     0,  8192, 12288, 14336, 
+    14592,     0,  8192, 12288, 14336, 14592, 14600,     0, 
+     8192, 12288, 14336, 14592, 14600,     0,  8192, 12288, 
+    14336, 14592, 14600, 14602,     0,  8192, 12288, 14336, 
+    14592, 14600,     0,  8192, 12288, 14336, 14592, 14608, 
+    14604,     0,  8192, 12288, 14336, 14592, 14608, 14604, 
+        0,  8192, 12288, 14336, 14592, 14608, 14609, 14606, 
+        0,  8192, 12288, 14336, 14592,     0,  8192, 12288, 
+    14336, 14592, 14608,     0,  8192, 12288, 14336, 14592, 
+    14608,     0,  8192, 12288, 14336, 14592, 14608, 14610, 
+        0,  8192, 12288, 14336, 14592, 14608,     0,  8192, 
+    12288, 14336, 14592, 14608, 14612,     0,  8192, 12288, 
+    14336, 14592, 14608, 14612,     0,  8192, 12288, 14336, 
+    14592, 14608, 14616, 14614,     0,  8192, 12288, 14336, 
+    14592, 14608,     0,  8192, 12288, 14336, 14592, 14624, 
+    14616,     0,  8192, 12288, 14336, 14592, 14624, 14616, 
+        0,  8192, 12288, 14336, 14592, 14624, 14616, 14618, 
+        0,  8192, 12288, 14336, 14592, 14624, 14616,     0, 
+     8192, 12288, 14336, 14592, 14624, 14625, 14620,     0, 
+     8192, 12288, 14336, 14592, 14624, 14625, 14620,     0, 
+     8192, 12288, 14336, 14592, 14624, 14625, 14620, 14622, 
+        0,  8192, 12288, 14336, 14592,     0,  8192, 12288, 
+    14336, 14592, 14624,     0,  8192, 12288, 14336, 14592, 
+    14624,     0,  8192, 12288, 14336, 14592, 14624, 14626, 
+        0,  8192, 12288, 14336, 14592, 14624,     0,  8192, 
+    12288, 14336, 14592, 14624, 14628,     0,  8192, 12288, 
+    14336, 14592, 14624, 14628,     0,  8192, 12288, 14336, 
+    14592, 14624, 14632, 14630,     0,  8192, 12288, 14336, 
+    14592, 14624,     0,  8192, 12288, 14336, 14592, 14624, 
+    14632,     0,  8192, 12288, 14336, 14592, 14624, 14632, 
+        0,  8192, 12288, 14336, 14592, 14624, 14632, 14634, 
+        0,  8192, 12288, 14336, 14592, 14624, 14632,     0, 
+     8192, 12288, 14336, 14592, 14624, 14640, 14636,     0, 
+     8192, 12288, 14336, 14592, 14624, 14640, 14636,     0, 
+     8192, 12288, 14336, 14592, 14624, 14640, 14641, 14638, 
+        0,  8192, 12288, 14336, 14592, 14624,     0,  8192, 
+    12288, 14336, 14592, 14656, 14640,     0,  8192, 12288, 
+    14336, 14592, 14656, 14640,     0,  8192, 12288, 14336, 
+    14592, 14656, 14640, 14642,     0,  8192, 12288, 14336, 
+    14592, 14656, 14640,     0,  8192, 12288, 14336, 14592, 
+    14656, 14640, 14644,     0,  8192, 12288, 14336, 14592, 
+    14656, 14640, 14644,     0,  8192, 12288, 14336, 14592, 
+    14656, 14640, 14648, 14646,     0,  8192, 12288, 14336, 
+    14592, 14656, 14640,     0,  8192, 12288, 14336, 14592, 
+    14656, 14657, 14648,     0,  8192, 12288, 14336, 14592, 
+    14656, 14657, 14648,     0,  8192, 12288, 14336, 14592, 
+    14656, 14657, 14648, 14650,     0,  8192, 12288, 14336, 
+    14592, 14656, 14657, 14648,     0,  8192, 12288, 14336, 
+    14592, 14656, 14657, 14648, 14652,     0,  8192, 12288, 
+    14336, 14592, 14656, 14657, 14659, 14652,     0,  8192, 
+    12288, 14336, 14592, 14656, 14657, 14659, 14652, 14654, 
+        0,  8192, 12288, 14336, 14592,     0,  8192, 12288, 
+    14336, 14592, 14656,     0,  8192, 12288, 14336, 14592, 
+    14656,     0,  8192, 12288, 14336, 14592, 14656, 14658, 
+        0,  8192, 12288, 14336, 14592, 14656,     0,  8192, 
+    12288, 14336, 14592, 14656, 14660,     0,  8192, 12288, 
+    14336, 14592, 14656, 14660,     0,  8192, 12288, 14336, 
+    14592, 14656, 14664, 14662,     0,  8192, 12288, 14336, 
+    14592, 14656,     0,  8192, 12288, 14336, 14592, 14656, 
+    14664,     0,  8192, 12288, 14336, 14592, 14656, 14664, 
+        0,  8192, 12288, 14336, 14592, 14656, 14664, 14666, 
+        0,  8192, 12288, 14336, 14592, 14656, 14664,     0, 
+     8192, 12288, 14336, 14592, 14656, 14672, 14668,     0, 
+     8192, 12288, 14336, 14592, 14656, 14672, 14668,     0, 
+     8192, 12288, 14336, 14592, 14656, 14672, 14673, 14670, 
+        0,  8192, 12288, 14336, 14592, 14656,     0,  8192, 
+    12288, 14336, 14592, 14656, 14672,     0,  8192, 12288, 
+    14336, 14592, 14656, 14672,     0,  8192, 12288, 14336, 
+    14592, 14656, 14672, 14674,     0,  8192, 12288, 14336, 
+    14592, 14656, 14672,     0,  8192, 12288, 14336, 14592, 
+    14656, 14672, 14676,     0,  8192, 12288, 14336, 14592, 
+    14656, 14672, 14676,     0,  8192, 12288, 14336, 14592, 
+    14656, 14672, 14680, 14678,     0,  8192, 12288, 14336, 
+    14592, 14656, 14672,     0,  8192, 12288, 14336, 14592, 
+    14656, 14688, 14680,     0,  8192, 12288, 14336, 14592, 
+    14656, 14688, 14680,     0,  8192, 12288, 14336, 14592, 
+    14656, 14688, 14680, 14682,     0,  8192, 12288, 14336, 
+    14592, 14656, 14688, 14680,     0,  8192, 12288, 14336, 
+    14592, 14656, 14688, 14689, 14684,     0,  8192, 12288, 
+    14336, 14592, 14656, 14688, 14689, 14684,     0,  8192, 
+    12288, 14336, 14592, 14656, 14688, 14689, 14684, 14686, 
+        0,  8192, 12288, 14336, 14592, 14656,     0,  8192, 
+    12288, 14336, 14592, 14720, 14688,     0,  8192, 12288, 
+    14336, 14592, 14720, 14688,     0,  8192, 12288, 14336, 
+    14592, 14720, 14688, 14690,     0,  8192, 12288, 14336, 
+    14592, 14720, 14688,     0,  8192, 12288, 14336, 14592, 
+    14720, 14688, 14692,     0,  8192, 12288, 14336, 14592, 
+    14720, 14688, 14692,     0,  8192, 12288, 14336, 14592, 
+    14720, 14688, 14696, 14694,     0,  8192, 12288, 14336, 
+    14592, 14720, 14688,     0,  8192, 12288, 14336, 14592, 
+    14720, 14688, 14696,     0,  8192, 12288, 14336, 14592, 
+    14720, 14688, 14696,     0,  8192, 12288, 14336, 14592, 
+    14720, 14688, 14696, 14698,     0,  8192, 12288, 14336, 
+    14592, 14720, 14688, 14696,     0,  8192, 12288, 14336, 
+    14592, 14720, 14688, 14704, 14700,     0,  8192, 12288, 
+    14336, 14592, 14720, 14688, 14704, 14700,     0,  8192, 
+    12288, 14336, 14592, 14720, 14688, 14704, 14705, 14702, 
+        0,  8192, 12288, 14336, 14592, 14720, 14688,     0, 
+     8192, 12288, 14336, 14592, 14720, 14721, 14704,     0, 
+     8192, 12288, 14336, 14592, 14720, 14721, 14704,     0, 
+     8192, 12288, 14336, 14592, 14720, 14721, 14704, 14706, 
+        0,  8192, 12288, 14336, 14592, 14720, 14721, 14704, 
+        0,  8192, 12288, 14336, 14592, 14720, 14721, 14704, 
+    14708,     0,  8192, 12288, 14336, 14592, 14720, 14721, 
+    14704, 14708,     0,  8192, 12288, 14336, 14592, 14720, 
+    14721, 14704, 14712, 14710,     0,  8192, 12288, 14336, 
+    14592, 14720, 14721, 14704,     0,  8192, 12288, 14336, 
+    14592, 14720, 14721, 14704, 14712,     0,  8192, 12288, 
+    14336, 14592, 14720, 14721, 14723, 14712,     0,  8192, 
+    12288, 14336, 14592, 14720, 14721, 14723, 14712, 14714, 
+        0,  8192, 12288, 14336, 14592, 14720, 14721, 14723, 
+    14712,     0,  8192, 12288, 14336, 14592, 14720, 14721, 
+    14723, 14712, 14716,     0,  8192, 12288, 14336, 14592, 
+    14720, 14721, 14723, 14712, 14716,     0,  8192, 12288, 
+    14336, 14592, 14720, 14721, 14723, 14712, 14716, 14718, 
+        0,  8192, 12288, 14336, 14592,     0,  8192, 12288, 
+    14336, 14848, 14720,     0,  8192, 12288, 14336, 14848, 
+    14720,     0,  8192, 12288, 14336, 14848, 14720, 14722, 
+        0,  8192, 12288, 14336, 14848, 14720,     0,  8192, 
+    12288, 14336, 14848, 14720, 14724,     0,  8192, 12288, 
+    14336, 14848, 14720, 14724,     0,  8192, 12288, 14336, 
+    14848, 14720, 14728, 14726,     0,  8192, 12288, 14336, 
+    14848, 14720,     0,  8192, 12288, 14336, 14848, 14720, 
+    14728,     0,  8192, 12288, 14336, 14848, 14720, 14728, 
+        0,  8192, 12288, 14336, 14848, 14720, 14728, 14730, 
+        0,  8192, 12288, 14336, 14848, 14720, 14728,     0, 
+     8192, 12288, 14336, 14848, 14720, 14736, 14732,     0, 
+     8192, 12288, 14336, 14848, 14720, 14736, 14732,     0, 
+     8192, 12288, 14336, 14848, 14720, 14736, 14737, 14734, 
+        0,  8192, 12288, 14336, 14848, 14720,     0,  8192, 
+    12288, 14336, 14848, 14720, 14736,     0,  8192, 12288, 
+    14336, 14848, 14720, 14736,     0,  8192, 12288, 14336, 
+    14848, 14720, 14736, 14738,     0,  8192, 12288, 14336, 
+    14848, 14720, 14736,     0,  8192, 12288, 14336, 14848, 
+    14720, 14736, 14740,     0,  8192, 12288, 14336, 14848, 
+    14720, 14736, 14740,     0,  8192, 12288, 14336, 14848, 
+    14720, 14736, 14744, 14742,     0,  8192, 12288, 14336, 
+    14848, 14720, 14736,     0,  8192, 12288, 14336, 14848, 
+    14720, 14752, 14744,     0,  8192, 12288, 14336, 14848, 
+    14720, 14752, 14744,     0,  8192, 12288, 14336, 14848, 
+    14720, 14752, 14744, 14746,     0,  8192, 12288, 14336, 
+    14848, 14720, 14752, 14744,     0,  8192, 12288, 14336, 
+    14848, 14720, 14752, 14753, 14748,     0,  8192, 12288, 
+    14336, 14848, 14720, 14752, 14753, 14748,     0,  8192, 
+    12288, 14336, 14848, 14720, 14752, 14753, 14748, 14750, 
+        0,  8192, 12288, 14336, 14848, 14720,     0,  8192, 
+    12288, 14336, 14848, 14720, 14752,     0,  8192, 12288, 
+    14336, 14848, 14720, 14752,     0,  8192, 12288, 14336, 
+    14848, 14720, 14752, 14754,     0,  8192, 12288, 14336, 
+    14848, 14720, 14752,     0,  8192, 12288, 14336, 14848, 
+    14720, 14752, 14756,     0,  8192, 12288, 14336, 14848, 
+    14720, 14752, 14756,     0,  8192, 12288, 14336, 14848, 
+    14720, 14752, 14760, 14758,     0,  8192, 12288, 14336, 
+    14848, 14720, 14752,     0,  8192, 12288, 14336, 14848, 
+    14720, 14752, 14760,     0,  8192, 12288, 14336, 14848, 
+    14720, 14752, 14760,     0,  8192, 12288, 14336, 14848, 
+    14720, 14752, 14760, 14762,     0,  8192, 12288, 14336, 
+    14848, 14720, 14752, 14760,     0,  8192, 12288, 14336, 
+    14848, 14720, 14752, 14768, 14764,     0,  8192, 12288, 
+    14336, 14848, 14720, 14752, 14768, 14764,     0,  8192, 
+    12288, 14336, 14848, 14720, 14752, 14768, 14769, 14766, 
+        0,  8192, 12288, 14336, 14848, 14720, 14752,     0, 
+     8192, 12288, 14336, 14848, 14720, 14784, 14768,     0, 
+     8192, 12288, 14336, 14848, 14720, 14784, 14768,     0, 
+     8192, 12288, 14336, 14848, 14720, 14784, 14768, 14770, 
+        0,  8192, 12288, 14336, 14848, 14720, 14784, 14768, 
+        0,  8192, 12288, 14336, 14848, 14720, 14784, 14768, 
+    14772,     0,  8192, 12288, 14336, 14848, 14720, 14784, 
+    14768, 14772,     0,  8192, 12288, 14336, 14848, 14720, 
+    14784, 14768, 14776, 14774,     0,  8192, 12288, 14336, 
+    14848, 14720, 14784, 14768,     0,  8192, 12288, 14336, 
+    14848, 14720, 14784, 14785, 14776,     0,  8192, 12288, 
+    14336, 14848, 14720, 14784, 14785, 14776,     0,  8192, 
+    12288, 14336, 14848, 14720, 14784, 14785, 14776, 14778, 
+        0,  8192, 12288, 14336, 14848, 14720, 14784, 14785, 
+    14776,     0,  8192, 12288, 14336, 14848, 14720, 14784, 
+    14785, 14776, 14780,     0,  8192, 12288, 14336, 14848, 
+    14720, 14784, 14785, 14787, 14780,     0,  8192, 12288, 
+    14336, 14848, 14720, 14784, 14785, 14787, 14780, 14782, 
+        0,  8192, 12288, 14336, 14848, 14720,     0,  8192, 
+    12288, 14336, 14848, 14849, 14784,     0,  8192, 12288, 
+    14336, 14848, 14849, 14784,     0,  8192, 12288, 14336, 
+    14848, 14849, 14784, 14786,     0,  8192, 12288, 14336, 
+    14848, 14849, 14784,     0,  8192, 12288, 14336, 14848, 
+    14849, 14784, 14788,     0,  8192, 12288, 14336, 14848, 
+    14849, 14784, 14788,     0,  8192, 12288, 14336, 14848, 
+    14849, 14784, 14792, 14790,     0,  8192, 12288, 14336, 
+    14848, 14849, 14784,     0,  8192, 12288, 14336, 14848, 
+    14849, 14784, 14792,     0,  8192, 12288, 14336, 14848, 
+    14849, 14784, 14792,     0,  8192, 12288, 14336, 14848, 
+    14849, 14784, 14792, 14794,     0,  8192, 12288, 14336, 
+    14848, 14849, 14784, 14792,     0,  8192, 12288, 14336, 
+    14848, 14849, 14784, 14800, 14796,     0,  8192, 12288, 
+    14336, 14848, 14849, 14784, 14800, 14796,     0,  8192, 
+    12288, 14336, 14848, 14849, 14784, 14800, 14801, 14798, 
+        0,  8192, 12288, 14336, 14848, 14849, 14784,     0, 
+     8192, 12288, 14336, 14848, 14849, 14784, 14800,     0, 
+     8192, 12288, 14336, 14848, 14849, 14784, 14800,     0, 
+     8192, 12288, 14336, 14848, 14849, 14784, 14800, 14802, 
+        0,  8192, 12288, 14336, 14848, 14849, 14784, 14800, 
+        0,  8192, 12288, 14336, 14848, 14849, 14784, 14800, 
+    14804,     0,  8192, 12288, 14336, 14848, 14849, 14784, 
+    14800, 14804,     0,  8192, 12288, 14336, 14848, 14849, 
+    14784, 14800, 14808, 14806,     0,  8192, 12288, 14336, 
+    14848, 14849, 14784, 14800,     0,  8192, 12288, 14336, 
+    14848, 14849, 14784, 14816, 14808,     0,  8192, 12288, 
+    14336, 14848, 14849, 14784, 14816, 14808,     0,  8192, 
+    12288, 14336, 14848, 14849, 14784, 14816, 14808, 14810, 
+        0,  8192, 12288, 14336, 14848, 14849, 14784, 14816, 
+    14808,     0,  8192, 12288, 14336, 14848, 14849, 14784, 
+    14816, 14817, 14812,     0,  8192, 12288, 14336, 14848, 
+    14849, 14784, 14816, 14817, 14812,     0,  8192, 12288, 
+    14336, 14848, 14849, 14784, 14816, 14817, 14812, 14814, 
+        0,  8192, 12288, 14336, 14848, 14849, 14784,     0, 
+     8192, 12288, 14336, 14848, 14849, 14784, 14816,     0, 
+     8192, 12288, 14336, 14848, 14849, 14851, 14816,     0, 
+     8192, 12288, 14336, 14848, 14849, 14851, 14816, 14818, 
+        0,  8192, 12288, 14336, 14848, 14849, 14851, 14816, 
+        0,  8192, 12288, 14336, 14848, 14849, 14851, 14816, 
+    14820,     0,  8192, 12288, 14336, 14848, 14849, 14851, 
+    14816, 14820,     0,  8192, 12288, 14336, 14848, 14849, 
+    14851, 14816, 14824, 14822,     0,  8192, 12288, 14336, 
+    14848, 14849, 14851, 14816,     0,  8192, 12288, 14336, 
+    14848, 14849, 14851, 14816, 14824,     0,  8192, 12288, 
+    14336, 14848, 14849, 14851, 14816, 14824,     0,  8192, 
+    12288, 14336, 14848, 14849, 14851, 14816, 14824, 14826, 
+        0,  8192, 12288, 14336, 14848, 14849, 14851, 14816, 
+    14824,     0,  8192, 12288, 14336, 14848, 14849, 14851, 
+    14816, 14832, 14828,     0,  8192, 12288, 14336, 14848, 
+    14849, 14851, 14816, 14832, 14828,     0,  8192, 12288, 
+    14336, 14848, 14849, 14851, 14816, 14832, 14833, 14830, 
+        0,  8192, 12288, 14336, 14848, 14849, 14851, 14816, 
+        0,  8192, 12288, 14336, 14848, 14849, 14851, 14816, 
+    14832,     0,  8192, 12288, 14336, 14848, 14849, 14851, 
+    14816, 14832,     0,  8192, 12288, 14336, 14848, 14849, 
+    14851, 14816, 14832, 14834,     0,  8192, 12288, 14336, 
+    14848, 14849, 14851, 14855, 14832,     0,  8192, 12288, 
+    14336, 14848, 14849, 14851, 14855, 14832, 14836,     0, 
+     8192, 12288, 14336, 14848, 14849, 14851, 14855, 14832, 
+    14836,     0,  8192, 12288, 14336, 14848, 14849, 14851, 
+    14855, 14832, 14840, 14838,     0,  8192, 12288, 14336, 
+    14848, 14849, 14851, 14855, 14832,     0,  8192, 12288, 
+    14336, 14848, 14849, 14851, 14855, 14832, 14840,     0, 
+     8192, 12288, 14336, 14848, 14849, 14851, 14855, 14832, 
+    14840,     0,  8192, 12288, 14336, 14848, 14849, 14851, 
+    14855, 14832, 14840, 14842,     0,  8192, 12288, 14336, 
+    14848, 14849, 14851, 14855, 14832, 14840,     0,  8192, 
+    12288, 14336, 14848, 14849, 14851, 14855, 14832, 14840, 
+    14844,     0,  8192, 12288, 14336, 14848, 14849, 14851, 
+    14855, 14832, 14840, 14844,     0,  8192, 12288, 14336, 
+    14848, 14849, 14851, 14855, 14832, 14840, 14844, 14846, 
+        0,  8192, 12288, 14336,     0,  8192, 12288, 14336, 
+    14848,     0,  8192, 12288, 14336, 14848,     0,  8192, 
+    12288, 14336, 14848, 14850,     0,  8192, 12288, 14336, 
+    14848,     0,  8192, 12288, 14336, 14848, 14852,     0, 
+     8192, 12288, 14336, 14848, 14852,     0,  8192, 12288, 
+    14336, 14848, 14856, 14854,     0,  8192, 12288, 14336, 
+    14848,     0,  8192, 12288, 14336, 14848, 14856,     0, 
+     8192, 12288, 14336, 14848, 14856,     0,  8192, 12288, 
+    14336, 14848, 14856, 14858,     0,  8192, 12288, 14336, 
+    14848, 14856,     0,  8192, 12288, 14336, 14848, 14864, 
+    14860,     0,  8192, 12288, 14336, 14848, 14864, 14860, 
+        0,  8192, 12288, 14336, 14848, 14864, 14865, 14862, 
+        0,  8192, 12288, 14336, 14848,     0,  8192, 12288, 
+    14336, 14848, 14864,     0,  8192, 12288, 14336, 14848, 
+    14864,     0,  8192, 12288, 14336, 14848, 14864, 14866, 
+        0,  8192, 12288, 14336, 14848, 14864,     0,  8192, 
+    12288, 14336, 14848, 14864, 14868,     0,  8192, 12288, 
+    14336, 14848, 14864, 14868,     0,  8192, 12288, 14336, 
+    14848, 14864, 14872, 14870,     0,  8192, 12288, 14336, 
+    14848, 14864,     0,  8192, 12288, 14336, 14848, 14880, 
+    14872,     0,  8192, 12288, 14336, 14848, 14880, 14872, 
+        0,  8192, 12288, 14336, 14848, 14880, 14872, 14874, 
+        0,  8192, 12288, 14336, 14848, 14880, 14872,     0, 
+     8192, 12288, 14336, 14848, 14880, 14881, 14876,     0, 
+     8192, 12288, 14336, 14848, 14880, 14881, 14876,     0, 
+     8192, 12288, 14336, 14848, 14880, 14881, 14876, 14878, 
+        0,  8192, 12288, 14336, 14848,     0,  8192, 12288, 
+    14336, 14848, 14880,     0,  8192, 12288, 14336, 14848, 
+    14880,     0,  8192, 12288, 14336, 14848, 14880, 14882, 
+        0,  8192, 12288, 14336, 14848, 14880,     0,  8192, 
+    12288, 14336, 14848, 14880, 14884,     0,  8192, 12288, 
+    14336, 14848, 14880, 14884,     0,  8192, 12288, 14336, 
+    14848, 14880, 14888, 14886,     0,  8192, 12288, 14336, 
+    14848, 14880,     0,  8192, 12288, 14336, 14848, 14880, 
+    14888,     0,  8192, 12288, 14336, 14848, 14880, 14888, 
+        0,  8192, 12288, 14336, 14848, 14880, 14888, 14890, 
+        0,  8192, 12288, 14336, 14848, 14880, 14888,     0, 
+     8192, 12288, 14336, 14848, 14880, 14896, 14892,     0, 
+     8192, 12288, 14336, 14848, 14880, 14896, 14892,     0, 
+     8192, 12288, 14336, 14848, 14880, 14896, 14897, 14894, 
+        0,  8192, 12288, 14336, 14848, 14880,     0,  8192, 
+    12288, 14336, 14848, 14912, 14896,     0,  8192, 12288, 
+    14336, 14848, 14912, 14896,     0,  8192, 12288, 14336, 
+    14848, 14912, 14896, 14898,     0,  8192, 12288, 14336, 
+    14848, 14912, 14896,     0,  8192, 12288, 14336, 14848, 
+    14912, 14896, 14900,     0,  8192, 12288, 14336, 14848, 
+    14912, 14896, 14900,     0,  8192, 12288, 14336, 14848, 
+    14912, 14896, 14904, 14902,     0,  8192, 12288, 14336, 
+    14848, 14912, 14896,     0,  8192, 12288, 14336, 14848, 
+    14912, 14913, 14904,     0,  8192, 12288, 14336, 14848, 
+    14912, 14913, 14904,     0,  8192, 12288, 14336, 14848, 
+    14912, 14913, 14904, 14906,     0,  8192, 12288, 14336, 
+    14848, 14912, 14913, 14904,     0,  8192, 12288, 14336, 
+    14848, 14912, 14913, 14904, 14908,     0,  8192, 12288, 
+    14336, 14848, 14912, 14913, 14915, 14908,     0,  8192, 
+    12288, 14336, 14848, 14912, 14913, 14915, 14908, 14910, 
+        0,  8192, 12288, 14336, 14848,     0,  8192, 12288, 
+    14336, 14848, 14912,     0,  8192, 12288, 14336, 14848, 
+    14912,     0,  8192, 12288, 14336, 14848, 14912, 14914, 
+        0,  8192, 12288, 14336, 14848, 14912,     0,  8192, 
+    12288, 14336, 14848, 14912, 14916,     0,  8192, 12288, 
+    14336, 14848, 14912, 14916,     0,  8192, 12288, 14336, 
+    14848, 14912, 14920, 14918,     0,  8192, 12288, 14336, 
+    14848, 14912,     0,  8192, 12288, 14336, 14848, 14912, 
+    14920,     0,  8192, 12288, 14336, 14848, 14912, 14920, 
+        0,  8192, 12288, 14336, 14848, 14912, 14920, 14922, 
+        0,  8192, 12288, 14336, 14848, 14912, 14920,     0, 
+     8192, 12288, 14336, 14848, 14912, 14928, 14924,     0, 
+     8192, 12288, 14336, 14848, 14912, 14928, 14924,     0, 
+     8192, 12288, 14336, 14848, 14912, 14928, 14929, 14926, 
+        0,  8192, 12288, 14336, 14848, 14912,     0,  8192, 
+    12288, 14336, 14848, 14912, 14928,     0,  8192, 12288, 
+    14336, 14848, 14912, 14928,     0,  8192, 12288, 14336, 
+    14848, 14912, 14928, 14930,     0,  8192, 12288, 14336, 
+    14848, 14912, 14928,     0,  8192, 12288, 14336, 14848, 
+    14912, 14928, 14932,     0,  8192, 12288, 14336, 14848, 
+    14912, 14928, 14932,     0,  8192, 12288, 14336, 14848, 
+    14912, 14928, 14936, 14934,     0,  8192, 12288, 14336, 
+    14848, 14912, 14928,     0,  8192, 12288, 14336, 14848, 
+    14912, 14944, 14936,     0,  8192, 12288, 14336, 14848, 
+    14912, 14944, 14936,     0,  8192, 12288, 14336, 14848, 
+    14912, 14944, 14936, 14938,     0,  8192, 12288, 14336, 
+    14848, 14912, 14944, 14936,     0,  8192, 12288, 14336, 
+    14848, 14912, 14944, 14945, 14940,     0,  8192, 12288, 
+    14336, 14848, 14912, 14944, 14945, 14940,     0,  8192, 
+    12288, 14336, 14848, 14912, 14944, 14945, 14940, 14942, 
+        0,  8192, 12288, 14336, 14848, 14912,     0,  8192, 
+    12288, 14336, 14848, 14976, 14944,     0,  8192, 12288, 
+    14336, 14848, 14976, 14944,     0,  8192, 12288, 14336, 
+    14848, 14976, 14944, 14946,     0,  8192, 12288, 14336, 
+    14848, 14976, 14944,     0,  8192, 12288, 14336, 14848, 
+    14976, 14944, 14948,     0,  8192, 12288, 14336, 14848, 
+    14976, 14944, 14948,     0,  8192, 12288, 14336, 14848, 
+    14976, 14944, 14952, 14950,     0,  8192, 12288, 14336, 
+    14848, 14976, 14944,     0,  8192, 12288, 14336, 14848, 
+    14976, 14944, 14952,     0,  8192, 12288, 14336, 14848, 
+    14976, 14944, 14952,     0,  8192, 12288, 14336, 14848, 
+    14976, 14944, 14952, 14954,     0,  8192, 12288, 14336, 
+    14848, 14976, 14944, 14952,     0,  8192, 12288, 14336, 
+    14848, 14976, 14944, 14960, 14956,     0,  8192, 12288, 
+    14336, 14848, 14976, 14944, 14960, 14956,     0,  8192, 
+    12288, 14336, 14848, 14976, 14944, 14960, 14961, 14958, 
+        0,  8192, 12288, 14336, 14848, 14976, 14944,     0, 
+     8192, 12288, 14336, 14848, 14976, 14977, 14960,     0, 
+     8192, 12288, 14336, 14848, 14976, 14977, 14960,     0, 
+     8192, 12288, 14336, 14848, 14976, 14977, 14960, 14962, 
+        0,  8192, 12288, 14336, 14848, 14976, 14977, 14960, 
+        0,  8192, 12288, 14336, 14848, 14976, 14977, 14960, 
+    14964,     0,  8192, 12288, 14336, 14848, 14976, 14977, 
+    14960, 14964,     0,  8192, 12288, 14336, 14848, 14976, 
+    14977, 14960, 14968, 14966,     0,  8192, 12288, 14336, 
+    14848, 14976, 14977, 14960,     0,  8192, 12288, 14336, 
+    14848, 14976, 14977, 14960, 14968,     0,  8192, 12288, 
+    14336, 14848, 14976, 14977, 14979, 14968,     0,  8192, 
+    12288, 14336, 14848, 14976, 14977, 14979, 14968, 14970, 
+        0,  8192, 12288, 14336, 14848, 14976, 14977, 14979, 
+    14968,     0,  8192, 12288, 14336, 14848, 14976, 14977, 
+    14979, 14968, 14972,     0,  8192, 12288, 14336, 14848, 
+    14976, 14977, 14979, 14968, 14972,     0,  8192, 12288, 
+    14336, 14848, 14976, 14977, 14979, 14968, 14972, 14974, 
+        0,  8192, 12288, 14336, 14848,     0,  8192, 12288, 
+    14336, 14848, 14976,     0,  8192, 12288, 14336, 14848, 
+    14976,     0,  8192, 12288, 14336, 14848, 14976, 14978, 
+        0,  8192, 12288, 14336, 14848, 14976,     0,  8192, 
+    12288, 14336, 14848, 14976, 14980,     0,  8192, 12288, 
+    14336, 14848, 14976, 14980,     0,  8192, 12288, 14336, 
+    14848, 14976, 14984, 14982,     0,  8192, 12288, 14336, 
+    14848, 14976,     0,  8192, 12288, 14336, 14848, 14976, 
+    14984,     0,  8192, 12288, 14336, 14848, 14976, 14984, 
+        0,  8192, 12288, 14336, 14848, 14976, 14984, 14986, 
+        0,  8192, 12288, 14336, 14848, 14976, 14984,     0, 
+     8192, 12288, 14336, 14848, 14976, 14992, 14988,     0, 
+     8192, 12288, 14336, 14848, 14976, 14992, 14988,     0, 
+     8192, 12288, 14336, 14848, 14976, 14992, 14993, 14990, 
+        0,  8192, 12288, 14336, 14848, 14976,     0,  8192, 
+    12288, 14336, 14848, 14976, 14992,     0,  8192, 12288, 
+    14336, 14848, 14976, 14992,     0,  8192, 12288, 14336, 
+    14848, 14976, 14992, 14994,     0,  8192, 12288, 14336, 
+    14848, 14976, 14992,     0,  8192, 12288, 14336, 14848, 
+    14976, 14992, 14996,     0,  8192, 12288, 14336, 14848, 
+    14976, 14992, 14996,     0,  8192, 12288, 14336, 14848, 
+    14976, 14992, 15000, 14998,     0,  8192, 12288, 14336, 
+    14848, 14976, 14992,     0,  8192, 12288, 14336, 14848, 
+    14976, 15008, 15000,     0,  8192, 12288, 14336, 14848, 
+    14976, 15008, 15000,     0,  8192, 12288, 14336, 14848, 
+    14976, 15008, 15000, 15002,     0,  8192, 12288, 14336, 
+    14848, 14976, 15008, 15000,     0,  8192, 12288, 14336, 
+    14848, 14976, 15008, 15009, 15004,     0,  8192, 12288, 
+    14336, 14848, 14976, 15008, 15009, 15004,     0,  8192, 
+    12288, 14336, 14848, 14976, 15008, 15009, 15004, 15006, 
+        0,  8192, 12288, 14336, 14848, 14976,     0,  8192, 
+    12288, 14336, 14848, 14976, 15008,     0,  8192, 12288, 
+    14336, 14848, 14976, 15008,     0,  8192, 12288, 14336, 
+    14848, 14976, 15008, 15010,     0,  8192, 12288, 14336, 
+    14848, 14976, 15008,     0,  8192, 12288, 14336, 14848, 
+    14976, 15008, 15012,     0,  8192, 12288, 14336, 14848, 
+    14976, 15008, 15012,     0,  8192, 12288, 14336, 14848, 
+    14976, 15008, 15016, 15014,     0,  8192, 12288, 14336, 
+    14848, 14976, 15008,     0,  8192, 12288, 14336, 14848, 
+    14976, 15008, 15016,     0,  8192, 12288, 14336, 14848, 
+    14976, 15008, 15016,     0,  8192, 12288, 14336, 14848, 
+    14976, 15008, 15016, 15018,     0,  8192, 12288, 14336, 
+    14848, 14976, 15008, 15016,     0,  8192, 12288, 14336, 
+    14848, 14976, 15008, 15024, 15020,     0,  8192, 12288, 
+    14336, 14848, 14976, 15008, 15024, 15020,     0,  8192, 
+    12288, 14336, 14848, 14976, 15008, 15024, 15025, 15022, 
+        0,  8192, 12288, 14336, 14848, 14976, 15008,     0, 
+     8192, 12288, 14336, 14848, 14976, 15040, 15024,     0, 
+     8192, 12288, 14336, 14848, 14976, 15040, 15024,     0, 
+     8192, 12288, 14336, 14848, 14976, 15040, 15024, 15026, 
+        0,  8192, 12288, 14336, 14848, 14976, 15040, 15024, 
+        0,  8192, 12288, 14336, 14848, 14976, 15040, 15024, 
+    15028,     0,  8192, 12288, 14336, 14848, 14976, 15040, 
+    15024, 15028,     0,  8192, 12288, 14336, 14848, 14976, 
+    15040, 15024, 15032, 15030,     0,  8192, 12288, 14336, 
+    14848, 14976, 15040, 15024,     0,  8192, 12288, 14336, 
+    14848, 14976, 15040, 15041, 15032,     0,  8192, 12288, 
+    14336, 14848, 14976, 15040, 15041, 15032,     0,  8192, 
+    12288, 14336, 14848, 14976, 15040, 15041, 15032, 15034, 
+        0,  8192, 12288, 14336, 14848, 14976, 15040, 15041, 
+    15032,     0,  8192, 12288, 14336, 14848, 14976, 15040, 
+    15041, 15032, 15036,     0,  8192, 12288, 14336, 14848, 
+    14976, 15040, 15041, 15043, 15036,     0,  8192, 12288, 
+    14336, 14848, 14976, 15040, 15041, 15043, 15036, 15038, 
+        0,  8192, 12288, 14336, 14848, 14976,     0,  8192, 
+    12288, 14336, 14848, 15104, 15040,     0,  8192, 12288, 
+    14336, 14848, 15104, 15040,     0,  8192, 12288, 14336, 
+    14848, 15104, 15040, 15042,     0,  8192, 12288, 14336, 
+    14848, 15104, 15040,     0,  8192, 12288, 14336, 14848, 
+    15104, 15040, 15044,     0,  8192, 12288, 14336, 14848, 
+    15104, 15040, 15044,     0,  8192, 12288, 14336, 14848, 
+    15104, 15040, 15048, 15046,     0,  8192, 12288, 14336, 
+    14848, 15104, 15040,     0,  8192, 12288, 14336, 14848, 
+    15104, 15040, 15048,     0,  8192, 12288, 14336, 14848, 
+    15104, 15040, 15048,     0,  8192, 12288, 14336, 14848, 
+    15104, 15040, 15048, 15050,     0,  8192, 12288, 14336, 
+    14848, 15104, 15040, 15048,     0,  8192, 12288, 14336, 
+    14848, 15104, 15040, 15056, 15052,     0,  8192, 12288, 
+    14336, 14848, 15104, 15040, 15056, 15052,     0,  8192, 
+    12288, 14336, 14848, 15104, 15040, 15056, 15057, 15054, 
+        0,  8192, 12288, 14336, 14848, 15104, 15040,     0, 
+     8192, 12288, 14336, 14848, 15104, 15040, 15056,     0, 
+     8192, 12288, 14336, 14848, 15104, 15040, 15056,     0, 
+     8192, 12288, 14336, 14848, 15104, 15040, 15056, 15058, 
+        0,  8192, 12288, 14336, 14848, 15104, 15040, 15056, 
+        0,  8192, 12288, 14336, 14848, 15104, 15040, 15056, 
+    15060,     0,  8192, 12288, 14336, 14848, 15104, 15040, 
+    15056, 15060,     0,  8192, 12288, 14336, 14848, 15104, 
+    15040, 15056, 15064, 15062,     0,  8192, 12288, 14336, 
+    14848, 15104, 15040, 15056,     0,  8192, 12288, 14336, 
+    14848, 15104, 15040, 15072, 15064,     0,  8192, 12288, 
+    14336, 14848, 15104, 15040, 15072, 15064,     0,  8192, 
+    12288, 14336, 14848, 15104, 15040, 15072, 15064, 15066, 
+        0,  8192, 12288, 14336, 14848, 15104, 15040, 15072, 
+    15064,     0,  8192, 12288, 14336, 14848, 15104, 15040, 
+    15072, 15073, 15068,     0,  8192, 12288, 14336, 14848, 
+    15104, 15040, 15072, 15073, 15068,     0,  8192, 12288, 
+    14336, 14848, 15104, 15040, 15072, 15073, 15068, 15070, 
+        0,  8192, 12288, 14336, 14848, 15104, 15040,     0, 
+     8192, 12288, 14336, 14848, 15104, 15105, 15072,     0, 
+     8192, 12288, 14336, 14848, 15104, 15105, 15072,     0, 
+     8192, 12288, 14336, 14848, 15104, 15105, 15072, 15074, 
+        0,  8192, 12288, 14336, 14848, 15104, 15105, 15072, 
+        0,  8192, 12288, 14336, 14848, 15104, 15105, 15072, 
+    15076,     0,  8192, 12288, 14336, 14848, 15104, 15105, 
+    15072, 15076,     0,  8192, 12288, 14336, 14848, 15104, 
+    15105, 15072, 15080, 15078,     0,  8192, 12288, 14336, 
+    14848, 15104, 15105, 15072,     0,  8192, 12288, 14336, 
+    14848, 15104, 15105, 15072, 15080,     0,  8192, 12288, 
+    14336, 14848, 15104, 15105, 15072, 15080,     0,  8192, 
+    12288, 14336, 14848, 15104, 15105, 15072, 15080, 15082, 
+        0,  8192, 12288, 14336, 14848, 15104, 15105, 15072, 
+    15080,     0,  8192, 12288, 14336, 14848, 15104, 15105, 
+    15072, 15088, 15084,     0,  8192, 12288, 14336, 14848, 
+    15104, 15105, 15072, 15088, 15084,     0,  8192, 12288, 
+    14336, 14848, 15104, 15105, 15072, 15088, 15089, 15086, 
+        0,  8192, 12288, 14336, 14848, 15104, 15105, 15072, 
+        0,  8192, 12288, 14336, 14848, 15104, 15105, 15072, 
+    15088,     0,  8192, 12288, 14336, 14848, 15104, 15105, 
+    15107, 15088,     0,  8192, 12288, 14336, 14848, 15104, 
+    15105, 15107, 15088, 15090,     0,  8192, 12288, 14336, 
+    14848, 15104, 15105, 15107, 15088,     0,  8192, 12288, 
+    14336, 14848, 15104, 15105, 15107, 15088, 15092,     0, 
+     8192, 12288, 14336, 14848, 15104, 15105, 15107, 15088, 
+    15092,     0,  8192, 12288, 14336, 14848, 15104, 15105, 
+    15107, 15088, 15096, 15094,     0,  8192, 12288, 14336, 
+    14848, 15104, 15105, 15107, 15088,     0,  8192, 12288, 
+    14336, 14848, 15104, 15105, 15107, 15088, 15096,     0, 
+     8192, 12288, 14336, 14848, 15104, 15105, 15107, 15088, 
+    15096,     0,  8192, 12288, 14336, 14848, 15104, 15105, 
+    15107, 15088, 15096, 15098,     0,  8192, 12288, 14336, 
+    14848, 15104, 15105, 15107, 15111, 15096,     0,  8192, 
+    12288, 14336, 14848, 15104, 15105, 15107, 15111, 15096, 
+    15100,     0,  8192, 12288, 14336, 14848, 15104, 15105, 
+    15107, 15111, 15096, 15100,     0,  8192, 12288, 14336, 
+    14848, 15104, 15105, 15107, 15111, 15096, 15100, 15102, 
+        0,  8192, 12288, 14336, 14848,     0,  8192, 12288, 
+    14336, 15360, 15104,     0,  8192, 12288, 14336, 15360, 
+    15104,     0,  8192, 12288, 14336, 15360, 15104, 15106, 
+        0,  8192, 12288, 14336, 15360, 15104,     0,  8192, 
+    12288, 14336, 15360, 15104, 15108,     0,  8192, 12288, 
+    14336, 15360, 15104, 15108,     0,  8192, 12288, 14336, 
+    15360, 15104, 15112, 15110,     0,  8192, 12288, 14336, 
+    15360, 15104,     0,  8192, 12288, 14336, 15360, 15104, 
+    15112,     0,  8192, 12288, 14336, 15360, 15104, 15112, 
+        0,  8192, 12288, 14336, 15360, 15104, 15112, 15114, 
+        0,  8192, 12288, 14336, 15360, 15104, 15112,     0, 
+     8192, 12288, 14336, 15360, 15104, 15120, 15116,     0, 
+     8192, 12288, 14336, 15360, 15104, 15120, 15116,     0, 
+     8192, 12288, 14336, 15360, 15104, 15120, 15121, 15118, 
+        0,  8192, 12288, 14336, 15360, 15104,     0,  8192, 
+    12288, 14336, 15360, 15104, 15120,     0,  8192, 12288, 
+    14336, 15360, 15104, 15120,     0,  8192, 12288, 14336, 
+    15360, 15104, 15120, 15122,     0,  8192, 12288, 14336, 
+    15360, 15104, 15120,     0,  8192, 12288, 14336, 15360, 
+    15104, 15120, 15124,     0,  8192, 12288, 14336, 15360, 
+    15104, 15120, 15124,     0,  8192, 12288, 14336, 15360, 
+    15104, 15120, 15128, 15126,     0,  8192, 12288, 14336, 
+    15360, 15104, 15120,     0,  8192, 12288, 14336, 15360, 
+    15104, 15136, 15128,     0,  8192, 12288, 14336, 15360, 
+    15104, 15136, 15128,     0,  8192, 12288, 14336, 15360, 
+    15104, 15136, 15128, 15130,     0,  8192, 12288, 14336, 
+    15360, 15104, 15136, 15128,     0,  8192, 12288, 14336, 
+    15360, 15104, 15136, 15137, 15132,     0,  8192, 12288, 
+    14336, 15360, 15104, 15136, 15137, 15132,     0,  8192, 
+    12288, 14336, 15360, 15104, 15136, 15137, 15132, 15134, 
+        0,  8192, 12288, 14336, 15360, 15104,     0,  8192, 
+    12288, 14336, 15360, 15104, 15136,     0,  8192, 12288, 
+    14336, 15360, 15104, 15136,     0,  8192, 12288, 14336, 
+    15360, 15104, 15136, 15138,     0,  8192, 12288, 14336, 
+    15360, 15104, 15136,     0,  8192, 12288, 14336, 15360, 
+    15104, 15136, 15140,     0,  8192, 12288, 14336, 15360, 
+    15104, 15136, 15140,     0,  8192, 12288, 14336, 15360, 
+    15104, 15136, 15144, 15142,     0,  8192, 12288, 14336, 
+    15360, 15104, 15136,     0,  8192, 12288, 14336, 15360, 
+    15104, 15136, 15144,     0,  8192, 12288, 14336, 15360, 
+    15104, 15136, 15144,     0,  8192, 12288, 14336, 15360, 
+    15104, 15136, 15144, 15146,     0,  8192, 12288, 14336, 
+    15360, 15104, 15136, 15144,     0,  8192, 12288, 14336, 
+    15360, 15104, 15136, 15152, 15148,     0,  8192, 12288, 
+    14336, 15360, 15104, 15136, 15152, 15148,     0,  8192, 
+    12288, 14336, 15360, 15104, 15136, 15152, 15153, 15150, 
+        0,  8192, 12288, 14336, 15360, 15104, 15136,     0, 
+     8192, 12288, 14336, 15360, 15104, 15168, 15152,     0, 
+     8192, 12288, 14336, 15360, 15104, 15168, 15152,     0, 
+     8192, 12288, 14336, 15360, 15104, 15168, 15152, 15154, 
+        0,  8192, 12288, 14336, 15360, 15104, 15168, 15152, 
+        0,  8192, 12288, 14336, 15360, 15104, 15168, 15152, 
+    15156,     0,  8192, 12288, 14336, 15360, 15104, 15168, 
+    15152, 15156,     0,  8192, 12288, 14336, 15360, 15104, 
+    15168, 15152, 15160, 15158,     0,  8192, 12288, 14336, 
+    15360, 15104, 15168, 15152,     0,  8192, 12288, 14336, 
+    15360, 15104, 15168, 15169, 15160,     0,  8192, 12288, 
+    14336, 15360, 15104, 15168, 15169, 15160,     0,  8192, 
+    12288, 14336, 15360, 15104, 15168, 15169, 15160, 15162, 
+        0,  8192, 12288, 14336, 15360, 15104, 15168, 15169, 
+    15160,     0,  8192, 12288, 14336, 15360, 15104, 15168, 
+    15169, 15160, 15164,     0,  8192, 12288, 14336, 15360, 
+    15104, 15168, 15169, 15171, 15164,     0,  8192, 12288, 
+    14336, 15360, 15104, 15168, 15169, 15171, 15164, 15166, 
+        0,  8192, 12288, 14336, 15360, 15104,     0,  8192, 
+    12288, 14336, 15360, 15104, 15168,     0,  8192, 12288, 
+    14336, 15360, 15104, 15168,     0,  8192, 12288, 14336, 
+    15360, 15104, 15168, 15170,     0,  8192, 12288, 14336, 
+    15360, 15104, 15168,     0,  8192, 12288, 14336, 15360, 
+    15104, 15168, 15172,     0,  8192, 12288, 14336, 15360, 
+    15104, 15168, 15172,     0,  8192, 12288, 14336, 15360, 
+    15104, 15168, 15176, 15174,     0,  8192, 12288, 14336, 
+    15360, 15104, 15168,     0,  8192, 12288, 14336, 15360, 
+    15104, 15168, 15176,     0,  8192, 12288, 14336, 15360, 
+    15104, 15168, 15176,     0,  8192, 12288, 14336, 15360, 
+    15104, 15168, 15176, 15178,     0,  8192, 12288, 14336, 
+    15360, 15104, 15168, 15176,     0,  8192, 12288, 14336, 
+    15360, 15104, 15168, 15184, 15180,     0,  8192, 12288, 
+    14336, 15360, 15104, 15168, 15184, 15180,     0,  8192, 
+    12288, 14336, 15360, 15104, 15168, 15184, 15185, 15182, 
+        0,  8192, 12288, 14336, 15360, 15104, 15168,     0, 
+     8192, 12288, 14336, 15360, 15104, 15168, 15184,     0, 
+     8192, 12288, 14336, 15360, 15104, 15168, 15184,     0, 
+     8192, 12288, 14336, 15360, 15104, 15168, 15184, 15186, 
+        0,  8192, 12288, 14336, 15360, 15104, 15168, 15184, 
+        0,  8192, 12288, 14336, 15360, 15104, 15168, 15184, 
+    15188,     0,  8192, 12288, 14336, 15360, 15104, 15168, 
+    15184, 15188,     0,  8192, 12288, 14336, 15360, 15104, 
+    15168, 15184, 15192, 15190,     0,  8192, 12288, 14336, 
+    15360, 15104, 15168, 15184,     0,  8192, 12288, 14336, 
+    15360, 15104, 15168, 15200, 15192,     0,  8192, 12288, 
+    14336, 15360, 15104, 15168, 15200, 15192,     0,  8192, 
+    12288, 14336, 15360, 15104, 15168, 15200, 15192, 15194, 
+        0,  8192, 12288, 14336, 15360, 15104, 15168, 15200, 
+    15192,     0,  8192, 12288, 14336, 15360, 15104, 15168, 
+    15200, 15201, 15196,     0,  8192, 12288, 14336, 15360, 
+    15104, 15168, 15200, 15201, 15196,     0,  8192, 12288, 
+    14336, 15360, 15104, 15168, 15200, 15201, 15196, 15198, 
+        0,  8192, 12288, 14336, 15360, 15104, 15168,     0, 
+     8192, 12288, 14336, 15360, 15104, 15232, 15200,     0, 
+     8192, 12288, 14336, 15360, 15104, 15232, 15200,     0, 
+     8192, 12288, 14336, 15360, 15104, 15232, 15200, 15202, 
+        0,  8192, 12288, 14336, 15360, 15104, 15232, 15200, 
+        0,  8192, 12288, 14336, 15360, 15104, 15232, 15200, 
+    15204,     0,  8192, 12288, 14336, 15360, 15104, 15232, 
+    15200, 15204,     0,  8192, 12288, 14336, 15360, 15104, 
+    15232, 15200, 15208, 15206,     0,  8192, 12288, 14336, 
+    15360, 15104, 15232, 15200,     0,  8192, 12288, 14336, 
+    15360, 15104, 15232, 15200, 15208,     0,  8192, 12288, 
+    14336, 15360, 15104, 15232, 15200, 15208,     0,  8192, 
+    12288, 14336, 15360, 15104, 15232, 15200, 15208, 15210, 
+        0,  8192, 12288, 14336, 15360, 15104, 15232, 15200, 
+    15208,     0,  8192, 12288, 14336, 15360, 15104, 15232, 
+    15200, 15216, 15212,     0,  8192, 12288, 14336, 15360, 
+    15104, 15232, 15200, 15216, 15212,     0,  8192, 12288, 
+    14336, 15360, 15104, 15232, 15200, 15216, 15217, 15214, 
+        0,  8192, 12288, 14336, 15360, 15104, 15232, 15200, 
+        0,  8192, 12288, 14336, 15360, 15104, 15232, 15233, 
+    15216,     0,  8192, 12288, 14336, 15360, 15104, 15232, 
+    15233, 15216,     0,  8192, 12288, 14336, 15360, 15104, 
+    15232, 15233, 15216, 15218,     0,  8192, 12288, 14336, 
+    15360, 15104, 15232, 15233, 15216,     0,  8192, 12288, 
+    14336, 15360, 15104, 15232, 15233, 15216, 15220,     0, 
+     8192, 12288, 14336, 15360, 15104, 15232, 15233, 15216, 
+    15220,     0,  8192, 12288, 14336, 15360, 15104, 15232, 
+    15233, 15216, 15224, 15222,     0,  8192, 12288, 14336, 
+    15360, 15104, 15232, 15233, 15216,     0,  8192, 12288, 
+    14336, 15360, 15104, 15232, 15233, 15216, 15224,     0, 
+     8192, 12288, 14336, 15360, 15104, 15232, 15233, 15235, 
+    15224,     0,  8192, 12288, 14336, 15360, 15104, 15232, 
+    15233, 15235, 15224, 15226,     0,  8192, 12288, 14336, 
+    15360, 15104, 15232, 15233, 15235, 15224,     0,  8192, 
+    12288, 14336, 15360, 15104, 15232, 15233, 15235, 15224, 
+    15228,     0,  8192, 12288, 14336, 15360, 15104, 15232, 
+    15233, 15235, 15224, 15228,     0,  8192, 12288, 14336, 
+    15360, 15104, 15232, 15233, 15235, 15224, 15228, 15230, 
+        0,  8192, 12288, 14336, 15360, 15104,     0,  8192, 
+    12288, 14336, 15360, 15104, 15232,     0,  8192, 12288, 
+    14336, 15360, 15361, 15232,     0,  8192, 12288, 14336, 
+    15360, 15361, 15232, 15234,     0,  8192, 12288, 14336, 
+    15360, 15361, 15232,     0,  8192, 12288, 14336, 15360, 
+    15361, 15232, 15236,     0,  8192, 12288, 14336, 15360, 
+    15361, 15232, 15236,     0,  8192, 12288, 14336, 15360, 
+    15361, 15232, 15240, 15238,     0,  8192, 12288, 14336, 
+    15360, 15361, 15232,     0,  8192, 12288, 14336, 15360, 
+    15361, 15232, 15240,     0,  8192, 12288, 14336, 15360, 
+    15361, 15232, 15240,     0,  8192, 12288, 14336, 15360, 
+    15361, 15232, 15240, 15242,     0,  8192, 12288, 14336, 
+    15360, 15361, 15232, 15240,     0,  8192, 12288, 14336, 
+    15360, 15361, 15232, 15248, 15244,     0,  8192, 12288, 
+    14336, 15360, 15361, 15232, 15248, 15244,     0,  8192, 
+    12288, 14336, 15360, 15361, 15232, 15248, 15249, 15246, 
+        0,  8192, 12288, 14336, 15360, 15361, 15232,     0, 
+     8192, 12288, 14336, 15360, 15361, 15232, 15248,     0, 
+     8192, 12288, 14336, 15360, 15361, 15232, 15248,     0, 
+     8192, 12288, 14336, 15360, 15361, 15232, 15248, 15250, 
+        0,  8192, 12288, 14336, 15360, 15361, 15232, 15248, 
+        0,  8192, 12288, 14336, 15360, 15361, 15232, 15248, 
+    15252,     0,  8192, 12288, 14336, 15360, 15361, 15232, 
+    15248, 15252,     0,  8192, 12288, 14336, 15360, 15361, 
+    15232, 15248, 15256, 15254,     0,  8192, 12288, 14336, 
+    15360, 15361, 15232, 15248,     0,  8192, 12288, 14336, 
+    15360, 15361, 15232, 15264, 15256,     0,  8192, 12288, 
+    14336, 15360, 15361, 15232, 15264, 15256,     0,  8192, 
+    12288, 14336, 15360, 15361, 15232, 15264, 15256, 15258, 
+        0,  8192, 12288, 14336, 15360, 15361, 15232, 15264, 
+    15256,     0,  8192, 12288, 14336, 15360, 15361, 15232, 
+    15264, 15265, 15260,     0,  8192, 12288, 14336, 15360, 
+    15361, 15232, 15264, 15265, 15260,     0,  8192, 12288, 
+    14336, 15360, 15361, 15232, 15264, 15265, 15260, 15262, 
+        0,  8192, 12288, 14336, 15360, 15361, 15232,     0, 
+     8192, 12288, 14336, 15360, 15361, 15232, 15264,     0, 
+     8192, 12288, 14336, 15360, 15361, 15232, 15264,     0, 
+     8192, 12288, 14336, 15360, 15361, 15232, 15264, 15266, 
+        0,  8192, 12288, 14336, 15360, 15361, 15232, 15264, 
+        0,  8192, 12288, 14336, 15360, 15361, 15232, 15264, 
+    15268,     0,  8192, 12288, 14336, 15360, 15361, 15232, 
+    15264, 15268,     0,  8192, 12288, 14336, 15360, 15361, 
+    15232, 15264, 15272, 15270,     0,  8192, 12288, 14336, 
+    15360, 15361, 15232, 15264,     0,  8192, 12288, 14336, 
+    15360, 15361, 15232, 15264, 15272,     0,  8192, 12288, 
+    14336, 15360, 15361, 15232, 15264, 15272,     0,  8192, 
+    12288, 14336, 15360, 15361, 15232, 15264, 15272, 15274, 
+        0,  8192, 12288, 14336, 15360, 15361, 15232, 15264, 
+    15272,     0,  8192, 12288, 14336, 15360, 15361, 15232, 
+    15264, 15280, 15276,     0,  8192, 12288, 14336, 15360, 
+    15361, 15232, 15264, 15280, 15276,     0,  8192, 12288, 
+    14336, 15360, 15361, 15232, 15264, 15280, 15281, 15278, 
+        0,  8192, 12288, 14336, 15360, 15361, 15232, 15264, 
+        0,  8192, 12288, 14336, 15360, 15361, 15232, 15296, 
+    15280,     0,  8192, 12288, 14336, 15360, 15361, 15232, 
+    15296, 15280,     0,  8192, 12288, 14336, 15360, 15361, 
+    15232, 15296, 15280, 15282,     0,  8192, 12288, 14336, 
+    15360, 15361, 15232, 15296, 15280,     0,  8192, 12288, 
+    14336, 15360, 15361, 15232, 15296, 15280, 15284,     0, 
+     8192, 12288, 14336, 15360, 15361, 15232, 15296, 15280, 
+    15284,     0,  8192, 12288, 14336, 15360, 15361, 15232, 
+    15296, 15280, 15288, 15286,     0,  8192, 12288, 14336, 
+    15360, 15361, 15232, 15296, 15280,     0,  8192, 12288, 
+    14336, 15360, 15361, 15232, 15296, 15297, 15288,     0, 
+     8192, 12288, 14336, 15360, 15361, 15232, 15296, 15297, 
+    15288,     0,  8192, 12288, 14336, 15360, 15361, 15232, 
+    15296, 15297, 15288, 15290,     0,  8192, 12288, 14336, 
+    15360, 15361, 15232, 15296, 15297, 15288,     0,  8192, 
+    12288, 14336, 15360, 15361, 15232, 15296, 15297, 15288, 
+    15292,     0,  8192, 12288, 14336, 15360, 15361, 15232, 
+    15296, 15297, 15299, 15292,     0,  8192, 12288, 14336, 
+    15360, 15361, 15232, 15296, 15297, 15299, 15292, 15294, 
+        0,  8192, 12288, 14336, 15360, 15361, 15232,     0, 
+     8192, 12288, 14336, 15360, 15361, 15232, 15296,     0, 
+     8192, 12288, 14336, 15360, 15361, 15232, 15296,     0, 
+     8192, 12288, 14336, 15360, 15361, 15232, 15296, 15298, 
+        0,  8192, 12288, 14336, 15360, 15361, 15363, 15296, 
+        0,  8192, 12288, 14336, 15360, 15361, 15363, 15296, 
+    15300,     0,  8192, 12288, 14336, 15360, 15361, 15363, 
+    15296, 15300,     0,  8192, 12288, 14336, 15360, 15361, 
+    15363, 15296, 15304, 15302,     0,  8192, 12288, 14336, 
+    15360, 15361, 15363, 15296,     0,  8192, 12288, 14336, 
+    15360, 15361, 15363, 15296, 15304,     0,  8192, 12288, 
+    14336, 15360, 15361, 15363, 15296, 15304,     0,  8192, 
+    12288, 14336, 15360, 15361, 15363, 15296, 15304, 15306, 
+        0,  8192, 12288, 14336, 15360, 15361, 15363, 15296, 
+    15304,     0,  8192, 12288, 14336, 15360, 15361, 15363, 
+    15296, 15312, 15308,     0,  8192, 12288, 14336, 15360, 
+    15361, 15363, 15296, 15312, 15308,     0,  8192, 12288, 
+    14336, 15360, 15361, 15363, 15296, 15312, 15313, 15310, 
+        0,  8192, 12288, 14336, 15360, 15361, 15363, 15296, 
+        0,  8192, 12288, 14336, 15360, 15361, 15363, 15296, 
+    15312,     0,  8192, 12288, 14336, 15360, 15361, 15363, 
+    15296, 15312,     0,  8192, 12288, 14336, 15360, 15361, 
+    15363, 15296, 15312, 15314,     0,  8192, 12288, 14336, 
+    15360, 15361, 15363, 15296, 15312,     0,  8192, 12288, 
+    14336, 15360, 15361, 15363, 15296, 15312, 15316,     0, 
+     8192, 12288, 14336, 15360, 15361, 15363, 15296, 15312, 
+    15316,     0,  8192, 12288, 14336, 15360, 15361, 15363, 
+    15296, 15312, 15320, 15318,     0,  8192, 12288, 14336, 
+    15360, 15361, 15363, 15296, 15312,     0,  8192, 12288, 
+    14336, 15360, 15361, 15363, 15296, 15328, 15320,     0, 
+     8192, 12288, 14336, 15360, 15361, 15363, 15296, 15328, 
+    15320,     0,  8192, 12288, 14336, 15360, 15361, 15363, 
+    15296, 15328, 15320, 15322,     0,  8192, 12288, 14336, 
+    15360, 15361, 15363, 15296, 15328, 15320,     0,  8192, 
+    12288, 14336, 15360, 15361, 15363, 15296, 15328, 15329, 
+    15324,     0,  8192, 12288, 14336, 15360, 15361, 15363, 
+    15296, 15328, 15329, 15324,     0,  8192, 12288, 14336, 
+    15360, 15361, 15363, 15296, 15328, 15329, 15324, 15326, 
+        0,  8192, 12288, 14336, 15360, 15361, 15363, 15296, 
+        0,  8192, 12288, 14336, 15360, 15361, 15363, 15296, 
+    15328,     0,  8192, 12288, 14336, 15360, 15361, 15363, 
+    15296, 15328,     0,  8192, 12288, 14336, 15360, 15361, 
+    15363, 15296, 15328, 15330,     0,  8192, 12288, 14336, 
+    15360, 15361, 15363, 15296, 15328,     0,  8192, 12288, 
+    14336, 15360, 15361, 15363, 15296, 15328, 15332,     0, 
+     8192, 12288, 14336, 15360, 15361, 15363, 15296, 15328, 
+    15332,     0,  8192, 12288, 14336, 15360, 15361, 15363, 
+    15296, 15328, 15336, 15334,     0,  8192, 12288, 14336, 
+    15360, 15361, 15363, 15367, 15328,     0,  8192, 12288, 
+    14336, 15360, 15361, 15363, 15367, 15328, 15336,     0, 
+     8192, 12288, 14336, 15360, 15361, 15363, 15367, 15328, 
+    15336,     0,  8192, 12288, 14336, 15360, 15361, 15363, 
+    15367, 15328, 15336, 15338,     0,  8192, 12288, 14336, 
+    15360, 15361, 15363, 15367, 15328, 15336,     0,  8192, 
+    12288, 14336, 15360, 15361, 15363, 15367, 15328, 15344, 
+    15340,     0,  8192, 12288, 14336, 15360, 15361, 15363, 
+    15367, 15328, 15344, 15340,     0,  8192, 12288, 14336, 
+    15360, 15361, 15363, 15367, 15328, 15344, 15345, 15342, 
+        0,  8192, 12288, 14336, 15360, 15361, 15363, 15367, 
+    15328,     0,  8192, 12288, 14336, 15360, 15361, 15363, 
+    15367, 15328, 15344,     0,  8192, 12288, 14336, 15360, 
+    15361, 15363, 15367, 15328, 15344,     0,  8192, 12288, 
+    14336, 15360, 15361, 15363, 15367, 15328, 15344, 15346, 
+        0,  8192, 12288, 14336, 15360, 15361, 15363, 15367, 
+    15328, 15344,     0,  8192, 12288, 14336, 15360, 15361, 
+    15363, 15367, 15328, 15344, 15348,     0,  8192, 12288, 
+    14336, 15360, 15361, 15363, 15367, 15328, 15344, 15348, 
+        0,  8192, 12288, 14336, 15360, 15361, 15363, 15367, 
+    15328, 15344, 15352, 15350,     0,  8192, 12288, 14336, 
+    15360, 15361, 15363, 15367, 15328, 15344,     0,  8192, 
+    12288, 14336, 15360, 15361, 15363, 15367, 15328, 15344, 
+    15352,     0,  8192, 12288, 14336, 15360, 15361, 15363, 
+    15367, 15328, 15344, 15352,     0,  8192, 12288, 14336, 
+    15360, 15361, 15363, 15367, 15328, 15344, 15352, 15354, 
+        0,  8192, 12288, 14336, 15360, 15361, 15363, 15367, 
+    15328, 15344, 15352,     0,  8192, 12288, 14336, 15360, 
+    15361, 15363, 15367, 15328, 15344, 15352, 15356,     0, 
+     8192, 12288, 14336, 15360, 15361, 15363, 15367, 15328, 
+    15344, 15352, 15356,     0,  8192, 12288, 14336, 15360, 
+    15361, 15363, 15367, 15328, 15344, 15352, 15356, 15358, 
+        0,  8192, 12288, 14336,     0,  8192, 12288, 14336, 
+    15360,     0,  8192, 12288, 14336, 15360,     0,  8192, 
+    12288, 14336, 15360, 15362,     0,  8192, 12288, 14336, 
+    15360,     0, 16384, 12288, 14336, 15360, 15364,     0, 
+    16384, 12288, 14336, 15360, 15364,     0, 16384, 12288, 
+    14336, 15360, 15368, 15366,     0, 16384, 12288, 14336, 
+    15360,     0, 16384, 12288, 14336, 15360, 15368,     0, 
+    16384, 12288, 14336, 15360, 15368,     0, 16384, 12288, 
+    14336, 15360, 15368, 15370,     0, 16384, 12288, 14336, 
+    15360, 15368,     0, 16384, 12288, 14336, 15360, 15376, 
+    15372,     0, 16384, 12288, 14336, 15360, 15376, 15372, 
+        0, 16384, 12288, 14336, 15360, 15376, 15377, 15374, 
+        0, 16384, 12288, 14336, 15360,     0, 16384, 12288, 
+    14336, 15360, 15376,     0, 16384, 12288, 14336, 15360, 
+    15376,     0, 16384, 12288, 14336, 15360, 15376, 15378, 
+        0, 16384, 12288, 14336, 15360, 15376,     0, 16384, 
+    12288, 14336, 15360, 15376, 15380,     0, 16384, 12288, 
+    14336, 15360, 15376, 15380,     0, 16384, 12288, 14336, 
+    15360, 15376, 15384, 15382,     0, 16384, 12288, 14336, 
+    15360, 15376,     0, 16384, 12288, 14336, 15360, 15392, 
+    15384,     0, 16384, 12288, 14336, 15360, 15392, 15384, 
+        0, 16384, 12288, 14336, 15360, 15392, 15384, 15386, 
+        0, 16384, 12288, 14336, 15360, 15392, 15384,     0, 
+    16384, 12288, 14336, 15360, 15392, 15393, 15388,     0, 
+    16384, 12288, 14336, 15360, 15392, 15393, 15388,     0, 
+    16384, 12288, 14336, 15360, 15392, 15393, 15388, 15390, 
+        0, 16384, 12288, 14336, 15360,     0, 16384, 12288, 
+    14336, 15360, 15392,     0, 16384, 12288, 14336, 15360, 
+    15392,     0, 16384, 12288, 14336, 15360, 15392, 15394, 
+        0, 16384, 12288, 14336, 15360, 15392,     0, 16384, 
+    12288, 14336, 15360, 15392, 15396,     0, 16384, 12288, 
+    14336, 15360, 15392, 15396,     0, 16384, 12288, 14336, 
+    15360, 15392, 15400, 15398,     0, 16384, 12288, 14336, 
+    15360, 15392,     0, 16384, 12288, 14336, 15360, 15392, 
+    15400,     0, 16384, 12288, 14336, 15360, 15392, 15400, 
+        0, 16384, 12288, 14336, 15360, 15392, 15400, 15402, 
+        0, 16384, 12288, 14336, 15360, 15392, 15400,     0, 
+    16384, 12288, 14336, 15360, 15392, 15408, 15404,     0, 
+    16384, 12288, 14336, 15360, 15392, 15408, 15404,     0, 
+    16384, 12288, 14336, 15360, 15392, 15408, 15409, 15406, 
+        0, 16384, 12288, 14336, 15360, 15392,     0, 16384, 
+    12288, 14336, 15360, 15424, 15408,     0, 16384, 12288, 
+    14336, 15360, 15424, 15408,     0, 16384, 12288, 14336, 
+    15360, 15424, 15408, 15410,     0, 16384, 12288, 14336, 
+    15360, 15424, 15408,     0, 16384, 12288, 14336, 15360, 
+    15424, 15408, 15412,     0, 16384, 12288, 14336, 15360, 
+    15424, 15408, 15412,     0, 16384, 12288, 14336, 15360, 
+    15424, 15408, 15416, 15414,     0, 16384, 12288, 14336, 
+    15360, 15424, 15408,     0, 16384, 12288, 14336, 15360, 
+    15424, 15425, 15416,     0, 16384, 12288, 14336, 15360, 
+    15424, 15425, 15416,     0, 16384, 12288, 14336, 15360, 
+    15424, 15425, 15416, 15418,     0, 16384, 12288, 14336, 
+    15360, 15424, 15425, 15416,     0, 16384, 12288, 14336, 
+    15360, 15424, 15425, 15416, 15420,     0, 16384, 12288, 
+    14336, 15360, 15424, 15425, 15427, 15420,     0, 16384, 
+    12288, 14336, 15360, 15424, 15425, 15427, 15420, 15422, 
+        0, 16384, 12288, 14336, 15360,     0, 16384, 12288, 
+    14336, 15360, 15424,     0, 16384, 16385, 14336, 15360, 
+    15424,     0, 16384, 16385, 14336, 15360, 15424, 15426, 
+        0, 16384, 16385, 14336, 15360, 15424,     0, 16384, 
+    16385, 14336, 15360, 15424, 15428,     0, 16384, 16385, 
+    14336, 15360, 15424, 15428,     0, 16384, 16385, 14336, 
+    15360, 15424, 15432, 15430,     0, 16384, 16385, 14336, 
+    15360, 15424,     0, 16384, 16385, 14336, 15360, 15424, 
+    15432,     0, 16384, 16385, 14336, 15360, 15424, 15432, 
+        0, 16384, 16385, 14336, 15360, 15424, 15432, 15434, 
+        0, 16384, 16385, 14336, 15360, 15424, 15432,     0, 
+    16384, 16385, 14336, 15360, 15424, 15440, 15436,     0, 
+    16384, 16385, 14336, 15360, 15424, 15440, 15436,     0, 
+    16384, 16385, 14336, 15360, 15424, 15440, 15441, 15438, 
+        0, 16384, 16385, 14336, 15360, 15424,     0, 16384, 
+    16385, 14336, 15360, 15424, 15440,     0, 16384, 16385, 
+    14336, 15360, 15424, 15440,     0, 16384, 16385, 14336, 
+    15360, 15424, 15440, 15442,     0, 16384, 16385, 14336, 
+    15360, 15424, 15440,     0, 16384, 16385, 14336, 15360, 
+    15424, 15440, 15444,     0, 16384, 16385, 14336, 15360, 
+    15424, 15440, 15444,     0, 16384, 16385, 14336, 15360, 
+    15424, 15440, 15448, 15446,     0, 16384, 16385, 14336, 
+    15360, 15424, 15440,     0, 16384, 16385, 14336, 15360, 
+    15424, 15456, 15448,     0, 16384, 16385, 14336, 15360, 
+    15424, 15456, 15448,     0, 16384, 16385, 14336, 15360, 
+    15424, 15456, 15448, 15450,     0, 16384, 16385, 14336, 
+    15360, 15424, 15456, 15448,     0, 16384, 16385, 14336, 
+    15360, 15424, 15456, 15457, 15452,     0, 16384, 16385, 
+    14336, 15360, 15424, 15456, 15457, 15452,     0, 16384, 
+    16385, 14336, 15360, 15424, 15456, 15457, 15452, 15454, 
+        0, 16384, 16385, 14336, 15360, 15424,     0, 16384, 
+    16385, 14336, 15360, 15488, 15456,     0, 16384, 16385, 
+    14336, 15360, 15488, 15456,     0, 16384, 16385, 14336, 
+    15360, 15488, 15456, 15458,     0, 16384, 16385, 14336, 
+    15360, 15488, 15456,     0, 16384, 16385, 14336, 15360, 
+    15488, 15456, 15460,     0, 16384, 16385, 14336, 15360, 
+    15488, 15456, 15460,     0, 16384, 16385, 14336, 15360, 
+    15488, 15456, 15464, 15462,     0, 16384, 16385, 14336, 
+    15360, 15488, 15456,     0, 16384, 16385, 14336, 15360, 
+    15488, 15456, 15464,     0, 16384, 16385, 14336, 15360, 
+    15488, 15456, 15464,     0, 16384, 16385, 14336, 15360, 
+    15488, 15456, 15464, 15466,     0, 16384, 16385, 14336, 
+    15360, 15488, 15456, 15464,     0, 16384, 16385, 14336, 
+    15360, 15488, 15456, 15472, 15468,     0, 16384, 16385, 
+    14336, 15360, 15488, 15456, 15472, 15468,     0, 16384, 
+    16385, 14336, 15360, 15488, 15456, 15472, 15473, 15470, 
+        0, 16384, 16385, 14336, 15360, 15488, 15456,     0, 
+    16384, 16385, 14336, 15360, 15488, 15489, 15472,     0, 
+    16384, 16385, 14336, 15360, 15488, 15489, 15472,     0, 
+    16384, 16385, 14336, 15360, 15488, 15489, 15472, 15474, 
+        0, 16384, 16385, 14336, 15360, 15488, 15489, 15472, 
+        0, 16384, 16385, 14336, 15360, 15488, 15489, 15472, 
+    15476,     0, 16384, 16385, 14336, 15360, 15488, 15489, 
+    15472, 15476,     0, 16384, 16385, 14336, 15360, 15488, 
+    15489, 15472, 15480, 15478,     0, 16384, 16385, 14336, 
+    15360, 15488, 15489, 15472,     0, 16384, 16385, 14336, 
+    15360, 15488, 15489, 15472, 15480,     0, 16384, 16385, 
+    14336, 15360, 15488, 15489, 15491, 15480,     0, 16384, 
+    16385, 14336, 15360, 15488, 15489, 15491, 15480, 15482, 
+        0, 16384, 16385, 14336, 15360, 15488, 15489, 15491, 
+    15480,     0, 16384, 16385, 14336, 15360, 15488, 15489, 
+    15491, 15480, 15484,     0, 16384, 16385, 14336, 15360, 
+    15488, 15489, 15491, 15480, 15484,     0, 16384, 16385, 
+    14336, 15360, 15488, 15489, 15491, 15480, 15484, 15486, 
+        0, 16384, 16385, 14336, 15360,     0, 16384, 16385, 
+    14336, 15360, 15488,     0, 16384, 16385, 14336, 15360, 
+    15488,     0, 16384, 16385, 14336, 15360, 15488, 15490, 
+        0, 16384, 16385, 14336, 15360, 15488,     0, 16384, 
+    16385, 14336, 15360, 15488, 15492,     0, 16384, 16385, 
+    14336, 15360, 15488, 15492,     0, 16384, 16385, 14336, 
+    15360, 15488, 15496, 15494,     0, 16384, 16385, 14336, 
+    15360, 15488,     0, 16384, 16385, 14336, 15360, 15488, 
+    15496,     0, 16384, 16385, 14336, 15360, 15488, 15496, 
+        0, 16384, 16385, 14336, 15360, 15488, 15496, 15498, 
+        0, 16384, 16385, 14336, 15360, 15488, 15496,     0, 
+    16384, 16385, 14336, 15360, 15488, 15504, 15500,     0, 
+    16384, 16385, 14336, 15360, 15488, 15504, 15500,     0, 
+    16384, 16385, 14336, 15360, 15488, 15504, 15505, 15502, 
+        0, 16384, 16385, 14336, 15360, 15488,     0, 16384, 
+    16385, 14336, 15360, 15488, 15504,     0, 16384, 16385, 
+    14336, 15360, 15488, 15504,     0, 16384, 16385, 14336, 
+    15360, 15488, 15504, 15506,     0, 16384, 16385, 14336, 
+    15360, 15488, 15504,     0, 16384, 16385, 14336, 15360, 
+    15488, 15504, 15508,     0, 16384, 16385, 14336, 15360, 
+    15488, 15504, 15508,     0, 16384, 16385, 14336, 15360, 
+    15488, 15504, 15512, 15510,     0, 16384, 16385, 14336, 
+    15360, 15488, 15504,     0, 16384, 16385, 14336, 15360, 
+    15488, 15520, 15512,     0, 16384, 16385, 14336, 15360, 
+    15488, 15520, 15512,     0, 16384, 16385, 14336, 15360, 
+    15488, 15520, 15512, 15514,     0, 16384, 16385, 14336, 
+    15360, 15488, 15520, 15512,     0, 16384, 16385, 14336, 
+    15360, 15488, 15520, 15521, 15516,     0, 16384, 16385, 
+    14336, 15360, 15488, 15520, 15521, 15516,     0, 16384, 
+    16385, 14336, 15360, 15488, 15520, 15521, 15516, 15518, 
+        0, 16384, 16385, 14336, 15360, 15488,     0, 16384, 
+    16385, 14336, 15360, 15488, 15520,     0, 16384, 16385, 
+    14336, 15360, 15488, 15520,     0, 16384, 16385, 14336, 
+    15360, 15488, 15520, 15522,     0, 16384, 16385, 14336, 
+    15360, 15488, 15520,     0, 16384, 16385, 14336, 15360, 
+    15488, 15520, 15524,     0, 16384, 16385, 14336, 15360, 
+    15488, 15520, 15524,     0, 16384, 16385, 14336, 15360, 
+    15488, 15520, 15528, 15526,     0, 16384, 16385, 14336, 
+    15360, 15488, 15520,     0, 16384, 16385, 14336, 15360, 
+    15488, 15520, 15528,     0, 16384, 16385, 14336, 15360, 
+    15488, 15520, 15528,     0, 16384, 16385, 14336, 15360, 
+    15488, 15520, 15528, 15530,     0, 16384, 16385, 14336, 
+    15360, 15488, 15520, 15528,     0, 16384, 16385, 14336, 
+    15360, 15488, 15520, 15536, 15532,     0, 16384, 16385, 
+    14336, 15360, 15488, 15520, 15536, 15532,     0, 16384, 
+    16385, 14336, 15360, 15488, 15520, 15536, 15537, 15534, 
+        0, 16384, 16385, 14336, 15360, 15488, 15520,     0, 
+    16384, 16385, 14336, 15360, 15488, 15552, 15536,     0, 
+    16384, 16385, 14336, 15360, 15488, 15552, 15536,     0, 
+    16384, 16385, 14336, 15360, 15488, 15552, 15536, 15538, 
+        0, 16384, 16385, 14336, 15360, 15488, 15552, 15536, 
+        0, 16384, 16385, 14336, 15360, 15488, 15552, 15536, 
+    15540,     0, 16384, 16385, 14336, 15360, 15488, 15552, 
+    15536, 15540,     0, 16384, 16385, 14336, 15360, 15488, 
+    15552, 15536, 15544, 15542,     0, 16384, 16385, 14336, 
+    15360, 15488, 15552, 15536,     0, 16384, 16385, 14336, 
+    15360, 15488, 15552, 15553, 15544,     0, 16384, 16385, 
+    14336, 15360, 15488, 15552, 15553, 15544,     0, 16384, 
+    16385, 14336, 15360, 15488, 15552, 15553, 15544, 15546, 
+        0, 16384, 16385, 14336, 15360, 15488, 15552, 15553, 
+    15544,     0, 16384, 16385, 14336, 15360, 15488, 15552, 
+    15553, 15544, 15548,     0, 16384, 16385, 14336, 15360, 
+    15488, 15552, 15553, 15555, 15548,     0, 16384, 16385, 
+    14336, 15360, 15488, 15552, 15553, 15555, 15548, 15550, 
+        0, 16384, 16385, 14336, 15360, 15488,     0, 16384, 
+    16385, 14336, 15360, 15616, 15552,     0, 16384, 16385, 
+    14336, 15360, 15616, 15552,     0, 16384, 16385, 14336, 
+    15360, 15616, 15552, 15554,     0, 16384, 16385, 14336, 
+    15360, 15616, 15552,     0, 16384, 16385, 14336, 15360, 
+    15616, 15552, 15556,     0, 16384, 16385, 14336, 15360, 
+    15616, 15552, 15556,     0, 16384, 16385, 14336, 15360, 
+    15616, 15552, 15560, 15558,     0, 16384, 16385, 14336, 
+    15360, 15616, 15552,     0, 16384, 16385, 14336, 15360, 
+    15616, 15552, 15560,     0, 16384, 16385, 14336, 15360, 
+    15616, 15552, 15560,     0, 16384, 16385, 14336, 15360, 
+    15616, 15552, 15560, 15562,     0, 16384, 16385, 14336, 
+    15360, 15616, 15552, 15560,     0, 16384, 16385, 14336, 
+    15360, 15616, 15552, 15568, 15564,     0, 16384, 16385, 
+    14336, 15360, 15616, 15552, 15568, 15564,     0, 16384, 
+    16385, 14336, 15360, 15616, 15552, 15568, 15569, 15566, 
+        0, 16384, 16385, 14336, 15360, 15616, 15552,     0, 
+    16384, 16385, 14336, 15360, 15616, 15552, 15568,     0, 
+    16384, 16385, 14336, 15360, 15616, 15552, 15568,     0, 
+    16384, 16385, 14336, 15360, 15616, 15552, 15568, 15570, 
+        0, 16384, 16385, 14336, 15360, 15616, 15552, 15568, 
+        0, 16384, 16385, 14336, 15360, 15616, 15552, 15568, 
+    15572,     0, 16384, 16385, 14336, 15360, 15616, 15552, 
+    15568, 15572,     0, 16384, 16385, 14336, 15360, 15616, 
+    15552, 15568, 15576, 15574,     0, 16384, 16385, 14336, 
+    15360, 15616, 15552, 15568,     0, 16384, 16385, 14336, 
+    15360, 15616, 15552, 15584, 15576,     0, 16384, 16385, 
+    14336, 15360, 15616, 15552, 15584, 15576,     0, 16384, 
+    16385, 14336, 15360, 15616, 15552, 15584, 15576, 15578, 
+        0, 16384, 16385, 14336, 15360, 15616, 15552, 15584, 
+    15576,     0, 16384, 16385, 14336, 15360, 15616, 15552, 
+    15584, 15585, 15580,     0, 16384, 16385, 14336, 15360, 
+    15616, 15552, 15584, 15585, 15580,     0, 16384, 16385, 
+    14336, 15360, 15616, 15552, 15584, 15585, 15580, 15582, 
+        0, 16384, 16385, 14336, 15360, 15616, 15552,     0, 
+    16384, 16385, 14336, 15360, 15616, 15617, 15584,     0, 
+    16384, 16385, 14336, 15360, 15616, 15617, 15584,     0, 
+    16384, 16385, 14336, 15360, 15616, 15617, 15584, 15586, 
+        0, 16384, 16385, 14336, 15360, 15616, 15617, 15584, 
+        0, 16384, 16385, 14336, 15360, 15616, 15617, 15584, 
+    15588,     0, 16384, 16385, 14336, 15360, 15616, 15617, 
+    15584, 15588,     0, 16384, 16385, 14336, 15360, 15616, 
+    15617, 15584, 15592, 15590,     0, 16384, 16385, 14336, 
+    15360, 15616, 15617, 15584,     0, 16384, 16385, 14336, 
+    15360, 15616, 15617, 15584, 15592,     0, 16384, 16385, 
+    14336, 15360, 15616, 15617, 15584, 15592,     0, 16384, 
+    16385, 14336, 15360, 15616, 15617, 15584, 15592, 15594, 
+        0, 16384, 16385, 14336, 15360, 15616, 15617, 15584, 
+    15592,     0, 16384, 16385, 14336, 15360, 15616, 15617, 
+    15584, 15600, 15596,     0, 16384, 16385, 14336, 15360, 
+    15616, 15617, 15584, 15600, 15596,     0, 16384, 16385, 
+    14336, 15360, 15616, 15617, 15584, 15600, 15601, 15598, 
+        0, 16384, 16385, 14336, 15360, 15616, 15617, 15584, 
+        0, 16384, 16385, 14336, 15360, 15616, 15617, 15584, 
+    15600,     0, 16384, 16385, 14336, 15360, 15616, 15617, 
+    15619, 15600,     0, 16384, 16385, 14336, 15360, 15616, 
+    15617, 15619, 15600, 15602,     0, 16384, 16385, 14336, 
+    15360, 15616, 15617, 15619, 15600,     0, 16384, 16385, 
+    14336, 15360, 15616, 15617, 15619, 15600, 15604,     0, 
+    16384, 16385, 14336, 15360, 15616, 15617, 15619, 15600, 
+    15604,     0, 16384, 16385, 14336, 15360, 15616, 15617, 
+    15619, 15600, 15608, 15606,     0, 16384, 16385, 14336, 
+    15360, 15616, 15617, 15619, 15600,     0, 16384, 16385, 
+    14336, 15360, 15616, 15617, 15619, 15600, 15608,     0, 
+    16384, 16385, 14336, 15360, 15616, 15617, 15619, 15600, 
+    15608,     0, 16384, 16385, 14336, 15360, 15616, 15617, 
+    15619, 15600, 15608, 15610,     0, 16384, 16385, 14336, 
+    15360, 15616, 15617, 15619, 15623, 15608,     0, 16384, 
+    16385, 14336, 15360, 15616, 15617, 15619, 15623, 15608, 
+    15612,     0, 16384, 16385, 14336, 15360, 15616, 15617, 
+    15619, 15623, 15608, 15612,     0, 16384, 16385, 14336, 
+    15360, 15616, 15617, 15619, 15623, 15608, 15612, 15614, 
+        0, 16384, 16385, 14336, 15360,     0, 16384, 16385, 
+    14336, 15360, 15616,     0, 16384, 16385, 14336, 15360, 
+    15616,     0, 16384, 16385, 14336, 15360, 15616, 15618, 
+        0, 16384, 16385, 16387, 15360, 15616,     0, 16384, 
+    16385, 16387, 15360, 15616, 15620,     0, 16384, 16385, 
+    16387, 15360, 15616, 15620,     0, 16384, 16385, 16387, 
+    15360, 15616, 15624, 15622,     0, 16384, 16385, 16387, 
+    15360, 15616,     0, 16384, 16385, 16387, 15360, 15616, 
+    15624,     0, 16384, 16385, 16387, 15360, 15616, 15624, 
+        0, 16384, 16385, 16387, 15360, 15616, 15624, 15626, 
+        0, 16384, 16385, 16387, 15360, 15616, 15624,     0, 
+    16384, 16385, 16387, 15360, 15616, 15632, 15628,     0, 
+    16384, 16385, 16387, 15360, 15616, 15632, 15628,     0, 
+    16384, 16385, 16387, 15360, 15616, 15632, 15633, 15630, 
+        0, 16384, 16385, 16387, 15360, 15616,     0, 16384, 
+    16385, 16387, 15360, 15616, 15632,     0, 16384, 16385, 
+    16387, 15360, 15616, 15632,     0, 16384, 16385, 16387, 
+    15360, 15616, 15632, 15634,     0, 16384, 16385, 16387, 
+    15360, 15616, 15632,     0, 16384, 16385, 16387, 15360, 
+    15616, 15632, 15636,     0, 16384, 16385, 16387, 15360, 
+    15616, 15632, 15636,     0, 16384, 16385, 16387, 15360, 
+    15616, 15632, 15640, 15638,     0, 16384, 16385, 16387, 
+    15360, 15616, 15632,     0, 16384, 16385, 16387, 15360, 
+    15616, 15648, 15640,     0, 16384, 16385, 16387, 15360, 
+    15616, 15648, 15640,     0, 16384, 16385, 16387, 15360, 
+    15616, 15648, 15640, 15642,     0, 16384, 16385, 16387, 
+    15360, 15616, 15648, 15640,     0, 16384, 16385, 16387, 
+    15360, 15616, 15648, 15649, 15644,     0, 16384, 16385, 
+    16387, 15360, 15616, 15648, 15649, 15644,     0, 16384, 
+    16385, 16387, 15360, 15616, 15648, 15649, 15644, 15646, 
+        0, 16384, 16385, 16387, 15360, 15616,     0, 16384, 
+    16385, 16387, 15360, 15616, 15648,     0, 16384, 16385, 
+    16387, 15360, 15616, 15648,     0, 16384, 16385, 16387, 
+    15360, 15616, 15648, 15650,     0, 16384, 16385, 16387, 
+    15360, 15616, 15648,     0, 16384, 16385, 16387, 15360, 
+    15616, 15648, 15652,     0, 16384, 16385, 16387, 15360, 
+    15616, 15648, 15652,     0, 16384, 16385, 16387, 15360, 
+    15616, 15648, 15656, 15654,     0, 16384, 16385, 16387, 
+    15360, 15616, 15648,     0, 16384, 16385, 16387, 15360, 
+    15616, 15648, 15656,     0, 16384, 16385, 16387, 15360, 
+    15616, 15648, 15656,     0, 16384, 16385, 16387, 15360, 
+    15616, 15648, 15656, 15658,     0, 16384, 16385, 16387, 
+    15360, 15616, 15648, 15656,     0, 16384, 16385, 16387, 
+    15360, 15616, 15648, 15664, 15660,     0, 16384, 16385, 
+    16387, 15360, 15616, 15648, 15664, 15660,     0, 16384, 
+    16385, 16387, 15360, 15616, 15648, 15664, 15665, 15662, 
+        0, 16384, 16385, 16387, 15360, 15616, 15648,     0, 
+    16384, 16385, 16387, 15360, 15616, 15680, 15664,     0, 
+    16384, 16385, 16387, 15360, 15616, 15680, 15664,     0, 
+    16384, 16385, 16387, 15360, 15616, 15680, 15664, 15666, 
+        0, 16384, 16385, 16387, 15360, 15616, 15680, 15664, 
+        0, 16384, 16385, 16387, 15360, 15616, 15680, 15664, 
+    15668,     0, 16384, 16385, 16387, 15360, 15616, 15680, 
+    15664, 15668,     0, 16384, 16385, 16387, 15360, 15616, 
+    15680, 15664, 15672, 15670,     0, 16384, 16385, 16387, 
+    15360, 15616, 15680, 15664,     0, 16384, 16385, 16387, 
+    15360, 15616, 15680, 15681, 15672,     0, 16384, 16385, 
+    16387, 15360, 15616, 15680, 15681, 15672,     0, 16384, 
+    16385, 16387, 15360, 15616, 15680, 15681, 15672, 15674, 
+        0, 16384, 16385, 16387, 15360, 15616, 15680, 15681, 
+    15672,     0, 16384, 16385, 16387, 15360, 15616, 15680, 
+    15681, 15672, 15676,     0, 16384, 16385, 16387, 15360, 
+    15616, 15680, 15681, 15683, 15676,     0, 16384, 16385, 
+    16387, 15360, 15616, 15680, 15681, 15683, 15676, 15678, 
+        0, 16384, 16385, 16387, 15360, 15616,     0, 16384, 
+    16385, 16387, 15360, 15616, 15680,     0, 16384, 16385, 
+    16387, 15360, 15616, 15680,     0, 16384, 16385, 16387, 
+    15360, 15616, 15680, 15682,     0, 16384, 16385, 16387, 
+    15360, 15616, 15680,     0, 16384, 16385, 16387, 15360, 
+    15616, 15680, 15684,     0, 16384, 16385, 16387, 15360, 
+    15616, 15680, 15684,     0, 16384, 16385, 16387, 15360, 
+    15616, 15680, 15688, 15686,     0, 16384, 16385, 16387, 
+    15360, 15616, 15680,     0, 16384, 16385, 16387, 15360, 
+    15616, 15680, 15688,     0, 16384, 16385, 16387, 15360, 
+    15616, 15680, 15688,     0, 16384, 16385, 16387, 15360, 
+    15616, 15680, 15688, 15690,     0, 16384, 16385, 16387, 
+    15360, 15616, 15680, 15688,     0, 16384, 16385, 16387, 
+    15360, 15616, 15680, 15696, 15692,     0, 16384, 16385, 
+    16387, 15360, 15616, 15680, 15696, 15692,     0, 16384, 
+    16385, 16387, 15360, 15616, 15680, 15696, 15697, 15694, 
+        0, 16384, 16385, 16387, 15360, 15616, 15680,     0, 
+    16384, 16385, 16387, 15360, 15616, 15680, 15696,     0, 
+    16384, 16385, 16387, 15360, 15616, 15680, 15696,     0, 
+    16384, 16385, 16387, 15360, 15616, 15680, 15696, 15698, 
+        0, 16384, 16385, 16387, 15360, 15616, 15680, 15696, 
+        0, 16384, 16385, 16387, 15360, 15616, 15680, 15696, 
+    15700,     0, 16384, 16385, 16387, 15360, 15616, 15680, 
+    15696, 15700,     0, 16384, 16385, 16387, 15360, 15616, 
+    15680, 15696, 15704, 15702,     0, 16384, 16385, 16387, 
+    15360, 15616, 15680, 15696,     0, 16384, 16385, 16387, 
+    15360, 15616, 15680, 15712, 15704,     0, 16384, 16385, 
+    16387, 15360, 15616, 15680, 15712, 15704,     0, 16384, 
+    16385, 16387, 15360, 15616, 15680, 15712, 15704, 15706, 
+        0, 16384, 16385, 16387, 15360, 15616, 15680, 15712, 
+    15704,     0, 16384, 16385, 16387, 15360, 15616, 15680, 
+    15712, 15713, 15708,     0, 16384, 16385, 16387, 15360, 
+    15616, 15680, 15712, 15713, 15708,     0, 16384, 16385, 
+    16387, 15360, 15616, 15680, 15712, 15713, 15708, 15710, 
+        0, 16384, 16385, 16387, 15360, 15616, 15680,     0, 
+    16384, 16385, 16387, 15360, 15616, 15744, 15712,     0, 
+    16384, 16385, 16387, 15360, 15616, 15744, 15712,     0, 
+    16384, 16385, 16387, 15360, 15616, 15744, 15712, 15714, 
+        0, 16384, 16385, 16387, 15360, 15616, 15744, 15712, 
+        0, 16384, 16385, 16387, 15360, 15616, 15744, 15712, 
+    15716,     0, 16384, 16385, 16387, 15360, 15616, 15744, 
+    15712, 15716,     0, 16384, 16385, 16387, 15360, 15616, 
+    15744, 15712, 15720, 15718,     0, 16384, 16385, 16387, 
+    15360, 15616, 15744, 15712,     0, 16384, 16385, 16387, 
+    15360, 15616, 15744, 15712, 15720,     0, 16384, 16385, 
+    16387, 15360, 15616, 15744, 15712, 15720,     0, 16384, 
+    16385, 16387, 15360, 15616, 15744, 15712, 15720, 15722, 
+        0, 16384, 16385, 16387, 15360, 15616, 15744, 15712, 
+    15720,     0, 16384, 16385, 16387, 15360, 15616, 15744, 
+    15712, 15728, 15724,     0, 16384, 16385, 16387, 15360, 
+    15616, 15744, 15712, 15728, 15724,     0, 16384, 16385, 
+    16387, 15360, 15616, 15744, 15712, 15728, 15729, 15726, 
+        0, 16384, 16385, 16387, 15360, 15616, 15744, 15712, 
+        0, 16384, 16385, 16387, 15360, 15616, 15744, 15745, 
+    15728,     0, 16384, 16385, 16387, 15360, 15616, 15744, 
+    15745, 15728,     0, 16384, 16385, 16387, 15360, 15616, 
+    15744, 15745, 15728, 15730,     0, 16384, 16385, 16387, 
+    15360, 15616, 15744, 15745, 15728,     0, 16384, 16385, 
+    16387, 15360, 15616, 15744, 15745, 15728, 15732,     0, 
+    16384, 16385, 16387, 15360, 15616, 15744, 15745, 15728, 
+    15732,     0, 16384, 16385, 16387, 15360, 15616, 15744, 
+    15745, 15728, 15736, 15734,     0, 16384, 16385, 16387, 
+    15360, 15616, 15744, 15745, 15728,     0, 16384, 16385, 
+    16387, 15360, 15616, 15744, 15745, 15728, 15736,     0, 
+    16384, 16385, 16387, 15360, 15616, 15744, 15745, 15747, 
+    15736,     0, 16384, 16385, 16387, 15360, 15616, 15744, 
+    15745, 15747, 15736, 15738,     0, 16384, 16385, 16387, 
+    15360, 15616, 15744, 15745, 15747, 15736,     0, 16384, 
+    16385, 16387, 15360, 15616, 15744, 15745, 15747, 15736, 
+    15740,     0, 16384, 16385, 16387, 15360, 15616, 15744, 
+    15745, 15747, 15736, 15740,     0, 16384, 16385, 16387, 
+    15360, 15616, 15744, 15745, 15747, 15736, 15740, 15742, 
+        0, 16384, 16385, 16387, 15360, 15616,     0, 16384, 
+    16385, 16387, 15360, 15872, 15744,     0, 16384, 16385, 
+    16387, 15360, 15872, 15744,     0, 16384, 16385, 16387, 
+    15360, 15872, 15744, 15746,     0, 16384, 16385, 16387, 
+    15360, 15872, 15744,     0, 16384, 16385, 16387, 15360, 
+    15872, 15744, 15748,     0, 16384, 16385, 16387, 15360, 
+    15872, 15744, 15748,     0, 16384, 16385, 16387, 15360, 
+    15872, 15744, 15752, 15750,     0, 16384, 16385, 16387, 
+    15360, 15872, 15744,     0, 16384, 16385, 16387, 15360, 
+    15872, 15744, 15752,     0, 16384, 16385, 16387, 15360, 
+    15872, 15744, 15752,     0, 16384, 16385, 16387, 15360, 
+    15872, 15744, 15752, 15754,     0, 16384, 16385, 16387, 
+    15360, 15872, 15744, 15752,     0, 16384, 16385, 16387, 
+    15360, 15872, 15744, 15760, 15756,     0, 16384, 16385, 
+    16387, 15360, 15872, 15744, 15760, 15756,     0, 16384, 
+    16385, 16387, 15360, 15872, 15744, 15760, 15761, 15758, 
+        0, 16384, 16385, 16387, 15360, 15872, 15744,     0, 
+    16384, 16385, 16387, 15360, 15872, 15744, 15760,     0, 
+    16384, 16385, 16387, 15360, 15872, 15744, 15760,     0, 
+    16384, 16385, 16387, 15360, 15872, 15744, 15760, 15762, 
+        0, 16384, 16385, 16387, 15360, 15872, 15744, 15760, 
+        0, 16384, 16385, 16387, 15360, 15872, 15744, 15760, 
+    15764,     0, 16384, 16385, 16387, 15360, 15872, 15744, 
+    15760, 15764,     0, 16384, 16385, 16387, 15360, 15872, 
+    15744, 15760, 15768, 15766,     0, 16384, 16385, 16387, 
+    15360, 15872, 15744, 15760,     0, 16384, 16385, 16387, 
+    15360, 15872, 15744, 15776, 15768,     0, 16384, 16385, 
+    16387, 15360, 15872, 15744, 15776, 15768,     0, 16384, 
+    16385, 16387, 15360, 15872, 15744, 15776, 15768, 15770, 
+        0, 16384, 16385, 16387, 15360, 15872, 15744, 15776, 
+    15768,     0, 16384, 16385, 16387, 15360, 15872, 15744, 
+    15776, 15777, 15772,     0, 16384, 16385, 16387, 15360, 
+    15872, 15744, 15776, 15777, 15772,     0, 16384, 16385, 
+    16387, 15360, 15872, 15744, 15776, 15777, 15772, 15774, 
+        0, 16384, 16385, 16387, 15360, 15872, 15744,     0, 
+    16384, 16385, 16387, 15360, 15872, 15744, 15776,     0, 
+    16384, 16385, 16387, 15360, 15872, 15744, 15776,     0, 
+    16384, 16385, 16387, 15360, 15872, 15744, 15776, 15778, 
+        0, 16384, 16385, 16387, 15360, 15872, 15744, 15776, 
+        0, 16384, 16385, 16387, 15360, 15872, 15744, 15776, 
+    15780,     0, 16384, 16385, 16387, 15360, 15872, 15744, 
+    15776, 15780,     0, 16384, 16385, 16387, 15360, 15872, 
+    15744, 15776, 15784, 15782,     0, 16384, 16385, 16387, 
+    15360, 15872, 15744, 15776,     0, 16384, 16385, 16387, 
+    15360, 15872, 15744, 15776, 15784,     0, 16384, 16385, 
+    16387, 15360, 15872, 15744, 15776, 15784,     0, 16384, 
+    16385, 16387, 15360, 15872, 15744, 15776, 15784, 15786, 
+        0, 16384, 16385, 16387, 15360, 15872, 15744, 15776, 
+    15784,     0, 16384, 16385, 16387, 15360, 15872, 15744, 
+    15776, 15792, 15788,     0, 16384, 16385, 16387, 15360, 
+    15872, 15744, 15776, 15792, 15788,     0, 16384, 16385, 
+    16387, 15360, 15872, 15744, 15776, 15792, 15793, 15790, 
+        0, 16384, 16385, 16387, 15360, 15872, 15744, 15776, 
+        0, 16384, 16385, 16387, 15360, 15872, 15744, 15808, 
+    15792,     0, 16384, 16385, 16387, 15360, 15872, 15744, 
+    15808, 15792,     0, 16384, 16385, 16387, 15360, 15872, 
+    15744, 15808, 15792, 15794,     0, 16384, 16385, 16387, 
+    15360, 15872, 15744, 15808, 15792,     0, 16384, 16385, 
+    16387, 15360, 15872, 15744, 15808, 15792, 15796,     0, 
+    16384, 16385, 16387, 15360, 15872, 15744, 15808, 15792, 
+    15796,     0, 16384, 16385, 16387, 15360, 15872, 15744, 
+    15808, 15792, 15800, 15798,     0, 16384, 16385, 16387, 
+    15360, 15872, 15744, 15808, 15792,     0, 16384, 16385, 
+    16387, 15360, 15872, 15744, 15808, 15809, 15800,     0, 
+    16384, 16385, 16387, 15360, 15872, 15744, 15808, 15809, 
+    15800,     0, 16384, 16385, 16387, 15360, 15872, 15744, 
+    15808, 15809, 15800, 15802,     0, 16384, 16385, 16387, 
+    15360, 15872, 15744, 15808, 15809, 15800,     0, 16384, 
+    16385, 16387, 15360, 15872, 15744, 15808, 15809, 15800, 
+    15804,     0, 16384, 16385, 16387, 15360, 15872, 15744, 
+    15808, 15809, 15811, 15804,     0, 16384, 16385, 16387, 
+    15360, 15872, 15744, 15808, 15809, 15811, 15804, 15806, 
+        0, 16384, 16385, 16387, 15360, 15872, 15744,     0, 
+    16384, 16385, 16387, 15360, 15872, 15873, 15808,     0, 
+    16384, 16385, 16387, 15360, 15872, 15873, 15808,     0, 
+    16384, 16385, 16387, 15360, 15872, 15873, 15808, 15810, 
+        0, 16384, 16385, 16387, 15360, 15872, 15873, 15808, 
+        0, 16384, 16385, 16387, 15360, 15872, 15873, 15808, 
+    15812,     0, 16384, 16385, 16387, 15360, 15872, 15873, 
+    15808, 15812,     0, 16384, 16385, 16387, 15360, 15872, 
+    15873, 15808, 15816, 15814,     0, 16384, 16385, 16387, 
+    15360, 15872, 15873, 15808,     0, 16384, 16385, 16387, 
+    15360, 15872, 15873, 15808, 15816,     0, 16384, 16385, 
+    16387, 15360, 15872, 15873, 15808, 15816,     0, 16384, 
+    16385, 16387, 15360, 15872, 15873, 15808, 15816, 15818, 
+        0, 16384, 16385, 16387, 15360, 15872, 15873, 15808, 
+    15816,     0, 16384, 16385, 16387, 15360, 15872, 15873, 
+    15808, 15824, 15820,     0, 16384, 16385, 16387, 15360, 
+    15872, 15873, 15808, 15824, 15820,     0, 16384, 16385, 
+    16387, 15360, 15872, 15873, 15808, 15824, 15825, 15822, 
+        0, 16384, 16385, 16387, 15360, 15872, 15873, 15808, 
+        0, 16384, 16385, 16387, 15360, 15872, 15873, 15808, 
+    15824,     0, 16384, 16385, 16387, 15360, 15872, 15873, 
+    15808, 15824,     0, 16384, 16385, 16387, 15360, 15872, 
+    15873, 15808, 15824, 15826,     0, 16384, 16385, 16387, 
+    15360, 15872, 15873, 15808, 15824,     0, 16384, 16385, 
+    16387, 15360, 15872, 15873, 15808, 15824, 15828,     0, 
+    16384, 16385, 16387, 15360, 15872, 15873, 15808, 15824, 
+    15828,     0, 16384, 16385, 16387, 15360, 15872, 15873, 
+    15808, 15824, 15832, 15830,     0, 16384, 16385, 16387, 
+    15360, 15872, 15873, 15808, 15824,     0, 16384, 16385, 
+    16387, 15360, 15872, 15873, 15808, 15840, 15832,     0, 
+    16384, 16385, 16387, 15360, 15872, 15873, 15808, 15840, 
+    15832,     0, 16384, 16385, 16387, 15360, 15872, 15873, 
+    15808, 15840, 15832, 15834,     0, 16384, 16385, 16387, 
+    15360, 15872, 15873, 15808, 15840, 15832,     0, 16384, 
+    16385, 16387, 15360, 15872, 15873, 15808, 15840, 15841, 
+    15836,     0, 16384, 16385, 16387, 15360, 15872, 15873, 
+    15808, 15840, 15841, 15836,     0, 16384, 16385, 16387, 
+    15360, 15872, 15873, 15808, 15840, 15841, 15836, 15838, 
+        0, 16384, 16385, 16387, 15360, 15872, 15873, 15808, 
+        0, 16384, 16385, 16387, 15360, 15872, 15873, 15808, 
+    15840,     0, 16384, 16385, 16387, 15360, 15872, 15873, 
+    15875, 15840,     0, 16384, 16385, 16387, 15360, 15872, 
+    15873, 15875, 15840, 15842,     0, 16384, 16385, 16387, 
+    15360, 15872, 15873, 15875, 15840,     0, 16384, 16385, 
+    16387, 15360, 15872, 15873, 15875, 15840, 15844,     0, 
+    16384, 16385, 16387, 15360, 15872, 15873, 15875, 15840, 
+    15844,     0, 16384, 16385, 16387, 15360, 15872, 15873, 
+    15875, 15840, 15848, 15846,     0, 16384, 16385, 16387, 
+    15360, 15872, 15873, 15875, 15840,     0, 16384, 16385, 
+    16387, 15360, 15872, 15873, 15875, 15840, 15848,     0, 
+    16384, 16385, 16387, 15360, 15872, 15873, 15875, 15840, 
+    15848,     0, 16384, 16385, 16387, 15360, 15872, 15873, 
+    15875, 15840, 15848, 15850,     0, 16384, 16385, 16387, 
+    15360, 15872, 15873, 15875, 15840, 15848,     0, 16384, 
+    16385, 16387, 15360, 15872, 15873, 15875, 15840, 15856, 
+    15852,     0, 16384, 16385, 16387, 15360, 15872, 15873, 
+    15875, 15840, 15856, 15852,     0, 16384, 16385, 16387, 
+    15360, 15872, 15873, 15875, 15840, 15856, 15857, 15854, 
+        0, 16384, 16385, 16387, 15360, 15872, 15873, 15875, 
+    15840,     0, 16384, 16385, 16387, 15360, 15872, 15873, 
+    15875, 15840, 15856,     0, 16384, 16385, 16387, 15360, 
+    15872, 15873, 15875, 15840, 15856,     0, 16384, 16385, 
+    16387, 15360, 15872, 15873, 15875, 15840, 15856, 15858, 
+        0, 16384, 16385, 16387, 15360, 15872, 15873, 15875, 
+    15879, 15856,     0, 16384, 16385, 16387, 15360, 15872, 
+    15873, 15875, 15879, 15856, 15860,     0, 16384, 16385, 
+    16387, 15360, 15872, 15873, 15875, 15879, 15856, 15860, 
+        0, 16384, 16385, 16387, 15360, 15872, 15873, 15875, 
+    15879, 15856, 15864, 15862,     0, 16384, 16385, 16387, 
+    15360, 15872, 15873, 15875, 15879, 15856,     0, 16384, 
+    16385, 16387, 15360, 15872, 15873, 15875, 15879, 15856, 
+    15864,     0, 16384, 16385, 16387, 15360, 15872, 15873, 
+    15875, 15879, 15856, 15864,     0, 16384, 16385, 16387, 
+    15360, 15872, 15873, 15875, 15879, 15856, 15864, 15866, 
+        0, 16384, 16385, 16387, 15360, 15872, 15873, 15875, 
+    15879, 15856, 15864,     0, 16384, 16385, 16387, 15360, 
+    15872, 15873, 15875, 15879, 15856, 15864, 15868,     0, 
+    16384, 16385, 16387, 15360, 15872, 15873, 15875, 15879, 
+    15856, 15864, 15868,     0, 16384, 16385, 16387, 15360, 
+    15872, 15873, 15875, 15879, 15856, 15864, 15868, 15870, 
+        0, 16384, 16385, 16387, 15360,     0, 16384, 16385, 
+    16387, 15360, 15872,     0, 16384, 16385, 16387, 15360, 
+    15872,     0, 16384, 16385, 16387, 15360, 15872, 15874, 
+        0, 16384, 16385, 16387, 15360, 15872,     0, 16384, 
+    16385, 16387, 15360, 15872, 15876,     0, 16384, 16385, 
+    16387, 15360, 15872, 15876,     0, 16384, 16385, 16387, 
+    15360, 15872, 15880, 15878,     0, 16384, 16385, 16387, 
+    16391, 15872,     0, 16384, 16385, 16387, 16391, 15872, 
+    15880,     0, 16384, 16385, 16387, 16391, 15872, 15880, 
+        0, 16384, 16385, 16387, 16391, 15872, 15880, 15882, 
+        0, 16384, 16385, 16387, 16391, 15872, 15880,     0, 
+    16384, 16385, 16387, 16391, 15872, 15888, 15884,     0, 
+    16384, 16385, 16387, 16391, 15872, 15888, 15884,     0, 
+    16384, 16385, 16387, 16391, 15872, 15888, 15889, 15886, 
+        0, 16384, 16385, 16387, 16391, 15872,     0, 16384, 
+    16385, 16387, 16391, 15872, 15888,     0, 16384, 16385, 
+    16387, 16391, 15872, 15888,     0, 16384, 16385, 16387, 
+    16391, 15872, 15888, 15890,     0, 16384, 16385, 16387, 
+    16391, 15872, 15888,     0, 16384, 16385, 16387, 16391, 
+    15872, 15888, 15892,     0, 16384, 16385, 16387, 16391, 
+    15872, 15888, 15892,     0, 16384, 16385, 16387, 16391, 
+    15872, 15888, 15896, 15894,     0, 16384, 16385, 16387, 
+    16391, 15872, 15888,     0, 16384, 16385, 16387, 16391, 
+    15872, 15904, 15896,     0, 16384, 16385, 16387, 16391, 
+    15872, 15904, 15896,     0, 16384, 16385, 16387, 16391, 
+    15872, 15904, 15896, 15898,     0, 16384, 16385, 16387, 
+    16391, 15872, 15904, 15896,     0, 16384, 16385, 16387, 
+    16391, 15872, 15904, 15905, 15900,     0, 16384, 16385, 
+    16387, 16391, 15872, 15904, 15905, 15900,     0, 16384, 
+    16385, 16387, 16391, 15872, 15904, 15905, 15900, 15902, 
+        0, 16384, 16385, 16387, 16391, 15872,     0, 16384, 
+    16385, 16387, 16391, 15872, 15904,     0, 16384, 16385, 
+    16387, 16391, 15872, 15904,     0, 16384, 16385, 16387, 
+    16391, 15872, 15904, 15906,     0, 16384, 16385, 16387, 
+    16391, 15872, 15904,     0, 16384, 16385, 16387, 16391, 
+    15872, 15904, 15908,     0, 16384, 16385, 16387, 16391, 
+    15872, 15904, 15908,     0, 16384, 16385, 16387, 16391, 
+    15872, 15904, 15912, 15910,     0, 16384, 16385, 16387, 
+    16391, 15872, 15904,     0, 16384, 16385, 16387, 16391, 
+    15872, 15904, 15912,     0, 16384, 16385, 16387, 16391, 
+    15872, 15904, 15912,     0, 16384, 16385, 16387, 16391, 
+    15872, 15904, 15912, 15914,     0, 16384, 16385, 16387, 
+    16391, 15872, 15904, 15912,     0, 16384, 16385, 16387, 
+    16391, 15872, 15904, 15920, 15916,     0, 16384, 16385, 
+    16387, 16391, 15872, 15904, 15920, 15916,     0, 16384, 
+    16385, 16387, 16391, 15872, 15904, 15920, 15921, 15918, 
+        0, 16384, 16385, 16387, 16391, 15872, 15904,     0, 
+    16384, 16385, 16387, 16391, 15872, 15936, 15920,     0, 
+    16384, 16385, 16387, 16391, 15872, 15936, 15920,     0, 
+    16384, 16385, 16387, 16391, 15872, 15936, 15920, 15922, 
+        0, 16384, 16385, 16387, 16391, 15872, 15936, 15920, 
+        0, 16384, 16385, 16387, 16391, 15872, 15936, 15920, 
+    15924,     0, 16384, 16385, 16387, 16391, 15872, 15936, 
+    15920, 15924,     0, 16384, 16385, 16387, 16391, 15872, 
+    15936, 15920, 15928, 15926,     0, 16384, 16385, 16387, 
+    16391, 15872, 15936, 15920,     0, 16384, 16385, 16387, 
+    16391, 15872, 15936, 15937, 15928,     0, 16384, 16385, 
+    16387, 16391, 15872, 15936, 15937, 15928,     0, 16384, 
+    16385, 16387, 16391, 15872, 15936, 15937, 15928, 15930, 
+        0, 16384, 16385, 16387, 16391, 15872, 15936, 15937, 
+    15928,     0, 16384, 16385, 16387, 16391, 15872, 15936, 
+    15937, 15928, 15932,     0, 16384, 16385, 16387, 16391, 
+    15872, 15936, 15937, 15939, 15932,     0, 16384, 16385, 
+    16387, 16391, 15872, 15936, 15937, 15939, 15932, 15934, 
+        0, 16384, 16385, 16387, 16391, 15872,     0, 16384, 
+    16385, 16387, 16391, 15872, 15936,     0, 16384, 16385, 
+    16387, 16391, 15872, 15936,     0, 16384, 16385, 16387, 
+    16391, 15872, 15936, 15938,     0, 16384, 16385, 16387, 
+    16391, 15872, 15936,     0, 16384, 16385, 16387, 16391, 
+    15872, 15936, 15940,     0, 16384, 16385, 16387, 16391, 
+    15872, 15936, 15940,     0, 16384, 16385, 16387, 16391, 
+    15872, 15936, 15944, 15942,     0, 16384, 16385, 16387, 
+    16391, 15872, 15936,     0, 16384, 16385, 16387, 16391, 
+    15872, 15936, 15944,     0, 16384, 16385, 16387, 16391, 
+    15872, 15936, 15944,     0, 16384, 16385, 16387, 16391, 
+    15872, 15936, 15944, 15946,     0, 16384, 16385, 16387, 
+    16391, 15872, 15936, 15944,     0, 16384, 16385, 16387, 
+    16391, 15872, 15936, 15952, 15948,     0, 16384, 16385, 
+    16387, 16391, 15872, 15936, 15952, 15948,     0, 16384, 
+    16385, 16387, 16391, 15872, 15936, 15952, 15953, 15950, 
+        0, 16384, 16385, 16387, 16391, 15872, 15936,     0, 
+    16384, 16385, 16387, 16391, 15872, 15936, 15952,     0, 
+    16384, 16385, 16387, 16391, 15872, 15936, 15952,     0, 
+    16384, 16385, 16387, 16391, 15872, 15936, 15952, 15954, 
+        0, 16384, 16385, 16387, 16391, 15872, 15936, 15952, 
+        0, 16384, 16385, 16387, 16391, 15872, 15936, 15952, 
+    15956,     0, 16384, 16385, 16387, 16391, 15872, 15936, 
+    15952, 15956,     0, 16384, 16385, 16387, 16391, 15872, 
+    15936, 15952, 15960, 15958,     0, 16384, 16385, 16387, 
+    16391, 15872, 15936, 15952,     0, 16384, 16385, 16387, 
+    16391, 15872, 15936, 15968, 15960,     0, 16384, 16385, 
+    16387, 16391, 15872, 15936, 15968, 15960,     0, 16384, 
+    16385, 16387, 16391, 15872, 15936, 15968, 15960, 15962, 
+        0, 16384, 16385, 16387, 16391, 15872, 15936, 15968, 
+    15960,     0, 16384, 16385, 16387, 16391, 15872, 15936, 
+    15968, 15969, 15964,     0, 16384, 16385, 16387, 16391, 
+    15872, 15936, 15968, 15969, 15964,     0, 16384, 16385, 
+    16387, 16391, 15872, 15936, 15968, 15969, 15964, 15966, 
+        0, 16384, 16385, 16387, 16391, 15872, 15936,     0, 
+    16384, 16385, 16387, 16391, 15872, 16000, 15968,     0, 
+    16384, 16385, 16387, 16391, 15872, 16000, 15968,     0, 
+    16384, 16385, 16387, 16391, 15872, 16000, 15968, 15970, 
+        0, 16384, 16385, 16387, 16391, 15872, 16000, 15968, 
+        0, 16384, 16385, 16387, 16391, 15872, 16000, 15968, 
+    15972,     0, 16384, 16385, 16387, 16391, 15872, 16000, 
+    15968, 15972,     0, 16384, 16385, 16387, 16391, 15872, 
+    16000, 15968, 15976, 15974,     0, 16384, 16385, 16387, 
+    16391, 15872, 16000, 15968,     0, 16384, 16385, 16387, 
+    16391, 15872, 16000, 15968, 15976,     0, 16384, 16385, 
+    16387, 16391, 15872, 16000, 15968, 15976,     0, 16384, 
+    16385, 16387, 16391, 15872, 16000, 15968, 15976, 15978, 
+        0, 16384, 16385, 16387, 16391, 15872, 16000, 15968, 
+    15976,     0, 16384, 16385, 16387, 16391, 15872, 16000, 
+    15968, 15984, 15980,     0, 16384, 16385, 16387, 16391, 
+    15872, 16000, 15968, 15984, 15980,     0, 16384, 16385, 
+    16387, 16391, 15872, 16000, 15968, 15984, 15985, 15982, 
+        0, 16384, 16385, 16387, 16391, 15872, 16000, 15968, 
+        0, 16384, 16385, 16387, 16391, 15872, 16000, 16001, 
+    15984,     0, 16384, 16385, 16387, 16391, 15872, 16000, 
+    16001, 15984,     0, 16384, 16385, 16387, 16391, 15872, 
+    16000, 16001, 15984, 15986,     0, 16384, 16385, 16387, 
+    16391, 15872, 16000, 16001, 15984,     0, 16384, 16385, 
+    16387, 16391, 15872, 16000, 16001, 15984, 15988,     0, 
+    16384, 16385, 16387, 16391, 15872, 16000, 16001, 15984, 
+    15988,     0, 16384, 16385, 16387, 16391, 15872, 16000, 
+    16001, 15984, 15992, 15990,     0, 16384, 16385, 16387, 
+    16391, 15872, 16000, 16001, 15984,     0, 16384, 16385, 
+    16387, 16391, 15872, 16000, 16001, 15984, 15992,     0, 
+    16384, 16385, 16387, 16391, 15872, 16000, 16001, 16003, 
+    15992,     0, 16384, 16385, 16387, 16391, 15872, 16000, 
+    16001, 16003, 15992, 15994,     0, 16384, 16385, 16387, 
+    16391, 15872, 16000, 16001, 16003, 15992,     0, 16384, 
+    16385, 16387, 16391, 15872, 16000, 16001, 16003, 15992, 
+    15996,     0, 16384, 16385, 16387, 16391, 15872, 16000, 
+    16001, 16003, 15992, 15996,     0, 16384, 16385, 16387, 
+    16391, 15872, 16000, 16001, 16003, 15992, 15996, 15998, 
+        0, 16384, 16385, 16387, 16391, 15872,     0, 16384, 
+    16385, 16387, 16391, 15872, 16000,     0, 16384, 16385, 
+    16387, 16391, 15872, 16000,     0, 16384, 16385, 16387, 
+    16391, 15872, 16000, 16002,     0, 16384, 16385, 16387, 
+    16391, 15872, 16000,     0, 16384, 16385, 16387, 16391, 
+    15872, 16000, 16004,     0, 16384, 16385, 16387, 16391, 
+    15872, 16000, 16004,     0, 16384, 16385, 16387, 16391, 
+    15872, 16000, 16008, 16006,     0, 16384, 16385, 16387, 
+    16391, 15872, 16000,     0, 16384, 16385, 16387, 16391, 
+    15872, 16000, 16008,     0, 16384, 16385, 16387, 16391, 
+    15872, 16000, 16008,     0, 16384, 16385, 16387, 16391, 
+    15872, 16000, 16008, 16010,     0, 16384, 16385, 16387, 
+    16391, 15872, 16000, 16008,     0, 16384, 16385, 16387, 
+    16391, 15872, 16000, 16016, 16012,     0, 16384, 16385, 
+    16387, 16391, 15872, 16000, 16016, 16012,     0, 16384, 
+    16385, 16387, 16391, 15872, 16000, 16016, 16017, 16014, 
+        0, 16384, 16385, 16387, 16391, 15872, 16000,     0, 
+    16384, 16385, 16387, 16391, 15872, 16000, 16016,     0, 
+    16384, 16385, 16387, 16391, 15872, 16000, 16016,     0, 
+    16384, 16385, 16387, 16391, 15872, 16000, 16016, 16018, 
+        0, 16384, 16385, 16387, 16391, 15872, 16000, 16016, 
+        0, 16384, 16385, 16387, 16391, 15872, 16000, 16016, 
+    16020,     0, 16384, 16385, 16387, 16391, 15872, 16000, 
+    16016, 16020,     0, 16384, 16385, 16387, 16391, 15872, 
+    16000, 16016, 16024, 16022,     0, 16384, 16385, 16387, 
+    16391, 15872, 16000, 16016,     0, 16384, 16385, 16387, 
+    16391, 15872, 16000, 16032, 16024,     0, 16384, 16385, 
+    16387, 16391, 15872, 16000, 16032, 16024,     0, 16384, 
+    16385, 16387, 16391, 15872, 16000, 16032, 16024, 16026, 
+        0, 16384, 16385, 16387, 16391, 15872, 16000, 16032, 
+    16024,     0, 16384, 16385, 16387, 16391, 15872, 16000, 
+    16032, 16033, 16028,     0, 16384, 16385, 16387, 16391, 
+    15872, 16000, 16032, 16033, 16028,     0, 16384, 16385, 
+    16387, 16391, 15872, 16000, 16032, 16033, 16028, 16030, 
+        0, 16384, 16385, 16387, 16391, 15872, 16000,     0, 
+    16384, 16385, 16387, 16391, 15872, 16000, 16032,     0, 
+    16384, 16385, 16387, 16391, 15872, 16000, 16032,     0, 
+    16384, 16385, 16387, 16391, 15872, 16000, 16032, 16034, 
+        0, 16384, 16385, 16387, 16391, 15872, 16000, 16032, 
+        0, 16384, 16385, 16387, 16391, 15872, 16000, 16032, 
+    16036,     0, 16384, 16385, 16387, 16391, 15872, 16000, 
+    16032, 16036,     0, 16384, 16385, 16387, 16391, 15872, 
+    16000, 16032, 16040, 16038,     0, 16384, 16385, 16387, 
+    16391, 15872, 16000, 16032,     0, 16384, 16385, 16387, 
+    16391, 15872, 16000, 16032, 16040,     0, 16384, 16385, 
+    16387, 16391, 15872, 16000, 16032, 16040,     0, 16384, 
+    16385, 16387, 16391, 15872, 16000, 16032, 16040, 16042, 
+        0, 16384, 16385, 16387, 16391, 15872, 16000, 16032, 
+    16040,     0, 16384, 16385, 16387, 16391, 15872, 16000, 
+    16032, 16048, 16044,     0, 16384, 16385, 16387, 16391, 
+    15872, 16000, 16032, 16048, 16044,     0, 16384, 16385, 
+    16387, 16391, 15872, 16000, 16032, 16048, 16049, 16046, 
+        0, 16384, 16385, 16387, 16391, 15872, 16000, 16032, 
+        0, 16384, 16385, 16387, 16391, 15872, 16000, 16064, 
+    16048,     0, 16384, 16385, 16387, 16391, 15872, 16000, 
+    16064, 16048,     0, 16384, 16385, 16387, 16391, 15872, 
+    16000, 16064, 16048, 16050,     0, 16384, 16385, 16387, 
+    16391, 15872, 16000, 16064, 16048,     0, 16384, 16385, 
+    16387, 16391, 15872, 16000, 16064, 16048, 16052,     0, 
+    16384, 16385, 16387, 16391, 15872, 16000, 16064, 16048, 
+    16052,     0, 16384, 16385, 16387, 16391, 15872, 16000, 
+    16064, 16048, 16056, 16054,     0, 16384, 16385, 16387, 
+    16391, 15872, 16000, 16064, 16048,     0, 16384, 16385, 
+    16387, 16391, 15872, 16000, 16064, 16065, 16056,     0, 
+    16384, 16385, 16387, 16391, 15872, 16000, 16064, 16065, 
+    16056,     0, 16384, 16385, 16387, 16391, 15872, 16000, 
+    16064, 16065, 16056, 16058,     0, 16384, 16385, 16387, 
+    16391, 15872, 16000, 16064, 16065, 16056,     0, 16384, 
+    16385, 16387, 16391, 15872, 16000, 16064, 16065, 16056, 
+    16060,     0, 16384, 16385, 16387, 16391, 15872, 16000, 
+    16064, 16065, 16067, 16060,     0, 16384, 16385, 16387, 
+    16391, 15872, 16000, 16064, 16065, 16067, 16060, 16062, 
+        0, 16384, 16385, 16387, 16391, 15872, 16000,     0, 
+    16384, 16385, 16387, 16391, 15872, 16128, 16064,     0, 
+    16384, 16385, 16387, 16391, 15872, 16128, 16064,     0, 
+    16384, 16385, 16387, 16391, 15872, 16128, 16064, 16066, 
+        0, 16384, 16385, 16387, 16391, 15872, 16128, 16064, 
+        0, 16384, 16385, 16387, 16391, 15872, 16128, 16064, 
+    16068,     0, 16384, 16385, 16387, 16391, 15872, 16128, 
+    16064, 16068,     0, 16384, 16385, 16387, 16391, 15872, 
+    16128, 16064, 16072, 16070,     0, 16384, 16385, 16387, 
+    16391, 15872, 16128, 16064,     0, 16384, 16385, 16387, 
+    16391, 15872, 16128, 16064, 16072,     0, 16384, 16385, 
+    16387, 16391, 15872, 16128, 16064, 16072,     0, 16384, 
+    16385, 16387, 16391, 15872, 16128, 16064, 16072, 16074, 
+        0, 16384, 16385, 16387, 16391, 15872, 16128, 16064, 
+    16072,     0, 16384, 16385, 16387, 16391, 15872, 16128, 
+    16064, 16080, 16076,     0, 16384, 16385, 16387, 16391, 
+    15872, 16128, 16064, 16080, 16076,     0, 16384, 16385, 
+    16387, 16391, 15872, 16128, 16064, 16080, 16081, 16078, 
+        0, 16384, 16385, 16387, 16391, 15872, 16128, 16064, 
+        0, 16384, 16385, 16387, 16391, 15872, 16128, 16064, 
+    16080,     0, 16384, 16385, 16387, 16391, 15872, 16128, 
+    16064, 16080,     0, 16384, 16385, 16387, 16391, 15872, 
+    16128, 16064, 16080, 16082,     0, 16384, 16385, 16387, 
+    16391, 15872, 16128, 16064, 16080,     0, 16384, 16385, 
+    16387, 16391, 15872, 16128, 16064, 16080, 16084,     0, 
+    16384, 16385, 16387, 16391, 15872, 16128, 16064, 16080, 
+    16084,     0, 16384, 16385, 16387, 16391, 15872, 16128, 
+    16064, 16080, 16088, 16086,     0, 16384, 16385, 16387, 
+    16391, 15872, 16128, 16064, 16080,     0, 16384, 16385, 
+    16387, 16391, 15872, 16128, 16064, 16096, 16088,     0, 
+    16384, 16385, 16387, 16391, 15872, 16128, 16064, 16096, 
+    16088,     0, 16384, 16385, 16387, 16391, 15872, 16128, 
+    16064, 16096, 16088, 16090,     0, 16384, 16385, 16387, 
+    16391, 15872, 16128, 16064, 16096, 16088,     0, 16384, 
+    16385, 16387, 16391, 15872, 16128, 16064, 16096, 16097, 
+    16092,     0, 16384, 16385, 16387, 16391, 15872, 16128, 
+    16064, 16096, 16097, 16092,     0, 16384, 16385, 16387, 
+    16391, 15872, 16128, 16064, 16096, 16097, 16092, 16094, 
+        0, 16384, 16385, 16387, 16391, 15872, 16128, 16064, 
+        0, 16384, 16385, 16387, 16391, 15872, 16128, 16129, 
+    16096,     0, 16384, 16385, 16387, 16391, 15872, 16128, 
+    16129, 16096,     0, 16384, 16385, 16387, 16391, 15872, 
+    16128, 16129, 16096, 16098,     0, 16384, 16385, 16387, 
+    16391, 15872, 16128, 16129, 16096,     0, 16384, 16385, 
+    16387, 16391, 15872, 16128, 16129, 16096, 16100,     0, 
+    16384, 16385, 16387, 16391, 15872, 16128, 16129, 16096, 
+    16100,     0, 16384, 16385, 16387, 16391, 15872, 16128, 
+    16129, 16096, 16104, 16102,     0, 16384, 16385, 16387, 
+    16391, 15872, 16128, 16129, 16096,     0, 16384, 16385, 
+    16387, 16391, 15872, 16128, 16129, 16096, 16104,     0, 
+    16384, 16385, 16387, 16391, 15872, 16128, 16129, 16096, 
+    16104,     0, 16384, 16385, 16387, 16391, 15872, 16128, 
+    16129, 16096, 16104, 16106,     0, 16384, 16385, 16387, 
+    16391, 15872, 16128, 16129, 16096, 16104,     0, 16384, 
+    16385, 16387, 16391, 15872, 16128, 16129, 16096, 16112, 
+    16108,     0, 16384, 16385, 16387, 16391, 15872, 16128, 
+    16129, 16096, 16112, 16108,     0, 16384, 16385, 16387, 
+    16391, 15872, 16128, 16129, 16096, 16112, 16113, 16110, 
+        0, 16384, 16385, 16387, 16391, 15872, 16128, 16129, 
+    16096,     0, 16384, 16385, 16387, 16391, 15872, 16128, 
+    16129, 16096, 16112,     0, 16384, 16385, 16387, 16391, 
+    15872, 16128, 16129, 16131, 16112,     0, 16384, 16385, 
+    16387, 16391, 15872, 16128, 16129, 16131, 16112, 16114, 
+        0, 16384, 16385, 16387, 16391, 15872, 16128, 16129, 
+    16131, 16112,     0, 16384, 16385, 16387, 16391, 15872, 
+    16128, 16129, 16131, 16112, 16116,     0, 16384, 16385, 
+    16387, 16391, 15872, 16128, 16129, 16131, 16112, 16116, 
+        0, 16384, 16385, 16387, 16391, 15872, 16128, 16129, 
+    16131, 16112, 16120, 16118,     0, 16384, 16385, 16387, 
+    16391, 15872, 16128, 16129, 16131, 16112,     0, 16384, 
+    16385, 16387, 16391, 15872, 16128, 16129, 16131, 16112, 
+    16120,     0, 16384, 16385, 16387, 16391, 15872, 16128, 
+    16129, 16131, 16112, 16120,     0, 16384, 16385, 16387, 
+    16391, 15872, 16128, 16129, 16131, 16112, 16120, 16122, 
+        0, 16384, 16385, 16387, 16391, 15872, 16128, 16129, 
+    16131, 16135, 16120,     0, 16384, 16385, 16387, 16391, 
+    15872, 16128, 16129, 16131, 16135, 16120, 16124,     0, 
+    16384, 16385, 16387, 16391, 15872, 16128, 16129, 16131, 
+    16135, 16120, 16124,     0, 16384, 16385, 16387, 16391, 
+    15872, 16128, 16129, 16131, 16135, 16120, 16124, 16126, 
+        0, 16384, 16385, 16387, 16391, 15872,     0, 16384, 
+    16385, 16387, 16391, 15872, 16128,     0, 16384, 16385, 
+    16387, 16391, 15872, 16128,     0, 16384, 16385, 16387, 
+    16391, 15872, 16128, 16130,     0, 16384, 16385, 16387, 
+    16391, 15872, 16128,     0, 16384, 16385, 16387, 16391, 
+    15872, 16128, 16132,     0, 16384, 16385, 16387, 16391, 
+    15872, 16128, 16132,     0, 16384, 16385, 16387, 16391, 
+    15872, 16128, 16136, 16134,     0, 16384, 16385, 16387, 
+    16391, 15872, 16128,     0, 16384, 16385, 16387, 16391, 
+    15872, 16128, 16136,     0, 16384, 16385, 16387, 16391, 
+    15872, 16128, 16136,     0, 16384, 16385, 16387, 16391, 
+    15872, 16128, 16136, 16138,     0, 16384, 16385, 16387, 
+    16391, 15872, 16128, 16136,     0, 16384, 16385, 16387, 
+    16391, 15872, 16128, 16144, 16140,     0, 16384, 16385, 
+    16387, 16391, 15872, 16128, 16144, 16140,     0, 16384, 
+    16385, 16387, 16391, 15872, 16128, 16144, 16145, 16142, 
+        0, 16384, 16385, 16387, 16391, 16399, 16128,     0, 
+    16384, 16385, 16387, 16391, 16399, 16128, 16144,     0, 
+    16384, 16385, 16387, 16391, 16399, 16128, 16144,     0, 
+    16384, 16385, 16387, 16391, 16399, 16128, 16144, 16146, 
+        0, 16384, 16385, 16387, 16391, 16399, 16128, 16144, 
+        0, 16384, 16385, 16387, 16391, 16399, 16128, 16144, 
+    16148,     0, 16384, 16385, 16387, 16391, 16399, 16128, 
+    16144, 16148,     0, 16384, 16385, 16387, 16391, 16399, 
+    16128, 16144, 16152, 16150,     0, 16384, 16385, 16387, 
+    16391, 16399, 16128, 16144,     0, 16384, 16385, 16387, 
+    16391, 16399, 16128, 16160, 16152,     0, 16384, 16385, 
+    16387, 16391, 16399, 16128, 16160, 16152,     0, 16384, 
+    16385, 16387, 16391, 16399, 16128, 16160, 16152, 16154, 
+        0, 16384, 16385, 16387, 16391, 16399, 16128, 16160, 
+    16152,     0, 16384, 16385, 16387, 16391, 16399, 16128, 
+    16160, 16161, 16156,     0, 16384, 16385, 16387, 16391, 
+    16399, 16128, 16160, 16161, 16156,     0, 16384, 16385, 
+    16387, 16391, 16399, 16128, 16160, 16161, 16156, 16158, 
+        0, 16384, 16385, 16387, 16391, 16399, 16128,     0, 
+    16384, 16385, 16387, 16391, 16399, 16128, 16160,     0, 
+    16384, 16385, 16387, 16391, 16399, 16128, 16160,     0, 
+    16384, 16385, 16387, 16391, 16399, 16128, 16160, 16162, 
+        0, 16384, 16385, 16387, 16391, 16399, 16128, 16160, 
+        0, 16384, 16385, 16387, 16391, 16399, 16128, 16160, 
+    16164,     0, 16384, 16385, 16387, 16391, 16399, 16128, 
+    16160, 16164,     0, 16384, 16385, 16387, 16391, 16399, 
+    16128, 16160, 16168, 16166,     0, 16384, 16385, 16387, 
+    16391, 16399, 16128, 16160,     0, 16384, 16385, 16387, 
+    16391, 16399, 16128, 16160, 16168,     0, 16384, 16385, 
+    16387, 16391, 16399, 16128, 16160, 16168,     0, 16384, 
+    16385, 16387, 16391, 16399, 16128, 16160, 16168, 16170, 
+        0, 16384, 16385, 16387, 16391, 16399, 16128, 16160, 
+    16168,     0, 16384, 16385, 16387, 16391, 16399, 16128, 
+    16160, 16176, 16172,     0, 16384, 16385, 16387, 16391, 
+    16399, 16128, 16160, 16176, 16172,     0, 16384, 16385, 
+    16387, 16391, 16399, 16128, 16160, 16176, 16177, 16174, 
+        0, 16384, 16385, 16387, 16391, 16399, 16128, 16160, 
+        0, 16384, 16385, 16387, 16391, 16399, 16128, 16192, 
+    16176,     0, 16384, 16385, 16387, 16391, 16399, 16128, 
+    16192, 16176,     0, 16384, 16385, 16387, 16391, 16399, 
+    16128, 16192, 16176, 16178,     0, 16384, 16385, 16387, 
+    16391, 16399, 16128, 16192, 16176,     0, 16384, 16385, 
+    16387, 16391, 16399, 16128, 16192, 16176, 16180,     0, 
+    16384, 16385, 16387, 16391, 16399, 16128, 16192, 16176, 
+    16180,     0, 16384, 16385, 16387, 16391, 16399, 16128, 
+    16192, 16176, 16184, 16182,     0, 16384, 16385, 16387, 
+    16391, 16399, 16128, 16192, 16176,     0, 16384, 16385, 
+    16387, 16391, 16399, 16128, 16192, 16193, 16184,     0, 
+    16384, 16385, 16387, 16391, 16399, 16128, 16192, 16193, 
+    16184,     0, 16384, 16385, 16387, 16391, 16399, 16128, 
+    16192, 16193, 16184, 16186,     0, 16384, 16385, 16387, 
+    16391, 16399, 16128, 16192, 16193, 16184,     0, 16384, 
+    16385, 16387, 16391, 16399, 16128, 16192, 16193, 16184, 
+    16188,     0, 16384, 16385, 16387, 16391, 16399, 16128, 
+    16192, 16193, 16195, 16188,     0, 16384, 16385, 16387, 
+    16391, 16399, 16128, 16192, 16193, 16195, 16188, 16190, 
+        0, 16384, 16385, 16387, 16391, 16399, 16128,     0, 
+    16384, 16385, 16387, 16391, 16399, 16128, 16192,     0, 
+    16384, 16385, 16387, 16391, 16399, 16128, 16192,     0, 
+    16384, 16385, 16387, 16391, 16399, 16128, 16192, 16194, 
+        0, 16384, 16385, 16387, 16391, 16399, 16128, 16192, 
+        0, 16384, 16385, 16387, 16391, 16399, 16128, 16192, 
+    16196,     0, 16384, 16385, 16387, 16391, 16399, 16128, 
+    16192, 16196,     0, 16384, 16385, 16387, 16391, 16399, 
+    16128, 16192, 16200, 16198,     0, 16384, 16385, 16387, 
+    16391, 16399, 16128, 16192,     0, 16384, 16385, 16387, 
+    16391, 16399, 16128, 16192, 16200,     0, 16384, 16385, 
+    16387, 16391, 16399, 16128, 16192, 16200,     0, 16384, 
+    16385, 16387, 16391, 16399, 16128, 16192, 16200, 16202, 
+        0, 16384, 16385, 16387, 16391, 16399, 16128, 16192, 
+    16200,     0, 16384, 16385, 16387, 16391, 16399, 16128, 
+    16192, 16208, 16204,     0, 16384, 16385, 16387, 16391, 
+    16399, 16128, 16192, 16208, 16204,     0, 16384, 16385, 
+    16387, 16391, 16399, 16128, 16192, 16208, 16209, 16206, 
+        0, 16384, 16385, 16387, 16391, 16399, 16128, 16192, 
+        0, 16384, 16385, 16387, 16391, 16399, 16128, 16192, 
+    16208,     0, 16384, 16385, 16387, 16391, 16399, 16128, 
+    16192, 16208,     0, 16384, 16385, 16387, 16391, 16399, 
+    16128, 16192, 16208, 16210,     0, 16384, 16385, 16387, 
+    16391, 16399, 16128, 16192, 16208,     0, 16384, 16385, 
+    16387, 16391, 16399, 16128, 16192, 16208, 16212,     0, 
+    16384, 16385, 16387, 16391, 16399, 16128, 16192, 16208, 
+    16212,     0, 16384, 16385, 16387, 16391, 16399, 16128, 
+    16192, 16208, 16216, 16214,     0, 16384, 16385, 16387, 
+    16391, 16399, 16128, 16192, 16208,     0, 16384, 16385, 
+    16387, 16391, 16399, 16128, 16192, 16224, 16216,     0, 
+    16384, 16385, 16387, 16391, 16399, 16128, 16192, 16224, 
+    16216,     0, 16384, 16385, 16387, 16391, 16399, 16128, 
+    16192, 16224, 16216, 16218,     0, 16384, 16385, 16387, 
+    16391, 16399, 16128, 16192, 16224, 16216,     0, 16384, 
+    16385, 16387, 16391, 16399, 16128, 16192, 16224, 16225, 
+    16220,     0, 16384, 16385, 16387, 16391, 16399, 16128, 
+    16192, 16224, 16225, 16220,     0, 16384, 16385, 16387, 
+    16391, 16399, 16128, 16192, 16224, 16225, 16220, 16222, 
+        0, 16384, 16385, 16387, 16391, 16399, 16128, 16192, 
+        0, 16384, 16385, 16387, 16391, 16399, 16128, 16256, 
+    16224,     0, 16384, 16385, 16387, 16391, 16399, 16128, 
+    16256, 16224,     0, 16384, 16385, 16387, 16391, 16399, 
+    16128, 16256, 16224, 16226,     0, 16384, 16385, 16387, 
+    16391, 16399, 16128, 16256, 16224,     0, 16384, 16385, 
+    16387, 16391, 16399, 16128, 16256, 16224, 16228,     0, 
+    16384, 16385, 16387, 16391, 16399, 16128, 16256, 16224, 
+    16228,     0, 16384, 16385, 16387, 16391, 16399, 16128, 
+    16256, 16224, 16232, 16230,     0, 16384, 16385, 16387, 
+    16391, 16399, 16128, 16256, 16224,     0, 16384, 16385, 
+    16387, 16391, 16399, 16128, 16256, 16224, 16232,     0, 
+    16384, 16385, 16387, 16391, 16399, 16128, 16256, 16224, 
+    16232,     0, 16384, 16385, 16387, 16391, 16399, 16128, 
+    16256, 16224, 16232, 16234,     0, 16384, 16385, 16387, 
+    16391, 16399, 16128, 16256, 16224, 16232,     0, 16384, 
+    16385, 16387, 16391, 16399, 16128, 16256, 16224, 16240, 
+    16236,     0, 16384, 16385, 16387, 16391, 16399, 16128, 
+    16256, 16224, 16240, 16236,     0, 16384, 16385, 16387, 
+    16391, 16399, 16128, 16256, 16224, 16240, 16241, 16238, 
+        0, 16384, 16385, 16387, 16391, 16399, 16128, 16256, 
+    16224,     0, 16384, 16385, 16387, 16391, 16399, 16128, 
+    16256, 16257, 16240,     0, 16384, 16385, 16387, 16391, 
+    16399, 16128, 16256, 16257, 16240,     0, 16384, 16385, 
+    16387, 16391, 16399, 16128, 16256, 16257, 16240, 16242, 
+        0, 16384, 16385, 16387, 16391, 16399, 16128, 16256, 
+    16257, 16240,     0, 16384, 16385, 16387, 16391, 16399, 
+    16128, 16256, 16257, 16240, 16244,     0, 16384, 16385, 
+    16387, 16391, 16399, 16128, 16256, 16257, 16240, 16244, 
+        0, 16384, 16385, 16387, 16391, 16399, 16128, 16256, 
+    16257, 16240, 16248, 16246,     0, 16384, 16385, 16387, 
+    16391, 16399, 16128, 16256, 16257, 16240,     0, 16384, 
+    16385, 16387, 16391, 16399, 16128, 16256, 16257, 16240, 
+    16248,     0, 16384, 16385, 16387, 16391, 16399, 16128, 
+    16256, 16257, 16259, 16248,     0, 16384, 16385, 16387, 
+    16391, 16399, 16128, 16256, 16257, 16259, 16248, 16250, 
+        0, 16384, 16385, 16387, 16391, 16399, 16128, 16256, 
+    16257, 16259, 16248,     0, 16384, 16385, 16387, 16391, 
+    16399, 16128, 16256, 16257, 16259, 16248, 16252,     0, 
+    16384, 16385, 16387, 16391, 16399, 16128, 16256, 16257, 
+    16259, 16248, 16252,     0, 16384, 16385, 16387, 16391, 
+    16399, 16128, 16256, 16257, 16259, 16248, 16252, 16254, 
+        0, 16384, 16385, 16387, 16391, 16399, 16128,     0, 
+    16384, 16385, 16387, 16391, 16399, 16128, 16256,     0, 
+    16384, 16385, 16387, 16391, 16399, 16128, 16256,     0, 
+    16384, 16385, 16387, 16391, 16399, 16128, 16256, 16258, 
+        0, 16384, 16385, 16387, 16391, 16399, 16128, 16256, 
+        0, 16384, 16385, 16387, 16391, 16399, 16128, 16256, 
+    16260,     0, 16384, 16385, 16387, 16391, 16399, 16128, 
+    16256, 16260,     0, 16384, 16385, 16387, 16391, 16399, 
+    16128, 16256, 16264, 16262,     0, 16384, 16385, 16387, 
+    16391, 16399, 16128, 16256,     0, 16384, 16385, 16387, 
+    16391, 16399, 16128, 16256, 16264,     0, 16384, 16385, 
+    16387, 16391, 16399, 16128, 16256, 16264,     0, 16384, 
+    16385, 16387, 16391, 16399, 16128, 16256, 16264, 16266, 
+        0, 16384, 16385, 16387, 16391, 16399, 16128, 16256, 
+    16264,     0, 16384, 16385, 16387, 16391, 16399, 16128, 
+    16256, 16272, 16268,     0, 16384, 16385, 16387, 16391, 
+    16399, 16128, 16256, 16272, 16268,     0, 16384, 16385, 
+    16387, 16391, 16399, 16128, 16256, 16272, 16273, 16270, 
+        0, 16384, 16385, 16387, 16391, 16399, 16128, 16256, 
+        0, 16384, 16385, 16387, 16391, 16399, 16128, 16256, 
+    16272,     0, 16384, 16385, 16387, 16391, 16399, 16128, 
+    16256, 16272,     0, 16384, 16385, 16387, 16391, 16399, 
+    16128, 16256, 16272, 16274,     0, 16384, 16385, 16387, 
+    16391, 16399, 16128, 16256, 16272,     0, 16384, 16385, 
+    16387, 16391, 16399, 16128, 16256, 16272, 16276,     0, 
+    16384, 16385, 16387, 16391, 16399, 16128, 16256, 16272, 
+    16276,     0, 16384, 16385, 16387, 16391, 16399, 16128, 
+    16256, 16272, 16280, 16278,     0, 16384, 16385, 16387, 
+    16391, 16399, 16128, 16256, 16272,     0, 16384, 16385, 
+    16387, 16391, 16399, 16128, 16256, 16288, 16280,     0, 
+    16384, 16385, 16387, 16391, 16399, 16128, 16256, 16288, 
+    16280,     0, 16384, 16385, 16387, 16391, 16399, 16128, 
+    16256, 16288, 16280, 16282,     0, 16384, 16385, 16387, 
+    16391, 16399, 16128, 16256, 16288, 16280,     0, 16384, 
+    16385, 16387, 16391, 16399, 16128, 16256, 16288, 16289, 
+    16284,     0, 16384, 16385, 16387, 16391, 16399, 16128, 
+    16256, 16288, 16289, 16284,     0, 16384, 16385, 16387, 
+    16391, 16399, 16128, 16256, 16288, 16289, 16284, 16286, 
+        0, 16384, 16385, 16387, 16391, 16399, 16415, 16256, 
+        0, 16384, 16385, 16387, 16391, 16399, 16415, 16256, 
+    16288,     0, 16384, 16385, 16387, 16391, 16399, 16415, 
+    16256, 16288,     0, 16384, 16385, 16387, 16391, 16399, 
+    16415, 16256, 16288, 16290,     0, 16384, 16385, 16387, 
+    16391, 16399, 16415, 16256, 16288,     0, 16384, 16385, 
+    16387, 16391, 16399, 16415, 16256, 16288, 16292,     0, 
+    16384, 16385, 16387, 16391, 16399, 16415, 16256, 16288, 
+    16292,     0, 16384, 16385, 16387, 16391, 16399, 16415, 
+    16256, 16288, 16296, 16294,     0, 16384, 16385, 16387, 
+    16391, 16399, 16415, 16256, 16288,     0, 16384, 16385, 
+    16387, 16391, 16399, 16415, 16256, 16288, 16296,     0, 
+    16384, 16385, 16387, 16391, 16399, 16415, 16256, 16288, 
+    16296,     0, 16384, 16385, 16387, 16391, 16399, 16415, 
+    16256, 16288, 16296, 16298,     0, 16384, 16385, 16387, 
+    16391, 16399, 16415, 16256, 16288, 16296,     0, 16384, 
+    16385, 16387, 16391, 16399, 16415, 16256, 16288, 16304, 
+    16300,     0, 16384, 16385, 16387, 16391, 16399, 16415, 
+    16256, 16288, 16304, 16300,     0, 16384, 16385, 16387, 
+    16391, 16399, 16415, 16256, 16288, 16304, 16305, 16302, 
+        0, 16384, 16385, 16387, 16391, 16399, 16415, 16256, 
+    16288,     0, 16384, 16385, 16387, 16391, 16399, 16415, 
+    16256, 16320, 16304,     0, 16384, 16385, 16387, 16391, 
+    16399, 16415, 16256, 16320, 16304,     0, 16384, 16385, 
+    16387, 16391, 16399, 16415, 16256, 16320, 16304, 16306, 
+        0, 16384, 16385, 16387, 16391, 16399, 16415, 16256, 
+    16320, 16304,     0, 16384, 16385, 16387, 16391, 16399, 
+    16415, 16256, 16320, 16304, 16308,     0, 16384, 16385, 
+    16387, 16391, 16399, 16415, 16256, 16320, 16304, 16308, 
+        0, 16384, 16385, 16387, 16391, 16399, 16415, 16256, 
+    16320, 16304, 16312, 16310,     0, 16384, 16385, 16387, 
+    16391, 16399, 16415, 16256, 16320, 16304,     0, 16384, 
+    16385, 16387, 16391, 16399, 16415, 16256, 16320, 16321, 
+    16312,     0, 16384, 16385, 16387, 16391, 16399, 16415, 
+    16256, 16320, 16321, 16312,     0, 16384, 16385, 16387, 
+    16391, 16399, 16415, 16256, 16320, 16321, 16312, 16314, 
+        0, 16384, 16385, 16387, 16391, 16399, 16415, 16256, 
+    16320, 16321, 16312,     0, 16384, 16385, 16387, 16391, 
+    16399, 16415, 16256, 16320, 16321, 16312, 16316,     0, 
+    16384, 16385, 16387, 16391, 16399, 16415, 16256, 16320, 
+    16321, 16323, 16316,     0, 16384, 16385, 16387, 16391, 
+    16399, 16415, 16256, 16320, 16321, 16323, 16316, 16318, 
+        0, 16384, 16385, 16387, 16391, 16399, 16415, 16256, 
+        0, 16384, 16385, 16387, 16391, 16399, 16415, 16256, 
+    16320,     0, 16384, 16385, 16387, 16391, 16399, 16415, 
+    16256, 16320,     0, 16384, 16385, 16387, 16391, 16399, 
+    16415, 16256, 16320, 16322,     0, 16384, 16385, 16387, 
+    16391, 16399, 16415, 16256, 16320,     0, 16384, 16385, 
+    16387, 16391, 16399, 16415, 16256, 16320, 16324,     0, 
+    16384, 16385, 16387, 16391, 16399, 16415, 16256, 16320, 
+    16324,     0, 16384, 16385, 16387, 16391, 16399, 16415, 
+    16256, 16320, 16328, 16326,     0, 16384, 16385, 16387, 
+    16391, 16399, 16415, 16256, 16320,     0, 16384, 16385, 
+    16387, 16391, 16399, 16415, 16256, 16320, 16328,     0, 
+    16384, 16385, 16387, 16391, 16399, 16415, 16256, 16320, 
+    16328,     0, 16384, 16385, 16387, 16391, 16399, 16415, 
+    16256, 16320, 16328, 16330,     0, 16384, 16385, 16387, 
+    16391, 16399, 16415, 16256, 16320, 16328,     0, 16384, 
+    16385, 16387, 16391, 16399, 16415, 16256, 16320, 16336, 
+    16332,     0, 16384, 16385, 16387, 16391, 16399, 16415, 
+    16256, 16320, 16336, 16332,     0, 16384, 16385, 16387, 
+    16391, 16399, 16415, 16256, 16320, 16336, 16337, 16334, 
+        0, 16384, 16385, 16387, 16391, 16399, 16415, 16256, 
+    16320,     0, 16384, 16385, 16387, 16391, 16399, 16415, 
+    16256, 16320, 16336,     0, 16384, 16385, 16387, 16391, 
+    16399, 16415, 16256, 16320, 16336,     0, 16384, 16385, 
+    16387, 16391, 16399, 16415, 16256, 16320, 16336, 16338, 
+        0, 16384, 16385, 16387, 16391, 16399, 16415, 16256, 
+    16320, 16336,     0, 16384, 16385, 16387, 16391, 16399, 
+    16415, 16256, 16320, 16336, 16340,     0, 16384, 16385, 
+    16387, 16391, 16399, 16415, 16256, 16320, 16336, 16340, 
+        0, 16384, 16385, 16387, 16391, 16399, 16415, 16256, 
+    16320, 16336, 16344, 16342,     0, 16384, 16385, 16387, 
+    16391, 16399, 16415, 16256, 16320, 16336,     0, 16384, 
+    16385, 16387, 16391, 16399, 16415, 16256, 16320, 16352, 
+    16344,     0, 16384, 16385, 16387, 16391, 16399, 16415, 
+    16256, 16320, 16352, 16344,     0, 16384, 16385, 16387, 
+    16391, 16399, 16415, 16256, 16320, 16352, 16344, 16346, 
+        0, 16384, 16385, 16387, 16391, 16399, 16415, 16256, 
+    16320, 16352, 16344,     0, 16384, 16385, 16387, 16391, 
+    16399, 16415, 16256, 16320, 16352, 16353, 16348,     0, 
+    16384, 16385, 16387, 16391, 16399, 16415, 16256, 16320, 
+    16352, 16353, 16348,     0, 16384, 16385, 16387, 16391, 
+    16399, 16415, 16256, 16320, 16352, 16353, 16348, 16350, 
+        0, 16384, 16385, 16387, 16391, 16399, 16415, 16256, 
+    16320,     0, 16384, 16385, 16387, 16391, 16399, 16415, 
+    16256, 16320, 16352,     0, 16384, 16385, 16387, 16391, 
+    16399, 16415, 16256, 16320, 16352,     0, 16384, 16385, 
+    16387, 16391, 16399, 16415, 16256, 16320, 16352, 16354, 
+        0, 16384, 16385, 16387, 16391, 16399, 16415, 16256, 
+    16320, 16352,     0, 16384, 16385, 16387, 16391, 16399, 
+    16415, 16256, 16320, 16352, 16356,     0, 16384, 16385, 
+    16387, 16391, 16399, 16415, 16256, 16320, 16352, 16356, 
+        0, 16384, 16385, 16387, 16391, 16399, 16415, 16256, 
+    16320, 16352, 16360, 16358,     0, 16384, 16385, 16387, 
+    16391, 16399, 16415, 16256, 16320, 16352,     0, 16384, 
+    16385, 16387, 16391, 16399, 16415, 16256, 16320, 16352, 
+    16360,     0, 16384, 16385, 16387, 16391, 16399, 16415, 
+    16256, 16320, 16352, 16360,     0, 16384, 16385, 16387, 
+    16391, 16399, 16415, 16256, 16320, 16352, 16360, 16362, 
+        0, 16384, 16385, 16387, 16391, 16399, 16415, 16256, 
+    16320, 16352, 16360,     0, 16384, 16385, 16387, 16391, 
+    16399, 16415, 16256, 16320, 16352, 16368, 16364,     0, 
+    16384, 16385, 16387, 16391, 16399, 16415, 16256, 16320, 
+    16352, 16368, 16364,     0, 16384, 16385, 16387, 16391, 
+    16399, 16415, 16256, 16320, 16352, 16368, 16369, 16366, 
+        0, 16384, 16385, 16387, 16391, 16399, 16415, 16256, 
+    16320, 16352,     0, 16384, 16385, 16387, 16391, 16399, 
+    16415, 16256, 16320, 16352, 16368,     0, 16384, 16385, 
+    16387, 16391, 16399, 16415, 16256, 16320, 16352, 16368, 
+        0, 16384, 16385, 16387, 16391, 16399, 16415, 16256, 
+    16320, 16352, 16368, 16370,     0, 16384, 16385, 16387, 
+    16391, 16399, 16415, 16256, 16320, 16352, 16368,     0, 
+    16384, 16385, 16387, 16391, 16399, 16415, 16256, 16320, 
+    16352, 16368, 16372,     0, 16384, 16385, 16387, 16391, 
+    16399, 16415, 16256, 16320, 16352, 16368, 16372,     0, 
+    16384, 16385, 16387, 16391, 16399, 16415, 16256, 16320, 
+    16352, 16368, 16376, 16374,     0, 16384, 16385, 16387, 
+    16391, 16399, 16415, 16256, 16320, 16352, 16368,     0, 
+    16384, 16385, 16387, 16391, 16399, 16415, 16256, 16320, 
+    16352, 16368, 16376,     0, 16384, 16385, 16387, 16391, 
+    16399, 16415, 16256, 16320, 16352, 16368, 16376,     0, 
+    16384, 16385, 16387, 16391, 16399, 16415, 16256, 16320, 
+    16352, 16368, 16376, 16378,     0, 16384, 16385, 16387, 
+    16391, 16399, 16415, 16256, 16320, 16352, 16368, 16376, 
+        0, 16384, 16385, 16387, 16391, 16399, 16415, 16256, 
+    16320, 16352, 16368, 16376, 16380,     0, 16384, 16385, 
+    16387, 16391, 16399, 16415, 16256, 16320, 16352, 16368, 
+    16376, 16380,     0, 16384, 16385, 16387, 16391, 16399, 
+    16415, 16256, 16320, 16352, 16368, 16376, 16380, 16382, 
+        0,     0, 16384,     0, 16384,     0, 16384, 16386, 
+        0, 16384,     0, 16384, 16388,     0, 16384, 16388, 
+        0, 16384, 16392, 16390,     0, 16384,     0, 16384, 
+    16392,     0, 16384, 16392,     0, 16384, 16392, 16394, 
+        0, 16384, 16392,     0, 16384, 16400, 16396,     0, 
+    16384, 16400, 16396,     0, 16384, 16400, 16401, 16398, 
+        0, 16384,     0, 16384, 16400,     0, 16384, 16400, 
+        0, 16384, 16400, 16402,     0, 16384, 16400,     0, 
+    16384, 16400, 16404,     0, 16384, 16400, 16404,     0, 
+    16384, 16400, 16408, 16406,     0, 16384, 16400,     0, 
+    16384, 16416, 16408,     0, 16384, 16416, 16408,     0, 
+    16384, 16416, 16408, 16410,     0, 16384, 16416, 16408, 
+        0, 16384, 16416, 16417, 16412,     0, 16384, 16416, 
+    16417, 16412,     0, 16384, 16416, 16417, 16412, 16414, 
+        0, 16384,     0, 16384, 16416,     0, 16384, 16416, 
+        0, 16384, 16416, 16418,     0, 16384, 16416,     0, 
+    16384, 16416, 16420,     0, 16384, 16416, 16420,     0, 
+    16384, 16416, 16424, 16422,     0, 16384, 16416,     0, 
+    16384, 16416, 16424,     0, 16384, 16416, 16424,     0, 
+    16384, 16416, 16424, 16426,     0, 16384, 16416, 16424, 
+        0, 16384, 16416, 16432, 16428,     0, 16384, 16416, 
+    16432, 16428,     0, 16384, 16416, 16432, 16433, 16430, 
+        0, 16384, 16416,     0, 16384, 16448, 16432,     0, 
+    16384, 16448, 16432,     0, 16384, 16448, 16432, 16434, 
+        0, 16384, 16448, 16432,     0, 16384, 16448, 16432, 
+    16436,     0, 16384, 16448, 16432, 16436,     0, 16384, 
+    16448, 16432, 16440, 16438,     0, 16384, 16448, 16432, 
+        0, 16384, 16448, 16449, 16440,     0, 16384, 16448, 
+    16449, 16440,     0, 16384, 16448, 16449, 16440, 16442, 
+        0, 16384, 16448, 16449, 16440,     0, 16384, 16448, 
+    16449, 16440, 16444,     0, 16384, 16448, 16449, 16451, 
+    16444,     0, 16384, 16448, 16449, 16451, 16444, 16446, 
+        0, 16384,     0, 16384, 16448,     0, 16384, 16448, 
+        0, 16384, 16448, 16450,     0, 16384, 16448,     0, 
+    16384, 16448, 16452,     0, 16384, 16448, 16452,     0, 
+    16384, 16448, 16456, 16454,     0, 16384, 16448,     0, 
+    16384, 16448, 16456,     0, 16384, 16448, 16456,     0, 
+    16384, 16448, 16456, 16458,     0, 16384, 16448, 16456, 
+        0, 16384, 16448, 16464, 16460,     0, 16384, 16448, 
+    16464, 16460,     0, 16384, 16448, 16464, 16465, 16462, 
+        0, 16384, 16448,     0, 16384, 16448, 16464,     0, 
+    16384, 16448, 16464,     0, 16384, 16448, 16464, 16466, 
+        0, 16384, 16448, 16464,     0, 16384, 16448, 16464, 
+    16468,     0, 16384, 16448, 16464, 16468,     0, 16384, 
+    16448, 16464, 16472, 16470,     0, 16384, 16448, 16464, 
+        0, 16384, 16448, 16480, 16472,     0, 16384, 16448, 
+    16480, 16472,     0, 16384, 16448, 16480, 16472, 16474, 
+        0, 16384, 16448, 16480, 16472,     0, 16384, 16448, 
+    16480, 16481, 16476,     0, 16384, 16448, 16480, 16481, 
+    16476,     0, 16384, 16448, 16480, 16481, 16476, 16478, 
+        0, 16384, 16448,     0, 16384, 16512, 16480,     0, 
+    16384, 16512, 16480,     0, 16384, 16512, 16480, 16482, 
+        0, 16384, 16512, 16480,     0, 16384, 16512, 16480, 
+    16484,     0, 16384, 16512, 16480, 16484,     0, 16384, 
+    16512, 16480, 16488, 16486,     0, 16384, 16512, 16480, 
+        0, 16384, 16512, 16480, 16488,     0, 16384, 16512, 
+    16480, 16488,     0, 16384, 16512, 16480, 16488, 16490, 
+        0, 16384, 16512, 16480, 16488,     0, 16384, 16512, 
+    16480, 16496, 16492,     0, 16384, 16512, 16480, 16496, 
+    16492,     0, 16384, 16512, 16480, 16496, 16497, 16494, 
+        0, 16384, 16512, 16480,     0, 16384, 16512, 16513, 
+    16496,     0, 16384, 16512, 16513, 16496,     0, 16384, 
+    16512, 16513, 16496, 16498,     0, 16384, 16512, 16513, 
+    16496,     0, 16384, 16512, 16513, 16496, 16500,     0, 
+    16384, 16512, 16513, 16496, 16500,     0, 16384, 16512, 
+    16513, 16496, 16504, 16502,     0, 16384, 16512, 16513, 
+    16496,     0, 16384, 16512, 16513, 16496, 16504,     0, 
+    16384, 16512, 16513, 16515, 16504,     0, 16384, 16512, 
+    16513, 16515, 16504, 16506,     0, 16384, 16512, 16513, 
+    16515, 16504,     0, 16384, 16512, 16513, 16515, 16504, 
+    16508,     0, 16384, 16512, 16513, 16515, 16504, 16508, 
+        0, 16384, 16512, 16513, 16515, 16504, 16508, 16510, 
+        0, 16384,     0, 16384, 16512,     0, 16384, 16512, 
+        0, 16384, 16512, 16514,     0, 16384, 16512,     0, 
+    16384, 16512, 16516,     0, 16384, 16512, 16516,     0, 
+    16384, 16512, 16520, 16518,     0, 16384, 16512,     0, 
+    16384, 16512, 16520,     0, 16384, 16512, 16520,     0, 
+    16384, 16512, 16520, 16522,     0, 16384, 16512, 16520, 
+        0, 16384, 16512, 16528, 16524,     0, 16384, 16512, 
+    16528, 16524,     0, 16384, 16512, 16528, 16529, 16526, 
+        0, 16384, 16512,     0, 16384, 16512, 16528,     0, 
+    16384, 16512, 16528,     0, 16384, 16512, 16528, 16530, 
+        0, 16384, 16512, 16528,     0, 16384, 16512, 16528, 
+    16532,     0, 16384, 16512, 16528, 16532,     0, 16384, 
+    16512, 16528, 16536, 16534,     0, 16384, 16512, 16528, 
+        0, 16384, 16512, 16544, 16536,     0, 16384, 16512, 
+    16544, 16536,     0, 16384, 16512, 16544, 16536, 16538, 
+        0, 16384, 16512, 16544, 16536,     0, 16384, 16512, 
+    16544, 16545, 16540,     0, 16384, 16512, 16544, 16545, 
+    16540,     0, 16384, 16512, 16544, 16545, 16540, 16542, 
+        0, 16384, 16512,     0, 16384, 16512, 16544,     0, 
+    16384, 16512, 16544,     0, 16384, 16512, 16544, 16546, 
+        0, 16384, 16512, 16544,     0, 16384, 16512, 16544, 
+    16548,     0, 16384, 16512, 16544, 16548,     0, 16384, 
+    16512, 16544, 16552, 16550,     0, 16384, 16512, 16544, 
+        0, 16384, 16512, 16544, 16552,     0, 16384, 16512, 
+    16544, 16552,     0, 16384, 16512, 16544, 16552, 16554, 
+        0, 16384, 16512, 16544, 16552,     0, 16384, 16512, 
+    16544, 16560, 16556,     0, 16384, 16512, 16544, 16560, 
+    16556,     0, 16384, 16512, 16544, 16560, 16561, 16558, 
+        0, 16384, 16512, 16544,     0, 16384, 16512, 16576, 
+    16560,     0, 16384, 16512, 16576, 16560,     0, 16384, 
+    16512, 16576, 16560, 16562,     0, 16384, 16512, 16576, 
+    16560,     0, 16384, 16512, 16576, 16560, 16564,     0, 
+    16384, 16512, 16576, 16560, 16564,     0, 16384, 16512, 
+    16576, 16560, 16568, 16566,     0, 16384, 16512, 16576, 
+    16560,     0, 16384, 16512, 16576, 16577, 16568,     0, 
+    16384, 16512, 16576, 16577, 16568,     0, 16384, 16512, 
+    16576, 16577, 16568, 16570,     0, 16384, 16512, 16576, 
+    16577, 16568,     0, 16384, 16512, 16576, 16577, 16568, 
+    16572,     0, 16384, 16512, 16576, 16577, 16579, 16572, 
+        0, 16384, 16512, 16576, 16577, 16579, 16572, 16574, 
+        0, 16384, 16512,     0, 16384, 16640, 16576,     0, 
+    16384, 16640, 16576,     0, 16384, 16640, 16576, 16578, 
+        0, 16384, 16640, 16576,     0, 16384, 16640, 16576, 
+    16580,     0, 16384, 16640, 16576, 16580,     0, 16384, 
+    16640, 16576, 16584, 16582,     0, 16384, 16640, 16576, 
+        0, 16384, 16640, 16576, 16584,     0, 16384, 16640, 
+    16576, 16584,     0, 16384, 16640, 16576, 16584, 16586, 
+        0, 16384, 16640, 16576, 16584,     0, 16384, 16640, 
+    16576, 16592, 16588,     0, 16384, 16640, 16576, 16592, 
+    16588,     0, 16384, 16640, 16576, 16592, 16593, 16590, 
+        0, 16384, 16640, 16576,     0, 16384, 16640, 16576, 
+    16592,     0, 16384, 16640, 16576, 16592,     0, 16384, 
+    16640, 16576, 16592, 16594,     0, 16384, 16640, 16576, 
+    16592,     0, 16384, 16640, 16576, 16592, 16596,     0, 
+    16384, 16640, 16576, 16592, 16596,     0, 16384, 16640, 
+    16576, 16592, 16600, 16598,     0, 16384, 16640, 16576, 
+    16592,     0, 16384, 16640, 16576, 16608, 16600,     0, 
+    16384, 16640, 16576, 16608, 16600,     0, 16384, 16640, 
+    16576, 16608, 16600, 16602,     0, 16384, 16640, 16576, 
+    16608, 16600,     0, 16384, 16640, 16576, 16608, 16609, 
+    16604,     0, 16384, 16640, 16576, 16608, 16609, 16604, 
+        0, 16384, 16640, 16576, 16608, 16609, 16604, 16606, 
+        0, 16384, 16640, 16576,     0, 16384, 16640, 16641, 
+    16608,     0, 16384, 16640, 16641, 16608,     0, 16384, 
+    16640, 16641, 16608, 16610,     0, 16384, 16640, 16641, 
+    16608,     0, 16384, 16640, 16641, 16608, 16612,     0, 
+    16384, 16640, 16641, 16608, 16612,     0, 16384, 16640, 
+    16641, 16608, 16616, 16614,     0, 16384, 16640, 16641, 
+    16608,     0, 16384, 16640, 16641, 16608, 16616,     0, 
+    16384, 16640, 16641, 16608, 16616,     0, 16384, 16640, 
+    16641, 16608, 16616, 16618,     0, 16384, 16640, 16641, 
+    16608, 16616,     0, 16384, 16640, 16641, 16608, 16624, 
+    16620,     0, 16384, 16640, 16641, 16608, 16624, 16620, 
+        0, 16384, 16640, 16641, 16608, 16624, 16625, 16622, 
+        0, 16384, 16640, 16641, 16608,     0, 16384, 16640, 
+    16641, 16608, 16624,     0, 16384, 16640, 16641, 16643, 
+    16624,     0, 16384, 16640, 16641, 16643, 16624, 16626, 
+        0, 16384, 16640, 16641, 16643, 16624,     0, 16384, 
+    16640, 16641, 16643, 16624, 16628,     0, 16384, 16640, 
+    16641, 16643, 16624, 16628,     0, 16384, 16640, 16641, 
+    16643, 16624, 16632, 16630,     0, 16384, 16640, 16641, 
+    16643, 16624,     0, 16384, 16640, 16641, 16643, 16624, 
+    16632,     0, 16384, 16640, 16641, 16643, 16624, 16632, 
+        0, 16384, 16640, 16641, 16643, 16624, 16632, 16634, 
+        0, 16384, 16640, 16641, 16643, 16647, 16632,     0, 
+    16384, 16640, 16641, 16643, 16647, 16632, 16636,     0, 
+    16384, 16640, 16641, 16643, 16647, 16632, 16636,     0, 
+    16384, 16640, 16641, 16643, 16647, 16632, 16636, 16638, 
+        0, 16384,     0, 16384, 16640,     0, 16384, 16640, 
+        0, 16384, 16640, 16642,     0, 16384, 16640,     0, 
+    16384, 16640, 16644,     0, 16384, 16640, 16644,     0, 
+    16384, 16640, 16648, 16646,     0, 16384, 16640,     0, 
+    16384, 16640, 16648,     0, 16384, 16640, 16648,     0, 
+    16384, 16640, 16648, 16650,     0, 16384, 16640, 16648, 
+        0, 16384, 16640, 16656, 16652,     0, 16384, 16640, 
+    16656, 16652,     0, 16384, 16640, 16656, 16657, 16654, 
+        0, 16384, 16640,     0, 16384, 16640, 16656,     0, 
+    16384, 16640, 16656,     0, 16384, 16640, 16656, 16658, 
+        0, 16384, 16640, 16656,     0, 16384, 16640, 16656, 
+    16660,     0, 16384, 16640, 16656, 16660,     0, 16384, 
+    16640, 16656, 16664, 16662,     0, 16384, 16640, 16656, 
+        0, 16384, 16640, 16672, 16664,     0, 16384, 16640, 
+    16672, 16664,     0, 16384, 16640, 16672, 16664, 16666, 
+        0, 16384, 16640, 16672, 16664,     0, 16384, 16640, 
+    16672, 16673, 16668,     0, 16384, 16640, 16672, 16673, 
+    16668,     0, 16384, 16640, 16672, 16673, 16668, 16670, 
+        0, 16384, 16640,     0, 16384, 16640, 16672,     0, 
+    16384, 16640, 16672,     0, 16384, 16640, 16672, 16674, 
+        0, 16384, 16640, 16672,     0, 16384, 16640, 16672, 
+    16676,     0, 16384, 16640, 16672, 16676,     0, 16384, 
+    16640, 16672, 16680, 16678,     0, 16384, 16640, 16672, 
+        0, 16384, 16640, 16672, 16680,     0, 16384, 16640, 
+    16672, 16680,     0, 16384, 16640, 16672, 16680, 16682, 
+        0, 16384, 16640, 16672, 16680,     0, 16384, 16640, 
+    16672, 16688, 16684,     0, 16384, 16640, 16672, 16688, 
+    16684,     0, 16384, 16640, 16672, 16688, 16689, 16686, 
+        0, 16384, 16640, 16672,     0, 16384, 16640, 16704, 
+    16688,     0, 16384, 16640, 16704, 16688,     0, 16384, 
+    16640, 16704, 16688, 16690,     0, 16384, 16640, 16704, 
+    16688,     0, 16384, 16640, 16704, 16688, 16692,     0, 
+    16384, 16640, 16704, 16688, 16692,     0, 16384, 16640, 
+    16704, 16688, 16696, 16694,     0, 16384, 16640, 16704, 
+    16688,     0, 16384, 16640, 16704, 16705, 16696,     0, 
+    16384, 16640, 16704, 16705, 16696,     0, 16384, 16640, 
+    16704, 16705, 16696, 16698,     0, 16384, 16640, 16704, 
+    16705, 16696,     0, 16384, 16640, 16704, 16705, 16696, 
+    16700,     0, 16384, 16640, 16704, 16705, 16707, 16700, 
+        0, 16384, 16640, 16704, 16705, 16707, 16700, 16702, 
+        0, 16384, 16640,     0, 16384, 16640, 16704,     0, 
+    16384, 16640, 16704,     0, 16384, 16640, 16704, 16706, 
+        0, 16384, 16640, 16704,     0, 16384, 16640, 16704, 
+    16708,     0, 16384, 16640, 16704, 16708,     0, 16384, 
+    16640, 16704, 16712, 16710,     0, 16384, 16640, 16704, 
+        0, 16384, 16640, 16704, 16712,     0, 16384, 16640, 
+    16704, 16712,     0, 16384, 16640, 16704, 16712, 16714, 
+        0, 16384, 16640, 16704, 16712,     0, 16384, 16640, 
+    16704, 16720, 16716,     0, 16384, 16640, 16704, 16720, 
+    16716,     0, 16384, 16640, 16704, 16720, 16721, 16718, 
+        0, 16384, 16640, 16704,     0, 16384, 16640, 16704, 
+    16720,     0, 16384, 16640, 16704, 16720,     0, 16384, 
+    16640, 16704, 16720, 16722,     0, 16384, 16640, 16704, 
+    16720,     0, 16384, 16640, 16704, 16720, 16724,     0, 
+    16384, 16640, 16704, 16720, 16724,     0, 16384, 16640, 
+    16704, 16720, 16728, 16726,     0, 16384, 16640, 16704, 
+    16720,     0, 16384, 16640, 16704, 16736, 16728,     0, 
+    16384, 16640, 16704, 16736, 16728,     0, 16384, 16640, 
+    16704, 16736, 16728, 16730,     0, 16384, 16640, 16704, 
+    16736, 16728,     0, 16384, 16640, 16704, 16736, 16737, 
+    16732,     0, 16384, 16640, 16704, 16736, 16737, 16732, 
+        0, 16384, 16640, 16704, 16736, 16737, 16732, 16734, 
+        0, 16384, 16640, 16704,     0, 16384, 16640, 16768, 
+    16736,     0, 16384, 16640, 16768, 16736,     0, 16384, 
+    16640, 16768, 16736, 16738,     0, 16384, 16640, 16768, 
+    16736,     0, 16384, 16640, 16768, 16736, 16740,     0, 
+    16384, 16640, 16768, 16736, 16740,     0, 16384, 16640, 
+    16768, 16736, 16744, 16742,     0, 16384, 16640, 16768, 
+    16736,     0, 16384, 16640, 16768, 16736, 16744,     0, 
+    16384, 16640, 16768, 16736, 16744,     0, 16384, 16640, 
+    16768, 16736, 16744, 16746,     0, 16384, 16640, 16768, 
+    16736, 16744,     0, 16384, 16640, 16768, 16736, 16752, 
+    16748,     0, 16384, 16640, 16768, 16736, 16752, 16748, 
+        0, 16384, 16640, 16768, 16736, 16752, 16753, 16750, 
+        0, 16384, 16640, 16768, 16736,     0, 16384, 16640, 
+    16768, 16769, 16752,     0, 16384, 16640, 16768, 16769, 
+    16752,     0, 16384, 16640, 16768, 16769, 16752, 16754, 
+        0, 16384, 16640, 16768, 16769, 16752,     0, 16384, 
+    16640, 16768, 16769, 16752, 16756,     0, 16384, 16640, 
+    16768, 16769, 16752, 16756,     0, 16384, 16640, 16768, 
+    16769, 16752, 16760, 16758,     0, 16384, 16640, 16768, 
+    16769, 16752,     0, 16384, 16640, 16768, 16769, 16752, 
+    16760,     0, 16384, 16640, 16768, 16769, 16771, 16760, 
+        0, 16384, 16640, 16768, 16769, 16771, 16760, 16762, 
+        0, 16384, 16640, 16768, 16769, 16771, 16760,     0, 
+    16384, 16640, 16768, 16769, 16771, 16760, 16764,     0, 
+    16384, 16640, 16768, 16769, 16771, 16760, 16764,     0, 
+    16384, 16640, 16768, 16769, 16771, 16760, 16764, 16766, 
+        0, 16384, 16640,     0, 16384, 16896, 16768,     0, 
+    16384, 16896, 16768,     0, 16384, 16896, 16768, 16770, 
+        0, 16384, 16896, 16768,     0, 16384, 16896, 16768, 
+    16772,     0, 16384, 16896, 16768, 16772,     0, 16384, 
+    16896, 16768, 16776, 16774,     0, 16384, 16896, 16768, 
+        0, 16384, 16896, 16768, 16776,     0, 16384, 16896, 
+    16768, 16776,     0, 16384, 16896, 16768, 16776, 16778, 
+        0, 16384, 16896, 16768, 16776,     0, 16384, 16896, 
+    16768, 16784, 16780,     0, 16384, 16896, 16768, 16784, 
+    16780,     0, 16384, 16896, 16768, 16784, 16785, 16782, 
+        0, 16384, 16896, 16768,     0, 16384, 16896, 16768, 
+    16784,     0, 16384, 16896, 16768, 16784,     0, 16384, 
+    16896, 16768, 16784, 16786,     0, 16384, 16896, 16768, 
+    16784,     0, 16384, 16896, 16768, 16784, 16788,     0, 
+    16384, 16896, 16768, 16784, 16788,     0, 16384, 16896, 
+    16768, 16784, 16792, 16790,     0, 16384, 16896, 16768, 
+    16784,     0, 16384, 16896, 16768, 16800, 16792,     0, 
+    16384, 16896, 16768, 16800, 16792,     0, 16384, 16896, 
+    16768, 16800, 16792, 16794,     0, 16384, 16896, 16768, 
+    16800, 16792,     0, 16384, 16896, 16768, 16800, 16801, 
+    16796,     0, 16384, 16896, 16768, 16800, 16801, 16796, 
+        0, 16384, 16896, 16768, 16800, 16801, 16796, 16798, 
+        0, 16384, 16896, 16768,     0, 16384, 16896, 16768, 
+    16800,     0, 16384, 16896, 16768, 16800,     0, 16384, 
+    16896, 16768, 16800, 16802,     0, 16384, 16896, 16768, 
+    16800,     0, 16384, 16896, 16768, 16800, 16804,     0, 
+    16384, 16896, 16768, 16800, 16804,     0, 16384, 16896, 
+    16768, 16800, 16808, 16806,     0, 16384, 16896, 16768, 
+    16800,     0, 16384, 16896, 16768, 16800, 16808,     0, 
+    16384, 16896, 16768, 16800, 16808,     0, 16384, 16896, 
+    16768, 16800, 16808, 16810,     0, 16384, 16896, 16768, 
+    16800, 16808,     0, 16384, 16896, 16768, 16800, 16816, 
+    16812,     0, 16384, 16896, 16768, 16800, 16816, 16812, 
+        0, 16384, 16896, 16768, 16800, 16816, 16817, 16814, 
+        0, 16384, 16896, 16768, 16800,     0, 16384, 16896, 
+    16768, 16832, 16816,     0, 16384, 16896, 16768, 16832, 
+    16816,     0, 16384, 16896, 16768, 16832, 16816, 16818, 
+        0, 16384, 16896, 16768, 16832, 16816,     0, 16384, 
+    16896, 16768, 16832, 16816, 16820,     0, 16384, 16896, 
+    16768, 16832, 16816, 16820,     0, 16384, 16896, 16768, 
+    16832, 16816, 16824, 16822,     0, 16384, 16896, 16768, 
+    16832, 16816,     0, 16384, 16896, 16768, 16832, 16833, 
+    16824,     0, 16384, 16896, 16768, 16832, 16833, 16824, 
+        0, 16384, 16896, 16768, 16832, 16833, 16824, 16826, 
+        0, 16384, 16896, 16768, 16832, 16833, 16824,     0, 
+    16384, 16896, 16768, 16832, 16833, 16824, 16828,     0, 
+    16384, 16896, 16768, 16832, 16833, 16835, 16828,     0, 
+    16384, 16896, 16768, 16832, 16833, 16835, 16828, 16830, 
+        0, 16384, 16896, 16768,     0, 16384, 16896, 16897, 
+    16832,     0, 16384, 16896, 16897, 16832,     0, 16384, 
+    16896, 16897, 16832, 16834,     0, 16384, 16896, 16897, 
+    16832,     0, 16384, 16896, 16897, 16832, 16836,     0, 
+    16384, 16896, 16897, 16832, 16836,     0, 16384, 16896, 
+    16897, 16832, 16840, 16838,     0, 16384, 16896, 16897, 
+    16832,     0, 16384, 16896, 16897, 16832, 16840,     0, 
+    16384, 16896, 16897, 16832, 16840,     0, 16384, 16896, 
+    16897, 16832, 16840, 16842,     0, 16384, 16896, 16897, 
+    16832, 16840,     0, 16384, 16896, 16897, 16832, 16848, 
+    16844,     0, 16384, 16896, 16897, 16832, 16848, 16844, 
+        0, 16384, 16896, 16897, 16832, 16848, 16849, 16846, 
+        0, 16384, 16896, 16897, 16832,     0, 16384, 16896, 
+    16897, 16832, 16848,     0, 16384, 16896, 16897, 16832, 
+    16848,     0, 16384, 16896, 16897, 16832, 16848, 16850, 
+        0, 16384, 16896, 16897, 16832, 16848,     0, 16384, 
+    16896, 16897, 16832, 16848, 16852,     0, 16384, 16896, 
+    16897, 16832, 16848, 16852,     0, 16384, 16896, 16897, 
+    16832, 16848, 16856, 16854,     0, 16384, 16896, 16897, 
+    16832, 16848,     0, 16384, 16896, 16897, 16832, 16864, 
+    16856,     0, 16384, 16896, 16897, 16832, 16864, 16856, 
+        0, 16384, 16896, 16897, 16832, 16864, 16856, 16858, 
+        0, 16384, 16896, 16897, 16832, 16864, 16856,     0, 
+    16384, 16896, 16897, 16832, 16864, 16865, 16860,     0, 
+    16384, 16896, 16897, 16832, 16864, 16865, 16860,     0, 
+    16384, 16896, 16897, 16832, 16864, 16865, 16860, 16862, 
+        0, 16384, 16896, 16897, 16832,     0, 16384, 16896, 
+    16897, 16832, 16864,     0, 16384, 16896, 16897, 16899, 
+    16864,     0, 16384, 16896, 16897, 16899, 16864, 16866, 
+        0, 16384, 16896, 16897, 16899, 16864,     0, 16384, 
+    16896, 16897, 16899, 16864, 16868,     0, 16384, 16896, 
+    16897, 16899, 16864, 16868,     0, 16384, 16896, 16897, 
+    16899, 16864, 16872, 16870,     0, 16384, 16896, 16897, 
+    16899, 16864,     0, 16384, 16896, 16897, 16899, 16864, 
+    16872,     0, 16384, 16896, 16897, 16899, 16864, 16872, 
+        0, 16384, 16896, 16897, 16899, 16864, 16872, 16874, 
+        0, 16384, 16896, 16897, 16899, 16864, 16872,     0, 
+    16384, 16896, 16897, 16899, 16864, 16880, 16876,     0, 
+    16384, 16896, 16897, 16899, 16864, 16880, 16876,     0, 
+    16384, 16896, 16897, 16899, 16864, 16880, 16881, 16878, 
+        0, 16384, 16896, 16897, 16899, 16864,     0, 16384, 
+    16896, 16897, 16899, 16864, 16880,     0, 16384, 16896, 
+    16897, 16899, 16864, 16880,     0, 16384, 16896, 16897, 
+    16899, 16864, 16880, 16882,     0, 16384, 16896, 16897, 
+    16899, 16903, 16880,     0, 16384, 16896, 16897, 16899, 
+    16903, 16880, 16884,     0, 16384, 16896, 16897, 16899, 
+    16903, 16880, 16884,     0, 16384, 16896, 16897, 16899, 
+    16903, 16880, 16888, 16886,     0, 16384, 16896, 16897, 
+    16899, 16903, 16880,     0, 16384, 16896, 16897, 16899, 
+    16903, 16880, 16888,     0, 16384, 16896, 16897, 16899, 
+    16903, 16880, 16888,     0, 16384, 16896, 16897, 16899, 
+    16903, 16880, 16888, 16890,     0, 16384, 16896, 16897, 
+    16899, 16903, 16880, 16888,     0, 16384, 16896, 16897, 
+    16899, 16903, 16880, 16888, 16892,     0, 16384, 16896, 
+    16897, 16899, 16903, 16880, 16888, 16892,     0, 16384, 
+    16896, 16897, 16899, 16903, 16880, 16888, 16892, 16894, 
+        0, 16384,     0, 16384, 16896,     0, 16384, 16896, 
+        0, 16384, 16896, 16898,     0, 16384, 16896,     0, 
+    16384, 16896, 16900,     0, 16384, 16896, 16900,     0, 
+    16384, 16896, 16904, 16902,     0, 16384, 16896,     0, 
+    16384, 16896, 16904,     0, 16384, 16896, 16904,     0, 
+    16384, 16896, 16904, 16906,     0, 16384, 16896, 16904, 
+        0, 16384, 16896, 16912, 16908,     0, 16384, 16896, 
+    16912, 16908,     0, 16384, 16896, 16912, 16913, 16910, 
+        0, 16384, 16896,     0, 16384, 16896, 16912,     0, 
+    16384, 16896, 16912,     0, 16384, 16896, 16912, 16914, 
+        0, 16384, 16896, 16912,     0, 16384, 16896, 16912, 
+    16916,     0, 16384, 16896, 16912, 16916,     0, 16384, 
+    16896, 16912, 16920, 16918,     0, 16384, 16896, 16912, 
+        0, 16384, 16896, 16928, 16920,     0, 16384, 16896, 
+    16928, 16920,     0, 16384, 16896, 16928, 16920, 16922, 
+        0, 16384, 16896, 16928, 16920,     0, 16384, 16896, 
+    16928, 16929, 16924,     0, 16384, 16896, 16928, 16929, 
+    16924,     0, 16384, 16896, 16928, 16929, 16924, 16926, 
+        0, 16384, 16896,     0, 16384, 16896, 16928,     0, 
+    16384, 16896, 16928,     0, 16384, 16896, 16928, 16930, 
+        0, 16384, 16896, 16928,     0, 16384, 16896, 16928, 
+    16932,     0, 16384, 16896, 16928, 16932,     0, 16384, 
+    16896, 16928, 16936, 16934,     0, 16384, 16896, 16928, 
+        0, 16384, 16896, 16928, 16936,     0, 16384, 16896, 
+    16928, 16936,     0, 16384, 16896, 16928, 16936, 16938, 
+        0, 16384, 16896, 16928, 16936,     0, 16384, 16896, 
+    16928, 16944, 16940,     0, 16384, 16896, 16928, 16944, 
+    16940,     0, 16384, 16896, 16928, 16944, 16945, 16942, 
+        0, 16384, 16896, 16928,     0, 16384, 16896, 16960, 
+    16944,     0, 16384, 16896, 16960, 16944,     0, 16384, 
+    16896, 16960, 16944, 16946,     0, 16384, 16896, 16960, 
+    16944,     0, 16384, 16896, 16960, 16944, 16948,     0, 
+    16384, 16896, 16960, 16944, 16948,     0, 16384, 16896, 
+    16960, 16944, 16952, 16950,     0, 16384, 16896, 16960, 
+    16944,     0, 16384, 16896, 16960, 16961, 16952,     0, 
+    16384, 16896, 16960, 16961, 16952,     0, 16384, 16896, 
+    16960, 16961, 16952, 16954,     0, 16384, 16896, 16960, 
+    16961, 16952,     0, 16384, 16896, 16960, 16961, 16952, 
+    16956,     0, 16384, 16896, 16960, 16961, 16963, 16956, 
+        0, 16384, 16896, 16960, 16961, 16963, 16956, 16958, 
+        0, 16384, 16896,     0, 16384, 16896, 16960,     0, 
+    16384, 16896, 16960,     0, 16384, 16896, 16960, 16962, 
+        0, 16384, 16896, 16960,     0, 16384, 16896, 16960, 
+    16964,     0, 16384, 16896, 16960, 16964,     0, 16384, 
+    16896, 16960, 16968, 16966,     0, 16384, 16896, 16960, 
+        0, 16384, 16896, 16960, 16968,     0, 16384, 16896, 
+    16960, 16968,     0, 16384, 16896, 16960, 16968, 16970, 
+        0, 16384, 16896, 16960, 16968,     0, 16384, 16896, 
+    16960, 16976, 16972,     0, 16384, 16896, 16960, 16976, 
+    16972,     0, 16384, 16896, 16960, 16976, 16977, 16974, 
+        0, 16384, 16896, 16960,     0, 16384, 16896, 16960, 
+    16976,     0, 16384, 16896, 16960, 16976,     0, 16384, 
+    16896, 16960, 16976, 16978,     0, 16384, 16896, 16960, 
+    16976,     0, 16384, 16896, 16960, 16976, 16980,     0, 
+    16384, 16896, 16960, 16976, 16980,     0, 16384, 16896, 
+    16960, 16976, 16984, 16982,     0, 16384, 16896, 16960, 
+    16976,     0, 16384, 16896, 16960, 16992, 16984,     0, 
+    16384, 16896, 16960, 16992, 16984,     0, 16384, 16896, 
+    16960, 16992, 16984, 16986,     0, 16384, 16896, 16960, 
+    16992, 16984,     0, 16384, 16896, 16960, 16992, 16993, 
+    16988,     0, 16384, 16896, 16960, 16992, 16993, 16988, 
+        0, 16384, 16896, 16960, 16992, 16993, 16988, 16990, 
+        0, 16384, 16896, 16960,     0, 16384, 16896, 17024, 
+    16992,     0, 16384, 16896, 17024, 16992,     0, 16384, 
+    16896, 17024, 16992, 16994,     0, 16384, 16896, 17024, 
+    16992,     0, 16384, 16896, 17024, 16992, 16996,     0, 
+    16384, 16896, 17024, 16992, 16996,     0, 16384, 16896, 
+    17024, 16992, 17000, 16998,     0, 16384, 16896, 17024, 
+    16992,     0, 16384, 16896, 17024, 16992, 17000,     0, 
+    16384, 16896, 17024, 16992, 17000,     0, 16384, 16896, 
+    17024, 16992, 17000, 17002,     0, 16384, 16896, 17024, 
+    16992, 17000,     0, 16384, 16896, 17024, 16992, 17008, 
+    17004,     0, 16384, 16896, 17024, 16992, 17008, 17004, 
+        0, 16384, 16896, 17024, 16992, 17008, 17009, 17006, 
+        0, 16384, 16896, 17024, 16992,     0, 16384, 16896, 
+    17024, 17025, 17008,     0, 16384, 16896, 17024, 17025, 
+    17008,     0, 16384, 16896, 17024, 17025, 17008, 17010, 
+        0, 16384, 16896, 17024, 17025, 17008,     0, 16384, 
+    16896, 17024, 17025, 17008, 17012,     0, 16384, 16896, 
+    17024, 17025, 17008, 17012,     0, 16384, 16896, 17024, 
+    17025, 17008, 17016, 17014,     0, 16384, 16896, 17024, 
+    17025, 17008,     0, 16384, 16896, 17024, 17025, 17008, 
+    17016,     0, 16384, 16896, 17024, 17025, 17027, 17016, 
+        0, 16384, 16896, 17024, 17025, 17027, 17016, 17018, 
+        0, 16384, 16896, 17024, 17025, 17027, 17016,     0, 
+    16384, 16896, 17024, 17025, 17027, 17016, 17020,     0, 
+    16384, 16896, 17024, 17025, 17027, 17016, 17020,     0, 
+    16384, 16896, 17024, 17025, 17027, 17016, 17020, 17022, 
+        0, 16384, 16896,     0, 16384, 16896, 17024,     0, 
+    16384, 16896, 17024,     0, 16384, 16896, 17024, 17026, 
+        0, 16384, 16896, 17024,     0, 16384, 16896, 17024, 
+    17028,     0, 16384, 16896, 17024, 17028,     0, 16384, 
+    16896, 17024, 17032, 17030,     0, 16384, 16896, 17024, 
+        0, 16384, 16896, 17024, 17032,     0, 16384, 16896, 
+    17024, 17032,     0, 16384, 16896, 17024, 17032, 17034, 
+        0, 16384, 16896, 17024, 17032,     0, 16384, 16896, 
+    17024, 17040, 17036,     0, 16384, 16896, 17024, 17040, 
+    17036,     0, 16384, 16896, 17024, 17040, 17041, 17038, 
+        0, 16384, 16896, 17024,     0, 16384, 16896, 17024, 
+    17040,     0, 16384, 16896, 17024, 17040,     0, 16384, 
+    16896, 17024, 17040, 17042,     0, 16384, 16896, 17024, 
+    17040,     0, 16384, 16896, 17024, 17040, 17044,     0, 
+    16384, 16896, 17024, 17040, 17044,     0, 16384, 16896, 
+    17024, 17040, 17048, 17046,     0, 16384, 16896, 17024, 
+    17040,     0, 16384, 16896, 17024, 17056, 17048,     0, 
+    16384, 16896, 17024, 17056, 17048,     0, 16384, 16896, 
+    17024, 17056, 17048, 17050,     0, 16384, 16896, 17024, 
+    17056, 17048,     0, 16384, 16896, 17024, 17056, 17057, 
+    17052,     0, 16384, 16896, 17024, 17056, 17057, 17052, 
+        0, 16384, 16896, 17024, 17056, 17057, 17052, 17054, 
+        0, 16384, 16896, 17024,     0, 16384, 16896, 17024, 
+    17056,     0, 16384, 16896, 17024, 17056,     0, 16384, 
+    16896, 17024, 17056, 17058,     0, 16384, 16896, 17024, 
+    17056,     0, 16384, 16896, 17024, 17056, 17060,     0, 
+    16384, 16896, 17024, 17056, 17060,     0, 16384, 16896, 
+    17024, 17056, 17064, 17062,     0, 16384, 16896, 17024, 
+    17056,     0, 16384, 16896, 17024, 17056, 17064,     0, 
+    16384, 16896, 17024, 17056, 17064,     0, 16384, 16896, 
+    17024, 17056, 17064, 17066,     0, 16384, 16896, 17024, 
+    17056, 17064,     0, 16384, 16896, 17024, 17056, 17072, 
+    17068,     0, 16384, 16896, 17024, 17056, 17072, 17068, 
+        0, 16384, 16896, 17024, 17056, 17072, 17073, 17070, 
+        0, 16384, 16896, 17024, 17056,     0, 16384, 16896, 
+    17024, 17088, 17072,     0, 16384, 16896, 17024, 17088, 
+    17072,     0, 16384, 16896, 17024, 17088, 17072, 17074, 
+        0, 16384, 16896, 17024, 17088, 17072,     0, 16384, 
+    16896, 17024, 17088, 17072, 17076,     0, 16384, 16896, 
+    17024, 17088, 17072, 17076,     0, 16384, 16896, 17024, 
+    17088, 17072, 17080, 17078,     0, 16384, 16896, 17024, 
+    17088, 17072,     0, 16384, 16896, 17024, 17088, 17089, 
+    17080,     0, 16384, 16896, 17024, 17088, 17089, 17080, 
+        0, 16384, 16896, 17024, 17088, 17089, 17080, 17082, 
+        0, 16384, 16896, 17024, 17088, 17089, 17080,     0, 
+    16384, 16896, 17024, 17088, 17089, 17080, 17084,     0, 
+    16384, 16896, 17024, 17088, 17089, 17091, 17084,     0, 
+    16384, 16896, 17024, 17088, 17089, 17091, 17084, 17086, 
+        0, 16384, 16896, 17024,     0, 16384, 16896, 17152, 
+    17088,     0, 16384, 16896, 17152, 17088,     0, 16384, 
+    16896, 17152, 17088, 17090,     0, 16384, 16896, 17152, 
+    17088,     0, 16384, 16896, 17152, 17088, 17092,     0, 
+    16384, 16896, 17152, 17088, 17092,     0, 16384, 16896, 
+    17152, 17088, 17096, 17094,     0, 16384, 16896, 17152, 
+    17088,     0, 16384, 16896, 17152, 17088, 17096,     0, 
+    16384, 16896, 17152, 17088, 17096,     0, 16384, 16896, 
+    17152, 17088, 17096, 17098,     0, 16384, 16896, 17152, 
+    17088, 17096,     0, 16384, 16896, 17152, 17088, 17104, 
+    17100,     0, 16384, 16896, 17152, 17088, 17104, 17100, 
+        0, 16384, 16896, 17152, 17088, 17104, 17105, 17102, 
+        0, 16384, 16896, 17152, 17088,     0, 16384, 16896, 
+    17152, 17088, 17104,     0, 16384, 16896, 17152, 17088, 
+    17104,     0, 16384, 16896, 17152, 17088, 17104, 17106, 
+        0, 16384, 16896, 17152, 17088, 17104,     0, 16384, 
+    16896, 17152, 17088, 17104, 17108,     0, 16384, 16896, 
+    17152, 17088, 17104, 17108,     0, 16384, 16896, 17152, 
+    17088, 17104, 17112, 17110,     0, 16384, 16896, 17152, 
+    17088, 17104,     0, 16384, 16896, 17152, 17088, 17120, 
+    17112,     0, 16384, 16896, 17152, 17088, 17120, 17112, 
+        0, 16384, 16896, 17152, 17088, 17120, 17112, 17114, 
+        0, 16384, 16896, 17152, 17088, 17120, 17112,     0, 
+    16384, 16896, 17152, 17088, 17120, 17121, 17116,     0, 
+    16384, 16896, 17152, 17088, 17120, 17121, 17116,     0, 
+    16384, 16896, 17152, 17088, 17120, 17121, 17116, 17118, 
+        0, 16384, 16896, 17152, 17088,     0, 16384, 16896, 
+    17152, 17153, 17120,     0, 16384, 16896, 17152, 17153, 
+    17120,     0, 16384, 16896, 17152, 17153, 17120, 17122, 
+        0, 16384, 16896, 17152, 17153, 17120,     0, 16384, 
+    16896, 17152, 17153, 17120, 17124,     0, 16384, 16896, 
+    17152, 17153, 17120, 17124,     0, 16384, 16896, 17152, 
+    17153, 17120, 17128, 17126,     0, 16384, 16896, 17152, 
+    17153, 17120,     0, 16384, 16896, 17152, 17153, 17120, 
+    17128,     0, 16384, 16896, 17152, 17153, 17120, 17128, 
+        0, 16384, 16896, 17152, 17153, 17120, 17128, 17130, 
+        0, 16384, 16896, 17152, 17153, 17120, 17128,     0, 
+    16384, 16896, 17152, 17153, 17120, 17136, 17132,     0, 
+    16384, 16896, 17152, 17153, 17120, 17136, 17132,     0, 
+    16384, 16896, 17152, 17153, 17120, 17136, 17137, 17134, 
+        0, 16384, 16896, 17152, 17153, 17120,     0, 16384, 
+    16896, 17152, 17153, 17120, 17136,     0, 16384, 16896, 
+    17152, 17153, 17155, 17136,     0, 16384, 16896, 17152, 
+    17153, 17155, 17136, 17138,     0, 16384, 16896, 17152, 
+    17153, 17155, 17136,     0, 16384, 16896, 17152, 17153, 
+    17155, 17136, 17140,     0, 16384, 16896, 17152, 17153, 
+    17155, 17136, 17140,     0, 16384, 16896, 17152, 17153, 
+    17155, 17136, 17144, 17142,     0, 16384, 16896, 17152, 
+    17153, 17155, 17136,     0, 16384, 16896, 17152, 17153, 
+    17155, 17136, 17144,     0, 16384, 16896, 17152, 17153, 
+    17155, 17136, 17144,     0, 16384, 16896, 17152, 17153, 
+    17155, 17136, 17144, 17146,     0, 16384, 16896, 17152, 
+    17153, 17155, 17159, 17144,     0, 16384, 16896, 17152, 
+    17153, 17155, 17159, 17144, 17148,     0, 16384, 16896, 
+    17152, 17153, 17155, 17159, 17144, 17148,     0, 16384, 
+    16896, 17152, 17153, 17155, 17159, 17144, 17148, 17150, 
+        0, 16384, 16896,     0, 16384, 17408, 17152,     0, 
+    16384, 17408, 17152,     0, 16384, 17408, 17152, 17154, 
+        0, 16384, 17408, 17152,     0, 16384, 17408, 17152, 
+    17156,     0, 16384, 17408, 17152, 17156,     0, 16384, 
+    17408, 17152, 17160, 17158,     0, 16384, 17408, 17152, 
+        0, 16384, 17408, 17152, 17160,     0, 16384, 17408, 
+    17152, 17160,     0, 16384, 17408, 17152, 17160, 17162, 
+        0, 16384, 17408, 17152, 17160,     0, 16384, 17408, 
+    17152, 17168, 17164,     0, 16384, 17408, 17152, 17168, 
+    17164,     0, 16384, 17408, 17152, 17168, 17169, 17166, 
+        0, 16384, 17408, 17152,     0, 16384, 17408, 17152, 
+    17168,     0, 16384, 17408, 17152, 17168,     0, 16384, 
+    17408, 17152, 17168, 17170,     0, 16384, 17408, 17152, 
+    17168,     0, 16384, 17408, 17152, 17168, 17172,     0, 
+    16384, 17408, 17152, 17168, 17172,     0, 16384, 17408, 
+    17152, 17168, 17176, 17174,     0, 16384, 17408, 17152, 
+    17168,     0, 16384, 17408, 17152, 17184, 17176,     0, 
+    16384, 17408, 17152, 17184, 17176,     0, 16384, 17408, 
+    17152, 17184, 17176, 17178,     0, 16384, 17408, 17152, 
+    17184, 17176,     0, 16384, 17408, 17152, 17184, 17185, 
+    17180,     0, 16384, 17408, 17152, 17184, 17185, 17180, 
+        0, 16384, 17408, 17152, 17184, 17185, 17180, 17182, 
+        0, 16384, 17408, 17152,     0, 16384, 17408, 17152, 
+    17184,     0, 16384, 17408, 17152, 17184,     0, 16384, 
+    17408, 17152, 17184, 17186,     0, 16384, 17408, 17152, 
+    17184,     0, 16384, 17408, 17152, 17184, 17188,     0, 
+    16384, 17408, 17152, 17184, 17188,     0, 16384, 17408, 
+    17152, 17184, 17192, 17190,     0, 16384, 17408, 17152, 
+    17184,     0, 16384, 17408, 17152, 17184, 17192,     0, 
+    16384, 17408, 17152, 17184, 17192,     0, 16384, 17408, 
+    17152, 17184, 17192, 17194,     0, 16384, 17408, 17152, 
+    17184, 17192,     0, 16384, 17408, 17152, 17184, 17200, 
+    17196,     0, 16384, 17408, 17152, 17184, 17200, 17196, 
+        0, 16384, 17408, 17152, 17184, 17200, 17201, 17198, 
+        0, 16384, 17408, 17152, 17184,     0, 16384, 17408, 
+    17152, 17216, 17200,     0, 16384, 17408, 17152, 17216, 
+    17200,     0, 16384, 17408, 17152, 17216, 17200, 17202, 
+        0, 16384, 17408, 17152, 17216, 17200,     0, 16384, 
+    17408, 17152, 17216, 17200, 17204,     0, 16384, 17408, 
+    17152, 17216, 17200, 17204,     0, 16384, 17408, 17152, 
+    17216, 17200, 17208, 17206,     0, 16384, 17408, 17152, 
+    17216, 17200,     0, 16384, 17408, 17152, 17216, 17217, 
+    17208,     0, 16384, 17408, 17152, 17216, 17217, 17208, 
+        0, 16384, 17408, 17152, 17216, 17217, 17208, 17210, 
+        0, 16384, 17408, 17152, 17216, 17217, 17208,     0, 
+    16384, 17408, 17152, 17216, 17217, 17208, 17212,     0, 
+    16384, 17408, 17152, 17216, 17217, 17219, 17212,     0, 
+    16384, 17408, 17152, 17216, 17217, 17219, 17212, 17214, 
+        0, 16384, 17408, 17152,     0, 16384, 17408, 17152, 
+    17216,     0, 16384, 17408, 17152, 17216,     0, 16384, 
+    17408, 17152, 17216, 17218,     0, 16384, 17408, 17152, 
+    17216,     0, 16384, 17408, 17152, 17216, 17220,     0, 
+    16384, 17408, 17152, 17216, 17220,     0, 16384, 17408, 
+    17152, 17216, 17224, 17222,     0, 16384, 17408, 17152, 
+    17216,     0, 16384, 17408, 17152, 17216, 17224,     0, 
+    16384, 17408, 17152, 17216, 17224,     0, 16384, 17408, 
+    17152, 17216, 17224, 17226,     0, 16384, 17408, 17152, 
+    17216, 17224,     0, 16384, 17408, 17152, 17216, 17232, 
+    17228,     0, 16384, 17408, 17152, 17216, 17232, 17228, 
+        0, 16384, 17408, 17152, 17216, 17232, 17233, 17230, 
+        0, 16384, 17408, 17152, 17216,     0, 16384, 17408, 
+    17152, 17216, 17232,     0, 16384, 17408, 17152, 17216, 
+    17232,     0, 16384, 17408, 17152, 17216, 17232, 17234, 
+        0, 16384, 17408, 17152, 17216, 17232,     0, 16384, 
+    17408, 17152, 17216, 17232, 17236,     0, 16384, 17408, 
+    17152, 17216, 17232, 17236,     0, 16384, 17408, 17152, 
+    17216, 17232, 17240, 17238,     0, 16384, 17408, 17152, 
+    17216, 17232,     0, 16384, 17408, 17152, 17216, 17248, 
+    17240,     0, 16384, 17408, 17152, 17216, 17248, 17240, 
+        0, 16384, 17408, 17152, 17216, 17248, 17240, 17242, 
+        0, 16384, 17408, 17152, 17216, 17248, 17240,     0, 
+    16384, 17408, 17152, 17216, 17248, 17249, 17244,     0, 
+    16384, 17408, 17152, 17216, 17248, 17249, 17244,     0, 
+    16384, 17408, 17152, 17216, 17248, 17249, 17244, 17246, 
+        0, 16384, 17408, 17152, 17216,     0, 16384, 17408, 
+    17152, 17280, 17248,     0, 16384, 17408, 17152, 17280, 
+    17248,     0, 16384, 17408, 17152, 17280, 17248, 17250, 
+        0, 16384, 17408, 17152, 17280, 17248,     0, 16384, 
+    17408, 17152, 17280, 17248, 17252,     0, 16384, 17408, 
+    17152, 17280, 17248, 17252,     0, 16384, 17408, 17152, 
+    17280, 17248, 17256, 17254,     0, 16384, 17408, 17152, 
+    17280, 17248,     0, 16384, 17408, 17152, 17280, 17248, 
+    17256,     0, 16384, 17408, 17152, 17280, 17248, 17256, 
+        0, 16384, 17408, 17152, 17280, 17248, 17256, 17258, 
+        0, 16384, 17408, 17152, 17280, 17248, 17256,     0, 
+    16384, 17408, 17152, 17280, 17248, 17264, 17260,     0, 
+    16384, 17408, 17152, 17280, 17248, 17264, 17260,     0, 
+    16384, 17408, 17152, 17280, 17248, 17264, 17265, 17262, 
+        0, 16384, 17408, 17152, 17280, 17248,     0, 16384, 
+    17408, 17152, 17280, 17281, 17264,     0, 16384, 17408, 
+    17152, 17280, 17281, 17264,     0, 16384, 17408, 17152, 
+    17280, 17281, 17264, 17266,     0, 16384, 17408, 17152, 
+    17280, 17281, 17264,     0, 16384, 17408, 17152, 17280, 
+    17281, 17264, 17268,     0, 16384, 17408, 17152, 17280, 
+    17281, 17264, 17268,     0, 16384, 17408, 17152, 17280, 
+    17281, 17264, 17272, 17270,     0, 16384, 17408, 17152, 
+    17280, 17281, 17264,     0, 16384, 17408, 17152, 17280, 
+    17281, 17264, 17272,     0, 16384, 17408, 17152, 17280, 
+    17281, 17283, 17272,     0, 16384, 17408, 17152, 17280, 
+    17281, 17283, 17272, 17274,     0, 16384, 17408, 17152, 
+    17280, 17281, 17283, 17272,     0, 16384, 17408, 17152, 
+    17280, 17281, 17283, 17272, 17276,     0, 16384, 17408, 
+    17152, 17280, 17281, 17283, 17272, 17276,     0, 16384, 
+    17408, 17152, 17280, 17281, 17283, 17272, 17276, 17278, 
+        0, 16384, 17408, 17152,     0, 16384, 17408, 17152, 
+    17280,     0, 16384, 17408, 17409, 17280,     0, 16384, 
+    17408, 17409, 17280, 17282,     0, 16384, 17408, 17409, 
+    17280,     0, 16384, 17408, 17409, 17280, 17284,     0, 
+    16384, 17408, 17409, 17280, 17284,     0, 16384, 17408, 
+    17409, 17280, 17288, 17286,     0, 16384, 17408, 17409, 
+    17280,     0, 16384, 17408, 17409, 17280, 17288,     0, 
+    16384, 17408, 17409, 17280, 17288,     0, 16384, 17408, 
+    17409, 17280, 17288, 17290,     0, 16384, 17408, 17409, 
+    17280, 17288,     0, 16384, 17408, 17409, 17280, 17296, 
+    17292,     0, 16384, 17408, 17409, 17280, 17296, 17292, 
+        0, 16384, 17408, 17409, 17280, 17296, 17297, 17294, 
+        0, 16384, 17408, 17409, 17280,     0, 16384, 17408, 
+    17409, 17280, 17296,     0, 16384, 17408, 17409, 17280, 
+    17296,     0, 16384, 17408, 17409, 17280, 17296, 17298, 
+        0, 16384, 17408, 17409, 17280, 17296,     0, 16384, 
+    17408, 17409, 17280, 17296, 17300,     0, 16384, 17408, 
+    17409, 17280, 17296, 17300,     0, 16384, 17408, 17409, 
+    17280, 17296, 17304, 17302,     0, 16384, 17408, 17409, 
+    17280, 17296,     0, 16384, 17408, 17409, 17280, 17312, 
+    17304,     0, 16384, 17408, 17409, 17280, 17312, 17304, 
+        0, 16384, 17408, 17409, 17280, 17312, 17304, 17306, 
+        0, 16384, 17408, 17409, 17280, 17312, 17304,     0, 
+    16384, 17408, 17409, 17280, 17312, 17313, 17308,     0, 
+    16384, 17408, 17409, 17280, 17312, 17313, 17308,     0, 
+    16384, 17408, 17409, 17280, 17312, 17313, 17308, 17310, 
+        0, 16384, 17408, 17409, 17280,     0, 16384, 17408, 
+    17409, 17280, 17312,     0, 16384, 17408, 17409, 17280, 
+    17312,     0, 16384, 17408, 17409, 17280, 17312, 17314, 
+        0, 16384, 17408, 17409, 17280, 17312,     0, 16384, 
+    17408, 17409, 17280, 17312, 17316,     0, 16384, 17408, 
+    17409, 17280, 17312, 17316,     0, 16384, 17408, 17409, 
+    17280, 17312, 17320, 17318,     0, 16384, 17408, 17409, 
+    17280, 17312,     0, 16384, 17408, 17409, 17280, 17312, 
+    17320,     0, 16384, 17408, 17409, 17280, 17312, 17320, 
+        0, 16384, 17408, 17409, 17280, 17312, 17320, 17322, 
+        0, 16384, 17408, 17409, 17280, 17312, 17320,     0, 
+    16384, 17408, 17409, 17280, 17312, 17328, 17324,     0, 
+    16384, 17408, 17409, 17280, 17312, 17328, 17324,     0, 
+    16384, 17408, 17409, 17280, 17312, 17328, 17329, 17326, 
+        0, 16384, 17408, 17409, 17280, 17312,     0, 16384, 
+    17408, 17409, 17280, 17344, 17328,     0, 16384, 17408, 
+    17409, 17280, 17344, 17328,     0, 16384, 17408, 17409, 
+    17280, 17344, 17328, 17330,     0, 16384, 17408, 17409, 
+    17280, 17344, 17328,     0, 16384, 17408, 17409, 17280, 
+    17344, 17328, 17332,     0, 16384, 17408, 17409, 17280, 
+    17344, 17328, 17332,     0, 16384, 17408, 17409, 17280, 
+    17344, 17328, 17336, 17334,     0, 16384, 17408, 17409, 
+    17280, 17344, 17328,     0, 16384, 17408, 17409, 17280, 
+    17344, 17345, 17336,     0, 16384, 17408, 17409, 17280, 
+    17344, 17345, 17336,     0, 16384, 17408, 17409, 17280, 
+    17344, 17345, 17336, 17338,     0, 16384, 17408, 17409, 
+    17280, 17344, 17345, 17336,     0, 16384, 17408, 17409, 
+    17280, 17344, 17345, 17336, 17340,     0, 16384, 17408, 
+    17409, 17280, 17344, 17345, 17347, 17340,     0, 16384, 
+    17408, 17409, 17280, 17344, 17345, 17347, 17340, 17342, 
+        0, 16384, 17408, 17409, 17280,     0, 16384, 17408, 
+    17409, 17280, 17344,     0, 16384, 17408, 17409, 17280, 
+    17344,     0, 16384, 17408, 17409, 17280, 17344, 17346, 
+        0, 16384, 17408, 17409, 17411, 17344,     0, 16384, 
+    17408, 17409, 17411, 17344, 17348,     0, 16384, 17408, 
+    17409, 17411, 17344, 17348,     0, 16384, 17408, 17409, 
+    17411, 17344, 17352, 17350,     0, 16384, 17408, 17409, 
+    17411, 17344,     0, 16384, 17408, 17409, 17411, 17344, 
+    17352,     0, 16384, 17408, 17409, 17411, 17344, 17352, 
+        0, 16384, 17408, 17409, 17411, 17344, 17352, 17354, 
+        0, 16384, 17408, 17409, 17411, 17344, 17352,     0, 
+    16384, 17408, 17409, 17411, 17344, 17360, 17356,     0, 
+    16384, 17408, 17409, 17411, 17344, 17360, 17356,     0, 
+    16384, 17408, 17409, 17411, 17344, 17360, 17361, 17358, 
+        0, 16384, 17408, 17409, 17411, 17344,     0, 16384, 
+    17408, 17409, 17411, 17344, 17360,     0, 16384, 17408, 
+    17409, 17411, 17344, 17360,     0, 16384, 17408, 17409, 
+    17411, 17344, 17360, 17362,     0, 16384, 17408, 17409, 
+    17411, 17344, 17360,     0, 16384, 17408, 17409, 17411, 
+    17344, 17360, 17364,     0, 16384, 17408, 17409, 17411, 
+    17344, 17360, 17364,     0, 16384, 17408, 17409, 17411, 
+    17344, 17360, 17368, 17366,     0, 16384, 17408, 17409, 
+    17411, 17344, 17360,     0, 16384, 17408, 17409, 17411, 
+    17344, 17376, 17368,     0, 16384, 17408, 17409, 17411, 
+    17344, 17376, 17368,     0, 16384, 17408, 17409, 17411, 
+    17344, 17376, 17368, 17370,     0, 16384, 17408, 17409, 
+    17411, 17344, 17376, 17368,     0, 16384, 17408, 17409, 
+    17411, 17344, 17376, 17377, 17372,     0, 16384, 17408, 
+    17409, 17411, 17344, 17376, 17377, 17372,     0, 16384, 
+    17408, 17409, 17411, 17344, 17376, 17377, 17372, 17374, 
+        0, 16384, 17408, 17409, 17411, 17344,     0, 16384, 
+    17408, 17409, 17411, 17344, 17376,     0, 16384, 17408, 
+    17409, 17411, 17344, 17376,     0, 16384, 17408, 17409, 
+    17411, 17344, 17376, 17378,     0, 16384, 17408, 17409, 
+    17411, 17344, 17376,     0, 16384, 17408, 17409, 17411, 
+    17344, 17376, 17380,     0, 16384, 17408, 17409, 17411, 
+    17344, 17376, 17380,     0, 16384, 17408, 17409, 17411, 
+    17344, 17376, 17384, 17382,     0, 16384, 17408, 17409, 
+    17411, 17415, 17376,     0, 16384, 17408, 17409, 17411, 
+    17415, 17376, 17384,     0, 16384, 17408, 17409, 17411, 
+    17415, 17376, 17384,     0, 16384, 17408, 17409, 17411, 
+    17415, 17376, 17384, 17386,     0, 16384, 17408, 17409, 
+    17411, 17415, 17376, 17384,     0, 16384, 17408, 17409, 
+    17411, 17415, 17376, 17392, 17388,     0, 16384, 17408, 
+    17409, 17411, 17415, 17376, 17392, 17388,     0, 16384, 
+    17408, 17409, 17411, 17415, 17376, 17392, 17393, 17390, 
+        0, 16384, 17408, 17409, 17411, 17415, 17376,     0, 
+    16384, 17408, 17409, 17411, 17415, 17376, 17392,     0, 
+    16384, 17408, 17409, 17411, 17415, 17376, 17392,     0, 
+    16384, 17408, 17409, 17411, 17415, 17376, 17392, 17394, 
+        0, 16384, 17408, 17409, 17411, 17415, 17376, 17392, 
+        0, 16384, 17408, 17409, 17411, 17415, 17376, 17392, 
+    17396,     0, 16384, 17408, 17409, 17411, 17415, 17376, 
+    17392, 17396,     0, 16384, 17408, 17409, 17411, 17415, 
+    17376, 17392, 17400, 17398,     0, 16384, 17408, 17409, 
+    17411, 17415, 17376, 17392,     0, 16384, 17408, 17409, 
+    17411, 17415, 17376, 17392, 17400,     0, 16384, 17408, 
+    17409, 17411, 17415, 17376, 17392, 17400,     0, 16384, 
+    17408, 17409, 17411, 17415, 17376, 17392, 17400, 17402, 
+        0, 16384, 17408, 17409, 17411, 17415, 17376, 17392, 
+    17400,     0, 16384, 17408, 17409, 17411, 17415, 17376, 
+    17392, 17400, 17404,     0, 16384, 17408, 17409, 17411, 
+    17415, 17376, 17392, 17400, 17404,     0, 16384, 17408, 
+    17409, 17411, 17415, 17376, 17392, 17400, 17404, 17406, 
+        0, 16384,     0, 16384, 17408,     0, 16384, 17408, 
+        0, 16384, 17408, 17410,     0, 16384, 17408,     0, 
+    16384, 17408, 17412,     0, 16384, 17408, 17412,     0, 
+    16384, 17408, 17416, 17414,     0, 16384, 17408,     0, 
+    16384, 17408, 17416,     0, 16384, 17408, 17416,     0, 
+    16384, 17408, 17416, 17418,     0, 16384, 17408, 17416, 
+        0, 16384, 17408, 17424, 17420,     0, 16384, 17408, 
+    17424, 17420,     0, 16384, 17408, 17424, 17425, 17422, 
+        0, 16384, 17408,     0, 16384, 17408, 17424,     0, 
+    16384, 17408, 17424,     0, 16384, 17408, 17424, 17426, 
+        0, 16384, 17408, 17424,     0, 16384, 17408, 17424, 
+    17428,     0, 16384, 17408, 17424, 17428,     0, 16384, 
+    17408, 17424, 17432, 17430,     0, 16384, 17408, 17424, 
+        0, 16384, 17408, 17440, 17432,     0, 16384, 17408, 
+    17440, 17432,     0, 16384, 17408, 17440, 17432, 17434, 
+        0, 16384, 17408, 17440, 17432,     0, 16384, 17408, 
+    17440, 17441, 17436,     0, 16384, 17408, 17440, 17441, 
+    17436,     0, 16384, 17408, 17440, 17441, 17436, 17438, 
+        0, 16384, 17408,     0, 16384, 17408, 17440,     0, 
+    16384, 17408, 17440,     0, 16384, 17408, 17440, 17442, 
+        0, 16384, 17408, 17440,     0, 16384, 17408, 17440, 
+    17444,     0, 16384, 17408, 17440, 17444,     0, 16384, 
+    17408, 17440, 17448, 17446,     0, 16384, 17408, 17440, 
+        0, 16384, 17408, 17440, 17448,     0, 16384, 17408, 
+    17440, 17448,     0, 16384, 17408, 17440, 17448, 17450, 
+        0, 16384, 17408, 17440, 17448,     0, 16384, 17408, 
+    17440, 17456, 17452,     0, 16384, 17408, 17440, 17456, 
+    17452,     0, 16384, 17408, 17440, 17456, 17457, 17454, 
+        0, 16384, 17408, 17440,     0, 16384, 17408, 17472, 
+    17456,     0, 16384, 17408, 17472, 17456,     0, 16384, 
+    17408, 17472, 17456, 17458,     0, 16384, 17408, 17472, 
+    17456,     0, 16384, 17408, 17472, 17456, 17460,     0, 
+    16384, 17408, 17472, 17456, 17460,     0, 16384, 17408, 
+    17472, 17456, 17464, 17462,     0, 16384, 17408, 17472, 
+    17456,     0, 16384, 17408, 17472, 17473, 17464,     0, 
+    16384, 17408, 17472, 17473, 17464,     0, 16384, 17408, 
+    17472, 17473, 17464, 17466,     0, 16384, 17408, 17472, 
+    17473, 17464,     0, 16384, 17408, 17472, 17473, 17464, 
+    17468,     0, 16384, 17408, 17472, 17473, 17475, 17468, 
+        0, 16384, 17408, 17472, 17473, 17475, 17468, 17470, 
+        0, 16384, 17408,     0, 16384, 17408, 17472,     0, 
+    16384, 17408, 17472,     0, 16384, 17408, 17472, 17474, 
+        0, 16384, 17408, 17472,     0, 16384, 17408, 17472, 
+    17476,     0, 16384, 17408, 17472, 17476,     0, 16384, 
+    17408, 17472, 17480, 17478,     0, 16384, 17408, 17472, 
+        0, 16384, 17408, 17472, 17480,     0, 16384, 17408, 
+    17472, 17480,     0, 16384, 17408, 17472, 17480, 17482, 
+        0, 16384, 17408, 17472, 17480,     0, 16384, 17408, 
+    17472, 17488, 17484,     0, 16384, 17408, 17472, 17488, 
+    17484,     0, 16384, 17408, 17472, 17488, 17489, 17486, 
+        0, 16384, 17408, 17472,     0, 16384, 17408, 17472, 
+    17488,     0, 16384, 17408, 17472, 17488,     0, 16384, 
+    17408, 17472, 17488, 17490,     0, 16384, 17408, 17472, 
+    17488,     0, 16384, 17408, 17472, 17488, 17492,     0, 
+    16384, 17408, 17472, 17488, 17492,     0, 16384, 17408, 
+    17472, 17488, 17496, 17494,     0, 16384, 17408, 17472, 
+    17488,     0, 16384, 17408, 17472, 17504, 17496,     0, 
+    16384, 17408, 17472, 17504, 17496,     0, 16384, 17408, 
+    17472, 17504, 17496, 17498,     0, 16384, 17408, 17472, 
+    17504, 17496,     0, 16384, 17408, 17472, 17504, 17505, 
+    17500,     0, 16384, 17408, 17472, 17504, 17505, 17500, 
+        0, 16384, 17408, 17472, 17504, 17505, 17500, 17502, 
+        0, 16384, 17408, 17472,     0, 16384, 17408, 17536, 
+    17504,     0, 16384, 17408, 17536, 17504,     0, 16384, 
+    17408, 17536, 17504, 17506,     0, 16384, 17408, 17536, 
+    17504,     0, 16384, 17408, 17536, 17504, 17508,     0, 
+    16384, 17408, 17536, 17504, 17508,     0, 16384, 17408, 
+    17536, 17504, 17512, 17510,     0, 16384, 17408, 17536, 
+    17504,     0, 16384, 17408, 17536, 17504, 17512,     0, 
+    16384, 17408, 17536, 17504, 17512,     0, 16384, 17408, 
+    17536, 17504, 17512, 17514,     0, 16384, 17408, 17536, 
+    17504, 17512,     0, 16384, 17408, 17536, 17504, 17520, 
+    17516,     0, 16384, 17408, 17536, 17504, 17520, 17516, 
+        0, 16384, 17408, 17536, 17504, 17520, 17521, 17518, 
+        0, 16384, 17408, 17536, 17504,     0, 16384, 17408, 
+    17536, 17537, 17520,     0, 16384, 17408, 17536, 17537, 
+    17520,     0, 16384, 17408, 17536, 17537, 17520, 17522, 
+        0, 16384, 17408, 17536, 17537, 17520,     0, 16384, 
+    17408, 17536, 17537, 17520, 17524,     0, 16384, 17408, 
+    17536, 17537, 17520, 17524,     0, 16384, 17408, 17536, 
+    17537, 17520, 17528, 17526,     0, 16384, 17408, 17536, 
+    17537, 17520,     0, 16384, 17408, 17536, 17537, 17520, 
+    17528,     0, 16384, 17408, 17536, 17537, 17539, 17528, 
+        0, 16384, 17408, 17536, 17537, 17539, 17528, 17530, 
+        0, 16384, 17408, 17536, 17537, 17539, 17528,     0, 
+    16384, 17408, 17536, 17537, 17539, 17528, 17532,     0, 
+    16384, 17408, 17536, 17537, 17539, 17528, 17532,     0, 
+    16384, 17408, 17536, 17537, 17539, 17528, 17532, 17534, 
+        0, 16384, 17408,     0, 16384, 17408, 17536,     0, 
+    16384, 17408, 17536,     0, 16384, 17408, 17536, 17538, 
+        0, 16384, 17408, 17536,     0, 16384, 17408, 17536, 
+    17540,     0, 16384, 17408, 17536, 17540,     0, 16384, 
+    17408, 17536, 17544, 17542,     0, 16384, 17408, 17536, 
+        0, 16384, 17408, 17536, 17544,     0, 16384, 17408, 
+    17536, 17544,     0, 16384, 17408, 17536, 17544, 17546, 
+        0, 16384, 17408, 17536, 17544,     0, 16384, 17408, 
+    17536, 17552, 17548,     0, 16384, 17408, 17536, 17552, 
+    17548,     0, 16384, 17408, 17536, 17552, 17553, 17550, 
+        0, 16384, 17408, 17536,     0, 16384, 17408, 17536, 
+    17552,     0, 16384, 17408, 17536, 17552,     0, 16384, 
+    17408, 17536, 17552, 17554,     0, 16384, 17408, 17536, 
+    17552,     0, 16384, 17408, 17536, 17552, 17556,     0, 
+    16384, 17408, 17536, 17552, 17556,     0, 16384, 17408, 
+    17536, 17552, 17560, 17558,     0, 16384, 17408, 17536, 
+    17552,     0, 16384, 17408, 17536, 17568, 17560,     0, 
+    16384, 17408, 17536, 17568, 17560,     0, 16384, 17408, 
+    17536, 17568, 17560, 17562,     0, 16384, 17408, 17536, 
+    17568, 17560,     0, 16384, 17408, 17536, 17568, 17569, 
+    17564,     0, 16384, 17408, 17536, 17568, 17569, 17564, 
+        0, 16384, 17408, 17536, 17568, 17569, 17564, 17566, 
+        0, 16384, 17408, 17536,     0, 16384, 17408, 17536, 
+    17568,     0, 16384, 17408, 17536, 17568,     0, 16384, 
+    17408, 17536, 17568, 17570,     0, 16384, 17408, 17536, 
+    17568,     0, 16384, 17408, 17536, 17568, 17572,     0, 
+    16384, 17408, 17536, 17568, 17572,     0, 16384, 17408, 
+    17536, 17568, 17576, 17574,     0, 16384, 17408, 17536, 
+    17568,     0, 16384, 17408, 17536, 17568, 17576,     0, 
+    16384, 17408, 17536, 17568, 17576,     0, 16384, 17408, 
+    17536, 17568, 17576, 17578,     0, 16384, 17408, 17536, 
+    17568, 17576,     0, 16384, 17408, 17536, 17568, 17584, 
+    17580,     0, 16384, 17408, 17536, 17568, 17584, 17580, 
+        0, 16384, 17408, 17536, 17568, 17584, 17585, 17582, 
+        0, 16384, 17408, 17536, 17568,     0, 16384, 17408, 
+    17536, 17600, 17584,     0, 16384, 17408, 17536, 17600, 
+    17584,     0, 16384, 17408, 17536, 17600, 17584, 17586, 
+        0, 16384, 17408, 17536, 17600, 17584,     0, 16384, 
+    17408, 17536, 17600, 17584, 17588,     0, 16384, 17408, 
+    17536, 17600, 17584, 17588,     0, 16384, 17408, 17536, 
+    17600, 17584, 17592, 17590,     0, 16384, 17408, 17536, 
+    17600, 17584,     0, 16384, 17408, 17536, 17600, 17601, 
+    17592,     0, 16384, 17408, 17536, 17600, 17601, 17592, 
+        0, 16384, 17408, 17536, 17600, 17601, 17592, 17594, 
+        0, 16384, 17408, 17536, 17600, 17601, 17592,     0, 
+    16384, 17408, 17536, 17600, 17601, 17592, 17596,     0, 
+    16384, 17408, 17536, 17600, 17601, 17603, 17596,     0, 
+    16384, 17408, 17536, 17600, 17601, 17603, 17596, 17598, 
+        0, 16384, 17408, 17536,     0, 16384, 17408, 17664, 
+    17600,     0, 16384, 17408, 17664, 17600,     0, 16384, 
+    17408, 17664, 17600, 17602,     0, 16384, 17408, 17664, 
+    17600,     0, 16384, 17408, 17664, 17600, 17604,     0, 
+    16384, 17408, 17664, 17600, 17604,     0, 16384, 17408, 
+    17664, 17600, 17608, 17606,     0, 16384, 17408, 17664, 
+    17600,     0, 16384, 17408, 17664, 17600, 17608,     0, 
+    16384, 17408, 17664, 17600, 17608,     0, 16384, 17408, 
+    17664, 17600, 17608, 17610,     0, 16384, 17408, 17664, 
+    17600, 17608,     0, 16384, 17408, 17664, 17600, 17616, 
+    17612,     0, 16384, 17408, 17664, 17600, 17616, 17612, 
+        0, 16384, 17408, 17664, 17600, 17616, 17617, 17614, 
+        0, 16384, 17408, 17664, 17600,     0, 16384, 17408, 
+    17664, 17600, 17616,     0, 16384, 17408, 17664, 17600, 
+    17616,     0, 16384, 17408, 17664, 17600, 17616, 17618, 
+        0, 16384, 17408, 17664, 17600, 17616,     0, 16384, 
+    17408, 17664, 17600, 17616, 17620,     0, 16384, 17408, 
+    17664, 17600, 17616, 17620,     0, 16384, 17408, 17664, 
+    17600, 17616, 17624, 17622,     0, 16384, 17408, 17664, 
+    17600, 17616,     0, 16384, 17408, 17664, 17600, 17632, 
+    17624,     0, 16384, 17408, 17664, 17600, 17632, 17624, 
+        0, 16384, 17408, 17664, 17600, 17632, 17624, 17626, 
+        0, 16384, 17408, 17664, 17600, 17632, 17624,     0, 
+    16384, 17408, 17664, 17600, 17632, 17633, 17628,     0, 
+    16384, 17408, 17664, 17600, 17632, 17633, 17628,     0, 
+    16384, 17408, 17664, 17600, 17632, 17633, 17628, 17630, 
+        0, 16384, 17408, 17664, 17600,     0, 16384, 17408, 
+    17664, 17665, 17632,     0, 16384, 17408, 17664, 17665, 
+    17632,     0, 16384, 17408, 17664, 17665, 17632, 17634, 
+        0, 16384, 17408, 17664, 17665, 17632,     0, 16384, 
+    17408, 17664, 17665, 17632, 17636,     0, 16384, 17408, 
+    17664, 17665, 17632, 17636,     0, 16384, 17408, 17664, 
+    17665, 17632, 17640, 17638,     0, 16384, 17408, 17664, 
+    17665, 17632,     0, 16384, 17408, 17664, 17665, 17632, 
+    17640,     0, 16384, 17408, 17664, 17665, 17632, 17640, 
+        0, 16384, 17408, 17664, 17665, 17632, 17640, 17642, 
+        0, 16384, 17408, 17664, 17665, 17632, 17640,     0, 
+    16384, 17408, 17664, 17665, 17632, 17648, 17644,     0, 
+    16384, 17408, 17664, 17665, 17632, 17648, 17644,     0, 
+    16384, 17408, 17664, 17665, 17632, 17648, 17649, 17646, 
+        0, 16384, 17408, 17664, 17665, 17632,     0, 16384, 
+    17408, 17664, 17665, 17632, 17648,     0, 16384, 17408, 
+    17664, 17665, 17667, 17648,     0, 16384, 17408, 17664, 
+    17665, 17667, 17648, 17650,     0, 16384, 17408, 17664, 
+    17665, 17667, 17648,     0, 16384, 17408, 17664, 17665, 
+    17667, 17648, 17652,     0, 16384, 17408, 17664, 17665, 
+    17667, 17648, 17652,     0, 16384, 17408, 17664, 17665, 
+    17667, 17648, 17656, 17654,     0, 16384, 17408, 17664, 
+    17665, 17667, 17648,     0, 16384, 17408, 17664, 17665, 
+    17667, 17648, 17656,     0, 16384, 17408, 17664, 17665, 
+    17667, 17648, 17656,     0, 16384, 17408, 17664, 17665, 
+    17667, 17648, 17656, 17658,     0, 16384, 17408, 17664, 
+    17665, 17667, 17671, 17656,     0, 16384, 17408, 17664, 
+    17665, 17667, 17671, 17656, 17660,     0, 16384, 17408, 
+    17664, 17665, 17667, 17671, 17656, 17660,     0, 16384, 
+    17408, 17664, 17665, 17667, 17671, 17656, 17660, 17662, 
+        0, 16384, 17408,     0, 16384, 17408, 17664,     0, 
+    16384, 17408, 17664,     0, 16384, 17408, 17664, 17666, 
+        0, 16384, 17408, 17664,     0, 16384, 17408, 17664, 
+    17668,     0, 16384, 17408, 17664, 17668,     0, 16384, 
+    17408, 17664, 17672, 17670,     0, 16384, 17408, 17664, 
+        0, 16384, 17408, 17664, 17672,     0, 16384, 17408, 
+    17664, 17672,     0, 16384, 17408, 17664, 17672, 17674, 
+        0, 16384, 17408, 17664, 17672,     0, 16384, 17408, 
+    17664, 17680, 17676,     0, 16384, 17408, 17664, 17680, 
+    17676,     0, 16384, 17408, 17664, 17680, 17681, 17678, 
+        0, 16384, 17408, 17664,     0, 16384, 17408, 17664, 
+    17680,     0, 16384, 17408, 17664, 17680,     0, 16384, 
+    17408, 17664, 17680, 17682,     0, 16384, 17408, 17664, 
+    17680,     0, 16384, 17408, 17664, 17680, 17684,     0, 
+    16384, 17408, 17664, 17680, 17684,     0, 16384, 17408, 
+    17664, 17680, 17688, 17686,     0, 16384, 17408, 17664, 
+    17680,     0, 16384, 17408, 17664, 17696, 17688,     0, 
+    16384, 17408, 17664, 17696, 17688,     0, 16384, 17408, 
+    17664, 17696, 17688, 17690,     0, 16384, 17408, 17664, 
+    17696, 17688,     0, 16384, 17408, 17664, 17696, 17697, 
+    17692,     0, 16384, 17408, 17664, 17696, 17697, 17692, 
+        0, 16384, 17408, 17664, 17696, 17697, 17692, 17694, 
+        0, 16384, 17408, 17664,     0, 16384, 17408, 17664, 
+    17696,     0, 16384, 17408, 17664, 17696,     0, 16384, 
+    17408, 17664, 17696, 17698,     0, 16384, 17408, 17664, 
+    17696,     0, 16384, 17408, 17664, 17696, 17700,     0, 
+    16384, 17408, 17664, 17696, 17700,     0, 16384, 17408, 
+    17664, 17696, 17704, 17702,     0, 16384, 17408, 17664, 
+    17696,     0, 16384, 17408, 17664, 17696, 17704,     0, 
+    16384, 17408, 17664, 17696, 17704,     0, 16384, 17408, 
+    17664, 17696, 17704, 17706,     0, 16384, 17408, 17664, 
+    17696, 17704,     0, 16384, 17408, 17664, 17696, 17712, 
+    17708,     0, 16384, 17408, 17664, 17696, 17712, 17708, 
+        0, 16384, 17408, 17664, 17696, 17712, 17713, 17710, 
+        0, 16384, 17408, 17664, 17696,     0, 16384, 17408, 
+    17664, 17728, 17712,     0, 16384, 17408, 17664, 17728, 
+    17712,     0, 16384, 17408, 17664, 17728, 17712, 17714, 
+        0, 16384, 17408, 17664, 17728, 17712,     0, 16384, 
+    17408, 17664, 17728, 17712, 17716,     0, 16384, 17408, 
+    17664, 17728, 17712, 17716,     0, 16384, 17408, 17664, 
+    17728, 17712, 17720, 17718,     0, 16384, 17408, 17664, 
+    17728, 17712,     0, 16384, 17408, 17664, 17728, 17729, 
+    17720,     0, 16384, 17408, 17664, 17728, 17729, 17720, 
+        0, 16384, 17408, 17664, 17728, 17729, 17720, 17722, 
+        0, 16384, 17408, 17664, 17728, 17729, 17720,     0, 
+    16384, 17408, 17664, 17728, 17729, 17720, 17724,     0, 
+    16384, 17408, 17664, 17728, 17729, 17731, 17724,     0, 
+    16384, 17408, 17664, 17728, 17729, 17731, 17724, 17726, 
+        0, 16384, 17408, 17664,     0, 16384, 17408, 17664, 
+    17728,     0, 16384, 17408, 17664, 17728,     0, 16384, 
+    17408, 17664, 17728, 17730,     0, 16384, 17408, 17664, 
+    17728,     0, 16384, 17408, 17664, 17728, 17732,     0, 
+    16384, 17408, 17664, 17728, 17732,     0, 16384, 17408, 
+    17664, 17728, 17736, 17734,     0, 16384, 17408, 17664, 
+    17728,     0, 16384, 17408, 17664, 17728, 17736,     0, 
+    16384, 17408, 17664, 17728, 17736,     0, 16384, 17408, 
+    17664, 17728, 17736, 17738,     0, 16384, 17408, 17664, 
+    17728, 17736,     0, 16384, 17408, 17664, 17728, 17744, 
+    17740,     0, 16384, 17408, 17664, 17728, 17744, 17740, 
+        0, 16384, 17408, 17664, 17728, 17744, 17745, 17742, 
+        0, 16384, 17408, 17664, 17728,     0, 16384, 17408, 
+    17664, 17728, 17744,     0, 16384, 17408, 17664, 17728, 
+    17744,     0, 16384, 17408, 17664, 17728, 17744, 17746, 
+        0, 16384, 17408, 17664, 17728, 17744,     0, 16384, 
+    17408, 17664, 17728, 17744, 17748,     0, 16384, 17408, 
+    17664, 17728, 17744, 17748,     0, 16384, 17408, 17664, 
+    17728, 17744, 17752, 17750,     0, 16384, 17408, 17664, 
+    17728, 17744,     0, 16384, 17408, 17664, 17728, 17760, 
+    17752,     0, 16384, 17408, 17664, 17728, 17760, 17752, 
+        0, 16384, 17408, 17664, 17728, 17760, 17752, 17754, 
+        0, 16384, 17408, 17664, 17728, 17760, 17752,     0, 
+    16384, 17408, 17664, 17728, 17760, 17761, 17756,     0, 
+    16384, 17408, 17664, 17728, 17760, 17761, 17756,     0, 
+    16384, 17408, 17664, 17728, 17760, 17761, 17756, 17758, 
+        0, 16384, 17408, 17664, 17728,     0, 16384, 17408, 
+    17664, 17792, 17760,     0, 16384, 17408, 17664, 17792, 
+    17760,     0, 16384, 17408, 17664, 17792, 17760, 17762, 
+        0, 16384, 17408, 17664, 17792, 17760,     0, 16384, 
+    17408, 17664, 17792, 17760, 17764,     0, 16384, 17408, 
+    17664, 17792, 17760, 17764,     0, 16384, 17408, 17664, 
+    17792, 17760, 17768, 17766,     0, 16384, 17408, 17664, 
+    17792, 17760,     0, 16384, 17408, 17664, 17792, 17760, 
+    17768,     0, 16384, 17408, 17664, 17792, 17760, 17768, 
+        0, 16384, 17408, 17664, 17792, 17760, 17768, 17770, 
+        0, 16384, 17408, 17664, 17792, 17760, 17768,     0, 
+    16384, 17408, 17664, 17792, 17760, 17776, 17772,     0, 
+    16384, 17408, 17664, 17792, 17760, 17776, 17772,     0, 
+    16384, 17408, 17664, 17792, 17760, 17776, 17777, 17774, 
+        0, 16384, 17408, 17664, 17792, 17760,     0, 16384, 
+    17408, 17664, 17792, 17793, 17776,     0, 16384, 17408, 
+    17664, 17792, 17793, 17776,     0, 16384, 17408, 17664, 
+    17792, 17793, 17776, 17778,     0, 16384, 17408, 17664, 
+    17792, 17793, 17776,     0, 16384, 17408, 17664, 17792, 
+    17793, 17776, 17780,     0, 16384, 17408, 17664, 17792, 
+    17793, 17776, 17780,     0, 16384, 17408, 17664, 17792, 
+    17793, 17776, 17784, 17782,     0, 16384, 17408, 17664, 
+    17792, 17793, 17776,     0, 16384, 17408, 17664, 17792, 
+    17793, 17776, 17784,     0, 16384, 17408, 17664, 17792, 
+    17793, 17795, 17784,     0, 16384, 17408, 17664, 17792, 
+    17793, 17795, 17784, 17786,     0, 16384, 17408, 17664, 
+    17792, 17793, 17795, 17784,     0, 16384, 17408, 17664, 
+    17792, 17793, 17795, 17784, 17788,     0, 16384, 17408, 
+    17664, 17792, 17793, 17795, 17784, 17788,     0, 16384, 
+    17408, 17664, 17792, 17793, 17795, 17784, 17788, 17790, 
+        0, 16384, 17408, 17664,     0, 16384, 17408, 17920, 
+    17792,     0, 16384, 17408, 17920, 17792,     0, 16384, 
+    17408, 17920, 17792, 17794,     0, 16384, 17408, 17920, 
+    17792,     0, 16384, 17408, 17920, 17792, 17796,     0, 
+    16384, 17408, 17920, 17792, 17796,     0, 16384, 17408, 
+    17920, 17792, 17800, 17798,     0, 16384, 17408, 17920, 
+    17792,     0, 16384, 17408, 17920, 17792, 17800,     0, 
+    16384, 17408, 17920, 17792, 17800,     0, 16384, 17408, 
+    17920, 17792, 17800, 17802,     0, 16384, 17408, 17920, 
+    17792, 17800,     0, 16384, 17408, 17920, 17792, 17808, 
+    17804,     0, 16384, 17408, 17920, 17792, 17808, 17804, 
+        0, 16384, 17408, 17920, 17792, 17808, 17809, 17806, 
+        0, 16384, 17408, 17920, 17792,     0, 16384, 17408, 
+    17920, 17792, 17808,     0, 16384, 17408, 17920, 17792, 
+    17808,     0, 16384, 17408, 17920, 17792, 17808, 17810, 
+        0, 16384, 17408, 17920, 17792, 17808,     0, 16384, 
+    17408, 17920, 17792, 17808, 17812,     0, 16384, 17408, 
+    17920, 17792, 17808, 17812,     0, 16384, 17408, 17920, 
+    17792, 17808, 17816, 17814,     0, 16384, 17408, 17920, 
+    17792, 17808,     0, 16384, 17408, 17920, 17792, 17824, 
+    17816,     0, 16384, 17408, 17920, 17792, 17824, 17816, 
+        0, 16384, 17408, 17920, 17792, 17824, 17816, 17818, 
+        0, 16384, 17408, 17920, 17792, 17824, 17816,     0, 
+    16384, 17408, 17920, 17792, 17824, 17825, 17820,     0, 
+    16384, 17408, 17920, 17792, 17824, 17825, 17820,     0, 
+    16384, 17408, 17920, 17792, 17824, 17825, 17820, 17822, 
+        0, 16384, 17408, 17920, 17792,     0, 16384, 17408, 
+    17920, 17792, 17824,     0, 16384, 17408, 17920, 17792, 
+    17824,     0, 16384, 17408, 17920, 17792, 17824, 17826, 
+        0, 16384, 17408, 17920, 17792, 17824,     0, 16384, 
+    17408, 17920, 17792, 17824, 17828,     0, 16384, 17408, 
+    17920, 17792, 17824, 17828,     0, 16384, 17408, 17920, 
+    17792, 17824, 17832, 17830,     0, 16384, 17408, 17920, 
+    17792, 17824,     0, 16384, 17408, 17920, 17792, 17824, 
+    17832,     0, 16384, 17408, 17920, 17792, 17824, 17832, 
+        0, 16384, 17408, 17920, 17792, 17824, 17832, 17834, 
+        0, 16384, 17408, 17920, 17792, 17824, 17832,     0, 
+    16384, 17408, 17920, 17792, 17824, 17840, 17836,     0, 
+    16384, 17408, 17920, 17792, 17824, 17840, 17836,     0, 
+    16384, 17408, 17920, 17792, 17824, 17840, 17841, 17838, 
+        0, 16384, 17408, 17920, 17792, 17824,     0, 16384, 
+    17408, 17920, 17792, 17856, 17840,     0, 16384, 17408, 
+    17920, 17792, 17856, 17840,     0, 16384, 17408, 17920, 
+    17792, 17856, 17840, 17842,     0, 16384, 17408, 17920, 
+    17792, 17856, 17840,     0, 16384, 17408, 17920, 17792, 
+    17856, 17840, 17844,     0, 16384, 17408, 17920, 17792, 
+    17856, 17840, 17844,     0, 16384, 17408, 17920, 17792, 
+    17856, 17840, 17848, 17846,     0, 16384, 17408, 17920, 
+    17792, 17856, 17840,     0, 16384, 17408, 17920, 17792, 
+    17856, 17857, 17848,     0, 16384, 17408, 17920, 17792, 
+    17856, 17857, 17848,     0, 16384, 17408, 17920, 17792, 
+    17856, 17857, 17848, 17850,     0, 16384, 17408, 17920, 
+    17792, 17856, 17857, 17848,     0, 16384, 17408, 17920, 
+    17792, 17856, 17857, 17848, 17852,     0, 16384, 17408, 
+    17920, 17792, 17856, 17857, 17859, 17852,     0, 16384, 
+    17408, 17920, 17792, 17856, 17857, 17859, 17852, 17854, 
+        0, 16384, 17408, 17920, 17792,     0, 16384, 17408, 
+    17920, 17921, 17856,     0, 16384, 17408, 17920, 17921, 
+    17856,     0, 16384, 17408, 17920, 17921, 17856, 17858, 
+        0, 16384, 17408, 17920, 17921, 17856,     0, 16384, 
+    17408, 17920, 17921, 17856, 17860,     0, 16384, 17408, 
+    17920, 17921, 17856, 17860,     0, 16384, 17408, 17920, 
+    17921, 17856, 17864, 17862,     0, 16384, 17408, 17920, 
+    17921, 17856,     0, 16384, 17408, 17920, 17921, 17856, 
+    17864,     0, 16384, 17408, 17920, 17921, 17856, 17864, 
+        0, 16384, 17408, 17920, 17921, 17856, 17864, 17866, 
+        0, 16384, 17408, 17920, 17921, 17856, 17864,     0, 
+    16384, 17408, 17920, 17921, 17856, 17872, 17868,     0, 
+    16384, 17408, 17920, 17921, 17856, 17872, 17868,     0, 
+    16384, 17408, 17920, 17921, 17856, 17872, 17873, 17870, 
+        0, 16384, 17408, 17920, 17921, 17856,     0, 16384, 
+    17408, 17920, 17921, 17856, 17872,     0, 16384, 17408, 
+    17920, 17921, 17856, 17872,     0, 16384, 17408, 17920, 
+    17921, 17856, 17872, 17874,     0, 16384, 17408, 17920, 
+    17921, 17856, 17872,     0, 16384, 17408, 17920, 17921, 
+    17856, 17872, 17876,     0, 16384, 17408, 17920, 17921, 
+    17856, 17872, 17876,     0, 16384, 17408, 17920, 17921, 
+    17856, 17872, 17880, 17878,     0, 16384, 17408, 17920, 
+    17921, 17856, 17872,     0, 16384, 17408, 17920, 17921, 
+    17856, 17888, 17880,     0, 16384, 17408, 17920, 17921, 
+    17856, 17888, 17880,     0, 16384, 17408, 17920, 17921, 
+    17856, 17888, 17880, 17882,     0, 16384, 17408, 17920, 
+    17921, 17856, 17888, 17880,     0, 16384, 17408, 17920, 
+    17921, 17856, 17888, 17889, 17884,     0, 16384, 17408, 
+    17920, 17921, 17856, 17888, 17889, 17884,     0, 16384, 
+    17408, 17920, 17921, 17856, 17888, 17889, 17884, 17886, 
+        0, 16384, 17408, 17920, 17921, 17856,     0, 16384, 
+    17408, 17920, 17921, 17856, 17888,     0, 16384, 17408, 
+    17920, 17921, 17923, 17888,     0, 16384, 17408, 17920, 
+    17921, 17923, 17888, 17890,     0, 16384, 17408, 17920, 
+    17921, 17923, 17888,     0, 16384, 17408, 17920, 17921, 
+    17923, 17888, 17892,     0, 16384, 17408, 17920, 17921, 
+    17923, 17888, 17892,     0, 16384, 17408, 17920, 17921, 
+    17923, 17888, 17896, 17894,     0, 16384, 17408, 17920, 
+    17921, 17923, 17888,     0, 16384, 17408, 17920, 17921, 
+    17923, 17888, 17896,     0, 16384, 17408, 17920, 17921, 
+    17923, 17888, 17896,     0, 16384, 17408, 17920, 17921, 
+    17923, 17888, 17896, 17898,     0, 16384, 17408, 17920, 
+    17921, 17923, 17888, 17896,     0, 16384, 17408, 17920, 
+    17921, 17923, 17888, 17904, 17900,     0, 16384, 17408, 
+    17920, 17921, 17923, 17888, 17904, 17900,     0, 16384, 
+    17408, 17920, 17921, 17923, 17888, 17904, 17905, 17902, 
+        0, 16384, 17408, 17920, 17921, 17923, 17888,     0, 
+    16384, 17408, 17920, 17921, 17923, 17888, 17904,     0, 
+    16384, 17408, 17920, 17921, 17923, 17888, 17904,     0, 
+    16384, 17408, 17920, 17921, 17923, 17888, 17904, 17906, 
+        0, 16384, 17408, 17920, 17921, 17923, 17927, 17904, 
+        0, 16384, 17408, 17920, 17921, 17923, 17927, 17904, 
+    17908,     0, 16384, 17408, 17920, 17921, 17923, 17927, 
+    17904, 17908,     0, 16384, 17408, 17920, 17921, 17923, 
+    17927, 17904, 17912, 17910,     0, 16384, 17408, 17920, 
+    17921, 17923, 17927, 17904,     0, 16384, 17408, 17920, 
+    17921, 17923, 17927, 17904, 17912,     0, 16384, 17408, 
+    17920, 17921, 17923, 17927, 17904, 17912,     0, 16384, 
+    17408, 17920, 17921, 17923, 17927, 17904, 17912, 17914, 
+        0, 16384, 17408, 17920, 17921, 17923, 17927, 17904, 
+    17912,     0, 16384, 17408, 17920, 17921, 17923, 17927, 
+    17904, 17912, 17916,     0, 16384, 17408, 17920, 17921, 
+    17923, 17927, 17904, 17912, 17916,     0, 16384, 17408, 
+    17920, 17921, 17923, 17927, 17904, 17912, 17916, 17918, 
+        0, 16384, 17408,     0, 16384, 18432, 17920,     0, 
+    16384, 18432, 17920,     0, 16384, 18432, 17920, 17922, 
+        0, 16384, 18432, 17920,     0, 16384, 18432, 17920, 
+    17924,     0, 16384, 18432, 17920, 17924,     0, 16384, 
+    18432, 17920, 17928, 17926,     0, 16384, 18432, 17920, 
+        0, 16384, 18432, 17920, 17928,     0, 16384, 18432, 
+    17920, 17928,     0, 16384, 18432, 17920, 17928, 17930, 
+        0, 16384, 18432, 17920, 17928,     0, 16384, 18432, 
+    17920, 17936, 17932,     0, 16384, 18432, 17920, 17936, 
+    17932,     0, 16384, 18432, 17920, 17936, 17937, 17934, 
+        0, 16384, 18432, 17920,     0, 16384, 18432, 17920, 
+    17936,     0, 16384, 18432, 17920, 17936,     0, 16384, 
+    18432, 17920, 17936, 17938,     0, 16384, 18432, 17920, 
+    17936,     0, 16384, 18432, 17920, 17936, 17940,     0, 
+    16384, 18432, 17920, 17936, 17940,     0, 16384, 18432, 
+    17920, 17936, 17944, 17942,     0, 16384, 18432, 17920, 
+    17936,     0, 16384, 18432, 17920, 17952, 17944,     0, 
+    16384, 18432, 17920, 17952, 17944,     0, 16384, 18432, 
+    17920, 17952, 17944, 17946,     0, 16384, 18432, 17920, 
+    17952, 17944,     0, 16384, 18432, 17920, 17952, 17953, 
+    17948,     0, 16384, 18432, 17920, 17952, 17953, 17948, 
+        0, 16384, 18432, 17920, 17952, 17953, 17948, 17950, 
+        0, 16384, 18432, 17920,     0, 16384, 18432, 17920, 
+    17952,     0, 16384, 18432, 17920, 17952,     0, 16384, 
+    18432, 17920, 17952, 17954,     0, 16384, 18432, 17920, 
+    17952,     0, 16384, 18432, 17920, 17952, 17956,     0, 
+    16384, 18432, 17920, 17952, 17956,     0, 16384, 18432, 
+    17920, 17952, 17960, 17958,     0, 16384, 18432, 17920, 
+    17952,     0, 16384, 18432, 17920, 17952, 17960,     0, 
+    16384, 18432, 17920, 17952, 17960,     0, 16384, 18432, 
+    17920, 17952, 17960, 17962,     0, 16384, 18432, 17920, 
+    17952, 17960,     0, 16384, 18432, 17920, 17952, 17968, 
+    17964,     0, 16384, 18432, 17920, 17952, 17968, 17964, 
+        0, 16384, 18432, 17920, 17952, 17968, 17969, 17966, 
+        0, 16384, 18432, 17920, 17952,     0, 16384, 18432, 
+    17920, 17984, 17968,     0, 16384, 18432, 17920, 17984, 
+    17968,     0, 16384, 18432, 17920, 17984, 17968, 17970, 
+        0, 16384, 18432, 17920, 17984, 17968,     0, 16384, 
+    18432, 17920, 17984, 17968, 17972,     0, 16384, 18432, 
+    17920, 17984, 17968, 17972,     0, 16384, 18432, 17920, 
+    17984, 17968, 17976, 17974,     0, 16384, 18432, 17920, 
+    17984, 17968,     0, 16384, 18432, 17920, 17984, 17985, 
+    17976,     0, 16384, 18432, 17920, 17984, 17985, 17976, 
+        0, 16384, 18432, 17920, 17984, 17985, 17976, 17978, 
+        0, 16384, 18432, 17920, 17984, 17985, 17976,     0, 
+    16384, 18432, 17920, 17984, 17985, 17976, 17980,     0, 
+    16384, 18432, 17920, 17984, 17985, 17987, 17980,     0, 
+    16384, 18432, 17920, 17984, 17985, 17987, 17980, 17982, 
+        0, 16384, 18432, 17920,     0, 16384, 18432, 17920, 
+    17984,     0, 16384, 18432, 17920, 17984,     0, 16384, 
+    18432, 17920, 17984, 17986,     0, 16384, 18432, 17920, 
+    17984,     0, 16384, 18432, 17920, 17984, 17988,     0, 
+    16384, 18432, 17920, 17984, 17988,     0, 16384, 18432, 
+    17920, 17984, 17992, 17990,     0, 16384, 18432, 17920, 
+    17984,     0, 16384, 18432, 17920, 17984, 17992,     0, 
+    16384, 18432, 17920, 17984, 17992,     0, 16384, 18432, 
+    17920, 17984, 17992, 17994,     0, 16384, 18432, 17920, 
+    17984, 17992,     0, 16384, 18432, 17920, 17984, 18000, 
+    17996,     0, 16384, 18432, 17920, 17984, 18000, 17996, 
+        0, 16384, 18432, 17920, 17984, 18000, 18001, 17998, 
+        0, 16384, 18432, 17920, 17984,     0, 16384, 18432, 
+    17920, 17984, 18000,     0, 16384, 18432, 17920, 17984, 
+    18000,     0, 16384, 18432, 17920, 17984, 18000, 18002, 
+        0, 16384, 18432, 17920, 17984, 18000,     0, 16384, 
+    18432, 17920, 17984, 18000, 18004,     0, 16384, 18432, 
+    17920, 17984, 18000, 18004,     0, 16384, 18432, 17920, 
+    17984, 18000, 18008, 18006,     0, 16384, 18432, 17920, 
+    17984, 18000,     0, 16384, 18432, 17920, 17984, 18016, 
+    18008,     0, 16384, 18432, 17920, 17984, 18016, 18008, 
+        0, 16384, 18432, 17920, 17984, 18016, 18008, 18010, 
+        0, 16384, 18432, 17920, 17984, 18016, 18008,     0, 
+    16384, 18432, 17920, 17984, 18016, 18017, 18012,     0, 
+    16384, 18432, 17920, 17984, 18016, 18017, 18012,     0, 
+    16384, 18432, 17920, 17984, 18016, 18017, 18012, 18014, 
+        0, 16384, 18432, 17920, 17984,     0, 16384, 18432, 
+    17920, 18048, 18016,     0, 16384, 18432, 17920, 18048, 
+    18016,     0, 16384, 18432, 17920, 18048, 18016, 18018, 
+        0, 16384, 18432, 17920, 18048, 18016,     0, 16384, 
+    18432, 17920, 18048, 18016, 18020,     0, 16384, 18432, 
+    17920, 18048, 18016, 18020,     0, 16384, 18432, 17920, 
+    18048, 18016, 18024, 18022,     0, 16384, 18432, 17920, 
+    18048, 18016,     0, 16384, 18432, 17920, 18048, 18016, 
+    18024,     0, 16384, 18432, 17920, 18048, 18016, 18024, 
+        0, 16384, 18432, 17920, 18048, 18016, 18024, 18026, 
+        0, 16384, 18432, 17920, 18048, 18016, 18024,     0, 
+    16384, 18432, 17920, 18048, 18016, 18032, 18028,     0, 
+    16384, 18432, 17920, 18048, 18016, 18032, 18028,     0, 
+    16384, 18432, 17920, 18048, 18016, 18032, 18033, 18030, 
+        0, 16384, 18432, 17920, 18048, 18016,     0, 16384, 
+    18432, 17920, 18048, 18049, 18032,     0, 16384, 18432, 
+    17920, 18048, 18049, 18032,     0, 16384, 18432, 17920, 
+    18048, 18049, 18032, 18034,     0, 16384, 18432, 17920, 
+    18048, 18049, 18032,     0, 16384, 18432, 17920, 18048, 
+    18049, 18032, 18036,     0, 16384, 18432, 17920, 18048, 
+    18049, 18032, 18036,     0, 16384, 18432, 17920, 18048, 
+    18049, 18032, 18040, 18038,     0, 16384, 18432, 17920, 
+    18048, 18049, 18032,     0, 16384, 18432, 17920, 18048, 
+    18049, 18032, 18040,     0, 16384, 18432, 17920, 18048, 
+    18049, 18051, 18040,     0, 16384, 18432, 17920, 18048, 
+    18049, 18051, 18040, 18042,     0, 16384, 18432, 17920, 
+    18048, 18049, 18051, 18040,     0, 16384, 18432, 17920, 
+    18048, 18049, 18051, 18040, 18044,     0, 16384, 18432, 
+    17920, 18048, 18049, 18051, 18040, 18044,     0, 16384, 
+    18432, 17920, 18048, 18049, 18051, 18040, 18044, 18046, 
+        0, 16384, 18432, 17920,     0, 16384, 18432, 17920, 
+    18048,     0, 16384, 18432, 17920, 18048,     0, 16384, 
+    18432, 17920, 18048, 18050,     0, 16384, 18432, 17920, 
+    18048,     0, 16384, 18432, 17920, 18048, 18052,     0, 
+    16384, 18432, 17920, 18048, 18052,     0, 16384, 18432, 
+    17920, 18048, 18056, 18054,     0, 16384, 18432, 17920, 
+    18048,     0, 16384, 18432, 17920, 18048, 18056,     0, 
+    16384, 18432, 17920, 18048, 18056,     0, 16384, 18432, 
+    17920, 18048, 18056, 18058,     0, 16384, 18432, 17920, 
+    18048, 18056,     0, 16384, 18432, 17920, 18048, 18064, 
+    18060,     0, 16384, 18432, 17920, 18048, 18064, 18060, 
+        0, 16384, 18432, 17920, 18048, 18064, 18065, 18062, 
+        0, 16384, 18432, 17920, 18048,     0, 16384, 18432, 
+    17920, 18048, 18064,     0, 16384, 18432, 17920, 18048, 
+    18064,     0, 16384, 18432, 17920, 18048, 18064, 18066, 
+        0, 16384, 18432, 17920, 18048, 18064,     0, 16384, 
+    18432, 17920, 18048, 18064, 18068,     0, 16384, 18432, 
+    17920, 18048, 18064, 18068,     0, 16384, 18432, 17920, 
+    18048, 18064, 18072, 18070,     0, 16384, 18432, 17920, 
+    18048, 18064,     0, 16384, 18432, 17920, 18048, 18080, 
+    18072,     0, 16384, 18432, 17920, 18048, 18080, 18072, 
+        0, 16384, 18432, 17920, 18048, 18080, 18072, 18074, 
+        0, 16384, 18432, 17920, 18048, 18080, 18072,     0, 
+    16384, 18432, 17920, 18048, 18080, 18081, 18076,     0, 
+    16384, 18432, 17920, 18048, 18080, 18081, 18076,     0, 
+    16384, 18432, 17920, 18048, 18080, 18081, 18076, 18078, 
+        0, 16384, 18432, 17920, 18048,     0, 16384, 18432, 
+    17920, 18048, 18080,     0, 16384, 18432, 17920, 18048, 
+    18080,     0, 16384, 18432, 17920, 18048, 18080, 18082, 
+        0, 16384, 18432, 17920, 18048, 18080,     0, 16384, 
+    18432, 17920, 18048, 18080, 18084,     0, 16384, 18432, 
+    17920, 18048, 18080, 18084,     0, 16384, 18432, 17920, 
+    18048, 18080, 18088, 18086,     0, 16384, 18432, 17920, 
+    18048, 18080,     0, 16384, 18432, 17920, 18048, 18080, 
+    18088,     0, 16384, 18432, 17920, 18048, 18080, 18088, 
+        0, 16384, 18432, 17920, 18048, 18080, 18088, 18090, 
+        0, 16384, 18432, 17920, 18048, 18080, 18088,     0, 
+    16384, 18432, 17920, 18048, 18080, 18096, 18092,     0, 
+    16384, 18432, 17920, 18048, 18080, 18096, 18092,     0, 
+    16384, 18432, 17920, 18048, 18080, 18096, 18097, 18094, 
+        0, 16384, 18432, 17920, 18048, 18080,     0, 16384, 
+    18432, 17920, 18048, 18112, 18096,     0, 16384, 18432, 
+    17920, 18048, 18112, 18096,     0, 16384, 18432, 17920, 
+    18048, 18112, 18096, 18098,     0, 16384, 18432, 17920, 
+    18048, 18112, 18096,     0, 16384, 18432, 17920, 18048, 
+    18112, 18096, 18100,     0, 16384, 18432, 17920, 18048, 
+    18112, 18096, 18100,     0, 16384, 18432, 17920, 18048, 
+    18112, 18096, 18104, 18102,     0, 16384, 18432, 17920, 
+    18048, 18112, 18096,     0, 16384, 18432, 17920, 18048, 
+    18112, 18113, 18104,     0, 16384, 18432, 17920, 18048, 
+    18112, 18113, 18104,     0, 16384, 18432, 17920, 18048, 
+    18112, 18113, 18104, 18106,     0, 16384, 18432, 17920, 
+    18048, 18112, 18113, 18104,     0, 16384, 18432, 17920, 
+    18048, 18112, 18113, 18104, 18108,     0, 16384, 18432, 
+    17920, 18048, 18112, 18113, 18115, 18108,     0, 16384, 
+    18432, 17920, 18048, 18112, 18113, 18115, 18108, 18110, 
+        0, 16384, 18432, 17920, 18048,     0, 16384, 18432, 
+    17920, 18176, 18112,     0, 16384, 18432, 17920, 18176, 
+    18112,     0, 16384, 18432, 17920, 18176, 18112, 18114, 
+        0, 16384, 18432, 17920, 18176, 18112,     0, 16384, 
+    18432, 17920, 18176, 18112, 18116,     0, 16384, 18432, 
+    17920, 18176, 18112, 18116,     0, 16384, 18432, 17920, 
+    18176, 18112, 18120, 18118,     0, 16384, 18432, 17920, 
+    18176, 18112,     0, 16384, 18432, 17920, 18176, 18112, 
+    18120,     0, 16384, 18432, 17920, 18176, 18112, 18120, 
+        0, 16384, 18432, 17920, 18176, 18112, 18120, 18122, 
+        0, 16384, 18432, 17920, 18176, 18112, 18120,     0, 
+    16384, 18432, 17920, 18176, 18112, 18128, 18124,     0, 
+    16384, 18432, 17920, 18176, 18112, 18128, 18124,     0, 
+    16384, 18432, 17920, 18176, 18112, 18128, 18129, 18126, 
+        0, 16384, 18432, 17920, 18176, 18112,     0, 16384, 
+    18432, 17920, 18176, 18112, 18128,     0, 16384, 18432, 
+    17920, 18176, 18112, 18128,     0, 16384, 18432, 17920, 
+    18176, 18112, 18128, 18130,     0, 16384, 18432, 17920, 
+    18176, 18112, 18128,     0, 16384, 18432, 17920, 18176, 
+    18112, 18128, 18132,     0, 16384, 18432, 17920, 18176, 
+    18112, 18128, 18132,     0, 16384, 18432, 17920, 18176, 
+    18112, 18128, 18136, 18134,     0, 16384, 18432, 17920, 
+    18176, 18112, 18128,     0, 16384, 18432, 17920, 18176, 
+    18112, 18144, 18136,     0, 16384, 18432, 17920, 18176, 
+    18112, 18144, 18136,     0, 16384, 18432, 17920, 18176, 
+    18112, 18144, 18136, 18138,     0, 16384, 18432, 17920, 
+    18176, 18112, 18144, 18136,     0, 16384, 18432, 17920, 
+    18176, 18112, 18144, 18145, 18140,     0, 16384, 18432, 
+    17920, 18176, 18112, 18144, 18145, 18140,     0, 16384, 
+    18432, 17920, 18176, 18112, 18144, 18145, 18140, 18142, 
+        0, 16384, 18432, 17920, 18176, 18112,     0, 16384, 
+    18432, 17920, 18176, 18177, 18144,     0, 16384, 18432, 
+    17920, 18176, 18177, 18144,     0, 16384, 18432, 17920, 
+    18176, 18177, 18144, 18146,     0, 16384, 18432, 17920, 
+    18176, 18177, 18144,     0, 16384, 18432, 17920, 18176, 
+    18177, 18144, 18148,     0, 16384, 18432, 17920, 18176, 
+    18177, 18144, 18148,     0, 16384, 18432, 17920, 18176, 
+    18177, 18144, 18152, 18150,     0, 16384, 18432, 17920, 
+    18176, 18177, 18144,     0, 16384, 18432, 17920, 18176, 
+    18177, 18144, 18152,     0, 16384, 18432, 17920, 18176, 
+    18177, 18144, 18152,     0, 16384, 18432, 17920, 18176, 
+    18177, 18144, 18152, 18154,     0, 16384, 18432, 17920, 
+    18176, 18177, 18144, 18152,     0, 16384, 18432, 17920, 
+    18176, 18177, 18144, 18160, 18156,     0, 16384, 18432, 
+    17920, 18176, 18177, 18144, 18160, 18156,     0, 16384, 
+    18432, 17920, 18176, 18177, 18144, 18160, 18161, 18158, 
+        0, 16384, 18432, 17920, 18176, 18177, 18144,     0, 
+    16384, 18432, 17920, 18176, 18177, 18144, 18160,     0, 
+    16384, 18432, 17920, 18176, 18177, 18179, 18160,     0, 
+    16384, 18432, 17920, 18176, 18177, 18179, 18160, 18162, 
+        0, 16384, 18432, 17920, 18176, 18177, 18179, 18160, 
+        0, 16384, 18432, 17920, 18176, 18177, 18179, 18160, 
+    18164,     0, 16384, 18432, 17920, 18176, 18177, 18179, 
+    18160, 18164,     0, 16384, 18432, 17920, 18176, 18177, 
+    18179, 18160, 18168, 18166,     0, 16384, 18432, 17920, 
+    18176, 18177, 18179, 18160,     0, 16384, 18432, 17920, 
+    18176, 18177, 18179, 18160, 18168,     0, 16384, 18432, 
+    17920, 18176, 18177, 18179, 18160, 18168,     0, 16384, 
+    18432, 17920, 18176, 18177, 18179, 18160, 18168, 18170, 
+        0, 16384, 18432, 17920, 18176, 18177, 18179, 18183, 
+    18168,     0, 16384, 18432, 17920, 18176, 18177, 18179, 
+    18183, 18168, 18172,     0, 16384, 18432, 17920, 18176, 
+    18177, 18179, 18183, 18168, 18172,     0, 16384, 18432, 
+    17920, 18176, 18177, 18179, 18183, 18168, 18172, 18174, 
+        0, 16384, 18432, 17920,     0, 16384, 18432, 17920, 
+    18176,     0, 16384, 18432, 18433, 18176,     0, 16384, 
+    18432, 18433, 18176, 18178,     0, 16384, 18432, 18433, 
+    18176,     0, 16384, 18432, 18433, 18176, 18180,     0, 
+    16384, 18432, 18433, 18176, 18180,     0, 16384, 18432, 
+    18433, 18176, 18184, 18182,     0, 16384, 18432, 18433, 
+    18176,     0, 16384, 18432, 18433, 18176, 18184,     0, 
+    16384, 18432, 18433, 18176, 18184,     0, 16384, 18432, 
+    18433, 18176, 18184, 18186,     0, 16384, 18432, 18433, 
+    18176, 18184,     0, 16384, 18432, 18433, 18176, 18192, 
+    18188,     0, 16384, 18432, 18433, 18176, 18192, 18188, 
+        0, 16384, 18432, 18433, 18176, 18192, 18193, 18190, 
+        0, 16384, 18432, 18433, 18176,     0, 16384, 18432, 
+    18433, 18176, 18192,     0, 16384, 18432, 18433, 18176, 
+    18192,     0, 16384, 18432, 18433, 18176, 18192, 18194, 
+        0, 16384, 18432, 18433, 18176, 18192,     0, 16384, 
+    18432, 18433, 18176, 18192, 18196,     0, 16384, 18432, 
+    18433, 18176, 18192, 18196,     0, 16384, 18432, 18433, 
+    18176, 18192, 18200, 18198,     0, 16384, 18432, 18433, 
+    18176, 18192,     0, 16384, 18432, 18433, 18176, 18208, 
+    18200,     0, 16384, 18432, 18433, 18176, 18208, 18200, 
+        0, 16384, 18432, 18433, 18176, 18208, 18200, 18202, 
+        0, 16384, 18432, 18433, 18176, 18208, 18200,     0, 
+    16384, 18432, 18433, 18176, 18208, 18209, 18204,     0, 
+    16384, 18432, 18433, 18176, 18208, 18209, 18204,     0, 
+    16384, 18432, 18433, 18176, 18208, 18209, 18204, 18206, 
+        0, 16384, 18432, 18433, 18176,     0, 16384, 18432, 
+    18433, 18176, 18208,     0, 16384, 18432, 18433, 18176, 
+    18208,     0, 16384, 18432, 18433, 18176, 18208, 18210, 
+        0, 16384, 18432, 18433, 18176, 18208,     0, 16384, 
+    18432, 18433, 18176, 18208, 18212,     0, 16384, 18432, 
+    18433, 18176, 18208, 18212,     0, 16384, 18432, 18433, 
+    18176, 18208, 18216, 18214,     0, 16384, 18432, 18433, 
+    18176, 18208,     0, 16384, 18432, 18433, 18176, 18208, 
+    18216,     0, 16384, 18432, 18433, 18176, 18208, 18216, 
+        0, 16384, 18432, 18433, 18176, 18208, 18216, 18218, 
+        0, 16384, 18432, 18433, 18176, 18208, 18216,     0, 
+    16384, 18432, 18433, 18176, 18208, 18224, 18220,     0, 
+    16384, 18432, 18433, 18176, 18208, 18224, 18220,     0, 
+    16384, 18432, 18433, 18176, 18208, 18224, 18225, 18222, 
+        0, 16384, 18432, 18433, 18176, 18208,     0, 16384, 
+    18432, 18433, 18176, 18240, 18224,     0, 16384, 18432, 
+    18433, 18176, 18240, 18224,     0, 16384, 18432, 18433, 
+    18176, 18240, 18224, 18226,     0, 16384, 18432, 18433, 
+    18176, 18240, 18224,     0, 16384, 18432, 18433, 18176, 
+    18240, 18224, 18228,     0, 16384, 18432, 18433, 18176, 
+    18240, 18224, 18228,     0, 16384, 18432, 18433, 18176, 
+    18240, 18224, 18232, 18230,     0, 16384, 18432, 18433, 
+    18176, 18240, 18224,     0, 16384, 18432, 18433, 18176, 
+    18240, 18241, 18232,     0, 16384, 18432, 18433, 18176, 
+    18240, 18241, 18232,     0, 16384, 18432, 18433, 18176, 
+    18240, 18241, 18232, 18234,     0, 16384, 18432, 18433, 
+    18176, 18240, 18241, 18232,     0, 16384, 18432, 18433, 
+    18176, 18240, 18241, 18232, 18236,     0, 16384, 18432, 
+    18433, 18176, 18240, 18241, 18243, 18236,     0, 16384, 
+    18432, 18433, 18176, 18240, 18241, 18243, 18236, 18238, 
+        0, 16384, 18432, 18433, 18176,     0, 16384, 18432, 
+    18433, 18176, 18240,     0, 16384, 18432, 18433, 18176, 
+    18240,     0, 16384, 18432, 18433, 18176, 18240, 18242, 
+        0, 16384, 18432, 18433, 18176, 18240,     0, 16384, 
+    18432, 18433, 18176, 18240, 18244,     0, 16384, 18432, 
+    18433, 18176, 18240, 18244,     0, 16384, 18432, 18433, 
+    18176, 18240, 18248, 18246,     0, 16384, 18432, 18433, 
+    18176, 18240,     0, 16384, 18432, 18433, 18176, 18240, 
+    18248,     0, 16384, 18432, 18433, 18176, 18240, 18248, 
+        0, 16384, 18432, 18433, 18176, 18240, 18248, 18250, 
+        0, 16384, 18432, 18433, 18176, 18240, 18248,     0, 
+    16384, 18432, 18433, 18176, 18240, 18256, 18252,     0, 
+    16384, 18432, 18433, 18176, 18240, 18256, 18252,     0, 
+    16384, 18432, 18433, 18176, 18240, 18256, 18257, 18254, 
+        0, 16384, 18432, 18433, 18176, 18240,     0, 16384, 
+    18432, 18433, 18176, 18240, 18256,     0, 16384, 18432, 
+    18433, 18176, 18240, 18256,     0, 16384, 18432, 18433, 
+    18176, 18240, 18256, 18258,     0, 16384, 18432, 18433, 
+    18176, 18240, 18256,     0, 16384, 18432, 18433, 18176, 
+    18240, 18256, 18260,     0, 16384, 18432, 18433, 18176, 
+    18240, 18256, 18260,     0, 16384, 18432, 18433, 18176, 
+    18240, 18256, 18264, 18262,     0, 16384, 18432, 18433, 
+    18176, 18240, 18256,     0, 16384, 18432, 18433, 18176, 
+    18240, 18272, 18264,     0, 16384, 18432, 18433, 18176, 
+    18240, 18272, 18264,     0, 16384, 18432, 18433, 18176, 
+    18240, 18272, 18264, 18266,     0, 16384, 18432, 18433, 
+    18176, 18240, 18272, 18264,     0, 16384, 18432, 18433, 
+    18176, 18240, 18272, 18273, 18268,     0, 16384, 18432, 
+    18433, 18176, 18240, 18272, 18273, 18268,     0, 16384, 
+    18432, 18433, 18176, 18240, 18272, 18273, 18268, 18270, 
+        0, 16384, 18432, 18433, 18176, 18240,     0, 16384, 
+    18432, 18433, 18176, 18304, 18272,     0, 16384, 18432, 
+    18433, 18176, 18304, 18272,     0, 16384, 18432, 18433, 
+    18176, 18304, 18272, 18274,     0, 16384, 18432, 18433, 
+    18176, 18304, 18272,     0, 16384, 18432, 18433, 18176, 
+    18304, 18272, 18276,     0, 16384, 18432, 18433, 18176, 
+    18304, 18272, 18276,     0, 16384, 18432, 18433, 18176, 
+    18304, 18272, 18280, 18278,     0, 16384, 18432, 18433, 
+    18176, 18304, 18272,     0, 16384, 18432, 18433, 18176, 
+    18304, 18272, 18280,     0, 16384, 18432, 18433, 18176, 
+    18304, 18272, 18280,     0, 16384, 18432, 18433, 18176, 
+    18304, 18272, 18280, 18282,     0, 16384, 18432, 18433, 
+    18176, 18304, 18272, 18280,     0, 16384, 18432, 18433, 
+    18176, 18304, 18272, 18288, 18284,     0, 16384, 18432, 
+    18433, 18176, 18304, 18272, 18288, 18284,     0, 16384, 
+    18432, 18433, 18176, 18304, 18272, 18288, 18289, 18286, 
+        0, 16384, 18432, 18433, 18176, 18304, 18272,     0, 
+    16384, 18432, 18433, 18176, 18304, 18305, 18288,     0, 
+    16384, 18432, 18433, 18176, 18304, 18305, 18288,     0, 
+    16384, 18432, 18433, 18176, 18304, 18305, 18288, 18290, 
+        0, 16384, 18432, 18433, 18176, 18304, 18305, 18288, 
+        0, 16384, 18432, 18433, 18176, 18304, 18305, 18288, 
+    18292,     0, 16384, 18432, 18433, 18176, 18304, 18305, 
+    18288, 18292,     0, 16384, 18432, 18433, 18176, 18304, 
+    18305, 18288, 18296, 18294,     0, 16384, 18432, 18433, 
+    18176, 18304, 18305, 18288,     0, 16384, 18432, 18433, 
+    18176, 18304, 18305, 18288, 18296,     0, 16384, 18432, 
+    18433, 18176, 18304, 18305, 18307, 18296,     0, 16384, 
+    18432, 18433, 18176, 18304, 18305, 18307, 18296, 18298, 
+        0, 16384, 18432, 18433, 18176, 18304, 18305, 18307, 
+    18296,     0, 16384, 18432, 18433, 18176, 18304, 18305, 
+    18307, 18296, 18300,     0, 16384, 18432, 18433, 18176, 
+    18304, 18305, 18307, 18296, 18300,     0, 16384, 18432, 
+    18433, 18176, 18304, 18305, 18307, 18296, 18300, 18302, 
+        0, 16384, 18432, 18433, 18176,     0, 16384, 18432, 
+    18433, 18176, 18304,     0, 16384, 18432, 18433, 18176, 
+    18304,     0, 16384, 18432, 18433, 18176, 18304, 18306, 
+        0, 16384, 18432, 18433, 18435, 18304,     0, 16384, 
+    18432, 18433, 18435, 18304, 18308,     0, 16384, 18432, 
+    18433, 18435, 18304, 18308,     0, 16384, 18432, 18433, 
+    18435, 18304, 18312, 18310,     0, 16384, 18432, 18433, 
+    18435, 18304,     0, 16384, 18432, 18433, 18435, 18304, 
+    18312,     0, 16384, 18432, 18433, 18435, 18304, 18312, 
+        0, 16384, 18432, 18433, 18435, 18304, 18312, 18314, 
+        0, 16384, 18432, 18433, 18435, 18304, 18312,     0, 
+    16384, 18432, 18433, 18435, 18304, 18320, 18316,     0, 
+    16384, 18432, 18433, 18435, 18304, 18320, 18316,     0, 
+    16384, 18432, 18433, 18435, 18304, 18320, 18321, 18318, 
+        0, 16384, 18432, 18433, 18435, 18304,     0, 16384, 
+    18432, 18433, 18435, 18304, 18320,     0, 16384, 18432, 
+    18433, 18435, 18304, 18320,     0, 16384, 18432, 18433, 
+    18435, 18304, 18320, 18322,     0, 16384, 18432, 18433, 
+    18435, 18304, 18320,     0, 16384, 18432, 18433, 18435, 
+    18304, 18320, 18324,     0, 16384, 18432, 18433, 18435, 
+    18304, 18320, 18324,     0, 16384, 18432, 18433, 18435, 
+    18304, 18320, 18328, 18326,     0, 16384, 18432, 18433, 
+    18435, 18304, 18320,     0, 16384, 18432, 18433, 18435, 
+    18304, 18336, 18328,     0, 16384, 18432, 18433, 18435, 
+    18304, 18336, 18328,     0, 16384, 18432, 18433, 18435, 
+    18304, 18336, 18328, 18330,     0, 16384, 18432, 18433, 
+    18435, 18304, 18336, 18328,     0, 16384, 18432, 18433, 
+    18435, 18304, 18336, 18337, 18332,     0, 16384, 18432, 
+    18433, 18435, 18304, 18336, 18337, 18332,     0, 16384, 
+    18432, 18433, 18435, 18304, 18336, 18337, 18332, 18334, 
+        0, 16384, 18432, 18433, 18435, 18304,     0, 16384, 
+    18432, 18433, 18435, 18304, 18336,     0, 16384, 18432, 
+    18433, 18435, 18304, 18336,     0, 16384, 18432, 18433, 
+    18435, 18304, 18336, 18338,     0, 16384, 18432, 18433, 
+    18435, 18304, 18336,     0, 16384, 18432, 18433, 18435, 
+    18304, 18336, 18340,     0, 16384, 18432, 18433, 18435, 
+    18304, 18336, 18340,     0, 16384, 18432, 18433, 18435, 
+    18304, 18336, 18344, 18342,     0, 16384, 18432, 18433, 
+    18435, 18304, 18336,     0, 16384, 18432, 18433, 18435, 
+    18304, 18336, 18344,     0, 16384, 18432, 18433, 18435, 
+    18304, 18336, 18344,     0, 16384, 18432, 18433, 18435, 
+    18304, 18336, 18344, 18346,     0, 16384, 18432, 18433, 
+    18435, 18304, 18336, 18344,     0, 16384, 18432, 18433, 
+    18435, 18304, 18336, 18352, 18348,     0, 16384, 18432, 
+    18433, 18435, 18304, 18336, 18352, 18348,     0, 16384, 
+    18432, 18433, 18435, 18304, 18336, 18352, 18353, 18350, 
+        0, 16384, 18432, 18433, 18435, 18304, 18336,     0, 
+    16384, 18432, 18433, 18435, 18304, 18368, 18352,     0, 
+    16384, 18432, 18433, 18435, 18304, 18368, 18352,     0, 
+    16384, 18432, 18433, 18435, 18304, 18368, 18352, 18354, 
+        0, 16384, 18432, 18433, 18435, 18304, 18368, 18352, 
+        0, 16384, 18432, 18433, 18435, 18304, 18368, 18352, 
+    18356,     0, 16384, 18432, 18433, 18435, 18304, 18368, 
+    18352, 18356,     0, 16384, 18432, 18433, 18435, 18304, 
+    18368, 18352, 18360, 18358,     0, 16384, 18432, 18433, 
+    18435, 18304, 18368, 18352,     0, 16384, 18432, 18433, 
+    18435, 18304, 18368, 18369, 18360,     0, 16384, 18432, 
+    18433, 18435, 18304, 18368, 18369, 18360,     0, 16384, 
+    18432, 18433, 18435, 18304, 18368, 18369, 18360, 18362, 
+        0, 16384, 18432, 18433, 18435, 18304, 18368, 18369, 
+    18360,     0, 16384, 18432, 18433, 18435, 18304, 18368, 
+    18369, 18360, 18364,     0, 16384, 18432, 18433, 18435, 
+    18304, 18368, 18369, 18371, 18364,     0, 16384, 18432, 
+    18433, 18435, 18304, 18368, 18369, 18371, 18364, 18366, 
+        0, 16384, 18432, 18433, 18435, 18304,     0, 16384, 
+    18432, 18433, 18435, 18304, 18368,     0, 16384, 18432, 
+    18433, 18435, 18304, 18368,     0, 16384, 18432, 18433, 
+    18435, 18304, 18368, 18370,     0, 16384, 18432, 18433, 
+    18435, 18304, 18368,     0, 16384, 18432, 18433, 18435, 
+    18304, 18368, 18372,     0, 16384, 18432, 18433, 18435, 
+    18304, 18368, 18372,     0, 16384, 18432, 18433, 18435, 
+    18304, 18368, 18376, 18374,     0, 16384, 18432, 18433, 
+    18435, 18439, 18368,     0, 16384, 18432, 18433, 18435, 
+    18439, 18368, 18376,     0, 16384, 18432, 18433, 18435, 
+    18439, 18368, 18376,     0, 16384, 18432, 18433, 18435, 
+    18439, 18368, 18376, 18378,     0, 16384, 18432, 18433, 
+    18435, 18439, 18368, 18376,     0, 16384, 18432, 18433, 
+    18435, 18439, 18368, 18384, 18380,     0, 16384, 18432, 
+    18433, 18435, 18439, 18368, 18384, 18380,     0, 16384, 
+    18432, 18433, 18435, 18439, 18368, 18384, 18385, 18382, 
+        0, 16384, 18432, 18433, 18435, 18439, 18368,     0, 
+    16384, 18432, 18433, 18435, 18439, 18368, 18384,     0, 
+    16384, 18432, 18433, 18435, 18439, 18368, 18384,     0, 
+    16384, 18432, 18433, 18435, 18439, 18368, 18384, 18386, 
+        0, 16384, 18432, 18433, 18435, 18439, 18368, 18384, 
+        0, 16384, 18432, 18433, 18435, 18439, 18368, 18384, 
+    18388,     0, 16384, 18432, 18433, 18435, 18439, 18368, 
+    18384, 18388,     0, 16384, 18432, 18433, 18435, 18439, 
+    18368, 18384, 18392, 18390,     0, 16384, 18432, 18433, 
+    18435, 18439, 18368, 18384,     0, 16384, 18432, 18433, 
+    18435, 18439, 18368, 18400, 18392,     0, 16384, 18432, 
+    18433, 18435, 18439, 18368, 18400, 18392,     0, 16384, 
+    18432, 18433, 18435, 18439, 18368, 18400, 18392, 18394, 
+        0, 16384, 18432, 18433, 18435, 18439, 18368, 18400, 
+    18392,     0, 16384, 18432, 18433, 18435, 18439, 18368, 
+    18400, 18401, 18396,     0, 16384, 18432, 18433, 18435, 
+    18439, 18368, 18400, 18401, 18396,     0, 16384, 18432, 
+    18433, 18435, 18439, 18368, 18400, 18401, 18396, 18398, 
+        0, 16384, 18432, 18433, 18435, 18439, 18368,     0, 
+    16384, 18432, 18433, 18435, 18439, 18368, 18400,     0, 
+    16384, 18432, 18433, 18435, 18439, 18368, 18400,     0, 
+    16384, 18432, 18433, 18435, 18439, 18368, 18400, 18402, 
+        0, 16384, 18432, 18433, 18435, 18439, 18368, 18400, 
+        0, 16384, 18432, 18433, 18435, 18439, 18368, 18400, 
+    18404,     0, 16384, 18432, 18433, 18435, 18439, 18368, 
+    18400, 18404,     0, 16384, 18432, 18433, 18435, 18439, 
+    18368, 18400, 18408, 18406,     0, 16384, 18432, 18433, 
+    18435, 18439, 18368, 18400,     0, 16384, 18432, 18433, 
+    18435, 18439, 18368, 18400, 18408,     0, 16384, 18432, 
+    18433, 18435, 18439, 18368, 18400, 18408,     0, 16384, 
+    18432, 18433, 18435, 18439, 18368, 18400, 18408, 18410, 
+        0, 16384, 18432, 18433, 18435, 18439, 18368, 18400, 
+    18408,     0, 16384, 18432, 18433, 18435, 18439, 18368, 
+    18400, 18416, 18412,     0, 16384, 18432, 18433, 18435, 
+    18439, 18368, 18400, 18416, 18412,     0, 16384, 18432, 
+    18433, 18435, 18439, 18368, 18400, 18416, 18417, 18414, 
+        0, 16384, 18432, 18433, 18435, 18439, 18447, 18400, 
+        0, 16384, 18432, 18433, 18435, 18439, 18447, 18400, 
+    18416,     0, 16384, 18432, 18433, 18435, 18439, 18447, 
+    18400, 18416,     0, 16384, 18432, 18433, 18435, 18439, 
+    18447, 18400, 18416, 18418,     0, 16384, 18432, 18433, 
+    18435, 18439, 18447, 18400, 18416,     0, 16384, 18432, 
+    18433, 18435, 18439, 18447, 18400, 18416, 18420,     0, 
+    16384, 18432, 18433, 18435, 18439, 18447, 18400, 18416, 
+    18420,     0, 16384, 18432, 18433, 18435, 18439, 18447, 
+    18400, 18416, 18424, 18422,     0, 16384, 18432, 18433, 
+    18435, 18439, 18447, 18400, 18416,     0, 16384, 18432, 
+    18433, 18435, 18439, 18447, 18400, 18416, 18424,     0, 
+    16384, 18432, 18433, 18435, 18439, 18447, 18400, 18416, 
+    18424,     0, 16384, 18432, 18433, 18435, 18439, 18447, 
+    18400, 18416, 18424, 18426,     0, 16384, 18432, 18433, 
+    18435, 18439, 18447, 18400, 18416, 18424,     0, 16384, 
+    18432, 18433, 18435, 18439, 18447, 18400, 18416, 18424, 
+    18428,     0, 16384, 18432, 18433, 18435, 18439, 18447, 
+    18400, 18416, 18424, 18428,     0, 16384, 18432, 18433, 
+    18435, 18439, 18447, 18400, 18416, 18424, 18428, 18430, 
+        0, 16384,     0, 16384, 18432,     0, 16384, 18432, 
+        0, 16384, 18432, 18434,     0, 16384, 18432,     0, 
+    16384, 18432, 18436,     0, 16384, 18432, 18436,     0, 
+    16384, 18432, 18440, 18438,     0, 16384, 18432,     0, 
+    16384, 18432, 18440,     0, 16384, 18432, 18440,     0, 
+    16384, 18432, 18440, 18442,     0, 16384, 18432, 18440, 
+        0, 16384, 18432, 18448, 18444,     0, 16384, 18432, 
+    18448, 18444,     0, 16384, 18432, 18448, 18449, 18446, 
+        0, 16384, 18432,     0, 16384, 18432, 18448,     0, 
+    16384, 18432, 18448,     0, 16384, 18432, 18448, 18450, 
+        0, 16384, 18432, 18448,     0, 16384, 18432, 18448, 
+    18452,     0, 16384, 18432, 18448, 18452,     0, 16384, 
+    18432, 18448, 18456, 18454,     0, 16384, 18432, 18448, 
+        0, 16384, 18432, 18464, 18456,     0, 16384, 18432, 
+    18464, 18456,     0, 16384, 18432, 18464, 18456, 18458, 
+        0, 16384, 18432, 18464, 18456,     0, 16384, 18432, 
+    18464, 18465, 18460,     0, 16384, 18432, 18464, 18465, 
+    18460,     0, 16384, 18432, 18464, 18465, 18460, 18462, 
+        0, 16384, 18432,     0, 16384, 18432, 18464,     0, 
+    16384, 18432, 18464,     0, 16384, 18432, 18464, 18466, 
+        0, 16384, 18432, 18464,     0, 16384, 18432, 18464, 
+    18468,     0, 16384, 18432, 18464, 18468,     0, 16384, 
+    18432, 18464, 18472, 18470,     0, 16384, 18432, 18464, 
+        0, 16384, 18432, 18464, 18472,     0, 16384, 18432, 
+    18464, 18472,     0, 16384, 18432, 18464, 18472, 18474, 
+        0, 16384, 18432, 18464, 18472,     0, 16384, 18432, 
+    18464, 18480, 18476,     0, 16384, 18432, 18464, 18480, 
+    18476,     0, 16384, 18432, 18464, 18480, 18481, 18478, 
+        0, 16384, 18432, 18464,     0, 16384, 18432, 18496, 
+    18480,     0, 16384, 18432, 18496, 18480,     0, 16384, 
+    18432, 18496, 18480, 18482,     0, 16384, 18432, 18496, 
+    18480,     0, 16384, 18432, 18496, 18480, 18484,     0, 
+    16384, 18432, 18496, 18480, 18484,     0, 16384, 18432, 
+    18496, 18480, 18488, 18486,     0, 16384, 18432, 18496, 
+    18480,     0, 16384, 18432, 18496, 18497, 18488,     0, 
+    16384, 18432, 18496, 18497, 18488,     0, 16384, 18432, 
+    18496, 18497, 18488, 18490,     0, 16384, 18432, 18496, 
+    18497, 18488,     0, 16384, 18432, 18496, 18497, 18488, 
+    18492,     0, 16384, 18432, 18496, 18497, 18499, 18492, 
+        0, 16384, 18432, 18496, 18497, 18499, 18492, 18494, 
+        0, 16384, 18432,     0, 16384, 18432, 18496,     0, 
+    16384, 18432, 18496,     0, 16384, 18432, 18496, 18498, 
+        0, 16384, 18432, 18496,     0, 16384, 18432, 18496, 
+    18500,     0, 16384, 18432, 18496, 18500,     0, 16384, 
+    18432, 18496, 18504, 18502,     0, 16384, 18432, 18496, 
+        0, 16384, 18432, 18496, 18504,     0, 16384, 18432, 
+    18496, 18504,     0, 16384, 18432, 18496, 18504, 18506, 
+        0, 16384, 18432, 18496, 18504,     0, 16384, 18432, 
+    18496, 18512, 18508,     0, 16384, 18432, 18496, 18512, 
+    18508,     0, 16384, 18432, 18496, 18512, 18513, 18510, 
+        0, 16384, 18432, 18496,     0, 16384, 18432, 18496, 
+    18512,     0, 16384, 18432, 18496, 18512,     0, 16384, 
+    18432, 18496, 18512, 18514,     0, 16384, 18432, 18496, 
+    18512,     0, 16384, 18432, 18496, 18512, 18516,     0, 
+    16384, 18432, 18496, 18512, 18516,     0, 16384, 18432, 
+    18496, 18512, 18520, 18518,     0, 16384, 18432, 18496, 
+    18512,     0, 16384, 18432, 18496, 18528, 18520,     0, 
+    16384, 18432, 18496, 18528, 18520,     0, 16384, 18432, 
+    18496, 18528, 18520, 18522,     0, 16384, 18432, 18496, 
+    18528, 18520,     0, 16384, 18432, 18496, 18528, 18529, 
+    18524,     0, 16384, 18432, 18496, 18528, 18529, 18524, 
+        0, 16384, 18432, 18496, 18528, 18529, 18524, 18526, 
+        0, 16384, 18432, 18496,     0, 16384, 18432, 18560, 
+    18528,     0, 16384, 18432, 18560, 18528,     0, 16384, 
+    18432, 18560, 18528, 18530,     0, 16384, 18432, 18560, 
+    18528,     0, 16384, 18432, 18560, 18528, 18532,     0, 
+    16384, 18432, 18560, 18528, 18532,     0, 16384, 18432, 
+    18560, 18528, 18536, 18534,     0, 16384, 18432, 18560, 
+    18528,     0, 16384, 18432, 18560, 18528, 18536,     0, 
+    16384, 18432, 18560, 18528, 18536,     0, 16384, 18432, 
+    18560, 18528, 18536, 18538,     0, 16384, 18432, 18560, 
+    18528, 18536,     0, 16384, 18432, 18560, 18528, 18544, 
+    18540,     0, 16384, 18432, 18560, 18528, 18544, 18540, 
+        0, 16384, 18432, 18560, 18528, 18544, 18545, 18542, 
+        0, 16384, 18432, 18560, 18528,     0, 16384, 18432, 
+    18560, 18561, 18544,     0, 16384, 18432, 18560, 18561, 
+    18544,     0, 16384, 18432, 18560, 18561, 18544, 18546, 
+        0, 16384, 18432, 18560, 18561, 18544,     0, 16384, 
+    18432, 18560, 18561, 18544, 18548,     0, 16384, 18432, 
+    18560, 18561, 18544, 18548,     0, 16384, 18432, 18560, 
+    18561, 18544, 18552, 18550,     0, 16384, 18432, 18560, 
+    18561, 18544,     0, 16384, 18432, 18560, 18561, 18544, 
+    18552,     0, 16384, 18432, 18560, 18561, 18563, 18552, 
+        0, 16384, 18432, 18560, 18561, 18563, 18552, 18554, 
+        0, 16384, 18432, 18560, 18561, 18563, 18552,     0, 
+    16384, 18432, 18560, 18561, 18563, 18552, 18556,     0, 
+    16384, 18432, 18560, 18561, 18563, 18552, 18556,     0, 
+    16384, 18432, 18560, 18561, 18563, 18552, 18556, 18558, 
+        0, 16384, 18432,     0, 16384, 18432, 18560,     0, 
+    16384, 18432, 18560,     0, 16384, 18432, 18560, 18562, 
+        0, 16384, 18432, 18560,     0, 16384, 18432, 18560, 
+    18564,     0, 16384, 18432, 18560, 18564,     0, 16384, 
+    18432, 18560, 18568, 18566,     0, 16384, 18432, 18560, 
+        0, 16384, 18432, 18560, 18568,     0, 16384, 18432, 
+    18560, 18568,     0, 16384, 18432, 18560, 18568, 18570, 
+        0, 16384, 18432, 18560, 18568,     0, 16384, 18432, 
+    18560, 18576, 18572,     0, 16384, 18432, 18560, 18576, 
+    18572,     0, 16384, 18432, 18560, 18576, 18577, 18574, 
+        0, 16384, 18432, 18560,     0, 16384, 18432, 18560, 
+    18576,     0, 16384, 18432, 18560, 18576,     0, 16384, 
+    18432, 18560, 18576, 18578,     0, 16384, 18432, 18560, 
+    18576,     0, 16384, 18432, 18560, 18576, 18580,     0, 
+    16384, 18432, 18560, 18576, 18580,     0, 16384, 18432, 
+    18560, 18576, 18584, 18582,     0, 16384, 18432, 18560, 
+    18576,     0, 16384, 18432, 18560, 18592, 18584,     0, 
+    16384, 18432, 18560, 18592, 18584,     0, 16384, 18432, 
+    18560, 18592, 18584, 18586,     0, 16384, 18432, 18560, 
+    18592, 18584,     0, 16384, 18432, 18560, 18592, 18593, 
+    18588,     0, 16384, 18432, 18560, 18592, 18593, 18588, 
+        0, 16384, 18432, 18560, 18592, 18593, 18588, 18590, 
+        0, 16384, 18432, 18560,     0, 16384, 18432, 18560, 
+    18592,     0, 16384, 18432, 18560, 18592,     0, 16384, 
+    18432, 18560, 18592, 18594,     0, 16384, 18432, 18560, 
+    18592,     0, 16384, 18432, 18560, 18592, 18596,     0, 
+    16384, 18432, 18560, 18592, 18596,     0, 16384, 18432, 
+    18560, 18592, 18600, 18598,     0, 16384, 18432, 18560, 
+    18592,     0, 16384, 18432, 18560, 18592, 18600,     0, 
+    16384, 18432, 18560, 18592, 18600,     0, 16384, 18432, 
+    18560, 18592, 18600, 18602,     0, 16384, 18432, 18560, 
+    18592, 18600,     0, 16384, 18432, 18560, 18592, 18608, 
+    18604,     0, 16384, 18432, 18560, 18592, 18608, 18604, 
+        0, 16384, 18432, 18560, 18592, 18608, 18609, 18606, 
+        0, 16384, 18432, 18560, 18592,     0, 16384, 18432, 
+    18560, 18624, 18608,     0, 16384, 18432, 18560, 18624, 
+    18608,     0, 16384, 18432, 18560, 18624, 18608, 18610, 
+        0, 16384, 18432, 18560, 18624, 18608,     0, 16384, 
+    18432, 18560, 18624, 18608, 18612,     0, 16384, 18432, 
+    18560, 18624, 18608, 18612,     0, 16384, 18432, 18560, 
+    18624, 18608, 18616, 18614,     0, 16384, 18432, 18560, 
+    18624, 18608,     0, 16384, 18432, 18560, 18624, 18625, 
+    18616,     0, 16384, 18432, 18560, 18624, 18625, 18616, 
+        0, 16384, 18432, 18560, 18624, 18625, 18616, 18618, 
+        0, 16384, 18432, 18560, 18624, 18625, 18616,     0, 
+    16384, 18432, 18560, 18624, 18625, 18616, 18620,     0, 
+    16384, 18432, 18560, 18624, 18625, 18627, 18620,     0, 
+    16384, 18432, 18560, 18624, 18625, 18627, 18620, 18622, 
+        0, 16384, 18432, 18560,     0, 16384, 18432, 18688, 
+    18624,     0, 16384, 18432, 18688, 18624,     0, 16384, 
+    18432, 18688, 18624, 18626,     0, 16384, 18432, 18688, 
+    18624,     0, 16384, 18432, 18688, 18624, 18628,     0, 
+    16384, 18432, 18688, 18624, 18628,     0, 16384, 18432, 
+    18688, 18624, 18632, 18630,     0, 16384, 18432, 18688, 
+    18624,     0, 16384, 18432, 18688, 18624, 18632,     0, 
+    16384, 18432, 18688, 18624, 18632,     0, 16384, 18432, 
+    18688, 18624, 18632, 18634,     0, 16384, 18432, 18688, 
+    18624, 18632,     0, 16384, 18432, 18688, 18624, 18640, 
+    18636,     0, 16384, 18432, 18688, 18624, 18640, 18636, 
+        0, 16384, 18432, 18688, 18624, 18640, 18641, 18638, 
+        0, 16384, 18432, 18688, 18624,     0, 16384, 18432, 
+    18688, 18624, 18640,     0, 16384, 18432, 18688, 18624, 
+    18640,     0, 16384, 18432, 18688, 18624, 18640, 18642, 
+        0, 16384, 18432, 18688, 18624, 18640,     0, 16384, 
+    18432, 18688, 18624, 18640, 18644,     0, 16384, 18432, 
+    18688, 18624, 18640, 18644,     0, 16384, 18432, 18688, 
+    18624, 18640, 18648, 18646,     0, 16384, 18432, 18688, 
+    18624, 18640,     0, 16384, 18432, 18688, 18624, 18656, 
+    18648,     0, 16384, 18432, 18688, 18624, 18656, 18648, 
+        0, 16384, 18432, 18688, 18624, 18656, 18648, 18650, 
+        0, 16384, 18432, 18688, 18624, 18656, 18648,     0, 
+    16384, 18432, 18688, 18624, 18656, 18657, 18652,     0, 
+    16384, 18432, 18688, 18624, 18656, 18657, 18652,     0, 
+    16384, 18432, 18688, 18624, 18656, 18657, 18652, 18654, 
+        0, 16384, 18432, 18688, 18624,     0, 16384, 18432, 
+    18688, 18689, 18656,     0, 16384, 18432, 18688, 18689, 
+    18656,     0, 16384, 18432, 18688, 18689, 18656, 18658, 
+        0, 16384, 18432, 18688, 18689, 18656,     0, 16384, 
+    18432, 18688, 18689, 18656, 18660,     0, 16384, 18432, 
+    18688, 18689, 18656, 18660,     0, 16384, 18432, 18688, 
+    18689, 18656, 18664, 18662,     0, 16384, 18432, 18688, 
+    18689, 18656,     0, 16384, 18432, 18688, 18689, 18656, 
+    18664,     0, 16384, 18432, 18688, 18689, 18656, 18664, 
+        0, 16384, 18432, 18688, 18689, 18656, 18664, 18666, 
+        0, 16384, 18432, 18688, 18689, 18656, 18664,     0, 
+    16384, 18432, 18688, 18689, 18656, 18672, 18668,     0, 
+    16384, 18432, 18688, 18689, 18656, 18672, 18668,     0, 
+    16384, 18432, 18688, 18689, 18656, 18672, 18673, 18670, 
+        0, 16384, 18432, 18688, 18689, 18656,     0, 16384, 
+    18432, 18688, 18689, 18656, 18672,     0, 16384, 18432, 
+    18688, 18689, 18691, 18672,     0, 16384, 18432, 18688, 
+    18689, 18691, 18672, 18674,     0, 16384, 18432, 18688, 
+    18689, 18691, 18672,     0, 16384, 18432, 18688, 18689, 
+    18691, 18672, 18676,     0, 16384, 18432, 18688, 18689, 
+    18691, 18672, 18676,     0, 16384, 18432, 18688, 18689, 
+    18691, 18672, 18680, 18678,     0, 16384, 18432, 18688, 
+    18689, 18691, 18672,     0, 16384, 18432, 18688, 18689, 
+    18691, 18672, 18680,     0, 16384, 18432, 18688, 18689, 
+    18691, 18672, 18680,     0, 16384, 18432, 18688, 18689, 
+    18691, 18672, 18680, 18682,     0, 16384, 18432, 18688, 
+    18689, 18691, 18695, 18680,     0, 16384, 18432, 18688, 
+    18689, 18691, 18695, 18680, 18684,     0, 16384, 18432, 
+    18688, 18689, 18691, 18695, 18680, 18684,     0, 16384, 
+    18432, 18688, 18689, 18691, 18695, 18680, 18684, 18686, 
+        0, 16384, 18432,     0, 16384, 18432, 18688,     0, 
+    16384, 18432, 18688,     0, 16384, 18432, 18688, 18690, 
+        0, 16384, 18432, 18688,     0, 16384, 18432, 18688, 
+    18692,     0, 16384, 18432, 18688, 18692,     0, 16384, 
+    18432, 18688, 18696, 18694,     0, 16384, 18432, 18688, 
+        0, 16384, 18432, 18688, 18696,     0, 16384, 18432, 
+    18688, 18696,     0, 16384, 18432, 18688, 18696, 18698, 
+        0, 16384, 18432, 18688, 18696,     0, 16384, 18432, 
+    18688, 18704, 18700,     0, 16384, 18432, 18688, 18704, 
+    18700,     0, 16384, 18432, 18688, 18704, 18705, 18702, 
+        0, 16384, 18432, 18688,     0, 16384, 18432, 18688, 
+    18704,     0, 16384, 18432, 18688, 18704,     0, 16384, 
+    18432, 18688, 18704, 18706,     0, 16384, 18432, 18688, 
+    18704,     0, 16384, 18432, 18688, 18704, 18708,     0, 
+    16384, 18432, 18688, 18704, 18708,     0, 16384, 18432, 
+    18688, 18704, 18712, 18710,     0, 16384, 18432, 18688, 
+    18704,     0, 16384, 18432, 18688, 18720, 18712,     0, 
+    16384, 18432, 18688, 18720, 18712,     0, 16384, 18432, 
+    18688, 18720, 18712, 18714,     0, 16384, 18432, 18688, 
+    18720, 18712,     0, 16384, 18432, 18688, 18720, 18721, 
+    18716,     0, 16384, 18432, 18688, 18720, 18721, 18716, 
+        0, 16384, 18432, 18688, 18720, 18721, 18716, 18718, 
+        0, 16384, 18432, 18688,     0, 16384, 18432, 18688, 
+    18720,     0, 16384, 18432, 18688, 18720,     0, 16384, 
+    18432, 18688, 18720, 18722,     0, 16384, 18432, 18688, 
+    18720,     0, 16384, 18432, 18688, 18720, 18724,     0, 
+    16384, 18432, 18688, 18720, 18724,     0, 16384, 18432, 
+    18688, 18720, 18728, 18726,     0, 16384, 18432, 18688, 
+    18720,     0, 16384, 18432, 18688, 18720, 18728,     0, 
+    16384, 18432, 18688, 18720, 18728,     0, 16384, 18432, 
+    18688, 18720, 18728, 18730,     0, 16384, 18432, 18688, 
+    18720, 18728,     0, 16384, 18432, 18688, 18720, 18736, 
+    18732,     0, 16384, 18432, 18688, 18720, 18736, 18732, 
+        0, 16384, 18432, 18688, 18720, 18736, 18737, 18734, 
+        0, 16384, 18432, 18688, 18720,     0, 16384, 18432, 
+    18688, 18752, 18736,     0, 16384, 18432, 18688, 18752, 
+    18736,     0, 16384, 18432, 18688, 18752, 18736, 18738, 
+        0, 16384, 18432, 18688, 18752, 18736,     0, 16384, 
+    18432, 18688, 18752, 18736, 18740,     0, 16384, 18432, 
+    18688, 18752, 18736, 18740,     0, 16384, 18432, 18688, 
+    18752, 18736, 18744, 18742,     0, 16384, 18432, 18688, 
+    18752, 18736,     0, 16384, 18432, 18688, 18752, 18753, 
+    18744,     0, 16384, 18432, 18688, 18752, 18753, 18744, 
+        0, 16384, 18432, 18688, 18752, 18753, 18744, 18746, 
+        0, 16384, 18432, 18688, 18752, 18753, 18744,     0, 
+    16384, 18432, 18688, 18752, 18753, 18744, 18748,     0, 
+    16384, 18432, 18688, 18752, 18753, 18755, 18748,     0, 
+    16384, 18432, 18688, 18752, 18753, 18755, 18748, 18750, 
+        0, 16384, 18432, 18688,     0, 16384, 18432, 18688, 
+    18752,     0, 16384, 18432, 18688, 18752,     0, 16384, 
+    18432, 18688, 18752, 18754,     0, 16384, 18432, 18688, 
+    18752,     0, 16384, 18432, 18688, 18752, 18756,     0, 
+    16384, 18432, 18688, 18752, 18756,     0, 16384, 18432, 
+    18688, 18752, 18760, 18758,     0, 16384, 18432, 18688, 
+    18752,     0, 16384, 18432, 18688, 18752, 18760,     0, 
+    16384, 18432, 18688, 18752, 18760,     0, 16384, 18432, 
+    18688, 18752, 18760, 18762,     0, 16384, 18432, 18688, 
+    18752, 18760,     0, 16384, 18432, 18688, 18752, 18768, 
+    18764,     0, 16384, 18432, 18688, 18752, 18768, 18764, 
+        0, 16384, 18432, 18688, 18752, 18768, 18769, 18766, 
+        0, 16384, 18432, 18688, 18752,     0, 16384, 18432, 
+    18688, 18752, 18768,     0, 16384, 18432, 18688, 18752, 
+    18768,     0, 16384, 18432, 18688, 18752, 18768, 18770, 
+        0, 16384, 18432, 18688, 18752, 18768,     0, 16384, 
+    18432, 18688, 18752, 18768, 18772,     0, 16384, 18432, 
+    18688, 18752, 18768, 18772,     0, 16384, 18432, 18688, 
+    18752, 18768, 18776, 18774,     0, 16384, 18432, 18688, 
+    18752, 18768,     0, 16384, 18432, 18688, 18752, 18784, 
+    18776,     0, 16384, 18432, 18688, 18752, 18784, 18776, 
+        0, 16384, 18432, 18688, 18752, 18784, 18776, 18778, 
+        0, 16384, 18432, 18688, 18752, 18784, 18776,     0, 
+    16384, 18432, 18688, 18752, 18784, 18785, 18780,     0, 
+    16384, 18432, 18688, 18752, 18784, 18785, 18780,     0, 
+    16384, 18432, 18688, 18752, 18784, 18785, 18780, 18782, 
+        0, 16384, 18432, 18688, 18752,     0, 16384, 18432, 
+    18688, 18816, 18784,     0, 16384, 18432, 18688, 18816, 
+    18784,     0, 16384, 18432, 18688, 18816, 18784, 18786, 
+        0, 16384, 18432, 18688, 18816, 18784,     0, 16384, 
+    18432, 18688, 18816, 18784, 18788,     0, 16384, 18432, 
+    18688, 18816, 18784, 18788,     0, 16384, 18432, 18688, 
+    18816, 18784, 18792, 18790,     0, 16384, 18432, 18688, 
+    18816, 18784,     0, 16384, 18432, 18688, 18816, 18784, 
+    18792,     0, 16384, 18432, 18688, 18816, 18784, 18792, 
+        0, 16384, 18432, 18688, 18816, 18784, 18792, 18794, 
+        0, 16384, 18432, 18688, 18816, 18784, 18792,     0, 
+    16384, 18432, 18688, 18816, 18784, 18800, 18796,     0, 
+    16384, 18432, 18688, 18816, 18784, 18800, 18796,     0, 
+    16384, 18432, 18688, 18816, 18784, 18800, 18801, 18798, 
+        0, 16384, 18432, 18688, 18816, 18784,     0, 16384, 
+    18432, 18688, 18816, 18817, 18800,     0, 16384, 18432, 
+    18688, 18816, 18817, 18800,     0, 16384, 18432, 18688, 
+    18816, 18817, 18800, 18802,     0, 16384, 18432, 18688, 
+    18816, 18817, 18800,     0, 16384, 18432, 18688, 18816, 
+    18817, 18800, 18804,     0, 16384, 18432, 18688, 18816, 
+    18817, 18800, 18804,     0, 16384, 18432, 18688, 18816, 
+    18817, 18800, 18808, 18806,     0, 16384, 18432, 18688, 
+    18816, 18817, 18800,     0, 16384, 18432, 18688, 18816, 
+    18817, 18800, 18808,     0, 16384, 18432, 18688, 18816, 
+    18817, 18819, 18808,     0, 16384, 18432, 18688, 18816, 
+    18817, 18819, 18808, 18810,     0, 16384, 18432, 18688, 
+    18816, 18817, 18819, 18808,     0, 16384, 18432, 18688, 
+    18816, 18817, 18819, 18808, 18812,     0, 16384, 18432, 
+    18688, 18816, 18817, 18819, 18808, 18812,     0, 16384, 
+    18432, 18688, 18816, 18817, 18819, 18808, 18812, 18814, 
+        0, 16384, 18432, 18688,     0, 16384, 18432, 18944, 
+    18816,     0, 16384, 18432, 18944, 18816,     0, 16384, 
+    18432, 18944, 18816, 18818,     0, 16384, 18432, 18944, 
+    18816,     0, 16384, 18432, 18944, 18816, 18820,     0, 
+    16384, 18432, 18944, 18816, 18820,     0, 16384, 18432, 
+    18944, 18816, 18824, 18822,     0, 16384, 18432, 18944, 
+    18816,     0, 16384, 18432, 18944, 18816, 18824,     0, 
+    16384, 18432, 18944, 18816, 18824,     0, 16384, 18432, 
+    18944, 18816, 18824, 18826,     0, 16384, 18432, 18944, 
+    18816, 18824,     0, 16384, 18432, 18944, 18816, 18832, 
+    18828,     0, 16384, 18432, 18944, 18816, 18832, 18828, 
+        0, 16384, 18432, 18944, 18816, 18832, 18833, 18830, 
+        0, 16384, 18432, 18944, 18816,     0, 16384, 18432, 
+    18944, 18816, 18832,     0, 16384, 18432, 18944, 18816, 
+    18832,     0, 16384, 18432, 18944, 18816, 18832, 18834, 
+        0, 16384, 18432, 18944, 18816, 18832,     0, 16384, 
+    18432, 18944, 18816, 18832, 18836,     0, 16384, 18432, 
+    18944, 18816, 18832, 18836,     0, 16384, 18432, 18944, 
+    18816, 18832, 18840, 18838,     0, 16384, 18432, 18944, 
+    18816, 18832,     0, 16384, 18432, 18944, 18816, 18848, 
+    18840,     0, 16384, 18432, 18944, 18816, 18848, 18840, 
+        0, 16384, 18432, 18944, 18816, 18848, 18840, 18842, 
+        0, 16384, 18432, 18944, 18816, 18848, 18840,     0, 
+    16384, 18432, 18944, 18816, 18848, 18849, 18844,     0, 
+    16384, 18432, 18944, 18816, 18848, 18849, 18844,     0, 
+    16384, 18432, 18944, 18816, 18848, 18849, 18844, 18846, 
+        0, 16384, 18432, 18944, 18816,     0, 16384, 18432, 
+    18944, 18816, 18848,     0, 16384, 18432, 18944, 18816, 
+    18848,     0, 16384, 18432, 18944, 18816, 18848, 18850, 
+        0, 16384, 18432, 18944, 18816, 18848,     0, 16384, 
+    18432, 18944, 18816, 18848, 18852,     0, 16384, 18432, 
+    18944, 18816, 18848, 18852,     0, 16384, 18432, 18944, 
+    18816, 18848, 18856, 18854,     0, 16384, 18432, 18944, 
+    18816, 18848,     0, 16384, 18432, 18944, 18816, 18848, 
+    18856,     0, 16384, 18432, 18944, 18816, 18848, 18856, 
+        0, 16384, 18432, 18944, 18816, 18848, 18856, 18858, 
+        0, 16384, 18432, 18944, 18816, 18848, 18856,     0, 
+    16384, 18432, 18944, 18816, 18848, 18864, 18860,     0, 
+    16384, 18432, 18944, 18816, 18848, 18864, 18860,     0, 
+    16384, 18432, 18944, 18816, 18848, 18864, 18865, 18862, 
+        0, 16384, 18432, 18944, 18816, 18848,     0, 16384, 
+    18432, 18944, 18816, 18880, 18864,     0, 16384, 18432, 
+    18944, 18816, 18880, 18864,     0, 16384, 18432, 18944, 
+    18816, 18880, 18864, 18866,     0, 16384, 18432, 18944, 
+    18816, 18880, 18864,     0, 16384, 18432, 18944, 18816, 
+    18880, 18864, 18868,     0, 16384, 18432, 18944, 18816, 
+    18880, 18864, 18868,     0, 16384, 18432, 18944, 18816, 
+    18880, 18864, 18872, 18870,     0, 16384, 18432, 18944, 
+    18816, 18880, 18864,     0, 16384, 18432, 18944, 18816, 
+    18880, 18881, 18872,     0, 16384, 18432, 18944, 18816, 
+    18880, 18881, 18872,     0, 16384, 18432, 18944, 18816, 
+    18880, 18881, 18872, 18874,     0, 16384, 18432, 18944, 
+    18816, 18880, 18881, 18872,     0, 16384, 18432, 18944, 
+    18816, 18880, 18881, 18872, 18876,     0, 16384, 18432, 
+    18944, 18816, 18880, 18881, 18883, 18876,     0, 16384, 
+    18432, 18944, 18816, 18880, 18881, 18883, 18876, 18878, 
+        0, 16384, 18432, 18944, 18816,     0, 16384, 18432, 
+    18944, 18945, 18880,     0, 16384, 18432, 18944, 18945, 
+    18880,     0, 16384, 18432, 18944, 18945, 18880, 18882, 
+        0, 16384, 18432, 18944, 18945, 18880,     0, 16384, 
+    18432, 18944, 18945, 18880, 18884,     0, 16384, 18432, 
+    18944, 18945, 18880, 18884,     0, 16384, 18432, 18944, 
+    18945, 18880, 18888, 18886,     0, 16384, 18432, 18944, 
+    18945, 18880,     0, 16384, 18432, 18944, 18945, 18880, 
+    18888,     0, 16384, 18432, 18944, 18945, 18880, 18888, 
+        0, 16384, 18432, 18944, 18945, 18880, 18888, 18890, 
+        0, 16384, 18432, 18944, 18945, 18880, 18888,     0, 
+    16384, 18432, 18944, 18945, 18880, 18896, 18892,     0, 
+    16384, 18432, 18944, 18945, 18880, 18896, 18892,     0, 
+    16384, 18432, 18944, 18945, 18880, 18896, 18897, 18894, 
+        0, 16384, 18432, 18944, 18945, 18880,     0, 16384, 
+    18432, 18944, 18945, 18880, 18896,     0, 16384, 18432, 
+    18944, 18945, 18880, 18896,     0, 16384, 18432, 18944, 
+    18945, 18880, 18896, 18898,     0, 16384, 18432, 18944, 
+    18945, 18880, 18896,     0, 16384, 18432, 18944, 18945, 
+    18880, 18896, 18900,     0, 16384, 18432, 18944, 18945, 
+    18880, 18896, 18900,     0, 16384, 18432, 18944, 18945, 
+    18880, 18896, 18904, 18902,     0, 16384, 18432, 18944, 
+    18945, 18880, 18896,     0, 16384, 18432, 18944, 18945, 
+    18880, 18912, 18904,     0, 16384, 18432, 18944, 18945, 
+    18880, 18912, 18904,     0, 16384, 18432, 18944, 18945, 
+    18880, 18912, 18904, 18906,     0, 16384, 18432, 18944, 
+    18945, 18880, 18912, 18904,     0, 16384, 18432, 18944, 
+    18945, 18880, 18912, 18913, 18908,     0, 16384, 18432, 
+    18944, 18945, 18880, 18912, 18913, 18908,     0, 16384, 
+    18432, 18944, 18945, 18880, 18912, 18913, 18908, 18910, 
+        0, 16384, 18432, 18944, 18945, 18880,     0, 16384, 
+    18432, 18944, 18945, 18880, 18912,     0, 16384, 18432, 
+    18944, 18945, 18947, 18912,     0, 16384, 18432, 18944, 
+    18945, 18947, 18912, 18914,     0, 16384, 18432, 18944, 
+    18945, 18947, 18912,     0, 16384, 18432, 18944, 18945, 
+    18947, 18912, 18916,     0, 16384, 18432, 18944, 18945, 
+    18947, 18912, 18916,     0, 16384, 18432, 18944, 18945, 
+    18947, 18912, 18920, 18918,     0, 16384, 18432, 18944, 
+    18945, 18947, 18912,     0, 16384, 18432, 18944, 18945, 
+    18947, 18912, 18920,     0, 16384, 18432, 18944, 18945, 
+    18947, 18912, 18920,     0, 16384, 18432, 18944, 18945, 
+    18947, 18912, 18920, 18922,     0, 16384, 18432, 18944, 
+    18945, 18947, 18912, 18920,     0, 16384, 18432, 18944, 
+    18945, 18947, 18912, 18928, 18924,     0, 16384, 18432, 
+    18944, 18945, 18947, 18912, 18928, 18924,     0, 16384, 
+    18432, 18944, 18945, 18947, 18912, 18928, 18929, 18926, 
+        0, 16384, 18432, 18944, 18945, 18947, 18912,     0, 
+    16384, 18432, 18944, 18945, 18947, 18912, 18928,     0, 
+    16384, 18432, 18944, 18945, 18947, 18912, 18928,     0, 
+    16384, 18432, 18944, 18945, 18947, 18912, 18928, 18930, 
+        0, 16384, 18432, 18944, 18945, 18947, 18951, 18928, 
+        0, 16384, 18432, 18944, 18945, 18947, 18951, 18928, 
+    18932,     0, 16384, 18432, 18944, 18945, 18947, 18951, 
+    18928, 18932,     0, 16384, 18432, 18944, 18945, 18947, 
+    18951, 18928, 18936, 18934,     0, 16384, 18432, 18944, 
+    18945, 18947, 18951, 18928,     0, 16384, 18432, 18944, 
+    18945, 18947, 18951, 18928, 18936,     0, 16384, 18432, 
+    18944, 18945, 18947, 18951, 18928, 18936,     0, 16384, 
+    18432, 18944, 18945, 18947, 18951, 18928, 18936, 18938, 
+        0, 16384, 18432, 18944, 18945, 18947, 18951, 18928, 
+    18936,     0, 16384, 18432, 18944, 18945, 18947, 18951, 
+    18928, 18936, 18940,     0, 16384, 18432, 18944, 18945, 
+    18947, 18951, 18928, 18936, 18940,     0, 16384, 18432, 
+    18944, 18945, 18947, 18951, 18928, 18936, 18940, 18942, 
+        0, 16384, 18432,     0, 16384, 18432, 18944,     0, 
+    16384, 18432, 18944,     0, 16384, 18432, 18944, 18946, 
+        0, 16384, 18432, 18944,     0, 16384, 18432, 18944, 
+    18948,     0, 16384, 18432, 18944, 18948,     0, 16384, 
+    18432, 18944, 18952, 18950,     0, 16384, 18432, 18944, 
+        0, 16384, 18432, 18944, 18952,     0, 16384, 18432, 
+    18944, 18952,     0, 16384, 18432, 18944, 18952, 18954, 
+        0, 16384, 18432, 18944, 18952,     0, 16384, 18432, 
+    18944, 18960, 18956,     0, 16384, 18432, 18944, 18960, 
+    18956,     0, 16384, 18432, 18944, 18960, 18961, 18958, 
+        0, 16384, 18432, 18944,     0, 16384, 18432, 18944, 
+    18960,     0, 16384, 18432, 18944, 18960,     0, 16384, 
+    18432, 18944, 18960, 18962,     0, 16384, 18432, 18944, 
+    18960,     0, 16384, 18432, 18944, 18960, 18964,     0, 
+    16384, 18432, 18944, 18960, 18964,     0, 16384, 18432, 
+    18944, 18960, 18968, 18966,     0, 16384, 18432, 18944, 
+    18960,     0, 16384, 18432, 18944, 18976, 18968,     0, 
+    16384, 18432, 18944, 18976, 18968,     0, 16384, 18432, 
+    18944, 18976, 18968, 18970,     0, 16384, 18432, 18944, 
+    18976, 18968,     0, 16384, 18432, 18944, 18976, 18977, 
+    18972,     0, 16384, 18432, 18944, 18976, 18977, 18972, 
+        0, 16384, 18432, 18944, 18976, 18977, 18972, 18974, 
+        0, 16384, 18432, 18944,     0, 16384, 18432, 18944, 
+    18976,     0, 16384, 18432, 18944, 18976,     0, 16384, 
+    18432, 18944, 18976, 18978,     0, 16384, 18432, 18944, 
+    18976,     0, 16384, 18432, 18944, 18976, 18980,     0, 
+    16384, 18432, 18944, 18976, 18980,     0, 16384, 18432, 
+    18944, 18976, 18984, 18982,     0, 16384, 18432, 18944, 
+    18976,     0, 16384, 18432, 18944, 18976, 18984,     0, 
+    16384, 18432, 18944, 18976, 18984,     0, 16384, 18432, 
+    18944, 18976, 18984, 18986,     0, 16384, 18432, 18944, 
+    18976, 18984,     0, 16384, 18432, 18944, 18976, 18992, 
+    18988,     0, 16384, 18432, 18944, 18976, 18992, 18988, 
+        0, 16384, 18432, 18944, 18976, 18992, 18993, 18990, 
+        0, 16384, 18432, 18944, 18976,     0, 16384, 18432, 
+    18944, 19008, 18992,     0, 16384, 18432, 18944, 19008, 
+    18992,     0, 16384, 18432, 18944, 19008, 18992, 18994, 
+        0, 16384, 18432, 18944, 19008, 18992,     0, 16384, 
+    18432, 18944, 19008, 18992, 18996,     0, 16384, 18432, 
+    18944, 19008, 18992, 18996,     0, 16384, 18432, 18944, 
+    19008, 18992, 19000, 18998,     0, 16384, 18432, 18944, 
+    19008, 18992,     0, 16384, 18432, 18944, 19008, 19009, 
+    19000,     0, 16384, 18432, 18944, 19008, 19009, 19000, 
+        0, 16384, 18432, 18944, 19008, 19009, 19000, 19002, 
+        0, 16384, 18432, 18944, 19008, 19009, 19000,     0, 
+    16384, 18432, 18944, 19008, 19009, 19000, 19004,     0, 
+    16384, 18432, 18944, 19008, 19009, 19011, 19004,     0, 
+    16384, 18432, 18944, 19008, 19009, 19011, 19004, 19006, 
+        0, 16384, 18432, 18944,     0, 16384, 18432, 18944, 
+    19008,     0, 16384, 18432, 18944, 19008,     0, 16384, 
+    18432, 18944, 19008, 19010,     0, 16384, 18432, 18944, 
+    19008,     0, 16384, 18432, 18944, 19008, 19012,     0, 
+    16384, 18432, 18944, 19008, 19012,     0, 16384, 18432, 
+    18944, 19008, 19016, 19014,     0, 16384, 18432, 18944, 
+    19008,     0, 16384, 18432, 18944, 19008, 19016,     0, 
+    16384, 18432, 18944, 19008, 19016,     0, 16384, 18432, 
+    18944, 19008, 19016, 19018,     0, 16384, 18432, 18944, 
+    19008, 19016,     0, 16384, 18432, 18944, 19008, 19024, 
+    19020,     0, 16384, 18432, 18944, 19008, 19024, 19020, 
+        0, 16384, 18432, 18944, 19008, 19024, 19025, 19022, 
+        0, 16384, 18432, 18944, 19008,     0, 16384, 18432, 
+    18944, 19008, 19024,     0, 16384, 18432, 18944, 19008, 
+    19024,     0, 16384, 18432, 18944, 19008, 19024, 19026, 
+        0, 16384, 18432, 18944, 19008, 19024,     0, 16384, 
+    18432, 18944, 19008, 19024, 19028,     0, 16384, 18432, 
+    18944, 19008, 19024, 19028,     0, 16384, 18432, 18944, 
+    19008, 19024, 19032, 19030,     0, 16384, 18432, 18944, 
+    19008, 19024,     0, 16384, 18432, 18944, 19008, 19040, 
+    19032,     0, 16384, 18432, 18944, 19008, 19040, 19032, 
+        0, 16384, 18432, 18944, 19008, 19040, 19032, 19034, 
+        0, 16384, 18432, 18944, 19008, 19040, 19032,     0, 
+    16384, 18432, 18944, 19008, 19040, 19041, 19036,     0, 
+    16384, 18432, 18944, 19008, 19040, 19041, 19036,     0, 
+    16384, 18432, 18944, 19008, 19040, 19041, 19036, 19038, 
+        0, 16384, 18432, 18944, 19008,     0, 16384, 18432, 
+    18944, 19072, 19040,     0, 16384, 18432, 18944, 19072, 
+    19040,     0, 16384, 18432, 18944, 19072, 19040, 19042, 
+        0, 16384, 18432, 18944, 19072, 19040,     0, 16384, 
+    18432, 18944, 19072, 19040, 19044,     0, 16384, 18432, 
+    18944, 19072, 19040, 19044,     0, 16384, 18432, 18944, 
+    19072, 19040, 19048, 19046,     0, 16384, 18432, 18944, 
+    19072, 19040,     0, 16384, 18432, 18944, 19072, 19040, 
+    19048,     0, 16384, 18432, 18944, 19072, 19040, 19048, 
+        0, 16384, 18432, 18944, 19072, 19040, 19048, 19050, 
+        0, 16384, 18432, 18944, 19072, 19040, 19048,     0, 
+    16384, 18432, 18944, 19072, 19040, 19056, 19052,     0, 
+    16384, 18432, 18944, 19072, 19040, 19056, 19052,     0, 
+    16384, 18432, 18944, 19072, 19040, 19056, 19057, 19054, 
+        0, 16384, 18432, 18944, 19072, 19040,     0, 16384, 
+    18432, 18944, 19072, 19073, 19056,     0, 16384, 18432, 
+    18944, 19072, 19073, 19056,     0, 16384, 18432, 18944, 
+    19072, 19073, 19056, 19058,     0, 16384, 18432, 18944, 
+    19072, 19073, 19056,     0, 16384, 18432, 18944, 19072, 
+    19073, 19056, 19060,     0, 16384, 18432, 18944, 19072, 
+    19073, 19056, 19060,     0, 16384, 18432, 18944, 19072, 
+    19073, 19056, 19064, 19062,     0, 16384, 18432, 18944, 
+    19072, 19073, 19056,     0, 16384, 18432, 18944, 19072, 
+    19073, 19056, 19064,     0, 16384, 18432, 18944, 19072, 
+    19073, 19075, 19064,     0, 16384, 18432, 18944, 19072, 
+    19073, 19075, 19064, 19066,     0, 16384, 18432, 18944, 
+    19072, 19073, 19075, 19064,     0, 16384, 18432, 18944, 
+    19072, 19073, 19075, 19064, 19068,     0, 16384, 18432, 
+    18944, 19072, 19073, 19075, 19064, 19068,     0, 16384, 
+    18432, 18944, 19072, 19073, 19075, 19064, 19068, 19070, 
+        0, 16384, 18432, 18944,     0, 16384, 18432, 18944, 
+    19072,     0, 16384, 18432, 18944, 19072,     0, 16384, 
+    18432, 18944, 19072, 19074,     0, 16384, 18432, 18944, 
+    19072,     0, 16384, 18432, 18944, 19072, 19076,     0, 
+    16384, 18432, 18944, 19072, 19076,     0, 16384, 18432, 
+    18944, 19072, 19080, 19078,     0, 16384, 18432, 18944, 
+    19072,     0, 16384, 18432, 18944, 19072, 19080,     0, 
+    16384, 18432, 18944, 19072, 19080,     0, 16384, 18432, 
+    18944, 19072, 19080, 19082,     0, 16384, 18432, 18944, 
+    19072, 19080,     0, 16384, 18432, 18944, 19072, 19088, 
+    19084,     0, 16384, 18432, 18944, 19072, 19088, 19084, 
+        0, 16384, 18432, 18944, 19072, 19088, 19089, 19086, 
+        0, 16384, 18432, 18944, 19072,     0, 16384, 18432, 
+    18944, 19072, 19088,     0, 16384, 18432, 18944, 19072, 
+    19088,     0, 16384, 18432, 18944, 19072, 19088, 19090, 
+        0, 16384, 18432, 18944, 19072, 19088,     0, 16384, 
+    18432, 18944, 19072, 19088, 19092,     0, 16384, 18432, 
+    18944, 19072, 19088, 19092,     0, 16384, 18432, 18944, 
+    19072, 19088, 19096, 19094,     0, 16384, 18432, 18944, 
+    19072, 19088,     0, 16384, 18432, 18944, 19072, 19104, 
+    19096,     0, 16384, 18432, 18944, 19072, 19104, 19096, 
+        0, 16384, 18432, 18944, 19072, 19104, 19096, 19098, 
+        0, 16384, 18432, 18944, 19072, 19104, 19096,     0, 
+    16384, 18432, 18944, 19072, 19104, 19105, 19100,     0, 
+    16384, 18432, 18944, 19072, 19104, 19105, 19100,     0, 
+    16384, 18432, 18944, 19072, 19104, 19105, 19100, 19102, 
+        0, 16384, 18432, 18944, 19072,     0, 16384, 18432, 
+    18944, 19072, 19104,     0, 16384, 18432, 18944, 19072, 
+    19104,     0, 16384, 18432, 18944, 19072, 19104, 19106, 
+        0, 16384, 18432, 18944, 19072, 19104,     0, 16384, 
+    18432, 18944, 19072, 19104, 19108,     0, 16384, 18432, 
+    18944, 19072, 19104, 19108,     0, 16384, 18432, 18944, 
+    19072, 19104, 19112, 19110,     0, 16384, 18432, 18944, 
+    19072, 19104,     0, 16384, 18432, 18944, 19072, 19104, 
+    19112,     0, 16384, 18432, 18944, 19072, 19104, 19112, 
+        0, 16384, 18432, 18944, 19072, 19104, 19112, 19114, 
+        0, 16384, 18432, 18944, 19072, 19104, 19112,     0, 
+    16384, 18432, 18944, 19072, 19104, 19120, 19116,     0, 
+    16384, 18432, 18944, 19072, 19104, 19120, 19116,     0, 
+    16384, 18432, 18944, 19072, 19104, 19120, 19121, 19118, 
+        0, 16384, 18432, 18944, 19072, 19104,     0, 16384, 
+    18432, 18944, 19072, 19136, 19120,     0, 16384, 18432, 
+    18944, 19072, 19136, 19120,     0, 16384, 18432, 18944, 
+    19072, 19136, 19120, 19122,     0, 16384, 18432, 18944, 
+    19072, 19136, 19120,     0, 16384, 18432, 18944, 19072, 
+    19136, 19120, 19124,     0, 16384, 18432, 18944, 19072, 
+    19136, 19120, 19124,     0, 16384, 18432, 18944, 19072, 
+    19136, 19120, 19128, 19126,     0, 16384, 18432, 18944, 
+    19072, 19136, 19120,     0, 16384, 18432, 18944, 19072, 
+    19136, 19137, 19128,     0, 16384, 18432, 18944, 19072, 
+    19136, 19137, 19128,     0, 16384, 18432, 18944, 19072, 
+    19136, 19137, 19128, 19130,     0, 16384, 18432, 18944, 
+    19072, 19136, 19137, 19128,     0, 16384, 18432, 18944, 
+    19072, 19136, 19137, 19128, 19132,     0, 16384, 18432, 
+    18944, 19072, 19136, 19137, 19139, 19132,     0, 16384, 
+    18432, 18944, 19072, 19136, 19137, 19139, 19132, 19134, 
+        0, 16384, 18432, 18944, 19072,     0, 16384, 18432, 
+    18944, 19200, 19136,     0, 16384, 18432, 18944, 19200, 
+    19136,     0, 16384, 18432, 18944, 19200, 19136, 19138, 
+        0, 16384, 18432, 18944, 19200, 19136,     0, 16384, 
+    18432, 18944, 19200, 19136, 19140,     0, 16384, 18432, 
+    18944, 19200, 19136, 19140,     0, 16384, 18432, 18944, 
+    19200, 19136, 19144, 19142,     0, 16384, 18432, 18944, 
+    19200, 19136,     0, 16384, 18432, 18944, 19200, 19136, 
+    19144,     0, 16384, 18432, 18944, 19200, 19136, 19144, 
+        0, 16384, 18432, 18944, 19200, 19136, 19144, 19146, 
+        0, 16384, 18432, 18944, 19200, 19136, 19144,     0, 
+    16384, 18432, 18944, 19200, 19136, 19152, 19148,     0, 
+    16384, 18432, 18944, 19200, 19136, 19152, 19148,     0, 
+    16384, 18432, 18944, 19200, 19136, 19152, 19153, 19150, 
+        0, 16384, 18432, 18944, 19200, 19136,     0, 16384, 
+    18432, 18944, 19200, 19136, 19152,     0, 16384, 18432, 
+    18944, 19200, 19136, 19152,     0, 16384, 18432, 18944, 
+    19200, 19136, 19152, 19154,     0, 16384, 18432, 18944, 
+    19200, 19136, 19152,     0, 16384, 18432, 18944, 19200, 
+    19136, 19152, 19156,     0, 16384, 18432, 18944, 19200, 
+    19136, 19152, 19156,     0, 16384, 18432, 18944, 19200, 
+    19136, 19152, 19160, 19158,     0, 16384, 18432, 18944, 
+    19200, 19136, 19152,     0, 16384, 18432, 18944, 19200, 
+    19136, 19168, 19160,     0, 16384, 18432, 18944, 19200, 
+    19136, 19168, 19160,     0, 16384, 18432, 18944, 19200, 
+    19136, 19168, 19160, 19162,     0, 16384, 18432, 18944, 
+    19200, 19136, 19168, 19160,     0, 16384, 18432, 18944, 
+    19200, 19136, 19168, 19169, 19164,     0, 16384, 18432, 
+    18944, 19200, 19136, 19168, 19169, 19164,     0, 16384, 
+    18432, 18944, 19200, 19136, 19168, 19169, 19164, 19166, 
+        0, 16384, 18432, 18944, 19200, 19136,     0, 16384, 
+    18432, 18944, 19200, 19201, 19168,     0, 16384, 18432, 
+    18944, 19200, 19201, 19168,     0, 16384, 18432, 18944, 
+    19200, 19201, 19168, 19170,     0, 16384, 18432, 18944, 
+    19200, 19201, 19168,     0, 16384, 18432, 18944, 19200, 
+    19201, 19168, 19172,     0, 16384, 18432, 18944, 19200, 
+    19201, 19168, 19172,     0, 16384, 18432, 18944, 19200, 
+    19201, 19168, 19176, 19174,     0, 16384, 18432, 18944, 
+    19200, 19201, 19168,     0, 16384, 18432, 18944, 19200, 
+    19201, 19168, 19176,     0, 16384, 18432, 18944, 19200, 
+    19201, 19168, 19176,     0, 16384, 18432, 18944, 19200, 
+    19201, 19168, 19176, 19178,     0, 16384, 18432, 18944, 
+    19200, 19201, 19168, 19176,     0, 16384, 18432, 18944, 
+    19200, 19201, 19168, 19184, 19180,     0, 16384, 18432, 
+    18944, 19200, 19201, 19168, 19184, 19180,     0, 16384, 
+    18432, 18944, 19200, 19201, 19168, 19184, 19185, 19182, 
+        0, 16384, 18432, 18944, 19200, 19201, 19168,     0, 
+    16384, 18432, 18944, 19200, 19201, 19168, 19184,     0, 
+    16384, 18432, 18944, 19200, 19201, 19203, 19184,     0, 
+    16384, 18432, 18944, 19200, 19201, 19203, 19184, 19186, 
+        0, 16384, 18432, 18944, 19200, 19201, 19203, 19184, 
+        0, 16384, 18432, 18944, 19200, 19201, 19203, 19184, 
+    19188,     0, 16384, 18432, 18944, 19200, 19201, 19203, 
+    19184, 19188,     0, 16384, 18432, 18944, 19200, 19201, 
+    19203, 19184, 19192, 19190,     0, 16384, 18432, 18944, 
+    19200, 19201, 19203, 19184,     0, 16384, 18432, 18944, 
+    19200, 19201, 19203, 19184, 19192,     0, 16384, 18432, 
+    18944, 19200, 19201, 19203, 19184, 19192,     0, 16384, 
+    18432, 18944, 19200, 19201, 19203, 19184, 19192, 19194, 
+        0, 16384, 18432, 18944, 19200, 19201, 19203, 19207, 
+    19192,     0, 16384, 18432, 18944, 19200, 19201, 19203, 
+    19207, 19192, 19196,     0, 16384, 18432, 18944, 19200, 
+    19201, 19203, 19207, 19192, 19196,     0, 16384, 18432, 
+    18944, 19200, 19201, 19203, 19207, 19192, 19196, 19198, 
+        0, 16384, 18432, 18944,     0, 16384, 18432, 19456, 
+    19200,     0, 16384, 18432, 19456, 19200,     0, 16384, 
+    18432, 19456, 19200, 19202,     0, 16384, 18432, 19456, 
+    19200,     0, 16384, 18432, 19456, 19200, 19204,     0, 
+    16384, 18432, 19456, 19200, 19204,     0, 16384, 18432, 
+    19456, 19200, 19208, 19206,     0, 16384, 18432, 19456, 
+    19200,     0, 16384, 18432, 19456, 19200, 19208,     0, 
+    16384, 18432, 19456, 19200, 19208,     0, 16384, 18432, 
+    19456, 19200, 19208, 19210,     0, 16384, 18432, 19456, 
+    19200, 19208,     0, 16384, 18432, 19456, 19200, 19216, 
+    19212,     0, 16384, 18432, 19456, 19200, 19216, 19212, 
+        0, 16384, 18432, 19456, 19200, 19216, 19217, 19214, 
+        0, 16384, 18432, 19456, 19200,     0, 16384, 18432, 
+    19456, 19200, 19216,     0, 16384, 18432, 19456, 19200, 
+    19216,     0, 16384, 18432, 19456, 19200, 19216, 19218, 
+        0, 16384, 18432, 19456, 19200, 19216,     0, 16384, 
+    18432, 19456, 19200, 19216, 19220,     0, 16384, 18432, 
+    19456, 19200, 19216, 19220,     0, 16384, 18432, 19456, 
+    19200, 19216, 19224, 19222,     0, 16384, 18432, 19456, 
+    19200, 19216,     0, 16384, 18432, 19456, 19200, 19232, 
+    19224,     0, 16384, 18432, 19456, 19200, 19232, 19224, 
+        0, 16384, 18432, 19456, 19200, 19232, 19224, 19226, 
+        0, 16384, 18432, 19456, 19200, 19232, 19224,     0, 
+    16384, 18432, 19456, 19200, 19232, 19233, 19228,     0, 
+    16384, 18432, 19456, 19200, 19232, 19233, 19228,     0, 
+    16384, 18432, 19456, 19200, 19232, 19233, 19228, 19230, 
+        0, 16384, 18432, 19456, 19200,     0, 16384, 18432, 
+    19456, 19200, 19232,     0, 16384, 18432, 19456, 19200, 
+    19232,     0, 16384, 18432, 19456, 19200, 19232, 19234, 
+        0, 16384, 18432, 19456, 19200, 19232,     0, 16384, 
+    18432, 19456, 19200, 19232, 19236,     0, 16384, 18432, 
+    19456, 19200, 19232, 19236,     0, 16384, 18432, 19456, 
+    19200, 19232, 19240, 19238,     0, 16384, 18432, 19456, 
+    19200, 19232,     0, 16384, 18432, 19456, 19200, 19232, 
+    19240,     0, 16384, 18432, 19456, 19200, 19232, 19240, 
+        0, 16384, 18432, 19456, 19200, 19232, 19240, 19242, 
+        0, 16384, 18432, 19456, 19200, 19232, 19240,     0, 
+    16384, 18432, 19456, 19200, 19232, 19248, 19244,     0, 
+    16384, 18432, 19456, 19200, 19232, 19248, 19244,     0, 
+    16384, 18432, 19456, 19200, 19232, 19248, 19249, 19246, 
+        0, 16384, 18432, 19456, 19200, 19232,     0, 16384, 
+    18432, 19456, 19200, 19264, 19248,     0, 16384, 18432, 
+    19456, 19200, 19264, 19248,     0, 16384, 18432, 19456, 
+    19200, 19264, 19248, 19250,     0, 16384, 18432, 19456, 
+    19200, 19264, 19248,     0, 16384, 18432, 19456, 19200, 
+    19264, 19248, 19252,     0, 16384, 18432, 19456, 19200, 
+    19264, 19248, 19252,     0, 16384, 18432, 19456, 19200, 
+    19264, 19248, 19256, 19254,     0, 16384, 18432, 19456, 
+    19200, 19264, 19248,     0, 16384, 18432, 19456, 19200, 
+    19264, 19265, 19256,     0, 16384, 18432, 19456, 19200, 
+    19264, 19265, 19256,     0, 16384, 18432, 19456, 19200, 
+    19264, 19265, 19256, 19258,     0, 16384, 18432, 19456, 
+    19200, 19264, 19265, 19256,     0, 16384, 18432, 19456, 
+    19200, 19264, 19265, 19256, 19260,     0, 16384, 18432, 
+    19456, 19200, 19264, 19265, 19267, 19260,     0, 16384, 
+    18432, 19456, 19200, 19264, 19265, 19267, 19260, 19262, 
+        0, 16384, 18432, 19456, 19200,     0, 16384, 18432, 
+    19456, 19200, 19264,     0, 16384, 18432, 19456, 19200, 
+    19264,     0, 16384, 18432, 19456, 19200, 19264, 19266, 
+        0, 16384, 18432, 19456, 19200, 19264,     0, 16384, 
+    18432, 19456, 19200, 19264, 19268,     0, 16384, 18432, 
+    19456, 19200, 19264, 19268,     0, 16384, 18432, 19456, 
+    19200, 19264, 19272, 19270,     0, 16384, 18432, 19456, 
+    19200, 19264,     0, 16384, 18432, 19456, 19200, 19264, 
+    19272,     0, 16384, 18432, 19456, 19200, 19264, 19272, 
+        0, 16384, 18432, 19456, 19200, 19264, 19272, 19274, 
+        0, 16384, 18432, 19456, 19200, 19264, 19272,     0, 
+    16384, 18432, 19456, 19200, 19264, 19280, 19276,     0, 
+    16384, 18432, 19456, 19200, 19264, 19280, 19276,     0, 
+    16384, 18432, 19456, 19200, 19264, 19280, 19281, 19278, 
+        0, 16384, 18432, 19456, 19200, 19264,     0, 16384, 
+    18432, 19456, 19200, 19264, 19280,     0, 16384, 18432, 
+    19456, 19200, 19264, 19280,     0, 16384, 18432, 19456, 
+    19200, 19264, 19280, 19282,     0, 16384, 18432, 19456, 
+    19200, 19264, 19280,     0, 16384, 18432, 19456, 19200, 
+    19264, 19280, 19284,     0, 16384, 18432, 19456, 19200, 
+    19264, 19280, 19284,     0, 16384, 18432, 19456, 19200, 
+    19264, 19280, 19288, 19286,     0, 16384, 18432, 19456, 
+    19200, 19264, 19280,     0, 16384, 18432, 19456, 19200, 
+    19264, 19296, 19288,     0, 16384, 18432, 19456, 19200, 
+    19264, 19296, 19288,     0, 16384, 18432, 19456, 19200, 
+    19264, 19296, 19288, 19290,     0, 16384, 18432, 19456, 
+    19200, 19264, 19296, 19288,     0, 16384, 18432, 19456, 
+    19200, 19264, 19296, 19297, 19292,     0, 16384, 18432, 
+    19456, 19200, 19264, 19296, 19297, 19292,     0, 16384, 
+    18432, 19456, 19200, 19264, 19296, 19297, 19292, 19294, 
+        0, 16384, 18432, 19456, 19200, 19264,     0, 16384, 
+    18432, 19456, 19200, 19328, 19296,     0, 16384, 18432, 
+    19456, 19200, 19328, 19296,     0, 16384, 18432, 19456, 
+    19200, 19328, 19296, 19298,     0, 16384, 18432, 19456, 
+    19200, 19328, 19296,     0, 16384, 18432, 19456, 19200, 
+    19328, 19296, 19300,     0, 16384, 18432, 19456, 19200, 
+    19328, 19296, 19300,     0, 16384, 18432, 19456, 19200, 
+    19328, 19296, 19304, 19302,     0, 16384, 18432, 19456, 
+    19200, 19328, 19296,     0, 16384, 18432, 19456, 19200, 
+    19328, 19296, 19304,     0, 16384, 18432, 19456, 19200, 
+    19328, 19296, 19304,     0, 16384, 18432, 19456, 19200, 
+    19328, 19296, 19304, 19306,     0, 16384, 18432, 19456, 
+    19200, 19328, 19296, 19304,     0, 16384, 18432, 19456, 
+    19200, 19328, 19296, 19312, 19308,     0, 16384, 18432, 
+    19456, 19200, 19328, 19296, 19312, 19308,     0, 16384, 
+    18432, 19456, 19200, 19328, 19296, 19312, 19313, 19310, 
+        0, 16384, 18432, 19456, 19200, 19328, 19296,     0, 
+    16384, 18432, 19456, 19200, 19328, 19329, 19312,     0, 
+    16384, 18432, 19456, 19200, 19328, 19329, 19312,     0, 
+    16384, 18432, 19456, 19200, 19328, 19329, 19312, 19314, 
+        0, 16384, 18432, 19456, 19200, 19328, 19329, 19312, 
+        0, 16384, 18432, 19456, 19200, 19328, 19329, 19312, 
+    19316,     0, 16384, 18432, 19456, 19200, 19328, 19329, 
+    19312, 19316,     0, 16384, 18432, 19456, 19200, 19328, 
+    19329, 19312, 19320, 19318,     0, 16384, 18432, 19456, 
+    19200, 19328, 19329, 19312,     0, 16384, 18432, 19456, 
+    19200, 19328, 19329, 19312, 19320,     0, 16384, 18432, 
+    19456, 19200, 19328, 19329, 19331, 19320,     0, 16384, 
+    18432, 19456, 19200, 19328, 19329, 19331, 19320, 19322, 
+        0, 16384, 18432, 19456, 19200, 19328, 19329, 19331, 
+    19320,     0, 16384, 18432, 19456, 19200, 19328, 19329, 
+    19331, 19320, 19324,     0, 16384, 18432, 19456, 19200, 
+    19328, 19329, 19331, 19320, 19324,     0, 16384, 18432, 
+    19456, 19200, 19328, 19329, 19331, 19320, 19324, 19326, 
+        0, 16384, 18432, 19456, 19200,     0, 16384, 18432, 
+    19456, 19200, 19328,     0, 16384, 18432, 19456, 19457, 
+    19328,     0, 16384, 18432, 19456, 19457, 19328, 19330, 
+        0, 16384, 18432, 19456, 19457, 19328,     0, 16384, 
+    18432, 19456, 19457, 19328, 19332,     0, 16384, 18432, 
+    19456, 19457, 19328, 19332,     0, 16384, 18432, 19456, 
+    19457, 19328, 19336, 19334,     0, 16384, 18432, 19456, 
+    19457, 19328,     0, 16384, 18432, 19456, 19457, 19328, 
+    19336,     0, 16384, 18432, 19456, 19457, 19328, 19336, 
+        0, 16384, 18432, 19456, 19457, 19328, 19336, 19338, 
+        0, 16384, 18432, 19456, 19457, 19328, 19336,     0, 
+    16384, 18432, 19456, 19457, 19328, 19344, 19340,     0, 
+    16384, 18432, 19456, 19457, 19328, 19344, 19340,     0, 
+    16384, 18432, 19456, 19457, 19328, 19344, 19345, 19342, 
+        0, 16384, 18432, 19456, 19457, 19328,     0, 16384, 
+    18432, 19456, 19457, 19328, 19344,     0, 16384, 18432, 
+    19456, 19457, 19328, 19344,     0, 16384, 18432, 19456, 
+    19457, 19328, 19344, 19346,     0, 16384, 18432, 19456, 
+    19457, 19328, 19344,     0, 16384, 18432, 19456, 19457, 
+    19328, 19344, 19348,     0, 16384, 18432, 19456, 19457, 
+    19328, 19344, 19348,     0, 16384, 18432, 19456, 19457, 
+    19328, 19344, 19352, 19350,     0, 16384, 18432, 19456, 
+    19457, 19328, 19344,     0, 16384, 18432, 19456, 19457, 
+    19328, 19360, 19352,     0, 16384, 18432, 19456, 19457, 
+    19328, 19360, 19352,     0, 16384, 18432, 19456, 19457, 
+    19328, 19360, 19352, 19354,     0, 16384, 18432, 19456, 
+    19457, 19328, 19360, 19352,     0, 16384, 18432, 19456, 
+    19457, 19328, 19360, 19361, 19356,     0, 16384, 18432, 
+    19456, 19457, 19328, 19360, 19361, 19356,     0, 16384, 
+    18432, 19456, 19457, 19328, 19360, 19361, 19356, 19358, 
+        0, 16384, 18432, 19456, 19457, 19328,     0, 16384, 
+    18432, 19456, 19457, 19328, 19360,     0, 16384, 18432, 
+    19456, 19457, 19328, 19360,     0, 16384, 18432, 19456, 
+    19457, 19328, 19360, 19362,     0, 16384, 18432, 19456, 
+    19457, 19328, 19360,     0, 16384, 18432, 19456, 19457, 
+    19328, 19360, 19364,     0, 16384, 18432, 19456, 19457, 
+    19328, 19360, 19364,     0, 16384, 18432, 19456, 19457, 
+    19328, 19360, 19368, 19366,     0, 16384, 18432, 19456, 
+    19457, 19328, 19360,     0, 16384, 18432, 19456, 19457, 
+    19328, 19360, 19368,     0, 16384, 18432, 19456, 19457, 
+    19328, 19360, 19368,     0, 16384, 18432, 19456, 19457, 
+    19328, 19360, 19368, 19370,     0, 16384, 18432, 19456, 
+    19457, 19328, 19360, 19368,     0, 16384, 18432, 19456, 
+    19457, 19328, 19360, 19376, 19372,     0, 16384, 18432, 
+    19456, 19457, 19328, 19360, 19376, 19372,     0, 16384, 
+    18432, 19456, 19457, 19328, 19360, 19376, 19377, 19374, 
+        0, 16384, 18432, 19456, 19457, 19328, 19360,     0, 
+    16384, 18432, 19456, 19457, 19328, 19392, 19376,     0, 
+    16384, 18432, 19456, 19457, 19328, 19392, 19376,     0, 
+    16384, 18432, 19456, 19457, 19328, 19392, 19376, 19378, 
+        0, 16384, 18432, 19456, 19457, 19328, 19392, 19376, 
+        0, 16384, 18432, 19456, 19457, 19328, 19392, 19376, 
+    19380,     0, 16384, 18432, 19456, 19457, 19328, 19392, 
+    19376, 19380,     0, 16384, 18432, 19456, 19457, 19328, 
+    19392, 19376, 19384, 19382,     0, 16384, 18432, 19456, 
+    19457, 19328, 19392, 19376,     0, 16384, 18432, 19456, 
+    19457, 19328, 19392, 19393, 19384,     0, 16384, 18432, 
+    19456, 19457, 19328, 19392, 19393, 19384,     0, 16384, 
+    18432, 19456, 19457, 19328, 19392, 19393, 19384, 19386, 
+        0, 16384, 18432, 19456, 19457, 19328, 19392, 19393, 
+    19384,     0, 16384, 18432, 19456, 19457, 19328, 19392, 
+    19393, 19384, 19388,     0, 16384, 18432, 19456, 19457, 
+    19328, 19392, 19393, 19395, 19388,     0, 16384, 18432, 
+    19456, 19457, 19328, 19392, 19393, 19395, 19388, 19390, 
+        0, 16384, 18432, 19456, 19457, 19328,     0, 16384, 
+    18432, 19456, 19457, 19328, 19392,     0, 16384, 18432, 
+    19456, 19457, 19328, 19392,     0, 16384, 18432, 19456, 
+    19457, 19328, 19392, 19394,     0, 16384, 18432, 19456, 
+    19457, 19459, 19392,     0, 16384, 18432, 19456, 19457, 
+    19459, 19392, 19396,     0, 16384, 18432, 19456, 19457, 
+    19459, 19392, 19396,     0, 16384, 18432, 19456, 19457, 
+    19459, 19392, 19400, 19398,     0, 16384, 18432, 19456, 
+    19457, 19459, 19392,     0, 16384, 18432, 19456, 19457, 
+    19459, 19392, 19400,     0, 16384, 18432, 19456, 19457, 
+    19459, 19392, 19400,     0, 16384, 18432, 19456, 19457, 
+    19459, 19392, 19400, 19402,     0, 16384, 18432, 19456, 
+    19457, 19459, 19392, 19400,     0, 16384, 18432, 19456, 
+    19457, 19459, 19392, 19408, 19404,     0, 16384, 18432, 
+    19456, 19457, 19459, 19392, 19408, 19404,     0, 16384, 
+    18432, 19456, 19457, 19459, 19392, 19408, 19409, 19406, 
+        0, 16384, 18432, 19456, 19457, 19459, 19392,     0, 
+    16384, 18432, 19456, 19457, 19459, 19392, 19408,     0, 
+    16384, 18432, 19456, 19457, 19459, 19392, 19408,     0, 
+    16384, 18432, 19456, 19457, 19459, 19392, 19408, 19410, 
+        0, 16384, 18432, 19456, 19457, 19459, 19392, 19408, 
+        0, 16384, 18432, 19456, 19457, 19459, 19392, 19408, 
+    19412,     0, 16384, 18432, 19456, 19457, 19459, 19392, 
+    19408, 19412,     0, 16384, 18432, 19456, 19457, 19459, 
+    19392, 19408, 19416, 19414,     0, 16384, 18432, 19456, 
+    19457, 19459, 19392, 19408,     0, 16384, 18432, 19456, 
+    19457, 19459, 19392, 19424, 19416,     0, 16384, 18432, 
+    19456, 19457, 19459, 19392, 19424, 19416,     0, 16384, 
+    18432, 19456, 19457, 19459, 19392, 19424, 19416, 19418, 
+        0, 16384, 18432, 19456, 19457, 19459, 19392, 19424, 
+    19416,     0, 16384, 18432, 19456, 19457, 19459, 19392, 
+    19424, 19425, 19420,     0, 16384, 18432, 19456, 19457, 
+    19459, 19392, 19424, 19425, 19420,     0, 16384, 18432, 
+    19456, 19457, 19459, 19392, 19424, 19425, 19420, 19422, 
+        0, 16384, 18432, 19456, 19457, 19459, 19392,     0, 
+    16384, 18432, 19456, 19457, 19459, 19392, 19424,     0, 
+    16384, 18432, 19456, 19457, 19459, 19392, 19424,     0, 
+    16384, 18432, 19456, 19457, 19459, 19392, 19424, 19426, 
+        0, 16384, 18432, 19456, 19457, 19459, 19392, 19424, 
+        0, 16384, 18432, 19456, 19457, 19459, 19392, 19424, 
+    19428,     0, 16384, 18432, 19456, 19457, 19459, 19392, 
+    19424, 19428,     0, 16384, 18432, 19456, 19457, 19459, 
+    19392, 19424, 19432, 19430,     0, 16384, 18432, 19456, 
+    19457, 19459, 19463, 19424,     0, 16384, 18432, 19456, 
+    19457, 19459, 19463, 19424, 19432,     0, 16384, 18432, 
+    19456, 19457, 19459, 19463, 19424, 19432,     0, 16384, 
+    18432, 19456, 19457, 19459, 19463, 19424, 19432, 19434, 
+        0, 16384, 18432, 19456, 19457, 19459, 19463, 19424, 
+    19432,     0, 16384, 18432, 19456, 19457, 19459, 19463, 
+    19424, 19440, 19436,     0, 16384, 18432, 19456, 19457, 
+    19459, 19463, 19424, 19440, 19436,     0, 16384, 18432, 
+    19456, 19457, 19459, 19463, 19424, 19440, 19441, 19438, 
+        0, 16384, 18432, 19456, 19457, 19459, 19463, 19424, 
+        0, 16384, 18432, 19456, 19457, 19459, 19463, 19424, 
+    19440,     0, 16384, 18432, 19456, 19457, 19459, 19463, 
+    19424, 19440,     0, 16384, 18432, 19456, 19457, 19459, 
+    19463, 19424, 19440, 19442,     0, 16384, 18432, 19456, 
+    19457, 19459, 19463, 19424, 19440,     0, 16384, 18432, 
+    19456, 19457, 19459, 19463, 19424, 19440, 19444,     0, 
+    16384, 18432, 19456, 19457, 19459, 19463, 19424, 19440, 
+    19444,     0, 16384, 18432, 19456, 19457, 19459, 19463, 
+    19424, 19440, 19448, 19446,     0, 16384, 18432, 19456, 
+    19457, 19459, 19463, 19424, 19440,     0, 16384, 18432, 
+    19456, 19457, 19459, 19463, 19424, 19440, 19448,     0, 
+    16384, 18432, 19456, 19457, 19459, 19463, 19424, 19440, 
+    19448,     0, 16384, 18432, 19456, 19457, 19459, 19463, 
+    19424, 19440, 19448, 19450,     0, 16384, 18432, 19456, 
+    19457, 19459, 19463, 19424, 19440, 19448,     0, 16384, 
+    18432, 19456, 19457, 19459, 19463, 19424, 19440, 19448, 
+    19452,     0, 16384, 18432, 19456, 19457, 19459, 19463, 
+    19424, 19440, 19448, 19452,     0, 16384, 18432, 19456, 
+    19457, 19459, 19463, 19424, 19440, 19448, 19452, 19454, 
+        0, 16384, 18432,     0, 16384, 18432, 19456,     0, 
+    16384, 18432, 19456,     0, 16384, 18432, 19456, 19458, 
+        0, 16384, 18432, 19456,     0, 16384, 18432, 19456, 
+    19460,     0, 16384, 18432, 19456, 19460,     0, 16384, 
+    18432, 19456, 19464, 19462,     0, 16384, 18432, 19456, 
+        0, 16384, 18432, 19456, 19464,     0, 16384, 18432, 
+    19456, 19464,     0, 16384, 18432, 19456, 19464, 19466, 
+        0, 16384, 18432, 19456, 19464,     0, 16384, 18432, 
+    19456, 19472, 19468,     0, 16384, 18432, 19456, 19472, 
+    19468,     0, 16384, 18432, 19456, 19472, 19473, 19470, 
+        0, 16384, 18432, 19456,     0, 16384, 18432, 19456, 
+    19472,     0, 16384, 18432, 19456, 19472,     0, 16384, 
+    18432, 19456, 19472, 19474,     0, 16384, 18432, 19456, 
+    19472,     0, 16384, 18432, 19456, 19472, 19476,     0, 
+    16384, 18432, 19456, 19472, 19476,     0, 16384, 18432, 
+    19456, 19472, 19480, 19478,     0, 16384, 18432, 19456, 
+    19472,     0, 16384, 18432, 19456, 19488, 19480,     0, 
+    16384, 18432, 19456, 19488, 19480,     0, 16384, 18432, 
+    19456, 19488, 19480, 19482,     0, 16384, 18432, 19456, 
+    19488, 19480,     0, 16384, 18432, 19456, 19488, 19489, 
+    19484,     0, 16384, 18432, 19456, 19488, 19489, 19484, 
+        0, 16384, 18432, 19456, 19488, 19489, 19484, 19486, 
+        0, 16384, 18432, 19456,     0, 16384, 18432, 19456, 
+    19488,     0, 16384, 18432, 19456, 19488,     0, 16384, 
+    18432, 19456, 19488, 19490,     0, 16384, 18432, 19456, 
+    19488,     0, 16384, 18432, 19456, 19488, 19492,     0, 
+    16384, 18432, 19456, 19488, 19492,     0, 16384, 18432, 
+    19456, 19488, 19496, 19494,     0, 16384, 18432, 19456, 
+    19488,     0, 16384, 18432, 19456, 19488, 19496,     0, 
+    16384, 18432, 19456, 19488, 19496,     0, 16384, 18432, 
+    19456, 19488, 19496, 19498,     0, 16384, 18432, 19456, 
+    19488, 19496,     0, 16384, 18432, 19456, 19488, 19504, 
+    19500,     0, 16384, 18432, 19456, 19488, 19504, 19500, 
+        0, 16384, 18432, 19456, 19488, 19504, 19505, 19502, 
+        0, 16384, 18432, 19456, 19488,     0, 16384, 18432, 
+    19456, 19520, 19504,     0, 16384, 18432, 19456, 19520, 
+    19504,     0, 16384, 18432, 19456, 19520, 19504, 19506, 
+        0, 16384, 18432, 19456, 19520, 19504,     0, 16384, 
+    18432, 19456, 19520, 19504, 19508,     0, 16384, 18432, 
+    19456, 19520, 19504, 19508,     0, 16384, 18432, 19456, 
+    19520, 19504, 19512, 19510,     0, 16384, 18432, 19456, 
+    19520, 19504,     0, 16384, 18432, 19456, 19520, 19521, 
+    19512,     0, 16384, 18432, 19456, 19520, 19521, 19512, 
+        0, 16384, 18432, 19456, 19520, 19521, 19512, 19514, 
+        0, 16384, 18432, 19456, 19520, 19521, 19512,     0, 
+    16384, 18432, 19456, 19520, 19521, 19512, 19516,     0, 
+    16384, 18432, 19456, 19520, 19521, 19523, 19516,     0, 
+    16384, 18432, 19456, 19520, 19521, 19523, 19516, 19518, 
+        0, 16384, 18432, 19456,     0, 16384, 18432, 19456, 
+    19520,     0, 16384, 18432, 19456, 19520,     0, 16384, 
+    18432, 19456, 19520, 19522,     0, 16384, 18432, 19456, 
+    19520,     0, 16384, 18432, 19456, 19520, 19524,     0, 
+    16384, 18432, 19456, 19520, 19524,     0, 16384, 18432, 
+    19456, 19520, 19528, 19526,     0, 16384, 18432, 19456, 
+    19520,     0, 16384, 18432, 19456, 19520, 19528,     0, 
+    16384, 18432, 19456, 19520, 19528,     0, 16384, 18432, 
+    19456, 19520, 19528, 19530,     0, 16384, 18432, 19456, 
+    19520, 19528,     0, 16384, 18432, 19456, 19520, 19536, 
+    19532,     0, 16384, 18432, 19456, 19520, 19536, 19532, 
+        0, 16384, 18432, 19456, 19520, 19536, 19537, 19534, 
+        0, 16384, 18432, 19456, 19520,     0, 16384, 18432, 
+    19456, 19520, 19536,     0, 16384, 18432, 19456, 19520, 
+    19536,     0, 16384, 18432, 19456, 19520, 19536, 19538, 
+        0, 16384, 18432, 19456, 19520, 19536,     0, 16384, 
+    18432, 19456, 19520, 19536, 19540,     0, 16384, 18432, 
+    19456, 19520, 19536, 19540,     0, 16384, 18432, 19456, 
+    19520, 19536, 19544, 19542,     0, 16384, 18432, 19456, 
+    19520, 19536,     0, 16384, 18432, 19456, 19520, 19552, 
+    19544,     0, 16384, 18432, 19456, 19520, 19552, 19544, 
+        0, 16384, 18432, 19456, 19520, 19552, 19544, 19546, 
+        0, 16384, 18432, 19456, 19520, 19552, 19544,     0, 
+    16384, 18432, 19456, 19520, 19552, 19553, 19548,     0, 
+    16384, 18432, 19456, 19520, 19552, 19553, 19548,     0, 
+    16384, 18432, 19456, 19520, 19552, 19553, 19548, 19550, 
+        0, 16384, 18432, 19456, 19520,     0, 16384, 18432, 
+    19456, 19584, 19552,     0, 16384, 18432, 19456, 19584, 
+    19552,     0, 16384, 18432, 19456, 19584, 19552, 19554, 
+        0, 16384, 18432, 19456, 19584, 19552,     0, 16384, 
+    18432, 19456, 19584, 19552, 19556,     0, 16384, 18432, 
+    19456, 19584, 19552, 19556,     0, 16384, 18432, 19456, 
+    19584, 19552, 19560, 19558,     0, 16384, 18432, 19456, 
+    19584, 19552,     0, 16384, 18432, 19456, 19584, 19552, 
+    19560,     0, 16384, 18432, 19456, 19584, 19552, 19560, 
+        0, 16384, 18432, 19456, 19584, 19552, 19560, 19562, 
+        0, 16384, 18432, 19456, 19584, 19552, 19560,     0, 
+    16384, 18432, 19456, 19584, 19552, 19568, 19564,     0, 
+    16384, 18432, 19456, 19584, 19552, 19568, 19564,     0, 
+    16384, 18432, 19456, 19584, 19552, 19568, 19569, 19566, 
+        0, 16384, 18432, 19456, 19584, 19552,     0, 16384, 
+    18432, 19456, 19584, 19585, 19568,     0, 16384, 18432, 
+    19456, 19584, 19585, 19568,     0, 16384, 18432, 19456, 
+    19584, 19585, 19568, 19570,     0, 16384, 18432, 19456, 
+    19584, 19585, 19568,     0, 16384, 18432, 19456, 19584, 
+    19585, 19568, 19572,     0, 16384, 18432, 19456, 19584, 
+    19585, 19568, 19572,     0, 16384, 18432, 19456, 19584, 
+    19585, 19568, 19576, 19574,     0, 16384, 18432, 19456, 
+    19584, 19585, 19568,     0, 16384, 18432, 19456, 19584, 
+    19585, 19568, 19576,     0, 16384, 18432, 19456, 19584, 
+    19585, 19587, 19576,     0, 16384, 18432, 19456, 19584, 
+    19585, 19587, 19576, 19578,     0, 16384, 18432, 19456, 
+    19584, 19585, 19587, 19576,     0, 16384, 18432, 19456, 
+    19584, 19585, 19587, 19576, 19580,     0, 16384, 18432, 
+    19456, 19584, 19585, 19587, 19576, 19580,     0, 16384, 
+    18432, 19456, 19584, 19585, 19587, 19576, 19580, 19582, 
+        0, 16384, 18432, 19456,     0, 16384, 18432, 19456, 
+    19584,     0, 16384, 18432, 19456, 19584,     0, 16384, 
+    18432, 19456, 19584, 19586,     0, 16384, 18432, 19456, 
+    19584,     0, 16384, 18432, 19456, 19584, 19588,     0, 
+    16384, 18432, 19456, 19584, 19588,     0, 16384, 18432, 
+    19456, 19584, 19592, 19590,     0, 16384, 18432, 19456, 
+    19584,     0, 16384, 18432, 19456, 19584, 19592,     0, 
+    16384, 18432, 19456, 19584, 19592,     0, 16384, 18432, 
+    19456, 19584, 19592, 19594,     0, 16384, 18432, 19456, 
+    19584, 19592,     0, 16384, 18432, 19456, 19584, 19600, 
+    19596,     0, 16384, 18432, 19456, 19584, 19600, 19596, 
+        0, 16384, 18432, 19456, 19584, 19600, 19601, 19598, 
+        0, 16384, 18432, 19456, 19584,     0, 16384, 18432, 
+    19456, 19584, 19600,     0, 16384, 18432, 19456, 19584, 
+    19600,     0, 16384, 18432, 19456, 19584, 19600, 19602, 
+        0, 16384, 18432, 19456, 19584, 19600,     0, 16384, 
+    18432, 19456, 19584, 19600, 19604,     0, 16384, 18432, 
+    19456, 19584, 19600, 19604,     0, 16384, 18432, 19456, 
+    19584, 19600, 19608, 19606,     0, 16384, 18432, 19456, 
+    19584, 19600,     0, 16384, 18432, 19456, 19584, 19616, 
+    19608,     0, 16384, 18432, 19456, 19584, 19616, 19608, 
+        0, 16384, 18432, 19456, 19584, 19616, 19608, 19610, 
+        0, 16384, 18432, 19456, 19584, 19616, 19608,     0, 
+    16384, 18432, 19456, 19584, 19616, 19617, 19612,     0, 
+    16384, 18432, 19456, 19584, 19616, 19617, 19612,     0, 
+    16384, 18432, 19456, 19584, 19616, 19617, 19612, 19614, 
+        0, 16384, 18432, 19456, 19584,     0, 16384, 18432, 
+    19456, 19584, 19616,     0, 16384, 18432, 19456, 19584, 
+    19616,     0, 16384, 18432, 19456, 19584, 19616, 19618, 
+        0, 16384, 18432, 19456, 19584, 19616,     0, 16384, 
+    18432, 19456, 19584, 19616, 19620,     0, 16384, 18432, 
+    19456, 19584, 19616, 19620,     0, 16384, 18432, 19456, 
+    19584, 19616, 19624, 19622,     0, 16384, 18432, 19456, 
+    19584, 19616,     0, 16384, 18432, 19456, 19584, 19616, 
+    19624,     0, 16384, 18432, 19456, 19584, 19616, 19624, 
+        0, 16384, 18432, 19456, 19584, 19616, 19624, 19626, 
+        0, 16384, 18432, 19456, 19584, 19616, 19624,     0, 
+    16384, 18432, 19456, 19584, 19616, 19632, 19628,     0, 
+    16384, 18432, 19456, 19584, 19616, 19632, 19628,     0, 
+    16384, 18432, 19456, 19584, 19616, 19632, 19633, 19630, 
+        0, 16384, 18432, 19456, 19584, 19616,     0, 16384, 
+    18432, 19456, 19584, 19648, 19632,     0, 16384, 18432, 
+    19456, 19584, 19648, 19632,     0, 16384, 18432, 19456, 
+    19584, 19648, 19632, 19634,     0, 16384, 18432, 19456, 
+    19584, 19648, 19632,     0, 16384, 18432, 19456, 19584, 
+    19648, 19632, 19636,     0, 16384, 18432, 19456, 19584, 
+    19648, 19632, 19636,     0, 16384, 18432, 19456, 19584, 
+    19648, 19632, 19640, 19638,     0, 16384, 18432, 19456, 
+    19584, 19648, 19632,     0, 16384, 18432, 19456, 19584, 
+    19648, 19649, 19640,     0, 16384, 18432, 19456, 19584, 
+    19648, 19649, 19640,     0, 16384, 18432, 19456, 19584, 
+    19648, 19649, 19640, 19642,     0, 16384, 18432, 19456, 
+    19584, 19648, 19649, 19640,     0, 16384, 18432, 19456, 
+    19584, 19648, 19649, 19640, 19644,     0, 16384, 18432, 
+    19456, 19584, 19648, 19649, 19651, 19644,     0, 16384, 
+    18432, 19456, 19584, 19648, 19649, 19651, 19644, 19646, 
+        0, 16384, 18432, 19456, 19584,     0, 16384, 18432, 
+    19456, 19712, 19648,     0, 16384, 18432, 19456, 19712, 
+    19648,     0, 16384, 18432, 19456, 19712, 19648, 19650, 
+        0, 16384, 18432, 19456, 19712, 19648,     0, 16384, 
+    18432, 19456, 19712, 19648, 19652,     0, 16384, 18432, 
+    19456, 19712, 19648, 19652,     0, 16384, 18432, 19456, 
+    19712, 19648, 19656, 19654,     0, 16384, 18432, 19456, 
+    19712, 19648,     0, 16384, 18432, 19456, 19712, 19648, 
+    19656,     0, 16384, 18432, 19456, 19712, 19648, 19656, 
+        0, 16384, 18432, 19456, 19712, 19648, 19656, 19658, 
+        0, 16384, 18432, 19456, 19712, 19648, 19656,     0, 
+    16384, 18432, 19456, 19712, 19648, 19664, 19660,     0, 
+    16384, 18432, 19456, 19712, 19648, 19664, 19660,     0, 
+    16384, 18432, 19456, 19712, 19648, 19664, 19665, 19662, 
+        0, 16384, 18432, 19456, 19712, 19648,     0, 16384, 
+    18432, 19456, 19712, 19648, 19664,     0, 16384, 18432, 
+    19456, 19712, 19648, 19664,     0, 16384, 18432, 19456, 
+    19712, 19648, 19664, 19666,     0, 16384, 18432, 19456, 
+    19712, 19648, 19664,     0, 16384, 18432, 19456, 19712, 
+    19648, 19664, 19668,     0, 16384, 18432, 19456, 19712, 
+    19648, 19664, 19668,     0, 16384, 18432, 19456, 19712, 
+    19648, 19664, 19672, 19670,     0, 16384, 18432, 19456, 
+    19712, 19648, 19664,     0, 16384, 18432, 19456, 19712, 
+    19648, 19680, 19672,     0, 16384, 18432, 19456, 19712, 
+    19648, 19680, 19672,     0, 16384, 18432, 19456, 19712, 
+    19648, 19680, 19672, 19674,     0, 16384, 18432, 19456, 
+    19712, 19648, 19680, 19672,     0, 16384, 18432, 19456, 
+    19712, 19648, 19680, 19681, 19676,     0, 16384, 18432, 
+    19456, 19712, 19648, 19680, 19681, 19676,     0, 16384, 
+    18432, 19456, 19712, 19648, 19680, 19681, 19676, 19678, 
+        0, 16384, 18432, 19456, 19712, 19648,     0, 16384, 
+    18432, 19456, 19712, 19713, 19680,     0, 16384, 18432, 
+    19456, 19712, 19713, 19680,     0, 16384, 18432, 19456, 
+    19712, 19713, 19680, 19682,     0, 16384, 18432, 19456, 
+    19712, 19713, 19680,     0, 16384, 18432, 19456, 19712, 
+    19713, 19680, 19684,     0, 16384, 18432, 19456, 19712, 
+    19713, 19680, 19684,     0, 16384, 18432, 19456, 19712, 
+    19713, 19680, 19688, 19686,     0, 16384, 18432, 19456, 
+    19712, 19713, 19680,     0, 16384, 18432, 19456, 19712, 
+    19713, 19680, 19688,     0, 16384, 18432, 19456, 19712, 
+    19713, 19680, 19688,     0, 16384, 18432, 19456, 19712, 
+    19713, 19680, 19688, 19690,     0, 16384, 18432, 19456, 
+    19712, 19713, 19680, 19688,     0, 16384, 18432, 19456, 
+    19712, 19713, 19680, 19696, 19692,     0, 16384, 18432, 
+    19456, 19712, 19713, 19680, 19696, 19692,     0, 16384, 
+    18432, 19456, 19712, 19713, 19680, 19696, 19697, 19694, 
+        0, 16384, 18432, 19456, 19712, 19713, 19680,     0, 
+    16384, 18432, 19456, 19712, 19713, 19680, 19696,     0, 
+    16384, 18432, 19456, 19712, 19713, 19715, 19696,     0, 
+    16384, 18432, 19456, 19712, 19713, 19715, 19696, 19698, 
+        0, 16384, 18432, 19456, 19712, 19713, 19715, 19696, 
+        0, 16384, 18432, 19456, 19712, 19713, 19715, 19696, 
+    19700,     0, 16384, 18432, 19456, 19712, 19713, 19715, 
+    19696, 19700,     0, 16384, 18432, 19456, 19712, 19713, 
+    19715, 19696, 19704, 19702,     0, 16384, 18432, 19456, 
+    19712, 19713, 19715, 19696,     0, 16384, 18432, 19456, 
+    19712, 19713, 19715, 19696, 19704,     0, 16384, 18432, 
+    19456, 19712, 19713, 19715, 19696, 19704,     0, 16384, 
+    18432, 19456, 19712, 19713, 19715, 19696, 19704, 19706, 
+        0, 16384, 18432, 19456, 19712, 19713, 19715, 19719, 
+    19704,     0, 16384, 18432, 19456, 19712, 19713, 19715, 
+    19719, 19704, 19708,     0, 16384, 18432, 19456, 19712, 
+    19713, 19715, 19719, 19704, 19708,     0, 16384, 18432, 
+    19456, 19712, 19713, 19715, 19719, 19704, 19708, 19710, 
+        0, 16384, 18432, 19456,     0, 16384, 20480, 19456, 
+    19712,     0, 16384, 20480, 19456, 19712,     0, 16384, 
+    20480, 19456, 19712, 19714,     0, 16384, 20480, 19456, 
+    19712,     0, 16384, 20480, 19456, 19712, 19716,     0, 
+    16384, 20480, 19456, 19712, 19716,     0, 16384, 20480, 
+    19456, 19712, 19720, 19718,     0, 16384, 20480, 19456, 
+    19712,     0, 16384, 20480, 19456, 19712, 19720,     0, 
+    16384, 20480, 19456, 19712, 19720,     0, 16384, 20480, 
+    19456, 19712, 19720, 19722,     0, 16384, 20480, 19456, 
+    19712, 19720,     0, 16384, 20480, 19456, 19712, 19728, 
+    19724,     0, 16384, 20480, 19456, 19712, 19728, 19724, 
+        0, 16384, 20480, 19456, 19712, 19728, 19729, 19726, 
+        0, 16384, 20480, 19456, 19712,     0, 16384, 20480, 
+    19456, 19712, 19728,     0, 16384, 20480, 19456, 19712, 
+    19728,     0, 16384, 20480, 19456, 19712, 19728, 19730, 
+        0, 16384, 20480, 19456, 19712, 19728,     0, 16384, 
+    20480, 19456, 19712, 19728, 19732,     0, 16384, 20480, 
+    19456, 19712, 19728, 19732,     0, 16384, 20480, 19456, 
+    19712, 19728, 19736, 19734,     0, 16384, 20480, 19456, 
+    19712, 19728,     0, 16384, 20480, 19456, 19712, 19744, 
+    19736,     0, 16384, 20480, 19456, 19712, 19744, 19736, 
+        0, 16384, 20480, 19456, 19712, 19744, 19736, 19738, 
+        0, 16384, 20480, 19456, 19712, 19744, 19736,     0, 
+    16384, 20480, 19456, 19712, 19744, 19745, 19740,     0, 
+    16384, 20480, 19456, 19712, 19744, 19745, 19740,     0, 
+    16384, 20480, 19456, 19712, 19744, 19745, 19740, 19742, 
+        0, 16384, 20480, 19456, 19712,     0, 16384, 20480, 
+    19456, 19712, 19744,     0, 16384, 20480, 19456, 19712, 
+    19744,     0, 16384, 20480, 19456, 19712, 19744, 19746, 
+        0, 16384, 20480, 19456, 19712, 19744,     0, 16384, 
+    20480, 19456, 19712, 19744, 19748,     0, 16384, 20480, 
+    19456, 19712, 19744, 19748,     0, 16384, 20480, 19456, 
+    19712, 19744, 19752, 19750,     0, 16384, 20480, 19456, 
+    19712, 19744,     0, 16384, 20480, 19456, 19712, 19744, 
+    19752,     0, 16384, 20480, 19456, 19712, 19744, 19752, 
+        0, 16384, 20480, 19456, 19712, 19744, 19752, 19754, 
+        0, 16384, 20480, 19456, 19712, 19744, 19752,     0, 
+    16384, 20480, 19456, 19712, 19744, 19760, 19756,     0, 
+    16384, 20480, 19456, 19712, 19744, 19760, 19756,     0, 
+    16384, 20480, 19456, 19712, 19744, 19760, 19761, 19758, 
+        0, 16384, 20480, 19456, 19712, 19744,     0, 16384, 
+    20480, 19456, 19712, 19776, 19760,     0, 16384, 20480, 
+    19456, 19712, 19776, 19760,     0, 16384, 20480, 19456, 
+    19712, 19776, 19760, 19762,     0, 16384, 20480, 19456, 
+    19712, 19776, 19760,     0, 16384, 20480, 19456, 19712, 
+    19776, 19760, 19764,     0, 16384, 20480, 19456, 19712, 
+    19776, 19760, 19764,     0, 16384, 20480, 19456, 19712, 
+    19776, 19760, 19768, 19766,     0, 16384, 20480, 19456, 
+    19712, 19776, 19760,     0, 16384, 20480, 19456, 19712, 
+    19776, 19777, 19768,     0, 16384, 20480, 19456, 19712, 
+    19776, 19777, 19768,     0, 16384, 20480, 19456, 19712, 
+    19776, 19777, 19768, 19770,     0, 16384, 20480, 19456, 
+    19712, 19776, 19777, 19768,     0, 16384, 20480, 19456, 
+    19712, 19776, 19777, 19768, 19772,     0, 16384, 20480, 
+    19456, 19712, 19776, 19777, 19779, 19772,     0, 16384, 
+    20480, 19456, 19712, 19776, 19777, 19779, 19772, 19774, 
+        0, 16384, 20480, 19456, 19712,     0, 16384, 20480, 
+    19456, 19712, 19776,     0, 16384, 20480, 19456, 19712, 
+    19776,     0, 16384, 20480, 19456, 19712, 19776, 19778, 
+        0, 16384, 20480, 19456, 19712, 19776,     0, 16384, 
+    20480, 19456, 19712, 19776, 19780,     0, 16384, 20480, 
+    19456, 19712, 19776, 19780,     0, 16384, 20480, 19456, 
+    19712, 19776, 19784, 19782,     0, 16384, 20480, 19456, 
+    19712, 19776,     0, 16384, 20480, 19456, 19712, 19776, 
+    19784,     0, 16384, 20480, 19456, 19712, 19776, 19784, 
+        0, 16384, 20480, 19456, 19712, 19776, 19784, 19786, 
+        0, 16384, 20480, 19456, 19712, 19776, 19784,     0, 
+    16384, 20480, 19456, 19712, 19776, 19792, 19788,     0, 
+    16384, 20480, 19456, 19712, 19776, 19792, 19788,     0, 
+    16384, 20480, 19456, 19712, 19776, 19792, 19793, 19790, 
+        0, 16384, 20480, 19456, 19712, 19776,     0, 16384, 
+    20480, 19456, 19712, 19776, 19792,     0, 16384, 20480, 
+    19456, 19712, 19776, 19792,     0, 16384, 20480, 19456, 
+    19712, 19776, 19792, 19794,     0, 16384, 20480, 19456, 
+    19712, 19776, 19792,     0, 16384, 20480, 19456, 19712, 
+    19776, 19792, 19796,     0, 16384, 20480, 19456, 19712, 
+    19776, 19792, 19796,     0, 16384, 20480, 19456, 19712, 
+    19776, 19792, 19800, 19798,     0, 16384, 20480, 19456, 
+    19712, 19776, 19792,     0, 16384, 20480, 19456, 19712, 
+    19776, 19808, 19800,     0, 16384, 20480, 19456, 19712, 
+    19776, 19808, 19800,     0, 16384, 20480, 19456, 19712, 
+    19776, 19808, 19800, 19802,     0, 16384, 20480, 19456, 
+    19712, 19776, 19808, 19800,     0, 16384, 20480, 19456, 
+    19712, 19776, 19808, 19809, 19804,     0, 16384, 20480, 
+    19456, 19712, 19776, 19808, 19809, 19804,     0, 16384, 
+    20480, 19456, 19712, 19776, 19808, 19809, 19804, 19806, 
+        0, 16384, 20480, 19456, 19712, 19776,     0, 16384, 
+    20480, 19456, 19712, 19840, 19808,     0, 16384, 20480, 
+    19456, 19712, 19840, 19808,     0, 16384, 20480, 19456, 
+    19712, 19840, 19808, 19810,     0, 16384, 20480, 19456, 
+    19712, 19840, 19808,     0, 16384, 20480, 19456, 19712, 
+    19840, 19808, 19812,     0, 16384, 20480, 19456, 19712, 
+    19840, 19808, 19812,     0, 16384, 20480, 19456, 19712, 
+    19840, 19808, 19816, 19814,     0, 16384, 20480, 19456, 
+    19712, 19840, 19808,     0, 16384, 20480, 19456, 19712, 
+    19840, 19808, 19816,     0, 16384, 20480, 19456, 19712, 
+    19840, 19808, 19816,     0, 16384, 20480, 19456, 19712, 
+    19840, 19808, 19816, 19818,     0, 16384, 20480, 19456, 
+    19712, 19840, 19808, 19816,     0, 16384, 20480, 19456, 
+    19712, 19840, 19808, 19824, 19820,     0, 16384, 20480, 
+    19456, 19712, 19840, 19808, 19824, 19820,     0, 16384, 
+    20480, 19456, 19712, 19840, 19808, 19824, 19825, 19822, 
+        0, 16384, 20480, 19456, 19712, 19840, 19808,     0, 
+    16384, 20480, 19456, 19712, 19840, 19841, 19824,     0, 
+    16384, 20480, 19456, 19712, 19840, 19841, 19824,     0, 
+    16384, 20480, 19456, 19712, 19840, 19841, 19824, 19826, 
+        0, 16384, 20480, 19456, 19712, 19840, 19841, 19824, 
+        0, 16384, 20480, 19456, 19712, 19840, 19841, 19824, 
+    19828,     0, 16384, 20480, 19456, 19712, 19840, 19841, 
+    19824, 19828,     0, 16384, 20480, 19456, 19712, 19840, 
+    19841, 19824, 19832, 19830,     0, 16384, 20480, 19456, 
+    19712, 19840, 19841, 19824,     0, 16384, 20480, 19456, 
+    19712, 19840, 19841, 19824, 19832,     0, 16384, 20480, 
+    19456, 19712, 19840, 19841, 19843, 19832,     0, 16384, 
+    20480, 19456, 19712, 19840, 19841, 19843, 19832, 19834, 
+        0, 16384, 20480, 19456, 19712, 19840, 19841, 19843, 
+    19832,     0, 16384, 20480, 19456, 19712, 19840, 19841, 
+    19843, 19832, 19836,     0, 16384, 20480, 19456, 19712, 
+    19840, 19841, 19843, 19832, 19836,     0, 16384, 20480, 
+    19456, 19712, 19840, 19841, 19843, 19832, 19836, 19838, 
+        0, 16384, 20480, 19456, 19712,     0, 16384, 20480, 
+    19456, 19968, 19840,     0, 16384, 20480, 19456, 19968, 
+    19840,     0, 16384, 20480, 19456, 19968, 19840, 19842, 
+        0, 16384, 20480, 19456, 19968, 19840,     0, 16384, 
+    20480, 19456, 19968, 19840, 19844,     0, 16384, 20480, 
+    19456, 19968, 19840, 19844,     0, 16384, 20480, 19456, 
+    19968, 19840, 19848, 19846,     0, 16384, 20480, 19456, 
+    19968, 19840,     0, 16384, 20480, 19456, 19968, 19840, 
+    19848,     0, 16384, 20480, 19456, 19968, 19840, 19848, 
+        0, 16384, 20480, 19456, 19968, 19840, 19848, 19850, 
+        0, 16384, 20480, 19456, 19968, 19840, 19848,     0, 
+    16384, 20480, 19456, 19968, 19840, 19856, 19852,     0, 
+    16384, 20480, 19456, 19968, 19840, 19856, 19852,     0, 
+    16384, 20480, 19456, 19968, 19840, 19856, 19857, 19854, 
+        0, 16384, 20480, 19456, 19968, 19840,     0, 16384, 
+    20480, 19456, 19968, 19840, 19856,     0, 16384, 20480, 
+    19456, 19968, 19840, 19856,     0, 16384, 20480, 19456, 
+    19968, 19840, 19856, 19858,     0, 16384, 20480, 19456, 
+    19968, 19840, 19856,     0, 16384, 20480, 19456, 19968, 
+    19840, 19856, 19860,     0, 16384, 20480, 19456, 19968, 
+    19840, 19856, 19860,     0, 16384, 20480, 19456, 19968, 
+    19840, 19856, 19864, 19862,     0, 16384, 20480, 19456, 
+    19968, 19840, 19856,     0, 16384, 20480, 19456, 19968, 
+    19840, 19872, 19864,     0, 16384, 20480, 19456, 19968, 
+    19840, 19872, 19864,     0, 16384, 20480, 19456, 19968, 
+    19840, 19872, 19864, 19866,     0, 16384, 20480, 19456, 
+    19968, 19840, 19872, 19864,     0, 16384, 20480, 19456, 
+    19968, 19840, 19872, 19873, 19868,     0, 16384, 20480, 
+    19456, 19968, 19840, 19872, 19873, 19868,     0, 16384, 
+    20480, 19456, 19968, 19840, 19872, 19873, 19868, 19870, 
+        0, 16384, 20480, 19456, 19968, 19840,     0, 16384, 
+    20480, 19456, 19968, 19840, 19872,     0, 16384, 20480, 
+    19456, 19968, 19840, 19872,     0, 16384, 20480, 19456, 
+    19968, 19840, 19872, 19874,     0, 16384, 20480, 19456, 
+    19968, 19840, 19872,     0, 16384, 20480, 19456, 19968, 
+    19840, 19872, 19876,     0, 16384, 20480, 19456, 19968, 
+    19840, 19872, 19876,     0, 16384, 20480, 19456, 19968, 
+    19840, 19872, 19880, 19878,     0, 16384, 20480, 19456, 
+    19968, 19840, 19872,     0, 16384, 20480, 19456, 19968, 
+    19840, 19872, 19880,     0, 16384, 20480, 19456, 19968, 
+    19840, 19872, 19880,     0, 16384, 20480, 19456, 19968, 
+    19840, 19872, 19880, 19882,     0, 16384, 20480, 19456, 
+    19968, 19840, 19872, 19880,     0, 16384, 20480, 19456, 
+    19968, 19840, 19872, 19888, 19884,     0, 16384, 20480, 
+    19456, 19968, 19840, 19872, 19888, 19884,     0, 16384, 
+    20480, 19456, 19968, 19840, 19872, 19888, 19889, 19886, 
+        0, 16384, 20480, 19456, 19968, 19840, 19872,     0, 
+    16384, 20480, 19456, 19968, 19840, 19904, 19888,     0, 
+    16384, 20480, 19456, 19968, 19840, 19904, 19888,     0, 
+    16384, 20480, 19456, 19968, 19840, 19904, 19888, 19890, 
+        0, 16384, 20480, 19456, 19968, 19840, 19904, 19888, 
+        0, 16384, 20480, 19456, 19968, 19840, 19904, 19888, 
+    19892,     0, 16384, 20480, 19456, 19968, 19840, 19904, 
+    19888, 19892,     0, 16384, 20480, 19456, 19968, 19840, 
+    19904, 19888, 19896, 19894,     0, 16384, 20480, 19456, 
+    19968, 19840, 19904, 19888,     0, 16384, 20480, 19456, 
+    19968, 19840, 19904, 19905, 19896,     0, 16384, 20480, 
+    19456, 19968, 19840, 19904, 19905, 19896,     0, 16384, 
+    20480, 19456, 19968, 19840, 19904, 19905, 19896, 19898, 
+        0, 16384, 20480, 19456, 19968, 19840, 19904, 19905, 
+    19896,     0, 16384, 20480, 19456, 19968, 19840, 19904, 
+    19905, 19896, 19900,     0, 16384, 20480, 19456, 19968, 
+    19840, 19904, 19905, 19907, 19900,     0, 16384, 20480, 
+    19456, 19968, 19840, 19904, 19905, 19907, 19900, 19902, 
+        0, 16384, 20480, 19456, 19968, 19840,     0, 16384, 
+    20480, 19456, 19968, 19969, 19904,     0, 16384, 20480, 
+    19456, 19968, 19969, 19904,     0, 16384, 20480, 19456, 
+    19968, 19969, 19904, 19906,     0, 16384, 20480, 19456, 
+    19968, 19969, 19904,     0, 16384, 20480, 19456, 19968, 
+    19969, 19904, 19908,     0, 16384, 20480, 19456, 19968, 
+    19969, 19904, 19908,     0, 16384, 20480, 19456, 19968, 
+    19969, 19904, 19912, 19910,     0, 16384, 20480, 19456, 
+    19968, 19969, 19904,     0, 16384, 20480, 19456, 19968, 
+    19969, 19904, 19912,     0, 16384, 20480, 19456, 19968, 
+    19969, 19904, 19912,     0, 16384, 20480, 19456, 19968, 
+    19969, 19904, 19912, 19914,     0, 16384, 20480, 19456, 
+    19968, 19969, 19904, 19912,     0, 16384, 20480, 19456, 
+    19968, 19969, 19904, 19920, 19916,     0, 16384, 20480, 
+    19456, 19968, 19969, 19904, 19920, 19916,     0, 16384, 
+    20480, 19456, 19968, 19969, 19904, 19920, 19921, 19918, 
+        0, 16384, 20480, 19456, 19968, 19969, 19904,     0, 
+    16384, 20480, 19456, 19968, 19969, 19904, 19920,     0, 
+    16384, 20480, 19456, 19968, 19969, 19904, 19920,     0, 
+    16384, 20480, 19456, 19968, 19969, 19904, 19920, 19922, 
+        0, 16384, 20480, 19456, 19968, 19969, 19904, 19920, 
+        0, 16384, 20480, 19456, 19968, 19969, 19904, 19920, 
+    19924,     0, 16384, 20480, 19456, 19968, 19969, 19904, 
+    19920, 19924,     0, 16384, 20480, 19456, 19968, 19969, 
+    19904, 19920, 19928, 19926,     0, 16384, 20480, 19456, 
+    19968, 19969, 19904, 19920,     0, 16384, 20480, 19456, 
+    19968, 19969, 19904, 19936, 19928,     0, 16384, 20480, 
+    19456, 19968, 19969, 19904, 19936, 19928,     0, 16384, 
+    20480, 19456, 19968, 19969, 19904, 19936, 19928, 19930, 
+        0, 16384, 20480, 19456, 19968, 19969, 19904, 19936, 
+    19928,     0, 16384, 20480, 19456, 19968, 19969, 19904, 
+    19936, 19937, 19932,     0, 16384, 20480, 19456, 19968, 
+    19969, 19904, 19936, 19937, 19932,     0, 16384, 20480, 
+    19456, 19968, 19969, 19904, 19936, 19937, 19932, 19934, 
+        0, 16384, 20480, 19456, 19968, 19969, 19904,     0, 
+    16384, 20480, 19456, 19968, 19969, 19904, 19936,     0, 
+    16384, 20480, 19456, 19968, 19969, 19971, 19936,     0, 
+    16384, 20480, 19456, 19968, 19969, 19971, 19936, 19938, 
+        0, 16384, 20480, 19456, 19968, 19969, 19971, 19936, 
+        0, 16384, 20480, 19456, 19968, 19969, 19971, 19936, 
+    19940,     0, 16384, 20480, 19456, 19968, 19969, 19971, 
+    19936, 19940,     0, 16384, 20480, 19456, 19968, 19969, 
+    19971, 19936, 19944, 19942,     0, 16384, 20480, 19456, 
+    19968, 19969, 19971, 19936,     0, 16384, 20480, 19456, 
+    19968, 19969, 19971, 19936, 19944,     0, 16384, 20480, 
+    19456, 19968, 19969, 19971, 19936, 19944,     0, 16384, 
+    20480, 19456, 19968, 19969, 19971, 19936, 19944, 19946, 
+        0, 16384, 20480, 19456, 19968, 19969, 19971, 19936, 
+    19944,     0, 16384, 20480, 19456, 19968, 19969, 19971, 
+    19936, 19952, 19948,     0, 16384, 20480, 19456, 19968, 
+    19969, 19971, 19936, 19952, 19948,     0, 16384, 20480, 
+    19456, 19968, 19969, 19971, 19936, 19952, 19953, 19950, 
+        0, 16384, 20480, 19456, 19968, 19969, 19971, 19936, 
+        0, 16384, 20480, 19456, 19968, 19969, 19971, 19936, 
+    19952,     0, 16384, 20480, 19456, 19968, 19969, 19971, 
+    19936, 19952,     0, 16384, 20480, 19456, 19968, 19969, 
+    19971, 19936, 19952, 19954,     0, 16384, 20480, 19456, 
+    19968, 19969, 19971, 19975, 19952,     0, 16384, 20480, 
+    19456, 19968, 19969, 19971, 19975, 19952, 19956,     0, 
+    16384, 20480, 19456, 19968, 19969, 19971, 19975, 19952, 
+    19956,     0, 16384, 20480, 19456, 19968, 19969, 19971, 
+    19975, 19952, 19960, 19958,     0, 16384, 20480, 19456, 
+    19968, 19969, 19971, 19975, 19952,     0, 16384, 20480, 
+    19456, 19968, 19969, 19971, 19975, 19952, 19960,     0, 
+    16384, 20480, 19456, 19968, 19969, 19971, 19975, 19952, 
+    19960,     0, 16384, 20480, 19456, 19968, 19969, 19971, 
+    19975, 19952, 19960, 19962,     0, 16384, 20480, 19456, 
+    19968, 19969, 19971, 19975, 19952, 19960,     0, 16384, 
+    20480, 19456, 19968, 19969, 19971, 19975, 19952, 19960, 
+    19964,     0, 16384, 20480, 19456, 19968, 19969, 19971, 
+    19975, 19952, 19960, 19964,     0, 16384, 20480, 19456, 
+    19968, 19969, 19971, 19975, 19952, 19960, 19964, 19966, 
+        0, 16384, 20480, 19456,     0, 16384, 20480, 19456, 
+    19968,     0, 16384, 20480, 20481, 19968,     0, 16384, 
+    20480, 20481, 19968, 19970,     0, 16384, 20480, 20481, 
+    19968,     0, 16384, 20480, 20481, 19968, 19972,     0, 
+    16384, 20480, 20481, 19968, 19972,     0, 16384, 20480, 
+    20481, 19968, 19976, 19974,     0, 16384, 20480, 20481, 
+    19968,     0, 16384, 20480, 20481, 19968, 19976,     0, 
+    16384, 20480, 20481, 19968, 19976,     0, 16384, 20480, 
+    20481, 19968, 19976, 19978,     0, 16384, 20480, 20481, 
+    19968, 19976,     0, 16384, 20480, 20481, 19968, 19984, 
+    19980,     0, 16384, 20480, 20481, 19968, 19984, 19980, 
+        0, 16384, 20480, 20481, 19968, 19984, 19985, 19982, 
+        0, 16384, 20480, 20481, 19968,     0, 16384, 20480, 
+    20481, 19968, 19984,     0, 16384, 20480, 20481, 19968, 
+    19984,     0, 16384, 20480, 20481, 19968, 19984, 19986, 
+        0, 16384, 20480, 20481, 19968, 19984,     0, 16384, 
+    20480, 20481, 19968, 19984, 19988,     0, 16384, 20480, 
+    20481, 19968, 19984, 19988,     0, 16384, 20480, 20481, 
+    19968, 19984, 19992, 19990,     0, 16384, 20480, 20481, 
+    19968, 19984,     0, 16384, 20480, 20481, 19968, 20000, 
+    19992,     0, 16384, 20480, 20481, 19968, 20000, 19992, 
+        0, 16384, 20480, 20481, 19968, 20000, 19992, 19994, 
+        0, 16384, 20480, 20481, 19968, 20000, 19992,     0, 
+    16384, 20480, 20481, 19968, 20000, 20001, 19996,     0, 
+    16384, 20480, 20481, 19968, 20000, 20001, 19996,     0, 
+    16384, 20480, 20481, 19968, 20000, 20001, 19996, 19998, 
+        0, 16384, 20480, 20481, 19968,     0, 16384, 20480, 
+    20481, 19968, 20000,     0, 16384, 20480, 20481, 19968, 
+    20000,     0, 16384, 20480, 20481, 19968, 20000, 20002, 
+        0, 16384, 20480, 20481, 19968, 20000,     0, 16384, 
+    20480, 20481, 19968, 20000, 20004,     0, 16384, 20480, 
+    20481, 19968, 20000, 20004,     0, 16384, 20480, 20481, 
+    19968, 20000, 20008, 20006,     0, 16384, 20480, 20481, 
+    19968, 20000,     0, 16384, 20480, 20481, 19968, 20000, 
+    20008,     0, 16384, 20480, 20481, 19968, 20000, 20008, 
+        0, 16384, 20480, 20481, 19968, 20000, 20008, 20010, 
+        0, 16384, 20480, 20481, 19968, 20000, 20008,     0, 
+    16384, 20480, 20481, 19968, 20000, 20016, 20012,     0, 
+    16384, 20480, 20481, 19968, 20000, 20016, 20012,     0, 
+    16384, 20480, 20481, 19968, 20000, 20016, 20017, 20014, 
+        0, 16384, 20480, 20481, 19968, 20000,     0, 16384, 
+    20480, 20481, 19968, 20032, 20016,     0, 16384, 20480, 
+    20481, 19968, 20032, 20016,     0, 16384, 20480, 20481, 
+    19968, 20032, 20016, 20018,     0, 16384, 20480, 20481, 
+    19968, 20032, 20016,     0, 16384, 20480, 20481, 19968, 
+    20032, 20016, 20020,     0, 16384, 20480, 20481, 19968, 
+    20032, 20016, 20020,     0, 16384, 20480, 20481, 19968, 
+    20032, 20016, 20024, 20022,     0, 16384, 20480, 20481, 
+    19968, 20032, 20016,     0, 16384, 20480, 20481, 19968, 
+    20032, 20033, 20024,     0, 16384, 20480, 20481, 19968, 
+    20032, 20033, 20024,     0, 16384, 20480, 20481, 19968, 
+    20032, 20033, 20024, 20026,     0, 16384, 20480, 20481, 
+    19968, 20032, 20033, 20024,     0, 16384, 20480, 20481, 
+    19968, 20032, 20033, 20024, 20028,     0, 16384, 20480, 
+    20481, 19968, 20032, 20033, 20035, 20028,     0, 16384, 
+    20480, 20481, 19968, 20032, 20033, 20035, 20028, 20030, 
+        0, 16384, 20480, 20481, 19968,     0, 16384, 20480, 
+    20481, 19968, 20032,     0, 16384, 20480, 20481, 19968, 
+    20032,     0, 16384, 20480, 20481, 19968, 20032, 20034, 
+        0, 16384, 20480, 20481, 19968, 20032,     0, 16384, 
+    20480, 20481, 19968, 20032, 20036,     0, 16384, 20480, 
+    20481, 19968, 20032, 20036,     0, 16384, 20480, 20481, 
+    19968, 20032, 20040, 20038,     0, 16384, 20480, 20481, 
+    19968, 20032,     0, 16384, 20480, 20481, 19968, 20032, 
+    20040,     0, 16384, 20480, 20481, 19968, 20032, 20040, 
+        0, 16384, 20480, 20481, 19968, 20032, 20040, 20042, 
+        0, 16384, 20480, 20481, 19968, 20032, 20040,     0, 
+    16384, 20480, 20481, 19968, 20032, 20048, 20044,     0, 
+    16384, 20480, 20481, 19968, 20032, 20048, 20044,     0, 
+    16384, 20480, 20481, 19968, 20032, 20048, 20049, 20046, 
+        0, 16384, 20480, 20481, 19968, 20032,     0, 16384, 
+    20480, 20481, 19968, 20032, 20048,     0, 16384, 20480, 
+    20481, 19968, 20032, 20048,     0, 16384, 20480, 20481, 
+    19968, 20032, 20048, 20050,     0, 16384, 20480, 20481, 
+    19968, 20032, 20048,     0, 16384, 20480, 20481, 19968, 
+    20032, 20048, 20052,     0, 16384, 20480, 20481, 19968, 
+    20032, 20048, 20052,     0, 16384, 20480, 20481, 19968, 
+    20032, 20048, 20056, 20054,     0, 16384, 20480, 20481, 
+    19968, 20032, 20048,     0, 16384, 20480, 20481, 19968, 
+    20032, 20064, 20056,     0, 16384, 20480, 20481, 19968, 
+    20032, 20064, 20056,     0, 16384, 20480, 20481, 19968, 
+    20032, 20064, 20056, 20058,     0, 16384, 20480, 20481, 
+    19968, 20032, 20064, 20056,     0, 16384, 20480, 20481, 
+    19968, 20032, 20064, 20065, 20060,     0, 16384, 20480, 
+    20481, 19968, 20032, 20064, 20065, 20060,     0, 16384, 
+    20480, 20481, 19968, 20032, 20064, 20065, 20060, 20062, 
+        0, 16384, 20480, 20481, 19968, 20032,     0, 16384, 
+    20480, 20481, 19968, 20096, 20064,     0, 16384, 20480, 
+    20481, 19968, 20096, 20064,     0, 16384, 20480, 20481, 
+    19968, 20096, 20064, 20066,     0, 16384, 20480, 20481, 
+    19968, 20096, 20064,     0, 16384, 20480, 20481, 19968, 
+    20096, 20064, 20068,     0, 16384, 20480, 20481, 19968, 
+    20096, 20064, 20068,     0, 16384, 20480, 20481, 19968, 
+    20096, 20064, 20072, 20070,     0, 16384, 20480, 20481, 
+    19968, 20096, 20064,     0, 16384, 20480, 20481, 19968, 
+    20096, 20064, 20072,     0, 16384, 20480, 20481, 19968, 
+    20096, 20064, 20072,     0, 16384, 20480, 20481, 19968, 
+    20096, 20064, 20072, 20074,     0, 16384, 20480, 20481, 
+    19968, 20096, 20064, 20072,     0, 16384, 20480, 20481, 
+    19968, 20096, 20064, 20080, 20076,     0, 16384, 20480, 
+    20481, 19968, 20096, 20064, 20080, 20076,     0, 16384, 
+    20480, 20481, 19968, 20096, 20064, 20080, 20081, 20078, 
+        0, 16384, 20480, 20481, 19968, 20096, 20064,     0, 
+    16384, 20480, 20481, 19968, 20096, 20097, 20080,     0, 
+    16384, 20480, 20481, 19968, 20096, 20097, 20080,     0, 
+    16384, 20480, 20481, 19968, 20096, 20097, 20080, 20082, 
+        0, 16384, 20480, 20481, 19968, 20096, 20097, 20080, 
+        0, 16384, 20480, 20481, 19968, 20096, 20097, 20080, 
+    20084,     0, 16384, 20480, 20481, 19968, 20096, 20097, 
+    20080, 20084,     0, 16384, 20480, 20481, 19968, 20096, 
+    20097, 20080, 20088, 20086,     0, 16384, 20480, 20481, 
+    19968, 20096, 20097, 20080,     0, 16384, 20480, 20481, 
+    19968, 20096, 20097, 20080, 20088,     0, 16384, 20480, 
+    20481, 19968, 20096, 20097, 20099, 20088,     0, 16384, 
+    20480, 20481, 19968, 20096, 20097, 20099, 20088, 20090, 
+        0, 16384, 20480, 20481, 19968, 20096, 20097, 20099, 
+    20088,     0, 16384, 20480, 20481, 19968, 20096, 20097, 
+    20099, 20088, 20092,     0, 16384, 20480, 20481, 19968, 
+    20096, 20097, 20099, 20088, 20092,     0, 16384, 20480, 
+    20481, 19968, 20096, 20097, 20099, 20088, 20092, 20094, 
+        0, 16384, 20480, 20481, 19968,     0, 16384, 20480, 
+    20481, 19968, 20096,     0, 16384, 20480, 20481, 19968, 
+    20096,     0, 16384, 20480, 20481, 19968, 20096, 20098, 
+        0, 16384, 20480, 20481, 19968, 20096,     0, 16384, 
+    20480, 20481, 19968, 20096, 20100,     0, 16384, 20480, 
+    20481, 19968, 20096, 20100,     0, 16384, 20480, 20481, 
+    19968, 20096, 20104, 20102,     0, 16384, 20480, 20481, 
+    19968, 20096,     0, 16384, 20480, 20481, 19968, 20096, 
+    20104,     0, 16384, 20480, 20481, 19968, 20096, 20104, 
+        0, 16384, 20480, 20481, 19968, 20096, 20104, 20106, 
+        0, 16384, 20480, 20481, 19968, 20096, 20104,     0, 
+    16384, 20480, 20481, 19968, 20096, 20112, 20108,     0, 
+    16384, 20480, 20481, 19968, 20096, 20112, 20108,     0, 
+    16384, 20480, 20481, 19968, 20096, 20112, 20113, 20110, 
+        0, 16384, 20480, 20481, 19968, 20096,     0, 16384, 
+    20480, 20481, 19968, 20096, 20112,     0, 16384, 20480, 
+    20481, 19968, 20096, 20112,     0, 16384, 20480, 20481, 
+    19968, 20096, 20112, 20114,     0, 16384, 20480, 20481, 
+    19968, 20096, 20112,     0, 16384, 20480, 20481, 19968, 
+    20096, 20112, 20116,     0, 16384, 20480, 20481, 19968, 
+    20096, 20112, 20116,     0, 16384, 20480, 20481, 19968, 
+    20096, 20112, 20120, 20118,     0, 16384, 20480, 20481, 
+    19968, 20096, 20112,     0, 16384, 20480, 20481, 19968, 
+    20096, 20128, 20120,     0, 16384, 20480, 20481, 19968, 
+    20096, 20128, 20120,     0, 16384, 20480, 20481, 19968, 
+    20096, 20128, 20120, 20122,     0, 16384, 20480, 20481, 
+    19968, 20096, 20128, 20120,     0, 16384, 20480, 20481, 
+    19968, 20096, 20128, 20129, 20124,     0, 16384, 20480, 
+    20481, 19968, 20096, 20128, 20129, 20124,     0, 16384, 
+    20480, 20481, 19968, 20096, 20128, 20129, 20124, 20126, 
+        0, 16384, 20480, 20481, 19968, 20096,     0, 16384, 
+    20480, 20481, 19968, 20096, 20128,     0, 16384, 20480, 
+    20481, 19968, 20096, 20128,     0, 16384, 20480, 20481, 
+    19968, 20096, 20128, 20130,     0, 16384, 20480, 20481, 
+    19968, 20096, 20128,     0, 16384, 20480, 20481, 19968, 
+    20096, 20128, 20132,     0, 16384, 20480, 20481, 19968, 
+    20096, 20128, 20132,     0, 16384, 20480, 20481, 19968, 
+    20096, 20128, 20136, 20134,     0, 16384, 20480, 20481, 
+    19968, 20096, 20128,     0, 16384, 20480, 20481, 19968, 
+    20096, 20128, 20136,     0, 16384, 20480, 20481, 19968, 
+    20096, 20128, 20136,     0, 16384, 20480, 20481, 19968, 
+    20096, 20128, 20136, 20138,     0, 16384, 20480, 20481, 
+    19968, 20096, 20128, 20136,     0, 16384, 20480, 20481, 
+    19968, 20096, 20128, 20144, 20140,     0, 16384, 20480, 
+    20481, 19968, 20096, 20128, 20144, 20140,     0, 16384, 
+    20480, 20481, 19968, 20096, 20128, 20144, 20145, 20142, 
+        0, 16384, 20480, 20481, 19968, 20096, 20128,     0, 
+    16384, 20480, 20481, 19968, 20096, 20160, 20144,     0, 
+    16384, 20480, 20481, 19968, 20096, 20160, 20144,     0, 
+    16384, 20480, 20481, 19968, 20096, 20160, 20144, 20146, 
+        0, 16384, 20480, 20481, 19968, 20096, 20160, 20144, 
+        0, 16384, 20480, 20481, 19968, 20096, 20160, 20144, 
+    20148,     0, 16384, 20480, 20481, 19968, 20096, 20160, 
+    20144, 20148,     0, 16384, 20480, 20481, 19968, 20096, 
+    20160, 20144, 20152, 20150,     0, 16384, 20480, 20481, 
+    19968, 20096, 20160, 20144,     0, 16384, 20480, 20481, 
+    19968, 20096, 20160, 20161, 20152,     0, 16384, 20480, 
+    20481, 19968, 20096, 20160, 20161, 20152,     0, 16384, 
+    20480, 20481, 19968, 20096, 20160, 20161, 20152, 20154, 
+        0, 16384, 20480, 20481, 19968, 20096, 20160, 20161, 
+    20152,     0, 16384, 20480, 20481, 19968, 20096, 20160, 
+    20161, 20152, 20156,     0, 16384, 20480, 20481, 19968, 
+    20096, 20160, 20161, 20163, 20156,     0, 16384, 20480, 
+    20481, 19968, 20096, 20160, 20161, 20163, 20156, 20158, 
+        0, 16384, 20480, 20481, 19968, 20096,     0, 16384, 
+    20480, 20481, 19968, 20224, 20160,     0, 16384, 20480, 
+    20481, 19968, 20224, 20160,     0, 16384, 20480, 20481, 
+    19968, 20224, 20160, 20162,     0, 16384, 20480, 20481, 
+    19968, 20224, 20160,     0, 16384, 20480, 20481, 19968, 
+    20224, 20160, 20164,     0, 16384, 20480, 20481, 19968, 
+    20224, 20160, 20164,     0, 16384, 20480, 20481, 19968, 
+    20224, 20160, 20168, 20166,     0, 16384, 20480, 20481, 
+    19968, 20224, 20160,     0, 16384, 20480, 20481, 19968, 
+    20224, 20160, 20168,     0, 16384, 20480, 20481, 19968, 
+    20224, 20160, 20168,     0, 16384, 20480, 20481, 19968, 
+    20224, 20160, 20168, 20170,     0, 16384, 20480, 20481, 
+    19968, 20224, 20160, 20168,     0, 16384, 20480, 20481, 
+    19968, 20224, 20160, 20176, 20172,     0, 16384, 20480, 
+    20481, 19968, 20224, 20160, 20176, 20172,     0, 16384, 
+    20480, 20481, 19968, 20224, 20160, 20176, 20177, 20174, 
+        0, 16384, 20480, 20481, 19968, 20224, 20160,     0, 
+    16384, 20480, 20481, 19968, 20224, 20160, 20176,     0, 
+    16384, 20480, 20481, 19968, 20224, 20160, 20176,     0, 
+    16384, 20480, 20481, 19968, 20224, 20160, 20176, 20178, 
+        0, 16384, 20480, 20481, 19968, 20224, 20160, 20176, 
+        0, 16384, 20480, 20481, 19968, 20224, 20160, 20176, 
+    20180,     0, 16384, 20480, 20481, 19968, 20224, 20160, 
+    20176, 20180,     0, 16384, 20480, 20481, 19968, 20224, 
+    20160, 20176, 20184, 20182,     0, 16384, 20480, 20481, 
+    19968, 20224, 20160, 20176,     0, 16384, 20480, 20481, 
+    19968, 20224, 20160, 20192, 20184,     0, 16384, 20480, 
+    20481, 19968, 20224, 20160, 20192, 20184,     0, 16384, 
+    20480, 20481, 19968, 20224, 20160, 20192, 20184, 20186, 
+        0, 16384, 20480, 20481, 19968, 20224, 20160, 20192, 
+    20184,     0, 16384, 20480, 20481, 19968, 20224, 20160, 
+    20192, 20193, 20188,     0, 16384, 20480, 20481, 19968, 
+    20224, 20160, 20192, 20193, 20188,     0, 16384, 20480, 
+    20481, 19968, 20224, 20160, 20192, 20193, 20188, 20190, 
+        0, 16384, 20480, 20481, 19968, 20224, 20160,     0, 
+    16384, 20480, 20481, 19968, 20224, 20225, 20192,     0, 
+    16384, 20480, 20481, 19968, 20224, 20225, 20192,     0, 
+    16384, 20480, 20481, 19968, 20224, 20225, 20192, 20194, 
+        0, 16384, 20480, 20481, 19968, 20224, 20225, 20192, 
+        0, 16384, 20480, 20481, 19968, 20224, 20225, 20192, 
+    20196,     0, 16384, 20480, 20481, 19968, 20224, 20225, 
+    20192, 20196,     0, 16384, 20480, 20481, 19968, 20224, 
+    20225, 20192, 20200, 20198,     0, 16384, 20480, 20481, 
+    19968, 20224, 20225, 20192,     0, 16384, 20480, 20481, 
+    19968, 20224, 20225, 20192, 20200,     0, 16384, 20480, 
+    20481, 19968, 20224, 20225, 20192, 20200,     0, 16384, 
+    20480, 20481, 19968, 20224, 20225, 20192, 20200, 20202, 
+        0, 16384, 20480, 20481, 19968, 20224, 20225, 20192, 
+    20200,     0, 16384, 20480, 20481, 19968, 20224, 20225, 
+    20192, 20208, 20204,     0, 16384, 20480, 20481, 19968, 
+    20224, 20225, 20192, 20208, 20204,     0, 16384, 20480, 
+    20481, 19968, 20224, 20225, 20192, 20208, 20209, 20206, 
+        0, 16384, 20480, 20481, 19968, 20224, 20225, 20192, 
+        0, 16384, 20480, 20481, 19968, 20224, 20225, 20192, 
+    20208,     0, 16384, 20480, 20481, 19968, 20224, 20225, 
+    20227, 20208,     0, 16384, 20480, 20481, 19968, 20224, 
+    20225, 20227, 20208, 20210,     0, 16384, 20480, 20481, 
+    19968, 20224, 20225, 20227, 20208,     0, 16384, 20480, 
+    20481, 19968, 20224, 20225, 20227, 20208, 20212,     0, 
+    16384, 20480, 20481, 19968, 20224, 20225, 20227, 20208, 
+    20212,     0, 16384, 20480, 20481, 19968, 20224, 20225, 
+    20227, 20208, 20216, 20214,     0, 16384, 20480, 20481, 
+    19968, 20224, 20225, 20227, 20208,     0, 16384, 20480, 
+    20481, 19968, 20224, 20225, 20227, 20208, 20216,     0, 
+    16384, 20480, 20481, 19968, 20224, 20225, 20227, 20208, 
+    20216,     0, 16384, 20480, 20481, 19968, 20224, 20225, 
+    20227, 20208, 20216, 20218,     0, 16384, 20480, 20481, 
+    19968, 20224, 20225, 20227, 20231, 20216,     0, 16384, 
+    20480, 20481, 19968, 20224, 20225, 20227, 20231, 20216, 
+    20220,     0, 16384, 20480, 20481, 19968, 20224, 20225, 
+    20227, 20231, 20216, 20220,     0, 16384, 20480, 20481, 
+    19968, 20224, 20225, 20227, 20231, 20216, 20220, 20222, 
+        0, 16384, 20480, 20481, 19968,     0, 16384, 20480, 
+    20481, 19968, 20224,     0, 16384, 20480, 20481, 19968, 
+    20224,     0, 16384, 20480, 20481, 19968, 20224, 20226, 
+        0, 16384, 20480, 20481, 20483, 20224,     0, 16384, 
+    20480, 20481, 20483, 20224, 20228,     0, 16384, 20480, 
+    20481, 20483, 20224, 20228,     0, 16384, 20480, 20481, 
+    20483, 20224, 20232, 20230,     0, 16384, 20480, 20481, 
+    20483, 20224,     0, 16384, 20480, 20481, 20483, 20224, 
+    20232,     0, 16384, 20480, 20481, 20483, 20224, 20232, 
+        0, 16384, 20480, 20481, 20483, 20224, 20232, 20234, 
+        0, 16384, 20480, 20481, 20483, 20224, 20232,     0, 
+    16384, 20480, 20481, 20483, 20224, 20240, 20236,     0, 
+    16384, 20480, 20481, 20483, 20224, 20240, 20236,     0, 
+    16384, 20480, 20481, 20483, 20224, 20240, 20241, 20238, 
+        0, 16384, 20480, 20481, 20483, 20224,     0, 16384, 
+    20480, 20481, 20483, 20224, 20240,     0, 16384, 20480, 
+    20481, 20483, 20224, 20240,     0, 16384, 20480, 20481, 
+    20483, 20224, 20240, 20242,     0, 16384, 20480, 20481, 
+    20483, 20224, 20240,     0, 16384, 20480, 20481, 20483, 
+    20224, 20240, 20244,     0, 16384, 20480, 20481, 20483, 
+    20224, 20240, 20244,     0, 16384, 20480, 20481, 20483, 
+    20224, 20240, 20248, 20246,     0, 16384, 20480, 20481, 
+    20483, 20224, 20240,     0, 16384, 20480, 20481, 20483, 
+    20224, 20256, 20248,     0, 16384, 20480, 20481, 20483, 
+    20224, 20256, 20248,     0, 16384, 20480, 20481, 20483, 
+    20224, 20256, 20248, 20250,     0, 16384, 20480, 20481, 
+    20483, 20224, 20256, 20248,     0, 16384, 20480, 20481, 
+    20483, 20224, 20256, 20257, 20252,     0, 16384, 20480, 
+    20481, 20483, 20224, 20256, 20257, 20252,     0, 16384, 
+    20480, 20481, 20483, 20224, 20256, 20257, 20252, 20254, 
+        0, 16384, 20480, 20481, 20483, 20224,     0, 16384, 
+    20480, 20481, 20483, 20224, 20256,     0, 16384, 20480, 
+    20481, 20483, 20224, 20256,     0, 16384, 20480, 20481, 
+    20483, 20224, 20256, 20258,     0, 16384, 20480, 20481, 
+    20483, 20224, 20256,     0, 16384, 20480, 20481, 20483, 
+    20224, 20256, 20260,     0, 16384, 20480, 20481, 20483, 
+    20224, 20256, 20260,     0, 16384, 20480, 20481, 20483, 
+    20224, 20256, 20264, 20262,     0, 16384, 20480, 20481, 
+    20483, 20224, 20256,     0, 16384, 20480, 20481, 20483, 
+    20224, 20256, 20264,     0, 16384, 20480, 20481, 20483, 
+    20224, 20256, 20264,     0, 16384, 20480, 20481, 20483, 
+    20224, 20256, 20264, 20266,     0, 16384, 20480, 20481, 
+    20483, 20224, 20256, 20264,     0, 16384, 20480, 20481, 
+    20483, 20224, 20256, 20272, 20268,     0, 16384, 20480, 
+    20481, 20483, 20224, 20256, 20272, 20268,     0, 16384, 
+    20480, 20481, 20483, 20224, 20256, 20272, 20273, 20270, 
+        0, 16384, 20480, 20481, 20483, 20224, 20256,     0, 
+    16384, 20480, 20481, 20483, 20224, 20288, 20272,     0, 
+    16384, 20480, 20481, 20483, 20224, 20288, 20272,     0, 
+    16384, 20480, 20481, 20483, 20224, 20288, 20272, 20274, 
+        0, 16384, 20480, 20481, 20483, 20224, 20288, 20272, 
+        0, 16384, 20480, 20481, 20483, 20224, 20288, 20272, 
+    20276,     0, 16384, 20480, 20481, 20483, 20224, 20288, 
+    20272, 20276,     0, 16384, 20480, 20481, 20483, 20224, 
+    20288, 20272, 20280, 20278,     0, 16384, 20480, 20481, 
+    20483, 20224, 20288, 20272,     0, 16384, 20480, 20481, 
+    20483, 20224, 20288, 20289, 20280,     0, 16384, 20480, 
+    20481, 20483, 20224, 20288, 20289, 20280,     0, 16384, 
+    20480, 20481, 20483, 20224, 20288, 20289, 20280, 20282, 
+        0, 16384, 20480, 20481, 20483, 20224, 20288, 20289, 
+    20280,     0, 16384, 20480, 20481, 20483, 20224, 20288, 
+    20289, 20280, 20284,     0, 16384, 20480, 20481, 20483, 
+    20224, 20288, 20289, 20291, 20284,     0, 16384, 20480, 
+    20481, 20483, 20224, 20288, 20289, 20291, 20284, 20286, 
+        0, 16384, 20480, 20481, 20483, 20224,     0, 16384, 
+    20480, 20481, 20483, 20224, 20288,     0, 16384, 20480, 
+    20481, 20483, 20224, 20288,     0, 16384, 20480, 20481, 
+    20483, 20224, 20288, 20290,     0, 16384, 20480, 20481, 
+    20483, 20224, 20288,     0, 16384, 20480, 20481, 20483, 
+    20224, 20288, 20292,     0, 16384, 20480, 20481, 20483, 
+    20224, 20288, 20292,     0, 16384, 20480, 20481, 20483, 
+    20224, 20288, 20296, 20294,     0, 16384, 20480, 20481, 
+    20483, 20224, 20288,     0, 16384, 20480, 20481, 20483, 
+    20224, 20288, 20296,     0, 16384, 20480, 20481, 20483, 
+    20224, 20288, 20296,     0, 16384, 20480, 20481, 20483, 
+    20224, 20288, 20296, 20298,     0, 16384, 20480, 20481, 
+    20483, 20224, 20288, 20296,     0, 16384, 20480, 20481, 
+    20483, 20224, 20288, 20304, 20300,     0, 16384, 20480, 
+    20481, 20483, 20224, 20288, 20304, 20300,     0, 16384, 
+    20480, 20481, 20483, 20224, 20288, 20304, 20305, 20302, 
+        0, 16384, 20480, 20481, 20483, 20224, 20288,     0, 
+    16384, 20480, 20481, 20483, 20224, 20288, 20304,     0, 
+    16384, 20480, 20481, 20483, 20224, 20288, 20304,     0, 
+    16384, 20480, 20481, 20483, 20224, 20288, 20304, 20306, 
+        0, 16384, 20480, 20481, 20483, 20224, 20288, 20304, 
+        0, 16384, 20480, 20481, 20483, 20224, 20288, 20304, 
+    20308,     0, 16384, 20480, 20481, 20483, 20224, 20288, 
+    20304, 20308,     0, 16384, 20480, 20481, 20483, 20224, 
+    20288, 20304, 20312, 20310,     0, 16384, 20480, 20481, 
+    20483, 20224, 20288, 20304,     0, 16384, 20480, 20481, 
+    20483, 20224, 20288, 20320, 20312,     0, 16384, 20480, 
+    20481, 20483, 20224, 20288, 20320, 20312,     0, 16384, 
+    20480, 20481, 20483, 20224, 20288, 20320, 20312, 20314, 
+        0, 16384, 20480, 20481, 20483, 20224, 20288, 20320, 
+    20312,     0, 16384, 20480, 20481, 20483, 20224, 20288, 
+    20320, 20321, 20316,     0, 16384, 20480, 20481, 20483, 
+    20224, 20288, 20320, 20321, 20316,     0, 16384, 20480, 
+    20481, 20483, 20224, 20288, 20320, 20321, 20316, 20318, 
+        0, 16384, 20480, 20481, 20483, 20224, 20288,     0, 
+    16384, 20480, 20481, 20483, 20224, 20352, 20320,     0, 
+    16384, 20480, 20481, 20483, 20224, 20352, 20320,     0, 
+    16384, 20480, 20481, 20483, 20224, 20352, 20320, 20322, 
+        0, 16384, 20480, 20481, 20483, 20224, 20352, 20320, 
+        0, 16384, 20480, 20481, 20483, 20224, 20352, 20320, 
+    20324,     0, 16384, 20480, 20481, 20483, 20224, 20352, 
+    20320, 20324,     0, 16384, 20480, 20481, 20483, 20224, 
+    20352, 20320, 20328, 20326,     0, 16384, 20480, 20481, 
+    20483, 20224, 20352, 20320,     0, 16384, 20480, 20481, 
+    20483, 20224, 20352, 20320, 20328,     0, 16384, 20480, 
+    20481, 20483, 20224, 20352, 20320, 20328,     0, 16384, 
+    20480, 20481, 20483, 20224, 20352, 20320, 20328, 20330, 
+        0, 16384, 20480, 20481, 20483, 20224, 20352, 20320, 
+    20328,     0, 16384, 20480, 20481, 20483, 20224, 20352, 
+    20320, 20336, 20332,     0, 16384, 20480, 20481, 20483, 
+    20224, 20352, 20320, 20336, 20332,     0, 16384, 20480, 
+    20481, 20483, 20224, 20352, 20320, 20336, 20337, 20334, 
+        0, 16384, 20480, 20481, 20483, 20224, 20352, 20320, 
+        0, 16384, 20480, 20481, 20483, 20224, 20352, 20353, 
+    20336,     0, 16384, 20480, 20481, 20483, 20224, 20352, 
+    20353, 20336,     0, 16384, 20480, 20481, 20483, 20224, 
+    20352, 20353, 20336, 20338,     0, 16384, 20480, 20481, 
+    20483, 20224, 20352, 20353, 20336,     0, 16384, 20480, 
+    20481, 20483, 20224, 20352, 20353, 20336, 20340,     0, 
+    16384, 20480, 20481, 20483, 20224, 20352, 20353, 20336, 
+    20340,     0, 16384, 20480, 20481, 20483, 20224, 20352, 
+    20353, 20336, 20344, 20342,     0, 16384, 20480, 20481, 
+    20483, 20224, 20352, 20353, 20336,     0, 16384, 20480, 
+    20481, 20483, 20224, 20352, 20353, 20336, 20344,     0, 
+    16384, 20480, 20481, 20483, 20224, 20352, 20353, 20355, 
+    20344,     0, 16384, 20480, 20481, 20483, 20224, 20352, 
+    20353, 20355, 20344, 20346,     0, 16384, 20480, 20481, 
+    20483, 20224, 20352, 20353, 20355, 20344,     0, 16384, 
+    20480, 20481, 20483, 20224, 20352, 20353, 20355, 20344, 
+    20348,     0, 16384, 20480, 20481, 20483, 20224, 20352, 
+    20353, 20355, 20344, 20348,     0, 16384, 20480, 20481, 
+    20483, 20224, 20352, 20353, 20355, 20344, 20348, 20350, 
+        0, 16384, 20480, 20481, 20483, 20224,     0, 16384, 
+    20480, 20481, 20483, 20224, 20352,     0, 16384, 20480, 
+    20481, 20483, 20224, 20352,     0, 16384, 20480, 20481, 
+    20483, 20224, 20352, 20354,     0, 16384, 20480, 20481, 
+    20483, 20224, 20352,     0, 16384, 20480, 20481, 20483, 
+    20224, 20352, 20356,     0, 16384, 20480, 20481, 20483, 
+    20224, 20352, 20356,     0, 16384, 20480, 20481, 20483, 
+    20224, 20352, 20360, 20358,     0, 16384, 20480, 20481, 
+    20483, 20487, 20352,     0, 16384, 20480, 20481, 20483, 
+    20487, 20352, 20360,     0, 16384, 20480, 20481, 20483, 
+    20487, 20352, 20360,     0, 16384, 20480, 20481, 20483, 
+    20487, 20352, 20360, 20362,     0, 16384, 20480, 20481, 
+    20483, 20487, 20352, 20360,     0, 16384, 20480, 20481, 
+    20483, 20487, 20352, 20368, 20364,     0, 16384, 20480, 
+    20481, 20483, 20487, 20352, 20368, 20364,     0, 16384, 
+    20480, 20481, 20483, 20487, 20352, 20368, 20369, 20366, 
+        0, 16384, 20480, 20481, 20483, 20487, 20352,     0, 
+    16384, 20480, 20481, 20483, 20487, 20352, 20368,     0, 
+    16384, 20480, 20481, 20483, 20487, 20352, 20368,     0, 
+    16384, 20480, 20481, 20483, 20487, 20352, 20368, 20370, 
+        0, 16384, 20480, 20481, 20483, 20487, 20352, 20368, 
+        0, 16384, 20480, 20481, 20483, 20487, 20352, 20368, 
+    20372,     0, 16384, 20480, 20481, 20483, 20487, 20352, 
+    20368, 20372,     0, 16384, 20480, 20481, 20483, 20487, 
+    20352, 20368, 20376, 20374,     0, 16384, 20480, 20481, 
+    20483, 20487, 20352, 20368,     0, 16384, 20480, 20481, 
+    20483, 20487, 20352, 20384, 20376,     0, 16384, 20480, 
+    20481, 20483, 20487, 20352, 20384, 20376,     0, 16384, 
+    20480, 20481, 20483, 20487, 20352, 20384, 20376, 20378, 
+        0, 16384, 20480, 20481, 20483, 20487, 20352, 20384, 
+    20376,     0, 16384, 20480, 20481, 20483, 20487, 20352, 
+    20384, 20385, 20380,     0, 16384, 20480, 20481, 20483, 
+    20487, 20352, 20384, 20385, 20380,     0, 16384, 20480, 
+    20481, 20483, 20487, 20352, 20384, 20385, 20380, 20382, 
+        0, 16384, 20480, 20481, 20483, 20487, 20352,     0, 
+    16384, 20480, 20481, 20483, 20487, 20352, 20384,     0, 
+    16384, 20480, 20481, 20483, 20487, 20352, 20384,     0, 
+    16384, 20480, 20481, 20483, 20487, 20352, 20384, 20386, 
+        0, 16384, 20480, 20481, 20483, 20487, 20352, 20384, 
+        0, 16384, 20480, 20481, 20483, 20487, 20352, 20384, 
+    20388,     0, 16384, 20480, 20481, 20483, 20487, 20352, 
+    20384, 20388,     0, 16384, 20480, 20481, 20483, 20487, 
+    20352, 20384, 20392, 20390,     0, 16384, 20480, 20481, 
+    20483, 20487, 20352, 20384,     0, 16384, 20480, 20481, 
+    20483, 20487, 20352, 20384, 20392,     0, 16384, 20480, 
+    20481, 20483, 20487, 20352, 20384, 20392,     0, 16384, 
+    20480, 20481, 20483, 20487, 20352, 20384, 20392, 20394, 
+        0, 16384, 20480, 20481, 20483, 20487, 20352, 20384, 
+    20392,     0, 16384, 20480, 20481, 20483, 20487, 20352, 
+    20384, 20400, 20396,     0, 16384, 20480, 20481, 20483, 
+    20487, 20352, 20384, 20400, 20396,     0, 16384, 20480, 
+    20481, 20483, 20487, 20352, 20384, 20400, 20401, 20398, 
+        0, 16384, 20480, 20481, 20483, 20487, 20352, 20384, 
+        0, 16384, 20480, 20481, 20483, 20487, 20352, 20416, 
+    20400,     0, 16384, 20480, 20481, 20483, 20487, 20352, 
+    20416, 20400,     0, 16384, 20480, 20481, 20483, 20487, 
+    20352, 20416, 20400, 20402,     0, 16384, 20480, 20481, 
+    20483, 20487, 20352, 20416, 20400,     0, 16384, 20480, 
+    20481, 20483, 20487, 20352, 20416, 20400, 20404,     0, 
+    16384, 20480, 20481, 20483, 20487, 20352, 20416, 20400, 
+    20404,     0, 16384, 20480, 20481, 20483, 20487, 20352, 
+    20416, 20400, 20408, 20406,     0, 16384, 20480, 20481, 
+    20483, 20487, 20352, 20416, 20400,     0, 16384, 20480, 
+    20481, 20483, 20487, 20352, 20416, 20417, 20408,     0, 
+    16384, 20480, 20481, 20483, 20487, 20352, 20416, 20417, 
+    20408,     0, 16384, 20480, 20481, 20483, 20487, 20352, 
+    20416, 20417, 20408, 20410,     0, 16384, 20480, 20481, 
+    20483, 20487, 20352, 20416, 20417, 20408,     0, 16384, 
+    20480, 20481, 20483, 20487, 20352, 20416, 20417, 20408, 
+    20412,     0, 16384, 20480, 20481, 20483, 20487, 20352, 
+    20416, 20417, 20419, 20412,     0, 16384, 20480, 20481, 
+    20483, 20487, 20352, 20416, 20417, 20419, 20412, 20414, 
+        0, 16384, 20480, 20481, 20483, 20487, 20352,     0, 
+    16384, 20480, 20481, 20483, 20487, 20352, 20416,     0, 
+    16384, 20480, 20481, 20483, 20487, 20352, 20416,     0, 
+    16384, 20480, 20481, 20483, 20487, 20352, 20416, 20418, 
+        0, 16384, 20480, 20481, 20483, 20487, 20352, 20416, 
+        0, 16384, 20480, 20481, 20483, 20487, 20352, 20416, 
+    20420,     0, 16384, 20480, 20481, 20483, 20487, 20352, 
+    20416, 20420,     0, 16384, 20480, 20481, 20483, 20487, 
+    20352, 20416, 20424, 20422,     0, 16384, 20480, 20481, 
+    20483, 20487, 20352, 20416,     0, 16384, 20480, 20481, 
+    20483, 20487, 20352, 20416, 20424,     0, 16384, 20480, 
+    20481, 20483, 20487, 20352, 20416, 20424,     0, 16384, 
+    20480, 20481, 20483, 20487, 20352, 20416, 20424, 20426, 
+        0, 16384, 20480, 20481, 20483, 20487, 20352, 20416, 
+    20424,     0, 16384, 20480, 20481, 20483, 20487, 20352, 
+    20416, 20432, 20428,     0, 16384, 20480, 20481, 20483, 
+    20487, 20352, 20416, 20432, 20428,     0, 16384, 20480, 
+    20481, 20483, 20487, 20352, 20416, 20432, 20433, 20430, 
+        0, 16384, 20480, 20481, 20483, 20487, 20495, 20416, 
+        0, 16384, 20480, 20481, 20483, 20487, 20495, 20416, 
+    20432,     0, 16384, 20480, 20481, 20483, 20487, 20495, 
+    20416, 20432,     0, 16384, 20480, 20481, 20483, 20487, 
+    20495, 20416, 20432, 20434,     0, 16384, 20480, 20481, 
+    20483, 20487, 20495, 20416, 20432,     0, 16384, 20480, 
+    20481, 20483, 20487, 20495, 20416, 20432, 20436,     0, 
+    16384, 20480, 20481, 20483, 20487, 20495, 20416, 20432, 
+    20436,     0, 16384, 20480, 20481, 20483, 20487, 20495, 
+    20416, 20432, 20440, 20438,     0, 16384, 20480, 20481, 
+    20483, 20487, 20495, 20416, 20432,     0, 16384, 20480, 
+    20481, 20483, 20487, 20495, 20416, 20448, 20440,     0, 
+    16384, 20480, 20481, 20483, 20487, 20495, 20416, 20448, 
+    20440,     0, 16384, 20480, 20481, 20483, 20487, 20495, 
+    20416, 20448, 20440, 20442,     0, 16384, 20480, 20481, 
+    20483, 20487, 20495, 20416, 20448, 20440,     0, 16384, 
+    20480, 20481, 20483, 20487, 20495, 20416, 20448, 20449, 
+    20444,     0, 16384, 20480, 20481, 20483, 20487, 20495, 
+    20416, 20448, 20449, 20444,     0, 16384, 20480, 20481, 
+    20483, 20487, 20495, 20416, 20448, 20449, 20444, 20446, 
+        0, 16384, 20480, 20481, 20483, 20487, 20495, 20416, 
+        0, 16384, 20480, 20481, 20483, 20487, 20495, 20416, 
+    20448,     0, 16384, 20480, 20481, 20483, 20487, 20495, 
+    20416, 20448,     0, 16384, 20480, 20481, 20483, 20487, 
+    20495, 20416, 20448, 20450,     0, 16384, 20480, 20481, 
+    20483, 20487, 20495, 20416, 20448,     0, 16384, 20480, 
+    20481, 20483, 20487, 20495, 20416, 20448, 20452,     0, 
+    16384, 20480, 20481, 20483, 20487, 20495, 20416, 20448, 
+    20452,     0, 16384, 20480, 20481, 20483, 20487, 20495, 
+    20416, 20448, 20456, 20454,     0, 16384, 20480, 20481, 
+    20483, 20487, 20495, 20416, 20448,     0, 16384, 20480, 
+    20481, 20483, 20487, 20495, 20416, 20448, 20456,     0, 
+    16384, 20480, 20481, 20483, 20487, 20495, 20416, 20448, 
+    20456,     0, 16384, 20480, 20481, 20483, 20487, 20495, 
+    20416, 20448, 20456, 20458,     0, 16384, 20480, 20481, 
+    20483, 20487, 20495, 20416, 20448, 20456,     0, 16384, 
+    20480, 20481, 20483, 20487, 20495, 20416, 20448, 20464, 
+    20460,     0, 16384, 20480, 20481, 20483, 20487, 20495, 
+    20416, 20448, 20464, 20460,     0, 16384, 20480, 20481, 
+    20483, 20487, 20495, 20416, 20448, 20464, 20465, 20462, 
+        0, 16384, 20480, 20481, 20483, 20487, 20495, 20416, 
+    20448,     0, 16384, 20480, 20481, 20483, 20487, 20495, 
+    20416, 20448, 20464,     0, 16384, 20480, 20481, 20483, 
+    20487, 20495, 20416, 20448, 20464,     0, 16384, 20480, 
+    20481, 20483, 20487, 20495, 20416, 20448, 20464, 20466, 
+        0, 16384, 20480, 20481, 20483, 20487, 20495, 20416, 
+    20448, 20464,     0, 16384, 20480, 20481, 20483, 20487, 
+    20495, 20416, 20448, 20464, 20468,     0, 16384, 20480, 
+    20481, 20483, 20487, 20495, 20416, 20448, 20464, 20468, 
+        0, 16384, 20480, 20481, 20483, 20487, 20495, 20416, 
+    20448, 20464, 20472, 20470,     0, 16384, 20480, 20481, 
+    20483, 20487, 20495, 20416, 20448, 20464,     0, 16384, 
+    20480, 20481, 20483, 20487, 20495, 20416, 20448, 20464, 
+    20472,     0, 16384, 20480, 20481, 20483, 20487, 20495, 
+    20416, 20448, 20464, 20472,     0, 16384, 20480, 20481, 
+    20483, 20487, 20495, 20416, 20448, 20464, 20472, 20474, 
+        0, 16384, 20480, 20481, 20483, 20487, 20495, 20416, 
+    20448, 20464, 20472,     0, 16384, 20480, 20481, 20483, 
+    20487, 20495, 20416, 20448, 20464, 20472, 20476,     0, 
+    16384, 20480, 20481, 20483, 20487, 20495, 20416, 20448, 
+    20464, 20472, 20476,     0, 16384, 20480, 20481, 20483, 
+    20487, 20495, 20416, 20448, 20464, 20472, 20476, 20478, 
+        0, 16384,     0, 16384, 20480,     0, 16384, 20480, 
+        0, 16384, 20480, 20482,     0, 16384, 20480,     0, 
+    16384, 20480, 20484,     0, 16384, 20480, 20484,     0, 
+    16384, 20480, 20488, 20486,     0, 16384, 20480,     0, 
+    16384, 20480, 20488,     0, 16384, 20480, 20488,     0, 
+    16384, 20480, 20488, 20490,     0, 16384, 20480, 20488, 
+        0, 16384, 20480, 20496, 20492,     0, 16384, 20480, 
+    20496, 20492,     0, 16384, 20480, 20496, 20497, 20494, 
+        0, 16384, 20480,     0, 16384, 20480, 20496,     0, 
+    16384, 20480, 20496,     0, 16384, 20480, 20496, 20498, 
+        0, 16384, 20480, 20496,     0, 16384, 20480, 20496, 
+    20500,     0, 16384, 20480, 20496, 20500,     0, 16384, 
+    20480, 20496, 20504, 20502,     0, 16384, 20480, 20496, 
+        0, 16384, 20480, 20512, 20504,     0, 16384, 20480, 
+    20512, 20504,     0, 16384, 20480, 20512, 20504, 20506, 
+        0, 16384, 20480, 20512, 20504,     0, 16384, 20480, 
+    20512, 20513, 20508,     0, 16384, 20480, 20512, 20513, 
+    20508,     0, 16384, 20480, 20512, 20513, 20508, 20510, 
+        0, 16384, 20480,     0, 16384, 20480, 20512,     0, 
+    16384, 20480, 20512,     0, 16384, 20480, 20512, 20514, 
+        0, 16384, 20480, 20512,     0, 16384, 20480, 20512, 
+    20516,     0, 16384, 20480, 20512, 20516,     0, 16384, 
+    20480, 20512, 20520, 20518,     0, 16384, 20480, 20512, 
+        0, 16384, 20480, 20512, 20520,     0, 16384, 20480, 
+    20512, 20520,     0, 16384, 20480, 20512, 20520, 20522, 
+        0, 16384, 20480, 20512, 20520,     0, 16384, 20480, 
+    20512, 20528, 20524,     0, 16384, 20480, 20512, 20528, 
+    20524,     0, 16384, 20480, 20512, 20528, 20529, 20526, 
+        0, 16384, 20480, 20512,     0, 16384, 20480, 20544, 
+    20528,     0, 16384, 20480, 20544, 20528,     0, 16384, 
+    20480, 20544, 20528, 20530,     0, 16384, 20480, 20544, 
+    20528,     0, 16384, 20480, 20544, 20528, 20532,     0, 
+    16384, 20480, 20544, 20528, 20532,     0, 16384, 20480, 
+    20544, 20528, 20536, 20534,     0, 16384, 20480, 20544, 
+    20528,     0, 16384, 20480, 20544, 20545, 20536,     0, 
+    16384, 20480, 20544, 20545, 20536,     0, 16384, 20480, 
+    20544, 20545, 20536, 20538,     0, 16384, 20480, 20544, 
+    20545, 20536,     0, 16384, 20480, 20544, 20545, 20536, 
+    20540,     0, 16384, 20480, 20544, 20545, 20547, 20540, 
+        0, 16384, 20480, 20544, 20545, 20547, 20540, 20542, 
+        0, 16384, 20480,     0, 16384, 20480, 20544,     0, 
+    16384, 20480, 20544,     0, 16384, 20480, 20544, 20546, 
+        0, 16384, 20480, 20544,     0, 16384, 20480, 20544, 
+    20548,     0, 16384, 20480, 20544, 20548,     0, 16384, 
+    20480, 20544, 20552, 20550,     0, 16384, 20480, 20544, 
+        0, 16384, 20480, 20544, 20552,     0, 16384, 20480, 
+    20544, 20552,     0, 16384, 20480, 20544, 20552, 20554, 
+        0, 16384, 20480, 20544, 20552,     0, 16384, 20480, 
+    20544, 20560, 20556,     0, 16384, 20480, 20544, 20560, 
+    20556,     0, 16384, 20480, 20544, 20560, 20561, 20558, 
+        0, 16384, 20480, 20544,     0, 16384, 20480, 20544, 
+    20560,     0, 16384, 20480, 20544, 20560,     0, 16384, 
+    20480, 20544, 20560, 20562,     0, 16384, 20480, 20544, 
+    20560,     0, 16384, 20480, 20544, 20560, 20564,     0, 
+    16384, 20480, 20544, 20560, 20564,     0, 16384, 20480, 
+    20544, 20560, 20568, 20566,     0, 16384, 20480, 20544, 
+    20560,     0, 16384, 20480, 20544, 20576, 20568,     0, 
+    16384, 20480, 20544, 20576, 20568,     0, 16384, 20480, 
+    20544, 20576, 20568, 20570,     0, 16384, 20480, 20544, 
+    20576, 20568,     0, 16384, 20480, 20544, 20576, 20577, 
+    20572,     0, 16384, 20480, 20544, 20576, 20577, 20572, 
+        0, 16384, 20480, 20544, 20576, 20577, 20572, 20574, 
+        0, 16384, 20480, 20544,     0, 16384, 20480, 20608, 
+    20576,     0, 16384, 20480, 20608, 20576,     0, 16384, 
+    20480, 20608, 20576, 20578,     0, 16384, 20480, 20608, 
+    20576,     0, 16384, 20480, 20608, 20576, 20580,     0, 
+    16384, 20480, 20608, 20576, 20580,     0, 16384, 20480, 
+    20608, 20576, 20584, 20582,     0, 16384, 20480, 20608, 
+    20576,     0, 16384, 20480, 20608, 20576, 20584,     0, 
+    16384, 20480, 20608, 20576, 20584,     0, 16384, 20480, 
+    20608, 20576, 20584, 20586,     0, 16384, 20480, 20608, 
+    20576, 20584,     0, 16384, 20480, 20608, 20576, 20592, 
+    20588,     0, 16384, 20480, 20608, 20576, 20592, 20588, 
+        0, 16384, 20480, 20608, 20576, 20592, 20593, 20590, 
+        0, 16384, 20480, 20608, 20576,     0, 16384, 20480, 
+    20608, 20609, 20592,     0, 16384, 20480, 20608, 20609, 
+    20592,     0, 16384, 20480, 20608, 20609, 20592, 20594, 
+        0, 16384, 20480, 20608, 20609, 20592,     0, 16384, 
+    20480, 20608, 20609, 20592, 20596,     0, 16384, 20480, 
+    20608, 20609, 20592, 20596,     0, 16384, 20480, 20608, 
+    20609, 20592, 20600, 20598,     0, 16384, 20480, 20608, 
+    20609, 20592,     0, 16384, 20480, 20608, 20609, 20592, 
+    20600,     0, 16384, 20480, 20608, 20609, 20611, 20600, 
+        0, 16384, 20480, 20608, 20609, 20611, 20600, 20602, 
+        0, 16384, 20480, 20608, 20609, 20611, 20600,     0, 
+    16384, 20480, 20608, 20609, 20611, 20600, 20604,     0, 
+    16384, 20480, 20608, 20609, 20611, 20600, 20604,     0, 
+    16384, 20480, 20608, 20609, 20611, 20600, 20604, 20606, 
+        0, 16384, 20480,     0, 16384, 20480, 20608,     0, 
+    16384, 20480, 20608,     0, 16384, 20480, 20608, 20610, 
+        0, 16384, 20480, 20608,     0, 16384, 20480, 20608, 
+    20612,     0, 16384, 20480, 20608, 20612,     0, 16384, 
+    20480, 20608, 20616, 20614,     0, 16384, 20480, 20608, 
+        0, 16384, 20480, 20608, 20616,     0, 16384, 20480, 
+    20608, 20616,     0, 16384, 20480, 20608, 20616, 20618, 
+        0, 16384, 20480, 20608, 20616,     0, 16384, 20480, 
+    20608, 20624, 20620,     0, 16384, 20480, 20608, 20624, 
+    20620,     0, 16384, 20480, 20608, 20624, 20625, 20622, 
+        0, 16384, 20480, 20608,     0, 16384, 20480, 20608, 
+    20624,     0, 16384, 20480, 20608, 20624,     0, 16384, 
+    20480, 20608, 20624, 20626,     0, 16384, 20480, 20608, 
+    20624,     0, 16384, 20480, 20608, 20624, 20628,     0, 
+    16384, 20480, 20608, 20624, 20628,     0, 16384, 20480, 
+    20608, 20624, 20632, 20630,     0, 16384, 20480, 20608, 
+    20624,     0, 16384, 20480, 20608, 20640, 20632,     0, 
+    16384, 20480, 20608, 20640, 20632,     0, 16384, 20480, 
+    20608, 20640, 20632, 20634,     0, 16384, 20480, 20608, 
+    20640, 20632,     0, 16384, 20480, 20608, 20640, 20641, 
+    20636,     0, 16384, 20480, 20608, 20640, 20641, 20636, 
+        0, 16384, 20480, 20608, 20640, 20641, 20636, 20638, 
+        0, 16384, 20480, 20608,     0, 16384, 20480, 20608, 
+    20640,     0, 16384, 20480, 20608, 20640,     0, 16384, 
+    20480, 20608, 20640, 20642,     0, 16384, 20480, 20608, 
+    20640,     0, 16384, 20480, 20608, 20640, 20644,     0, 
+    16384, 20480, 20608, 20640, 20644,     0, 16384, 20480, 
+    20608, 20640, 20648, 20646,     0, 16384, 20480, 20608, 
+    20640,     0, 16384, 20480, 20608, 20640, 20648,     0, 
+    16384, 20480, 20608, 20640, 20648,     0, 16384, 20480, 
+    20608, 20640, 20648, 20650,     0, 16384, 20480, 20608, 
+    20640, 20648,     0, 16384, 20480, 20608, 20640, 20656, 
+    20652,     0, 16384, 20480, 20608, 20640, 20656, 20652, 
+        0, 16384, 20480, 20608, 20640, 20656, 20657, 20654, 
+        0, 16384, 20480, 20608, 20640,     0, 16384, 20480, 
+    20608, 20672, 20656,     0, 16384, 20480, 20608, 20672, 
+    20656,     0, 16384, 20480, 20608, 20672, 20656, 20658, 
+        0, 16384, 20480, 20608, 20672, 20656,     0, 16384, 
+    20480, 20608, 20672, 20656, 20660,     0, 16384, 20480, 
+    20608, 20672, 20656, 20660,     0, 16384, 20480, 20608, 
+    20672, 20656, 20664, 20662,     0, 16384, 20480, 20608, 
+    20672, 20656,     0, 16384, 20480, 20608, 20672, 20673, 
+    20664,     0, 16384, 20480, 20608, 20672, 20673, 20664, 
+        0, 16384, 20480, 20608, 20672, 20673, 20664, 20666, 
+        0, 16384, 20480, 20608, 20672, 20673, 20664,     0, 
+    16384, 20480, 20608, 20672, 20673, 20664, 20668,     0, 
+    16384, 20480, 20608, 20672, 20673, 20675, 20668,     0, 
+    16384, 20480, 20608, 20672, 20673, 20675, 20668, 20670, 
+        0, 16384, 20480, 20608,     0, 16384, 20480, 20736, 
+    20672,     0, 16384, 20480, 20736, 20672,     0, 16384, 
+    20480, 20736, 20672, 20674,     0, 16384, 20480, 20736, 
+    20672,     0, 16384, 20480, 20736, 20672, 20676,     0, 
+    16384, 20480, 20736, 20672, 20676,     0, 16384, 20480, 
+    20736, 20672, 20680, 20678,     0, 16384, 20480, 20736, 
+    20672,     0, 16384, 20480, 20736, 20672, 20680,     0, 
+    16384, 20480, 20736, 20672, 20680,     0, 16384, 20480, 
+    20736, 20672, 20680, 20682,     0, 16384, 20480, 20736, 
+    20672, 20680,     0, 16384, 20480, 20736, 20672, 20688, 
+    20684,     0, 16384, 20480, 20736, 20672, 20688, 20684, 
+        0, 16384, 20480, 20736, 20672, 20688, 20689, 20686, 
+        0, 16384, 20480, 20736, 20672,     0, 16384, 20480, 
+    20736, 20672, 20688,     0, 16384, 20480, 20736, 20672, 
+    20688,     0, 16384, 20480, 20736, 20672, 20688, 20690, 
+        0, 16384, 20480, 20736, 20672, 20688,     0, 16384, 
+    20480, 20736, 20672, 20688, 20692,     0, 16384, 20480, 
+    20736, 20672, 20688, 20692,     0, 16384, 20480, 20736, 
+    20672, 20688, 20696, 20694,     0, 16384, 20480, 20736, 
+    20672, 20688,     0, 16384, 20480, 20736, 20672, 20704, 
+    20696,     0, 16384, 20480, 20736, 20672, 20704, 20696, 
+        0, 16384, 20480, 20736, 20672, 20704, 20696, 20698, 
+        0, 16384, 20480, 20736, 20672, 20704, 20696,     0, 
+    16384, 20480, 20736, 20672, 20704, 20705, 20700,     0, 
+    16384, 20480, 20736, 20672, 20704, 20705, 20700,     0, 
+    16384, 20480, 20736, 20672, 20704, 20705, 20700, 20702, 
+        0, 16384, 20480, 20736, 20672,     0, 16384, 20480, 
+    20736, 20737, 20704,     0, 16384, 20480, 20736, 20737, 
+    20704,     0, 16384, 20480, 20736, 20737, 20704, 20706, 
+        0, 16384, 20480, 20736, 20737, 20704,     0, 16384, 
+    20480, 20736, 20737, 20704, 20708,     0, 16384, 20480, 
+    20736, 20737, 20704, 20708,     0, 16384, 20480, 20736, 
+    20737, 20704, 20712, 20710,     0, 16384, 20480, 20736, 
+    20737, 20704,     0, 16384, 20480, 20736, 20737, 20704, 
+    20712,     0, 16384, 20480, 20736, 20737, 20704, 20712, 
+        0, 16384, 20480, 20736, 20737, 20704, 20712, 20714, 
+        0, 16384, 20480, 20736, 20737, 20704, 20712,     0, 
+    16384, 20480, 20736, 20737, 20704, 20720, 20716,     0, 
+    16384, 20480, 20736, 20737, 20704, 20720, 20716,     0, 
+    16384, 20480, 20736, 20737, 20704, 20720, 20721, 20718, 
+        0, 16384, 20480, 20736, 20737, 20704,     0, 16384, 
+    20480, 20736, 20737, 20704, 20720,     0, 16384, 20480, 
+    20736, 20737, 20739, 20720,     0, 16384, 20480, 20736, 
+    20737, 20739, 20720, 20722,     0, 16384, 20480, 20736, 
+    20737, 20739, 20720,     0, 16384, 20480, 20736, 20737, 
+    20739, 20720, 20724,     0, 16384, 20480, 20736, 20737, 
+    20739, 20720, 20724,     0, 16384, 20480, 20736, 20737, 
+    20739, 20720, 20728, 20726,     0, 16384, 20480, 20736, 
+    20737, 20739, 20720,     0, 16384, 20480, 20736, 20737, 
+    20739, 20720, 20728,     0, 16384, 20480, 20736, 20737, 
+    20739, 20720, 20728,     0, 16384, 20480, 20736, 20737, 
+    20739, 20720, 20728, 20730,     0, 16384, 20480, 20736, 
+    20737, 20739, 20743, 20728,     0, 16384, 20480, 20736, 
+    20737, 20739, 20743, 20728, 20732,     0, 16384, 20480, 
+    20736, 20737, 20739, 20743, 20728, 20732,     0, 16384, 
+    20480, 20736, 20737, 20739, 20743, 20728, 20732, 20734, 
+        0, 16384, 20480,     0, 16384, 20480, 20736,     0, 
+    16384, 20480, 20736,     0, 16384, 20480, 20736, 20738, 
+        0, 16384, 20480, 20736,     0, 16384, 20480, 20736, 
+    20740,     0, 16384, 20480, 20736, 20740,     0, 16384, 
+    20480, 20736, 20744, 20742,     0, 16384, 20480, 20736, 
+        0, 16384, 20480, 20736, 20744,     0, 16384, 20480, 
+    20736, 20744,     0, 16384, 20480, 20736, 20744, 20746, 
+        0, 16384, 20480, 20736, 20744,     0, 16384, 20480, 
+    20736, 20752, 20748,     0, 16384, 20480, 20736, 20752, 
+    20748,     0, 16384, 20480, 20736, 20752, 20753, 20750, 
+        0, 16384, 20480, 20736,     0, 16384, 20480, 20736, 
+    20752,     0, 16384, 20480, 20736, 20752,     0, 16384, 
+    20480, 20736, 20752, 20754,     0, 16384, 20480, 20736, 
+    20752,     0, 16384, 20480, 20736, 20752, 20756,     0, 
+    16384, 20480, 20736, 20752, 20756,     0, 16384, 20480, 
+    20736, 20752, 20760, 20758,     0, 16384, 20480, 20736, 
+    20752,     0, 16384, 20480, 20736, 20768, 20760,     0, 
+    16384, 20480, 20736, 20768, 20760,     0, 16384, 20480, 
+    20736, 20768, 20760, 20762,     0, 16384, 20480, 20736, 
+    20768, 20760,     0, 16384, 20480, 20736, 20768, 20769, 
+    20764,     0, 16384, 20480, 20736, 20768, 20769, 20764, 
+        0, 16384, 20480, 20736, 20768, 20769, 20764, 20766, 
+        0, 16384, 20480, 20736,     0, 16384, 20480, 20736, 
+    20768,     0, 16384, 20480, 20736, 20768,     0, 16384, 
+    20480, 20736, 20768, 20770,     0, 16384, 20480, 20736, 
+    20768,     0, 16384, 20480, 20736, 20768, 20772,     0, 
+    16384, 20480, 20736, 20768, 20772,     0, 16384, 20480, 
+    20736, 20768, 20776, 20774,     0, 16384, 20480, 20736, 
+    20768,     0, 16384, 20480, 20736, 20768, 20776,     0, 
+    16384, 20480, 20736, 20768, 20776,     0, 16384, 20480, 
+    20736, 20768, 20776, 20778,     0, 16384, 20480, 20736, 
+    20768, 20776,     0, 16384, 20480, 20736, 20768, 20784, 
+    20780,     0, 16384, 20480, 20736, 20768, 20784, 20780, 
+        0, 16384, 20480, 20736, 20768, 20784, 20785, 20782, 
+        0, 16384, 20480, 20736, 20768,     0, 16384, 20480, 
+    20736, 20800, 20784,     0, 16384, 20480, 20736, 20800, 
+    20784,     0, 16384, 20480, 20736, 20800, 20784, 20786, 
+        0, 16384, 20480, 20736, 20800, 20784,     0, 16384, 
+    20480, 20736, 20800, 20784, 20788,     0, 16384, 20480, 
+    20736, 20800, 20784, 20788,     0, 16384, 20480, 20736, 
+    20800, 20784, 20792, 20790,     0, 16384, 20480, 20736, 
+    20800, 20784,     0, 16384, 20480, 20736, 20800, 20801, 
+    20792,     0, 16384, 20480, 20736, 20800, 20801, 20792, 
+        0, 16384, 20480, 20736, 20800, 20801, 20792, 20794, 
+        0, 16384, 20480, 20736, 20800, 20801, 20792,     0, 
+    16384, 20480, 20736, 20800, 20801, 20792, 20796,     0, 
+    16384, 20480, 20736, 20800, 20801, 20803, 20796,     0, 
+    16384, 20480, 20736, 20800, 20801, 20803, 20796, 20798, 
+        0, 16384, 20480, 20736,     0, 16384, 20480, 20736, 
+    20800,     0, 16384, 20480, 20736, 20800,     0, 16384, 
+    20480, 20736, 20800, 20802,     0, 16384, 20480, 20736, 
+    20800,     0, 16384, 20480, 20736, 20800, 20804,     0, 
+    16384, 20480, 20736, 20800, 20804,     0, 16384, 20480, 
+    20736, 20800, 20808, 20806,     0, 16384, 20480, 20736, 
+    20800,     0, 16384, 20480, 20736, 20800, 20808,     0, 
+    16384, 20480, 20736, 20800, 20808,     0, 16384, 20480, 
+    20736, 20800, 20808, 20810,     0, 16384, 20480, 20736, 
+    20800, 20808,     0, 16384, 20480, 20736, 20800, 20816, 
+    20812,     0, 16384, 20480, 20736, 20800, 20816, 20812, 
+        0, 16384, 20480, 20736, 20800, 20816, 20817, 20814, 
+        0, 16384, 20480, 20736, 20800,     0, 16384, 20480, 
+    20736, 20800, 20816,     0, 16384, 20480, 20736, 20800, 
+    20816,     0, 16384, 20480, 20736, 20800, 20816, 20818, 
+        0, 16384, 20480, 20736, 20800, 20816,     0, 16384, 
+    20480, 20736, 20800, 20816, 20820,     0, 16384, 20480, 
+    20736, 20800, 20816, 20820,     0, 16384, 20480, 20736, 
+    20800, 20816, 20824, 20822,     0, 16384, 20480, 20736, 
+    20800, 20816,     0, 16384, 20480, 20736, 20800, 20832, 
+    20824,     0, 16384, 20480, 20736, 20800, 20832, 20824, 
+        0, 16384, 20480, 20736, 20800, 20832, 20824, 20826, 
+        0, 16384, 20480, 20736, 20800, 20832, 20824,     0, 
+    16384, 20480, 20736, 20800, 20832, 20833, 20828,     0, 
+    16384, 20480, 20736, 20800, 20832, 20833, 20828,     0, 
+    16384, 20480, 20736, 20800, 20832, 20833, 20828, 20830, 
+        0, 16384, 20480, 20736, 20800,     0, 16384, 20480, 
+    20736, 20864, 20832,     0, 16384, 20480, 20736, 20864, 
+    20832,     0, 16384, 20480, 20736, 20864, 20832, 20834, 
+        0, 16384, 20480, 20736, 20864, 20832,     0, 16384, 
+    20480, 20736, 20864, 20832, 20836,     0, 16384, 20480, 
+    20736, 20864, 20832, 20836,     0, 16384, 20480, 20736, 
+    20864, 20832, 20840, 20838,     0, 16384, 20480, 20736, 
+    20864, 20832,     0, 16384, 20480, 20736, 20864, 20832, 
+    20840,     0, 16384, 20480, 20736, 20864, 20832, 20840, 
+        0, 16384, 20480, 20736, 20864, 20832, 20840, 20842, 
+        0, 16384, 20480, 20736, 20864, 20832, 20840,     0, 
+    16384, 20480, 20736, 20864, 20832, 20848, 20844,     0, 
+    16384, 20480, 20736, 20864, 20832, 20848, 20844,     0, 
+    16384, 20480, 20736, 20864, 20832, 20848, 20849, 20846, 
+        0, 16384, 20480, 20736, 20864, 20832,     0, 16384, 
+    20480, 20736, 20864, 20865, 20848,     0, 16384, 20480, 
+    20736, 20864, 20865, 20848,     0, 16384, 20480, 20736, 
+    20864, 20865, 20848, 20850,     0, 16384, 20480, 20736, 
+    20864, 20865, 20848,     0, 16384, 20480, 20736, 20864, 
+    20865, 20848, 20852,     0, 16384, 20480, 20736, 20864, 
+    20865, 20848, 20852,     0, 16384, 20480, 20736, 20864, 
+    20865, 20848, 20856, 20854,     0, 16384, 20480, 20736, 
+    20864, 20865, 20848,     0, 16384, 20480, 20736, 20864, 
+    20865, 20848, 20856,     0, 16384, 20480, 20736, 20864, 
+    20865, 20867, 20856,     0, 16384, 20480, 20736, 20864, 
+    20865, 20867, 20856, 20858,     0, 16384, 20480, 20736, 
+    20864, 20865, 20867, 20856,     0, 16384, 20480, 20736, 
+    20864, 20865, 20867, 20856, 20860,     0, 16384, 20480, 
+    20736, 20864, 20865, 20867, 20856, 20860,     0, 16384, 
+    20480, 20736, 20864, 20865, 20867, 20856, 20860, 20862, 
+        0, 16384, 20480, 20736,     0, 16384, 20480, 20992, 
+    20864,     0, 16384, 20480, 20992, 20864,     0, 16384, 
+    20480, 20992, 20864, 20866,     0, 16384, 20480, 20992, 
+    20864,     0, 16384, 20480, 20992, 20864, 20868,     0, 
+    16384, 20480, 20992, 20864, 20868,     0, 16384, 20480, 
+    20992, 20864, 20872, 20870,     0, 16384, 20480, 20992, 
+    20864,     0, 16384, 20480, 20992, 20864, 20872,     0, 
+    16384, 20480, 20992, 20864, 20872,     0, 16384, 20480, 
+    20992, 20864, 20872, 20874,     0, 16384, 20480, 20992, 
+    20864, 20872,     0, 16384, 20480, 20992, 20864, 20880, 
+    20876,     0, 16384, 20480, 20992, 20864, 20880, 20876, 
+        0, 16384, 20480, 20992, 20864, 20880, 20881, 20878, 
+        0, 16384, 20480, 20992, 20864,     0, 16384, 20480, 
+    20992, 20864, 20880,     0, 16384, 20480, 20992, 20864, 
+    20880,     0, 16384, 20480, 20992, 20864, 20880, 20882, 
+        0, 16384, 20480, 20992, 20864, 20880,     0, 16384, 
+    20480, 20992, 20864, 20880, 20884,     0, 16384, 20480, 
+    20992, 20864, 20880, 20884,     0, 16384, 20480, 20992, 
+    20864, 20880, 20888, 20886,     0, 16384, 20480, 20992, 
+    20864, 20880,     0, 16384, 20480, 20992, 20864, 20896, 
+    20888,     0, 16384, 20480, 20992, 20864, 20896, 20888, 
+        0, 16384, 20480, 20992, 20864, 20896, 20888, 20890, 
+        0, 16384, 20480, 20992, 20864, 20896, 20888,     0, 
+    16384, 20480, 20992, 20864, 20896, 20897, 20892,     0, 
+    16384, 20480, 20992, 20864, 20896, 20897, 20892,     0, 
+    16384, 20480, 20992, 20864, 20896, 20897, 20892, 20894, 
+        0, 16384, 20480, 20992, 20864,     0, 16384, 20480, 
+    20992, 20864, 20896,     0, 16384, 20480, 20992, 20864, 
+    20896,     0, 16384, 20480, 20992, 20864, 20896, 20898, 
+        0, 16384, 20480, 20992, 20864, 20896,     0, 16384, 
+    20480, 20992, 20864, 20896, 20900,     0, 16384, 20480, 
+    20992, 20864, 20896, 20900,     0, 16384, 20480, 20992, 
+    20864, 20896, 20904, 20902,     0, 16384, 20480, 20992, 
+    20864, 20896,     0, 16384, 20480, 20992, 20864, 20896, 
+    20904,     0, 16384, 20480, 20992, 20864, 20896, 20904, 
+        0, 16384, 20480, 20992, 20864, 20896, 20904, 20906, 
+        0, 16384, 20480, 20992, 20864, 20896, 20904,     0, 
+    16384, 20480, 20992, 20864, 20896, 20912, 20908,     0, 
+    16384, 20480, 20992, 20864, 20896, 20912, 20908,     0, 
+    16384, 20480, 20992, 20864, 20896, 20912, 20913, 20910, 
+        0, 16384, 20480, 20992, 20864, 20896,     0, 16384, 
+    20480, 20992, 20864, 20928, 20912,     0, 16384, 20480, 
+    20992, 20864, 20928, 20912,     0, 16384, 20480, 20992, 
+    20864, 20928, 20912, 20914,     0, 16384, 20480, 20992, 
+    20864, 20928, 20912,     0, 16384, 20480, 20992, 20864, 
+    20928, 20912, 20916,     0, 16384, 20480, 20992, 20864, 
+    20928, 20912, 20916,     0, 16384, 20480, 20992, 20864, 
+    20928, 20912, 20920, 20918,     0, 16384, 20480, 20992, 
+    20864, 20928, 20912,     0, 16384, 20480, 20992, 20864, 
+    20928, 20929, 20920,     0, 16384, 20480, 20992, 20864, 
+    20928, 20929, 20920,     0, 16384, 20480, 20992, 20864, 
+    20928, 20929, 20920, 20922,     0, 16384, 20480, 20992, 
+    20864, 20928, 20929, 20920,     0, 16384, 20480, 20992, 
+    20864, 20928, 20929, 20920, 20924,     0, 16384, 20480, 
+    20992, 20864, 20928, 20929, 20931, 20924,     0, 16384, 
+    20480, 20992, 20864, 20928, 20929, 20931, 20924, 20926, 
+        0, 16384, 20480, 20992, 20864,     0, 16384, 20480, 
+    20992, 20993, 20928,     0, 16384, 20480, 20992, 20993, 
+    20928,     0, 16384, 20480, 20992, 20993, 20928, 20930, 
+        0, 16384, 20480, 20992, 20993, 20928,     0, 16384, 
+    20480, 20992, 20993, 20928, 20932,     0, 16384, 20480, 
+    20992, 20993, 20928, 20932,     0, 16384, 20480, 20992, 
+    20993, 20928, 20936, 20934,     0, 16384, 20480, 20992, 
+    20993, 20928,     0, 16384, 20480, 20992, 20993, 20928, 
+    20936,     0, 16384, 20480, 20992, 20993, 20928, 20936, 
+        0, 16384, 20480, 20992, 20993, 20928, 20936, 20938, 
+        0, 16384, 20480, 20992, 20993, 20928, 20936,     0, 
+    16384, 20480, 20992, 20993, 20928, 20944, 20940,     0, 
+    16384, 20480, 20992, 20993, 20928, 20944, 20940,     0, 
+    16384, 20480, 20992, 20993, 20928, 20944, 20945, 20942, 
+        0, 16384, 20480, 20992, 20993, 20928,     0, 16384, 
+    20480, 20992, 20993, 20928, 20944,     0, 16384, 20480, 
+    20992, 20993, 20928, 20944,     0, 16384, 20480, 20992, 
+    20993, 20928, 20944, 20946,     0, 16384, 20480, 20992, 
+    20993, 20928, 20944,     0, 16384, 20480, 20992, 20993, 
+    20928, 20944, 20948,     0, 16384, 20480, 20992, 20993, 
+    20928, 20944, 20948,     0, 16384, 20480, 20992, 20993, 
+    20928, 20944, 20952, 20950,     0, 16384, 20480, 20992, 
+    20993, 20928, 20944,     0, 16384, 20480, 20992, 20993, 
+    20928, 20960, 20952,     0, 16384, 20480, 20992, 20993, 
+    20928, 20960, 20952,     0, 16384, 20480, 20992, 20993, 
+    20928, 20960, 20952, 20954,     0, 16384, 20480, 20992, 
+    20993, 20928, 20960, 20952,     0, 16384, 20480, 20992, 
+    20993, 20928, 20960, 20961, 20956,     0, 16384, 20480, 
+    20992, 20993, 20928, 20960, 20961, 20956,     0, 16384, 
+    20480, 20992, 20993, 20928, 20960, 20961, 20956, 20958, 
+        0, 16384, 20480, 20992, 20993, 20928,     0, 16384, 
+    20480, 20992, 20993, 20928, 20960,     0, 16384, 20480, 
+    20992, 20993, 20995, 20960,     0, 16384, 20480, 20992, 
+    20993, 20995, 20960, 20962,     0, 16384, 20480, 20992, 
+    20993, 20995, 20960,     0, 16384, 20480, 20992, 20993, 
+    20995, 20960, 20964,     0, 16384, 20480, 20992, 20993, 
+    20995, 20960, 20964,     0, 16384, 20480, 20992, 20993, 
+    20995, 20960, 20968, 20966,     0, 16384, 20480, 20992, 
+    20993, 20995, 20960,     0, 16384, 20480, 20992, 20993, 
+    20995, 20960, 20968,     0, 16384, 20480, 20992, 20993, 
+    20995, 20960, 20968,     0, 16384, 20480, 20992, 20993, 
+    20995, 20960, 20968, 20970,     0, 16384, 20480, 20992, 
+    20993, 20995, 20960, 20968,     0, 16384, 20480, 20992, 
+    20993, 20995, 20960, 20976, 20972,     0, 16384, 20480, 
+    20992, 20993, 20995, 20960, 20976, 20972,     0, 16384, 
+    20480, 20992, 20993, 20995, 20960, 20976, 20977, 20974, 
+        0, 16384, 20480, 20992, 20993, 20995, 20960,     0, 
+    16384, 20480, 20992, 20993, 20995, 20960, 20976,     0, 
+    16384, 20480, 20992, 20993, 20995, 20960, 20976,     0, 
+    16384, 20480, 20992, 20993, 20995, 20960, 20976, 20978, 
+        0, 16384, 20480, 20992, 20993, 20995, 20999, 20976, 
+        0, 16384, 20480, 20992, 20993, 20995, 20999, 20976, 
+    20980,     0, 16384, 20480, 20992, 20993, 20995, 20999, 
+    20976, 20980,     0, 16384, 20480, 20992, 20993, 20995, 
+    20999, 20976, 20984, 20982,     0, 16384, 20480, 20992, 
+    20993, 20995, 20999, 20976,     0, 16384, 20480, 20992, 
+    20993, 20995, 20999, 20976, 20984,     0, 16384, 20480, 
+    20992, 20993, 20995, 20999, 20976, 20984,     0, 16384, 
+    20480, 20992, 20993, 20995, 20999, 20976, 20984, 20986, 
+        0, 16384, 20480, 20992, 20993, 20995, 20999, 20976, 
+    20984,     0, 16384, 20480, 20992, 20993, 20995, 20999, 
+    20976, 20984, 20988,     0, 16384, 20480, 20992, 20993, 
+    20995, 20999, 20976, 20984, 20988,     0, 16384, 20480, 
+    20992, 20993, 20995, 20999, 20976, 20984, 20988, 20990, 
+        0, 16384, 20480,     0, 16384, 20480, 20992,     0, 
+    16384, 20480, 20992,     0, 16384, 20480, 20992, 20994, 
+        0, 16384, 20480, 20992,     0, 16384, 20480, 20992, 
+    20996,     0, 16384, 20480, 20992, 20996,     0, 16384, 
+    20480, 20992, 21000, 20998,     0, 16384, 20480, 20992, 
+        0, 16384, 20480, 20992, 21000,     0, 16384, 20480, 
+    20992, 21000,     0, 16384, 20480, 20992, 21000, 21002, 
+        0, 16384, 20480, 20992, 21000,     0, 16384, 20480, 
+    20992, 21008, 21004,     0, 16384, 20480, 20992, 21008, 
+    21004,     0, 16384, 20480, 20992, 21008, 21009, 21006, 
+        0, 16384, 20480, 20992,     0, 16384, 20480, 20992, 
+    21008,     0, 16384, 20480, 20992, 21008,     0, 16384, 
+    20480, 20992, 21008, 21010,     0, 16384, 20480, 20992, 
+    21008,     0, 16384, 20480, 20992, 21008, 21012,     0, 
+    16384, 20480, 20992, 21008, 21012,     0, 16384, 20480, 
+    20992, 21008, 21016, 21014,     0, 16384, 20480, 20992, 
+    21008,     0, 16384, 20480, 20992, 21024, 21016,     0, 
+    16384, 20480, 20992, 21024, 21016,     0, 16384, 20480, 
+    20992, 21024, 21016, 21018,     0, 16384, 20480, 20992, 
+    21024, 21016,     0, 16384, 20480, 20992, 21024, 21025, 
+    21020,     0, 16384, 20480, 20992, 21024, 21025, 21020, 
+        0, 16384, 20480, 20992, 21024, 21025, 21020, 21022, 
+        0, 16384, 20480, 20992,     0, 16384, 20480, 20992, 
+    21024,     0, 16384, 20480, 20992, 21024,     0, 16384, 
+    20480, 20992, 21024, 21026,     0, 16384, 20480, 20992, 
+    21024,     0, 16384, 20480, 20992, 21024, 21028,     0, 
+    16384, 20480, 20992, 21024, 21028,     0, 16384, 20480, 
+    20992, 21024, 21032, 21030,     0, 16384, 20480, 20992, 
+    21024,     0, 16384, 20480, 20992, 21024, 21032,     0, 
+    16384, 20480, 20992, 21024, 21032,     0, 16384, 20480, 
+    20992, 21024, 21032, 21034,     0, 16384, 20480, 20992, 
+    21024, 21032,     0, 16384, 20480, 20992, 21024, 21040, 
+    21036,     0, 16384, 20480, 20992, 21024, 21040, 21036, 
+        0, 16384, 20480, 20992, 21024, 21040, 21041, 21038, 
+        0, 16384, 20480, 20992, 21024,     0, 16384, 20480, 
+    20992, 21056, 21040,     0, 16384, 20480, 20992, 21056, 
+    21040,     0, 16384, 20480, 20992, 21056, 21040, 21042, 
+        0, 16384, 20480, 20992, 21056, 21040,     0, 16384, 
+    20480, 20992, 21056, 21040, 21044,     0, 16384, 20480, 
+    20992, 21056, 21040, 21044,     0, 16384, 20480, 20992, 
+    21056, 21040, 21048, 21046,     0, 16384, 20480, 20992, 
+    21056, 21040,     0, 16384, 20480, 20992, 21056, 21057, 
+    21048,     0, 16384, 20480, 20992, 21056, 21057, 21048, 
+        0, 16384, 20480, 20992, 21056, 21057, 21048, 21050, 
+        0, 16384, 20480, 20992, 21056, 21057, 21048,     0, 
+    16384, 20480, 20992, 21056, 21057, 21048, 21052,     0, 
+    16384, 20480, 20992, 21056, 21057, 21059, 21052,     0, 
+    16384, 20480, 20992, 21056, 21057, 21059, 21052, 21054, 
+        0, 16384, 20480, 20992,     0, 16384, 20480, 20992, 
+    21056,     0, 16384, 20480, 20992, 21056,     0, 16384, 
+    20480, 20992, 21056, 21058,     0, 16384, 20480, 20992, 
+    21056,     0, 16384, 20480, 20992, 21056, 21060,     0, 
+    16384, 20480, 20992, 21056, 21060,     0, 16384, 20480, 
+    20992, 21056, 21064, 21062,     0, 16384, 20480, 20992, 
+    21056,     0, 16384, 20480, 20992, 21056, 21064,     0, 
+    16384, 20480, 20992, 21056, 21064,     0, 16384, 20480, 
+    20992, 21056, 21064, 21066,     0, 16384, 20480, 20992, 
+    21056, 21064,     0, 16384, 20480, 20992, 21056, 21072, 
+    21068,     0, 16384, 20480, 20992, 21056, 21072, 21068, 
+        0, 16384, 20480, 20992, 21056, 21072, 21073, 21070, 
+        0, 16384, 20480, 20992, 21056,     0, 16384, 20480, 
+    20992, 21056, 21072,     0, 16384, 20480, 20992, 21056, 
+    21072,     0, 16384, 20480, 20992, 21056, 21072, 21074, 
+        0, 16384, 20480, 20992, 21056, 21072,     0, 16384, 
+    20480, 20992, 21056, 21072, 21076,     0, 16384, 20480, 
+    20992, 21056, 21072, 21076,     0, 16384, 20480, 20992, 
+    21056, 21072, 21080, 21078,     0, 16384, 20480, 20992, 
+    21056, 21072,     0, 16384, 20480, 20992, 21056, 21088, 
+    21080,     0, 16384, 20480, 20992, 21056, 21088, 21080, 
+        0, 16384, 20480, 20992, 21056, 21088, 21080, 21082, 
+        0, 16384, 20480, 20992, 21056, 21088, 21080,     0, 
+    16384, 20480, 20992, 21056, 21088, 21089, 21084,     0, 
+    16384, 20480, 20992, 21056, 21088, 21089, 21084,     0, 
+    16384, 20480, 20992, 21056, 21088, 21089, 21084, 21086, 
+        0, 16384, 20480, 20992, 21056,     0, 16384, 20480, 
+    20992, 21120, 21088,     0, 16384, 20480, 20992, 21120, 
+    21088,     0, 16384, 20480, 20992, 21120, 21088, 21090, 
+        0, 16384, 20480, 20992, 21120, 21088,     0, 16384, 
+    20480, 20992, 21120, 21088, 21092,     0, 16384, 20480, 
+    20992, 21120, 21088, 21092,     0, 16384, 20480, 20992, 
+    21120, 21088, 21096, 21094,     0, 16384, 20480, 20992, 
+    21120, 21088,     0, 16384, 20480, 20992, 21120, 21088, 
+    21096,     0, 16384, 20480, 20992, 21120, 21088, 21096, 
+        0, 16384, 20480, 20992, 21120, 21088, 21096, 21098, 
+        0, 16384, 20480, 20992, 21120, 21088, 21096,     0, 
+    16384, 20480, 20992, 21120, 21088, 21104, 21100,     0, 
+    16384, 20480, 20992, 21120, 21088, 21104, 21100,     0, 
+    16384, 20480, 20992, 21120, 21088, 21104, 21105, 21102, 
+        0, 16384, 20480, 20992, 21120, 21088,     0, 16384, 
+    20480, 20992, 21120, 21121, 21104,     0, 16384, 20480, 
+    20992, 21120, 21121, 21104,     0, 16384, 20480, 20992, 
+    21120, 21121, 21104, 21106,     0, 16384, 20480, 20992, 
+    21120, 21121, 21104,     0, 16384, 20480, 20992, 21120, 
+    21121, 21104, 21108,     0, 16384, 20480, 20992, 21120, 
+    21121, 21104, 21108,     0, 16384, 20480, 20992, 21120, 
+    21121, 21104, 21112, 21110,     0, 16384, 20480, 20992, 
+    21120, 21121, 21104,     0, 16384, 20480, 20992, 21120, 
+    21121, 21104, 21112,     0, 16384, 20480, 20992, 21120, 
+    21121, 21123, 21112,     0, 16384, 20480, 20992, 21120, 
+    21121, 21123, 21112, 21114,     0, 16384, 20480, 20992, 
+    21120, 21121, 21123, 21112,     0, 16384, 20480, 20992, 
+    21120, 21121, 21123, 21112, 21116,     0, 16384, 20480, 
+    20992, 21120, 21121, 21123, 21112, 21116,     0, 16384, 
+    20480, 20992, 21120, 21121, 21123, 21112, 21116, 21118, 
+        0, 16384, 20480, 20992,     0, 16384, 20480, 20992, 
+    21120,     0, 16384, 20480, 20992, 21120,     0, 16384, 
+    20480, 20992, 21120, 21122,     0, 16384, 20480, 20992, 
+    21120,     0, 16384, 20480, 20992, 21120, 21124,     0, 
+    16384, 20480, 20992, 21120, 21124,     0, 16384, 20480, 
+    20992, 21120, 21128, 21126,     0, 16384, 20480, 20992, 
+    21120,     0, 16384, 20480, 20992, 21120, 21128,     0, 
+    16384, 20480, 20992, 21120, 21128,     0, 16384, 20480, 
+    20992, 21120, 21128, 21130,     0, 16384, 20480, 20992, 
+    21120, 21128,     0, 16384, 20480, 20992, 21120, 21136, 
+    21132,     0, 16384, 20480, 20992, 21120, 21136, 21132, 
+        0, 16384, 20480, 20992, 21120, 21136, 21137, 21134, 
+        0, 16384, 20480, 20992, 21120,     0, 16384, 20480, 
+    20992, 21120, 21136,     0, 16384, 20480, 20992, 21120, 
+    21136,     0, 16384, 20480, 20992, 21120, 21136, 21138, 
+        0, 16384, 20480, 20992, 21120, 21136,     0, 16384, 
+    20480, 20992, 21120, 21136, 21140,     0, 16384, 20480, 
+    20992, 21120, 21136, 21140,     0, 16384, 20480, 20992, 
+    21120, 21136, 21144, 21142,     0, 16384, 20480, 20992, 
+    21120, 21136,     0, 16384, 20480, 20992, 21120, 21152, 
+    21144,     0, 16384, 20480, 20992, 21120, 21152, 21144, 
+        0, 16384, 20480, 20992, 21120, 21152, 21144, 21146, 
+        0, 16384, 20480, 20992, 21120, 21152, 21144,     0, 
+    16384, 20480, 20992, 21120, 21152, 21153, 21148,     0, 
+    16384, 20480, 20992, 21120, 21152, 21153, 21148,     0, 
+    16384, 20480, 20992, 21120, 21152, 21153, 21148, 21150, 
+        0, 16384, 20480, 20992, 21120,     0, 16384, 20480, 
+    20992, 21120, 21152,     0, 16384, 20480, 20992, 21120, 
+    21152,     0, 16384, 20480, 20992, 21120, 21152, 21154, 
+        0, 16384, 20480, 20992, 21120, 21152,     0, 16384, 
+    20480, 20992, 21120, 21152, 21156,     0, 16384, 20480, 
+    20992, 21120, 21152, 21156,     0, 16384, 20480, 20992, 
+    21120, 21152, 21160, 21158,     0, 16384, 20480, 20992, 
+    21120, 21152,     0, 16384, 20480, 20992, 21120, 21152, 
+    21160,     0, 16384, 20480, 20992, 21120, 21152, 21160, 
+        0, 16384, 20480, 20992, 21120, 21152, 21160, 21162, 
+        0, 16384, 20480, 20992, 21120, 21152, 21160,     0, 
+    16384, 20480, 20992, 21120, 21152, 21168, 21164,     0, 
+    16384, 20480, 20992, 21120, 21152, 21168, 21164,     0, 
+    16384, 20480, 20992, 21120, 21152, 21168, 21169, 21166, 
+        0, 16384, 20480, 20992, 21120, 21152,     0, 16384, 
+    20480, 20992, 21120, 21184, 21168,     0, 16384, 20480, 
+    20992, 21120, 21184, 21168,     0, 16384, 20480, 20992, 
+    21120, 21184, 21168, 21170,     0, 16384, 20480, 20992, 
+    21120, 21184, 21168,     0, 16384, 20480, 20992, 21120, 
+    21184, 21168, 21172,     0, 16384, 20480, 20992, 21120, 
+    21184, 21168, 21172,     0, 16384, 20480, 20992, 21120, 
+    21184, 21168, 21176, 21174,     0, 16384, 20480, 20992, 
+    21120, 21184, 21168,     0, 16384, 20480, 20992, 21120, 
+    21184, 21185, 21176,     0, 16384, 20480, 20992, 21120, 
+    21184, 21185, 21176,     0, 16384, 20480, 20992, 21120, 
+    21184, 21185, 21176, 21178,     0, 16384, 20480, 20992, 
+    21120, 21184, 21185, 21176,     0, 16384, 20480, 20992, 
+    21120, 21184, 21185, 21176, 21180,     0, 16384, 20480, 
+    20992, 21120, 21184, 21185, 21187, 21180,     0, 16384, 
+    20480, 20992, 21120, 21184, 21185, 21187, 21180, 21182, 
+        0, 16384, 20480, 20992, 21120,     0, 16384, 20480, 
+    20992, 21248, 21184,     0, 16384, 20480, 20992, 21248, 
+    21184,     0, 16384, 20480, 20992, 21248, 21184, 21186, 
+        0, 16384, 20480, 20992, 21248, 21184,     0, 16384, 
+    20480, 20992, 21248, 21184, 21188,     0, 16384, 20480, 
+    20992, 21248, 21184, 21188,     0, 16384, 20480, 20992, 
+    21248, 21184, 21192, 21190,     0, 16384, 20480, 20992, 
+    21248, 21184,     0, 16384, 20480, 20992, 21248, 21184, 
+    21192,     0, 16384, 20480, 20992, 21248, 21184, 21192, 
+        0, 16384, 20480, 20992, 21248, 21184, 21192, 21194, 
+        0, 16384, 20480, 20992, 21248, 21184, 21192,     0, 
+    16384, 20480, 20992, 21248, 21184, 21200, 21196,     0, 
+    16384, 20480, 20992, 21248, 21184, 21200, 21196,     0, 
+    16384, 20480, 20992, 21248, 21184, 21200, 21201, 21198, 
+        0, 16384, 20480, 20992, 21248, 21184,     0, 16384, 
+    20480, 20992, 21248, 21184, 21200,     0, 16384, 20480, 
+    20992, 21248, 21184, 21200,     0, 16384, 20480, 20992, 
+    21248, 21184, 21200, 21202,     0, 16384, 20480, 20992, 
+    21248, 21184, 21200,     0, 16384, 20480, 20992, 21248, 
+    21184, 21200, 21204,     0, 16384, 20480, 20992, 21248, 
+    21184, 21200, 21204,     0, 16384, 20480, 20992, 21248, 
+    21184, 21200, 21208, 21206,     0, 16384, 20480, 20992, 
+    21248, 21184, 21200,     0, 16384, 20480, 20992, 21248, 
+    21184, 21216, 21208,     0, 16384, 20480, 20992, 21248, 
+    21184, 21216, 21208,     0, 16384, 20480, 20992, 21248, 
+    21184, 21216, 21208, 21210,     0, 16384, 20480, 20992, 
+    21248, 21184, 21216, 21208,     0, 16384, 20480, 20992, 
+    21248, 21184, 21216, 21217, 21212,     0, 16384, 20480, 
+    20992, 21248, 21184, 21216, 21217, 21212,     0, 16384, 
+    20480, 20992, 21248, 21184, 21216, 21217, 21212, 21214, 
+        0, 16384, 20480, 20992, 21248, 21184,     0, 16384, 
+    20480, 20992, 21248, 21249, 21216,     0, 16384, 20480, 
+    20992, 21248, 21249, 21216,     0, 16384, 20480, 20992, 
+    21248, 21249, 21216, 21218,     0, 16384, 20480, 20992, 
+    21248, 21249, 21216,     0, 16384, 20480, 20992, 21248, 
+    21249, 21216, 21220,     0, 16384, 20480, 20992, 21248, 
+    21249, 21216, 21220,     0, 16384, 20480, 20992, 21248, 
+    21249, 21216, 21224, 21222,     0, 16384, 20480, 20992, 
+    21248, 21249, 21216,     0, 16384, 20480, 20992, 21248, 
+    21249, 21216, 21224,     0, 16384, 20480, 20992, 21248, 
+    21249, 21216, 21224,     0, 16384, 20480, 20992, 21248, 
+    21249, 21216, 21224, 21226,     0, 16384, 20480, 20992, 
+    21248, 21249, 21216, 21224,     0, 16384, 20480, 20992, 
+    21248, 21249, 21216, 21232, 21228,     0, 16384, 20480, 
+    20992, 21248, 21249, 21216, 21232, 21228,     0, 16384, 
+    20480, 20992, 21248, 21249, 21216, 21232, 21233, 21230, 
+        0, 16384, 20480, 20992, 21248, 21249, 21216,     0, 
+    16384, 20480, 20992, 21248, 21249, 21216, 21232,     0, 
+    16384, 20480, 20992, 21248, 21249, 21251, 21232,     0, 
+    16384, 20480, 20992, 21248, 21249, 21251, 21232, 21234, 
+        0, 16384, 20480, 20992, 21248, 21249, 21251, 21232, 
+        0, 16384, 20480, 20992, 21248, 21249, 21251, 21232, 
+    21236,     0, 16384, 20480, 20992, 21248, 21249, 21251, 
+    21232, 21236,     0, 16384, 20480, 20992, 21248, 21249, 
+    21251, 21232, 21240, 21238,     0, 16384, 20480, 20992, 
+    21248, 21249, 21251, 21232,     0, 16384, 20480, 20992, 
+    21248, 21249, 21251, 21232, 21240,     0, 16384, 20480, 
+    20992, 21248, 21249, 21251, 21232, 21240,     0, 16384, 
+    20480, 20992, 21248, 21249, 21251, 21232, 21240, 21242, 
+        0, 16384, 20480, 20992, 21248, 21249, 21251, 21255, 
+    21240,     0, 16384, 20480, 20992, 21248, 21249, 21251, 
+    21255, 21240, 21244,     0, 16384, 20480, 20992, 21248, 
+    21249, 21251, 21255, 21240, 21244,     0, 16384, 20480, 
+    20992, 21248, 21249, 21251, 21255, 21240, 21244, 21246, 
+        0, 16384, 20480, 20992,     0, 16384, 20480, 21504, 
+    21248,     0, 16384, 20480, 21504, 21248,     0, 16384, 
+    20480, 21504, 21248, 21250,     0, 16384, 20480, 21504, 
+    21248,     0, 16384, 20480, 21504, 21248, 21252,     0, 
+    16384, 20480, 21504, 21248, 21252,     0, 16384, 20480, 
+    21504, 21248, 21256, 21254,     0, 16384, 20480, 21504, 
+    21248,     0, 16384, 20480, 21504, 21248, 21256,     0, 
+    16384, 20480, 21504, 21248, 21256,     0, 16384, 20480, 
+    21504, 21248, 21256, 21258,     0, 16384, 20480, 21504, 
+    21248, 21256,     0, 16384, 20480, 21504, 21248, 21264, 
+    21260,     0, 16384, 20480, 21504, 21248, 21264, 21260, 
+        0, 16384, 20480, 21504, 21248, 21264, 21265, 21262, 
+        0, 16384, 20480, 21504, 21248,     0, 16384, 20480, 
+    21504, 21248, 21264,     0, 16384, 20480, 21504, 21248, 
+    21264,     0, 16384, 20480, 21504, 21248, 21264, 21266, 
+        0, 16384, 20480, 21504, 21248, 21264,     0, 16384, 
+    20480, 21504, 21248, 21264, 21268,     0, 16384, 20480, 
+    21504, 21248, 21264, 21268,     0, 16384, 20480, 21504, 
+    21248, 21264, 21272, 21270,     0, 16384, 20480, 21504, 
+    21248, 21264,     0, 16384, 20480, 21504, 21248, 21280, 
+    21272,     0, 16384, 20480, 21504, 21248, 21280, 21272, 
+        0, 16384, 20480, 21504, 21248, 21280, 21272, 21274, 
+        0, 16384, 20480, 21504, 21248, 21280, 21272,     0, 
+    16384, 20480, 21504, 21248, 21280, 21281, 21276,     0, 
+    16384, 20480, 21504, 21248, 21280, 21281, 21276,     0, 
+    16384, 20480, 21504, 21248, 21280, 21281, 21276, 21278, 
+        0, 16384, 20480, 21504, 21248,     0, 16384, 20480, 
+    21504, 21248, 21280,     0, 16384, 20480, 21504, 21248, 
+    21280,     0, 16384, 20480, 21504, 21248, 21280, 21282, 
+        0, 16384, 20480, 21504, 21248, 21280,     0, 16384, 
+    20480, 21504, 21248, 21280, 21284,     0, 16384, 20480, 
+    21504, 21248, 21280, 21284,     0, 16384, 20480, 21504, 
+    21248, 21280, 21288, 21286,     0, 16384, 20480, 21504, 
+    21248, 21280,     0, 16384, 20480, 21504, 21248, 21280, 
+    21288,     0, 16384, 20480, 21504, 21248, 21280, 21288, 
+        0, 16384, 20480, 21504, 21248, 21280, 21288, 21290, 
+        0, 16384, 20480, 21504, 21248, 21280, 21288,     0, 
+    16384, 20480, 21504, 21248, 21280, 21296, 21292,     0, 
+    16384, 20480, 21504, 21248, 21280, 21296, 21292,     0, 
+    16384, 20480, 21504, 21248, 21280, 21296, 21297, 21294, 
+        0, 16384, 20480, 21504, 21248, 21280,     0, 16384, 
+    20480, 21504, 21248, 21312, 21296,     0, 16384, 20480, 
+    21504, 21248, 21312, 21296,     0, 16384, 20480, 21504, 
+    21248, 21312, 21296, 21298,     0, 16384, 20480, 21504, 
+    21248, 21312, 21296,     0, 16384, 20480, 21504, 21248, 
+    21312, 21296, 21300,     0, 16384, 20480, 21504, 21248, 
+    21312, 21296, 21300,     0, 16384, 20480, 21504, 21248, 
+    21312, 21296, 21304, 21302,     0, 16384, 20480, 21504, 
+    21248, 21312, 21296,     0, 16384, 20480, 21504, 21248, 
+    21312, 21313, 21304,     0, 16384, 20480, 21504, 21248, 
+    21312, 21313, 21304,     0, 16384, 20480, 21504, 21248, 
+    21312, 21313, 21304, 21306,     0, 16384, 20480, 21504, 
+    21248, 21312, 21313, 21304,     0, 16384, 20480, 21504, 
+    21248, 21312, 21313, 21304, 21308,     0, 16384, 20480, 
+    21504, 21248, 21312, 21313, 21315, 21308,     0, 16384, 
+    20480, 21504, 21248, 21312, 21313, 21315, 21308, 21310, 
+        0, 16384, 20480, 21504, 21248,     0, 16384, 20480, 
+    21504, 21248, 21312,     0, 16384, 20480, 21504, 21248, 
+    21312,     0, 16384, 20480, 21504, 21248, 21312, 21314, 
+        0, 16384, 20480, 21504, 21248, 21312,     0, 16384, 
+    20480, 21504, 21248, 21312, 21316,     0, 16384, 20480, 
+    21504, 21248, 21312, 21316,     0, 16384, 20480, 21504, 
+    21248, 21312, 21320, 21318,     0, 16384, 20480, 21504, 
+    21248, 21312,     0, 16384, 20480, 21504, 21248, 21312, 
+    21320,     0, 16384, 20480, 21504, 21248, 21312, 21320, 
+        0, 16384, 20480, 21504, 21248, 21312, 21320, 21322, 
+        0, 16384, 20480, 21504, 21248, 21312, 21320,     0, 
+    16384, 20480, 21504, 21248, 21312, 21328, 21324,     0, 
+    16384, 20480, 21504, 21248, 21312, 21328, 21324,     0, 
+    16384, 20480, 21504, 21248, 21312, 21328, 21329, 21326, 
+        0, 16384, 20480, 21504, 21248, 21312,     0, 16384, 
+    20480, 21504, 21248, 21312, 21328,     0, 16384, 20480, 
+    21504, 21248, 21312, 21328,     0, 16384, 20480, 21504, 
+    21248, 21312, 21328, 21330,     0, 16384, 20480, 21504, 
+    21248, 21312, 21328,     0, 16384, 20480, 21504, 21248, 
+    21312, 21328, 21332,     0, 16384, 20480, 21504, 21248, 
+    21312, 21328, 21332,     0, 16384, 20480, 21504, 21248, 
+    21312, 21328, 21336, 21334,     0, 16384, 20480, 21504, 
+    21248, 21312, 21328,     0, 16384, 20480, 21504, 21248, 
+    21312, 21344, 21336,     0, 16384, 20480, 21504, 21248, 
+    21312, 21344, 21336,     0, 16384, 20480, 21504, 21248, 
+    21312, 21344, 21336, 21338,     0, 16384, 20480, 21504, 
+    21248, 21312, 21344, 21336,     0, 16384, 20480, 21504, 
+    21248, 21312, 21344, 21345, 21340,     0, 16384, 20480, 
+    21504, 21248, 21312, 21344, 21345, 21340,     0, 16384, 
+    20480, 21504, 21248, 21312, 21344, 21345, 21340, 21342, 
+        0, 16384, 20480, 21504, 21248, 21312,     0, 16384, 
+    20480, 21504, 21248, 21376, 21344,     0, 16384, 20480, 
+    21504, 21248, 21376, 21344,     0, 16384, 20480, 21504, 
+    21248, 21376, 21344, 21346,     0, 16384, 20480, 21504, 
+    21248, 21376, 21344,     0, 16384, 20480, 21504, 21248, 
+    21376, 21344, 21348,     0, 16384, 20480, 21504, 21248, 
+    21376, 21344, 21348,     0, 16384, 20480, 21504, 21248, 
+    21376, 21344, 21352, 21350,     0, 16384, 20480, 21504, 
+    21248, 21376, 21344,     0, 16384, 20480, 21504, 21248, 
+    21376, 21344, 21352,     0, 16384, 20480, 21504, 21248, 
+    21376, 21344, 21352,     0, 16384, 20480, 21504, 21248, 
+    21376, 21344, 21352, 21354,     0, 16384, 20480, 21504, 
+    21248, 21376, 21344, 21352,     0, 16384, 20480, 21504, 
+    21248, 21376, 21344, 21360, 21356,     0, 16384, 20480, 
+    21504, 21248, 21376, 21344, 21360, 21356,     0, 16384, 
+    20480, 21504, 21248, 21376, 21344, 21360, 21361, 21358, 
+        0, 16384, 20480, 21504, 21248, 21376, 21344,     0, 
+    16384, 20480, 21504, 21248, 21376, 21377, 21360,     0, 
+    16384, 20480, 21504, 21248, 21376, 21377, 21360,     0, 
+    16384, 20480, 21504, 21248, 21376, 21377, 21360, 21362, 
+        0, 16384, 20480, 21504, 21248, 21376, 21377, 21360, 
+        0, 16384, 20480, 21504, 21248, 21376, 21377, 21360, 
+    21364,     0, 16384, 20480, 21504, 21248, 21376, 21377, 
+    21360, 21364,     0, 16384, 20480, 21504, 21248, 21376, 
+    21377, 21360, 21368, 21366,     0, 16384, 20480, 21504, 
+    21248, 21376, 21377, 21360,     0, 16384, 20480, 21504, 
+    21248, 21376, 21377, 21360, 21368,     0, 16384, 20480, 
+    21504, 21248, 21376, 21377, 21379, 21368,     0, 16384, 
+    20480, 21504, 21248, 21376, 21377, 21379, 21368, 21370, 
+        0, 16384, 20480, 21504, 21248, 21376, 21377, 21379, 
+    21368,     0, 16384, 20480, 21504, 21248, 21376, 21377, 
+    21379, 21368, 21372,     0, 16384, 20480, 21504, 21248, 
+    21376, 21377, 21379, 21368, 21372,     0, 16384, 20480, 
+    21504, 21248, 21376, 21377, 21379, 21368, 21372, 21374, 
+        0, 16384, 20480, 21504, 21248,     0, 16384, 20480, 
+    21504, 21248, 21376,     0, 16384, 20480, 21504, 21505, 
+    21376,     0, 16384, 20480, 21504, 21505, 21376, 21378, 
+        0, 16384, 20480, 21504, 21505, 21376,     0, 16384, 
+    20480, 21504, 21505, 21376, 21380,     0, 16384, 20480, 
+    21504, 21505, 21376, 21380,     0, 16384, 20480, 21504, 
+    21505, 21376, 21384, 21382,     0, 16384, 20480, 21504, 
+    21505, 21376,     0, 16384, 20480, 21504, 21505, 21376, 
+    21384,     0, 16384, 20480, 21504, 21505, 21376, 21384, 
+        0, 16384, 20480, 21504, 21505, 21376, 21384, 21386, 
+        0, 16384, 20480, 21504, 21505, 21376, 21384,     0, 
+    16384, 20480, 21504, 21505, 21376, 21392, 21388,     0, 
+    16384, 20480, 21504, 21505, 21376, 21392, 21388,     0, 
+    16384, 20480, 21504, 21505, 21376, 21392, 21393, 21390, 
+        0, 16384, 20480, 21504, 21505, 21376,     0, 16384, 
+    20480, 21504, 21505, 21376, 21392,     0, 16384, 20480, 
+    21504, 21505, 21376, 21392,     0, 16384, 20480, 21504, 
+    21505, 21376, 21392, 21394,     0, 16384, 20480, 21504, 
+    21505, 21376, 21392,     0, 16384, 20480, 21504, 21505, 
+    21376, 21392, 21396,     0, 16384, 20480, 21504, 21505, 
+    21376, 21392, 21396,     0, 16384, 20480, 21504, 21505, 
+    21376, 21392, 21400, 21398,     0, 16384, 20480, 21504, 
+    21505, 21376, 21392,     0, 16384, 20480, 21504, 21505, 
+    21376, 21408, 21400,     0, 16384, 20480, 21504, 21505, 
+    21376, 21408, 21400,     0, 16384, 20480, 21504, 21505, 
+    21376, 21408, 21400, 21402,     0, 16384, 20480, 21504, 
+    21505, 21376, 21408, 21400,     0, 16384, 20480, 21504, 
+    21505, 21376, 21408, 21409, 21404,     0, 16384, 20480, 
+    21504, 21505, 21376, 21408, 21409, 21404,     0, 16384, 
+    20480, 21504, 21505, 21376, 21408, 21409, 21404, 21406, 
+        0, 16384, 20480, 21504, 21505, 21376,     0, 16384, 
+    20480, 21504, 21505, 21376, 21408,     0, 16384, 20480, 
+    21504, 21505, 21376, 21408,     0, 16384, 20480, 21504, 
+    21505, 21376, 21408, 21410,     0, 16384, 20480, 21504, 
+    21505, 21376, 21408,     0, 16384, 20480, 21504, 21505, 
+    21376, 21408, 21412,     0, 16384, 20480, 21504, 21505, 
+    21376, 21408, 21412,     0, 16384, 20480, 21504, 21505, 
+    21376, 21408, 21416, 21414,     0, 16384, 20480, 21504, 
+    21505, 21376, 21408,     0, 16384, 20480, 21504, 21505, 
+    21376, 21408, 21416,     0, 16384, 20480, 21504, 21505, 
+    21376, 21408, 21416,     0, 16384, 20480, 21504, 21505, 
+    21376, 21408, 21416, 21418,     0, 16384, 20480, 21504, 
+    21505, 21376, 21408, 21416,     0, 16384, 20480, 21504, 
+    21505, 21376, 21408, 21424, 21420,     0, 16384, 20480, 
+    21504, 21505, 21376, 21408, 21424, 21420,     0, 16384, 
+    20480, 21504, 21505, 21376, 21408, 21424, 21425, 21422, 
+        0, 16384, 20480, 21504, 21505, 21376, 21408,     0, 
+    16384, 20480, 21504, 21505, 21376, 21440, 21424,     0, 
+    16384, 20480, 21504, 21505, 21376, 21440, 21424,     0, 
+    16384, 20480, 21504, 21505, 21376, 21440, 21424, 21426, 
+        0, 16384, 20480, 21504, 21505, 21376, 21440, 21424, 
+        0, 16384, 20480, 21504, 21505, 21376, 21440, 21424, 
+    21428,     0, 16384, 20480, 21504, 21505, 21376, 21440, 
+    21424, 21428,     0, 16384, 20480, 21504, 21505, 21376, 
+    21440, 21424, 21432, 21430,     0, 16384, 20480, 21504, 
+    21505, 21376, 21440, 21424,     0, 16384, 20480, 21504, 
+    21505, 21376, 21440, 21441, 21432,     0, 16384, 20480, 
+    21504, 21505, 21376, 21440, 21441, 21432,     0, 16384, 
+    20480, 21504, 21505, 21376, 21440, 21441, 21432, 21434, 
+        0, 16384, 20480, 21504, 21505, 21376, 21440, 21441, 
+    21432,     0, 16384, 20480, 21504, 21505, 21376, 21440, 
+    21441, 21432, 21436,     0, 16384, 20480, 21504, 21505, 
+    21376, 21440, 21441, 21443, 21436,     0, 16384, 20480, 
+    21504, 21505, 21376, 21440, 21441, 21443, 21436, 21438, 
+        0, 16384, 20480, 21504, 21505, 21376,     0, 16384, 
+    20480, 21504, 21505, 21376, 21440,     0, 16384, 20480, 
+    21504, 21505, 21376, 21440,     0, 16384, 20480, 21504, 
+    21505, 21376, 21440, 21442,     0, 16384, 20480, 21504, 
+    21505, 21507, 21440,     0, 16384, 20480, 21504, 21505, 
+    21507, 21440, 21444,     0, 16384, 20480, 21504, 21505, 
+    21507, 21440, 21444,     0, 16384, 20480, 21504, 21505, 
+    21507, 21440, 21448, 21446,     0, 16384, 20480, 21504, 
+    21505, 21507, 21440,     0, 16384, 20480, 21504, 21505, 
+    21507, 21440, 21448,     0, 16384, 20480, 21504, 21505, 
+    21507, 21440, 21448,     0, 16384, 20480, 21504, 21505, 
+    21507, 21440, 21448, 21450,     0, 16384, 20480, 21504, 
+    21505, 21507, 21440, 21448,     0, 16384, 20480, 21504, 
+    21505, 21507, 21440, 21456, 21452,     0, 16384, 20480, 
+    21504, 21505, 21507, 21440, 21456, 21452,     0, 16384, 
+    20480, 21504, 21505, 21507, 21440, 21456, 21457, 21454, 
+        0, 16384, 20480, 21504, 21505, 21507, 21440,     0, 
+    16384, 20480, 21504, 21505, 21507, 21440, 21456,     0, 
+    16384, 20480, 21504, 21505, 21507, 21440, 21456,     0, 
+    16384, 20480, 21504, 21505, 21507, 21440, 21456, 21458, 
+        0, 16384, 20480, 21504, 21505, 21507, 21440, 21456, 
+        0, 16384, 20480, 21504, 21505, 21507, 21440, 21456, 
+    21460,     0, 16384, 20480, 21504, 21505, 21507, 21440, 
+    21456, 21460,     0, 16384, 20480, 21504, 21505, 21507, 
+    21440, 21456, 21464, 21462,     0, 16384, 20480, 21504, 
+    21505, 21507, 21440, 21456,     0, 16384, 20480, 21504, 
+    21505, 21507, 21440, 21472, 21464,     0, 16384, 20480, 
+    21504, 21505, 21507, 21440, 21472, 21464,     0, 16384, 
+    20480, 21504, 21505, 21507, 21440, 21472, 21464, 21466, 
+        0, 16384, 20480, 21504, 21505, 21507, 21440, 21472, 
+    21464,     0, 16384, 20480, 21504, 21505, 21507, 21440, 
+    21472, 21473, 21468,     0, 16384, 20480, 21504, 21505, 
+    21507, 21440, 21472, 21473, 21468,     0, 16384, 20480, 
+    21504, 21505, 21507, 21440, 21472, 21473, 21468, 21470, 
+        0, 16384, 20480, 21504, 21505, 21507, 21440,     0, 
+    16384, 20480, 21504, 21505, 21507, 21440, 21472,     0, 
+    16384, 20480, 21504, 21505, 21507, 21440, 21472,     0, 
+    16384, 20480, 21504, 21505, 21507, 21440, 21472, 21474, 
+        0, 16384, 20480, 21504, 21505, 21507, 21440, 21472, 
+        0, 16384, 20480, 21504, 21505, 21507, 21440, 21472, 
+    21476,     0, 16384, 20480, 21504, 21505, 21507, 21440, 
+    21472, 21476,     0, 16384, 20480, 21504, 21505, 21507, 
+    21440, 21472, 21480, 21478,     0, 16384, 20480, 21504, 
+    21505, 21507, 21511, 21472,     0, 16384, 20480, 21504, 
+    21505, 21507, 21511, 21472, 21480,     0, 16384, 20480, 
+    21504, 21505, 21507, 21511, 21472, 21480,     0, 16384, 
+    20480, 21504, 21505, 21507, 21511, 21472, 21480, 21482, 
+        0, 16384, 20480, 21504, 21505, 21507, 21511, 21472, 
+    21480,     0, 16384, 20480, 21504, 21505, 21507, 21511, 
+    21472, 21488, 21484,     0, 16384, 20480, 21504, 21505, 
+    21507, 21511, 21472, 21488, 21484,     0, 16384, 20480, 
+    21504, 21505, 21507, 21511, 21472, 21488, 21489, 21486, 
+        0, 16384, 20480, 21504, 21505, 21507, 21511, 21472, 
+        0, 16384, 20480, 21504, 21505, 21507, 21511, 21472, 
+    21488,     0, 16384, 20480, 21504, 21505, 21507, 21511, 
+    21472, 21488,     0, 16384, 20480, 21504, 21505, 21507, 
+    21511, 21472, 21488, 21490,     0, 16384, 20480, 21504, 
+    21505, 21507, 21511, 21472, 21488,     0, 16384, 20480, 
+    21504, 21505, 21507, 21511, 21472, 21488, 21492,     0, 
+    16384, 20480, 21504, 21505, 21507, 21511, 21472, 21488, 
+    21492,     0, 16384, 20480, 21504, 21505, 21507, 21511, 
+    21472, 21488, 21496, 21494,     0, 16384, 20480, 21504, 
+    21505, 21507, 21511, 21472, 21488,     0, 16384, 20480, 
+    21504, 21505, 21507, 21511, 21472, 21488, 21496,     0, 
+    16384, 20480, 21504, 21505, 21507, 21511, 21472, 21488, 
+    21496,     0, 16384, 20480, 21504, 21505, 21507, 21511, 
+    21472, 21488, 21496, 21498,     0, 16384, 20480, 21504, 
+    21505, 21507, 21511, 21472, 21488, 21496,     0, 16384, 
+    20480, 21504, 21505, 21507, 21511, 21472, 21488, 21496, 
+    21500,     0, 16384, 20480, 21504, 21505, 21507, 21511, 
+    21472, 21488, 21496, 21500,     0, 16384, 20480, 21504, 
+    21505, 21507, 21511, 21472, 21488, 21496, 21500, 21502, 
+        0, 16384, 20480,     0, 16384, 20480, 21504,     0, 
+    16384, 20480, 21504,     0, 16384, 20480, 21504, 21506, 
+        0, 16384, 20480, 21504,     0, 16384, 20480, 21504, 
+    21508,     0, 16384, 20480, 21504, 21508,     0, 16384, 
+    20480, 21504, 21512, 21510,     0, 16384, 20480, 21504, 
+        0, 16384, 20480, 21504, 21512,     0, 16384, 20480, 
+    21504, 21512,     0, 16384, 20480, 21504, 21512, 21514, 
+        0, 16384, 20480, 21504, 21512,     0, 16384, 20480, 
+    21504, 21520, 21516,     0, 16384, 20480, 21504, 21520, 
+    21516,     0, 16384, 20480, 21504, 21520, 21521, 21518, 
+        0, 16384, 20480, 21504,     0, 16384, 20480, 21504, 
+    21520,     0, 16384, 20480, 21504, 21520,     0, 16384, 
+    20480, 21504, 21520, 21522,     0, 16384, 20480, 21504, 
+    21520,     0, 16384, 20480, 21504, 21520, 21524,     0, 
+    16384, 20480, 21504, 21520, 21524,     0, 16384, 20480, 
+    21504, 21520, 21528, 21526,     0, 16384, 20480, 21504, 
+    21520,     0, 16384, 20480, 21504, 21536, 21528,     0, 
+    16384, 20480, 21504, 21536, 21528,     0, 16384, 20480, 
+    21504, 21536, 21528, 21530,     0, 16384, 20480, 21504, 
+    21536, 21528,     0, 16384, 20480, 21504, 21536, 21537, 
+    21532,     0, 16384, 20480, 21504, 21536, 21537, 21532, 
+        0, 16384, 20480, 21504, 21536, 21537, 21532, 21534, 
+        0, 16384, 20480, 21504,     0, 16384, 20480, 21504, 
+    21536,     0, 16384, 20480, 21504, 21536,     0, 16384, 
+    20480, 21504, 21536, 21538,     0, 16384, 20480, 21504, 
+    21536,     0, 16384, 20480, 21504, 21536, 21540,     0, 
+    16384, 20480, 21504, 21536, 21540,     0, 16384, 20480, 
+    21504, 21536, 21544, 21542,     0, 16384, 20480, 21504, 
+    21536,     0, 16384, 20480, 21504, 21536, 21544,     0, 
+    16384, 20480, 21504, 21536, 21544,     0, 16384, 20480, 
+    21504, 21536, 21544, 21546,     0, 16384, 20480, 21504, 
+    21536, 21544,     0, 16384, 20480, 21504, 21536, 21552, 
+    21548,     0, 16384, 20480, 21504, 21536, 21552, 21548, 
+        0, 16384, 20480, 21504, 21536, 21552, 21553, 21550, 
+        0, 16384, 20480, 21504, 21536,     0, 16384, 20480, 
+    21504, 21568, 21552,     0, 16384, 20480, 21504, 21568, 
+    21552,     0, 16384, 20480, 21504, 21568, 21552, 21554, 
+        0, 16384, 20480, 21504, 21568, 21552,     0, 16384, 
+    20480, 21504, 21568, 21552, 21556,     0, 16384, 20480, 
+    21504, 21568, 21552, 21556,     0, 16384, 20480, 21504, 
+    21568, 21552, 21560, 21558,     0, 16384, 20480, 21504, 
+    21568, 21552,     0, 16384, 20480, 21504, 21568, 21569, 
+    21560,     0, 16384, 20480, 21504, 21568, 21569, 21560, 
+        0, 16384, 20480, 21504, 21568, 21569, 21560, 21562, 
+        0, 16384, 20480, 21504, 21568, 21569, 21560,     0, 
+    16384, 20480, 21504, 21568, 21569, 21560, 21564,     0, 
+    16384, 20480, 21504, 21568, 21569, 21571, 21564,     0, 
+    16384, 20480, 21504, 21568, 21569, 21571, 21564, 21566, 
+        0, 16384, 20480, 21504,     0, 16384, 20480, 21504, 
+    21568,     0, 16384, 20480, 21504, 21568,     0, 16384, 
+    20480, 21504, 21568, 21570,     0, 16384, 20480, 21504, 
+    21568,     0, 16384, 20480, 21504, 21568, 21572,     0, 
+    16384, 20480, 21504, 21568, 21572,     0, 16384, 20480, 
+    21504, 21568, 21576, 21574,     0, 16384, 20480, 21504, 
+    21568,     0, 16384, 20480, 21504, 21568, 21576,     0, 
+    16384, 20480, 21504, 21568, 21576,     0, 16384, 20480, 
+    21504, 21568, 21576, 21578,     0, 16384, 20480, 21504, 
+    21568, 21576,     0, 16384, 20480, 21504, 21568, 21584, 
+    21580,     0, 16384, 20480, 21504, 21568, 21584, 21580, 
+        0, 16384, 20480, 21504, 21568, 21584, 21585, 21582, 
+        0, 16384, 20480, 21504, 21568,     0, 16384, 20480, 
+    21504, 21568, 21584,     0, 16384, 20480, 21504, 21568, 
+    21584,     0, 16384, 20480, 21504, 21568, 21584, 21586, 
+        0, 16384, 20480, 21504, 21568, 21584,     0, 16384, 
+    20480, 21504, 21568, 21584, 21588,     0, 16384, 20480, 
+    21504, 21568, 21584, 21588,     0, 16384, 20480, 21504, 
+    21568, 21584, 21592, 21590,     0, 16384, 20480, 21504, 
+    21568, 21584,     0, 16384, 20480, 21504, 21568, 21600, 
+    21592,     0, 16384, 20480, 21504, 21568, 21600, 21592, 
+        0, 16384, 20480, 21504, 21568, 21600, 21592, 21594, 
+        0, 16384, 20480, 21504, 21568, 21600, 21592,     0, 
+    16384, 20480, 21504, 21568, 21600, 21601, 21596,     0, 
+    16384, 20480, 21504, 21568, 21600, 21601, 21596,     0, 
+    16384, 20480, 21504, 21568, 21600, 21601, 21596, 21598, 
+        0, 16384, 20480, 21504, 21568,     0, 16384, 20480, 
+    21504, 21632, 21600,     0, 16384, 20480, 21504, 21632, 
+    21600,     0, 16384, 20480, 21504, 21632, 21600, 21602, 
+        0, 16384, 20480, 21504, 21632, 21600,     0, 16384, 
+    20480, 21504, 21632, 21600, 21604,     0, 16384, 20480, 
+    21504, 21632, 21600, 21604,     0, 16384, 20480, 21504, 
+    21632, 21600, 21608, 21606,     0, 16384, 20480, 21504, 
+    21632, 21600,     0, 16384, 20480, 21504, 21632, 21600, 
+    21608,     0, 16384, 20480, 21504, 21632, 21600, 21608, 
+        0, 16384, 20480, 21504, 21632, 21600, 21608, 21610, 
+        0, 16384, 20480, 21504, 21632, 21600, 21608,     0, 
+    16384, 20480, 21504, 21632, 21600, 21616, 21612,     0, 
+    16384, 20480, 21504, 21632, 21600, 21616, 21612,     0, 
+    16384, 20480, 21504, 21632, 21600, 21616, 21617, 21614, 
+        0, 16384, 20480, 21504, 21632, 21600,     0, 16384, 
+    20480, 21504, 21632, 21633, 21616,     0, 16384, 20480, 
+    21504, 21632, 21633, 21616,     0, 16384, 20480, 21504, 
+    21632, 21633, 21616, 21618,     0, 16384, 20480, 21504, 
+    21632, 21633, 21616,     0, 16384, 20480, 21504, 21632, 
+    21633, 21616, 21620,     0, 16384, 20480, 21504, 21632, 
+    21633, 21616, 21620,     0, 16384, 20480, 21504, 21632, 
+    21633, 21616, 21624, 21622,     0, 16384, 20480, 21504, 
+    21632, 21633, 21616,     0, 16384, 20480, 21504, 21632, 
+    21633, 21616, 21624,     0, 16384, 20480, 21504, 21632, 
+    21633, 21635, 21624,     0, 16384, 20480, 21504, 21632, 
+    21633, 21635, 21624, 21626,     0, 16384, 20480, 21504, 
+    21632, 21633, 21635, 21624,     0, 16384, 20480, 21504, 
+    21632, 21633, 21635, 21624, 21628,     0, 16384, 20480, 
+    21504, 21632, 21633, 21635, 21624, 21628,     0, 16384, 
+    20480, 21504, 21632, 21633, 21635, 21624, 21628, 21630, 
+        0, 16384, 20480, 21504,     0, 16384, 20480, 21504, 
+    21632,     0, 16384, 20480, 21504, 21632,     0, 16384, 
+    20480, 21504, 21632, 21634,     0, 16384, 20480, 21504, 
+    21632,     0, 16384, 20480, 21504, 21632, 21636,     0, 
+    16384, 20480, 21504, 21632, 21636,     0, 16384, 20480, 
+    21504, 21632, 21640, 21638,     0, 16384, 20480, 21504, 
+    21632,     0, 16384, 20480, 21504, 21632, 21640,     0, 
+    16384, 20480, 21504, 21632, 21640,     0, 16384, 20480, 
+    21504, 21632, 21640, 21642,     0, 16384, 20480, 21504, 
+    21632, 21640,     0, 16384, 20480, 21504, 21632, 21648, 
+    21644,     0, 16384, 20480, 21504, 21632, 21648, 21644, 
+        0, 16384, 20480, 21504, 21632, 21648, 21649, 21646, 
+        0, 16384, 20480, 21504, 21632,     0, 16384, 20480, 
+    21504, 21632, 21648,     0, 16384, 20480, 21504, 21632, 
+    21648,     0, 16384, 20480, 21504, 21632, 21648, 21650, 
+        0, 16384, 20480, 21504, 21632, 21648,     0, 16384, 
+    20480, 21504, 21632, 21648, 21652,     0, 16384, 20480, 
+    21504, 21632, 21648, 21652,     0, 16384, 20480, 21504, 
+    21632, 21648, 21656, 21654,     0, 16384, 20480, 21504, 
+    21632, 21648,     0, 16384, 20480, 21504, 21632, 21664, 
+    21656,     0, 16384, 20480, 21504, 21632, 21664, 21656, 
+        0, 16384, 20480, 21504, 21632, 21664, 21656, 21658, 
+        0, 16384, 20480, 21504, 21632, 21664, 21656,     0, 
+    16384, 20480, 21504, 21632, 21664, 21665, 21660,     0, 
+    16384, 20480, 21504, 21632, 21664, 21665, 21660,     0, 
+    16384, 20480, 21504, 21632, 21664, 21665, 21660, 21662, 
+        0, 16384, 20480, 21504, 21632,     0, 16384, 20480, 
+    21504, 21632, 21664,     0, 16384, 20480, 21504, 21632, 
+    21664,     0, 16384, 20480, 21504, 21632, 21664, 21666, 
+        0, 16384, 20480, 21504, 21632, 21664,     0, 16384, 
+    20480, 21504, 21632, 21664, 21668,     0, 16384, 20480, 
+    21504, 21632, 21664, 21668,     0, 16384, 20480, 21504, 
+    21632, 21664, 21672, 21670,     0, 16384, 20480, 21504, 
+    21632, 21664,     0, 16384, 20480, 21504, 21632, 21664, 
+    21672,     0, 16384, 20480, 21504, 21632, 21664, 21672, 
+        0, 16384, 20480, 21504, 21632, 21664, 21672, 21674, 
+        0, 16384, 20480, 21504, 21632, 21664, 21672,     0, 
+    16384, 20480, 21504, 21632, 21664, 21680, 21676,     0, 
+    16384, 20480, 21504, 21632, 21664, 21680, 21676,     0, 
+    16384, 20480, 21504, 21632, 21664, 21680, 21681, 21678, 
+        0, 16384, 20480, 21504, 21632, 21664,     0, 16384, 
+    20480, 21504, 21632, 21696, 21680,     0, 16384, 20480, 
+    21504, 21632, 21696, 21680,     0, 16384, 20480, 21504, 
+    21632, 21696, 21680, 21682,     0, 16384, 20480, 21504, 
+    21632, 21696, 21680,     0, 16384, 20480, 21504, 21632, 
+    21696, 21680, 21684,     0, 16384, 20480, 21504, 21632, 
+    21696, 21680, 21684,     0, 16384, 20480, 21504, 21632, 
+    21696, 21680, 21688, 21686,     0, 16384, 20480, 21504, 
+    21632, 21696, 21680,     0, 16384, 20480, 21504, 21632, 
+    21696, 21697, 21688,     0, 16384, 20480, 21504, 21632, 
+    21696, 21697, 21688,     0, 16384, 20480, 21504, 21632, 
+    21696, 21697, 21688, 21690,     0, 16384, 20480, 21504, 
+    21632, 21696, 21697, 21688,     0, 16384, 20480, 21504, 
+    21632, 21696, 21697, 21688, 21692,     0, 16384, 20480, 
+    21504, 21632, 21696, 21697, 21699, 21692,     0, 16384, 
+    20480, 21504, 21632, 21696, 21697, 21699, 21692, 21694, 
+        0, 16384, 20480, 21504, 21632,     0, 16384, 20480, 
+    21504, 21760, 21696,     0, 16384, 20480, 21504, 21760, 
+    21696,     0, 16384, 20480, 21504, 21760, 21696, 21698, 
+        0, 16384, 20480, 21504, 21760, 21696,     0, 16384, 
+    20480, 21504, 21760, 21696, 21700,     0, 16384, 20480, 
+    21504, 21760, 21696, 21700,     0, 16384, 20480, 21504, 
+    21760, 21696, 21704, 21702,     0, 16384, 20480, 21504, 
+    21760, 21696,     0, 16384, 20480, 21504, 21760, 21696, 
+    21704,     0, 16384, 20480, 21504, 21760, 21696, 21704, 
+        0, 16384, 20480, 21504, 21760, 21696, 21704, 21706, 
+        0, 16384, 20480, 21504, 21760, 21696, 21704,     0, 
+    16384, 20480, 21504, 21760, 21696, 21712, 21708,     0, 
+    16384, 20480, 21504, 21760, 21696, 21712, 21708,     0, 
+    16384, 20480, 21504, 21760, 21696, 21712, 21713, 21710, 
+        0, 16384, 20480, 21504, 21760, 21696,     0, 16384, 
+    20480, 21504, 21760, 21696, 21712,     0, 16384, 20480, 
+    21504, 21760, 21696, 21712,     0, 16384, 20480, 21504, 
+    21760, 21696, 21712, 21714,     0, 16384, 20480, 21504, 
+    21760, 21696, 21712,     0, 16384, 20480, 21504, 21760, 
+    21696, 21712, 21716,     0, 16384, 20480, 21504, 21760, 
+    21696, 21712, 21716,     0, 16384, 20480, 21504, 21760, 
+    21696, 21712, 21720, 21718,     0, 16384, 20480, 21504, 
+    21760, 21696, 21712,     0, 16384, 20480, 21504, 21760, 
+    21696, 21728, 21720,     0, 16384, 20480, 21504, 21760, 
+    21696, 21728, 21720,     0, 16384, 20480, 21504, 21760, 
+    21696, 21728, 21720, 21722,     0, 16384, 20480, 21504, 
+    21760, 21696, 21728, 21720,     0, 16384, 20480, 21504, 
+    21760, 21696, 21728, 21729, 21724,     0, 16384, 20480, 
+    21504, 21760, 21696, 21728, 21729, 21724,     0, 16384, 
+    20480, 21504, 21760, 21696, 21728, 21729, 21724, 21726, 
+        0, 16384, 20480, 21504, 21760, 21696,     0, 16384, 
+    20480, 21504, 21760, 21761, 21728,     0, 16384, 20480, 
+    21504, 21760, 21761, 21728,     0, 16384, 20480, 21504, 
+    21760, 21761, 21728, 21730,     0, 16384, 20480, 21504, 
+    21760, 21761, 21728,     0, 16384, 20480, 21504, 21760, 
+    21761, 21728, 21732,     0, 16384, 20480, 21504, 21760, 
+    21761, 21728, 21732,     0, 16384, 20480, 21504, 21760, 
+    21761, 21728, 21736, 21734,     0, 16384, 20480, 21504, 
+    21760, 21761, 21728,     0, 16384, 20480, 21504, 21760, 
+    21761, 21728, 21736,     0, 16384, 20480, 21504, 21760, 
+    21761, 21728, 21736,     0, 16384, 20480, 21504, 21760, 
+    21761, 21728, 21736, 21738,     0, 16384, 20480, 21504, 
+    21760, 21761, 21728, 21736,     0, 16384, 20480, 21504, 
+    21760, 21761, 21728, 21744, 21740,     0, 16384, 20480, 
+    21504, 21760, 21761, 21728, 21744, 21740,     0, 16384, 
+    20480, 21504, 21760, 21761, 21728, 21744, 21745, 21742, 
+        0, 16384, 20480, 21504, 21760, 21761, 21728,     0, 
+    16384, 20480, 21504, 21760, 21761, 21728, 21744,     0, 
+    16384, 20480, 21504, 21760, 21761, 21763, 21744,     0, 
+    16384, 20480, 21504, 21760, 21761, 21763, 21744, 21746, 
+        0, 16384, 20480, 21504, 21760, 21761, 21763, 21744, 
+        0, 16384, 20480, 21504, 21760, 21761, 21763, 21744, 
+    21748,     0, 16384, 20480, 21504, 21760, 21761, 21763, 
+    21744, 21748,     0, 16384, 20480, 21504, 21760, 21761, 
+    21763, 21744, 21752, 21750,     0, 16384, 20480, 21504, 
+    21760, 21761, 21763, 21744,     0, 16384, 20480, 21504, 
+    21760, 21761, 21763, 21744, 21752,     0, 16384, 20480, 
+    21504, 21760, 21761, 21763, 21744, 21752,     0, 16384, 
+    20480, 21504, 21760, 21761, 21763, 21744, 21752, 21754, 
+        0, 16384, 20480, 21504, 21760, 21761, 21763, 21767, 
+    21752,     0, 16384, 20480, 21504, 21760, 21761, 21763, 
+    21767, 21752, 21756,     0, 16384, 20480, 21504, 21760, 
+    21761, 21763, 21767, 21752, 21756,     0, 16384, 20480, 
+    21504, 21760, 21761, 21763, 21767, 21752, 21756, 21758, 
+        0, 16384, 20480, 21504,     0, 16384, 20480, 21504, 
+    21760,     0, 16384, 20480, 21504, 21760,     0, 16384, 
+    20480, 21504, 21760, 21762,     0, 16384, 20480, 21504, 
+    21760,     0, 16384, 20480, 21504, 21760, 21764,     0, 
+    16384, 20480, 21504, 21760, 21764,     0, 16384, 20480, 
+    21504, 21760, 21768, 21766,     0, 16384, 20480, 21504, 
+    21760,     0, 16384, 20480, 21504, 21760, 21768,     0, 
+    16384, 20480, 21504, 21760, 21768,     0, 16384, 20480, 
+    21504, 21760, 21768, 21770,     0, 16384, 20480, 21504, 
+    21760, 21768,     0, 16384, 20480, 21504, 21760, 21776, 
+    21772,     0, 16384, 20480, 21504, 21760, 21776, 21772, 
+        0, 16384, 20480, 21504, 21760, 21776, 21777, 21774, 
+        0, 16384, 20480, 21504, 21760,     0, 16384, 20480, 
+    21504, 21760, 21776,     0, 16384, 20480, 21504, 21760, 
+    21776,     0, 16384, 20480, 21504, 21760, 21776, 21778, 
+        0, 16384, 20480, 21504, 21760, 21776,     0, 16384, 
+    20480, 21504, 21760, 21776, 21780,     0, 16384, 20480, 
+    21504, 21760, 21776, 21780,     0, 16384, 20480, 21504, 
+    21760, 21776, 21784, 21782,     0, 16384, 20480, 21504, 
+    21760, 21776,     0, 16384, 20480, 21504, 21760, 21792, 
+    21784,     0, 16384, 20480, 21504, 21760, 21792, 21784, 
+        0, 16384, 20480, 21504, 21760, 21792, 21784, 21786, 
+        0, 16384, 20480, 21504, 21760, 21792, 21784,     0, 
+    16384, 20480, 21504, 21760, 21792, 21793, 21788,     0, 
+    16384, 20480, 21504, 21760, 21792, 21793, 21788,     0, 
+    16384, 20480, 21504, 21760, 21792, 21793, 21788, 21790, 
+        0, 16384, 20480, 21504, 21760,     0, 16384, 20480, 
+    21504, 21760, 21792,     0, 16384, 20480, 21504, 21760, 
+    21792,     0, 16384, 20480, 21504, 21760, 21792, 21794, 
+        0, 16384, 20480, 21504, 21760, 21792,     0, 16384, 
+    20480, 21504, 21760, 21792, 21796,     0, 16384, 20480, 
+    21504, 21760, 21792, 21796,     0, 16384, 20480, 21504, 
+    21760, 21792, 21800, 21798,     0, 16384, 20480, 21504, 
+    21760, 21792,     0, 16384, 20480, 21504, 21760, 21792, 
+    21800,     0, 16384, 20480, 21504, 21760, 21792, 21800, 
+        0, 16384, 20480, 21504, 21760, 21792, 21800, 21802, 
+        0, 16384, 20480, 21504, 21760, 21792, 21800,     0, 
+    16384, 20480, 21504, 21760, 21792, 21808, 21804,     0, 
+    16384, 20480, 21504, 21760, 21792, 21808, 21804,     0, 
+    16384, 20480, 21504, 21760, 21792, 21808, 21809, 21806, 
+        0, 16384, 20480, 21504, 21760, 21792,     0, 16384, 
+    20480, 21504, 21760, 21824, 21808,     0, 16384, 20480, 
+    21504, 21760, 21824, 21808,     0, 16384, 20480, 21504, 
+    21760, 21824, 21808, 21810,     0, 16384, 20480, 21504, 
+    21760, 21824, 21808,     0, 16384, 20480, 21504, 21760, 
+    21824, 21808, 21812,     0, 16384, 20480, 21504, 21760, 
+    21824, 21808, 21812,     0, 16384, 20480, 21504, 21760, 
+    21824, 21808, 21816, 21814,     0, 16384, 20480, 21504, 
+    21760, 21824, 21808,     0, 16384, 20480, 21504, 21760, 
+    21824, 21825, 21816,     0, 16384, 20480, 21504, 21760, 
+    21824, 21825, 21816,     0, 16384, 20480, 21504, 21760, 
+    21824, 21825, 21816, 21818,     0, 16384, 20480, 21504, 
+    21760, 21824, 21825, 21816,     0, 16384, 20480, 21504, 
+    21760, 21824, 21825, 21816, 21820,     0, 16384, 20480, 
+    21504, 21760, 21824, 21825, 21827, 21820,     0, 16384, 
+    20480, 21504, 21760, 21824, 21825, 21827, 21820, 21822, 
+        0, 16384, 20480, 21504, 21760,     0, 16384, 20480, 
+    21504, 21760, 21824,     0, 16384, 20480, 21504, 21760, 
+    21824,     0, 16384, 20480, 21504, 21760, 21824, 21826, 
+        0, 16384, 20480, 21504, 21760, 21824,     0, 16384, 
+    20480, 21504, 21760, 21824, 21828,     0, 16384, 20480, 
+    21504, 21760, 21824, 21828,     0, 16384, 20480, 21504, 
+    21760, 21824, 21832, 21830,     0, 16384, 20480, 21504, 
+    21760, 21824,     0, 16384, 20480, 21504, 21760, 21824, 
+    21832,     0, 16384, 20480, 21504, 21760, 21824, 21832, 
+        0, 16384, 20480, 21504, 21760, 21824, 21832, 21834, 
+        0, 16384, 20480, 21504, 21760, 21824, 21832,     0, 
+    16384, 20480, 21504, 21760, 21824, 21840, 21836,     0, 
+    16384, 20480, 21504, 21760, 21824, 21840, 21836,     0, 
+    16384, 20480, 21504, 21760, 21824, 21840, 21841, 21838, 
+        0, 16384, 20480, 21504, 21760, 21824,     0, 16384, 
+    20480, 21504, 21760, 21824, 21840,     0, 16384, 20480, 
+    21504, 21760, 21824, 21840,     0, 16384, 20480, 21504, 
+    21760, 21824, 21840, 21842,     0, 16384, 20480, 21504, 
+    21760, 21824, 21840,     0, 16384, 20480, 21504, 21760, 
+    21824, 21840, 21844,     0, 16384, 20480, 21504, 21760, 
+    21824, 21840, 21844,     0, 16384, 20480, 21504, 21760, 
+    21824, 21840, 21848, 21846,     0, 16384, 20480, 21504, 
+    21760, 21824, 21840,     0, 16384, 20480, 21504, 21760, 
+    21824, 21856, 21848,     0, 16384, 20480, 21504, 21760, 
+    21824, 21856, 21848,     0, 16384, 20480, 21504, 21760, 
+    21824, 21856, 21848, 21850,     0, 16384, 20480, 21504, 
+    21760, 21824, 21856, 21848,     0, 16384, 20480, 21504, 
+    21760, 21824, 21856, 21857, 21852,     0, 16384, 20480, 
+    21504, 21760, 21824, 21856, 21857, 21852,     0, 16384, 
+    20480, 21504, 21760, 21824, 21856, 21857, 21852, 21854, 
+        0, 16384, 20480, 21504, 21760, 21824,     0, 16384, 
+    20480, 21504, 21760, 21888, 21856,     0, 16384, 20480, 
+    21504, 21760, 21888, 21856,     0, 16384, 20480, 21504, 
+    21760, 21888, 21856, 21858,     0, 16384, 20480, 21504, 
+    21760, 21888, 21856,     0, 16384, 20480, 21504, 21760, 
+    21888, 21856, 21860,     0, 16384, 20480, 21504, 21760, 
+    21888, 21856, 21860,     0, 16384, 20480, 21504, 21760, 
+    21888, 21856, 21864, 21862,     0, 16384, 20480, 21504, 
+    21760, 21888, 21856,     0, 16384, 20480, 21504, 21760, 
+    21888, 21856, 21864,     0, 16384, 20480, 21504, 21760, 
+    21888, 21856, 21864,     0, 16384, 20480, 21504, 21760, 
+    21888, 21856, 21864, 21866,     0, 16384, 20480, 21504, 
+    21760, 21888, 21856, 21864,     0, 16384, 20480, 21504, 
+    21760, 21888, 21856, 21872, 21868,     0, 16384, 20480, 
+    21504, 21760, 21888, 21856, 21872, 21868,     0, 16384, 
+    20480, 21504, 21760, 21888, 21856, 21872, 21873, 21870, 
+        0, 16384, 20480, 21504, 21760, 21888, 21856,     0, 
+    16384, 20480, 21504, 21760, 21888, 21889, 21872,     0, 
+    16384, 20480, 21504, 21760, 21888, 21889, 21872,     0, 
+    16384, 20480, 21504, 21760, 21888, 21889, 21872, 21874, 
+        0, 16384, 20480, 21504, 21760, 21888, 21889, 21872, 
+        0, 16384, 20480, 21504, 21760, 21888, 21889, 21872, 
+    21876,     0, 16384, 20480, 21504, 21760, 21888, 21889, 
+    21872, 21876,     0, 16384, 20480, 21504, 21760, 21888, 
+    21889, 21872, 21880, 21878,     0, 16384, 20480, 21504, 
+    21760, 21888, 21889, 21872,     0, 16384, 20480, 21504, 
+    21760, 21888, 21889, 21872, 21880,     0, 16384, 20480, 
+    21504, 21760, 21888, 21889, 21891, 21880,     0, 16384, 
+    20480, 21504, 21760, 21888, 21889, 21891, 21880, 21882, 
+        0, 16384, 20480, 21504, 21760, 21888, 21889, 21891, 
+    21880,     0, 16384, 20480, 21504, 21760, 21888, 21889, 
+    21891, 21880, 21884,     0, 16384, 20480, 21504, 21760, 
+    21888, 21889, 21891, 21880, 21884,     0, 16384, 20480, 
+    21504, 21760, 21888, 21889, 21891, 21880, 21884, 21886, 
+        0, 16384, 20480, 21504, 21760,     0, 16384, 20480, 
+    21504, 22016, 21888,     0, 16384, 20480, 21504, 22016, 
+    21888,     0, 16384, 20480, 21504, 22016, 21888, 21890, 
+        0, 16384, 20480, 21504, 22016, 21888,     0, 16384, 
+    20480, 21504, 22016, 21888, 21892,     0, 16384, 20480, 
+    21504, 22016, 21888, 21892,     0, 16384, 20480, 21504, 
+    22016, 21888, 21896, 21894,     0, 16384, 20480, 21504, 
+    22016, 21888,     0, 16384, 20480, 21504, 22016, 21888, 
+    21896,     0, 16384, 20480, 21504, 22016, 21888, 21896, 
+        0, 16384, 20480, 21504, 22016, 21888, 21896, 21898, 
+        0, 16384, 20480, 21504, 22016, 21888, 21896,     0, 
+    16384, 20480, 21504, 22016, 21888, 21904, 21900,     0, 
+    16384, 20480, 21504, 22016, 21888, 21904, 21900,     0, 
+    16384, 20480, 21504, 22016, 21888, 21904, 21905, 21902, 
+        0, 16384, 20480, 21504, 22016, 21888,     0, 16384, 
+    20480, 21504, 22016, 21888, 21904,     0, 16384, 20480, 
+    21504, 22016, 21888, 21904,     0, 16384, 20480, 21504, 
+    22016, 21888, 21904, 21906,     0, 16384, 20480, 21504, 
+    22016, 21888, 21904,     0, 16384, 20480, 21504, 22016, 
+    21888, 21904, 21908,     0, 16384, 20480, 21504, 22016, 
+    21888, 21904, 21908,     0, 16384, 20480, 21504, 22016, 
+    21888, 21904, 21912, 21910,     0, 16384, 20480, 21504, 
+    22016, 21888, 21904,     0, 16384, 20480, 21504, 22016, 
+    21888, 21920, 21912,     0, 16384, 20480, 21504, 22016, 
+    21888, 21920, 21912,     0, 16384, 20480, 21504, 22016, 
+    21888, 21920, 21912, 21914,     0, 16384, 20480, 21504, 
+    22016, 21888, 21920, 21912,     0, 16384, 20480, 21504, 
+    22016, 21888, 21920, 21921, 21916,     0, 16384, 20480, 
+    21504, 22016, 21888, 21920, 21921, 21916,     0, 16384, 
+    20480, 21504, 22016, 21888, 21920, 21921, 21916, 21918, 
+        0, 16384, 20480, 21504, 22016, 21888,     0, 16384, 
+    20480, 21504, 22016, 21888, 21920,     0, 16384, 20480, 
+    21504, 22016, 21888, 21920,     0, 16384, 20480, 21504, 
+    22016, 21888, 21920, 21922,     0, 16384, 20480, 21504, 
+    22016, 21888, 21920,     0, 16384, 20480, 21504, 22016, 
+    21888, 21920, 21924,     0, 16384, 20480, 21504, 22016, 
+    21888, 21920, 21924,     0, 16384, 20480, 21504, 22016, 
+    21888, 21920, 21928, 21926,     0, 16384, 20480, 21504, 
+    22016, 21888, 21920,     0, 16384, 20480, 21504, 22016, 
+    21888, 21920, 21928,     0, 16384, 20480, 21504, 22016, 
+    21888, 21920, 21928,     0, 16384, 20480, 21504, 22016, 
+    21888, 21920, 21928, 21930,     0, 16384, 20480, 21504, 
+    22016, 21888, 21920, 21928,     0, 16384, 20480, 21504, 
+    22016, 21888, 21920, 21936, 21932,     0, 16384, 20480, 
+    21504, 22016, 21888, 21920, 21936, 21932,     0, 16384, 
+    20480, 21504, 22016, 21888, 21920, 21936, 21937, 21934, 
+        0, 16384, 20480, 21504, 22016, 21888, 21920,     0, 
+    16384, 20480, 21504, 22016, 21888, 21952, 21936,     0, 
+    16384, 20480, 21504, 22016, 21888, 21952, 21936,     0, 
+    16384, 20480, 21504, 22016, 21888, 21952, 21936, 21938, 
+        0, 16384, 20480, 21504, 22016, 21888, 21952, 21936, 
+        0, 16384, 20480, 21504, 22016, 21888, 21952, 21936, 
+    21940,     0, 16384, 20480, 21504, 22016, 21888, 21952, 
+    21936, 21940,     0, 16384, 20480, 21504, 22016, 21888, 
+    21952, 21936, 21944, 21942,     0, 16384, 20480, 21504, 
+    22016, 21888, 21952, 21936,     0, 16384, 20480, 21504, 
+    22016, 21888, 21952, 21953, 21944,     0, 16384, 20480, 
+    21504, 22016, 21888, 21952, 21953, 21944,     0, 16384, 
+    20480, 21504, 22016, 21888, 21952, 21953, 21944, 21946, 
+        0, 16384, 20480, 21504, 22016, 21888, 21952, 21953, 
+    21944,     0, 16384, 20480, 21504, 22016, 21888, 21952, 
+    21953, 21944, 21948,     0, 16384, 20480, 21504, 22016, 
+    21888, 21952, 21953, 21955, 21948,     0, 16384, 20480, 
+    21504, 22016, 21888, 21952, 21953, 21955, 21948, 21950, 
+        0, 16384, 20480, 21504, 22016, 21888,     0, 16384, 
+    20480, 21504, 22016, 22017, 21952,     0, 16384, 20480, 
+    21504, 22016, 22017, 21952,     0, 16384, 20480, 21504, 
+    22016, 22017, 21952, 21954,     0, 16384, 20480, 21504, 
+    22016, 22017, 21952,     0, 16384, 20480, 21504, 22016, 
+    22017, 21952, 21956,     0, 16384, 20480, 21504, 22016, 
+    22017, 21952, 21956,     0, 16384, 20480, 21504, 22016, 
+    22017, 21952, 21960, 21958,     0, 16384, 20480, 21504, 
+    22016, 22017, 21952,     0, 16384, 20480, 21504, 22016, 
+    22017, 21952, 21960,     0, 16384, 20480, 21504, 22016, 
+    22017, 21952, 21960,     0, 16384, 20480, 21504, 22016, 
+    22017, 21952, 21960, 21962,     0, 16384, 20480, 21504, 
+    22016, 22017, 21952, 21960,     0, 16384, 20480, 21504, 
+    22016, 22017, 21952, 21968, 21964,     0, 16384, 20480, 
+    21504, 22016, 22017, 21952, 21968, 21964,     0, 16384, 
+    20480, 21504, 22016, 22017, 21952, 21968, 21969, 21966, 
+        0, 16384, 20480, 21504, 22016, 22017, 21952,     0, 
+    16384, 20480, 21504, 22016, 22017, 21952, 21968,     0, 
+    16384, 20480, 21504, 22016, 22017, 21952, 21968,     0, 
+    16384, 20480, 21504, 22016, 22017, 21952, 21968, 21970, 
+        0, 16384, 20480, 21504, 22016, 22017, 21952, 21968, 
+        0, 16384, 20480, 21504, 22016, 22017, 21952, 21968, 
+    21972,     0, 16384, 20480, 21504, 22016, 22017, 21952, 
+    21968, 21972,     0, 16384, 20480, 21504, 22016, 22017, 
+    21952, 21968, 21976, 21974,     0, 16384, 20480, 21504, 
+    22016, 22017, 21952, 21968,     0, 16384, 20480, 21504, 
+    22016, 22017, 21952, 21984, 21976,     0, 16384, 20480, 
+    21504, 22016, 22017, 21952, 21984, 21976,     0, 16384, 
+    20480, 21504, 22016, 22017, 21952, 21984, 21976, 21978, 
+        0, 16384, 20480, 21504, 22016, 22017, 21952, 21984, 
+    21976,     0, 16384, 20480, 21504, 22016, 22017, 21952, 
+    21984, 21985, 21980,     0, 16384, 20480, 21504, 22016, 
+    22017, 21952, 21984, 21985, 21980,     0, 16384, 20480, 
+    21504, 22016, 22017, 21952, 21984, 21985, 21980, 21982, 
+        0, 16384, 20480, 21504, 22016, 22017, 21952,     0, 
+    16384, 20480, 21504, 22016, 22017, 21952, 21984,     0, 
+    16384, 20480, 21504, 22016, 22017, 22019, 21984,     0, 
+    16384, 20480, 21504, 22016, 22017, 22019, 21984, 21986, 
+        0, 16384, 20480, 21504, 22016, 22017, 22019, 21984, 
+        0, 16384, 20480, 21504, 22016, 22017, 22019, 21984, 
+    21988,     0, 16384, 20480, 21504, 22016, 22017, 22019, 
+    21984, 21988,     0, 16384, 20480, 21504, 22016, 22017, 
+    22019, 21984, 21992, 21990,     0, 16384, 20480, 21504, 
+    22016, 22017, 22019, 21984,     0, 16384, 20480, 21504, 
+    22016, 22017, 22019, 21984, 21992,     0, 16384, 20480, 
+    21504, 22016, 22017, 22019, 21984, 21992,     0, 16384, 
+    20480, 21504, 22016, 22017, 22019, 21984, 21992, 21994, 
+        0, 16384, 20480, 21504, 22016, 22017, 22019, 21984, 
+    21992,     0, 16384, 20480, 21504, 22016, 22017, 22019, 
+    21984, 22000, 21996,     0, 16384, 20480, 21504, 22016, 
+    22017, 22019, 21984, 22000, 21996,     0, 16384, 20480, 
+    21504, 22016, 22017, 22019, 21984, 22000, 22001, 21998, 
+        0, 16384, 20480, 21504, 22016, 22017, 22019, 21984, 
+        0, 16384, 20480, 21504, 22016, 22017, 22019, 21984, 
+    22000,     0, 16384, 20480, 21504, 22016, 22017, 22019, 
+    21984, 22000,     0, 16384, 20480, 21504, 22016, 22017, 
+    22019, 21984, 22000, 22002,     0, 16384, 20480, 21504, 
+    22016, 22017, 22019, 22023, 22000,     0, 16384, 20480, 
+    21504, 22016, 22017, 22019, 22023, 22000, 22004,     0, 
+    16384, 20480, 21504, 22016, 22017, 22019, 22023, 22000, 
+    22004,     0, 16384, 20480, 21504, 22016, 22017, 22019, 
+    22023, 22000, 22008, 22006,     0, 16384, 20480, 21504, 
+    22016, 22017, 22019, 22023, 22000,     0, 16384, 20480, 
+    21504, 22016, 22017, 22019, 22023, 22000, 22008,     0, 
+    16384, 20480, 21504, 22016, 22017, 22019, 22023, 22000, 
+    22008,     0, 16384, 20480, 21504, 22016, 22017, 22019, 
+    22023, 22000, 22008, 22010,     0, 16384, 20480, 21504, 
+    22016, 22017, 22019, 22023, 22000, 22008,     0, 16384, 
+    20480, 21504, 22016, 22017, 22019, 22023, 22000, 22008, 
+    22012,     0, 16384, 20480, 21504, 22016, 22017, 22019, 
+    22023, 22000, 22008, 22012,     0, 16384, 20480, 21504, 
+    22016, 22017, 22019, 22023, 22000, 22008, 22012, 22014, 
+        0, 16384, 20480, 21504,     0, 16384, 20480, 22528, 
+    22016,     0, 16384, 20480, 22528, 22016,     0, 16384, 
+    20480, 22528, 22016, 22018,     0, 16384, 20480, 22528, 
+    22016,     0, 16384, 20480, 22528, 22016, 22020,     0, 
+    16384, 20480, 22528, 22016, 22020,     0, 16384, 20480, 
+    22528, 22016, 22024, 22022,     0, 16384, 20480, 22528, 
+    22016,     0, 16384, 20480, 22528, 22016, 22024,     0, 
+    16384, 20480, 22528, 22016, 22024,     0, 16384, 20480, 
+    22528, 22016, 22024, 22026,     0, 16384, 20480, 22528, 
+    22016, 22024,     0, 16384, 20480, 22528, 22016, 22032, 
+    22028,     0, 16384, 20480, 22528, 22016, 22032, 22028, 
+        0, 16384, 20480, 22528, 22016, 22032, 22033, 22030, 
+        0, 16384, 20480, 22528, 22016,     0, 16384, 20480, 
+    22528, 22016, 22032,     0, 16384, 20480, 22528, 22016, 
+    22032,     0, 16384, 20480, 22528, 22016, 22032, 22034, 
+        0, 16384, 20480, 22528, 22016, 22032,     0, 16384, 
+    20480, 22528, 22016, 22032, 22036,     0, 16384, 20480, 
+    22528, 22016, 22032, 22036,     0, 16384, 20480, 22528, 
+    22016, 22032, 22040, 22038,     0, 16384, 20480, 22528, 
+    22016, 22032,     0, 16384, 20480, 22528, 22016, 22048, 
+    22040,     0, 16384, 20480, 22528, 22016, 22048, 22040, 
+        0, 16384, 20480, 22528, 22016, 22048, 22040, 22042, 
+        0, 16384, 20480, 22528, 22016, 22048, 22040,     0, 
+    16384, 20480, 22528, 22016, 22048, 22049, 22044,     0, 
+    16384, 20480, 22528, 22016, 22048, 22049, 22044,     0, 
+    16384, 20480, 22528, 22016, 22048, 22049, 22044, 22046, 
+        0, 16384, 20480, 22528, 22016,     0, 16384, 20480, 
+    22528, 22016, 22048,     0, 16384, 20480, 22528, 22016, 
+    22048,     0, 16384, 20480, 22528, 22016, 22048, 22050, 
+        0, 16384, 20480, 22528, 22016, 22048,     0, 16384, 
+    20480, 22528, 22016, 22048, 22052,     0, 16384, 20480, 
+    22528, 22016, 22048, 22052,     0, 16384, 20480, 22528, 
+    22016, 22048, 22056, 22054,     0, 16384, 20480, 22528, 
+    22016, 22048,     0, 16384, 20480, 22528, 22016, 22048, 
+    22056,     0, 16384, 20480, 22528, 22016, 22048, 22056, 
+        0, 16384, 20480, 22528, 22016, 22048, 22056, 22058, 
+        0, 16384, 20480, 22528, 22016, 22048, 22056,     0, 
+    16384, 20480, 22528, 22016, 22048, 22064, 22060,     0, 
+    16384, 20480, 22528, 22016, 22048, 22064, 22060,     0, 
+    16384, 20480, 22528, 22016, 22048, 22064, 22065, 22062, 
+        0, 16384, 20480, 22528, 22016, 22048,     0, 16384, 
+    20480, 22528, 22016, 22080, 22064,     0, 16384, 20480, 
+    22528, 22016, 22080, 22064,     0, 16384, 20480, 22528, 
+    22016, 22080, 22064, 22066,     0, 16384, 20480, 22528, 
+    22016, 22080, 22064,     0, 16384, 20480, 22528, 22016, 
+    22080, 22064, 22068,     0, 16384, 20480, 22528, 22016, 
+    22080, 22064, 22068,     0, 16384, 20480, 22528, 22016, 
+    22080, 22064, 22072, 22070,     0, 16384, 20480, 22528, 
+    22016, 22080, 22064,     0, 16384, 20480, 22528, 22016, 
+    22080, 22081, 22072,     0, 16384, 20480, 22528, 22016, 
+    22080, 22081, 22072,     0, 16384, 20480, 22528, 22016, 
+    22080, 22081, 22072, 22074,     0, 16384, 20480, 22528, 
+    22016, 22080, 22081, 22072,     0, 16384, 20480, 22528, 
+    22016, 22080, 22081, 22072, 22076,     0, 16384, 20480, 
+    22528, 22016, 22080, 22081, 22083, 22076,     0, 16384, 
+    20480, 22528, 22016, 22080, 22081, 22083, 22076, 22078, 
+        0, 16384, 20480, 22528, 22016,     0, 16384, 20480, 
+    22528, 22016, 22080,     0, 16384, 20480, 22528, 22016, 
+    22080,     0, 16384, 20480, 22528, 22016, 22080, 22082, 
+        0, 16384, 20480, 22528, 22016, 22080,     0, 16384, 
+    20480, 22528, 22016, 22080, 22084,     0, 16384, 20480, 
+    22528, 22016, 22080, 22084,     0, 16384, 20480, 22528, 
+    22016, 22080, 22088, 22086,     0, 16384, 20480, 22528, 
+    22016, 22080,     0, 16384, 20480, 22528, 22016, 22080, 
+    22088,     0, 16384, 20480, 22528, 22016, 22080, 22088, 
+        0, 16384, 20480, 22528, 22016, 22080, 22088, 22090, 
+        0, 16384, 20480, 22528, 22016, 22080, 22088,     0, 
+    16384, 20480, 22528, 22016, 22080, 22096, 22092,     0, 
+    16384, 20480, 22528, 22016, 22080, 22096, 22092,     0, 
+    16384, 20480, 22528, 22016, 22080, 22096, 22097, 22094, 
+        0, 16384, 20480, 22528, 22016, 22080,     0, 16384, 
+    20480, 22528, 22016, 22080, 22096,     0, 16384, 20480, 
+    22528, 22016, 22080, 22096,     0, 16384, 20480, 22528, 
+    22016, 22080, 22096, 22098,     0, 16384, 20480, 22528, 
+    22016, 22080, 22096,     0, 16384, 20480, 22528, 22016, 
+    22080, 22096, 22100,     0, 16384, 20480, 22528, 22016, 
+    22080, 22096, 22100,     0, 16384, 20480, 22528, 22016, 
+    22080, 22096, 22104, 22102,     0, 16384, 20480, 22528, 
+    22016, 22080, 22096,     0, 16384, 20480, 22528, 22016, 
+    22080, 22112, 22104,     0, 16384, 20480, 22528, 22016, 
+    22080, 22112, 22104,     0, 16384, 20480, 22528, 22016, 
+    22080, 22112, 22104, 22106,     0, 16384, 20480, 22528, 
+    22016, 22080, 22112, 22104,     0, 16384, 20480, 22528, 
+    22016, 22080, 22112, 22113, 22108,     0, 16384, 20480, 
+    22528, 22016, 22080, 22112, 22113, 22108,     0, 16384, 
+    20480, 22528, 22016, 22080, 22112, 22113, 22108, 22110, 
+        0, 16384, 20480, 22528, 22016, 22080,     0, 16384, 
+    20480, 22528, 22016, 22144, 22112,     0, 16384, 20480, 
+    22528, 22016, 22144, 22112,     0, 16384, 20480, 22528, 
+    22016, 22144, 22112, 22114,     0, 16384, 20480, 22528, 
+    22016, 22144, 22112,     0, 16384, 20480, 22528, 22016, 
+    22144, 22112, 22116,     0, 16384, 20480, 22528, 22016, 
+    22144, 22112, 22116,     0, 16384, 20480, 22528, 22016, 
+    22144, 22112, 22120, 22118,     0, 16384, 20480, 22528, 
+    22016, 22144, 22112,     0, 16384, 20480, 22528, 22016, 
+    22144, 22112, 22120,     0, 16384, 20480, 22528, 22016, 
+    22144, 22112, 22120,     0, 16384, 20480, 22528, 22016, 
+    22144, 22112, 22120, 22122,     0, 16384, 20480, 22528, 
+    22016, 22144, 22112, 22120,     0, 16384, 20480, 22528, 
+    22016, 22144, 22112, 22128, 22124,     0, 16384, 20480, 
+    22528, 22016, 22144, 22112, 22128, 22124,     0, 16384, 
+    20480, 22528, 22016, 22144, 22112, 22128, 22129, 22126, 
+        0, 16384, 20480, 22528, 22016, 22144, 22112,     0, 
+    16384, 20480, 22528, 22016, 22144, 22145, 22128,     0, 
+    16384, 20480, 22528, 22016, 22144, 22145, 22128,     0, 
+    16384, 20480, 22528, 22016, 22144, 22145, 22128, 22130, 
+        0, 16384, 20480, 22528, 22016, 22144, 22145, 22128, 
+        0, 16384, 20480, 22528, 22016, 22144, 22145, 22128, 
+    22132,     0, 16384, 20480, 22528, 22016, 22144, 22145, 
+    22128, 22132,     0, 16384, 20480, 22528, 22016, 22144, 
+    22145, 22128, 22136, 22134,     0, 16384, 20480, 22528, 
+    22016, 22144, 22145, 22128,     0, 16384, 20480, 22528, 
+    22016, 22144, 22145, 22128, 22136,     0, 16384, 20480, 
+    22528, 22016, 22144, 22145, 22147, 22136,     0, 16384, 
+    20480, 22528, 22016, 22144, 22145, 22147, 22136, 22138, 
+        0, 16384, 20480, 22528, 22016, 22144, 22145, 22147, 
+    22136,     0, 16384, 20480, 22528, 22016, 22144, 22145, 
+    22147, 22136, 22140,     0, 16384, 20480, 22528, 22016, 
+    22144, 22145, 22147, 22136, 22140,     0, 16384, 20480, 
+    22528, 22016, 22144, 22145, 22147, 22136, 22140, 22142, 
+        0, 16384, 20480, 22528, 22016,     0, 16384, 20480, 
+    22528, 22016, 22144,     0, 16384, 20480, 22528, 22016, 
+    22144,     0, 16384, 20480, 22528, 22016, 22144, 22146, 
+        0, 16384, 20480, 22528, 22016, 22144,     0, 16384, 
+    20480, 22528, 22016, 22144, 22148,     0, 16384, 20480, 
+    22528, 22016, 22144, 22148,     0, 16384, 20480, 22528, 
+    22016, 22144, 22152, 22150,     0, 16384, 20480, 22528, 
+    22016, 22144,     0, 16384, 20480, 22528, 22016, 22144, 
+    22152,     0, 16384, 20480, 22528, 22016, 22144, 22152, 
+        0, 16384, 20480, 22528, 22016, 22144, 22152, 22154, 
+        0, 16384, 20480, 22528, 22016, 22144, 22152,     0, 
+    16384, 20480, 22528, 22016, 22144, 22160, 22156,     0, 
+    16384, 20480, 22528, 22016, 22144, 22160, 22156,     0, 
+    16384, 20480, 22528, 22016, 22144, 22160, 22161, 22158, 
+        0, 16384, 20480, 22528, 22016, 22144,     0, 16384, 
+    20480, 22528, 22016, 22144, 22160,     0, 16384, 20480, 
+    22528, 22016, 22144, 22160,     0, 16384, 20480, 22528, 
+    22016, 22144, 22160, 22162,     0, 16384, 20480, 22528, 
+    22016, 22144, 22160,     0, 16384, 20480, 22528, 22016, 
+    22144, 22160, 22164,     0, 16384, 20480, 22528, 22016, 
+    22144, 22160, 22164,     0, 16384, 20480, 22528, 22016, 
+    22144, 22160, 22168, 22166,     0, 16384, 20480, 22528, 
+    22016, 22144, 22160,     0, 16384, 20480, 22528, 22016, 
+    22144, 22176, 22168,     0, 16384, 20480, 22528, 22016, 
+    22144, 22176, 22168,     0, 16384, 20480, 22528, 22016, 
+    22144, 22176, 22168, 22170,     0, 16384, 20480, 22528, 
+    22016, 22144, 22176, 22168,     0, 16384, 20480, 22528, 
+    22016, 22144, 22176, 22177, 22172,     0, 16384, 20480, 
+    22528, 22016, 22144, 22176, 22177, 22172,     0, 16384, 
+    20480, 22528, 22016, 22144, 22176, 22177, 22172, 22174, 
+        0, 16384, 20480, 22528, 22016, 22144,     0, 16384, 
+    20480, 22528, 22016, 22144, 22176,     0, 16384, 20480, 
+    22528, 22016, 22144, 22176,     0, 16384, 20480, 22528, 
+    22016, 22144, 22176, 22178,     0, 16384, 20480, 22528, 
+    22016, 22144, 22176,     0, 16384, 20480, 22528, 22016, 
+    22144, 22176, 22180,     0, 16384, 20480, 22528, 22016, 
+    22144, 22176, 22180,     0, 16384, 20480, 22528, 22016, 
+    22144, 22176, 22184, 22182,     0, 16384, 20480, 22528, 
+    22016, 22144, 22176,     0, 16384, 20480, 22528, 22016, 
+    22144, 22176, 22184,     0, 16384, 20480, 22528, 22016, 
+    22144, 22176, 22184,     0, 16384, 20480, 22528, 22016, 
+    22144, 22176, 22184, 22186,     0, 16384, 20480, 22528, 
+    22016, 22144, 22176, 22184,     0, 16384, 20480, 22528, 
+    22016, 22144, 22176, 22192, 22188,     0, 16384, 20480, 
+    22528, 22016, 22144, 22176, 22192, 22188,     0, 16384, 
+    20480, 22528, 22016, 22144, 22176, 22192, 22193, 22190, 
+        0, 16384, 20480, 22528, 22016, 22144, 22176,     0, 
+    16384, 20480, 22528, 22016, 22144, 22208, 22192,     0, 
+    16384, 20480, 22528, 22016, 22144, 22208, 22192,     0, 
+    16384, 20480, 22528, 22016, 22144, 22208, 22192, 22194, 
+        0, 16384, 20480, 22528, 22016, 22144, 22208, 22192, 
+        0, 16384, 20480, 22528, 22016, 22144, 22208, 22192, 
+    22196,     0, 16384, 20480, 22528, 22016, 22144, 22208, 
+    22192, 22196,     0, 16384, 20480, 22528, 22016, 22144, 
+    22208, 22192, 22200, 22198,     0, 16384, 20480, 22528, 
+    22016, 22144, 22208, 22192,     0, 16384, 20480, 22528, 
+    22016, 22144, 22208, 22209, 22200,     0, 16384, 20480, 
+    22528, 22016, 22144, 22208, 22209, 22200,     0, 16384, 
+    20480, 22528, 22016, 22144, 22208, 22209, 22200, 22202, 
+        0, 16384, 20480, 22528, 22016, 22144, 22208, 22209, 
+    22200,     0, 16384, 20480, 22528, 22016, 22144, 22208, 
+    22209, 22200, 22204,     0, 16384, 20480, 22528, 22016, 
+    22144, 22208, 22209, 22211, 22204,     0, 16384, 20480, 
+    22528, 22016, 22144, 22208, 22209, 22211, 22204, 22206, 
+        0, 16384, 20480, 22528, 22016, 22144,     0, 16384, 
+    20480, 22528, 22016, 22272, 22208,     0, 16384, 20480, 
+    22528, 22016, 22272, 22208,     0, 16384, 20480, 22528, 
+    22016, 22272, 22208, 22210,     0, 16384, 20480, 22528, 
+    22016, 22272, 22208,     0, 16384, 20480, 22528, 22016, 
+    22272, 22208, 22212,     0, 16384, 20480, 22528, 22016, 
+    22272, 22208, 22212,     0, 16384, 20480, 22528, 22016, 
+    22272, 22208, 22216, 22214,     0, 16384, 20480, 22528, 
+    22016, 22272, 22208,     0, 16384, 20480, 22528, 22016, 
+    22272, 22208, 22216,     0, 16384, 20480, 22528, 22016, 
+    22272, 22208, 22216,     0, 16384, 20480, 22528, 22016, 
+    22272, 22208, 22216, 22218,     0, 16384, 20480, 22528, 
+    22016, 22272, 22208, 22216,     0, 16384, 20480, 22528, 
+    22016, 22272, 22208, 22224, 22220,     0, 16384, 20480, 
+    22528, 22016, 22272, 22208, 22224, 22220,     0, 16384, 
+    20480, 22528, 22016, 22272, 22208, 22224, 22225, 22222, 
+        0, 16384, 20480, 22528, 22016, 22272, 22208,     0, 
+    16384, 20480, 22528, 22016, 22272, 22208, 22224,     0, 
+    16384, 20480, 22528, 22016, 22272, 22208, 22224,     0, 
+    16384, 20480, 22528, 22016, 22272, 22208, 22224, 22226, 
+        0, 16384, 20480, 22528, 22016, 22272, 22208, 22224, 
+        0, 16384, 20480, 22528, 22016, 22272, 22208, 22224, 
+    22228,     0, 16384, 20480, 22528, 22016, 22272, 22208, 
+    22224, 22228,     0, 16384, 20480, 22528, 22016, 22272, 
+    22208, 22224, 22232, 22230,     0, 16384, 20480, 22528, 
+    22016, 22272, 22208, 22224,     0, 16384, 20480, 22528, 
+    22016, 22272, 22208, 22240, 22232,     0, 16384, 20480, 
+    22528, 22016, 22272, 22208, 22240, 22232,     0, 16384, 
+    20480, 22528, 22016, 22272, 22208, 22240, 22232, 22234, 
+        0, 16384, 20480, 22528, 22016, 22272, 22208, 22240, 
+    22232,     0, 16384, 20480, 22528, 22016, 22272, 22208, 
+    22240, 22241, 22236,     0, 16384, 20480, 22528, 22016, 
+    22272, 22208, 22240, 22241, 22236,     0, 16384, 20480, 
+    22528, 22016, 22272, 22208, 22240, 22241, 22236, 22238, 
+        0, 16384, 20480, 22528, 22016, 22272, 22208,     0, 
+    16384, 20480, 22528, 22016, 22272, 22273, 22240,     0, 
+    16384, 20480, 22528, 22016, 22272, 22273, 22240,     0, 
+    16384, 20480, 22528, 22016, 22272, 22273, 22240, 22242, 
+        0, 16384, 20480, 22528, 22016, 22272, 22273, 22240, 
+        0, 16384, 20480, 22528, 22016, 22272, 22273, 22240, 
+    22244,     0, 16384, 20480, 22528, 22016, 22272, 22273, 
+    22240, 22244,     0, 16384, 20480, 22528, 22016, 22272, 
+    22273, 22240, 22248, 22246,     0, 16384, 20480, 22528, 
+    22016, 22272, 22273, 22240,     0, 16384, 20480, 22528, 
+    22016, 22272, 22273, 22240, 22248,     0, 16384, 20480, 
+    22528, 22016, 22272, 22273, 22240, 22248,     0, 16384, 
+    20480, 22528, 22016, 22272, 22273, 22240, 22248, 22250, 
+        0, 16384, 20480, 22528, 22016, 22272, 22273, 22240, 
+    22248,     0, 16384, 20480, 22528, 22016, 22272, 22273, 
+    22240, 22256, 22252,     0, 16384, 20480, 22528, 22016, 
+    22272, 22273, 22240, 22256, 22252,     0, 16384, 20480, 
+    22528, 22016, 22272, 22273, 22240, 22256, 22257, 22254, 
+        0, 16384, 20480, 22528, 22016, 22272, 22273, 22240, 
+        0, 16384, 20480, 22528, 22016, 22272, 22273, 22240, 
+    22256,     0, 16384, 20480, 22528, 22016, 22272, 22273, 
+    22275, 22256,     0, 16384, 20480, 22528, 22016, 22272, 
+    22273, 22275, 22256, 22258,     0, 16384, 20480, 22528, 
+    22016, 22272, 22273, 22275, 22256,     0, 16384, 20480, 
+    22528, 22016, 22272, 22273, 22275, 22256, 22260,     0, 
+    16384, 20480, 22528, 22016, 22272, 22273, 22275, 22256, 
+    22260,     0, 16384, 20480, 22528, 22016, 22272, 22273, 
+    22275, 22256, 22264, 22262,     0, 16384, 20480, 22528, 
+    22016, 22272, 22273, 22275, 22256,     0, 16384, 20480, 
+    22528, 22016, 22272, 22273, 22275, 22256, 22264,     0, 
+    16384, 20480, 22528, 22016, 22272, 22273, 22275, 22256, 
+    22264,     0, 16384, 20480, 22528, 22016, 22272, 22273, 
+    22275, 22256, 22264, 22266,     0, 16384, 20480, 22528, 
+    22016, 22272, 22273, 22275, 22279, 22264,     0, 16384, 
+    20480, 22528, 22016, 22272, 22273, 22275, 22279, 22264, 
+    22268,     0, 16384, 20480, 22528, 22016, 22272, 22273, 
+    22275, 22279, 22264, 22268,     0, 16384, 20480, 22528, 
+    22016, 22272, 22273, 22275, 22279, 22264, 22268, 22270, 
+        0, 16384, 20480, 22528, 22016,     0, 16384, 20480, 
+    22528, 22016, 22272,     0, 16384, 20480, 22528, 22529, 
+    22272,     0, 16384, 20480, 22528, 22529, 22272, 22274, 
+        0, 16384, 20480, 22528, 22529, 22272,     0, 16384, 
+    20480, 22528, 22529, 22272, 22276,     0, 16384, 20480, 
+    22528, 22529, 22272, 22276,     0, 16384, 20480, 22528, 
+    22529, 22272, 22280, 22278,     0, 16384, 20480, 22528, 
+    22529, 22272,     0, 16384, 20480, 22528, 22529, 22272, 
+    22280,     0, 16384, 20480, 22528, 22529, 22272, 22280, 
+        0, 16384, 20480, 22528, 22529, 22272, 22280, 22282, 
+        0, 16384, 20480, 22528, 22529, 22272, 22280,     0, 
+    16384, 20480, 22528, 22529, 22272, 22288, 22284,     0, 
+    16384, 20480, 22528, 22529, 22272, 22288, 22284,     0, 
+    16384, 20480, 22528, 22529, 22272, 22288, 22289, 22286, 
+        0, 16384, 20480, 22528, 22529, 22272,     0, 16384, 
+    20480, 22528, 22529, 22272, 22288,     0, 16384, 20480, 
+    22528, 22529, 22272, 22288,     0, 16384, 20480, 22528, 
+    22529, 22272, 22288, 22290,     0, 16384, 20480, 22528, 
+    22529, 22272, 22288,     0, 16384, 20480, 22528, 22529, 
+    22272, 22288, 22292,     0, 16384, 20480, 22528, 22529, 
+    22272, 22288, 22292,     0, 16384, 20480, 22528, 22529, 
+    22272, 22288, 22296, 22294,     0, 16384, 20480, 22528, 
+    22529, 22272, 22288,     0, 16384, 20480, 22528, 22529, 
+    22272, 22304, 22296,     0, 16384, 20480, 22528, 22529, 
+    22272, 22304, 22296,     0, 16384, 20480, 22528, 22529, 
+    22272, 22304, 22296, 22298,     0, 16384, 20480, 22528, 
+    22529, 22272, 22304, 22296,     0, 16384, 20480, 22528, 
+    22529, 22272, 22304, 22305, 22300,     0, 16384, 20480, 
+    22528, 22529, 22272, 22304, 22305, 22300,     0, 16384, 
+    20480, 22528, 22529, 22272, 22304, 22305, 22300, 22302, 
+        0, 16384, 20480, 22528, 22529, 22272,     0, 16384, 
+    20480, 22528, 22529, 22272, 22304,     0, 16384, 20480, 
+    22528, 22529, 22272, 22304,     0, 16384, 20480, 22528, 
+    22529, 22272, 22304, 22306,     0, 16384, 20480, 22528, 
+    22529, 22272, 22304,     0, 16384, 20480, 22528, 22529, 
+    22272, 22304, 22308,     0, 16384, 20480, 22528, 22529, 
+    22272, 22304, 22308,     0, 16384, 20480, 22528, 22529, 
+    22272, 22304, 22312, 22310,     0, 16384, 20480, 22528, 
+    22529, 22272, 22304,     0, 16384, 20480, 22528, 22529, 
+    22272, 22304, 22312,     0, 16384, 20480, 22528, 22529, 
+    22272, 22304, 22312,     0, 16384, 20480, 22528, 22529, 
+    22272, 22304, 22312, 22314,     0, 16384, 20480, 22528, 
+    22529, 22272, 22304, 22312,     0, 16384, 20480, 22528, 
+    22529, 22272, 22304, 22320, 22316,     0, 16384, 20480, 
+    22528, 22529, 22272, 22304, 22320, 22316,     0, 16384, 
+    20480, 22528, 22529, 22272, 22304, 22320, 22321, 22318, 
+        0, 16384, 20480, 22528, 22529, 22272, 22304,     0, 
+    16384, 20480, 22528, 22529, 22272, 22336, 22320,     0, 
+    16384, 20480, 22528, 22529, 22272, 22336, 22320,     0, 
+    16384, 20480, 22528, 22529, 22272, 22336, 22320, 22322, 
+        0, 16384, 20480, 22528, 22529, 22272, 22336, 22320, 
+        0, 16384, 20480, 22528, 22529, 22272, 22336, 22320, 
+    22324,     0, 16384, 20480, 22528, 22529, 22272, 22336, 
+    22320, 22324,     0, 16384, 20480, 22528, 22529, 22272, 
+    22336, 22320, 22328, 22326,     0, 16384, 20480, 22528, 
+    22529, 22272, 22336, 22320,     0, 16384, 20480, 22528, 
+    22529, 22272, 22336, 22337, 22328,     0, 16384, 20480, 
+    22528, 22529, 22272, 22336, 22337, 22328,     0, 16384, 
+    20480, 22528, 22529, 22272, 22336, 22337, 22328, 22330, 
+        0, 16384, 20480, 22528, 22529, 22272, 22336, 22337, 
+    22328,     0, 16384, 20480, 22528, 22529, 22272, 22336, 
+    22337, 22328, 22332,     0, 16384, 20480, 22528, 22529, 
+    22272, 22336, 22337, 22339, 22332,     0, 16384, 20480, 
+    22528, 22529, 22272, 22336, 22337, 22339, 22332, 22334, 
+        0, 16384, 20480, 22528, 22529, 22272,     0, 16384, 
+    20480, 22528, 22529, 22272, 22336,     0, 16384, 20480, 
+    22528, 22529, 22272, 22336,     0, 16384, 20480, 22528, 
+    22529, 22272, 22336, 22338,     0, 16384, 20480, 22528, 
+    22529, 22272, 22336,     0, 16384, 20480, 22528, 22529, 
+    22272, 22336, 22340,     0, 16384, 20480, 22528, 22529, 
+    22272, 22336, 22340,     0, 16384, 20480, 22528, 22529, 
+    22272, 22336, 22344, 22342,     0, 16384, 20480, 22528, 
+    22529, 22272, 22336,     0, 16384, 20480, 22528, 22529, 
+    22272, 22336, 22344,     0, 16384, 20480, 22528, 22529, 
+    22272, 22336, 22344,     0, 16384, 20480, 22528, 22529, 
+    22272, 22336, 22344, 22346,     0, 16384, 20480, 22528, 
+    22529, 22272, 22336, 22344,     0, 16384, 20480, 22528, 
+    22529, 22272, 22336, 22352, 22348,     0, 16384, 20480, 
+    22528, 22529, 22272, 22336, 22352, 22348,     0, 16384, 
+    20480, 22528, 22529, 22272, 22336, 22352, 22353, 22350, 
+        0, 16384, 20480, 22528, 22529, 22272, 22336,     0, 
+    16384, 20480, 22528, 22529, 22272, 22336, 22352,     0, 
+    16384, 20480, 22528, 22529, 22272, 22336, 22352,     0, 
+    16384, 20480, 22528, 22529, 22272, 22336, 22352, 22354, 
+        0, 16384, 20480, 22528, 22529, 22272, 22336, 22352, 
+        0, 16384, 20480, 22528, 22529, 22272, 22336, 22352, 
+    22356,     0, 16384, 20480, 22528, 22529, 22272, 22336, 
+    22352, 22356,     0, 16384, 20480, 22528, 22529, 22272, 
+    22336, 22352, 22360, 22358,     0, 16384, 20480, 22528, 
+    22529, 22272, 22336, 22352,     0, 16384, 20480, 22528, 
+    22529, 22272, 22336, 22368, 22360,     0, 16384, 20480, 
+    22528, 22529, 22272, 22336, 22368, 22360,     0, 16384, 
+    20480, 22528, 22529, 22272, 22336, 22368, 22360, 22362, 
+        0, 16384, 20480, 22528, 22529, 22272, 22336, 22368, 
+    22360,     0, 16384, 20480, 22528, 22529, 22272, 22336, 
+    22368, 22369, 22364,     0, 16384, 20480, 22528, 22529, 
+    22272, 22336, 22368, 22369, 22364,     0, 16384, 20480, 
+    22528, 22529, 22272, 22336, 22368, 22369, 22364, 22366, 
+        0, 16384, 20480, 22528, 22529, 22272, 22336,     0, 
+    16384, 20480, 22528, 22529, 22272, 22400, 22368,     0, 
+    16384, 20480, 22528, 22529, 22272, 22400, 22368,     0, 
+    16384, 20480, 22528, 22529, 22272, 22400, 22368, 22370, 
+        0, 16384, 20480, 22528, 22529, 22272, 22400, 22368, 
+        0, 16384, 20480, 22528, 22529, 22272, 22400, 22368, 
+    22372,     0, 16384, 20480, 22528, 22529, 22272, 22400, 
+    22368, 22372,     0, 16384, 20480, 22528, 22529, 22272, 
+    22400, 22368, 22376, 22374,     0, 16384, 20480, 22528, 
+    22529, 22272, 22400, 22368,     0, 16384, 20480, 22528, 
+    22529, 22272, 22400, 22368, 22376,     0, 16384, 20480, 
+    22528, 22529, 22272, 22400, 22368, 22376,     0, 16384, 
+    20480, 22528, 22529, 22272, 22400, 22368, 22376, 22378, 
+        0, 16384, 20480, 22528, 22529, 22272, 22400, 22368, 
+    22376,     0, 16384, 20480, 22528, 22529, 22272, 22400, 
+    22368, 22384, 22380,     0, 16384, 20480, 22528, 22529, 
+    22272, 22400, 22368, 22384, 22380,     0, 16384, 20480, 
+    22528, 22529, 22272, 22400, 22368, 22384, 22385, 22382, 
+        0, 16384, 20480, 22528, 22529, 22272, 22400, 22368, 
+        0, 16384, 20480, 22528, 22529, 22272, 22400, 22401, 
+    22384,     0, 16384, 20480, 22528, 22529, 22272, 22400, 
+    22401, 22384,     0, 16384, 20480, 22528, 22529, 22272, 
+    22400, 22401, 22384, 22386,     0, 16384, 20480, 22528, 
+    22529, 22272, 22400, 22401, 22384,     0, 16384, 20480, 
+    22528, 22529, 22272, 22400, 22401, 22384, 22388,     0, 
+    16384, 20480, 22528, 22529, 22272, 22400, 22401, 22384, 
+    22388,     0, 16384, 20480, 22528, 22529, 22272, 22400, 
+    22401, 22384, 22392, 22390,     0, 16384, 20480, 22528, 
+    22529, 22272, 22400, 22401, 22384,     0, 16384, 20480, 
+    22528, 22529, 22272, 22400, 22401, 22384, 22392,     0, 
+    16384, 20480, 22528, 22529, 22272, 22400, 22401, 22403, 
+    22392,     0, 16384, 20480, 22528, 22529, 22272, 22400, 
+    22401, 22403, 22392, 22394,     0, 16384, 20480, 22528, 
+    22529, 22272, 22400, 22401, 22403, 22392,     0, 16384, 
+    20480, 22528, 22529, 22272, 22400, 22401, 22403, 22392, 
+    22396,     0, 16384, 20480, 22528, 22529, 22272, 22400, 
+    22401, 22403, 22392, 22396,     0, 16384, 20480, 22528, 
+    22529, 22272, 22400, 22401, 22403, 22392, 22396, 22398, 
+        0, 16384, 20480, 22528, 22529, 22272,     0, 16384, 
+    20480, 22528, 22529, 22272, 22400,     0, 16384, 20480, 
+    22528, 22529, 22272, 22400,     0, 16384, 20480, 22528, 
+    22529, 22272, 22400, 22402,     0, 16384, 20480, 22528, 
+    22529, 22531, 22400,     0, 16384, 20480, 22528, 22529, 
+    22531, 22400, 22404,     0, 16384, 20480, 22528, 22529, 
+    22531, 22400, 22404,     0, 16384, 20480, 22528, 22529, 
+    22531, 22400, 22408, 22406,     0, 16384, 20480, 22528, 
+    22529, 22531, 22400,     0, 16384, 20480, 22528, 22529, 
+    22531, 22400, 22408,     0, 16384, 20480, 22528, 22529, 
+    22531, 22400, 22408,     0, 16384, 20480, 22528, 22529, 
+    22531, 22400, 22408, 22410,     0, 16384, 20480, 22528, 
+    22529, 22531, 22400, 22408,     0, 16384, 20480, 22528, 
+    22529, 22531, 22400, 22416, 22412,     0, 16384, 20480, 
+    22528, 22529, 22531, 22400, 22416, 22412,     0, 16384, 
+    20480, 22528, 22529, 22531, 22400, 22416, 22417, 22414, 
+        0, 16384, 20480, 22528, 22529, 22531, 22400,     0, 
+    16384, 20480, 22528, 22529, 22531, 22400, 22416,     0, 
+    16384, 20480, 22528, 22529, 22531, 22400, 22416,     0, 
+    16384, 20480, 22528, 22529, 22531, 22400, 22416, 22418, 
+        0, 16384, 20480, 22528, 22529, 22531, 22400, 22416, 
+        0, 16384, 20480, 22528, 22529, 22531, 22400, 22416, 
+    22420,     0, 16384, 20480, 22528, 22529, 22531, 22400, 
+    22416, 22420,     0, 16384, 20480, 22528, 22529, 22531, 
+    22400, 22416, 22424, 22422,     0, 16384, 20480, 22528, 
+    22529, 22531, 22400, 22416,     0, 16384, 20480, 22528, 
+    22529, 22531, 22400, 22432, 22424,     0, 16384, 20480, 
+    22528, 22529, 22531, 22400, 22432, 22424,     0, 16384, 
+    20480, 22528, 22529, 22531, 22400, 22432, 22424, 22426, 
+        0, 16384, 20480, 22528, 22529, 22531, 22400, 22432, 
+    22424,     0, 16384, 20480, 22528, 22529, 22531, 22400, 
+    22432, 22433, 22428,     0, 16384, 20480, 22528, 22529, 
+    22531, 22400, 22432, 22433, 22428,     0, 16384, 20480, 
+    22528, 22529, 22531, 22400, 22432, 22433, 22428, 22430, 
+        0, 16384, 20480, 22528, 22529, 22531, 22400,     0, 
+    16384, 20480, 22528, 22529, 22531, 22400, 22432,     0, 
+    16384, 20480, 22528, 22529, 22531, 22400, 22432,     0, 
+    16384, 20480, 22528, 22529, 22531, 22400, 22432, 22434, 
+        0, 16384, 20480, 22528, 22529, 22531, 22400, 22432, 
+        0, 16384, 20480, 22528, 22529, 22531, 22400, 22432, 
+    22436,     0, 16384, 20480, 22528, 22529, 22531, 22400, 
+    22432, 22436,     0, 16384, 20480, 22528, 22529, 22531, 
+    22400, 22432, 22440, 22438,     0, 16384, 20480, 22528, 
+    22529, 22531, 22400, 22432,     0, 16384, 20480, 22528, 
+    22529, 22531, 22400, 22432, 22440,     0, 16384, 20480, 
+    22528, 22529, 22531, 22400, 22432, 22440,     0, 16384, 
+    20480, 22528, 22529, 22531, 22400, 22432, 22440, 22442, 
+        0, 16384, 20480, 22528, 22529, 22531, 22400, 22432, 
+    22440,     0, 16384, 20480, 22528, 22529, 22531, 22400, 
+    22432, 22448, 22444,     0, 16384, 20480, 22528, 22529, 
+    22531, 22400, 22432, 22448, 22444,     0, 16384, 20480, 
+    22528, 22529, 22531, 22400, 22432, 22448, 22449, 22446, 
+        0, 16384, 20480, 22528, 22529, 22531, 22400, 22432, 
+        0, 16384, 20480, 22528, 22529, 22531, 22400, 22464, 
+    22448,     0, 16384, 20480, 22528, 22529, 22531, 22400, 
+    22464, 22448,     0, 16384, 20480, 22528, 22529, 22531, 
+    22400, 22464, 22448, 22450,     0, 16384, 20480, 22528, 
+    22529, 22531, 22400, 22464, 22448,     0, 16384, 20480, 
+    22528, 22529, 22531, 22400, 22464, 22448, 22452,     0, 
+    16384, 20480, 22528, 22529, 22531, 22400, 22464, 22448, 
+    22452,     0, 16384, 20480, 22528, 22529, 22531, 22400, 
+    22464, 22448, 22456, 22454,     0, 16384, 20480, 22528, 
+    22529, 22531, 22400, 22464, 22448,     0, 16384, 20480, 
+    22528, 22529, 22531, 22400, 22464, 22465, 22456,     0, 
+    16384, 20480, 22528, 22529, 22531, 22400, 22464, 22465, 
+    22456,     0, 16384, 20480, 22528, 22529, 22531, 22400, 
+    22464, 22465, 22456, 22458,     0, 16384, 20480, 22528, 
+    22529, 22531, 22400, 22464, 22465, 22456,     0, 16384, 
+    20480, 22528, 22529, 22531, 22400, 22464, 22465, 22456, 
+    22460,     0, 16384, 20480, 22528, 22529, 22531, 22400, 
+    22464, 22465, 22467, 22460,     0, 16384, 20480, 22528, 
+    22529, 22531, 22400, 22464, 22465, 22467, 22460, 22462, 
+        0, 16384, 20480, 22528, 22529, 22531, 22400,     0, 
+    16384, 20480, 22528, 22529, 22531, 22400, 22464,     0, 
+    16384, 20480, 22528, 22529, 22531, 22400, 22464,     0, 
+    16384, 20480, 22528, 22529, 22531, 22400, 22464, 22466, 
+        0, 16384, 20480, 22528, 22529, 22531, 22400, 22464, 
+        0, 16384, 20480, 22528, 22529, 22531, 22400, 22464, 
+    22468,     0, 16384, 20480, 22528, 22529, 22531, 22400, 
+    22464, 22468,     0, 16384, 20480, 22528, 22529, 22531, 
+    22400, 22464, 22472, 22470,     0, 16384, 20480, 22528, 
+    22529, 22531, 22535, 22464,     0, 16384, 20480, 22528, 
+    22529, 22531, 22535, 22464, 22472,     0, 16384, 20480, 
+    22528, 22529, 22531, 22535, 22464, 22472,     0, 16384, 
+    20480, 22528, 22529, 22531, 22535, 22464, 22472, 22474, 
+        0, 16384, 20480, 22528, 22529, 22531, 22535, 22464, 
+    22472,     0, 16384, 20480, 22528, 22529, 22531, 22535, 
+    22464, 22480, 22476,     0, 16384, 20480, 22528, 22529, 
+    22531, 22535, 22464, 22480, 22476,     0, 16384, 20480, 
+    22528, 22529, 22531, 22535, 22464, 22480, 22481, 22478, 
+        0, 16384, 20480, 22528, 22529, 22531, 22535, 22464, 
+        0, 16384, 20480, 22528, 22529, 22531, 22535, 22464, 
+    22480,     0, 16384, 20480, 22528, 22529, 22531, 22535, 
+    22464, 22480,     0, 16384, 20480, 22528, 22529, 22531, 
+    22535, 22464, 22480, 22482,     0, 16384, 20480, 22528, 
+    22529, 22531, 22535, 22464, 22480,     0, 16384, 20480, 
+    22528, 22529, 22531, 22535, 22464, 22480, 22484,     0, 
+    16384, 20480, 22528, 22529, 22531, 22535, 22464, 22480, 
+    22484,     0, 16384, 20480, 22528, 22529, 22531, 22535, 
+    22464, 22480, 22488, 22486,     0, 16384, 20480, 22528, 
+    22529, 22531, 22535, 22464, 22480,     0, 16384, 20480, 
+    22528, 22529, 22531, 22535, 22464, 22496, 22488,     0, 
+    16384, 20480, 22528, 22529, 22531, 22535, 22464, 22496, 
+    22488,     0, 16384, 20480, 22528, 22529, 22531, 22535, 
+    22464, 22496, 22488, 22490,     0, 16384, 20480, 22528, 
+    22529, 22531, 22535, 22464, 22496, 22488,     0, 16384, 
+    20480, 22528, 22529, 22531, 22535, 22464, 22496, 22497, 
+    22492,     0, 16384, 20480, 22528, 22529, 22531, 22535, 
+    22464, 22496, 22497, 22492,     0, 16384, 20480, 22528, 
+    22529, 22531, 22535, 22464, 22496, 22497, 22492, 22494, 
+        0, 16384, 20480, 22528, 22529, 22531, 22535, 22464, 
+        0, 16384, 20480, 22528, 22529, 22531, 22535, 22464, 
+    22496,     0, 16384, 20480, 22528, 22529, 22531, 22535, 
+    22464, 22496,     0, 16384, 20480, 22528, 22529, 22531, 
+    22535, 22464, 22496, 22498,     0, 16384, 20480, 22528, 
+    22529, 22531, 22535, 22464, 22496,     0, 16384, 20480, 
+    22528, 22529, 22531, 22535, 22464, 22496, 22500,     0, 
+    16384, 20480, 22528, 22529, 22531, 22535, 22464, 22496, 
+    22500,     0, 16384, 20480, 22528, 22529, 22531, 22535, 
+    22464, 22496, 22504, 22502,     0, 16384, 20480, 22528, 
+    22529, 22531, 22535, 22464, 22496,     0, 16384, 20480, 
+    22528, 22529, 22531, 22535, 22464, 22496, 22504,     0, 
+    16384, 20480, 22528, 22529, 22531, 22535, 22464, 22496, 
+    22504,     0, 16384, 20480, 22528, 22529, 22531, 22535, 
+    22464, 22496, 22504, 22506,     0, 16384, 20480, 22528, 
+    22529, 22531, 22535, 22464, 22496, 22504,     0, 16384, 
+    20480, 22528, 22529, 22531, 22535, 22464, 22496, 22512, 
+    22508,     0, 16384, 20480, 22528, 22529, 22531, 22535, 
+    22464, 22496, 22512, 22508,     0, 16384, 20480, 22528, 
+    22529, 22531, 22535, 22464, 22496, 22512, 22513, 22510, 
+        0, 16384, 20480, 22528, 22529, 22531, 22535, 22543, 
+    22496,     0, 16384, 20480, 22528, 22529, 22531, 22535, 
+    22543, 22496, 22512,     0, 16384, 20480, 22528, 22529, 
+    22531, 22535, 22543, 22496, 22512,     0, 16384, 20480, 
+    22528, 22529, 22531, 22535, 22543, 22496, 22512, 22514, 
+        0, 16384, 20480, 22528, 22529, 22531, 22535, 22543, 
+    22496, 22512,     0, 16384, 20480, 22528, 22529, 22531, 
+    22535, 22543, 22496, 22512, 22516,     0, 16384, 20480, 
+    22528, 22529, 22531, 22535, 22543, 22496, 22512, 22516, 
+        0, 16384, 20480, 22528, 22529, 22531, 22535, 22543, 
+    22496, 22512, 22520, 22518,     0, 16384, 20480, 22528, 
+    22529, 22531, 22535, 22543, 22496, 22512,     0, 16384, 
+    20480, 22528, 22529, 22531, 22535, 22543, 22496, 22512, 
+    22520,     0, 16384, 20480, 22528, 22529, 22531, 22535, 
+    22543, 22496, 22512, 22520,     0, 16384, 20480, 22528, 
+    22529, 22531, 22535, 22543, 22496, 22512, 22520, 22522, 
+        0, 16384, 20480, 22528, 22529, 22531, 22535, 22543, 
+    22496, 22512, 22520,     0, 16384, 20480, 22528, 22529, 
+    22531, 22535, 22543, 22496, 22512, 22520, 22524,     0, 
+    16384, 20480, 22528, 22529, 22531, 22535, 22543, 22496, 
+    22512, 22520, 22524,     0, 16384, 20480, 22528, 22529, 
+    22531, 22535, 22543, 22496, 22512, 22520, 22524, 22526, 
+        0, 16384, 20480,     0, 16384, 20480, 22528,     0, 
+    16384, 20480, 22528,     0, 16384, 20480, 22528, 22530, 
+        0, 16384, 20480, 22528,     0, 16384, 20480, 22528, 
+    22532,     0, 16384, 20480, 22528, 22532,     0, 16384, 
+    20480, 22528, 22536, 22534,     0, 16384, 20480, 22528, 
+        0, 16384, 20480, 22528, 22536,     0, 16384, 20480, 
+    22528, 22536,     0, 16384, 20480, 22528, 22536, 22538, 
+        0, 16384, 20480, 22528, 22536,     0, 16384, 20480, 
+    22528, 22544, 22540,     0, 16384, 20480, 22528, 22544, 
+    22540,     0, 16384, 20480, 22528, 22544, 22545, 22542, 
+        0, 16384, 20480, 22528,     0, 16384, 20480, 22528, 
+    22544,     0, 16384, 20480, 22528, 22544,     0, 16384, 
+    20480, 22528, 22544, 22546,     0, 16384, 20480, 22528, 
+    22544,     0, 16384, 20480, 22528, 22544, 22548,     0, 
+    16384, 20480, 22528, 22544, 22548,     0, 16384, 20480, 
+    22528, 22544, 22552, 22550,     0, 16384, 20480, 22528, 
+    22544,     0, 16384, 20480, 22528, 22560, 22552,     0, 
+    16384, 20480, 22528, 22560, 22552,     0, 16384, 20480, 
+    22528, 22560, 22552, 22554,     0, 16384, 20480, 22528, 
+    22560, 22552,     0, 16384, 20480, 22528, 22560, 22561, 
+    22556,     0, 16384, 20480, 22528, 22560, 22561, 22556, 
+        0, 16384, 20480, 22528, 22560, 22561, 22556, 22558, 
+        0, 16384, 20480, 22528,     0, 16384, 20480, 22528, 
+    22560,     0, 16384, 20480, 22528, 22560,     0, 16384, 
+    20480, 22528, 22560, 22562,     0, 16384, 20480, 22528, 
+    22560,     0, 16384, 20480, 22528, 22560, 22564,     0, 
+    16384, 20480, 22528, 22560, 22564,     0, 16384, 20480, 
+    22528, 22560, 22568, 22566,     0, 16384, 20480, 22528, 
+    22560,     0, 16384, 20480, 22528, 22560, 22568,     0, 
+    16384, 20480, 22528, 22560, 22568,     0, 16384, 20480, 
+    22528, 22560, 22568, 22570,     0, 16384, 20480, 22528, 
+    22560, 22568,     0, 16384, 20480, 22528, 22560, 22576, 
+    22572,     0, 16384, 20480, 22528, 22560, 22576, 22572, 
+        0, 16384, 20480, 22528, 22560, 22576, 22577, 22574, 
+        0, 16384, 20480, 22528, 22560,     0, 16384, 20480, 
+    22528, 22592, 22576,     0, 16384, 20480, 22528, 22592, 
+    22576,     0, 16384, 20480, 22528, 22592, 22576, 22578, 
+        0, 16384, 20480, 22528, 22592, 22576,     0, 16384, 
+    20480, 22528, 22592, 22576, 22580,     0, 16384, 20480, 
+    22528, 22592, 22576, 22580,     0, 16384, 20480, 22528, 
+    22592, 22576, 22584, 22582,     0, 16384, 20480, 22528, 
+    22592, 22576,     0, 16384, 20480, 22528, 22592, 22593, 
+    22584,     0, 16384, 20480, 22528, 22592, 22593, 22584, 
+        0, 16384, 20480, 22528, 22592, 22593, 22584, 22586, 
+        0, 16384, 20480, 22528, 22592, 22593, 22584,     0, 
+    16384, 20480, 22528, 22592, 22593, 22584, 22588,     0, 
+    16384, 20480, 22528, 22592, 22593, 22595, 22588,     0, 
+    16384, 20480, 22528, 22592, 22593, 22595, 22588, 22590, 
+        0, 16384, 20480, 22528,     0, 16384, 20480, 22528, 
+    22592,     0, 16384, 20480, 22528, 22592,     0, 16384, 
+    20480, 22528, 22592, 22594,     0, 16384, 20480, 22528, 
+    22592,     0, 16384, 20480, 22528, 22592, 22596,     0, 
+    16384, 20480, 22528, 22592, 22596,     0, 16384, 20480, 
+    22528, 22592, 22600, 22598,     0, 16384, 20480, 22528, 
+    22592,     0, 16384, 20480, 22528, 22592, 22600,     0, 
+    16384, 20480, 22528, 22592, 22600,     0, 16384, 20480, 
+    22528, 22592, 22600, 22602,     0, 16384, 20480, 22528, 
+    22592, 22600,     0, 16384, 20480, 22528, 22592, 22608, 
+    22604,     0, 16384, 20480, 22528, 22592, 22608, 22604, 
+        0, 16384, 20480, 22528, 22592, 22608, 22609, 22606, 
+        0, 16384, 20480, 22528, 22592,     0, 16384, 20480, 
+    22528, 22592, 22608,     0, 16384, 20480, 22528, 22592, 
+    22608,     0, 16384, 20480, 22528, 22592, 22608, 22610, 
+        0, 16384, 20480, 22528, 22592, 22608,     0, 16384, 
+    20480, 22528, 22592, 22608, 22612,     0, 16384, 20480, 
+    22528, 22592, 22608, 22612,     0, 16384, 20480, 22528, 
+    22592, 22608, 22616, 22614,     0, 16384, 20480, 22528, 
+    22592, 22608,     0, 16384, 20480, 22528, 22592, 22624, 
+    22616,     0, 16384, 20480, 22528, 22592, 22624, 22616, 
+        0, 16384, 20480, 22528, 22592, 22624, 22616, 22618, 
+        0, 16384, 20480, 22528, 22592, 22624, 22616,     0, 
+    16384, 20480, 22528, 22592, 22624, 22625, 22620,     0, 
+    16384, 20480, 22528, 22592, 22624, 22625, 22620,     0, 
+    16384, 20480, 22528, 22592, 22624, 22625, 22620, 22622, 
+        0, 16384, 20480, 22528, 22592,     0, 16384, 20480, 
+    22528, 22656, 22624,     0, 16384, 20480, 22528, 22656, 
+    22624,     0, 16384, 20480, 22528, 22656, 22624, 22626, 
+        0, 16384, 20480, 22528, 22656, 22624,     0, 16384, 
+    20480, 22528, 22656, 22624, 22628,     0, 16384, 20480, 
+    22528, 22656, 22624, 22628,     0, 16384, 20480, 22528, 
+    22656, 22624, 22632, 22630,     0, 16384, 20480, 22528, 
+    22656, 22624,     0, 16384, 20480, 22528, 22656, 22624, 
+    22632,     0, 16384, 20480, 22528, 22656, 22624, 22632, 
+        0, 16384, 20480, 22528, 22656, 22624, 22632, 22634, 
+        0, 16384, 20480, 22528, 22656, 22624, 22632,     0, 
+    16384, 20480, 22528, 22656, 22624, 22640, 22636,     0, 
+    16384, 20480, 22528, 22656, 22624, 22640, 22636,     0, 
+    16384, 20480, 22528, 22656, 22624, 22640, 22641, 22638, 
+        0, 16384, 20480, 22528, 22656, 22624,     0, 16384, 
+    20480, 22528, 22656, 22657, 22640,     0, 16384, 20480, 
+    22528, 22656, 22657, 22640,     0, 16384, 20480, 22528, 
+    22656, 22657, 22640, 22642,     0, 16384, 20480, 22528, 
+    22656, 22657, 22640,     0, 16384, 20480, 22528, 22656, 
+    22657, 22640, 22644,     0, 16384, 20480, 22528, 22656, 
+    22657, 22640, 22644,     0, 16384, 20480, 22528, 22656, 
+    22657, 22640, 22648, 22646,     0, 16384, 20480, 22528, 
+    22656, 22657, 22640,     0, 16384, 20480, 22528, 22656, 
+    22657, 22640, 22648,     0, 16384, 20480, 22528, 22656, 
+    22657, 22659, 22648,     0, 16384, 20480, 22528, 22656, 
+    22657, 22659, 22648, 22650,     0, 16384, 20480, 22528, 
+    22656, 22657, 22659, 22648,     0, 16384, 20480, 22528, 
+    22656, 22657, 22659, 22648, 22652,     0, 16384, 20480, 
+    22528, 22656, 22657, 22659, 22648, 22652,     0, 16384, 
+    20480, 22528, 22656, 22657, 22659, 22648, 22652, 22654, 
+        0, 16384, 20480, 22528,     0, 16384, 20480, 22528, 
+    22656,     0, 16384, 20480, 22528, 22656,     0, 16384, 
+    20480, 22528, 22656, 22658,     0, 16384, 20480, 22528, 
+    22656,     0, 16384, 20480, 22528, 22656, 22660,     0, 
+    16384, 20480, 22528, 22656, 22660,     0, 16384, 20480, 
+    22528, 22656, 22664, 22662,     0, 16384, 20480, 22528, 
+    22656,     0, 16384, 20480, 22528, 22656, 22664,     0, 
+    16384, 20480, 22528, 22656, 22664,     0, 16384, 20480, 
+    22528, 22656, 22664, 22666,     0, 16384, 20480, 22528, 
+    22656, 22664,     0, 16384, 20480, 22528, 22656, 22672, 
+    22668,     0, 16384, 20480, 22528, 22656, 22672, 22668, 
+        0, 16384, 20480, 22528, 22656, 22672, 22673, 22670, 
+        0, 16384, 20480, 22528, 22656,     0, 16384, 20480, 
+    22528, 22656, 22672,     0, 16384, 20480, 22528, 22656, 
+    22672,     0, 16384, 20480, 22528, 22656, 22672, 22674, 
+        0, 16384, 20480, 22528, 22656, 22672,     0, 16384, 
+    20480, 22528, 22656, 22672, 22676,     0, 16384, 20480, 
+    22528, 22656, 22672, 22676,     0, 16384, 20480, 22528, 
+    22656, 22672, 22680, 22678,     0, 16384, 20480, 22528, 
+    22656, 22672,     0, 16384, 20480, 22528, 22656, 22688, 
+    22680,     0, 16384, 20480, 22528, 22656, 22688, 22680, 
+        0, 16384, 20480, 22528, 22656, 22688, 22680, 22682, 
+        0, 16384, 20480, 22528, 22656, 22688, 22680,     0, 
+    16384, 20480, 22528, 22656, 22688, 22689, 22684,     0, 
+    16384, 20480, 22528, 22656, 22688, 22689, 22684,     0, 
+    16384, 20480, 22528, 22656, 22688, 22689, 22684, 22686, 
+        0, 16384, 20480, 22528, 22656,     0, 16384, 20480, 
+    22528, 22656, 22688,     0, 16384, 20480, 22528, 22656, 
+    22688,     0, 16384, 20480, 22528, 22656, 22688, 22690, 
+        0, 16384, 20480, 22528, 22656, 22688,     0, 16384, 
+    20480, 22528, 22656, 22688, 22692,     0, 16384, 20480, 
+    22528, 22656, 22688, 22692,     0, 16384, 20480, 22528, 
+    22656, 22688, 22696, 22694,     0, 16384, 20480, 22528, 
+    22656, 22688,     0, 16384, 20480, 22528, 22656, 22688, 
+    22696,     0, 16384, 20480, 22528, 22656, 22688, 22696, 
+        0, 16384, 20480, 22528, 22656, 22688, 22696, 22698, 
+        0, 16384, 20480, 22528, 22656, 22688, 22696,     0, 
+    16384, 20480, 22528, 22656, 22688, 22704, 22700,     0, 
+    16384, 20480, 22528, 22656, 22688, 22704, 22700,     0, 
+    16384, 20480, 22528, 22656, 22688, 22704, 22705, 22702, 
+        0, 16384, 20480, 22528, 22656, 22688,     0, 16384, 
+    20480, 22528, 22656, 22720, 22704,     0, 16384, 20480, 
+    22528, 22656, 22720, 22704,     0, 16384, 20480, 22528, 
+    22656, 22720, 22704, 22706,     0, 16384, 20480, 22528, 
+    22656, 22720, 22704,     0, 16384, 20480, 22528, 22656, 
+    22720, 22704, 22708,     0, 16384, 20480, 22528, 22656, 
+    22720, 22704, 22708,     0, 16384, 20480, 22528, 22656, 
+    22720, 22704, 22712, 22710,     0, 16384, 20480, 22528, 
+    22656, 22720, 22704,     0, 16384, 20480, 22528, 22656, 
+    22720, 22721, 22712,     0, 16384, 20480, 22528, 22656, 
+    22720, 22721, 22712,     0, 16384, 20480, 22528, 22656, 
+    22720, 22721, 22712, 22714,     0, 16384, 20480, 22528, 
+    22656, 22720, 22721, 22712,     0, 16384, 20480, 22528, 
+    22656, 22720, 22721, 22712, 22716,     0, 16384, 20480, 
+    22528, 22656, 22720, 22721, 22723, 22716,     0, 16384, 
+    20480, 22528, 22656, 22720, 22721, 22723, 22716, 22718, 
+        0, 16384, 20480, 22528, 22656,     0, 16384, 20480, 
+    22528, 22784, 22720,     0, 16384, 20480, 22528, 22784, 
+    22720,     0, 16384, 20480, 22528, 22784, 22720, 22722, 
+        0, 16384, 20480, 22528, 22784, 22720,     0, 16384, 
+    20480, 22528, 22784, 22720, 22724,     0, 16384, 20480, 
+    22528, 22784, 22720, 22724,     0, 16384, 20480, 22528, 
+    22784, 22720, 22728, 22726,     0, 16384, 20480, 22528, 
+    22784, 22720,     0, 16384, 20480, 22528, 22784, 22720, 
+    22728,     0, 16384, 20480, 22528, 22784, 22720, 22728, 
+        0, 16384, 20480, 22528, 22784, 22720, 22728, 22730, 
+        0, 16384, 20480, 22528, 22784, 22720, 22728,     0, 
+    16384, 20480, 22528, 22784, 22720, 22736, 22732,     0, 
+    16384, 20480, 22528, 22784, 22720, 22736, 22732,     0, 
+    16384, 20480, 22528, 22784, 22720, 22736, 22737, 22734, 
+        0, 16384, 20480, 22528, 22784, 22720,     0, 16384, 
+    20480, 22528, 22784, 22720, 22736,     0, 16384, 20480, 
+    22528, 22784, 22720, 22736,     0, 16384, 20480, 22528, 
+    22784, 22720, 22736, 22738,     0, 16384, 20480, 22528, 
+    22784, 22720, 22736,     0, 16384, 20480, 22528, 22784, 
+    22720, 22736, 22740,     0, 16384, 20480, 22528, 22784, 
+    22720, 22736, 22740,     0, 16384, 20480, 22528, 22784, 
+    22720, 22736, 22744, 22742,     0, 16384, 20480, 22528, 
+    22784, 22720, 22736,     0, 16384, 20480, 22528, 22784, 
+    22720, 22752, 22744,     0, 16384, 20480, 22528, 22784, 
+    22720, 22752, 22744,     0, 16384, 20480, 22528, 22784, 
+    22720, 22752, 22744, 22746,     0, 16384, 20480, 22528, 
+    22784, 22720, 22752, 22744,     0, 16384, 20480, 22528, 
+    22784, 22720, 22752, 22753, 22748,     0, 16384, 20480, 
+    22528, 22784, 22720, 22752, 22753, 22748,     0, 16384, 
+    20480, 22528, 22784, 22720, 22752, 22753, 22748, 22750, 
+        0, 16384, 20480, 22528, 22784, 22720,     0, 16384, 
+    20480, 22528, 22784, 22785, 22752,     0, 16384, 20480, 
+    22528, 22784, 22785, 22752,     0, 16384, 20480, 22528, 
+    22784, 22785, 22752, 22754,     0, 16384, 20480, 22528, 
+    22784, 22785, 22752,     0, 16384, 20480, 22528, 22784, 
+    22785, 22752, 22756,     0, 16384, 20480, 22528, 22784, 
+    22785, 22752, 22756,     0, 16384, 20480, 22528, 22784, 
+    22785, 22752, 22760, 22758,     0, 16384, 20480, 22528, 
+    22784, 22785, 22752,     0, 16384, 20480, 22528, 22784, 
+    22785, 22752, 22760,     0, 16384, 20480, 22528, 22784, 
+    22785, 22752, 22760,     0, 16384, 20480, 22528, 22784, 
+    22785, 22752, 22760, 22762,     0, 16384, 20480, 22528, 
+    22784, 22785, 22752, 22760,     0, 16384, 20480, 22528, 
+    22784, 22785, 22752, 22768, 22764,     0, 16384, 20480, 
+    22528, 22784, 22785, 22752, 22768, 22764,     0, 16384, 
+    20480, 22528, 22784, 22785, 22752, 22768, 22769, 22766, 
+        0, 16384, 20480, 22528, 22784, 22785, 22752,     0, 
+    16384, 20480, 22528, 22784, 22785, 22752, 22768,     0, 
+    16384, 20480, 22528, 22784, 22785, 22787, 22768,     0, 
+    16384, 20480, 22528, 22784, 22785, 22787, 22768, 22770, 
+        0, 16384, 20480, 22528, 22784, 22785, 22787, 22768, 
+        0, 16384, 20480, 22528, 22784, 22785, 22787, 22768, 
+    22772,     0, 16384, 20480, 22528, 22784, 22785, 22787, 
+    22768, 22772,     0, 16384, 20480, 22528, 22784, 22785, 
+    22787, 22768, 22776, 22774,     0, 16384, 20480, 22528, 
+    22784, 22785, 22787, 22768,     0, 16384, 20480, 22528, 
+    22784, 22785, 22787, 22768, 22776,     0, 16384, 20480, 
+    22528, 22784, 22785, 22787, 22768, 22776,     0, 16384, 
+    20480, 22528, 22784, 22785, 22787, 22768, 22776, 22778, 
+        0, 16384, 20480, 22528, 22784, 22785, 22787, 22791, 
+    22776,     0, 16384, 20480, 22528, 22784, 22785, 22787, 
+    22791, 22776, 22780,     0, 16384, 20480, 22528, 22784, 
+    22785, 22787, 22791, 22776, 22780,     0, 16384, 20480, 
+    22528, 22784, 22785, 22787, 22791, 22776, 22780, 22782, 
+        0, 16384, 20480, 22528,     0, 16384, 20480, 22528, 
+    22784,     0, 16384, 20480, 22528, 22784,     0, 16384, 
+    20480, 22528, 22784, 22786,     0, 16384, 20480, 22528, 
+    22784,     0, 16384, 20480, 22528, 22784, 22788,     0, 
+    16384, 20480, 22528, 22784, 22788,     0, 16384, 20480, 
+    22528, 22784, 22792, 22790,     0, 16384, 20480, 22528, 
+    22784,     0, 16384, 20480, 22528, 22784, 22792,     0, 
+    16384, 20480, 22528, 22784, 22792,     0, 16384, 20480, 
+    22528, 22784, 22792, 22794,     0, 16384, 20480, 22528, 
+    22784, 22792,     0, 16384, 20480, 22528, 22784, 22800, 
+    22796,     0, 16384, 20480, 22528, 22784, 22800, 22796, 
+        0, 16384, 20480, 22528, 22784, 22800, 22801, 22798, 
+        0, 16384, 20480, 22528, 22784,     0, 16384, 20480, 
+    22528, 22784, 22800,     0, 16384, 20480, 22528, 22784, 
+    22800,     0, 16384, 20480, 22528, 22784, 22800, 22802, 
+        0, 16384, 20480, 22528, 22784, 22800,     0, 16384, 
+    20480, 22528, 22784, 22800, 22804,     0, 16384, 20480, 
+    22528, 22784, 22800, 22804,     0, 16384, 20480, 22528, 
+    22784, 22800, 22808, 22806,     0, 16384, 20480, 22528, 
+    22784, 22800,     0, 16384, 20480, 22528, 22784, 22816, 
+    22808,     0, 16384, 20480, 22528, 22784, 22816, 22808, 
+        0, 16384, 20480, 22528, 22784, 22816, 22808, 22810, 
+        0, 16384, 20480, 22528, 22784, 22816, 22808,     0, 
+    16384, 20480, 22528, 22784, 22816, 22817, 22812,     0, 
+    16384, 20480, 22528, 22784, 22816, 22817, 22812,     0, 
+    16384, 20480, 22528, 22784, 22816, 22817, 22812, 22814, 
+        0, 16384, 20480, 22528, 22784,     0, 16384, 20480, 
+    22528, 22784, 22816,     0, 16384, 20480, 22528, 22784, 
+    22816,     0, 16384, 20480, 22528, 22784, 22816, 22818, 
+        0, 16384, 20480, 22528, 22784, 22816,     0, 16384, 
+    20480, 22528, 22784, 22816, 22820,     0, 16384, 20480, 
+    22528, 22784, 22816, 22820,     0, 16384, 20480, 22528, 
+    22784, 22816, 22824, 22822,     0, 16384, 20480, 22528, 
+    22784, 22816,     0, 16384, 20480, 22528, 22784, 22816, 
+    22824,     0, 16384, 20480, 22528, 22784, 22816, 22824, 
+        0, 16384, 20480, 22528, 22784, 22816, 22824, 22826, 
+        0, 16384, 20480, 22528, 22784, 22816, 22824,     0, 
+    16384, 20480, 22528, 22784, 22816, 22832, 22828,     0, 
+    16384, 20480, 22528, 22784, 22816, 22832, 22828,     0, 
+    16384, 20480, 22528, 22784, 22816, 22832, 22833, 22830, 
+        0, 16384, 20480, 22528, 22784, 22816,     0, 16384, 
+    20480, 22528, 22784, 22848, 22832,     0, 16384, 20480, 
+    22528, 22784, 22848, 22832,     0, 16384, 20480, 22528, 
+    22784, 22848, 22832, 22834,     0, 16384, 20480, 22528, 
+    22784, 22848, 22832,     0, 16384, 20480, 22528, 22784, 
+    22848, 22832, 22836,     0, 16384, 20480, 22528, 22784, 
+    22848, 22832, 22836,     0, 16384, 20480, 22528, 22784, 
+    22848, 22832, 22840, 22838,     0, 16384, 20480, 22528, 
+    22784, 22848, 22832,     0, 16384, 20480, 22528, 22784, 
+    22848, 22849, 22840,     0, 16384, 20480, 22528, 22784, 
+    22848, 22849, 22840,     0, 16384, 20480, 22528, 22784, 
+    22848, 22849, 22840, 22842,     0, 16384, 20480, 22528, 
+    22784, 22848, 22849, 22840,     0, 16384, 20480, 22528, 
+    22784, 22848, 22849, 22840, 22844,     0, 16384, 20480, 
+    22528, 22784, 22848, 22849, 22851, 22844,     0, 16384, 
+    20480, 22528, 22784, 22848, 22849, 22851, 22844, 22846, 
+        0, 16384, 20480, 22528, 22784,     0, 16384, 20480, 
+    22528, 22784, 22848,     0, 16384, 20480, 22528, 22784, 
+    22848,     0, 16384, 20480, 22528, 22784, 22848, 22850, 
+        0, 16384, 20480, 22528, 22784, 22848,     0, 16384, 
+    20480, 22528, 22784, 22848, 22852,     0, 16384, 20480, 
+    22528, 22784, 22848, 22852,     0, 16384, 20480, 22528, 
+    22784, 22848, 22856, 22854,     0, 16384, 20480, 22528, 
+    22784, 22848,     0, 16384, 20480, 22528, 22784, 22848, 
+    22856,     0, 16384, 20480, 22528, 22784, 22848, 22856, 
+        0, 16384, 20480, 22528, 22784, 22848, 22856, 22858, 
+        0, 16384, 20480, 22528, 22784, 22848, 22856,     0, 
+    16384, 20480, 22528, 22784, 22848, 22864, 22860,     0, 
+    16384, 20480, 22528, 22784, 22848, 22864, 22860,     0, 
+    16384, 20480, 22528, 22784, 22848, 22864, 22865, 22862, 
+        0, 16384, 20480, 22528, 22784, 22848,     0, 16384, 
+    20480, 22528, 22784, 22848, 22864,     0, 16384, 20480, 
+    22528, 22784, 22848, 22864,     0, 16384, 20480, 22528, 
+    22784, 22848, 22864, 22866,     0, 16384, 20480, 22528, 
+    22784, 22848, 22864,     0, 16384, 20480, 22528, 22784, 
+    22848, 22864, 22868,     0, 16384, 20480, 22528, 22784, 
+    22848, 22864, 22868,     0, 16384, 20480, 22528, 22784, 
+    22848, 22864, 22872, 22870,     0, 16384, 20480, 22528, 
+    22784, 22848, 22864,     0, 16384, 20480, 22528, 22784, 
+    22848, 22880, 22872,     0, 16384, 20480, 22528, 22784, 
+    22848, 22880, 22872,     0, 16384, 20480, 22528, 22784, 
+    22848, 22880, 22872, 22874,     0, 16384, 20480, 22528, 
+    22784, 22848, 22880, 22872,     0, 16384, 20480, 22528, 
+    22784, 22848, 22880, 22881, 22876,     0, 16384, 20480, 
+    22528, 22784, 22848, 22880, 22881, 22876,     0, 16384, 
+    20480, 22528, 22784, 22848, 22880, 22881, 22876, 22878, 
+        0, 16384, 20480, 22528, 22784, 22848,     0, 16384, 
+    20480, 22528, 22784, 22912, 22880,     0, 16384, 20480, 
+    22528, 22784, 22912, 22880,     0, 16384, 20480, 22528, 
+    22784, 22912, 22880, 22882,     0, 16384, 20480, 22528, 
+    22784, 22912, 22880,     0, 16384, 20480, 22528, 22784, 
+    22912, 22880, 22884,     0, 16384, 20480, 22528, 22784, 
+    22912, 22880, 22884,     0, 16384, 20480, 22528, 22784, 
+    22912, 22880, 22888, 22886,     0, 16384, 20480, 22528, 
+    22784, 22912, 22880,     0, 16384, 20480, 22528, 22784, 
+    22912, 22880, 22888,     0, 16384, 20480, 22528, 22784, 
+    22912, 22880, 22888,     0, 16384, 20480, 22528, 22784, 
+    22912, 22880, 22888, 22890,     0, 16384, 20480, 22528, 
+    22784, 22912, 22880, 22888,     0, 16384, 20480, 22528, 
+    22784, 22912, 22880, 22896, 22892,     0, 16384, 20480, 
+    22528, 22784, 22912, 22880, 22896, 22892,     0, 16384, 
+    20480, 22528, 22784, 22912, 22880, 22896, 22897, 22894, 
+        0, 16384, 20480, 22528, 22784, 22912, 22880,     0, 
+    16384, 20480, 22528, 22784, 22912, 22913, 22896,     0, 
+    16384, 20480, 22528, 22784, 22912, 22913, 22896,     0, 
+    16384, 20480, 22528, 22784, 22912, 22913, 22896, 22898, 
+        0, 16384, 20480, 22528, 22784, 22912, 22913, 22896, 
+        0, 16384, 20480, 22528, 22784, 22912, 22913, 22896, 
+    22900,     0, 16384, 20480, 22528, 22784, 22912, 22913, 
+    22896, 22900,     0, 16384, 20480, 22528, 22784, 22912, 
+    22913, 22896, 22904, 22902,     0, 16384, 20480, 22528, 
+    22784, 22912, 22913, 22896,     0, 16384, 20480, 22528, 
+    22784, 22912, 22913, 22896, 22904,     0, 16384, 20480, 
+    22528, 22784, 22912, 22913, 22915, 22904,     0, 16384, 
+    20480, 22528, 22784, 22912, 22913, 22915, 22904, 22906, 
+        0, 16384, 20480, 22528, 22784, 22912, 22913, 22915, 
+    22904,     0, 16384, 20480, 22528, 22784, 22912, 22913, 
+    22915, 22904, 22908,     0, 16384, 20480, 22528, 22784, 
+    22912, 22913, 22915, 22904, 22908,     0, 16384, 20480, 
+    22528, 22784, 22912, 22913, 22915, 22904, 22908, 22910, 
+        0, 16384, 20480, 22528, 22784,     0, 16384, 20480, 
+    22528, 23040, 22912,     0, 16384, 20480, 22528, 23040, 
+    22912,     0, 16384, 20480, 22528, 23040, 22912, 22914, 
+        0, 16384, 20480, 22528, 23040, 22912,     0, 16384, 
+    20480, 22528, 23040, 22912, 22916,     0, 16384, 20480, 
+    22528, 23040, 22912, 22916,     0, 16384, 20480, 22528, 
+    23040, 22912, 22920, 22918,     0, 16384, 20480, 22528, 
+    23040, 22912,     0, 16384, 20480, 22528, 23040, 22912, 
+    22920,     0, 16384, 20480, 22528, 23040, 22912, 22920, 
+        0, 16384, 20480, 22528, 23040, 22912, 22920, 22922, 
+        0, 16384, 20480, 22528, 23040, 22912, 22920,     0, 
+    16384, 20480, 22528, 23040, 22912, 22928, 22924,     0, 
+    16384, 20480, 22528, 23040, 22912, 22928, 22924,     0, 
+    16384, 20480, 22528, 23040, 22912, 22928, 22929, 22926, 
+        0, 16384, 20480, 22528, 23040, 22912,     0, 16384, 
+    20480, 22528, 23040, 22912, 22928,     0, 16384, 20480, 
+    22528, 23040, 22912, 22928,     0, 16384, 20480, 22528, 
+    23040, 22912, 22928, 22930,     0, 16384, 20480, 22528, 
+    23040, 22912, 22928,     0, 16384, 20480, 22528, 23040, 
+    22912, 22928, 22932,     0, 16384, 20480, 22528, 23040, 
+    22912, 22928, 22932,     0, 16384, 20480, 22528, 23040, 
+    22912, 22928, 22936, 22934,     0, 16384, 20480, 22528, 
+    23040, 22912, 22928,     0, 16384, 20480, 22528, 23040, 
+    22912, 22944, 22936,     0, 16384, 20480, 22528, 23040, 
+    22912, 22944, 22936,     0, 16384, 20480, 22528, 23040, 
+    22912, 22944, 22936, 22938,     0, 16384, 20480, 22528, 
+    23040, 22912, 22944, 22936,     0, 16384, 20480, 22528, 
+    23040, 22912, 22944, 22945, 22940,     0, 16384, 20480, 
+    22528, 23040, 22912, 22944, 22945, 22940,     0, 16384, 
+    20480, 22528, 23040, 22912, 22944, 22945, 22940, 22942, 
+        0, 16384, 20480, 22528, 23040, 22912,     0, 16384, 
+    20480, 22528, 23040, 22912, 22944,     0, 16384, 20480, 
+    22528, 23040, 22912, 22944,     0, 16384, 20480, 22528, 
+    23040, 22912, 22944, 22946,     0, 16384, 20480, 22528, 
+    23040, 22912, 22944,     0, 16384, 20480, 22528, 23040, 
+    22912, 22944, 22948,     0, 16384, 20480, 22528, 23040, 
+    22912, 22944, 22948,     0, 16384, 20480, 22528, 23040, 
+    22912, 22944, 22952, 22950,     0, 16384, 20480, 22528, 
+    23040, 22912, 22944,     0, 16384, 20480, 22528, 23040, 
+    22912, 22944, 22952,     0, 16384, 20480, 22528, 23040, 
+    22912, 22944, 22952,     0, 16384, 20480, 22528, 23040, 
+    22912, 22944, 22952, 22954,     0, 16384, 20480, 22528, 
+    23040, 22912, 22944, 22952,     0, 16384, 20480, 22528, 
+    23040, 22912, 22944, 22960, 22956,     0, 16384, 20480, 
+    22528, 23040, 22912, 22944, 22960, 22956,     0, 16384, 
+    20480, 22528, 23040, 22912, 22944, 22960, 22961, 22958, 
+        0, 16384, 20480, 22528, 23040, 22912, 22944,     0, 
+    16384, 20480, 22528, 23040, 22912, 22976, 22960,     0, 
+    16384, 20480, 22528, 23040, 22912, 22976, 22960,     0, 
+    16384, 20480, 22528, 23040, 22912, 22976, 22960, 22962, 
+        0, 16384, 20480, 22528, 23040, 22912, 22976, 22960, 
+        0, 16384, 20480, 22528, 23040, 22912, 22976, 22960, 
+    22964,     0, 16384, 20480, 22528, 23040, 22912, 22976, 
+    22960, 22964,     0, 16384, 20480, 22528, 23040, 22912, 
+    22976, 22960, 22968, 22966,     0, 16384, 20480, 22528, 
+    23040, 22912, 22976, 22960,     0, 16384, 20480, 22528, 
+    23040, 22912, 22976, 22977, 22968,     0, 16384, 20480, 
+    22528, 23040, 22912, 22976, 22977, 22968,     0, 16384, 
+    20480, 22528, 23040, 22912, 22976, 22977, 22968, 22970, 
+        0, 16384, 20480, 22528, 23040, 22912, 22976, 22977, 
+    22968,     0, 16384, 20480, 22528, 23040, 22912, 22976, 
+    22977, 22968, 22972,     0, 16384, 20480, 22528, 23040, 
+    22912, 22976, 22977, 22979, 22972,     0, 16384, 20480, 
+    22528, 23040, 22912, 22976, 22977, 22979, 22972, 22974, 
+        0, 16384, 20480, 22528, 23040, 22912,     0, 16384, 
+    20480, 22528, 23040, 23041, 22976,     0, 16384, 20480, 
+    22528, 23040, 23041, 22976,     0, 16384, 20480, 22528, 
+    23040, 23041, 22976, 22978,     0, 16384, 20480, 22528, 
+    23040, 23041, 22976,     0, 16384, 20480, 22528, 23040, 
+    23041, 22976, 22980,     0, 16384, 20480, 22528, 23040, 
+    23041, 22976, 22980,     0, 16384, 20480, 22528, 23040, 
+    23041, 22976, 22984, 22982,     0, 16384, 20480, 22528, 
+    23040, 23041, 22976,     0, 16384, 20480, 22528, 23040, 
+    23041, 22976, 22984,     0, 16384, 20480, 22528, 23040, 
+    23041, 22976, 22984,     0, 16384, 20480, 22528, 23040, 
+    23041, 22976, 22984, 22986,     0, 16384, 20480, 22528, 
+    23040, 23041, 22976, 22984,     0, 16384, 20480, 22528, 
+    23040, 23041, 22976, 22992, 22988,     0, 16384, 20480, 
+    22528, 23040, 23041, 22976, 22992, 22988,     0, 16384, 
+    20480, 22528, 23040, 23041, 22976, 22992, 22993, 22990, 
+        0, 16384, 20480, 22528, 23040, 23041, 22976,     0, 
+    16384, 20480, 22528, 23040, 23041, 22976, 22992,     0, 
+    16384, 20480, 22528, 23040, 23041, 22976, 22992,     0, 
+    16384, 20480, 22528, 23040, 23041, 22976, 22992, 22994, 
+        0, 16384, 20480, 22528, 23040, 23041, 22976, 22992, 
+        0, 16384, 20480, 22528, 23040, 23041, 22976, 22992, 
+    22996,     0, 16384, 20480, 22528, 23040, 23041, 22976, 
+    22992, 22996,     0, 16384, 20480, 22528, 23040, 23041, 
+    22976, 22992, 23000, 22998,     0, 16384, 20480, 22528, 
+    23040, 23041, 22976, 22992,     0, 16384, 20480, 22528, 
+    23040, 23041, 22976, 23008, 23000,     0, 16384, 20480, 
+    22528, 23040, 23041, 22976, 23008, 23000,     0, 16384, 
+    20480, 22528, 23040, 23041, 22976, 23008, 23000, 23002, 
+        0, 16384, 20480, 22528, 23040, 23041, 22976, 23008, 
+    23000,     0, 16384, 20480, 22528, 23040, 23041, 22976, 
+    23008, 23009, 23004,     0, 16384, 20480, 22528, 23040, 
+    23041, 22976, 23008, 23009, 23004,     0, 16384, 20480, 
+    22528, 23040, 23041, 22976, 23008, 23009, 23004, 23006, 
+        0, 16384, 20480, 22528, 23040, 23041, 22976,     0, 
+    16384, 20480, 22528, 23040, 23041, 22976, 23008,     0, 
+    16384, 20480, 22528, 23040, 23041, 23043, 23008,     0, 
+    16384, 20480, 22528, 23040, 23041, 23043, 23008, 23010, 
+        0, 16384, 20480, 22528, 23040, 23041, 23043, 23008, 
+        0, 16384, 20480, 22528, 23040, 23041, 23043, 23008, 
+    23012,     0, 16384, 20480, 22528, 23040, 23041, 23043, 
+    23008, 23012,     0, 16384, 20480, 22528, 23040, 23041, 
+    23043, 23008, 23016, 23014,     0, 16384, 20480, 22528, 
+    23040, 23041, 23043, 23008,     0, 16384, 20480, 22528, 
+    23040, 23041, 23043, 23008, 23016,     0, 16384, 20480, 
+    22528, 23040, 23041, 23043, 23008, 23016,     0, 16384, 
+    20480, 22528, 23040, 23041, 23043, 23008, 23016, 23018, 
+        0, 16384, 20480, 22528, 23040, 23041, 23043, 23008, 
+    23016,     0, 16384, 20480, 22528, 23040, 23041, 23043, 
+    23008, 23024, 23020,     0, 16384, 20480, 22528, 23040, 
+    23041, 23043, 23008, 23024, 23020,     0, 16384, 20480, 
+    22528, 23040, 23041, 23043, 23008, 23024, 23025, 23022, 
+        0, 16384, 20480, 22528, 23040, 23041, 23043, 23008, 
+        0, 16384, 20480, 22528, 23040, 23041, 23043, 23008, 
+    23024,     0, 16384, 20480, 22528, 23040, 23041, 23043, 
+    23008, 23024,     0, 16384, 20480, 22528, 23040, 23041, 
+    23043, 23008, 23024, 23026,     0, 16384, 20480, 22528, 
+    23040, 23041, 23043, 23047, 23024,     0, 16384, 20480, 
+    22528, 23040, 23041, 23043, 23047, 23024, 23028,     0, 
+    16384, 20480, 22528, 23040, 23041, 23043, 23047, 23024, 
+    23028,     0, 16384, 20480, 22528, 23040, 23041, 23043, 
+    23047, 23024, 23032, 23030,     0, 16384, 20480, 22528, 
+    23040, 23041, 23043, 23047, 23024,     0, 16384, 20480, 
+    22528, 23040, 23041, 23043, 23047, 23024, 23032,     0, 
+    16384, 20480, 22528, 23040, 23041, 23043, 23047, 23024, 
+    23032,     0, 16384, 20480, 22528, 23040, 23041, 23043, 
+    23047, 23024, 23032, 23034,     0, 16384, 20480, 22528, 
+    23040, 23041, 23043, 23047, 23024, 23032,     0, 16384, 
+    20480, 22528, 23040, 23041, 23043, 23047, 23024, 23032, 
+    23036,     0, 16384, 20480, 22528, 23040, 23041, 23043, 
+    23047, 23024, 23032, 23036,     0, 16384, 20480, 22528, 
+    23040, 23041, 23043, 23047, 23024, 23032, 23036, 23038, 
+        0, 16384, 20480, 22528,     0, 16384, 20480, 22528, 
+    23040,     0, 16384, 20480, 22528, 23040,     0, 16384, 
+    20480, 22528, 23040, 23042,     0, 16384, 20480, 22528, 
+    23040,     0, 16384, 20480, 22528, 23040, 23044,     0, 
+    16384, 20480, 22528, 23040, 23044,     0, 16384, 20480, 
+    22528, 23040, 23048, 23046,     0, 16384, 20480, 22528, 
+    23040,     0, 16384, 20480, 22528, 23040, 23048,     0, 
+    16384, 20480, 22528, 23040, 23048,     0, 16384, 20480, 
+    22528, 23040, 23048, 23050,     0, 16384, 20480, 22528, 
+    23040, 23048,     0, 16384, 20480, 22528, 23040, 23056, 
+    23052,     0, 16384, 20480, 22528, 23040, 23056, 23052, 
+        0, 16384, 20480, 22528, 23040, 23056, 23057, 23054, 
+        0, 16384, 20480, 22528, 23040,     0, 16384, 20480, 
+    22528, 23040, 23056,     0, 16384, 20480, 22528, 23040, 
+    23056,     0, 16384, 20480, 22528, 23040, 23056, 23058, 
+        0, 16384, 20480, 22528, 23040, 23056,     0, 16384, 
+    20480, 22528, 23040, 23056, 23060,     0, 16384, 20480, 
+    22528, 23040, 23056, 23060,     0, 16384, 20480, 22528, 
+    23040, 23056, 23064, 23062,     0, 16384, 20480, 22528, 
+    23040, 23056,     0, 16384, 20480, 22528, 23040, 23072, 
+    23064,     0, 16384, 20480, 22528, 23040, 23072, 23064, 
+        0, 16384, 20480, 22528, 23040, 23072, 23064, 23066, 
+        0, 16384, 20480, 22528, 23040, 23072, 23064,     0, 
+    16384, 20480, 22528, 23040, 23072, 23073, 23068,     0, 
+    16384, 20480, 22528, 23040, 23072, 23073, 23068,     0, 
+    16384, 20480, 22528, 23040, 23072, 23073, 23068, 23070, 
+        0, 16384, 20480, 22528, 23040,     0, 16384, 20480, 
+    22528, 23040, 23072,     0, 16384, 20480, 22528, 23040, 
+    23072,     0, 16384, 20480, 22528, 23040, 23072, 23074, 
+        0, 16384, 20480, 22528, 23040, 23072,     0, 16384, 
+    20480, 22528, 23040, 23072, 23076,     0, 16384, 20480, 
+    22528, 23040, 23072, 23076,     0, 16384, 20480, 22528, 
+    23040, 23072, 23080, 23078,     0, 16384, 20480, 22528, 
+    23040, 23072,     0, 16384, 20480, 22528, 23040, 23072, 
+    23080,     0, 16384, 20480, 22528, 23040, 23072, 23080, 
+        0, 16384, 20480, 22528, 23040, 23072, 23080, 23082, 
+        0, 16384, 20480, 22528, 23040, 23072, 23080,     0, 
+    16384, 20480, 22528, 23040, 23072, 23088, 23084,     0, 
+    16384, 20480, 22528, 23040, 23072, 23088, 23084,     0, 
+    16384, 20480, 22528, 23040, 23072, 23088, 23089, 23086, 
+        0, 16384, 20480, 22528, 23040, 23072,     0, 16384, 
+    20480, 22528, 23040, 23104, 23088,     0, 16384, 20480, 
+    22528, 23040, 23104, 23088,     0, 16384, 20480, 22528, 
+    23040, 23104, 23088, 23090,     0, 16384, 20480, 22528, 
+    23040, 23104, 23088,     0, 16384, 20480, 22528, 23040, 
+    23104, 23088, 23092,     0, 16384, 20480, 22528, 23040, 
+    23104, 23088, 23092,     0, 16384, 20480, 22528, 23040, 
+    23104, 23088, 23096, 23094,     0, 16384, 20480, 22528, 
+    23040, 23104, 23088,     0, 16384, 20480, 22528, 23040, 
+    23104, 23105, 23096,     0, 16384, 20480, 22528, 23040, 
+    23104, 23105, 23096,     0, 16384, 20480, 22528, 23040, 
+    23104, 23105, 23096, 23098,     0, 16384, 20480, 22528, 
+    23040, 23104, 23105, 23096,     0, 16384, 20480, 22528, 
+    23040, 23104, 23105, 23096, 23100,     0, 16384, 20480, 
+    22528, 23040, 23104, 23105, 23107, 23100,     0, 16384, 
+    20480, 22528, 23040, 23104, 23105, 23107, 23100, 23102, 
+        0, 16384, 20480, 22528, 23040,     0, 16384, 20480, 
+    22528, 23040, 23104,     0, 16384, 20480, 22528, 23040, 
+    23104,     0, 16384, 20480, 22528, 23040, 23104, 23106, 
+        0, 16384, 20480, 22528, 23040, 23104,     0, 16384, 
+    20480, 22528, 23040, 23104, 23108,     0, 16384, 20480, 
+    22528, 23040, 23104, 23108,     0, 16384, 20480, 22528, 
+    23040, 23104, 23112, 23110,     0, 16384, 20480, 22528, 
+    23040, 23104,     0, 16384, 20480, 22528, 23040, 23104, 
+    23112,     0, 16384, 20480, 22528, 23040, 23104, 23112, 
+        0, 16384, 20480, 22528, 23040, 23104, 23112, 23114, 
+        0, 16384, 20480, 22528, 23040, 23104, 23112,     0, 
+    16384, 20480, 22528, 23040, 23104, 23120, 23116,     0, 
+    16384, 20480, 22528, 23040, 23104, 23120, 23116,     0, 
+    16384, 20480, 22528, 23040, 23104, 23120, 23121, 23118, 
+        0, 16384, 20480, 22528, 23040, 23104,     0, 16384, 
+    20480, 22528, 23040, 23104, 23120,     0, 16384, 20480, 
+    22528, 23040, 23104, 23120,     0, 16384, 20480, 22528, 
+    23040, 23104, 23120, 23122,     0, 16384, 20480, 22528, 
+    23040, 23104, 23120,     0, 16384, 20480, 22528, 23040, 
+    23104, 23120, 23124,     0, 16384, 20480, 22528, 23040, 
+    23104, 23120, 23124,     0, 16384, 20480, 22528, 23040, 
+    23104, 23120, 23128, 23126,     0, 16384, 20480, 22528, 
+    23040, 23104, 23120,     0, 16384, 20480, 22528, 23040, 
+    23104, 23136, 23128,     0, 16384, 20480, 22528, 23040, 
+    23104, 23136, 23128,     0, 16384, 20480, 22528, 23040, 
+    23104, 23136, 23128, 23130,     0, 16384, 20480, 22528, 
+    23040, 23104, 23136, 23128,     0, 16384, 20480, 22528, 
+    23040, 23104, 23136, 23137, 23132,     0, 16384, 20480, 
+    22528, 23040, 23104, 23136, 23137, 23132,     0, 16384, 
+    20480, 22528, 23040, 23104, 23136, 23137, 23132, 23134, 
+        0, 16384, 20480, 22528, 23040, 23104,     0, 16384, 
+    20480, 22528, 23040, 23168, 23136,     0, 16384, 20480, 
+    22528, 23040, 23168, 23136,     0, 16384, 20480, 22528, 
+    23040, 23168, 23136, 23138,     0, 16384, 20480, 22528, 
+    23040, 23168, 23136,     0, 16384, 20480, 22528, 23040, 
+    23168, 23136, 23140,     0, 16384, 20480, 22528, 23040, 
+    23168, 23136, 23140,     0, 16384, 20480, 22528, 23040, 
+    23168, 23136, 23144, 23142,     0, 16384, 20480, 22528, 
+    23040, 23168, 23136,     0, 16384, 20480, 22528, 23040, 
+    23168, 23136, 23144,     0, 16384, 20480, 22528, 23040, 
+    23168, 23136, 23144,     0, 16384, 20480, 22528, 23040, 
+    23168, 23136, 23144, 23146,     0, 16384, 20480, 22528, 
+    23040, 23168, 23136, 23144,     0, 16384, 20480, 22528, 
+    23040, 23168, 23136, 23152, 23148,     0, 16384, 20480, 
+    22528, 23040, 23168, 23136, 23152, 23148,     0, 16384, 
+    20480, 22528, 23040, 23168, 23136, 23152, 23153, 23150, 
+        0, 16384, 20480, 22528, 23040, 23168, 23136,     0, 
+    16384, 20480, 22528, 23040, 23168, 23169, 23152,     0, 
+    16384, 20480, 22528, 23040, 23168, 23169, 23152,     0, 
+    16384, 20480, 22528, 23040, 23168, 23169, 23152, 23154, 
+        0, 16384, 20480, 22528, 23040, 23168, 23169, 23152, 
+        0, 16384, 20480, 22528, 23040, 23168, 23169, 23152, 
+    23156,     0, 16384, 20480, 22528, 23040, 23168, 23169, 
+    23152, 23156,     0, 16384, 20480, 22528, 23040, 23168, 
+    23169, 23152, 23160, 23158,     0, 16384, 20480, 22528, 
+    23040, 23168, 23169, 23152,     0, 16384, 20480, 22528, 
+    23040, 23168, 23169, 23152, 23160,     0, 16384, 20480, 
+    22528, 23040, 23168, 23169, 23171, 23160,     0, 16384, 
+    20480, 22528, 23040, 23168, 23169, 23171, 23160, 23162, 
+        0, 16384, 20480, 22528, 23040, 23168, 23169, 23171, 
+    23160,     0, 16384, 20480, 22528, 23040, 23168, 23169, 
+    23171, 23160, 23164,     0, 16384, 20480, 22528, 23040, 
+    23168, 23169, 23171, 23160, 23164,     0, 16384, 20480, 
+    22528, 23040, 23168, 23169, 23171, 23160, 23164, 23166, 
+        0, 16384, 20480, 22528, 23040,     0, 16384, 20480, 
+    22528, 23040, 23168,     0, 16384, 20480, 22528, 23040, 
+    23168,     0, 16384, 20480, 22528, 23040, 23168, 23170, 
+        0, 16384, 20480, 22528, 23040, 23168,     0, 16384, 
+    20480, 22528, 23040, 23168, 23172,     0, 16384, 20480, 
+    22528, 23040, 23168, 23172,     0, 16384, 20480, 22528, 
+    23040, 23168, 23176, 23174,     0, 16384, 20480, 22528, 
+    23040, 23168,     0, 16384, 20480, 22528, 23040, 23168, 
+    23176,     0, 16384, 20480, 22528, 23040, 23168, 23176, 
+        0, 16384, 20480, 22528, 23040, 23168, 23176, 23178, 
+        0, 16384, 20480, 22528, 23040, 23168, 23176,     0, 
+    16384, 20480, 22528, 23040, 23168, 23184, 23180,     0, 
+    16384, 20480, 22528, 23040, 23168, 23184, 23180,     0, 
+    16384, 20480, 22528, 23040, 23168, 23184, 23185, 23182, 
+        0, 16384, 20480, 22528, 23040, 23168,     0, 16384, 
+    20480, 22528, 23040, 23168, 23184,     0, 16384, 20480, 
+    22528, 23040, 23168, 23184,     0, 16384, 20480, 22528, 
+    23040, 23168, 23184, 23186,     0, 16384, 20480, 22528, 
+    23040, 23168, 23184,     0, 16384, 20480, 22528, 23040, 
+    23168, 23184, 23188,     0, 16384, 20480, 22528, 23040, 
+    23168, 23184, 23188,     0, 16384, 20480, 22528, 23040, 
+    23168, 23184, 23192, 23190,     0, 16384, 20480, 22528, 
+    23040, 23168, 23184,     0, 16384, 20480, 22528, 23040, 
+    23168, 23200, 23192,     0, 16384, 20480, 22528, 23040, 
+    23168, 23200, 23192,     0, 16384, 20480, 22528, 23040, 
+    23168, 23200, 23192, 23194,     0, 16384, 20480, 22528, 
+    23040, 23168, 23200, 23192,     0, 16384, 20480, 22528, 
+    23040, 23168, 23200, 23201, 23196,     0, 16384, 20480, 
+    22528, 23040, 23168, 23200, 23201, 23196,     0, 16384, 
+    20480, 22528, 23040, 23168, 23200, 23201, 23196, 23198, 
+        0, 16384, 20480, 22528, 23040, 23168,     0, 16384, 
+    20480, 22528, 23040, 23168, 23200,     0, 16384, 20480, 
+    22528, 23040, 23168, 23200,     0, 16384, 20480, 22528, 
+    23040, 23168, 23200, 23202,     0, 16384, 20480, 22528, 
+    23040, 23168, 23200,     0, 16384, 20480, 22528, 23040, 
+    23168, 23200, 23204,     0, 16384, 20480, 22528, 23040, 
+    23168, 23200, 23204,     0, 16384, 20480, 22528, 23040, 
+    23168, 23200, 23208, 23206,     0, 16384, 20480, 22528, 
+    23040, 23168, 23200,     0, 16384, 20480, 22528, 23040, 
+    23168, 23200, 23208,     0, 16384, 20480, 22528, 23040, 
+    23168, 23200, 23208,     0, 16384, 20480, 22528, 23040, 
+    23168, 23200, 23208, 23210,     0, 16384, 20480, 22528, 
+    23040, 23168, 23200, 23208,     0, 16384, 20480, 22528, 
+    23040, 23168, 23200, 23216, 23212,     0, 16384, 20480, 
+    22528, 23040, 23168, 23200, 23216, 23212,     0, 16384, 
+    20480, 22528, 23040, 23168, 23200, 23216, 23217, 23214, 
+        0, 16384, 20480, 22528, 23040, 23168, 23200,     0, 
+    16384, 20480, 22528, 23040, 23168, 23232, 23216,     0, 
+    16384, 20480, 22528, 23040, 23168, 23232, 23216,     0, 
+    16384, 20480, 22528, 23040, 23168, 23232, 23216, 23218, 
+        0, 16384, 20480, 22528, 23040, 23168, 23232, 23216, 
+        0, 16384, 20480, 22528, 23040, 23168, 23232, 23216, 
+    23220,     0, 16384, 20480, 22528, 23040, 23168, 23232, 
+    23216, 23220,     0, 16384, 20480, 22528, 23040, 23168, 
+    23232, 23216, 23224, 23222,     0, 16384, 20480, 22528, 
+    23040, 23168, 23232, 23216,     0, 16384, 20480, 22528, 
+    23040, 23168, 23232, 23233, 23224,     0, 16384, 20480, 
+    22528, 23040, 23168, 23232, 23233, 23224,     0, 16384, 
+    20480, 22528, 23040, 23168, 23232, 23233, 23224, 23226, 
+        0, 16384, 20480, 22528, 23040, 23168, 23232, 23233, 
+    23224,     0, 16384, 20480, 22528, 23040, 23168, 23232, 
+    23233, 23224, 23228,     0, 16384, 20480, 22528, 23040, 
+    23168, 23232, 23233, 23235, 23228,     0, 16384, 20480, 
+    22528, 23040, 23168, 23232, 23233, 23235, 23228, 23230, 
+        0, 16384, 20480, 22528, 23040, 23168,     0, 16384, 
+    20480, 22528, 23040, 23296, 23232,     0, 16384, 20480, 
+    22528, 23040, 23296, 23232,     0, 16384, 20480, 22528, 
+    23040, 23296, 23232, 23234,     0, 16384, 20480, 22528, 
+    23040, 23296, 23232,     0, 16384, 20480, 22528, 23040, 
+    23296, 23232, 23236,     0, 16384, 20480, 22528, 23040, 
+    23296, 23232, 23236,     0, 16384, 20480, 22528, 23040, 
+    23296, 23232, 23240, 23238,     0, 16384, 20480, 22528, 
+    23040, 23296, 23232,     0, 16384, 20480, 22528, 23040, 
+    23296, 23232, 23240,     0, 16384, 20480, 22528, 23040, 
+    23296, 23232, 23240,     0, 16384, 20480, 22528, 23040, 
+    23296, 23232, 23240, 23242,     0, 16384, 20480, 22528, 
+    23040, 23296, 23232, 23240,     0, 16384, 20480, 22528, 
+    23040, 23296, 23232, 23248, 23244,     0, 16384, 20480, 
+    22528, 23040, 23296, 23232, 23248, 23244,     0, 16384, 
+    20480, 22528, 23040, 23296, 23232, 23248, 23249, 23246, 
+        0, 16384, 20480, 22528, 23040, 23296, 23232,     0, 
+    16384, 20480, 22528, 23040, 23296, 23232, 23248,     0, 
+    16384, 20480, 22528, 23040, 23296, 23232, 23248,     0, 
+    16384, 20480, 22528, 23040, 23296, 23232, 23248, 23250, 
+        0, 16384, 20480, 22528, 23040, 23296, 23232, 23248, 
+        0, 16384, 20480, 22528, 23040, 23296, 23232, 23248, 
+    23252,     0, 16384, 20480, 22528, 23040, 23296, 23232, 
+    23248, 23252,     0, 16384, 20480, 22528, 23040, 23296, 
+    23232, 23248, 23256, 23254,     0, 16384, 20480, 22528, 
+    23040, 23296, 23232, 23248,     0, 16384, 20480, 22528, 
+    23040, 23296, 23232, 23264, 23256,     0, 16384, 20480, 
+    22528, 23040, 23296, 23232, 23264, 23256,     0, 16384, 
+    20480, 22528, 23040, 23296, 23232, 23264, 23256, 23258, 
+        0, 16384, 20480, 22528, 23040, 23296, 23232, 23264, 
+    23256,     0, 16384, 20480, 22528, 23040, 23296, 23232, 
+    23264, 23265, 23260,     0, 16384, 20480, 22528, 23040, 
+    23296, 23232, 23264, 23265, 23260,     0, 16384, 20480, 
+    22528, 23040, 23296, 23232, 23264, 23265, 23260, 23262, 
+        0, 16384, 20480, 22528, 23040, 23296, 23232,     0, 
+    16384, 20480, 22528, 23040, 23296, 23297, 23264,     0, 
+    16384, 20480, 22528, 23040, 23296, 23297, 23264,     0, 
+    16384, 20480, 22528, 23040, 23296, 23297, 23264, 23266, 
+        0, 16384, 20480, 22528, 23040, 23296, 23297, 23264, 
+        0, 16384, 20480, 22528, 23040, 23296, 23297, 23264, 
+    23268,     0, 16384, 20480, 22528, 23040, 23296, 23297, 
+    23264, 23268,     0, 16384, 20480, 22528, 23040, 23296, 
+    23297, 23264, 23272, 23270,     0, 16384, 20480, 22528, 
+    23040, 23296, 23297, 23264,     0, 16384, 20480, 22528, 
+    23040, 23296, 23297, 23264, 23272,     0, 16384, 20480, 
+    22528, 23040, 23296, 23297, 23264, 23272,     0, 16384, 
+    20480, 22528, 23040, 23296, 23297, 23264, 23272, 23274, 
+        0, 16384, 20480, 22528, 23040, 23296, 23297, 23264, 
+    23272,     0, 16384, 20480, 22528, 23040, 23296, 23297, 
+    23264, 23280, 23276,     0, 16384, 20480, 22528, 23040, 
+    23296, 23297, 23264, 23280, 23276,     0, 16384, 20480, 
+    22528, 23040, 23296, 23297, 23264, 23280, 23281, 23278, 
+        0, 16384, 20480, 22528, 23040, 23296, 23297, 23264, 
+        0, 16384, 20480, 22528, 23040, 23296, 23297, 23264, 
+    23280,     0, 16384, 20480, 22528, 23040, 23296, 23297, 
+    23299, 23280,     0, 16384, 20480, 22528, 23040, 23296, 
+    23297, 23299, 23280, 23282,     0, 16384, 20480, 22528, 
+    23040, 23296, 23297, 23299, 23280,     0, 16384, 20480, 
+    22528, 23040, 23296, 23297, 23299, 23280, 23284,     0, 
+    16384, 20480, 22528, 23040, 23296, 23297, 23299, 23280, 
+    23284,     0, 16384, 20480, 22528, 23040, 23296, 23297, 
+    23299, 23280, 23288, 23286,     0, 16384, 20480, 22528, 
+    23040, 23296, 23297, 23299, 23280,     0, 16384, 20480, 
+    22528, 23040, 23296, 23297, 23299, 23280, 23288,     0, 
+    16384, 20480, 22528, 23040, 23296, 23297, 23299, 23280, 
+    23288,     0, 16384, 20480, 22528, 23040, 23296, 23297, 
+    23299, 23280, 23288, 23290,     0, 16384, 20480, 22528, 
+    23040, 23296, 23297, 23299, 23303, 23288,     0, 16384, 
+    20480, 22528, 23040, 23296, 23297, 23299, 23303, 23288, 
+    23292,     0, 16384, 20480, 22528, 23040, 23296, 23297, 
+    23299, 23303, 23288, 23292,     0, 16384, 20480, 22528, 
+    23040, 23296, 23297, 23299, 23303, 23288, 23292, 23294, 
+        0, 16384, 20480, 22528, 23040,     0, 16384, 20480, 
+    22528, 23552, 23296,     0, 16384, 20480, 22528, 23552, 
+    23296,     0, 16384, 20480, 22528, 23552, 23296, 23298, 
+        0, 16384, 20480, 22528, 23552, 23296,     0, 16384, 
+    20480, 22528, 23552, 23296, 23300,     0, 16384, 20480, 
+    22528, 23552, 23296, 23300,     0, 16384, 20480, 22528, 
+    23552, 23296, 23304, 23302,     0, 16384, 20480, 22528, 
+    23552, 23296,     0, 16384, 20480, 22528, 23552, 23296, 
+    23304,     0, 16384, 20480, 22528, 23552, 23296, 23304, 
+        0, 16384, 20480, 22528, 23552, 23296, 23304, 23306, 
+        0, 16384, 20480, 22528, 23552, 23296, 23304,     0, 
+    16384, 20480, 22528, 23552, 23296, 23312, 23308,     0, 
+    16384, 20480, 22528, 23552, 23296, 23312, 23308,     0, 
+    16384, 20480, 22528, 23552, 23296, 23312, 23313, 23310, 
+        0, 16384, 20480, 22528, 23552, 23296,     0, 16384, 
+    20480, 22528, 23552, 23296, 23312,     0, 16384, 20480, 
+    22528, 23552, 23296, 23312,     0, 16384, 20480, 22528, 
+    23552, 23296, 23312, 23314,     0, 16384, 20480, 22528, 
+    23552, 23296, 23312,     0, 16384, 20480, 22528, 23552, 
+    23296, 23312, 23316,     0, 16384, 20480, 22528, 23552, 
+    23296, 23312, 23316,     0, 16384, 20480, 22528, 23552, 
+    23296, 23312, 23320, 23318,     0, 16384, 20480, 22528, 
+    23552, 23296, 23312,     0, 16384, 20480, 22528, 23552, 
+    23296, 23328, 23320,     0, 16384, 20480, 22528, 23552, 
+    23296, 23328, 23320,     0, 16384, 20480, 22528, 23552, 
+    23296, 23328, 23320, 23322,     0, 16384, 20480, 22528, 
+    23552, 23296, 23328, 23320,     0, 16384, 20480, 22528, 
+    23552, 23296, 23328, 23329, 23324,     0, 16384, 20480, 
+    22528, 23552, 23296, 23328, 23329, 23324,     0, 16384, 
+    20480, 22528, 23552, 23296, 23328, 23329, 23324, 23326, 
+        0, 16384, 20480, 22528, 23552, 23296,     0, 16384, 
+    20480, 22528, 23552, 23296, 23328,     0, 16384, 20480, 
+    22528, 23552, 23296, 23328,     0, 16384, 20480, 22528, 
+    23552, 23296, 23328, 23330,     0, 16384, 20480, 22528, 
+    23552, 23296, 23328,     0, 16384, 20480, 22528, 23552, 
+    23296, 23328, 23332,     0, 16384, 20480, 22528, 23552, 
+    23296, 23328, 23332,     0, 16384, 20480, 22528, 23552, 
+    23296, 23328, 23336, 23334,     0, 16384, 20480, 22528, 
+    23552, 23296, 23328,     0, 16384, 20480, 22528, 23552, 
+    23296, 23328, 23336,     0, 16384, 20480, 22528, 23552, 
+    23296, 23328, 23336,     0, 16384, 20480, 22528, 23552, 
+    23296, 23328, 23336, 23338,     0, 16384, 20480, 22528, 
+    23552, 23296, 23328, 23336,     0, 16384, 20480, 22528, 
+    23552, 23296, 23328, 23344, 23340,     0, 16384, 20480, 
+    22528, 23552, 23296, 23328, 23344, 23340,     0, 16384, 
+    20480, 22528, 23552, 23296, 23328, 23344, 23345, 23342, 
+        0, 16384, 20480, 22528, 23552, 23296, 23328,     0, 
+    16384, 20480, 22528, 23552, 23296, 23360, 23344,     0, 
+    16384, 20480, 22528, 23552, 23296, 23360, 23344,     0, 
+    16384, 20480, 22528, 23552, 23296, 23360, 23344, 23346, 
+        0, 16384, 20480, 22528, 23552, 23296, 23360, 23344, 
+        0, 16384, 20480, 22528, 23552, 23296, 23360, 23344, 
+    23348,     0, 16384, 20480, 22528, 23552, 23296, 23360, 
+    23344, 23348,     0, 16384, 20480, 22528, 23552, 23296, 
+    23360, 23344, 23352, 23350,     0, 16384, 20480, 22528, 
+    23552, 23296, 23360, 23344,     0, 16384, 20480, 22528, 
+    23552, 23296, 23360, 23361, 23352,     0, 16384, 20480, 
+    22528, 23552, 23296, 23360, 23361, 23352,     0, 16384, 
+    20480, 22528, 23552, 23296, 23360, 23361, 23352, 23354, 
+        0, 16384, 20480, 22528, 23552, 23296, 23360, 23361, 
+    23352,     0, 16384, 20480, 22528, 23552, 23296, 23360, 
+    23361, 23352, 23356,     0, 16384, 20480, 22528, 23552, 
+    23296, 23360, 23361, 23363, 23356,     0, 16384, 20480, 
+    22528, 23552, 23296, 23360, 23361, 23363, 23356, 23358, 
+        0, 16384, 20480, 22528, 23552, 23296,     0, 16384, 
+    20480, 22528, 23552, 23296, 23360,     0, 16384, 20480, 
+    22528, 23552, 23296, 23360,     0, 16384, 20480, 22528, 
+    23552, 23296, 23360, 23362,     0, 16384, 20480, 22528, 
+    23552, 23296, 23360,     0, 16384, 20480, 22528, 23552, 
+    23296, 23360, 23364,     0, 16384, 20480, 22528, 23552, 
+    23296, 23360, 23364,     0, 16384, 20480, 22528, 23552, 
+    23296, 23360, 23368, 23366,     0, 16384, 20480, 22528, 
+    23552, 23296, 23360,     0, 16384, 20480, 22528, 23552, 
+    23296, 23360, 23368,     0, 16384, 20480, 22528, 23552, 
+    23296, 23360, 23368,     0, 16384, 20480, 22528, 23552, 
+    23296, 23360, 23368, 23370,     0, 16384, 20480, 22528, 
+    23552, 23296, 23360, 23368,     0, 16384, 20480, 22528, 
+    23552, 23296, 23360, 23376, 23372,     0, 16384, 20480, 
+    22528, 23552, 23296, 23360, 23376, 23372,     0, 16384, 
+    20480, 22528, 23552, 23296, 23360, 23376, 23377, 23374, 
+        0, 16384, 20480, 22528, 23552, 23296, 23360,     0, 
+    16384, 20480, 22528, 23552, 23296, 23360, 23376,     0, 
+    16384, 20480, 22528, 23552, 23296, 23360, 23376,     0, 
+    16384, 20480, 22528, 23552, 23296, 23360, 23376, 23378, 
+        0, 16384, 20480, 22528, 23552, 23296, 23360, 23376, 
+        0, 16384, 20480, 22528, 23552, 23296, 23360, 23376, 
+    23380,     0, 16384, 20480, 22528, 23552, 23296, 23360, 
+    23376, 23380,     0, 16384, 20480, 22528, 23552, 23296, 
+    23360, 23376, 23384, 23382,     0, 16384, 20480, 22528, 
+    23552, 23296, 23360, 23376,     0, 16384, 20480, 22528, 
+    23552, 23296, 23360, 23392, 23384,     0, 16384, 20480, 
+    22528, 23552, 23296, 23360, 23392, 23384,     0, 16384, 
+    20480, 22528, 23552, 23296, 23360, 23392, 23384, 23386, 
+        0, 16384, 20480, 22528, 23552, 23296, 23360, 23392, 
+    23384,     0, 16384, 20480, 22528, 23552, 23296, 23360, 
+    23392, 23393, 23388,     0, 16384, 20480, 22528, 23552, 
+    23296, 23360, 23392, 23393, 23388,     0, 16384, 20480, 
+    22528, 23552, 23296, 23360, 23392, 23393, 23388, 23390, 
+        0, 16384, 20480, 22528, 23552, 23296, 23360,     0, 
+    16384, 20480, 22528, 23552, 23296, 23424, 23392,     0, 
+    16384, 20480, 22528, 23552, 23296, 23424, 23392,     0, 
+    16384, 20480, 22528, 23552, 23296, 23424, 23392, 23394, 
+        0, 16384, 20480, 22528, 23552, 23296, 23424, 23392, 
+        0, 16384, 20480, 22528, 23552, 23296, 23424, 23392, 
+    23396,     0, 16384, 20480, 22528, 23552, 23296, 23424, 
+    23392, 23396,     0, 16384, 20480, 22528, 23552, 23296, 
+    23424, 23392, 23400, 23398,     0, 16384, 20480, 22528, 
+    23552, 23296, 23424, 23392,     0, 16384, 20480, 22528, 
+    23552, 23296, 23424, 23392, 23400,     0, 16384, 20480, 
+    22528, 23552, 23296, 23424, 23392, 23400,     0, 16384, 
+    20480, 22528, 23552, 23296, 23424, 23392, 23400, 23402, 
+        0, 16384, 20480, 22528, 23552, 23296, 23424, 23392, 
+    23400,     0, 16384, 20480, 22528, 23552, 23296, 23424, 
+    23392, 23408, 23404,     0, 16384, 20480, 22528, 23552, 
+    23296, 23424, 23392, 23408, 23404,     0, 16384, 20480, 
+    22528, 23552, 23296, 23424, 23392, 23408, 23409, 23406, 
+        0, 16384, 20480, 22528, 23552, 23296, 23424, 23392, 
+        0, 16384, 20480, 22528, 23552, 23296, 23424, 23425, 
+    23408,     0, 16384, 20480, 22528, 23552, 23296, 23424, 
+    23425, 23408,     0, 16384, 20480, 22528, 23552, 23296, 
+    23424, 23425, 23408, 23410,     0, 16384, 20480, 22528, 
+    23552, 23296, 23424, 23425, 23408,     0, 16384, 20480, 
+    22528, 23552, 23296, 23424, 23425, 23408, 23412,     0, 
+    16384, 20480, 22528, 23552, 23296, 23424, 23425, 23408, 
+    23412,     0, 16384, 20480, 22528, 23552, 23296, 23424, 
+    23425, 23408, 23416, 23414,     0, 16384, 20480, 22528, 
+    23552, 23296, 23424, 23425, 23408,     0, 16384, 20480, 
+    22528, 23552, 23296, 23424, 23425, 23408, 23416,     0, 
+    16384, 20480, 22528, 23552, 23296, 23424, 23425, 23427, 
+    23416,     0, 16384, 20480, 22528, 23552, 23296, 23424, 
+    23425, 23427, 23416, 23418,     0, 16384, 20480, 22528, 
+    23552, 23296, 23424, 23425, 23427, 23416,     0, 16384, 
+    20480, 22528, 23552, 23296, 23424, 23425, 23427, 23416, 
+    23420,     0, 16384, 20480, 22528, 23552, 23296, 23424, 
+    23425, 23427, 23416, 23420,     0, 16384, 20480, 22528, 
+    23552, 23296, 23424, 23425, 23427, 23416, 23420, 23422, 
+        0, 16384, 20480, 22528, 23552, 23296,     0, 16384, 
+    20480, 22528, 23552, 23296, 23424,     0, 16384, 20480, 
+    22528, 23552, 23553, 23424,     0, 16384, 20480, 22528, 
+    23552, 23553, 23424, 23426,     0, 16384, 20480, 22528, 
+    23552, 23553, 23424,     0, 16384, 20480, 22528, 23552, 
+    23553, 23424, 23428,     0, 16384, 20480, 22528, 23552, 
+    23553, 23424, 23428,     0, 16384, 20480, 22528, 23552, 
+    23553, 23424, 23432, 23430,     0, 16384, 20480, 22528, 
+    23552, 23553, 23424,     0, 16384, 20480, 22528, 23552, 
+    23553, 23424, 23432,     0, 16384, 20480, 22528, 23552, 
+    23553, 23424, 23432,     0, 16384, 20480, 22528, 23552, 
+    23553, 23424, 23432, 23434,     0, 16384, 20480, 22528, 
+    23552, 23553, 23424, 23432,     0, 16384, 20480, 22528, 
+    23552, 23553, 23424, 23440, 23436,     0, 16384, 20480, 
+    22528, 23552, 23553, 23424, 23440, 23436,     0, 16384, 
+    20480, 22528, 23552, 23553, 23424, 23440, 23441, 23438, 
+        0, 16384, 20480, 22528, 23552, 23553, 23424,     0, 
+    16384, 20480, 22528, 23552, 23553, 23424, 23440,     0, 
+    16384, 20480, 22528, 23552, 23553, 23424, 23440,     0, 
+    16384, 20480, 22528, 23552, 23553, 23424, 23440, 23442, 
+        0, 16384, 20480, 22528, 23552, 23553, 23424, 23440, 
+        0, 16384, 20480, 22528, 23552, 23553, 23424, 23440, 
+    23444,     0, 16384, 20480, 22528, 23552, 23553, 23424, 
+    23440, 23444,     0, 16384, 20480, 22528, 23552, 23553, 
+    23424, 23440, 23448, 23446,     0, 16384, 20480, 22528, 
+    23552, 23553, 23424, 23440,     0, 16384, 20480, 22528, 
+    23552, 23553, 23424, 23456, 23448,     0, 16384, 20480, 
+    22528, 23552, 23553, 23424, 23456, 23448,     0, 16384, 
+    20480, 22528, 23552, 23553, 23424, 23456, 23448, 23450, 
+        0, 16384, 20480, 22528, 23552, 23553, 23424, 23456, 
+    23448,     0, 16384, 20480, 22528, 23552, 23553, 23424, 
+    23456, 23457, 23452,     0, 16384, 20480, 22528, 23552, 
+    23553, 23424, 23456, 23457, 23452,     0, 16384, 20480, 
+    22528, 23552, 23553, 23424, 23456, 23457, 23452, 23454, 
+        0, 16384, 20480, 22528, 23552, 23553, 23424,     0, 
+    16384, 20480, 22528, 23552, 23553, 23424, 23456,     0, 
+    16384, 20480, 22528, 23552, 23553, 23424, 23456,     0, 
+    16384, 20480, 22528, 23552, 23553, 23424, 23456, 23458, 
+        0, 16384, 20480, 22528, 23552, 23553, 23424, 23456, 
+        0, 16384, 20480, 22528, 23552, 23553, 23424, 23456, 
+    23460,     0, 16384, 20480, 22528, 23552, 23553, 23424, 
+    23456, 23460,     0, 16384, 20480, 22528, 23552, 23553, 
+    23424, 23456, 23464, 23462,     0, 16384, 20480, 22528, 
+    23552, 23553, 23424, 23456,     0, 16384, 20480, 22528, 
+    23552, 23553, 23424, 23456, 23464,     0, 16384, 20480, 
+    22528, 23552, 23553, 23424, 23456, 23464,     0, 16384, 
+    20480, 22528, 23552, 23553, 23424, 23456, 23464, 23466, 
+        0, 16384, 20480, 22528, 23552, 23553, 23424, 23456, 
+    23464,     0, 16384, 20480, 22528, 23552, 23553, 23424, 
+    23456, 23472, 23468,     0, 16384, 20480, 22528, 23552, 
+    23553, 23424, 23456, 23472, 23468,     0, 16384, 20480, 
+    22528, 23552, 23553, 23424, 23456, 23472, 23473, 23470, 
+        0, 16384, 20480, 22528, 23552, 23553, 23424, 23456, 
+        0, 16384, 20480, 22528, 23552, 23553, 23424, 23488, 
+    23472,     0, 16384, 20480, 22528, 23552, 23553, 23424, 
+    23488, 23472,     0, 16384, 20480, 22528, 23552, 23553, 
+    23424, 23488, 23472, 23474,     0, 16384, 20480, 22528, 
+    23552, 23553, 23424, 23488, 23472,     0, 16384, 20480, 
+    22528, 23552, 23553, 23424, 23488, 23472, 23476,     0, 
+    16384, 20480, 22528, 23552, 23553, 23424, 23488, 23472, 
+    23476,     0, 16384, 20480, 22528, 23552, 23553, 23424, 
+    23488, 23472, 23480, 23478,     0, 16384, 20480, 22528, 
+    23552, 23553, 23424, 23488, 23472,     0, 16384, 20480, 
+    22528, 23552, 23553, 23424, 23488, 23489, 23480,     0, 
+    16384, 20480, 22528, 23552, 23553, 23424, 23488, 23489, 
+    23480,     0, 16384, 20480, 22528, 23552, 23553, 23424, 
+    23488, 23489, 23480, 23482,     0, 16384, 20480, 22528, 
+    23552, 23553, 23424, 23488, 23489, 23480,     0, 16384, 
+    20480, 22528, 23552, 23553, 23424, 23488, 23489, 23480, 
+    23484,     0, 16384, 20480, 22528, 23552, 23553, 23424, 
+    23488, 23489, 23491, 23484,     0, 16384, 20480, 22528, 
+    23552, 23553, 23424, 23488, 23489, 23491, 23484, 23486, 
+        0, 16384, 20480, 22528, 23552, 23553, 23424,     0, 
+    16384, 20480, 22528, 23552, 23553, 23424, 23488,     0, 
+    16384, 20480, 22528, 23552, 23553, 23424, 23488,     0, 
+    16384, 20480, 22528, 23552, 23553, 23424, 23488, 23490, 
+        0, 16384, 20480, 22528, 23552, 23553, 23555, 23488, 
+        0, 16384, 20480, 22528, 23552, 23553, 23555, 23488, 
+    23492,     0, 16384, 20480, 22528, 23552, 23553, 23555, 
+    23488, 23492,     0, 16384, 20480, 22528, 23552, 23553, 
+    23555, 23488, 23496, 23494,     0, 16384, 20480, 22528, 
+    23552, 23553, 23555, 23488,     0, 16384, 20480, 22528, 
+    23552, 23553, 23555, 23488, 23496,     0, 16384, 20480, 
+    22528, 23552, 23553, 23555, 23488, 23496,     0, 16384, 
+    20480, 22528, 23552, 23553, 23555, 23488, 23496, 23498, 
+        0, 16384, 20480, 22528, 23552, 23553, 23555, 23488, 
+    23496,     0, 16384, 20480, 22528, 23552, 23553, 23555, 
+    23488, 23504, 23500,     0, 16384, 20480, 22528, 23552, 
+    23553, 23555, 23488, 23504, 23500,     0, 16384, 20480, 
+    22528, 23552, 23553, 23555, 23488, 23504, 23505, 23502, 
+        0, 16384, 20480, 22528, 23552, 23553, 23555, 23488, 
+        0, 16384, 20480, 22528, 23552, 23553, 23555, 23488, 
+    23504,     0, 16384, 20480, 22528, 23552, 23553, 23555, 
+    23488, 23504,     0, 16384, 20480, 22528, 23552, 23553, 
+    23555, 23488, 23504, 23506,     0, 16384, 20480, 22528, 
+    23552, 23553, 23555, 23488, 23504,     0, 16384, 20480, 
+    22528, 23552, 23553, 23555, 23488, 23504, 23508,     0, 
+    16384, 20480, 22528, 23552, 23553, 23555, 23488, 23504, 
+    23508,     0, 16384, 20480, 22528, 23552, 23553, 23555, 
+    23488, 23504, 23512, 23510,     0, 16384, 20480, 22528, 
+    23552, 23553, 23555, 23488, 23504,     0, 16384, 20480, 
+    22528, 23552, 23553, 23555, 23488, 23520, 23512,     0, 
+    16384, 20480, 22528, 23552, 23553, 23555, 23488, 23520, 
+    23512,     0, 16384, 20480, 22528, 23552, 23553, 23555, 
+    23488, 23520, 23512, 23514,     0, 16384, 20480, 22528, 
+    23552, 23553, 23555, 23488, 23520, 23512,     0, 16384, 
+    20480, 22528, 23552, 23553, 23555, 23488, 23520, 23521, 
+    23516,     0, 16384, 20480, 22528, 23552, 23553, 23555, 
+    23488, 23520, 23521, 23516,     0, 16384, 20480, 22528, 
+    23552, 23553, 23555, 23488, 23520, 23521, 23516, 23518, 
+        0, 16384, 20480, 22528, 23552, 23553, 23555, 23488, 
+        0, 16384, 20480, 22528, 23552, 23553, 23555, 23488, 
+    23520,     0, 16384, 20480, 22528, 23552, 23553, 23555, 
+    23488, 23520,     0, 16384, 20480, 22528, 23552, 23553, 
+    23555, 23488, 23520, 23522,     0, 16384, 20480, 22528, 
+    23552, 23553, 23555, 23488, 23520,     0, 16384, 20480, 
+    22528, 23552, 23553, 23555, 23488, 23520, 23524,     0, 
+    16384, 20480, 22528, 23552, 23553, 23555, 23488, 23520, 
+    23524,     0, 16384, 20480, 22528, 23552, 23553, 23555, 
+    23488, 23520, 23528, 23526,     0, 16384, 20480, 22528, 
+    23552, 23553, 23555, 23559, 23520,     0, 16384, 20480, 
+    22528, 23552, 23553, 23555, 23559, 23520, 23528,     0, 
+    16384, 20480, 22528, 23552, 23553, 23555, 23559, 23520, 
+    23528,     0, 16384, 20480, 22528, 23552, 23553, 23555, 
+    23559, 23520, 23528, 23530,     0, 16384, 20480, 22528, 
+    23552, 23553, 23555, 23559, 23520, 23528,     0, 16384, 
+    20480, 22528, 23552, 23553, 23555, 23559, 23520, 23536, 
+    23532,     0, 16384, 20480, 22528, 23552, 23553, 23555, 
+    23559, 23520, 23536, 23532,     0, 16384, 20480, 22528, 
+    23552, 23553, 23555, 23559, 23520, 23536, 23537, 23534, 
+        0, 16384, 20480, 22528, 23552, 23553, 23555, 23559, 
+    23520,     0, 16384, 20480, 22528, 23552, 23553, 23555, 
+    23559, 23520, 23536,     0, 16384, 20480, 22528, 23552, 
+    23553, 23555, 23559, 23520, 23536,     0, 16384, 20480, 
+    22528, 23552, 23553, 23555, 23559, 23520, 23536, 23538, 
+        0, 16384, 20480, 22528, 23552, 23553, 23555, 23559, 
+    23520, 23536,     0, 16384, 20480, 22528, 23552, 23553, 
+    23555, 23559, 23520, 23536, 23540,     0, 16384, 20480, 
+    22528, 23552, 23553, 23555, 23559, 23520, 23536, 23540, 
+        0, 16384, 20480, 22528, 23552, 23553, 23555, 23559, 
+    23520, 23536, 23544, 23542,     0, 16384, 20480, 22528, 
+    23552, 23553, 23555, 23559, 23520, 23536,     0, 16384, 
+    20480, 22528, 23552, 23553, 23555, 23559, 23520, 23536, 
+    23544,     0, 16384, 20480, 22528, 23552, 23553, 23555, 
+    23559, 23520, 23536, 23544,     0, 16384, 20480, 22528, 
+    23552, 23553, 23555, 23559, 23520, 23536, 23544, 23546, 
+        0, 16384, 20480, 22528, 23552, 23553, 23555, 23559, 
+    23520, 23536, 23544,     0, 16384, 20480, 22528, 23552, 
+    23553, 23555, 23559, 23520, 23536, 23544, 23548,     0, 
+    16384, 20480, 22528, 23552, 23553, 23555, 23559, 23520, 
+    23536, 23544, 23548,     0, 16384, 20480, 22528, 23552, 
+    23553, 23555, 23559, 23520, 23536, 23544, 23548, 23550, 
+        0, 16384, 20480, 22528,     0, 16384, 20480, 22528, 
+    23552,     0, 16384, 20480, 22528, 23552,     0, 16384, 
+    20480, 22528, 23552, 23554,     0, 16384, 20480, 22528, 
+    23552,     0, 16384, 20480, 22528, 23552, 23556,     0, 
+    16384, 20480, 22528, 23552, 23556,     0, 16384, 20480, 
+    22528, 23552, 23560, 23558,     0, 16384, 20480, 22528, 
+    23552,     0, 16384, 20480, 22528, 23552, 23560,     0, 
+    16384, 20480, 22528, 23552, 23560,     0, 16384, 20480, 
+    22528, 23552, 23560, 23562,     0, 16384, 20480, 22528, 
+    23552, 23560,     0, 16384, 20480, 22528, 23552, 23568, 
+    23564,     0, 16384, 20480, 22528, 23552, 23568, 23564, 
+        0, 16384, 20480, 22528, 23552, 23568, 23569, 23566, 
+        0, 16384, 20480, 22528, 23552,     0, 16384, 20480, 
+    22528, 23552, 23568,     0, 16384, 20480, 22528, 23552, 
+    23568,     0, 16384, 20480, 22528, 23552, 23568, 23570, 
+        0, 16384, 20480, 22528, 23552, 23568,     0, 16384, 
+    20480, 22528, 23552, 23568, 23572,     0, 16384, 20480, 
+    22528, 23552, 23568, 23572,     0, 16384, 20480, 22528, 
+    23552, 23568, 23576, 23574,     0, 16384, 20480, 22528, 
+    23552, 23568,     0, 16384, 20480, 22528, 23552, 23584, 
+    23576,     0, 16384, 20480, 22528, 23552, 23584, 23576, 
+        0, 16384, 20480, 22528, 23552, 23584, 23576, 23578, 
+        0, 16384, 20480, 22528, 23552, 23584, 23576,     0, 
+    16384, 20480, 22528, 23552, 23584, 23585, 23580,     0, 
+    16384, 20480, 22528, 23552, 23584, 23585, 23580,     0, 
+    16384, 20480, 22528, 23552, 23584, 23585, 23580, 23582, 
+        0, 16384, 20480, 22528, 23552,     0, 16384, 20480, 
+    22528, 23552, 23584,     0, 16384, 20480, 22528, 23552, 
+    23584,     0, 16384, 20480, 22528, 23552, 23584, 23586, 
+        0, 16384, 20480, 22528, 23552, 23584,     0, 16384, 
+    20480, 22528, 23552, 23584, 23588,     0, 16384, 20480, 
+    22528, 23552, 23584, 23588,     0, 16384, 20480, 22528, 
+    23552, 23584, 23592, 23590,     0, 16384, 20480, 22528, 
+    23552, 23584,     0, 16384, 20480, 22528, 23552, 23584, 
+    23592,     0, 16384, 20480, 22528, 23552, 23584, 23592, 
+        0, 16384, 20480, 22528, 23552, 23584, 23592, 23594, 
+        0, 16384, 20480, 22528, 23552, 23584, 23592,     0, 
+    16384, 20480, 22528, 23552, 23584, 23600, 23596,     0, 
+    16384, 20480, 22528, 23552, 23584, 23600, 23596,     0, 
+    16384, 20480, 22528, 23552, 23584, 23600, 23601, 23598, 
+        0, 16384, 20480, 22528, 23552, 23584,     0, 16384, 
+    20480, 22528, 23552, 23616, 23600,     0, 16384, 20480, 
+    22528, 23552, 23616, 23600,     0, 16384, 20480, 22528, 
+    23552, 23616, 23600, 23602,     0, 16384, 20480, 22528, 
+    23552, 23616, 23600,     0, 16384, 20480, 22528, 23552, 
+    23616, 23600, 23604,     0, 16384, 20480, 22528, 23552, 
+    23616, 23600, 23604,     0, 16384, 20480, 22528, 23552, 
+    23616, 23600, 23608, 23606,     0, 16384, 20480, 22528, 
+    23552, 23616, 23600,     0, 16384, 20480, 22528, 23552, 
+    23616, 23617, 23608,     0, 16384, 20480, 22528, 23552, 
+    23616, 23617, 23608,     0, 16384, 20480, 22528, 23552, 
+    23616, 23617, 23608, 23610,     0, 16384, 20480, 22528, 
+    23552, 23616, 23617, 23608,     0, 16384, 20480, 22528, 
+    23552, 23616, 23617, 23608, 23612,     0, 16384, 20480, 
+    22528, 23552, 23616, 23617, 23619, 23612,     0, 16384, 
+    20480, 22528, 23552, 23616, 23617, 23619, 23612, 23614, 
+        0, 16384, 20480, 22528, 23552,     0, 16384, 24576, 
+    22528, 23552, 23616,     0, 16384, 24576, 22528, 23552, 
+    23616,     0, 16384, 24576, 22528, 23552, 23616, 23618, 
+        0, 16384, 24576, 22528, 23552, 23616,     0, 16384, 
+    24576, 22528, 23552, 23616, 23620,     0, 16384, 24576, 
+    22528, 23552, 23616, 23620,     0, 16384, 24576, 22528, 
+    23552, 23616, 23624, 23622,     0, 16384, 24576, 22528, 
+    23552, 23616,     0, 16384, 24576, 22528, 23552, 23616, 
+    23624,     0, 16384, 24576, 22528, 23552, 23616, 23624, 
+        0, 16384, 24576, 22528, 23552, 23616, 23624, 23626, 
+        0, 16384, 24576, 22528, 23552, 23616, 23624,     0, 
+    16384, 24576, 22528, 23552, 23616, 23632, 23628,     0, 
+    16384, 24576, 22528, 23552, 23616, 23632, 23628,     0, 
+    16384, 24576, 22528, 23552, 23616, 23632, 23633, 23630, 
+        0, 16384, 24576, 22528, 23552, 23616,     0, 16384, 
+    24576, 22528, 23552, 23616, 23632,     0, 16384, 24576, 
+    22528, 23552, 23616, 23632,     0, 16384, 24576, 22528, 
+    23552, 23616, 23632, 23634,     0, 16384, 24576, 22528, 
+    23552, 23616, 23632,     0, 16384, 24576, 22528, 23552, 
+    23616, 23632, 23636,     0, 16384, 24576, 22528, 23552, 
+    23616, 23632, 23636,     0, 16384, 24576, 22528, 23552, 
+    23616, 23632, 23640, 23638,     0, 16384, 24576, 22528, 
+    23552, 23616, 23632,     0, 16384, 24576, 22528, 23552, 
+    23616, 23648, 23640,     0, 16384, 24576, 22528, 23552, 
+    23616, 23648, 23640,     0, 16384, 24576, 22528, 23552, 
+    23616, 23648, 23640, 23642,     0, 16384, 24576, 22528, 
+    23552, 23616, 23648, 23640,     0, 16384, 24576, 22528, 
+    23552, 23616, 23648, 23649, 23644,     0, 16384, 24576, 
+    22528, 23552, 23616, 23648, 23649, 23644,     0, 16384, 
+    24576, 22528, 23552, 23616, 23648, 23649, 23644, 23646, 
+        0, 16384, 24576, 22528, 23552, 23616,     0, 16384, 
+    24576, 22528, 23552, 23680, 23648,     0, 16384, 24576, 
+    22528, 23552, 23680, 23648,     0, 16384, 24576, 22528, 
+    23552, 23680, 23648, 23650,     0, 16384, 24576, 22528, 
+    23552, 23680, 23648,     0, 16384, 24576, 22528, 23552, 
+    23680, 23648, 23652,     0, 16384, 24576, 22528, 23552, 
+    23680, 23648, 23652,     0, 16384, 24576, 22528, 23552, 
+    23680, 23648, 23656, 23654,     0, 16384, 24576, 22528, 
+    23552, 23680, 23648,     0, 16384, 24576, 22528, 23552, 
+    23680, 23648, 23656,     0, 16384, 24576, 22528, 23552, 
+    23680, 23648, 23656,     0, 16384, 24576, 22528, 23552, 
+    23680, 23648, 23656, 23658,     0, 16384, 24576, 22528, 
+    23552, 23680, 23648, 23656,     0, 16384, 24576, 22528, 
+    23552, 23680, 23648, 23664, 23660,     0, 16384, 24576, 
+    22528, 23552, 23680, 23648, 23664, 23660,     0, 16384, 
+    24576, 22528, 23552, 23680, 23648, 23664, 23665, 23662, 
+        0, 16384, 24576, 22528, 23552, 23680, 23648,     0, 
+    16384, 24576, 22528, 23552, 23680, 23681, 23664,     0, 
+    16384, 24576, 22528, 23552, 23680, 23681, 23664,     0, 
+    16384, 24576, 22528, 23552, 23680, 23681, 23664, 23666, 
+        0, 16384, 24576, 22528, 23552, 23680, 23681, 23664, 
+        0, 16384, 24576, 22528, 23552, 23680, 23681, 23664, 
+    23668,     0, 16384, 24576, 22528, 23552, 23680, 23681, 
+    23664, 23668,     0, 16384, 24576, 22528, 23552, 23680, 
+    23681, 23664, 23672, 23670,     0, 16384, 24576, 22528, 
+    23552, 23680, 23681, 23664,     0, 16384, 24576, 22528, 
+    23552, 23680, 23681, 23664, 23672,     0, 16384, 24576, 
+    22528, 23552, 23680, 23681, 23683, 23672,     0, 16384, 
+    24576, 22528, 23552, 23680, 23681, 23683, 23672, 23674, 
+        0, 16384, 24576, 22528, 23552, 23680, 23681, 23683, 
+    23672,     0, 16384, 24576, 22528, 23552, 23680, 23681, 
+    23683, 23672, 23676,     0, 16384, 24576, 22528, 23552, 
+    23680, 23681, 23683, 23672, 23676,     0, 16384, 24576, 
+    22528, 23552, 23680, 23681, 23683, 23672, 23676, 23678, 
+        0, 16384, 24576, 22528, 23552,     0, 16384, 24576, 
+    22528, 23552, 23680,     0, 16384, 24576, 22528, 23552, 
+    23680,     0, 16384, 24576, 22528, 23552, 23680, 23682, 
+        0, 16384, 24576, 22528, 23552, 23680,     0, 16384, 
+    24576, 22528, 23552, 23680, 23684,     0, 16384, 24576, 
+    22528, 23552, 23680, 23684,     0, 16384, 24576, 22528, 
+    23552, 23680, 23688, 23686,     0, 16384, 24576, 22528, 
+    23552, 23680,     0, 16384, 24576, 22528, 23552, 23680, 
+    23688,     0, 16384, 24576, 22528, 23552, 23680, 23688, 
+        0, 16384, 24576, 22528, 23552, 23680, 23688, 23690, 
+        0, 16384, 24576, 22528, 23552, 23680, 23688,     0, 
+    16384, 24576, 22528, 23552, 23680, 23696, 23692,     0, 
+    16384, 24576, 22528, 23552, 23680, 23696, 23692,     0, 
+    16384, 24576, 22528, 23552, 23680, 23696, 23697, 23694, 
+        0, 16384, 24576, 22528, 23552, 23680,     0, 16384, 
+    24576, 22528, 23552, 23680, 23696,     0, 16384, 24576, 
+    22528, 23552, 23680, 23696,     0, 16384, 24576, 22528, 
+    23552, 23680, 23696, 23698,     0, 16384, 24576, 22528, 
+    23552, 23680, 23696,     0, 16384, 24576, 22528, 23552, 
+    23680, 23696, 23700,     0, 16384, 24576, 22528, 23552, 
+    23680, 23696, 23700,     0, 16384, 24576, 22528, 23552, 
+    23680, 23696, 23704, 23702,     0, 16384, 24576, 22528, 
+    23552, 23680, 23696,     0, 16384, 24576, 22528, 23552, 
+    23680, 23712, 23704,     0, 16384, 24576, 22528, 23552, 
+    23680, 23712, 23704,     0, 16384, 24576, 22528, 23552, 
+    23680, 23712, 23704, 23706,     0, 16384, 24576, 22528, 
+    23552, 23680, 23712, 23704,     0, 16384, 24576, 22528, 
+    23552, 23680, 23712, 23713, 23708,     0, 16384, 24576, 
+    22528, 23552, 23680, 23712, 23713, 23708,     0, 16384, 
+    24576, 22528, 23552, 23680, 23712, 23713, 23708, 23710, 
+        0, 16384, 24576, 22528, 23552, 23680,     0, 16384, 
+    24576, 22528, 23552, 23680, 23712,     0, 16384, 24576, 
+    22528, 23552, 23680, 23712,     0, 16384, 24576, 22528, 
+    23552, 23680, 23712, 23714,     0, 16384, 24576, 22528, 
+    23552, 23680, 23712,     0, 16384, 24576, 22528, 23552, 
+    23680, 23712, 23716,     0, 16384, 24576, 22528, 23552, 
+    23680, 23712, 23716,     0, 16384, 24576, 22528, 23552, 
+    23680, 23712, 23720, 23718,     0, 16384, 24576, 22528, 
+    23552, 23680, 23712,     0, 16384, 24576, 22528, 23552, 
+    23680, 23712, 23720,     0, 16384, 24576, 22528, 23552, 
+    23680, 23712, 23720,     0, 16384, 24576, 22528, 23552, 
+    23680, 23712, 23720, 23722,     0, 16384, 24576, 22528, 
+    23552, 23680, 23712, 23720,     0, 16384, 24576, 22528, 
+    23552, 23680, 23712, 23728, 23724,     0, 16384, 24576, 
+    22528, 23552, 23680, 23712, 23728, 23724,     0, 16384, 
+    24576, 22528, 23552, 23680, 23712, 23728, 23729, 23726, 
+        0, 16384, 24576, 22528, 23552, 23680, 23712,     0, 
+    16384, 24576, 22528, 23552, 23680, 23744, 23728,     0, 
+    16384, 24576, 22528, 23552, 23680, 23744, 23728,     0, 
+    16384, 24576, 22528, 23552, 23680, 23744, 23728, 23730, 
+        0, 16384, 24576, 22528, 23552, 23680, 23744, 23728, 
+        0, 16384, 24576, 22528, 23552, 23680, 23744, 23728, 
+    23732,     0, 16384, 24576, 22528, 23552, 23680, 23744, 
+    23728, 23732,     0, 16384, 24576, 22528, 23552, 23680, 
+    23744, 23728, 23736, 23734,     0, 16384, 24576, 22528, 
+    23552, 23680, 23744, 23728,     0, 16384, 24576, 22528, 
+    23552, 23680, 23744, 23745, 23736,     0, 16384, 24576, 
+    22528, 23552, 23680, 23744, 23745, 23736,     0, 16384, 
+    24576, 22528, 23552, 23680, 23744, 23745, 23736, 23738, 
+        0, 16384, 24576, 22528, 23552, 23680, 23744, 23745, 
+    23736,     0, 16384, 24576, 22528, 23552, 23680, 23744, 
+    23745, 23736, 23740,     0, 16384, 24576, 22528, 23552, 
+    23680, 23744, 23745, 23747, 23740,     0, 16384, 24576, 
+    22528, 23552, 23680, 23744, 23745, 23747, 23740, 23742, 
+        0, 16384, 24576, 22528, 23552, 23680,     0, 16384, 
+    24576, 22528, 23552, 23808, 23744,     0, 16384, 24576, 
+    22528, 23552, 23808, 23744,     0, 16384, 24576, 22528, 
+    23552, 23808, 23744, 23746,     0, 16384, 24576, 22528, 
+    23552, 23808, 23744,     0, 16384, 24576, 22528, 23552, 
+    23808, 23744, 23748,     0, 16384, 24576, 22528, 23552, 
+    23808, 23744, 23748,     0, 16384, 24576, 22528, 23552, 
+    23808, 23744, 23752, 23750,     0, 16384, 24576, 22528, 
+    23552, 23808, 23744,     0, 16384, 24576, 22528, 23552, 
+    23808, 23744, 23752,     0, 16384, 24576, 22528, 23552, 
+    23808, 23744, 23752,     0, 16384, 24576, 22528, 23552, 
+    23808, 23744, 23752, 23754,     0, 16384, 24576, 22528, 
+    23552, 23808, 23744, 23752,     0, 16384, 24576, 22528, 
+    23552, 23808, 23744, 23760, 23756,     0, 16384, 24576, 
+    22528, 23552, 23808, 23744, 23760, 23756,     0, 16384, 
+    24576, 22528, 23552, 23808, 23744, 23760, 23761, 23758, 
+        0, 16384, 24576, 22528, 23552, 23808, 23744,     0, 
+    16384, 24576, 22528, 23552, 23808, 23744, 23760,     0, 
+    16384, 24576, 22528, 23552, 23808, 23744, 23760,     0, 
+    16384, 24576, 22528, 23552, 23808, 23744, 23760, 23762, 
+        0, 16384, 24576, 22528, 23552, 23808, 23744, 23760, 
+        0, 16384, 24576, 22528, 23552, 23808, 23744, 23760, 
+    23764,     0, 16384, 24576, 22528, 23552, 23808, 23744, 
+    23760, 23764,     0, 16384, 24576, 22528, 23552, 23808, 
+    23744, 23760, 23768, 23766,     0, 16384, 24576, 22528, 
+    23552, 23808, 23744, 23760,     0, 16384, 24576, 22528, 
+    23552, 23808, 23744, 23776, 23768,     0, 16384, 24576, 
+    22528, 23552, 23808, 23744, 23776, 23768,     0, 16384, 
+    24576, 22528, 23552, 23808, 23744, 23776, 23768, 23770, 
+        0, 16384, 24576, 22528, 23552, 23808, 23744, 23776, 
+    23768,     0, 16384, 24576, 22528, 23552, 23808, 23744, 
+    23776, 23777, 23772,     0, 16384, 24576, 22528, 23552, 
+    23808, 23744, 23776, 23777, 23772,     0, 16384, 24576, 
+    22528, 23552, 23808, 23744, 23776, 23777, 23772, 23774, 
+        0, 16384, 24576, 22528, 23552, 23808, 23744,     0, 
+    16384, 24576, 22528, 23552, 23808, 23809, 23776,     0, 
+    16384, 24576, 22528, 23552, 23808, 23809, 23776,     0, 
+    16384, 24576, 22528, 23552, 23808, 23809, 23776, 23778, 
+        0, 16384, 24576, 22528, 23552, 23808, 23809, 23776, 
+        0, 16384, 24576, 22528, 23552, 23808, 23809, 23776, 
+    23780,     0, 16384, 24576, 22528, 23552, 23808, 23809, 
+    23776, 23780,     0, 16384, 24576, 22528, 23552, 23808, 
+    23809, 23776, 23784, 23782,     0, 16384, 24576, 22528, 
+    23552, 23808, 23809, 23776,     0, 16384, 24576, 22528, 
+    23552, 23808, 23809, 23776, 23784,     0, 16384, 24576, 
+    22528, 23552, 23808, 23809, 23776, 23784,     0, 16384, 
+    24576, 22528, 23552, 23808, 23809, 23776, 23784, 23786, 
+        0, 16384, 24576, 22528, 23552, 23808, 23809, 23776, 
+    23784,     0, 16384, 24576, 22528, 23552, 23808, 23809, 
+    23776, 23792, 23788,     0, 16384, 24576, 22528, 23552, 
+    23808, 23809, 23776, 23792, 23788,     0, 16384, 24576, 
+    22528, 23552, 23808, 23809, 23776, 23792, 23793, 23790, 
+        0, 16384, 24576, 22528, 23552, 23808, 23809, 23776, 
+        0, 16384, 24576, 22528, 23552, 23808, 23809, 23776, 
+    23792,     0, 16384, 24576, 22528, 23552, 23808, 23809, 
+    23811, 23792,     0, 16384, 24576, 22528, 23552, 23808, 
+    23809, 23811, 23792, 23794,     0, 16384, 24576, 22528, 
+    23552, 23808, 23809, 23811, 23792,     0, 16384, 24576, 
+    22528, 23552, 23808, 23809, 23811, 23792, 23796,     0, 
+    16384, 24576, 22528, 23552, 23808, 23809, 23811, 23792, 
+    23796,     0, 16384, 24576, 22528, 23552, 23808, 23809, 
+    23811, 23792, 23800, 23798,     0, 16384, 24576, 22528, 
+    23552, 23808, 23809, 23811, 23792,     0, 16384, 24576, 
+    22528, 23552, 23808, 23809, 23811, 23792, 23800,     0, 
+    16384, 24576, 22528, 23552, 23808, 23809, 23811, 23792, 
+    23800,     0, 16384, 24576, 22528, 23552, 23808, 23809, 
+    23811, 23792, 23800, 23802,     0, 16384, 24576, 22528, 
+    23552, 23808, 23809, 23811, 23815, 23800,     0, 16384, 
+    24576, 22528, 23552, 23808, 23809, 23811, 23815, 23800, 
+    23804,     0, 16384, 24576, 22528, 23552, 23808, 23809, 
+    23811, 23815, 23800, 23804,     0, 16384, 24576, 22528, 
+    23552, 23808, 23809, 23811, 23815, 23800, 23804, 23806, 
+        0, 16384, 24576, 22528, 23552,     0, 16384, 24576, 
+    22528, 23552, 23808,     0, 16384, 24576, 24577, 23552, 
+    23808,     0, 16384, 24576, 24577, 23552, 23808, 23810, 
+        0, 16384, 24576, 24577, 23552, 23808,     0, 16384, 
+    24576, 24577, 23552, 23808, 23812,     0, 16384, 24576, 
+    24577, 23552, 23808, 23812,     0, 16384, 24576, 24577, 
+    23552, 23808, 23816, 23814,     0, 16384, 24576, 24577, 
+    23552, 23808,     0, 16384, 24576, 24577, 23552, 23808, 
+    23816,     0, 16384, 24576, 24577, 23552, 23808, 23816, 
+        0, 16384, 24576, 24577, 23552, 23808, 23816, 23818, 
+        0, 16384, 24576, 24577, 23552, 23808, 23816,     0, 
+    16384, 24576, 24577, 23552, 23808, 23824, 23820,     0, 
+    16384, 24576, 24577, 23552, 23808, 23824, 23820,     0, 
+    16384, 24576, 24577, 23552, 23808, 23824, 23825, 23822, 
+        0, 16384, 24576, 24577, 23552, 23808,     0, 16384, 
+    24576, 24577, 23552, 23808, 23824,     0, 16384, 24576, 
+    24577, 23552, 23808, 23824,     0, 16384, 24576, 24577, 
+    23552, 23808, 23824, 23826,     0, 16384, 24576, 24577, 
+    23552, 23808, 23824,     0, 16384, 24576, 24577, 23552, 
+    23808, 23824, 23828,     0, 16384, 24576, 24577, 23552, 
+    23808, 23824, 23828,     0, 16384, 24576, 24577, 23552, 
+    23808, 23824, 23832, 23830,     0, 16384, 24576, 24577, 
+    23552, 23808, 23824,     0, 16384, 24576, 24577, 23552, 
+    23808, 23840, 23832,     0, 16384, 24576, 24577, 23552, 
+    23808, 23840, 23832,     0, 16384, 24576, 24577, 23552, 
+    23808, 23840, 23832, 23834,     0, 16384, 24576, 24577, 
+    23552, 23808, 23840, 23832,     0, 16384, 24576, 24577, 
+    23552, 23808, 23840, 23841, 23836,     0, 16384, 24576, 
+    24577, 23552, 23808, 23840, 23841, 23836,     0, 16384, 
+    24576, 24577, 23552, 23808, 23840, 23841, 23836, 23838, 
+        0, 16384, 24576, 24577, 23552, 23808,     0, 16384, 
+    24576, 24577, 23552, 23808, 23840,     0, 16384, 24576, 
+    24577, 23552, 23808, 23840,     0, 16384, 24576, 24577, 
+    23552, 23808, 23840, 23842,     0, 16384, 24576, 24577, 
+    23552, 23808, 23840,     0, 16384, 24576, 24577, 23552, 
+    23808, 23840, 23844,     0, 16384, 24576, 24577, 23552, 
+    23808, 23840, 23844,     0, 16384, 24576, 24577, 23552, 
+    23808, 23840, 23848, 23846,     0, 16384, 24576, 24577, 
+    23552, 23808, 23840,     0, 16384, 24576, 24577, 23552, 
+    23808, 23840, 23848,     0, 16384, 24576, 24577, 23552, 
+    23808, 23840, 23848,     0, 16384, 24576, 24577, 23552, 
+    23808, 23840, 23848, 23850,     0, 16384, 24576, 24577, 
+    23552, 23808, 23840, 23848,     0, 16384, 24576, 24577, 
+    23552, 23808, 23840, 23856, 23852,     0, 16384, 24576, 
+    24577, 23552, 23808, 23840, 23856, 23852,     0, 16384, 
+    24576, 24577, 23552, 23808, 23840, 23856, 23857, 23854, 
+        0, 16384, 24576, 24577, 23552, 23808, 23840,     0, 
+    16384, 24576, 24577, 23552, 23808, 23872, 23856,     0, 
+    16384, 24576, 24577, 23552, 23808, 23872, 23856,     0, 
+    16384, 24576, 24577, 23552, 23808, 23872, 23856, 23858, 
+        0, 16384, 24576, 24577, 23552, 23808, 23872, 23856, 
+        0, 16384, 24576, 24577, 23552, 23808, 23872, 23856, 
+    23860,     0, 16384, 24576, 24577, 23552, 23808, 23872, 
+    23856, 23860,     0, 16384, 24576, 24577, 23552, 23808, 
+    23872, 23856, 23864, 23862,     0, 16384, 24576, 24577, 
+    23552, 23808, 23872, 23856,     0, 16384, 24576, 24577, 
+    23552, 23808, 23872, 23873, 23864,     0, 16384, 24576, 
+    24577, 23552, 23808, 23872, 23873, 23864,     0, 16384, 
+    24576, 24577, 23552, 23808, 23872, 23873, 23864, 23866, 
+        0, 16384, 24576, 24577, 23552, 23808, 23872, 23873, 
+    23864,     0, 16384, 24576, 24577, 23552, 23808, 23872, 
+    23873, 23864, 23868,     0, 16384, 24576, 24577, 23552, 
+    23808, 23872, 23873, 23875, 23868,     0, 16384, 24576, 
+    24577, 23552, 23808, 23872, 23873, 23875, 23868, 23870, 
+        0, 16384, 24576, 24577, 23552, 23808,     0, 16384, 
+    24576, 24577, 23552, 23808, 23872,     0, 16384, 24576, 
+    24577, 23552, 23808, 23872,     0, 16384, 24576, 24577, 
+    23552, 23808, 23872, 23874,     0, 16384, 24576, 24577, 
+    23552, 23808, 23872,     0, 16384, 24576, 24577, 23552, 
+    23808, 23872, 23876,     0, 16384, 24576, 24577, 23552, 
+    23808, 23872, 23876,     0, 16384, 24576, 24577, 23552, 
+    23808, 23872, 23880, 23878,     0, 16384, 24576, 24577, 
+    23552, 23808, 23872,     0, 16384, 24576, 24577, 23552, 
+    23808, 23872, 23880,     0, 16384, 24576, 24577, 23552, 
+    23808, 23872, 23880,     0, 16384, 24576, 24577, 23552, 
+    23808, 23872, 23880, 23882,     0, 16384, 24576, 24577, 
+    23552, 23808, 23872, 23880,     0, 16384, 24576, 24577, 
+    23552, 23808, 23872, 23888, 23884,     0, 16384, 24576, 
+    24577, 23552, 23808, 23872, 23888, 23884,     0, 16384, 
+    24576, 24577, 23552, 23808, 23872, 23888, 23889, 23886, 
+        0, 16384, 24576, 24577, 23552, 23808, 23872,     0, 
+    16384, 24576, 24577, 23552, 23808, 23872, 23888,     0, 
+    16384, 24576, 24577, 23552, 23808, 23872, 23888,     0, 
+    16384, 24576, 24577, 23552, 23808, 23872, 23888, 23890, 
+        0, 16384, 24576, 24577, 23552, 23808, 23872, 23888, 
+        0, 16384, 24576, 24577, 23552, 23808, 23872, 23888, 
+    23892,     0, 16384, 24576, 24577, 23552, 23808, 23872, 
+    23888, 23892,     0, 16384, 24576, 24577, 23552, 23808, 
+    23872, 23888, 23896, 23894,     0, 16384, 24576, 24577, 
+    23552, 23808, 23872, 23888,     0, 16384, 24576, 24577, 
+    23552, 23808, 23872, 23904, 23896,     0, 16384, 24576, 
+    24577, 23552, 23808, 23872, 23904, 23896,     0, 16384, 
+    24576, 24577, 23552, 23808, 23872, 23904, 23896, 23898, 
+        0, 16384, 24576, 24577, 23552, 23808, 23872, 23904, 
+    23896,     0, 16384, 24576, 24577, 23552, 23808, 23872, 
+    23904, 23905, 23900,     0, 16384, 24576, 24577, 23552, 
+    23808, 23872, 23904, 23905, 23900,     0, 16384, 24576, 
+    24577, 23552, 23808, 23872, 23904, 23905, 23900, 23902, 
+        0, 16384, 24576, 24577, 23552, 23808, 23872,     0, 
+    16384, 24576, 24577, 23552, 23808, 23936, 23904,     0, 
+    16384, 24576, 24577, 23552, 23808, 23936, 23904,     0, 
+    16384, 24576, 24577, 23552, 23808, 23936, 23904, 23906, 
+        0, 16384, 24576, 24577, 23552, 23808, 23936, 23904, 
+        0, 16384, 24576, 24577, 23552, 23808, 23936, 23904, 
+    23908,     0, 16384, 24576, 24577, 23552, 23808, 23936, 
+    23904, 23908,     0, 16384, 24576, 24577, 23552, 23808, 
+    23936, 23904, 23912, 23910,     0, 16384, 24576, 24577, 
+    23552, 23808, 23936, 23904,     0, 16384, 24576, 24577, 
+    23552, 23808, 23936, 23904, 23912,     0, 16384, 24576, 
+    24577, 23552, 23808, 23936, 23904, 23912,     0, 16384, 
+    24576, 24577, 23552, 23808, 23936, 23904, 23912, 23914, 
+        0, 16384, 24576, 24577, 23552, 23808, 23936, 23904, 
+    23912,     0, 16384, 24576, 24577, 23552, 23808, 23936, 
+    23904, 23920, 23916,     0, 16384, 24576, 24577, 23552, 
+    23808, 23936, 23904, 23920, 23916,     0, 16384, 24576, 
+    24577, 23552, 23808, 23936, 23904, 23920, 23921, 23918, 
+        0, 16384, 24576, 24577, 23552, 23808, 23936, 23904, 
+        0, 16384, 24576, 24577, 23552, 23808, 23936, 23937, 
+    23920,     0, 16384, 24576, 24577, 23552, 23808, 23936, 
+    23937, 23920,     0, 16384, 24576, 24577, 23552, 23808, 
+    23936, 23937, 23920, 23922,     0, 16384, 24576, 24577, 
+    23552, 23808, 23936, 23937, 23920,     0, 16384, 24576, 
+    24577, 23552, 23808, 23936, 23937, 23920, 23924,     0, 
+    16384, 24576, 24577, 23552, 23808, 23936, 23937, 23920, 
+    23924,     0, 16384, 24576, 24577, 23552, 23808, 23936, 
+    23937, 23920, 23928, 23926,     0, 16384, 24576, 24577, 
+    23552, 23808, 23936, 23937, 23920,     0, 16384, 24576, 
+    24577, 23552, 23808, 23936, 23937, 23920, 23928,     0, 
+    16384, 24576, 24577, 23552, 23808, 23936, 23937, 23939, 
+    23928,     0, 16384, 24576, 24577, 23552, 23808, 23936, 
+    23937, 23939, 23928, 23930,     0, 16384, 24576, 24577, 
+    23552, 23808, 23936, 23937, 23939, 23928,     0, 16384, 
+    24576, 24577, 23552, 23808, 23936, 23937, 23939, 23928, 
+    23932,     0, 16384, 24576, 24577, 23552, 23808, 23936, 
+    23937, 23939, 23928, 23932,     0, 16384, 24576, 24577, 
+    23552, 23808, 23936, 23937, 23939, 23928, 23932, 23934, 
+        0, 16384, 24576, 24577, 23552, 23808,     0, 16384, 
+    24576, 24577, 23552, 24064, 23936,     0, 16384, 24576, 
+    24577, 23552, 24064, 23936,     0, 16384, 24576, 24577, 
+    23552, 24064, 23936, 23938,     0, 16384, 24576, 24577, 
+    23552, 24064, 23936,     0, 16384, 24576, 24577, 23552, 
+    24064, 23936, 23940,     0, 16384, 24576, 24577, 23552, 
+    24064, 23936, 23940,     0, 16384, 24576, 24577, 23552, 
+    24064, 23936, 23944, 23942,     0, 16384, 24576, 24577, 
+    23552, 24064, 23936,     0, 16384, 24576, 24577, 23552, 
+    24064, 23936, 23944,     0, 16384, 24576, 24577, 23552, 
+    24064, 23936, 23944,     0, 16384, 24576, 24577, 23552, 
+    24064, 23936, 23944, 23946,     0, 16384, 24576, 24577, 
+    23552, 24064, 23936, 23944,     0, 16384, 24576, 24577, 
+    23552, 24064, 23936, 23952, 23948,     0, 16384, 24576, 
+    24577, 23552, 24064, 23936, 23952, 23948,     0, 16384, 
+    24576, 24577, 23552, 24064, 23936, 23952, 23953, 23950, 
+        0, 16384, 24576, 24577, 23552, 24064, 23936,     0, 
+    16384, 24576, 24577, 23552, 24064, 23936, 23952,     0, 
+    16384, 24576, 24577, 23552, 24064, 23936, 23952,     0, 
+    16384, 24576, 24577, 23552, 24064, 23936, 23952, 23954, 
+        0, 16384, 24576, 24577, 23552, 24064, 23936, 23952, 
+        0, 16384, 24576, 24577, 23552, 24064, 23936, 23952, 
+    23956,     0, 16384, 24576, 24577, 23552, 24064, 23936, 
+    23952, 23956,     0, 16384, 24576, 24577, 23552, 24064, 
+    23936, 23952, 23960, 23958,     0, 16384, 24576, 24577, 
+    23552, 24064, 23936, 23952,     0, 16384, 24576, 24577, 
+    23552, 24064, 23936, 23968, 23960,     0, 16384, 24576, 
+    24577, 23552, 24064, 23936, 23968, 23960,     0, 16384, 
+    24576, 24577, 23552, 24064, 23936, 23968, 23960, 23962, 
+        0, 16384, 24576, 24577, 23552, 24064, 23936, 23968, 
+    23960,     0, 16384, 24576, 24577, 23552, 24064, 23936, 
+    23968, 23969, 23964,     0, 16384, 24576, 24577, 23552, 
+    24064, 23936, 23968, 23969, 23964,     0, 16384, 24576, 
+    24577, 23552, 24064, 23936, 23968, 23969, 23964, 23966, 
+        0, 16384, 24576, 24577, 23552, 24064, 23936,     0, 
+    16384, 24576, 24577, 23552, 24064, 23936, 23968,     0, 
+    16384, 24576, 24577, 23552, 24064, 23936, 23968,     0, 
+    16384, 24576, 24577, 23552, 24064, 23936, 23968, 23970, 
+        0, 16384, 24576, 24577, 23552, 24064, 23936, 23968, 
+        0, 16384, 24576, 24577, 23552, 24064, 23936, 23968, 
+    23972,     0, 16384, 24576, 24577, 23552, 24064, 23936, 
+    23968, 23972,     0, 16384, 24576, 24577, 23552, 24064, 
+    23936, 23968, 23976, 23974,     0, 16384, 24576, 24577, 
+    23552, 24064, 23936, 23968,     0, 16384, 24576, 24577, 
+    23552, 24064, 23936, 23968, 23976,     0, 16384, 24576, 
+    24577, 23552, 24064, 23936, 23968, 23976,     0, 16384, 
+    24576, 24577, 23552, 24064, 23936, 23968, 23976, 23978, 
+        0, 16384, 24576, 24577, 23552, 24064, 23936, 23968, 
+    23976,     0, 16384, 24576, 24577, 23552, 24064, 23936, 
+    23968, 23984, 23980,     0, 16384, 24576, 24577, 23552, 
+    24064, 23936, 23968, 23984, 23980,     0, 16384, 24576, 
+    24577, 23552, 24064, 23936, 23968, 23984, 23985, 23982, 
+        0, 16384, 24576, 24577, 23552, 24064, 23936, 23968, 
+        0, 16384, 24576, 24577, 23552, 24064, 23936, 24000, 
+    23984,     0, 16384, 24576, 24577, 23552, 24064, 23936, 
+    24000, 23984,     0, 16384, 24576, 24577, 23552, 24064, 
+    23936, 24000, 23984, 23986,     0, 16384, 24576, 24577, 
+    23552, 24064, 23936, 24000, 23984,     0, 16384, 24576, 
+    24577, 23552, 24064, 23936, 24000, 23984, 23988,     0, 
+    16384, 24576, 24577, 23552, 24064, 23936, 24000, 23984, 
+    23988,     0, 16384, 24576, 24577, 23552, 24064, 23936, 
+    24000, 23984, 23992, 23990,     0, 16384, 24576, 24577, 
+    23552, 24064, 23936, 24000, 23984,     0, 16384, 24576, 
+    24577, 23552, 24064, 23936, 24000, 24001, 23992,     0, 
+    16384, 24576, 24577, 23552, 24064, 23936, 24000, 24001, 
+    23992,     0, 16384, 24576, 24577, 23552, 24064, 23936, 
+    24000, 24001, 23992, 23994,     0, 16384, 24576, 24577, 
+    23552, 24064, 23936, 24000, 24001, 23992,     0, 16384, 
+    24576, 24577, 23552, 24064, 23936, 24000, 24001, 23992, 
+    23996,     0, 16384, 24576, 24577, 23552, 24064, 23936, 
+    24000, 24001, 24003, 23996,     0, 16384, 24576, 24577, 
+    23552, 24064, 23936, 24000, 24001, 24003, 23996, 23998, 
+        0, 16384, 24576, 24577, 23552, 24064, 23936,     0, 
+    16384, 24576, 24577, 23552, 24064, 24065, 24000,     0, 
+    16384, 24576, 24577, 23552, 24064, 24065, 24000,     0, 
+    16384, 24576, 24577, 23552, 24064, 24065, 24000, 24002, 
+        0, 16384, 24576, 24577, 23552, 24064, 24065, 24000, 
+        0, 16384, 24576, 24577, 23552, 24064, 24065, 24000, 
+    24004,     0, 16384, 24576, 24577, 23552, 24064, 24065, 
+    24000, 24004,     0, 16384, 24576, 24577, 23552, 24064, 
+    24065, 24000, 24008, 24006,     0, 16384, 24576, 24577, 
+    23552, 24064, 24065, 24000,     0, 16384, 24576, 24577, 
+    23552, 24064, 24065, 24000, 24008,     0, 16384, 24576, 
+    24577, 23552, 24064, 24065, 24000, 24008,     0, 16384, 
+    24576, 24577, 23552, 24064, 24065, 24000, 24008, 24010, 
+        0, 16384, 24576, 24577, 23552, 24064, 24065, 24000, 
+    24008,     0, 16384, 24576, 24577, 23552, 24064, 24065, 
+    24000, 24016, 24012,     0, 16384, 24576, 24577, 23552, 
+    24064, 24065, 24000, 24016, 24012,     0, 16384, 24576, 
+    24577, 23552, 24064, 24065, 24000, 24016, 24017, 24014, 
+        0, 16384, 24576, 24577, 23552, 24064, 24065, 24000, 
+        0, 16384, 24576, 24577, 23552, 24064, 24065, 24000, 
+    24016,     0, 16384, 24576, 24577, 23552, 24064, 24065, 
+    24000, 24016,     0, 16384, 24576, 24577, 23552, 24064, 
+    24065, 24000, 24016, 24018,     0, 16384, 24576, 24577, 
+    23552, 24064, 24065, 24000, 24016,     0, 16384, 24576, 
+    24577, 23552, 24064, 24065, 24000, 24016, 24020,     0, 
+    16384, 24576, 24577, 23552, 24064, 24065, 24000, 24016, 
+    24020,     0, 16384, 24576, 24577, 23552, 24064, 24065, 
+    24000, 24016, 24024, 24022,     0, 16384, 24576, 24577, 
+    23552, 24064, 24065, 24000, 24016,     0, 16384, 24576, 
+    24577, 23552, 24064, 24065, 24000, 24032, 24024,     0, 
+    16384, 24576, 24577, 23552, 24064, 24065, 24000, 24032, 
+    24024,     0, 16384, 24576, 24577, 23552, 24064, 24065, 
+    24000, 24032, 24024, 24026,     0, 16384, 24576, 24577, 
+    23552, 24064, 24065, 24000, 24032, 24024,     0, 16384, 
+    24576, 24577, 23552, 24064, 24065, 24000, 24032, 24033, 
+    24028,     0, 16384, 24576, 24577, 23552, 24064, 24065, 
+    24000, 24032, 24033, 24028,     0, 16384, 24576, 24577, 
+    23552, 24064, 24065, 24000, 24032, 24033, 24028, 24030, 
+        0, 16384, 24576, 24577, 23552, 24064, 24065, 24000, 
+        0, 16384, 24576, 24577, 23552, 24064, 24065, 24000, 
+    24032,     0, 16384, 24576, 24577, 23552, 24064, 24065, 
+    24067, 24032,     0, 16384, 24576, 24577, 23552, 24064, 
+    24065, 24067, 24032, 24034,     0, 16384, 24576, 24577, 
+    23552, 24064, 24065, 24067, 24032,     0, 16384, 24576, 
+    24577, 23552, 24064, 24065, 24067, 24032, 24036,     0, 
+    16384, 24576, 24577, 23552, 24064, 24065, 24067, 24032, 
+    24036,     0, 16384, 24576, 24577, 23552, 24064, 24065, 
+    24067, 24032, 24040, 24038,     0, 16384, 24576, 24577, 
+    23552, 24064, 24065, 24067, 24032,     0, 16384, 24576, 
+    24577, 23552, 24064, 24065, 24067, 24032, 24040,     0, 
+    16384, 24576, 24577, 23552, 24064, 24065, 24067, 24032, 
+    24040,     0, 16384, 24576, 24577, 23552, 24064, 24065, 
+    24067, 24032, 24040, 24042,     0, 16384, 24576, 24577, 
+    23552, 24064, 24065, 24067, 24032, 24040,     0, 16384, 
+    24576, 24577, 23552, 24064, 24065, 24067, 24032, 24048, 
+    24044,     0, 16384, 24576, 24577, 23552, 24064, 24065, 
+    24067, 24032, 24048, 24044,     0, 16384, 24576, 24577, 
+    23552, 24064, 24065, 24067, 24032, 24048, 24049, 24046, 
+        0, 16384, 24576, 24577, 23552, 24064, 24065, 24067, 
+    24032,     0, 16384, 24576, 24577, 23552, 24064, 24065, 
+    24067, 24032, 24048,     0, 16384, 24576, 24577, 23552, 
+    24064, 24065, 24067, 24032, 24048,     0, 16384, 24576, 
+    24577, 23552, 24064, 24065, 24067, 24032, 24048, 24050, 
+        0, 16384, 24576, 24577, 23552, 24064, 24065, 24067, 
+    24071, 24048,     0, 16384, 24576, 24577, 23552, 24064, 
+    24065, 24067, 24071, 24048, 24052,     0, 16384, 24576, 
+    24577, 23552, 24064, 24065, 24067, 24071, 24048, 24052, 
+        0, 16384, 24576, 24577, 23552, 24064, 24065, 24067, 
+    24071, 24048, 24056, 24054,     0, 16384, 24576, 24577, 
+    23552, 24064, 24065, 24067, 24071, 24048,     0, 16384, 
+    24576, 24577, 23552, 24064, 24065, 24067, 24071, 24048, 
+    24056,     0, 16384, 24576, 24577, 23552, 24064, 24065, 
+    24067, 24071, 24048, 24056,     0, 16384, 24576, 24577, 
+    23552, 24064, 24065, 24067, 24071, 24048, 24056, 24058, 
+        0, 16384, 24576, 24577, 23552, 24064, 24065, 24067, 
+    24071, 24048, 24056,     0, 16384, 24576, 24577, 23552, 
+    24064, 24065, 24067, 24071, 24048, 24056, 24060,     0, 
+    16384, 24576, 24577, 23552, 24064, 24065, 24067, 24071, 
+    24048, 24056, 24060,     0, 16384, 24576, 24577, 23552, 
+    24064, 24065, 24067, 24071, 24048, 24056, 24060, 24062, 
+        0, 16384, 24576, 24577, 23552,     0, 16384, 24576, 
+    24577, 23552, 24064,     0, 16384, 24576, 24577, 23552, 
+    24064,     0, 16384, 24576, 24577, 23552, 24064, 24066, 
+        0, 16384, 24576, 24577, 24579, 24064,     0, 16384, 
+    24576, 24577, 24579, 24064, 24068,     0, 16384, 24576, 
+    24577, 24579, 24064, 24068,     0, 16384, 24576, 24577, 
+    24579, 24064, 24072, 24070,     0, 16384, 24576, 24577, 
+    24579, 24064,     0, 16384, 24576, 24577, 24579, 24064, 
+    24072,     0, 16384, 24576, 24577, 24579, 24064, 24072, 
+        0, 16384, 24576, 24577, 24579, 24064, 24072, 24074, 
+        0, 16384, 24576, 24577, 24579, 24064, 24072,     0, 
+    16384, 24576, 24577, 24579, 24064, 24080, 24076,     0, 
+    16384, 24576, 24577, 24579, 24064, 24080, 24076,     0, 
+    16384, 24576, 24577, 24579, 24064, 24080, 24081, 24078, 
+        0, 16384, 24576, 24577, 24579, 24064,     0, 16384, 
+    24576, 24577, 24579, 24064, 24080,     0, 16384, 24576, 
+    24577, 24579, 24064, 24080,     0, 16384, 24576, 24577, 
+    24579, 24064, 24080, 24082,     0, 16384, 24576, 24577, 
+    24579, 24064, 24080,     0, 16384, 24576, 24577, 24579, 
+    24064, 24080, 24084,     0, 16384, 24576, 24577, 24579, 
+    24064, 24080, 24084,     0, 16384, 24576, 24577, 24579, 
+    24064, 24080, 24088, 24086,     0, 16384, 24576, 24577, 
+    24579, 24064, 24080,     0, 16384, 24576, 24577, 24579, 
+    24064, 24096, 24088,     0, 16384, 24576, 24577, 24579, 
+    24064, 24096, 24088,     0, 16384, 24576, 24577, 24579, 
+    24064, 24096, 24088, 24090,     0, 16384, 24576, 24577, 
+    24579, 24064, 24096, 24088,     0, 16384, 24576, 24577, 
+    24579, 24064, 24096, 24097, 24092,     0, 16384, 24576, 
+    24577, 24579, 24064, 24096, 24097, 24092,     0, 16384, 
+    24576, 24577, 24579, 24064, 24096, 24097, 24092, 24094, 
+        0, 16384, 24576, 24577, 24579, 24064,     0, 16384, 
+    24576, 24577, 24579, 24064, 24096,     0, 16384, 24576, 
+    24577, 24579, 24064, 24096,     0, 16384, 24576, 24577, 
+    24579, 24064, 24096, 24098,     0, 16384, 24576, 24577, 
+    24579, 24064, 24096,     0, 16384, 24576, 24577, 24579, 
+    24064, 24096, 24100,     0, 16384, 24576, 24577, 24579, 
+    24064, 24096, 24100,     0, 16384, 24576, 24577, 24579, 
+    24064, 24096, 24104, 24102,     0, 16384, 24576, 24577, 
+    24579, 24064, 24096,     0, 16384, 24576, 24577, 24579, 
+    24064, 24096, 24104,     0, 16384, 24576, 24577, 24579, 
+    24064, 24096, 24104,     0, 16384, 24576, 24577, 24579, 
+    24064, 24096, 24104, 24106,     0, 16384, 24576, 24577, 
+    24579, 24064, 24096, 24104,     0, 16384, 24576, 24577, 
+    24579, 24064, 24096, 24112, 24108,     0, 16384, 24576, 
+    24577, 24579, 24064, 24096, 24112, 24108,     0, 16384, 
+    24576, 24577, 24579, 24064, 24096, 24112, 24113, 24110, 
+        0, 16384, 24576, 24577, 24579, 24064, 24096,     0, 
+    16384, 24576, 24577, 24579, 24064, 24128, 24112,     0, 
+    16384, 24576, 24577, 24579, 24064, 24128, 24112,     0, 
+    16384, 24576, 24577, 24579, 24064, 24128, 24112, 24114, 
+        0, 16384, 24576, 24577, 24579, 24064, 24128, 24112, 
+        0, 16384, 24576, 24577, 24579, 24064, 24128, 24112, 
+    24116,     0, 16384, 24576, 24577, 24579, 24064, 24128, 
+    24112, 24116,     0, 16384, 24576, 24577, 24579, 24064, 
+    24128, 24112, 24120, 24118,     0, 16384, 24576, 24577, 
+    24579, 24064, 24128, 24112,     0, 16384, 24576, 24577, 
+    24579, 24064, 24128, 24129, 24120,     0, 16384, 24576, 
+    24577, 24579, 24064, 24128, 24129, 24120,     0, 16384, 
+    24576, 24577, 24579, 24064, 24128, 24129, 24120, 24122, 
+        0, 16384, 24576, 24577, 24579, 24064, 24128, 24129, 
+    24120,     0, 16384, 24576, 24577, 24579, 24064, 24128, 
+    24129, 24120, 24124,     0, 16384, 24576, 24577, 24579, 
+    24064, 24128, 24129, 24131, 24124,     0, 16384, 24576, 
+    24577, 24579, 24064, 24128, 24129, 24131, 24124, 24126, 
+        0, 16384, 24576, 24577, 24579, 24064,     0, 16384, 
+    24576, 24577, 24579, 24064, 24128,     0, 16384, 24576, 
+    24577, 24579, 24064, 24128,     0, 16384, 24576, 24577, 
+    24579, 24064, 24128, 24130,     0, 16384, 24576, 24577, 
+    24579, 24064, 24128,     0, 16384, 24576, 24577, 24579, 
+    24064, 24128, 24132,     0, 16384, 24576, 24577, 24579, 
+    24064, 24128, 24132,     0, 16384, 24576, 24577, 24579, 
+    24064, 24128, 24136, 24134,     0, 16384, 24576, 24577, 
+    24579, 24064, 24128,     0, 16384, 24576, 24577, 24579, 
+    24064, 24128, 24136,     0, 16384, 24576, 24577, 24579, 
+    24064, 24128, 24136,     0, 16384, 24576, 24577, 24579, 
+    24064, 24128, 24136, 24138,     0, 16384, 24576, 24577, 
+    24579, 24064, 24128, 24136,     0, 16384, 24576, 24577, 
+    24579, 24064, 24128, 24144, 24140,     0, 16384, 24576, 
+    24577, 24579, 24064, 24128, 24144, 24140,     0, 16384, 
+    24576, 24577, 24579, 24064, 24128, 24144, 24145, 24142, 
+        0, 16384, 24576, 24577, 24579, 24064, 24128,     0, 
+    16384, 24576, 24577, 24579, 24064, 24128, 24144,     0, 
+    16384, 24576, 24577, 24579, 24064, 24128, 24144,     0, 
+    16384, 24576, 24577, 24579, 24064, 24128, 24144, 24146, 
+        0, 16384, 24576, 24577, 24579, 24064, 24128, 24144, 
+        0, 16384, 24576, 24577, 24579, 24064, 24128, 24144, 
+    24148,     0, 16384, 24576, 24577, 24579, 24064, 24128, 
+    24144, 24148,     0, 16384, 24576, 24577, 24579, 24064, 
+    24128, 24144, 24152, 24150,     0, 16384, 24576, 24577, 
+    24579, 24064, 24128, 24144,     0, 16384, 24576, 24577, 
+    24579, 24064, 24128, 24160, 24152,     0, 16384, 24576, 
+    24577, 24579, 24064, 24128, 24160, 24152,     0, 16384, 
+    24576, 24577, 24579, 24064, 24128, 24160, 24152, 24154, 
+        0, 16384, 24576, 24577, 24579, 24064, 24128, 24160, 
+    24152,     0, 16384, 24576, 24577, 24579, 24064, 24128, 
+    24160, 24161, 24156,     0, 16384, 24576, 24577, 24579, 
+    24064, 24128, 24160, 24161, 24156,     0, 16384, 24576, 
+    24577, 24579, 24064, 24128, 24160, 24161, 24156, 24158, 
+        0, 16384, 24576, 24577, 24579, 24064, 24128,     0, 
+    16384, 24576, 24577, 24579, 24064, 24192, 24160,     0, 
+    16384, 24576, 24577, 24579, 24064, 24192, 24160,     0, 
+    16384, 24576, 24577, 24579, 24064, 24192, 24160, 24162, 
+        0, 16384, 24576, 24577, 24579, 24064, 24192, 24160, 
+        0, 16384, 24576, 24577, 24579, 24064, 24192, 24160, 
+    24164,     0, 16384, 24576, 24577, 24579, 24064, 24192, 
+    24160, 24164,     0, 16384, 24576, 24577, 24579, 24064, 
+    24192, 24160, 24168, 24166,     0, 16384, 24576, 24577, 
+    24579, 24064, 24192, 24160,     0, 16384, 24576, 24577, 
+    24579, 24064, 24192, 24160, 24168,     0, 16384, 24576, 
+    24577, 24579, 24064, 24192, 24160, 24168,     0, 16384, 
+    24576, 24577, 24579, 24064, 24192, 24160, 24168, 24170, 
+        0, 16384, 24576, 24577, 24579, 24064, 24192, 24160, 
+    24168,     0, 16384, 24576, 24577, 24579, 24064, 24192, 
+    24160, 24176, 24172,     0, 16384, 24576, 24577, 24579, 
+    24064, 24192, 24160, 24176, 24172,     0, 16384, 24576, 
+    24577, 24579, 24064, 24192, 24160, 24176, 24177, 24174, 
+        0, 16384, 24576, 24577, 24579, 24064, 24192, 24160, 
+        0, 16384, 24576, 24577, 24579, 24064, 24192, 24193, 
+    24176,     0, 16384, 24576, 24577, 24579, 24064, 24192, 
+    24193, 24176,     0, 16384, 24576, 24577, 24579, 24064, 
+    24192, 24193, 24176, 24178,     0, 16384, 24576, 24577, 
+    24579, 24064, 24192, 24193, 24176,     0, 16384, 24576, 
+    24577, 24579, 24064, 24192, 24193, 24176, 24180,     0, 
+    16384, 24576, 24577, 24579, 24064, 24192, 24193, 24176, 
+    24180,     0, 16384, 24576, 24577, 24579, 24064, 24192, 
+    24193, 24176, 24184, 24182,     0, 16384, 24576, 24577, 
+    24579, 24064, 24192, 24193, 24176,     0, 16384, 24576, 
+    24577, 24579, 24064, 24192, 24193, 24176, 24184,     0, 
+    16384, 24576, 24577, 24579, 24064, 24192, 24193, 24195, 
+    24184,     0, 16384, 24576, 24577, 24579, 24064, 24192, 
+    24193, 24195, 24184, 24186,     0, 16384, 24576, 24577, 
+    24579, 24064, 24192, 24193, 24195, 24184,     0, 16384, 
+    24576, 24577, 24579, 24064, 24192, 24193, 24195, 24184, 
+    24188,     0, 16384, 24576, 24577, 24579, 24064, 24192, 
+    24193, 24195, 24184, 24188,     0, 16384, 24576, 24577, 
+    24579, 24064, 24192, 24193, 24195, 24184, 24188, 24190, 
+        0, 16384, 24576, 24577, 24579, 24064,     0, 16384, 
+    24576, 24577, 24579, 24064, 24192,     0, 16384, 24576, 
+    24577, 24579, 24064, 24192,     0, 16384, 24576, 24577, 
+    24579, 24064, 24192, 24194,     0, 16384, 24576, 24577, 
+    24579, 24064, 24192,     0, 16384, 24576, 24577, 24579, 
+    24064, 24192, 24196,     0, 16384, 24576, 24577, 24579, 
+    24064, 24192, 24196,     0, 16384, 24576, 24577, 24579, 
+    24064, 24192, 24200, 24198,     0, 16384, 24576, 24577, 
+    24579, 24064, 24192,     0, 16384, 24576, 24577, 24579, 
+    24064, 24192, 24200,     0, 16384, 24576, 24577, 24579, 
+    24064, 24192, 24200,     0, 16384, 24576, 24577, 24579, 
+    24064, 24192, 24200, 24202,     0, 16384, 24576, 24577, 
+    24579, 24064, 24192, 24200,     0, 16384, 24576, 24577, 
+    24579, 24064, 24192, 24208, 24204,     0, 16384, 24576, 
+    24577, 24579, 24064, 24192, 24208, 24204,     0, 16384, 
+    24576, 24577, 24579, 24064, 24192, 24208, 24209, 24206, 
+        0, 16384, 24576, 24577, 24579, 24064, 24192,     0, 
+    16384, 24576, 24577, 24579, 24064, 24192, 24208,     0, 
+    16384, 24576, 24577, 24579, 24064, 24192, 24208,     0, 
+    16384, 24576, 24577, 24579, 24064, 24192, 24208, 24210, 
+        0, 16384, 24576, 24577, 24579, 24064, 24192, 24208, 
+        0, 16384, 24576, 24577, 24579, 24064, 24192, 24208, 
+    24212,     0, 16384, 24576, 24577, 24579, 24064, 24192, 
+    24208, 24212,     0, 16384, 24576, 24577, 24579, 24064, 
+    24192, 24208, 24216, 24214,     0, 16384, 24576, 24577, 
+    24579, 24064, 24192, 24208,     0, 16384, 24576, 24577, 
+    24579, 24064, 24192, 24224, 24216,     0, 16384, 24576, 
+    24577, 24579, 24064, 24192, 24224, 24216,     0, 16384, 
+    24576, 24577, 24579, 24064, 24192, 24224, 24216, 24218, 
+        0, 16384, 24576, 24577, 24579, 24064, 24192, 24224, 
+    24216,     0, 16384, 24576, 24577, 24579, 24064, 24192, 
+    24224, 24225, 24220,     0, 16384, 24576, 24577, 24579, 
+    24064, 24192, 24224, 24225, 24220,     0, 16384, 24576, 
+    24577, 24579, 24064, 24192, 24224, 24225, 24220, 24222, 
+        0, 16384, 24576, 24577, 24579, 24064, 24192,     0, 
+    16384, 24576, 24577, 24579, 24064, 24192, 24224,     0, 
+    16384, 24576, 24577, 24579, 24064, 24192, 24224,     0, 
+    16384, 24576, 24577, 24579, 24064, 24192, 24224, 24226, 
+        0, 16384, 24576, 24577, 24579, 24064, 24192, 24224, 
+        0, 16384, 24576, 24577, 24579, 24064, 24192, 24224, 
+    24228,     0, 16384, 24576, 24577, 24579, 24064, 24192, 
+    24224, 24228,     0, 16384, 24576, 24577, 24579, 24064, 
+    24192, 24224, 24232, 24230,     0, 16384, 24576, 24577, 
+    24579, 24064, 24192, 24224,     0, 16384, 24576, 24577, 
+    24579, 24064, 24192, 24224, 24232,     0, 16384, 24576, 
+    24577, 24579, 24064, 24192, 24224, 24232,     0, 16384, 
+    24576, 24577, 24579, 24064, 24192, 24224, 24232, 24234, 
+        0, 16384, 24576, 24577, 24579, 24064, 24192, 24224, 
+    24232,     0, 16384, 24576, 24577, 24579, 24064, 24192, 
+    24224, 24240, 24236,     0, 16384, 24576, 24577, 24579, 
+    24064, 24192, 24224, 24240, 24236,     0, 16384, 24576, 
+    24577, 24579, 24064, 24192, 24224, 24240, 24241, 24238, 
+        0, 16384, 24576, 24577, 24579, 24064, 24192, 24224, 
+        0, 16384, 24576, 24577, 24579, 24064, 24192, 24256, 
+    24240,     0, 16384, 24576, 24577, 24579, 24064, 24192, 
+    24256, 24240,     0, 16384, 24576, 24577, 24579, 24064, 
+    24192, 24256, 24240, 24242,     0, 16384, 24576, 24577, 
+    24579, 24064, 24192, 24256, 24240,     0, 16384, 24576, 
+    24577, 24579, 24064, 24192, 24256, 24240, 24244,     0, 
+    16384, 24576, 24577, 24579, 24064, 24192, 24256, 24240, 
+    24244,     0, 16384, 24576, 24577, 24579, 24064, 24192, 
+    24256, 24240, 24248, 24246,     0, 16384, 24576, 24577, 
+    24579, 24064, 24192, 24256, 24240,     0, 16384, 24576, 
+    24577, 24579, 24064, 24192, 24256, 24257, 24248,     0, 
+    16384, 24576, 24577, 24579, 24064, 24192, 24256, 24257, 
+    24248,     0, 16384, 24576, 24577, 24579, 24064, 24192, 
+    24256, 24257, 24248, 24250,     0, 16384, 24576, 24577, 
+    24579, 24064, 24192, 24256, 24257, 24248,     0, 16384, 
+    24576, 24577, 24579, 24064, 24192, 24256, 24257, 24248, 
+    24252,     0, 16384, 24576, 24577, 24579, 24064, 24192, 
+    24256, 24257, 24259, 24252,     0, 16384, 24576, 24577, 
+    24579, 24064, 24192, 24256, 24257, 24259, 24252, 24254, 
+        0, 16384, 24576, 24577, 24579, 24064, 24192,     0, 
+    16384, 24576, 24577, 24579, 24064, 24320, 24256,     0, 
+    16384, 24576, 24577, 24579, 24064, 24320, 24256,     0, 
+    16384, 24576, 24577, 24579, 24064, 24320, 24256, 24258, 
+        0, 16384, 24576, 24577, 24579, 24064, 24320, 24256, 
+        0, 16384, 24576, 24577, 24579, 24064, 24320, 24256, 
+    24260,     0, 16384, 24576, 24577, 24579, 24064, 24320, 
+    24256, 24260,     0, 16384, 24576, 24577, 24579, 24064, 
+    24320, 24256, 24264, 24262,     0, 16384, 24576, 24577, 
+    24579, 24064, 24320, 24256,     0, 16384, 24576, 24577, 
+    24579, 24064, 24320, 24256, 24264,     0, 16384, 24576, 
+    24577, 24579, 24064, 24320, 24256, 24264,     0, 16384, 
+    24576, 24577, 24579, 24064, 24320, 24256, 24264, 24266, 
+        0, 16384, 24576, 24577, 24579, 24064, 24320, 24256, 
+    24264,     0, 16384, 24576, 24577, 24579, 24064, 24320, 
+    24256, 24272, 24268,     0, 16384, 24576, 24577, 24579, 
+    24064, 24320, 24256, 24272, 24268,     0, 16384, 24576, 
+    24577, 24579, 24064, 24320, 24256, 24272, 24273, 24270, 
+        0, 16384, 24576, 24577, 24579, 24064, 24320, 24256, 
+        0, 16384, 24576, 24577, 24579, 24064, 24320, 24256, 
+    24272,     0, 16384, 24576, 24577, 24579, 24064, 24320, 
+    24256, 24272,     0, 16384, 24576, 24577, 24579, 24064, 
+    24320, 24256, 24272, 24274,     0, 16384, 24576, 24577, 
+    24579, 24064, 24320, 24256, 24272,     0, 16384, 24576, 
+    24577, 24579, 24064, 24320, 24256, 24272, 24276,     0, 
+    16384, 24576, 24577, 24579, 24064, 24320, 24256, 24272, 
+    24276,     0, 16384, 24576, 24577, 24579, 24064, 24320, 
+    24256, 24272, 24280, 24278,     0, 16384, 24576, 24577, 
+    24579, 24064, 24320, 24256, 24272,     0, 16384, 24576, 
+    24577, 24579, 24064, 24320, 24256, 24288, 24280,     0, 
+    16384, 24576, 24577, 24579, 24064, 24320, 24256, 24288, 
+    24280,     0, 16384, 24576, 24577, 24579, 24064, 24320, 
+    24256, 24288, 24280, 24282,     0, 16384, 24576, 24577, 
+    24579, 24064, 24320, 24256, 24288, 24280,     0, 16384, 
+    24576, 24577, 24579, 24064, 24320, 24256, 24288, 24289, 
+    24284,     0, 16384, 24576, 24577, 24579, 24064, 24320, 
+    24256, 24288, 24289, 24284,     0, 16384, 24576, 24577, 
+    24579, 24064, 24320, 24256, 24288, 24289, 24284, 24286, 
+        0, 16384, 24576, 24577, 24579, 24064, 24320, 24256, 
+        0, 16384, 24576, 24577, 24579, 24064, 24320, 24321, 
+    24288,     0, 16384, 24576, 24577, 24579, 24064, 24320, 
+    24321, 24288,     0, 16384, 24576, 24577, 24579, 24064, 
+    24320, 24321, 24288, 24290,     0, 16384, 24576, 24577, 
+    24579, 24064, 24320, 24321, 24288,     0, 16384, 24576, 
+    24577, 24579, 24064, 24320, 24321, 24288, 24292,     0, 
+    16384, 24576, 24577, 24579, 24064, 24320, 24321, 24288, 
+    24292,     0, 16384, 24576, 24577, 24579, 24064, 24320, 
+    24321, 24288, 24296, 24294,     0, 16384, 24576, 24577, 
+    24579, 24064, 24320, 24321, 24288,     0, 16384, 24576, 
+    24577, 24579, 24064, 24320, 24321, 24288, 24296,     0, 
+    16384, 24576, 24577, 24579, 24064, 24320, 24321, 24288, 
+    24296,     0, 16384, 24576, 24577, 24579, 24064, 24320, 
+    24321, 24288, 24296, 24298,     0, 16384, 24576, 24577, 
+    24579, 24064, 24320, 24321, 24288, 24296,     0, 16384, 
+    24576, 24577, 24579, 24064, 24320, 24321, 24288, 24304, 
+    24300,     0, 16384, 24576, 24577, 24579, 24064, 24320, 
+    24321, 24288, 24304, 24300,     0, 16384, 24576, 24577, 
+    24579, 24064, 24320, 24321, 24288, 24304, 24305, 24302, 
+        0, 16384, 24576, 24577, 24579, 24064, 24320, 24321, 
+    24288,     0, 16384, 24576, 24577, 24579, 24064, 24320, 
+    24321, 24288, 24304,     0, 16384, 24576, 24577, 24579, 
+    24064, 24320, 24321, 24323, 24304,     0, 16384, 24576, 
+    24577, 24579, 24064, 24320, 24321, 24323, 24304, 24306, 
+        0, 16384, 24576, 24577, 24579, 24064, 24320, 24321, 
+    24323, 24304,     0, 16384, 24576, 24577, 24579, 24064, 
+    24320, 24321, 24323, 24304, 24308,     0, 16384, 24576, 
+    24577, 24579, 24064, 24320, 24321, 24323, 24304, 24308, 
+        0, 16384, 24576, 24577, 24579, 24064, 24320, 24321, 
+    24323, 24304, 24312, 24310,     0, 16384, 24576, 24577, 
+    24579, 24064, 24320, 24321, 24323, 24304,     0, 16384, 
+    24576, 24577, 24579, 24064, 24320, 24321, 24323, 24304, 
+    24312,     0, 16384, 24576, 24577, 24579, 24064, 24320, 
+    24321, 24323, 24304, 24312,     0, 16384, 24576, 24577, 
+    24579, 24064, 24320, 24321, 24323, 24304, 24312, 24314, 
+        0, 16384, 24576, 24577, 24579, 24064, 24320, 24321, 
+    24323, 24327, 24312,     0, 16384, 24576, 24577, 24579, 
+    24064, 24320, 24321, 24323, 24327, 24312, 24316,     0, 
+    16384, 24576, 24577, 24579, 24064, 24320, 24321, 24323, 
+    24327, 24312, 24316,     0, 16384, 24576, 24577, 24579, 
+    24064, 24320, 24321, 24323, 24327, 24312, 24316, 24318, 
+        0, 16384, 24576, 24577, 24579, 24064,     0, 16384, 
+    24576, 24577, 24579, 24064, 24320,     0, 16384, 24576, 
+    24577, 24579, 24064, 24320,     0, 16384, 24576, 24577, 
+    24579, 24064, 24320, 24322,     0, 16384, 24576, 24577, 
+    24579, 24064, 24320,     0, 16384, 24576, 24577, 24579, 
+    24064, 24320, 24324,     0, 16384, 24576, 24577, 24579, 
+    24064, 24320, 24324,     0, 16384, 24576, 24577, 24579, 
+    24064, 24320, 24328, 24326,     0, 16384, 24576, 24577, 
+    24579, 24583, 24320,     0, 16384, 24576, 24577, 24579, 
+    24583, 24320, 24328,     0, 16384, 24576, 24577, 24579, 
+    24583, 24320, 24328,     0, 16384, 24576, 24577, 24579, 
+    24583, 24320, 24328, 24330,     0, 16384, 24576, 24577, 
+    24579, 24583, 24320, 24328,     0, 16384, 24576, 24577, 
+    24579, 24583, 24320, 24336, 24332,     0, 16384, 24576, 
+    24577, 24579, 24583, 24320, 24336, 24332,     0, 16384, 
+    24576, 24577, 24579, 24583, 24320, 24336, 24337, 24334, 
+        0, 16384, 24576, 24577, 24579, 24583, 24320,     0, 
+    16384, 24576, 24577, 24579, 24583, 24320, 24336,     0, 
+    16384, 24576, 24577, 24579, 24583, 24320, 24336,     0, 
+    16384, 24576, 24577, 24579, 24583, 24320, 24336, 24338, 
+        0, 16384, 24576, 24577, 24579, 24583, 24320, 24336, 
+        0, 16384, 24576, 24577, 24579, 24583, 24320, 24336, 
+    24340,     0, 16384, 24576, 24577, 24579, 24583, 24320, 
+    24336, 24340,     0, 16384, 24576, 24577, 24579, 24583, 
+    24320, 24336, 24344, 24342,     0, 16384, 24576, 24577, 
+    24579, 24583, 24320, 24336,     0, 16384, 24576, 24577, 
+    24579, 24583, 24320, 24352, 24344,     0, 16384, 24576, 
+    24577, 24579, 24583, 24320, 24352, 24344,     0, 16384, 
+    24576, 24577, 24579, 24583, 24320, 24352, 24344, 24346, 
+        0, 16384, 24576, 24577, 24579, 24583, 24320, 24352, 
+    24344,     0, 16384, 24576, 24577, 24579, 24583, 24320, 
+    24352, 24353, 24348,     0, 16384, 24576, 24577, 24579, 
+    24583, 24320, 24352, 24353, 24348,     0, 16384, 24576, 
+    24577, 24579, 24583, 24320, 24352, 24353, 24348, 24350, 
+        0, 16384, 24576, 24577, 24579, 24583, 24320,     0, 
+    16384, 24576, 24577, 24579, 24583, 24320, 24352,     0, 
+    16384, 24576, 24577, 24579, 24583, 24320, 24352,     0, 
+    16384, 24576, 24577, 24579, 24583, 24320, 24352, 24354, 
+        0, 16384, 24576, 24577, 24579, 24583, 24320, 24352, 
+        0, 16384, 24576, 24577, 24579, 24583, 24320, 24352, 
+    24356,     0, 16384, 24576, 24577, 24579, 24583, 24320, 
+    24352, 24356,     0, 16384, 24576, 24577, 24579, 24583, 
+    24320, 24352, 24360, 24358,     0, 16384, 24576, 24577, 
+    24579, 24583, 24320, 24352,     0, 16384, 24576, 24577, 
+    24579, 24583, 24320, 24352, 24360,     0, 16384, 24576, 
+    24577, 24579, 24583, 24320, 24352, 24360,     0, 16384, 
+    24576, 24577, 24579, 24583, 24320, 24352, 24360, 24362, 
+        0, 16384, 24576, 24577, 24579, 24583, 24320, 24352, 
+    24360,     0, 16384, 24576, 24577, 24579, 24583, 24320, 
+    24352, 24368, 24364,     0, 16384, 24576, 24577, 24579, 
+    24583, 24320, 24352, 24368, 24364,     0, 16384, 24576, 
+    24577, 24579, 24583, 24320, 24352, 24368, 24369, 24366, 
+        0, 16384, 24576, 24577, 24579, 24583, 24320, 24352, 
+        0, 16384, 24576, 24577, 24579, 24583, 24320, 24384, 
+    24368,     0, 16384, 24576, 24577, 24579, 24583, 24320, 
+    24384, 24368,     0, 16384, 24576, 24577, 24579, 24583, 
+    24320, 24384, 24368, 24370,     0, 16384, 24576, 24577, 
+    24579, 24583, 24320, 24384, 24368,     0, 16384, 24576, 
+    24577, 24579, 24583, 24320, 24384, 24368, 24372,     0, 
+    16384, 24576, 24577, 24579, 24583, 24320, 24384, 24368, 
+    24372,     0, 16384, 24576, 24577, 24579, 24583, 24320, 
+    24384, 24368, 24376, 24374,     0, 16384, 24576, 24577, 
+    24579, 24583, 24320, 24384, 24368,     0, 16384, 24576, 
+    24577, 24579, 24583, 24320, 24384, 24385, 24376,     0, 
+    16384, 24576, 24577, 24579, 24583, 24320, 24384, 24385, 
+    24376,     0, 16384, 24576, 24577, 24579, 24583, 24320, 
+    24384, 24385, 24376, 24378,     0, 16384, 24576, 24577, 
+    24579, 24583, 24320, 24384, 24385, 24376,     0, 16384, 
+    24576, 24577, 24579, 24583, 24320, 24384, 24385, 24376, 
+    24380,     0, 16384, 24576, 24577, 24579, 24583, 24320, 
+    24384, 24385, 24387, 24380,     0, 16384, 24576, 24577, 
+    24579, 24583, 24320, 24384, 24385, 24387, 24380, 24382, 
+        0, 16384, 24576, 24577, 24579, 24583, 24320,     0, 
+    16384, 24576, 24577, 24579, 24583, 24320, 24384,     0, 
+    16384, 24576, 24577, 24579, 24583, 24320, 24384,     0, 
+    16384, 24576, 24577, 24579, 24583, 24320, 24384, 24386, 
+        0, 16384, 24576, 24577, 24579, 24583, 24320, 24384, 
+        0, 16384, 24576, 24577, 24579, 24583, 24320, 24384, 
+    24388,     0, 16384, 24576, 24577, 24579, 24583, 24320, 
+    24384, 24388,     0, 16384, 24576, 24577, 24579, 24583, 
+    24320, 24384, 24392, 24390,     0, 16384, 24576, 24577, 
+    24579, 24583, 24320, 24384,     0, 16384, 24576, 24577, 
+    24579, 24583, 24320, 24384, 24392,     0, 16384, 24576, 
+    24577, 24579, 24583, 24320, 24384, 24392,     0, 16384, 
+    24576, 24577, 24579, 24583, 24320, 24384, 24392, 24394, 
+        0, 16384, 24576, 24577, 24579, 24583, 24320, 24384, 
+    24392,     0, 16384, 24576, 24577, 24579, 24583, 24320, 
+    24384, 24400, 24396,     0, 16384, 24576, 24577, 24579, 
+    24583, 24320, 24384, 24400, 24396,     0, 16384, 24576, 
+    24577, 24579, 24583, 24320, 24384, 24400, 24401, 24398, 
+        0, 16384, 24576, 24577, 24579, 24583, 24320, 24384, 
+        0, 16384, 24576, 24577, 24579, 24583, 24320, 24384, 
+    24400,     0, 16384, 24576, 24577, 24579, 24583, 24320, 
+    24384, 24400,     0, 16384, 24576, 24577, 24579, 24583, 
+    24320, 24384, 24400, 24402,     0, 16384, 24576, 24577, 
+    24579, 24583, 24320, 24384, 24400,     0, 16384, 24576, 
+    24577, 24579, 24583, 24320, 24384, 24400, 24404,     0, 
+    16384, 24576, 24577, 24579, 24583, 24320, 24384, 24400, 
+    24404,     0, 16384, 24576, 24577, 24579, 24583, 24320, 
+    24384, 24400, 24408, 24406,     0, 16384, 24576, 24577, 
+    24579, 24583, 24320, 24384, 24400,     0, 16384, 24576, 
+    24577, 24579, 24583, 24320, 24384, 24416, 24408,     0, 
+    16384, 24576, 24577, 24579, 24583, 24320, 24384, 24416, 
+    24408,     0, 16384, 24576, 24577, 24579, 24583, 24320, 
+    24384, 24416, 24408, 24410,     0, 16384, 24576, 24577, 
+    24579, 24583, 24320, 24384, 24416, 24408,     0, 16384, 
+    24576, 24577, 24579, 24583, 24320, 24384, 24416, 24417, 
+    24412,     0, 16384, 24576, 24577, 24579, 24583, 24320, 
+    24384, 24416, 24417, 24412,     0, 16384, 24576, 24577, 
+    24579, 24583, 24320, 24384, 24416, 24417, 24412, 24414, 
+        0, 16384, 24576, 24577, 24579, 24583, 24320, 24384, 
+        0, 16384, 24576, 24577, 24579, 24583, 24320, 24448, 
+    24416,     0, 16384, 24576, 24577, 24579, 24583, 24320, 
+    24448, 24416,     0, 16384, 24576, 24577, 24579, 24583, 
+    24320, 24448, 24416, 24418,     0, 16384, 24576, 24577, 
+    24579, 24583, 24320, 24448, 24416,     0, 16384, 24576, 
+    24577, 24579, 24583, 24320, 24448, 24416, 24420,     0, 
+    16384, 24576, 24577, 24579, 24583, 24320, 24448, 24416, 
+    24420,     0, 16384, 24576, 24577, 24579, 24583, 24320, 
+    24448, 24416, 24424, 24422,     0, 16384, 24576, 24577, 
+    24579, 24583, 24320, 24448, 24416,     0, 16384, 24576, 
+    24577, 24579, 24583, 24320, 24448, 24416, 24424,     0, 
+    16384, 24576, 24577, 24579, 24583, 24320, 24448, 24416, 
+    24424,     0, 16384, 24576, 24577, 24579, 24583, 24320, 
+    24448, 24416, 24424, 24426,     0, 16384, 24576, 24577, 
+    24579, 24583, 24320, 24448, 24416, 24424,     0, 16384, 
+    24576, 24577, 24579, 24583, 24320, 24448, 24416, 24432, 
+    24428,     0, 16384, 24576, 24577, 24579, 24583, 24320, 
+    24448, 24416, 24432, 24428,     0, 16384, 24576, 24577, 
+    24579, 24583, 24320, 24448, 24416, 24432, 24433, 24430, 
+        0, 16384, 24576, 24577, 24579, 24583, 24320, 24448, 
+    24416,     0, 16384, 24576, 24577, 24579, 24583, 24320, 
+    24448, 24449, 24432,     0, 16384, 24576, 24577, 24579, 
+    24583, 24320, 24448, 24449, 24432,     0, 16384, 24576, 
+    24577, 24579, 24583, 24320, 24448, 24449, 24432, 24434, 
+        0, 16384, 24576, 24577, 24579, 24583, 24320, 24448, 
+    24449, 24432,     0, 16384, 24576, 24577, 24579, 24583, 
+    24320, 24448, 24449, 24432, 24436,     0, 16384, 24576, 
+    24577, 24579, 24583, 24320, 24448, 24449, 24432, 24436, 
+        0, 16384, 24576, 24577, 24579, 24583, 24320, 24448, 
+    24449, 24432, 24440, 24438,     0, 16384, 24576, 24577, 
+    24579, 24583, 24320, 24448, 24449, 24432,     0, 16384, 
+    24576, 24577, 24579, 24583, 24320, 24448, 24449, 24432, 
+    24440,     0, 16384, 24576, 24577, 24579, 24583, 24320, 
+    24448, 24449, 24451, 24440,     0, 16384, 24576, 24577, 
+    24579, 24583, 24320, 24448, 24449, 24451, 24440, 24442, 
+        0, 16384, 24576, 24577, 24579, 24583, 24320, 24448, 
+    24449, 24451, 24440,     0, 16384, 24576, 24577, 24579, 
+    24583, 24320, 24448, 24449, 24451, 24440, 24444,     0, 
+    16384, 24576, 24577, 24579, 24583, 24320, 24448, 24449, 
+    24451, 24440, 24444,     0, 16384, 24576, 24577, 24579, 
+    24583, 24320, 24448, 24449, 24451, 24440, 24444, 24446, 
+        0, 16384, 24576, 24577, 24579, 24583, 24320,     0, 
+    16384, 24576, 24577, 24579, 24583, 24320, 24448,     0, 
+    16384, 24576, 24577, 24579, 24583, 24320, 24448,     0, 
+    16384, 24576, 24577, 24579, 24583, 24320, 24448, 24450, 
+        0, 16384, 24576, 24577, 24579, 24583, 24320, 24448, 
+        0, 16384, 24576, 24577, 24579, 24583, 24320, 24448, 
+    24452,     0, 16384, 24576, 24577, 24579, 24583, 24320, 
+    24448, 24452,     0, 16384, 24576, 24577, 24579, 24583, 
+    24320, 24448, 24456, 24454,     0, 16384, 24576, 24577, 
+    24579, 24583, 24320, 24448,     0, 16384, 24576, 24577, 
+    24579, 24583, 24320, 24448, 24456,     0, 16384, 24576, 
+    24577, 24579, 24583, 24320, 24448, 24456,     0, 16384, 
+    24576, 24577, 24579, 24583, 24320, 24448, 24456, 24458, 
+        0, 16384, 24576, 24577, 24579, 24583, 24320, 24448, 
+    24456,     0, 16384, 24576, 24577, 24579, 24583, 24320, 
+    24448, 24464, 24460,     0, 16384, 24576, 24577, 24579, 
+    24583, 24320, 24448, 24464, 24460,     0, 16384, 24576, 
+    24577, 24579, 24583, 24320, 24448, 24464, 24465, 24462, 
+        0, 16384, 24576, 24577, 24579, 24583, 24591, 24448, 
+        0, 16384, 24576, 24577, 24579, 24583, 24591, 24448, 
+    24464,     0, 16384, 24576, 24577, 24579, 24583, 24591, 
+    24448, 24464,     0, 16384, 24576, 24577, 24579, 24583, 
+    24591, 24448, 24464, 24466,     0, 16384, 24576, 24577, 
+    24579, 24583, 24591, 24448, 24464,     0, 16384, 24576, 
+    24577, 24579, 24583, 24591, 24448, 24464, 24468,     0, 
+    16384, 24576, 24577, 24579, 24583, 24591, 24448, 24464, 
+    24468,     0, 16384, 24576, 24577, 24579, 24583, 24591, 
+    24448, 24464, 24472, 24470,     0, 16384, 24576, 24577, 
+    24579, 24583, 24591, 24448, 24464,     0, 16384, 24576, 
+    24577, 24579, 24583, 24591, 24448, 24480, 24472,     0, 
+    16384, 24576, 24577, 24579, 24583, 24591, 24448, 24480, 
+    24472,     0, 16384, 24576, 24577, 24579, 24583, 24591, 
+    24448, 24480, 24472, 24474,     0, 16384, 24576, 24577, 
+    24579, 24583, 24591, 24448, 24480, 24472,     0, 16384, 
+    24576, 24577, 24579, 24583, 24591, 24448, 24480, 24481, 
+    24476,     0, 16384, 24576, 24577, 24579, 24583, 24591, 
+    24448, 24480, 24481, 24476,     0, 16384, 24576, 24577, 
+    24579, 24583, 24591, 24448, 24480, 24481, 24476, 24478, 
+        0, 16384, 24576, 24577, 24579, 24583, 24591, 24448, 
+        0, 16384, 24576, 24577, 24579, 24583, 24591, 24448, 
+    24480,     0, 16384, 24576, 24577, 24579, 24583, 24591, 
+    24448, 24480,     0, 16384, 24576, 24577, 24579, 24583, 
+    24591, 24448, 24480, 24482,     0, 16384, 24576, 24577, 
+    24579, 24583, 24591, 24448, 24480,     0, 16384, 24576, 
+    24577, 24579, 24583, 24591, 24448, 24480, 24484,     0, 
+    16384, 24576, 24577, 24579, 24583, 24591, 24448, 24480, 
+    24484,     0, 16384, 24576, 24577, 24579, 24583, 24591, 
+    24448, 24480, 24488, 24486,     0, 16384, 24576, 24577, 
+    24579, 24583, 24591, 24448, 24480,     0, 16384, 24576, 
+    24577, 24579, 24583, 24591, 24448, 24480, 24488,     0, 
+    16384, 24576, 24577, 24579, 24583, 24591, 24448, 24480, 
+    24488,     0, 16384, 24576, 24577, 24579, 24583, 24591, 
+    24448, 24480, 24488, 24490,     0, 16384, 24576, 24577, 
+    24579, 24583, 24591, 24448, 24480, 24488,     0, 16384, 
+    24576, 24577, 24579, 24583, 24591, 24448, 24480, 24496, 
+    24492,     0, 16384, 24576, 24577, 24579, 24583, 24591, 
+    24448, 24480, 24496, 24492,     0, 16384, 24576, 24577, 
+    24579, 24583, 24591, 24448, 24480, 24496, 24497, 24494, 
+        0, 16384, 24576, 24577, 24579, 24583, 24591, 24448, 
+    24480,     0, 16384, 24576, 24577, 24579, 24583, 24591, 
+    24448, 24512, 24496,     0, 16384, 24576, 24577, 24579, 
+    24583, 24591, 24448, 24512, 24496,     0, 16384, 24576, 
+    24577, 24579, 24583, 24591, 24448, 24512, 24496, 24498, 
+        0, 16384, 24576, 24577, 24579, 24583, 24591, 24448, 
+    24512, 24496,     0, 16384, 24576, 24577, 24579, 24583, 
+    24591, 24448, 24512, 24496, 24500,     0, 16384, 24576, 
+    24577, 24579, 24583, 24591, 24448, 24512, 24496, 24500, 
+        0, 16384, 24576, 24577, 24579, 24583, 24591, 24448, 
+    24512, 24496, 24504, 24502,     0, 16384, 24576, 24577, 
+    24579, 24583, 24591, 24448, 24512, 24496,     0, 16384, 
+    24576, 24577, 24579, 24583, 24591, 24448, 24512, 24513, 
+    24504,     0, 16384, 24576, 24577, 24579, 24583, 24591, 
+    24448, 24512, 24513, 24504,     0, 16384, 24576, 24577, 
+    24579, 24583, 24591, 24448, 24512, 24513, 24504, 24506, 
+        0, 16384, 24576, 24577, 24579, 24583, 24591, 24448, 
+    24512, 24513, 24504,     0, 16384, 24576, 24577, 24579, 
+    24583, 24591, 24448, 24512, 24513, 24504, 24508,     0, 
+    16384, 24576, 24577, 24579, 24583, 24591, 24448, 24512, 
+    24513, 24515, 24508,     0, 16384, 24576, 24577, 24579, 
+    24583, 24591, 24448, 24512, 24513, 24515, 24508, 24510, 
+        0, 16384, 24576, 24577, 24579, 24583, 24591, 24448, 
+        0, 16384, 24576, 24577, 24579, 24583, 24591, 24448, 
+    24512,     0, 16384, 24576, 24577, 24579, 24583, 24591, 
+    24448, 24512,     0, 16384, 24576, 24577, 24579, 24583, 
+    24591, 24448, 24512, 24514,     0, 16384, 24576, 24577, 
+    24579, 24583, 24591, 24448, 24512,     0, 16384, 24576, 
+    24577, 24579, 24583, 24591, 24448, 24512, 24516,     0, 
+    16384, 24576, 24577, 24579, 24583, 24591, 24448, 24512, 
+    24516,     0, 16384, 24576, 24577, 24579, 24583, 24591, 
+    24448, 24512, 24520, 24518,     0, 16384, 24576, 24577, 
+    24579, 24583, 24591, 24448, 24512,     0, 16384, 24576, 
+    24577, 24579, 24583, 24591, 24448, 24512, 24520,     0, 
+    16384, 24576, 24577, 24579, 24583, 24591, 24448, 24512, 
+    24520,     0, 16384, 24576, 24577, 24579, 24583, 24591, 
+    24448, 24512, 24520, 24522,     0, 16384, 24576, 24577, 
+    24579, 24583, 24591, 24448, 24512, 24520,     0, 16384, 
+    24576, 24577, 24579, 24583, 24591, 24448, 24512, 24528, 
+    24524,     0, 16384, 24576, 24577, 24579, 24583, 24591, 
+    24448, 24512, 24528, 24524,     0, 16384, 24576, 24577, 
+    24579, 24583, 24591, 24448, 24512, 24528, 24529, 24526, 
+        0, 16384, 24576, 24577, 24579, 24583, 24591, 24448, 
+    24512,     0, 16384, 24576, 24577, 24579, 24583, 24591, 
+    24448, 24512, 24528,     0, 16384, 24576, 24577, 24579, 
+    24583, 24591, 24448, 24512, 24528,     0, 16384, 24576, 
+    24577, 24579, 24583, 24591, 24448, 24512, 24528, 24530, 
+        0, 16384, 24576, 24577, 24579, 24583, 24591, 24448, 
+    24512, 24528,     0, 16384, 24576, 24577, 24579, 24583, 
+    24591, 24448, 24512, 24528, 24532,     0, 16384, 24576, 
+    24577, 24579, 24583, 24591, 24448, 24512, 24528, 24532, 
+        0, 16384, 24576, 24577, 24579, 24583, 24591, 24448, 
+    24512, 24528, 24536, 24534,     0, 16384, 24576, 24577, 
+    24579, 24583, 24591, 24448, 24512, 24528,     0, 16384, 
+    24576, 24577, 24579, 24583, 24591, 24448, 24512, 24544, 
+    24536,     0, 16384, 24576, 24577, 24579, 24583, 24591, 
+    24448, 24512, 24544, 24536,     0, 16384, 24576, 24577, 
+    24579, 24583, 24591, 24448, 24512, 24544, 24536, 24538, 
+        0, 16384, 24576, 24577, 24579, 24583, 24591, 24448, 
+    24512, 24544, 24536,     0, 16384, 24576, 24577, 24579, 
+    24583, 24591, 24448, 24512, 24544, 24545, 24540,     0, 
+    16384, 24576, 24577, 24579, 24583, 24591, 24448, 24512, 
+    24544, 24545, 24540,     0, 16384, 24576, 24577, 24579, 
+    24583, 24591, 24448, 24512, 24544, 24545, 24540, 24542, 
+        0, 16384, 24576, 24577, 24579, 24583, 24591, 24607, 
+    24512,     0, 16384, 24576, 24577, 24579, 24583, 24591, 
+    24607, 24512, 24544,     0, 16384, 24576, 24577, 24579, 
+    24583, 24591, 24607, 24512, 24544,     0, 16384, 24576, 
+    24577, 24579, 24583, 24591, 24607, 24512, 24544, 24546, 
+        0, 16384, 24576, 24577, 24579, 24583, 24591, 24607, 
+    24512, 24544,     0, 16384, 24576, 24577, 24579, 24583, 
+    24591, 24607, 24512, 24544, 24548,     0, 16384, 24576, 
+    24577, 24579, 24583, 24591, 24607, 24512, 24544, 24548, 
+        0, 16384, 24576, 24577, 24579, 24583, 24591, 24607, 
+    24512, 24544, 24552, 24550,     0, 16384, 24576, 24577, 
+    24579, 24583, 24591, 24607, 24512, 24544,     0, 16384, 
+    24576, 24577, 24579, 24583, 24591, 24607, 24512, 24544, 
+    24552,     0, 16384, 24576, 24577, 24579, 24583, 24591, 
+    24607, 24512, 24544, 24552,     0, 16384, 24576, 24577, 
+    24579, 24583, 24591, 24607, 24512, 24544, 24552, 24554, 
+        0, 16384, 24576, 24577, 24579, 24583, 24591, 24607, 
+    24512, 24544, 24552,     0, 16384, 24576, 24577, 24579, 
+    24583, 24591, 24607, 24512, 24544, 24560, 24556,     0, 
+    16384, 24576, 24577, 24579, 24583, 24591, 24607, 24512, 
+    24544, 24560, 24556,     0, 16384, 24576, 24577, 24579, 
+    24583, 24591, 24607, 24512, 24544, 24560, 24561, 24558, 
+        0, 16384, 24576, 24577, 24579, 24583, 24591, 24607, 
+    24512, 24544,     0, 16384, 24576, 24577, 24579, 24583, 
+    24591, 24607, 24512, 24544, 24560,     0, 16384, 24576, 
+    24577, 24579, 24583, 24591, 24607, 24512, 24544, 24560, 
+        0, 16384, 24576, 24577, 24579, 24583, 24591, 24607, 
+    24512, 24544, 24560, 24562,     0, 16384, 24576, 24577, 
+    24579, 24583, 24591, 24607, 24512, 24544, 24560,     0, 
+    16384, 24576, 24577, 24579, 24583, 24591, 24607, 24512, 
+    24544, 24560, 24564,     0, 16384, 24576, 24577, 24579, 
+    24583, 24591, 24607, 24512, 24544, 24560, 24564,     0, 
+    16384, 24576, 24577, 24579, 24583, 24591, 24607, 24512, 
+    24544, 24560, 24568, 24566,     0, 16384, 24576, 24577, 
+    24579, 24583, 24591, 24607, 24512, 24544, 24560,     0, 
+    16384, 24576, 24577, 24579, 24583, 24591, 24607, 24512, 
+    24544, 24560, 24568,     0, 16384, 24576, 24577, 24579, 
+    24583, 24591, 24607, 24512, 24544, 24560, 24568,     0, 
+    16384, 24576, 24577, 24579, 24583, 24591, 24607, 24512, 
+    24544, 24560, 24568, 24570,     0, 16384, 24576, 24577, 
+    24579, 24583, 24591, 24607, 24512, 24544, 24560, 24568, 
+        0, 16384, 24576, 24577, 24579, 24583, 24591, 24607, 
+    24512, 24544, 24560, 24568, 24572,     0, 16384, 24576, 
+    24577, 24579, 24583, 24591, 24607, 24512, 24544, 24560, 
+    24568, 24572,     0, 16384, 24576, 24577, 24579, 24583, 
+    24591, 24607, 24512, 24544, 24560, 24568, 24572, 24574, 
+        0, 16384,     0, 16384, 24576,     0, 16384, 24576, 
+        0, 16384, 24576, 24578,     0, 16384, 24576,     0, 
+    16384, 24576, 24580,     0, 16384, 24576, 24580,     0, 
+    16384, 24576, 24584, 24582,     0, 16384, 24576,     0, 
+    16384, 24576, 24584,     0, 16384, 24576, 24584,     0, 
+    16384, 24576, 24584, 24586,     0, 16384, 24576, 24584, 
+        0, 16384, 24576, 24592, 24588,     0, 16384, 24576, 
+    24592, 24588,     0, 16384, 24576, 24592, 24593, 24590, 
+        0, 16384, 24576,     0, 16384, 24576, 24592,     0, 
+    16384, 24576, 24592,     0, 16384, 24576, 24592, 24594, 
+        0, 16384, 24576, 24592,     0, 16384, 24576, 24592, 
+    24596,     0, 16384, 24576, 24592, 24596,     0, 16384, 
+    24576, 24592, 24600, 24598,     0, 16384, 24576, 24592, 
+        0, 16384, 24576, 24608, 24600,     0, 16384, 24576, 
+    24608, 24600,     0, 16384, 24576, 24608, 24600, 24602, 
+        0, 16384, 24576, 24608, 24600,     0, 16384, 24576, 
+    24608, 24609, 24604,     0, 16384, 24576, 24608, 24609, 
+    24604,     0, 16384, 24576, 24608, 24609, 24604, 24606, 
+        0, 16384, 24576,     0, 16384, 24576, 24608,     0, 
+    16384, 24576, 24608,     0, 16384, 24576, 24608, 24610, 
+        0, 16384, 24576, 24608,     0, 16384, 24576, 24608, 
+    24612,     0, 16384, 24576, 24608, 24612,     0, 16384, 
+    24576, 24608, 24616, 24614,     0, 16384, 24576, 24608, 
+        0, 16384, 24576, 24608, 24616,     0, 16384, 24576, 
+    24608, 24616,     0, 16384, 24576, 24608, 24616, 24618, 
+        0, 16384, 24576, 24608, 24616,     0, 16384, 24576, 
+    24608, 24624, 24620,     0, 16384, 24576, 24608, 24624, 
+    24620,     0, 16384, 24576, 24608, 24624, 24625, 24622, 
+        0, 16384, 24576, 24608,     0, 16384, 24576, 24640, 
+    24624,     0, 16384, 24576, 24640, 24624,     0, 16384, 
+    24576, 24640, 24624, 24626,     0, 16384, 24576, 24640, 
+    24624,     0, 16384, 24576, 24640, 24624, 24628,     0, 
+    16384, 24576, 24640, 24624, 24628,     0, 16384, 24576, 
+    24640, 24624, 24632, 24630,     0, 16384, 24576, 24640, 
+    24624,     0, 16384, 24576, 24640, 24641, 24632,     0, 
+    16384, 24576, 24640, 24641, 24632,     0, 16384, 24576, 
+    24640, 24641, 24632, 24634,     0, 16384, 24576, 24640, 
+    24641, 24632,     0, 16384, 24576, 24640, 24641, 24632, 
+    24636,     0, 16384, 24576, 24640, 24641, 24643, 24636, 
+        0, 16384, 24576, 24640, 24641, 24643, 24636, 24638, 
+        0, 16384, 24576,     0, 16384, 24576, 24640,     0, 
+    16384, 24576, 24640,     0, 16384, 24576, 24640, 24642, 
+        0, 16384, 24576, 24640,     0, 16384, 24576, 24640, 
+    24644,     0, 16384, 24576, 24640, 24644,     0, 16384, 
+    24576, 24640, 24648, 24646,     0, 16384, 24576, 24640, 
+        0, 16384, 24576, 24640, 24648,     0, 16384, 24576, 
+    24640, 24648,     0, 16384, 24576, 24640, 24648, 24650, 
+        0, 16384, 24576, 24640, 24648,     0, 16384, 24576, 
+    24640, 24656, 24652,     0, 16384, 24576, 24640, 24656, 
+    24652,     0, 16384, 24576, 24640, 24656, 24657, 24654, 
+        0, 16384, 24576, 24640,     0, 16384, 24576, 24640, 
+    24656,     0, 16384, 24576, 24640, 24656,     0, 16384, 
+    24576, 24640, 24656, 24658,     0, 16384, 24576, 24640, 
+    24656,     0, 16384, 24576, 24640, 24656, 24660,     0, 
+    16384, 24576, 24640, 24656, 24660,     0, 16384, 24576, 
+    24640, 24656, 24664, 24662,     0, 16384, 24576, 24640, 
+    24656,     0, 16384, 24576, 24640, 24672, 24664,     0, 
+    16384, 24576, 24640, 24672, 24664,     0, 16384, 24576, 
+    24640, 24672, 24664, 24666,     0, 16384, 24576, 24640, 
+    24672, 24664,     0, 16384, 24576, 24640, 24672, 24673, 
+    24668,     0, 16384, 24576, 24640, 24672, 24673, 24668, 
+        0, 16384, 24576, 24640, 24672, 24673, 24668, 24670, 
+        0, 16384, 24576, 24640,     0, 16384, 24576, 24704, 
+    24672,     0, 16384, 24576, 24704, 24672,     0, 16384, 
+    24576, 24704, 24672, 24674,     0, 16384, 24576, 24704, 
+    24672,     0, 16384, 24576, 24704, 24672, 24676,     0, 
+    16384, 24576, 24704, 24672, 24676,     0, 16384, 24576, 
+    24704, 24672, 24680, 24678,     0, 16384, 24576, 24704, 
+    24672,     0, 16384, 24576, 24704, 24672, 24680,     0, 
+    16384, 24576, 24704, 24672, 24680,     0, 16384, 24576, 
+    24704, 24672, 24680, 24682,     0, 16384, 24576, 24704, 
+    24672, 24680,     0, 16384, 24576, 24704, 24672, 24688, 
+    24684,     0, 16384, 24576, 24704, 24672, 24688, 24684, 
+        0, 16384, 24576, 24704, 24672, 24688, 24689, 24686, 
+        0, 16384, 24576, 24704, 24672,     0, 16384, 24576, 
+    24704, 24705, 24688,     0, 16384, 24576, 24704, 24705, 
+    24688,     0, 16384, 24576, 24704, 24705, 24688, 24690, 
+        0, 16384, 24576, 24704, 24705, 24688,     0, 16384, 
+    24576, 24704, 24705, 24688, 24692,     0, 16384, 24576, 
+    24704, 24705, 24688, 24692,     0, 16384, 24576, 24704, 
+    24705, 24688, 24696, 24694,     0, 16384, 24576, 24704, 
+    24705, 24688,     0, 16384, 24576, 24704, 24705, 24688, 
+    24696,     0, 16384, 24576, 24704, 24705, 24707, 24696, 
+        0, 16384, 24576, 24704, 24705, 24707, 24696, 24698, 
+        0, 16384, 24576, 24704, 24705, 24707, 24696,     0, 
+    16384, 24576, 24704, 24705, 24707, 24696, 24700,     0, 
+    16384, 24576, 24704, 24705, 24707, 24696, 24700,     0, 
+    16384, 24576, 24704, 24705, 24707, 24696, 24700, 24702, 
+        0, 16384, 24576,     0, 16384, 24576, 24704,     0, 
+    16384, 24576, 24704,     0, 16384, 24576, 24704, 24706, 
+        0, 16384, 24576, 24704,     0, 16384, 24576, 24704, 
+    24708,     0, 16384, 24576, 24704, 24708,     0, 16384, 
+    24576, 24704, 24712, 24710,     0, 16384, 24576, 24704, 
+        0, 16384, 24576, 24704, 24712,     0, 16384, 24576, 
+    24704, 24712,     0, 16384, 24576, 24704, 24712, 24714, 
+        0, 16384, 24576, 24704, 24712,     0, 16384, 24576, 
+    24704, 24720, 24716,     0, 16384, 24576, 24704, 24720, 
+    24716,     0, 16384, 24576, 24704, 24720, 24721, 24718, 
+        0, 16384, 24576, 24704,     0, 16384, 24576, 24704, 
+    24720,     0, 16384, 24576, 24704, 24720,     0, 16384, 
+    24576, 24704, 24720, 24722,     0, 16384, 24576, 24704, 
+    24720,     0, 16384, 24576, 24704, 24720, 24724,     0, 
+    16384, 24576, 24704, 24720, 24724,     0, 16384, 24576, 
+    24704, 24720, 24728, 24726,     0, 16384, 24576, 24704, 
+    24720,     0, 16384, 24576, 24704, 24736, 24728,     0, 
+    16384, 24576, 24704, 24736, 24728,     0, 16384, 24576, 
+    24704, 24736, 24728, 24730,     0, 16384, 24576, 24704, 
+    24736, 24728,     0, 16384, 24576, 24704, 24736, 24737, 
+    24732,     0, 16384, 24576, 24704, 24736, 24737, 24732, 
+        0, 16384, 24576, 24704, 24736, 24737, 24732, 24734, 
+        0, 16384, 24576, 24704,     0, 16384, 24576, 24704, 
+    24736,     0, 16384, 24576, 24704, 24736,     0, 16384, 
+    24576, 24704, 24736, 24738,     0, 16384, 24576, 24704, 
+    24736,     0, 16384, 24576, 24704, 24736, 24740,     0, 
+    16384, 24576, 24704, 24736, 24740,     0, 16384, 24576, 
+    24704, 24736, 24744, 24742,     0, 16384, 24576, 24704, 
+    24736,     0, 16384, 24576, 24704, 24736, 24744,     0, 
+    16384, 24576, 24704, 24736, 24744,     0, 16384, 24576, 
+    24704, 24736, 24744, 24746,     0, 16384, 24576, 24704, 
+    24736, 24744,     0, 16384, 24576, 24704, 24736, 24752, 
+    24748,     0, 16384, 24576, 24704, 24736, 24752, 24748, 
+        0, 16384, 24576, 24704, 24736, 24752, 24753, 24750, 
+        0, 16384, 24576, 24704, 24736,     0, 16384, 24576, 
+    24704, 24768, 24752,     0, 16384, 24576, 24704, 24768, 
+    24752,     0, 16384, 24576, 24704, 24768, 24752, 24754, 
+        0, 16384, 24576, 24704, 24768, 24752,     0, 16384, 
+    24576, 24704, 24768, 24752, 24756,     0, 16384, 24576, 
+    24704, 24768, 24752, 24756,     0, 16384, 24576, 24704, 
+    24768, 24752, 24760, 24758,     0, 16384, 24576, 24704, 
+    24768, 24752,     0, 16384, 24576, 24704, 24768, 24769, 
+    24760,     0, 16384, 24576, 24704, 24768, 24769, 24760, 
+        0, 16384, 24576, 24704, 24768, 24769, 24760, 24762, 
+        0, 16384, 24576, 24704, 24768, 24769, 24760,     0, 
+    16384, 24576, 24704, 24768, 24769, 24760, 24764,     0, 
+    16384, 24576, 24704, 24768, 24769, 24771, 24764,     0, 
+    16384, 24576, 24704, 24768, 24769, 24771, 24764, 24766, 
+        0, 16384, 24576, 24704,     0, 16384, 24576, 24832, 
+    24768,     0, 16384, 24576, 24832, 24768,     0, 16384, 
+    24576, 24832, 24768, 24770,     0, 16384, 24576, 24832, 
+    24768,     0, 16384, 24576, 24832, 24768, 24772,     0, 
+    16384, 24576, 24832, 24768, 24772,     0, 16384, 24576, 
+    24832, 24768, 24776, 24774,     0, 16384, 24576, 24832, 
+    24768,     0, 16384, 24576, 24832, 24768, 24776,     0, 
+    16384, 24576, 24832, 24768, 24776,     0, 16384, 24576, 
+    24832, 24768, 24776, 24778,     0, 16384, 24576, 24832, 
+    24768, 24776,     0, 16384, 24576, 24832, 24768, 24784, 
+    24780,     0, 16384, 24576, 24832, 24768, 24784, 24780, 
+        0, 16384, 24576, 24832, 24768, 24784, 24785, 24782, 
+        0, 16384, 24576, 24832, 24768,     0, 16384, 24576, 
+    24832, 24768, 24784,     0, 16384, 24576, 24832, 24768, 
+    24784,     0, 16384, 24576, 24832, 24768, 24784, 24786, 
+        0, 16384, 24576, 24832, 24768, 24784,     0, 16384, 
+    24576, 24832, 24768, 24784, 24788,     0, 16384, 24576, 
+    24832, 24768, 24784, 24788,     0, 16384, 24576, 24832, 
+    24768, 24784, 24792, 24790,     0, 16384, 24576, 24832, 
+    24768, 24784,     0, 16384, 24576, 24832, 24768, 24800, 
+    24792,     0, 16384, 24576, 24832, 24768, 24800, 24792, 
+        0, 16384, 24576, 24832, 24768, 24800, 24792, 24794, 
+        0, 16384, 24576, 24832, 24768, 24800, 24792,     0, 
+    16384, 24576, 24832, 24768, 24800, 24801, 24796,     0, 
+    16384, 24576, 24832, 24768, 24800, 24801, 24796,     0, 
+    16384, 24576, 24832, 24768, 24800, 24801, 24796, 24798, 
+        0, 16384, 24576, 24832, 24768,     0, 16384, 24576, 
+    24832, 24833, 24800,     0, 16384, 24576, 24832, 24833, 
+    24800,     0, 16384, 24576, 24832, 24833, 24800, 24802, 
+        0, 16384, 24576, 24832, 24833, 24800,     0, 16384, 
+    24576, 24832, 24833, 24800, 24804,     0, 16384, 24576, 
+    24832, 24833, 24800, 24804,     0, 16384, 24576, 24832, 
+    24833, 24800, 24808, 24806,     0, 16384, 24576, 24832, 
+    24833, 24800,     0, 16384, 24576, 24832, 24833, 24800, 
+    24808,     0, 16384, 24576, 24832, 24833, 24800, 24808, 
+        0, 16384, 24576, 24832, 24833, 24800, 24808, 24810, 
+        0, 16384, 24576, 24832, 24833, 24800, 24808,     0, 
+    16384, 24576, 24832, 24833, 24800, 24816, 24812,     0, 
+    16384, 24576, 24832, 24833, 24800, 24816, 24812,     0, 
+    16384, 24576, 24832, 24833, 24800, 24816, 24817, 24814, 
+        0, 16384, 24576, 24832, 24833, 24800,     0, 16384, 
+    24576, 24832, 24833, 24800, 24816,     0, 16384, 24576, 
+    24832, 24833, 24835, 24816,     0, 16384, 24576, 24832, 
+    24833, 24835, 24816, 24818,     0, 16384, 24576, 24832, 
+    24833, 24835, 24816,     0, 16384, 24576, 24832, 24833, 
+    24835, 24816, 24820,     0, 16384, 24576, 24832, 24833, 
+    24835, 24816, 24820,     0, 16384, 24576, 24832, 24833, 
+    24835, 24816, 24824, 24822,     0, 16384, 24576, 24832, 
+    24833, 24835, 24816,     0, 16384, 24576, 24832, 24833, 
+    24835, 24816, 24824,     0, 16384, 24576, 24832, 24833, 
+    24835, 24816, 24824,     0, 16384, 24576, 24832, 24833, 
+    24835, 24816, 24824, 24826,     0, 16384, 24576, 24832, 
+    24833, 24835, 24839, 24824,     0, 16384, 24576, 24832, 
+    24833, 24835, 24839, 24824, 24828,     0, 16384, 24576, 
+    24832, 24833, 24835, 24839, 24824, 24828,     0, 16384, 
+    24576, 24832, 24833, 24835, 24839, 24824, 24828, 24830, 
+        0, 16384, 24576,     0, 16384, 24576, 24832,     0, 
+    16384, 24576, 24832,     0, 16384, 24576, 24832, 24834, 
+        0, 16384, 24576, 24832,     0, 16384, 24576, 24832, 
+    24836,     0, 16384, 24576, 24832, 24836,     0, 16384, 
+    24576, 24832, 24840, 24838,     0, 16384, 24576, 24832, 
+        0, 16384, 24576, 24832, 24840,     0, 16384, 24576, 
+    24832, 24840,     0, 16384, 24576, 24832, 24840, 24842, 
+        0, 16384, 24576, 24832, 24840,     0, 16384, 24576, 
+    24832, 24848, 24844,     0, 16384, 24576, 24832, 24848, 
+    24844,     0, 16384, 24576, 24832, 24848, 24849, 24846, 
+        0, 16384, 24576, 24832,     0, 16384, 24576, 24832, 
+    24848,     0, 16384, 24576, 24832, 24848,     0, 16384, 
+    24576, 24832, 24848, 24850,     0, 16384, 24576, 24832, 
+    24848,     0, 16384, 24576, 24832, 24848, 24852,     0, 
+    16384, 24576, 24832, 24848, 24852,     0, 16384, 24576, 
+    24832, 24848, 24856, 24854,     0, 16384, 24576, 24832, 
+    24848,     0, 16384, 24576, 24832, 24864, 24856,     0, 
+    16384, 24576, 24832, 24864, 24856,     0, 16384, 24576, 
+    24832, 24864, 24856, 24858,     0, 16384, 24576, 24832, 
+    24864, 24856,     0, 16384, 24576, 24832, 24864, 24865, 
+    24860,     0, 16384, 24576, 24832, 24864, 24865, 24860, 
+        0, 16384, 24576, 24832, 24864, 24865, 24860, 24862, 
+        0, 16384, 24576, 24832,     0, 16384, 24576, 24832, 
+    24864,     0, 16384, 24576, 24832, 24864,     0, 16384, 
+    24576, 24832, 24864, 24866,     0, 16384, 24576, 24832, 
+    24864,     0, 16384, 24576, 24832, 24864, 24868,     0, 
+    16384, 24576, 24832, 24864, 24868,     0, 16384, 24576, 
+    24832, 24864, 24872, 24870,     0, 16384, 24576, 24832, 
+    24864,     0, 16384, 24576, 24832, 24864, 24872,     0, 
+    16384, 24576, 24832, 24864, 24872,     0, 16384, 24576, 
+    24832, 24864, 24872, 24874,     0, 16384, 24576, 24832, 
+    24864, 24872,     0, 16384, 24576, 24832, 24864, 24880, 
+    24876,     0, 16384, 24576, 24832, 24864, 24880, 24876, 
+        0, 16384, 24576, 24832, 24864, 24880, 24881, 24878, 
+        0, 16384, 24576, 24832, 24864,     0, 16384, 24576, 
+    24832, 24896, 24880,     0, 16384, 24576, 24832, 24896, 
+    24880,     0, 16384, 24576, 24832, 24896, 24880, 24882, 
+        0, 16384, 24576, 24832, 24896, 24880,     0, 16384, 
+    24576, 24832, 24896, 24880, 24884,     0, 16384, 24576, 
+    24832, 24896, 24880, 24884,     0, 16384, 24576, 24832, 
+    24896, 24880, 24888, 24886,     0, 16384, 24576, 24832, 
+    24896, 24880,     0, 16384, 24576, 24832, 24896, 24897, 
+    24888,     0, 16384, 24576, 24832, 24896, 24897, 24888, 
+        0, 16384, 24576, 24832, 24896, 24897, 24888, 24890, 
+        0, 16384, 24576, 24832, 24896, 24897, 24888,     0, 
+    16384, 24576, 24832, 24896, 24897, 24888, 24892,     0, 
+    16384, 24576, 24832, 24896, 24897, 24899, 24892,     0, 
+    16384, 24576, 24832, 24896, 24897, 24899, 24892, 24894, 
+        0, 16384, 24576, 24832,     0, 16384, 24576, 24832, 
+    24896,     0, 16384, 24576, 24832, 24896,     0, 16384, 
+    24576, 24832, 24896, 24898,     0, 16384, 24576, 24832, 
+    24896,     0, 16384, 24576, 24832, 24896, 24900,     0, 
+    16384, 24576, 24832, 24896, 24900,     0, 16384, 24576, 
+    24832, 24896, 24904, 24902,     0, 16384, 24576, 24832, 
+    24896,     0, 16384, 24576, 24832, 24896, 24904,     0, 
+    16384, 24576, 24832, 24896, 24904,     0, 16384, 24576, 
+    24832, 24896, 24904, 24906,     0, 16384, 24576, 24832, 
+    24896, 24904,     0, 16384, 24576, 24832, 24896, 24912, 
+    24908,     0, 16384, 24576, 24832, 24896, 24912, 24908, 
+        0, 16384, 24576, 24832, 24896, 24912, 24913, 24910, 
+        0, 16384, 24576, 24832, 24896,     0, 16384, 24576, 
+    24832, 24896, 24912,     0, 16384, 24576, 24832, 24896, 
+    24912,     0, 16384, 24576, 24832, 24896, 24912, 24914, 
+        0, 16384, 24576, 24832, 24896, 24912,     0, 16384, 
+    24576, 24832, 24896, 24912, 24916,     0, 16384, 24576, 
+    24832, 24896, 24912, 24916,     0, 16384, 24576, 24832, 
+    24896, 24912, 24920, 24918,     0, 16384, 24576, 24832, 
+    24896, 24912,     0, 16384, 24576, 24832, 24896, 24928, 
+    24920,     0, 16384, 24576, 24832, 24896, 24928, 24920, 
+        0, 16384, 24576, 24832, 24896, 24928, 24920, 24922, 
+        0, 16384, 24576, 24832, 24896, 24928, 24920,     0, 
+    16384, 24576, 24832, 24896, 24928, 24929, 24924,     0, 
+    16384, 24576, 24832, 24896, 24928, 24929, 24924,     0, 
+    16384, 24576, 24832, 24896, 24928, 24929, 24924, 24926, 
+        0, 16384, 24576, 24832, 24896,     0, 16384, 24576, 
+    24832, 24960, 24928,     0, 16384, 24576, 24832, 24960, 
+    24928,     0, 16384, 24576, 24832, 24960, 24928, 24930, 
+        0, 16384, 24576, 24832, 24960, 24928,     0, 16384, 
+    24576, 24832, 24960, 24928, 24932,     0, 16384, 24576, 
+    24832, 24960, 24928, 24932,     0, 16384, 24576, 24832, 
+    24960, 24928, 24936, 24934,     0, 16384, 24576, 24832, 
+    24960, 24928,     0, 16384, 24576, 24832, 24960, 24928, 
+    24936,     0, 16384, 24576, 24832, 24960, 24928, 24936, 
+        0, 16384, 24576, 24832, 24960, 24928, 24936, 24938, 
+        0, 16384, 24576, 24832, 24960, 24928, 24936,     0, 
+    16384, 24576, 24832, 24960, 24928, 24944, 24940,     0, 
+    16384, 24576, 24832, 24960, 24928, 24944, 24940,     0, 
+    16384, 24576, 24832, 24960, 24928, 24944, 24945, 24942, 
+        0, 16384, 24576, 24832, 24960, 24928,     0, 16384, 
+    24576, 24832, 24960, 24961, 24944,     0, 16384, 24576, 
+    24832, 24960, 24961, 24944,     0, 16384, 24576, 24832, 
+    24960, 24961, 24944, 24946,     0, 16384, 24576, 24832, 
+    24960, 24961, 24944,     0, 16384, 24576, 24832, 24960, 
+    24961, 24944, 24948,     0, 16384, 24576, 24832, 24960, 
+    24961, 24944, 24948,     0, 16384, 24576, 24832, 24960, 
+    24961, 24944, 24952, 24950,     0, 16384, 24576, 24832, 
+    24960, 24961, 24944,     0, 16384, 24576, 24832, 24960, 
+    24961, 24944, 24952,     0, 16384, 24576, 24832, 24960, 
+    24961, 24963, 24952,     0, 16384, 24576, 24832, 24960, 
+    24961, 24963, 24952, 24954,     0, 16384, 24576, 24832, 
+    24960, 24961, 24963, 24952,     0, 16384, 24576, 24832, 
+    24960, 24961, 24963, 24952, 24956,     0, 16384, 24576, 
+    24832, 24960, 24961, 24963, 24952, 24956,     0, 16384, 
+    24576, 24832, 24960, 24961, 24963, 24952, 24956, 24958, 
+        0, 16384, 24576, 24832,     0, 16384, 24576, 25088, 
+    24960,     0, 16384, 24576, 25088, 24960,     0, 16384, 
+    24576, 25088, 24960, 24962,     0, 16384, 24576, 25088, 
+    24960,     0, 16384, 24576, 25088, 24960, 24964,     0, 
+    16384, 24576, 25088, 24960, 24964,     0, 16384, 24576, 
+    25088, 24960, 24968, 24966,     0, 16384, 24576, 25088, 
+    24960,     0, 16384, 24576, 25088, 24960, 24968,     0, 
+    16384, 24576, 25088, 24960, 24968,     0, 16384, 24576, 
+    25088, 24960, 24968, 24970,     0, 16384, 24576, 25088, 
+    24960, 24968,     0, 16384, 24576, 25088, 24960, 24976, 
+    24972,     0, 16384, 24576, 25088, 24960, 24976, 24972, 
+        0, 16384, 24576, 25088, 24960, 24976, 24977, 24974, 
+        0, 16384, 24576, 25088, 24960,     0, 16384, 24576, 
+    25088, 24960, 24976,     0, 16384, 24576, 25088, 24960, 
+    24976,     0, 16384, 24576, 25088, 24960, 24976, 24978, 
+        0, 16384, 24576, 25088, 24960, 24976,     0, 16384, 
+    24576, 25088, 24960, 24976, 24980,     0, 16384, 24576, 
+    25088, 24960, 24976, 24980,     0, 16384, 24576, 25088, 
+    24960, 24976, 24984, 24982,     0, 16384, 24576, 25088, 
+    24960, 24976,     0, 16384, 24576, 25088, 24960, 24992, 
+    24984,     0, 16384, 24576, 25088, 24960, 24992, 24984, 
+        0, 16384, 24576, 25088, 24960, 24992, 24984, 24986, 
+        0, 16384, 24576, 25088, 24960, 24992, 24984,     0, 
+    16384, 24576, 25088, 24960, 24992, 24993, 24988,     0, 
+    16384, 24576, 25088, 24960, 24992, 24993, 24988,     0, 
+    16384, 24576, 25088, 24960, 24992, 24993, 24988, 24990, 
+        0, 16384, 24576, 25088, 24960,     0, 16384, 24576, 
+    25088, 24960, 24992,     0, 16384, 24576, 25088, 24960, 
+    24992,     0, 16384, 24576, 25088, 24960, 24992, 24994, 
+        0, 16384, 24576, 25088, 24960, 24992,     0, 16384, 
+    24576, 25088, 24960, 24992, 24996,     0, 16384, 24576, 
+    25088, 24960, 24992, 24996,     0, 16384, 24576, 25088, 
+    24960, 24992, 25000, 24998,     0, 16384, 24576, 25088, 
+    24960, 24992,     0, 16384, 24576, 25088, 24960, 24992, 
+    25000,     0, 16384, 24576, 25088, 24960, 24992, 25000, 
+        0, 16384, 24576, 25088, 24960, 24992, 25000, 25002, 
+        0, 16384, 24576, 25088, 24960, 24992, 25000,     0, 
+    16384, 24576, 25088, 24960, 24992, 25008, 25004,     0, 
+    16384, 24576, 25088, 24960, 24992, 25008, 25004,     0, 
+    16384, 24576, 25088, 24960, 24992, 25008, 25009, 25006, 
+        0, 16384, 24576, 25088, 24960, 24992,     0, 16384, 
+    24576, 25088, 24960, 25024, 25008,     0, 16384, 24576, 
+    25088, 24960, 25024, 25008,     0, 16384, 24576, 25088, 
+    24960, 25024, 25008, 25010,     0, 16384, 24576, 25088, 
+    24960, 25024, 25008,     0, 16384, 24576, 25088, 24960, 
+    25024, 25008, 25012,     0, 16384, 24576, 25088, 24960, 
+    25024, 25008, 25012,     0, 16384, 24576, 25088, 24960, 
+    25024, 25008, 25016, 25014,     0, 16384, 24576, 25088, 
+    24960, 25024, 25008,     0, 16384, 24576, 25088, 24960, 
+    25024, 25025, 25016,     0, 16384, 24576, 25088, 24960, 
+    25024, 25025, 25016,     0, 16384, 24576, 25088, 24960, 
+    25024, 25025, 25016, 25018,     0, 16384, 24576, 25088, 
+    24960, 25024, 25025, 25016,     0, 16384, 24576, 25088, 
+    24960, 25024, 25025, 25016, 25020,     0, 16384, 24576, 
+    25088, 24960, 25024, 25025, 25027, 25020,     0, 16384, 
+    24576, 25088, 24960, 25024, 25025, 25027, 25020, 25022, 
+        0, 16384, 24576, 25088, 24960,     0, 16384, 24576, 
+    25088, 25089, 25024,     0, 16384, 24576, 25088, 25089, 
+    25024,     0, 16384, 24576, 25088, 25089, 25024, 25026, 
+        0, 16384, 24576, 25088, 25089, 25024,     0, 16384, 
+    24576, 25088, 25089, 25024, 25028,     0, 16384, 24576, 
+    25088, 25089, 25024, 25028,     0, 16384, 24576, 25088, 
+    25089, 25024, 25032, 25030,     0, 16384, 24576, 25088, 
+    25089, 25024,     0, 16384, 24576, 25088, 25089, 25024, 
+    25032,     0, 16384, 24576, 25088, 25089, 25024, 25032, 
+        0, 16384, 24576, 25088, 25089, 25024, 25032, 25034, 
+        0, 16384, 24576, 25088, 25089, 25024, 25032,     0, 
+    16384, 24576, 25088, 25089, 25024, 25040, 25036,     0, 
+    16384, 24576, 25088, 25089, 25024, 25040, 25036,     0, 
+    16384, 24576, 25088, 25089, 25024, 25040, 25041, 25038, 
+        0, 16384, 24576, 25088, 25089, 25024,     0, 16384, 
+    24576, 25088, 25089, 25024, 25040,     0, 16384, 24576, 
+    25088, 25089, 25024, 25040,     0, 16384, 24576, 25088, 
+    25089, 25024, 25040, 25042,     0, 16384, 24576, 25088, 
+    25089, 25024, 25040,     0, 16384, 24576, 25088, 25089, 
+    25024, 25040, 25044,     0, 16384, 24576, 25088, 25089, 
+    25024, 25040, 25044,     0, 16384, 24576, 25088, 25089, 
+    25024, 25040, 25048, 25046,     0, 16384, 24576, 25088, 
+    25089, 25024, 25040,     0, 16384, 24576, 25088, 25089, 
+    25024, 25056, 25048,     0, 16384, 24576, 25088, 25089, 
+    25024, 25056, 25048,     0, 16384, 24576, 25088, 25089, 
+    25024, 25056, 25048, 25050,     0, 16384, 24576, 25088, 
+    25089, 25024, 25056, 25048,     0, 16384, 24576, 25088, 
+    25089, 25024, 25056, 25057, 25052,     0, 16384, 24576, 
+    25088, 25089, 25024, 25056, 25057, 25052,     0, 16384, 
+    24576, 25088, 25089, 25024, 25056, 25057, 25052, 25054, 
+        0, 16384, 24576, 25088, 25089, 25024,     0, 16384, 
+    24576, 25088, 25089, 25024, 25056,     0, 16384, 24576, 
+    25088, 25089, 25091, 25056,     0, 16384, 24576, 25088, 
+    25089, 25091, 25056, 25058,     0, 16384, 24576, 25088, 
+    25089, 25091, 25056,     0, 16384, 24576, 25088, 25089, 
+    25091, 25056, 25060,     0, 16384, 24576, 25088, 25089, 
+    25091, 25056, 25060,     0, 16384, 24576, 25088, 25089, 
+    25091, 25056, 25064, 25062,     0, 16384, 24576, 25088, 
+    25089, 25091, 25056,     0, 16384, 24576, 25088, 25089, 
+    25091, 25056, 25064,     0, 16384, 24576, 25088, 25089, 
+    25091, 25056, 25064,     0, 16384, 24576, 25088, 25089, 
+    25091, 25056, 25064, 25066,     0, 16384, 24576, 25088, 
+    25089, 25091, 25056, 25064,     0, 16384, 24576, 25088, 
+    25089, 25091, 25056, 25072, 25068,     0, 16384, 24576, 
+    25088, 25089, 25091, 25056, 25072, 25068,     0, 16384, 
+    24576, 25088, 25089, 25091, 25056, 25072, 25073, 25070, 
+        0, 16384, 24576, 25088, 25089, 25091, 25056,     0, 
+    16384, 24576, 25088, 25089, 25091, 25056, 25072,     0, 
+    16384, 24576, 25088, 25089, 25091, 25056, 25072,     0, 
+    16384, 24576, 25088, 25089, 25091, 25056, 25072, 25074, 
+        0, 16384, 24576, 25088, 25089, 25091, 25095, 25072, 
+        0, 16384, 24576, 25088, 25089, 25091, 25095, 25072, 
+    25076,     0, 16384, 24576, 25088, 25089, 25091, 25095, 
+    25072, 25076,     0, 16384, 24576, 25088, 25089, 25091, 
+    25095, 25072, 25080, 25078,     0, 16384, 24576, 25088, 
+    25089, 25091, 25095, 25072,     0, 16384, 24576, 25088, 
+    25089, 25091, 25095, 25072, 25080,     0, 16384, 24576, 
+    25088, 25089, 25091, 25095, 25072, 25080,     0, 16384, 
+    24576, 25088, 25089, 25091, 25095, 25072, 25080, 25082, 
+        0, 16384, 24576, 25088, 25089, 25091, 25095, 25072, 
+    25080,     0, 16384, 24576, 25088, 25089, 25091, 25095, 
+    25072, 25080, 25084,     0, 16384, 24576, 25088, 25089, 
+    25091, 25095, 25072, 25080, 25084,     0, 16384, 24576, 
+    25088, 25089, 25091, 25095, 25072, 25080, 25084, 25086, 
+        0, 16384, 24576,     0, 16384, 24576, 25088,     0, 
+    16384, 24576, 25088,     0, 16384, 24576, 25088, 25090, 
+        0, 16384, 24576, 25088,     0, 16384, 24576, 25088, 
+    25092,     0, 16384, 24576, 25088, 25092,     0, 16384, 
+    24576, 25088, 25096, 25094,     0, 16384, 24576, 25088, 
+        0, 16384, 24576, 25088, 25096,     0, 16384, 24576, 
+    25088, 25096,     0, 16384, 24576, 25088, 25096, 25098, 
+        0, 16384, 24576, 25088, 25096,     0, 16384, 24576, 
+    25088, 25104, 25100,     0, 16384, 24576, 25088, 25104, 
+    25100,     0, 16384, 24576, 25088, 25104, 25105, 25102, 
+        0, 16384, 24576, 25088,     0, 16384, 24576, 25088, 
+    25104,     0, 16384, 24576, 25088, 25104,     0, 16384, 
+    24576, 25088, 25104, 25106,     0, 16384, 24576, 25088, 
+    25104,     0, 16384, 24576, 25088, 25104, 25108,     0, 
+    16384, 24576, 25088, 25104, 25108,     0, 16384, 24576, 
+    25088, 25104, 25112, 25110,     0, 16384, 24576, 25088, 
+    25104,     0, 16384, 24576, 25088, 25120, 25112,     0, 
+    16384, 24576, 25088, 25120, 25112,     0, 16384, 24576, 
+    25088, 25120, 25112, 25114,     0, 16384, 24576, 25088, 
+    25120, 25112,     0, 16384, 24576, 25088, 25120, 25121, 
+    25116,     0, 16384, 24576, 25088, 25120, 25121, 25116, 
+        0, 16384, 24576, 25088, 25120, 25121, 25116, 25118, 
+        0, 16384, 24576, 25088,     0, 16384, 24576, 25088, 
+    25120,     0, 16384, 24576, 25088, 25120,     0, 16384, 
+    24576, 25088, 25120, 25122,     0, 16384, 24576, 25088, 
+    25120,     0, 16384, 24576, 25088, 25120, 25124,     0, 
+    16384, 24576, 25088, 25120, 25124,     0, 16384, 24576, 
+    25088, 25120, 25128, 25126,     0, 16384, 24576, 25088, 
+    25120,     0, 16384, 24576, 25088, 25120, 25128,     0, 
+    16384, 24576, 25088, 25120, 25128,     0, 16384, 24576, 
+    25088, 25120, 25128, 25130,     0, 16384, 24576, 25088, 
+    25120, 25128,     0, 16384, 24576, 25088, 25120, 25136, 
+    25132,     0, 16384, 24576, 25088, 25120, 25136, 25132, 
+        0, 16384, 24576, 25088, 25120, 25136, 25137, 25134, 
+        0, 16384, 24576, 25088, 25120,     0, 16384, 24576, 
+    25088, 25152, 25136,     0, 16384, 24576, 25088, 25152, 
+    25136,     0, 16384, 24576, 25088, 25152, 25136, 25138, 
+        0, 16384, 24576, 25088, 25152, 25136,     0, 16384, 
+    24576, 25088, 25152, 25136, 25140,     0, 16384, 24576, 
+    25088, 25152, 25136, 25140,     0, 16384, 24576, 25088, 
+    25152, 25136, 25144, 25142,     0, 16384, 24576, 25088, 
+    25152, 25136,     0, 16384, 24576, 25088, 25152, 25153, 
+    25144,     0, 16384, 24576, 25088, 25152, 25153, 25144, 
+        0, 16384, 24576, 25088, 25152, 25153, 25144, 25146, 
+        0, 16384, 24576, 25088, 25152, 25153, 25144,     0, 
+    16384, 24576, 25088, 25152, 25153, 25144, 25148,     0, 
+    16384, 24576, 25088, 25152, 25153, 25155, 25148,     0, 
+    16384, 24576, 25088, 25152, 25153, 25155, 25148, 25150, 
+        0, 16384, 24576, 25088,     0, 16384, 24576, 25088, 
+    25152,     0, 16384, 24576, 25088, 25152,     0, 16384, 
+    24576, 25088, 25152, 25154,     0, 16384, 24576, 25088, 
+    25152,     0, 16384, 24576, 25088, 25152, 25156,     0, 
+    16384, 24576, 25088, 25152, 25156,     0, 16384, 24576, 
+    25088, 25152, 25160, 25158,     0, 16384, 24576, 25088, 
+    25152,     0, 16384, 24576, 25088, 25152, 25160,     0, 
+    16384, 24576, 25088, 25152, 25160,     0, 16384, 24576, 
+    25088, 25152, 25160, 25162,     0, 16384, 24576, 25088, 
+    25152, 25160,     0, 16384, 24576, 25088, 25152, 25168, 
+    25164,     0, 16384, 24576, 25088, 25152, 25168, 25164, 
+        0, 16384, 24576, 25088, 25152, 25168, 25169, 25166, 
+        0, 16384, 24576, 25088, 25152,     0, 16384, 24576, 
+    25088, 25152, 25168,     0, 16384, 24576, 25088, 25152, 
+    25168,     0, 16384, 24576, 25088, 25152, 25168, 25170, 
+        0, 16384, 24576, 25088, 25152, 25168,     0, 16384, 
+    24576, 25088, 25152, 25168, 25172,     0, 16384, 24576, 
+    25088, 25152, 25168, 25172,     0, 16384, 24576, 25088, 
+    25152, 25168, 25176, 25174,     0, 16384, 24576, 25088, 
+    25152, 25168,     0, 16384, 24576, 25088, 25152, 25184, 
+    25176,     0, 16384, 24576, 25088, 25152, 25184, 25176, 
+        0, 16384, 24576, 25088, 25152, 25184, 25176, 25178, 
+        0, 16384, 24576, 25088, 25152, 25184, 25176,     0, 
+    16384, 24576, 25088, 25152, 25184, 25185, 25180,     0, 
+    16384, 24576, 25088, 25152, 25184, 25185, 25180,     0, 
+    16384, 24576, 25088, 25152, 25184, 25185, 25180, 25182, 
+        0, 16384, 24576, 25088, 25152,     0, 16384, 24576, 
+    25088, 25216, 25184,     0, 16384, 24576, 25088, 25216, 
+    25184,     0, 16384, 24576, 25088, 25216, 25184, 25186, 
+        0, 16384, 24576, 25088, 25216, 25184,     0, 16384, 
+    24576, 25088, 25216, 25184, 25188,     0, 16384, 24576, 
+    25088, 25216, 25184, 25188,     0, 16384, 24576, 25088, 
+    25216, 25184, 25192, 25190,     0, 16384, 24576, 25088, 
+    25216, 25184,     0, 16384, 24576, 25088, 25216, 25184, 
+    25192,     0, 16384, 24576, 25088, 25216, 25184, 25192, 
+        0, 16384, 24576, 25088, 25216, 25184, 25192, 25194, 
+        0, 16384, 24576, 25088, 25216, 25184, 25192,     0, 
+    16384, 24576, 25088, 25216, 25184, 25200, 25196,     0, 
+    16384, 24576, 25088, 25216, 25184, 25200, 25196,     0, 
+    16384, 24576, 25088, 25216, 25184, 25200, 25201, 25198, 
+        0, 16384, 24576, 25088, 25216, 25184,     0, 16384, 
+    24576, 25088, 25216, 25217, 25200,     0, 16384, 24576, 
+    25088, 25216, 25217, 25200,     0, 16384, 24576, 25088, 
+    25216, 25217, 25200, 25202,     0, 16384, 24576, 25088, 
+    25216, 25217, 25200,     0, 16384, 24576, 25088, 25216, 
+    25217, 25200, 25204,     0, 16384, 24576, 25088, 25216, 
+    25217, 25200, 25204,     0, 16384, 24576, 25088, 25216, 
+    25217, 25200, 25208, 25206,     0, 16384, 24576, 25088, 
+    25216, 25217, 25200,     0, 16384, 24576, 25088, 25216, 
+    25217, 25200, 25208,     0, 16384, 24576, 25088, 25216, 
+    25217, 25219, 25208,     0, 16384, 24576, 25088, 25216, 
+    25217, 25219, 25208, 25210,     0, 16384, 24576, 25088, 
+    25216, 25217, 25219, 25208,     0, 16384, 24576, 25088, 
+    25216, 25217, 25219, 25208, 25212,     0, 16384, 24576, 
+    25088, 25216, 25217, 25219, 25208, 25212,     0, 16384, 
+    24576, 25088, 25216, 25217, 25219, 25208, 25212, 25214, 
+        0, 16384, 24576, 25088,     0, 16384, 24576, 25088, 
+    25216,     0, 16384, 24576, 25088, 25216,     0, 16384, 
+    24576, 25088, 25216, 25218,     0, 16384, 24576, 25088, 
+    25216,     0, 16384, 24576, 25088, 25216, 25220,     0, 
+    16384, 24576, 25088, 25216, 25220,     0, 16384, 24576, 
+    25088, 25216, 25224, 25222,     0, 16384, 24576, 25088, 
+    25216,     0, 16384, 24576, 25088, 25216, 25224,     0, 
+    16384, 24576, 25088, 25216, 25224,     0, 16384, 24576, 
+    25088, 25216, 25224, 25226,     0, 16384, 24576, 25088, 
+    25216, 25224,     0, 16384, 24576, 25088, 25216, 25232, 
+    25228,     0, 16384, 24576, 25088, 25216, 25232, 25228, 
+        0, 16384, 24576, 25088, 25216, 25232, 25233, 25230, 
+        0, 16384, 24576, 25088, 25216,     0, 16384, 24576, 
+    25088, 25216, 25232,     0, 16384, 24576, 25088, 25216, 
+    25232,     0, 16384, 24576, 25088, 25216, 25232, 25234, 
+        0, 16384, 24576, 25088, 25216, 25232,     0, 16384, 
+    24576, 25088, 25216, 25232, 25236,     0, 16384, 24576, 
+    25088, 25216, 25232, 25236,     0, 16384, 24576, 25088, 
+    25216, 25232, 25240, 25238,     0, 16384, 24576, 25088, 
+    25216, 25232,     0, 16384, 24576, 25088, 25216, 25248, 
+    25240,     0, 16384, 24576, 25088, 25216, 25248, 25240, 
+        0, 16384, 24576, 25088, 25216, 25248, 25240, 25242, 
+        0, 16384, 24576, 25088, 25216, 25248, 25240,     0, 
+    16384, 24576, 25088, 25216, 25248, 25249, 25244,     0, 
+    16384, 24576, 25088, 25216, 25248, 25249, 25244,     0, 
+    16384, 24576, 25088, 25216, 25248, 25249, 25244, 25246, 
+        0, 16384, 24576, 25088, 25216,     0, 16384, 24576, 
+    25088, 25216, 25248,     0, 16384, 24576, 25088, 25216, 
+    25248,     0, 16384, 24576, 25088, 25216, 25248, 25250, 
+        0, 16384, 24576, 25088, 25216, 25248,     0, 16384, 
+    24576, 25088, 25216, 25248, 25252,     0, 16384, 24576, 
+    25088, 25216, 25248, 25252,     0, 16384, 24576, 25088, 
+    25216, 25248, 25256, 25254,     0, 16384, 24576, 25088, 
+    25216, 25248,     0, 16384, 24576, 25088, 25216, 25248, 
+    25256,     0, 16384, 24576, 25088, 25216, 25248, 25256, 
+        0, 16384, 24576, 25088, 25216, 25248, 25256, 25258, 
+        0, 16384, 24576, 25088, 25216, 25248, 25256,     0, 
+    16384, 24576, 25088, 25216, 25248, 25264, 25260,     0, 
+    16384, 24576, 25088, 25216, 25248, 25264, 25260,     0, 
+    16384, 24576, 25088, 25216, 25248, 25264, 25265, 25262, 
+        0, 16384, 24576, 25088, 25216, 25248,     0, 16384, 
+    24576, 25088, 25216, 25280, 25264,     0, 16384, 24576, 
+    25088, 25216, 25280, 25264,     0, 16384, 24576, 25088, 
+    25216, 25280, 25264, 25266,     0, 16384, 24576, 25088, 
+    25216, 25280, 25264,     0, 16384, 24576, 25088, 25216, 
+    25280, 25264, 25268,     0, 16384, 24576, 25088, 25216, 
+    25280, 25264, 25268,     0, 16384, 24576, 25088, 25216, 
+    25280, 25264, 25272, 25270,     0, 16384, 24576, 25088, 
+    25216, 25280, 25264,     0, 16384, 24576, 25088, 25216, 
+    25280, 25281, 25272,     0, 16384, 24576, 25088, 25216, 
+    25280, 25281, 25272,     0, 16384, 24576, 25088, 25216, 
+    25280, 25281, 25272, 25274,     0, 16384, 24576, 25088, 
+    25216, 25280, 25281, 25272,     0, 16384, 24576, 25088, 
+    25216, 25280, 25281, 25272, 25276,     0, 16384, 24576, 
+    25088, 25216, 25280, 25281, 25283, 25276,     0, 16384, 
+    24576, 25088, 25216, 25280, 25281, 25283, 25276, 25278, 
+        0, 16384, 24576, 25088, 25216,     0, 16384, 24576, 
+    25088, 25344, 25280,     0, 16384, 24576, 25088, 25344, 
+    25280,     0, 16384, 24576, 25088, 25344, 25280, 25282, 
+        0, 16384, 24576, 25088, 25344, 25280,     0, 16384, 
+    24576, 25088, 25344, 25280, 25284,     0, 16384, 24576, 
+    25088, 25344, 25280, 25284,     0, 16384, 24576, 25088, 
+    25344, 25280, 25288, 25286,     0, 16384, 24576, 25088, 
+    25344, 25280,     0, 16384, 24576, 25088, 25344, 25280, 
+    25288,     0, 16384, 24576, 25088, 25344, 25280, 25288, 
+        0, 16384, 24576, 25088, 25344, 25280, 25288, 25290, 
+        0, 16384, 24576, 25088, 25344, 25280, 25288,     0, 
+    16384, 24576, 25088, 25344, 25280, 25296, 25292,     0, 
+    16384, 24576, 25088, 25344, 25280, 25296, 25292,     0, 
+    16384, 24576, 25088, 25344, 25280, 25296, 25297, 25294, 
+        0, 16384, 24576, 25088, 25344, 25280,     0, 16384, 
+    24576, 25088, 25344, 25280, 25296,     0, 16384, 24576, 
+    25088, 25344, 25280, 25296,     0, 16384, 24576, 25088, 
+    25344, 25280, 25296, 25298,     0, 16384, 24576, 25088, 
+    25344, 25280, 25296,     0, 16384, 24576, 25088, 25344, 
+    25280, 25296, 25300,     0, 16384, 24576, 25088, 25344, 
+    25280, 25296, 25300,     0, 16384, 24576, 25088, 25344, 
+    25280, 25296, 25304, 25302,     0, 16384, 24576, 25088, 
+    25344, 25280, 25296,     0, 16384, 24576, 25088, 25344, 
+    25280, 25312, 25304,     0, 16384, 24576, 25088, 25344, 
+    25280, 25312, 25304,     0, 16384, 24576, 25088, 25344, 
+    25280, 25312, 25304, 25306,     0, 16384, 24576, 25088, 
+    25344, 25280, 25312, 25304,     0, 16384, 24576, 25088, 
+    25344, 25280, 25312, 25313, 25308,     0, 16384, 24576, 
+    25088, 25344, 25280, 25312, 25313, 25308,     0, 16384, 
+    24576, 25088, 25344, 25280, 25312, 25313, 25308, 25310, 
+        0, 16384, 24576, 25088, 25344, 25280,     0, 16384, 
+    24576, 25088, 25344, 25345, 25312,     0, 16384, 24576, 
+    25088, 25344, 25345, 25312,     0, 16384, 24576, 25088, 
+    25344, 25345, 25312, 25314,     0, 16384, 24576, 25088, 
+    25344, 25345, 25312,     0, 16384, 24576, 25088, 25344, 
+    25345, 25312, 25316,     0, 16384, 24576, 25088, 25344, 
+    25345, 25312, 25316,     0, 16384, 24576, 25088, 25344, 
+    25345, 25312, 25320, 25318,     0, 16384, 24576, 25088, 
+    25344, 25345, 25312,     0, 16384, 24576, 25088, 25344, 
+    25345, 25312, 25320,     0, 16384, 24576, 25088, 25344, 
+    25345, 25312, 25320,     0, 16384, 24576, 25088, 25344, 
+    25345, 25312, 25320, 25322,     0, 16384, 24576, 25088, 
+    25344, 25345, 25312, 25320,     0, 16384, 24576, 25088, 
+    25344, 25345, 25312, 25328, 25324,     0, 16384, 24576, 
+    25088, 25344, 25345, 25312, 25328, 25324,     0, 16384, 
+    24576, 25088, 25344, 25345, 25312, 25328, 25329, 25326, 
+        0, 16384, 24576, 25088, 25344, 25345, 25312,     0, 
+    16384, 24576, 25088, 25344, 25345, 25312, 25328,     0, 
+    16384, 24576, 25088, 25344, 25345, 25347, 25328,     0, 
+    16384, 24576, 25088, 25344, 25345, 25347, 25328, 25330, 
+        0, 16384, 24576, 25088, 25344, 25345, 25347, 25328, 
+        0, 16384, 24576, 25088, 25344, 25345, 25347, 25328, 
+    25332,     0, 16384, 24576, 25088, 25344, 25345, 25347, 
+    25328, 25332,     0, 16384, 24576, 25088, 25344, 25345, 
+    25347, 25328, 25336, 25334,     0, 16384, 24576, 25088, 
+    25344, 25345, 25347, 25328,     0, 16384, 24576, 25088, 
+    25344, 25345, 25347, 25328, 25336,     0, 16384, 24576, 
+    25088, 25344, 25345, 25347, 25328, 25336,     0, 16384, 
+    24576, 25088, 25344, 25345, 25347, 25328, 25336, 25338, 
+        0, 16384, 24576, 25088, 25344, 25345, 25347, 25351, 
+    25336,     0, 16384, 24576, 25088, 25344, 25345, 25347, 
+    25351, 25336, 25340,     0, 16384, 24576, 25088, 25344, 
+    25345, 25347, 25351, 25336, 25340,     0, 16384, 24576, 
+    25088, 25344, 25345, 25347, 25351, 25336, 25340, 25342, 
+        0, 16384, 24576, 25088,     0, 16384, 24576, 25600, 
+    25344,     0, 16384, 24576, 25600, 25344,     0, 16384, 
+    24576, 25600, 25344, 25346,     0, 16384, 24576, 25600, 
+    25344,     0, 16384, 24576, 25600, 25344, 25348,     0, 
+    16384, 24576, 25600, 25344, 25348,     0, 16384, 24576, 
+    25600, 25344, 25352, 25350,     0, 16384, 24576, 25600, 
+    25344,     0, 16384, 24576, 25600, 25344, 25352,     0, 
+    16384, 24576, 25600, 25344, 25352,     0, 16384, 24576, 
+    25600, 25344, 25352, 25354,     0, 16384, 24576, 25600, 
+    25344, 25352,     0, 16384, 24576, 25600, 25344, 25360, 
+    25356,     0, 16384, 24576, 25600, 25344, 25360, 25356, 
+        0, 16384, 24576, 25600, 25344, 25360, 25361, 25358, 
+        0, 16384, 24576, 25600, 25344,     0, 16384, 24576, 
+    25600, 25344, 25360,     0, 16384, 24576, 25600, 25344, 
+    25360,     0, 16384, 24576, 25600, 25344, 25360, 25362, 
+        0, 16384, 24576, 25600, 25344, 25360,     0, 16384, 
+    24576, 25600, 25344, 25360, 25364,     0, 16384, 24576, 
+    25600, 25344, 25360, 25364,     0, 16384, 24576, 25600, 
+    25344, 25360, 25368, 25366,     0, 16384, 24576, 25600, 
+    25344, 25360,     0, 16384, 24576, 25600, 25344, 25376, 
+    25368,     0, 16384, 24576, 25600, 25344, 25376, 25368, 
+        0, 16384, 24576, 25600, 25344, 25376, 25368, 25370, 
+        0, 16384, 24576, 25600, 25344, 25376, 25368,     0, 
+    16384, 24576, 25600, 25344, 25376, 25377, 25372,     0, 
+    16384, 24576, 25600, 25344, 25376, 25377, 25372,     0, 
+    16384, 24576, 25600, 25344, 25376, 25377, 25372, 25374, 
+        0, 16384, 24576, 25600, 25344,     0, 16384, 24576, 
+    25600, 25344, 25376,     0, 16384, 24576, 25600, 25344, 
+    25376,     0, 16384, 24576, 25600, 25344, 25376, 25378, 
+        0, 16384, 24576, 25600, 25344, 25376,     0, 16384, 
+    24576, 25600, 25344, 25376, 25380,     0, 16384, 24576, 
+    25600, 25344, 25376, 25380,     0, 16384, 24576, 25600, 
+    25344, 25376, 25384, 25382,     0, 16384, 24576, 25600, 
+    25344, 25376,     0, 16384, 24576, 25600, 25344, 25376, 
+    25384,     0, 16384, 24576, 25600, 25344, 25376, 25384, 
+        0, 16384, 24576, 25600, 25344, 25376, 25384, 25386, 
+        0, 16384, 24576, 25600, 25344, 25376, 25384,     0, 
+    16384, 24576, 25600, 25344, 25376, 25392, 25388,     0, 
+    16384, 24576, 25600, 25344, 25376, 25392, 25388,     0, 
+    16384, 24576, 25600, 25344, 25376, 25392, 25393, 25390, 
+        0, 16384, 24576, 25600, 25344, 25376,     0, 16384, 
+    24576, 25600, 25344, 25408, 25392,     0, 16384, 24576, 
+    25600, 25344, 25408, 25392,     0, 16384, 24576, 25600, 
+    25344, 25408, 25392, 25394,     0, 16384, 24576, 25600, 
+    25344, 25408, 25392,     0, 16384, 24576, 25600, 25344, 
+    25408, 25392, 25396,     0, 16384, 24576, 25600, 25344, 
+    25408, 25392, 25396,     0, 16384, 24576, 25600, 25344, 
+    25408, 25392, 25400, 25398,     0, 16384, 24576, 25600, 
+    25344, 25408, 25392,     0, 16384, 24576, 25600, 25344, 
+    25408, 25409, 25400,     0, 16384, 24576, 25600, 25344, 
+    25408, 25409, 25400,     0, 16384, 24576, 25600, 25344, 
+    25408, 25409, 25400, 25402,     0, 16384, 24576, 25600, 
+    25344, 25408, 25409, 25400,     0, 16384, 24576, 25600, 
+    25344, 25408, 25409, 25400, 25404,     0, 16384, 24576, 
+    25600, 25344, 25408, 25409, 25411, 25404,     0, 16384, 
+    24576, 25600, 25344, 25408, 25409, 25411, 25404, 25406, 
+        0, 16384, 24576, 25600, 25344,     0, 16384, 24576, 
+    25600, 25344, 25408,     0, 16384, 24576, 25600, 25344, 
+    25408,     0, 16384, 24576, 25600, 25344, 25408, 25410, 
+        0, 16384, 24576, 25600, 25344, 25408,     0, 16384, 
+    24576, 25600, 25344, 25408, 25412,     0, 16384, 24576, 
+    25600, 25344, 25408, 25412,     0, 16384, 24576, 25600, 
+    25344, 25408, 25416, 25414,     0, 16384, 24576, 25600, 
+    25344, 25408,     0, 16384, 24576, 25600, 25344, 25408, 
+    25416,     0, 16384, 24576, 25600, 25344, 25408, 25416, 
+        0, 16384, 24576, 25600, 25344, 25408, 25416, 25418, 
+        0, 16384, 24576, 25600, 25344, 25408, 25416,     0, 
+    16384, 24576, 25600, 25344, 25408, 25424, 25420,     0, 
+    16384, 24576, 25600, 25344, 25408, 25424, 25420,     0, 
+    16384, 24576, 25600, 25344, 25408, 25424, 25425, 25422, 
+        0, 16384, 24576, 25600, 25344, 25408,     0, 16384, 
+    24576, 25600, 25344, 25408, 25424,     0, 16384, 24576, 
+    25600, 25344, 25408, 25424,     0, 16384, 24576, 25600, 
+    25344, 25408, 25424, 25426,     0, 16384, 24576, 25600, 
+    25344, 25408, 25424,     0, 16384, 24576, 25600, 25344, 
+    25408, 25424, 25428,     0, 16384, 24576, 25600, 25344, 
+    25408, 25424, 25428,     0, 16384, 24576, 25600, 25344, 
+    25408, 25424, 25432, 25430,     0, 16384, 24576, 25600, 
+    25344, 25408, 25424,     0, 16384, 24576, 25600, 25344, 
+    25408, 25440, 25432,     0, 16384, 24576, 25600, 25344, 
+    25408, 25440, 25432,     0, 16384, 24576, 25600, 25344, 
+    25408, 25440, 25432, 25434,     0, 16384, 24576, 25600, 
+    25344, 25408, 25440, 25432,     0, 16384, 24576, 25600, 
+    25344, 25408, 25440, 25441, 25436,     0, 16384, 24576, 
+    25600, 25344, 25408, 25440, 25441, 25436,     0, 16384, 
+    24576, 25600, 25344, 25408, 25440, 25441, 25436, 25438, 
+        0, 16384, 24576, 25600, 25344, 25408,     0, 16384, 
+    24576, 25600, 25344, 25472, 25440,     0, 16384, 24576, 
+    25600, 25344, 25472, 25440,     0, 16384, 24576, 25600, 
+    25344, 25472, 25440, 25442,     0, 16384, 24576, 25600, 
+    25344, 25472, 25440,     0, 16384, 24576, 25600, 25344, 
+    25472, 25440, 25444,     0, 16384, 24576, 25600, 25344, 
+    25472, 25440, 25444,     0, 16384, 24576, 25600, 25344, 
+    25472, 25440, 25448, 25446,     0, 16384, 24576, 25600, 
+    25344, 25472, 25440,     0, 16384, 24576, 25600, 25344, 
+    25472, 25440, 25448,     0, 16384, 24576, 25600, 25344, 
+    25472, 25440, 25448,     0, 16384, 24576, 25600, 25344, 
+    25472, 25440, 25448, 25450,     0, 16384, 24576, 25600, 
+    25344, 25472, 25440, 25448,     0, 16384, 24576, 25600, 
+    25344, 25472, 25440, 25456, 25452,     0, 16384, 24576, 
+    25600, 25344, 25472, 25440, 25456, 25452,     0, 16384, 
+    24576, 25600, 25344, 25472, 25440, 25456, 25457, 25454, 
+        0, 16384, 24576, 25600, 25344, 25472, 25440,     0, 
+    16384, 24576, 25600, 25344, 25472, 25473, 25456,     0, 
+    16384, 24576, 25600, 25344, 25472, 25473, 25456,     0, 
+    16384, 24576, 25600, 25344, 25472, 25473, 25456, 25458, 
+        0, 16384, 24576, 25600, 25344, 25472, 25473, 25456, 
+        0, 16384, 24576, 25600, 25344, 25472, 25473, 25456, 
+    25460,     0, 16384, 24576, 25600, 25344, 25472, 25473, 
+    25456, 25460,     0, 16384, 24576, 25600, 25344, 25472, 
+    25473, 25456, 25464, 25462,     0, 16384, 24576, 25600, 
+    25344, 25472, 25473, 25456,     0, 16384, 24576, 25600, 
+    25344, 25472, 25473, 25456, 25464,     0, 16384, 24576, 
+    25600, 25344, 25472, 25473, 25475, 25464,     0, 16384, 
+    24576, 25600, 25344, 25472, 25473, 25475, 25464, 25466, 
+        0, 16384, 24576, 25600, 25344, 25472, 25473, 25475, 
+    25464,     0, 16384, 24576, 25600, 25344, 25472, 25473, 
+    25475, 25464, 25468,     0, 16384, 24576, 25600, 25344, 
+    25472, 25473, 25475, 25464, 25468,     0, 16384, 24576, 
+    25600, 25344, 25472, 25473, 25475, 25464, 25468, 25470, 
+        0, 16384, 24576, 25600, 25344,     0, 16384, 24576, 
+    25600, 25344, 25472,     0, 16384, 24576, 25600, 25601, 
+    25472,     0, 16384, 24576, 25600, 25601, 25472, 25474, 
+        0, 16384, 24576, 25600, 25601, 25472,     0, 16384, 
+    24576, 25600, 25601, 25472, 25476,     0, 16384, 24576, 
+    25600, 25601, 25472, 25476,     0, 16384, 24576, 25600, 
+    25601, 25472, 25480, 25478,     0, 16384, 24576, 25600, 
+    25601, 25472,     0, 16384, 24576, 25600, 25601, 25472, 
+    25480,     0, 16384, 24576, 25600, 25601, 25472, 25480, 
+        0, 16384, 24576, 25600, 25601, 25472, 25480, 25482, 
+        0, 16384, 24576, 25600, 25601, 25472, 25480,     0, 
+    16384, 24576, 25600, 25601, 25472, 25488, 25484,     0, 
+    16384, 24576, 25600, 25601, 25472, 25488, 25484,     0, 
+    16384, 24576, 25600, 25601, 25472, 25488, 25489, 25486, 
+        0, 16384, 24576, 25600, 25601, 25472,     0, 16384, 
+    24576, 25600, 25601, 25472, 25488,     0, 16384, 24576, 
+    25600, 25601, 25472, 25488,     0, 16384, 24576, 25600, 
+    25601, 25472, 25488, 25490,     0, 16384, 24576, 25600, 
+    25601, 25472, 25488,     0, 16384, 24576, 25600, 25601, 
+    25472, 25488, 25492,     0, 16384, 24576, 25600, 25601, 
+    25472, 25488, 25492,     0, 16384, 24576, 25600, 25601, 
+    25472, 25488, 25496, 25494,     0, 16384, 24576, 25600, 
+    25601, 25472, 25488,     0, 16384, 24576, 25600, 25601, 
+    25472, 25504, 25496,     0, 16384, 24576, 25600, 25601, 
+    25472, 25504, 25496,     0, 16384, 24576, 25600, 25601, 
+    25472, 25504, 25496, 25498,     0, 16384, 24576, 25600, 
+    25601, 25472, 25504, 25496,     0, 16384, 24576, 25600, 
+    25601, 25472, 25504, 25505, 25500,     0, 16384, 24576, 
+    25600, 25601, 25472, 25504, 25505, 25500,     0, 16384, 
+    24576, 25600, 25601, 25472, 25504, 25505, 25500, 25502, 
+        0, 16384, 24576, 25600, 25601, 25472,     0, 16384, 
+    24576, 25600, 25601, 25472, 25504,     0, 16384, 24576, 
+    25600, 25601, 25472, 25504,     0, 16384, 24576, 25600, 
+    25601, 25472, 25504, 25506,     0, 16384, 24576, 25600, 
+    25601, 25472, 25504,     0, 16384, 24576, 25600, 25601, 
+    25472, 25504, 25508,     0, 16384, 24576, 25600, 25601, 
+    25472, 25504, 25508,     0, 16384, 24576, 25600, 25601, 
+    25472, 25504, 25512, 25510,     0, 16384, 24576, 25600, 
+    25601, 25472, 25504,     0, 16384, 24576, 25600, 25601, 
+    25472, 25504, 25512,     0, 16384, 24576, 25600, 25601, 
+    25472, 25504, 25512,     0, 16384, 24576, 25600, 25601, 
+    25472, 25504, 25512, 25514,     0, 16384, 24576, 25600, 
+    25601, 25472, 25504, 25512,     0, 16384, 24576, 25600, 
+    25601, 25472, 25504, 25520, 25516,     0, 16384, 24576, 
+    25600, 25601, 25472, 25504, 25520, 25516,     0, 16384, 
+    24576, 25600, 25601, 25472, 25504, 25520, 25521, 25518, 
+        0, 16384, 24576, 25600, 25601, 25472, 25504,     0, 
+    16384, 24576, 25600, 25601, 25472, 25536, 25520,     0, 
+    16384, 24576, 25600, 25601, 25472, 25536, 25520,     0, 
+    16384, 24576, 25600, 25601, 25472, 25536, 25520, 25522, 
+        0, 16384, 24576, 25600, 25601, 25472, 25536, 25520, 
+        0, 16384, 24576, 25600, 25601, 25472, 25536, 25520, 
+    25524,     0, 16384, 24576, 25600, 25601, 25472, 25536, 
+    25520, 25524,     0, 16384, 24576, 25600, 25601, 25472, 
+    25536, 25520, 25528, 25526,     0, 16384, 24576, 25600, 
+    25601, 25472, 25536, 25520,     0, 16384, 24576, 25600, 
+    25601, 25472, 25536, 25537, 25528,     0, 16384, 24576, 
+    25600, 25601, 25472, 25536, 25537, 25528,     0, 16384, 
+    24576, 25600, 25601, 25472, 25536, 25537, 25528, 25530, 
+        0, 16384, 24576, 25600, 25601, 25472, 25536, 25537, 
+    25528,     0, 16384, 24576, 25600, 25601, 25472, 25536, 
+    25537, 25528, 25532,     0, 16384, 24576, 25600, 25601, 
+    25472, 25536, 25537, 25539, 25532,     0, 16384, 24576, 
+    25600, 25601, 25472, 25536, 25537, 25539, 25532, 25534, 
+        0, 16384, 24576, 25600, 25601, 25472,     0, 16384, 
+    24576, 25600, 25601, 25472, 25536,     0, 16384, 24576, 
+    25600, 25601, 25472, 25536,     0, 16384, 24576, 25600, 
+    25601, 25472, 25536, 25538,     0, 16384, 24576, 25600, 
+    25601, 25603, 25536,     0, 16384, 24576, 25600, 25601, 
+    25603, 25536, 25540,     0, 16384, 24576, 25600, 25601, 
+    25603, 25536, 25540,     0, 16384, 24576, 25600, 25601, 
+    25603, 25536, 25544, 25542,     0, 16384, 24576, 25600, 
+    25601, 25603, 25536,     0, 16384, 24576, 25600, 25601, 
+    25603, 25536, 25544,     0, 16384, 24576, 25600, 25601, 
+    25603, 25536, 25544,     0, 16384, 24576, 25600, 25601, 
+    25603, 25536, 25544, 25546,     0, 16384, 24576, 25600, 
+    25601, 25603, 25536, 25544,     0, 16384, 24576, 25600, 
+    25601, 25603, 25536, 25552, 25548,     0, 16384, 24576, 
+    25600, 25601, 25603, 25536, 25552, 25548,     0, 16384, 
+    24576, 25600, 25601, 25603, 25536, 25552, 25553, 25550, 
+        0, 16384, 24576, 25600, 25601, 25603, 25536,     0, 
+    16384, 24576, 25600, 25601, 25603, 25536, 25552,     0, 
+    16384, 24576, 25600, 25601, 25603, 25536, 25552,     0, 
+    16384, 24576, 25600, 25601, 25603, 25536, 25552, 25554, 
+        0, 16384, 24576, 25600, 25601, 25603, 25536, 25552, 
+        0, 16384, 24576, 25600, 25601, 25603, 25536, 25552, 
+    25556,     0, 16384, 24576, 25600, 25601, 25603, 25536, 
+    25552, 25556,     0, 16384, 24576, 25600, 25601, 25603, 
+    25536, 25552, 25560, 25558,     0, 16384, 24576, 25600, 
+    25601, 25603, 25536, 25552,     0, 16384, 24576, 25600, 
+    25601, 25603, 25536, 25568, 25560,     0, 16384, 24576, 
+    25600, 25601, 25603, 25536, 25568, 25560,     0, 16384, 
+    24576, 25600, 25601, 25603, 25536, 25568, 25560, 25562, 
+        0, 16384, 24576, 25600, 25601, 25603, 25536, 25568, 
+    25560,     0, 16384, 24576, 25600, 25601, 25603, 25536, 
+    25568, 25569, 25564,     0, 16384, 24576, 25600, 25601, 
+    25603, 25536, 25568, 25569, 25564,     0, 16384, 24576, 
+    25600, 25601, 25603, 25536, 25568, 25569, 25564, 25566, 
+        0, 16384, 24576, 25600, 25601, 25603, 25536,     0, 
+    16384, 24576, 25600, 25601, 25603, 25536, 25568,     0, 
+    16384, 24576, 25600, 25601, 25603, 25536, 25568,     0, 
+    16384, 24576, 25600, 25601, 25603, 25536, 25568, 25570, 
+        0, 16384, 24576, 25600, 25601, 25603, 25536, 25568, 
+        0, 16384, 24576, 25600, 25601, 25603, 25536, 25568, 
+    25572,     0, 16384, 24576, 25600, 25601, 25603, 25536, 
+    25568, 25572,     0, 16384, 24576, 25600, 25601, 25603, 
+    25536, 25568, 25576, 25574,     0, 16384, 24576, 25600, 
+    25601, 25603, 25607, 25568,     0, 16384, 24576, 25600, 
+    25601, 25603, 25607, 25568, 25576,     0, 16384, 24576, 
+    25600, 25601, 25603, 25607, 25568, 25576,     0, 16384, 
+    24576, 25600, 25601, 25603, 25607, 25568, 25576, 25578, 
+        0, 16384, 24576, 25600, 25601, 25603, 25607, 25568, 
+    25576,     0, 16384, 24576, 25600, 25601, 25603, 25607, 
+    25568, 25584, 25580,     0, 16384, 24576, 25600, 25601, 
+    25603, 25607, 25568, 25584, 25580,     0, 16384, 24576, 
+    25600, 25601, 25603, 25607, 25568, 25584, 25585, 25582, 
+        0, 16384, 24576, 25600, 25601, 25603, 25607, 25568, 
+        0, 16384, 24576, 25600, 25601, 25603, 25607, 25568, 
+    25584,     0, 16384, 24576, 25600, 25601, 25603, 25607, 
+    25568, 25584,     0, 16384, 24576, 25600, 25601, 25603, 
+    25607, 25568, 25584, 25586,     0, 16384, 24576, 25600, 
+    25601, 25603, 25607, 25568, 25584,     0, 16384, 24576, 
+    25600, 25601, 25603, 25607, 25568, 25584, 25588,     0, 
+    16384, 24576, 25600, 25601, 25603, 25607, 25568, 25584, 
+    25588,     0, 16384, 24576, 25600, 25601, 25603, 25607, 
+    25568, 25584, 25592, 25590,     0, 16384, 24576, 25600, 
+    25601, 25603, 25607, 25568, 25584,     0, 16384, 24576, 
+    25600, 25601, 25603, 25607, 25568, 25584, 25592,     0, 
+    16384, 24576, 25600, 25601, 25603, 25607, 25568, 25584, 
+    25592,     0, 16384, 24576, 25600, 25601, 25603, 25607, 
+    25568, 25584, 25592, 25594,     0, 16384, 24576, 25600, 
+    25601, 25603, 25607, 25568, 25584, 25592,     0, 16384, 
+    24576, 25600, 25601, 25603, 25607, 25568, 25584, 25592, 
+    25596,     0, 16384, 24576, 25600, 25601, 25603, 25607, 
+    25568, 25584, 25592, 25596,     0, 16384, 24576, 25600, 
+    25601, 25603, 25607, 25568, 25584, 25592, 25596, 25598, 
+        0, 16384, 24576,     0, 16384, 24576, 25600,     0, 
+    16384, 24576, 25600,     0, 16384, 24576, 25600, 25602, 
+        0, 16384, 24576, 25600,     0, 16384, 24576, 25600, 
+    25604,     0, 16384, 24576, 25600, 25604,     0, 16384, 
+    24576, 25600, 25608, 25606,     0, 16384, 24576, 25600, 
+        0, 16384, 24576, 25600, 25608,     0, 16384, 24576, 
+    25600, 25608,     0, 16384, 24576, 25600, 25608, 25610, 
+        0, 16384, 24576, 25600, 25608,     0, 16384, 24576, 
+    25600, 25616, 25612,     0, 16384, 24576, 25600, 25616, 
+    25612,     0, 16384, 24576, 25600, 25616, 25617, 25614, 
+        0, 16384, 24576, 25600,     0, 16384, 24576, 25600, 
+    25616,     0, 16384, 24576, 25600, 25616,     0, 16384, 
+    24576, 25600, 25616, 25618,     0, 16384, 24576, 25600, 
+    25616,     0, 16384, 24576, 25600, 25616, 25620,     0, 
+    16384, 24576, 25600, 25616, 25620,     0, 16384, 24576, 
+    25600, 25616, 25624, 25622,     0, 16384, 24576, 25600, 
+    25616,     0, 16384, 24576, 25600, 25632, 25624,     0, 
+    16384, 24576, 25600, 25632, 25624,     0, 16384, 24576, 
+    25600, 25632, 25624, 25626,     0, 16384, 24576, 25600, 
+    25632, 25624,     0, 16384, 24576, 25600, 25632, 25633, 
+    25628,     0, 16384, 24576, 25600, 25632, 25633, 25628, 
+        0, 16384, 24576, 25600, 25632, 25633, 25628, 25630, 
+        0, 16384, 24576, 25600,     0, 16384, 24576, 25600, 
+    25632,     0, 16384, 24576, 25600, 25632,     0, 16384, 
+    24576, 25600, 25632, 25634,     0, 16384, 24576, 25600, 
+    25632,     0, 16384, 24576, 25600, 25632, 25636,     0, 
+    16384, 24576, 25600, 25632, 25636,     0, 16384, 24576, 
+    25600, 25632, 25640, 25638,     0, 16384, 24576, 25600, 
+    25632,     0, 16384, 24576, 25600, 25632, 25640,     0, 
+    16384, 24576, 25600, 25632, 25640,     0, 16384, 24576, 
+    25600, 25632, 25640, 25642,     0, 16384, 24576, 25600, 
+    25632, 25640,     0, 16384, 24576, 25600, 25632, 25648, 
+    25644,     0, 16384, 24576, 25600, 25632, 25648, 25644, 
+        0, 16384, 24576, 25600, 25632, 25648, 25649, 25646, 
+        0, 16384, 24576, 25600, 25632,     0, 16384, 24576, 
+    25600, 25664, 25648,     0, 16384, 24576, 25600, 25664, 
+    25648,     0, 16384, 24576, 25600, 25664, 25648, 25650, 
+        0, 16384, 24576, 25600, 25664, 25648,     0, 16384, 
+    24576, 25600, 25664, 25648, 25652,     0, 16384, 24576, 
+    25600, 25664, 25648, 25652,     0, 16384, 24576, 25600, 
+    25664, 25648, 25656, 25654,     0, 16384, 24576, 25600, 
+    25664, 25648,     0, 16384, 24576, 25600, 25664, 25665, 
+    25656,     0, 16384, 24576, 25600, 25664, 25665, 25656, 
+        0, 16384, 24576, 25600, 25664, 25665, 25656, 25658, 
+        0, 16384, 24576, 25600, 25664, 25665, 25656,     0, 
+    16384, 24576, 25600, 25664, 25665, 25656, 25660,     0, 
+    16384, 24576, 25600, 25664, 25665, 25667, 25660,     0, 
+    16384, 24576, 25600, 25664, 25665, 25667, 25660, 25662, 
+        0, 16384, 24576, 25600,     0, 16384, 24576, 25600, 
+    25664,     0, 16384, 24576, 25600, 25664,     0, 16384, 
+    24576, 25600, 25664, 25666,     0, 16384, 24576, 25600, 
+    25664,     0, 16384, 24576, 25600, 25664, 25668,     0, 
+    16384, 24576, 25600, 25664, 25668,     0, 16384, 24576, 
+    25600, 25664, 25672, 25670,     0, 16384, 24576, 25600, 
+    25664,     0, 16384, 24576, 25600, 25664, 25672,     0, 
+    16384, 24576, 25600, 25664, 25672,     0, 16384, 24576, 
+    25600, 25664, 25672, 25674,     0, 16384, 24576, 25600, 
+    25664, 25672,     0, 16384, 24576, 25600, 25664, 25680, 
+    25676,     0, 16384, 24576, 25600, 25664, 25680, 25676, 
+        0, 16384, 24576, 25600, 25664, 25680, 25681, 25678, 
+        0, 16384, 24576, 25600, 25664,     0, 16384, 24576, 
+    25600, 25664, 25680,     0, 16384, 24576, 25600, 25664, 
+    25680,     0, 16384, 24576, 25600, 25664, 25680, 25682, 
+        0, 16384, 24576, 25600, 25664, 25680,     0, 16384, 
+    24576, 25600, 25664, 25680, 25684,     0, 16384, 24576, 
+    25600, 25664, 25680, 25684,     0, 16384, 24576, 25600, 
+    25664, 25680, 25688, 25686,     0, 16384, 24576, 25600, 
+    25664, 25680,     0, 16384, 24576, 25600, 25664, 25696, 
+    25688,     0, 16384, 24576, 25600, 25664, 25696, 25688, 
+        0, 16384, 24576, 25600, 25664, 25696, 25688, 25690, 
+        0, 16384, 24576, 25600, 25664, 25696, 25688,     0, 
+    16384, 24576, 25600, 25664, 25696, 25697, 25692,     0, 
+    16384, 24576, 25600, 25664, 25696, 25697, 25692,     0, 
+    16384, 24576, 25600, 25664, 25696, 25697, 25692, 25694, 
+        0, 16384, 24576, 25600, 25664,     0, 16384, 24576, 
+    25600, 25728, 25696,     0, 16384, 24576, 25600, 25728, 
+    25696,     0, 16384, 24576, 25600, 25728, 25696, 25698, 
+        0, 16384, 24576, 25600, 25728, 25696,     0, 16384, 
+    24576, 25600, 25728, 25696, 25700,     0, 16384, 24576, 
+    25600, 25728, 25696, 25700,     0, 16384, 24576, 25600, 
+    25728, 25696, 25704, 25702,     0, 16384, 24576, 25600, 
+    25728, 25696,     0, 16384, 24576, 25600, 25728, 25696, 
+    25704,     0, 16384, 24576, 25600, 25728, 25696, 25704, 
+        0, 16384, 24576, 25600, 25728, 25696, 25704, 25706, 
+        0, 16384, 24576, 25600, 25728, 25696, 25704,     0, 
+    16384, 24576, 25600, 25728, 25696, 25712, 25708,     0, 
+    16384, 24576, 25600, 25728, 25696, 25712, 25708,     0, 
+    16384, 24576, 25600, 25728, 25696, 25712, 25713, 25710, 
+        0, 16384, 24576, 25600, 25728, 25696,     0, 16384, 
+    24576, 25600, 25728, 25729, 25712,     0, 16384, 24576, 
+    25600, 25728, 25729, 25712,     0, 16384, 24576, 25600, 
+    25728, 25729, 25712, 25714,     0, 16384, 24576, 25600, 
+    25728, 25729, 25712,     0, 16384, 24576, 25600, 25728, 
+    25729, 25712, 25716,     0, 16384, 24576, 25600, 25728, 
+    25729, 25712, 25716,     0, 16384, 24576, 25600, 25728, 
+    25729, 25712, 25720, 25718,     0, 16384, 24576, 25600, 
+    25728, 25729, 25712,     0, 16384, 24576, 25600, 25728, 
+    25729, 25712, 25720,     0, 16384, 24576, 25600, 25728, 
+    25729, 25731, 25720,     0, 16384, 24576, 25600, 25728, 
+    25729, 25731, 25720, 25722,     0, 16384, 24576, 25600, 
+    25728, 25729, 25731, 25720,     0, 16384, 24576, 25600, 
+    25728, 25729, 25731, 25720, 25724,     0, 16384, 24576, 
+    25600, 25728, 25729, 25731, 25720, 25724,     0, 16384, 
+    24576, 25600, 25728, 25729, 25731, 25720, 25724, 25726, 
+        0, 16384, 24576, 25600,     0, 16384, 24576, 25600, 
+    25728,     0, 16384, 24576, 25600, 25728,     0, 16384, 
+    24576, 25600, 25728, 25730,     0, 16384, 24576, 25600, 
+    25728,     0, 16384, 24576, 25600, 25728, 25732,     0, 
+    16384, 24576, 25600, 25728, 25732,     0, 16384, 24576, 
+    25600, 25728, 25736, 25734,     0, 16384, 24576, 25600, 
+    25728,     0, 16384, 24576, 25600, 25728, 25736,     0, 
+    16384, 24576, 25600, 25728, 25736,     0, 16384, 24576, 
+    25600, 25728, 25736, 25738,     0, 16384, 24576, 25600, 
+    25728, 25736,     0, 16384, 24576, 25600, 25728, 25744, 
+    25740,     0, 16384, 24576, 25600, 25728, 25744, 25740, 
+        0, 16384, 24576, 25600, 25728, 25744, 25745, 25742, 
+        0, 16384, 24576, 25600, 25728,     0, 16384, 24576, 
+    25600, 25728, 25744,     0, 16384, 24576, 25600, 25728, 
+    25744,     0, 16384, 24576, 25600, 25728, 25744, 25746, 
+        0, 16384, 24576, 25600, 25728, 25744,     0, 16384, 
+    24576, 25600, 25728, 25744, 25748,     0, 16384, 24576, 
+    25600, 25728, 25744, 25748,     0, 16384, 24576, 25600, 
+    25728, 25744, 25752, 25750,     0, 16384, 24576, 25600, 
+    25728, 25744,     0, 16384, 24576, 25600, 25728, 25760, 
+    25752,     0, 16384, 24576, 25600, 25728, 25760, 25752, 
+        0, 16384, 24576, 25600, 25728, 25760, 25752, 25754, 
+        0, 16384, 24576, 25600, 25728, 25760, 25752,     0, 
+    16384, 24576, 25600, 25728, 25760, 25761, 25756,     0, 
+    16384, 24576, 25600, 25728, 25760, 25761, 25756,     0, 
+    16384, 24576, 25600, 25728, 25760, 25761, 25756, 25758, 
+        0, 16384, 24576, 25600, 25728,     0, 16384, 24576, 
+    25600, 25728, 25760,     0, 16384, 24576, 25600, 25728, 
+    25760,     0, 16384, 24576, 25600, 25728, 25760, 25762, 
+        0, 16384, 24576, 25600, 25728, 25760,     0, 16384, 
+    24576, 25600, 25728, 25760, 25764,     0, 16384, 24576, 
+    25600, 25728, 25760, 25764,     0, 16384, 24576, 25600, 
+    25728, 25760, 25768, 25766,     0, 16384, 24576, 25600, 
+    25728, 25760,     0, 16384, 24576, 25600, 25728, 25760, 
+    25768,     0, 16384, 24576, 25600, 25728, 25760, 25768, 
+        0, 16384, 24576, 25600, 25728, 25760, 25768, 25770, 
+        0, 16384, 24576, 25600, 25728, 25760, 25768,     0, 
+    16384, 24576, 25600, 25728, 25760, 25776, 25772,     0, 
+    16384, 24576, 25600, 25728, 25760, 25776, 25772,     0, 
+    16384, 24576, 25600, 25728, 25760, 25776, 25777, 25774, 
+        0, 16384, 24576, 25600, 25728, 25760,     0, 16384, 
+    24576, 25600, 25728, 25792, 25776,     0, 16384, 24576, 
+    25600, 25728, 25792, 25776,     0, 16384, 24576, 25600, 
+    25728, 25792, 25776, 25778,     0, 16384, 24576, 25600, 
+    25728, 25792, 25776,     0, 16384, 24576, 25600, 25728, 
+    25792, 25776, 25780,     0, 16384, 24576, 25600, 25728, 
+    25792, 25776, 25780,     0, 16384, 24576, 25600, 25728, 
+    25792, 25776, 25784, 25782,     0, 16384, 24576, 25600, 
+    25728, 25792, 25776,     0, 16384, 24576, 25600, 25728, 
+    25792, 25793, 25784,     0, 16384, 24576, 25600, 25728, 
+    25792, 25793, 25784,     0, 16384, 24576, 25600, 25728, 
+    25792, 25793, 25784, 25786,     0, 16384, 24576, 25600, 
+    25728, 25792, 25793, 25784,     0, 16384, 24576, 25600, 
+    25728, 25792, 25793, 25784, 25788,     0, 16384, 24576, 
+    25600, 25728, 25792, 25793, 25795, 25788,     0, 16384, 
+    24576, 25600, 25728, 25792, 25793, 25795, 25788, 25790, 
+        0, 16384, 24576, 25600, 25728,     0, 16384, 24576, 
+    25600, 25856, 25792,     0, 16384, 24576, 25600, 25856, 
+    25792,     0, 16384, 24576, 25600, 25856, 25792, 25794, 
+        0, 16384, 24576, 25600, 25856, 25792,     0, 16384, 
+    24576, 25600, 25856, 25792, 25796,     0, 16384, 24576, 
+    25600, 25856, 25792, 25796,     0, 16384, 24576, 25600, 
+    25856, 25792, 25800, 25798,     0, 16384, 24576, 25600, 
+    25856, 25792,     0, 16384, 24576, 25600, 25856, 25792, 
+    25800,     0, 16384, 24576, 25600, 25856, 25792, 25800, 
+        0, 16384, 24576, 25600, 25856, 25792, 25800, 25802, 
+        0, 16384, 24576, 25600, 25856, 25792, 25800,     0, 
+    16384, 24576, 25600, 25856, 25792, 25808, 25804,     0, 
+    16384, 24576, 25600, 25856, 25792, 25808, 25804,     0, 
+    16384, 24576, 25600, 25856, 25792, 25808, 25809, 25806, 
+        0, 16384, 24576, 25600, 25856, 25792,     0, 16384, 
+    24576, 25600, 25856, 25792, 25808,     0, 16384, 24576, 
+    25600, 25856, 25792, 25808,     0, 16384, 24576, 25600, 
+    25856, 25792, 25808, 25810,     0, 16384, 24576, 25600, 
+    25856, 25792, 25808,     0, 16384, 24576, 25600, 25856, 
+    25792, 25808, 25812,     0, 16384, 24576, 25600, 25856, 
+    25792, 25808, 25812,     0, 16384, 24576, 25600, 25856, 
+    25792, 25808, 25816, 25814,     0, 16384, 24576, 25600, 
+    25856, 25792, 25808,     0, 16384, 24576, 25600, 25856, 
+    25792, 25824, 25816,     0, 16384, 24576, 25600, 25856, 
+    25792, 25824, 25816,     0, 16384, 24576, 25600, 25856, 
+    25792, 25824, 25816, 25818,     0, 16384, 24576, 25600, 
+    25856, 25792, 25824, 25816,     0, 16384, 24576, 25600, 
+    25856, 25792, 25824, 25825, 25820,     0, 16384, 24576, 
+    25600, 25856, 25792, 25824, 25825, 25820,     0, 16384, 
+    24576, 25600, 25856, 25792, 25824, 25825, 25820, 25822, 
+        0, 16384, 24576, 25600, 25856, 25792,     0, 16384, 
+    24576, 25600, 25856, 25857, 25824,     0, 16384, 24576, 
+    25600, 25856, 25857, 25824,     0, 16384, 24576, 25600, 
+    25856, 25857, 25824, 25826,     0, 16384, 24576, 25600, 
+    25856, 25857, 25824,     0, 16384, 24576, 25600, 25856, 
+    25857, 25824, 25828,     0, 16384, 24576, 25600, 25856, 
+    25857, 25824, 25828,     0, 16384, 24576, 25600, 25856, 
+    25857, 25824, 25832, 25830,     0, 16384, 24576, 25600, 
+    25856, 25857, 25824,     0, 16384, 24576, 25600, 25856, 
+    25857, 25824, 25832,     0, 16384, 24576, 25600, 25856, 
+    25857, 25824, 25832,     0, 16384, 24576, 25600, 25856, 
+    25857, 25824, 25832, 25834,     0, 16384, 24576, 25600, 
+    25856, 25857, 25824, 25832,     0, 16384, 24576, 25600, 
+    25856, 25857, 25824, 25840, 25836,     0, 16384, 24576, 
+    25600, 25856, 25857, 25824, 25840, 25836,     0, 16384, 
+    24576, 25600, 25856, 25857, 25824, 25840, 25841, 25838, 
+        0, 16384, 24576, 25600, 25856, 25857, 25824,     0, 
+    16384, 24576, 25600, 25856, 25857, 25824, 25840,     0, 
+    16384, 24576, 25600, 25856, 25857, 25859, 25840,     0, 
+    16384, 24576, 25600, 25856, 25857, 25859, 25840, 25842, 
+        0, 16384, 24576, 25600, 25856, 25857, 25859, 25840, 
+        0, 16384, 24576, 25600, 25856, 25857, 25859, 25840, 
+    25844,     0, 16384, 24576, 25600, 25856, 25857, 25859, 
+    25840, 25844,     0, 16384, 24576, 25600, 25856, 25857, 
+    25859, 25840, 25848, 25846,     0, 16384, 24576, 25600, 
+    25856, 25857, 25859, 25840,     0, 16384, 24576, 25600, 
+    25856, 25857, 25859, 25840, 25848,     0, 16384, 24576, 
+    25600, 25856, 25857, 25859, 25840, 25848,     0, 16384, 
+    24576, 25600, 25856, 25857, 25859, 25840, 25848, 25850, 
+        0, 16384, 24576, 25600, 25856, 25857, 25859, 25863, 
+    25848,     0, 16384, 24576, 25600, 25856, 25857, 25859, 
+    25863, 25848, 25852,     0, 16384, 24576, 25600, 25856, 
+    25857, 25859, 25863, 25848, 25852,     0, 16384, 24576, 
+    25600, 25856, 25857, 25859, 25863, 25848, 25852, 25854, 
+        0, 16384, 24576, 25600,     0, 16384, 24576, 25600, 
+    25856,     0, 16384, 24576, 25600, 25856,     0, 16384, 
+    24576, 25600, 25856, 25858,     0, 16384, 24576, 25600, 
+    25856,     0, 16384, 24576, 25600, 25856, 25860,     0, 
+    16384, 24576, 25600, 25856, 25860,     0, 16384, 24576, 
+    25600, 25856, 25864, 25862,     0, 16384, 24576, 25600, 
+    25856,     0, 16384, 24576, 25600, 25856, 25864,     0, 
+    16384, 24576, 25600, 25856, 25864,     0, 16384, 24576, 
+    25600, 25856, 25864, 25866,     0, 16384, 24576, 25600, 
+    25856, 25864,     0, 16384, 24576, 25600, 25856, 25872, 
+    25868,     0, 16384, 24576, 25600, 25856, 25872, 25868, 
+        0, 16384, 24576, 25600, 25856, 25872, 25873, 25870, 
+        0, 16384, 24576, 25600, 25856,     0, 16384, 24576, 
+    25600, 25856, 25872,     0, 16384, 24576, 25600, 25856, 
+    25872,     0, 16384, 24576, 25600, 25856, 25872, 25874, 
+        0, 16384, 24576, 25600, 25856, 25872,     0, 16384, 
+    24576, 25600, 25856, 25872, 25876,     0, 16384, 24576, 
+    25600, 25856, 25872, 25876,     0, 16384, 24576, 25600, 
+    25856, 25872, 25880, 25878,     0, 16384, 24576, 25600, 
+    25856, 25872,     0, 16384, 24576, 25600, 25856, 25888, 
+    25880,     0, 16384, 24576, 25600, 25856, 25888, 25880, 
+        0, 16384, 24576, 25600, 25856, 25888, 25880, 25882, 
+        0, 16384, 24576, 25600, 25856, 25888, 25880,     0, 
+    16384, 24576, 25600, 25856, 25888, 25889, 25884,     0, 
+    16384, 24576, 25600, 25856, 25888, 25889, 25884,     0, 
+    16384, 24576, 25600, 25856, 25888, 25889, 25884, 25886, 
+        0, 16384, 24576, 25600, 25856,     0, 16384, 24576, 
+    25600, 25856, 25888,     0, 16384, 24576, 25600, 25856, 
+    25888,     0, 16384, 24576, 25600, 25856, 25888, 25890, 
+        0, 16384, 24576, 25600, 25856, 25888,     0, 16384, 
+    24576, 25600, 25856, 25888, 25892,     0, 16384, 24576, 
+    25600, 25856, 25888, 25892,     0, 16384, 24576, 25600, 
+    25856, 25888, 25896, 25894,     0, 16384, 24576, 25600, 
+    25856, 25888,     0, 16384, 24576, 25600, 25856, 25888, 
+    25896,     0, 16384, 24576, 25600, 25856, 25888, 25896, 
+        0, 16384, 24576, 25600, 25856, 25888, 25896, 25898, 
+        0, 16384, 24576, 25600, 25856, 25888, 25896,     0, 
+    16384, 24576, 25600, 25856, 25888, 25904, 25900,     0, 
+    16384, 24576, 25600, 25856, 25888, 25904, 25900,     0, 
+    16384, 24576, 25600, 25856, 25888, 25904, 25905, 25902, 
+        0, 16384, 24576, 25600, 25856, 25888,     0, 16384, 
+    24576, 25600, 25856, 25920, 25904,     0, 16384, 24576, 
+    25600, 25856, 25920, 25904,     0, 16384, 24576, 25600, 
+    25856, 25920, 25904, 25906,     0, 16384, 24576, 25600, 
+    25856, 25920, 25904,     0, 16384, 24576, 25600, 25856, 
+    25920, 25904, 25908,     0, 16384, 24576, 25600, 25856, 
+    25920, 25904, 25908,     0, 16384, 24576, 25600, 25856, 
+    25920, 25904, 25912, 25910,     0, 16384, 24576, 25600, 
+    25856, 25920, 25904,     0, 16384, 24576, 25600, 25856, 
+    25920, 25921, 25912,     0, 16384, 24576, 25600, 25856, 
+    25920, 25921, 25912,     0, 16384, 24576, 25600, 25856, 
+    25920, 25921, 25912, 25914,     0, 16384, 24576, 25600, 
+    25856, 25920, 25921, 25912,     0, 16384, 24576, 25600, 
+    25856, 25920, 25921, 25912, 25916,     0, 16384, 24576, 
+    25600, 25856, 25920, 25921, 25923, 25916,     0, 16384, 
+    24576, 25600, 25856, 25920, 25921, 25923, 25916, 25918, 
+        0, 16384, 24576, 25600, 25856,     0, 16384, 24576, 
+    25600, 25856, 25920,     0, 16384, 24576, 25600, 25856, 
+    25920,     0, 16384, 24576, 25600, 25856, 25920, 25922, 
+        0, 16384, 24576, 25600, 25856, 25920,     0, 16384, 
+    24576, 25600, 25856, 25920, 25924,     0, 16384, 24576, 
+    25600, 25856, 25920, 25924,     0, 16384, 24576, 25600, 
+    25856, 25920, 25928, 25926,     0, 16384, 24576, 25600, 
+    25856, 25920,     0, 16384, 24576, 25600, 25856, 25920, 
+    25928,     0, 16384, 24576, 25600, 25856, 25920, 25928, 
+        0, 16384, 24576, 25600, 25856, 25920, 25928, 25930, 
+        0, 16384, 24576, 25600, 25856, 25920, 25928,     0, 
+    16384, 24576, 25600, 25856, 25920, 25936, 25932,     0, 
+    16384, 24576, 25600, 25856, 25920, 25936, 25932,     0, 
+    16384, 24576, 25600, 25856, 25920, 25936, 25937, 25934, 
+        0, 16384, 24576, 25600, 25856, 25920,     0, 16384, 
+    24576, 25600, 25856, 25920, 25936,     0, 16384, 24576, 
+    25600, 25856, 25920, 25936,     0, 16384, 24576, 25600, 
+    25856, 25920, 25936, 25938,     0, 16384, 24576, 25600, 
+    25856, 25920, 25936,     0, 16384, 24576, 25600, 25856, 
+    25920, 25936, 25940,     0, 16384, 24576, 25600, 25856, 
+    25920, 25936, 25940,     0, 16384, 24576, 25600, 25856, 
+    25920, 25936, 25944, 25942,     0, 16384, 24576, 25600, 
+    25856, 25920, 25936,     0, 16384, 24576, 25600, 25856, 
+    25920, 25952, 25944,     0, 16384, 24576, 25600, 25856, 
+    25920, 25952, 25944,     0, 16384, 24576, 25600, 25856, 
+    25920, 25952, 25944, 25946,     0, 16384, 24576, 25600, 
+    25856, 25920, 25952, 25944,     0, 16384, 24576, 25600, 
+    25856, 25920, 25952, 25953, 25948,     0, 16384, 24576, 
+    25600, 25856, 25920, 25952, 25953, 25948,     0, 16384, 
+    24576, 25600, 25856, 25920, 25952, 25953, 25948, 25950, 
+        0, 16384, 24576, 25600, 25856, 25920,     0, 16384, 
+    24576, 25600, 25856, 25984, 25952,     0, 16384, 24576, 
+    25600, 25856, 25984, 25952,     0, 16384, 24576, 25600, 
+    25856, 25984, 25952, 25954,     0, 16384, 24576, 25600, 
+    25856, 25984, 25952,     0, 16384, 24576, 25600, 25856, 
+    25984, 25952, 25956,     0, 16384, 24576, 25600, 25856, 
+    25984, 25952, 25956,     0, 16384, 24576, 25600, 25856, 
+    25984, 25952, 25960, 25958,     0, 16384, 24576, 25600, 
+    25856, 25984, 25952,     0, 16384, 24576, 25600, 25856, 
+    25984, 25952, 25960,     0, 16384, 24576, 25600, 25856, 
+    25984, 25952, 25960,     0, 16384, 24576, 25600, 25856, 
+    25984, 25952, 25960, 25962,     0, 16384, 24576, 25600, 
+    25856, 25984, 25952, 25960,     0, 16384, 24576, 25600, 
+    25856, 25984, 25952, 25968, 25964,     0, 16384, 24576, 
+    25600, 25856, 25984, 25952, 25968, 25964,     0, 16384, 
+    24576, 25600, 25856, 25984, 25952, 25968, 25969, 25966, 
+        0, 16384, 24576, 25600, 25856, 25984, 25952,     0, 
+    16384, 24576, 25600, 25856, 25984, 25985, 25968,     0, 
+    16384, 24576, 25600, 25856, 25984, 25985, 25968,     0, 
+    16384, 24576, 25600, 25856, 25984, 25985, 25968, 25970, 
+        0, 16384, 24576, 25600, 25856, 25984, 25985, 25968, 
+        0, 16384, 24576, 25600, 25856, 25984, 25985, 25968, 
+    25972,     0, 16384, 24576, 25600, 25856, 25984, 25985, 
+    25968, 25972,     0, 16384, 24576, 25600, 25856, 25984, 
+    25985, 25968, 25976, 25974,     0, 16384, 24576, 25600, 
+    25856, 25984, 25985, 25968,     0, 16384, 24576, 25600, 
+    25856, 25984, 25985, 25968, 25976,     0, 16384, 24576, 
+    25600, 25856, 25984, 25985, 25987, 25976,     0, 16384, 
+    24576, 25600, 25856, 25984, 25985, 25987, 25976, 25978, 
+        0, 16384, 24576, 25600, 25856, 25984, 25985, 25987, 
+    25976,     0, 16384, 24576, 25600, 25856, 25984, 25985, 
+    25987, 25976, 25980,     0, 16384, 24576, 25600, 25856, 
+    25984, 25985, 25987, 25976, 25980,     0, 16384, 24576, 
+    25600, 25856, 25984, 25985, 25987, 25976, 25980, 25982, 
+        0, 16384, 24576, 25600, 25856,     0, 16384, 24576, 
+    25600, 26112, 25984,     0, 16384, 24576, 25600, 26112, 
+    25984,     0, 16384, 24576, 25600, 26112, 25984, 25986, 
+        0, 16384, 24576, 25600, 26112, 25984,     0, 16384, 
+    24576, 25600, 26112, 25984, 25988,     0, 16384, 24576, 
+    25600, 26112, 25984, 25988,     0, 16384, 24576, 25600, 
+    26112, 25984, 25992, 25990,     0, 16384, 24576, 25600, 
+    26112, 25984,     0, 16384, 24576, 25600, 26112, 25984, 
+    25992,     0, 16384, 24576, 25600, 26112, 25984, 25992, 
+        0, 16384, 24576, 25600, 26112, 25984, 25992, 25994, 
+        0, 16384, 24576, 25600, 26112, 25984, 25992,     0, 
+    16384, 24576, 25600, 26112, 25984, 26000, 25996,     0, 
+    16384, 24576, 25600, 26112, 25984, 26000, 25996,     0, 
+    16384, 24576, 25600, 26112, 25984, 26000, 26001, 25998, 
+        0, 16384, 24576, 25600, 26112, 25984,     0, 16384, 
+    24576, 25600, 26112, 25984, 26000,     0, 16384, 24576, 
+    25600, 26112, 25984, 26000,     0, 16384, 24576, 25600, 
+    26112, 25984, 26000, 26002,     0, 16384, 24576, 25600, 
+    26112, 25984, 26000,     0, 16384, 24576, 25600, 26112, 
+    25984, 26000, 26004,     0, 16384, 24576, 25600, 26112, 
+    25984, 26000, 26004,     0, 16384, 24576, 25600, 26112, 
+    25984, 26000, 26008, 26006,     0, 16384, 24576, 25600, 
+    26112, 25984, 26000,     0, 16384, 24576, 25600, 26112, 
+    25984, 26016, 26008,     0, 16384, 24576, 25600, 26112, 
+    25984, 26016, 26008,     0, 16384, 24576, 25600, 26112, 
+    25984, 26016, 26008, 26010,     0, 16384, 24576, 25600, 
+    26112, 25984, 26016, 26008,     0, 16384, 24576, 25600, 
+    26112, 25984, 26016, 26017, 26012,     0, 16384, 24576, 
+    25600, 26112, 25984, 26016, 26017, 26012,     0, 16384, 
+    24576, 25600, 26112, 25984, 26016, 26017, 26012, 26014, 
+        0, 16384, 24576, 25600, 26112, 25984,     0, 16384, 
+    24576, 25600, 26112, 25984, 26016,     0, 16384, 24576, 
+    25600, 26112, 25984, 26016,     0, 16384, 24576, 25600, 
+    26112, 25984, 26016, 26018,     0, 16384, 24576, 25600, 
+    26112, 25984, 26016,     0, 16384, 24576, 25600, 26112, 
+    25984, 26016, 26020,     0, 16384, 24576, 25600, 26112, 
+    25984, 26016, 26020,     0, 16384, 24576, 25600, 26112, 
+    25984, 26016, 26024, 26022,     0, 16384, 24576, 25600, 
+    26112, 25984, 26016,     0, 16384, 24576, 25600, 26112, 
+    25984, 26016, 26024,     0, 16384, 24576, 25600, 26112, 
+    25984, 26016, 26024,     0, 16384, 24576, 25600, 26112, 
+    25984, 26016, 26024, 26026,     0, 16384, 24576, 25600, 
+    26112, 25984, 26016, 26024,     0, 16384, 24576, 25600, 
+    26112, 25984, 26016, 26032, 26028,     0, 16384, 24576, 
+    25600, 26112, 25984, 26016, 26032, 26028,     0, 16384, 
+    24576, 25600, 26112, 25984, 26016, 26032, 26033, 26030, 
+        0, 16384, 24576, 25600, 26112, 25984, 26016,     0, 
+    16384, 24576, 25600, 26112, 25984, 26048, 26032,     0, 
+    16384, 24576, 25600, 26112, 25984, 26048, 26032,     0, 
+    16384, 24576, 25600, 26112, 25984, 26048, 26032, 26034, 
+        0, 16384, 24576, 25600, 26112, 25984, 26048, 26032, 
+        0, 16384, 24576, 25600, 26112, 25984, 26048, 26032, 
+    26036,     0, 16384, 24576, 25600, 26112, 25984, 26048, 
+    26032, 26036,     0, 16384, 24576, 25600, 26112, 25984, 
+    26048, 26032, 26040, 26038,     0, 16384, 24576, 25600, 
+    26112, 25984, 26048, 26032,     0, 16384, 24576, 25600, 
+    26112, 25984, 26048, 26049, 26040,     0, 16384, 24576, 
+    25600, 26112, 25984, 26048, 26049, 26040,     0, 16384, 
+    24576, 25600, 26112, 25984, 26048, 26049, 26040, 26042, 
+        0, 16384, 24576, 25600, 26112, 25984, 26048, 26049, 
+    26040,     0, 16384, 24576, 25600, 26112, 25984, 26048, 
+    26049, 26040, 26044,     0, 16384, 24576, 25600, 26112, 
+    25984, 26048, 26049, 26051, 26044,     0, 16384, 24576, 
+    25600, 26112, 25984, 26048, 26049, 26051, 26044, 26046, 
+        0, 16384, 24576, 25600, 26112, 25984,     0, 16384, 
+    24576, 25600, 26112, 26113, 26048,     0, 16384, 24576, 
+    25600, 26112, 26113, 26048,     0, 16384, 24576, 25600, 
+    26112, 26113, 26048, 26050,     0, 16384, 24576, 25600, 
+    26112, 26113, 26048,     0, 16384, 24576, 25600, 26112, 
+    26113, 26048, 26052,     0, 16384, 24576, 25600, 26112, 
+    26113, 26048, 26052,     0, 16384, 24576, 25600, 26112, 
+    26113, 26048, 26056, 26054,     0, 16384, 24576, 25600, 
+    26112, 26113, 26048,     0, 16384, 24576, 25600, 26112, 
+    26113, 26048, 26056,     0, 16384, 24576, 25600, 26112, 
+    26113, 26048, 26056,     0, 16384, 24576, 25600, 26112, 
+    26113, 26048, 26056, 26058,     0, 16384, 24576, 25600, 
+    26112, 26113, 26048, 26056,     0, 16384, 24576, 25600, 
+    26112, 26113, 26048, 26064, 26060,     0, 16384, 24576, 
+    25600, 26112, 26113, 26048, 26064, 26060,     0, 16384, 
+    24576, 25600, 26112, 26113, 26048, 26064, 26065, 26062, 
+        0, 16384, 24576, 25600, 26112, 26113, 26048,     0, 
+    16384, 24576, 25600, 26112, 26113, 26048, 26064,     0, 
+    16384, 24576, 25600, 26112, 26113, 26048, 26064,     0, 
+    16384, 24576, 25600, 26112, 26113, 26048, 26064, 26066, 
+        0, 16384, 24576, 25600, 26112, 26113, 26048, 26064, 
+        0, 16384, 24576, 25600, 26112, 26113, 26048, 26064, 
+    26068,     0, 16384, 24576, 25600, 26112, 26113, 26048, 
+    26064, 26068,     0, 16384, 24576, 25600, 26112, 26113, 
+    26048, 26064, 26072, 26070,     0, 16384, 24576, 25600, 
+    26112, 26113, 26048, 26064,     0, 16384, 24576, 25600, 
+    26112, 26113, 26048, 26080, 26072,     0, 16384, 24576, 
+    25600, 26112, 26113, 26048, 26080, 26072,     0, 16384, 
+    24576, 25600, 26112, 26113, 26048, 26080, 26072, 26074, 
+        0, 16384, 24576, 25600, 26112, 26113, 26048, 26080, 
+    26072,     0, 16384, 24576, 25600, 26112, 26113, 26048, 
+    26080, 26081, 26076,     0, 16384, 24576, 25600, 26112, 
+    26113, 26048, 26080, 26081, 26076,     0, 16384, 24576, 
+    25600, 26112, 26113, 26048, 26080, 26081, 26076, 26078, 
+        0, 16384, 24576, 25600, 26112, 26113, 26048,     0, 
+    16384, 24576, 25600, 26112, 26113, 26048, 26080,     0, 
+    16384, 24576, 25600, 26112, 26113, 26115, 26080,     0, 
+    16384, 24576, 25600, 26112, 26113, 26115, 26080, 26082, 
+        0, 16384, 24576, 25600, 26112, 26113, 26115, 26080, 
+        0, 16384, 24576, 25600, 26112, 26113, 26115, 26080, 
+    26084,     0, 16384, 24576, 25600, 26112, 26113, 26115, 
+    26080, 26084,     0, 16384, 24576, 25600, 26112, 26113, 
+    26115, 26080, 26088, 26086,     0, 16384, 24576, 25600, 
+    26112, 26113, 26115, 26080,     0, 16384, 24576, 25600, 
+    26112, 26113, 26115, 26080, 26088,     0, 16384, 24576, 
+    25600, 26112, 26113, 26115, 26080, 26088,     0, 16384, 
+    24576, 25600, 26112, 26113, 26115, 26080, 26088, 26090, 
+        0, 16384, 24576, 25600, 26112, 26113, 26115, 26080, 
+    26088,     0, 16384, 24576, 25600, 26112, 26113, 26115, 
+    26080, 26096, 26092,     0, 16384, 24576, 25600, 26112, 
+    26113, 26115, 26080, 26096, 26092,     0, 16384, 24576, 
+    25600, 26112, 26113, 26115, 26080, 26096, 26097, 26094, 
+        0, 16384, 24576, 25600, 26112, 26113, 26115, 26080, 
+        0, 16384, 24576, 25600, 26112, 26113, 26115, 26080, 
+    26096,     0, 16384, 24576, 25600, 26112, 26113, 26115, 
+    26080, 26096,     0, 16384, 24576, 25600, 26112, 26113, 
+    26115, 26080, 26096, 26098,     0, 16384, 24576, 25600, 
+    26112, 26113, 26115, 26119, 26096,     0, 16384, 24576, 
+    25600, 26112, 26113, 26115, 26119, 26096, 26100,     0, 
+    16384, 24576, 25600, 26112, 26113, 26115, 26119, 26096, 
+    26100,     0, 16384, 24576, 25600, 26112, 26113, 26115, 
+    26119, 26096, 26104, 26102,     0, 16384, 24576, 25600, 
+    26112, 26113, 26115, 26119, 26096,     0, 16384, 24576, 
+    25600, 26112, 26113, 26115, 26119, 26096, 26104,     0, 
+    16384, 24576, 25600, 26112, 26113, 26115, 26119, 26096, 
+    26104,     0, 16384, 24576, 25600, 26112, 26113, 26115, 
+    26119, 26096, 26104, 26106,     0, 16384, 24576, 25600, 
+    26112, 26113, 26115, 26119, 26096, 26104,     0, 16384, 
+    24576, 25600, 26112, 26113, 26115, 26119, 26096, 26104, 
+    26108,     0, 16384, 24576, 25600, 26112, 26113, 26115, 
+    26119, 26096, 26104, 26108,     0, 16384, 24576, 25600, 
+    26112, 26113, 26115, 26119, 26096, 26104, 26108, 26110, 
+        0, 16384, 24576, 25600,     0, 16384, 24576, 26624, 
+    26112,     0, 16384, 24576, 26624, 26112,     0, 16384, 
+    24576, 26624, 26112, 26114,     0, 16384, 24576, 26624, 
+    26112,     0, 16384, 24576, 26624, 26112, 26116,     0, 
+    16384, 24576, 26624, 26112, 26116,     0, 16384, 24576, 
+    26624, 26112, 26120, 26118,     0, 16384, 24576, 26624, 
+    26112,     0, 16384, 24576, 26624, 26112, 26120,     0, 
+    16384, 24576, 26624, 26112, 26120,     0, 16384, 24576, 
+    26624, 26112, 26120, 26122,     0, 16384, 24576, 26624, 
+    26112, 26120,     0, 16384, 24576, 26624, 26112, 26128, 
+    26124,     0, 16384, 24576, 26624, 26112, 26128, 26124, 
+        0, 16384, 24576, 26624, 26112, 26128, 26129, 26126, 
+        0, 16384, 24576, 26624, 26112,     0, 16384, 24576, 
+    26624, 26112, 26128,     0, 16384, 24576, 26624, 26112, 
+    26128,     0, 16384, 24576, 26624, 26112, 26128, 26130, 
+        0, 16384, 24576, 26624, 26112, 26128,     0, 16384, 
+    24576, 26624, 26112, 26128, 26132,     0, 16384, 24576, 
+    26624, 26112, 26128, 26132,     0, 16384, 24576, 26624, 
+    26112, 26128, 26136, 26134,     0, 16384, 24576, 26624, 
+    26112, 26128,     0, 16384, 24576, 26624, 26112, 26144, 
+    26136,     0, 16384, 24576, 26624, 26112, 26144, 26136, 
+        0, 16384, 24576, 26624, 26112, 26144, 26136, 26138, 
+        0, 16384, 24576, 26624, 26112, 26144, 26136,     0, 
+    16384, 24576, 26624, 26112, 26144, 26145, 26140,     0, 
+    16384, 24576, 26624, 26112, 26144, 26145, 26140,     0, 
+    16384, 24576, 26624, 26112, 26144, 26145, 26140, 26142, 
+        0, 16384, 24576, 26624, 26112,     0, 16384, 24576, 
+    26624, 26112, 26144,     0, 16384, 24576, 26624, 26112, 
+    26144,     0, 16384, 24576, 26624, 26112, 26144, 26146, 
+        0, 16384, 24576, 26624, 26112, 26144,     0, 16384, 
+    24576, 26624, 26112, 26144, 26148,     0, 16384, 24576, 
+    26624, 26112, 26144, 26148,     0, 16384, 24576, 26624, 
+    26112, 26144, 26152, 26150,     0, 16384, 24576, 26624, 
+    26112, 26144,     0, 16384, 24576, 26624, 26112, 26144, 
+    26152,     0, 16384, 24576, 26624, 26112, 26144, 26152, 
+        0, 16384, 24576, 26624, 26112, 26144, 26152, 26154, 
+        0, 16384, 24576, 26624, 26112, 26144, 26152,     0, 
+    16384, 24576, 26624, 26112, 26144, 26160, 26156,     0, 
+    16384, 24576, 26624, 26112, 26144, 26160, 26156,     0, 
+    16384, 24576, 26624, 26112, 26144, 26160, 26161, 26158, 
+        0, 16384, 24576, 26624, 26112, 26144,     0, 16384, 
+    24576, 26624, 26112, 26176, 26160,     0, 16384, 24576, 
+    26624, 26112, 26176, 26160,     0, 16384, 24576, 26624, 
+    26112, 26176, 26160, 26162,     0, 16384, 24576, 26624, 
+    26112, 26176, 26160,     0, 16384, 24576, 26624, 26112, 
+    26176, 26160, 26164,     0, 16384, 24576, 26624, 26112, 
+    26176, 26160, 26164,     0, 16384, 24576, 26624, 26112, 
+    26176, 26160, 26168, 26166,     0, 16384, 24576, 26624, 
+    26112, 26176, 26160,     0, 16384, 24576, 26624, 26112, 
+    26176, 26177, 26168,     0, 16384, 24576, 26624, 26112, 
+    26176, 26177, 26168,     0, 16384, 24576, 26624, 26112, 
+    26176, 26177, 26168, 26170,     0, 16384, 24576, 26624, 
+    26112, 26176, 26177, 26168,     0, 16384, 24576, 26624, 
+    26112, 26176, 26177, 26168, 26172,     0, 16384, 24576, 
+    26624, 26112, 26176, 26177, 26179, 26172,     0, 16384, 
+    24576, 26624, 26112, 26176, 26177, 26179, 26172, 26174, 
+        0, 16384, 24576, 26624, 26112,     0, 16384, 24576, 
+    26624, 26112, 26176,     0, 16384, 24576, 26624, 26112, 
+    26176,     0, 16384, 24576, 26624, 26112, 26176, 26178, 
+        0, 16384, 24576, 26624, 26112, 26176,     0, 16384, 
+    24576, 26624, 26112, 26176, 26180,     0, 16384, 24576, 
+    26624, 26112, 26176, 26180,     0, 16384, 24576, 26624, 
+    26112, 26176, 26184, 26182,     0, 16384, 24576, 26624, 
+    26112, 26176,     0, 16384, 24576, 26624, 26112, 26176, 
+    26184,     0, 16384, 24576, 26624, 26112, 26176, 26184, 
+        0, 16384, 24576, 26624, 26112, 26176, 26184, 26186, 
+        0, 16384, 24576, 26624, 26112, 26176, 26184,     0, 
+    16384, 24576, 26624, 26112, 26176, 26192, 26188,     0, 
+    16384, 24576, 26624, 26112, 26176, 26192, 26188,     0, 
+    16384, 24576, 26624, 26112, 26176, 26192, 26193, 26190, 
+        0, 16384, 24576, 26624, 26112, 26176,     0, 16384, 
+    24576, 26624, 26112, 26176, 26192,     0, 16384, 24576, 
+    26624, 26112, 26176, 26192,     0, 16384, 24576, 26624, 
+    26112, 26176, 26192, 26194,     0, 16384, 24576, 26624, 
+    26112, 26176, 26192,     0, 16384, 24576, 26624, 26112, 
+    26176, 26192, 26196,     0, 16384, 24576, 26624, 26112, 
+    26176, 26192, 26196,     0, 16384, 24576, 26624, 26112, 
+    26176, 26192, 26200, 26198,     0, 16384, 24576, 26624, 
+    26112, 26176, 26192,     0, 16384, 24576, 26624, 26112, 
+    26176, 26208, 26200,     0, 16384, 24576, 26624, 26112, 
+    26176, 26208, 26200,     0, 16384, 24576, 26624, 26112, 
+    26176, 26208, 26200, 26202,     0, 16384, 24576, 26624, 
+    26112, 26176, 26208, 26200,     0, 16384, 24576, 26624, 
+    26112, 26176, 26208, 26209, 26204,     0, 16384, 24576, 
+    26624, 26112, 26176, 26208, 26209, 26204,     0, 16384, 
+    24576, 26624, 26112, 26176, 26208, 26209, 26204, 26206, 
+        0, 16384, 24576, 26624, 26112, 26176,     0, 16384, 
+    24576, 26624, 26112, 26240, 26208,     0, 16384, 24576, 
+    26624, 26112, 26240, 26208,     0, 16384, 24576, 26624, 
+    26112, 26240, 26208, 26210,     0, 16384, 24576, 26624, 
+    26112, 26240, 26208,     0, 16384, 24576, 26624, 26112, 
+    26240, 26208, 26212,     0, 16384, 24576, 26624, 26112, 
+    26240, 26208, 26212,     0, 16384, 24576, 26624, 26112, 
+    26240, 26208, 26216, 26214,     0, 16384, 24576, 26624, 
+    26112, 26240, 26208,     0, 16384, 24576, 26624, 26112, 
+    26240, 26208, 26216,     0, 16384, 24576, 26624, 26112, 
+    26240, 26208, 26216,     0, 16384, 24576, 26624, 26112, 
+    26240, 26208, 26216, 26218,     0, 16384, 24576, 26624, 
+    26112, 26240, 26208, 26216,     0, 16384, 24576, 26624, 
+    26112, 26240, 26208, 26224, 26220,     0, 16384, 24576, 
+    26624, 26112, 26240, 26208, 26224, 26220,     0, 16384, 
+    24576, 26624, 26112, 26240, 26208, 26224, 26225, 26222, 
+        0, 16384, 24576, 26624, 26112, 26240, 26208,     0, 
+    16384, 24576, 26624, 26112, 26240, 26241, 26224,     0, 
+    16384, 24576, 26624, 26112, 26240, 26241, 26224,     0, 
+    16384, 24576, 26624, 26112, 26240, 26241, 26224, 26226, 
+        0, 16384, 24576, 26624, 26112, 26240, 26241, 26224, 
+        0, 16384, 24576, 26624, 26112, 26240, 26241, 26224, 
+    26228,     0, 16384, 24576, 26624, 26112, 26240, 26241, 
+    26224, 26228,     0, 16384, 24576, 26624, 26112, 26240, 
+    26241, 26224, 26232, 26230,     0, 16384, 24576, 26624, 
+    26112, 26240, 26241, 26224,     0, 16384, 24576, 26624, 
+    26112, 26240, 26241, 26224, 26232,     0, 16384, 24576, 
+    26624, 26112, 26240, 26241, 26243, 26232,     0, 16384, 
+    24576, 26624, 26112, 26240, 26241, 26243, 26232, 26234, 
+        0, 16384, 24576, 26624, 26112, 26240, 26241, 26243, 
+    26232,     0, 16384, 24576, 26624, 26112, 26240, 26241, 
+    26243, 26232, 26236,     0, 16384, 24576, 26624, 26112, 
+    26240, 26241, 26243, 26232, 26236,     0, 16384, 24576, 
+    26624, 26112, 26240, 26241, 26243, 26232, 26236, 26238, 
+        0, 16384, 24576, 26624, 26112,     0, 16384, 24576, 
+    26624, 26112, 26240,     0, 16384, 24576, 26624, 26112, 
+    26240,     0, 16384, 24576, 26624, 26112, 26240, 26242, 
+        0, 16384, 24576, 26624, 26112, 26240,     0, 16384, 
+    24576, 26624, 26112, 26240, 26244,     0, 16384, 24576, 
+    26624, 26112, 26240, 26244,     0, 16384, 24576, 26624, 
+    26112, 26240, 26248, 26246,     0, 16384, 24576, 26624, 
+    26112, 26240,     0, 16384, 24576, 26624, 26112, 26240, 
+    26248,     0, 16384, 24576, 26624, 26112, 26240, 26248, 
+        0, 16384, 24576, 26624, 26112, 26240, 26248, 26250, 
+        0, 16384, 24576, 26624, 26112, 26240, 26248,     0, 
+    16384, 24576, 26624, 26112, 26240, 26256, 26252,     0, 
+    16384, 24576, 26624, 26112, 26240, 26256, 26252,     0, 
+    16384, 24576, 26624, 26112, 26240, 26256, 26257, 26254, 
+        0, 16384, 24576, 26624, 26112, 26240,     0, 16384, 
+    24576, 26624, 26112, 26240, 26256,     0, 16384, 24576, 
+    26624, 26112, 26240, 26256,     0, 16384, 24576, 26624, 
+    26112, 26240, 26256, 26258,     0, 16384, 24576, 26624, 
+    26112, 26240, 26256,     0, 16384, 24576, 26624, 26112, 
+    26240, 26256, 26260,     0, 16384, 24576, 26624, 26112, 
+    26240, 26256, 26260,     0, 16384, 24576, 26624, 26112, 
+    26240, 26256, 26264, 26262,     0, 16384, 24576, 26624, 
+    26112, 26240, 26256,     0, 16384, 24576, 26624, 26112, 
+    26240, 26272, 26264,     0, 16384, 24576, 26624, 26112, 
+    26240, 26272, 26264,     0, 16384, 24576, 26624, 26112, 
+    26240, 26272, 26264, 26266,     0, 16384, 24576, 26624, 
+    26112, 26240, 26272, 26264,     0, 16384, 24576, 26624, 
+    26112, 26240, 26272, 26273, 26268,     0, 16384, 24576, 
+    26624, 26112, 26240, 26272, 26273, 26268,     0, 16384, 
+    24576, 26624, 26112, 26240, 26272, 26273, 26268, 26270, 
+        0, 16384, 24576, 26624, 26112, 26240,     0, 16384, 
+    24576, 26624, 26112, 26240, 26272,     0, 16384, 24576, 
+    26624, 26112, 26240, 26272,     0, 16384, 24576, 26624, 
+    26112, 26240, 26272, 26274,     0, 16384, 24576, 26624, 
+    26112, 26240, 26272,     0, 16384, 24576, 26624, 26112, 
+    26240, 26272, 26276,     0, 16384, 24576, 26624, 26112, 
+    26240, 26272, 26276,     0, 16384, 24576, 26624, 26112, 
+    26240, 26272, 26280, 26278,     0, 16384, 24576, 26624, 
+    26112, 26240, 26272,     0, 16384, 24576, 26624, 26112, 
+    26240, 26272, 26280,     0, 16384, 24576, 26624, 26112, 
+    26240, 26272, 26280,     0, 16384, 24576, 26624, 26112, 
+    26240, 26272, 26280, 26282,     0, 16384, 24576, 26624, 
+    26112, 26240, 26272, 26280,     0, 16384, 24576, 26624, 
+    26112, 26240, 26272, 26288, 26284,     0, 16384, 24576, 
+    26624, 26112, 26240, 26272, 26288, 26284,     0, 16384, 
+    24576, 26624, 26112, 26240, 26272, 26288, 26289, 26286, 
+        0, 16384, 24576, 26624, 26112, 26240, 26272,     0, 
+    16384, 24576, 26624, 26112, 26240, 26304, 26288,     0, 
+    16384, 24576, 26624, 26112, 26240, 26304, 26288,     0, 
+    16384, 24576, 26624, 26112, 26240, 26304, 26288, 26290, 
+        0, 16384, 24576, 26624, 26112, 26240, 26304, 26288, 
+        0, 16384, 24576, 26624, 26112, 26240, 26304, 26288, 
+    26292,     0, 16384, 24576, 26624, 26112, 26240, 26304, 
+    26288, 26292,     0, 16384, 24576, 26624, 26112, 26240, 
+    26304, 26288, 26296, 26294,     0, 16384, 24576, 26624, 
+    26112, 26240, 26304, 26288,     0, 16384, 24576, 26624, 
+    26112, 26240, 26304, 26305, 26296,     0, 16384, 24576, 
+    26624, 26112, 26240, 26304, 26305, 26296,     0, 16384, 
+    24576, 26624, 26112, 26240, 26304, 26305, 26296, 26298, 
+        0, 16384, 24576, 26624, 26112, 26240, 26304, 26305, 
+    26296,     0, 16384, 24576, 26624, 26112, 26240, 26304, 
+    26305, 26296, 26300,     0, 16384, 24576, 26624, 26112, 
+    26240, 26304, 26305, 26307, 26300,     0, 16384, 24576, 
+    26624, 26112, 26240, 26304, 26305, 26307, 26300, 26302, 
+        0, 16384, 24576, 26624, 26112, 26240,     0, 16384, 
+    24576, 26624, 26112, 26368, 26304,     0, 16384, 24576, 
+    26624, 26112, 26368, 26304,     0, 16384, 24576, 26624, 
+    26112, 26368, 26304, 26306,     0, 16384, 24576, 26624, 
+    26112, 26368, 26304,     0, 16384, 24576, 26624, 26112, 
+    26368, 26304, 26308,     0, 16384, 24576, 26624, 26112, 
+    26368, 26304, 26308,     0, 16384, 24576, 26624, 26112, 
+    26368, 26304, 26312, 26310,     0, 16384, 24576, 26624, 
+    26112, 26368, 26304,     0, 16384, 24576, 26624, 26112, 
+    26368, 26304, 26312,     0, 16384, 24576, 26624, 26112, 
+    26368, 26304, 26312,     0, 16384, 24576, 26624, 26112, 
+    26368, 26304, 26312, 26314,     0, 16384, 24576, 26624, 
+    26112, 26368, 26304, 26312,     0, 16384, 24576, 26624, 
+    26112, 26368, 26304, 26320, 26316,     0, 16384, 24576, 
+    26624, 26112, 26368, 26304, 26320, 26316,     0, 16384, 
+    24576, 26624, 26112, 26368, 26304, 26320, 26321, 26318, 
+        0, 16384, 24576, 26624, 26112, 26368, 26304,     0, 
+    16384, 24576, 26624, 26112, 26368, 26304, 26320,     0, 
+    16384, 24576, 26624, 26112, 26368, 26304, 26320,     0, 
+    16384, 24576, 26624, 26112, 26368, 26304, 26320, 26322, 
+        0, 16384, 24576, 26624, 26112, 26368, 26304, 26320, 
+        0, 16384, 24576, 26624, 26112, 26368, 26304, 26320, 
+    26324,     0, 16384, 24576, 26624, 26112, 26368, 26304, 
+    26320, 26324,     0, 16384, 24576, 26624, 26112, 26368, 
+    26304, 26320, 26328, 26326,     0, 16384, 24576, 26624, 
+    26112, 26368, 26304, 26320,     0, 16384, 24576, 26624, 
+    26112, 26368, 26304, 26336, 26328,     0, 16384, 24576, 
+    26624, 26112, 26368, 26304, 26336, 26328,     0, 16384, 
+    24576, 26624, 26112, 26368, 26304, 26336, 26328, 26330, 
+        0, 16384, 24576, 26624, 26112, 26368, 26304, 26336, 
+    26328,     0, 16384, 24576, 26624, 26112, 26368, 26304, 
+    26336, 26337, 26332,     0, 16384, 24576, 26624, 26112, 
+    26368, 26304, 26336, 26337, 26332,     0, 16384, 24576, 
+    26624, 26112, 26368, 26304, 26336, 26337, 26332, 26334, 
+        0, 16384, 24576, 26624, 26112, 26368, 26304,     0, 
+    16384, 24576, 26624, 26112, 26368, 26369, 26336,     0, 
+    16384, 24576, 26624, 26112, 26368, 26369, 26336,     0, 
+    16384, 24576, 26624, 26112, 26368, 26369, 26336, 26338, 
+        0, 16384, 24576, 26624, 26112, 26368, 26369, 26336, 
+        0, 16384, 24576, 26624, 26112, 26368, 26369, 26336, 
+    26340,     0, 16384, 24576, 26624, 26112, 26368, 26369, 
+    26336, 26340,     0, 16384, 24576, 26624, 26112, 26368, 
+    26369, 26336, 26344, 26342,     0, 16384, 24576, 26624, 
+    26112, 26368, 26369, 26336,     0, 16384, 24576, 26624, 
+    26112, 26368, 26369, 26336, 26344,     0, 16384, 24576, 
+    26624, 26112, 26368, 26369, 26336, 26344,     0, 16384, 
+    24576, 26624, 26112, 26368, 26369, 26336, 26344, 26346, 
+        0, 16384, 24576, 26624, 26112, 26368, 26369, 26336, 
+    26344,     0, 16384, 24576, 26624, 26112, 26368, 26369, 
+    26336, 26352, 26348,     0, 16384, 24576, 26624, 26112, 
+    26368, 26369, 26336, 26352, 26348,     0, 16384, 24576, 
+    26624, 26112, 26368, 26369, 26336, 26352, 26353, 26350, 
+        0, 16384, 24576, 26624, 26112, 26368, 26369, 26336, 
+        0, 16384, 24576, 26624, 26112, 26368, 26369, 26336, 
+    26352,     0, 16384, 24576, 26624, 26112, 26368, 26369, 
+    26371, 26352,     0, 16384, 24576, 26624, 26112, 26368, 
+    26369, 26371, 26352, 26354,     0, 16384, 24576, 26624, 
+    26112, 26368, 26369, 26371, 26352,     0, 16384, 24576, 
+    26624, 26112, 26368, 26369, 26371, 26352, 26356,     0, 
+    16384, 24576, 26624, 26112, 26368, 26369, 26371, 26352, 
+    26356,     0, 16384, 24576, 26624, 26112, 26368, 26369, 
+    26371, 26352, 26360, 26358,     0, 16384, 24576, 26624, 
+    26112, 26368, 26369, 26371, 26352,     0, 16384, 24576, 
+    26624, 26112, 26368, 26369, 26371, 26352, 26360,     0, 
+    16384, 24576, 26624, 26112, 26368, 26369, 26371, 26352, 
+    26360,     0, 16384, 24576, 26624, 26112, 26368, 26369, 
+    26371, 26352, 26360, 26362,     0, 16384, 24576, 26624, 
+    26112, 26368, 26369, 26371, 26375, 26360,     0, 16384, 
+    24576, 26624, 26112, 26368, 26369, 26371, 26375, 26360, 
+    26364,     0, 16384, 24576, 26624, 26112, 26368, 26369, 
+    26371, 26375, 26360, 26364,     0, 16384, 24576, 26624, 
+    26112, 26368, 26369, 26371, 26375, 26360, 26364, 26366, 
+        0, 16384, 24576, 26624, 26112,     0, 16384, 24576, 
+    26624, 26112, 26368,     0, 16384, 24576, 26624, 26625, 
+    26368,     0, 16384, 24576, 26624, 26625, 26368, 26370, 
+        0, 16384, 24576, 26624, 26625, 26368,     0, 16384, 
+    24576, 26624, 26625, 26368, 26372,     0, 16384, 24576, 
+    26624, 26625, 26368, 26372,     0, 16384, 24576, 26624, 
+    26625, 26368, 26376, 26374,     0, 16384, 24576, 26624, 
+    26625, 26368,     0, 16384, 24576, 26624, 26625, 26368, 
+    26376,     0, 16384, 24576, 26624, 26625, 26368, 26376, 
+        0, 16384, 24576, 26624, 26625, 26368, 26376, 26378, 
+        0, 16384, 24576, 26624, 26625, 26368, 26376,     0, 
+    16384, 24576, 26624, 26625, 26368, 26384, 26380,     0, 
+    16384, 24576, 26624, 26625, 26368, 26384, 26380,     0, 
+    16384, 24576, 26624, 26625, 26368, 26384, 26385, 26382, 
+        0, 16384, 24576, 26624, 26625, 26368,     0, 16384, 
+    24576, 26624, 26625, 26368, 26384,     0, 16384, 24576, 
+    26624, 26625, 26368, 26384,     0, 16384, 24576, 26624, 
+    26625, 26368, 26384, 26386,     0, 16384, 24576, 26624, 
+    26625, 26368, 26384,     0, 16384, 24576, 26624, 26625, 
+    26368, 26384, 26388,     0, 16384, 24576, 26624, 26625, 
+    26368, 26384, 26388,     0, 16384, 24576, 26624, 26625, 
+    26368, 26384, 26392, 26390,     0, 16384, 24576, 26624, 
+    26625, 26368, 26384,     0, 16384, 24576, 26624, 26625, 
+    26368, 26400, 26392,     0, 16384, 24576, 26624, 26625, 
+    26368, 26400, 26392,     0, 16384, 24576, 26624, 26625, 
+    26368, 26400, 26392, 26394,     0, 16384, 24576, 26624, 
+    26625, 26368, 26400, 26392,     0, 16384, 24576, 26624, 
+    26625, 26368, 26400, 26401, 26396,     0, 16384, 24576, 
+    26624, 26625, 26368, 26400, 26401, 26396,     0, 16384, 
+    24576, 26624, 26625, 26368, 26400, 26401, 26396, 26398, 
+        0, 16384, 24576, 26624, 26625, 26368,     0, 16384, 
+    24576, 26624, 26625, 26368, 26400,     0, 16384, 24576, 
+    26624, 26625, 26368, 26400,     0, 16384, 24576, 26624, 
+    26625, 26368, 26400, 26402,     0, 16384, 24576, 26624, 
+    26625, 26368, 26400,     0, 16384, 24576, 26624, 26625, 
+    26368, 26400, 26404,     0, 16384, 24576, 26624, 26625, 
+    26368, 26400, 26404,     0, 16384, 24576, 26624, 26625, 
+    26368, 26400, 26408, 26406,     0, 16384, 24576, 26624, 
+    26625, 26368, 26400,     0, 16384, 24576, 26624, 26625, 
+    26368, 26400, 26408,     0, 16384, 24576, 26624, 26625, 
+    26368, 26400, 26408,     0, 16384, 24576, 26624, 26625, 
+    26368, 26400, 26408, 26410,     0, 16384, 24576, 26624, 
+    26625, 26368, 26400, 26408,     0, 16384, 24576, 26624, 
+    26625, 26368, 26400, 26416, 26412,     0, 16384, 24576, 
+    26624, 26625, 26368, 26400, 26416, 26412,     0, 16384, 
+    24576, 26624, 26625, 26368, 26400, 26416, 26417, 26414, 
+        0, 16384, 24576, 26624, 26625, 26368, 26400,     0, 
+    16384, 24576, 26624, 26625, 26368, 26432, 26416,     0, 
+    16384, 24576, 26624, 26625, 26368, 26432, 26416,     0, 
+    16384, 24576, 26624, 26625, 26368, 26432, 26416, 26418, 
+        0, 16384, 24576, 26624, 26625, 26368, 26432, 26416, 
+        0, 16384, 24576, 26624, 26625, 26368, 26432, 26416, 
+    26420,     0, 16384, 24576, 26624, 26625, 26368, 26432, 
+    26416, 26420,     0, 16384, 24576, 26624, 26625, 26368, 
+    26432, 26416, 26424, 26422,     0, 16384, 24576, 26624, 
+    26625, 26368, 26432, 26416,     0, 16384, 24576, 26624, 
+    26625, 26368, 26432, 26433, 26424,     0, 16384, 24576, 
+    26624, 26625, 26368, 26432, 26433, 26424,     0, 16384, 
+    24576, 26624, 26625, 26368, 26432, 26433, 26424, 26426, 
+        0, 16384, 24576, 26624, 26625, 26368, 26432, 26433, 
+    26424,     0, 16384, 24576, 26624, 26625, 26368, 26432, 
+    26433, 26424, 26428,     0, 16384, 24576, 26624, 26625, 
+    26368, 26432, 26433, 26435, 26428,     0, 16384, 24576, 
+    26624, 26625, 26368, 26432, 26433, 26435, 26428, 26430, 
+        0, 16384, 24576, 26624, 26625, 26368,     0, 16384, 
+    24576, 26624, 26625, 26368, 26432,     0, 16384, 24576, 
+    26624, 26625, 26368, 26432,     0, 16384, 24576, 26624, 
+    26625, 26368, 26432, 26434,     0, 16384, 24576, 26624, 
+    26625, 26368, 26432,     0, 16384, 24576, 26624, 26625, 
+    26368, 26432, 26436,     0, 16384, 24576, 26624, 26625, 
+    26368, 26432, 26436,     0, 16384, 24576, 26624, 26625, 
+    26368, 26432, 26440, 26438,     0, 16384, 24576, 26624, 
+    26625, 26368, 26432,     0, 16384, 24576, 26624, 26625, 
+    26368, 26432, 26440,     0, 16384, 24576, 26624, 26625, 
+    26368, 26432, 26440,     0, 16384, 24576, 26624, 26625, 
+    26368, 26432, 26440, 26442,     0, 16384, 24576, 26624, 
+    26625, 26368, 26432, 26440,     0, 16384, 24576, 26624, 
+    26625, 26368, 26432, 26448, 26444,     0, 16384, 24576, 
+    26624, 26625, 26368, 26432, 26448, 26444,     0, 16384, 
+    24576, 26624, 26625, 26368, 26432, 26448, 26449, 26446, 
+        0, 16384, 24576, 26624, 26625, 26368, 26432,     0, 
+    16384, 24576, 26624, 26625, 26368, 26432, 26448,     0, 
+    16384, 24576, 26624, 26625, 26368, 26432, 26448,     0, 
+    16384, 24576, 26624, 26625, 26368, 26432, 26448, 26450, 
+        0, 16384, 24576, 26624, 26625, 26368, 26432, 26448, 
+        0, 16384, 24576, 26624, 26625, 26368, 26432, 26448, 
+    26452,     0, 16384, 24576, 26624, 26625, 26368, 26432, 
+    26448, 26452,     0, 16384, 24576, 26624, 26625, 26368, 
+    26432, 26448, 26456, 26454,     0, 16384, 24576, 26624, 
+    26625, 26368, 26432, 26448,     0, 16384, 24576, 26624, 
+    26625, 26368, 26432, 26464, 26456,     0, 16384, 24576, 
+    26624, 26625, 26368, 26432, 26464, 26456,     0, 16384, 
+    24576, 26624, 26625, 26368, 26432, 26464, 26456, 26458, 
+        0, 16384, 24576, 26624, 26625, 26368, 26432, 26464, 
+    26456,     0, 16384, 24576, 26624, 26625, 26368, 26432, 
+    26464, 26465, 26460,     0, 16384, 24576, 26624, 26625, 
+    26368, 26432, 26464, 26465, 26460,     0, 16384, 24576, 
+    26624, 26625, 26368, 26432, 26464, 26465, 26460, 26462, 
+        0, 16384, 24576, 26624, 26625, 26368, 26432,     0, 
+    16384, 24576, 26624, 26625, 26368, 26496, 26464,     0, 
+    16384, 24576, 26624, 26625, 26368, 26496, 26464,     0, 
+    16384, 24576, 26624, 26625, 26368, 26496, 26464, 26466, 
+        0, 16384, 24576, 26624, 26625, 26368, 26496, 26464, 
+        0, 16384, 24576, 26624, 26625, 26368, 26496, 26464, 
+    26468,     0, 16384, 24576, 26624, 26625, 26368, 26496, 
+    26464, 26468,     0, 16384, 24576, 26624, 26625, 26368, 
+    26496, 26464, 26472, 26470,     0, 16384, 24576, 26624, 
+    26625, 26368, 26496, 26464,     0, 16384, 24576, 26624, 
+    26625, 26368, 26496, 26464, 26472,     0, 16384, 24576, 
+    26624, 26625, 26368, 26496, 26464, 26472,     0, 16384, 
+    24576, 26624, 26625, 26368, 26496, 26464, 26472, 26474, 
+        0, 16384, 24576, 26624, 26625, 26368, 26496, 26464, 
+    26472,     0, 16384, 24576, 26624, 26625, 26368, 26496, 
+    26464, 26480, 26476,     0, 16384, 24576, 26624, 26625, 
+    26368, 26496, 26464, 26480, 26476,     0, 16384, 24576, 
+    26624, 26625, 26368, 26496, 26464, 26480, 26481, 26478, 
+        0, 16384, 24576, 26624, 26625, 26368, 26496, 26464, 
+        0, 16384, 24576, 26624, 26625, 26368, 26496, 26497, 
+    26480,     0, 16384, 24576, 26624, 26625, 26368, 26496, 
+    26497, 26480,     0, 16384, 24576, 26624, 26625, 26368, 
+    26496, 26497, 26480, 26482,     0, 16384, 24576, 26624, 
+    26625, 26368, 26496, 26497, 26480,     0, 16384, 24576, 
+    26624, 26625, 26368, 26496, 26497, 26480, 26484,     0, 
+    16384, 24576, 26624, 26625, 26368, 26496, 26497, 26480, 
+    26484,     0, 16384, 24576, 26624, 26625, 26368, 26496, 
+    26497, 26480, 26488, 26486,     0, 16384, 24576, 26624, 
+    26625, 26368, 26496, 26497, 26480,     0, 16384, 24576, 
+    26624, 26625, 26368, 26496, 26497, 26480, 26488,     0, 
+    16384, 24576, 26624, 26625, 26368, 26496, 26497, 26499, 
+    26488,     0, 16384, 24576, 26624, 26625, 26368, 26496, 
+    26497, 26499, 26488, 26490,     0, 16384, 24576, 26624, 
+    26625, 26368, 26496, 26497, 26499, 26488,     0, 16384, 
+    24576, 26624, 26625, 26368, 26496, 26497, 26499, 26488, 
+    26492,     0, 16384, 24576, 26624, 26625, 26368, 26496, 
+    26497, 26499, 26488, 26492,     0, 16384, 24576, 26624, 
+    26625, 26368, 26496, 26497, 26499, 26488, 26492, 26494, 
+        0, 16384, 24576, 26624, 26625, 26368,     0, 16384, 
+    24576, 26624, 26625, 26368, 26496,     0, 16384, 24576, 
+    26624, 26625, 26368, 26496,     0, 16384, 24576, 26624, 
+    26625, 26368, 26496, 26498,     0, 16384, 24576, 26624, 
+    26625, 26627, 26496,     0, 16384, 24576, 26624, 26625, 
+    26627, 26496, 26500,     0, 16384, 24576, 26624, 26625, 
+    26627, 26496, 26500,     0, 16384, 24576, 26624, 26625, 
+    26627, 26496, 26504, 26502,     0, 16384, 24576, 26624, 
+    26625, 26627, 26496,     0, 16384, 24576, 26624, 26625, 
+    26627, 26496, 26504,     0, 16384, 24576, 26624, 26625, 
+    26627, 26496, 26504,     0, 16384, 24576, 26624, 26625, 
+    26627, 26496, 26504, 26506,     0, 16384, 24576, 26624, 
+    26625, 26627, 26496, 26504,     0, 16384, 24576, 26624, 
+    26625, 26627, 26496, 26512, 26508,     0, 16384, 24576, 
+    26624, 26625, 26627, 26496, 26512, 26508,     0, 16384, 
+    24576, 26624, 26625, 26627, 26496, 26512, 26513, 26510, 
+        0, 16384, 24576, 26624, 26625, 26627, 26496,     0, 
+    16384, 24576, 26624, 26625, 26627, 26496, 26512,     0, 
+    16384, 24576, 26624, 26625, 26627, 26496, 26512,     0, 
+    16384, 24576, 26624, 26625, 26627, 26496, 26512, 26514, 
+        0, 16384, 24576, 26624, 26625, 26627, 26496, 26512, 
+        0, 16384, 24576, 26624, 26625, 26627, 26496, 26512, 
+    26516,     0, 16384, 24576, 26624, 26625, 26627, 26496, 
+    26512, 26516,     0, 16384, 24576, 26624, 26625, 26627, 
+    26496, 26512, 26520, 26518,     0, 16384, 24576, 26624, 
+    26625, 26627, 26496, 26512,     0, 16384, 24576, 26624, 
+    26625, 26627, 26496, 26528, 26520,     0, 16384, 24576, 
+    26624, 26625, 26627, 26496, 26528, 26520,     0, 16384, 
+    24576, 26624, 26625, 26627, 26496, 26528, 26520, 26522, 
+        0, 16384, 24576, 26624, 26625, 26627, 26496, 26528, 
+    26520,     0, 16384, 24576, 26624, 26625, 26627, 26496, 
+    26528, 26529, 26524,     0, 16384, 24576, 26624, 26625, 
+    26627, 26496, 26528, 26529, 26524,     0, 16384, 24576, 
+    26624, 26625, 26627, 26496, 26528, 26529, 26524, 26526, 
+        0, 16384, 24576, 26624, 26625, 26627, 26496,     0, 
+    16384, 24576, 26624, 26625, 26627, 26496, 26528,     0, 
+    16384, 24576, 26624, 26625, 26627, 26496, 26528,     0, 
+    16384, 24576, 26624, 26625, 26627, 26496, 26528, 26530, 
+        0, 16384, 24576, 26624, 26625, 26627, 26496, 26528, 
+        0, 16384, 24576, 26624, 26625, 26627, 26496, 26528, 
+    26532,     0, 16384, 24576, 26624, 26625, 26627, 26496, 
+    26528, 26532,     0, 16384, 24576, 26624, 26625, 26627, 
+    26496, 26528, 26536, 26534,     0, 16384, 24576, 26624, 
+    26625, 26627, 26496, 26528,     0, 16384, 24576, 26624, 
+    26625, 26627, 26496, 26528, 26536,     0, 16384, 24576, 
+    26624, 26625, 26627, 26496, 26528, 26536,     0, 16384, 
+    24576, 26624, 26625, 26627, 26496, 26528, 26536, 26538, 
+        0, 16384, 24576, 26624, 26625, 26627, 26496, 26528, 
+    26536,     0, 16384, 24576, 26624, 26625, 26627, 26496, 
+    26528, 26544, 26540,     0, 16384, 24576, 26624, 26625, 
+    26627, 26496, 26528, 26544, 26540,     0, 16384, 24576, 
+    26624, 26625, 26627, 26496, 26528, 26544, 26545, 26542, 
+        0, 16384, 24576, 26624, 26625, 26627, 26496, 26528, 
+        0, 16384, 24576, 26624, 26625, 26627, 26496, 26560, 
+    26544,     0, 16384, 24576, 26624, 26625, 26627, 26496, 
+    26560, 26544,     0, 16384, 24576, 26624, 26625, 26627, 
+    26496, 26560, 26544, 26546,     0, 16384, 24576, 26624, 
+    26625, 26627, 26496, 26560, 26544,     0, 16384, 24576, 
+    26624, 26625, 26627, 26496, 26560, 26544, 26548,     0, 
+    16384, 24576, 26624, 26625, 26627, 26496, 26560, 26544, 
+    26548,     0, 16384, 24576, 26624, 26625, 26627, 26496, 
+    26560, 26544, 26552, 26550,     0, 16384, 24576, 26624, 
+    26625, 26627, 26496, 26560, 26544,     0, 16384, 24576, 
+    26624, 26625, 26627, 26496, 26560, 26561, 26552,     0, 
+    16384, 24576, 26624, 26625, 26627, 26496, 26560, 26561, 
+    26552,     0, 16384, 24576, 26624, 26625, 26627, 26496, 
+    26560, 26561, 26552, 26554,     0, 16384, 24576, 26624, 
+    26625, 26627, 26496, 26560, 26561, 26552,     0, 16384, 
+    24576, 26624, 26625, 26627, 26496, 26560, 26561, 26552, 
+    26556,     0, 16384, 24576, 26624, 26625, 26627, 26496, 
+    26560, 26561, 26563, 26556,     0, 16384, 24576, 26624, 
+    26625, 26627, 26496, 26560, 26561, 26563, 26556, 26558, 
+        0, 16384, 24576, 26624, 26625, 26627, 26496,     0, 
+    16384, 24576, 26624, 26625, 26627, 26496, 26560,     0, 
+    16384, 24576, 26624, 26625, 26627, 26496, 26560,     0, 
+    16384, 24576, 26624, 26625, 26627, 26496, 26560, 26562, 
+        0, 16384, 24576, 26624, 26625, 26627, 26496, 26560, 
+        0, 16384, 24576, 26624, 26625, 26627, 26496, 26560, 
+    26564,     0, 16384, 24576, 26624, 26625, 26627, 26496, 
+    26560, 26564,     0, 16384, 24576, 26624, 26625, 26627, 
+    26496, 26560, 26568, 26566,     0, 16384, 24576, 26624, 
+    26625, 26627, 26631, 26560,     0, 16384, 24576, 26624, 
+    26625, 26627, 26631, 26560, 26568,     0, 16384, 24576, 
+    26624, 26625, 26627, 26631, 26560, 26568,     0, 16384, 
+    24576, 26624, 26625, 26627, 26631, 26560, 26568, 26570, 
+        0, 16384, 24576, 26624, 26625, 26627, 26631, 26560, 
+    26568,     0, 16384, 24576, 26624, 26625, 26627, 26631, 
+    26560, 26576, 26572,     0, 16384, 24576, 26624, 26625, 
+    26627, 26631, 26560, 26576, 26572,     0, 16384, 24576, 
+    26624, 26625, 26627, 26631, 26560, 26576, 26577, 26574, 
+        0, 16384, 24576, 26624, 26625, 26627, 26631, 26560, 
+        0, 16384, 24576, 26624, 26625, 26627, 26631, 26560, 
+    26576,     0, 16384, 24576, 26624, 26625, 26627, 26631, 
+    26560, 26576,     0, 16384, 24576, 26624, 26625, 26627, 
+    26631, 26560, 26576, 26578,     0, 16384, 24576, 26624, 
+    26625, 26627, 26631, 26560, 26576,     0, 16384, 24576, 
+    26624, 26625, 26627, 26631, 26560, 26576, 26580,     0, 
+    16384, 24576, 26624, 26625, 26627, 26631, 26560, 26576, 
+    26580,     0, 16384, 24576, 26624, 26625, 26627, 26631, 
+    26560, 26576, 26584, 26582,     0, 16384, 24576, 26624, 
+    26625, 26627, 26631, 26560, 26576,     0, 16384, 24576, 
+    26624, 26625, 26627, 26631, 26560, 26592, 26584,     0, 
+    16384, 24576, 26624, 26625, 26627, 26631, 26560, 26592, 
+    26584,     0, 16384, 24576, 26624, 26625, 26627, 26631, 
+    26560, 26592, 26584, 26586,     0, 16384, 24576, 26624, 
+    26625, 26627, 26631, 26560, 26592, 26584,     0, 16384, 
+    24576, 26624, 26625, 26627, 26631, 26560, 26592, 26593, 
+    26588,     0, 16384, 24576, 26624, 26625, 26627, 26631, 
+    26560, 26592, 26593, 26588,     0, 16384, 24576, 26624, 
+    26625, 26627, 26631, 26560, 26592, 26593, 26588, 26590, 
+        0, 16384, 24576, 26624, 26625, 26627, 26631, 26560, 
+        0, 16384, 24576, 26624, 26625, 26627, 26631, 26560, 
+    26592,     0, 16384, 24576, 26624, 26625, 26627, 26631, 
+    26560, 26592,     0, 16384, 24576, 26624, 26625, 26627, 
+    26631, 26560, 26592, 26594,     0, 16384, 24576, 26624, 
+    26625, 26627, 26631, 26560, 26592,     0, 16384, 24576, 
+    26624, 26625, 26627, 26631, 26560, 26592, 26596,     0, 
+    16384, 24576, 26624, 26625, 26627, 26631, 26560, 26592, 
+    26596,     0, 16384, 24576, 26624, 26625, 26627, 26631, 
+    26560, 26592, 26600, 26598,     0, 16384, 24576, 26624, 
+    26625, 26627, 26631, 26560, 26592,     0, 16384, 24576, 
+    26624, 26625, 26627, 26631, 26560, 26592, 26600,     0, 
+    16384, 24576, 26624, 26625, 26627, 26631, 26560, 26592, 
+    26600,     0, 16384, 24576, 26624, 26625, 26627, 26631, 
+    26560, 26592, 26600, 26602,     0, 16384, 24576, 26624, 
+    26625, 26627, 26631, 26560, 26592, 26600,     0, 16384, 
+    24576, 26624, 26625, 26627, 26631, 26560, 26592, 26608, 
+    26604,     0, 16384, 24576, 26624, 26625, 26627, 26631, 
+    26560, 26592, 26608, 26604,     0, 16384, 24576, 26624, 
+    26625, 26627, 26631, 26560, 26592, 26608, 26609, 26606, 
+        0, 16384, 24576, 26624, 26625, 26627, 26631, 26639, 
+    26592,     0, 16384, 24576, 26624, 26625, 26627, 26631, 
+    26639, 26592, 26608,     0, 16384, 24576, 26624, 26625, 
+    26627, 26631, 26639, 26592, 26608,     0, 16384, 24576, 
+    26624, 26625, 26627, 26631, 26639, 26592, 26608, 26610, 
+        0, 16384, 24576, 26624, 26625, 26627, 26631, 26639, 
+    26592, 26608,     0, 16384, 24576, 26624, 26625, 26627, 
+    26631, 26639, 26592, 26608, 26612,     0, 16384, 24576, 
+    26624, 26625, 26627, 26631, 26639, 26592, 26608, 26612, 
+        0, 16384, 24576, 26624, 26625, 26627, 26631, 26639, 
+    26592, 26608, 26616, 26614,     0, 16384, 24576, 26624, 
+    26625, 26627, 26631, 26639, 26592, 26608,     0, 16384, 
+    24576, 26624, 26625, 26627, 26631, 26639, 26592, 26608, 
+    26616,     0, 16384, 24576, 26624, 26625, 26627, 26631, 
+    26639, 26592, 26608, 26616,     0, 16384, 24576, 26624, 
+    26625, 26627, 26631, 26639, 26592, 26608, 26616, 26618, 
+        0, 16384, 24576, 26624, 26625, 26627, 26631, 26639, 
+    26592, 26608, 26616,     0, 16384, 24576, 26624, 26625, 
+    26627, 26631, 26639, 26592, 26608, 26616, 26620,     0, 
+    16384, 24576, 26624, 26625, 26627, 26631, 26639, 26592, 
+    26608, 26616, 26620,     0, 16384, 24576, 26624, 26625, 
+    26627, 26631, 26639, 26592, 26608, 26616, 26620, 26622, 
+        0, 16384, 24576,     0, 16384, 24576, 26624,     0, 
+    16384, 24576, 26624,     0, 16384, 24576, 26624, 26626, 
+        0, 16384, 24576, 26624,     0, 16384, 24576, 26624, 
+    26628,     0, 16384, 24576, 26624, 26628,     0, 16384, 
+    24576, 26624, 26632, 26630,     0, 16384, 24576, 26624, 
+        0, 16384, 24576, 26624, 26632,     0, 16384, 24576, 
+    26624, 26632,     0, 16384, 24576, 26624, 26632, 26634, 
+        0, 16384, 24576, 26624, 26632,     0, 16384, 24576, 
+    26624, 26640, 26636,     0, 16384, 24576, 26624, 26640, 
+    26636,     0, 16384, 24576, 26624, 26640, 26641, 26638, 
+        0, 16384, 24576, 26624,     0, 16384, 24576, 26624, 
+    26640,     0, 16384, 24576, 26624, 26640,     0, 16384, 
+    24576, 26624, 26640, 26642,     0, 16384, 24576, 26624, 
+    26640,     0, 16384, 24576, 26624, 26640, 26644,     0, 
+    16384, 24576, 26624, 26640, 26644,     0, 16384, 24576, 
+    26624, 26640, 26648, 26646,     0, 16384, 24576, 26624, 
+    26640,     0, 16384, 24576, 26624, 26656, 26648,     0, 
+    16384, 24576, 26624, 26656, 26648,     0, 16384, 24576, 
+    26624, 26656, 26648, 26650,     0, 16384, 24576, 26624, 
+    26656, 26648,     0, 16384, 24576, 26624, 26656, 26657, 
+    26652,     0, 16384, 24576, 26624, 26656, 26657, 26652, 
+        0, 16384, 24576, 26624, 26656, 26657, 26652, 26654, 
+        0, 16384, 24576, 26624,     0, 16384, 24576, 26624, 
+    26656,     0, 16384, 24576, 26624, 26656,     0, 16384, 
+    24576, 26624, 26656, 26658,     0, 16384, 24576, 26624, 
+    26656,     0, 16384, 24576, 26624, 26656, 26660,     0, 
+    16384, 24576, 26624, 26656, 26660,     0, 16384, 24576, 
+    26624, 26656, 26664, 26662,     0, 16384, 24576, 26624, 
+    26656,     0, 16384, 24576, 26624, 26656, 26664,     0, 
+    16384, 24576, 26624, 26656, 26664,     0, 16384, 24576, 
+    26624, 26656, 26664, 26666,     0, 16384, 24576, 26624, 
+    26656, 26664,     0, 16384, 24576, 26624, 26656, 26672, 
+    26668,     0, 16384, 24576, 26624, 26656, 26672, 26668, 
+        0, 16384, 24576, 26624, 26656, 26672, 26673, 26670, 
+        0, 16384, 24576, 26624, 26656,     0, 16384, 24576, 
+    26624, 26688, 26672,     0, 16384, 24576, 26624, 26688, 
+    26672,     0, 16384, 24576, 26624, 26688, 26672, 26674, 
+        0, 16384, 24576, 26624, 26688, 26672,     0, 16384, 
+    24576, 26624, 26688, 26672, 26676,     0, 16384, 24576, 
+    26624, 26688, 26672, 26676,     0, 16384, 24576, 26624, 
+    26688, 26672, 26680, 26678,     0, 16384, 24576, 26624, 
+    26688, 26672,     0, 16384, 24576, 26624, 26688, 26689, 
+    26680,     0, 16384, 24576, 26624, 26688, 26689, 26680, 
+        0, 16384, 24576, 26624, 26688, 26689, 26680, 26682, 
+        0, 16384, 24576, 26624, 26688, 26689, 26680,     0, 
+    16384, 24576, 26624, 26688, 26689, 26680, 26684,     0, 
+    16384, 24576, 26624, 26688, 26689, 26691, 26684,     0, 
+    16384, 24576, 26624, 26688, 26689, 26691, 26684, 26686, 
+        0, 16384, 24576, 26624,     0, 16384, 24576, 26624, 
+    26688,     0, 16384, 24576, 26624, 26688,     0, 16384, 
+    24576, 26624, 26688, 26690,     0, 16384, 24576, 26624, 
+    26688,     0, 16384, 24576, 26624, 26688, 26692,     0, 
+    16384, 24576, 26624, 26688, 26692,     0, 16384, 24576, 
+    26624, 26688, 26696, 26694,     0, 16384, 24576, 26624, 
+    26688,     0, 16384, 24576, 26624, 26688, 26696,     0, 
+    16384, 24576, 26624, 26688, 26696,     0, 16384, 24576, 
+    26624, 26688, 26696, 26698,     0, 16384, 24576, 26624, 
+    26688, 26696,     0, 16384, 24576, 26624, 26688, 26704, 
+    26700,     0, 16384, 24576, 26624, 26688, 26704, 26700, 
+        0, 16384, 24576, 26624, 26688, 26704, 26705, 26702, 
+        0, 16384, 24576, 26624, 26688,     0, 16384, 24576, 
+    26624, 26688, 26704,     0, 16384, 24576, 26624, 26688, 
+    26704,     0, 16384, 24576, 26624, 26688, 26704, 26706, 
+        0, 16384, 24576, 26624, 26688, 26704,     0, 16384, 
+    24576, 26624, 26688, 26704, 26708,     0, 16384, 24576, 
+    26624, 26688, 26704, 26708,     0, 16384, 24576, 26624, 
+    26688, 26704, 26712, 26710,     0, 16384, 24576, 26624, 
+    26688, 26704,     0, 16384, 24576, 26624, 26688, 26720, 
+    26712,     0, 16384, 24576, 26624, 26688, 26720, 26712, 
+        0, 16384, 24576, 26624, 26688, 26720, 26712, 26714, 
+        0, 16384, 24576, 26624, 26688, 26720, 26712,     0, 
+    16384, 24576, 26624, 26688, 26720, 26721, 26716,     0, 
+    16384, 24576, 26624, 26688, 26720, 26721, 26716,     0, 
+    16384, 24576, 26624, 26688, 26720, 26721, 26716, 26718, 
+        0, 16384, 24576, 26624, 26688,     0, 16384, 24576, 
+    26624, 26752, 26720,     0, 16384, 24576, 26624, 26752, 
+    26720,     0, 16384, 24576, 26624, 26752, 26720, 26722, 
+        0, 16384, 24576, 26624, 26752, 26720,     0, 16384, 
+    24576, 26624, 26752, 26720, 26724,     0, 16384, 24576, 
+    26624, 26752, 26720, 26724,     0, 16384, 24576, 26624, 
+    26752, 26720, 26728, 26726,     0, 16384, 24576, 26624, 
+    26752, 26720,     0, 16384, 24576, 26624, 26752, 26720, 
+    26728,     0, 16384, 24576, 26624, 26752, 26720, 26728, 
+        0, 16384, 24576, 26624, 26752, 26720, 26728, 26730, 
+        0, 16384, 24576, 26624, 26752, 26720, 26728,     0, 
+    16384, 24576, 26624, 26752, 26720, 26736, 26732,     0, 
+    16384, 24576, 26624, 26752, 26720, 26736, 26732,     0, 
+    16384, 24576, 26624, 26752, 26720, 26736, 26737, 26734, 
+        0, 16384, 24576, 26624, 26752, 26720,     0, 16384, 
+    24576, 26624, 26752, 26753, 26736,     0, 16384, 24576, 
+    26624, 26752, 26753, 26736,     0, 16384, 24576, 26624, 
+    26752, 26753, 26736, 26738,     0, 16384, 24576, 26624, 
+    26752, 26753, 26736,     0, 16384, 24576, 26624, 26752, 
+    26753, 26736, 26740,     0, 16384, 24576, 26624, 26752, 
+    26753, 26736, 26740,     0, 16384, 24576, 26624, 26752, 
+    26753, 26736, 26744, 26742,     0, 16384, 24576, 26624, 
+    26752, 26753, 26736,     0, 16384, 24576, 26624, 26752, 
+    26753, 26736, 26744,     0, 16384, 24576, 26624, 26752, 
+    26753, 26755, 26744,     0, 16384, 24576, 26624, 26752, 
+    26753, 26755, 26744, 26746,     0, 16384, 24576, 26624, 
+    26752, 26753, 26755, 26744,     0, 16384, 24576, 26624, 
+    26752, 26753, 26755, 26744, 26748,     0, 16384, 24576, 
+    26624, 26752, 26753, 26755, 26744, 26748,     0, 16384, 
+    24576, 26624, 26752, 26753, 26755, 26744, 26748, 26750, 
+        0, 16384, 24576, 26624,     0, 16384, 24576, 26624, 
+    26752,     0, 16384, 24576, 26624, 26752,     0, 16384, 
+    24576, 26624, 26752, 26754,     0, 16384, 24576, 26624, 
+    26752,     0, 16384, 24576, 26624, 26752, 26756,     0, 
+    16384, 24576, 26624, 26752, 26756,     0, 16384, 24576, 
+    26624, 26752, 26760, 26758,     0, 16384, 24576, 26624, 
+    26752,     0, 16384, 24576, 26624, 26752, 26760,     0, 
+    16384, 24576, 26624, 26752, 26760,     0, 16384, 24576, 
+    26624, 26752, 26760, 26762,     0, 16384, 24576, 26624, 
+    26752, 26760,     0, 16384, 24576, 26624, 26752, 26768, 
+    26764,     0, 16384, 24576, 26624, 26752, 26768, 26764, 
+        0, 16384, 24576, 26624, 26752, 26768, 26769, 26766, 
+        0, 16384, 24576, 26624, 26752,     0, 16384, 24576, 
+    26624, 26752, 26768,     0, 16384, 24576, 26624, 26752, 
+    26768,     0, 16384, 24576, 26624, 26752, 26768, 26770, 
+        0, 16384, 24576, 26624, 26752, 26768,     0, 16384, 
+    24576, 26624, 26752, 26768, 26772,     0, 16384, 24576, 
+    26624, 26752, 26768, 26772,     0, 16384, 24576, 26624, 
+    26752, 26768, 26776, 26774,     0, 16384, 24576, 26624, 
+    26752, 26768,     0, 16384, 24576, 26624, 26752, 26784, 
+    26776,     0, 16384, 24576, 26624, 26752, 26784, 26776, 
+        0, 16384, 24576, 26624, 26752, 26784, 26776, 26778, 
+        0, 16384, 24576, 26624, 26752, 26784, 26776,     0, 
+    16384, 24576, 26624, 26752, 26784, 26785, 26780,     0, 
+    16384, 24576, 26624, 26752, 26784, 26785, 26780,     0, 
+    16384, 24576, 26624, 26752, 26784, 26785, 26780, 26782, 
+        0, 16384, 24576, 26624, 26752,     0, 16384, 24576, 
+    26624, 26752, 26784,     0, 16384, 24576, 26624, 26752, 
+    26784,     0, 16384, 24576, 26624, 26752, 26784, 26786, 
+        0, 16384, 24576, 26624, 26752, 26784,     0, 16384, 
+    24576, 26624, 26752, 26784, 26788,     0, 16384, 24576, 
+    26624, 26752, 26784, 26788,     0, 16384, 24576, 26624, 
+    26752, 26784, 26792, 26790,     0, 16384, 24576, 26624, 
+    26752, 26784,     0, 16384, 24576, 26624, 26752, 26784, 
+    26792,     0, 16384, 24576, 26624, 26752, 26784, 26792, 
+        0, 16384, 24576, 26624, 26752, 26784, 26792, 26794, 
+        0, 16384, 24576, 26624, 26752, 26784, 26792,     0, 
+    16384, 24576, 26624, 26752, 26784, 26800, 26796,     0, 
+    16384, 24576, 26624, 26752, 26784, 26800, 26796,     0, 
+    16384, 24576, 26624, 26752, 26784, 26800, 26801, 26798, 
+        0, 16384, 24576, 26624, 26752, 26784,     0, 16384, 
+    24576, 26624, 26752, 26816, 26800,     0, 16384, 24576, 
+    26624, 26752, 26816, 26800,     0, 16384, 24576, 26624, 
+    26752, 26816, 26800, 26802,     0, 16384, 24576, 26624, 
+    26752, 26816, 26800,     0, 16384, 24576, 26624, 26752, 
+    26816, 26800, 26804,     0, 16384, 24576, 26624, 26752, 
+    26816, 26800, 26804,     0, 16384, 24576, 26624, 26752, 
+    26816, 26800, 26808, 26806,     0, 16384, 24576, 26624, 
+    26752, 26816, 26800,     0, 16384, 24576, 26624, 26752, 
+    26816, 26817, 26808,     0, 16384, 24576, 26624, 26752, 
+    26816, 26817, 26808,     0, 16384, 24576, 26624, 26752, 
+    26816, 26817, 26808, 26810,     0, 16384, 24576, 26624, 
+    26752, 26816, 26817, 26808,     0, 16384, 24576, 26624, 
+    26752, 26816, 26817, 26808, 26812,     0, 16384, 24576, 
+    26624, 26752, 26816, 26817, 26819, 26812,     0, 16384, 
+    24576, 26624, 26752, 26816, 26817, 26819, 26812, 26814, 
+        0, 16384, 24576, 26624, 26752,     0, 16384, 24576, 
+    26624, 26880, 26816,     0, 16384, 24576, 26624, 26880, 
+    26816,     0, 16384, 24576, 26624, 26880, 26816, 26818, 
+        0, 16384, 24576, 26624, 26880, 26816,     0, 16384, 
+    24576, 26624, 26880, 26816, 26820,     0, 16384, 24576, 
+    26624, 26880, 26816, 26820,     0, 16384, 24576, 26624, 
+    26880, 26816, 26824, 26822,     0, 16384, 24576, 26624, 
+    26880, 26816,     0, 16384, 24576, 26624, 26880, 26816, 
+    26824,     0, 16384, 24576, 26624, 26880, 26816, 26824, 
+        0, 16384, 24576, 26624, 26880, 26816, 26824, 26826, 
+        0, 16384, 24576, 26624, 26880, 26816, 26824,     0, 
+    16384, 24576, 26624, 26880, 26816, 26832, 26828,     0, 
+    16384, 24576, 26624, 26880, 26816, 26832, 26828,     0, 
+    16384, 24576, 26624, 26880, 26816, 26832, 26833, 26830, 
+        0, 16384, 24576, 26624, 26880, 26816,     0, 16384, 
+    24576, 26624, 26880, 26816, 26832,     0, 16384, 24576, 
+    26624, 26880, 26816, 26832,     0, 16384, 24576, 26624, 
+    26880, 26816, 26832, 26834,     0, 16384, 24576, 26624, 
+    26880, 26816, 26832,     0, 16384, 24576, 26624, 26880, 
+    26816, 26832, 26836,     0, 16384, 24576, 26624, 26880, 
+    26816, 26832, 26836,     0, 16384, 24576, 26624, 26880, 
+    26816, 26832, 26840, 26838,     0, 16384, 24576, 26624, 
+    26880, 26816, 26832,     0, 16384, 24576, 26624, 26880, 
+    26816, 26848, 26840,     0, 16384, 24576, 26624, 26880, 
+    26816, 26848, 26840,     0, 16384, 24576, 26624, 26880, 
+    26816, 26848, 26840, 26842,     0, 16384, 24576, 26624, 
+    26880, 26816, 26848, 26840,     0, 16384, 24576, 26624, 
+    26880, 26816, 26848, 26849, 26844,     0, 16384, 24576, 
+    26624, 26880, 26816, 26848, 26849, 26844,     0, 16384, 
+    24576, 26624, 26880, 26816, 26848, 26849, 26844, 26846, 
+        0, 16384, 24576, 26624, 26880, 26816,     0, 16384, 
+    24576, 26624, 26880, 26881, 26848,     0, 16384, 24576, 
+    26624, 26880, 26881, 26848,     0, 16384, 24576, 26624, 
+    26880, 26881, 26848, 26850,     0, 16384, 24576, 26624, 
+    26880, 26881, 26848,     0, 16384, 24576, 26624, 26880, 
+    26881, 26848, 26852,     0, 16384, 24576, 26624, 26880, 
+    26881, 26848, 26852,     0, 16384, 24576, 26624, 26880, 
+    26881, 26848, 26856, 26854,     0, 16384, 24576, 26624, 
+    26880, 26881, 26848,     0, 16384, 24576, 26624, 26880, 
+    26881, 26848, 26856,     0, 16384, 24576, 26624, 26880, 
+    26881, 26848, 26856,     0, 16384, 24576, 26624, 26880, 
+    26881, 26848, 26856, 26858,     0, 16384, 24576, 26624, 
+    26880, 26881, 26848, 26856,     0, 16384, 24576, 26624, 
+    26880, 26881, 26848, 26864, 26860,     0, 16384, 24576, 
+    26624, 26880, 26881, 26848, 26864, 26860,     0, 16384, 
+    24576, 26624, 26880, 26881, 26848, 26864, 26865, 26862, 
+        0, 16384, 24576, 26624, 26880, 26881, 26848,     0, 
+    16384, 24576, 26624, 26880, 26881, 26848, 26864,     0, 
+    16384, 24576, 26624, 26880, 26881, 26883, 26864,     0, 
+    16384, 24576, 26624, 26880, 26881, 26883, 26864, 26866, 
+        0, 16384, 24576, 26624, 26880, 26881, 26883, 26864, 
+        0, 16384, 24576, 26624, 26880, 26881, 26883, 26864, 
+    26868,     0, 16384, 24576, 26624, 26880, 26881, 26883, 
+    26864, 26868,     0, 16384, 24576, 26624, 26880, 26881, 
+    26883, 26864, 26872, 26870,     0, 16384, 24576, 26624, 
+    26880, 26881, 26883, 26864,     0, 16384, 24576, 26624, 
+    26880, 26881, 26883, 26864, 26872,     0, 16384, 24576, 
+    26624, 26880, 26881, 26883, 26864, 26872,     0, 16384, 
+    24576, 26624, 26880, 26881, 26883, 26864, 26872, 26874, 
+        0, 16384, 24576, 26624, 26880, 26881, 26883, 26887, 
+    26872,     0, 16384, 24576, 26624, 26880, 26881, 26883, 
+    26887, 26872, 26876,     0, 16384, 24576, 26624, 26880, 
+    26881, 26883, 26887, 26872, 26876,     0, 16384, 24576, 
+    26624, 26880, 26881, 26883, 26887, 26872, 26876, 26878, 
+        0, 16384, 24576, 26624,     0, 16384, 24576, 26624, 
+    26880,     0, 16384, 24576, 26624, 26880,     0, 16384, 
+    24576, 26624, 26880, 26882,     0, 16384, 24576, 26624, 
+    26880,     0, 16384, 24576, 26624, 26880, 26884,     0, 
+    16384, 24576, 26624, 26880, 26884,     0, 16384, 24576, 
+    26624, 26880, 26888, 26886,     0, 16384, 24576, 26624, 
+    26880,     0, 16384, 24576, 26624, 26880, 26888,     0, 
+    16384, 24576, 26624, 26880, 26888,     0, 16384, 24576, 
+    26624, 26880, 26888, 26890,     0, 16384, 24576, 26624, 
+    26880, 26888,     0, 16384, 24576, 26624, 26880, 26896, 
+    26892,     0, 16384, 24576, 26624, 26880, 26896, 26892, 
+        0, 16384, 24576, 26624, 26880, 26896, 26897, 26894, 
+        0, 16384, 24576, 26624, 26880,     0, 16384, 24576, 
+    26624, 26880, 26896,     0, 16384, 24576, 26624, 26880, 
+    26896,     0, 16384, 24576, 26624, 26880, 26896, 26898, 
+        0, 16384, 24576, 26624, 26880, 26896,     0, 16384, 
+    24576, 26624, 26880, 26896, 26900,     0, 16384, 24576, 
+    26624, 26880, 26896, 26900,     0, 16384, 24576, 26624, 
+    26880, 26896, 26904, 26902,     0, 16384, 24576, 26624, 
+    26880, 26896,     0, 16384, 24576, 26624, 26880, 26912, 
+    26904,     0, 16384, 24576, 26624, 26880, 26912, 26904, 
+        0, 16384, 24576, 26624, 26880, 26912, 26904, 26906, 
+        0, 16384, 24576, 26624, 26880, 26912, 26904,     0, 
+    16384, 24576, 26624, 26880, 26912, 26913, 26908,     0, 
+    16384, 24576, 26624, 26880, 26912, 26913, 26908,     0, 
+    16384, 24576, 26624, 26880, 26912, 26913, 26908, 26910, 
+        0, 16384, 24576, 26624, 26880,     0, 16384, 24576, 
+    26624, 26880, 26912,     0, 16384, 24576, 26624, 26880, 
+    26912,     0, 16384, 24576, 26624, 26880, 26912, 26914, 
+        0, 16384, 24576, 26624, 26880, 26912,     0, 16384, 
+    24576, 26624, 26880, 26912, 26916,     0, 16384, 24576, 
+    26624, 26880, 26912, 26916,     0, 16384, 24576, 26624, 
+    26880, 26912, 26920, 26918,     0, 16384, 24576, 26624, 
+    26880, 26912,     0, 16384, 24576, 26624, 26880, 26912, 
+    26920,     0, 16384, 24576, 26624, 26880, 26912, 26920, 
+        0, 16384, 24576, 26624, 26880, 26912, 26920, 26922, 
+        0, 16384, 24576, 26624, 26880, 26912, 26920,     0, 
+    16384, 24576, 26624, 26880, 26912, 26928, 26924,     0, 
+    16384, 24576, 26624, 26880, 26912, 26928, 26924,     0, 
+    16384, 24576, 26624, 26880, 26912, 26928, 26929, 26926, 
+        0, 16384, 24576, 26624, 26880, 26912,     0, 16384, 
+    24576, 26624, 26880, 26944, 26928,     0, 16384, 24576, 
+    26624, 26880, 26944, 26928,     0, 16384, 24576, 26624, 
+    26880, 26944, 26928, 26930,     0, 16384, 24576, 26624, 
+    26880, 26944, 26928,     0, 16384, 24576, 26624, 26880, 
+    26944, 26928, 26932,     0, 16384, 24576, 26624, 26880, 
+    26944, 26928, 26932,     0, 16384, 24576, 26624, 26880, 
+    26944, 26928, 26936, 26934,     0, 16384, 24576, 26624, 
+    26880, 26944, 26928,     0, 16384, 24576, 26624, 26880, 
+    26944, 26945, 26936,     0, 16384, 24576, 26624, 26880, 
+    26944, 26945, 26936,     0, 16384, 24576, 26624, 26880, 
+    26944, 26945, 26936, 26938,     0, 16384, 24576, 26624, 
+    26880, 26944, 26945, 26936,     0, 16384, 24576, 26624, 
+    26880, 26944, 26945, 26936, 26940,     0, 16384, 24576, 
+    26624, 26880, 26944, 26945, 26947, 26940,     0, 16384, 
+    24576, 26624, 26880, 26944, 26945, 26947, 26940, 26942, 
+        0, 16384, 24576, 26624, 26880,     0, 16384, 24576, 
+    26624, 26880, 26944,     0, 16384, 24576, 26624, 26880, 
+    26944,     0, 16384, 24576, 26624, 26880, 26944, 26946, 
+        0, 16384, 24576, 26624, 26880, 26944,     0, 16384, 
+    24576, 26624, 26880, 26944, 26948,     0, 16384, 24576, 
+    26624, 26880, 26944, 26948,     0, 16384, 24576, 26624, 
+    26880, 26944, 26952, 26950,     0, 16384, 24576, 26624, 
+    26880, 26944,     0, 16384, 24576, 26624, 26880, 26944, 
+    26952,     0, 16384, 24576, 26624, 26880, 26944, 26952, 
+        0, 16384, 24576, 26624, 26880, 26944, 26952, 26954, 
+        0, 16384, 24576, 26624, 26880, 26944, 26952,     0, 
+    16384, 24576, 26624, 26880, 26944, 26960, 26956,     0, 
+    16384, 24576, 26624, 26880, 26944, 26960, 26956,     0, 
+    16384, 24576, 26624, 26880, 26944, 26960, 26961, 26958, 
+        0, 16384, 24576, 26624, 26880, 26944,     0, 16384, 
+    24576, 26624, 26880, 26944, 26960,     0, 16384, 24576, 
+    26624, 26880, 26944, 26960,     0, 16384, 24576, 26624, 
+    26880, 26944, 26960, 26962,     0, 16384, 24576, 26624, 
+    26880, 26944, 26960,     0, 16384, 24576, 26624, 26880, 
+    26944, 26960, 26964,     0, 16384, 24576, 26624, 26880, 
+    26944, 26960, 26964,     0, 16384, 24576, 26624, 26880, 
+    26944, 26960, 26968, 26966,     0, 16384, 24576, 26624, 
+    26880, 26944, 26960,     0, 16384, 24576, 26624, 26880, 
+    26944, 26976, 26968,     0, 16384, 24576, 26624, 26880, 
+    26944, 26976, 26968,     0, 16384, 24576, 26624, 26880, 
+    26944, 26976, 26968, 26970,     0, 16384, 24576, 26624, 
+    26880, 26944, 26976, 26968,     0, 16384, 24576, 26624, 
+    26880, 26944, 26976, 26977, 26972,     0, 16384, 24576, 
+    26624, 26880, 26944, 26976, 26977, 26972,     0, 16384, 
+    24576, 26624, 26880, 26944, 26976, 26977, 26972, 26974, 
+        0, 16384, 24576, 26624, 26880, 26944,     0, 16384, 
+    24576, 26624, 26880, 27008, 26976,     0, 16384, 24576, 
+    26624, 26880, 27008, 26976,     0, 16384, 24576, 26624, 
+    26880, 27008, 26976, 26978,     0, 16384, 24576, 26624, 
+    26880, 27008, 26976,     0, 16384, 24576, 26624, 26880, 
+    27008, 26976, 26980,     0, 16384, 24576, 26624, 26880, 
+    27008, 26976, 26980,     0, 16384, 24576, 26624, 26880, 
+    27008, 26976, 26984, 26982,     0, 16384, 24576, 26624, 
+    26880, 27008, 26976,     0, 16384, 24576, 26624, 26880, 
+    27008, 26976, 26984,     0, 16384, 24576, 26624, 26880, 
+    27008, 26976, 26984,     0, 16384, 24576, 26624, 26880, 
+    27008, 26976, 26984, 26986,     0, 16384, 24576, 26624, 
+    26880, 27008, 26976, 26984,     0, 16384, 24576, 26624, 
+    26880, 27008, 26976, 26992, 26988,     0, 16384, 24576, 
+    26624, 26880, 27008, 26976, 26992, 26988,     0, 16384, 
+    24576, 26624, 26880, 27008, 26976, 26992, 26993, 26990, 
+        0, 16384, 24576, 26624, 26880, 27008, 26976,     0, 
+    16384, 24576, 26624, 26880, 27008, 27009, 26992,     0, 
+    16384, 24576, 26624, 26880, 27008, 27009, 26992,     0, 
+    16384, 24576, 26624, 26880, 27008, 27009, 26992, 26994, 
+        0, 16384, 24576, 26624, 26880, 27008, 27009, 26992, 
+        0, 16384, 24576, 26624, 26880, 27008, 27009, 26992, 
+    26996,     0, 16384, 24576, 26624, 26880, 27008, 27009, 
+    26992, 26996,     0, 16384, 24576, 26624, 26880, 27008, 
+    27009, 26992, 27000, 26998,     0, 16384, 24576, 26624, 
+    26880, 27008, 27009, 26992,     0, 16384, 24576, 26624, 
+    26880, 27008, 27009, 26992, 27000,     0, 16384, 24576, 
+    26624, 26880, 27008, 27009, 27011, 27000,     0, 16384, 
+    24576, 26624, 26880, 27008, 27009, 27011, 27000, 27002, 
+        0, 16384, 24576, 26624, 26880, 27008, 27009, 27011, 
+    27000,     0, 16384, 24576, 26624, 26880, 27008, 27009, 
+    27011, 27000, 27004,     0, 16384, 24576, 26624, 26880, 
+    27008, 27009, 27011, 27000, 27004,     0, 16384, 24576, 
+    26624, 26880, 27008, 27009, 27011, 27000, 27004, 27006, 
+        0, 16384, 24576, 26624, 26880,     0, 16384, 24576, 
+    26624, 27136, 27008,     0, 16384, 24576, 26624, 27136, 
+    27008,     0, 16384, 24576, 26624, 27136, 27008, 27010, 
+        0, 16384, 24576, 26624, 27136, 27008,     0, 16384, 
+    24576, 26624, 27136, 27008, 27012,     0, 16384, 24576, 
+    26624, 27136, 27008, 27012,     0, 16384, 24576, 26624, 
+    27136, 27008, 27016, 27014,     0, 16384, 24576, 26624, 
+    27136, 27008,     0, 16384, 24576, 26624, 27136, 27008, 
+    27016,     0, 16384, 24576, 26624, 27136, 27008, 27016, 
+        0, 16384, 24576, 26624, 27136, 27008, 27016, 27018, 
+        0, 16384, 24576, 26624, 27136, 27008, 27016,     0, 
+    16384, 24576, 26624, 27136, 27008, 27024, 27020,     0, 
+    16384, 24576, 26624, 27136, 27008, 27024, 27020,     0, 
+    16384, 24576, 26624, 27136, 27008, 27024, 27025, 27022, 
+        0, 16384, 24576, 26624, 27136, 27008,     0, 16384, 
+    24576, 26624, 27136, 27008, 27024,     0, 16384, 24576, 
+    26624, 27136, 27008, 27024,     0, 16384, 24576, 26624, 
+    27136, 27008, 27024, 27026,     0, 16384, 24576, 26624, 
+    27136, 27008, 27024,     0, 16384, 24576, 26624, 27136, 
+    27008, 27024, 27028,     0, 16384, 24576, 26624, 27136, 
+    27008, 27024, 27028,     0, 16384, 24576, 26624, 27136, 
+    27008, 27024, 27032, 27030,     0, 16384, 24576, 26624, 
+    27136, 27008, 27024,     0, 16384, 24576, 26624, 27136, 
+    27008, 27040, 27032,     0, 16384, 24576, 26624, 27136, 
+    27008, 27040, 27032,     0, 16384, 24576, 26624, 27136, 
+    27008, 27040, 27032, 27034,     0, 16384, 24576, 26624, 
+    27136, 27008, 27040, 27032,     0, 16384, 24576, 26624, 
+    27136, 27008, 27040, 27041, 27036,     0, 16384, 24576, 
+    26624, 27136, 27008, 27040, 27041, 27036,     0, 16384, 
+    24576, 26624, 27136, 27008, 27040, 27041, 27036, 27038, 
+        0, 16384, 24576, 26624, 27136, 27008,     0, 16384, 
+    24576, 26624, 27136, 27008, 27040,     0, 16384, 24576, 
+    26624, 27136, 27008, 27040,     0, 16384, 24576, 26624, 
+    27136, 27008, 27040, 27042,     0, 16384, 24576, 26624, 
+    27136, 27008, 27040,     0, 16384, 24576, 26624, 27136, 
+    27008, 27040, 27044,     0, 16384, 24576, 26624, 27136, 
+    27008, 27040, 27044,     0, 16384, 24576, 26624, 27136, 
+    27008, 27040, 27048, 27046,     0, 16384, 24576, 26624, 
+    27136, 27008, 27040,     0, 16384, 24576, 26624, 27136, 
+    27008, 27040, 27048,     0, 16384, 24576, 26624, 27136, 
+    27008, 27040, 27048,     0, 16384, 24576, 26624, 27136, 
+    27008, 27040, 27048, 27050,     0, 16384, 24576, 26624, 
+    27136, 27008, 27040, 27048,     0, 16384, 24576, 26624, 
+    27136, 27008, 27040, 27056, 27052,     0, 16384, 24576, 
+    26624, 27136, 27008, 27040, 27056, 27052,     0, 16384, 
+    24576, 26624, 27136, 27008, 27040, 27056, 27057, 27054, 
+        0, 16384, 24576, 26624, 27136, 27008, 27040,     0, 
+    16384, 24576, 26624, 27136, 27008, 27072, 27056,     0, 
+    16384, 24576, 26624, 27136, 27008, 27072, 27056,     0, 
+    16384, 24576, 26624, 27136, 27008, 27072, 27056, 27058, 
+        0, 16384, 24576, 26624, 27136, 27008, 27072, 27056, 
+        0, 16384, 24576, 26624, 27136, 27008, 27072, 27056, 
+    27060,     0, 16384, 24576, 26624, 27136, 27008, 27072, 
+    27056, 27060,     0, 16384, 24576, 26624, 27136, 27008, 
+    27072, 27056, 27064, 27062,     0, 16384, 24576, 26624, 
+    27136, 27008, 27072, 27056,     0, 16384, 24576, 26624, 
+    27136, 27008, 27072, 27073, 27064,     0, 16384, 24576, 
+    26624, 27136, 27008, 27072, 27073, 27064,     0, 16384, 
+    24576, 26624, 27136, 27008, 27072, 27073, 27064, 27066, 
+        0, 16384, 24576, 26624, 27136, 27008, 27072, 27073, 
+    27064,     0, 16384, 24576, 26624, 27136, 27008, 27072, 
+    27073, 27064, 27068,     0, 16384, 24576, 26624, 27136, 
+    27008, 27072, 27073, 27075, 27068,     0, 16384, 24576, 
+    26624, 27136, 27008, 27072, 27073, 27075, 27068, 27070, 
+        0, 16384, 24576, 26624, 27136, 27008,     0, 16384, 
+    24576, 26624, 27136, 27137, 27072,     0, 16384, 24576, 
+    26624, 27136, 27137, 27072,     0, 16384, 24576, 26624, 
+    27136, 27137, 27072, 27074,     0, 16384, 24576, 26624, 
+    27136, 27137, 27072,     0, 16384, 24576, 26624, 27136, 
+    27137, 27072, 27076,     0, 16384, 24576, 26624, 27136, 
+    27137, 27072, 27076,     0, 16384, 24576, 26624, 27136, 
+    27137, 27072, 27080, 27078,     0, 16384, 24576, 26624, 
+    27136, 27137, 27072,     0, 16384, 24576, 26624, 27136, 
+    27137, 27072, 27080,     0, 16384, 24576, 26624, 27136, 
+    27137, 27072, 27080,     0, 16384, 24576, 26624, 27136, 
+    27137, 27072, 27080, 27082,     0, 16384, 24576, 26624, 
+    27136, 27137, 27072, 27080,     0, 16384, 24576, 26624, 
+    27136, 27137, 27072, 27088, 27084,     0, 16384, 24576, 
+    26624, 27136, 27137, 27072, 27088, 27084,     0, 16384, 
+    24576, 26624, 27136, 27137, 27072, 27088, 27089, 27086, 
+        0, 16384, 24576, 26624, 27136, 27137, 27072,     0, 
+    16384, 24576, 26624, 27136, 27137, 27072, 27088,     0, 
+    16384, 24576, 26624, 27136, 27137, 27072, 27088,     0, 
+    16384, 24576, 26624, 27136, 27137, 27072, 27088, 27090, 
+        0, 16384, 24576, 26624, 27136, 27137, 27072, 27088, 
+        0, 16384, 24576, 26624, 27136, 27137, 27072, 27088, 
+    27092,     0, 16384, 24576, 26624, 27136, 27137, 27072, 
+    27088, 27092,     0, 16384, 24576, 26624, 27136, 27137, 
+    27072, 27088, 27096, 27094,     0, 16384, 24576, 26624, 
+    27136, 27137, 27072, 27088,     0, 16384, 24576, 26624, 
+    27136, 27137, 27072, 27104, 27096,     0, 16384, 24576, 
+    26624, 27136, 27137, 27072, 27104, 27096,     0, 16384, 
+    24576, 26624, 27136, 27137, 27072, 27104, 27096, 27098, 
+        0, 16384, 24576, 26624, 27136, 27137, 27072, 27104, 
+    27096,     0, 16384, 24576, 26624, 27136, 27137, 27072, 
+    27104, 27105, 27100,     0, 16384, 24576, 26624, 27136, 
+    27137, 27072, 27104, 27105, 27100,     0, 16384, 24576, 
+    26624, 27136, 27137, 27072, 27104, 27105, 27100, 27102, 
+        0, 16384, 24576, 26624, 27136, 27137, 27072,     0, 
+    16384, 24576, 26624, 27136, 27137, 27072, 27104,     0, 
+    16384, 24576, 26624, 27136, 27137, 27139, 27104,     0, 
+    16384, 24576, 26624, 27136, 27137, 27139, 27104, 27106, 
+        0, 16384, 24576, 26624, 27136, 27137, 27139, 27104, 
+        0, 16384, 24576, 26624, 27136, 27137, 27139, 27104, 
+    27108,     0, 16384, 24576, 26624, 27136, 27137, 27139, 
+    27104, 27108,     0, 16384, 24576, 26624, 27136, 27137, 
+    27139, 27104, 27112, 27110,     0, 16384, 24576, 26624, 
+    27136, 27137, 27139, 27104,     0, 16384, 24576, 26624, 
+    27136, 27137, 27139, 27104, 27112,     0, 16384, 24576, 
+    26624, 27136, 27137, 27139, 27104, 27112,     0, 16384, 
+    24576, 26624, 27136, 27137, 27139, 27104, 27112, 27114, 
+        0, 16384, 24576, 26624, 27136, 27137, 27139, 27104, 
+    27112,     0, 16384, 24576, 26624, 27136, 27137, 27139, 
+    27104, 27120, 27116,     0, 16384, 24576, 26624, 27136, 
+    27137, 27139, 27104, 27120, 27116,     0, 16384, 24576, 
+    26624, 27136, 27137, 27139, 27104, 27120, 27121, 27118, 
+        0, 16384, 24576, 26624, 27136, 27137, 27139, 27104, 
+        0, 16384, 24576, 26624, 27136, 27137, 27139, 27104, 
+    27120,     0, 16384, 24576, 26624, 27136, 27137, 27139, 
+    27104, 27120,     0, 16384, 24576, 26624, 27136, 27137, 
+    27139, 27104, 27120, 27122,     0, 16384, 24576, 26624, 
+    27136, 27137, 27139, 27143, 27120,     0, 16384, 24576, 
+    26624, 27136, 27137, 27139, 27143, 27120, 27124,     0, 
+    16384, 24576, 26624, 27136, 27137, 27139, 27143, 27120, 
+    27124,     0, 16384, 24576, 26624, 27136, 27137, 27139, 
+    27143, 27120, 27128, 27126,     0, 16384, 24576, 26624, 
+    27136, 27137, 27139, 27143, 27120,     0, 16384, 24576, 
+    26624, 27136, 27137, 27139, 27143, 27120, 27128,     0, 
+    16384, 24576, 26624, 27136, 27137, 27139, 27143, 27120, 
+    27128,     0, 16384, 24576, 26624, 27136, 27137, 27139, 
+    27143, 27120, 27128, 27130,     0, 16384, 24576, 26624, 
+    27136, 27137, 27139, 27143, 27120, 27128,     0, 16384, 
+    24576, 26624, 27136, 27137, 27139, 27143, 27120, 27128, 
+    27132,     0, 16384, 24576, 26624, 27136, 27137, 27139, 
+    27143, 27120, 27128, 27132,     0, 16384, 24576, 26624, 
+    27136, 27137, 27139, 27143, 27120, 27128, 27132, 27134, 
+        0, 16384, 24576, 26624,     0, 16384, 24576, 26624, 
+    27136,     0, 16384, 24576, 26624, 27136,     0, 16384, 
+    24576, 26624, 27136, 27138,     0, 16384, 24576, 26624, 
+    27136,     0, 16384, 24576, 26624, 27136, 27140,     0, 
+    16384, 24576, 26624, 27136, 27140,     0, 16384, 24576, 
+    26624, 27136, 27144, 27142,     0, 16384, 24576, 26624, 
+    27136,     0, 16384, 24576, 26624, 27136, 27144,     0, 
+    16384, 24576, 26624, 27136, 27144,     0, 16384, 24576, 
+    26624, 27136, 27144, 27146,     0, 16384, 24576, 26624, 
+    27136, 27144,     0, 16384, 24576, 26624, 27136, 27152, 
+    27148,     0, 16384, 24576, 26624, 27136, 27152, 27148, 
+        0, 16384, 24576, 26624, 27136, 27152, 27153, 27150, 
+        0, 16384, 24576, 26624, 27136,     0, 16384, 24576, 
+    26624, 27136, 27152,     0, 16384, 24576, 26624, 27136, 
+    27152,     0, 16384, 24576, 26624, 27136, 27152, 27154, 
+        0, 16384, 24576, 26624, 27136, 27152,     0, 16384, 
+    24576, 26624, 27136, 27152, 27156,     0, 16384, 24576, 
+    26624, 27136, 27152, 27156,     0, 16384, 24576, 26624, 
+    27136, 27152, 27160, 27158,     0, 16384, 24576, 26624, 
+    27136, 27152,     0, 16384, 24576, 26624, 27136, 27168, 
+    27160,     0, 16384, 24576, 26624, 27136, 27168, 27160, 
+        0, 16384, 24576, 26624, 27136, 27168, 27160, 27162, 
+        0, 16384, 24576, 26624, 27136, 27168, 27160,     0, 
+    16384, 24576, 26624, 27136, 27168, 27169, 27164,     0, 
+    16384, 24576, 26624, 27136, 27168, 27169, 27164,     0, 
+    16384, 24576, 26624, 27136, 27168, 27169, 27164, 27166, 
+        0, 16384, 24576, 26624, 27136,     0, 16384, 24576, 
+    26624, 27136, 27168,     0, 16384, 24576, 26624, 27136, 
+    27168,     0, 16384, 24576, 26624, 27136, 27168, 27170, 
+        0, 16384, 24576, 26624, 27136, 27168,     0, 16384, 
+    24576, 26624, 27136, 27168, 27172,     0, 16384, 24576, 
+    26624, 27136, 27168, 27172,     0, 16384, 24576, 26624, 
+    27136, 27168, 27176, 27174,     0, 16384, 24576, 26624, 
+    27136, 27168,     0, 16384, 24576, 26624, 27136, 27168, 
+    27176,     0, 16384, 24576, 26624, 27136, 27168, 27176, 
+        0, 16384, 24576, 26624, 27136, 27168, 27176, 27178, 
+        0, 16384, 24576, 26624, 27136, 27168, 27176,     0, 
+    16384, 24576, 26624, 27136, 27168, 27184, 27180,     0, 
+    16384, 24576, 26624, 27136, 27168, 27184, 27180,     0, 
+    16384, 24576, 26624, 27136, 27168, 27184, 27185, 27182, 
+        0, 16384, 24576, 26624, 27136, 27168,     0, 16384, 
+    24576, 26624, 27136, 27200, 27184,     0, 16384, 24576, 
+    26624, 27136, 27200, 27184,     0, 16384, 24576, 26624, 
+    27136, 27200, 27184, 27186,     0, 16384, 24576, 26624, 
+    27136, 27200, 27184,     0, 16384, 24576, 26624, 27136, 
+    27200, 27184, 27188,     0, 16384, 24576, 26624, 27136, 
+    27200, 27184, 27188,     0, 16384, 24576, 26624, 27136, 
+    27200, 27184, 27192, 27190,     0, 16384, 24576, 26624, 
+    27136, 27200, 27184,     0, 16384, 24576, 26624, 27136, 
+    27200, 27201, 27192,     0, 16384, 24576, 26624, 27136, 
+    27200, 27201, 27192,     0, 16384, 24576, 26624, 27136, 
+    27200, 27201, 27192, 27194,     0, 16384, 24576, 26624, 
+    27136, 27200, 27201, 27192,     0, 16384, 24576, 26624, 
+    27136, 27200, 27201, 27192, 27196,     0, 16384, 24576, 
+    26624, 27136, 27200, 27201, 27203, 27196,     0, 16384, 
+    24576, 26624, 27136, 27200, 27201, 27203, 27196, 27198, 
+        0, 16384, 24576, 26624, 27136,     0, 16384, 24576, 
+    26624, 27136, 27200,     0, 16384, 24576, 26624, 27136, 
+    27200,     0, 16384, 24576, 26624, 27136, 27200, 27202, 
+        0, 16384, 24576, 26624, 27136, 27200,     0, 16384, 
+    24576, 26624, 27136, 27200, 27204,     0, 16384, 24576, 
+    26624, 27136, 27200, 27204,     0, 16384, 24576, 26624, 
+    27136, 27200, 27208, 27206,     0, 16384, 24576, 26624, 
+    27136, 27200,     0, 16384, 24576, 26624, 27136, 27200, 
+    27208,     0, 16384, 24576, 26624, 27136, 27200, 27208, 
+        0, 16384, 24576, 26624, 27136, 27200, 27208, 27210, 
+        0, 16384, 24576, 26624, 27136, 27200, 27208,     0, 
+    16384, 24576, 26624, 27136, 27200, 27216, 27212,     0, 
+    16384, 24576, 26624, 27136, 27200, 27216, 27212,     0, 
+    16384, 24576, 26624, 27136, 27200, 27216, 27217, 27214, 
+        0, 16384, 24576, 26624, 27136, 27200,     0, 16384, 
+    24576, 26624, 27136, 27200, 27216,     0, 16384, 24576, 
+    26624, 27136, 27200, 27216,     0, 16384, 24576, 26624, 
+    27136, 27200, 27216, 27218,     0, 16384, 24576, 26624, 
+    27136, 27200, 27216,     0, 16384, 24576, 26624, 27136, 
+    27200, 27216, 27220,     0, 16384, 24576, 26624, 27136, 
+    27200, 27216, 27220,     0, 16384, 24576, 26624, 27136, 
+    27200, 27216, 27224, 27222,     0, 16384, 24576, 26624, 
+    27136, 27200, 27216,     0, 16384, 24576, 26624, 27136, 
+    27200, 27232, 27224,     0, 16384, 24576, 26624, 27136, 
+    27200, 27232, 27224,     0, 16384, 24576, 26624, 27136, 
+    27200, 27232, 27224, 27226,     0, 16384, 24576, 26624, 
+    27136, 27200, 27232, 27224,     0, 16384, 24576, 26624, 
+    27136, 27200, 27232, 27233, 27228,     0, 16384, 24576, 
+    26624, 27136, 27200, 27232, 27233, 27228,     0, 16384, 
+    24576, 26624, 27136, 27200, 27232, 27233, 27228, 27230, 
+        0, 16384, 24576, 26624, 27136, 27200,     0, 16384, 
+    24576, 26624, 27136, 27264, 27232,     0, 16384, 24576, 
+    26624, 27136, 27264, 27232,     0, 16384, 24576, 26624, 
+    27136, 27264, 27232, 27234,     0, 16384, 24576, 26624, 
+    27136, 27264, 27232,     0, 16384, 24576, 26624, 27136, 
+    27264, 27232, 27236,     0, 16384, 24576, 26624, 27136, 
+    27264, 27232, 27236,     0, 16384, 24576, 26624, 27136, 
+    27264, 27232, 27240, 27238,     0, 16384, 24576, 26624, 
+    27136, 27264, 27232,     0, 16384, 24576, 26624, 27136, 
+    27264, 27232, 27240,     0, 16384, 24576, 26624, 27136, 
+    27264, 27232, 27240,     0, 16384, 24576, 26624, 27136, 
+    27264, 27232, 27240, 27242,     0, 16384, 24576, 26624, 
+    27136, 27264, 27232, 27240,     0, 16384, 24576, 26624, 
+    27136, 27264, 27232, 27248, 27244,     0, 16384, 24576, 
+    26624, 27136, 27264, 27232, 27248, 27244,     0, 16384, 
+    24576, 26624, 27136, 27264, 27232, 27248, 27249, 27246, 
+        0, 16384, 24576, 26624, 27136, 27264, 27232,     0, 
+    16384, 24576, 26624, 27136, 27264, 27265, 27248,     0, 
+    16384, 24576, 26624, 27136, 27264, 27265, 27248,     0, 
+    16384, 24576, 26624, 27136, 27264, 27265, 27248, 27250, 
+        0, 16384, 24576, 26624, 27136, 27264, 27265, 27248, 
+        0, 16384, 24576, 26624, 27136, 27264, 27265, 27248, 
+    27252,     0, 16384, 24576, 26624, 27136, 27264, 27265, 
+    27248, 27252,     0, 16384, 24576, 26624, 27136, 27264, 
+    27265, 27248, 27256, 27254,     0, 16384, 24576, 26624, 
+    27136, 27264, 27265, 27248,     0, 16384, 24576, 26624, 
+    27136, 27264, 27265, 27248, 27256,     0, 16384, 24576, 
+    26624, 27136, 27264, 27265, 27267, 27256,     0, 16384, 
+    24576, 26624, 27136, 27264, 27265, 27267, 27256, 27258, 
+        0, 16384, 24576, 26624, 27136, 27264, 27265, 27267, 
+    27256,     0, 16384, 24576, 26624, 27136, 27264, 27265, 
+    27267, 27256, 27260,     0, 16384, 24576, 26624, 27136, 
+    27264, 27265, 27267, 27256, 27260,     0, 16384, 24576, 
+    26624, 27136, 27264, 27265, 27267, 27256, 27260, 27262, 
+        0, 16384, 24576, 26624, 27136,     0, 16384, 24576, 
+    26624, 27136, 27264,     0, 16384, 24576, 26624, 27136, 
+    27264,     0, 16384, 24576, 26624, 27136, 27264, 27266, 
+        0, 16384, 24576, 26624, 27136, 27264,     0, 16384, 
+    24576, 26624, 27136, 27264, 27268,     0, 16384, 24576, 
+    26624, 27136, 27264, 27268,     0, 16384, 24576, 26624, 
+    27136, 27264, 27272, 27270,     0, 16384, 24576, 26624, 
+    27136, 27264,     0, 16384, 24576, 26624, 27136, 27264, 
+    27272,     0, 16384, 24576, 26624, 27136, 27264, 27272, 
+        0, 16384, 24576, 26624, 27136, 27264, 27272, 27274, 
+        0, 16384, 24576, 26624, 27136, 27264, 27272,     0, 
+    16384, 24576, 26624, 27136, 27264, 27280, 27276,     0, 
+    16384, 24576, 26624, 27136, 27264, 27280, 27276,     0, 
+    16384, 24576, 26624, 27136, 27264, 27280, 27281, 27278, 
+        0, 16384, 24576, 26624, 27136, 27264,     0, 16384, 
+    24576, 26624, 27136, 27264, 27280,     0, 16384, 24576, 
+    26624, 27136, 27264, 27280,     0, 16384, 24576, 26624, 
+    27136, 27264, 27280, 27282,     0, 16384, 24576, 26624, 
+    27136, 27264, 27280,     0, 16384, 24576, 26624, 27136, 
+    27264, 27280, 27284,     0, 16384, 24576, 26624, 27136, 
+    27264, 27280, 27284,     0, 16384, 24576, 26624, 27136, 
+    27264, 27280, 27288, 27286,     0, 16384, 24576, 26624, 
+    27136, 27264, 27280,     0, 16384, 24576, 26624, 27136, 
+    27264, 27296, 27288,     0, 16384, 24576, 26624, 27136, 
+    27264, 27296, 27288,     0, 16384, 24576, 26624, 27136, 
+    27264, 27296, 27288, 27290,     0, 16384, 24576, 26624, 
+    27136, 27264, 27296, 27288,     0, 16384, 24576, 26624, 
+    27136, 27264, 27296, 27297, 27292,     0, 16384, 24576, 
+    26624, 27136, 27264, 27296, 27297, 27292,     0, 16384, 
+    24576, 26624, 27136, 27264, 27296, 27297, 27292, 27294, 
+        0, 16384, 24576, 26624, 27136, 27264,     0, 16384, 
+    24576, 26624, 27136, 27264, 27296,     0, 16384, 24576, 
+    26624, 27136, 27264, 27296,     0, 16384, 24576, 26624, 
+    27136, 27264, 27296, 27298,     0, 16384, 24576, 26624, 
+    27136, 27264, 27296,     0, 16384, 24576, 26624, 27136, 
+    27264, 27296, 27300,     0, 16384, 24576, 26624, 27136, 
+    27264, 27296, 27300,     0, 16384, 24576, 26624, 27136, 
+    27264, 27296, 27304, 27302,     0, 16384, 24576, 26624, 
+    27136, 27264, 27296,     0, 16384, 24576, 26624, 27136, 
+    27264, 27296, 27304,     0, 16384, 24576, 26624, 27136, 
+    27264, 27296, 27304,     0, 16384, 24576, 26624, 27136, 
+    27264, 27296, 27304, 27306,     0, 16384, 24576, 26624, 
+    27136, 27264, 27296, 27304,     0, 16384, 24576, 26624, 
+    27136, 27264, 27296, 27312, 27308,     0, 16384, 24576, 
+    26624, 27136, 27264, 27296, 27312, 27308,     0, 16384, 
+    24576, 26624, 27136, 27264, 27296, 27312, 27313, 27310, 
+        0, 16384, 24576, 26624, 27136, 27264, 27296,     0, 
+    16384, 24576, 26624, 27136, 27264, 27328, 27312,     0, 
+    16384, 24576, 26624, 27136, 27264, 27328, 27312,     0, 
+    16384, 24576, 26624, 27136, 27264, 27328, 27312, 27314, 
+        0, 16384, 24576, 26624, 27136, 27264, 27328, 27312, 
+        0, 16384, 24576, 26624, 27136, 27264, 27328, 27312, 
+    27316,     0, 16384, 24576, 26624, 27136, 27264, 27328, 
+    27312, 27316,     0, 16384, 24576, 26624, 27136, 27264, 
+    27328, 27312, 27320, 27318,     0, 16384, 24576, 26624, 
+    27136, 27264, 27328, 27312,     0, 16384, 24576, 26624, 
+    27136, 27264, 27328, 27329, 27320,     0, 16384, 24576, 
+    26624, 27136, 27264, 27328, 27329, 27320,     0, 16384, 
+    24576, 26624, 27136, 27264, 27328, 27329, 27320, 27322, 
+        0, 16384, 24576, 26624, 27136, 27264, 27328, 27329, 
+    27320,     0, 16384, 24576, 26624, 27136, 27264, 27328, 
+    27329, 27320, 27324,     0, 16384, 24576, 26624, 27136, 
+    27264, 27328, 27329, 27331, 27324,     0, 16384, 24576, 
+    26624, 27136, 27264, 27328, 27329, 27331, 27324, 27326, 
+        0, 16384, 24576, 26624, 27136, 27264,     0, 16384, 
+    24576, 26624, 27136, 27392, 27328,     0, 16384, 24576, 
+    26624, 27136, 27392, 27328,     0, 16384, 24576, 26624, 
+    27136, 27392, 27328, 27330,     0, 16384, 24576, 26624, 
+    27136, 27392, 27328,     0, 16384, 24576, 26624, 27136, 
+    27392, 27328, 27332,     0, 16384, 24576, 26624, 27136, 
+    27392, 27328, 27332,     0, 16384, 24576, 26624, 27136, 
+    27392, 27328, 27336, 27334,     0, 16384, 24576, 26624, 
+    27136, 27392, 27328,     0, 16384, 24576, 26624, 27136, 
+    27392, 27328, 27336,     0, 16384, 24576, 26624, 27136, 
+    27392, 27328, 27336,     0, 16384, 24576, 26624, 27136, 
+    27392, 27328, 27336, 27338,     0, 16384, 24576, 26624, 
+    27136, 27392, 27328, 27336,     0, 16384, 24576, 26624, 
+    27136, 27392, 27328, 27344, 27340,     0, 16384, 24576, 
+    26624, 27136, 27392, 27328, 27344, 27340,     0, 16384, 
+    24576, 26624, 27136, 27392, 27328, 27344, 27345, 27342, 
+        0, 16384, 24576, 26624, 27136, 27392, 27328,     0, 
+    16384, 24576, 26624, 27136, 27392, 27328, 27344,     0, 
+    16384, 24576, 26624, 27136, 27392, 27328, 27344,     0, 
+    16384, 24576, 26624, 27136, 27392, 27328, 27344, 27346, 
+        0, 16384, 24576, 26624, 27136, 27392, 27328, 27344, 
+        0, 16384, 24576, 26624, 27136, 27392, 27328, 27344, 
+    27348,     0, 16384, 24576, 26624, 27136, 27392, 27328, 
+    27344, 27348,     0, 16384, 24576, 26624, 27136, 27392, 
+    27328, 27344, 27352, 27350,     0, 16384, 24576, 26624, 
+    27136, 27392, 27328, 27344,     0, 16384, 24576, 26624, 
+    27136, 27392, 27328, 27360, 27352,     0, 16384, 24576, 
+    26624, 27136, 27392, 27328, 27360, 27352,     0, 16384, 
+    24576, 26624, 27136, 27392, 27328, 27360, 27352, 27354, 
+        0, 16384, 24576, 26624, 27136, 27392, 27328, 27360, 
+    27352,     0, 16384, 24576, 26624, 27136, 27392, 27328, 
+    27360, 27361, 27356,     0, 16384, 24576, 26624, 27136, 
+    27392, 27328, 27360, 27361, 27356,     0, 16384, 24576, 
+    26624, 27136, 27392, 27328, 27360, 27361, 27356, 27358, 
+        0, 16384, 24576, 26624, 27136, 27392, 27328,     0, 
+    16384, 24576, 26624, 27136, 27392, 27393, 27360,     0, 
+    16384, 24576, 26624, 27136, 27392, 27393, 27360,     0, 
+    16384, 24576, 26624, 27136, 27392, 27393, 27360, 27362, 
+        0, 16384, 24576, 26624, 27136, 27392, 27393, 27360, 
+        0, 16384, 24576, 26624, 27136, 27392, 27393, 27360, 
+    27364,     0, 16384, 24576, 26624, 27136, 27392, 27393, 
+    27360, 27364,     0, 16384, 24576, 26624, 27136, 27392, 
+    27393, 27360, 27368, 27366,     0, 16384, 24576, 26624, 
+    27136, 27392, 27393, 27360,     0, 16384, 24576, 26624, 
+    27136, 27392, 27393, 27360, 27368,     0, 16384, 24576, 
+    26624, 27136, 27392, 27393, 27360, 27368,     0, 16384, 
+    24576, 26624, 27136, 27392, 27393, 27360, 27368, 27370, 
+        0, 16384, 24576, 26624, 27136, 27392, 27393, 27360, 
+    27368,     0, 16384, 24576, 26624, 27136, 27392, 27393, 
+    27360, 27376, 27372,     0, 16384, 24576, 26624, 27136, 
+    27392, 27393, 27360, 27376, 27372,     0, 16384, 24576, 
+    26624, 27136, 27392, 27393, 27360, 27376, 27377, 27374, 
+        0, 16384, 24576, 26624, 27136, 27392, 27393, 27360, 
+        0, 16384, 24576, 26624, 27136, 27392, 27393, 27360, 
+    27376,     0, 16384, 24576, 26624, 27136, 27392, 27393, 
+    27395, 27376,     0, 16384, 24576, 26624, 27136, 27392, 
+    27393, 27395, 27376, 27378,     0, 16384, 24576, 26624, 
+    27136, 27392, 27393, 27395, 27376,     0, 16384, 24576, 
+    26624, 27136, 27392, 27393, 27395, 27376, 27380,     0, 
+    16384, 24576, 26624, 27136, 27392, 27393, 27395, 27376, 
+    27380,     0, 16384, 24576, 26624, 27136, 27392, 27393, 
+    27395, 27376, 27384, 27382,     0, 16384, 24576, 26624, 
+    27136, 27392, 27393, 27395, 27376,     0, 16384, 24576, 
+    26624, 27136, 27392, 27393, 27395, 27376, 27384,     0, 
+    16384, 24576, 26624, 27136, 27392, 27393, 27395, 27376, 
+    27384,     0, 16384, 24576, 26624, 27136, 27392, 27393, 
+    27395, 27376, 27384, 27386,     0, 16384, 24576, 26624, 
+    27136, 27392, 27393, 27395, 27399, 27384,     0, 16384, 
+    24576, 26624, 27136, 27392, 27393, 27395, 27399, 27384, 
+    27388,     0, 16384, 24576, 26624, 27136, 27392, 27393, 
+    27395, 27399, 27384, 27388,     0, 16384, 24576, 26624, 
+    27136, 27392, 27393, 27395, 27399, 27384, 27388, 27390, 
+        0, 16384, 24576, 26624, 27136,     0, 16384, 24576, 
+    26624, 27648, 27392,     0, 16384, 24576, 26624, 27648, 
+    27392,     0, 16384, 24576, 26624, 27648, 27392, 27394, 
+        0, 16384, 24576, 26624, 27648, 27392,     0, 16384, 
+    24576, 26624, 27648, 27392, 27396,     0, 16384, 24576, 
+    26624, 27648, 27392, 27396,     0, 16384, 24576, 26624, 
+    27648, 27392, 27400, 27398,     0, 16384, 24576, 26624, 
+    27648, 27392,     0, 16384, 24576, 26624, 27648, 27392, 
+    27400,     0, 16384, 24576, 26624, 27648, 27392, 27400, 
+        0, 16384, 24576, 26624, 27648, 27392, 27400, 27402, 
+        0, 16384, 24576, 26624, 27648, 27392, 27400,     0, 
+    16384, 24576, 26624, 27648, 27392, 27408, 27404,     0, 
+    16384, 24576, 26624, 27648, 27392, 27408, 27404,     0, 
+    16384, 24576, 26624, 27648, 27392, 27408, 27409, 27406, 
+        0, 16384, 24576, 26624, 27648, 27392,     0, 16384, 
+    24576, 26624, 27648, 27392, 27408,     0, 16384, 24576, 
+    26624, 27648, 27392, 27408,     0, 16384, 24576, 26624, 
+    27648, 27392, 27408, 27410,     0, 16384, 24576, 26624, 
+    27648, 27392, 27408,     0, 16384, 24576, 26624, 27648, 
+    27392, 27408, 27412,     0, 16384, 24576, 26624, 27648, 
+    27392, 27408, 27412,     0, 16384, 24576, 26624, 27648, 
+    27392, 27408, 27416, 27414,     0, 16384, 24576, 26624, 
+    27648, 27392, 27408,     0, 16384, 24576, 26624, 27648, 
+    27392, 27424, 27416,     0, 16384, 24576, 26624, 27648, 
+    27392, 27424, 27416,     0, 16384, 24576, 26624, 27648, 
+    27392, 27424, 27416, 27418,     0, 16384, 24576, 26624, 
+    27648, 27392, 27424, 27416,     0, 16384, 24576, 26624, 
+    27648, 27392, 27424, 27425, 27420,     0, 16384, 24576, 
+    26624, 27648, 27392, 27424, 27425, 27420,     0, 16384, 
+    24576, 26624, 27648, 27392, 27424, 27425, 27420, 27422, 
+        0, 16384, 24576, 26624, 27648, 27392,     0, 16384, 
+    24576, 26624, 27648, 27392, 27424,     0, 16384, 24576, 
+    26624, 27648, 27392, 27424,     0, 16384, 24576, 26624, 
+    27648, 27392, 27424, 27426,     0, 16384, 24576, 26624, 
+    27648, 27392, 27424,     0, 16384, 24576, 26624, 27648, 
+    27392, 27424, 27428,     0, 16384, 24576, 26624, 27648, 
+    27392, 27424, 27428,     0, 16384, 24576, 26624, 27648, 
+    27392, 27424, 27432, 27430,     0, 16384, 24576, 26624, 
+    27648, 27392, 27424,     0, 16384, 24576, 26624, 27648, 
+    27392, 27424, 27432,     0, 16384, 24576, 26624, 27648, 
+    27392, 27424, 27432,     0, 16384, 24576, 26624, 27648, 
+    27392, 27424, 27432, 27434,     0, 16384, 24576, 26624, 
+    27648, 27392, 27424, 27432,     0, 16384, 24576, 26624, 
+    27648, 27392, 27424, 27440, 27436,     0, 16384, 24576, 
+    26624, 27648, 27392, 27424, 27440, 27436,     0, 16384, 
+    24576, 26624, 27648, 27392, 27424, 27440, 27441, 27438, 
+        0, 16384, 24576, 26624, 27648, 27392, 27424,     0, 
+    16384, 24576, 26624, 27648, 27392, 27456, 27440,     0, 
+    16384, 24576, 26624, 27648, 27392, 27456, 27440,     0, 
+    16384, 24576, 26624, 27648, 27392, 27456, 27440, 27442, 
+        0, 16384, 24576, 26624, 27648, 27392, 27456, 27440, 
+        0, 16384, 24576, 26624, 27648, 27392, 27456, 27440, 
+    27444,     0, 16384, 24576, 26624, 27648, 27392, 27456, 
+    27440, 27444,     0, 16384, 24576, 26624, 27648, 27392, 
+    27456, 27440, 27448, 27446,     0, 16384, 24576, 26624, 
+    27648, 27392, 27456, 27440,     0, 16384, 24576, 26624, 
+    27648, 27392, 27456, 27457, 27448,     0, 16384, 24576, 
+    26624, 27648, 27392, 27456, 27457, 27448,     0, 16384, 
+    24576, 26624, 27648, 27392, 27456, 27457, 27448, 27450, 
+        0, 16384, 24576, 26624, 27648, 27392, 27456, 27457, 
+    27448,     0, 16384, 24576, 26624, 27648, 27392, 27456, 
+    27457, 27448, 27452,     0, 16384, 24576, 26624, 27648, 
+    27392, 27456, 27457, 27459, 27452,     0, 16384, 24576, 
+    26624, 27648, 27392, 27456, 27457, 27459, 27452, 27454, 
+        0, 16384, 24576, 26624, 27648, 27392,     0, 16384, 
+    24576, 26624, 27648, 27392, 27456,     0, 16384, 24576, 
+    26624, 27648, 27392, 27456,     0, 16384, 24576, 26624, 
+    27648, 27392, 27456, 27458,     0, 16384, 24576, 26624, 
+    27648, 27392, 27456,     0, 16384, 24576, 26624, 27648, 
+    27392, 27456, 27460,     0, 16384, 24576, 26624, 27648, 
+    27392, 27456, 27460,     0, 16384, 24576, 26624, 27648, 
+    27392, 27456, 27464, 27462,     0, 16384, 24576, 26624, 
+    27648, 27392, 27456,     0, 16384, 24576, 26624, 27648, 
+    27392, 27456, 27464,     0, 16384, 24576, 26624, 27648, 
+    27392, 27456, 27464,     0, 16384, 24576, 26624, 27648, 
+    27392, 27456, 27464, 27466,     0, 16384, 24576, 26624, 
+    27648, 27392, 27456, 27464,     0, 16384, 24576, 26624, 
+    27648, 27392, 27456, 27472, 27468,     0, 16384, 24576, 
+    26624, 27648, 27392, 27456, 27472, 27468,     0, 16384, 
+    24576, 26624, 27648, 27392, 27456, 27472, 27473, 27470, 
+        0, 16384, 24576, 26624, 27648, 27392, 27456,     0, 
+    16384, 24576, 26624, 27648, 27392, 27456, 27472,     0, 
+    16384, 24576, 26624, 27648, 27392, 27456, 27472,     0, 
+    16384, 24576, 26624, 27648, 27392, 27456, 27472, 27474, 
+        0, 16384, 24576, 26624, 27648, 27392, 27456, 27472, 
+        0, 16384, 24576, 26624, 27648, 27392, 27456, 27472, 
+    27476,     0, 16384, 24576, 26624, 27648, 27392, 27456, 
+    27472, 27476,     0, 16384, 24576, 26624, 27648, 27392, 
+    27456, 27472, 27480, 27478,     0, 16384, 24576, 26624, 
+    27648, 27392, 27456, 27472,     0, 16384, 24576, 26624, 
+    27648, 27392, 27456, 27488, 27480,     0, 16384, 24576, 
+    26624, 27648, 27392, 27456, 27488, 27480,     0, 16384, 
+    24576, 26624, 27648, 27392, 27456, 27488, 27480, 27482, 
+        0, 16384, 24576, 26624, 27648, 27392, 27456, 27488, 
+    27480,     0, 16384, 24576, 26624, 27648, 27392, 27456, 
+    27488, 27489, 27484,     0, 16384, 24576, 26624, 27648, 
+    27392, 27456, 27488, 27489, 27484,     0, 16384, 24576, 
+    26624, 27648, 27392, 27456, 27488, 27489, 27484, 27486, 
+        0, 16384, 24576, 26624, 27648, 27392, 27456,     0, 
+    16384, 24576, 26624, 27648, 27392, 27520, 27488,     0, 
+    16384, 24576, 26624, 27648, 27392, 27520, 27488,     0, 
+    16384, 24576, 26624, 27648, 27392, 27520, 27488, 27490, 
+        0, 16384, 24576, 26624, 27648, 27392, 27520, 27488, 
+        0, 16384, 24576, 26624, 27648, 27392, 27520, 27488, 
+    27492,     0, 16384, 24576, 26624, 27648, 27392, 27520, 
+    27488, 27492,     0, 16384, 24576, 26624, 27648, 27392, 
+    27520, 27488, 27496, 27494,     0, 16384, 24576, 26624, 
+    27648, 27392, 27520, 27488,     0, 16384, 24576, 26624, 
+    27648, 27392, 27520, 27488, 27496,     0, 16384, 24576, 
+    26624, 27648, 27392, 27520, 27488, 27496,     0, 16384, 
+    24576, 26624, 27648, 27392, 27520, 27488, 27496, 27498, 
+        0, 16384, 24576, 26624, 27648, 27392, 27520, 27488, 
+    27496,     0, 16384, 24576, 26624, 27648, 27392, 27520, 
+    27488, 27504, 27500,     0, 16384, 24576, 26624, 27648, 
+    27392, 27520, 27488, 27504, 27500,     0, 16384, 24576, 
+    26624, 27648, 27392, 27520, 27488, 27504, 27505, 27502, 
+        0, 16384, 24576, 26624, 27648, 27392, 27520, 27488, 
+        0, 16384, 24576, 26624, 27648, 27392, 27520, 27521, 
+    27504,     0, 16384, 24576, 26624, 27648, 27392, 27520, 
+    27521, 27504,     0, 16384, 24576, 26624, 27648, 27392, 
+    27520, 27521, 27504, 27506,     0, 16384, 24576, 26624, 
+    27648, 27392, 27520, 27521, 27504,     0, 16384, 24576, 
+    26624, 27648, 27392, 27520, 27521, 27504, 27508,     0, 
+    16384, 24576, 26624, 27648, 27392, 27520, 27521, 27504, 
+    27508,     0, 16384, 24576, 26624, 27648, 27392, 27520, 
+    27521, 27504, 27512, 27510,     0, 16384, 24576, 26624, 
+    27648, 27392, 27520, 27521, 27504,     0, 16384, 24576, 
+    26624, 27648, 27392, 27520, 27521, 27504, 27512,     0, 
+    16384, 24576, 26624, 27648, 27392, 27520, 27521, 27523, 
+    27512,     0, 16384, 24576, 26624, 27648, 27392, 27520, 
+    27521, 27523, 27512, 27514,     0, 16384, 24576, 26624, 
+    27648, 27392, 27520, 27521, 27523, 27512,     0, 16384, 
+    24576, 26624, 27648, 27392, 27520, 27521, 27523, 27512, 
+    27516,     0, 16384, 24576, 26624, 27648, 27392, 27520, 
+    27521, 27523, 27512, 27516,     0, 16384, 24576, 26624, 
+    27648, 27392, 27520, 27521, 27523, 27512, 27516, 27518, 
+        0, 16384, 24576, 26624, 27648, 27392,     0, 16384, 
+    24576, 26624, 27648, 27392, 27520,     0, 16384, 24576, 
+    26624, 27648, 27649, 27520,     0, 16384, 24576, 26624, 
+    27648, 27649, 27520, 27522,     0, 16384, 24576, 26624, 
+    27648, 27649, 27520,     0, 16384, 24576, 26624, 27648, 
+    27649, 27520, 27524,     0, 16384, 24576, 26624, 27648, 
+    27649, 27520, 27524,     0, 16384, 24576, 26624, 27648, 
+    27649, 27520, 27528, 27526,     0, 16384, 24576, 26624, 
+    27648, 27649, 27520,     0, 16384, 24576, 26624, 27648, 
+    27649, 27520, 27528,     0, 16384, 24576, 26624, 27648, 
+    27649, 27520, 27528,     0, 16384, 24576, 26624, 27648, 
+    27649, 27520, 27528, 27530,     0, 16384, 24576, 26624, 
+    27648, 27649, 27520, 27528,     0, 16384, 24576, 26624, 
+    27648, 27649, 27520, 27536, 27532,     0, 16384, 24576, 
+    26624, 27648, 27649, 27520, 27536, 27532,     0, 16384, 
+    24576, 26624, 27648, 27649, 27520, 27536, 27537, 27534, 
+        0, 16384, 24576, 26624, 27648, 27649, 27520,     0, 
+    16384, 24576, 26624, 27648, 27649, 27520, 27536,     0, 
+    16384, 24576, 26624, 27648, 27649, 27520, 27536,     0, 
+    16384, 24576, 26624, 27648, 27649, 27520, 27536, 27538, 
+        0, 16384, 24576, 26624, 27648, 27649, 27520, 27536, 
+        0, 16384, 24576, 26624, 27648, 27649, 27520, 27536, 
+    27540,     0, 16384, 24576, 26624, 27648, 27649, 27520, 
+    27536, 27540,     0, 16384, 24576, 26624, 27648, 27649, 
+    27520, 27536, 27544, 27542,     0, 16384, 24576, 26624, 
+    27648, 27649, 27520, 27536,     0, 16384, 24576, 26624, 
+    27648, 27649, 27520, 27552, 27544,     0, 16384, 24576, 
+    26624, 27648, 27649, 27520, 27552, 27544,     0, 16384, 
+    24576, 26624, 27648, 27649, 27520, 27552, 27544, 27546, 
+        0, 16384, 24576, 26624, 27648, 27649, 27520, 27552, 
+    27544,     0, 16384, 24576, 26624, 27648, 27649, 27520, 
+    27552, 27553, 27548,     0, 16384, 24576, 26624, 27648, 
+    27649, 27520, 27552, 27553, 27548,     0, 16384, 24576, 
+    26624, 27648, 27649, 27520, 27552, 27553, 27548, 27550, 
+        0, 16384, 24576, 26624, 27648, 27649, 27520,     0, 
+    16384, 24576, 26624, 27648, 27649, 27520, 27552,     0, 
+    16384, 24576, 26624, 27648, 27649, 27520, 27552,     0, 
+    16384, 24576, 26624, 27648, 27649, 27520, 27552, 27554, 
+        0, 16384, 24576, 26624, 27648, 27649, 27520, 27552, 
+        0, 16384, 24576, 26624, 27648, 27649, 27520, 27552, 
+    27556,     0, 16384, 24576, 26624, 27648, 27649, 27520, 
+    27552, 27556,     0, 16384, 24576, 26624, 27648, 27649, 
+    27520, 27552, 27560, 27558,     0, 16384, 24576, 26624, 
+    27648, 27649, 27520, 27552,     0, 16384, 24576, 26624, 
+    27648, 27649, 27520, 27552, 27560,     0, 16384, 24576, 
+    26624, 27648, 27649, 27520, 27552, 27560,     0, 16384, 
+    24576, 26624, 27648, 27649, 27520, 27552, 27560, 27562, 
+        0, 16384, 24576, 26624, 27648, 27649, 27520, 27552, 
+    27560,     0, 16384, 24576, 26624, 27648, 27649, 27520, 
+    27552, 27568, 27564,     0, 16384, 24576, 26624, 27648, 
+    27649, 27520, 27552, 27568, 27564,     0, 16384, 24576, 
+    26624, 27648, 27649, 27520, 27552, 27568, 27569, 27566, 
+        0, 16384, 24576, 26624, 27648, 27649, 27520, 27552, 
+        0, 16384, 24576, 26624, 27648, 27649, 27520, 27584, 
+    27568,     0, 16384, 24576, 26624, 27648, 27649, 27520, 
+    27584, 27568,     0, 16384, 24576, 26624, 27648, 27649, 
+    27520, 27584, 27568, 27570,     0, 16384, 24576, 26624, 
+    27648, 27649, 27520, 27584, 27568,     0, 16384, 24576, 
+    26624, 27648, 27649, 27520, 27584, 27568, 27572,     0, 
+    16384, 24576, 26624, 27648, 27649, 27520, 27584, 27568, 
+    27572,     0, 16384, 24576, 26624, 27648, 27649, 27520, 
+    27584, 27568, 27576, 27574,     0, 16384, 24576, 26624, 
+    27648, 27649, 27520, 27584, 27568,     0, 16384, 24576, 
+    26624, 27648, 27649, 27520, 27584, 27585, 27576,     0, 
+    16384, 24576, 26624, 27648, 27649, 27520, 27584, 27585, 
+    27576,     0, 16384, 24576, 26624, 27648, 27649, 27520, 
+    27584, 27585, 27576, 27578,     0, 16384, 24576, 26624, 
+    27648, 27649, 27520, 27584, 27585, 27576,     0, 16384, 
+    24576, 26624, 27648, 27649, 27520, 27584, 27585, 27576, 
+    27580,     0, 16384, 24576, 26624, 27648, 27649, 27520, 
+    27584, 27585, 27587, 27580,     0, 16384, 24576, 26624, 
+    27648, 27649, 27520, 27584, 27585, 27587, 27580, 27582, 
+        0, 16384, 24576, 26624, 27648, 27649, 27520,     0, 
+    16384, 24576, 26624, 27648, 27649, 27520, 27584,     0, 
+    16384, 24576, 26624, 27648, 27649, 27520, 27584,     0, 
+    16384, 24576, 26624, 27648, 27649, 27520, 27584, 27586, 
+        0, 16384, 24576, 26624, 27648, 27649, 27651, 27584, 
+        0, 16384, 24576, 26624, 27648, 27649, 27651, 27584, 
+    27588,     0, 16384, 24576, 26624, 27648, 27649, 27651, 
+    27584, 27588,     0, 16384, 24576, 26624, 27648, 27649, 
+    27651, 27584, 27592, 27590,     0, 16384, 24576, 26624, 
+    27648, 27649, 27651, 27584,     0, 16384, 24576, 26624, 
+    27648, 27649, 27651, 27584, 27592,     0, 16384, 24576, 
+    26624, 27648, 27649, 27651, 27584, 27592,     0, 16384, 
+    24576, 26624, 27648, 27649, 27651, 27584, 27592, 27594, 
+        0, 16384, 24576, 26624, 27648, 27649, 27651, 27584, 
+    27592,     0, 16384, 24576, 26624, 27648, 27649, 27651, 
+    27584, 27600, 27596,     0, 16384, 24576, 26624, 27648, 
+    27649, 27651, 27584, 27600, 27596,     0, 16384, 24576, 
+    26624, 27648, 27649, 27651, 27584, 27600, 27601, 27598, 
+        0, 16384, 24576, 26624, 27648, 27649, 27651, 27584, 
+        0, 16384, 24576, 26624, 27648, 27649, 27651, 27584, 
+    27600,     0, 16384, 24576, 26624, 27648, 27649, 27651, 
+    27584, 27600,     0, 16384, 24576, 26624, 27648, 27649, 
+    27651, 27584, 27600, 27602,     0, 16384, 24576, 26624, 
+    27648, 27649, 27651, 27584, 27600,     0, 16384, 24576, 
+    26624, 27648, 27649, 27651, 27584, 27600, 27604,     0, 
+    16384, 24576, 26624, 27648, 27649, 27651, 27584, 27600, 
+    27604,     0, 16384, 24576, 26624, 27648, 27649, 27651, 
+    27584, 27600, 27608, 27606,     0, 16384, 24576, 26624, 
+    27648, 27649, 27651, 27584, 27600,     0, 16384, 24576, 
+    26624, 27648, 27649, 27651, 27584, 27616, 27608,     0, 
+    16384, 24576, 26624, 27648, 27649, 27651, 27584, 27616, 
+    27608,     0, 16384, 24576, 26624, 27648, 27649, 27651, 
+    27584, 27616, 27608, 27610,     0, 16384, 24576, 26624, 
+    27648, 27649, 27651, 27584, 27616, 27608,     0, 16384, 
+    24576, 26624, 27648, 27649, 27651, 27584, 27616, 27617, 
+    27612,     0, 16384, 24576, 26624, 27648, 27649, 27651, 
+    27584, 27616, 27617, 27612,     0, 16384, 24576, 26624, 
+    27648, 27649, 27651, 27584, 27616, 27617, 27612, 27614, 
+        0, 16384, 24576, 26624, 27648, 27649, 27651, 27584, 
+        0, 16384, 24576, 26624, 27648, 27649, 27651, 27584, 
+    27616,     0, 16384, 24576, 26624, 27648, 27649, 27651, 
+    27584, 27616,     0, 16384, 24576, 26624, 27648, 27649, 
+    27651, 27584, 27616, 27618,     0, 16384, 24576, 26624, 
+    27648, 27649, 27651, 27584, 27616,     0, 16384, 24576, 
+    26624, 27648, 27649, 27651, 27584, 27616, 27620,     0, 
+    16384, 24576, 26624, 27648, 27649, 27651, 27584, 27616, 
+    27620,     0, 16384, 24576, 26624, 27648, 27649, 27651, 
+    27584, 27616, 27624, 27622,     0, 16384, 24576, 26624, 
+    27648, 27649, 27651, 27655, 27616,     0, 16384, 24576, 
+    26624, 27648, 27649, 27651, 27655, 27616, 27624,     0, 
+    16384, 24576, 26624, 27648, 27649, 27651, 27655, 27616, 
+    27624,     0, 16384, 24576, 26624, 27648, 27649, 27651, 
+    27655, 27616, 27624, 27626,     0, 16384, 24576, 26624, 
+    27648, 27649, 27651, 27655, 27616, 27624,     0, 16384, 
+    24576, 26624, 27648, 27649, 27651, 27655, 27616, 27632, 
+    27628,     0, 16384, 24576, 26624, 27648, 27649, 27651, 
+    27655, 27616, 27632, 27628,     0, 16384, 24576, 26624, 
+    27648, 27649, 27651, 27655, 27616, 27632, 27633, 27630, 
+        0, 16384, 24576, 26624, 27648, 27649, 27651, 27655, 
+    27616,     0, 16384, 24576, 26624, 27648, 27649, 27651, 
+    27655, 27616, 27632,     0, 16384, 24576, 26624, 27648, 
+    27649, 27651, 27655, 27616, 27632,     0, 16384, 24576, 
+    26624, 27648, 27649, 27651, 27655, 27616, 27632, 27634, 
+        0, 16384, 24576, 26624, 27648, 27649, 27651, 27655, 
+    27616, 27632,     0, 16384, 24576, 26624, 27648, 27649, 
+    27651, 27655, 27616, 27632, 27636,     0, 16384, 24576, 
+    26624, 27648, 27649, 27651, 27655, 27616, 27632, 27636, 
+        0, 16384, 24576, 26624, 27648, 27649, 27651, 27655, 
+    27616, 27632, 27640, 27638,     0, 16384, 24576, 26624, 
+    27648, 27649, 27651, 27655, 27616, 27632,     0, 16384, 
+    24576, 26624, 27648, 27649, 27651, 27655, 27616, 27632, 
+    27640,     0, 16384, 24576, 26624, 27648, 27649, 27651, 
+    27655, 27616, 27632, 27640,     0, 16384, 24576, 26624, 
+    27648, 27649, 27651, 27655, 27616, 27632, 27640, 27642, 
+        0, 16384, 24576, 26624, 27648, 27649, 27651, 27655, 
+    27616, 27632, 27640,     0, 16384, 24576, 26624, 27648, 
+    27649, 27651, 27655, 27616, 27632, 27640, 27644,     0, 
+    16384, 24576, 26624, 27648, 27649, 27651, 27655, 27616, 
+    27632, 27640, 27644,     0, 16384, 24576, 26624, 27648, 
+    27649, 27651, 27655, 27616, 27632, 27640, 27644, 27646, 
+        0, 16384, 24576, 26624,     0, 16384, 24576, 26624, 
+    27648,     0, 16384, 24576, 26624, 27648,     0, 16384, 
+    24576, 26624, 27648, 27650,     0, 16384, 24576, 26624, 
+    27648,     0, 16384, 24576, 26624, 27648, 27652,     0, 
+    16384, 24576, 26624, 27648, 27652,     0, 16384, 24576, 
+    26624, 27648, 27656, 27654,     0, 16384, 24576, 26624, 
+    27648,     0, 16384, 24576, 26624, 27648, 27656,     0, 
+    16384, 24576, 26624, 27648, 27656,     0, 16384, 24576, 
+    26624, 27648, 27656, 27658,     0, 16384, 24576, 26624, 
+    27648, 27656,     0, 16384, 24576, 26624, 27648, 27664, 
+    27660,     0, 16384, 24576, 26624, 27648, 27664, 27660, 
+        0, 16384, 24576, 26624, 27648, 27664, 27665, 27662, 
+        0, 16384, 24576, 26624, 27648,     0, 16384, 24576, 
+    26624, 27648, 27664,     0, 16384, 24576, 26624, 27648, 
+    27664,     0, 16384, 24576, 26624, 27648, 27664, 27666, 
+        0, 16384, 24576, 26624, 27648, 27664,     0, 16384, 
+    24576, 26624, 27648, 27664, 27668,     0, 16384, 24576, 
+    26624, 27648, 27664, 27668,     0, 16384, 24576, 26624, 
+    27648, 27664, 27672, 27670,     0, 16384, 24576, 26624, 
+    27648, 27664,     0, 16384, 24576, 26624, 27648, 27680, 
+    27672,     0, 16384, 24576, 26624, 27648, 27680, 27672, 
+        0, 16384, 24576, 26624, 27648, 27680, 27672, 27674, 
+        0, 16384, 24576, 26624, 27648, 27680, 27672,     0, 
+    16384, 24576, 26624, 27648, 27680, 27681, 27676,     0, 
+    16384, 24576, 26624, 27648, 27680, 27681, 27676,     0, 
+    16384, 24576, 26624, 27648, 27680, 27681, 27676, 27678, 
+        0, 16384, 24576, 26624, 27648,     0, 16384, 24576, 
+    26624, 27648, 27680,     0, 16384, 24576, 26624, 27648, 
+    27680,     0, 16384, 24576, 26624, 27648, 27680, 27682, 
+        0, 16384, 24576, 26624, 27648, 27680,     0, 16384, 
+    24576, 26624, 27648, 27680, 27684,     0, 16384, 24576, 
+    26624, 27648, 27680, 27684,     0, 16384, 24576, 26624, 
+    27648, 27680, 27688, 27686,     0, 16384, 24576, 26624, 
+    27648, 27680,     0, 16384, 24576, 26624, 27648, 27680, 
+    27688,     0, 16384, 24576, 26624, 27648, 27680, 27688, 
+        0, 16384, 24576, 26624, 27648, 27680, 27688, 27690, 
+        0, 16384, 24576, 26624, 27648, 27680, 27688,     0, 
+    16384, 24576, 26624, 27648, 27680, 27696, 27692,     0, 
+    16384, 24576, 26624, 27648, 27680, 27696, 27692,     0, 
+    16384, 24576, 26624, 27648, 27680, 27696, 27697, 27694, 
+        0, 16384, 24576, 26624, 27648, 27680,     0, 16384, 
+    24576, 26624, 27648, 27712, 27696,     0, 16384, 24576, 
+    26624, 27648, 27712, 27696,     0, 16384, 24576, 26624, 
+    27648, 27712, 27696, 27698,     0, 16384, 24576, 26624, 
+    27648, 27712, 27696,     0, 16384, 24576, 26624, 27648, 
+    27712, 27696, 27700,     0, 16384, 24576, 26624, 27648, 
+    27712, 27696, 27700,     0, 16384, 24576, 26624, 27648, 
+    27712, 27696, 27704, 27702,     0, 16384, 24576, 26624, 
+    27648, 27712, 27696,     0, 16384, 24576, 26624, 27648, 
+    27712, 27713, 27704,     0, 16384, 24576, 26624, 27648, 
+    27712, 27713, 27704,     0, 16384, 24576, 26624, 27648, 
+    27712, 27713, 27704, 27706,     0, 16384, 24576, 26624, 
+    27648, 27712, 27713, 27704,     0, 16384, 24576, 26624, 
+    27648, 27712, 27713, 27704, 27708,     0, 16384, 24576, 
+    26624, 27648, 27712, 27713, 27715, 27708,     0, 16384, 
+    24576, 26624, 27648, 27712, 27713, 27715, 27708, 27710, 
+        0, 16384, 24576, 26624, 27648,     0, 16384, 24576, 
+    26624, 27648, 27712,     0, 16384, 24576, 26624, 27648, 
+    27712,     0, 16384, 24576, 26624, 27648, 27712, 27714, 
+        0, 16384, 24576, 26624, 27648, 27712,     0, 16384, 
+    24576, 26624, 27648, 27712, 27716,     0, 16384, 24576, 
+    26624, 27648, 27712, 27716,     0, 16384, 24576, 26624, 
+    27648, 27712, 27720, 27718,     0, 16384, 24576, 26624, 
+    27648, 27712,     0, 16384, 24576, 26624, 27648, 27712, 
+    27720,     0, 16384, 24576, 26624, 27648, 27712, 27720, 
+        0, 16384, 24576, 26624, 27648, 27712, 27720, 27722, 
+        0, 16384, 24576, 26624, 27648, 27712, 27720,     0, 
+    16384, 24576, 26624, 27648, 27712, 27728, 27724,     0, 
+    16384, 24576, 26624, 27648, 27712, 27728, 27724,     0, 
+    16384, 24576, 26624, 27648, 27712, 27728, 27729, 27726, 
+        0, 16384, 24576, 26624, 27648, 27712,     0, 16384, 
+    24576, 26624, 27648, 27712, 27728,     0, 16384, 24576, 
+    26624, 27648, 27712, 27728,     0, 16384, 24576, 26624, 
+    27648, 27712, 27728, 27730,     0, 16384, 24576, 26624, 
+    27648, 27712, 27728,     0, 16384, 24576, 26624, 27648, 
+    27712, 27728, 27732,     0, 16384, 24576, 26624, 27648, 
+    27712, 27728, 27732,     0, 16384, 24576, 26624, 27648, 
+    27712, 27728, 27736, 27734,     0, 16384, 24576, 26624, 
+    27648, 27712, 27728,     0, 16384, 24576, 26624, 27648, 
+    27712, 27744, 27736,     0, 16384, 24576, 26624, 27648, 
+    27712, 27744, 27736,     0, 16384, 24576, 26624, 27648, 
+    27712, 27744, 27736, 27738,     0, 16384, 24576, 26624, 
+    27648, 27712, 27744, 27736,     0, 16384, 24576, 26624, 
+    27648, 27712, 27744, 27745, 27740,     0, 16384, 24576, 
+    26624, 27648, 27712, 27744, 27745, 27740,     0, 16384, 
+    24576, 26624, 27648, 27712, 27744, 27745, 27740, 27742, 
+        0, 16384, 24576, 26624, 27648, 27712,     0, 16384, 
+    24576, 26624, 27648, 27776, 27744,     0, 16384, 24576, 
+    26624, 27648, 27776, 27744,     0, 16384, 24576, 26624, 
+    27648, 27776, 27744, 27746,     0, 16384, 24576, 26624, 
+    27648, 27776, 27744,     0, 16384, 24576, 26624, 27648, 
+    27776, 27744, 27748,     0, 16384, 24576, 26624, 27648, 
+    27776, 27744, 27748,     0, 16384, 24576, 26624, 27648, 
+    27776, 27744, 27752, 27750,     0, 16384, 24576, 26624, 
+    27648, 27776, 27744,     0, 16384, 24576, 26624, 27648, 
+    27776, 27744, 27752,     0, 16384, 24576, 26624, 27648, 
+    27776, 27744, 27752,     0, 16384, 24576, 26624, 27648, 
+    27776, 27744, 27752, 27754,     0, 16384, 24576, 26624, 
+    27648, 27776, 27744, 27752,     0, 16384, 24576, 26624, 
+    27648, 27776, 27744, 27760, 27756,     0, 16384, 24576, 
+    26624, 27648, 27776, 27744, 27760, 27756,     0, 16384, 
+    24576, 26624, 27648, 27776, 27744, 27760, 27761, 27758, 
+        0, 16384, 24576, 26624, 27648, 27776, 27744,     0, 
+    16384, 24576, 26624, 27648, 27776, 27777, 27760,     0, 
+    16384, 24576, 26624, 27648, 27776, 27777, 27760,     0, 
+    16384, 24576, 26624, 27648, 27776, 27777, 27760, 27762, 
+        0, 16384, 24576, 26624, 27648, 27776, 27777, 27760, 
+        0, 16384, 24576, 26624, 27648, 27776, 27777, 27760, 
+    27764,     0, 16384, 24576, 26624, 27648, 27776, 27777, 
+    27760, 27764,     0, 16384, 24576, 26624, 27648, 27776, 
+    27777, 27760, 27768, 27766,     0, 16384, 24576, 26624, 
+    27648, 27776, 27777, 27760,     0, 16384, 24576, 26624, 
+    27648, 27776, 27777, 27760, 27768,     0, 16384, 24576, 
+    26624, 27648, 27776, 27777, 27779, 27768,     0, 16384, 
+    24576, 26624, 27648, 27776, 27777, 27779, 27768, 27770, 
+        0, 16384, 24576, 26624, 27648, 27776, 27777, 27779, 
+    27768,     0, 16384, 24576, 26624, 27648, 27776, 27777, 
+    27779, 27768, 27772,     0, 16384, 24576, 26624, 27648, 
+    27776, 27777, 27779, 27768, 27772,     0, 16384, 24576, 
+    26624, 27648, 27776, 27777, 27779, 27768, 27772, 27774, 
+        0, 16384, 24576, 26624, 27648,     0, 16384, 24576, 
+    26624, 27648, 27776,     0, 16384, 24576, 26624, 27648, 
+    27776,     0, 16384, 24576, 26624, 27648, 27776, 27778, 
+        0, 16384, 24576, 26624, 27648, 27776,     0, 16384, 
+    24576, 26624, 27648, 27776, 27780,     0, 16384, 24576, 
+    26624, 27648, 27776, 27780,     0, 16384, 24576, 26624, 
+    27648, 27776, 27784, 27782,     0, 16384, 24576, 26624, 
+    27648, 27776,     0, 16384, 24576, 26624, 27648, 27776, 
+    27784,     0, 16384, 24576, 26624, 27648, 27776, 27784, 
+        0, 16384, 24576, 26624, 27648, 27776, 27784, 27786, 
+        0, 16384, 24576, 26624, 27648, 27776, 27784,     0, 
+    16384, 24576, 26624, 27648, 27776, 27792, 27788,     0, 
+    16384, 24576, 26624, 27648, 27776, 27792, 27788,     0, 
+    16384, 24576, 26624, 27648, 27776, 27792, 27793, 27790, 
+        0, 16384, 24576, 26624, 27648, 27776,     0, 16384, 
+    24576, 26624, 27648, 27776, 27792,     0, 16384, 24576, 
+    26624, 27648, 27776, 27792,     0, 16384, 24576, 26624, 
+    27648, 27776, 27792, 27794,     0, 16384, 24576, 26624, 
+    27648, 27776, 27792,     0, 16384, 24576, 26624, 27648, 
+    27776, 27792, 27796,     0, 16384, 24576, 26624, 27648, 
+    27776, 27792, 27796,     0, 16384, 24576, 26624, 27648, 
+    27776, 27792, 27800, 27798,     0, 16384, 24576, 26624, 
+    27648, 27776, 27792,     0, 16384, 24576, 26624, 27648, 
+    27776, 27808, 27800,     0, 16384, 24576, 26624, 27648, 
+    27776, 27808, 27800,     0, 16384, 24576, 26624, 27648, 
+    27776, 27808, 27800, 27802,     0, 16384, 24576, 26624, 
+    27648, 27776, 27808, 27800,     0, 16384, 24576, 26624, 
+    27648, 27776, 27808, 27809, 27804,     0, 16384, 24576, 
+    26624, 27648, 27776, 27808, 27809, 27804,     0, 16384, 
+    24576, 26624, 27648, 27776, 27808, 27809, 27804, 27806, 
+        0, 16384, 24576, 26624, 27648, 27776,     0, 16384, 
+    24576, 26624, 27648, 27776, 27808,     0, 16384, 24576, 
+    26624, 27648, 27776, 27808,     0, 16384, 24576, 26624, 
+    27648, 27776, 27808, 27810,     0, 16384, 24576, 26624, 
+    27648, 27776, 27808,     0, 16384, 24576, 26624, 27648, 
+    27776, 27808, 27812,     0, 16384, 24576, 26624, 27648, 
+    27776, 27808, 27812,     0, 16384, 24576, 26624, 27648, 
+    27776, 27808, 27816, 27814,     0, 16384, 24576, 26624, 
+    27648, 27776, 27808,     0, 16384, 24576, 26624, 27648, 
+    27776, 27808, 27816,     0, 16384, 24576, 26624, 27648, 
+    27776, 27808, 27816,     0, 16384, 24576, 26624, 27648, 
+    27776, 27808, 27816, 27818,     0, 16384, 24576, 26624, 
+    27648, 27776, 27808, 27816,     0, 16384, 24576, 26624, 
+    27648, 27776, 27808, 27824, 27820,     0, 16384, 24576, 
+    26624, 27648, 27776, 27808, 27824, 27820,     0, 16384, 
+    24576, 26624, 27648, 27776, 27808, 27824, 27825, 27822, 
+        0, 16384, 24576, 26624, 27648, 27776, 27808,     0, 
+    16384, 24576, 26624, 27648, 27776, 27840, 27824,     0, 
+    16384, 24576, 26624, 27648, 27776, 27840, 27824,     0, 
+    16384, 24576, 26624, 27648, 27776, 27840, 27824, 27826, 
+        0, 16384, 24576, 26624, 27648, 27776, 27840, 27824, 
+        0, 16384, 24576, 26624, 27648, 27776, 27840, 27824, 
+    27828,     0, 16384, 24576, 26624, 27648, 27776, 27840, 
+    27824, 27828,     0, 16384, 24576, 26624, 27648, 27776, 
+    27840, 27824, 27832, 27830,     0, 16384, 24576, 26624, 
+    27648, 27776, 27840, 27824,     0, 16384, 24576, 26624, 
+    27648, 27776, 27840, 27841, 27832,     0, 16384, 24576, 
+    26624, 27648, 27776, 27840, 27841, 27832,     0, 16384, 
+    24576, 26624, 27648, 27776, 27840, 27841, 27832, 27834, 
+        0, 16384, 24576, 26624, 27648, 27776, 27840, 27841, 
+    27832,     0, 16384, 24576, 26624, 27648, 27776, 27840, 
+    27841, 27832, 27836,     0, 16384, 24576, 26624, 27648, 
+    27776, 27840, 27841, 27843, 27836,     0, 16384, 24576, 
+    26624, 27648, 27776, 27840, 27841, 27843, 27836, 27838, 
+        0, 16384, 24576, 26624, 27648, 27776,     0, 16384, 
+    24576, 26624, 27648, 27904, 27840,     0, 16384, 24576, 
+    26624, 27648, 27904, 27840,     0, 16384, 24576, 26624, 
+    27648, 27904, 27840, 27842,     0, 16384, 24576, 26624, 
+    27648, 27904, 27840,     0, 16384, 24576, 26624, 27648, 
+    27904, 27840, 27844,     0, 16384, 24576, 26624, 27648, 
+    27904, 27840, 27844,     0, 16384, 24576, 26624, 27648, 
+    27904, 27840, 27848, 27846,     0, 16384, 24576, 26624, 
+    27648, 27904, 27840,     0, 16384, 24576, 26624, 27648, 
+    27904, 27840, 27848,     0, 16384, 24576, 26624, 27648, 
+    27904, 27840, 27848,     0, 16384, 24576, 26624, 27648, 
+    27904, 27840, 27848, 27850,     0, 16384, 24576, 26624, 
+    27648, 27904, 27840, 27848,     0, 16384, 24576, 26624, 
+    27648, 27904, 27840, 27856, 27852,     0, 16384, 24576, 
+    26624, 27648, 27904, 27840, 27856, 27852,     0, 16384, 
+    24576, 26624, 27648, 27904, 27840, 27856, 27857, 27854, 
+        0, 16384, 24576, 26624, 27648, 27904, 27840,     0, 
+    16384, 24576, 26624, 27648, 27904, 27840, 27856,     0, 
+    16384, 24576, 26624, 27648, 27904, 27840, 27856,     0, 
+    16384, 24576, 26624, 27648, 27904, 27840, 27856, 27858, 
+        0, 16384, 24576, 26624, 27648, 27904, 27840, 27856, 
+        0, 16384, 24576, 26624, 27648, 27904, 27840, 27856, 
+    27860,     0, 16384, 24576, 26624, 27648, 27904, 27840, 
+    27856, 27860,     0, 16384, 24576, 26624, 27648, 27904, 
+    27840, 27856, 27864, 27862,     0, 16384, 24576, 26624, 
+    27648, 27904, 27840, 27856,     0, 16384, 24576, 26624, 
+    27648, 27904, 27840, 27872, 27864,     0, 16384, 24576, 
+    26624, 27648, 27904, 27840, 27872, 27864,     0, 16384, 
+    24576, 26624, 27648, 27904, 27840, 27872, 27864, 27866, 
+        0, 16384, 24576, 26624, 27648, 27904, 27840, 27872, 
+    27864,     0, 16384, 24576, 26624, 27648, 27904, 27840, 
+    27872, 27873, 27868,     0, 16384, 24576, 26624, 27648, 
+    27904, 27840, 27872, 27873, 27868,     0, 16384, 24576, 
+    26624, 27648, 27904, 27840, 27872, 27873, 27868, 27870, 
+        0, 16384, 24576, 26624, 27648, 27904, 27840,     0, 
+    16384, 24576, 26624, 27648, 27904, 27905, 27872,     0, 
+    16384, 24576, 26624, 27648, 27904, 27905, 27872,     0, 
+    16384, 24576, 26624, 27648, 27904, 27905, 27872, 27874, 
+        0, 16384, 24576, 26624, 27648, 27904, 27905, 27872, 
+        0, 16384, 24576, 26624, 27648, 27904, 27905, 27872, 
+    27876,     0, 16384, 24576, 26624, 27648, 27904, 27905, 
+    27872, 27876,     0, 16384, 24576, 26624, 27648, 27904, 
+    27905, 27872, 27880, 27878,     0, 16384, 24576, 26624, 
+    27648, 27904, 27905, 27872,     0, 16384, 24576, 26624, 
+    27648, 27904, 27905, 27872, 27880,     0, 16384, 24576, 
+    26624, 27648, 27904, 27905, 27872, 27880,     0, 16384, 
+    24576, 26624, 27648, 27904, 27905, 27872, 27880, 27882, 
+        0, 16384, 24576, 26624, 27648, 27904, 27905, 27872, 
+    27880,     0, 16384, 24576, 26624, 27648, 27904, 27905, 
+    27872, 27888, 27884,     0, 16384, 24576, 26624, 27648, 
+    27904, 27905, 27872, 27888, 27884,     0, 16384, 24576, 
+    26624, 27648, 27904, 27905, 27872, 27888, 27889, 27886, 
+        0, 16384, 24576, 26624, 27648, 27904, 27905, 27872, 
+        0, 16384, 24576, 26624, 27648, 27904, 27905, 27872, 
+    27888,     0, 16384, 24576, 26624, 27648, 27904, 27905, 
+    27907, 27888,     0, 16384, 24576, 26624, 27648, 27904, 
+    27905, 27907, 27888, 27890,     0, 16384, 24576, 26624, 
+    27648, 27904, 27905, 27907, 27888,     0, 16384, 24576, 
+    26624, 27648, 27904, 27905, 27907, 27888, 27892,     0, 
+    16384, 24576, 26624, 27648, 27904, 27905, 27907, 27888, 
+    27892,     0, 16384, 24576, 26624, 27648, 27904, 27905, 
+    27907, 27888, 27896, 27894,     0, 16384, 24576, 26624, 
+    27648, 27904, 27905, 27907, 27888,     0, 16384, 24576, 
+    26624, 27648, 27904, 27905, 27907, 27888, 27896,     0, 
+    16384, 24576, 26624, 27648, 27904, 27905, 27907, 27888, 
+    27896,     0, 16384, 24576, 26624, 27648, 27904, 27905, 
+    27907, 27888, 27896, 27898,     0, 16384, 24576, 26624, 
+    27648, 27904, 27905, 27907, 27911, 27896,     0, 16384, 
+    24576, 26624, 27648, 27904, 27905, 27907, 27911, 27896, 
+    27900,     0, 16384, 24576, 26624, 27648, 27904, 27905, 
+    27907, 27911, 27896, 27900,     0, 16384, 24576, 26624, 
+    27648, 27904, 27905, 27907, 27911, 27896, 27900, 27902, 
+        0, 16384, 24576, 26624, 27648,     0, 16384, 24576, 
+    28672, 27648, 27904,     0, 16384, 24576, 28672, 27648, 
+    27904,     0, 16384, 24576, 28672, 27648, 27904, 27906, 
+        0, 16384, 24576, 28672, 27648, 27904,     0, 16384, 
+    24576, 28672, 27648, 27904, 27908,     0, 16384, 24576, 
+    28672, 27648, 27904, 27908,     0, 16384, 24576, 28672, 
+    27648, 27904, 27912, 27910,     0, 16384, 24576, 28672, 
+    27648, 27904,     0, 16384, 24576, 28672, 27648, 27904, 
+    27912,     0, 16384, 24576, 28672, 27648, 27904, 27912, 
+        0, 16384, 24576, 28672, 27648, 27904, 27912, 27914, 
+        0, 16384, 24576, 28672, 27648, 27904, 27912,     0, 
+    16384, 24576, 28672, 27648, 27904, 27920, 27916,     0, 
+    16384, 24576, 28672, 27648, 27904, 27920, 27916,     0, 
+    16384, 24576, 28672, 27648, 27904, 27920, 27921, 27918, 
+        0, 16384, 24576, 28672, 27648, 27904,     0, 16384, 
+    24576, 28672, 27648, 27904, 27920,     0, 16384, 24576, 
+    28672, 27648, 27904, 27920,     0, 16384, 24576, 28672, 
+    27648, 27904, 27920, 27922,     0, 16384, 24576, 28672, 
+    27648, 27904, 27920,     0, 16384, 24576, 28672, 27648, 
+    27904, 27920, 27924,     0, 16384, 24576, 28672, 27648, 
+    27904, 27920, 27924,     0, 16384, 24576, 28672, 27648, 
+    27904, 27920, 27928, 27926,     0, 16384, 24576, 28672, 
+    27648, 27904, 27920,     0, 16384, 24576, 28672, 27648, 
+    27904, 27936, 27928,     0, 16384, 24576, 28672, 27648, 
+    27904, 27936, 27928,     0, 16384, 24576, 28672, 27648, 
+    27904, 27936, 27928, 27930,     0, 16384, 24576, 28672, 
+    27648, 27904, 27936, 27928,     0, 16384, 24576, 28672, 
+    27648, 27904, 27936, 27937, 27932,     0, 16384, 24576, 
+    28672, 27648, 27904, 27936, 27937, 27932,     0, 16384, 
+    24576, 28672, 27648, 27904, 27936, 27937, 27932, 27934, 
+        0, 16384, 24576, 28672, 27648, 27904,     0, 16384, 
+    24576, 28672, 27648, 27904, 27936,     0, 16384, 24576, 
+    28672, 27648, 27904, 27936,     0, 16384, 24576, 28672, 
+    27648, 27904, 27936, 27938,     0, 16384, 24576, 28672, 
+    27648, 27904, 27936,     0, 16384, 24576, 28672, 27648, 
+    27904, 27936, 27940,     0, 16384, 24576, 28672, 27648, 
+    27904, 27936, 27940,     0, 16384, 24576, 28672, 27648, 
+    27904, 27936, 27944, 27942,     0, 16384, 24576, 28672, 
+    27648, 27904, 27936,     0, 16384, 24576, 28672, 27648, 
+    27904, 27936, 27944,     0, 16384, 24576, 28672, 27648, 
+    27904, 27936, 27944,     0, 16384, 24576, 28672, 27648, 
+    27904, 27936, 27944, 27946,     0, 16384, 24576, 28672, 
+    27648, 27904, 27936, 27944,     0, 16384, 24576, 28672, 
+    27648, 27904, 27936, 27952, 27948,     0, 16384, 24576, 
+    28672, 27648, 27904, 27936, 27952, 27948,     0, 16384, 
+    24576, 28672, 27648, 27904, 27936, 27952, 27953, 27950, 
+        0, 16384, 24576, 28672, 27648, 27904, 27936,     0, 
+    16384, 24576, 28672, 27648, 27904, 27968, 27952,     0, 
+    16384, 24576, 28672, 27648, 27904, 27968, 27952,     0, 
+    16384, 24576, 28672, 27648, 27904, 27968, 27952, 27954, 
+        0, 16384, 24576, 28672, 27648, 27904, 27968, 27952, 
+        0, 16384, 24576, 28672, 27648, 27904, 27968, 27952, 
+    27956,     0, 16384, 24576, 28672, 27648, 27904, 27968, 
+    27952, 27956,     0, 16384, 24576, 28672, 27648, 27904, 
+    27968, 27952, 27960, 27958,     0, 16384, 24576, 28672, 
+    27648, 27904, 27968, 27952,     0, 16384, 24576, 28672, 
+    27648, 27904, 27968, 27969, 27960,     0, 16384, 24576, 
+    28672, 27648, 27904, 27968, 27969, 27960,     0, 16384, 
+    24576, 28672, 27648, 27904, 27968, 27969, 27960, 27962, 
+        0, 16384, 24576, 28672, 27648, 27904, 27968, 27969, 
+    27960,     0, 16384, 24576, 28672, 27648, 27904, 27968, 
+    27969, 27960, 27964,     0, 16384, 24576, 28672, 27648, 
+    27904, 27968, 27969, 27971, 27964,     0, 16384, 24576, 
+    28672, 27648, 27904, 27968, 27969, 27971, 27964, 27966, 
+        0, 16384, 24576, 28672, 27648, 27904,     0, 16384, 
+    24576, 28672, 27648, 27904, 27968,     0, 16384, 24576, 
+    28672, 27648, 27904, 27968,     0, 16384, 24576, 28672, 
+    27648, 27904, 27968, 27970,     0, 16384, 24576, 28672, 
+    27648, 27904, 27968,     0, 16384, 24576, 28672, 27648, 
+    27904, 27968, 27972,     0, 16384, 24576, 28672, 27648, 
+    27904, 27968, 27972,     0, 16384, 24576, 28672, 27648, 
+    27904, 27968, 27976, 27974,     0, 16384, 24576, 28672, 
+    27648, 27904, 27968,     0, 16384, 24576, 28672, 27648, 
+    27904, 27968, 27976,     0, 16384, 24576, 28672, 27648, 
+    27904, 27968, 27976,     0, 16384, 24576, 28672, 27648, 
+    27904, 27968, 27976, 27978,     0, 16384, 24576, 28672, 
+    27648, 27904, 27968, 27976,     0, 16384, 24576, 28672, 
+    27648, 27904, 27968, 27984, 27980,     0, 16384, 24576, 
+    28672, 27648, 27904, 27968, 27984, 27980,     0, 16384, 
+    24576, 28672, 27648, 27904, 27968, 27984, 27985, 27982, 
+        0, 16384, 24576, 28672, 27648, 27904, 27968,     0, 
+    16384, 24576, 28672, 27648, 27904, 27968, 27984,     0, 
+    16384, 24576, 28672, 27648, 27904, 27968, 27984,     0, 
+    16384, 24576, 28672, 27648, 27904, 27968, 27984, 27986, 
+        0, 16384, 24576, 28672, 27648, 27904, 27968, 27984, 
+        0, 16384, 24576, 28672, 27648, 27904, 27968, 27984, 
+    27988,     0, 16384, 24576, 28672, 27648, 27904, 27968, 
+    27984, 27988,     0, 16384, 24576, 28672, 27648, 27904, 
+    27968, 27984, 27992, 27990,     0, 16384, 24576, 28672, 
+    27648, 27904, 27968, 27984,     0, 16384, 24576, 28672, 
+    27648, 27904, 27968, 28000, 27992,     0, 16384, 24576, 
+    28672, 27648, 27904, 27968, 28000, 27992,     0, 16384, 
+    24576, 28672, 27648, 27904, 27968, 28000, 27992, 27994, 
+        0, 16384, 24576, 28672, 27648, 27904, 27968, 28000, 
+    27992,     0, 16384, 24576, 28672, 27648, 27904, 27968, 
+    28000, 28001, 27996,     0, 16384, 24576, 28672, 27648, 
+    27904, 27968, 28000, 28001, 27996,     0, 16384, 24576, 
+    28672, 27648, 27904, 27968, 28000, 28001, 27996, 27998, 
+        0, 16384, 24576, 28672, 27648, 27904, 27968,     0, 
+    16384, 24576, 28672, 27648, 27904, 28032, 28000,     0, 
+    16384, 24576, 28672, 27648, 27904, 28032, 28000,     0, 
+    16384, 24576, 28672, 27648, 27904, 28032, 28000, 28002, 
+        0, 16384, 24576, 28672, 27648, 27904, 28032, 28000, 
+        0, 16384, 24576, 28672, 27648, 27904, 28032, 28000, 
+    28004,     0, 16384, 24576, 28672, 27648, 27904, 28032, 
+    28000, 28004,     0, 16384, 24576, 28672, 27648, 27904, 
+    28032, 28000, 28008, 28006,     0, 16384, 24576, 28672, 
+    27648, 27904, 28032, 28000,     0, 16384, 24576, 28672, 
+    27648, 27904, 28032, 28000, 28008,     0, 16384, 24576, 
+    28672, 27648, 27904, 28032, 28000, 28008,     0, 16384, 
+    24576, 28672, 27648, 27904, 28032, 28000, 28008, 28010, 
+        0, 16384, 24576, 28672, 27648, 27904, 28032, 28000, 
+    28008,     0, 16384, 24576, 28672, 27648, 27904, 28032, 
+    28000, 28016, 28012,     0, 16384, 24576, 28672, 27648, 
+    27904, 28032, 28000, 28016, 28012,     0, 16384, 24576, 
+    28672, 27648, 27904, 28032, 28000, 28016, 28017, 28014, 
+        0, 16384, 24576, 28672, 27648, 27904, 28032, 28000, 
+        0, 16384, 24576, 28672, 27648, 27904, 28032, 28033, 
+    28016,     0, 16384, 24576, 28672, 27648, 27904, 28032, 
+    28033, 28016,     0, 16384, 24576, 28672, 27648, 27904, 
+    28032, 28033, 28016, 28018,     0, 16384, 24576, 28672, 
+    27648, 27904, 28032, 28033, 28016,     0, 16384, 24576, 
+    28672, 27648, 27904, 28032, 28033, 28016, 28020,     0, 
+    16384, 24576, 28672, 27648, 27904, 28032, 28033, 28016, 
+    28020,     0, 16384, 24576, 28672, 27648, 27904, 28032, 
+    28033, 28016, 28024, 28022,     0, 16384, 24576, 28672, 
+    27648, 27904, 28032, 28033, 28016,     0, 16384, 24576, 
+    28672, 27648, 27904, 28032, 28033, 28016, 28024,     0, 
+    16384, 24576, 28672, 27648, 27904, 28032, 28033, 28035, 
+    28024,     0, 16384, 24576, 28672, 27648, 27904, 28032, 
+    28033, 28035, 28024, 28026,     0, 16384, 24576, 28672, 
+    27648, 27904, 28032, 28033, 28035, 28024,     0, 16384, 
+    24576, 28672, 27648, 27904, 28032, 28033, 28035, 28024, 
+    28028,     0, 16384, 24576, 28672, 27648, 27904, 28032, 
+    28033, 28035, 28024, 28028,     0, 16384, 24576, 28672, 
+    27648, 27904, 28032, 28033, 28035, 28024, 28028, 28030, 
+        0, 16384, 24576, 28672, 27648, 27904,     0, 16384, 
+    24576, 28672, 27648, 28160, 28032,     0, 16384, 24576, 
+    28672, 27648, 28160, 28032,     0, 16384, 24576, 28672, 
+    27648, 28160, 28032, 28034,     0, 16384, 24576, 28672, 
+    27648, 28160, 28032,     0, 16384, 24576, 28672, 27648, 
+    28160, 28032, 28036,     0, 16384, 24576, 28672, 27648, 
+    28160, 28032, 28036,     0, 16384, 24576, 28672, 27648, 
+    28160, 28032, 28040, 28038,     0, 16384, 24576, 28672, 
+    27648, 28160, 28032,     0, 16384, 24576, 28672, 27648, 
+    28160, 28032, 28040,     0, 16384, 24576, 28672, 27648, 
+    28160, 28032, 28040,     0, 16384, 24576, 28672, 27648, 
+    28160, 28032, 28040, 28042,     0, 16384, 24576, 28672, 
+    27648, 28160, 28032, 28040,     0, 16384, 24576, 28672, 
+    27648, 28160, 28032, 28048, 28044,     0, 16384, 24576, 
+    28672, 27648, 28160, 28032, 28048, 28044,     0, 16384, 
+    24576, 28672, 27648, 28160, 28032, 28048, 28049, 28046, 
+        0, 16384, 24576, 28672, 27648, 28160, 28032,     0, 
+    16384, 24576, 28672, 27648, 28160, 28032, 28048,     0, 
+    16384, 24576, 28672, 27648, 28160, 28032, 28048,     0, 
+    16384, 24576, 28672, 27648, 28160, 28032, 28048, 28050, 
+        0, 16384, 24576, 28672, 27648, 28160, 28032, 28048, 
+        0, 16384, 24576, 28672, 27648, 28160, 28032, 28048, 
+    28052,     0, 16384, 24576, 28672, 27648, 28160, 28032, 
+    28048, 28052,     0, 16384, 24576, 28672, 27648, 28160, 
+    28032, 28048, 28056, 28054,     0, 16384, 24576, 28672, 
+    27648, 28160, 28032, 28048,     0, 16384, 24576, 28672, 
+    27648, 28160, 28032, 28064, 28056,     0, 16384, 24576, 
+    28672, 27648, 28160, 28032, 28064, 28056,     0, 16384, 
+    24576, 28672, 27648, 28160, 28032, 28064, 28056, 28058, 
+        0, 16384, 24576, 28672, 27648, 28160, 28032, 28064, 
+    28056,     0, 16384, 24576, 28672, 27648, 28160, 28032, 
+    28064, 28065, 28060,     0, 16384, 24576, 28672, 27648, 
+    28160, 28032, 28064, 28065, 28060,     0, 16384, 24576, 
+    28672, 27648, 28160, 28032, 28064, 28065, 28060, 28062, 
+        0, 16384, 24576, 28672, 27648, 28160, 28032,     0, 
+    16384, 24576, 28672, 27648, 28160, 28032, 28064,     0, 
+    16384, 24576, 28672, 27648, 28160, 28032, 28064,     0, 
+    16384, 24576, 28672, 27648, 28160, 28032, 28064, 28066, 
+        0, 16384, 24576, 28672, 27648, 28160, 28032, 28064, 
+        0, 16384, 24576, 28672, 27648, 28160, 28032, 28064, 
+    28068,     0, 16384, 24576, 28672, 27648, 28160, 28032, 
+    28064, 28068,     0, 16384, 24576, 28672, 27648, 28160, 
+    28032, 28064, 28072, 28070,     0, 16384, 24576, 28672, 
+    27648, 28160, 28032, 28064,     0, 16384, 24576, 28672, 
+    27648, 28160, 28032, 28064, 28072,     0, 16384, 24576, 
+    28672, 27648, 28160, 28032, 28064, 28072,     0, 16384, 
+    24576, 28672, 27648, 28160, 28032, 28064, 28072, 28074, 
+        0, 16384, 24576, 28672, 27648, 28160, 28032, 28064, 
+    28072,     0, 16384, 24576, 28672, 27648, 28160, 28032, 
+    28064, 28080, 28076,     0, 16384, 24576, 28672, 27648, 
+    28160, 28032, 28064, 28080, 28076,     0, 16384, 24576, 
+    28672, 27648, 28160, 28032, 28064, 28080, 28081, 28078, 
+        0, 16384, 24576, 28672, 27648, 28160, 28032, 28064, 
+        0, 16384, 24576, 28672, 27648, 28160, 28032, 28096, 
+    28080,     0, 16384, 24576, 28672, 27648, 28160, 28032, 
+    28096, 28080,     0, 16384, 24576, 28672, 27648, 28160, 
+    28032, 28096, 28080, 28082,     0, 16384, 24576, 28672, 
+    27648, 28160, 28032, 28096, 28080,     0, 16384, 24576, 
+    28672, 27648, 28160, 28032, 28096, 28080, 28084,     0, 
+    16384, 24576, 28672, 27648, 28160, 28032, 28096, 28080, 
+    28084,     0, 16384, 24576, 28672, 27648, 28160, 28032, 
+    28096, 28080, 28088, 28086,     0, 16384, 24576, 28672, 
+    27648, 28160, 28032, 28096, 28080,     0, 16384, 24576, 
+    28672, 27648, 28160, 28032, 28096, 28097, 28088,     0, 
+    16384, 24576, 28672, 27648, 28160, 28032, 28096, 28097, 
+    28088,     0, 16384, 24576, 28672, 27648, 28160, 28032, 
+    28096, 28097, 28088, 28090,     0, 16384, 24576, 28672, 
+    27648, 28160, 28032, 28096, 28097, 28088,     0, 16384, 
+    24576, 28672, 27648, 28160, 28032, 28096, 28097, 28088, 
+    28092,     0, 16384, 24576, 28672, 27648, 28160, 28032, 
+    28096, 28097, 28099, 28092,     0, 16384, 24576, 28672, 
+    27648, 28160, 28032, 28096, 28097, 28099, 28092, 28094, 
+        0, 16384, 24576, 28672, 27648, 28160, 28032,     0, 
+    16384, 24576, 28672, 27648, 28160, 28161, 28096,     0, 
+    16384, 24576, 28672, 27648, 28160, 28161, 28096,     0, 
+    16384, 24576, 28672, 27648, 28160, 28161, 28096, 28098, 
+        0, 16384, 24576, 28672, 27648, 28160, 28161, 28096, 
+        0, 16384, 24576, 28672, 27648, 28160, 28161, 28096, 
+    28100,     0, 16384, 24576, 28672, 27648, 28160, 28161, 
+    28096, 28100,     0, 16384, 24576, 28672, 27648, 28160, 
+    28161, 28096, 28104, 28102,     0, 16384, 24576, 28672, 
+    27648, 28160, 28161, 28096,     0, 16384, 24576, 28672, 
+    27648, 28160, 28161, 28096, 28104,     0, 16384, 24576, 
+    28672, 27648, 28160, 28161, 28096, 28104,     0, 16384, 
+    24576, 28672, 27648, 28160, 28161, 28096, 28104, 28106, 
+        0, 16384, 24576, 28672, 27648, 28160, 28161, 28096, 
+    28104,     0, 16384, 24576, 28672, 27648, 28160, 28161, 
+    28096, 28112, 28108,     0, 16384, 24576, 28672, 27648, 
+    28160, 28161, 28096, 28112, 28108,     0, 16384, 24576, 
+    28672, 27648, 28160, 28161, 28096, 28112, 28113, 28110, 
+        0, 16384, 24576, 28672, 27648, 28160, 28161, 28096, 
+        0, 16384, 24576, 28672, 27648, 28160, 28161, 28096, 
+    28112,     0, 16384, 24576, 28672, 27648, 28160, 28161, 
+    28096, 28112,     0, 16384, 24576, 28672, 27648, 28160, 
+    28161, 28096, 28112, 28114,     0, 16384, 24576, 28672, 
+    27648, 28160, 28161, 28096, 28112,     0, 16384, 24576, 
+    28672, 27648, 28160, 28161, 28096, 28112, 28116,     0, 
+    16384, 24576, 28672, 27648, 28160, 28161, 28096, 28112, 
+    28116,     0, 16384, 24576, 28672, 27648, 28160, 28161, 
+    28096, 28112, 28120, 28118,     0, 16384, 24576, 28672, 
+    27648, 28160, 28161, 28096, 28112,     0, 16384, 24576, 
+    28672, 27648, 28160, 28161, 28096, 28128, 28120,     0, 
+    16384, 24576, 28672, 27648, 28160, 28161, 28096, 28128, 
+    28120,     0, 16384, 24576, 28672, 27648, 28160, 28161, 
+    28096, 28128, 28120, 28122,     0, 16384, 24576, 28672, 
+    27648, 28160, 28161, 28096, 28128, 28120,     0, 16384, 
+    24576, 28672, 27648, 28160, 28161, 28096, 28128, 28129, 
+    28124,     0, 16384, 24576, 28672, 27648, 28160, 28161, 
+    28096, 28128, 28129, 28124,     0, 16384, 24576, 28672, 
+    27648, 28160, 28161, 28096, 28128, 28129, 28124, 28126, 
+        0, 16384, 24576, 28672, 27648, 28160, 28161, 28096, 
+        0, 16384, 24576, 28672, 27648, 28160, 28161, 28096, 
+    28128,     0, 16384, 24576, 28672, 27648, 28160, 28161, 
+    28163, 28128,     0, 16384, 24576, 28672, 27648, 28160, 
+    28161, 28163, 28128, 28130,     0, 16384, 24576, 28672, 
+    27648, 28160, 28161, 28163, 28128,     0, 16384, 24576, 
+    28672, 27648, 28160, 28161, 28163, 28128, 28132,     0, 
+    16384, 24576, 28672, 27648, 28160, 28161, 28163, 28128, 
+    28132,     0, 16384, 24576, 28672, 27648, 28160, 28161, 
+    28163, 28128, 28136, 28134,     0, 16384, 24576, 28672, 
+    27648, 28160, 28161, 28163, 28128,     0, 16384, 24576, 
+    28672, 27648, 28160, 28161, 28163, 28128, 28136,     0, 
+    16384, 24576, 28672, 27648, 28160, 28161, 28163, 28128, 
+    28136,     0, 16384, 24576, 28672, 27648, 28160, 28161, 
+    28163, 28128, 28136, 28138,     0, 16384, 24576, 28672, 
+    27648, 28160, 28161, 28163, 28128, 28136,     0, 16384, 
+    24576, 28672, 27648, 28160, 28161, 28163, 28128, 28144, 
+    28140,     0, 16384, 24576, 28672, 27648, 28160, 28161, 
+    28163, 28128, 28144, 28140,     0, 16384, 24576, 28672, 
+    27648, 28160, 28161, 28163, 28128, 28144, 28145, 28142, 
+        0, 16384, 24576, 28672, 27648, 28160, 28161, 28163, 
+    28128,     0, 16384, 24576, 28672, 27648, 28160, 28161, 
+    28163, 28128, 28144,     0, 16384, 24576, 28672, 27648, 
+    28160, 28161, 28163, 28128, 28144,     0, 16384, 24576, 
+    28672, 27648, 28160, 28161, 28163, 28128, 28144, 28146, 
+        0, 16384, 24576, 28672, 27648, 28160, 28161, 28163, 
+    28167, 28144,     0, 16384, 24576, 28672, 27648, 28160, 
+    28161, 28163, 28167, 28144, 28148,     0, 16384, 24576, 
+    28672, 27648, 28160, 28161, 28163, 28167, 28144, 28148, 
+        0, 16384, 24576, 28672, 27648, 28160, 28161, 28163, 
+    28167, 28144, 28152, 28150,     0, 16384, 24576, 28672, 
+    27648, 28160, 28161, 28163, 28167, 28144,     0, 16384, 
+    24576, 28672, 27648, 28160, 28161, 28163, 28167, 28144, 
+    28152,     0, 16384, 24576, 28672, 27648, 28160, 28161, 
+    28163, 28167, 28144, 28152,     0, 16384, 24576, 28672, 
+    27648, 28160, 28161, 28163, 28167, 28144, 28152, 28154, 
+        0, 16384, 24576, 28672, 27648, 28160, 28161, 28163, 
+    28167, 28144, 28152,     0, 16384, 24576, 28672, 27648, 
+    28160, 28161, 28163, 28167, 28144, 28152, 28156,     0, 
+    16384, 24576, 28672, 27648, 28160, 28161, 28163, 28167, 
+    28144, 28152, 28156,     0, 16384, 24576, 28672, 27648, 
+    28160, 28161, 28163, 28167, 28144, 28152, 28156, 28158, 
+        0, 16384, 24576, 28672, 27648,     0, 16384, 24576, 
+    28672, 27648, 28160,     0, 16384, 24576, 28672, 28673, 
+    28160,     0, 16384, 24576, 28672, 28673, 28160, 28162, 
+        0, 16384, 24576, 28672, 28673, 28160,     0, 16384, 
+    24576, 28672, 28673, 28160, 28164,     0, 16384, 24576, 
+    28672, 28673, 28160, 28164,     0, 16384, 24576, 28672, 
+    28673, 28160, 28168, 28166,     0, 16384, 24576, 28672, 
+    28673, 28160,     0, 16384, 24576, 28672, 28673, 28160, 
+    28168,     0, 16384, 24576, 28672, 28673, 28160, 28168, 
+        0, 16384, 24576, 28672, 28673, 28160, 28168, 28170, 
+        0, 16384, 24576, 28672, 28673, 28160, 28168,     0, 
+    16384, 24576, 28672, 28673, 28160, 28176, 28172,     0, 
+    16384, 24576, 28672, 28673, 28160, 28176, 28172,     0, 
+    16384, 24576, 28672, 28673, 28160, 28176, 28177, 28174, 
+        0, 16384, 24576, 28672, 28673, 28160,     0, 16384, 
+    24576, 28672, 28673, 28160, 28176,     0, 16384, 24576, 
+    28672, 28673, 28160, 28176,     0, 16384, 24576, 28672, 
+    28673, 28160, 28176, 28178,     0, 16384, 24576, 28672, 
+    28673, 28160, 28176,     0, 16384, 24576, 28672, 28673, 
+    28160, 28176, 28180,     0, 16384, 24576, 28672, 28673, 
+    28160, 28176, 28180,     0, 16384, 24576, 28672, 28673, 
+    28160, 28176, 28184, 28182,     0, 16384, 24576, 28672, 
+    28673, 28160, 28176,     0, 16384, 24576, 28672, 28673, 
+    28160, 28192, 28184,     0, 16384, 24576, 28672, 28673, 
+    28160, 28192, 28184,     0, 16384, 24576, 28672, 28673, 
+    28160, 28192, 28184, 28186,     0, 16384, 24576, 28672, 
+    28673, 28160, 28192, 28184,     0, 16384, 24576, 28672, 
+    28673, 28160, 28192, 28193, 28188,     0, 16384, 24576, 
+    28672, 28673, 28160, 28192, 28193, 28188,     0, 16384, 
+    24576, 28672, 28673, 28160, 28192, 28193, 28188, 28190, 
+        0, 16384, 24576, 28672, 28673, 28160,     0, 16384, 
+    24576, 28672, 28673, 28160, 28192,     0, 16384, 24576, 
+    28672, 28673, 28160, 28192,     0, 16384, 24576, 28672, 
+    28673, 28160, 28192, 28194,     0, 16384, 24576, 28672, 
+    28673, 28160, 28192,     0, 16384, 24576, 28672, 28673, 
+    28160, 28192, 28196,     0, 16384, 24576, 28672, 28673, 
+    28160, 28192, 28196,     0, 16384, 24576, 28672, 28673, 
+    28160, 28192, 28200, 28198,     0, 16384, 24576, 28672, 
+    28673, 28160, 28192,     0, 16384, 24576, 28672, 28673, 
+    28160, 28192, 28200,     0, 16384, 24576, 28672, 28673, 
+    28160, 28192, 28200,     0, 16384, 24576, 28672, 28673, 
+    28160, 28192, 28200, 28202,     0, 16384, 24576, 28672, 
+    28673, 28160, 28192, 28200,     0, 16384, 24576, 28672, 
+    28673, 28160, 28192, 28208, 28204,     0, 16384, 24576, 
+    28672, 28673, 28160, 28192, 28208, 28204,     0, 16384, 
+    24576, 28672, 28673, 28160, 28192, 28208, 28209, 28206, 
+        0, 16384, 24576, 28672, 28673, 28160, 28192,     0, 
+    16384, 24576, 28672, 28673, 28160, 28224, 28208,     0, 
+    16384, 24576, 28672, 28673, 28160, 28224, 28208,     0, 
+    16384, 24576, 28672, 28673, 28160, 28224, 28208, 28210, 
+        0, 16384, 24576, 28672, 28673, 28160, 28224, 28208, 
+        0, 16384, 24576, 28672, 28673, 28160, 28224, 28208, 
+    28212,     0, 16384, 24576, 28672, 28673, 28160, 28224, 
+    28208, 28212,     0, 16384, 24576, 28672, 28673, 28160, 
+    28224, 28208, 28216, 28214,     0, 16384, 24576, 28672, 
+    28673, 28160, 28224, 28208,     0, 16384, 24576, 28672, 
+    28673, 28160, 28224, 28225, 28216,     0, 16384, 24576, 
+    28672, 28673, 28160, 28224, 28225, 28216,     0, 16384, 
+    24576, 28672, 28673, 28160, 28224, 28225, 28216, 28218, 
+        0, 16384, 24576, 28672, 28673, 28160, 28224, 28225, 
+    28216,     0, 16384, 24576, 28672, 28673, 28160, 28224, 
+    28225, 28216, 28220,     0, 16384, 24576, 28672, 28673, 
+    28160, 28224, 28225, 28227, 28220,     0, 16384, 24576, 
+    28672, 28673, 28160, 28224, 28225, 28227, 28220, 28222, 
+        0, 16384, 24576, 28672, 28673, 28160,     0, 16384, 
+    24576, 28672, 28673, 28160, 28224,     0, 16384, 24576, 
+    28672, 28673, 28160, 28224,     0, 16384, 24576, 28672, 
+    28673, 28160, 28224, 28226,     0, 16384, 24576, 28672, 
+    28673, 28160, 28224,     0, 16384, 24576, 28672, 28673, 
+    28160, 28224, 28228,     0, 16384, 24576, 28672, 28673, 
+    28160, 28224, 28228,     0, 16384, 24576, 28672, 28673, 
+    28160, 28224, 28232, 28230,     0, 16384, 24576, 28672, 
+    28673, 28160, 28224,     0, 16384, 24576, 28672, 28673, 
+    28160, 28224, 28232,     0, 16384, 24576, 28672, 28673, 
+    28160, 28224, 28232,     0, 16384, 24576, 28672, 28673, 
+    28160, 28224, 28232, 28234,     0, 16384, 24576, 28672, 
+    28673, 28160, 28224, 28232,     0, 16384, 24576, 28672, 
+    28673, 28160, 28224, 28240, 28236,     0, 16384, 24576, 
+    28672, 28673, 28160, 28224, 28240, 28236,     0, 16384, 
+    24576, 28672, 28673, 28160, 28224, 28240, 28241, 28238, 
+        0, 16384, 24576, 28672, 28673, 28160, 28224,     0, 
+    16384, 24576, 28672, 28673, 28160, 28224, 28240,     0, 
+    16384, 24576, 28672, 28673, 28160, 28224, 28240,     0, 
+    16384, 24576, 28672, 28673, 28160, 28224, 28240, 28242, 
+        0, 16384, 24576, 28672, 28673, 28160, 28224, 28240, 
+        0, 16384, 24576, 28672, 28673, 28160, 28224, 28240, 
+    28244,     0, 16384, 24576, 28672, 28673, 28160, 28224, 
+    28240, 28244,     0, 16384, 24576, 28672, 28673, 28160, 
+    28224, 28240, 28248, 28246,     0, 16384, 24576, 28672, 
+    28673, 28160, 28224, 28240,     0, 16384, 24576, 28672, 
+    28673, 28160, 28224, 28256, 28248,     0, 16384, 24576, 
+    28672, 28673, 28160, 28224, 28256, 28248,     0, 16384, 
+    24576, 28672, 28673, 28160, 28224, 28256, 28248, 28250, 
+        0, 16384, 24576, 28672, 28673, 28160, 28224, 28256, 
+    28248,     0, 16384, 24576, 28672, 28673, 28160, 28224, 
+    28256, 28257, 28252,     0, 16384, 24576, 28672, 28673, 
+    28160, 28224, 28256, 28257, 28252,     0, 16384, 24576, 
+    28672, 28673, 28160, 28224, 28256, 28257, 28252, 28254, 
+        0, 16384, 24576, 28672, 28673, 28160, 28224,     0, 
+    16384, 24576, 28672, 28673, 28160, 28288, 28256,     0, 
+    16384, 24576, 28672, 28673, 28160, 28288, 28256,     0, 
+    16384, 24576, 28672, 28673, 28160, 28288, 28256, 28258, 
+        0, 16384, 24576, 28672, 28673, 28160, 28288, 28256, 
+        0, 16384, 24576, 28672, 28673, 28160, 28288, 28256, 
+    28260,     0, 16384, 24576, 28672, 28673, 28160, 28288, 
+    28256, 28260,     0, 16384, 24576, 28672, 28673, 28160, 
+    28288, 28256, 28264, 28262,     0, 16384, 24576, 28672, 
+    28673, 28160, 28288, 28256,     0, 16384, 24576, 28672, 
+    28673, 28160, 28288, 28256, 28264,     0, 16384, 24576, 
+    28672, 28673, 28160, 28288, 28256, 28264,     0, 16384, 
+    24576, 28672, 28673, 28160, 28288, 28256, 28264, 28266, 
+        0, 16384, 24576, 28672, 28673, 28160, 28288, 28256, 
+    28264,     0, 16384, 24576, 28672, 28673, 28160, 28288, 
+    28256, 28272, 28268,     0, 16384, 24576, 28672, 28673, 
+    28160, 28288, 28256, 28272, 28268,     0, 16384, 24576, 
+    28672, 28673, 28160, 28288, 28256, 28272, 28273, 28270, 
+        0, 16384, 24576, 28672, 28673, 28160, 28288, 28256, 
+        0, 16384, 24576, 28672, 28673, 28160, 28288, 28289, 
+    28272,     0, 16384, 24576, 28672, 28673, 28160, 28288, 
+    28289, 28272,     0, 16384, 24576, 28672, 28673, 28160, 
+    28288, 28289, 28272, 28274,     0, 16384, 24576, 28672, 
+    28673, 28160, 28288, 28289, 28272,     0, 16384, 24576, 
+    28672, 28673, 28160, 28288, 28289, 28272, 28276,     0, 
+    16384, 24576, 28672, 28673, 28160, 28288, 28289, 28272, 
+    28276,     0, 16384, 24576, 28672, 28673, 28160, 28288, 
+    28289, 28272, 28280, 28278,     0, 16384, 24576, 28672, 
+    28673, 28160, 28288, 28289, 28272,     0, 16384, 24576, 
+    28672, 28673, 28160, 28288, 28289, 28272, 28280,     0, 
+    16384, 24576, 28672, 28673, 28160, 28288, 28289, 28291, 
+    28280,     0, 16384, 24576, 28672, 28673, 28160, 28288, 
+    28289, 28291, 28280, 28282,     0, 16384, 24576, 28672, 
+    28673, 28160, 28288, 28289, 28291, 28280,     0, 16384, 
+    24576, 28672, 28673, 28160, 28288, 28289, 28291, 28280, 
+    28284,     0, 16384, 24576, 28672, 28673, 28160, 28288, 
+    28289, 28291, 28280, 28284,     0, 16384, 24576, 28672, 
+    28673, 28160, 28288, 28289, 28291, 28280, 28284, 28286, 
+        0, 16384, 24576, 28672, 28673, 28160,     0, 16384, 
+    24576, 28672, 28673, 28160, 28288,     0, 16384, 24576, 
+    28672, 28673, 28160, 28288,     0, 16384, 24576, 28672, 
+    28673, 28160, 28288, 28290,     0, 16384, 24576, 28672, 
+    28673, 28160, 28288,     0, 16384, 24576, 28672, 28673, 
+    28160, 28288, 28292,     0, 16384, 24576, 28672, 28673, 
+    28160, 28288, 28292,     0, 16384, 24576, 28672, 28673, 
+    28160, 28288, 28296, 28294,     0, 16384, 24576, 28672, 
+    28673, 28160, 28288,     0, 16384, 24576, 28672, 28673, 
+    28160, 28288, 28296,     0, 16384, 24576, 28672, 28673, 
+    28160, 28288, 28296,     0, 16384, 24576, 28672, 28673, 
+    28160, 28288, 28296, 28298,     0, 16384, 24576, 28672, 
+    28673, 28160, 28288, 28296,     0, 16384, 24576, 28672, 
+    28673, 28160, 28288, 28304, 28300,     0, 16384, 24576, 
+    28672, 28673, 28160, 28288, 28304, 28300,     0, 16384, 
+    24576, 28672, 28673, 28160, 28288, 28304, 28305, 28302, 
+        0, 16384, 24576, 28672, 28673, 28160, 28288,     0, 
+    16384, 24576, 28672, 28673, 28160, 28288, 28304,     0, 
+    16384, 24576, 28672, 28673, 28160, 28288, 28304,     0, 
+    16384, 24576, 28672, 28673, 28160, 28288, 28304, 28306, 
+        0, 16384, 24576, 28672, 28673, 28160, 28288, 28304, 
+        0, 16384, 24576, 28672, 28673, 28160, 28288, 28304, 
+    28308,     0, 16384, 24576, 28672, 28673, 28160, 28288, 
+    28304, 28308,     0, 16384, 24576, 28672, 28673, 28160, 
+    28288, 28304, 28312, 28310,     0, 16384, 24576, 28672, 
+    28673, 28160, 28288, 28304,     0, 16384, 24576, 28672, 
+    28673, 28160, 28288, 28320, 28312,     0, 16384, 24576, 
+    28672, 28673, 28160, 28288, 28320, 28312,     0, 16384, 
+    24576, 28672, 28673, 28160, 28288, 28320, 28312, 28314, 
+        0, 16384, 24576, 28672, 28673, 28160, 28288, 28320, 
+    28312,     0, 16384, 24576, 28672, 28673, 28160, 28288, 
+    28320, 28321, 28316,     0, 16384, 24576, 28672, 28673, 
+    28160, 28288, 28320, 28321, 28316,     0, 16384, 24576, 
+    28672, 28673, 28160, 28288, 28320, 28321, 28316, 28318, 
+        0, 16384, 24576, 28672, 28673, 28160, 28288,     0, 
+    16384, 24576, 28672, 28673, 28160, 28288, 28320,     0, 
+    16384, 24576, 28672, 28673, 28160, 28288, 28320,     0, 
+    16384, 24576, 28672, 28673, 28160, 28288, 28320, 28322, 
+        0, 16384, 24576, 28672, 28673, 28160, 28288, 28320, 
+        0, 16384, 24576, 28672, 28673, 28160, 28288, 28320, 
+    28324,     0, 16384, 24576, 28672, 28673, 28160, 28288, 
+    28320, 28324,     0, 16384, 24576, 28672, 28673, 28160, 
+    28288, 28320, 28328, 28326,     0, 16384, 24576, 28672, 
+    28673, 28160, 28288, 28320,     0, 16384, 24576, 28672, 
+    28673, 28160, 28288, 28320, 28328,     0, 16384, 24576, 
+    28672, 28673, 28160, 28288, 28320, 28328,     0, 16384, 
+    24576, 28672, 28673, 28160, 28288, 28320, 28328, 28330, 
+        0, 16384, 24576, 28672, 28673, 28160, 28288, 28320, 
+    28328,     0, 16384, 24576, 28672, 28673, 28160, 28288, 
+    28320, 28336, 28332,     0, 16384, 24576, 28672, 28673, 
+    28160, 28288, 28320, 28336, 28332,     0, 16384, 24576, 
+    28672, 28673, 28160, 28288, 28320, 28336, 28337, 28334, 
+        0, 16384, 24576, 28672, 28673, 28160, 28288, 28320, 
+        0, 16384, 24576, 28672, 28673, 28160, 28288, 28352, 
+    28336,     0, 16384, 24576, 28672, 28673, 28160, 28288, 
+    28352, 28336,     0, 16384, 24576, 28672, 28673, 28160, 
+    28288, 28352, 28336, 28338,     0, 16384, 24576, 28672, 
+    28673, 28160, 28288, 28352, 28336,     0, 16384, 24576, 
+    28672, 28673, 28160, 28288, 28352, 28336, 28340,     0, 
+    16384, 24576, 28672, 28673, 28160, 28288, 28352, 28336, 
+    28340,     0, 16384, 24576, 28672, 28673, 28160, 28288, 
+    28352, 28336, 28344, 28342,     0, 16384, 24576, 28672, 
+    28673, 28160, 28288, 28352, 28336,     0, 16384, 24576, 
+    28672, 28673, 28160, 28288, 28352, 28353, 28344,     0, 
+    16384, 24576, 28672, 28673, 28160, 28288, 28352, 28353, 
+    28344,     0, 16384, 24576, 28672, 28673, 28160, 28288, 
+    28352, 28353, 28344, 28346,     0, 16384, 24576, 28672, 
+    28673, 28160, 28288, 28352, 28353, 28344,     0, 16384, 
+    24576, 28672, 28673, 28160, 28288, 28352, 28353, 28344, 
+    28348,     0, 16384, 24576, 28672, 28673, 28160, 28288, 
+    28352, 28353, 28355, 28348,     0, 16384, 24576, 28672, 
+    28673, 28160, 28288, 28352, 28353, 28355, 28348, 28350, 
+        0, 16384, 24576, 28672, 28673, 28160, 28288,     0, 
+    16384, 24576, 28672, 28673, 28160, 28416, 28352,     0, 
+    16384, 24576, 28672, 28673, 28160, 28416, 28352,     0, 
+    16384, 24576, 28672, 28673, 28160, 28416, 28352, 28354, 
+        0, 16384, 24576, 28672, 28673, 28160, 28416, 28352, 
+        0, 16384, 24576, 28672, 28673, 28160, 28416, 28352, 
+    28356,     0, 16384, 24576, 28672, 28673, 28160, 28416, 
+    28352, 28356,     0, 16384, 24576, 28672, 28673, 28160, 
+    28416, 28352, 28360, 28358,     0, 16384, 24576, 28672, 
+    28673, 28160, 28416, 28352,     0, 16384, 24576, 28672, 
+    28673, 28160, 28416, 28352, 28360,     0, 16384, 24576, 
+    28672, 28673, 28160, 28416, 28352, 28360,     0, 16384, 
+    24576, 28672, 28673, 28160, 28416, 28352, 28360, 28362, 
+        0, 16384, 24576, 28672, 28673, 28160, 28416, 28352, 
+    28360,     0, 16384, 24576, 28672, 28673, 28160, 28416, 
+    28352, 28368, 28364,     0, 16384, 24576, 28672, 28673, 
+    28160, 28416, 28352, 28368, 28364,     0, 16384, 24576, 
+    28672, 28673, 28160, 28416, 28352, 28368, 28369, 28366, 
+        0, 16384, 24576, 28672, 28673, 28160, 28416, 28352, 
+        0, 16384, 24576, 28672, 28673, 28160, 28416, 28352, 
+    28368,     0, 16384, 24576, 28672, 28673, 28160, 28416, 
+    28352, 28368,     0, 16384, 24576, 28672, 28673, 28160, 
+    28416, 28352, 28368, 28370,     0, 16384, 24576, 28672, 
+    28673, 28160, 28416, 28352, 28368,     0, 16384, 24576, 
+    28672, 28673, 28160, 28416, 28352, 28368, 28372,     0, 
+    16384, 24576, 28672, 28673, 28160, 28416, 28352, 28368, 
+    28372,     0, 16384, 24576, 28672, 28673, 28160, 28416, 
+    28352, 28368, 28376, 28374,     0, 16384, 24576, 28672, 
+    28673, 28160, 28416, 28352, 28368,     0, 16384, 24576, 
+    28672, 28673, 28160, 28416, 28352, 28384, 28376,     0, 
+    16384, 24576, 28672, 28673, 28160, 28416, 28352, 28384, 
+    28376,     0, 16384, 24576, 28672, 28673, 28160, 28416, 
+    28352, 28384, 28376, 28378,     0, 16384, 24576, 28672, 
+    28673, 28160, 28416, 28352, 28384, 28376,     0, 16384, 
+    24576, 28672, 28673, 28160, 28416, 28352, 28384, 28385, 
+    28380,     0, 16384, 24576, 28672, 28673, 28160, 28416, 
+    28352, 28384, 28385, 28380,     0, 16384, 24576, 28672, 
+    28673, 28160, 28416, 28352, 28384, 28385, 28380, 28382, 
+        0, 16384, 24576, 28672, 28673, 28160, 28416, 28352, 
+        0, 16384, 24576, 28672, 28673, 28160, 28416, 28417, 
+    28384,     0, 16384, 24576, 28672, 28673, 28160, 28416, 
+    28417, 28384,     0, 16384, 24576, 28672, 28673, 28160, 
+    28416, 28417, 28384, 28386,     0, 16384, 24576, 28672, 
+    28673, 28160, 28416, 28417, 28384,     0, 16384, 24576, 
+    28672, 28673, 28160, 28416, 28417, 28384, 28388,     0, 
+    16384, 24576, 28672, 28673, 28160, 28416, 28417, 28384, 
+    28388,     0, 16384, 24576, 28672, 28673, 28160, 28416, 
+    28417, 28384, 28392, 28390,     0, 16384, 24576, 28672, 
+    28673, 28160, 28416, 28417, 28384,     0, 16384, 24576, 
+    28672, 28673, 28160, 28416, 28417, 28384, 28392,     0, 
+    16384, 24576, 28672, 28673, 28160, 28416, 28417, 28384, 
+    28392,     0, 16384, 24576, 28672, 28673, 28160, 28416, 
+    28417, 28384, 28392, 28394,     0, 16384, 24576, 28672, 
+    28673, 28160, 28416, 28417, 28384, 28392,     0, 16384, 
+    24576, 28672, 28673, 28160, 28416, 28417, 28384, 28400, 
+    28396,     0, 16384, 24576, 28672, 28673, 28160, 28416, 
+    28417, 28384, 28400, 28396,     0, 16384, 24576, 28672, 
+    28673, 28160, 28416, 28417, 28384, 28400, 28401, 28398, 
+        0, 16384, 24576, 28672, 28673, 28160, 28416, 28417, 
+    28384,     0, 16384, 24576, 28672, 28673, 28160, 28416, 
+    28417, 28384, 28400,     0, 16384, 24576, 28672, 28673, 
+    28160, 28416, 28417, 28419, 28400,     0, 16384, 24576, 
+    28672, 28673, 28160, 28416, 28417, 28419, 28400, 28402, 
+        0, 16384, 24576, 28672, 28673, 28160, 28416, 28417, 
+    28419, 28400,     0, 16384, 24576, 28672, 28673, 28160, 
+    28416, 28417, 28419, 28400, 28404,     0, 16384, 24576, 
+    28672, 28673, 28160, 28416, 28417, 28419, 28400, 28404, 
+        0, 16384, 24576, 28672, 28673, 28160, 28416, 28417, 
+    28419, 28400, 28408, 28406,     0, 16384, 24576, 28672, 
+    28673, 28160, 28416, 28417, 28419, 28400,     0, 16384, 
+    24576, 28672, 28673, 28160, 28416, 28417, 28419, 28400, 
+    28408,     0, 16384, 24576, 28672, 28673, 28160, 28416, 
+    28417, 28419, 28400, 28408,     0, 16384, 24576, 28672, 
+    28673, 28160, 28416, 28417, 28419, 28400, 28408, 28410, 
+        0, 16384, 24576, 28672, 28673, 28160, 28416, 28417, 
+    28419, 28423, 28408,     0, 16384, 24576, 28672, 28673, 
+    28160, 28416, 28417, 28419, 28423, 28408, 28412,     0, 
+    16384, 24576, 28672, 28673, 28160, 28416, 28417, 28419, 
+    28423, 28408, 28412,     0, 16384, 24576, 28672, 28673, 
+    28160, 28416, 28417, 28419, 28423, 28408, 28412, 28414, 
+        0, 16384, 24576, 28672, 28673, 28160,     0, 16384, 
+    24576, 28672, 28673, 28160, 28416,     0, 16384, 24576, 
+    28672, 28673, 28160, 28416,     0, 16384, 24576, 28672, 
+    28673, 28160, 28416, 28418,     0, 16384, 24576, 28672, 
+    28673, 28675, 28416,     0, 16384, 24576, 28672, 28673, 
+    28675, 28416, 28420,     0, 16384, 24576, 28672, 28673, 
+    28675, 28416, 28420,     0, 16384, 24576, 28672, 28673, 
+    28675, 28416, 28424, 28422,     0, 16384, 24576, 28672, 
+    28673, 28675, 28416,     0, 16384, 24576, 28672, 28673, 
+    28675, 28416, 28424,     0, 16384, 24576, 28672, 28673, 
+    28675, 28416, 28424,     0, 16384, 24576, 28672, 28673, 
+    28675, 28416, 28424, 28426,     0, 16384, 24576, 28672, 
+    28673, 28675, 28416, 28424,     0, 16384, 24576, 28672, 
+    28673, 28675, 28416, 28432, 28428,     0, 16384, 24576, 
+    28672, 28673, 28675, 28416, 28432, 28428,     0, 16384, 
+    24576, 28672, 28673, 28675, 28416, 28432, 28433, 28430, 
+        0, 16384, 24576, 28672, 28673, 28675, 28416,     0, 
+    16384, 24576, 28672, 28673, 28675, 28416, 28432,     0, 
+    16384, 24576, 28672, 28673, 28675, 28416, 28432,     0, 
+    16384, 24576, 28672, 28673, 28675, 28416, 28432, 28434, 
+        0, 16384, 24576, 28672, 28673, 28675, 28416, 28432, 
+        0, 16384, 24576, 28672, 28673, 28675, 28416, 28432, 
+    28436,     0, 16384, 24576, 28672, 28673, 28675, 28416, 
+    28432, 28436,     0, 16384, 24576, 28672, 28673, 28675, 
+    28416, 28432, 28440, 28438,     0, 16384, 24576, 28672, 
+    28673, 28675, 28416, 28432,     0, 16384, 24576, 28672, 
+    28673, 28675, 28416, 28448, 28440,     0, 16384, 24576, 
+    28672, 28673, 28675, 28416, 28448, 28440,     0, 16384, 
+    24576, 28672, 28673, 28675, 28416, 28448, 28440, 28442, 
+        0, 16384, 24576, 28672, 28673, 28675, 28416, 28448, 
+    28440,     0, 16384, 24576, 28672, 28673, 28675, 28416, 
+    28448, 28449, 28444,     0, 16384, 24576, 28672, 28673, 
+    28675, 28416, 28448, 28449, 28444,     0, 16384, 24576, 
+    28672, 28673, 28675, 28416, 28448, 28449, 28444, 28446, 
+        0, 16384, 24576, 28672, 28673, 28675, 28416,     0, 
+    16384, 24576, 28672, 28673, 28675, 28416, 28448,     0, 
+    16384, 24576, 28672, 28673, 28675, 28416, 28448,     0, 
+    16384, 24576, 28672, 28673, 28675, 28416, 28448, 28450, 
+        0, 16384, 24576, 28672, 28673, 28675, 28416, 28448, 
+        0, 16384, 24576, 28672, 28673, 28675, 28416, 28448, 
+    28452,     0, 16384, 24576, 28672, 28673, 28675, 28416, 
+    28448, 28452,     0, 16384, 24576, 28672, 28673, 28675, 
+    28416, 28448, 28456, 28454,     0, 16384, 24576, 28672, 
+    28673, 28675, 28416, 28448,     0, 16384, 24576, 28672, 
+    28673, 28675, 28416, 28448, 28456,     0, 16384, 24576, 
+    28672, 28673, 28675, 28416, 28448, 28456,     0, 16384, 
+    24576, 28672, 28673, 28675, 28416, 28448, 28456, 28458, 
+        0, 16384, 24576, 28672, 28673, 28675, 28416, 28448, 
+    28456,     0, 16384, 24576, 28672, 28673, 28675, 28416, 
+    28448, 28464, 28460,     0, 16384, 24576, 28672, 28673, 
+    28675, 28416, 28448, 28464, 28460,     0, 16384, 24576, 
+    28672, 28673, 28675, 28416, 28448, 28464, 28465, 28462, 
+        0, 16384, 24576, 28672, 28673, 28675, 28416, 28448, 
+        0, 16384, 24576, 28672, 28673, 28675, 28416, 28480, 
+    28464,     0, 16384, 24576, 28672, 28673, 28675, 28416, 
+    28480, 28464,     0, 16384, 24576, 28672, 28673, 28675, 
+    28416, 28480, 28464, 28466,     0, 16384, 24576, 28672, 
+    28673, 28675, 28416, 28480, 28464,     0, 16384, 24576, 
+    28672, 28673, 28675, 28416, 28480, 28464, 28468,     0, 
+    16384, 24576, 28672, 28673, 28675, 28416, 28480, 28464, 
+    28468,     0, 16384, 24576, 28672, 28673, 28675, 28416, 
+    28480, 28464, 28472, 28470,     0, 16384, 24576, 28672, 
+    28673, 28675, 28416, 28480, 28464,     0, 16384, 24576, 
+    28672, 28673, 28675, 28416, 28480, 28481, 28472,     0, 
+    16384, 24576, 28672, 28673, 28675, 28416, 28480, 28481, 
+    28472,     0, 16384, 24576, 28672, 28673, 28675, 28416, 
+    28480, 28481, 28472, 28474,     0, 16384, 24576, 28672, 
+    28673, 28675, 28416, 28480, 28481, 28472,     0, 16384, 
+    24576, 28672, 28673, 28675, 28416, 28480, 28481, 28472, 
+    28476,     0, 16384, 24576, 28672, 28673, 28675, 28416, 
+    28480, 28481, 28483, 28476,     0, 16384, 24576, 28672, 
+    28673, 28675, 28416, 28480, 28481, 28483, 28476, 28478, 
+        0, 16384, 24576, 28672, 28673, 28675, 28416,     0, 
+    16384, 24576, 28672, 28673, 28675, 28416, 28480,     0, 
+    16384, 24576, 28672, 28673, 28675, 28416, 28480,     0, 
+    16384, 24576, 28672, 28673, 28675, 28416, 28480, 28482, 
+        0, 16384, 24576, 28672, 28673, 28675, 28416, 28480, 
+        0, 16384, 24576, 28672, 28673, 28675, 28416, 28480, 
+    28484,     0, 16384, 24576, 28672, 28673, 28675, 28416, 
+    28480, 28484,     0, 16384, 24576, 28672, 28673, 28675, 
+    28416, 28480, 28488, 28486,     0, 16384, 24576, 28672, 
+    28673, 28675, 28416, 28480,     0, 16384, 24576, 28672, 
+    28673, 28675, 28416, 28480, 28488,     0, 16384, 24576, 
+    28672, 28673, 28675, 28416, 28480, 28488,     0, 16384, 
+    24576, 28672, 28673, 28675, 28416, 28480, 28488, 28490, 
+        0, 16384, 24576, 28672, 28673, 28675, 28416, 28480, 
+    28488,     0, 16384, 24576, 28672, 28673, 28675, 28416, 
+    28480, 28496, 28492,     0, 16384, 24576, 28672, 28673, 
+    28675, 28416, 28480, 28496, 28492,     0, 16384, 24576, 
+    28672, 28673, 28675, 28416, 28480, 28496, 28497, 28494, 
+        0, 16384, 24576, 28672, 28673, 28675, 28416, 28480, 
+        0, 16384, 24576, 28672, 28673, 28675, 28416, 28480, 
+    28496,     0, 16384, 24576, 28672, 28673, 28675, 28416, 
+    28480, 28496,     0, 16384, 24576, 28672, 28673, 28675, 
+    28416, 28480, 28496, 28498,     0, 16384, 24576, 28672, 
+    28673, 28675, 28416, 28480, 28496,     0, 16384, 24576, 
+    28672, 28673, 28675, 28416, 28480, 28496, 28500,     0, 
+    16384, 24576, 28672, 28673, 28675, 28416, 28480, 28496, 
+    28500,     0, 16384, 24576, 28672, 28673, 28675, 28416, 
+    28480, 28496, 28504, 28502,     0, 16384, 24576, 28672, 
+    28673, 28675, 28416, 28480, 28496,     0, 16384, 24576, 
+    28672, 28673, 28675, 28416, 28480, 28512, 28504,     0, 
+    16384, 24576, 28672, 28673, 28675, 28416, 28480, 28512, 
+    28504,     0, 16384, 24576, 28672, 28673, 28675, 28416, 
+    28480, 28512, 28504, 28506,     0, 16384, 24576, 28672, 
+    28673, 28675, 28416, 28480, 28512, 28504,     0, 16384, 
+    24576, 28672, 28673, 28675, 28416, 28480, 28512, 28513, 
+    28508,     0, 16384, 24576, 28672, 28673, 28675, 28416, 
+    28480, 28512, 28513, 28508,     0, 16384, 24576, 28672, 
+    28673, 28675, 28416, 28480, 28512, 28513, 28508, 28510, 
+        0, 16384, 24576, 28672, 28673, 28675, 28416, 28480, 
+        0, 16384, 24576, 28672, 28673, 28675, 28416, 28544, 
+    28512,     0, 16384, 24576, 28672, 28673, 28675, 28416, 
+    28544, 28512,     0, 16384, 24576, 28672, 28673, 28675, 
+    28416, 28544, 28512, 28514,     0, 16384, 24576, 28672, 
+    28673, 28675, 28416, 28544, 28512,     0, 16384, 24576, 
+    28672, 28673, 28675, 28416, 28544, 28512, 28516,     0, 
+    16384, 24576, 28672, 28673, 28675, 28416, 28544, 28512, 
+    28516,     0, 16384, 24576, 28672, 28673, 28675, 28416, 
+    28544, 28512, 28520, 28518,     0, 16384, 24576, 28672, 
+    28673, 28675, 28416, 28544, 28512,     0, 16384, 24576, 
+    28672, 28673, 28675, 28416, 28544, 28512, 28520,     0, 
+    16384, 24576, 28672, 28673, 28675, 28416, 28544, 28512, 
+    28520,     0, 16384, 24576, 28672, 28673, 28675, 28416, 
+    28544, 28512, 28520, 28522,     0, 16384, 24576, 28672, 
+    28673, 28675, 28416, 28544, 28512, 28520,     0, 16384, 
+    24576, 28672, 28673, 28675, 28416, 28544, 28512, 28528, 
+    28524,     0, 16384, 24576, 28672, 28673, 28675, 28416, 
+    28544, 28512, 28528, 28524,     0, 16384, 24576, 28672, 
+    28673, 28675, 28416, 28544, 28512, 28528, 28529, 28526, 
+        0, 16384, 24576, 28672, 28673, 28675, 28416, 28544, 
+    28512,     0, 16384, 24576, 28672, 28673, 28675, 28416, 
+    28544, 28545, 28528,     0, 16384, 24576, 28672, 28673, 
+    28675, 28416, 28544, 28545, 28528,     0, 16384, 24576, 
+    28672, 28673, 28675, 28416, 28544, 28545, 28528, 28530, 
+        0, 16384, 24576, 28672, 28673, 28675, 28416, 28544, 
+    28545, 28528,     0, 16384, 24576, 28672, 28673, 28675, 
+    28416, 28544, 28545, 28528, 28532,     0, 16384, 24576, 
+    28672, 28673, 28675, 28416, 28544, 28545, 28528, 28532, 
+        0, 16384, 24576, 28672, 28673, 28675, 28416, 28544, 
+    28545, 28528, 28536, 28534,     0, 16384, 24576, 28672, 
+    28673, 28675, 28416, 28544, 28545, 28528,     0, 16384, 
+    24576, 28672, 28673, 28675, 28416, 28544, 28545, 28528, 
+    28536,     0, 16384, 24576, 28672, 28673, 28675, 28416, 
+    28544, 28545, 28547, 28536,     0, 16384, 24576, 28672, 
+    28673, 28675, 28416, 28544, 28545, 28547, 28536, 28538, 
+        0, 16384, 24576, 28672, 28673, 28675, 28416, 28544, 
+    28545, 28547, 28536,     0, 16384, 24576, 28672, 28673, 
+    28675, 28416, 28544, 28545, 28547, 28536, 28540,     0, 
+    16384, 24576, 28672, 28673, 28675, 28416, 28544, 28545, 
+    28547, 28536, 28540,     0, 16384, 24576, 28672, 28673, 
+    28675, 28416, 28544, 28545, 28547, 28536, 28540, 28542, 
+        0, 16384, 24576, 28672, 28673, 28675, 28416,     0, 
+    16384, 24576, 28672, 28673, 28675, 28416, 28544,     0, 
+    16384, 24576, 28672, 28673, 28675, 28416, 28544,     0, 
+    16384, 24576, 28672, 28673, 28675, 28416, 28544, 28546, 
+        0, 16384, 24576, 28672, 28673, 28675, 28416, 28544, 
+        0, 16384, 24576, 28672, 28673, 28675, 28416, 28544, 
+    28548,     0, 16384, 24576, 28672, 28673, 28675, 28416, 
+    28544, 28548,     0, 16384, 24576, 28672, 28673, 28675, 
+    28416, 28544, 28552, 28550,     0, 16384, 24576, 28672, 
+    28673, 28675, 28679, 28544,     0, 16384, 24576, 28672, 
+    28673, 28675, 28679, 28544, 28552,     0, 16384, 24576, 
+    28672, 28673, 28675, 28679, 28544, 28552,     0, 16384, 
+    24576, 28672, 28673, 28675, 28679, 28544, 28552, 28554, 
+        0, 16384, 24576, 28672, 28673, 28675, 28679, 28544, 
+    28552,     0, 16384, 24576, 28672, 28673, 28675, 28679, 
+    28544, 28560, 28556,     0, 16384, 24576, 28672, 28673, 
+    28675, 28679, 28544, 28560, 28556,     0, 16384, 24576, 
+    28672, 28673, 28675, 28679, 28544, 28560, 28561, 28558, 
+        0, 16384, 24576, 28672, 28673, 28675, 28679, 28544, 
+        0, 16384, 24576, 28672, 28673, 28675, 28679, 28544, 
+    28560,     0, 16384, 24576, 28672, 28673, 28675, 28679, 
+    28544, 28560,     0, 16384, 24576, 28672, 28673, 28675, 
+    28679, 28544, 28560, 28562,     0, 16384, 24576, 28672, 
+    28673, 28675, 28679, 28544, 28560,     0, 16384, 24576, 
+    28672, 28673, 28675, 28679, 28544, 28560, 28564,     0, 
+    16384, 24576, 28672, 28673, 28675, 28679, 28544, 28560, 
+    28564,     0, 16384, 24576, 28672, 28673, 28675, 28679, 
+    28544, 28560, 28568, 28566,     0, 16384, 24576, 28672, 
+    28673, 28675, 28679, 28544, 28560,     0, 16384, 24576, 
+    28672, 28673, 28675, 28679, 28544, 28576, 28568,     0, 
+    16384, 24576, 28672, 28673, 28675, 28679, 28544, 28576, 
+    28568,     0, 16384, 24576, 28672, 28673, 28675, 28679, 
+    28544, 28576, 28568, 28570,     0, 16384, 24576, 28672, 
+    28673, 28675, 28679, 28544, 28576, 28568,     0, 16384, 
+    24576, 28672, 28673, 28675, 28679, 28544, 28576, 28577, 
+    28572,     0, 16384, 24576, 28672, 28673, 28675, 28679, 
+    28544, 28576, 28577, 28572,     0, 16384, 24576, 28672, 
+    28673, 28675, 28679, 28544, 28576, 28577, 28572, 28574, 
+        0, 16384, 24576, 28672, 28673, 28675, 28679, 28544, 
+        0, 16384, 24576, 28672, 28673, 28675, 28679, 28544, 
+    28576,     0, 16384, 24576, 28672, 28673, 28675, 28679, 
+    28544, 28576,     0, 16384, 24576, 28672, 28673, 28675, 
+    28679, 28544, 28576, 28578,     0, 16384, 24576, 28672, 
+    28673, 28675, 28679, 28544, 28576,     0, 16384, 24576, 
+    28672, 28673, 28675, 28679, 28544, 28576, 28580,     0, 
+    16384, 24576, 28672, 28673, 28675, 28679, 28544, 28576, 
+    28580,     0, 16384, 24576, 28672, 28673, 28675, 28679, 
+    28544, 28576, 28584, 28582,     0, 16384, 24576, 28672, 
+    28673, 28675, 28679, 28544, 28576,     0, 16384, 24576, 
+    28672, 28673, 28675, 28679, 28544, 28576, 28584,     0, 
+    16384, 24576, 28672, 28673, 28675, 28679, 28544, 28576, 
+    28584,     0, 16384, 24576, 28672, 28673, 28675, 28679, 
+    28544, 28576, 28584, 28586,     0, 16384, 24576, 28672, 
+    28673, 28675, 28679, 28544, 28576, 28584,     0, 16384, 
+    24576, 28672, 28673, 28675, 28679, 28544, 28576, 28592, 
+    28588,     0, 16384, 24576, 28672, 28673, 28675, 28679, 
+    28544, 28576, 28592, 28588,     0, 16384, 24576, 28672, 
+    28673, 28675, 28679, 28544, 28576, 28592, 28593, 28590, 
+        0, 16384, 24576, 28672, 28673, 28675, 28679, 28544, 
+    28576,     0, 16384, 24576, 28672, 28673, 28675, 28679, 
+    28544, 28608, 28592,     0, 16384, 24576, 28672, 28673, 
+    28675, 28679, 28544, 28608, 28592,     0, 16384, 24576, 
+    28672, 28673, 28675, 28679, 28544, 28608, 28592, 28594, 
+        0, 16384, 24576, 28672, 28673, 28675, 28679, 28544, 
+    28608, 28592,     0, 16384, 24576, 28672, 28673, 28675, 
+    28679, 28544, 28608, 28592, 28596,     0, 16384, 24576, 
+    28672, 28673, 28675, 28679, 28544, 28608, 28592, 28596, 
+        0, 16384, 24576, 28672, 28673, 28675, 28679, 28544, 
+    28608, 28592, 28600, 28598,     0, 16384, 24576, 28672, 
+    28673, 28675, 28679, 28544, 28608, 28592,     0, 16384, 
+    24576, 28672, 28673, 28675, 28679, 28544, 28608, 28609, 
+    28600,     0, 16384, 24576, 28672, 28673, 28675, 28679, 
+    28544, 28608, 28609, 28600,     0, 16384, 24576, 28672, 
+    28673, 28675, 28679, 28544, 28608, 28609, 28600, 28602, 
+        0, 16384, 24576, 28672, 28673, 28675, 28679, 28544, 
+    28608, 28609, 28600,     0, 16384, 24576, 28672, 28673, 
+    28675, 28679, 28544, 28608, 28609, 28600, 28604,     0, 
+    16384, 24576, 28672, 28673, 28675, 28679, 28544, 28608, 
+    28609, 28611, 28604,     0, 16384, 24576, 28672, 28673, 
+    28675, 28679, 28544, 28608, 28609, 28611, 28604, 28606, 
+        0, 16384, 24576, 28672, 28673, 28675, 28679, 28544, 
+        0, 16384, 24576, 28672, 28673, 28675, 28679, 28544, 
+    28608,     0, 16384, 24576, 28672, 28673, 28675, 28679, 
+    28544, 28608,     0, 16384, 24576, 28672, 28673, 28675, 
+    28679, 28544, 28608, 28610,     0, 16384, 24576, 28672, 
+    28673, 28675, 28679, 28544, 28608,     0, 16384, 24576, 
+    28672, 28673, 28675, 28679, 28544, 28608, 28612,     0, 
+    16384, 24576, 28672, 28673, 28675, 28679, 28544, 28608, 
+    28612,     0, 16384, 24576, 28672, 28673, 28675, 28679, 
+    28544, 28608, 28616, 28614,     0, 16384, 24576, 28672, 
+    28673, 28675, 28679, 28544, 28608,     0, 16384, 24576, 
+    28672, 28673, 28675, 28679, 28544, 28608, 28616,     0, 
+    16384, 24576, 28672, 28673, 28675, 28679, 28544, 28608, 
+    28616,     0, 16384, 24576, 28672, 28673, 28675, 28679, 
+    28544, 28608, 28616, 28618,     0, 16384, 24576, 28672, 
+    28673, 28675, 28679, 28544, 28608, 28616,     0, 16384, 
+    24576, 28672, 28673, 28675, 28679, 28544, 28608, 28624, 
+    28620,     0, 16384, 24576, 28672, 28673, 28675, 28679, 
+    28544, 28608, 28624, 28620,     0, 16384, 24576, 28672, 
+    28673, 28675, 28679, 28544, 28608, 28624, 28625, 28622, 
+        0, 16384, 24576, 28672, 28673, 28675, 28679, 28687, 
+    28608,     0, 16384, 24576, 28672, 28673, 28675, 28679, 
+    28687, 28608, 28624,     0, 16384, 24576, 28672, 28673, 
+    28675, 28679, 28687, 28608, 28624,     0, 16384, 24576, 
+    28672, 28673, 28675, 28679, 28687, 28608, 28624, 28626, 
+        0, 16384, 24576, 28672, 28673, 28675, 28679, 28687, 
+    28608, 28624,     0, 16384, 24576, 28672, 28673, 28675, 
+    28679, 28687, 28608, 28624, 28628,     0, 16384, 24576, 
+    28672, 28673, 28675, 28679, 28687, 28608, 28624, 28628, 
+        0, 16384, 24576, 28672, 28673, 28675, 28679, 28687, 
+    28608, 28624, 28632, 28630,     0, 16384, 24576, 28672, 
+    28673, 28675, 28679, 28687, 28608, 28624,     0, 16384, 
+    24576, 28672, 28673, 28675, 28679, 28687, 28608, 28640, 
+    28632,     0, 16384, 24576, 28672, 28673, 28675, 28679, 
+    28687, 28608, 28640, 28632,     0, 16384, 24576, 28672, 
+    28673, 28675, 28679, 28687, 28608, 28640, 28632, 28634, 
+        0, 16384, 24576, 28672, 28673, 28675, 28679, 28687, 
+    28608, 28640, 28632,     0, 16384, 24576, 28672, 28673, 
+    28675, 28679, 28687, 28608, 28640, 28641, 28636,     0, 
+    16384, 24576, 28672, 28673, 28675, 28679, 28687, 28608, 
+    28640, 28641, 28636,     0, 16384, 24576, 28672, 28673, 
+    28675, 28679, 28687, 28608, 28640, 28641, 28636, 28638, 
+        0, 16384, 24576, 28672, 28673, 28675, 28679, 28687, 
+    28608,     0, 16384, 24576, 28672, 28673, 28675, 28679, 
+    28687, 28608, 28640,     0, 16384, 24576, 28672, 28673, 
+    28675, 28679, 28687, 28608, 28640,     0, 16384, 24576, 
+    28672, 28673, 28675, 28679, 28687, 28608, 28640, 28642, 
+        0, 16384, 24576, 28672, 28673, 28675, 28679, 28687, 
+    28608, 28640,     0, 16384, 24576, 28672, 28673, 28675, 
+    28679, 28687, 28608, 28640, 28644,     0, 16384, 24576, 
+    28672, 28673, 28675, 28679, 28687, 28608, 28640, 28644, 
+        0, 16384, 24576, 28672, 28673, 28675, 28679, 28687, 
+    28608, 28640, 28648, 28646,     0, 16384, 24576, 28672, 
+    28673, 28675, 28679, 28687, 28608, 28640,     0, 16384, 
+    24576, 28672, 28673, 28675, 28679, 28687, 28608, 28640, 
+    28648,     0, 16384, 24576, 28672, 28673, 28675, 28679, 
+    28687, 28608, 28640, 28648,     0, 16384, 24576, 28672, 
+    28673, 28675, 28679, 28687, 28608, 28640, 28648, 28650, 
+        0, 16384, 24576, 28672, 28673, 28675, 28679, 28687, 
+    28608, 28640, 28648,     0, 16384, 24576, 28672, 28673, 
+    28675, 28679, 28687, 28608, 28640, 28656, 28652,     0, 
+    16384, 24576, 28672, 28673, 28675, 28679, 28687, 28608, 
+    28640, 28656, 28652,     0, 16384, 24576, 28672, 28673, 
+    28675, 28679, 28687, 28608, 28640, 28656, 28657, 28654, 
+        0, 16384, 24576, 28672, 28673, 28675, 28679, 28687, 
+    28608, 28640,     0, 16384, 24576, 28672, 28673, 28675, 
+    28679, 28687, 28608, 28640, 28656,     0, 16384, 24576, 
+    28672, 28673, 28675, 28679, 28687, 28608, 28640, 28656, 
+        0, 16384, 24576, 28672, 28673, 28675, 28679, 28687, 
+    28608, 28640, 28656, 28658,     0, 16384, 24576, 28672, 
+    28673, 28675, 28679, 28687, 28608, 28640, 28656,     0, 
+    16384, 24576, 28672, 28673, 28675, 28679, 28687, 28608, 
+    28640, 28656, 28660,     0, 16384, 24576, 28672, 28673, 
+    28675, 28679, 28687, 28608, 28640, 28656, 28660,     0, 
+    16384, 24576, 28672, 28673, 28675, 28679, 28687, 28608, 
+    28640, 28656, 28664, 28662,     0, 16384, 24576, 28672, 
+    28673, 28675, 28679, 28687, 28608, 28640, 28656,     0, 
+    16384, 24576, 28672, 28673, 28675, 28679, 28687, 28608, 
+    28640, 28656, 28664,     0, 16384, 24576, 28672, 28673, 
+    28675, 28679, 28687, 28608, 28640, 28656, 28664,     0, 
+    16384, 24576, 28672, 28673, 28675, 28679, 28687, 28608, 
+    28640, 28656, 28664, 28666,     0, 16384, 24576, 28672, 
+    28673, 28675, 28679, 28687, 28608, 28640, 28656, 28664, 
+        0, 16384, 24576, 28672, 28673, 28675, 28679, 28687, 
+    28608, 28640, 28656, 28664, 28668,     0, 16384, 24576, 
+    28672, 28673, 28675, 28679, 28687, 28608, 28640, 28656, 
+    28664, 28668,     0, 16384, 24576, 28672, 28673, 28675, 
+    28679, 28687, 28608, 28640, 28656, 28664, 28668, 28670, 
+        0, 16384, 24576,     0, 16384, 24576, 28672,     0, 
+    16384, 24576, 28672,     0, 16384, 24576, 28672, 28674, 
+        0, 16384, 24576, 28672,     0, 16384, 24576, 28672, 
+    28676,     0, 16384, 24576, 28672, 28676,     0, 16384, 
+    24576, 28672, 28680, 28678,     0, 16384, 24576, 28672, 
+        0, 16384, 24576, 28672, 28680,     0, 16384, 24576, 
+    28672, 28680,     0, 16384, 24576, 28672, 28680, 28682, 
+        0, 16384, 24576, 28672, 28680,     0, 16384, 24576, 
+    28672, 28688, 28684,     0, 16384, 24576, 28672, 28688, 
+    28684,     0, 16384, 24576, 28672, 28688, 28689, 28686, 
+        0, 16384, 24576, 28672,     0, 16384, 24576, 28672, 
+    28688,     0, 16384, 24576, 28672, 28688,     0, 16384, 
+    24576, 28672, 28688, 28690,     0, 16384, 24576, 28672, 
+    28688,     0, 16384, 24576, 28672, 28688, 28692,     0, 
+    16384, 24576, 28672, 28688, 28692,     0, 16384, 24576, 
+    28672, 28688, 28696, 28694,     0, 16384, 24576, 28672, 
+    28688,     0, 16384, 24576, 28672, 28704, 28696,     0, 
+    16384, 24576, 28672, 28704, 28696,     0, 16384, 24576, 
+    28672, 28704, 28696, 28698,     0, 16384, 24576, 28672, 
+    28704, 28696,     0, 16384, 24576, 28672, 28704, 28705, 
+    28700,     0, 16384, 24576, 28672, 28704, 28705, 28700, 
+        0, 16384, 24576, 28672, 28704, 28705, 28700, 28702, 
+        0, 16384, 24576, 28672,     0, 16384, 24576, 28672, 
+    28704,     0, 16384, 24576, 28672, 28704,     0, 16384, 
+    24576, 28672, 28704, 28706,     0, 16384, 24576, 28672, 
+    28704,     0, 16384, 24576, 28672, 28704, 28708,     0, 
+    16384, 24576, 28672, 28704, 28708,     0, 16384, 24576, 
+    28672, 28704, 28712, 28710,     0, 16384, 24576, 28672, 
+    28704,     0, 16384, 24576, 28672, 28704, 28712,     0, 
+    16384, 24576, 28672, 28704, 28712,     0, 16384, 24576, 
+    28672, 28704, 28712, 28714,     0, 16384, 24576, 28672, 
+    28704, 28712,     0, 16384, 24576, 28672, 28704, 28720, 
+    28716,     0, 16384, 24576, 28672, 28704, 28720, 28716, 
+        0, 16384, 24576, 28672, 28704, 28720, 28721, 28718, 
+        0, 16384, 24576, 28672, 28704,     0, 16384, 24576, 
+    28672, 28736, 28720,     0, 16384, 24576, 28672, 28736, 
+    28720,     0, 16384, 24576, 28672, 28736, 28720, 28722, 
+        0, 16384, 24576, 28672, 28736, 28720,     0, 16384, 
+    24576, 28672, 28736, 28720, 28724,     0, 16384, 24576, 
+    28672, 28736, 28720, 28724,     0, 16384, 24576, 28672, 
+    28736, 28720, 28728, 28726,     0, 16384, 24576, 28672, 
+    28736, 28720,     0, 16384, 24576, 28672, 28736, 28737, 
+    28728,     0, 16384, 24576, 28672, 28736, 28737, 28728, 
+        0, 16384, 24576, 28672, 28736, 28737, 28728, 28730, 
+        0, 16384, 24576, 28672, 28736, 28737, 28728,     0, 
+    16384, 24576, 28672, 28736, 28737, 28728, 28732,     0, 
+    16384, 24576, 28672, 28736, 28737, 28739, 28732,     0, 
+    16384, 24576, 28672, 28736, 28737, 28739, 28732, 28734, 
+        0, 16384, 24576, 28672,     0, 16384, 24576, 28672, 
+    28736,     0, 16384, 24576, 28672, 28736,     0, 16384, 
+    24576, 28672, 28736, 28738,     0, 16384, 24576, 28672, 
+    28736,     0, 16384, 24576, 28672, 28736, 28740,     0, 
+    16384, 24576, 28672, 28736, 28740,     0, 16384, 24576, 
+    28672, 28736, 28744, 28742,     0, 16384, 24576, 28672, 
+    28736,     0, 16384, 24576, 28672, 28736, 28744,     0, 
+    16384, 24576, 28672, 28736, 28744,     0, 16384, 24576, 
+    28672, 28736, 28744, 28746,     0, 16384, 24576, 28672, 
+    28736, 28744,     0, 16384, 24576, 28672, 28736, 28752, 
+    28748,     0, 16384, 24576, 28672, 28736, 28752, 28748, 
+        0, 16384, 24576, 28672, 28736, 28752, 28753, 28750, 
+        0, 16384, 24576, 28672, 28736,     0, 16384, 24576, 
+    28672, 28736, 28752,     0, 16384, 24576, 28672, 28736, 
+    28752,     0, 16384, 24576, 28672, 28736, 28752, 28754, 
+        0, 16384, 24576, 28672, 28736, 28752,     0, 16384, 
+    24576, 28672, 28736, 28752, 28756,     0, 16384, 24576, 
+    28672, 28736, 28752, 28756,     0, 16384, 24576, 28672, 
+    28736, 28752, 28760, 28758,     0, 16384, 24576, 28672, 
+    28736, 28752,     0, 16384, 24576, 28672, 28736, 28768, 
+    28760,     0, 16384, 24576, 28672, 28736, 28768, 28760, 
+        0, 16384, 24576, 28672, 28736, 28768, 28760, 28762, 
+        0, 16384, 24576, 28672, 28736, 28768, 28760,     0, 
+    16384, 24576, 28672, 28736, 28768, 28769, 28764,     0, 
+    16384, 24576, 28672, 28736, 28768, 28769, 28764,     0, 
+    16384, 24576, 28672, 28736, 28768, 28769, 28764, 28766, 
+        0, 16384, 24576, 28672, 28736,     0, 16384, 24576, 
+    28672, 28800, 28768,     0, 16384, 24576, 28672, 28800, 
+    28768,     0, 16384, 24576, 28672, 28800, 28768, 28770, 
+        0, 16384, 24576, 28672, 28800, 28768,     0, 16384, 
+    24576, 28672, 28800, 28768, 28772,     0, 16384, 24576, 
+    28672, 28800, 28768, 28772,     0, 16384, 24576, 28672, 
+    28800, 28768, 28776, 28774,     0, 16384, 24576, 28672, 
+    28800, 28768,     0, 16384, 24576, 28672, 28800, 28768, 
+    28776,     0, 16384, 24576, 28672, 28800, 28768, 28776, 
+        0, 16384, 24576, 28672, 28800, 28768, 28776, 28778, 
+        0, 16384, 24576, 28672, 28800, 28768, 28776,     0, 
+    16384, 24576, 28672, 28800, 28768, 28784, 28780,     0, 
+    16384, 24576, 28672, 28800, 28768, 28784, 28780,     0, 
+    16384, 24576, 28672, 28800, 28768, 28784, 28785, 28782, 
+        0, 16384, 24576, 28672, 28800, 28768,     0, 16384, 
+    24576, 28672, 28800, 28801, 28784,     0, 16384, 24576, 
+    28672, 28800, 28801, 28784,     0, 16384, 24576, 28672, 
+    28800, 28801, 28784, 28786,     0, 16384, 24576, 28672, 
+    28800, 28801, 28784,     0, 16384, 24576, 28672, 28800, 
+    28801, 28784, 28788,     0, 16384, 24576, 28672, 28800, 
+    28801, 28784, 28788,     0, 16384, 24576, 28672, 28800, 
+    28801, 28784, 28792, 28790,     0, 16384, 24576, 28672, 
+    28800, 28801, 28784,     0, 16384, 24576, 28672, 28800, 
+    28801, 28784, 28792,     0, 16384, 24576, 28672, 28800, 
+    28801, 28803, 28792,     0, 16384, 24576, 28672, 28800, 
+    28801, 28803, 28792, 28794,     0, 16384, 24576, 28672, 
+    28800, 28801, 28803, 28792,     0, 16384, 24576, 28672, 
+    28800, 28801, 28803, 28792, 28796,     0, 16384, 24576, 
+    28672, 28800, 28801, 28803, 28792, 28796,     0, 16384, 
+    24576, 28672, 28800, 28801, 28803, 28792, 28796, 28798, 
+        0, 16384, 24576, 28672,     0, 16384, 24576, 28672, 
+    28800,     0, 16384, 24576, 28672, 28800,     0, 16384, 
+    24576, 28672, 28800, 28802,     0, 16384, 24576, 28672, 
+    28800,     0, 16384, 24576, 28672, 28800, 28804,     0, 
+    16384, 24576, 28672, 28800, 28804,     0, 16384, 24576, 
+    28672, 28800, 28808, 28806,     0, 16384, 24576, 28672, 
+    28800,     0, 16384, 24576, 28672, 28800, 28808,     0, 
+    16384, 24576, 28672, 28800, 28808,     0, 16384, 24576, 
+    28672, 28800, 28808, 28810,     0, 16384, 24576, 28672, 
+    28800, 28808,     0, 16384, 24576, 28672, 28800, 28816, 
+    28812,     0, 16384, 24576, 28672, 28800, 28816, 28812, 
+        0, 16384, 24576, 28672, 28800, 28816, 28817, 28814, 
+        0, 16384, 24576, 28672, 28800,     0, 16384, 24576, 
+    28672, 28800, 28816,     0, 16384, 24576, 28672, 28800, 
+    28816,     0, 16384, 24576, 28672, 28800, 28816, 28818, 
+        0, 16384, 24576, 28672, 28800, 28816,     0, 16384, 
+    24576, 28672, 28800, 28816, 28820,     0, 16384, 24576, 
+    28672, 28800, 28816, 28820,     0, 16384, 24576, 28672, 
+    28800, 28816, 28824, 28822,     0, 16384, 24576, 28672, 
+    28800, 28816,     0, 16384, 24576, 28672, 28800, 28832, 
+    28824,     0, 16384, 24576, 28672, 28800, 28832, 28824, 
+        0, 16384, 24576, 28672, 28800, 28832, 28824, 28826, 
+        0, 16384, 24576, 28672, 28800, 28832, 28824,     0, 
+    16384, 24576, 28672, 28800, 28832, 28833, 28828,     0, 
+    16384, 24576, 28672, 28800, 28832, 28833, 28828,     0, 
+    16384, 24576, 28672, 28800, 28832, 28833, 28828, 28830, 
+        0, 16384, 24576, 28672, 28800,     0, 16384, 24576, 
+    28672, 28800, 28832,     0, 16384, 24576, 28672, 28800, 
+    28832,     0, 16384, 24576, 28672, 28800, 28832, 28834, 
+        0, 16384, 24576, 28672, 28800, 28832,     0, 16384, 
+    24576, 28672, 28800, 28832, 28836,     0, 16384, 24576, 
+    28672, 28800, 28832, 28836,     0, 16384, 24576, 28672, 
+    28800, 28832, 28840, 28838,     0, 16384, 24576, 28672, 
+    28800, 28832,     0, 16384, 24576, 28672, 28800, 28832, 
+    28840,     0, 16384, 24576, 28672, 28800, 28832, 28840, 
+        0, 16384, 24576, 28672, 28800, 28832, 28840, 28842, 
+        0, 16384, 24576, 28672, 28800, 28832, 28840,     0, 
+    16384, 24576, 28672, 28800, 28832, 28848, 28844,     0, 
+    16384, 24576, 28672, 28800, 28832, 28848, 28844,     0, 
+    16384, 24576, 28672, 28800, 28832, 28848, 28849, 28846, 
+        0, 16384, 24576, 28672, 28800, 28832,     0, 16384, 
+    24576, 28672, 28800, 28864, 28848,     0, 16384, 24576, 
+    28672, 28800, 28864, 28848,     0, 16384, 24576, 28672, 
+    28800, 28864, 28848, 28850,     0, 16384, 24576, 28672, 
+    28800, 28864, 28848,     0, 16384, 24576, 28672, 28800, 
+    28864, 28848, 28852,     0, 16384, 24576, 28672, 28800, 
+    28864, 28848, 28852,     0, 16384, 24576, 28672, 28800, 
+    28864, 28848, 28856, 28854,     0, 16384, 24576, 28672, 
+    28800, 28864, 28848,     0, 16384, 24576, 28672, 28800, 
+    28864, 28865, 28856,     0, 16384, 24576, 28672, 28800, 
+    28864, 28865, 28856,     0, 16384, 24576, 28672, 28800, 
+    28864, 28865, 28856, 28858,     0, 16384, 24576, 28672, 
+    28800, 28864, 28865, 28856,     0, 16384, 24576, 28672, 
+    28800, 28864, 28865, 28856, 28860,     0, 16384, 24576, 
+    28672, 28800, 28864, 28865, 28867, 28860,     0, 16384, 
+    24576, 28672, 28800, 28864, 28865, 28867, 28860, 28862, 
+        0, 16384, 24576, 28672, 28800,     0, 16384, 24576, 
+    28672, 28928, 28864,     0, 16384, 24576, 28672, 28928, 
+    28864,     0, 16384, 24576, 28672, 28928, 28864, 28866, 
+        0, 16384, 24576, 28672, 28928, 28864,     0, 16384, 
+    24576, 28672, 28928, 28864, 28868,     0, 16384, 24576, 
+    28672, 28928, 28864, 28868,     0, 16384, 24576, 28672, 
+    28928, 28864, 28872, 28870,     0, 16384, 24576, 28672, 
+    28928, 28864,     0, 16384, 24576, 28672, 28928, 28864, 
+    28872,     0, 16384, 24576, 28672, 28928, 28864, 28872, 
+        0, 16384, 24576, 28672, 28928, 28864, 28872, 28874, 
+        0, 16384, 24576, 28672, 28928, 28864, 28872,     0, 
+    16384, 24576, 28672, 28928, 28864, 28880, 28876,     0, 
+    16384, 24576, 28672, 28928, 28864, 28880, 28876,     0, 
+    16384, 24576, 28672, 28928, 28864, 28880, 28881, 28878, 
+        0, 16384, 24576, 28672, 28928, 28864,     0, 16384, 
+    24576, 28672, 28928, 28864, 28880,     0, 16384, 24576, 
+    28672, 28928, 28864, 28880,     0, 16384, 24576, 28672, 
+    28928, 28864, 28880, 28882,     0, 16384, 24576, 28672, 
+    28928, 28864, 28880,     0, 16384, 24576, 28672, 28928, 
+    28864, 28880, 28884,     0, 16384, 24576, 28672, 28928, 
+    28864, 28880, 28884,     0, 16384, 24576, 28672, 28928, 
+    28864, 28880, 28888, 28886,     0, 16384, 24576, 28672, 
+    28928, 28864, 28880,     0, 16384, 24576, 28672, 28928, 
+    28864, 28896, 28888,     0, 16384, 24576, 28672, 28928, 
+    28864, 28896, 28888,     0, 16384, 24576, 28672, 28928, 
+    28864, 28896, 28888, 28890,     0, 16384, 24576, 28672, 
+    28928, 28864, 28896, 28888,     0, 16384, 24576, 28672, 
+    28928, 28864, 28896, 28897, 28892,     0, 16384, 24576, 
+    28672, 28928, 28864, 28896, 28897, 28892,     0, 16384, 
+    24576, 28672, 28928, 28864, 28896, 28897, 28892, 28894, 
+        0, 16384, 24576, 28672, 28928, 28864,     0, 16384, 
+    24576, 28672, 28928, 28929, 28896,     0, 16384, 24576, 
+    28672, 28928, 28929, 28896,     0, 16384, 24576, 28672, 
+    28928, 28929, 28896, 28898,     0, 16384, 24576, 28672, 
+    28928, 28929, 28896,     0, 16384, 24576, 28672, 28928, 
+    28929, 28896, 28900,     0, 16384, 24576, 28672, 28928, 
+    28929, 28896, 28900,     0, 16384, 24576, 28672, 28928, 
+    28929, 28896, 28904, 28902,     0, 16384, 24576, 28672, 
+    28928, 28929, 28896,     0, 16384, 24576, 28672, 28928, 
+    28929, 28896, 28904,     0, 16384, 24576, 28672, 28928, 
+    28929, 28896, 28904,     0, 16384, 24576, 28672, 28928, 
+    28929, 28896, 28904, 28906,     0, 16384, 24576, 28672, 
+    28928, 28929, 28896, 28904,     0, 16384, 24576, 28672, 
+    28928, 28929, 28896, 28912, 28908,     0, 16384, 24576, 
+    28672, 28928, 28929, 28896, 28912, 28908,     0, 16384, 
+    24576, 28672, 28928, 28929, 28896, 28912, 28913, 28910, 
+        0, 16384, 24576, 28672, 28928, 28929, 28896,     0, 
+    16384, 24576, 28672, 28928, 28929, 28896, 28912,     0, 
+    16384, 24576, 28672, 28928, 28929, 28931, 28912,     0, 
+    16384, 24576, 28672, 28928, 28929, 28931, 28912, 28914, 
+        0, 16384, 24576, 28672, 28928, 28929, 28931, 28912, 
+        0, 16384, 24576, 28672, 28928, 28929, 28931, 28912, 
+    28916,     0, 16384, 24576, 28672, 28928, 28929, 28931, 
+    28912, 28916,     0, 16384, 24576, 28672, 28928, 28929, 
+    28931, 28912, 28920, 28918,     0, 16384, 24576, 28672, 
+    28928, 28929, 28931, 28912,     0, 16384, 24576, 28672, 
+    28928, 28929, 28931, 28912, 28920,     0, 16384, 24576, 
+    28672, 28928, 28929, 28931, 28912, 28920,     0, 16384, 
+    24576, 28672, 28928, 28929, 28931, 28912, 28920, 28922, 
+        0, 16384, 24576, 28672, 28928, 28929, 28931, 28935, 
+    28920,     0, 16384, 24576, 28672, 28928, 28929, 28931, 
+    28935, 28920, 28924,     0, 16384, 24576, 28672, 28928, 
+    28929, 28931, 28935, 28920, 28924,     0, 16384, 24576, 
+    28672, 28928, 28929, 28931, 28935, 28920, 28924, 28926, 
+        0, 16384, 24576, 28672,     0, 16384, 24576, 28672, 
+    28928,     0, 16384, 24576, 28672, 28928,     0, 16384, 
+    24576, 28672, 28928, 28930,     0, 16384, 24576, 28672, 
+    28928,     0, 16384, 24576, 28672, 28928, 28932,     0, 
+    16384, 24576, 28672, 28928, 28932,     0, 16384, 24576, 
+    28672, 28928, 28936, 28934,     0, 16384, 24576, 28672, 
+    28928,     0, 16384, 24576, 28672, 28928, 28936,     0, 
+    16384, 24576, 28672, 28928, 28936,     0, 16384, 24576, 
+    28672, 28928, 28936, 28938,     0, 16384, 24576, 28672, 
+    28928, 28936,     0, 16384, 24576, 28672, 28928, 28944, 
+    28940,     0, 16384, 24576, 28672, 28928, 28944, 28940, 
+        0, 16384, 24576, 28672, 28928, 28944, 28945, 28942, 
+        0, 16384, 24576, 28672, 28928,     0, 16384, 24576, 
+    28672, 28928, 28944,     0, 16384, 24576, 28672, 28928, 
+    28944,     0, 16384, 24576, 28672, 28928, 28944, 28946, 
+        0, 16384, 24576, 28672, 28928, 28944,     0, 16384, 
+    24576, 28672, 28928, 28944, 28948,     0, 16384, 24576, 
+    28672, 28928, 28944, 28948,     0, 16384, 24576, 28672, 
+    28928, 28944, 28952, 28950,     0, 16384, 24576, 28672, 
+    28928, 28944,     0, 16384, 24576, 28672, 28928, 28960, 
+    28952,     0, 16384, 24576, 28672, 28928, 28960, 28952, 
+        0, 16384, 24576, 28672, 28928, 28960, 28952, 28954, 
+        0, 16384, 24576, 28672, 28928, 28960, 28952,     0, 
+    16384, 24576, 28672, 28928, 28960, 28961, 28956,     0, 
+    16384, 24576, 28672, 28928, 28960, 28961, 28956,     0, 
+    16384, 24576, 28672, 28928, 28960, 28961, 28956, 28958, 
+        0, 16384, 24576, 28672, 28928,     0, 16384, 24576, 
+    28672, 28928, 28960,     0, 16384, 24576, 28672, 28928, 
+    28960,     0, 16384, 24576, 28672, 28928, 28960, 28962, 
+        0, 16384, 24576, 28672, 28928, 28960,     0, 16384, 
+    24576, 28672, 28928, 28960, 28964,     0, 16384, 24576, 
+    28672, 28928, 28960, 28964,     0, 16384, 24576, 28672, 
+    28928, 28960, 28968, 28966,     0, 16384, 24576, 28672, 
+    28928, 28960,     0, 16384, 24576, 28672, 28928, 28960, 
+    28968,     0, 16384, 24576, 28672, 28928, 28960, 28968, 
+        0, 16384, 24576, 28672, 28928, 28960, 28968, 28970, 
+        0, 16384, 24576, 28672, 28928, 28960, 28968,     0, 
+    16384, 24576, 28672, 28928, 28960, 28976, 28972,     0, 
+    16384, 24576, 28672, 28928, 28960, 28976, 28972,     0, 
+    16384, 24576, 28672, 28928, 28960, 28976, 28977, 28974, 
+        0, 16384, 24576, 28672, 28928, 28960,     0, 16384, 
+    24576, 28672, 28928, 28992, 28976,     0, 16384, 24576, 
+    28672, 28928, 28992, 28976,     0, 16384, 24576, 28672, 
+    28928, 28992, 28976, 28978,     0, 16384, 24576, 28672, 
+    28928, 28992, 28976,     0, 16384, 24576, 28672, 28928, 
+    28992, 28976, 28980,     0, 16384, 24576, 28672, 28928, 
+    28992, 28976, 28980,     0, 16384, 24576, 28672, 28928, 
+    28992, 28976, 28984, 28982,     0, 16384, 24576, 28672, 
+    28928, 28992, 28976,     0, 16384, 24576, 28672, 28928, 
+    28992, 28993, 28984,     0, 16384, 24576, 28672, 28928, 
+    28992, 28993, 28984,     0, 16384, 24576, 28672, 28928, 
+    28992, 28993, 28984, 28986,     0, 16384, 24576, 28672, 
+    28928, 28992, 28993, 28984,     0, 16384, 24576, 28672, 
+    28928, 28992, 28993, 28984, 28988,     0, 16384, 24576, 
+    28672, 28928, 28992, 28993, 28995, 28988,     0, 16384, 
+    24576, 28672, 28928, 28992, 28993, 28995, 28988, 28990, 
+        0, 16384, 24576, 28672, 28928,     0, 16384, 24576, 
+    28672, 28928, 28992,     0, 16384, 24576, 28672, 28928, 
+    28992,     0, 16384, 24576, 28672, 28928, 28992, 28994, 
+        0, 16384, 24576, 28672, 28928, 28992,     0, 16384, 
+    24576, 28672, 28928, 28992, 28996,     0, 16384, 24576, 
+    28672, 28928, 28992, 28996,     0, 16384, 24576, 28672, 
+    28928, 28992, 29000, 28998,     0, 16384, 24576, 28672, 
+    28928, 28992,     0, 16384, 24576, 28672, 28928, 28992, 
+    29000,     0, 16384, 24576, 28672, 28928, 28992, 29000, 
+        0, 16384, 24576, 28672, 28928, 28992, 29000, 29002, 
+        0, 16384, 24576, 28672, 28928, 28992, 29000,     0, 
+    16384, 24576, 28672, 28928, 28992, 29008, 29004,     0, 
+    16384, 24576, 28672, 28928, 28992, 29008, 29004,     0, 
+    16384, 24576, 28672, 28928, 28992, 29008, 29009, 29006, 
+        0, 16384, 24576, 28672, 28928, 28992,     0, 16384, 
+    24576, 28672, 28928, 28992, 29008,     0, 16384, 24576, 
+    28672, 28928, 28992, 29008,     0, 16384, 24576, 28672, 
+    28928, 28992, 29008, 29010,     0, 16384, 24576, 28672, 
+    28928, 28992, 29008,     0, 16384, 24576, 28672, 28928, 
+    28992, 29008, 29012,     0, 16384, 24576, 28672, 28928, 
+    28992, 29008, 29012,     0, 16384, 24576, 28672, 28928, 
+    28992, 29008, 29016, 29014,     0, 16384, 24576, 28672, 
+    28928, 28992, 29008,     0, 16384, 24576, 28672, 28928, 
+    28992, 29024, 29016,     0, 16384, 24576, 28672, 28928, 
+    28992, 29024, 29016,     0, 16384, 24576, 28672, 28928, 
+    28992, 29024, 29016, 29018,     0, 16384, 24576, 28672, 
+    28928, 28992, 29024, 29016,     0, 16384, 24576, 28672, 
+    28928, 28992, 29024, 29025, 29020,     0, 16384, 24576, 
+    28672, 28928, 28992, 29024, 29025, 29020,     0, 16384, 
+    24576, 28672, 28928, 28992, 29024, 29025, 29020, 29022, 
+        0, 16384, 24576, 28672, 28928, 28992,     0, 16384, 
+    24576, 28672, 28928, 29056, 29024,     0, 16384, 24576, 
+    28672, 28928, 29056, 29024,     0, 16384, 24576, 28672, 
+    28928, 29056, 29024, 29026,     0, 16384, 24576, 28672, 
+    28928, 29056, 29024,     0, 16384, 24576, 28672, 28928, 
+    29056, 29024, 29028,     0, 16384, 24576, 28672, 28928, 
+    29056, 29024, 29028,     0, 16384, 24576, 28672, 28928, 
+    29056, 29024, 29032, 29030,     0, 16384, 24576, 28672, 
+    28928, 29056, 29024,     0, 16384, 24576, 28672, 28928, 
+    29056, 29024, 29032,     0, 16384, 24576, 28672, 28928, 
+    29056, 29024, 29032,     0, 16384, 24576, 28672, 28928, 
+    29056, 29024, 29032, 29034,     0, 16384, 24576, 28672, 
+    28928, 29056, 29024, 29032,     0, 16384, 24576, 28672, 
+    28928, 29056, 29024, 29040, 29036,     0, 16384, 24576, 
+    28672, 28928, 29056, 29024, 29040, 29036,     0, 16384, 
+    24576, 28672, 28928, 29056, 29024, 29040, 29041, 29038, 
+        0, 16384, 24576, 28672, 28928, 29056, 29024,     0, 
+    16384, 24576, 28672, 28928, 29056, 29057, 29040,     0, 
+    16384, 24576, 28672, 28928, 29056, 29057, 29040,     0, 
+    16384, 24576, 28672, 28928, 29056, 29057, 29040, 29042, 
+        0, 16384, 24576, 28672, 28928, 29056, 29057, 29040, 
+        0, 16384, 24576, 28672, 28928, 29056, 29057, 29040, 
+    29044,     0, 16384, 24576, 28672, 28928, 29056, 29057, 
+    29040, 29044,     0, 16384, 24576, 28672, 28928, 29056, 
+    29057, 29040, 29048, 29046,     0, 16384, 24576, 28672, 
+    28928, 29056, 29057, 29040,     0, 16384, 24576, 28672, 
+    28928, 29056, 29057, 29040, 29048,     0, 16384, 24576, 
+    28672, 28928, 29056, 29057, 29059, 29048,     0, 16384, 
+    24576, 28672, 28928, 29056, 29057, 29059, 29048, 29050, 
+        0, 16384, 24576, 28672, 28928, 29056, 29057, 29059, 
+    29048,     0, 16384, 24576, 28672, 28928, 29056, 29057, 
+    29059, 29048, 29052,     0, 16384, 24576, 28672, 28928, 
+    29056, 29057, 29059, 29048, 29052,     0, 16384, 24576, 
+    28672, 28928, 29056, 29057, 29059, 29048, 29052, 29054, 
+        0, 16384, 24576, 28672, 28928,     0, 16384, 24576, 
+    28672, 29184, 29056,     0, 16384, 24576, 28672, 29184, 
+    29056,     0, 16384, 24576, 28672, 29184, 29056, 29058, 
+        0, 16384, 24576, 28672, 29184, 29056,     0, 16384, 
+    24576, 28672, 29184, 29056, 29060,     0, 16384, 24576, 
+    28672, 29184, 29056, 29060,     0, 16384, 24576, 28672, 
+    29184, 29056, 29064, 29062,     0, 16384, 24576, 28672, 
+    29184, 29056,     0, 16384, 24576, 28672, 29184, 29056, 
+    29064,     0, 16384, 24576, 28672, 29184, 29056, 29064, 
+        0, 16384, 24576, 28672, 29184, 29056, 29064, 29066, 
+        0, 16384, 24576, 28672, 29184, 29056, 29064,     0, 
+    16384, 24576, 28672, 29184, 29056, 29072, 29068,     0, 
+    16384, 24576, 28672, 29184, 29056, 29072, 29068,     0, 
+    16384, 24576, 28672, 29184, 29056, 29072, 29073, 29070, 
+        0, 16384, 24576, 28672, 29184, 29056,     0, 16384, 
+    24576, 28672, 29184, 29056, 29072,     0, 16384, 24576, 
+    28672, 29184, 29056, 29072,     0, 16384, 24576, 28672, 
+    29184, 29056, 29072, 29074,     0, 16384, 24576, 28672, 
+    29184, 29056, 29072,     0, 16384, 24576, 28672, 29184, 
+    29056, 29072, 29076,     0, 16384, 24576, 28672, 29184, 
+    29056, 29072, 29076,     0, 16384, 24576, 28672, 29184, 
+    29056, 29072, 29080, 29078,     0, 16384, 24576, 28672, 
+    29184, 29056, 29072,     0, 16384, 24576, 28672, 29184, 
+    29056, 29088, 29080,     0, 16384, 24576, 28672, 29184, 
+    29056, 29088, 29080,     0, 16384, 24576, 28672, 29184, 
+    29056, 29088, 29080, 29082,     0, 16384, 24576, 28672, 
+    29184, 29056, 29088, 29080,     0, 16384, 24576, 28672, 
+    29184, 29056, 29088, 29089, 29084,     0, 16384, 24576, 
+    28672, 29184, 29056, 29088, 29089, 29084,     0, 16384, 
+    24576, 28672, 29184, 29056, 29088, 29089, 29084, 29086, 
+        0, 16384, 24576, 28672, 29184, 29056,     0, 16384, 
+    24576, 28672, 29184, 29056, 29088,     0, 16384, 24576, 
+    28672, 29184, 29056, 29088,     0, 16384, 24576, 28672, 
+    29184, 29056, 29088, 29090,     0, 16384, 24576, 28672, 
+    29184, 29056, 29088,     0, 16384, 24576, 28672, 29184, 
+    29056, 29088, 29092,     0, 16384, 24576, 28672, 29184, 
+    29056, 29088, 29092,     0, 16384, 24576, 28672, 29184, 
+    29056, 29088, 29096, 29094,     0, 16384, 24576, 28672, 
+    29184, 29056, 29088,     0, 16384, 24576, 28672, 29184, 
+    29056, 29088, 29096,     0, 16384, 24576, 28672, 29184, 
+    29056, 29088, 29096,     0, 16384, 24576, 28672, 29184, 
+    29056, 29088, 29096, 29098,     0, 16384, 24576, 28672, 
+    29184, 29056, 29088, 29096,     0, 16384, 24576, 28672, 
+    29184, 29056, 29088, 29104, 29100,     0, 16384, 24576, 
+    28672, 29184, 29056, 29088, 29104, 29100,     0, 16384, 
+    24576, 28672, 29184, 29056, 29088, 29104, 29105, 29102, 
+        0, 16384, 24576, 28672, 29184, 29056, 29088,     0, 
+    16384, 24576, 28672, 29184, 29056, 29120, 29104,     0, 
+    16384, 24576, 28672, 29184, 29056, 29120, 29104,     0, 
+    16384, 24576, 28672, 29184, 29056, 29120, 29104, 29106, 
+        0, 16384, 24576, 28672, 29184, 29056, 29120, 29104, 
+        0, 16384, 24576, 28672, 29184, 29056, 29120, 29104, 
+    29108,     0, 16384, 24576, 28672, 29184, 29056, 29120, 
+    29104, 29108,     0, 16384, 24576, 28672, 29184, 29056, 
+    29120, 29104, 29112, 29110,     0, 16384, 24576, 28672, 
+    29184, 29056, 29120, 29104,     0, 16384, 24576, 28672, 
+    29184, 29056, 29120, 29121, 29112,     0, 16384, 24576, 
+    28672, 29184, 29056, 29120, 29121, 29112,     0, 16384, 
+    24576, 28672, 29184, 29056, 29120, 29121, 29112, 29114, 
+        0, 16384, 24576, 28672, 29184, 29056, 29120, 29121, 
+    29112,     0, 16384, 24576, 28672, 29184, 29056, 29120, 
+    29121, 29112, 29116,     0, 16384, 24576, 28672, 29184, 
+    29056, 29120, 29121, 29123, 29116,     0, 16384, 24576, 
+    28672, 29184, 29056, 29120, 29121, 29123, 29116, 29118, 
+        0, 16384, 24576, 28672, 29184, 29056,     0, 16384, 
+    24576, 28672, 29184, 29185, 29120,     0, 16384, 24576, 
+    28672, 29184, 29185, 29120,     0, 16384, 24576, 28672, 
+    29184, 29185, 29120, 29122,     0, 16384, 24576, 28672, 
+    29184, 29185, 29120,     0, 16384, 24576, 28672, 29184, 
+    29185, 29120, 29124,     0, 16384, 24576, 28672, 29184, 
+    29185, 29120, 29124,     0, 16384, 24576, 28672, 29184, 
+    29185, 29120, 29128, 29126,     0, 16384, 24576, 28672, 
+    29184, 29185, 29120,     0, 16384, 24576, 28672, 29184, 
+    29185, 29120, 29128,     0, 16384, 24576, 28672, 29184, 
+    29185, 29120, 29128,     0, 16384, 24576, 28672, 29184, 
+    29185, 29120, 29128, 29130,     0, 16384, 24576, 28672, 
+    29184, 29185, 29120, 29128,     0, 16384, 24576, 28672, 
+    29184, 29185, 29120, 29136, 29132,     0, 16384, 24576, 
+    28672, 29184, 29185, 29120, 29136, 29132,     0, 16384, 
+    24576, 28672, 29184, 29185, 29120, 29136, 29137, 29134, 
+        0, 16384, 24576, 28672, 29184, 29185, 29120,     0, 
+    16384, 24576, 28672, 29184, 29185, 29120, 29136,     0, 
+    16384, 24576, 28672, 29184, 29185, 29120, 29136,     0, 
+    16384, 24576, 28672, 29184, 29185, 29120, 29136, 29138, 
+        0, 16384, 24576, 28672, 29184, 29185, 29120, 29136, 
+        0, 16384, 24576, 28672, 29184, 29185, 29120, 29136, 
+    29140,     0, 16384, 24576, 28672, 29184, 29185, 29120, 
+    29136, 29140,     0, 16384, 24576, 28672, 29184, 29185, 
+    29120, 29136, 29144, 29142,     0, 16384, 24576, 28672, 
+    29184, 29185, 29120, 29136,     0, 16384, 24576, 28672, 
+    29184, 29185, 29120, 29152, 29144,     0, 16384, 24576, 
+    28672, 29184, 29185, 29120, 29152, 29144,     0, 16384, 
+    24576, 28672, 29184, 29185, 29120, 29152, 29144, 29146, 
+        0, 16384, 24576, 28672, 29184, 29185, 29120, 29152, 
+    29144,     0, 16384, 24576, 28672, 29184, 29185, 29120, 
+    29152, 29153, 29148,     0, 16384, 24576, 28672, 29184, 
+    29185, 29120, 29152, 29153, 29148,     0, 16384, 24576, 
+    28672, 29184, 29185, 29120, 29152, 29153, 29148, 29150, 
+        0, 16384, 24576, 28672, 29184, 29185, 29120,     0, 
+    16384, 24576, 28672, 29184, 29185, 29120, 29152,     0, 
+    16384, 24576, 28672, 29184, 29185, 29187, 29152,     0, 
+    16384, 24576, 28672, 29184, 29185, 29187, 29152, 29154, 
+        0, 16384, 24576, 28672, 29184, 29185, 29187, 29152, 
+        0, 16384, 24576, 28672, 29184, 29185, 29187, 29152, 
+    29156,     0, 16384, 24576, 28672, 29184, 29185, 29187, 
+    29152, 29156,     0, 16384, 24576, 28672, 29184, 29185, 
+    29187, 29152, 29160, 29158,     0, 16384, 24576, 28672, 
+    29184, 29185, 29187, 29152,     0, 16384, 24576, 28672, 
+    29184, 29185, 29187, 29152, 29160,     0, 16384, 24576, 
+    28672, 29184, 29185, 29187, 29152, 29160,     0, 16384, 
+    24576, 28672, 29184, 29185, 29187, 29152, 29160, 29162, 
+        0, 16384, 24576, 28672, 29184, 29185, 29187, 29152, 
+    29160,     0, 16384, 24576, 28672, 29184, 29185, 29187, 
+    29152, 29168, 29164,     0, 16384, 24576, 28672, 29184, 
+    29185, 29187, 29152, 29168, 29164,     0, 16384, 24576, 
+    28672, 29184, 29185, 29187, 29152, 29168, 29169, 29166, 
+        0, 16384, 24576, 28672, 29184, 29185, 29187, 29152, 
+        0, 16384, 24576, 28672, 29184, 29185, 29187, 29152, 
+    29168,     0, 16384, 24576, 28672, 29184, 29185, 29187, 
+    29152, 29168,     0, 16384, 24576, 28672, 29184, 29185, 
+    29187, 29152, 29168, 29170,     0, 16384, 24576, 28672, 
+    29184, 29185, 29187, 29191, 29168,     0, 16384, 24576, 
+    28672, 29184, 29185, 29187, 29191, 29168, 29172,     0, 
+    16384, 24576, 28672, 29184, 29185, 29187, 29191, 29168, 
+    29172,     0, 16384, 24576, 28672, 29184, 29185, 29187, 
+    29191, 29168, 29176, 29174,     0, 16384, 24576, 28672, 
+    29184, 29185, 29187, 29191, 29168,     0, 16384, 24576, 
+    28672, 29184, 29185, 29187, 29191, 29168, 29176,     0, 
+    16384, 24576, 28672, 29184, 29185, 29187, 29191, 29168, 
+    29176,     0, 16384, 24576, 28672, 29184, 29185, 29187, 
+    29191, 29168, 29176, 29178,     0, 16384, 24576, 28672, 
+    29184, 29185, 29187, 29191, 29168, 29176,     0, 16384, 
+    24576, 28672, 29184, 29185, 29187, 29191, 29168, 29176, 
+    29180,     0, 16384, 24576, 28672, 29184, 29185, 29187, 
+    29191, 29168, 29176, 29180,     0, 16384, 24576, 28672, 
+    29184, 29185, 29187, 29191, 29168, 29176, 29180, 29182, 
+        0, 16384, 24576, 28672,     0, 16384, 24576, 28672, 
+    29184,     0, 16384, 24576, 28672, 29184,     0, 16384, 
+    24576, 28672, 29184, 29186,     0, 16384, 24576, 28672, 
+    29184,     0, 16384, 24576, 28672, 29184, 29188,     0, 
+    16384, 24576, 28672, 29184, 29188,     0, 16384, 24576, 
+    28672, 29184, 29192, 29190,     0, 16384, 24576, 28672, 
+    29184,     0, 16384, 24576, 28672, 29184, 29192,     0, 
+    16384, 24576, 28672, 29184, 29192,     0, 16384, 24576, 
+    28672, 29184, 29192, 29194,     0, 16384, 24576, 28672, 
+    29184, 29192,     0, 16384, 24576, 28672, 29184, 29200, 
+    29196,     0, 16384, 24576, 28672, 29184, 29200, 29196, 
+        0, 16384, 24576, 28672, 29184, 29200, 29201, 29198, 
+        0, 16384, 24576, 28672, 29184,     0, 16384, 24576, 
+    28672, 29184, 29200,     0, 16384, 24576, 28672, 29184, 
+    29200,     0, 16384, 24576, 28672, 29184, 29200, 29202, 
+        0, 16384, 24576, 28672, 29184, 29200,     0, 16384, 
+    24576, 28672, 29184, 29200, 29204,     0, 16384, 24576, 
+    28672, 29184, 29200, 29204,     0, 16384, 24576, 28672, 
+    29184, 29200, 29208, 29206,     0, 16384, 24576, 28672, 
+    29184, 29200,     0, 16384, 24576, 28672, 29184, 29216, 
+    29208,     0, 16384, 24576, 28672, 29184, 29216, 29208, 
+        0, 16384, 24576, 28672, 29184, 29216, 29208, 29210, 
+        0, 16384, 24576, 28672, 29184, 29216, 29208,     0, 
+    16384, 24576, 28672, 29184, 29216, 29217, 29212,     0, 
+    16384, 24576, 28672, 29184, 29216, 29217, 29212,     0, 
+    16384, 24576, 28672, 29184, 29216, 29217, 29212, 29214, 
+        0, 16384, 24576, 28672, 29184,     0, 16384, 24576, 
+    28672, 29184, 29216,     0, 16384, 24576, 28672, 29184, 
+    29216,     0, 16384, 24576, 28672, 29184, 29216, 29218, 
+        0, 16384, 24576, 28672, 29184, 29216,     0, 16384, 
+    24576, 28672, 29184, 29216, 29220,     0, 16384, 24576, 
+    28672, 29184, 29216, 29220,     0, 16384, 24576, 28672, 
+    29184, 29216, 29224, 29222,     0, 16384, 24576, 28672, 
+    29184, 29216,     0, 16384, 24576, 28672, 29184, 29216, 
+    29224,     0, 16384, 24576, 28672, 29184, 29216, 29224, 
+        0, 16384, 24576, 28672, 29184, 29216, 29224, 29226, 
+        0, 16384, 24576, 28672, 29184, 29216, 29224,     0, 
+    16384, 24576, 28672, 29184, 29216, 29232, 29228,     0, 
+    16384, 24576, 28672, 29184, 29216, 29232, 29228,     0, 
+    16384, 24576, 28672, 29184, 29216, 29232, 29233, 29230, 
+        0, 16384, 24576, 28672, 29184, 29216,     0, 16384, 
+    24576, 28672, 29184, 29248, 29232,     0, 16384, 24576, 
+    28672, 29184, 29248, 29232,     0, 16384, 24576, 28672, 
+    29184, 29248, 29232, 29234,     0, 16384, 24576, 28672, 
+    29184, 29248, 29232,     0, 16384, 24576, 28672, 29184, 
+    29248, 29232, 29236,     0, 16384, 24576, 28672, 29184, 
+    29248, 29232, 29236,     0, 16384, 24576, 28672, 29184, 
+    29248, 29232, 29240, 29238,     0, 16384, 24576, 28672, 
+    29184, 29248, 29232,     0, 16384, 24576, 28672, 29184, 
+    29248, 29249, 29240,     0, 16384, 24576, 28672, 29184, 
+    29248, 29249, 29240,     0, 16384, 24576, 28672, 29184, 
+    29248, 29249, 29240, 29242,     0, 16384, 24576, 28672, 
+    29184, 29248, 29249, 29240,     0, 16384, 24576, 28672, 
+    29184, 29248, 29249, 29240, 29244,     0, 16384, 24576, 
+    28672, 29184, 29248, 29249, 29251, 29244,     0, 16384, 
+    24576, 28672, 29184, 29248, 29249, 29251, 29244, 29246, 
+        0, 16384, 24576, 28672, 29184,     0, 16384, 24576, 
+    28672, 29184, 29248,     0, 16384, 24576, 28672, 29184, 
+    29248,     0, 16384, 24576, 28672, 29184, 29248, 29250, 
+        0, 16384, 24576, 28672, 29184, 29248,     0, 16384, 
+    24576, 28672, 29184, 29248, 29252,     0, 16384, 24576, 
+    28672, 29184, 29248, 29252,     0, 16384, 24576, 28672, 
+    29184, 29248, 29256, 29254,     0, 16384, 24576, 28672, 
+    29184, 29248,     0, 16384, 24576, 28672, 29184, 29248, 
+    29256,     0, 16384, 24576, 28672, 29184, 29248, 29256, 
+        0, 16384, 24576, 28672, 29184, 29248, 29256, 29258, 
+        0, 16384, 24576, 28672, 29184, 29248, 29256,     0, 
+    16384, 24576, 28672, 29184, 29248, 29264, 29260,     0, 
+    16384, 24576, 28672, 29184, 29248, 29264, 29260,     0, 
+    16384, 24576, 28672, 29184, 29248, 29264, 29265, 29262, 
+        0, 16384, 24576, 28672, 29184, 29248,     0, 16384, 
+    24576, 28672, 29184, 29248, 29264,     0, 16384, 24576, 
+    28672, 29184, 29248, 29264,     0, 16384, 24576, 28672, 
+    29184, 29248, 29264, 29266,     0, 16384, 24576, 28672, 
+    29184, 29248, 29264,     0, 16384, 24576, 28672, 29184, 
+    29248, 29264, 29268,     0, 16384, 24576, 28672, 29184, 
+    29248, 29264, 29268,     0, 16384, 24576, 28672, 29184, 
+    29248, 29264, 29272, 29270,     0, 16384, 24576, 28672, 
+    29184, 29248, 29264,     0, 16384, 24576, 28672, 29184, 
+    29248, 29280, 29272,     0, 16384, 24576, 28672, 29184, 
+    29248, 29280, 29272,     0, 16384, 24576, 28672, 29184, 
+    29248, 29280, 29272, 29274,     0, 16384, 24576, 28672, 
+    29184, 29248, 29280, 29272,     0, 16384, 24576, 28672, 
+    29184, 29248, 29280, 29281, 29276,     0, 16384, 24576, 
+    28672, 29184, 29248, 29280, 29281, 29276,     0, 16384, 
+    24576, 28672, 29184, 29248, 29280, 29281, 29276, 29278, 
+        0, 16384, 24576, 28672, 29184, 29248,     0, 16384, 
+    24576, 28672, 29184, 29312, 29280,     0, 16384, 24576, 
+    28672, 29184, 29312, 29280,     0, 16384, 24576, 28672, 
+    29184, 29312, 29280, 29282,     0, 16384, 24576, 28672, 
+    29184, 29312, 29280,     0, 16384, 24576, 28672, 29184, 
+    29312, 29280, 29284,     0, 16384, 24576, 28672, 29184, 
+    29312, 29280, 29284,     0, 16384, 24576, 28672, 29184, 
+    29312, 29280, 29288, 29286,     0, 16384, 24576, 28672, 
+    29184, 29312, 29280,     0, 16384, 24576, 28672, 29184, 
+    29312, 29280, 29288,     0, 16384, 24576, 28672, 29184, 
+    29312, 29280, 29288,     0, 16384, 24576, 28672, 29184, 
+    29312, 29280, 29288, 29290,     0, 16384, 24576, 28672, 
+    29184, 29312, 29280, 29288,     0, 16384, 24576, 28672, 
+    29184, 29312, 29280, 29296, 29292,     0, 16384, 24576, 
+    28672, 29184, 29312, 29280, 29296, 29292,     0, 16384, 
+    24576, 28672, 29184, 29312, 29280, 29296, 29297, 29294, 
+        0, 16384, 24576, 28672, 29184, 29312, 29280,     0, 
+    16384, 24576, 28672, 29184, 29312, 29313, 29296,     0, 
+    16384, 24576, 28672, 29184, 29312, 29313, 29296,     0, 
+    16384, 24576, 28672, 29184, 29312, 29313, 29296, 29298, 
+        0, 16384, 24576, 28672, 29184, 29312, 29313, 29296, 
+        0, 16384, 24576, 28672, 29184, 29312, 29313, 29296, 
+    29300,     0, 16384, 24576, 28672, 29184, 29312, 29313, 
+    29296, 29300,     0, 16384, 24576, 28672, 29184, 29312, 
+    29313, 29296, 29304, 29302,     0, 16384, 24576, 28672, 
+    29184, 29312, 29313, 29296,     0, 16384, 24576, 28672, 
+    29184, 29312, 29313, 29296, 29304,     0, 16384, 24576, 
+    28672, 29184, 29312, 29313, 29315, 29304,     0, 16384, 
+    24576, 28672, 29184, 29312, 29313, 29315, 29304, 29306, 
+        0, 16384, 24576, 28672, 29184, 29312, 29313, 29315, 
+    29304,     0, 16384, 24576, 28672, 29184, 29312, 29313, 
+    29315, 29304, 29308,     0, 16384, 24576, 28672, 29184, 
+    29312, 29313, 29315, 29304, 29308,     0, 16384, 24576, 
+    28672, 29184, 29312, 29313, 29315, 29304, 29308, 29310, 
+        0, 16384, 24576, 28672, 29184,     0, 16384, 24576, 
+    28672, 29184, 29312,     0, 16384, 24576, 28672, 29184, 
+    29312,     0, 16384, 24576, 28672, 29184, 29312, 29314, 
+        0, 16384, 24576, 28672, 29184, 29312,     0, 16384, 
+    24576, 28672, 29184, 29312, 29316,     0, 16384, 24576, 
+    28672, 29184, 29312, 29316,     0, 16384, 24576, 28672, 
+    29184, 29312, 29320, 29318,     0, 16384, 24576, 28672, 
+    29184, 29312,     0, 16384, 24576, 28672, 29184, 29312, 
+    29320,     0, 16384, 24576, 28672, 29184, 29312, 29320, 
+        0, 16384, 24576, 28672, 29184, 29312, 29320, 29322, 
+        0, 16384, 24576, 28672, 29184, 29312, 29320,     0, 
+    16384, 24576, 28672, 29184, 29312, 29328, 29324,     0, 
+    16384, 24576, 28672, 29184, 29312, 29328, 29324,     0, 
+    16384, 24576, 28672, 29184, 29312, 29328, 29329, 29326, 
+        0, 16384, 24576, 28672, 29184, 29312,     0, 16384, 
+    24576, 28672, 29184, 29312, 29328,     0, 16384, 24576, 
+    28672, 29184, 29312, 29328,     0, 16384, 24576, 28672, 
+    29184, 29312, 29328, 29330,     0, 16384, 24576, 28672, 
+    29184, 29312, 29328,     0, 16384, 24576, 28672, 29184, 
+    29312, 29328, 29332,     0, 16384, 24576, 28672, 29184, 
+    29312, 29328, 29332,     0, 16384, 24576, 28672, 29184, 
+    29312, 29328, 29336, 29334,     0, 16384, 24576, 28672, 
+    29184, 29312, 29328,     0, 16384, 24576, 28672, 29184, 
+    29312, 29344, 29336,     0, 16384, 24576, 28672, 29184, 
+    29312, 29344, 29336,     0, 16384, 24576, 28672, 29184, 
+    29312, 29344, 29336, 29338,     0, 16384, 24576, 28672, 
+    29184, 29312, 29344, 29336,     0, 16384, 24576, 28672, 
+    29184, 29312, 29344, 29345, 29340,     0, 16384, 24576, 
+    28672, 29184, 29312, 29344, 29345, 29340,     0, 16384, 
+    24576, 28672, 29184, 29312, 29344, 29345, 29340, 29342, 
+        0, 16384, 24576, 28672, 29184, 29312,     0, 16384, 
+    24576, 28672, 29184, 29312, 29344,     0, 16384, 24576, 
+    28672, 29184, 29312, 29344,     0, 16384, 24576, 28672, 
+    29184, 29312, 29344, 29346,     0, 16384, 24576, 28672, 
+    29184, 29312, 29344,     0, 16384, 24576, 28672, 29184, 
+    29312, 29344, 29348,     0, 16384, 24576, 28672, 29184, 
+    29312, 29344, 29348,     0, 16384, 24576, 28672, 29184, 
+    29312, 29344, 29352, 29350,     0, 16384, 24576, 28672, 
+    29184, 29312, 29344,     0, 16384, 24576, 28672, 29184, 
+    29312, 29344, 29352,     0, 16384, 24576, 28672, 29184, 
+    29312, 29344, 29352,     0, 16384, 24576, 28672, 29184, 
+    29312, 29344, 29352, 29354,     0, 16384, 24576, 28672, 
+    29184, 29312, 29344, 29352,     0, 16384, 24576, 28672, 
+    29184, 29312, 29344, 29360, 29356,     0, 16384, 24576, 
+    28672, 29184, 29312, 29344, 29360, 29356,     0, 16384, 
+    24576, 28672, 29184, 29312, 29344, 29360, 29361, 29358, 
+        0, 16384, 24576, 28672, 29184, 29312, 29344,     0, 
+    16384, 24576, 28672, 29184, 29312, 29376, 29360,     0, 
+    16384, 24576, 28672, 29184, 29312, 29376, 29360,     0, 
+    16384, 24576, 28672, 29184, 29312, 29376, 29360, 29362, 
+        0, 16384, 24576, 28672, 29184, 29312, 29376, 29360, 
+        0, 16384, 24576, 28672, 29184, 29312, 29376, 29360, 
+    29364,     0, 16384, 24576, 28672, 29184, 29312, 29376, 
+    29360, 29364,     0, 16384, 24576, 28672, 29184, 29312, 
+    29376, 29360, 29368, 29366,     0, 16384, 24576, 28672, 
+    29184, 29312, 29376, 29360,     0, 16384, 24576, 28672, 
+    29184, 29312, 29376, 29377, 29368,     0, 16384, 24576, 
+    28672, 29184, 29312, 29376, 29377, 29368,     0, 16384, 
+    24576, 28672, 29184, 29312, 29376, 29377, 29368, 29370, 
+        0, 16384, 24576, 28672, 29184, 29312, 29376, 29377, 
+    29368,     0, 16384, 24576, 28672, 29184, 29312, 29376, 
+    29377, 29368, 29372,     0, 16384, 24576, 28672, 29184, 
+    29312, 29376, 29377, 29379, 29372,     0, 16384, 24576, 
+    28672, 29184, 29312, 29376, 29377, 29379, 29372, 29374, 
+        0, 16384, 24576, 28672, 29184, 29312,     0, 16384, 
+    24576, 28672, 29184, 29440, 29376,     0, 16384, 24576, 
+    28672, 29184, 29440, 29376,     0, 16384, 24576, 28672, 
+    29184, 29440, 29376, 29378,     0, 16384, 24576, 28672, 
+    29184, 29440, 29376,     0, 16384, 24576, 28672, 29184, 
+    29440, 29376, 29380,     0, 16384, 24576, 28672, 29184, 
+    29440, 29376, 29380,     0, 16384, 24576, 28672, 29184, 
+    29440, 29376, 29384, 29382,     0, 16384, 24576, 28672, 
+    29184, 29440, 29376,     0, 16384, 24576, 28672, 29184, 
+    29440, 29376, 29384,     0, 16384, 24576, 28672, 29184, 
+    29440, 29376, 29384,     0, 16384, 24576, 28672, 29184, 
+    29440, 29376, 29384, 29386,     0, 16384, 24576, 28672, 
+    29184, 29440, 29376, 29384,     0, 16384, 24576, 28672, 
+    29184, 29440, 29376, 29392, 29388,     0, 16384, 24576, 
+    28672, 29184, 29440, 29376, 29392, 29388,     0, 16384, 
+    24576, 28672, 29184, 29440, 29376, 29392, 29393, 29390, 
+        0, 16384, 24576, 28672, 29184, 29440, 29376,     0, 
+    16384, 24576, 28672, 29184, 29440, 29376, 29392,     0, 
+    16384, 24576, 28672, 29184, 29440, 29376, 29392,     0, 
+    16384, 24576, 28672, 29184, 29440, 29376, 29392, 29394, 
+        0, 16384, 24576, 28672, 29184, 29440, 29376, 29392, 
+        0, 16384, 24576, 28672, 29184, 29440, 29376, 29392, 
+    29396,     0, 16384, 24576, 28672, 29184, 29440, 29376, 
+    29392, 29396,     0, 16384, 24576, 28672, 29184, 29440, 
+    29376, 29392, 29400, 29398,     0, 16384, 24576, 28672, 
+    29184, 29440, 29376, 29392,     0, 16384, 24576, 28672, 
+    29184, 29440, 29376, 29408, 29400,     0, 16384, 24576, 
+    28672, 29184, 29440, 29376, 29408, 29400,     0, 16384, 
+    24576, 28672, 29184, 29440, 29376, 29408, 29400, 29402, 
+        0, 16384, 24576, 28672, 29184, 29440, 29376, 29408, 
+    29400,     0, 16384, 24576, 28672, 29184, 29440, 29376, 
+    29408, 29409, 29404,     0, 16384, 24576, 28672, 29184, 
+    29440, 29376, 29408, 29409, 29404,     0, 16384, 24576, 
+    28672, 29184, 29440, 29376, 29408, 29409, 29404, 29406, 
+        0, 16384, 24576, 28672, 29184, 29440, 29376,     0, 
+    16384, 24576, 28672, 29184, 29440, 29441, 29408,     0, 
+    16384, 24576, 28672, 29184, 29440, 29441, 29408,     0, 
+    16384, 24576, 28672, 29184, 29440, 29441, 29408, 29410, 
+        0, 16384, 24576, 28672, 29184, 29440, 29441, 29408, 
+        0, 16384, 24576, 28672, 29184, 29440, 29441, 29408, 
+    29412,     0, 16384, 24576, 28672, 29184, 29440, 29441, 
+    29408, 29412,     0, 16384, 24576, 28672, 29184, 29440, 
+    29441, 29408, 29416, 29414,     0, 16384, 24576, 28672, 
+    29184, 29440, 29441, 29408,     0, 16384, 24576, 28672, 
+    29184, 29440, 29441, 29408, 29416,     0, 16384, 24576, 
+    28672, 29184, 29440, 29441, 29408, 29416,     0, 16384, 
+    24576, 28672, 29184, 29440, 29441, 29408, 29416, 29418, 
+        0, 16384, 24576, 28672, 29184, 29440, 29441, 29408, 
+    29416,     0, 16384, 24576, 28672, 29184, 29440, 29441, 
+    29408, 29424, 29420,     0, 16384, 24576, 28672, 29184, 
+    29440, 29441, 29408, 29424, 29420,     0, 16384, 24576, 
+    28672, 29184, 29440, 29441, 29408, 29424, 29425, 29422, 
+        0, 16384, 24576, 28672, 29184, 29440, 29441, 29408, 
+        0, 16384, 24576, 28672, 29184, 29440, 29441, 29408, 
+    29424,     0, 16384, 24576, 28672, 29184, 29440, 29441, 
+    29443, 29424,     0, 16384, 24576, 28672, 29184, 29440, 
+    29441, 29443, 29424, 29426,     0, 16384, 24576, 28672, 
+    29184, 29440, 29441, 29443, 29424,     0, 16384, 24576, 
+    28672, 29184, 29440, 29441, 29443, 29424, 29428,     0, 
+    16384, 24576, 28672, 29184, 29440, 29441, 29443, 29424, 
+    29428,     0, 16384, 24576, 28672, 29184, 29440, 29441, 
+    29443, 29424, 29432, 29430,     0, 16384, 24576, 28672, 
+    29184, 29440, 29441, 29443, 29424,     0, 16384, 24576, 
+    28672, 29184, 29440, 29441, 29443, 29424, 29432,     0, 
+    16384, 24576, 28672, 29184, 29440, 29441, 29443, 29424, 
+    29432,     0, 16384, 24576, 28672, 29184, 29440, 29441, 
+    29443, 29424, 29432, 29434,     0, 16384, 24576, 28672, 
+    29184, 29440, 29441, 29443, 29447, 29432,     0, 16384, 
+    24576, 28672, 29184, 29440, 29441, 29443, 29447, 29432, 
+    29436,     0, 16384, 24576, 28672, 29184, 29440, 29441, 
+    29443, 29447, 29432, 29436,     0, 16384, 24576, 28672, 
+    29184, 29440, 29441, 29443, 29447, 29432, 29436, 29438, 
+        0, 16384, 24576, 28672, 29184,     0, 16384, 24576, 
+    28672, 29696, 29440,     0, 16384, 24576, 28672, 29696, 
+    29440,     0, 16384, 24576, 28672, 29696, 29440, 29442, 
+        0, 16384, 24576, 28672, 29696, 29440,     0, 16384, 
+    24576, 28672, 29696, 29440, 29444,     0, 16384, 24576, 
+    28672, 29696, 29440, 29444,     0, 16384, 24576, 28672, 
+    29696, 29440, 29448, 29446,     0, 16384, 24576, 28672, 
+    29696, 29440,     0, 16384, 24576, 28672, 29696, 29440, 
+    29448,     0, 16384, 24576, 28672, 29696, 29440, 29448, 
+        0, 16384, 24576, 28672, 29696, 29440, 29448, 29450, 
+        0, 16384, 24576, 28672, 29696, 29440, 29448,     0, 
+    16384, 24576, 28672, 29696, 29440, 29456, 29452,     0, 
+    16384, 24576, 28672, 29696, 29440, 29456, 29452,     0, 
+    16384, 24576, 28672, 29696, 29440, 29456, 29457, 29454, 
+        0, 16384, 24576, 28672, 29696, 29440,     0, 16384, 
+    24576, 28672, 29696, 29440, 29456,     0, 16384, 24576, 
+    28672, 29696, 29440, 29456,     0, 16384, 24576, 28672, 
+    29696, 29440, 29456, 29458,     0, 16384, 24576, 28672, 
+    29696, 29440, 29456,     0, 16384, 24576, 28672, 29696, 
+    29440, 29456, 29460,     0, 16384, 24576, 28672, 29696, 
+    29440, 29456, 29460,     0, 16384, 24576, 28672, 29696, 
+    29440, 29456, 29464, 29462,     0, 16384, 24576, 28672, 
+    29696, 29440, 29456,     0, 16384, 24576, 28672, 29696, 
+    29440, 29472, 29464,     0, 16384, 24576, 28672, 29696, 
+    29440, 29472, 29464,     0, 16384, 24576, 28672, 29696, 
+    29440, 29472, 29464, 29466,     0, 16384, 24576, 28672, 
+    29696, 29440, 29472, 29464,     0, 16384, 24576, 28672, 
+    29696, 29440, 29472, 29473, 29468,     0, 16384, 24576, 
+    28672, 29696, 29440, 29472, 29473, 29468,     0, 16384, 
+    24576, 28672, 29696, 29440, 29472, 29473, 29468, 29470, 
+        0, 16384, 24576, 28672, 29696, 29440,     0, 16384, 
+    24576, 28672, 29696, 29440, 29472,     0, 16384, 24576, 
+    28672, 29696, 29440, 29472,     0, 16384, 24576, 28672, 
+    29696, 29440, 29472, 29474,     0, 16384, 24576, 28672, 
+    29696, 29440, 29472,     0, 16384, 24576, 28672, 29696, 
+    29440, 29472, 29476,     0, 16384, 24576, 28672, 29696, 
+    29440, 29472, 29476,     0, 16384, 24576, 28672, 29696, 
+    29440, 29472, 29480, 29478,     0, 16384, 24576, 28672, 
+    29696, 29440, 29472,     0, 16384, 24576, 28672, 29696, 
+    29440, 29472, 29480,     0, 16384, 24576, 28672, 29696, 
+    29440, 29472, 29480,     0, 16384, 24576, 28672, 29696, 
+    29440, 29472, 29480, 29482,     0, 16384, 24576, 28672, 
+    29696, 29440, 29472, 29480,     0, 16384, 24576, 28672, 
+    29696, 29440, 29472, 29488, 29484,     0, 16384, 24576, 
+    28672, 29696, 29440, 29472, 29488, 29484,     0, 16384, 
+    24576, 28672, 29696, 29440, 29472, 29488, 29489, 29486, 
+        0, 16384, 24576, 28672, 29696, 29440, 29472,     0, 
+    16384, 24576, 28672, 29696, 29440, 29504, 29488,     0, 
+    16384, 24576, 28672, 29696, 29440, 29504, 29488,     0, 
+    16384, 24576, 28672, 29696, 29440, 29504, 29488, 29490, 
+        0, 16384, 24576, 28672, 29696, 29440, 29504, 29488, 
+        0, 16384, 24576, 28672, 29696, 29440, 29504, 29488, 
+    29492,     0, 16384, 24576, 28672, 29696, 29440, 29504, 
+    29488, 29492,     0, 16384, 24576, 28672, 29696, 29440, 
+    29504, 29488, 29496, 29494,     0, 16384, 24576, 28672, 
+    29696, 29440, 29504, 29488,     0, 16384, 24576, 28672, 
+    29696, 29440, 29504, 29505, 29496,     0, 16384, 24576, 
+    28672, 29696, 29440, 29504, 29505, 29496,     0, 16384, 
+    24576, 28672, 29696, 29440, 29504, 29505, 29496, 29498, 
+        0, 16384, 24576, 28672, 29696, 29440, 29504, 29505, 
+    29496,     0, 16384, 24576, 28672, 29696, 29440, 29504, 
+    29505, 29496, 29500,     0, 16384, 24576, 28672, 29696, 
+    29440, 29504, 29505, 29507, 29500,     0, 16384, 24576, 
+    28672, 29696, 29440, 29504, 29505, 29507, 29500, 29502, 
+        0, 16384, 24576, 28672, 29696, 29440,     0, 16384, 
+    24576, 28672, 29696, 29440, 29504,     0, 16384, 24576, 
+    28672, 29696, 29440, 29504,     0, 16384, 24576, 28672, 
+    29696, 29440, 29504, 29506,     0, 16384, 24576, 28672, 
+    29696, 29440, 29504,     0, 16384, 24576, 28672, 29696, 
+    29440, 29504, 29508,     0, 16384, 24576, 28672, 29696, 
+    29440, 29504, 29508,     0, 16384, 24576, 28672, 29696, 
+    29440, 29504, 29512, 29510,     0, 16384, 24576, 28672, 
+    29696, 29440, 29504,     0, 16384, 24576, 28672, 29696, 
+    29440, 29504, 29512,     0, 16384, 24576, 28672, 29696, 
+    29440, 29504, 29512,     0, 16384, 24576, 28672, 29696, 
+    29440, 29504, 29512, 29514,     0, 16384, 24576, 28672, 
+    29696, 29440, 29504, 29512,     0, 16384, 24576, 28672, 
+    29696, 29440, 29504, 29520, 29516,     0, 16384, 24576, 
+    28672, 29696, 29440, 29504, 29520, 29516,     0, 16384, 
+    24576, 28672, 29696, 29440, 29504, 29520, 29521, 29518, 
+        0, 16384, 24576, 28672, 29696, 29440, 29504,     0, 
+    16384, 24576, 28672, 29696, 29440, 29504, 29520,     0, 
+    16384, 24576, 28672, 29696, 29440, 29504, 29520,     0, 
+    16384, 24576, 28672, 29696, 29440, 29504, 29520, 29522, 
+        0, 16384, 24576, 28672, 29696, 29440, 29504, 29520, 
+        0, 16384, 24576, 28672, 29696, 29440, 29504, 29520, 
+    29524,     0, 16384, 24576, 28672, 29696, 29440, 29504, 
+    29520, 29524,     0, 16384, 24576, 28672, 29696, 29440, 
+    29504, 29520, 29528, 29526,     0, 16384, 24576, 28672, 
+    29696, 29440, 29504, 29520,     0, 16384, 24576, 28672, 
+    29696, 29440, 29504, 29536, 29528,     0, 16384, 24576, 
+    28672, 29696, 29440, 29504, 29536, 29528,     0, 16384, 
+    24576, 28672, 29696, 29440, 29504, 29536, 29528, 29530, 
+        0, 16384, 24576, 28672, 29696, 29440, 29504, 29536, 
+    29528,     0, 16384, 24576, 28672, 29696, 29440, 29504, 
+    29536, 29537, 29532,     0, 16384, 24576, 28672, 29696, 
+    29440, 29504, 29536, 29537, 29532,     0, 16384, 24576, 
+    28672, 29696, 29440, 29504, 29536, 29537, 29532, 29534, 
+        0, 16384, 24576, 28672, 29696, 29440, 29504,     0, 
+    16384, 24576, 28672, 29696, 29440, 29568, 29536,     0, 
+    16384, 24576, 28672, 29696, 29440, 29568, 29536,     0, 
+    16384, 24576, 28672, 29696, 29440, 29568, 29536, 29538, 
+        0, 16384, 24576, 28672, 29696, 29440, 29568, 29536, 
+        0, 16384, 24576, 28672, 29696, 29440, 29568, 29536, 
+    29540,     0, 16384, 24576, 28672, 29696, 29440, 29568, 
+    29536, 29540,     0, 16384, 24576, 28672, 29696, 29440, 
+    29568, 29536, 29544, 29542,     0, 16384, 24576, 28672, 
+    29696, 29440, 29568, 29536,     0, 16384, 24576, 28672, 
+    29696, 29440, 29568, 29536, 29544,     0, 16384, 24576, 
+    28672, 29696, 29440, 29568, 29536, 29544,     0, 16384, 
+    24576, 28672, 29696, 29440, 29568, 29536, 29544, 29546, 
+        0, 16384, 24576, 28672, 29696, 29440, 29568, 29536, 
+    29544,     0, 16384, 24576, 28672, 29696, 29440, 29568, 
+    29536, 29552, 29548,     0, 16384, 24576, 28672, 29696, 
+    29440, 29568, 29536, 29552, 29548,     0, 16384, 24576, 
+    28672, 29696, 29440, 29568, 29536, 29552, 29553, 29550, 
+        0, 16384, 24576, 28672, 29696, 29440, 29568, 29536, 
+        0, 16384, 24576, 28672, 29696, 29440, 29568, 29569, 
+    29552,     0, 16384, 24576, 28672, 29696, 29440, 29568, 
+    29569, 29552,     0, 16384, 24576, 28672, 29696, 29440, 
+    29568, 29569, 29552, 29554,     0, 16384, 24576, 28672, 
+    29696, 29440, 29568, 29569, 29552,     0, 16384, 24576, 
+    28672, 29696, 29440, 29568, 29569, 29552, 29556,     0, 
+    16384, 24576, 28672, 29696, 29440, 29568, 29569, 29552, 
+    29556,     0, 16384, 24576, 28672, 29696, 29440, 29568, 
+    29569, 29552, 29560, 29558,     0, 16384, 24576, 28672, 
+    29696, 29440, 29568, 29569, 29552,     0, 16384, 24576, 
+    28672, 29696, 29440, 29568, 29569, 29552, 29560,     0, 
+    16384, 24576, 28672, 29696, 29440, 29568, 29569, 29571, 
+    29560,     0, 16384, 24576, 28672, 29696, 29440, 29568, 
+    29569, 29571, 29560, 29562,     0, 16384, 24576, 28672, 
+    29696, 29440, 29568, 29569, 29571, 29560,     0, 16384, 
+    24576, 28672, 29696, 29440, 29568, 29569, 29571, 29560, 
+    29564,     0, 16384, 24576, 28672, 29696, 29440, 29568, 
+    29569, 29571, 29560, 29564,     0, 16384, 24576, 28672, 
+    29696, 29440, 29568, 29569, 29571, 29560, 29564, 29566, 
+        0, 16384, 24576, 28672, 29696, 29440,     0, 16384, 
+    24576, 28672, 29696, 29440, 29568,     0, 16384, 24576, 
+    28672, 29696, 29697, 29568,     0, 16384, 24576, 28672, 
+    29696, 29697, 29568, 29570,     0, 16384, 24576, 28672, 
+    29696, 29697, 29568,     0, 16384, 24576, 28672, 29696, 
+    29697, 29568, 29572,     0, 16384, 24576, 28672, 29696, 
+    29697, 29568, 29572,     0, 16384, 24576, 28672, 29696, 
+    29697, 29568, 29576, 29574,     0, 16384, 24576, 28672, 
+    29696, 29697, 29568,     0, 16384, 24576, 28672, 29696, 
+    29697, 29568, 29576,     0, 16384, 24576, 28672, 29696, 
+    29697, 29568, 29576,     0, 16384, 24576, 28672, 29696, 
+    29697, 29568, 29576, 29578,     0, 16384, 24576, 28672, 
+    29696, 29697, 29568, 29576,     0, 16384, 24576, 28672, 
+    29696, 29697, 29568, 29584, 29580,     0, 16384, 24576, 
+    28672, 29696, 29697, 29568, 29584, 29580,     0, 16384, 
+    24576, 28672, 29696, 29697, 29568, 29584, 29585, 29582, 
+        0, 16384, 24576, 28672, 29696, 29697, 29568,     0, 
+    16384, 24576, 28672, 29696, 29697, 29568, 29584,     0, 
+    16384, 24576, 28672, 29696, 29697, 29568, 29584,     0, 
+    16384, 24576, 28672, 29696, 29697, 29568, 29584, 29586, 
+        0, 16384, 24576, 28672, 29696, 29697, 29568, 29584, 
+        0, 16384, 24576, 28672, 29696, 29697, 29568, 29584, 
+    29588,     0, 16384, 24576, 28672, 29696, 29697, 29568, 
+    29584, 29588,     0, 16384, 24576, 28672, 29696, 29697, 
+    29568, 29584, 29592, 29590,     0, 16384, 24576, 28672, 
+    29696, 29697, 29568, 29584,     0, 16384, 24576, 28672, 
+    29696, 29697, 29568, 29600, 29592,     0, 16384, 24576, 
+    28672, 29696, 29697, 29568, 29600, 29592,     0, 16384, 
+    24576, 28672, 29696, 29697, 29568, 29600, 29592, 29594, 
+        0, 16384, 24576, 28672, 29696, 29697, 29568, 29600, 
+    29592,     0, 16384, 24576, 28672, 29696, 29697, 29568, 
+    29600, 29601, 29596,     0, 16384, 24576, 28672, 29696, 
+    29697, 29568, 29600, 29601, 29596,     0, 16384, 24576, 
+    28672, 29696, 29697, 29568, 29600, 29601, 29596, 29598, 
+        0, 16384, 24576, 28672, 29696, 29697, 29568,     0, 
+    16384, 24576, 28672, 29696, 29697, 29568, 29600,     0, 
+    16384, 24576, 28672, 29696, 29697, 29568, 29600,     0, 
+    16384, 24576, 28672, 29696, 29697, 29568, 29600, 29602, 
+        0, 16384, 24576, 28672, 29696, 29697, 29568, 29600, 
+        0, 16384, 24576, 28672, 29696, 29697, 29568, 29600, 
+    29604,     0, 16384, 24576, 28672, 29696, 29697, 29568, 
+    29600, 29604,     0, 16384, 24576, 28672, 29696, 29697, 
+    29568, 29600, 29608, 29606,     0, 16384, 24576, 28672, 
+    29696, 29697, 29568, 29600,     0, 16384, 24576, 28672, 
+    29696, 29697, 29568, 29600, 29608,     0, 16384, 24576, 
+    28672, 29696, 29697, 29568, 29600, 29608,     0, 16384, 
+    24576, 28672, 29696, 29697, 29568, 29600, 29608, 29610, 
+        0, 16384, 24576, 28672, 29696, 29697, 29568, 29600, 
+    29608,     0, 16384, 24576, 28672, 29696, 29697, 29568, 
+    29600, 29616, 29612,     0, 16384, 24576, 28672, 29696, 
+    29697, 29568, 29600, 29616, 29612,     0, 16384, 24576, 
+    28672, 29696, 29697, 29568, 29600, 29616, 29617, 29614, 
+        0, 16384, 24576, 28672, 29696, 29697, 29568, 29600, 
+        0, 16384, 24576, 28672, 29696, 29697, 29568, 29632, 
+    29616,     0, 16384, 24576, 28672, 29696, 29697, 29568, 
+    29632, 29616,     0, 16384, 24576, 28672, 29696, 29697, 
+    29568, 29632, 29616, 29618,     0, 16384, 24576, 28672, 
+    29696, 29697, 29568, 29632, 29616,     0, 16384, 24576, 
+    28672, 29696, 29697, 29568, 29632, 29616, 29620,     0, 
+    16384, 24576, 28672, 29696, 29697, 29568, 29632, 29616, 
+    29620,     0, 16384, 24576, 28672, 29696, 29697, 29568, 
+    29632, 29616, 29624, 29622,     0, 16384, 24576, 28672, 
+    29696, 29697, 29568, 29632, 29616,     0, 16384, 24576, 
+    28672, 29696, 29697, 29568, 29632, 29633, 29624,     0, 
+    16384, 24576, 28672, 29696, 29697, 29568, 29632, 29633, 
+    29624,     0, 16384, 24576, 28672, 29696, 29697, 29568, 
+    29632, 29633, 29624, 29626,     0, 16384, 24576, 28672, 
+    29696, 29697, 29568, 29632, 29633, 29624,     0, 16384, 
+    24576, 28672, 29696, 29697, 29568, 29632, 29633, 29624, 
+    29628,     0, 16384, 24576, 28672, 29696, 29697, 29568, 
+    29632, 29633, 29635, 29628,     0, 16384, 24576, 28672, 
+    29696, 29697, 29568, 29632, 29633, 29635, 29628, 29630, 
+        0, 16384, 24576, 28672, 29696, 29697, 29568,     0, 
+    16384, 24576, 28672, 29696, 29697, 29568, 29632,     0, 
+    16384, 24576, 28672, 29696, 29697, 29568, 29632,     0, 
+    16384, 24576, 28672, 29696, 29697, 29568, 29632, 29634, 
+        0, 16384, 24576, 28672, 29696, 29697, 29699, 29632, 
+        0, 16384, 24576, 28672, 29696, 29697, 29699, 29632, 
+    29636,     0, 16384, 24576, 28672, 29696, 29697, 29699, 
+    29632, 29636,     0, 16384, 24576, 28672, 29696, 29697, 
+    29699, 29632, 29640, 29638,     0, 16384, 24576, 28672, 
+    29696, 29697, 29699, 29632,     0, 16384, 24576, 28672, 
+    29696, 29697, 29699, 29632, 29640,     0, 16384, 24576, 
+    28672, 29696, 29697, 29699, 29632, 29640,     0, 16384, 
+    24576, 28672, 29696, 29697, 29699, 29632, 29640, 29642, 
+        0, 16384, 24576, 28672, 29696, 29697, 29699, 29632, 
+    29640,     0, 16384, 24576, 28672, 29696, 29697, 29699, 
+    29632, 29648, 29644,     0, 16384, 24576, 28672, 29696, 
+    29697, 29699, 29632, 29648, 29644,     0, 16384, 24576, 
+    28672, 29696, 29697, 29699, 29632, 29648, 29649, 29646, 
+        0, 16384, 24576, 28672, 29696, 29697, 29699, 29632, 
+        0, 16384, 24576, 28672, 29696, 29697, 29699, 29632, 
+    29648,     0, 16384, 24576, 28672, 29696, 29697, 29699, 
+    29632, 29648,     0, 16384, 24576, 28672, 29696, 29697, 
+    29699, 29632, 29648, 29650,     0, 16384, 24576, 28672, 
+    29696, 29697, 29699, 29632, 29648,     0, 16384, 24576, 
+    28672, 29696, 29697, 29699, 29632, 29648, 29652,     0, 
+    16384, 24576, 28672, 29696, 29697, 29699, 29632, 29648, 
+    29652,     0, 16384, 24576, 28672, 29696, 29697, 29699, 
+    29632, 29648, 29656, 29654,     0, 16384, 24576, 28672, 
+    29696, 29697, 29699, 29632, 29648,     0, 16384, 24576, 
+    28672, 29696, 29697, 29699, 29632, 29664, 29656,     0, 
+    16384, 24576, 28672, 29696, 29697, 29699, 29632, 29664, 
+    29656,     0, 16384, 24576, 28672, 29696, 29697, 29699, 
+    29632, 29664, 29656, 29658,     0, 16384, 24576, 28672, 
+    29696, 29697, 29699, 29632, 29664, 29656,     0, 16384, 
+    24576, 28672, 29696, 29697, 29699, 29632, 29664, 29665, 
+    29660,     0, 16384, 24576, 28672, 29696, 29697, 29699, 
+    29632, 29664, 29665, 29660,     0, 16384, 24576, 28672, 
+    29696, 29697, 29699, 29632, 29664, 29665, 29660, 29662, 
+        0, 16384, 24576, 28672, 29696, 29697, 29699, 29632, 
+        0, 16384, 24576, 28672, 29696, 29697, 29699, 29632, 
+    29664,     0, 16384, 24576, 28672, 29696, 29697, 29699, 
+    29632, 29664,     0, 16384, 24576, 28672, 29696, 29697, 
+    29699, 29632, 29664, 29666,     0, 16384, 24576, 28672, 
+    29696, 29697, 29699, 29632, 29664,     0, 16384, 24576, 
+    28672, 29696, 29697, 29699, 29632, 29664, 29668,     0, 
+    16384, 24576, 28672, 29696, 29697, 29699, 29632, 29664, 
+    29668,     0, 16384, 24576, 28672, 29696, 29697, 29699, 
+    29632, 29664, 29672, 29670,     0, 16384, 24576, 28672, 
+    29696, 29697, 29699, 29703, 29664,     0, 16384, 24576, 
+    28672, 29696, 29697, 29699, 29703, 29664, 29672,     0, 
+    16384, 24576, 28672, 29696, 29697, 29699, 29703, 29664, 
+    29672,     0, 16384, 24576, 28672, 29696, 29697, 29699, 
+    29703, 29664, 29672, 29674,     0, 16384, 24576, 28672, 
+    29696, 29697, 29699, 29703, 29664, 29672,     0, 16384, 
+    24576, 28672, 29696, 29697, 29699, 29703, 29664, 29680, 
+    29676,     0, 16384, 24576, 28672, 29696, 29697, 29699, 
+    29703, 29664, 29680, 29676,     0, 16384, 24576, 28672, 
+    29696, 29697, 29699, 29703, 29664, 29680, 29681, 29678, 
+        0, 16384, 24576, 28672, 29696, 29697, 29699, 29703, 
+    29664,     0, 16384, 24576, 28672, 29696, 29697, 29699, 
+    29703, 29664, 29680,     0, 16384, 24576, 28672, 29696, 
+    29697, 29699, 29703, 29664, 29680,     0, 16384, 24576, 
+    28672, 29696, 29697, 29699, 29703, 29664, 29680, 29682, 
+        0, 16384, 24576, 28672, 29696, 29697, 29699, 29703, 
+    29664, 29680,     0, 16384, 24576, 28672, 29696, 29697, 
+    29699, 29703, 29664, 29680, 29684,     0, 16384, 24576, 
+    28672, 29696, 29697, 29699, 29703, 29664, 29680, 29684, 
+        0, 16384, 24576, 28672, 29696, 29697, 29699, 29703, 
+    29664, 29680, 29688, 29686,     0, 16384, 24576, 28672, 
+    29696, 29697, 29699, 29703, 29664, 29680,     0, 16384, 
+    24576, 28672, 29696, 29697, 29699, 29703, 29664, 29680, 
+    29688,     0, 16384, 24576, 28672, 29696, 29697, 29699, 
+    29703, 29664, 29680, 29688,     0, 16384, 24576, 28672, 
+    29696, 29697, 29699, 29703, 29664, 29680, 29688, 29690, 
+        0, 16384, 24576, 28672, 29696, 29697, 29699, 29703, 
+    29664, 29680, 29688,     0, 16384, 24576, 28672, 29696, 
+    29697, 29699, 29703, 29664, 29680, 29688, 29692,     0, 
+    16384, 24576, 28672, 29696, 29697, 29699, 29703, 29664, 
+    29680, 29688, 29692,     0, 16384, 24576, 28672, 29696, 
+    29697, 29699, 29703, 29664, 29680, 29688, 29692, 29694, 
+        0, 16384, 24576, 28672,     0, 16384, 24576, 28672, 
+    29696,     0, 16384, 24576, 28672, 29696,     0, 16384, 
+    24576, 28672, 29696, 29698,     0, 16384, 24576, 28672, 
+    29696,     0, 16384, 24576, 28672, 29696, 29700,     0, 
+    16384, 24576, 28672, 29696, 29700,     0, 16384, 24576, 
+    28672, 29696, 29704, 29702,     0, 16384, 24576, 28672, 
+    29696,     0, 16384, 24576, 28672, 29696, 29704,     0, 
+    16384, 24576, 28672, 29696, 29704,     0, 16384, 24576, 
+    28672, 29696, 29704, 29706,     0, 16384, 24576, 28672, 
+    29696, 29704,     0, 16384, 24576, 28672, 29696, 29712, 
+    29708,     0, 16384, 24576, 28672, 29696, 29712, 29708, 
+        0, 16384, 24576, 28672, 29696, 29712, 29713, 29710, 
+        0, 16384, 24576, 28672, 29696,     0, 16384, 24576, 
+    28672, 29696, 29712,     0, 16384, 24576, 28672, 29696, 
+    29712,     0, 16384, 24576, 28672, 29696, 29712, 29714, 
+        0, 16384, 24576, 28672, 29696, 29712,     0, 16384, 
+    24576, 28672, 29696, 29712, 29716,     0, 16384, 24576, 
+    28672, 29696, 29712, 29716,     0, 16384, 24576, 28672, 
+    29696, 29712, 29720, 29718,     0, 16384, 24576, 28672, 
+    29696, 29712,     0, 16384, 24576, 28672, 29696, 29728, 
+    29720,     0, 16384, 24576, 28672, 29696, 29728, 29720, 
+        0, 16384, 24576, 28672, 29696, 29728, 29720, 29722, 
+        0, 16384, 24576, 28672, 29696, 29728, 29720,     0, 
+    16384, 24576, 28672, 29696, 29728, 29729, 29724,     0, 
+    16384, 24576, 28672, 29696, 29728, 29729, 29724,     0, 
+    16384, 24576, 28672, 29696, 29728, 29729, 29724, 29726, 
+        0, 16384, 24576, 28672, 29696,     0, 16384, 24576, 
+    28672, 29696, 29728,     0, 16384, 24576, 28672, 29696, 
+    29728,     0, 16384, 24576, 28672, 29696, 29728, 29730, 
+        0, 16384, 24576, 28672, 29696, 29728,     0, 16384, 
+    24576, 28672, 29696, 29728, 29732,     0, 16384, 24576, 
+    28672, 29696, 29728, 29732,     0, 16384, 24576, 28672, 
+    29696, 29728, 29736, 29734,     0, 16384, 24576, 28672, 
+    29696, 29728,     0, 16384, 24576, 28672, 29696, 29728, 
+    29736,     0, 16384, 24576, 28672, 29696, 29728, 29736, 
+        0, 16384, 24576, 28672, 29696, 29728, 29736, 29738, 
+        0, 16384, 24576, 28672, 29696, 29728, 29736,     0, 
+    16384, 24576, 28672, 29696, 29728, 29744, 29740,     0, 
+    16384, 24576, 28672, 29696, 29728, 29744, 29740,     0, 
+    16384, 24576, 28672, 29696, 29728, 29744, 29745, 29742, 
+        0, 16384, 24576, 28672, 29696, 29728,     0, 16384, 
+    24576, 28672, 29696, 29760, 29744,     0, 16384, 24576, 
+    28672, 29696, 29760, 29744,     0, 16384, 24576, 28672, 
+    29696, 29760, 29744, 29746,     0, 16384, 24576, 28672, 
+    29696, 29760, 29744,     0, 16384, 24576, 28672, 29696, 
+    29760, 29744, 29748,     0, 16384, 24576, 28672, 29696, 
+    29760, 29744, 29748,     0, 16384, 24576, 28672, 29696, 
+    29760, 29744, 29752, 29750,     0, 16384, 24576, 28672, 
+    29696, 29760, 29744,     0, 16384, 24576, 28672, 29696, 
+    29760, 29761, 29752,     0, 16384, 24576, 28672, 29696, 
+    29760, 29761, 29752,     0, 16384, 24576, 28672, 29696, 
+    29760, 29761, 29752, 29754,     0, 16384, 24576, 28672, 
+    29696, 29760, 29761, 29752,     0, 16384, 24576, 28672, 
+    29696, 29760, 29761, 29752, 29756,     0, 16384, 24576, 
+    28672, 29696, 29760, 29761, 29763, 29756,     0, 16384, 
+    24576, 28672, 29696, 29760, 29761, 29763, 29756, 29758, 
+        0, 16384, 24576, 28672, 29696,     0, 16384, 24576, 
+    28672, 29696, 29760,     0, 16384, 24576, 28672, 29696, 
+    29760,     0, 16384, 24576, 28672, 29696, 29760, 29762, 
+        0, 16384, 24576, 28672, 29696, 29760,     0, 16384, 
+    24576, 28672, 29696, 29760, 29764,     0, 16384, 24576, 
+    28672, 29696, 29760, 29764,     0, 16384, 24576, 28672, 
+    29696, 29760, 29768, 29766,     0, 16384, 24576, 28672, 
+    29696, 29760,     0, 16384, 24576, 28672, 29696, 29760, 
+    29768,     0, 16384, 24576, 28672, 29696, 29760, 29768, 
+        0, 16384, 24576, 28672, 29696, 29760, 29768, 29770, 
+        0, 16384, 24576, 28672, 29696, 29760, 29768,     0, 
+    16384, 24576, 28672, 29696, 29760, 29776, 29772,     0, 
+    16384, 24576, 28672, 29696, 29760, 29776, 29772,     0, 
+    16384, 24576, 28672, 29696, 29760, 29776, 29777, 29774, 
+        0, 16384, 24576, 28672, 29696, 29760,     0, 16384, 
+    24576, 28672, 29696, 29760, 29776,     0, 16384, 24576, 
+    28672, 29696, 29760, 29776,     0, 16384, 24576, 28672, 
+    29696, 29760, 29776, 29778,     0, 16384, 24576, 28672, 
+    29696, 29760, 29776,     0, 16384, 24576, 28672, 29696, 
+    29760, 29776, 29780,     0, 16384, 24576, 28672, 29696, 
+    29760, 29776, 29780,     0, 16384, 24576, 28672, 29696, 
+    29760, 29776, 29784, 29782,     0, 16384, 24576, 28672, 
+    29696, 29760, 29776,     0, 16384, 24576, 28672, 29696, 
+    29760, 29792, 29784,     0, 16384, 24576, 28672, 29696, 
+    29760, 29792, 29784,     0, 16384, 24576, 28672, 29696, 
+    29760, 29792, 29784, 29786,     0, 16384, 24576, 28672, 
+    29696, 29760, 29792, 29784,     0, 16384, 24576, 28672, 
+    29696, 29760, 29792, 29793, 29788,     0, 16384, 24576, 
+    28672, 29696, 29760, 29792, 29793, 29788,     0, 16384, 
+    24576, 28672, 29696, 29760, 29792, 29793, 29788, 29790, 
+        0, 16384, 24576, 28672, 29696, 29760,     0, 16384, 
+    24576, 28672, 29696, 29824, 29792,     0, 16384, 24576, 
+    28672, 29696, 29824, 29792,     0, 16384, 24576, 28672, 
+    29696, 29824, 29792, 29794,     0, 16384, 24576, 28672, 
+    29696, 29824, 29792,     0, 16384, 24576, 28672, 29696, 
+    29824, 29792, 29796,     0, 16384, 24576, 28672, 29696, 
+    29824, 29792, 29796,     0, 16384, 24576, 28672, 29696, 
+    29824, 29792, 29800, 29798,     0, 16384, 24576, 28672, 
+    29696, 29824, 29792,     0, 16384, 24576, 28672, 29696, 
+    29824, 29792, 29800,     0, 16384, 24576, 28672, 29696, 
+    29824, 29792, 29800,     0, 16384, 24576, 28672, 29696, 
+    29824, 29792, 29800, 29802,     0, 16384, 24576, 28672, 
+    29696, 29824, 29792, 29800,     0, 16384, 24576, 28672, 
+    29696, 29824, 29792, 29808, 29804,     0, 16384, 24576, 
+    28672, 29696, 29824, 29792, 29808, 29804,     0, 16384, 
+    24576, 28672, 29696, 29824, 29792, 29808, 29809, 29806, 
+        0, 16384, 24576, 28672, 29696, 29824, 29792,     0, 
+    16384, 24576, 28672, 29696, 29824, 29825, 29808,     0, 
+    16384, 24576, 28672, 29696, 29824, 29825, 29808,     0, 
+    16384, 24576, 28672, 29696, 29824, 29825, 29808, 29810, 
+        0, 16384, 24576, 28672, 29696, 29824, 29825, 29808, 
+        0, 16384, 24576, 28672, 29696, 29824, 29825, 29808, 
+    29812,     0, 16384, 24576, 28672, 29696, 29824, 29825, 
+    29808, 29812,     0, 16384, 24576, 28672, 29696, 29824, 
+    29825, 29808, 29816, 29814,     0, 16384, 24576, 28672, 
+    29696, 29824, 29825, 29808,     0, 16384, 24576, 28672, 
+    29696, 29824, 29825, 29808, 29816,     0, 16384, 24576, 
+    28672, 29696, 29824, 29825, 29827, 29816,     0, 16384, 
+    24576, 28672, 29696, 29824, 29825, 29827, 29816, 29818, 
+        0, 16384, 24576, 28672, 29696, 29824, 29825, 29827, 
+    29816,     0, 16384, 24576, 28672, 29696, 29824, 29825, 
+    29827, 29816, 29820,     0, 16384, 24576, 28672, 29696, 
+    29824, 29825, 29827, 29816, 29820,     0, 16384, 24576, 
+    28672, 29696, 29824, 29825, 29827, 29816, 29820, 29822, 
+        0, 16384, 24576, 28672, 29696,     0, 16384, 24576, 
+    28672, 29696, 29824,     0, 16384, 24576, 28672, 29696, 
+    29824,     0, 16384, 24576, 28672, 29696, 29824, 29826, 
+        0, 16384, 24576, 28672, 29696, 29824,     0, 16384, 
+    24576, 28672, 29696, 29824, 29828,     0, 16384, 24576, 
+    28672, 29696, 29824, 29828,     0, 16384, 24576, 28672, 
+    29696, 29824, 29832, 29830,     0, 16384, 24576, 28672, 
+    29696, 29824,     0, 16384, 24576, 28672, 29696, 29824, 
+    29832,     0, 16384, 24576, 28672, 29696, 29824, 29832, 
+        0, 16384, 24576, 28672, 29696, 29824, 29832, 29834, 
+        0, 16384, 24576, 28672, 29696, 29824, 29832,     0, 
+    16384, 24576, 28672, 29696, 29824, 29840, 29836,     0, 
+    16384, 24576, 28672, 29696, 29824, 29840, 29836,     0, 
+    16384, 24576, 28672, 29696, 29824, 29840, 29841, 29838, 
+        0, 16384, 24576, 28672, 29696, 29824,     0, 16384, 
+    24576, 28672, 29696, 29824, 29840,     0, 16384, 24576, 
+    28672, 29696, 29824, 29840,     0, 16384, 24576, 28672, 
+    29696, 29824, 29840, 29842,     0, 16384, 24576, 28672, 
+    29696, 29824, 29840,     0, 16384, 24576, 28672, 29696, 
+    29824, 29840, 29844,     0, 16384, 24576, 28672, 29696, 
+    29824, 29840, 29844,     0, 16384, 24576, 28672, 29696, 
+    29824, 29840, 29848, 29846,     0, 16384, 24576, 28672, 
+    29696, 29824, 29840,     0, 16384, 24576, 28672, 29696, 
+    29824, 29856, 29848,     0, 16384, 24576, 28672, 29696, 
+    29824, 29856, 29848,     0, 16384, 24576, 28672, 29696, 
+    29824, 29856, 29848, 29850,     0, 16384, 24576, 28672, 
+    29696, 29824, 29856, 29848,     0, 16384, 24576, 28672, 
+    29696, 29824, 29856, 29857, 29852,     0, 16384, 24576, 
+    28672, 29696, 29824, 29856, 29857, 29852,     0, 16384, 
+    24576, 28672, 29696, 29824, 29856, 29857, 29852, 29854, 
+        0, 16384, 24576, 28672, 29696, 29824,     0, 16384, 
+    24576, 28672, 29696, 29824, 29856,     0, 16384, 24576, 
+    28672, 29696, 29824, 29856,     0, 16384, 24576, 28672, 
+    29696, 29824, 29856, 29858,     0, 16384, 24576, 28672, 
+    29696, 29824, 29856,     0, 16384, 24576, 28672, 29696, 
+    29824, 29856, 29860,     0, 16384, 24576, 28672, 29696, 
+    29824, 29856, 29860,     0, 16384, 24576, 28672, 29696, 
+    29824, 29856, 29864, 29862,     0, 16384, 24576, 28672, 
+    29696, 29824, 29856,     0, 16384, 24576, 28672, 29696, 
+    29824, 29856, 29864,     0, 16384, 24576, 28672, 29696, 
+    29824, 29856, 29864,     0, 16384, 24576, 28672, 29696, 
+    29824, 29856, 29864, 29866,     0, 16384, 24576, 28672, 
+    29696, 29824, 29856, 29864,     0, 16384, 24576, 28672, 
+    29696, 29824, 29856, 29872, 29868,     0, 16384, 24576, 
+    28672, 29696, 29824, 29856, 29872, 29868,     0, 16384, 
+    24576, 28672, 29696, 29824, 29856, 29872, 29873, 29870, 
+        0, 16384, 24576, 28672, 29696, 29824, 29856,     0, 
+    16384, 24576, 28672, 29696, 29824, 29888, 29872,     0, 
+    16384, 24576, 28672, 29696, 29824, 29888, 29872,     0, 
+    16384, 24576, 28672, 29696, 29824, 29888, 29872, 29874, 
+        0, 16384, 24576, 28672, 29696, 29824, 29888, 29872, 
+        0, 16384, 24576, 28672, 29696, 29824, 29888, 29872, 
+    29876,     0, 16384, 24576, 28672, 29696, 29824, 29888, 
+    29872, 29876,     0, 16384, 24576, 28672, 29696, 29824, 
+    29888, 29872, 29880, 29878,     0, 16384, 24576, 28672, 
+    29696, 29824, 29888, 29872,     0, 16384, 24576, 28672, 
+    29696, 29824, 29888, 29889, 29880,     0, 16384, 24576, 
+    28672, 29696, 29824, 29888, 29889, 29880,     0, 16384, 
+    24576, 28672, 29696, 29824, 29888, 29889, 29880, 29882, 
+        0, 16384, 24576, 28672, 29696, 29824, 29888, 29889, 
+    29880,     0, 16384, 24576, 28672, 29696, 29824, 29888, 
+    29889, 29880, 29884,     0, 16384, 24576, 28672, 29696, 
+    29824, 29888, 29889, 29891, 29884,     0, 16384, 24576, 
+    28672, 29696, 29824, 29888, 29889, 29891, 29884, 29886, 
+        0, 16384, 24576, 28672, 29696, 29824,     0, 16384, 
+    24576, 28672, 29696, 29952, 29888,     0, 16384, 24576, 
+    28672, 29696, 29952, 29888,     0, 16384, 24576, 28672, 
+    29696, 29952, 29888, 29890,     0, 16384, 24576, 28672, 
+    29696, 29952, 29888,     0, 16384, 24576, 28672, 29696, 
+    29952, 29888, 29892,     0, 16384, 24576, 28672, 29696, 
+    29952, 29888, 29892,     0, 16384, 24576, 28672, 29696, 
+    29952, 29888, 29896, 29894,     0, 16384, 24576, 28672, 
+    29696, 29952, 29888,     0, 16384, 24576, 28672, 29696, 
+    29952, 29888, 29896,     0, 16384, 24576, 28672, 29696, 
+    29952, 29888, 29896,     0, 16384, 24576, 28672, 29696, 
+    29952, 29888, 29896, 29898,     0, 16384, 24576, 28672, 
+    29696, 29952, 29888, 29896,     0, 16384, 24576, 28672, 
+    29696, 29952, 29888, 29904, 29900,     0, 16384, 24576, 
+    28672, 29696, 29952, 29888, 29904, 29900,     0, 16384, 
+    24576, 28672, 29696, 29952, 29888, 29904, 29905, 29902, 
+        0, 16384, 24576, 28672, 29696, 29952, 29888,     0, 
+    16384, 24576, 28672, 29696, 29952, 29888, 29904,     0, 
+    16384, 24576, 28672, 29696, 29952, 29888, 29904,     0, 
+    16384, 24576, 28672, 29696, 29952, 29888, 29904, 29906, 
+        0, 16384, 24576, 28672, 29696, 29952, 29888, 29904, 
+        0, 16384, 24576, 28672, 29696, 29952, 29888, 29904, 
+    29908,     0, 16384, 24576, 28672, 29696, 29952, 29888, 
+    29904, 29908,     0, 16384, 24576, 28672, 29696, 29952, 
+    29888, 29904, 29912, 29910,     0, 16384, 24576, 28672, 
+    29696, 29952, 29888, 29904,     0, 16384, 24576, 28672, 
+    29696, 29952, 29888, 29920, 29912,     0, 16384, 24576, 
+    28672, 29696, 29952, 29888, 29920, 29912,     0, 16384, 
+    24576, 28672, 29696, 29952, 29888, 29920, 29912, 29914, 
+        0, 16384, 24576, 28672, 29696, 29952, 29888, 29920, 
+    29912,     0, 16384, 24576, 28672, 29696, 29952, 29888, 
+    29920, 29921, 29916,     0, 16384, 24576, 28672, 29696, 
+    29952, 29888, 29920, 29921, 29916,     0, 16384, 24576, 
+    28672, 29696, 29952, 29888, 29920, 29921, 29916, 29918, 
+        0, 16384, 24576, 28672, 29696, 29952, 29888,     0, 
+    16384, 24576, 28672, 29696, 29952, 29953, 29920,     0, 
+    16384, 24576, 28672, 29696, 29952, 29953, 29920,     0, 
+    16384, 24576, 28672, 29696, 29952, 29953, 29920, 29922, 
+        0, 16384, 24576, 28672, 29696, 29952, 29953, 29920, 
+        0, 16384, 24576, 28672, 29696, 29952, 29953, 29920, 
+    29924,     0, 16384, 24576, 28672, 29696, 29952, 29953, 
+    29920, 29924,     0, 16384, 24576, 28672, 29696, 29952, 
+    29953, 29920, 29928, 29926,     0, 16384, 24576, 28672, 
+    29696, 29952, 29953, 29920,     0, 16384, 24576, 28672, 
+    29696, 29952, 29953, 29920, 29928,     0, 16384, 24576, 
+    28672, 29696, 29952, 29953, 29920, 29928,     0, 16384, 
+    24576, 28672, 29696, 29952, 29953, 29920, 29928, 29930, 
+        0, 16384, 24576, 28672, 29696, 29952, 29953, 29920, 
+    29928,     0, 16384, 24576, 28672, 29696, 29952, 29953, 
+    29920, 29936, 29932,     0, 16384, 24576, 28672, 29696, 
+    29952, 29953, 29920, 29936, 29932,     0, 16384, 24576, 
+    28672, 29696, 29952, 29953, 29920, 29936, 29937, 29934, 
+        0, 16384, 24576, 28672, 29696, 29952, 29953, 29920, 
+        0, 16384, 24576, 28672, 29696, 29952, 29953, 29920, 
+    29936,     0, 16384, 24576, 28672, 29696, 29952, 29953, 
+    29955, 29936,     0, 16384, 24576, 28672, 29696, 29952, 
+    29953, 29955, 29936, 29938,     0, 16384, 24576, 28672, 
+    29696, 29952, 29953, 29955, 29936,     0, 16384, 24576, 
+    28672, 29696, 29952, 29953, 29955, 29936, 29940,     0, 
+    16384, 24576, 28672, 29696, 29952, 29953, 29955, 29936, 
+    29940,     0, 16384, 24576, 28672, 29696, 29952, 29953, 
+    29955, 29936, 29944, 29942,     0, 16384, 24576, 28672, 
+    29696, 29952, 29953, 29955, 29936,     0, 16384, 24576, 
+    28672, 29696, 29952, 29953, 29955, 29936, 29944,     0, 
+    16384, 24576, 28672, 29696, 29952, 29953, 29955, 29936, 
+    29944,     0, 16384, 24576, 28672, 29696, 29952, 29953, 
+    29955, 29936, 29944, 29946,     0, 16384, 24576, 28672, 
+    29696, 29952, 29953, 29955, 29959, 29944,     0, 16384, 
+    24576, 28672, 29696, 29952, 29953, 29955, 29959, 29944, 
+    29948,     0, 16384, 24576, 28672, 29696, 29952, 29953, 
+    29955, 29959, 29944, 29948,     0, 16384, 24576, 28672, 
+    29696, 29952, 29953, 29955, 29959, 29944, 29948, 29950, 
+        0, 16384, 24576, 28672, 29696,     0, 16384, 24576, 
+    28672, 29696, 29952,     0, 16384, 24576, 28672, 29696, 
+    29952,     0, 16384, 24576, 28672, 29696, 29952, 29954, 
+        0, 16384, 24576, 28672, 29696, 29952,     0, 16384, 
+    24576, 28672, 29696, 29952, 29956,     0, 16384, 24576, 
+    28672, 29696, 29952, 29956,     0, 16384, 24576, 28672, 
+    29696, 29952, 29960, 29958,     0, 16384, 24576, 28672, 
+    29696, 29952,     0, 16384, 24576, 28672, 29696, 29952, 
+    29960,     0, 16384, 24576, 28672, 29696, 29952, 29960, 
+        0, 16384, 24576, 28672, 29696, 29952, 29960, 29962, 
+        0, 16384, 24576, 28672, 29696, 29952, 29960,     0, 
+    16384, 24576, 28672, 29696, 29952, 29968, 29964,     0, 
+    16384, 24576, 28672, 29696, 29952, 29968, 29964,     0, 
+    16384, 24576, 28672, 29696, 29952, 29968, 29969, 29966, 
+        0, 16384, 24576, 28672, 29696, 29952,     0, 16384, 
+    24576, 28672, 29696, 29952, 29968,     0, 16384, 24576, 
+    28672, 29696, 29952, 29968,     0, 16384, 24576, 28672, 
+    29696, 29952, 29968, 29970,     0, 16384, 24576, 28672, 
+    29696, 29952, 29968,     0, 16384, 24576, 28672, 29696, 
+    29952, 29968, 29972,     0, 16384, 24576, 28672, 29696, 
+    29952, 29968, 29972,     0, 16384, 24576, 28672, 29696, 
+    29952, 29968, 29976, 29974,     0, 16384, 24576, 28672, 
+    29696, 29952, 29968,     0, 16384, 24576, 28672, 29696, 
+    29952, 29984, 29976,     0, 16384, 24576, 28672, 29696, 
+    29952, 29984, 29976,     0, 16384, 24576, 28672, 29696, 
+    29952, 29984, 29976, 29978,     0, 16384, 24576, 28672, 
+    29696, 29952, 29984, 29976,     0, 16384, 24576, 28672, 
+    29696, 29952, 29984, 29985, 29980,     0, 16384, 24576, 
+    28672, 29696, 29952, 29984, 29985, 29980,     0, 16384, 
+    24576, 28672, 29696, 29952, 29984, 29985, 29980, 29982, 
+        0, 16384, 24576, 28672, 29696, 29952,     0, 16384, 
+    24576, 28672, 29696, 29952, 29984,     0, 16384, 24576, 
+    28672, 29696, 29952, 29984,     0, 16384, 24576, 28672, 
+    29696, 29952, 29984, 29986,     0, 16384, 24576, 28672, 
+    29696, 29952, 29984,     0, 16384, 24576, 28672, 29696, 
+    29952, 29984, 29988,     0, 16384, 24576, 28672, 29696, 
+    29952, 29984, 29988,     0, 16384, 24576, 28672, 29696, 
+    29952, 29984, 29992, 29990,     0, 16384, 24576, 28672, 
+    29696, 29952, 29984,     0, 16384, 24576, 28672, 29696, 
+    29952, 29984, 29992,     0, 16384, 24576, 28672, 29696, 
+    29952, 29984, 29992,     0, 16384, 24576, 28672, 29696, 
+    29952, 29984, 29992, 29994,     0, 16384, 24576, 28672, 
+    29696, 29952, 29984, 29992,     0, 16384, 24576, 28672, 
+    29696, 29952, 29984, 30000, 29996,     0, 16384, 24576, 
+    28672, 29696, 29952, 29984, 30000, 29996,     0, 16384, 
+    24576, 28672, 29696, 29952, 29984, 30000, 30001, 29998, 
+        0, 16384, 24576, 28672, 29696, 29952, 29984,     0, 
+    16384, 24576, 28672, 29696, 29952, 30016, 30000,     0, 
+    16384, 24576, 28672, 29696, 29952, 30016, 30000,     0, 
+    16384, 24576, 28672, 29696, 29952, 30016, 30000, 30002, 
+        0, 16384, 24576, 28672, 29696, 29952, 30016, 30000, 
+        0, 16384, 24576, 28672, 29696, 29952, 30016, 30000, 
+    30004,     0, 16384, 24576, 28672, 29696, 29952, 30016, 
+    30000, 30004,     0, 16384, 24576, 28672, 29696, 29952, 
+    30016, 30000, 30008, 30006,     0, 16384, 24576, 28672, 
+    29696, 29952, 30016, 30000,     0, 16384, 24576, 28672, 
+    29696, 29952, 30016, 30017, 30008,     0, 16384, 24576, 
+    28672, 29696, 29952, 30016, 30017, 30008,     0, 16384, 
+    24576, 28672, 29696, 29952, 30016, 30017, 30008, 30010, 
+        0, 16384, 24576, 28672, 29696, 29952, 30016, 30017, 
+    30008,     0, 16384, 24576, 28672, 29696, 29952, 30016, 
+    30017, 30008, 30012,     0, 16384, 24576, 28672, 29696, 
+    29952, 30016, 30017, 30019, 30012,     0, 16384, 24576, 
+    28672, 29696, 29952, 30016, 30017, 30019, 30012, 30014, 
+        0, 16384, 24576, 28672, 29696, 29952,     0, 16384, 
+    24576, 28672, 29696, 29952, 30016,     0, 16384, 24576, 
+    28672, 29696, 29952, 30016,     0, 16384, 24576, 28672, 
+    29696, 29952, 30016, 30018,     0, 16384, 24576, 28672, 
+    29696, 29952, 30016,     0, 16384, 24576, 28672, 29696, 
+    29952, 30016, 30020,     0, 16384, 24576, 28672, 29696, 
+    29952, 30016, 30020,     0, 16384, 24576, 28672, 29696, 
+    29952, 30016, 30024, 30022,     0, 16384, 24576, 28672, 
+    29696, 29952, 30016,     0, 16384, 24576, 28672, 29696, 
+    29952, 30016, 30024,     0, 16384, 24576, 28672, 29696, 
+    29952, 30016, 30024,     0, 16384, 24576, 28672, 29696, 
+    29952, 30016, 30024, 30026,     0, 16384, 24576, 28672, 
+    29696, 29952, 30016, 30024,     0, 16384, 24576, 28672, 
+    29696, 29952, 30016, 30032, 30028,     0, 16384, 24576, 
+    28672, 29696, 29952, 30016, 30032, 30028,     0, 16384, 
+    24576, 28672, 29696, 29952, 30016, 30032, 30033, 30030, 
+        0, 16384, 24576, 28672, 29696, 29952, 30016,     0, 
+    16384, 24576, 28672, 29696, 29952, 30016, 30032,     0, 
+    16384, 24576, 28672, 29696, 29952, 30016, 30032,     0, 
+    16384, 24576, 28672, 29696, 29952, 30016, 30032, 30034, 
+        0, 16384, 24576, 28672, 29696, 29952, 30016, 30032, 
+        0, 16384, 24576, 28672, 29696, 29952, 30016, 30032, 
+    30036,     0, 16384, 24576, 28672, 29696, 29952, 30016, 
+    30032, 30036,     0, 16384, 24576, 28672, 29696, 29952, 
+    30016, 30032, 30040, 30038,     0, 16384, 24576, 28672, 
+    29696, 29952, 30016, 30032,     0, 16384, 24576, 28672, 
+    29696, 29952, 30016, 30048, 30040,     0, 16384, 24576, 
+    28672, 29696, 29952, 30016, 30048, 30040,     0, 16384, 
+    24576, 28672, 29696, 29952, 30016, 30048, 30040, 30042, 
+        0, 16384, 24576, 28672, 29696, 29952, 30016, 30048, 
+    30040,     0, 16384, 24576, 28672, 29696, 29952, 30016, 
+    30048, 30049, 30044,     0, 16384, 24576, 28672, 29696, 
+    29952, 30016, 30048, 30049, 30044,     0, 16384, 24576, 
+    28672, 29696, 29952, 30016, 30048, 30049, 30044, 30046, 
+        0, 16384, 24576, 28672, 29696, 29952, 30016,     0, 
+    16384, 24576, 28672, 29696, 29952, 30080, 30048,     0, 
+    16384, 24576, 28672, 29696, 29952, 30080, 30048,     0, 
+    16384, 24576, 28672, 29696, 29952, 30080, 30048, 30050, 
+        0, 16384, 24576, 28672, 29696, 29952, 30080, 30048, 
+        0, 16384, 24576, 28672, 29696, 29952, 30080, 30048, 
+    30052,     0, 16384, 24576, 28672, 29696, 29952, 30080, 
+    30048, 30052,     0, 16384, 24576, 28672, 29696, 29952, 
+    30080, 30048, 30056, 30054,     0, 16384, 24576, 28672, 
+    29696, 29952, 30080, 30048,     0, 16384, 24576, 28672, 
+    29696, 29952, 30080, 30048, 30056,     0, 16384, 24576, 
+    28672, 29696, 29952, 30080, 30048, 30056,     0, 16384, 
+    24576, 28672, 29696, 29952, 30080, 30048, 30056, 30058, 
+        0, 16384, 24576, 28672, 29696, 29952, 30080, 30048, 
+    30056,     0, 16384, 24576, 28672, 29696, 29952, 30080, 
+    30048, 30064, 30060,     0, 16384, 24576, 28672, 29696, 
+    29952, 30080, 30048, 30064, 30060,     0, 16384, 24576, 
+    28672, 29696, 29952, 30080, 30048, 30064, 30065, 30062, 
+        0, 16384, 24576, 28672, 29696, 29952, 30080, 30048, 
+        0, 16384, 24576, 28672, 29696, 29952, 30080, 30081, 
+    30064,     0, 16384, 24576, 28672, 29696, 29952, 30080, 
+    30081, 30064,     0, 16384, 24576, 28672, 29696, 29952, 
+    30080, 30081, 30064, 30066,     0, 16384, 24576, 28672, 
+    29696, 29952, 30080, 30081, 30064,     0, 16384, 24576, 
+    28672, 29696, 29952, 30080, 30081, 30064, 30068,     0, 
+    16384, 24576, 28672, 29696, 29952, 30080, 30081, 30064, 
+    30068,     0, 16384, 24576, 28672, 29696, 29952, 30080, 
+    30081, 30064, 30072, 30070,     0, 16384, 24576, 28672, 
+    29696, 29952, 30080, 30081, 30064,     0, 16384, 24576, 
+    28672, 29696, 29952, 30080, 30081, 30064, 30072,     0, 
+    16384, 24576, 28672, 29696, 29952, 30080, 30081, 30083, 
+    30072,     0, 16384, 24576, 28672, 29696, 29952, 30080, 
+    30081, 30083, 30072, 30074,     0, 16384, 24576, 28672, 
+    29696, 29952, 30080, 30081, 30083, 30072,     0, 16384, 
+    24576, 28672, 29696, 29952, 30080, 30081, 30083, 30072, 
+    30076,     0, 16384, 24576, 28672, 29696, 29952, 30080, 
+    30081, 30083, 30072, 30076,     0, 16384, 24576, 28672, 
+    29696, 29952, 30080, 30081, 30083, 30072, 30076, 30078, 
+        0, 16384, 24576, 28672, 29696, 29952,     0, 16384, 
+    24576, 28672, 29696, 30208, 30080,     0, 16384, 24576, 
+    28672, 29696, 30208, 30080,     0, 16384, 24576, 28672, 
+    29696, 30208, 30080, 30082,     0, 16384, 24576, 28672, 
+    29696, 30208, 30080,     0, 16384, 24576, 28672, 29696, 
+    30208, 30080, 30084,     0, 16384, 24576, 28672, 29696, 
+    30208, 30080, 30084,     0, 16384, 24576, 28672, 29696, 
+    30208, 30080, 30088, 30086,     0, 16384, 24576, 28672, 
+    29696, 30208, 30080,     0, 16384, 24576, 28672, 29696, 
+    30208, 30080, 30088,     0, 16384, 24576, 28672, 29696, 
+    30208, 30080, 30088,     0, 16384, 24576, 28672, 29696, 
+    30208, 30080, 30088, 30090,     0, 16384, 24576, 28672, 
+    29696, 30208, 30080, 30088,     0, 16384, 24576, 28672, 
+    29696, 30208, 30080, 30096, 30092,     0, 16384, 24576, 
+    28672, 29696, 30208, 30080, 30096, 30092,     0, 16384, 
+    24576, 28672, 29696, 30208, 30080, 30096, 30097, 30094, 
+        0, 16384, 24576, 28672, 29696, 30208, 30080,     0, 
+    16384, 24576, 28672, 29696, 30208, 30080, 30096,     0, 
+    16384, 24576, 28672, 29696, 30208, 30080, 30096,     0, 
+    16384, 24576, 28672, 29696, 30208, 30080, 30096, 30098, 
+        0, 16384, 24576, 28672, 29696, 30208, 30080, 30096, 
+        0, 16384, 24576, 28672, 29696, 30208, 30080, 30096, 
+    30100,     0, 16384, 24576, 28672, 29696, 30208, 30080, 
+    30096, 30100,     0, 16384, 24576, 28672, 29696, 30208, 
+    30080, 30096, 30104, 30102,     0, 16384, 24576, 28672, 
+    29696, 30208, 30080, 30096,     0, 16384, 24576, 28672, 
+    29696, 30208, 30080, 30112, 30104,     0, 16384, 24576, 
+    28672, 29696, 30208, 30080, 30112, 30104,     0, 16384, 
+    24576, 28672, 29696, 30208, 30080, 30112, 30104, 30106, 
+        0, 16384, 24576, 28672, 29696, 30208, 30080, 30112, 
+    30104,     0, 16384, 24576, 28672, 29696, 30208, 30080, 
+    30112, 30113, 30108,     0, 16384, 24576, 28672, 29696, 
+    30208, 30080, 30112, 30113, 30108,     0, 16384, 24576, 
+    28672, 29696, 30208, 30080, 30112, 30113, 30108, 30110, 
+        0, 16384, 24576, 28672, 29696, 30208, 30080,     0, 
+    16384, 24576, 28672, 29696, 30208, 30080, 30112,     0, 
+    16384, 24576, 28672, 29696, 30208, 30080, 30112,     0, 
+    16384, 24576, 28672, 29696, 30208, 30080, 30112, 30114, 
+        0, 16384, 24576, 28672, 29696, 30208, 30080, 30112, 
+        0, 16384, 24576, 28672, 29696, 30208, 30080, 30112, 
+    30116,     0, 16384, 24576, 28672, 29696, 30208, 30080, 
+    30112, 30116,     0, 16384, 24576, 28672, 29696, 30208, 
+    30080, 30112, 30120, 30118,     0, 16384, 24576, 28672, 
+    29696, 30208, 30080, 30112,     0, 16384, 24576, 28672, 
+    29696, 30208, 30080, 30112, 30120,     0, 16384, 24576, 
+    28672, 29696, 30208, 30080, 30112, 30120,     0, 16384, 
+    24576, 28672, 29696, 30208, 30080, 30112, 30120, 30122, 
+        0, 16384, 24576, 28672, 29696, 30208, 30080, 30112, 
+    30120,     0, 16384, 24576, 28672, 29696, 30208, 30080, 
+    30112, 30128, 30124,     0, 16384, 24576, 28672, 29696, 
+    30208, 30080, 30112, 30128, 30124,     0, 16384, 24576, 
+    28672, 29696, 30208, 30080, 30112, 30128, 30129, 30126, 
+        0, 16384, 24576, 28672, 29696, 30208, 30080, 30112, 
+        0, 16384, 24576, 28672, 29696, 30208, 30080, 30144, 
+    30128,     0, 16384, 24576, 28672, 29696, 30208, 30080, 
+    30144, 30128,     0, 16384, 24576, 28672, 29696, 30208, 
+    30080, 30144, 30128, 30130,     0, 16384, 24576, 28672, 
+    29696, 30208, 30080, 30144, 30128,     0, 16384, 24576, 
+    28672, 29696, 30208, 30080, 30144, 30128, 30132,     0, 
+    16384, 24576, 28672, 29696, 30208, 30080, 30144, 30128, 
+    30132,     0, 16384, 24576, 28672, 29696, 30208, 30080, 
+    30144, 30128, 30136, 30134,     0, 16384, 24576, 28672, 
+    29696, 30208, 30080, 30144, 30128,     0, 16384, 24576, 
+    28672, 29696, 30208, 30080, 30144, 30145, 30136,     0, 
+    16384, 24576, 28672, 29696, 30208, 30080, 30144, 30145, 
+    30136,     0, 16384, 24576, 28672, 29696, 30208, 30080, 
+    30144, 30145, 30136, 30138,     0, 16384, 24576, 28672, 
+    29696, 30208, 30080, 30144, 30145, 30136,     0, 16384, 
+    24576, 28672, 29696, 30208, 30080, 30144, 30145, 30136, 
+    30140,     0, 16384, 24576, 28672, 29696, 30208, 30080, 
+    30144, 30145, 30147, 30140,     0, 16384, 24576, 28672, 
+    29696, 30208, 30080, 30144, 30145, 30147, 30140, 30142, 
+        0, 16384, 24576, 28672, 29696, 30208, 30080,     0, 
+    16384, 24576, 28672, 29696, 30208, 30209, 30144,     0, 
+    16384, 24576, 28672, 29696, 30208, 30209, 30144,     0, 
+    16384, 24576, 28672, 29696, 30208, 30209, 30144, 30146, 
+        0, 16384, 24576, 28672, 29696, 30208, 30209, 30144, 
+        0, 16384, 24576, 28672, 29696, 30208, 30209, 30144, 
+    30148,     0, 16384, 24576, 28672, 29696, 30208, 30209, 
+    30144, 30148,     0, 16384, 24576, 28672, 29696, 30208, 
+    30209, 30144, 30152, 30150,     0, 16384, 24576, 28672, 
+    29696, 30208, 30209, 30144,     0, 16384, 24576, 28672, 
+    29696, 30208, 30209, 30144, 30152,     0, 16384, 24576, 
+    28672, 29696, 30208, 30209, 30144, 30152,     0, 16384, 
+    24576, 28672, 29696, 30208, 30209, 30144, 30152, 30154, 
+        0, 16384, 24576, 28672, 29696, 30208, 30209, 30144, 
+    30152,     0, 16384, 24576, 28672, 29696, 30208, 30209, 
+    30144, 30160, 30156,     0, 16384, 24576, 28672, 29696, 
+    30208, 30209, 30144, 30160, 30156,     0, 16384, 24576, 
+    28672, 29696, 30208, 30209, 30144, 30160, 30161, 30158, 
+        0, 16384, 24576, 28672, 29696, 30208, 30209, 30144, 
+        0, 16384, 24576, 28672, 29696, 30208, 30209, 30144, 
+    30160,     0, 16384, 24576, 28672, 29696, 30208, 30209, 
+    30144, 30160,     0, 16384, 24576, 28672, 29696, 30208, 
+    30209, 30144, 30160, 30162,     0, 16384, 24576, 28672, 
+    29696, 30208, 30209, 30144, 30160,     0, 16384, 24576, 
+    28672, 29696, 30208, 30209, 30144, 30160, 30164,     0, 
+    16384, 24576, 28672, 29696, 30208, 30209, 30144, 30160, 
+    30164,     0, 16384, 24576, 28672, 29696, 30208, 30209, 
+    30144, 30160, 30168, 30166,     0, 16384, 24576, 28672, 
+    29696, 30208, 30209, 30144, 30160,     0, 16384, 24576, 
+    28672, 29696, 30208, 30209, 30144, 30176, 30168,     0, 
+    16384, 24576, 28672, 29696, 30208, 30209, 30144, 30176, 
+    30168,     0, 16384, 24576, 28672, 29696, 30208, 30209, 
+    30144, 30176, 30168, 30170,     0, 16384, 24576, 28672, 
+    29696, 30208, 30209, 30144, 30176, 30168,     0, 16384, 
+    24576, 28672, 29696, 30208, 30209, 30144, 30176, 30177, 
+    30172,     0, 16384, 24576, 28672, 29696, 30208, 30209, 
+    30144, 30176, 30177, 30172,     0, 16384, 24576, 28672, 
+    29696, 30208, 30209, 30144, 30176, 30177, 30172, 30174, 
+        0, 16384, 24576, 28672, 29696, 30208, 30209, 30144, 
+        0, 16384, 24576, 28672, 29696, 30208, 30209, 30144, 
+    30176,     0, 16384, 24576, 28672, 29696, 30208, 30209, 
+    30211, 30176,     0, 16384, 24576, 28672, 29696, 30208, 
+    30209, 30211, 30176, 30178,     0, 16384, 24576, 28672, 
+    29696, 30208, 30209, 30211, 30176,     0, 16384, 24576, 
+    28672, 29696, 30208, 30209, 30211, 30176, 30180,     0, 
+    16384, 24576, 28672, 29696, 30208, 30209, 30211, 30176, 
+    30180,     0, 16384, 24576, 28672, 29696, 30208, 30209, 
+    30211, 30176, 30184, 30182,     0, 16384, 24576, 28672, 
+    29696, 30208, 30209, 30211, 30176,     0, 16384, 24576, 
+    28672, 29696, 30208, 30209, 30211, 30176, 30184,     0, 
+    16384, 24576, 28672, 29696, 30208, 30209, 30211, 30176, 
+    30184,     0, 16384, 24576, 28672, 29696, 30208, 30209, 
+    30211, 30176, 30184, 30186,     0, 16384, 24576, 28672, 
+    29696, 30208, 30209, 30211, 30176, 30184,     0, 16384, 
+    24576, 28672, 29696, 30208, 30209, 30211, 30176, 30192, 
+    30188,     0, 16384, 24576, 28672, 29696, 30208, 30209, 
+    30211, 30176, 30192, 30188,     0, 16384, 24576, 28672, 
+    29696, 30208, 30209, 30211, 30176, 30192, 30193, 30190, 
+        0, 16384, 24576, 28672, 29696, 30208, 30209, 30211, 
+    30176,     0, 16384, 24576, 28672, 29696, 30208, 30209, 
+    30211, 30176, 30192,     0, 16384, 24576, 28672, 29696, 
+    30208, 30209, 30211, 30176, 30192,     0, 16384, 24576, 
+    28672, 29696, 30208, 30209, 30211, 30176, 30192, 30194, 
+        0, 16384, 24576, 28672, 29696, 30208, 30209, 30211, 
+    30215, 30192,     0, 16384, 24576, 28672, 29696, 30208, 
+    30209, 30211, 30215, 30192, 30196,     0, 16384, 24576, 
+    28672, 29696, 30208, 30209, 30211, 30215, 30192, 30196, 
+        0, 16384, 24576, 28672, 29696, 30208, 30209, 30211, 
+    30215, 30192, 30200, 30198,     0, 16384, 24576, 28672, 
+    29696, 30208, 30209, 30211, 30215, 30192,     0, 16384, 
+    24576, 28672, 29696, 30208, 30209, 30211, 30215, 30192, 
+    30200,     0, 16384, 24576, 28672, 29696, 30208, 30209, 
+    30211, 30215, 30192, 30200,     0, 16384, 24576, 28672, 
+    29696, 30208, 30209, 30211, 30215, 30192, 30200, 30202, 
+        0, 16384, 24576, 28672, 29696, 30208, 30209, 30211, 
+    30215, 30192, 30200,     0, 16384, 24576, 28672, 29696, 
+    30208, 30209, 30211, 30215, 30192, 30200, 30204,     0, 
+    16384, 24576, 28672, 29696, 30208, 30209, 30211, 30215, 
+    30192, 30200, 30204,     0, 16384, 24576, 28672, 29696, 
+    30208, 30209, 30211, 30215, 30192, 30200, 30204, 30206, 
+        0, 16384, 24576, 28672, 29696,     0, 16384, 24576, 
+    28672, 30720, 30208,     0, 16384, 24576, 28672, 30720, 
+    30208,     0, 16384, 24576, 28672, 30720, 30208, 30210, 
+        0, 16384, 24576, 28672, 30720, 30208,     0, 16384, 
+    24576, 28672, 30720, 30208, 30212,     0, 16384, 24576, 
+    28672, 30720, 30208, 30212,     0, 16384, 24576, 28672, 
+    30720, 30208, 30216, 30214,     0, 16384, 24576, 28672, 
+    30720, 30208,     0, 16384, 24576, 28672, 30720, 30208, 
+    30216,     0, 16384, 24576, 28672, 30720, 30208, 30216, 
+        0, 16384, 24576, 28672, 30720, 30208, 30216, 30218, 
+        0, 16384, 24576, 28672, 30720, 30208, 30216,     0, 
+    16384, 24576, 28672, 30720, 30208, 30224, 30220,     0, 
+    16384, 24576, 28672, 30720, 30208, 30224, 30220,     0, 
+    16384, 24576, 28672, 30720, 30208, 30224, 30225, 30222, 
+        0, 16384, 24576, 28672, 30720, 30208,     0, 16384, 
+    24576, 28672, 30720, 30208, 30224,     0, 16384, 24576, 
+    28672, 30720, 30208, 30224,     0, 16384, 24576, 28672, 
+    30720, 30208, 30224, 30226,     0, 16384, 24576, 28672, 
+    30720, 30208, 30224,     0, 16384, 24576, 28672, 30720, 
+    30208, 30224, 30228,     0, 16384, 24576, 28672, 30720, 
+    30208, 30224, 30228,     0, 16384, 24576, 28672, 30720, 
+    30208, 30224, 30232, 30230,     0, 16384, 24576, 28672, 
+    30720, 30208, 30224,     0, 16384, 24576, 28672, 30720, 
+    30208, 30240, 30232,     0, 16384, 24576, 28672, 30720, 
+    30208, 30240, 30232,     0, 16384, 24576, 28672, 30720, 
+    30208, 30240, 30232, 30234,     0, 16384, 24576, 28672, 
+    30720, 30208, 30240, 30232,     0, 16384, 24576, 28672, 
+    30720, 30208, 30240, 30241, 30236,     0, 16384, 24576, 
+    28672, 30720, 30208, 30240, 30241, 30236,     0, 16384, 
+    24576, 28672, 30720, 30208, 30240, 30241, 30236, 30238, 
+        0, 16384, 24576, 28672, 30720, 30208,     0, 16384, 
+    24576, 28672, 30720, 30208, 30240,     0, 16384, 24576, 
+    28672, 30720, 30208, 30240,     0, 16384, 24576, 28672, 
+    30720, 30208, 30240, 30242,     0, 16384, 24576, 28672, 
+    30720, 30208, 30240,     0, 16384, 24576, 28672, 30720, 
+    30208, 30240, 30244,     0, 16384, 24576, 28672, 30720, 
+    30208, 30240, 30244,     0, 16384, 24576, 28672, 30720, 
+    30208, 30240, 30248, 30246,     0, 16384, 24576, 28672, 
+    30720, 30208, 30240,     0, 16384, 24576, 28672, 30720, 
+    30208, 30240, 30248,     0, 16384, 24576, 28672, 30720, 
+    30208, 30240, 30248,     0, 16384, 24576, 28672, 30720, 
+    30208, 30240, 30248, 30250,     0, 16384, 24576, 28672, 
+    30720, 30208, 30240, 30248,     0, 16384, 24576, 28672, 
+    30720, 30208, 30240, 30256, 30252,     0, 16384, 24576, 
+    28672, 30720, 30208, 30240, 30256, 30252,     0, 16384, 
+    24576, 28672, 30720, 30208, 30240, 30256, 30257, 30254, 
+        0, 16384, 24576, 28672, 30720, 30208, 30240,     0, 
+    16384, 24576, 28672, 30720, 30208, 30272, 30256,     0, 
+    16384, 24576, 28672, 30720, 30208, 30272, 30256,     0, 
+    16384, 24576, 28672, 30720, 30208, 30272, 30256, 30258, 
+        0, 16384, 24576, 28672, 30720, 30208, 30272, 30256, 
+        0, 16384, 24576, 28672, 30720, 30208, 30272, 30256, 
+    30260,     0, 16384, 24576, 28672, 30720, 30208, 30272, 
+    30256, 30260,     0, 16384, 24576, 28672, 30720, 30208, 
+    30272, 30256, 30264, 30262,     0, 16384, 24576, 28672, 
+    30720, 30208, 30272, 30256,     0, 16384, 24576, 28672, 
+    30720, 30208, 30272, 30273, 30264,     0, 16384, 24576, 
+    28672, 30720, 30208, 30272, 30273, 30264,     0, 16384, 
+    24576, 28672, 30720, 30208, 30272, 30273, 30264, 30266, 
+        0, 16384, 24576, 28672, 30720, 30208, 30272, 30273, 
+    30264,     0, 16384, 24576, 28672, 30720, 30208, 30272, 
+    30273, 30264, 30268,     0, 16384, 24576, 28672, 30720, 
+    30208, 30272, 30273, 30275, 30268,     0, 16384, 24576, 
+    28672, 30720, 30208, 30272, 30273, 30275, 30268, 30270, 
+        0, 16384, 24576, 28672, 30720, 30208,     0, 16384, 
+    24576, 28672, 30720, 30208, 30272,     0, 16384, 24576, 
+    28672, 30720, 30208, 30272,     0, 16384, 24576, 28672, 
+    30720, 30208, 30272, 30274,     0, 16384, 24576, 28672, 
+    30720, 30208, 30272,     0, 16384, 24576, 28672, 30720, 
+    30208, 30272, 30276,     0, 16384, 24576, 28672, 30720, 
+    30208, 30272, 30276,     0, 16384, 24576, 28672, 30720, 
+    30208, 30272, 30280, 30278,     0, 16384, 24576, 28672, 
+    30720, 30208, 30272,     0, 16384, 24576, 28672, 30720, 
+    30208, 30272, 30280,     0, 16384, 24576, 28672, 30720, 
+    30208, 30272, 30280,     0, 16384, 24576, 28672, 30720, 
+    30208, 30272, 30280, 30282,     0, 16384, 24576, 28672, 
+    30720, 30208, 30272, 30280,     0, 16384, 24576, 28672, 
+    30720, 30208, 30272, 30288, 30284,     0, 16384, 24576, 
+    28672, 30720, 30208, 30272, 30288, 30284,     0, 16384, 
+    24576, 28672, 30720, 30208, 30272, 30288, 30289, 30286, 
+        0, 16384, 24576, 28672, 30720, 30208, 30272,     0, 
+    16384, 24576, 28672, 30720, 30208, 30272, 30288,     0, 
+    16384, 24576, 28672, 30720, 30208, 30272, 30288,     0, 
+    16384, 24576, 28672, 30720, 30208, 30272, 30288, 30290, 
+        0, 16384, 24576, 28672, 30720, 30208, 30272, 30288, 
+        0, 16384, 24576, 28672, 30720, 30208, 30272, 30288, 
+    30292,     0, 16384, 24576, 28672, 30720, 30208, 30272, 
+    30288, 30292,     0, 16384, 24576, 28672, 30720, 30208, 
+    30272, 30288, 30296, 30294,     0, 16384, 24576, 28672, 
+    30720, 30208, 30272, 30288,     0, 16384, 24576, 28672, 
+    30720, 30208, 30272, 30304, 30296,     0, 16384, 24576, 
+    28672, 30720, 30208, 30272, 30304, 30296,     0, 16384, 
+    24576, 28672, 30720, 30208, 30272, 30304, 30296, 30298, 
+        0, 16384, 24576, 28672, 30720, 30208, 30272, 30304, 
+    30296,     0, 16384, 24576, 28672, 30720, 30208, 30272, 
+    30304, 30305, 30300,     0, 16384, 24576, 28672, 30720, 
+    30208, 30272, 30304, 30305, 30300,     0, 16384, 24576, 
+    28672, 30720, 30208, 30272, 30304, 30305, 30300, 30302, 
+        0, 16384, 24576, 28672, 30720, 30208, 30272,     0, 
+    16384, 24576, 28672, 30720, 30208, 30336, 30304,     0, 
+    16384, 24576, 28672, 30720, 30208, 30336, 30304,     0, 
+    16384, 24576, 28672, 30720, 30208, 30336, 30304, 30306, 
+        0, 16384, 24576, 28672, 30720, 30208, 30336, 30304, 
+        0, 16384, 24576, 28672, 30720, 30208, 30336, 30304, 
+    30308,     0, 16384, 24576, 28672, 30720, 30208, 30336, 
+    30304, 30308,     0, 16384, 24576, 28672, 30720, 30208, 
+    30336, 30304, 30312, 30310,     0, 16384, 24576, 28672, 
+    30720, 30208, 30336, 30304,     0, 16384, 24576, 28672, 
+    30720, 30208, 30336, 30304, 30312,     0, 16384, 24576, 
+    28672, 30720, 30208, 30336, 30304, 30312,     0, 16384, 
+    24576, 28672, 30720, 30208, 30336, 30304, 30312, 30314, 
+        0, 16384, 24576, 28672, 30720, 30208, 30336, 30304, 
+    30312,     0, 16384, 24576, 28672, 30720, 30208, 30336, 
+    30304, 30320, 30316,     0, 16384, 24576, 28672, 30720, 
+    30208, 30336, 30304, 30320, 30316,     0, 16384, 24576, 
+    28672, 30720, 30208, 30336, 30304, 30320, 30321, 30318, 
+        0, 16384, 24576, 28672, 30720, 30208, 30336, 30304, 
+        0, 16384, 24576, 28672, 30720, 30208, 30336, 30337, 
+    30320,     0, 16384, 24576, 28672, 30720, 30208, 30336, 
+    30337, 30320,     0, 16384, 24576, 28672, 30720, 30208, 
+    30336, 30337, 30320, 30322,     0, 16384, 24576, 28672, 
+    30720, 30208, 30336, 30337, 30320,     0, 16384, 24576, 
+    28672, 30720, 30208, 30336, 30337, 30320, 30324,     0, 
+    16384, 24576, 28672, 30720, 30208, 30336, 30337, 30320, 
+    30324,     0, 16384, 24576, 28672, 30720, 30208, 30336, 
+    30337, 30320, 30328, 30326,     0, 16384, 24576, 28672, 
+    30720, 30208, 30336, 30337, 30320,     0, 16384, 24576, 
+    28672, 30720, 30208, 30336, 30337, 30320, 30328,     0, 
+    16384, 24576, 28672, 30720, 30208, 30336, 30337, 30339, 
+    30328,     0, 16384, 24576, 28672, 30720, 30208, 30336, 
+    30337, 30339, 30328, 30330,     0, 16384, 24576, 28672, 
+    30720, 30208, 30336, 30337, 30339, 30328,     0, 16384, 
+    24576, 28672, 30720, 30208, 30336, 30337, 30339, 30328, 
+    30332,     0, 16384, 24576, 28672, 30720, 30208, 30336, 
+    30337, 30339, 30328, 30332,     0, 16384, 24576, 28672, 
+    30720, 30208, 30336, 30337, 30339, 30328, 30332, 30334, 
+        0, 16384, 24576, 28672, 30720, 30208,     0, 16384, 
+    24576, 28672, 30720, 30208, 30336,     0, 16384, 24576, 
+    28672, 30720, 30208, 30336,     0, 16384, 24576, 28672, 
+    30720, 30208, 30336, 30338,     0, 16384, 24576, 28672, 
+    30720, 30208, 30336,     0, 16384, 24576, 28672, 30720, 
+    30208, 30336, 30340,     0, 16384, 24576, 28672, 30720, 
+    30208, 30336, 30340,     0, 16384, 24576, 28672, 30720, 
+    30208, 30336, 30344, 30342,     0, 16384, 24576, 28672, 
+    30720, 30208, 30336,     0, 16384, 24576, 28672, 30720, 
+    30208, 30336, 30344,     0, 16384, 24576, 28672, 30720, 
+    30208, 30336, 30344,     0, 16384, 24576, 28672, 30720, 
+    30208, 30336, 30344, 30346,     0, 16384, 24576, 28672, 
+    30720, 30208, 30336, 30344,     0, 16384, 24576, 28672, 
+    30720, 30208, 30336, 30352, 30348,     0, 16384, 24576, 
+    28672, 30720, 30208, 30336, 30352, 30348,     0, 16384, 
+    24576, 28672, 30720, 30208, 30336, 30352, 30353, 30350, 
+        0, 16384, 24576, 28672, 30720, 30208, 30336,     0, 
+    16384, 24576, 28672, 30720, 30208, 30336, 30352,     0, 
+    16384, 24576, 28672, 30720, 30208, 30336, 30352,     0, 
+    16384, 24576, 28672, 30720, 30208, 30336, 30352, 30354, 
+        0, 16384, 24576, 28672, 30720, 30208, 30336, 30352, 
+        0, 16384, 24576, 28672, 30720, 30208, 30336, 30352, 
+    30356,     0, 16384, 24576, 28672, 30720, 30208, 30336, 
+    30352, 30356,     0, 16384, 24576, 28672, 30720, 30208, 
+    30336, 30352, 30360, 30358,     0, 16384, 24576, 28672, 
+    30720, 30208, 30336, 30352,     0, 16384, 24576, 28672, 
+    30720, 30208, 30336, 30368, 30360,     0, 16384, 24576, 
+    28672, 30720, 30208, 30336, 30368, 30360,     0, 16384, 
+    24576, 28672, 30720, 30208, 30336, 30368, 30360, 30362, 
+        0, 16384, 24576, 28672, 30720, 30208, 30336, 30368, 
+    30360,     0, 16384, 24576, 28672, 30720, 30208, 30336, 
+    30368, 30369, 30364,     0, 16384, 24576, 28672, 30720, 
+    30208, 30336, 30368, 30369, 30364,     0, 16384, 24576, 
+    28672, 30720, 30208, 30336, 30368, 30369, 30364, 30366, 
+        0, 16384, 24576, 28672, 30720, 30208, 30336,     0, 
+    16384, 24576, 28672, 30720, 30208, 30336, 30368,     0, 
+    16384, 24576, 28672, 30720, 30208, 30336, 30368,     0, 
+    16384, 24576, 28672, 30720, 30208, 30336, 30368, 30370, 
+        0, 16384, 24576, 28672, 30720, 30208, 30336, 30368, 
+        0, 16384, 24576, 28672, 30720, 30208, 30336, 30368, 
+    30372,     0, 16384, 24576, 28672, 30720, 30208, 30336, 
+    30368, 30372,     0, 16384, 24576, 28672, 30720, 30208, 
+    30336, 30368, 30376, 30374,     0, 16384, 24576, 28672, 
+    30720, 30208, 30336, 30368,     0, 16384, 24576, 28672, 
+    30720, 30208, 30336, 30368, 30376,     0, 16384, 24576, 
+    28672, 30720, 30208, 30336, 30368, 30376,     0, 16384, 
+    24576, 28672, 30720, 30208, 30336, 30368, 30376, 30378, 
+        0, 16384, 24576, 28672, 30720, 30208, 30336, 30368, 
+    30376,     0, 16384, 24576, 28672, 30720, 30208, 30336, 
+    30368, 30384, 30380,     0, 16384, 24576, 28672, 30720, 
+    30208, 30336, 30368, 30384, 30380,     0, 16384, 24576, 
+    28672, 30720, 30208, 30336, 30368, 30384, 30385, 30382, 
+        0, 16384, 24576, 28672, 30720, 30208, 30336, 30368, 
+        0, 16384, 24576, 28672, 30720, 30208, 30336, 30400, 
+    30384,     0, 16384, 24576, 28672, 30720, 30208, 30336, 
+    30400, 30384,     0, 16384, 24576, 28672, 30720, 30208, 
+    30336, 30400, 30384, 30386,     0, 16384, 24576, 28672, 
+    30720, 30208, 30336, 30400, 30384,     0, 16384, 24576, 
+    28672, 30720, 30208, 30336, 30400, 30384, 30388,     0, 
+    16384, 24576, 28672, 30720, 30208, 30336, 30400, 30384, 
+    30388,     0, 16384, 24576, 28672, 30720, 30208, 30336, 
+    30400, 30384, 30392, 30390,     0, 16384, 24576, 28672, 
+    30720, 30208, 30336, 30400, 30384,     0, 16384, 24576, 
+    28672, 30720, 30208, 30336, 30400, 30401, 30392,     0, 
+    16384, 24576, 28672, 30720, 30208, 30336, 30400, 30401, 
+    30392,     0, 16384, 24576, 28672, 30720, 30208, 30336, 
+    30400, 30401, 30392, 30394,     0, 16384, 24576, 28672, 
+    30720, 30208, 30336, 30400, 30401, 30392,     0, 16384, 
+    24576, 28672, 30720, 30208, 30336, 30400, 30401, 30392, 
+    30396,     0, 16384, 24576, 28672, 30720, 30208, 30336, 
+    30400, 30401, 30403, 30396,     0, 16384, 24576, 28672, 
+    30720, 30208, 30336, 30400, 30401, 30403, 30396, 30398, 
+        0, 16384, 24576, 28672, 30720, 30208, 30336,     0, 
+    16384, 24576, 28672, 30720, 30208, 30464, 30400,     0, 
+    16384, 24576, 28672, 30720, 30208, 30464, 30400,     0, 
+    16384, 24576, 28672, 30720, 30208, 30464, 30400, 30402, 
+        0, 16384, 24576, 28672, 30720, 30208, 30464, 30400, 
+        0, 16384, 24576, 28672, 30720, 30208, 30464, 30400, 
+    30404,     0, 16384, 24576, 28672, 30720, 30208, 30464, 
+    30400, 30404,     0, 16384, 24576, 28672, 30720, 30208, 
+    30464, 30400, 30408, 30406,     0, 16384, 24576, 28672, 
+    30720, 30208, 30464, 30400,     0, 16384, 24576, 28672, 
+    30720, 30208, 30464, 30400, 30408,     0, 16384, 24576, 
+    28672, 30720, 30208, 30464, 30400, 30408,     0, 16384, 
+    24576, 28672, 30720, 30208, 30464, 30400, 30408, 30410, 
+        0, 16384, 24576, 28672, 30720, 30208, 30464, 30400, 
+    30408,     0, 16384, 24576, 28672, 30720, 30208, 30464, 
+    30400, 30416, 30412,     0, 16384, 24576, 28672, 30720, 
+    30208, 30464, 30400, 30416, 30412,     0, 16384, 24576, 
+    28672, 30720, 30208, 30464, 30400, 30416, 30417, 30414, 
+        0, 16384, 24576, 28672, 30720, 30208, 30464, 30400, 
+        0, 16384, 24576, 28672, 30720, 30208, 30464, 30400, 
+    30416,     0, 16384, 24576, 28672, 30720, 30208, 30464, 
+    30400, 30416,     0, 16384, 24576, 28672, 30720, 30208, 
+    30464, 30400, 30416, 30418,     0, 16384, 24576, 28672, 
+    30720, 30208, 30464, 30400, 30416,     0, 16384, 24576, 
+    28672, 30720, 30208, 30464, 30400, 30416, 30420,     0, 
+    16384, 24576, 28672, 30720, 30208, 30464, 30400, 30416, 
+    30420,     0, 16384, 24576, 28672, 30720, 30208, 30464, 
+    30400, 30416, 30424, 30422,     0, 16384, 24576, 28672, 
+    30720, 30208, 30464, 30400, 30416,     0, 16384, 24576, 
+    28672, 30720, 30208, 30464, 30400, 30432, 30424,     0, 
+    16384, 24576, 28672, 30720, 30208, 30464, 30400, 30432, 
+    30424,     0, 16384, 24576, 28672, 30720, 30208, 30464, 
+    30400, 30432, 30424, 30426,     0, 16384, 24576, 28672, 
+    30720, 30208, 30464, 30400, 30432, 30424,     0, 16384, 
+    24576, 28672, 30720, 30208, 30464, 30400, 30432, 30433, 
+    30428,     0, 16384, 24576, 28672, 30720, 30208, 30464, 
+    30400, 30432, 30433, 30428,     0, 16384, 24576, 28672, 
+    30720, 30208, 30464, 30400, 30432, 30433, 30428, 30430, 
+        0, 16384, 24576, 28672, 30720, 30208, 30464, 30400, 
+        0, 16384, 24576, 28672, 30720, 30208, 30464, 30465, 
+    30432,     0, 16384, 24576, 28672, 30720, 30208, 30464, 
+    30465, 30432,     0, 16384, 24576, 28672, 30720, 30208, 
+    30464, 30465, 30432, 30434,     0, 16384, 24576, 28672, 
+    30720, 30208, 30464, 30465, 30432,     0, 16384, 24576, 
+    28672, 30720, 30208, 30464, 30465, 30432, 30436,     0, 
+    16384, 24576, 28672, 30720, 30208, 30464, 30465, 30432, 
+    30436,     0, 16384, 24576, 28672, 30720, 30208, 30464, 
+    30465, 30432, 30440, 30438,     0, 16384, 24576, 28672, 
+    30720, 30208, 30464, 30465, 30432,     0, 16384, 24576, 
+    28672, 30720, 30208, 30464, 30465, 30432, 30440,     0, 
+    16384, 24576, 28672, 30720, 30208, 30464, 30465, 30432, 
+    30440,     0, 16384, 24576, 28672, 30720, 30208, 30464, 
+    30465, 30432, 30440, 30442,     0, 16384, 24576, 28672, 
+    30720, 30208, 30464, 30465, 30432, 30440,     0, 16384, 
+    24576, 28672, 30720, 30208, 30464, 30465, 30432, 30448, 
+    30444,     0, 16384, 24576, 28672, 30720, 30208, 30464, 
+    30465, 30432, 30448, 30444,     0, 16384, 24576, 28672, 
+    30720, 30208, 30464, 30465, 30432, 30448, 30449, 30446, 
+        0, 16384, 24576, 28672, 30720, 30208, 30464, 30465, 
+    30432,     0, 16384, 24576, 28672, 30720, 30208, 30464, 
+    30465, 30432, 30448,     0, 16384, 24576, 28672, 30720, 
+    30208, 30464, 30465, 30467, 30448,     0, 16384, 24576, 
+    28672, 30720, 30208, 30464, 30465, 30467, 30448, 30450, 
+        0, 16384, 24576, 28672, 30720, 30208, 30464, 30465, 
+    30467, 30448,     0, 16384, 24576, 28672, 30720, 30208, 
+    30464, 30465, 30467, 30448, 30452,     0, 16384, 24576, 
+    28672, 30720, 30208, 30464, 30465, 30467, 30448, 30452, 
+        0, 16384, 24576, 28672, 30720, 30208, 30464, 30465, 
+    30467, 30448, 30456, 30454,     0, 16384, 24576, 28672, 
+    30720, 30208, 30464, 30465, 30467, 30448,     0, 16384, 
+    24576, 28672, 30720, 30208, 30464, 30465, 30467, 30448, 
+    30456,     0, 16384, 24576, 28672, 30720, 30208, 30464, 
+    30465, 30467, 30448, 30456,     0, 16384, 24576, 28672, 
+    30720, 30208, 30464, 30465, 30467, 30448, 30456, 30458, 
+        0, 16384, 24576, 28672, 30720, 30208, 30464, 30465, 
+    30467, 30471, 30456,     0, 16384, 24576, 28672, 30720, 
+    30208, 30464, 30465, 30467, 30471, 30456, 30460,     0, 
+    16384, 24576, 28672, 30720, 30208, 30464, 30465, 30467, 
+    30471, 30456, 30460,     0, 16384, 24576, 28672, 30720, 
+    30208, 30464, 30465, 30467, 30471, 30456, 30460, 30462, 
+        0, 16384, 24576, 28672, 30720, 30208,     0, 16384, 
+    24576, 28672, 30720, 30208, 30464,     0, 16384, 24576, 
+    28672, 30720, 30721, 30464,     0, 16384, 24576, 28672, 
+    30720, 30721, 30464, 30466,     0, 16384, 24576, 28672, 
+    30720, 30721, 30464,     0, 16384, 24576, 28672, 30720, 
+    30721, 30464, 30468,     0, 16384, 24576, 28672, 30720, 
+    30721, 30464, 30468,     0, 16384, 24576, 28672, 30720, 
+    30721, 30464, 30472, 30470,     0, 16384, 24576, 28672, 
+    30720, 30721, 30464,     0, 16384, 24576, 28672, 30720, 
+    30721, 30464, 30472,     0, 16384, 24576, 28672, 30720, 
+    30721, 30464, 30472,     0, 16384, 24576, 28672, 30720, 
+    30721, 30464, 30472, 30474,     0, 16384, 24576, 28672, 
+    30720, 30721, 30464, 30472,     0, 16384, 24576, 28672, 
+    30720, 30721, 30464, 30480, 30476,     0, 16384, 24576, 
+    28672, 30720, 30721, 30464, 30480, 30476,     0, 16384, 
+    24576, 28672, 30720, 30721, 30464, 30480, 30481, 30478, 
+        0, 16384, 24576, 28672, 30720, 30721, 30464,     0, 
+    16384, 24576, 28672, 30720, 30721, 30464, 30480,     0, 
+    16384, 24576, 28672, 30720, 30721, 30464, 30480,     0, 
+    16384, 24576, 28672, 30720, 30721, 30464, 30480, 30482, 
+        0, 16384, 24576, 28672, 30720, 30721, 30464, 30480, 
+        0, 16384, 24576, 28672, 30720, 30721, 30464, 30480, 
+    30484,     0, 16384, 24576, 28672, 30720, 30721, 30464, 
+    30480, 30484,     0, 16384, 24576, 28672, 30720, 30721, 
+    30464, 30480, 30488, 30486,     0, 16384, 24576, 28672, 
+    30720, 30721, 30464, 30480,     0, 16384, 24576, 28672, 
+    30720, 30721, 30464, 30496, 30488,     0, 16384, 24576, 
+    28672, 30720, 30721, 30464, 30496, 30488,     0, 16384, 
+    24576, 28672, 30720, 30721, 30464, 30496, 30488, 30490, 
+        0, 16384, 24576, 28672, 30720, 30721, 30464, 30496, 
+    30488,     0, 16384, 24576, 28672, 30720, 30721, 30464, 
+    30496, 30497, 30492,     0, 16384, 24576, 28672, 30720, 
+    30721, 30464, 30496, 30497, 30492,     0, 16384, 24576, 
+    28672, 30720, 30721, 30464, 30496, 30497, 30492, 30494, 
+        0, 16384, 24576, 28672, 30720, 30721, 30464,     0, 
+    16384, 24576, 28672, 30720, 30721, 30464, 30496,     0, 
+    16384, 24576, 28672, 30720, 30721, 30464, 30496,     0, 
+    16384, 24576, 28672, 30720, 30721, 30464, 30496, 30498, 
+        0, 16384, 24576, 28672, 30720, 30721, 30464, 30496, 
+        0, 16384, 24576, 28672, 30720, 30721, 30464, 30496, 
+    30500,     0, 16384, 24576, 28672, 30720, 30721, 30464, 
+    30496, 30500,     0, 16384, 24576, 28672, 30720, 30721, 
+    30464, 30496, 30504, 30502,     0, 16384, 24576, 28672, 
+    30720, 30721, 30464, 30496,     0, 16384, 24576, 28672, 
+    30720, 30721, 30464, 30496, 30504,     0, 16384, 24576, 
+    28672, 30720, 30721, 30464, 30496, 30504,     0, 16384, 
+    24576, 28672, 30720, 30721, 30464, 30496, 30504, 30506, 
+        0, 16384, 24576, 28672, 30720, 30721, 30464, 30496, 
+    30504,     0, 16384, 24576, 28672, 30720, 30721, 30464, 
+    30496, 30512, 30508,     0, 16384, 24576, 28672, 30720, 
+    30721, 30464, 30496, 30512, 30508,     0, 16384, 24576, 
+    28672, 30720, 30721, 30464, 30496, 30512, 30513, 30510, 
+        0, 16384, 24576, 28672, 30720, 30721, 30464, 30496, 
+        0, 16384, 24576, 28672, 30720, 30721, 30464, 30528, 
+    30512,     0, 16384, 24576, 28672, 30720, 30721, 30464, 
+    30528, 30512,     0, 16384, 24576, 28672, 30720, 30721, 
+    30464, 30528, 30512, 30514,     0, 16384, 24576, 28672, 
+    30720, 30721, 30464, 30528, 30512,     0, 16384, 24576, 
+    28672, 30720, 30721, 30464, 30528, 30512, 30516,     0, 
+    16384, 24576, 28672, 30720, 30721, 30464, 30528, 30512, 
+    30516,     0, 16384, 24576, 28672, 30720, 30721, 30464, 
+    30528, 30512, 30520, 30518,     0, 16384, 24576, 28672, 
+    30720, 30721, 30464, 30528, 30512,     0, 16384, 24576, 
+    28672, 30720, 30721, 30464, 30528, 30529, 30520,     0, 
+    16384, 24576, 28672, 30720, 30721, 30464, 30528, 30529, 
+    30520,     0, 16384, 24576, 28672, 30720, 30721, 30464, 
+    30528, 30529, 30520, 30522,     0, 16384, 24576, 28672, 
+    30720, 30721, 30464, 30528, 30529, 30520,     0, 16384, 
+    24576, 28672, 30720, 30721, 30464, 30528, 30529, 30520, 
+    30524,     0, 16384, 24576, 28672, 30720, 30721, 30464, 
+    30528, 30529, 30531, 30524,     0, 16384, 24576, 28672, 
+    30720, 30721, 30464, 30528, 30529, 30531, 30524, 30526, 
+        0, 16384, 24576, 28672, 30720, 30721, 30464,     0, 
+    16384, 24576, 28672, 30720, 30721, 30464, 30528,     0, 
+    16384, 24576, 28672, 30720, 30721, 30464, 30528,     0, 
+    16384, 24576, 28672, 30720, 30721, 30464, 30528, 30530, 
+        0, 16384, 24576, 28672, 30720, 30721, 30464, 30528, 
+        0, 16384, 24576, 28672, 30720, 30721, 30464, 30528, 
+    30532,     0, 16384, 24576, 28672, 30720, 30721, 30464, 
+    30528, 30532,     0, 16384, 24576, 28672, 30720, 30721, 
+    30464, 30528, 30536, 30534,     0, 16384, 24576, 28672, 
+    30720, 30721, 30464, 30528,     0, 16384, 24576, 28672, 
+    30720, 30721, 30464, 30528, 30536,     0, 16384, 24576, 
+    28672, 30720, 30721, 30464, 30528, 30536,     0, 16384, 
+    24576, 28672, 30720, 30721, 30464, 30528, 30536, 30538, 
+        0, 16384, 24576, 28672, 30720, 30721, 30464, 30528, 
+    30536,     0, 16384, 24576, 28672, 30720, 30721, 30464, 
+    30528, 30544, 30540,     0, 16384, 24576, 28672, 30720, 
+    30721, 30464, 30528, 30544, 30540,     0, 16384, 24576, 
+    28672, 30720, 30721, 30464, 30528, 30544, 30545, 30542, 
+        0, 16384, 24576, 28672, 30720, 30721, 30464, 30528, 
+        0, 16384, 24576, 28672, 30720, 30721, 30464, 30528, 
+    30544,     0, 16384, 24576, 28672, 30720, 30721, 30464, 
+    30528, 30544,     0, 16384, 24576, 28672, 30720, 30721, 
+    30464, 30528, 30544, 30546,     0, 16384, 24576, 28672, 
+    30720, 30721, 30464, 30528, 30544,     0, 16384, 24576, 
+    28672, 30720, 30721, 30464, 30528, 30544, 30548,     0, 
+    16384, 24576, 28672, 30720, 30721, 30464, 30528, 30544, 
+    30548,     0, 16384, 24576, 28672, 30720, 30721, 30464, 
+    30528, 30544, 30552, 30550,     0, 16384, 24576, 28672, 
+    30720, 30721, 30464, 30528, 30544,     0, 16384, 24576, 
+    28672, 30720, 30721, 30464, 30528, 30560, 30552,     0, 
+    16384, 24576, 28672, 30720, 30721, 30464, 30528, 30560, 
+    30552,     0, 16384, 24576, 28672, 30720, 30721, 30464, 
+    30528, 30560, 30552, 30554,     0, 16384, 24576, 28672, 
+    30720, 30721, 30464, 30528, 30560, 30552,     0, 16384, 
+    24576, 28672, 30720, 30721, 30464, 30528, 30560, 30561, 
+    30556,     0, 16384, 24576, 28672, 30720, 30721, 30464, 
+    30528, 30560, 30561, 30556,     0, 16384, 24576, 28672, 
+    30720, 30721, 30464, 30528, 30560, 30561, 30556, 30558, 
+        0, 16384, 24576, 28672, 30720, 30721, 30464, 30528, 
+        0, 16384, 24576, 28672, 30720, 30721, 30464, 30592, 
+    30560,     0, 16384, 24576, 28672, 30720, 30721, 30464, 
+    30592, 30560,     0, 16384, 24576, 28672, 30720, 30721, 
+    30464, 30592, 30560, 30562,     0, 16384, 24576, 28672, 
+    30720, 30721, 30464, 30592, 30560,     0, 16384, 24576, 
+    28672, 30720, 30721, 30464, 30592, 30560, 30564,     0, 
+    16384, 24576, 28672, 30720, 30721, 30464, 30592, 30560, 
+    30564,     0, 16384, 24576, 28672, 30720, 30721, 30464, 
+    30592, 30560, 30568, 30566,     0, 16384, 24576, 28672, 
+    30720, 30721, 30464, 30592, 30560,     0, 16384, 24576, 
+    28672, 30720, 30721, 30464, 30592, 30560, 30568,     0, 
+    16384, 24576, 28672, 30720, 30721, 30464, 30592, 30560, 
+    30568,     0, 16384, 24576, 28672, 30720, 30721, 30464, 
+    30592, 30560, 30568, 30570,     0, 16384, 24576, 28672, 
+    30720, 30721, 30464, 30592, 30560, 30568,     0, 16384, 
+    24576, 28672, 30720, 30721, 30464, 30592, 30560, 30576, 
+    30572,     0, 16384, 24576, 28672, 30720, 30721, 30464, 
+    30592, 30560, 30576, 30572,     0, 16384, 24576, 28672, 
+    30720, 30721, 30464, 30592, 30560, 30576, 30577, 30574, 
+        0, 16384, 24576, 28672, 30720, 30721, 30464, 30592, 
+    30560,     0, 16384, 24576, 28672, 30720, 30721, 30464, 
+    30592, 30593, 30576,     0, 16384, 24576, 28672, 30720, 
+    30721, 30464, 30592, 30593, 30576,     0, 16384, 24576, 
+    28672, 30720, 30721, 30464, 30592, 30593, 30576, 30578, 
+        0, 16384, 24576, 28672, 30720, 30721, 30464, 30592, 
+    30593, 30576,     0, 16384, 24576, 28672, 30720, 30721, 
+    30464, 30592, 30593, 30576, 30580,     0, 16384, 24576, 
+    28672, 30720, 30721, 30464, 30592, 30593, 30576, 30580, 
+        0, 16384, 24576, 28672, 30720, 30721, 30464, 30592, 
+    30593, 30576, 30584, 30582,     0, 16384, 24576, 28672, 
+    30720, 30721, 30464, 30592, 30593, 30576,     0, 16384, 
+    24576, 28672, 30720, 30721, 30464, 30592, 30593, 30576, 
+    30584,     0, 16384, 24576, 28672, 30720, 30721, 30464, 
+    30592, 30593, 30595, 30584,     0, 16384, 24576, 28672, 
+    30720, 30721, 30464, 30592, 30593, 30595, 30584, 30586, 
+        0, 16384, 24576, 28672, 30720, 30721, 30464, 30592, 
+    30593, 30595, 30584,     0, 16384, 24576, 28672, 30720, 
+    30721, 30464, 30592, 30593, 30595, 30584, 30588,     0, 
+    16384, 24576, 28672, 30720, 30721, 30464, 30592, 30593, 
+    30595, 30584, 30588,     0, 16384, 24576, 28672, 30720, 
+    30721, 30464, 30592, 30593, 30595, 30584, 30588, 30590, 
+        0, 16384, 24576, 28672, 30720, 30721, 30464,     0, 
+    16384, 24576, 28672, 30720, 30721, 30464, 30592,     0, 
+    16384, 24576, 28672, 30720, 30721, 30464, 30592,     0, 
+    16384, 24576, 28672, 30720, 30721, 30464, 30592, 30594, 
+        0, 16384, 24576, 28672, 30720, 30721, 30723, 30592, 
+        0, 16384, 24576, 28672, 30720, 30721, 30723, 30592, 
+    30596,     0, 16384, 24576, 28672, 30720, 30721, 30723, 
+    30592, 30596,     0, 16384, 24576, 28672, 30720, 30721, 
+    30723, 30592, 30600, 30598,     0, 16384, 24576, 28672, 
+    30720, 30721, 30723, 30592,     0, 16384, 24576, 28672, 
+    30720, 30721, 30723, 30592, 30600,     0, 16384, 24576, 
+    28672, 30720, 30721, 30723, 30592, 30600,     0, 16384, 
+    24576, 28672, 30720, 30721, 30723, 30592, 30600, 30602, 
+        0, 16384, 24576, 28672, 30720, 30721, 30723, 30592, 
+    30600,     0, 16384, 24576, 28672, 30720, 30721, 30723, 
+    30592, 30608, 30604,     0, 16384, 24576, 28672, 30720, 
+    30721, 30723, 30592, 30608, 30604,     0, 16384, 24576, 
+    28672, 30720, 30721, 30723, 30592, 30608, 30609, 30606, 
+        0, 16384, 24576, 28672, 30720, 30721, 30723, 30592, 
+        0, 16384, 24576, 28672, 30720, 30721, 30723, 30592, 
+    30608,     0, 16384, 24576, 28672, 30720, 30721, 30723, 
+    30592, 30608,     0, 16384, 24576, 28672, 30720, 30721, 
+    30723, 30592, 30608, 30610,     0, 16384, 24576, 28672, 
+    30720, 30721, 30723, 30592, 30608,     0, 16384, 24576, 
+    28672, 30720, 30721, 30723, 30592, 30608, 30612,     0, 
+    16384, 24576, 28672, 30720, 30721, 30723, 30592, 30608, 
+    30612,     0, 16384, 24576, 28672, 30720, 30721, 30723, 
+    30592, 30608, 30616, 30614,     0, 16384, 24576, 28672, 
+    30720, 30721, 30723, 30592, 30608,     0, 16384, 24576, 
+    28672, 30720, 30721, 30723, 30592, 30624, 30616,     0, 
+    16384, 24576, 28672, 30720, 30721, 30723, 30592, 30624, 
+    30616,     0, 16384, 24576, 28672, 30720, 30721, 30723, 
+    30592, 30624, 30616, 30618,     0, 16384, 24576, 28672, 
+    30720, 30721, 30723, 30592, 30624, 30616,     0, 16384, 
+    24576, 28672, 30720, 30721, 30723, 30592, 30624, 30625, 
+    30620,     0, 16384, 24576, 28672, 30720, 30721, 30723, 
+    30592, 30624, 30625, 30620,     0, 16384, 24576, 28672, 
+    30720, 30721, 30723, 30592, 30624, 30625, 30620, 30622, 
+        0, 16384, 24576, 28672, 30720, 30721, 30723, 30592, 
+        0, 16384, 24576, 28672, 30720, 30721, 30723, 30592, 
+    30624,     0, 16384, 24576, 28672, 30720, 30721, 30723, 
+    30592, 30624,     0, 16384, 24576, 28672, 30720, 30721, 
+    30723, 30592, 30624, 30626,     0, 16384, 24576, 28672, 
+    30720, 30721, 30723, 30592, 30624,     0, 16384, 24576, 
+    28672, 30720, 30721, 30723, 30592, 30624, 30628,     0, 
+    16384, 24576, 28672, 30720, 30721, 30723, 30592, 30624, 
+    30628,     0, 16384, 24576, 28672, 30720, 30721, 30723, 
+    30592, 30624, 30632, 30630,     0, 16384, 24576, 28672, 
+    30720, 30721, 30723, 30592, 30624,     0, 16384, 24576, 
+    28672, 30720, 30721, 30723, 30592, 30624, 30632,     0, 
+    16384, 24576, 28672, 30720, 30721, 30723, 30592, 30624, 
+    30632,     0, 16384, 24576, 28672, 30720, 30721, 30723, 
+    30592, 30624, 30632, 30634,     0, 16384, 24576, 28672, 
+    30720, 30721, 30723, 30592, 30624, 30632,     0, 16384, 
+    24576, 28672, 30720, 30721, 30723, 30592, 30624, 30640, 
+    30636,     0, 16384, 24576, 28672, 30720, 30721, 30723, 
+    30592, 30624, 30640, 30636,     0, 16384, 24576, 28672, 
+    30720, 30721, 30723, 30592, 30624, 30640, 30641, 30638, 
+        0, 16384, 24576, 28672, 30720, 30721, 30723, 30592, 
+    30624,     0, 16384, 24576, 28672, 30720, 30721, 30723, 
+    30592, 30656, 30640,     0, 16384, 24576, 28672, 30720, 
+    30721, 30723, 30592, 30656, 30640,     0, 16384, 24576, 
+    28672, 30720, 30721, 30723, 30592, 30656, 30640, 30642, 
+        0, 16384, 24576, 28672, 30720, 30721, 30723, 30592, 
+    30656, 30640,     0, 16384, 24576, 28672, 30720, 30721, 
+    30723, 30592, 30656, 30640, 30644,     0, 16384, 24576, 
+    28672, 30720, 30721, 30723, 30592, 30656, 30640, 30644, 
+        0, 16384, 24576, 28672, 30720, 30721, 30723, 30592, 
+    30656, 30640, 30648, 30646,     0, 16384, 24576, 28672, 
+    30720, 30721, 30723, 30592, 30656, 30640,     0, 16384, 
+    24576, 28672, 30720, 30721, 30723, 30592, 30656, 30657, 
+    30648,     0, 16384, 24576, 28672, 30720, 30721, 30723, 
+    30592, 30656, 30657, 30648,     0, 16384, 24576, 28672, 
+    30720, 30721, 30723, 30592, 30656, 30657, 30648, 30650, 
+        0, 16384, 24576, 28672, 30720, 30721, 30723, 30592, 
+    30656, 30657, 30648,     0, 16384, 24576, 28672, 30720, 
+    30721, 30723, 30592, 30656, 30657, 30648, 30652,     0, 
+    16384, 24576, 28672, 30720, 30721, 30723, 30592, 30656, 
+    30657, 30659, 30652,     0, 16384, 24576, 28672, 30720, 
+    30721, 30723, 30592, 30656, 30657, 30659, 30652, 30654, 
+        0, 16384, 24576, 28672, 30720, 30721, 30723, 30592, 
+        0, 16384, 24576, 28672, 30720, 30721, 30723, 30592, 
+    30656,     0, 16384, 24576, 28672, 30720, 30721, 30723, 
+    30592, 30656,     0, 16384, 24576, 28672, 30720, 30721, 
+    30723, 30592, 30656, 30658,     0, 16384, 24576, 28672, 
+    30720, 30721, 30723, 30592, 30656,     0, 16384, 24576, 
+    28672, 30720, 30721, 30723, 30592, 30656, 30660,     0, 
+    16384, 24576, 28672, 30720, 30721, 30723, 30592, 30656, 
+    30660,     0, 16384, 24576, 28672, 30720, 30721, 30723, 
+    30592, 30656, 30664, 30662,     0, 16384, 24576, 28672, 
+    30720, 30721, 30723, 30727, 30656,     0, 16384, 24576, 
+    28672, 30720, 30721, 30723, 30727, 30656, 30664,     0, 
+    16384, 24576, 28672, 30720, 30721, 30723, 30727, 30656, 
+    30664,     0, 16384, 24576, 28672, 30720, 30721, 30723, 
+    30727, 30656, 30664, 30666,     0, 16384, 24576, 28672, 
+    30720, 30721, 30723, 30727, 30656, 30664,     0, 16384, 
+    24576, 28672, 30720, 30721, 30723, 30727, 30656, 30672, 
+    30668,     0, 16384, 24576, 28672, 30720, 30721, 30723, 
+    30727, 30656, 30672, 30668,     0, 16384, 24576, 28672, 
+    30720, 30721, 30723, 30727, 30656, 30672, 30673, 30670, 
+        0, 16384, 24576, 28672, 30720, 30721, 30723, 30727, 
+    30656,     0, 16384, 24576, 28672, 30720, 30721, 30723, 
+    30727, 30656, 30672,     0, 16384, 24576, 28672, 30720, 
+    30721, 30723, 30727, 30656, 30672,     0, 16384, 24576, 
+    28672, 30720, 30721, 30723, 30727, 30656, 30672, 30674, 
+        0, 16384, 24576, 28672, 30720, 30721, 30723, 30727, 
+    30656, 30672,     0, 16384, 24576, 28672, 30720, 30721, 
+    30723, 30727, 30656, 30672, 30676,     0, 16384, 24576, 
+    28672, 30720, 30721, 30723, 30727, 30656, 30672, 30676, 
+        0, 16384, 24576, 28672, 30720, 30721, 30723, 30727, 
+    30656, 30672, 30680, 30678,     0, 16384, 24576, 28672, 
+    30720, 30721, 30723, 30727, 30656, 30672,     0, 16384, 
+    24576, 28672, 30720, 30721, 30723, 30727, 30656, 30688, 
+    30680,     0, 16384, 24576, 28672, 30720, 30721, 30723, 
+    30727, 30656, 30688, 30680,     0, 16384, 24576, 28672, 
+    30720, 30721, 30723, 30727, 30656, 30688, 30680, 30682, 
+        0, 16384, 24576, 28672, 30720, 30721, 30723, 30727, 
+    30656, 30688, 30680,     0, 16384, 24576, 28672, 30720, 
+    30721, 30723, 30727, 30656, 30688, 30689, 30684,     0, 
+    16384, 24576, 28672, 30720, 30721, 30723, 30727, 30656, 
+    30688, 30689, 30684,     0, 16384, 24576, 28672, 30720, 
+    30721, 30723, 30727, 30656, 30688, 30689, 30684, 30686, 
+        0, 16384, 24576, 28672, 30720, 30721, 30723, 30727, 
+    30656,     0, 16384, 24576, 28672, 30720, 30721, 30723, 
+    30727, 30656, 30688,     0, 16384, 24576, 28672, 30720, 
+    30721, 30723, 30727, 30656, 30688,     0, 16384, 24576, 
+    28672, 30720, 30721, 30723, 30727, 30656, 30688, 30690, 
+        0, 16384, 24576, 28672, 30720, 30721, 30723, 30727, 
+    30656, 30688,     0, 16384, 24576, 28672, 30720, 30721, 
+    30723, 30727, 30656, 30688, 30692,     0, 16384, 24576, 
+    28672, 30720, 30721, 30723, 30727, 30656, 30688, 30692, 
+        0, 16384, 24576, 28672, 30720, 30721, 30723, 30727, 
+    30656, 30688, 30696, 30694,     0, 16384, 24576, 28672, 
+    30720, 30721, 30723, 30727, 30656, 30688,     0, 16384, 
+    24576, 28672, 30720, 30721, 30723, 30727, 30656, 30688, 
+    30696,     0, 16384, 24576, 28672, 30720, 30721, 30723, 
+    30727, 30656, 30688, 30696,     0, 16384, 24576, 28672, 
+    30720, 30721, 30723, 30727, 30656, 30688, 30696, 30698, 
+        0, 16384, 24576, 28672, 30720, 30721, 30723, 30727, 
+    30656, 30688, 30696,     0, 16384, 24576, 28672, 30720, 
+    30721, 30723, 30727, 30656, 30688, 30704, 30700,     0, 
+    16384, 24576, 28672, 30720, 30721, 30723, 30727, 30656, 
+    30688, 30704, 30700,     0, 16384, 24576, 28672, 30720, 
+    30721, 30723, 30727, 30656, 30688, 30704, 30705, 30702, 
+        0, 16384, 24576, 28672, 30720, 30721, 30723, 30727, 
+    30735, 30688,     0, 16384, 24576, 28672, 30720, 30721, 
+    30723, 30727, 30735, 30688, 30704,     0, 16384, 24576, 
+    28672, 30720, 30721, 30723, 30727, 30735, 30688, 30704, 
+        0, 16384, 24576, 28672, 30720, 30721, 30723, 30727, 
+    30735, 30688, 30704, 30706,     0, 16384, 24576, 28672, 
+    30720, 30721, 30723, 30727, 30735, 30688, 30704,     0, 
+    16384, 24576, 28672, 30720, 30721, 30723, 30727, 30735, 
+    30688, 30704, 30708,     0, 16384, 24576, 28672, 30720, 
+    30721, 30723, 30727, 30735, 30688, 30704, 30708,     0, 
+    16384, 24576, 28672, 30720, 30721, 30723, 30727, 30735, 
+    30688, 30704, 30712, 30710,     0, 16384, 24576, 28672, 
+    30720, 30721, 30723, 30727, 30735, 30688, 30704,     0, 
+    16384, 24576, 28672, 30720, 30721, 30723, 30727, 30735, 
+    30688, 30704, 30712,     0, 16384, 24576, 28672, 30720, 
+    30721, 30723, 30727, 30735, 30688, 30704, 30712,     0, 
+    16384, 24576, 28672, 30720, 30721, 30723, 30727, 30735, 
+    30688, 30704, 30712, 30714,     0, 16384, 24576, 28672, 
+    30720, 30721, 30723, 30727, 30735, 30688, 30704, 30712, 
+        0, 16384, 24576, 28672, 30720, 30721, 30723, 30727, 
+    30735, 30688, 30704, 30712, 30716,     0, 16384, 24576, 
+    28672, 30720, 30721, 30723, 30727, 30735, 30688, 30704, 
+    30712, 30716,     0, 16384, 24576, 28672, 30720, 30721, 
+    30723, 30727, 30735, 30688, 30704, 30712, 30716, 30718, 
+        0, 16384, 24576, 28672,     0, 16384, 24576, 28672, 
+    30720,     0, 16384, 24576, 28672, 30720,     0, 16384, 
+    24576, 28672, 30720, 30722,     0, 16384, 24576, 28672, 
+    30720,     0, 16384, 24576, 28672, 30720, 30724,     0, 
+    16384, 24576, 28672, 30720, 30724,     0, 16384, 24576, 
+    28672, 30720, 30728, 30726,     0, 16384, 24576, 28672, 
+    30720,     0, 16384, 24576, 28672, 30720, 30728,     0, 
+    16384, 24576, 28672, 30720, 30728,     0, 16384, 24576, 
+    28672, 30720, 30728, 30730,     0, 16384, 24576, 28672, 
+    30720, 30728,     0, 16384, 24576, 28672, 30720, 30736, 
+    30732,     0, 16384, 24576, 28672, 30720, 30736, 30732, 
+        0, 16384, 24576, 28672, 30720, 30736, 30737, 30734, 
+        0, 16384, 24576, 28672, 30720,     0, 16384, 24576, 
+    28672, 30720, 30736,     0, 16384, 24576, 28672, 30720, 
+    30736,     0, 16384, 24576, 28672, 30720, 30736, 30738, 
+        0, 16384, 24576, 28672, 30720, 30736,     0, 16384, 
+    24576, 28672, 30720, 30736, 30740,     0, 16384, 24576, 
+    28672, 30720, 30736, 30740,     0, 16384, 24576, 28672, 
+    30720, 30736, 30744, 30742,     0, 16384, 24576, 28672, 
+    30720, 30736,     0, 16384, 24576, 28672, 30720, 30752, 
+    30744,     0, 16384, 24576, 28672, 30720, 30752, 30744, 
+        0, 16384, 24576, 28672, 30720, 30752, 30744, 30746, 
+        0, 16384, 24576, 28672, 30720, 30752, 30744,     0, 
+    16384, 24576, 28672, 30720, 30752, 30753, 30748,     0, 
+    16384, 24576, 28672, 30720, 30752, 30753, 30748,     0, 
+    16384, 24576, 28672, 30720, 30752, 30753, 30748, 30750, 
+        0, 16384, 24576, 28672, 30720,     0, 16384, 24576, 
+    28672, 30720, 30752,     0, 16384, 24576, 28672, 30720, 
+    30752,     0, 16384, 24576, 28672, 30720, 30752, 30754, 
+        0, 16384, 24576, 28672, 30720, 30752,     0, 16384, 
+    24576, 28672, 30720, 30752, 30756,     0, 16384, 24576, 
+    28672, 30720, 30752, 30756,     0, 16384, 24576, 28672, 
+    30720, 30752, 30760, 30758,     0, 16384, 24576, 28672, 
+    30720, 30752,     0, 16384, 24576, 28672, 30720, 30752, 
+    30760,     0, 16384, 24576, 28672, 30720, 30752, 30760, 
+        0, 16384, 24576, 28672, 30720, 30752, 30760, 30762, 
+        0, 16384, 24576, 28672, 30720, 30752, 30760,     0, 
+    16384, 24576, 28672, 30720, 30752, 30768, 30764,     0, 
+    16384, 24576, 28672, 30720, 30752, 30768, 30764,     0, 
+    16384, 24576, 28672, 30720, 30752, 30768, 30769, 30766, 
+        0, 16384, 24576, 28672, 30720, 30752,     0, 16384, 
+    24576, 28672, 30720, 30784, 30768,     0, 16384, 24576, 
+    28672, 30720, 30784, 30768,     0, 16384, 24576, 28672, 
+    30720, 30784, 30768, 30770,     0, 16384, 24576, 28672, 
+    30720, 30784, 30768,     0, 16384, 24576, 28672, 30720, 
+    30784, 30768, 30772,     0, 16384, 24576, 28672, 30720, 
+    30784, 30768, 30772,     0, 16384, 24576, 28672, 30720, 
+    30784, 30768, 30776, 30774,     0, 16384, 24576, 28672, 
+    30720, 30784, 30768,     0, 16384, 24576, 28672, 30720, 
+    30784, 30785, 30776,     0, 16384, 24576, 28672, 30720, 
+    30784, 30785, 30776,     0, 16384, 24576, 28672, 30720, 
+    30784, 30785, 30776, 30778,     0, 16384, 24576, 28672, 
+    30720, 30784, 30785, 30776,     0, 16384, 24576, 28672, 
+    30720, 30784, 30785, 30776, 30780,     0, 16384, 24576, 
+    28672, 30720, 30784, 30785, 30787, 30780,     0, 16384, 
+    24576, 28672, 30720, 30784, 30785, 30787, 30780, 30782, 
+        0, 16384, 24576, 28672, 30720,     0, 16384, 24576, 
+    28672, 30720, 30784,     0, 16384, 24576, 28672, 30720, 
+    30784,     0, 16384, 24576, 28672, 30720, 30784, 30786, 
+        0, 16384, 24576, 28672, 30720, 30784,     0, 16384, 
+    24576, 28672, 30720, 30784, 30788,     0, 16384, 24576, 
+    28672, 30720, 30784, 30788,     0, 16384, 24576, 28672, 
+    30720, 30784, 30792, 30790,     0, 16384, 24576, 28672, 
+    30720, 30784,     0, 16384, 24576, 28672, 30720, 30784, 
+    30792,     0, 16384, 24576, 28672, 30720, 30784, 30792, 
+        0, 16384, 24576, 28672, 30720, 30784, 30792, 30794, 
+        0, 16384, 24576, 28672, 30720, 30784, 30792,     0, 
+    16384, 24576, 28672, 30720, 30784, 30800, 30796,     0, 
+    16384, 24576, 28672, 30720, 30784, 30800, 30796,     0, 
+    16384, 24576, 28672, 30720, 30784, 30800, 30801, 30798, 
+        0, 16384, 24576, 28672, 30720, 30784,     0, 16384, 
+    24576, 28672, 30720, 30784, 30800,     0, 16384, 24576, 
+    28672, 30720, 30784, 30800,     0, 16384, 24576, 28672, 
+    30720, 30784, 30800, 30802,     0, 16384, 24576, 28672, 
+    30720, 30784, 30800,     0, 16384, 24576, 28672, 30720, 
+    30784, 30800, 30804,     0, 16384, 24576, 28672, 30720, 
+    30784, 30800, 30804,     0, 16384, 24576, 28672, 30720, 
+    30784, 30800, 30808, 30806,     0, 16384, 24576, 28672, 
+    30720, 30784, 30800,     0, 16384, 24576, 28672, 30720, 
+    30784, 30816, 30808,     0, 16384, 24576, 28672, 30720, 
+    30784, 30816, 30808,     0, 16384, 24576, 28672, 30720, 
+    30784, 30816, 30808, 30810,     0, 16384, 24576, 28672, 
+    30720, 30784, 30816, 30808,     0, 16384, 24576, 28672, 
+    30720, 30784, 30816, 30817, 30812,     0, 16384, 24576, 
+    28672, 30720, 30784, 30816, 30817, 30812,     0, 16384, 
+    24576, 28672, 30720, 30784, 30816, 30817, 30812, 30814, 
+        0, 16384, 24576, 28672, 30720, 30784,     0, 16384, 
+    24576, 28672, 30720, 30848, 30816,     0, 16384, 24576, 
+    28672, 30720, 30848, 30816,     0, 16384, 24576, 28672, 
+    30720, 30848, 30816, 30818,     0, 16384, 24576, 28672, 
+    30720, 30848, 30816,     0, 16384, 24576, 28672, 30720, 
+    30848, 30816, 30820,     0, 16384, 24576, 28672, 30720, 
+    30848, 30816, 30820,     0, 16384, 24576, 28672, 30720, 
+    30848, 30816, 30824, 30822,     0, 16384, 24576, 28672, 
+    30720, 30848, 30816,     0, 16384, 24576, 28672, 30720, 
+    30848, 30816, 30824,     0, 16384, 24576, 28672, 30720, 
+    30848, 30816, 30824,     0, 16384, 24576, 28672, 30720, 
+    30848, 30816, 30824, 30826,     0, 16384, 24576, 28672, 
+    30720, 30848, 30816, 30824,     0, 16384, 24576, 28672, 
+    30720, 30848, 30816, 30832, 30828,     0, 16384, 24576, 
+    28672, 30720, 30848, 30816, 30832, 30828,     0, 16384, 
+    24576, 28672, 30720, 30848, 30816, 30832, 30833, 30830, 
+        0, 16384, 24576, 28672, 30720, 30848, 30816,     0, 
+    16384, 24576, 28672, 30720, 30848, 30849, 30832,     0, 
+    16384, 24576, 28672, 30720, 30848, 30849, 30832,     0, 
+    16384, 24576, 28672, 30720, 30848, 30849, 30832, 30834, 
+        0, 16384, 24576, 28672, 30720, 30848, 30849, 30832, 
+        0, 16384, 24576, 28672, 30720, 30848, 30849, 30832, 
+    30836,     0, 16384, 24576, 28672, 30720, 30848, 30849, 
+    30832, 30836,     0, 16384, 24576, 28672, 30720, 30848, 
+    30849, 30832, 30840, 30838,     0, 16384, 24576, 28672, 
+    30720, 30848, 30849, 30832,     0, 16384, 24576, 28672, 
+    30720, 30848, 30849, 30832, 30840,     0, 16384, 24576, 
+    28672, 30720, 30848, 30849, 30851, 30840,     0, 16384, 
+    24576, 28672, 30720, 30848, 30849, 30851, 30840, 30842, 
+        0, 16384, 24576, 28672, 30720, 30848, 30849, 30851, 
+    30840,     0, 16384, 24576, 28672, 30720, 30848, 30849, 
+    30851, 30840, 30844,     0, 16384, 24576, 28672, 30720, 
+    30848, 30849, 30851, 30840, 30844,     0, 16384, 24576, 
+    28672, 30720, 30848, 30849, 30851, 30840, 30844, 30846, 
+        0, 16384, 24576, 28672, 30720,     0, 16384, 24576, 
+    28672, 30720, 30848,     0, 16384, 24576, 28672, 30720, 
+    30848,     0, 16384, 24576, 28672, 30720, 30848, 30850, 
+        0, 16384, 24576, 28672, 30720, 30848,     0, 16384, 
+    24576, 28672, 30720, 30848, 30852,     0, 16384, 24576, 
+    28672, 30720, 30848, 30852,     0, 16384, 24576, 28672, 
+    30720, 30848, 30856, 30854,     0, 16384, 24576, 28672, 
+    30720, 30848,     0, 16384, 24576, 28672, 30720, 30848, 
+    30856,     0, 16384, 24576, 28672, 30720, 30848, 30856, 
+        0, 16384, 24576, 28672, 30720, 30848, 30856, 30858, 
+        0, 16384, 24576, 28672, 30720, 30848, 30856,     0, 
+    16384, 24576, 28672, 30720, 30848, 30864, 30860,     0, 
+    16384, 24576, 28672, 30720, 30848, 30864, 30860,     0, 
+    16384, 24576, 28672, 30720, 30848, 30864, 30865, 30862, 
+        0, 16384, 24576, 28672, 30720, 30848,     0, 16384, 
+    24576, 28672, 30720, 30848, 30864,     0, 16384, 24576, 
+    28672, 30720, 30848, 30864,     0, 16384, 24576, 28672, 
+    30720, 30848, 30864, 30866,     0, 16384, 24576, 28672, 
+    30720, 30848, 30864,     0, 16384, 24576, 28672, 30720, 
+    30848, 30864, 30868,     0, 16384, 24576, 28672, 30720, 
+    30848, 30864, 30868,     0, 16384, 24576, 28672, 30720, 
+    30848, 30864, 30872, 30870,     0, 16384, 24576, 28672, 
+    30720, 30848, 30864,     0, 16384, 24576, 28672, 30720, 
+    30848, 30880, 30872,     0, 16384, 24576, 28672, 30720, 
+    30848, 30880, 30872,     0, 16384, 24576, 28672, 30720, 
+    30848, 30880, 30872, 30874,     0, 16384, 24576, 28672, 
+    30720, 30848, 30880, 30872,     0, 16384, 24576, 28672, 
+    30720, 30848, 30880, 30881, 30876,     0, 16384, 24576, 
+    28672, 30720, 30848, 30880, 30881, 30876,     0, 16384, 
+    24576, 28672, 30720, 30848, 30880, 30881, 30876, 30878, 
+        0, 16384, 24576, 28672, 30720, 30848,     0, 16384, 
+    24576, 28672, 30720, 30848, 30880,     0, 16384, 24576, 
+    28672, 30720, 30848, 30880,     0, 16384, 24576, 28672, 
+    30720, 30848, 30880, 30882,     0, 16384, 24576, 28672, 
+    30720, 30848, 30880,     0, 16384, 24576, 28672, 30720, 
+    30848, 30880, 30884,     0, 16384, 24576, 28672, 30720, 
+    30848, 30880, 30884,     0, 16384, 24576, 28672, 30720, 
+    30848, 30880, 30888, 30886,     0, 16384, 24576, 28672, 
+    30720, 30848, 30880,     0, 16384, 24576, 28672, 30720, 
+    30848, 30880, 30888,     0, 16384, 24576, 28672, 30720, 
+    30848, 30880, 30888,     0, 16384, 24576, 28672, 30720, 
+    30848, 30880, 30888, 30890,     0, 16384, 24576, 28672, 
+    30720, 30848, 30880, 30888,     0, 16384, 24576, 28672, 
+    30720, 30848, 30880, 30896, 30892,     0, 16384, 24576, 
+    28672, 30720, 30848, 30880, 30896, 30892,     0, 16384, 
+    24576, 28672, 30720, 30848, 30880, 30896, 30897, 30894, 
+        0, 16384, 24576, 28672, 30720, 30848, 30880,     0, 
+    16384, 24576, 28672, 30720, 30848, 30912, 30896,     0, 
+    16384, 24576, 28672, 30720, 30848, 30912, 30896,     0, 
+    16384, 24576, 28672, 30720, 30848, 30912, 30896, 30898, 
+        0, 16384, 24576, 28672, 30720, 30848, 30912, 30896, 
+        0, 16384, 24576, 28672, 30720, 30848, 30912, 30896, 
+    30900,     0, 16384, 24576, 28672, 30720, 30848, 30912, 
+    30896, 30900,     0, 16384, 24576, 28672, 30720, 30848, 
+    30912, 30896, 30904, 30902,     0, 16384, 24576, 28672, 
+    30720, 30848, 30912, 30896,     0, 16384, 24576, 28672, 
+    30720, 30848, 30912, 30913, 30904,     0, 16384, 24576, 
+    28672, 30720, 30848, 30912, 30913, 30904,     0, 16384, 
+    24576, 28672, 30720, 30848, 30912, 30913, 30904, 30906, 
+        0, 16384, 24576, 28672, 30720, 30848, 30912, 30913, 
+    30904,     0, 16384, 24576, 28672, 30720, 30848, 30912, 
+    30913, 30904, 30908,     0, 16384, 24576, 28672, 30720, 
+    30848, 30912, 30913, 30915, 30908,     0, 16384, 24576, 
+    28672, 30720, 30848, 30912, 30913, 30915, 30908, 30910, 
+        0, 16384, 24576, 28672, 30720, 30848,     0, 16384, 
+    24576, 28672, 30720, 30976, 30912,     0, 16384, 24576, 
+    28672, 30720, 30976, 30912,     0, 16384, 24576, 28672, 
+    30720, 30976, 30912, 30914,     0, 16384, 24576, 28672, 
+    30720, 30976, 30912,     0, 16384, 24576, 28672, 30720, 
+    30976, 30912, 30916,     0, 16384, 24576, 28672, 30720, 
+    30976, 30912, 30916,     0, 16384, 24576, 28672, 30720, 
+    30976, 30912, 30920, 30918,     0, 16384, 24576, 28672, 
+    30720, 30976, 30912,     0, 16384, 24576, 28672, 30720, 
+    30976, 30912, 30920,     0, 16384, 24576, 28672, 30720, 
+    30976, 30912, 30920,     0, 16384, 24576, 28672, 30720, 
+    30976, 30912, 30920, 30922,     0, 16384, 24576, 28672, 
+    30720, 30976, 30912, 30920,     0, 16384, 24576, 28672, 
+    30720, 30976, 30912, 30928, 30924,     0, 16384, 24576, 
+    28672, 30720, 30976, 30912, 30928, 30924,     0, 16384, 
+    24576, 28672, 30720, 30976, 30912, 30928, 30929, 30926, 
+        0, 16384, 24576, 28672, 30720, 30976, 30912,     0, 
+    16384, 24576, 28672, 30720, 30976, 30912, 30928,     0, 
+    16384, 24576, 28672, 30720, 30976, 30912, 30928,     0, 
+    16384, 24576, 28672, 30720, 30976, 30912, 30928, 30930, 
+        0, 16384, 24576, 28672, 30720, 30976, 30912, 30928, 
+        0, 16384, 24576, 28672, 30720, 30976, 30912, 30928, 
+    30932,     0, 16384, 24576, 28672, 30720, 30976, 30912, 
+    30928, 30932,     0, 16384, 24576, 28672, 30720, 30976, 
+    30912, 30928, 30936, 30934,     0, 16384, 24576, 28672, 
+    30720, 30976, 30912, 30928,     0, 16384, 24576, 28672, 
+    30720, 30976, 30912, 30944, 30936,     0, 16384, 24576, 
+    28672, 30720, 30976, 30912, 30944, 30936,     0, 16384, 
+    24576, 28672, 30720, 30976, 30912, 30944, 30936, 30938, 
+        0, 16384, 24576, 28672, 30720, 30976, 30912, 30944, 
+    30936,     0, 16384, 24576, 28672, 30720, 30976, 30912, 
+    30944, 30945, 30940,     0, 16384, 24576, 28672, 30720, 
+    30976, 30912, 30944, 30945, 30940,     0, 16384, 24576, 
+    28672, 30720, 30976, 30912, 30944, 30945, 30940, 30942, 
+        0, 16384, 24576, 28672, 30720, 30976, 30912,     0, 
+    16384, 24576, 28672, 30720, 30976, 30977, 30944,     0, 
+    16384, 24576, 28672, 30720, 30976, 30977, 30944,     0, 
+    16384, 24576, 28672, 30720, 30976, 30977, 30944, 30946, 
+        0, 16384, 24576, 28672, 30720, 30976, 30977, 30944, 
+        0, 16384, 24576, 28672, 30720, 30976, 30977, 30944, 
+    30948,     0, 16384, 24576, 28672, 30720, 30976, 30977, 
+    30944, 30948,     0, 16384, 24576, 28672, 30720, 30976, 
+    30977, 30944, 30952, 30950,     0, 16384, 24576, 28672, 
+    30720, 30976, 30977, 30944,     0, 16384, 24576, 28672, 
+    30720, 30976, 30977, 30944, 30952,     0, 16384, 24576, 
+    28672, 30720, 30976, 30977, 30944, 30952,     0, 16384, 
+    24576, 28672, 30720, 30976, 30977, 30944, 30952, 30954, 
+        0, 16384, 24576, 28672, 30720, 30976, 30977, 30944, 
+    30952,     0, 16384, 24576, 28672, 30720, 30976, 30977, 
+    30944, 30960, 30956,     0, 16384, 24576, 28672, 30720, 
+    30976, 30977, 30944, 30960, 30956,     0, 16384, 24576, 
+    28672, 30720, 30976, 30977, 30944, 30960, 30961, 30958, 
+        0, 16384, 24576, 28672, 30720, 30976, 30977, 30944, 
+        0, 16384, 24576, 28672, 30720, 30976, 30977, 30944, 
+    30960,     0, 16384, 24576, 28672, 30720, 30976, 30977, 
+    30979, 30960,     0, 16384, 24576, 28672, 30720, 30976, 
+    30977, 30979, 30960, 30962,     0, 16384, 24576, 28672, 
+    30720, 30976, 30977, 30979, 30960,     0, 16384, 24576, 
+    28672, 30720, 30976, 30977, 30979, 30960, 30964,     0, 
+    16384, 24576, 28672, 30720, 30976, 30977, 30979, 30960, 
+    30964,     0, 16384, 24576, 28672, 30720, 30976, 30977, 
+    30979, 30960, 30968, 30966,     0, 16384, 24576, 28672, 
+    30720, 30976, 30977, 30979, 30960,     0, 16384, 24576, 
+    28672, 30720, 30976, 30977, 30979, 30960, 30968,     0, 
+    16384, 24576, 28672, 30720, 30976, 30977, 30979, 30960, 
+    30968,     0, 16384, 24576, 28672, 30720, 30976, 30977, 
+    30979, 30960, 30968, 30970,     0, 16384, 24576, 28672, 
+    30720, 30976, 30977, 30979, 30983, 30968,     0, 16384, 
+    24576, 28672, 30720, 30976, 30977, 30979, 30983, 30968, 
+    30972,     0, 16384, 24576, 28672, 30720, 30976, 30977, 
+    30979, 30983, 30968, 30972,     0, 16384, 24576, 28672, 
+    30720, 30976, 30977, 30979, 30983, 30968, 30972, 30974, 
+        0, 16384, 24576, 28672, 30720,     0, 16384, 24576, 
+    28672, 30720, 30976,     0, 16384, 24576, 28672, 30720, 
+    30976,     0, 16384, 24576, 28672, 30720, 30976, 30978, 
+        0, 16384, 24576, 28672, 30720, 30976,     0, 16384, 
+    24576, 28672, 30720, 30976, 30980,     0, 16384, 24576, 
+    28672, 30720, 30976, 30980,     0, 16384, 24576, 28672, 
+    30720, 30976, 30984, 30982,     0, 16384, 24576, 28672, 
+    30720, 30976,     0, 16384, 24576, 28672, 30720, 30976, 
+    30984,     0, 16384, 24576, 28672, 30720, 30976, 30984, 
+        0, 16384, 24576, 28672, 30720, 30976, 30984, 30986, 
+        0, 16384, 24576, 28672, 30720, 30976, 30984,     0, 
+    16384, 24576, 28672, 30720, 30976, 30992, 30988,     0, 
+    16384, 24576, 28672, 30720, 30976, 30992, 30988,     0, 
+    16384, 24576, 28672, 30720, 30976, 30992, 30993, 30990, 
+        0, 16384, 24576, 28672, 30720, 30976,     0, 16384, 
+    24576, 28672, 30720, 30976, 30992,     0, 16384, 24576, 
+    28672, 30720, 30976, 30992,     0, 16384, 24576, 28672, 
+    30720, 30976, 30992, 30994,     0, 16384, 24576, 28672, 
+    30720, 30976, 30992,     0, 16384, 24576, 28672, 30720, 
+    30976, 30992, 30996,     0, 16384, 24576, 28672, 30720, 
+    30976, 30992, 30996,     0, 16384, 24576, 28672, 30720, 
+    30976, 30992, 31000, 30998,     0, 16384, 24576, 28672, 
+    30720, 30976, 30992,     0, 16384, 24576, 28672, 30720, 
+    30976, 31008, 31000,     0, 16384, 24576, 28672, 30720, 
+    30976, 31008, 31000,     0, 16384, 24576, 28672, 30720, 
+    30976, 31008, 31000, 31002,     0, 16384, 24576, 28672, 
+    30720, 30976, 31008, 31000,     0, 16384, 24576, 28672, 
+    30720, 30976, 31008, 31009, 31004,     0, 16384, 24576, 
+    28672, 30720, 30976, 31008, 31009, 31004,     0, 16384, 
+    24576, 28672, 30720, 30976, 31008, 31009, 31004, 31006, 
+        0, 16384, 24576, 28672, 30720, 30976,     0, 16384, 
+    24576, 28672, 30720, 30976, 31008,     0, 16384, 24576, 
+    28672, 30720, 30976, 31008,     0, 16384, 24576, 28672, 
+    30720, 30976, 31008, 31010,     0, 16384, 24576, 28672, 
+    30720, 30976, 31008,     0, 16384, 24576, 28672, 30720, 
+    30976, 31008, 31012,     0, 16384, 24576, 28672, 30720, 
+    30976, 31008, 31012,     0, 16384, 24576, 28672, 30720, 
+    30976, 31008, 31016, 31014,     0, 16384, 24576, 28672, 
+    30720, 30976, 31008,     0, 16384, 24576, 28672, 30720, 
+    30976, 31008, 31016,     0, 16384, 24576, 28672, 30720, 
+    30976, 31008, 31016,     0, 16384, 24576, 28672, 30720, 
+    30976, 31008, 31016, 31018,     0, 16384, 24576, 28672, 
+    30720, 30976, 31008, 31016,     0, 16384, 24576, 28672, 
+    30720, 30976, 31008, 31024, 31020,     0, 16384, 24576, 
+    28672, 30720, 30976, 31008, 31024, 31020,     0, 16384, 
+    24576, 28672, 30720, 30976, 31008, 31024, 31025, 31022, 
+        0, 16384, 24576, 28672, 30720, 30976, 31008,     0, 
+    16384, 24576, 28672, 30720, 30976, 31040, 31024,     0, 
+    16384, 24576, 28672, 30720, 30976, 31040, 31024,     0, 
+    16384, 24576, 28672, 30720, 30976, 31040, 31024, 31026, 
+        0, 16384, 24576, 28672, 30720, 30976, 31040, 31024, 
+        0, 16384, 24576, 28672, 30720, 30976, 31040, 31024, 
+    31028,     0, 16384, 24576, 28672, 30720, 30976, 31040, 
+    31024, 31028,     0, 16384, 24576, 28672, 30720, 30976, 
+    31040, 31024, 31032, 31030,     0, 16384, 24576, 28672, 
+    30720, 30976, 31040, 31024,     0, 16384, 24576, 28672, 
+    30720, 30976, 31040, 31041, 31032,     0, 16384, 24576, 
+    28672, 30720, 30976, 31040, 31041, 31032,     0, 16384, 
+    24576, 28672, 30720, 30976, 31040, 31041, 31032, 31034, 
+        0, 16384, 24576, 28672, 30720, 30976, 31040, 31041, 
+    31032,     0, 16384, 24576, 28672, 30720, 30976, 31040, 
+    31041, 31032, 31036,     0, 16384, 24576, 28672, 30720, 
+    30976, 31040, 31041, 31043, 31036,     0, 16384, 24576, 
+    28672, 30720, 30976, 31040, 31041, 31043, 31036, 31038, 
+        0, 16384, 24576, 28672, 30720, 30976,     0, 16384, 
+    24576, 28672, 30720, 30976, 31040,     0, 16384, 24576, 
+    28672, 30720, 30976, 31040,     0, 16384, 24576, 28672, 
+    30720, 30976, 31040, 31042,     0, 16384, 24576, 28672, 
+    30720, 30976, 31040,     0, 16384, 24576, 28672, 30720, 
+    30976, 31040, 31044,     0, 16384, 24576, 28672, 30720, 
+    30976, 31040, 31044,     0, 16384, 24576, 28672, 30720, 
+    30976, 31040, 31048, 31046,     0, 16384, 24576, 28672, 
+    30720, 30976, 31040,     0, 16384, 24576, 28672, 30720, 
+    30976, 31040, 31048,     0, 16384, 24576, 28672, 30720, 
+    30976, 31040, 31048,     0, 16384, 24576, 28672, 30720, 
+    30976, 31040, 31048, 31050,     0, 16384, 24576, 28672, 
+    30720, 30976, 31040, 31048,     0, 16384, 24576, 28672, 
+    30720, 30976, 31040, 31056, 31052,     0, 16384, 24576, 
+    28672, 30720, 30976, 31040, 31056, 31052,     0, 16384, 
+    24576, 28672, 30720, 30976, 31040, 31056, 31057, 31054, 
+        0, 16384, 24576, 28672, 30720, 30976, 31040,     0, 
+    16384, 24576, 28672, 30720, 30976, 31040, 31056,     0, 
+    16384, 24576, 28672, 30720, 30976, 31040, 31056,     0, 
+    16384, 24576, 28672, 30720, 30976, 31040, 31056, 31058, 
+        0, 16384, 24576, 28672, 30720, 30976, 31040, 31056, 
+        0, 16384, 24576, 28672, 30720, 30976, 31040, 31056, 
+    31060,     0, 16384, 24576, 28672, 30720, 30976, 31040, 
+    31056, 31060,     0, 16384, 24576, 28672, 30720, 30976, 
+    31040, 31056, 31064, 31062,     0, 16384, 24576, 28672, 
+    30720, 30976, 31040, 31056,     0, 16384, 24576, 28672, 
+    30720, 30976, 31040, 31072, 31064,     0, 16384, 24576, 
+    28672, 30720, 30976, 31040, 31072, 31064,     0, 16384, 
+    24576, 28672, 30720, 30976, 31040, 31072, 31064, 31066, 
+        0, 16384, 24576, 28672, 30720, 30976, 31040, 31072, 
+    31064,     0, 16384, 24576, 28672, 30720, 30976, 31040, 
+    31072, 31073, 31068,     0, 16384, 24576, 28672, 30720, 
+    30976, 31040, 31072, 31073, 31068,     0, 16384, 24576, 
+    28672, 30720, 30976, 31040, 31072, 31073, 31068, 31070, 
+        0, 16384, 24576, 28672, 30720, 30976, 31040,     0, 
+    16384, 24576, 28672, 30720, 30976, 31104, 31072,     0, 
+    16384, 24576, 28672, 30720, 30976, 31104, 31072,     0, 
+    16384, 24576, 28672, 30720, 30976, 31104, 31072, 31074, 
+        0, 16384, 24576, 28672, 30720, 30976, 31104, 31072, 
+        0, 16384, 24576, 28672, 30720, 30976, 31104, 31072, 
+    31076,     0, 16384, 24576, 28672, 30720, 30976, 31104, 
+    31072, 31076,     0, 16384, 24576, 28672, 30720, 30976, 
+    31104, 31072, 31080, 31078,     0, 16384, 24576, 28672, 
+    30720, 30976, 31104, 31072,     0, 16384, 24576, 28672, 
+    30720, 30976, 31104, 31072, 31080,     0, 16384, 24576, 
+    28672, 30720, 30976, 31104, 31072, 31080,     0, 16384, 
+    24576, 28672, 30720, 30976, 31104, 31072, 31080, 31082, 
+        0, 16384, 24576, 28672, 30720, 30976, 31104, 31072, 
+    31080,     0, 16384, 24576, 28672, 30720, 30976, 31104, 
+    31072, 31088, 31084,     0, 16384, 24576, 28672, 30720, 
+    30976, 31104, 31072, 31088, 31084,     0, 16384, 24576, 
+    28672, 30720, 30976, 31104, 31072, 31088, 31089, 31086, 
+        0, 16384, 24576, 28672, 30720, 30976, 31104, 31072, 
+        0, 16384, 24576, 28672, 30720, 30976, 31104, 31105, 
+    31088,     0, 16384, 24576, 28672, 30720, 30976, 31104, 
+    31105, 31088,     0, 16384, 24576, 28672, 30720, 30976, 
+    31104, 31105, 31088, 31090,     0, 16384, 24576, 28672, 
+    30720, 30976, 31104, 31105, 31088,     0, 16384, 24576, 
+    28672, 30720, 30976, 31104, 31105, 31088, 31092,     0, 
+    16384, 24576, 28672, 30720, 30976, 31104, 31105, 31088, 
+    31092,     0, 16384, 24576, 28672, 30720, 30976, 31104, 
+    31105, 31088, 31096, 31094,     0, 16384, 24576, 28672, 
+    30720, 30976, 31104, 31105, 31088,     0, 16384, 24576, 
+    28672, 30720, 30976, 31104, 31105, 31088, 31096,     0, 
+    16384, 24576, 28672, 30720, 30976, 31104, 31105, 31107, 
+    31096,     0, 16384, 24576, 28672, 30720, 30976, 31104, 
+    31105, 31107, 31096, 31098,     0, 16384, 24576, 28672, 
+    30720, 30976, 31104, 31105, 31107, 31096,     0, 16384, 
+    24576, 28672, 30720, 30976, 31104, 31105, 31107, 31096, 
+    31100,     0, 16384, 24576, 28672, 30720, 30976, 31104, 
+    31105, 31107, 31096, 31100,     0, 16384, 24576, 28672, 
+    30720, 30976, 31104, 31105, 31107, 31096, 31100, 31102, 
+        0, 16384, 24576, 28672, 30720, 30976,     0, 16384, 
+    24576, 28672, 30720, 31232, 31104,     0, 16384, 24576, 
+    28672, 30720, 31232, 31104,     0, 16384, 24576, 28672, 
+    30720, 31232, 31104, 31106,     0, 16384, 24576, 28672, 
+    30720, 31232, 31104,     0, 16384, 24576, 28672, 30720, 
+    31232, 31104, 31108,     0, 16384, 24576, 28672, 30720, 
+    31232, 31104, 31108,     0, 16384, 24576, 28672, 30720, 
+    31232, 31104, 31112, 31110,     0, 16384, 24576, 28672, 
+    30720, 31232, 31104,     0, 16384, 24576, 28672, 30720, 
+    31232, 31104, 31112,     0, 16384, 24576, 28672, 30720, 
+    31232, 31104, 31112,     0, 16384, 24576, 28672, 30720, 
+    31232, 31104, 31112, 31114,     0, 16384, 24576, 28672, 
+    30720, 31232, 31104, 31112,     0, 16384, 24576, 28672, 
+    30720, 31232, 31104, 31120, 31116,     0, 16384, 24576, 
+    28672, 30720, 31232, 31104, 31120, 31116,     0, 16384, 
+    24576, 28672, 30720, 31232, 31104, 31120, 31121, 31118, 
+        0, 16384, 24576, 28672, 30720, 31232, 31104,     0, 
+    16384, 24576, 28672, 30720, 31232, 31104, 31120,     0, 
+    16384, 24576, 28672, 30720, 31232, 31104, 31120,     0, 
+    16384, 24576, 28672, 30720, 31232, 31104, 31120, 31122, 
+        0, 16384, 24576, 28672, 30720, 31232, 31104, 31120, 
+        0, 16384, 24576, 28672, 30720, 31232, 31104, 31120, 
+    31124,     0, 16384, 24576, 28672, 30720, 31232, 31104, 
+    31120, 31124,     0, 16384, 24576, 28672, 30720, 31232, 
+    31104, 31120, 31128, 31126,     0, 16384, 24576, 28672, 
+    30720, 31232, 31104, 31120,     0, 16384, 24576, 28672, 
+    30720, 31232, 31104, 31136, 31128,     0, 16384, 24576, 
+    28672, 30720, 31232, 31104, 31136, 31128,     0, 16384, 
+    24576, 28672, 30720, 31232, 31104, 31136, 31128, 31130, 
+        0, 16384, 24576, 28672, 30720, 31232, 31104, 31136, 
+    31128,     0, 16384, 24576, 28672, 30720, 31232, 31104, 
+    31136, 31137, 31132,     0, 16384, 24576, 28672, 30720, 
+    31232, 31104, 31136, 31137, 31132,     0, 16384, 24576, 
+    28672, 30720, 31232, 31104, 31136, 31137, 31132, 31134, 
+        0, 16384, 24576, 28672, 30720, 31232, 31104,     0, 
+    16384, 24576, 28672, 30720, 31232, 31104, 31136,     0, 
+    16384, 24576, 28672, 30720, 31232, 31104, 31136,     0, 
+    16384, 24576, 28672, 30720, 31232, 31104, 31136, 31138, 
+        0, 16384, 24576, 28672, 30720, 31232, 31104, 31136, 
+        0, 16384, 24576, 28672, 30720, 31232, 31104, 31136, 
+    31140,     0, 16384, 24576, 28672, 30720, 31232, 31104, 
+    31136, 31140,     0, 16384, 24576, 28672, 30720, 31232, 
+    31104, 31136, 31144, 31142,     0, 16384, 24576, 28672, 
+    30720, 31232, 31104, 31136,     0, 16384, 24576, 28672, 
+    30720, 31232, 31104, 31136, 31144,     0, 16384, 24576, 
+    28672, 30720, 31232, 31104, 31136, 31144,     0, 16384, 
+    24576, 28672, 30720, 31232, 31104, 31136, 31144, 31146, 
+        0, 16384, 24576, 28672, 30720, 31232, 31104, 31136, 
+    31144,     0, 16384, 24576, 28672, 30720, 31232, 31104, 
+    31136, 31152, 31148,     0, 16384, 24576, 28672, 30720, 
+    31232, 31104, 31136, 31152, 31148,     0, 16384, 24576, 
+    28672, 30720, 31232, 31104, 31136, 31152, 31153, 31150, 
+        0, 16384, 24576, 28672, 30720, 31232, 31104, 31136, 
+        0, 16384, 24576, 28672, 30720, 31232, 31104, 31168, 
+    31152,     0, 16384, 24576, 28672, 30720, 31232, 31104, 
+    31168, 31152,     0, 16384, 24576, 28672, 30720, 31232, 
+    31104, 31168, 31152, 31154,     0, 16384, 24576, 28672, 
+    30720, 31232, 31104, 31168, 31152,     0, 16384, 24576, 
+    28672, 30720, 31232, 31104, 31168, 31152, 31156,     0, 
+    16384, 24576, 28672, 30720, 31232, 31104, 31168, 31152, 
+    31156,     0, 16384, 24576, 28672, 30720, 31232, 31104, 
+    31168, 31152, 31160, 31158,     0, 16384, 24576, 28672, 
+    30720, 31232, 31104, 31168, 31152,     0, 16384, 24576, 
+    28672, 30720, 31232, 31104, 31168, 31169, 31160,     0, 
+    16384, 24576, 28672, 30720, 31232, 31104, 31168, 31169, 
+    31160,     0, 16384, 24576, 28672, 30720, 31232, 31104, 
+    31168, 31169, 31160, 31162,     0, 16384, 24576, 28672, 
+    30720, 31232, 31104, 31168, 31169, 31160,     0, 16384, 
+    24576, 28672, 30720, 31232, 31104, 31168, 31169, 31160, 
+    31164,     0, 16384, 24576, 28672, 30720, 31232, 31104, 
+    31168, 31169, 31171, 31164,     0, 16384, 24576, 28672, 
+    30720, 31232, 31104, 31168, 31169, 31171, 31164, 31166, 
+        0, 16384, 24576, 28672, 30720, 31232, 31104,     0, 
+    16384, 24576, 28672, 30720, 31232, 31233, 31168,     0, 
+    16384, 24576, 28672, 30720, 31232, 31233, 31168,     0, 
+    16384, 24576, 28672, 30720, 31232, 31233, 31168, 31170, 
+        0, 16384, 24576, 28672, 30720, 31232, 31233, 31168, 
+        0, 16384, 24576, 28672, 30720, 31232, 31233, 31168, 
+    31172,     0, 16384, 24576, 28672, 30720, 31232, 31233, 
+    31168, 31172,     0, 16384, 24576, 28672, 30720, 31232, 
+    31233, 31168, 31176, 31174,     0, 16384, 24576, 28672, 
+    30720, 31232, 31233, 31168,     0, 16384, 24576, 28672, 
+    30720, 31232, 31233, 31168, 31176,     0, 16384, 24576, 
+    28672, 30720, 31232, 31233, 31168, 31176,     0, 16384, 
+    24576, 28672, 30720, 31232, 31233, 31168, 31176, 31178, 
+        0, 16384, 24576, 28672, 30720, 31232, 31233, 31168, 
+    31176,     0, 16384, 24576, 28672, 30720, 31232, 31233, 
+    31168, 31184, 31180,     0, 16384, 24576, 28672, 30720, 
+    31232, 31233, 31168, 31184, 31180,     0, 16384, 24576, 
+    28672, 30720, 31232, 31233, 31168, 31184, 31185, 31182, 
+        0, 16384, 24576, 28672, 30720, 31232, 31233, 31168, 
+        0, 16384, 24576, 28672, 30720, 31232, 31233, 31168, 
+    31184,     0, 16384, 24576, 28672, 30720, 31232, 31233, 
+    31168, 31184,     0, 16384, 24576, 28672, 30720, 31232, 
+    31233, 31168, 31184, 31186,     0, 16384, 24576, 28672, 
+    30720, 31232, 31233, 31168, 31184,     0, 16384, 24576, 
+    28672, 30720, 31232, 31233, 31168, 31184, 31188,     0, 
+    16384, 24576, 28672, 30720, 31232, 31233, 31168, 31184, 
+    31188,     0, 16384, 24576, 28672, 30720, 31232, 31233, 
+    31168, 31184, 31192, 31190,     0, 16384, 24576, 28672, 
+    30720, 31232, 31233, 31168, 31184,     0, 16384, 24576, 
+    28672, 30720, 31232, 31233, 31168, 31200, 31192,     0, 
+    16384, 24576, 28672, 30720, 31232, 31233, 31168, 31200, 
+    31192,     0, 16384, 24576, 28672, 30720, 31232, 31233, 
+    31168, 31200, 31192, 31194,     0, 16384, 24576, 28672, 
+    30720, 31232, 31233, 31168, 31200, 31192,     0, 16384, 
+    24576, 28672, 30720, 31232, 31233, 31168, 31200, 31201, 
+    31196,     0, 16384, 24576, 28672, 30720, 31232, 31233, 
+    31168, 31200, 31201, 31196,     0, 16384, 24576, 28672, 
+    30720, 31232, 31233, 31168, 31200, 31201, 31196, 31198, 
+        0, 16384, 24576, 28672, 30720, 31232, 31233, 31168, 
+        0, 16384, 24576, 28672, 30720, 31232, 31233, 31168, 
+    31200,     0, 16384, 24576, 28672, 30720, 31232, 31233, 
+    31235, 31200,     0, 16384, 24576, 28672, 30720, 31232, 
+    31233, 31235, 31200, 31202,     0, 16384, 24576, 28672, 
+    30720, 31232, 31233, 31235, 31200,     0, 16384, 24576, 
+    28672, 30720, 31232, 31233, 31235, 31200, 31204,     0, 
+    16384, 24576, 28672, 30720, 31232, 31233, 31235, 31200, 
+    31204,     0, 16384, 24576, 28672, 30720, 31232, 31233, 
+    31235, 31200, 31208, 31206,     0, 16384, 24576, 28672, 
+    30720, 31232, 31233, 31235, 31200,     0, 16384, 24576, 
+    28672, 30720, 31232, 31233, 31235, 31200, 31208,     0, 
+    16384, 24576, 28672, 30720, 31232, 31233, 31235, 31200, 
+    31208,     0, 16384, 24576, 28672, 30720, 31232, 31233, 
+    31235, 31200, 31208, 31210,     0, 16384, 24576, 28672, 
+    30720, 31232, 31233, 31235, 31200, 31208,     0, 16384, 
+    24576, 28672, 30720, 31232, 31233, 31235, 31200, 31216, 
+    31212,     0, 16384, 24576, 28672, 30720, 31232, 31233, 
+    31235, 31200, 31216, 31212,     0, 16384, 24576, 28672, 
+    30720, 31232, 31233, 31235, 31200, 31216, 31217, 31214, 
+        0, 16384, 24576, 28672, 30720, 31232, 31233, 31235, 
+    31200,     0, 16384, 24576, 28672, 30720, 31232, 31233, 
+    31235, 31200, 31216,     0, 16384, 24576, 28672, 30720, 
+    31232, 31233, 31235, 31200, 31216,     0, 16384, 24576, 
+    28672, 30720, 31232, 31233, 31235, 31200, 31216, 31218, 
+        0, 16384, 24576, 28672, 30720, 31232, 31233, 31235, 
+    31239, 31216,     0, 16384, 24576, 28672, 30720, 31232, 
+    31233, 31235, 31239, 31216, 31220,     0, 16384, 24576, 
+    28672, 30720, 31232, 31233, 31235, 31239, 31216, 31220, 
+        0, 16384, 24576, 28672, 30720, 31232, 31233, 31235, 
+    31239, 31216, 31224, 31222,     0, 16384, 24576, 28672, 
+    30720, 31232, 31233, 31235, 31239, 31216,     0, 16384, 
+    24576, 28672, 30720, 31232, 31233, 31235, 31239, 31216, 
+    31224,     0, 16384, 24576, 28672, 30720, 31232, 31233, 
+    31235, 31239, 31216, 31224,     0, 16384, 24576, 28672, 
+    30720, 31232, 31233, 31235, 31239, 31216, 31224, 31226, 
+        0, 16384, 24576, 28672, 30720, 31232, 31233, 31235, 
+    31239, 31216, 31224,     0, 16384, 24576, 28672, 30720, 
+    31232, 31233, 31235, 31239, 31216, 31224, 31228,     0, 
+    16384, 24576, 28672, 30720, 31232, 31233, 31235, 31239, 
+    31216, 31224, 31228,     0, 16384, 24576, 28672, 30720, 
+    31232, 31233, 31235, 31239, 31216, 31224, 31228, 31230, 
+        0, 16384, 24576, 28672, 30720,     0, 16384, 24576, 
+    28672, 30720, 31232,     0, 16384, 24576, 28672, 30720, 
+    31232,     0, 16384, 24576, 28672, 30720, 31232, 31234, 
+        0, 16384, 24576, 28672, 30720, 31232,     0, 16384, 
+    24576, 28672, 30720, 31232, 31236,     0, 16384, 24576, 
+    28672, 30720, 31232, 31236,     0, 16384, 24576, 28672, 
+    30720, 31232, 31240, 31238,     0, 16384, 24576, 28672, 
+    30720, 31232,     0, 16384, 24576, 28672, 30720, 31232, 
+    31240,     0, 16384, 24576, 28672, 30720, 31232, 31240, 
+        0, 16384, 24576, 28672, 30720, 31232, 31240, 31242, 
+        0, 16384, 24576, 28672, 30720, 31232, 31240,     0, 
+    16384, 24576, 28672, 30720, 31232, 31248, 31244,     0, 
+    16384, 24576, 28672, 30720, 31232, 31248, 31244,     0, 
+    16384, 24576, 28672, 30720, 31232, 31248, 31249, 31246, 
+        0, 16384, 24576, 28672, 30720, 31232,     0, 16384, 
+    24576, 28672, 30720, 31232, 31248,     0, 16384, 24576, 
+    28672, 30720, 31232, 31248,     0, 16384, 24576, 28672, 
+    30720, 31232, 31248, 31250,     0, 16384, 24576, 28672, 
+    30720, 31232, 31248,     0, 16384, 24576, 28672, 30720, 
+    31232, 31248, 31252,     0, 16384, 24576, 28672, 30720, 
+    31232, 31248, 31252,     0, 16384, 24576, 28672, 30720, 
+    31232, 31248, 31256, 31254,     0, 16384, 24576, 28672, 
+    30720, 31232, 31248,     0, 16384, 24576, 28672, 30720, 
+    31232, 31264, 31256,     0, 16384, 24576, 28672, 30720, 
+    31232, 31264, 31256,     0, 16384, 24576, 28672, 30720, 
+    31232, 31264, 31256, 31258,     0, 16384, 24576, 28672, 
+    30720, 31232, 31264, 31256,     0, 16384, 24576, 28672, 
+    30720, 31232, 31264, 31265, 31260,     0, 16384, 24576, 
+    28672, 30720, 31232, 31264, 31265, 31260,     0, 16384, 
+    24576, 28672, 30720, 31232, 31264, 31265, 31260, 31262, 
+        0, 16384, 24576, 28672, 30720, 31232,     0, 16384, 
+    24576, 28672, 30720, 31232, 31264,     0, 16384, 24576, 
+    28672, 30720, 31232, 31264,     0, 16384, 24576, 28672, 
+    30720, 31232, 31264, 31266,     0, 16384, 24576, 28672, 
+    30720, 31232, 31264,     0, 16384, 24576, 28672, 30720, 
+    31232, 31264, 31268,     0, 16384, 24576, 28672, 30720, 
+    31232, 31264, 31268,     0, 16384, 24576, 28672, 30720, 
+    31232, 31264, 31272, 31270,     0, 16384, 24576, 28672, 
+    30720, 31232, 31264,     0, 16384, 24576, 28672, 30720, 
+    31232, 31264, 31272,     0, 16384, 24576, 28672, 30720, 
+    31232, 31264, 31272,     0, 16384, 24576, 28672, 30720, 
+    31232, 31264, 31272, 31274,     0, 16384, 24576, 28672, 
+    30720, 31232, 31264, 31272,     0, 16384, 24576, 28672, 
+    30720, 31232, 31264, 31280, 31276,     0, 16384, 24576, 
+    28672, 30720, 31232, 31264, 31280, 31276,     0, 16384, 
+    24576, 28672, 30720, 31232, 31264, 31280, 31281, 31278, 
+        0, 16384, 24576, 28672, 30720, 31232, 31264,     0, 
+    16384, 24576, 28672, 30720, 31232, 31296, 31280,     0, 
+    16384, 24576, 28672, 30720, 31232, 31296, 31280,     0, 
+    16384, 24576, 28672, 30720, 31232, 31296, 31280, 31282, 
+        0, 16384, 24576, 28672, 30720, 31232, 31296, 31280, 
+        0, 16384, 24576, 28672, 30720, 31232, 31296, 31280, 
+    31284,     0, 16384, 24576, 28672, 30720, 31232, 31296, 
+    31280, 31284,     0, 16384, 24576, 28672, 30720, 31232, 
+    31296, 31280, 31288, 31286,     0, 16384, 24576, 28672, 
+    30720, 31232, 31296, 31280,     0, 16384, 24576, 28672, 
+    30720, 31232, 31296, 31297, 31288,     0, 16384, 24576, 
+    28672, 30720, 31232, 31296, 31297, 31288,     0, 16384, 
+    24576, 28672, 30720, 31232, 31296, 31297, 31288, 31290, 
+        0, 16384, 24576, 28672, 30720, 31232, 31296, 31297, 
+    31288,     0, 16384, 24576, 28672, 30720, 31232, 31296, 
+    31297, 31288, 31292,     0, 16384, 24576, 28672, 30720, 
+    31232, 31296, 31297, 31299, 31292,     0, 16384, 24576, 
+    28672, 30720, 31232, 31296, 31297, 31299, 31292, 31294, 
+        0, 16384, 24576, 28672, 30720, 31232,     0, 16384, 
+    24576, 28672, 30720, 31232, 31296,     0, 16384, 24576, 
+    28672, 30720, 31232, 31296,     0, 16384, 24576, 28672, 
+    30720, 31232, 31296, 31298,     0, 16384, 24576, 28672, 
+    30720, 31232, 31296,     0, 16384, 24576, 28672, 30720, 
+    31232, 31296, 31300,     0, 16384, 24576, 28672, 30720, 
+    31232, 31296, 31300,     0, 16384, 24576, 28672, 30720, 
+    31232, 31296, 31304, 31302,     0, 16384, 24576, 28672, 
+    30720, 31232, 31296,     0, 16384, 24576, 28672, 30720, 
+    31232, 31296, 31304,     0, 16384, 24576, 28672, 30720, 
+    31232, 31296, 31304,     0, 16384, 24576, 28672, 30720, 
+    31232, 31296, 31304, 31306,     0, 16384, 24576, 28672, 
+    30720, 31232, 31296, 31304,     0, 16384, 24576, 28672, 
+    30720, 31232, 31296, 31312, 31308,     0, 16384, 24576, 
+    28672, 30720, 31232, 31296, 31312, 31308,     0, 16384, 
+    24576, 28672, 30720, 31232, 31296, 31312, 31313, 31310, 
+        0, 16384, 24576, 28672, 30720, 31232, 31296,     0, 
+    16384, 24576, 28672, 30720, 31232, 31296, 31312,     0, 
+    16384, 24576, 28672, 30720, 31232, 31296, 31312,     0, 
+    16384, 24576, 28672, 30720, 31232, 31296, 31312, 31314, 
+        0, 16384, 24576, 28672, 30720, 31232, 31296, 31312, 
+        0, 16384, 24576, 28672, 30720, 31232, 31296, 31312, 
+    31316,     0, 16384, 24576, 28672, 30720, 31232, 31296, 
+    31312, 31316,     0, 16384, 24576, 28672, 30720, 31232, 
+    31296, 31312, 31320, 31318,     0, 16384, 24576, 28672, 
+    30720, 31232, 31296, 31312,     0, 16384, 24576, 28672, 
+    30720, 31232, 31296, 31328, 31320,     0, 16384, 24576, 
+    28672, 30720, 31232, 31296, 31328, 31320,     0, 16384, 
+    24576, 28672, 30720, 31232, 31296, 31328, 31320, 31322, 
+        0, 16384, 24576, 28672, 30720, 31232, 31296, 31328, 
+    31320,     0, 16384, 24576, 28672, 30720, 31232, 31296, 
+    31328, 31329, 31324,     0, 16384, 24576, 28672, 30720, 
+    31232, 31296, 31328, 31329, 31324,     0, 16384, 24576, 
+    28672, 30720, 31232, 31296, 31328, 31329, 31324, 31326, 
+        0, 16384, 24576, 28672, 30720, 31232, 31296,     0, 
+    16384, 24576, 28672, 30720, 31232, 31360, 31328,     0, 
+    16384, 24576, 28672, 30720, 31232, 31360, 31328,     0, 
+    16384, 24576, 28672, 30720, 31232, 31360, 31328, 31330, 
+        0, 16384, 24576, 28672, 30720, 31232, 31360, 31328, 
+        0, 16384, 24576, 28672, 30720, 31232, 31360, 31328, 
+    31332,     0, 16384, 24576, 28672, 30720, 31232, 31360, 
+    31328, 31332,     0, 16384, 24576, 28672, 30720, 31232, 
+    31360, 31328, 31336, 31334,     0, 16384, 24576, 28672, 
+    30720, 31232, 31360, 31328,     0, 16384, 24576, 28672, 
+    30720, 31232, 31360, 31328, 31336,     0, 16384, 24576, 
+    28672, 30720, 31232, 31360, 31328, 31336,     0, 16384, 
+    24576, 28672, 30720, 31232, 31360, 31328, 31336, 31338, 
+        0, 16384, 24576, 28672, 30720, 31232, 31360, 31328, 
+    31336,     0, 16384, 24576, 28672, 30720, 31232, 31360, 
+    31328, 31344, 31340,     0, 16384, 24576, 28672, 30720, 
+    31232, 31360, 31328, 31344, 31340,     0, 16384, 24576, 
+    28672, 30720, 31232, 31360, 31328, 31344, 31345, 31342, 
+        0, 16384, 24576, 28672, 30720, 31232, 31360, 31328, 
+        0, 16384, 24576, 28672, 30720, 31232, 31360, 31361, 
+    31344,     0, 16384, 24576, 28672, 30720, 31232, 31360, 
+    31361, 31344,     0, 16384, 24576, 28672, 30720, 31232, 
+    31360, 31361, 31344, 31346,     0, 16384, 24576, 28672, 
+    30720, 31232, 31360, 31361, 31344,     0, 16384, 24576, 
+    28672, 30720, 31232, 31360, 31361, 31344, 31348,     0, 
+    16384, 24576, 28672, 30720, 31232, 31360, 31361, 31344, 
+    31348,     0, 16384, 24576, 28672, 30720, 31232, 31360, 
+    31361, 31344, 31352, 31350,     0, 16384, 24576, 28672, 
+    30720, 31232, 31360, 31361, 31344,     0, 16384, 24576, 
+    28672, 30720, 31232, 31360, 31361, 31344, 31352,     0, 
+    16384, 24576, 28672, 30720, 31232, 31360, 31361, 31363, 
+    31352,     0, 16384, 24576, 28672, 30720, 31232, 31360, 
+    31361, 31363, 31352, 31354,     0, 16384, 24576, 28672, 
+    30720, 31232, 31360, 31361, 31363, 31352,     0, 16384, 
+    24576, 28672, 30720, 31232, 31360, 31361, 31363, 31352, 
+    31356,     0, 16384, 24576, 28672, 30720, 31232, 31360, 
+    31361, 31363, 31352, 31356,     0, 16384, 24576, 28672, 
+    30720, 31232, 31360, 31361, 31363, 31352, 31356, 31358, 
+        0, 16384, 24576, 28672, 30720, 31232,     0, 16384, 
+    24576, 28672, 30720, 31232, 31360,     0, 16384, 24576, 
+    28672, 30720, 31232, 31360,     0, 16384, 24576, 28672, 
+    30720, 31232, 31360, 31362,     0, 16384, 24576, 28672, 
+    30720, 31232, 31360,     0, 16384, 24576, 28672, 30720, 
+    31232, 31360, 31364,     0, 16384, 24576, 28672, 30720, 
+    31232, 31360, 31364,     0, 16384, 24576, 28672, 30720, 
+    31232, 31360, 31368, 31366,     0, 16384, 24576, 28672, 
+    30720, 31232, 31360,     0, 16384, 24576, 28672, 30720, 
+    31232, 31360, 31368,     0, 16384, 24576, 28672, 30720, 
+    31232, 31360, 31368,     0, 16384, 24576, 28672, 30720, 
+    31232, 31360, 31368, 31370,     0, 16384, 24576, 28672, 
+    30720, 31232, 31360, 31368,     0, 16384, 24576, 28672, 
+    30720, 31232, 31360, 31376, 31372,     0, 16384, 24576, 
+    28672, 30720, 31232, 31360, 31376, 31372,     0, 16384, 
+    24576, 28672, 30720, 31232, 31360, 31376, 31377, 31374, 
+        0, 16384, 24576, 28672, 30720, 31232, 31360,     0, 
+    16384, 24576, 28672, 30720, 31232, 31360, 31376,     0, 
+    16384, 24576, 28672, 30720, 31232, 31360, 31376,     0, 
+    16384, 24576, 28672, 30720, 31232, 31360, 31376, 31378, 
+        0, 16384, 24576, 28672, 30720, 31232, 31360, 31376, 
+        0, 16384, 24576, 28672, 30720, 31232, 31360, 31376, 
+    31380,     0, 16384, 24576, 28672, 30720, 31232, 31360, 
+    31376, 31380,     0, 16384, 24576, 28672, 30720, 31232, 
+    31360, 31376, 31384, 31382,     0, 16384, 24576, 28672, 
+    30720, 31232, 31360, 31376,     0, 16384, 24576, 28672, 
+    30720, 31232, 31360, 31392, 31384,     0, 16384, 24576, 
+    28672, 30720, 31232, 31360, 31392, 31384,     0, 16384, 
+    24576, 28672, 30720, 31232, 31360, 31392, 31384, 31386, 
+        0, 16384, 24576, 28672, 30720, 31232, 31360, 31392, 
+    31384,     0, 16384, 24576, 28672, 30720, 31232, 31360, 
+    31392, 31393, 31388,     0, 16384, 24576, 28672, 30720, 
+    31232, 31360, 31392, 31393, 31388,     0, 16384, 24576, 
+    28672, 30720, 31232, 31360, 31392, 31393, 31388, 31390, 
+        0, 16384, 24576, 28672, 30720, 31232, 31360,     0, 
+    16384, 24576, 28672, 30720, 31232, 31360, 31392,     0, 
+    16384, 24576, 28672, 30720, 31232, 31360, 31392,     0, 
+    16384, 24576, 28672, 30720, 31232, 31360, 31392, 31394, 
+        0, 16384, 24576, 28672, 30720, 31232, 31360, 31392, 
+        0, 16384, 24576, 28672, 30720, 31232, 31360, 31392, 
+    31396,     0, 16384, 24576, 28672, 30720, 31232, 31360, 
+    31392, 31396,     0, 16384, 24576, 28672, 30720, 31232, 
+    31360, 31392, 31400, 31398,     0, 16384, 24576, 28672, 
+    30720, 31232, 31360, 31392,     0, 16384, 24576, 28672, 
+    30720, 31232, 31360, 31392, 31400,     0, 16384, 24576, 
+    28672, 30720, 31232, 31360, 31392, 31400,     0, 16384, 
+    24576, 28672, 30720, 31232, 31360, 31392, 31400, 31402, 
+        0, 16384, 24576, 28672, 30720, 31232, 31360, 31392, 
+    31400,     0, 16384, 24576, 28672, 30720, 31232, 31360, 
+    31392, 31408, 31404,     0, 16384, 24576, 28672, 30720, 
+    31232, 31360, 31392, 31408, 31404,     0, 16384, 24576, 
+    28672, 30720, 31232, 31360, 31392, 31408, 31409, 31406, 
+        0, 16384, 24576, 28672, 30720, 31232, 31360, 31392, 
+        0, 16384, 24576, 28672, 30720, 31232, 31360, 31424, 
+    31408,     0, 16384, 24576, 28672, 30720, 31232, 31360, 
+    31424, 31408,     0, 16384, 24576, 28672, 30720, 31232, 
+    31360, 31424, 31408, 31410,     0, 16384, 24576, 28672, 
+    30720, 31232, 31360, 31424, 31408,     0, 16384, 24576, 
+    28672, 30720, 31232, 31360, 31424, 31408, 31412,     0, 
+    16384, 24576, 28672, 30720, 31232, 31360, 31424, 31408, 
+    31412,     0, 16384, 24576, 28672, 30720, 31232, 31360, 
+    31424, 31408, 31416, 31414,     0, 16384, 24576, 28672, 
+    30720, 31232, 31360, 31424, 31408,     0, 16384, 24576, 
+    28672, 30720, 31232, 31360, 31424, 31425, 31416,     0, 
+    16384, 24576, 28672, 30720, 31232, 31360, 31424, 31425, 
+    31416,     0, 16384, 24576, 28672, 30720, 31232, 31360, 
+    31424, 31425, 31416, 31418,     0, 16384, 24576, 28672, 
+    30720, 31232, 31360, 31424, 31425, 31416,     0, 16384, 
+    24576, 28672, 30720, 31232, 31360, 31424, 31425, 31416, 
+    31420,     0, 16384, 24576, 28672, 30720, 31232, 31360, 
+    31424, 31425, 31427, 31420,     0, 16384, 24576, 28672, 
+    30720, 31232, 31360, 31424, 31425, 31427, 31420, 31422, 
+        0, 16384, 24576, 28672, 30720, 31232, 31360,     0, 
+    16384, 24576, 28672, 30720, 31232, 31488, 31424,     0, 
+    16384, 24576, 28672, 30720, 31232, 31488, 31424,     0, 
+    16384, 24576, 28672, 30720, 31232, 31488, 31424, 31426, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31424, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31424, 
+    31428,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31424, 31428,     0, 16384, 24576, 28672, 30720, 31232, 
+    31488, 31424, 31432, 31430,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31424,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31424, 31432,     0, 16384, 24576, 
+    28672, 30720, 31232, 31488, 31424, 31432,     0, 16384, 
+    24576, 28672, 30720, 31232, 31488, 31424, 31432, 31434, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31424, 
+    31432,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31424, 31440, 31436,     0, 16384, 24576, 28672, 30720, 
+    31232, 31488, 31424, 31440, 31436,     0, 16384, 24576, 
+    28672, 30720, 31232, 31488, 31424, 31440, 31441, 31438, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31424, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31424, 
+    31440,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31424, 31440,     0, 16384, 24576, 28672, 30720, 31232, 
+    31488, 31424, 31440, 31442,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31424, 31440,     0, 16384, 24576, 
+    28672, 30720, 31232, 31488, 31424, 31440, 31444,     0, 
+    16384, 24576, 28672, 30720, 31232, 31488, 31424, 31440, 
+    31444,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31424, 31440, 31448, 31446,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31424, 31440,     0, 16384, 24576, 
+    28672, 30720, 31232, 31488, 31424, 31456, 31448,     0, 
+    16384, 24576, 28672, 30720, 31232, 31488, 31424, 31456, 
+    31448,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31424, 31456, 31448, 31450,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31424, 31456, 31448,     0, 16384, 
+    24576, 28672, 30720, 31232, 31488, 31424, 31456, 31457, 
+    31452,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31424, 31456, 31457, 31452,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31424, 31456, 31457, 31452, 31454, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31424, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31489, 
+    31456,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31489, 31456,     0, 16384, 24576, 28672, 30720, 31232, 
+    31488, 31489, 31456, 31458,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31489, 31456,     0, 16384, 24576, 
+    28672, 30720, 31232, 31488, 31489, 31456, 31460,     0, 
+    16384, 24576, 28672, 30720, 31232, 31488, 31489, 31456, 
+    31460,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31489, 31456, 31464, 31462,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31489, 31456,     0, 16384, 24576, 
+    28672, 30720, 31232, 31488, 31489, 31456, 31464,     0, 
+    16384, 24576, 28672, 30720, 31232, 31488, 31489, 31456, 
+    31464,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31489, 31456, 31464, 31466,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31489, 31456, 31464,     0, 16384, 
+    24576, 28672, 30720, 31232, 31488, 31489, 31456, 31472, 
+    31468,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31489, 31456, 31472, 31468,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31489, 31456, 31472, 31473, 31470, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31489, 
+    31456,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31489, 31456, 31472,     0, 16384, 24576, 28672, 30720, 
+    31232, 31488, 31489, 31491, 31472,     0, 16384, 24576, 
+    28672, 30720, 31232, 31488, 31489, 31491, 31472, 31474, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31489, 
+    31491, 31472,     0, 16384, 24576, 28672, 30720, 31232, 
+    31488, 31489, 31491, 31472, 31476,     0, 16384, 24576, 
+    28672, 30720, 31232, 31488, 31489, 31491, 31472, 31476, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31489, 
+    31491, 31472, 31480, 31478,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31489, 31491, 31472,     0, 16384, 
+    24576, 28672, 30720, 31232, 31488, 31489, 31491, 31472, 
+    31480,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31489, 31491, 31472, 31480,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31489, 31491, 31472, 31480, 31482, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31489, 
+    31491, 31495, 31480,     0, 16384, 24576, 28672, 30720, 
+    31232, 31488, 31489, 31491, 31495, 31480, 31484,     0, 
+    16384, 24576, 28672, 30720, 31232, 31488, 31489, 31491, 
+    31495, 31480, 31484,     0, 16384, 24576, 28672, 30720, 
+    31232, 31488, 31489, 31491, 31495, 31480, 31484, 31486, 
+        0, 16384, 24576, 28672, 30720, 31232,     0, 16384, 
+    24576, 28672, 30720, 31232, 31488,     0, 16384, 24576, 
+    28672, 30720, 31232, 31488,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31490,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488,     0, 16384, 24576, 28672, 30720, 
+    31232, 31488, 31492,     0, 16384, 24576, 28672, 30720, 
+    31232, 31488, 31492,     0, 16384, 24576, 28672, 30720, 
+    31232, 31488, 31496, 31494,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488,     0, 16384, 24576, 28672, 30720, 
+    31232, 31488, 31496,     0, 16384, 24576, 28672, 30720, 
+    31232, 31488, 31496,     0, 16384, 24576, 28672, 30720, 
+    31232, 31488, 31496, 31498,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31496,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31504, 31500,     0, 16384, 24576, 
+    28672, 30720, 31232, 31488, 31504, 31500,     0, 16384, 
+    24576, 28672, 30720, 31232, 31488, 31504, 31505, 31502, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488,     0, 
+    16384, 24576, 28672, 30720, 31232, 31488, 31504,     0, 
+    16384, 24576, 28672, 30720, 31232, 31488, 31504,     0, 
+    16384, 24576, 28672, 30720, 31232, 31488, 31504, 31506, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31504, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31504, 
+    31508,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31504, 31508,     0, 16384, 24576, 28672, 30720, 31232, 
+    31488, 31504, 31512, 31510,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31504,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31520, 31512,     0, 16384, 24576, 
+    28672, 30720, 31232, 31488, 31520, 31512,     0, 16384, 
+    24576, 28672, 30720, 31232, 31488, 31520, 31512, 31514, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31520, 
+    31512,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31520, 31521, 31516,     0, 16384, 24576, 28672, 30720, 
+    31232, 31488, 31520, 31521, 31516,     0, 16384, 24576, 
+    28672, 30720, 31232, 31488, 31520, 31521, 31516, 31518, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488,     0, 
+    16384, 24576, 28672, 30720, 31232, 31488, 31520,     0, 
+    16384, 24576, 28672, 30720, 31232, 31488, 31520,     0, 
+    16384, 24576, 28672, 30720, 31232, 31488, 31520, 31522, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31520, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31520, 
+    31524,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31520, 31524,     0, 16384, 24576, 28672, 30720, 31232, 
+    31488, 31520, 31528, 31526,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31520,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31520, 31528,     0, 16384, 24576, 
+    28672, 30720, 31232, 31488, 31520, 31528,     0, 16384, 
+    24576, 28672, 30720, 31232, 31488, 31520, 31528, 31530, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31520, 
+    31528,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31520, 31536, 31532,     0, 16384, 24576, 28672, 30720, 
+    31232, 31488, 31520, 31536, 31532,     0, 16384, 24576, 
+    28672, 30720, 31232, 31488, 31520, 31536, 31537, 31534, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31520, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31552, 
+    31536,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31552, 31536,     0, 16384, 24576, 28672, 30720, 31232, 
+    31488, 31552, 31536, 31538,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31552, 31536,     0, 16384, 24576, 
+    28672, 30720, 31232, 31488, 31552, 31536, 31540,     0, 
+    16384, 24576, 28672, 30720, 31232, 31488, 31552, 31536, 
+    31540,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31552, 31536, 31544, 31542,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31552, 31536,     0, 16384, 24576, 
+    28672, 30720, 31232, 31488, 31552, 31553, 31544,     0, 
+    16384, 24576, 28672, 30720, 31232, 31488, 31552, 31553, 
+    31544,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31552, 31553, 31544, 31546,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31552, 31553, 31544,     0, 16384, 
+    24576, 28672, 30720, 31232, 31488, 31552, 31553, 31544, 
+    31548,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31552, 31553, 31555, 31548,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31552, 31553, 31555, 31548, 31550, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488,     0, 
+    16384, 24576, 28672, 30720, 31232, 31488, 31552,     0, 
+    16384, 24576, 28672, 30720, 31232, 31488, 31552,     0, 
+    16384, 24576, 28672, 30720, 31232, 31488, 31552, 31554, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31552, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31552, 
+    31556,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31552, 31556,     0, 16384, 24576, 28672, 30720, 31232, 
+    31488, 31552, 31560, 31558,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31552,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31552, 31560,     0, 16384, 24576, 
+    28672, 30720, 31232, 31488, 31552, 31560,     0, 16384, 
+    24576, 28672, 30720, 31232, 31488, 31552, 31560, 31562, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31552, 
+    31560,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31552, 31568, 31564,     0, 16384, 24576, 28672, 30720, 
+    31232, 31488, 31552, 31568, 31564,     0, 16384, 24576, 
+    28672, 30720, 31232, 31488, 31552, 31568, 31569, 31566, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31552, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31552, 
+    31568,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31552, 31568,     0, 16384, 24576, 28672, 30720, 31232, 
+    31488, 31552, 31568, 31570,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31552, 31568,     0, 16384, 24576, 
+    28672, 30720, 31232, 31488, 31552, 31568, 31572,     0, 
+    16384, 24576, 28672, 30720, 31232, 31488, 31552, 31568, 
+    31572,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31552, 31568, 31576, 31574,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31552, 31568,     0, 16384, 24576, 
+    28672, 30720, 31232, 31488, 31552, 31584, 31576,     0, 
+    16384, 24576, 28672, 30720, 31232, 31488, 31552, 31584, 
+    31576,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31552, 31584, 31576, 31578,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31552, 31584, 31576,     0, 16384, 
+    24576, 28672, 30720, 31232, 31488, 31552, 31584, 31585, 
+    31580,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31552, 31584, 31585, 31580,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31552, 31584, 31585, 31580, 31582, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31552, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31616, 
+    31584,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31616, 31584,     0, 16384, 24576, 28672, 30720, 31232, 
+    31488, 31616, 31584, 31586,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31616, 31584,     0, 16384, 24576, 
+    28672, 30720, 31232, 31488, 31616, 31584, 31588,     0, 
+    16384, 24576, 28672, 30720, 31232, 31488, 31616, 31584, 
+    31588,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31616, 31584, 31592, 31590,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31616, 31584,     0, 16384, 24576, 
+    28672, 30720, 31232, 31488, 31616, 31584, 31592,     0, 
+    16384, 24576, 28672, 30720, 31232, 31488, 31616, 31584, 
+    31592,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31616, 31584, 31592, 31594,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31616, 31584, 31592,     0, 16384, 
+    24576, 28672, 30720, 31232, 31488, 31616, 31584, 31600, 
+    31596,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31616, 31584, 31600, 31596,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31616, 31584, 31600, 31601, 31598, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31616, 
+    31584,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31616, 31617, 31600,     0, 16384, 24576, 28672, 30720, 
+    31232, 31488, 31616, 31617, 31600,     0, 16384, 24576, 
+    28672, 30720, 31232, 31488, 31616, 31617, 31600, 31602, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31616, 
+    31617, 31600,     0, 16384, 24576, 28672, 30720, 31232, 
+    31488, 31616, 31617, 31600, 31604,     0, 16384, 24576, 
+    28672, 30720, 31232, 31488, 31616, 31617, 31600, 31604, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31616, 
+    31617, 31600, 31608, 31606,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31616, 31617, 31600,     0, 16384, 
+    24576, 28672, 30720, 31232, 31488, 31616, 31617, 31600, 
+    31608,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31616, 31617, 31619, 31608,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31616, 31617, 31619, 31608, 31610, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31616, 
+    31617, 31619, 31608,     0, 16384, 24576, 28672, 30720, 
+    31232, 31488, 31616, 31617, 31619, 31608, 31612,     0, 
+    16384, 24576, 28672, 30720, 31232, 31488, 31616, 31617, 
+    31619, 31608, 31612,     0, 16384, 24576, 28672, 30720, 
+    31232, 31488, 31616, 31617, 31619, 31608, 31612, 31614, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488,     0, 
+    16384, 24576, 28672, 30720, 31232, 31488, 31616,     0, 
+    16384, 24576, 28672, 30720, 31232, 31488, 31616,     0, 
+    16384, 24576, 28672, 30720, 31232, 31488, 31616, 31618, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31616, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31616, 
+    31620,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31616, 31620,     0, 16384, 24576, 28672, 30720, 31232, 
+    31488, 31616, 31624, 31622,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31616,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31616, 31624,     0, 16384, 24576, 
+    28672, 30720, 31232, 31488, 31616, 31624,     0, 16384, 
+    24576, 28672, 30720, 31232, 31488, 31616, 31624, 31626, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31616, 
+    31624,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31616, 31632, 31628,     0, 16384, 24576, 28672, 30720, 
+    31232, 31488, 31616, 31632, 31628,     0, 16384, 24576, 
+    28672, 30720, 31232, 31488, 31616, 31632, 31633, 31630, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31616, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31616, 
+    31632,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31616, 31632,     0, 16384, 24576, 28672, 30720, 31232, 
+    31488, 31616, 31632, 31634,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31616, 31632,     0, 16384, 24576, 
+    28672, 30720, 31232, 31488, 31616, 31632, 31636,     0, 
+    16384, 24576, 28672, 30720, 31232, 31488, 31616, 31632, 
+    31636,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31616, 31632, 31640, 31638,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31616, 31632,     0, 16384, 24576, 
+    28672, 30720, 31232, 31488, 31616, 31648, 31640,     0, 
+    16384, 24576, 28672, 30720, 31232, 31488, 31616, 31648, 
+    31640,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31616, 31648, 31640, 31642,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31616, 31648, 31640,     0, 16384, 
+    24576, 28672, 30720, 31232, 31488, 31616, 31648, 31649, 
+    31644,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31616, 31648, 31649, 31644,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31616, 31648, 31649, 31644, 31646, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31616, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31616, 
+    31648,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31616, 31648,     0, 16384, 24576, 28672, 30720, 31232, 
+    31488, 31616, 31648, 31650,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31616, 31648,     0, 16384, 24576, 
+    28672, 30720, 31232, 31488, 31616, 31648, 31652,     0, 
+    16384, 24576, 28672, 30720, 31232, 31488, 31616, 31648, 
+    31652,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31616, 31648, 31656, 31654,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31616, 31648,     0, 16384, 24576, 
+    28672, 30720, 31232, 31488, 31616, 31648, 31656,     0, 
+    16384, 24576, 28672, 30720, 31232, 31488, 31616, 31648, 
+    31656,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31616, 31648, 31656, 31658,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31616, 31648, 31656,     0, 16384, 
+    24576, 28672, 30720, 31232, 31488, 31616, 31648, 31664, 
+    31660,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31616, 31648, 31664, 31660,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31616, 31648, 31664, 31665, 31662, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31616, 
+    31648,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31616, 31680, 31664,     0, 16384, 24576, 28672, 30720, 
+    31232, 31488, 31616, 31680, 31664,     0, 16384, 24576, 
+    28672, 30720, 31232, 31488, 31616, 31680, 31664, 31666, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31616, 
+    31680, 31664,     0, 16384, 24576, 28672, 30720, 31232, 
+    31488, 31616, 31680, 31664, 31668,     0, 16384, 24576, 
+    28672, 30720, 31232, 31488, 31616, 31680, 31664, 31668, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31616, 
+    31680, 31664, 31672, 31670,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31616, 31680, 31664,     0, 16384, 
+    24576, 28672, 30720, 31232, 31488, 31616, 31680, 31681, 
+    31672,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31616, 31680, 31681, 31672,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31616, 31680, 31681, 31672, 31674, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31616, 
+    31680, 31681, 31672,     0, 16384, 24576, 28672, 30720, 
+    31232, 31488, 31616, 31680, 31681, 31672, 31676,     0, 
+    16384, 24576, 28672, 30720, 31232, 31488, 31616, 31680, 
+    31681, 31683, 31676,     0, 16384, 24576, 28672, 30720, 
+    31232, 31488, 31616, 31680, 31681, 31683, 31676, 31678, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31616, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31616, 
+    31680,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31616, 31680,     0, 16384, 24576, 28672, 30720, 31232, 
+    31488, 31616, 31680, 31682,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31616, 31680,     0, 16384, 24576, 
+    28672, 30720, 31232, 31488, 31616, 31680, 31684,     0, 
+    16384, 24576, 28672, 30720, 31232, 31488, 31616, 31680, 
+    31684,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31616, 31680, 31688, 31686,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31616, 31680,     0, 16384, 24576, 
+    28672, 30720, 31232, 31488, 31616, 31680, 31688,     0, 
+    16384, 24576, 28672, 30720, 31232, 31488, 31616, 31680, 
+    31688,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31616, 31680, 31688, 31690,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31616, 31680, 31688,     0, 16384, 
+    24576, 28672, 30720, 31232, 31488, 31616, 31680, 31696, 
+    31692,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31616, 31680, 31696, 31692,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31616, 31680, 31696, 31697, 31694, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31616, 
+    31680,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31616, 31680, 31696,     0, 16384, 24576, 28672, 30720, 
+    31232, 31488, 31616, 31680, 31696,     0, 16384, 24576, 
+    28672, 30720, 31232, 31488, 31616, 31680, 31696, 31698, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31616, 
+    31680, 31696,     0, 16384, 24576, 28672, 30720, 31232, 
+    31488, 31616, 31680, 31696, 31700,     0, 16384, 24576, 
+    28672, 30720, 31232, 31488, 31616, 31680, 31696, 31700, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31616, 
+    31680, 31696, 31704, 31702,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31616, 31680, 31696,     0, 16384, 
+    24576, 28672, 30720, 31232, 31488, 31616, 31680, 31712, 
+    31704,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31616, 31680, 31712, 31704,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31616, 31680, 31712, 31704, 31706, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31616, 
+    31680, 31712, 31704,     0, 16384, 24576, 28672, 30720, 
+    31232, 31488, 31616, 31680, 31712, 31713, 31708,     0, 
+    16384, 24576, 28672, 30720, 31232, 31488, 31616, 31680, 
+    31712, 31713, 31708,     0, 16384, 24576, 28672, 30720, 
+    31232, 31488, 31616, 31680, 31712, 31713, 31708, 31710, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31616, 
+    31680,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31616, 31680, 31712,     0, 16384, 24576, 28672, 30720, 
+    31232, 31488, 31616, 31680, 31712,     0, 16384, 24576, 
+    28672, 30720, 31232, 31488, 31616, 31680, 31712, 31714, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31616, 
+    31680, 31712,     0, 16384, 24576, 28672, 30720, 31232, 
+    31488, 31616, 31680, 31712, 31716,     0, 16384, 24576, 
+    28672, 30720, 31232, 31488, 31616, 31680, 31712, 31716, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31616, 
+    31680, 31712, 31720, 31718,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31616, 31680, 31712,     0, 16384, 
+    24576, 28672, 30720, 31232, 31488, 31616, 31680, 31712, 
+    31720,     0, 16384, 24576, 28672, 30720, 31232, 31488, 
+    31616, 31680, 31712, 31720,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31616, 31680, 31712, 31720, 31722, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31616, 
+    31680, 31712, 31720,     0, 16384, 24576, 28672, 30720, 
+    31232, 31488, 31616, 31680, 31712, 31728, 31724,     0, 
+    16384, 24576, 28672, 30720, 31232, 31488, 31616, 31680, 
+    31712, 31728, 31724,     0, 16384, 24576, 28672, 30720, 
+    31232, 31488, 31616, 31680, 31712, 31728, 31729, 31726, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31616, 
+    31680, 31712,     0, 16384, 24576, 28672, 30720, 31232, 
+    31488, 31616, 31680, 31712, 31728,     0, 16384, 24576, 
+    28672, 30720, 31232, 31488, 31616, 31680, 31712, 31728, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31616, 
+    31680, 31712, 31728, 31730,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31616, 31680, 31712, 31728,     0, 
+    16384, 24576, 28672, 30720, 31232, 31488, 31616, 31680, 
+    31712, 31728, 31732,     0, 16384, 24576, 28672, 30720, 
+    31232, 31488, 31616, 31680, 31712, 31728, 31732,     0, 
+    16384, 24576, 28672, 30720, 31232, 31488, 31616, 31680, 
+    31712, 31728, 31736, 31734,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31616, 31680, 31712, 31728,     0, 
+    16384, 24576, 28672, 30720, 31232, 31488, 31616, 31680, 
+    31712, 31728, 31736,     0, 16384, 24576, 28672, 30720, 
+    31232, 31488, 31616, 31680, 31712, 31728, 31736,     0, 
+    16384, 24576, 28672, 30720, 31232, 31488, 31616, 31680, 
+    31712, 31728, 31736, 31738,     0, 16384, 24576, 28672, 
+    30720, 31232, 31488, 31616, 31680, 31712, 31728, 31736, 
+        0, 16384, 24576, 28672, 30720, 31232, 31488, 31616, 
+    31680, 31712, 31728, 31736, 31740,     0, 16384, 24576, 
+    28672, 30720, 31232, 31488, 31616, 31680, 31712, 31728, 
+    31736, 31740,     0, 16384, 24576, 28672, 30720, 31232, 
+    31488, 31616, 31680, 31712, 31728, 31736, 31740, 31742, 
+        0,     1,     3,     7,    15,     0,     1,     3, 
+        7,    15,    31,     0,     1,     3,     7,    15, 
+       31,     0,     1,     3,     7,    15,    31,    63, 
+        0,     1,     3,     7,    15,    31,     0,     1, 
+        3,     7,    15,    31,    63,     0,     1,     3, 
+        7,    15,    31,    63,     0,     1,     3,     7, 
+       15,    31,    63,   127,     0,     1,     3,     7, 
+       15,    31,     0,     1,     3,     7,    15,    31, 
+       63,     0,     1,     3,     7,    15,    31,    63, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+        0,     1,     3,     7,    15,    31,     0,     1, 
+        3,     7,    15,    31,    63,     0,     1,     3, 
+        7,    15,    31,    63,     0,     1,     3,     7, 
+       15,    31,    63,   127,     0,     1,     3,     7, 
+       15,    31,    63,     0,     1,     3,     7,    15, 
+       31,    63,   127,     0,     1,     3,     7,    15, 
+       31,    63,   127,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,     0,     1,     3,     7, 
+       15,    31,    63,     0,     1,     3,     7,    15, 
+       31,    63,   127,     0,     1,     3,     7,    15, 
+       31,    63,   127,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,     0,     1,     3,     7, 
+       15,    31,    63,   127,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+        0,     1,     3,     7,    15,    31,     0,     1, 
+        3,     7,    15,    31,    63,     0,     1,     3, 
+        7,    15,    31,    63,     0,     1,     3,     7, 
+       15,    31,    63,   127,     0,     1,     3,     7, 
+       15,    31,    63,     0,     1,     3,     7,    15, 
+       31,    63,   127,     0,     1,     3,     7,    15, 
+       31,    63,   127,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,     0,     1,     3,     7, 
+       15,    31,    63,     0,     1,     3,     7,    15, 
+       31,    63,   127,     0,     1,     3,     7,    15, 
+       31,    63,   127,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,     0,     1,     3,     7, 
+       15,    31,    63,   127,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+        0,     1,     3,     7,    15,    31,    63,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,     0,     1, 
+        3,     7,    15,    31,    63,     0,     1,     3, 
+        7,    15,    31,    63,     0,     1,     3,     7, 
+       15,    31,    63,   127,     0,     1,     3,     7, 
+       15,    31,    63,     0,     1,     3,     7,    15, 
+       31,    63,   127,     0,     1,     3,     7,    15, 
+       31,    63,   127,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,     0,     1,     3,     7, 
+       15,    31,    63,     0,     1,     3,     7,    15, 
+       31,    63,   127,     0,     1,     3,     7,    15, 
+       31,    63,   127,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,     0,     1,     3,     7, 
+       15,    31,    63,   127,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+        0,     1,     3,     7,    15,    31,    63,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,     0,     1, 
+        3,     7,    15,    31,    63,     0,     1,     3, 
+        7,    15,    31,    63,     0,     1,     3,     7, 
+       15,    31,    63,   127,     0,     1,     3,     7, 
+       15,    31,    63,     0,     1,     3,     7,    15, 
+       31,    63,   127,     0,     1,     3,     7,    15, 
+       31,    63,   127,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,     0,     1,     3,     7, 
+       15,    31,    63,     0,     1,     3,     7,    15, 
+       31,    63,   127,     0,     1,     3,     7,    15, 
+       31,    63,   127,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,     0,     1,     3,     7, 
+       15,    31,    63,   127,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+        0,     1,     3,     7,    15,    31,    63,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,     0,     1, 
+        3,     7,    15,    31,    63,     0,     1,     3, 
+        7,    15,    31,    63,     0,     1,     3,     7, 
+       15,    31,    63,   127,     0,     1,     3,     7, 
+       15,    31,    63,     0,     1,     3,     7,    15, 
+       31,    63,   127,     0,     1,     3,     7,    15, 
+       31,    63,   127,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,     0,     1,     3,     7, 
+       15,    31,    63,     0,     1,     3,     7,    15, 
+       31,    63,   127,     0,     1,     3,     7,    15, 
+       31,    63,   127,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,     0,     1,     3,     7, 
+       15,    31,    63,   127,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+        0,     1,     3,     7,    15,    31,    63,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,    63,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,  4095,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+     2047,  4095,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,  2047,  4095,  8191, 
+        0,     1,     3,     7,    15,    31,     0,     1, 
+        3,     7,    15,    31,    63,     0,     1,     3, 
+        7,    15,    31,    63,     0,     1,     3,     7, 
+       15,    31,    63,   127,     0,     1,     3,     7, 
+       15,    31,    63,     0,     1,     3,     7,    15, 
+       31,    63,   127,     0,     1,     3,     7,    15, 
+       31,    63,   127,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,     0,     1,     3,     7, 
+       15,    31,    63,     0,     1,     3,     7,    15, 
+       31,    63,   127,     0,     1,     3,     7,    15, 
+       31,    63,   127,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,     0,     1,     3,     7, 
+       15,    31,    63,   127,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+        0,     1,     3,     7,    15,    31,    63,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,    63,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,  4095,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+     2047,  4095,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,  2047,  4095,  8191, 
+        0,     1,     3,     7,    15,    31,    63,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,  4095,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+     2047,  4095,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,  2047,  4095,  8191, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,  4095,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+     2047,  4095,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,  2047,  4095,  8191, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,  4095,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+     2047,  4095,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,  2047,  4095,  8191, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,  4095,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+     2047,  4095,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,  2047,  4095,  8191, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+     4095,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,  2047,  4095,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,  2047,  4095,  8191,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,  4095,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+     2047,  4095,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,  2047,  4095,  8191, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,  4095,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+     2047,  4095,  8191,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+     8191,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,  2047,  4095,  8191, 16383, 
+        0,     0, 32768,     0, 32768,     0, 32768, 32770, 
+        0, 32768,     0, 32768, 32772,     0, 32768, 32772, 
+        0, 32768, 32776, 32774,     0, 32768,     0, 32768, 
+    32776,     0, 32768, 32776,     0, 32768, 32776, 32778, 
+        0, 32768, 32776,     0, 32768, 32784, 32780,     0, 
+    32768, 32784, 32780,     0, 32768, 32784, 32785, 32782, 
+        0, 32768,     0, 32768, 32784,     0, 32768, 32784, 
+        0, 32768, 32784, 32786,     0, 32768, 32784,     0, 
+    32768, 32784, 32788,     0, 32768, 32784, 32788,     0, 
+    32768, 32784, 32792, 32790,     0, 32768, 32784,     0, 
+    32768, 32800, 32792,     0, 32768, 32800, 32792,     0, 
+    32768, 32800, 32792, 32794,     0, 32768, 32800, 32792, 
+        0, 32768, 32800, 32801, 32796,     0, 32768, 32800, 
+    32801, 32796,     0, 32768, 32800, 32801, 32796, 32798, 
+        0, 32768,     0, 32768, 32800,     0, 32768, 32800, 
+        0, 32768, 32800, 32802,     0, 32768, 32800,     0, 
+    32768, 32800, 32804,     0, 32768, 32800, 32804,     0, 
+    32768, 32800, 32808, 32806,     0, 32768, 32800,     0, 
+    32768, 32800, 32808,     0, 32768, 32800, 32808,     0, 
+    32768, 32800, 32808, 32810,     0, 32768, 32800, 32808, 
+        0, 32768, 32800, 32816, 32812,     0, 32768, 32800, 
+    32816, 32812,     0, 32768, 32800, 32816, 32817, 32814, 
+        0, 32768, 32800,     0, 32768, 32832, 32816,     0, 
+    32768, 32832, 32816,     0, 32768, 32832, 32816, 32818, 
+        0, 32768, 32832, 32816,     0, 32768, 32832, 32816, 
+    32820,     0, 32768, 32832, 32816, 32820,     0, 32768, 
+    32832, 32816, 32824, 32822,     0, 32768, 32832, 32816, 
+        0, 32768, 32832, 32833, 32824,     0, 32768, 32832, 
+    32833, 32824,     0, 32768, 32832, 32833, 32824, 32826, 
+        0, 32768, 32832, 32833, 32824,     0, 32768, 32832, 
+    32833, 32824, 32828,     0, 32768, 32832, 32833, 32835, 
+    32828,     0, 32768, 32832, 32833, 32835, 32828, 32830, 
+        0, 32768,     0, 32768, 32832,     0, 32768, 32832, 
+        0, 32768, 32832, 32834,     0, 32768, 32832,     0, 
+    32768, 32832, 32836,     0, 32768, 32832, 32836,     0, 
+    32768, 32832, 32840, 32838,     0, 32768, 32832,     0, 
+    32768, 32832, 32840,     0, 32768, 32832, 32840,     0, 
+    32768, 32832, 32840, 32842,     0, 32768, 32832, 32840, 
+        0, 32768, 32832, 32848, 32844,     0, 32768, 32832, 
+    32848, 32844,     0, 32768, 32832, 32848, 32849, 32846, 
+        0, 32768, 32832,     0, 32768, 32832, 32848,     0, 
+    32768, 32832, 32848,     0, 32768, 32832, 32848, 32850, 
+        0, 32768, 32832, 32848,     0, 32768, 32832, 32848, 
+    32852,     0, 32768, 32832, 32848, 32852,     0, 32768, 
+    32832, 32848, 32856, 32854,     0, 32768, 32832, 32848, 
+        0, 32768, 32832, 32864, 32856,     0, 32768, 32832, 
+    32864, 32856,     0, 32768, 32832, 32864, 32856, 32858, 
+        0, 32768, 32832, 32864, 32856,     0, 32768, 32832, 
+    32864, 32865, 32860,     0, 32768, 32832, 32864, 32865, 
+    32860,     0, 32768, 32832, 32864, 32865, 32860, 32862, 
+        0, 32768, 32832,     0, 32768, 32896, 32864,     0, 
+    32768, 32896, 32864,     0, 32768, 32896, 32864, 32866, 
+        0, 32768, 32896, 32864,     0, 32768, 32896, 32864, 
+    32868,     0, 32768, 32896, 32864, 32868,     0, 32768, 
+    32896, 32864, 32872, 32870,     0, 32768, 32896, 32864, 
+        0, 32768, 32896, 32864, 32872,     0, 32768, 32896, 
+    32864, 32872,     0, 32768, 32896, 32864, 32872, 32874, 
+        0, 32768, 32896, 32864, 32872,     0, 32768, 32896, 
+    32864, 32880, 32876,     0, 32768, 32896, 32864, 32880, 
+    32876,     0, 32768, 32896, 32864, 32880, 32881, 32878, 
+        0, 32768, 32896, 32864,     0, 32768, 32896, 32897, 
+    32880,     0, 32768, 32896, 32897, 32880,     0, 32768, 
+    32896, 32897, 32880, 32882,     0, 32768, 32896, 32897, 
+    32880,     0, 32768, 32896, 32897, 32880, 32884,     0, 
+    32768, 32896, 32897, 32880, 32884,     0, 32768, 32896, 
+    32897, 32880, 32888, 32886,     0, 32768, 32896, 32897, 
+    32880,     0, 32768, 32896, 32897, 32880, 32888,     0, 
+    32768, 32896, 32897, 32899, 32888,     0, 32768, 32896, 
+    32897, 32899, 32888, 32890,     0, 32768, 32896, 32897, 
+    32899, 32888,     0, 32768, 32896, 32897, 32899, 32888, 
+    32892,     0, 32768, 32896, 32897, 32899, 32888, 32892, 
+        0, 32768, 32896, 32897, 32899, 32888, 32892, 32894, 
+        0, 32768,     0, 32768, 32896,     0, 32768, 32896, 
+        0, 32768, 32896, 32898,     0, 32768, 32896,     0, 
+    32768, 32896, 32900,     0, 32768, 32896, 32900,     0, 
+    32768, 32896, 32904, 32902,     0, 32768, 32896,     0, 
+    32768, 32896, 32904,     0, 32768, 32896, 32904,     0, 
+    32768, 32896, 32904, 32906,     0, 32768, 32896, 32904, 
+        0, 32768, 32896, 32912, 32908,     0, 32768, 32896, 
+    32912, 32908,     0, 32768, 32896, 32912, 32913, 32910, 
+        0, 32768, 32896,     0, 32768, 32896, 32912,     0, 
+    32768, 32896, 32912,     0, 32768, 32896, 32912, 32914, 
+        0, 32768, 32896, 32912,     0, 32768, 32896, 32912, 
+    32916,     0, 32768, 32896, 32912, 32916,     0, 32768, 
+    32896, 32912, 32920, 32918,     0, 32768, 32896, 32912, 
+        0, 32768, 32896, 32928, 32920,     0, 32768, 32896, 
+    32928, 32920,     0, 32768, 32896, 32928, 32920, 32922, 
+        0, 32768, 32896, 32928, 32920,     0, 32768, 32896, 
+    32928, 32929, 32924,     0, 32768, 32896, 32928, 32929, 
+    32924,     0, 32768, 32896, 32928, 32929, 32924, 32926, 
+        0, 32768, 32896,     0, 32768, 32896, 32928,     0, 
+    32768, 32896, 32928,     0, 32768, 32896, 32928, 32930, 
+        0, 32768, 32896, 32928,     0, 32768, 32896, 32928, 
+    32932,     0, 32768, 32896, 32928, 32932,     0, 32768, 
+    32896, 32928, 32936, 32934,     0, 32768, 32896, 32928, 
+        0, 32768, 32896, 32928, 32936,     0, 32768, 32896, 
+    32928, 32936,     0, 32768, 32896, 32928, 32936, 32938, 
+        0, 32768, 32896, 32928, 32936,     0, 32768, 32896, 
+    32928, 32944, 32940,     0, 32768, 32896, 32928, 32944, 
+    32940,     0, 32768, 32896, 32928, 32944, 32945, 32942, 
+        0, 32768, 32896, 32928,     0, 32768, 32896, 32960, 
+    32944,     0, 32768, 32896, 32960, 32944,     0, 32768, 
+    32896, 32960, 32944, 32946,     0, 32768, 32896, 32960, 
+    32944,     0, 32768, 32896, 32960, 32944, 32948,     0, 
+    32768, 32896, 32960, 32944, 32948,     0, 32768, 32896, 
+    32960, 32944, 32952, 32950,     0, 32768, 32896, 32960, 
+    32944,     0, 32768, 32896, 32960, 32961, 32952,     0, 
+    32768, 32896, 32960, 32961, 32952,     0, 32768, 32896, 
+    32960, 32961, 32952, 32954,     0, 32768, 32896, 32960, 
+    32961, 32952,     0, 32768, 32896, 32960, 32961, 32952, 
+    32956,     0, 32768, 32896, 32960, 32961, 32963, 32956, 
+        0, 32768, 32896, 32960, 32961, 32963, 32956, 32958, 
+        0, 32768, 32896,     0, 32768, 33024, 32960,     0, 
+    32768, 33024, 32960,     0, 32768, 33024, 32960, 32962, 
+        0, 32768, 33024, 32960,     0, 32768, 33024, 32960, 
+    32964,     0, 32768, 33024, 32960, 32964,     0, 32768, 
+    33024, 32960, 32968, 32966,     0, 32768, 33024, 32960, 
+        0, 32768, 33024, 32960, 32968,     0, 32768, 33024, 
+    32960, 32968,     0, 32768, 33024, 32960, 32968, 32970, 
+        0, 32768, 33024, 32960, 32968,     0, 32768, 33024, 
+    32960, 32976, 32972,     0, 32768, 33024, 32960, 32976, 
+    32972,     0, 32768, 33024, 32960, 32976, 32977, 32974, 
+        0, 32768, 33024, 32960,     0, 32768, 33024, 32960, 
+    32976,     0, 32768, 33024, 32960, 32976,     0, 32768, 
+    33024, 32960, 32976, 32978,     0, 32768, 33024, 32960, 
+    32976,     0, 32768, 33024, 32960, 32976, 32980,     0, 
+    32768, 33024, 32960, 32976, 32980,     0, 32768, 33024, 
+    32960, 32976, 32984, 32982,     0, 32768, 33024, 32960, 
+    32976,     0, 32768, 33024, 32960, 32992, 32984,     0, 
+    32768, 33024, 32960, 32992, 32984,     0, 32768, 33024, 
+    32960, 32992, 32984, 32986,     0, 32768, 33024, 32960, 
+    32992, 32984,     0, 32768, 33024, 32960, 32992, 32993, 
+    32988,     0, 32768, 33024, 32960, 32992, 32993, 32988, 
+        0, 32768, 33024, 32960, 32992, 32993, 32988, 32990, 
+        0, 32768, 33024, 32960,     0, 32768, 33024, 33025, 
+    32992,     0, 32768, 33024, 33025, 32992,     0, 32768, 
+    33024, 33025, 32992, 32994,     0, 32768, 33024, 33025, 
+    32992,     0, 32768, 33024, 33025, 32992, 32996,     0, 
+    32768, 33024, 33025, 32992, 32996,     0, 32768, 33024, 
+    33025, 32992, 33000, 32998,     0, 32768, 33024, 33025, 
+    32992,     0, 32768, 33024, 33025, 32992, 33000,     0, 
+    32768, 33024, 33025, 32992, 33000,     0, 32768, 33024, 
+    33025, 32992, 33000, 33002,     0, 32768, 33024, 33025, 
+    32992, 33000,     0, 32768, 33024, 33025, 32992, 33008, 
+    33004,     0, 32768, 33024, 33025, 32992, 33008, 33004, 
+        0, 32768, 33024, 33025, 32992, 33008, 33009, 33006, 
+        0, 32768, 33024, 33025, 32992,     0, 32768, 33024, 
+    33025, 32992, 33008,     0, 32768, 33024, 33025, 33027, 
+    33008,     0, 32768, 33024, 33025, 33027, 33008, 33010, 
+        0, 32768, 33024, 33025, 33027, 33008,     0, 32768, 
+    33024, 33025, 33027, 33008, 33012,     0, 32768, 33024, 
+    33025, 33027, 33008, 33012,     0, 32768, 33024, 33025, 
+    33027, 33008, 33016, 33014,     0, 32768, 33024, 33025, 
+    33027, 33008,     0, 32768, 33024, 33025, 33027, 33008, 
+    33016,     0, 32768, 33024, 33025, 33027, 33008, 33016, 
+        0, 32768, 33024, 33025, 33027, 33008, 33016, 33018, 
+        0, 32768, 33024, 33025, 33027, 33031, 33016,     0, 
+    32768, 33024, 33025, 33027, 33031, 33016, 33020,     0, 
+    32768, 33024, 33025, 33027, 33031, 33016, 33020,     0, 
+    32768, 33024, 33025, 33027, 33031, 33016, 33020, 33022, 
+        0, 32768,     0, 32768, 33024,     0, 32768, 33024, 
+        0, 32768, 33024, 33026,     0, 32768, 33024,     0, 
+    32768, 33024, 33028,     0, 32768, 33024, 33028,     0, 
+    32768, 33024, 33032, 33030,     0, 32768, 33024,     0, 
+    32768, 33024, 33032,     0, 32768, 33024, 33032,     0, 
+    32768, 33024, 33032, 33034,     0, 32768, 33024, 33032, 
+        0, 32768, 33024, 33040, 33036,     0, 32768, 33024, 
+    33040, 33036,     0, 32768, 33024, 33040, 33041, 33038, 
+        0, 32768, 33024,     0, 32768, 33024, 33040,     0, 
+    32768, 33024, 33040,     0, 32768, 33024, 33040, 33042, 
+        0, 32768, 33024, 33040,     0, 32768, 33024, 33040, 
+    33044,     0, 32768, 33024, 33040, 33044,     0, 32768, 
+    33024, 33040, 33048, 33046,     0, 32768, 33024, 33040, 
+        0, 32768, 33024, 33056, 33048,     0, 32768, 33024, 
+    33056, 33048,     0, 32768, 33024, 33056, 33048, 33050, 
+        0, 32768, 33024, 33056, 33048,     0, 32768, 33024, 
+    33056, 33057, 33052,     0, 32768, 33024, 33056, 33057, 
+    33052,     0, 32768, 33024, 33056, 33057, 33052, 33054, 
+        0, 32768, 33024,     0, 32768, 33024, 33056,     0, 
+    32768, 33024, 33056,     0, 32768, 33024, 33056, 33058, 
+        0, 32768, 33024, 33056,     0, 32768, 33024, 33056, 
+    33060,     0, 32768, 33024, 33056, 33060,     0, 32768, 
+    33024, 33056, 33064, 33062,     0, 32768, 33024, 33056, 
+        0, 32768, 33024, 33056, 33064,     0, 32768, 33024, 
+    33056, 33064,     0, 32768, 33024, 33056, 33064, 33066, 
+        0, 32768, 33024, 33056, 33064,     0, 32768, 33024, 
+    33056, 33072, 33068,     0, 32768, 33024, 33056, 33072, 
+    33068,     0, 32768, 33024, 33056, 33072, 33073, 33070, 
+        0, 32768, 33024, 33056,     0, 32768, 33024, 33088, 
+    33072,     0, 32768, 33024, 33088, 33072,     0, 32768, 
+    33024, 33088, 33072, 33074,     0, 32768, 33024, 33088, 
+    33072,     0, 32768, 33024, 33088, 33072, 33076,     0, 
+    32768, 33024, 33088, 33072, 33076,     0, 32768, 33024, 
+    33088, 33072, 33080, 33078,     0, 32768, 33024, 33088, 
+    33072,     0, 32768, 33024, 33088, 33089, 33080,     0, 
+    32768, 33024, 33088, 33089, 33080,     0, 32768, 33024, 
+    33088, 33089, 33080, 33082,     0, 32768, 33024, 33088, 
+    33089, 33080,     0, 32768, 33024, 33088, 33089, 33080, 
+    33084,     0, 32768, 33024, 33088, 33089, 33091, 33084, 
+        0, 32768, 33024, 33088, 33089, 33091, 33084, 33086, 
+        0, 32768, 33024,     0, 32768, 33024, 33088,     0, 
+    32768, 33024, 33088,     0, 32768, 33024, 33088, 33090, 
+        0, 32768, 33024, 33088,     0, 32768, 33024, 33088, 
+    33092,     0, 32768, 33024, 33088, 33092,     0, 32768, 
+    33024, 33088, 33096, 33094,     0, 32768, 33024, 33088, 
+        0, 32768, 33024, 33088, 33096,     0, 32768, 33024, 
+    33088, 33096,     0, 32768, 33024, 33088, 33096, 33098, 
+        0, 32768, 33024, 33088, 33096,     0, 32768, 33024, 
+    33088, 33104, 33100,     0, 32768, 33024, 33088, 33104, 
+    33100,     0, 32768, 33024, 33088, 33104, 33105, 33102, 
+        0, 32768, 33024, 33088,     0, 32768, 33024, 33088, 
+    33104,     0, 32768, 33024, 33088, 33104,     0, 32768, 
+    33024, 33088, 33104, 33106,     0, 32768, 33024, 33088, 
+    33104,     0, 32768, 33024, 33088, 33104, 33108,     0, 
+    32768, 33024, 33088, 33104, 33108,     0, 32768, 33024, 
+    33088, 33104, 33112, 33110,     0, 32768, 33024, 33088, 
+    33104,     0, 32768, 33024, 33088, 33120, 33112,     0, 
+    32768, 33024, 33088, 33120, 33112,     0, 32768, 33024, 
+    33088, 33120, 33112, 33114,     0, 32768, 33024, 33088, 
+    33120, 33112,     0, 32768, 33024, 33088, 33120, 33121, 
+    33116,     0, 32768, 33024, 33088, 33120, 33121, 33116, 
+        0, 32768, 33024, 33088, 33120, 33121, 33116, 33118, 
+        0, 32768, 33024, 33088,     0, 32768, 33024, 33152, 
+    33120,     0, 32768, 33024, 33152, 33120,     0, 32768, 
+    33024, 33152, 33120, 33122,     0, 32768, 33024, 33152, 
+    33120,     0, 32768, 33024, 33152, 33120, 33124,     0, 
+    32768, 33024, 33152, 33120, 33124,     0, 32768, 33024, 
+    33152, 33120, 33128, 33126,     0, 32768, 33024, 33152, 
+    33120,     0, 32768, 33024, 33152, 33120, 33128,     0, 
+    32768, 33024, 33152, 33120, 33128,     0, 32768, 33024, 
+    33152, 33120, 33128, 33130,     0, 32768, 33024, 33152, 
+    33120, 33128,     0, 32768, 33024, 33152, 33120, 33136, 
+    33132,     0, 32768, 33024, 33152, 33120, 33136, 33132, 
+        0, 32768, 33024, 33152, 33120, 33136, 33137, 33134, 
+        0, 32768, 33024, 33152, 33120,     0, 32768, 33024, 
+    33152, 33153, 33136,     0, 32768, 33024, 33152, 33153, 
+    33136,     0, 32768, 33024, 33152, 33153, 33136, 33138, 
+        0, 32768, 33024, 33152, 33153, 33136,     0, 32768, 
+    33024, 33152, 33153, 33136, 33140,     0, 32768, 33024, 
+    33152, 33153, 33136, 33140,     0, 32768, 33024, 33152, 
+    33153, 33136, 33144, 33142,     0, 32768, 33024, 33152, 
+    33153, 33136,     0, 32768, 33024, 33152, 33153, 33136, 
+    33144,     0, 32768, 33024, 33152, 33153, 33155, 33144, 
+        0, 32768, 33024, 33152, 33153, 33155, 33144, 33146, 
+        0, 32768, 33024, 33152, 33153, 33155, 33144,     0, 
+    32768, 33024, 33152, 33153, 33155, 33144, 33148,     0, 
+    32768, 33024, 33152, 33153, 33155, 33144, 33148,     0, 
+    32768, 33024, 33152, 33153, 33155, 33144, 33148, 33150, 
+        0, 32768, 33024,     0, 32768, 33280, 33152,     0, 
+    32768, 33280, 33152,     0, 32768, 33280, 33152, 33154, 
+        0, 32768, 33280, 33152,     0, 32768, 33280, 33152, 
+    33156,     0, 32768, 33280, 33152, 33156,     0, 32768, 
+    33280, 33152, 33160, 33158,     0, 32768, 33280, 33152, 
+        0, 32768, 33280, 33152, 33160,     0, 32768, 33280, 
+    33152, 33160,     0, 32768, 33280, 33152, 33160, 33162, 
+        0, 32768, 33280, 33152, 33160,     0, 32768, 33280, 
+    33152, 33168, 33164,     0, 32768, 33280, 33152, 33168, 
+    33164,     0, 32768, 33280, 33152, 33168, 33169, 33166, 
+        0, 32768, 33280, 33152,     0, 32768, 33280, 33152, 
+    33168,     0, 32768, 33280, 33152, 33168,     0, 32768, 
+    33280, 33152, 33168, 33170,     0, 32768, 33280, 33152, 
+    33168,     0, 32768, 33280, 33152, 33168, 33172,     0, 
+    32768, 33280, 33152, 33168, 33172,     0, 32768, 33280, 
+    33152, 33168, 33176, 33174,     0, 32768, 33280, 33152, 
+    33168,     0, 32768, 33280, 33152, 33184, 33176,     0, 
+    32768, 33280, 33152, 33184, 33176,     0, 32768, 33280, 
+    33152, 33184, 33176, 33178,     0, 32768, 33280, 33152, 
+    33184, 33176,     0, 32768, 33280, 33152, 33184, 33185, 
+    33180,     0, 32768, 33280, 33152, 33184, 33185, 33180, 
+        0, 32768, 33280, 33152, 33184, 33185, 33180, 33182, 
+        0, 32768, 33280, 33152,     0, 32768, 33280, 33152, 
+    33184,     0, 32768, 33280, 33152, 33184,     0, 32768, 
+    33280, 33152, 33184, 33186,     0, 32768, 33280, 33152, 
+    33184,     0, 32768, 33280, 33152, 33184, 33188,     0, 
+    32768, 33280, 33152, 33184, 33188,     0, 32768, 33280, 
+    33152, 33184, 33192, 33190,     0, 32768, 33280, 33152, 
+    33184,     0, 32768, 33280, 33152, 33184, 33192,     0, 
+    32768, 33280, 33152, 33184, 33192,     0, 32768, 33280, 
+    33152, 33184, 33192, 33194,     0, 32768, 33280, 33152, 
+    33184, 33192,     0, 32768, 33280, 33152, 33184, 33200, 
+    33196,     0, 32768, 33280, 33152, 33184, 33200, 33196, 
+        0, 32768, 33280, 33152, 33184, 33200, 33201, 33198, 
+        0, 32768, 33280, 33152, 33184,     0, 32768, 33280, 
+    33152, 33216, 33200,     0, 32768, 33280, 33152, 33216, 
+    33200,     0, 32768, 33280, 33152, 33216, 33200, 33202, 
+        0, 32768, 33280, 33152, 33216, 33200,     0, 32768, 
+    33280, 33152, 33216, 33200, 33204,     0, 32768, 33280, 
+    33152, 33216, 33200, 33204,     0, 32768, 33280, 33152, 
+    33216, 33200, 33208, 33206,     0, 32768, 33280, 33152, 
+    33216, 33200,     0, 32768, 33280, 33152, 33216, 33217, 
+    33208,     0, 32768, 33280, 33152, 33216, 33217, 33208, 
+        0, 32768, 33280, 33152, 33216, 33217, 33208, 33210, 
+        0, 32768, 33280, 33152, 33216, 33217, 33208,     0, 
+    32768, 33280, 33152, 33216, 33217, 33208, 33212,     0, 
+    32768, 33280, 33152, 33216, 33217, 33219, 33212,     0, 
+    32768, 33280, 33152, 33216, 33217, 33219, 33212, 33214, 
+        0, 32768, 33280, 33152,     0, 32768, 33280, 33281, 
+    33216,     0, 32768, 33280, 33281, 33216,     0, 32768, 
+    33280, 33281, 33216, 33218,     0, 32768, 33280, 33281, 
+    33216,     0, 32768, 33280, 33281, 33216, 33220,     0, 
+    32768, 33280, 33281, 33216, 33220,     0, 32768, 33280, 
+    33281, 33216, 33224, 33222,     0, 32768, 33280, 33281, 
+    33216,     0, 32768, 33280, 33281, 33216, 33224,     0, 
+    32768, 33280, 33281, 33216, 33224,     0, 32768, 33280, 
+    33281, 33216, 33224, 33226,     0, 32768, 33280, 33281, 
+    33216, 33224,     0, 32768, 33280, 33281, 33216, 33232, 
+    33228,     0, 32768, 33280, 33281, 33216, 33232, 33228, 
+        0, 32768, 33280, 33281, 33216, 33232, 33233, 33230, 
+        0, 32768, 33280, 33281, 33216,     0, 32768, 33280, 
+    33281, 33216, 33232,     0, 32768, 33280, 33281, 33216, 
+    33232,     0, 32768, 33280, 33281, 33216, 33232, 33234, 
+        0, 32768, 33280, 33281, 33216, 33232,     0, 32768, 
+    33280, 33281, 33216, 33232, 33236,     0, 32768, 33280, 
+    33281, 33216, 33232, 33236,     0, 32768, 33280, 33281, 
+    33216, 33232, 33240, 33238,     0, 32768, 33280, 33281, 
+    33216, 33232,     0, 32768, 33280, 33281, 33216, 33248, 
+    33240,     0, 32768, 33280, 33281, 33216, 33248, 33240, 
+        0, 32768, 33280, 33281, 33216, 33248, 33240, 33242, 
+        0, 32768, 33280, 33281, 33216, 33248, 33240,     0, 
+    32768, 33280, 33281, 33216, 33248, 33249, 33244,     0, 
+    32768, 33280, 33281, 33216, 33248, 33249, 33244,     0, 
+    32768, 33280, 33281, 33216, 33248, 33249, 33244, 33246, 
+        0, 32768, 33280, 33281, 33216,     0, 32768, 33280, 
+    33281, 33216, 33248,     0, 32768, 33280, 33281, 33283, 
+    33248,     0, 32768, 33280, 33281, 33283, 33248, 33250, 
+        0, 32768, 33280, 33281, 33283, 33248,     0, 32768, 
+    33280, 33281, 33283, 33248, 33252,     0, 32768, 33280, 
+    33281, 33283, 33248, 33252,     0, 32768, 33280, 33281, 
+    33283, 33248, 33256, 33254,     0, 32768, 33280, 33281, 
+    33283, 33248,     0, 32768, 33280, 33281, 33283, 33248, 
+    33256,     0, 32768, 33280, 33281, 33283, 33248, 33256, 
+        0, 32768, 33280, 33281, 33283, 33248, 33256, 33258, 
+        0, 32768, 33280, 33281, 33283, 33248, 33256,     0, 
+    32768, 33280, 33281, 33283, 33248, 33264, 33260,     0, 
+    32768, 33280, 33281, 33283, 33248, 33264, 33260,     0, 
+    32768, 33280, 33281, 33283, 33248, 33264, 33265, 33262, 
+        0, 32768, 33280, 33281, 33283, 33248,     0, 32768, 
+    33280, 33281, 33283, 33248, 33264,     0, 32768, 33280, 
+    33281, 33283, 33248, 33264,     0, 32768, 33280, 33281, 
+    33283, 33248, 33264, 33266,     0, 32768, 33280, 33281, 
+    33283, 33287, 33264,     0, 32768, 33280, 33281, 33283, 
+    33287, 33264, 33268,     0, 32768, 33280, 33281, 33283, 
+    33287, 33264, 33268,     0, 32768, 33280, 33281, 33283, 
+    33287, 33264, 33272, 33270,     0, 32768, 33280, 33281, 
+    33283, 33287, 33264,     0, 32768, 33280, 33281, 33283, 
+    33287, 33264, 33272,     0, 32768, 33280, 33281, 33283, 
+    33287, 33264, 33272,     0, 32768, 33280, 33281, 33283, 
+    33287, 33264, 33272, 33274,     0, 32768, 33280, 33281, 
+    33283, 33287, 33264, 33272,     0, 32768, 33280, 33281, 
+    33283, 33287, 33264, 33272, 33276,     0, 32768, 33280, 
+    33281, 33283, 33287, 33264, 33272, 33276,     0, 32768, 
+    33280, 33281, 33283, 33287, 33264, 33272, 33276, 33278, 
+        0, 32768,     0, 32768, 33280,     0, 32768, 33280, 
+        0, 32768, 33280, 33282,     0, 32768, 33280,     0, 
+    32768, 33280, 33284,     0, 32768, 33280, 33284,     0, 
+    32768, 33280, 33288, 33286,     0, 32768, 33280,     0, 
+    32768, 33280, 33288,     0, 32768, 33280, 33288,     0, 
+    32768, 33280, 33288, 33290,     0, 32768, 33280, 33288, 
+        0, 32768, 33280, 33296, 33292,     0, 32768, 33280, 
+    33296, 33292,     0, 32768, 33280, 33296, 33297, 33294, 
+        0, 32768, 33280,     0, 32768, 33280, 33296,     0, 
+    32768, 33280, 33296,     0, 32768, 33280, 33296, 33298, 
+        0, 32768, 33280, 33296,     0, 32768, 33280, 33296, 
+    33300,     0, 32768, 33280, 33296, 33300,     0, 32768, 
+    33280, 33296, 33304, 33302,     0, 32768, 33280, 33296, 
+        0, 32768, 33280, 33312, 33304,     0, 32768, 33280, 
+    33312, 33304,     0, 32768, 33280, 33312, 33304, 33306, 
+        0, 32768, 33280, 33312, 33304,     0, 32768, 33280, 
+    33312, 33313, 33308,     0, 32768, 33280, 33312, 33313, 
+    33308,     0, 32768, 33280, 33312, 33313, 33308, 33310, 
+        0, 32768, 33280,     0, 32768, 33280, 33312,     0, 
+    32768, 33280, 33312,     0, 32768, 33280, 33312, 33314, 
+        0, 32768, 33280, 33312,     0, 32768, 33280, 33312, 
+    33316,     0, 32768, 33280, 33312, 33316,     0, 32768, 
+    33280, 33312, 33320, 33318,     0, 32768, 33280, 33312, 
+        0, 32768, 33280, 33312, 33320,     0, 32768, 33280, 
+    33312, 33320,     0, 32768, 33280, 33312, 33320, 33322, 
+        0, 32768, 33280, 33312, 33320,     0, 32768, 33280, 
+    33312, 33328, 33324,     0, 32768, 33280, 33312, 33328, 
+    33324,     0, 32768, 33280, 33312, 33328, 33329, 33326, 
+        0, 32768, 33280, 33312,     0, 32768, 33280, 33344, 
+    33328,     0, 32768, 33280, 33344, 33328,     0, 32768, 
+    33280, 33344, 33328, 33330,     0, 32768, 33280, 33344, 
+    33328,     0, 32768, 33280, 33344, 33328, 33332,     0, 
+    32768, 33280, 33344, 33328, 33332,     0, 32768, 33280, 
+    33344, 33328, 33336, 33334,     0, 32768, 33280, 33344, 
+    33328,     0, 32768, 33280, 33344, 33345, 33336,     0, 
+    32768, 33280, 33344, 33345, 33336,     0, 32768, 33280, 
+    33344, 33345, 33336, 33338,     0, 32768, 33280, 33344, 
+    33345, 33336,     0, 32768, 33280, 33344, 33345, 33336, 
+    33340,     0, 32768, 33280, 33344, 33345, 33347, 33340, 
+        0, 32768, 33280, 33344, 33345, 33347, 33340, 33342, 
+        0, 32768, 33280,     0, 32768, 33280, 33344,     0, 
+    32768, 33280, 33344,     0, 32768, 33280, 33344, 33346, 
+        0, 32768, 33280, 33344,     0, 32768, 33280, 33344, 
+    33348,     0, 32768, 33280, 33344, 33348,     0, 32768, 
+    33280, 33344, 33352, 33350,     0, 32768, 33280, 33344, 
+        0, 32768, 33280, 33344, 33352,     0, 32768, 33280, 
+    33344, 33352,     0, 32768, 33280, 33344, 33352, 33354, 
+        0, 32768, 33280, 33344, 33352,     0, 32768, 33280, 
+    33344, 33360, 33356,     0, 32768, 33280, 33344, 33360, 
+    33356,     0, 32768, 33280, 33344, 33360, 33361, 33358, 
+        0, 32768, 33280, 33344,     0, 32768, 33280, 33344, 
+    33360,     0, 32768, 33280, 33344, 33360,     0, 32768, 
+    33280, 33344, 33360, 33362,     0, 32768, 33280, 33344, 
+    33360,     0, 32768, 33280, 33344, 33360, 33364,     0, 
+    32768, 33280, 33344, 33360, 33364,     0, 32768, 33280, 
+    33344, 33360, 33368, 33366,     0, 32768, 33280, 33344, 
+    33360,     0, 32768, 33280, 33344, 33376, 33368,     0, 
+    32768, 33280, 33344, 33376, 33368,     0, 32768, 33280, 
+    33344, 33376, 33368, 33370,     0, 32768, 33280, 33344, 
+    33376, 33368,     0, 32768, 33280, 33344, 33376, 33377, 
+    33372,     0, 32768, 33280, 33344, 33376, 33377, 33372, 
+        0, 32768, 33280, 33344, 33376, 33377, 33372, 33374, 
+        0, 32768, 33280, 33344,     0, 32768, 33280, 33408, 
+    33376,     0, 32768, 33280, 33408, 33376,     0, 32768, 
+    33280, 33408, 33376, 33378,     0, 32768, 33280, 33408, 
+    33376,     0, 32768, 33280, 33408, 33376, 33380,     0, 
+    32768, 33280, 33408, 33376, 33380,     0, 32768, 33280, 
+    33408, 33376, 33384, 33382,     0, 32768, 33280, 33408, 
+    33376,     0, 32768, 33280, 33408, 33376, 33384,     0, 
+    32768, 33280, 33408, 33376, 33384,     0, 32768, 33280, 
+    33408, 33376, 33384, 33386,     0, 32768, 33280, 33408, 
+    33376, 33384,     0, 32768, 33280, 33408, 33376, 33392, 
+    33388,     0, 32768, 33280, 33408, 33376, 33392, 33388, 
+        0, 32768, 33280, 33408, 33376, 33392, 33393, 33390, 
+        0, 32768, 33280, 33408, 33376,     0, 32768, 33280, 
+    33408, 33409, 33392,     0, 32768, 33280, 33408, 33409, 
+    33392,     0, 32768, 33280, 33408, 33409, 33392, 33394, 
+        0, 32768, 33280, 33408, 33409, 33392,     0, 32768, 
+    33280, 33408, 33409, 33392, 33396,     0, 32768, 33280, 
+    33408, 33409, 33392, 33396,     0, 32768, 33280, 33408, 
+    33409, 33392, 33400, 33398,     0, 32768, 33280, 33408, 
+    33409, 33392,     0, 32768, 33280, 33408, 33409, 33392, 
+    33400,     0, 32768, 33280, 33408, 33409, 33411, 33400, 
+        0, 32768, 33280, 33408, 33409, 33411, 33400, 33402, 
+        0, 32768, 33280, 33408, 33409, 33411, 33400,     0, 
+    32768, 33280, 33408, 33409, 33411, 33400, 33404,     0, 
+    32768, 33280, 33408, 33409, 33411, 33400, 33404,     0, 
+    32768, 33280, 33408, 33409, 33411, 33400, 33404, 33406, 
+        0, 32768, 33280,     0, 32768, 33280, 33408,     0, 
+    32768, 33280, 33408,     0, 32768, 33280, 33408, 33410, 
+        0, 32768, 33280, 33408,     0, 32768, 33280, 33408, 
+    33412,     0, 32768, 33280, 33408, 33412,     0, 32768, 
+    33280, 33408, 33416, 33414,     0, 32768, 33280, 33408, 
+        0, 32768, 33280, 33408, 33416,     0, 32768, 33280, 
+    33408, 33416,     0, 32768, 33280, 33408, 33416, 33418, 
+        0, 32768, 33280, 33408, 33416,     0, 32768, 33280, 
+    33408, 33424, 33420,     0, 32768, 33280, 33408, 33424, 
+    33420,     0, 32768, 33280, 33408, 33424, 33425, 33422, 
+        0, 32768, 33280, 33408,     0, 32768, 33280, 33408, 
+    33424,     0, 32768, 33280, 33408, 33424,     0, 32768, 
+    33280, 33408, 33424, 33426,     0, 32768, 33280, 33408, 
+    33424,     0, 32768, 33280, 33408, 33424, 33428,     0, 
+    32768, 33280, 33408, 33424, 33428,     0, 32768, 33280, 
+    33408, 33424, 33432, 33430,     0, 32768, 33280, 33408, 
+    33424,     0, 32768, 33280, 33408, 33440, 33432,     0, 
+    32768, 33280, 33408, 33440, 33432,     0, 32768, 33280, 
+    33408, 33440, 33432, 33434,     0, 32768, 33280, 33408, 
+    33440, 33432,     0, 32768, 33280, 33408, 33440, 33441, 
+    33436,     0, 32768, 33280, 33408, 33440, 33441, 33436, 
+        0, 32768, 33280, 33408, 33440, 33441, 33436, 33438, 
+        0, 32768, 33280, 33408,     0, 32768, 33280, 33408, 
+    33440,     0, 32768, 33280, 33408, 33440,     0, 32768, 
+    33280, 33408, 33440, 33442,     0, 32768, 33280, 33408, 
+    33440,     0, 32768, 33280, 33408, 33440, 33444,     0, 
+    32768, 33280, 33408, 33440, 33444,     0, 32768, 33280, 
+    33408, 33440, 33448, 33446,     0, 32768, 33280, 33408, 
+    33440,     0, 32768, 33280, 33408, 33440, 33448,     0, 
+    32768, 33280, 33408, 33440, 33448,     0, 32768, 33280, 
+    33408, 33440, 33448, 33450,     0, 32768, 33280, 33408, 
+    33440, 33448,     0, 32768, 33280, 33408, 33440, 33456, 
+    33452,     0, 32768, 33280, 33408, 33440, 33456, 33452, 
+        0, 32768, 33280, 33408, 33440, 33456, 33457, 33454, 
+        0, 32768, 33280, 33408, 33440,     0, 32768, 33280, 
+    33408, 33472, 33456,     0, 32768, 33280, 33408, 33472, 
+    33456,     0, 32768, 33280, 33408, 33472, 33456, 33458, 
+        0, 32768, 33280, 33408, 33472, 33456,     0, 32768, 
+    33280, 33408, 33472, 33456, 33460,     0, 32768, 33280, 
+    33408, 33472, 33456, 33460,     0, 32768, 33280, 33408, 
+    33472, 33456, 33464, 33462,     0, 32768, 33280, 33408, 
+    33472, 33456,     0, 32768, 33280, 33408, 33472, 33473, 
+    33464,     0, 32768, 33280, 33408, 33472, 33473, 33464, 
+        0, 32768, 33280, 33408, 33472, 33473, 33464, 33466, 
+        0, 32768, 33280, 33408, 33472, 33473, 33464,     0, 
+    32768, 33280, 33408, 33472, 33473, 33464, 33468,     0, 
+    32768, 33280, 33408, 33472, 33473, 33475, 33468,     0, 
+    32768, 33280, 33408, 33472, 33473, 33475, 33468, 33470, 
+        0, 32768, 33280, 33408,     0, 32768, 33280, 33536, 
+    33472,     0, 32768, 33280, 33536, 33472,     0, 32768, 
+    33280, 33536, 33472, 33474,     0, 32768, 33280, 33536, 
+    33472,     0, 32768, 33280, 33536, 33472, 33476,     0, 
+    32768, 33280, 33536, 33472, 33476,     0, 32768, 33280, 
+    33536, 33472, 33480, 33478,     0, 32768, 33280, 33536, 
+    33472,     0, 32768, 33280, 33536, 33472, 33480,     0, 
+    32768, 33280, 33536, 33472, 33480,     0, 32768, 33280, 
+    33536, 33472, 33480, 33482,     0, 32768, 33280, 33536, 
+    33472, 33480,     0, 32768, 33280, 33536, 33472, 33488, 
+    33484,     0, 32768, 33280, 33536, 33472, 33488, 33484, 
+        0, 32768, 33280, 33536, 33472, 33488, 33489, 33486, 
+        0, 32768, 33280, 33536, 33472,     0, 32768, 33280, 
+    33536, 33472, 33488,     0, 32768, 33280, 33536, 33472, 
+    33488,     0, 32768, 33280, 33536, 33472, 33488, 33490, 
+        0, 32768, 33280, 33536, 33472, 33488,     0, 32768, 
+    33280, 33536, 33472, 33488, 33492,     0, 32768, 33280, 
+    33536, 33472, 33488, 33492,     0, 32768, 33280, 33536, 
+    33472, 33488, 33496, 33494,     0, 32768, 33280, 33536, 
+    33472, 33488,     0, 32768, 33280, 33536, 33472, 33504, 
+    33496,     0, 32768, 33280, 33536, 33472, 33504, 33496, 
+        0, 32768, 33280, 33536, 33472, 33504, 33496, 33498, 
+        0, 32768, 33280, 33536, 33472, 33504, 33496,     0, 
+    32768, 33280, 33536, 33472, 33504, 33505, 33500,     0, 
+    32768, 33280, 33536, 33472, 33504, 33505, 33500,     0, 
+    32768, 33280, 33536, 33472, 33504, 33505, 33500, 33502, 
+        0, 32768, 33280, 33536, 33472,     0, 32768, 33280, 
+    33536, 33537, 33504,     0, 32768, 33280, 33536, 33537, 
+    33504,     0, 32768, 33280, 33536, 33537, 33504, 33506, 
+        0, 32768, 33280, 33536, 33537, 33504,     0, 32768, 
+    33280, 33536, 33537, 33504, 33508,     0, 32768, 33280, 
+    33536, 33537, 33504, 33508,     0, 32768, 33280, 33536, 
+    33537, 33504, 33512, 33510,     0, 32768, 33280, 33536, 
+    33537, 33504,     0, 32768, 33280, 33536, 33537, 33504, 
+    33512,     0, 32768, 33280, 33536, 33537, 33504, 33512, 
+        0, 32768, 33280, 33536, 33537, 33504, 33512, 33514, 
+        0, 32768, 33280, 33536, 33537, 33504, 33512,     0, 
+    32768, 33280, 33536, 33537, 33504, 33520, 33516,     0, 
+    32768, 33280, 33536, 33537, 33504, 33520, 33516,     0, 
+    32768, 33280, 33536, 33537, 33504, 33520, 33521, 33518, 
+        0, 32768, 33280, 33536, 33537, 33504,     0, 32768, 
+    33280, 33536, 33537, 33504, 33520,     0, 32768, 33280, 
+    33536, 33537, 33539, 33520,     0, 32768, 33280, 33536, 
+    33537, 33539, 33520, 33522,     0, 32768, 33280, 33536, 
+    33537, 33539, 33520,     0, 32768, 33280, 33536, 33537, 
+    33539, 33520, 33524,     0, 32768, 33280, 33536, 33537, 
+    33539, 33520, 33524,     0, 32768, 33280, 33536, 33537, 
+    33539, 33520, 33528, 33526,     0, 32768, 33280, 33536, 
+    33537, 33539, 33520,     0, 32768, 33280, 33536, 33537, 
+    33539, 33520, 33528,     0, 32768, 33280, 33536, 33537, 
+    33539, 33520, 33528,     0, 32768, 33280, 33536, 33537, 
+    33539, 33520, 33528, 33530,     0, 32768, 33280, 33536, 
+    33537, 33539, 33543, 33528,     0, 32768, 33280, 33536, 
+    33537, 33539, 33543, 33528, 33532,     0, 32768, 33280, 
+    33536, 33537, 33539, 33543, 33528, 33532,     0, 32768, 
+    33280, 33536, 33537, 33539, 33543, 33528, 33532, 33534, 
+        0, 32768, 33280,     0, 32768, 33792, 33536,     0, 
+    32768, 33792, 33536,     0, 32768, 33792, 33536, 33538, 
+        0, 32768, 33792, 33536,     0, 32768, 33792, 33536, 
+    33540,     0, 32768, 33792, 33536, 33540,     0, 32768, 
+    33792, 33536, 33544, 33542,     0, 32768, 33792, 33536, 
+        0, 32768, 33792, 33536, 33544,     0, 32768, 33792, 
+    33536, 33544,     0, 32768, 33792, 33536, 33544, 33546, 
+        0, 32768, 33792, 33536, 33544,     0, 32768, 33792, 
+    33536, 33552, 33548,     0, 32768, 33792, 33536, 33552, 
+    33548,     0, 32768, 33792, 33536, 33552, 33553, 33550, 
+        0, 32768, 33792, 33536,     0, 32768, 33792, 33536, 
+    33552,     0, 32768, 33792, 33536, 33552,     0, 32768, 
+    33792, 33536, 33552, 33554,     0, 32768, 33792, 33536, 
+    33552,     0, 32768, 33792, 33536, 33552, 33556,     0, 
+    32768, 33792, 33536, 33552, 33556,     0, 32768, 33792, 
+    33536, 33552, 33560, 33558,     0, 32768, 33792, 33536, 
+    33552,     0, 32768, 33792, 33536, 33568, 33560,     0, 
+    32768, 33792, 33536, 33568, 33560,     0, 32768, 33792, 
+    33536, 33568, 33560, 33562,     0, 32768, 33792, 33536, 
+    33568, 33560,     0, 32768, 33792, 33536, 33568, 33569, 
+    33564,     0, 32768, 33792, 33536, 33568, 33569, 33564, 
+        0, 32768, 33792, 33536, 33568, 33569, 33564, 33566, 
+        0, 32768, 33792, 33536,     0, 32768, 33792, 33536, 
+    33568,     0, 32768, 33792, 33536, 33568,     0, 32768, 
+    33792, 33536, 33568, 33570,     0, 32768, 33792, 33536, 
+    33568,     0, 32768, 33792, 33536, 33568, 33572,     0, 
+    32768, 33792, 33536, 33568, 33572,     0, 32768, 33792, 
+    33536, 33568, 33576, 33574,     0, 32768, 33792, 33536, 
+    33568,     0, 32768, 33792, 33536, 33568, 33576,     0, 
+    32768, 33792, 33536, 33568, 33576,     0, 32768, 33792, 
+    33536, 33568, 33576, 33578,     0, 32768, 33792, 33536, 
+    33568, 33576,     0, 32768, 33792, 33536, 33568, 33584, 
+    33580,     0, 32768, 33792, 33536, 33568, 33584, 33580, 
+        0, 32768, 33792, 33536, 33568, 33584, 33585, 33582, 
+        0, 32768, 33792, 33536, 33568,     0, 32768, 33792, 
+    33536, 33600, 33584,     0, 32768, 33792, 33536, 33600, 
+    33584,     0, 32768, 33792, 33536, 33600, 33584, 33586, 
+        0, 32768, 33792, 33536, 33600, 33584,     0, 32768, 
+    33792, 33536, 33600, 33584, 33588,     0, 32768, 33792, 
+    33536, 33600, 33584, 33588,     0, 32768, 33792, 33536, 
+    33600, 33584, 33592, 33590,     0, 32768, 33792, 33536, 
+    33600, 33584,     0, 32768, 33792, 33536, 33600, 33601, 
+    33592,     0, 32768, 33792, 33536, 33600, 33601, 33592, 
+        0, 32768, 33792, 33536, 33600, 33601, 33592, 33594, 
+        0, 32768, 33792, 33536, 33600, 33601, 33592,     0, 
+    32768, 33792, 33536, 33600, 33601, 33592, 33596,     0, 
+    32768, 33792, 33536, 33600, 33601, 33603, 33596,     0, 
+    32768, 33792, 33536, 33600, 33601, 33603, 33596, 33598, 
+        0, 32768, 33792, 33536,     0, 32768, 33792, 33536, 
+    33600,     0, 32768, 33792, 33536, 33600,     0, 32768, 
+    33792, 33536, 33600, 33602,     0, 32768, 33792, 33536, 
+    33600,     0, 32768, 33792, 33536, 33600, 33604,     0, 
+    32768, 33792, 33536, 33600, 33604,     0, 32768, 33792, 
+    33536, 33600, 33608, 33606,     0, 32768, 33792, 33536, 
+    33600,     0, 32768, 33792, 33536, 33600, 33608,     0, 
+    32768, 33792, 33536, 33600, 33608,     0, 32768, 33792, 
+    33536, 33600, 33608, 33610,     0, 32768, 33792, 33536, 
+    33600, 33608,     0, 32768, 33792, 33536, 33600, 33616, 
+    33612,     0, 32768, 33792, 33536, 33600, 33616, 33612, 
+        0, 32768, 33792, 33536, 33600, 33616, 33617, 33614, 
+        0, 32768, 33792, 33536, 33600,     0, 32768, 33792, 
+    33536, 33600, 33616,     0, 32768, 33792, 33536, 33600, 
+    33616,     0, 32768, 33792, 33536, 33600, 33616, 33618, 
+        0, 32768, 33792, 33536, 33600, 33616,     0, 32768, 
+    33792, 33536, 33600, 33616, 33620,     0, 32768, 33792, 
+    33536, 33600, 33616, 33620,     0, 32768, 33792, 33536, 
+    33600, 33616, 33624, 33622,     0, 32768, 33792, 33536, 
+    33600, 33616,     0, 32768, 33792, 33536, 33600, 33632, 
+    33624,     0, 32768, 33792, 33536, 33600, 33632, 33624, 
+        0, 32768, 33792, 33536, 33600, 33632, 33624, 33626, 
+        0, 32768, 33792, 33536, 33600, 33632, 33624,     0, 
+    32768, 33792, 33536, 33600, 33632, 33633, 33628,     0, 
+    32768, 33792, 33536, 33600, 33632, 33633, 33628,     0, 
+    32768, 33792, 33536, 33600, 33632, 33633, 33628, 33630, 
+        0, 32768, 33792, 33536, 33600,     0, 32768, 33792, 
+    33536, 33664, 33632,     0, 32768, 33792, 33536, 33664, 
+    33632,     0, 32768, 33792, 33536, 33664, 33632, 33634, 
+        0, 32768, 33792, 33536, 33664, 33632,     0, 32768, 
+    33792, 33536, 33664, 33632, 33636,     0, 32768, 33792, 
+    33536, 33664, 33632, 33636,     0, 32768, 33792, 33536, 
+    33664, 33632, 33640, 33638,     0, 32768, 33792, 33536, 
+    33664, 33632,     0, 32768, 33792, 33536, 33664, 33632, 
+    33640,     0, 32768, 33792, 33536, 33664, 33632, 33640, 
+        0, 32768, 33792, 33536, 33664, 33632, 33640, 33642, 
+        0, 32768, 33792, 33536, 33664, 33632, 33640,     0, 
+    32768, 33792, 33536, 33664, 33632, 33648, 33644,     0, 
+    32768, 33792, 33536, 33664, 33632, 33648, 33644,     0, 
+    32768, 33792, 33536, 33664, 33632, 33648, 33649, 33646, 
+        0, 32768, 33792, 33536, 33664, 33632,     0, 32768, 
+    33792, 33536, 33664, 33665, 33648,     0, 32768, 33792, 
+    33536, 33664, 33665, 33648,     0, 32768, 33792, 33536, 
+    33664, 33665, 33648, 33650,     0, 32768, 33792, 33536, 
+    33664, 33665, 33648,     0, 32768, 33792, 33536, 33664, 
+    33665, 33648, 33652,     0, 32768, 33792, 33536, 33664, 
+    33665, 33648, 33652,     0, 32768, 33792, 33536, 33664, 
+    33665, 33648, 33656, 33654,     0, 32768, 33792, 33536, 
+    33664, 33665, 33648,     0, 32768, 33792, 33536, 33664, 
+    33665, 33648, 33656,     0, 32768, 33792, 33536, 33664, 
+    33665, 33667, 33656,     0, 32768, 33792, 33536, 33664, 
+    33665, 33667, 33656, 33658,     0, 32768, 33792, 33536, 
+    33664, 33665, 33667, 33656,     0, 32768, 33792, 33536, 
+    33664, 33665, 33667, 33656, 33660,     0, 32768, 33792, 
+    33536, 33664, 33665, 33667, 33656, 33660,     0, 32768, 
+    33792, 33536, 33664, 33665, 33667, 33656, 33660, 33662, 
+        0, 32768, 33792, 33536,     0, 32768, 33792, 33793, 
+    33664,     0, 32768, 33792, 33793, 33664,     0, 32768, 
+    33792, 33793, 33664, 33666,     0, 32768, 33792, 33793, 
+    33664,     0, 32768, 33792, 33793, 33664, 33668,     0, 
+    32768, 33792, 33793, 33664, 33668,     0, 32768, 33792, 
+    33793, 33664, 33672, 33670,     0, 32768, 33792, 33793, 
+    33664,     0, 32768, 33792, 33793, 33664, 33672,     0, 
+    32768, 33792, 33793, 33664, 33672,     0, 32768, 33792, 
+    33793, 33664, 33672, 33674,     0, 32768, 33792, 33793, 
+    33664, 33672,     0, 32768, 33792, 33793, 33664, 33680, 
+    33676,     0, 32768, 33792, 33793, 33664, 33680, 33676, 
+        0, 32768, 33792, 33793, 33664, 33680, 33681, 33678, 
+        0, 32768, 33792, 33793, 33664,     0, 32768, 33792, 
+    33793, 33664, 33680,     0, 32768, 33792, 33793, 33664, 
+    33680,     0, 32768, 33792, 33793, 33664, 33680, 33682, 
+        0, 32768, 33792, 33793, 33664, 33680,     0, 32768, 
+    33792, 33793, 33664, 33680, 33684,     0, 32768, 33792, 
+    33793, 33664, 33680, 33684,     0, 32768, 33792, 33793, 
+    33664, 33680, 33688, 33686,     0, 32768, 33792, 33793, 
+    33664, 33680,     0, 32768, 33792, 33793, 33664, 33696, 
+    33688,     0, 32768, 33792, 33793, 33664, 33696, 33688, 
+        0, 32768, 33792, 33793, 33664, 33696, 33688, 33690, 
+        0, 32768, 33792, 33793, 33664, 33696, 33688,     0, 
+    32768, 33792, 33793, 33664, 33696, 33697, 33692,     0, 
+    32768, 33792, 33793, 33664, 33696, 33697, 33692,     0, 
+    32768, 33792, 33793, 33664, 33696, 33697, 33692, 33694, 
+        0, 32768, 33792, 33793, 33664,     0, 32768, 33792, 
+    33793, 33664, 33696,     0, 32768, 33792, 33793, 33664, 
+    33696,     0, 32768, 33792, 33793, 33664, 33696, 33698, 
+        0, 32768, 33792, 33793, 33664, 33696,     0, 32768, 
+    33792, 33793, 33664, 33696, 33700,     0, 32768, 33792, 
+    33793, 33664, 33696, 33700,     0, 32768, 33792, 33793, 
+    33664, 33696, 33704, 33702,     0, 32768, 33792, 33793, 
+    33664, 33696,     0, 32768, 33792, 33793, 33664, 33696, 
+    33704,     0, 32768, 33792, 33793, 33664, 33696, 33704, 
+        0, 32768, 33792, 33793, 33664, 33696, 33704, 33706, 
+        0, 32768, 33792, 33793, 33664, 33696, 33704,     0, 
+    32768, 33792, 33793, 33664, 33696, 33712, 33708,     0, 
+    32768, 33792, 33793, 33664, 33696, 33712, 33708,     0, 
+    32768, 33792, 33793, 33664, 33696, 33712, 33713, 33710, 
+        0, 32768, 33792, 33793, 33664, 33696,     0, 32768, 
+    33792, 33793, 33664, 33728, 33712,     0, 32768, 33792, 
+    33793, 33664, 33728, 33712,     0, 32768, 33792, 33793, 
+    33664, 33728, 33712, 33714,     0, 32768, 33792, 33793, 
+    33664, 33728, 33712,     0, 32768, 33792, 33793, 33664, 
+    33728, 33712, 33716,     0, 32768, 33792, 33793, 33664, 
+    33728, 33712, 33716,     0, 32768, 33792, 33793, 33664, 
+    33728, 33712, 33720, 33718,     0, 32768, 33792, 33793, 
+    33664, 33728, 33712,     0, 32768, 33792, 33793, 33664, 
+    33728, 33729, 33720,     0, 32768, 33792, 33793, 33664, 
+    33728, 33729, 33720,     0, 32768, 33792, 33793, 33664, 
+    33728, 33729, 33720, 33722,     0, 32768, 33792, 33793, 
+    33664, 33728, 33729, 33720,     0, 32768, 33792, 33793, 
+    33664, 33728, 33729, 33720, 33724,     0, 32768, 33792, 
+    33793, 33664, 33728, 33729, 33731, 33724,     0, 32768, 
+    33792, 33793, 33664, 33728, 33729, 33731, 33724, 33726, 
+        0, 32768, 33792, 33793, 33664,     0, 32768, 33792, 
+    33793, 33664, 33728,     0, 32768, 33792, 33793, 33795, 
+    33728,     0, 32768, 33792, 33793, 33795, 33728, 33730, 
+        0, 32768, 33792, 33793, 33795, 33728,     0, 32768, 
+    33792, 33793, 33795, 33728, 33732,     0, 32768, 33792, 
+    33793, 33795, 33728, 33732,     0, 32768, 33792, 33793, 
+    33795, 33728, 33736, 33734,     0, 32768, 33792, 33793, 
+    33795, 33728,     0, 32768, 33792, 33793, 33795, 33728, 
+    33736,     0, 32768, 33792, 33793, 33795, 33728, 33736, 
+        0, 32768, 33792, 33793, 33795, 33728, 33736, 33738, 
+        0, 32768, 33792, 33793, 33795, 33728, 33736,     0, 
+    32768, 33792, 33793, 33795, 33728, 33744, 33740,     0, 
+    32768, 33792, 33793, 33795, 33728, 33744, 33740,     0, 
+    32768, 33792, 33793, 33795, 33728, 33744, 33745, 33742, 
+        0, 32768, 33792, 33793, 33795, 33728,     0, 32768, 
+    33792, 33793, 33795, 33728, 33744,     0, 32768, 33792, 
+    33793, 33795, 33728, 33744,     0, 32768, 33792, 33793, 
+    33795, 33728, 33744, 33746,     0, 32768, 33792, 33793, 
+    33795, 33728, 33744,     0, 32768, 33792, 33793, 33795, 
+    33728, 33744, 33748,     0, 32768, 33792, 33793, 33795, 
+    33728, 33744, 33748,     0, 32768, 33792, 33793, 33795, 
+    33728, 33744, 33752, 33750,     0, 32768, 33792, 33793, 
+    33795, 33728, 33744,     0, 32768, 33792, 33793, 33795, 
+    33728, 33760, 33752,     0, 32768, 33792, 33793, 33795, 
+    33728, 33760, 33752,     0, 32768, 33792, 33793, 33795, 
+    33728, 33760, 33752, 33754,     0, 32768, 33792, 33793, 
+    33795, 33728, 33760, 33752,     0, 32768, 33792, 33793, 
+    33795, 33728, 33760, 33761, 33756,     0, 32768, 33792, 
+    33793, 33795, 33728, 33760, 33761, 33756,     0, 32768, 
+    33792, 33793, 33795, 33728, 33760, 33761, 33756, 33758, 
+        0, 32768, 33792, 33793, 33795, 33728,     0, 32768, 
+    33792, 33793, 33795, 33728, 33760,     0, 32768, 33792, 
+    33793, 33795, 33728, 33760,     0, 32768, 33792, 33793, 
+    33795, 33728, 33760, 33762,     0, 32768, 33792, 33793, 
+    33795, 33799, 33760,     0, 32768, 33792, 33793, 33795, 
+    33799, 33760, 33764,     0, 32768, 33792, 33793, 33795, 
+    33799, 33760, 33764,     0, 32768, 33792, 33793, 33795, 
+    33799, 33760, 33768, 33766,     0, 32768, 33792, 33793, 
+    33795, 33799, 33760,     0, 32768, 33792, 33793, 33795, 
+    33799, 33760, 33768,     0, 32768, 33792, 33793, 33795, 
+    33799, 33760, 33768,     0, 32768, 33792, 33793, 33795, 
+    33799, 33760, 33768, 33770,     0, 32768, 33792, 33793, 
+    33795, 33799, 33760, 33768,     0, 32768, 33792, 33793, 
+    33795, 33799, 33760, 33776, 33772,     0, 32768, 33792, 
+    33793, 33795, 33799, 33760, 33776, 33772,     0, 32768, 
+    33792, 33793, 33795, 33799, 33760, 33776, 33777, 33774, 
+        0, 32768, 33792, 33793, 33795, 33799, 33760,     0, 
+    32768, 33792, 33793, 33795, 33799, 33760, 33776,     0, 
+    32768, 33792, 33793, 33795, 33799, 33760, 33776,     0, 
+    32768, 33792, 33793, 33795, 33799, 33760, 33776, 33778, 
+        0, 32768, 33792, 33793, 33795, 33799, 33760, 33776, 
+        0, 32768, 33792, 33793, 33795, 33799, 33760, 33776, 
+    33780,     0, 32768, 33792, 33793, 33795, 33799, 33760, 
+    33776, 33780,     0, 32768, 33792, 33793, 33795, 33799, 
+    33760, 33776, 33784, 33782,     0, 32768, 33792, 33793, 
+    33795, 33799, 33807, 33776,     0, 32768, 33792, 33793, 
+    33795, 33799, 33807, 33776, 33784,     0, 32768, 33792, 
+    33793, 33795, 33799, 33807, 33776, 33784,     0, 32768, 
+    33792, 33793, 33795, 33799, 33807, 33776, 33784, 33786, 
+        0, 32768, 33792, 33793, 33795, 33799, 33807, 33776, 
+    33784,     0, 32768, 33792, 33793, 33795, 33799, 33807, 
+    33776, 33784, 33788,     0, 32768, 33792, 33793, 33795, 
+    33799, 33807, 33776, 33784, 33788,     0, 32768, 33792, 
+    33793, 33795, 33799, 33807, 33776, 33784, 33788, 33790, 
+        0, 32768,     0, 32768, 33792,     0, 32768, 33792, 
+        0, 32768, 33792, 33794,     0, 32768, 33792,     0, 
+    32768, 33792, 33796,     0, 32768, 33792, 33796,     0, 
+    32768, 33792, 33800, 33798,     0, 32768, 33792,     0, 
+    32768, 33792, 33800,     0, 32768, 33792, 33800,     0, 
+    32768, 33792, 33800, 33802,     0, 32768, 33792, 33800, 
+        0, 32768, 33792, 33808, 33804,     0, 32768, 33792, 
+    33808, 33804,     0, 32768, 33792, 33808, 33809, 33806, 
+        0, 32768, 33792,     0, 32768, 33792, 33808,     0, 
+    32768, 33792, 33808,     0, 32768, 33792, 33808, 33810, 
+        0, 32768, 33792, 33808,     0, 32768, 33792, 33808, 
+    33812,     0, 32768, 33792, 33808, 33812,     0, 32768, 
+    33792, 33808, 33816, 33814,     0, 32768, 33792, 33808, 
+        0, 32768, 33792, 33824, 33816,     0, 32768, 33792, 
+    33824, 33816,     0, 32768, 33792, 33824, 33816, 33818, 
+        0, 32768, 33792, 33824, 33816,     0, 32768, 33792, 
+    33824, 33825, 33820,     0, 32768, 33792, 33824, 33825, 
+    33820,     0, 32768, 33792, 33824, 33825, 33820, 33822, 
+        0, 32768, 33792,     0, 32768, 33792, 33824,     0, 
+    32768, 33792, 33824,     0, 32768, 33792, 33824, 33826, 
+        0, 32768, 33792, 33824,     0, 32768, 33792, 33824, 
+    33828,     0, 32768, 33792, 33824, 33828,     0, 32768, 
+    33792, 33824, 33832, 33830,     0, 32768, 33792, 33824, 
+        0, 32768, 33792, 33824, 33832,     0, 32768, 33792, 
+    33824, 33832,     0, 32768, 33792, 33824, 33832, 33834, 
+        0, 32768, 33792, 33824, 33832,     0, 32768, 33792, 
+    33824, 33840, 33836,     0, 32768, 33792, 33824, 33840, 
+    33836,     0, 32768, 33792, 33824, 33840, 33841, 33838, 
+        0, 32768, 33792, 33824,     0, 32768, 33792, 33856, 
+    33840,     0, 32768, 33792, 33856, 33840,     0, 32768, 
+    33792, 33856, 33840, 33842,     0, 32768, 33792, 33856, 
+    33840,     0, 32768, 33792, 33856, 33840, 33844,     0, 
+    32768, 33792, 33856, 33840, 33844,     0, 32768, 33792, 
+    33856, 33840, 33848, 33846,     0, 32768, 33792, 33856, 
+    33840,     0, 32768, 33792, 33856, 33857, 33848,     0, 
+    32768, 33792, 33856, 33857, 33848,     0, 32768, 33792, 
+    33856, 33857, 33848, 33850,     0, 32768, 33792, 33856, 
+    33857, 33848,     0, 32768, 33792, 33856, 33857, 33848, 
+    33852,     0, 32768, 33792, 33856, 33857, 33859, 33852, 
+        0, 32768, 33792, 33856, 33857, 33859, 33852, 33854, 
+        0, 32768, 33792,     0, 32768, 33792, 33856,     0, 
+    32768, 33792, 33856,     0, 32768, 33792, 33856, 33858, 
+        0, 32768, 33792, 33856,     0, 32768, 33792, 33856, 
+    33860,     0, 32768, 33792, 33856, 33860,     0, 32768, 
+    33792, 33856, 33864, 33862,     0, 32768, 33792, 33856, 
+        0, 32768, 33792, 33856, 33864,     0, 32768, 33792, 
+    33856, 33864,     0, 32768, 33792, 33856, 33864, 33866, 
+        0, 32768, 33792, 33856, 33864,     0, 32768, 33792, 
+    33856, 33872, 33868,     0, 32768, 33792, 33856, 33872, 
+    33868,     0, 32768, 33792, 33856, 33872, 33873, 33870, 
+        0, 32768, 33792, 33856,     0, 32768, 33792, 33856, 
+    33872,     0, 32768, 33792, 33856, 33872,     0, 32768, 
+    33792, 33856, 33872, 33874,     0, 32768, 33792, 33856, 
+    33872,     0, 32768, 33792, 33856, 33872, 33876,     0, 
+    32768, 33792, 33856, 33872, 33876,     0, 32768, 33792, 
+    33856, 33872, 33880, 33878,     0, 32768, 33792, 33856, 
+    33872,     0, 32768, 33792, 33856, 33888, 33880,     0, 
+    32768, 33792, 33856, 33888, 33880,     0, 32768, 33792, 
+    33856, 33888, 33880, 33882,     0, 32768, 33792, 33856, 
+    33888, 33880,     0, 32768, 33792, 33856, 33888, 33889, 
+    33884,     0, 32768, 33792, 33856, 33888, 33889, 33884, 
+        0, 32768, 33792, 33856, 33888, 33889, 33884, 33886, 
+        0, 32768, 33792, 33856,     0, 32768, 33792, 33920, 
+    33888,     0, 32768, 33792, 33920, 33888,     0, 32768, 
+    33792, 33920, 33888, 33890,     0, 32768, 33792, 33920, 
+    33888,     0, 32768, 33792, 33920, 33888, 33892,     0, 
+    32768, 33792, 33920, 33888, 33892,     0, 32768, 33792, 
+    33920, 33888, 33896, 33894,     0, 32768, 33792, 33920, 
+    33888,     0, 32768, 33792, 33920, 33888, 33896,     0, 
+    32768, 33792, 33920, 33888, 33896,     0, 32768, 33792, 
+    33920, 33888, 33896, 33898,     0, 32768, 33792, 33920, 
+    33888, 33896,     0, 32768, 33792, 33920, 33888, 33904, 
+    33900,     0, 32768, 33792, 33920, 33888, 33904, 33900, 
+        0, 32768, 33792, 33920, 33888, 33904, 33905, 33902, 
+        0, 32768, 33792, 33920, 33888,     0, 32768, 33792, 
+    33920, 33921, 33904,     0, 32768, 33792, 33920, 33921, 
+    33904,     0, 32768, 33792, 33920, 33921, 33904, 33906, 
+        0, 32768, 33792, 33920, 33921, 33904,     0, 32768, 
+    33792, 33920, 33921, 33904, 33908,     0, 32768, 33792, 
+    33920, 33921, 33904, 33908,     0, 32768, 33792, 33920, 
+    33921, 33904, 33912, 33910,     0, 32768, 33792, 33920, 
+    33921, 33904,     0, 32768, 33792, 33920, 33921, 33904, 
+    33912,     0, 32768, 33792, 33920, 33921, 33923, 33912, 
+        0, 32768, 33792, 33920, 33921, 33923, 33912, 33914, 
+        0, 32768, 33792, 33920, 33921, 33923, 33912,     0, 
+    32768, 33792, 33920, 33921, 33923, 33912, 33916,     0, 
+    32768, 33792, 33920, 33921, 33923, 33912, 33916,     0, 
+    32768, 33792, 33920, 33921, 33923, 33912, 33916, 33918, 
+        0, 32768, 33792,     0, 32768, 33792, 33920,     0, 
+    32768, 33792, 33920,     0, 32768, 33792, 33920, 33922, 
+        0, 32768, 33792, 33920,     0, 32768, 33792, 33920, 
+    33924,     0, 32768, 33792, 33920, 33924,     0, 32768, 
+    33792, 33920, 33928, 33926,     0, 32768, 33792, 33920, 
+        0, 32768, 33792, 33920, 33928,     0, 32768, 33792, 
+    33920, 33928,     0, 32768, 33792, 33920, 33928, 33930, 
+        0, 32768, 33792, 33920, 33928,     0, 32768, 33792, 
+    33920, 33936, 33932,     0, 32768, 33792, 33920, 33936, 
+    33932,     0, 32768, 33792, 33920, 33936, 33937, 33934, 
+        0, 32768, 33792, 33920,     0, 32768, 33792, 33920, 
+    33936,     0, 32768, 33792, 33920, 33936,     0, 32768, 
+    33792, 33920, 33936, 33938,     0, 32768, 33792, 33920, 
+    33936,     0, 32768, 33792, 33920, 33936, 33940,     0, 
+    32768, 33792, 33920, 33936, 33940,     0, 32768, 33792, 
+    33920, 33936, 33944, 33942,     0, 32768, 33792, 33920, 
+    33936,     0, 32768, 33792, 33920, 33952, 33944,     0, 
+    32768, 33792, 33920, 33952, 33944,     0, 32768, 33792, 
+    33920, 33952, 33944, 33946,     0, 32768, 33792, 33920, 
+    33952, 33944,     0, 32768, 33792, 33920, 33952, 33953, 
+    33948,     0, 32768, 33792, 33920, 33952, 33953, 33948, 
+        0, 32768, 33792, 33920, 33952, 33953, 33948, 33950, 
+        0, 32768, 33792, 33920,     0, 32768, 33792, 33920, 
+    33952,     0, 32768, 33792, 33920, 33952,     0, 32768, 
+    33792, 33920, 33952, 33954,     0, 32768, 33792, 33920, 
+    33952,     0, 32768, 33792, 33920, 33952, 33956,     0, 
+    32768, 33792, 33920, 33952, 33956,     0, 32768, 33792, 
+    33920, 33952, 33960, 33958,     0, 32768, 33792, 33920, 
+    33952,     0, 32768, 33792, 33920, 33952, 33960,     0, 
+    32768, 33792, 33920, 33952, 33960,     0, 32768, 33792, 
+    33920, 33952, 33960, 33962,     0, 32768, 33792, 33920, 
+    33952, 33960,     0, 32768, 33792, 33920, 33952, 33968, 
+    33964,     0, 32768, 33792, 33920, 33952, 33968, 33964, 
+        0, 32768, 33792, 33920, 33952, 33968, 33969, 33966, 
+        0, 32768, 33792, 33920, 33952,     0, 32768, 33792, 
+    33920, 33984, 33968,     0, 32768, 33792, 33920, 33984, 
+    33968,     0, 32768, 33792, 33920, 33984, 33968, 33970, 
+        0, 32768, 33792, 33920, 33984, 33968,     0, 32768, 
+    33792, 33920, 33984, 33968, 33972,     0, 32768, 33792, 
+    33920, 33984, 33968, 33972,     0, 32768, 33792, 33920, 
+    33984, 33968, 33976, 33974,     0, 32768, 33792, 33920, 
+    33984, 33968,     0, 32768, 33792, 33920, 33984, 33985, 
+    33976,     0, 32768, 33792, 33920, 33984, 33985, 33976, 
+        0, 32768, 33792, 33920, 33984, 33985, 33976, 33978, 
+        0, 32768, 33792, 33920, 33984, 33985, 33976,     0, 
+    32768, 33792, 33920, 33984, 33985, 33976, 33980,     0, 
+    32768, 33792, 33920, 33984, 33985, 33987, 33980,     0, 
+    32768, 33792, 33920, 33984, 33985, 33987, 33980, 33982, 
+        0, 32768, 33792, 33920,     0, 32768, 33792, 34048, 
+    33984,     0, 32768, 33792, 34048, 33984,     0, 32768, 
+    33792, 34048, 33984, 33986,     0, 32768, 33792, 34048, 
+    33984,     0, 32768, 33792, 34048, 33984, 33988,     0, 
+    32768, 33792, 34048, 33984, 33988,     0, 32768, 33792, 
+    34048, 33984, 33992, 33990,     0, 32768, 33792, 34048, 
+    33984,     0, 32768, 33792, 34048, 33984, 33992,     0, 
+    32768, 33792, 34048, 33984, 33992,     0, 32768, 33792, 
+    34048, 33984, 33992, 33994,     0, 32768, 33792, 34048, 
+    33984, 33992,     0, 32768, 33792, 34048, 33984, 34000, 
+    33996,     0, 32768, 33792, 34048, 33984, 34000, 33996, 
+        0, 32768, 33792, 34048, 33984, 34000, 34001, 33998, 
+        0, 32768, 33792, 34048, 33984,     0, 32768, 33792, 
+    34048, 33984, 34000,     0, 32768, 33792, 34048, 33984, 
+    34000,     0, 32768, 33792, 34048, 33984, 34000, 34002, 
+        0, 32768, 33792, 34048, 33984, 34000,     0, 32768, 
+    33792, 34048, 33984, 34000, 34004,     0, 32768, 33792, 
+    34048, 33984, 34000, 34004,     0, 32768, 33792, 34048, 
+    33984, 34000, 34008, 34006,     0, 32768, 33792, 34048, 
+    33984, 34000,     0, 32768, 33792, 34048, 33984, 34016, 
+    34008,     0, 32768, 33792, 34048, 33984, 34016, 34008, 
+        0, 32768, 33792, 34048, 33984, 34016, 34008, 34010, 
+        0, 32768, 33792, 34048, 33984, 34016, 34008,     0, 
+    32768, 33792, 34048, 33984, 34016, 34017, 34012,     0, 
+    32768, 33792, 34048, 33984, 34016, 34017, 34012,     0, 
+    32768, 33792, 34048, 33984, 34016, 34017, 34012, 34014, 
+        0, 32768, 33792, 34048, 33984,     0, 32768, 33792, 
+    34048, 34049, 34016,     0, 32768, 33792, 34048, 34049, 
+    34016,     0, 32768, 33792, 34048, 34049, 34016, 34018, 
+        0, 32768, 33792, 34048, 34049, 34016,     0, 32768, 
+    33792, 34048, 34049, 34016, 34020,     0, 32768, 33792, 
+    34048, 34049, 34016, 34020,     0, 32768, 33792, 34048, 
+    34049, 34016, 34024, 34022,     0, 32768, 33792, 34048, 
+    34049, 34016,     0, 32768, 33792, 34048, 34049, 34016, 
+    34024,     0, 32768, 33792, 34048, 34049, 34016, 34024, 
+        0, 32768, 33792, 34048, 34049, 34016, 34024, 34026, 
+        0, 32768, 33792, 34048, 34049, 34016, 34024,     0, 
+    32768, 33792, 34048, 34049, 34016, 34032, 34028,     0, 
+    32768, 33792, 34048, 34049, 34016, 34032, 34028,     0, 
+    32768, 33792, 34048, 34049, 34016, 34032, 34033, 34030, 
+        0, 32768, 33792, 34048, 34049, 34016,     0, 32768, 
+    33792, 34048, 34049, 34016, 34032,     0, 32768, 33792, 
+    34048, 34049, 34051, 34032,     0, 32768, 33792, 34048, 
+    34049, 34051, 34032, 34034,     0, 32768, 33792, 34048, 
+    34049, 34051, 34032,     0, 32768, 33792, 34048, 34049, 
+    34051, 34032, 34036,     0, 32768, 33792, 34048, 34049, 
+    34051, 34032, 34036,     0, 32768, 33792, 34048, 34049, 
+    34051, 34032, 34040, 34038,     0, 32768, 33792, 34048, 
+    34049, 34051, 34032,     0, 32768, 33792, 34048, 34049, 
+    34051, 34032, 34040,     0, 32768, 33792, 34048, 34049, 
+    34051, 34032, 34040,     0, 32768, 33792, 34048, 34049, 
+    34051, 34032, 34040, 34042,     0, 32768, 33792, 34048, 
+    34049, 34051, 34055, 34040,     0, 32768, 33792, 34048, 
+    34049, 34051, 34055, 34040, 34044,     0, 32768, 33792, 
+    34048, 34049, 34051, 34055, 34040, 34044,     0, 32768, 
+    33792, 34048, 34049, 34051, 34055, 34040, 34044, 34046, 
+        0, 32768, 33792,     0, 32768, 33792, 34048,     0, 
+    32768, 33792, 34048,     0, 32768, 33792, 34048, 34050, 
+        0, 32768, 33792, 34048,     0, 32768, 33792, 34048, 
+    34052,     0, 32768, 33792, 34048, 34052,     0, 32768, 
+    33792, 34048, 34056, 34054,     0, 32768, 33792, 34048, 
+        0, 32768, 33792, 34048, 34056,     0, 32768, 33792, 
+    34048, 34056,     0, 32768, 33792, 34048, 34056, 34058, 
+        0, 32768, 33792, 34048, 34056,     0, 32768, 33792, 
+    34048, 34064, 34060,     0, 32768, 33792, 34048, 34064, 
+    34060,     0, 32768, 33792, 34048, 34064, 34065, 34062, 
+        0, 32768, 33792, 34048,     0, 32768, 33792, 34048, 
+    34064,     0, 32768, 33792, 34048, 34064,     0, 32768, 
+    33792, 34048, 34064, 34066,     0, 32768, 33792, 34048, 
+    34064,     0, 32768, 33792, 34048, 34064, 34068,     0, 
+    32768, 33792, 34048, 34064, 34068,     0, 32768, 33792, 
+    34048, 34064, 34072, 34070,     0, 32768, 33792, 34048, 
+    34064,     0, 32768, 33792, 34048, 34080, 34072,     0, 
+    32768, 33792, 34048, 34080, 34072,     0, 32768, 33792, 
+    34048, 34080, 34072, 34074,     0, 32768, 33792, 34048, 
+    34080, 34072,     0, 32768, 33792, 34048, 34080, 34081, 
+    34076,     0, 32768, 33792, 34048, 34080, 34081, 34076, 
+        0, 32768, 33792, 34048, 34080, 34081, 34076, 34078, 
+        0, 32768, 33792, 34048,     0, 32768, 33792, 34048, 
+    34080,     0, 32768, 33792, 34048, 34080,     0, 32768, 
+    33792, 34048, 34080, 34082,     0, 32768, 33792, 34048, 
+    34080,     0, 32768, 33792, 34048, 34080, 34084,     0, 
+    32768, 33792, 34048, 34080, 34084,     0, 32768, 33792, 
+    34048, 34080, 34088, 34086,     0, 32768, 33792, 34048, 
+    34080,     0, 32768, 33792, 34048, 34080, 34088,     0, 
+    32768, 33792, 34048, 34080, 34088,     0, 32768, 33792, 
+    34048, 34080, 34088, 34090,     0, 32768, 33792, 34048, 
+    34080, 34088,     0, 32768, 33792, 34048, 34080, 34096, 
+    34092,     0, 32768, 33792, 34048, 34080, 34096, 34092, 
+        0, 32768, 33792, 34048, 34080, 34096, 34097, 34094, 
+        0, 32768, 33792, 34048, 34080,     0, 32768, 33792, 
+    34048, 34112, 34096,     0, 32768, 33792, 34048, 34112, 
+    34096,     0, 32768, 33792, 34048, 34112, 34096, 34098, 
+        0, 32768, 33792, 34048, 34112, 34096,     0, 32768, 
+    33792, 34048, 34112, 34096, 34100,     0, 32768, 33792, 
+    34048, 34112, 34096, 34100,     0, 32768, 33792, 34048, 
+    34112, 34096, 34104, 34102,     0, 32768, 33792, 34048, 
+    34112, 34096,     0, 32768, 33792, 34048, 34112, 34113, 
+    34104,     0, 32768, 33792, 34048, 34112, 34113, 34104, 
+        0, 32768, 33792, 34048, 34112, 34113, 34104, 34106, 
+        0, 32768, 33792, 34048, 34112, 34113, 34104,     0, 
+    32768, 33792, 34048, 34112, 34113, 34104, 34108,     0, 
+    32768, 33792, 34048, 34112, 34113, 34115, 34108,     0, 
+    32768, 33792, 34048, 34112, 34113, 34115, 34108, 34110, 
+        0, 32768, 33792, 34048,     0, 32768, 33792, 34048, 
+    34112,     0, 32768, 33792, 34048, 34112,     0, 32768, 
+    33792, 34048, 34112, 34114,     0, 32768, 33792, 34048, 
+    34112,     0, 32768, 33792, 34048, 34112, 34116,     0, 
+    32768, 33792, 34048, 34112, 34116,     0, 32768, 33792, 
+    34048, 34112, 34120, 34118,     0, 32768, 33792, 34048, 
+    34112,     0, 32768, 33792, 34048, 34112, 34120,     0, 
+    32768, 33792, 34048, 34112, 34120,     0, 32768, 33792, 
+    34048, 34112, 34120, 34122,     0, 32768, 33792, 34048, 
+    34112, 34120,     0, 32768, 33792, 34048, 34112, 34128, 
+    34124,     0, 32768, 33792, 34048, 34112, 34128, 34124, 
+        0, 32768, 33792, 34048, 34112, 34128, 34129, 34126, 
+        0, 32768, 33792, 34048, 34112,     0, 32768, 33792, 
+    34048, 34112, 34128,     0, 32768, 33792, 34048, 34112, 
+    34128,     0, 32768, 33792, 34048, 34112, 34128, 34130, 
+        0, 32768, 33792, 34048, 34112, 34128,     0, 32768, 
+    33792, 34048, 34112, 34128, 34132,     0, 32768, 33792, 
+    34048, 34112, 34128, 34132,     0, 32768, 33792, 34048, 
+    34112, 34128, 34136, 34134,     0, 32768, 33792, 34048, 
+    34112, 34128,     0, 32768, 33792, 34048, 34112, 34144, 
+    34136,     0, 32768, 33792, 34048, 34112, 34144, 34136, 
+        0, 32768, 33792, 34048, 34112, 34144, 34136, 34138, 
+        0, 32768, 33792, 34048, 34112, 34144, 34136,     0, 
+    32768, 33792, 34048, 34112, 34144, 34145, 34140,     0, 
+    32768, 33792, 34048, 34112, 34144, 34145, 34140,     0, 
+    32768, 33792, 34048, 34112, 34144, 34145, 34140, 34142, 
+        0, 32768, 33792, 34048, 34112,     0, 32768, 33792, 
+    34048, 34176, 34144,     0, 32768, 33792, 34048, 34176, 
+    34144,     0, 32768, 33792, 34048, 34176, 34144, 34146, 
+        0, 32768, 33792, 34048, 34176, 34144,     0, 32768, 
+    33792, 34048, 34176, 34144, 34148,     0, 32768, 33792, 
+    34048, 34176, 34144, 34148,     0, 32768, 33792, 34048, 
+    34176, 34144, 34152, 34150,     0, 32768, 33792, 34048, 
+    34176, 34144,     0, 32768, 33792, 34048, 34176, 34144, 
+    34152,     0, 32768, 33792, 34048, 34176, 34144, 34152, 
+        0, 32768, 33792, 34048, 34176, 34144, 34152, 34154, 
+        0, 32768, 33792, 34048, 34176, 34144, 34152,     0, 
+    32768, 33792, 34048, 34176, 34144, 34160, 34156,     0, 
+    32768, 33792, 34048, 34176, 34144, 34160, 34156,     0, 
+    32768, 33792, 34048, 34176, 34144, 34160, 34161, 34158, 
+        0, 32768, 33792, 34048, 34176, 34144,     0, 32768, 
+    33792, 34048, 34176, 34177, 34160,     0, 32768, 33792, 
+    34048, 34176, 34177, 34160,     0, 32768, 33792, 34048, 
+    34176, 34177, 34160, 34162,     0, 32768, 33792, 34048, 
+    34176, 34177, 34160,     0, 32768, 33792, 34048, 34176, 
+    34177, 34160, 34164,     0, 32768, 33792, 34048, 34176, 
+    34177, 34160, 34164,     0, 32768, 33792, 34048, 34176, 
+    34177, 34160, 34168, 34166,     0, 32768, 33792, 34048, 
+    34176, 34177, 34160,     0, 32768, 33792, 34048, 34176, 
+    34177, 34160, 34168,     0, 32768, 33792, 34048, 34176, 
+    34177, 34179, 34168,     0, 32768, 33792, 34048, 34176, 
+    34177, 34179, 34168, 34170,     0, 32768, 33792, 34048, 
+    34176, 34177, 34179, 34168,     0, 32768, 33792, 34048, 
+    34176, 34177, 34179, 34168, 34172,     0, 32768, 33792, 
+    34048, 34176, 34177, 34179, 34168, 34172,     0, 32768, 
+    33792, 34048, 34176, 34177, 34179, 34168, 34172, 34174, 
+        0, 32768, 33792, 34048,     0, 32768, 33792, 34304, 
+    34176,     0, 32768, 33792, 34304, 34176,     0, 32768, 
+    33792, 34304, 34176, 34178,     0, 32768, 33792, 34304, 
+    34176,     0, 32768, 33792, 34304, 34176, 34180,     0, 
+    32768, 33792, 34304, 34176, 34180,     0, 32768, 33792, 
+    34304, 34176, 34184, 34182,     0, 32768, 33792, 34304, 
+    34176,     0, 32768, 33792, 34304, 34176, 34184,     0, 
+    32768, 33792, 34304, 34176, 34184,     0, 32768, 33792, 
+    34304, 34176, 34184, 34186,     0, 32768, 33792, 34304, 
+    34176, 34184,     0, 32768, 33792, 34304, 34176, 34192, 
+    34188,     0, 32768, 33792, 34304, 34176, 34192, 34188, 
+        0, 32768, 33792, 34304, 34176, 34192, 34193, 34190, 
+        0, 32768, 33792, 34304, 34176,     0, 32768, 33792, 
+    34304, 34176, 34192,     0, 32768, 33792, 34304, 34176, 
+    34192,     0, 32768, 33792, 34304, 34176, 34192, 34194, 
+        0, 32768, 33792, 34304, 34176, 34192,     0, 32768, 
+    33792, 34304, 34176, 34192, 34196,     0, 32768, 33792, 
+    34304, 34176, 34192, 34196,     0, 32768, 33792, 34304, 
+    34176, 34192, 34200, 34198,     0, 32768, 33792, 34304, 
+    34176, 34192,     0, 32768, 33792, 34304, 34176, 34208, 
+    34200,     0, 32768, 33792, 34304, 34176, 34208, 34200, 
+        0, 32768, 33792, 34304, 34176, 34208, 34200, 34202, 
+        0, 32768, 33792, 34304, 34176, 34208, 34200,     0, 
+    32768, 33792, 34304, 34176, 34208, 34209, 34204,     0, 
+    32768, 33792, 34304, 34176, 34208, 34209, 34204,     0, 
+    32768, 33792, 34304, 34176, 34208, 34209, 34204, 34206, 
+        0, 32768, 33792, 34304, 34176,     0, 32768, 33792, 
+    34304, 34176, 34208,     0, 32768, 33792, 34304, 34176, 
+    34208,     0, 32768, 33792, 34304, 34176, 34208, 34210, 
+        0, 32768, 33792, 34304, 34176, 34208,     0, 32768, 
+    33792, 34304, 34176, 34208, 34212,     0, 32768, 33792, 
+    34304, 34176, 34208, 34212,     0, 32768, 33792, 34304, 
+    34176, 34208, 34216, 34214,     0, 32768, 33792, 34304, 
+    34176, 34208,     0, 32768, 33792, 34304, 34176, 34208, 
+    34216,     0, 32768, 33792, 34304, 34176, 34208, 34216, 
+        0, 32768, 33792, 34304, 34176, 34208, 34216, 34218, 
+        0, 32768, 33792, 34304, 34176, 34208, 34216,     0, 
+    32768, 33792, 34304, 34176, 34208, 34224, 34220,     0, 
+    32768, 33792, 34304, 34176, 34208, 34224, 34220,     0, 
+    32768, 33792, 34304, 34176, 34208, 34224, 34225, 34222, 
+        0, 32768, 33792, 34304, 34176, 34208,     0, 32768, 
+    33792, 34304, 34176, 34240, 34224,     0, 32768, 33792, 
+    34304, 34176, 34240, 34224,     0, 32768, 33792, 34304, 
+    34176, 34240, 34224, 34226,     0, 32768, 33792, 34304, 
+    34176, 34240, 34224,     0, 32768, 33792, 34304, 34176, 
+    34240, 34224, 34228,     0, 32768, 33792, 34304, 34176, 
+    34240, 34224, 34228,     0, 32768, 33792, 34304, 34176, 
+    34240, 34224, 34232, 34230,     0, 32768, 33792, 34304, 
+    34176, 34240, 34224,     0, 32768, 33792, 34304, 34176, 
+    34240, 34241, 34232,     0, 32768, 33792, 34304, 34176, 
+    34240, 34241, 34232,     0, 32768, 33792, 34304, 34176, 
+    34240, 34241, 34232, 34234,     0, 32768, 33792, 34304, 
+    34176, 34240, 34241, 34232,     0, 32768, 33792, 34304, 
+    34176, 34240, 34241, 34232, 34236,     0, 32768, 33792, 
+    34304, 34176, 34240, 34241, 34243, 34236,     0, 32768, 
+    33792, 34304, 34176, 34240, 34241, 34243, 34236, 34238, 
+        0, 32768, 33792, 34304, 34176,     0, 32768, 33792, 
+    34304, 34305, 34240,     0, 32768, 33792, 34304, 34305, 
+    34240,     0, 32768, 33792, 34304, 34305, 34240, 34242, 
+        0, 32768, 33792, 34304, 34305, 34240,     0, 32768, 
+    33792, 34304, 34305, 34240, 34244,     0, 32768, 33792, 
+    34304, 34305, 34240, 34244,     0, 32768, 33792, 34304, 
+    34305, 34240, 34248, 34246,     0, 32768, 33792, 34304, 
+    34305, 34240,     0, 32768, 33792, 34304, 34305, 34240, 
+    34248,     0, 32768, 33792, 34304, 34305, 34240, 34248, 
+        0, 32768, 33792, 34304, 34305, 34240, 34248, 34250, 
+        0, 32768, 33792, 34304, 34305, 34240, 34248,     0, 
+    32768, 33792, 34304, 34305, 34240, 34256, 34252,     0, 
+    32768, 33792, 34304, 34305, 34240, 34256, 34252,     0, 
+    32768, 33792, 34304, 34305, 34240, 34256, 34257, 34254, 
+        0, 32768, 33792, 34304, 34305, 34240,     0, 32768, 
+    33792, 34304, 34305, 34240, 34256,     0, 32768, 33792, 
+    34304, 34305, 34240, 34256,     0, 32768, 33792, 34304, 
+    34305, 34240, 34256, 34258,     0, 32768, 33792, 34304, 
+    34305, 34240, 34256,     0, 32768, 33792, 34304, 34305, 
+    34240, 34256, 34260,     0, 32768, 33792, 34304, 34305, 
+    34240, 34256, 34260,     0, 32768, 33792, 34304, 34305, 
+    34240, 34256, 34264, 34262,     0, 32768, 33792, 34304, 
+    34305, 34240, 34256,     0, 32768, 33792, 34304, 34305, 
+    34240, 34272, 34264,     0, 32768, 33792, 34304, 34305, 
+    34240, 34272, 34264,     0, 32768, 33792, 34304, 34305, 
+    34240, 34272, 34264, 34266,     0, 32768, 33792, 34304, 
+    34305, 34240, 34272, 34264,     0, 32768, 33792, 34304, 
+    34305, 34240, 34272, 34273, 34268,     0, 32768, 33792, 
+    34304, 34305, 34240, 34272, 34273, 34268,     0, 32768, 
+    33792, 34304, 34305, 34240, 34272, 34273, 34268, 34270, 
+        0, 32768, 33792, 34304, 34305, 34240,     0, 32768, 
+    33792, 34304, 34305, 34240, 34272,     0, 32768, 33792, 
+    34304, 34305, 34307, 34272,     0, 32768, 33792, 34304, 
+    34305, 34307, 34272, 34274,     0, 32768, 33792, 34304, 
+    34305, 34307, 34272,     0, 32768, 33792, 34304, 34305, 
+    34307, 34272, 34276,     0, 32768, 33792, 34304, 34305, 
+    34307, 34272, 34276,     0, 32768, 33792, 34304, 34305, 
+    34307, 34272, 34280, 34278,     0, 32768, 33792, 34304, 
+    34305, 34307, 34272,     0, 32768, 33792, 34304, 34305, 
+    34307, 34272, 34280,     0, 32768, 33792, 34304, 34305, 
+    34307, 34272, 34280,     0, 32768, 33792, 34304, 34305, 
+    34307, 34272, 34280, 34282,     0, 32768, 33792, 34304, 
+    34305, 34307, 34272, 34280,     0, 32768, 33792, 34304, 
+    34305, 34307, 34272, 34288, 34284,     0, 32768, 33792, 
+    34304, 34305, 34307, 34272, 34288, 34284,     0, 32768, 
+    33792, 34304, 34305, 34307, 34272, 34288, 34289, 34286, 
+        0, 32768, 33792, 34304, 34305, 34307, 34272,     0, 
+    32768, 33792, 34304, 34305, 34307, 34272, 34288,     0, 
+    32768, 33792, 34304, 34305, 34307, 34272, 34288,     0, 
+    32768, 33792, 34304, 34305, 34307, 34272, 34288, 34290, 
+        0, 32768, 33792, 34304, 34305, 34307, 34311, 34288, 
+        0, 32768, 33792, 34304, 34305, 34307, 34311, 34288, 
+    34292,     0, 32768, 33792, 34304, 34305, 34307, 34311, 
+    34288, 34292,     0, 32768, 33792, 34304, 34305, 34307, 
+    34311, 34288, 34296, 34294,     0, 32768, 33792, 34304, 
+    34305, 34307, 34311, 34288,     0, 32768, 33792, 34304, 
+    34305, 34307, 34311, 34288, 34296,     0, 32768, 33792, 
+    34304, 34305, 34307, 34311, 34288, 34296,     0, 32768, 
+    33792, 34304, 34305, 34307, 34311, 34288, 34296, 34298, 
+        0, 32768, 33792, 34304, 34305, 34307, 34311, 34288, 
+    34296,     0, 32768, 33792, 34304, 34305, 34307, 34311, 
+    34288, 34296, 34300,     0, 32768, 33792, 34304, 34305, 
+    34307, 34311, 34288, 34296, 34300,     0, 32768, 33792, 
+    34304, 34305, 34307, 34311, 34288, 34296, 34300, 34302, 
+        0, 32768, 33792,     0, 32768, 34816, 34304,     0, 
+    32768, 34816, 34304,     0, 32768, 34816, 34304, 34306, 
+        0, 32768, 34816, 34304,     0, 32768, 34816, 34304, 
+    34308,     0, 32768, 34816, 34304, 34308,     0, 32768, 
+    34816, 34304, 34312, 34310,     0, 32768, 34816, 34304, 
+        0, 32768, 34816, 34304, 34312,     0, 32768, 34816, 
+    34304, 34312,     0, 32768, 34816, 34304, 34312, 34314, 
+        0, 32768, 34816, 34304, 34312,     0, 32768, 34816, 
+    34304, 34320, 34316,     0, 32768, 34816, 34304, 34320, 
+    34316,     0, 32768, 34816, 34304, 34320, 34321, 34318, 
+        0, 32768, 34816, 34304,     0, 32768, 34816, 34304, 
+    34320,     0, 32768, 34816, 34304, 34320,     0, 32768, 
+    34816, 34304, 34320, 34322,     0, 32768, 34816, 34304, 
+    34320,     0, 32768, 34816, 34304, 34320, 34324,     0, 
+    32768, 34816, 34304, 34320, 34324,     0, 32768, 34816, 
+    34304, 34320, 34328, 34326,     0, 32768, 34816, 34304, 
+    34320,     0, 32768, 34816, 34304, 34336, 34328,     0, 
+    32768, 34816, 34304, 34336, 34328,     0, 32768, 34816, 
+    34304, 34336, 34328, 34330,     0, 32768, 34816, 34304, 
+    34336, 34328,     0, 32768, 34816, 34304, 34336, 34337, 
+    34332,     0, 32768, 34816, 34304, 34336, 34337, 34332, 
+        0, 32768, 34816, 34304, 34336, 34337, 34332, 34334, 
+        0, 32768, 34816, 34304,     0, 32768, 34816, 34304, 
+    34336,     0, 32768, 34816, 34304, 34336,     0, 32768, 
+    34816, 34304, 34336, 34338,     0, 32768, 34816, 34304, 
+    34336,     0, 32768, 34816, 34304, 34336, 34340,     0, 
+    32768, 34816, 34304, 34336, 34340,     0, 32768, 34816, 
+    34304, 34336, 34344, 34342,     0, 32768, 34816, 34304, 
+    34336,     0, 32768, 34816, 34304, 34336, 34344,     0, 
+    32768, 34816, 34304, 34336, 34344,     0, 32768, 34816, 
+    34304, 34336, 34344, 34346,     0, 32768, 34816, 34304, 
+    34336, 34344,     0, 32768, 34816, 34304, 34336, 34352, 
+    34348,     0, 32768, 34816, 34304, 34336, 34352, 34348, 
+        0, 32768, 34816, 34304, 34336, 34352, 34353, 34350, 
+        0, 32768, 34816, 34304, 34336,     0, 32768, 34816, 
+    34304, 34368, 34352,     0, 32768, 34816, 34304, 34368, 
+    34352,     0, 32768, 34816, 34304, 34368, 34352, 34354, 
+        0, 32768, 34816, 34304, 34368, 34352,     0, 32768, 
+    34816, 34304, 34368, 34352, 34356,     0, 32768, 34816, 
+    34304, 34368, 34352, 34356,     0, 32768, 34816, 34304, 
+    34368, 34352, 34360, 34358,     0, 32768, 34816, 34304, 
+    34368, 34352,     0, 32768, 34816, 34304, 34368, 34369, 
+    34360,     0, 32768, 34816, 34304, 34368, 34369, 34360, 
+        0, 32768, 34816, 34304, 34368, 34369, 34360, 34362, 
+        0, 32768, 34816, 34304, 34368, 34369, 34360,     0, 
+    32768, 34816, 34304, 34368, 34369, 34360, 34364,     0, 
+    32768, 34816, 34304, 34368, 34369, 34371, 34364,     0, 
+    32768, 34816, 34304, 34368, 34369, 34371, 34364, 34366, 
+        0, 32768, 34816, 34304,     0, 32768, 34816, 34304, 
+    34368,     0, 32768, 34816, 34304, 34368,     0, 32768, 
+    34816, 34304, 34368, 34370,     0, 32768, 34816, 34304, 
+    34368,     0, 32768, 34816, 34304, 34368, 34372,     0, 
+    32768, 34816, 34304, 34368, 34372,     0, 32768, 34816, 
+    34304, 34368, 34376, 34374,     0, 32768, 34816, 34304, 
+    34368,     0, 32768, 34816, 34304, 34368, 34376,     0, 
+    32768, 34816, 34304, 34368, 34376,     0, 32768, 34816, 
+    34304, 34368, 34376, 34378,     0, 32768, 34816, 34304, 
+    34368, 34376,     0, 32768, 34816, 34304, 34368, 34384, 
+    34380,     0, 32768, 34816, 34304, 34368, 34384, 34380, 
+        0, 32768, 34816, 34304, 34368, 34384, 34385, 34382, 
+        0, 32768, 34816, 34304, 34368,     0, 32768, 34816, 
+    34304, 34368, 34384,     0, 32768, 34816, 34304, 34368, 
+    34384,     0, 32768, 34816, 34304, 34368, 34384, 34386, 
+        0, 32768, 34816, 34304, 34368, 34384,     0, 32768, 
+    34816, 34304, 34368, 34384, 34388,     0, 32768, 34816, 
+    34304, 34368, 34384, 34388,     0, 32768, 34816, 34304, 
+    34368, 34384, 34392, 34390,     0, 32768, 34816, 34304, 
+    34368, 34384,     0, 32768, 34816, 34304, 34368, 34400, 
+    34392,     0, 32768, 34816, 34304, 34368, 34400, 34392, 
+        0, 32768, 34816, 34304, 34368, 34400, 34392, 34394, 
+        0, 32768, 34816, 34304, 34368, 34400, 34392,     0, 
+    32768, 34816, 34304, 34368, 34400, 34401, 34396,     0, 
+    32768, 34816, 34304, 34368, 34400, 34401, 34396,     0, 
+    32768, 34816, 34304, 34368, 34400, 34401, 34396, 34398, 
+        0, 32768, 34816, 34304, 34368,     0, 32768, 34816, 
+    34304, 34432, 34400,     0, 32768, 34816, 34304, 34432, 
+    34400,     0, 32768, 34816, 34304, 34432, 34400, 34402, 
+        0, 32768, 34816, 34304, 34432, 34400,     0, 32768, 
+    34816, 34304, 34432, 34400, 34404,     0, 32768, 34816, 
+    34304, 34432, 34400, 34404,     0, 32768, 34816, 34304, 
+    34432, 34400, 34408, 34406,     0, 32768, 34816, 34304, 
+    34432, 34400,     0, 32768, 34816, 34304, 34432, 34400, 
+    34408,     0, 32768, 34816, 34304, 34432, 34400, 34408, 
+        0, 32768, 34816, 34304, 34432, 34400, 34408, 34410, 
+        0, 32768, 34816, 34304, 34432, 34400, 34408,     0, 
+    32768, 34816, 34304, 34432, 34400, 34416, 34412,     0, 
+    32768, 34816, 34304, 34432, 34400, 34416, 34412,     0, 
+    32768, 34816, 34304, 34432, 34400, 34416, 34417, 34414, 
+        0, 32768, 34816, 34304, 34432, 34400,     0, 32768, 
+    34816, 34304, 34432, 34433, 34416,     0, 32768, 34816, 
+    34304, 34432, 34433, 34416,     0, 32768, 34816, 34304, 
+    34432, 34433, 34416, 34418,     0, 32768, 34816, 34304, 
+    34432, 34433, 34416,     0, 32768, 34816, 34304, 34432, 
+    34433, 34416, 34420,     0, 32768, 34816, 34304, 34432, 
+    34433, 34416, 34420,     0, 32768, 34816, 34304, 34432, 
+    34433, 34416, 34424, 34422,     0, 32768, 34816, 34304, 
+    34432, 34433, 34416,     0, 32768, 34816, 34304, 34432, 
+    34433, 34416, 34424,     0, 32768, 34816, 34304, 34432, 
+    34433, 34435, 34424,     0, 32768, 34816, 34304, 34432, 
+    34433, 34435, 34424, 34426,     0, 32768, 34816, 34304, 
+    34432, 34433, 34435, 34424,     0, 32768, 34816, 34304, 
+    34432, 34433, 34435, 34424, 34428,     0, 32768, 34816, 
+    34304, 34432, 34433, 34435, 34424, 34428,     0, 32768, 
+    34816, 34304, 34432, 34433, 34435, 34424, 34428, 34430, 
+        0, 32768, 34816, 34304,     0, 32768, 34816, 34304, 
+    34432,     0, 32768, 34816, 34304, 34432,     0, 32768, 
+    34816, 34304, 34432, 34434,     0, 32768, 34816, 34304, 
+    34432,     0, 32768, 34816, 34304, 34432, 34436,     0, 
+    32768, 34816, 34304, 34432, 34436,     0, 32768, 34816, 
+    34304, 34432, 34440, 34438,     0, 32768, 34816, 34304, 
+    34432,     0, 32768, 34816, 34304, 34432, 34440,     0, 
+    32768, 34816, 34304, 34432, 34440,     0, 32768, 34816, 
+    34304, 34432, 34440, 34442,     0, 32768, 34816, 34304, 
+    34432, 34440,     0, 32768, 34816, 34304, 34432, 34448, 
+    34444,     0, 32768, 34816, 34304, 34432, 34448, 34444, 
+        0, 32768, 34816, 34304, 34432, 34448, 34449, 34446, 
+        0, 32768, 34816, 34304, 34432,     0, 32768, 34816, 
+    34304, 34432, 34448,     0, 32768, 34816, 34304, 34432, 
+    34448,     0, 32768, 34816, 34304, 34432, 34448, 34450, 
+        0, 32768, 34816, 34304, 34432, 34448,     0, 32768, 
+    34816, 34304, 34432, 34448, 34452,     0, 32768, 34816, 
+    34304, 34432, 34448, 34452,     0, 32768, 34816, 34304, 
+    34432, 34448, 34456, 34454,     0, 32768, 34816, 34304, 
+    34432, 34448,     0, 32768, 34816, 34304, 34432, 34464, 
+    34456,     0, 32768, 34816, 34304, 34432, 34464, 34456, 
+        0, 32768, 34816, 34304, 34432, 34464, 34456, 34458, 
+        0, 32768, 34816, 34304, 34432, 34464, 34456,     0, 
+    32768, 34816, 34304, 34432, 34464, 34465, 34460,     0, 
+    32768, 34816, 34304, 34432, 34464, 34465, 34460,     0, 
+    32768, 34816, 34304, 34432, 34464, 34465, 34460, 34462, 
+        0, 32768, 34816, 34304, 34432,     0, 32768, 34816, 
+    34304, 34432, 34464,     0, 32768, 34816, 34304, 34432, 
+    34464,     0, 32768, 34816, 34304, 34432, 34464, 34466, 
+        0, 32768, 34816, 34304, 34432, 34464,     0, 32768, 
+    34816, 34304, 34432, 34464, 34468,     0, 32768, 34816, 
+    34304, 34432, 34464, 34468,     0, 32768, 34816, 34304, 
+    34432, 34464, 34472, 34470,     0, 32768, 34816, 34304, 
+    34432, 34464,     0, 32768, 34816, 34304, 34432, 34464, 
+    34472,     0, 32768, 34816, 34304, 34432, 34464, 34472, 
+        0, 32768, 34816, 34304, 34432, 34464, 34472, 34474, 
+        0, 32768, 34816, 34304, 34432, 34464, 34472,     0, 
+    32768, 34816, 34304, 34432, 34464, 34480, 34476,     0, 
+    32768, 34816, 34304, 34432, 34464, 34480, 34476,     0, 
+    32768, 34816, 34304, 34432, 34464, 34480, 34481, 34478, 
+        0, 32768, 34816, 34304, 34432, 34464,     0, 32768, 
+    34816, 34304, 34432, 34496, 34480,     0, 32768, 34816, 
+    34304, 34432, 34496, 34480,     0, 32768, 34816, 34304, 
+    34432, 34496, 34480, 34482,     0, 32768, 34816, 34304, 
+    34432, 34496, 34480,     0, 32768, 34816, 34304, 34432, 
+    34496, 34480, 34484,     0, 32768, 34816, 34304, 34432, 
+    34496, 34480, 34484,     0, 32768, 34816, 34304, 34432, 
+    34496, 34480, 34488, 34486,     0, 32768, 34816, 34304, 
+    34432, 34496, 34480,     0, 32768, 34816, 34304, 34432, 
+    34496, 34497, 34488,     0, 32768, 34816, 34304, 34432, 
+    34496, 34497, 34488,     0, 32768, 34816, 34304, 34432, 
+    34496, 34497, 34488, 34490,     0, 32768, 34816, 34304, 
+    34432, 34496, 34497, 34488,     0, 32768, 34816, 34304, 
+    34432, 34496, 34497, 34488, 34492,     0, 32768, 34816, 
+    34304, 34432, 34496, 34497, 34499, 34492,     0, 32768, 
+    34816, 34304, 34432, 34496, 34497, 34499, 34492, 34494, 
+        0, 32768, 34816, 34304, 34432,     0, 32768, 34816, 
+    34304, 34560, 34496,     0, 32768, 34816, 34304, 34560, 
+    34496,     0, 32768, 34816, 34304, 34560, 34496, 34498, 
+        0, 32768, 34816, 34304, 34560, 34496,     0, 32768, 
+    34816, 34304, 34560, 34496, 34500,     0, 32768, 34816, 
+    34304, 34560, 34496, 34500,     0, 32768, 34816, 34304, 
+    34560, 34496, 34504, 34502,     0, 32768, 34816, 34304, 
+    34560, 34496,     0, 32768, 34816, 34304, 34560, 34496, 
+    34504,     0, 32768, 34816, 34304, 34560, 34496, 34504, 
+        0, 32768, 34816, 34304, 34560, 34496, 34504, 34506, 
+        0, 32768, 34816, 34304, 34560, 34496, 34504,     0, 
+    32768, 34816, 34304, 34560, 34496, 34512, 34508,     0, 
+    32768, 34816, 34304, 34560, 34496, 34512, 34508,     0, 
+    32768, 34816, 34304, 34560, 34496, 34512, 34513, 34510, 
+        0, 32768, 34816, 34304, 34560, 34496,     0, 32768, 
+    34816, 34304, 34560, 34496, 34512,     0, 32768, 34816, 
+    34304, 34560, 34496, 34512,     0, 32768, 34816, 34304, 
+    34560, 34496, 34512, 34514,     0, 32768, 34816, 34304, 
+    34560, 34496, 34512,     0, 32768, 34816, 34304, 34560, 
+    34496, 34512, 34516,     0, 32768, 34816, 34304, 34560, 
+    34496, 34512, 34516,     0, 32768, 34816, 34304, 34560, 
+    34496, 34512, 34520, 34518,     0, 32768, 34816, 34304, 
+    34560, 34496, 34512,     0, 32768, 34816, 34304, 34560, 
+    34496, 34528, 34520,     0, 32768, 34816, 34304, 34560, 
+    34496, 34528, 34520,     0, 32768, 34816, 34304, 34560, 
+    34496, 34528, 34520, 34522,     0, 32768, 34816, 34304, 
+    34560, 34496, 34528, 34520,     0, 32768, 34816, 34304, 
+    34560, 34496, 34528, 34529, 34524,     0, 32768, 34816, 
+    34304, 34560, 34496, 34528, 34529, 34524,     0, 32768, 
+    34816, 34304, 34560, 34496, 34528, 34529, 34524, 34526, 
+        0, 32768, 34816, 34304, 34560, 34496,     0, 32768, 
+    34816, 34304, 34560, 34561, 34528,     0, 32768, 34816, 
+    34304, 34560, 34561, 34528,     0, 32768, 34816, 34304, 
+    34560, 34561, 34528, 34530,     0, 32768, 34816, 34304, 
+    34560, 34561, 34528,     0, 32768, 34816, 34304, 34560, 
+    34561, 34528, 34532,     0, 32768, 34816, 34304, 34560, 
+    34561, 34528, 34532,     0, 32768, 34816, 34304, 34560, 
+    34561, 34528, 34536, 34534,     0, 32768, 34816, 34304, 
+    34560, 34561, 34528,     0, 32768, 34816, 34304, 34560, 
+    34561, 34528, 34536,     0, 32768, 34816, 34304, 34560, 
+    34561, 34528, 34536,     0, 32768, 34816, 34304, 34560, 
+    34561, 34528, 34536, 34538,     0, 32768, 34816, 34304, 
+    34560, 34561, 34528, 34536,     0, 32768, 34816, 34304, 
+    34560, 34561, 34528, 34544, 34540,     0, 32768, 34816, 
+    34304, 34560, 34561, 34528, 34544, 34540,     0, 32768, 
+    34816, 34304, 34560, 34561, 34528, 34544, 34545, 34542, 
+        0, 32768, 34816, 34304, 34560, 34561, 34528,     0, 
+    32768, 34816, 34304, 34560, 34561, 34528, 34544,     0, 
+    32768, 34816, 34304, 34560, 34561, 34563, 34544,     0, 
+    32768, 34816, 34304, 34560, 34561, 34563, 34544, 34546, 
+        0, 32768, 34816, 34304, 34560, 34561, 34563, 34544, 
+        0, 32768, 34816, 34304, 34560, 34561, 34563, 34544, 
+    34548,     0, 32768, 34816, 34304, 34560, 34561, 34563, 
+    34544, 34548,     0, 32768, 34816, 34304, 34560, 34561, 
+    34563, 34544, 34552, 34550,     0, 32768, 34816, 34304, 
+    34560, 34561, 34563, 34544,     0, 32768, 34816, 34304, 
+    34560, 34561, 34563, 34544, 34552,     0, 32768, 34816, 
+    34304, 34560, 34561, 34563, 34544, 34552,     0, 32768, 
+    34816, 34304, 34560, 34561, 34563, 34544, 34552, 34554, 
+        0, 32768, 34816, 34304, 34560, 34561, 34563, 34567, 
+    34552,     0, 32768, 34816, 34304, 34560, 34561, 34563, 
+    34567, 34552, 34556,     0, 32768, 34816, 34304, 34560, 
+    34561, 34563, 34567, 34552, 34556,     0, 32768, 34816, 
+    34304, 34560, 34561, 34563, 34567, 34552, 34556, 34558, 
+        0, 32768, 34816, 34304,     0, 32768, 34816, 34304, 
+    34560,     0, 32768, 34816, 34817, 34560,     0, 32768, 
+    34816, 34817, 34560, 34562,     0, 32768, 34816, 34817, 
+    34560,     0, 32768, 34816, 34817, 34560, 34564,     0, 
+    32768, 34816, 34817, 34560, 34564,     0, 32768, 34816, 
+    34817, 34560, 34568, 34566,     0, 32768, 34816, 34817, 
+    34560,     0, 32768, 34816, 34817, 34560, 34568,     0, 
+    32768, 34816, 34817, 34560, 34568,     0, 32768, 34816, 
+    34817, 34560, 34568, 34570,     0, 32768, 34816, 34817, 
+    34560, 34568,     0, 32768, 34816, 34817, 34560, 34576, 
+    34572,     0, 32768, 34816, 34817, 34560, 34576, 34572, 
+        0, 32768, 34816, 34817, 34560, 34576, 34577, 34574, 
+        0, 32768, 34816, 34817, 34560,     0, 32768, 34816, 
+    34817, 34560, 34576,     0, 32768, 34816, 34817, 34560, 
+    34576,     0, 32768, 34816, 34817, 34560, 34576, 34578, 
+        0, 32768, 34816, 34817, 34560, 34576,     0, 32768, 
+    34816, 34817, 34560, 34576, 34580,     0, 32768, 34816, 
+    34817, 34560, 34576, 34580,     0, 32768, 34816, 34817, 
+    34560, 34576, 34584, 34582,     0, 32768, 34816, 34817, 
+    34560, 34576,     0, 32768, 34816, 34817, 34560, 34592, 
+    34584,     0, 32768, 34816, 34817, 34560, 34592, 34584, 
+        0, 32768, 34816, 34817, 34560, 34592, 34584, 34586, 
+        0, 32768, 34816, 34817, 34560, 34592, 34584,     0, 
+    32768, 34816, 34817, 34560, 34592, 34593, 34588,     0, 
+    32768, 34816, 34817, 34560, 34592, 34593, 34588,     0, 
+    32768, 34816, 34817, 34560, 34592, 34593, 34588, 34590, 
+        0, 32768, 34816, 34817, 34560,     0, 32768, 34816, 
+    34817, 34560, 34592,     0, 32768, 34816, 34817, 34560, 
+    34592,     0, 32768, 34816, 34817, 34560, 34592, 34594, 
+        0, 32768, 34816, 34817, 34560, 34592,     0, 32768, 
+    34816, 34817, 34560, 34592, 34596,     0, 32768, 34816, 
+    34817, 34560, 34592, 34596,     0, 32768, 34816, 34817, 
+    34560, 34592, 34600, 34598,     0, 32768, 34816, 34817, 
+    34560, 34592,     0, 32768, 34816, 34817, 34560, 34592, 
+    34600,     0, 32768, 34816, 34817, 34560, 34592, 34600, 
+        0, 32768, 34816, 34817, 34560, 34592, 34600, 34602, 
+        0, 32768, 34816, 34817, 34560, 34592, 34600,     0, 
+    32768, 34816, 34817, 34560, 34592, 34608, 34604,     0, 
+    32768, 34816, 34817, 34560, 34592, 34608, 34604,     0, 
+    32768, 34816, 34817, 34560, 34592, 34608, 34609, 34606, 
+        0, 32768, 34816, 34817, 34560, 34592,     0, 32768, 
+    34816, 34817, 34560, 34624, 34608,     0, 32768, 34816, 
+    34817, 34560, 34624, 34608,     0, 32768, 34816, 34817, 
+    34560, 34624, 34608, 34610,     0, 32768, 34816, 34817, 
+    34560, 34624, 34608,     0, 32768, 34816, 34817, 34560, 
+    34624, 34608, 34612,     0, 32768, 34816, 34817, 34560, 
+    34624, 34608, 34612,     0, 32768, 34816, 34817, 34560, 
+    34624, 34608, 34616, 34614,     0, 32768, 34816, 34817, 
+    34560, 34624, 34608,     0, 32768, 34816, 34817, 34560, 
+    34624, 34625, 34616,     0, 32768, 34816, 34817, 34560, 
+    34624, 34625, 34616,     0, 32768, 34816, 34817, 34560, 
+    34624, 34625, 34616, 34618,     0, 32768, 34816, 34817, 
+    34560, 34624, 34625, 34616,     0, 32768, 34816, 34817, 
+    34560, 34624, 34625, 34616, 34620,     0, 32768, 34816, 
+    34817, 34560, 34624, 34625, 34627, 34620,     0, 32768, 
+    34816, 34817, 34560, 34624, 34625, 34627, 34620, 34622, 
+        0, 32768, 34816, 34817, 34560,     0, 32768, 34816, 
+    34817, 34560, 34624,     0, 32768, 34816, 34817, 34560, 
+    34624,     0, 32768, 34816, 34817, 34560, 34624, 34626, 
+        0, 32768, 34816, 34817, 34560, 34624,     0, 32768, 
+    34816, 34817, 34560, 34624, 34628,     0, 32768, 34816, 
+    34817, 34560, 34624, 34628,     0, 32768, 34816, 34817, 
+    34560, 34624, 34632, 34630,     0, 32768, 34816, 34817, 
+    34560, 34624,     0, 32768, 34816, 34817, 34560, 34624, 
+    34632,     0, 32768, 34816, 34817, 34560, 34624, 34632, 
+        0, 32768, 34816, 34817, 34560, 34624, 34632, 34634, 
+        0, 32768, 34816, 34817, 34560, 34624, 34632,     0, 
+    32768, 34816, 34817, 34560, 34624, 34640, 34636,     0, 
+    32768, 34816, 34817, 34560, 34624, 34640, 34636,     0, 
+    32768, 34816, 34817, 34560, 34624, 34640, 34641, 34638, 
+        0, 32768, 34816, 34817, 34560, 34624,     0, 32768, 
+    34816, 34817, 34560, 34624, 34640,     0, 32768, 34816, 
+    34817, 34560, 34624, 34640,     0, 32768, 34816, 34817, 
+    34560, 34624, 34640, 34642,     0, 32768, 34816, 34817, 
+    34560, 34624, 34640,     0, 32768, 34816, 34817, 34560, 
+    34624, 34640, 34644,     0, 32768, 34816, 34817, 34560, 
+    34624, 34640, 34644,     0, 32768, 34816, 34817, 34560, 
+    34624, 34640, 34648, 34646,     0, 32768, 34816, 34817, 
+    34560, 34624, 34640,     0, 32768, 34816, 34817, 34560, 
+    34624, 34656, 34648,     0, 32768, 34816, 34817, 34560, 
+    34624, 34656, 34648,     0, 32768, 34816, 34817, 34560, 
+    34624, 34656, 34648, 34650,     0, 32768, 34816, 34817, 
+    34560, 34624, 34656, 34648,     0, 32768, 34816, 34817, 
+    34560, 34624, 34656, 34657, 34652,     0, 32768, 34816, 
+    34817, 34560, 34624, 34656, 34657, 34652,     0, 32768, 
+    34816, 34817, 34560, 34624, 34656, 34657, 34652, 34654, 
+        0, 32768, 34816, 34817, 34560, 34624,     0, 32768, 
+    34816, 34817, 34560, 34688, 34656,     0, 32768, 34816, 
+    34817, 34560, 34688, 34656,     0, 32768, 34816, 34817, 
+    34560, 34688, 34656, 34658,     0, 32768, 34816, 34817, 
+    34560, 34688, 34656,     0, 32768, 34816, 34817, 34560, 
+    34688, 34656, 34660,     0, 32768, 34816, 34817, 34560, 
+    34688, 34656, 34660,     0, 32768, 34816, 34817, 34560, 
+    34688, 34656, 34664, 34662,     0, 32768, 34816, 34817, 
+    34560, 34688, 34656,     0, 32768, 34816, 34817, 34560, 
+    34688, 34656, 34664,     0, 32768, 34816, 34817, 34560, 
+    34688, 34656, 34664,     0, 32768, 34816, 34817, 34560, 
+    34688, 34656, 34664, 34666,     0, 32768, 34816, 34817, 
+    34560, 34688, 34656, 34664,     0, 32768, 34816, 34817, 
+    34560, 34688, 34656, 34672, 34668,     0, 32768, 34816, 
+    34817, 34560, 34688, 34656, 34672, 34668,     0, 32768, 
+    34816, 34817, 34560, 34688, 34656, 34672, 34673, 34670, 
+        0, 32768, 34816, 34817, 34560, 34688, 34656,     0, 
+    32768, 34816, 34817, 34560, 34688, 34689, 34672,     0, 
+    32768, 34816, 34817, 34560, 34688, 34689, 34672,     0, 
+    32768, 34816, 34817, 34560, 34688, 34689, 34672, 34674, 
+        0, 32768, 34816, 34817, 34560, 34688, 34689, 34672, 
+        0, 32768, 34816, 34817, 34560, 34688, 34689, 34672, 
+    34676,     0, 32768, 34816, 34817, 34560, 34688, 34689, 
+    34672, 34676,     0, 32768, 34816, 34817, 34560, 34688, 
+    34689, 34672, 34680, 34678,     0, 32768, 34816, 34817, 
+    34560, 34688, 34689, 34672,     0, 32768, 34816, 34817, 
+    34560, 34688, 34689, 34672, 34680,     0, 32768, 34816, 
+    34817, 34560, 34688, 34689, 34691, 34680,     0, 32768, 
+    34816, 34817, 34560, 34688, 34689, 34691, 34680, 34682, 
+        0, 32768, 34816, 34817, 34560, 34688, 34689, 34691, 
+    34680,     0, 32768, 34816, 34817, 34560, 34688, 34689, 
+    34691, 34680, 34684,     0, 32768, 34816, 34817, 34560, 
+    34688, 34689, 34691, 34680, 34684,     0, 32768, 34816, 
+    34817, 34560, 34688, 34689, 34691, 34680, 34684, 34686, 
+        0, 32768, 34816, 34817, 34560,     0, 32768, 34816, 
+    34817, 34560, 34688,     0, 32768, 34816, 34817, 34560, 
+    34688,     0, 32768, 34816, 34817, 34560, 34688, 34690, 
+        0, 32768, 34816, 34817, 34819, 34688,     0, 32768, 
+    34816, 34817, 34819, 34688, 34692,     0, 32768, 34816, 
+    34817, 34819, 34688, 34692,     0, 32768, 34816, 34817, 
+    34819, 34688, 34696, 34694,     0, 32768, 34816, 34817, 
+    34819, 34688,     0, 32768, 34816, 34817, 34819, 34688, 
+    34696,     0, 32768, 34816, 34817, 34819, 34688, 34696, 
+        0, 32768, 34816, 34817, 34819, 34688, 34696, 34698, 
+        0, 32768, 34816, 34817, 34819, 34688, 34696,     0, 
+    32768, 34816, 34817, 34819, 34688, 34704, 34700,     0, 
+    32768, 34816, 34817, 34819, 34688, 34704, 34700,     0, 
+    32768, 34816, 34817, 34819, 34688, 34704, 34705, 34702, 
+        0, 32768, 34816, 34817, 34819, 34688,     0, 32768, 
+    34816, 34817, 34819, 34688, 34704,     0, 32768, 34816, 
+    34817, 34819, 34688, 34704,     0, 32768, 34816, 34817, 
+    34819, 34688, 34704, 34706,     0, 32768, 34816, 34817, 
+    34819, 34688, 34704,     0, 32768, 34816, 34817, 34819, 
+    34688, 34704, 34708,     0, 32768, 34816, 34817, 34819, 
+    34688, 34704, 34708,     0, 32768, 34816, 34817, 34819, 
+    34688, 34704, 34712, 34710,     0, 32768, 34816, 34817, 
+    34819, 34688, 34704,     0, 32768, 34816, 34817, 34819, 
+    34688, 34720, 34712,     0, 32768, 34816, 34817, 34819, 
+    34688, 34720, 34712,     0, 32768, 34816, 34817, 34819, 
+    34688, 34720, 34712, 34714,     0, 32768, 34816, 34817, 
+    34819, 34688, 34720, 34712,     0, 32768, 34816, 34817, 
+    34819, 34688, 34720, 34721, 34716,     0, 32768, 34816, 
+    34817, 34819, 34688, 34720, 34721, 34716,     0, 32768, 
+    34816, 34817, 34819, 34688, 34720, 34721, 34716, 34718, 
+        0, 32768, 34816, 34817, 34819, 34688,     0, 32768, 
+    34816, 34817, 34819, 34688, 34720,     0, 32768, 34816, 
+    34817, 34819, 34688, 34720,     0, 32768, 34816, 34817, 
+    34819, 34688, 34720, 34722,     0, 32768, 34816, 34817, 
+    34819, 34688, 34720,     0, 32768, 34816, 34817, 34819, 
+    34688, 34720, 34724,     0, 32768, 34816, 34817, 34819, 
+    34688, 34720, 34724,     0, 32768, 34816, 34817, 34819, 
+    34688, 34720, 34728, 34726,     0, 32768, 34816, 34817, 
+    34819, 34688, 34720,     0, 32768, 34816, 34817, 34819, 
+    34688, 34720, 34728,     0, 32768, 34816, 34817, 34819, 
+    34688, 34720, 34728,     0, 32768, 34816, 34817, 34819, 
+    34688, 34720, 34728, 34730,     0, 32768, 34816, 34817, 
+    34819, 34688, 34720, 34728,     0, 32768, 34816, 34817, 
+    34819, 34688, 34720, 34736, 34732,     0, 32768, 34816, 
+    34817, 34819, 34688, 34720, 34736, 34732,     0, 32768, 
+    34816, 34817, 34819, 34688, 34720, 34736, 34737, 34734, 
+        0, 32768, 34816, 34817, 34819, 34688, 34720,     0, 
+    32768, 34816, 34817, 34819, 34688, 34752, 34736,     0, 
+    32768, 34816, 34817, 34819, 34688, 34752, 34736,     0, 
+    32768, 34816, 34817, 34819, 34688, 34752, 34736, 34738, 
+        0, 32768, 34816, 34817, 34819, 34688, 34752, 34736, 
+        0, 32768, 34816, 34817, 34819, 34688, 34752, 34736, 
+    34740,     0, 32768, 34816, 34817, 34819, 34688, 34752, 
+    34736, 34740,     0, 32768, 34816, 34817, 34819, 34688, 
+    34752, 34736, 34744, 34742,     0, 32768, 34816, 34817, 
+    34819, 34688, 34752, 34736,     0, 32768, 34816, 34817, 
+    34819, 34688, 34752, 34753, 34744,     0, 32768, 34816, 
+    34817, 34819, 34688, 34752, 34753, 34744,     0, 32768, 
+    34816, 34817, 34819, 34688, 34752, 34753, 34744, 34746, 
+        0, 32768, 34816, 34817, 34819, 34688, 34752, 34753, 
+    34744,     0, 32768, 34816, 34817, 34819, 34688, 34752, 
+    34753, 34744, 34748,     0, 32768, 34816, 34817, 34819, 
+    34688, 34752, 34753, 34755, 34748,     0, 32768, 34816, 
+    34817, 34819, 34688, 34752, 34753, 34755, 34748, 34750, 
+        0, 32768, 34816, 34817, 34819, 34688,     0, 32768, 
+    34816, 34817, 34819, 34688, 34752,     0, 32768, 34816, 
+    34817, 34819, 34688, 34752,     0, 32768, 34816, 34817, 
+    34819, 34688, 34752, 34754,     0, 32768, 34816, 34817, 
+    34819, 34688, 34752,     0, 32768, 34816, 34817, 34819, 
+    34688, 34752, 34756,     0, 32768, 34816, 34817, 34819, 
+    34688, 34752, 34756,     0, 32768, 34816, 34817, 34819, 
+    34688, 34752, 34760, 34758,     0, 32768, 34816, 34817, 
+    34819, 34823, 34752,     0, 32768, 34816, 34817, 34819, 
+    34823, 34752, 34760,     0, 32768, 34816, 34817, 34819, 
+    34823, 34752, 34760,     0, 32768, 34816, 34817, 34819, 
+    34823, 34752, 34760, 34762,     0, 32768, 34816, 34817, 
+    34819, 34823, 34752, 34760,     0, 32768, 34816, 34817, 
+    34819, 34823, 34752, 34768, 34764,     0, 32768, 34816, 
+    34817, 34819, 34823, 34752, 34768, 34764,     0, 32768, 
+    34816, 34817, 34819, 34823, 34752, 34768, 34769, 34766, 
+        0, 32768, 34816, 34817, 34819, 34823, 34752,     0, 
+    32768, 34816, 34817, 34819, 34823, 34752, 34768,     0, 
+    32768, 34816, 34817, 34819, 34823, 34752, 34768,     0, 
+    32768, 34816, 34817, 34819, 34823, 34752, 34768, 34770, 
+        0, 32768, 34816, 34817, 34819, 34823, 34752, 34768, 
+        0, 32768, 34816, 34817, 34819, 34823, 34752, 34768, 
+    34772,     0, 32768, 34816, 34817, 34819, 34823, 34752, 
+    34768, 34772,     0, 32768, 34816, 34817, 34819, 34823, 
+    34752, 34768, 34776, 34774,     0, 32768, 34816, 34817, 
+    34819, 34823, 34752, 34768,     0, 32768, 34816, 34817, 
+    34819, 34823, 34752, 34784, 34776,     0, 32768, 34816, 
+    34817, 34819, 34823, 34752, 34784, 34776,     0, 32768, 
+    34816, 34817, 34819, 34823, 34752, 34784, 34776, 34778, 
+        0, 32768, 34816, 34817, 34819, 34823, 34752, 34784, 
+    34776,     0, 32768, 34816, 34817, 34819, 34823, 34752, 
+    34784, 34785, 34780,     0, 32768, 34816, 34817, 34819, 
+    34823, 34752, 34784, 34785, 34780,     0, 32768, 34816, 
+    34817, 34819, 34823, 34752, 34784, 34785, 34780, 34782, 
+        0, 32768, 34816, 34817, 34819, 34823, 34752,     0, 
+    32768, 34816, 34817, 34819, 34823, 34752, 34784,     0, 
+    32768, 34816, 34817, 34819, 34823, 34752, 34784,     0, 
+    32768, 34816, 34817, 34819, 34823, 34752, 34784, 34786, 
+        0, 32768, 34816, 34817, 34819, 34823, 34752, 34784, 
+        0, 32768, 34816, 34817, 34819, 34823, 34752, 34784, 
+    34788,     0, 32768, 34816, 34817, 34819, 34823, 34752, 
+    34784, 34788,     0, 32768, 34816, 34817, 34819, 34823, 
+    34752, 34784, 34792, 34790,     0, 32768, 34816, 34817, 
+    34819, 34823, 34752, 34784,     0, 32768, 34816, 34817, 
+    34819, 34823, 34752, 34784, 34792,     0, 32768, 34816, 
+    34817, 34819, 34823, 34752, 34784, 34792,     0, 32768, 
+    34816, 34817, 34819, 34823, 34752, 34784, 34792, 34794, 
+        0, 32768, 34816, 34817, 34819, 34823, 34752, 34784, 
+    34792,     0, 32768, 34816, 34817, 34819, 34823, 34752, 
+    34784, 34800, 34796,     0, 32768, 34816, 34817, 34819, 
+    34823, 34752, 34784, 34800, 34796,     0, 32768, 34816, 
+    34817, 34819, 34823, 34752, 34784, 34800, 34801, 34798, 
+        0, 32768, 34816, 34817, 34819, 34823, 34831, 34784, 
+        0, 32768, 34816, 34817, 34819, 34823, 34831, 34784, 
+    34800,     0, 32768, 34816, 34817, 34819, 34823, 34831, 
+    34784, 34800,     0, 32768, 34816, 34817, 34819, 34823, 
+    34831, 34784, 34800, 34802,     0, 32768, 34816, 34817, 
+    34819, 34823, 34831, 34784, 34800,     0, 32768, 34816, 
+    34817, 34819, 34823, 34831, 34784, 34800, 34804,     0, 
+    32768, 34816, 34817, 34819, 34823, 34831, 34784, 34800, 
+    34804,     0, 32768, 34816, 34817, 34819, 34823, 34831, 
+    34784, 34800, 34808, 34806,     0, 32768, 34816, 34817, 
+    34819, 34823, 34831, 34784, 34800,     0, 32768, 34816, 
+    34817, 34819, 34823, 34831, 34784, 34800, 34808,     0, 
+    32768, 34816, 34817, 34819, 34823, 34831, 34784, 34800, 
+    34808,     0, 32768, 34816, 34817, 34819, 34823, 34831, 
+    34784, 34800, 34808, 34810,     0, 32768, 34816, 34817, 
+    34819, 34823, 34831, 34784, 34800, 34808,     0, 32768, 
+    34816, 34817, 34819, 34823, 34831, 34784, 34800, 34808, 
+    34812,     0, 32768, 34816, 34817, 34819, 34823, 34831, 
+    34784, 34800, 34808, 34812,     0, 32768, 34816, 34817, 
+    34819, 34823, 34831, 34784, 34800, 34808, 34812, 34814, 
+        0, 32768,     0, 32768, 34816,     0, 32768, 34816, 
+        0, 32768, 34816, 34818,     0, 32768, 34816,     0, 
+    32768, 34816, 34820,     0, 32768, 34816, 34820,     0, 
+    32768, 34816, 34824, 34822,     0, 32768, 34816,     0, 
+    32768, 34816, 34824,     0, 32768, 34816, 34824,     0, 
+    32768, 34816, 34824, 34826,     0, 32768, 34816, 34824, 
+        0, 32768, 34816, 34832, 34828,     0, 32768, 34816, 
+    34832, 34828,     0, 32768, 34816, 34832, 34833, 34830, 
+        0, 32768, 34816,     0, 32768, 34816, 34832,     0, 
+    32768, 34816, 34832,     0, 32768, 34816, 34832, 34834, 
+        0, 32768, 34816, 34832,     0, 32768, 34816, 34832, 
+    34836,     0, 32768, 34816, 34832, 34836,     0, 32768, 
+    34816, 34832, 34840, 34838,     0, 32768, 34816, 34832, 
+        0, 32768, 34816, 34848, 34840,     0, 32768, 34816, 
+    34848, 34840,     0, 32768, 34816, 34848, 34840, 34842, 
+        0, 32768, 34816, 34848, 34840,     0, 32768, 34816, 
+    34848, 34849, 34844,     0, 32768, 34816, 34848, 34849, 
+    34844,     0, 32768, 34816, 34848, 34849, 34844, 34846, 
+        0, 32768, 34816,     0, 32768, 34816, 34848,     0, 
+    32768, 34816, 34848,     0, 32768, 34816, 34848, 34850, 
+        0, 32768, 34816, 34848,     0, 32768, 34816, 34848, 
+    34852,     0, 32768, 34816, 34848, 34852,     0, 32768, 
+    34816, 34848, 34856, 34854,     0, 32768, 34816, 34848, 
+        0, 32768, 34816, 34848, 34856,     0, 32768, 34816, 
+    34848, 34856,     0, 32768, 34816, 34848, 34856, 34858, 
+        0, 32768, 34816, 34848, 34856,     0, 32768, 34816, 
+    34848, 34864, 34860,     0, 32768, 34816, 34848, 34864, 
+    34860,     0, 32768, 34816, 34848, 34864, 34865, 34862, 
+        0, 32768, 34816, 34848,     0, 32768, 34816, 34880, 
+    34864,     0, 32768, 34816, 34880, 34864,     0, 32768, 
+    34816, 34880, 34864, 34866,     0, 32768, 34816, 34880, 
+    34864,     0, 32768, 34816, 34880, 34864, 34868,     0, 
+    32768, 34816, 34880, 34864, 34868,     0, 32768, 34816, 
+    34880, 34864, 34872, 34870,     0, 32768, 34816, 34880, 
+    34864,     0, 32768, 34816, 34880, 34881, 34872,     0, 
+    32768, 34816, 34880, 34881, 34872,     0, 32768, 34816, 
+    34880, 34881, 34872, 34874,     0, 32768, 34816, 34880, 
+    34881, 34872,     0, 32768, 34816, 34880, 34881, 34872, 
+    34876,     0, 32768, 34816, 34880, 34881, 34883, 34876, 
+        0, 32768, 34816, 34880, 34881, 34883, 34876, 34878, 
+        0, 32768, 34816,     0, 32768, 34816, 34880,     0, 
+    32768, 34816, 34880,     0, 32768, 34816, 34880, 34882, 
+        0, 32768, 34816, 34880,     0, 32768, 34816, 34880, 
+    34884,     0, 32768, 34816, 34880, 34884,     0, 32768, 
+    34816, 34880, 34888, 34886,     0, 32768, 34816, 34880, 
+        0, 32768, 34816, 34880, 34888,     0, 32768, 34816, 
+    34880, 34888,     0, 32768, 34816, 34880, 34888, 34890, 
+        0, 32768, 34816, 34880, 34888,     0, 32768, 34816, 
+    34880, 34896, 34892,     0, 32768, 34816, 34880, 34896, 
+    34892,     0, 32768, 34816, 34880, 34896, 34897, 34894, 
+        0, 32768, 34816, 34880,     0, 32768, 34816, 34880, 
+    34896,     0, 32768, 34816, 34880, 34896,     0, 32768, 
+    34816, 34880, 34896, 34898,     0, 32768, 34816, 34880, 
+    34896,     0, 32768, 34816, 34880, 34896, 34900,     0, 
+    32768, 34816, 34880, 34896, 34900,     0, 32768, 34816, 
+    34880, 34896, 34904, 34902,     0, 32768, 34816, 34880, 
+    34896,     0, 32768, 34816, 34880, 34912, 34904,     0, 
+    32768, 34816, 34880, 34912, 34904,     0, 32768, 34816, 
+    34880, 34912, 34904, 34906,     0, 32768, 34816, 34880, 
+    34912, 34904,     0, 32768, 34816, 34880, 34912, 34913, 
+    34908,     0, 32768, 34816, 34880, 34912, 34913, 34908, 
+        0, 32768, 34816, 34880, 34912, 34913, 34908, 34910, 
+        0, 32768, 34816, 34880,     0, 32768, 34816, 34944, 
+    34912,     0, 32768, 34816, 34944, 34912,     0, 32768, 
+    34816, 34944, 34912, 34914,     0, 32768, 34816, 34944, 
+    34912,     0, 32768, 34816, 34944, 34912, 34916,     0, 
+    32768, 34816, 34944, 34912, 34916,     0, 32768, 34816, 
+    34944, 34912, 34920, 34918,     0, 32768, 34816, 34944, 
+    34912,     0, 32768, 34816, 34944, 34912, 34920,     0, 
+    32768, 34816, 34944, 34912, 34920,     0, 32768, 34816, 
+    34944, 34912, 34920, 34922,     0, 32768, 34816, 34944, 
+    34912, 34920,     0, 32768, 34816, 34944, 34912, 34928, 
+    34924,     0, 32768, 34816, 34944, 34912, 34928, 34924, 
+        0, 32768, 34816, 34944, 34912, 34928, 34929, 34926, 
+        0, 32768, 34816, 34944, 34912,     0, 32768, 34816, 
+    34944, 34945, 34928,     0, 32768, 34816, 34944, 34945, 
+    34928,     0, 32768, 34816, 34944, 34945, 34928, 34930, 
+        0, 32768, 34816, 34944, 34945, 34928,     0, 32768, 
+    34816, 34944, 34945, 34928, 34932,     0, 32768, 34816, 
+    34944, 34945, 34928, 34932,     0, 32768, 34816, 34944, 
+    34945, 34928, 34936, 34934,     0, 32768, 34816, 34944, 
+    34945, 34928,     0, 32768, 34816, 34944, 34945, 34928, 
+    34936,     0, 32768, 34816, 34944, 34945, 34947, 34936, 
+        0, 32768, 34816, 34944, 34945, 34947, 34936, 34938, 
+        0, 32768, 34816, 34944, 34945, 34947, 34936,     0, 
+    32768, 34816, 34944, 34945, 34947, 34936, 34940,     0, 
+    32768, 34816, 34944, 34945, 34947, 34936, 34940,     0, 
+    32768, 34816, 34944, 34945, 34947, 34936, 34940, 34942, 
+        0, 32768, 34816,     0, 32768, 34816, 34944,     0, 
+    32768, 34816, 34944,     0, 32768, 34816, 34944, 34946, 
+        0, 32768, 34816, 34944,     0, 32768, 34816, 34944, 
+    34948,     0, 32768, 34816, 34944, 34948,     0, 32768, 
+    34816, 34944, 34952, 34950,     0, 32768, 34816, 34944, 
+        0, 32768, 34816, 34944, 34952,     0, 32768, 34816, 
+    34944, 34952,     0, 32768, 34816, 34944, 34952, 34954, 
+        0, 32768, 34816, 34944, 34952,     0, 32768, 34816, 
+    34944, 34960, 34956,     0, 32768, 34816, 34944, 34960, 
+    34956,     0, 32768, 34816, 34944, 34960, 34961, 34958, 
+        0, 32768, 34816, 34944,     0, 32768, 34816, 34944, 
+    34960,     0, 32768, 34816, 34944, 34960,     0, 32768, 
+    34816, 34944, 34960, 34962,     0, 32768, 34816, 34944, 
+    34960,     0, 32768, 34816, 34944, 34960, 34964,     0, 
+    32768, 34816, 34944, 34960, 34964,     0, 32768, 34816, 
+    34944, 34960, 34968, 34966,     0, 32768, 34816, 34944, 
+    34960,     0, 32768, 34816, 34944, 34976, 34968,     0, 
+    32768, 34816, 34944, 34976, 34968,     0, 32768, 34816, 
+    34944, 34976, 34968, 34970,     0, 32768, 34816, 34944, 
+    34976, 34968,     0, 32768, 34816, 34944, 34976, 34977, 
+    34972,     0, 32768, 34816, 34944, 34976, 34977, 34972, 
+        0, 32768, 34816, 34944, 34976, 34977, 34972, 34974, 
+        0, 32768, 34816, 34944,     0, 32768, 34816, 34944, 
+    34976,     0, 32768, 34816, 34944, 34976,     0, 32768, 
+    34816, 34944, 34976, 34978,     0, 32768, 34816, 34944, 
+    34976,     0, 32768, 34816, 34944, 34976, 34980,     0, 
+    32768, 34816, 34944, 34976, 34980,     0, 32768, 34816, 
+    34944, 34976, 34984, 34982,     0, 32768, 34816, 34944, 
+    34976,     0, 32768, 34816, 34944, 34976, 34984,     0, 
+    32768, 34816, 34944, 34976, 34984,     0, 32768, 34816, 
+    34944, 34976, 34984, 34986,     0, 32768, 34816, 34944, 
+    34976, 34984,     0, 32768, 34816, 34944, 34976, 34992, 
+    34988,     0, 32768, 34816, 34944, 34976, 34992, 34988, 
+        0, 32768, 34816, 34944, 34976, 34992, 34993, 34990, 
+        0, 32768, 34816, 34944, 34976,     0, 32768, 34816, 
+    34944, 35008, 34992,     0, 32768, 34816, 34944, 35008, 
+    34992,     0, 32768, 34816, 34944, 35008, 34992, 34994, 
+        0, 32768, 34816, 34944, 35008, 34992,     0, 32768, 
+    34816, 34944, 35008, 34992, 34996,     0, 32768, 34816, 
+    34944, 35008, 34992, 34996,     0, 32768, 34816, 34944, 
+    35008, 34992, 35000, 34998,     0, 32768, 34816, 34944, 
+    35008, 34992,     0, 32768, 34816, 34944, 35008, 35009, 
+    35000,     0, 32768, 34816, 34944, 35008, 35009, 35000, 
+        0, 32768, 34816, 34944, 35008, 35009, 35000, 35002, 
+        0, 32768, 34816, 34944, 35008, 35009, 35000,     0, 
+    32768, 34816, 34944, 35008, 35009, 35000, 35004,     0, 
+    32768, 34816, 34944, 35008, 35009, 35011, 35004,     0, 
+    32768, 34816, 34944, 35008, 35009, 35011, 35004, 35006, 
+        0, 32768, 34816, 34944,     0, 32768, 34816, 35072, 
+    35008,     0, 32768, 34816, 35072, 35008,     0, 32768, 
+    34816, 35072, 35008, 35010,     0, 32768, 34816, 35072, 
+    35008,     0, 32768, 34816, 35072, 35008, 35012,     0, 
+    32768, 34816, 35072, 35008, 35012,     0, 32768, 34816, 
+    35072, 35008, 35016, 35014,     0, 32768, 34816, 35072, 
+    35008,     0, 32768, 34816, 35072, 35008, 35016,     0, 
+    32768, 34816, 35072, 35008, 35016,     0, 32768, 34816, 
+    35072, 35008, 35016, 35018,     0, 32768, 34816, 35072, 
+    35008, 35016,     0, 32768, 34816, 35072, 35008, 35024, 
+    35020,     0, 32768, 34816, 35072, 35008, 35024, 35020, 
+        0, 32768, 34816, 35072, 35008, 35024, 35025, 35022, 
+        0, 32768, 34816, 35072, 35008,     0, 32768, 34816, 
+    35072, 35008, 35024,     0, 32768, 34816, 35072, 35008, 
+    35024,     0, 32768, 34816, 35072, 35008, 35024, 35026, 
+        0, 32768, 34816, 35072, 35008, 35024,     0, 32768, 
+    34816, 35072, 35008, 35024, 35028,     0, 32768, 34816, 
+    35072, 35008, 35024, 35028,     0, 32768, 34816, 35072, 
+    35008, 35024, 35032, 35030,     0, 32768, 34816, 35072, 
+    35008, 35024,     0, 32768, 34816, 35072, 35008, 35040, 
+    35032,     0, 32768, 34816, 35072, 35008, 35040, 35032, 
+        0, 32768, 34816, 35072, 35008, 35040, 35032, 35034, 
+        0, 32768, 34816, 35072, 35008, 35040, 35032,     0, 
+    32768, 34816, 35072, 35008, 35040, 35041, 35036,     0, 
+    32768, 34816, 35072, 35008, 35040, 35041, 35036,     0, 
+    32768, 34816, 35072, 35008, 35040, 35041, 35036, 35038, 
+        0, 32768, 34816, 35072, 35008,     0, 32768, 34816, 
+    35072, 35073, 35040,     0, 32768, 34816, 35072, 35073, 
+    35040,     0, 32768, 34816, 35072, 35073, 35040, 35042, 
+        0, 32768, 34816, 35072, 35073, 35040,     0, 32768, 
+    34816, 35072, 35073, 35040, 35044,     0, 32768, 34816, 
+    35072, 35073, 35040, 35044,     0, 32768, 34816, 35072, 
+    35073, 35040, 35048, 35046,     0, 32768, 34816, 35072, 
+    35073, 35040,     0, 32768, 34816, 35072, 35073, 35040, 
+    35048,     0, 32768, 34816, 35072, 35073, 35040, 35048, 
+        0, 32768, 34816, 35072, 35073, 35040, 35048, 35050, 
+        0, 32768, 34816, 35072, 35073, 35040, 35048,     0, 
+    32768, 34816, 35072, 35073, 35040, 35056, 35052,     0, 
+    32768, 34816, 35072, 35073, 35040, 35056, 35052,     0, 
+    32768, 34816, 35072, 35073, 35040, 35056, 35057, 35054, 
+        0, 32768, 34816, 35072, 35073, 35040,     0, 32768, 
+    34816, 35072, 35073, 35040, 35056,     0, 32768, 34816, 
+    35072, 35073, 35075, 35056,     0, 32768, 34816, 35072, 
+    35073, 35075, 35056, 35058,     0, 32768, 34816, 35072, 
+    35073, 35075, 35056,     0, 32768, 34816, 35072, 35073, 
+    35075, 35056, 35060,     0, 32768, 34816, 35072, 35073, 
+    35075, 35056, 35060,     0, 32768, 34816, 35072, 35073, 
+    35075, 35056, 35064, 35062,     0, 32768, 34816, 35072, 
+    35073, 35075, 35056,     0, 32768, 34816, 35072, 35073, 
+    35075, 35056, 35064,     0, 32768, 34816, 35072, 35073, 
+    35075, 35056, 35064,     0, 32768, 34816, 35072, 35073, 
+    35075, 35056, 35064, 35066,     0, 32768, 34816, 35072, 
+    35073, 35075, 35079, 35064,     0, 32768, 34816, 35072, 
+    35073, 35075, 35079, 35064, 35068,     0, 32768, 34816, 
+    35072, 35073, 35075, 35079, 35064, 35068,     0, 32768, 
+    34816, 35072, 35073, 35075, 35079, 35064, 35068, 35070, 
+        0, 32768, 34816,     0, 32768, 34816, 35072,     0, 
+    32768, 34816, 35072,     0, 32768, 34816, 35072, 35074, 
+        0, 32768, 34816, 35072,     0, 32768, 34816, 35072, 
+    35076,     0, 32768, 34816, 35072, 35076,     0, 32768, 
+    34816, 35072, 35080, 35078,     0, 32768, 34816, 35072, 
+        0, 32768, 34816, 35072, 35080,     0, 32768, 34816, 
+    35072, 35080,     0, 32768, 34816, 35072, 35080, 35082, 
+        0, 32768, 34816, 35072, 35080,     0, 32768, 34816, 
+    35072, 35088, 35084,     0, 32768, 34816, 35072, 35088, 
+    35084,     0, 32768, 34816, 35072, 35088, 35089, 35086, 
+        0, 32768, 34816, 35072,     0, 32768, 34816, 35072, 
+    35088,     0, 32768, 34816, 35072, 35088,     0, 32768, 
+    34816, 35072, 35088, 35090,     0, 32768, 34816, 35072, 
+    35088,     0, 32768, 34816, 35072, 35088, 35092,     0, 
+    32768, 34816, 35072, 35088, 35092,     0, 32768, 34816, 
+    35072, 35088, 35096, 35094,     0, 32768, 34816, 35072, 
+    35088,     0, 32768, 34816, 35072, 35104, 35096,     0, 
+    32768, 34816, 35072, 35104, 35096,     0, 32768, 34816, 
+    35072, 35104, 35096, 35098,     0, 32768, 34816, 35072, 
+    35104, 35096,     0, 32768, 34816, 35072, 35104, 35105, 
+    35100,     0, 32768, 34816, 35072, 35104, 35105, 35100, 
+        0, 32768, 34816, 35072, 35104, 35105, 35100, 35102, 
+        0, 32768, 34816, 35072,     0, 32768, 34816, 35072, 
+    35104,     0, 32768, 34816, 35072, 35104,     0, 32768, 
+    34816, 35072, 35104, 35106,     0, 32768, 34816, 35072, 
+    35104,     0, 32768, 34816, 35072, 35104, 35108,     0, 
+    32768, 34816, 35072, 35104, 35108,     0, 32768, 34816, 
+    35072, 35104, 35112, 35110,     0, 32768, 34816, 35072, 
+    35104,     0, 32768, 34816, 35072, 35104, 35112,     0, 
+    32768, 34816, 35072, 35104, 35112,     0, 32768, 34816, 
+    35072, 35104, 35112, 35114,     0, 32768, 34816, 35072, 
+    35104, 35112,     0, 32768, 34816, 35072, 35104, 35120, 
+    35116,     0, 32768, 34816, 35072, 35104, 35120, 35116, 
+        0, 32768, 34816, 35072, 35104, 35120, 35121, 35118, 
+        0, 32768, 34816, 35072, 35104,     0, 32768, 34816, 
+    35072, 35136, 35120,     0, 32768, 34816, 35072, 35136, 
+    35120,     0, 32768, 34816, 35072, 35136, 35120, 35122, 
+        0, 32768, 34816, 35072, 35136, 35120,     0, 32768, 
+    34816, 35072, 35136, 35120, 35124,     0, 32768, 34816, 
+    35072, 35136, 35120, 35124,     0, 32768, 34816, 35072, 
+    35136, 35120, 35128, 35126,     0, 32768, 34816, 35072, 
+    35136, 35120,     0, 32768, 34816, 35072, 35136, 35137, 
+    35128,     0, 32768, 34816, 35072, 35136, 35137, 35128, 
+        0, 32768, 34816, 35072, 35136, 35137, 35128, 35130, 
+        0, 32768, 34816, 35072, 35136, 35137, 35128,     0, 
+    32768, 34816, 35072, 35136, 35137, 35128, 35132,     0, 
+    32768, 34816, 35072, 35136, 35137, 35139, 35132,     0, 
+    32768, 34816, 35072, 35136, 35137, 35139, 35132, 35134, 
+        0, 32768, 34816, 35072,     0, 32768, 34816, 35072, 
+    35136,     0, 32768, 34816, 35072, 35136,     0, 32768, 
+    34816, 35072, 35136, 35138,     0, 32768, 34816, 35072, 
+    35136,     0, 32768, 34816, 35072, 35136, 35140,     0, 
+    32768, 34816, 35072, 35136, 35140,     0, 32768, 34816, 
+    35072, 35136, 35144, 35142,     0, 32768, 34816, 35072, 
+    35136,     0, 32768, 34816, 35072, 35136, 35144,     0, 
+    32768, 34816, 35072, 35136, 35144,     0, 32768, 34816, 
+    35072, 35136, 35144, 35146,     0, 32768, 34816, 35072, 
+    35136, 35144,     0, 32768, 34816, 35072, 35136, 35152, 
+    35148,     0, 32768, 34816, 35072, 35136, 35152, 35148, 
+        0, 32768, 34816, 35072, 35136, 35152, 35153, 35150, 
+        0, 32768, 34816, 35072, 35136,     0, 32768, 34816, 
+    35072, 35136, 35152,     0, 32768, 34816, 35072, 35136, 
+    35152,     0, 32768, 34816, 35072, 35136, 35152, 35154, 
+        0, 32768, 34816, 35072, 35136, 35152,     0, 32768, 
+    34816, 35072, 35136, 35152, 35156,     0, 32768, 34816, 
+    35072, 35136, 35152, 35156,     0, 32768, 34816, 35072, 
+    35136, 35152, 35160, 35158,     0, 32768, 34816, 35072, 
+    35136, 35152,     0, 32768, 34816, 35072, 35136, 35168, 
+    35160,     0, 32768, 34816, 35072, 35136, 35168, 35160, 
+        0, 32768, 34816, 35072, 35136, 35168, 35160, 35162, 
+        0, 32768, 34816, 35072, 35136, 35168, 35160,     0, 
+    32768, 34816, 35072, 35136, 35168, 35169, 35164,     0, 
+    32768, 34816, 35072, 35136, 35168, 35169, 35164,     0, 
+    32768, 34816, 35072, 35136, 35168, 35169, 35164, 35166, 
+        0, 32768, 34816, 35072, 35136,     0, 32768, 34816, 
+    35072, 35200, 35168,     0, 32768, 34816, 35072, 35200, 
+    35168,     0, 32768, 34816, 35072, 35200, 35168, 35170, 
+        0, 32768, 34816, 35072, 35200, 35168,     0, 32768, 
+    34816, 35072, 35200, 35168, 35172,     0, 32768, 34816, 
+    35072, 35200, 35168, 35172,     0, 32768, 34816, 35072, 
+    35200, 35168, 35176, 35174,     0, 32768, 34816, 35072, 
+    35200, 35168,     0, 32768, 34816, 35072, 35200, 35168, 
+    35176,     0, 32768, 34816, 35072, 35200, 35168, 35176, 
+        0, 32768, 34816, 35072, 35200, 35168, 35176, 35178, 
+        0, 32768, 34816, 35072, 35200, 35168, 35176,     0, 
+    32768, 34816, 35072, 35200, 35168, 35184, 35180,     0, 
+    32768, 34816, 35072, 35200, 35168, 35184, 35180,     0, 
+    32768, 34816, 35072, 35200, 35168, 35184, 35185, 35182, 
+        0, 32768, 34816, 35072, 35200, 35168,     0, 32768, 
+    34816, 35072, 35200, 35201, 35184,     0, 32768, 34816, 
+    35072, 35200, 35201, 35184,     0, 32768, 34816, 35072, 
+    35200, 35201, 35184, 35186,     0, 32768, 34816, 35072, 
+    35200, 35201, 35184,     0, 32768, 34816, 35072, 35200, 
+    35201, 35184, 35188,     0, 32768, 34816, 35072, 35200, 
+    35201, 35184, 35188,     0, 32768, 34816, 35072, 35200, 
+    35201, 35184, 35192, 35190,     0, 32768, 34816, 35072, 
+    35200, 35201, 35184,     0, 32768, 34816, 35072, 35200, 
+    35201, 35184, 35192,     0, 32768, 34816, 35072, 35200, 
+    35201, 35203, 35192,     0, 32768, 34816, 35072, 35200, 
+    35201, 35203, 35192, 35194,     0, 32768, 34816, 35072, 
+    35200, 35201, 35203, 35192,     0, 32768, 34816, 35072, 
+    35200, 35201, 35203, 35192, 35196,     0, 32768, 34816, 
+    35072, 35200, 35201, 35203, 35192, 35196,     0, 32768, 
+    34816, 35072, 35200, 35201, 35203, 35192, 35196, 35198, 
+        0, 32768, 34816, 35072,     0, 32768, 34816, 35328, 
+    35200,     0, 32768, 34816, 35328, 35200,     0, 32768, 
+    34816, 35328, 35200, 35202,     0, 32768, 34816, 35328, 
+    35200,     0, 32768, 34816, 35328, 35200, 35204,     0, 
+    32768, 34816, 35328, 35200, 35204,     0, 32768, 34816, 
+    35328, 35200, 35208, 35206,     0, 32768, 34816, 35328, 
+    35200,     0, 32768, 34816, 35328, 35200, 35208,     0, 
+    32768, 34816, 35328, 35200, 35208,     0, 32768, 34816, 
+    35328, 35200, 35208, 35210,     0, 32768, 34816, 35328, 
+    35200, 35208,     0, 32768, 34816, 35328, 35200, 35216, 
+    35212,     0, 32768, 34816, 35328, 35200, 35216, 35212, 
+        0, 32768, 34816, 35328, 35200, 35216, 35217, 35214, 
+        0, 32768, 34816, 35328, 35200,     0, 32768, 34816, 
+    35328, 35200, 35216,     0, 32768, 34816, 35328, 35200, 
+    35216,     0, 32768, 34816, 35328, 35200, 35216, 35218, 
+        0, 32768, 34816, 35328, 35200, 35216,     0, 32768, 
+    34816, 35328, 35200, 35216, 35220,     0, 32768, 34816, 
+    35328, 35200, 35216, 35220,     0, 32768, 34816, 35328, 
+    35200, 35216, 35224, 35222,     0, 32768, 34816, 35328, 
+    35200, 35216,     0, 32768, 34816, 35328, 35200, 35232, 
+    35224,     0, 32768, 34816, 35328, 35200, 35232, 35224, 
+        0, 32768, 34816, 35328, 35200, 35232, 35224, 35226, 
+        0, 32768, 34816, 35328, 35200, 35232, 35224,     0, 
+    32768, 34816, 35328, 35200, 35232, 35233, 35228,     0, 
+    32768, 34816, 35328, 35200, 35232, 35233, 35228,     0, 
+    32768, 34816, 35328, 35200, 35232, 35233, 35228, 35230, 
+        0, 32768, 34816, 35328, 35200,     0, 32768, 34816, 
+    35328, 35200, 35232,     0, 32768, 34816, 35328, 35200, 
+    35232,     0, 32768, 34816, 35328, 35200, 35232, 35234, 
+        0, 32768, 34816, 35328, 35200, 35232,     0, 32768, 
+    34816, 35328, 35200, 35232, 35236,     0, 32768, 34816, 
+    35328, 35200, 35232, 35236,     0, 32768, 34816, 35328, 
+    35200, 35232, 35240, 35238,     0, 32768, 34816, 35328, 
+    35200, 35232,     0, 32768, 34816, 35328, 35200, 35232, 
+    35240,     0, 32768, 34816, 35328, 35200, 35232, 35240, 
+        0, 32768, 34816, 35328, 35200, 35232, 35240, 35242, 
+        0, 32768, 34816, 35328, 35200, 35232, 35240,     0, 
+    32768, 34816, 35328, 35200, 35232, 35248, 35244,     0, 
+    32768, 34816, 35328, 35200, 35232, 35248, 35244,     0, 
+    32768, 34816, 35328, 35200, 35232, 35248, 35249, 35246, 
+        0, 32768, 34816, 35328, 35200, 35232,     0, 32768, 
+    34816, 35328, 35200, 35264, 35248,     0, 32768, 34816, 
+    35328, 35200, 35264, 35248,     0, 32768, 34816, 35328, 
+    35200, 35264, 35248, 35250,     0, 32768, 34816, 35328, 
+    35200, 35264, 35248,     0, 32768, 34816, 35328, 35200, 
+    35264, 35248, 35252,     0, 32768, 34816, 35328, 35200, 
+    35264, 35248, 35252,     0, 32768, 34816, 35328, 35200, 
+    35264, 35248, 35256, 35254,     0, 32768, 34816, 35328, 
+    35200, 35264, 35248,     0, 32768, 34816, 35328, 35200, 
+    35264, 35265, 35256,     0, 32768, 34816, 35328, 35200, 
+    35264, 35265, 35256,     0, 32768, 34816, 35328, 35200, 
+    35264, 35265, 35256, 35258,     0, 32768, 34816, 35328, 
+    35200, 35264, 35265, 35256,     0, 32768, 34816, 35328, 
+    35200, 35264, 35265, 35256, 35260,     0, 32768, 34816, 
+    35328, 35200, 35264, 35265, 35267, 35260,     0, 32768, 
+    34816, 35328, 35200, 35264, 35265, 35267, 35260, 35262, 
+        0, 32768, 34816, 35328, 35200,     0, 32768, 34816, 
+    35328, 35329, 35264,     0, 32768, 34816, 35328, 35329, 
+    35264,     0, 32768, 34816, 35328, 35329, 35264, 35266, 
+        0, 32768, 34816, 35328, 35329, 35264,     0, 32768, 
+    34816, 35328, 35329, 35264, 35268,     0, 32768, 34816, 
+    35328, 35329, 35264, 35268,     0, 32768, 34816, 35328, 
+    35329, 35264, 35272, 35270,     0, 32768, 34816, 35328, 
+    35329, 35264,     0, 32768, 34816, 35328, 35329, 35264, 
+    35272,     0, 32768, 34816, 35328, 35329, 35264, 35272, 
+        0, 32768, 34816, 35328, 35329, 35264, 35272, 35274, 
+        0, 32768, 34816, 35328, 35329, 35264, 35272,     0, 
+    32768, 34816, 35328, 35329, 35264, 35280, 35276,     0, 
+    32768, 34816, 35328, 35329, 35264, 35280, 35276,     0, 
+    32768, 34816, 35328, 35329, 35264, 35280, 35281, 35278, 
+        0, 32768, 34816, 35328, 35329, 35264,     0, 32768, 
+    34816, 35328, 35329, 35264, 35280,     0, 32768, 34816, 
+    35328, 35329, 35264, 35280,     0, 32768, 34816, 35328, 
+    35329, 35264, 35280, 35282,     0, 32768, 34816, 35328, 
+    35329, 35264, 35280,     0, 32768, 34816, 35328, 35329, 
+    35264, 35280, 35284,     0, 32768, 34816, 35328, 35329, 
+    35264, 35280, 35284,     0, 32768, 34816, 35328, 35329, 
+    35264, 35280, 35288, 35286,     0, 32768, 34816, 35328, 
+    35329, 35264, 35280,     0, 32768, 34816, 35328, 35329, 
+    35264, 35296, 35288,     0, 32768, 34816, 35328, 35329, 
+    35264, 35296, 35288,     0, 32768, 34816, 35328, 35329, 
+    35264, 35296, 35288, 35290,     0, 32768, 34816, 35328, 
+    35329, 35264, 35296, 35288,     0, 32768, 34816, 35328, 
+    35329, 35264, 35296, 35297, 35292,     0, 32768, 34816, 
+    35328, 35329, 35264, 35296, 35297, 35292,     0, 32768, 
+    34816, 35328, 35329, 35264, 35296, 35297, 35292, 35294, 
+        0, 32768, 34816, 35328, 35329, 35264,     0, 32768, 
+    34816, 35328, 35329, 35264, 35296,     0, 32768, 34816, 
+    35328, 35329, 35331, 35296,     0, 32768, 34816, 35328, 
+    35329, 35331, 35296, 35298,     0, 32768, 34816, 35328, 
+    35329, 35331, 35296,     0, 32768, 34816, 35328, 35329, 
+    35331, 35296, 35300,     0, 32768, 34816, 35328, 35329, 
+    35331, 35296, 35300,     0, 32768, 34816, 35328, 35329, 
+    35331, 35296, 35304, 35302,     0, 32768, 34816, 35328, 
+    35329, 35331, 35296,     0, 32768, 34816, 35328, 35329, 
+    35331, 35296, 35304,     0, 32768, 34816, 35328, 35329, 
+    35331, 35296, 35304,     0, 32768, 34816, 35328, 35329, 
+    35331, 35296, 35304, 35306,     0, 32768, 34816, 35328, 
+    35329, 35331, 35296, 35304,     0, 32768, 34816, 35328, 
+    35329, 35331, 35296, 35312, 35308,     0, 32768, 34816, 
+    35328, 35329, 35331, 35296, 35312, 35308,     0, 32768, 
+    34816, 35328, 35329, 35331, 35296, 35312, 35313, 35310, 
+        0, 32768, 34816, 35328, 35329, 35331, 35296,     0, 
+    32768, 34816, 35328, 35329, 35331, 35296, 35312,     0, 
+    32768, 34816, 35328, 35329, 35331, 35296, 35312,     0, 
+    32768, 34816, 35328, 35329, 35331, 35296, 35312, 35314, 
+        0, 32768, 34816, 35328, 35329, 35331, 35335, 35312, 
+        0, 32768, 34816, 35328, 35329, 35331, 35335, 35312, 
+    35316,     0, 32768, 34816, 35328, 35329, 35331, 35335, 
+    35312, 35316,     0, 32768, 34816, 35328, 35329, 35331, 
+    35335, 35312, 35320, 35318,     0, 32768, 34816, 35328, 
+    35329, 35331, 35335, 35312,     0, 32768, 34816, 35328, 
+    35329, 35331, 35335, 35312, 35320,     0, 32768, 34816, 
+    35328, 35329, 35331, 35335, 35312, 35320,     0, 32768, 
+    34816, 35328, 35329, 35331, 35335, 35312, 35320, 35322, 
+        0, 32768, 34816, 35328, 35329, 35331, 35335, 35312, 
+    35320,     0, 32768, 34816, 35328, 35329, 35331, 35335, 
+    35312, 35320, 35324,     0, 32768, 34816, 35328, 35329, 
+    35331, 35335, 35312, 35320, 35324,     0, 32768, 34816, 
+    35328, 35329, 35331, 35335, 35312, 35320, 35324, 35326, 
+        0, 32768, 34816,     0, 32768, 34816, 35328,     0, 
+    32768, 34816, 35328,     0, 32768, 34816, 35328, 35330, 
+        0, 32768, 34816, 35328,     0, 32768, 34816, 35328, 
+    35332,     0, 32768, 34816, 35328, 35332,     0, 32768, 
+    34816, 35328, 35336, 35334,     0, 32768, 34816, 35328, 
+        0, 32768, 34816, 35328, 35336,     0, 32768, 34816, 
+    35328, 35336,     0, 32768, 34816, 35328, 35336, 35338, 
+        0, 32768, 34816, 35328, 35336,     0, 32768, 34816, 
+    35328, 35344, 35340,     0, 32768, 34816, 35328, 35344, 
+    35340,     0, 32768, 34816, 35328, 35344, 35345, 35342, 
+        0, 32768, 34816, 35328,     0, 32768, 34816, 35328, 
+    35344,     0, 32768, 34816, 35328, 35344,     0, 32768, 
+    34816, 35328, 35344, 35346,     0, 32768, 34816, 35328, 
+    35344,     0, 32768, 34816, 35328, 35344, 35348,     0, 
+    32768, 34816, 35328, 35344, 35348,     0, 32768, 34816, 
+    35328, 35344, 35352, 35350,     0, 32768, 34816, 35328, 
+    35344,     0, 32768, 34816, 35328, 35360, 35352,     0, 
+    32768, 34816, 35328, 35360, 35352,     0, 32768, 34816, 
+    35328, 35360, 35352, 35354,     0, 32768, 34816, 35328, 
+    35360, 35352,     0, 32768, 34816, 35328, 35360, 35361, 
+    35356,     0, 32768, 34816, 35328, 35360, 35361, 35356, 
+        0, 32768, 34816, 35328, 35360, 35361, 35356, 35358, 
+        0, 32768, 34816, 35328,     0, 32768, 34816, 35328, 
+    35360,     0, 32768, 34816, 35328, 35360,     0, 32768, 
+    34816, 35328, 35360, 35362,     0, 32768, 34816, 35328, 
+    35360,     0, 32768, 34816, 35328, 35360, 35364,     0, 
+    32768, 34816, 35328, 35360, 35364,     0, 32768, 34816, 
+    35328, 35360, 35368, 35366,     0, 32768, 34816, 35328, 
+    35360,     0, 32768, 34816, 35328, 35360, 35368,     0, 
+    32768, 34816, 35328, 35360, 35368,     0, 32768, 34816, 
+    35328, 35360, 35368, 35370,     0, 32768, 34816, 35328, 
+    35360, 35368,     0, 32768, 34816, 35328, 35360, 35376, 
+    35372,     0, 32768, 34816, 35328, 35360, 35376, 35372, 
+        0, 32768, 34816, 35328, 35360, 35376, 35377, 35374, 
+        0, 32768, 34816, 35328, 35360,     0, 32768, 34816, 
+    35328, 35392, 35376,     0, 32768, 34816, 35328, 35392, 
+    35376,     0, 32768, 34816, 35328, 35392, 35376, 35378, 
+        0, 32768, 34816, 35328, 35392, 35376,     0, 32768, 
+    34816, 35328, 35392, 35376, 35380,     0, 32768, 34816, 
+    35328, 35392, 35376, 35380,     0, 32768, 34816, 35328, 
+    35392, 35376, 35384, 35382,     0, 32768, 34816, 35328, 
+    35392, 35376,     0, 32768, 34816, 35328, 35392, 35393, 
+    35384,     0, 32768, 34816, 35328, 35392, 35393, 35384, 
+        0, 32768, 34816, 35328, 35392, 35393, 35384, 35386, 
+        0, 32768, 34816, 35328, 35392, 35393, 35384,     0, 
+    32768, 34816, 35328, 35392, 35393, 35384, 35388,     0, 
+    32768, 34816, 35328, 35392, 35393, 35395, 35388,     0, 
+    32768, 34816, 35328, 35392, 35393, 35395, 35388, 35390, 
+        0, 32768, 34816, 35328,     0, 32768, 34816, 35328, 
+    35392,     0, 32768, 34816, 35328, 35392,     0, 32768, 
+    34816, 35328, 35392, 35394,     0, 32768, 34816, 35328, 
+    35392,     0, 32768, 34816, 35328, 35392, 35396,     0, 
+    32768, 34816, 35328, 35392, 35396,     0, 32768, 34816, 
+    35328, 35392, 35400, 35398,     0, 32768, 34816, 35328, 
+    35392,     0, 32768, 34816, 35328, 35392, 35400,     0, 
+    32768, 34816, 35328, 35392, 35400,     0, 32768, 34816, 
+    35328, 35392, 35400, 35402,     0, 32768, 34816, 35328, 
+    35392, 35400,     0, 32768, 34816, 35328, 35392, 35408, 
+    35404,     0, 32768, 34816, 35328, 35392, 35408, 35404, 
+        0, 32768, 34816, 35328, 35392, 35408, 35409, 35406, 
+        0, 32768, 34816, 35328, 35392,     0, 32768, 34816, 
+    35328, 35392, 35408,     0, 32768, 34816, 35328, 35392, 
+    35408,     0, 32768, 34816, 35328, 35392, 35408, 35410, 
+        0, 32768, 34816, 35328, 35392, 35408,     0, 32768, 
+    34816, 35328, 35392, 35408, 35412,     0, 32768, 34816, 
+    35328, 35392, 35408, 35412,     0, 32768, 34816, 35328, 
+    35392, 35408, 35416, 35414,     0, 32768, 34816, 35328, 
+    35392, 35408,     0, 32768, 34816, 35328, 35392, 35424, 
+    35416,     0, 32768, 34816, 35328, 35392, 35424, 35416, 
+        0, 32768, 34816, 35328, 35392, 35424, 35416, 35418, 
+        0, 32768, 34816, 35328, 35392, 35424, 35416,     0, 
+    32768, 34816, 35328, 35392, 35424, 35425, 35420,     0, 
+    32768, 34816, 35328, 35392, 35424, 35425, 35420,     0, 
+    32768, 34816, 35328, 35392, 35424, 35425, 35420, 35422, 
+        0, 32768, 34816, 35328, 35392,     0, 32768, 34816, 
+    35328, 35456, 35424,     0, 32768, 34816, 35328, 35456, 
+    35424,     0, 32768, 34816, 35328, 35456, 35424, 35426, 
+        0, 32768, 34816, 35328, 35456, 35424,     0, 32768, 
+    34816, 35328, 35456, 35424, 35428,     0, 32768, 34816, 
+    35328, 35456, 35424, 35428,     0, 32768, 34816, 35328, 
+    35456, 35424, 35432, 35430,     0, 32768, 34816, 35328, 
+    35456, 35424,     0, 32768, 34816, 35328, 35456, 35424, 
+    35432,     0, 32768, 34816, 35328, 35456, 35424, 35432, 
+        0, 32768, 34816, 35328, 35456, 35424, 35432, 35434, 
+        0, 32768, 34816, 35328, 35456, 35424, 35432,     0, 
+    32768, 34816, 35328, 35456, 35424, 35440, 35436,     0, 
+    32768, 34816, 35328, 35456, 35424, 35440, 35436,     0, 
+    32768, 34816, 35328, 35456, 35424, 35440, 35441, 35438, 
+        0, 32768, 34816, 35328, 35456, 35424,     0, 32768, 
+    34816, 35328, 35456, 35457, 35440,     0, 32768, 34816, 
+    35328, 35456, 35457, 35440,     0, 32768, 34816, 35328, 
+    35456, 35457, 35440, 35442,     0, 32768, 34816, 35328, 
+    35456, 35457, 35440,     0, 32768, 34816, 35328, 35456, 
+    35457, 35440, 35444,     0, 32768, 34816, 35328, 35456, 
+    35457, 35440, 35444,     0, 32768, 34816, 35328, 35456, 
+    35457, 35440, 35448, 35446,     0, 32768, 34816, 35328, 
+    35456, 35457, 35440,     0, 32768, 34816, 35328, 35456, 
+    35457, 35440, 35448,     0, 32768, 34816, 35328, 35456, 
+    35457, 35459, 35448,     0, 32768, 34816, 35328, 35456, 
+    35457, 35459, 35448, 35450,     0, 32768, 34816, 35328, 
+    35456, 35457, 35459, 35448,     0, 32768, 34816, 35328, 
+    35456, 35457, 35459, 35448, 35452,     0, 32768, 34816, 
+    35328, 35456, 35457, 35459, 35448, 35452,     0, 32768, 
+    34816, 35328, 35456, 35457, 35459, 35448, 35452, 35454, 
+        0, 32768, 34816, 35328,     0, 32768, 34816, 35328, 
+    35456,     0, 32768, 34816, 35328, 35456,     0, 32768, 
+    34816, 35328, 35456, 35458,     0, 32768, 34816, 35328, 
+    35456,     0, 32768, 34816, 35328, 35456, 35460,     0, 
+    32768, 34816, 35328, 35456, 35460,     0, 32768, 34816, 
+    35328, 35456, 35464, 35462,     0, 32768, 34816, 35328, 
+    35456,     0, 32768, 34816, 35328, 35456, 35464,     0, 
+    32768, 34816, 35328, 35456, 35464,     0, 32768, 34816, 
+    35328, 35456, 35464, 35466,     0, 32768, 34816, 35328, 
+    35456, 35464,     0, 32768, 34816, 35328, 35456, 35472, 
+    35468,     0, 32768, 34816, 35328, 35456, 35472, 35468, 
+        0, 32768, 34816, 35328, 35456, 35472, 35473, 35470, 
+        0, 32768, 34816, 35328, 35456,     0, 32768, 34816, 
+    35328, 35456, 35472,     0, 32768, 34816, 35328, 35456, 
+    35472,     0, 32768, 34816, 35328, 35456, 35472, 35474, 
+        0, 32768, 34816, 35328, 35456, 35472,     0, 32768, 
+    34816, 35328, 35456, 35472, 35476,     0, 32768, 34816, 
+    35328, 35456, 35472, 35476,     0, 32768, 34816, 35328, 
+    35456, 35472, 35480, 35478,     0, 32768, 34816, 35328, 
+    35456, 35472,     0, 32768, 34816, 35328, 35456, 35488, 
+    35480,     0, 32768, 34816, 35328, 35456, 35488, 35480, 
+        0, 32768, 34816, 35328, 35456, 35488, 35480, 35482, 
+        0, 32768, 34816, 35328, 35456, 35488, 35480,     0, 
+    32768, 34816, 35328, 35456, 35488, 35489, 35484,     0, 
+    32768, 34816, 35328, 35456, 35488, 35489, 35484,     0, 
+    32768, 34816, 35328, 35456, 35488, 35489, 35484, 35486, 
+        0, 32768, 34816, 35328, 35456,     0, 32768, 34816, 
+    35328, 35456, 35488,     0, 32768, 34816, 35328, 35456, 
+    35488,     0, 32768, 34816, 35328, 35456, 35488, 35490, 
+        0, 32768, 34816, 35328, 35456, 35488,     0, 32768, 
+    34816, 35328, 35456, 35488, 35492,     0, 32768, 34816, 
+    35328, 35456, 35488, 35492,     0, 32768, 34816, 35328, 
+    35456, 35488, 35496, 35494,     0, 32768, 34816, 35328, 
+    35456, 35488,     0, 32768, 34816, 35328, 35456, 35488, 
+    35496,     0, 32768, 34816, 35328, 35456, 35488, 35496, 
+        0, 32768, 34816, 35328, 35456, 35488, 35496, 35498, 
+        0, 32768, 34816, 35328, 35456, 35488, 35496,     0, 
+    32768, 34816, 35328, 35456, 35488, 35504, 35500,     0, 
+    32768, 34816, 35328, 35456, 35488, 35504, 35500,     0, 
+    32768, 34816, 35328, 35456, 35488, 35504, 35505, 35502, 
+        0, 32768, 34816, 35328, 35456, 35488,     0, 32768, 
+    34816, 35328, 35456, 35520, 35504,     0, 32768, 34816, 
+    35328, 35456, 35520, 35504,     0, 32768, 34816, 35328, 
+    35456, 35520, 35504, 35506,     0, 32768, 34816, 35328, 
+    35456, 35520, 35504,     0, 32768, 34816, 35328, 35456, 
+    35520, 35504, 35508,     0, 32768, 34816, 35328, 35456, 
+    35520, 35504, 35508,     0, 32768, 34816, 35328, 35456, 
+    35520, 35504, 35512, 35510,     0, 32768, 34816, 35328, 
+    35456, 35520, 35504,     0, 32768, 34816, 35328, 35456, 
+    35520, 35521, 35512,     0, 32768, 34816, 35328, 35456, 
+    35520, 35521, 35512,     0, 32768, 34816, 35328, 35456, 
+    35520, 35521, 35512, 35514,     0, 32768, 34816, 35328, 
+    35456, 35520, 35521, 35512,     0, 32768, 34816, 35328, 
+    35456, 35520, 35521, 35512, 35516,     0, 32768, 34816, 
+    35328, 35456, 35520, 35521, 35523, 35516,     0, 32768, 
+    34816, 35328, 35456, 35520, 35521, 35523, 35516, 35518, 
+        0, 32768, 34816, 35328, 35456,     0, 32768, 34816, 
+    35328, 35584, 35520,     0, 32768, 34816, 35328, 35584, 
+    35520,     0, 32768, 34816, 35328, 35584, 35520, 35522, 
+        0, 32768, 34816, 35328, 35584, 35520,     0, 32768, 
+    34816, 35328, 35584, 35520, 35524,     0, 32768, 34816, 
+    35328, 35584, 35520, 35524,     0, 32768, 34816, 35328, 
+    35584, 35520, 35528, 35526,     0, 32768, 34816, 35328, 
+    35584, 35520,     0, 32768, 34816, 35328, 35584, 35520, 
+    35528,     0, 32768, 34816, 35328, 35584, 35520, 35528, 
+        0, 32768, 34816, 35328, 35584, 35520, 35528, 35530, 
+        0, 32768, 34816, 35328, 35584, 35520, 35528,     0, 
+    32768, 34816, 35328, 35584, 35520, 35536, 35532,     0, 
+    32768, 34816, 35328, 35584, 35520, 35536, 35532,     0, 
+    32768, 34816, 35328, 35584, 35520, 35536, 35537, 35534, 
+        0, 32768, 34816, 35328, 35584, 35520,     0, 32768, 
+    34816, 35328, 35584, 35520, 35536,     0, 32768, 34816, 
+    35328, 35584, 35520, 35536,     0, 32768, 34816, 35328, 
+    35584, 35520, 35536, 35538,     0, 32768, 34816, 35328, 
+    35584, 35520, 35536,     0, 32768, 34816, 35328, 35584, 
+    35520, 35536, 35540,     0, 32768, 34816, 35328, 35584, 
+    35520, 35536, 35540,     0, 32768, 34816, 35328, 35584, 
+    35520, 35536, 35544, 35542,     0, 32768, 34816, 35328, 
+    35584, 35520, 35536,     0, 32768, 34816, 35328, 35584, 
+    35520, 35552, 35544,     0, 32768, 34816, 35328, 35584, 
+    35520, 35552, 35544,     0, 32768, 34816, 35328, 35584, 
+    35520, 35552, 35544, 35546,     0, 32768, 34816, 35328, 
+    35584, 35520, 35552, 35544,     0, 32768, 34816, 35328, 
+    35584, 35520, 35552, 35553, 35548,     0, 32768, 34816, 
+    35328, 35584, 35520, 35552, 35553, 35548,     0, 32768, 
+    34816, 35328, 35584, 35520, 35552, 35553, 35548, 35550, 
+        0, 32768, 34816, 35328, 35584, 35520,     0, 32768, 
+    34816, 35328, 35584, 35585, 35552,     0, 32768, 34816, 
+    35328, 35584, 35585, 35552,     0, 32768, 34816, 35328, 
+    35584, 35585, 35552, 35554,     0, 32768, 34816, 35328, 
+    35584, 35585, 35552,     0, 32768, 34816, 35328, 35584, 
+    35585, 35552, 35556,     0, 32768, 34816, 35328, 35584, 
+    35585, 35552, 35556,     0, 32768, 34816, 35328, 35584, 
+    35585, 35552, 35560, 35558,     0, 32768, 34816, 35328, 
+    35584, 35585, 35552,     0, 32768, 34816, 35328, 35584, 
+    35585, 35552, 35560,     0, 32768, 34816, 35328, 35584, 
+    35585, 35552, 35560,     0, 32768, 34816, 35328, 35584, 
+    35585, 35552, 35560, 35562,     0, 32768, 34816, 35328, 
+    35584, 35585, 35552, 35560,     0, 32768, 34816, 35328, 
+    35584, 35585, 35552, 35568, 35564,     0, 32768, 34816, 
+    35328, 35584, 35585, 35552, 35568, 35564,     0, 32768, 
+    34816, 35328, 35584, 35585, 35552, 35568, 35569, 35566, 
+        0, 32768, 34816, 35328, 35584, 35585, 35552,     0, 
+    32768, 34816, 35328, 35584, 35585, 35552, 35568,     0, 
+    32768, 34816, 35328, 35584, 35585, 35587, 35568,     0, 
+    32768, 34816, 35328, 35584, 35585, 35587, 35568, 35570, 
+        0, 32768, 34816, 35328, 35584, 35585, 35587, 35568, 
+        0, 32768, 34816, 35328, 35584, 35585, 35587, 35568, 
+    35572,     0, 32768, 34816, 35328, 35584, 35585, 35587, 
+    35568, 35572,     0, 32768, 34816, 35328, 35584, 35585, 
+    35587, 35568, 35576, 35574,     0, 32768, 34816, 35328, 
+    35584, 35585, 35587, 35568,     0, 32768, 34816, 35328, 
+    35584, 35585, 35587, 35568, 35576,     0, 32768, 34816, 
+    35328, 35584, 35585, 35587, 35568, 35576,     0, 32768, 
+    34816, 35328, 35584, 35585, 35587, 35568, 35576, 35578, 
+        0, 32768, 34816, 35328, 35584, 35585, 35587, 35591, 
+    35576,     0, 32768, 34816, 35328, 35584, 35585, 35587, 
+    35591, 35576, 35580,     0, 32768, 34816, 35328, 35584, 
+    35585, 35587, 35591, 35576, 35580,     0, 32768, 34816, 
+    35328, 35584, 35585, 35587, 35591, 35576, 35580, 35582, 
+        0, 32768, 34816, 35328,     0, 32768, 34816, 35840, 
+    35584,     0, 32768, 34816, 35840, 35584,     0, 32768, 
+    34816, 35840, 35584, 35586,     0, 32768, 34816, 35840, 
+    35584,     0, 32768, 34816, 35840, 35584, 35588,     0, 
+    32768, 34816, 35840, 35584, 35588,     0, 32768, 34816, 
+    35840, 35584, 35592, 35590,     0, 32768, 34816, 35840, 
+    35584,     0, 32768, 34816, 35840, 35584, 35592,     0, 
+    32768, 34816, 35840, 35584, 35592,     0, 32768, 34816, 
+    35840, 35584, 35592, 35594,     0, 32768, 34816, 35840, 
+    35584, 35592,     0, 32768, 34816, 35840, 35584, 35600, 
+    35596,     0, 32768, 34816, 35840, 35584, 35600, 35596, 
+        0, 32768, 34816, 35840, 35584, 35600, 35601, 35598, 
+        0, 32768, 34816, 35840, 35584,     0, 32768, 34816, 
+    35840, 35584, 35600,     0, 32768, 34816, 35840, 35584, 
+    35600,     0, 32768, 34816, 35840, 35584, 35600, 35602, 
+        0, 32768, 34816, 35840, 35584, 35600,     0, 32768, 
+    34816, 35840, 35584, 35600, 35604,     0, 32768, 34816, 
+    35840, 35584, 35600, 35604,     0, 32768, 34816, 35840, 
+    35584, 35600, 35608, 35606,     0, 32768, 34816, 35840, 
+    35584, 35600,     0, 32768, 34816, 35840, 35584, 35616, 
+    35608,     0, 32768, 34816, 35840, 35584, 35616, 35608, 
+        0, 32768, 34816, 35840, 35584, 35616, 35608, 35610, 
+        0, 32768, 34816, 35840, 35584, 35616, 35608,     0, 
+    32768, 34816, 35840, 35584, 35616, 35617, 35612,     0, 
+    32768, 34816, 35840, 35584, 35616, 35617, 35612,     0, 
+    32768, 34816, 35840, 35584, 35616, 35617, 35612, 35614, 
+        0, 32768, 34816, 35840, 35584,     0, 32768, 34816, 
+    35840, 35584, 35616,     0, 32768, 34816, 35840, 35584, 
+    35616,     0, 32768, 34816, 35840, 35584, 35616, 35618, 
+        0, 32768, 34816, 35840, 35584, 35616,     0, 32768, 
+    34816, 35840, 35584, 35616, 35620,     0, 32768, 34816, 
+    35840, 35584, 35616, 35620,     0, 32768, 34816, 35840, 
+    35584, 35616, 35624, 35622,     0, 32768, 34816, 35840, 
+    35584, 35616,     0, 32768, 34816, 35840, 35584, 35616, 
+    35624,     0, 32768, 34816, 35840, 35584, 35616, 35624, 
+        0, 32768, 34816, 35840, 35584, 35616, 35624, 35626, 
+        0, 32768, 34816, 35840, 35584, 35616, 35624,     0, 
+    32768, 34816, 35840, 35584, 35616, 35632, 35628,     0, 
+    32768, 34816, 35840, 35584, 35616, 35632, 35628,     0, 
+    32768, 34816, 35840, 35584, 35616, 35632, 35633, 35630, 
+        0, 32768, 34816, 35840, 35584, 35616,     0, 32768, 
+    34816, 35840, 35584, 35648, 35632,     0, 32768, 34816, 
+    35840, 35584, 35648, 35632,     0, 32768, 34816, 35840, 
+    35584, 35648, 35632, 35634,     0, 32768, 34816, 35840, 
+    35584, 35648, 35632,     0, 32768, 34816, 35840, 35584, 
+    35648, 35632, 35636,     0, 32768, 34816, 35840, 35584, 
+    35648, 35632, 35636,     0, 32768, 34816, 35840, 35584, 
+    35648, 35632, 35640, 35638,     0, 32768, 34816, 35840, 
+    35584, 35648, 35632,     0, 32768, 34816, 35840, 35584, 
+    35648, 35649, 35640,     0, 32768, 34816, 35840, 35584, 
+    35648, 35649, 35640,     0, 32768, 34816, 35840, 35584, 
+    35648, 35649, 35640, 35642,     0, 32768, 34816, 35840, 
+    35584, 35648, 35649, 35640,     0, 32768, 34816, 35840, 
+    35584, 35648, 35649, 35640, 35644,     0, 32768, 34816, 
+    35840, 35584, 35648, 35649, 35651, 35644,     0, 32768, 
+    34816, 35840, 35584, 35648, 35649, 35651, 35644, 35646, 
+        0, 32768, 34816, 35840, 35584,     0, 32768, 34816, 
+    35840, 35584, 35648,     0, 32768, 34816, 35840, 35584, 
+    35648,     0, 32768, 34816, 35840, 35584, 35648, 35650, 
+        0, 32768, 34816, 35840, 35584, 35648,     0, 32768, 
+    34816, 35840, 35584, 35648, 35652,     0, 32768, 34816, 
+    35840, 35584, 35648, 35652,     0, 32768, 34816, 35840, 
+    35584, 35648, 35656, 35654,     0, 32768, 34816, 35840, 
+    35584, 35648,     0, 32768, 34816, 35840, 35584, 35648, 
+    35656,     0, 32768, 34816, 35840, 35584, 35648, 35656, 
+        0, 32768, 34816, 35840, 35584, 35648, 35656, 35658, 
+        0, 32768, 34816, 35840, 35584, 35648, 35656,     0, 
+    32768, 34816, 35840, 35584, 35648, 35664, 35660,     0, 
+    32768, 34816, 35840, 35584, 35648, 35664, 35660,     0, 
+    32768, 34816, 35840, 35584, 35648, 35664, 35665, 35662, 
+        0, 32768, 34816, 35840, 35584, 35648,     0, 32768, 
+    34816, 35840, 35584, 35648, 35664,     0, 32768, 34816, 
+    35840, 35584, 35648, 35664,     0, 32768, 34816, 35840, 
+    35584, 35648, 35664, 35666,     0, 32768, 34816, 35840, 
+    35584, 35648, 35664,     0, 32768, 34816, 35840, 35584, 
+    35648, 35664, 35668,     0, 32768, 34816, 35840, 35584, 
+    35648, 35664, 35668,     0, 32768, 34816, 35840, 35584, 
+    35648, 35664, 35672, 35670,     0, 32768, 34816, 35840, 
+    35584, 35648, 35664,     0, 32768, 34816, 35840, 35584, 
+    35648, 35680, 35672,     0, 32768, 34816, 35840, 35584, 
+    35648, 35680, 35672,     0, 32768, 34816, 35840, 35584, 
+    35648, 35680, 35672, 35674,     0, 32768, 34816, 35840, 
+    35584, 35648, 35680, 35672,     0, 32768, 34816, 35840, 
+    35584, 35648, 35680, 35681, 35676,     0, 32768, 34816, 
+    35840, 35584, 35648, 35680, 35681, 35676,     0, 32768, 
+    34816, 35840, 35584, 35648, 35680, 35681, 35676, 35678, 
+        0, 32768, 34816, 35840, 35584, 35648,     0, 32768, 
+    34816, 35840, 35584, 35712, 35680,     0, 32768, 34816, 
+    35840, 35584, 35712, 35680,     0, 32768, 34816, 35840, 
+    35584, 35712, 35680, 35682,     0, 32768, 34816, 35840, 
+    35584, 35712, 35680,     0, 32768, 34816, 35840, 35584, 
+    35712, 35680, 35684,     0, 32768, 34816, 35840, 35584, 
+    35712, 35680, 35684,     0, 32768, 34816, 35840, 35584, 
+    35712, 35680, 35688, 35686,     0, 32768, 34816, 35840, 
+    35584, 35712, 35680,     0, 32768, 34816, 35840, 35584, 
+    35712, 35680, 35688,     0, 32768, 34816, 35840, 35584, 
+    35712, 35680, 35688,     0, 32768, 34816, 35840, 35584, 
+    35712, 35680, 35688, 35690,     0, 32768, 34816, 35840, 
+    35584, 35712, 35680, 35688,     0, 32768, 34816, 35840, 
+    35584, 35712, 35680, 35696, 35692,     0, 32768, 34816, 
+    35840, 35584, 35712, 35680, 35696, 35692,     0, 32768, 
+    34816, 35840, 35584, 35712, 35680, 35696, 35697, 35694, 
+        0, 32768, 34816, 35840, 35584, 35712, 35680,     0, 
+    32768, 34816, 35840, 35584, 35712, 35713, 35696,     0, 
+    32768, 34816, 35840, 35584, 35712, 35713, 35696,     0, 
+    32768, 34816, 35840, 35584, 35712, 35713, 35696, 35698, 
+        0, 32768, 34816, 35840, 35584, 35712, 35713, 35696, 
+        0, 32768, 34816, 35840, 35584, 35712, 35713, 35696, 
+    35700,     0, 32768, 34816, 35840, 35584, 35712, 35713, 
+    35696, 35700,     0, 32768, 34816, 35840, 35584, 35712, 
+    35713, 35696, 35704, 35702,     0, 32768, 34816, 35840, 
+    35584, 35712, 35713, 35696,     0, 32768, 34816, 35840, 
+    35584, 35712, 35713, 35696, 35704,     0, 32768, 34816, 
+    35840, 35584, 35712, 35713, 35715, 35704,     0, 32768, 
+    34816, 35840, 35584, 35712, 35713, 35715, 35704, 35706, 
+        0, 32768, 34816, 35840, 35584, 35712, 35713, 35715, 
+    35704,     0, 32768, 34816, 35840, 35584, 35712, 35713, 
+    35715, 35704, 35708,     0, 32768, 34816, 35840, 35584, 
+    35712, 35713, 35715, 35704, 35708,     0, 32768, 34816, 
+    35840, 35584, 35712, 35713, 35715, 35704, 35708, 35710, 
+        0, 32768, 34816, 35840, 35584,     0, 32768, 34816, 
+    35840, 35584, 35712,     0, 32768, 34816, 35840, 35841, 
+    35712,     0, 32768, 34816, 35840, 35841, 35712, 35714, 
+        0, 32768, 34816, 35840, 35841, 35712,     0, 32768, 
+    34816, 35840, 35841, 35712, 35716,     0, 32768, 34816, 
+    35840, 35841, 35712, 35716,     0, 32768, 34816, 35840, 
+    35841, 35712, 35720, 35718,     0, 32768, 34816, 35840, 
+    35841, 35712,     0, 32768, 34816, 35840, 35841, 35712, 
+    35720,     0, 32768, 34816, 35840, 35841, 35712, 35720, 
+        0, 32768, 34816, 35840, 35841, 35712, 35720, 35722, 
+        0, 32768, 34816, 35840, 35841, 35712, 35720,     0, 
+    32768, 34816, 35840, 35841, 35712, 35728, 35724,     0, 
+    32768, 34816, 35840, 35841, 35712, 35728, 35724,     0, 
+    32768, 34816, 35840, 35841, 35712, 35728, 35729, 35726, 
+        0, 32768, 34816, 35840, 35841, 35712,     0, 32768, 
+    34816, 35840, 35841, 35712, 35728,     0, 32768, 34816, 
+    35840, 35841, 35712, 35728,     0, 32768, 34816, 35840, 
+    35841, 35712, 35728, 35730,     0, 32768, 34816, 35840, 
+    35841, 35712, 35728,     0, 32768, 34816, 35840, 35841, 
+    35712, 35728, 35732,     0, 32768, 34816, 35840, 35841, 
+    35712, 35728, 35732,     0, 32768, 34816, 35840, 35841, 
+    35712, 35728, 35736, 35734,     0, 32768, 34816, 35840, 
+    35841, 35712, 35728,     0, 32768, 34816, 35840, 35841, 
+    35712, 35744, 35736,     0, 32768, 34816, 35840, 35841, 
+    35712, 35744, 35736,     0, 32768, 34816, 35840, 35841, 
+    35712, 35744, 35736, 35738,     0, 32768, 34816, 35840, 
+    35841, 35712, 35744, 35736,     0, 32768, 34816, 35840, 
+    35841, 35712, 35744, 35745, 35740,     0, 32768, 34816, 
+    35840, 35841, 35712, 35744, 35745, 35740,     0, 32768, 
+    34816, 35840, 35841, 35712, 35744, 35745, 35740, 35742, 
+        0, 32768, 34816, 35840, 35841, 35712,     0, 32768, 
+    34816, 35840, 35841, 35712, 35744,     0, 32768, 34816, 
+    35840, 35841, 35712, 35744,     0, 32768, 34816, 35840, 
+    35841, 35712, 35744, 35746,     0, 32768, 34816, 35840, 
+    35841, 35712, 35744,     0, 32768, 34816, 35840, 35841, 
+    35712, 35744, 35748,     0, 32768, 34816, 35840, 35841, 
+    35712, 35744, 35748,     0, 32768, 34816, 35840, 35841, 
+    35712, 35744, 35752, 35750,     0, 32768, 34816, 35840, 
+    35841, 35712, 35744,     0, 32768, 34816, 35840, 35841, 
+    35712, 35744, 35752,     0, 32768, 34816, 35840, 35841, 
+    35712, 35744, 35752,     0, 32768, 34816, 35840, 35841, 
+    35712, 35744, 35752, 35754,     0, 32768, 34816, 35840, 
+    35841, 35712, 35744, 35752,     0, 32768, 34816, 35840, 
+    35841, 35712, 35744, 35760, 35756,     0, 32768, 34816, 
+    35840, 35841, 35712, 35744, 35760, 35756,     0, 32768, 
+    34816, 35840, 35841, 35712, 35744, 35760, 35761, 35758, 
+        0, 32768, 34816, 35840, 35841, 35712, 35744,     0, 
+    32768, 34816, 35840, 35841, 35712, 35776, 35760,     0, 
+    32768, 34816, 35840, 35841, 35712, 35776, 35760,     0, 
+    32768, 34816, 35840, 35841, 35712, 35776, 35760, 35762, 
+        0, 32768, 34816, 35840, 35841, 35712, 35776, 35760, 
+        0, 32768, 34816, 35840, 35841, 35712, 35776, 35760, 
+    35764,     0, 32768, 34816, 35840, 35841, 35712, 35776, 
+    35760, 35764,     0, 32768, 34816, 35840, 35841, 35712, 
+    35776, 35760, 35768, 35766,     0, 32768, 34816, 35840, 
+    35841, 35712, 35776, 35760,     0, 32768, 34816, 35840, 
+    35841, 35712, 35776, 35777, 35768,     0, 32768, 34816, 
+    35840, 35841, 35712, 35776, 35777, 35768,     0, 32768, 
+    34816, 35840, 35841, 35712, 35776, 35777, 35768, 35770, 
+        0, 32768, 34816, 35840, 35841, 35712, 35776, 35777, 
+    35768,     0, 32768, 34816, 35840, 35841, 35712, 35776, 
+    35777, 35768, 35772,     0, 32768, 34816, 35840, 35841, 
+    35712, 35776, 35777, 35779, 35772,     0, 32768, 34816, 
+    35840, 35841, 35712, 35776, 35777, 35779, 35772, 35774, 
+        0, 32768, 34816, 35840, 35841, 35712,     0, 32768, 
+    34816, 35840, 35841, 35712, 35776,     0, 32768, 34816, 
+    35840, 35841, 35712, 35776,     0, 32768, 34816, 35840, 
+    35841, 35712, 35776, 35778,     0, 32768, 34816, 35840, 
+    35841, 35843, 35776,     0, 32768, 34816, 35840, 35841, 
+    35843, 35776, 35780,     0, 32768, 34816, 35840, 35841, 
+    35843, 35776, 35780,     0, 32768, 34816, 35840, 35841, 
+    35843, 35776, 35784, 35782,     0, 32768, 34816, 35840, 
+    35841, 35843, 35776,     0, 32768, 34816, 35840, 35841, 
+    35843, 35776, 35784,     0, 32768, 34816, 35840, 35841, 
+    35843, 35776, 35784,     0, 32768, 34816, 35840, 35841, 
+    35843, 35776, 35784, 35786,     0, 32768, 34816, 35840, 
+    35841, 35843, 35776, 35784,     0, 32768, 34816, 35840, 
+    35841, 35843, 35776, 35792, 35788,     0, 32768, 34816, 
+    35840, 35841, 35843, 35776, 35792, 35788,     0, 32768, 
+    34816, 35840, 35841, 35843, 35776, 35792, 35793, 35790, 
+        0, 32768, 34816, 35840, 35841, 35843, 35776,     0, 
+    32768, 34816, 35840, 35841, 35843, 35776, 35792,     0, 
+    32768, 34816, 35840, 35841, 35843, 35776, 35792,     0, 
+    32768, 34816, 35840, 35841, 35843, 35776, 35792, 35794, 
+        0, 32768, 34816, 35840, 35841, 35843, 35776, 35792, 
+        0, 32768, 34816, 35840, 35841, 35843, 35776, 35792, 
+    35796,     0, 32768, 34816, 35840, 35841, 35843, 35776, 
+    35792, 35796,     0, 32768, 34816, 35840, 35841, 35843, 
+    35776, 35792, 35800, 35798,     0, 32768, 34816, 35840, 
+    35841, 35843, 35776, 35792,     0, 32768, 34816, 35840, 
+    35841, 35843, 35776, 35808, 35800,     0, 32768, 34816, 
+    35840, 35841, 35843, 35776, 35808, 35800,     0, 32768, 
+    34816, 35840, 35841, 35843, 35776, 35808, 35800, 35802, 
+        0, 32768, 34816, 35840, 35841, 35843, 35776, 35808, 
+    35800,     0, 32768, 34816, 35840, 35841, 35843, 35776, 
+    35808, 35809, 35804,     0, 32768, 34816, 35840, 35841, 
+    35843, 35776, 35808, 35809, 35804,     0, 32768, 34816, 
+    35840, 35841, 35843, 35776, 35808, 35809, 35804, 35806, 
+        0, 32768, 34816, 35840, 35841, 35843, 35776,     0, 
+    32768, 34816, 35840, 35841, 35843, 35776, 35808,     0, 
+    32768, 34816, 35840, 35841, 35843, 35776, 35808,     0, 
+    32768, 34816, 35840, 35841, 35843, 35776, 35808, 35810, 
+        0, 32768, 34816, 35840, 35841, 35843, 35776, 35808, 
+        0, 32768, 34816, 35840, 35841, 35843, 35776, 35808, 
+    35812,     0, 32768, 34816, 35840, 35841, 35843, 35776, 
+    35808, 35812,     0, 32768, 34816, 35840, 35841, 35843, 
+    35776, 35808, 35816, 35814,     0, 32768, 34816, 35840, 
+    35841, 35843, 35847, 35808,     0, 32768, 34816, 35840, 
+    35841, 35843, 35847, 35808, 35816,     0, 32768, 34816, 
+    35840, 35841, 35843, 35847, 35808, 35816,     0, 32768, 
+    34816, 35840, 35841, 35843, 35847, 35808, 35816, 35818, 
+        0, 32768, 34816, 35840, 35841, 35843, 35847, 35808, 
+    35816,     0, 32768, 34816, 35840, 35841, 35843, 35847, 
+    35808, 35824, 35820,     0, 32768, 34816, 35840, 35841, 
+    35843, 35847, 35808, 35824, 35820,     0, 32768, 34816, 
+    35840, 35841, 35843, 35847, 35808, 35824, 35825, 35822, 
+        0, 32768, 34816, 35840, 35841, 35843, 35847, 35808, 
+        0, 32768, 34816, 35840, 35841, 35843, 35847, 35808, 
+    35824,     0, 32768, 34816, 35840, 35841, 35843, 35847, 
+    35808, 35824,     0, 32768, 34816, 35840, 35841, 35843, 
+    35847, 35808, 35824, 35826,     0, 32768, 34816, 35840, 
+    35841, 35843, 35847, 35808, 35824,     0, 32768, 34816, 
+    35840, 35841, 35843, 35847, 35808, 35824, 35828,     0, 
+    32768, 34816, 35840, 35841, 35843, 35847, 35808, 35824, 
+    35828,     0, 32768, 34816, 35840, 35841, 35843, 35847, 
+    35808, 35824, 35832, 35830,     0, 32768, 34816, 35840, 
+    35841, 35843, 35847, 35808, 35824,     0, 32768, 34816, 
+    35840, 35841, 35843, 35847, 35808, 35824, 35832,     0, 
+    32768, 34816, 35840, 35841, 35843, 35847, 35808, 35824, 
+    35832,     0, 32768, 34816, 35840, 35841, 35843, 35847, 
+    35808, 35824, 35832, 35834,     0, 32768, 34816, 35840, 
+    35841, 35843, 35847, 35808, 35824, 35832,     0, 32768, 
+    34816, 35840, 35841, 35843, 35847, 35808, 35824, 35832, 
+    35836,     0, 32768, 34816, 35840, 35841, 35843, 35847, 
+    35808, 35824, 35832, 35836,     0, 32768, 34816, 35840, 
+    35841, 35843, 35847, 35808, 35824, 35832, 35836, 35838, 
+        0, 32768, 34816,     0, 32768, 34816, 35840,     0, 
+    32768, 34816, 35840,     0, 32768, 34816, 35840, 35842, 
+        0, 32768, 34816, 35840,     0, 32768, 34816, 35840, 
+    35844,     0, 32768, 34816, 35840, 35844,     0, 32768, 
+    34816, 35840, 35848, 35846,     0, 32768, 34816, 35840, 
+        0, 32768, 34816, 35840, 35848,     0, 32768, 34816, 
+    35840, 35848,     0, 32768, 34816, 35840, 35848, 35850, 
+        0, 32768, 34816, 35840, 35848,     0, 32768, 34816, 
+    35840, 35856, 35852,     0, 32768, 34816, 35840, 35856, 
+    35852,     0, 32768, 34816, 35840, 35856, 35857, 35854, 
+        0, 32768, 34816, 35840,     0, 32768, 34816, 35840, 
+    35856,     0, 32768, 34816, 35840, 35856,     0, 32768, 
+    34816, 35840, 35856, 35858,     0, 32768, 34816, 35840, 
+    35856,     0, 32768, 34816, 35840, 35856, 35860,     0, 
+    32768, 34816, 35840, 35856, 35860,     0, 32768, 34816, 
+    35840, 35856, 35864, 35862,     0, 32768, 34816, 35840, 
+    35856,     0, 32768, 34816, 35840, 35872, 35864,     0, 
+    32768, 34816, 35840, 35872, 35864,     0, 32768, 34816, 
+    35840, 35872, 35864, 35866,     0, 32768, 34816, 35840, 
+    35872, 35864,     0, 32768, 34816, 35840, 35872, 35873, 
+    35868,     0, 32768, 34816, 35840, 35872, 35873, 35868, 
+        0, 32768, 34816, 35840, 35872, 35873, 35868, 35870, 
+        0, 32768, 34816, 35840,     0, 32768, 34816, 35840, 
+    35872,     0, 32768, 34816, 35840, 35872,     0, 32768, 
+    34816, 35840, 35872, 35874,     0, 32768, 34816, 35840, 
+    35872,     0, 32768, 34816, 35840, 35872, 35876,     0, 
+    32768, 34816, 35840, 35872, 35876,     0, 32768, 34816, 
+    35840, 35872, 35880, 35878,     0, 32768, 34816, 35840, 
+    35872,     0, 32768, 34816, 35840, 35872, 35880,     0, 
+    32768, 34816, 35840, 35872, 35880,     0, 32768, 34816, 
+    35840, 35872, 35880, 35882,     0, 32768, 34816, 35840, 
+    35872, 35880,     0, 32768, 34816, 35840, 35872, 35888, 
+    35884,     0, 32768, 34816, 35840, 35872, 35888, 35884, 
+        0, 32768, 34816, 35840, 35872, 35888, 35889, 35886, 
+        0, 32768, 34816, 35840, 35872,     0, 32768, 34816, 
+    35840, 35904, 35888,     0, 32768, 34816, 35840, 35904, 
+    35888,     0, 32768, 34816, 35840, 35904, 35888, 35890, 
+        0, 32768, 34816, 35840, 35904, 35888,     0, 32768, 
+    34816, 35840, 35904, 35888, 35892,     0, 32768, 34816, 
+    35840, 35904, 35888, 35892,     0, 32768, 34816, 35840, 
+    35904, 35888, 35896, 35894,     0, 32768, 34816, 35840, 
+    35904, 35888,     0, 32768, 34816, 35840, 35904, 35905, 
+    35896,     0, 32768, 34816, 35840, 35904, 35905, 35896, 
+        0, 32768, 34816, 35840, 35904, 35905, 35896, 35898, 
+        0, 32768, 34816, 35840, 35904, 35905, 35896,     0, 
+    32768, 34816, 35840, 35904, 35905, 35896, 35900,     0, 
+    32768, 34816, 35840, 35904, 35905, 35907, 35900,     0, 
+    32768, 34816, 35840, 35904, 35905, 35907, 35900, 35902, 
+        0, 32768, 34816, 35840,     0, 32768, 34816, 35840, 
+    35904,     0, 32768, 34816, 35840, 35904,     0, 32768, 
+    34816, 35840, 35904, 35906,     0, 32768, 34816, 35840, 
+    35904,     0, 32768, 34816, 35840, 35904, 35908,     0, 
+    32768, 34816, 35840, 35904, 35908,     0, 32768, 34816, 
+    35840, 35904, 35912, 35910,     0, 32768, 34816, 35840, 
+    35904,     0, 32768, 34816, 35840, 35904, 35912,     0, 
+    32768, 34816, 35840, 35904, 35912,     0, 32768, 34816, 
+    35840, 35904, 35912, 35914,     0, 32768, 34816, 35840, 
+    35904, 35912,     0, 32768, 34816, 35840, 35904, 35920, 
+    35916,     0, 32768, 34816, 35840, 35904, 35920, 35916, 
+        0, 32768, 34816, 35840, 35904, 35920, 35921, 35918, 
+        0, 32768, 34816, 35840, 35904,     0, 32768, 34816, 
+    35840, 35904, 35920,     0, 32768, 34816, 35840, 35904, 
+    35920,     0, 32768, 34816, 35840, 35904, 35920, 35922, 
+        0, 32768, 34816, 35840, 35904, 35920,     0, 32768, 
+    34816, 35840, 35904, 35920, 35924,     0, 32768, 34816, 
+    35840, 35904, 35920, 35924,     0, 32768, 34816, 35840, 
+    35904, 35920, 35928, 35926,     0, 32768, 34816, 35840, 
+    35904, 35920,     0, 32768, 34816, 35840, 35904, 35936, 
+    35928,     0, 32768, 34816, 35840, 35904, 35936, 35928, 
+        0, 32768, 34816, 35840, 35904, 35936, 35928, 35930, 
+        0, 32768, 34816, 35840, 35904, 35936, 35928,     0, 
+    32768, 34816, 35840, 35904, 35936, 35937, 35932,     0, 
+    32768, 34816, 35840, 35904, 35936, 35937, 35932,     0, 
+    32768, 34816, 35840, 35904, 35936, 35937, 35932, 35934, 
+        0, 32768, 34816, 35840, 35904,     0, 32768, 34816, 
+    35840, 35968, 35936,     0, 32768, 34816, 35840, 35968, 
+    35936,     0, 32768, 34816, 35840, 35968, 35936, 35938, 
+        0, 32768, 34816, 35840, 35968, 35936,     0, 32768, 
+    34816, 35840, 35968, 35936, 35940,     0, 32768, 34816, 
+    35840, 35968, 35936, 35940,     0, 32768, 34816, 35840, 
+    35968, 35936, 35944, 35942,     0, 32768, 34816, 35840, 
+    35968, 35936,     0, 32768, 34816, 35840, 35968, 35936, 
+    35944,     0, 32768, 34816, 35840, 35968, 35936, 35944, 
+        0, 32768, 34816, 35840, 35968, 35936, 35944, 35946, 
+        0, 32768, 34816, 35840, 35968, 35936, 35944,     0, 
+    32768, 34816, 35840, 35968, 35936, 35952, 35948,     0, 
+    32768, 34816, 35840, 35968, 35936, 35952, 35948,     0, 
+    32768, 34816, 35840, 35968, 35936, 35952, 35953, 35950, 
+        0, 32768, 34816, 35840, 35968, 35936,     0, 32768, 
+    34816, 35840, 35968, 35969, 35952,     0, 32768, 34816, 
+    35840, 35968, 35969, 35952,     0, 32768, 34816, 35840, 
+    35968, 35969, 35952, 35954,     0, 32768, 34816, 35840, 
+    35968, 35969, 35952,     0, 32768, 34816, 35840, 35968, 
+    35969, 35952, 35956,     0, 32768, 34816, 35840, 35968, 
+    35969, 35952, 35956,     0, 32768, 34816, 35840, 35968, 
+    35969, 35952, 35960, 35958,     0, 32768, 34816, 35840, 
+    35968, 35969, 35952,     0, 32768, 34816, 35840, 35968, 
+    35969, 35952, 35960,     0, 32768, 34816, 35840, 35968, 
+    35969, 35971, 35960,     0, 32768, 34816, 35840, 35968, 
+    35969, 35971, 35960, 35962,     0, 32768, 34816, 35840, 
+    35968, 35969, 35971, 35960,     0, 32768, 34816, 35840, 
+    35968, 35969, 35971, 35960, 35964,     0, 32768, 34816, 
+    35840, 35968, 35969, 35971, 35960, 35964,     0, 32768, 
+    34816, 35840, 35968, 35969, 35971, 35960, 35964, 35966, 
+        0, 32768, 34816, 35840,     0, 32768, 34816, 35840, 
+    35968,     0, 32768, 34816, 35840, 35968,     0, 32768, 
+    34816, 35840, 35968, 35970,     0, 32768, 34816, 35840, 
+    35968,     0, 32768, 34816, 35840, 35968, 35972,     0, 
+    32768, 34816, 35840, 35968, 35972,     0, 32768, 34816, 
+    35840, 35968, 35976, 35974,     0, 32768, 34816, 35840, 
+    35968,     0, 32768, 34816, 35840, 35968, 35976,     0, 
+    32768, 34816, 35840, 35968, 35976,     0, 32768, 34816, 
+    35840, 35968, 35976, 35978,     0, 32768, 34816, 35840, 
+    35968, 35976,     0, 32768, 34816, 35840, 35968, 35984, 
+    35980,     0, 32768, 34816, 35840, 35968, 35984, 35980, 
+        0, 32768, 34816, 35840, 35968, 35984, 35985, 35982, 
+        0, 32768, 34816, 35840, 35968,     0, 32768, 34816, 
+    35840, 35968, 35984,     0, 32768, 34816, 35840, 35968, 
+    35984,     0, 32768, 34816, 35840, 35968, 35984, 35986, 
+        0, 32768, 34816, 35840, 35968, 35984,     0, 32768, 
+    34816, 35840, 35968, 35984, 35988,     0, 32768, 34816, 
+    35840, 35968, 35984, 35988,     0, 32768, 34816, 35840, 
+    35968, 35984, 35992, 35990,     0, 32768, 34816, 35840, 
+    35968, 35984,     0, 32768, 34816, 35840, 35968, 36000, 
+    35992,     0, 32768, 34816, 35840, 35968, 36000, 35992, 
+        0, 32768, 34816, 35840, 35968, 36000, 35992, 35994, 
+        0, 32768, 34816, 35840, 35968, 36000, 35992,     0, 
+    32768, 34816, 35840, 35968, 36000, 36001, 35996,     0, 
+    32768, 34816, 35840, 35968, 36000, 36001, 35996,     0, 
+    32768, 34816, 35840, 35968, 36000, 36001, 35996, 35998, 
+        0, 32768, 34816, 35840, 35968,     0, 32768, 34816, 
+    35840, 35968, 36000,     0, 32768, 34816, 35840, 35968, 
+    36000,     0, 32768, 34816, 35840, 35968, 36000, 36002, 
+        0, 32768, 34816, 35840, 35968, 36000,     0, 32768, 
+    34816, 35840, 35968, 36000, 36004,     0, 32768, 34816, 
+    35840, 35968, 36000, 36004,     0, 32768, 34816, 35840, 
+    35968, 36000, 36008, 36006,     0, 32768, 34816, 35840, 
+    35968, 36000,     0, 32768, 34816, 35840, 35968, 36000, 
+    36008,     0, 32768, 34816, 35840, 35968, 36000, 36008, 
+        0, 32768, 34816, 35840, 35968, 36000, 36008, 36010, 
+        0, 32768, 34816, 35840, 35968, 36000, 36008,     0, 
+    32768, 34816, 35840, 35968, 36000, 36016, 36012,     0, 
+    32768, 34816, 35840, 35968, 36000, 36016, 36012,     0, 
+    32768, 34816, 35840, 35968, 36000, 36016, 36017, 36014, 
+        0, 32768, 34816, 35840, 35968, 36000,     0, 32768, 
+    34816, 35840, 35968, 36032, 36016,     0, 32768, 34816, 
+    35840, 35968, 36032, 36016,     0, 32768, 34816, 35840, 
+    35968, 36032, 36016, 36018,     0, 32768, 34816, 35840, 
+    35968, 36032, 36016,     0, 32768, 34816, 35840, 35968, 
+    36032, 36016, 36020,     0, 32768, 34816, 35840, 35968, 
+    36032, 36016, 36020,     0, 32768, 34816, 35840, 35968, 
+    36032, 36016, 36024, 36022,     0, 32768, 34816, 35840, 
+    35968, 36032, 36016,     0, 32768, 34816, 35840, 35968, 
+    36032, 36033, 36024,     0, 32768, 34816, 35840, 35968, 
+    36032, 36033, 36024,     0, 32768, 34816, 35840, 35968, 
+    36032, 36033, 36024, 36026,     0, 32768, 34816, 35840, 
+    35968, 36032, 36033, 36024,     0, 32768, 34816, 35840, 
+    35968, 36032, 36033, 36024, 36028,     0, 32768, 34816, 
+    35840, 35968, 36032, 36033, 36035, 36028,     0, 32768, 
+    34816, 35840, 35968, 36032, 36033, 36035, 36028, 36030, 
+        0, 32768, 34816, 35840, 35968,     0, 32768, 34816, 
+    35840, 36096, 36032,     0, 32768, 34816, 35840, 36096, 
+    36032,     0, 32768, 34816, 35840, 36096, 36032, 36034, 
+        0, 32768, 34816, 35840, 36096, 36032,     0, 32768, 
+    34816, 35840, 36096, 36032, 36036,     0, 32768, 34816, 
+    35840, 36096, 36032, 36036,     0, 32768, 34816, 35840, 
+    36096, 36032, 36040, 36038,     0, 32768, 34816, 35840, 
+    36096, 36032,     0, 32768, 34816, 35840, 36096, 36032, 
+    36040,     0, 32768, 34816, 35840, 36096, 36032, 36040, 
+        0, 32768, 34816, 35840, 36096, 36032, 36040, 36042, 
+        0, 32768, 34816, 35840, 36096, 36032, 36040,     0, 
+    32768, 34816, 35840, 36096, 36032, 36048, 36044,     0, 
+    32768, 34816, 35840, 36096, 36032, 36048, 36044,     0, 
+    32768, 34816, 35840, 36096, 36032, 36048, 36049, 36046, 
+        0, 32768, 34816, 35840, 36096, 36032,     0, 32768, 
+    34816, 35840, 36096, 36032, 36048,     0, 32768, 34816, 
+    35840, 36096, 36032, 36048,     0, 32768, 34816, 35840, 
+    36096, 36032, 36048, 36050,     0, 32768, 34816, 35840, 
+    36096, 36032, 36048,     0, 32768, 34816, 35840, 36096, 
+    36032, 36048, 36052,     0, 32768, 34816, 35840, 36096, 
+    36032, 36048, 36052,     0, 32768, 34816, 35840, 36096, 
+    36032, 36048, 36056, 36054,     0, 32768, 34816, 35840, 
+    36096, 36032, 36048,     0, 32768, 34816, 35840, 36096, 
+    36032, 36064, 36056,     0, 32768, 34816, 35840, 36096, 
+    36032, 36064, 36056,     0, 32768, 34816, 35840, 36096, 
+    36032, 36064, 36056, 36058,     0, 32768, 34816, 35840, 
+    36096, 36032, 36064, 36056,     0, 32768, 34816, 35840, 
+    36096, 36032, 36064, 36065, 36060,     0, 32768, 34816, 
+    35840, 36096, 36032, 36064, 36065, 36060,     0, 32768, 
+    34816, 35840, 36096, 36032, 36064, 36065, 36060, 36062, 
+        0, 32768, 34816, 35840, 36096, 36032,     0, 32768, 
+    34816, 35840, 36096, 36097, 36064,     0, 32768, 34816, 
+    35840, 36096, 36097, 36064,     0, 32768, 34816, 35840, 
+    36096, 36097, 36064, 36066,     0, 32768, 34816, 35840, 
+    36096, 36097, 36064,     0, 32768, 34816, 35840, 36096, 
+    36097, 36064, 36068,     0, 32768, 34816, 35840, 36096, 
+    36097, 36064, 36068,     0, 32768, 34816, 35840, 36096, 
+    36097, 36064, 36072, 36070,     0, 32768, 34816, 35840, 
+    36096, 36097, 36064,     0, 32768, 34816, 35840, 36096, 
+    36097, 36064, 36072,     0, 32768, 34816, 35840, 36096, 
+    36097, 36064, 36072,     0, 32768, 34816, 35840, 36096, 
+    36097, 36064, 36072, 36074,     0, 32768, 34816, 35840, 
+    36096, 36097, 36064, 36072,     0, 32768, 34816, 35840, 
+    36096, 36097, 36064, 36080, 36076,     0, 32768, 34816, 
+    35840, 36096, 36097, 36064, 36080, 36076,     0, 32768, 
+    34816, 35840, 36096, 36097, 36064, 36080, 36081, 36078, 
+        0, 32768, 34816, 35840, 36096, 36097, 36064,     0, 
+    32768, 34816, 35840, 36096, 36097, 36064, 36080,     0, 
+    32768, 34816, 35840, 36096, 36097, 36099, 36080,     0, 
+    32768, 34816, 35840, 36096, 36097, 36099, 36080, 36082, 
+        0, 32768, 34816, 35840, 36096, 36097, 36099, 36080, 
+        0, 32768, 34816, 35840, 36096, 36097, 36099, 36080, 
+    36084,     0, 32768, 34816, 35840, 36096, 36097, 36099, 
+    36080, 36084,     0, 32768, 34816, 35840, 36096, 36097, 
+    36099, 36080, 36088, 36086,     0, 32768, 34816, 35840, 
+    36096, 36097, 36099, 36080,     0, 32768, 34816, 35840, 
+    36096, 36097, 36099, 36080, 36088,     0, 32768, 34816, 
+    35840, 36096, 36097, 36099, 36080, 36088,     0, 32768, 
+    34816, 35840, 36096, 36097, 36099, 36080, 36088, 36090, 
+        0, 32768, 34816, 35840, 36096, 36097, 36099, 36103, 
+    36088,     0, 32768, 34816, 35840, 36096, 36097, 36099, 
+    36103, 36088, 36092,     0, 32768, 34816, 35840, 36096, 
+    36097, 36099, 36103, 36088, 36092,     0, 32768, 34816, 
+    35840, 36096, 36097, 36099, 36103, 36088, 36092, 36094, 
+        0, 32768, 34816, 35840,     0, 32768, 36864, 35840, 
+    36096,     0, 32768, 36864, 35840, 36096,     0, 32768, 
+    36864, 35840, 36096, 36098,     0, 32768, 36864, 35840, 
+    36096,     0, 32768, 36864, 35840, 36096, 36100,     0, 
+    32768, 36864, 35840, 36096, 36100,     0, 32768, 36864, 
+    35840, 36096, 36104, 36102,     0, 32768, 36864, 35840, 
+    36096,     0, 32768, 36864, 35840, 36096, 36104,     0, 
+    32768, 36864, 35840, 36096, 36104,     0, 32768, 36864, 
+    35840, 36096, 36104, 36106,     0, 32768, 36864, 35840, 
+    36096, 36104,     0, 32768, 36864, 35840, 36096, 36112, 
+    36108,     0, 32768, 36864, 35840, 36096, 36112, 36108, 
+        0, 32768, 36864, 35840, 36096, 36112, 36113, 36110, 
+        0, 32768, 36864, 35840, 36096,     0, 32768, 36864, 
+    35840, 36096, 36112,     0, 32768, 36864, 35840, 36096, 
+    36112,     0, 32768, 36864, 35840, 36096, 36112, 36114, 
+        0, 32768, 36864, 35840, 36096, 36112,     0, 32768, 
+    36864, 35840, 36096, 36112, 36116,     0, 32768, 36864, 
+    35840, 36096, 36112, 36116,     0, 32768, 36864, 35840, 
+    36096, 36112, 36120, 36118,     0, 32768, 36864, 35840, 
+    36096, 36112,     0, 32768, 36864, 35840, 36096, 36128, 
+    36120,     0, 32768, 36864, 35840, 36096, 36128, 36120, 
+        0, 32768, 36864, 35840, 36096, 36128, 36120, 36122, 
+        0, 32768, 36864, 35840, 36096, 36128, 36120,     0, 
+    32768, 36864, 35840, 36096, 36128, 36129, 36124,     0, 
+    32768, 36864, 35840, 36096, 36128, 36129, 36124,     0, 
+    32768, 36864, 35840, 36096, 36128, 36129, 36124, 36126, 
+        0, 32768, 36864, 35840, 36096,     0, 32768, 36864, 
+    35840, 36096, 36128,     0, 32768, 36864, 35840, 36096, 
+    36128,     0, 32768, 36864, 35840, 36096, 36128, 36130, 
+        0, 32768, 36864, 35840, 36096, 36128,     0, 32768, 
+    36864, 35840, 36096, 36128, 36132,     0, 32768, 36864, 
+    35840, 36096, 36128, 36132,     0, 32768, 36864, 35840, 
+    36096, 36128, 36136, 36134,     0, 32768, 36864, 35840, 
+    36096, 36128,     0, 32768, 36864, 35840, 36096, 36128, 
+    36136,     0, 32768, 36864, 35840, 36096, 36128, 36136, 
+        0, 32768, 36864, 35840, 36096, 36128, 36136, 36138, 
+        0, 32768, 36864, 35840, 36096, 36128, 36136,     0, 
+    32768, 36864, 35840, 36096, 36128, 36144, 36140,     0, 
+    32768, 36864, 35840, 36096, 36128, 36144, 36140,     0, 
+    32768, 36864, 35840, 36096, 36128, 36144, 36145, 36142, 
+        0, 32768, 36864, 35840, 36096, 36128,     0, 32768, 
+    36864, 35840, 36096, 36160, 36144,     0, 32768, 36864, 
+    35840, 36096, 36160, 36144,     0, 32768, 36864, 35840, 
+    36096, 36160, 36144, 36146,     0, 32768, 36864, 35840, 
+    36096, 36160, 36144,     0, 32768, 36864, 35840, 36096, 
+    36160, 36144, 36148,     0, 32768, 36864, 35840, 36096, 
+    36160, 36144, 36148,     0, 32768, 36864, 35840, 36096, 
+    36160, 36144, 36152, 36150,     0, 32768, 36864, 35840, 
+    36096, 36160, 36144,     0, 32768, 36864, 35840, 36096, 
+    36160, 36161, 36152,     0, 32768, 36864, 35840, 36096, 
+    36160, 36161, 36152,     0, 32768, 36864, 35840, 36096, 
+    36160, 36161, 36152, 36154,     0, 32768, 36864, 35840, 
+    36096, 36160, 36161, 36152,     0, 32768, 36864, 35840, 
+    36096, 36160, 36161, 36152, 36156,     0, 32768, 36864, 
+    35840, 36096, 36160, 36161, 36163, 36156,     0, 32768, 
+    36864, 35840, 36096, 36160, 36161, 36163, 36156, 36158, 
+        0, 32768, 36864, 35840, 36096,     0, 32768, 36864, 
+    35840, 36096, 36160,     0, 32768, 36864, 35840, 36096, 
+    36160,     0, 32768, 36864, 35840, 36096, 36160, 36162, 
+        0, 32768, 36864, 35840, 36096, 36160,     0, 32768, 
+    36864, 35840, 36096, 36160, 36164,     0, 32768, 36864, 
+    35840, 36096, 36160, 36164,     0, 32768, 36864, 35840, 
+    36096, 36160, 36168, 36166,     0, 32768, 36864, 35840, 
+    36096, 36160,     0, 32768, 36864, 35840, 36096, 36160, 
+    36168,     0, 32768, 36864, 35840, 36096, 36160, 36168, 
+        0, 32768, 36864, 35840, 36096, 36160, 36168, 36170, 
+        0, 32768, 36864, 35840, 36096, 36160, 36168,     0, 
+    32768, 36864, 35840, 36096, 36160, 36176, 36172,     0, 
+    32768, 36864, 35840, 36096, 36160, 36176, 36172,     0, 
+    32768, 36864, 35840, 36096, 36160, 36176, 36177, 36174, 
+        0, 32768, 36864, 35840, 36096, 36160,     0, 32768, 
+    36864, 35840, 36096, 36160, 36176,     0, 32768, 36864, 
+    35840, 36096, 36160, 36176,     0, 32768, 36864, 35840, 
+    36096, 36160, 36176, 36178,     0, 32768, 36864, 35840, 
+    36096, 36160, 36176,     0, 32768, 36864, 35840, 36096, 
+    36160, 36176, 36180,     0, 32768, 36864, 35840, 36096, 
+    36160, 36176, 36180,     0, 32768, 36864, 35840, 36096, 
+    36160, 36176, 36184, 36182,     0, 32768, 36864, 35840, 
+    36096, 36160, 36176,     0, 32768, 36864, 35840, 36096, 
+    36160, 36192, 36184,     0, 32768, 36864, 35840, 36096, 
+    36160, 36192, 36184,     0, 32768, 36864, 35840, 36096, 
+    36160, 36192, 36184, 36186,     0, 32768, 36864, 35840, 
+    36096, 36160, 36192, 36184,     0, 32768, 36864, 35840, 
+    36096, 36160, 36192, 36193, 36188,     0, 32768, 36864, 
+    35840, 36096, 36160, 36192, 36193, 36188,     0, 32768, 
+    36864, 35840, 36096, 36160, 36192, 36193, 36188, 36190, 
+        0, 32768, 36864, 35840, 36096, 36160,     0, 32768, 
+    36864, 35840, 36096, 36224, 36192,     0, 32768, 36864, 
+    35840, 36096, 36224, 36192,     0, 32768, 36864, 35840, 
+    36096, 36224, 36192, 36194,     0, 32768, 36864, 35840, 
+    36096, 36224, 36192,     0, 32768, 36864, 35840, 36096, 
+    36224, 36192, 36196,     0, 32768, 36864, 35840, 36096, 
+    36224, 36192, 36196,     0, 32768, 36864, 35840, 36096, 
+    36224, 36192, 36200, 36198,     0, 32768, 36864, 35840, 
+    36096, 36224, 36192,     0, 32768, 36864, 35840, 36096, 
+    36224, 36192, 36200,     0, 32768, 36864, 35840, 36096, 
+    36224, 36192, 36200,     0, 32768, 36864, 35840, 36096, 
+    36224, 36192, 36200, 36202,     0, 32768, 36864, 35840, 
+    36096, 36224, 36192, 36200,     0, 32768, 36864, 35840, 
+    36096, 36224, 36192, 36208, 36204,     0, 32768, 36864, 
+    35840, 36096, 36224, 36192, 36208, 36204,     0, 32768, 
+    36864, 35840, 36096, 36224, 36192, 36208, 36209, 36206, 
+        0, 32768, 36864, 35840, 36096, 36224, 36192,     0, 
+    32768, 36864, 35840, 36096, 36224, 36225, 36208,     0, 
+    32768, 36864, 35840, 36096, 36224, 36225, 36208,     0, 
+    32768, 36864, 35840, 36096, 36224, 36225, 36208, 36210, 
+        0, 32768, 36864, 35840, 36096, 36224, 36225, 36208, 
+        0, 32768, 36864, 35840, 36096, 36224, 36225, 36208, 
+    36212,     0, 32768, 36864, 35840, 36096, 36224, 36225, 
+    36208, 36212,     0, 32768, 36864, 35840, 36096, 36224, 
+    36225, 36208, 36216, 36214,     0, 32768, 36864, 35840, 
+    36096, 36224, 36225, 36208,     0, 32768, 36864, 35840, 
+    36096, 36224, 36225, 36208, 36216,     0, 32768, 36864, 
+    35840, 36096, 36224, 36225, 36227, 36216,     0, 32768, 
+    36864, 35840, 36096, 36224, 36225, 36227, 36216, 36218, 
+        0, 32768, 36864, 35840, 36096, 36224, 36225, 36227, 
+    36216,     0, 32768, 36864, 35840, 36096, 36224, 36225, 
+    36227, 36216, 36220,     0, 32768, 36864, 35840, 36096, 
+    36224, 36225, 36227, 36216, 36220,     0, 32768, 36864, 
+    35840, 36096, 36224, 36225, 36227, 36216, 36220, 36222, 
+        0, 32768, 36864, 35840, 36096,     0, 32768, 36864, 
+    35840, 36352, 36224,     0, 32768, 36864, 35840, 36352, 
+    36224,     0, 32768, 36864, 35840, 36352, 36224, 36226, 
+        0, 32768, 36864, 35840, 36352, 36224,     0, 32768, 
+    36864, 35840, 36352, 36224, 36228,     0, 32768, 36864, 
+    35840, 36352, 36224, 36228,     0, 32768, 36864, 35840, 
+    36352, 36224, 36232, 36230,     0, 32768, 36864, 35840, 
+    36352, 36224,     0, 32768, 36864, 35840, 36352, 36224, 
+    36232,     0, 32768, 36864, 35840, 36352, 36224, 36232, 
+        0, 32768, 36864, 35840, 36352, 36224, 36232, 36234, 
+        0, 32768, 36864, 35840, 36352, 36224, 36232,     0, 
+    32768, 36864, 35840, 36352, 36224, 36240, 36236,     0, 
+    32768, 36864, 35840, 36352, 36224, 36240, 36236,     0, 
+    32768, 36864, 35840, 36352, 36224, 36240, 36241, 36238, 
+        0, 32768, 36864, 35840, 36352, 36224,     0, 32768, 
+    36864, 35840, 36352, 36224, 36240,     0, 32768, 36864, 
+    35840, 36352, 36224, 36240,     0, 32768, 36864, 35840, 
+    36352, 36224, 36240, 36242,     0, 32768, 36864, 35840, 
+    36352, 36224, 36240,     0, 32768, 36864, 35840, 36352, 
+    36224, 36240, 36244,     0, 32768, 36864, 35840, 36352, 
+    36224, 36240, 36244,     0, 32768, 36864, 35840, 36352, 
+    36224, 36240, 36248, 36246,     0, 32768, 36864, 35840, 
+    36352, 36224, 36240,     0, 32768, 36864, 35840, 36352, 
+    36224, 36256, 36248,     0, 32768, 36864, 35840, 36352, 
+    36224, 36256, 36248,     0, 32768, 36864, 35840, 36352, 
+    36224, 36256, 36248, 36250,     0, 32768, 36864, 35840, 
+    36352, 36224, 36256, 36248,     0, 32768, 36864, 35840, 
+    36352, 36224, 36256, 36257, 36252,     0, 32768, 36864, 
+    35840, 36352, 36224, 36256, 36257, 36252,     0, 32768, 
+    36864, 35840, 36352, 36224, 36256, 36257, 36252, 36254, 
+        0, 32768, 36864, 35840, 36352, 36224,     0, 32768, 
+    36864, 35840, 36352, 36224, 36256,     0, 32768, 36864, 
+    35840, 36352, 36224, 36256,     0, 32768, 36864, 35840, 
+    36352, 36224, 36256, 36258,     0, 32768, 36864, 35840, 
+    36352, 36224, 36256,     0, 32768, 36864, 35840, 36352, 
+    36224, 36256, 36260,     0, 32768, 36864, 35840, 36352, 
+    36224, 36256, 36260,     0, 32768, 36864, 35840, 36352, 
+    36224, 36256, 36264, 36262,     0, 32768, 36864, 35840, 
+    36352, 36224, 36256,     0, 32768, 36864, 35840, 36352, 
+    36224, 36256, 36264,     0, 32768, 36864, 35840, 36352, 
+    36224, 36256, 36264,     0, 32768, 36864, 35840, 36352, 
+    36224, 36256, 36264, 36266,     0, 32768, 36864, 35840, 
+    36352, 36224, 36256, 36264,     0, 32768, 36864, 35840, 
+    36352, 36224, 36256, 36272, 36268,     0, 32768, 36864, 
+    35840, 36352, 36224, 36256, 36272, 36268,     0, 32768, 
+    36864, 35840, 36352, 36224, 36256, 36272, 36273, 36270, 
+        0, 32768, 36864, 35840, 36352, 36224, 36256,     0, 
+    32768, 36864, 35840, 36352, 36224, 36288, 36272,     0, 
+    32768, 36864, 35840, 36352, 36224, 36288, 36272,     0, 
+    32768, 36864, 35840, 36352, 36224, 36288, 36272, 36274, 
+        0, 32768, 36864, 35840, 36352, 36224, 36288, 36272, 
+        0, 32768, 36864, 35840, 36352, 36224, 36288, 36272, 
+    36276,     0, 32768, 36864, 35840, 36352, 36224, 36288, 
+    36272, 36276,     0, 32768, 36864, 35840, 36352, 36224, 
+    36288, 36272, 36280, 36278,     0, 32768, 36864, 35840, 
+    36352, 36224, 36288, 36272,     0, 32768, 36864, 35840, 
+    36352, 36224, 36288, 36289, 36280,     0, 32768, 36864, 
+    35840, 36352, 36224, 36288, 36289, 36280,     0, 32768, 
+    36864, 35840, 36352, 36224, 36288, 36289, 36280, 36282, 
+        0, 32768, 36864, 35840, 36352, 36224, 36288, 36289, 
+    36280,     0, 32768, 36864, 35840, 36352, 36224, 36288, 
+    36289, 36280, 36284,     0, 32768, 36864, 35840, 36352, 
+    36224, 36288, 36289, 36291, 36284,     0, 32768, 36864, 
+    35840, 36352, 36224, 36288, 36289, 36291, 36284, 36286, 
+        0, 32768, 36864, 35840, 36352, 36224,     0, 32768, 
+    36864, 35840, 36352, 36353, 36288,     0, 32768, 36864, 
+    35840, 36352, 36353, 36288,     0, 32768, 36864, 35840, 
+    36352, 36353, 36288, 36290,     0, 32768, 36864, 35840, 
+    36352, 36353, 36288,     0, 32768, 36864, 35840, 36352, 
+    36353, 36288, 36292,     0, 32768, 36864, 35840, 36352, 
+    36353, 36288, 36292,     0, 32768, 36864, 35840, 36352, 
+    36353, 36288, 36296, 36294,     0, 32768, 36864, 35840, 
+    36352, 36353, 36288,     0, 32768, 36864, 35840, 36352, 
+    36353, 36288, 36296,     0, 32768, 36864, 35840, 36352, 
+    36353, 36288, 36296,     0, 32768, 36864, 35840, 36352, 
+    36353, 36288, 36296, 36298,     0, 32768, 36864, 35840, 
+    36352, 36353, 36288, 36296,     0, 32768, 36864, 35840, 
+    36352, 36353, 36288, 36304, 36300,     0, 32768, 36864, 
+    35840, 36352, 36353, 36288, 36304, 36300,     0, 32768, 
+    36864, 35840, 36352, 36353, 36288, 36304, 36305, 36302, 
+        0, 32768, 36864, 35840, 36352, 36353, 36288,     0, 
+    32768, 36864, 35840, 36352, 36353, 36288, 36304,     0, 
+    32768, 36864, 35840, 36352, 36353, 36288, 36304,     0, 
+    32768, 36864, 35840, 36352, 36353, 36288, 36304, 36306, 
+        0, 32768, 36864, 35840, 36352, 36353, 36288, 36304, 
+        0, 32768, 36864, 35840, 36352, 36353, 36288, 36304, 
+    36308,     0, 32768, 36864, 35840, 36352, 36353, 36288, 
+    36304, 36308,     0, 32768, 36864, 35840, 36352, 36353, 
+    36288, 36304, 36312, 36310,     0, 32768, 36864, 35840, 
+    36352, 36353, 36288, 36304,     0, 32768, 36864, 35840, 
+    36352, 36353, 36288, 36320, 36312,     0, 32768, 36864, 
+    35840, 36352, 36353, 36288, 36320, 36312,     0, 32768, 
+    36864, 35840, 36352, 36353, 36288, 36320, 36312, 36314, 
+        0, 32768, 36864, 35840, 36352, 36353, 36288, 36320, 
+    36312,     0, 32768, 36864, 35840, 36352, 36353, 36288, 
+    36320, 36321, 36316,     0, 32768, 36864, 35840, 36352, 
+    36353, 36288, 36320, 36321, 36316,     0, 32768, 36864, 
+    35840, 36352, 36353, 36288, 36320, 36321, 36316, 36318, 
+        0, 32768, 36864, 35840, 36352, 36353, 36288,     0, 
+    32768, 36864, 35840, 36352, 36353, 36288, 36320,     0, 
+    32768, 36864, 35840, 36352, 36353, 36355, 36320,     0, 
+    32768, 36864, 35840, 36352, 36353, 36355, 36320, 36322, 
+        0, 32768, 36864, 35840, 36352, 36353, 36355, 36320, 
+        0, 32768, 36864, 35840, 36352, 36353, 36355, 36320, 
+    36324,     0, 32768, 36864, 35840, 36352, 36353, 36355, 
+    36320, 36324,     0, 32768, 36864, 35840, 36352, 36353, 
+    36355, 36320, 36328, 36326,     0, 32768, 36864, 35840, 
+    36352, 36353, 36355, 36320,     0, 32768, 36864, 35840, 
+    36352, 36353, 36355, 36320, 36328,     0, 32768, 36864, 
+    35840, 36352, 36353, 36355, 36320, 36328,     0, 32768, 
+    36864, 35840, 36352, 36353, 36355, 36320, 36328, 36330, 
+        0, 32768, 36864, 35840, 36352, 36353, 36355, 36320, 
+    36328,     0, 32768, 36864, 35840, 36352, 36353, 36355, 
+    36320, 36336, 36332,     0, 32768, 36864, 35840, 36352, 
+    36353, 36355, 36320, 36336, 36332,     0, 32768, 36864, 
+    35840, 36352, 36353, 36355, 36320, 36336, 36337, 36334, 
+        0, 32768, 36864, 35840, 36352, 36353, 36355, 36320, 
+        0, 32768, 36864, 35840, 36352, 36353, 36355, 36320, 
+    36336,     0, 32768, 36864, 35840, 36352, 36353, 36355, 
+    36320, 36336,     0, 32768, 36864, 35840, 36352, 36353, 
+    36355, 36320, 36336, 36338,     0, 32768, 36864, 35840, 
+    36352, 36353, 36355, 36359, 36336,     0, 32768, 36864, 
+    35840, 36352, 36353, 36355, 36359, 36336, 36340,     0, 
+    32768, 36864, 35840, 36352, 36353, 36355, 36359, 36336, 
+    36340,     0, 32768, 36864, 35840, 36352, 36353, 36355, 
+    36359, 36336, 36344, 36342,     0, 32768, 36864, 35840, 
+    36352, 36353, 36355, 36359, 36336,     0, 32768, 36864, 
+    35840, 36352, 36353, 36355, 36359, 36336, 36344,     0, 
+    32768, 36864, 35840, 36352, 36353, 36355, 36359, 36336, 
+    36344,     0, 32768, 36864, 35840, 36352, 36353, 36355, 
+    36359, 36336, 36344, 36346,     0, 32768, 36864, 35840, 
+    36352, 36353, 36355, 36359, 36336, 36344,     0, 32768, 
+    36864, 35840, 36352, 36353, 36355, 36359, 36336, 36344, 
+    36348,     0, 32768, 36864, 35840, 36352, 36353, 36355, 
+    36359, 36336, 36344, 36348,     0, 32768, 36864, 35840, 
+    36352, 36353, 36355, 36359, 36336, 36344, 36348, 36350, 
+        0, 32768, 36864, 35840,     0, 32768, 36864, 35840, 
+    36352,     0, 32768, 36864, 36865, 36352,     0, 32768, 
+    36864, 36865, 36352, 36354,     0, 32768, 36864, 36865, 
+    36352,     0, 32768, 36864, 36865, 36352, 36356,     0, 
+    32768, 36864, 36865, 36352, 36356,     0, 32768, 36864, 
+    36865, 36352, 36360, 36358,     0, 32768, 36864, 36865, 
+    36352,     0, 32768, 36864, 36865, 36352, 36360,     0, 
+    32768, 36864, 36865, 36352, 36360,     0, 32768, 36864, 
+    36865, 36352, 36360, 36362,     0, 32768, 36864, 36865, 
+    36352, 36360,     0, 32768, 36864, 36865, 36352, 36368, 
+    36364,     0, 32768, 36864, 36865, 36352, 36368, 36364, 
+        0, 32768, 36864, 36865, 36352, 36368, 36369, 36366, 
+        0, 32768, 36864, 36865, 36352,     0, 32768, 36864, 
+    36865, 36352, 36368,     0, 32768, 36864, 36865, 36352, 
+    36368,     0, 32768, 36864, 36865, 36352, 36368, 36370, 
+        0, 32768, 36864, 36865, 36352, 36368,     0, 32768, 
+    36864, 36865, 36352, 36368, 36372,     0, 32768, 36864, 
+    36865, 36352, 36368, 36372,     0, 32768, 36864, 36865, 
+    36352, 36368, 36376, 36374,     0, 32768, 36864, 36865, 
+    36352, 36368,     0, 32768, 36864, 36865, 36352, 36384, 
+    36376,     0, 32768, 36864, 36865, 36352, 36384, 36376, 
+        0, 32768, 36864, 36865, 36352, 36384, 36376, 36378, 
+        0, 32768, 36864, 36865, 36352, 36384, 36376,     0, 
+    32768, 36864, 36865, 36352, 36384, 36385, 36380,     0, 
+    32768, 36864, 36865, 36352, 36384, 36385, 36380,     0, 
+    32768, 36864, 36865, 36352, 36384, 36385, 36380, 36382, 
+        0, 32768, 36864, 36865, 36352,     0, 32768, 36864, 
+    36865, 36352, 36384,     0, 32768, 36864, 36865, 36352, 
+    36384,     0, 32768, 36864, 36865, 36352, 36384, 36386, 
+        0, 32768, 36864, 36865, 36352, 36384,     0, 32768, 
+    36864, 36865, 36352, 36384, 36388,     0, 32768, 36864, 
+    36865, 36352, 36384, 36388,     0, 32768, 36864, 36865, 
+    36352, 36384, 36392, 36390,     0, 32768, 36864, 36865, 
+    36352, 36384,     0, 32768, 36864, 36865, 36352, 36384, 
+    36392,     0, 32768, 36864, 36865, 36352, 36384, 36392, 
+        0, 32768, 36864, 36865, 36352, 36384, 36392, 36394, 
+        0, 32768, 36864, 36865, 36352, 36384, 36392,     0, 
+    32768, 36864, 36865, 36352, 36384, 36400, 36396,     0, 
+    32768, 36864, 36865, 36352, 36384, 36400, 36396,     0, 
+    32768, 36864, 36865, 36352, 36384, 36400, 36401, 36398, 
+        0, 32768, 36864, 36865, 36352, 36384,     0, 32768, 
+    36864, 36865, 36352, 36416, 36400,     0, 32768, 36864, 
+    36865, 36352, 36416, 36400,     0, 32768, 36864, 36865, 
+    36352, 36416, 36400, 36402,     0, 32768, 36864, 36865, 
+    36352, 36416, 36400,     0, 32768, 36864, 36865, 36352, 
+    36416, 36400, 36404,     0, 32768, 36864, 36865, 36352, 
+    36416, 36400, 36404,     0, 32768, 36864, 36865, 36352, 
+    36416, 36400, 36408, 36406,     0, 32768, 36864, 36865, 
+    36352, 36416, 36400,     0, 32768, 36864, 36865, 36352, 
+    36416, 36417, 36408,     0, 32768, 36864, 36865, 36352, 
+    36416, 36417, 36408,     0, 32768, 36864, 36865, 36352, 
+    36416, 36417, 36408, 36410,     0, 32768, 36864, 36865, 
+    36352, 36416, 36417, 36408,     0, 32768, 36864, 36865, 
+    36352, 36416, 36417, 36408, 36412,     0, 32768, 36864, 
+    36865, 36352, 36416, 36417, 36419, 36412,     0, 32768, 
+    36864, 36865, 36352, 36416, 36417, 36419, 36412, 36414, 
+        0, 32768, 36864, 36865, 36352,     0, 32768, 36864, 
+    36865, 36352, 36416,     0, 32768, 36864, 36865, 36352, 
+    36416,     0, 32768, 36864, 36865, 36352, 36416, 36418, 
+        0, 32768, 36864, 36865, 36352, 36416,     0, 32768, 
+    36864, 36865, 36352, 36416, 36420,     0, 32768, 36864, 
+    36865, 36352, 36416, 36420,     0, 32768, 36864, 36865, 
+    36352, 36416, 36424, 36422,     0, 32768, 36864, 36865, 
+    36352, 36416,     0, 32768, 36864, 36865, 36352, 36416, 
+    36424,     0, 32768, 36864, 36865, 36352, 36416, 36424, 
+        0, 32768, 36864, 36865, 36352, 36416, 36424, 36426, 
+        0, 32768, 36864, 36865, 36352, 36416, 36424,     0, 
+    32768, 36864, 36865, 36352, 36416, 36432, 36428,     0, 
+    32768, 36864, 36865, 36352, 36416, 36432, 36428,     0, 
+    32768, 36864, 36865, 36352, 36416, 36432, 36433, 36430, 
+        0, 32768, 36864, 36865, 36352, 36416,     0, 32768, 
+    36864, 36865, 36352, 36416, 36432,     0, 32768, 36864, 
+    36865, 36352, 36416, 36432,     0, 32768, 36864, 36865, 
+    36352, 36416, 36432, 36434,     0, 32768, 36864, 36865, 
+    36352, 36416, 36432,     0, 32768, 36864, 36865, 36352, 
+    36416, 36432, 36436,     0, 32768, 36864, 36865, 36352, 
+    36416, 36432, 36436,     0, 32768, 36864, 36865, 36352, 
+    36416, 36432, 36440, 36438,     0, 32768, 36864, 36865, 
+    36352, 36416, 36432,     0, 32768, 36864, 36865, 36352, 
+    36416, 36448, 36440,     0, 32768, 36864, 36865, 36352, 
+    36416, 36448, 36440,     0, 32768, 36864, 36865, 36352, 
+    36416, 36448, 36440, 36442,     0, 32768, 36864, 36865, 
+    36352, 36416, 36448, 36440,     0, 32768, 36864, 36865, 
+    36352, 36416, 36448, 36449, 36444,     0, 32768, 36864, 
+    36865, 36352, 36416, 36448, 36449, 36444,     0, 32768, 
+    36864, 36865, 36352, 36416, 36448, 36449, 36444, 36446, 
+        0, 32768, 36864, 36865, 36352, 36416,     0, 32768, 
+    36864, 36865, 36352, 36480, 36448,     0, 32768, 36864, 
+    36865, 36352, 36480, 36448,     0, 32768, 36864, 36865, 
+    36352, 36480, 36448, 36450,     0, 32768, 36864, 36865, 
+    36352, 36480, 36448,     0, 32768, 36864, 36865, 36352, 
+    36480, 36448, 36452,     0, 32768, 36864, 36865, 36352, 
+    36480, 36448, 36452,     0, 32768, 36864, 36865, 36352, 
+    36480, 36448, 36456, 36454,     0, 32768, 36864, 36865, 
+    36352, 36480, 36448,     0, 32768, 36864, 36865, 36352, 
+    36480, 36448, 36456,     0, 32768, 36864, 36865, 36352, 
+    36480, 36448, 36456,     0, 32768, 36864, 36865, 36352, 
+    36480, 36448, 36456, 36458,     0, 32768, 36864, 36865, 
+    36352, 36480, 36448, 36456,     0, 32768, 36864, 36865, 
+    36352, 36480, 36448, 36464, 36460,     0, 32768, 36864, 
+    36865, 36352, 36480, 36448, 36464, 36460,     0, 32768, 
+    36864, 36865, 36352, 36480, 36448, 36464, 36465, 36462, 
+        0, 32768, 36864, 36865, 36352, 36480, 36448,     0, 
+    32768, 36864, 36865, 36352, 36480, 36481, 36464,     0, 
+    32768, 36864, 36865, 36352, 36480, 36481, 36464,     0, 
+    32768, 36864, 36865, 36352, 36480, 36481, 36464, 36466, 
+        0, 32768, 36864, 36865, 36352, 36480, 36481, 36464, 
+        0, 32768, 36864, 36865, 36352, 36480, 36481, 36464, 
+    36468,     0, 32768, 36864, 36865, 36352, 36480, 36481, 
+    36464, 36468,     0, 32768, 36864, 36865, 36352, 36480, 
+    36481, 36464, 36472, 36470,     0, 32768, 36864, 36865, 
+    36352, 36480, 36481, 36464,     0, 32768, 36864, 36865, 
+    36352, 36480, 36481, 36464, 36472,     0, 32768, 36864, 
+    36865, 36352, 36480, 36481, 36483, 36472,     0, 32768, 
+    36864, 36865, 36352, 36480, 36481, 36483, 36472, 36474, 
+        0, 32768, 36864, 36865, 36352, 36480, 36481, 36483, 
+    36472,     0, 32768, 36864, 36865, 36352, 36480, 36481, 
+    36483, 36472, 36476,     0, 32768, 36864, 36865, 36352, 
+    36480, 36481, 36483, 36472, 36476,     0, 32768, 36864, 
+    36865, 36352, 36480, 36481, 36483, 36472, 36476, 36478, 
+        0, 32768, 36864, 36865, 36352,     0, 32768, 36864, 
+    36865, 36352, 36480,     0, 32768, 36864, 36865, 36352, 
+    36480,     0, 32768, 36864, 36865, 36352, 36480, 36482, 
+        0, 32768, 36864, 36865, 36352, 36480,     0, 32768, 
+    36864, 36865, 36352, 36480, 36484,     0, 32768, 36864, 
+    36865, 36352, 36480, 36484,     0, 32768, 36864, 36865, 
+    36352, 36480, 36488, 36486,     0, 32768, 36864, 36865, 
+    36352, 36480,     0, 32768, 36864, 36865, 36352, 36480, 
+    36488,     0, 32768, 36864, 36865, 36352, 36480, 36488, 
+        0, 32768, 36864, 36865, 36352, 36480, 36488, 36490, 
+        0, 32768, 36864, 36865, 36352, 36480, 36488,     0, 
+    32768, 36864, 36865, 36352, 36480, 36496, 36492,     0, 
+    32768, 36864, 36865, 36352, 36480, 36496, 36492,     0, 
+    32768, 36864, 36865, 36352, 36480, 36496, 36497, 36494, 
+        0, 32768, 36864, 36865, 36352, 36480,     0, 32768, 
+    36864, 36865, 36352, 36480, 36496,     0, 32768, 36864, 
+    36865, 36352, 36480, 36496,     0, 32768, 36864, 36865, 
+    36352, 36480, 36496, 36498,     0, 32768, 36864, 36865, 
+    36352, 36480, 36496,     0, 32768, 36864, 36865, 36352, 
+    36480, 36496, 36500,     0, 32768, 36864, 36865, 36352, 
+    36480, 36496, 36500,     0, 32768, 36864, 36865, 36352, 
+    36480, 36496, 36504, 36502,     0, 32768, 36864, 36865, 
+    36352, 36480, 36496,     0, 32768, 36864, 36865, 36352, 
+    36480, 36512, 36504,     0, 32768, 36864, 36865, 36352, 
+    36480, 36512, 36504,     0, 32768, 36864, 36865, 36352, 
+    36480, 36512, 36504, 36506,     0, 32768, 36864, 36865, 
+    36352, 36480, 36512, 36504,     0, 32768, 36864, 36865, 
+    36352, 36480, 36512, 36513, 36508,     0, 32768, 36864, 
+    36865, 36352, 36480, 36512, 36513, 36508,     0, 32768, 
+    36864, 36865, 36352, 36480, 36512, 36513, 36508, 36510, 
+        0, 32768, 36864, 36865, 36352, 36480,     0, 32768, 
+    36864, 36865, 36352, 36480, 36512,     0, 32768, 36864, 
+    36865, 36352, 36480, 36512,     0, 32768, 36864, 36865, 
+    36352, 36480, 36512, 36514,     0, 32768, 36864, 36865, 
+    36352, 36480, 36512,     0, 32768, 36864, 36865, 36352, 
+    36480, 36512, 36516,     0, 32768, 36864, 36865, 36352, 
+    36480, 36512, 36516,     0, 32768, 36864, 36865, 36352, 
+    36480, 36512, 36520, 36518,     0, 32768, 36864, 36865, 
+    36352, 36480, 36512,     0, 32768, 36864, 36865, 36352, 
+    36480, 36512, 36520,     0, 32768, 36864, 36865, 36352, 
+    36480, 36512, 36520,     0, 32768, 36864, 36865, 36352, 
+    36480, 36512, 36520, 36522,     0, 32768, 36864, 36865, 
+    36352, 36480, 36512, 36520,     0, 32768, 36864, 36865, 
+    36352, 36480, 36512, 36528, 36524,     0, 32768, 36864, 
+    36865, 36352, 36480, 36512, 36528, 36524,     0, 32768, 
+    36864, 36865, 36352, 36480, 36512, 36528, 36529, 36526, 
+        0, 32768, 36864, 36865, 36352, 36480, 36512,     0, 
+    32768, 36864, 36865, 36352, 36480, 36544, 36528,     0, 
+    32768, 36864, 36865, 36352, 36480, 36544, 36528,     0, 
+    32768, 36864, 36865, 36352, 36480, 36544, 36528, 36530, 
+        0, 32768, 36864, 36865, 36352, 36480, 36544, 36528, 
+        0, 32768, 36864, 36865, 36352, 36480, 36544, 36528, 
+    36532,     0, 32768, 36864, 36865, 36352, 36480, 36544, 
+    36528, 36532,     0, 32768, 36864, 36865, 36352, 36480, 
+    36544, 36528, 36536, 36534,     0, 32768, 36864, 36865, 
+    36352, 36480, 36544, 36528,     0, 32768, 36864, 36865, 
+    36352, 36480, 36544, 36545, 36536,     0, 32768, 36864, 
+    36865, 36352, 36480, 36544, 36545, 36536,     0, 32768, 
+    36864, 36865, 36352, 36480, 36544, 36545, 36536, 36538, 
+        0, 32768, 36864, 36865, 36352, 36480, 36544, 36545, 
+    36536,     0, 32768, 36864, 36865, 36352, 36480, 36544, 
+    36545, 36536, 36540,     0, 32768, 36864, 36865, 36352, 
+    36480, 36544, 36545, 36547, 36540,     0, 32768, 36864, 
+    36865, 36352, 36480, 36544, 36545, 36547, 36540, 36542, 
+        0, 32768, 36864, 36865, 36352, 36480,     0, 32768, 
+    36864, 36865, 36352, 36608, 36544,     0, 32768, 36864, 
+    36865, 36352, 36608, 36544,     0, 32768, 36864, 36865, 
+    36352, 36608, 36544, 36546,     0, 32768, 36864, 36865, 
+    36352, 36608, 36544,     0, 32768, 36864, 36865, 36352, 
+    36608, 36544, 36548,     0, 32768, 36864, 36865, 36352, 
+    36608, 36544, 36548,     0, 32768, 36864, 36865, 36352, 
+    36608, 36544, 36552, 36550,     0, 32768, 36864, 36865, 
+    36352, 36608, 36544,     0, 32768, 36864, 36865, 36352, 
+    36608, 36544, 36552,     0, 32768, 36864, 36865, 36352, 
+    36608, 36544, 36552,     0, 32768, 36864, 36865, 36352, 
+    36608, 36544, 36552, 36554,     0, 32768, 36864, 36865, 
+    36352, 36608, 36544, 36552,     0, 32768, 36864, 36865, 
+    36352, 36608, 36544, 36560, 36556,     0, 32768, 36864, 
+    36865, 36352, 36608, 36544, 36560, 36556,     0, 32768, 
+    36864, 36865, 36352, 36608, 36544, 36560, 36561, 36558, 
+        0, 32768, 36864, 36865, 36352, 36608, 36544,     0, 
+    32768, 36864, 36865, 36352, 36608, 36544, 36560,     0, 
+    32768, 36864, 36865, 36352, 36608, 36544, 36560,     0, 
+    32768, 36864, 36865, 36352, 36608, 36544, 36560, 36562, 
+        0, 32768, 36864, 36865, 36352, 36608, 36544, 36560, 
+        0, 32768, 36864, 36865, 36352, 36608, 36544, 36560, 
+    36564,     0, 32768, 36864, 36865, 36352, 36608, 36544, 
+    36560, 36564,     0, 32768, 36864, 36865, 36352, 36608, 
+    36544, 36560, 36568, 36566,     0, 32768, 36864, 36865, 
+    36352, 36608, 36544, 36560,     0, 32768, 36864, 36865, 
+    36352, 36608, 36544, 36576, 36568,     0, 32768, 36864, 
+    36865, 36352, 36608, 36544, 36576, 36568,     0, 32768, 
+    36864, 36865, 36352, 36608, 36544, 36576, 36568, 36570, 
+        0, 32768, 36864, 36865, 36352, 36608, 36544, 36576, 
+    36568,     0, 32768, 36864, 36865, 36352, 36608, 36544, 
+    36576, 36577, 36572,     0, 32768, 36864, 36865, 36352, 
+    36608, 36544, 36576, 36577, 36572,     0, 32768, 36864, 
+    36865, 36352, 36608, 36544, 36576, 36577, 36572, 36574, 
+        0, 32768, 36864, 36865, 36352, 36608, 36544,     0, 
+    32768, 36864, 36865, 36352, 36608, 36609, 36576,     0, 
+    32768, 36864, 36865, 36352, 36608, 36609, 36576,     0, 
+    32768, 36864, 36865, 36352, 36608, 36609, 36576, 36578, 
+        0, 32768, 36864, 36865, 36352, 36608, 36609, 36576, 
+        0, 32768, 36864, 36865, 36352, 36608, 36609, 36576, 
+    36580,     0, 32768, 36864, 36865, 36352, 36608, 36609, 
+    36576, 36580,     0, 32768, 36864, 36865, 36352, 36608, 
+    36609, 36576, 36584, 36582,     0, 32768, 36864, 36865, 
+    36352, 36608, 36609, 36576,     0, 32768, 36864, 36865, 
+    36352, 36608, 36609, 36576, 36584,     0, 32768, 36864, 
+    36865, 36352, 36608, 36609, 36576, 36584,     0, 32768, 
+    36864, 36865, 36352, 36608, 36609, 36576, 36584, 36586, 
+        0, 32768, 36864, 36865, 36352, 36608, 36609, 36576, 
+    36584,     0, 32768, 36864, 36865, 36352, 36608, 36609, 
+    36576, 36592, 36588,     0, 32768, 36864, 36865, 36352, 
+    36608, 36609, 36576, 36592, 36588,     0, 32768, 36864, 
+    36865, 36352, 36608, 36609, 36576, 36592, 36593, 36590, 
+        0, 32768, 36864, 36865, 36352, 36608, 36609, 36576, 
+        0, 32768, 36864, 36865, 36352, 36608, 36609, 36576, 
+    36592,     0, 32768, 36864, 36865, 36352, 36608, 36609, 
+    36611, 36592,     0, 32768, 36864, 36865, 36352, 36608, 
+    36609, 36611, 36592, 36594,     0, 32768, 36864, 36865, 
+    36352, 36608, 36609, 36611, 36592,     0, 32768, 36864, 
+    36865, 36352, 36608, 36609, 36611, 36592, 36596,     0, 
+    32768, 36864, 36865, 36352, 36608, 36609, 36611, 36592, 
+    36596,     0, 32768, 36864, 36865, 36352, 36608, 36609, 
+    36611, 36592, 36600, 36598,     0, 32768, 36864, 36865, 
+    36352, 36608, 36609, 36611, 36592,     0, 32768, 36864, 
+    36865, 36352, 36608, 36609, 36611, 36592, 36600,     0, 
+    32768, 36864, 36865, 36352, 36608, 36609, 36611, 36592, 
+    36600,     0, 32768, 36864, 36865, 36352, 36608, 36609, 
+    36611, 36592, 36600, 36602,     0, 32768, 36864, 36865, 
+    36352, 36608, 36609, 36611, 36615, 36600,     0, 32768, 
+    36864, 36865, 36352, 36608, 36609, 36611, 36615, 36600, 
+    36604,     0, 32768, 36864, 36865, 36352, 36608, 36609, 
+    36611, 36615, 36600, 36604,     0, 32768, 36864, 36865, 
+    36352, 36608, 36609, 36611, 36615, 36600, 36604, 36606, 
+        0, 32768, 36864, 36865, 36352,     0, 32768, 36864, 
+    36865, 36352, 36608,     0, 32768, 36864, 36865, 36352, 
+    36608,     0, 32768, 36864, 36865, 36352, 36608, 36610, 
+        0, 32768, 36864, 36865, 36867, 36608,     0, 32768, 
+    36864, 36865, 36867, 36608, 36612,     0, 32768, 36864, 
+    36865, 36867, 36608, 36612,     0, 32768, 36864, 36865, 
+    36867, 36608, 36616, 36614,     0, 32768, 36864, 36865, 
+    36867, 36608,     0, 32768, 36864, 36865, 36867, 36608, 
+    36616,     0, 32768, 36864, 36865, 36867, 36608, 36616, 
+        0, 32768, 36864, 36865, 36867, 36608, 36616, 36618, 
+        0, 32768, 36864, 36865, 36867, 36608, 36616,     0, 
+    32768, 36864, 36865, 36867, 36608, 36624, 36620,     0, 
+    32768, 36864, 36865, 36867, 36608, 36624, 36620,     0, 
+    32768, 36864, 36865, 36867, 36608, 36624, 36625, 36622, 
+        0, 32768, 36864, 36865, 36867, 36608,     0, 32768, 
+    36864, 36865, 36867, 36608, 36624,     0, 32768, 36864, 
+    36865, 36867, 36608, 36624,     0, 32768, 36864, 36865, 
+    36867, 36608, 36624, 36626,     0, 32768, 36864, 36865, 
+    36867, 36608, 36624,     0, 32768, 36864, 36865, 36867, 
+    36608, 36624, 36628,     0, 32768, 36864, 36865, 36867, 
+    36608, 36624, 36628,     0, 32768, 36864, 36865, 36867, 
+    36608, 36624, 36632, 36630,     0, 32768, 36864, 36865, 
+    36867, 36608, 36624,     0, 32768, 36864, 36865, 36867, 
+    36608, 36640, 36632,     0, 32768, 36864, 36865, 36867, 
+    36608, 36640, 36632,     0, 32768, 36864, 36865, 36867, 
+    36608, 36640, 36632, 36634,     0, 32768, 36864, 36865, 
+    36867, 36608, 36640, 36632,     0, 32768, 36864, 36865, 
+    36867, 36608, 36640, 36641, 36636,     0, 32768, 36864, 
+    36865, 36867, 36608, 36640, 36641, 36636,     0, 32768, 
+    36864, 36865, 36867, 36608, 36640, 36641, 36636, 36638, 
+        0, 32768, 36864, 36865, 36867, 36608,     0, 32768, 
+    36864, 36865, 36867, 36608, 36640,     0, 32768, 36864, 
+    36865, 36867, 36608, 36640,     0, 32768, 36864, 36865, 
+    36867, 36608, 36640, 36642,     0, 32768, 36864, 36865, 
+    36867, 36608, 36640,     0, 32768, 36864, 36865, 36867, 
+    36608, 36640, 36644,     0, 32768, 36864, 36865, 36867, 
+    36608, 36640, 36644,     0, 32768, 36864, 36865, 36867, 
+    36608, 36640, 36648, 36646,     0, 32768, 36864, 36865, 
+    36867, 36608, 36640,     0, 32768, 36864, 36865, 36867, 
+    36608, 36640, 36648,     0, 32768, 36864, 36865, 36867, 
+    36608, 36640, 36648,     0, 32768, 36864, 36865, 36867, 
+    36608, 36640, 36648, 36650,     0, 32768, 36864, 36865, 
+    36867, 36608, 36640, 36648,     0, 32768, 36864, 36865, 
+    36867, 36608, 36640, 36656, 36652,     0, 32768, 36864, 
+    36865, 36867, 36608, 36640, 36656, 36652,     0, 32768, 
+    36864, 36865, 36867, 36608, 36640, 36656, 36657, 36654, 
+        0, 32768, 36864, 36865, 36867, 36608, 36640,     0, 
+    32768, 36864, 36865, 36867, 36608, 36672, 36656,     0, 
+    32768, 36864, 36865, 36867, 36608, 36672, 36656,     0, 
+    32768, 36864, 36865, 36867, 36608, 36672, 36656, 36658, 
+        0, 32768, 36864, 36865, 36867, 36608, 36672, 36656, 
+        0, 32768, 36864, 36865, 36867, 36608, 36672, 36656, 
+    36660,     0, 32768, 36864, 36865, 36867, 36608, 36672, 
+    36656, 36660,     0, 32768, 36864, 36865, 36867, 36608, 
+    36672, 36656, 36664, 36662,     0, 32768, 36864, 36865, 
+    36867, 36608, 36672, 36656,     0, 32768, 36864, 36865, 
+    36867, 36608, 36672, 36673, 36664,     0, 32768, 36864, 
+    36865, 36867, 36608, 36672, 36673, 36664,     0, 32768, 
+    36864, 36865, 36867, 36608, 36672, 36673, 36664, 36666, 
+        0, 32768, 36864, 36865, 36867, 36608, 36672, 36673, 
+    36664,     0, 32768, 36864, 36865, 36867, 36608, 36672, 
+    36673, 36664, 36668,     0, 32768, 36864, 36865, 36867, 
+    36608, 36672, 36673, 36675, 36668,     0, 32768, 36864, 
+    36865, 36867, 36608, 36672, 36673, 36675, 36668, 36670, 
+        0, 32768, 36864, 36865, 36867, 36608,     0, 32768, 
+    36864, 36865, 36867, 36608, 36672,     0, 32768, 36864, 
+    36865, 36867, 36608, 36672,     0, 32768, 36864, 36865, 
+    36867, 36608, 36672, 36674,     0, 32768, 36864, 36865, 
+    36867, 36608, 36672,     0, 32768, 36864, 36865, 36867, 
+    36608, 36672, 36676,     0, 32768, 36864, 36865, 36867, 
+    36608, 36672, 36676,     0, 32768, 36864, 36865, 36867, 
+    36608, 36672, 36680, 36678,     0, 32768, 36864, 36865, 
+    36867, 36608, 36672,     0, 32768, 36864, 36865, 36867, 
+    36608, 36672, 36680,     0, 32768, 36864, 36865, 36867, 
+    36608, 36672, 36680,     0, 32768, 36864, 36865, 36867, 
+    36608, 36672, 36680, 36682,     0, 32768, 36864, 36865, 
+    36867, 36608, 36672, 36680,     0, 32768, 36864, 36865, 
+    36867, 36608, 36672, 36688, 36684,     0, 32768, 36864, 
+    36865, 36867, 36608, 36672, 36688, 36684,     0, 32768, 
+    36864, 36865, 36867, 36608, 36672, 36688, 36689, 36686, 
+        0, 32768, 36864, 36865, 36867, 36608, 36672,     0, 
+    32768, 36864, 36865, 36867, 36608, 36672, 36688,     0, 
+    32768, 36864, 36865, 36867, 36608, 36672, 36688,     0, 
+    32768, 36864, 36865, 36867, 36608, 36672, 36688, 36690, 
+        0, 32768, 36864, 36865, 36867, 36608, 36672, 36688, 
+        0, 32768, 36864, 36865, 36867, 36608, 36672, 36688, 
+    36692,     0, 32768, 36864, 36865, 36867, 36608, 36672, 
+    36688, 36692,     0, 32768, 36864, 36865, 36867, 36608, 
+    36672, 36688, 36696, 36694,     0, 32768, 36864, 36865, 
+    36867, 36608, 36672, 36688,     0, 32768, 36864, 36865, 
+    36867, 36608, 36672, 36704, 36696,     0, 32768, 36864, 
+    36865, 36867, 36608, 36672, 36704, 36696,     0, 32768, 
+    36864, 36865, 36867, 36608, 36672, 36704, 36696, 36698, 
+        0, 32768, 36864, 36865, 36867, 36608, 36672, 36704, 
+    36696,     0, 32768, 36864, 36865, 36867, 36608, 36672, 
+    36704, 36705, 36700,     0, 32768, 36864, 36865, 36867, 
+    36608, 36672, 36704, 36705, 36700,     0, 32768, 36864, 
+    36865, 36867, 36608, 36672, 36704, 36705, 36700, 36702, 
+        0, 32768, 36864, 36865, 36867, 36608, 36672,     0, 
+    32768, 36864, 36865, 36867, 36608, 36736, 36704,     0, 
+    32768, 36864, 36865, 36867, 36608, 36736, 36704,     0, 
+    32768, 36864, 36865, 36867, 36608, 36736, 36704, 36706, 
+        0, 32768, 36864, 36865, 36867, 36608, 36736, 36704, 
+        0, 32768, 36864, 36865, 36867, 36608, 36736, 36704, 
+    36708,     0, 32768, 36864, 36865, 36867, 36608, 36736, 
+    36704, 36708,     0, 32768, 36864, 36865, 36867, 36608, 
+    36736, 36704, 36712, 36710,     0, 32768, 36864, 36865, 
+    36867, 36608, 36736, 36704,     0, 32768, 36864, 36865, 
+    36867, 36608, 36736, 36704, 36712,     0, 32768, 36864, 
+    36865, 36867, 36608, 36736, 36704, 36712,     0, 32768, 
+    36864, 36865, 36867, 36608, 36736, 36704, 36712, 36714, 
+        0, 32768, 36864, 36865, 36867, 36608, 36736, 36704, 
+    36712,     0, 32768, 36864, 36865, 36867, 36608, 36736, 
+    36704, 36720, 36716,     0, 32768, 36864, 36865, 36867, 
+    36608, 36736, 36704, 36720, 36716,     0, 32768, 36864, 
+    36865, 36867, 36608, 36736, 36704, 36720, 36721, 36718, 
+        0, 32768, 36864, 36865, 36867, 36608, 36736, 36704, 
+        0, 32768, 36864, 36865, 36867, 36608, 36736, 36737, 
+    36720,     0, 32768, 36864, 36865, 36867, 36608, 36736, 
+    36737, 36720,     0, 32768, 36864, 36865, 36867, 36608, 
+    36736, 36737, 36720, 36722,     0, 32768, 36864, 36865, 
+    36867, 36608, 36736, 36737, 36720,     0, 32768, 36864, 
+    36865, 36867, 36608, 36736, 36737, 36720, 36724,     0, 
+    32768, 36864, 36865, 36867, 36608, 36736, 36737, 36720, 
+    36724,     0, 32768, 36864, 36865, 36867, 36608, 36736, 
+    36737, 36720, 36728, 36726,     0, 32768, 36864, 36865, 
+    36867, 36608, 36736, 36737, 36720,     0, 32768, 36864, 
+    36865, 36867, 36608, 36736, 36737, 36720, 36728,     0, 
+    32768, 36864, 36865, 36867, 36608, 36736, 36737, 36739, 
+    36728,     0, 32768, 36864, 36865, 36867, 36608, 36736, 
+    36737, 36739, 36728, 36730,     0, 32768, 36864, 36865, 
+    36867, 36608, 36736, 36737, 36739, 36728,     0, 32768, 
+    36864, 36865, 36867, 36608, 36736, 36737, 36739, 36728, 
+    36732,     0, 32768, 36864, 36865, 36867, 36608, 36736, 
+    36737, 36739, 36728, 36732,     0, 32768, 36864, 36865, 
+    36867, 36608, 36736, 36737, 36739, 36728, 36732, 36734, 
+        0, 32768, 36864, 36865, 36867, 36608,     0, 32768, 
+    36864, 36865, 36867, 36608, 36736,     0, 32768, 36864, 
+    36865, 36867, 36608, 36736,     0, 32768, 36864, 36865, 
+    36867, 36608, 36736, 36738,     0, 32768, 36864, 36865, 
+    36867, 36608, 36736,     0, 32768, 36864, 36865, 36867, 
+    36608, 36736, 36740,     0, 32768, 36864, 36865, 36867, 
+    36608, 36736, 36740,     0, 32768, 36864, 36865, 36867, 
+    36608, 36736, 36744, 36742,     0, 32768, 36864, 36865, 
+    36867, 36871, 36736,     0, 32768, 36864, 36865, 36867, 
+    36871, 36736, 36744,     0, 32768, 36864, 36865, 36867, 
+    36871, 36736, 36744,     0, 32768, 36864, 36865, 36867, 
+    36871, 36736, 36744, 36746,     0, 32768, 36864, 36865, 
+    36867, 36871, 36736, 36744,     0, 32768, 36864, 36865, 
+    36867, 36871, 36736, 36752, 36748,     0, 32768, 36864, 
+    36865, 36867, 36871, 36736, 36752, 36748,     0, 32768, 
+    36864, 36865, 36867, 36871, 36736, 36752, 36753, 36750, 
+        0, 32768, 36864, 36865, 36867, 36871, 36736,     0, 
+    32768, 36864, 36865, 36867, 36871, 36736, 36752,     0, 
+    32768, 36864, 36865, 36867, 36871, 36736, 36752,     0, 
+    32768, 36864, 36865, 36867, 36871, 36736, 36752, 36754, 
+        0, 32768, 36864, 36865, 36867, 36871, 36736, 36752, 
+        0, 32768, 36864, 36865, 36867, 36871, 36736, 36752, 
+    36756,     0, 32768, 36864, 36865, 36867, 36871, 36736, 
+    36752, 36756,     0, 32768, 36864, 36865, 36867, 36871, 
+    36736, 36752, 36760, 36758,     0, 32768, 36864, 36865, 
+    36867, 36871, 36736, 36752,     0, 32768, 36864, 36865, 
+    36867, 36871, 36736, 36768, 36760,     0, 32768, 36864, 
+    36865, 36867, 36871, 36736, 36768, 36760,     0, 32768, 
+    36864, 36865, 36867, 36871, 36736, 36768, 36760, 36762, 
+        0, 32768, 36864, 36865, 36867, 36871, 36736, 36768, 
+    36760,     0, 32768, 36864, 36865, 36867, 36871, 36736, 
+    36768, 36769, 36764,     0, 32768, 36864, 36865, 36867, 
+    36871, 36736, 36768, 36769, 36764,     0, 32768, 36864, 
+    36865, 36867, 36871, 36736, 36768, 36769, 36764, 36766, 
+        0, 32768, 36864, 36865, 36867, 36871, 36736,     0, 
+    32768, 36864, 36865, 36867, 36871, 36736, 36768,     0, 
+    32768, 36864, 36865, 36867, 36871, 36736, 36768,     0, 
+    32768, 36864, 36865, 36867, 36871, 36736, 36768, 36770, 
+        0, 32768, 36864, 36865, 36867, 36871, 36736, 36768, 
+        0, 32768, 36864, 36865, 36867, 36871, 36736, 36768, 
+    36772,     0, 32768, 36864, 36865, 36867, 36871, 36736, 
+    36768, 36772,     0, 32768, 36864, 36865, 36867, 36871, 
+    36736, 36768, 36776, 36774,     0, 32768, 36864, 36865, 
+    36867, 36871, 36736, 36768,     0, 32768, 36864, 36865, 
+    36867, 36871, 36736, 36768, 36776,     0, 32768, 36864, 
+    36865, 36867, 36871, 36736, 36768, 36776,     0, 32768, 
+    36864, 36865, 36867, 36871, 36736, 36768, 36776, 36778, 
+        0, 32768, 36864, 36865, 36867, 36871, 36736, 36768, 
+    36776,     0, 32768, 36864, 36865, 36867, 36871, 36736, 
+    36768, 36784, 36780,     0, 32768, 36864, 36865, 36867, 
+    36871, 36736, 36768, 36784, 36780,     0, 32768, 36864, 
+    36865, 36867, 36871, 36736, 36768, 36784, 36785, 36782, 
+        0, 32768, 36864, 36865, 36867, 36871, 36736, 36768, 
+        0, 32768, 36864, 36865, 36867, 36871, 36736, 36800, 
+    36784,     0, 32768, 36864, 36865, 36867, 36871, 36736, 
+    36800, 36784,     0, 32768, 36864, 36865, 36867, 36871, 
+    36736, 36800, 36784, 36786,     0, 32768, 36864, 36865, 
+    36867, 36871, 36736, 36800, 36784,     0, 32768, 36864, 
+    36865, 36867, 36871, 36736, 36800, 36784, 36788,     0, 
+    32768, 36864, 36865, 36867, 36871, 36736, 36800, 36784, 
+    36788,     0, 32768, 36864, 36865, 36867, 36871, 36736, 
+    36800, 36784, 36792, 36790,     0, 32768, 36864, 36865, 
+    36867, 36871, 36736, 36800, 36784,     0, 32768, 36864, 
+    36865, 36867, 36871, 36736, 36800, 36801, 36792,     0, 
+    32768, 36864, 36865, 36867, 36871, 36736, 36800, 36801, 
+    36792,     0, 32768, 36864, 36865, 36867, 36871, 36736, 
+    36800, 36801, 36792, 36794,     0, 32768, 36864, 36865, 
+    36867, 36871, 36736, 36800, 36801, 36792,     0, 32768, 
+    36864, 36865, 36867, 36871, 36736, 36800, 36801, 36792, 
+    36796,     0, 32768, 36864, 36865, 36867, 36871, 36736, 
+    36800, 36801, 36803, 36796,     0, 32768, 36864, 36865, 
+    36867, 36871, 36736, 36800, 36801, 36803, 36796, 36798, 
+        0, 32768, 36864, 36865, 36867, 36871, 36736,     0, 
+    32768, 36864, 36865, 36867, 36871, 36736, 36800,     0, 
+    32768, 36864, 36865, 36867, 36871, 36736, 36800,     0, 
+    32768, 36864, 36865, 36867, 36871, 36736, 36800, 36802, 
+        0, 32768, 36864, 36865, 36867, 36871, 36736, 36800, 
+        0, 32768, 36864, 36865, 36867, 36871, 36736, 36800, 
+    36804,     0, 32768, 36864, 36865, 36867, 36871, 36736, 
+    36800, 36804,     0, 32768, 36864, 36865, 36867, 36871, 
+    36736, 36800, 36808, 36806,     0, 32768, 36864, 36865, 
+    36867, 36871, 36736, 36800,     0, 32768, 36864, 36865, 
+    36867, 36871, 36736, 36800, 36808,     0, 32768, 36864, 
+    36865, 36867, 36871, 36736, 36800, 36808,     0, 32768, 
+    36864, 36865, 36867, 36871, 36736, 36800, 36808, 36810, 
+        0, 32768, 36864, 36865, 36867, 36871, 36736, 36800, 
+    36808,     0, 32768, 36864, 36865, 36867, 36871, 36736, 
+    36800, 36816, 36812,     0, 32768, 36864, 36865, 36867, 
+    36871, 36736, 36800, 36816, 36812,     0, 32768, 36864, 
+    36865, 36867, 36871, 36736, 36800, 36816, 36817, 36814, 
+        0, 32768, 36864, 36865, 36867, 36871, 36879, 36800, 
+        0, 32768, 36864, 36865, 36867, 36871, 36879, 36800, 
+    36816,     0, 32768, 36864, 36865, 36867, 36871, 36879, 
+    36800, 36816,     0, 32768, 36864, 36865, 36867, 36871, 
+    36879, 36800, 36816, 36818,     0, 32768, 36864, 36865, 
+    36867, 36871, 36879, 36800, 36816,     0, 32768, 36864, 
+    36865, 36867, 36871, 36879, 36800, 36816, 36820,     0, 
+    32768, 36864, 36865, 36867, 36871, 36879, 36800, 36816, 
+    36820,     0, 32768, 36864, 36865, 36867, 36871, 36879, 
+    36800, 36816, 36824, 36822,     0, 32768, 36864, 36865, 
+    36867, 36871, 36879, 36800, 36816,     0, 32768, 36864, 
+    36865, 36867, 36871, 36879, 36800, 36832, 36824,     0, 
+    32768, 36864, 36865, 36867, 36871, 36879, 36800, 36832, 
+    36824,     0, 32768, 36864, 36865, 36867, 36871, 36879, 
+    36800, 36832, 36824, 36826,     0, 32768, 36864, 36865, 
+    36867, 36871, 36879, 36800, 36832, 36824,     0, 32768, 
+    36864, 36865, 36867, 36871, 36879, 36800, 36832, 36833, 
+    36828,     0, 32768, 36864, 36865, 36867, 36871, 36879, 
+    36800, 36832, 36833, 36828,     0, 32768, 36864, 36865, 
+    36867, 36871, 36879, 36800, 36832, 36833, 36828, 36830, 
+        0, 32768, 36864, 36865, 36867, 36871, 36879, 36800, 
+        0, 32768, 36864, 36865, 36867, 36871, 36879, 36800, 
+    36832,     0, 32768, 36864, 36865, 36867, 36871, 36879, 
+    36800, 36832,     0, 32768, 36864, 36865, 36867, 36871, 
+    36879, 36800, 36832, 36834,     0, 32768, 36864, 36865, 
+    36867, 36871, 36879, 36800, 36832,     0, 32768, 36864, 
+    36865, 36867, 36871, 36879, 36800, 36832, 36836,     0, 
+    32768, 36864, 36865, 36867, 36871, 36879, 36800, 36832, 
+    36836,     0, 32768, 36864, 36865, 36867, 36871, 36879, 
+    36800, 36832, 36840, 36838,     0, 32768, 36864, 36865, 
+    36867, 36871, 36879, 36800, 36832,     0, 32768, 36864, 
+    36865, 36867, 36871, 36879, 36800, 36832, 36840,     0, 
+    32768, 36864, 36865, 36867, 36871, 36879, 36800, 36832, 
+    36840,     0, 32768, 36864, 36865, 36867, 36871, 36879, 
+    36800, 36832, 36840, 36842,     0, 32768, 36864, 36865, 
+    36867, 36871, 36879, 36800, 36832, 36840,     0, 32768, 
+    36864, 36865, 36867, 36871, 36879, 36800, 36832, 36848, 
+    36844,     0, 32768, 36864, 36865, 36867, 36871, 36879, 
+    36800, 36832, 36848, 36844,     0, 32768, 36864, 36865, 
+    36867, 36871, 36879, 36800, 36832, 36848, 36849, 36846, 
+        0, 32768, 36864, 36865, 36867, 36871, 36879, 36800, 
+    36832,     0, 32768, 36864, 36865, 36867, 36871, 36879, 
+    36800, 36832, 36848,     0, 32768, 36864, 36865, 36867, 
+    36871, 36879, 36800, 36832, 36848,     0, 32768, 36864, 
+    36865, 36867, 36871, 36879, 36800, 36832, 36848, 36850, 
+        0, 32768, 36864, 36865, 36867, 36871, 36879, 36800, 
+    36832, 36848,     0, 32768, 36864, 36865, 36867, 36871, 
+    36879, 36800, 36832, 36848, 36852,     0, 32768, 36864, 
+    36865, 36867, 36871, 36879, 36800, 36832, 36848, 36852, 
+        0, 32768, 36864, 36865, 36867, 36871, 36879, 36800, 
+    36832, 36848, 36856, 36854,     0, 32768, 36864, 36865, 
+    36867, 36871, 36879, 36800, 36832, 36848,     0, 32768, 
+    36864, 36865, 36867, 36871, 36879, 36800, 36832, 36848, 
+    36856,     0, 32768, 36864, 36865, 36867, 36871, 36879, 
+    36800, 36832, 36848, 36856,     0, 32768, 36864, 36865, 
+    36867, 36871, 36879, 36800, 36832, 36848, 36856, 36858, 
+        0, 32768, 36864, 36865, 36867, 36871, 36879, 36800, 
+    36832, 36848, 36856,     0, 32768, 36864, 36865, 36867, 
+    36871, 36879, 36800, 36832, 36848, 36856, 36860,     0, 
+    32768, 36864, 36865, 36867, 36871, 36879, 36800, 36832, 
+    36848, 36856, 36860,     0, 32768, 36864, 36865, 36867, 
+    36871, 36879, 36800, 36832, 36848, 36856, 36860, 36862, 
+        0, 32768,     0, 32768, 36864,     0, 32768, 36864, 
+        0, 32768, 36864, 36866,     0, 32768, 36864,     0, 
+    32768, 36864, 36868,     0, 32768, 36864, 36868,     0, 
+    32768, 36864, 36872, 36870,     0, 32768, 36864,     0, 
+    32768, 36864, 36872,     0, 32768, 36864, 36872,     0, 
+    32768, 36864, 36872, 36874,     0, 32768, 36864, 36872, 
+        0, 32768, 36864, 36880, 36876,     0, 32768, 36864, 
+    36880, 36876,     0, 32768, 36864, 36880, 36881, 36878, 
+        0, 32768, 36864,     0, 32768, 36864, 36880,     0, 
+    32768, 36864, 36880,     0, 32768, 36864, 36880, 36882, 
+        0, 32768, 36864, 36880,     0, 32768, 36864, 36880, 
+    36884,     0, 32768, 36864, 36880, 36884,     0, 32768, 
+    36864, 36880, 36888, 36886,     0, 32768, 36864, 36880, 
+        0, 32768, 36864, 36896, 36888,     0, 32768, 36864, 
+    36896, 36888,     0, 32768, 36864, 36896, 36888, 36890, 
+        0, 32768, 36864, 36896, 36888,     0, 32768, 36864, 
+    36896, 36897, 36892,     0, 32768, 36864, 36896, 36897, 
+    36892,     0, 32768, 36864, 36896, 36897, 36892, 36894, 
+        0, 32768, 36864,     0, 32768, 36864, 36896,     0, 
+    32768, 36864, 36896,     0, 32768, 36864, 36896, 36898, 
+        0, 32768, 36864, 36896,     0, 32768, 36864, 36896, 
+    36900,     0, 32768, 36864, 36896, 36900,     0, 32768, 
+    36864, 36896, 36904, 36902,     0, 32768, 36864, 36896, 
+        0, 32768, 36864, 36896, 36904,     0, 32768, 36864, 
+    36896, 36904,     0, 32768, 36864, 36896, 36904, 36906, 
+        0, 32768, 36864, 36896, 36904,     0, 32768, 36864, 
+    36896, 36912, 36908,     0, 32768, 36864, 36896, 36912, 
+    36908,     0, 32768, 36864, 36896, 36912, 36913, 36910, 
+        0, 32768, 36864, 36896,     0, 32768, 36864, 36928, 
+    36912,     0, 32768, 36864, 36928, 36912,     0, 32768, 
+    36864, 36928, 36912, 36914,     0, 32768, 36864, 36928, 
+    36912,     0, 32768, 36864, 36928, 36912, 36916,     0, 
+    32768, 36864, 36928, 36912, 36916,     0, 32768, 36864, 
+    36928, 36912, 36920, 36918,     0, 32768, 36864, 36928, 
+    36912,     0, 32768, 36864, 36928, 36929, 36920,     0, 
+    32768, 36864, 36928, 36929, 36920,     0, 32768, 36864, 
+    36928, 36929, 36920, 36922,     0, 32768, 36864, 36928, 
+    36929, 36920,     0, 32768, 36864, 36928, 36929, 36920, 
+    36924,     0, 32768, 36864, 36928, 36929, 36931, 36924, 
+        0, 32768, 36864, 36928, 36929, 36931, 36924, 36926, 
+        0, 32768, 36864,     0, 32768, 36864, 36928,     0, 
+    32768, 36864, 36928,     0, 32768, 36864, 36928, 36930, 
+        0, 32768, 36864, 36928,     0, 32768, 36864, 36928, 
+    36932,     0, 32768, 36864, 36928, 36932,     0, 32768, 
+    36864, 36928, 36936, 36934,     0, 32768, 36864, 36928, 
+        0, 32768, 36864, 36928, 36936,     0, 32768, 36864, 
+    36928, 36936,     0, 32768, 36864, 36928, 36936, 36938, 
+        0, 32768, 36864, 36928, 36936,     0, 32768, 36864, 
+    36928, 36944, 36940,     0, 32768, 36864, 36928, 36944, 
+    36940,     0, 32768, 36864, 36928, 36944, 36945, 36942, 
+        0, 32768, 36864, 36928,     0, 32768, 36864, 36928, 
+    36944,     0, 32768, 36864, 36928, 36944,     0, 32768, 
+    36864, 36928, 36944, 36946,     0, 32768, 36864, 36928, 
+    36944,     0, 32768, 36864, 36928, 36944, 36948,     0, 
+    32768, 36864, 36928, 36944, 36948,     0, 32768, 36864, 
+    36928, 36944, 36952, 36950,     0, 32768, 36864, 36928, 
+    36944,     0, 32768, 36864, 36928, 36960, 36952,     0, 
+    32768, 36864, 36928, 36960, 36952,     0, 32768, 36864, 
+    36928, 36960, 36952, 36954,     0, 32768, 36864, 36928, 
+    36960, 36952,     0, 32768, 36864, 36928, 36960, 36961, 
+    36956,     0, 32768, 36864, 36928, 36960, 36961, 36956, 
+        0, 32768, 36864, 36928, 36960, 36961, 36956, 36958, 
+        0, 32768, 36864, 36928,     0, 32768, 36864, 36992, 
+    36960,     0, 32768, 36864, 36992, 36960,     0, 32768, 
+    36864, 36992, 36960, 36962,     0, 32768, 36864, 36992, 
+    36960,     0, 32768, 36864, 36992, 36960, 36964,     0, 
+    32768, 36864, 36992, 36960, 36964,     0, 32768, 36864, 
+    36992, 36960, 36968, 36966,     0, 32768, 36864, 36992, 
+    36960,     0, 32768, 36864, 36992, 36960, 36968,     0, 
+    32768, 36864, 36992, 36960, 36968,     0, 32768, 36864, 
+    36992, 36960, 36968, 36970,     0, 32768, 36864, 36992, 
+    36960, 36968,     0, 32768, 36864, 36992, 36960, 36976, 
+    36972,     0, 32768, 36864, 36992, 36960, 36976, 36972, 
+        0, 32768, 36864, 36992, 36960, 36976, 36977, 36974, 
+        0, 32768, 36864, 36992, 36960,     0, 32768, 36864, 
+    36992, 36993, 36976,     0, 32768, 36864, 36992, 36993, 
+    36976,     0, 32768, 36864, 36992, 36993, 36976, 36978, 
+        0, 32768, 36864, 36992, 36993, 36976,     0, 32768, 
+    36864, 36992, 36993, 36976, 36980,     0, 32768, 36864, 
+    36992, 36993, 36976, 36980,     0, 32768, 36864, 36992, 
+    36993, 36976, 36984, 36982,     0, 32768, 36864, 36992, 
+    36993, 36976,     0, 32768, 36864, 36992, 36993, 36976, 
+    36984,     0, 32768, 36864, 36992, 36993, 36995, 36984, 
+        0, 32768, 36864, 36992, 36993, 36995, 36984, 36986, 
+        0, 32768, 36864, 36992, 36993, 36995, 36984,     0, 
+    32768, 36864, 36992, 36993, 36995, 36984, 36988,     0, 
+    32768, 36864, 36992, 36993, 36995, 36984, 36988,     0, 
+    32768, 36864, 36992, 36993, 36995, 36984, 36988, 36990, 
+        0, 32768, 36864,     0, 32768, 36864, 36992,     0, 
+    32768, 36864, 36992,     0, 32768, 36864, 36992, 36994, 
+        0, 32768, 36864, 36992,     0, 32768, 36864, 36992, 
+    36996,     0, 32768, 36864, 36992, 36996,     0, 32768, 
+    36864, 36992, 37000, 36998,     0, 32768, 36864, 36992, 
+        0, 32768, 36864, 36992, 37000,     0, 32768, 36864, 
+    36992, 37000,     0, 32768, 36864, 36992, 37000, 37002, 
+        0, 32768, 36864, 36992, 37000,     0, 32768, 36864, 
+    36992, 37008, 37004,     0, 32768, 36864, 36992, 37008, 
+    37004,     0, 32768, 36864, 36992, 37008, 37009, 37006, 
+        0, 32768, 36864, 36992,     0, 32768, 36864, 36992, 
+    37008,     0, 32768, 36864, 36992, 37008,     0, 32768, 
+    36864, 36992, 37008, 37010,     0, 32768, 36864, 36992, 
+    37008,     0, 32768, 36864, 36992, 37008, 37012,     0, 
+    32768, 36864, 36992, 37008, 37012,     0, 32768, 36864, 
+    36992, 37008, 37016, 37014,     0, 32768, 36864, 36992, 
+    37008,     0, 32768, 36864, 36992, 37024, 37016,     0, 
+    32768, 36864, 36992, 37024, 37016,     0, 32768, 36864, 
+    36992, 37024, 37016, 37018,     0, 32768, 36864, 36992, 
+    37024, 37016,     0, 32768, 36864, 36992, 37024, 37025, 
+    37020,     0, 32768, 36864, 36992, 37024, 37025, 37020, 
+        0, 32768, 36864, 36992, 37024, 37025, 37020, 37022, 
+        0, 32768, 36864, 36992,     0, 32768, 36864, 36992, 
+    37024,     0, 32768, 36864, 36992, 37024,     0, 32768, 
+    36864, 36992, 37024, 37026,     0, 32768, 36864, 36992, 
+    37024,     0, 32768, 36864, 36992, 37024, 37028,     0, 
+    32768, 36864, 36992, 37024, 37028,     0, 32768, 36864, 
+    36992, 37024, 37032, 37030,     0, 32768, 36864, 36992, 
+    37024,     0, 32768, 36864, 36992, 37024, 37032,     0, 
+    32768, 36864, 36992, 37024, 37032,     0, 32768, 36864, 
+    36992, 37024, 37032, 37034,     0, 32768, 36864, 36992, 
+    37024, 37032,     0, 32768, 36864, 36992, 37024, 37040, 
+    37036,     0, 32768, 36864, 36992, 37024, 37040, 37036, 
+        0, 32768, 36864, 36992, 37024, 37040, 37041, 37038, 
+        0, 32768, 36864, 36992, 37024,     0, 32768, 36864, 
+    36992, 37056, 37040,     0, 32768, 36864, 36992, 37056, 
+    37040,     0, 32768, 36864, 36992, 37056, 37040, 37042, 
+        0, 32768, 36864, 36992, 37056, 37040,     0, 32768, 
+    36864, 36992, 37056, 37040, 37044,     0, 32768, 36864, 
+    36992, 37056, 37040, 37044,     0, 32768, 36864, 36992, 
+    37056, 37040, 37048, 37046,     0, 32768, 36864, 36992, 
+    37056, 37040,     0, 32768, 36864, 36992, 37056, 37057, 
+    37048,     0, 32768, 36864, 36992, 37056, 37057, 37048, 
+        0, 32768, 36864, 36992, 37056, 37057, 37048, 37050, 
+        0, 32768, 36864, 36992, 37056, 37057, 37048,     0, 
+    32768, 36864, 36992, 37056, 37057, 37048, 37052,     0, 
+    32768, 36864, 36992, 37056, 37057, 37059, 37052,     0, 
+    32768, 36864, 36992, 37056, 37057, 37059, 37052, 37054, 
+        0, 32768, 36864, 36992,     0, 32768, 36864, 37120, 
+    37056,     0, 32768, 36864, 37120, 37056,     0, 32768, 
+    36864, 37120, 37056, 37058,     0, 32768, 36864, 37120, 
+    37056,     0, 32768, 36864, 37120, 37056, 37060,     0, 
+    32768, 36864, 37120, 37056, 37060,     0, 32768, 36864, 
+    37120, 37056, 37064, 37062,     0, 32768, 36864, 37120, 
+    37056,     0, 32768, 36864, 37120, 37056, 37064,     0, 
+    32768, 36864, 37120, 37056, 37064,     0, 32768, 36864, 
+    37120, 37056, 37064, 37066,     0, 32768, 36864, 37120, 
+    37056, 37064,     0, 32768, 36864, 37120, 37056, 37072, 
+    37068,     0, 32768, 36864, 37120, 37056, 37072, 37068, 
+        0, 32768, 36864, 37120, 37056, 37072, 37073, 37070, 
+        0, 32768, 36864, 37120, 37056,     0, 32768, 36864, 
+    37120, 37056, 37072,     0, 32768, 36864, 37120, 37056, 
+    37072,     0, 32768, 36864, 37120, 37056, 37072, 37074, 
+        0, 32768, 36864, 37120, 37056, 37072,     0, 32768, 
+    36864, 37120, 37056, 37072, 37076,     0, 32768, 36864, 
+    37120, 37056, 37072, 37076,     0, 32768, 36864, 37120, 
+    37056, 37072, 37080, 37078,     0, 32768, 36864, 37120, 
+    37056, 37072,     0, 32768, 36864, 37120, 37056, 37088, 
+    37080,     0, 32768, 36864, 37120, 37056, 37088, 37080, 
+        0, 32768, 36864, 37120, 37056, 37088, 37080, 37082, 
+        0, 32768, 36864, 37120, 37056, 37088, 37080,     0, 
+    32768, 36864, 37120, 37056, 37088, 37089, 37084,     0, 
+    32768, 36864, 37120, 37056, 37088, 37089, 37084,     0, 
+    32768, 36864, 37120, 37056, 37088, 37089, 37084, 37086, 
+        0, 32768, 36864, 37120, 37056,     0, 32768, 36864, 
+    37120, 37121, 37088,     0, 32768, 36864, 37120, 37121, 
+    37088,     0, 32768, 36864, 37120, 37121, 37088, 37090, 
+        0, 32768, 36864, 37120, 37121, 37088,     0, 32768, 
+    36864, 37120, 37121, 37088, 37092,     0, 32768, 36864, 
+    37120, 37121, 37088, 37092,     0, 32768, 36864, 37120, 
+    37121, 37088, 37096, 37094,     0, 32768, 36864, 37120, 
+    37121, 37088,     0, 32768, 36864, 37120, 37121, 37088, 
+    37096,     0, 32768, 36864, 37120, 37121, 37088, 37096, 
+        0, 32768, 36864, 37120, 37121, 37088, 37096, 37098, 
+        0, 32768, 36864, 37120, 37121, 37088, 37096,     0, 
+    32768, 36864, 37120, 37121, 37088, 37104, 37100,     0, 
+    32768, 36864, 37120, 37121, 37088, 37104, 37100,     0, 
+    32768, 36864, 37120, 37121, 37088, 37104, 37105, 37102, 
+        0, 32768, 36864, 37120, 37121, 37088,     0, 32768, 
+    36864, 37120, 37121, 37088, 37104,     0, 32768, 36864, 
+    37120, 37121, 37123, 37104,     0, 32768, 36864, 37120, 
+    37121, 37123, 37104, 37106,     0, 32768, 36864, 37120, 
+    37121, 37123, 37104,     0, 32768, 36864, 37120, 37121, 
+    37123, 37104, 37108,     0, 32768, 36864, 37120, 37121, 
+    37123, 37104, 37108,     0, 32768, 36864, 37120, 37121, 
+    37123, 37104, 37112, 37110,     0, 32768, 36864, 37120, 
+    37121, 37123, 37104,     0, 32768, 36864, 37120, 37121, 
+    37123, 37104, 37112,     0, 32768, 36864, 37120, 37121, 
+    37123, 37104, 37112,     0, 32768, 36864, 37120, 37121, 
+    37123, 37104, 37112, 37114,     0, 32768, 36864, 37120, 
+    37121, 37123, 37127, 37112,     0, 32768, 36864, 37120, 
+    37121, 37123, 37127, 37112, 37116,     0, 32768, 36864, 
+    37120, 37121, 37123, 37127, 37112, 37116,     0, 32768, 
+    36864, 37120, 37121, 37123, 37127, 37112, 37116, 37118, 
+        0, 32768, 36864,     0, 32768, 36864, 37120,     0, 
+    32768, 36864, 37120,     0, 32768, 36864, 37120, 37122, 
+        0, 32768, 36864, 37120,     0, 32768, 36864, 37120, 
+    37124,     0, 32768, 36864, 37120, 37124,     0, 32768, 
+    36864, 37120, 37128, 37126,     0, 32768, 36864, 37120, 
+        0, 32768, 36864, 37120, 37128,     0, 32768, 36864, 
+    37120, 37128,     0, 32768, 36864, 37120, 37128, 37130, 
+        0, 32768, 36864, 37120, 37128,     0, 32768, 36864, 
+    37120, 37136, 37132,     0, 32768, 36864, 37120, 37136, 
+    37132,     0, 32768, 36864, 37120, 37136, 37137, 37134, 
+        0, 32768, 36864, 37120,     0, 32768, 36864, 37120, 
+    37136,     0, 32768, 36864, 37120, 37136,     0, 32768, 
+    36864, 37120, 37136, 37138,     0, 32768, 36864, 37120, 
+    37136,     0, 32768, 36864, 37120, 37136, 37140,     0, 
+    32768, 36864, 37120, 37136, 37140,     0, 32768, 36864, 
+    37120, 37136, 37144, 37142,     0, 32768, 36864, 37120, 
+    37136,     0, 32768, 36864, 37120, 37152, 37144,     0, 
+    32768, 36864, 37120, 37152, 37144,     0, 32768, 36864, 
+    37120, 37152, 37144, 37146,     0, 32768, 36864, 37120, 
+    37152, 37144,     0, 32768, 36864, 37120, 37152, 37153, 
+    37148,     0, 32768, 36864, 37120, 37152, 37153, 37148, 
+        0, 32768, 36864, 37120, 37152, 37153, 37148, 37150, 
+        0, 32768, 36864, 37120,     0, 32768, 36864, 37120, 
+    37152,     0, 32768, 36864, 37120, 37152,     0, 32768, 
+    36864, 37120, 37152, 37154,     0, 32768, 36864, 37120, 
+    37152,     0, 32768, 36864, 37120, 37152, 37156,     0, 
+    32768, 36864, 37120, 37152, 37156,     0, 32768, 36864, 
+    37120, 37152, 37160, 37158,     0, 32768, 36864, 37120, 
+    37152,     0, 32768, 36864, 37120, 37152, 37160,     0, 
+    32768, 36864, 37120, 37152, 37160,     0, 32768, 36864, 
+    37120, 37152, 37160, 37162,     0, 32768, 36864, 37120, 
+    37152, 37160,     0, 32768, 36864, 37120, 37152, 37168, 
+    37164,     0, 32768, 36864, 37120, 37152, 37168, 37164, 
+        0, 32768, 36864, 37120, 37152, 37168, 37169, 37166, 
+        0, 32768, 36864, 37120, 37152,     0, 32768, 36864, 
+    37120, 37184, 37168,     0, 32768, 36864, 37120, 37184, 
+    37168,     0, 32768, 36864, 37120, 37184, 37168, 37170, 
+        0, 32768, 36864, 37120, 37184, 37168,     0, 32768, 
+    36864, 37120, 37184, 37168, 37172,     0, 32768, 36864, 
+    37120, 37184, 37168, 37172,     0, 32768, 36864, 37120, 
+    37184, 37168, 37176, 37174,     0, 32768, 36864, 37120, 
+    37184, 37168,     0, 32768, 36864, 37120, 37184, 37185, 
+    37176,     0, 32768, 36864, 37120, 37184, 37185, 37176, 
+        0, 32768, 36864, 37120, 37184, 37185, 37176, 37178, 
+        0, 32768, 36864, 37120, 37184, 37185, 37176,     0, 
+    32768, 36864, 37120, 37184, 37185, 37176, 37180,     0, 
+    32768, 36864, 37120, 37184, 37185, 37187, 37180,     0, 
+    32768, 36864, 37120, 37184, 37185, 37187, 37180, 37182, 
+        0, 32768, 36864, 37120,     0, 32768, 36864, 37120, 
+    37184,     0, 32768, 36864, 37120, 37184,     0, 32768, 
+    36864, 37120, 37184, 37186,     0, 32768, 36864, 37120, 
+    37184,     0, 32768, 36864, 37120, 37184, 37188,     0, 
+    32768, 36864, 37120, 37184, 37188,     0, 32768, 36864, 
+    37120, 37184, 37192, 37190,     0, 32768, 36864, 37120, 
+    37184,     0, 32768, 36864, 37120, 37184, 37192,     0, 
+    32768, 36864, 37120, 37184, 37192,     0, 32768, 36864, 
+    37120, 37184, 37192, 37194,     0, 32768, 36864, 37120, 
+    37184, 37192,     0, 32768, 36864, 37120, 37184, 37200, 
+    37196,     0, 32768, 36864, 37120, 37184, 37200, 37196, 
+        0, 32768, 36864, 37120, 37184, 37200, 37201, 37198, 
+        0, 32768, 36864, 37120, 37184,     0, 32768, 36864, 
+    37120, 37184, 37200,     0, 32768, 36864, 37120, 37184, 
+    37200,     0, 32768, 36864, 37120, 37184, 37200, 37202, 
+        0, 32768, 36864, 37120, 37184, 37200,     0, 32768, 
+    36864, 37120, 37184, 37200, 37204,     0, 32768, 36864, 
+    37120, 37184, 37200, 37204,     0, 32768, 36864, 37120, 
+    37184, 37200, 37208, 37206,     0, 32768, 36864, 37120, 
+    37184, 37200,     0, 32768, 36864, 37120, 37184, 37216, 
+    37208,     0, 32768, 36864, 37120, 37184, 37216, 37208, 
+        0, 32768, 36864, 37120, 37184, 37216, 37208, 37210, 
+        0, 32768, 36864, 37120, 37184, 37216, 37208,     0, 
+    32768, 36864, 37120, 37184, 37216, 37217, 37212,     0, 
+    32768, 36864, 37120, 37184, 37216, 37217, 37212,     0, 
+    32768, 36864, 37120, 37184, 37216, 37217, 37212, 37214, 
+        0, 32768, 36864, 37120, 37184,     0, 32768, 36864, 
+    37120, 37248, 37216,     0, 32768, 36864, 37120, 37248, 
+    37216,     0, 32768, 36864, 37120, 37248, 37216, 37218, 
+        0, 32768, 36864, 37120, 37248, 37216,     0, 32768, 
+    36864, 37120, 37248, 37216, 37220,     0, 32768, 36864, 
+    37120, 37248, 37216, 37220,     0, 32768, 36864, 37120, 
+    37248, 37216, 37224, 37222,     0, 32768, 36864, 37120, 
+    37248, 37216,     0, 32768, 36864, 37120, 37248, 37216, 
+    37224,     0, 32768, 36864, 37120, 37248, 37216, 37224, 
+        0, 32768, 36864, 37120, 37248, 37216, 37224, 37226, 
+        0, 32768, 36864, 37120, 37248, 37216, 37224,     0, 
+    32768, 36864, 37120, 37248, 37216, 37232, 37228,     0, 
+    32768, 36864, 37120, 37248, 37216, 37232, 37228,     0, 
+    32768, 36864, 37120, 37248, 37216, 37232, 37233, 37230, 
+        0, 32768, 36864, 37120, 37248, 37216,     0, 32768, 
+    36864, 37120, 37248, 37249, 37232,     0, 32768, 36864, 
+    37120, 37248, 37249, 37232,     0, 32768, 36864, 37120, 
+    37248, 37249, 37232, 37234,     0, 32768, 36864, 37120, 
+    37248, 37249, 37232,     0, 32768, 36864, 37120, 37248, 
+    37249, 37232, 37236,     0, 32768, 36864, 37120, 37248, 
+    37249, 37232, 37236,     0, 32768, 36864, 37120, 37248, 
+    37249, 37232, 37240, 37238,     0, 32768, 36864, 37120, 
+    37248, 37249, 37232,     0, 32768, 36864, 37120, 37248, 
+    37249, 37232, 37240,     0, 32768, 36864, 37120, 37248, 
+    37249, 37251, 37240,     0, 32768, 36864, 37120, 37248, 
+    37249, 37251, 37240, 37242,     0, 32768, 36864, 37120, 
+    37248, 37249, 37251, 37240,     0, 32768, 36864, 37120, 
+    37248, 37249, 37251, 37240, 37244,     0, 32768, 36864, 
+    37120, 37248, 37249, 37251, 37240, 37244,     0, 32768, 
+    36864, 37120, 37248, 37249, 37251, 37240, 37244, 37246, 
+        0, 32768, 36864, 37120,     0, 32768, 36864, 37376, 
+    37248,     0, 32768, 36864, 37376, 37248,     0, 32768, 
+    36864, 37376, 37248, 37250,     0, 32768, 36864, 37376, 
+    37248,     0, 32768, 36864, 37376, 37248, 37252,     0, 
+    32768, 36864, 37376, 37248, 37252,     0, 32768, 36864, 
+    37376, 37248, 37256, 37254,     0, 32768, 36864, 37376, 
+    37248,     0, 32768, 36864, 37376, 37248, 37256,     0, 
+    32768, 36864, 37376, 37248, 37256,     0, 32768, 36864, 
+    37376, 37248, 37256, 37258,     0, 32768, 36864, 37376, 
+    37248, 37256,     0, 32768, 36864, 37376, 37248, 37264, 
+    37260,     0, 32768, 36864, 37376, 37248, 37264, 37260, 
+        0, 32768, 36864, 37376, 37248, 37264, 37265, 37262, 
+        0, 32768, 36864, 37376, 37248,     0, 32768, 36864, 
+    37376, 37248, 37264,     0, 32768, 36864, 37376, 37248, 
+    37264,     0, 32768, 36864, 37376, 37248, 37264, 37266, 
+        0, 32768, 36864, 37376, 37248, 37264,     0, 32768, 
+    36864, 37376, 37248, 37264, 37268,     0, 32768, 36864, 
+    37376, 37248, 37264, 37268,     0, 32768, 36864, 37376, 
+    37248, 37264, 37272, 37270,     0, 32768, 36864, 37376, 
+    37248, 37264,     0, 32768, 36864, 37376, 37248, 37280, 
+    37272,     0, 32768, 36864, 37376, 37248, 37280, 37272, 
+        0, 32768, 36864, 37376, 37248, 37280, 37272, 37274, 
+        0, 32768, 36864, 37376, 37248, 37280, 37272,     0, 
+    32768, 36864, 37376, 37248, 37280, 37281, 37276,     0, 
+    32768, 36864, 37376, 37248, 37280, 37281, 37276,     0, 
+    32768, 36864, 37376, 37248, 37280, 37281, 37276, 37278, 
+        0, 32768, 36864, 37376, 37248,     0, 32768, 36864, 
+    37376, 37248, 37280,     0, 32768, 36864, 37376, 37248, 
+    37280,     0, 32768, 36864, 37376, 37248, 37280, 37282, 
+        0, 32768, 36864, 37376, 37248, 37280,     0, 32768, 
+    36864, 37376, 37248, 37280, 37284,     0, 32768, 36864, 
+    37376, 37248, 37280, 37284,     0, 32768, 36864, 37376, 
+    37248, 37280, 37288, 37286,     0, 32768, 36864, 37376, 
+    37248, 37280,     0, 32768, 36864, 37376, 37248, 37280, 
+    37288,     0, 32768, 36864, 37376, 37248, 37280, 37288, 
+        0, 32768, 36864, 37376, 37248, 37280, 37288, 37290, 
+        0, 32768, 36864, 37376, 37248, 37280, 37288,     0, 
+    32768, 36864, 37376, 37248, 37280, 37296, 37292,     0, 
+    32768, 36864, 37376, 37248, 37280, 37296, 37292,     0, 
+    32768, 36864, 37376, 37248, 37280, 37296, 37297, 37294, 
+        0, 32768, 36864, 37376, 37248, 37280,     0, 32768, 
+    36864, 37376, 37248, 37312, 37296,     0, 32768, 36864, 
+    37376, 37248, 37312, 37296,     0, 32768, 36864, 37376, 
+    37248, 37312, 37296, 37298,     0, 32768, 36864, 37376, 
+    37248, 37312, 37296,     0, 32768, 36864, 37376, 37248, 
+    37312, 37296, 37300,     0, 32768, 36864, 37376, 37248, 
+    37312, 37296, 37300,     0, 32768, 36864, 37376, 37248, 
+    37312, 37296, 37304, 37302,     0, 32768, 36864, 37376, 
+    37248, 37312, 37296,     0, 32768, 36864, 37376, 37248, 
+    37312, 37313, 37304,     0, 32768, 36864, 37376, 37248, 
+    37312, 37313, 37304,     0, 32768, 36864, 37376, 37248, 
+    37312, 37313, 37304, 37306,     0, 32768, 36864, 37376, 
+    37248, 37312, 37313, 37304,     0, 32768, 36864, 37376, 
+    37248, 37312, 37313, 37304, 37308,     0, 32768, 36864, 
+    37376, 37248, 37312, 37313, 37315, 37308,     0, 32768, 
+    36864, 37376, 37248, 37312, 37313, 37315, 37308, 37310, 
+        0, 32768, 36864, 37376, 37248,     0, 32768, 36864, 
+    37376, 37377, 37312,     0, 32768, 36864, 37376, 37377, 
+    37312,     0, 32768, 36864, 37376, 37377, 37312, 37314, 
+        0, 32768, 36864, 37376, 37377, 37312,     0, 32768, 
+    36864, 37376, 37377, 37312, 37316,     0, 32768, 36864, 
+    37376, 37377, 37312, 37316,     0, 32768, 36864, 37376, 
+    37377, 37312, 37320, 37318,     0, 32768, 36864, 37376, 
+    37377, 37312,     0, 32768, 36864, 37376, 37377, 37312, 
+    37320,     0, 32768, 36864, 37376, 37377, 37312, 37320, 
+        0, 32768, 36864, 37376, 37377, 37312, 37320, 37322, 
+        0, 32768, 36864, 37376, 37377, 37312, 37320,     0, 
+    32768, 36864, 37376, 37377, 37312, 37328, 37324,     0, 
+    32768, 36864, 37376, 37377, 37312, 37328, 37324,     0, 
+    32768, 36864, 37376, 37377, 37312, 37328, 37329, 37326, 
+        0, 32768, 36864, 37376, 37377, 37312,     0, 32768, 
+    36864, 37376, 37377, 37312, 37328,     0, 32768, 36864, 
+    37376, 37377, 37312, 37328,     0, 32768, 36864, 37376, 
+    37377, 37312, 37328, 37330,     0, 32768, 36864, 37376, 
+    37377, 37312, 37328,     0, 32768, 36864, 37376, 37377, 
+    37312, 37328, 37332,     0, 32768, 36864, 37376, 37377, 
+    37312, 37328, 37332,     0, 32768, 36864, 37376, 37377, 
+    37312, 37328, 37336, 37334,     0, 32768, 36864, 37376, 
+    37377, 37312, 37328,     0, 32768, 36864, 37376, 37377, 
+    37312, 37344, 37336,     0, 32768, 36864, 37376, 37377, 
+    37312, 37344, 37336,     0, 32768, 36864, 37376, 37377, 
+    37312, 37344, 37336, 37338,     0, 32768, 36864, 37376, 
+    37377, 37312, 37344, 37336,     0, 32768, 36864, 37376, 
+    37377, 37312, 37344, 37345, 37340,     0, 32768, 36864, 
+    37376, 37377, 37312, 37344, 37345, 37340,     0, 32768, 
+    36864, 37376, 37377, 37312, 37344, 37345, 37340, 37342, 
+        0, 32768, 36864, 37376, 37377, 37312,     0, 32768, 
+    36864, 37376, 37377, 37312, 37344,     0, 32768, 36864, 
+    37376, 37377, 37379, 37344,     0, 32768, 36864, 37376, 
+    37377, 37379, 37344, 37346,     0, 32768, 36864, 37376, 
+    37377, 37379, 37344,     0, 32768, 36864, 37376, 37377, 
+    37379, 37344, 37348,     0, 32768, 36864, 37376, 37377, 
+    37379, 37344, 37348,     0, 32768, 36864, 37376, 37377, 
+    37379, 37344, 37352, 37350,     0, 32768, 36864, 37376, 
+    37377, 37379, 37344,     0, 32768, 36864, 37376, 37377, 
+    37379, 37344, 37352,     0, 32768, 36864, 37376, 37377, 
+    37379, 37344, 37352,     0, 32768, 36864, 37376, 37377, 
+    37379, 37344, 37352, 37354,     0, 32768, 36864, 37376, 
+    37377, 37379, 37344, 37352,     0, 32768, 36864, 37376, 
+    37377, 37379, 37344, 37360, 37356,     0, 32768, 36864, 
+    37376, 37377, 37379, 37344, 37360, 37356,     0, 32768, 
+    36864, 37376, 37377, 37379, 37344, 37360, 37361, 37358, 
+        0, 32768, 36864, 37376, 37377, 37379, 37344,     0, 
+    32768, 36864, 37376, 37377, 37379, 37344, 37360,     0, 
+    32768, 36864, 37376, 37377, 37379, 37344, 37360,     0, 
+    32768, 36864, 37376, 37377, 37379, 37344, 37360, 37362, 
+        0, 32768, 36864, 37376, 37377, 37379, 37383, 37360, 
+        0, 32768, 36864, 37376, 37377, 37379, 37383, 37360, 
+    37364,     0, 32768, 36864, 37376, 37377, 37379, 37383, 
+    37360, 37364,     0, 32768, 36864, 37376, 37377, 37379, 
+    37383, 37360, 37368, 37366,     0, 32768, 36864, 37376, 
+    37377, 37379, 37383, 37360,     0, 32768, 36864, 37376, 
+    37377, 37379, 37383, 37360, 37368,     0, 32768, 36864, 
+    37376, 37377, 37379, 37383, 37360, 37368,     0, 32768, 
+    36864, 37376, 37377, 37379, 37383, 37360, 37368, 37370, 
+        0, 32768, 36864, 37376, 37377, 37379, 37383, 37360, 
+    37368,     0, 32768, 36864, 37376, 37377, 37379, 37383, 
+    37360, 37368, 37372,     0, 32768, 36864, 37376, 37377, 
+    37379, 37383, 37360, 37368, 37372,     0, 32768, 36864, 
+    37376, 37377, 37379, 37383, 37360, 37368, 37372, 37374, 
+        0, 32768, 36864,     0, 32768, 36864, 37376,     0, 
+    32768, 36864, 37376,     0, 32768, 36864, 37376, 37378, 
+        0, 32768, 36864, 37376,     0, 32768, 36864, 37376, 
+    37380,     0, 32768, 36864, 37376, 37380,     0, 32768, 
+    36864, 37376, 37384, 37382,     0, 32768, 36864, 37376, 
+        0, 32768, 36864, 37376, 37384,     0, 32768, 36864, 
+    37376, 37384,     0, 32768, 36864, 37376, 37384, 37386, 
+        0, 32768, 36864, 37376, 37384,     0, 32768, 36864, 
+    37376, 37392, 37388,     0, 32768, 36864, 37376, 37392, 
+    37388,     0, 32768, 36864, 37376, 37392, 37393, 37390, 
+        0, 32768, 36864, 37376,     0, 32768, 36864, 37376, 
+    37392,     0, 32768, 36864, 37376, 37392,     0, 32768, 
+    36864, 37376, 37392, 37394,     0, 32768, 36864, 37376, 
+    37392,     0, 32768, 36864, 37376, 37392, 37396,     0, 
+    32768, 36864, 37376, 37392, 37396,     0, 32768, 36864, 
+    37376, 37392, 37400, 37398,     0, 32768, 36864, 37376, 
+    37392,     0, 32768, 36864, 37376, 37408, 37400,     0, 
+    32768, 36864, 37376, 37408, 37400,     0, 32768, 36864, 
+    37376, 37408, 37400, 37402,     0, 32768, 36864, 37376, 
+    37408, 37400,     0, 32768, 36864, 37376, 37408, 37409, 
+    37404,     0, 32768, 36864, 37376, 37408, 37409, 37404, 
+        0, 32768, 36864, 37376, 37408, 37409, 37404, 37406, 
+        0, 32768, 36864, 37376,     0, 32768, 36864, 37376, 
+    37408,     0, 32768, 36864, 37376, 37408,     0, 32768, 
+    36864, 37376, 37408, 37410,     0, 32768, 36864, 37376, 
+    37408,     0, 32768, 36864, 37376, 37408, 37412,     0, 
+    32768, 36864, 37376, 37408, 37412,     0, 32768, 36864, 
+    37376, 37408, 37416, 37414,     0, 32768, 36864, 37376, 
+    37408,     0, 32768, 36864, 37376, 37408, 37416,     0, 
+    32768, 36864, 37376, 37408, 37416,     0, 32768, 36864, 
+    37376, 37408, 37416, 37418,     0, 32768, 36864, 37376, 
+    37408, 37416,     0, 32768, 36864, 37376, 37408, 37424, 
+    37420,     0, 32768, 36864, 37376, 37408, 37424, 37420, 
+        0, 32768, 36864, 37376, 37408, 37424, 37425, 37422, 
+        0, 32768, 36864, 37376, 37408,     0, 32768, 36864, 
+    37376, 37440, 37424,     0, 32768, 36864, 37376, 37440, 
+    37424,     0, 32768, 36864, 37376, 37440, 37424, 37426, 
+        0, 32768, 36864, 37376, 37440, 37424,     0, 32768, 
+    36864, 37376, 37440, 37424, 37428,     0, 32768, 36864, 
+    37376, 37440, 37424, 37428,     0, 32768, 36864, 37376, 
+    37440, 37424, 37432, 37430,     0, 32768, 36864, 37376, 
+    37440, 37424,     0, 32768, 36864, 37376, 37440, 37441, 
+    37432,     0, 32768, 36864, 37376, 37440, 37441, 37432, 
+        0, 32768, 36864, 37376, 37440, 37441, 37432, 37434, 
+        0, 32768, 36864, 37376, 37440, 37441, 37432,     0, 
+    32768, 36864, 37376, 37440, 37441, 37432, 37436,     0, 
+    32768, 36864, 37376, 37440, 37441, 37443, 37436,     0, 
+    32768, 36864, 37376, 37440, 37441, 37443, 37436, 37438, 
+        0, 32768, 36864, 37376,     0, 32768, 36864, 37376, 
+    37440,     0, 32768, 36864, 37376, 37440,     0, 32768, 
+    36864, 37376, 37440, 37442,     0, 32768, 36864, 37376, 
+    37440,     0, 32768, 36864, 37376, 37440, 37444,     0, 
+    32768, 36864, 37376, 37440, 37444,     0, 32768, 36864, 
+    37376, 37440, 37448, 37446,     0, 32768, 36864, 37376, 
+    37440,     0, 32768, 36864, 37376, 37440, 37448,     0, 
+    32768, 36864, 37376, 37440, 37448,     0, 32768, 36864, 
+    37376, 37440, 37448, 37450,     0, 32768, 36864, 37376, 
+    37440, 37448,     0, 32768, 36864, 37376, 37440, 37456, 
+    37452,     0, 32768, 36864, 37376, 37440, 37456, 37452, 
+        0, 32768, 36864, 37376, 37440, 37456, 37457, 37454, 
+        0, 32768, 36864, 37376, 37440,     0, 32768, 36864, 
+    37376, 37440, 37456,     0, 32768, 36864, 37376, 37440, 
+    37456,     0, 32768, 36864, 37376, 37440, 37456, 37458, 
+        0, 32768, 36864, 37376, 37440, 37456,     0, 32768, 
+    36864, 37376, 37440, 37456, 37460,     0, 32768, 36864, 
+    37376, 37440, 37456, 37460,     0, 32768, 36864, 37376, 
+    37440, 37456, 37464, 37462,     0, 32768, 36864, 37376, 
+    37440, 37456,     0, 32768, 36864, 37376, 37440, 37472, 
+    37464,     0, 32768, 36864, 37376, 37440, 37472, 37464, 
+        0, 32768, 36864, 37376, 37440, 37472, 37464, 37466, 
+        0, 32768, 36864, 37376, 37440, 37472, 37464,     0, 
+    32768, 36864, 37376, 37440, 37472, 37473, 37468,     0, 
+    32768, 36864, 37376, 37440, 37472, 37473, 37468,     0, 
+    32768, 36864, 37376, 37440, 37472, 37473, 37468, 37470, 
+        0, 32768, 36864, 37376, 37440,     0, 32768, 36864, 
+    37376, 37504, 37472,     0, 32768, 36864, 37376, 37504, 
+    37472,     0, 32768, 36864, 37376, 37504, 37472, 37474, 
+        0, 32768, 36864, 37376, 37504, 37472,     0, 32768, 
+    36864, 37376, 37504, 37472, 37476,     0, 32768, 36864, 
+    37376, 37504, 37472, 37476,     0, 32768, 36864, 37376, 
+    37504, 37472, 37480, 37478,     0, 32768, 36864, 37376, 
+    37504, 37472,     0, 32768, 36864, 37376, 37504, 37472, 
+    37480,     0, 32768, 36864, 37376, 37504, 37472, 37480, 
+        0, 32768, 36864, 37376, 37504, 37472, 37480, 37482, 
+        0, 32768, 36864, 37376, 37504, 37472, 37480,     0, 
+    32768, 36864, 37376, 37504, 37472, 37488, 37484,     0, 
+    32768, 36864, 37376, 37504, 37472, 37488, 37484,     0, 
+    32768, 36864, 37376, 37504, 37472, 37488, 37489, 37486, 
+        0, 32768, 36864, 37376, 37504, 37472,     0, 32768, 
+    36864, 37376, 37504, 37505, 37488,     0, 32768, 36864, 
+    37376, 37504, 37505, 37488,     0, 32768, 36864, 37376, 
+    37504, 37505, 37488, 37490,     0, 32768, 36864, 37376, 
+    37504, 37505, 37488,     0, 32768, 36864, 37376, 37504, 
+    37505, 37488, 37492,     0, 32768, 36864, 37376, 37504, 
+    37505, 37488, 37492,     0, 32768, 36864, 37376, 37504, 
+    37505, 37488, 37496, 37494,     0, 32768, 36864, 37376, 
+    37504, 37505, 37488,     0, 32768, 36864, 37376, 37504, 
+    37505, 37488, 37496,     0, 32768, 36864, 37376, 37504, 
+    37505, 37507, 37496,     0, 32768, 36864, 37376, 37504, 
+    37505, 37507, 37496, 37498,     0, 32768, 36864, 37376, 
+    37504, 37505, 37507, 37496,     0, 32768, 36864, 37376, 
+    37504, 37505, 37507, 37496, 37500,     0, 32768, 36864, 
+    37376, 37504, 37505, 37507, 37496, 37500,     0, 32768, 
+    36864, 37376, 37504, 37505, 37507, 37496, 37500, 37502, 
+        0, 32768, 36864, 37376,     0, 32768, 36864, 37376, 
+    37504,     0, 32768, 36864, 37376, 37504,     0, 32768, 
+    36864, 37376, 37504, 37506,     0, 32768, 36864, 37376, 
+    37504,     0, 32768, 36864, 37376, 37504, 37508,     0, 
+    32768, 36864, 37376, 37504, 37508,     0, 32768, 36864, 
+    37376, 37504, 37512, 37510,     0, 32768, 36864, 37376, 
+    37504,     0, 32768, 36864, 37376, 37504, 37512,     0, 
+    32768, 36864, 37376, 37504, 37512,     0, 32768, 36864, 
+    37376, 37504, 37512, 37514,     0, 32768, 36864, 37376, 
+    37504, 37512,     0, 32768, 36864, 37376, 37504, 37520, 
+    37516,     0, 32768, 36864, 37376, 37504, 37520, 37516, 
+        0, 32768, 36864, 37376, 37504, 37520, 37521, 37518, 
+        0, 32768, 36864, 37376, 37504,     0, 32768, 36864, 
+    37376, 37504, 37520,     0, 32768, 36864, 37376, 37504, 
+    37520,     0, 32768, 36864, 37376, 37504, 37520, 37522, 
+        0, 32768, 36864, 37376, 37504, 37520,     0, 32768, 
+    36864, 37376, 37504, 37520, 37524,     0, 32768, 36864, 
+    37376, 37504, 37520, 37524,     0, 32768, 36864, 37376, 
+    37504, 37520, 37528, 37526,     0, 32768, 36864, 37376, 
+    37504, 37520,     0, 32768, 36864, 37376, 37504, 37536, 
+    37528,     0, 32768, 36864, 37376, 37504, 37536, 37528, 
+        0, 32768, 36864, 37376, 37504, 37536, 37528, 37530, 
+        0, 32768, 36864, 37376, 37504, 37536, 37528,     0, 
+    32768, 36864, 37376, 37504, 37536, 37537, 37532,     0, 
+    32768, 36864, 37376, 37504, 37536, 37537, 37532,     0, 
+    32768, 36864, 37376, 37504, 37536, 37537, 37532, 37534, 
+        0, 32768, 36864, 37376, 37504,     0, 32768, 36864, 
+    37376, 37504, 37536,     0, 32768, 36864, 37376, 37504, 
+    37536,     0, 32768, 36864, 37376, 37504, 37536, 37538, 
+        0, 32768, 36864, 37376, 37504, 37536,     0, 32768, 
+    36864, 37376, 37504, 37536, 37540,     0, 32768, 36864, 
+    37376, 37504, 37536, 37540,     0, 32768, 36864, 37376, 
+    37504, 37536, 37544, 37542,     0, 32768, 36864, 37376, 
+    37504, 37536,     0, 32768, 36864, 37376, 37504, 37536, 
+    37544,     0, 32768, 36864, 37376, 37504, 37536, 37544, 
+        0, 32768, 36864, 37376, 37504, 37536, 37544, 37546, 
+        0, 32768, 36864, 37376, 37504, 37536, 37544,     0, 
+    32768, 36864, 37376, 37504, 37536, 37552, 37548,     0, 
+    32768, 36864, 37376, 37504, 37536, 37552, 37548,     0, 
+    32768, 36864, 37376, 37504, 37536, 37552, 37553, 37550, 
+        0, 32768, 36864, 37376, 37504, 37536,     0, 32768, 
+    36864, 37376, 37504, 37568, 37552,     0, 32768, 36864, 
+    37376, 37504, 37568, 37552,     0, 32768, 36864, 37376, 
+    37504, 37568, 37552, 37554,     0, 32768, 36864, 37376, 
+    37504, 37568, 37552,     0, 32768, 36864, 37376, 37504, 
+    37568, 37552, 37556,     0, 32768, 36864, 37376, 37504, 
+    37568, 37552, 37556,     0, 32768, 36864, 37376, 37504, 
+    37568, 37552, 37560, 37558,     0, 32768, 36864, 37376, 
+    37504, 37568, 37552,     0, 32768, 36864, 37376, 37504, 
+    37568, 37569, 37560,     0, 32768, 36864, 37376, 37504, 
+    37568, 37569, 37560,     0, 32768, 36864, 37376, 37504, 
+    37568, 37569, 37560, 37562,     0, 32768, 36864, 37376, 
+    37504, 37568, 37569, 37560,     0, 32768, 36864, 37376, 
+    37504, 37568, 37569, 37560, 37564,     0, 32768, 36864, 
+    37376, 37504, 37568, 37569, 37571, 37564,     0, 32768, 
+    36864, 37376, 37504, 37568, 37569, 37571, 37564, 37566, 
+        0, 32768, 36864, 37376, 37504,     0, 32768, 36864, 
+    37376, 37632, 37568,     0, 32768, 36864, 37376, 37632, 
+    37568,     0, 32768, 36864, 37376, 37632, 37568, 37570, 
+        0, 32768, 36864, 37376, 37632, 37568,     0, 32768, 
+    36864, 37376, 37632, 37568, 37572,     0, 32768, 36864, 
+    37376, 37632, 37568, 37572,     0, 32768, 36864, 37376, 
+    37632, 37568, 37576, 37574,     0, 32768, 36864, 37376, 
+    37632, 37568,     0, 32768, 36864, 37376, 37632, 37568, 
+    37576,     0, 32768, 36864, 37376, 37632, 37568, 37576, 
+        0, 32768, 36864, 37376, 37632, 37568, 37576, 37578, 
+        0, 32768, 36864, 37376, 37632, 37568, 37576,     0, 
+    32768, 36864, 37376, 37632, 37568, 37584, 37580,     0, 
+    32768, 36864, 37376, 37632, 37568, 37584, 37580,     0, 
+    32768, 36864, 37376, 37632, 37568, 37584, 37585, 37582, 
+        0, 32768, 36864, 37376, 37632, 37568,     0, 32768, 
+    36864, 37376, 37632, 37568, 37584,     0, 32768, 36864, 
+    37376, 37632, 37568, 37584,     0, 32768, 36864, 37376, 
+    37632, 37568, 37584, 37586,     0, 32768, 36864, 37376, 
+    37632, 37568, 37584,     0, 32768, 36864, 37376, 37632, 
+    37568, 37584, 37588,     0, 32768, 36864, 37376, 37632, 
+    37568, 37584, 37588,     0, 32768, 36864, 37376, 37632, 
+    37568, 37584, 37592, 37590,     0, 32768, 36864, 37376, 
+    37632, 37568, 37584,     0, 32768, 36864, 37376, 37632, 
+    37568, 37600, 37592,     0, 32768, 36864, 37376, 37632, 
+    37568, 37600, 37592,     0, 32768, 36864, 37376, 37632, 
+    37568, 37600, 37592, 37594,     0, 32768, 36864, 37376, 
+    37632, 37568, 37600, 37592,     0, 32768, 36864, 37376, 
+    37632, 37568, 37600, 37601, 37596,     0, 32768, 36864, 
+    37376, 37632, 37568, 37600, 37601, 37596,     0, 32768, 
+    36864, 37376, 37632, 37568, 37600, 37601, 37596, 37598, 
+        0, 32768, 36864, 37376, 37632, 37568,     0, 32768, 
+    36864, 37376, 37632, 37633, 37600,     0, 32768, 36864, 
+    37376, 37632, 37633, 37600,     0, 32768, 36864, 37376, 
+    37632, 37633, 37600, 37602,     0, 32768, 36864, 37376, 
+    37632, 37633, 37600,     0, 32768, 36864, 37376, 37632, 
+    37633, 37600, 37604,     0, 32768, 36864, 37376, 37632, 
+    37633, 37600, 37604,     0, 32768, 36864, 37376, 37632, 
+    37633, 37600, 37608, 37606,     0, 32768, 36864, 37376, 
+    37632, 37633, 37600,     0, 32768, 36864, 37376, 37632, 
+    37633, 37600, 37608,     0, 32768, 36864, 37376, 37632, 
+    37633, 37600, 37608,     0, 32768, 36864, 37376, 37632, 
+    37633, 37600, 37608, 37610,     0, 32768, 36864, 37376, 
+    37632, 37633, 37600, 37608,     0, 32768, 36864, 37376, 
+    37632, 37633, 37600, 37616, 37612,     0, 32768, 36864, 
+    37376, 37632, 37633, 37600, 37616, 37612,     0, 32768, 
+    36864, 37376, 37632, 37633, 37600, 37616, 37617, 37614, 
+        0, 32768, 36864, 37376, 37632, 37633, 37600,     0, 
+    32768, 36864, 37376, 37632, 37633, 37600, 37616,     0, 
+    32768, 36864, 37376, 37632, 37633, 37635, 37616,     0, 
+    32768, 36864, 37376, 37632, 37633, 37635, 37616, 37618, 
+        0, 32768, 36864, 37376, 37632, 37633, 37635, 37616, 
+        0, 32768, 36864, 37376, 37632, 37633, 37635, 37616, 
+    37620,     0, 32768, 36864, 37376, 37632, 37633, 37635, 
+    37616, 37620,     0, 32768, 36864, 37376, 37632, 37633, 
+    37635, 37616, 37624, 37622,     0, 32768, 36864, 37376, 
+    37632, 37633, 37635, 37616,     0, 32768, 36864, 37376, 
+    37632, 37633, 37635, 37616, 37624,     0, 32768, 36864, 
+    37376, 37632, 37633, 37635, 37616, 37624,     0, 32768, 
+    36864, 37376, 37632, 37633, 37635, 37616, 37624, 37626, 
+        0, 32768, 36864, 37376, 37632, 37633, 37635, 37639, 
+    37624,     0, 32768, 36864, 37376, 37632, 37633, 37635, 
+    37639, 37624, 37628,     0, 32768, 36864, 37376, 37632, 
+    37633, 37635, 37639, 37624, 37628,     0, 32768, 36864, 
+    37376, 37632, 37633, 37635, 37639, 37624, 37628, 37630, 
+        0, 32768, 36864, 37376,     0, 32768, 36864, 37888, 
+    37632,     0, 32768, 36864, 37888, 37632,     0, 32768, 
+    36864, 37888, 37632, 37634,     0, 32768, 36864, 37888, 
+    37632,     0, 32768, 36864, 37888, 37632, 37636,     0, 
+    32768, 36864, 37888, 37632, 37636,     0, 32768, 36864, 
+    37888, 37632, 37640, 37638,     0, 32768, 36864, 37888, 
+    37632,     0, 32768, 36864, 37888, 37632, 37640,     0, 
+    32768, 36864, 37888, 37632, 37640,     0, 32768, 36864, 
+    37888, 37632, 37640, 37642,     0, 32768, 36864, 37888, 
+    37632, 37640,     0, 32768, 36864, 37888, 37632, 37648, 
+    37644,     0, 32768, 36864, 37888, 37632, 37648, 37644, 
+        0, 32768, 36864, 37888, 37632, 37648, 37649, 37646, 
+        0, 32768, 36864, 37888, 37632,     0, 32768, 36864, 
+    37888, 37632, 37648,     0, 32768, 36864, 37888, 37632, 
+    37648,     0, 32768, 36864, 37888, 37632, 37648, 37650, 
+        0, 32768, 36864, 37888, 37632, 37648,     0, 32768, 
+    36864, 37888, 37632, 37648, 37652,     0, 32768, 36864, 
+    37888, 37632, 37648, 37652,     0, 32768, 36864, 37888, 
+    37632, 37648, 37656, 37654,     0, 32768, 36864, 37888, 
+    37632, 37648,     0, 32768, 36864, 37888, 37632, 37664, 
+    37656,     0, 32768, 36864, 37888, 37632, 37664, 37656, 
+        0, 32768, 36864, 37888, 37632, 37664, 37656, 37658, 
+        0, 32768, 36864, 37888, 37632, 37664, 37656,     0, 
+    32768, 36864, 37888, 37632, 37664, 37665, 37660,     0, 
+    32768, 36864, 37888, 37632, 37664, 37665, 37660,     0, 
+    32768, 36864, 37888, 37632, 37664, 37665, 37660, 37662, 
+        0, 32768, 36864, 37888, 37632,     0, 32768, 36864, 
+    37888, 37632, 37664,     0, 32768, 36864, 37888, 37632, 
+    37664,     0, 32768, 36864, 37888, 37632, 37664, 37666, 
+        0, 32768, 36864, 37888, 37632, 37664,     0, 32768, 
+    36864, 37888, 37632, 37664, 37668,     0, 32768, 36864, 
+    37888, 37632, 37664, 37668,     0, 32768, 36864, 37888, 
+    37632, 37664, 37672, 37670,     0, 32768, 36864, 37888, 
+    37632, 37664,     0, 32768, 36864, 37888, 37632, 37664, 
+    37672,     0, 32768, 36864, 37888, 37632, 37664, 37672, 
+        0, 32768, 36864, 37888, 37632, 37664, 37672, 37674, 
+        0, 32768, 36864, 37888, 37632, 37664, 37672,     0, 
+    32768, 36864, 37888, 37632, 37664, 37680, 37676,     0, 
+    32768, 36864, 37888, 37632, 37664, 37680, 37676,     0, 
+    32768, 36864, 37888, 37632, 37664, 37680, 37681, 37678, 
+        0, 32768, 36864, 37888, 37632, 37664,     0, 32768, 
+    36864, 37888, 37632, 37696, 37680,     0, 32768, 36864, 
+    37888, 37632, 37696, 37680,     0, 32768, 36864, 37888, 
+    37632, 37696, 37680, 37682,     0, 32768, 36864, 37888, 
+    37632, 37696, 37680,     0, 32768, 36864, 37888, 37632, 
+    37696, 37680, 37684,     0, 32768, 36864, 37888, 37632, 
+    37696, 37680, 37684,     0, 32768, 36864, 37888, 37632, 
+    37696, 37680, 37688, 37686,     0, 32768, 36864, 37888, 
+    37632, 37696, 37680,     0, 32768, 36864, 37888, 37632, 
+    37696, 37697, 37688,     0, 32768, 36864, 37888, 37632, 
+    37696, 37697, 37688,     0, 32768, 36864, 37888, 37632, 
+    37696, 37697, 37688, 37690,     0, 32768, 36864, 37888, 
+    37632, 37696, 37697, 37688,     0, 32768, 36864, 37888, 
+    37632, 37696, 37697, 37688, 37692,     0, 32768, 36864, 
+    37888, 37632, 37696, 37697, 37699, 37692,     0, 32768, 
+    36864, 37888, 37632, 37696, 37697, 37699, 37692, 37694, 
+        0, 32768, 36864, 37888, 37632,     0, 32768, 36864, 
+    37888, 37632, 37696,     0, 32768, 36864, 37888, 37632, 
+    37696,     0, 32768, 36864, 37888, 37632, 37696, 37698, 
+        0, 32768, 36864, 37888, 37632, 37696,     0, 32768, 
+    36864, 37888, 37632, 37696, 37700,     0, 32768, 36864, 
+    37888, 37632, 37696, 37700,     0, 32768, 36864, 37888, 
+    37632, 37696, 37704, 37702,     0, 32768, 36864, 37888, 
+    37632, 37696,     0, 32768, 36864, 37888, 37632, 37696, 
+    37704,     0, 32768, 36864, 37888, 37632, 37696, 37704, 
+        0, 32768, 36864, 37888, 37632, 37696, 37704, 37706, 
+        0, 32768, 36864, 37888, 37632, 37696, 37704,     0, 
+    32768, 36864, 37888, 37632, 37696, 37712, 37708,     0, 
+    32768, 36864, 37888, 37632, 37696, 37712, 37708,     0, 
+    32768, 36864, 37888, 37632, 37696, 37712, 37713, 37710, 
+        0, 32768, 36864, 37888, 37632, 37696,     0, 32768, 
+    36864, 37888, 37632, 37696, 37712,     0, 32768, 36864, 
+    37888, 37632, 37696, 37712,     0, 32768, 36864, 37888, 
+    37632, 37696, 37712, 37714,     0, 32768, 36864, 37888, 
+    37632, 37696, 37712,     0, 32768, 36864, 37888, 37632, 
+    37696, 37712, 37716,     0, 32768, 36864, 37888, 37632, 
+    37696, 37712, 37716,     0, 32768, 36864, 37888, 37632, 
+    37696, 37712, 37720, 37718,     0, 32768, 36864, 37888, 
+    37632, 37696, 37712,     0, 32768, 36864, 37888, 37632, 
+    37696, 37728, 37720,     0, 32768, 36864, 37888, 37632, 
+    37696, 37728, 37720,     0, 32768, 36864, 37888, 37632, 
+    37696, 37728, 37720, 37722,     0, 32768, 36864, 37888, 
+    37632, 37696, 37728, 37720,     0, 32768, 36864, 37888, 
+    37632, 37696, 37728, 37729, 37724,     0, 32768, 36864, 
+    37888, 37632, 37696, 37728, 37729, 37724,     0, 32768, 
+    36864, 37888, 37632, 37696, 37728, 37729, 37724, 37726, 
+        0, 32768, 36864, 37888, 37632, 37696,     0, 32768, 
+    36864, 37888, 37632, 37760, 37728,     0, 32768, 36864, 
+    37888, 37632, 37760, 37728,     0, 32768, 36864, 37888, 
+    37632, 37760, 37728, 37730,     0, 32768, 36864, 37888, 
+    37632, 37760, 37728,     0, 32768, 36864, 37888, 37632, 
+    37760, 37728, 37732,     0, 32768, 36864, 37888, 37632, 
+    37760, 37728, 37732,     0, 32768, 36864, 37888, 37632, 
+    37760, 37728, 37736, 37734,     0, 32768, 36864, 37888, 
+    37632, 37760, 37728,     0, 32768, 36864, 37888, 37632, 
+    37760, 37728, 37736,     0, 32768, 36864, 37888, 37632, 
+    37760, 37728, 37736,     0, 32768, 36864, 37888, 37632, 
+    37760, 37728, 37736, 37738,     0, 32768, 36864, 37888, 
+    37632, 37760, 37728, 37736,     0, 32768, 36864, 37888, 
+    37632, 37760, 37728, 37744, 37740,     0, 32768, 36864, 
+    37888, 37632, 37760, 37728, 37744, 37740,     0, 32768, 
+    36864, 37888, 37632, 37760, 37728, 37744, 37745, 37742, 
+        0, 32768, 36864, 37888, 37632, 37760, 37728,     0, 
+    32768, 36864, 37888, 37632, 37760, 37761, 37744,     0, 
+    32768, 36864, 37888, 37632, 37760, 37761, 37744,     0, 
+    32768, 36864, 37888, 37632, 37760, 37761, 37744, 37746, 
+        0, 32768, 36864, 37888, 37632, 37760, 37761, 37744, 
+        0, 32768, 36864, 37888, 37632, 37760, 37761, 37744, 
+    37748,     0, 32768, 36864, 37888, 37632, 37760, 37761, 
+    37744, 37748,     0, 32768, 36864, 37888, 37632, 37760, 
+    37761, 37744, 37752, 37750,     0, 32768, 36864, 37888, 
+    37632, 37760, 37761, 37744,     0, 32768, 36864, 37888, 
+    37632, 37760, 37761, 37744, 37752,     0, 32768, 36864, 
+    37888, 37632, 37760, 37761, 37763, 37752,     0, 32768, 
+    36864, 37888, 37632, 37760, 37761, 37763, 37752, 37754, 
+        0, 32768, 36864, 37888, 37632, 37760, 37761, 37763, 
+    37752,     0, 32768, 36864, 37888, 37632, 37760, 37761, 
+    37763, 37752, 37756,     0, 32768, 36864, 37888, 37632, 
+    37760, 37761, 37763, 37752, 37756,     0, 32768, 36864, 
+    37888, 37632, 37760, 37761, 37763, 37752, 37756, 37758, 
+        0, 32768, 36864, 37888, 37632,     0, 32768, 36864, 
+    37888, 37632, 37760,     0, 32768, 36864, 37888, 37889, 
+    37760,     0, 32768, 36864, 37888, 37889, 37760, 37762, 
+        0, 32768, 36864, 37888, 37889, 37760,     0, 32768, 
+    36864, 37888, 37889, 37760, 37764,     0, 32768, 36864, 
+    37888, 37889, 37760, 37764,     0, 32768, 36864, 37888, 
+    37889, 37760, 37768, 37766,     0, 32768, 36864, 37888, 
+    37889, 37760,     0, 32768, 36864, 37888, 37889, 37760, 
+    37768,     0, 32768, 36864, 37888, 37889, 37760, 37768, 
+        0, 32768, 36864, 37888, 37889, 37760, 37768, 37770, 
+        0, 32768, 36864, 37888, 37889, 37760, 37768,     0, 
+    32768, 36864, 37888, 37889, 37760, 37776, 37772,     0, 
+    32768, 36864, 37888, 37889, 37760, 37776, 37772,     0, 
+    32768, 36864, 37888, 37889, 37760, 37776, 37777, 37774, 
+        0, 32768, 36864, 37888, 37889, 37760,     0, 32768, 
+    36864, 37888, 37889, 37760, 37776,     0, 32768, 36864, 
+    37888, 37889, 37760, 37776,     0, 32768, 36864, 37888, 
+    37889, 37760, 37776, 37778,     0, 32768, 36864, 37888, 
+    37889, 37760, 37776,     0, 32768, 36864, 37888, 37889, 
+    37760, 37776, 37780,     0, 32768, 36864, 37888, 37889, 
+    37760, 37776, 37780,     0, 32768, 36864, 37888, 37889, 
+    37760, 37776, 37784, 37782,     0, 32768, 36864, 37888, 
+    37889, 37760, 37776,     0, 32768, 36864, 37888, 37889, 
+    37760, 37792, 37784,     0, 32768, 36864, 37888, 37889, 
+    37760, 37792, 37784,     0, 32768, 36864, 37888, 37889, 
+    37760, 37792, 37784, 37786,     0, 32768, 36864, 37888, 
+    37889, 37760, 37792, 37784,     0, 32768, 36864, 37888, 
+    37889, 37760, 37792, 37793, 37788,     0, 32768, 36864, 
+    37888, 37889, 37760, 37792, 37793, 37788,     0, 32768, 
+    36864, 37888, 37889, 37760, 37792, 37793, 37788, 37790, 
+        0, 32768, 36864, 37888, 37889, 37760,     0, 32768, 
+    36864, 37888, 37889, 37760, 37792,     0, 32768, 36864, 
+    37888, 37889, 37760, 37792,     0, 32768, 36864, 37888, 
+    37889, 37760, 37792, 37794,     0, 32768, 36864, 37888, 
+    37889, 37760, 37792,     0, 32768, 36864, 37888, 37889, 
+    37760, 37792, 37796,     0, 32768, 36864, 37888, 37889, 
+    37760, 37792, 37796,     0, 32768, 36864, 37888, 37889, 
+    37760, 37792, 37800, 37798,     0, 32768, 36864, 37888, 
+    37889, 37760, 37792,     0, 32768, 36864, 37888, 37889, 
+    37760, 37792, 37800,     0, 32768, 36864, 37888, 37889, 
+    37760, 37792, 37800,     0, 32768, 36864, 37888, 37889, 
+    37760, 37792, 37800, 37802,     0, 32768, 36864, 37888, 
+    37889, 37760, 37792, 37800,     0, 32768, 36864, 37888, 
+    37889, 37760, 37792, 37808, 37804,     0, 32768, 36864, 
+    37888, 37889, 37760, 37792, 37808, 37804,     0, 32768, 
+    36864, 37888, 37889, 37760, 37792, 37808, 37809, 37806, 
+        0, 32768, 36864, 37888, 37889, 37760, 37792,     0, 
+    32768, 36864, 37888, 37889, 37760, 37824, 37808,     0, 
+    32768, 36864, 37888, 37889, 37760, 37824, 37808,     0, 
+    32768, 36864, 37888, 37889, 37760, 37824, 37808, 37810, 
+        0, 32768, 36864, 37888, 37889, 37760, 37824, 37808, 
+        0, 32768, 36864, 37888, 37889, 37760, 37824, 37808, 
+    37812,     0, 32768, 36864, 37888, 37889, 37760, 37824, 
+    37808, 37812,     0, 32768, 36864, 37888, 37889, 37760, 
+    37824, 37808, 37816, 37814,     0, 32768, 36864, 37888, 
+    37889, 37760, 37824, 37808,     0, 32768, 36864, 37888, 
+    37889, 37760, 37824, 37825, 37816,     0, 32768, 36864, 
+    37888, 37889, 37760, 37824, 37825, 37816,     0, 32768, 
+    36864, 37888, 37889, 37760, 37824, 37825, 37816, 37818, 
+        0, 32768, 36864, 37888, 37889, 37760, 37824, 37825, 
+    37816,     0, 32768, 36864, 37888, 37889, 37760, 37824, 
+    37825, 37816, 37820,     0, 32768, 36864, 37888, 37889, 
+    37760, 37824, 37825, 37827, 37820,     0, 32768, 36864, 
+    37888, 37889, 37760, 37824, 37825, 37827, 37820, 37822, 
+        0, 32768, 36864, 37888, 37889, 37760,     0, 32768, 
+    36864, 37888, 37889, 37760, 37824,     0, 32768, 36864, 
+    37888, 37889, 37760, 37824,     0, 32768, 36864, 37888, 
+    37889, 37760, 37824, 37826,     0, 32768, 36864, 37888, 
+    37889, 37891, 37824,     0, 32768, 36864, 37888, 37889, 
+    37891, 37824, 37828,     0, 32768, 36864, 37888, 37889, 
+    37891, 37824, 37828,     0, 32768, 36864, 37888, 37889, 
+    37891, 37824, 37832, 37830,     0, 32768, 36864, 37888, 
+    37889, 37891, 37824,     0, 32768, 36864, 37888, 37889, 
+    37891, 37824, 37832,     0, 32768, 36864, 37888, 37889, 
+    37891, 37824, 37832,     0, 32768, 36864, 37888, 37889, 
+    37891, 37824, 37832, 37834,     0, 32768, 36864, 37888, 
+    37889, 37891, 37824, 37832,     0, 32768, 36864, 37888, 
+    37889, 37891, 37824, 37840, 37836,     0, 32768, 36864, 
+    37888, 37889, 37891, 37824, 37840, 37836,     0, 32768, 
+    36864, 37888, 37889, 37891, 37824, 37840, 37841, 37838, 
+        0, 32768, 36864, 37888, 37889, 37891, 37824,     0, 
+    32768, 36864, 37888, 37889, 37891, 37824, 37840,     0, 
+    32768, 36864, 37888, 37889, 37891, 37824, 37840,     0, 
+    32768, 36864, 37888, 37889, 37891, 37824, 37840, 37842, 
+        0, 32768, 36864, 37888, 37889, 37891, 37824, 37840, 
+        0, 32768, 36864, 37888, 37889, 37891, 37824, 37840, 
+    37844,     0, 32768, 36864, 37888, 37889, 37891, 37824, 
+    37840, 37844,     0, 32768, 36864, 37888, 37889, 37891, 
+    37824, 37840, 37848, 37846,     0, 32768, 36864, 37888, 
+    37889, 37891, 37824, 37840,     0, 32768, 36864, 37888, 
+    37889, 37891, 37824, 37856, 37848,     0, 32768, 36864, 
+    37888, 37889, 37891, 37824, 37856, 37848,     0, 32768, 
+    36864, 37888, 37889, 37891, 37824, 37856, 37848, 37850, 
+        0, 32768, 36864, 37888, 37889, 37891, 37824, 37856, 
+    37848,     0, 32768, 36864, 37888, 37889, 37891, 37824, 
+    37856, 37857, 37852,     0, 32768, 36864, 37888, 37889, 
+    37891, 37824, 37856, 37857, 37852,     0, 32768, 36864, 
+    37888, 37889, 37891, 37824, 37856, 37857, 37852, 37854, 
+        0, 32768, 36864, 37888, 37889, 37891, 37824,     0, 
+    32768, 36864, 37888, 37889, 37891, 37824, 37856,     0, 
+    32768, 36864, 37888, 37889, 37891, 37824, 37856,     0, 
+    32768, 36864, 37888, 37889, 37891, 37824, 37856, 37858, 
+        0, 32768, 36864, 37888, 37889, 37891, 37824, 37856, 
+        0, 32768, 36864, 37888, 37889, 37891, 37824, 37856, 
+    37860,     0, 32768, 36864, 37888, 37889, 37891, 37824, 
+    37856, 37860,     0, 32768, 36864, 37888, 37889, 37891, 
+    37824, 37856, 37864, 37862,     0, 32768, 36864, 37888, 
+    37889, 37891, 37895, 37856,     0, 32768, 36864, 37888, 
+    37889, 37891, 37895, 37856, 37864,     0, 32768, 36864, 
+    37888, 37889, 37891, 37895, 37856, 37864,     0, 32768, 
+    36864, 37888, 37889, 37891, 37895, 37856, 37864, 37866, 
+        0, 32768, 36864, 37888, 37889, 37891, 37895, 37856, 
+    37864,     0, 32768, 36864, 37888, 37889, 37891, 37895, 
+    37856, 37872, 37868,     0, 32768, 36864, 37888, 37889, 
+    37891, 37895, 37856, 37872, 37868,     0, 32768, 36864, 
+    37888, 37889, 37891, 37895, 37856, 37872, 37873, 37870, 
+        0, 32768, 36864, 37888, 37889, 37891, 37895, 37856, 
+        0, 32768, 36864, 37888, 37889, 37891, 37895, 37856, 
+    37872,     0, 32768, 36864, 37888, 37889, 37891, 37895, 
+    37856, 37872,     0, 32768, 36864, 37888, 37889, 37891, 
+    37895, 37856, 37872, 37874,     0, 32768, 36864, 37888, 
+    37889, 37891, 37895, 37856, 37872,     0, 32768, 36864, 
+    37888, 37889, 37891, 37895, 37856, 37872, 37876,     0, 
+    32768, 36864, 37888, 37889, 37891, 37895, 37856, 37872, 
+    37876,     0, 32768, 36864, 37888, 37889, 37891, 37895, 
+    37856, 37872, 37880, 37878,     0, 32768, 36864, 37888, 
+    37889, 37891, 37895, 37856, 37872,     0, 32768, 36864, 
+    37888, 37889, 37891, 37895, 37856, 37872, 37880,     0, 
+    32768, 36864, 37888, 37889, 37891, 37895, 37856, 37872, 
+    37880,     0, 32768, 36864, 37888, 37889, 37891, 37895, 
+    37856, 37872, 37880, 37882,     0, 32768, 36864, 37888, 
+    37889, 37891, 37895, 37856, 37872, 37880,     0, 32768, 
+    36864, 37888, 37889, 37891, 37895, 37856, 37872, 37880, 
+    37884,     0, 32768, 36864, 37888, 37889, 37891, 37895, 
+    37856, 37872, 37880, 37884,     0, 32768, 36864, 37888, 
+    37889, 37891, 37895, 37856, 37872, 37880, 37884, 37886, 
+        0, 32768, 36864,     0, 32768, 36864, 37888,     0, 
+    32768, 36864, 37888,     0, 32768, 36864, 37888, 37890, 
+        0, 32768, 36864, 37888,     0, 32768, 36864, 37888, 
+    37892,     0, 32768, 36864, 37888, 37892,     0, 32768, 
+    36864, 37888, 37896, 37894,     0, 32768, 36864, 37888, 
+        0, 32768, 36864, 37888, 37896,     0, 32768, 36864, 
+    37888, 37896,     0, 32768, 36864, 37888, 37896, 37898, 
+        0, 32768, 36864, 37888, 37896,     0, 32768, 36864, 
+    37888, 37904, 37900,     0, 32768, 36864, 37888, 37904, 
+    37900,     0, 32768, 36864, 37888, 37904, 37905, 37902, 
+        0, 32768, 36864, 37888,     0, 32768, 36864, 37888, 
+    37904,     0, 32768, 36864, 37888, 37904,     0, 32768, 
+    36864, 37888, 37904, 37906,     0, 32768, 36864, 37888, 
+    37904,     0, 32768, 36864, 37888, 37904, 37908,     0, 
+    32768, 36864, 37888, 37904, 37908,     0, 32768, 36864, 
+    37888, 37904, 37912, 37910,     0, 32768, 36864, 37888, 
+    37904,     0, 32768, 36864, 37888, 37920, 37912,     0, 
+    32768, 36864, 37888, 37920, 37912,     0, 32768, 36864, 
+    37888, 37920, 37912, 37914,     0, 32768, 36864, 37888, 
+    37920, 37912,     0, 32768, 36864, 37888, 37920, 37921, 
+    37916,     0, 32768, 36864, 37888, 37920, 37921, 37916, 
+        0, 32768, 36864, 37888, 37920, 37921, 37916, 37918, 
+        0, 32768, 36864, 37888,     0, 32768, 36864, 37888, 
+    37920,     0, 32768, 36864, 37888, 37920,     0, 32768, 
+    36864, 37888, 37920, 37922,     0, 32768, 36864, 37888, 
+    37920,     0, 32768, 36864, 37888, 37920, 37924,     0, 
+    32768, 36864, 37888, 37920, 37924,     0, 32768, 36864, 
+    37888, 37920, 37928, 37926,     0, 32768, 36864, 37888, 
+    37920,     0, 32768, 36864, 37888, 37920, 37928,     0, 
+    32768, 36864, 37888, 37920, 37928,     0, 32768, 36864, 
+    37888, 37920, 37928, 37930,     0, 32768, 36864, 37888, 
+    37920, 37928,     0, 32768, 36864, 37888, 37920, 37936, 
+    37932,     0, 32768, 36864, 37888, 37920, 37936, 37932, 
+        0, 32768, 36864, 37888, 37920, 37936, 37937, 37934, 
+        0, 32768, 36864, 37888, 37920,     0, 32768, 36864, 
+    37888, 37952, 37936,     0, 32768, 36864, 37888, 37952, 
+    37936,     0, 32768, 36864, 37888, 37952, 37936, 37938, 
+        0, 32768, 36864, 37888, 37952, 37936,     0, 32768, 
+    36864, 37888, 37952, 37936, 37940,     0, 32768, 36864, 
+    37888, 37952, 37936, 37940,     0, 32768, 36864, 37888, 
+    37952, 37936, 37944, 37942,     0, 32768, 36864, 37888, 
+    37952, 37936,     0, 32768, 36864, 37888, 37952, 37953, 
+    37944,     0, 32768, 36864, 37888, 37952, 37953, 37944, 
+        0, 32768, 36864, 37888, 37952, 37953, 37944, 37946, 
+        0, 32768, 36864, 37888, 37952, 37953, 37944,     0, 
+    32768, 36864, 37888, 37952, 37953, 37944, 37948,     0, 
+    32768, 36864, 37888, 37952, 37953, 37955, 37948,     0, 
+    32768, 36864, 37888, 37952, 37953, 37955, 37948, 37950, 
+        0, 32768, 36864, 37888,     0, 32768, 36864, 37888, 
+    37952,     0, 32768, 36864, 37888, 37952,     0, 32768, 
+    36864, 37888, 37952, 37954,     0, 32768, 36864, 37888, 
+    37952,     0, 32768, 36864, 37888, 37952, 37956,     0, 
+    32768, 36864, 37888, 37952, 37956,     0, 32768, 36864, 
+    37888, 37952, 37960, 37958,     0, 32768, 36864, 37888, 
+    37952,     0, 32768, 36864, 37888, 37952, 37960,     0, 
+    32768, 36864, 37888, 37952, 37960,     0, 32768, 36864, 
+    37888, 37952, 37960, 37962,     0, 32768, 36864, 37888, 
+    37952, 37960,     0, 32768, 36864, 37888, 37952, 37968, 
+    37964,     0, 32768, 36864, 37888, 37952, 37968, 37964, 
+        0, 32768, 36864, 37888, 37952, 37968, 37969, 37966, 
+        0, 32768, 36864, 37888, 37952,     0, 32768, 36864, 
+    37888, 37952, 37968,     0, 32768, 36864, 37888, 37952, 
+    37968,     0, 32768, 36864, 37888, 37952, 37968, 37970, 
+        0, 32768, 36864, 37888, 37952, 37968,     0, 32768, 
+    36864, 37888, 37952, 37968, 37972,     0, 32768, 36864, 
+    37888, 37952, 37968, 37972,     0, 32768, 36864, 37888, 
+    37952, 37968, 37976, 37974,     0, 32768, 36864, 37888, 
+    37952, 37968,     0, 32768, 36864, 37888, 37952, 37984, 
+    37976,     0, 32768, 36864, 37888, 37952, 37984, 37976, 
+        0, 32768, 36864, 37888, 37952, 37984, 37976, 37978, 
+        0, 32768, 36864, 37888, 37952, 37984, 37976,     0, 
+    32768, 36864, 37888, 37952, 37984, 37985, 37980,     0, 
+    32768, 36864, 37888, 37952, 37984, 37985, 37980,     0, 
+    32768, 36864, 37888, 37952, 37984, 37985, 37980, 37982, 
+        0, 32768, 36864, 37888, 37952,     0, 32768, 36864, 
+    37888, 38016, 37984,     0, 32768, 36864, 37888, 38016, 
+    37984,     0, 32768, 36864, 37888, 38016, 37984, 37986, 
+        0, 32768, 36864, 37888, 38016, 37984,     0, 32768, 
+    36864, 37888, 38016, 37984, 37988,     0, 32768, 36864, 
+    37888, 38016, 37984, 37988,     0, 32768, 36864, 37888, 
+    38016, 37984, 37992, 37990,     0, 32768, 36864, 37888, 
+    38016, 37984,     0, 32768, 36864, 37888, 38016, 37984, 
+    37992,     0, 32768, 36864, 37888, 38016, 37984, 37992, 
+        0, 32768, 36864, 37888, 38016, 37984, 37992, 37994, 
+        0, 32768, 36864, 37888, 38016, 37984, 37992,     0, 
+    32768, 36864, 37888, 38016, 37984, 38000, 37996,     0, 
+    32768, 36864, 37888, 38016, 37984, 38000, 37996,     0, 
+    32768, 36864, 37888, 38016, 37984, 38000, 38001, 37998, 
+        0, 32768, 36864, 37888, 38016, 37984,     0, 32768, 
+    36864, 37888, 38016, 38017, 38000,     0, 32768, 36864, 
+    37888, 38016, 38017, 38000,     0, 32768, 36864, 37888, 
+    38016, 38017, 38000, 38002,     0, 32768, 36864, 37888, 
+    38016, 38017, 38000,     0, 32768, 36864, 37888, 38016, 
+    38017, 38000, 38004,     0, 32768, 36864, 37888, 38016, 
+    38017, 38000, 38004,     0, 32768, 36864, 37888, 38016, 
+    38017, 38000, 38008, 38006,     0, 32768, 36864, 37888, 
+    38016, 38017, 38000,     0, 32768, 36864, 37888, 38016, 
+    38017, 38000, 38008,     0, 32768, 36864, 37888, 38016, 
+    38017, 38019, 38008,     0, 32768, 36864, 37888, 38016, 
+    38017, 38019, 38008, 38010,     0, 32768, 36864, 37888, 
+    38016, 38017, 38019, 38008,     0, 32768, 36864, 37888, 
+    38016, 38017, 38019, 38008, 38012,     0, 32768, 36864, 
+    37888, 38016, 38017, 38019, 38008, 38012,     0, 32768, 
+    36864, 37888, 38016, 38017, 38019, 38008, 38012, 38014, 
+        0, 32768, 36864, 37888,     0, 32768, 36864, 37888, 
+    38016,     0, 32768, 36864, 37888, 38016,     0, 32768, 
+    36864, 37888, 38016, 38018,     0, 32768, 36864, 37888, 
+    38016,     0, 32768, 36864, 37888, 38016, 38020,     0, 
+    32768, 36864, 37888, 38016, 38020,     0, 32768, 36864, 
+    37888, 38016, 38024, 38022,     0, 32768, 36864, 37888, 
+    38016,     0, 32768, 36864, 37888, 38016, 38024,     0, 
+    32768, 36864, 37888, 38016, 38024,     0, 32768, 36864, 
+    37888, 38016, 38024, 38026,     0, 32768, 36864, 37888, 
+    38016, 38024,     0, 32768, 36864, 37888, 38016, 38032, 
+    38028,     0, 32768, 36864, 37888, 38016, 38032, 38028, 
+        0, 32768, 36864, 37888, 38016, 38032, 38033, 38030, 
+        0, 32768, 36864, 37888, 38016,     0, 32768, 36864, 
+    37888, 38016, 38032,     0, 32768, 36864, 37888, 38016, 
+    38032,     0, 32768, 36864, 37888, 38016, 38032, 38034, 
+        0, 32768, 36864, 37888, 38016, 38032,     0, 32768, 
+    36864, 37888, 38016, 38032, 38036,     0, 32768, 36864, 
+    37888, 38016, 38032, 38036,     0, 32768, 36864, 37888, 
+    38016, 38032, 38040, 38038,     0, 32768, 36864, 37888, 
+    38016, 38032,     0, 32768, 36864, 37888, 38016, 38048, 
+    38040,     0, 32768, 36864, 37888, 38016, 38048, 38040, 
+        0, 32768, 36864, 37888, 38016, 38048, 38040, 38042, 
+        0, 32768, 36864, 37888, 38016, 38048, 38040,     0, 
+    32768, 36864, 37888, 38016, 38048, 38049, 38044,     0, 
+    32768, 36864, 37888, 38016, 38048, 38049, 38044,     0, 
+    32768, 36864, 37888, 38016, 38048, 38049, 38044, 38046, 
+        0, 32768, 36864, 37888, 38016,     0, 32768, 36864, 
+    37888, 38016, 38048,     0, 32768, 36864, 37888, 38016, 
+    38048,     0, 32768, 36864, 37888, 38016, 38048, 38050, 
+        0, 32768, 36864, 37888, 38016, 38048,     0, 32768, 
+    36864, 37888, 38016, 38048, 38052,     0, 32768, 36864, 
+    37888, 38016, 38048, 38052,     0, 32768, 36864, 37888, 
+    38016, 38048, 38056, 38054,     0, 32768, 36864, 37888, 
+    38016, 38048,     0, 32768, 36864, 37888, 38016, 38048, 
+    38056,     0, 32768, 36864, 37888, 38016, 38048, 38056, 
+        0, 32768, 36864, 37888, 38016, 38048, 38056, 38058, 
+        0, 32768, 36864, 37888, 38016, 38048, 38056,     0, 
+    32768, 36864, 37888, 38016, 38048, 38064, 38060,     0, 
+    32768, 36864, 37888, 38016, 38048, 38064, 38060,     0, 
+    32768, 36864, 37888, 38016, 38048, 38064, 38065, 38062, 
+        0, 32768, 36864, 37888, 38016, 38048,     0, 32768, 
+    36864, 37888, 38016, 38080, 38064,     0, 32768, 36864, 
+    37888, 38016, 38080, 38064,     0, 32768, 36864, 37888, 
+    38016, 38080, 38064, 38066,     0, 32768, 36864, 37888, 
+    38016, 38080, 38064,     0, 32768, 36864, 37888, 38016, 
+    38080, 38064, 38068,     0, 32768, 36864, 37888, 38016, 
+    38080, 38064, 38068,     0, 32768, 36864, 37888, 38016, 
+    38080, 38064, 38072, 38070,     0, 32768, 36864, 37888, 
+    38016, 38080, 38064,     0, 32768, 36864, 37888, 38016, 
+    38080, 38081, 38072,     0, 32768, 36864, 37888, 38016, 
+    38080, 38081, 38072,     0, 32768, 36864, 37888, 38016, 
+    38080, 38081, 38072, 38074,     0, 32768, 36864, 37888, 
+    38016, 38080, 38081, 38072,     0, 32768, 36864, 37888, 
+    38016, 38080, 38081, 38072, 38076,     0, 32768, 36864, 
+    37888, 38016, 38080, 38081, 38083, 38076,     0, 32768, 
+    36864, 37888, 38016, 38080, 38081, 38083, 38076, 38078, 
+        0, 32768, 36864, 37888, 38016,     0, 32768, 36864, 
+    37888, 38144, 38080,     0, 32768, 36864, 37888, 38144, 
+    38080,     0, 32768, 36864, 37888, 38144, 38080, 38082, 
+        0, 32768, 36864, 37888, 38144, 38080,     0, 32768, 
+    36864, 37888, 38144, 38080, 38084,     0, 32768, 36864, 
+    37888, 38144, 38080, 38084,     0, 32768, 36864, 37888, 
+    38144, 38080, 38088, 38086,     0, 32768, 36864, 37888, 
+    38144, 38080,     0, 32768, 36864, 37888, 38144, 38080, 
+    38088,     0, 32768, 36864, 37888, 38144, 38080, 38088, 
+        0, 32768, 36864, 37888, 38144, 38080, 38088, 38090, 
+        0, 32768, 36864, 37888, 38144, 38080, 38088,     0, 
+    32768, 36864, 37888, 38144, 38080, 38096, 38092,     0, 
+    32768, 36864, 37888, 38144, 38080, 38096, 38092,     0, 
+    32768, 36864, 37888, 38144, 38080, 38096, 38097, 38094, 
+        0, 32768, 36864, 37888, 38144, 38080,     0, 32768, 
+    36864, 37888, 38144, 38080, 38096,     0, 32768, 36864, 
+    37888, 38144, 38080, 38096,     0, 32768, 36864, 37888, 
+    38144, 38080, 38096, 38098,     0, 32768, 36864, 37888, 
+    38144, 38080, 38096,     0, 32768, 36864, 37888, 38144, 
+    38080, 38096, 38100,     0, 32768, 36864, 37888, 38144, 
+    38080, 38096, 38100,     0, 32768, 36864, 37888, 38144, 
+    38080, 38096, 38104, 38102,     0, 32768, 36864, 37888, 
+    38144, 38080, 38096,     0, 32768, 36864, 37888, 38144, 
+    38080, 38112, 38104,     0, 32768, 36864, 37888, 38144, 
+    38080, 38112, 38104,     0, 32768, 36864, 37888, 38144, 
+    38080, 38112, 38104, 38106,     0, 32768, 36864, 37888, 
+    38144, 38080, 38112, 38104,     0, 32768, 36864, 37888, 
+    38144, 38080, 38112, 38113, 38108,     0, 32768, 36864, 
+    37888, 38144, 38080, 38112, 38113, 38108,     0, 32768, 
+    36864, 37888, 38144, 38080, 38112, 38113, 38108, 38110, 
+        0, 32768, 36864, 37888, 38144, 38080,     0, 32768, 
+    36864, 37888, 38144, 38145, 38112,     0, 32768, 36864, 
+    37888, 38144, 38145, 38112,     0, 32768, 36864, 37888, 
+    38144, 38145, 38112, 38114,     0, 32768, 36864, 37888, 
+    38144, 38145, 38112,     0, 32768, 36864, 37888, 38144, 
+    38145, 38112, 38116,     0, 32768, 36864, 37888, 38144, 
+    38145, 38112, 38116,     0, 32768, 36864, 37888, 38144, 
+    38145, 38112, 38120, 38118,     0, 32768, 36864, 37888, 
+    38144, 38145, 38112,     0, 32768, 36864, 37888, 38144, 
+    38145, 38112, 38120,     0, 32768, 36864, 37888, 38144, 
+    38145, 38112, 38120,     0, 32768, 36864, 37888, 38144, 
+    38145, 38112, 38120, 38122,     0, 32768, 36864, 37888, 
+    38144, 38145, 38112, 38120,     0, 32768, 36864, 37888, 
+    38144, 38145, 38112, 38128, 38124,     0, 32768, 36864, 
+    37888, 38144, 38145, 38112, 38128, 38124,     0, 32768, 
+    36864, 37888, 38144, 38145, 38112, 38128, 38129, 38126, 
+        0, 32768, 36864, 37888, 38144, 38145, 38112,     0, 
+    32768, 36864, 37888, 38144, 38145, 38112, 38128,     0, 
+    32768, 36864, 37888, 38144, 38145, 38147, 38128,     0, 
+    32768, 36864, 37888, 38144, 38145, 38147, 38128, 38130, 
+        0, 32768, 36864, 37888, 38144, 38145, 38147, 38128, 
+        0, 32768, 36864, 37888, 38144, 38145, 38147, 38128, 
+    38132,     0, 32768, 36864, 37888, 38144, 38145, 38147, 
+    38128, 38132,     0, 32768, 36864, 37888, 38144, 38145, 
+    38147, 38128, 38136, 38134,     0, 32768, 36864, 37888, 
+    38144, 38145, 38147, 38128,     0, 32768, 36864, 37888, 
+    38144, 38145, 38147, 38128, 38136,     0, 32768, 36864, 
+    37888, 38144, 38145, 38147, 38128, 38136,     0, 32768, 
+    36864, 37888, 38144, 38145, 38147, 38128, 38136, 38138, 
+        0, 32768, 36864, 37888, 38144, 38145, 38147, 38151, 
+    38136,     0, 32768, 36864, 37888, 38144, 38145, 38147, 
+    38151, 38136, 38140,     0, 32768, 36864, 37888, 38144, 
+    38145, 38147, 38151, 38136, 38140,     0, 32768, 36864, 
+    37888, 38144, 38145, 38147, 38151, 38136, 38140, 38142, 
+        0, 32768, 36864, 37888,     0, 32768, 36864, 37888, 
+    38144,     0, 32768, 36864, 37888, 38144,     0, 32768, 
+    36864, 37888, 38144, 38146,     0, 32768, 36864, 37888, 
+    38144,     0, 32768, 36864, 37888, 38144, 38148,     0, 
+    32768, 36864, 37888, 38144, 38148,     0, 32768, 36864, 
+    37888, 38144, 38152, 38150,     0, 32768, 36864, 37888, 
+    38144,     0, 32768, 36864, 37888, 38144, 38152,     0, 
+    32768, 36864, 37888, 38144, 38152,     0, 32768, 36864, 
+    37888, 38144, 38152, 38154,     0, 32768, 36864, 37888, 
+    38144, 38152,     0, 32768, 36864, 37888, 38144, 38160, 
+    38156,     0, 32768, 36864, 37888, 38144, 38160, 38156, 
+        0, 32768, 36864, 37888, 38144, 38160, 38161, 38158, 
+        0, 32768, 36864, 37888, 38144,     0, 32768, 36864, 
+    37888, 38144, 38160,     0, 32768, 36864, 37888, 38144, 
+    38160,     0, 32768, 36864, 37888, 38144, 38160, 38162, 
+        0, 32768, 36864, 37888, 38144, 38160,     0, 32768, 
+    36864, 37888, 38144, 38160, 38164,     0, 32768, 36864, 
+    37888, 38144, 38160, 38164,     0, 32768, 36864, 37888, 
+    38144, 38160, 38168, 38166,     0, 32768, 36864, 37888, 
+    38144, 38160,     0, 32768, 36864, 37888, 38144, 38176, 
+    38168,     0, 32768, 36864, 37888, 38144, 38176, 38168, 
+        0, 32768, 36864, 37888, 38144, 38176, 38168, 38170, 
+        0, 32768, 36864, 37888, 38144, 38176, 38168,     0, 
+    32768, 36864, 37888, 38144, 38176, 38177, 38172,     0, 
+    32768, 36864, 37888, 38144, 38176, 38177, 38172,     0, 
+    32768, 36864, 37888, 38144, 38176, 38177, 38172, 38174, 
+        0, 32768, 36864, 37888, 38144,     0, 32768, 36864, 
+    37888, 38144, 38176,     0, 32768, 36864, 37888, 38144, 
+    38176,     0, 32768, 36864, 37888, 38144, 38176, 38178, 
+        0, 32768, 36864, 37888, 38144, 38176,     0, 32768, 
+    36864, 37888, 38144, 38176, 38180,     0, 32768, 36864, 
+    37888, 38144, 38176, 38180,     0, 32768, 36864, 37888, 
+    38144, 38176, 38184, 38182,     0, 32768, 36864, 37888, 
+    38144, 38176,     0, 32768, 36864, 37888, 38144, 38176, 
+    38184,     0, 32768, 36864, 37888, 38144, 38176, 38184, 
+        0, 32768, 36864, 37888, 38144, 38176, 38184, 38186, 
+        0, 32768, 36864, 37888, 38144, 38176, 38184,     0, 
+    32768, 36864, 37888, 38144, 38176, 38192, 38188,     0, 
+    32768, 36864, 37888, 38144, 38176, 38192, 38188,     0, 
+    32768, 36864, 37888, 38144, 38176, 38192, 38193, 38190, 
+        0, 32768, 36864, 37888, 38144, 38176,     0, 32768, 
+    36864, 37888, 38144, 38208, 38192,     0, 32768, 36864, 
+    37888, 38144, 38208, 38192,     0, 32768, 36864, 37888, 
+    38144, 38208, 38192, 38194,     0, 32768, 36864, 37888, 
+    38144, 38208, 38192,     0, 32768, 36864, 37888, 38144, 
+    38208, 38192, 38196,     0, 32768, 36864, 37888, 38144, 
+    38208, 38192, 38196,     0, 32768, 36864, 37888, 38144, 
+    38208, 38192, 38200, 38198,     0, 32768, 36864, 37888, 
+    38144, 38208, 38192,     0, 32768, 36864, 37888, 38144, 
+    38208, 38209, 38200,     0, 32768, 36864, 37888, 38144, 
+    38208, 38209, 38200,     0, 32768, 36864, 37888, 38144, 
+    38208, 38209, 38200, 38202,     0, 32768, 36864, 37888, 
+    38144, 38208, 38209, 38200,     0, 32768, 36864, 37888, 
+    38144, 38208, 38209, 38200, 38204,     0, 32768, 36864, 
+    37888, 38144, 38208, 38209, 38211, 38204,     0, 32768, 
+    36864, 37888, 38144, 38208, 38209, 38211, 38204, 38206, 
+        0, 32768, 36864, 37888, 38144,     0, 32768, 36864, 
+    37888, 38144, 38208,     0, 32768, 36864, 37888, 38144, 
+    38208,     0, 32768, 36864, 37888, 38144, 38208, 38210, 
+        0, 32768, 36864, 37888, 38144, 38208,     0, 32768, 
+    36864, 37888, 38144, 38208, 38212,     0, 32768, 36864, 
+    37888, 38144, 38208, 38212,     0, 32768, 36864, 37888, 
+    38144, 38208, 38216, 38214,     0, 32768, 36864, 37888, 
+    38144, 38208,     0, 32768, 36864, 37888, 38144, 38208, 
+    38216,     0, 32768, 36864, 37888, 38144, 38208, 38216, 
+        0, 32768, 36864, 37888, 38144, 38208, 38216, 38218, 
+        0, 32768, 36864, 37888, 38144, 38208, 38216,     0, 
+    32768, 36864, 37888, 38144, 38208, 38224, 38220,     0, 
+    32768, 36864, 37888, 38144, 38208, 38224, 38220,     0, 
+    32768, 36864, 37888, 38144, 38208, 38224, 38225, 38222, 
+        0, 32768, 36864, 37888, 38144, 38208,     0, 32768, 
+    36864, 37888, 38144, 38208, 38224,     0, 32768, 36864, 
+    37888, 38144, 38208, 38224,     0, 32768, 36864, 37888, 
+    38144, 38208, 38224, 38226,     0, 32768, 36864, 37888, 
+    38144, 38208, 38224,     0, 32768, 36864, 37888, 38144, 
+    38208, 38224, 38228,     0, 32768, 36864, 37888, 38144, 
+    38208, 38224, 38228,     0, 32768, 36864, 37888, 38144, 
+    38208, 38224, 38232, 38230,     0, 32768, 36864, 37888, 
+    38144, 38208, 38224,     0, 32768, 36864, 37888, 38144, 
+    38208, 38240, 38232,     0, 32768, 36864, 37888, 38144, 
+    38208, 38240, 38232,     0, 32768, 36864, 37888, 38144, 
+    38208, 38240, 38232, 38234,     0, 32768, 36864, 37888, 
+    38144, 38208, 38240, 38232,     0, 32768, 36864, 37888, 
+    38144, 38208, 38240, 38241, 38236,     0, 32768, 36864, 
+    37888, 38144, 38208, 38240, 38241, 38236,     0, 32768, 
+    36864, 37888, 38144, 38208, 38240, 38241, 38236, 38238, 
+        0, 32768, 36864, 37888, 38144, 38208,     0, 32768, 
+    36864, 37888, 38144, 38272, 38240,     0, 32768, 36864, 
+    37888, 38144, 38272, 38240,     0, 32768, 36864, 37888, 
+    38144, 38272, 38240, 38242,     0, 32768, 36864, 37888, 
+    38144, 38272, 38240,     0, 32768, 36864, 37888, 38144, 
+    38272, 38240, 38244,     0, 32768, 36864, 37888, 38144, 
+    38272, 38240, 38244,     0, 32768, 36864, 37888, 38144, 
+    38272, 38240, 38248, 38246,     0, 32768, 36864, 37888, 
+    38144, 38272, 38240,     0, 32768, 36864, 37888, 38144, 
+    38272, 38240, 38248,     0, 32768, 36864, 37888, 38144, 
+    38272, 38240, 38248,     0, 32768, 36864, 37888, 38144, 
+    38272, 38240, 38248, 38250,     0, 32768, 36864, 37888, 
+    38144, 38272, 38240, 38248,     0, 32768, 36864, 37888, 
+    38144, 38272, 38240, 38256, 38252,     0, 32768, 36864, 
+    37888, 38144, 38272, 38240, 38256, 38252,     0, 32768, 
+    36864, 37888, 38144, 38272, 38240, 38256, 38257, 38254, 
+        0, 32768, 36864, 37888, 38144, 38272, 38240,     0, 
+    32768, 36864, 37888, 38144, 38272, 38273, 38256,     0, 
+    32768, 36864, 37888, 38144, 38272, 38273, 38256,     0, 
+    32768, 36864, 37888, 38144, 38272, 38273, 38256, 38258, 
+        0, 32768, 36864, 37888, 38144, 38272, 38273, 38256, 
+        0, 32768, 36864, 37888, 38144, 38272, 38273, 38256, 
+    38260,     0, 32768, 36864, 37888, 38144, 38272, 38273, 
+    38256, 38260,     0, 32768, 36864, 37888, 38144, 38272, 
+    38273, 38256, 38264, 38262,     0, 32768, 36864, 37888, 
+    38144, 38272, 38273, 38256,     0, 32768, 36864, 37888, 
+    38144, 38272, 38273, 38256, 38264,     0, 32768, 36864, 
+    37888, 38144, 38272, 38273, 38275, 38264,     0, 32768, 
+    36864, 37888, 38144, 38272, 38273, 38275, 38264, 38266, 
+        0, 32768, 36864, 37888, 38144, 38272, 38273, 38275, 
+    38264,     0, 32768, 36864, 37888, 38144, 38272, 38273, 
+    38275, 38264, 38268,     0, 32768, 36864, 37888, 38144, 
+    38272, 38273, 38275, 38264, 38268,     0, 32768, 36864, 
+    37888, 38144, 38272, 38273, 38275, 38264, 38268, 38270, 
+        0, 32768, 36864, 37888, 38144,     0, 32768, 36864, 
+    37888, 38400, 38272,     0, 32768, 36864, 37888, 38400, 
+    38272,     0, 32768, 36864, 37888, 38400, 38272, 38274, 
+        0, 32768, 36864, 37888, 38400, 38272,     0, 32768, 
+    36864, 37888, 38400, 38272, 38276,     0, 32768, 36864, 
+    37888, 38400, 38272, 38276,     0, 32768, 36864, 37888, 
+    38400, 38272, 38280, 38278,     0, 32768, 36864, 37888, 
+    38400, 38272,     0, 32768, 36864, 37888, 38400, 38272, 
+    38280,     0, 32768, 36864, 37888, 38400, 38272, 38280, 
+        0, 32768, 36864, 37888, 38400, 38272, 38280, 38282, 
+        0, 32768, 36864, 37888, 38400, 38272, 38280,     0, 
+    32768, 36864, 37888, 38400, 38272, 38288, 38284,     0, 
+    32768, 36864, 37888, 38400, 38272, 38288, 38284,     0, 
+    32768, 36864, 37888, 38400, 38272, 38288, 38289, 38286, 
+        0, 32768, 36864, 37888, 38400, 38272,     0, 32768, 
+    36864, 37888, 38400, 38272, 38288,     0, 32768, 36864, 
+    37888, 38400, 38272, 38288,     0, 32768, 36864, 37888, 
+    38400, 38272, 38288, 38290,     0, 32768, 36864, 37888, 
+    38400, 38272, 38288,     0, 32768, 36864, 37888, 38400, 
+    38272, 38288, 38292,     0, 32768, 36864, 37888, 38400, 
+    38272, 38288, 38292,     0, 32768, 36864, 37888, 38400, 
+    38272, 38288, 38296, 38294,     0, 32768, 36864, 37888, 
+    38400, 38272, 38288,     0, 32768, 36864, 37888, 38400, 
+    38272, 38304, 38296,     0, 32768, 36864, 37888, 38400, 
+    38272, 38304, 38296,     0, 32768, 36864, 37888, 38400, 
+    38272, 38304, 38296, 38298,     0, 32768, 36864, 37888, 
+    38400, 38272, 38304, 38296,     0, 32768, 36864, 37888, 
+    38400, 38272, 38304, 38305, 38300,     0, 32768, 36864, 
+    37888, 38400, 38272, 38304, 38305, 38300,     0, 32768, 
+    36864, 37888, 38400, 38272, 38304, 38305, 38300, 38302, 
+        0, 32768, 36864, 37888, 38400, 38272,     0, 32768, 
+    36864, 37888, 38400, 38272, 38304,     0, 32768, 36864, 
+    37888, 38400, 38272, 38304,     0, 32768, 36864, 37888, 
+    38400, 38272, 38304, 38306,     0, 32768, 36864, 37888, 
+    38400, 38272, 38304,     0, 32768, 36864, 37888, 38400, 
+    38272, 38304, 38308,     0, 32768, 36864, 37888, 38400, 
+    38272, 38304, 38308,     0, 32768, 36864, 37888, 38400, 
+    38272, 38304, 38312, 38310,     0, 32768, 36864, 37888, 
+    38400, 38272, 38304,     0, 32768, 36864, 37888, 38400, 
+    38272, 38304, 38312,     0, 32768, 36864, 37888, 38400, 
+    38272, 38304, 38312,     0, 32768, 36864, 37888, 38400, 
+    38272, 38304, 38312, 38314,     0, 32768, 36864, 37888, 
+    38400, 38272, 38304, 38312,     0, 32768, 36864, 37888, 
+    38400, 38272, 38304, 38320, 38316,     0, 32768, 36864, 
+    37888, 38400, 38272, 38304, 38320, 38316,     0, 32768, 
+    36864, 37888, 38400, 38272, 38304, 38320, 38321, 38318, 
+        0, 32768, 36864, 37888, 38400, 38272, 38304,     0, 
+    32768, 36864, 37888, 38400, 38272, 38336, 38320,     0, 
+    32768, 36864, 37888, 38400, 38272, 38336, 38320,     0, 
+    32768, 36864, 37888, 38400, 38272, 38336, 38320, 38322, 
+        0, 32768, 36864, 37888, 38400, 38272, 38336, 38320, 
+        0, 32768, 36864, 37888, 38400, 38272, 38336, 38320, 
+    38324,     0, 32768, 36864, 37888, 38400, 38272, 38336, 
+    38320, 38324,     0, 32768, 36864, 37888, 38400, 38272, 
+    38336, 38320, 38328, 38326,     0, 32768, 36864, 37888, 
+    38400, 38272, 38336, 38320,     0, 32768, 36864, 37888, 
+    38400, 38272, 38336, 38337, 38328,     0, 32768, 36864, 
+    37888, 38400, 38272, 38336, 38337, 38328,     0, 32768, 
+    36864, 37888, 38400, 38272, 38336, 38337, 38328, 38330, 
+        0, 32768, 36864, 37888, 38400, 38272, 38336, 38337, 
+    38328,     0, 32768, 36864, 37888, 38400, 38272, 38336, 
+    38337, 38328, 38332,     0, 32768, 36864, 37888, 38400, 
+    38272, 38336, 38337, 38339, 38332,     0, 32768, 36864, 
+    37888, 38400, 38272, 38336, 38337, 38339, 38332, 38334, 
+        0, 32768, 36864, 37888, 38400, 38272,     0, 32768, 
+    36864, 37888, 38400, 38401, 38336,     0, 32768, 36864, 
+    37888, 38400, 38401, 38336,     0, 32768, 36864, 37888, 
+    38400, 38401, 38336, 38338,     0, 32768, 36864, 37888, 
+    38400, 38401, 38336,     0, 32768, 36864, 37888, 38400, 
+    38401, 38336, 38340,     0, 32768, 36864, 37888, 38400, 
+    38401, 38336, 38340,     0, 32768, 36864, 37888, 38400, 
+    38401, 38336, 38344, 38342,     0, 32768, 36864, 37888, 
+    38400, 38401, 38336,     0, 32768, 36864, 37888, 38400, 
+    38401, 38336, 38344,     0, 32768, 36864, 37888, 38400, 
+    38401, 38336, 38344,     0, 32768, 36864, 37888, 38400, 
+    38401, 38336, 38344, 38346,     0, 32768, 36864, 37888, 
+    38400, 38401, 38336, 38344,     0, 32768, 36864, 37888, 
+    38400, 38401, 38336, 38352, 38348,     0, 32768, 36864, 
+    37888, 38400, 38401, 38336, 38352, 38348,     0, 32768, 
+    36864, 37888, 38400, 38401, 38336, 38352, 38353, 38350, 
+        0, 32768, 36864, 37888, 38400, 38401, 38336,     0, 
+    32768, 36864, 37888, 38400, 38401, 38336, 38352,     0, 
+    32768, 36864, 37888, 38400, 38401, 38336, 38352,     0, 
+    32768, 36864, 37888, 38400, 38401, 38336, 38352, 38354, 
+        0, 32768, 36864, 37888, 38400, 38401, 38336, 38352, 
+        0, 32768, 36864, 37888, 38400, 38401, 38336, 38352, 
+    38356,     0, 32768, 36864, 37888, 38400, 38401, 38336, 
+    38352, 38356,     0, 32768, 36864, 37888, 38400, 38401, 
+    38336, 38352, 38360, 38358,     0, 32768, 36864, 37888, 
+    38400, 38401, 38336, 38352,     0, 32768, 36864, 37888, 
+    38400, 38401, 38336, 38368, 38360,     0, 32768, 36864, 
+    37888, 38400, 38401, 38336, 38368, 38360,     0, 32768, 
+    36864, 37888, 38400, 38401, 38336, 38368, 38360, 38362, 
+        0, 32768, 36864, 37888, 38400, 38401, 38336, 38368, 
+    38360,     0, 32768, 36864, 37888, 38400, 38401, 38336, 
+    38368, 38369, 38364,     0, 32768, 36864, 37888, 38400, 
+    38401, 38336, 38368, 38369, 38364,     0, 32768, 36864, 
+    37888, 38400, 38401, 38336, 38368, 38369, 38364, 38366, 
+        0, 32768, 36864, 37888, 38400, 38401, 38336,     0, 
+    32768, 36864, 37888, 38400, 38401, 38336, 38368,     0, 
+    32768, 36864, 37888, 38400, 38401, 38403, 38368,     0, 
+    32768, 36864, 37888, 38400, 38401, 38403, 38368, 38370, 
+        0, 32768, 36864, 37888, 38400, 38401, 38403, 38368, 
+        0, 32768, 36864, 37888, 38400, 38401, 38403, 38368, 
+    38372,     0, 32768, 36864, 37888, 38400, 38401, 38403, 
+    38368, 38372,     0, 32768, 36864, 37888, 38400, 38401, 
+    38403, 38368, 38376, 38374,     0, 32768, 36864, 37888, 
+    38400, 38401, 38403, 38368,     0, 32768, 36864, 37888, 
+    38400, 38401, 38403, 38368, 38376,     0, 32768, 36864, 
+    37888, 38400, 38401, 38403, 38368, 38376,     0, 32768, 
+    36864, 37888, 38400, 38401, 38403, 38368, 38376, 38378, 
+        0, 32768, 36864, 37888, 38400, 38401, 38403, 38368, 
+    38376,     0, 32768, 36864, 37888, 38400, 38401, 38403, 
+    38368, 38384, 38380,     0, 32768, 36864, 37888, 38400, 
+    38401, 38403, 38368, 38384, 38380,     0, 32768, 36864, 
+    37888, 38400, 38401, 38403, 38368, 38384, 38385, 38382, 
+        0, 32768, 36864, 37888, 38400, 38401, 38403, 38368, 
+        0, 32768, 36864, 37888, 38400, 38401, 38403, 38368, 
+    38384,     0, 32768, 36864, 37888, 38400, 38401, 38403, 
+    38368, 38384,     0, 32768, 36864, 37888, 38400, 38401, 
+    38403, 38368, 38384, 38386,     0, 32768, 36864, 37888, 
+    38400, 38401, 38403, 38407, 38384,     0, 32768, 36864, 
+    37888, 38400, 38401, 38403, 38407, 38384, 38388,     0, 
+    32768, 36864, 37888, 38400, 38401, 38403, 38407, 38384, 
+    38388,     0, 32768, 36864, 37888, 38400, 38401, 38403, 
+    38407, 38384, 38392, 38390,     0, 32768, 36864, 37888, 
+    38400, 38401, 38403, 38407, 38384,     0, 32768, 36864, 
+    37888, 38400, 38401, 38403, 38407, 38384, 38392,     0, 
+    32768, 36864, 37888, 38400, 38401, 38403, 38407, 38384, 
+    38392,     0, 32768, 36864, 37888, 38400, 38401, 38403, 
+    38407, 38384, 38392, 38394,     0, 32768, 36864, 37888, 
+    38400, 38401, 38403, 38407, 38384, 38392,     0, 32768, 
+    36864, 37888, 38400, 38401, 38403, 38407, 38384, 38392, 
+    38396,     0, 32768, 36864, 37888, 38400, 38401, 38403, 
+    38407, 38384, 38392, 38396,     0, 32768, 36864, 37888, 
+    38400, 38401, 38403, 38407, 38384, 38392, 38396, 38398, 
+        0, 32768, 36864, 37888,     0, 32768, 36864, 38912, 
+    38400,     0, 32768, 36864, 38912, 38400,     0, 32768, 
+    36864, 38912, 38400, 38402,     0, 32768, 36864, 38912, 
+    38400,     0, 32768, 36864, 38912, 38400, 38404,     0, 
+    32768, 36864, 38912, 38400, 38404,     0, 32768, 36864, 
+    38912, 38400, 38408, 38406,     0, 32768, 36864, 38912, 
+    38400,     0, 32768, 36864, 38912, 38400, 38408,     0, 
+    32768, 36864, 38912, 38400, 38408,     0, 32768, 36864, 
+    38912, 38400, 38408, 38410,     0, 32768, 36864, 38912, 
+    38400, 38408,     0, 32768, 36864, 38912, 38400, 38416, 
+    38412,     0, 32768, 36864, 38912, 38400, 38416, 38412, 
+        0, 32768, 36864, 38912, 38400, 38416, 38417, 38414, 
+        0, 32768, 36864, 38912, 38400,     0, 32768, 36864, 
+    38912, 38400, 38416,     0, 32768, 36864, 38912, 38400, 
+    38416,     0, 32768, 36864, 38912, 38400, 38416, 38418, 
+        0, 32768, 36864, 38912, 38400, 38416,     0, 32768, 
+    36864, 38912, 38400, 38416, 38420,     0, 32768, 36864, 
+    38912, 38400, 38416, 38420,     0, 32768, 36864, 38912, 
+    38400, 38416, 38424, 38422,     0, 32768, 36864, 38912, 
+    38400, 38416,     0, 32768, 36864, 38912, 38400, 38432, 
+    38424,     0, 32768, 36864, 38912, 38400, 38432, 38424, 
+        0, 32768, 36864, 38912, 38400, 38432, 38424, 38426, 
+        0, 32768, 36864, 38912, 38400, 38432, 38424,     0, 
+    32768, 36864, 38912, 38400, 38432, 38433, 38428,     0, 
+    32768, 36864, 38912, 38400, 38432, 38433, 38428,     0, 
+    32768, 36864, 38912, 38400, 38432, 38433, 38428, 38430, 
+        0, 32768, 36864, 38912, 38400,     0, 32768, 36864, 
+    38912, 38400, 38432,     0, 32768, 36864, 38912, 38400, 
+    38432,     0, 32768, 36864, 38912, 38400, 38432, 38434, 
+        0, 32768, 36864, 38912, 38400, 38432,     0, 32768, 
+    36864, 38912, 38400, 38432, 38436,     0, 32768, 36864, 
+    38912, 38400, 38432, 38436,     0, 32768, 36864, 38912, 
+    38400, 38432, 38440, 38438,     0, 32768, 36864, 38912, 
+    38400, 38432,     0, 32768, 36864, 38912, 38400, 38432, 
+    38440,     0, 32768, 36864, 38912, 38400, 38432, 38440, 
+        0, 32768, 36864, 38912, 38400, 38432, 38440, 38442, 
+        0, 32768, 36864, 38912, 38400, 38432, 38440,     0, 
+    32768, 36864, 38912, 38400, 38432, 38448, 38444,     0, 
+    32768, 36864, 38912, 38400, 38432, 38448, 38444,     0, 
+    32768, 36864, 38912, 38400, 38432, 38448, 38449, 38446, 
+        0, 32768, 36864, 38912, 38400, 38432,     0, 32768, 
+    36864, 38912, 38400, 38464, 38448,     0, 32768, 36864, 
+    38912, 38400, 38464, 38448,     0, 32768, 36864, 38912, 
+    38400, 38464, 38448, 38450,     0, 32768, 36864, 38912, 
+    38400, 38464, 38448,     0, 32768, 36864, 38912, 38400, 
+    38464, 38448, 38452,     0, 32768, 36864, 38912, 38400, 
+    38464, 38448, 38452,     0, 32768, 36864, 38912, 38400, 
+    38464, 38448, 38456, 38454,     0, 32768, 36864, 38912, 
+    38400, 38464, 38448,     0, 32768, 36864, 38912, 38400, 
+    38464, 38465, 38456,     0, 32768, 36864, 38912, 38400, 
+    38464, 38465, 38456,     0, 32768, 36864, 38912, 38400, 
+    38464, 38465, 38456, 38458,     0, 32768, 36864, 38912, 
+    38400, 38464, 38465, 38456,     0, 32768, 36864, 38912, 
+    38400, 38464, 38465, 38456, 38460,     0, 32768, 36864, 
+    38912, 38400, 38464, 38465, 38467, 38460,     0, 32768, 
+    36864, 38912, 38400, 38464, 38465, 38467, 38460, 38462, 
+        0, 32768, 36864, 38912, 38400,     0, 32768, 36864, 
+    38912, 38400, 38464,     0, 32768, 36864, 38912, 38400, 
+    38464,     0, 32768, 36864, 38912, 38400, 38464, 38466, 
+        0, 32768, 36864, 38912, 38400, 38464,     0, 32768, 
+    36864, 38912, 38400, 38464, 38468,     0, 32768, 36864, 
+    38912, 38400, 38464, 38468,     0, 32768, 36864, 38912, 
+    38400, 38464, 38472, 38470,     0, 32768, 36864, 38912, 
+    38400, 38464,     0, 32768, 36864, 38912, 38400, 38464, 
+    38472,     0, 32768, 36864, 38912, 38400, 38464, 38472, 
+        0, 32768, 36864, 38912, 38400, 38464, 38472, 38474, 
+        0, 32768, 36864, 38912, 38400, 38464, 38472,     0, 
+    32768, 36864, 38912, 38400, 38464, 38480, 38476,     0, 
+    32768, 36864, 38912, 38400, 38464, 38480, 38476,     0, 
+    32768, 36864, 38912, 38400, 38464, 38480, 38481, 38478, 
+        0, 32768, 36864, 38912, 38400, 38464,     0, 32768, 
+    36864, 38912, 38400, 38464, 38480,     0, 32768, 36864, 
+    38912, 38400, 38464, 38480,     0, 32768, 36864, 38912, 
+    38400, 38464, 38480, 38482,     0, 32768, 36864, 38912, 
+    38400, 38464, 38480,     0, 32768, 36864, 38912, 38400, 
+    38464, 38480, 38484,     0, 32768, 36864, 38912, 38400, 
+    38464, 38480, 38484,     0, 32768, 36864, 38912, 38400, 
+    38464, 38480, 38488, 38486,     0, 32768, 36864, 38912, 
+    38400, 38464, 38480,     0, 32768, 36864, 38912, 38400, 
+    38464, 38496, 38488,     0, 32768, 36864, 38912, 38400, 
+    38464, 38496, 38488,     0, 32768, 36864, 38912, 38400, 
+    38464, 38496, 38488, 38490,     0, 32768, 36864, 38912, 
+    38400, 38464, 38496, 38488,     0, 32768, 36864, 38912, 
+    38400, 38464, 38496, 38497, 38492,     0, 32768, 36864, 
+    38912, 38400, 38464, 38496, 38497, 38492,     0, 32768, 
+    36864, 38912, 38400, 38464, 38496, 38497, 38492, 38494, 
+        0, 32768, 36864, 38912, 38400, 38464,     0, 32768, 
+    36864, 38912, 38400, 38528, 38496,     0, 32768, 36864, 
+    38912, 38400, 38528, 38496,     0, 32768, 36864, 38912, 
+    38400, 38528, 38496, 38498,     0, 32768, 36864, 38912, 
+    38400, 38528, 38496,     0, 32768, 36864, 38912, 38400, 
+    38528, 38496, 38500,     0, 32768, 36864, 38912, 38400, 
+    38528, 38496, 38500,     0, 32768, 36864, 38912, 38400, 
+    38528, 38496, 38504, 38502,     0, 32768, 36864, 38912, 
+    38400, 38528, 38496,     0, 32768, 36864, 38912, 38400, 
+    38528, 38496, 38504,     0, 32768, 36864, 38912, 38400, 
+    38528, 38496, 38504,     0, 32768, 36864, 38912, 38400, 
+    38528, 38496, 38504, 38506,     0, 32768, 36864, 38912, 
+    38400, 38528, 38496, 38504,     0, 32768, 36864, 38912, 
+    38400, 38528, 38496, 38512, 38508,     0, 32768, 36864, 
+    38912, 38400, 38528, 38496, 38512, 38508,     0, 32768, 
+    36864, 38912, 38400, 38528, 38496, 38512, 38513, 38510, 
+        0, 32768, 36864, 38912, 38400, 38528, 38496,     0, 
+    32768, 36864, 38912, 38400, 38528, 38529, 38512,     0, 
+    32768, 36864, 38912, 38400, 38528, 38529, 38512,     0, 
+    32768, 36864, 38912, 38400, 38528, 38529, 38512, 38514, 
+        0, 32768, 36864, 38912, 38400, 38528, 38529, 38512, 
+        0, 32768, 36864, 38912, 38400, 38528, 38529, 38512, 
+    38516,     0, 32768, 36864, 38912, 38400, 38528, 38529, 
+    38512, 38516,     0, 32768, 36864, 38912, 38400, 38528, 
+    38529, 38512, 38520, 38518,     0, 32768, 36864, 38912, 
+    38400, 38528, 38529, 38512,     0, 32768, 36864, 38912, 
+    38400, 38528, 38529, 38512, 38520,     0, 32768, 36864, 
+    38912, 38400, 38528, 38529, 38531, 38520,     0, 32768, 
+    36864, 38912, 38400, 38528, 38529, 38531, 38520, 38522, 
+        0, 32768, 36864, 38912, 38400, 38528, 38529, 38531, 
+    38520,     0, 32768, 36864, 38912, 38400, 38528, 38529, 
+    38531, 38520, 38524,     0, 32768, 36864, 38912, 38400, 
+    38528, 38529, 38531, 38520, 38524,     0, 32768, 36864, 
+    38912, 38400, 38528, 38529, 38531, 38520, 38524, 38526, 
+        0, 32768, 36864, 38912, 38400,     0, 32768, 36864, 
+    38912, 38400, 38528,     0, 32768, 36864, 38912, 38400, 
+    38528,     0, 32768, 36864, 38912, 38400, 38528, 38530, 
+        0, 32768, 36864, 38912, 38400, 38528,     0, 32768, 
+    36864, 38912, 38400, 38528, 38532,     0, 32768, 36864, 
+    38912, 38400, 38528, 38532,     0, 32768, 36864, 38912, 
+    38400, 38528, 38536, 38534,     0, 32768, 36864, 38912, 
+    38400, 38528,     0, 32768, 36864, 38912, 38400, 38528, 
+    38536,     0, 32768, 36864, 38912, 38400, 38528, 38536, 
+        0, 32768, 36864, 38912, 38400, 38528, 38536, 38538, 
+        0, 32768, 36864, 38912, 38400, 38528, 38536,     0, 
+    32768, 36864, 38912, 38400, 38528, 38544, 38540,     0, 
+    32768, 36864, 38912, 38400, 38528, 38544, 38540,     0, 
+    32768, 36864, 38912, 38400, 38528, 38544, 38545, 38542, 
+        0, 32768, 36864, 38912, 38400, 38528,     0, 32768, 
+    36864, 38912, 38400, 38528, 38544,     0, 32768, 36864, 
+    38912, 38400, 38528, 38544,     0, 32768, 36864, 38912, 
+    38400, 38528, 38544, 38546,     0, 32768, 36864, 38912, 
+    38400, 38528, 38544,     0, 32768, 36864, 38912, 38400, 
+    38528, 38544, 38548,     0, 32768, 36864, 38912, 38400, 
+    38528, 38544, 38548,     0, 32768, 36864, 38912, 38400, 
+    38528, 38544, 38552, 38550,     0, 32768, 36864, 38912, 
+    38400, 38528, 38544,     0, 32768, 36864, 38912, 38400, 
+    38528, 38560, 38552,     0, 32768, 36864, 38912, 38400, 
+    38528, 38560, 38552,     0, 32768, 36864, 38912, 38400, 
+    38528, 38560, 38552, 38554,     0, 32768, 36864, 38912, 
+    38400, 38528, 38560, 38552,     0, 32768, 36864, 38912, 
+    38400, 38528, 38560, 38561, 38556,     0, 32768, 36864, 
+    38912, 38400, 38528, 38560, 38561, 38556,     0, 32768, 
+    36864, 38912, 38400, 38528, 38560, 38561, 38556, 38558, 
+        0, 32768, 36864, 38912, 38400, 38528,     0, 32768, 
+    36864, 38912, 38400, 38528, 38560,     0, 32768, 36864, 
+    38912, 38400, 38528, 38560,     0, 32768, 36864, 38912, 
+    38400, 38528, 38560, 38562,     0, 32768, 36864, 38912, 
+    38400, 38528, 38560,     0, 32768, 36864, 38912, 38400, 
+    38528, 38560, 38564,     0, 32768, 36864, 38912, 38400, 
+    38528, 38560, 38564,     0, 32768, 36864, 38912, 38400, 
+    38528, 38560, 38568, 38566,     0, 32768, 36864, 38912, 
+    38400, 38528, 38560,     0, 32768, 36864, 38912, 38400, 
+    38528, 38560, 38568,     0, 32768, 36864, 38912, 38400, 
+    38528, 38560, 38568,     0, 32768, 36864, 38912, 38400, 
+    38528, 38560, 38568, 38570,     0, 32768, 36864, 38912, 
+    38400, 38528, 38560, 38568,     0, 32768, 36864, 38912, 
+    38400, 38528, 38560, 38576, 38572,     0, 32768, 36864, 
+    38912, 38400, 38528, 38560, 38576, 38572,     0, 32768, 
+    36864, 38912, 38400, 38528, 38560, 38576, 38577, 38574, 
+        0, 32768, 36864, 38912, 38400, 38528, 38560,     0, 
+    32768, 36864, 38912, 38400, 38528, 38592, 38576,     0, 
+    32768, 36864, 38912, 38400, 38528, 38592, 38576,     0, 
+    32768, 36864, 38912, 38400, 38528, 38592, 38576, 38578, 
+        0, 32768, 36864, 38912, 38400, 38528, 38592, 38576, 
+        0, 32768, 36864, 38912, 38400, 38528, 38592, 38576, 
+    38580,     0, 32768, 36864, 38912, 38400, 38528, 38592, 
+    38576, 38580,     0, 32768, 36864, 38912, 38400, 38528, 
+    38592, 38576, 38584, 38582,     0, 32768, 36864, 38912, 
+    38400, 38528, 38592, 38576,     0, 32768, 36864, 38912, 
+    38400, 38528, 38592, 38593, 38584,     0, 32768, 36864, 
+    38912, 38400, 38528, 38592, 38593, 38584,     0, 32768, 
+    36864, 38912, 38400, 38528, 38592, 38593, 38584, 38586, 
+        0, 32768, 36864, 38912, 38400, 38528, 38592, 38593, 
+    38584,     0, 32768, 36864, 38912, 38400, 38528, 38592, 
+    38593, 38584, 38588,     0, 32768, 36864, 38912, 38400, 
+    38528, 38592, 38593, 38595, 38588,     0, 32768, 36864, 
+    38912, 38400, 38528, 38592, 38593, 38595, 38588, 38590, 
+        0, 32768, 36864, 38912, 38400, 38528,     0, 32768, 
+    36864, 38912, 38400, 38656, 38592,     0, 32768, 36864, 
+    38912, 38400, 38656, 38592,     0, 32768, 36864, 38912, 
+    38400, 38656, 38592, 38594,     0, 32768, 36864, 38912, 
+    38400, 38656, 38592,     0, 32768, 36864, 38912, 38400, 
+    38656, 38592, 38596,     0, 32768, 36864, 38912, 38400, 
+    38656, 38592, 38596,     0, 32768, 36864, 38912, 38400, 
+    38656, 38592, 38600, 38598,     0, 32768, 36864, 38912, 
+    38400, 38656, 38592,     0, 32768, 36864, 38912, 38400, 
+    38656, 38592, 38600,     0, 32768, 36864, 38912, 38400, 
+    38656, 38592, 38600,     0, 32768, 36864, 38912, 38400, 
+    38656, 38592, 38600, 38602,     0, 32768, 36864, 38912, 
+    38400, 38656, 38592, 38600,     0, 32768, 36864, 38912, 
+    38400, 38656, 38592, 38608, 38604,     0, 32768, 36864, 
+    38912, 38400, 38656, 38592, 38608, 38604,     0, 32768, 
+    36864, 38912, 38400, 38656, 38592, 38608, 38609, 38606, 
+        0, 32768, 36864, 38912, 38400, 38656, 38592,     0, 
+    32768, 36864, 38912, 38400, 38656, 38592, 38608,     0, 
+    32768, 36864, 38912, 38400, 38656, 38592, 38608,     0, 
+    32768, 36864, 38912, 38400, 38656, 38592, 38608, 38610, 
+        0, 32768, 36864, 38912, 38400, 38656, 38592, 38608, 
+        0, 32768, 36864, 38912, 38400, 38656, 38592, 38608, 
+    38612,     0, 32768, 36864, 38912, 38400, 38656, 38592, 
+    38608, 38612,     0, 32768, 36864, 38912, 38400, 38656, 
+    38592, 38608, 38616, 38614,     0, 32768, 36864, 38912, 
+    38400, 38656, 38592, 38608,     0, 32768, 36864, 38912, 
+    38400, 38656, 38592, 38624, 38616,     0, 32768, 36864, 
+    38912, 38400, 38656, 38592, 38624, 38616,     0, 32768, 
+    36864, 38912, 38400, 38656, 38592, 38624, 38616, 38618, 
+        0, 32768, 36864, 38912, 38400, 38656, 38592, 38624, 
+    38616,     0, 32768, 36864, 38912, 38400, 38656, 38592, 
+    38624, 38625, 38620,     0, 32768, 36864, 38912, 38400, 
+    38656, 38592, 38624, 38625, 38620,     0, 32768, 36864, 
+    38912, 38400, 38656, 38592, 38624, 38625, 38620, 38622, 
+        0, 32768, 36864, 38912, 38400, 38656, 38592,     0, 
+    32768, 36864, 38912, 38400, 38656, 38657, 38624,     0, 
+    32768, 36864, 38912, 38400, 38656, 38657, 38624,     0, 
+    32768, 36864, 38912, 38400, 38656, 38657, 38624, 38626, 
+        0, 32768, 36864, 38912, 38400, 38656, 38657, 38624, 
+        0, 32768, 36864, 38912, 38400, 38656, 38657, 38624, 
+    38628,     0, 32768, 36864, 38912, 38400, 38656, 38657, 
+    38624, 38628,     0, 32768, 36864, 38912, 38400, 38656, 
+    38657, 38624, 38632, 38630,     0, 32768, 36864, 38912, 
+    38400, 38656, 38657, 38624,     0, 32768, 36864, 38912, 
+    38400, 38656, 38657, 38624, 38632,     0, 32768, 36864, 
+    38912, 38400, 38656, 38657, 38624, 38632,     0, 32768, 
+    36864, 38912, 38400, 38656, 38657, 38624, 38632, 38634, 
+        0, 32768, 36864, 38912, 38400, 38656, 38657, 38624, 
+    38632,     0, 32768, 36864, 38912, 38400, 38656, 38657, 
+    38624, 38640, 38636,     0, 32768, 36864, 38912, 38400, 
+    38656, 38657, 38624, 38640, 38636,     0, 32768, 36864, 
+    38912, 38400, 38656, 38657, 38624, 38640, 38641, 38638, 
+        0, 32768, 36864, 38912, 38400, 38656, 38657, 38624, 
+        0, 32768, 36864, 38912, 38400, 38656, 38657, 38624, 
+    38640,     0, 32768, 36864, 38912, 38400, 38656, 38657, 
+    38659, 38640,     0, 32768, 36864, 38912, 38400, 38656, 
+    38657, 38659, 38640, 38642,     0, 32768, 36864, 38912, 
+    38400, 38656, 38657, 38659, 38640,     0, 32768, 36864, 
+    38912, 38400, 38656, 38657, 38659, 38640, 38644,     0, 
+    32768, 36864, 38912, 38400, 38656, 38657, 38659, 38640, 
+    38644,     0, 32768, 36864, 38912, 38400, 38656, 38657, 
+    38659, 38640, 38648, 38646,     0, 32768, 36864, 38912, 
+    38400, 38656, 38657, 38659, 38640,     0, 32768, 36864, 
+    38912, 38400, 38656, 38657, 38659, 38640, 38648,     0, 
+    32768, 36864, 38912, 38400, 38656, 38657, 38659, 38640, 
+    38648,     0, 32768, 36864, 38912, 38400, 38656, 38657, 
+    38659, 38640, 38648, 38650,     0, 32768, 36864, 38912, 
+    38400, 38656, 38657, 38659, 38663, 38648,     0, 32768, 
+    36864, 38912, 38400, 38656, 38657, 38659, 38663, 38648, 
+    38652,     0, 32768, 36864, 38912, 38400, 38656, 38657, 
+    38659, 38663, 38648, 38652,     0, 32768, 36864, 38912, 
+    38400, 38656, 38657, 38659, 38663, 38648, 38652, 38654, 
+        0, 32768, 36864, 38912, 38400,     0, 32768, 36864, 
+    38912, 38400, 38656,     0, 32768, 36864, 38912, 38913, 
+    38656,     0, 32768, 36864, 38912, 38913, 38656, 38658, 
+        0, 32768, 36864, 38912, 38913, 38656,     0, 32768, 
+    36864, 38912, 38913, 38656, 38660,     0, 32768, 36864, 
+    38912, 38913, 38656, 38660,     0, 32768, 36864, 38912, 
+    38913, 38656, 38664, 38662,     0, 32768, 36864, 38912, 
+    38913, 38656,     0, 32768, 36864, 38912, 38913, 38656, 
+    38664,     0, 32768, 36864, 38912, 38913, 38656, 38664, 
+        0, 32768, 36864, 38912, 38913, 38656, 38664, 38666, 
+        0, 32768, 36864, 38912, 38913, 38656, 38664,     0, 
+    32768, 36864, 38912, 38913, 38656, 38672, 38668,     0, 
+    32768, 36864, 38912, 38913, 38656, 38672, 38668,     0, 
+    32768, 36864, 38912, 38913, 38656, 38672, 38673, 38670, 
+        0, 32768, 36864, 38912, 38913, 38656,     0, 32768, 
+    36864, 38912, 38913, 38656, 38672,     0, 32768, 36864, 
+    38912, 38913, 38656, 38672,     0, 32768, 36864, 38912, 
+    38913, 38656, 38672, 38674,     0, 32768, 36864, 38912, 
+    38913, 38656, 38672,     0, 32768, 36864, 38912, 38913, 
+    38656, 38672, 38676,     0, 32768, 36864, 38912, 38913, 
+    38656, 38672, 38676,     0, 32768, 36864, 38912, 38913, 
+    38656, 38672, 38680, 38678,     0, 32768, 36864, 38912, 
+    38913, 38656, 38672,     0, 32768, 36864, 38912, 38913, 
+    38656, 38688, 38680,     0, 32768, 36864, 38912, 38913, 
+    38656, 38688, 38680,     0, 32768, 36864, 38912, 38913, 
+    38656, 38688, 38680, 38682,     0, 32768, 36864, 38912, 
+    38913, 38656, 38688, 38680,     0, 32768, 36864, 38912, 
+    38913, 38656, 38688, 38689, 38684,     0, 32768, 36864, 
+    38912, 38913, 38656, 38688, 38689, 38684,     0, 32768, 
+    36864, 38912, 38913, 38656, 38688, 38689, 38684, 38686, 
+        0, 32768, 36864, 38912, 38913, 38656,     0, 32768, 
+    36864, 38912, 38913, 38656, 38688,     0, 32768, 36864, 
+    38912, 38913, 38656, 38688,     0, 32768, 36864, 38912, 
+    38913, 38656, 38688, 38690,     0, 32768, 36864, 38912, 
+    38913, 38656, 38688,     0, 32768, 36864, 38912, 38913, 
+    38656, 38688, 38692,     0, 32768, 36864, 38912, 38913, 
+    38656, 38688, 38692,     0, 32768, 36864, 38912, 38913, 
+    38656, 38688, 38696, 38694,     0, 32768, 36864, 38912, 
+    38913, 38656, 38688,     0, 32768, 36864, 38912, 38913, 
+    38656, 38688, 38696,     0, 32768, 36864, 38912, 38913, 
+    38656, 38688, 38696,     0, 32768, 36864, 38912, 38913, 
+    38656, 38688, 38696, 38698,     0, 32768, 36864, 38912, 
+    38913, 38656, 38688, 38696,     0, 32768, 36864, 38912, 
+    38913, 38656, 38688, 38704, 38700,     0, 32768, 36864, 
+    38912, 38913, 38656, 38688, 38704, 38700,     0, 32768, 
+    36864, 38912, 38913, 38656, 38688, 38704, 38705, 38702, 
+        0, 32768, 36864, 38912, 38913, 38656, 38688,     0, 
+    32768, 36864, 38912, 38913, 38656, 38720, 38704,     0, 
+    32768, 36864, 38912, 38913, 38656, 38720, 38704,     0, 
+    32768, 36864, 38912, 38913, 38656, 38720, 38704, 38706, 
+        0, 32768, 36864, 38912, 38913, 38656, 38720, 38704, 
+        0, 32768, 36864, 38912, 38913, 38656, 38720, 38704, 
+    38708,     0, 32768, 36864, 38912, 38913, 38656, 38720, 
+    38704, 38708,     0, 32768, 36864, 38912, 38913, 38656, 
+    38720, 38704, 38712, 38710,     0, 32768, 36864, 38912, 
+    38913, 38656, 38720, 38704,     0, 32768, 36864, 38912, 
+    38913, 38656, 38720, 38721, 38712,     0, 32768, 36864, 
+    38912, 38913, 38656, 38720, 38721, 38712,     0, 32768, 
+    36864, 38912, 38913, 38656, 38720, 38721, 38712, 38714, 
+        0, 32768, 36864, 38912, 38913, 38656, 38720, 38721, 
+    38712,     0, 32768, 36864, 38912, 38913, 38656, 38720, 
+    38721, 38712, 38716,     0, 32768, 36864, 38912, 38913, 
+    38656, 38720, 38721, 38723, 38716,     0, 32768, 36864, 
+    38912, 38913, 38656, 38720, 38721, 38723, 38716, 38718, 
+        0, 32768, 36864, 38912, 38913, 38656,     0, 32768, 
+    36864, 38912, 38913, 38656, 38720,     0, 32768, 36864, 
+    38912, 38913, 38656, 38720,     0, 32768, 36864, 38912, 
+    38913, 38656, 38720, 38722,     0, 32768, 36864, 38912, 
+    38913, 38656, 38720,     0, 32768, 36864, 38912, 38913, 
+    38656, 38720, 38724,     0, 32768, 36864, 38912, 38913, 
+    38656, 38720, 38724,     0, 32768, 36864, 38912, 38913, 
+    38656, 38720, 38728, 38726,     0, 32768, 36864, 38912, 
+    38913, 38656, 38720,     0, 32768, 36864, 38912, 38913, 
+    38656, 38720, 38728,     0, 32768, 36864, 38912, 38913, 
+    38656, 38720, 38728,     0, 32768, 36864, 38912, 38913, 
+    38656, 38720, 38728, 38730,     0, 32768, 36864, 38912, 
+    38913, 38656, 38720, 38728,     0, 32768, 36864, 38912, 
+    38913, 38656, 38720, 38736, 38732,     0, 32768, 36864, 
+    38912, 38913, 38656, 38720, 38736, 38732,     0, 32768, 
+    36864, 38912, 38913, 38656, 38720, 38736, 38737, 38734, 
+        0, 32768, 36864, 38912, 38913, 38656, 38720,     0, 
+    32768, 36864, 38912, 38913, 38656, 38720, 38736,     0, 
+    32768, 36864, 38912, 38913, 38656, 38720, 38736,     0, 
+    32768, 36864, 38912, 38913, 38656, 38720, 38736, 38738, 
+        0, 32768, 36864, 38912, 38913, 38656, 38720, 38736, 
+        0, 32768, 36864, 38912, 38913, 38656, 38720, 38736, 
+    38740,     0, 32768, 36864, 38912, 38913, 38656, 38720, 
+    38736, 38740,     0, 32768, 36864, 38912, 38913, 38656, 
+    38720, 38736, 38744, 38742,     0, 32768, 36864, 38912, 
+    38913, 38656, 38720, 38736,     0, 32768, 36864, 38912, 
+    38913, 38656, 38720, 38752, 38744,     0, 32768, 36864, 
+    38912, 38913, 38656, 38720, 38752, 38744,     0, 32768, 
+    36864, 38912, 38913, 38656, 38720, 38752, 38744, 38746, 
+        0, 32768, 36864, 38912, 38913, 38656, 38720, 38752, 
+    38744,     0, 32768, 36864, 38912, 38913, 38656, 38720, 
+    38752, 38753, 38748,     0, 32768, 36864, 38912, 38913, 
+    38656, 38720, 38752, 38753, 38748,     0, 32768, 36864, 
+    38912, 38913, 38656, 38720, 38752, 38753, 38748, 38750, 
+        0, 32768, 36864, 38912, 38913, 38656, 38720,     0, 
+    32768, 36864, 38912, 38913, 38656, 38784, 38752,     0, 
+    32768, 36864, 38912, 38913, 38656, 38784, 38752,     0, 
+    32768, 36864, 38912, 38913, 38656, 38784, 38752, 38754, 
+        0, 32768, 36864, 38912, 38913, 38656, 38784, 38752, 
+        0, 32768, 36864, 38912, 38913, 38656, 38784, 38752, 
+    38756,     0, 32768, 36864, 38912, 38913, 38656, 38784, 
+    38752, 38756,     0, 32768, 36864, 38912, 38913, 38656, 
+    38784, 38752, 38760, 38758,     0, 32768, 36864, 38912, 
+    38913, 38656, 38784, 38752,     0, 32768, 36864, 38912, 
+    38913, 38656, 38784, 38752, 38760,     0, 32768, 36864, 
+    38912, 38913, 38656, 38784, 38752, 38760,     0, 32768, 
+    36864, 38912, 38913, 38656, 38784, 38752, 38760, 38762, 
+        0, 32768, 36864, 38912, 38913, 38656, 38784, 38752, 
+    38760,     0, 32768, 36864, 38912, 38913, 38656, 38784, 
+    38752, 38768, 38764,     0, 32768, 36864, 38912, 38913, 
+    38656, 38784, 38752, 38768, 38764,     0, 32768, 36864, 
+    38912, 38913, 38656, 38784, 38752, 38768, 38769, 38766, 
+        0, 32768, 36864, 38912, 38913, 38656, 38784, 38752, 
+        0, 32768, 36864, 38912, 38913, 38656, 38784, 38785, 
+    38768,     0, 32768, 36864, 38912, 38913, 38656, 38784, 
+    38785, 38768,     0, 32768, 36864, 38912, 38913, 38656, 
+    38784, 38785, 38768, 38770,     0, 32768, 36864, 38912, 
+    38913, 38656, 38784, 38785, 38768,     0, 32768, 36864, 
+    38912, 38913, 38656, 38784, 38785, 38768, 38772,     0, 
+    32768, 36864, 38912, 38913, 38656, 38784, 38785, 38768, 
+    38772,     0, 32768, 36864, 38912, 38913, 38656, 38784, 
+    38785, 38768, 38776, 38774,     0, 32768, 36864, 38912, 
+    38913, 38656, 38784, 38785, 38768,     0, 32768, 36864, 
+    38912, 38913, 38656, 38784, 38785, 38768, 38776,     0, 
+    32768, 36864, 38912, 38913, 38656, 38784, 38785, 38787, 
+    38776,     0, 32768, 36864, 38912, 38913, 38656, 38784, 
+    38785, 38787, 38776, 38778,     0, 32768, 36864, 38912, 
+    38913, 38656, 38784, 38785, 38787, 38776,     0, 32768, 
+    36864, 38912, 38913, 38656, 38784, 38785, 38787, 38776, 
+    38780,     0, 32768, 36864, 38912, 38913, 38656, 38784, 
+    38785, 38787, 38776, 38780,     0, 32768, 36864, 38912, 
+    38913, 38656, 38784, 38785, 38787, 38776, 38780, 38782, 
+        0, 32768, 36864, 38912, 38913, 38656,     0, 32768, 
+    36864, 38912, 38913, 38656, 38784,     0, 32768, 36864, 
+    38912, 38913, 38656, 38784,     0, 32768, 36864, 38912, 
+    38913, 38656, 38784, 38786,     0, 32768, 36864, 38912, 
+    38913, 38915, 38784,     0, 32768, 36864, 38912, 38913, 
+    38915, 38784, 38788,     0, 32768, 36864, 38912, 38913, 
+    38915, 38784, 38788,     0, 32768, 36864, 38912, 38913, 
+    38915, 38784, 38792, 38790,     0, 32768, 36864, 38912, 
+    38913, 38915, 38784,     0, 32768, 36864, 38912, 38913, 
+    38915, 38784, 38792,     0, 32768, 36864, 38912, 38913, 
+    38915, 38784, 38792,     0, 32768, 36864, 38912, 38913, 
+    38915, 38784, 38792, 38794,     0, 32768, 36864, 38912, 
+    38913, 38915, 38784, 38792,     0, 32768, 36864, 38912, 
+    38913, 38915, 38784, 38800, 38796,     0, 32768, 36864, 
+    38912, 38913, 38915, 38784, 38800, 38796,     0, 32768, 
+    36864, 38912, 38913, 38915, 38784, 38800, 38801, 38798, 
+        0, 32768, 36864, 38912, 38913, 38915, 38784,     0, 
+    32768, 36864, 38912, 38913, 38915, 38784, 38800,     0, 
+    32768, 36864, 38912, 38913, 38915, 38784, 38800,     0, 
+    32768, 36864, 38912, 38913, 38915, 38784, 38800, 38802, 
+        0, 32768, 36864, 38912, 38913, 38915, 38784, 38800, 
+        0, 32768, 36864, 38912, 38913, 38915, 38784, 38800, 
+    38804,     0, 32768, 36864, 38912, 38913, 38915, 38784, 
+    38800, 38804,     0, 32768, 36864, 38912, 38913, 38915, 
+    38784, 38800, 38808, 38806,     0, 32768, 36864, 38912, 
+    38913, 38915, 38784, 38800,     0, 32768, 36864, 38912, 
+    38913, 38915, 38784, 38816, 38808,     0, 32768, 36864, 
+    38912, 38913, 38915, 38784, 38816, 38808,     0, 32768, 
+    36864, 38912, 38913, 38915, 38784, 38816, 38808, 38810, 
+        0, 32768, 36864, 38912, 38913, 38915, 38784, 38816, 
+    38808,     0, 32768, 36864, 38912, 38913, 38915, 38784, 
+    38816, 38817, 38812,     0, 32768, 36864, 38912, 38913, 
+    38915, 38784, 38816, 38817, 38812,     0, 32768, 36864, 
+    38912, 38913, 38915, 38784, 38816, 38817, 38812, 38814, 
+        0, 32768, 36864, 38912, 38913, 38915, 38784,     0, 
+    32768, 36864, 38912, 38913, 38915, 38784, 38816,     0, 
+    32768, 36864, 38912, 38913, 38915, 38784, 38816,     0, 
+    32768, 36864, 38912, 38913, 38915, 38784, 38816, 38818, 
+        0, 32768, 36864, 38912, 38913, 38915, 38784, 38816, 
+        0, 32768, 36864, 38912, 38913, 38915, 38784, 38816, 
+    38820,     0, 32768, 36864, 38912, 38913, 38915, 38784, 
+    38816, 38820,     0, 32768, 36864, 38912, 38913, 38915, 
+    38784, 38816, 38824, 38822,     0, 32768, 36864, 38912, 
+    38913, 38915, 38784, 38816,     0, 32768, 36864, 38912, 
+    38913, 38915, 38784, 38816, 38824,     0, 32768, 36864, 
+    38912, 38913, 38915, 38784, 38816, 38824,     0, 32768, 
+    36864, 38912, 38913, 38915, 38784, 38816, 38824, 38826, 
+        0, 32768, 36864, 38912, 38913, 38915, 38784, 38816, 
+    38824,     0, 32768, 36864, 38912, 38913, 38915, 38784, 
+    38816, 38832, 38828,     0, 32768, 36864, 38912, 38913, 
+    38915, 38784, 38816, 38832, 38828,     0, 32768, 36864, 
+    38912, 38913, 38915, 38784, 38816, 38832, 38833, 38830, 
+        0, 32768, 36864, 38912, 38913, 38915, 38784, 38816, 
+        0, 32768, 36864, 38912, 38913, 38915, 38784, 38848, 
+    38832,     0, 32768, 36864, 38912, 38913, 38915, 38784, 
+    38848, 38832,     0, 32768, 36864, 38912, 38913, 38915, 
+    38784, 38848, 38832, 38834,     0, 32768, 36864, 38912, 
+    38913, 38915, 38784, 38848, 38832,     0, 32768, 36864, 
+    38912, 38913, 38915, 38784, 38848, 38832, 38836,     0, 
+    32768, 36864, 38912, 38913, 38915, 38784, 38848, 38832, 
+    38836,     0, 32768, 36864, 38912, 38913, 38915, 38784, 
+    38848, 38832, 38840, 38838,     0, 32768, 36864, 38912, 
+    38913, 38915, 38784, 38848, 38832,     0, 32768, 36864, 
+    38912, 38913, 38915, 38784, 38848, 38849, 38840,     0, 
+    32768, 36864, 38912, 38913, 38915, 38784, 38848, 38849, 
+    38840,     0, 32768, 36864, 38912, 38913, 38915, 38784, 
+    38848, 38849, 38840, 38842,     0, 32768, 36864, 38912, 
+    38913, 38915, 38784, 38848, 38849, 38840,     0, 32768, 
+    36864, 38912, 38913, 38915, 38784, 38848, 38849, 38840, 
+    38844,     0, 32768, 36864, 38912, 38913, 38915, 38784, 
+    38848, 38849, 38851, 38844,     0, 32768, 36864, 38912, 
+    38913, 38915, 38784, 38848, 38849, 38851, 38844, 38846, 
+        0, 32768, 36864, 38912, 38913, 38915, 38784,     0, 
+    32768, 36864, 38912, 38913, 38915, 38784, 38848,     0, 
+    32768, 36864, 38912, 38913, 38915, 38784, 38848,     0, 
+    32768, 36864, 38912, 38913, 38915, 38784, 38848, 38850, 
+        0, 32768, 36864, 38912, 38913, 38915, 38784, 38848, 
+        0, 32768, 36864, 38912, 38913, 38915, 38784, 38848, 
+    38852,     0, 32768, 36864, 38912, 38913, 38915, 38784, 
+    38848, 38852,     0, 32768, 36864, 38912, 38913, 38915, 
+    38784, 38848, 38856, 38854,     0, 32768, 36864, 38912, 
+    38913, 38915, 38919, 38848,     0, 32768, 36864, 38912, 
+    38913, 38915, 38919, 38848, 38856,     0, 32768, 36864, 
+    38912, 38913, 38915, 38919, 38848, 38856,     0, 32768, 
+    36864, 38912, 38913, 38915, 38919, 38848, 38856, 38858, 
+        0, 32768, 36864, 38912, 38913, 38915, 38919, 38848, 
+    38856,     0, 32768, 36864, 38912, 38913, 38915, 38919, 
+    38848, 38864, 38860,     0, 32768, 36864, 38912, 38913, 
+    38915, 38919, 38848, 38864, 38860,     0, 32768, 36864, 
+    38912, 38913, 38915, 38919, 38848, 38864, 38865, 38862, 
+        0, 32768, 36864, 38912, 38913, 38915, 38919, 38848, 
+        0, 32768, 36864, 38912, 38913, 38915, 38919, 38848, 
+    38864,     0, 32768, 36864, 38912, 38913, 38915, 38919, 
+    38848, 38864,     0, 32768, 36864, 38912, 38913, 38915, 
+    38919, 38848, 38864, 38866,     0, 32768, 36864, 38912, 
+    38913, 38915, 38919, 38848, 38864,     0, 32768, 36864, 
+    38912, 38913, 38915, 38919, 38848, 38864, 38868,     0, 
+    32768, 36864, 38912, 38913, 38915, 38919, 38848, 38864, 
+    38868,     0, 32768, 36864, 38912, 38913, 38915, 38919, 
+    38848, 38864, 38872, 38870,     0, 32768, 36864, 38912, 
+    38913, 38915, 38919, 38848, 38864,     0, 32768, 36864, 
+    38912, 38913, 38915, 38919, 38848, 38880, 38872,     0, 
+    32768, 36864, 38912, 38913, 38915, 38919, 38848, 38880, 
+    38872,     0, 32768, 36864, 38912, 38913, 38915, 38919, 
+    38848, 38880, 38872, 38874,     0, 32768, 36864, 38912, 
+    38913, 38915, 38919, 38848, 38880, 38872,     0, 32768, 
+    36864, 38912, 38913, 38915, 38919, 38848, 38880, 38881, 
+    38876,     0, 32768, 36864, 38912, 38913, 38915, 38919, 
+    38848, 38880, 38881, 38876,     0, 32768, 36864, 38912, 
+    38913, 38915, 38919, 38848, 38880, 38881, 38876, 38878, 
+        0, 32768, 36864, 38912, 38913, 38915, 38919, 38848, 
+        0, 32768, 36864, 38912, 38913, 38915, 38919, 38848, 
+    38880,     0, 32768, 36864, 38912, 38913, 38915, 38919, 
+    38848, 38880,     0, 32768, 36864, 38912, 38913, 38915, 
+    38919, 38848, 38880, 38882,     0, 32768, 36864, 38912, 
+    38913, 38915, 38919, 38848, 38880,     0, 32768, 36864, 
+    38912, 38913, 38915, 38919, 38848, 38880, 38884,     0, 
+    32768, 36864, 38912, 38913, 38915, 38919, 38848, 38880, 
+    38884,     0, 32768, 36864, 38912, 38913, 38915, 38919, 
+    38848, 38880, 38888, 38886,     0, 32768, 36864, 38912, 
+    38913, 38915, 38919, 38848, 38880,     0, 32768, 36864, 
+    38912, 38913, 38915, 38919, 38848, 38880, 38888,     0, 
+    32768, 36864, 38912, 38913, 38915, 38919, 38848, 38880, 
+    38888,     0, 32768, 36864, 38912, 38913, 38915, 38919, 
+    38848, 38880, 38888, 38890,     0, 32768, 36864, 38912, 
+    38913, 38915, 38919, 38848, 38880, 38888,     0, 32768, 
+    36864, 38912, 38913, 38915, 38919, 38848, 38880, 38896, 
+    38892,     0, 32768, 36864, 38912, 38913, 38915, 38919, 
+    38848, 38880, 38896, 38892,     0, 32768, 36864, 38912, 
+    38913, 38915, 38919, 38848, 38880, 38896, 38897, 38894, 
+        0, 32768, 36864, 38912, 38913, 38915, 38919, 38927, 
+    38880,     0, 32768, 36864, 38912, 38913, 38915, 38919, 
+    38927, 38880, 38896,     0, 32768, 36864, 38912, 38913, 
+    38915, 38919, 38927, 38880, 38896,     0, 32768, 36864, 
+    38912, 38913, 38915, 38919, 38927, 38880, 38896, 38898, 
+        0, 32768, 36864, 38912, 38913, 38915, 38919, 38927, 
+    38880, 38896,     0, 32768, 36864, 38912, 38913, 38915, 
+    38919, 38927, 38880, 38896, 38900,     0, 32768, 36864, 
+    38912, 38913, 38915, 38919, 38927, 38880, 38896, 38900, 
+        0, 32768, 36864, 38912, 38913, 38915, 38919, 38927, 
+    38880, 38896, 38904, 38902,     0, 32768, 36864, 38912, 
+    38913, 38915, 38919, 38927, 38880, 38896,     0, 32768, 
+    36864, 38912, 38913, 38915, 38919, 38927, 38880, 38896, 
+    38904,     0, 32768, 36864, 38912, 38913, 38915, 38919, 
+    38927, 38880, 38896, 38904,     0, 32768, 36864, 38912, 
+    38913, 38915, 38919, 38927, 38880, 38896, 38904, 38906, 
+        0, 32768, 36864, 38912, 38913, 38915, 38919, 38927, 
+    38880, 38896, 38904,     0, 32768, 36864, 38912, 38913, 
+    38915, 38919, 38927, 38880, 38896, 38904, 38908,     0, 
+    32768, 36864, 38912, 38913, 38915, 38919, 38927, 38880, 
+    38896, 38904, 38908,     0, 32768, 36864, 38912, 38913, 
+    38915, 38919, 38927, 38880, 38896, 38904, 38908, 38910, 
+        0, 32768, 36864,     0, 32768, 36864, 38912,     0, 
+    32768, 36864, 38912,     0, 32768, 36864, 38912, 38914, 
+        0, 32768, 36864, 38912,     0, 32768, 36864, 38912, 
+    38916,     0, 32768, 36864, 38912, 38916,     0, 32768, 
+    36864, 38912, 38920, 38918,     0, 32768, 36864, 38912, 
+        0, 32768, 36864, 38912, 38920,     0, 32768, 36864, 
+    38912, 38920,     0, 32768, 36864, 38912, 38920, 38922, 
+        0, 32768, 36864, 38912, 38920,     0, 32768, 36864, 
+    38912, 38928, 38924,     0, 32768, 36864, 38912, 38928, 
+    38924,     0, 32768, 36864, 38912, 38928, 38929, 38926, 
+        0, 32768, 36864, 38912,     0, 32768, 36864, 38912, 
+    38928,     0, 32768, 36864, 38912, 38928,     0, 32768, 
+    36864, 38912, 38928, 38930,     0, 32768, 36864, 38912, 
+    38928,     0, 32768, 36864, 38912, 38928, 38932,     0, 
+    32768, 36864, 38912, 38928, 38932,     0, 32768, 36864, 
+    38912, 38928, 38936, 38934,     0, 32768, 36864, 38912, 
+    38928,     0, 32768, 36864, 38912, 38944, 38936,     0, 
+    32768, 36864, 38912, 38944, 38936,     0, 32768, 36864, 
+    38912, 38944, 38936, 38938,     0, 32768, 36864, 38912, 
+    38944, 38936,     0, 32768, 36864, 38912, 38944, 38945, 
+    38940,     0, 32768, 36864, 38912, 38944, 38945, 38940, 
+        0, 32768, 36864, 38912, 38944, 38945, 38940, 38942, 
+        0, 32768, 36864, 38912,     0, 32768, 36864, 38912, 
+    38944,     0, 32768, 36864, 38912, 38944,     0, 32768, 
+    36864, 38912, 38944, 38946,     0, 32768, 36864, 38912, 
+    38944,     0, 32768, 36864, 38912, 38944, 38948,     0, 
+    32768, 36864, 38912, 38944, 38948,     0, 32768, 36864, 
+    38912, 38944, 38952, 38950,     0, 32768, 36864, 38912, 
+    38944,     0, 32768, 36864, 38912, 38944, 38952,     0, 
+    32768, 36864, 38912, 38944, 38952,     0, 32768, 36864, 
+    38912, 38944, 38952, 38954,     0, 32768, 36864, 38912, 
+    38944, 38952,     0, 32768, 36864, 38912, 38944, 38960, 
+    38956,     0, 32768, 36864, 38912, 38944, 38960, 38956, 
+        0, 32768, 36864, 38912, 38944, 38960, 38961, 38958, 
+        0, 32768, 36864, 38912, 38944,     0, 32768, 36864, 
+    38912, 38976, 38960,     0, 32768, 36864, 38912, 38976, 
+    38960,     0, 32768, 36864, 38912, 38976, 38960, 38962, 
+        0, 32768, 36864, 38912, 38976, 38960,     0, 32768, 
+    36864, 38912, 38976, 38960, 38964,     0, 32768, 36864, 
+    38912, 38976, 38960, 38964,     0, 32768, 36864, 38912, 
+    38976, 38960, 38968, 38966,     0, 32768, 36864, 38912, 
+    38976, 38960,     0, 32768, 36864, 38912, 38976, 38977, 
+    38968,     0, 32768, 36864, 38912, 38976, 38977, 38968, 
+        0, 32768, 36864, 38912, 38976, 38977, 38968, 38970, 
+        0, 32768, 36864, 38912, 38976, 38977, 38968,     0, 
+    32768, 36864, 38912, 38976, 38977, 38968, 38972,     0, 
+    32768, 36864, 38912, 38976, 38977, 38979, 38972,     0, 
+    32768, 36864, 38912, 38976, 38977, 38979, 38972, 38974, 
+        0, 32768, 36864, 38912,     0, 32768, 36864, 38912, 
+    38976,     0, 32768, 36864, 38912, 38976,     0, 32768, 
+    36864, 38912, 38976, 38978,     0, 32768, 36864, 38912, 
+    38976,     0, 32768, 36864, 38912, 38976, 38980,     0, 
+    32768, 36864, 38912, 38976, 38980,     0, 32768, 36864, 
+    38912, 38976, 38984, 38982,     0, 32768, 36864, 38912, 
+    38976,     0, 32768, 36864, 38912, 38976, 38984,     0, 
+    32768, 36864, 38912, 38976, 38984,     0, 32768, 36864, 
+    38912, 38976, 38984, 38986,     0, 32768, 36864, 38912, 
+    38976, 38984,     0, 32768, 36864, 38912, 38976, 38992, 
+    38988,     0, 32768, 36864, 38912, 38976, 38992, 38988, 
+        0, 32768, 36864, 38912, 38976, 38992, 38993, 38990, 
+        0, 32768, 36864, 38912, 38976,     0, 32768, 36864, 
+    38912, 38976, 38992,     0, 32768, 36864, 38912, 38976, 
+    38992,     0, 32768, 36864, 38912, 38976, 38992, 38994, 
+        0, 32768, 36864, 38912, 38976, 38992,     0, 32768, 
+    36864, 38912, 38976, 38992, 38996,     0, 32768, 36864, 
+    38912, 38976, 38992, 38996,     0, 32768, 36864, 38912, 
+    38976, 38992, 39000, 38998,     0, 32768, 36864, 38912, 
+    38976, 38992,     0, 32768, 36864, 38912, 38976, 39008, 
+    39000,     0, 32768, 36864, 38912, 38976, 39008, 39000, 
+        0, 32768, 36864, 38912, 38976, 39008, 39000, 39002, 
+        0, 32768, 36864, 38912, 38976, 39008, 39000,     0, 
+    32768, 36864, 38912, 38976, 39008, 39009, 39004,     0, 
+    32768, 36864, 38912, 38976, 39008, 39009, 39004,     0, 
+    32768, 36864, 38912, 38976, 39008, 39009, 39004, 39006, 
+        0, 32768, 36864, 38912, 38976,     0, 32768, 36864, 
+    38912, 39040, 39008,     0, 32768, 36864, 38912, 39040, 
+    39008,     0, 32768, 36864, 38912, 39040, 39008, 39010, 
+        0, 32768, 36864, 38912, 39040, 39008,     0, 32768, 
+    36864, 38912, 39040, 39008, 39012,     0, 32768, 36864, 
+    38912, 39040, 39008, 39012,     0, 32768, 36864, 38912, 
+    39040, 39008, 39016, 39014,     0, 32768, 36864, 38912, 
+    39040, 39008,     0, 32768, 36864, 38912, 39040, 39008, 
+    39016,     0, 32768, 36864, 38912, 39040, 39008, 39016, 
+        0, 32768, 36864, 38912, 39040, 39008, 39016, 39018, 
+        0, 32768, 36864, 38912, 39040, 39008, 39016,     0, 
+    32768, 36864, 38912, 39040, 39008, 39024, 39020,     0, 
+    32768, 36864, 38912, 39040, 39008, 39024, 39020,     0, 
+    32768, 36864, 38912, 39040, 39008, 39024, 39025, 39022, 
+        0, 32768, 36864, 38912, 39040, 39008,     0, 32768, 
+    36864, 38912, 39040, 39041, 39024,     0, 32768, 36864, 
+    38912, 39040, 39041, 39024,     0, 32768, 36864, 38912, 
+    39040, 39041, 39024, 39026,     0, 32768, 36864, 38912, 
+    39040, 39041, 39024,     0, 32768, 36864, 38912, 39040, 
+    39041, 39024, 39028,     0, 32768, 36864, 38912, 39040, 
+    39041, 39024, 39028,     0, 32768, 36864, 38912, 39040, 
+    39041, 39024, 39032, 39030,     0, 32768, 36864, 38912, 
+    39040, 39041, 39024,     0, 32768, 36864, 38912, 39040, 
+    39041, 39024, 39032,     0, 32768, 36864, 38912, 39040, 
+    39041, 39043, 39032,     0, 32768, 36864, 38912, 39040, 
+    39041, 39043, 39032, 39034,     0, 32768, 36864, 38912, 
+    39040, 39041, 39043, 39032,     0, 32768, 36864, 38912, 
+    39040, 39041, 39043, 39032, 39036,     0, 32768, 36864, 
+    38912, 39040, 39041, 39043, 39032, 39036,     0, 32768, 
+    36864, 38912, 39040, 39041, 39043, 39032, 39036, 39038, 
+        0, 32768, 36864, 38912,     0, 32768, 36864, 38912, 
+    39040,     0, 32768, 36864, 38912, 39040,     0, 32768, 
+    36864, 38912, 39040, 39042,     0, 32768, 36864, 38912, 
+    39040,     0, 32768, 36864, 38912, 39040, 39044,     0, 
+    32768, 36864, 38912, 39040, 39044,     0, 32768, 36864, 
+    38912, 39040, 39048, 39046,     0, 32768, 36864, 38912, 
+    39040,     0, 32768, 36864, 38912, 39040, 39048,     0, 
+    32768, 36864, 38912, 39040, 39048,     0, 32768, 36864, 
+    38912, 39040, 39048, 39050,     0, 32768, 36864, 38912, 
+    39040, 39048,     0, 32768, 36864, 38912, 39040, 39056, 
+    39052,     0, 32768, 36864, 38912, 39040, 39056, 39052, 
+        0, 32768, 36864, 38912, 39040, 39056, 39057, 39054, 
+        0, 32768, 36864, 38912, 39040,     0, 32768, 36864, 
+    38912, 39040, 39056,     0, 32768, 36864, 38912, 39040, 
+    39056,     0, 32768, 36864, 38912, 39040, 39056, 39058, 
+        0, 32768, 36864, 38912, 39040, 39056,     0, 32768, 
+    36864, 38912, 39040, 39056, 39060,     0, 32768, 36864, 
+    38912, 39040, 39056, 39060,     0, 32768, 36864, 38912, 
+    39040, 39056, 39064, 39062,     0, 32768, 36864, 38912, 
+    39040, 39056,     0, 32768, 36864, 38912, 39040, 39072, 
+    39064,     0, 32768, 36864, 38912, 39040, 39072, 39064, 
+        0, 32768, 36864, 38912, 39040, 39072, 39064, 39066, 
+        0, 32768, 36864, 38912, 39040, 39072, 39064,     0, 
+    32768, 36864, 38912, 39040, 39072, 39073, 39068,     0, 
+    32768, 36864, 38912, 39040, 39072, 39073, 39068,     0, 
+    32768, 36864, 38912, 39040, 39072, 39073, 39068, 39070, 
+        0, 32768, 36864, 38912, 39040,     0, 32768, 36864, 
+    38912, 39040, 39072,     0, 32768, 36864, 38912, 39040, 
+    39072,     0, 32768, 36864, 38912, 39040, 39072, 39074, 
+        0, 32768, 36864, 38912, 39040, 39072,     0, 32768, 
+    36864, 38912, 39040, 39072, 39076,     0, 32768, 36864, 
+    38912, 39040, 39072, 39076,     0, 32768, 36864, 38912, 
+    39040, 39072, 39080, 39078,     0, 32768, 36864, 38912, 
+    39040, 39072,     0, 32768, 36864, 38912, 39040, 39072, 
+    39080,     0, 32768, 36864, 38912, 39040, 39072, 39080, 
+        0, 32768, 36864, 38912, 39040, 39072, 39080, 39082, 
+        0, 32768, 36864, 38912, 39040, 39072, 39080,     0, 
+    32768, 36864, 38912, 39040, 39072, 39088, 39084,     0, 
+    32768, 36864, 38912, 39040, 39072, 39088, 39084,     0, 
+    32768, 36864, 38912, 39040, 39072, 39088, 39089, 39086, 
+        0, 32768, 36864, 38912, 39040, 39072,     0, 32768, 
+    36864, 38912, 39040, 39104, 39088,     0, 32768, 36864, 
+    38912, 39040, 39104, 39088,     0, 32768, 36864, 38912, 
+    39040, 39104, 39088, 39090,     0, 32768, 36864, 38912, 
+    39040, 39104, 39088,     0, 32768, 36864, 38912, 39040, 
+    39104, 39088, 39092,     0, 32768, 36864, 38912, 39040, 
+    39104, 39088, 39092,     0, 32768, 36864, 38912, 39040, 
+    39104, 39088, 39096, 39094,     0, 32768, 36864, 38912, 
+    39040, 39104, 39088,     0, 32768, 36864, 38912, 39040, 
+    39104, 39105, 39096,     0, 32768, 36864, 38912, 39040, 
+    39104, 39105, 39096,     0, 32768, 36864, 38912, 39040, 
+    39104, 39105, 39096, 39098,     0, 32768, 36864, 38912, 
+    39040, 39104, 39105, 39096,     0, 32768, 36864, 38912, 
+    39040, 39104, 39105, 39096, 39100,     0, 32768, 36864, 
+    38912, 39040, 39104, 39105, 39107, 39100,     0, 32768, 
+    36864, 38912, 39040, 39104, 39105, 39107, 39100, 39102, 
+        0, 32768, 36864, 38912, 39040,     0, 32768, 36864, 
+    38912, 39168, 39104,     0, 32768, 36864, 38912, 39168, 
+    39104,     0, 32768, 36864, 38912, 39168, 39104, 39106, 
+        0, 32768, 36864, 38912, 39168, 39104,     0, 32768, 
+    36864, 38912, 39168, 39104, 39108,     0, 32768, 36864, 
+    38912, 39168, 39104, 39108,     0, 32768, 36864, 38912, 
+    39168, 39104, 39112, 39110,     0, 32768, 36864, 38912, 
+    39168, 39104,     0, 32768, 36864, 38912, 39168, 39104, 
+    39112,     0, 32768, 36864, 38912, 39168, 39104, 39112, 
+        0, 32768, 36864, 38912, 39168, 39104, 39112, 39114, 
+        0, 32768, 36864, 38912, 39168, 39104, 39112,     0, 
+    32768, 36864, 38912, 39168, 39104, 39120, 39116,     0, 
+    32768, 36864, 38912, 39168, 39104, 39120, 39116,     0, 
+    32768, 36864, 38912, 39168, 39104, 39120, 39121, 39118, 
+        0, 32768, 36864, 38912, 39168, 39104,     0, 32768, 
+    36864, 38912, 39168, 39104, 39120,     0, 32768, 36864, 
+    38912, 39168, 39104, 39120,     0, 32768, 36864, 38912, 
+    39168, 39104, 39120, 39122,     0, 32768, 36864, 38912, 
+    39168, 39104, 39120,     0, 32768, 36864, 38912, 39168, 
+    39104, 39120, 39124,     0, 32768, 36864, 38912, 39168, 
+    39104, 39120, 39124,     0, 32768, 36864, 38912, 39168, 
+    39104, 39120, 39128, 39126,     0, 32768, 36864, 38912, 
+    39168, 39104, 39120,     0, 32768, 36864, 38912, 39168, 
+    39104, 39136, 39128,     0, 32768, 36864, 38912, 39168, 
+    39104, 39136, 39128,     0, 32768, 36864, 38912, 39168, 
+    39104, 39136, 39128, 39130,     0, 32768, 36864, 38912, 
+    39168, 39104, 39136, 39128,     0, 32768, 36864, 38912, 
+    39168, 39104, 39136, 39137, 39132,     0, 32768, 36864, 
+    38912, 39168, 39104, 39136, 39137, 39132,     0, 32768, 
+    36864, 38912, 39168, 39104, 39136, 39137, 39132, 39134, 
+        0, 32768, 36864, 38912, 39168, 39104,     0, 32768, 
+    36864, 38912, 39168, 39169, 39136,     0, 32768, 36864, 
+    38912, 39168, 39169, 39136,     0, 32768, 36864, 38912, 
+    39168, 39169, 39136, 39138,     0, 32768, 36864, 38912, 
+    39168, 39169, 39136,     0, 32768, 36864, 38912, 39168, 
+    39169, 39136, 39140,     0, 32768, 36864, 38912, 39168, 
+    39169, 39136, 39140,     0, 32768, 36864, 38912, 39168, 
+    39169, 39136, 39144, 39142,     0, 32768, 36864, 38912, 
+    39168, 39169, 39136,     0, 32768, 36864, 38912, 39168, 
+    39169, 39136, 39144,     0, 32768, 36864, 38912, 39168, 
+    39169, 39136, 39144,     0, 32768, 36864, 38912, 39168, 
+    39169, 39136, 39144, 39146,     0, 32768, 36864, 38912, 
+    39168, 39169, 39136, 39144,     0, 32768, 36864, 38912, 
+    39168, 39169, 39136, 39152, 39148,     0, 32768, 36864, 
+    38912, 39168, 39169, 39136, 39152, 39148,     0, 32768, 
+    36864, 38912, 39168, 39169, 39136, 39152, 39153, 39150, 
+        0, 32768, 36864, 38912, 39168, 39169, 39136,     0, 
+    32768, 36864, 38912, 39168, 39169, 39136, 39152,     0, 
+    32768, 36864, 38912, 39168, 39169, 39171, 39152,     0, 
+    32768, 36864, 38912, 39168, 39169, 39171, 39152, 39154, 
+        0, 32768, 36864, 38912, 39168, 39169, 39171, 39152, 
+        0, 32768, 36864, 38912, 39168, 39169, 39171, 39152, 
+    39156,     0, 32768, 36864, 38912, 39168, 39169, 39171, 
+    39152, 39156,     0, 32768, 36864, 38912, 39168, 39169, 
+    39171, 39152, 39160, 39158,     0, 32768, 36864, 38912, 
+    39168, 39169, 39171, 39152,     0, 32768, 36864, 38912, 
+    39168, 39169, 39171, 39152, 39160,     0, 32768, 36864, 
+    38912, 39168, 39169, 39171, 39152, 39160,     0, 32768, 
+    36864, 38912, 39168, 39169, 39171, 39152, 39160, 39162, 
+        0, 32768, 36864, 38912, 39168, 39169, 39171, 39175, 
+    39160,     0, 32768, 36864, 38912, 39168, 39169, 39171, 
+    39175, 39160, 39164,     0, 32768, 36864, 38912, 39168, 
+    39169, 39171, 39175, 39160, 39164,     0, 32768, 36864, 
+    38912, 39168, 39169, 39171, 39175, 39160, 39164, 39166, 
+        0, 32768, 36864, 38912,     0, 32768, 36864, 38912, 
+    39168,     0, 32768, 36864, 38912, 39168,     0, 32768, 
+    36864, 38912, 39168, 39170,     0, 32768, 36864, 38912, 
+    39168,     0, 32768, 36864, 38912, 39168, 39172,     0, 
+    32768, 36864, 38912, 39168, 39172,     0, 32768, 36864, 
+    38912, 39168, 39176, 39174,     0, 32768, 36864, 38912, 
+    39168,     0, 32768, 36864, 38912, 39168, 39176,     0, 
+    32768, 36864, 38912, 39168, 39176,     0, 32768, 36864, 
+    38912, 39168, 39176, 39178,     0, 32768, 36864, 38912, 
+    39168, 39176,     0, 32768, 36864, 38912, 39168, 39184, 
+    39180,     0, 32768, 36864, 38912, 39168, 39184, 39180, 
+        0, 32768, 36864, 38912, 39168, 39184, 39185, 39182, 
+        0, 32768, 36864, 38912, 39168,     0, 32768, 36864, 
+    38912, 39168, 39184,     0, 32768, 36864, 38912, 39168, 
+    39184,     0, 32768, 36864, 38912, 39168, 39184, 39186, 
+        0, 32768, 36864, 38912, 39168, 39184,     0, 32768, 
+    36864, 38912, 39168, 39184, 39188,     0, 32768, 36864, 
+    38912, 39168, 39184, 39188,     0, 32768, 36864, 38912, 
+    39168, 39184, 39192, 39190,     0, 32768, 36864, 38912, 
+    39168, 39184,     0, 32768, 36864, 38912, 39168, 39200, 
+    39192,     0, 32768, 36864, 38912, 39168, 39200, 39192, 
+        0, 32768, 36864, 38912, 39168, 39200, 39192, 39194, 
+        0, 32768, 36864, 38912, 39168, 39200, 39192,     0, 
+    32768, 36864, 38912, 39168, 39200, 39201, 39196,     0, 
+    32768, 36864, 38912, 39168, 39200, 39201, 39196,     0, 
+    32768, 36864, 38912, 39168, 39200, 39201, 39196, 39198, 
+        0, 32768, 36864, 38912, 39168,     0, 32768, 36864, 
+    38912, 39168, 39200,     0, 32768, 36864, 38912, 39168, 
+    39200,     0, 32768, 36864, 38912, 39168, 39200, 39202, 
+        0, 32768, 36864, 38912, 39168, 39200,     0, 32768, 
+    36864, 38912, 39168, 39200, 39204,     0, 32768, 36864, 
+    38912, 39168, 39200, 39204,     0, 32768, 36864, 38912, 
+    39168, 39200, 39208, 39206,     0, 32768, 36864, 38912, 
+    39168, 39200,     0, 32768, 36864, 38912, 39168, 39200, 
+    39208,     0, 32768, 36864, 38912, 39168, 39200, 39208, 
+        0, 32768, 36864, 38912, 39168, 39200, 39208, 39210, 
+        0, 32768, 36864, 38912, 39168, 39200, 39208,     0, 
+    32768, 36864, 38912, 39168, 39200, 39216, 39212,     0, 
+    32768, 36864, 38912, 39168, 39200, 39216, 39212,     0, 
+    32768, 36864, 38912, 39168, 39200, 39216, 39217, 39214, 
+        0, 32768, 36864, 38912, 39168, 39200,     0, 32768, 
+    36864, 38912, 39168, 39232, 39216,     0, 32768, 36864, 
+    38912, 39168, 39232, 39216,     0, 32768, 36864, 38912, 
+    39168, 39232, 39216, 39218,     0, 32768, 36864, 38912, 
+    39168, 39232, 39216,     0, 32768, 36864, 38912, 39168, 
+    39232, 39216, 39220,     0, 32768, 36864, 38912, 39168, 
+    39232, 39216, 39220,     0, 32768, 36864, 38912, 39168, 
+    39232, 39216, 39224, 39222,     0, 32768, 36864, 38912, 
+    39168, 39232, 39216,     0, 32768, 36864, 38912, 39168, 
+    39232, 39233, 39224,     0, 32768, 36864, 38912, 39168, 
+    39232, 39233, 39224,     0, 32768, 36864, 38912, 39168, 
+    39232, 39233, 39224, 39226,     0, 32768, 36864, 38912, 
+    39168, 39232, 39233, 39224,     0, 32768, 36864, 38912, 
+    39168, 39232, 39233, 39224, 39228,     0, 32768, 36864, 
+    38912, 39168, 39232, 39233, 39235, 39228,     0, 32768, 
+    36864, 38912, 39168, 39232, 39233, 39235, 39228, 39230, 
+        0, 32768, 36864, 38912, 39168,     0, 32768, 36864, 
+    38912, 39168, 39232,     0, 32768, 36864, 38912, 39168, 
+    39232,     0, 32768, 36864, 38912, 39168, 39232, 39234, 
+        0, 32768, 36864, 38912, 39168, 39232,     0, 32768, 
+    36864, 38912, 39168, 39232, 39236,     0, 32768, 36864, 
+    38912, 39168, 39232, 39236,     0, 32768, 36864, 38912, 
+    39168, 39232, 39240, 39238,     0, 32768, 36864, 38912, 
+    39168, 39232,     0, 32768, 36864, 38912, 39168, 39232, 
+    39240,     0, 32768, 36864, 38912, 39168, 39232, 39240, 
+        0, 32768, 36864, 38912, 39168, 39232, 39240, 39242, 
+        0, 32768, 36864, 38912, 39168, 39232, 39240,     0, 
+    32768, 36864, 38912, 39168, 39232, 39248, 39244,     0, 
+    32768, 36864, 38912, 39168, 39232, 39248, 39244,     0, 
+    32768, 36864, 38912, 39168, 39232, 39248, 39249, 39246, 
+        0, 32768, 36864, 38912, 39168, 39232,     0, 32768, 
+    36864, 38912, 39168, 39232, 39248,     0, 32768, 36864, 
+    38912, 39168, 39232, 39248,     0, 32768, 36864, 38912, 
+    39168, 39232, 39248, 39250,     0, 32768, 36864, 38912, 
+    39168, 39232, 39248,     0, 32768, 36864, 38912, 39168, 
+    39232, 39248, 39252,     0, 32768, 36864, 38912, 39168, 
+    39232, 39248, 39252,     0, 32768, 36864, 38912, 39168, 
+    39232, 39248, 39256, 39254,     0, 32768, 36864, 38912, 
+    39168, 39232, 39248,     0, 32768, 36864, 38912, 39168, 
+    39232, 39264, 39256,     0, 32768, 36864, 38912, 39168, 
+    39232, 39264, 39256,     0, 32768, 36864, 38912, 39168, 
+    39232, 39264, 39256, 39258,     0, 32768, 36864, 38912, 
+    39168, 39232, 39264, 39256,     0, 32768, 36864, 38912, 
+    39168, 39232, 39264, 39265, 39260,     0, 32768, 36864, 
+    38912, 39168, 39232, 39264, 39265, 39260,     0, 32768, 
+    36864, 38912, 39168, 39232, 39264, 39265, 39260, 39262, 
+        0, 32768, 36864, 38912, 39168, 39232,     0, 32768, 
+    36864, 38912, 39168, 39296, 39264,     0, 32768, 36864, 
+    38912, 39168, 39296, 39264,     0, 32768, 36864, 38912, 
+    39168, 39296, 39264, 39266,     0, 32768, 36864, 38912, 
+    39168, 39296, 39264,     0, 32768, 36864, 38912, 39168, 
+    39296, 39264, 39268,     0, 32768, 36864, 38912, 39168, 
+    39296, 39264, 39268,     0, 32768, 36864, 38912, 39168, 
+    39296, 39264, 39272, 39270,     0, 32768, 36864, 38912, 
+    39168, 39296, 39264,     0, 32768, 36864, 38912, 39168, 
+    39296, 39264, 39272,     0, 32768, 36864, 38912, 39168, 
+    39296, 39264, 39272,     0, 32768, 36864, 38912, 39168, 
+    39296, 39264, 39272, 39274,     0, 32768, 36864, 38912, 
+    39168, 39296, 39264, 39272,     0, 32768, 36864, 38912, 
+    39168, 39296, 39264, 39280, 39276,     0, 32768, 36864, 
+    38912, 39168, 39296, 39264, 39280, 39276,     0, 32768, 
+    36864, 38912, 39168, 39296, 39264, 39280, 39281, 39278, 
+        0, 32768, 36864, 38912, 39168, 39296, 39264,     0, 
+    32768, 36864, 38912, 39168, 39296, 39297, 39280,     0, 
+    32768, 36864, 38912, 39168, 39296, 39297, 39280,     0, 
+    32768, 36864, 38912, 39168, 39296, 39297, 39280, 39282, 
+        0, 32768, 36864, 38912, 39168, 39296, 39297, 39280, 
+        0, 32768, 36864, 38912, 39168, 39296, 39297, 39280, 
+    39284,     0, 32768, 36864, 38912, 39168, 39296, 39297, 
+    39280, 39284,     0, 32768, 36864, 38912, 39168, 39296, 
+    39297, 39280, 39288, 39286,     0, 32768, 36864, 38912, 
+    39168, 39296, 39297, 39280,     0, 32768, 36864, 38912, 
+    39168, 39296, 39297, 39280, 39288,     0, 32768, 36864, 
+    38912, 39168, 39296, 39297, 39299, 39288,     0, 32768, 
+    36864, 38912, 39168, 39296, 39297, 39299, 39288, 39290, 
+        0, 32768, 36864, 38912, 39168, 39296, 39297, 39299, 
+    39288,     0, 32768, 36864, 38912, 39168, 39296, 39297, 
+    39299, 39288, 39292,     0, 32768, 36864, 38912, 39168, 
+    39296, 39297, 39299, 39288, 39292,     0, 32768, 36864, 
+    38912, 39168, 39296, 39297, 39299, 39288, 39292, 39294, 
+        0, 32768, 36864, 38912, 39168,     0, 32768, 36864, 
+    38912, 39424, 39296,     0, 32768, 36864, 38912, 39424, 
+    39296,     0, 32768, 36864, 38912, 39424, 39296, 39298, 
+        0, 32768, 36864, 38912, 39424, 39296,     0, 32768, 
+    36864, 38912, 39424, 39296, 39300,     0, 32768, 36864, 
+    38912, 39424, 39296, 39300,     0, 32768, 36864, 38912, 
+    39424, 39296, 39304, 39302,     0, 32768, 36864, 38912, 
+    39424, 39296,     0, 32768, 36864, 38912, 39424, 39296, 
+    39304,     0, 32768, 36864, 38912, 39424, 39296, 39304, 
+        0, 32768, 36864, 38912, 39424, 39296, 39304, 39306, 
+        0, 32768, 36864, 38912, 39424, 39296, 39304,     0, 
+    32768, 36864, 38912, 39424, 39296, 39312, 39308,     0, 
+    32768, 36864, 38912, 39424, 39296, 39312, 39308,     0, 
+    32768, 36864, 38912, 39424, 39296, 39312, 39313, 39310, 
+        0, 32768, 36864, 38912, 39424, 39296,     0, 32768, 
+    36864, 38912, 39424, 39296, 39312,     0, 32768, 36864, 
+    38912, 39424, 39296, 39312,     0, 32768, 36864, 38912, 
+    39424, 39296, 39312, 39314,     0, 32768, 36864, 38912, 
+    39424, 39296, 39312,     0, 32768, 36864, 38912, 39424, 
+    39296, 39312, 39316,     0, 32768, 36864, 38912, 39424, 
+    39296, 39312, 39316,     0, 32768, 36864, 38912, 39424, 
+    39296, 39312, 39320, 39318,     0, 32768, 36864, 38912, 
+    39424, 39296, 39312,     0, 32768, 36864, 38912, 39424, 
+    39296, 39328, 39320,     0, 32768, 36864, 38912, 39424, 
+    39296, 39328, 39320,     0, 32768, 36864, 38912, 39424, 
+    39296, 39328, 39320, 39322,     0, 32768, 36864, 38912, 
+    39424, 39296, 39328, 39320,     0, 32768, 36864, 38912, 
+    39424, 39296, 39328, 39329, 39324,     0, 32768, 36864, 
+    38912, 39424, 39296, 39328, 39329, 39324,     0, 32768, 
+    36864, 38912, 39424, 39296, 39328, 39329, 39324, 39326, 
+        0, 32768, 36864, 38912, 39424, 39296,     0, 32768, 
+    36864, 38912, 39424, 39296, 39328,     0, 32768, 36864, 
+    38912, 39424, 39296, 39328,     0, 32768, 36864, 38912, 
+    39424, 39296, 39328, 39330,     0, 32768, 36864, 38912, 
+    39424, 39296, 39328,     0, 32768, 36864, 38912, 39424, 
+    39296, 39328, 39332,     0, 32768, 36864, 38912, 39424, 
+    39296, 39328, 39332,     0, 32768, 36864, 38912, 39424, 
+    39296, 39328, 39336, 39334,     0, 32768, 36864, 38912, 
+    39424, 39296, 39328,     0, 32768, 36864, 38912, 39424, 
+    39296, 39328, 39336,     0, 32768, 36864, 38912, 39424, 
+    39296, 39328, 39336,     0, 32768, 36864, 38912, 39424, 
+    39296, 39328, 39336, 39338,     0, 32768, 36864, 38912, 
+    39424, 39296, 39328, 39336,     0, 32768, 36864, 38912, 
+    39424, 39296, 39328, 39344, 39340,     0, 32768, 36864, 
+    38912, 39424, 39296, 39328, 39344, 39340,     0, 32768, 
+    36864, 38912, 39424, 39296, 39328, 39344, 39345, 39342, 
+        0, 32768, 36864, 38912, 39424, 39296, 39328,     0, 
+    32768, 36864, 38912, 39424, 39296, 39360, 39344,     0, 
+    32768, 36864, 38912, 39424, 39296, 39360, 39344,     0, 
+    32768, 36864, 38912, 39424, 39296, 39360, 39344, 39346, 
+        0, 32768, 36864, 38912, 39424, 39296, 39360, 39344, 
+        0, 32768, 36864, 38912, 39424, 39296, 39360, 39344, 
+    39348,     0, 32768, 36864, 38912, 39424, 39296, 39360, 
+    39344, 39348,     0, 32768, 36864, 38912, 39424, 39296, 
+    39360, 39344, 39352, 39350,     0, 32768, 36864, 38912, 
+    39424, 39296, 39360, 39344,     0, 32768, 36864, 38912, 
+    39424, 39296, 39360, 39361, 39352,     0, 32768, 36864, 
+    38912, 39424, 39296, 39360, 39361, 39352,     0, 32768, 
+    36864, 38912, 39424, 39296, 39360, 39361, 39352, 39354, 
+        0, 32768, 36864, 38912, 39424, 39296, 39360, 39361, 
+    39352,     0, 32768, 36864, 38912, 39424, 39296, 39360, 
+    39361, 39352, 39356,     0, 32768, 36864, 38912, 39424, 
+    39296, 39360, 39361, 39363, 39356,     0, 32768, 36864, 
+    38912, 39424, 39296, 39360, 39361, 39363, 39356, 39358, 
+        0, 32768, 36864, 38912, 39424, 39296,     0, 32768, 
+    36864, 38912, 39424, 39425, 39360,     0, 32768, 36864, 
+    38912, 39424, 39425, 39360,     0, 32768, 36864, 38912, 
+    39424, 39425, 39360, 39362,     0, 32768, 36864, 38912, 
+    39424, 39425, 39360,     0, 32768, 36864, 38912, 39424, 
+    39425, 39360, 39364,     0, 32768, 36864, 38912, 39424, 
+    39425, 39360, 39364,     0, 32768, 36864, 38912, 39424, 
+    39425, 39360, 39368, 39366,     0, 32768, 36864, 38912, 
+    39424, 39425, 39360,     0, 32768, 36864, 38912, 39424, 
+    39425, 39360, 39368,     0, 32768, 36864, 38912, 39424, 
+    39425, 39360, 39368,     0, 32768, 36864, 38912, 39424, 
+    39425, 39360, 39368, 39370,     0, 32768, 36864, 38912, 
+    39424, 39425, 39360, 39368,     0, 32768, 36864, 38912, 
+    39424, 39425, 39360, 39376, 39372,     0, 32768, 36864, 
+    38912, 39424, 39425, 39360, 39376, 39372,     0, 32768, 
+    36864, 38912, 39424, 39425, 39360, 39376, 39377, 39374, 
+        0, 32768, 36864, 38912, 39424, 39425, 39360,     0, 
+    32768, 36864, 38912, 39424, 39425, 39360, 39376,     0, 
+    32768, 36864, 38912, 39424, 39425, 39360, 39376,     0, 
+    32768, 36864, 38912, 39424, 39425, 39360, 39376, 39378, 
+        0, 32768, 36864, 38912, 39424, 39425, 39360, 39376, 
+        0, 32768, 36864, 38912, 39424, 39425, 39360, 39376, 
+    39380,     0, 32768, 36864, 38912, 39424, 39425, 39360, 
+    39376, 39380,     0, 32768, 36864, 38912, 39424, 39425, 
+    39360, 39376, 39384, 39382,     0, 32768, 36864, 38912, 
+    39424, 39425, 39360, 39376,     0, 32768, 36864, 38912, 
+    39424, 39425, 39360, 39392, 39384,     0, 32768, 36864, 
+    38912, 39424, 39425, 39360, 39392, 39384,     0, 32768, 
+    36864, 38912, 39424, 39425, 39360, 39392, 39384, 39386, 
+        0, 32768, 36864, 38912, 39424, 39425, 39360, 39392, 
+    39384,     0, 32768, 36864, 38912, 39424, 39425, 39360, 
+    39392, 39393, 39388,     0, 32768, 36864, 38912, 39424, 
+    39425, 39360, 39392, 39393, 39388,     0, 32768, 36864, 
+    38912, 39424, 39425, 39360, 39392, 39393, 39388, 39390, 
+        0, 32768, 36864, 38912, 39424, 39425, 39360,     0, 
+    32768, 36864, 38912, 39424, 39425, 39360, 39392,     0, 
+    32768, 36864, 38912, 39424, 39425, 39427, 39392,     0, 
+    32768, 36864, 38912, 39424, 39425, 39427, 39392, 39394, 
+        0, 32768, 36864, 38912, 39424, 39425, 39427, 39392, 
+        0, 32768, 36864, 38912, 39424, 39425, 39427, 39392, 
+    39396,     0, 32768, 36864, 38912, 39424, 39425, 39427, 
+    39392, 39396,     0, 32768, 36864, 38912, 39424, 39425, 
+    39427, 39392, 39400, 39398,     0, 32768, 36864, 38912, 
+    39424, 39425, 39427, 39392,     0, 32768, 36864, 38912, 
+    39424, 39425, 39427, 39392, 39400,     0, 32768, 36864, 
+    38912, 39424, 39425, 39427, 39392, 39400,     0, 32768, 
+    36864, 38912, 39424, 39425, 39427, 39392, 39400, 39402, 
+        0, 32768, 36864, 38912, 39424, 39425, 39427, 39392, 
+    39400,     0, 32768, 36864, 38912, 39424, 39425, 39427, 
+    39392, 39408, 39404,     0, 32768, 36864, 38912, 39424, 
+    39425, 39427, 39392, 39408, 39404,     0, 32768, 36864, 
+    38912, 39424, 39425, 39427, 39392, 39408, 39409, 39406, 
+        0, 32768, 36864, 38912, 39424, 39425, 39427, 39392, 
+        0, 32768, 36864, 38912, 39424, 39425, 39427, 39392, 
+    39408,     0, 32768, 36864, 38912, 39424, 39425, 39427, 
+    39392, 39408,     0, 32768, 36864, 38912, 39424, 39425, 
+    39427, 39392, 39408, 39410,     0, 32768, 36864, 38912, 
+    39424, 39425, 39427, 39431, 39408,     0, 32768, 36864, 
+    38912, 39424, 39425, 39427, 39431, 39408, 39412,     0, 
+    32768, 36864, 38912, 39424, 39425, 39427, 39431, 39408, 
+    39412,     0, 32768, 36864, 38912, 39424, 39425, 39427, 
+    39431, 39408, 39416, 39414,     0, 32768, 36864, 38912, 
+    39424, 39425, 39427, 39431, 39408,     0, 32768, 36864, 
+    38912, 39424, 39425, 39427, 39431, 39408, 39416,     0, 
+    32768, 36864, 38912, 39424, 39425, 39427, 39431, 39408, 
+    39416,     0, 32768, 36864, 38912, 39424, 39425, 39427, 
+    39431, 39408, 39416, 39418,     0, 32768, 36864, 38912, 
+    39424, 39425, 39427, 39431, 39408, 39416,     0, 32768, 
+    36864, 38912, 39424, 39425, 39427, 39431, 39408, 39416, 
+    39420,     0, 32768, 36864, 38912, 39424, 39425, 39427, 
+    39431, 39408, 39416, 39420,     0, 32768, 36864, 38912, 
+    39424, 39425, 39427, 39431, 39408, 39416, 39420, 39422, 
+        0, 32768, 36864, 38912,     0, 32768, 36864, 38912, 
+    39424,     0, 32768, 36864, 38912, 39424,     0, 32768, 
+    36864, 38912, 39424, 39426,     0, 32768, 36864, 38912, 
+    39424,     0, 32768, 36864, 38912, 39424, 39428,     0, 
+    32768, 36864, 38912, 39424, 39428,     0, 32768, 36864, 
+    38912, 39424, 39432, 39430,     0, 32768, 36864, 38912, 
+    39424,     0, 32768, 36864, 38912, 39424, 39432,     0, 
+    32768, 36864, 38912, 39424, 39432,     0, 32768, 36864, 
+    38912, 39424, 39432, 39434,     0, 32768, 36864, 38912, 
+    39424, 39432,     0, 32768, 36864, 38912, 39424, 39440, 
+    39436,     0, 32768, 36864, 38912, 39424, 39440, 39436, 
+        0, 32768, 36864, 38912, 39424, 39440, 39441, 39438, 
+        0, 32768, 36864, 38912, 39424,     0, 32768, 36864, 
+    38912, 39424, 39440,     0, 32768, 36864, 38912, 39424, 
+    39440,     0, 32768, 36864, 38912, 39424, 39440, 39442, 
+        0, 32768, 36864, 38912, 39424, 39440,     0, 32768, 
+    36864, 38912, 39424, 39440, 39444,     0, 32768, 36864, 
+    38912, 39424, 39440, 39444,     0, 32768, 36864, 38912, 
+    39424, 39440, 39448, 39446,     0, 32768, 36864, 38912, 
+    39424, 39440,     0, 32768, 36864, 38912, 39424, 39456, 
+    39448,     0, 32768, 36864, 38912, 39424, 39456, 39448, 
+        0, 32768, 36864, 38912, 39424, 39456, 39448, 39450, 
+        0, 32768, 36864, 38912, 39424, 39456, 39448,     0, 
+    32768, 36864, 38912, 39424, 39456, 39457, 39452,     0, 
+    32768, 36864, 38912, 39424, 39456, 39457, 39452,     0, 
+    32768, 36864, 38912, 39424, 39456, 39457, 39452, 39454, 
+        0, 32768, 36864, 38912, 39424,     0, 32768, 36864, 
+    38912, 39424, 39456,     0, 32768, 36864, 38912, 39424, 
+    39456,     0, 32768, 36864, 38912, 39424, 39456, 39458, 
+        0, 32768, 36864, 38912, 39424, 39456,     0, 32768, 
+    36864, 38912, 39424, 39456, 39460,     0, 32768, 36864, 
+    38912, 39424, 39456, 39460,     0, 32768, 36864, 38912, 
+    39424, 39456, 39464, 39462,     0, 32768, 36864, 38912, 
+    39424, 39456,     0, 32768, 36864, 38912, 39424, 39456, 
+    39464,     0, 32768, 36864, 38912, 39424, 39456, 39464, 
+        0, 32768, 36864, 38912, 39424, 39456, 39464, 39466, 
+        0, 32768, 36864, 38912, 39424, 39456, 39464,     0, 
+    32768, 36864, 38912, 39424, 39456, 39472, 39468,     0, 
+    32768, 36864, 38912, 39424, 39456, 39472, 39468,     0, 
+    32768, 36864, 38912, 39424, 39456, 39472, 39473, 39470, 
+        0, 32768, 36864, 38912, 39424, 39456,     0, 32768, 
+    36864, 38912, 39424, 39488, 39472,     0, 32768, 36864, 
+    38912, 39424, 39488, 39472,     0, 32768, 36864, 38912, 
+    39424, 39488, 39472, 39474,     0, 32768, 36864, 38912, 
+    39424, 39488, 39472,     0, 32768, 36864, 38912, 39424, 
+    39488, 39472, 39476,     0, 32768, 36864, 38912, 39424, 
+    39488, 39472, 39476,     0, 32768, 36864, 38912, 39424, 
+    39488, 39472, 39480, 39478,     0, 32768, 36864, 38912, 
+    39424, 39488, 39472,     0, 32768, 36864, 38912, 39424, 
+    39488, 39489, 39480,     0, 32768, 36864, 38912, 39424, 
+    39488, 39489, 39480,     0, 32768, 36864, 38912, 39424, 
+    39488, 39489, 39480, 39482,     0, 32768, 36864, 38912, 
+    39424, 39488, 39489, 39480,     0, 32768, 36864, 38912, 
+    39424, 39488, 39489, 39480, 39484,     0, 32768, 36864, 
+    38912, 39424, 39488, 39489, 39491, 39484,     0, 32768, 
+    36864, 38912, 39424, 39488, 39489, 39491, 39484, 39486, 
+        0, 32768, 36864, 38912, 39424,     0, 32768, 36864, 
+    38912, 39424, 39488,     0, 32768, 36864, 38912, 39424, 
+    39488,     0, 32768, 36864, 38912, 39424, 39488, 39490, 
+        0, 32768, 36864, 38912, 39424, 39488,     0, 32768, 
+    36864, 38912, 39424, 39488, 39492,     0, 32768, 36864, 
+    38912, 39424, 39488, 39492,     0, 32768, 36864, 38912, 
+    39424, 39488, 39496, 39494,     0, 32768, 36864, 38912, 
+    39424, 39488,     0, 32768, 36864, 38912, 39424, 39488, 
+    39496,     0, 32768, 36864, 38912, 39424, 39488, 39496, 
+        0, 32768, 36864, 38912, 39424, 39488, 39496, 39498, 
+        0, 32768, 36864, 38912, 39424, 39488, 39496,     0, 
+    32768, 36864, 38912, 39424, 39488, 39504, 39500,     0, 
+    32768, 36864, 38912, 39424, 39488, 39504, 39500,     0, 
+    32768, 36864, 38912, 39424, 39488, 39504, 39505, 39502, 
+        0, 32768, 36864, 38912, 39424, 39488,     0, 32768, 
+    36864, 38912, 39424, 39488, 39504,     0, 32768, 36864, 
+    38912, 39424, 39488, 39504,     0, 32768, 36864, 38912, 
+    39424, 39488, 39504, 39506,     0, 32768, 36864, 38912, 
+    39424, 39488, 39504,     0, 32768, 36864, 38912, 39424, 
+    39488, 39504, 39508,     0, 32768, 36864, 38912, 39424, 
+    39488, 39504, 39508,     0, 32768, 36864, 38912, 39424, 
+    39488, 39504, 39512, 39510,     0, 32768, 36864, 38912, 
+    39424, 39488, 39504,     0, 32768, 36864, 38912, 39424, 
+    39488, 39520, 39512,     0, 32768, 36864, 38912, 39424, 
+    39488, 39520, 39512,     0, 32768, 36864, 38912, 39424, 
+    39488, 39520, 39512, 39514,     0, 32768, 36864, 38912, 
+    39424, 39488, 39520, 39512,     0, 32768, 36864, 38912, 
+    39424, 39488, 39520, 39521, 39516,     0, 32768, 36864, 
+    38912, 39424, 39488, 39520, 39521, 39516,     0, 32768, 
+    36864, 38912, 39424, 39488, 39520, 39521, 39516, 39518, 
+        0, 32768, 36864, 38912, 39424, 39488,     0, 32768, 
+    36864, 38912, 39424, 39552, 39520,     0, 32768, 36864, 
+    38912, 39424, 39552, 39520,     0, 32768, 36864, 38912, 
+    39424, 39552, 39520, 39522,     0, 32768, 36864, 38912, 
+    39424, 39552, 39520,     0, 32768, 36864, 38912, 39424, 
+    39552, 39520, 39524,     0, 32768, 36864, 38912, 39424, 
+    39552, 39520, 39524,     0, 32768, 36864, 38912, 39424, 
+    39552, 39520, 39528, 39526,     0, 32768, 36864, 38912, 
+    39424, 39552, 39520,     0, 32768, 36864, 38912, 39424, 
+    39552, 39520, 39528,     0, 32768, 36864, 38912, 39424, 
+    39552, 39520, 39528,     0, 32768, 36864, 38912, 39424, 
+    39552, 39520, 39528, 39530,     0, 32768, 36864, 38912, 
+    39424, 39552, 39520, 39528,     0, 32768, 36864, 38912, 
+    39424, 39552, 39520, 39536, 39532,     0, 32768, 36864, 
+    38912, 39424, 39552, 39520, 39536, 39532,     0, 32768, 
+    36864, 38912, 39424, 39552, 39520, 39536, 39537, 39534, 
+        0, 32768, 36864, 38912, 39424, 39552, 39520,     0, 
+    32768, 36864, 38912, 39424, 39552, 39553, 39536,     0, 
+    32768, 36864, 38912, 39424, 39552, 39553, 39536,     0, 
+    32768, 36864, 38912, 39424, 39552, 39553, 39536, 39538, 
+        0, 32768, 36864, 38912, 39424, 39552, 39553, 39536, 
+        0, 32768, 36864, 38912, 39424, 39552, 39553, 39536, 
+    39540,     0, 32768, 36864, 38912, 39424, 39552, 39553, 
+    39536, 39540,     0, 32768, 36864, 38912, 39424, 39552, 
+    39553, 39536, 39544, 39542,     0, 32768, 36864, 38912, 
+    39424, 39552, 39553, 39536,     0, 32768, 36864, 38912, 
+    39424, 39552, 39553, 39536, 39544,     0, 32768, 36864, 
+    38912, 39424, 39552, 39553, 39555, 39544,     0, 32768, 
+    36864, 38912, 39424, 39552, 39553, 39555, 39544, 39546, 
+        0, 32768, 36864, 38912, 39424, 39552, 39553, 39555, 
+    39544,     0, 32768, 36864, 38912, 39424, 39552, 39553, 
+    39555, 39544, 39548,     0, 32768, 36864, 38912, 39424, 
+    39552, 39553, 39555, 39544, 39548,     0, 32768, 36864, 
+    38912, 39424, 39552, 39553, 39555, 39544, 39548, 39550, 
+        0, 32768, 36864, 38912, 39424,     0, 32768, 36864, 
+    38912, 39424, 39552,     0, 32768, 36864, 38912, 39424, 
+    39552,     0, 32768, 36864, 38912, 39424, 39552, 39554, 
+        0, 32768, 36864, 38912, 39424, 39552,     0, 32768, 
+    36864, 38912, 39424, 39552, 39556,     0, 32768, 36864, 
+    38912, 39424, 39552, 39556,     0, 32768, 36864, 38912, 
+    39424, 39552, 39560, 39558,     0, 32768, 36864, 38912, 
+    39424, 39552,     0, 32768, 36864, 38912, 39424, 39552, 
+    39560,     0, 32768, 36864, 38912, 39424, 39552, 39560, 
+        0, 32768, 36864, 38912, 39424, 39552, 39560, 39562, 
+        0, 32768, 36864, 38912, 39424, 39552, 39560,     0, 
+    32768, 36864, 38912, 39424, 39552, 39568, 39564,     0, 
+    32768, 36864, 38912, 39424, 39552, 39568, 39564,     0, 
+    32768, 36864, 38912, 39424, 39552, 39568, 39569, 39566, 
+        0, 32768, 36864, 38912, 39424, 39552,     0, 32768, 
+    36864, 38912, 39424, 39552, 39568,     0, 32768, 36864, 
+    38912, 39424, 39552, 39568,     0, 32768, 36864, 38912, 
+    39424, 39552, 39568, 39570,     0, 32768, 36864, 38912, 
+    39424, 39552, 39568,     0, 32768, 36864, 38912, 39424, 
+    39552, 39568, 39572,     0, 32768, 36864, 38912, 39424, 
+    39552, 39568, 39572,     0, 32768, 36864, 38912, 39424, 
+    39552, 39568, 39576, 39574,     0, 32768, 36864, 38912, 
+    39424, 39552, 39568,     0, 32768, 36864, 38912, 39424, 
+    39552, 39584, 39576,     0, 32768, 36864, 38912, 39424, 
+    39552, 39584, 39576,     0, 32768, 36864, 38912, 39424, 
+    39552, 39584, 39576, 39578,     0, 32768, 36864, 38912, 
+    39424, 39552, 39584, 39576,     0, 32768, 36864, 38912, 
+    39424, 39552, 39584, 39585, 39580,     0, 32768, 36864, 
+    38912, 39424, 39552, 39584, 39585, 39580,     0, 32768, 
+    36864, 38912, 39424, 39552, 39584, 39585, 39580, 39582, 
+        0, 32768, 36864, 38912, 39424, 39552,     0, 32768, 
+    36864, 38912, 39424, 39552, 39584,     0, 32768, 36864, 
+    38912, 39424, 39552, 39584,     0, 32768, 36864, 38912, 
+    39424, 39552, 39584, 39586,     0, 32768, 36864, 38912, 
+    39424, 39552, 39584,     0, 32768, 36864, 38912, 39424, 
+    39552, 39584, 39588,     0, 32768, 36864, 38912, 39424, 
+    39552, 39584, 39588,     0, 32768, 36864, 38912, 39424, 
+    39552, 39584, 39592, 39590,     0, 32768, 36864, 38912, 
+    39424, 39552, 39584,     0, 32768, 36864, 38912, 39424, 
+    39552, 39584, 39592,     0, 32768, 36864, 38912, 39424, 
+    39552, 39584, 39592,     0, 32768, 36864, 38912, 39424, 
+    39552, 39584, 39592, 39594,     0, 32768, 36864, 38912, 
+    39424, 39552, 39584, 39592,     0, 32768, 36864, 38912, 
+    39424, 39552, 39584, 39600, 39596,     0, 32768, 36864, 
+    38912, 39424, 39552, 39584, 39600, 39596,     0, 32768, 
+    36864, 38912, 39424, 39552, 39584, 39600, 39601, 39598, 
+        0, 32768, 36864, 38912, 39424, 39552, 39584,     0, 
+    32768, 36864, 38912, 39424, 39552, 39616, 39600,     0, 
+    32768, 36864, 38912, 39424, 39552, 39616, 39600,     0, 
+    32768, 36864, 38912, 39424, 39552, 39616, 39600, 39602, 
+        0, 32768, 36864, 38912, 39424, 39552, 39616, 39600, 
+        0, 32768, 36864, 38912, 39424, 39552, 39616, 39600, 
+    39604,     0, 32768, 36864, 38912, 39424, 39552, 39616, 
+    39600, 39604,     0, 32768, 36864, 38912, 39424, 39552, 
+    39616, 39600, 39608, 39606,     0, 32768, 36864, 38912, 
+    39424, 39552, 39616, 39600,     0, 32768, 36864, 38912, 
+    39424, 39552, 39616, 39617, 39608,     0, 32768, 36864, 
+    38912, 39424, 39552, 39616, 39617, 39608,     0, 32768, 
+    36864, 38912, 39424, 39552, 39616, 39617, 39608, 39610, 
+        0, 32768, 36864, 38912, 39424, 39552, 39616, 39617, 
+    39608,     0, 32768, 36864, 38912, 39424, 39552, 39616, 
+    39617, 39608, 39612,     0, 32768, 36864, 38912, 39424, 
+    39552, 39616, 39617, 39619, 39612,     0, 32768, 36864, 
+    38912, 39424, 39552, 39616, 39617, 39619, 39612, 39614, 
+        0, 32768, 36864, 38912, 39424, 39552,     0, 32768, 
+    36864, 38912, 39424, 39680, 39616,     0, 32768, 36864, 
+    38912, 39424, 39680, 39616,     0, 32768, 36864, 38912, 
+    39424, 39680, 39616, 39618,     0, 32768, 36864, 38912, 
+    39424, 39680, 39616,     0, 32768, 36864, 38912, 39424, 
+    39680, 39616, 39620,     0, 32768, 36864, 38912, 39424, 
+    39680, 39616, 39620,     0, 32768, 36864, 38912, 39424, 
+    39680, 39616, 39624, 39622,     0, 32768, 36864, 38912, 
+    39424, 39680, 39616,     0, 32768, 36864, 38912, 39424, 
+    39680, 39616, 39624,     0, 32768, 36864, 38912, 39424, 
+    39680, 39616, 39624,     0, 32768, 36864, 38912, 39424, 
+    39680, 39616, 39624, 39626,     0, 32768, 36864, 38912, 
+    39424, 39680, 39616, 39624,     0, 32768, 36864, 38912, 
+    39424, 39680, 39616, 39632, 39628,     0, 32768, 36864, 
+    38912, 39424, 39680, 39616, 39632, 39628,     0, 32768, 
+    36864, 38912, 39424, 39680, 39616, 39632, 39633, 39630, 
+        0, 32768, 36864, 38912, 39424, 39680, 39616,     0, 
+    32768, 36864, 38912, 39424, 39680, 39616, 39632,     0, 
+    32768, 36864, 38912, 39424, 39680, 39616, 39632,     0, 
+    32768, 36864, 38912, 39424, 39680, 39616, 39632, 39634, 
+        0, 32768, 36864, 38912, 39424, 39680, 39616, 39632, 
+        0, 32768, 36864, 38912, 39424, 39680, 39616, 39632, 
+    39636,     0, 32768, 36864, 38912, 39424, 39680, 39616, 
+    39632, 39636,     0, 32768, 36864, 38912, 39424, 39680, 
+    39616, 39632, 39640, 39638,     0, 32768, 36864, 38912, 
+    39424, 39680, 39616, 39632,     0, 32768, 36864, 38912, 
+    39424, 39680, 39616, 39648, 39640,     0, 32768, 36864, 
+    38912, 39424, 39680, 39616, 39648, 39640,     0, 32768, 
+    36864, 38912, 39424, 39680, 39616, 39648, 39640, 39642, 
+        0, 32768, 36864, 38912, 39424, 39680, 39616, 39648, 
+    39640,     0, 32768, 36864, 38912, 39424, 39680, 39616, 
+    39648, 39649, 39644,     0, 32768, 36864, 38912, 39424, 
+    39680, 39616, 39648, 39649, 39644,     0, 32768, 36864, 
+    38912, 39424, 39680, 39616, 39648, 39649, 39644, 39646, 
+        0, 32768, 36864, 38912, 39424, 39680, 39616,     0, 
+    32768, 36864, 38912, 39424, 39680, 39681, 39648,     0, 
+    32768, 36864, 38912, 39424, 39680, 39681, 39648,     0, 
+    32768, 36864, 38912, 39424, 39680, 39681, 39648, 39650, 
+        0, 32768, 36864, 38912, 39424, 39680, 39681, 39648, 
+        0, 32768, 36864, 38912, 39424, 39680, 39681, 39648, 
+    39652,     0, 32768, 36864, 38912, 39424, 39680, 39681, 
+    39648, 39652,     0, 32768, 36864, 38912, 39424, 39680, 
+    39681, 39648, 39656, 39654,     0, 32768, 36864, 38912, 
+    39424, 39680, 39681, 39648,     0, 32768, 36864, 38912, 
+    39424, 39680, 39681, 39648, 39656,     0, 32768, 36864, 
+    38912, 39424, 39680, 39681, 39648, 39656,     0, 32768, 
+    36864, 38912, 39424, 39680, 39681, 39648, 39656, 39658, 
+        0, 32768, 36864, 38912, 39424, 39680, 39681, 39648, 
+    39656,     0, 32768, 36864, 38912, 39424, 39680, 39681, 
+    39648, 39664, 39660,     0, 32768, 36864, 38912, 39424, 
+    39680, 39681, 39648, 39664, 39660,     0, 32768, 36864, 
+    38912, 39424, 39680, 39681, 39648, 39664, 39665, 39662, 
+        0, 32768, 36864, 38912, 39424, 39680, 39681, 39648, 
+        0, 32768, 36864, 38912, 39424, 39680, 39681, 39648, 
+    39664,     0, 32768, 36864, 38912, 39424, 39680, 39681, 
+    39683, 39664,     0, 32768, 36864, 38912, 39424, 39680, 
+    39681, 39683, 39664, 39666,     0, 32768, 36864, 38912, 
+    39424, 39680, 39681, 39683, 39664,     0, 32768, 36864, 
+    38912, 39424, 39680, 39681, 39683, 39664, 39668,     0, 
+    32768, 36864, 38912, 39424, 39680, 39681, 39683, 39664, 
+    39668,     0, 32768, 36864, 38912, 39424, 39680, 39681, 
+    39683, 39664, 39672, 39670,     0, 32768, 36864, 38912, 
+    39424, 39680, 39681, 39683, 39664,     0, 32768, 36864, 
+    38912, 39424, 39680, 39681, 39683, 39664, 39672,     0, 
+    32768, 36864, 38912, 39424, 39680, 39681, 39683, 39664, 
+    39672,     0, 32768, 36864, 38912, 39424, 39680, 39681, 
+    39683, 39664, 39672, 39674,     0, 32768, 36864, 38912, 
+    39424, 39680, 39681, 39683, 39687, 39672,     0, 32768, 
+    36864, 38912, 39424, 39680, 39681, 39683, 39687, 39672, 
+    39676,     0, 32768, 36864, 38912, 39424, 39680, 39681, 
+    39683, 39687, 39672, 39676,     0, 32768, 36864, 38912, 
+    39424, 39680, 39681, 39683, 39687, 39672, 39676, 39678, 
+        0, 32768, 36864, 38912, 39424,     0, 32768, 36864, 
+    38912, 39936, 39680,     0, 32768, 36864, 38912, 39936, 
+    39680,     0, 32768, 36864, 38912, 39936, 39680, 39682, 
+        0, 32768, 36864, 38912, 39936, 39680,     0, 32768, 
+    36864, 38912, 39936, 39680, 39684,     0, 32768, 36864, 
+    38912, 39936, 39680, 39684,     0, 32768, 36864, 38912, 
+    39936, 39680, 39688, 39686,     0, 32768, 36864, 38912, 
+    39936, 39680,     0, 32768, 36864, 38912, 39936, 39680, 
+    39688,     0, 32768, 36864, 38912, 39936, 39680, 39688, 
+        0, 32768, 36864, 38912, 39936, 39680, 39688, 39690, 
+        0, 32768, 36864, 38912, 39936, 39680, 39688,     0, 
+    32768, 36864, 38912, 39936, 39680, 39696, 39692,     0, 
+    32768, 36864, 38912, 39936, 39680, 39696, 39692,     0, 
+    32768, 36864, 38912, 39936, 39680, 39696, 39697, 39694, 
+        0, 32768, 36864, 38912, 39936, 39680,     0, 32768, 
+    36864, 38912, 39936, 39680, 39696,     0, 32768, 36864, 
+    38912, 39936, 39680, 39696,     0, 32768, 36864, 38912, 
+    39936, 39680, 39696, 39698,     0, 32768, 36864, 38912, 
+    39936, 39680, 39696,     0, 32768, 36864, 38912, 39936, 
+    39680, 39696, 39700,     0, 32768, 36864, 38912, 39936, 
+    39680, 39696, 39700,     0, 32768, 36864, 38912, 39936, 
+    39680, 39696, 39704, 39702,     0, 32768, 36864, 38912, 
+    39936, 39680, 39696,     0, 32768, 36864, 38912, 39936, 
+    39680, 39712, 39704,     0, 32768, 36864, 38912, 39936, 
+    39680, 39712, 39704,     0, 32768, 36864, 38912, 39936, 
+    39680, 39712, 39704, 39706,     0, 32768, 36864, 38912, 
+    39936, 39680, 39712, 39704,     0, 32768, 36864, 38912, 
+    39936, 39680, 39712, 39713, 39708,     0, 32768, 36864, 
+    38912, 39936, 39680, 39712, 39713, 39708,     0, 32768, 
+    36864, 38912, 39936, 39680, 39712, 39713, 39708, 39710, 
+        0, 32768, 36864, 38912, 39936, 39680,     0, 32768, 
+    36864, 38912, 39936, 39680, 39712,     0, 32768, 36864, 
+    38912, 39936, 39680, 39712,     0, 32768, 36864, 38912, 
+    39936, 39680, 39712, 39714,     0, 32768, 36864, 38912, 
+    39936, 39680, 39712,     0, 32768, 36864, 38912, 39936, 
+    39680, 39712, 39716,     0, 32768, 36864, 38912, 39936, 
+    39680, 39712, 39716,     0, 32768, 36864, 38912, 39936, 
+    39680, 39712, 39720, 39718,     0, 32768, 36864, 38912, 
+    39936, 39680, 39712,     0, 32768, 36864, 38912, 39936, 
+    39680, 39712, 39720,     0, 32768, 36864, 38912, 39936, 
+    39680, 39712, 39720,     0, 32768, 36864, 38912, 39936, 
+    39680, 39712, 39720, 39722,     0, 32768, 36864, 38912, 
+    39936, 39680, 39712, 39720,     0, 32768, 36864, 38912, 
+    39936, 39680, 39712, 39728, 39724,     0, 32768, 36864, 
+    38912, 39936, 39680, 39712, 39728, 39724,     0, 32768, 
+    36864, 38912, 39936, 39680, 39712, 39728, 39729, 39726, 
+        0, 32768, 36864, 38912, 39936, 39680, 39712,     0, 
+    32768, 36864, 38912, 39936, 39680, 39744, 39728,     0, 
+    32768, 36864, 38912, 39936, 39680, 39744, 39728,     0, 
+    32768, 36864, 38912, 39936, 39680, 39744, 39728, 39730, 
+        0, 32768, 36864, 38912, 39936, 39680, 39744, 39728, 
+        0, 32768, 36864, 38912, 39936, 39680, 39744, 39728, 
+    39732,     0, 32768, 36864, 38912, 39936, 39680, 39744, 
+    39728, 39732,     0, 32768, 36864, 38912, 39936, 39680, 
+    39744, 39728, 39736, 39734,     0, 32768, 36864, 38912, 
+    39936, 39680, 39744, 39728,     0, 32768, 36864, 38912, 
+    39936, 39680, 39744, 39745, 39736,     0, 32768, 36864, 
+    38912, 39936, 39680, 39744, 39745, 39736,     0, 32768, 
+    36864, 38912, 39936, 39680, 39744, 39745, 39736, 39738, 
+        0, 32768, 36864, 38912, 39936, 39680, 39744, 39745, 
+    39736,     0, 32768, 36864, 38912, 39936, 39680, 39744, 
+    39745, 39736, 39740,     0, 32768, 36864, 38912, 39936, 
+    39680, 39744, 39745, 39747, 39740,     0, 32768, 36864, 
+    38912, 39936, 39680, 39744, 39745, 39747, 39740, 39742, 
+        0, 32768, 36864, 38912, 39936, 39680,     0, 32768, 
+    36864, 38912, 39936, 39680, 39744,     0, 32768, 36864, 
+    38912, 39936, 39680, 39744,     0, 32768, 36864, 38912, 
+    39936, 39680, 39744, 39746,     0, 32768, 36864, 38912, 
+    39936, 39680, 39744,     0, 32768, 36864, 38912, 39936, 
+    39680, 39744, 39748,     0, 32768, 36864, 38912, 39936, 
+    39680, 39744, 39748,     0, 32768, 36864, 38912, 39936, 
+    39680, 39744, 39752, 39750,     0, 32768, 36864, 38912, 
+    39936, 39680, 39744,     0, 32768, 36864, 38912, 39936, 
+    39680, 39744, 39752,     0, 32768, 36864, 38912, 39936, 
+    39680, 39744, 39752,     0, 32768, 36864, 38912, 39936, 
+    39680, 39744, 39752, 39754,     0, 32768, 36864, 38912, 
+    39936, 39680, 39744, 39752,     0, 32768, 36864, 38912, 
+    39936, 39680, 39744, 39760, 39756,     0, 32768, 36864, 
+    38912, 39936, 39680, 39744, 39760, 39756,     0, 32768, 
+    36864, 38912, 39936, 39680, 39744, 39760, 39761, 39758, 
+        0, 32768, 36864, 38912, 39936, 39680, 39744,     0, 
+    32768, 36864, 38912, 39936, 39680, 39744, 39760,     0, 
+    32768, 36864, 38912, 39936, 39680, 39744, 39760,     0, 
+    32768, 36864, 38912, 39936, 39680, 39744, 39760, 39762, 
+        0, 32768, 36864, 38912, 39936, 39680, 39744, 39760, 
+        0, 32768, 36864, 38912, 39936, 39680, 39744, 39760, 
+    39764,     0, 32768, 36864, 38912, 39936, 39680, 39744, 
+    39760, 39764,     0, 32768, 36864, 38912, 39936, 39680, 
+    39744, 39760, 39768, 39766,     0, 32768, 36864, 38912, 
+    39936, 39680, 39744, 39760,     0, 32768, 36864, 38912, 
+    39936, 39680, 39744, 39776, 39768,     0, 32768, 36864, 
+    38912, 39936, 39680, 39744, 39776, 39768,     0, 32768, 
+    36864, 38912, 39936, 39680, 39744, 39776, 39768, 39770, 
+        0, 32768, 36864, 38912, 39936, 39680, 39744, 39776, 
+    39768,     0, 32768, 36864, 38912, 39936, 39680, 39744, 
+    39776, 39777, 39772,     0, 32768, 36864, 38912, 39936, 
+    39680, 39744, 39776, 39777, 39772,     0, 32768, 36864, 
+    38912, 39936, 39680, 39744, 39776, 39777, 39772, 39774, 
+        0, 32768, 36864, 38912, 39936, 39680, 39744,     0, 
+    32768, 36864, 38912, 39936, 39680, 39808, 39776,     0, 
+    32768, 36864, 38912, 39936, 39680, 39808, 39776,     0, 
+    32768, 36864, 38912, 39936, 39680, 39808, 39776, 39778, 
+        0, 32768, 36864, 38912, 39936, 39680, 39808, 39776, 
+        0, 32768, 36864, 38912, 39936, 39680, 39808, 39776, 
+    39780,     0, 32768, 36864, 38912, 39936, 39680, 39808, 
+    39776, 39780,     0, 32768, 36864, 38912, 39936, 39680, 
+    39808, 39776, 39784, 39782,     0, 32768, 36864, 38912, 
+    39936, 39680, 39808, 39776,     0, 32768, 36864, 38912, 
+    39936, 39680, 39808, 39776, 39784,     0, 32768, 36864, 
+    38912, 39936, 39680, 39808, 39776, 39784,     0, 32768, 
+    36864, 38912, 39936, 39680, 39808, 39776, 39784, 39786, 
+        0, 32768, 36864, 38912, 39936, 39680, 39808, 39776, 
+    39784,     0, 32768, 36864, 38912, 39936, 39680, 39808, 
+    39776, 39792, 39788,     0, 32768, 36864, 38912, 39936, 
+    39680, 39808, 39776, 39792, 39788,     0, 32768, 36864, 
+    38912, 39936, 39680, 39808, 39776, 39792, 39793, 39790, 
+        0, 32768, 36864, 38912, 39936, 39680, 39808, 39776, 
+        0, 32768, 36864, 38912, 39936, 39680, 39808, 39809, 
+    39792,     0, 32768, 36864, 38912, 39936, 39680, 39808, 
+    39809, 39792,     0, 32768, 36864, 38912, 39936, 39680, 
+    39808, 39809, 39792, 39794,     0, 32768, 36864, 38912, 
+    39936, 39680, 39808, 39809, 39792,     0, 32768, 36864, 
+    38912, 39936, 39680, 39808, 39809, 39792, 39796,     0, 
+    32768, 36864, 38912, 39936, 39680, 39808, 39809, 39792, 
+    39796,     0, 32768, 36864, 38912, 39936, 39680, 39808, 
+    39809, 39792, 39800, 39798,     0, 32768, 36864, 38912, 
+    39936, 39680, 39808, 39809, 39792,     0, 32768, 36864, 
+    38912, 39936, 39680, 39808, 39809, 39792, 39800,     0, 
+    32768, 36864, 38912, 39936, 39680, 39808, 39809, 39811, 
+    39800,     0, 32768, 36864, 38912, 39936, 39680, 39808, 
+    39809, 39811, 39800, 39802,     0, 32768, 36864, 38912, 
+    39936, 39680, 39808, 39809, 39811, 39800,     0, 32768, 
+    36864, 38912, 39936, 39680, 39808, 39809, 39811, 39800, 
+    39804,     0, 32768, 36864, 38912, 39936, 39680, 39808, 
+    39809, 39811, 39800, 39804,     0, 32768, 36864, 38912, 
+    39936, 39680, 39808, 39809, 39811, 39800, 39804, 39806, 
+        0, 32768, 36864, 38912, 39936, 39680,     0, 32768, 
+    36864, 38912, 39936, 39680, 39808,     0, 32768, 36864, 
+    38912, 39936, 39937, 39808,     0, 32768, 36864, 38912, 
+    39936, 39937, 39808, 39810,     0, 32768, 36864, 38912, 
+    39936, 39937, 39808,     0, 32768, 36864, 38912, 39936, 
+    39937, 39808, 39812,     0, 32768, 36864, 38912, 39936, 
+    39937, 39808, 39812,     0, 32768, 36864, 38912, 39936, 
+    39937, 39808, 39816, 39814,     0, 32768, 36864, 38912, 
+    39936, 39937, 39808,     0, 32768, 36864, 38912, 39936, 
+    39937, 39808, 39816,     0, 32768, 36864, 38912, 39936, 
+    39937, 39808, 39816,     0, 32768, 36864, 38912, 39936, 
+    39937, 39808, 39816, 39818,     0, 32768, 36864, 38912, 
+    39936, 39937, 39808, 39816,     0, 32768, 36864, 38912, 
+    39936, 39937, 39808, 39824, 39820,     0, 32768, 36864, 
+    38912, 39936, 39937, 39808, 39824, 39820,     0, 32768, 
+    36864, 38912, 39936, 39937, 39808, 39824, 39825, 39822, 
+        0, 32768, 36864, 38912, 39936, 39937, 39808,     0, 
+    32768, 36864, 38912, 39936, 39937, 39808, 39824,     0, 
+    32768, 36864, 38912, 39936, 39937, 39808, 39824,     0, 
+    32768, 36864, 38912, 39936, 39937, 39808, 39824, 39826, 
+        0, 32768, 36864, 38912, 39936, 39937, 39808, 39824, 
+        0, 32768, 36864, 38912, 39936, 39937, 39808, 39824, 
+    39828,     0, 32768, 36864, 38912, 39936, 39937, 39808, 
+    39824, 39828,     0, 32768, 36864, 38912, 39936, 39937, 
+    39808, 39824, 39832, 39830,     0, 32768, 36864, 38912, 
+    39936, 39937, 39808, 39824,     0, 32768, 36864, 38912, 
+    39936, 39937, 39808, 39840, 39832,     0, 32768, 36864, 
+    38912, 39936, 39937, 39808, 39840, 39832,     0, 32768, 
+    36864, 38912, 39936, 39937, 39808, 39840, 39832, 39834, 
+        0, 32768, 36864, 38912, 39936, 39937, 39808, 39840, 
+    39832,     0, 32768, 36864, 38912, 39936, 39937, 39808, 
+    39840, 39841, 39836,     0, 32768, 36864, 38912, 39936, 
+    39937, 39808, 39840, 39841, 39836,     0, 32768, 36864, 
+    38912, 39936, 39937, 39808, 39840, 39841, 39836, 39838, 
+        0, 32768, 36864, 38912, 39936, 39937, 39808,     0, 
+    32768, 36864, 38912, 39936, 39937, 39808, 39840,     0, 
+    32768, 36864, 38912, 39936, 39937, 39808, 39840,     0, 
+    32768, 36864, 38912, 39936, 39937, 39808, 39840, 39842, 
+        0, 32768, 36864, 38912, 39936, 39937, 39808, 39840, 
+        0, 32768, 36864, 38912, 39936, 39937, 39808, 39840, 
+    39844,     0, 32768, 36864, 38912, 39936, 39937, 39808, 
+    39840, 39844,     0, 32768, 36864, 38912, 39936, 39937, 
+    39808, 39840, 39848, 39846,     0, 32768, 36864, 38912, 
+    39936, 39937, 39808, 39840,     0, 32768, 36864, 38912, 
+    39936, 39937, 39808, 39840, 39848,     0, 32768, 36864, 
+    38912, 39936, 39937, 39808, 39840, 39848,     0, 32768, 
+    36864, 38912, 39936, 39937, 39808, 39840, 39848, 39850, 
+        0, 32768, 36864, 38912, 39936, 39937, 39808, 39840, 
+    39848,     0, 32768, 36864, 38912, 39936, 39937, 39808, 
+    39840, 39856, 39852,     0, 32768, 36864, 38912, 39936, 
+    39937, 39808, 39840, 39856, 39852,     0, 32768, 36864, 
+    38912, 39936, 39937, 39808, 39840, 39856, 39857, 39854, 
+        0, 32768, 36864, 38912, 39936, 39937, 39808, 39840, 
+        0, 32768, 36864, 38912, 39936, 39937, 39808, 39872, 
+    39856,     0, 32768, 36864, 38912, 39936, 39937, 39808, 
+    39872, 39856,     0, 32768, 36864, 38912, 39936, 39937, 
+    39808, 39872, 39856, 39858,     0, 32768, 36864, 38912, 
+    39936, 39937, 39808, 39872, 39856,     0, 32768, 36864, 
+    38912, 39936, 39937, 39808, 39872, 39856, 39860,     0, 
+    32768, 36864, 38912, 39936, 39937, 39808, 39872, 39856, 
+    39860,     0, 32768, 36864, 38912, 39936, 39937, 39808, 
+    39872, 39856, 39864, 39862,     0, 32768, 36864, 38912, 
+    39936, 39937, 39808, 39872, 39856,     0, 32768, 36864, 
+    38912, 39936, 39937, 39808, 39872, 39873, 39864,     0, 
+    32768, 36864, 38912, 39936, 39937, 39808, 39872, 39873, 
+    39864,     0, 32768, 36864, 38912, 39936, 39937, 39808, 
+    39872, 39873, 39864, 39866,     0, 32768, 36864, 38912, 
+    39936, 39937, 39808, 39872, 39873, 39864,     0, 32768, 
+    36864, 38912, 39936, 39937, 39808, 39872, 39873, 39864, 
+    39868,     0, 32768, 36864, 38912, 39936, 39937, 39808, 
+    39872, 39873, 39875, 39868,     0, 32768, 36864, 38912, 
+    39936, 39937, 39808, 39872, 39873, 39875, 39868, 39870, 
+        0, 32768, 36864, 38912, 39936, 39937, 39808,     0, 
+    32768, 36864, 38912, 39936, 39937, 39808, 39872,     0, 
+    32768, 36864, 38912, 39936, 39937, 39808, 39872,     0, 
+    32768, 36864, 38912, 39936, 39937, 39808, 39872, 39874, 
+        0, 32768, 36864, 38912, 39936, 39937, 39939, 39872, 
+        0, 32768, 36864, 38912, 39936, 39937, 39939, 39872, 
+    39876,     0, 32768, 36864, 38912, 39936, 39937, 39939, 
+    39872, 39876,     0, 32768, 36864, 38912, 39936, 39937, 
+    39939, 39872, 39880, 39878,     0, 32768, 36864, 38912, 
+    39936, 39937, 39939, 39872,     0, 32768, 36864, 38912, 
+    39936, 39937, 39939, 39872, 39880,     0, 32768, 36864, 
+    38912, 39936, 39937, 39939, 39872, 39880,     0, 32768, 
+    36864, 38912, 39936, 39937, 39939, 39872, 39880, 39882, 
+        0, 32768, 36864, 38912, 39936, 39937, 39939, 39872, 
+    39880,     0, 32768, 36864, 38912, 39936, 39937, 39939, 
+    39872, 39888, 39884,     0, 32768, 36864, 38912, 39936, 
+    39937, 39939, 39872, 39888, 39884,     0, 32768, 36864, 
+    38912, 39936, 39937, 39939, 39872, 39888, 39889, 39886, 
+        0, 32768, 36864, 38912, 39936, 39937, 39939, 39872, 
+        0, 32768, 36864, 38912, 39936, 39937, 39939, 39872, 
+    39888,     0, 32768, 36864, 38912, 39936, 39937, 39939, 
+    39872, 39888,     0, 32768, 36864, 38912, 39936, 39937, 
+    39939, 39872, 39888, 39890,     0, 32768, 36864, 38912, 
+    39936, 39937, 39939, 39872, 39888,     0, 32768, 36864, 
+    38912, 39936, 39937, 39939, 39872, 39888, 39892,     0, 
+    32768, 36864, 38912, 39936, 39937, 39939, 39872, 39888, 
+    39892,     0, 32768, 36864, 38912, 39936, 39937, 39939, 
+    39872, 39888, 39896, 39894,     0, 32768, 36864, 38912, 
+    39936, 39937, 39939, 39872, 39888,     0, 32768, 36864, 
+    38912, 39936, 39937, 39939, 39872, 39904, 39896,     0, 
+    32768, 36864, 38912, 39936, 39937, 39939, 39872, 39904, 
+    39896,     0, 32768, 36864, 38912, 39936, 39937, 39939, 
+    39872, 39904, 39896, 39898,     0, 32768, 36864, 38912, 
+    39936, 39937, 39939, 39872, 39904, 39896,     0, 32768, 
+    36864, 38912, 39936, 39937, 39939, 39872, 39904, 39905, 
+    39900,     0, 32768, 36864, 38912, 39936, 39937, 39939, 
+    39872, 39904, 39905, 39900,     0, 32768, 36864, 38912, 
+    39936, 39937, 39939, 39872, 39904, 39905, 39900, 39902, 
+        0, 32768, 36864, 38912, 39936, 39937, 39939, 39872, 
+        0, 32768, 36864, 38912, 39936, 39937, 39939, 39872, 
+    39904,     0, 32768, 36864, 38912, 39936, 39937, 39939, 
+    39872, 39904,     0, 32768, 36864, 38912, 39936, 39937, 
+    39939, 39872, 39904, 39906,     0, 32768, 36864, 38912, 
+    39936, 39937, 39939, 39872, 39904,     0, 32768, 36864, 
+    38912, 39936, 39937, 39939, 39872, 39904, 39908,     0, 
+    32768, 36864, 38912, 39936, 39937, 39939, 39872, 39904, 
+    39908,     0, 32768, 36864, 38912, 39936, 39937, 39939, 
+    39872, 39904, 39912, 39910,     0, 32768, 36864, 38912, 
+    39936, 39937, 39939, 39943, 39904,     0, 32768, 36864, 
+    38912, 39936, 39937, 39939, 39943, 39904, 39912,     0, 
+    32768, 36864, 38912, 39936, 39937, 39939, 39943, 39904, 
+    39912,     0, 32768, 36864, 38912, 39936, 39937, 39939, 
+    39943, 39904, 39912, 39914,     0, 32768, 36864, 38912, 
+    39936, 39937, 39939, 39943, 39904, 39912,     0, 32768, 
+    36864, 38912, 39936, 39937, 39939, 39943, 39904, 39920, 
+    39916,     0, 32768, 36864, 38912, 39936, 39937, 39939, 
+    39943, 39904, 39920, 39916,     0, 32768, 36864, 38912, 
+    39936, 39937, 39939, 39943, 39904, 39920, 39921, 39918, 
+        0, 32768, 36864, 38912, 39936, 39937, 39939, 39943, 
+    39904,     0, 32768, 36864, 38912, 39936, 39937, 39939, 
+    39943, 39904, 39920,     0, 32768, 36864, 38912, 39936, 
+    39937, 39939, 39943, 39904, 39920,     0, 32768, 36864, 
+    38912, 39936, 39937, 39939, 39943, 39904, 39920, 39922, 
+        0, 32768, 36864, 38912, 39936, 39937, 39939, 39943, 
+    39904, 39920,     0, 32768, 36864, 38912, 39936, 39937, 
+    39939, 39943, 39904, 39920, 39924,     0, 32768, 36864, 
+    38912, 39936, 39937, 39939, 39943, 39904, 39920, 39924, 
+        0, 32768, 36864, 38912, 39936, 39937, 39939, 39943, 
+    39904, 39920, 39928, 39926,     0, 32768, 36864, 38912, 
+    39936, 39937, 39939, 39943, 39904, 39920,     0, 32768, 
+    36864, 38912, 39936, 39937, 39939, 39943, 39904, 39920, 
+    39928,     0, 32768, 36864, 38912, 39936, 39937, 39939, 
+    39943, 39904, 39920, 39928,     0, 32768, 36864, 38912, 
+    39936, 39937, 39939, 39943, 39904, 39920, 39928, 39930, 
+        0, 32768, 36864, 38912, 39936, 39937, 39939, 39943, 
+    39904, 39920, 39928,     0, 32768, 36864, 38912, 39936, 
+    39937, 39939, 39943, 39904, 39920, 39928, 39932,     0, 
+    32768, 36864, 38912, 39936, 39937, 39939, 39943, 39904, 
+    39920, 39928, 39932,     0, 32768, 36864, 38912, 39936, 
+    39937, 39939, 39943, 39904, 39920, 39928, 39932, 39934, 
+        0, 32768, 36864, 38912,     0, 32768, 36864, 38912, 
+    39936,     0, 32768, 36864, 38912, 39936,     0, 32768, 
+    36864, 38912, 39936, 39938,     0, 32768, 36864, 38912, 
+    39936,     0, 32768, 36864, 38912, 39936, 39940,     0, 
+    32768, 36864, 38912, 39936, 39940,     0, 32768, 36864, 
+    38912, 39936, 39944, 39942,     0, 32768, 36864, 38912, 
+    39936,     0, 32768, 36864, 38912, 39936, 39944,     0, 
+    32768, 36864, 38912, 39936, 39944,     0, 32768, 36864, 
+    38912, 39936, 39944, 39946,     0, 32768, 36864, 38912, 
+    39936, 39944,     0, 32768, 36864, 38912, 39936, 39952, 
+    39948,     0, 32768, 36864, 38912, 39936, 39952, 39948, 
+        0, 32768, 36864, 38912, 39936, 39952, 39953, 39950, 
+        0, 32768, 36864, 38912, 39936,     0, 32768, 36864, 
+    38912, 39936, 39952,     0, 32768, 36864, 38912, 39936, 
+    39952,     0, 32768, 36864, 38912, 39936, 39952, 39954, 
+        0, 32768, 36864, 38912, 39936, 39952,     0, 32768, 
+    36864, 38912, 39936, 39952, 39956,     0, 32768, 36864, 
+    38912, 39936, 39952, 39956,     0, 32768, 36864, 38912, 
+    39936, 39952, 39960, 39958,     0, 32768, 36864, 38912, 
+    39936, 39952,     0, 32768, 36864, 38912, 39936, 39968, 
+    39960,     0, 32768, 36864, 38912, 39936, 39968, 39960, 
+        0, 32768, 36864, 38912, 39936, 39968, 39960, 39962, 
+        0, 32768, 36864, 38912, 39936, 39968, 39960,     0, 
+    32768, 36864, 38912, 39936, 39968, 39969, 39964,     0, 
+    32768, 36864, 38912, 39936, 39968, 39969, 39964,     0, 
+    32768, 36864, 38912, 39936, 39968, 39969, 39964, 39966, 
+        0, 32768, 36864, 38912, 39936,     0, 32768, 36864, 
+    38912, 39936, 39968,     0, 32768, 36864, 38912, 39936, 
+    39968,     0, 32768, 36864, 38912, 39936, 39968, 39970, 
+        0, 32768, 36864, 38912, 39936, 39968,     0, 32768, 
+    36864, 38912, 39936, 39968, 39972,     0, 32768, 36864, 
+    38912, 39936, 39968, 39972,     0, 32768, 36864, 38912, 
+    39936, 39968, 39976, 39974,     0, 32768, 36864, 38912, 
+    39936, 39968,     0, 32768, 36864, 38912, 39936, 39968, 
+    39976,     0, 32768, 36864, 38912, 39936, 39968, 39976, 
+        0, 32768, 36864, 38912, 39936, 39968, 39976, 39978, 
+        0, 32768, 36864, 38912, 39936, 39968, 39976,     0, 
+    32768, 36864, 38912, 39936, 39968, 39984, 39980,     0, 
+    32768, 36864, 38912, 39936, 39968, 39984, 39980,     0, 
+    32768, 36864, 38912, 39936, 39968, 39984, 39985, 39982, 
+        0, 32768, 36864, 38912, 39936, 39968,     0, 32768, 
+    36864, 38912, 39936, 40000, 39984,     0, 32768, 36864, 
+    38912, 39936, 40000, 39984,     0, 32768, 36864, 38912, 
+    39936, 40000, 39984, 39986,     0, 32768, 36864, 38912, 
+    39936, 40000, 39984,     0, 32768, 36864, 38912, 39936, 
+    40000, 39984, 39988,     0, 32768, 36864, 38912, 39936, 
+    40000, 39984, 39988,     0, 32768, 36864, 38912, 39936, 
+    40000, 39984, 39992, 39990,     0, 32768, 36864, 38912, 
+    39936, 40000, 39984,     0, 32768, 36864, 38912, 39936, 
+    40000, 40001, 39992,     0, 32768, 36864, 38912, 39936, 
+    40000, 40001, 39992,     0, 32768, 36864, 38912, 39936, 
+    40000, 40001, 39992, 39994,     0, 32768, 36864, 38912, 
+    39936, 40000, 40001, 39992,     0, 32768, 36864, 38912, 
+    39936, 40000, 40001, 39992, 39996,     0, 32768, 36864, 
+    38912, 39936, 40000, 40001, 40003, 39996,     0, 32768, 
+    36864, 38912, 39936, 40000, 40001, 40003, 39996, 39998, 
+        0, 32768, 36864, 38912, 39936,     0, 32768, 40960, 
+    38912, 39936, 40000,     0, 32768, 40960, 38912, 39936, 
+    40000,     0, 32768, 40960, 38912, 39936, 40000, 40002, 
+        0, 32768, 40960, 38912, 39936, 40000,     0, 32768, 
+    40960, 38912, 39936, 40000, 40004,     0, 32768, 40960, 
+    38912, 39936, 40000, 40004,     0, 32768, 40960, 38912, 
+    39936, 40000, 40008, 40006,     0, 32768, 40960, 38912, 
+    39936, 40000,     0, 32768, 40960, 38912, 39936, 40000, 
+    40008,     0, 32768, 40960, 38912, 39936, 40000, 40008, 
+        0, 32768, 40960, 38912, 39936, 40000, 40008, 40010, 
+        0, 32768, 40960, 38912, 39936, 40000, 40008,     0, 
+    32768, 40960, 38912, 39936, 40000, 40016, 40012,     0, 
+    32768, 40960, 38912, 39936, 40000, 40016, 40012,     0, 
+    32768, 40960, 38912, 39936, 40000, 40016, 40017, 40014, 
+        0, 32768, 40960, 38912, 39936, 40000,     0, 32768, 
+    40960, 38912, 39936, 40000, 40016,     0, 32768, 40960, 
+    38912, 39936, 40000, 40016,     0, 32768, 40960, 38912, 
+    39936, 40000, 40016, 40018,     0, 32768, 40960, 38912, 
+    39936, 40000, 40016,     0, 32768, 40960, 38912, 39936, 
+    40000, 40016, 40020,     0, 32768, 40960, 38912, 39936, 
+    40000, 40016, 40020,     0, 32768, 40960, 38912, 39936, 
+    40000, 40016, 40024, 40022,     0, 32768, 40960, 38912, 
+    39936, 40000, 40016,     0, 32768, 40960, 38912, 39936, 
+    40000, 40032, 40024,     0, 32768, 40960, 38912, 39936, 
+    40000, 40032, 40024,     0, 32768, 40960, 38912, 39936, 
+    40000, 40032, 40024, 40026,     0, 32768, 40960, 38912, 
+    39936, 40000, 40032, 40024,     0, 32768, 40960, 38912, 
+    39936, 40000, 40032, 40033, 40028,     0, 32768, 40960, 
+    38912, 39936, 40000, 40032, 40033, 40028,     0, 32768, 
+    40960, 38912, 39936, 40000, 40032, 40033, 40028, 40030, 
+        0, 32768, 40960, 38912, 39936, 40000,     0, 32768, 
+    40960, 38912, 39936, 40064, 40032,     0, 32768, 40960, 
+    38912, 39936, 40064, 40032,     0, 32768, 40960, 38912, 
+    39936, 40064, 40032, 40034,     0, 32768, 40960, 38912, 
+    39936, 40064, 40032,     0, 32768, 40960, 38912, 39936, 
+    40064, 40032, 40036,     0, 32768, 40960, 38912, 39936, 
+    40064, 40032, 40036,     0, 32768, 40960, 38912, 39936, 
+    40064, 40032, 40040, 40038,     0, 32768, 40960, 38912, 
+    39936, 40064, 40032,     0, 32768, 40960, 38912, 39936, 
+    40064, 40032, 40040,     0, 32768, 40960, 38912, 39936, 
+    40064, 40032, 40040,     0, 32768, 40960, 38912, 39936, 
+    40064, 40032, 40040, 40042,     0, 32768, 40960, 38912, 
+    39936, 40064, 40032, 40040,     0, 32768, 40960, 38912, 
+    39936, 40064, 40032, 40048, 40044,     0, 32768, 40960, 
+    38912, 39936, 40064, 40032, 40048, 40044,     0, 32768, 
+    40960, 38912, 39936, 40064, 40032, 40048, 40049, 40046, 
+        0, 32768, 40960, 38912, 39936, 40064, 40032,     0, 
+    32768, 40960, 38912, 39936, 40064, 40065, 40048,     0, 
+    32768, 40960, 38912, 39936, 40064, 40065, 40048,     0, 
+    32768, 40960, 38912, 39936, 40064, 40065, 40048, 40050, 
+        0, 32768, 40960, 38912, 39936, 40064, 40065, 40048, 
+        0, 32768, 40960, 38912, 39936, 40064, 40065, 40048, 
+    40052,     0, 32768, 40960, 38912, 39936, 40064, 40065, 
+    40048, 40052,     0, 32768, 40960, 38912, 39936, 40064, 
+    40065, 40048, 40056, 40054,     0, 32768, 40960, 38912, 
+    39936, 40064, 40065, 40048,     0, 32768, 40960, 38912, 
+    39936, 40064, 40065, 40048, 40056,     0, 32768, 40960, 
+    38912, 39936, 40064, 40065, 40067, 40056,     0, 32768, 
+    40960, 38912, 39936, 40064, 40065, 40067, 40056, 40058, 
+        0, 32768, 40960, 38912, 39936, 40064, 40065, 40067, 
+    40056,     0, 32768, 40960, 38912, 39936, 40064, 40065, 
+    40067, 40056, 40060,     0, 32768, 40960, 38912, 39936, 
+    40064, 40065, 40067, 40056, 40060,     0, 32768, 40960, 
+    38912, 39936, 40064, 40065, 40067, 40056, 40060, 40062, 
+        0, 32768, 40960, 38912, 39936,     0, 32768, 40960, 
+    38912, 39936, 40064,     0, 32768, 40960, 38912, 39936, 
+    40064,     0, 32768, 40960, 38912, 39936, 40064, 40066, 
+        0, 32768, 40960, 38912, 39936, 40064,     0, 32768, 
+    40960, 38912, 39936, 40064, 40068,     0, 32768, 40960, 
+    38912, 39936, 40064, 40068,     0, 32768, 40960, 38912, 
+    39936, 40064, 40072, 40070,     0, 32768, 40960, 38912, 
+    39936, 40064,     0, 32768, 40960, 38912, 39936, 40064, 
+    40072,     0, 32768, 40960, 38912, 39936, 40064, 40072, 
+        0, 32768, 40960, 38912, 39936, 40064, 40072, 40074, 
+        0, 32768, 40960, 38912, 39936, 40064, 40072,     0, 
+    32768, 40960, 38912, 39936, 40064, 40080, 40076,     0, 
+    32768, 40960, 38912, 39936, 40064, 40080, 40076,     0, 
+    32768, 40960, 38912, 39936, 40064, 40080, 40081, 40078, 
+        0, 32768, 40960, 38912, 39936, 40064,     0, 32768, 
+    40960, 38912, 39936, 40064, 40080,     0, 32768, 40960, 
+    38912, 39936, 40064, 40080,     0, 32768, 40960, 38912, 
+    39936, 40064, 40080, 40082,     0, 32768, 40960, 38912, 
+    39936, 40064, 40080,     0, 32768, 40960, 38912, 39936, 
+    40064, 40080, 40084,     0, 32768, 40960, 38912, 39936, 
+    40064, 40080, 40084,     0, 32768, 40960, 38912, 39936, 
+    40064, 40080, 40088, 40086,     0, 32768, 40960, 38912, 
+    39936, 40064, 40080,     0, 32768, 40960, 38912, 39936, 
+    40064, 40096, 40088,     0, 32768, 40960, 38912, 39936, 
+    40064, 40096, 40088,     0, 32768, 40960, 38912, 39936, 
+    40064, 40096, 40088, 40090,     0, 32768, 40960, 38912, 
+    39936, 40064, 40096, 40088,     0, 32768, 40960, 38912, 
+    39936, 40064, 40096, 40097, 40092,     0, 32768, 40960, 
+    38912, 39936, 40064, 40096, 40097, 40092,     0, 32768, 
+    40960, 38912, 39936, 40064, 40096, 40097, 40092, 40094, 
+        0, 32768, 40960, 38912, 39936, 40064,     0, 32768, 
+    40960, 38912, 39936, 40064, 40096,     0, 32768, 40960, 
+    38912, 39936, 40064, 40096,     0, 32768, 40960, 38912, 
+    39936, 40064, 40096, 40098,     0, 32768, 40960, 38912, 
+    39936, 40064, 40096,     0, 32768, 40960, 38912, 39936, 
+    40064, 40096, 40100,     0, 32768, 40960, 38912, 39936, 
+    40064, 40096, 40100,     0, 32768, 40960, 38912, 39936, 
+    40064, 40096, 40104, 40102,     0, 32768, 40960, 38912, 
+    39936, 40064, 40096,     0, 32768, 40960, 38912, 39936, 
+    40064, 40096, 40104,     0, 32768, 40960, 38912, 39936, 
+    40064, 40096, 40104,     0, 32768, 40960, 38912, 39936, 
+    40064, 40096, 40104, 40106,     0, 32768, 40960, 38912, 
+    39936, 40064, 40096, 40104,     0, 32768, 40960, 38912, 
+    39936, 40064, 40096, 40112, 40108,     0, 32768, 40960, 
+    38912, 39936, 40064, 40096, 40112, 40108,     0, 32768, 
+    40960, 38912, 39936, 40064, 40096, 40112, 40113, 40110, 
+        0, 32768, 40960, 38912, 39936, 40064, 40096,     0, 
+    32768, 40960, 38912, 39936, 40064, 40128, 40112,     0, 
+    32768, 40960, 38912, 39936, 40064, 40128, 40112,     0, 
+    32768, 40960, 38912, 39936, 40064, 40128, 40112, 40114, 
+        0, 32768, 40960, 38912, 39936, 40064, 40128, 40112, 
+        0, 32768, 40960, 38912, 39936, 40064, 40128, 40112, 
+    40116,     0, 32768, 40960, 38912, 39936, 40064, 40128, 
+    40112, 40116,     0, 32768, 40960, 38912, 39936, 40064, 
+    40128, 40112, 40120, 40118,     0, 32768, 40960, 38912, 
+    39936, 40064, 40128, 40112,     0, 32768, 40960, 38912, 
+    39936, 40064, 40128, 40129, 40120,     0, 32768, 40960, 
+    38912, 39936, 40064, 40128, 40129, 40120,     0, 32768, 
+    40960, 38912, 39936, 40064, 40128, 40129, 40120, 40122, 
+        0, 32768, 40960, 38912, 39936, 40064, 40128, 40129, 
+    40120,     0, 32768, 40960, 38912, 39936, 40064, 40128, 
+    40129, 40120, 40124,     0, 32768, 40960, 38912, 39936, 
+    40064, 40128, 40129, 40131, 40124,     0, 32768, 40960, 
+    38912, 39936, 40064, 40128, 40129, 40131, 40124, 40126, 
+        0, 32768, 40960, 38912, 39936, 40064,     0, 32768, 
+    40960, 38912, 39936, 40192, 40128,     0, 32768, 40960, 
+    38912, 39936, 40192, 40128,     0, 32768, 40960, 38912, 
+    39936, 40192, 40128, 40130,     0, 32768, 40960, 38912, 
+    39936, 40192, 40128,     0, 32768, 40960, 38912, 39936, 
+    40192, 40128, 40132,     0, 32768, 40960, 38912, 39936, 
+    40192, 40128, 40132,     0, 32768, 40960, 38912, 39936, 
+    40192, 40128, 40136, 40134,     0, 32768, 40960, 38912, 
+    39936, 40192, 40128,     0, 32768, 40960, 38912, 39936, 
+    40192, 40128, 40136,     0, 32768, 40960, 38912, 39936, 
+    40192, 40128, 40136,     0, 32768, 40960, 38912, 39936, 
+    40192, 40128, 40136, 40138,     0, 32768, 40960, 38912, 
+    39936, 40192, 40128, 40136,     0, 32768, 40960, 38912, 
+    39936, 40192, 40128, 40144, 40140,     0, 32768, 40960, 
+    38912, 39936, 40192, 40128, 40144, 40140,     0, 32768, 
+    40960, 38912, 39936, 40192, 40128, 40144, 40145, 40142, 
+        0, 32768, 40960, 38912, 39936, 40192, 40128,     0, 
+    32768, 40960, 38912, 39936, 40192, 40128, 40144,     0, 
+    32768, 40960, 38912, 39936, 40192, 40128, 40144,     0, 
+    32768, 40960, 38912, 39936, 40192, 40128, 40144, 40146, 
+        0, 32768, 40960, 38912, 39936, 40192, 40128, 40144, 
+        0, 32768, 40960, 38912, 39936, 40192, 40128, 40144, 
+    40148,     0, 32768, 40960, 38912, 39936, 40192, 40128, 
+    40144, 40148,     0, 32768, 40960, 38912, 39936, 40192, 
+    40128, 40144, 40152, 40150,     0, 32768, 40960, 38912, 
+    39936, 40192, 40128, 40144,     0, 32768, 40960, 38912, 
+    39936, 40192, 40128, 40160, 40152,     0, 32768, 40960, 
+    38912, 39936, 40192, 40128, 40160, 40152,     0, 32768, 
+    40960, 38912, 39936, 40192, 40128, 40160, 40152, 40154, 
+        0, 32768, 40960, 38912, 39936, 40192, 40128, 40160, 
+    40152,     0, 32768, 40960, 38912, 39936, 40192, 40128, 
+    40160, 40161, 40156,     0, 32768, 40960, 38912, 39936, 
+    40192, 40128, 40160, 40161, 40156,     0, 32768, 40960, 
+    38912, 39936, 40192, 40128, 40160, 40161, 40156, 40158, 
+        0, 32768, 40960, 38912, 39936, 40192, 40128,     0, 
+    32768, 40960, 38912, 39936, 40192, 40193, 40160,     0, 
+    32768, 40960, 38912, 39936, 40192, 40193, 40160,     0, 
+    32768, 40960, 38912, 39936, 40192, 40193, 40160, 40162, 
+        0, 32768, 40960, 38912, 39936, 40192, 40193, 40160, 
+        0, 32768, 40960, 38912, 39936, 40192, 40193, 40160, 
+    40164,     0, 32768, 40960, 38912, 39936, 40192, 40193, 
+    40160, 40164,     0, 32768, 40960, 38912, 39936, 40192, 
+    40193, 40160, 40168, 40166,     0, 32768, 40960, 38912, 
+    39936, 40192, 40193, 40160,     0, 32768, 40960, 38912, 
+    39936, 40192, 40193, 40160, 40168,     0, 32768, 40960, 
+    38912, 39936, 40192, 40193, 40160, 40168,     0, 32768, 
+    40960, 38912, 39936, 40192, 40193, 40160, 40168, 40170, 
+        0, 32768, 40960, 38912, 39936, 40192, 40193, 40160, 
+    40168,     0, 32768, 40960, 38912, 39936, 40192, 40193, 
+    40160, 40176, 40172,     0, 32768, 40960, 38912, 39936, 
+    40192, 40193, 40160, 40176, 40172,     0, 32768, 40960, 
+    38912, 39936, 40192, 40193, 40160, 40176, 40177, 40174, 
+        0, 32768, 40960, 38912, 39936, 40192, 40193, 40160, 
+        0, 32768, 40960, 38912, 39936, 40192, 40193, 40160, 
+    40176,     0, 32768, 40960, 38912, 39936, 40192, 40193, 
+    40195, 40176,     0, 32768, 40960, 38912, 39936, 40192, 
+    40193, 40195, 40176, 40178,     0, 32768, 40960, 38912, 
+    39936, 40192, 40193, 40195, 40176,     0, 32768, 40960, 
+    38912, 39936, 40192, 40193, 40195, 40176, 40180,     0, 
+    32768, 40960, 38912, 39936, 40192, 40193, 40195, 40176, 
+    40180,     0, 32768, 40960, 38912, 39936, 40192, 40193, 
+    40195, 40176, 40184, 40182,     0, 32768, 40960, 38912, 
+    39936, 40192, 40193, 40195, 40176,     0, 32768, 40960, 
+    38912, 39936, 40192, 40193, 40195, 40176, 40184,     0, 
+    32768, 40960, 38912, 39936, 40192, 40193, 40195, 40176, 
+    40184,     0, 32768, 40960, 38912, 39936, 40192, 40193, 
+    40195, 40176, 40184, 40186,     0, 32768, 40960, 38912, 
+    39936, 40192, 40193, 40195, 40199, 40184,     0, 32768, 
+    40960, 38912, 39936, 40192, 40193, 40195, 40199, 40184, 
+    40188,     0, 32768, 40960, 38912, 39936, 40192, 40193, 
+    40195, 40199, 40184, 40188,     0, 32768, 40960, 38912, 
+    39936, 40192, 40193, 40195, 40199, 40184, 40188, 40190, 
+        0, 32768, 40960, 38912, 39936,     0, 32768, 40960, 
+    38912, 39936, 40192,     0, 32768, 40960, 40961, 39936, 
+    40192,     0, 32768, 40960, 40961, 39936, 40192, 40194, 
+        0, 32768, 40960, 40961, 39936, 40192,     0, 32768, 
+    40960, 40961, 39936, 40192, 40196,     0, 32768, 40960, 
+    40961, 39936, 40192, 40196,     0, 32768, 40960, 40961, 
+    39936, 40192, 40200, 40198,     0, 32768, 40960, 40961, 
+    39936, 40192,     0, 32768, 40960, 40961, 39936, 40192, 
+    40200,     0, 32768, 40960, 40961, 39936, 40192, 40200, 
+        0, 32768, 40960, 40961, 39936, 40192, 40200, 40202, 
+        0, 32768, 40960, 40961, 39936, 40192, 40200,     0, 
+    32768, 40960, 40961, 39936, 40192, 40208, 40204,     0, 
+    32768, 40960, 40961, 39936, 40192, 40208, 40204,     0, 
+    32768, 40960, 40961, 39936, 40192, 40208, 40209, 40206, 
+        0, 32768, 40960, 40961, 39936, 40192,     0, 32768, 
+    40960, 40961, 39936, 40192, 40208,     0, 32768, 40960, 
+    40961, 39936, 40192, 40208,     0, 32768, 40960, 40961, 
+    39936, 40192, 40208, 40210,     0, 32768, 40960, 40961, 
+    39936, 40192, 40208,     0, 32768, 40960, 40961, 39936, 
+    40192, 40208, 40212,     0, 32768, 40960, 40961, 39936, 
+    40192, 40208, 40212,     0, 32768, 40960, 40961, 39936, 
+    40192, 40208, 40216, 40214,     0, 32768, 40960, 40961, 
+    39936, 40192, 40208,     0, 32768, 40960, 40961, 39936, 
+    40192, 40224, 40216,     0, 32768, 40960, 40961, 39936, 
+    40192, 40224, 40216,     0, 32768, 40960, 40961, 39936, 
+    40192, 40224, 40216, 40218,     0, 32768, 40960, 40961, 
+    39936, 40192, 40224, 40216,     0, 32768, 40960, 40961, 
+    39936, 40192, 40224, 40225, 40220,     0, 32768, 40960, 
+    40961, 39936, 40192, 40224, 40225, 40220,     0, 32768, 
+    40960, 40961, 39936, 40192, 40224, 40225, 40220, 40222, 
+        0, 32768, 40960, 40961, 39936, 40192,     0, 32768, 
+    40960, 40961, 39936, 40192, 40224,     0, 32768, 40960, 
+    40961, 39936, 40192, 40224,     0, 32768, 40960, 40961, 
+    39936, 40192, 40224, 40226,     0, 32768, 40960, 40961, 
+    39936, 40192, 40224,     0, 32768, 40960, 40961, 39936, 
+    40192, 40224, 40228,     0, 32768, 40960, 40961, 39936, 
+    40192, 40224, 40228,     0, 32768, 40960, 40961, 39936, 
+    40192, 40224, 40232, 40230,     0, 32768, 40960, 40961, 
+    39936, 40192, 40224,     0, 32768, 40960, 40961, 39936, 
+    40192, 40224, 40232,     0, 32768, 40960, 40961, 39936, 
+    40192, 40224, 40232,     0, 32768, 40960, 40961, 39936, 
+    40192, 40224, 40232, 40234,     0, 32768, 40960, 40961, 
+    39936, 40192, 40224, 40232,     0, 32768, 40960, 40961, 
+    39936, 40192, 40224, 40240, 40236,     0, 32768, 40960, 
+    40961, 39936, 40192, 40224, 40240, 40236,     0, 32768, 
+    40960, 40961, 39936, 40192, 40224, 40240, 40241, 40238, 
+        0, 32768, 40960, 40961, 39936, 40192, 40224,     0, 
+    32768, 40960, 40961, 39936, 40192, 40256, 40240,     0, 
+    32768, 40960, 40961, 39936, 40192, 40256, 40240,     0, 
+    32768, 40960, 40961, 39936, 40192, 40256, 40240, 40242, 
+        0, 32768, 40960, 40961, 39936, 40192, 40256, 40240, 
+        0, 32768, 40960, 40961, 39936, 40192, 40256, 40240, 
+    40244,     0, 32768, 40960, 40961, 39936, 40192, 40256, 
+    40240, 40244,     0, 32768, 40960, 40961, 39936, 40192, 
+    40256, 40240, 40248, 40246,     0, 32768, 40960, 40961, 
+    39936, 40192, 40256, 40240,     0, 32768, 40960, 40961, 
+    39936, 40192, 40256, 40257, 40248,     0, 32768, 40960, 
+    40961, 39936, 40192, 40256, 40257, 40248,     0, 32768, 
+    40960, 40961, 39936, 40192, 40256, 40257, 40248, 40250, 
+        0, 32768, 40960, 40961, 39936, 40192, 40256, 40257, 
+    40248,     0, 32768, 40960, 40961, 39936, 40192, 40256, 
+    40257, 40248, 40252,     0, 32768, 40960, 40961, 39936, 
+    40192, 40256, 40257, 40259, 40252,     0, 32768, 40960, 
+    40961, 39936, 40192, 40256, 40257, 40259, 40252, 40254, 
+        0, 32768, 40960, 40961, 39936, 40192,     0, 32768, 
+    40960, 40961, 39936, 40192, 40256,     0, 32768, 40960, 
+    40961, 39936, 40192, 40256,     0, 32768, 40960, 40961, 
+    39936, 40192, 40256, 40258,     0, 32768, 40960, 40961, 
+    39936, 40192, 40256,     0, 32768, 40960, 40961, 39936, 
+    40192, 40256, 40260,     0, 32768, 40960, 40961, 39936, 
+    40192, 40256, 40260,     0, 32768, 40960, 40961, 39936, 
+    40192, 40256, 40264, 40262,     0, 32768, 40960, 40961, 
+    39936, 40192, 40256,     0, 32768, 40960, 40961, 39936, 
+    40192, 40256, 40264,     0, 32768, 40960, 40961, 39936, 
+    40192, 40256, 40264,     0, 32768, 40960, 40961, 39936, 
+    40192, 40256, 40264, 40266,     0, 32768, 40960, 40961, 
+    39936, 40192, 40256, 40264,     0, 32768, 40960, 40961, 
+    39936, 40192, 40256, 40272, 40268,     0, 32768, 40960, 
+    40961, 39936, 40192, 40256, 40272, 40268,     0, 32768, 
+    40960, 40961, 39936, 40192, 40256, 40272, 40273, 40270, 
+        0, 32768, 40960, 40961, 39936, 40192, 40256,     0, 
+    32768, 40960, 40961, 39936, 40192, 40256, 40272,     0, 
+    32768, 40960, 40961, 39936, 40192, 40256, 40272,     0, 
+    32768, 40960, 40961, 39936, 40192, 40256, 40272, 40274, 
+        0, 32768, 40960, 40961, 39936, 40192, 40256, 40272, 
+        0, 32768, 40960, 40961, 39936, 40192, 40256, 40272, 
+    40276,     0, 32768, 40960, 40961, 39936, 40192, 40256, 
+    40272, 40276,     0, 32768, 40960, 40961, 39936, 40192, 
+    40256, 40272, 40280, 40278,     0, 32768, 40960, 40961, 
+    39936, 40192, 40256, 40272,     0, 32768, 40960, 40961, 
+    39936, 40192, 40256, 40288, 40280,     0, 32768, 40960, 
+    40961, 39936, 40192, 40256, 40288, 40280,     0, 32768, 
+    40960, 40961, 39936, 40192, 40256, 40288, 40280, 40282, 
+        0, 32768, 40960, 40961, 39936, 40192, 40256, 40288, 
+    40280,     0, 32768, 40960, 40961, 39936, 40192, 40256, 
+    40288, 40289, 40284,     0, 32768, 40960, 40961, 39936, 
+    40192, 40256, 40288, 40289, 40284,     0, 32768, 40960, 
+    40961, 39936, 40192, 40256, 40288, 40289, 40284, 40286, 
+        0, 32768, 40960, 40961, 39936, 40192, 40256,     0, 
+    32768, 40960, 40961, 39936, 40192, 40320, 40288,     0, 
+    32768, 40960, 40961, 39936, 40192, 40320, 40288,     0, 
+    32768, 40960, 40961, 39936, 40192, 40320, 40288, 40290, 
+        0, 32768, 40960, 40961, 39936, 40192, 40320, 40288, 
+        0, 32768, 40960, 40961, 39936, 40192, 40320, 40288, 
+    40292,     0, 32768, 40960, 40961, 39936, 40192, 40320, 
+    40288, 40292,     0, 32768, 40960, 40961, 39936, 40192, 
+    40320, 40288, 40296, 40294,     0, 32768, 40960, 40961, 
+    39936, 40192, 40320, 40288,     0, 32768, 40960, 40961, 
+    39936, 40192, 40320, 40288, 40296,     0, 32768, 40960, 
+    40961, 39936, 40192, 40320, 40288, 40296,     0, 32768, 
+    40960, 40961, 39936, 40192, 40320, 40288, 40296, 40298, 
+        0, 32768, 40960, 40961, 39936, 40192, 40320, 40288, 
+    40296,     0, 32768, 40960, 40961, 39936, 40192, 40320, 
+    40288, 40304, 40300,     0, 32768, 40960, 40961, 39936, 
+    40192, 40320, 40288, 40304, 40300,     0, 32768, 40960, 
+    40961, 39936, 40192, 40320, 40288, 40304, 40305, 40302, 
+        0, 32768, 40960, 40961, 39936, 40192, 40320, 40288, 
+        0, 32768, 40960, 40961, 39936, 40192, 40320, 40321, 
+    40304,     0, 32768, 40960, 40961, 39936, 40192, 40320, 
+    40321, 40304,     0, 32768, 40960, 40961, 39936, 40192, 
+    40320, 40321, 40304, 40306,     0, 32768, 40960, 40961, 
+    39936, 40192, 40320, 40321, 40304,     0, 32768, 40960, 
+    40961, 39936, 40192, 40320, 40321, 40304, 40308,     0, 
+    32768, 40960, 40961, 39936, 40192, 40320, 40321, 40304, 
+    40308,     0, 32768, 40960, 40961, 39936, 40192, 40320, 
+    40321, 40304, 40312, 40310,     0, 32768, 40960, 40961, 
+    39936, 40192, 40320, 40321, 40304,     0, 32768, 40960, 
+    40961, 39936, 40192, 40320, 40321, 40304, 40312,     0, 
+    32768, 40960, 40961, 39936, 40192, 40320, 40321, 40323, 
+    40312,     0, 32768, 40960, 40961, 39936, 40192, 40320, 
+    40321, 40323, 40312, 40314,     0, 32768, 40960, 40961, 
+    39936, 40192, 40320, 40321, 40323, 40312,     0, 32768, 
+    40960, 40961, 39936, 40192, 40320, 40321, 40323, 40312, 
+    40316,     0, 32768, 40960, 40961, 39936, 40192, 40320, 
+    40321, 40323, 40312, 40316,     0, 32768, 40960, 40961, 
+    39936, 40192, 40320, 40321, 40323, 40312, 40316, 40318, 
+        0, 32768, 40960, 40961, 39936, 40192,     0, 32768, 
+    40960, 40961, 39936, 40448, 40320,     0, 32768, 40960, 
+    40961, 39936, 40448, 40320,     0, 32768, 40960, 40961, 
+    39936, 40448, 40320, 40322,     0, 32768, 40960, 40961, 
+    39936, 40448, 40320,     0, 32768, 40960, 40961, 39936, 
+    40448, 40320, 40324,     0, 32768, 40960, 40961, 39936, 
+    40448, 40320, 40324,     0, 32768, 40960, 40961, 39936, 
+    40448, 40320, 40328, 40326,     0, 32768, 40960, 40961, 
+    39936, 40448, 40320,     0, 32768, 40960, 40961, 39936, 
+    40448, 40320, 40328,     0, 32768, 40960, 40961, 39936, 
+    40448, 40320, 40328,     0, 32768, 40960, 40961, 39936, 
+    40448, 40320, 40328, 40330,     0, 32768, 40960, 40961, 
+    39936, 40448, 40320, 40328,     0, 32768, 40960, 40961, 
+    39936, 40448, 40320, 40336, 40332,     0, 32768, 40960, 
+    40961, 39936, 40448, 40320, 40336, 40332,     0, 32768, 
+    40960, 40961, 39936, 40448, 40320, 40336, 40337, 40334, 
+        0, 32768, 40960, 40961, 39936, 40448, 40320,     0, 
+    32768, 40960, 40961, 39936, 40448, 40320, 40336,     0, 
+    32768, 40960, 40961, 39936, 40448, 40320, 40336,     0, 
+    32768, 40960, 40961, 39936, 40448, 40320, 40336, 40338, 
+        0, 32768, 40960, 40961, 39936, 40448, 40320, 40336, 
+        0, 32768, 40960, 40961, 39936, 40448, 40320, 40336, 
+    40340,     0, 32768, 40960, 40961, 39936, 40448, 40320, 
+    40336, 40340,     0, 32768, 40960, 40961, 39936, 40448, 
+    40320, 40336, 40344, 40342,     0, 32768, 40960, 40961, 
+    39936, 40448, 40320, 40336,     0, 32768, 40960, 40961, 
+    39936, 40448, 40320, 40352, 40344,     0, 32768, 40960, 
+    40961, 39936, 40448, 40320, 40352, 40344,     0, 32768, 
+    40960, 40961, 39936, 40448, 40320, 40352, 40344, 40346, 
+        0, 32768, 40960, 40961, 39936, 40448, 40320, 40352, 
+    40344,     0, 32768, 40960, 40961, 39936, 40448, 40320, 
+    40352, 40353, 40348,     0, 32768, 40960, 40961, 39936, 
+    40448, 40320, 40352, 40353, 40348,     0, 32768, 40960, 
+    40961, 39936, 40448, 40320, 40352, 40353, 40348, 40350, 
+        0, 32768, 40960, 40961, 39936, 40448, 40320,     0, 
+    32768, 40960, 40961, 39936, 40448, 40320, 40352,     0, 
+    32768, 40960, 40961, 39936, 40448, 40320, 40352,     0, 
+    32768, 40960, 40961, 39936, 40448, 40320, 40352, 40354, 
+        0, 32768, 40960, 40961, 39936, 40448, 40320, 40352, 
+        0, 32768, 40960, 40961, 39936, 40448, 40320, 40352, 
+    40356,     0, 32768, 40960, 40961, 39936, 40448, 40320, 
+    40352, 40356,     0, 32768, 40960, 40961, 39936, 40448, 
+    40320, 40352, 40360, 40358,     0, 32768, 40960, 40961, 
+    39936, 40448, 40320, 40352,     0, 32768, 40960, 40961, 
+    39936, 40448, 40320, 40352, 40360,     0, 32768, 40960, 
+    40961, 39936, 40448, 40320, 40352, 40360,     0, 32768, 
+    40960, 40961, 39936, 40448, 40320, 40352, 40360, 40362, 
+        0, 32768, 40960, 40961, 39936, 40448, 40320, 40352, 
+    40360,     0, 32768, 40960, 40961, 39936, 40448, 40320, 
+    40352, 40368, 40364,     0, 32768, 40960, 40961, 39936, 
+    40448, 40320, 40352, 40368, 40364,     0, 32768, 40960, 
+    40961, 39936, 40448, 40320, 40352, 40368, 40369, 40366, 
+        0, 32768, 40960, 40961, 39936, 40448, 40320, 40352, 
+        0, 32768, 40960, 40961, 39936, 40448, 40320, 40384, 
+    40368,     0, 32768, 40960, 40961, 39936, 40448, 40320, 
+    40384, 40368,     0, 32768, 40960, 40961, 39936, 40448, 
+    40320, 40384, 40368, 40370,     0, 32768, 40960, 40961, 
+    39936, 40448, 40320, 40384, 40368,     0, 32768, 40960, 
+    40961, 39936, 40448, 40320, 40384, 40368, 40372,     0, 
+    32768, 40960, 40961, 39936, 40448, 40320, 40384, 40368, 
+    40372,     0, 32768, 40960, 40961, 39936, 40448, 40320, 
+    40384, 40368, 40376, 40374,     0, 32768, 40960, 40961, 
+    39936, 40448, 40320, 40384, 40368,     0, 32768, 40960, 
+    40961, 39936, 40448, 40320, 40384, 40385, 40376,     0, 
+    32768, 40960, 40961, 39936, 40448, 40320, 40384, 40385, 
+    40376,     0, 32768, 40960, 40961, 39936, 40448, 40320, 
+    40384, 40385, 40376, 40378,     0, 32768, 40960, 40961, 
+    39936, 40448, 40320, 40384, 40385, 40376,     0, 32768, 
+    40960, 40961, 39936, 40448, 40320, 40384, 40385, 40376, 
+    40380,     0, 32768, 40960, 40961, 39936, 40448, 40320, 
+    40384, 40385, 40387, 40380,     0, 32768, 40960, 40961, 
+    39936, 40448, 40320, 40384, 40385, 40387, 40380, 40382, 
+        0, 32768, 40960, 40961, 39936, 40448, 40320,     0, 
+    32768, 40960, 40961, 39936, 40448, 40449, 40384,     0, 
+    32768, 40960, 40961, 39936, 40448, 40449, 40384,     0, 
+    32768, 40960, 40961, 39936, 40448, 40449, 40384, 40386, 
+        0, 32768, 40960, 40961, 39936, 40448, 40449, 40384, 
+        0, 32768, 40960, 40961, 39936, 40448, 40449, 40384, 
+    40388,     0, 32768, 40960, 40961, 39936, 40448, 40449, 
+    40384, 40388,     0, 32768, 40960, 40961, 39936, 40448, 
+    40449, 40384, 40392, 40390,     0, 32768, 40960, 40961, 
+    39936, 40448, 40449, 40384,     0, 32768, 40960, 40961, 
+    39936, 40448, 40449, 40384, 40392,     0, 32768, 40960, 
+    40961, 39936, 40448, 40449, 40384, 40392,     0, 32768, 
+    40960, 40961, 39936, 40448, 40449, 40384, 40392, 40394, 
+        0, 32768, 40960, 40961, 39936, 40448, 40449, 40384, 
+    40392,     0, 32768, 40960, 40961, 39936, 40448, 40449, 
+    40384, 40400, 40396,     0, 32768, 40960, 40961, 39936, 
+    40448, 40449, 40384, 40400, 40396,     0, 32768, 40960, 
+    40961, 39936, 40448, 40449, 40384, 40400, 40401, 40398, 
+        0, 32768, 40960, 40961, 39936, 40448, 40449, 40384, 
+        0, 32768, 40960, 40961, 39936, 40448, 40449, 40384, 
+    40400,     0, 32768, 40960, 40961, 39936, 40448, 40449, 
+    40384, 40400,     0, 32768, 40960, 40961, 39936, 40448, 
+    40449, 40384, 40400, 40402,     0, 32768, 40960, 40961, 
+    39936, 40448, 40449, 40384, 40400,     0, 32768, 40960, 
+    40961, 39936, 40448, 40449, 40384, 40400, 40404,     0, 
+    32768, 40960, 40961, 39936, 40448, 40449, 40384, 40400, 
+    40404,     0, 32768, 40960, 40961, 39936, 40448, 40449, 
+    40384, 40400, 40408, 40406,     0, 32768, 40960, 40961, 
+    39936, 40448, 40449, 40384, 40400,     0, 32768, 40960, 
+    40961, 39936, 40448, 40449, 40384, 40416, 40408,     0, 
+    32768, 40960, 40961, 39936, 40448, 40449, 40384, 40416, 
+    40408,     0, 32768, 40960, 40961, 39936, 40448, 40449, 
+    40384, 40416, 40408, 40410,     0, 32768, 40960, 40961, 
+    39936, 40448, 40449, 40384, 40416, 40408,     0, 32768, 
+    40960, 40961, 39936, 40448, 40449, 40384, 40416, 40417, 
+    40412,     0, 32768, 40960, 40961, 39936, 40448, 40449, 
+    40384, 40416, 40417, 40412,     0, 32768, 40960, 40961, 
+    39936, 40448, 40449, 40384, 40416, 40417, 40412, 40414, 
+        0, 32768, 40960, 40961, 39936, 40448, 40449, 40384, 
+        0, 32768, 40960, 40961, 39936, 40448, 40449, 40384, 
+    40416,     0, 32768, 40960, 40961, 39936, 40448, 40449, 
+    40451, 40416,     0, 32768, 40960, 40961, 39936, 40448, 
+    40449, 40451, 40416, 40418,     0, 32768, 40960, 40961, 
+    39936, 40448, 40449, 40451, 40416,     0, 32768, 40960, 
+    40961, 39936, 40448, 40449, 40451, 40416, 40420,     0, 
+    32768, 40960, 40961, 39936, 40448, 40449, 40451, 40416, 
+    40420,     0, 32768, 40960, 40961, 39936, 40448, 40449, 
+    40451, 40416, 40424, 40422,     0, 32768, 40960, 40961, 
+    39936, 40448, 40449, 40451, 40416,     0, 32768, 40960, 
+    40961, 39936, 40448, 40449, 40451, 40416, 40424,     0, 
+    32768, 40960, 40961, 39936, 40448, 40449, 40451, 40416, 
+    40424,     0, 32768, 40960, 40961, 39936, 40448, 40449, 
+    40451, 40416, 40424, 40426,     0, 32768, 40960, 40961, 
+    39936, 40448, 40449, 40451, 40416, 40424,     0, 32768, 
+    40960, 40961, 39936, 40448, 40449, 40451, 40416, 40432, 
+    40428,     0, 32768, 40960, 40961, 39936, 40448, 40449, 
+    40451, 40416, 40432, 40428,     0, 32768, 40960, 40961, 
+    39936, 40448, 40449, 40451, 40416, 40432, 40433, 40430, 
+        0, 32768, 40960, 40961, 39936, 40448, 40449, 40451, 
+    40416,     0, 32768, 40960, 40961, 39936, 40448, 40449, 
+    40451, 40416, 40432,     0, 32768, 40960, 40961, 39936, 
+    40448, 40449, 40451, 40416, 40432,     0, 32768, 40960, 
+    40961, 39936, 40448, 40449, 40451, 40416, 40432, 40434, 
+        0, 32768, 40960, 40961, 39936, 40448, 40449, 40451, 
+    40455, 40432,     0, 32768, 40960, 40961, 39936, 40448, 
+    40449, 40451, 40455, 40432, 40436,     0, 32768, 40960, 
+    40961, 39936, 40448, 40449, 40451, 40455, 40432, 40436, 
+        0, 32768, 40960, 40961, 39936, 40448, 40449, 40451, 
+    40455, 40432, 40440, 40438,     0, 32768, 40960, 40961, 
+    39936, 40448, 40449, 40451, 40455, 40432,     0, 32768, 
+    40960, 40961, 39936, 40448, 40449, 40451, 40455, 40432, 
+    40440,     0, 32768, 40960, 40961, 39936, 40448, 40449, 
+    40451, 40455, 40432, 40440,     0, 32768, 40960, 40961, 
+    39936, 40448, 40449, 40451, 40455, 40432, 40440, 40442, 
+        0, 32768, 40960, 40961, 39936, 40448, 40449, 40451, 
+    40455, 40432, 40440,     0, 32768, 40960, 40961, 39936, 
+    40448, 40449, 40451, 40455, 40432, 40440, 40444,     0, 
+    32768, 40960, 40961, 39936, 40448, 40449, 40451, 40455, 
+    40432, 40440, 40444,     0, 32768, 40960, 40961, 39936, 
+    40448, 40449, 40451, 40455, 40432, 40440, 40444, 40446, 
+        0, 32768, 40960, 40961, 39936,     0, 32768, 40960, 
+    40961, 39936, 40448,     0, 32768, 40960, 40961, 39936, 
+    40448,     0, 32768, 40960, 40961, 39936, 40448, 40450, 
+        0, 32768, 40960, 40961, 40963, 40448,     0, 32768, 
+    40960, 40961, 40963, 40448, 40452,     0, 32768, 40960, 
+    40961, 40963, 40448, 40452,     0, 32768, 40960, 40961, 
+    40963, 40448, 40456, 40454,     0, 32768, 40960, 40961, 
+    40963, 40448,     0, 32768, 40960, 40961, 40963, 40448, 
+    40456,     0, 32768, 40960, 40961, 40963, 40448, 40456, 
+        0, 32768, 40960, 40961, 40963, 40448, 40456, 40458, 
+        0, 32768, 40960, 40961, 40963, 40448, 40456,     0, 
+    32768, 40960, 40961, 40963, 40448, 40464, 40460,     0, 
+    32768, 40960, 40961, 40963, 40448, 40464, 40460,     0, 
+    32768, 40960, 40961, 40963, 40448, 40464, 40465, 40462, 
+        0, 32768, 40960, 40961, 40963, 40448,     0, 32768, 
+    40960, 40961, 40963, 40448, 40464,     0, 32768, 40960, 
+    40961, 40963, 40448, 40464,     0, 32768, 40960, 40961, 
+    40963, 40448, 40464, 40466,     0, 32768, 40960, 40961, 
+    40963, 40448, 40464,     0, 32768, 40960, 40961, 40963, 
+    40448, 40464, 40468,     0, 32768, 40960, 40961, 40963, 
+    40448, 40464, 40468,     0, 32768, 40960, 40961, 40963, 
+    40448, 40464, 40472, 40470,     0, 32768, 40960, 40961, 
+    40963, 40448, 40464,     0, 32768, 40960, 40961, 40963, 
+    40448, 40480, 40472,     0, 32768, 40960, 40961, 40963, 
+    40448, 40480, 40472,     0, 32768, 40960, 40961, 40963, 
+    40448, 40480, 40472, 40474,     0, 32768, 40960, 40961, 
+    40963, 40448, 40480, 40472,     0, 32768, 40960, 40961, 
+    40963, 40448, 40480, 40481, 40476,     0, 32768, 40960, 
+    40961, 40963, 40448, 40480, 40481, 40476,     0, 32768, 
+    40960, 40961, 40963, 40448, 40480, 40481, 40476, 40478, 
+        0, 32768, 40960, 40961, 40963, 40448,     0, 32768, 
+    40960, 40961, 40963, 40448, 40480,     0, 32768, 40960, 
+    40961, 40963, 40448, 40480,     0, 32768, 40960, 40961, 
+    40963, 40448, 40480, 40482,     0, 32768, 40960, 40961, 
+    40963, 40448, 40480,     0, 32768, 40960, 40961, 40963, 
+    40448, 40480, 40484,     0, 32768, 40960, 40961, 40963, 
+    40448, 40480, 40484,     0, 32768, 40960, 40961, 40963, 
+    40448, 40480, 40488, 40486,     0, 32768, 40960, 40961, 
+    40963, 40448, 40480,     0, 32768, 40960, 40961, 40963, 
+    40448, 40480, 40488,     0, 32768, 40960, 40961, 40963, 
+    40448, 40480, 40488,     0, 32768, 40960, 40961, 40963, 
+    40448, 40480, 40488, 40490,     0, 32768, 40960, 40961, 
+    40963, 40448, 40480, 40488,     0, 32768, 40960, 40961, 
+    40963, 40448, 40480, 40496, 40492,     0, 32768, 40960, 
+    40961, 40963, 40448, 40480, 40496, 40492,     0, 32768, 
+    40960, 40961, 40963, 40448, 40480, 40496, 40497, 40494, 
+        0, 32768, 40960, 40961, 40963, 40448, 40480,     0, 
+    32768, 40960, 40961, 40963, 40448, 40512, 40496,     0, 
+    32768, 40960, 40961, 40963, 40448, 40512, 40496,     0, 
+    32768, 40960, 40961, 40963, 40448, 40512, 40496, 40498, 
+        0, 32768, 40960, 40961, 40963, 40448, 40512, 40496, 
+        0, 32768, 40960, 40961, 40963, 40448, 40512, 40496, 
+    40500,     0, 32768, 40960, 40961, 40963, 40448, 40512, 
+    40496, 40500,     0, 32768, 40960, 40961, 40963, 40448, 
+    40512, 40496, 40504, 40502,     0, 32768, 40960, 40961, 
+    40963, 40448, 40512, 40496,     0, 32768, 40960, 40961, 
+    40963, 40448, 40512, 40513, 40504,     0, 32768, 40960, 
+    40961, 40963, 40448, 40512, 40513, 40504,     0, 32768, 
+    40960, 40961, 40963, 40448, 40512, 40513, 40504, 40506, 
+        0, 32768, 40960, 40961, 40963, 40448, 40512, 40513, 
+    40504,     0, 32768, 40960, 40961, 40963, 40448, 40512, 
+    40513, 40504, 40508,     0, 32768, 40960, 40961, 40963, 
+    40448, 40512, 40513, 40515, 40508,     0, 32768, 40960, 
+    40961, 40963, 40448, 40512, 40513, 40515, 40508, 40510, 
+        0, 32768, 40960, 40961, 40963, 40448,     0, 32768, 
+    40960, 40961, 40963, 40448, 40512,     0, 32768, 40960, 
+    40961, 40963, 40448, 40512,     0, 32768, 40960, 40961, 
+    40963, 40448, 40512, 40514,     0, 32768, 40960, 40961, 
+    40963, 40448, 40512,     0, 32768, 40960, 40961, 40963, 
+    40448, 40512, 40516,     0, 32768, 40960, 40961, 40963, 
+    40448, 40512, 40516,     0, 32768, 40960, 40961, 40963, 
+    40448, 40512, 40520, 40518,     0, 32768, 40960, 40961, 
+    40963, 40448, 40512,     0, 32768, 40960, 40961, 40963, 
+    40448, 40512, 40520,     0, 32768, 40960, 40961, 40963, 
+    40448, 40512, 40520,     0, 32768, 40960, 40961, 40963, 
+    40448, 40512, 40520, 40522,     0, 32768, 40960, 40961, 
+    40963, 40448, 40512, 40520,     0, 32768, 40960, 40961, 
+    40963, 40448, 40512, 40528, 40524,     0, 32768, 40960, 
+    40961, 40963, 40448, 40512, 40528, 40524,     0, 32768, 
+    40960, 40961, 40963, 40448, 40512, 40528, 40529, 40526, 
+        0, 32768, 40960, 40961, 40963, 40448, 40512,     0, 
+    32768, 40960, 40961, 40963, 40448, 40512, 40528,     0, 
+    32768, 40960, 40961, 40963, 40448, 40512, 40528,     0, 
+    32768, 40960, 40961, 40963, 40448, 40512, 40528, 40530, 
+        0, 32768, 40960, 40961, 40963, 40448, 40512, 40528, 
+        0, 32768, 40960, 40961, 40963, 40448, 40512, 40528, 
+    40532,     0, 32768, 40960, 40961, 40963, 40448, 40512, 
+    40528, 40532,     0, 32768, 40960, 40961, 40963, 40448, 
+    40512, 40528, 40536, 40534,     0, 32768, 40960, 40961, 
+    40963, 40448, 40512, 40528,     0, 32768, 40960, 40961, 
+    40963, 40448, 40512, 40544, 40536,     0, 32768, 40960, 
+    40961, 40963, 40448, 40512, 40544, 40536,     0, 32768, 
+    40960, 40961, 40963, 40448, 40512, 40544, 40536, 40538, 
+        0, 32768, 40960, 40961, 40963, 40448, 40512, 40544, 
+    40536,     0, 32768, 40960, 40961, 40963, 40448, 40512, 
+    40544, 40545, 40540,     0, 32768, 40960, 40961, 40963, 
+    40448, 40512, 40544, 40545, 40540,     0, 32768, 40960, 
+    40961, 40963, 40448, 40512, 40544, 40545, 40540, 40542, 
+        0, 32768, 40960, 40961, 40963, 40448, 40512,     0, 
+    32768, 40960, 40961, 40963, 40448, 40576, 40544,     0, 
+    32768, 40960, 40961, 40963, 40448, 40576, 40544,     0, 
+    32768, 40960, 40961, 40963, 40448, 40576, 40544, 40546, 
+        0, 32768, 40960, 40961, 40963, 40448, 40576, 40544, 
+        0, 32768, 40960, 40961, 40963, 40448, 40576, 40544, 
+    40548,     0, 32768, 40960, 40961, 40963, 40448, 40576, 
+    40544, 40548,     0, 32768, 40960, 40961, 40963, 40448, 
+    40576, 40544, 40552, 40550,     0, 32768, 40960, 40961, 
+    40963, 40448, 40576, 40544,     0, 32768, 40960, 40961, 
+    40963, 40448, 40576, 40544, 40552,     0, 32768, 40960, 
+    40961, 40963, 40448, 40576, 40544, 40552,     0, 32768, 
+    40960, 40961, 40963, 40448, 40576, 40544, 40552, 40554, 
+        0, 32768, 40960, 40961, 40963, 40448, 40576, 40544, 
+    40552,     0, 32768, 40960, 40961, 40963, 40448, 40576, 
+    40544, 40560, 40556,     0, 32768, 40960, 40961, 40963, 
+    40448, 40576, 40544, 40560, 40556,     0, 32768, 40960, 
+    40961, 40963, 40448, 40576, 40544, 40560, 40561, 40558, 
+        0, 32768, 40960, 40961, 40963, 40448, 40576, 40544, 
+        0, 32768, 40960, 40961, 40963, 40448, 40576, 40577, 
+    40560,     0, 32768, 40960, 40961, 40963, 40448, 40576, 
+    40577, 40560,     0, 32768, 40960, 40961, 40963, 40448, 
+    40576, 40577, 40560, 40562,     0, 32768, 40960, 40961, 
+    40963, 40448, 40576, 40577, 40560,     0, 32768, 40960, 
+    40961, 40963, 40448, 40576, 40577, 40560, 40564,     0, 
+    32768, 40960, 40961, 40963, 40448, 40576, 40577, 40560, 
+    40564,     0, 32768, 40960, 40961, 40963, 40448, 40576, 
+    40577, 40560, 40568, 40566,     0, 32768, 40960, 40961, 
+    40963, 40448, 40576, 40577, 40560,     0, 32768, 40960, 
+    40961, 40963, 40448, 40576, 40577, 40560, 40568,     0, 
+    32768, 40960, 40961, 40963, 40448, 40576, 40577, 40579, 
+    40568,     0, 32768, 40960, 40961, 40963, 40448, 40576, 
+    40577, 40579, 40568, 40570,     0, 32768, 40960, 40961, 
+    40963, 40448, 40576, 40577, 40579, 40568,     0, 32768, 
+    40960, 40961, 40963, 40448, 40576, 40577, 40579, 40568, 
+    40572,     0, 32768, 40960, 40961, 40963, 40448, 40576, 
+    40577, 40579, 40568, 40572,     0, 32768, 40960, 40961, 
+    40963, 40448, 40576, 40577, 40579, 40568, 40572, 40574, 
+        0, 32768, 40960, 40961, 40963, 40448,     0, 32768, 
+    40960, 40961, 40963, 40448, 40576,     0, 32768, 40960, 
+    40961, 40963, 40448, 40576,     0, 32768, 40960, 40961, 
+    40963, 40448, 40576, 40578,     0, 32768, 40960, 40961, 
+    40963, 40448, 40576,     0, 32768, 40960, 40961, 40963, 
+    40448, 40576, 40580,     0, 32768, 40960, 40961, 40963, 
+    40448, 40576, 40580,     0, 32768, 40960, 40961, 40963, 
+    40448, 40576, 40584, 40582,     0, 32768, 40960, 40961, 
+    40963, 40448, 40576,     0, 32768, 40960, 40961, 40963, 
+    40448, 40576, 40584,     0, 32768, 40960, 40961, 40963, 
+    40448, 40576, 40584,     0, 32768, 40960, 40961, 40963, 
+    40448, 40576, 40584, 40586,     0, 32768, 40960, 40961, 
+    40963, 40448, 40576, 40584,     0, 32768, 40960, 40961, 
+    40963, 40448, 40576, 40592, 40588,     0, 32768, 40960, 
+    40961, 40963, 40448, 40576, 40592, 40588,     0, 32768, 
+    40960, 40961, 40963, 40448, 40576, 40592, 40593, 40590, 
+        0, 32768, 40960, 40961, 40963, 40448, 40576,     0, 
+    32768, 40960, 40961, 40963, 40448, 40576, 40592,     0, 
+    32768, 40960, 40961, 40963, 40448, 40576, 40592,     0, 
+    32768, 40960, 40961, 40963, 40448, 40576, 40592, 40594, 
+        0, 32768, 40960, 40961, 40963, 40448, 40576, 40592, 
+        0, 32768, 40960, 40961, 40963, 40448, 40576, 40592, 
+    40596,     0, 32768, 40960, 40961, 40963, 40448, 40576, 
+    40592, 40596,     0, 32768, 40960, 40961, 40963, 40448, 
+    40576, 40592, 40600, 40598,     0, 32768, 40960, 40961, 
+    40963, 40448, 40576, 40592,     0, 32768, 40960, 40961, 
+    40963, 40448, 40576, 40608, 40600,     0, 32768, 40960, 
+    40961, 40963, 40448, 40576, 40608, 40600,     0, 32768, 
+    40960, 40961, 40963, 40448, 40576, 40608, 40600, 40602, 
+        0, 32768, 40960, 40961, 40963, 40448, 40576, 40608, 
+    40600,     0, 32768, 40960, 40961, 40963, 40448, 40576, 
+    40608, 40609, 40604,     0, 32768, 40960, 40961, 40963, 
+    40448, 40576, 40608, 40609, 40604,     0, 32768, 40960, 
+    40961, 40963, 40448, 40576, 40608, 40609, 40604, 40606, 
+        0, 32768, 40960, 40961, 40963, 40448, 40576,     0, 
+    32768, 40960, 40961, 40963, 40448, 40576, 40608,     0, 
+    32768, 40960, 40961, 40963, 40448, 40576, 40608,     0, 
+    32768, 40960, 40961, 40963, 40448, 40576, 40608, 40610, 
+        0, 32768, 40960, 40961, 40963, 40448, 40576, 40608, 
+        0, 32768, 40960, 40961, 40963, 40448, 40576, 40608, 
+    40612,     0, 32768, 40960, 40961, 40963, 40448, 40576, 
+    40608, 40612,     0, 32768, 40960, 40961, 40963, 40448, 
+    40576, 40608, 40616, 40614,     0, 32768, 40960, 40961, 
+    40963, 40448, 40576, 40608,     0, 32768, 40960, 40961, 
+    40963, 40448, 40576, 40608, 40616,     0, 32768, 40960, 
+    40961, 40963, 40448, 40576, 40608, 40616,     0, 32768, 
+    40960, 40961, 40963, 40448, 40576, 40608, 40616, 40618, 
+        0, 32768, 40960, 40961, 40963, 40448, 40576, 40608, 
+    40616,     0, 32768, 40960, 40961, 40963, 40448, 40576, 
+    40608, 40624, 40620,     0, 32768, 40960, 40961, 40963, 
+    40448, 40576, 40608, 40624, 40620,     0, 32768, 40960, 
+    40961, 40963, 40448, 40576, 40608, 40624, 40625, 40622, 
+        0, 32768, 40960, 40961, 40963, 40448, 40576, 40608, 
+        0, 32768, 40960, 40961, 40963, 40448, 40576, 40640, 
+    40624,     0, 32768, 40960, 40961, 40963, 40448, 40576, 
+    40640, 40624,     0, 32768, 40960, 40961, 40963, 40448, 
+    40576, 40640, 40624, 40626,     0, 32768, 40960, 40961, 
+    40963, 40448, 40576, 40640, 40624,     0, 32768, 40960, 
+    40961, 40963, 40448, 40576, 40640, 40624, 40628,     0, 
+    32768, 40960, 40961, 40963, 40448, 40576, 40640, 40624, 
+    40628,     0, 32768, 40960, 40961, 40963, 40448, 40576, 
+    40640, 40624, 40632, 40630,     0, 32768, 40960, 40961, 
+    40963, 40448, 40576, 40640, 40624,     0, 32768, 40960, 
+    40961, 40963, 40448, 40576, 40640, 40641, 40632,     0, 
+    32768, 40960, 40961, 40963, 40448, 40576, 40640, 40641, 
+    40632,     0, 32768, 40960, 40961, 40963, 40448, 40576, 
+    40640, 40641, 40632, 40634,     0, 32768, 40960, 40961, 
+    40963, 40448, 40576, 40640, 40641, 40632,     0, 32768, 
+    40960, 40961, 40963, 40448, 40576, 40640, 40641, 40632, 
+    40636,     0, 32768, 40960, 40961, 40963, 40448, 40576, 
+    40640, 40641, 40643, 40636,     0, 32768, 40960, 40961, 
+    40963, 40448, 40576, 40640, 40641, 40643, 40636, 40638, 
+        0, 32768, 40960, 40961, 40963, 40448, 40576,     0, 
+    32768, 40960, 40961, 40963, 40448, 40704, 40640,     0, 
+    32768, 40960, 40961, 40963, 40448, 40704, 40640,     0, 
+    32768, 40960, 40961, 40963, 40448, 40704, 40640, 40642, 
+        0, 32768, 40960, 40961, 40963, 40448, 40704, 40640, 
+        0, 32768, 40960, 40961, 40963, 40448, 40704, 40640, 
+    40644,     0, 32768, 40960, 40961, 40963, 40448, 40704, 
+    40640, 40644,     0, 32768, 40960, 40961, 40963, 40448, 
+    40704, 40640, 40648, 40646,     0, 32768, 40960, 40961, 
+    40963, 40448, 40704, 40640,     0, 32768, 40960, 40961, 
+    40963, 40448, 40704, 40640, 40648,     0, 32768, 40960, 
+    40961, 40963, 40448, 40704, 40640, 40648,     0, 32768, 
+    40960, 40961, 40963, 40448, 40704, 40640, 40648, 40650, 
+        0, 32768, 40960, 40961, 40963, 40448, 40704, 40640, 
+    40648,     0, 32768, 40960, 40961, 40963, 40448, 40704, 
+    40640, 40656, 40652,     0, 32768, 40960, 40961, 40963, 
+    40448, 40704, 40640, 40656, 40652,     0, 32768, 40960, 
+    40961, 40963, 40448, 40704, 40640, 40656, 40657, 40654, 
+        0, 32768, 40960, 40961, 40963, 40448, 40704, 40640, 
+        0, 32768, 40960, 40961, 40963, 40448, 40704, 40640, 
+    40656,     0, 32768, 40960, 40961, 40963, 40448, 40704, 
+    40640, 40656,     0, 32768, 40960, 40961, 40963, 40448, 
+    40704, 40640, 40656, 40658,     0, 32768, 40960, 40961, 
+    40963, 40448, 40704, 40640, 40656,     0, 32768, 40960, 
+    40961, 40963, 40448, 40704, 40640, 40656, 40660,     0, 
+    32768, 40960, 40961, 40963, 40448, 40704, 40640, 40656, 
+    40660,     0, 32768, 40960, 40961, 40963, 40448, 40704, 
+    40640, 40656, 40664, 40662,     0, 32768, 40960, 40961, 
+    40963, 40448, 40704, 40640, 40656,     0, 32768, 40960, 
+    40961, 40963, 40448, 40704, 40640, 40672, 40664,     0, 
+    32768, 40960, 40961, 40963, 40448, 40704, 40640, 40672, 
+    40664,     0, 32768, 40960, 40961, 40963, 40448, 40704, 
+    40640, 40672, 40664, 40666,     0, 32768, 40960, 40961, 
+    40963, 40448, 40704, 40640, 40672, 40664,     0, 32768, 
+    40960, 40961, 40963, 40448, 40704, 40640, 40672, 40673, 
+    40668,     0, 32768, 40960, 40961, 40963, 40448, 40704, 
+    40640, 40672, 40673, 40668,     0, 32768, 40960, 40961, 
+    40963, 40448, 40704, 40640, 40672, 40673, 40668, 40670, 
+        0, 32768, 40960, 40961, 40963, 40448, 40704, 40640, 
+        0, 32768, 40960, 40961, 40963, 40448, 40704, 40705, 
+    40672,     0, 32768, 40960, 40961, 40963, 40448, 40704, 
+    40705, 40672,     0, 32768, 40960, 40961, 40963, 40448, 
+    40704, 40705, 40672, 40674,     0, 32768, 40960, 40961, 
+    40963, 40448, 40704, 40705, 40672,     0, 32768, 40960, 
+    40961, 40963, 40448, 40704, 40705, 40672, 40676,     0, 
+    32768, 40960, 40961, 40963, 40448, 40704, 40705, 40672, 
+    40676,     0, 32768, 40960, 40961, 40963, 40448, 40704, 
+    40705, 40672, 40680, 40678,     0, 32768, 40960, 40961, 
+    40963, 40448, 40704, 40705, 40672,     0, 32768, 40960, 
+    40961, 40963, 40448, 40704, 40705, 40672, 40680,     0, 
+    32768, 40960, 40961, 40963, 40448, 40704, 40705, 40672, 
+    40680,     0, 32768, 40960, 40961, 40963, 40448, 40704, 
+    40705, 40672, 40680, 40682,     0, 32768, 40960, 40961, 
+    40963, 40448, 40704, 40705, 40672, 40680,     0, 32768, 
+    40960, 40961, 40963, 40448, 40704, 40705, 40672, 40688, 
+    40684,     0, 32768, 40960, 40961, 40963, 40448, 40704, 
+    40705, 40672, 40688, 40684,     0, 32768, 40960, 40961, 
+    40963, 40448, 40704, 40705, 40672, 40688, 40689, 40686, 
+        0, 32768, 40960, 40961, 40963, 40448, 40704, 40705, 
+    40672,     0, 32768, 40960, 40961, 40963, 40448, 40704, 
+    40705, 40672, 40688,     0, 32768, 40960, 40961, 40963, 
+    40448, 40704, 40705, 40707, 40688,     0, 32768, 40960, 
+    40961, 40963, 40448, 40704, 40705, 40707, 40688, 40690, 
+        0, 32768, 40960, 40961, 40963, 40448, 40704, 40705, 
+    40707, 40688,     0, 32768, 40960, 40961, 40963, 40448, 
+    40704, 40705, 40707, 40688, 40692,     0, 32768, 40960, 
+    40961, 40963, 40448, 40704, 40705, 40707, 40688, 40692, 
+        0, 32768, 40960, 40961, 40963, 40448, 40704, 40705, 
+    40707, 40688, 40696, 40694,     0, 32768, 40960, 40961, 
+    40963, 40448, 40704, 40705, 40707, 40688,     0, 32768, 
+    40960, 40961, 40963, 40448, 40704, 40705, 40707, 40688, 
+    40696,     0, 32768, 40960, 40961, 40963, 40448, 40704, 
+    40705, 40707, 40688, 40696,     0, 32768, 40960, 40961, 
+    40963, 40448, 40704, 40705, 40707, 40688, 40696, 40698, 
+        0, 32768, 40960, 40961, 40963, 40448, 40704, 40705, 
+    40707, 40711, 40696,     0, 32768, 40960, 40961, 40963, 
+    40448, 40704, 40705, 40707, 40711, 40696, 40700,     0, 
+    32768, 40960, 40961, 40963, 40448, 40704, 40705, 40707, 
+    40711, 40696, 40700,     0, 32768, 40960, 40961, 40963, 
+    40448, 40704, 40705, 40707, 40711, 40696, 40700, 40702, 
+        0, 32768, 40960, 40961, 40963, 40448,     0, 32768, 
+    40960, 40961, 40963, 40448, 40704,     0, 32768, 40960, 
+    40961, 40963, 40448, 40704,     0, 32768, 40960, 40961, 
+    40963, 40448, 40704, 40706,     0, 32768, 40960, 40961, 
+    40963, 40448, 40704,     0, 32768, 40960, 40961, 40963, 
+    40448, 40704, 40708,     0, 32768, 40960, 40961, 40963, 
+    40448, 40704, 40708,     0, 32768, 40960, 40961, 40963, 
+    40448, 40704, 40712, 40710,     0, 32768, 40960, 40961, 
+    40963, 40967, 40704,     0, 32768, 40960, 40961, 40963, 
+    40967, 40704, 40712,     0, 32768, 40960, 40961, 40963, 
+    40967, 40704, 40712,     0, 32768, 40960, 40961, 40963, 
+    40967, 40704, 40712, 40714,     0, 32768, 40960, 40961, 
+    40963, 40967, 40704, 40712,     0, 32768, 40960, 40961, 
+    40963, 40967, 40704, 40720, 40716,     0, 32768, 40960, 
+    40961, 40963, 40967, 40704, 40720, 40716,     0, 32768, 
+    40960, 40961, 40963, 40967, 40704, 40720, 40721, 40718, 
+        0, 32768, 40960, 40961, 40963, 40967, 40704,     0, 
+    32768, 40960, 40961, 40963, 40967, 40704, 40720,     0, 
+    32768, 40960, 40961, 40963, 40967, 40704, 40720,     0, 
+    32768, 40960, 40961, 40963, 40967, 40704, 40720, 40722, 
+        0, 32768, 40960, 40961, 40963, 40967, 40704, 40720, 
+        0, 32768, 40960, 40961, 40963, 40967, 40704, 40720, 
+    40724,     0, 32768, 40960, 40961, 40963, 40967, 40704, 
+    40720, 40724,     0, 32768, 40960, 40961, 40963, 40967, 
+    40704, 40720, 40728, 40726,     0, 32768, 40960, 40961, 
+    40963, 40967, 40704, 40720,     0, 32768, 40960, 40961, 
+    40963, 40967, 40704, 40736, 40728,     0, 32768, 40960, 
+    40961, 40963, 40967, 40704, 40736, 40728,     0, 32768, 
+    40960, 40961, 40963, 40967, 40704, 40736, 40728, 40730, 
+        0, 32768, 40960, 40961, 40963, 40967, 40704, 40736, 
+    40728,     0, 32768, 40960, 40961, 40963, 40967, 40704, 
+    40736, 40737, 40732,     0, 32768, 40960, 40961, 40963, 
+    40967, 40704, 40736, 40737, 40732,     0, 32768, 40960, 
+    40961, 40963, 40967, 40704, 40736, 40737, 40732, 40734, 
+        0, 32768, 40960, 40961, 40963, 40967, 40704,     0, 
+    32768, 40960, 40961, 40963, 40967, 40704, 40736,     0, 
+    32768, 40960, 40961, 40963, 40967, 40704, 40736,     0, 
+    32768, 40960, 40961, 40963, 40967, 40704, 40736, 40738, 
+        0, 32768, 40960, 40961, 40963, 40967, 40704, 40736, 
+        0, 32768, 40960, 40961, 40963, 40967, 40704, 40736, 
+    40740,     0, 32768, 40960, 40961, 40963, 40967, 40704, 
+    40736, 40740,     0, 32768, 40960, 40961, 40963, 40967, 
+    40704, 40736, 40744, 40742,     0, 32768, 40960, 40961, 
+    40963, 40967, 40704, 40736,     0, 32768, 40960, 40961, 
+    40963, 40967, 40704, 40736, 40744,     0, 32768, 40960, 
+    40961, 40963, 40967, 40704, 40736, 40744,     0, 32768, 
+    40960, 40961, 40963, 40967, 40704, 40736, 40744, 40746, 
+        0, 32768, 40960, 40961, 40963, 40967, 40704, 40736, 
+    40744,     0, 32768, 40960, 40961, 40963, 40967, 40704, 
+    40736, 40752, 40748,     0, 32768, 40960, 40961, 40963, 
+    40967, 40704, 40736, 40752, 40748,     0, 32768, 40960, 
+    40961, 40963, 40967, 40704, 40736, 40752, 40753, 40750, 
+        0, 32768, 40960, 40961, 40963, 40967, 40704, 40736, 
+        0, 32768, 40960, 40961, 40963, 40967, 40704, 40768, 
+    40752,     0, 32768, 40960, 40961, 40963, 40967, 40704, 
+    40768, 40752,     0, 32768, 40960, 40961, 40963, 40967, 
+    40704, 40768, 40752, 40754,     0, 32768, 40960, 40961, 
+    40963, 40967, 40704, 40768, 40752,     0, 32768, 40960, 
+    40961, 40963, 40967, 40704, 40768, 40752, 40756,     0, 
+    32768, 40960, 40961, 40963, 40967, 40704, 40768, 40752, 
+    40756,     0, 32768, 40960, 40961, 40963, 40967, 40704, 
+    40768, 40752, 40760, 40758,     0, 32768, 40960, 40961, 
+    40963, 40967, 40704, 40768, 40752,     0, 32768, 40960, 
+    40961, 40963, 40967, 40704, 40768, 40769, 40760,     0, 
+    32768, 40960, 40961, 40963, 40967, 40704, 40768, 40769, 
+    40760,     0, 32768, 40960, 40961, 40963, 40967, 40704, 
+    40768, 40769, 40760, 40762,     0, 32768, 40960, 40961, 
+    40963, 40967, 40704, 40768, 40769, 40760,     0, 32768, 
+    40960, 40961, 40963, 40967, 40704, 40768, 40769, 40760, 
+    40764,     0, 32768, 40960, 40961, 40963, 40967, 40704, 
+    40768, 40769, 40771, 40764,     0, 32768, 40960, 40961, 
+    40963, 40967, 40704, 40768, 40769, 40771, 40764, 40766, 
+        0, 32768, 40960, 40961, 40963, 40967, 40704,     0, 
+    32768, 40960, 40961, 40963, 40967, 40704, 40768,     0, 
+    32768, 40960, 40961, 40963, 40967, 40704, 40768,     0, 
+    32768, 40960, 40961, 40963, 40967, 40704, 40768, 40770, 
+        0, 32768, 40960, 40961, 40963, 40967, 40704, 40768, 
+        0, 32768, 40960, 40961, 40963, 40967, 40704, 40768, 
+    40772,     0, 32768, 40960, 40961, 40963, 40967, 40704, 
+    40768, 40772,     0, 32768, 40960, 40961, 40963, 40967, 
+    40704, 40768, 40776, 40774,     0, 32768, 40960, 40961, 
+    40963, 40967, 40704, 40768,     0, 32768, 40960, 40961, 
+    40963, 40967, 40704, 40768, 40776,     0, 32768, 40960, 
+    40961, 40963, 40967, 40704, 40768, 40776,     0, 32768, 
+    40960, 40961, 40963, 40967, 40704, 40768, 40776, 40778, 
+        0, 32768, 40960, 40961, 40963, 40967, 40704, 40768, 
+    40776,     0, 32768, 40960, 40961, 40963, 40967, 40704, 
+    40768, 40784, 40780,     0, 32768, 40960, 40961, 40963, 
+    40967, 40704, 40768, 40784, 40780,     0, 32768, 40960, 
+    40961, 40963, 40967, 40704, 40768, 40784, 40785, 40782, 
+        0, 32768, 40960, 40961, 40963, 40967, 40704, 40768, 
+        0, 32768, 40960, 40961, 40963, 40967, 40704, 40768, 
+    40784,     0, 32768, 40960, 40961, 40963, 40967, 40704, 
+    40768, 40784,     0, 32768, 40960, 40961, 40963, 40967, 
+    40704, 40768, 40784, 40786,     0, 32768, 40960, 40961, 
+    40963, 40967, 40704, 40768, 40784,     0, 32768, 40960, 
+    40961, 40963, 40967, 40704, 40768, 40784, 40788,     0, 
+    32768, 40960, 40961, 40963, 40967, 40704, 40768, 40784, 
+    40788,     0, 32768, 40960, 40961, 40963, 40967, 40704, 
+    40768, 40784, 40792, 40790,     0, 32768, 40960, 40961, 
+    40963, 40967, 40704, 40768, 40784,     0, 32768, 40960, 
+    40961, 40963, 40967, 40704, 40768, 40800, 40792,     0, 
+    32768, 40960, 40961, 40963, 40967, 40704, 40768, 40800, 
+    40792,     0, 32768, 40960, 40961, 40963, 40967, 40704, 
+    40768, 40800, 40792, 40794,     0, 32768, 40960, 40961, 
+    40963, 40967, 40704, 40768, 40800, 40792,     0, 32768, 
+    40960, 40961, 40963, 40967, 40704, 40768, 40800, 40801, 
+    40796,     0, 32768, 40960, 40961, 40963, 40967, 40704, 
+    40768, 40800, 40801, 40796,     0, 32768, 40960, 40961, 
+    40963, 40967, 40704, 40768, 40800, 40801, 40796, 40798, 
+        0, 32768, 40960, 40961, 40963, 40967, 40704, 40768, 
+        0, 32768, 40960, 40961, 40963, 40967, 40704, 40832, 
+    40800,     0, 32768, 40960, 40961, 40963, 40967, 40704, 
+    40832, 40800,     0, 32768, 40960, 40961, 40963, 40967, 
+    40704, 40832, 40800, 40802,     0, 32768, 40960, 40961, 
+    40963, 40967, 40704, 40832, 40800,     0, 32768, 40960, 
+    40961, 40963, 40967, 40704, 40832, 40800, 40804,     0, 
+    32768, 40960, 40961, 40963, 40967, 40704, 40832, 40800, 
+    40804,     0, 32768, 40960, 40961, 40963, 40967, 40704, 
+    40832, 40800, 40808, 40806,     0, 32768, 40960, 40961, 
+    40963, 40967, 40704, 40832, 40800,     0, 32768, 40960, 
+    40961, 40963, 40967, 40704, 40832, 40800, 40808,     0, 
+    32768, 40960, 40961, 40963, 40967, 40704, 40832, 40800, 
+    40808,     0, 32768, 40960, 40961, 40963, 40967, 40704, 
+    40832, 40800, 40808, 40810,     0, 32768, 40960, 40961, 
+    40963, 40967, 40704, 40832, 40800, 40808,     0, 32768, 
+    40960, 40961, 40963, 40967, 40704, 40832, 40800, 40816, 
+    40812,     0, 32768, 40960, 40961, 40963, 40967, 40704, 
+    40832, 40800, 40816, 40812,     0, 32768, 40960, 40961, 
+    40963, 40967, 40704, 40832, 40800, 40816, 40817, 40814, 
+        0, 32768, 40960, 40961, 40963, 40967, 40704, 40832, 
+    40800,     0, 32768, 40960, 40961, 40963, 40967, 40704, 
+    40832, 40833, 40816,     0, 32768, 40960, 40961, 40963, 
+    40967, 40704, 40832, 40833, 40816,     0, 32768, 40960, 
+    40961, 40963, 40967, 40704, 40832, 40833, 40816, 40818, 
+        0, 32768, 40960, 40961, 40963, 40967, 40704, 40832, 
+    40833, 40816,     0, 32768, 40960, 40961, 40963, 40967, 
+    40704, 40832, 40833, 40816, 40820,     0, 32768, 40960, 
+    40961, 40963, 40967, 40704, 40832, 40833, 40816, 40820, 
+        0, 32768, 40960, 40961, 40963, 40967, 40704, 40832, 
+    40833, 40816, 40824, 40822,     0, 32768, 40960, 40961, 
+    40963, 40967, 40704, 40832, 40833, 40816,     0, 32768, 
+    40960, 40961, 40963, 40967, 40704, 40832, 40833, 40816, 
+    40824,     0, 32768, 40960, 40961, 40963, 40967, 40704, 
+    40832, 40833, 40835, 40824,     0, 32768, 40960, 40961, 
+    40963, 40967, 40704, 40832, 40833, 40835, 40824, 40826, 
+        0, 32768, 40960, 40961, 40963, 40967, 40704, 40832, 
+    40833, 40835, 40824,     0, 32768, 40960, 40961, 40963, 
+    40967, 40704, 40832, 40833, 40835, 40824, 40828,     0, 
+    32768, 40960, 40961, 40963, 40967, 40704, 40832, 40833, 
+    40835, 40824, 40828,     0, 32768, 40960, 40961, 40963, 
+    40967, 40704, 40832, 40833, 40835, 40824, 40828, 40830, 
+        0, 32768, 40960, 40961, 40963, 40967, 40704,     0, 
+    32768, 40960, 40961, 40963, 40967, 40704, 40832,     0, 
+    32768, 40960, 40961, 40963, 40967, 40704, 40832,     0, 
+    32768, 40960, 40961, 40963, 40967, 40704, 40832, 40834, 
+        0, 32768, 40960, 40961, 40963, 40967, 40704, 40832, 
+        0, 32768, 40960, 40961, 40963, 40967, 40704, 40832, 
+    40836,     0, 32768, 40960, 40961, 40963, 40967, 40704, 
+    40832, 40836,     0, 32768, 40960, 40961, 40963, 40967, 
+    40704, 40832, 40840, 40838,     0, 32768, 40960, 40961, 
+    40963, 40967, 40704, 40832,     0, 32768, 40960, 40961, 
+    40963, 40967, 40704, 40832, 40840,     0, 32768, 40960, 
+    40961, 40963, 40967, 40704, 40832, 40840,     0, 32768, 
+    40960, 40961, 40963, 40967, 40704, 40832, 40840, 40842, 
+        0, 32768, 40960, 40961, 40963, 40967, 40704, 40832, 
+    40840,     0, 32768, 40960, 40961, 40963, 40967, 40704, 
+    40832, 40848, 40844,     0, 32768, 40960, 40961, 40963, 
+    40967, 40704, 40832, 40848, 40844,     0, 32768, 40960, 
+    40961, 40963, 40967, 40704, 40832, 40848, 40849, 40846, 
+        0, 32768, 40960, 40961, 40963, 40967, 40975, 40832, 
+        0, 32768, 40960, 40961, 40963, 40967, 40975, 40832, 
+    40848,     0, 32768, 40960, 40961, 40963, 40967, 40975, 
+    40832, 40848,     0, 32768, 40960, 40961, 40963, 40967, 
+    40975, 40832, 40848, 40850,     0, 32768, 40960, 40961, 
+    40963, 40967, 40975, 40832, 40848,     0, 32768, 40960, 
+    40961, 40963, 40967, 40975, 40832, 40848, 40852,     0, 
+    32768, 40960, 40961, 40963, 40967, 40975, 40832, 40848, 
+    40852,     0, 32768, 40960, 40961, 40963, 40967, 40975, 
+    40832, 40848, 40856, 40854,     0, 32768, 40960, 40961, 
+    40963, 40967, 40975, 40832, 40848,     0, 32768, 40960, 
+    40961, 40963, 40967, 40975, 40832, 40864, 40856,     0, 
+    32768, 40960, 40961, 40963, 40967, 40975, 40832, 40864, 
+    40856,     0, 32768, 40960, 40961, 40963, 40967, 40975, 
+    40832, 40864, 40856, 40858,     0, 32768, 40960, 40961, 
+    40963, 40967, 40975, 40832, 40864, 40856,     0, 32768, 
+    40960, 40961, 40963, 40967, 40975, 40832, 40864, 40865, 
+    40860,     0, 32768, 40960, 40961, 40963, 40967, 40975, 
+    40832, 40864, 40865, 40860,     0, 32768, 40960, 40961, 
+    40963, 40967, 40975, 40832, 40864, 40865, 40860, 40862, 
+        0, 32768, 40960, 40961, 40963, 40967, 40975, 40832, 
+        0, 32768, 40960, 40961, 40963, 40967, 40975, 40832, 
+    40864,     0, 32768, 40960, 40961, 40963, 40967, 40975, 
+    40832, 40864,     0, 32768, 40960, 40961, 40963, 40967, 
+    40975, 40832, 40864, 40866,     0, 32768, 40960, 40961, 
+    40963, 40967, 40975, 40832, 40864,     0, 32768, 40960, 
+    40961, 40963, 40967, 40975, 40832, 40864, 40868,     0, 
+    32768, 40960, 40961, 40963, 40967, 40975, 40832, 40864, 
+    40868,     0, 32768, 40960, 40961, 40963, 40967, 40975, 
+    40832, 40864, 40872, 40870,     0, 32768, 40960, 40961, 
+    40963, 40967, 40975, 40832, 40864,     0, 32768, 40960, 
+    40961, 40963, 40967, 40975, 40832, 40864, 40872,     0, 
+    32768, 40960, 40961, 40963, 40967, 40975, 40832, 40864, 
+    40872,     0, 32768, 40960, 40961, 40963, 40967, 40975, 
+    40832, 40864, 40872, 40874,     0, 32768, 40960, 40961, 
+    40963, 40967, 40975, 40832, 40864, 40872,     0, 32768, 
+    40960, 40961, 40963, 40967, 40975, 40832, 40864, 40880, 
+    40876,     0, 32768, 40960, 40961, 40963, 40967, 40975, 
+    40832, 40864, 40880, 40876,     0, 32768, 40960, 40961, 
+    40963, 40967, 40975, 40832, 40864, 40880, 40881, 40878, 
+        0, 32768, 40960, 40961, 40963, 40967, 40975, 40832, 
+    40864,     0, 32768, 40960, 40961, 40963, 40967, 40975, 
+    40832, 40896, 40880,     0, 32768, 40960, 40961, 40963, 
+    40967, 40975, 40832, 40896, 40880,     0, 32768, 40960, 
+    40961, 40963, 40967, 40975, 40832, 40896, 40880, 40882, 
+        0, 32768, 40960, 40961, 40963, 40967, 40975, 40832, 
+    40896, 40880,     0, 32768, 40960, 40961, 40963, 40967, 
+    40975, 40832, 40896, 40880, 40884,     0, 32768, 40960, 
+    40961, 40963, 40967, 40975, 40832, 40896, 40880, 40884, 
+        0, 32768, 40960, 40961, 40963, 40967, 40975, 40832, 
+    40896, 40880, 40888, 40886,     0, 32768, 40960, 40961, 
+    40963, 40967, 40975, 40832, 40896, 40880,     0, 32768, 
+    40960, 40961, 40963, 40967, 40975, 40832, 40896, 40897, 
+    40888,     0, 32768, 40960, 40961, 40963, 40967, 40975, 
+    40832, 40896, 40897, 40888,     0, 32768, 40960, 40961, 
+    40963, 40967, 40975, 40832, 40896, 40897, 40888, 40890, 
+        0, 32768, 40960, 40961, 40963, 40967, 40975, 40832, 
+    40896, 40897, 40888,     0, 32768, 40960, 40961, 40963, 
+    40967, 40975, 40832, 40896, 40897, 40888, 40892,     0, 
+    32768, 40960, 40961, 40963, 40967, 40975, 40832, 40896, 
+    40897, 40899, 40892,     0, 32768, 40960, 40961, 40963, 
+    40967, 40975, 40832, 40896, 40897, 40899, 40892, 40894, 
+        0, 32768, 40960, 40961, 40963, 40967, 40975, 40832, 
+        0, 32768, 40960, 40961, 40963, 40967, 40975, 40832, 
+    40896,     0, 32768, 40960, 40961, 40963, 40967, 40975, 
+    40832, 40896,     0, 32768, 40960, 40961, 40963, 40967, 
+    40975, 40832, 40896, 40898,     0, 32768, 40960, 40961, 
+    40963, 40967, 40975, 40832, 40896,     0, 32768, 40960, 
+    40961, 40963, 40967, 40975, 40832, 40896, 40900,     0, 
+    32768, 40960, 40961, 40963, 40967, 40975, 40832, 40896, 
+    40900,     0, 32768, 40960, 40961, 40963, 40967, 40975, 
+    40832, 40896, 40904, 40902,     0, 32768, 40960, 40961, 
+    40963, 40967, 40975, 40832, 40896,     0, 32768, 40960, 
+    40961, 40963, 40967, 40975, 40832, 40896, 40904,     0, 
+    32768, 40960, 40961, 40963, 40967, 40975, 40832, 40896, 
+    40904,     0, 32768, 40960, 40961, 40963, 40967, 40975, 
+    40832, 40896, 40904, 40906,     0, 32768, 40960, 40961, 
+    40963, 40967, 40975, 40832, 40896, 40904,     0, 32768, 
+    40960, 40961, 40963, 40967, 40975, 40832, 40896, 40912, 
+    40908,     0, 32768, 40960, 40961, 40963, 40967, 40975, 
+    40832, 40896, 40912, 40908,     0, 32768, 40960, 40961, 
+    40963, 40967, 40975, 40832, 40896, 40912, 40913, 40910, 
+        0, 32768, 40960, 40961, 40963, 40967, 40975, 40832, 
+    40896,     0, 32768, 40960, 40961, 40963, 40967, 40975, 
+    40832, 40896, 40912,     0, 32768, 40960, 40961, 40963, 
+    40967, 40975, 40832, 40896, 40912,     0, 32768, 40960, 
+    40961, 40963, 40967, 40975, 40832, 40896, 40912, 40914, 
+        0, 32768, 40960, 40961, 40963, 40967, 40975, 40832, 
+    40896, 40912,     0, 32768, 40960, 40961, 40963, 40967, 
+    40975, 40832, 40896, 40912, 40916,     0, 32768, 40960, 
+    40961, 40963, 40967, 40975, 40832, 40896, 40912, 40916, 
+        0, 32768, 40960, 40961, 40963, 40967, 40975, 40832, 
+    40896, 40912, 40920, 40918,     0, 32768, 40960, 40961, 
+    40963, 40967, 40975, 40832, 40896, 40912,     0, 32768, 
+    40960, 40961, 40963, 40967, 40975, 40832, 40896, 40928, 
+    40920,     0, 32768, 40960, 40961, 40963, 40967, 40975, 
+    40832, 40896, 40928, 40920,     0, 32768, 40960, 40961, 
+    40963, 40967, 40975, 40832, 40896, 40928, 40920, 40922, 
+        0, 32768, 40960, 40961, 40963, 40967, 40975, 40832, 
+    40896, 40928, 40920,     0, 32768, 40960, 40961, 40963, 
+    40967, 40975, 40832, 40896, 40928, 40929, 40924,     0, 
+    32768, 40960, 40961, 40963, 40967, 40975, 40832, 40896, 
+    40928, 40929, 40924,     0, 32768, 40960, 40961, 40963, 
+    40967, 40975, 40832, 40896, 40928, 40929, 40924, 40926, 
+        0, 32768, 40960, 40961, 40963, 40967, 40975, 40991, 
+    40896,     0, 32768, 40960, 40961, 40963, 40967, 40975, 
+    40991, 40896, 40928,     0, 32768, 40960, 40961, 40963, 
+    40967, 40975, 40991, 40896, 40928,     0, 32768, 40960, 
+    40961, 40963, 40967, 40975, 40991, 40896, 40928, 40930, 
+        0, 32768, 40960, 40961, 40963, 40967, 40975, 40991, 
+    40896, 40928,     0, 32768, 40960, 40961, 40963, 40967, 
+    40975, 40991, 40896, 40928, 40932,     0, 32768, 40960, 
+    40961, 40963, 40967, 40975, 40991, 40896, 40928, 40932, 
+        0, 32768, 40960, 40961, 40963, 40967, 40975, 40991, 
+    40896, 40928, 40936, 40934,     0, 32768, 40960, 40961, 
+    40963, 40967, 40975, 40991, 40896, 40928,     0, 32768, 
+    40960, 40961, 40963, 40967, 40975, 40991, 40896, 40928, 
+    40936,     0, 32768, 40960, 40961, 40963, 40967, 40975, 
+    40991, 40896, 40928, 40936,     0, 32768, 40960, 40961, 
+    40963, 40967, 40975, 40991, 40896, 40928, 40936, 40938, 
+        0, 32768, 40960, 40961, 40963, 40967, 40975, 40991, 
+    40896, 40928, 40936,     0, 32768, 40960, 40961, 40963, 
+    40967, 40975, 40991, 40896, 40928, 40944, 40940,     0, 
+    32768, 40960, 40961, 40963, 40967, 40975, 40991, 40896, 
+    40928, 40944, 40940,     0, 32768, 40960, 40961, 40963, 
+    40967, 40975, 40991, 40896, 40928, 40944, 40945, 40942, 
+        0, 32768, 40960, 40961, 40963, 40967, 40975, 40991, 
+    40896, 40928,     0, 32768, 40960, 40961, 40963, 40967, 
+    40975, 40991, 40896, 40928, 40944,     0, 32768, 40960, 
+    40961, 40963, 40967, 40975, 40991, 40896, 40928, 40944, 
+        0, 32768, 40960, 40961, 40963, 40967, 40975, 40991, 
+    40896, 40928, 40944, 40946,     0, 32768, 40960, 40961, 
+    40963, 40967, 40975, 40991, 40896, 40928, 40944,     0, 
+    32768, 40960, 40961, 40963, 40967, 40975, 40991, 40896, 
+    40928, 40944, 40948,     0, 32768, 40960, 40961, 40963, 
+    40967, 40975, 40991, 40896, 40928, 40944, 40948,     0, 
+    32768, 40960, 40961, 40963, 40967, 40975, 40991, 40896, 
+    40928, 40944, 40952, 40950,     0, 32768, 40960, 40961, 
+    40963, 40967, 40975, 40991, 40896, 40928, 40944,     0, 
+    32768, 40960, 40961, 40963, 40967, 40975, 40991, 40896, 
+    40928, 40944, 40952,     0, 32768, 40960, 40961, 40963, 
+    40967, 40975, 40991, 40896, 40928, 40944, 40952,     0, 
+    32768, 40960, 40961, 40963, 40967, 40975, 40991, 40896, 
+    40928, 40944, 40952, 40954,     0, 32768, 40960, 40961, 
+    40963, 40967, 40975, 40991, 40896, 40928, 40944, 40952, 
+        0, 32768, 40960, 40961, 40963, 40967, 40975, 40991, 
+    40896, 40928, 40944, 40952, 40956,     0, 32768, 40960, 
+    40961, 40963, 40967, 40975, 40991, 40896, 40928, 40944, 
+    40952, 40956,     0, 32768, 40960, 40961, 40963, 40967, 
+    40975, 40991, 40896, 40928, 40944, 40952, 40956, 40958, 
+        0, 32768,     0, 32768, 40960,     0, 32768, 40960, 
+        0, 32768, 40960, 40962,     0, 32768, 40960,     0, 
+    32768, 40960, 40964,     0, 32768, 40960, 40964,     0, 
+    32768, 40960, 40968, 40966,     0, 32768, 40960,     0, 
+    32768, 40960, 40968,     0, 32768, 40960, 40968,     0, 
+    32768, 40960, 40968, 40970,     0, 32768, 40960, 40968, 
+        0, 32768, 40960, 40976, 40972,     0, 32768, 40960, 
+    40976, 40972,     0, 32768, 40960, 40976, 40977, 40974, 
+        0, 32768, 40960,     0, 32768, 40960, 40976,     0, 
+    32768, 40960, 40976,     0, 32768, 40960, 40976, 40978, 
+        0, 32768, 40960, 40976,     0, 32768, 40960, 40976, 
+    40980,     0, 32768, 40960, 40976, 40980,     0, 32768, 
+    40960, 40976, 40984, 40982,     0, 32768, 40960, 40976, 
+        0, 32768, 40960, 40992, 40984,     0, 32768, 40960, 
+    40992, 40984,     0, 32768, 40960, 40992, 40984, 40986, 
+        0, 32768, 40960, 40992, 40984,     0, 32768, 40960, 
+    40992, 40993, 40988,     0, 32768, 40960, 40992, 40993, 
+    40988,     0, 32768, 40960, 40992, 40993, 40988, 40990, 
+        0, 32768, 40960,     0, 32768, 40960, 40992,     0, 
+    32768, 40960, 40992,     0, 32768, 40960, 40992, 40994, 
+        0, 32768, 40960, 40992,     0, 32768, 40960, 40992, 
+    40996,     0, 32768, 40960, 40992, 40996,     0, 32768, 
+    40960, 40992, 41000, 40998,     0, 32768, 40960, 40992, 
+        0, 32768, 40960, 40992, 41000,     0, 32768, 40960, 
+    40992, 41000,     0, 32768, 40960, 40992, 41000, 41002, 
+        0, 32768, 40960, 40992, 41000,     0, 32768, 40960, 
+    40992, 41008, 41004,     0, 32768, 40960, 40992, 41008, 
+    41004,     0, 32768, 40960, 40992, 41008, 41009, 41006, 
+        0, 32768, 40960, 40992,     0, 32768, 40960, 41024, 
+    41008,     0, 32768, 40960, 41024, 41008,     0, 32768, 
+    40960, 41024, 41008, 41010,     0, 32768, 40960, 41024, 
+    41008,     0, 32768, 40960, 41024, 41008, 41012,     0, 
+    32768, 40960, 41024, 41008, 41012,     0, 32768, 40960, 
+    41024, 41008, 41016, 41014,     0, 32768, 40960, 41024, 
+    41008,     0, 32768, 40960, 41024, 41025, 41016,     0, 
+    32768, 40960, 41024, 41025, 41016,     0, 32768, 40960, 
+    41024, 41025, 41016, 41018,     0, 32768, 40960, 41024, 
+    41025, 41016,     0, 32768, 40960, 41024, 41025, 41016, 
+    41020,     0, 32768, 40960, 41024, 41025, 41027, 41020, 
+        0, 32768, 40960, 41024, 41025, 41027, 41020, 41022, 
+        0, 32768, 40960,     0, 32768, 40960, 41024,     0, 
+    32768, 40960, 41024,     0, 32768, 40960, 41024, 41026, 
+        0, 32768, 40960, 41024,     0, 32768, 40960, 41024, 
+    41028,     0, 32768, 40960, 41024, 41028,     0, 32768, 
+    40960, 41024, 41032, 41030,     0, 32768, 40960, 41024, 
+        0, 32768, 40960, 41024, 41032,     0, 32768, 40960, 
+    41024, 41032,     0, 32768, 40960, 41024, 41032, 41034, 
+        0, 32768, 40960, 41024, 41032,     0, 32768, 40960, 
+    41024, 41040, 41036,     0, 32768, 40960, 41024, 41040, 
+    41036,     0, 32768, 40960, 41024, 41040, 41041, 41038, 
+        0, 32768, 40960, 41024,     0, 32768, 40960, 41024, 
+    41040,     0, 32768, 40960, 41024, 41040,     0, 32768, 
+    40960, 41024, 41040, 41042,     0, 32768, 40960, 41024, 
+    41040,     0, 32768, 40960, 41024, 41040, 41044,     0, 
+    32768, 40960, 41024, 41040, 41044,     0, 32768, 40960, 
+    41024, 41040, 41048, 41046,     0, 32768, 40960, 41024, 
+    41040,     0, 32768, 40960, 41024, 41056, 41048,     0, 
+    32768, 40960, 41024, 41056, 41048,     0, 32768, 40960, 
+    41024, 41056, 41048, 41050,     0, 32768, 40960, 41024, 
+    41056, 41048,     0, 32768, 40960, 41024, 41056, 41057, 
+    41052,     0, 32768, 40960, 41024, 41056, 41057, 41052, 
+        0, 32768, 40960, 41024, 41056, 41057, 41052, 41054, 
+        0, 32768, 40960, 41024,     0, 32768, 40960, 41088, 
+    41056,     0, 32768, 40960, 41088, 41056,     0, 32768, 
+    40960, 41088, 41056, 41058,     0, 32768, 40960, 41088, 
+    41056,     0, 32768, 40960, 41088, 41056, 41060,     0, 
+    32768, 40960, 41088, 41056, 41060,     0, 32768, 40960, 
+    41088, 41056, 41064, 41062,     0, 32768, 40960, 41088, 
+    41056,     0, 32768, 40960, 41088, 41056, 41064,     0, 
+    32768, 40960, 41088, 41056, 41064,     0, 32768, 40960, 
+    41088, 41056, 41064, 41066,     0, 32768, 40960, 41088, 
+    41056, 41064,     0, 32768, 40960, 41088, 41056, 41072, 
+    41068,     0, 32768, 40960, 41088, 41056, 41072, 41068, 
+        0, 32768, 40960, 41088, 41056, 41072, 41073, 41070, 
+        0, 32768, 40960, 41088, 41056,     0, 32768, 40960, 
+    41088, 41089, 41072,     0, 32768, 40960, 41088, 41089, 
+    41072,     0, 32768, 40960, 41088, 41089, 41072, 41074, 
+        0, 32768, 40960, 41088, 41089, 41072,     0, 32768, 
+    40960, 41088, 41089, 41072, 41076,     0, 32768, 40960, 
+    41088, 41089, 41072, 41076,     0, 32768, 40960, 41088, 
+    41089, 41072, 41080, 41078,     0, 32768, 40960, 41088, 
+    41089, 41072,     0, 32768, 40960, 41088, 41089, 41072, 
+    41080,     0, 32768, 40960, 41088, 41089, 41091, 41080, 
+        0, 32768, 40960, 41088, 41089, 41091, 41080, 41082, 
+        0, 32768, 40960, 41088, 41089, 41091, 41080,     0, 
+    32768, 40960, 41088, 41089, 41091, 41080, 41084,     0, 
+    32768, 40960, 41088, 41089, 41091, 41080, 41084,     0, 
+    32768, 40960, 41088, 41089, 41091, 41080, 41084, 41086, 
+        0, 32768, 40960,     0, 32768, 40960, 41088,     0, 
+    32768, 40960, 41088,     0, 32768, 40960, 41088, 41090, 
+        0, 32768, 40960, 41088,     0, 32768, 40960, 41088, 
+    41092,     0, 32768, 40960, 41088, 41092,     0, 32768, 
+    40960, 41088, 41096, 41094,     0, 32768, 40960, 41088, 
+        0, 32768, 40960, 41088, 41096,     0, 32768, 40960, 
+    41088, 41096,     0, 32768, 40960, 41088, 41096, 41098, 
+        0, 32768, 40960, 41088, 41096,     0, 32768, 40960, 
+    41088, 41104, 41100,     0, 32768, 40960, 41088, 41104, 
+    41100,     0, 32768, 40960, 41088, 41104, 41105, 41102, 
+        0, 32768, 40960, 41088,     0, 32768, 40960, 41088, 
+    41104,     0, 32768, 40960, 41088, 41104,     0, 32768, 
+    40960, 41088, 41104, 41106,     0, 32768, 40960, 41088, 
+    41104,     0, 32768, 40960, 41088, 41104, 41108,     0, 
+    32768, 40960, 41088, 41104, 41108,     0, 32768, 40960, 
+    41088, 41104, 41112, 41110,     0, 32768, 40960, 41088, 
+    41104,     0, 32768, 40960, 41088, 41120, 41112,     0, 
+    32768, 40960, 41088, 41120, 41112,     0, 32768, 40960, 
+    41088, 41120, 41112, 41114,     0, 32768, 40960, 41088, 
+    41120, 41112,     0, 32768, 40960, 41088, 41120, 41121, 
+    41116,     0, 32768, 40960, 41088, 41120, 41121, 41116, 
+        0, 32768, 40960, 41088, 41120, 41121, 41116, 41118, 
+        0, 32768, 40960, 41088,     0, 32768, 40960, 41088, 
+    41120,     0, 32768, 40960, 41088, 41120,     0, 32768, 
+    40960, 41088, 41120, 41122,     0, 32768, 40960, 41088, 
+    41120,     0, 32768, 40960, 41088, 41120, 41124,     0, 
+    32768, 40960, 41088, 41120, 41124,     0, 32768, 40960, 
+    41088, 41120, 41128, 41126,     0, 32768, 40960, 41088, 
+    41120,     0, 32768, 40960, 41088, 41120, 41128,     0, 
+    32768, 40960, 41088, 41120, 41128,     0, 32768, 40960, 
+    41088, 41120, 41128, 41130,     0, 32768, 40960, 41088, 
+    41120, 41128,     0, 32768, 40960, 41088, 41120, 41136, 
+    41132,     0, 32768, 40960, 41088, 41120, 41136, 41132, 
+        0, 32768, 40960, 41088, 41120, 41136, 41137, 41134, 
+        0, 32768, 40960, 41088, 41120,     0, 32768, 40960, 
+    41088, 41152, 41136,     0, 32768, 40960, 41088, 41152, 
+    41136,     0, 32768, 40960, 41088, 41152, 41136, 41138, 
+        0, 32768, 40960, 41088, 41152, 41136,     0, 32768, 
+    40960, 41088, 41152, 41136, 41140,     0, 32768, 40960, 
+    41088, 41152, 41136, 41140,     0, 32768, 40960, 41088, 
+    41152, 41136, 41144, 41142,     0, 32768, 40960, 41088, 
+    41152, 41136,     0, 32768, 40960, 41088, 41152, 41153, 
+    41144,     0, 32768, 40960, 41088, 41152, 41153, 41144, 
+        0, 32768, 40960, 41088, 41152, 41153, 41144, 41146, 
+        0, 32768, 40960, 41088, 41152, 41153, 41144,     0, 
+    32768, 40960, 41088, 41152, 41153, 41144, 41148,     0, 
+    32768, 40960, 41088, 41152, 41153, 41155, 41148,     0, 
+    32768, 40960, 41088, 41152, 41153, 41155, 41148, 41150, 
+        0, 32768, 40960, 41088,     0, 32768, 40960, 41216, 
+    41152,     0, 32768, 40960, 41216, 41152,     0, 32768, 
+    40960, 41216, 41152, 41154,     0, 32768, 40960, 41216, 
+    41152,     0, 32768, 40960, 41216, 41152, 41156,     0, 
+    32768, 40960, 41216, 41152, 41156,     0, 32768, 40960, 
+    41216, 41152, 41160, 41158,     0, 32768, 40960, 41216, 
+    41152,     0, 32768, 40960, 41216, 41152, 41160,     0, 
+    32768, 40960, 41216, 41152, 41160,     0, 32768, 40960, 
+    41216, 41152, 41160, 41162,     0, 32768, 40960, 41216, 
+    41152, 41160,     0, 32768, 40960, 41216, 41152, 41168, 
+    41164,     0, 32768, 40960, 41216, 41152, 41168, 41164, 
+        0, 32768, 40960, 41216, 41152, 41168, 41169, 41166, 
+        0, 32768, 40960, 41216, 41152,     0, 32768, 40960, 
+    41216, 41152, 41168,     0, 32768, 40960, 41216, 41152, 
+    41168,     0, 32768, 40960, 41216, 41152, 41168, 41170, 
+        0, 32768, 40960, 41216, 41152, 41168,     0, 32768, 
+    40960, 41216, 41152, 41168, 41172,     0, 32768, 40960, 
+    41216, 41152, 41168, 41172,     0, 32768, 40960, 41216, 
+    41152, 41168, 41176, 41174,     0, 32768, 40960, 41216, 
+    41152, 41168,     0, 32768, 40960, 41216, 41152, 41184, 
+    41176,     0, 32768, 40960, 41216, 41152, 41184, 41176, 
+        0, 32768, 40960, 41216, 41152, 41184, 41176, 41178, 
+        0, 32768, 40960, 41216, 41152, 41184, 41176,     0, 
+    32768, 40960, 41216, 41152, 41184, 41185, 41180,     0, 
+    32768, 40960, 41216, 41152, 41184, 41185, 41180,     0, 
+    32768, 40960, 41216, 41152, 41184, 41185, 41180, 41182, 
+        0, 32768, 40960, 41216, 41152,     0, 32768, 40960, 
+    41216, 41217, 41184,     0, 32768, 40960, 41216, 41217, 
+    41184,     0, 32768, 40960, 41216, 41217, 41184, 41186, 
+        0, 32768, 40960, 41216, 41217, 41184,     0, 32768, 
+    40960, 41216, 41217, 41184, 41188,     0, 32768, 40960, 
+    41216, 41217, 41184, 41188,     0, 32768, 40960, 41216, 
+    41217, 41184, 41192, 41190,     0, 32768, 40960, 41216, 
+    41217, 41184,     0, 32768, 40960, 41216, 41217, 41184, 
+    41192,     0, 32768, 40960, 41216, 41217, 41184, 41192, 
+        0, 32768, 40960, 41216, 41217, 41184, 41192, 41194, 
+        0, 32768, 40960, 41216, 41217, 41184, 41192,     0, 
+    32768, 40960, 41216, 41217, 41184, 41200, 41196,     0, 
+    32768, 40960, 41216, 41217, 41184, 41200, 41196,     0, 
+    32768, 40960, 41216, 41217, 41184, 41200, 41201, 41198, 
+        0, 32768, 40960, 41216, 41217, 41184,     0, 32768, 
+    40960, 41216, 41217, 41184, 41200,     0, 32768, 40960, 
+    41216, 41217, 41219, 41200,     0, 32768, 40960, 41216, 
+    41217, 41219, 41200, 41202,     0, 32768, 40960, 41216, 
+    41217, 41219, 41200,     0, 32768, 40960, 41216, 41217, 
+    41219, 41200, 41204,     0, 32768, 40960, 41216, 41217, 
+    41219, 41200, 41204,     0, 32768, 40960, 41216, 41217, 
+    41219, 41200, 41208, 41206,     0, 32768, 40960, 41216, 
+    41217, 41219, 41200,     0, 32768, 40960, 41216, 41217, 
+    41219, 41200, 41208,     0, 32768, 40960, 41216, 41217, 
+    41219, 41200, 41208,     0, 32768, 40960, 41216, 41217, 
+    41219, 41200, 41208, 41210,     0, 32768, 40960, 41216, 
+    41217, 41219, 41223, 41208,     0, 32768, 40960, 41216, 
+    41217, 41219, 41223, 41208, 41212,     0, 32768, 40960, 
+    41216, 41217, 41219, 41223, 41208, 41212,     0, 32768, 
+    40960, 41216, 41217, 41219, 41223, 41208, 41212, 41214, 
+        0, 32768, 40960,     0, 32768, 40960, 41216,     0, 
+    32768, 40960, 41216,     0, 32768, 40960, 41216, 41218, 
+        0, 32768, 40960, 41216,     0, 32768, 40960, 41216, 
+    41220,     0, 32768, 40960, 41216, 41220,     0, 32768, 
+    40960, 41216, 41224, 41222,     0, 32768, 40960, 41216, 
+        0, 32768, 40960, 41216, 41224,     0, 32768, 40960, 
+    41216, 41224,     0, 32768, 40960, 41216, 41224, 41226, 
+        0, 32768, 40960, 41216, 41224,     0, 32768, 40960, 
+    41216, 41232, 41228,     0, 32768, 40960, 41216, 41232, 
+    41228,     0, 32768, 40960, 41216, 41232, 41233, 41230, 
+        0, 32768, 40960, 41216,     0, 32768, 40960, 41216, 
+    41232,     0, 32768, 40960, 41216, 41232,     0, 32768, 
+    40960, 41216, 41232, 41234,     0, 32768, 40960, 41216, 
+    41232,     0, 32768, 40960, 41216, 41232, 41236,     0, 
+    32768, 40960, 41216, 41232, 41236,     0, 32768, 40960, 
+    41216, 41232, 41240, 41238,     0, 32768, 40960, 41216, 
+    41232,     0, 32768, 40960, 41216, 41248, 41240,     0, 
+    32768, 40960, 41216, 41248, 41240,     0, 32768, 40960, 
+    41216, 41248, 41240, 41242,     0, 32768, 40960, 41216, 
+    41248, 41240,     0, 32768, 40960, 41216, 41248, 41249, 
+    41244,     0, 32768, 40960, 41216, 41248, 41249, 41244, 
+        0, 32768, 40960, 41216, 41248, 41249, 41244, 41246, 
+        0, 32768, 40960, 41216,     0, 32768, 40960, 41216, 
+    41248,     0, 32768, 40960, 41216, 41248,     0, 32768, 
+    40960, 41216, 41248, 41250,     0, 32768, 40960, 41216, 
+    41248,     0, 32768, 40960, 41216, 41248, 41252,     0, 
+    32768, 40960, 41216, 41248, 41252,     0, 32768, 40960, 
+    41216, 41248, 41256, 41254,     0, 32768, 40960, 41216, 
+    41248,     0, 32768, 40960, 41216, 41248, 41256,     0, 
+    32768, 40960, 41216, 41248, 41256,     0, 32768, 40960, 
+    41216, 41248, 41256, 41258,     0, 32768, 40960, 41216, 
+    41248, 41256,     0, 32768, 40960, 41216, 41248, 41264, 
+    41260,     0, 32768, 40960, 41216, 41248, 41264, 41260, 
+        0, 32768, 40960, 41216, 41248, 41264, 41265, 41262, 
+        0, 32768, 40960, 41216, 41248,     0, 32768, 40960, 
+    41216, 41280, 41264,     0, 32768, 40960, 41216, 41280, 
+    41264,     0, 32768, 40960, 41216, 41280, 41264, 41266, 
+        0, 32768, 40960, 41216, 41280, 41264,     0, 32768, 
+    40960, 41216, 41280, 41264, 41268,     0, 32768, 40960, 
+    41216, 41280, 41264, 41268,     0, 32768, 40960, 41216, 
+    41280, 41264, 41272, 41270,     0, 32768, 40960, 41216, 
+    41280, 41264,     0, 32768, 40960, 41216, 41280, 41281, 
+    41272,     0, 32768, 40960, 41216, 41280, 41281, 41272, 
+        0, 32768, 40960, 41216, 41280, 41281, 41272, 41274, 
+        0, 32768, 40960, 41216, 41280, 41281, 41272,     0, 
+    32768, 40960, 41216, 41280, 41281, 41272, 41276,     0, 
+    32768, 40960, 41216, 41280, 41281, 41283, 41276,     0, 
+    32768, 40960, 41216, 41280, 41281, 41283, 41276, 41278, 
+        0, 32768, 40960, 41216,     0, 32768, 40960, 41216, 
+    41280,     0, 32768, 40960, 41216, 41280,     0, 32768, 
+    40960, 41216, 41280, 41282,     0, 32768, 40960, 41216, 
+    41280,     0, 32768, 40960, 41216, 41280, 41284,     0, 
+    32768, 40960, 41216, 41280, 41284,     0, 32768, 40960, 
+    41216, 41280, 41288, 41286,     0, 32768, 40960, 41216, 
+    41280,     0, 32768, 40960, 41216, 41280, 41288,     0, 
+    32768, 40960, 41216, 41280, 41288,     0, 32768, 40960, 
+    41216, 41280, 41288, 41290,     0, 32768, 40960, 41216, 
+    41280, 41288,     0, 32768, 40960, 41216, 41280, 41296, 
+    41292,     0, 32768, 40960, 41216, 41280, 41296, 41292, 
+        0, 32768, 40960, 41216, 41280, 41296, 41297, 41294, 
+        0, 32768, 40960, 41216, 41280,     0, 32768, 40960, 
+    41216, 41280, 41296,     0, 32768, 40960, 41216, 41280, 
+    41296,     0, 32768, 40960, 41216, 41280, 41296, 41298, 
+        0, 32768, 40960, 41216, 41280, 41296,     0, 32768, 
+    40960, 41216, 41280, 41296, 41300,     0, 32768, 40960, 
+    41216, 41280, 41296, 41300,     0, 32768, 40960, 41216, 
+    41280, 41296, 41304, 41302,     0, 32768, 40960, 41216, 
+    41280, 41296,     0, 32768, 40960, 41216, 41280, 41312, 
+    41304,     0, 32768, 40960, 41216, 41280, 41312, 41304, 
+        0, 32768, 40960, 41216, 41280, 41312, 41304, 41306, 
+        0, 32768, 40960, 41216, 41280, 41312, 41304,     0, 
+    32768, 40960, 41216, 41280, 41312, 41313, 41308,     0, 
+    32768, 40960, 41216, 41280, 41312, 41313, 41308,     0, 
+    32768, 40960, 41216, 41280, 41312, 41313, 41308, 41310, 
+        0, 32768, 40960, 41216, 41280,     0, 32768, 40960, 
+    41216, 41344, 41312,     0, 32768, 40960, 41216, 41344, 
+    41312,     0, 32768, 40960, 41216, 41344, 41312, 41314, 
+        0, 32768, 40960, 41216, 41344, 41312,     0, 32768, 
+    40960, 41216, 41344, 41312, 41316,     0, 32768, 40960, 
+    41216, 41344, 41312, 41316,     0, 32768, 40960, 41216, 
+    41344, 41312, 41320, 41318,     0, 32768, 40960, 41216, 
+    41344, 41312,     0, 32768, 40960, 41216, 41344, 41312, 
+    41320,     0, 32768, 40960, 41216, 41344, 41312, 41320, 
+        0, 32768, 40960, 41216, 41344, 41312, 41320, 41322, 
+        0, 32768, 40960, 41216, 41344, 41312, 41320,     0, 
+    32768, 40960, 41216, 41344, 41312, 41328, 41324,     0, 
+    32768, 40960, 41216, 41344, 41312, 41328, 41324,     0, 
+    32768, 40960, 41216, 41344, 41312, 41328, 41329, 41326, 
+        0, 32768, 40960, 41216, 41344, 41312,     0, 32768, 
+    40960, 41216, 41344, 41345, 41328,     0, 32768, 40960, 
+    41216, 41344, 41345, 41328,     0, 32768, 40960, 41216, 
+    41344, 41345, 41328, 41330,     0, 32768, 40960, 41216, 
+    41344, 41345, 41328,     0, 32768, 40960, 41216, 41344, 
+    41345, 41328, 41332,     0, 32768, 40960, 41216, 41344, 
+    41345, 41328, 41332,     0, 32768, 40960, 41216, 41344, 
+    41345, 41328, 41336, 41334,     0, 32768, 40960, 41216, 
+    41344, 41345, 41328,     0, 32768, 40960, 41216, 41344, 
+    41345, 41328, 41336,     0, 32768, 40960, 41216, 41344, 
+    41345, 41347, 41336,     0, 32768, 40960, 41216, 41344, 
+    41345, 41347, 41336, 41338,     0, 32768, 40960, 41216, 
+    41344, 41345, 41347, 41336,     0, 32768, 40960, 41216, 
+    41344, 41345, 41347, 41336, 41340,     0, 32768, 40960, 
+    41216, 41344, 41345, 41347, 41336, 41340,     0, 32768, 
+    40960, 41216, 41344, 41345, 41347, 41336, 41340, 41342, 
+        0, 32768, 40960, 41216,     0, 32768, 40960, 41472, 
+    41344,     0, 32768, 40960, 41472, 41344,     0, 32768, 
+    40960, 41472, 41344, 41346,     0, 32768, 40960, 41472, 
+    41344,     0, 32768, 40960, 41472, 41344, 41348,     0, 
+    32768, 40960, 41472, 41344, 41348,     0, 32768, 40960, 
+    41472, 41344, 41352, 41350,     0, 32768, 40960, 41472, 
+    41344,     0, 32768, 40960, 41472, 41344, 41352,     0, 
+    32768, 40960, 41472, 41344, 41352,     0, 32768, 40960, 
+    41472, 41344, 41352, 41354,     0, 32768, 40960, 41472, 
+    41344, 41352,     0, 32768, 40960, 41472, 41344, 41360, 
+    41356,     0, 32768, 40960, 41472, 41344, 41360, 41356, 
+        0, 32768, 40960, 41472, 41344, 41360, 41361, 41358, 
+        0, 32768, 40960, 41472, 41344,     0, 32768, 40960, 
+    41472, 41344, 41360,     0, 32768, 40960, 41472, 41344, 
+    41360,     0, 32768, 40960, 41472, 41344, 41360, 41362, 
+        0, 32768, 40960, 41472, 41344, 41360,     0, 32768, 
+    40960, 41472, 41344, 41360, 41364,     0, 32768, 40960, 
+    41472, 41344, 41360, 41364,     0, 32768, 40960, 41472, 
+    41344, 41360, 41368, 41366,     0, 32768, 40960, 41472, 
+    41344, 41360,     0, 32768, 40960, 41472, 41344, 41376, 
+    41368,     0, 32768, 40960, 41472, 41344, 41376, 41368, 
+        0, 32768, 40960, 41472, 41344, 41376, 41368, 41370, 
+        0, 32768, 40960, 41472, 41344, 41376, 41368,     0, 
+    32768, 40960, 41472, 41344, 41376, 41377, 41372,     0, 
+    32768, 40960, 41472, 41344, 41376, 41377, 41372,     0, 
+    32768, 40960, 41472, 41344, 41376, 41377, 41372, 41374, 
+        0, 32768, 40960, 41472, 41344,     0, 32768, 40960, 
+    41472, 41344, 41376,     0, 32768, 40960, 41472, 41344, 
+    41376,     0, 32768, 40960, 41472, 41344, 41376, 41378, 
+        0, 32768, 40960, 41472, 41344, 41376,     0, 32768, 
+    40960, 41472, 41344, 41376, 41380,     0, 32768, 40960, 
+    41472, 41344, 41376, 41380,     0, 32768, 40960, 41472, 
+    41344, 41376, 41384, 41382,     0, 32768, 40960, 41472, 
+    41344, 41376,     0, 32768, 40960, 41472, 41344, 41376, 
+    41384,     0, 32768, 40960, 41472, 41344, 41376, 41384, 
+        0, 32768, 40960, 41472, 41344, 41376, 41384, 41386, 
+        0, 32768, 40960, 41472, 41344, 41376, 41384,     0, 
+    32768, 40960, 41472, 41344, 41376, 41392, 41388,     0, 
+    32768, 40960, 41472, 41344, 41376, 41392, 41388,     0, 
+    32768, 40960, 41472, 41344, 41376, 41392, 41393, 41390, 
+        0, 32768, 40960, 41472, 41344, 41376,     0, 32768, 
+    40960, 41472, 41344, 41408, 41392,     0, 32768, 40960, 
+    41472, 41344, 41408, 41392,     0, 32768, 40960, 41472, 
+    41344, 41408, 41392, 41394,     0, 32768, 40960, 41472, 
+    41344, 41408, 41392,     0, 32768, 40960, 41472, 41344, 
+    41408, 41392, 41396,     0, 32768, 40960, 41472, 41344, 
+    41408, 41392, 41396,     0, 32768, 40960, 41472, 41344, 
+    41408, 41392, 41400, 41398,     0, 32768, 40960, 41472, 
+    41344, 41408, 41392,     0, 32768, 40960, 41472, 41344, 
+    41408, 41409, 41400,     0, 32768, 40960, 41472, 41344, 
+    41408, 41409, 41400,     0, 32768, 40960, 41472, 41344, 
+    41408, 41409, 41400, 41402,     0, 32768, 40960, 41472, 
+    41344, 41408, 41409, 41400,     0, 32768, 40960, 41472, 
+    41344, 41408, 41409, 41400, 41404,     0, 32768, 40960, 
+    41472, 41344, 41408, 41409, 41411, 41404,     0, 32768, 
+    40960, 41472, 41344, 41408, 41409, 41411, 41404, 41406, 
+        0, 32768, 40960, 41472, 41344,     0, 32768, 40960, 
+    41472, 41473, 41408,     0, 32768, 40960, 41472, 41473, 
+    41408,     0, 32768, 40960, 41472, 41473, 41408, 41410, 
+        0, 32768, 40960, 41472, 41473, 41408,     0, 32768, 
+    40960, 41472, 41473, 41408, 41412,     0, 32768, 40960, 
+    41472, 41473, 41408, 41412,     0, 32768, 40960, 41472, 
+    41473, 41408, 41416, 41414,     0, 32768, 40960, 41472, 
+    41473, 41408,     0, 32768, 40960, 41472, 41473, 41408, 
+    41416,     0, 32768, 40960, 41472, 41473, 41408, 41416, 
+        0, 32768, 40960, 41472, 41473, 41408, 41416, 41418, 
+        0, 32768, 40960, 41472, 41473, 41408, 41416,     0, 
+    32768, 40960, 41472, 41473, 41408, 41424, 41420,     0, 
+    32768, 40960, 41472, 41473, 41408, 41424, 41420,     0, 
+    32768, 40960, 41472, 41473, 41408, 41424, 41425, 41422, 
+        0, 32768, 40960, 41472, 41473, 41408,     0, 32768, 
+    40960, 41472, 41473, 41408, 41424,     0, 32768, 40960, 
+    41472, 41473, 41408, 41424,     0, 32768, 40960, 41472, 
+    41473, 41408, 41424, 41426,     0, 32768, 40960, 41472, 
+    41473, 41408, 41424,     0, 32768, 40960, 41472, 41473, 
+    41408, 41424, 41428,     0, 32768, 40960, 41472, 41473, 
+    41408, 41424, 41428,     0, 32768, 40960, 41472, 41473, 
+    41408, 41424, 41432, 41430,     0, 32768, 40960, 41472, 
+    41473, 41408, 41424,     0, 32768, 40960, 41472, 41473, 
+    41408, 41440, 41432,     0, 32768, 40960, 41472, 41473, 
+    41408, 41440, 41432,     0, 32768, 40960, 41472, 41473, 
+    41408, 41440, 41432, 41434,     0, 32768, 40960, 41472, 
+    41473, 41408, 41440, 41432,     0, 32768, 40960, 41472, 
+    41473, 41408, 41440, 41441, 41436,     0, 32768, 40960, 
+    41472, 41473, 41408, 41440, 41441, 41436,     0, 32768, 
+    40960, 41472, 41473, 41408, 41440, 41441, 41436, 41438, 
+        0, 32768, 40960, 41472, 41473, 41408,     0, 32768, 
+    40960, 41472, 41473, 41408, 41440,     0, 32768, 40960, 
+    41472, 41473, 41475, 41440,     0, 32768, 40960, 41472, 
+    41473, 41475, 41440, 41442,     0, 32768, 40960, 41472, 
+    41473, 41475, 41440,     0, 32768, 40960, 41472, 41473, 
+    41475, 41440, 41444,     0, 32768, 40960, 41472, 41473, 
+    41475, 41440, 41444,     0, 32768, 40960, 41472, 41473, 
+    41475, 41440, 41448, 41446,     0, 32768, 40960, 41472, 
+    41473, 41475, 41440,     0, 32768, 40960, 41472, 41473, 
+    41475, 41440, 41448,     0, 32768, 40960, 41472, 41473, 
+    41475, 41440, 41448,     0, 32768, 40960, 41472, 41473, 
+    41475, 41440, 41448, 41450,     0, 32768, 40960, 41472, 
+    41473, 41475, 41440, 41448,     0, 32768, 40960, 41472, 
+    41473, 41475, 41440, 41456, 41452,     0, 32768, 40960, 
+    41472, 41473, 41475, 41440, 41456, 41452,     0, 32768, 
+    40960, 41472, 41473, 41475, 41440, 41456, 41457, 41454, 
+        0, 32768, 40960, 41472, 41473, 41475, 41440,     0, 
+    32768, 40960, 41472, 41473, 41475, 41440, 41456,     0, 
+    32768, 40960, 41472, 41473, 41475, 41440, 41456,     0, 
+    32768, 40960, 41472, 41473, 41475, 41440, 41456, 41458, 
+        0, 32768, 40960, 41472, 41473, 41475, 41479, 41456, 
+        0, 32768, 40960, 41472, 41473, 41475, 41479, 41456, 
+    41460,     0, 32768, 40960, 41472, 41473, 41475, 41479, 
+    41456, 41460,     0, 32768, 40960, 41472, 41473, 41475, 
+    41479, 41456, 41464, 41462,     0, 32768, 40960, 41472, 
+    41473, 41475, 41479, 41456,     0, 32768, 40960, 41472, 
+    41473, 41475, 41479, 41456, 41464,     0, 32768, 40960, 
+    41472, 41473, 41475, 41479, 41456, 41464,     0, 32768, 
+    40960, 41472, 41473, 41475, 41479, 41456, 41464, 41466, 
+        0, 32768, 40960, 41472, 41473, 41475, 41479, 41456, 
+    41464,     0, 32768, 40960, 41472, 41473, 41475, 41479, 
+    41456, 41464, 41468,     0, 32768, 40960, 41472, 41473, 
+    41475, 41479, 41456, 41464, 41468,     0, 32768, 40960, 
+    41472, 41473, 41475, 41479, 41456, 41464, 41468, 41470, 
+        0, 32768, 40960,     0, 32768, 40960, 41472,     0, 
+    32768, 40960, 41472,     0, 32768, 40960, 41472, 41474, 
+        0, 32768, 40960, 41472,     0, 32768, 40960, 41472, 
+    41476,     0, 32768, 40960, 41472, 41476,     0, 32768, 
+    40960, 41472, 41480, 41478,     0, 32768, 40960, 41472, 
+        0, 32768, 40960, 41472, 41480,     0, 32768, 40960, 
+    41472, 41480,     0, 32768, 40960, 41472, 41480, 41482, 
+        0, 32768, 40960, 41472, 41480,     0, 32768, 40960, 
+    41472, 41488, 41484,     0, 32768, 40960, 41472, 41488, 
+    41484,     0, 32768, 40960, 41472, 41488, 41489, 41486, 
+        0, 32768, 40960, 41472,     0, 32768, 40960, 41472, 
+    41488,     0, 32768, 40960, 41472, 41488,     0, 32768, 
+    40960, 41472, 41488, 41490,     0, 32768, 40960, 41472, 
+    41488,     0, 32768, 40960, 41472, 41488, 41492,     0, 
+    32768, 40960, 41472, 41488, 41492,     0, 32768, 40960, 
+    41472, 41488, 41496, 41494,     0, 32768, 40960, 41472, 
+    41488,     0, 32768, 40960, 41472, 41504, 41496,     0, 
+    32768, 40960, 41472, 41504, 41496,     0, 32768, 40960, 
+    41472, 41504, 41496, 41498,     0, 32768, 40960, 41472, 
+    41504, 41496,     0, 32768, 40960, 41472, 41504, 41505, 
+    41500,     0, 32768, 40960, 41472, 41504, 41505, 41500, 
+        0, 32768, 40960, 41472, 41504, 41505, 41500, 41502, 
+        0, 32768, 40960, 41472,     0, 32768, 40960, 41472, 
+    41504,     0, 32768, 40960, 41472, 41504,     0, 32768, 
+    40960, 41472, 41504, 41506,     0, 32768, 40960, 41472, 
+    41504,     0, 32768, 40960, 41472, 41504, 41508,     0, 
+    32768, 40960, 41472, 41504, 41508,     0, 32768, 40960, 
+    41472, 41504, 41512, 41510,     0, 32768, 40960, 41472, 
+    41504,     0, 32768, 40960, 41472, 41504, 41512,     0, 
+    32768, 40960, 41472, 41504, 41512,     0, 32768, 40960, 
+    41472, 41504, 41512, 41514,     0, 32768, 40960, 41472, 
+    41504, 41512,     0, 32768, 40960, 41472, 41504, 41520, 
+    41516,     0, 32768, 40960, 41472, 41504, 41520, 41516, 
+        0, 32768, 40960, 41472, 41504, 41520, 41521, 41518, 
+        0, 32768, 40960, 41472, 41504,     0, 32768, 40960, 
+    41472, 41536, 41520,     0, 32768, 40960, 41472, 41536, 
+    41520,     0, 32768, 40960, 41472, 41536, 41520, 41522, 
+        0, 32768, 40960, 41472, 41536, 41520,     0, 32768, 
+    40960, 41472, 41536, 41520, 41524,     0, 32768, 40960, 
+    41472, 41536, 41520, 41524,     0, 32768, 40960, 41472, 
+    41536, 41520, 41528, 41526,     0, 32768, 40960, 41472, 
+    41536, 41520,     0, 32768, 40960, 41472, 41536, 41537, 
+    41528,     0, 32768, 40960, 41472, 41536, 41537, 41528, 
+        0, 32768, 40960, 41472, 41536, 41537, 41528, 41530, 
+        0, 32768, 40960, 41472, 41536, 41537, 41528,     0, 
+    32768, 40960, 41472, 41536, 41537, 41528, 41532,     0, 
+    32768, 40960, 41472, 41536, 41537, 41539, 41532,     0, 
+    32768, 40960, 41472, 41536, 41537, 41539, 41532, 41534, 
+        0, 32768, 40960, 41472,     0, 32768, 40960, 41472, 
+    41536,     0, 32768, 40960, 41472, 41536,     0, 32768, 
+    40960, 41472, 41536, 41538,     0, 32768, 40960, 41472, 
+    41536,     0, 32768, 40960, 41472, 41536, 41540,     0, 
+    32768, 40960, 41472, 41536, 41540,     0, 32768, 40960, 
+    41472, 41536, 41544, 41542,     0, 32768, 40960, 41472, 
+    41536,     0, 32768, 40960, 41472, 41536, 41544,     0, 
+    32768, 40960, 41472, 41536, 41544,     0, 32768, 40960, 
+    41472, 41536, 41544, 41546,     0, 32768, 40960, 41472, 
+    41536, 41544,     0, 32768, 40960, 41472, 41536, 41552, 
+    41548,     0, 32768, 40960, 41472, 41536, 41552, 41548, 
+        0, 32768, 40960, 41472, 41536, 41552, 41553, 41550, 
+        0, 32768, 40960, 41472, 41536,     0, 32768, 40960, 
+    41472, 41536, 41552,     0, 32768, 40960, 41472, 41536, 
+    41552,     0, 32768, 40960, 41472, 41536, 41552, 41554, 
+        0, 32768, 40960, 41472, 41536, 41552,     0, 32768, 
+    40960, 41472, 41536, 41552, 41556,     0, 32768, 40960, 
+    41472, 41536, 41552, 41556,     0, 32768, 40960, 41472, 
+    41536, 41552, 41560, 41558,     0, 32768, 40960, 41472, 
+    41536, 41552,     0, 32768, 40960, 41472, 41536, 41568, 
+    41560,     0, 32768, 40960, 41472, 41536, 41568, 41560, 
+        0, 32768, 40960, 41472, 41536, 41568, 41560, 41562, 
+        0, 32768, 40960, 41472, 41536, 41568, 41560,     0, 
+    32768, 40960, 41472, 41536, 41568, 41569, 41564,     0, 
+    32768, 40960, 41472, 41536, 41568, 41569, 41564,     0, 
+    32768, 40960, 41472, 41536, 41568, 41569, 41564, 41566, 
+        0, 32768, 40960, 41472, 41536,     0, 32768, 40960, 
+    41472, 41600, 41568,     0, 32768, 40960, 41472, 41600, 
+    41568,     0, 32768, 40960, 41472, 41600, 41568, 41570, 
+        0, 32768, 40960, 41472, 41600, 41568,     0, 32768, 
+    40960, 41472, 41600, 41568, 41572,     0, 32768, 40960, 
+    41472, 41600, 41568, 41572,     0, 32768, 40960, 41472, 
+    41600, 41568, 41576, 41574,     0, 32768, 40960, 41472, 
+    41600, 41568,     0, 32768, 40960, 41472, 41600, 41568, 
+    41576,     0, 32768, 40960, 41472, 41600, 41568, 41576, 
+        0, 32768, 40960, 41472, 41600, 41568, 41576, 41578, 
+        0, 32768, 40960, 41472, 41600, 41568, 41576,     0, 
+    32768, 40960, 41472, 41600, 41568, 41584, 41580,     0, 
+    32768, 40960, 41472, 41600, 41568, 41584, 41580,     0, 
+    32768, 40960, 41472, 41600, 41568, 41584, 41585, 41582, 
+        0, 32768, 40960, 41472, 41600, 41568,     0, 32768, 
+    40960, 41472, 41600, 41601, 41584,     0, 32768, 40960, 
+    41472, 41600, 41601, 41584,     0, 32768, 40960, 41472, 
+    41600, 41601, 41584, 41586,     0, 32768, 40960, 41472, 
+    41600, 41601, 41584,     0, 32768, 40960, 41472, 41600, 
+    41601, 41584, 41588,     0, 32768, 40960, 41472, 41600, 
+    41601, 41584, 41588,     0, 32768, 40960, 41472, 41600, 
+    41601, 41584, 41592, 41590,     0, 32768, 40960, 41472, 
+    41600, 41601, 41584,     0, 32768, 40960, 41472, 41600, 
+    41601, 41584, 41592,     0, 32768, 40960, 41472, 41600, 
+    41601, 41603, 41592,     0, 32768, 40960, 41472, 41600, 
+    41601, 41603, 41592, 41594,     0, 32768, 40960, 41472, 
+    41600, 41601, 41603, 41592,     0, 32768, 40960, 41472, 
+    41600, 41601, 41603, 41592, 41596,     0, 32768, 40960, 
+    41472, 41600, 41601, 41603, 41592, 41596,     0, 32768, 
+    40960, 41472, 41600, 41601, 41603, 41592, 41596, 41598, 
+        0, 32768, 40960, 41472,     0, 32768, 40960, 41472, 
+    41600,     0, 32768, 40960, 41472, 41600,     0, 32768, 
+    40960, 41472, 41600, 41602,     0, 32768, 40960, 41472, 
+    41600,     0, 32768, 40960, 41472, 41600, 41604,     0, 
+    32768, 40960, 41472, 41600, 41604,     0, 32768, 40960, 
+    41472, 41600, 41608, 41606,     0, 32768, 40960, 41472, 
+    41600,     0, 32768, 40960, 41472, 41600, 41608,     0, 
+    32768, 40960, 41472, 41600, 41608,     0, 32768, 40960, 
+    41472, 41600, 41608, 41610,     0, 32768, 40960, 41472, 
+    41600, 41608,     0, 32768, 40960, 41472, 41600, 41616, 
+    41612,     0, 32768, 40960, 41472, 41600, 41616, 41612, 
+        0, 32768, 40960, 41472, 41600, 41616, 41617, 41614, 
+        0, 32768, 40960, 41472, 41600,     0, 32768, 40960, 
+    41472, 41600, 41616,     0, 32768, 40960, 41472, 41600, 
+    41616,     0, 32768, 40960, 41472, 41600, 41616, 41618, 
+        0, 32768, 40960, 41472, 41600, 41616,     0, 32768, 
+    40960, 41472, 41600, 41616, 41620,     0, 32768, 40960, 
+    41472, 41600, 41616, 41620,     0, 32768, 40960, 41472, 
+    41600, 41616, 41624, 41622,     0, 32768, 40960, 41472, 
+    41600, 41616,     0, 32768, 40960, 41472, 41600, 41632, 
+    41624,     0, 32768, 40960, 41472, 41600, 41632, 41624, 
+        0, 32768, 40960, 41472, 41600, 41632, 41624, 41626, 
+        0, 32768, 40960, 41472, 41600, 41632, 41624,     0, 
+    32768, 40960, 41472, 41600, 41632, 41633, 41628,     0, 
+    32768, 40960, 41472, 41600, 41632, 41633, 41628,     0, 
+    32768, 40960, 41472, 41600, 41632, 41633, 41628, 41630, 
+        0, 32768, 40960, 41472, 41600,     0, 32768, 40960, 
+    41472, 41600, 41632,     0, 32768, 40960, 41472, 41600, 
+    41632,     0, 32768, 40960, 41472, 41600, 41632, 41634, 
+        0, 32768, 40960, 41472, 41600, 41632,     0, 32768, 
+    40960, 41472, 41600, 41632, 41636,     0, 32768, 40960, 
+    41472, 41600, 41632, 41636,     0, 32768, 40960, 41472, 
+    41600, 41632, 41640, 41638,     0, 32768, 40960, 41472, 
+    41600, 41632,     0, 32768, 40960, 41472, 41600, 41632, 
+    41640,     0, 32768, 40960, 41472, 41600, 41632, 41640, 
+        0, 32768, 40960, 41472, 41600, 41632, 41640, 41642, 
+        0, 32768, 40960, 41472, 41600, 41632, 41640,     0, 
+    32768, 40960, 41472, 41600, 41632, 41648, 41644,     0, 
+    32768, 40960, 41472, 41600, 41632, 41648, 41644,     0, 
+    32768, 40960, 41472, 41600, 41632, 41648, 41649, 41646, 
+        0, 32768, 40960, 41472, 41600, 41632,     0, 32768, 
+    40960, 41472, 41600, 41664, 41648,     0, 32768, 40960, 
+    41472, 41600, 41664, 41648,     0, 32768, 40960, 41472, 
+    41600, 41664, 41648, 41650,     0, 32768, 40960, 41472, 
+    41600, 41664, 41648,     0, 32768, 40960, 41472, 41600, 
+    41664, 41648, 41652,     0, 32768, 40960, 41472, 41600, 
+    41664, 41648, 41652,     0, 32768, 40960, 41472, 41600, 
+    41664, 41648, 41656, 41654,     0, 32768, 40960, 41472, 
+    41600, 41664, 41648,     0, 32768, 40960, 41472, 41600, 
+    41664, 41665, 41656,     0, 32768, 40960, 41472, 41600, 
+    41664, 41665, 41656,     0, 32768, 40960, 41472, 41600, 
+    41664, 41665, 41656, 41658,     0, 32768, 40960, 41472, 
+    41600, 41664, 41665, 41656,     0, 32768, 40960, 41472, 
+    41600, 41664, 41665, 41656, 41660,     0, 32768, 40960, 
+    41472, 41600, 41664, 41665, 41667, 41660,     0, 32768, 
+    40960, 41472, 41600, 41664, 41665, 41667, 41660, 41662, 
+        0, 32768, 40960, 41472, 41600,     0, 32768, 40960, 
+    41472, 41728, 41664,     0, 32768, 40960, 41472, 41728, 
+    41664,     0, 32768, 40960, 41472, 41728, 41664, 41666, 
+        0, 32768, 40960, 41472, 41728, 41664,     0, 32768, 
+    40960, 41472, 41728, 41664, 41668,     0, 32768, 40960, 
+    41472, 41728, 41664, 41668,     0, 32768, 40960, 41472, 
+    41728, 41664, 41672, 41670,     0, 32768, 40960, 41472, 
+    41728, 41664,     0, 32768, 40960, 41472, 41728, 41664, 
+    41672,     0, 32768, 40960, 41472, 41728, 41664, 41672, 
+        0, 32768, 40960, 41472, 41728, 41664, 41672, 41674, 
+        0, 32768, 40960, 41472, 41728, 41664, 41672,     0, 
+    32768, 40960, 41472, 41728, 41664, 41680, 41676,     0, 
+    32768, 40960, 41472, 41728, 41664, 41680, 41676,     0, 
+    32768, 40960, 41472, 41728, 41664, 41680, 41681, 41678, 
+        0, 32768, 40960, 41472, 41728, 41664,     0, 32768, 
+    40960, 41472, 41728, 41664, 41680,     0, 32768, 40960, 
+    41472, 41728, 41664, 41680,     0, 32768, 40960, 41472, 
+    41728, 41664, 41680, 41682,     0, 32768, 40960, 41472, 
+    41728, 41664, 41680,     0, 32768, 40960, 41472, 41728, 
+    41664, 41680, 41684,     0, 32768, 40960, 41472, 41728, 
+    41664, 41680, 41684,     0, 32768, 40960, 41472, 41728, 
+    41664, 41680, 41688, 41686,     0, 32768, 40960, 41472, 
+    41728, 41664, 41680,     0, 32768, 40960, 41472, 41728, 
+    41664, 41696, 41688,     0, 32768, 40960, 41472, 41728, 
+    41664, 41696, 41688,     0, 32768, 40960, 41472, 41728, 
+    41664, 41696, 41688, 41690,     0, 32768, 40960, 41472, 
+    41728, 41664, 41696, 41688,     0, 32768, 40960, 41472, 
+    41728, 41664, 41696, 41697, 41692,     0, 32768, 40960, 
+    41472, 41728, 41664, 41696, 41697, 41692,     0, 32768, 
+    40960, 41472, 41728, 41664, 41696, 41697, 41692, 41694, 
+        0, 32768, 40960, 41472, 41728, 41664,     0, 32768, 
+    40960, 41472, 41728, 41729, 41696,     0, 32768, 40960, 
+    41472, 41728, 41729, 41696,     0, 32768, 40960, 41472, 
+    41728, 41729, 41696, 41698,     0, 32768, 40960, 41472, 
+    41728, 41729, 41696,     0, 32768, 40960, 41472, 41728, 
+    41729, 41696, 41700,     0, 32768, 40960, 41472, 41728, 
+    41729, 41696, 41700,     0, 32768, 40960, 41472, 41728, 
+    41729, 41696, 41704, 41702,     0, 32768, 40960, 41472, 
+    41728, 41729, 41696,     0, 32768, 40960, 41472, 41728, 
+    41729, 41696, 41704,     0, 32768, 40960, 41472, 41728, 
+    41729, 41696, 41704,     0, 32768, 40960, 41472, 41728, 
+    41729, 41696, 41704, 41706,     0, 32768, 40960, 41472, 
+    41728, 41729, 41696, 41704,     0, 32768, 40960, 41472, 
+    41728, 41729, 41696, 41712, 41708,     0, 32768, 40960, 
+    41472, 41728, 41729, 41696, 41712, 41708,     0, 32768, 
+    40960, 41472, 41728, 41729, 41696, 41712, 41713, 41710, 
+        0, 32768, 40960, 41472, 41728, 41729, 41696,     0, 
+    32768, 40960, 41472, 41728, 41729, 41696, 41712,     0, 
+    32768, 40960, 41472, 41728, 41729, 41731, 41712,     0, 
+    32768, 40960, 41472, 41728, 41729, 41731, 41712, 41714, 
+        0, 32768, 40960, 41472, 41728, 41729, 41731, 41712, 
+        0, 32768, 40960, 41472, 41728, 41729, 41731, 41712, 
+    41716,     0, 32768, 40960, 41472, 41728, 41729, 41731, 
+    41712, 41716,     0, 32768, 40960, 41472, 41728, 41729, 
+    41731, 41712, 41720, 41718,     0, 32768, 40960, 41472, 
+    41728, 41729, 41731, 41712,     0, 32768, 40960, 41472, 
+    41728, 41729, 41731, 41712, 41720,     0, 32768, 40960, 
+    41472, 41728, 41729, 41731, 41712, 41720,     0, 32768, 
+    40960, 41472, 41728, 41729, 41731, 41712, 41720, 41722, 
+        0, 32768, 40960, 41472, 41728, 41729, 41731, 41735, 
+    41720,     0, 32768, 40960, 41472, 41728, 41729, 41731, 
+    41735, 41720, 41724,     0, 32768, 40960, 41472, 41728, 
+    41729, 41731, 41735, 41720, 41724,     0, 32768, 40960, 
+    41472, 41728, 41729, 41731, 41735, 41720, 41724, 41726, 
+        0, 32768, 40960, 41472,     0, 32768, 40960, 41984, 
+    41728,     0, 32768, 40960, 41984, 41728,     0, 32768, 
+    40960, 41984, 41728, 41730,     0, 32768, 40960, 41984, 
+    41728,     0, 32768, 40960, 41984, 41728, 41732,     0, 
+    32768, 40960, 41984, 41728, 41732,     0, 32768, 40960, 
+    41984, 41728, 41736, 41734,     0, 32768, 40960, 41984, 
+    41728,     0, 32768, 40960, 41984, 41728, 41736,     0, 
+    32768, 40960, 41984, 41728, 41736,     0, 32768, 40960, 
+    41984, 41728, 41736, 41738,     0, 32768, 40960, 41984, 
+    41728, 41736,     0, 32768, 40960, 41984, 41728, 41744, 
+    41740,     0, 32768, 40960, 41984, 41728, 41744, 41740, 
+        0, 32768, 40960, 41984, 41728, 41744, 41745, 41742, 
+        0, 32768, 40960, 41984, 41728,     0, 32768, 40960, 
+    41984, 41728, 41744,     0, 32768, 40960, 41984, 41728, 
+    41744,     0, 32768, 40960, 41984, 41728, 41744, 41746, 
+        0, 32768, 40960, 41984, 41728, 41744,     0, 32768, 
+    40960, 41984, 41728, 41744, 41748,     0, 32768, 40960, 
+    41984, 41728, 41744, 41748,     0, 32768, 40960, 41984, 
+    41728, 41744, 41752, 41750,     0, 32768, 40960, 41984, 
+    41728, 41744,     0, 32768, 40960, 41984, 41728, 41760, 
+    41752,     0, 32768, 40960, 41984, 41728, 41760, 41752, 
+        0, 32768, 40960, 41984, 41728, 41760, 41752, 41754, 
+        0, 32768, 40960, 41984, 41728, 41760, 41752,     0, 
+    32768, 40960, 41984, 41728, 41760, 41761, 41756,     0, 
+    32768, 40960, 41984, 41728, 41760, 41761, 41756,     0, 
+    32768, 40960, 41984, 41728, 41760, 41761, 41756, 41758, 
+        0, 32768, 40960, 41984, 41728,     0, 32768, 40960, 
+    41984, 41728, 41760,     0, 32768, 40960, 41984, 41728, 
+    41760,     0, 32768, 40960, 41984, 41728, 41760, 41762, 
+        0, 32768, 40960, 41984, 41728, 41760,     0, 32768, 
+    40960, 41984, 41728, 41760, 41764,     0, 32768, 40960, 
+    41984, 41728, 41760, 41764,     0, 32768, 40960, 41984, 
+    41728, 41760, 41768, 41766,     0, 32768, 40960, 41984, 
+    41728, 41760,     0, 32768, 40960, 41984, 41728, 41760, 
+    41768,     0, 32768, 40960, 41984, 41728, 41760, 41768, 
+        0, 32768, 40960, 41984, 41728, 41760, 41768, 41770, 
+        0, 32768, 40960, 41984, 41728, 41760, 41768,     0, 
+    32768, 40960, 41984, 41728, 41760, 41776, 41772,     0, 
+    32768, 40960, 41984, 41728, 41760, 41776, 41772,     0, 
+    32768, 40960, 41984, 41728, 41760, 41776, 41777, 41774, 
+        0, 32768, 40960, 41984, 41728, 41760,     0, 32768, 
+    40960, 41984, 41728, 41792, 41776,     0, 32768, 40960, 
+    41984, 41728, 41792, 41776,     0, 32768, 40960, 41984, 
+    41728, 41792, 41776, 41778,     0, 32768, 40960, 41984, 
+    41728, 41792, 41776,     0, 32768, 40960, 41984, 41728, 
+    41792, 41776, 41780,     0, 32768, 40960, 41984, 41728, 
+    41792, 41776, 41780,     0, 32768, 40960, 41984, 41728, 
+    41792, 41776, 41784, 41782,     0, 32768, 40960, 41984, 
+    41728, 41792, 41776,     0, 32768, 40960, 41984, 41728, 
+    41792, 41793, 41784,     0, 32768, 40960, 41984, 41728, 
+    41792, 41793, 41784,     0, 32768, 40960, 41984, 41728, 
+    41792, 41793, 41784, 41786,     0, 32768, 40960, 41984, 
+    41728, 41792, 41793, 41784,     0, 32768, 40960, 41984, 
+    41728, 41792, 41793, 41784, 41788,     0, 32768, 40960, 
+    41984, 41728, 41792, 41793, 41795, 41788,     0, 32768, 
+    40960, 41984, 41728, 41792, 41793, 41795, 41788, 41790, 
+        0, 32768, 40960, 41984, 41728,     0, 32768, 40960, 
+    41984, 41728, 41792,     0, 32768, 40960, 41984, 41728, 
+    41792,     0, 32768, 40960, 41984, 41728, 41792, 41794, 
+        0, 32768, 40960, 41984, 41728, 41792,     0, 32768, 
+    40960, 41984, 41728, 41792, 41796,     0, 32768, 40960, 
+    41984, 41728, 41792, 41796,     0, 32768, 40960, 41984, 
+    41728, 41792, 41800, 41798,     0, 32768, 40960, 41984, 
+    41728, 41792,     0, 32768, 40960, 41984, 41728, 41792, 
+    41800,     0, 32768, 40960, 41984, 41728, 41792, 41800, 
+        0, 32768, 40960, 41984, 41728, 41792, 41800, 41802, 
+        0, 32768, 40960, 41984, 41728, 41792, 41800,     0, 
+    32768, 40960, 41984, 41728, 41792, 41808, 41804,     0, 
+    32768, 40960, 41984, 41728, 41792, 41808, 41804,     0, 
+    32768, 40960, 41984, 41728, 41792, 41808, 41809, 41806, 
+        0, 32768, 40960, 41984, 41728, 41792,     0, 32768, 
+    40960, 41984, 41728, 41792, 41808,     0, 32768, 40960, 
+    41984, 41728, 41792, 41808,     0, 32768, 40960, 41984, 
+    41728, 41792, 41808, 41810,     0, 32768, 40960, 41984, 
+    41728, 41792, 41808,     0, 32768, 40960, 41984, 41728, 
+    41792, 41808, 41812,     0, 32768, 40960, 41984, 41728, 
+    41792, 41808, 41812,     0, 32768, 40960, 41984, 41728, 
+    41792, 41808, 41816, 41814,     0, 32768, 40960, 41984, 
+    41728, 41792, 41808,     0, 32768, 40960, 41984, 41728, 
+    41792, 41824, 41816,     0, 32768, 40960, 41984, 41728, 
+    41792, 41824, 41816,     0, 32768, 40960, 41984, 41728, 
+    41792, 41824, 41816, 41818,     0, 32768, 40960, 41984, 
+    41728, 41792, 41824, 41816,     0, 32768, 40960, 41984, 
+    41728, 41792, 41824, 41825, 41820,     0, 32768, 40960, 
+    41984, 41728, 41792, 41824, 41825, 41820,     0, 32768, 
+    40960, 41984, 41728, 41792, 41824, 41825, 41820, 41822, 
+        0, 32768, 40960, 41984, 41728, 41792,     0, 32768, 
+    40960, 41984, 41728, 41856, 41824,     0, 32768, 40960, 
+    41984, 41728, 41856, 41824,     0, 32768, 40960, 41984, 
+    41728, 41856, 41824, 41826,     0, 32768, 40960, 41984, 
+    41728, 41856, 41824,     0, 32768, 40960, 41984, 41728, 
+    41856, 41824, 41828,     0, 32768, 40960, 41984, 41728, 
+    41856, 41824, 41828,     0, 32768, 40960, 41984, 41728, 
+    41856, 41824, 41832, 41830,     0, 32768, 40960, 41984, 
+    41728, 41856, 41824,     0, 32768, 40960, 41984, 41728, 
+    41856, 41824, 41832,     0, 32768, 40960, 41984, 41728, 
+    41856, 41824, 41832,     0, 32768, 40960, 41984, 41728, 
+    41856, 41824, 41832, 41834,     0, 32768, 40960, 41984, 
+    41728, 41856, 41824, 41832,     0, 32768, 40960, 41984, 
+    41728, 41856, 41824, 41840, 41836,     0, 32768, 40960, 
+    41984, 41728, 41856, 41824, 41840, 41836,     0, 32768, 
+    40960, 41984, 41728, 41856, 41824, 41840, 41841, 41838, 
+        0, 32768, 40960, 41984, 41728, 41856, 41824,     0, 
+    32768, 40960, 41984, 41728, 41856, 41857, 41840,     0, 
+    32768, 40960, 41984, 41728, 41856, 41857, 41840,     0, 
+    32768, 40960, 41984, 41728, 41856, 41857, 41840, 41842, 
+        0, 32768, 40960, 41984, 41728, 41856, 41857, 41840, 
+        0, 32768, 40960, 41984, 41728, 41856, 41857, 41840, 
+    41844,     0, 32768, 40960, 41984, 41728, 41856, 41857, 
+    41840, 41844,     0, 32768, 40960, 41984, 41728, 41856, 
+    41857, 41840, 41848, 41846,     0, 32768, 40960, 41984, 
+    41728, 41856, 41857, 41840,     0, 32768, 40960, 41984, 
+    41728, 41856, 41857, 41840, 41848,     0, 32768, 40960, 
+    41984, 41728, 41856, 41857, 41859, 41848,     0, 32768, 
+    40960, 41984, 41728, 41856, 41857, 41859, 41848, 41850, 
+        0, 32768, 40960, 41984, 41728, 41856, 41857, 41859, 
+    41848,     0, 32768, 40960, 41984, 41728, 41856, 41857, 
+    41859, 41848, 41852,     0, 32768, 40960, 41984, 41728, 
+    41856, 41857, 41859, 41848, 41852,     0, 32768, 40960, 
+    41984, 41728, 41856, 41857, 41859, 41848, 41852, 41854, 
+        0, 32768, 40960, 41984, 41728,     0, 32768, 40960, 
+    41984, 41728, 41856,     0, 32768, 40960, 41984, 41985, 
+    41856,     0, 32768, 40960, 41984, 41985, 41856, 41858, 
+        0, 32768, 40960, 41984, 41985, 41856,     0, 32768, 
+    40960, 41984, 41985, 41856, 41860,     0, 32768, 40960, 
+    41984, 41985, 41856, 41860,     0, 32768, 40960, 41984, 
+    41985, 41856, 41864, 41862,     0, 32768, 40960, 41984, 
+    41985, 41856,     0, 32768, 40960, 41984, 41985, 41856, 
+    41864,     0, 32768, 40960, 41984, 41985, 41856, 41864, 
+        0, 32768, 40960, 41984, 41985, 41856, 41864, 41866, 
+        0, 32768, 40960, 41984, 41985, 41856, 41864,     0, 
+    32768, 40960, 41984, 41985, 41856, 41872, 41868,     0, 
+    32768, 40960, 41984, 41985, 41856, 41872, 41868,     0, 
+    32768, 40960, 41984, 41985, 41856, 41872, 41873, 41870, 
+        0, 32768, 40960, 41984, 41985, 41856,     0, 32768, 
+    40960, 41984, 41985, 41856, 41872,     0, 32768, 40960, 
+    41984, 41985, 41856, 41872,     0, 32768, 40960, 41984, 
+    41985, 41856, 41872, 41874,     0, 32768, 40960, 41984, 
+    41985, 41856, 41872,     0, 32768, 40960, 41984, 41985, 
+    41856, 41872, 41876,     0, 32768, 40960, 41984, 41985, 
+    41856, 41872, 41876,     0, 32768, 40960, 41984, 41985, 
+    41856, 41872, 41880, 41878,     0, 32768, 40960, 41984, 
+    41985, 41856, 41872,     0, 32768, 40960, 41984, 41985, 
+    41856, 41888, 41880,     0, 32768, 40960, 41984, 41985, 
+    41856, 41888, 41880,     0, 32768, 40960, 41984, 41985, 
+    41856, 41888, 41880, 41882,     0, 32768, 40960, 41984, 
+    41985, 41856, 41888, 41880,     0, 32768, 40960, 41984, 
+    41985, 41856, 41888, 41889, 41884,     0, 32768, 40960, 
+    41984, 41985, 41856, 41888, 41889, 41884,     0, 32768, 
+    40960, 41984, 41985, 41856, 41888, 41889, 41884, 41886, 
+        0, 32768, 40960, 41984, 41985, 41856,     0, 32768, 
+    40960, 41984, 41985, 41856, 41888,     0, 32768, 40960, 
+    41984, 41985, 41856, 41888,     0, 32768, 40960, 41984, 
+    41985, 41856, 41888, 41890,     0, 32768, 40960, 41984, 
+    41985, 41856, 41888,     0, 32768, 40960, 41984, 41985, 
+    41856, 41888, 41892,     0, 32768, 40960, 41984, 41985, 
+    41856, 41888, 41892,     0, 32768, 40960, 41984, 41985, 
+    41856, 41888, 41896, 41894,     0, 32768, 40960, 41984, 
+    41985, 41856, 41888,     0, 32768, 40960, 41984, 41985, 
+    41856, 41888, 41896,     0, 32768, 40960, 41984, 41985, 
+    41856, 41888, 41896,     0, 32768, 40960, 41984, 41985, 
+    41856, 41888, 41896, 41898,     0, 32768, 40960, 41984, 
+    41985, 41856, 41888, 41896,     0, 32768, 40960, 41984, 
+    41985, 41856, 41888, 41904, 41900,     0, 32768, 40960, 
+    41984, 41985, 41856, 41888, 41904, 41900,     0, 32768, 
+    40960, 41984, 41985, 41856, 41888, 41904, 41905, 41902, 
+        0, 32768, 40960, 41984, 41985, 41856, 41888,     0, 
+    32768, 40960, 41984, 41985, 41856, 41920, 41904,     0, 
+    32768, 40960, 41984, 41985, 41856, 41920, 41904,     0, 
+    32768, 40960, 41984, 41985, 41856, 41920, 41904, 41906, 
+        0, 32768, 40960, 41984, 41985, 41856, 41920, 41904, 
+        0, 32768, 40960, 41984, 41985, 41856, 41920, 41904, 
+    41908,     0, 32768, 40960, 41984, 41985, 41856, 41920, 
+    41904, 41908,     0, 32768, 40960, 41984, 41985, 41856, 
+    41920, 41904, 41912, 41910,     0, 32768, 40960, 41984, 
+    41985, 41856, 41920, 41904,     0, 32768, 40960, 41984, 
+    41985, 41856, 41920, 41921, 41912,     0, 32768, 40960, 
+    41984, 41985, 41856, 41920, 41921, 41912,     0, 32768, 
+    40960, 41984, 41985, 41856, 41920, 41921, 41912, 41914, 
+        0, 32768, 40960, 41984, 41985, 41856, 41920, 41921, 
+    41912,     0, 32768, 40960, 41984, 41985, 41856, 41920, 
+    41921, 41912, 41916,     0, 32768, 40960, 41984, 41985, 
+    41856, 41920, 41921, 41923, 41916,     0, 32768, 40960, 
+    41984, 41985, 41856, 41920, 41921, 41923, 41916, 41918, 
+        0, 32768, 40960, 41984, 41985, 41856,     0, 32768, 
+    40960, 41984, 41985, 41856, 41920,     0, 32768, 40960, 
+    41984, 41985, 41856, 41920,     0, 32768, 40960, 41984, 
+    41985, 41856, 41920, 41922,     0, 32768, 40960, 41984, 
+    41985, 41987, 41920,     0, 32768, 40960, 41984, 41985, 
+    41987, 41920, 41924,     0, 32768, 40960, 41984, 41985, 
+    41987, 41920, 41924,     0, 32768, 40960, 41984, 41985, 
+    41987, 41920, 41928, 41926,     0, 32768, 40960, 41984, 
+    41985, 41987, 41920,     0, 32768, 40960, 41984, 41985, 
+    41987, 41920, 41928,     0, 32768, 40960, 41984, 41985, 
+    41987, 41920, 41928,     0, 32768, 40960, 41984, 41985, 
+    41987, 41920, 41928, 41930,     0, 32768, 40960, 41984, 
+    41985, 41987, 41920, 41928,     0, 32768, 40960, 41984, 
+    41985, 41987, 41920, 41936, 41932,     0, 32768, 40960, 
+    41984, 41985, 41987, 41920, 41936, 41932,     0, 32768, 
+    40960, 41984, 41985, 41987, 41920, 41936, 41937, 41934, 
+        0, 32768, 40960, 41984, 41985, 41987, 41920,     0, 
+    32768, 40960, 41984, 41985, 41987, 41920, 41936,     0, 
+    32768, 40960, 41984, 41985, 41987, 41920, 41936,     0, 
+    32768, 40960, 41984, 41985, 41987, 41920, 41936, 41938, 
+        0, 32768, 40960, 41984, 41985, 41987, 41920, 41936, 
+        0, 32768, 40960, 41984, 41985, 41987, 41920, 41936, 
+    41940,     0, 32768, 40960, 41984, 41985, 41987, 41920, 
+    41936, 41940,     0, 32768, 40960, 41984, 41985, 41987, 
+    41920, 41936, 41944, 41942,     0, 32768, 40960, 41984, 
+    41985, 41987, 41920, 41936,     0, 32768, 40960, 41984, 
+    41985, 41987, 41920, 41952, 41944,     0, 32768, 40960, 
+    41984, 41985, 41987, 41920, 41952, 41944,     0, 32768, 
+    40960, 41984, 41985, 41987, 41920, 41952, 41944, 41946, 
+        0, 32768, 40960, 41984, 41985, 41987, 41920, 41952, 
+    41944,     0, 32768, 40960, 41984, 41985, 41987, 41920, 
+    41952, 41953, 41948,     0, 32768, 40960, 41984, 41985, 
+    41987, 41920, 41952, 41953, 41948,     0, 32768, 40960, 
+    41984, 41985, 41987, 41920, 41952, 41953, 41948, 41950, 
+        0, 32768, 40960, 41984, 41985, 41987, 41920,     0, 
+    32768, 40960, 41984, 41985, 41987, 41920, 41952,     0, 
+    32768, 40960, 41984, 41985, 41987, 41920, 41952,     0, 
+    32768, 40960, 41984, 41985, 41987, 41920, 41952, 41954, 
+        0, 32768, 40960, 41984, 41985, 41987, 41920, 41952, 
+        0, 32768, 40960, 41984, 41985, 41987, 41920, 41952, 
+    41956,     0, 32768, 40960, 41984, 41985, 41987, 41920, 
+    41952, 41956,     0, 32768, 40960, 41984, 41985, 41987, 
+    41920, 41952, 41960, 41958,     0, 32768, 40960, 41984, 
+    41985, 41987, 41991, 41952,     0, 32768, 40960, 41984, 
+    41985, 41987, 41991, 41952, 41960,     0, 32768, 40960, 
+    41984, 41985, 41987, 41991, 41952, 41960,     0, 32768, 
+    40960, 41984, 41985, 41987, 41991, 41952, 41960, 41962, 
+        0, 32768, 40960, 41984, 41985, 41987, 41991, 41952, 
+    41960,     0, 32768, 40960, 41984, 41985, 41987, 41991, 
+    41952, 41968, 41964,     0, 32768, 40960, 41984, 41985, 
+    41987, 41991, 41952, 41968, 41964,     0, 32768, 40960, 
+    41984, 41985, 41987, 41991, 41952, 41968, 41969, 41966, 
+        0, 32768, 40960, 41984, 41985, 41987, 41991, 41952, 
+        0, 32768, 40960, 41984, 41985, 41987, 41991, 41952, 
+    41968,     0, 32768, 40960, 41984, 41985, 41987, 41991, 
+    41952, 41968,     0, 32768, 40960, 41984, 41985, 41987, 
+    41991, 41952, 41968, 41970,     0, 32768, 40960, 41984, 
+    41985, 41987, 41991, 41952, 41968,     0, 32768, 40960, 
+    41984, 41985, 41987, 41991, 41952, 41968, 41972,     0, 
+    32768, 40960, 41984, 41985, 41987, 41991, 41952, 41968, 
+    41972,     0, 32768, 40960, 41984, 41985, 41987, 41991, 
+    41952, 41968, 41976, 41974,     0, 32768, 40960, 41984, 
+    41985, 41987, 41991, 41952, 41968,     0, 32768, 40960, 
+    41984, 41985, 41987, 41991, 41952, 41968, 41976,     0, 
+    32768, 40960, 41984, 41985, 41987, 41991, 41952, 41968, 
+    41976,     0, 32768, 40960, 41984, 41985, 41987, 41991, 
+    41952, 41968, 41976, 41978,     0, 32768, 40960, 41984, 
+    41985, 41987, 41991, 41952, 41968, 41976,     0, 32768, 
+    40960, 41984, 41985, 41987, 41991, 41952, 41968, 41976, 
+    41980,     0, 32768, 40960, 41984, 41985, 41987, 41991, 
+    41952, 41968, 41976, 41980,     0, 32768, 40960, 41984, 
+    41985, 41987, 41991, 41952, 41968, 41976, 41980, 41982, 
+        0, 32768, 40960,     0, 32768, 40960, 41984,     0, 
+    32768, 40960, 41984,     0, 32768, 40960, 41984, 41986, 
+        0, 32768, 40960, 41984,     0, 32768, 40960, 41984, 
+    41988,     0, 32768, 40960, 41984, 41988,     0, 32768, 
+    40960, 41984, 41992, 41990,     0, 32768, 40960, 41984, 
+        0, 32768, 40960, 41984, 41992,     0, 32768, 40960, 
+    41984, 41992,     0, 32768, 40960, 41984, 41992, 41994, 
+        0, 32768, 40960, 41984, 41992,     0, 32768, 40960, 
+    41984, 42000, 41996,     0, 32768, 40960, 41984, 42000, 
+    41996,     0, 32768, 40960, 41984, 42000, 42001, 41998, 
+        0, 32768, 40960, 41984,     0, 32768, 40960, 41984, 
+    42000,     0, 32768, 40960, 41984, 42000,     0, 32768, 
+    40960, 41984, 42000, 42002,     0, 32768, 40960, 41984, 
+    42000,     0, 32768, 40960, 41984, 42000, 42004,     0, 
+    32768, 40960, 41984, 42000, 42004,     0, 32768, 40960, 
+    41984, 42000, 42008, 42006,     0, 32768, 40960, 41984, 
+    42000,     0, 32768, 40960, 41984, 42016, 42008,     0, 
+    32768, 40960, 41984, 42016, 42008,     0, 32768, 40960, 
+    41984, 42016, 42008, 42010,     0, 32768, 40960, 41984, 
+    42016, 42008,     0, 32768, 40960, 41984, 42016, 42017, 
+    42012,     0, 32768, 40960, 41984, 42016, 42017, 42012, 
+        0, 32768, 40960, 41984, 42016, 42017, 42012, 42014, 
+        0, 32768, 40960, 41984,     0, 32768, 40960, 41984, 
+    42016,     0, 32768, 40960, 41984, 42016,     0, 32768, 
+    40960, 41984, 42016, 42018,     0, 32768, 40960, 41984, 
+    42016,     0, 32768, 40960, 41984, 42016, 42020,     0, 
+    32768, 40960, 41984, 42016, 42020,     0, 32768, 40960, 
+    41984, 42016, 42024, 42022,     0, 32768, 40960, 41984, 
+    42016,     0, 32768, 40960, 41984, 42016, 42024,     0, 
+    32768, 40960, 41984, 42016, 42024,     0, 32768, 40960, 
+    41984, 42016, 42024, 42026,     0, 32768, 40960, 41984, 
+    42016, 42024,     0, 32768, 40960, 41984, 42016, 42032, 
+    42028,     0, 32768, 40960, 41984, 42016, 42032, 42028, 
+        0, 32768, 40960, 41984, 42016, 42032, 42033, 42030, 
+        0, 32768, 40960, 41984, 42016,     0, 32768, 40960, 
+    41984, 42048, 42032,     0, 32768, 40960, 41984, 42048, 
+    42032,     0, 32768, 40960, 41984, 42048, 42032, 42034, 
+        0, 32768, 40960, 41984, 42048, 42032,     0, 32768, 
+    40960, 41984, 42048, 42032, 42036,     0, 32768, 40960, 
+    41984, 42048, 42032, 42036,     0, 32768, 40960, 41984, 
+    42048, 42032, 42040, 42038,     0, 32768, 40960, 41984, 
+    42048, 42032,     0, 32768, 40960, 41984, 42048, 42049, 
+    42040,     0, 32768, 40960, 41984, 42048, 42049, 42040, 
+        0, 32768, 40960, 41984, 42048, 42049, 42040, 42042, 
+        0, 32768, 40960, 41984, 42048, 42049, 42040,     0, 
+    32768, 40960, 41984, 42048, 42049, 42040, 42044,     0, 
+    32768, 40960, 41984, 42048, 42049, 42051, 42044,     0, 
+    32768, 40960, 41984, 42048, 42049, 42051, 42044, 42046, 
+        0, 32768, 40960, 41984,     0, 32768, 40960, 41984, 
+    42048,     0, 32768, 40960, 41984, 42048,     0, 32768, 
+    40960, 41984, 42048, 42050,     0, 32768, 40960, 41984, 
+    42048,     0, 32768, 40960, 41984, 42048, 42052,     0, 
+    32768, 40960, 41984, 42048, 42052,     0, 32768, 40960, 
+    41984, 42048, 42056, 42054,     0, 32768, 40960, 41984, 
+    42048,     0, 32768, 40960, 41984, 42048, 42056,     0, 
+    32768, 40960, 41984, 42048, 42056,     0, 32768, 40960, 
+    41984, 42048, 42056, 42058,     0, 32768, 40960, 41984, 
+    42048, 42056,     0, 32768, 40960, 41984, 42048, 42064, 
+    42060,     0, 32768, 40960, 41984, 42048, 42064, 42060, 
+        0, 32768, 40960, 41984, 42048, 42064, 42065, 42062, 
+        0, 32768, 40960, 41984, 42048,     0, 32768, 40960, 
+    41984, 42048, 42064,     0, 32768, 40960, 41984, 42048, 
+    42064,     0, 32768, 40960, 41984, 42048, 42064, 42066, 
+        0, 32768, 40960, 41984, 42048, 42064,     0, 32768, 
+    40960, 41984, 42048, 42064, 42068,     0, 32768, 40960, 
+    41984, 42048, 42064, 42068,     0, 32768, 40960, 41984, 
+    42048, 42064, 42072, 42070,     0, 32768, 40960, 41984, 
+    42048, 42064,     0, 32768, 40960, 41984, 42048, 42080, 
+    42072,     0, 32768, 40960, 41984, 42048, 42080, 42072, 
+        0, 32768, 40960, 41984, 42048, 42080, 42072, 42074, 
+        0, 32768, 40960, 41984, 42048, 42080, 42072,     0, 
+    32768, 40960, 41984, 42048, 42080, 42081, 42076,     0, 
+    32768, 40960, 41984, 42048, 42080, 42081, 42076,     0, 
+    32768, 40960, 41984, 42048, 42080, 42081, 42076, 42078, 
+        0, 32768, 40960, 41984, 42048,     0, 32768, 40960, 
+    41984, 42112, 42080,     0, 32768, 40960, 41984, 42112, 
+    42080,     0, 32768, 40960, 41984, 42112, 42080, 42082, 
+        0, 32768, 40960, 41984, 42112, 42080,     0, 32768, 
+    40960, 41984, 42112, 42080, 42084,     0, 32768, 40960, 
+    41984, 42112, 42080, 42084,     0, 32768, 40960, 41984, 
+    42112, 42080, 42088, 42086,     0, 32768, 40960, 41984, 
+    42112, 42080,     0, 32768, 40960, 41984, 42112, 42080, 
+    42088,     0, 32768, 40960, 41984, 42112, 42080, 42088, 
+        0, 32768, 40960, 41984, 42112, 42080, 42088, 42090, 
+        0, 32768, 40960, 41984, 42112, 42080, 42088,     0, 
+    32768, 40960, 41984, 42112, 42080, 42096, 42092,     0, 
+    32768, 40960, 41984, 42112, 42080, 42096, 42092,     0, 
+    32768, 40960, 41984, 42112, 42080, 42096, 42097, 42094, 
+        0, 32768, 40960, 41984, 42112, 42080,     0, 32768, 
+    40960, 41984, 42112, 42113, 42096,     0, 32768, 40960, 
+    41984, 42112, 42113, 42096,     0, 32768, 40960, 41984, 
+    42112, 42113, 42096, 42098,     0, 32768, 40960, 41984, 
+    42112, 42113, 42096,     0, 32768, 40960, 41984, 42112, 
+    42113, 42096, 42100,     0, 32768, 40960, 41984, 42112, 
+    42113, 42096, 42100,     0, 32768, 40960, 41984, 42112, 
+    42113, 42096, 42104, 42102,     0, 32768, 40960, 41984, 
+    42112, 42113, 42096,     0, 32768, 40960, 41984, 42112, 
+    42113, 42096, 42104,     0, 32768, 40960, 41984, 42112, 
+    42113, 42115, 42104,     0, 32768, 40960, 41984, 42112, 
+    42113, 42115, 42104, 42106,     0, 32768, 40960, 41984, 
+    42112, 42113, 42115, 42104,     0, 32768, 40960, 41984, 
+    42112, 42113, 42115, 42104, 42108,     0, 32768, 40960, 
+    41984, 42112, 42113, 42115, 42104, 42108,     0, 32768, 
+    40960, 41984, 42112, 42113, 42115, 42104, 42108, 42110, 
+        0, 32768, 40960, 41984,     0, 32768, 40960, 41984, 
+    42112,     0, 32768, 40960, 41984, 42112,     0, 32768, 
+    40960, 41984, 42112, 42114,     0, 32768, 40960, 41984, 
+    42112,     0, 32768, 40960, 41984, 42112, 42116,     0, 
+    32768, 40960, 41984, 42112, 42116,     0, 32768, 40960, 
+    41984, 42112, 42120, 42118,     0, 32768, 40960, 41984, 
+    42112,     0, 32768, 40960, 41984, 42112, 42120,     0, 
+    32768, 40960, 41984, 42112, 42120,     0, 32768, 40960, 
+    41984, 42112, 42120, 42122,     0, 32768, 40960, 41984, 
+    42112, 42120,     0, 32768, 40960, 41984, 42112, 42128, 
+    42124,     0, 32768, 40960, 41984, 42112, 42128, 42124, 
+        0, 32768, 40960, 41984, 42112, 42128, 42129, 42126, 
+        0, 32768, 40960, 41984, 42112,     0, 32768, 40960, 
+    41984, 42112, 42128,     0, 32768, 40960, 41984, 42112, 
+    42128,     0, 32768, 40960, 41984, 42112, 42128, 42130, 
+        0, 32768, 40960, 41984, 42112, 42128,     0, 32768, 
+    40960, 41984, 42112, 42128, 42132,     0, 32768, 40960, 
+    41984, 42112, 42128, 42132,     0, 32768, 40960, 41984, 
+    42112, 42128, 42136, 42134,     0, 32768, 40960, 41984, 
+    42112, 42128,     0, 32768, 40960, 41984, 42112, 42144, 
+    42136,     0, 32768, 40960, 41984, 42112, 42144, 42136, 
+        0, 32768, 40960, 41984, 42112, 42144, 42136, 42138, 
+        0, 32768, 40960, 41984, 42112, 42144, 42136,     0, 
+    32768, 40960, 41984, 42112, 42144, 42145, 42140,     0, 
+    32768, 40960, 41984, 42112, 42144, 42145, 42140,     0, 
+    32768, 40960, 41984, 42112, 42144, 42145, 42140, 42142, 
+        0, 32768, 40960, 41984, 42112,     0, 32768, 40960, 
+    41984, 42112, 42144,     0, 32768, 40960, 41984, 42112, 
+    42144,     0, 32768, 40960, 41984, 42112, 42144, 42146, 
+        0, 32768, 40960, 41984, 42112, 42144,     0, 32768, 
+    40960, 41984, 42112, 42144, 42148,     0, 32768, 40960, 
+    41984, 42112, 42144, 42148,     0, 32768, 40960, 41984, 
+    42112, 42144, 42152, 42150,     0, 32768, 40960, 41984, 
+    42112, 42144,     0, 32768, 40960, 41984, 42112, 42144, 
+    42152,     0, 32768, 40960, 41984, 42112, 42144, 42152, 
+        0, 32768, 40960, 41984, 42112, 42144, 42152, 42154, 
+        0, 32768, 40960, 41984, 42112, 42144, 42152,     0, 
+    32768, 40960, 41984, 42112, 42144, 42160, 42156,     0, 
+    32768, 40960, 41984, 42112, 42144, 42160, 42156,     0, 
+    32768, 40960, 41984, 42112, 42144, 42160, 42161, 42158, 
+        0, 32768, 40960, 41984, 42112, 42144,     0, 32768, 
+    40960, 41984, 42112, 42176, 42160,     0, 32768, 40960, 
+    41984, 42112, 42176, 42160,     0, 32768, 40960, 41984, 
+    42112, 42176, 42160, 42162,     0, 32768, 40960, 41984, 
+    42112, 42176, 42160,     0, 32768, 40960, 41984, 42112, 
+    42176, 42160, 42164,     0, 32768, 40960, 41984, 42112, 
+    42176, 42160, 42164,     0, 32768, 40960, 41984, 42112, 
+    42176, 42160, 42168, 42166,     0, 32768, 40960, 41984, 
+    42112, 42176, 42160,     0, 32768, 40960, 41984, 42112, 
+    42176, 42177, 42168,     0, 32768, 40960, 41984, 42112, 
+    42176, 42177, 42168,     0, 32768, 40960, 41984, 42112, 
+    42176, 42177, 42168, 42170,     0, 32768, 40960, 41984, 
+    42112, 42176, 42177, 42168,     0, 32768, 40960, 41984, 
+    42112, 42176, 42177, 42168, 42172,     0, 32768, 40960, 
+    41984, 42112, 42176, 42177, 42179, 42172,     0, 32768, 
+    40960, 41984, 42112, 42176, 42177, 42179, 42172, 42174, 
+        0, 32768, 40960, 41984, 42112,     0, 32768, 40960, 
+    41984, 42240, 42176,     0, 32768, 40960, 41984, 42240, 
+    42176,     0, 32768, 40960, 41984, 42240, 42176, 42178, 
+        0, 32768, 40960, 41984, 42240, 42176,     0, 32768, 
+    40960, 41984, 42240, 42176, 42180,     0, 32768, 40960, 
+    41984, 42240, 42176, 42180,     0, 32768, 40960, 41984, 
+    42240, 42176, 42184, 42182,     0, 32768, 40960, 41984, 
+    42240, 42176,     0, 32768, 40960, 41984, 42240, 42176, 
+    42184,     0, 32768, 40960, 41984, 42240, 42176, 42184, 
+        0, 32768, 40960, 41984, 42240, 42176, 42184, 42186, 
+        0, 32768, 40960, 41984, 42240, 42176, 42184,     0, 
+    32768, 40960, 41984, 42240, 42176, 42192, 42188,     0, 
+    32768, 40960, 41984, 42240, 42176, 42192, 42188,     0, 
+    32768, 40960, 41984, 42240, 42176, 42192, 42193, 42190, 
+        0, 32768, 40960, 41984, 42240, 42176,     0, 32768, 
+    40960, 41984, 42240, 42176, 42192,     0, 32768, 40960, 
+    41984, 42240, 42176, 42192,     0, 32768, 40960, 41984, 
+    42240, 42176, 42192, 42194,     0, 32768, 40960, 41984, 
+    42240, 42176, 42192,     0, 32768, 40960, 41984, 42240, 
+    42176, 42192, 42196,     0, 32768, 40960, 41984, 42240, 
+    42176, 42192, 42196,     0, 32768, 40960, 41984, 42240, 
+    42176, 42192, 42200, 42198,     0, 32768, 40960, 41984, 
+    42240, 42176, 42192,     0, 32768, 40960, 41984, 42240, 
+    42176, 42208, 42200,     0, 32768, 40960, 41984, 42240, 
+    42176, 42208, 42200,     0, 32768, 40960, 41984, 42240, 
+    42176, 42208, 42200, 42202,     0, 32768, 40960, 41984, 
+    42240, 42176, 42208, 42200,     0, 32768, 40960, 41984, 
+    42240, 42176, 42208, 42209, 42204,     0, 32768, 40960, 
+    41984, 42240, 42176, 42208, 42209, 42204,     0, 32768, 
+    40960, 41984, 42240, 42176, 42208, 42209, 42204, 42206, 
+        0, 32768, 40960, 41984, 42240, 42176,     0, 32768, 
+    40960, 41984, 42240, 42241, 42208,     0, 32768, 40960, 
+    41984, 42240, 42241, 42208,     0, 32768, 40960, 41984, 
+    42240, 42241, 42208, 42210,     0, 32768, 40960, 41984, 
+    42240, 42241, 42208,     0, 32768, 40960, 41984, 42240, 
+    42241, 42208, 42212,     0, 32768, 40960, 41984, 42240, 
+    42241, 42208, 42212,     0, 32768, 40960, 41984, 42240, 
+    42241, 42208, 42216, 42214,     0, 32768, 40960, 41984, 
+    42240, 42241, 42208,     0, 32768, 40960, 41984, 42240, 
+    42241, 42208, 42216,     0, 32768, 40960, 41984, 42240, 
+    42241, 42208, 42216,     0, 32768, 40960, 41984, 42240, 
+    42241, 42208, 42216, 42218,     0, 32768, 40960, 41984, 
+    42240, 42241, 42208, 42216,     0, 32768, 40960, 41984, 
+    42240, 42241, 42208, 42224, 42220,     0, 32768, 40960, 
+    41984, 42240, 42241, 42208, 42224, 42220,     0, 32768, 
+    40960, 41984, 42240, 42241, 42208, 42224, 42225, 42222, 
+        0, 32768, 40960, 41984, 42240, 42241, 42208,     0, 
+    32768, 40960, 41984, 42240, 42241, 42208, 42224,     0, 
+    32768, 40960, 41984, 42240, 42241, 42243, 42224,     0, 
+    32768, 40960, 41984, 42240, 42241, 42243, 42224, 42226, 
+        0, 32768, 40960, 41984, 42240, 42241, 42243, 42224, 
+        0, 32768, 40960, 41984, 42240, 42241, 42243, 42224, 
+    42228,     0, 32768, 40960, 41984, 42240, 42241, 42243, 
+    42224, 42228,     0, 32768, 40960, 41984, 42240, 42241, 
+    42243, 42224, 42232, 42230,     0, 32768, 40960, 41984, 
+    42240, 42241, 42243, 42224,     0, 32768, 40960, 41984, 
+    42240, 42241, 42243, 42224, 42232,     0, 32768, 40960, 
+    41984, 42240, 42241, 42243, 42224, 42232,     0, 32768, 
+    40960, 41984, 42240, 42241, 42243, 42224, 42232, 42234, 
+        0, 32768, 40960, 41984, 42240, 42241, 42243, 42247, 
+    42232,     0, 32768, 40960, 41984, 42240, 42241, 42243, 
+    42247, 42232, 42236,     0, 32768, 40960, 41984, 42240, 
+    42241, 42243, 42247, 42232, 42236,     0, 32768, 40960, 
+    41984, 42240, 42241, 42243, 42247, 42232, 42236, 42238, 
+        0, 32768, 40960, 41984,     0, 32768, 40960, 41984, 
+    42240,     0, 32768, 40960, 41984, 42240,     0, 32768, 
+    40960, 41984, 42240, 42242,     0, 32768, 40960, 41984, 
+    42240,     0, 32768, 40960, 41984, 42240, 42244,     0, 
+    32768, 40960, 41984, 42240, 42244,     0, 32768, 40960, 
+    41984, 42240, 42248, 42246,     0, 32768, 40960, 41984, 
+    42240,     0, 32768, 40960, 41984, 42240, 42248,     0, 
+    32768, 40960, 41984, 42240, 42248,     0, 32768, 40960, 
+    41984, 42240, 42248, 42250,     0, 32768, 40960, 41984, 
+    42240, 42248,     0, 32768, 40960, 41984, 42240, 42256, 
+    42252,     0, 32768, 40960, 41984, 42240, 42256, 42252, 
+        0, 32768, 40960, 41984, 42240, 42256, 42257, 42254, 
+        0, 32768, 40960, 41984, 42240,     0, 32768, 40960, 
+    41984, 42240, 42256,     0, 32768, 40960, 41984, 42240, 
+    42256,     0, 32768, 40960, 41984, 42240, 42256, 42258, 
+        0, 32768, 40960, 41984, 42240, 42256,     0, 32768, 
+    40960, 41984, 42240, 42256, 42260,     0, 32768, 40960, 
+    41984, 42240, 42256, 42260,     0, 32768, 40960, 41984, 
+    42240, 42256, 42264, 42262,     0, 32768, 40960, 41984, 
+    42240, 42256,     0, 32768, 40960, 41984, 42240, 42272, 
+    42264,     0, 32768, 40960, 41984, 42240, 42272, 42264, 
+        0, 32768, 40960, 41984, 42240, 42272, 42264, 42266, 
+        0, 32768, 40960, 41984, 42240, 42272, 42264,     0, 
+    32768, 40960, 41984, 42240, 42272, 42273, 42268,     0, 
+    32768, 40960, 41984, 42240, 42272, 42273, 42268,     0, 
+    32768, 40960, 41984, 42240, 42272, 42273, 42268, 42270, 
+        0, 32768, 40960, 41984, 42240,     0, 32768, 40960, 
+    41984, 42240, 42272,     0, 32768, 40960, 41984, 42240, 
+    42272,     0, 32768, 40960, 41984, 42240, 42272, 42274, 
+        0, 32768, 40960, 41984, 42240, 42272,     0, 32768, 
+    40960, 41984, 42240, 42272, 42276,     0, 32768, 40960, 
+    41984, 42240, 42272, 42276,     0, 32768, 40960, 41984, 
+    42240, 42272, 42280, 42278,     0, 32768, 40960, 41984, 
+    42240, 42272,     0, 32768, 40960, 41984, 42240, 42272, 
+    42280,     0, 32768, 40960, 41984, 42240, 42272, 42280, 
+        0, 32768, 40960, 41984, 42240, 42272, 42280, 42282, 
+        0, 32768, 40960, 41984, 42240, 42272, 42280,     0, 
+    32768, 40960, 41984, 42240, 42272, 42288, 42284,     0, 
+    32768, 40960, 41984, 42240, 42272, 42288, 42284,     0, 
+    32768, 40960, 41984, 42240, 42272, 42288, 42289, 42286, 
+        0, 32768, 40960, 41984, 42240, 42272,     0, 32768, 
+    40960, 41984, 42240, 42304, 42288,     0, 32768, 40960, 
+    41984, 42240, 42304, 42288,     0, 32768, 40960, 41984, 
+    42240, 42304, 42288, 42290,     0, 32768, 40960, 41984, 
+    42240, 42304, 42288,     0, 32768, 40960, 41984, 42240, 
+    42304, 42288, 42292,     0, 32768, 40960, 41984, 42240, 
+    42304, 42288, 42292,     0, 32768, 40960, 41984, 42240, 
+    42304, 42288, 42296, 42294,     0, 32768, 40960, 41984, 
+    42240, 42304, 42288,     0, 32768, 40960, 41984, 42240, 
+    42304, 42305, 42296,     0, 32768, 40960, 41984, 42240, 
+    42304, 42305, 42296,     0, 32768, 40960, 41984, 42240, 
+    42304, 42305, 42296, 42298,     0, 32768, 40960, 41984, 
+    42240, 42304, 42305, 42296,     0, 32768, 40960, 41984, 
+    42240, 42304, 42305, 42296, 42300,     0, 32768, 40960, 
+    41984, 42240, 42304, 42305, 42307, 42300,     0, 32768, 
+    40960, 41984, 42240, 42304, 42305, 42307, 42300, 42302, 
+        0, 32768, 40960, 41984, 42240,     0, 32768, 40960, 
+    41984, 42240, 42304,     0, 32768, 40960, 41984, 42240, 
+    42304,     0, 32768, 40960, 41984, 42240, 42304, 42306, 
+        0, 32768, 40960, 41984, 42240, 42304,     0, 32768, 
+    40960, 41984, 42240, 42304, 42308,     0, 32768, 40960, 
+    41984, 42240, 42304, 42308,     0, 32768, 40960, 41984, 
+    42240, 42304, 42312, 42310,     0, 32768, 40960, 41984, 
+    42240, 42304,     0, 32768, 40960, 41984, 42240, 42304, 
+    42312,     0, 32768, 40960, 41984, 42240, 42304, 42312, 
+        0, 32768, 40960, 41984, 42240, 42304, 42312, 42314, 
+        0, 32768, 40960, 41984, 42240, 42304, 42312,     0, 
+    32768, 40960, 41984, 42240, 42304, 42320, 42316,     0, 
+    32768, 40960, 41984, 42240, 42304, 42320, 42316,     0, 
+    32768, 40960, 41984, 42240, 42304, 42320, 42321, 42318, 
+        0, 32768, 40960, 41984, 42240, 42304,     0, 32768, 
+    40960, 41984, 42240, 42304, 42320,     0, 32768, 40960, 
+    41984, 42240, 42304, 42320,     0, 32768, 40960, 41984, 
+    42240, 42304, 42320, 42322,     0, 32768, 40960, 41984, 
+    42240, 42304, 42320,     0, 32768, 40960, 41984, 42240, 
+    42304, 42320, 42324,     0, 32768, 40960, 41984, 42240, 
+    42304, 42320, 42324,     0, 32768, 40960, 41984, 42240, 
+    42304, 42320, 42328, 42326,     0, 32768, 40960, 41984, 
+    42240, 42304, 42320,     0, 32768, 40960, 41984, 42240, 
+    42304, 42336, 42328,     0, 32768, 40960, 41984, 42240, 
+    42304, 42336, 42328,     0, 32768, 40960, 41984, 42240, 
+    42304, 42336, 42328, 42330,     0, 32768, 40960, 41984, 
+    42240, 42304, 42336, 42328,     0, 32768, 40960, 41984, 
+    42240, 42304, 42336, 42337, 42332,     0, 32768, 40960, 
+    41984, 42240, 42304, 42336, 42337, 42332,     0, 32768, 
+    40960, 41984, 42240, 42304, 42336, 42337, 42332, 42334, 
+        0, 32768, 40960, 41984, 42240, 42304,     0, 32768, 
+    40960, 41984, 42240, 42368, 42336,     0, 32768, 40960, 
+    41984, 42240, 42368, 42336,     0, 32768, 40960, 41984, 
+    42240, 42368, 42336, 42338,     0, 32768, 40960, 41984, 
+    42240, 42368, 42336,     0, 32768, 40960, 41984, 42240, 
+    42368, 42336, 42340,     0, 32768, 40960, 41984, 42240, 
+    42368, 42336, 42340,     0, 32768, 40960, 41984, 42240, 
+    42368, 42336, 42344, 42342,     0, 32768, 40960, 41984, 
+    42240, 42368, 42336,     0, 32768, 40960, 41984, 42240, 
+    42368, 42336, 42344,     0, 32768, 40960, 41984, 42240, 
+    42368, 42336, 42344,     0, 32768, 40960, 41984, 42240, 
+    42368, 42336, 42344, 42346,     0, 32768, 40960, 41984, 
+    42240, 42368, 42336, 42344,     0, 32768, 40960, 41984, 
+    42240, 42368, 42336, 42352, 42348,     0, 32768, 40960, 
+    41984, 42240, 42368, 42336, 42352, 42348,     0, 32768, 
+    40960, 41984, 42240, 42368, 42336, 42352, 42353, 42350, 
+        0, 32768, 40960, 41984, 42240, 42368, 42336,     0, 
+    32768, 40960, 41984, 42240, 42368, 42369, 42352,     0, 
+    32768, 40960, 41984, 42240, 42368, 42369, 42352,     0, 
+    32768, 40960, 41984, 42240, 42368, 42369, 42352, 42354, 
+        0, 32768, 40960, 41984, 42240, 42368, 42369, 42352, 
+        0, 32768, 40960, 41984, 42240, 42368, 42369, 42352, 
+    42356,     0, 32768, 40960, 41984, 42240, 42368, 42369, 
+    42352, 42356,     0, 32768, 40960, 41984, 42240, 42368, 
+    42369, 42352, 42360, 42358,     0, 32768, 40960, 41984, 
+    42240, 42368, 42369, 42352,     0, 32768, 40960, 41984, 
+    42240, 42368, 42369, 42352, 42360,     0, 32768, 40960, 
+    41984, 42240, 42368, 42369, 42371, 42360,     0, 32768, 
+    40960, 41984, 42240, 42368, 42369, 42371, 42360, 42362, 
+        0, 32768, 40960, 41984, 42240, 42368, 42369, 42371, 
+    42360,     0, 32768, 40960, 41984, 42240, 42368, 42369, 
+    42371, 42360, 42364,     0, 32768, 40960, 41984, 42240, 
+    42368, 42369, 42371, 42360, 42364,     0, 32768, 40960, 
+    41984, 42240, 42368, 42369, 42371, 42360, 42364, 42366, 
+        0, 32768, 40960, 41984, 42240,     0, 32768, 40960, 
+    41984, 42496, 42368,     0, 32768, 40960, 41984, 42496, 
+    42368,     0, 32768, 40960, 41984, 42496, 42368, 42370, 
+        0, 32768, 40960, 41984, 42496, 42368,     0, 32768, 
+    40960, 41984, 42496, 42368, 42372,     0, 32768, 40960, 
+    41984, 42496, 42368, 42372,     0, 32768, 40960, 41984, 
+    42496, 42368, 42376, 42374,     0, 32768, 40960, 41984, 
+    42496, 42368,     0, 32768, 40960, 41984, 42496, 42368, 
+    42376,     0, 32768, 40960, 41984, 42496, 42368, 42376, 
+        0, 32768, 40960, 41984, 42496, 42368, 42376, 42378, 
+        0, 32768, 40960, 41984, 42496, 42368, 42376,     0, 
+    32768, 40960, 41984, 42496, 42368, 42384, 42380,     0, 
+    32768, 40960, 41984, 42496, 42368, 42384, 42380,     0, 
+    32768, 40960, 41984, 42496, 42368, 42384, 42385, 42382, 
+        0, 32768, 40960, 41984, 42496, 42368,     0, 32768, 
+    40960, 41984, 42496, 42368, 42384,     0, 32768, 40960, 
+    41984, 42496, 42368, 42384,     0, 32768, 40960, 41984, 
+    42496, 42368, 42384, 42386,     0, 32768, 40960, 41984, 
+    42496, 42368, 42384,     0, 32768, 40960, 41984, 42496, 
+    42368, 42384, 42388,     0, 32768, 40960, 41984, 42496, 
+    42368, 42384, 42388,     0, 32768, 40960, 41984, 42496, 
+    42368, 42384, 42392, 42390,     0, 32768, 40960, 41984, 
+    42496, 42368, 42384,     0, 32768, 40960, 41984, 42496, 
+    42368, 42400, 42392,     0, 32768, 40960, 41984, 42496, 
+    42368, 42400, 42392,     0, 32768, 40960, 41984, 42496, 
+    42368, 42400, 42392, 42394,     0, 32768, 40960, 41984, 
+    42496, 42368, 42400, 42392,     0, 32768, 40960, 41984, 
+    42496, 42368, 42400, 42401, 42396,     0, 32768, 40960, 
+    41984, 42496, 42368, 42400, 42401, 42396,     0, 32768, 
+    40960, 41984, 42496, 42368, 42400, 42401, 42396, 42398, 
+        0, 32768, 40960, 41984, 42496, 42368,     0, 32768, 
+    40960, 41984, 42496, 42368, 42400,     0, 32768, 40960, 
+    41984, 42496, 42368, 42400,     0, 32768, 40960, 41984, 
+    42496, 42368, 42400, 42402,     0, 32768, 40960, 41984, 
+    42496, 42368, 42400,     0, 32768, 40960, 41984, 42496, 
+    42368, 42400, 42404,     0, 32768, 40960, 41984, 42496, 
+    42368, 42400, 42404,     0, 32768, 40960, 41984, 42496, 
+    42368, 42400, 42408, 42406,     0, 32768, 40960, 41984, 
+    42496, 42368, 42400,     0, 32768, 40960, 41984, 42496, 
+    42368, 42400, 42408,     0, 32768, 40960, 41984, 42496, 
+    42368, 42400, 42408,     0, 32768, 40960, 41984, 42496, 
+    42368, 42400, 42408, 42410,     0, 32768, 40960, 41984, 
+    42496, 42368, 42400, 42408,     0, 32768, 40960, 41984, 
+    42496, 42368, 42400, 42416, 42412,     0, 32768, 40960, 
+    41984, 42496, 42368, 42400, 42416, 42412,     0, 32768, 
+    40960, 41984, 42496, 42368, 42400, 42416, 42417, 42414, 
+        0, 32768, 40960, 41984, 42496, 42368, 42400,     0, 
+    32768, 40960, 41984, 42496, 42368, 42432, 42416,     0, 
+    32768, 40960, 41984, 42496, 42368, 42432, 42416,     0, 
+    32768, 40960, 41984, 42496, 42368, 42432, 42416, 42418, 
+        0, 32768, 40960, 41984, 42496, 42368, 42432, 42416, 
+        0, 32768, 40960, 41984, 42496, 42368, 42432, 42416, 
+    42420,     0, 32768, 40960, 41984, 42496, 42368, 42432, 
+    42416, 42420,     0, 32768, 40960, 41984, 42496, 42368, 
+    42432, 42416, 42424, 42422,     0, 32768, 40960, 41984, 
+    42496, 42368, 42432, 42416,     0, 32768, 40960, 41984, 
+    42496, 42368, 42432, 42433, 42424,     0, 32768, 40960, 
+    41984, 42496, 42368, 42432, 42433, 42424,     0, 32768, 
+    40960, 41984, 42496, 42368, 42432, 42433, 42424, 42426, 
+        0, 32768, 40960, 41984, 42496, 42368, 42432, 42433, 
+    42424,     0, 32768, 40960, 41984, 42496, 42368, 42432, 
+    42433, 42424, 42428,     0, 32768, 40960, 41984, 42496, 
+    42368, 42432, 42433, 42435, 42428,     0, 32768, 40960, 
+    41984, 42496, 42368, 42432, 42433, 42435, 42428, 42430, 
+        0, 32768, 40960, 41984, 42496, 42368,     0, 32768, 
+    40960, 41984, 42496, 42497, 42432,     0, 32768, 40960, 
+    41984, 42496, 42497, 42432,     0, 32768, 40960, 41984, 
+    42496, 42497, 42432, 42434,     0, 32768, 40960, 41984, 
+    42496, 42497, 42432,     0, 32768, 40960, 41984, 42496, 
+    42497, 42432, 42436,     0, 32768, 40960, 41984, 42496, 
+    42497, 42432, 42436,     0, 32768, 40960, 41984, 42496, 
+    42497, 42432, 42440, 42438,     0, 32768, 40960, 41984, 
+    42496, 42497, 42432,     0, 32768, 40960, 41984, 42496, 
+    42497, 42432, 42440,     0, 32768, 40960, 41984, 42496, 
+    42497, 42432, 42440,     0, 32768, 40960, 41984, 42496, 
+    42497, 42432, 42440, 42442,     0, 32768, 40960, 41984, 
+    42496, 42497, 42432, 42440,     0, 32768, 40960, 41984, 
+    42496, 42497, 42432, 42448, 42444,     0, 32768, 40960, 
+    41984, 42496, 42497, 42432, 42448, 42444,     0, 32768, 
+    40960, 41984, 42496, 42497, 42432, 42448, 42449, 42446, 
+        0, 32768, 40960, 41984, 42496, 42497, 42432,     0, 
+    32768, 40960, 41984, 42496, 42497, 42432, 42448,     0, 
+    32768, 40960, 41984, 42496, 42497, 42432, 42448,     0, 
+    32768, 40960, 41984, 42496, 42497, 42432, 42448, 42450, 
+        0, 32768, 40960, 41984, 42496, 42497, 42432, 42448, 
+        0, 32768, 40960, 41984, 42496, 42497, 42432, 42448, 
+    42452,     0, 32768, 40960, 41984, 42496, 42497, 42432, 
+    42448, 42452,     0, 32768, 40960, 41984, 42496, 42497, 
+    42432, 42448, 42456, 42454,     0, 32768, 40960, 41984, 
+    42496, 42497, 42432, 42448,     0, 32768, 40960, 41984, 
+    42496, 42497, 42432, 42464, 42456,     0, 32768, 40960, 
+    41984, 42496, 42497, 42432, 42464, 42456,     0, 32768, 
+    40960, 41984, 42496, 42497, 42432, 42464, 42456, 42458, 
+        0, 32768, 40960, 41984, 42496, 42497, 42432, 42464, 
+    42456,     0, 32768, 40960, 41984, 42496, 42497, 42432, 
+    42464, 42465, 42460,     0, 32768, 40960, 41984, 42496, 
+    42497, 42432, 42464, 42465, 42460,     0, 32768, 40960, 
+    41984, 42496, 42497, 42432, 42464, 42465, 42460, 42462, 
+        0, 32768, 40960, 41984, 42496, 42497, 42432,     0, 
+    32768, 40960, 41984, 42496, 42497, 42432, 42464,     0, 
+    32768, 40960, 41984, 42496, 42497, 42499, 42464,     0, 
+    32768, 40960, 41984, 42496, 42497, 42499, 42464, 42466, 
+        0, 32768, 40960, 41984, 42496, 42497, 42499, 42464, 
+        0, 32768, 40960, 41984, 42496, 42497, 42499, 42464, 
+    42468,     0, 32768, 40960, 41984, 42496, 42497, 42499, 
+    42464, 42468,     0, 32768, 40960, 41984, 42496, 42497, 
+    42499, 42464, 42472, 42470,     0, 32768, 40960, 41984, 
+    42496, 42497, 42499, 42464,     0, 32768, 40960, 41984, 
+    42496, 42497, 42499, 42464, 42472,     0, 32768, 40960, 
+    41984, 42496, 42497, 42499, 42464, 42472,     0, 32768, 
+    40960, 41984, 42496, 42497, 42499, 42464, 42472, 42474, 
+        0, 32768, 40960, 41984, 42496, 42497, 42499, 42464, 
+    42472,     0, 32768, 40960, 41984, 42496, 42497, 42499, 
+    42464, 42480, 42476,     0, 32768, 40960, 41984, 42496, 
+    42497, 42499, 42464, 42480, 42476,     0, 32768, 40960, 
+    41984, 42496, 42497, 42499, 42464, 42480, 42481, 42478, 
+        0, 32768, 40960, 41984, 42496, 42497, 42499, 42464, 
+        0, 32768, 40960, 41984, 42496, 42497, 42499, 42464, 
+    42480,     0, 32768, 40960, 41984, 42496, 42497, 42499, 
+    42464, 42480,     0, 32768, 40960, 41984, 42496, 42497, 
+    42499, 42464, 42480, 42482,     0, 32768, 40960, 41984, 
+    42496, 42497, 42499, 42503, 42480,     0, 32768, 40960, 
+    41984, 42496, 42497, 42499, 42503, 42480, 42484,     0, 
+    32768, 40960, 41984, 42496, 42497, 42499, 42503, 42480, 
+    42484,     0, 32768, 40960, 41984, 42496, 42497, 42499, 
+    42503, 42480, 42488, 42486,     0, 32768, 40960, 41984, 
+    42496, 42497, 42499, 42503, 42480,     0, 32768, 40960, 
+    41984, 42496, 42497, 42499, 42503, 42480, 42488,     0, 
+    32768, 40960, 41984, 42496, 42497, 42499, 42503, 42480, 
+    42488,     0, 32768, 40960, 41984, 42496, 42497, 42499, 
+    42503, 42480, 42488, 42490,     0, 32768, 40960, 41984, 
+    42496, 42497, 42499, 42503, 42480, 42488,     0, 32768, 
+    40960, 41984, 42496, 42497, 42499, 42503, 42480, 42488, 
+    42492,     0, 32768, 40960, 41984, 42496, 42497, 42499, 
+    42503, 42480, 42488, 42492,     0, 32768, 40960, 41984, 
+    42496, 42497, 42499, 42503, 42480, 42488, 42492, 42494, 
+        0, 32768, 40960, 41984,     0, 32768, 40960, 43008, 
+    42496,     0, 32768, 40960, 43008, 42496,     0, 32768, 
+    40960, 43008, 42496, 42498,     0, 32768, 40960, 43008, 
+    42496,     0, 32768, 40960, 43008, 42496, 42500,     0, 
+    32768, 40960, 43008, 42496, 42500,     0, 32768, 40960, 
+    43008, 42496, 42504, 42502,     0, 32768, 40960, 43008, 
+    42496,     0, 32768, 40960, 43008, 42496, 42504,     0, 
+    32768, 40960, 43008, 42496, 42504,     0, 32768, 40960, 
+    43008, 42496, 42504, 42506,     0, 32768, 40960, 43008, 
+    42496, 42504,     0, 32768, 40960, 43008, 42496, 42512, 
+    42508,     0, 32768, 40960, 43008, 42496, 42512, 42508, 
+        0, 32768, 40960, 43008, 42496, 42512, 42513, 42510, 
+        0, 32768, 40960, 43008, 42496,     0, 32768, 40960, 
+    43008, 42496, 42512,     0, 32768, 40960, 43008, 42496, 
+    42512,     0, 32768, 40960, 43008, 42496, 42512, 42514, 
+        0, 32768, 40960, 43008, 42496, 42512,     0, 32768, 
+    40960, 43008, 42496, 42512, 42516,     0, 32768, 40960, 
+    43008, 42496, 42512, 42516,     0, 32768, 40960, 43008, 
+    42496, 42512, 42520, 42518,     0, 32768, 40960, 43008, 
+    42496, 42512,     0, 32768, 40960, 43008, 42496, 42528, 
+    42520,     0, 32768, 40960, 43008, 42496, 42528, 42520, 
+        0, 32768, 40960, 43008, 42496, 42528, 42520, 42522, 
+        0, 32768, 40960, 43008, 42496, 42528, 42520,     0, 
+    32768, 40960, 43008, 42496, 42528, 42529, 42524,     0, 
+    32768, 40960, 43008, 42496, 42528, 42529, 42524,     0, 
+    32768, 40960, 43008, 42496, 42528, 42529, 42524, 42526, 
+        0, 32768, 40960, 43008, 42496,     0, 32768, 40960, 
+    43008, 42496, 42528,     0, 32768, 40960, 43008, 42496, 
+    42528,     0, 32768, 40960, 43008, 42496, 42528, 42530, 
+        0, 32768, 40960, 43008, 42496, 42528,     0, 32768, 
+    40960, 43008, 42496, 42528, 42532,     0, 32768, 40960, 
+    43008, 42496, 42528, 42532,     0, 32768, 40960, 43008, 
+    42496, 42528, 42536, 42534,     0, 32768, 40960, 43008, 
+    42496, 42528,     0, 32768, 40960, 43008, 42496, 42528, 
+    42536,     0, 32768, 40960, 43008, 42496, 42528, 42536, 
+        0, 32768, 40960, 43008, 42496, 42528, 42536, 42538, 
+        0, 32768, 40960, 43008, 42496, 42528, 42536,     0, 
+    32768, 40960, 43008, 42496, 42528, 42544, 42540,     0, 
+    32768, 40960, 43008, 42496, 42528, 42544, 42540,     0, 
+    32768, 40960, 43008, 42496, 42528, 42544, 42545, 42542, 
+        0, 32768, 40960, 43008, 42496, 42528,     0, 32768, 
+    40960, 43008, 42496, 42560, 42544,     0, 32768, 40960, 
+    43008, 42496, 42560, 42544,     0, 32768, 40960, 43008, 
+    42496, 42560, 42544, 42546,     0, 32768, 40960, 43008, 
+    42496, 42560, 42544,     0, 32768, 40960, 43008, 42496, 
+    42560, 42544, 42548,     0, 32768, 40960, 43008, 42496, 
+    42560, 42544, 42548,     0, 32768, 40960, 43008, 42496, 
+    42560, 42544, 42552, 42550,     0, 32768, 40960, 43008, 
+    42496, 42560, 42544,     0, 32768, 40960, 43008, 42496, 
+    42560, 42561, 42552,     0, 32768, 40960, 43008, 42496, 
+    42560, 42561, 42552,     0, 32768, 40960, 43008, 42496, 
+    42560, 42561, 42552, 42554,     0, 32768, 40960, 43008, 
+    42496, 42560, 42561, 42552,     0, 32768, 40960, 43008, 
+    42496, 42560, 42561, 42552, 42556,     0, 32768, 40960, 
+    43008, 42496, 42560, 42561, 42563, 42556,     0, 32768, 
+    40960, 43008, 42496, 42560, 42561, 42563, 42556, 42558, 
+        0, 32768, 40960, 43008, 42496,     0, 32768, 40960, 
+    43008, 42496, 42560,     0, 32768, 40960, 43008, 42496, 
+    42560,     0, 32768, 40960, 43008, 42496, 42560, 42562, 
+        0, 32768, 40960, 43008, 42496, 42560,     0, 32768, 
+    40960, 43008, 42496, 42560, 42564,     0, 32768, 40960, 
+    43008, 42496, 42560, 42564,     0, 32768, 40960, 43008, 
+    42496, 42560, 42568, 42566,     0, 32768, 40960, 43008, 
+    42496, 42560,     0, 32768, 40960, 43008, 42496, 42560, 
+    42568,     0, 32768, 40960, 43008, 42496, 42560, 42568, 
+        0, 32768, 40960, 43008, 42496, 42560, 42568, 42570, 
+        0, 32768, 40960, 43008, 42496, 42560, 42568,     0, 
+    32768, 40960, 43008, 42496, 42560, 42576, 42572,     0, 
+    32768, 40960, 43008, 42496, 42560, 42576, 42572,     0, 
+    32768, 40960, 43008, 42496, 42560, 42576, 42577, 42574, 
+        0, 32768, 40960, 43008, 42496, 42560,     0, 32768, 
+    40960, 43008, 42496, 42560, 42576,     0, 32768, 40960, 
+    43008, 42496, 42560, 42576,     0, 32768, 40960, 43008, 
+    42496, 42560, 42576, 42578,     0, 32768, 40960, 43008, 
+    42496, 42560, 42576,     0, 32768, 40960, 43008, 42496, 
+    42560, 42576, 42580,     0, 32768, 40960, 43008, 42496, 
+    42560, 42576, 42580,     0, 32768, 40960, 43008, 42496, 
+    42560, 42576, 42584, 42582,     0, 32768, 40960, 43008, 
+    42496, 42560, 42576,     0, 32768, 40960, 43008, 42496, 
+    42560, 42592, 42584,     0, 32768, 40960, 43008, 42496, 
+    42560, 42592, 42584,     0, 32768, 40960, 43008, 42496, 
+    42560, 42592, 42584, 42586,     0, 32768, 40960, 43008, 
+    42496, 42560, 42592, 42584,     0, 32768, 40960, 43008, 
+    42496, 42560, 42592, 42593, 42588,     0, 32768, 40960, 
+    43008, 42496, 42560, 42592, 42593, 42588,     0, 32768, 
+    40960, 43008, 42496, 42560, 42592, 42593, 42588, 42590, 
+        0, 32768, 40960, 43008, 42496, 42560,     0, 32768, 
+    40960, 43008, 42496, 42624, 42592,     0, 32768, 40960, 
+    43008, 42496, 42624, 42592,     0, 32768, 40960, 43008, 
+    42496, 42624, 42592, 42594,     0, 32768, 40960, 43008, 
+    42496, 42624, 42592,     0, 32768, 40960, 43008, 42496, 
+    42624, 42592, 42596,     0, 32768, 40960, 43008, 42496, 
+    42624, 42592, 42596,     0, 32768, 40960, 43008, 42496, 
+    42624, 42592, 42600, 42598,     0, 32768, 40960, 43008, 
+    42496, 42624, 42592,     0, 32768, 40960, 43008, 42496, 
+    42624, 42592, 42600,     0, 32768, 40960, 43008, 42496, 
+    42624, 42592, 42600,     0, 32768, 40960, 43008, 42496, 
+    42624, 42592, 42600, 42602,     0, 32768, 40960, 43008, 
+    42496, 42624, 42592, 42600,     0, 32768, 40960, 43008, 
+    42496, 42624, 42592, 42608, 42604,     0, 32768, 40960, 
+    43008, 42496, 42624, 42592, 42608, 42604,     0, 32768, 
+    40960, 43008, 42496, 42624, 42592, 42608, 42609, 42606, 
+        0, 32768, 40960, 43008, 42496, 42624, 42592,     0, 
+    32768, 40960, 43008, 42496, 42624, 42625, 42608,     0, 
+    32768, 40960, 43008, 42496, 42624, 42625, 42608,     0, 
+    32768, 40960, 43008, 42496, 42624, 42625, 42608, 42610, 
+        0, 32768, 40960, 43008, 42496, 42624, 42625, 42608, 
+        0, 32768, 40960, 43008, 42496, 42624, 42625, 42608, 
+    42612,     0, 32768, 40960, 43008, 42496, 42624, 42625, 
+    42608, 42612,     0, 32768, 40960, 43008, 42496, 42624, 
+    42625, 42608, 42616, 42614,     0, 32768, 40960, 43008, 
+    42496, 42624, 42625, 42608,     0, 32768, 40960, 43008, 
+    42496, 42624, 42625, 42608, 42616,     0, 32768, 40960, 
+    43008, 42496, 42624, 42625, 42627, 42616,     0, 32768, 
+    40960, 43008, 42496, 42624, 42625, 42627, 42616, 42618, 
+        0, 32768, 40960, 43008, 42496, 42624, 42625, 42627, 
+    42616,     0, 32768, 40960, 43008, 42496, 42624, 42625, 
+    42627, 42616, 42620,     0, 32768, 40960, 43008, 42496, 
+    42624, 42625, 42627, 42616, 42620,     0, 32768, 40960, 
+    43008, 42496, 42624, 42625, 42627, 42616, 42620, 42622, 
+        0, 32768, 40960, 43008, 42496,     0, 32768, 40960, 
+    43008, 42496, 42624,     0, 32768, 40960, 43008, 42496, 
+    42624,     0, 32768, 40960, 43008, 42496, 42624, 42626, 
+        0, 32768, 40960, 43008, 42496, 42624,     0, 32768, 
+    40960, 43008, 42496, 42624, 42628,     0, 32768, 40960, 
+    43008, 42496, 42624, 42628,     0, 32768, 40960, 43008, 
+    42496, 42624, 42632, 42630,     0, 32768, 40960, 43008, 
+    42496, 42624,     0, 32768, 40960, 43008, 42496, 42624, 
+    42632,     0, 32768, 40960, 43008, 42496, 42624, 42632, 
+        0, 32768, 40960, 43008, 42496, 42624, 42632, 42634, 
+        0, 32768, 40960, 43008, 42496, 42624, 42632,     0, 
+    32768, 40960, 43008, 42496, 42624, 42640, 42636,     0, 
+    32768, 40960, 43008, 42496, 42624, 42640, 42636,     0, 
+    32768, 40960, 43008, 42496, 42624, 42640, 42641, 42638, 
+        0, 32768, 40960, 43008, 42496, 42624,     0, 32768, 
+    40960, 43008, 42496, 42624, 42640,     0, 32768, 40960, 
+    43008, 42496, 42624, 42640,     0, 32768, 40960, 43008, 
+    42496, 42624, 42640, 42642,     0, 32768, 40960, 43008, 
+    42496, 42624, 42640,     0, 32768, 40960, 43008, 42496, 
+    42624, 42640, 42644,     0, 32768, 40960, 43008, 42496, 
+    42624, 42640, 42644,     0, 32768, 40960, 43008, 42496, 
+    42624, 42640, 42648, 42646,     0, 32768, 40960, 43008, 
+    42496, 42624, 42640,     0, 32768, 40960, 43008, 42496, 
+    42624, 42656, 42648,     0, 32768, 40960, 43008, 42496, 
+    42624, 42656, 42648,     0, 32768, 40960, 43008, 42496, 
+    42624, 42656, 42648, 42650,     0, 32768, 40960, 43008, 
+    42496, 42624, 42656, 42648,     0, 32768, 40960, 43008, 
+    42496, 42624, 42656, 42657, 42652,     0, 32768, 40960, 
+    43008, 42496, 42624, 42656, 42657, 42652,     0, 32768, 
+    40960, 43008, 42496, 42624, 42656, 42657, 42652, 42654, 
+        0, 32768, 40960, 43008, 42496, 42624,     0, 32768, 
+    40960, 43008, 42496, 42624, 42656,     0, 32768, 40960, 
+    43008, 42496, 42624, 42656,     0, 32768, 40960, 43008, 
+    42496, 42624, 42656, 42658,     0, 32768, 40960, 43008, 
+    42496, 42624, 42656,     0, 32768, 40960, 43008, 42496, 
+    42624, 42656, 42660,     0, 32768, 40960, 43008, 42496, 
+    42624, 42656, 42660,     0, 32768, 40960, 43008, 42496, 
+    42624, 42656, 42664, 42662,     0, 32768, 40960, 43008, 
+    42496, 42624, 42656,     0, 32768, 40960, 43008, 42496, 
+    42624, 42656, 42664,     0, 32768, 40960, 43008, 42496, 
+    42624, 42656, 42664,     0, 32768, 40960, 43008, 42496, 
+    42624, 42656, 42664, 42666,     0, 32768, 40960, 43008, 
+    42496, 42624, 42656, 42664,     0, 32768, 40960, 43008, 
+    42496, 42624, 42656, 42672, 42668,     0, 32768, 40960, 
+    43008, 42496, 42624, 42656, 42672, 42668,     0, 32768, 
+    40960, 43008, 42496, 42624, 42656, 42672, 42673, 42670, 
+        0, 32768, 40960, 43008, 42496, 42624, 42656,     0, 
+    32768, 40960, 43008, 42496, 42624, 42688, 42672,     0, 
+    32768, 40960, 43008, 42496, 42624, 42688, 42672,     0, 
+    32768, 40960, 43008, 42496, 42624, 42688, 42672, 42674, 
+        0, 32768, 40960, 43008, 42496, 42624, 42688, 42672, 
+        0, 32768, 40960, 43008, 42496, 42624, 42688, 42672, 
+    42676,     0, 32768, 40960, 43008, 42496, 42624, 42688, 
+    42672, 42676,     0, 32768, 40960, 43008, 42496, 42624, 
+    42688, 42672, 42680, 42678,     0, 32768, 40960, 43008, 
+    42496, 42624, 42688, 42672,     0, 32768, 40960, 43008, 
+    42496, 42624, 42688, 42689, 42680,     0, 32768, 40960, 
+    43008, 42496, 42624, 42688, 42689, 42680,     0, 32768, 
+    40960, 43008, 42496, 42624, 42688, 42689, 42680, 42682, 
+        0, 32768, 40960, 43008, 42496, 42624, 42688, 42689, 
+    42680,     0, 32768, 40960, 43008, 42496, 42624, 42688, 
+    42689, 42680, 42684,     0, 32768, 40960, 43008, 42496, 
+    42624, 42688, 42689, 42691, 42684,     0, 32768, 40960, 
+    43008, 42496, 42624, 42688, 42689, 42691, 42684, 42686, 
+        0, 32768, 40960, 43008, 42496, 42624,     0, 32768, 
+    40960, 43008, 42496, 42752, 42688,     0, 32768, 40960, 
+    43008, 42496, 42752, 42688,     0, 32768, 40960, 43008, 
+    42496, 42752, 42688, 42690,     0, 32768, 40960, 43008, 
+    42496, 42752, 42688,     0, 32768, 40960, 43008, 42496, 
+    42752, 42688, 42692,     0, 32768, 40960, 43008, 42496, 
+    42752, 42688, 42692,     0, 32768, 40960, 43008, 42496, 
+    42752, 42688, 42696, 42694,     0, 32768, 40960, 43008, 
+    42496, 42752, 42688,     0, 32768, 40960, 43008, 42496, 
+    42752, 42688, 42696,     0, 32768, 40960, 43008, 42496, 
+    42752, 42688, 42696,     0, 32768, 40960, 43008, 42496, 
+    42752, 42688, 42696, 42698,     0, 32768, 40960, 43008, 
+    42496, 42752, 42688, 42696,     0, 32768, 40960, 43008, 
+    42496, 42752, 42688, 42704, 42700,     0, 32768, 40960, 
+    43008, 42496, 42752, 42688, 42704, 42700,     0, 32768, 
+    40960, 43008, 42496, 42752, 42688, 42704, 42705, 42702, 
+        0, 32768, 40960, 43008, 42496, 42752, 42688,     0, 
+    32768, 40960, 43008, 42496, 42752, 42688, 42704,     0, 
+    32768, 40960, 43008, 42496, 42752, 42688, 42704,     0, 
+    32768, 40960, 43008, 42496, 42752, 42688, 42704, 42706, 
+        0, 32768, 40960, 43008, 42496, 42752, 42688, 42704, 
+        0, 32768, 40960, 43008, 42496, 42752, 42688, 42704, 
+    42708,     0, 32768, 40960, 43008, 42496, 42752, 42688, 
+    42704, 42708,     0, 32768, 40960, 43008, 42496, 42752, 
+    42688, 42704, 42712, 42710,     0, 32768, 40960, 43008, 
+    42496, 42752, 42688, 42704,     0, 32768, 40960, 43008, 
+    42496, 42752, 42688, 42720, 42712,     0, 32768, 40960, 
+    43008, 42496, 42752, 42688, 42720, 42712,     0, 32768, 
+    40960, 43008, 42496, 42752, 42688, 42720, 42712, 42714, 
+        0, 32768, 40960, 43008, 42496, 42752, 42688, 42720, 
+    42712,     0, 32768, 40960, 43008, 42496, 42752, 42688, 
+    42720, 42721, 42716,     0, 32768, 40960, 43008, 42496, 
+    42752, 42688, 42720, 42721, 42716,     0, 32768, 40960, 
+    43008, 42496, 42752, 42688, 42720, 42721, 42716, 42718, 
+        0, 32768, 40960, 43008, 42496, 42752, 42688,     0, 
+    32768, 40960, 43008, 42496, 42752, 42753, 42720,     0, 
+    32768, 40960, 43008, 42496, 42752, 42753, 42720,     0, 
+    32768, 40960, 43008, 42496, 42752, 42753, 42720, 42722, 
+        0, 32768, 40960, 43008, 42496, 42752, 42753, 42720, 
+        0, 32768, 40960, 43008, 42496, 42752, 42753, 42720, 
+    42724,     0, 32768, 40960, 43008, 42496, 42752, 42753, 
+    42720, 42724,     0, 32768, 40960, 43008, 42496, 42752, 
+    42753, 42720, 42728, 42726,     0, 32768, 40960, 43008, 
+    42496, 42752, 42753, 42720,     0, 32768, 40960, 43008, 
+    42496, 42752, 42753, 42720, 42728,     0, 32768, 40960, 
+    43008, 42496, 42752, 42753, 42720, 42728,     0, 32768, 
+    40960, 43008, 42496, 42752, 42753, 42720, 42728, 42730, 
+        0, 32768, 40960, 43008, 42496, 42752, 42753, 42720, 
+    42728,     0, 32768, 40960, 43008, 42496, 42752, 42753, 
+    42720, 42736, 42732,     0, 32768, 40960, 43008, 42496, 
+    42752, 42753, 42720, 42736, 42732,     0, 32768, 40960, 
+    43008, 42496, 42752, 42753, 42720, 42736, 42737, 42734, 
+        0, 32768, 40960, 43008, 42496, 42752, 42753, 42720, 
+        0, 32768, 40960, 43008, 42496, 42752, 42753, 42720, 
+    42736,     0, 32768, 40960, 43008, 42496, 42752, 42753, 
+    42755, 42736,     0, 32768, 40960, 43008, 42496, 42752, 
+    42753, 42755, 42736, 42738,     0, 32768, 40960, 43008, 
+    42496, 42752, 42753, 42755, 42736,     0, 32768, 40960, 
+    43008, 42496, 42752, 42753, 42755, 42736, 42740,     0, 
+    32768, 40960, 43008, 42496, 42752, 42753, 42755, 42736, 
+    42740,     0, 32768, 40960, 43008, 42496, 42752, 42753, 
+    42755, 42736, 42744, 42742,     0, 32768, 40960, 43008, 
+    42496, 42752, 42753, 42755, 42736,     0, 32768, 40960, 
+    43008, 42496, 42752, 42753, 42755, 42736, 42744,     0, 
+    32768, 40960, 43008, 42496, 42752, 42753, 42755, 42736, 
+    42744,     0, 32768, 40960, 43008, 42496, 42752, 42753, 
+    42755, 42736, 42744, 42746,     0, 32768, 40960, 43008, 
+    42496, 42752, 42753, 42755, 42759, 42744,     0, 32768, 
+    40960, 43008, 42496, 42752, 42753, 42755, 42759, 42744, 
+    42748,     0, 32768, 40960, 43008, 42496, 42752, 42753, 
+    42755, 42759, 42744, 42748,     0, 32768, 40960, 43008, 
+    42496, 42752, 42753, 42755, 42759, 42744, 42748, 42750, 
+        0, 32768, 40960, 43008, 42496,     0, 32768, 40960, 
+    43008, 42496, 42752,     0, 32768, 40960, 43008, 43009, 
+    42752,     0, 32768, 40960, 43008, 43009, 42752, 42754, 
+        0, 32768, 40960, 43008, 43009, 42752,     0, 32768, 
+    40960, 43008, 43009, 42752, 42756,     0, 32768, 40960, 
+    43008, 43009, 42752, 42756,     0, 32768, 40960, 43008, 
+    43009, 42752, 42760, 42758,     0, 32768, 40960, 43008, 
+    43009, 42752,     0, 32768, 40960, 43008, 43009, 42752, 
+    42760,     0, 32768, 40960, 43008, 43009, 42752, 42760, 
+        0, 32768, 40960, 43008, 43009, 42752, 42760, 42762, 
+        0, 32768, 40960, 43008, 43009, 42752, 42760,     0, 
+    32768, 40960, 43008, 43009, 42752, 42768, 42764,     0, 
+    32768, 40960, 43008, 43009, 42752, 42768, 42764,     0, 
+    32768, 40960, 43008, 43009, 42752, 42768, 42769, 42766, 
+        0, 32768, 40960, 43008, 43009, 42752,     0, 32768, 
+    40960, 43008, 43009, 42752, 42768,     0, 32768, 40960, 
+    43008, 43009, 42752, 42768,     0, 32768, 40960, 43008, 
+    43009, 42752, 42768, 42770,     0, 32768, 40960, 43008, 
+    43009, 42752, 42768,     0, 32768, 40960, 43008, 43009, 
+    42752, 42768, 42772,     0, 32768, 40960, 43008, 43009, 
+    42752, 42768, 42772,     0, 32768, 40960, 43008, 43009, 
+    42752, 42768, 42776, 42774,     0, 32768, 40960, 43008, 
+    43009, 42752, 42768,     0, 32768, 40960, 43008, 43009, 
+    42752, 42784, 42776,     0, 32768, 40960, 43008, 43009, 
+    42752, 42784, 42776,     0, 32768, 40960, 43008, 43009, 
+    42752, 42784, 42776, 42778,     0, 32768, 40960, 43008, 
+    43009, 42752, 42784, 42776,     0, 32768, 40960, 43008, 
+    43009, 42752, 42784, 42785, 42780,     0, 32768, 40960, 
+    43008, 43009, 42752, 42784, 42785, 42780,     0, 32768, 
+    40960, 43008, 43009, 42752, 42784, 42785, 42780, 42782, 
+        0, 32768, 40960, 43008, 43009, 42752,     0, 32768, 
+    40960, 43008, 43009, 42752, 42784,     0, 32768, 40960, 
+    43008, 43009, 42752, 42784,     0, 32768, 40960, 43008, 
+    43009, 42752, 42784, 42786,     0, 32768, 40960, 43008, 
+    43009, 42752, 42784,     0, 32768, 40960, 43008, 43009, 
+    42752, 42784, 42788,     0, 32768, 40960, 43008, 43009, 
+    42752, 42784, 42788,     0, 32768, 40960, 43008, 43009, 
+    42752, 42784, 42792, 42790,     0, 32768, 40960, 43008, 
+    43009, 42752, 42784,     0, 32768, 40960, 43008, 43009, 
+    42752, 42784, 42792,     0, 32768, 40960, 43008, 43009, 
+    42752, 42784, 42792,     0, 32768, 40960, 43008, 43009, 
+    42752, 42784, 42792, 42794,     0, 32768, 40960, 43008, 
+    43009, 42752, 42784, 42792,     0, 32768, 40960, 43008, 
+    43009, 42752, 42784, 42800, 42796,     0, 32768, 40960, 
+    43008, 43009, 42752, 42784, 42800, 42796,     0, 32768, 
+    40960, 43008, 43009, 42752, 42784, 42800, 42801, 42798, 
+        0, 32768, 40960, 43008, 43009, 42752, 42784,     0, 
+    32768, 40960, 43008, 43009, 42752, 42816, 42800,     0, 
+    32768, 40960, 43008, 43009, 42752, 42816, 42800,     0, 
+    32768, 40960, 43008, 43009, 42752, 42816, 42800, 42802, 
+        0, 32768, 40960, 43008, 43009, 42752, 42816, 42800, 
+        0, 32768, 40960, 43008, 43009, 42752, 42816, 42800, 
+    42804,     0, 32768, 40960, 43008, 43009, 42752, 42816, 
+    42800, 42804,     0, 32768, 40960, 43008, 43009, 42752, 
+    42816, 42800, 42808, 42806,     0, 32768, 40960, 43008, 
+    43009, 42752, 42816, 42800,     0, 32768, 40960, 43008, 
+    43009, 42752, 42816, 42817, 42808,     0, 32768, 40960, 
+    43008, 43009, 42752, 42816, 42817, 42808,     0, 32768, 
+    40960, 43008, 43009, 42752, 42816, 42817, 42808, 42810, 
+        0, 32768, 40960, 43008, 43009, 42752, 42816, 42817, 
+    42808,     0, 32768, 40960, 43008, 43009, 42752, 42816, 
+    42817, 42808, 42812,     0, 32768, 40960, 43008, 43009, 
+    42752, 42816, 42817, 42819, 42812,     0, 32768, 40960, 
+    43008, 43009, 42752, 42816, 42817, 42819, 42812, 42814, 
+        0, 32768, 40960, 43008, 43009, 42752,     0, 32768, 
+    40960, 43008, 43009, 42752, 42816,     0, 32768, 40960, 
+    43008, 43009, 42752, 42816,     0, 32768, 40960, 43008, 
+    43009, 42752, 42816, 42818,     0, 32768, 40960, 43008, 
+    43009, 42752, 42816,     0, 32768, 40960, 43008, 43009, 
+    42752, 42816, 42820,     0, 32768, 40960, 43008, 43009, 
+    42752, 42816, 42820,     0, 32768, 40960, 43008, 43009, 
+    42752, 42816, 42824, 42822,     0, 32768, 40960, 43008, 
+    43009, 42752, 42816,     0, 32768, 40960, 43008, 43009, 
+    42752, 42816, 42824,     0, 32768, 40960, 43008, 43009, 
+    42752, 42816, 42824,     0, 32768, 40960, 43008, 43009, 
+    42752, 42816, 42824, 42826,     0, 32768, 40960, 43008, 
+    43009, 42752, 42816, 42824,     0, 32768, 40960, 43008, 
+    43009, 42752, 42816, 42832, 42828,     0, 32768, 40960, 
+    43008, 43009, 42752, 42816, 42832, 42828,     0, 32768, 
+    40960, 43008, 43009, 42752, 42816, 42832, 42833, 42830, 
+        0, 32768, 40960, 43008, 43009, 42752, 42816,     0, 
+    32768, 40960, 43008, 43009, 42752, 42816, 42832,     0, 
+    32768, 40960, 43008, 43009, 42752, 42816, 42832,     0, 
+    32768, 40960, 43008, 43009, 42752, 42816, 42832, 42834, 
+        0, 32768, 40960, 43008, 43009, 42752, 42816, 42832, 
+        0, 32768, 40960, 43008, 43009, 42752, 42816, 42832, 
+    42836,     0, 32768, 40960, 43008, 43009, 42752, 42816, 
+    42832, 42836,     0, 32768, 40960, 43008, 43009, 42752, 
+    42816, 42832, 42840, 42838,     0, 32768, 40960, 43008, 
+    43009, 42752, 42816, 42832,     0, 32768, 40960, 43008, 
+    43009, 42752, 42816, 42848, 42840,     0, 32768, 40960, 
+    43008, 43009, 42752, 42816, 42848, 42840,     0, 32768, 
+    40960, 43008, 43009, 42752, 42816, 42848, 42840, 42842, 
+        0, 32768, 40960, 43008, 43009, 42752, 42816, 42848, 
+    42840,     0, 32768, 40960, 43008, 43009, 42752, 42816, 
+    42848, 42849, 42844,     0, 32768, 40960, 43008, 43009, 
+    42752, 42816, 42848, 42849, 42844,     0, 32768, 40960, 
+    43008, 43009, 42752, 42816, 42848, 42849, 42844, 42846, 
+        0, 32768, 40960, 43008, 43009, 42752, 42816,     0, 
+    32768, 40960, 43008, 43009, 42752, 42880, 42848,     0, 
+    32768, 40960, 43008, 43009, 42752, 42880, 42848,     0, 
+    32768, 40960, 43008, 43009, 42752, 42880, 42848, 42850, 
+        0, 32768, 40960, 43008, 43009, 42752, 42880, 42848, 
+        0, 32768, 40960, 43008, 43009, 42752, 42880, 42848, 
+    42852,     0, 32768, 40960, 43008, 43009, 42752, 42880, 
+    42848, 42852,     0, 32768, 40960, 43008, 43009, 42752, 
+    42880, 42848, 42856, 42854,     0, 32768, 40960, 43008, 
+    43009, 42752, 42880, 42848,     0, 32768, 40960, 43008, 
+    43009, 42752, 42880, 42848, 42856,     0, 32768, 40960, 
+    43008, 43009, 42752, 42880, 42848, 42856,     0, 32768, 
+    40960, 43008, 43009, 42752, 42880, 42848, 42856, 42858, 
+        0, 32768, 40960, 43008, 43009, 42752, 42880, 42848, 
+    42856,     0, 32768, 40960, 43008, 43009, 42752, 42880, 
+    42848, 42864, 42860,     0, 32768, 40960, 43008, 43009, 
+    42752, 42880, 42848, 42864, 42860,     0, 32768, 40960, 
+    43008, 43009, 42752, 42880, 42848, 42864, 42865, 42862, 
+        0, 32768, 40960, 43008, 43009, 42752, 42880, 42848, 
+        0, 32768, 40960, 43008, 43009, 42752, 42880, 42881, 
+    42864,     0, 32768, 40960, 43008, 43009, 42752, 42880, 
+    42881, 42864,     0, 32768, 40960, 43008, 43009, 42752, 
+    42880, 42881, 42864, 42866,     0, 32768, 40960, 43008, 
+    43009, 42752, 42880, 42881, 42864,     0, 32768, 40960, 
+    43008, 43009, 42752, 42880, 42881, 42864, 42868,     0, 
+    32768, 40960, 43008, 43009, 42752, 42880, 42881, 42864, 
+    42868,     0, 32768, 40960, 43008, 43009, 42752, 42880, 
+    42881, 42864, 42872, 42870,     0, 32768, 40960, 43008, 
+    43009, 42752, 42880, 42881, 42864,     0, 32768, 40960, 
+    43008, 43009, 42752, 42880, 42881, 42864, 42872,     0, 
+    32768, 40960, 43008, 43009, 42752, 42880, 42881, 42883, 
+    42872,     0, 32768, 40960, 43008, 43009, 42752, 42880, 
+    42881, 42883, 42872, 42874,     0, 32768, 40960, 43008, 
+    43009, 42752, 42880, 42881, 42883, 42872,     0, 32768, 
+    40960, 43008, 43009, 42752, 42880, 42881, 42883, 42872, 
+    42876,     0, 32768, 40960, 43008, 43009, 42752, 42880, 
+    42881, 42883, 42872, 42876,     0, 32768, 40960, 43008, 
+    43009, 42752, 42880, 42881, 42883, 42872, 42876, 42878, 
+        0, 32768, 40960, 43008, 43009, 42752,     0, 32768, 
+    40960, 43008, 43009, 42752, 42880,     0, 32768, 40960, 
+    43008, 43009, 42752, 42880,     0, 32768, 40960, 43008, 
+    43009, 42752, 42880, 42882,     0, 32768, 40960, 43008, 
+    43009, 43011, 42880,     0, 32768, 40960, 43008, 43009, 
+    43011, 42880, 42884,     0, 32768, 40960, 43008, 43009, 
+    43011, 42880, 42884,     0, 32768, 40960, 43008, 43009, 
+    43011, 42880, 42888, 42886,     0, 32768, 40960, 43008, 
+    43009, 43011, 42880,     0, 32768, 40960, 43008, 43009, 
+    43011, 42880, 42888,     0, 32768, 40960, 43008, 43009, 
+    43011, 42880, 42888,     0, 32768, 40960, 43008, 43009, 
+    43011, 42880, 42888, 42890,     0, 32768, 40960, 43008, 
+    43009, 43011, 42880, 42888,     0, 32768, 40960, 43008, 
+    43009, 43011, 42880, 42896, 42892,     0, 32768, 40960, 
+    43008, 43009, 43011, 42880, 42896, 42892,     0, 32768, 
+    40960, 43008, 43009, 43011, 42880, 42896, 42897, 42894, 
+        0, 32768, 40960, 43008, 43009, 43011, 42880,     0, 
+    32768, 40960, 43008, 43009, 43011, 42880, 42896,     0, 
+    32768, 40960, 43008, 43009, 43011, 42880, 42896,     0, 
+    32768, 40960, 43008, 43009, 43011, 42880, 42896, 42898, 
+        0, 32768, 40960, 43008, 43009, 43011, 42880, 42896, 
+        0, 32768, 40960, 43008, 43009, 43011, 42880, 42896, 
+    42900,     0, 32768, 40960, 43008, 43009, 43011, 42880, 
+    42896, 42900,     0, 32768, 40960, 43008, 43009, 43011, 
+    42880, 42896, 42904, 42902,     0, 32768, 40960, 43008, 
+    43009, 43011, 42880, 42896,     0, 32768, 40960, 43008, 
+    43009, 43011, 42880, 42912, 42904,     0, 32768, 40960, 
+    43008, 43009, 43011, 42880, 42912, 42904,     0, 32768, 
+    40960, 43008, 43009, 43011, 42880, 42912, 42904, 42906, 
+        0, 32768, 40960, 43008, 43009, 43011, 42880, 42912, 
+    42904,     0, 32768, 40960, 43008, 43009, 43011, 42880, 
+    42912, 42913, 42908,     0, 32768, 40960, 43008, 43009, 
+    43011, 42880, 42912, 42913, 42908,     0, 32768, 40960, 
+    43008, 43009, 43011, 42880, 42912, 42913, 42908, 42910, 
+        0, 32768, 40960, 43008, 43009, 43011, 42880,     0, 
+    32768, 40960, 43008, 43009, 43011, 42880, 42912,     0, 
+    32768, 40960, 43008, 43009, 43011, 42880, 42912,     0, 
+    32768, 40960, 43008, 43009, 43011, 42880, 42912, 42914, 
+        0, 32768, 40960, 43008, 43009, 43011, 42880, 42912, 
+        0, 32768, 40960, 43008, 43009, 43011, 42880, 42912, 
+    42916,     0, 32768, 40960, 43008, 43009, 43011, 42880, 
+    42912, 42916,     0, 32768, 40960, 43008, 43009, 43011, 
+    42880, 42912, 42920, 42918,     0, 32768, 40960, 43008, 
+    43009, 43011, 42880, 42912,     0, 32768, 40960, 43008, 
+    43009, 43011, 42880, 42912, 42920,     0, 32768, 40960, 
+    43008, 43009, 43011, 42880, 42912, 42920,     0, 32768, 
+    40960, 43008, 43009, 43011, 42880, 42912, 42920, 42922, 
+        0, 32768, 40960, 43008, 43009, 43011, 42880, 42912, 
+    42920,     0, 32768, 40960, 43008, 43009, 43011, 42880, 
+    42912, 42928, 42924,     0, 32768, 40960, 43008, 43009, 
+    43011, 42880, 42912, 42928, 42924,     0, 32768, 40960, 
+    43008, 43009, 43011, 42880, 42912, 42928, 42929, 42926, 
+        0, 32768, 40960, 43008, 43009, 43011, 42880, 42912, 
+        0, 32768, 40960, 43008, 43009, 43011, 42880, 42944, 
+    42928,     0, 32768, 40960, 43008, 43009, 43011, 42880, 
+    42944, 42928,     0, 32768, 40960, 43008, 43009, 43011, 
+    42880, 42944, 42928, 42930,     0, 32768, 40960, 43008, 
+    43009, 43011, 42880, 42944, 42928,     0, 32768, 40960, 
+    43008, 43009, 43011, 42880, 42944, 42928, 42932,     0, 
+    32768, 40960, 43008, 43009, 43011, 42880, 42944, 42928, 
+    42932,     0, 32768, 40960, 43008, 43009, 43011, 42880, 
+    42944, 42928, 42936, 42934,     0, 32768, 40960, 43008, 
+    43009, 43011, 42880, 42944, 42928,     0, 32768, 40960, 
+    43008, 43009, 43011, 42880, 42944, 42945, 42936,     0, 
+    32768, 40960, 43008, 43009, 43011, 42880, 42944, 42945, 
+    42936,     0, 32768, 40960, 43008, 43009, 43011, 42880, 
+    42944, 42945, 42936, 42938,     0, 32768, 40960, 43008, 
+    43009, 43011, 42880, 42944, 42945, 42936,     0, 32768, 
+    40960, 43008, 43009, 43011, 42880, 42944, 42945, 42936, 
+    42940,     0, 32768, 40960, 43008, 43009, 43011, 42880, 
+    42944, 42945, 42947, 42940,     0, 32768, 40960, 43008, 
+    43009, 43011, 42880, 42944, 42945, 42947, 42940, 42942, 
+        0, 32768, 40960, 43008, 43009, 43011, 42880,     0, 
+    32768, 40960, 43008, 43009, 43011, 42880, 42944,     0, 
+    32768, 40960, 43008, 43009, 43011, 42880, 42944,     0, 
+    32768, 40960, 43008, 43009, 43011, 42880, 42944, 42946, 
+        0, 32768, 40960, 43008, 43009, 43011, 42880, 42944, 
+        0, 32768, 40960, 43008, 43009, 43011, 42880, 42944, 
+    42948,     0, 32768, 40960, 43008, 43009, 43011, 42880, 
+    42944, 42948,     0, 32768, 40960, 43008, 43009, 43011, 
+    42880, 42944, 42952, 42950,     0, 32768, 40960, 43008, 
+    43009, 43011, 43015, 42944,     0, 32768, 40960, 43008, 
+    43009, 43011, 43015, 42944, 42952,     0, 32768, 40960, 
+    43008, 43009, 43011, 43015, 42944, 42952,     0, 32768, 
+    40960, 43008, 43009, 43011, 43015, 42944, 42952, 42954, 
+        0, 32768, 40960, 43008, 43009, 43011, 43015, 42944, 
+    42952,     0, 32768, 40960, 43008, 43009, 43011, 43015, 
+    42944, 42960, 42956,     0, 32768, 40960, 43008, 43009, 
+    43011, 43015, 42944, 42960, 42956,     0, 32768, 40960, 
+    43008, 43009, 43011, 43015, 42944, 42960, 42961, 42958, 
+        0, 32768, 40960, 43008, 43009, 43011, 43015, 42944, 
+        0, 32768, 40960, 43008, 43009, 43011, 43015, 42944, 
+    42960,     0, 32768, 40960, 43008, 43009, 43011, 43015, 
+    42944, 42960,     0, 32768, 40960, 43008, 43009, 43011, 
+    43015, 42944, 42960, 42962,     0, 32768, 40960, 43008, 
+    43009, 43011, 43015, 42944, 42960,     0, 32768, 40960, 
+    43008, 43009, 43011, 43015, 42944, 42960, 42964,     0, 
+    32768, 40960, 43008, 43009, 43011, 43015, 42944, 42960, 
+    42964,     0, 32768, 40960, 43008, 43009, 43011, 43015, 
+    42944, 42960, 42968, 42966,     0, 32768, 40960, 43008, 
+    43009, 43011, 43015, 42944, 42960,     0, 32768, 40960, 
+    43008, 43009, 43011, 43015, 42944, 42976, 42968,     0, 
+    32768, 40960, 43008, 43009, 43011, 43015, 42944, 42976, 
+    42968,     0, 32768, 40960, 43008, 43009, 43011, 43015, 
+    42944, 42976, 42968, 42970,     0, 32768, 40960, 43008, 
+    43009, 43011, 43015, 42944, 42976, 42968,     0, 32768, 
+    40960, 43008, 43009, 43011, 43015, 42944, 42976, 42977, 
+    42972,     0, 32768, 40960, 43008, 43009, 43011, 43015, 
+    42944, 42976, 42977, 42972,     0, 32768, 40960, 43008, 
+    43009, 43011, 43015, 42944, 42976, 42977, 42972, 42974, 
+        0, 32768, 40960, 43008, 43009, 43011, 43015, 42944, 
+        0, 32768, 40960, 43008, 43009, 43011, 43015, 42944, 
+    42976,     0, 32768, 40960, 43008, 43009, 43011, 43015, 
+    42944, 42976,     0, 32768, 40960, 43008, 43009, 43011, 
+    43015, 42944, 42976, 42978,     0, 32768, 40960, 43008, 
+    43009, 43011, 43015, 42944, 42976,     0, 32768, 40960, 
+    43008, 43009, 43011, 43015, 42944, 42976, 42980,     0, 
+    32768, 40960, 43008, 43009, 43011, 43015, 42944, 42976, 
+    42980,     0, 32768, 40960, 43008, 43009, 43011, 43015, 
+    42944, 42976, 42984, 42982,     0, 32768, 40960, 43008, 
+    43009, 43011, 43015, 42944, 42976,     0, 32768, 40960, 
+    43008, 43009, 43011, 43015, 42944, 42976, 42984,     0, 
+    32768, 40960, 43008, 43009, 43011, 43015, 42944, 42976, 
+    42984,     0, 32768, 40960, 43008, 43009, 43011, 43015, 
+    42944, 42976, 42984, 42986,     0, 32768, 40960, 43008, 
+    43009, 43011, 43015, 42944, 42976, 42984,     0, 32768, 
+    40960, 43008, 43009, 43011, 43015, 42944, 42976, 42992, 
+    42988,     0, 32768, 40960, 43008, 43009, 43011, 43015, 
+    42944, 42976, 42992, 42988,     0, 32768, 40960, 43008, 
+    43009, 43011, 43015, 42944, 42976, 42992, 42993, 42990, 
+        0, 32768, 40960, 43008, 43009, 43011, 43015, 43023, 
+    42976,     0, 32768, 40960, 43008, 43009, 43011, 43015, 
+    43023, 42976, 42992,     0, 32768, 40960, 43008, 43009, 
+    43011, 43015, 43023, 42976, 42992,     0, 32768, 40960, 
+    43008, 43009, 43011, 43015, 43023, 42976, 42992, 42994, 
+        0, 32768, 40960, 43008, 43009, 43011, 43015, 43023, 
+    42976, 42992,     0, 32768, 40960, 43008, 43009, 43011, 
+    43015, 43023, 42976, 42992, 42996,     0, 32768, 40960, 
+    43008, 43009, 43011, 43015, 43023, 42976, 42992, 42996, 
+        0, 32768, 40960, 43008, 43009, 43011, 43015, 43023, 
+    42976, 42992, 43000, 42998,     0, 32768, 40960, 43008, 
+    43009, 43011, 43015, 43023, 42976, 42992,     0, 32768, 
+    40960, 43008, 43009, 43011, 43015, 43023, 42976, 42992, 
+    43000,     0, 32768, 40960, 43008, 43009, 43011, 43015, 
+    43023, 42976, 42992, 43000,     0, 32768, 40960, 43008, 
+    43009, 43011, 43015, 43023, 42976, 42992, 43000, 43002, 
+        0, 32768, 40960, 43008, 43009, 43011, 43015, 43023, 
+    42976, 42992, 43000,     0, 32768, 40960, 43008, 43009, 
+    43011, 43015, 43023, 42976, 42992, 43000, 43004,     0, 
+    32768, 40960, 43008, 43009, 43011, 43015, 43023, 42976, 
+    42992, 43000, 43004,     0, 32768, 40960, 43008, 43009, 
+    43011, 43015, 43023, 42976, 42992, 43000, 43004, 43006, 
+        0, 32768, 40960,     0, 32768, 40960, 43008,     0, 
+    32768, 40960, 43008,     0, 32768, 40960, 43008, 43010, 
+        0, 32768, 40960, 43008,     0, 32768, 40960, 43008, 
+    43012,     0, 32768, 40960, 43008, 43012,     0, 32768, 
+    40960, 43008, 43016, 43014,     0, 32768, 40960, 43008, 
+        0, 32768, 40960, 43008, 43016,     0, 32768, 40960, 
+    43008, 43016,     0, 32768, 40960, 43008, 43016, 43018, 
+        0, 32768, 40960, 43008, 43016,     0, 32768, 40960, 
+    43008, 43024, 43020,     0, 32768, 40960, 43008, 43024, 
+    43020,     0, 32768, 40960, 43008, 43024, 43025, 43022, 
+        0, 32768, 40960, 43008,     0, 32768, 40960, 43008, 
+    43024,     0, 32768, 40960, 43008, 43024,     0, 32768, 
+    40960, 43008, 43024, 43026,     0, 32768, 40960, 43008, 
+    43024,     0, 32768, 40960, 43008, 43024, 43028,     0, 
+    32768, 40960, 43008, 43024, 43028,     0, 32768, 40960, 
+    43008, 43024, 43032, 43030,     0, 32768, 40960, 43008, 
+    43024,     0, 32768, 40960, 43008, 43040, 43032,     0, 
+    32768, 40960, 43008, 43040, 43032,     0, 32768, 40960, 
+    43008, 43040, 43032, 43034,     0, 32768, 40960, 43008, 
+    43040, 43032,     0, 32768, 40960, 43008, 43040, 43041, 
+    43036,     0, 32768, 40960, 43008, 43040, 43041, 43036, 
+        0, 32768, 40960, 43008, 43040, 43041, 43036, 43038, 
+        0, 32768, 40960, 43008,     0, 32768, 40960, 43008, 
+    43040,     0, 32768, 40960, 43008, 43040,     0, 32768, 
+    40960, 43008, 43040, 43042,     0, 32768, 40960, 43008, 
+    43040,     0, 32768, 40960, 43008, 43040, 43044,     0, 
+    32768, 40960, 43008, 43040, 43044,     0, 32768, 40960, 
+    43008, 43040, 43048, 43046,     0, 32768, 40960, 43008, 
+    43040,     0, 32768, 40960, 43008, 43040, 43048,     0, 
+    32768, 40960, 43008, 43040, 43048,     0, 32768, 40960, 
+    43008, 43040, 43048, 43050,     0, 32768, 40960, 43008, 
+    43040, 43048,     0, 32768, 40960, 43008, 43040, 43056, 
+    43052,     0, 32768, 40960, 43008, 43040, 43056, 43052, 
+        0, 32768, 40960, 43008, 43040, 43056, 43057, 43054, 
+        0, 32768, 40960, 43008, 43040,     0, 32768, 40960, 
+    43008, 43072, 43056,     0, 32768, 40960, 43008, 43072, 
+    43056,     0, 32768, 40960, 43008, 43072, 43056, 43058, 
+        0, 32768, 40960, 43008, 43072, 43056,     0, 32768, 
+    40960, 43008, 43072, 43056, 43060,     0, 32768, 40960, 
+    43008, 43072, 43056, 43060,     0, 32768, 40960, 43008, 
+    43072, 43056, 43064, 43062,     0, 32768, 40960, 43008, 
+    43072, 43056,     0, 32768, 40960, 43008, 43072, 43073, 
+    43064,     0, 32768, 40960, 43008, 43072, 43073, 43064, 
+        0, 32768, 40960, 43008, 43072, 43073, 43064, 43066, 
+        0, 32768, 40960, 43008, 43072, 43073, 43064,     0, 
+    32768, 40960, 43008, 43072, 43073, 43064, 43068,     0, 
+    32768, 40960, 43008, 43072, 43073, 43075, 43068,     0, 
+    32768, 40960, 43008, 43072, 43073, 43075, 43068, 43070, 
+        0, 32768, 40960, 43008,     0, 32768, 40960, 43008, 
+    43072,     0, 32768, 40960, 43008, 43072,     0, 32768, 
+    40960, 43008, 43072, 43074,     0, 32768, 40960, 43008, 
+    43072,     0, 32768, 40960, 43008, 43072, 43076,     0, 
+    32768, 40960, 43008, 43072, 43076,     0, 32768, 40960, 
+    43008, 43072, 43080, 43078,     0, 32768, 40960, 43008, 
+    43072,     0, 32768, 40960, 43008, 43072, 43080,     0, 
+    32768, 40960, 43008, 43072, 43080,     0, 32768, 40960, 
+    43008, 43072, 43080, 43082,     0, 32768, 40960, 43008, 
+    43072, 43080,     0, 32768, 40960, 43008, 43072, 43088, 
+    43084,     0, 32768, 40960, 43008, 43072, 43088, 43084, 
+        0, 32768, 40960, 43008, 43072, 43088, 43089, 43086, 
+        0, 32768, 40960, 43008, 43072,     0, 32768, 40960, 
+    43008, 43072, 43088,     0, 32768, 40960, 43008, 43072, 
+    43088,     0, 32768, 40960, 43008, 43072, 43088, 43090, 
+        0, 32768, 40960, 43008, 43072, 43088,     0, 32768, 
+    40960, 43008, 43072, 43088, 43092,     0, 32768, 40960, 
+    43008, 43072, 43088, 43092,     0, 32768, 40960, 43008, 
+    43072, 43088, 43096, 43094,     0, 32768, 40960, 43008, 
+    43072, 43088,     0, 32768, 40960, 43008, 43072, 43104, 
+    43096,     0, 32768, 40960, 43008, 43072, 43104, 43096, 
+        0, 32768, 40960, 43008, 43072, 43104, 43096, 43098, 
+        0, 32768, 40960, 43008, 43072, 43104, 43096,     0, 
+    32768, 40960, 43008, 43072, 43104, 43105, 43100,     0, 
+    32768, 40960, 43008, 43072, 43104, 43105, 43100,     0, 
+    32768, 40960, 43008, 43072, 43104, 43105, 43100, 43102, 
+        0, 32768, 40960, 43008, 43072,     0, 32768, 40960, 
+    43008, 43136, 43104,     0, 32768, 40960, 43008, 43136, 
+    43104,     0, 32768, 40960, 43008, 43136, 43104, 43106, 
+        0, 32768, 40960, 43008, 43136, 43104,     0, 32768, 
+    40960, 43008, 43136, 43104, 43108,     0, 32768, 40960, 
+    43008, 43136, 43104, 43108,     0, 32768, 40960, 43008, 
+    43136, 43104, 43112, 43110,     0, 32768, 40960, 43008, 
+    43136, 43104,     0, 32768, 40960, 43008, 43136, 43104, 
+    43112,     0, 32768, 40960, 43008, 43136, 43104, 43112, 
+        0, 32768, 40960, 43008, 43136, 43104, 43112, 43114, 
+        0, 32768, 40960, 43008, 43136, 43104, 43112,     0, 
+    32768, 40960, 43008, 43136, 43104, 43120, 43116,     0, 
+    32768, 40960, 43008, 43136, 43104, 43120, 43116,     0, 
+    32768, 40960, 43008, 43136, 43104, 43120, 43121, 43118, 
+        0, 32768, 40960, 43008, 43136, 43104,     0, 32768, 
+    40960, 43008, 43136, 43137, 43120,     0, 32768, 40960, 
+    43008, 43136, 43137, 43120,     0, 32768, 40960, 43008, 
+    43136, 43137, 43120, 43122,     0, 32768, 40960, 43008, 
+    43136, 43137, 43120,     0, 32768, 40960, 43008, 43136, 
+    43137, 43120, 43124,     0, 32768, 40960, 43008, 43136, 
+    43137, 43120, 43124,     0, 32768, 40960, 43008, 43136, 
+    43137, 43120, 43128, 43126,     0, 32768, 40960, 43008, 
+    43136, 43137, 43120,     0, 32768, 40960, 43008, 43136, 
+    43137, 43120, 43128,     0, 32768, 40960, 43008, 43136, 
+    43137, 43139, 43128,     0, 32768, 40960, 43008, 43136, 
+    43137, 43139, 43128, 43130,     0, 32768, 40960, 43008, 
+    43136, 43137, 43139, 43128,     0, 32768, 40960, 43008, 
+    43136, 43137, 43139, 43128, 43132,     0, 32768, 40960, 
+    43008, 43136, 43137, 43139, 43128, 43132,     0, 32768, 
+    40960, 43008, 43136, 43137, 43139, 43128, 43132, 43134, 
+        0, 32768, 40960, 43008,     0, 32768, 40960, 43008, 
+    43136,     0, 32768, 40960, 43008, 43136,     0, 32768, 
+    40960, 43008, 43136, 43138,     0, 32768, 40960, 43008, 
+    43136,     0, 32768, 40960, 43008, 43136, 43140,     0, 
+    32768, 40960, 43008, 43136, 43140,     0, 32768, 40960, 
+    43008, 43136, 43144, 43142,     0, 32768, 40960, 43008, 
+    43136,     0, 32768, 40960, 43008, 43136, 43144,     0, 
+    32768, 40960, 43008, 43136, 43144,     0, 32768, 40960, 
+    43008, 43136, 43144, 43146,     0, 32768, 40960, 43008, 
+    43136, 43144,     0, 32768, 40960, 43008, 43136, 43152, 
+    43148,     0, 32768, 40960, 43008, 43136, 43152, 43148, 
+        0, 32768, 40960, 43008, 43136, 43152, 43153, 43150, 
+        0, 32768, 40960, 43008, 43136,     0, 32768, 40960, 
+    43008, 43136, 43152,     0, 32768, 40960, 43008, 43136, 
+    43152,     0, 32768, 40960, 43008, 43136, 43152, 43154, 
+        0, 32768, 40960, 43008, 43136, 43152,     0, 32768, 
+    40960, 43008, 43136, 43152, 43156,     0, 32768, 40960, 
+    43008, 43136, 43152, 43156,     0, 32768, 40960, 43008, 
+    43136, 43152, 43160, 43158,     0, 32768, 40960, 43008, 
+    43136, 43152,     0, 32768, 40960, 43008, 43136, 43168, 
+    43160,     0, 32768, 40960, 43008, 43136, 43168, 43160, 
+        0, 32768, 40960, 43008, 43136, 43168, 43160, 43162, 
+        0, 32768, 40960, 43008, 43136, 43168, 43160,     0, 
+    32768, 40960, 43008, 43136, 43168, 43169, 43164,     0, 
+    32768, 40960, 43008, 43136, 43168, 43169, 43164,     0, 
+    32768, 40960, 43008, 43136, 43168, 43169, 43164, 43166, 
+        0, 32768, 40960, 43008, 43136,     0, 32768, 40960, 
+    43008, 43136, 43168,     0, 32768, 40960, 43008, 43136, 
+    43168,     0, 32768, 40960, 43008, 43136, 43168, 43170, 
+        0, 32768, 40960, 43008, 43136, 43168,     0, 32768, 
+    40960, 43008, 43136, 43168, 43172,     0, 32768, 40960, 
+    43008, 43136, 43168, 43172,     0, 32768, 40960, 43008, 
+    43136, 43168, 43176, 43174,     0, 32768, 40960, 43008, 
+    43136, 43168,     0, 32768, 40960, 43008, 43136, 43168, 
+    43176,     0, 32768, 40960, 43008, 43136, 43168, 43176, 
+        0, 32768, 40960, 43008, 43136, 43168, 43176, 43178, 
+        0, 32768, 40960, 43008, 43136, 43168, 43176,     0, 
+    32768, 40960, 43008, 43136, 43168, 43184, 43180,     0, 
+    32768, 40960, 43008, 43136, 43168, 43184, 43180,     0, 
+    32768, 40960, 43008, 43136, 43168, 43184, 43185, 43182, 
+        0, 32768, 40960, 43008, 43136, 43168,     0, 32768, 
+    40960, 43008, 43136, 43200, 43184,     0, 32768, 40960, 
+    43008, 43136, 43200, 43184,     0, 32768, 40960, 43008, 
+    43136, 43200, 43184, 43186,     0, 32768, 40960, 43008, 
+    43136, 43200, 43184,     0, 32768, 40960, 43008, 43136, 
+    43200, 43184, 43188,     0, 32768, 40960, 43008, 43136, 
+    43200, 43184, 43188,     0, 32768, 40960, 43008, 43136, 
+    43200, 43184, 43192, 43190,     0, 32768, 40960, 43008, 
+    43136, 43200, 43184,     0, 32768, 40960, 43008, 43136, 
+    43200, 43201, 43192,     0, 32768, 40960, 43008, 43136, 
+    43200, 43201, 43192,     0, 32768, 40960, 43008, 43136, 
+    43200, 43201, 43192, 43194,     0, 32768, 40960, 43008, 
+    43136, 43200, 43201, 43192,     0, 32768, 40960, 43008, 
+    43136, 43200, 43201, 43192, 43196,     0, 32768, 40960, 
+    43008, 43136, 43200, 43201, 43203, 43196,     0, 32768, 
+    40960, 43008, 43136, 43200, 43201, 43203, 43196, 43198, 
+        0, 32768, 40960, 43008, 43136,     0, 32768, 40960, 
+    43008, 43264, 43200,     0, 32768, 40960, 43008, 43264, 
+    43200,     0, 32768, 40960, 43008, 43264, 43200, 43202, 
+        0, 32768, 40960, 43008, 43264, 43200,     0, 32768, 
+    40960, 43008, 43264, 43200, 43204,     0, 32768, 40960, 
+    43008, 43264, 43200, 43204,     0, 32768, 40960, 43008, 
+    43264, 43200, 43208, 43206,     0, 32768, 40960, 43008, 
+    43264, 43200,     0, 32768, 40960, 43008, 43264, 43200, 
+    43208,     0, 32768, 40960, 43008, 43264, 43200, 43208, 
+        0, 32768, 40960, 43008, 43264, 43200, 43208, 43210, 
+        0, 32768, 40960, 43008, 43264, 43200, 43208,     0, 
+    32768, 40960, 43008, 43264, 43200, 43216, 43212,     0, 
+    32768, 40960, 43008, 43264, 43200, 43216, 43212,     0, 
+    32768, 40960, 43008, 43264, 43200, 43216, 43217, 43214, 
+        0, 32768, 40960, 43008, 43264, 43200,     0, 32768, 
+    40960, 43008, 43264, 43200, 43216,     0, 32768, 40960, 
+    43008, 43264, 43200, 43216,     0, 32768, 40960, 43008, 
+    43264, 43200, 43216, 43218,     0, 32768, 40960, 43008, 
+    43264, 43200, 43216,     0, 32768, 40960, 43008, 43264, 
+    43200, 43216, 43220,     0, 32768, 40960, 43008, 43264, 
+    43200, 43216, 43220,     0, 32768, 40960, 43008, 43264, 
+    43200, 43216, 43224, 43222,     0, 32768, 40960, 43008, 
+    43264, 43200, 43216,     0, 32768, 40960, 43008, 43264, 
+    43200, 43232, 43224,     0, 32768, 40960, 43008, 43264, 
+    43200, 43232, 43224,     0, 32768, 40960, 43008, 43264, 
+    43200, 43232, 43224, 43226,     0, 32768, 40960, 43008, 
+    43264, 43200, 43232, 43224,     0, 32768, 40960, 43008, 
+    43264, 43200, 43232, 43233, 43228,     0, 32768, 40960, 
+    43008, 43264, 43200, 43232, 43233, 43228,     0, 32768, 
+    40960, 43008, 43264, 43200, 43232, 43233, 43228, 43230, 
+        0, 32768, 40960, 43008, 43264, 43200,     0, 32768, 
+    40960, 43008, 43264, 43265, 43232,     0, 32768, 40960, 
+    43008, 43264, 43265, 43232,     0, 32768, 40960, 43008, 
+    43264, 43265, 43232, 43234,     0, 32768, 40960, 43008, 
+    43264, 43265, 43232,     0, 32768, 40960, 43008, 43264, 
+    43265, 43232, 43236,     0, 32768, 40960, 43008, 43264, 
+    43265, 43232, 43236,     0, 32768, 40960, 43008, 43264, 
+    43265, 43232, 43240, 43238,     0, 32768, 40960, 43008, 
+    43264, 43265, 43232,     0, 32768, 40960, 43008, 43264, 
+    43265, 43232, 43240,     0, 32768, 40960, 43008, 43264, 
+    43265, 43232, 43240,     0, 32768, 40960, 43008, 43264, 
+    43265, 43232, 43240, 43242,     0, 32768, 40960, 43008, 
+    43264, 43265, 43232, 43240,     0, 32768, 40960, 43008, 
+    43264, 43265, 43232, 43248, 43244,     0, 32768, 40960, 
+    43008, 43264, 43265, 43232, 43248, 43244,     0, 32768, 
+    40960, 43008, 43264, 43265, 43232, 43248, 43249, 43246, 
+        0, 32768, 40960, 43008, 43264, 43265, 43232,     0, 
+    32768, 40960, 43008, 43264, 43265, 43232, 43248,     0, 
+    32768, 40960, 43008, 43264, 43265, 43267, 43248,     0, 
+    32768, 40960, 43008, 43264, 43265, 43267, 43248, 43250, 
+        0, 32768, 40960, 43008, 43264, 43265, 43267, 43248, 
+        0, 32768, 40960, 43008, 43264, 43265, 43267, 43248, 
+    43252,     0, 32768, 40960, 43008, 43264, 43265, 43267, 
+    43248, 43252,     0, 32768, 40960, 43008, 43264, 43265, 
+    43267, 43248, 43256, 43254,     0, 32768, 40960, 43008, 
+    43264, 43265, 43267, 43248,     0, 32768, 40960, 43008, 
+    43264, 43265, 43267, 43248, 43256,     0, 32768, 40960, 
+    43008, 43264, 43265, 43267, 43248, 43256,     0, 32768, 
+    40960, 43008, 43264, 43265, 43267, 43248, 43256, 43258, 
+        0, 32768, 40960, 43008, 43264, 43265, 43267, 43271, 
+    43256,     0, 32768, 40960, 43008, 43264, 43265, 43267, 
+    43271, 43256, 43260,     0, 32768, 40960, 43008, 43264, 
+    43265, 43267, 43271, 43256, 43260,     0, 32768, 40960, 
+    43008, 43264, 43265, 43267, 43271, 43256, 43260, 43262, 
+        0, 32768, 40960, 43008,     0, 32768, 40960, 43008, 
+    43264,     0, 32768, 40960, 43008, 43264,     0, 32768, 
+    40960, 43008, 43264, 43266,     0, 32768, 40960, 43008, 
+    43264,     0, 32768, 40960, 43008, 43264, 43268,     0, 
+    32768, 40960, 43008, 43264, 43268,     0, 32768, 40960, 
+    43008, 43264, 43272, 43270,     0, 32768, 40960, 43008, 
+    43264,     0, 32768, 40960, 43008, 43264, 43272,     0, 
+    32768, 40960, 43008, 43264, 43272,     0, 32768, 40960, 
+    43008, 43264, 43272, 43274,     0, 32768, 40960, 43008, 
+    43264, 43272,     0, 32768, 40960, 43008, 43264, 43280, 
+    43276,     0, 32768, 40960, 43008, 43264, 43280, 43276, 
+        0, 32768, 40960, 43008, 43264, 43280, 43281, 43278, 
+        0, 32768, 40960, 43008, 43264,     0, 32768, 40960, 
+    43008, 43264, 43280,     0, 32768, 40960, 43008, 43264, 
+    43280,     0, 32768, 40960, 43008, 43264, 43280, 43282, 
+        0, 32768, 40960, 43008, 43264, 43280,     0, 32768, 
+    40960, 43008, 43264, 43280, 43284,     0, 32768, 40960, 
+    43008, 43264, 43280, 43284,     0, 32768, 40960, 43008, 
+    43264, 43280, 43288, 43286,     0, 32768, 40960, 43008, 
+    43264, 43280,     0, 32768, 40960, 43008, 43264, 43296, 
+    43288,     0, 32768, 40960, 43008, 43264, 43296, 43288, 
+        0, 32768, 40960, 43008, 43264, 43296, 43288, 43290, 
+        0, 32768, 40960, 43008, 43264, 43296, 43288,     0, 
+    32768, 40960, 43008, 43264, 43296, 43297, 43292,     0, 
+    32768, 40960, 43008, 43264, 43296, 43297, 43292,     0, 
+    32768, 40960, 43008, 43264, 43296, 43297, 43292, 43294, 
+        0, 32768, 40960, 43008, 43264,     0, 32768, 40960, 
+    43008, 43264, 43296,     0, 32768, 40960, 43008, 43264, 
+    43296,     0, 32768, 40960, 43008, 43264, 43296, 43298, 
+        0, 32768, 40960, 43008, 43264, 43296,     0, 32768, 
+    40960, 43008, 43264, 43296, 43300,     0, 32768, 40960, 
+    43008, 43264, 43296, 43300,     0, 32768, 40960, 43008, 
+    43264, 43296, 43304, 43302,     0, 32768, 40960, 43008, 
+    43264, 43296,     0, 32768, 40960, 43008, 43264, 43296, 
+    43304,     0, 32768, 40960, 43008, 43264, 43296, 43304, 
+        0, 32768, 40960, 43008, 43264, 43296, 43304, 43306, 
+        0, 32768, 40960, 43008, 43264, 43296, 43304,     0, 
+    32768, 40960, 43008, 43264, 43296, 43312, 43308,     0, 
+    32768, 40960, 43008, 43264, 43296, 43312, 43308,     0, 
+    32768, 40960, 43008, 43264, 43296, 43312, 43313, 43310, 
+        0, 32768, 40960, 43008, 43264, 43296,     0, 32768, 
+    40960, 43008, 43264, 43328, 43312,     0, 32768, 40960, 
+    43008, 43264, 43328, 43312,     0, 32768, 40960, 43008, 
+    43264, 43328, 43312, 43314,     0, 32768, 40960, 43008, 
+    43264, 43328, 43312,     0, 32768, 40960, 43008, 43264, 
+    43328, 43312, 43316,     0, 32768, 40960, 43008, 43264, 
+    43328, 43312, 43316,     0, 32768, 40960, 43008, 43264, 
+    43328, 43312, 43320, 43318,     0, 32768, 40960, 43008, 
+    43264, 43328, 43312,     0, 32768, 40960, 43008, 43264, 
+    43328, 43329, 43320,     0, 32768, 40960, 43008, 43264, 
+    43328, 43329, 43320,     0, 32768, 40960, 43008, 43264, 
+    43328, 43329, 43320, 43322,     0, 32768, 40960, 43008, 
+    43264, 43328, 43329, 43320,     0, 32768, 40960, 43008, 
+    43264, 43328, 43329, 43320, 43324,     0, 32768, 40960, 
+    43008, 43264, 43328, 43329, 43331, 43324,     0, 32768, 
+    40960, 43008, 43264, 43328, 43329, 43331, 43324, 43326, 
+        0, 32768, 40960, 43008, 43264,     0, 32768, 40960, 
+    43008, 43264, 43328,     0, 32768, 40960, 43008, 43264, 
+    43328,     0, 32768, 40960, 43008, 43264, 43328, 43330, 
+        0, 32768, 40960, 43008, 43264, 43328,     0, 32768, 
+    40960, 43008, 43264, 43328, 43332,     0, 32768, 40960, 
+    43008, 43264, 43328, 43332,     0, 32768, 40960, 43008, 
+    43264, 43328, 43336, 43334,     0, 32768, 40960, 43008, 
+    43264, 43328,     0, 32768, 40960, 43008, 43264, 43328, 
+    43336,     0, 32768, 40960, 43008, 43264, 43328, 43336, 
+        0, 32768, 40960, 43008, 43264, 43328, 43336, 43338, 
+        0, 32768, 40960, 43008, 43264, 43328, 43336,     0, 
+    32768, 40960, 43008, 43264, 43328, 43344, 43340,     0, 
+    32768, 40960, 43008, 43264, 43328, 43344, 43340,     0, 
+    32768, 40960, 43008, 43264, 43328, 43344, 43345, 43342, 
+        0, 32768, 40960, 43008, 43264, 43328,     0, 32768, 
+    40960, 43008, 43264, 43328, 43344,     0, 32768, 40960, 
+    43008, 43264, 43328, 43344,     0, 32768, 40960, 43008, 
+    43264, 43328, 43344, 43346,     0, 32768, 40960, 43008, 
+    43264, 43328, 43344,     0, 32768, 40960, 43008, 43264, 
+    43328, 43344, 43348,     0, 32768, 40960, 43008, 43264, 
+    43328, 43344, 43348,     0, 32768, 40960, 43008, 43264, 
+    43328, 43344, 43352, 43350,     0, 32768, 40960, 43008, 
+    43264, 43328, 43344,     0, 32768, 40960, 43008, 43264, 
+    43328, 43360, 43352,     0, 32768, 40960, 43008, 43264, 
+    43328, 43360, 43352,     0, 32768, 40960, 43008, 43264, 
+    43328, 43360, 43352, 43354,     0, 32768, 40960, 43008, 
+    43264, 43328, 43360, 43352,     0, 32768, 40960, 43008, 
+    43264, 43328, 43360, 43361, 43356,     0, 32768, 40960, 
+    43008, 43264, 43328, 43360, 43361, 43356,     0, 32768, 
+    40960, 43008, 43264, 43328, 43360, 43361, 43356, 43358, 
+        0, 32768, 40960, 43008, 43264, 43328,     0, 32768, 
+    40960, 43008, 43264, 43392, 43360,     0, 32768, 40960, 
+    43008, 43264, 43392, 43360,     0, 32768, 40960, 43008, 
+    43264, 43392, 43360, 43362,     0, 32768, 40960, 43008, 
+    43264, 43392, 43360,     0, 32768, 40960, 43008, 43264, 
+    43392, 43360, 43364,     0, 32768, 40960, 43008, 43264, 
+    43392, 43360, 43364,     0, 32768, 40960, 43008, 43264, 
+    43392, 43360, 43368, 43366,     0, 32768, 40960, 43008, 
+    43264, 43392, 43360,     0, 32768, 40960, 43008, 43264, 
+    43392, 43360, 43368,     0, 32768, 40960, 43008, 43264, 
+    43392, 43360, 43368,     0, 32768, 40960, 43008, 43264, 
+    43392, 43360, 43368, 43370,     0, 32768, 40960, 43008, 
+    43264, 43392, 43360, 43368,     0, 32768, 40960, 43008, 
+    43264, 43392, 43360, 43376, 43372,     0, 32768, 40960, 
+    43008, 43264, 43392, 43360, 43376, 43372,     0, 32768, 
+    40960, 43008, 43264, 43392, 43360, 43376, 43377, 43374, 
+        0, 32768, 40960, 43008, 43264, 43392, 43360,     0, 
+    32768, 40960, 43008, 43264, 43392, 43393, 43376,     0, 
+    32768, 40960, 43008, 43264, 43392, 43393, 43376,     0, 
+    32768, 40960, 43008, 43264, 43392, 43393, 43376, 43378, 
+        0, 32768, 40960, 43008, 43264, 43392, 43393, 43376, 
+        0, 32768, 40960, 43008, 43264, 43392, 43393, 43376, 
+    43380,     0, 32768, 40960, 43008, 43264, 43392, 43393, 
+    43376, 43380,     0, 32768, 40960, 43008, 43264, 43392, 
+    43393, 43376, 43384, 43382,     0, 32768, 40960, 43008, 
+    43264, 43392, 43393, 43376,     0, 32768, 40960, 43008, 
+    43264, 43392, 43393, 43376, 43384,     0, 32768, 40960, 
+    43008, 43264, 43392, 43393, 43395, 43384,     0, 32768, 
+    40960, 43008, 43264, 43392, 43393, 43395, 43384, 43386, 
+        0, 32768, 40960, 43008, 43264, 43392, 43393, 43395, 
+    43384,     0, 32768, 40960, 43008, 43264, 43392, 43393, 
+    43395, 43384, 43388,     0, 32768, 40960, 43008, 43264, 
+    43392, 43393, 43395, 43384, 43388,     0, 32768, 40960, 
+    43008, 43264, 43392, 43393, 43395, 43384, 43388, 43390, 
+        0, 32768, 40960, 43008, 43264,     0, 32768, 40960, 
+    43008, 43520, 43392,     0, 32768, 40960, 43008, 43520, 
+    43392,     0, 32768, 40960, 43008, 43520, 43392, 43394, 
+        0, 32768, 40960, 43008, 43520, 43392,     0, 32768, 
+    40960, 43008, 43520, 43392, 43396,     0, 32768, 40960, 
+    43008, 43520, 43392, 43396,     0, 32768, 40960, 43008, 
+    43520, 43392, 43400, 43398,     0, 32768, 40960, 43008, 
+    43520, 43392,     0, 32768, 40960, 43008, 43520, 43392, 
+    43400,     0, 32768, 40960, 43008, 43520, 43392, 43400, 
+        0, 32768, 40960, 43008, 43520, 43392, 43400, 43402, 
+        0, 32768, 40960, 43008, 43520, 43392, 43400,     0, 
+    32768, 40960, 43008, 43520, 43392, 43408, 43404,     0, 
+    32768, 40960, 43008, 43520, 43392, 43408, 43404,     0, 
+    32768, 40960, 43008, 43520, 43392, 43408, 43409, 43406, 
+        0, 32768, 40960, 43008, 43520, 43392,     0, 32768, 
+    40960, 43008, 43520, 43392, 43408,     0, 32768, 40960, 
+    43008, 43520, 43392, 43408,     0, 32768, 40960, 43008, 
+    43520, 43392, 43408, 43410,     0, 32768, 40960, 43008, 
+    43520, 43392, 43408,     0, 32768, 40960, 43008, 43520, 
+    43392, 43408, 43412,     0, 32768, 40960, 43008, 43520, 
+    43392, 43408, 43412,     0, 32768, 40960, 43008, 43520, 
+    43392, 43408, 43416, 43414,     0, 32768, 40960, 43008, 
+    43520, 43392, 43408,     0, 32768, 40960, 43008, 43520, 
+    43392, 43424, 43416,     0, 32768, 40960, 43008, 43520, 
+    43392, 43424, 43416,     0, 32768, 40960, 43008, 43520, 
+    43392, 43424, 43416, 43418,     0, 32768, 40960, 43008, 
+    43520, 43392, 43424, 43416,     0, 32768, 40960, 43008, 
+    43520, 43392, 43424, 43425, 43420,     0, 32768, 40960, 
+    43008, 43520, 43392, 43424, 43425, 43420,     0, 32768, 
+    40960, 43008, 43520, 43392, 43424, 43425, 43420, 43422, 
+        0, 32768, 40960, 43008, 43520, 43392,     0, 32768, 
+    40960, 43008, 43520, 43392, 43424,     0, 32768, 40960, 
+    43008, 43520, 43392, 43424,     0, 32768, 40960, 43008, 
+    43520, 43392, 43424, 43426,     0, 32768, 40960, 43008, 
+    43520, 43392, 43424,     0, 32768, 40960, 43008, 43520, 
+    43392, 43424, 43428,     0, 32768, 40960, 43008, 43520, 
+    43392, 43424, 43428,     0, 32768, 40960, 43008, 43520, 
+    43392, 43424, 43432, 43430,     0, 32768, 40960, 43008, 
+    43520, 43392, 43424,     0, 32768, 40960, 43008, 43520, 
+    43392, 43424, 43432,     0, 32768, 40960, 43008, 43520, 
+    43392, 43424, 43432,     0, 32768, 40960, 43008, 43520, 
+    43392, 43424, 43432, 43434,     0, 32768, 40960, 43008, 
+    43520, 43392, 43424, 43432,     0, 32768, 40960, 43008, 
+    43520, 43392, 43424, 43440, 43436,     0, 32768, 40960, 
+    43008, 43520, 43392, 43424, 43440, 43436,     0, 32768, 
+    40960, 43008, 43520, 43392, 43424, 43440, 43441, 43438, 
+        0, 32768, 40960, 43008, 43520, 43392, 43424,     0, 
+    32768, 40960, 43008, 43520, 43392, 43456, 43440,     0, 
+    32768, 40960, 43008, 43520, 43392, 43456, 43440,     0, 
+    32768, 40960, 43008, 43520, 43392, 43456, 43440, 43442, 
+        0, 32768, 40960, 43008, 43520, 43392, 43456, 43440, 
+        0, 32768, 40960, 43008, 43520, 43392, 43456, 43440, 
+    43444,     0, 32768, 40960, 43008, 43520, 43392, 43456, 
+    43440, 43444,     0, 32768, 40960, 43008, 43520, 43392, 
+    43456, 43440, 43448, 43446,     0, 32768, 40960, 43008, 
+    43520, 43392, 43456, 43440,     0, 32768, 40960, 43008, 
+    43520, 43392, 43456, 43457, 43448,     0, 32768, 40960, 
+    43008, 43520, 43392, 43456, 43457, 43448,     0, 32768, 
+    40960, 43008, 43520, 43392, 43456, 43457, 43448, 43450, 
+        0, 32768, 40960, 43008, 43520, 43392, 43456, 43457, 
+    43448,     0, 32768, 40960, 43008, 43520, 43392, 43456, 
+    43457, 43448, 43452,     0, 32768, 40960, 43008, 43520, 
+    43392, 43456, 43457, 43459, 43452,     0, 32768, 40960, 
+    43008, 43520, 43392, 43456, 43457, 43459, 43452, 43454, 
+        0, 32768, 40960, 43008, 43520, 43392,     0, 32768, 
+    40960, 43008, 43520, 43521, 43456,     0, 32768, 40960, 
+    43008, 43520, 43521, 43456,     0, 32768, 40960, 43008, 
+    43520, 43521, 43456, 43458,     0, 32768, 40960, 43008, 
+    43520, 43521, 43456,     0, 32768, 40960, 43008, 43520, 
+    43521, 43456, 43460,     0, 32768, 40960, 43008, 43520, 
+    43521, 43456, 43460,     0, 32768, 40960, 43008, 43520, 
+    43521, 43456, 43464, 43462,     0, 32768, 40960, 43008, 
+    43520, 43521, 43456,     0, 32768, 40960, 43008, 43520, 
+    43521, 43456, 43464,     0, 32768, 40960, 43008, 43520, 
+    43521, 43456, 43464,     0, 32768, 40960, 43008, 43520, 
+    43521, 43456, 43464, 43466,     0, 32768, 40960, 43008, 
+    43520, 43521, 43456, 43464,     0, 32768, 40960, 43008, 
+    43520, 43521, 43456, 43472, 43468,     0, 32768, 40960, 
+    43008, 43520, 43521, 43456, 43472, 43468,     0, 32768, 
+    40960, 43008, 43520, 43521, 43456, 43472, 43473, 43470, 
+        0, 32768, 40960, 43008, 43520, 43521, 43456,     0, 
+    32768, 40960, 43008, 43520, 43521, 43456, 43472,     0, 
+    32768, 40960, 43008, 43520, 43521, 43456, 43472,     0, 
+    32768, 40960, 43008, 43520, 43521, 43456, 43472, 43474, 
+        0, 32768, 40960, 43008, 43520, 43521, 43456, 43472, 
+        0, 32768, 40960, 43008, 43520, 43521, 43456, 43472, 
+    43476,     0, 32768, 40960, 43008, 43520, 43521, 43456, 
+    43472, 43476,     0, 32768, 40960, 43008, 43520, 43521, 
+    43456, 43472, 43480, 43478,     0, 32768, 40960, 43008, 
+    43520, 43521, 43456, 43472,     0, 32768, 40960, 43008, 
+    43520, 43521, 43456, 43488, 43480,     0, 32768, 40960, 
+    43008, 43520, 43521, 43456, 43488, 43480,     0, 32768, 
+    40960, 43008, 43520, 43521, 43456, 43488, 43480, 43482, 
+        0, 32768, 40960, 43008, 43520, 43521, 43456, 43488, 
+    43480,     0, 32768, 40960, 43008, 43520, 43521, 43456, 
+    43488, 43489, 43484,     0, 32768, 40960, 43008, 43520, 
+    43521, 43456, 43488, 43489, 43484,     0, 32768, 40960, 
+    43008, 43520, 43521, 43456, 43488, 43489, 43484, 43486, 
+        0, 32768, 40960, 43008, 43520, 43521, 43456,     0, 
+    32768, 40960, 43008, 43520, 43521, 43456, 43488,     0, 
+    32768, 40960, 43008, 43520, 43521, 43523, 43488,     0, 
+    32768, 40960, 43008, 43520, 43521, 43523, 43488, 43490, 
+        0, 32768, 40960, 43008, 43520, 43521, 43523, 43488, 
+        0, 32768, 40960, 43008, 43520, 43521, 43523, 43488, 
+    43492,     0, 32768, 40960, 43008, 43520, 43521, 43523, 
+    43488, 43492,     0, 32768, 40960, 43008, 43520, 43521, 
+    43523, 43488, 43496, 43494,     0, 32768, 40960, 43008, 
+    43520, 43521, 43523, 43488,     0, 32768, 40960, 43008, 
+    43520, 43521, 43523, 43488, 43496,     0, 32768, 40960, 
+    43008, 43520, 43521, 43523, 43488, 43496,     0, 32768, 
+    40960, 43008, 43520, 43521, 43523, 43488, 43496, 43498, 
+        0, 32768, 40960, 43008, 43520, 43521, 43523, 43488, 
+    43496,     0, 32768, 40960, 43008, 43520, 43521, 43523, 
+    43488, 43504, 43500,     0, 32768, 40960, 43008, 43520, 
+    43521, 43523, 43488, 43504, 43500,     0, 32768, 40960, 
+    43008, 43520, 43521, 43523, 43488, 43504, 43505, 43502, 
+        0, 32768, 40960, 43008, 43520, 43521, 43523, 43488, 
+        0, 32768, 40960, 43008, 43520, 43521, 43523, 43488, 
+    43504,     0, 32768, 40960, 43008, 43520, 43521, 43523, 
+    43488, 43504,     0, 32768, 40960, 43008, 43520, 43521, 
+    43523, 43488, 43504, 43506,     0, 32768, 40960, 43008, 
+    43520, 43521, 43523, 43527, 43504,     0, 32768, 40960, 
+    43008, 43520, 43521, 43523, 43527, 43504, 43508,     0, 
+    32768, 40960, 43008, 43520, 43521, 43523, 43527, 43504, 
+    43508,     0, 32768, 40960, 43008, 43520, 43521, 43523, 
+    43527, 43504, 43512, 43510,     0, 32768, 40960, 43008, 
+    43520, 43521, 43523, 43527, 43504,     0, 32768, 40960, 
+    43008, 43520, 43521, 43523, 43527, 43504, 43512,     0, 
+    32768, 40960, 43008, 43520, 43521, 43523, 43527, 43504, 
+    43512,     0, 32768, 40960, 43008, 43520, 43521, 43523, 
+    43527, 43504, 43512, 43514,     0, 32768, 40960, 43008, 
+    43520, 43521, 43523, 43527, 43504, 43512,     0, 32768, 
+    40960, 43008, 43520, 43521, 43523, 43527, 43504, 43512, 
+    43516,     0, 32768, 40960, 43008, 43520, 43521, 43523, 
+    43527, 43504, 43512, 43516,     0, 32768, 40960, 43008, 
+    43520, 43521, 43523, 43527, 43504, 43512, 43516, 43518, 
+        0, 32768, 40960, 43008,     0, 32768, 40960, 43008, 
+    43520,     0, 32768, 40960, 43008, 43520,     0, 32768, 
+    40960, 43008, 43520, 43522,     0, 32768, 40960, 43008, 
+    43520,     0, 32768, 40960, 43008, 43520, 43524,     0, 
+    32768, 40960, 43008, 43520, 43524,     0, 32768, 40960, 
+    43008, 43520, 43528, 43526,     0, 32768, 40960, 43008, 
+    43520,     0, 32768, 40960, 43008, 43520, 43528,     0, 
+    32768, 40960, 43008, 43520, 43528,     0, 32768, 40960, 
+    43008, 43520, 43528, 43530,     0, 32768, 40960, 43008, 
+    43520, 43528,     0, 32768, 40960, 43008, 43520, 43536, 
+    43532,     0, 32768, 40960, 43008, 43520, 43536, 43532, 
+        0, 32768, 40960, 43008, 43520, 43536, 43537, 43534, 
+        0, 32768, 40960, 43008, 43520,     0, 32768, 40960, 
+    43008, 43520, 43536,     0, 32768, 40960, 43008, 43520, 
+    43536,     0, 32768, 40960, 43008, 43520, 43536, 43538, 
+        0, 32768, 40960, 43008, 43520, 43536,     0, 32768, 
+    40960, 43008, 43520, 43536, 43540,     0, 32768, 40960, 
+    43008, 43520, 43536, 43540,     0, 32768, 40960, 43008, 
+    43520, 43536, 43544, 43542,     0, 32768, 40960, 43008, 
+    43520, 43536,     0, 32768, 40960, 43008, 43520, 43552, 
+    43544,     0, 32768, 40960, 43008, 43520, 43552, 43544, 
+        0, 32768, 40960, 43008, 43520, 43552, 43544, 43546, 
+        0, 32768, 40960, 43008, 43520, 43552, 43544,     0, 
+    32768, 40960, 43008, 43520, 43552, 43553, 43548,     0, 
+    32768, 40960, 43008, 43520, 43552, 43553, 43548,     0, 
+    32768, 40960, 43008, 43520, 43552, 43553, 43548, 43550, 
+        0, 32768, 40960, 43008, 43520,     0, 32768, 40960, 
+    43008, 43520, 43552,     0, 32768, 40960, 43008, 43520, 
+    43552,     0, 32768, 40960, 43008, 43520, 43552, 43554, 
+        0, 32768, 40960, 43008, 43520, 43552,     0, 32768, 
+    40960, 43008, 43520, 43552, 43556,     0, 32768, 40960, 
+    43008, 43520, 43552, 43556,     0, 32768, 40960, 43008, 
+    43520, 43552, 43560, 43558,     0, 32768, 40960, 43008, 
+    43520, 43552,     0, 32768, 40960, 43008, 43520, 43552, 
+    43560,     0, 32768, 40960, 43008, 43520, 43552, 43560, 
+        0, 32768, 40960, 43008, 43520, 43552, 43560, 43562, 
+        0, 32768, 40960, 43008, 43520, 43552, 43560,     0, 
+    32768, 40960, 43008, 43520, 43552, 43568, 43564,     0, 
+    32768, 40960, 43008, 43520, 43552, 43568, 43564,     0, 
+    32768, 40960, 43008, 43520, 43552, 43568, 43569, 43566, 
+        0, 32768, 40960, 43008, 43520, 43552,     0, 32768, 
+    40960, 43008, 43520, 43584, 43568,     0, 32768, 40960, 
+    43008, 43520, 43584, 43568,     0, 32768, 40960, 43008, 
+    43520, 43584, 43568, 43570,     0, 32768, 40960, 43008, 
+    43520, 43584, 43568,     0, 32768, 40960, 43008, 43520, 
+    43584, 43568, 43572,     0, 32768, 40960, 43008, 43520, 
+    43584, 43568, 43572,     0, 32768, 40960, 43008, 43520, 
+    43584, 43568, 43576, 43574,     0, 32768, 40960, 43008, 
+    43520, 43584, 43568,     0, 32768, 40960, 43008, 43520, 
+    43584, 43585, 43576,     0, 32768, 40960, 43008, 43520, 
+    43584, 43585, 43576,     0, 32768, 40960, 43008, 43520, 
+    43584, 43585, 43576, 43578,     0, 32768, 40960, 43008, 
+    43520, 43584, 43585, 43576,     0, 32768, 40960, 43008, 
+    43520, 43584, 43585, 43576, 43580,     0, 32768, 40960, 
+    43008, 43520, 43584, 43585, 43587, 43580,     0, 32768, 
+    40960, 43008, 43520, 43584, 43585, 43587, 43580, 43582, 
+        0, 32768, 40960, 43008, 43520,     0, 32768, 40960, 
+    43008, 43520, 43584,     0, 32768, 40960, 43008, 43520, 
+    43584,     0, 32768, 40960, 43008, 43520, 43584, 43586, 
+        0, 32768, 40960, 43008, 43520, 43584,     0, 32768, 
+    40960, 43008, 43520, 43584, 43588,     0, 32768, 40960, 
+    43008, 43520, 43584, 43588,     0, 32768, 40960, 43008, 
+    43520, 43584, 43592, 43590,     0, 32768, 40960, 43008, 
+    43520, 43584,     0, 32768, 40960, 43008, 43520, 43584, 
+    43592,     0, 32768, 40960, 43008, 43520, 43584, 43592, 
+        0, 32768, 40960, 43008, 43520, 43584, 43592, 43594, 
+        0, 32768, 40960, 43008, 43520, 43584, 43592,     0, 
+    32768, 40960, 43008, 43520, 43584, 43600, 43596,     0, 
+    32768, 40960, 43008, 43520, 43584, 43600, 43596,     0, 
+    32768, 40960, 43008, 43520, 43584, 43600, 43601, 43598, 
+        0, 32768, 40960, 43008, 43520, 43584,     0, 32768, 
+    40960, 43008, 43520, 43584, 43600,     0, 32768, 40960, 
+    43008, 43520, 43584, 43600,     0, 32768, 40960, 43008, 
+    43520, 43584, 43600, 43602,     0, 32768, 40960, 43008, 
+    43520, 43584, 43600,     0, 32768, 40960, 43008, 43520, 
+    43584, 43600, 43604,     0, 32768, 40960, 43008, 43520, 
+    43584, 43600, 43604,     0, 32768, 40960, 43008, 43520, 
+    43584, 43600, 43608, 43606,     0, 32768, 40960, 43008, 
+    43520, 43584, 43600,     0, 32768, 40960, 43008, 43520, 
+    43584, 43616, 43608,     0, 32768, 40960, 43008, 43520, 
+    43584, 43616, 43608,     0, 32768, 40960, 43008, 43520, 
+    43584, 43616, 43608, 43610,     0, 32768, 40960, 43008, 
+    43520, 43584, 43616, 43608,     0, 32768, 40960, 43008, 
+    43520, 43584, 43616, 43617, 43612,     0, 32768, 40960, 
+    43008, 43520, 43584, 43616, 43617, 43612,     0, 32768, 
+    40960, 43008, 43520, 43584, 43616, 43617, 43612, 43614, 
+        0, 32768, 40960, 43008, 43520, 43584,     0, 32768, 
+    40960, 43008, 43520, 43648, 43616,     0, 32768, 40960, 
+    43008, 43520, 43648, 43616,     0, 32768, 40960, 43008, 
+    43520, 43648, 43616, 43618,     0, 32768, 40960, 43008, 
+    43520, 43648, 43616,     0, 32768, 40960, 43008, 43520, 
+    43648, 43616, 43620,     0, 32768, 40960, 43008, 43520, 
+    43648, 43616, 43620,     0, 32768, 40960, 43008, 43520, 
+    43648, 43616, 43624, 43622,     0, 32768, 40960, 43008, 
+    43520, 43648, 43616,     0, 32768, 40960, 43008, 43520, 
+    43648, 43616, 43624,     0, 32768, 40960, 43008, 43520, 
+    43648, 43616, 43624,     0, 32768, 40960, 43008, 43520, 
+    43648, 43616, 43624, 43626,     0, 32768, 40960, 43008, 
+    43520, 43648, 43616, 43624,     0, 32768, 40960, 43008, 
+    43520, 43648, 43616, 43632, 43628,     0, 32768, 40960, 
+    43008, 43520, 43648, 43616, 43632, 43628,     0, 32768, 
+    40960, 43008, 43520, 43648, 43616, 43632, 43633, 43630, 
+        0, 32768, 40960, 43008, 43520, 43648, 43616,     0, 
+    32768, 40960, 43008, 43520, 43648, 43649, 43632,     0, 
+    32768, 40960, 43008, 43520, 43648, 43649, 43632,     0, 
+    32768, 40960, 43008, 43520, 43648, 43649, 43632, 43634, 
+        0, 32768, 40960, 43008, 43520, 43648, 43649, 43632, 
+        0, 32768, 40960, 43008, 43520, 43648, 43649, 43632, 
+    43636,     0, 32768, 40960, 43008, 43520, 43648, 43649, 
+    43632, 43636,     0, 32768, 40960, 43008, 43520, 43648, 
+    43649, 43632, 43640, 43638,     0, 32768, 40960, 43008, 
+    43520, 43648, 43649, 43632,     0, 32768, 40960, 43008, 
+    43520, 43648, 43649, 43632, 43640,     0, 32768, 40960, 
+    43008, 43520, 43648, 43649, 43651, 43640,     0, 32768, 
+    40960, 43008, 43520, 43648, 43649, 43651, 43640, 43642, 
+        0, 32768, 40960, 43008, 43520, 43648, 43649, 43651, 
+    43640,     0, 32768, 40960, 43008, 43520, 43648, 43649, 
+    43651, 43640, 43644,     0, 32768, 40960, 43008, 43520, 
+    43648, 43649, 43651, 43640, 43644,     0, 32768, 40960, 
+    43008, 43520, 43648, 43649, 43651, 43640, 43644, 43646, 
+        0, 32768, 40960, 43008, 43520,     0, 32768, 40960, 
+    43008, 43520, 43648,     0, 32768, 40960, 43008, 43520, 
+    43648,     0, 32768, 40960, 43008, 43520, 43648, 43650, 
+        0, 32768, 40960, 43008, 43520, 43648,     0, 32768, 
+    40960, 43008, 43520, 43648, 43652,     0, 32768, 40960, 
+    43008, 43520, 43648, 43652,     0, 32768, 40960, 43008, 
+    43520, 43648, 43656, 43654,     0, 32768, 40960, 43008, 
+    43520, 43648,     0, 32768, 40960, 43008, 43520, 43648, 
+    43656,     0, 32768, 40960, 43008, 43520, 43648, 43656, 
+        0, 32768, 40960, 43008, 43520, 43648, 43656, 43658, 
+        0, 32768, 40960, 43008, 43520, 43648, 43656,     0, 
+    32768, 40960, 43008, 43520, 43648, 43664, 43660,     0, 
+    32768, 40960, 43008, 43520, 43648, 43664, 43660,     0, 
+    32768, 40960, 43008, 43520, 43648, 43664, 43665, 43662, 
+        0, 32768, 40960, 43008, 43520, 43648,     0, 32768, 
+    40960, 43008, 43520, 43648, 43664,     0, 32768, 40960, 
+    43008, 43520, 43648, 43664,     0, 32768, 40960, 43008, 
+    43520, 43648, 43664, 43666,     0, 32768, 40960, 43008, 
+    43520, 43648, 43664,     0, 32768, 40960, 43008, 43520, 
+    43648, 43664, 43668,     0, 32768, 40960, 43008, 43520, 
+    43648, 43664, 43668,     0, 32768, 40960, 43008, 43520, 
+    43648, 43664, 43672, 43670,     0, 32768, 40960, 43008, 
+    43520, 43648, 43664,     0, 32768, 40960, 43008, 43520, 
+    43648, 43680, 43672,     0, 32768, 40960, 43008, 43520, 
+    43648, 43680, 43672,     0, 32768, 40960, 43008, 43520, 
+    43648, 43680, 43672, 43674,     0, 32768, 40960, 43008, 
+    43520, 43648, 43680, 43672,     0, 32768, 40960, 43008, 
+    43520, 43648, 43680, 43681, 43676,     0, 32768, 40960, 
+    43008, 43520, 43648, 43680, 43681, 43676,     0, 32768, 
+    40960, 43008, 43520, 43648, 43680, 43681, 43676, 43678, 
+        0, 32768, 40960, 43008, 43520, 43648,     0, 32768, 
+    40960, 43008, 43520, 43648, 43680,     0, 32768, 40960, 
+    43008, 43520, 43648, 43680,     0, 32768, 40960, 43008, 
+    43520, 43648, 43680, 43682,     0, 32768, 40960, 43008, 
+    43520, 43648, 43680,     0, 32768, 40960, 43008, 43520, 
+    43648, 43680, 43684,     0, 32768, 40960, 43008, 43520, 
+    43648, 43680, 43684,     0, 32768, 40960, 43008, 43520, 
+    43648, 43680, 43688, 43686,     0, 32768, 40960, 43008, 
+    43520, 43648, 43680,     0, 32768, 40960, 43008, 43520, 
+    43648, 43680, 43688,     0, 32768, 40960, 43008, 43520, 
+    43648, 43680, 43688,     0, 32768, 40960, 43008, 43520, 
+    43648, 43680, 43688, 43690,     0, 32768, 40960, 43008, 
+    43520, 43648, 43680, 43688,     0, 32768, 40960, 43008, 
+    43520, 43648, 43680, 43696, 43692,     0, 32768, 40960, 
+    43008, 43520, 43648, 43680, 43696, 43692,     0, 32768, 
+    40960, 43008, 43520, 43648, 43680, 43696, 43697, 43694, 
+        0, 32768, 40960, 43008, 43520, 43648, 43680,     0, 
+    32768, 40960, 43008, 43520, 43648, 43712, 43696,     0, 
+    32768, 40960, 43008, 43520, 43648, 43712, 43696,     0, 
+    32768, 40960, 43008, 43520, 43648, 43712, 43696, 43698, 
+        0, 32768, 40960, 43008, 43520, 43648, 43712, 43696, 
+        0, 32768, 40960, 43008, 43520, 43648, 43712, 43696, 
+    43700,     0, 32768, 40960, 43008, 43520, 43648, 43712, 
+    43696, 43700,     0, 32768, 40960, 43008, 43520, 43648, 
+    43712, 43696, 43704, 43702,     0, 32768, 40960, 43008, 
+    43520, 43648, 43712, 43696,     0, 32768, 40960, 43008, 
+    43520, 43648, 43712, 43713, 43704,     0, 32768, 40960, 
+    43008, 43520, 43648, 43712, 43713, 43704,     0, 32768, 
+    40960, 43008, 43520, 43648, 43712, 43713, 43704, 43706, 
+        0, 32768, 40960, 43008, 43520, 43648, 43712, 43713, 
+    43704,     0, 32768, 40960, 43008, 43520, 43648, 43712, 
+    43713, 43704, 43708,     0, 32768, 40960, 43008, 43520, 
+    43648, 43712, 43713, 43715, 43708,     0, 32768, 40960, 
+    43008, 43520, 43648, 43712, 43713, 43715, 43708, 43710, 
+        0, 32768, 40960, 43008, 43520, 43648,     0, 32768, 
+    40960, 43008, 43520, 43776, 43712,     0, 32768, 40960, 
+    43008, 43520, 43776, 43712,     0, 32768, 40960, 43008, 
+    43520, 43776, 43712, 43714,     0, 32768, 40960, 43008, 
+    43520, 43776, 43712,     0, 32768, 40960, 43008, 43520, 
+    43776, 43712, 43716,     0, 32768, 40960, 43008, 43520, 
+    43776, 43712, 43716,     0, 32768, 40960, 43008, 43520, 
+    43776, 43712, 43720, 43718,     0, 32768, 40960, 43008, 
+    43520, 43776, 43712,     0, 32768, 40960, 43008, 43520, 
+    43776, 43712, 43720,     0, 32768, 40960, 43008, 43520, 
+    43776, 43712, 43720,     0, 32768, 40960, 43008, 43520, 
+    43776, 43712, 43720, 43722,     0, 32768, 40960, 43008, 
+    43520, 43776, 43712, 43720,     0, 32768, 40960, 43008, 
+    43520, 43776, 43712, 43728, 43724,     0, 32768, 40960, 
+    43008, 43520, 43776, 43712, 43728, 43724,     0, 32768, 
+    40960, 43008, 43520, 43776, 43712, 43728, 43729, 43726, 
+        0, 32768, 40960, 43008, 43520, 43776, 43712,     0, 
+    32768, 40960, 43008, 43520, 43776, 43712, 43728,     0, 
+    32768, 40960, 43008, 43520, 43776, 43712, 43728,     0, 
+    32768, 40960, 43008, 43520, 43776, 43712, 43728, 43730, 
+        0, 32768, 40960, 43008, 43520, 43776, 43712, 43728, 
+        0, 32768, 40960, 43008, 43520, 43776, 43712, 43728, 
+    43732,     0, 32768, 40960, 43008, 43520, 43776, 43712, 
+    43728, 43732,     0, 32768, 40960, 43008, 43520, 43776, 
+    43712, 43728, 43736, 43734,     0, 32768, 40960, 43008, 
+    43520, 43776, 43712, 43728,     0, 32768, 40960, 43008, 
+    43520, 43776, 43712, 43744, 43736,     0, 32768, 40960, 
+    43008, 43520, 43776, 43712, 43744, 43736,     0, 32768, 
+    40960, 43008, 43520, 43776, 43712, 43744, 43736, 43738, 
+        0, 32768, 40960, 43008, 43520, 43776, 43712, 43744, 
+    43736,     0, 32768, 40960, 43008, 43520, 43776, 43712, 
+    43744, 43745, 43740,     0, 32768, 40960, 43008, 43520, 
+    43776, 43712, 43744, 43745, 43740,     0, 32768, 40960, 
+    43008, 43520, 43776, 43712, 43744, 43745, 43740, 43742, 
+        0, 32768, 40960, 43008, 43520, 43776, 43712,     0, 
+    32768, 40960, 43008, 43520, 43776, 43777, 43744,     0, 
+    32768, 40960, 43008, 43520, 43776, 43777, 43744,     0, 
+    32768, 40960, 43008, 43520, 43776, 43777, 43744, 43746, 
+        0, 32768, 40960, 43008, 43520, 43776, 43777, 43744, 
+        0, 32768, 40960, 43008, 43520, 43776, 43777, 43744, 
+    43748,     0, 32768, 40960, 43008, 43520, 43776, 43777, 
+    43744, 43748,     0, 32768, 40960, 43008, 43520, 43776, 
+    43777, 43744, 43752, 43750,     0, 32768, 40960, 43008, 
+    43520, 43776, 43777, 43744,     0, 32768, 40960, 43008, 
+    43520, 43776, 43777, 43744, 43752,     0, 32768, 40960, 
+    43008, 43520, 43776, 43777, 43744, 43752,     0, 32768, 
+    40960, 43008, 43520, 43776, 43777, 43744, 43752, 43754, 
+        0, 32768, 40960, 43008, 43520, 43776, 43777, 43744, 
+    43752,     0, 32768, 40960, 43008, 43520, 43776, 43777, 
+    43744, 43760, 43756,     0, 32768, 40960, 43008, 43520, 
+    43776, 43777, 43744, 43760, 43756,     0, 32768, 40960, 
+    43008, 43520, 43776, 43777, 43744, 43760, 43761, 43758, 
+        0, 32768, 40960, 43008, 43520, 43776, 43777, 43744, 
+        0, 32768, 40960, 43008, 43520, 43776, 43777, 43744, 
+    43760,     0, 32768, 40960, 43008, 43520, 43776, 43777, 
+    43779, 43760,     0, 32768, 40960, 43008, 43520, 43776, 
+    43777, 43779, 43760, 43762,     0, 32768, 40960, 43008, 
+    43520, 43776, 43777, 43779, 43760,     0, 32768, 40960, 
+    43008, 43520, 43776, 43777, 43779, 43760, 43764,     0, 
+    32768, 40960, 43008, 43520, 43776, 43777, 43779, 43760, 
+    43764,     0, 32768, 40960, 43008, 43520, 43776, 43777, 
+    43779, 43760, 43768, 43766,     0, 32768, 40960, 43008, 
+    43520, 43776, 43777, 43779, 43760,     0, 32768, 40960, 
+    43008, 43520, 43776, 43777, 43779, 43760, 43768,     0, 
+    32768, 40960, 43008, 43520, 43776, 43777, 43779, 43760, 
+    43768,     0, 32768, 40960, 43008, 43520, 43776, 43777, 
+    43779, 43760, 43768, 43770,     0, 32768, 40960, 43008, 
+    43520, 43776, 43777, 43779, 43783, 43768,     0, 32768, 
+    40960, 43008, 43520, 43776, 43777, 43779, 43783, 43768, 
+    43772,     0, 32768, 40960, 43008, 43520, 43776, 43777, 
+    43779, 43783, 43768, 43772,     0, 32768, 40960, 43008, 
+    43520, 43776, 43777, 43779, 43783, 43768, 43772, 43774, 
+        0, 32768, 40960, 43008, 43520,     0, 32768, 40960, 
+    43008, 44032, 43776,     0, 32768, 40960, 43008, 44032, 
+    43776,     0, 32768, 40960, 43008, 44032, 43776, 43778, 
+        0, 32768, 40960, 43008, 44032, 43776,     0, 32768, 
+    40960, 43008, 44032, 43776, 43780,     0, 32768, 40960, 
+    43008, 44032, 43776, 43780,     0, 32768, 40960, 43008, 
+    44032, 43776, 43784, 43782,     0, 32768, 40960, 43008, 
+    44032, 43776,     0, 32768, 40960, 43008, 44032, 43776, 
+    43784,     0, 32768, 40960, 43008, 44032, 43776, 43784, 
+        0, 32768, 40960, 43008, 44032, 43776, 43784, 43786, 
+        0, 32768, 40960, 43008, 44032, 43776, 43784,     0, 
+    32768, 40960, 43008, 44032, 43776, 43792, 43788,     0, 
+    32768, 40960, 43008, 44032, 43776, 43792, 43788,     0, 
+    32768, 40960, 43008, 44032, 43776, 43792, 43793, 43790, 
+        0, 32768, 40960, 43008, 44032, 43776,     0, 32768, 
+    40960, 43008, 44032, 43776, 43792,     0, 32768, 40960, 
+    43008, 44032, 43776, 43792,     0, 32768, 40960, 43008, 
+    44032, 43776, 43792, 43794,     0, 32768, 40960, 43008, 
+    44032, 43776, 43792,     0, 32768, 40960, 43008, 44032, 
+    43776, 43792, 43796,     0, 32768, 40960, 43008, 44032, 
+    43776, 43792, 43796,     0, 32768, 40960, 43008, 44032, 
+    43776, 43792, 43800, 43798,     0, 32768, 40960, 43008, 
+    44032, 43776, 43792,     0, 32768, 40960, 43008, 44032, 
+    43776, 43808, 43800,     0, 32768, 40960, 43008, 44032, 
+    43776, 43808, 43800,     0, 32768, 40960, 43008, 44032, 
+    43776, 43808, 43800, 43802,     0, 32768, 40960, 43008, 
+    44032, 43776, 43808, 43800,     0, 32768, 40960, 43008, 
+    44032, 43776, 43808, 43809, 43804,     0, 32768, 40960, 
+    43008, 44032, 43776, 43808, 43809, 43804,     0, 32768, 
+    40960, 43008, 44032, 43776, 43808, 43809, 43804, 43806, 
+        0, 32768, 40960, 43008, 44032, 43776,     0, 32768, 
+    40960, 43008, 44032, 43776, 43808,     0, 32768, 40960, 
+    43008, 44032, 43776, 43808,     0, 32768, 40960, 43008, 
+    44032, 43776, 43808, 43810,     0, 32768, 40960, 43008, 
+    44032, 43776, 43808,     0, 32768, 40960, 43008, 44032, 
+    43776, 43808, 43812,     0, 32768, 40960, 43008, 44032, 
+    43776, 43808, 43812,     0, 32768, 40960, 43008, 44032, 
+    43776, 43808, 43816, 43814,     0, 32768, 40960, 43008, 
+    44032, 43776, 43808,     0, 32768, 40960, 43008, 44032, 
+    43776, 43808, 43816,     0, 32768, 40960, 43008, 44032, 
+    43776, 43808, 43816,     0, 32768, 40960, 43008, 44032, 
+    43776, 43808, 43816, 43818,     0, 32768, 40960, 43008, 
+    44032, 43776, 43808, 43816,     0, 32768, 40960, 43008, 
+    44032, 43776, 43808, 43824, 43820,     0, 32768, 40960, 
+    43008, 44032, 43776, 43808, 43824, 43820,     0, 32768, 
+    40960, 43008, 44032, 43776, 43808, 43824, 43825, 43822, 
+        0, 32768, 40960, 43008, 44032, 43776, 43808,     0, 
+    32768, 40960, 43008, 44032, 43776, 43840, 43824,     0, 
+    32768, 40960, 43008, 44032, 43776, 43840, 43824,     0, 
+    32768, 40960, 43008, 44032, 43776, 43840, 43824, 43826, 
+        0, 32768, 40960, 43008, 44032, 43776, 43840, 43824, 
+        0, 32768, 40960, 43008, 44032, 43776, 43840, 43824, 
+    43828,     0, 32768, 40960, 43008, 44032, 43776, 43840, 
+    43824, 43828,     0, 32768, 40960, 43008, 44032, 43776, 
+    43840, 43824, 43832, 43830,     0, 32768, 40960, 43008, 
+    44032, 43776, 43840, 43824,     0, 32768, 40960, 43008, 
+    44032, 43776, 43840, 43841, 43832,     0, 32768, 40960, 
+    43008, 44032, 43776, 43840, 43841, 43832,     0, 32768, 
+    40960, 43008, 44032, 43776, 43840, 43841, 43832, 43834, 
+        0, 32768, 40960, 43008, 44032, 43776, 43840, 43841, 
+    43832,     0, 32768, 40960, 43008, 44032, 43776, 43840, 
+    43841, 43832, 43836,     0, 32768, 40960, 43008, 44032, 
+    43776, 43840, 43841, 43843, 43836,     0, 32768, 40960, 
+    43008, 44032, 43776, 43840, 43841, 43843, 43836, 43838, 
+        0, 32768, 40960, 43008, 44032, 43776,     0, 32768, 
+    40960, 43008, 44032, 43776, 43840,     0, 32768, 40960, 
+    43008, 44032, 43776, 43840,     0, 32768, 40960, 43008, 
+    44032, 43776, 43840, 43842,     0, 32768, 40960, 43008, 
+    44032, 43776, 43840,     0, 32768, 40960, 43008, 44032, 
+    43776, 43840, 43844,     0, 32768, 40960, 43008, 44032, 
+    43776, 43840, 43844,     0, 32768, 40960, 43008, 44032, 
+    43776, 43840, 43848, 43846,     0, 32768, 40960, 43008, 
+    44032, 43776, 43840,     0, 32768, 40960, 43008, 44032, 
+    43776, 43840, 43848,     0, 32768, 40960, 43008, 44032, 
+    43776, 43840, 43848,     0, 32768, 40960, 43008, 44032, 
+    43776, 43840, 43848, 43850,     0, 32768, 40960, 43008, 
+    44032, 43776, 43840, 43848,     0, 32768, 40960, 43008, 
+    44032, 43776, 43840, 43856, 43852,     0, 32768, 40960, 
+    43008, 44032, 43776, 43840, 43856, 43852,     0, 32768, 
+    40960, 43008, 44032, 43776, 43840, 43856, 43857, 43854, 
+        0, 32768, 40960, 43008, 44032, 43776, 43840,     0, 
+    32768, 40960, 43008, 44032, 43776, 43840, 43856,     0, 
+    32768, 40960, 43008, 44032, 43776, 43840, 43856,     0, 
+    32768, 40960, 43008, 44032, 43776, 43840, 43856, 43858, 
+        0, 32768, 40960, 43008, 44032, 43776, 43840, 43856, 
+        0, 32768, 40960, 43008, 44032, 43776, 43840, 43856, 
+    43860,     0, 32768, 40960, 43008, 44032, 43776, 43840, 
+    43856, 43860,     0, 32768, 40960, 43008, 44032, 43776, 
+    43840, 43856, 43864, 43862,     0, 32768, 40960, 43008, 
+    44032, 43776, 43840, 43856,     0, 32768, 40960, 43008, 
+    44032, 43776, 43840, 43872, 43864,     0, 32768, 40960, 
+    43008, 44032, 43776, 43840, 43872, 43864,     0, 32768, 
+    40960, 43008, 44032, 43776, 43840, 43872, 43864, 43866, 
+        0, 32768, 40960, 43008, 44032, 43776, 43840, 43872, 
+    43864,     0, 32768, 40960, 43008, 44032, 43776, 43840, 
+    43872, 43873, 43868,     0, 32768, 40960, 43008, 44032, 
+    43776, 43840, 43872, 43873, 43868,     0, 32768, 40960, 
+    43008, 44032, 43776, 43840, 43872, 43873, 43868, 43870, 
+        0, 32768, 40960, 43008, 44032, 43776, 43840,     0, 
+    32768, 40960, 43008, 44032, 43776, 43904, 43872,     0, 
+    32768, 40960, 43008, 44032, 43776, 43904, 43872,     0, 
+    32768, 40960, 43008, 44032, 43776, 43904, 43872, 43874, 
+        0, 32768, 40960, 43008, 44032, 43776, 43904, 43872, 
+        0, 32768, 40960, 43008, 44032, 43776, 43904, 43872, 
+    43876,     0, 32768, 40960, 43008, 44032, 43776, 43904, 
+    43872, 43876,     0, 32768, 40960, 43008, 44032, 43776, 
+    43904, 43872, 43880, 43878,     0, 32768, 40960, 43008, 
+    44032, 43776, 43904, 43872,     0, 32768, 40960, 43008, 
+    44032, 43776, 43904, 43872, 43880,     0, 32768, 40960, 
+    43008, 44032, 43776, 43904, 43872, 43880,     0, 32768, 
+    40960, 43008, 44032, 43776, 43904, 43872, 43880, 43882, 
+        0, 32768, 40960, 43008, 44032, 43776, 43904, 43872, 
+    43880,     0, 32768, 40960, 43008, 44032, 43776, 43904, 
+    43872, 43888, 43884,     0, 32768, 40960, 43008, 44032, 
+    43776, 43904, 43872, 43888, 43884,     0, 32768, 40960, 
+    43008, 44032, 43776, 43904, 43872, 43888, 43889, 43886, 
+        0, 32768, 40960, 43008, 44032, 43776, 43904, 43872, 
+        0, 32768, 40960, 43008, 44032, 43776, 43904, 43905, 
+    43888,     0, 32768, 40960, 43008, 44032, 43776, 43904, 
+    43905, 43888,     0, 32768, 40960, 43008, 44032, 43776, 
+    43904, 43905, 43888, 43890,     0, 32768, 40960, 43008, 
+    44032, 43776, 43904, 43905, 43888,     0, 32768, 40960, 
+    43008, 44032, 43776, 43904, 43905, 43888, 43892,     0, 
+    32768, 40960, 43008, 44032, 43776, 43904, 43905, 43888, 
+    43892,     0, 32768, 40960, 43008, 44032, 43776, 43904, 
+    43905, 43888, 43896, 43894,     0, 32768, 40960, 43008, 
+    44032, 43776, 43904, 43905, 43888,     0, 32768, 40960, 
+    43008, 44032, 43776, 43904, 43905, 43888, 43896,     0, 
+    32768, 40960, 43008, 44032, 43776, 43904, 43905, 43907, 
+    43896,     0, 32768, 40960, 43008, 44032, 43776, 43904, 
+    43905, 43907, 43896, 43898,     0, 32768, 40960, 43008, 
+    44032, 43776, 43904, 43905, 43907, 43896,     0, 32768, 
+    40960, 43008, 44032, 43776, 43904, 43905, 43907, 43896, 
+    43900,     0, 32768, 40960, 43008, 44032, 43776, 43904, 
+    43905, 43907, 43896, 43900,     0, 32768, 40960, 43008, 
+    44032, 43776, 43904, 43905, 43907, 43896, 43900, 43902, 
+        0, 32768, 40960, 43008, 44032, 43776,     0, 32768, 
+    40960, 43008, 44032, 43776, 43904,     0, 32768, 40960, 
+    43008, 44032, 44033, 43904,     0, 32768, 40960, 43008, 
+    44032, 44033, 43904, 43906,     0, 32768, 40960, 43008, 
+    44032, 44033, 43904,     0, 32768, 40960, 43008, 44032, 
+    44033, 43904, 43908,     0, 32768, 40960, 43008, 44032, 
+    44033, 43904, 43908,     0, 32768, 40960, 43008, 44032, 
+    44033, 43904, 43912, 43910,     0, 32768, 40960, 43008, 
+    44032, 44033, 43904,     0, 32768, 40960, 43008, 44032, 
+    44033, 43904, 43912,     0, 32768, 40960, 43008, 44032, 
+    44033, 43904, 43912,     0, 32768, 40960, 43008, 44032, 
+    44033, 43904, 43912, 43914,     0, 32768, 40960, 43008, 
+    44032, 44033, 43904, 43912,     0, 32768, 40960, 43008, 
+    44032, 44033, 43904, 43920, 43916,     0, 32768, 40960, 
+    43008, 44032, 44033, 43904, 43920, 43916,     0, 32768, 
+    40960, 43008, 44032, 44033, 43904, 43920, 43921, 43918, 
+        0, 32768, 40960, 43008, 44032, 44033, 43904,     0, 
+    32768, 40960, 43008, 44032, 44033, 43904, 43920,     0, 
+    32768, 40960, 43008, 44032, 44033, 43904, 43920,     0, 
+    32768, 40960, 43008, 44032, 44033, 43904, 43920, 43922, 
+        0, 32768, 40960, 43008, 44032, 44033, 43904, 43920, 
+        0, 32768, 40960, 43008, 44032, 44033, 43904, 43920, 
+    43924,     0, 32768, 40960, 43008, 44032, 44033, 43904, 
+    43920, 43924,     0, 32768, 40960, 43008, 44032, 44033, 
+    43904, 43920, 43928, 43926,     0, 32768, 40960, 43008, 
+    44032, 44033, 43904, 43920,     0, 32768, 40960, 43008, 
+    44032, 44033, 43904, 43936, 43928,     0, 32768, 40960, 
+    43008, 44032, 44033, 43904, 43936, 43928,     0, 32768, 
+    40960, 43008, 44032, 44033, 43904, 43936, 43928, 43930, 
+        0, 32768, 40960, 43008, 44032, 44033, 43904, 43936, 
+    43928,     0, 32768, 40960, 43008, 44032, 44033, 43904, 
+    43936, 43937, 43932,     0, 32768, 40960, 43008, 44032, 
+    44033, 43904, 43936, 43937, 43932,     0, 32768, 40960, 
+    43008, 44032, 44033, 43904, 43936, 43937, 43932, 43934, 
+        0, 32768, 40960, 43008, 44032, 44033, 43904,     0, 
+    32768, 40960, 43008, 44032, 44033, 43904, 43936,     0, 
+    32768, 40960, 43008, 44032, 44033, 43904, 43936,     0, 
+    32768, 40960, 43008, 44032, 44033, 43904, 43936, 43938, 
+        0, 32768, 40960, 43008, 44032, 44033, 43904, 43936, 
+        0, 32768, 40960, 43008, 44032, 44033, 43904, 43936, 
+    43940,     0, 32768, 40960, 43008, 44032, 44033, 43904, 
+    43936, 43940,     0, 32768, 40960, 43008, 44032, 44033, 
+    43904, 43936, 43944, 43942,     0, 32768, 40960, 43008, 
+    44032, 44033, 43904, 43936,     0, 32768, 40960, 43008, 
+    44032, 44033, 43904, 43936, 43944,     0, 32768, 40960, 
+    43008, 44032, 44033, 43904, 43936, 43944,     0, 32768, 
+    40960, 43008, 44032, 44033, 43904, 43936, 43944, 43946, 
+        0, 32768, 40960, 43008, 44032, 44033, 43904, 43936, 
+    43944,     0, 32768, 40960, 43008, 44032, 44033, 43904, 
+    43936, 43952, 43948,     0, 32768, 40960, 43008, 44032, 
+    44033, 43904, 43936, 43952, 43948,     0, 32768, 40960, 
+    43008, 44032, 44033, 43904, 43936, 43952, 43953, 43950, 
+        0, 32768, 40960, 43008, 44032, 44033, 43904, 43936, 
+        0, 32768, 40960, 43008, 44032, 44033, 43904, 43968, 
+    43952,     0, 32768, 40960, 43008, 44032, 44033, 43904, 
+    43968, 43952,     0, 32768, 40960, 43008, 44032, 44033, 
+    43904, 43968, 43952, 43954,     0, 32768, 40960, 43008, 
+    44032, 44033, 43904, 43968, 43952,     0, 32768, 40960, 
+    43008, 44032, 44033, 43904, 43968, 43952, 43956,     0, 
+    32768, 40960, 43008, 44032, 44033, 43904, 43968, 43952, 
+    43956,     0, 32768, 40960, 43008, 44032, 44033, 43904, 
+    43968, 43952, 43960, 43958,     0, 32768, 40960, 43008, 
+    44032, 44033, 43904, 43968, 43952,     0, 32768, 40960, 
+    43008, 44032, 44033, 43904, 43968, 43969, 43960,     0, 
+    32768, 40960, 43008, 44032, 44033, 43904, 43968, 43969, 
+    43960,     0, 32768, 40960, 43008, 44032, 44033, 43904, 
+    43968, 43969, 43960, 43962,     0, 32768, 40960, 43008, 
+    44032, 44033, 43904, 43968, 43969, 43960,     0, 32768, 
+    40960, 43008, 44032, 44033, 43904, 43968, 43969, 43960, 
+    43964,     0, 32768, 40960, 43008, 44032, 44033, 43904, 
+    43968, 43969, 43971, 43964,     0, 32768, 40960, 43008, 
+    44032, 44033, 43904, 43968, 43969, 43971, 43964, 43966, 
+        0, 32768, 40960, 43008, 44032, 44033, 43904,     0, 
+    32768, 40960, 43008, 44032, 44033, 43904, 43968,     0, 
+    32768, 40960, 43008, 44032, 44033, 43904, 43968,     0, 
+    32768, 40960, 43008, 44032, 44033, 43904, 43968, 43970, 
+        0, 32768, 40960, 43008, 44032, 44033, 44035, 43968, 
+        0, 32768, 40960, 43008, 44032, 44033, 44035, 43968, 
+    43972,     0, 32768, 40960, 43008, 44032, 44033, 44035, 
+    43968, 43972,     0, 32768, 40960, 43008, 44032, 44033, 
+    44035, 43968, 43976, 43974,     0, 32768, 40960, 43008, 
+    44032, 44033, 44035, 43968,     0, 32768, 40960, 43008, 
+    44032, 44033, 44035, 43968, 43976,     0, 32768, 40960, 
+    43008, 44032, 44033, 44035, 43968, 43976,     0, 32768, 
+    40960, 43008, 44032, 44033, 44035, 43968, 43976, 43978, 
+        0, 32768, 40960, 43008, 44032, 44033, 44035, 43968, 
+    43976,     0, 32768, 40960, 43008, 44032, 44033, 44035, 
+    43968, 43984, 43980,     0, 32768, 40960, 43008, 44032, 
+    44033, 44035, 43968, 43984, 43980,     0, 32768, 40960, 
+    43008, 44032, 44033, 44035, 43968, 43984, 43985, 43982, 
+        0, 32768, 40960, 43008, 44032, 44033, 44035, 43968, 
+        0, 32768, 40960, 43008, 44032, 44033, 44035, 43968, 
+    43984,     0, 32768, 40960, 43008, 44032, 44033, 44035, 
+    43968, 43984,     0, 32768, 40960, 43008, 44032, 44033, 
+    44035, 43968, 43984, 43986,     0, 32768, 40960, 43008, 
+    44032, 44033, 44035, 43968, 43984,     0, 32768, 40960, 
+    43008, 44032, 44033, 44035, 43968, 43984, 43988,     0, 
+    32768, 40960, 43008, 44032, 44033, 44035, 43968, 43984, 
+    43988,     0, 32768, 40960, 43008, 44032, 44033, 44035, 
+    43968, 43984, 43992, 43990,     0, 32768, 40960, 43008, 
+    44032, 44033, 44035, 43968, 43984,     0, 32768, 40960, 
+    43008, 44032, 44033, 44035, 43968, 44000, 43992,     0, 
+    32768, 40960, 43008, 44032, 44033, 44035, 43968, 44000, 
+    43992,     0, 32768, 40960, 43008, 44032, 44033, 44035, 
+    43968, 44000, 43992, 43994,     0, 32768, 40960, 43008, 
+    44032, 44033, 44035, 43968, 44000, 43992,     0, 32768, 
+    40960, 43008, 44032, 44033, 44035, 43968, 44000, 44001, 
+    43996,     0, 32768, 40960, 43008, 44032, 44033, 44035, 
+    43968, 44000, 44001, 43996,     0, 32768, 40960, 43008, 
+    44032, 44033, 44035, 43968, 44000, 44001, 43996, 43998, 
+        0, 32768, 40960, 43008, 44032, 44033, 44035, 43968, 
+        0, 32768, 40960, 43008, 44032, 44033, 44035, 43968, 
+    44000,     0, 32768, 40960, 43008, 44032, 44033, 44035, 
+    43968, 44000,     0, 32768, 40960, 43008, 44032, 44033, 
+    44035, 43968, 44000, 44002,     0, 32768, 40960, 43008, 
+    44032, 44033, 44035, 43968, 44000,     0, 32768, 40960, 
+    43008, 44032, 44033, 44035, 43968, 44000, 44004,     0, 
+    32768, 40960, 43008, 44032, 44033, 44035, 43968, 44000, 
+    44004,     0, 32768, 40960, 43008, 44032, 44033, 44035, 
+    43968, 44000, 44008, 44006,     0, 32768, 40960, 43008, 
+    44032, 44033, 44035, 44039, 44000,     0, 32768, 40960, 
+    43008, 44032, 44033, 44035, 44039, 44000, 44008,     0, 
+    32768, 40960, 43008, 44032, 44033, 44035, 44039, 44000, 
+    44008,     0, 32768, 40960, 43008, 44032, 44033, 44035, 
+    44039, 44000, 44008, 44010,     0, 32768, 40960, 43008, 
+    44032, 44033, 44035, 44039, 44000, 44008,     0, 32768, 
+    40960, 43008, 44032, 44033, 44035, 44039, 44000, 44016, 
+    44012,     0, 32768, 40960, 43008, 44032, 44033, 44035, 
+    44039, 44000, 44016, 44012,     0, 32768, 40960, 43008, 
+    44032, 44033, 44035, 44039, 44000, 44016, 44017, 44014, 
+        0, 32768, 40960, 43008, 44032, 44033, 44035, 44039, 
+    44000,     0, 32768, 40960, 43008, 44032, 44033, 44035, 
+    44039, 44000, 44016,     0, 32768, 40960, 43008, 44032, 
+    44033, 44035, 44039, 44000, 44016,     0, 32768, 40960, 
+    43008, 44032, 44033, 44035, 44039, 44000, 44016, 44018, 
+        0, 32768, 40960, 43008, 44032, 44033, 44035, 44039, 
+    44000, 44016,     0, 32768, 40960, 43008, 44032, 44033, 
+    44035, 44039, 44000, 44016, 44020,     0, 32768, 40960, 
+    43008, 44032, 44033, 44035, 44039, 44000, 44016, 44020, 
+        0, 32768, 40960, 43008, 44032, 44033, 44035, 44039, 
+    44000, 44016, 44024, 44022,     0, 32768, 40960, 43008, 
+    44032, 44033, 44035, 44039, 44000, 44016,     0, 32768, 
+    40960, 43008, 44032, 44033, 44035, 44039, 44000, 44016, 
+    44024,     0, 32768, 40960, 43008, 44032, 44033, 44035, 
+    44039, 44000, 44016, 44024,     0, 32768, 40960, 43008, 
+    44032, 44033, 44035, 44039, 44000, 44016, 44024, 44026, 
+        0, 32768, 40960, 43008, 44032, 44033, 44035, 44039, 
+    44000, 44016, 44024,     0, 32768, 40960, 43008, 44032, 
+    44033, 44035, 44039, 44000, 44016, 44024, 44028,     0, 
+    32768, 40960, 43008, 44032, 44033, 44035, 44039, 44000, 
+    44016, 44024, 44028,     0, 32768, 40960, 43008, 44032, 
+    44033, 44035, 44039, 44000, 44016, 44024, 44028, 44030, 
+        0, 32768, 40960, 43008,     0, 32768, 40960, 43008, 
+    44032,     0, 32768, 40960, 43008, 44032,     0, 32768, 
+    40960, 43008, 44032, 44034,     0, 32768, 40960, 43008, 
+    44032,     0, 32768, 40960, 43008, 44032, 44036,     0, 
+    32768, 40960, 43008, 44032, 44036,     0, 32768, 40960, 
+    43008, 44032, 44040, 44038,     0, 32768, 40960, 43008, 
+    44032,     0, 32768, 40960, 43008, 44032, 44040,     0, 
+    32768, 40960, 43008, 44032, 44040,     0, 32768, 40960, 
+    43008, 44032, 44040, 44042,     0, 32768, 40960, 43008, 
+    44032, 44040,     0, 32768, 40960, 43008, 44032, 44048, 
+    44044,     0, 32768, 40960, 43008, 44032, 44048, 44044, 
+        0, 32768, 40960, 43008, 44032, 44048, 44049, 44046, 
+        0, 32768, 40960, 43008, 44032,     0, 32768, 40960, 
+    43008, 44032, 44048,     0, 32768, 40960, 43008, 44032, 
+    44048,     0, 32768, 40960, 43008, 44032, 44048, 44050, 
+        0, 32768, 40960, 43008, 44032, 44048,     0, 32768, 
+    40960, 43008, 44032, 44048, 44052,     0, 32768, 40960, 
+    43008, 44032, 44048, 44052,     0, 32768, 40960, 43008, 
+    44032, 44048, 44056, 44054,     0, 32768, 40960, 43008, 
+    44032, 44048,     0, 32768, 40960, 43008, 44032, 44064, 
+    44056,     0, 32768, 40960, 43008, 44032, 44064, 44056, 
+        0, 32768, 40960, 43008, 44032, 44064, 44056, 44058, 
+        0, 32768, 40960, 43008, 44032, 44064, 44056,     0, 
+    32768, 40960, 43008, 44032, 44064, 44065, 44060,     0, 
+    32768, 40960, 43008, 44032, 44064, 44065, 44060,     0, 
+    32768, 40960, 43008, 44032, 44064, 44065, 44060, 44062, 
+        0, 32768, 40960, 43008, 44032,     0, 32768, 40960, 
+    43008, 44032, 44064,     0, 32768, 40960, 43008, 44032, 
+    44064,     0, 32768, 40960, 43008, 44032, 44064, 44066, 
+        0, 32768, 40960, 43008, 44032, 44064,     0, 32768, 
+    40960, 43008, 44032, 44064, 44068,     0, 32768, 40960, 
+    43008, 44032, 44064, 44068,     0, 32768, 40960, 43008, 
+    44032, 44064, 44072, 44070,     0, 32768, 40960, 43008, 
+    44032, 44064,     0, 32768, 40960, 43008, 44032, 44064, 
+    44072,     0, 32768, 40960, 43008, 44032, 44064, 44072, 
+        0, 32768, 40960, 43008, 44032, 44064, 44072, 44074, 
+        0, 32768, 40960, 43008, 44032, 44064, 44072,     0, 
+    32768, 40960, 43008, 44032, 44064, 44080, 44076,     0, 
+    32768, 40960, 43008, 44032, 44064, 44080, 44076,     0, 
+    32768, 40960, 43008, 44032, 44064, 44080, 44081, 44078, 
+        0, 32768, 40960, 43008, 44032, 44064,     0, 32768, 
+    40960, 43008, 44032, 44096, 44080,     0, 32768, 40960, 
+    43008, 44032, 44096, 44080,     0, 32768, 40960, 43008, 
+    44032, 44096, 44080, 44082,     0, 32768, 40960, 43008, 
+    44032, 44096, 44080,     0, 32768, 40960, 43008, 44032, 
+    44096, 44080, 44084,     0, 32768, 40960, 43008, 44032, 
+    44096, 44080, 44084,     0, 32768, 40960, 43008, 44032, 
+    44096, 44080, 44088, 44086,     0, 32768, 40960, 43008, 
+    44032, 44096, 44080,     0, 32768, 40960, 43008, 44032, 
+    44096, 44097, 44088,     0, 32768, 40960, 43008, 44032, 
+    44096, 44097, 44088,     0, 32768, 40960, 43008, 44032, 
+    44096, 44097, 44088, 44090,     0, 32768, 40960, 43008, 
+    44032, 44096, 44097, 44088,     0, 32768, 40960, 43008, 
+    44032, 44096, 44097, 44088, 44092,     0, 32768, 40960, 
+    43008, 44032, 44096, 44097, 44099, 44092,     0, 32768, 
+    40960, 43008, 44032, 44096, 44097, 44099, 44092, 44094, 
+        0, 32768, 40960, 43008, 44032,     0, 32768, 40960, 
+    43008, 44032, 44096,     0, 32768, 40960, 43008, 44032, 
+    44096,     0, 32768, 40960, 43008, 44032, 44096, 44098, 
+        0, 32768, 40960, 43008, 44032, 44096,     0, 32768, 
+    40960, 43008, 44032, 44096, 44100,     0, 32768, 40960, 
+    43008, 44032, 44096, 44100,     0, 32768, 40960, 43008, 
+    44032, 44096, 44104, 44102,     0, 32768, 40960, 43008, 
+    44032, 44096,     0, 32768, 40960, 43008, 44032, 44096, 
+    44104,     0, 32768, 40960, 43008, 44032, 44096, 44104, 
+        0, 32768, 40960, 43008, 44032, 44096, 44104, 44106, 
+        0, 32768, 40960, 43008, 44032, 44096, 44104,     0, 
+    32768, 40960, 43008, 44032, 44096, 44112, 44108,     0, 
+    32768, 40960, 43008, 44032, 44096, 44112, 44108,     0, 
+    32768, 40960, 43008, 44032, 44096, 44112, 44113, 44110, 
+        0, 32768, 40960, 43008, 44032, 44096,     0, 32768, 
+    40960, 43008, 44032, 44096, 44112,     0, 32768, 40960, 
+    43008, 44032, 44096, 44112,     0, 32768, 40960, 43008, 
+    44032, 44096, 44112, 44114,     0, 32768, 40960, 43008, 
+    44032, 44096, 44112,     0, 32768, 40960, 43008, 44032, 
+    44096, 44112, 44116,     0, 32768, 40960, 43008, 44032, 
+    44096, 44112, 44116,     0, 32768, 40960, 43008, 44032, 
+    44096, 44112, 44120, 44118,     0, 32768, 40960, 43008, 
+    44032, 44096, 44112,     0, 32768, 40960, 43008, 44032, 
+    44096, 44128, 44120,     0, 32768, 40960, 43008, 44032, 
+    44096, 44128, 44120,     0, 32768, 40960, 43008, 44032, 
+    44096, 44128, 44120, 44122,     0, 32768, 40960, 43008, 
+    44032, 44096, 44128, 44120,     0, 32768, 40960, 43008, 
+    44032, 44096, 44128, 44129, 44124,     0, 32768, 40960, 
+    43008, 44032, 44096, 44128, 44129, 44124,     0, 32768, 
+    40960, 43008, 44032, 44096, 44128, 44129, 44124, 44126, 
+        0, 32768, 40960, 43008, 44032, 44096,     0, 32768, 
+    40960, 43008, 44032, 44160, 44128,     0, 32768, 40960, 
+    43008, 44032, 44160, 44128,     0, 32768, 40960, 43008, 
+    44032, 44160, 44128, 44130,     0, 32768, 40960, 43008, 
+    44032, 44160, 44128,     0, 32768, 40960, 43008, 44032, 
+    44160, 44128, 44132,     0, 32768, 40960, 43008, 44032, 
+    44160, 44128, 44132,     0, 32768, 40960, 43008, 44032, 
+    44160, 44128, 44136, 44134,     0, 32768, 40960, 43008, 
+    44032, 44160, 44128,     0, 32768, 40960, 43008, 44032, 
+    44160, 44128, 44136,     0, 32768, 40960, 43008, 44032, 
+    44160, 44128, 44136,     0, 32768, 40960, 43008, 44032, 
+    44160, 44128, 44136, 44138,     0, 32768, 40960, 43008, 
+    44032, 44160, 44128, 44136,     0, 32768, 40960, 43008, 
+    44032, 44160, 44128, 44144, 44140,     0, 32768, 40960, 
+    43008, 44032, 44160, 44128, 44144, 44140,     0, 32768, 
+    40960, 43008, 44032, 44160, 44128, 44144, 44145, 44142, 
+        0, 32768, 40960, 43008, 44032, 44160, 44128,     0, 
+    32768, 40960, 43008, 44032, 44160, 44161, 44144,     0, 
+    32768, 40960, 43008, 44032, 44160, 44161, 44144,     0, 
+    32768, 40960, 43008, 44032, 44160, 44161, 44144, 44146, 
+        0, 32768, 40960, 43008, 44032, 44160, 44161, 44144, 
+        0, 32768, 40960, 43008, 44032, 44160, 44161, 44144, 
+    44148,     0, 32768, 40960, 43008, 44032, 44160, 44161, 
+    44144, 44148,     0, 32768, 40960, 43008, 44032, 44160, 
+    44161, 44144, 44152, 44150,     0, 32768, 40960, 43008, 
+    44032, 44160, 44161, 44144,     0, 32768, 40960, 43008, 
+    44032, 44160, 44161, 44144, 44152,     0, 32768, 40960, 
+    43008, 44032, 44160, 44161, 44163, 44152,     0, 32768, 
+    40960, 43008, 44032, 44160, 44161, 44163, 44152, 44154, 
+        0, 32768, 40960, 43008, 44032, 44160, 44161, 44163, 
+    44152,     0, 32768, 40960, 43008, 44032, 44160, 44161, 
+    44163, 44152, 44156,     0, 32768, 40960, 43008, 44032, 
+    44160, 44161, 44163, 44152, 44156,     0, 32768, 40960, 
+    43008, 44032, 44160, 44161, 44163, 44152, 44156, 44158, 
+        0, 32768, 40960, 43008, 44032,     0, 32768, 40960, 
+    43008, 44032, 44160,     0, 32768, 40960, 43008, 44032, 
+    44160,     0, 32768, 40960, 43008, 44032, 44160, 44162, 
+        0, 32768, 40960, 43008, 44032, 44160,     0, 32768, 
+    40960, 43008, 44032, 44160, 44164,     0, 32768, 40960, 
+    43008, 44032, 44160, 44164,     0, 32768, 40960, 43008, 
+    44032, 44160, 44168, 44166,     0, 32768, 40960, 43008, 
+    44032, 44160,     0, 32768, 40960, 43008, 44032, 44160, 
+    44168,     0, 32768, 40960, 43008, 44032, 44160, 44168, 
+        0, 32768, 40960, 43008, 44032, 44160, 44168, 44170, 
+        0, 32768, 40960, 43008, 44032, 44160, 44168,     0, 
+    32768, 40960, 43008, 44032, 44160, 44176, 44172,     0, 
+    32768, 40960, 43008, 44032, 44160, 44176, 44172,     0, 
+    32768, 40960, 43008, 44032, 44160, 44176, 44177, 44174, 
+        0, 32768, 40960, 43008, 44032, 44160,     0, 32768, 
+    40960, 43008, 44032, 44160, 44176,     0, 32768, 40960, 
+    43008, 44032, 44160, 44176,     0, 32768, 40960, 43008, 
+    44032, 44160, 44176, 44178,     0, 32768, 40960, 43008, 
+    44032, 44160, 44176,     0, 32768, 40960, 43008, 44032, 
+    44160, 44176, 44180,     0, 32768, 40960, 43008, 44032, 
+    44160, 44176, 44180,     0, 32768, 40960, 43008, 44032, 
+    44160, 44176, 44184, 44182,     0, 32768, 40960, 43008, 
+    44032, 44160, 44176,     0, 32768, 40960, 43008, 44032, 
+    44160, 44192, 44184,     0, 32768, 40960, 43008, 44032, 
+    44160, 44192, 44184,     0, 32768, 40960, 43008, 44032, 
+    44160, 44192, 44184, 44186,     0, 32768, 40960, 43008, 
+    44032, 44160, 44192, 44184,     0, 32768, 40960, 43008, 
+    44032, 44160, 44192, 44193, 44188,     0, 32768, 40960, 
+    43008, 44032, 44160, 44192, 44193, 44188,     0, 32768, 
+    40960, 43008, 44032, 44160, 44192, 44193, 44188, 44190, 
+        0, 32768, 40960, 43008, 44032, 44160,     0, 32768, 
+    40960, 43008, 44032, 44160, 44192,     0, 32768, 40960, 
+    43008, 44032, 44160, 44192,     0, 32768, 40960, 43008, 
+    44032, 44160, 44192, 44194,     0, 32768, 40960, 43008, 
+    44032, 44160, 44192,     0, 32768, 40960, 43008, 44032, 
+    44160, 44192, 44196,     0, 32768, 40960, 43008, 44032, 
+    44160, 44192, 44196,     0, 32768, 40960, 43008, 44032, 
+    44160, 44192, 44200, 44198,     0, 32768, 40960, 43008, 
+    44032, 44160, 44192,     0, 32768, 40960, 43008, 44032, 
+    44160, 44192, 44200,     0, 32768, 40960, 43008, 44032, 
+    44160, 44192, 44200,     0, 32768, 40960, 43008, 44032, 
+    44160, 44192, 44200, 44202,     0, 32768, 40960, 43008, 
+    44032, 44160, 44192, 44200,     0, 32768, 40960, 43008, 
+    44032, 44160, 44192, 44208, 44204,     0, 32768, 40960, 
+    43008, 44032, 44160, 44192, 44208, 44204,     0, 32768, 
+    40960, 43008, 44032, 44160, 44192, 44208, 44209, 44206, 
+        0, 32768, 40960, 43008, 44032, 44160, 44192,     0, 
+    32768, 40960, 43008, 44032, 44160, 44224, 44208,     0, 
+    32768, 40960, 43008, 44032, 44160, 44224, 44208,     0, 
+    32768, 40960, 43008, 44032, 44160, 44224, 44208, 44210, 
+        0, 32768, 40960, 43008, 44032, 44160, 44224, 44208, 
+        0, 32768, 40960, 43008, 44032, 44160, 44224, 44208, 
+    44212,     0, 32768, 40960, 43008, 44032, 44160, 44224, 
+    44208, 44212,     0, 32768, 40960, 43008, 44032, 44160, 
+    44224, 44208, 44216, 44214,     0, 32768, 40960, 43008, 
+    44032, 44160, 44224, 44208,     0, 32768, 40960, 43008, 
+    44032, 44160, 44224, 44225, 44216,     0, 32768, 40960, 
+    43008, 44032, 44160, 44224, 44225, 44216,     0, 32768, 
+    40960, 43008, 44032, 44160, 44224, 44225, 44216, 44218, 
+        0, 32768, 40960, 43008, 44032, 44160, 44224, 44225, 
+    44216,     0, 32768, 40960, 43008, 44032, 44160, 44224, 
+    44225, 44216, 44220,     0, 32768, 40960, 43008, 44032, 
+    44160, 44224, 44225, 44227, 44220,     0, 32768, 40960, 
+    43008, 44032, 44160, 44224, 44225, 44227, 44220, 44222, 
+        0, 32768, 40960, 43008, 44032, 44160,     0, 32768, 
+    40960, 43008, 44032, 44288, 44224,     0, 32768, 40960, 
+    43008, 44032, 44288, 44224,     0, 32768, 40960, 43008, 
+    44032, 44288, 44224, 44226,     0, 32768, 40960, 43008, 
+    44032, 44288, 44224,     0, 32768, 40960, 43008, 44032, 
+    44288, 44224, 44228,     0, 32768, 40960, 43008, 44032, 
+    44288, 44224, 44228,     0, 32768, 40960, 43008, 44032, 
+    44288, 44224, 44232, 44230,     0, 32768, 40960, 43008, 
+    44032, 44288, 44224,     0, 32768, 40960, 43008, 44032, 
+    44288, 44224, 44232,     0, 32768, 40960, 43008, 44032, 
+    44288, 44224, 44232,     0, 32768, 40960, 43008, 44032, 
+    44288, 44224, 44232, 44234,     0, 32768, 40960, 43008, 
+    44032, 44288, 44224, 44232,     0, 32768, 40960, 43008, 
+    44032, 44288, 44224, 44240, 44236,     0, 32768, 40960, 
+    43008, 44032, 44288, 44224, 44240, 44236,     0, 32768, 
+    40960, 43008, 44032, 44288, 44224, 44240, 44241, 44238, 
+        0, 32768, 40960, 43008, 44032, 44288, 44224,     0, 
+    32768, 40960, 43008, 44032, 44288, 44224, 44240,     0, 
+    32768, 40960, 43008, 44032, 44288, 44224, 44240,     0, 
+    32768, 40960, 43008, 44032, 44288, 44224, 44240, 44242, 
+        0, 32768, 40960, 43008, 44032, 44288, 44224, 44240, 
+        0, 32768, 40960, 43008, 44032, 44288, 44224, 44240, 
+    44244,     0, 32768, 40960, 43008, 44032, 44288, 44224, 
+    44240, 44244,     0, 32768, 40960, 43008, 44032, 44288, 
+    44224, 44240, 44248, 44246,     0, 32768, 40960, 43008, 
+    44032, 44288, 44224, 44240,     0, 32768, 40960, 43008, 
+    44032, 44288, 44224, 44256, 44248,     0, 32768, 40960, 
+    43008, 44032, 44288, 44224, 44256, 44248,     0, 32768, 
+    40960, 43008, 44032, 44288, 44224, 44256, 44248, 44250, 
+        0, 32768, 40960, 43008, 44032, 44288, 44224, 44256, 
+    44248,     0, 32768, 40960, 43008, 44032, 44288, 44224, 
+    44256, 44257, 44252,     0, 32768, 40960, 43008, 44032, 
+    44288, 44224, 44256, 44257, 44252,     0, 32768, 40960, 
+    43008, 44032, 44288, 44224, 44256, 44257, 44252, 44254, 
+        0, 32768, 40960, 43008, 44032, 44288, 44224,     0, 
+    32768, 40960, 43008, 44032, 44288, 44289, 44256,     0, 
+    32768, 40960, 43008, 44032, 44288, 44289, 44256,     0, 
+    32768, 40960, 43008, 44032, 44288, 44289, 44256, 44258, 
+        0, 32768, 40960, 43008, 44032, 44288, 44289, 44256, 
+        0, 32768, 40960, 43008, 44032, 44288, 44289, 44256, 
+    44260,     0, 32768, 40960, 43008, 44032, 44288, 44289, 
+    44256, 44260,     0, 32768, 40960, 43008, 44032, 44288, 
+    44289, 44256, 44264, 44262,     0, 32768, 40960, 43008, 
+    44032, 44288, 44289, 44256,     0, 32768, 40960, 43008, 
+    44032, 44288, 44289, 44256, 44264,     0, 32768, 40960, 
+    43008, 44032, 44288, 44289, 44256, 44264,     0, 32768, 
+    40960, 43008, 44032, 44288, 44289, 44256, 44264, 44266, 
+        0, 32768, 40960, 43008, 44032, 44288, 44289, 44256, 
+    44264,     0, 32768, 40960, 43008, 44032, 44288, 44289, 
+    44256, 44272, 44268,     0, 32768, 40960, 43008, 44032, 
+    44288, 44289, 44256, 44272, 44268,     0, 32768, 40960, 
+    43008, 44032, 44288, 44289, 44256, 44272, 44273, 44270, 
+        0, 32768, 40960, 43008, 44032, 44288, 44289, 44256, 
+        0, 32768, 40960, 43008, 44032, 44288, 44289, 44256, 
+    44272,     0, 32768, 40960, 43008, 44032, 44288, 44289, 
+    44291, 44272,     0, 32768, 40960, 43008, 44032, 44288, 
+    44289, 44291, 44272, 44274,     0, 32768, 40960, 43008, 
+    44032, 44288, 44289, 44291, 44272,     0, 32768, 40960, 
+    43008, 44032, 44288, 44289, 44291, 44272, 44276,     0, 
+    32768, 40960, 43008, 44032, 44288, 44289, 44291, 44272, 
+    44276,     0, 32768, 40960, 43008, 44032, 44288, 44289, 
+    44291, 44272, 44280, 44278,     0, 32768, 40960, 43008, 
+    44032, 44288, 44289, 44291, 44272,     0, 32768, 40960, 
+    43008, 44032, 44288, 44289, 44291, 44272, 44280,     0, 
+    32768, 40960, 43008, 44032, 44288, 44289, 44291, 44272, 
+    44280,     0, 32768, 40960, 43008, 44032, 44288, 44289, 
+    44291, 44272, 44280, 44282,     0, 32768, 40960, 43008, 
+    44032, 44288, 44289, 44291, 44295, 44280,     0, 32768, 
+    40960, 43008, 44032, 44288, 44289, 44291, 44295, 44280, 
+    44284,     0, 32768, 40960, 43008, 44032, 44288, 44289, 
+    44291, 44295, 44280, 44284,     0, 32768, 40960, 43008, 
+    44032, 44288, 44289, 44291, 44295, 44280, 44284, 44286, 
+        0, 32768, 40960, 43008, 44032,     0, 32768, 40960, 
+    45056, 44032, 44288,     0, 32768, 40960, 45056, 44032, 
+    44288,     0, 32768, 40960, 45056, 44032, 44288, 44290, 
+        0, 32768, 40960, 45056, 44032, 44288,     0, 32768, 
+    40960, 45056, 44032, 44288, 44292,     0, 32768, 40960, 
+    45056, 44032, 44288, 44292,     0, 32768, 40960, 45056, 
+    44032, 44288, 44296, 44294,     0, 32768, 40960, 45056, 
+    44032, 44288,     0, 32768, 40960, 45056, 44032, 44288, 
+    44296,     0, 32768, 40960, 45056, 44032, 44288, 44296, 
+        0, 32768, 40960, 45056, 44032, 44288, 44296, 44298, 
+        0, 32768, 40960, 45056, 44032, 44288, 44296,     0, 
+    32768, 40960, 45056, 44032, 44288, 44304, 44300,     0, 
+    32768, 40960, 45056, 44032, 44288, 44304, 44300,     0, 
+    32768, 40960, 45056, 44032, 44288, 44304, 44305, 44302, 
+        0, 32768, 40960, 45056, 44032, 44288,     0, 32768, 
+    40960, 45056, 44032, 44288, 44304,     0, 32768, 40960, 
+    45056, 44032, 44288, 44304,     0, 32768, 40960, 45056, 
+    44032, 44288, 44304, 44306,     0, 32768, 40960, 45056, 
+    44032, 44288, 44304,     0, 32768, 40960, 45056, 44032, 
+    44288, 44304, 44308,     0, 32768, 40960, 45056, 44032, 
+    44288, 44304, 44308,     0, 32768, 40960, 45056, 44032, 
+    44288, 44304, 44312, 44310,     0, 32768, 40960, 45056, 
+    44032, 44288, 44304,     0, 32768, 40960, 45056, 44032, 
+    44288, 44320, 44312,     0, 32768, 40960, 45056, 44032, 
+    44288, 44320, 44312,     0, 32768, 40960, 45056, 44032, 
+    44288, 44320, 44312, 44314,     0, 32768, 40960, 45056, 
+    44032, 44288, 44320, 44312,     0, 32768, 40960, 45056, 
+    44032, 44288, 44320, 44321, 44316,     0, 32768, 40960, 
+    45056, 44032, 44288, 44320, 44321, 44316,     0, 32768, 
+    40960, 45056, 44032, 44288, 44320, 44321, 44316, 44318, 
+        0, 32768, 40960, 45056, 44032, 44288,     0, 32768, 
+    40960, 45056, 44032, 44288, 44320,     0, 32768, 40960, 
+    45056, 44032, 44288, 44320,     0, 32768, 40960, 45056, 
+    44032, 44288, 44320, 44322,     0, 32768, 40960, 45056, 
+    44032, 44288, 44320,     0, 32768, 40960, 45056, 44032, 
+    44288, 44320, 44324,     0, 32768, 40960, 45056, 44032, 
+    44288, 44320, 44324,     0, 32768, 40960, 45056, 44032, 
+    44288, 44320, 44328, 44326,     0, 32768, 40960, 45056, 
+    44032, 44288, 44320,     0, 32768, 40960, 45056, 44032, 
+    44288, 44320, 44328,     0, 32768, 40960, 45056, 44032, 
+    44288, 44320, 44328,     0, 32768, 40960, 45056, 44032, 
+    44288, 44320, 44328, 44330,     0, 32768, 40960, 45056, 
+    44032, 44288, 44320, 44328,     0, 32768, 40960, 45056, 
+    44032, 44288, 44320, 44336, 44332,     0, 32768, 40960, 
+    45056, 44032, 44288, 44320, 44336, 44332,     0, 32768, 
+    40960, 45056, 44032, 44288, 44320, 44336, 44337, 44334, 
+        0, 32768, 40960, 45056, 44032, 44288, 44320,     0, 
+    32768, 40960, 45056, 44032, 44288, 44352, 44336,     0, 
+    32768, 40960, 45056, 44032, 44288, 44352, 44336,     0, 
+    32768, 40960, 45056, 44032, 44288, 44352, 44336, 44338, 
+        0, 32768, 40960, 45056, 44032, 44288, 44352, 44336, 
+        0, 32768, 40960, 45056, 44032, 44288, 44352, 44336, 
+    44340,     0, 32768, 40960, 45056, 44032, 44288, 44352, 
+    44336, 44340,     0, 32768, 40960, 45056, 44032, 44288, 
+    44352, 44336, 44344, 44342,     0, 32768, 40960, 45056, 
+    44032, 44288, 44352, 44336,     0, 32768, 40960, 45056, 
+    44032, 44288, 44352, 44353, 44344,     0, 32768, 40960, 
+    45056, 44032, 44288, 44352, 44353, 44344,     0, 32768, 
+    40960, 45056, 44032, 44288, 44352, 44353, 44344, 44346, 
+        0, 32768, 40960, 45056, 44032, 44288, 44352, 44353, 
+    44344,     0, 32768, 40960, 45056, 44032, 44288, 44352, 
+    44353, 44344, 44348,     0, 32768, 40960, 45056, 44032, 
+    44288, 44352, 44353, 44355, 44348,     0, 32768, 40960, 
+    45056, 44032, 44288, 44352, 44353, 44355, 44348, 44350, 
+        0, 32768, 40960, 45056, 44032, 44288,     0, 32768, 
+    40960, 45056, 44032, 44288, 44352,     0, 32768, 40960, 
+    45056, 44032, 44288, 44352,     0, 32768, 40960, 45056, 
+    44032, 44288, 44352, 44354,     0, 32768, 40960, 45056, 
+    44032, 44288, 44352,     0, 32768, 40960, 45056, 44032, 
+    44288, 44352, 44356,     0, 32768, 40960, 45056, 44032, 
+    44288, 44352, 44356,     0, 32768, 40960, 45056, 44032, 
+    44288, 44352, 44360, 44358,     0, 32768, 40960, 45056, 
+    44032, 44288, 44352,     0, 32768, 40960, 45056, 44032, 
+    44288, 44352, 44360,     0, 32768, 40960, 45056, 44032, 
+    44288, 44352, 44360,     0, 32768, 40960, 45056, 44032, 
+    44288, 44352, 44360, 44362,     0, 32768, 40960, 45056, 
+    44032, 44288, 44352, 44360,     0, 32768, 40960, 45056, 
+    44032, 44288, 44352, 44368, 44364,     0, 32768, 40960, 
+    45056, 44032, 44288, 44352, 44368, 44364,     0, 32768, 
+    40960, 45056, 44032, 44288, 44352, 44368, 44369, 44366, 
+        0, 32768, 40960, 45056, 44032, 44288, 44352,     0, 
+    32768, 40960, 45056, 44032, 44288, 44352, 44368,     0, 
+    32768, 40960, 45056, 44032, 44288, 44352, 44368,     0, 
+    32768, 40960, 45056, 44032, 44288, 44352, 44368, 44370, 
+        0, 32768, 40960, 45056, 44032, 44288, 44352, 44368, 
+        0, 32768, 40960, 45056, 44032, 44288, 44352, 44368, 
+    44372,     0, 32768, 40960, 45056, 44032, 44288, 44352, 
+    44368, 44372,     0, 32768, 40960, 45056, 44032, 44288, 
+    44352, 44368, 44376, 44374,     0, 32768, 40960, 45056, 
+    44032, 44288, 44352, 44368,     0, 32768, 40960, 45056, 
+    44032, 44288, 44352, 44384, 44376,     0, 32768, 40960, 
+    45056, 44032, 44288, 44352, 44384, 44376,     0, 32768, 
+    40960, 45056, 44032, 44288, 44352, 44384, 44376, 44378, 
+        0, 32768, 40960, 45056, 44032, 44288, 44352, 44384, 
+    44376,     0, 32768, 40960, 45056, 44032, 44288, 44352, 
+    44384, 44385, 44380,     0, 32768, 40960, 45056, 44032, 
+    44288, 44352, 44384, 44385, 44380,     0, 32768, 40960, 
+    45056, 44032, 44288, 44352, 44384, 44385, 44380, 44382, 
+        0, 32768, 40960, 45056, 44032, 44288, 44352,     0, 
+    32768, 40960, 45056, 44032, 44288, 44416, 44384,     0, 
+    32768, 40960, 45056, 44032, 44288, 44416, 44384,     0, 
+    32768, 40960, 45056, 44032, 44288, 44416, 44384, 44386, 
+        0, 32768, 40960, 45056, 44032, 44288, 44416, 44384, 
+        0, 32768, 40960, 45056, 44032, 44288, 44416, 44384, 
+    44388,     0, 32768, 40960, 45056, 44032, 44288, 44416, 
+    44384, 44388,     0, 32768, 40960, 45056, 44032, 44288, 
+    44416, 44384, 44392, 44390,     0, 32768, 40960, 45056, 
+    44032, 44288, 44416, 44384,     0, 32768, 40960, 45056, 
+    44032, 44288, 44416, 44384, 44392,     0, 32768, 40960, 
+    45056, 44032, 44288, 44416, 44384, 44392,     0, 32768, 
+    40960, 45056, 44032, 44288, 44416, 44384, 44392, 44394, 
+        0, 32768, 40960, 45056, 44032, 44288, 44416, 44384, 
+    44392,     0, 32768, 40960, 45056, 44032, 44288, 44416, 
+    44384, 44400, 44396,     0, 32768, 40960, 45056, 44032, 
+    44288, 44416, 44384, 44400, 44396,     0, 32768, 40960, 
+    45056, 44032, 44288, 44416, 44384, 44400, 44401, 44398, 
+        0, 32768, 40960, 45056, 44032, 44288, 44416, 44384, 
+        0, 32768, 40960, 45056, 44032, 44288, 44416, 44417, 
+    44400,     0, 32768, 40960, 45056, 44032, 44288, 44416, 
+    44417, 44400,     0, 32768, 40960, 45056, 44032, 44288, 
+    44416, 44417, 44400, 44402,     0, 32768, 40960, 45056, 
+    44032, 44288, 44416, 44417, 44400,     0, 32768, 40960, 
+    45056, 44032, 44288, 44416, 44417, 44400, 44404,     0, 
+    32768, 40960, 45056, 44032, 44288, 44416, 44417, 44400, 
+    44404,     0, 32768, 40960, 45056, 44032, 44288, 44416, 
+    44417, 44400, 44408, 44406,     0, 32768, 40960, 45056, 
+    44032, 44288, 44416, 44417, 44400,     0, 32768, 40960, 
+    45056, 44032, 44288, 44416, 44417, 44400, 44408,     0, 
+    32768, 40960, 45056, 44032, 44288, 44416, 44417, 44419, 
+    44408,     0, 32768, 40960, 45056, 44032, 44288, 44416, 
+    44417, 44419, 44408, 44410,     0, 32768, 40960, 45056, 
+    44032, 44288, 44416, 44417, 44419, 44408,     0, 32768, 
+    40960, 45056, 44032, 44288, 44416, 44417, 44419, 44408, 
+    44412,     0, 32768, 40960, 45056, 44032, 44288, 44416, 
+    44417, 44419, 44408, 44412,     0, 32768, 40960, 45056, 
+    44032, 44288, 44416, 44417, 44419, 44408, 44412, 44414, 
+        0, 32768, 40960, 45056, 44032, 44288,     0, 32768, 
+    40960, 45056, 44032, 44544, 44416,     0, 32768, 40960, 
+    45056, 44032, 44544, 44416,     0, 32768, 40960, 45056, 
+    44032, 44544, 44416, 44418,     0, 32768, 40960, 45056, 
+    44032, 44544, 44416,     0, 32768, 40960, 45056, 44032, 
+    44544, 44416, 44420,     0, 32768, 40960, 45056, 44032, 
+    44544, 44416, 44420,     0, 32768, 40960, 45056, 44032, 
+    44544, 44416, 44424, 44422,     0, 32768, 40960, 45056, 
+    44032, 44544, 44416,     0, 32768, 40960, 45056, 44032, 
+    44544, 44416, 44424,     0, 32768, 40960, 45056, 44032, 
+    44544, 44416, 44424,     0, 32768, 40960, 45056, 44032, 
+    44544, 44416, 44424, 44426,     0, 32768, 40960, 45056, 
+    44032, 44544, 44416, 44424,     0, 32768, 40960, 45056, 
+    44032, 44544, 44416, 44432, 44428,     0, 32768, 40960, 
+    45056, 44032, 44544, 44416, 44432, 44428,     0, 32768, 
+    40960, 45056, 44032, 44544, 44416, 44432, 44433, 44430, 
+        0, 32768, 40960, 45056, 44032, 44544, 44416,     0, 
+    32768, 40960, 45056, 44032, 44544, 44416, 44432,     0, 
+    32768, 40960, 45056, 44032, 44544, 44416, 44432,     0, 
+    32768, 40960, 45056, 44032, 44544, 44416, 44432, 44434, 
+        0, 32768, 40960, 45056, 44032, 44544, 44416, 44432, 
+        0, 32768, 40960, 45056, 44032, 44544, 44416, 44432, 
+    44436,     0, 32768, 40960, 45056, 44032, 44544, 44416, 
+    44432, 44436,     0, 32768, 40960, 45056, 44032, 44544, 
+    44416, 44432, 44440, 44438,     0, 32768, 40960, 45056, 
+    44032, 44544, 44416, 44432,     0, 32768, 40960, 45056, 
+    44032, 44544, 44416, 44448, 44440,     0, 32768, 40960, 
+    45056, 44032, 44544, 44416, 44448, 44440,     0, 32768, 
+    40960, 45056, 44032, 44544, 44416, 44448, 44440, 44442, 
+        0, 32768, 40960, 45056, 44032, 44544, 44416, 44448, 
+    44440,     0, 32768, 40960, 45056, 44032, 44544, 44416, 
+    44448, 44449, 44444,     0, 32768, 40960, 45056, 44032, 
+    44544, 44416, 44448, 44449, 44444,     0, 32768, 40960, 
+    45056, 44032, 44544, 44416, 44448, 44449, 44444, 44446, 
+        0, 32768, 40960, 45056, 44032, 44544, 44416,     0, 
+    32768, 40960, 45056, 44032, 44544, 44416, 44448,     0, 
+    32768, 40960, 45056, 44032, 44544, 44416, 44448,     0, 
+    32768, 40960, 45056, 44032, 44544, 44416, 44448, 44450, 
+        0, 32768, 40960, 45056, 44032, 44544, 44416, 44448, 
+        0, 32768, 40960, 45056, 44032, 44544, 44416, 44448, 
+    44452,     0, 32768, 40960, 45056, 44032, 44544, 44416, 
+    44448, 44452,     0, 32768, 40960, 45056, 44032, 44544, 
+    44416, 44448, 44456, 44454,     0, 32768, 40960, 45056, 
+    44032, 44544, 44416, 44448,     0, 32768, 40960, 45056, 
+    44032, 44544, 44416, 44448, 44456,     0, 32768, 40960, 
+    45056, 44032, 44544, 44416, 44448, 44456,     0, 32768, 
+    40960, 45056, 44032, 44544, 44416, 44448, 44456, 44458, 
+        0, 32768, 40960, 45056, 44032, 44544, 44416, 44448, 
+    44456,     0, 32768, 40960, 45056, 44032, 44544, 44416, 
+    44448, 44464, 44460,     0, 32768, 40960, 45056, 44032, 
+    44544, 44416, 44448, 44464, 44460,     0, 32768, 40960, 
+    45056, 44032, 44544, 44416, 44448, 44464, 44465, 44462, 
+        0, 32768, 40960, 45056, 44032, 44544, 44416, 44448, 
+        0, 32768, 40960, 45056, 44032, 44544, 44416, 44480, 
+    44464,     0, 32768, 40960, 45056, 44032, 44544, 44416, 
+    44480, 44464,     0, 32768, 40960, 45056, 44032, 44544, 
+    44416, 44480, 44464, 44466,     0, 32768, 40960, 45056, 
+    44032, 44544, 44416, 44480, 44464,     0, 32768, 40960, 
+    45056, 44032, 44544, 44416, 44480, 44464, 44468,     0, 
+    32768, 40960, 45056, 44032, 44544, 44416, 44480, 44464, 
+    44468,     0, 32768, 40960, 45056, 44032, 44544, 44416, 
+    44480, 44464, 44472, 44470,     0, 32768, 40960, 45056, 
+    44032, 44544, 44416, 44480, 44464,     0, 32768, 40960, 
+    45056, 44032, 44544, 44416, 44480, 44481, 44472,     0, 
+    32768, 40960, 45056, 44032, 44544, 44416, 44480, 44481, 
+    44472,     0, 32768, 40960, 45056, 44032, 44544, 44416, 
+    44480, 44481, 44472, 44474,     0, 32768, 40960, 45056, 
+    44032, 44544, 44416, 44480, 44481, 44472,     0, 32768, 
+    40960, 45056, 44032, 44544, 44416, 44480, 44481, 44472, 
+    44476,     0, 32768, 40960, 45056, 44032, 44544, 44416, 
+    44480, 44481, 44483, 44476,     0, 32768, 40960, 45056, 
+    44032, 44544, 44416, 44480, 44481, 44483, 44476, 44478, 
+        0, 32768, 40960, 45056, 44032, 44544, 44416,     0, 
+    32768, 40960, 45056, 44032, 44544, 44545, 44480,     0, 
+    32768, 40960, 45056, 44032, 44544, 44545, 44480,     0, 
+    32768, 40960, 45056, 44032, 44544, 44545, 44480, 44482, 
+        0, 32768, 40960, 45056, 44032, 44544, 44545, 44480, 
+        0, 32768, 40960, 45056, 44032, 44544, 44545, 44480, 
+    44484,     0, 32768, 40960, 45056, 44032, 44544, 44545, 
+    44480, 44484,     0, 32768, 40960, 45056, 44032, 44544, 
+    44545, 44480, 44488, 44486,     0, 32768, 40960, 45056, 
+    44032, 44544, 44545, 44480,     0, 32768, 40960, 45056, 
+    44032, 44544, 44545, 44480, 44488,     0, 32768, 40960, 
+    45056, 44032, 44544, 44545, 44480, 44488,     0, 32768, 
+    40960, 45056, 44032, 44544, 44545, 44480, 44488, 44490, 
+        0, 32768, 40960, 45056, 44032, 44544, 44545, 44480, 
+    44488,     0, 32768, 40960, 45056, 44032, 44544, 44545, 
+    44480, 44496, 44492,     0, 32768, 40960, 45056, 44032, 
+    44544, 44545, 44480, 44496, 44492,     0, 32768, 40960, 
+    45056, 44032, 44544, 44545, 44480, 44496, 44497, 44494, 
+        0, 32768, 40960, 45056, 44032, 44544, 44545, 44480, 
+        0, 32768, 40960, 45056, 44032, 44544, 44545, 44480, 
+    44496,     0, 32768, 40960, 45056, 44032, 44544, 44545, 
+    44480, 44496,     0, 32768, 40960, 45056, 44032, 44544, 
+    44545, 44480, 44496, 44498,     0, 32768, 40960, 45056, 
+    44032, 44544, 44545, 44480, 44496,     0, 32768, 40960, 
+    45056, 44032, 44544, 44545, 44480, 44496, 44500,     0, 
+    32768, 40960, 45056, 44032, 44544, 44545, 44480, 44496, 
+    44500,     0, 32768, 40960, 45056, 44032, 44544, 44545, 
+    44480, 44496, 44504, 44502,     0, 32768, 40960, 45056, 
+    44032, 44544, 44545, 44480, 44496,     0, 32768, 40960, 
+    45056, 44032, 44544, 44545, 44480, 44512, 44504,     0, 
+    32768, 40960, 45056, 44032, 44544, 44545, 44480, 44512, 
+    44504,     0, 32768, 40960, 45056, 44032, 44544, 44545, 
+    44480, 44512, 44504, 44506,     0, 32768, 40960, 45056, 
+    44032, 44544, 44545, 44480, 44512, 44504,     0, 32768, 
+    40960, 45056, 44032, 44544, 44545, 44480, 44512, 44513, 
+    44508,     0, 32768, 40960, 45056, 44032, 44544, 44545, 
+    44480, 44512, 44513, 44508,     0, 32768, 40960, 45056, 
+    44032, 44544, 44545, 44480, 44512, 44513, 44508, 44510, 
+        0, 32768, 40960, 45056, 44032, 44544, 44545, 44480, 
+        0, 32768, 40960, 45056, 44032, 44544, 44545, 44480, 
+    44512,     0, 32768, 40960, 45056, 44032, 44544, 44545, 
+    44547, 44512,     0, 32768, 40960, 45056, 44032, 44544, 
+    44545, 44547, 44512, 44514,     0, 32768, 40960, 45056, 
+    44032, 44544, 44545, 44547, 44512,     0, 32768, 40960, 
+    45056, 44032, 44544, 44545, 44547, 44512, 44516,     0, 
+    32768, 40960, 45056, 44032, 44544, 44545, 44547, 44512, 
+    44516,     0, 32768, 40960, 45056, 44032, 44544, 44545, 
+    44547, 44512, 44520, 44518,     0, 32768, 40960, 45056, 
+    44032, 44544, 44545, 44547, 44512,     0, 32768, 40960, 
+    45056, 44032, 44544, 44545, 44547, 44512, 44520,     0, 
+    32768, 40960, 45056, 44032, 44544, 44545, 44547, 44512, 
+    44520,     0, 32768, 40960, 45056, 44032, 44544, 44545, 
+    44547, 44512, 44520, 44522,     0, 32768, 40960, 45056, 
+    44032, 44544, 44545, 44547, 44512, 44520,     0, 32768, 
+    40960, 45056, 44032, 44544, 44545, 44547, 44512, 44528, 
+    44524,     0, 32768, 40960, 45056, 44032, 44544, 44545, 
+    44547, 44512, 44528, 44524,     0, 32768, 40960, 45056, 
+    44032, 44544, 44545, 44547, 44512, 44528, 44529, 44526, 
+        0, 32768, 40960, 45056, 44032, 44544, 44545, 44547, 
+    44512,     0, 32768, 40960, 45056, 44032, 44544, 44545, 
+    44547, 44512, 44528,     0, 32768, 40960, 45056, 44032, 
+    44544, 44545, 44547, 44512, 44528,     0, 32768, 40960, 
+    45056, 44032, 44544, 44545, 44547, 44512, 44528, 44530, 
+        0, 32768, 40960, 45056, 44032, 44544, 44545, 44547, 
+    44551, 44528,     0, 32768, 40960, 45056, 44032, 44544, 
+    44545, 44547, 44551, 44528, 44532,     0, 32768, 40960, 
+    45056, 44032, 44544, 44545, 44547, 44551, 44528, 44532, 
+        0, 32768, 40960, 45056, 44032, 44544, 44545, 44547, 
+    44551, 44528, 44536, 44534,     0, 32768, 40960, 45056, 
+    44032, 44544, 44545, 44547, 44551, 44528,     0, 32768, 
+    40960, 45056, 44032, 44544, 44545, 44547, 44551, 44528, 
+    44536,     0, 32768, 40960, 45056, 44032, 44544, 44545, 
+    44547, 44551, 44528, 44536,     0, 32768, 40960, 45056, 
+    44032, 44544, 44545, 44547, 44551, 44528, 44536, 44538, 
+        0, 32768, 40960, 45056, 44032, 44544, 44545, 44547, 
+    44551, 44528, 44536,     0, 32768, 40960, 45056, 44032, 
+    44544, 44545, 44547, 44551, 44528, 44536, 44540,     0, 
+    32768, 40960, 45056, 44032, 44544, 44545, 44547, 44551, 
+    44528, 44536, 44540,     0, 32768, 40960, 45056, 44032, 
+    44544, 44545, 44547, 44551, 44528, 44536, 44540, 44542, 
+        0, 32768, 40960, 45056, 44032,     0, 32768, 40960, 
+    45056, 44032, 44544,     0, 32768, 40960, 45056, 45057, 
+    44544,     0, 32768, 40960, 45056, 45057, 44544, 44546, 
+        0, 32768, 40960, 45056, 45057, 44544,     0, 32768, 
+    40960, 45056, 45057, 44544, 44548,     0, 32768, 40960, 
+    45056, 45057, 44544, 44548,     0, 32768, 40960, 45056, 
+    45057, 44544, 44552, 44550,     0, 32768, 40960, 45056, 
+    45057, 44544,     0, 32768, 40960, 45056, 45057, 44544, 
+    44552,     0, 32768, 40960, 45056, 45057, 44544, 44552, 
+        0, 32768, 40960, 45056, 45057, 44544, 44552, 44554, 
+        0, 32768, 40960, 45056, 45057, 44544, 44552,     0, 
+    32768, 40960, 45056, 45057, 44544, 44560, 44556,     0, 
+    32768, 40960, 45056, 45057, 44544, 44560, 44556,     0, 
+    32768, 40960, 45056, 45057, 44544, 44560, 44561, 44558, 
+        0, 32768, 40960, 45056, 45057, 44544,     0, 32768, 
+    40960, 45056, 45057, 44544, 44560,     0, 32768, 40960, 
+    45056, 45057, 44544, 44560,     0, 32768, 40960, 45056, 
+    45057, 44544, 44560, 44562,     0, 32768, 40960, 45056, 
+    45057, 44544, 44560,     0, 32768, 40960, 45056, 45057, 
+    44544, 44560, 44564,     0, 32768, 40960, 45056, 45057, 
+    44544, 44560, 44564,     0, 32768, 40960, 45056, 45057, 
+    44544, 44560, 44568, 44566,     0, 32768, 40960, 45056, 
+    45057, 44544, 44560,     0, 32768, 40960, 45056, 45057, 
+    44544, 44576, 44568,     0, 32768, 40960, 45056, 45057, 
+    44544, 44576, 44568,     0, 32768, 40960, 45056, 45057, 
+    44544, 44576, 44568, 44570,     0, 32768, 40960, 45056, 
+    45057, 44544, 44576, 44568,     0, 32768, 40960, 45056, 
+    45057, 44544, 44576, 44577, 44572,     0, 32768, 40960, 
+    45056, 45057, 44544, 44576, 44577, 44572,     0, 32768, 
+    40960, 45056, 45057, 44544, 44576, 44577, 44572, 44574, 
+        0, 32768, 40960, 45056, 45057, 44544,     0, 32768, 
+    40960, 45056, 45057, 44544, 44576,     0, 32768, 40960, 
+    45056, 45057, 44544, 44576,     0, 32768, 40960, 45056, 
+    45057, 44544, 44576, 44578,     0, 32768, 40960, 45056, 
+    45057, 44544, 44576,     0, 32768, 40960, 45056, 45057, 
+    44544, 44576, 44580,     0, 32768, 40960, 45056, 45057, 
+    44544, 44576, 44580,     0, 32768, 40960, 45056, 45057, 
+    44544, 44576, 44584, 44582,     0, 32768, 40960, 45056, 
+    45057, 44544, 44576,     0, 32768, 40960, 45056, 45057, 
+    44544, 44576, 44584,     0, 32768, 40960, 45056, 45057, 
+    44544, 44576, 44584,     0, 32768, 40960, 45056, 45057, 
+    44544, 44576, 44584, 44586,     0, 32768, 40960, 45056, 
+    45057, 44544, 44576, 44584,     0, 32768, 40960, 45056, 
+    45057, 44544, 44576, 44592, 44588,     0, 32768, 40960, 
+    45056, 45057, 44544, 44576, 44592, 44588,     0, 32768, 
+    40960, 45056, 45057, 44544, 44576, 44592, 44593, 44590, 
+        0, 32768, 40960, 45056, 45057, 44544, 44576,     0, 
+    32768, 40960, 45056, 45057, 44544, 44608, 44592,     0, 
+    32768, 40960, 45056, 45057, 44544, 44608, 44592,     0, 
+    32768, 40960, 45056, 45057, 44544, 44608, 44592, 44594, 
+        0, 32768, 40960, 45056, 45057, 44544, 44608, 44592, 
+        0, 32768, 40960, 45056, 45057, 44544, 44608, 44592, 
+    44596,     0, 32768, 40960, 45056, 45057, 44544, 44608, 
+    44592, 44596,     0, 32768, 40960, 45056, 45057, 44544, 
+    44608, 44592, 44600, 44598,     0, 32768, 40960, 45056, 
+    45057, 44544, 44608, 44592,     0, 32768, 40960, 45056, 
+    45057, 44544, 44608, 44609, 44600,     0, 32768, 40960, 
+    45056, 45057, 44544, 44608, 44609, 44600,     0, 32768, 
+    40960, 45056, 45057, 44544, 44608, 44609, 44600, 44602, 
+        0, 32768, 40960, 45056, 45057, 44544, 44608, 44609, 
+    44600,     0, 32768, 40960, 45056, 45057, 44544, 44608, 
+    44609, 44600, 44604,     0, 32768, 40960, 45056, 45057, 
+    44544, 44608, 44609, 44611, 44604,     0, 32768, 40960, 
+    45056, 45057, 44544, 44608, 44609, 44611, 44604, 44606, 
+        0, 32768, 40960, 45056, 45057, 44544,     0, 32768, 
+    40960, 45056, 45057, 44544, 44608,     0, 32768, 40960, 
+    45056, 45057, 44544, 44608,     0, 32768, 40960, 45056, 
+    45057, 44544, 44608, 44610,     0, 32768, 40960, 45056, 
+    45057, 44544, 44608,     0, 32768, 40960, 45056, 45057, 
+    44544, 44608, 44612,     0, 32768, 40960, 45056, 45057, 
+    44544, 44608, 44612,     0, 32768, 40960, 45056, 45057, 
+    44544, 44608, 44616, 44614,     0, 32768, 40960, 45056, 
+    45057, 44544, 44608,     0, 32768, 40960, 45056, 45057, 
+    44544, 44608, 44616,     0, 32768, 40960, 45056, 45057, 
+    44544, 44608, 44616,     0, 32768, 40960, 45056, 45057, 
+    44544, 44608, 44616, 44618,     0, 32768, 40960, 45056, 
+    45057, 44544, 44608, 44616,     0, 32768, 40960, 45056, 
+    45057, 44544, 44608, 44624, 44620,     0, 32768, 40960, 
+    45056, 45057, 44544, 44608, 44624, 44620,     0, 32768, 
+    40960, 45056, 45057, 44544, 44608, 44624, 44625, 44622, 
+        0, 32768, 40960, 45056, 45057, 44544, 44608,     0, 
+    32768, 40960, 45056, 45057, 44544, 44608, 44624,     0, 
+    32768, 40960, 45056, 45057, 44544, 44608, 44624,     0, 
+    32768, 40960, 45056, 45057, 44544, 44608, 44624, 44626, 
+        0, 32768, 40960, 45056, 45057, 44544, 44608, 44624, 
+        0, 32768, 40960, 45056, 45057, 44544, 44608, 44624, 
+    44628,     0, 32768, 40960, 45056, 45057, 44544, 44608, 
+    44624, 44628,     0, 32768, 40960, 45056, 45057, 44544, 
+    44608, 44624, 44632, 44630,     0, 32768, 40960, 45056, 
+    45057, 44544, 44608, 44624,     0, 32768, 40960, 45056, 
+    45057, 44544, 44608, 44640, 44632,     0, 32768, 40960, 
+    45056, 45057, 44544, 44608, 44640, 44632,     0, 32768, 
+    40960, 45056, 45057, 44544, 44608, 44640, 44632, 44634, 
+        0, 32768, 40960, 45056, 45057, 44544, 44608, 44640, 
+    44632,     0, 32768, 40960, 45056, 45057, 44544, 44608, 
+    44640, 44641, 44636,     0, 32768, 40960, 45056, 45057, 
+    44544, 44608, 44640, 44641, 44636,     0, 32768, 40960, 
+    45056, 45057, 44544, 44608, 44640, 44641, 44636, 44638, 
+        0, 32768, 40960, 45056, 45057, 44544, 44608,     0, 
+    32768, 40960, 45056, 45057, 44544, 44672, 44640,     0, 
+    32768, 40960, 45056, 45057, 44544, 44672, 44640,     0, 
+    32768, 40960, 45056, 45057, 44544, 44672, 44640, 44642, 
+        0, 32768, 40960, 45056, 45057, 44544, 44672, 44640, 
+        0, 32768, 40960, 45056, 45057, 44544, 44672, 44640, 
+    44644,     0, 32768, 40960, 45056, 45057, 44544, 44672, 
+    44640, 44644,     0, 32768, 40960, 45056, 45057, 44544, 
+    44672, 44640, 44648, 44646,     0, 32768, 40960, 45056, 
+    45057, 44544, 44672, 44640,     0, 32768, 40960, 45056, 
+    45057, 44544, 44672, 44640, 44648,     0, 32768, 40960, 
+    45056, 45057, 44544, 44672, 44640, 44648,     0, 32768, 
+    40960, 45056, 45057, 44544, 44672, 44640, 44648, 44650, 
+        0, 32768, 40960, 45056, 45057, 44544, 44672, 44640, 
+    44648,     0, 32768, 40960, 45056, 45057, 44544, 44672, 
+    44640, 44656, 44652,     0, 32768, 40960, 45056, 45057, 
+    44544, 44672, 44640, 44656, 44652,     0, 32768, 40960, 
+    45056, 45057, 44544, 44672, 44640, 44656, 44657, 44654, 
+        0, 32768, 40960, 45056, 45057, 44544, 44672, 44640, 
+        0, 32768, 40960, 45056, 45057, 44544, 44672, 44673, 
+    44656,     0, 32768, 40960, 45056, 45057, 44544, 44672, 
+    44673, 44656,     0, 32768, 40960, 45056, 45057, 44544, 
+    44672, 44673, 44656, 44658,     0, 32768, 40960, 45056, 
+    45057, 44544, 44672, 44673, 44656,     0, 32768, 40960, 
+    45056, 45057, 44544, 44672, 44673, 44656, 44660,     0, 
+    32768, 40960, 45056, 45057, 44544, 44672, 44673, 44656, 
+    44660,     0, 32768, 40960, 45056, 45057, 44544, 44672, 
+    44673, 44656, 44664, 44662,     0, 32768, 40960, 45056, 
+    45057, 44544, 44672, 44673, 44656,     0, 32768, 40960, 
+    45056, 45057, 44544, 44672, 44673, 44656, 44664,     0, 
+    32768, 40960, 45056, 45057, 44544, 44672, 44673, 44675, 
+    44664,     0, 32768, 40960, 45056, 45057, 44544, 44672, 
+    44673, 44675, 44664, 44666,     0, 32768, 40960, 45056, 
+    45057, 44544, 44672, 44673, 44675, 44664,     0, 32768, 
+    40960, 45056, 45057, 44544, 44672, 44673, 44675, 44664, 
+    44668,     0, 32768, 40960, 45056, 45057, 44544, 44672, 
+    44673, 44675, 44664, 44668,     0, 32768, 40960, 45056, 
+    45057, 44544, 44672, 44673, 44675, 44664, 44668, 44670, 
+        0, 32768, 40960, 45056, 45057, 44544,     0, 32768, 
+    40960, 45056, 45057, 44544, 44672,     0, 32768, 40960, 
+    45056, 45057, 44544, 44672,     0, 32768, 40960, 45056, 
+    45057, 44544, 44672, 44674,     0, 32768, 40960, 45056, 
+    45057, 44544, 44672,     0, 32768, 40960, 45056, 45057, 
+    44544, 44672, 44676,     0, 32768, 40960, 45056, 45057, 
+    44544, 44672, 44676,     0, 32768, 40960, 45056, 45057, 
+    44544, 44672, 44680, 44678,     0, 32768, 40960, 45056, 
+    45057, 44544, 44672,     0, 32768, 40960, 45056, 45057, 
+    44544, 44672, 44680,     0, 32768, 40960, 45056, 45057, 
+    44544, 44672, 44680,     0, 32768, 40960, 45056, 45057, 
+    44544, 44672, 44680, 44682,     0, 32768, 40960, 45056, 
+    45057, 44544, 44672, 44680,     0, 32768, 40960, 45056, 
+    45057, 44544, 44672, 44688, 44684,     0, 32768, 40960, 
+    45056, 45057, 44544, 44672, 44688, 44684,     0, 32768, 
+    40960, 45056, 45057, 44544, 44672, 44688, 44689, 44686, 
+        0, 32768, 40960, 45056, 45057, 44544, 44672,     0, 
+    32768, 40960, 45056, 45057, 44544, 44672, 44688,     0, 
+    32768, 40960, 45056, 45057, 44544, 44672, 44688,     0, 
+    32768, 40960, 45056, 45057, 44544, 44672, 44688, 44690, 
+        0, 32768, 40960, 45056, 45057, 44544, 44672, 44688, 
+        0, 32768, 40960, 45056, 45057, 44544, 44672, 44688, 
+    44692,     0, 32768, 40960, 45056, 45057, 44544, 44672, 
+    44688, 44692,     0, 32768, 40960, 45056, 45057, 44544, 
+    44672, 44688, 44696, 44694,     0, 32768, 40960, 45056, 
+    45057, 44544, 44672, 44688,     0, 32768, 40960, 45056, 
+    45057, 44544, 44672, 44704, 44696,     0, 32768, 40960, 
+    45056, 45057, 44544, 44672, 44704, 44696,     0, 32768, 
+    40960, 45056, 45057, 44544, 44672, 44704, 44696, 44698, 
+        0, 32768, 40960, 45056, 45057, 44544, 44672, 44704, 
+    44696,     0, 32768, 40960, 45056, 45057, 44544, 44672, 
+    44704, 44705, 44700,     0, 32768, 40960, 45056, 45057, 
+    44544, 44672, 44704, 44705, 44700,     0, 32768, 40960, 
+    45056, 45057, 44544, 44672, 44704, 44705, 44700, 44702, 
+        0, 32768, 40960, 45056, 45057, 44544, 44672,     0, 
+    32768, 40960, 45056, 45057, 44544, 44672, 44704,     0, 
+    32768, 40960, 45056, 45057, 44544, 44672, 44704,     0, 
+    32768, 40960, 45056, 45057, 44544, 44672, 44704, 44706, 
+        0, 32768, 40960, 45056, 45057, 44544, 44672, 44704, 
+        0, 32768, 40960, 45056, 45057, 44544, 44672, 44704, 
+    44708,     0, 32768, 40960, 45056, 45057, 44544, 44672, 
+    44704, 44708,     0, 32768, 40960, 45056, 45057, 44544, 
+    44672, 44704, 44712, 44710,     0, 32768, 40960, 45056, 
+    45057, 44544, 44672, 44704,     0, 32768, 40960, 45056, 
+    45057, 44544, 44672, 44704, 44712,     0, 32768, 40960, 
+    45056, 45057, 44544, 44672, 44704, 44712,     0, 32768, 
+    40960, 45056, 45057, 44544, 44672, 44704, 44712, 44714, 
+        0, 32768, 40960, 45056, 45057, 44544, 44672, 44704, 
+    44712,     0, 32768, 40960, 45056, 45057, 44544, 44672, 
+    44704, 44720, 44716,     0, 32768, 40960, 45056, 45057, 
+    44544, 44672, 44704, 44720, 44716,     0, 32768, 40960, 
+    45056, 45057, 44544, 44672, 44704, 44720, 44721, 44718, 
+        0, 32768, 40960, 45056, 45057, 44544, 44672, 44704, 
+        0, 32768, 40960, 45056, 45057, 44544, 44672, 44736, 
+    44720,     0, 32768, 40960, 45056, 45057, 44544, 44672, 
+    44736, 44720,     0, 32768, 40960, 45056, 45057, 44544, 
+    44672, 44736, 44720, 44722,     0, 32768, 40960, 45056, 
+    45057, 44544, 44672, 44736, 44720,     0, 32768, 40960, 
+    45056, 45057, 44544, 44672, 44736, 44720, 44724,     0, 
+    32768, 40960, 45056, 45057, 44544, 44672, 44736, 44720, 
+    44724,     0, 32768, 40960, 45056, 45057, 44544, 44672, 
+    44736, 44720, 44728, 44726,     0, 32768, 40960, 45056, 
+    45057, 44544, 44672, 44736, 44720,     0, 32768, 40960, 
+    45056, 45057, 44544, 44672, 44736, 44737, 44728,     0, 
+    32768, 40960, 45056, 45057, 44544, 44672, 44736, 44737, 
+    44728,     0, 32768, 40960, 45056, 45057, 44544, 44672, 
+    44736, 44737, 44728, 44730,     0, 32768, 40960, 45056, 
+    45057, 44544, 44672, 44736, 44737, 44728,     0, 32768, 
+    40960, 45056, 45057, 44544, 44672, 44736, 44737, 44728, 
+    44732,     0, 32768, 40960, 45056, 45057, 44544, 44672, 
+    44736, 44737, 44739, 44732,     0, 32768, 40960, 45056, 
+    45057, 44544, 44672, 44736, 44737, 44739, 44732, 44734, 
+        0, 32768, 40960, 45056, 45057, 44544, 44672,     0, 
+    32768, 40960, 45056, 45057, 44544, 44800, 44736,     0, 
+    32768, 40960, 45056, 45057, 44544, 44800, 44736,     0, 
+    32768, 40960, 45056, 45057, 44544, 44800, 44736, 44738, 
+        0, 32768, 40960, 45056, 45057, 44544, 44800, 44736, 
+        0, 32768, 40960, 45056, 45057, 44544, 44800, 44736, 
+    44740,     0, 32768, 40960, 45056, 45057, 44544, 44800, 
+    44736, 44740,     0, 32768, 40960, 45056, 45057, 44544, 
+    44800, 44736, 44744, 44742,     0, 32768, 40960, 45056, 
+    45057, 44544, 44800, 44736,     0, 32768, 40960, 45056, 
+    45057, 44544, 44800, 44736, 44744,     0, 32768, 40960, 
+    45056, 45057, 44544, 44800, 44736, 44744,     0, 32768, 
+    40960, 45056, 45057, 44544, 44800, 44736, 44744, 44746, 
+        0, 32768, 40960, 45056, 45057, 44544, 44800, 44736, 
+    44744,     0, 32768, 40960, 45056, 45057, 44544, 44800, 
+    44736, 44752, 44748,     0, 32768, 40960, 45056, 45057, 
+    44544, 44800, 44736, 44752, 44748,     0, 32768, 40960, 
+    45056, 45057, 44544, 44800, 44736, 44752, 44753, 44750, 
+        0, 32768, 40960, 45056, 45057, 44544, 44800, 44736, 
+        0, 32768, 40960, 45056, 45057, 44544, 44800, 44736, 
+    44752,     0, 32768, 40960, 45056, 45057, 44544, 44800, 
+    44736, 44752,     0, 32768, 40960, 45056, 45057, 44544, 
+    44800, 44736, 44752, 44754,     0, 32768, 40960, 45056, 
+    45057, 44544, 44800, 44736, 44752,     0, 32768, 40960, 
+    45056, 45057, 44544, 44800, 44736, 44752, 44756,     0, 
+    32768, 40960, 45056, 45057, 44544, 44800, 44736, 44752, 
+    44756,     0, 32768, 40960, 45056, 45057, 44544, 44800, 
+    44736, 44752, 44760, 44758,     0, 32768, 40960, 45056, 
+    45057, 44544, 44800, 44736, 44752,     0, 32768, 40960, 
+    45056, 45057, 44544, 44800, 44736, 44768, 44760,     0, 
+    32768, 40960, 45056, 45057, 44544, 44800, 44736, 44768, 
+    44760,     0, 32768, 40960, 45056, 45057, 44544, 44800, 
+    44736, 44768, 44760, 44762,     0, 32768, 40960, 45056, 
+    45057, 44544, 44800, 44736, 44768, 44760,     0, 32768, 
+    40960, 45056, 45057, 44544, 44800, 44736, 44768, 44769, 
+    44764,     0, 32768, 40960, 45056, 45057, 44544, 44800, 
+    44736, 44768, 44769, 44764,     0, 32768, 40960, 45056, 
+    45057, 44544, 44800, 44736, 44768, 44769, 44764, 44766, 
+        0, 32768, 40960, 45056, 45057, 44544, 44800, 44736, 
+        0, 32768, 40960, 45056, 45057, 44544, 44800, 44801, 
+    44768,     0, 32768, 40960, 45056, 45057, 44544, 44800, 
+    44801, 44768,     0, 32768, 40960, 45056, 45057, 44544, 
+    44800, 44801, 44768, 44770,     0, 32768, 40960, 45056, 
+    45057, 44544, 44800, 44801, 44768,     0, 32768, 40960, 
+    45056, 45057, 44544, 44800, 44801, 44768, 44772,     0, 
+    32768, 40960, 45056, 45057, 44544, 44800, 44801, 44768, 
+    44772,     0, 32768, 40960, 45056, 45057, 44544, 44800, 
+    44801, 44768, 44776, 44774,     0, 32768, 40960, 45056, 
+    45057, 44544, 44800, 44801, 44768,     0, 32768, 40960, 
+    45056, 45057, 44544, 44800, 44801, 44768, 44776,     0, 
+    32768, 40960, 45056, 45057, 44544, 44800, 44801, 44768, 
+    44776,     0, 32768, 40960, 45056, 45057, 44544, 44800, 
+    44801, 44768, 44776, 44778,     0, 32768, 40960, 45056, 
+    45057, 44544, 44800, 44801, 44768, 44776,     0, 32768, 
+    40960, 45056, 45057, 44544, 44800, 44801, 44768, 44784, 
+    44780,     0, 32768, 40960, 45056, 45057, 44544, 44800, 
+    44801, 44768, 44784, 44780,     0, 32768, 40960, 45056, 
+    45057, 44544, 44800, 44801, 44768, 44784, 44785, 44782, 
+        0, 32768, 40960, 45056, 45057, 44544, 44800, 44801, 
+    44768,     0, 32768, 40960, 45056, 45057, 44544, 44800, 
+    44801, 44768, 44784,     0, 32768, 40960, 45056, 45057, 
+    44544, 44800, 44801, 44803, 44784,     0, 32768, 40960, 
+    45056, 45057, 44544, 44800, 44801, 44803, 44784, 44786, 
+        0, 32768, 40960, 45056, 45057, 44544, 44800, 44801, 
+    44803, 44784,     0, 32768, 40960, 45056, 45057, 44544, 
+    44800, 44801, 44803, 44784, 44788,     0, 32768, 40960, 
+    45056, 45057, 44544, 44800, 44801, 44803, 44784, 44788, 
+        0, 32768, 40960, 45056, 45057, 44544, 44800, 44801, 
+    44803, 44784, 44792, 44790,     0, 32768, 40960, 45056, 
+    45057, 44544, 44800, 44801, 44803, 44784,     0, 32768, 
+    40960, 45056, 45057, 44544, 44800, 44801, 44803, 44784, 
+    44792,     0, 32768, 40960, 45056, 45057, 44544, 44800, 
+    44801, 44803, 44784, 44792,     0, 32768, 40960, 45056, 
+    45057, 44544, 44800, 44801, 44803, 44784, 44792, 44794, 
+        0, 32768, 40960, 45056, 45057, 44544, 44800, 44801, 
+    44803, 44807, 44792,     0, 32768, 40960, 45056, 45057, 
+    44544, 44800, 44801, 44803, 44807, 44792, 44796,     0, 
+    32768, 40960, 45056, 45057, 44544, 44800, 44801, 44803, 
+    44807, 44792, 44796,     0, 32768, 40960, 45056, 45057, 
+    44544, 44800, 44801, 44803, 44807, 44792, 44796, 44798, 
+        0, 32768, 40960, 45056, 45057, 44544,     0, 32768, 
+    40960, 45056, 45057, 44544, 44800,     0, 32768, 40960, 
+    45056, 45057, 44544, 44800,     0, 32768, 40960, 45056, 
+    45057, 44544, 44800, 44802,     0, 32768, 40960, 45056, 
+    45057, 45059, 44800,     0, 32768, 40960, 45056, 45057, 
+    45059, 44800, 44804,     0, 32768, 40960, 45056, 45057, 
+    45059, 44800, 44804,     0, 32768, 40960, 45056, 45057, 
+    45059, 44800, 44808, 44806,     0, 32768, 40960, 45056, 
+    45057, 45059, 44800,     0, 32768, 40960, 45056, 45057, 
+    45059, 44800, 44808,     0, 32768, 40960, 45056, 45057, 
+    45059, 44800, 44808,     0, 32768, 40960, 45056, 45057, 
+    45059, 44800, 44808, 44810,     0, 32768, 40960, 45056, 
+    45057, 45059, 44800, 44808,     0, 32768, 40960, 45056, 
+    45057, 45059, 44800, 44816, 44812,     0, 32768, 40960, 
+    45056, 45057, 45059, 44800, 44816, 44812,     0, 32768, 
+    40960, 45056, 45057, 45059, 44800, 44816, 44817, 44814, 
+        0, 32768, 40960, 45056, 45057, 45059, 44800,     0, 
+    32768, 40960, 45056, 45057, 45059, 44800, 44816,     0, 
+    32768, 40960, 45056, 45057, 45059, 44800, 44816,     0, 
+    32768, 40960, 45056, 45057, 45059, 44800, 44816, 44818, 
+        0, 32768, 40960, 45056, 45057, 45059, 44800, 44816, 
+        0, 32768, 40960, 45056, 45057, 45059, 44800, 44816, 
+    44820,     0, 32768, 40960, 45056, 45057, 45059, 44800, 
+    44816, 44820,     0, 32768, 40960, 45056, 45057, 45059, 
+    44800, 44816, 44824, 44822,     0, 32768, 40960, 45056, 
+    45057, 45059, 44800, 44816,     0, 32768, 40960, 45056, 
+    45057, 45059, 44800, 44832, 44824,     0, 32768, 40960, 
+    45056, 45057, 45059, 44800, 44832, 44824,     0, 32768, 
+    40960, 45056, 45057, 45059, 44800, 44832, 44824, 44826, 
+        0, 32768, 40960, 45056, 45057, 45059, 44800, 44832, 
+    44824,     0, 32768, 40960, 45056, 45057, 45059, 44800, 
+    44832, 44833, 44828,     0, 32768, 40960, 45056, 45057, 
+    45059, 44800, 44832, 44833, 44828,     0, 32768, 40960, 
+    45056, 45057, 45059, 44800, 44832, 44833, 44828, 44830, 
+        0, 32768, 40960, 45056, 45057, 45059, 44800,     0, 
+    32768, 40960, 45056, 45057, 45059, 44800, 44832,     0, 
+    32768, 40960, 45056, 45057, 45059, 44800, 44832,     0, 
+    32768, 40960, 45056, 45057, 45059, 44800, 44832, 44834, 
+        0, 32768, 40960, 45056, 45057, 45059, 44800, 44832, 
+        0, 32768, 40960, 45056, 45057, 45059, 44800, 44832, 
+    44836,     0, 32768, 40960, 45056, 45057, 45059, 44800, 
+    44832, 44836,     0, 32768, 40960, 45056, 45057, 45059, 
+    44800, 44832, 44840, 44838,     0, 32768, 40960, 45056, 
+    45057, 45059, 44800, 44832,     0, 32768, 40960, 45056, 
+    45057, 45059, 44800, 44832, 44840,     0, 32768, 40960, 
+    45056, 45057, 45059, 44800, 44832, 44840,     0, 32768, 
+    40960, 45056, 45057, 45059, 44800, 44832, 44840, 44842, 
+        0, 32768, 40960, 45056, 45057, 45059, 44800, 44832, 
+    44840,     0, 32768, 40960, 45056, 45057, 45059, 44800, 
+    44832, 44848, 44844,     0, 32768, 40960, 45056, 45057, 
+    45059, 44800, 44832, 44848, 44844,     0, 32768, 40960, 
+    45056, 45057, 45059, 44800, 44832, 44848, 44849, 44846, 
+        0, 32768, 40960, 45056, 45057, 45059, 44800, 44832, 
+        0, 32768, 40960, 45056, 45057, 45059, 44800, 44864, 
+    44848,     0, 32768, 40960, 45056, 45057, 45059, 44800, 
+    44864, 44848,     0, 32768, 40960, 45056, 45057, 45059, 
+    44800, 44864, 44848, 44850,     0, 32768, 40960, 45056, 
+    45057, 45059, 44800, 44864, 44848,     0, 32768, 40960, 
+    45056, 45057, 45059, 44800, 44864, 44848, 44852,     0, 
+    32768, 40960, 45056, 45057, 45059, 44800, 44864, 44848, 
+    44852,     0, 32768, 40960, 45056, 45057, 45059, 44800, 
+    44864, 44848, 44856, 44854,     0, 32768, 40960, 45056, 
+    45057, 45059, 44800, 44864, 44848,     0, 32768, 40960, 
+    45056, 45057, 45059, 44800, 44864, 44865, 44856,     0, 
+    32768, 40960, 45056, 45057, 45059, 44800, 44864, 44865, 
+    44856,     0, 32768, 40960, 45056, 45057, 45059, 44800, 
+    44864, 44865, 44856, 44858,     0, 32768, 40960, 45056, 
+    45057, 45059, 44800, 44864, 44865, 44856,     0, 32768, 
+    40960, 45056, 45057, 45059, 44800, 44864, 44865, 44856, 
+    44860,     0, 32768, 40960, 45056, 45057, 45059, 44800, 
+    44864, 44865, 44867, 44860,     0, 32768, 40960, 45056, 
+    45057, 45059, 44800, 44864, 44865, 44867, 44860, 44862, 
+        0, 32768, 40960, 45056, 45057, 45059, 44800,     0, 
+    32768, 40960, 45056, 45057, 45059, 44800, 44864,     0, 
+    32768, 40960, 45056, 45057, 45059, 44800, 44864,     0, 
+    32768, 40960, 45056, 45057, 45059, 44800, 44864, 44866, 
+        0, 32768, 40960, 45056, 45057, 45059, 44800, 44864, 
+        0, 32768, 40960, 45056, 45057, 45059, 44800, 44864, 
+    44868,     0, 32768, 40960, 45056, 45057, 45059, 44800, 
+    44864, 44868,     0, 32768, 40960, 45056, 45057, 45059, 
+    44800, 44864, 44872, 44870,     0, 32768, 40960, 45056, 
+    45057, 45059, 44800, 44864,     0, 32768, 40960, 45056, 
+    45057, 45059, 44800, 44864, 44872,     0, 32768, 40960, 
+    45056, 45057, 45059, 44800, 44864, 44872,     0, 32768, 
+    40960, 45056, 45057, 45059, 44800, 44864, 44872, 44874, 
+        0, 32768, 40960, 45056, 45057, 45059, 44800, 44864, 
+    44872,     0, 32768, 40960, 45056, 45057, 45059, 44800, 
+    44864, 44880, 44876,     0, 32768, 40960, 45056, 45057, 
+    45059, 44800, 44864, 44880, 44876,     0, 32768, 40960, 
+    45056, 45057, 45059, 44800, 44864, 44880, 44881, 44878, 
+        0, 32768, 40960, 45056, 45057, 45059, 44800, 44864, 
+        0, 32768, 40960, 45056, 45057, 45059, 44800, 44864, 
+    44880,     0, 32768, 40960, 45056, 45057, 45059, 44800, 
+    44864, 44880,     0, 32768, 40960, 45056, 45057, 45059, 
+    44800, 44864, 44880, 44882,     0, 32768, 40960, 45056, 
+    45057, 45059, 44800, 44864, 44880,     0, 32768, 40960, 
+    45056, 45057, 45059, 44800, 44864, 44880, 44884,     0, 
+    32768, 40960, 45056, 45057, 45059, 44800, 44864, 44880, 
+    44884,     0, 32768, 40960, 45056, 45057, 45059, 44800, 
+    44864, 44880, 44888, 44886,     0, 32768, 40960, 45056, 
+    45057, 45059, 44800, 44864, 44880,     0, 32768, 40960, 
+    45056, 45057, 45059, 44800, 44864, 44896, 44888,     0, 
+    32768, 40960, 45056, 45057, 45059, 44800, 44864, 44896, 
+    44888,     0, 32768, 40960, 45056, 45057, 45059, 44800, 
+    44864, 44896, 44888, 44890,     0, 32768, 40960, 45056, 
+    45057, 45059, 44800, 44864, 44896, 44888,     0, 32768, 
+    40960, 45056, 45057, 45059, 44800, 44864, 44896, 44897, 
+    44892,     0, 32768, 40960, 45056, 45057, 45059, 44800, 
+    44864, 44896, 44897, 44892,     0, 32768, 40960, 45056, 
+    45057, 45059, 44800, 44864, 44896, 44897, 44892, 44894, 
+        0, 32768, 40960, 45056, 45057, 45059, 44800, 44864, 
+        0, 32768, 40960, 45056, 45057, 45059, 44800, 44928, 
+    44896,     0, 32768, 40960, 45056, 45057, 45059, 44800, 
+    44928, 44896,     0, 32768, 40960, 45056, 45057, 45059, 
+    44800, 44928, 44896, 44898,     0, 32768, 40960, 45056, 
+    45057, 45059, 44800, 44928, 44896,     0, 32768, 40960, 
+    45056, 45057, 45059, 44800, 44928, 44896, 44900,     0, 
+    32768, 40960, 45056, 45057, 45059, 44800, 44928, 44896, 
+    44900,     0, 32768, 40960, 45056, 45057, 45059, 44800, 
+    44928, 44896, 44904, 44902,     0, 32768, 40960, 45056, 
+    45057, 45059, 44800, 44928, 44896,     0, 32768, 40960, 
+    45056, 45057, 45059, 44800, 44928, 44896, 44904,     0, 
+    32768, 40960, 45056, 45057, 45059, 44800, 44928, 44896, 
+    44904,     0, 32768, 40960, 45056, 45057, 45059, 44800, 
+    44928, 44896, 44904, 44906,     0, 32768, 40960, 45056, 
+    45057, 45059, 44800, 44928, 44896, 44904,     0, 32768, 
+    40960, 45056, 45057, 45059, 44800, 44928, 44896, 44912, 
+    44908,     0, 32768, 40960, 45056, 45057, 45059, 44800, 
+    44928, 44896, 44912, 44908,     0, 32768, 40960, 45056, 
+    45057, 45059, 44800, 44928, 44896, 44912, 44913, 44910, 
+        0, 32768, 40960, 45056, 45057, 45059, 44800, 44928, 
+    44896,     0, 32768, 40960, 45056, 45057, 45059, 44800, 
+    44928, 44929, 44912,     0, 32768, 40960, 45056, 45057, 
+    45059, 44800, 44928, 44929, 44912,     0, 32768, 40960, 
+    45056, 45057, 45059, 44800, 44928, 44929, 44912, 44914, 
+        0, 32768, 40960, 45056, 45057, 45059, 44800, 44928, 
+    44929, 44912,     0, 32768, 40960, 45056, 45057, 45059, 
+    44800, 44928, 44929, 44912, 44916,     0, 32768, 40960, 
+    45056, 45057, 45059, 44800, 44928, 44929, 44912, 44916, 
+        0, 32768, 40960, 45056, 45057, 45059, 44800, 44928, 
+    44929, 44912, 44920, 44918,     0, 32768, 40960, 45056, 
+    45057, 45059, 44800, 44928, 44929, 44912,     0, 32768, 
+    40960, 45056, 45057, 45059, 44800, 44928, 44929, 44912, 
+    44920,     0, 32768, 40960, 45056, 45057, 45059, 44800, 
+    44928, 44929, 44931, 44920,     0, 32768, 40960, 45056, 
+    45057, 45059, 44800, 44928, 44929, 44931, 44920, 44922, 
+        0, 32768, 40960, 45056, 45057, 45059, 44800, 44928, 
+    44929, 44931, 44920,     0, 32768, 40960, 45056, 45057, 
+    45059, 44800, 44928, 44929, 44931, 44920, 44924,     0, 
+    32768, 40960, 45056, 45057, 45059, 44800, 44928, 44929, 
+    44931, 44920, 44924,     0, 32768, 40960, 45056, 45057, 
+    45059, 44800, 44928, 44929, 44931, 44920, 44924, 44926, 
+        0, 32768, 40960, 45056, 45057, 45059, 44800,     0, 
+    32768, 40960, 45056, 45057, 45059, 44800, 44928,     0, 
+    32768, 40960, 45056, 45057, 45059, 44800, 44928,     0, 
+    32768, 40960, 45056, 45057, 45059, 44800, 44928, 44930, 
+        0, 32768, 40960, 45056, 45057, 45059, 44800, 44928, 
+        0, 32768, 40960, 45056, 45057, 45059, 44800, 44928, 
+    44932,     0, 32768, 40960, 45056, 45057, 45059, 44800, 
+    44928, 44932,     0, 32768, 40960, 45056, 45057, 45059, 
+    44800, 44928, 44936, 44934,     0, 32768, 40960, 45056, 
+    45057, 45059, 45063, 44928,     0, 32768, 40960, 45056, 
+    45057, 45059, 45063, 44928, 44936,     0, 32768, 40960, 
+    45056, 45057, 45059, 45063, 44928, 44936,     0, 32768, 
+    40960, 45056, 45057, 45059, 45063, 44928, 44936, 44938, 
+        0, 32768, 40960, 45056, 45057, 45059, 45063, 44928, 
+    44936,     0, 32768, 40960, 45056, 45057, 45059, 45063, 
+    44928, 44944, 44940,     0, 32768, 40960, 45056, 45057, 
+    45059, 45063, 44928, 44944, 44940,     0, 32768, 40960, 
+    45056, 45057, 45059, 45063, 44928, 44944, 44945, 44942, 
+        0, 32768, 40960, 45056, 45057, 45059, 45063, 44928, 
+        0, 32768, 40960, 45056, 45057, 45059, 45063, 44928, 
+    44944,     0, 32768, 40960, 45056, 45057, 45059, 45063, 
+    44928, 44944,     0, 32768, 40960, 45056, 45057, 45059, 
+    45063, 44928, 44944, 44946,     0, 32768, 40960, 45056, 
+    45057, 45059, 45063, 44928, 44944,     0, 32768, 40960, 
+    45056, 45057, 45059, 45063, 44928, 44944, 44948,     0, 
+    32768, 40960, 45056, 45057, 45059, 45063, 44928, 44944, 
+    44948,     0, 32768, 40960, 45056, 45057, 45059, 45063, 
+    44928, 44944, 44952, 44950,     0, 32768, 40960, 45056, 
+    45057, 45059, 45063, 44928, 44944,     0, 32768, 40960, 
+    45056, 45057, 45059, 45063, 44928, 44960, 44952,     0, 
+    32768, 40960, 45056, 45057, 45059, 45063, 44928, 44960, 
+    44952,     0, 32768, 40960, 45056, 45057, 45059, 45063, 
+    44928, 44960, 44952, 44954,     0, 32768, 40960, 45056, 
+    45057, 45059, 45063, 44928, 44960, 44952,     0, 32768, 
+    40960, 45056, 45057, 45059, 45063, 44928, 44960, 44961, 
+    44956,     0, 32768, 40960, 45056, 45057, 45059, 45063, 
+    44928, 44960, 44961, 44956,     0, 32768, 40960, 45056, 
+    45057, 45059, 45063, 44928, 44960, 44961, 44956, 44958, 
+        0, 32768, 40960, 45056, 45057, 45059, 45063, 44928, 
+        0, 32768, 40960, 45056, 45057, 45059, 45063, 44928, 
+    44960,     0, 32768, 40960, 45056, 45057, 45059, 45063, 
+    44928, 44960,     0, 32768, 40960, 45056, 45057, 45059, 
+    45063, 44928, 44960, 44962,     0, 32768, 40960, 45056, 
+    45057, 45059, 45063, 44928, 44960,     0, 32768, 40960, 
+    45056, 45057, 45059, 45063, 44928, 44960, 44964,     0, 
+    32768, 40960, 45056, 45057, 45059, 45063, 44928, 44960, 
+    44964,     0, 32768, 40960, 45056, 45057, 45059, 45063, 
+    44928, 44960, 44968, 44966,     0, 32768, 40960, 45056, 
+    45057, 45059, 45063, 44928, 44960,     0, 32768, 40960, 
+    45056, 45057, 45059, 45063, 44928, 44960, 44968,     0, 
+    32768, 40960, 45056, 45057, 45059, 45063, 44928, 44960, 
+    44968,     0, 32768, 40960, 45056, 45057, 45059, 45063, 
+    44928, 44960, 44968, 44970,     0, 32768, 40960, 45056, 
+    45057, 45059, 45063, 44928, 44960, 44968,     0, 32768, 
+    40960, 45056, 45057, 45059, 45063, 44928, 44960, 44976, 
+    44972,     0, 32768, 40960, 45056, 45057, 45059, 45063, 
+    44928, 44960, 44976, 44972,     0, 32768, 40960, 45056, 
+    45057, 45059, 45063, 44928, 44960, 44976, 44977, 44974, 
+        0, 32768, 40960, 45056, 45057, 45059, 45063, 44928, 
+    44960,     0, 32768, 40960, 45056, 45057, 45059, 45063, 
+    44928, 44992, 44976,     0, 32768, 40960, 45056, 45057, 
+    45059, 45063, 44928, 44992, 44976,     0, 32768, 40960, 
+    45056, 45057, 45059, 45063, 44928, 44992, 44976, 44978, 
+        0, 32768, 40960, 45056, 45057, 45059, 45063, 44928, 
+    44992, 44976,     0, 32768, 40960, 45056, 45057, 45059, 
+    45063, 44928, 44992, 44976, 44980,     0, 32768, 40960, 
+    45056, 45057, 45059, 45063, 44928, 44992, 44976, 44980, 
+        0, 32768, 40960, 45056, 45057, 45059, 45063, 44928, 
+    44992, 44976, 44984, 44982,     0, 32768, 40960, 45056, 
+    45057, 45059, 45063, 44928, 44992, 44976,     0, 32768, 
+    40960, 45056, 45057, 45059, 45063, 44928, 44992, 44993, 
+    44984,     0, 32768, 40960, 45056, 45057, 45059, 45063, 
+    44928, 44992, 44993, 44984,     0, 32768, 40960, 45056, 
+    45057, 45059, 45063, 44928, 44992, 44993, 44984, 44986, 
+        0, 32768, 40960, 45056, 45057, 45059, 45063, 44928, 
+    44992, 44993, 44984,     0, 32768, 40960, 45056, 45057, 
+    45059, 45063, 44928, 44992, 44993, 44984, 44988,     0, 
+    32768, 40960, 45056, 45057, 45059, 45063, 44928, 44992, 
+    44993, 44995, 44988,     0, 32768, 40960, 45056, 45057, 
+    45059, 45063, 44928, 44992, 44993, 44995, 44988, 44990, 
+        0, 32768, 40960, 45056, 45057, 45059, 45063, 44928, 
+        0, 32768, 40960, 45056, 45057, 45059, 45063, 44928, 
+    44992,     0, 32768, 40960, 45056, 45057, 45059, 45063, 
+    44928, 44992,     0, 32768, 40960, 45056, 45057, 45059, 
+    45063, 44928, 44992, 44994,     0, 32768, 40960, 45056, 
+    45057, 45059, 45063, 44928, 44992,     0, 32768, 40960, 
+    45056, 45057, 45059, 45063, 44928, 44992, 44996,     0, 
+    32768, 40960, 45056, 45057, 45059, 45063, 44928, 44992, 
+    44996,     0, 32768, 40960, 45056, 45057, 45059, 45063, 
+    44928, 44992, 45000, 44998,     0, 32768, 40960, 45056, 
+    45057, 45059, 45063, 44928, 44992,     0, 32768, 40960, 
+    45056, 45057, 45059, 45063, 44928, 44992, 45000,     0, 
+    32768, 40960, 45056, 45057, 45059, 45063, 44928, 44992, 
+    45000,     0, 32768, 40960, 45056, 45057, 45059, 45063, 
+    44928, 44992, 45000, 45002,     0, 32768, 40960, 45056, 
+    45057, 45059, 45063, 44928, 44992, 45000,     0, 32768, 
+    40960, 45056, 45057, 45059, 45063, 44928, 44992, 45008, 
+    45004,     0, 32768, 40960, 45056, 45057, 45059, 45063, 
+    44928, 44992, 45008, 45004,     0, 32768, 40960, 45056, 
+    45057, 45059, 45063, 44928, 44992, 45008, 45009, 45006, 
+        0, 32768, 40960, 45056, 45057, 45059, 45063, 45071, 
+    44992,     0, 32768, 40960, 45056, 45057, 45059, 45063, 
+    45071, 44992, 45008,     0, 32768, 40960, 45056, 45057, 
+    45059, 45063, 45071, 44992, 45008,     0, 32768, 40960, 
+    45056, 45057, 45059, 45063, 45071, 44992, 45008, 45010, 
+        0, 32768, 40960, 45056, 45057, 45059, 45063, 45071, 
+    44992, 45008,     0, 32768, 40960, 45056, 45057, 45059, 
+    45063, 45071, 44992, 45008, 45012,     0, 32768, 40960, 
+    45056, 45057, 45059, 45063, 45071, 44992, 45008, 45012, 
+        0, 32768, 40960, 45056, 45057, 45059, 45063, 45071, 
+    44992, 45008, 45016, 45014,     0, 32768, 40960, 45056, 
+    45057, 45059, 45063, 45071, 44992, 45008,     0, 32768, 
+    40960, 45056, 45057, 45059, 45063, 45071, 44992, 45024, 
+    45016,     0, 32768, 40960, 45056, 45057, 45059, 45063, 
+    45071, 44992, 45024, 45016,     0, 32768, 40960, 45056, 
+    45057, 45059, 45063, 45071, 44992, 45024, 45016, 45018, 
+        0, 32768, 40960, 45056, 45057, 45059, 45063, 45071, 
+    44992, 45024, 45016,     0, 32768, 40960, 45056, 45057, 
+    45059, 45063, 45071, 44992, 45024, 45025, 45020,     0, 
+    32768, 40960, 45056, 45057, 45059, 45063, 45071, 44992, 
+    45024, 45025, 45020,     0, 32768, 40960, 45056, 45057, 
+    45059, 45063, 45071, 44992, 45024, 45025, 45020, 45022, 
+        0, 32768, 40960, 45056, 45057, 45059, 45063, 45071, 
+    44992,     0, 32768, 40960, 45056, 45057, 45059, 45063, 
+    45071, 44992, 45024,     0, 32768, 40960, 45056, 45057, 
+    45059, 45063, 45071, 44992, 45024,     0, 32768, 40960, 
+    45056, 45057, 45059, 45063, 45071, 44992, 45024, 45026, 
+        0, 32768, 40960, 45056, 45057, 45059, 45063, 45071, 
+    44992, 45024,     0, 32768, 40960, 45056, 45057, 45059, 
+    45063, 45071, 44992, 45024, 45028,     0, 32768, 40960, 
+    45056, 45057, 45059, 45063, 45071, 44992, 45024, 45028, 
+        0, 32768, 40960, 45056, 45057, 45059, 45063, 45071, 
+    44992, 45024, 45032, 45030,     0, 32768, 40960, 45056, 
+    45057, 45059, 45063, 45071, 44992, 45024,     0, 32768, 
+    40960, 45056, 45057, 45059, 45063, 45071, 44992, 45024, 
+    45032,     0, 32768, 40960, 45056, 45057, 45059, 45063, 
+    45071, 44992, 45024, 45032,     0, 32768, 40960, 45056, 
+    45057, 45059, 45063, 45071, 44992, 45024, 45032, 45034, 
+        0, 32768, 40960, 45056, 45057, 45059, 45063, 45071, 
+    44992, 45024, 45032,     0, 32768, 40960, 45056, 45057, 
+    45059, 45063, 45071, 44992, 45024, 45040, 45036,     0, 
+    32768, 40960, 45056, 45057, 45059, 45063, 45071, 44992, 
+    45024, 45040, 45036,     0, 32768, 40960, 45056, 45057, 
+    45059, 45063, 45071, 44992, 45024, 45040, 45041, 45038, 
+        0, 32768, 40960, 45056, 45057, 45059, 45063, 45071, 
+    44992, 45024,     0, 32768, 40960, 45056, 45057, 45059, 
+    45063, 45071, 44992, 45024, 45040,     0, 32768, 40960, 
+    45056, 45057, 45059, 45063, 45071, 44992, 45024, 45040, 
+        0, 32768, 40960, 45056, 45057, 45059, 45063, 45071, 
+    44992, 45024, 45040, 45042,     0, 32768, 40960, 45056, 
+    45057, 45059, 45063, 45071, 44992, 45024, 45040,     0, 
+    32768, 40960, 45056, 45057, 45059, 45063, 45071, 44992, 
+    45024, 45040, 45044,     0, 32768, 40960, 45056, 45057, 
+    45059, 45063, 45071, 44992, 45024, 45040, 45044,     0, 
+    32768, 40960, 45056, 45057, 45059, 45063, 45071, 44992, 
+    45024, 45040, 45048, 45046,     0, 32768, 40960, 45056, 
+    45057, 45059, 45063, 45071, 44992, 45024, 45040,     0, 
+    32768, 40960, 45056, 45057, 45059, 45063, 45071, 44992, 
+    45024, 45040, 45048,     0, 32768, 40960, 45056, 45057, 
+    45059, 45063, 45071, 44992, 45024, 45040, 45048,     0, 
+    32768, 40960, 45056, 45057, 45059, 45063, 45071, 44992, 
+    45024, 45040, 45048, 45050,     0, 32768, 40960, 45056, 
+    45057, 45059, 45063, 45071, 44992, 45024, 45040, 45048, 
+        0, 32768, 40960, 45056, 45057, 45059, 45063, 45071, 
+    44992, 45024, 45040, 45048, 45052,     0, 32768, 40960, 
+    45056, 45057, 45059, 45063, 45071, 44992, 45024, 45040, 
+    45048, 45052,     0, 32768, 40960, 45056, 45057, 45059, 
+    45063, 45071, 44992, 45024, 45040, 45048, 45052, 45054, 
+        0, 32768, 40960,     0, 32768, 40960, 45056,     0, 
+    32768, 40960, 45056,     0, 32768, 40960, 45056, 45058, 
+        0, 32768, 40960, 45056,     0, 32768, 40960, 45056, 
+    45060,     0, 32768, 40960, 45056, 45060,     0, 32768, 
+    40960, 45056, 45064, 45062,     0, 32768, 40960, 45056, 
+        0, 32768, 40960, 45056, 45064,     0, 32768, 40960, 
+    45056, 45064,     0, 32768, 40960, 45056, 45064, 45066, 
+        0, 32768, 40960, 45056, 45064,     0, 32768, 40960, 
+    45056, 45072, 45068,     0, 32768, 40960, 45056, 45072, 
+    45068,     0, 32768, 40960, 45056, 45072, 45073, 45070, 
+        0, 32768, 40960, 45056,     0, 32768, 40960, 45056, 
+    45072,     0, 32768, 40960, 45056, 45072,     0, 32768, 
+    40960, 45056, 45072, 45074,     0, 32768, 40960, 45056, 
+    45072,     0, 32768, 40960, 45056, 45072, 45076,     0, 
+    32768, 40960, 45056, 45072, 45076,     0, 32768, 40960, 
+    45056, 45072, 45080, 45078,     0, 32768, 40960, 45056, 
+    45072,     0, 32768, 40960, 45056, 45088, 45080,     0, 
+    32768, 40960, 45056, 45088, 45080,     0, 32768, 40960, 
+    45056, 45088, 45080, 45082,     0, 32768, 40960, 45056, 
+    45088, 45080,     0, 32768, 40960, 45056, 45088, 45089, 
+    45084,     0, 32768, 40960, 45056, 45088, 45089, 45084, 
+        0, 32768, 40960, 45056, 45088, 45089, 45084, 45086, 
+        0, 32768, 40960, 45056,     0, 32768, 40960, 45056, 
+    45088,     0, 32768, 40960, 45056, 45088,     0, 32768, 
+    40960, 45056, 45088, 45090,     0, 32768, 40960, 45056, 
+    45088,     0, 32768, 40960, 45056, 45088, 45092,     0, 
+    32768, 40960, 45056, 45088, 45092,     0, 32768, 40960, 
+    45056, 45088, 45096, 45094,     0, 32768, 40960, 45056, 
+    45088,     0, 32768, 40960, 45056, 45088, 45096,     0, 
+    32768, 40960, 45056, 45088, 45096,     0, 32768, 40960, 
+    45056, 45088, 45096, 45098,     0, 32768, 40960, 45056, 
+    45088, 45096,     0, 32768, 40960, 45056, 45088, 45104, 
+    45100,     0, 32768, 40960, 45056, 45088, 45104, 45100, 
+        0, 32768, 40960, 45056, 45088, 45104, 45105, 45102, 
+        0, 32768, 40960, 45056, 45088,     0, 32768, 40960, 
+    45056, 45120, 45104,     0, 32768, 40960, 45056, 45120, 
+    45104,     0, 32768, 40960, 45056, 45120, 45104, 45106, 
+        0, 32768, 40960, 45056, 45120, 45104,     0, 32768, 
+    40960, 45056, 45120, 45104, 45108,     0, 32768, 40960, 
+    45056, 45120, 45104, 45108,     0, 32768, 40960, 45056, 
+    45120, 45104, 45112, 45110,     0, 32768, 40960, 45056, 
+    45120, 45104,     0, 32768, 40960, 45056, 45120, 45121, 
+    45112,     0, 32768, 40960, 45056, 45120, 45121, 45112, 
+        0, 32768, 40960, 45056, 45120, 45121, 45112, 45114, 
+        0, 32768, 40960, 45056, 45120, 45121, 45112,     0, 
+    32768, 40960, 45056, 45120, 45121, 45112, 45116,     0, 
+    32768, 40960, 45056, 45120, 45121, 45123, 45116,     0, 
+    32768, 40960, 45056, 45120, 45121, 45123, 45116, 45118, 
+        0, 32768, 40960, 45056,     0, 32768, 40960, 45056, 
+    45120,     0, 32768, 40960, 45056, 45120,     0, 32768, 
+    40960, 45056, 45120, 45122,     0, 32768, 40960, 45056, 
+    45120,     0, 32768, 40960, 45056, 45120, 45124,     0, 
+    32768, 40960, 45056, 45120, 45124,     0, 32768, 40960, 
+    45056, 45120, 45128, 45126,     0, 32768, 40960, 45056, 
+    45120,     0, 32768, 40960, 45056, 45120, 45128,     0, 
+    32768, 40960, 45056, 45120, 45128,     0, 32768, 40960, 
+    45056, 45120, 45128, 45130,     0, 32768, 40960, 45056, 
+    45120, 45128,     0, 32768, 40960, 45056, 45120, 45136, 
+    45132,     0, 32768, 40960, 45056, 45120, 45136, 45132, 
+        0, 32768, 40960, 45056, 45120, 45136, 45137, 45134, 
+        0, 32768, 40960, 45056, 45120,     0, 32768, 40960, 
+    45056, 45120, 45136,     0, 32768, 40960, 45056, 45120, 
+    45136,     0, 32768, 40960, 45056, 45120, 45136, 45138, 
+        0, 32768, 40960, 45056, 45120, 45136,     0, 32768, 
+    40960, 45056, 45120, 45136, 45140,     0, 32768, 40960, 
+    45056, 45120, 45136, 45140,     0, 32768, 40960, 45056, 
+    45120, 45136, 45144, 45142,     0, 32768, 40960, 45056, 
+    45120, 45136,     0, 32768, 40960, 45056, 45120, 45152, 
+    45144,     0, 32768, 40960, 45056, 45120, 45152, 45144, 
+        0, 32768, 40960, 45056, 45120, 45152, 45144, 45146, 
+        0, 32768, 40960, 45056, 45120, 45152, 45144,     0, 
+    32768, 40960, 45056, 45120, 45152, 45153, 45148,     0, 
+    32768, 40960, 45056, 45120, 45152, 45153, 45148,     0, 
+    32768, 40960, 45056, 45120, 45152, 45153, 45148, 45150, 
+        0, 32768, 40960, 45056, 45120,     0, 32768, 40960, 
+    45056, 45184, 45152,     0, 32768, 40960, 45056, 45184, 
+    45152,     0, 32768, 40960, 45056, 45184, 45152, 45154, 
+        0, 32768, 40960, 45056, 45184, 45152,     0, 32768, 
+    40960, 45056, 45184, 45152, 45156,     0, 32768, 40960, 
+    45056, 45184, 45152, 45156,     0, 32768, 40960, 45056, 
+    45184, 45152, 45160, 45158,     0, 32768, 40960, 45056, 
+    45184, 45152,     0, 32768, 40960, 45056, 45184, 45152, 
+    45160,     0, 32768, 40960, 45056, 45184, 45152, 45160, 
+        0, 32768, 40960, 45056, 45184, 45152, 45160, 45162, 
+        0, 32768, 40960, 45056, 45184, 45152, 45160,     0, 
+    32768, 40960, 45056, 45184, 45152, 45168, 45164,     0, 
+    32768, 40960, 45056, 45184, 45152, 45168, 45164,     0, 
+    32768, 40960, 45056, 45184, 45152, 45168, 45169, 45166, 
+        0, 32768, 40960, 45056, 45184, 45152,     0, 32768, 
+    40960, 45056, 45184, 45185, 45168,     0, 32768, 40960, 
+    45056, 45184, 45185, 45168,     0, 32768, 40960, 45056, 
+    45184, 45185, 45168, 45170,     0, 32768, 40960, 45056, 
+    45184, 45185, 45168,     0, 32768, 40960, 45056, 45184, 
+    45185, 45168, 45172,     0, 32768, 40960, 45056, 45184, 
+    45185, 45168, 45172,     0, 32768, 40960, 45056, 45184, 
+    45185, 45168, 45176, 45174,     0, 32768, 40960, 45056, 
+    45184, 45185, 45168,     0, 32768, 40960, 45056, 45184, 
+    45185, 45168, 45176,     0, 32768, 40960, 45056, 45184, 
+    45185, 45187, 45176,     0, 32768, 40960, 45056, 45184, 
+    45185, 45187, 45176, 45178,     0, 32768, 40960, 45056, 
+    45184, 45185, 45187, 45176,     0, 32768, 40960, 45056, 
+    45184, 45185, 45187, 45176, 45180,     0, 32768, 40960, 
+    45056, 45184, 45185, 45187, 45176, 45180,     0, 32768, 
+    40960, 45056, 45184, 45185, 45187, 45176, 45180, 45182, 
+        0, 32768, 40960, 45056,     0, 32768, 40960, 45056, 
+    45184,     0, 32768, 40960, 45056, 45184,     0, 32768, 
+    40960, 45056, 45184, 45186,     0, 32768, 40960, 45056, 
+    45184,     0, 32768, 40960, 45056, 45184, 45188,     0, 
+    32768, 40960, 45056, 45184, 45188,     0, 32768, 40960, 
+    45056, 45184, 45192, 45190,     0, 32768, 40960, 45056, 
+    45184,     0, 32768, 40960, 45056, 45184, 45192,     0, 
+    32768, 40960, 45056, 45184, 45192,     0, 32768, 40960, 
+    45056, 45184, 45192, 45194,     0, 32768, 40960, 45056, 
+    45184, 45192,     0, 32768, 40960, 45056, 45184, 45200, 
+    45196,     0, 32768, 40960, 45056, 45184, 45200, 45196, 
+        0, 32768, 40960, 45056, 45184, 45200, 45201, 45198, 
+        0, 32768, 40960, 45056, 45184,     0, 32768, 40960, 
+    45056, 45184, 45200,     0, 32768, 40960, 45056, 45184, 
+    45200,     0, 32768, 40960, 45056, 45184, 45200, 45202, 
+        0, 32768, 40960, 45056, 45184, 45200,     0, 32768, 
+    40960, 45056, 45184, 45200, 45204,     0, 32768, 40960, 
+    45056, 45184, 45200, 45204,     0, 32768, 40960, 45056, 
+    45184, 45200, 45208, 45206,     0, 32768, 40960, 45056, 
+    45184, 45200,     0, 32768, 40960, 45056, 45184, 45216, 
+    45208,     0, 32768, 40960, 45056, 45184, 45216, 45208, 
+        0, 32768, 40960, 45056, 45184, 45216, 45208, 45210, 
+        0, 32768, 40960, 45056, 45184, 45216, 45208,     0, 
+    32768, 40960, 45056, 45184, 45216, 45217, 45212,     0, 
+    32768, 40960, 45056, 45184, 45216, 45217, 45212,     0, 
+    32768, 40960, 45056, 45184, 45216, 45217, 45212, 45214, 
+        0, 32768, 40960, 45056, 45184,     0, 32768, 40960, 
+    45056, 45184, 45216,     0, 32768, 40960, 45056, 45184, 
+    45216,     0, 32768, 40960, 45056, 45184, 45216, 45218, 
+        0, 32768, 40960, 45056, 45184, 45216,     0, 32768, 
+    40960, 45056, 45184, 45216, 45220,     0, 32768, 40960, 
+    45056, 45184, 45216, 45220,     0, 32768, 40960, 45056, 
+    45184, 45216, 45224, 45222,     0, 32768, 40960, 45056, 
+    45184, 45216,     0, 32768, 40960, 45056, 45184, 45216, 
+    45224,     0, 32768, 40960, 45056, 45184, 45216, 45224, 
+        0, 32768, 40960, 45056, 45184, 45216, 45224, 45226, 
+        0, 32768, 40960, 45056, 45184, 45216, 45224,     0, 
+    32768, 40960, 45056, 45184, 45216, 45232, 45228,     0, 
+    32768, 40960, 45056, 45184, 45216, 45232, 45228,     0, 
+    32768, 40960, 45056, 45184, 45216, 45232, 45233, 45230, 
+        0, 32768, 40960, 45056, 45184, 45216,     0, 32768, 
+    40960, 45056, 45184, 45248, 45232,     0, 32768, 40960, 
+    45056, 45184, 45248, 45232,     0, 32768, 40960, 45056, 
+    45184, 45248, 45232, 45234,     0, 32768, 40960, 45056, 
+    45184, 45248, 45232,     0, 32768, 40960, 45056, 45184, 
+    45248, 45232, 45236,     0, 32768, 40960, 45056, 45184, 
+    45248, 45232, 45236,     0, 32768, 40960, 45056, 45184, 
+    45248, 45232, 45240, 45238,     0, 32768, 40960, 45056, 
+    45184, 45248, 45232,     0, 32768, 40960, 45056, 45184, 
+    45248, 45249, 45240,     0, 32768, 40960, 45056, 45184, 
+    45248, 45249, 45240,     0, 32768, 40960, 45056, 45184, 
+    45248, 45249, 45240, 45242,     0, 32768, 40960, 45056, 
+    45184, 45248, 45249, 45240,     0, 32768, 40960, 45056, 
+    45184, 45248, 45249, 45240, 45244,     0, 32768, 40960, 
+    45056, 45184, 45248, 45249, 45251, 45244,     0, 32768, 
+    40960, 45056, 45184, 45248, 45249, 45251, 45244, 45246, 
+        0, 32768, 40960, 45056, 45184,     0, 32768, 40960, 
+    45056, 45312, 45248,     0, 32768, 40960, 45056, 45312, 
+    45248,     0, 32768, 40960, 45056, 45312, 45248, 45250, 
+        0, 32768, 40960, 45056, 45312, 45248,     0, 32768, 
+    40960, 45056, 45312, 45248, 45252,     0, 32768, 40960, 
+    45056, 45312, 45248, 45252,     0, 32768, 40960, 45056, 
+    45312, 45248, 45256, 45254,     0, 32768, 40960, 45056, 
+    45312, 45248,     0, 32768, 40960, 45056, 45312, 45248, 
+    45256,     0, 32768, 40960, 45056, 45312, 45248, 45256, 
+        0, 32768, 40960, 45056, 45312, 45248, 45256, 45258, 
+        0, 32768, 40960, 45056, 45312, 45248, 45256,     0, 
+    32768, 40960, 45056, 45312, 45248, 45264, 45260,     0, 
+    32768, 40960, 45056, 45312, 45248, 45264, 45260,     0, 
+    32768, 40960, 45056, 45312, 45248, 45264, 45265, 45262, 
+        0, 32768, 40960, 45056, 45312, 45248,     0, 32768, 
+    40960, 45056, 45312, 45248, 45264,     0, 32768, 40960, 
+    45056, 45312, 45248, 45264,     0, 32768, 40960, 45056, 
+    45312, 45248, 45264, 45266,     0, 32768, 40960, 45056, 
+    45312, 45248, 45264,     0, 32768, 40960, 45056, 45312, 
+    45248, 45264, 45268,     0, 32768, 40960, 45056, 45312, 
+    45248, 45264, 45268,     0, 32768, 40960, 45056, 45312, 
+    45248, 45264, 45272, 45270,     0, 32768, 40960, 45056, 
+    45312, 45248, 45264,     0, 32768, 40960, 45056, 45312, 
+    45248, 45280, 45272,     0, 32768, 40960, 45056, 45312, 
+    45248, 45280, 45272,     0, 32768, 40960, 45056, 45312, 
+    45248, 45280, 45272, 45274,     0, 32768, 40960, 45056, 
+    45312, 45248, 45280, 45272,     0, 32768, 40960, 45056, 
+    45312, 45248, 45280, 45281, 45276,     0, 32768, 40960, 
+    45056, 45312, 45248, 45280, 45281, 45276,     0, 32768, 
+    40960, 45056, 45312, 45248, 45280, 45281, 45276, 45278, 
+        0, 32768, 40960, 45056, 45312, 45248,     0, 32768, 
+    40960, 45056, 45312, 45313, 45280,     0, 32768, 40960, 
+    45056, 45312, 45313, 45280,     0, 32768, 40960, 45056, 
+    45312, 45313, 45280, 45282,     0, 32768, 40960, 45056, 
+    45312, 45313, 45280,     0, 32768, 40960, 45056, 45312, 
+    45313, 45280, 45284,     0, 32768, 40960, 45056, 45312, 
+    45313, 45280, 45284,     0, 32768, 40960, 45056, 45312, 
+    45313, 45280, 45288, 45286,     0, 32768, 40960, 45056, 
+    45312, 45313, 45280,     0, 32768, 40960, 45056, 45312, 
+    45313, 45280, 45288,     0, 32768, 40960, 45056, 45312, 
+    45313, 45280, 45288,     0, 32768, 40960, 45056, 45312, 
+    45313, 45280, 45288, 45290,     0, 32768, 40960, 45056, 
+    45312, 45313, 45280, 45288,     0, 32768, 40960, 45056, 
+    45312, 45313, 45280, 45296, 45292,     0, 32768, 40960, 
+    45056, 45312, 45313, 45280, 45296, 45292,     0, 32768, 
+    40960, 45056, 45312, 45313, 45280, 45296, 45297, 45294, 
+        0, 32768, 40960, 45056, 45312, 45313, 45280,     0, 
+    32768, 40960, 45056, 45312, 45313, 45280, 45296,     0, 
+    32768, 40960, 45056, 45312, 45313, 45315, 45296,     0, 
+    32768, 40960, 45056, 45312, 45313, 45315, 45296, 45298, 
+        0, 32768, 40960, 45056, 45312, 45313, 45315, 45296, 
+        0, 32768, 40960, 45056, 45312, 45313, 45315, 45296, 
+    45300,     0, 32768, 40960, 45056, 45312, 45313, 45315, 
+    45296, 45300,     0, 32768, 40960, 45056, 45312, 45313, 
+    45315, 45296, 45304, 45302,     0, 32768, 40960, 45056, 
+    45312, 45313, 45315, 45296,     0, 32768, 40960, 45056, 
+    45312, 45313, 45315, 45296, 45304,     0, 32768, 40960, 
+    45056, 45312, 45313, 45315, 45296, 45304,     0, 32768, 
+    40960, 45056, 45312, 45313, 45315, 45296, 45304, 45306, 
+        0, 32768, 40960, 45056, 45312, 45313, 45315, 45319, 
+    45304,     0, 32768, 40960, 45056, 45312, 45313, 45315, 
+    45319, 45304, 45308,     0, 32768, 40960, 45056, 45312, 
+    45313, 45315, 45319, 45304, 45308,     0, 32768, 40960, 
+    45056, 45312, 45313, 45315, 45319, 45304, 45308, 45310, 
+        0, 32768, 40960, 45056,     0, 32768, 40960, 45056, 
+    45312,     0, 32768, 40960, 45056, 45312,     0, 32768, 
+    40960, 45056, 45312, 45314,     0, 32768, 40960, 45056, 
+    45312,     0, 32768, 40960, 45056, 45312, 45316,     0, 
+    32768, 40960, 45056, 45312, 45316,     0, 32768, 40960, 
+    45056, 45312, 45320, 45318,     0, 32768, 40960, 45056, 
+    45312,     0, 32768, 40960, 45056, 45312, 45320,     0, 
+    32768, 40960, 45056, 45312, 45320,     0, 32768, 40960, 
+    45056, 45312, 45320, 45322,     0, 32768, 40960, 45056, 
+    45312, 45320,     0, 32768, 40960, 45056, 45312, 45328, 
+    45324,     0, 32768, 40960, 45056, 45312, 45328, 45324, 
+        0, 32768, 40960, 45056, 45312, 45328, 45329, 45326, 
+        0, 32768, 40960, 45056, 45312,     0, 32768, 40960, 
+    45056, 45312, 45328,     0, 32768, 40960, 45056, 45312, 
+    45328,     0, 32768, 40960, 45056, 45312, 45328, 45330, 
+        0, 32768, 40960, 45056, 45312, 45328,     0, 32768, 
+    40960, 45056, 45312, 45328, 45332,     0, 32768, 40960, 
+    45056, 45312, 45328, 45332,     0, 32768, 40960, 45056, 
+    45312, 45328, 45336, 45334,     0, 32768, 40960, 45056, 
+    45312, 45328,     0, 32768, 40960, 45056, 45312, 45344, 
+    45336,     0, 32768, 40960, 45056, 45312, 45344, 45336, 
+        0, 32768, 40960, 45056, 45312, 45344, 45336, 45338, 
+        0, 32768, 40960, 45056, 45312, 45344, 45336,     0, 
+    32768, 40960, 45056, 45312, 45344, 45345, 45340,     0, 
+    32768, 40960, 45056, 45312, 45344, 45345, 45340,     0, 
+    32768, 40960, 45056, 45312, 45344, 45345, 45340, 45342, 
+        0, 32768, 40960, 45056, 45312,     0, 32768, 40960, 
+    45056, 45312, 45344,     0, 32768, 40960, 45056, 45312, 
+    45344,     0, 32768, 40960, 45056, 45312, 45344, 45346, 
+        0, 32768, 40960, 45056, 45312, 45344,     0, 32768, 
+    40960, 45056, 45312, 45344, 45348,     0, 32768, 40960, 
+    45056, 45312, 45344, 45348,     0, 32768, 40960, 45056, 
+    45312, 45344, 45352, 45350,     0, 32768, 40960, 45056, 
+    45312, 45344,     0, 32768, 40960, 45056, 45312, 45344, 
+    45352,     0, 32768, 40960, 45056, 45312, 45344, 45352, 
+        0, 32768, 40960, 45056, 45312, 45344, 45352, 45354, 
+        0, 32768, 40960, 45056, 45312, 45344, 45352,     0, 
+    32768, 40960, 45056, 45312, 45344, 45360, 45356,     0, 
+    32768, 40960, 45056, 45312, 45344, 45360, 45356,     0, 
+    32768, 40960, 45056, 45312, 45344, 45360, 45361, 45358, 
+        0, 32768, 40960, 45056, 45312, 45344,     0, 32768, 
+    40960, 45056, 45312, 45376, 45360,     0, 32768, 40960, 
+    45056, 45312, 45376, 45360,     0, 32768, 40960, 45056, 
+    45312, 45376, 45360, 45362,     0, 32768, 40960, 45056, 
+    45312, 45376, 45360,     0, 32768, 40960, 45056, 45312, 
+    45376, 45360, 45364,     0, 32768, 40960, 45056, 45312, 
+    45376, 45360, 45364,     0, 32768, 40960, 45056, 45312, 
+    45376, 45360, 45368, 45366,     0, 32768, 40960, 45056, 
+    45312, 45376, 45360,     0, 32768, 40960, 45056, 45312, 
+    45376, 45377, 45368,     0, 32768, 40960, 45056, 45312, 
+    45376, 45377, 45368,     0, 32768, 40960, 45056, 45312, 
+    45376, 45377, 45368, 45370,     0, 32768, 40960, 45056, 
+    45312, 45376, 45377, 45368,     0, 32768, 40960, 45056, 
+    45312, 45376, 45377, 45368, 45372,     0, 32768, 40960, 
+    45056, 45312, 45376, 45377, 45379, 45372,     0, 32768, 
+    40960, 45056, 45312, 45376, 45377, 45379, 45372, 45374, 
+        0, 32768, 40960, 45056, 45312,     0, 32768, 40960, 
+    45056, 45312, 45376,     0, 32768, 40960, 45056, 45312, 
+    45376,     0, 32768, 40960, 45056, 45312, 45376, 45378, 
+        0, 32768, 40960, 45056, 45312, 45376,     0, 32768, 
+    40960, 45056, 45312, 45376, 45380,     0, 32768, 40960, 
+    45056, 45312, 45376, 45380,     0, 32768, 40960, 45056, 
+    45312, 45376, 45384, 45382,     0, 32768, 40960, 45056, 
+    45312, 45376,     0, 32768, 40960, 45056, 45312, 45376, 
+    45384,     0, 32768, 40960, 45056, 45312, 45376, 45384, 
+        0, 32768, 40960, 45056, 45312, 45376, 45384, 45386, 
+        0, 32768, 40960, 45056, 45312, 45376, 45384,     0, 
+    32768, 40960, 45056, 45312, 45376, 45392, 45388,     0, 
+    32768, 40960, 45056, 45312, 45376, 45392, 45388,     0, 
+    32768, 40960, 45056, 45312, 45376, 45392, 45393, 45390, 
+        0, 32768, 40960, 45056, 45312, 45376,     0, 32768, 
+    40960, 45056, 45312, 45376, 45392,     0, 32768, 40960, 
+    45056, 45312, 45376, 45392,     0, 32768, 40960, 45056, 
+    45312, 45376, 45392, 45394,     0, 32768, 40960, 45056, 
+    45312, 45376, 45392,     0, 32768, 40960, 45056, 45312, 
+    45376, 45392, 45396,     0, 32768, 40960, 45056, 45312, 
+    45376, 45392, 45396,     0, 32768, 40960, 45056, 45312, 
+    45376, 45392, 45400, 45398,     0, 32768, 40960, 45056, 
+    45312, 45376, 45392,     0, 32768, 40960, 45056, 45312, 
+    45376, 45408, 45400,     0, 32768, 40960, 45056, 45312, 
+    45376, 45408, 45400,     0, 32768, 40960, 45056, 45312, 
+    45376, 45408, 45400, 45402,     0, 32768, 40960, 45056, 
+    45312, 45376, 45408, 45400,     0, 32768, 40960, 45056, 
+    45312, 45376, 45408, 45409, 45404,     0, 32768, 40960, 
+    45056, 45312, 45376, 45408, 45409, 45404,     0, 32768, 
+    40960, 45056, 45312, 45376, 45408, 45409, 45404, 45406, 
+        0, 32768, 40960, 45056, 45312, 45376,     0, 32768, 
+    40960, 45056, 45312, 45440, 45408,     0, 32768, 40960, 
+    45056, 45312, 45440, 45408,     0, 32768, 40960, 45056, 
+    45312, 45440, 45408, 45410,     0, 32768, 40960, 45056, 
+    45312, 45440, 45408,     0, 32768, 40960, 45056, 45312, 
+    45440, 45408, 45412,     0, 32768, 40960, 45056, 45312, 
+    45440, 45408, 45412,     0, 32768, 40960, 45056, 45312, 
+    45440, 45408, 45416, 45414,     0, 32768, 40960, 45056, 
+    45312, 45440, 45408,     0, 32768, 40960, 45056, 45312, 
+    45440, 45408, 45416,     0, 32768, 40960, 45056, 45312, 
+    45440, 45408, 45416,     0, 32768, 40960, 45056, 45312, 
+    45440, 45408, 45416, 45418,     0, 32768, 40960, 45056, 
+    45312, 45440, 45408, 45416,     0, 32768, 40960, 45056, 
+    45312, 45440, 45408, 45424, 45420,     0, 32768, 40960, 
+    45056, 45312, 45440, 45408, 45424, 45420,     0, 32768, 
+    40960, 45056, 45312, 45440, 45408, 45424, 45425, 45422, 
+        0, 32768, 40960, 45056, 45312, 45440, 45408,     0, 
+    32768, 40960, 45056, 45312, 45440, 45441, 45424,     0, 
+    32768, 40960, 45056, 45312, 45440, 45441, 45424,     0, 
+    32768, 40960, 45056, 45312, 45440, 45441, 45424, 45426, 
+        0, 32768, 40960, 45056, 45312, 45440, 45441, 45424, 
+        0, 32768, 40960, 45056, 45312, 45440, 45441, 45424, 
+    45428,     0, 32768, 40960, 45056, 45312, 45440, 45441, 
+    45424, 45428,     0, 32768, 40960, 45056, 45312, 45440, 
+    45441, 45424, 45432, 45430,     0, 32768, 40960, 45056, 
+    45312, 45440, 45441, 45424,     0, 32768, 40960, 45056, 
+    45312, 45440, 45441, 45424, 45432,     0, 32768, 40960, 
+    45056, 45312, 45440, 45441, 45443, 45432,     0, 32768, 
+    40960, 45056, 45312, 45440, 45441, 45443, 45432, 45434, 
+        0, 32768, 40960, 45056, 45312, 45440, 45441, 45443, 
+    45432,     0, 32768, 40960, 45056, 45312, 45440, 45441, 
+    45443, 45432, 45436,     0, 32768, 40960, 45056, 45312, 
+    45440, 45441, 45443, 45432, 45436,     0, 32768, 40960, 
+    45056, 45312, 45440, 45441, 45443, 45432, 45436, 45438, 
+        0, 32768, 40960, 45056, 45312,     0, 32768, 40960, 
+    45056, 45568, 45440,     0, 32768, 40960, 45056, 45568, 
+    45440,     0, 32768, 40960, 45056, 45568, 45440, 45442, 
+        0, 32768, 40960, 45056, 45568, 45440,     0, 32768, 
+    40960, 45056, 45568, 45440, 45444,     0, 32768, 40960, 
+    45056, 45568, 45440, 45444,     0, 32768, 40960, 45056, 
+    45568, 45440, 45448, 45446,     0, 32768, 40960, 45056, 
+    45568, 45440,     0, 32768, 40960, 45056, 45568, 45440, 
+    45448,     0, 32768, 40960, 45056, 45568, 45440, 45448, 
+        0, 32768, 40960, 45056, 45568, 45440, 45448, 45450, 
+        0, 32768, 40960, 45056, 45568, 45440, 45448,     0, 
+    32768, 40960, 45056, 45568, 45440, 45456, 45452,     0, 
+    32768, 40960, 45056, 45568, 45440, 45456, 45452,     0, 
+    32768, 40960, 45056, 45568, 45440, 45456, 45457, 45454, 
+        0, 32768, 40960, 45056, 45568, 45440,     0, 32768, 
+    40960, 45056, 45568, 45440, 45456,     0, 32768, 40960, 
+    45056, 45568, 45440, 45456,     0, 32768, 40960, 45056, 
+    45568, 45440, 45456, 45458,     0, 32768, 40960, 45056, 
+    45568, 45440, 45456,     0, 32768, 40960, 45056, 45568, 
+    45440, 45456, 45460,     0, 32768, 40960, 45056, 45568, 
+    45440, 45456, 45460,     0, 32768, 40960, 45056, 45568, 
+    45440, 45456, 45464, 45462,     0, 32768, 40960, 45056, 
+    45568, 45440, 45456,     0, 32768, 40960, 45056, 45568, 
+    45440, 45472, 45464,     0, 32768, 40960, 45056, 45568, 
+    45440, 45472, 45464,     0, 32768, 40960, 45056, 45568, 
+    45440, 45472, 45464, 45466,     0, 32768, 40960, 45056, 
+    45568, 45440, 45472, 45464,     0, 32768, 40960, 45056, 
+    45568, 45440, 45472, 45473, 45468,     0, 32768, 40960, 
+    45056, 45568, 45440, 45472, 45473, 45468,     0, 32768, 
+    40960, 45056, 45568, 45440, 45472, 45473, 45468, 45470, 
+        0, 32768, 40960, 45056, 45568, 45440,     0, 32768, 
+    40960, 45056, 45568, 45440, 45472,     0, 32768, 40960, 
+    45056, 45568, 45440, 45472,     0, 32768, 40960, 45056, 
+    45568, 45440, 45472, 45474,     0, 32768, 40960, 45056, 
+    45568, 45440, 45472,     0, 32768, 40960, 45056, 45568, 
+    45440, 45472, 45476,     0, 32768, 40960, 45056, 45568, 
+    45440, 45472, 45476,     0, 32768, 40960, 45056, 45568, 
+    45440, 45472, 45480, 45478,     0, 32768, 40960, 45056, 
+    45568, 45440, 45472,     0, 32768, 40960, 45056, 45568, 
+    45440, 45472, 45480,     0, 32768, 40960, 45056, 45568, 
+    45440, 45472, 45480,     0, 32768, 40960, 45056, 45568, 
+    45440, 45472, 45480, 45482,     0, 32768, 40960, 45056, 
+    45568, 45440, 45472, 45480,     0, 32768, 40960, 45056, 
+    45568, 45440, 45472, 45488, 45484,     0, 32768, 40960, 
+    45056, 45568, 45440, 45472, 45488, 45484,     0, 32768, 
+    40960, 45056, 45568, 45440, 45472, 45488, 45489, 45486, 
+        0, 32768, 40960, 45056, 45568, 45440, 45472,     0, 
+    32768, 40960, 45056, 45568, 45440, 45504, 45488,     0, 
+    32768, 40960, 45056, 45568, 45440, 45504, 45488,     0, 
+    32768, 40960, 45056, 45568, 45440, 45504, 45488, 45490, 
+        0, 32768, 40960, 45056, 45568, 45440, 45504, 45488, 
+        0, 32768, 40960, 45056, 45568, 45440, 45504, 45488, 
+    45492,     0, 32768, 40960, 45056, 45568, 45440, 45504, 
+    45488, 45492,     0, 32768, 40960, 45056, 45568, 45440, 
+    45504, 45488, 45496, 45494,     0, 32768, 40960, 45056, 
+    45568, 45440, 45504, 45488,     0, 32768, 40960, 45056, 
+    45568, 45440, 45504, 45505, 45496,     0, 32768, 40960, 
+    45056, 45568, 45440, 45504, 45505, 45496,     0, 32768, 
+    40960, 45056, 45568, 45440, 45504, 45505, 45496, 45498, 
+        0, 32768, 40960, 45056, 45568, 45440, 45504, 45505, 
+    45496,     0, 32768, 40960, 45056, 45568, 45440, 45504, 
+    45505, 45496, 45500,     0, 32768, 40960, 45056, 45568, 
+    45440, 45504, 45505, 45507, 45500,     0, 32768, 40960, 
+    45056, 45568, 45440, 45504, 45505, 45507, 45500, 45502, 
+        0, 32768, 40960, 45056, 45568, 45440,     0, 32768, 
+    40960, 45056, 45568, 45569, 45504,     0, 32768, 40960, 
+    45056, 45568, 45569, 45504,     0, 32768, 40960, 45056, 
+    45568, 45569, 45504, 45506,     0, 32768, 40960, 45056, 
+    45568, 45569, 45504,     0, 32768, 40960, 45056, 45568, 
+    45569, 45504, 45508,     0, 32768, 40960, 45056, 45568, 
+    45569, 45504, 45508,     0, 32768, 40960, 45056, 45568, 
+    45569, 45504, 45512, 45510,     0, 32768, 40960, 45056, 
+    45568, 45569, 45504,     0, 32768, 40960, 45056, 45568, 
+    45569, 45504, 45512,     0, 32768, 40960, 45056, 45568, 
+    45569, 45504, 45512,     0, 32768, 40960, 45056, 45568, 
+    45569, 45504, 45512, 45514,     0, 32768, 40960, 45056, 
+    45568, 45569, 45504, 45512,     0, 32768, 40960, 45056, 
+    45568, 45569, 45504, 45520, 45516,     0, 32768, 40960, 
+    45056, 45568, 45569, 45504, 45520, 45516,     0, 32768, 
+    40960, 45056, 45568, 45569, 45504, 45520, 45521, 45518, 
+        0, 32768, 40960, 45056, 45568, 45569, 45504,     0, 
+    32768, 40960, 45056, 45568, 45569, 45504, 45520,     0, 
+    32768, 40960, 45056, 45568, 45569, 45504, 45520,     0, 
+    32768, 40960, 45056, 45568, 45569, 45504, 45520, 45522, 
+        0, 32768, 40960, 45056, 45568, 45569, 45504, 45520, 
+        0, 32768, 40960, 45056, 45568, 45569, 45504, 45520, 
+    45524,     0, 32768, 40960, 45056, 45568, 45569, 45504, 
+    45520, 45524,     0, 32768, 40960, 45056, 45568, 45569, 
+    45504, 45520, 45528, 45526,     0, 32768, 40960, 45056, 
+    45568, 45569, 45504, 45520,     0, 32768, 40960, 45056, 
+    45568, 45569, 45504, 45536, 45528,     0, 32768, 40960, 
+    45056, 45568, 45569, 45504, 45536, 45528,     0, 32768, 
+    40960, 45056, 45568, 45569, 45504, 45536, 45528, 45530, 
+        0, 32768, 40960, 45056, 45568, 45569, 45504, 45536, 
+    45528,     0, 32768, 40960, 45056, 45568, 45569, 45504, 
+    45536, 45537, 45532,     0, 32768, 40960, 45056, 45568, 
+    45569, 45504, 45536, 45537, 45532,     0, 32768, 40960, 
+    45056, 45568, 45569, 45504, 45536, 45537, 45532, 45534, 
+        0, 32768, 40960, 45056, 45568, 45569, 45504,     0, 
+    32768, 40960, 45056, 45568, 45569, 45504, 45536,     0, 
+    32768, 40960, 45056, 45568, 45569, 45571, 45536,     0, 
+    32768, 40960, 45056, 45568, 45569, 45571, 45536, 45538, 
+        0, 32768, 40960, 45056, 45568, 45569, 45571, 45536, 
+        0, 32768, 40960, 45056, 45568, 45569, 45571, 45536, 
+    45540,     0, 32768, 40960, 45056, 45568, 45569, 45571, 
+    45536, 45540,     0, 32768, 40960, 45056, 45568, 45569, 
+    45571, 45536, 45544, 45542,     0, 32768, 40960, 45056, 
+    45568, 45569, 45571, 45536,     0, 32768, 40960, 45056, 
+    45568, 45569, 45571, 45536, 45544,     0, 32768, 40960, 
+    45056, 45568, 45569, 45571, 45536, 45544,     0, 32768, 
+    40960, 45056, 45568, 45569, 45571, 45536, 45544, 45546, 
+        0, 32768, 40960, 45056, 45568, 45569, 45571, 45536, 
+    45544,     0, 32768, 40960, 45056, 45568, 45569, 45571, 
+    45536, 45552, 45548,     0, 32768, 40960, 45056, 45568, 
+    45569, 45571, 45536, 45552, 45548,     0, 32768, 40960, 
+    45056, 45568, 45569, 45571, 45536, 45552, 45553, 45550, 
+        0, 32768, 40960, 45056, 45568, 45569, 45571, 45536, 
+        0, 32768, 40960, 45056, 45568, 45569, 45571, 45536, 
+    45552,     0, 32768, 40960, 45056, 45568, 45569, 45571, 
+    45536, 45552,     0, 32768, 40960, 45056, 45568, 45569, 
+    45571, 45536, 45552, 45554,     0, 32768, 40960, 45056, 
+    45568, 45569, 45571, 45575, 45552,     0, 32768, 40960, 
+    45056, 45568, 45569, 45571, 45575, 45552, 45556,     0, 
+    32768, 40960, 45056, 45568, 45569, 45571, 45575, 45552, 
+    45556,     0, 32768, 40960, 45056, 45568, 45569, 45571, 
+    45575, 45552, 45560, 45558,     0, 32768, 40960, 45056, 
+    45568, 45569, 45571, 45575, 45552,     0, 32768, 40960, 
+    45056, 45568, 45569, 45571, 45575, 45552, 45560,     0, 
+    32768, 40960, 45056, 45568, 45569, 45571, 45575, 45552, 
+    45560,     0, 32768, 40960, 45056, 45568, 45569, 45571, 
+    45575, 45552, 45560, 45562,     0, 32768, 40960, 45056, 
+    45568, 45569, 45571, 45575, 45552, 45560,     0, 32768, 
+    40960, 45056, 45568, 45569, 45571, 45575, 45552, 45560, 
+    45564,     0, 32768, 40960, 45056, 45568, 45569, 45571, 
+    45575, 45552, 45560, 45564,     0, 32768, 40960, 45056, 
+    45568, 45569, 45571, 45575, 45552, 45560, 45564, 45566, 
+        0, 32768, 40960, 45056,     0, 32768, 40960, 45056, 
+    45568,     0, 32768, 40960, 45056, 45568,     0, 32768, 
+    40960, 45056, 45568, 45570,     0, 32768, 40960, 45056, 
+    45568,     0, 32768, 40960, 45056, 45568, 45572,     0, 
+    32768, 40960, 45056, 45568, 45572,     0, 32768, 40960, 
+    45056, 45568, 45576, 45574,     0, 32768, 40960, 45056, 
+    45568,     0, 32768, 40960, 45056, 45568, 45576,     0, 
+    32768, 40960, 45056, 45568, 45576,     0, 32768, 40960, 
+    45056, 45568, 45576, 45578,     0, 32768, 40960, 45056, 
+    45568, 45576,     0, 32768, 40960, 45056, 45568, 45584, 
+    45580,     0, 32768, 40960, 45056, 45568, 45584, 45580, 
+        0, 32768, 40960, 45056, 45568, 45584, 45585, 45582, 
+        0, 32768, 40960, 45056, 45568,     0, 32768, 40960, 
+    45056, 45568, 45584,     0, 32768, 40960, 45056, 45568, 
+    45584,     0, 32768, 40960, 45056, 45568, 45584, 45586, 
+        0, 32768, 40960, 45056, 45568, 45584,     0, 32768, 
+    40960, 45056, 45568, 45584, 45588,     0, 32768, 40960, 
+    45056, 45568, 45584, 45588,     0, 32768, 40960, 45056, 
+    45568, 45584, 45592, 45590,     0, 32768, 40960, 45056, 
+    45568, 45584,     0, 32768, 40960, 45056, 45568, 45600, 
+    45592,     0, 32768, 40960, 45056, 45568, 45600, 45592, 
+        0, 32768, 40960, 45056, 45568, 45600, 45592, 45594, 
+        0, 32768, 40960, 45056, 45568, 45600, 45592,     0, 
+    32768, 40960, 45056, 45568, 45600, 45601, 45596,     0, 
+    32768, 40960, 45056, 45568, 45600, 45601, 45596,     0, 
+    32768, 40960, 45056, 45568, 45600, 45601, 45596, 45598, 
+        0, 32768, 40960, 45056, 45568,     0, 32768, 40960, 
+    45056, 45568, 45600,     0, 32768, 40960, 45056, 45568, 
+    45600,     0, 32768, 40960, 45056, 45568, 45600, 45602, 
+        0, 32768, 40960, 45056, 45568, 45600,     0, 32768, 
+    40960, 45056, 45568, 45600, 45604,     0, 32768, 40960, 
+    45056, 45568, 45600, 45604,     0, 32768, 40960, 45056, 
+    45568, 45600, 45608, 45606,     0, 32768, 40960, 45056, 
+    45568, 45600,     0, 32768, 40960, 45056, 45568, 45600, 
+    45608,     0, 32768, 40960, 45056, 45568, 45600, 45608, 
+        0, 32768, 40960, 45056, 45568, 45600, 45608, 45610, 
+        0, 32768, 40960, 45056, 45568, 45600, 45608,     0, 
+    32768, 40960, 45056, 45568, 45600, 45616, 45612,     0, 
+    32768, 40960, 45056, 45568, 45600, 45616, 45612,     0, 
+    32768, 40960, 45056, 45568, 45600, 45616, 45617, 45614, 
+        0, 32768, 40960, 45056, 45568, 45600,     0, 32768, 
+    40960, 45056, 45568, 45632, 45616,     0, 32768, 40960, 
+    45056, 45568, 45632, 45616,     0, 32768, 40960, 45056, 
+    45568, 45632, 45616, 45618,     0, 32768, 40960, 45056, 
+    45568, 45632, 45616,     0, 32768, 40960, 45056, 45568, 
+    45632, 45616, 45620,     0, 32768, 40960, 45056, 45568, 
+    45632, 45616, 45620,     0, 32768, 40960, 45056, 45568, 
+    45632, 45616, 45624, 45622,     0, 32768, 40960, 45056, 
+    45568, 45632, 45616,     0, 32768, 40960, 45056, 45568, 
+    45632, 45633, 45624,     0, 32768, 40960, 45056, 45568, 
+    45632, 45633, 45624,     0, 32768, 40960, 45056, 45568, 
+    45632, 45633, 45624, 45626,     0, 32768, 40960, 45056, 
+    45568, 45632, 45633, 45624,     0, 32768, 40960, 45056, 
+    45568, 45632, 45633, 45624, 45628,     0, 32768, 40960, 
+    45056, 45568, 45632, 45633, 45635, 45628,     0, 32768, 
+    40960, 45056, 45568, 45632, 45633, 45635, 45628, 45630, 
+        0, 32768, 40960, 45056, 45568,     0, 32768, 40960, 
+    45056, 45568, 45632,     0, 32768, 40960, 45056, 45568, 
+    45632,     0, 32768, 40960, 45056, 45568, 45632, 45634, 
+        0, 32768, 40960, 45056, 45568, 45632,     0, 32768, 
+    40960, 45056, 45568, 45632, 45636,     0, 32768, 40960, 
+    45056, 45568, 45632, 45636,     0, 32768, 40960, 45056, 
+    45568, 45632, 45640, 45638,     0, 32768, 40960, 45056, 
+    45568, 45632,     0, 32768, 40960, 45056, 45568, 45632, 
+    45640,     0, 32768, 40960, 45056, 45568, 45632, 45640, 
+        0, 32768, 40960, 45056, 45568, 45632, 45640, 45642, 
+        0, 32768, 40960, 45056, 45568, 45632, 45640,     0, 
+    32768, 40960, 45056, 45568, 45632, 45648, 45644,     0, 
+    32768, 40960, 45056, 45568, 45632, 45648, 45644,     0, 
+    32768, 40960, 45056, 45568, 45632, 45648, 45649, 45646, 
+        0, 32768, 40960, 45056, 45568, 45632,     0, 32768, 
+    40960, 45056, 45568, 45632, 45648,     0, 32768, 40960, 
+    45056, 45568, 45632, 45648,     0, 32768, 40960, 45056, 
+    45568, 45632, 45648, 45650,     0, 32768, 40960, 45056, 
+    45568, 45632, 45648,     0, 32768, 40960, 45056, 45568, 
+    45632, 45648, 45652,     0, 32768, 40960, 45056, 45568, 
+    45632, 45648, 45652,     0, 32768, 40960, 45056, 45568, 
+    45632, 45648, 45656, 45654,     0, 32768, 40960, 45056, 
+    45568, 45632, 45648,     0, 32768, 40960, 45056, 45568, 
+    45632, 45664, 45656,     0, 32768, 40960, 45056, 45568, 
+    45632, 45664, 45656,     0, 32768, 40960, 45056, 45568, 
+    45632, 45664, 45656, 45658,     0, 32768, 40960, 45056, 
+    45568, 45632, 45664, 45656,     0, 32768, 40960, 45056, 
+    45568, 45632, 45664, 45665, 45660,     0, 32768, 40960, 
+    45056, 45568, 45632, 45664, 45665, 45660,     0, 32768, 
+    40960, 45056, 45568, 45632, 45664, 45665, 45660, 45662, 
+        0, 32768, 40960, 45056, 45568, 45632,     0, 32768, 
+    40960, 45056, 45568, 45696, 45664,     0, 32768, 40960, 
+    45056, 45568, 45696, 45664,     0, 32768, 40960, 45056, 
+    45568, 45696, 45664, 45666,     0, 32768, 40960, 45056, 
+    45568, 45696, 45664,     0, 32768, 40960, 45056, 45568, 
+    45696, 45664, 45668,     0, 32768, 40960, 45056, 45568, 
+    45696, 45664, 45668,     0, 32768, 40960, 45056, 45568, 
+    45696, 45664, 45672, 45670,     0, 32768, 40960, 45056, 
+    45568, 45696, 45664,     0, 32768, 40960, 45056, 45568, 
+    45696, 45664, 45672,     0, 32768, 40960, 45056, 45568, 
+    45696, 45664, 45672,     0, 32768, 40960, 45056, 45568, 
+    45696, 45664, 45672, 45674,     0, 32768, 40960, 45056, 
+    45568, 45696, 45664, 45672,     0, 32768, 40960, 45056, 
+    45568, 45696, 45664, 45680, 45676,     0, 32768, 40960, 
+    45056, 45568, 45696, 45664, 45680, 45676,     0, 32768, 
+    40960, 45056, 45568, 45696, 45664, 45680, 45681, 45678, 
+        0, 32768, 40960, 45056, 45568, 45696, 45664,     0, 
+    32768, 40960, 45056, 45568, 45696, 45697, 45680,     0, 
+    32768, 40960, 45056, 45568, 45696, 45697, 45680,     0, 
+    32768, 40960, 45056, 45568, 45696, 45697, 45680, 45682, 
+        0, 32768, 40960, 45056, 45568, 45696, 45697, 45680, 
+        0, 32768, 40960, 45056, 45568, 45696, 45697, 45680, 
+    45684,     0, 32768, 40960, 45056, 45568, 45696, 45697, 
+    45680, 45684,     0, 32768, 40960, 45056, 45568, 45696, 
+    45697, 45680, 45688, 45686,     0, 32768, 40960, 45056, 
+    45568, 45696, 45697, 45680,     0, 32768, 40960, 45056, 
+    45568, 45696, 45697, 45680, 45688,     0, 32768, 40960, 
+    45056, 45568, 45696, 45697, 45699, 45688,     0, 32768, 
+    40960, 45056, 45568, 45696, 45697, 45699, 45688, 45690, 
+        0, 32768, 40960, 45056, 45568, 45696, 45697, 45699, 
+    45688,     0, 32768, 40960, 45056, 45568, 45696, 45697, 
+    45699, 45688, 45692,     0, 32768, 40960, 45056, 45568, 
+    45696, 45697, 45699, 45688, 45692,     0, 32768, 40960, 
+    45056, 45568, 45696, 45697, 45699, 45688, 45692, 45694, 
+        0, 32768, 40960, 45056, 45568,     0, 32768, 40960, 
+    45056, 45568, 45696,     0, 32768, 40960, 45056, 45568, 
+    45696,     0, 32768, 40960, 45056, 45568, 45696, 45698, 
+        0, 32768, 40960, 45056, 45568, 45696,     0, 32768, 
+    40960, 45056, 45568, 45696, 45700,     0, 32768, 40960, 
+    45056, 45568, 45696, 45700,     0, 32768, 40960, 45056, 
+    45568, 45696, 45704, 45702,     0, 32768, 40960, 45056, 
+    45568, 45696,     0, 32768, 40960, 45056, 45568, 45696, 
+    45704,     0, 32768, 40960, 45056, 45568, 45696, 45704, 
+        0, 32768, 40960, 45056, 45568, 45696, 45704, 45706, 
+        0, 32768, 40960, 45056, 45568, 45696, 45704,     0, 
+    32768, 40960, 45056, 45568, 45696, 45712, 45708,     0, 
+    32768, 40960, 45056, 45568, 45696, 45712, 45708,     0, 
+    32768, 40960, 45056, 45568, 45696, 45712, 45713, 45710, 
+        0, 32768, 40960, 45056, 45568, 45696,     0, 32768, 
+    40960, 45056, 45568, 45696, 45712,     0, 32768, 40960, 
+    45056, 45568, 45696, 45712,     0, 32768, 40960, 45056, 
+    45568, 45696, 45712, 45714,     0, 32768, 40960, 45056, 
+    45568, 45696, 45712,     0, 32768, 40960, 45056, 45568, 
+    45696, 45712, 45716,     0, 32768, 40960, 45056, 45568, 
+    45696, 45712, 45716,     0, 32768, 40960, 45056, 45568, 
+    45696, 45712, 45720, 45718,     0, 32768, 40960, 45056, 
+    45568, 45696, 45712,     0, 32768, 40960, 45056, 45568, 
+    45696, 45728, 45720,     0, 32768, 40960, 45056, 45568, 
+    45696, 45728, 45720,     0, 32768, 40960, 45056, 45568, 
+    45696, 45728, 45720, 45722,     0, 32768, 40960, 45056, 
+    45568, 45696, 45728, 45720,     0, 32768, 40960, 45056, 
+    45568, 45696, 45728, 45729, 45724,     0, 32768, 40960, 
+    45056, 45568, 45696, 45728, 45729, 45724,     0, 32768, 
+    40960, 45056, 45568, 45696, 45728, 45729, 45724, 45726, 
+        0, 32768, 40960, 45056, 45568, 45696,     0, 32768, 
+    40960, 45056, 45568, 45696, 45728,     0, 32768, 40960, 
+    45056, 45568, 45696, 45728,     0, 32768, 40960, 45056, 
+    45568, 45696, 45728, 45730,     0, 32768, 40960, 45056, 
+    45568, 45696, 45728,     0, 32768, 40960, 45056, 45568, 
+    45696, 45728, 45732,     0, 32768, 40960, 45056, 45568, 
+    45696, 45728, 45732,     0, 32768, 40960, 45056, 45568, 
+    45696, 45728, 45736, 45734,     0, 32768, 40960, 45056, 
+    45568, 45696, 45728,     0, 32768, 40960, 45056, 45568, 
+    45696, 45728, 45736,     0, 32768, 40960, 45056, 45568, 
+    45696, 45728, 45736,     0, 32768, 40960, 45056, 45568, 
+    45696, 45728, 45736, 45738,     0, 32768, 40960, 45056, 
+    45568, 45696, 45728, 45736,     0, 32768, 40960, 45056, 
+    45568, 45696, 45728, 45744, 45740,     0, 32768, 40960, 
+    45056, 45568, 45696, 45728, 45744, 45740,     0, 32768, 
+    40960, 45056, 45568, 45696, 45728, 45744, 45745, 45742, 
+        0, 32768, 40960, 45056, 45568, 45696, 45728,     0, 
+    32768, 40960, 45056, 45568, 45696, 45760, 45744,     0, 
+    32768, 40960, 45056, 45568, 45696, 45760, 45744,     0, 
+    32768, 40960, 45056, 45568, 45696, 45760, 45744, 45746, 
+        0, 32768, 40960, 45056, 45568, 45696, 45760, 45744, 
+        0, 32768, 40960, 45056, 45568, 45696, 45760, 45744, 
+    45748,     0, 32768, 40960, 45056, 45568, 45696, 45760, 
+    45744, 45748,     0, 32768, 40960, 45056, 45568, 45696, 
+    45760, 45744, 45752, 45750,     0, 32768, 40960, 45056, 
+    45568, 45696, 45760, 45744,     0, 32768, 40960, 45056, 
+    45568, 45696, 45760, 45761, 45752,     0, 32768, 40960, 
+    45056, 45568, 45696, 45760, 45761, 45752,     0, 32768, 
+    40960, 45056, 45568, 45696, 45760, 45761, 45752, 45754, 
+        0, 32768, 40960, 45056, 45568, 45696, 45760, 45761, 
+    45752,     0, 32768, 40960, 45056, 45568, 45696, 45760, 
+    45761, 45752, 45756,     0, 32768, 40960, 45056, 45568, 
+    45696, 45760, 45761, 45763, 45756,     0, 32768, 40960, 
+    45056, 45568, 45696, 45760, 45761, 45763, 45756, 45758, 
+        0, 32768, 40960, 45056, 45568, 45696,     0, 32768, 
+    40960, 45056, 45568, 45824, 45760,     0, 32768, 40960, 
+    45056, 45568, 45824, 45760,     0, 32768, 40960, 45056, 
+    45568, 45824, 45760, 45762,     0, 32768, 40960, 45056, 
+    45568, 45824, 45760,     0, 32768, 40960, 45056, 45568, 
+    45824, 45760, 45764,     0, 32768, 40960, 45056, 45568, 
+    45824, 45760, 45764,     0, 32768, 40960, 45056, 45568, 
+    45824, 45760, 45768, 45766,     0, 32768, 40960, 45056, 
+    45568, 45824, 45760,     0, 32768, 40960, 45056, 45568, 
+    45824, 45760, 45768,     0, 32768, 40960, 45056, 45568, 
+    45824, 45760, 45768,     0, 32768, 40960, 45056, 45568, 
+    45824, 45760, 45768, 45770,     0, 32768, 40960, 45056, 
+    45568, 45824, 45760, 45768,     0, 32768, 40960, 45056, 
+    45568, 45824, 45760, 45776, 45772,     0, 32768, 40960, 
+    45056, 45568, 45824, 45760, 45776, 45772,     0, 32768, 
+    40960, 45056, 45568, 45824, 45760, 45776, 45777, 45774, 
+        0, 32768, 40960, 45056, 45568, 45824, 45760,     0, 
+    32768, 40960, 45056, 45568, 45824, 45760, 45776,     0, 
+    32768, 40960, 45056, 45568, 45824, 45760, 45776,     0, 
+    32768, 40960, 45056, 45568, 45824, 45760, 45776, 45778, 
+        0, 32768, 40960, 45056, 45568, 45824, 45760, 45776, 
+        0, 32768, 40960, 45056, 45568, 45824, 45760, 45776, 
+    45780,     0, 32768, 40960, 45056, 45568, 45824, 45760, 
+    45776, 45780,     0, 32768, 40960, 45056, 45568, 45824, 
+    45760, 45776, 45784, 45782,     0, 32768, 40960, 45056, 
+    45568, 45824, 45760, 45776,     0, 32768, 40960, 45056, 
+    45568, 45824, 45760, 45792, 45784,     0, 32768, 40960, 
+    45056, 45568, 45824, 45760, 45792, 45784,     0, 32768, 
+    40960, 45056, 45568, 45824, 45760, 45792, 45784, 45786, 
+        0, 32768, 40960, 45056, 45568, 45824, 45760, 45792, 
+    45784,     0, 32768, 40960, 45056, 45568, 45824, 45760, 
+    45792, 45793, 45788,     0, 32768, 40960, 45056, 45568, 
+    45824, 45760, 45792, 45793, 45788,     0, 32768, 40960, 
+    45056, 45568, 45824, 45760, 45792, 45793, 45788, 45790, 
+        0, 32768, 40960, 45056, 45568, 45824, 45760,     0, 
+    32768, 40960, 45056, 45568, 45824, 45825, 45792,     0, 
+    32768, 40960, 45056, 45568, 45824, 45825, 45792,     0, 
+    32768, 40960, 45056, 45568, 45824, 45825, 45792, 45794, 
+        0, 32768, 40960, 45056, 45568, 45824, 45825, 45792, 
+        0, 32768, 40960, 45056, 45568, 45824, 45825, 45792, 
+    45796,     0, 32768, 40960, 45056, 45568, 45824, 45825, 
+    45792, 45796,     0, 32768, 40960, 45056, 45568, 45824, 
+    45825, 45792, 45800, 45798,     0, 32768, 40960, 45056, 
+    45568, 45824, 45825, 45792,     0, 32768, 40960, 45056, 
+    45568, 45824, 45825, 45792, 45800,     0, 32768, 40960, 
+    45056, 45568, 45824, 45825, 45792, 45800,     0, 32768, 
+    40960, 45056, 45568, 45824, 45825, 45792, 45800, 45802, 
+        0, 32768, 40960, 45056, 45568, 45824, 45825, 45792, 
+    45800,     0, 32768, 40960, 45056, 45568, 45824, 45825, 
+    45792, 45808, 45804,     0, 32768, 40960, 45056, 45568, 
+    45824, 45825, 45792, 45808, 45804,     0, 32768, 40960, 
+    45056, 45568, 45824, 45825, 45792, 45808, 45809, 45806, 
+        0, 32768, 40960, 45056, 45568, 45824, 45825, 45792, 
+        0, 32768, 40960, 45056, 45568, 45824, 45825, 45792, 
+    45808,     0, 32768, 40960, 45056, 45568, 45824, 45825, 
+    45827, 45808,     0, 32768, 40960, 45056, 45568, 45824, 
+    45825, 45827, 45808, 45810,     0, 32768, 40960, 45056, 
+    45568, 45824, 45825, 45827, 45808,     0, 32768, 40960, 
+    45056, 45568, 45824, 45825, 45827, 45808, 45812,     0, 
+    32768, 40960, 45056, 45568, 45824, 45825, 45827, 45808, 
+    45812,     0, 32768, 40960, 45056, 45568, 45824, 45825, 
+    45827, 45808, 45816, 45814,     0, 32768, 40960, 45056, 
+    45568, 45824, 45825, 45827, 45808,     0, 32768, 40960, 
+    45056, 45568, 45824, 45825, 45827, 45808, 45816,     0, 
+    32768, 40960, 45056, 45568, 45824, 45825, 45827, 45808, 
+    45816,     0, 32768, 40960, 45056, 45568, 45824, 45825, 
+    45827, 45808, 45816, 45818,     0, 32768, 40960, 45056, 
+    45568, 45824, 45825, 45827, 45831, 45816,     0, 32768, 
+    40960, 45056, 45568, 45824, 45825, 45827, 45831, 45816, 
+    45820,     0, 32768, 40960, 45056, 45568, 45824, 45825, 
+    45827, 45831, 45816, 45820,     0, 32768, 40960, 45056, 
+    45568, 45824, 45825, 45827, 45831, 45816, 45820, 45822, 
+        0, 32768, 40960, 45056, 45568,     0, 32768, 40960, 
+    45056, 46080, 45824,     0, 32768, 40960, 45056, 46080, 
+    45824,     0, 32768, 40960, 45056, 46080, 45824, 45826, 
+        0, 32768, 40960, 45056, 46080, 45824,     0, 32768, 
+    40960, 45056, 46080, 45824, 45828,     0, 32768, 40960, 
+    45056, 46080, 45824, 45828,     0, 32768, 40960, 45056, 
+    46080, 45824, 45832, 45830,     0, 32768, 40960, 45056, 
+    46080, 45824,     0, 32768, 40960, 45056, 46080, 45824, 
+    45832,     0, 32768, 40960, 45056, 46080, 45824, 45832, 
+        0, 32768, 40960, 45056, 46080, 45824, 45832, 45834, 
+        0, 32768, 40960, 45056, 46080, 45824, 45832,     0, 
+    32768, 40960, 45056, 46080, 45824, 45840, 45836,     0, 
+    32768, 40960, 45056, 46080, 45824, 45840, 45836,     0, 
+    32768, 40960, 45056, 46080, 45824, 45840, 45841, 45838, 
+        0, 32768, 40960, 45056, 46080, 45824,     0, 32768, 
+    40960, 45056, 46080, 45824, 45840,     0, 32768, 40960, 
+    45056, 46080, 45824, 45840,     0, 32768, 40960, 45056, 
+    46080, 45824, 45840, 45842,     0, 32768, 40960, 45056, 
+    46080, 45824, 45840,     0, 32768, 40960, 45056, 46080, 
+    45824, 45840, 45844,     0, 32768, 40960, 45056, 46080, 
+    45824, 45840, 45844,     0, 32768, 40960, 45056, 46080, 
+    45824, 45840, 45848, 45846,     0, 32768, 40960, 45056, 
+    46080, 45824, 45840,     0, 32768, 40960, 45056, 46080, 
+    45824, 45856, 45848,     0, 32768, 40960, 45056, 46080, 
+    45824, 45856, 45848,     0, 32768, 40960, 45056, 46080, 
+    45824, 45856, 45848, 45850,     0, 32768, 40960, 45056, 
+    46080, 45824, 45856, 45848,     0, 32768, 40960, 45056, 
+    46080, 45824, 45856, 45857, 45852,     0, 32768, 40960, 
+    45056, 46080, 45824, 45856, 45857, 45852,     0, 32768, 
+    40960, 45056, 46080, 45824, 45856, 45857, 45852, 45854, 
+        0, 32768, 40960, 45056, 46080, 45824,     0, 32768, 
+    40960, 45056, 46080, 45824, 45856,     0, 32768, 40960, 
+    45056, 46080, 45824, 45856,     0, 32768, 40960, 45056, 
+    46080, 45824, 45856, 45858,     0, 32768, 40960, 45056, 
+    46080, 45824, 45856,     0, 32768, 40960, 45056, 46080, 
+    45824, 45856, 45860,     0, 32768, 40960, 45056, 46080, 
+    45824, 45856, 45860,     0, 32768, 40960, 45056, 46080, 
+    45824, 45856, 45864, 45862,     0, 32768, 40960, 45056, 
+    46080, 45824, 45856,     0, 32768, 40960, 45056, 46080, 
+    45824, 45856, 45864,     0, 32768, 40960, 45056, 46080, 
+    45824, 45856, 45864,     0, 32768, 40960, 45056, 46080, 
+    45824, 45856, 45864, 45866,     0, 32768, 40960, 45056, 
+    46080, 45824, 45856, 45864,     0, 32768, 40960, 45056, 
+    46080, 45824, 45856, 45872, 45868,     0, 32768, 40960, 
+    45056, 46080, 45824, 45856, 45872, 45868,     0, 32768, 
+    40960, 45056, 46080, 45824, 45856, 45872, 45873, 45870, 
+        0, 32768, 40960, 45056, 46080, 45824, 45856,     0, 
+    32768, 40960, 45056, 46080, 45824, 45888, 45872,     0, 
+    32768, 40960, 45056, 46080, 45824, 45888, 45872,     0, 
+    32768, 40960, 45056, 46080, 45824, 45888, 45872, 45874, 
+        0, 32768, 40960, 45056, 46080, 45824, 45888, 45872, 
+        0, 32768, 40960, 45056, 46080, 45824, 45888, 45872, 
+    45876,     0, 32768, 40960, 45056, 46080, 45824, 45888, 
+    45872, 45876,     0, 32768, 40960, 45056, 46080, 45824, 
+    45888, 45872, 45880, 45878,     0, 32768, 40960, 45056, 
+    46080, 45824, 45888, 45872,     0, 32768, 40960, 45056, 
+    46080, 45824, 45888, 45889, 45880,     0, 32768, 40960, 
+    45056, 46080, 45824, 45888, 45889, 45880,     0, 32768, 
+    40960, 45056, 46080, 45824, 45888, 45889, 45880, 45882, 
+        0, 32768, 40960, 45056, 46080, 45824, 45888, 45889, 
+    45880,     0, 32768, 40960, 45056, 46080, 45824, 45888, 
+    45889, 45880, 45884,     0, 32768, 40960, 45056, 46080, 
+    45824, 45888, 45889, 45891, 45884,     0, 32768, 40960, 
+    45056, 46080, 45824, 45888, 45889, 45891, 45884, 45886, 
+        0, 32768, 40960, 45056, 46080, 45824,     0, 32768, 
+    40960, 45056, 46080, 45824, 45888,     0, 32768, 40960, 
+    45056, 46080, 45824, 45888,     0, 32768, 40960, 45056, 
+    46080, 45824, 45888, 45890,     0, 32768, 40960, 45056, 
+    46080, 45824, 45888,     0, 32768, 40960, 45056, 46080, 
+    45824, 45888, 45892,     0, 32768, 40960, 45056, 46080, 
+    45824, 45888, 45892,     0, 32768, 40960, 45056, 46080, 
+    45824, 45888, 45896, 45894,     0, 32768, 40960, 45056, 
+    46080, 45824, 45888,     0, 32768, 40960, 45056, 46080, 
+    45824, 45888, 45896,     0, 32768, 40960, 45056, 46080, 
+    45824, 45888, 45896,     0, 32768, 40960, 45056, 46080, 
+    45824, 45888, 45896, 45898,     0, 32768, 40960, 45056, 
+    46080, 45824, 45888, 45896,     0, 32768, 40960, 45056, 
+    46080, 45824, 45888, 45904, 45900,     0, 32768, 40960, 
+    45056, 46080, 45824, 45888, 45904, 45900,     0, 32768, 
+    40960, 45056, 46080, 45824, 45888, 45904, 45905, 45902, 
+        0, 32768, 40960, 45056, 46080, 45824, 45888,     0, 
+    32768, 40960, 45056, 46080, 45824, 45888, 45904,     0, 
+    32768, 40960, 45056, 46080, 45824, 45888, 45904,     0, 
+    32768, 40960, 45056, 46080, 45824, 45888, 45904, 45906, 
+        0, 32768, 40960, 45056, 46080, 45824, 45888, 45904, 
+        0, 32768, 40960, 45056, 46080, 45824, 45888, 45904, 
+    45908,     0, 32768, 40960, 45056, 46080, 45824, 45888, 
+    45904, 45908,     0, 32768, 40960, 45056, 46080, 45824, 
+    45888, 45904, 45912, 45910,     0, 32768, 40960, 45056, 
+    46080, 45824, 45888, 45904,     0, 32768, 40960, 45056, 
+    46080, 45824, 45888, 45920, 45912,     0, 32768, 40960, 
+    45056, 46080, 45824, 45888, 45920, 45912,     0, 32768, 
+    40960, 45056, 46080, 45824, 45888, 45920, 45912, 45914, 
+        0, 32768, 40960, 45056, 46080, 45824, 45888, 45920, 
+    45912,     0, 32768, 40960, 45056, 46080, 45824, 45888, 
+    45920, 45921, 45916,     0, 32768, 40960, 45056, 46080, 
+    45824, 45888, 45920, 45921, 45916,     0, 32768, 40960, 
+    45056, 46080, 45824, 45888, 45920, 45921, 45916, 45918, 
+        0, 32768, 40960, 45056, 46080, 45824, 45888,     0, 
+    32768, 40960, 45056, 46080, 45824, 45952, 45920,     0, 
+    32768, 40960, 45056, 46080, 45824, 45952, 45920,     0, 
+    32768, 40960, 45056, 46080, 45824, 45952, 45920, 45922, 
+        0, 32768, 40960, 45056, 46080, 45824, 45952, 45920, 
+        0, 32768, 40960, 45056, 46080, 45824, 45952, 45920, 
+    45924,     0, 32768, 40960, 45056, 46080, 45824, 45952, 
+    45920, 45924,     0, 32768, 40960, 45056, 46080, 45824, 
+    45952, 45920, 45928, 45926,     0, 32768, 40960, 45056, 
+    46080, 45824, 45952, 45920,     0, 32768, 40960, 45056, 
+    46080, 45824, 45952, 45920, 45928,     0, 32768, 40960, 
+    45056, 46080, 45824, 45952, 45920, 45928,     0, 32768, 
+    40960, 45056, 46080, 45824, 45952, 45920, 45928, 45930, 
+        0, 32768, 40960, 45056, 46080, 45824, 45952, 45920, 
+    45928,     0, 32768, 40960, 45056, 46080, 45824, 45952, 
+    45920, 45936, 45932,     0, 32768, 40960, 45056, 46080, 
+    45824, 45952, 45920, 45936, 45932,     0, 32768, 40960, 
+    45056, 46080, 45824, 45952, 45920, 45936, 45937, 45934, 
+        0, 32768, 40960, 45056, 46080, 45824, 45952, 45920, 
+        0, 32768, 40960, 45056, 46080, 45824, 45952, 45953, 
+    45936,     0, 32768, 40960, 45056, 46080, 45824, 45952, 
+    45953, 45936,     0, 32768, 40960, 45056, 46080, 45824, 
+    45952, 45953, 45936, 45938,     0, 32768, 40960, 45056, 
+    46080, 45824, 45952, 45953, 45936,     0, 32768, 40960, 
+    45056, 46080, 45824, 45952, 45953, 45936, 45940,     0, 
+    32768, 40960, 45056, 46080, 45824, 45952, 45953, 45936, 
+    45940,     0, 32768, 40960, 45056, 46080, 45824, 45952, 
+    45953, 45936, 45944, 45942,     0, 32768, 40960, 45056, 
+    46080, 45824, 45952, 45953, 45936,     0, 32768, 40960, 
+    45056, 46080, 45824, 45952, 45953, 45936, 45944,     0, 
+    32768, 40960, 45056, 46080, 45824, 45952, 45953, 45955, 
+    45944,     0, 32768, 40960, 45056, 46080, 45824, 45952, 
+    45953, 45955, 45944, 45946,     0, 32768, 40960, 45056, 
+    46080, 45824, 45952, 45953, 45955, 45944,     0, 32768, 
+    40960, 45056, 46080, 45824, 45952, 45953, 45955, 45944, 
+    45948,     0, 32768, 40960, 45056, 46080, 45824, 45952, 
+    45953, 45955, 45944, 45948,     0, 32768, 40960, 45056, 
+    46080, 45824, 45952, 45953, 45955, 45944, 45948, 45950, 
+        0, 32768, 40960, 45056, 46080, 45824,     0, 32768, 
+    40960, 45056, 46080, 45824, 45952,     0, 32768, 40960, 
+    45056, 46080, 46081, 45952,     0, 32768, 40960, 45056, 
+    46080, 46081, 45952, 45954,     0, 32768, 40960, 45056, 
+    46080, 46081, 45952,     0, 32768, 40960, 45056, 46080, 
+    46081, 45952, 45956,     0, 32768, 40960, 45056, 46080, 
+    46081, 45952, 45956,     0, 32768, 40960, 45056, 46080, 
+    46081, 45952, 45960, 45958,     0, 32768, 40960, 45056, 
+    46080, 46081, 45952,     0, 32768, 40960, 45056, 46080, 
+    46081, 45952, 45960,     0, 32768, 40960, 45056, 46080, 
+    46081, 45952, 45960,     0, 32768, 40960, 45056, 46080, 
+    46081, 45952, 45960, 45962,     0, 32768, 40960, 45056, 
+    46080, 46081, 45952, 45960,     0, 32768, 40960, 45056, 
+    46080, 46081, 45952, 45968, 45964,     0, 32768, 40960, 
+    45056, 46080, 46081, 45952, 45968, 45964,     0, 32768, 
+    40960, 45056, 46080, 46081, 45952, 45968, 45969, 45966, 
+        0, 32768, 40960, 45056, 46080, 46081, 45952,     0, 
+    32768, 40960, 45056, 46080, 46081, 45952, 45968,     0, 
+    32768, 40960, 45056, 46080, 46081, 45952, 45968,     0, 
+    32768, 40960, 45056, 46080, 46081, 45952, 45968, 45970, 
+        0, 32768, 40960, 45056, 46080, 46081, 45952, 45968, 
+        0, 32768, 40960, 45056, 46080, 46081, 45952, 45968, 
+    45972,     0, 32768, 40960, 45056, 46080, 46081, 45952, 
+    45968, 45972,     0, 32768, 40960, 45056, 46080, 46081, 
+    45952, 45968, 45976, 45974,     0, 32768, 40960, 45056, 
+    46080, 46081, 45952, 45968,     0, 32768, 40960, 45056, 
+    46080, 46081, 45952, 45984, 45976,     0, 32768, 40960, 
+    45056, 46080, 46081, 45952, 45984, 45976,     0, 32768, 
+    40960, 45056, 46080, 46081, 45952, 45984, 45976, 45978, 
+        0, 32768, 40960, 45056, 46080, 46081, 45952, 45984, 
+    45976,     0, 32768, 40960, 45056, 46080, 46081, 45952, 
+    45984, 45985, 45980,     0, 32768, 40960, 45056, 46080, 
+    46081, 45952, 45984, 45985, 45980,     0, 32768, 40960, 
+    45056, 46080, 46081, 45952, 45984, 45985, 45980, 45982, 
+        0, 32768, 40960, 45056, 46080, 46081, 45952,     0, 
+    32768, 40960, 45056, 46080, 46081, 45952, 45984,     0, 
+    32768, 40960, 45056, 46080, 46081, 45952, 45984,     0, 
+    32768, 40960, 45056, 46080, 46081, 45952, 45984, 45986, 
+        0, 32768, 40960, 45056, 46080, 46081, 45952, 45984, 
+        0, 32768, 40960, 45056, 46080, 46081, 45952, 45984, 
+    45988,     0, 32768, 40960, 45056, 46080, 46081, 45952, 
+    45984, 45988,     0, 32768, 40960, 45056, 46080, 46081, 
+    45952, 45984, 45992, 45990,     0, 32768, 40960, 45056, 
+    46080, 46081, 45952, 45984,     0, 32768, 40960, 45056, 
+    46080, 46081, 45952, 45984, 45992,     0, 32768, 40960, 
+    45056, 46080, 46081, 45952, 45984, 45992,     0, 32768, 
+    40960, 45056, 46080, 46081, 45952, 45984, 45992, 45994, 
+        0, 32768, 40960, 45056, 46080, 46081, 45952, 45984, 
+    45992,     0, 32768, 40960, 45056, 46080, 46081, 45952, 
+    45984, 46000, 45996,     0, 32768, 40960, 45056, 46080, 
+    46081, 45952, 45984, 46000, 45996,     0, 32768, 40960, 
+    45056, 46080, 46081, 45952, 45984, 46000, 46001, 45998, 
+        0, 32768, 40960, 45056, 46080, 46081, 45952, 45984, 
+        0, 32768, 40960, 45056, 46080, 46081, 45952, 46016, 
+    46000,     0, 32768, 40960, 45056, 46080, 46081, 45952, 
+    46016, 46000,     0, 32768, 40960, 45056, 46080, 46081, 
+    45952, 46016, 46000, 46002,     0, 32768, 40960, 45056, 
+    46080, 46081, 45952, 46016, 46000,     0, 32768, 40960, 
+    45056, 46080, 46081, 45952, 46016, 46000, 46004,     0, 
+    32768, 40960, 45056, 46080, 46081, 45952, 46016, 46000, 
+    46004,     0, 32768, 40960, 45056, 46080, 46081, 45952, 
+    46016, 46000, 46008, 46006,     0, 32768, 40960, 45056, 
+    46080, 46081, 45952, 46016, 46000,     0, 32768, 40960, 
+    45056, 46080, 46081, 45952, 46016, 46017, 46008,     0, 
+    32768, 40960, 45056, 46080, 46081, 45952, 46016, 46017, 
+    46008,     0, 32768, 40960, 45056, 46080, 46081, 45952, 
+    46016, 46017, 46008, 46010,     0, 32768, 40960, 45056, 
+    46080, 46081, 45952, 46016, 46017, 46008,     0, 32768, 
+    40960, 45056, 46080, 46081, 45952, 46016, 46017, 46008, 
+    46012,     0, 32768, 40960, 45056, 46080, 46081, 45952, 
+    46016, 46017, 46019, 46012,     0, 32768, 40960, 45056, 
+    46080, 46081, 45952, 46016, 46017, 46019, 46012, 46014, 
+        0, 32768, 40960, 45056, 46080, 46081, 45952,     0, 
+    32768, 40960, 45056, 46080, 46081, 45952, 46016,     0, 
+    32768, 40960, 45056, 46080, 46081, 45952, 46016,     0, 
+    32768, 40960, 45056, 46080, 46081, 45952, 46016, 46018, 
+        0, 32768, 40960, 45056, 46080, 46081, 46083, 46016, 
+        0, 32768, 40960, 45056, 46080, 46081, 46083, 46016, 
+    46020,     0, 32768, 40960, 45056, 46080, 46081, 46083, 
+    46016, 46020,     0, 32768, 40960, 45056, 46080, 46081, 
+    46083, 46016, 46024, 46022,     0, 32768, 40960, 45056, 
+    46080, 46081, 46083, 46016,     0, 32768, 40960, 45056, 
+    46080, 46081, 46083, 46016, 46024,     0, 32768, 40960, 
+    45056, 46080, 46081, 46083, 46016, 46024,     0, 32768, 
+    40960, 45056, 46080, 46081, 46083, 46016, 46024, 46026, 
+        0, 32768, 40960, 45056, 46080, 46081, 46083, 46016, 
+    46024,     0, 32768, 40960, 45056, 46080, 46081, 46083, 
+    46016, 46032, 46028,     0, 32768, 40960, 45056, 46080, 
+    46081, 46083, 46016, 46032, 46028,     0, 32768, 40960, 
+    45056, 46080, 46081, 46083, 46016, 46032, 46033, 46030, 
+        0, 32768, 40960, 45056, 46080, 46081, 46083, 46016, 
+        0, 32768, 40960, 45056, 46080, 46081, 46083, 46016, 
+    46032,     0, 32768, 40960, 45056, 46080, 46081, 46083, 
+    46016, 46032,     0, 32768, 40960, 45056, 46080, 46081, 
+    46083, 46016, 46032, 46034,     0, 32768, 40960, 45056, 
+    46080, 46081, 46083, 46016, 46032,     0, 32768, 40960, 
+    45056, 46080, 46081, 46083, 46016, 46032, 46036,     0, 
+    32768, 40960, 45056, 46080, 46081, 46083, 46016, 46032, 
+    46036,     0, 32768, 40960, 45056, 46080, 46081, 46083, 
+    46016, 46032, 46040, 46038,     0, 32768, 40960, 45056, 
+    46080, 46081, 46083, 46016, 46032,     0, 32768, 40960, 
+    45056, 46080, 46081, 46083, 46016, 46048, 46040,     0, 
+    32768, 40960, 45056, 46080, 46081, 46083, 46016, 46048, 
+    46040,     0, 32768, 40960, 45056, 46080, 46081, 46083, 
+    46016, 46048, 46040, 46042,     0, 32768, 40960, 45056, 
+    46080, 46081, 46083, 46016, 46048, 46040,     0, 32768, 
+    40960, 45056, 46080, 46081, 46083, 46016, 46048, 46049, 
+    46044,     0, 32768, 40960, 45056, 46080, 46081, 46083, 
+    46016, 46048, 46049, 46044,     0, 32768, 40960, 45056, 
+    46080, 46081, 46083, 46016, 46048, 46049, 46044, 46046, 
+        0, 32768, 40960, 45056, 46080, 46081, 46083, 46016, 
+        0, 32768, 40960, 45056, 46080, 46081, 46083, 46016, 
+    46048,     0, 32768, 40960, 45056, 46080, 46081, 46083, 
+    46016, 46048,     0, 32768, 40960, 45056, 46080, 46081, 
+    46083, 46016, 46048, 46050,     0, 32768, 40960, 45056, 
+    46080, 46081, 46083, 46016, 46048,     0, 32768, 40960, 
+    45056, 46080, 46081, 46083, 46016, 46048, 46052,     0, 
+    32768, 40960, 45056, 46080, 46081, 46083, 46016, 46048, 
+    46052,     0, 32768, 40960, 45056, 46080, 46081, 46083, 
+    46016, 46048, 46056, 46054,     0, 32768, 40960, 45056, 
+    46080, 46081, 46083, 46087, 46048,     0, 32768, 40960, 
+    45056, 46080, 46081, 46083, 46087, 46048, 46056,     0, 
+    32768, 40960, 45056, 46080, 46081, 46083, 46087, 46048, 
+    46056,     0, 32768, 40960, 45056, 46080, 46081, 46083, 
+    46087, 46048, 46056, 46058,     0, 32768, 40960, 45056, 
+    46080, 46081, 46083, 46087, 46048, 46056,     0, 32768, 
+    40960, 45056, 46080, 46081, 46083, 46087, 46048, 46064, 
+    46060,     0, 32768, 40960, 45056, 46080, 46081, 46083, 
+    46087, 46048, 46064, 46060,     0, 32768, 40960, 45056, 
+    46080, 46081, 46083, 46087, 46048, 46064, 46065, 46062, 
+        0, 32768, 40960, 45056, 46080, 46081, 46083, 46087, 
+    46048,     0, 32768, 40960, 45056, 46080, 46081, 46083, 
+    46087, 46048, 46064,     0, 32768, 40960, 45056, 46080, 
+    46081, 46083, 46087, 46048, 46064,     0, 32768, 40960, 
+    45056, 46080, 46081, 46083, 46087, 46048, 46064, 46066, 
+        0, 32768, 40960, 45056, 46080, 46081, 46083, 46087, 
+    46048, 46064,     0, 32768, 40960, 45056, 46080, 46081, 
+    46083, 46087, 46048, 46064, 46068,     0, 32768, 40960, 
+    45056, 46080, 46081, 46083, 46087, 46048, 46064, 46068, 
+        0, 32768, 40960, 45056, 46080, 46081, 46083, 46087, 
+    46048, 46064, 46072, 46070,     0, 32768, 40960, 45056, 
+    46080, 46081, 46083, 46087, 46048, 46064,     0, 32768, 
+    40960, 45056, 46080, 46081, 46083, 46087, 46048, 46064, 
+    46072,     0, 32768, 40960, 45056, 46080, 46081, 46083, 
+    46087, 46048, 46064, 46072,     0, 32768, 40960, 45056, 
+    46080, 46081, 46083, 46087, 46048, 46064, 46072, 46074, 
+        0, 32768, 40960, 45056, 46080, 46081, 46083, 46087, 
+    46048, 46064, 46072,     0, 32768, 40960, 45056, 46080, 
+    46081, 46083, 46087, 46048, 46064, 46072, 46076,     0, 
+    32768, 40960, 45056, 46080, 46081, 46083, 46087, 46048, 
+    46064, 46072, 46076,     0, 32768, 40960, 45056, 46080, 
+    46081, 46083, 46087, 46048, 46064, 46072, 46076, 46078, 
+        0, 32768, 40960, 45056,     0, 32768, 40960, 45056, 
+    46080,     0, 32768, 40960, 45056, 46080,     0, 32768, 
+    40960, 45056, 46080, 46082,     0, 32768, 40960, 45056, 
+    46080,     0, 32768, 40960, 45056, 46080, 46084,     0, 
+    32768, 40960, 45056, 46080, 46084,     0, 32768, 40960, 
+    45056, 46080, 46088, 46086,     0, 32768, 40960, 45056, 
+    46080,     0, 32768, 40960, 45056, 46080, 46088,     0, 
+    32768, 40960, 45056, 46080, 46088,     0, 32768, 40960, 
+    45056, 46080, 46088, 46090,     0, 32768, 40960, 45056, 
+    46080, 46088,     0, 32768, 40960, 45056, 46080, 46096, 
+    46092,     0, 32768, 40960, 45056, 46080, 46096, 46092, 
+        0, 32768, 40960, 45056, 46080, 46096, 46097, 46094, 
+        0, 32768, 40960, 45056, 46080,     0, 32768, 40960, 
+    45056, 46080, 46096,     0, 32768, 40960, 45056, 46080, 
+    46096,     0, 32768, 40960, 45056, 46080, 46096, 46098, 
+        0, 32768, 40960, 45056, 46080, 46096,     0, 32768, 
+    40960, 45056, 46080, 46096, 46100,     0, 32768, 40960, 
+    45056, 46080, 46096, 46100,     0, 32768, 40960, 45056, 
+    46080, 46096, 46104, 46102,     0, 32768, 40960, 45056, 
+    46080, 46096,     0, 32768, 40960, 45056, 46080, 46112, 
+    46104,     0, 32768, 40960, 45056, 46080, 46112, 46104, 
+        0, 32768, 40960, 45056, 46080, 46112, 46104, 46106, 
+        0, 32768, 40960, 45056, 46080, 46112, 46104,     0, 
+    32768, 40960, 45056, 46080, 46112, 46113, 46108,     0, 
+    32768, 40960, 45056, 46080, 46112, 46113, 46108,     0, 
+    32768, 40960, 45056, 46080, 46112, 46113, 46108, 46110, 
+        0, 32768, 40960, 45056, 46080,     0, 32768, 40960, 
+    45056, 46080, 46112,     0, 32768, 40960, 45056, 46080, 
+    46112,     0, 32768, 40960, 45056, 46080, 46112, 46114, 
+        0, 32768, 40960, 45056, 46080, 46112,     0, 32768, 
+    40960, 45056, 46080, 46112, 46116,     0, 32768, 40960, 
+    45056, 46080, 46112, 46116,     0, 32768, 40960, 45056, 
+    46080, 46112, 46120, 46118,     0, 32768, 40960, 45056, 
+    46080, 46112,     0, 32768, 40960, 45056, 46080, 46112, 
+    46120,     0, 32768, 40960, 45056, 46080, 46112, 46120, 
+        0, 32768, 40960, 45056, 46080, 46112, 46120, 46122, 
+        0, 32768, 40960, 45056, 46080, 46112, 46120,     0, 
+    32768, 40960, 45056, 46080, 46112, 46128, 46124,     0, 
+    32768, 40960, 45056, 46080, 46112, 46128, 46124,     0, 
+    32768, 40960, 45056, 46080, 46112, 46128, 46129, 46126, 
+        0, 32768, 40960, 45056, 46080, 46112,     0, 32768, 
+    40960, 45056, 46080, 46144, 46128,     0, 32768, 40960, 
+    45056, 46080, 46144, 46128,     0, 32768, 40960, 45056, 
+    46080, 46144, 46128, 46130,     0, 32768, 40960, 45056, 
+    46080, 46144, 46128,     0, 32768, 40960, 45056, 46080, 
+    46144, 46128, 46132,     0, 32768, 40960, 45056, 46080, 
+    46144, 46128, 46132,     0, 32768, 40960, 45056, 46080, 
+    46144, 46128, 46136, 46134,     0, 32768, 40960, 45056, 
+    46080, 46144, 46128,     0, 32768, 40960, 45056, 46080, 
+    46144, 46145, 46136,     0, 32768, 40960, 45056, 46080, 
+    46144, 46145, 46136,     0, 32768, 40960, 45056, 46080, 
+    46144, 46145, 46136, 46138,     0, 32768, 40960, 45056, 
+    46080, 46144, 46145, 46136,     0, 32768, 40960, 45056, 
+    46080, 46144, 46145, 46136, 46140,     0, 32768, 40960, 
+    45056, 46080, 46144, 46145, 46147, 46140,     0, 32768, 
+    40960, 45056, 46080, 46144, 46145, 46147, 46140, 46142, 
+        0, 32768, 40960, 45056, 46080,     0, 32768, 40960, 
+    45056, 46080, 46144,     0, 32768, 40960, 45056, 46080, 
+    46144,     0, 32768, 40960, 45056, 46080, 46144, 46146, 
+        0, 32768, 40960, 45056, 46080, 46144,     0, 32768, 
+    40960, 45056, 46080, 46144, 46148,     0, 32768, 40960, 
+    45056, 46080, 46144, 46148,     0, 32768, 40960, 45056, 
+    46080, 46144, 46152, 46150,     0, 32768, 40960, 45056, 
+    46080, 46144,     0, 32768, 40960, 45056, 46080, 46144, 
+    46152,     0, 32768, 40960, 45056, 46080, 46144, 46152, 
+        0, 32768, 40960, 45056, 46080, 46144, 46152, 46154, 
+        0, 32768, 40960, 45056, 46080, 46144, 46152,     0, 
+    32768, 40960, 45056, 46080, 46144, 46160, 46156,     0, 
+    32768, 40960, 45056, 46080, 46144, 46160, 46156,     0, 
+    32768, 40960, 45056, 46080, 46144, 46160, 46161, 46158, 
+        0, 32768, 40960, 45056, 46080, 46144,     0, 32768, 
+    40960, 45056, 46080, 46144, 46160,     0, 32768, 40960, 
+    45056, 46080, 46144, 46160,     0, 32768, 40960, 45056, 
+    46080, 46144, 46160, 46162,     0, 32768, 40960, 45056, 
+    46080, 46144, 46160,     0, 32768, 40960, 45056, 46080, 
+    46144, 46160, 46164,     0, 32768, 40960, 45056, 46080, 
+    46144, 46160, 46164,     0, 32768, 40960, 45056, 46080, 
+    46144, 46160, 46168, 46166,     0, 32768, 40960, 45056, 
+    46080, 46144, 46160,     0, 32768, 40960, 45056, 46080, 
+    46144, 46176, 46168,     0, 32768, 40960, 45056, 46080, 
+    46144, 46176, 46168,     0, 32768, 40960, 45056, 46080, 
+    46144, 46176, 46168, 46170,     0, 32768, 40960, 45056, 
+    46080, 46144, 46176, 46168,     0, 32768, 40960, 45056, 
+    46080, 46144, 46176, 46177, 46172,     0, 32768, 40960, 
+    45056, 46080, 46144, 46176, 46177, 46172,     0, 32768, 
+    40960, 45056, 46080, 46144, 46176, 46177, 46172, 46174, 
+        0, 32768, 40960, 45056, 46080, 46144,     0, 32768, 
+    40960, 45056, 46080, 46208, 46176,     0, 32768, 40960, 
+    45056, 46080, 46208, 46176,     0, 32768, 40960, 45056, 
+    46080, 46208, 46176, 46178,     0, 32768, 40960, 45056, 
+    46080, 46208, 46176,     0, 32768, 40960, 45056, 46080, 
+    46208, 46176, 46180,     0, 32768, 40960, 45056, 46080, 
+    46208, 46176, 46180,     0, 32768, 40960, 45056, 46080, 
+    46208, 46176, 46184, 46182,     0, 32768, 40960, 45056, 
+    46080, 46208, 46176,     0, 32768, 40960, 45056, 46080, 
+    46208, 46176, 46184,     0, 32768, 40960, 45056, 46080, 
+    46208, 46176, 46184,     0, 32768, 40960, 45056, 46080, 
+    46208, 46176, 46184, 46186,     0, 32768, 40960, 45056, 
+    46080, 46208, 46176, 46184,     0, 32768, 40960, 45056, 
+    46080, 46208, 46176, 46192, 46188,     0, 32768, 40960, 
+    45056, 46080, 46208, 46176, 46192, 46188,     0, 32768, 
+    40960, 45056, 46080, 46208, 46176, 46192, 46193, 46190, 
+        0, 32768, 40960, 45056, 46080, 46208, 46176,     0, 
+    32768, 40960, 45056, 46080, 46208, 46209, 46192,     0, 
+    32768, 40960, 45056, 46080, 46208, 46209, 46192,     0, 
+    32768, 40960, 45056, 46080, 46208, 46209, 46192, 46194, 
+        0, 32768, 40960, 45056, 46080, 46208, 46209, 46192, 
+        0, 32768, 40960, 45056, 46080, 46208, 46209, 46192, 
+    46196,     0, 32768, 40960, 45056, 46080, 46208, 46209, 
+    46192, 46196,     0, 32768, 40960, 45056, 46080, 46208, 
+    46209, 46192, 46200, 46198,     0, 32768, 40960, 45056, 
+    46080, 46208, 46209, 46192,     0, 32768, 40960, 45056, 
+    46080, 46208, 46209, 46192, 46200,     0, 32768, 40960, 
+    45056, 46080, 46208, 46209, 46211, 46200,     0, 32768, 
+    40960, 45056, 46080, 46208, 46209, 46211, 46200, 46202, 
+        0, 32768, 40960, 45056, 46080, 46208, 46209, 46211, 
+    46200,     0, 32768, 40960, 45056, 46080, 46208, 46209, 
+    46211, 46200, 46204,     0, 32768, 40960, 45056, 46080, 
+    46208, 46209, 46211, 46200, 46204,     0, 32768, 40960, 
+    45056, 46080, 46208, 46209, 46211, 46200, 46204, 46206, 
+        0, 32768, 40960, 45056, 46080,     0, 32768, 40960, 
+    45056, 46080, 46208,     0, 32768, 40960, 45056, 46080, 
+    46208,     0, 32768, 40960, 45056, 46080, 46208, 46210, 
+        0, 32768, 40960, 45056, 46080, 46208,     0, 32768, 
+    40960, 45056, 46080, 46208, 46212,     0, 32768, 40960, 
+    45056, 46080, 46208, 46212,     0, 32768, 40960, 45056, 
+    46080, 46208, 46216, 46214,     0, 32768, 40960, 45056, 
+    46080, 46208,     0, 32768, 40960, 45056, 46080, 46208, 
+    46216,     0, 32768, 40960, 45056, 46080, 46208, 46216, 
+        0, 32768, 40960, 45056, 46080, 46208, 46216, 46218, 
+        0, 32768, 40960, 45056, 46080, 46208, 46216,     0, 
+    32768, 40960, 45056, 46080, 46208, 46224, 46220,     0, 
+    32768, 40960, 45056, 46080, 46208, 46224, 46220,     0, 
+    32768, 40960, 45056, 46080, 46208, 46224, 46225, 46222, 
+        0, 32768, 40960, 45056, 46080, 46208,     0, 32768, 
+    40960, 45056, 46080, 46208, 46224,     0, 32768, 40960, 
+    45056, 46080, 46208, 46224,     0, 32768, 40960, 45056, 
+    46080, 46208, 46224, 46226,     0, 32768, 40960, 45056, 
+    46080, 46208, 46224,     0, 32768, 40960, 45056, 46080, 
+    46208, 46224, 46228,     0, 32768, 40960, 45056, 46080, 
+    46208, 46224, 46228,     0, 32768, 40960, 45056, 46080, 
+    46208, 46224, 46232, 46230,     0, 32768, 40960, 45056, 
+    46080, 46208, 46224,     0, 32768, 40960, 45056, 46080, 
+    46208, 46240, 46232,     0, 32768, 40960, 45056, 46080, 
+    46208, 46240, 46232,     0, 32768, 40960, 45056, 46080, 
+    46208, 46240, 46232, 46234,     0, 32768, 40960, 45056, 
+    46080, 46208, 46240, 46232,     0, 32768, 40960, 45056, 
+    46080, 46208, 46240, 46241, 46236,     0, 32768, 40960, 
+    45056, 46080, 46208, 46240, 46241, 46236,     0, 32768, 
+    40960, 45056, 46080, 46208, 46240, 46241, 46236, 46238, 
+        0, 32768, 40960, 45056, 46080, 46208,     0, 32768, 
+    40960, 45056, 46080, 46208, 46240,     0, 32768, 40960, 
+    45056, 46080, 46208, 46240,     0, 32768, 40960, 45056, 
+    46080, 46208, 46240, 46242,     0, 32768, 40960, 45056, 
+    46080, 46208, 46240,     0, 32768, 40960, 45056, 46080, 
+    46208, 46240, 46244,     0, 32768, 40960, 45056, 46080, 
+    46208, 46240, 46244,     0, 32768, 40960, 45056, 46080, 
+    46208, 46240, 46248, 46246,     0, 32768, 40960, 45056, 
+    46080, 46208, 46240,     0, 32768, 40960, 45056, 46080, 
+    46208, 46240, 46248,     0, 32768, 40960, 45056, 46080, 
+    46208, 46240, 46248,     0, 32768, 40960, 45056, 46080, 
+    46208, 46240, 46248, 46250,     0, 32768, 40960, 45056, 
+    46080, 46208, 46240, 46248,     0, 32768, 40960, 45056, 
+    46080, 46208, 46240, 46256, 46252,     0, 32768, 40960, 
+    45056, 46080, 46208, 46240, 46256, 46252,     0, 32768, 
+    40960, 45056, 46080, 46208, 46240, 46256, 46257, 46254, 
+        0, 32768, 40960, 45056, 46080, 46208, 46240,     0, 
+    32768, 40960, 45056, 46080, 46208, 46272, 46256,     0, 
+    32768, 40960, 45056, 46080, 46208, 46272, 46256,     0, 
+    32768, 40960, 45056, 46080, 46208, 46272, 46256, 46258, 
+        0, 32768, 40960, 45056, 46080, 46208, 46272, 46256, 
+        0, 32768, 40960, 45056, 46080, 46208, 46272, 46256, 
+    46260,     0, 32768, 40960, 45056, 46080, 46208, 46272, 
+    46256, 46260,     0, 32768, 40960, 45056, 46080, 46208, 
+    46272, 46256, 46264, 46262,     0, 32768, 40960, 45056, 
+    46080, 46208, 46272, 46256,     0, 32768, 40960, 45056, 
+    46080, 46208, 46272, 46273, 46264,     0, 32768, 40960, 
+    45056, 46080, 46208, 46272, 46273, 46264,     0, 32768, 
+    40960, 45056, 46080, 46208, 46272, 46273, 46264, 46266, 
+        0, 32768, 40960, 45056, 46080, 46208, 46272, 46273, 
+    46264,     0, 32768, 40960, 45056, 46080, 46208, 46272, 
+    46273, 46264, 46268,     0, 32768, 40960, 45056, 46080, 
+    46208, 46272, 46273, 46275, 46268,     0, 32768, 40960, 
+    45056, 46080, 46208, 46272, 46273, 46275, 46268, 46270, 
+        0, 32768, 40960, 45056, 46080, 46208,     0, 32768, 
+    40960, 45056, 46080, 46336, 46272,     0, 32768, 40960, 
+    45056, 46080, 46336, 46272,     0, 32768, 40960, 45056, 
+    46080, 46336, 46272, 46274,     0, 32768, 40960, 45056, 
+    46080, 46336, 46272,     0, 32768, 40960, 45056, 46080, 
+    46336, 46272, 46276,     0, 32768, 40960, 45056, 46080, 
+    46336, 46272, 46276,     0, 32768, 40960, 45056, 46080, 
+    46336, 46272, 46280, 46278,     0, 32768, 40960, 45056, 
+    46080, 46336, 46272,     0, 32768, 40960, 45056, 46080, 
+    46336, 46272, 46280,     0, 32768, 40960, 45056, 46080, 
+    46336, 46272, 46280,     0, 32768, 40960, 45056, 46080, 
+    46336, 46272, 46280, 46282,     0, 32768, 40960, 45056, 
+    46080, 46336, 46272, 46280,     0, 32768, 40960, 45056, 
+    46080, 46336, 46272, 46288, 46284,     0, 32768, 40960, 
+    45056, 46080, 46336, 46272, 46288, 46284,     0, 32768, 
+    40960, 45056, 46080, 46336, 46272, 46288, 46289, 46286, 
+        0, 32768, 40960, 45056, 46080, 46336, 46272,     0, 
+    32768, 40960, 45056, 46080, 46336, 46272, 46288,     0, 
+    32768, 40960, 45056, 46080, 46336, 46272, 46288,     0, 
+    32768, 40960, 45056, 46080, 46336, 46272, 46288, 46290, 
+        0, 32768, 40960, 45056, 46080, 46336, 46272, 46288, 
+        0, 32768, 40960, 45056, 46080, 46336, 46272, 46288, 
+    46292,     0, 32768, 40960, 45056, 46080, 46336, 46272, 
+    46288, 46292,     0, 32768, 40960, 45056, 46080, 46336, 
+    46272, 46288, 46296, 46294,     0, 32768, 40960, 45056, 
+    46080, 46336, 46272, 46288,     0, 32768, 40960, 45056, 
+    46080, 46336, 46272, 46304, 46296,     0, 32768, 40960, 
+    45056, 46080, 46336, 46272, 46304, 46296,     0, 32768, 
+    40960, 45056, 46080, 46336, 46272, 46304, 46296, 46298, 
+        0, 32768, 40960, 45056, 46080, 46336, 46272, 46304, 
+    46296,     0, 32768, 40960, 45056, 46080, 46336, 46272, 
+    46304, 46305, 46300,     0, 32768, 40960, 45056, 46080, 
+    46336, 46272, 46304, 46305, 46300,     0, 32768, 40960, 
+    45056, 46080, 46336, 46272, 46304, 46305, 46300, 46302, 
+        0, 32768, 40960, 45056, 46080, 46336, 46272,     0, 
+    32768, 40960, 45056, 46080, 46336, 46337, 46304,     0, 
+    32768, 40960, 45056, 46080, 46336, 46337, 46304,     0, 
+    32768, 40960, 45056, 46080, 46336, 46337, 46304, 46306, 
+        0, 32768, 40960, 45056, 46080, 46336, 46337, 46304, 
+        0, 32768, 40960, 45056, 46080, 46336, 46337, 46304, 
+    46308,     0, 32768, 40960, 45056, 46080, 46336, 46337, 
+    46304, 46308,     0, 32768, 40960, 45056, 46080, 46336, 
+    46337, 46304, 46312, 46310,     0, 32768, 40960, 45056, 
+    46080, 46336, 46337, 46304,     0, 32768, 40960, 45056, 
+    46080, 46336, 46337, 46304, 46312,     0, 32768, 40960, 
+    45056, 46080, 46336, 46337, 46304, 46312,     0, 32768, 
+    40960, 45056, 46080, 46336, 46337, 46304, 46312, 46314, 
+        0, 32768, 40960, 45056, 46080, 46336, 46337, 46304, 
+    46312,     0, 32768, 40960, 45056, 46080, 46336, 46337, 
+    46304, 46320, 46316,     0, 32768, 40960, 45056, 46080, 
+    46336, 46337, 46304, 46320, 46316,     0, 32768, 40960, 
+    45056, 46080, 46336, 46337, 46304, 46320, 46321, 46318, 
+        0, 32768, 40960, 45056, 46080, 46336, 46337, 46304, 
+        0, 32768, 40960, 45056, 46080, 46336, 46337, 46304, 
+    46320,     0, 32768, 40960, 45056, 46080, 46336, 46337, 
+    46339, 46320,     0, 32768, 40960, 45056, 46080, 46336, 
+    46337, 46339, 46320, 46322,     0, 32768, 40960, 45056, 
+    46080, 46336, 46337, 46339, 46320,     0, 32768, 40960, 
+    45056, 46080, 46336, 46337, 46339, 46320, 46324,     0, 
+    32768, 40960, 45056, 46080, 46336, 46337, 46339, 46320, 
+    46324,     0, 32768, 40960, 45056, 46080, 46336, 46337, 
+    46339, 46320, 46328, 46326,     0, 32768, 40960, 45056, 
+    46080, 46336, 46337, 46339, 46320,     0, 32768, 40960, 
+    45056, 46080, 46336, 46337, 46339, 46320, 46328,     0, 
+    32768, 40960, 45056, 46080, 46336, 46337, 46339, 46320, 
+    46328,     0, 32768, 40960, 45056, 46080, 46336, 46337, 
+    46339, 46320, 46328, 46330,     0, 32768, 40960, 45056, 
+    46080, 46336, 46337, 46339, 46343, 46328,     0, 32768, 
+    40960, 45056, 46080, 46336, 46337, 46339, 46343, 46328, 
+    46332,     0, 32768, 40960, 45056, 46080, 46336, 46337, 
+    46339, 46343, 46328, 46332,     0, 32768, 40960, 45056, 
+    46080, 46336, 46337, 46339, 46343, 46328, 46332, 46334, 
+        0, 32768, 40960, 45056, 46080,     0, 32768, 40960, 
+    45056, 46080, 46336,     0, 32768, 40960, 45056, 46080, 
+    46336,     0, 32768, 40960, 45056, 46080, 46336, 46338, 
+        0, 32768, 40960, 45056, 46080, 46336,     0, 32768, 
+    40960, 45056, 46080, 46336, 46340,     0, 32768, 40960, 
+    45056, 46080, 46336, 46340,     0, 32768, 40960, 45056, 
+    46080, 46336, 46344, 46342,     0, 32768, 40960, 45056, 
+    46080, 46336,     0, 32768, 40960, 45056, 46080, 46336, 
+    46344,     0, 32768, 40960, 45056, 46080, 46336, 46344, 
+        0, 32768, 40960, 45056, 46080, 46336, 46344, 46346, 
+        0, 32768, 40960, 45056, 46080, 46336, 46344,     0, 
+    32768, 40960, 45056, 46080, 46336, 46352, 46348,     0, 
+    32768, 40960, 45056, 46080, 46336, 46352, 46348,     0, 
+    32768, 40960, 45056, 46080, 46336, 46352, 46353, 46350, 
+        0, 32768, 40960, 45056, 46080, 46336,     0, 32768, 
+    40960, 45056, 46080, 46336, 46352,     0, 32768, 40960, 
+    45056, 46080, 46336, 46352,     0, 32768, 40960, 45056, 
+    46080, 46336, 46352, 46354,     0, 32768, 40960, 45056, 
+    46080, 46336, 46352,     0, 32768, 40960, 45056, 46080, 
+    46336, 46352, 46356,     0, 32768, 40960, 45056, 46080, 
+    46336, 46352, 46356,     0, 32768, 40960, 45056, 46080, 
+    46336, 46352, 46360, 46358,     0, 32768, 40960, 45056, 
+    46080, 46336, 46352,     0, 32768, 40960, 45056, 46080, 
+    46336, 46368, 46360,     0, 32768, 40960, 45056, 46080, 
+    46336, 46368, 46360,     0, 32768, 40960, 45056, 46080, 
+    46336, 46368, 46360, 46362,     0, 32768, 40960, 45056, 
+    46080, 46336, 46368, 46360,     0, 32768, 40960, 45056, 
+    46080, 46336, 46368, 46369, 46364,     0, 32768, 40960, 
+    45056, 46080, 46336, 46368, 46369, 46364,     0, 32768, 
+    40960, 45056, 46080, 46336, 46368, 46369, 46364, 46366, 
+        0, 32768, 40960, 45056, 46080, 46336,     0, 32768, 
+    40960, 45056, 46080, 46336, 46368,     0, 32768, 40960, 
+    45056, 46080, 46336, 46368,     0, 32768, 40960, 45056, 
+    46080, 46336, 46368, 46370,     0, 32768, 40960, 45056, 
+    46080, 46336, 46368,     0, 32768, 40960, 45056, 46080, 
+    46336, 46368, 46372,     0, 32768, 40960, 45056, 46080, 
+    46336, 46368, 46372,     0, 32768, 40960, 45056, 46080, 
+    46336, 46368, 46376, 46374,     0, 32768, 40960, 45056, 
+    46080, 46336, 46368,     0, 32768, 40960, 45056, 46080, 
+    46336, 46368, 46376,     0, 32768, 40960, 45056, 46080, 
+    46336, 46368, 46376,     0, 32768, 40960, 45056, 46080, 
+    46336, 46368, 46376, 46378,     0, 32768, 40960, 45056, 
+    46080, 46336, 46368, 46376,     0, 32768, 40960, 45056, 
+    46080, 46336, 46368, 46384, 46380,     0, 32768, 40960, 
+    45056, 46080, 46336, 46368, 46384, 46380,     0, 32768, 
+    40960, 45056, 46080, 46336, 46368, 46384, 46385, 46382, 
+        0, 32768, 40960, 45056, 46080, 46336, 46368,     0, 
+    32768, 40960, 45056, 46080, 46336, 46400, 46384,     0, 
+    32768, 40960, 45056, 46080, 46336, 46400, 46384,     0, 
+    32768, 40960, 45056, 46080, 46336, 46400, 46384, 46386, 
+        0, 32768, 40960, 45056, 46080, 46336, 46400, 46384, 
+        0, 32768, 40960, 45056, 46080, 46336, 46400, 46384, 
+    46388,     0, 32768, 40960, 45056, 46080, 46336, 46400, 
+    46384, 46388,     0, 32768, 40960, 45056, 46080, 46336, 
+    46400, 46384, 46392, 46390,     0, 32768, 40960, 45056, 
+    46080, 46336, 46400, 46384,     0, 32768, 40960, 45056, 
+    46080, 46336, 46400, 46401, 46392,     0, 32768, 40960, 
+    45056, 46080, 46336, 46400, 46401, 46392,     0, 32768, 
+    40960, 45056, 46080, 46336, 46400, 46401, 46392, 46394, 
+        0, 32768, 40960, 45056, 46080, 46336, 46400, 46401, 
+    46392,     0, 32768, 40960, 45056, 46080, 46336, 46400, 
+    46401, 46392, 46396,     0, 32768, 40960, 45056, 46080, 
+    46336, 46400, 46401, 46403, 46396,     0, 32768, 40960, 
+    45056, 46080, 46336, 46400, 46401, 46403, 46396, 46398, 
+        0, 32768, 40960, 45056, 46080, 46336,     0, 32768, 
+    40960, 45056, 46080, 46336, 46400,     0, 32768, 40960, 
+    45056, 46080, 46336, 46400,     0, 32768, 40960, 45056, 
+    46080, 46336, 46400, 46402,     0, 32768, 40960, 45056, 
+    46080, 46336, 46400,     0, 32768, 40960, 45056, 46080, 
+    46336, 46400, 46404,     0, 32768, 40960, 45056, 46080, 
+    46336, 46400, 46404,     0, 32768, 40960, 45056, 46080, 
+    46336, 46400, 46408, 46406,     0, 32768, 40960, 45056, 
+    46080, 46336, 46400,     0, 32768, 40960, 45056, 46080, 
+    46336, 46400, 46408,     0, 32768, 40960, 45056, 46080, 
+    46336, 46400, 46408,     0, 32768, 40960, 45056, 46080, 
+    46336, 46400, 46408, 46410,     0, 32768, 40960, 45056, 
+    46080, 46336, 46400, 46408,     0, 32768, 40960, 45056, 
+    46080, 46336, 46400, 46416, 46412,     0, 32768, 40960, 
+    45056, 46080, 46336, 46400, 46416, 46412,     0, 32768, 
+    40960, 45056, 46080, 46336, 46400, 46416, 46417, 46414, 
+        0, 32768, 40960, 45056, 46080, 46336, 46400,     0, 
+    32768, 40960, 45056, 46080, 46336, 46400, 46416,     0, 
+    32768, 40960, 45056, 46080, 46336, 46400, 46416,     0, 
+    32768, 40960, 45056, 46080, 46336, 46400, 46416, 46418, 
+        0, 32768, 40960, 45056, 46080, 46336, 46400, 46416, 
+        0, 32768, 40960, 45056, 46080, 46336, 46400, 46416, 
+    46420,     0, 32768, 40960, 45056, 46080, 46336, 46400, 
+    46416, 46420,     0, 32768, 40960, 45056, 46080, 46336, 
+    46400, 46416, 46424, 46422,     0, 32768, 40960, 45056, 
+    46080, 46336, 46400, 46416,     0, 32768, 40960, 45056, 
+    46080, 46336, 46400, 46432, 46424,     0, 32768, 40960, 
+    45056, 46080, 46336, 46400, 46432, 46424,     0, 32768, 
+    40960, 45056, 46080, 46336, 46400, 46432, 46424, 46426, 
+        0, 32768, 40960, 45056, 46080, 46336, 46400, 46432, 
+    46424,     0, 32768, 40960, 45056, 46080, 46336, 46400, 
+    46432, 46433, 46428,     0, 32768, 40960, 45056, 46080, 
+    46336, 46400, 46432, 46433, 46428,     0, 32768, 40960, 
+    45056, 46080, 46336, 46400, 46432, 46433, 46428, 46430, 
+        0, 32768, 40960, 45056, 46080, 46336, 46400,     0, 
+    32768, 40960, 45056, 46080, 46336, 46464, 46432,     0, 
+    32768, 40960, 45056, 46080, 46336, 46464, 46432,     0, 
+    32768, 40960, 45056, 46080, 46336, 46464, 46432, 46434, 
+        0, 32768, 40960, 45056, 46080, 46336, 46464, 46432, 
+        0, 32768, 40960, 45056, 46080, 46336, 46464, 46432, 
+    46436,     0, 32768, 40960, 45056, 46080, 46336, 46464, 
+    46432, 46436,     0, 32768, 40960, 45056, 46080, 46336, 
+    46464, 46432, 46440, 46438,     0, 32768, 40960, 45056, 
+    46080, 46336, 46464, 46432,     0, 32768, 40960, 45056, 
+    46080, 46336, 46464, 46432, 46440,     0, 32768, 40960, 
+    45056, 46080, 46336, 46464, 46432, 46440,     0, 32768, 
+    40960, 45056, 46080, 46336, 46464, 46432, 46440, 46442, 
+        0, 32768, 40960, 45056, 46080, 46336, 46464, 46432, 
+    46440,     0, 32768, 40960, 45056, 46080, 46336, 46464, 
+    46432, 46448, 46444,     0, 32768, 40960, 45056, 46080, 
+    46336, 46464, 46432, 46448, 46444,     0, 32768, 40960, 
+    45056, 46080, 46336, 46464, 46432, 46448, 46449, 46446, 
+        0, 32768, 40960, 45056, 46080, 46336, 46464, 46432, 
+        0, 32768, 40960, 45056, 46080, 46336, 46464, 46465, 
+    46448,     0, 32768, 40960, 45056, 46080, 46336, 46464, 
+    46465, 46448,     0, 32768, 40960, 45056, 46080, 46336, 
+    46464, 46465, 46448, 46450,     0, 32768, 40960, 45056, 
+    46080, 46336, 46464, 46465, 46448,     0, 32768, 40960, 
+    45056, 46080, 46336, 46464, 46465, 46448, 46452,     0, 
+    32768, 40960, 45056, 46080, 46336, 46464, 46465, 46448, 
+    46452,     0, 32768, 40960, 45056, 46080, 46336, 46464, 
+    46465, 46448, 46456, 46454,     0, 32768, 40960, 45056, 
+    46080, 46336, 46464, 46465, 46448,     0, 32768, 40960, 
+    45056, 46080, 46336, 46464, 46465, 46448, 46456,     0, 
+    32768, 40960, 45056, 46080, 46336, 46464, 46465, 46467, 
+    46456,     0, 32768, 40960, 45056, 46080, 46336, 46464, 
+    46465, 46467, 46456, 46458,     0, 32768, 40960, 45056, 
+    46080, 46336, 46464, 46465, 46467, 46456,     0, 32768, 
+    40960, 45056, 46080, 46336, 46464, 46465, 46467, 46456, 
+    46460,     0, 32768, 40960, 45056, 46080, 46336, 46464, 
+    46465, 46467, 46456, 46460,     0, 32768, 40960, 45056, 
+    46080, 46336, 46464, 46465, 46467, 46456, 46460, 46462, 
+        0, 32768, 40960, 45056, 46080, 46336,     0, 32768, 
+    40960, 45056, 46080, 46592, 46464,     0, 32768, 40960, 
+    45056, 46080, 46592, 46464,     0, 32768, 40960, 45056, 
+    46080, 46592, 46464, 46466,     0, 32768, 40960, 45056, 
+    46080, 46592, 46464,     0, 32768, 40960, 45056, 46080, 
+    46592, 46464, 46468,     0, 32768, 40960, 45056, 46080, 
+    46592, 46464, 46468,     0, 32768, 40960, 45056, 46080, 
+    46592, 46464, 46472, 46470,     0, 32768, 40960, 45056, 
+    46080, 46592, 46464,     0, 32768, 40960, 45056, 46080, 
+    46592, 46464, 46472,     0, 32768, 40960, 45056, 46080, 
+    46592, 46464, 46472,     0, 32768, 40960, 45056, 46080, 
+    46592, 46464, 46472, 46474,     0, 32768, 40960, 45056, 
+    46080, 46592, 46464, 46472,     0, 32768, 40960, 45056, 
+    46080, 46592, 46464, 46480, 46476,     0, 32768, 40960, 
+    45056, 46080, 46592, 46464, 46480, 46476,     0, 32768, 
+    40960, 45056, 46080, 46592, 46464, 46480, 46481, 46478, 
+        0, 32768, 40960, 45056, 46080, 46592, 46464,     0, 
+    32768, 40960, 45056, 46080, 46592, 46464, 46480,     0, 
+    32768, 40960, 45056, 46080, 46592, 46464, 46480,     0, 
+    32768, 40960, 45056, 46080, 46592, 46464, 46480, 46482, 
+        0, 32768, 40960, 45056, 46080, 46592, 46464, 46480, 
+        0, 32768, 40960, 45056, 46080, 46592, 46464, 46480, 
+    46484,     0, 32768, 40960, 45056, 46080, 46592, 46464, 
+    46480, 46484,     0, 32768, 40960, 45056, 46080, 46592, 
+    46464, 46480, 46488, 46486,     0, 32768, 40960, 45056, 
+    46080, 46592, 46464, 46480,     0, 32768, 40960, 45056, 
+    46080, 46592, 46464, 46496, 46488,     0, 32768, 40960, 
+    45056, 46080, 46592, 46464, 46496, 46488,     0, 32768, 
+    40960, 45056, 46080, 46592, 46464, 46496, 46488, 46490, 
+        0, 32768, 40960, 45056, 46080, 46592, 46464, 46496, 
+    46488,     0, 32768, 40960, 45056, 46080, 46592, 46464, 
+    46496, 46497, 46492,     0, 32768, 40960, 45056, 46080, 
+    46592, 46464, 46496, 46497, 46492,     0, 32768, 40960, 
+    45056, 46080, 46592, 46464, 46496, 46497, 46492, 46494, 
+        0, 32768, 40960, 45056, 46080, 46592, 46464,     0, 
+    32768, 40960, 45056, 46080, 46592, 46464, 46496,     0, 
+    32768, 40960, 45056, 46080, 46592, 46464, 46496,     0, 
+    32768, 40960, 45056, 46080, 46592, 46464, 46496, 46498, 
+        0, 32768, 40960, 45056, 46080, 46592, 46464, 46496, 
+        0, 32768, 40960, 45056, 46080, 46592, 46464, 46496, 
+    46500,     0, 32768, 40960, 45056, 46080, 46592, 46464, 
+    46496, 46500,     0, 32768, 40960, 45056, 46080, 46592, 
+    46464, 46496, 46504, 46502,     0, 32768, 40960, 45056, 
+    46080, 46592, 46464, 46496,     0, 32768, 40960, 45056, 
+    46080, 46592, 46464, 46496, 46504,     0, 32768, 40960, 
+    45056, 46080, 46592, 46464, 46496, 46504,     0, 32768, 
+    40960, 45056, 46080, 46592, 46464, 46496, 46504, 46506, 
+        0, 32768, 40960, 45056, 46080, 46592, 46464, 46496, 
+    46504,     0, 32768, 40960, 45056, 46080, 46592, 46464, 
+    46496, 46512, 46508,     0, 32768, 40960, 45056, 46080, 
+    46592, 46464, 46496, 46512, 46508,     0, 32768, 40960, 
+    45056, 46080, 46592, 46464, 46496, 46512, 46513, 46510, 
+        0, 32768, 40960, 45056, 46080, 46592, 46464, 46496, 
+        0, 32768, 40960, 45056, 46080, 46592, 46464, 46528, 
+    46512,     0, 32768, 40960, 45056, 46080, 46592, 46464, 
+    46528, 46512,     0, 32768, 40960, 45056, 46080, 46592, 
+    46464, 46528, 46512, 46514,     0, 32768, 40960, 45056, 
+    46080, 46592, 46464, 46528, 46512,     0, 32768, 40960, 
+    45056, 46080, 46592, 46464, 46528, 46512, 46516,     0, 
+    32768, 40960, 45056, 46080, 46592, 46464, 46528, 46512, 
+    46516,     0, 32768, 40960, 45056, 46080, 46592, 46464, 
+    46528, 46512, 46520, 46518,     0, 32768, 40960, 45056, 
+    46080, 46592, 46464, 46528, 46512,     0, 32768, 40960, 
+    45056, 46080, 46592, 46464, 46528, 46529, 46520,     0, 
+    32768, 40960, 45056, 46080, 46592, 46464, 46528, 46529, 
+    46520,     0, 32768, 40960, 45056, 46080, 46592, 46464, 
+    46528, 46529, 46520, 46522,     0, 32768, 40960, 45056, 
+    46080, 46592, 46464, 46528, 46529, 46520,     0, 32768, 
+    40960, 45056, 46080, 46592, 46464, 46528, 46529, 46520, 
+    46524,     0, 32768, 40960, 45056, 46080, 46592, 46464, 
+    46528, 46529, 46531, 46524,     0, 32768, 40960, 45056, 
+    46080, 46592, 46464, 46528, 46529, 46531, 46524, 46526, 
+        0, 32768, 40960, 45056, 46080, 46592, 46464,     0, 
+    32768, 40960, 45056, 46080, 46592, 46593, 46528,     0, 
+    32768, 40960, 45056, 46080, 46592, 46593, 46528,     0, 
+    32768, 40960, 45056, 46080, 46592, 46593, 46528, 46530, 
+        0, 32768, 40960, 45056, 46080, 46592, 46593, 46528, 
+        0, 32768, 40960, 45056, 46080, 46592, 46593, 46528, 
+    46532,     0, 32768, 40960, 45056, 46080, 46592, 46593, 
+    46528, 46532,     0, 32768, 40960, 45056, 46080, 46592, 
+    46593, 46528, 46536, 46534,     0, 32768, 40960, 45056, 
+    46080, 46592, 46593, 46528,     0, 32768, 40960, 45056, 
+    46080, 46592, 46593, 46528, 46536,     0, 32768, 40960, 
+    45056, 46080, 46592, 46593, 46528, 46536,     0, 32768, 
+    40960, 45056, 46080, 46592, 46593, 46528, 46536, 46538, 
+        0, 32768, 40960, 45056, 46080, 46592, 46593, 46528, 
+    46536,     0, 32768, 40960, 45056, 46080, 46592, 46593, 
+    46528, 46544, 46540,     0, 32768, 40960, 45056, 46080, 
+    46592, 46593, 46528, 46544, 46540,     0, 32768, 40960, 
+    45056, 46080, 46592, 46593, 46528, 46544, 46545, 46542, 
+        0, 32768, 40960, 45056, 46080, 46592, 46593, 46528, 
+        0, 32768, 40960, 45056, 46080, 46592, 46593, 46528, 
+    46544,     0, 32768, 40960, 45056, 46080, 46592, 46593, 
+    46528, 46544,     0, 32768, 40960, 45056, 46080, 46592, 
+    46593, 46528, 46544, 46546,     0, 32768, 40960, 45056, 
+    46080, 46592, 46593, 46528, 46544,     0, 32768, 40960, 
+    45056, 46080, 46592, 46593, 46528, 46544, 46548,     0, 
+    32768, 40960, 45056, 46080, 46592, 46593, 46528, 46544, 
+    46548,     0, 32768, 40960, 45056, 46080, 46592, 46593, 
+    46528, 46544, 46552, 46550,     0, 32768, 40960, 45056, 
+    46080, 46592, 46593, 46528, 46544,     0, 32768, 40960, 
+    45056, 46080, 46592, 46593, 46528, 46560, 46552,     0, 
+    32768, 40960, 45056, 46080, 46592, 46593, 46528, 46560, 
+    46552,     0, 32768, 40960, 45056, 46080, 46592, 46593, 
+    46528, 46560, 46552, 46554,     0, 32768, 40960, 45056, 
+    46080, 46592, 46593, 46528, 46560, 46552,     0, 32768, 
+    40960, 45056, 46080, 46592, 46593, 46528, 46560, 46561, 
+    46556,     0, 32768, 40960, 45056, 46080, 46592, 46593, 
+    46528, 46560, 46561, 46556,     0, 32768, 40960, 45056, 
+    46080, 46592, 46593, 46528, 46560, 46561, 46556, 46558, 
+        0, 32768, 40960, 45056, 46080, 46592, 46593, 46528, 
+        0, 32768, 40960, 45056, 46080, 46592, 46593, 46528, 
+    46560,     0, 32768, 40960, 45056, 46080, 46592, 46593, 
+    46595, 46560,     0, 32768, 40960, 45056, 46080, 46592, 
+    46593, 46595, 46560, 46562,     0, 32768, 40960, 45056, 
+    46080, 46592, 46593, 46595, 46560,     0, 32768, 40960, 
+    45056, 46080, 46592, 46593, 46595, 46560, 46564,     0, 
+    32768, 40960, 45056, 46080, 46592, 46593, 46595, 46560, 
+    46564,     0, 32768, 40960, 45056, 46080, 46592, 46593, 
+    46595, 46560, 46568, 46566,     0, 32768, 40960, 45056, 
+    46080, 46592, 46593, 46595, 46560,     0, 32768, 40960, 
+    45056, 46080, 46592, 46593, 46595, 46560, 46568,     0, 
+    32768, 40960, 45056, 46080, 46592, 46593, 46595, 46560, 
+    46568,     0, 32768, 40960, 45056, 46080, 46592, 46593, 
+    46595, 46560, 46568, 46570,     0, 32768, 40960, 45056, 
+    46080, 46592, 46593, 46595, 46560, 46568,     0, 32768, 
+    40960, 45056, 46080, 46592, 46593, 46595, 46560, 46576, 
+    46572,     0, 32768, 40960, 45056, 46080, 46592, 46593, 
+    46595, 46560, 46576, 46572,     0, 32768, 40960, 45056, 
+    46080, 46592, 46593, 46595, 46560, 46576, 46577, 46574, 
+        0, 32768, 40960, 45056, 46080, 46592, 46593, 46595, 
+    46560,     0, 32768, 40960, 45056, 46080, 46592, 46593, 
+    46595, 46560, 46576,     0, 32768, 40960, 45056, 46080, 
+    46592, 46593, 46595, 46560, 46576,     0, 32768, 40960, 
+    45056, 46080, 46592, 46593, 46595, 46560, 46576, 46578, 
+        0, 32768, 40960, 45056, 46080, 46592, 46593, 46595, 
+    46599, 46576,     0, 32768, 40960, 45056, 46080, 46592, 
+    46593, 46595, 46599, 46576, 46580,     0, 32768, 40960, 
+    45056, 46080, 46592, 46593, 46595, 46599, 46576, 46580, 
+        0, 32768, 40960, 45056, 46080, 46592, 46593, 46595, 
+    46599, 46576, 46584, 46582,     0, 32768, 40960, 45056, 
+    46080, 46592, 46593, 46595, 46599, 46576,     0, 32768, 
+    40960, 45056, 46080, 46592, 46593, 46595, 46599, 46576, 
+    46584,     0, 32768, 40960, 45056, 46080, 46592, 46593, 
+    46595, 46599, 46576, 46584,     0, 32768, 40960, 45056, 
+    46080, 46592, 46593, 46595, 46599, 46576, 46584, 46586, 
+        0, 32768, 40960, 45056, 46080, 46592, 46593, 46595, 
+    46599, 46576, 46584,     0, 32768, 40960, 45056, 46080, 
+    46592, 46593, 46595, 46599, 46576, 46584, 46588,     0, 
+    32768, 40960, 45056, 46080, 46592, 46593, 46595, 46599, 
+    46576, 46584, 46588,     0, 32768, 40960, 45056, 46080, 
+    46592, 46593, 46595, 46599, 46576, 46584, 46588, 46590, 
+        0, 32768, 40960, 45056, 46080,     0, 32768, 40960, 
+    45056, 47104, 46592,     0, 32768, 40960, 45056, 47104, 
+    46592,     0, 32768, 40960, 45056, 47104, 46592, 46594, 
+        0, 32768, 40960, 45056, 47104, 46592,     0, 32768, 
+    40960, 45056, 47104, 46592, 46596,     0, 32768, 40960, 
+    45056, 47104, 46592, 46596,     0, 32768, 40960, 45056, 
+    47104, 46592, 46600, 46598,     0, 32768, 40960, 45056, 
+    47104, 46592,     0, 32768, 40960, 45056, 47104, 46592, 
+    46600,     0, 32768, 40960, 45056, 47104, 46592, 46600, 
+        0, 32768, 40960, 45056, 47104, 46592, 46600, 46602, 
+        0, 32768, 40960, 45056, 47104, 46592, 46600,     0, 
+    32768, 40960, 45056, 47104, 46592, 46608, 46604,     0, 
+    32768, 40960, 45056, 47104, 46592, 46608, 46604,     0, 
+    32768, 40960, 45056, 47104, 46592, 46608, 46609, 46606, 
+        0, 32768, 40960, 45056, 47104, 46592,     0, 32768, 
+    40960, 45056, 47104, 46592, 46608,     0, 32768, 40960, 
+    45056, 47104, 46592, 46608,     0, 32768, 40960, 45056, 
+    47104, 46592, 46608, 46610,     0, 32768, 40960, 45056, 
+    47104, 46592, 46608,     0, 32768, 40960, 45056, 47104, 
+    46592, 46608, 46612,     0, 32768, 40960, 45056, 47104, 
+    46592, 46608, 46612,     0, 32768, 40960, 45056, 47104, 
+    46592, 46608, 46616, 46614,     0, 32768, 40960, 45056, 
+    47104, 46592, 46608,     0, 32768, 40960, 45056, 47104, 
+    46592, 46624, 46616,     0, 32768, 40960, 45056, 47104, 
+    46592, 46624, 46616,     0, 32768, 40960, 45056, 47104, 
+    46592, 46624, 46616, 46618,     0, 32768, 40960, 45056, 
+    47104, 46592, 46624, 46616,     0, 32768, 40960, 45056, 
+    47104, 46592, 46624, 46625, 46620,     0, 32768, 40960, 
+    45056, 47104, 46592, 46624, 46625, 46620,     0, 32768, 
+    40960, 45056, 47104, 46592, 46624, 46625, 46620, 46622, 
+        0, 32768, 40960, 45056, 47104, 46592,     0, 32768, 
+    40960, 45056, 47104, 46592, 46624,     0, 32768, 40960, 
+    45056, 47104, 46592, 46624,     0, 32768, 40960, 45056, 
+    47104, 46592, 46624, 46626,     0, 32768, 40960, 45056, 
+    47104, 46592, 46624,     0, 32768, 40960, 45056, 47104, 
+    46592, 46624, 46628,     0, 32768, 40960, 45056, 47104, 
+    46592, 46624, 46628,     0, 32768, 40960, 45056, 47104, 
+    46592, 46624, 46632, 46630,     0, 32768, 40960, 45056, 
+    47104, 46592, 46624,     0, 32768, 40960, 45056, 47104, 
+    46592, 46624, 46632,     0, 32768, 40960, 45056, 47104, 
+    46592, 46624, 46632,     0, 32768, 40960, 45056, 47104, 
+    46592, 46624, 46632, 46634,     0, 32768, 40960, 45056, 
+    47104, 46592, 46624, 46632,     0, 32768, 40960, 45056, 
+    47104, 46592, 46624, 46640, 46636,     0, 32768, 40960, 
+    45056, 47104, 46592, 46624, 46640, 46636,     0, 32768, 
+    40960, 45056, 47104, 46592, 46624, 46640, 46641, 46638, 
+        0, 32768, 40960, 45056, 47104, 46592, 46624,     0, 
+    32768, 40960, 45056, 47104, 46592, 46656, 46640,     0, 
+    32768, 40960, 45056, 47104, 46592, 46656, 46640,     0, 
+    32768, 40960, 45056, 47104, 46592, 46656, 46640, 46642, 
+        0, 32768, 40960, 45056, 47104, 46592, 46656, 46640, 
+        0, 32768, 40960, 45056, 47104, 46592, 46656, 46640, 
+    46644,     0, 32768, 40960, 45056, 47104, 46592, 46656, 
+    46640, 46644,     0, 32768, 40960, 45056, 47104, 46592, 
+    46656, 46640, 46648, 46646,     0, 32768, 40960, 45056, 
+    47104, 46592, 46656, 46640,     0, 32768, 40960, 45056, 
+    47104, 46592, 46656, 46657, 46648,     0, 32768, 40960, 
+    45056, 47104, 46592, 46656, 46657, 46648,     0, 32768, 
+    40960, 45056, 47104, 46592, 46656, 46657, 46648, 46650, 
+        0, 32768, 40960, 45056, 47104, 46592, 46656, 46657, 
+    46648,     0, 32768, 40960, 45056, 47104, 46592, 46656, 
+    46657, 46648, 46652,     0, 32768, 40960, 45056, 47104, 
+    46592, 46656, 46657, 46659, 46652,     0, 32768, 40960, 
+    45056, 47104, 46592, 46656, 46657, 46659, 46652, 46654, 
+        0, 32768, 40960, 45056, 47104, 46592,     0, 32768, 
+    40960, 45056, 47104, 46592, 46656,     0, 32768, 40960, 
+    45056, 47104, 46592, 46656,     0, 32768, 40960, 45056, 
+    47104, 46592, 46656, 46658,     0, 32768, 40960, 45056, 
+    47104, 46592, 46656,     0, 32768, 40960, 45056, 47104, 
+    46592, 46656, 46660,     0, 32768, 40960, 45056, 47104, 
+    46592, 46656, 46660,     0, 32768, 40960, 45056, 47104, 
+    46592, 46656, 46664, 46662,     0, 32768, 40960, 45056, 
+    47104, 46592, 46656,     0, 32768, 40960, 45056, 47104, 
+    46592, 46656, 46664,     0, 32768, 40960, 45056, 47104, 
+    46592, 46656, 46664,     0, 32768, 40960, 45056, 47104, 
+    46592, 46656, 46664, 46666,     0, 32768, 40960, 45056, 
+    47104, 46592, 46656, 46664,     0, 32768, 40960, 45056, 
+    47104, 46592, 46656, 46672, 46668,     0, 32768, 40960, 
+    45056, 47104, 46592, 46656, 46672, 46668,     0, 32768, 
+    40960, 45056, 47104, 46592, 46656, 46672, 46673, 46670, 
+        0, 32768, 40960, 45056, 47104, 46592, 46656,     0, 
+    32768, 40960, 45056, 47104, 46592, 46656, 46672,     0, 
+    32768, 40960, 45056, 47104, 46592, 46656, 46672,     0, 
+    32768, 40960, 45056, 47104, 46592, 46656, 46672, 46674, 
+        0, 32768, 40960, 45056, 47104, 46592, 46656, 46672, 
+        0, 32768, 40960, 45056, 47104, 46592, 46656, 46672, 
+    46676,     0, 32768, 40960, 45056, 47104, 46592, 46656, 
+    46672, 46676,     0, 32768, 40960, 45056, 47104, 46592, 
+    46656, 46672, 46680, 46678,     0, 32768, 40960, 45056, 
+    47104, 46592, 46656, 46672,     0, 32768, 40960, 45056, 
+    47104, 46592, 46656, 46688, 46680,     0, 32768, 40960, 
+    45056, 47104, 46592, 46656, 46688, 46680,     0, 32768, 
+    40960, 45056, 47104, 46592, 46656, 46688, 46680, 46682, 
+        0, 32768, 40960, 45056, 47104, 46592, 46656, 46688, 
+    46680,     0, 32768, 40960, 45056, 47104, 46592, 46656, 
+    46688, 46689, 46684,     0, 32768, 40960, 45056, 47104, 
+    46592, 46656, 46688, 46689, 46684,     0, 32768, 40960, 
+    45056, 47104, 46592, 46656, 46688, 46689, 46684, 46686, 
+        0, 32768, 40960, 45056, 47104, 46592, 46656,     0, 
+    32768, 40960, 45056, 47104, 46592, 46720, 46688,     0, 
+    32768, 40960, 45056, 47104, 46592, 46720, 46688,     0, 
+    32768, 40960, 45056, 47104, 46592, 46720, 46688, 46690, 
+        0, 32768, 40960, 45056, 47104, 46592, 46720, 46688, 
+        0, 32768, 40960, 45056, 47104, 46592, 46720, 46688, 
+    46692,     0, 32768, 40960, 45056, 47104, 46592, 46720, 
+    46688, 46692,     0, 32768, 40960, 45056, 47104, 46592, 
+    46720, 46688, 46696, 46694,     0, 32768, 40960, 45056, 
+    47104, 46592, 46720, 46688,     0, 32768, 40960, 45056, 
+    47104, 46592, 46720, 46688, 46696,     0, 32768, 40960, 
+    45056, 47104, 46592, 46720, 46688, 46696,     0, 32768, 
+    40960, 45056, 47104, 46592, 46720, 46688, 46696, 46698, 
+        0, 32768, 40960, 45056, 47104, 46592, 46720, 46688, 
+    46696,     0, 32768, 40960, 45056, 47104, 46592, 46720, 
+    46688, 46704, 46700,     0, 32768, 40960, 45056, 47104, 
+    46592, 46720, 46688, 46704, 46700,     0, 32768, 40960, 
+    45056, 47104, 46592, 46720, 46688, 46704, 46705, 46702, 
+        0, 32768, 40960, 45056, 47104, 46592, 46720, 46688, 
+        0, 32768, 40960, 45056, 47104, 46592, 46720, 46721, 
+    46704,     0, 32768, 40960, 45056, 47104, 46592, 46720, 
+    46721, 46704,     0, 32768, 40960, 45056, 47104, 46592, 
+    46720, 46721, 46704, 46706,     0, 32768, 40960, 45056, 
+    47104, 46592, 46720, 46721, 46704,     0, 32768, 40960, 
+    45056, 47104, 46592, 46720, 46721, 46704, 46708,     0, 
+    32768, 40960, 45056, 47104, 46592, 46720, 46721, 46704, 
+    46708,     0, 32768, 40960, 45056, 47104, 46592, 46720, 
+    46721, 46704, 46712, 46710,     0, 32768, 40960, 45056, 
+    47104, 46592, 46720, 46721, 46704,     0, 32768, 40960, 
+    45056, 47104, 46592, 46720, 46721, 46704, 46712,     0, 
+    32768, 40960, 45056, 47104, 46592, 46720, 46721, 46723, 
+    46712,     0, 32768, 40960, 45056, 47104, 46592, 46720, 
+    46721, 46723, 46712, 46714,     0, 32768, 40960, 45056, 
+    47104, 46592, 46720, 46721, 46723, 46712,     0, 32768, 
+    40960, 45056, 47104, 46592, 46720, 46721, 46723, 46712, 
+    46716,     0, 32768, 40960, 45056, 47104, 46592, 46720, 
+    46721, 46723, 46712, 46716,     0, 32768, 40960, 45056, 
+    47104, 46592, 46720, 46721, 46723, 46712, 46716, 46718, 
+        0, 32768, 40960, 45056, 47104, 46592,     0, 32768, 
+    40960, 45056, 47104, 46592, 46720,     0, 32768, 40960, 
+    45056, 47104, 46592, 46720,     0, 32768, 40960, 45056, 
+    47104, 46592, 46720, 46722,     0, 32768, 40960, 45056, 
+    47104, 46592, 46720,     0, 32768, 40960, 45056, 47104, 
+    46592, 46720, 46724,     0, 32768, 40960, 45056, 47104, 
+    46592, 46720, 46724,     0, 32768, 40960, 45056, 47104, 
+    46592, 46720, 46728, 46726,     0, 32768, 40960, 45056, 
+    47104, 46592, 46720,     0, 32768, 40960, 45056, 47104, 
+    46592, 46720, 46728,     0, 32768, 40960, 45056, 47104, 
+    46592, 46720, 46728,     0, 32768, 40960, 45056, 47104, 
+    46592, 46720, 46728, 46730,     0, 32768, 40960, 45056, 
+    47104, 46592, 46720, 46728,     0, 32768, 40960, 45056, 
+    47104, 46592, 46720, 46736, 46732,     0, 32768, 40960, 
+    45056, 47104, 46592, 46720, 46736, 46732,     0, 32768, 
+    40960, 45056, 47104, 46592, 46720, 46736, 46737, 46734, 
+        0, 32768, 40960, 45056, 47104, 46592, 46720,     0, 
+    32768, 40960, 45056, 47104, 46592, 46720, 46736,     0, 
+    32768, 40960, 45056, 47104, 46592, 46720, 46736,     0, 
+    32768, 40960, 45056, 47104, 46592, 46720, 46736, 46738, 
+        0, 32768, 40960, 45056, 47104, 46592, 46720, 46736, 
+        0, 32768, 40960, 45056, 47104, 46592, 46720, 46736, 
+    46740,     0, 32768, 40960, 45056, 47104, 46592, 46720, 
+    46736, 46740,     0, 32768, 40960, 45056, 47104, 46592, 
+    46720, 46736, 46744, 46742,     0, 32768, 40960, 45056, 
+    47104, 46592, 46720, 46736,     0, 32768, 40960, 45056, 
+    47104, 46592, 46720, 46752, 46744,     0, 32768, 40960, 
+    45056, 47104, 46592, 46720, 46752, 46744,     0, 32768, 
+    40960, 45056, 47104, 46592, 46720, 46752, 46744, 46746, 
+        0, 32768, 40960, 45056, 47104, 46592, 46720, 46752, 
+    46744,     0, 32768, 40960, 45056, 47104, 46592, 46720, 
+    46752, 46753, 46748,     0, 32768, 40960, 45056, 47104, 
+    46592, 46720, 46752, 46753, 46748,     0, 32768, 40960, 
+    45056, 47104, 46592, 46720, 46752, 46753, 46748, 46750, 
+        0, 32768, 40960, 45056, 47104, 46592, 46720,     0, 
+    32768, 40960, 45056, 47104, 46592, 46720, 46752,     0, 
+    32768, 40960, 45056, 47104, 46592, 46720, 46752,     0, 
+    32768, 40960, 45056, 47104, 46592, 46720, 46752, 46754, 
+        0, 32768, 40960, 45056, 47104, 46592, 46720, 46752, 
+        0, 32768, 40960, 45056, 47104, 46592, 46720, 46752, 
+    46756,     0, 32768, 40960, 45056, 47104, 46592, 46720, 
+    46752, 46756,     0, 32768, 40960, 45056, 47104, 46592, 
+    46720, 46752, 46760, 46758,     0, 32768, 40960, 45056, 
+    47104, 46592, 46720, 46752,     0, 32768, 40960, 45056, 
+    47104, 46592, 46720, 46752, 46760,     0, 32768, 40960, 
+    45056, 47104, 46592, 46720, 46752, 46760,     0, 32768, 
+    40960, 45056, 47104, 46592, 46720, 46752, 46760, 46762, 
+        0, 32768, 40960, 45056, 47104, 46592, 46720, 46752, 
+    46760,     0, 32768, 40960, 45056, 47104, 46592, 46720, 
+    46752, 46768, 46764,     0, 32768, 40960, 45056, 47104, 
+    46592, 46720, 46752, 46768, 46764,     0, 32768, 40960, 
+    45056, 47104, 46592, 46720, 46752, 46768, 46769, 46766, 
+        0, 32768, 40960, 45056, 47104, 46592, 46720, 46752, 
+        0, 32768, 40960, 45056, 47104, 46592, 46720, 46784, 
+    46768,     0, 32768, 40960, 45056, 47104, 46592, 46720, 
+    46784, 46768,     0, 32768, 40960, 45056, 47104, 46592, 
+    46720, 46784, 46768, 46770,     0, 32768, 40960, 45056, 
+    47104, 46592, 46720, 46784, 46768,     0, 32768, 40960, 
+    45056, 47104, 46592, 46720, 46784, 46768, 46772,     0, 
+    32768, 40960, 45056, 47104, 46592, 46720, 46784, 46768, 
+    46772,     0, 32768, 40960, 45056, 47104, 46592, 46720, 
+    46784, 46768, 46776, 46774,     0, 32768, 40960, 45056, 
+    47104, 46592, 46720, 46784, 46768,     0, 32768, 40960, 
+    45056, 47104, 46592, 46720, 46784, 46785, 46776,     0, 
+    32768, 40960, 45056, 47104, 46592, 46720, 46784, 46785, 
+    46776,     0, 32768, 40960, 45056, 47104, 46592, 46720, 
+    46784, 46785, 46776, 46778,     0, 32768, 40960, 45056, 
+    47104, 46592, 46720, 46784, 46785, 46776,     0, 32768, 
+    40960, 45056, 47104, 46592, 46720, 46784, 46785, 46776, 
+    46780,     0, 32768, 40960, 45056, 47104, 46592, 46720, 
+    46784, 46785, 46787, 46780,     0, 32768, 40960, 45056, 
+    47104, 46592, 46720, 46784, 46785, 46787, 46780, 46782, 
+        0, 32768, 40960, 45056, 47104, 46592, 46720,     0, 
+    32768, 40960, 45056, 47104, 46592, 46848, 46784,     0, 
+    32768, 40960, 45056, 47104, 46592, 46848, 46784,     0, 
+    32768, 40960, 45056, 47104, 46592, 46848, 46784, 46786, 
+        0, 32768, 40960, 45056, 47104, 46592, 46848, 46784, 
+        0, 32768, 40960, 45056, 47104, 46592, 46848, 46784, 
+    46788,     0, 32768, 40960, 45056, 47104, 46592, 46848, 
+    46784, 46788,     0, 32768, 40960, 45056, 47104, 46592, 
+    46848, 46784, 46792, 46790,     0, 32768, 40960, 45056, 
+    47104, 46592, 46848, 46784,     0, 32768, 40960, 45056, 
+    47104, 46592, 46848, 46784, 46792,     0, 32768, 40960, 
+    45056, 47104, 46592, 46848, 46784, 46792,     0, 32768, 
+    40960, 45056, 47104, 46592, 46848, 46784, 46792, 46794, 
+        0, 32768, 40960, 45056, 47104, 46592, 46848, 46784, 
+    46792,     0, 32768, 40960, 45056, 47104, 46592, 46848, 
+    46784, 46800, 46796,     0, 32768, 40960, 45056, 47104, 
+    46592, 46848, 46784, 46800, 46796,     0, 32768, 40960, 
+    45056, 47104, 46592, 46848, 46784, 46800, 46801, 46798, 
+        0, 32768, 40960, 45056, 47104, 46592, 46848, 46784, 
+        0, 32768, 40960, 45056, 47104, 46592, 46848, 46784, 
+    46800,     0, 32768, 40960, 45056, 47104, 46592, 46848, 
+    46784, 46800,     0, 32768, 40960, 45056, 47104, 46592, 
+    46848, 46784, 46800, 46802,     0, 32768, 40960, 45056, 
+    47104, 46592, 46848, 46784, 46800,     0, 32768, 40960, 
+    45056, 47104, 46592, 46848, 46784, 46800, 46804,     0, 
+    32768, 40960, 45056, 47104, 46592, 46848, 46784, 46800, 
+    46804,     0, 32768, 40960, 45056, 47104, 46592, 46848, 
+    46784, 46800, 46808, 46806,     0, 32768, 40960, 45056, 
+    47104, 46592, 46848, 46784, 46800,     0, 32768, 40960, 
+    45056, 47104, 46592, 46848, 46784, 46816, 46808,     0, 
+    32768, 40960, 45056, 47104, 46592, 46848, 46784, 46816, 
+    46808,     0, 32768, 40960, 45056, 47104, 46592, 46848, 
+    46784, 46816, 46808, 46810,     0, 32768, 40960, 45056, 
+    47104, 46592, 46848, 46784, 46816, 46808,     0, 32768, 
+    40960, 45056, 47104, 46592, 46848, 46784, 46816, 46817, 
+    46812,     0, 32768, 40960, 45056, 47104, 46592, 46848, 
+    46784, 46816, 46817, 46812,     0, 32768, 40960, 45056, 
+    47104, 46592, 46848, 46784, 46816, 46817, 46812, 46814, 
+        0, 32768, 40960, 45056, 47104, 46592, 46848, 46784, 
+        0, 32768, 40960, 45056, 47104, 46592, 46848, 46849, 
+    46816,     0, 32768, 40960, 45056, 47104, 46592, 46848, 
+    46849, 46816,     0, 32768, 40960, 45056, 47104, 46592, 
+    46848, 46849, 46816, 46818,     0, 32768, 40960, 45056, 
+    47104, 46592, 46848, 46849, 46816,     0, 32768, 40960, 
+    45056, 47104, 46592, 46848, 46849, 46816, 46820,     0, 
+    32768, 40960, 45056, 47104, 46592, 46848, 46849, 46816, 
+    46820,     0, 32768, 40960, 45056, 47104, 46592, 46848, 
+    46849, 46816, 46824, 46822,     0, 32768, 40960, 45056, 
+    47104, 46592, 46848, 46849, 46816,     0, 32768, 40960, 
+    45056, 47104, 46592, 46848, 46849, 46816, 46824,     0, 
+    32768, 40960, 45056, 47104, 46592, 46848, 46849, 46816, 
+    46824,     0, 32768, 40960, 45056, 47104, 46592, 46848, 
+    46849, 46816, 46824, 46826,     0, 32768, 40960, 45056, 
+    47104, 46592, 46848, 46849, 46816, 46824,     0, 32768, 
+    40960, 45056, 47104, 46592, 46848, 46849, 46816, 46832, 
+    46828,     0, 32768, 40960, 45056, 47104, 46592, 46848, 
+    46849, 46816, 46832, 46828,     0, 32768, 40960, 45056, 
+    47104, 46592, 46848, 46849, 46816, 46832, 46833, 46830, 
+        0, 32768, 40960, 45056, 47104, 46592, 46848, 46849, 
+    46816,     0, 32768, 40960, 45056, 47104, 46592, 46848, 
+    46849, 46816, 46832,     0, 32768, 40960, 45056, 47104, 
+    46592, 46848, 46849, 46851, 46832,     0, 32768, 40960, 
+    45056, 47104, 46592, 46848, 46849, 46851, 46832, 46834, 
+        0, 32768, 40960, 45056, 47104, 46592, 46848, 46849, 
+    46851, 46832,     0, 32768, 40960, 45056, 47104, 46592, 
+    46848, 46849, 46851, 46832, 46836,     0, 32768, 40960, 
+    45056, 47104, 46592, 46848, 46849, 46851, 46832, 46836, 
+        0, 32768, 40960, 45056, 47104, 46592, 46848, 46849, 
+    46851, 46832, 46840, 46838,     0, 32768, 40960, 45056, 
+    47104, 46592, 46848, 46849, 46851, 46832,     0, 32768, 
+    40960, 45056, 47104, 46592, 46848, 46849, 46851, 46832, 
+    46840,     0, 32768, 40960, 45056, 47104, 46592, 46848, 
+    46849, 46851, 46832, 46840,     0, 32768, 40960, 45056, 
+    47104, 46592, 46848, 46849, 46851, 46832, 46840, 46842, 
+        0, 32768, 40960, 45056, 47104, 46592, 46848, 46849, 
+    46851, 46855, 46840,     0, 32768, 40960, 45056, 47104, 
+    46592, 46848, 46849, 46851, 46855, 46840, 46844,     0, 
+    32768, 40960, 45056, 47104, 46592, 46848, 46849, 46851, 
+    46855, 46840, 46844,     0, 32768, 40960, 45056, 47104, 
+    46592, 46848, 46849, 46851, 46855, 46840, 46844, 46846, 
+        0, 32768, 40960, 45056, 47104, 46592,     0, 32768, 
+    40960, 45056, 47104, 46592, 46848,     0, 32768, 40960, 
+    45056, 47104, 47105, 46848,     0, 32768, 40960, 45056, 
+    47104, 47105, 46848, 46850,     0, 32768, 40960, 45056, 
+    47104, 47105, 46848,     0, 32768, 40960, 45056, 47104, 
+    47105, 46848, 46852,     0, 32768, 40960, 45056, 47104, 
+    47105, 46848, 46852,     0, 32768, 40960, 45056, 47104, 
+    47105, 46848, 46856, 46854,     0, 32768, 40960, 45056, 
+    47104, 47105, 46848,     0, 32768, 40960, 45056, 47104, 
+    47105, 46848, 46856,     0, 32768, 40960, 45056, 47104, 
+    47105, 46848, 46856,     0, 32768, 40960, 45056, 47104, 
+    47105, 46848, 46856, 46858,     0, 32768, 40960, 45056, 
+    47104, 47105, 46848, 46856,     0, 32768, 40960, 45056, 
+    47104, 47105, 46848, 46864, 46860,     0, 32768, 40960, 
+    45056, 47104, 47105, 46848, 46864, 46860,     0, 32768, 
+    40960, 45056, 47104, 47105, 46848, 46864, 46865, 46862, 
+        0, 32768, 40960, 45056, 47104, 47105, 46848,     0, 
+    32768, 40960, 45056, 47104, 47105, 46848, 46864,     0, 
+    32768, 40960, 45056, 47104, 47105, 46848, 46864,     0, 
+    32768, 40960, 45056, 47104, 47105, 46848, 46864, 46866, 
+        0, 32768, 40960, 45056, 47104, 47105, 46848, 46864, 
+        0, 32768, 40960, 45056, 47104, 47105, 46848, 46864, 
+    46868,     0, 32768, 40960, 45056, 47104, 47105, 46848, 
+    46864, 46868,     0, 32768, 40960, 45056, 47104, 47105, 
+    46848, 46864, 46872, 46870,     0, 32768, 40960, 45056, 
+    47104, 47105, 46848, 46864,     0, 32768, 40960, 45056, 
+    47104, 47105, 46848, 46880, 46872,     0, 32768, 40960, 
+    45056, 47104, 47105, 46848, 46880, 46872,     0, 32768, 
+    40960, 45056, 47104, 47105, 46848, 46880, 46872, 46874, 
+        0, 32768, 40960, 45056, 47104, 47105, 46848, 46880, 
+    46872,     0, 32768, 40960, 45056, 47104, 47105, 46848, 
+    46880, 46881, 46876,     0, 32768, 40960, 45056, 47104, 
+    47105, 46848, 46880, 46881, 46876,     0, 32768, 40960, 
+    45056, 47104, 47105, 46848, 46880, 46881, 46876, 46878, 
+        0, 32768, 40960, 45056, 47104, 47105, 46848,     0, 
+    32768, 40960, 45056, 47104, 47105, 46848, 46880,     0, 
+    32768, 40960, 45056, 47104, 47105, 46848, 46880,     0, 
+    32768, 40960, 45056, 47104, 47105, 46848, 46880, 46882, 
+        0, 32768, 40960, 45056, 47104, 47105, 46848, 46880, 
+        0, 32768, 40960, 45056, 47104, 47105, 46848, 46880, 
+    46884,     0, 32768, 40960, 45056, 47104, 47105, 46848, 
+    46880, 46884,     0, 32768, 40960, 45056, 47104, 47105, 
+    46848, 46880, 46888, 46886,     0, 32768, 40960, 45056, 
+    47104, 47105, 46848, 46880,     0, 32768, 40960, 45056, 
+    47104, 47105, 46848, 46880, 46888,     0, 32768, 40960, 
+    45056, 47104, 47105, 46848, 46880, 46888,     0, 32768, 
+    40960, 45056, 47104, 47105, 46848, 46880, 46888, 46890, 
+        0, 32768, 40960, 45056, 47104, 47105, 46848, 46880, 
+    46888,     0, 32768, 40960, 45056, 47104, 47105, 46848, 
+    46880, 46896, 46892,     0, 32768, 40960, 45056, 47104, 
+    47105, 46848, 46880, 46896, 46892,     0, 32768, 40960, 
+    45056, 47104, 47105, 46848, 46880, 46896, 46897, 46894, 
+        0, 32768, 40960, 45056, 47104, 47105, 46848, 46880, 
+        0, 32768, 40960, 45056, 47104, 47105, 46848, 46912, 
+    46896,     0, 32768, 40960, 45056, 47104, 47105, 46848, 
+    46912, 46896,     0, 32768, 40960, 45056, 47104, 47105, 
+    46848, 46912, 46896, 46898,     0, 32768, 40960, 45056, 
+    47104, 47105, 46848, 46912, 46896,     0, 32768, 40960, 
+    45056, 47104, 47105, 46848, 46912, 46896, 46900,     0, 
+    32768, 40960, 45056, 47104, 47105, 46848, 46912, 46896, 
+    46900,     0, 32768, 40960, 45056, 47104, 47105, 46848, 
+    46912, 46896, 46904, 46902,     0, 32768, 40960, 45056, 
+    47104, 47105, 46848, 46912, 46896,     0, 32768, 40960, 
+    45056, 47104, 47105, 46848, 46912, 46913, 46904,     0, 
+    32768, 40960, 45056, 47104, 47105, 46848, 46912, 46913, 
+    46904,     0, 32768, 40960, 45056, 47104, 47105, 46848, 
+    46912, 46913, 46904, 46906,     0, 32768, 40960, 45056, 
+    47104, 47105, 46848, 46912, 46913, 46904,     0, 32768, 
+    40960, 45056, 47104, 47105, 46848, 46912, 46913, 46904, 
+    46908,     0, 32768, 40960, 45056, 47104, 47105, 46848, 
+    46912, 46913, 46915, 46908,     0, 32768, 40960, 45056, 
+    47104, 47105, 46848, 46912, 46913, 46915, 46908, 46910, 
+        0, 32768, 40960, 45056, 47104, 47105, 46848,     0, 
+    32768, 40960, 45056, 47104, 47105, 46848, 46912,     0, 
+    32768, 40960, 45056, 47104, 47105, 46848, 46912,     0, 
+    32768, 40960, 45056, 47104, 47105, 46848, 46912, 46914, 
+        0, 32768, 40960, 45056, 47104, 47105, 46848, 46912, 
+        0, 32768, 40960, 45056, 47104, 47105, 46848, 46912, 
+    46916,     0, 32768, 40960, 45056, 47104, 47105, 46848, 
+    46912, 46916,     0, 32768, 40960, 45056, 47104, 47105, 
+    46848, 46912, 46920, 46918,     0, 32768, 40960, 45056, 
+    47104, 47105, 46848, 46912,     0, 32768, 40960, 45056, 
+    47104, 47105, 46848, 46912, 46920,     0, 32768, 40960, 
+    45056, 47104, 47105, 46848, 46912, 46920,     0, 32768, 
+    40960, 45056, 47104, 47105, 46848, 46912, 46920, 46922, 
+        0, 32768, 40960, 45056, 47104, 47105, 46848, 46912, 
+    46920,     0, 32768, 40960, 45056, 47104, 47105, 46848, 
+    46912, 46928, 46924,     0, 32768, 40960, 45056, 47104, 
+    47105, 46848, 46912, 46928, 46924,     0, 32768, 40960, 
+    45056, 47104, 47105, 46848, 46912, 46928, 46929, 46926, 
+        0, 32768, 40960, 45056, 47104, 47105, 46848, 46912, 
+        0, 32768, 40960, 45056, 47104, 47105, 46848, 46912, 
+    46928,     0, 32768, 40960, 45056, 47104, 47105, 46848, 
+    46912, 46928,     0, 32768, 40960, 45056, 47104, 47105, 
+    46848, 46912, 46928, 46930,     0, 32768, 40960, 45056, 
+    47104, 47105, 46848, 46912, 46928,     0, 32768, 40960, 
+    45056, 47104, 47105, 46848, 46912, 46928, 46932,     0, 
+    32768, 40960, 45056, 47104, 47105, 46848, 46912, 46928, 
+    46932,     0, 32768, 40960, 45056, 47104, 47105, 46848, 
+    46912, 46928, 46936, 46934,     0, 32768, 40960, 45056, 
+    47104, 47105, 46848, 46912, 46928,     0, 32768, 40960, 
+    45056, 47104, 47105, 46848, 46912, 46944, 46936,     0, 
+    32768, 40960, 45056, 47104, 47105, 46848, 46912, 46944, 
+    46936,     0, 32768, 40960, 45056, 47104, 47105, 46848, 
+    46912, 46944, 46936, 46938,     0, 32768, 40960, 45056, 
+    47104, 47105, 46848, 46912, 46944, 46936,     0, 32768, 
+    40960, 45056, 47104, 47105, 46848, 46912, 46944, 46945, 
+    46940,     0, 32768, 40960, 45056, 47104, 47105, 46848, 
+    46912, 46944, 46945, 46940,     0, 32768, 40960, 45056, 
+    47104, 47105, 46848, 46912, 46944, 46945, 46940, 46942, 
+        0, 32768, 40960, 45056, 47104, 47105, 46848, 46912, 
+        0, 32768, 40960, 45056, 47104, 47105, 46848, 46976, 
+    46944,     0, 32768, 40960, 45056, 47104, 47105, 46848, 
+    46976, 46944,     0, 32768, 40960, 45056, 47104, 47105, 
+    46848, 46976, 46944, 46946,     0, 32768, 40960, 45056, 
+    47104, 47105, 46848, 46976, 46944,     0, 32768, 40960, 
+    45056, 47104, 47105, 46848, 46976, 46944, 46948,     0, 
+    32768, 40960, 45056, 47104, 47105, 46848, 46976, 46944, 
+    46948,     0, 32768, 40960, 45056, 47104, 47105, 46848, 
+    46976, 46944, 46952, 46950,     0, 32768, 40960, 45056, 
+    47104, 47105, 46848, 46976, 46944,     0, 32768, 40960, 
+    45056, 47104, 47105, 46848, 46976, 46944, 46952,     0, 
+    32768, 40960, 45056, 47104, 47105, 46848, 46976, 46944, 
+    46952,     0, 32768, 40960, 45056, 47104, 47105, 46848, 
+    46976, 46944, 46952, 46954,     0, 32768, 40960, 45056, 
+    47104, 47105, 46848, 46976, 46944, 46952,     0, 32768, 
+    40960, 45056, 47104, 47105, 46848, 46976, 46944, 46960, 
+    46956,     0, 32768, 40960, 45056, 47104, 47105, 46848, 
+    46976, 46944, 46960, 46956,     0, 32768, 40960, 45056, 
+    47104, 47105, 46848, 46976, 46944, 46960, 46961, 46958, 
+        0, 32768, 40960, 45056, 47104, 47105, 46848, 46976, 
+    46944,     0, 32768, 40960, 45056, 47104, 47105, 46848, 
+    46976, 46977, 46960,     0, 32768, 40960, 45056, 47104, 
+    47105, 46848, 46976, 46977, 46960,     0, 32768, 40960, 
+    45056, 47104, 47105, 46848, 46976, 46977, 46960, 46962, 
+        0, 32768, 40960, 45056, 47104, 47105, 46848, 46976, 
+    46977, 46960,     0, 32768, 40960, 45056, 47104, 47105, 
+    46848, 46976, 46977, 46960, 46964,     0, 32768, 40960, 
+    45056, 47104, 47105, 46848, 46976, 46977, 46960, 46964, 
+        0, 32768, 40960, 45056, 47104, 47105, 46848, 46976, 
+    46977, 46960, 46968, 46966,     0, 32768, 40960, 45056, 
+    47104, 47105, 46848, 46976, 46977, 46960,     0, 32768, 
+    40960, 45056, 47104, 47105, 46848, 46976, 46977, 46960, 
+    46968,     0, 32768, 40960, 45056, 47104, 47105, 46848, 
+    46976, 46977, 46979, 46968,     0, 32768, 40960, 45056, 
+    47104, 47105, 46848, 46976, 46977, 46979, 46968, 46970, 
+        0, 32768, 40960, 45056, 47104, 47105, 46848, 46976, 
+    46977, 46979, 46968,     0, 32768, 40960, 45056, 47104, 
+    47105, 46848, 46976, 46977, 46979, 46968, 46972,     0, 
+    32768, 40960, 45056, 47104, 47105, 46848, 46976, 46977, 
+    46979, 46968, 46972,     0, 32768, 40960, 45056, 47104, 
+    47105, 46848, 46976, 46977, 46979, 46968, 46972, 46974, 
+        0, 32768, 40960, 45056, 47104, 47105, 46848,     0, 
+    32768, 40960, 45056, 47104, 47105, 46848, 46976,     0, 
+    32768, 40960, 45056, 47104, 47105, 46848, 46976,     0, 
+    32768, 40960, 45056, 47104, 47105, 46848, 46976, 46978, 
+        0, 32768, 40960, 45056, 47104, 47105, 47107, 46976, 
+        0, 32768, 40960, 45056, 47104, 47105, 47107, 46976, 
+    46980,     0, 32768, 40960, 45056, 47104, 47105, 47107, 
+    46976, 46980,     0, 32768, 40960, 45056, 47104, 47105, 
+    47107, 46976, 46984, 46982,     0, 32768, 40960, 45056, 
+    47104, 47105, 47107, 46976,     0, 32768, 40960, 45056, 
+    47104, 47105, 47107, 46976, 46984,     0, 32768, 40960, 
+    45056, 47104, 47105, 47107, 46976, 46984,     0, 32768, 
+    40960, 45056, 47104, 47105, 47107, 46976, 46984, 46986, 
+        0, 32768, 40960, 45056, 47104, 47105, 47107, 46976, 
+    46984,     0, 32768, 40960, 45056, 47104, 47105, 47107, 
+    46976, 46992, 46988,     0, 32768, 40960, 45056, 47104, 
+    47105, 47107, 46976, 46992, 46988,     0, 32768, 40960, 
+    45056, 47104, 47105, 47107, 46976, 46992, 46993, 46990, 
+        0, 32768, 40960, 45056, 47104, 47105, 47107, 46976, 
+        0, 32768, 40960, 45056, 47104, 47105, 47107, 46976, 
+    46992,     0, 32768, 40960, 45056, 47104, 47105, 47107, 
+    46976, 46992,     0, 32768, 40960, 45056, 47104, 47105, 
+    47107, 46976, 46992, 46994,     0, 32768, 40960, 45056, 
+    47104, 47105, 47107, 46976, 46992,     0, 32768, 40960, 
+    45056, 47104, 47105, 47107, 46976, 46992, 46996,     0, 
+    32768, 40960, 45056, 47104, 47105, 47107, 46976, 46992, 
+    46996,     0, 32768, 40960, 45056, 47104, 47105, 47107, 
+    46976, 46992, 47000, 46998,     0, 32768, 40960, 45056, 
+    47104, 47105, 47107, 46976, 46992,     0, 32768, 40960, 
+    45056, 47104, 47105, 47107, 46976, 47008, 47000,     0, 
+    32768, 40960, 45056, 47104, 47105, 47107, 46976, 47008, 
+    47000,     0, 32768, 40960, 45056, 47104, 47105, 47107, 
+    46976, 47008, 47000, 47002,     0, 32768, 40960, 45056, 
+    47104, 47105, 47107, 46976, 47008, 47000,     0, 32768, 
+    40960, 45056, 47104, 47105, 47107, 46976, 47008, 47009, 
+    47004,     0, 32768, 40960, 45056, 47104, 47105, 47107, 
+    46976, 47008, 47009, 47004,     0, 32768, 40960, 45056, 
+    47104, 47105, 47107, 46976, 47008, 47009, 47004, 47006, 
+        0, 32768, 40960, 45056, 47104, 47105, 47107, 46976, 
+        0, 32768, 40960, 45056, 47104, 47105, 47107, 46976, 
+    47008,     0, 32768, 40960, 45056, 47104, 47105, 47107, 
+    46976, 47008,     0, 32768, 40960, 45056, 47104, 47105, 
+    47107, 46976, 47008, 47010,     0, 32768, 40960, 45056, 
+    47104, 47105, 47107, 46976, 47008,     0, 32768, 40960, 
+    45056, 47104, 47105, 47107, 46976, 47008, 47012,     0, 
+    32768, 40960, 45056, 47104, 47105, 47107, 46976, 47008, 
+    47012,     0, 32768, 40960, 45056, 47104, 47105, 47107, 
+    46976, 47008, 47016, 47014,     0, 32768, 40960, 45056, 
+    47104, 47105, 47107, 46976, 47008,     0, 32768, 40960, 
+    45056, 47104, 47105, 47107, 46976, 47008, 47016,     0, 
+    32768, 40960, 45056, 47104, 47105, 47107, 46976, 47008, 
+    47016,     0, 32768, 40960, 45056, 47104, 47105, 47107, 
+    46976, 47008, 47016, 47018,     0, 32768, 40960, 45056, 
+    47104, 47105, 47107, 46976, 47008, 47016,     0, 32768, 
+    40960, 45056, 47104, 47105, 47107, 46976, 47008, 47024, 
+    47020,     0, 32768, 40960, 45056, 47104, 47105, 47107, 
+    46976, 47008, 47024, 47020,     0, 32768, 40960, 45056, 
+    47104, 47105, 47107, 46976, 47008, 47024, 47025, 47022, 
+        0, 32768, 40960, 45056, 47104, 47105, 47107, 46976, 
+    47008,     0, 32768, 40960, 45056, 47104, 47105, 47107, 
+    46976, 47040, 47024,     0, 32768, 40960, 45056, 47104, 
+    47105, 47107, 46976, 47040, 47024,     0, 32768, 40960, 
+    45056, 47104, 47105, 47107, 46976, 47040, 47024, 47026, 
+        0, 32768, 40960, 45056, 47104, 47105, 47107, 46976, 
+    47040, 47024,     0, 32768, 40960, 45056, 47104, 47105, 
+    47107, 46976, 47040, 47024, 47028,     0, 32768, 40960, 
+    45056, 47104, 47105, 47107, 46976, 47040, 47024, 47028, 
+        0, 32768, 40960, 45056, 47104, 47105, 47107, 46976, 
+    47040, 47024, 47032, 47030,     0, 32768, 40960, 45056, 
+    47104, 47105, 47107, 46976, 47040, 47024,     0, 32768, 
+    40960, 45056, 47104, 47105, 47107, 46976, 47040, 47041, 
+    47032,     0, 32768, 40960, 45056, 47104, 47105, 47107, 
+    46976, 47040, 47041, 47032,     0, 32768, 40960, 45056, 
+    47104, 47105, 47107, 46976, 47040, 47041, 47032, 47034, 
+        0, 32768, 40960, 45056, 47104, 47105, 47107, 46976, 
+    47040, 47041, 47032,     0, 32768, 40960, 45056, 47104, 
+    47105, 47107, 46976, 47040, 47041, 47032, 47036,     0, 
+    32768, 40960, 45056, 47104, 47105, 47107, 46976, 47040, 
+    47041, 47043, 47036,     0, 32768, 40960, 45056, 47104, 
+    47105, 47107, 46976, 47040, 47041, 47043, 47036, 47038, 
+        0, 32768, 40960, 45056, 47104, 47105, 47107, 46976, 
+        0, 32768, 40960, 45056, 47104, 47105, 47107, 46976, 
+    47040,     0, 32768, 40960, 45056, 47104, 47105, 47107, 
+    46976, 47040,     0, 32768, 40960, 45056, 47104, 47105, 
+    47107, 46976, 47040, 47042,     0, 32768, 40960, 45056, 
+    47104, 47105, 47107, 46976, 47040,     0, 32768, 40960, 
+    45056, 47104, 47105, 47107, 46976, 47040, 47044,     0, 
+    32768, 40960, 45056, 47104, 47105, 47107, 46976, 47040, 
+    47044,     0, 32768, 40960, 45056, 47104, 47105, 47107, 
+    46976, 47040, 47048, 47046,     0, 32768, 40960, 45056, 
+    47104, 47105, 47107, 47111, 47040,     0, 32768, 40960, 
+    45056, 47104, 47105, 47107, 47111, 47040, 47048,     0, 
+    32768, 40960, 45056, 47104, 47105, 47107, 47111, 47040, 
+    47048,     0, 32768, 40960, 45056, 47104, 47105, 47107, 
+    47111, 47040, 47048, 47050,     0, 32768, 40960, 45056, 
+    47104, 47105, 47107, 47111, 47040, 47048,     0, 32768, 
+    40960, 45056, 47104, 47105, 47107, 47111, 47040, 47056, 
+    47052,     0, 32768, 40960, 45056, 47104, 47105, 47107, 
+    47111, 47040, 47056, 47052,     0, 32768, 40960, 45056, 
+    47104, 47105, 47107, 47111, 47040, 47056, 47057, 47054, 
+        0, 32768, 40960, 45056, 47104, 47105, 47107, 47111, 
+    47040,     0, 32768, 40960, 45056, 47104, 47105, 47107, 
+    47111, 47040, 47056,     0, 32768, 40960, 45056, 47104, 
+    47105, 47107, 47111, 47040, 47056,     0, 32768, 40960, 
+    45056, 47104, 47105, 47107, 47111, 47040, 47056, 47058, 
+        0, 32768, 40960, 45056, 47104, 47105, 47107, 47111, 
+    47040, 47056,     0, 32768, 40960, 45056, 47104, 47105, 
+    47107, 47111, 47040, 47056, 47060,     0, 32768, 40960, 
+    45056, 47104, 47105, 47107, 47111, 47040, 47056, 47060, 
+        0, 32768, 40960, 45056, 47104, 47105, 47107, 47111, 
+    47040, 47056, 47064, 47062,     0, 32768, 40960, 45056, 
+    47104, 47105, 47107, 47111, 47040, 47056,     0, 32768, 
+    40960, 45056, 47104, 47105, 47107, 47111, 47040, 47072, 
+    47064,     0, 32768, 40960, 45056, 47104, 47105, 47107, 
+    47111, 47040, 47072, 47064,     0, 32768, 40960, 45056, 
+    47104, 47105, 47107, 47111, 47040, 47072, 47064, 47066, 
+        0, 32768, 40960, 45056, 47104, 47105, 47107, 47111, 
+    47040, 47072, 47064,     0, 32768, 40960, 45056, 47104, 
+    47105, 47107, 47111, 47040, 47072, 47073, 47068,     0, 
+    32768, 40960, 45056, 47104, 47105, 47107, 47111, 47040, 
+    47072, 47073, 47068,     0, 32768, 40960, 45056, 47104, 
+    47105, 47107, 47111, 47040, 47072, 47073, 47068, 47070, 
+        0, 32768, 40960, 45056, 47104, 47105, 47107, 47111, 
+    47040,     0, 32768, 40960, 45056, 47104, 47105, 47107, 
+    47111, 47040, 47072,     0, 32768, 40960, 45056, 47104, 
+    47105, 47107, 47111, 47040, 47072,     0, 32768, 40960, 
+    45056, 47104, 47105, 47107, 47111, 47040, 47072, 47074, 
+        0, 32768, 40960, 45056, 47104, 47105, 47107, 47111, 
+    47040, 47072,     0, 32768, 40960, 45056, 47104, 47105, 
+    47107, 47111, 47040, 47072, 47076,     0, 32768, 40960, 
+    45056, 47104, 47105, 47107, 47111, 47040, 47072, 47076, 
+        0, 32768, 40960, 45056, 47104, 47105, 47107, 47111, 
+    47040, 47072, 47080, 47078,     0, 32768, 40960, 45056, 
+    47104, 47105, 47107, 47111, 47040, 47072,     0, 32768, 
+    40960, 45056, 47104, 47105, 47107, 47111, 47040, 47072, 
+    47080,     0, 32768, 40960, 45056, 47104, 47105, 47107, 
+    47111, 47040, 47072, 47080,     0, 32768, 40960, 45056, 
+    47104, 47105, 47107, 47111, 47040, 47072, 47080, 47082, 
+        0, 32768, 40960, 45056, 47104, 47105, 47107, 47111, 
+    47040, 47072, 47080,     0, 32768, 40960, 45056, 47104, 
+    47105, 47107, 47111, 47040, 47072, 47088, 47084,     0, 
+    32768, 40960, 45056, 47104, 47105, 47107, 47111, 47040, 
+    47072, 47088, 47084,     0, 32768, 40960, 45056, 47104, 
+    47105, 47107, 47111, 47040, 47072, 47088, 47089, 47086, 
+        0, 32768, 40960, 45056, 47104, 47105, 47107, 47111, 
+    47119, 47072,     0, 32768, 40960, 45056, 47104, 47105, 
+    47107, 47111, 47119, 47072, 47088,     0, 32768, 40960, 
+    45056, 47104, 47105, 47107, 47111, 47119, 47072, 47088, 
+        0, 32768, 40960, 45056, 47104, 47105, 47107, 47111, 
+    47119, 47072, 47088, 47090,     0, 32768, 40960, 45056, 
+    47104, 47105, 47107, 47111, 47119, 47072, 47088,     0, 
+    32768, 40960, 45056, 47104, 47105, 47107, 47111, 47119, 
+    47072, 47088, 47092,     0, 32768, 40960, 45056, 47104, 
+    47105, 47107, 47111, 47119, 47072, 47088, 47092,     0, 
+    32768, 40960, 45056, 47104, 47105, 47107, 47111, 47119, 
+    47072, 47088, 47096, 47094,     0, 32768, 40960, 45056, 
+    47104, 47105, 47107, 47111, 47119, 47072, 47088,     0, 
+    32768, 40960, 45056, 47104, 47105, 47107, 47111, 47119, 
+    47072, 47088, 47096,     0, 32768, 40960, 45056, 47104, 
+    47105, 47107, 47111, 47119, 47072, 47088, 47096,     0, 
+    32768, 40960, 45056, 47104, 47105, 47107, 47111, 47119, 
+    47072, 47088, 47096, 47098,     0, 32768, 40960, 45056, 
+    47104, 47105, 47107, 47111, 47119, 47072, 47088, 47096, 
+        0, 32768, 40960, 45056, 47104, 47105, 47107, 47111, 
+    47119, 47072, 47088, 47096, 47100,     0, 32768, 40960, 
+    45056, 47104, 47105, 47107, 47111, 47119, 47072, 47088, 
+    47096, 47100,     0, 32768, 40960, 45056, 47104, 47105, 
+    47107, 47111, 47119, 47072, 47088, 47096, 47100, 47102, 
+        0, 32768, 40960, 45056,     0, 32768, 40960, 45056, 
+    47104,     0, 32768, 40960, 45056, 47104,     0, 32768, 
+    40960, 45056, 47104, 47106,     0, 32768, 40960, 45056, 
+    47104,     0, 32768, 40960, 45056, 47104, 47108,     0, 
+    32768, 40960, 45056, 47104, 47108,     0, 32768, 40960, 
+    45056, 47104, 47112, 47110,     0, 32768, 40960, 45056, 
+    47104,     0, 32768, 40960, 45056, 47104, 47112,     0, 
+    32768, 40960, 45056, 47104, 47112,     0, 32768, 40960, 
+    45056, 47104, 47112, 47114,     0, 32768, 40960, 45056, 
+    47104, 47112,     0, 32768, 40960, 45056, 47104, 47120, 
+    47116,     0, 32768, 40960, 45056, 47104, 47120, 47116, 
+        0, 32768, 40960, 45056, 47104, 47120, 47121, 47118, 
+        0, 32768, 40960, 45056, 47104,     0, 32768, 40960, 
+    45056, 47104, 47120,     0, 32768, 40960, 45056, 47104, 
+    47120,     0, 32768, 40960, 45056, 47104, 47120, 47122, 
+        0, 32768, 40960, 45056, 47104, 47120,     0, 32768, 
+    40960, 45056, 47104, 47120, 47124,     0, 32768, 40960, 
+    45056, 47104, 47120, 47124,     0, 32768, 40960, 45056, 
+    47104, 47120, 47128, 47126,     0, 32768, 40960, 45056, 
+    47104, 47120,     0, 32768, 40960, 45056, 47104, 47136, 
+    47128,     0, 32768, 40960, 45056, 47104, 47136, 47128, 
+        0, 32768, 40960, 45056, 47104, 47136, 47128, 47130, 
+        0, 32768, 40960, 45056, 47104, 47136, 47128,     0, 
+    32768, 40960, 45056, 47104, 47136, 47137, 47132,     0, 
+    32768, 40960, 45056, 47104, 47136, 47137, 47132,     0, 
+    32768, 40960, 45056, 47104, 47136, 47137, 47132, 47134, 
+        0, 32768, 40960, 45056, 47104,     0, 32768, 40960, 
+    45056, 47104, 47136,     0, 32768, 40960, 45056, 47104, 
+    47136,     0, 32768, 40960, 45056, 47104, 47136, 47138, 
+        0, 32768, 40960, 45056, 47104, 47136,     0, 32768, 
+    40960, 45056, 47104, 47136, 47140,     0, 32768, 40960, 
+    45056, 47104, 47136, 47140,     0, 32768, 40960, 45056, 
+    47104, 47136, 47144, 47142,     0, 32768, 40960, 45056, 
+    47104, 47136,     0, 32768, 40960, 45056, 47104, 47136, 
+    47144,     0, 32768, 40960, 45056, 47104, 47136, 47144, 
+        0, 32768, 40960, 45056, 47104, 47136, 47144, 47146, 
+        0, 32768, 40960, 45056, 47104, 47136, 47144,     0, 
+    32768, 40960, 45056, 47104, 47136, 47152, 47148,     0, 
+    32768, 40960, 45056, 47104, 47136, 47152, 47148,     0, 
+    32768, 40960, 45056, 47104, 47136, 47152, 47153, 47150, 
+        0, 32768, 40960, 45056, 47104, 47136,     0, 32768, 
+    40960, 45056, 47104, 47168, 47152,     0, 32768, 40960, 
+    45056, 47104, 47168, 47152,     0, 32768, 40960, 45056, 
+    47104, 47168, 47152, 47154,     0, 32768, 40960, 45056, 
+    47104, 47168, 47152,     0, 32768, 40960, 45056, 47104, 
+    47168, 47152, 47156,     0, 32768, 40960, 45056, 47104, 
+    47168, 47152, 47156,     0, 32768, 40960, 45056, 47104, 
+    47168, 47152, 47160, 47158,     0, 32768, 40960, 45056, 
+    47104, 47168, 47152,     0, 32768, 40960, 45056, 47104, 
+    47168, 47169, 47160,     0, 32768, 40960, 45056, 47104, 
+    47168, 47169, 47160,     0, 32768, 40960, 45056, 47104, 
+    47168, 47169, 47160, 47162,     0, 32768, 40960, 45056, 
+    47104, 47168, 47169, 47160,     0, 32768, 40960, 45056, 
+    47104, 47168, 47169, 47160, 47164,     0, 32768, 40960, 
+    45056, 47104, 47168, 47169, 47171, 47164,     0, 32768, 
+    40960, 45056, 47104, 47168, 47169, 47171, 47164, 47166, 
+        0, 32768, 40960, 45056, 47104,     0, 32768, 40960, 
+    45056, 47104, 47168,     0, 32768, 40960, 45056, 47104, 
+    47168,     0, 32768, 40960, 45056, 47104, 47168, 47170, 
+        0, 32768, 40960, 45056, 47104, 47168,     0, 32768, 
+    40960, 45056, 47104, 47168, 47172,     0, 32768, 40960, 
+    45056, 47104, 47168, 47172,     0, 32768, 40960, 45056, 
+    47104, 47168, 47176, 47174,     0, 32768, 40960, 45056, 
+    47104, 47168,     0, 32768, 40960, 45056, 47104, 47168, 
+    47176,     0, 32768, 40960, 45056, 47104, 47168, 47176, 
+        0, 32768, 40960, 45056, 47104, 47168, 47176, 47178, 
+        0, 32768, 40960, 45056, 47104, 47168, 47176,     0, 
+    32768, 40960, 45056, 47104, 47168, 47184, 47180,     0, 
+    32768, 40960, 45056, 47104, 47168, 47184, 47180,     0, 
+    32768, 40960, 45056, 47104, 47168, 47184, 47185, 47182, 
+        0, 32768, 40960, 45056, 47104, 47168,     0, 32768, 
+    40960, 45056, 47104, 47168, 47184,     0, 32768, 40960, 
+    45056, 47104, 47168, 47184,     0, 32768, 40960, 45056, 
+    47104, 47168, 47184, 47186,     0, 32768, 40960, 45056, 
+    47104, 47168, 47184,     0, 32768, 40960, 45056, 47104, 
+    47168, 47184, 47188,     0, 32768, 40960, 45056, 47104, 
+    47168, 47184, 47188,     0, 32768, 40960, 45056, 47104, 
+    47168, 47184, 47192, 47190,     0, 32768, 40960, 45056, 
+    47104, 47168, 47184,     0, 32768, 40960, 45056, 47104, 
+    47168, 47200, 47192,     0, 32768, 40960, 45056, 47104, 
+    47168, 47200, 47192,     0, 32768, 40960, 45056, 47104, 
+    47168, 47200, 47192, 47194,     0, 32768, 40960, 45056, 
+    47104, 47168, 47200, 47192,     0, 32768, 40960, 45056, 
+    47104, 47168, 47200, 47201, 47196,     0, 32768, 40960, 
+    45056, 47104, 47168, 47200, 47201, 47196,     0, 32768, 
+    40960, 45056, 47104, 47168, 47200, 47201, 47196, 47198, 
+        0, 32768, 40960, 45056, 47104, 47168,     0, 32768, 
+    40960, 45056, 47104, 47232, 47200,     0, 32768, 40960, 
+    45056, 47104, 47232, 47200,     0, 32768, 40960, 45056, 
+    47104, 47232, 47200, 47202,     0, 32768, 40960, 45056, 
+    47104, 47232, 47200,     0, 32768, 40960, 45056, 47104, 
+    47232, 47200, 47204,     0, 32768, 40960, 45056, 47104, 
+    47232, 47200, 47204,     0, 32768, 40960, 45056, 47104, 
+    47232, 47200, 47208, 47206,     0, 32768, 40960, 45056, 
+    47104, 47232, 47200,     0, 32768, 40960, 45056, 47104, 
+    47232, 47200, 47208,     0, 32768, 40960, 45056, 47104, 
+    47232, 47200, 47208,     0, 32768, 40960, 45056, 47104, 
+    47232, 47200, 47208, 47210,     0, 32768, 40960, 45056, 
+    47104, 47232, 47200, 47208,     0, 32768, 40960, 45056, 
+    47104, 47232, 47200, 47216, 47212,     0, 32768, 40960, 
+    45056, 47104, 47232, 47200, 47216, 47212,     0, 32768, 
+    40960, 45056, 47104, 47232, 47200, 47216, 47217, 47214, 
+        0, 32768, 40960, 45056, 47104, 47232, 47200,     0, 
+    32768, 40960, 45056, 47104, 47232, 47233, 47216,     0, 
+    32768, 40960, 45056, 47104, 47232, 47233, 47216,     0, 
+    32768, 40960, 45056, 47104, 47232, 47233, 47216, 47218, 
+        0, 32768, 40960, 45056, 47104, 47232, 47233, 47216, 
+        0, 32768, 40960, 45056, 47104, 47232, 47233, 47216, 
+    47220,     0, 32768, 40960, 45056, 47104, 47232, 47233, 
+    47216, 47220,     0, 32768, 40960, 45056, 47104, 47232, 
+    47233, 47216, 47224, 47222,     0, 32768, 40960, 45056, 
+    47104, 47232, 47233, 47216,     0, 32768, 40960, 45056, 
+    47104, 47232, 47233, 47216, 47224,     0, 32768, 40960, 
+    45056, 47104, 47232, 47233, 47235, 47224,     0, 32768, 
+    40960, 45056, 47104, 47232, 47233, 47235, 47224, 47226, 
+        0, 32768, 40960, 45056, 47104, 47232, 47233, 47235, 
+    47224,     0, 32768, 40960, 45056, 47104, 47232, 47233, 
+    47235, 47224, 47228,     0, 32768, 40960, 45056, 47104, 
+    47232, 47233, 47235, 47224, 47228,     0, 32768, 40960, 
+    45056, 47104, 47232, 47233, 47235, 47224, 47228, 47230, 
+        0, 32768, 40960, 45056, 47104,     0, 32768, 40960, 
+    45056, 47104, 47232,     0, 32768, 40960, 45056, 47104, 
+    47232,     0, 32768, 40960, 45056, 47104, 47232, 47234, 
+        0, 32768, 40960, 45056, 47104, 47232,     0, 32768, 
+    40960, 45056, 47104, 47232, 47236,     0, 32768, 40960, 
+    45056, 47104, 47232, 47236,     0, 32768, 40960, 45056, 
+    47104, 47232, 47240, 47238,     0, 32768, 40960, 45056, 
+    47104, 47232,     0, 32768, 40960, 45056, 47104, 47232, 
+    47240,     0, 32768, 40960, 45056, 47104, 47232, 47240, 
+        0, 32768, 40960, 45056, 47104, 47232, 47240, 47242, 
+        0, 32768, 40960, 45056, 47104, 47232, 47240,     0, 
+    32768, 40960, 45056, 47104, 47232, 47248, 47244,     0, 
+    32768, 40960, 45056, 47104, 47232, 47248, 47244,     0, 
+    32768, 40960, 45056, 47104, 47232, 47248, 47249, 47246, 
+        0, 32768, 40960, 45056, 47104, 47232,     0, 32768, 
+    40960, 45056, 47104, 47232, 47248,     0, 32768, 40960, 
+    45056, 47104, 47232, 47248,     0, 32768, 40960, 45056, 
+    47104, 47232, 47248, 47250,     0, 32768, 40960, 45056, 
+    47104, 47232, 47248,     0, 32768, 40960, 45056, 47104, 
+    47232, 47248, 47252,     0, 32768, 40960, 45056, 47104, 
+    47232, 47248, 47252,     0, 32768, 40960, 45056, 47104, 
+    47232, 47248, 47256, 47254,     0, 32768, 40960, 45056, 
+    47104, 47232, 47248,     0, 32768, 40960, 45056, 47104, 
+    47232, 47264, 47256,     0, 32768, 40960, 45056, 47104, 
+    47232, 47264, 47256,     0, 32768, 40960, 45056, 47104, 
+    47232, 47264, 47256, 47258,     0, 32768, 40960, 45056, 
+    47104, 47232, 47264, 47256,     0, 32768, 40960, 45056, 
+    47104, 47232, 47264, 47265, 47260,     0, 32768, 40960, 
+    45056, 47104, 47232, 47264, 47265, 47260,     0, 32768, 
+    40960, 45056, 47104, 47232, 47264, 47265, 47260, 47262, 
+        0, 32768, 40960, 45056, 47104, 47232,     0, 32768, 
+    40960, 45056, 47104, 47232, 47264,     0, 32768, 40960, 
+    45056, 47104, 47232, 47264,     0, 32768, 40960, 45056, 
+    47104, 47232, 47264, 47266,     0, 32768, 40960, 45056, 
+    47104, 47232, 47264,     0, 32768, 40960, 45056, 47104, 
+    47232, 47264, 47268,     0, 32768, 40960, 45056, 47104, 
+    47232, 47264, 47268,     0, 32768, 40960, 45056, 47104, 
+    47232, 47264, 47272, 47270,     0, 32768, 40960, 45056, 
+    47104, 47232, 47264,     0, 32768, 40960, 45056, 47104, 
+    47232, 47264, 47272,     0, 32768, 40960, 45056, 47104, 
+    47232, 47264, 47272,     0, 32768, 40960, 45056, 47104, 
+    47232, 47264, 47272, 47274,     0, 32768, 40960, 45056, 
+    47104, 47232, 47264, 47272,     0, 32768, 40960, 45056, 
+    47104, 47232, 47264, 47280, 47276,     0, 32768, 40960, 
+    45056, 47104, 47232, 47264, 47280, 47276,     0, 32768, 
+    40960, 45056, 47104, 47232, 47264, 47280, 47281, 47278, 
+        0, 32768, 40960, 45056, 47104, 47232, 47264,     0, 
+    32768, 40960, 45056, 47104, 47232, 47296, 47280,     0, 
+    32768, 40960, 45056, 47104, 47232, 47296, 47280,     0, 
+    32768, 40960, 45056, 47104, 47232, 47296, 47280, 47282, 
+        0, 32768, 40960, 45056, 47104, 47232, 47296, 47280, 
+        0, 32768, 40960, 45056, 47104, 47232, 47296, 47280, 
+    47284,     0, 32768, 40960, 45056, 47104, 47232, 47296, 
+    47280, 47284,     0, 32768, 40960, 45056, 47104, 47232, 
+    47296, 47280, 47288, 47286,     0, 32768, 40960, 45056, 
+    47104, 47232, 47296, 47280,     0, 32768, 40960, 45056, 
+    47104, 47232, 47296, 47297, 47288,     0, 32768, 40960, 
+    45056, 47104, 47232, 47296, 47297, 47288,     0, 32768, 
+    40960, 45056, 47104, 47232, 47296, 47297, 47288, 47290, 
+        0, 32768, 40960, 45056, 47104, 47232, 47296, 47297, 
+    47288,     0, 32768, 40960, 45056, 47104, 47232, 47296, 
+    47297, 47288, 47292,     0, 32768, 40960, 45056, 47104, 
+    47232, 47296, 47297, 47299, 47292,     0, 32768, 40960, 
+    45056, 47104, 47232, 47296, 47297, 47299, 47292, 47294, 
+        0, 32768, 40960, 45056, 47104, 47232,     0, 32768, 
+    40960, 45056, 47104, 47360, 47296,     0, 32768, 40960, 
+    45056, 47104, 47360, 47296,     0, 32768, 40960, 45056, 
+    47104, 47360, 47296, 47298,     0, 32768, 40960, 45056, 
+    47104, 47360, 47296,     0, 32768, 40960, 45056, 47104, 
+    47360, 47296, 47300,     0, 32768, 40960, 45056, 47104, 
+    47360, 47296, 47300,     0, 32768, 40960, 45056, 47104, 
+    47360, 47296, 47304, 47302,     0, 32768, 40960, 45056, 
+    47104, 47360, 47296,     0, 32768, 40960, 45056, 47104, 
+    47360, 47296, 47304,     0, 32768, 40960, 45056, 47104, 
+    47360, 47296, 47304,     0, 32768, 40960, 45056, 47104, 
+    47360, 47296, 47304, 47306,     0, 32768, 40960, 45056, 
+    47104, 47360, 47296, 47304,     0, 32768, 40960, 45056, 
+    47104, 47360, 47296, 47312, 47308,     0, 32768, 40960, 
+    45056, 47104, 47360, 47296, 47312, 47308,     0, 32768, 
+    40960, 45056, 47104, 47360, 47296, 47312, 47313, 47310, 
+        0, 32768, 40960, 45056, 47104, 47360, 47296,     0, 
+    32768, 40960, 45056, 47104, 47360, 47296, 47312,     0, 
+    32768, 40960, 45056, 47104, 47360, 47296, 47312,     0, 
+    32768, 40960, 45056, 47104, 47360, 47296, 47312, 47314, 
+        0, 32768, 40960, 45056, 47104, 47360, 47296, 47312, 
+        0, 32768, 40960, 45056, 47104, 47360, 47296, 47312, 
+    47316,     0, 32768, 40960, 45056, 47104, 47360, 47296, 
+    47312, 47316,     0, 32768, 40960, 45056, 47104, 47360, 
+    47296, 47312, 47320, 47318,     0, 32768, 40960, 45056, 
+    47104, 47360, 47296, 47312,     0, 32768, 40960, 45056, 
+    47104, 47360, 47296, 47328, 47320,     0, 32768, 40960, 
+    45056, 47104, 47360, 47296, 47328, 47320,     0, 32768, 
+    40960, 45056, 47104, 47360, 47296, 47328, 47320, 47322, 
+        0, 32768, 40960, 45056, 47104, 47360, 47296, 47328, 
+    47320,     0, 32768, 40960, 45056, 47104, 47360, 47296, 
+    47328, 47329, 47324,     0, 32768, 40960, 45056, 47104, 
+    47360, 47296, 47328, 47329, 47324,     0, 32768, 40960, 
+    45056, 47104, 47360, 47296, 47328, 47329, 47324, 47326, 
+        0, 32768, 40960, 45056, 47104, 47360, 47296,     0, 
+    32768, 40960, 45056, 47104, 47360, 47361, 47328,     0, 
+    32768, 40960, 45056, 47104, 47360, 47361, 47328,     0, 
+    32768, 40960, 45056, 47104, 47360, 47361, 47328, 47330, 
+        0, 32768, 40960, 45056, 47104, 47360, 47361, 47328, 
+        0, 32768, 40960, 45056, 47104, 47360, 47361, 47328, 
+    47332,     0, 32768, 40960, 45056, 47104, 47360, 47361, 
+    47328, 47332,     0, 32768, 40960, 45056, 47104, 47360, 
+    47361, 47328, 47336, 47334,     0, 32768, 40960, 45056, 
+    47104, 47360, 47361, 47328,     0, 32768, 40960, 45056, 
+    47104, 47360, 47361, 47328, 47336,     0, 32768, 40960, 
+    45056, 47104, 47360, 47361, 47328, 47336,     0, 32768, 
+    40960, 45056, 47104, 47360, 47361, 47328, 47336, 47338, 
+        0, 32768, 40960, 45056, 47104, 47360, 47361, 47328, 
+    47336,     0, 32768, 40960, 45056, 47104, 47360, 47361, 
+    47328, 47344, 47340,     0, 32768, 40960, 45056, 47104, 
+    47360, 47361, 47328, 47344, 47340,     0, 32768, 40960, 
+    45056, 47104, 47360, 47361, 47328, 47344, 47345, 47342, 
+        0, 32768, 40960, 45056, 47104, 47360, 47361, 47328, 
+        0, 32768, 40960, 45056, 47104, 47360, 47361, 47328, 
+    47344,     0, 32768, 40960, 45056, 47104, 47360, 47361, 
+    47363, 47344,     0, 32768, 40960, 45056, 47104, 47360, 
+    47361, 47363, 47344, 47346,     0, 32768, 40960, 45056, 
+    47104, 47360, 47361, 47363, 47344,     0, 32768, 40960, 
+    45056, 47104, 47360, 47361, 47363, 47344, 47348,     0, 
+    32768, 40960, 45056, 47104, 47360, 47361, 47363, 47344, 
+    47348,     0, 32768, 40960, 45056, 47104, 47360, 47361, 
+    47363, 47344, 47352, 47350,     0, 32768, 40960, 45056, 
+    47104, 47360, 47361, 47363, 47344,     0, 32768, 40960, 
+    45056, 47104, 47360, 47361, 47363, 47344, 47352,     0, 
+    32768, 40960, 45056, 47104, 47360, 47361, 47363, 47344, 
+    47352,     0, 32768, 40960, 45056, 47104, 47360, 47361, 
+    47363, 47344, 47352, 47354,     0, 32768, 40960, 45056, 
+    47104, 47360, 47361, 47363, 47367, 47352,     0, 32768, 
+    40960, 45056, 47104, 47360, 47361, 47363, 47367, 47352, 
+    47356,     0, 32768, 40960, 45056, 47104, 47360, 47361, 
+    47363, 47367, 47352, 47356,     0, 32768, 40960, 45056, 
+    47104, 47360, 47361, 47363, 47367, 47352, 47356, 47358, 
+        0, 32768, 40960, 45056, 47104,     0, 32768, 40960, 
+    45056, 47104, 47360,     0, 32768, 40960, 45056, 47104, 
+    47360,     0, 32768, 40960, 45056, 47104, 47360, 47362, 
+        0, 32768, 40960, 45056, 47104, 47360,     0, 32768, 
+    40960, 45056, 47104, 47360, 47364,     0, 32768, 40960, 
+    45056, 47104, 47360, 47364,     0, 32768, 40960, 45056, 
+    47104, 47360, 47368, 47366,     0, 32768, 40960, 45056, 
+    47104, 47360,     0, 32768, 40960, 45056, 47104, 47360, 
+    47368,     0, 32768, 40960, 45056, 47104, 47360, 47368, 
+        0, 32768, 40960, 45056, 47104, 47360, 47368, 47370, 
+        0, 32768, 40960, 45056, 47104, 47360, 47368,     0, 
+    32768, 40960, 45056, 47104, 47360, 47376, 47372,     0, 
+    32768, 40960, 45056, 47104, 47360, 47376, 47372,     0, 
+    32768, 40960, 45056, 47104, 47360, 47376, 47377, 47374, 
+        0, 32768, 40960, 45056, 47104, 47360,     0, 32768, 
+    40960, 45056, 47104, 47360, 47376,     0, 32768, 40960, 
+    45056, 47104, 47360, 47376,     0, 32768, 40960, 45056, 
+    47104, 47360, 47376, 47378,     0, 32768, 40960, 45056, 
+    47104, 47360, 47376,     0, 32768, 40960, 45056, 47104, 
+    47360, 47376, 47380,     0, 32768, 40960, 45056, 47104, 
+    47360, 47376, 47380,     0, 32768, 40960, 45056, 47104, 
+    47360, 47376, 47384, 47382,     0, 32768, 40960, 45056, 
+    47104, 47360, 47376,     0, 32768, 40960, 45056, 47104, 
+    47360, 47392, 47384,     0, 32768, 40960, 45056, 47104, 
+    47360, 47392, 47384,     0, 32768, 40960, 45056, 47104, 
+    47360, 47392, 47384, 47386,     0, 32768, 40960, 45056, 
+    47104, 47360, 47392, 47384,     0, 32768, 40960, 45056, 
+    47104, 47360, 47392, 47393, 47388,     0, 32768, 40960, 
+    45056, 47104, 47360, 47392, 47393, 47388,     0, 32768, 
+    40960, 45056, 47104, 47360, 47392, 47393, 47388, 47390, 
+        0, 32768, 40960, 45056, 47104, 47360,     0, 32768, 
+    40960, 45056, 47104, 47360, 47392,     0, 32768, 40960, 
+    45056, 47104, 47360, 47392,     0, 32768, 40960, 45056, 
+    47104, 47360, 47392, 47394,     0, 32768, 40960, 45056, 
+    47104, 47360, 47392,     0, 32768, 40960, 45056, 47104, 
+    47360, 47392, 47396,     0, 32768, 40960, 45056, 47104, 
+    47360, 47392, 47396,     0, 32768, 40960, 45056, 47104, 
+    47360, 47392, 47400, 47398,     0, 32768, 40960, 45056, 
+    47104, 47360, 47392,     0, 32768, 40960, 45056, 47104, 
+    47360, 47392, 47400,     0, 32768, 40960, 45056, 47104, 
+    47360, 47392, 47400,     0, 32768, 40960, 45056, 47104, 
+    47360, 47392, 47400, 47402,     0, 32768, 40960, 45056, 
+    47104, 47360, 47392, 47400,     0, 32768, 40960, 45056, 
+    47104, 47360, 47392, 47408, 47404,     0, 32768, 40960, 
+    45056, 47104, 47360, 47392, 47408, 47404,     0, 32768, 
+    40960, 45056, 47104, 47360, 47392, 47408, 47409, 47406, 
+        0, 32768, 40960, 45056, 47104, 47360, 47392,     0, 
+    32768, 40960, 45056, 47104, 47360, 47424, 47408,     0, 
+    32768, 40960, 45056, 47104, 47360, 47424, 47408,     0, 
+    32768, 40960, 45056, 47104, 47360, 47424, 47408, 47410, 
+        0, 32768, 40960, 45056, 47104, 47360, 47424, 47408, 
+        0, 32768, 40960, 45056, 47104, 47360, 47424, 47408, 
+    47412,     0, 32768, 40960, 45056, 47104, 47360, 47424, 
+    47408, 47412,     0, 32768, 40960, 45056, 47104, 47360, 
+    47424, 47408, 47416, 47414,     0, 32768, 40960, 45056, 
+    47104, 47360, 47424, 47408,     0, 32768, 40960, 45056, 
+    47104, 47360, 47424, 47425, 47416,     0, 32768, 40960, 
+    45056, 47104, 47360, 47424, 47425, 47416,     0, 32768, 
+    40960, 45056, 47104, 47360, 47424, 47425, 47416, 47418, 
+        0, 32768, 40960, 45056, 47104, 47360, 47424, 47425, 
+    47416,     0, 32768, 40960, 45056, 47104, 47360, 47424, 
+    47425, 47416, 47420,     0, 32768, 40960, 45056, 47104, 
+    47360, 47424, 47425, 47427, 47420,     0, 32768, 40960, 
+    45056, 47104, 47360, 47424, 47425, 47427, 47420, 47422, 
+        0, 32768, 40960, 45056, 47104, 47360,     0, 32768, 
+    40960, 45056, 47104, 47360, 47424,     0, 32768, 40960, 
+    45056, 47104, 47360, 47424,     0, 32768, 40960, 45056, 
+    47104, 47360, 47424, 47426,     0, 32768, 40960, 45056, 
+    47104, 47360, 47424,     0, 32768, 40960, 45056, 47104, 
+    47360, 47424, 47428,     0, 32768, 40960, 45056, 47104, 
+    47360, 47424, 47428,     0, 32768, 40960, 45056, 47104, 
+    47360, 47424, 47432, 47430,     0, 32768, 40960, 45056, 
+    47104, 47360, 47424,     0, 32768, 40960, 45056, 47104, 
+    47360, 47424, 47432,     0, 32768, 40960, 45056, 47104, 
+    47360, 47424, 47432,     0, 32768, 40960, 45056, 47104, 
+    47360, 47424, 47432, 47434,     0, 32768, 40960, 45056, 
+    47104, 47360, 47424, 47432,     0, 32768, 40960, 45056, 
+    47104, 47360, 47424, 47440, 47436,     0, 32768, 40960, 
+    45056, 47104, 47360, 47424, 47440, 47436,     0, 32768, 
+    40960, 45056, 47104, 47360, 47424, 47440, 47441, 47438, 
+        0, 32768, 40960, 45056, 47104, 47360, 47424,     0, 
+    32768, 40960, 45056, 47104, 47360, 47424, 47440,     0, 
+    32768, 40960, 45056, 47104, 47360, 47424, 47440,     0, 
+    32768, 40960, 45056, 47104, 47360, 47424, 47440, 47442, 
+        0, 32768, 40960, 45056, 47104, 47360, 47424, 47440, 
+        0, 32768, 40960, 45056, 47104, 47360, 47424, 47440, 
+    47444,     0, 32768, 40960, 45056, 47104, 47360, 47424, 
+    47440, 47444,     0, 32768, 40960, 45056, 47104, 47360, 
+    47424, 47440, 47448, 47446,     0, 32768, 40960, 45056, 
+    47104, 47360, 47424, 47440,     0, 32768, 40960, 45056, 
+    47104, 47360, 47424, 47456, 47448,     0, 32768, 40960, 
+    45056, 47104, 47360, 47424, 47456, 47448,     0, 32768, 
+    40960, 45056, 47104, 47360, 47424, 47456, 47448, 47450, 
+        0, 32768, 40960, 45056, 47104, 47360, 47424, 47456, 
+    47448,     0, 32768, 40960, 45056, 47104, 47360, 47424, 
+    47456, 47457, 47452,     0, 32768, 40960, 45056, 47104, 
+    47360, 47424, 47456, 47457, 47452,     0, 32768, 40960, 
+    45056, 47104, 47360, 47424, 47456, 47457, 47452, 47454, 
+        0, 32768, 40960, 45056, 47104, 47360, 47424,     0, 
+    32768, 40960, 45056, 47104, 47360, 47488, 47456,     0, 
+    32768, 40960, 45056, 47104, 47360, 47488, 47456,     0, 
+    32768, 40960, 45056, 47104, 47360, 47488, 47456, 47458, 
+        0, 32768, 40960, 45056, 47104, 47360, 47488, 47456, 
+        0, 32768, 40960, 45056, 47104, 47360, 47488, 47456, 
+    47460,     0, 32768, 40960, 45056, 47104, 47360, 47488, 
+    47456, 47460,     0, 32768, 40960, 45056, 47104, 47360, 
+    47488, 47456, 47464, 47462,     0, 32768, 40960, 45056, 
+    47104, 47360, 47488, 47456,     0, 32768, 40960, 45056, 
+    47104, 47360, 47488, 47456, 47464,     0, 32768, 40960, 
+    45056, 47104, 47360, 47488, 47456, 47464,     0, 32768, 
+    40960, 45056, 47104, 47360, 47488, 47456, 47464, 47466, 
+        0, 32768, 40960, 45056, 47104, 47360, 47488, 47456, 
+    47464,     0, 32768, 40960, 45056, 47104, 47360, 47488, 
+    47456, 47472, 47468,     0, 32768, 40960, 45056, 47104, 
+    47360, 47488, 47456, 47472, 47468,     0, 32768, 40960, 
+    45056, 47104, 47360, 47488, 47456, 47472, 47473, 47470, 
+        0, 32768, 40960, 45056, 47104, 47360, 47488, 47456, 
+        0, 32768, 40960, 45056, 47104, 47360, 47488, 47489, 
+    47472,     0, 32768, 40960, 45056, 47104, 47360, 47488, 
+    47489, 47472,     0, 32768, 40960, 45056, 47104, 47360, 
+    47488, 47489, 47472, 47474,     0, 32768, 40960, 45056, 
+    47104, 47360, 47488, 47489, 47472,     0, 32768, 40960, 
+    45056, 47104, 47360, 47488, 47489, 47472, 47476,     0, 
+    32768, 40960, 45056, 47104, 47360, 47488, 47489, 47472, 
+    47476,     0, 32768, 40960, 45056, 47104, 47360, 47488, 
+    47489, 47472, 47480, 47478,     0, 32768, 40960, 45056, 
+    47104, 47360, 47488, 47489, 47472,     0, 32768, 40960, 
+    45056, 47104, 47360, 47488, 47489, 47472, 47480,     0, 
+    32768, 40960, 45056, 47104, 47360, 47488, 47489, 47491, 
+    47480,     0, 32768, 40960, 45056, 47104, 47360, 47488, 
+    47489, 47491, 47480, 47482,     0, 32768, 40960, 45056, 
+    47104, 47360, 47488, 47489, 47491, 47480,     0, 32768, 
+    40960, 45056, 47104, 47360, 47488, 47489, 47491, 47480, 
+    47484,     0, 32768, 40960, 45056, 47104, 47360, 47488, 
+    47489, 47491, 47480, 47484,     0, 32768, 40960, 45056, 
+    47104, 47360, 47488, 47489, 47491, 47480, 47484, 47486, 
+        0, 32768, 40960, 45056, 47104, 47360,     0, 32768, 
+    40960, 45056, 47104, 47616, 47488,     0, 32768, 40960, 
+    45056, 47104, 47616, 47488,     0, 32768, 40960, 45056, 
+    47104, 47616, 47488, 47490,     0, 32768, 40960, 45056, 
+    47104, 47616, 47488,     0, 32768, 40960, 45056, 47104, 
+    47616, 47488, 47492,     0, 32768, 40960, 45056, 47104, 
+    47616, 47488, 47492,     0, 32768, 40960, 45056, 47104, 
+    47616, 47488, 47496, 47494,     0, 32768, 40960, 45056, 
+    47104, 47616, 47488,     0, 32768, 40960, 45056, 47104, 
+    47616, 47488, 47496,     0, 32768, 40960, 45056, 47104, 
+    47616, 47488, 47496,     0, 32768, 40960, 45056, 47104, 
+    47616, 47488, 47496, 47498,     0, 32768, 40960, 45056, 
+    47104, 47616, 47488, 47496,     0, 32768, 40960, 45056, 
+    47104, 47616, 47488, 47504, 47500,     0, 32768, 40960, 
+    45056, 47104, 47616, 47488, 47504, 47500,     0, 32768, 
+    40960, 45056, 47104, 47616, 47488, 47504, 47505, 47502, 
+        0, 32768, 40960, 45056, 47104, 47616, 47488,     0, 
+    32768, 40960, 45056, 47104, 47616, 47488, 47504,     0, 
+    32768, 40960, 45056, 47104, 47616, 47488, 47504,     0, 
+    32768, 40960, 45056, 47104, 47616, 47488, 47504, 47506, 
+        0, 32768, 40960, 45056, 47104, 47616, 47488, 47504, 
+        0, 32768, 40960, 45056, 47104, 47616, 47488, 47504, 
+    47508,     0, 32768, 40960, 45056, 47104, 47616, 47488, 
+    47504, 47508,     0, 32768, 40960, 45056, 47104, 47616, 
+    47488, 47504, 47512, 47510,     0, 32768, 40960, 45056, 
+    47104, 47616, 47488, 47504,     0, 32768, 40960, 45056, 
+    47104, 47616, 47488, 47520, 47512,     0, 32768, 40960, 
+    45056, 47104, 47616, 47488, 47520, 47512,     0, 32768, 
+    40960, 45056, 47104, 47616, 47488, 47520, 47512, 47514, 
+        0, 32768, 40960, 45056, 47104, 47616, 47488, 47520, 
+    47512,     0, 32768, 40960, 45056, 47104, 47616, 47488, 
+    47520, 47521, 47516,     0, 32768, 40960, 45056, 47104, 
+    47616, 47488, 47520, 47521, 47516,     0, 32768, 40960, 
+    45056, 47104, 47616, 47488, 47520, 47521, 47516, 47518, 
+        0, 32768, 40960, 45056, 47104, 47616, 47488,     0, 
+    32768, 40960, 45056, 47104, 47616, 47488, 47520,     0, 
+    32768, 40960, 45056, 47104, 47616, 47488, 47520,     0, 
+    32768, 40960, 45056, 47104, 47616, 47488, 47520, 47522, 
+        0, 32768, 40960, 45056, 47104, 47616, 47488, 47520, 
+        0, 32768, 40960, 45056, 47104, 47616, 47488, 47520, 
+    47524,     0, 32768, 40960, 45056, 47104, 47616, 47488, 
+    47520, 47524,     0, 32768, 40960, 45056, 47104, 47616, 
+    47488, 47520, 47528, 47526,     0, 32768, 40960, 45056, 
+    47104, 47616, 47488, 47520,     0, 32768, 40960, 45056, 
+    47104, 47616, 47488, 47520, 47528,     0, 32768, 40960, 
+    45056, 47104, 47616, 47488, 47520, 47528,     0, 32768, 
+    40960, 45056, 47104, 47616, 47488, 47520, 47528, 47530, 
+        0, 32768, 40960, 45056, 47104, 47616, 47488, 47520, 
+    47528,     0, 32768, 40960, 45056, 47104, 47616, 47488, 
+    47520, 47536, 47532,     0, 32768, 40960, 45056, 47104, 
+    47616, 47488, 47520, 47536, 47532,     0, 32768, 40960, 
+    45056, 47104, 47616, 47488, 47520, 47536, 47537, 47534, 
+        0, 32768, 40960, 45056, 47104, 47616, 47488, 47520, 
+        0, 32768, 40960, 45056, 47104, 47616, 47488, 47552, 
+    47536,     0, 32768, 40960, 45056, 47104, 47616, 47488, 
+    47552, 47536,     0, 32768, 40960, 45056, 47104, 47616, 
+    47488, 47552, 47536, 47538,     0, 32768, 40960, 45056, 
+    47104, 47616, 47488, 47552, 47536,     0, 32768, 40960, 
+    45056, 47104, 47616, 47488, 47552, 47536, 47540,     0, 
+    32768, 40960, 45056, 47104, 47616, 47488, 47552, 47536, 
+    47540,     0, 32768, 40960, 45056, 47104, 47616, 47488, 
+    47552, 47536, 47544, 47542,     0, 32768, 40960, 45056, 
+    47104, 47616, 47488, 47552, 47536,     0, 32768, 40960, 
+    45056, 47104, 47616, 47488, 47552, 47553, 47544,     0, 
+    32768, 40960, 45056, 47104, 47616, 47488, 47552, 47553, 
+    47544,     0, 32768, 40960, 45056, 47104, 47616, 47488, 
+    47552, 47553, 47544, 47546,     0, 32768, 40960, 45056, 
+    47104, 47616, 47488, 47552, 47553, 47544,     0, 32768, 
+    40960, 45056, 47104, 47616, 47488, 47552, 47553, 47544, 
+    47548,     0, 32768, 40960, 45056, 47104, 47616, 47488, 
+    47552, 47553, 47555, 47548,     0, 32768, 40960, 45056, 
+    47104, 47616, 47488, 47552, 47553, 47555, 47548, 47550, 
+        0, 32768, 40960, 45056, 47104, 47616, 47488,     0, 
+    32768, 40960, 45056, 47104, 47616, 47617, 47552,     0, 
+    32768, 40960, 45056, 47104, 47616, 47617, 47552,     0, 
+    32768, 40960, 45056, 47104, 47616, 47617, 47552, 47554, 
+        0, 32768, 40960, 45056, 47104, 47616, 47617, 47552, 
+        0, 32768, 40960, 45056, 47104, 47616, 47617, 47552, 
+    47556,     0, 32768, 40960, 45056, 47104, 47616, 47617, 
+    47552, 47556,     0, 32768, 40960, 45056, 47104, 47616, 
+    47617, 47552, 47560, 47558,     0, 32768, 40960, 45056, 
+    47104, 47616, 47617, 47552,     0, 32768, 40960, 45056, 
+    47104, 47616, 47617, 47552, 47560,     0, 32768, 40960, 
+    45056, 47104, 47616, 47617, 47552, 47560,     0, 32768, 
+    40960, 45056, 47104, 47616, 47617, 47552, 47560, 47562, 
+        0, 32768, 40960, 45056, 47104, 47616, 47617, 47552, 
+    47560,     0, 32768, 40960, 45056, 47104, 47616, 47617, 
+    47552, 47568, 47564,     0, 32768, 40960, 45056, 47104, 
+    47616, 47617, 47552, 47568, 47564,     0, 32768, 40960, 
+    45056, 47104, 47616, 47617, 47552, 47568, 47569, 47566, 
+        0, 32768, 40960, 45056, 47104, 47616, 47617, 47552, 
+        0, 32768, 40960, 45056, 47104, 47616, 47617, 47552, 
+    47568,     0, 32768, 40960, 45056, 47104, 47616, 47617, 
+    47552, 47568,     0, 32768, 40960, 45056, 47104, 47616, 
+    47617, 47552, 47568, 47570,     0, 32768, 40960, 45056, 
+    47104, 47616, 47617, 47552, 47568,     0, 32768, 40960, 
+    45056, 47104, 47616, 47617, 47552, 47568, 47572,     0, 
+    32768, 40960, 45056, 47104, 47616, 47617, 47552, 47568, 
+    47572,     0, 32768, 40960, 45056, 47104, 47616, 47617, 
+    47552, 47568, 47576, 47574,     0, 32768, 40960, 45056, 
+    47104, 47616, 47617, 47552, 47568,     0, 32768, 40960, 
+    45056, 47104, 47616, 47617, 47552, 47584, 47576,     0, 
+    32768, 40960, 45056, 47104, 47616, 47617, 47552, 47584, 
+    47576,     0, 32768, 40960, 45056, 47104, 47616, 47617, 
+    47552, 47584, 47576, 47578,     0, 32768, 40960, 45056, 
+    47104, 47616, 47617, 47552, 47584, 47576,     0, 32768, 
+    40960, 45056, 47104, 47616, 47617, 47552, 47584, 47585, 
+    47580,     0, 32768, 40960, 45056, 47104, 47616, 47617, 
+    47552, 47584, 47585, 47580,     0, 32768, 40960, 45056, 
+    47104, 47616, 47617, 47552, 47584, 47585, 47580, 47582, 
+        0, 32768, 40960, 45056, 47104, 47616, 47617, 47552, 
+        0, 32768, 40960, 45056, 47104, 47616, 47617, 47552, 
+    47584,     0, 32768, 40960, 45056, 47104, 47616, 47617, 
+    47619, 47584,     0, 32768, 40960, 45056, 47104, 47616, 
+    47617, 47619, 47584, 47586,     0, 32768, 40960, 45056, 
+    47104, 47616, 47617, 47619, 47584,     0, 32768, 40960, 
+    45056, 47104, 47616, 47617, 47619, 47584, 47588,     0, 
+    32768, 40960, 45056, 47104, 47616, 47617, 47619, 47584, 
+    47588,     0, 32768, 40960, 45056, 47104, 47616, 47617, 
+    47619, 47584, 47592, 47590,     0, 32768, 40960, 45056, 
+    47104, 47616, 47617, 47619, 47584,     0, 32768, 40960, 
+    45056, 47104, 47616, 47617, 47619, 47584, 47592,     0, 
+    32768, 40960, 45056, 47104, 47616, 47617, 47619, 47584, 
+    47592,     0, 32768, 40960, 45056, 47104, 47616, 47617, 
+    47619, 47584, 47592, 47594,     0, 32768, 40960, 45056, 
+    47104, 47616, 47617, 47619, 47584, 47592,     0, 32768, 
+    40960, 45056, 47104, 47616, 47617, 47619, 47584, 47600, 
+    47596,     0, 32768, 40960, 45056, 47104, 47616, 47617, 
+    47619, 47584, 47600, 47596,     0, 32768, 40960, 45056, 
+    47104, 47616, 47617, 47619, 47584, 47600, 47601, 47598, 
+        0, 32768, 40960, 45056, 47104, 47616, 47617, 47619, 
+    47584,     0, 32768, 40960, 45056, 47104, 47616, 47617, 
+    47619, 47584, 47600,     0, 32768, 40960, 45056, 47104, 
+    47616, 47617, 47619, 47584, 47600,     0, 32768, 40960, 
+    45056, 47104, 47616, 47617, 47619, 47584, 47600, 47602, 
+        0, 32768, 40960, 45056, 47104, 47616, 47617, 47619, 
+    47623, 47600,     0, 32768, 40960, 45056, 47104, 47616, 
+    47617, 47619, 47623, 47600, 47604,     0, 32768, 40960, 
+    45056, 47104, 47616, 47617, 47619, 47623, 47600, 47604, 
+        0, 32768, 40960, 45056, 47104, 47616, 47617, 47619, 
+    47623, 47600, 47608, 47606,     0, 32768, 40960, 45056, 
+    47104, 47616, 47617, 47619, 47623, 47600,     0, 32768, 
+    40960, 45056, 47104, 47616, 47617, 47619, 47623, 47600, 
+    47608,     0, 32768, 40960, 45056, 47104, 47616, 47617, 
+    47619, 47623, 47600, 47608,     0, 32768, 40960, 45056, 
+    47104, 47616, 47617, 47619, 47623, 47600, 47608, 47610, 
+        0, 32768, 40960, 45056, 47104, 47616, 47617, 47619, 
+    47623, 47600, 47608,     0, 32768, 40960, 45056, 47104, 
+    47616, 47617, 47619, 47623, 47600, 47608, 47612,     0, 
+    32768, 40960, 45056, 47104, 47616, 47617, 47619, 47623, 
+    47600, 47608, 47612,     0, 32768, 40960, 45056, 47104, 
+    47616, 47617, 47619, 47623, 47600, 47608, 47612, 47614, 
+        0, 32768, 40960, 45056, 47104,     0, 32768, 40960, 
+    45056, 47104, 47616,     0, 32768, 40960, 45056, 47104, 
+    47616,     0, 32768, 40960, 45056, 47104, 47616, 47618, 
+        0, 32768, 40960, 45056, 47104, 47616,     0, 32768, 
+    40960, 45056, 47104, 47616, 47620,     0, 32768, 40960, 
+    45056, 47104, 47616, 47620,     0, 32768, 40960, 45056, 
+    47104, 47616, 47624, 47622,     0, 32768, 40960, 45056, 
+    47104, 47616,     0, 32768, 40960, 45056, 47104, 47616, 
+    47624,     0, 32768, 40960, 45056, 47104, 47616, 47624, 
+        0, 32768, 40960, 45056, 47104, 47616, 47624, 47626, 
+        0, 32768, 40960, 45056, 47104, 47616, 47624,     0, 
+    32768, 40960, 45056, 47104, 47616, 47632, 47628,     0, 
+    32768, 40960, 45056, 47104, 47616, 47632, 47628,     0, 
+    32768, 40960, 45056, 47104, 47616, 47632, 47633, 47630, 
+        0, 32768, 40960, 45056, 47104, 47616,     0, 32768, 
+    40960, 45056, 47104, 47616, 47632,     0, 32768, 40960, 
+    45056, 47104, 47616, 47632,     0, 32768, 40960, 45056, 
+    47104, 47616, 47632, 47634,     0, 32768, 40960, 45056, 
+    47104, 47616, 47632,     0, 32768, 40960, 45056, 47104, 
+    47616, 47632, 47636,     0, 32768, 40960, 45056, 47104, 
+    47616, 47632, 47636,     0, 32768, 40960, 45056, 47104, 
+    47616, 47632, 47640, 47638,     0, 32768, 40960, 45056, 
+    47104, 47616, 47632,     0, 32768, 40960, 45056, 47104, 
+    47616, 47648, 47640,     0, 32768, 40960, 45056, 47104, 
+    47616, 47648, 47640,     0, 32768, 40960, 45056, 47104, 
+    47616, 47648, 47640, 47642,     0, 32768, 40960, 45056, 
+    47104, 47616, 47648, 47640,     0, 32768, 40960, 45056, 
+    47104, 47616, 47648, 47649, 47644,     0, 32768, 40960, 
+    45056, 47104, 47616, 47648, 47649, 47644,     0, 32768, 
+    40960, 45056, 47104, 47616, 47648, 47649, 47644, 47646, 
+        0, 32768, 40960, 45056, 47104, 47616,     0, 32768, 
+    40960, 45056, 47104, 47616, 47648,     0, 32768, 40960, 
+    45056, 47104, 47616, 47648,     0, 32768, 40960, 45056, 
+    47104, 47616, 47648, 47650,     0, 32768, 40960, 45056, 
+    47104, 47616, 47648,     0, 32768, 40960, 45056, 47104, 
+    47616, 47648, 47652,     0, 32768, 40960, 45056, 47104, 
+    47616, 47648, 47652,     0, 32768, 40960, 45056, 47104, 
+    47616, 47648, 47656, 47654,     0, 32768, 40960, 45056, 
+    47104, 47616, 47648,     0, 32768, 40960, 45056, 47104, 
+    47616, 47648, 47656,     0, 32768, 40960, 45056, 47104, 
+    47616, 47648, 47656,     0, 32768, 40960, 45056, 47104, 
+    47616, 47648, 47656, 47658,     0, 32768, 40960, 45056, 
+    47104, 47616, 47648, 47656,     0, 32768, 40960, 45056, 
+    47104, 47616, 47648, 47664, 47660,     0, 32768, 40960, 
+    45056, 47104, 47616, 47648, 47664, 47660,     0, 32768, 
+    40960, 45056, 47104, 47616, 47648, 47664, 47665, 47662, 
+        0, 32768, 40960, 45056, 47104, 47616, 47648,     0, 
+    32768, 40960, 45056, 47104, 47616, 47680, 47664,     0, 
+    32768, 40960, 45056, 47104, 47616, 47680, 47664,     0, 
+    32768, 40960, 45056, 47104, 47616, 47680, 47664, 47666, 
+        0, 32768, 40960, 45056, 47104, 47616, 47680, 47664, 
+        0, 32768, 40960, 45056, 47104, 47616, 47680, 47664, 
+    47668,     0, 32768, 40960, 45056, 47104, 47616, 47680, 
+    47664, 47668,     0, 32768, 40960, 45056, 47104, 47616, 
+    47680, 47664, 47672, 47670,     0, 32768, 40960, 45056, 
+    47104, 47616, 47680, 47664,     0, 32768, 40960, 45056, 
+    47104, 47616, 47680, 47681, 47672,     0, 32768, 40960, 
+    45056, 47104, 47616, 47680, 47681, 47672,     0, 32768, 
+    40960, 45056, 47104, 47616, 47680, 47681, 47672, 47674, 
+        0, 32768, 40960, 45056, 47104, 47616, 47680, 47681, 
+    47672,     0, 32768, 40960, 45056, 47104, 47616, 47680, 
+    47681, 47672, 47676,     0, 32768, 40960, 45056, 47104, 
+    47616, 47680, 47681, 47683, 47676,     0, 32768, 40960, 
+    45056, 47104, 47616, 47680, 47681, 47683, 47676, 47678, 
+        0, 32768, 40960, 45056, 47104, 47616,     0, 32768, 
+    40960, 45056, 47104, 47616, 47680,     0, 32768, 40960, 
+    45056, 47104, 47616, 47680,     0, 32768, 40960, 45056, 
+    47104, 47616, 47680, 47682,     0, 32768, 40960, 45056, 
+    47104, 47616, 47680,     0, 32768, 40960, 45056, 47104, 
+    47616, 47680, 47684,     0, 32768, 40960, 45056, 47104, 
+    47616, 47680, 47684,     0, 32768, 40960, 45056, 47104, 
+    47616, 47680, 47688, 47686,     0, 32768, 40960, 45056, 
+    47104, 47616, 47680,     0, 32768, 40960, 45056, 47104, 
+    47616, 47680, 47688,     0, 32768, 40960, 45056, 47104, 
+    47616, 47680, 47688,     0, 32768, 40960, 45056, 47104, 
+    47616, 47680, 47688, 47690,     0, 32768, 40960, 45056, 
+    47104, 47616, 47680, 47688,     0, 32768, 40960, 45056, 
+    47104, 47616, 47680, 47696, 47692,     0, 32768, 40960, 
+    45056, 47104, 47616, 47680, 47696, 47692,     0, 32768, 
+    40960, 45056, 47104, 47616, 47680, 47696, 47697, 47694, 
+        0, 32768, 40960, 45056, 47104, 47616, 47680,     0, 
+    32768, 40960, 45056, 47104, 47616, 47680, 47696,     0, 
+    32768, 40960, 45056, 47104, 47616, 47680, 47696,     0, 
+    32768, 40960, 45056, 47104, 47616, 47680, 47696, 47698, 
+        0, 32768, 40960, 45056, 47104, 47616, 47680, 47696, 
+        0, 32768, 40960, 45056, 47104, 47616, 47680, 47696, 
+    47700,     0, 32768, 40960, 45056, 47104, 47616, 47680, 
+    47696, 47700,     0, 32768, 40960, 45056, 47104, 47616, 
+    47680, 47696, 47704, 47702,     0, 32768, 40960, 45056, 
+    47104, 47616, 47680, 47696,     0, 32768, 40960, 45056, 
+    47104, 47616, 47680, 47712, 47704,     0, 32768, 40960, 
+    45056, 47104, 47616, 47680, 47712, 47704,     0, 32768, 
+    40960, 45056, 47104, 47616, 47680, 47712, 47704, 47706, 
+        0, 32768, 40960, 45056, 47104, 47616, 47680, 47712, 
+    47704,     0, 32768, 40960, 45056, 47104, 47616, 47680, 
+    47712, 47713, 47708,     0, 32768, 40960, 45056, 47104, 
+    47616, 47680, 47712, 47713, 47708,     0, 32768, 40960, 
+    45056, 47104, 47616, 47680, 47712, 47713, 47708, 47710, 
+        0, 32768, 40960, 45056, 47104, 47616, 47680,     0, 
+    32768, 40960, 45056, 47104, 47616, 47744, 47712,     0, 
+    32768, 40960, 45056, 47104, 47616, 47744, 47712,     0, 
+    32768, 40960, 45056, 47104, 47616, 47744, 47712, 47714, 
+        0, 32768, 40960, 45056, 47104, 47616, 47744, 47712, 
+        0, 32768, 40960, 45056, 47104, 47616, 47744, 47712, 
+    47716,     0, 32768, 40960, 45056, 47104, 47616, 47744, 
+    47712, 47716,     0, 32768, 40960, 45056, 47104, 47616, 
+    47744, 47712, 47720, 47718,     0, 32768, 40960, 45056, 
+    47104, 47616, 47744, 47712,     0, 32768, 40960, 45056, 
+    47104, 47616, 47744, 47712, 47720,     0, 32768, 40960, 
+    45056, 47104, 47616, 47744, 47712, 47720,     0, 32768, 
+    40960, 45056, 47104, 47616, 47744, 47712, 47720, 47722, 
+        0, 32768, 40960, 45056, 47104, 47616, 47744, 47712, 
+    47720,     0, 32768, 40960, 45056, 47104, 47616, 47744, 
+    47712, 47728, 47724,     0, 32768, 40960, 45056, 47104, 
+    47616, 47744, 47712, 47728, 47724,     0, 32768, 40960, 
+    45056, 47104, 47616, 47744, 47712, 47728, 47729, 47726, 
+        0, 32768, 40960, 45056, 47104, 47616, 47744, 47712, 
+        0, 32768, 40960, 45056, 47104, 47616, 47744, 47745, 
+    47728,     0, 32768, 40960, 45056, 47104, 47616, 47744, 
+    47745, 47728,     0, 32768, 40960, 45056, 47104, 47616, 
+    47744, 47745, 47728, 47730,     0, 32768, 40960, 45056, 
+    47104, 47616, 47744, 47745, 47728,     0, 32768, 40960, 
+    45056, 47104, 47616, 47744, 47745, 47728, 47732,     0, 
+    32768, 40960, 45056, 47104, 47616, 47744, 47745, 47728, 
+    47732,     0, 32768, 40960, 45056, 47104, 47616, 47744, 
+    47745, 47728, 47736, 47734,     0, 32768, 40960, 45056, 
+    47104, 47616, 47744, 47745, 47728,     0, 32768, 40960, 
+    45056, 47104, 47616, 47744, 47745, 47728, 47736,     0, 
+    32768, 40960, 45056, 47104, 47616, 47744, 47745, 47747, 
+    47736,     0, 32768, 40960, 45056, 47104, 47616, 47744, 
+    47745, 47747, 47736, 47738,     0, 32768, 40960, 45056, 
+    47104, 47616, 47744, 47745, 47747, 47736,     0, 32768, 
+    40960, 45056, 47104, 47616, 47744, 47745, 47747, 47736, 
+    47740,     0, 32768, 40960, 45056, 47104, 47616, 47744, 
+    47745, 47747, 47736, 47740,     0, 32768, 40960, 45056, 
+    47104, 47616, 47744, 47745, 47747, 47736, 47740, 47742, 
+        0, 32768, 40960, 45056, 47104, 47616,     0, 32768, 
+    40960, 45056, 47104, 47616, 47744,     0, 32768, 40960, 
+    45056, 47104, 47616, 47744,     0, 32768, 40960, 45056, 
+    47104, 47616, 47744, 47746,     0, 32768, 40960, 45056, 
+    47104, 47616, 47744,     0, 32768, 40960, 45056, 47104, 
+    47616, 47744, 47748,     0, 32768, 40960, 45056, 47104, 
+    47616, 47744, 47748,     0, 32768, 40960, 45056, 47104, 
+    47616, 47744, 47752, 47750,     0, 32768, 40960, 45056, 
+    47104, 47616, 47744,     0, 32768, 40960, 45056, 47104, 
+    47616, 47744, 47752,     0, 32768, 40960, 45056, 47104, 
+    47616, 47744, 47752,     0, 32768, 40960, 45056, 47104, 
+    47616, 47744, 47752, 47754,     0, 32768, 40960, 45056, 
+    47104, 47616, 47744, 47752,     0, 32768, 40960, 45056, 
+    47104, 47616, 47744, 47760, 47756,     0, 32768, 40960, 
+    45056, 47104, 47616, 47744, 47760, 47756,     0, 32768, 
+    40960, 45056, 47104, 47616, 47744, 47760, 47761, 47758, 
+        0, 32768, 40960, 45056, 47104, 47616, 47744,     0, 
+    32768, 40960, 45056, 47104, 47616, 47744, 47760,     0, 
+    32768, 40960, 45056, 47104, 47616, 47744, 47760,     0, 
+    32768, 40960, 45056, 47104, 47616, 47744, 47760, 47762, 
+        0, 32768, 40960, 45056, 47104, 47616, 47744, 47760, 
+        0, 32768, 40960, 45056, 47104, 47616, 47744, 47760, 
+    47764,     0, 32768, 40960, 45056, 47104, 47616, 47744, 
+    47760, 47764,     0, 32768, 40960, 45056, 47104, 47616, 
+    47744, 47760, 47768, 47766,     0, 32768, 40960, 45056, 
+    47104, 47616, 47744, 47760,     0, 32768, 40960, 45056, 
+    47104, 47616, 47744, 47776, 47768,     0, 32768, 40960, 
+    45056, 47104, 47616, 47744, 47776, 47768,     0, 32768, 
+    40960, 45056, 47104, 47616, 47744, 47776, 47768, 47770, 
+        0, 32768, 40960, 45056, 47104, 47616, 47744, 47776, 
+    47768,     0, 32768, 40960, 45056, 47104, 47616, 47744, 
+    47776, 47777, 47772,     0, 32768, 40960, 45056, 47104, 
+    47616, 47744, 47776, 47777, 47772,     0, 32768, 40960, 
+    45056, 47104, 47616, 47744, 47776, 47777, 47772, 47774, 
+        0, 32768, 40960, 45056, 47104, 47616, 47744,     0, 
+    32768, 40960, 45056, 47104, 47616, 47744, 47776,     0, 
+    32768, 40960, 45056, 47104, 47616, 47744, 47776,     0, 
+    32768, 40960, 45056, 47104, 47616, 47744, 47776, 47778, 
+        0, 32768, 40960, 45056, 47104, 47616, 47744, 47776, 
+        0, 32768, 40960, 45056, 47104, 47616, 47744, 47776, 
+    47780,     0, 32768, 40960, 45056, 47104, 47616, 47744, 
+    47776, 47780,     0, 32768, 40960, 45056, 47104, 47616, 
+    47744, 47776, 47784, 47782,     0, 32768, 40960, 45056, 
+    47104, 47616, 47744, 47776,     0, 32768, 40960, 45056, 
+    47104, 47616, 47744, 47776, 47784,     0, 32768, 40960, 
+    45056, 47104, 47616, 47744, 47776, 47784,     0, 32768, 
+    40960, 45056, 47104, 47616, 47744, 47776, 47784, 47786, 
+        0, 32768, 40960, 45056, 47104, 47616, 47744, 47776, 
+    47784,     0, 32768, 40960, 45056, 47104, 47616, 47744, 
+    47776, 47792, 47788,     0, 32768, 40960, 45056, 47104, 
+    47616, 47744, 47776, 47792, 47788,     0, 32768, 40960, 
+    45056, 47104, 47616, 47744, 47776, 47792, 47793, 47790, 
+        0, 32768, 40960, 45056, 47104, 47616, 47744, 47776, 
+        0, 32768, 40960, 45056, 47104, 47616, 47744, 47808, 
+    47792,     0, 32768, 40960, 45056, 47104, 47616, 47744, 
+    47808, 47792,     0, 32768, 40960, 45056, 47104, 47616, 
+    47744, 47808, 47792, 47794,     0, 32768, 40960, 45056, 
+    47104, 47616, 47744, 47808, 47792,     0, 32768, 40960, 
+    45056, 47104, 47616, 47744, 47808, 47792, 47796,     0, 
+    32768, 40960, 45056, 47104, 47616, 47744, 47808, 47792, 
+    47796,     0, 32768, 40960, 45056, 47104, 47616, 47744, 
+    47808, 47792, 47800, 47798,     0, 32768, 40960, 45056, 
+    47104, 47616, 47744, 47808, 47792,     0, 32768, 40960, 
+    45056, 47104, 47616, 47744, 47808, 47809, 47800,     0, 
+    32768, 40960, 45056, 47104, 47616, 47744, 47808, 47809, 
+    47800,     0, 32768, 40960, 45056, 47104, 47616, 47744, 
+    47808, 47809, 47800, 47802,     0, 32768, 40960, 45056, 
+    47104, 47616, 47744, 47808, 47809, 47800,     0, 32768, 
+    40960, 45056, 47104, 47616, 47744, 47808, 47809, 47800, 
+    47804,     0, 32768, 40960, 45056, 47104, 47616, 47744, 
+    47808, 47809, 47811, 47804,     0, 32768, 40960, 45056, 
+    47104, 47616, 47744, 47808, 47809, 47811, 47804, 47806, 
+        0, 32768, 40960, 45056, 47104, 47616, 47744,     0, 
+    32768, 40960, 45056, 47104, 47616, 47872, 47808,     0, 
+    32768, 40960, 45056, 47104, 47616, 47872, 47808,     0, 
+    32768, 40960, 45056, 47104, 47616, 47872, 47808, 47810, 
+        0, 32768, 40960, 45056, 47104, 47616, 47872, 47808, 
+        0, 32768, 40960, 45056, 47104, 47616, 47872, 47808, 
+    47812,     0, 32768, 40960, 45056, 47104, 47616, 47872, 
+    47808, 47812,     0, 32768, 40960, 45056, 47104, 47616, 
+    47872, 47808, 47816, 47814,     0, 32768, 40960, 45056, 
+    47104, 47616, 47872, 47808,     0, 32768, 40960, 45056, 
+    47104, 47616, 47872, 47808, 47816,     0, 32768, 40960, 
+    45056, 47104, 47616, 47872, 47808, 47816,     0, 32768, 
+    40960, 45056, 47104, 47616, 47872, 47808, 47816, 47818, 
+        0, 32768, 40960, 45056, 47104, 47616, 47872, 47808, 
+    47816,     0, 32768, 40960, 45056, 47104, 47616, 47872, 
+    47808, 47824, 47820,     0, 32768, 40960, 45056, 47104, 
+    47616, 47872, 47808, 47824, 47820,     0, 32768, 40960, 
+    45056, 47104, 47616, 47872, 47808, 47824, 47825, 47822, 
+        0, 32768, 40960, 45056, 47104, 47616, 47872, 47808, 
+        0, 32768, 40960, 45056, 47104, 47616, 47872, 47808, 
+    47824,     0, 32768, 40960, 45056, 47104, 47616, 47872, 
+    47808, 47824,     0, 32768, 40960, 45056, 47104, 47616, 
+    47872, 47808, 47824, 47826,     0, 32768, 40960, 45056, 
+    47104, 47616, 47872, 47808, 47824,     0, 32768, 40960, 
+    45056, 47104, 47616, 47872, 47808, 47824, 47828,     0, 
+    32768, 40960, 45056, 47104, 47616, 47872, 47808, 47824, 
+    47828,     0, 32768, 40960, 45056, 47104, 47616, 47872, 
+    47808, 47824, 47832, 47830,     0, 32768, 40960, 45056, 
+    47104, 47616, 47872, 47808, 47824,     0, 32768, 40960, 
+    45056, 47104, 47616, 47872, 47808, 47840, 47832,     0, 
+    32768, 40960, 45056, 47104, 47616, 47872, 47808, 47840, 
+    47832,     0, 32768, 40960, 45056, 47104, 47616, 47872, 
+    47808, 47840, 47832, 47834,     0, 32768, 40960, 45056, 
+    47104, 47616, 47872, 47808, 47840, 47832,     0, 32768, 
+    40960, 45056, 47104, 47616, 47872, 47808, 47840, 47841, 
+    47836,     0, 32768, 40960, 45056, 47104, 47616, 47872, 
+    47808, 47840, 47841, 47836,     0, 32768, 40960, 45056, 
+    47104, 47616, 47872, 47808, 47840, 47841, 47836, 47838, 
+        0, 32768, 40960, 45056, 47104, 47616, 47872, 47808, 
+        0, 32768, 40960, 45056, 47104, 47616, 47872, 47873, 
+    47840,     0, 32768, 40960, 45056, 47104, 47616, 47872, 
+    47873, 47840,     0, 32768, 40960, 45056, 47104, 47616, 
+    47872, 47873, 47840, 47842,     0, 32768, 40960, 45056, 
+    47104, 47616, 47872, 47873, 47840,     0, 32768, 40960, 
+    45056, 47104, 47616, 47872, 47873, 47840, 47844,     0, 
+    32768, 40960, 45056, 47104, 47616, 47872, 47873, 47840, 
+    47844,     0, 32768, 40960, 45056, 47104, 47616, 47872, 
+    47873, 47840, 47848, 47846,     0, 32768, 40960, 45056, 
+    47104, 47616, 47872, 47873, 47840,     0, 32768, 40960, 
+    45056, 47104, 47616, 47872, 47873, 47840, 47848,     0, 
+    32768, 40960, 45056, 47104, 47616, 47872, 47873, 47840, 
+    47848,     0, 32768, 40960, 45056, 47104, 47616, 47872, 
+    47873, 47840, 47848, 47850,     0, 32768, 40960, 45056, 
+    47104, 47616, 47872, 47873, 47840, 47848,     0, 32768, 
+    40960, 45056, 47104, 47616, 47872, 47873, 47840, 47856, 
+    47852,     0, 32768, 40960, 45056, 47104, 47616, 47872, 
+    47873, 47840, 47856, 47852,     0, 32768, 40960, 45056, 
+    47104, 47616, 47872, 47873, 47840, 47856, 47857, 47854, 
+        0, 32768, 40960, 45056, 47104, 47616, 47872, 47873, 
+    47840,     0, 32768, 40960, 45056, 47104, 47616, 47872, 
+    47873, 47840, 47856,     0, 32768, 40960, 45056, 47104, 
+    47616, 47872, 47873, 47875, 47856,     0, 32768, 40960, 
+    45056, 47104, 47616, 47872, 47873, 47875, 47856, 47858, 
+        0, 32768, 40960, 45056, 47104, 47616, 47872, 47873, 
+    47875, 47856,     0, 32768, 40960, 45056, 47104, 47616, 
+    47872, 47873, 47875, 47856, 47860,     0, 32768, 40960, 
+    45056, 47104, 47616, 47872, 47873, 47875, 47856, 47860, 
+        0, 32768, 40960, 45056, 47104, 47616, 47872, 47873, 
+    47875, 47856, 47864, 47862,     0, 32768, 40960, 45056, 
+    47104, 47616, 47872, 47873, 47875, 47856,     0, 32768, 
+    40960, 45056, 47104, 47616, 47872, 47873, 47875, 47856, 
+    47864,     0, 32768, 40960, 45056, 47104, 47616, 47872, 
+    47873, 47875, 47856, 47864,     0, 32768, 40960, 45056, 
+    47104, 47616, 47872, 47873, 47875, 47856, 47864, 47866, 
+        0, 32768, 40960, 45056, 47104, 47616, 47872, 47873, 
+    47875, 47879, 47864,     0, 32768, 40960, 45056, 47104, 
+    47616, 47872, 47873, 47875, 47879, 47864, 47868,     0, 
+    32768, 40960, 45056, 47104, 47616, 47872, 47873, 47875, 
+    47879, 47864, 47868,     0, 32768, 40960, 45056, 47104, 
+    47616, 47872, 47873, 47875, 47879, 47864, 47868, 47870, 
+        0, 32768, 40960, 45056, 47104, 47616,     0, 32768, 
+    40960, 45056, 47104, 48128, 47872,     0, 32768, 40960, 
+    45056, 47104, 48128, 47872,     0, 32768, 40960, 45056, 
+    47104, 48128, 47872, 47874,     0, 32768, 40960, 45056, 
+    47104, 48128, 47872,     0, 32768, 40960, 45056, 47104, 
+    48128, 47872, 47876,     0, 32768, 40960, 45056, 47104, 
+    48128, 47872, 47876,     0, 32768, 40960, 45056, 47104, 
+    48128, 47872, 47880, 47878,     0, 32768, 40960, 45056, 
+    47104, 48128, 47872,     0, 32768, 40960, 45056, 47104, 
+    48128, 47872, 47880,     0, 32768, 40960, 45056, 47104, 
+    48128, 47872, 47880,     0, 32768, 40960, 45056, 47104, 
+    48128, 47872, 47880, 47882,     0, 32768, 40960, 45056, 
+    47104, 48128, 47872, 47880,     0, 32768, 40960, 45056, 
+    47104, 48128, 47872, 47888, 47884,     0, 32768, 40960, 
+    45056, 47104, 48128, 47872, 47888, 47884,     0, 32768, 
+    40960, 45056, 47104, 48128, 47872, 47888, 47889, 47886, 
+        0, 32768, 40960, 45056, 47104, 48128, 47872,     0, 
+    32768, 40960, 45056, 47104, 48128, 47872, 47888,     0, 
+    32768, 40960, 45056, 47104, 48128, 47872, 47888,     0, 
+    32768, 40960, 45056, 47104, 48128, 47872, 47888, 47890, 
+        0, 32768, 40960, 45056, 47104, 48128, 47872, 47888, 
+        0, 32768, 40960, 45056, 47104, 48128, 47872, 47888, 
+    47892,     0, 32768, 40960, 45056, 47104, 48128, 47872, 
+    47888, 47892,     0, 32768, 40960, 45056, 47104, 48128, 
+    47872, 47888, 47896, 47894,     0, 32768, 40960, 45056, 
+    47104, 48128, 47872, 47888,     0, 32768, 40960, 45056, 
+    47104, 48128, 47872, 47904, 47896,     0, 32768, 40960, 
+    45056, 47104, 48128, 47872, 47904, 47896,     0, 32768, 
+    40960, 45056, 47104, 48128, 47872, 47904, 47896, 47898, 
+        0, 32768, 40960, 45056, 47104, 48128, 47872, 47904, 
+    47896,     0, 32768, 40960, 45056, 47104, 48128, 47872, 
+    47904, 47905, 47900,     0, 32768, 40960, 45056, 47104, 
+    48128, 47872, 47904, 47905, 47900,     0, 32768, 40960, 
+    45056, 47104, 48128, 47872, 47904, 47905, 47900, 47902, 
+        0, 32768, 40960, 45056, 47104, 48128, 47872,     0, 
+    32768, 40960, 45056, 47104, 48128, 47872, 47904,     0, 
+    32768, 40960, 45056, 47104, 48128, 47872, 47904,     0, 
+    32768, 40960, 45056, 47104, 48128, 47872, 47904, 47906, 
+        0, 32768, 40960, 45056, 47104, 48128, 47872, 47904, 
+        0, 32768, 40960, 45056, 47104, 48128, 47872, 47904, 
+    47908,     0, 32768, 40960, 45056, 47104, 48128, 47872, 
+    47904, 47908,     0, 32768, 40960, 45056, 47104, 48128, 
+    47872, 47904, 47912, 47910,     0, 32768, 40960, 45056, 
+    47104, 48128, 47872, 47904,     0, 32768, 40960, 45056, 
+    47104, 48128, 47872, 47904, 47912,     0, 32768, 40960, 
+    45056, 47104, 48128, 47872, 47904, 47912,     0, 32768, 
+    40960, 45056, 47104, 48128, 47872, 47904, 47912, 47914, 
+        0, 32768, 40960, 45056, 47104, 48128, 47872, 47904, 
+    47912,     0, 32768, 40960, 45056, 47104, 48128, 47872, 
+    47904, 47920, 47916,     0, 32768, 40960, 45056, 47104, 
+    48128, 47872, 47904, 47920, 47916,     0, 32768, 40960, 
+    45056, 47104, 48128, 47872, 47904, 47920, 47921, 47918, 
+        0, 32768, 40960, 45056, 47104, 48128, 47872, 47904, 
+        0, 32768, 40960, 45056, 47104, 48128, 47872, 47936, 
+    47920,     0, 32768, 40960, 45056, 47104, 48128, 47872, 
+    47936, 47920,     0, 32768, 40960, 45056, 47104, 48128, 
+    47872, 47936, 47920, 47922,     0, 32768, 40960, 45056, 
+    47104, 48128, 47872, 47936, 47920,     0, 32768, 40960, 
+    45056, 47104, 48128, 47872, 47936, 47920, 47924,     0, 
+    32768, 40960, 45056, 47104, 48128, 47872, 47936, 47920, 
+    47924,     0, 32768, 40960, 45056, 47104, 48128, 47872, 
+    47936, 47920, 47928, 47926,     0, 32768, 40960, 45056, 
+    47104, 48128, 47872, 47936, 47920,     0, 32768, 40960, 
+    45056, 47104, 48128, 47872, 47936, 47937, 47928,     0, 
+    32768, 40960, 45056, 47104, 48128, 47872, 47936, 47937, 
+    47928,     0, 32768, 40960, 45056, 47104, 48128, 47872, 
+    47936, 47937, 47928, 47930,     0, 32768, 40960, 45056, 
+    47104, 48128, 47872, 47936, 47937, 47928,     0, 32768, 
+    40960, 45056, 47104, 48128, 47872, 47936, 47937, 47928, 
+    47932,     0, 32768, 40960, 45056, 47104, 48128, 47872, 
+    47936, 47937, 47939, 47932,     0, 32768, 40960, 45056, 
+    47104, 48128, 47872, 47936, 47937, 47939, 47932, 47934, 
+        0, 32768, 40960, 45056, 47104, 48128, 47872,     0, 
+    32768, 40960, 45056, 47104, 48128, 47872, 47936,     0, 
+    32768, 40960, 45056, 47104, 48128, 47872, 47936,     0, 
+    32768, 40960, 45056, 47104, 48128, 47872, 47936, 47938, 
+        0, 32768, 40960, 45056, 47104, 48128, 47872, 47936, 
+        0, 32768, 40960, 45056, 47104, 48128, 47872, 47936, 
+    47940,     0, 32768, 40960, 45056, 47104, 48128, 47872, 
+    47936, 47940,     0, 32768, 40960, 45056, 47104, 48128, 
+    47872, 47936, 47944, 47942,     0, 32768, 40960, 45056, 
+    47104, 48128, 47872, 47936,     0, 32768, 40960, 45056, 
+    47104, 48128, 47872, 47936, 47944,     0, 32768, 40960, 
+    45056, 47104, 48128, 47872, 47936, 47944,     0, 32768, 
+    40960, 45056, 47104, 48128, 47872, 47936, 47944, 47946, 
+        0, 32768, 40960, 45056, 47104, 48128, 47872, 47936, 
+    47944,     0, 32768, 40960, 45056, 47104, 48128, 47872, 
+    47936, 47952, 47948,     0, 32768, 40960, 45056, 47104, 
+    48128, 47872, 47936, 47952, 47948,     0, 32768, 40960, 
+    45056, 47104, 48128, 47872, 47936, 47952, 47953, 47950, 
+        0, 32768, 40960, 45056, 47104, 48128, 47872, 47936, 
+        0, 32768, 40960, 45056, 47104, 48128, 47872, 47936, 
+    47952,     0, 32768, 40960, 45056, 47104, 48128, 47872, 
+    47936, 47952,     0, 32768, 40960, 45056, 47104, 48128, 
+    47872, 47936, 47952, 47954,     0, 32768, 40960, 45056, 
+    47104, 48128, 47872, 47936, 47952,     0, 32768, 40960, 
+    45056, 47104, 48128, 47872, 47936, 47952, 47956,     0, 
+    32768, 40960, 45056, 47104, 48128, 47872, 47936, 47952, 
+    47956,     0, 32768, 40960, 45056, 47104, 48128, 47872, 
+    47936, 47952, 47960, 47958,     0, 32768, 40960, 45056, 
+    47104, 48128, 47872, 47936, 47952,     0, 32768, 40960, 
+    45056, 47104, 48128, 47872, 47936, 47968, 47960,     0, 
+    32768, 40960, 45056, 47104, 48128, 47872, 47936, 47968, 
+    47960,     0, 32768, 40960, 45056, 47104, 48128, 47872, 
+    47936, 47968, 47960, 47962,     0, 32768, 40960, 45056, 
+    47104, 48128, 47872, 47936, 47968, 47960,     0, 32768, 
+    40960, 45056, 47104, 48128, 47872, 47936, 47968, 47969, 
+    47964,     0, 32768, 40960, 45056, 47104, 48128, 47872, 
+    47936, 47968, 47969, 47964,     0, 32768, 40960, 45056, 
+    47104, 48128, 47872, 47936, 47968, 47969, 47964, 47966, 
+        0, 32768, 40960, 45056, 47104, 48128, 47872, 47936, 
+        0, 32768, 40960, 45056, 47104, 48128, 47872, 48000, 
+    47968,     0, 32768, 40960, 45056, 47104, 48128, 47872, 
+    48000, 47968,     0, 32768, 40960, 45056, 47104, 48128, 
+    47872, 48000, 47968, 47970,     0, 32768, 40960, 45056, 
+    47104, 48128, 47872, 48000, 47968,     0, 32768, 40960, 
+    45056, 47104, 48128, 47872, 48000, 47968, 47972,     0, 
+    32768, 40960, 45056, 47104, 48128, 47872, 48000, 47968, 
+    47972,     0, 32768, 40960, 45056, 47104, 48128, 47872, 
+    48000, 47968, 47976, 47974,     0, 32768, 40960, 45056, 
+    47104, 48128, 47872, 48000, 47968,     0, 32768, 40960, 
+    45056, 47104, 48128, 47872, 48000, 47968, 47976,     0, 
+    32768, 40960, 45056, 47104, 48128, 47872, 48000, 47968, 
+    47976,     0, 32768, 40960, 45056, 47104, 48128, 47872, 
+    48000, 47968, 47976, 47978,     0, 32768, 40960, 45056, 
+    47104, 48128, 47872, 48000, 47968, 47976,     0, 32768, 
+    40960, 45056, 47104, 48128, 47872, 48000, 47968, 47984, 
+    47980,     0, 32768, 40960, 45056, 47104, 48128, 47872, 
+    48000, 47968, 47984, 47980,     0, 32768, 40960, 45056, 
+    47104, 48128, 47872, 48000, 47968, 47984, 47985, 47982, 
+        0, 32768, 40960, 45056, 47104, 48128, 47872, 48000, 
+    47968,     0, 32768, 40960, 45056, 47104, 48128, 47872, 
+    48000, 48001, 47984,     0, 32768, 40960, 45056, 47104, 
+    48128, 47872, 48000, 48001, 47984,     0, 32768, 40960, 
+    45056, 47104, 48128, 47872, 48000, 48001, 47984, 47986, 
+        0, 32768, 40960, 45056, 47104, 48128, 47872, 48000, 
+    48001, 47984,     0, 32768, 40960, 45056, 47104, 48128, 
+    47872, 48000, 48001, 47984, 47988,     0, 32768, 40960, 
+    45056, 47104, 48128, 47872, 48000, 48001, 47984, 47988, 
+        0, 32768, 40960, 45056, 47104, 48128, 47872, 48000, 
+    48001, 47984, 47992, 47990,     0, 32768, 40960, 45056, 
+    47104, 48128, 47872, 48000, 48001, 47984,     0, 32768, 
+    40960, 45056, 47104, 48128, 47872, 48000, 48001, 47984, 
+    47992,     0, 32768, 40960, 45056, 47104, 48128, 47872, 
+    48000, 48001, 48003, 47992,     0, 32768, 40960, 45056, 
+    47104, 48128, 47872, 48000, 48001, 48003, 47992, 47994, 
+        0, 32768, 40960, 45056, 47104, 48128, 47872, 48000, 
+    48001, 48003, 47992,     0, 32768, 40960, 45056, 47104, 
+    48128, 47872, 48000, 48001, 48003, 47992, 47996,     0, 
+    32768, 40960, 45056, 47104, 48128, 47872, 48000, 48001, 
+    48003, 47992, 47996,     0, 32768, 40960, 45056, 47104, 
+    48128, 47872, 48000, 48001, 48003, 47992, 47996, 47998, 
+        0, 32768, 40960, 45056, 47104, 48128, 47872,     0, 
+    32768, 40960, 45056, 47104, 48128, 47872, 48000,     0, 
+    32768, 40960, 45056, 47104, 48128, 48129, 48000,     0, 
+    32768, 40960, 45056, 47104, 48128, 48129, 48000, 48002, 
+        0, 32768, 40960, 45056, 47104, 48128, 48129, 48000, 
+        0, 32768, 40960, 45056, 47104, 48128, 48129, 48000, 
+    48004,     0, 32768, 40960, 45056, 47104, 48128, 48129, 
+    48000, 48004,     0, 32768, 40960, 45056, 47104, 48128, 
+    48129, 48000, 48008, 48006,     0, 32768, 40960, 45056, 
+    47104, 48128, 48129, 48000,     0, 32768, 40960, 45056, 
+    47104, 48128, 48129, 48000, 48008,     0, 32768, 40960, 
+    45056, 47104, 48128, 48129, 48000, 48008,     0, 32768, 
+    40960, 45056, 47104, 48128, 48129, 48000, 48008, 48010, 
+        0, 32768, 40960, 45056, 47104, 48128, 48129, 48000, 
+    48008,     0, 32768, 40960, 45056, 47104, 48128, 48129, 
+    48000, 48016, 48012,     0, 32768, 40960, 45056, 47104, 
+    48128, 48129, 48000, 48016, 48012,     0, 32768, 40960, 
+    45056, 47104, 48128, 48129, 48000, 48016, 48017, 48014, 
+        0, 32768, 40960, 45056, 47104, 48128, 48129, 48000, 
+        0, 32768, 40960, 45056, 47104, 48128, 48129, 48000, 
+    48016,     0, 32768, 40960, 45056, 47104, 48128, 48129, 
+    48000, 48016,     0, 32768, 40960, 45056, 47104, 48128, 
+    48129, 48000, 48016, 48018,     0, 32768, 40960, 45056, 
+    47104, 48128, 48129, 48000, 48016,     0, 32768, 40960, 
+    45056, 47104, 48128, 48129, 48000, 48016, 48020,     0, 
+    32768, 40960, 45056, 47104, 48128, 48129, 48000, 48016, 
+    48020,     0, 32768, 40960, 45056, 47104, 48128, 48129, 
+    48000, 48016, 48024, 48022,     0, 32768, 40960, 45056, 
+    47104, 48128, 48129, 48000, 48016,     0, 32768, 40960, 
+    45056, 47104, 48128, 48129, 48000, 48032, 48024,     0, 
+    32768, 40960, 45056, 47104, 48128, 48129, 48000, 48032, 
+    48024,     0, 32768, 40960, 45056, 47104, 48128, 48129, 
+    48000, 48032, 48024, 48026,     0, 32768, 40960, 45056, 
+    47104, 48128, 48129, 48000, 48032, 48024,     0, 32768, 
+    40960, 45056, 47104, 48128, 48129, 48000, 48032, 48033, 
+    48028,     0, 32768, 40960, 45056, 47104, 48128, 48129, 
+    48000, 48032, 48033, 48028,     0, 32768, 40960, 45056, 
+    47104, 48128, 48129, 48000, 48032, 48033, 48028, 48030, 
+        0, 32768, 40960, 45056, 47104, 48128, 48129, 48000, 
+        0, 32768, 40960, 45056, 47104, 48128, 48129, 48000, 
+    48032,     0, 32768, 40960, 45056, 47104, 48128, 48129, 
+    48000, 48032,     0, 32768, 40960, 45056, 47104, 48128, 
+    48129, 48000, 48032, 48034,     0, 32768, 40960, 45056, 
+    47104, 48128, 48129, 48000, 48032,     0, 32768, 40960, 
+    45056, 47104, 48128, 48129, 48000, 48032, 48036,     0, 
+    32768, 40960, 45056, 47104, 48128, 48129, 48000, 48032, 
+    48036,     0, 32768, 40960, 45056, 47104, 48128, 48129, 
+    48000, 48032, 48040, 48038,     0, 32768, 40960, 45056, 
+    47104, 48128, 48129, 48000, 48032,     0, 32768, 40960, 
+    45056, 47104, 48128, 48129, 48000, 48032, 48040,     0, 
+    32768, 40960, 45056, 47104, 48128, 48129, 48000, 48032, 
+    48040,     0, 32768, 40960, 45056, 47104, 48128, 48129, 
+    48000, 48032, 48040, 48042,     0, 32768, 40960, 45056, 
+    47104, 48128, 48129, 48000, 48032, 48040,     0, 32768, 
+    40960, 45056, 47104, 48128, 48129, 48000, 48032, 48048, 
+    48044,     0, 32768, 40960, 45056, 47104, 48128, 48129, 
+    48000, 48032, 48048, 48044,     0, 32768, 40960, 45056, 
+    47104, 48128, 48129, 48000, 48032, 48048, 48049, 48046, 
+        0, 32768, 40960, 45056, 47104, 48128, 48129, 48000, 
+    48032,     0, 32768, 40960, 45056, 47104, 48128, 48129, 
+    48000, 48064, 48048,     0, 32768, 40960, 45056, 47104, 
+    48128, 48129, 48000, 48064, 48048,     0, 32768, 40960, 
+    45056, 47104, 48128, 48129, 48000, 48064, 48048, 48050, 
+        0, 32768, 40960, 45056, 47104, 48128, 48129, 48000, 
+    48064, 48048,     0, 32768, 40960, 45056, 47104, 48128, 
+    48129, 48000, 48064, 48048, 48052,     0, 32768, 40960, 
+    45056, 47104, 48128, 48129, 48000, 48064, 48048, 48052, 
+        0, 32768, 40960, 45056, 47104, 48128, 48129, 48000, 
+    48064, 48048, 48056, 48054,     0, 32768, 40960, 45056, 
+    47104, 48128, 48129, 48000, 48064, 48048,     0, 32768, 
+    40960, 45056, 47104, 48128, 48129, 48000, 48064, 48065, 
+    48056,     0, 32768, 40960, 45056, 47104, 48128, 48129, 
+    48000, 48064, 48065, 48056,     0, 32768, 40960, 45056, 
+    47104, 48128, 48129, 48000, 48064, 48065, 48056, 48058, 
+        0, 32768, 40960, 45056, 47104, 48128, 48129, 48000, 
+    48064, 48065, 48056,     0, 32768, 40960, 45056, 47104, 
+    48128, 48129, 48000, 48064, 48065, 48056, 48060,     0, 
+    32768, 40960, 45056, 47104, 48128, 48129, 48000, 48064, 
+    48065, 48067, 48060,     0, 32768, 40960, 45056, 47104, 
+    48128, 48129, 48000, 48064, 48065, 48067, 48060, 48062, 
+        0, 32768, 40960, 45056, 47104, 48128, 48129, 48000, 
+        0, 32768, 40960, 45056, 47104, 48128, 48129, 48000, 
+    48064,     0, 32768, 40960, 45056, 47104, 48128, 48129, 
+    48000, 48064,     0, 32768, 40960, 45056, 47104, 48128, 
+    48129, 48000, 48064, 48066,     0, 32768, 40960, 45056, 
+    47104, 48128, 48129, 48131, 48064,     0, 32768, 40960, 
+    45056, 47104, 48128, 48129, 48131, 48064, 48068,     0, 
+    32768, 40960, 45056, 47104, 48128, 48129, 48131, 48064, 
+    48068,     0, 32768, 40960, 45056, 47104, 48128, 48129, 
+    48131, 48064, 48072, 48070,     0, 32768, 40960, 45056, 
+    47104, 48128, 48129, 48131, 48064,     0, 32768, 40960, 
+    45056, 47104, 48128, 48129, 48131, 48064, 48072,     0, 
+    32768, 40960, 45056, 47104, 48128, 48129, 48131, 48064, 
+    48072,     0, 32768, 40960, 45056, 47104, 48128, 48129, 
+    48131, 48064, 48072, 48074,     0, 32768, 40960, 45056, 
+    47104, 48128, 48129, 48131, 48064, 48072,     0, 32768, 
+    40960, 45056, 47104, 48128, 48129, 48131, 48064, 48080, 
+    48076,     0, 32768, 40960, 45056, 47104, 48128, 48129, 
+    48131, 48064, 48080, 48076,     0, 32768, 40960, 45056, 
+    47104, 48128, 48129, 48131, 48064, 48080, 48081, 48078, 
+        0, 32768, 40960, 45056, 47104, 48128, 48129, 48131, 
+    48064,     0, 32768, 40960, 45056, 47104, 48128, 48129, 
+    48131, 48064, 48080,     0, 32768, 40960, 45056, 47104, 
+    48128, 48129, 48131, 48064, 48080,     0, 32768, 40960, 
+    45056, 47104, 48128, 48129, 48131, 48064, 48080, 48082, 
+        0, 32768, 40960, 45056, 47104, 48128, 48129, 48131, 
+    48064, 48080,     0, 32768, 40960, 45056, 47104, 48128, 
+    48129, 48131, 48064, 48080, 48084,     0, 32768, 40960, 
+    45056, 47104, 48128, 48129, 48131, 48064, 48080, 48084, 
+        0, 32768, 40960, 45056, 47104, 48128, 48129, 48131, 
+    48064, 48080, 48088, 48086,     0, 32768, 40960, 45056, 
+    47104, 48128, 48129, 48131, 48064, 48080,     0, 32768, 
+    40960, 45056, 47104, 48128, 48129, 48131, 48064, 48096, 
+    48088,     0, 32768, 40960, 45056, 47104, 48128, 48129, 
+    48131, 48064, 48096, 48088,     0, 32768, 40960, 45056, 
+    47104, 48128, 48129, 48131, 48064, 48096, 48088, 48090, 
+        0, 32768, 40960, 45056, 47104, 48128, 48129, 48131, 
+    48064, 48096, 48088,     0, 32768, 40960, 45056, 47104, 
+    48128, 48129, 48131, 48064, 48096, 48097, 48092,     0, 
+    32768, 40960, 45056, 47104, 48128, 48129, 48131, 48064, 
+    48096, 48097, 48092,     0, 32768, 40960, 45056, 47104, 
+    48128, 48129, 48131, 48064, 48096, 48097, 48092, 48094, 
+        0, 32768, 40960, 45056, 47104, 48128, 48129, 48131, 
+    48064,     0, 32768, 40960, 45056, 47104, 48128, 48129, 
+    48131, 48064, 48096,     0, 32768, 40960, 45056, 47104, 
+    48128, 48129, 48131, 48064, 48096,     0, 32768, 40960, 
+    45056, 47104, 48128, 48129, 48131, 48064, 48096, 48098, 
+        0, 32768, 40960, 45056, 47104, 48128, 48129, 48131, 
+    48064, 48096,     0, 32768, 40960, 45056, 47104, 48128, 
+    48129, 48131, 48064, 48096, 48100,     0, 32768, 40960, 
+    45056, 47104, 48128, 48129, 48131, 48064, 48096, 48100, 
+        0, 32768, 40960, 45056, 47104, 48128, 48129, 48131, 
+    48064, 48096, 48104, 48102,     0, 32768, 40960, 45056, 
+    47104, 48128, 48129, 48131, 48135, 48096,     0, 32768, 
+    40960, 45056, 47104, 48128, 48129, 48131, 48135, 48096, 
+    48104,     0, 32768, 40960, 45056, 47104, 48128, 48129, 
+    48131, 48135, 48096, 48104,     0, 32768, 40960, 45056, 
+    47104, 48128, 48129, 48131, 48135, 48096, 48104, 48106, 
+        0, 32768, 40960, 45056, 47104, 48128, 48129, 48131, 
+    48135, 48096, 48104,     0, 32768, 40960, 45056, 47104, 
+    48128, 48129, 48131, 48135, 48096, 48112, 48108,     0, 
+    32768, 40960, 45056, 47104, 48128, 48129, 48131, 48135, 
+    48096, 48112, 48108,     0, 32768, 40960, 45056, 47104, 
+    48128, 48129, 48131, 48135, 48096, 48112, 48113, 48110, 
+        0, 32768, 40960, 45056, 47104, 48128, 48129, 48131, 
+    48135, 48096,     0, 32768, 40960, 45056, 47104, 48128, 
+    48129, 48131, 48135, 48096, 48112,     0, 32768, 40960, 
+    45056, 47104, 48128, 48129, 48131, 48135, 48096, 48112, 
+        0, 32768, 40960, 45056, 47104, 48128, 48129, 48131, 
+    48135, 48096, 48112, 48114,     0, 32768, 40960, 45056, 
+    47104, 48128, 48129, 48131, 48135, 48096, 48112,     0, 
+    32768, 40960, 45056, 47104, 48128, 48129, 48131, 48135, 
+    48096, 48112, 48116,     0, 32768, 40960, 45056, 47104, 
+    48128, 48129, 48131, 48135, 48096, 48112, 48116,     0, 
+    32768, 40960, 45056, 47104, 48128, 48129, 48131, 48135, 
+    48096, 48112, 48120, 48118,     0, 32768, 40960, 45056, 
+    47104, 48128, 48129, 48131, 48135, 48096, 48112,     0, 
+    32768, 40960, 45056, 47104, 48128, 48129, 48131, 48135, 
+    48096, 48112, 48120,     0, 32768, 40960, 45056, 47104, 
+    48128, 48129, 48131, 48135, 48096, 48112, 48120,     0, 
+    32768, 40960, 45056, 47104, 48128, 48129, 48131, 48135, 
+    48096, 48112, 48120, 48122,     0, 32768, 40960, 45056, 
+    47104, 48128, 48129, 48131, 48135, 48096, 48112, 48120, 
+        0, 32768, 40960, 45056, 47104, 48128, 48129, 48131, 
+    48135, 48096, 48112, 48120, 48124,     0, 32768, 40960, 
+    45056, 47104, 48128, 48129, 48131, 48135, 48096, 48112, 
+    48120, 48124,     0, 32768, 40960, 45056, 47104, 48128, 
+    48129, 48131, 48135, 48096, 48112, 48120, 48124, 48126, 
+        0,     1, 40960, 45056, 47104,     0,     1, 40960, 
+    45056, 47104, 48128,     0,     1, 40960, 45056, 47104, 
+    48128,     0,     1, 40960, 45056, 47104, 48128, 48130, 
+        0,     1, 40960, 45056, 47104, 48128,     0,     1, 
+    49152, 45056, 47104, 48128, 48132,     0,     1, 49152, 
+    45056, 47104, 48128, 48132,     0,     1, 49152, 45056, 
+    47104, 48128, 48136, 48134,     0,     1, 49152, 45056, 
+    47104, 48128,     0,     1, 49152, 45056, 47104, 48128, 
+    48136,     0,     1, 49152, 45056, 47104, 48128, 48136, 
+        0,     1, 49152, 45056, 47104, 48128, 48136, 48138, 
+        0,     1, 49152, 45056, 47104, 48128, 48136,     0, 
+        1, 49152, 45056, 47104, 48128, 48144, 48140,     0, 
+        1, 49152, 45056, 47104, 48128, 48144, 48140,     0, 
+        1, 49152, 45056, 47104, 48128, 48144, 48145, 48142, 
+        0,     1, 49152, 45056, 47104, 48128,     0,     1, 
+    49152, 45056, 47104, 48128, 48144,     0,     1, 49152, 
+    45056, 47104, 48128, 48144,     0,     1, 49152, 45056, 
+    47104, 48128, 48144, 48146,     0,     1, 49152, 45056, 
+    47104, 48128, 48144,     0,     1, 49152, 45056, 47104, 
+    48128, 48144, 48148,     0,     1, 49152, 45056, 47104, 
+    48128, 48144, 48148,     0,     1, 49152, 45056, 47104, 
+    48128, 48144, 48152, 48150,     0,     1, 49152, 45056, 
+    47104, 48128, 48144,     0,     1, 49152, 45056, 47104, 
+    48128, 48160, 48152,     0,     1, 49152, 45056, 47104, 
+    48128, 48160, 48152,     0,     1, 49152, 45056, 47104, 
+    48128, 48160, 48152, 48154,     0,     1, 49152, 45056, 
+    47104, 48128, 48160, 48152,     0,     1, 49152, 45056, 
+    47104, 48128, 48160, 48161, 48156,     0,     1, 49152, 
+    45056, 47104, 48128, 48160, 48161, 48156,     0,     1, 
+    49152, 45056, 47104, 48128, 48160, 48161, 48156, 48158, 
+        0,     1, 49152, 45056, 47104, 48128,     0,     1, 
+    49152, 45056, 47104, 48128, 48160,     0,     1, 49152, 
+    45056, 47104, 48128, 48160,     0,     1, 49152, 45056, 
+    47104, 48128, 48160, 48162,     0,     1, 49152, 45056, 
+    47104, 48128, 48160,     0,     1, 49152, 45056, 47104, 
+    48128, 48160, 48164,     0,     1, 49152, 45056, 47104, 
+    48128, 48160, 48164,     0,     1, 49152, 45056, 47104, 
+    48128, 48160, 48168, 48166,     0,     1, 49152, 45056, 
+    47104, 48128, 48160,     0,     1, 49152, 45056, 47104, 
+    48128, 48160, 48168,     0,     1, 49152, 45056, 47104, 
+    48128, 48160, 48168,     0,     1, 49152, 45056, 47104, 
+    48128, 48160, 48168, 48170,     0,     1, 49152, 45056, 
+    47104, 48128, 48160, 48168,     0,     1, 49152, 45056, 
+    47104, 48128, 48160, 48176, 48172,     0,     1, 49152, 
+    45056, 47104, 48128, 48160, 48176, 48172,     0,     1, 
+    49152, 45056, 47104, 48128, 48160, 48176, 48177, 48174, 
+        0,     1, 49152, 45056, 47104, 48128, 48160,     0, 
+        1, 49152, 45056, 47104, 48128, 48192, 48176,     0, 
+        1, 49152, 45056, 47104, 48128, 48192, 48176,     0, 
+        1, 49152, 45056, 47104, 48128, 48192, 48176, 48178, 
+        0,     1, 49152, 45056, 47104, 48128, 48192, 48176, 
+        0,     1, 49152, 45056, 47104, 48128, 48192, 48176, 
+    48180,     0,     1, 49152, 45056, 47104, 48128, 48192, 
+    48176, 48180,     0,     1, 49152, 45056, 47104, 48128, 
+    48192, 48176, 48184, 48182,     0,     1, 49152, 45056, 
+    47104, 48128, 48192, 48176,     0,     1, 49152, 45056, 
+    47104, 48128, 48192, 48193, 48184,     0,     1, 49152, 
+    45056, 47104, 48128, 48192, 48193, 48184,     0,     1, 
+    49152, 45056, 47104, 48128, 48192, 48193, 48184, 48186, 
+        0,     1, 49152, 45056, 47104, 48128, 48192, 48193, 
+    48184,     0,     1, 49152, 45056, 47104, 48128, 48192, 
+    48193, 48184, 48188,     0,     1, 49152, 45056, 47104, 
+    48128, 48192, 48193, 48195, 48188,     0,     1, 49152, 
+    45056, 47104, 48128, 48192, 48193, 48195, 48188, 48190, 
+        0,     1, 49152, 45056, 47104, 48128,     0,     1, 
+    49152, 45056, 47104, 48128, 48192,     0,     1, 49152, 
+    49153, 47104, 48128, 48192,     0,     1, 49152, 49153, 
+    47104, 48128, 48192, 48194,     0,     1, 49152, 49153, 
+    47104, 48128, 48192,     0,     1, 49152, 49153, 47104, 
+    48128, 48192, 48196,     0,     1, 49152, 49153, 47104, 
+    48128, 48192, 48196,     0,     1, 49152, 49153, 47104, 
+    48128, 48192, 48200, 48198,     0,     1, 49152, 49153, 
+    47104, 48128, 48192,     0,     1, 49152, 49153, 47104, 
+    48128, 48192, 48200,     0,     1, 49152, 49153, 47104, 
+    48128, 48192, 48200,     0,     1, 49152, 49153, 47104, 
+    48128, 48192, 48200, 48202,     0,     1, 49152, 49153, 
+    47104, 48128, 48192, 48200,     0,     1, 49152, 49153, 
+    47104, 48128, 48192, 48208, 48204,     0,     1, 49152, 
+    49153, 47104, 48128, 48192, 48208, 48204,     0,     1, 
+    49152, 49153, 47104, 48128, 48192, 48208, 48209, 48206, 
+        0,     1, 49152, 49153, 47104, 48128, 48192,     0, 
+        1, 49152, 49153, 47104, 48128, 48192, 48208,     0, 
+        1, 49152, 49153, 47104, 48128, 48192, 48208,     0, 
+        1, 49152, 49153, 47104, 48128, 48192, 48208, 48210, 
+        0,     1, 49152, 49153, 47104, 48128, 48192, 48208, 
+        0,     1, 49152, 49153, 47104, 48128, 48192, 48208, 
+    48212,     0,     1, 49152, 49153, 47104, 48128, 48192, 
+    48208, 48212,     0,     1, 49152, 49153, 47104, 48128, 
+    48192, 48208, 48216, 48214,     0,     1, 49152, 49153, 
+    47104, 48128, 48192, 48208,     0,     1, 49152, 49153, 
+    47104, 48128, 48192, 48224, 48216,     0,     1, 49152, 
+    49153, 47104, 48128, 48192, 48224, 48216,     0,     1, 
+    49152, 49153, 47104, 48128, 48192, 48224, 48216, 48218, 
+        0,     1, 49152, 49153, 47104, 48128, 48192, 48224, 
+    48216,     0,     1, 49152, 49153, 47104, 48128, 48192, 
+    48224, 48225, 48220,     0,     1, 49152, 49153, 47104, 
+    48128, 48192, 48224, 48225, 48220,     0,     1, 49152, 
+    49153, 47104, 48128, 48192, 48224, 48225, 48220, 48222, 
+        0,     1, 49152, 49153, 47104, 48128, 48192,     0, 
+        1, 49152, 49153, 47104, 48128, 48256, 48224,     0, 
+        1, 49152, 49153, 47104, 48128, 48256, 48224,     0, 
+        1, 49152, 49153, 47104, 48128, 48256, 48224, 48226, 
+        0,     1, 49152, 49153, 47104, 48128, 48256, 48224, 
+        0,     1, 49152, 49153, 47104, 48128, 48256, 48224, 
+    48228,     0,     1, 49152, 49153, 47104, 48128, 48256, 
+    48224, 48228,     0,     1, 49152, 49153, 47104, 48128, 
+    48256, 48224, 48232, 48230,     0,     1, 49152, 49153, 
+    47104, 48128, 48256, 48224,     0,     1, 49152, 49153, 
+    47104, 48128, 48256, 48224, 48232,     0,     1, 49152, 
+    49153, 47104, 48128, 48256, 48224, 48232,     0,     1, 
+    49152, 49153, 47104, 48128, 48256, 48224, 48232, 48234, 
+        0,     1, 49152, 49153, 47104, 48128, 48256, 48224, 
+    48232,     0,     1, 49152, 49153, 47104, 48128, 48256, 
+    48224, 48240, 48236,     0,     1, 49152, 49153, 47104, 
+    48128, 48256, 48224, 48240, 48236,     0,     1, 49152, 
+    49153, 47104, 48128, 48256, 48224, 48240, 48241, 48238, 
+        0,     1, 49152, 49153, 47104, 48128, 48256, 48224, 
+        0,     1, 49152, 49153, 47104, 48128, 48256, 48257, 
+    48240,     0,     1, 49152, 49153, 47104, 48128, 48256, 
+    48257, 48240,     0,     1, 49152, 49153, 47104, 48128, 
+    48256, 48257, 48240, 48242,     0,     1, 49152, 49153, 
+    47104, 48128, 48256, 48257, 48240,     0,     1, 49152, 
+    49153, 47104, 48128, 48256, 48257, 48240, 48244,     0, 
+        1, 49152, 49153, 47104, 48128, 48256, 48257, 48240, 
+    48244,     0,     1, 49152, 49153, 47104, 48128, 48256, 
+    48257, 48240, 48248, 48246,     0,     1, 49152, 49153, 
+    47104, 48128, 48256, 48257, 48240,     0,     1, 49152, 
+    49153, 47104, 48128, 48256, 48257, 48240, 48248,     0, 
+        1, 49152, 49153, 47104, 48128, 48256, 48257, 48259, 
+    48248,     0,     1, 49152, 49153, 47104, 48128, 48256, 
+    48257, 48259, 48248, 48250,     0,     1, 49152, 49153, 
+    47104, 48128, 48256, 48257, 48259, 48248,     0,     1, 
+    49152, 49153, 47104, 48128, 48256, 48257, 48259, 48248, 
+    48252,     0,     1, 49152, 49153, 47104, 48128, 48256, 
+    48257, 48259, 48248, 48252,     0,     1, 49152, 49153, 
+    47104, 48128, 48256, 48257, 48259, 48248, 48252, 48254, 
+        0,     1, 49152, 49153, 47104, 48128,     0,     1, 
+    49152, 49153, 47104, 48128, 48256,     0,     1, 49152, 
+    49153, 47104, 48128, 48256,     0,     1, 49152, 49153, 
+    47104, 48128, 48256, 48258,     0,     1, 49152, 49153, 
+    47104, 48128, 48256,     0,     1, 49152, 49153, 47104, 
+    48128, 48256, 48260,     0,     1, 49152, 49153, 47104, 
+    48128, 48256, 48260,     0,     1, 49152, 49153, 47104, 
+    48128, 48256, 48264, 48262,     0,     1, 49152, 49153, 
+    47104, 48128, 48256,     0,     1, 49152, 49153, 47104, 
+    48128, 48256, 48264,     0,     1, 49152, 49153, 47104, 
+    48128, 48256, 48264,     0,     1, 49152, 49153, 47104, 
+    48128, 48256, 48264, 48266,     0,     1, 49152, 49153, 
+    47104, 48128, 48256, 48264,     0,     1, 49152, 49153, 
+    47104, 48128, 48256, 48272, 48268,     0,     1, 49152, 
+    49153, 47104, 48128, 48256, 48272, 48268,     0,     1, 
+    49152, 49153, 47104, 48128, 48256, 48272, 48273, 48270, 
+        0,     1, 49152, 49153, 47104, 48128, 48256,     0, 
+        1, 49152, 49153, 47104, 48128, 48256, 48272,     0, 
+        1, 49152, 49153, 47104, 48128, 48256, 48272,     0, 
+        1, 49152, 49153, 47104, 48128, 48256, 48272, 48274, 
+        0,     1, 49152, 49153, 47104, 48128, 48256, 48272, 
+        0,     1, 49152, 49153, 47104, 48128, 48256, 48272, 
+    48276,     0,     1, 49152, 49153, 47104, 48128, 48256, 
+    48272, 48276,     0,     1, 49152, 49153, 47104, 48128, 
+    48256, 48272, 48280, 48278,     0,     1, 49152, 49153, 
+    47104, 48128, 48256, 48272,     0,     1, 49152, 49153, 
+    47104, 48128, 48256, 48288, 48280,     0,     1, 49152, 
+    49153, 47104, 48128, 48256, 48288, 48280,     0,     1, 
+    49152, 49153, 47104, 48128, 48256, 48288, 48280, 48282, 
+        0,     1, 49152, 49153, 47104, 48128, 48256, 48288, 
+    48280,     0,     1, 49152, 49153, 47104, 48128, 48256, 
+    48288, 48289, 48284,     0,     1, 49152, 49153, 47104, 
+    48128, 48256, 48288, 48289, 48284,     0,     1, 49152, 
+    49153, 47104, 48128, 48256, 48288, 48289, 48284, 48286, 
+        0,     1, 49152, 49153, 47104, 48128, 48256,     0, 
+        1, 49152, 49153, 47104, 48128, 48256, 48288,     0, 
+        1, 49152, 49153, 47104, 48128, 48256, 48288,     0, 
+        1, 49152, 49153, 47104, 48128, 48256, 48288, 48290, 
+        0,     1, 49152, 49153, 47104, 48128, 48256, 48288, 
+        0,     1, 49152, 49153, 47104, 48128, 48256, 48288, 
+    48292,     0,     1, 49152, 49153, 47104, 48128, 48256, 
+    48288, 48292,     0,     1, 49152, 49153, 47104, 48128, 
+    48256, 48288, 48296, 48294,     0,     1, 49152, 49153, 
+    47104, 48128, 48256, 48288,     0,     1, 49152, 49153, 
+    47104, 48128, 48256, 48288, 48296,     0,     1, 49152, 
+    49153, 47104, 48128, 48256, 48288, 48296,     0,     1, 
+    49152, 49153, 47104, 48128, 48256, 48288, 48296, 48298, 
+        0,     1, 49152, 49153, 47104, 48128, 48256, 48288, 
+    48296,     0,     1, 49152, 49153, 47104, 48128, 48256, 
+    48288, 48304, 48300,     0,     1, 49152, 49153, 47104, 
+    48128, 48256, 48288, 48304, 48300,     0,     1, 49152, 
+    49153, 47104, 48128, 48256, 48288, 48304, 48305, 48302, 
+        0,     1, 49152, 49153, 47104, 48128, 48256, 48288, 
+        0,     1, 49152, 49153, 47104, 48128, 48256, 48320, 
+    48304,     0,     1, 49152, 49153, 47104, 48128, 48256, 
+    48320, 48304,     0,     1, 49152, 49153, 47104, 48128, 
+    48256, 48320, 48304, 48306,     0,     1, 49152, 49153, 
+    47104, 48128, 48256, 48320, 48304,     0,     1, 49152, 
+    49153, 47104, 48128, 48256, 48320, 48304, 48308,     0, 
+        1, 49152, 49153, 47104, 48128, 48256, 48320, 48304, 
+    48308,     0,     1, 49152, 49153, 47104, 48128, 48256, 
+    48320, 48304, 48312, 48310,     0,     1, 49152, 49153, 
+    47104, 48128, 48256, 48320, 48304,     0,     1, 49152, 
+    49153, 47104, 48128, 48256, 48320, 48321, 48312,     0, 
+        1, 49152, 49153, 47104, 48128, 48256, 48320, 48321, 
+    48312,     0,     1, 49152, 49153, 47104, 48128, 48256, 
+    48320, 48321, 48312, 48314,     0,     1, 49152, 49153, 
+    47104, 48128, 48256, 48320, 48321, 48312,     0,     1, 
+    49152, 49153, 47104, 48128, 48256, 48320, 48321, 48312, 
+    48316,     0,     1, 49152, 49153, 47104, 48128, 48256, 
+    48320, 48321, 48323, 48316,     0,     1, 49152, 49153, 
+    47104, 48128, 48256, 48320, 48321, 48323, 48316, 48318, 
+        0,     1, 49152, 49153, 47104, 48128, 48256,     0, 
+        1, 49152, 49153, 47104, 48128, 48384, 48320,     0, 
+        1, 49152, 49153, 47104, 48128, 48384, 48320,     0, 
+        1, 49152, 49153, 47104, 48128, 48384, 48320, 48322, 
+        0,     1, 49152, 49153, 47104, 48128, 48384, 48320, 
+        0,     1, 49152, 49153, 47104, 48128, 48384, 48320, 
+    48324,     0,     1, 49152, 49153, 47104, 48128, 48384, 
+    48320, 48324,     0,     1, 49152, 49153, 47104, 48128, 
+    48384, 48320, 48328, 48326,     0,     1, 49152, 49153, 
+    47104, 48128, 48384, 48320,     0,     1, 49152, 49153, 
+    47104, 48128, 48384, 48320, 48328,     0,     1, 49152, 
+    49153, 47104, 48128, 48384, 48320, 48328,     0,     1, 
+    49152, 49153, 47104, 48128, 48384, 48320, 48328, 48330, 
+        0,     1, 49152, 49153, 47104, 48128, 48384, 48320, 
+    48328,     0,     1, 49152, 49153, 47104, 48128, 48384, 
+    48320, 48336, 48332,     0,     1, 49152, 49153, 47104, 
+    48128, 48384, 48320, 48336, 48332,     0,     1, 49152, 
+    49153, 47104, 48128, 48384, 48320, 48336, 48337, 48334, 
+        0,     1, 49152, 49153, 47104, 48128, 48384, 48320, 
+        0,     1, 49152, 49153, 47104, 48128, 48384, 48320, 
+    48336,     0,     1, 49152, 49153, 47104, 48128, 48384, 
+    48320, 48336,     0,     1, 49152, 49153, 47104, 48128, 
+    48384, 48320, 48336, 48338,     0,     1, 49152, 49153, 
+    47104, 48128, 48384, 48320, 48336,     0,     1, 49152, 
+    49153, 47104, 48128, 48384, 48320, 48336, 48340,     0, 
+        1, 49152, 49153, 47104, 48128, 48384, 48320, 48336, 
+    48340,     0,     1, 49152, 49153, 47104, 48128, 48384, 
+    48320, 48336, 48344, 48342,     0,     1, 49152, 49153, 
+    47104, 48128, 48384, 48320, 48336,     0,     1, 49152, 
+    49153, 47104, 48128, 48384, 48320, 48352, 48344,     0, 
+        1, 49152, 49153, 47104, 48128, 48384, 48320, 48352, 
+    48344,     0,     1, 49152, 49153, 47104, 48128, 48384, 
+    48320, 48352, 48344, 48346,     0,     1, 49152, 49153, 
+    47104, 48128, 48384, 48320, 48352, 48344,     0,     1, 
+    49152, 49153, 47104, 48128, 48384, 48320, 48352, 48353, 
+    48348,     0,     1, 49152, 49153, 47104, 48128, 48384, 
+    48320, 48352, 48353, 48348,     0,     1, 49152, 49153, 
+    47104, 48128, 48384, 48320, 48352, 48353, 48348, 48350, 
+        0,     1, 49152, 49153, 47104, 48128, 48384, 48320, 
+        0,     1, 49152, 49153, 47104, 48128, 48384, 48385, 
+    48352,     0,     1, 49152, 49153, 47104, 48128, 48384, 
+    48385, 48352,     0,     1, 49152, 49153, 47104, 48128, 
+    48384, 48385, 48352, 48354,     0,     1, 49152, 49153, 
+    47104, 48128, 48384, 48385, 48352,     0,     1, 49152, 
+    49153, 47104, 48128, 48384, 48385, 48352, 48356,     0, 
+        1, 49152, 49153, 47104, 48128, 48384, 48385, 48352, 
+    48356,     0,     1, 49152, 49153, 47104, 48128, 48384, 
+    48385, 48352, 48360, 48358,     0,     1, 49152, 49153, 
+    47104, 48128, 48384, 48385, 48352,     0,     1, 49152, 
+    49153, 47104, 48128, 48384, 48385, 48352, 48360,     0, 
+        1, 49152, 49153, 47104, 48128, 48384, 48385, 48352, 
+    48360,     0,     1, 49152, 49153, 47104, 48128, 48384, 
+    48385, 48352, 48360, 48362,     0,     1, 49152, 49153, 
+    47104, 48128, 48384, 48385, 48352, 48360,     0,     1, 
+    49152, 49153, 47104, 48128, 48384, 48385, 48352, 48368, 
+    48364,     0,     1, 49152, 49153, 47104, 48128, 48384, 
+    48385, 48352, 48368, 48364,     0,     1, 49152, 49153, 
+    47104, 48128, 48384, 48385, 48352, 48368, 48369, 48366, 
+        0,     1, 49152, 49153, 47104, 48128, 48384, 48385, 
+    48352,     0,     1, 49152, 49153, 47104, 48128, 48384, 
+    48385, 48352, 48368,     0,     1, 49152, 49153, 47104, 
+    48128, 48384, 48385, 48387, 48368,     0,     1, 49152, 
+    49153, 47104, 48128, 48384, 48385, 48387, 48368, 48370, 
+        0,     1, 49152, 49153, 47104, 48128, 48384, 48385, 
+    48387, 48368,     0,     1, 49152, 49153, 47104, 48128, 
+    48384, 48385, 48387, 48368, 48372,     0,     1, 49152, 
+    49153, 47104, 48128, 48384, 48385, 48387, 48368, 48372, 
+        0,     1, 49152, 49153, 47104, 48128, 48384, 48385, 
+    48387, 48368, 48376, 48374,     0,     1, 49152, 49153, 
+    47104, 48128, 48384, 48385, 48387, 48368,     0,     1, 
+    49152, 49153, 47104, 48128, 48384, 48385, 48387, 48368, 
+    48376,     0,     1, 49152, 49153, 47104, 48128, 48384, 
+    48385, 48387, 48368, 48376,     0,     1, 49152, 49153, 
+    47104, 48128, 48384, 48385, 48387, 48368, 48376, 48378, 
+        0,     1, 49152, 49153, 47104, 48128, 48384, 48385, 
+    48387, 48391, 48376,     0,     1, 49152, 49153, 47104, 
+    48128, 48384, 48385, 48387, 48391, 48376, 48380,     0, 
+        1, 49152, 49153, 47104, 48128, 48384, 48385, 48387, 
+    48391, 48376, 48380,     0,     1, 49152, 49153, 47104, 
+    48128, 48384, 48385, 48387, 48391, 48376, 48380, 48382, 
+        0,     1, 49152, 49153, 47104, 48128,     0,     1, 
+    49152, 49153, 47104, 48128, 48384,     0,     1, 49152, 
+    49153, 47104, 48128, 48384,     0,     1, 49152, 49153, 
+    47104, 48128, 48384, 48386,     0,     1, 49152, 49153, 
+    49155, 48128, 48384,     0,     1, 49152, 49153, 49155, 
+    48128, 48384, 48388,     0,     1, 49152, 49153, 49155, 
+    48128, 48384, 48388,     0,     1, 49152, 49153, 49155, 
+    48128, 48384, 48392, 48390,     0,     1, 49152, 49153, 
+    49155, 48128, 48384,     0,     1, 49152, 49153, 49155, 
+    48128, 48384, 48392,     0,     1, 49152, 49153, 49155, 
+    48128, 48384, 48392,     0,     1, 49152, 49153, 49155, 
+    48128, 48384, 48392, 48394,     0,     1, 49152, 49153, 
+    49155, 48128, 48384, 48392,     0,     1, 49152, 49153, 
+    49155, 48128, 48384, 48400, 48396,     0,     1, 49152, 
+    49153, 49155, 48128, 48384, 48400, 48396,     0,     1, 
+    49152, 49153, 49155, 48128, 48384, 48400, 48401, 48398, 
+        0,     1, 49152, 49153, 49155, 48128, 48384,     0, 
+        1, 49152, 49153, 49155, 48128, 48384, 48400,     0, 
+        1, 49152, 49153, 49155, 48128, 48384, 48400,     0, 
+        1, 49152, 49153, 49155, 48128, 48384, 48400, 48402, 
+        0,     1, 49152, 49153, 49155, 48128, 48384, 48400, 
+        0,     1, 49152, 49153, 49155, 48128, 48384, 48400, 
+    48404,     0,     1, 49152, 49153, 49155, 48128, 48384, 
+    48400, 48404,     0,     1, 49152, 49153, 49155, 48128, 
+    48384, 48400, 48408, 48406,     0,     1, 49152, 49153, 
+    49155, 48128, 48384, 48400,     0,     1, 49152, 49153, 
+    49155, 48128, 48384, 48416, 48408,     0,     1, 49152, 
+    49153, 49155, 48128, 48384, 48416, 48408,     0,     1, 
+    49152, 49153, 49155, 48128, 48384, 48416, 48408, 48410, 
+        0,     1, 49152, 49153, 49155, 48128, 48384, 48416, 
+    48408,     0,     1, 49152, 49153, 49155, 48128, 48384, 
+    48416, 48417, 48412,     0,     1, 49152, 49153, 49155, 
+    48128, 48384, 48416, 48417, 48412,     0,     1, 49152, 
+    49153, 49155, 48128, 48384, 48416, 48417, 48412, 48414, 
+        0,     1, 49152, 49153, 49155, 48128, 48384,     0, 
+        1, 49152, 49153, 49155, 48128, 48384, 48416,     0, 
+        1, 49152, 49153, 49155, 48128, 48384, 48416,     0, 
+        1, 49152, 49153, 49155, 48128, 48384, 48416, 48418, 
+        0,     1, 49152, 49153, 49155, 48128, 48384, 48416, 
+        0,     1, 49152, 49153, 49155, 48128, 48384, 48416, 
+    48420,     0,     1, 49152, 49153, 49155, 48128, 48384, 
+    48416, 48420,     0,     1, 49152, 49153, 49155, 48128, 
+    48384, 48416, 48424, 48422,     0,     1, 49152, 49153, 
+    49155, 48128, 48384, 48416,     0,     1, 49152, 49153, 
+    49155, 48128, 48384, 48416, 48424,     0,     1, 49152, 
+    49153, 49155, 48128, 48384, 48416, 48424,     0,     1, 
+    49152, 49153, 49155, 48128, 48384, 48416, 48424, 48426, 
+        0,     1, 49152, 49153, 49155, 48128, 48384, 48416, 
+    48424,     0,     1, 49152, 49153, 49155, 48128, 48384, 
+    48416, 48432, 48428,     0,     1, 49152, 49153, 49155, 
+    48128, 48384, 48416, 48432, 48428,     0,     1, 49152, 
+    49153, 49155, 48128, 48384, 48416, 48432, 48433, 48430, 
+        0,     1, 49152, 49153, 49155, 48128, 48384, 48416, 
+        0,     1, 49152, 49153, 49155, 48128, 48384, 48448, 
+    48432,     0,     1, 49152, 49153, 49155, 48128, 48384, 
+    48448, 48432,     0,     1, 49152, 49153, 49155, 48128, 
+    48384, 48448, 48432, 48434,     0,     1, 49152, 49153, 
+    49155, 48128, 48384, 48448, 48432,     0,     1, 49152, 
+    49153, 49155, 48128, 48384, 48448, 48432, 48436,     0, 
+        1, 49152, 49153, 49155, 48128, 48384, 48448, 48432, 
+    48436,     0,     1, 49152, 49153, 49155, 48128, 48384, 
+    48448, 48432, 48440, 48438,     0,     1, 49152, 49153, 
+    49155, 48128, 48384, 48448, 48432,     0,     1, 49152, 
+    49153, 49155, 48128, 48384, 48448, 48449, 48440,     0, 
+        1, 49152, 49153, 49155, 48128, 48384, 48448, 48449, 
+    48440,     0,     1, 49152, 49153, 49155, 48128, 48384, 
+    48448, 48449, 48440, 48442,     0,     1, 49152, 49153, 
+    49155, 48128, 48384, 48448, 48449, 48440,     0,     1, 
+    49152, 49153, 49155, 48128, 48384, 48448, 48449, 48440, 
+    48444,     0,     1, 49152, 49153, 49155, 48128, 48384, 
+    48448, 48449, 48451, 48444,     0,     1, 49152, 49153, 
+    49155, 48128, 48384, 48448, 48449, 48451, 48444, 48446, 
+        0,     1, 49152, 49153, 49155, 48128, 48384,     0, 
+        1, 49152, 49153, 49155, 48128, 48384, 48448,     0, 
+        1, 49152, 49153, 49155, 48128, 48384, 48448,     0, 
+        1, 49152, 49153, 49155, 48128, 48384, 48448, 48450, 
+        0,     1, 49152, 49153, 49155, 48128, 48384, 48448, 
+        0,     1, 49152, 49153, 49155, 48128, 48384, 48448, 
+    48452,     0,     1, 49152, 49153, 49155, 48128, 48384, 
+    48448, 48452,     0,     1, 49152, 49153, 49155, 48128, 
+    48384, 48448, 48456, 48454,     0,     1, 49152, 49153, 
+    49155, 48128, 48384, 48448,     0,     1, 49152, 49153, 
+    49155, 48128, 48384, 48448, 48456,     0,     1, 49152, 
+    49153, 49155, 48128, 48384, 48448, 48456,     0,     1, 
+    49152, 49153, 49155, 48128, 48384, 48448, 48456, 48458, 
+        0,     1, 49152, 49153, 49155, 48128, 48384, 48448, 
+    48456,     0,     1, 49152, 49153, 49155, 48128, 48384, 
+    48448, 48464, 48460,     0,     1, 49152, 49153, 49155, 
+    48128, 48384, 48448, 48464, 48460,     0,     1, 49152, 
+    49153, 49155, 48128, 48384, 48448, 48464, 48465, 48462, 
+        0,     1, 49152, 49153, 49155, 48128, 48384, 48448, 
+        0,     1, 49152, 49153, 49155, 48128, 48384, 48448, 
+    48464,     0,     1, 49152, 49153, 49155, 48128, 48384, 
+    48448, 48464,     0,     1, 49152, 49153, 49155, 48128, 
+    48384, 48448, 48464, 48466,     0,     1, 49152, 49153, 
+    49155, 48128, 48384, 48448, 48464,     0,     1, 49152, 
+    49153, 49155, 48128, 48384, 48448, 48464, 48468,     0, 
+        1, 49152, 49153, 49155, 48128, 48384, 48448, 48464, 
+    48468,     0,     1, 49152, 49153, 49155, 48128, 48384, 
+    48448, 48464, 48472, 48470,     0,     1, 49152, 49153, 
+    49155, 48128, 48384, 48448, 48464,     0,     1, 49152, 
+    49153, 49155, 48128, 48384, 48448, 48480, 48472,     0, 
+        1, 49152, 49153, 49155, 48128, 48384, 48448, 48480, 
+    48472,     0,     1, 49152, 49153, 49155, 48128, 48384, 
+    48448, 48480, 48472, 48474,     0,     1, 49152, 49153, 
+    49155, 48128, 48384, 48448, 48480, 48472,     0,     1, 
+    49152, 49153, 49155, 48128, 48384, 48448, 48480, 48481, 
+    48476,     0,     1, 49152, 49153, 49155, 48128, 48384, 
+    48448, 48480, 48481, 48476,     0,     1, 49152, 49153, 
+    49155, 48128, 48384, 48448, 48480, 48481, 48476, 48478, 
+        0,     1, 49152, 49153, 49155, 48128, 48384, 48448, 
+        0,     1, 49152, 49153, 49155, 48128, 48384, 48512, 
+    48480,     0,     1, 49152, 49153, 49155, 48128, 48384, 
+    48512, 48480,     0,     1, 49152, 49153, 49155, 48128, 
+    48384, 48512, 48480, 48482,     0,     1, 49152, 49153, 
+    49155, 48128, 48384, 48512, 48480,     0,     1, 49152, 
+    49153, 49155, 48128, 48384, 48512, 48480, 48484,     0, 
+        1, 49152, 49153, 49155, 48128, 48384, 48512, 48480, 
+    48484,     0,     1, 49152, 49153, 49155, 48128, 48384, 
+    48512, 48480, 48488, 48486,     0,     1, 49152, 49153, 
+    49155, 48128, 48384, 48512, 48480,     0,     1, 49152, 
+    49153, 49155, 48128, 48384, 48512, 48480, 48488,     0, 
+        1, 49152, 49153, 49155, 48128, 48384, 48512, 48480, 
+    48488,     0,     1, 49152, 49153, 49155, 48128, 48384, 
+    48512, 48480, 48488, 48490,     0,     1, 49152, 49153, 
+    49155, 48128, 48384, 48512, 48480, 48488,     0,     1, 
+    49152, 49153, 49155, 48128, 48384, 48512, 48480, 48496, 
+    48492,     0,     1, 49152, 49153, 49155, 48128, 48384, 
+    48512, 48480, 48496, 48492,     0,     1, 49152, 49153, 
+    49155, 48128, 48384, 48512, 48480, 48496, 48497, 48494, 
+        0,     1, 49152, 49153, 49155, 48128, 48384, 48512, 
+    48480,     0,     1, 49152, 49153, 49155, 48128, 48384, 
+    48512, 48513, 48496,     0,     1, 49152, 49153, 49155, 
+    48128, 48384, 48512, 48513, 48496,     0,     1, 49152, 
+    49153, 49155, 48128, 48384, 48512, 48513, 48496, 48498, 
+        0,     1, 49152, 49153, 49155, 48128, 48384, 48512, 
+    48513, 48496,     0,     1, 49152, 49153, 49155, 48128, 
+    48384, 48512, 48513, 48496, 48500,     0,     1, 49152, 
+    49153, 49155, 48128, 48384, 48512, 48513, 48496, 48500, 
+        0,     1, 49152, 49153, 49155, 48128, 48384, 48512, 
+    48513, 48496, 48504, 48502,     0,     1, 49152, 49153, 
+    49155, 48128, 48384, 48512, 48513, 48496,     0,     1, 
+    49152, 49153, 49155, 48128, 48384, 48512, 48513, 48496, 
+    48504,     0,     1, 49152, 49153, 49155, 48128, 48384, 
+    48512, 48513, 48515, 48504,     0,     1, 49152, 49153, 
+    49155, 48128, 48384, 48512, 48513, 48515, 48504, 48506, 
+        0,     1, 49152, 49153, 49155, 48128, 48384, 48512, 
+    48513, 48515, 48504,     0,     1, 49152, 49153, 49155, 
+    48128, 48384, 48512, 48513, 48515, 48504, 48508,     0, 
+        1, 49152, 49153, 49155, 48128, 48384, 48512, 48513, 
+    48515, 48504, 48508,     0,     1, 49152, 49153, 49155, 
+    48128, 48384, 48512, 48513, 48515, 48504, 48508, 48510, 
+        0,     1, 49152, 49153, 49155, 48128, 48384,     0, 
+        1, 49152, 49153, 49155, 48128, 48640, 48512,     0, 
+        1, 49152, 49153, 49155, 48128, 48640, 48512,     0, 
+        1, 49152, 49153, 49155, 48128, 48640, 48512, 48514, 
+        0,     1, 49152, 49153, 49155, 48128, 48640, 48512, 
+        0,     1, 49152, 49153, 49155, 48128, 48640, 48512, 
+    48516,     0,     1, 49152, 49153, 49155, 48128, 48640, 
+    48512, 48516,     0,     1, 49152, 49153, 49155, 48128, 
+    48640, 48512, 48520, 48518,     0,     1, 49152, 49153, 
+    49155, 48128, 48640, 48512,     0,     1, 49152, 49153, 
+    49155, 48128, 48640, 48512, 48520,     0,     1, 49152, 
+    49153, 49155, 48128, 48640, 48512, 48520,     0,     1, 
+    49152, 49153, 49155, 48128, 48640, 48512, 48520, 48522, 
+        0,     1, 49152, 49153, 49155, 48128, 48640, 48512, 
+    48520,     0,     1, 49152, 49153, 49155, 48128, 48640, 
+    48512, 48528, 48524,     0,     1, 49152, 49153, 49155, 
+    48128, 48640, 48512, 48528, 48524,     0,     1, 49152, 
+    49153, 49155, 48128, 48640, 48512, 48528, 48529, 48526, 
+        0,     1, 49152, 49153, 49155, 48128, 48640, 48512, 
+        0,     1, 49152, 49153, 49155, 48128, 48640, 48512, 
+    48528,     0,     1, 49152, 49153, 49155, 48128, 48640, 
+    48512, 48528,     0,     1, 49152, 49153, 49155, 48128, 
+    48640, 48512, 48528, 48530,     0,     1, 49152, 49153, 
+    49155, 48128, 48640, 48512, 48528,     0,     1, 49152, 
+    49153, 49155, 48128, 48640, 48512, 48528, 48532,     0, 
+        1, 49152, 49153, 49155, 48128, 48640, 48512, 48528, 
+    48532,     0,     1, 49152, 49153, 49155, 48128, 48640, 
+    48512, 48528, 48536, 48534,     0,     1, 49152, 49153, 
+    49155, 48128, 48640, 48512, 48528,     0,     1, 49152, 
+    49153, 49155, 48128, 48640, 48512, 48544, 48536,     0, 
+        1, 49152, 49153, 49155, 48128, 48640, 48512, 48544, 
+    48536,     0,     1, 49152, 49153, 49155, 48128, 48640, 
+    48512, 48544, 48536, 48538,     0,     1, 49152, 49153, 
+    49155, 48128, 48640, 48512, 48544, 48536,     0,     1, 
+    49152, 49153, 49155, 48128, 48640, 48512, 48544, 48545, 
+    48540,     0,     1, 49152, 49153, 49155, 48128, 48640, 
+    48512, 48544, 48545, 48540,     0,     1, 49152, 49153, 
+    49155, 48128, 48640, 48512, 48544, 48545, 48540, 48542, 
+        0,     1, 49152, 49153, 49155, 48128, 48640, 48512, 
+        0,     1, 49152, 49153, 49155, 48128, 48640, 48512, 
+    48544,     0,     1, 49152, 49153, 49155, 48128, 48640, 
+    48512, 48544,     0,     1, 49152, 49153, 49155, 48128, 
+    48640, 48512, 48544, 48546,     0,     1, 49152, 49153, 
+    49155, 48128, 48640, 48512, 48544,     0,     1, 49152, 
+    49153, 49155, 48128, 48640, 48512, 48544, 48548,     0, 
+        1, 49152, 49153, 49155, 48128, 48640, 48512, 48544, 
+    48548,     0,     1, 49152, 49153, 49155, 48128, 48640, 
+    48512, 48544, 48552, 48550,     0,     1, 49152, 49153, 
+    49155, 48128, 48640, 48512, 48544,     0,     1, 49152, 
+    49153, 49155, 48128, 48640, 48512, 48544, 48552,     0, 
+        1, 49152, 49153, 49155, 48128, 48640, 48512, 48544, 
+    48552,     0,     1, 49152, 49153, 49155, 48128, 48640, 
+    48512, 48544, 48552, 48554,     0,     1, 49152, 49153, 
+    49155, 48128, 48640, 48512, 48544, 48552,     0,     1, 
+    49152, 49153, 49155, 48128, 48640, 48512, 48544, 48560, 
+    48556,     0,     1, 49152, 49153, 49155, 48128, 48640, 
+    48512, 48544, 48560, 48556,     0,     1, 49152, 49153, 
+    49155, 48128, 48640, 48512, 48544, 48560, 48561, 48558, 
+        0,     1, 49152, 49153, 49155, 48128, 48640, 48512, 
+    48544,     0,     1, 49152, 49153, 49155, 48128, 48640, 
+    48512, 48576, 48560,     0,     1, 49152, 49153, 49155, 
+    48128, 48640, 48512, 48576, 48560,     0,     1, 49152, 
+    49153, 49155, 48128, 48640, 48512, 48576, 48560, 48562, 
+        0,     1, 49152, 49153, 49155, 48128, 48640, 48512, 
+    48576, 48560,     0,     1, 49152, 49153, 49155, 48128, 
+    48640, 48512, 48576, 48560, 48564,     0,     1, 49152, 
+    49153, 49155, 48128, 48640, 48512, 48576, 48560, 48564, 
+        0,     1, 49152, 49153, 49155, 48128, 48640, 48512, 
+    48576, 48560, 48568, 48566,     0,     1, 49152, 49153, 
+    49155, 48128, 48640, 48512, 48576, 48560,     0,     1, 
+    49152, 49153, 49155, 48128, 48640, 48512, 48576, 48577, 
+    48568,     0,     1, 49152, 49153, 49155, 48128, 48640, 
+    48512, 48576, 48577, 48568,     0,     1, 49152, 49153, 
+    49155, 48128, 48640, 48512, 48576, 48577, 48568, 48570, 
+        0,     1, 49152, 49153, 49155, 48128, 48640, 48512, 
+    48576, 48577, 48568,     0,     1, 49152, 49153, 49155, 
+    48128, 48640, 48512, 48576, 48577, 48568, 48572,     0, 
+        1, 49152, 49153, 49155, 48128, 48640, 48512, 48576, 
+    48577, 48579, 48572,     0,     1, 49152, 49153, 49155, 
+    48128, 48640, 48512, 48576, 48577, 48579, 48572, 48574, 
+        0,     1, 49152, 49153, 49155, 48128, 48640, 48512, 
+        0,     1, 49152, 49153, 49155, 48128, 48640, 48641, 
+    48576,     0,     1, 49152, 49153, 49155, 48128, 48640, 
+    48641, 48576,     0,     1, 49152, 49153, 49155, 48128, 
+    48640, 48641, 48576, 48578,     0,     1, 49152, 49153, 
+    49155, 48128, 48640, 48641, 48576,     0,     1, 49152, 
+    49153, 49155, 48128, 48640, 48641, 48576, 48580,     0, 
+        1, 49152, 49153, 49155, 48128, 48640, 48641, 48576, 
+    48580,     0,     1, 49152, 49153, 49155, 48128, 48640, 
+    48641, 48576, 48584, 48582,     0,     1, 49152, 49153, 
+    49155, 48128, 48640, 48641, 48576,     0,     1, 49152, 
+    49153, 49155, 48128, 48640, 48641, 48576, 48584,     0, 
+        1, 49152, 49153, 49155, 48128, 48640, 48641, 48576, 
+    48584,     0,     1, 49152, 49153, 49155, 48128, 48640, 
+    48641, 48576, 48584, 48586,     0,     1, 49152, 49153, 
+    49155, 48128, 48640, 48641, 48576, 48584,     0,     1, 
+    49152, 49153, 49155, 48128, 48640, 48641, 48576, 48592, 
+    48588,     0,     1, 49152, 49153, 49155, 48128, 48640, 
+    48641, 48576, 48592, 48588,     0,     1, 49152, 49153, 
+    49155, 48128, 48640, 48641, 48576, 48592, 48593, 48590, 
+        0,     1, 49152, 49153, 49155, 48128, 48640, 48641, 
+    48576,     0,     1, 49152, 49153, 49155, 48128, 48640, 
+    48641, 48576, 48592,     0,     1, 49152, 49153, 49155, 
+    48128, 48640, 48641, 48576, 48592,     0,     1, 49152, 
+    49153, 49155, 48128, 48640, 48641, 48576, 48592, 48594, 
+        0,     1, 49152, 49153, 49155, 48128, 48640, 48641, 
+    48576, 48592,     0,     1, 49152, 49153, 49155, 48128, 
+    48640, 48641, 48576, 48592, 48596,     0,     1, 49152, 
+    49153, 49155, 48128, 48640, 48641, 48576, 48592, 48596, 
+        0,     1, 49152, 49153, 49155, 48128, 48640, 48641, 
+    48576, 48592, 48600, 48598,     0,     1, 49152, 49153, 
+    49155, 48128, 48640, 48641, 48576, 48592,     0,     1, 
+    49152, 49153, 49155, 48128, 48640, 48641, 48576, 48608, 
+    48600,     0,     1, 49152, 49153, 49155, 48128, 48640, 
+    48641, 48576, 48608, 48600,     0,     1, 49152, 49153, 
+    49155, 48128, 48640, 48641, 48576, 48608, 48600, 48602, 
+        0,     1, 49152, 49153, 49155, 48128, 48640, 48641, 
+    48576, 48608, 48600,     0,     1, 49152, 49153, 49155, 
+    48128, 48640, 48641, 48576, 48608, 48609, 48604,     0, 
+        1, 49152, 49153, 49155, 48128, 48640, 48641, 48576, 
+    48608, 48609, 48604,     0,     1, 49152, 49153, 49155, 
+    48128, 48640, 48641, 48576, 48608, 48609, 48604, 48606, 
+        0,     1, 49152, 49153, 49155, 48128, 48640, 48641, 
+    48576,     0,     1, 49152, 49153, 49155, 48128, 48640, 
+    48641, 48576, 48608,     0,     1, 49152, 49153, 49155, 
+    48128, 48640, 48641, 48643, 48608,     0,     1, 49152, 
+    49153, 49155, 48128, 48640, 48641, 48643, 48608, 48610, 
+        0,     1, 49152, 49153, 49155, 48128, 48640, 48641, 
+    48643, 48608,     0,     1, 49152, 49153, 49155, 48128, 
+    48640, 48641, 48643, 48608, 48612,     0,     1, 49152, 
+    49153, 49155, 48128, 48640, 48641, 48643, 48608, 48612, 
+        0,     1, 49152, 49153, 49155, 48128, 48640, 48641, 
+    48643, 48608, 48616, 48614,     0,     1, 49152, 49153, 
+    49155, 48128, 48640, 48641, 48643, 48608,     0,     1, 
+    49152, 49153, 49155, 48128, 48640, 48641, 48643, 48608, 
+    48616,     0,     1, 49152, 49153, 49155, 48128, 48640, 
+    48641, 48643, 48608, 48616,     0,     1, 49152, 49153, 
+    49155, 48128, 48640, 48641, 48643, 48608, 48616, 48618, 
+        0,     1, 49152, 49153, 49155, 48128, 48640, 48641, 
+    48643, 48608, 48616,     0,     1, 49152, 49153, 49155, 
+    48128, 48640, 48641, 48643, 48608, 48624, 48620,     0, 
+        1, 49152, 49153, 49155, 48128, 48640, 48641, 48643, 
+    48608, 48624, 48620,     0,     1, 49152, 49153, 49155, 
+    48128, 48640, 48641, 48643, 48608, 48624, 48625, 48622, 
+        0,     1, 49152, 49153, 49155, 48128, 48640, 48641, 
+    48643, 48608,     0,     1, 49152, 49153, 49155, 48128, 
+    48640, 48641, 48643, 48608, 48624,     0,     1, 49152, 
+    49153, 49155, 48128, 48640, 48641, 48643, 48608, 48624, 
+        0,     1, 49152, 49153, 49155, 48128, 48640, 48641, 
+    48643, 48608, 48624, 48626,     0,     1, 49152, 49153, 
+    49155, 48128, 48640, 48641, 48643, 48647, 48624,     0, 
+        1, 49152, 49153, 49155, 48128, 48640, 48641, 48643, 
+    48647, 48624, 48628,     0,     1, 49152, 49153, 49155, 
+    48128, 48640, 48641, 48643, 48647, 48624, 48628,     0, 
+        1, 49152, 49153, 49155, 48128, 48640, 48641, 48643, 
+    48647, 48624, 48632, 48630,     0,     1, 49152, 49153, 
+    49155, 48128, 48640, 48641, 48643, 48647, 48624,     0, 
+        1, 49152, 49153, 49155, 48128, 48640, 48641, 48643, 
+    48647, 48624, 48632,     0,     1, 49152, 49153, 49155, 
+    48128, 48640, 48641, 48643, 48647, 48624, 48632,     0, 
+        1, 49152, 49153, 49155, 48128, 48640, 48641, 48643, 
+    48647, 48624, 48632, 48634,     0,     1, 49152, 49153, 
+    49155, 48128, 48640, 48641, 48643, 48647, 48624, 48632, 
+        0,     1, 49152, 49153, 49155, 48128, 48640, 48641, 
+    48643, 48647, 48624, 48632, 48636,     0,     1, 49152, 
+    49153, 49155, 48128, 48640, 48641, 48643, 48647, 48624, 
+    48632, 48636,     0,     1, 49152, 49153, 49155, 48128, 
+    48640, 48641, 48643, 48647, 48624, 48632, 48636, 48638, 
+        0,     1, 49152, 49153, 49155, 48128,     0,     1, 
+    49152, 49153, 49155, 48128, 48640,     0,     1, 49152, 
+    49153, 49155, 48128, 48640,     0,     1, 49152, 49153, 
+    49155, 48128, 48640, 48642,     0,     1, 49152, 49153, 
+    49155, 48128, 48640,     0,     1, 49152, 49153, 49155, 
+    48128, 48640, 48644,     0,     1, 49152, 49153, 49155, 
+    48128, 48640, 48644,     0,     1, 49152, 49153, 49155, 
+    48128, 48640, 48648, 48646,     0,     1, 49152, 49153, 
+    49155, 49159, 48640,     0,     1, 49152, 49153, 49155, 
+    49159, 48640, 48648,     0,     1, 49152, 49153, 49155, 
+    49159, 48640, 48648,     0,     1, 49152, 49153, 49155, 
+    49159, 48640, 48648, 48650,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48648,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48656, 48652,     0,     1, 49152, 
+    49153, 49155, 49159, 48640, 48656, 48652,     0,     1, 
+    49152, 49153, 49155, 49159, 48640, 48656, 48657, 48654, 
+        0,     1, 49152, 49153, 49155, 49159, 48640,     0, 
+        1, 49152, 49153, 49155, 49159, 48640, 48656,     0, 
+        1, 49152, 49153, 49155, 49159, 48640, 48656,     0, 
+        1, 49152, 49153, 49155, 49159, 48640, 48656, 48658, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48656, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48656, 
+    48660,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48656, 48660,     0,     1, 49152, 49153, 49155, 49159, 
+    48640, 48656, 48664, 48662,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48656,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48672, 48664,     0,     1, 49152, 
+    49153, 49155, 49159, 48640, 48672, 48664,     0,     1, 
+    49152, 49153, 49155, 49159, 48640, 48672, 48664, 48666, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48672, 
+    48664,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48672, 48673, 48668,     0,     1, 49152, 49153, 49155, 
+    49159, 48640, 48672, 48673, 48668,     0,     1, 49152, 
+    49153, 49155, 49159, 48640, 48672, 48673, 48668, 48670, 
+        0,     1, 49152, 49153, 49155, 49159, 48640,     0, 
+        1, 49152, 49153, 49155, 49159, 48640, 48672,     0, 
+        1, 49152, 49153, 49155, 49159, 48640, 48672,     0, 
+        1, 49152, 49153, 49155, 49159, 48640, 48672, 48674, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48672, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48672, 
+    48676,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48672, 48676,     0,     1, 49152, 49153, 49155, 49159, 
+    48640, 48672, 48680, 48678,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48672,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48672, 48680,     0,     1, 49152, 
+    49153, 49155, 49159, 48640, 48672, 48680,     0,     1, 
+    49152, 49153, 49155, 49159, 48640, 48672, 48680, 48682, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48672, 
+    48680,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48672, 48688, 48684,     0,     1, 49152, 49153, 49155, 
+    49159, 48640, 48672, 48688, 48684,     0,     1, 49152, 
+    49153, 49155, 49159, 48640, 48672, 48688, 48689, 48686, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48672, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48704, 
+    48688,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48704, 48688,     0,     1, 49152, 49153, 49155, 49159, 
+    48640, 48704, 48688, 48690,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48704, 48688,     0,     1, 49152, 
+    49153, 49155, 49159, 48640, 48704, 48688, 48692,     0, 
+        1, 49152, 49153, 49155, 49159, 48640, 48704, 48688, 
+    48692,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48704, 48688, 48696, 48694,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48704, 48688,     0,     1, 49152, 
+    49153, 49155, 49159, 48640, 48704, 48705, 48696,     0, 
+        1, 49152, 49153, 49155, 49159, 48640, 48704, 48705, 
+    48696,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48704, 48705, 48696, 48698,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48704, 48705, 48696,     0,     1, 
+    49152, 49153, 49155, 49159, 48640, 48704, 48705, 48696, 
+    48700,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48704, 48705, 48707, 48700,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48704, 48705, 48707, 48700, 48702, 
+        0,     1, 49152, 49153, 49155, 49159, 48640,     0, 
+        1, 49152, 49153, 49155, 49159, 48640, 48704,     0, 
+        1, 49152, 49153, 49155, 49159, 48640, 48704,     0, 
+        1, 49152, 49153, 49155, 49159, 48640, 48704, 48706, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48704, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48704, 
+    48708,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48704, 48708,     0,     1, 49152, 49153, 49155, 49159, 
+    48640, 48704, 48712, 48710,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48704,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48704, 48712,     0,     1, 49152, 
+    49153, 49155, 49159, 48640, 48704, 48712,     0,     1, 
+    49152, 49153, 49155, 49159, 48640, 48704, 48712, 48714, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48704, 
+    48712,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48704, 48720, 48716,     0,     1, 49152, 49153, 49155, 
+    49159, 48640, 48704, 48720, 48716,     0,     1, 49152, 
+    49153, 49155, 49159, 48640, 48704, 48720, 48721, 48718, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48704, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48704, 
+    48720,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48704, 48720,     0,     1, 49152, 49153, 49155, 49159, 
+    48640, 48704, 48720, 48722,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48704, 48720,     0,     1, 49152, 
+    49153, 49155, 49159, 48640, 48704, 48720, 48724,     0, 
+        1, 49152, 49153, 49155, 49159, 48640, 48704, 48720, 
+    48724,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48704, 48720, 48728, 48726,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48704, 48720,     0,     1, 49152, 
+    49153, 49155, 49159, 48640, 48704, 48736, 48728,     0, 
+        1, 49152, 49153, 49155, 49159, 48640, 48704, 48736, 
+    48728,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48704, 48736, 48728, 48730,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48704, 48736, 48728,     0,     1, 
+    49152, 49153, 49155, 49159, 48640, 48704, 48736, 48737, 
+    48732,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48704, 48736, 48737, 48732,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48704, 48736, 48737, 48732, 48734, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48704, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48768, 
+    48736,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48768, 48736,     0,     1, 49152, 49153, 49155, 49159, 
+    48640, 48768, 48736, 48738,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48768, 48736,     0,     1, 49152, 
+    49153, 49155, 49159, 48640, 48768, 48736, 48740,     0, 
+        1, 49152, 49153, 49155, 49159, 48640, 48768, 48736, 
+    48740,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48768, 48736, 48744, 48742,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48768, 48736,     0,     1, 49152, 
+    49153, 49155, 49159, 48640, 48768, 48736, 48744,     0, 
+        1, 49152, 49153, 49155, 49159, 48640, 48768, 48736, 
+    48744,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48768, 48736, 48744, 48746,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48768, 48736, 48744,     0,     1, 
+    49152, 49153, 49155, 49159, 48640, 48768, 48736, 48752, 
+    48748,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48768, 48736, 48752, 48748,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48768, 48736, 48752, 48753, 48750, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48768, 
+    48736,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48768, 48769, 48752,     0,     1, 49152, 49153, 49155, 
+    49159, 48640, 48768, 48769, 48752,     0,     1, 49152, 
+    49153, 49155, 49159, 48640, 48768, 48769, 48752, 48754, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48768, 
+    48769, 48752,     0,     1, 49152, 49153, 49155, 49159, 
+    48640, 48768, 48769, 48752, 48756,     0,     1, 49152, 
+    49153, 49155, 49159, 48640, 48768, 48769, 48752, 48756, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48768, 
+    48769, 48752, 48760, 48758,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48768, 48769, 48752,     0,     1, 
+    49152, 49153, 49155, 49159, 48640, 48768, 48769, 48752, 
+    48760,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48768, 48769, 48771, 48760,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48768, 48769, 48771, 48760, 48762, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48768, 
+    48769, 48771, 48760,     0,     1, 49152, 49153, 49155, 
+    49159, 48640, 48768, 48769, 48771, 48760, 48764,     0, 
+        1, 49152, 49153, 49155, 49159, 48640, 48768, 48769, 
+    48771, 48760, 48764,     0,     1, 49152, 49153, 49155, 
+    49159, 48640, 48768, 48769, 48771, 48760, 48764, 48766, 
+        0,     1, 49152, 49153, 49155, 49159, 48640,     0, 
+        1, 49152, 49153, 49155, 49159, 48640, 48768,     0, 
+        1, 49152, 49153, 49155, 49159, 48640, 48768,     0, 
+        1, 49152, 49153, 49155, 49159, 48640, 48768, 48770, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48768, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48768, 
+    48772,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48768, 48772,     0,     1, 49152, 49153, 49155, 49159, 
+    48640, 48768, 48776, 48774,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48768,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48768, 48776,     0,     1, 49152, 
+    49153, 49155, 49159, 48640, 48768, 48776,     0,     1, 
+    49152, 49153, 49155, 49159, 48640, 48768, 48776, 48778, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48768, 
+    48776,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48768, 48784, 48780,     0,     1, 49152, 49153, 49155, 
+    49159, 48640, 48768, 48784, 48780,     0,     1, 49152, 
+    49153, 49155, 49159, 48640, 48768, 48784, 48785, 48782, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48768, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48768, 
+    48784,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48768, 48784,     0,     1, 49152, 49153, 49155, 49159, 
+    48640, 48768, 48784, 48786,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48768, 48784,     0,     1, 49152, 
+    49153, 49155, 49159, 48640, 48768, 48784, 48788,     0, 
+        1, 49152, 49153, 49155, 49159, 48640, 48768, 48784, 
+    48788,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48768, 48784, 48792, 48790,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48768, 48784,     0,     1, 49152, 
+    49153, 49155, 49159, 48640, 48768, 48800, 48792,     0, 
+        1, 49152, 49153, 49155, 49159, 48640, 48768, 48800, 
+    48792,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48768, 48800, 48792, 48794,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48768, 48800, 48792,     0,     1, 
+    49152, 49153, 49155, 49159, 48640, 48768, 48800, 48801, 
+    48796,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48768, 48800, 48801, 48796,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48768, 48800, 48801, 48796, 48798, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48768, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48768, 
+    48800,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48768, 48800,     0,     1, 49152, 49153, 49155, 49159, 
+    48640, 48768, 48800, 48802,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48768, 48800,     0,     1, 49152, 
+    49153, 49155, 49159, 48640, 48768, 48800, 48804,     0, 
+        1, 49152, 49153, 49155, 49159, 48640, 48768, 48800, 
+    48804,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48768, 48800, 48808, 48806,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48768, 48800,     0,     1, 49152, 
+    49153, 49155, 49159, 48640, 48768, 48800, 48808,     0, 
+        1, 49152, 49153, 49155, 49159, 48640, 48768, 48800, 
+    48808,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48768, 48800, 48808, 48810,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48768, 48800, 48808,     0,     1, 
+    49152, 49153, 49155, 49159, 48640, 48768, 48800, 48816, 
+    48812,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48768, 48800, 48816, 48812,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48768, 48800, 48816, 48817, 48814, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48768, 
+    48800,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48768, 48832, 48816,     0,     1, 49152, 49153, 49155, 
+    49159, 48640, 48768, 48832, 48816,     0,     1, 49152, 
+    49153, 49155, 49159, 48640, 48768, 48832, 48816, 48818, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48768, 
+    48832, 48816,     0,     1, 49152, 49153, 49155, 49159, 
+    48640, 48768, 48832, 48816, 48820,     0,     1, 49152, 
+    49153, 49155, 49159, 48640, 48768, 48832, 48816, 48820, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48768, 
+    48832, 48816, 48824, 48822,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48768, 48832, 48816,     0,     1, 
+    49152, 49153, 49155, 49159, 48640, 48768, 48832, 48833, 
+    48824,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48768, 48832, 48833, 48824,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48768, 48832, 48833, 48824, 48826, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48768, 
+    48832, 48833, 48824,     0,     1, 49152, 49153, 49155, 
+    49159, 48640, 48768, 48832, 48833, 48824, 48828,     0, 
+        1, 49152, 49153, 49155, 49159, 48640, 48768, 48832, 
+    48833, 48835, 48828,     0,     1, 49152, 49153, 49155, 
+    49159, 48640, 48768, 48832, 48833, 48835, 48828, 48830, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48768, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48896, 
+    48832,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48896, 48832,     0,     1, 49152, 49153, 49155, 49159, 
+    48640, 48896, 48832, 48834,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48896, 48832,     0,     1, 49152, 
+    49153, 49155, 49159, 48640, 48896, 48832, 48836,     0, 
+        1, 49152, 49153, 49155, 49159, 48640, 48896, 48832, 
+    48836,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48896, 48832, 48840, 48838,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48896, 48832,     0,     1, 49152, 
+    49153, 49155, 49159, 48640, 48896, 48832, 48840,     0, 
+        1, 49152, 49153, 49155, 49159, 48640, 48896, 48832, 
+    48840,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48896, 48832, 48840, 48842,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48896, 48832, 48840,     0,     1, 
+    49152, 49153, 49155, 49159, 48640, 48896, 48832, 48848, 
+    48844,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48896, 48832, 48848, 48844,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48896, 48832, 48848, 48849, 48846, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48896, 
+    48832,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48896, 48832, 48848,     0,     1, 49152, 49153, 49155, 
+    49159, 48640, 48896, 48832, 48848,     0,     1, 49152, 
+    49153, 49155, 49159, 48640, 48896, 48832, 48848, 48850, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48896, 
+    48832, 48848,     0,     1, 49152, 49153, 49155, 49159, 
+    48640, 48896, 48832, 48848, 48852,     0,     1, 49152, 
+    49153, 49155, 49159, 48640, 48896, 48832, 48848, 48852, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48896, 
+    48832, 48848, 48856, 48854,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48896, 48832, 48848,     0,     1, 
+    49152, 49153, 49155, 49159, 48640, 48896, 48832, 48864, 
+    48856,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48896, 48832, 48864, 48856,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48896, 48832, 48864, 48856, 48858, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48896, 
+    48832, 48864, 48856,     0,     1, 49152, 49153, 49155, 
+    49159, 48640, 48896, 48832, 48864, 48865, 48860,     0, 
+        1, 49152, 49153, 49155, 49159, 48640, 48896, 48832, 
+    48864, 48865, 48860,     0,     1, 49152, 49153, 49155, 
+    49159, 48640, 48896, 48832, 48864, 48865, 48860, 48862, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48896, 
+    48832,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48896, 48897, 48864,     0,     1, 49152, 49153, 49155, 
+    49159, 48640, 48896, 48897, 48864,     0,     1, 49152, 
+    49153, 49155, 49159, 48640, 48896, 48897, 48864, 48866, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48896, 
+    48897, 48864,     0,     1, 49152, 49153, 49155, 49159, 
+    48640, 48896, 48897, 48864, 48868,     0,     1, 49152, 
+    49153, 49155, 49159, 48640, 48896, 48897, 48864, 48868, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48896, 
+    48897, 48864, 48872, 48870,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48896, 48897, 48864,     0,     1, 
+    49152, 49153, 49155, 49159, 48640, 48896, 48897, 48864, 
+    48872,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48896, 48897, 48864, 48872,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48896, 48897, 48864, 48872, 48874, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48896, 
+    48897, 48864, 48872,     0,     1, 49152, 49153, 49155, 
+    49159, 48640, 48896, 48897, 48864, 48880, 48876,     0, 
+        1, 49152, 49153, 49155, 49159, 48640, 48896, 48897, 
+    48864, 48880, 48876,     0,     1, 49152, 49153, 49155, 
+    49159, 48640, 48896, 48897, 48864, 48880, 48881, 48878, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48896, 
+    48897, 48864,     0,     1, 49152, 49153, 49155, 49159, 
+    48640, 48896, 48897, 48864, 48880,     0,     1, 49152, 
+    49153, 49155, 49159, 48640, 48896, 48897, 48899, 48880, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48896, 
+    48897, 48899, 48880, 48882,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48896, 48897, 48899, 48880,     0, 
+        1, 49152, 49153, 49155, 49159, 48640, 48896, 48897, 
+    48899, 48880, 48884,     0,     1, 49152, 49153, 49155, 
+    49159, 48640, 48896, 48897, 48899, 48880, 48884,     0, 
+        1, 49152, 49153, 49155, 49159, 48640, 48896, 48897, 
+    48899, 48880, 48888, 48886,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48896, 48897, 48899, 48880,     0, 
+        1, 49152, 49153, 49155, 49159, 48640, 48896, 48897, 
+    48899, 48880, 48888,     0,     1, 49152, 49153, 49155, 
+    49159, 48640, 48896, 48897, 48899, 48880, 48888,     0, 
+        1, 49152, 49153, 49155, 49159, 48640, 48896, 48897, 
+    48899, 48880, 48888, 48890,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48896, 48897, 48899, 48903, 48888, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48896, 
+    48897, 48899, 48903, 48888, 48892,     0,     1, 49152, 
+    49153, 49155, 49159, 48640, 48896, 48897, 48899, 48903, 
+    48888, 48892,     0,     1, 49152, 49153, 49155, 49159, 
+    48640, 48896, 48897, 48899, 48903, 48888, 48892, 48894, 
+        0,     1, 49152, 49153, 49155, 49159, 48640,     0, 
+        1, 49152, 49153, 49155, 49159, 48640, 48896,     0, 
+        1, 49152, 49153, 49155, 49159, 48640, 48896,     0, 
+        1, 49152, 49153, 49155, 49159, 48640, 48896, 48898, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48896, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48896, 
+    48900,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48896, 48900,     0,     1, 49152, 49153, 49155, 49159, 
+    48640, 48896, 48904, 48902,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48896,     0,     1, 49152, 49153, 
+    49155, 49159, 48640, 48896, 48904,     0,     1, 49152, 
+    49153, 49155, 49159, 48640, 48896, 48904,     0,     1, 
+    49152, 49153, 49155, 49159, 48640, 48896, 48904, 48906, 
+        0,     1, 49152, 49153, 49155, 49159, 48640, 48896, 
+    48904,     0,     1, 49152, 49153, 49155, 49159, 48640, 
+    48896, 48912, 48908,     0,     1, 49152, 49153, 49155, 
+    49159, 48640, 48896, 48912, 48908,     0,     1, 49152, 
+    49153, 49155, 49159, 48640, 48896, 48912, 48913, 48910, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 48896, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 48896, 
+    48912,     0,     1, 49152, 49153, 49155, 49159, 49167, 
+    48896, 48912,     0,     1, 49152, 49153, 49155, 49159, 
+    49167, 48896, 48912, 48914,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 48896, 48912,     0,     1, 49152, 
+    49153, 49155, 49159, 49167, 48896, 48912, 48916,     0, 
+        1, 49152, 49153, 49155, 49159, 49167, 48896, 48912, 
+    48916,     0,     1, 49152, 49153, 49155, 49159, 49167, 
+    48896, 48912, 48920, 48918,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 48896, 48912,     0,     1, 49152, 
+    49153, 49155, 49159, 49167, 48896, 48928, 48920,     0, 
+        1, 49152, 49153, 49155, 49159, 49167, 48896, 48928, 
+    48920,     0,     1, 49152, 49153, 49155, 49159, 49167, 
+    48896, 48928, 48920, 48922,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 48896, 48928, 48920,     0,     1, 
+    49152, 49153, 49155, 49159, 49167, 48896, 48928, 48929, 
+    48924,     0,     1, 49152, 49153, 49155, 49159, 49167, 
+    48896, 48928, 48929, 48924,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 48896, 48928, 48929, 48924, 48926, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 48896, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 48896, 
+    48928,     0,     1, 49152, 49153, 49155, 49159, 49167, 
+    48896, 48928,     0,     1, 49152, 49153, 49155, 49159, 
+    49167, 48896, 48928, 48930,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 48896, 48928,     0,     1, 49152, 
+    49153, 49155, 49159, 49167, 48896, 48928, 48932,     0, 
+        1, 49152, 49153, 49155, 49159, 49167, 48896, 48928, 
+    48932,     0,     1, 49152, 49153, 49155, 49159, 49167, 
+    48896, 48928, 48936, 48934,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 48896, 48928,     0,     1, 49152, 
+    49153, 49155, 49159, 49167, 48896, 48928, 48936,     0, 
+        1, 49152, 49153, 49155, 49159, 49167, 48896, 48928, 
+    48936,     0,     1, 49152, 49153, 49155, 49159, 49167, 
+    48896, 48928, 48936, 48938,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 48896, 48928, 48936,     0,     1, 
+    49152, 49153, 49155, 49159, 49167, 48896, 48928, 48944, 
+    48940,     0,     1, 49152, 49153, 49155, 49159, 49167, 
+    48896, 48928, 48944, 48940,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 48896, 48928, 48944, 48945, 48942, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 48896, 
+    48928,     0,     1, 49152, 49153, 49155, 49159, 49167, 
+    48896, 48960, 48944,     0,     1, 49152, 49153, 49155, 
+    49159, 49167, 48896, 48960, 48944,     0,     1, 49152, 
+    49153, 49155, 49159, 49167, 48896, 48960, 48944, 48946, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 48896, 
+    48960, 48944,     0,     1, 49152, 49153, 49155, 49159, 
+    49167, 48896, 48960, 48944, 48948,     0,     1, 49152, 
+    49153, 49155, 49159, 49167, 48896, 48960, 48944, 48948, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 48896, 
+    48960, 48944, 48952, 48950,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 48896, 48960, 48944,     0,     1, 
+    49152, 49153, 49155, 49159, 49167, 48896, 48960, 48961, 
+    48952,     0,     1, 49152, 49153, 49155, 49159, 49167, 
+    48896, 48960, 48961, 48952,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 48896, 48960, 48961, 48952, 48954, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 48896, 
+    48960, 48961, 48952,     0,     1, 49152, 49153, 49155, 
+    49159, 49167, 48896, 48960, 48961, 48952, 48956,     0, 
+        1, 49152, 49153, 49155, 49159, 49167, 48896, 48960, 
+    48961, 48963, 48956,     0,     1, 49152, 49153, 49155, 
+    49159, 49167, 48896, 48960, 48961, 48963, 48956, 48958, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 48896, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 48896, 
+    48960,     0,     1, 49152, 49153, 49155, 49159, 49167, 
+    48896, 48960,     0,     1, 49152, 49153, 49155, 49159, 
+    49167, 48896, 48960, 48962,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 48896, 48960,     0,     1, 49152, 
+    49153, 49155, 49159, 49167, 48896, 48960, 48964,     0, 
+        1, 49152, 49153, 49155, 49159, 49167, 48896, 48960, 
+    48964,     0,     1, 49152, 49153, 49155, 49159, 49167, 
+    48896, 48960, 48968, 48966,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 48896, 48960,     0,     1, 49152, 
+    49153, 49155, 49159, 49167, 48896, 48960, 48968,     0, 
+        1, 49152, 49153, 49155, 49159, 49167, 48896, 48960, 
+    48968,     0,     1, 49152, 49153, 49155, 49159, 49167, 
+    48896, 48960, 48968, 48970,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 48896, 48960, 48968,     0,     1, 
+    49152, 49153, 49155, 49159, 49167, 48896, 48960, 48976, 
+    48972,     0,     1, 49152, 49153, 49155, 49159, 49167, 
+    48896, 48960, 48976, 48972,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 48896, 48960, 48976, 48977, 48974, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 48896, 
+    48960,     0,     1, 49152, 49153, 49155, 49159, 49167, 
+    48896, 48960, 48976,     0,     1, 49152, 49153, 49155, 
+    49159, 49167, 48896, 48960, 48976,     0,     1, 49152, 
+    49153, 49155, 49159, 49167, 48896, 48960, 48976, 48978, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 48896, 
+    48960, 48976,     0,     1, 49152, 49153, 49155, 49159, 
+    49167, 48896, 48960, 48976, 48980,     0,     1, 49152, 
+    49153, 49155, 49159, 49167, 48896, 48960, 48976, 48980, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 48896, 
+    48960, 48976, 48984, 48982,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 48896, 48960, 48976,     0,     1, 
+    49152, 49153, 49155, 49159, 49167, 48896, 48960, 48992, 
+    48984,     0,     1, 49152, 49153, 49155, 49159, 49167, 
+    48896, 48960, 48992, 48984,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 48896, 48960, 48992, 48984, 48986, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 48896, 
+    48960, 48992, 48984,     0,     1, 49152, 49153, 49155, 
+    49159, 49167, 48896, 48960, 48992, 48993, 48988,     0, 
+        1, 49152, 49153, 49155, 49159, 49167, 48896, 48960, 
+    48992, 48993, 48988,     0,     1, 49152, 49153, 49155, 
+    49159, 49167, 48896, 48960, 48992, 48993, 48988, 48990, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 48896, 
+    48960,     0,     1, 49152, 49153, 49155, 49159, 49167, 
+    48896, 49024, 48992,     0,     1, 49152, 49153, 49155, 
+    49159, 49167, 48896, 49024, 48992,     0,     1, 49152, 
+    49153, 49155, 49159, 49167, 48896, 49024, 48992, 48994, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 48896, 
+    49024, 48992,     0,     1, 49152, 49153, 49155, 49159, 
+    49167, 48896, 49024, 48992, 48996,     0,     1, 49152, 
+    49153, 49155, 49159, 49167, 48896, 49024, 48992, 48996, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 48896, 
+    49024, 48992, 49000, 48998,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 48896, 49024, 48992,     0,     1, 
+    49152, 49153, 49155, 49159, 49167, 48896, 49024, 48992, 
+    49000,     0,     1, 49152, 49153, 49155, 49159, 49167, 
+    48896, 49024, 48992, 49000,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 48896, 49024, 48992, 49000, 49002, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 48896, 
+    49024, 48992, 49000,     0,     1, 49152, 49153, 49155, 
+    49159, 49167, 48896, 49024, 48992, 49008, 49004,     0, 
+        1, 49152, 49153, 49155, 49159, 49167, 48896, 49024, 
+    48992, 49008, 49004,     0,     1, 49152, 49153, 49155, 
+    49159, 49167, 48896, 49024, 48992, 49008, 49009, 49006, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 48896, 
+    49024, 48992,     0,     1, 49152, 49153, 49155, 49159, 
+    49167, 48896, 49024, 49025, 49008,     0,     1, 49152, 
+    49153, 49155, 49159, 49167, 48896, 49024, 49025, 49008, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 48896, 
+    49024, 49025, 49008, 49010,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 48896, 49024, 49025, 49008,     0, 
+        1, 49152, 49153, 49155, 49159, 49167, 48896, 49024, 
+    49025, 49008, 49012,     0,     1, 49152, 49153, 49155, 
+    49159, 49167, 48896, 49024, 49025, 49008, 49012,     0, 
+        1, 49152, 49153, 49155, 49159, 49167, 48896, 49024, 
+    49025, 49008, 49016, 49014,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 48896, 49024, 49025, 49008,     0, 
+        1, 49152, 49153, 49155, 49159, 49167, 48896, 49024, 
+    49025, 49008, 49016,     0,     1, 49152, 49153, 49155, 
+    49159, 49167, 48896, 49024, 49025, 49027, 49016,     0, 
+        1, 49152, 49153, 49155, 49159, 49167, 48896, 49024, 
+    49025, 49027, 49016, 49018,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 48896, 49024, 49025, 49027, 49016, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 48896, 
+    49024, 49025, 49027, 49016, 49020,     0,     1, 49152, 
+    49153, 49155, 49159, 49167, 48896, 49024, 49025, 49027, 
+    49016, 49020,     0,     1, 49152, 49153, 49155, 49159, 
+    49167, 48896, 49024, 49025, 49027, 49016, 49020, 49022, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 48896, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 48896, 
+    49024,     0,     1, 49152, 49153, 49155, 49159, 49167, 
+    48896, 49024,     0,     1, 49152, 49153, 49155, 49159, 
+    49167, 48896, 49024, 49026,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 48896, 49024,     0,     1, 49152, 
+    49153, 49155, 49159, 49167, 48896, 49024, 49028,     0, 
+        1, 49152, 49153, 49155, 49159, 49167, 48896, 49024, 
+    49028,     0,     1, 49152, 49153, 49155, 49159, 49167, 
+    48896, 49024, 49032, 49030,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 48896, 49024,     0,     1, 49152, 
+    49153, 49155, 49159, 49167, 48896, 49024, 49032,     0, 
+        1, 49152, 49153, 49155, 49159, 49167, 48896, 49024, 
+    49032,     0,     1, 49152, 49153, 49155, 49159, 49167, 
+    48896, 49024, 49032, 49034,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 48896, 49024, 49032,     0,     1, 
+    49152, 49153, 49155, 49159, 49167, 48896, 49024, 49040, 
+    49036,     0,     1, 49152, 49153, 49155, 49159, 49167, 
+    48896, 49024, 49040, 49036,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 48896, 49024, 49040, 49041, 49038, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 48896, 
+    49024,     0,     1, 49152, 49153, 49155, 49159, 49167, 
+    48896, 49024, 49040,     0,     1, 49152, 49153, 49155, 
+    49159, 49167, 48896, 49024, 49040,     0,     1, 49152, 
+    49153, 49155, 49159, 49167, 48896, 49024, 49040, 49042, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 48896, 
+    49024, 49040,     0,     1, 49152, 49153, 49155, 49159, 
+    49167, 48896, 49024, 49040, 49044,     0,     1, 49152, 
+    49153, 49155, 49159, 49167, 48896, 49024, 49040, 49044, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 48896, 
+    49024, 49040, 49048, 49046,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 48896, 49024, 49040,     0,     1, 
+    49152, 49153, 49155, 49159, 49167, 48896, 49024, 49056, 
+    49048,     0,     1, 49152, 49153, 49155, 49159, 49167, 
+    48896, 49024, 49056, 49048,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 48896, 49024, 49056, 49048, 49050, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 48896, 
+    49024, 49056, 49048,     0,     1, 49152, 49153, 49155, 
+    49159, 49167, 48896, 49024, 49056, 49057, 49052,     0, 
+        1, 49152, 49153, 49155, 49159, 49167, 48896, 49024, 
+    49056, 49057, 49052,     0,     1, 49152, 49153, 49155, 
+    49159, 49167, 48896, 49024, 49056, 49057, 49052, 49054, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 49183, 
+    49024,     0,     1, 49152, 49153, 49155, 49159, 49167, 
+    49183, 49024, 49056,     0,     1, 49152, 49153, 49155, 
+    49159, 49167, 49183, 49024, 49056,     0,     1, 49152, 
+    49153, 49155, 49159, 49167, 49183, 49024, 49056, 49058, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 49183, 
+    49024, 49056,     0,     1, 49152, 49153, 49155, 49159, 
+    49167, 49183, 49024, 49056, 49060,     0,     1, 49152, 
+    49153, 49155, 49159, 49167, 49183, 49024, 49056, 49060, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 49183, 
+    49024, 49056, 49064, 49062,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 49183, 49024, 49056,     0,     1, 
+    49152, 49153, 49155, 49159, 49167, 49183, 49024, 49056, 
+    49064,     0,     1, 49152, 49153, 49155, 49159, 49167, 
+    49183, 49024, 49056, 49064,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 49183, 49024, 49056, 49064, 49066, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 49183, 
+    49024, 49056, 49064,     0,     1, 49152, 49153, 49155, 
+    49159, 49167, 49183, 49024, 49056, 49072, 49068,     0, 
+        1, 49152, 49153, 49155, 49159, 49167, 49183, 49024, 
+    49056, 49072, 49068,     0,     1, 49152, 49153, 49155, 
+    49159, 49167, 49183, 49024, 49056, 49072, 49073, 49070, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 49183, 
+    49024, 49056,     0,     1, 49152, 49153, 49155, 49159, 
+    49167, 49183, 49024, 49088, 49072,     0,     1, 49152, 
+    49153, 49155, 49159, 49167, 49183, 49024, 49088, 49072, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 49183, 
+    49024, 49088, 49072, 49074,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 49183, 49024, 49088, 49072,     0, 
+        1, 49152, 49153, 49155, 49159, 49167, 49183, 49024, 
+    49088, 49072, 49076,     0,     1, 49152, 49153, 49155, 
+    49159, 49167, 49183, 49024, 49088, 49072, 49076,     0, 
+        1, 49152, 49153, 49155, 49159, 49167, 49183, 49024, 
+    49088, 49072, 49080, 49078,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 49183, 49024, 49088, 49072,     0, 
+        1, 49152, 49153, 49155, 49159, 49167, 49183, 49024, 
+    49088, 49089, 49080,     0,     1, 49152, 49153, 49155, 
+    49159, 49167, 49183, 49024, 49088, 49089, 49080,     0, 
+        1, 49152, 49153, 49155, 49159, 49167, 49183, 49024, 
+    49088, 49089, 49080, 49082,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 49183, 49024, 49088, 49089, 49080, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 49183, 
+    49024, 49088, 49089, 49080, 49084,     0,     1, 49152, 
+    49153, 49155, 49159, 49167, 49183, 49024, 49088, 49089, 
+    49091, 49084,     0,     1, 49152, 49153, 49155, 49159, 
+    49167, 49183, 49024, 49088, 49089, 49091, 49084, 49086, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 49183, 
+    49024,     0,     1, 49152, 49153, 49155, 49159, 49167, 
+    49183, 49024, 49088,     0,     1, 49152, 49153, 49155, 
+    49159, 49167, 49183, 49024, 49088,     0,     1, 49152, 
+    49153, 49155, 49159, 49167, 49183, 49024, 49088, 49090, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 49183, 
+    49024, 49088,     0,     1, 49152, 49153, 49155, 49159, 
+    49167, 49183, 49024, 49088, 49092,     0,     1, 49152, 
+    49153, 49155, 49159, 49167, 49183, 49024, 49088, 49092, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 49183, 
+    49024, 49088, 49096, 49094,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 49183, 49024, 49088,     0,     1, 
+    49152, 49153, 49155, 49159, 49167, 49183, 49024, 49088, 
+    49096,     0,     1, 49152, 49153, 49155, 49159, 49167, 
+    49183, 49024, 49088, 49096,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 49183, 49024, 49088, 49096, 49098, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 49183, 
+    49024, 49088, 49096,     0,     1, 49152, 49153, 49155, 
+    49159, 49167, 49183, 49024, 49088, 49104, 49100,     0, 
+        1, 49152, 49153, 49155, 49159, 49167, 49183, 49024, 
+    49088, 49104, 49100,     0,     1, 49152, 49153, 49155, 
+    49159, 49167, 49183, 49024, 49088, 49104, 49105, 49102, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 49183, 
+    49024, 49088,     0,     1, 49152, 49153, 49155, 49159, 
+    49167, 49183, 49024, 49088, 49104,     0,     1, 49152, 
+    49153, 49155, 49159, 49167, 49183, 49024, 49088, 49104, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 49183, 
+    49024, 49088, 49104, 49106,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 49183, 49024, 49088, 49104,     0, 
+        1, 49152, 49153, 49155, 49159, 49167, 49183, 49024, 
+    49088, 49104, 49108,     0,     1, 49152, 49153, 49155, 
+    49159, 49167, 49183, 49024, 49088, 49104, 49108,     0, 
+        1, 49152, 49153, 49155, 49159, 49167, 49183, 49024, 
+    49088, 49104, 49112, 49110,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 49183, 49024, 49088, 49104,     0, 
+        1, 49152, 49153, 49155, 49159, 49167, 49183, 49024, 
+    49088, 49120, 49112,     0,     1, 49152, 49153, 49155, 
+    49159, 49167, 49183, 49024, 49088, 49120, 49112,     0, 
+        1, 49152, 49153, 49155, 49159, 49167, 49183, 49024, 
+    49088, 49120, 49112, 49114,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 49183, 49024, 49088, 49120, 49112, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 49183, 
+    49024, 49088, 49120, 49121, 49116,     0,     1, 49152, 
+    49153, 49155, 49159, 49167, 49183, 49024, 49088, 49120, 
+    49121, 49116,     0,     1, 49152, 49153, 49155, 49159, 
+    49167, 49183, 49024, 49088, 49120, 49121, 49116, 49118, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 49183, 
+    49024, 49088,     0,     1, 49152, 49153, 49155, 49159, 
+    49167, 49183, 49024, 49088, 49120,     0,     1, 49152, 
+    49153, 49155, 49159, 49167, 49183, 49024, 49088, 49120, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 49183, 
+    49024, 49088, 49120, 49122,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 49183, 49024, 49088, 49120,     0, 
+        1, 49152, 49153, 49155, 49159, 49167, 49183, 49024, 
+    49088, 49120, 49124,     0,     1, 49152, 49153, 49155, 
+    49159, 49167, 49183, 49024, 49088, 49120, 49124,     0, 
+        1, 49152, 49153, 49155, 49159, 49167, 49183, 49024, 
+    49088, 49120, 49128, 49126,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 49183, 49024, 49088, 49120,     0, 
+        1, 49152, 49153, 49155, 49159, 49167, 49183, 49024, 
+    49088, 49120, 49128,     0,     1, 49152, 49153, 49155, 
+    49159, 49167, 49183, 49024, 49088, 49120, 49128,     0, 
+        1, 49152, 49153, 49155, 49159, 49167, 49183, 49024, 
+    49088, 49120, 49128, 49130,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 49183, 49024, 49088, 49120, 49128, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 49183, 
+    49024, 49088, 49120, 49136, 49132,     0,     1, 49152, 
+    49153, 49155, 49159, 49167, 49183, 49024, 49088, 49120, 
+    49136, 49132,     0,     1, 49152, 49153, 49155, 49159, 
+    49167, 49183, 49024, 49088, 49120, 49136, 49137, 49134, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 49183, 
+    49024, 49088, 49120,     0,     1, 49152, 49153, 49155, 
+    49159, 49167, 49183, 49024, 49088, 49120, 49136,     0, 
+        1, 49152, 49153, 49155, 49159, 49167, 49183, 49024, 
+    49088, 49120, 49136,     0,     1, 49152, 49153, 49155, 
+    49159, 49167, 49183, 49024, 49088, 49120, 49136, 49138, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 49183, 
+    49024, 49088, 49120, 49136,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 49183, 49024, 49088, 49120, 49136, 
+    49140,     0,     1, 49152, 49153, 49155, 49159, 49167, 
+    49183, 49024, 49088, 49120, 49136, 49140,     0,     1, 
+    49152, 49153, 49155, 49159, 49167, 49183, 49024, 49088, 
+    49120, 49136, 49144, 49142,     0,     1, 49152, 49153, 
+    49155, 49159, 49167, 49183, 49024, 49088, 49120, 49136, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 49183, 
+    49024, 49088, 49120, 49136, 49144,     0,     1, 49152, 
+    49153, 49155, 49159, 49167, 49183, 49024, 49088, 49120, 
+    49136, 49144,     0,     1, 49152, 49153, 49155, 49159, 
+    49167, 49183, 49024, 49088, 49120, 49136, 49144, 49146, 
+        0,     1, 49152, 49153, 49155, 49159, 49167, 49183, 
+    49024, 49088, 49120, 49136, 49144,     0,     1, 49152, 
+    49153, 49155, 49159, 49167, 49183, 49024, 49088, 49120, 
+    49136, 49144, 49148,     0,     1, 49152, 49153, 49155, 
+    49159, 49167, 49183, 49024, 49088, 49120, 49136, 49144, 
+    49148,     0,     1, 49152, 49153, 49155, 49159, 49167, 
+    49183, 49024, 49088, 49120, 49136, 49144, 49148, 49150, 
+        0,     1,     0,     1, 49152,     0,     1, 49152, 
+        0,     1, 49152, 49154,     0,     1, 49152,     0, 
+        1, 49152, 49156,     0,     1, 49152, 49156,     0, 
+        1, 49152, 49160, 49158,     0,     1, 49152,     0, 
+        1, 49152, 49160,     0,     1, 49152, 49160,     0, 
+        1, 49152, 49160, 49162,     0,     1, 49152, 49160, 
+        0,     1, 49152, 49168, 49164,     0,     1, 49152, 
+    49168, 49164,     0,     1, 49152, 49168, 49169, 49166, 
+        0,     1, 49152,     0,     1, 49152, 49168,     0, 
+        1, 49152, 49168,     0,     1, 49152, 49168, 49170, 
+        0,     1, 49152, 49168,     0,     1, 49152, 49168, 
+    49172,     0,     1, 49152, 49168, 49172,     0,     1, 
+    49152, 49168, 49176, 49174,     0,     1, 49152, 49168, 
+        0,     1, 49152, 49184, 49176,     0,     1, 49152, 
+    49184, 49176,     0,     1, 49152, 49184, 49176, 49178, 
+        0,     1, 49152, 49184, 49176,     0,     1, 49152, 
+    49184, 49185, 49180,     0,     1, 49152, 49184, 49185, 
+    49180,     0,     1, 49152, 49184, 49185, 49180, 49182, 
+        0,     1, 49152,     0,     1, 49152, 49184,     0, 
+        1, 49152, 49184,     0,     1, 49152, 49184, 49186, 
+        0,     1, 49152, 49184,     0,     1, 49152, 49184, 
+    49188,     0,     1, 49152, 49184, 49188,     0,     1, 
+    49152, 49184, 49192, 49190,     0,     1, 49152, 49184, 
+        0,     1, 49152, 49184, 49192,     0,     1, 49152, 
+    49184, 49192,     0,     1, 49152, 49184, 49192, 49194, 
+        0,     1, 49152, 49184, 49192,     0,     1, 49152, 
+    49184, 49200, 49196,     0,     1, 49152, 49184, 49200, 
+    49196,     0,     1, 49152, 49184, 49200, 49201, 49198, 
+        0,     1, 49152, 49184,     0,     1, 49152, 49216, 
+    49200,     0,     1, 49152, 49216, 49200,     0,     1, 
+    49152, 49216, 49200, 49202,     0,     1, 49152, 49216, 
+    49200,     0,     1, 49152, 49216, 49200, 49204,     0, 
+        1, 49152, 49216, 49200, 49204,     0,     1, 49152, 
+    49216, 49200, 49208, 49206,     0,     1, 49152, 49216, 
+    49200,     0,     1, 49152, 49216, 49217, 49208,     0, 
+        1, 49152, 49216, 49217, 49208,     0,     1, 49152, 
+    49216, 49217, 49208, 49210,     0,     1, 49152, 49216, 
+    49217, 49208,     0,     1, 49152, 49216, 49217, 49208, 
+    49212,     0,     1, 49152, 49216, 49217, 49219, 49212, 
+        0,     1, 49152, 49216, 49217, 49219, 49212, 49214, 
+        0,     1, 49152,     0,     1, 49152, 49216,     0, 
+        1, 49152, 49216,     0,     1, 49152, 49216, 49218, 
+        0,     1, 49152, 49216,     0,     1, 49152, 49216, 
+    49220,     0,     1, 49152, 49216, 49220,     0,     1, 
+    49152, 49216, 49224, 49222,     0,     1, 49152, 49216, 
+        0,     1, 49152, 49216, 49224,     0,     1, 49152, 
+    49216, 49224,     0,     1, 49152, 49216, 49224, 49226, 
+        0,     1, 49152, 49216, 49224,     0,     1, 49152, 
+    49216, 49232, 49228,     0,     1, 49152, 49216, 49232, 
+    49228,     0,     1, 49152, 49216, 49232, 49233, 49230, 
+        0,     1, 49152, 49216,     0,     1, 49152, 49216, 
+    49232,     0,     1, 49152, 49216, 49232,     0,     1, 
+    49152, 49216, 49232, 49234,     0,     1, 49152, 49216, 
+    49232,     0,     1, 49152, 49216, 49232, 49236,     0, 
+        1, 49152, 49216, 49232, 49236,     0,     1, 49152, 
+    49216, 49232, 49240, 49238,     0,     1, 49152, 49216, 
+    49232,     0,     1, 49152, 49216, 49248, 49240,     0, 
+        1, 49152, 49216, 49248, 49240,     0,     1, 49152, 
+    49216, 49248, 49240, 49242,     0,     1, 49152, 49216, 
+    49248, 49240,     0,     1, 49152, 49216, 49248, 49249, 
+    49244,     0,     1, 49152, 49216, 49248, 49249, 49244, 
+        0,     1, 49152, 49216, 49248, 49249, 49244, 49246, 
+        0,     1, 49152, 49216,     0,     1, 49152, 49280, 
+    49248,     0,     1, 49152, 49280, 49248,     0,     1, 
+    49152, 49280, 49248, 49250,     0,     1, 49152, 49280, 
+    49248,     0,     1, 49152, 49280, 49248, 49252,     0, 
+        1, 49152, 49280, 49248, 49252,     0,     1, 49152, 
+    49280, 49248, 49256, 49254,     0,     1, 49152, 49280, 
+    49248,     0,     1, 49152, 49280, 49248, 49256,     0, 
+        1, 49152, 49280, 49248, 49256,     0,     1, 49152, 
+    49280, 49248, 49256, 49258,     0,     1, 49152, 49280, 
+    49248, 49256,     0,     1, 49152, 49280, 49248, 49264, 
+    49260,     0,     1, 49152, 49280, 49248, 49264, 49260, 
+        0,     1, 49152, 49280, 49248, 49264, 49265, 49262, 
+        0,     1, 49152, 49280, 49248,     0,     1, 49152, 
+    49280, 49281, 49264,     0,     1, 49152, 49280, 49281, 
+    49264,     0,     1, 49152, 49280, 49281, 49264, 49266, 
+        0,     1, 49152, 49280, 49281, 49264,     0,     1, 
+    49152, 49280, 49281, 49264, 49268,     0,     1, 49152, 
+    49280, 49281, 49264, 49268,     0,     1, 49152, 49280, 
+    49281, 49264, 49272, 49270,     0,     1, 49152, 49280, 
+    49281, 49264,     0,     1, 49152, 49280, 49281, 49264, 
+    49272,     0,     1, 49152, 49280, 49281, 49283, 49272, 
+        0,     1, 49152, 49280, 49281, 49283, 49272, 49274, 
+        0,     1, 49152, 49280, 49281, 49283, 49272,     0, 
+        1, 49152, 49280, 49281, 49283, 49272, 49276,     0, 
+        1, 49152, 49280, 49281, 49283, 49272, 49276,     0, 
+        1, 49152, 49280, 49281, 49283, 49272, 49276, 49278, 
+        0,     1, 49152,     0,     1, 49152, 49280,     0, 
+        1, 49152, 49280,     0,     1, 49152, 49280, 49282, 
+        0,     1, 49152, 49280,     0,     1, 49152, 49280, 
+    49284,     0,     1, 49152, 49280, 49284,     0,     1, 
+    49152, 49280, 49288, 49286,     0,     1, 49152, 49280, 
+        0,     1, 49152, 49280, 49288,     0,     1, 49152, 
+    49280, 49288,     0,     1, 49152, 49280, 49288, 49290, 
+        0,     1, 49152, 49280, 49288,     0,     1, 49152, 
+    49280, 49296, 49292,     0,     1, 49152, 49280, 49296, 
+    49292,     0,     1, 49152, 49280, 49296, 49297, 49294, 
+        0,     1, 49152, 49280,     0,     1, 49152, 49280, 
+    49296,     0,     1, 49152, 49280, 49296,     0,     1, 
+    49152, 49280, 49296, 49298,     0,     1, 49152, 49280, 
+    49296,     0,     1, 49152, 49280, 49296, 49300,     0, 
+        1, 49152, 49280, 49296, 49300,     0,     1, 49152, 
+    49280, 49296, 49304, 49302,     0,     1, 49152, 49280, 
+    49296,     0,     1, 49152, 49280, 49312, 49304,     0, 
+        1, 49152, 49280, 49312, 49304,     0,     1, 49152, 
+    49280, 49312, 49304, 49306,     0,     1, 49152, 49280, 
+    49312, 49304,     0,     1, 49152, 49280, 49312, 49313, 
+    49308,     0,     1, 49152, 49280, 49312, 49313, 49308, 
+        0,     1, 49152, 49280, 49312, 49313, 49308, 49310, 
+        0,     1, 49152, 49280,     0,     1, 49152, 49280, 
+    49312,     0,     1, 49152, 49280, 49312,     0,     1, 
+    49152, 49280, 49312, 49314,     0,     1, 49152, 49280, 
+    49312,     0,     1, 49152, 49280, 49312, 49316,     0, 
+        1, 49152, 49280, 49312, 49316,     0,     1, 49152, 
+    49280, 49312, 49320, 49318,     0,     1, 49152, 49280, 
+    49312,     0,     1, 49152, 49280, 49312, 49320,     0, 
+        1, 49152, 49280, 49312, 49320,     0,     1, 49152, 
+    49280, 49312, 49320, 49322,     0,     1, 49152, 49280, 
+    49312, 49320,     0,     1, 49152, 49280, 49312, 49328, 
+    49324,     0,     1, 49152, 49280, 49312, 49328, 49324, 
+        0,     1, 49152, 49280, 49312, 49328, 49329, 49326, 
+        0,     1, 49152, 49280, 49312,     0,     1, 49152, 
+    49280, 49344, 49328,     0,     1, 49152, 49280, 49344, 
+    49328,     0,     1, 49152, 49280, 49344, 49328, 49330, 
+        0,     1, 49152, 49280, 49344, 49328,     0,     1, 
+    49152, 49280, 49344, 49328, 49332,     0,     1, 49152, 
+    49280, 49344, 49328, 49332,     0,     1, 49152, 49280, 
+    49344, 49328, 49336, 49334,     0,     1, 49152, 49280, 
+    49344, 49328,     0,     1, 49152, 49280, 49344, 49345, 
+    49336,     0,     1, 49152, 49280, 49344, 49345, 49336, 
+        0,     1, 49152, 49280, 49344, 49345, 49336, 49338, 
+        0,     1, 49152, 49280, 49344, 49345, 49336,     0, 
+        1, 49152, 49280, 49344, 49345, 49336, 49340,     0, 
+        1, 49152, 49280, 49344, 49345, 49347, 49340,     0, 
+        1, 49152, 49280, 49344, 49345, 49347, 49340, 49342, 
+        0,     1, 49152, 49280,     0,     1, 49152, 49408, 
+    49344,     0,     1, 49152, 49408, 49344,     0,     1, 
+    49152, 49408, 49344, 49346,     0,     1, 49152, 49408, 
+    49344,     0,     1, 49152, 49408, 49344, 49348,     0, 
+        1, 49152, 49408, 49344, 49348,     0,     1, 49152, 
+    49408, 49344, 49352, 49350,     0,     1, 49152, 49408, 
+    49344,     0,     1, 49152, 49408, 49344, 49352,     0, 
+        1, 49152, 49408, 49344, 49352,     0,     1, 49152, 
+    49408, 49344, 49352, 49354,     0,     1, 49152, 49408, 
+    49344, 49352,     0,     1, 49152, 49408, 49344, 49360, 
+    49356,     0,     1, 49152, 49408, 49344, 49360, 49356, 
+        0,     1, 49152, 49408, 49344, 49360, 49361, 49358, 
+        0,     1, 49152, 49408, 49344,     0,     1, 49152, 
+    49408, 49344, 49360,     0,     1, 49152, 49408, 49344, 
+    49360,     0,     1, 49152, 49408, 49344, 49360, 49362, 
+        0,     1, 49152, 49408, 49344, 49360,     0,     1, 
+    49152, 49408, 49344, 49360, 49364,     0,     1, 49152, 
+    49408, 49344, 49360, 49364,     0,     1, 49152, 49408, 
+    49344, 49360, 49368, 49366,     0,     1, 49152, 49408, 
+    49344, 49360,     0,     1, 49152, 49408, 49344, 49376, 
+    49368,     0,     1, 49152, 49408, 49344, 49376, 49368, 
+        0,     1, 49152, 49408, 49344, 49376, 49368, 49370, 
+        0,     1, 49152, 49408, 49344, 49376, 49368,     0, 
+        1, 49152, 49408, 49344, 49376, 49377, 49372,     0, 
+        1, 49152, 49408, 49344, 49376, 49377, 49372,     0, 
+        1, 49152, 49408, 49344, 49376, 49377, 49372, 49374, 
+        0,     1, 49152, 49408, 49344,     0,     1, 49152, 
+    49408, 49409, 49376,     0,     1, 49152, 49408, 49409, 
+    49376,     0,     1, 49152, 49408, 49409, 49376, 49378, 
+        0,     1, 49152, 49408, 49409, 49376,     0,     1, 
+    49152, 49408, 49409, 49376, 49380,     0,     1, 49152, 
+    49408, 49409, 49376, 49380,     0,     1, 49152, 49408, 
+    49409, 49376, 49384, 49382,     0,     1, 49152, 49408, 
+    49409, 49376,     0,     1, 49152, 49408, 49409, 49376, 
+    49384,     0,     1, 49152, 49408, 49409, 49376, 49384, 
+        0,     1, 49152, 49408, 49409, 49376, 49384, 49386, 
+        0,     1, 49152, 49408, 49409, 49376, 49384,     0, 
+        1, 49152, 49408, 49409, 49376, 49392, 49388,     0, 
+        1, 49152, 49408, 49409, 49376, 49392, 49388,     0, 
+        1, 49152, 49408, 49409, 49376, 49392, 49393, 49390, 
+        0,     1, 49152, 49408, 49409, 49376,     0,     1, 
+    49152, 49408, 49409, 49376, 49392,     0,     1, 49152, 
+    49408, 49409, 49411, 49392,     0,     1, 49152, 49408, 
+    49409, 49411, 49392, 49394,     0,     1, 49152, 49408, 
+    49409, 49411, 49392,     0,     1, 49152, 49408, 49409, 
+    49411, 49392, 49396,     0,     1, 49152, 49408, 49409, 
+    49411, 49392, 49396,     0,     1, 49152, 49408, 49409, 
+    49411, 49392, 49400, 49398,     0,     1, 49152, 49408, 
+    49409, 49411, 49392,     0,     1, 49152, 49408, 49409, 
+    49411, 49392, 49400,     0,     1, 49152, 49408, 49409, 
+    49411, 49392, 49400,     0,     1, 49152, 49408, 49409, 
+    49411, 49392, 49400, 49402,     0,     1, 49152, 49408, 
+    49409, 49411, 49415, 49400,     0,     1, 49152, 49408, 
+    49409, 49411, 49415, 49400, 49404,     0,     1, 49152, 
+    49408, 49409, 49411, 49415, 49400, 49404,     0,     1, 
+    49152, 49408, 49409, 49411, 49415, 49400, 49404, 49406, 
+        0,     1, 49152,     0,     1, 49152, 49408,     0, 
+        1, 49152, 49408,     0,     1, 49152, 49408, 49410, 
+        0,     1, 49152, 49408,     0,     1, 49152, 49408, 
+    49412,     0,     1, 49152, 49408, 49412,     0,     1, 
+    49152, 49408, 49416, 49414,     0,     1, 49152, 49408, 
+        0,     1, 49152, 49408, 49416,     0,     1, 49152, 
+    49408, 49416,     0,     1, 49152, 49408, 49416, 49418, 
+        0,     1, 49152, 49408, 49416,     0,     1, 49152, 
+    49408, 49424, 49420,     0,     1, 49152, 49408, 49424, 
+    49420,     0,     1, 49152, 49408, 49424, 49425, 49422, 
+        0,     1, 49152, 49408,     0,     1, 49152, 49408, 
+    49424,     0,     1, 49152, 49408, 49424,     0,     1, 
+    49152, 49408, 49424, 49426,     0,     1, 49152, 49408, 
+    49424,     0,     1, 49152, 49408, 49424, 49428,     0, 
+        1, 49152, 49408, 49424, 49428,     0,     1, 49152, 
+    49408, 49424, 49432, 49430,     0,     1, 49152, 49408, 
+    49424,     0,     1, 49152, 49408, 49440, 49432,     0, 
+        1, 49152, 49408, 49440, 49432,     0,     1, 49152, 
+    49408, 49440, 49432, 49434,     0,     1, 49152, 49408, 
+    49440, 49432,     0,     1, 49152, 49408, 49440, 49441, 
+    49436,     0,     1, 49152, 49408, 49440, 49441, 49436, 
+        0,     1, 49152, 49408, 49440, 49441, 49436, 49438, 
+        0,     1, 49152, 49408,     0,     1, 49152, 49408, 
+    49440,     0,     1, 49152, 49408, 49440,     0,     1, 
+    49152, 49408, 49440, 49442,     0,     1, 49152, 49408, 
+    49440,     0,     1, 49152, 49408, 49440, 49444,     0, 
+        1, 49152, 49408, 49440, 49444,     0,     1, 49152, 
+    49408, 49440, 49448, 49446,     0,     1, 49152, 49408, 
+    49440,     0,     1, 49152, 49408, 49440, 49448,     0, 
+        1, 49152, 49408, 49440, 49448,     0,     1, 49152, 
+    49408, 49440, 49448, 49450,     0,     1, 49152, 49408, 
+    49440, 49448,     0,     1, 49152, 49408, 49440, 49456, 
+    49452,     0,     1, 49152, 49408, 49440, 49456, 49452, 
+        0,     1, 49152, 49408, 49440, 49456, 49457, 49454, 
+        0,     1, 49152, 49408, 49440,     0,     1, 49152, 
+    49408, 49472, 49456,     0,     1, 49152, 49408, 49472, 
+    49456,     0,     1, 49152, 49408, 49472, 49456, 49458, 
+        0,     1, 49152, 49408, 49472, 49456,     0,     1, 
+    49152, 49408, 49472, 49456, 49460,     0,     1, 49152, 
+    49408, 49472, 49456, 49460,     0,     1, 49152, 49408, 
+    49472, 49456, 49464, 49462,     0,     1, 49152, 49408, 
+    49472, 49456,     0,     1, 49152, 49408, 49472, 49473, 
+    49464,     0,     1, 49152, 49408, 49472, 49473, 49464, 
+        0,     1, 49152, 49408, 49472, 49473, 49464, 49466, 
+        0,     1, 49152, 49408, 49472, 49473, 49464,     0, 
+        1, 49152, 49408, 49472, 49473, 49464, 49468,     0, 
+        1, 49152, 49408, 49472, 49473, 49475, 49468,     0, 
+        1, 49152, 49408, 49472, 49473, 49475, 49468, 49470, 
+        0,     1, 49152, 49408,     0,     1, 49152, 49408, 
+    49472,     0,     1, 49152, 49408, 49472,     0,     1, 
+    49152, 49408, 49472, 49474,     0,     1, 49152, 49408, 
+    49472,     0,     1, 49152, 49408, 49472, 49476,     0, 
+        1, 49152, 49408, 49472, 49476,     0,     1, 49152, 
+    49408, 49472, 49480, 49478,     0,     1, 49152, 49408, 
+    49472,     0,     1, 49152, 49408, 49472, 49480,     0, 
+        1, 49152, 49408, 49472, 49480,     0,     1, 49152, 
+    49408, 49472, 49480, 49482,     0,     1, 49152, 49408, 
+    49472, 49480,     0,     1, 49152, 49408, 49472, 49488, 
+    49484,     0,     1, 49152, 49408, 49472, 49488, 49484, 
+        0,     1, 49152, 49408, 49472, 49488, 49489, 49486, 
+        0,     1, 49152, 49408, 49472,     0,     1, 49152, 
+    49408, 49472, 49488,     0,     1, 49152, 49408, 49472, 
+    49488,     0,     1, 49152, 49408, 49472, 49488, 49490, 
+        0,     1, 49152, 49408, 49472, 49488,     0,     1, 
+    49152, 49408, 49472, 49488, 49492,     0,     1, 49152, 
+    49408, 49472, 49488, 49492,     0,     1, 49152, 49408, 
+    49472, 49488, 49496, 49494,     0,     1, 49152, 49408, 
+    49472, 49488,     0,     1, 49152, 49408, 49472, 49504, 
+    49496,     0,     1, 49152, 49408, 49472, 49504, 49496, 
+        0,     1, 49152, 49408, 49472, 49504, 49496, 49498, 
+        0,     1, 49152, 49408, 49472, 49504, 49496,     0, 
+        1, 49152, 49408, 49472, 49504, 49505, 49500,     0, 
+        1, 49152, 49408, 49472, 49504, 49505, 49500,     0, 
+        1, 49152, 49408, 49472, 49504, 49505, 49500, 49502, 
+        0,     1, 49152, 49408, 49472,     0,     1, 49152, 
+    49408, 49536, 49504,     0,     1, 49152, 49408, 49536, 
+    49504,     0,     1, 49152, 49408, 49536, 49504, 49506, 
+        0,     1, 49152, 49408, 49536, 49504,     0,     1, 
+    49152, 49408, 49536, 49504, 49508,     0,     1, 49152, 
+    49408, 49536, 49504, 49508,     0,     1, 49152, 49408, 
+    49536, 49504, 49512, 49510,     0,     1, 49152, 49408, 
+    49536, 49504,     0,     1, 49152, 49408, 49536, 49504, 
+    49512,     0,     1, 49152, 49408, 49536, 49504, 49512, 
+        0,     1, 49152, 49408, 49536, 49504, 49512, 49514, 
+        0,     1, 49152, 49408, 49536, 49504, 49512,     0, 
+        1, 49152, 49408, 49536, 49504, 49520, 49516,     0, 
+        1, 49152, 49408, 49536, 49504, 49520, 49516,     0, 
+        1, 49152, 49408, 49536, 49504, 49520, 49521, 49518, 
+        0,     1, 49152, 49408, 49536, 49504,     0,     1, 
+    49152, 49408, 49536, 49537, 49520,     0,     1, 49152, 
+    49408, 49536, 49537, 49520,     0,     1, 49152, 49408, 
+    49536, 49537, 49520, 49522,     0,     1, 49152, 49408, 
+    49536, 49537, 49520,     0,     1, 49152, 49408, 49536, 
+    49537, 49520, 49524,     0,     1, 49152, 49408, 49536, 
+    49537, 49520, 49524,     0,     1, 49152, 49408, 49536, 
+    49537, 49520, 49528, 49526,     0,     1, 49152, 49408, 
+    49536, 49537, 49520,     0,     1, 49152, 49408, 49536, 
+    49537, 49520, 49528,     0,     1, 49152, 49408, 49536, 
+    49537, 49539, 49528,     0,     1, 49152, 49408, 49536, 
+    49537, 49539, 49528, 49530,     0,     1, 49152, 49408, 
+    49536, 49537, 49539, 49528,     0,     1, 49152, 49408, 
+    49536, 49537, 49539, 49528, 49532,     0,     1, 49152, 
+    49408, 49536, 49537, 49539, 49528, 49532,     0,     1, 
+    49152, 49408, 49536, 49537, 49539, 49528, 49532, 49534, 
+        0,     1, 49152, 49408,     0,     1, 49152, 49664, 
+    49536,     0,     1, 49152, 49664, 49536,     0,     1, 
+    49152, 49664, 49536, 49538,     0,     1, 49152, 49664, 
+    49536,     0,     1, 49152, 49664, 49536, 49540,     0, 
+        1, 49152, 49664, 49536, 49540,     0,     1, 49152, 
+    49664, 49536, 49544, 49542,     0,     1, 49152, 49664, 
+    49536,     0,     1, 49152, 49664, 49536, 49544,     0, 
+        1, 49152, 49664, 49536, 49544,     0,     1, 49152, 
+    49664, 49536, 49544, 49546,     0,     1, 49152, 49664, 
+    49536, 49544,     0,     1, 49152, 49664, 49536, 49552, 
+    49548,     0,     1, 49152, 49664, 49536, 49552, 49548, 
+        0,     1, 49152, 49664, 49536, 49552, 49553, 49550, 
+        0,     1, 49152, 49664, 49536,     0,     1, 49152, 
+    49664, 49536, 49552,     0,     1, 49152, 49664, 49536, 
+    49552,     0,     1, 49152, 49664, 49536, 49552, 49554, 
+        0,     1, 49152, 49664, 49536, 49552,     0,     1, 
+    49152, 49664, 49536, 49552, 49556,     0,     1, 49152, 
+    49664, 49536, 49552, 49556,     0,     1, 49152, 49664, 
+    49536, 49552, 49560, 49558,     0,     1, 49152, 49664, 
+    49536, 49552,     0,     1, 49152, 49664, 49536, 49568, 
+    49560,     0,     1, 49152, 49664, 49536, 49568, 49560, 
+        0,     1, 49152, 49664, 49536, 49568, 49560, 49562, 
+        0,     1, 49152, 49664, 49536, 49568, 49560,     0, 
+        1, 49152, 49664, 49536, 49568, 49569, 49564,     0, 
+        1, 49152, 49664, 49536, 49568, 49569, 49564,     0, 
+        1, 49152, 49664, 49536, 49568, 49569, 49564, 49566, 
+        0,     1, 49152, 49664, 49536,     0,     1, 49152, 
+    49664, 49536, 49568,     0,     1, 49152, 49664, 49536, 
+    49568,     0,     1, 49152, 49664, 49536, 49568, 49570, 
+        0,     1, 49152, 49664, 49536, 49568,     0,     1, 
+    49152, 49664, 49536, 49568, 49572,     0,     1, 49152, 
+    49664, 49536, 49568, 49572,     0,     1, 49152, 49664, 
+    49536, 49568, 49576, 49574,     0,     1, 49152, 49664, 
+    49536, 49568,     0,     1, 49152, 49664, 49536, 49568, 
+    49576,     0,     1, 49152, 49664, 49536, 49568, 49576, 
+        0,     1, 49152, 49664, 49536, 49568, 49576, 49578, 
+        0,     1, 49152, 49664, 49536, 49568, 49576,     0, 
+        1, 49152, 49664, 49536, 49568, 49584, 49580,     0, 
+        1, 49152, 49664, 49536, 49568, 49584, 49580,     0, 
+        1, 49152, 49664, 49536, 49568, 49584, 49585, 49582, 
+        0,     1, 49152, 49664, 49536, 49568,     0,     1, 
+    49152, 49664, 49536, 49600, 49584,     0,     1, 49152, 
+    49664, 49536, 49600, 49584,     0,     1, 49152, 49664, 
+    49536, 49600, 49584, 49586,     0,     1, 49152, 49664, 
+    49536, 49600, 49584,     0,     1, 49152, 49664, 49536, 
+    49600, 49584, 49588,     0,     1, 49152, 49664, 49536, 
+    49600, 49584, 49588,     0,     1, 49152, 49664, 49536, 
+    49600, 49584, 49592, 49590,     0,     1, 49152, 49664, 
+    49536, 49600, 49584,     0,     1, 49152, 49664, 49536, 
+    49600, 49601, 49592,     0,     1, 49152, 49664, 49536, 
+    49600, 49601, 49592,     0,     1, 49152, 49664, 49536, 
+    49600, 49601, 49592, 49594,     0,     1, 49152, 49664, 
+    49536, 49600, 49601, 49592,     0,     1, 49152, 49664, 
+    49536, 49600, 49601, 49592, 49596,     0,     1, 49152, 
+    49664, 49536, 49600, 49601, 49603, 49596,     0,     1, 
+    49152, 49664, 49536, 49600, 49601, 49603, 49596, 49598, 
+        0,     1, 49152, 49664, 49536,     0,     1, 49152, 
+    49664, 49665, 49600,     0,     1, 49152, 49664, 49665, 
+    49600,     0,     1, 49152, 49664, 49665, 49600, 49602, 
+        0,     1, 49152, 49664, 49665, 49600,     0,     1, 
+    49152, 49664, 49665, 49600, 49604,     0,     1, 49152, 
+    49664, 49665, 49600, 49604,     0,     1, 49152, 49664, 
+    49665, 49600, 49608, 49606,     0,     1, 49152, 49664, 
+    49665, 49600,     0,     1, 49152, 49664, 49665, 49600, 
+    49608,     0,     1, 49152, 49664, 49665, 49600, 49608, 
+        0,     1, 49152, 49664, 49665, 49600, 49608, 49610, 
+        0,     1, 49152, 49664, 49665, 49600, 49608,     0, 
+        1, 49152, 49664, 49665, 49600, 49616, 49612,     0, 
+        1, 49152, 49664, 49665, 49600, 49616, 49612,     0, 
+        1, 49152, 49664, 49665, 49600, 49616, 49617, 49614, 
+        0,     1, 49152, 49664, 49665, 49600,     0,     1, 
+    49152, 49664, 49665, 49600, 49616,     0,     1, 49152, 
+    49664, 49665, 49600, 49616,     0,     1, 49152, 49664, 
+    49665, 49600, 49616, 49618,     0,     1, 49152, 49664, 
+    49665, 49600, 49616,     0,     1, 49152, 49664, 49665, 
+    49600, 49616, 49620,     0,     1, 49152, 49664, 49665, 
+    49600, 49616, 49620,     0,     1, 49152, 49664, 49665, 
+    49600, 49616, 49624, 49622,     0,     1, 49152, 49664, 
+    49665, 49600, 49616,     0,     1, 49152, 49664, 49665, 
+    49600, 49632, 49624,     0,     1, 49152, 49664, 49665, 
+    49600, 49632, 49624,     0,     1, 49152, 49664, 49665, 
+    49600, 49632, 49624, 49626,     0,     1, 49152, 49664, 
+    49665, 49600, 49632, 49624,     0,     1, 49152, 49664, 
+    49665, 49600, 49632, 49633, 49628,     0,     1, 49152, 
+    49664, 49665, 49600, 49632, 49633, 49628,     0,     1, 
+    49152, 49664, 49665, 49600, 49632, 49633, 49628, 49630, 
+        0,     1, 49152, 49664, 49665, 49600,     0,     1, 
+    49152, 49664, 49665, 49600, 49632,     0,     1, 49152, 
+    49664, 49665, 49667, 49632,     0,     1, 49152, 49664, 
+    49665, 49667, 49632, 49634,     0,     1, 49152, 49664, 
+    49665, 49667, 49632,     0,     1, 49152, 49664, 49665, 
+    49667, 49632, 49636,     0,     1, 49152, 49664, 49665, 
+    49667, 49632, 49636,     0,     1, 49152, 49664, 49665, 
+    49667, 49632, 49640, 49638,     0,     1, 49152, 49664, 
+    49665, 49667, 49632,     0,     1, 49152, 49664, 49665, 
+    49667, 49632, 49640,     0,     1, 49152, 49664, 49665, 
+    49667, 49632, 49640,     0,     1, 49152, 49664, 49665, 
+    49667, 49632, 49640, 49642,     0,     1, 49152, 49664, 
+    49665, 49667, 49632, 49640,     0,     1, 49152, 49664, 
+    49665, 49667, 49632, 49648, 49644,     0,     1, 49152, 
+    49664, 49665, 49667, 49632, 49648, 49644,     0,     1, 
+    49152, 49664, 49665, 49667, 49632, 49648, 49649, 49646, 
+        0,     1, 49152, 49664, 49665, 49667, 49632,     0, 
+        1, 49152, 49664, 49665, 49667, 49632, 49648,     0, 
+        1, 49152, 49664, 49665, 49667, 49632, 49648,     0, 
+        1, 49152, 49664, 49665, 49667, 49632, 49648, 49650, 
+        0,     1, 49152, 49664, 49665, 49667, 49671, 49648, 
+        0,     1, 49152, 49664, 49665, 49667, 49671, 49648, 
+    49652,     0,     1, 49152, 49664, 49665, 49667, 49671, 
+    49648, 49652,     0,     1, 49152, 49664, 49665, 49667, 
+    49671, 49648, 49656, 49654,     0,     1, 49152, 49664, 
+    49665, 49667, 49671, 49648,     0,     1, 49152, 49664, 
+    49665, 49667, 49671, 49648, 49656,     0,     1, 49152, 
+    49664, 49665, 49667, 49671, 49648, 49656,     0,     1, 
+    49152, 49664, 49665, 49667, 49671, 49648, 49656, 49658, 
+        0,     1, 49152, 49664, 49665, 49667, 49671, 49648, 
+    49656,     0,     1, 49152, 49664, 49665, 49667, 49671, 
+    49648, 49656, 49660,     0,     1, 49152, 49664, 49665, 
+    49667, 49671, 49648, 49656, 49660,     0,     1, 49152, 
+    49664, 49665, 49667, 49671, 49648, 49656, 49660, 49662, 
+        0,     1, 49152,     0,     1, 49152, 49664,     0, 
+        1, 49152, 49664,     0,     1, 49152, 49664, 49666, 
+        0,     1, 49152, 49664,     0,     1, 49152, 49664, 
+    49668,     0,     1, 49152, 49664, 49668,     0,     1, 
+    49152, 49664, 49672, 49670,     0,     1, 49152, 49664, 
+        0,     1, 49152, 49664, 49672,     0,     1, 49152, 
+    49664, 49672,     0,     1, 49152, 49664, 49672, 49674, 
+        0,     1, 49152, 49664, 49672,     0,     1, 49152, 
+    49664, 49680, 49676,     0,     1, 49152, 49664, 49680, 
+    49676,     0,     1, 49152, 49664, 49680, 49681, 49678, 
+        0,     1, 49152, 49664,     0,     1, 49152, 49664, 
+    49680,     0,     1, 49152, 49664, 49680,     0,     1, 
+    49152, 49664, 49680, 49682,     0,     1, 49152, 49664, 
+    49680,     0,     1, 49152, 49664, 49680, 49684,     0, 
+        1, 49152, 49664, 49680, 49684,     0,     1, 49152, 
+    49664, 49680, 49688, 49686,     0,     1, 49152, 49664, 
+    49680,     0,     1, 49152, 49664, 49696, 49688,     0, 
+        1, 49152, 49664, 49696, 49688,     0,     1, 49152, 
+    49664, 49696, 49688, 49690,     0,     1, 49152, 49664, 
+    49696, 49688,     0,     1, 49152, 49664, 49696, 49697, 
+    49692,     0,     1, 49152, 49664, 49696, 49697, 49692, 
+        0,     1, 49152, 49664, 49696, 49697, 49692, 49694, 
+        0,     1, 49152, 49664,     0,     1, 49152, 49664, 
+    49696,     0,     1, 49152, 49664, 49696,     0,     1, 
+    49152, 49664, 49696, 49698,     0,     1, 49152, 49664, 
+    49696,     0,     1, 49152, 49664, 49696, 49700,     0, 
+        1, 49152, 49664, 49696, 49700,     0,     1, 49152, 
+    49664, 49696, 49704, 49702,     0,     1, 49152, 49664, 
+    49696,     0,     1, 49152, 49664, 49696, 49704,     0, 
+        1, 49152, 49664, 49696, 49704,     0,     1, 49152, 
+    49664, 49696, 49704, 49706,     0,     1, 49152, 49664, 
+    49696, 49704,     0,     1, 49152, 49664, 49696, 49712, 
+    49708,     0,     1, 49152, 49664, 49696, 49712, 49708, 
+        0,     1, 49152, 49664, 49696, 49712, 49713, 49710, 
+        0,     1, 49152, 49664, 49696,     0,     1, 49152, 
+    49664, 49728, 49712,     0,     1, 49152, 49664, 49728, 
+    49712,     0,     1, 49152, 49664, 49728, 49712, 49714, 
+        0,     1, 49152, 49664, 49728, 49712,     0,     1, 
+    49152, 49664, 49728, 49712, 49716,     0,     1, 49152, 
+    49664, 49728, 49712, 49716,     0,     1, 49152, 49664, 
+    49728, 49712, 49720, 49718,     0,     1, 49152, 49664, 
+    49728, 49712,     0,     1, 49152, 49664, 49728, 49729, 
+    49720,     0,     1, 49152, 49664, 49728, 49729, 49720, 
+        0,     1, 49152, 49664, 49728, 49729, 49720, 49722, 
+        0,     1, 49152, 49664, 49728, 49729, 49720,     0, 
+        1, 49152, 49664, 49728, 49729, 49720, 49724,     0, 
+        1, 49152, 49664, 49728, 49729, 49731, 49724,     0, 
+        1, 49152, 49664, 49728, 49729, 49731, 49724, 49726, 
+        0,     1, 49152, 49664,     0,     1, 49152, 49664, 
+    49728,     0,     1, 49152, 49664, 49728,     0,     1, 
+    49152, 49664, 49728, 49730,     0,     1, 49152, 49664, 
+    49728,     0,     1, 49152, 49664, 49728, 49732,     0, 
+        1, 49152, 49664, 49728, 49732,     0,     1, 49152, 
+    49664, 49728, 49736, 49734,     0,     1, 49152, 49664, 
+    49728,     0,     1, 49152, 49664, 49728, 49736,     0, 
+        1, 49152, 49664, 49728, 49736,     0,     1, 49152, 
+    49664, 49728, 49736, 49738,     0,     1, 49152, 49664, 
+    49728, 49736,     0,     1, 49152, 49664, 49728, 49744, 
+    49740,     0,     1, 49152, 49664, 49728, 49744, 49740, 
+        0,     1, 49152, 49664, 49728, 49744, 49745, 49742, 
+        0,     1, 49152, 49664, 49728,     0,     1, 49152, 
+    49664, 49728, 49744,     0,     1, 49152, 49664, 49728, 
+    49744,     0,     1, 49152, 49664, 49728, 49744, 49746, 
+        0,     1, 49152, 49664, 49728, 49744,     0,     1, 
+    49152, 49664, 49728, 49744, 49748,     0,     1, 49152, 
+    49664, 49728, 49744, 49748,     0,     1, 49152, 49664, 
+    49728, 49744, 49752, 49750,     0,     1, 49152, 49664, 
+    49728, 49744,     0,     1, 49152, 49664, 49728, 49760, 
+    49752,     0,     1, 49152, 49664, 49728, 49760, 49752, 
+        0,     1, 49152, 49664, 49728, 49760, 49752, 49754, 
+        0,     1, 49152, 49664, 49728, 49760, 49752,     0, 
+        1, 49152, 49664, 49728, 49760, 49761, 49756,     0, 
+        1, 49152, 49664, 49728, 49760, 49761, 49756,     0, 
+        1, 49152, 49664, 49728, 49760, 49761, 49756, 49758, 
+        0,     1, 49152, 49664, 49728,     0,     1, 49152, 
+    49664, 49792, 49760,     0,     1, 49152, 49664, 49792, 
+    49760,     0,     1, 49152, 49664, 49792, 49760, 49762, 
+        0,     1, 49152, 49664, 49792, 49760,     0,     1, 
+    49152, 49664, 49792, 49760, 49764,     0,     1, 49152, 
+    49664, 49792, 49760, 49764,     0,     1, 49152, 49664, 
+    49792, 49760, 49768, 49766,     0,     1, 49152, 49664, 
+    49792, 49760,     0,     1, 49152, 49664, 49792, 49760, 
+    49768,     0,     1, 49152, 49664, 49792, 49760, 49768, 
+        0,     1, 49152, 49664, 49792, 49760, 49768, 49770, 
+        0,     1, 49152, 49664, 49792, 49760, 49768,     0, 
+        1, 49152, 49664, 49792, 49760, 49776, 49772,     0, 
+        1, 49152, 49664, 49792, 49760, 49776, 49772,     0, 
+        1, 49152, 49664, 49792, 49760, 49776, 49777, 49774, 
+        0,     1, 49152, 49664, 49792, 49760,     0,     1, 
+    49152, 49664, 49792, 49793, 49776,     0,     1, 49152, 
+    49664, 49792, 49793, 49776,     0,     1, 49152, 49664, 
+    49792, 49793, 49776, 49778,     0,     1, 49152, 49664, 
+    49792, 49793, 49776,     0,     1, 49152, 49664, 49792, 
+    49793, 49776, 49780,     0,     1, 49152, 49664, 49792, 
+    49793, 49776, 49780,     0,     1, 49152, 49664, 49792, 
+    49793, 49776, 49784, 49782,     0,     1, 49152, 49664, 
+    49792, 49793, 49776,     0,     1, 49152, 49664, 49792, 
+    49793, 49776, 49784,     0,     1, 49152, 49664, 49792, 
+    49793, 49795, 49784,     0,     1, 49152, 49664, 49792, 
+    49793, 49795, 49784, 49786,     0,     1, 49152, 49664, 
+    49792, 49793, 49795, 49784,     0,     1, 49152, 49664, 
+    49792, 49793, 49795, 49784, 49788,     0,     1, 49152, 
+    49664, 49792, 49793, 49795, 49784, 49788,     0,     1, 
+    49152, 49664, 49792, 49793, 49795, 49784, 49788, 49790, 
+        0,     1, 49152, 49664,     0,     1, 49152, 49664, 
+    49792,     0,     1, 49152, 49664, 49792,     0,     1, 
+    49152, 49664, 49792, 49794,     0,     1, 49152, 49664, 
+    49792,     0,     1, 49152, 49664, 49792, 49796,     0, 
+        1, 49152, 49664, 49792, 49796,     0,     1, 49152, 
+    49664, 49792, 49800, 49798,     0,     1, 49152, 49664, 
+    49792,     0,     1, 49152, 49664, 49792, 49800,     0, 
+        1, 49152, 49664, 49792, 49800,     0,     1, 49152, 
+    49664, 49792, 49800, 49802,     0,     1, 49152, 49664, 
+    49792, 49800,     0,     1, 49152, 49664, 49792, 49808, 
+    49804,     0,     1, 49152, 49664, 49792, 49808, 49804, 
+        0,     1, 49152, 49664, 49792, 49808, 49809, 49806, 
+        0,     1, 49152, 49664, 49792,     0,     1, 49152, 
+    49664, 49792, 49808,     0,     1, 49152, 49664, 49792, 
+    49808,     0,     1, 49152, 49664, 49792, 49808, 49810, 
+        0,     1, 49152, 49664, 49792, 49808,     0,     1, 
+    49152, 49664, 49792, 49808, 49812,     0,     1, 49152, 
+    49664, 49792, 49808, 49812,     0,     1, 49152, 49664, 
+    49792, 49808, 49816, 49814,     0,     1, 49152, 49664, 
+    49792, 49808,     0,     1, 49152, 49664, 49792, 49824, 
+    49816,     0,     1, 49152, 49664, 49792, 49824, 49816, 
+        0,     1, 49152, 49664, 49792, 49824, 49816, 49818, 
+        0,     1, 49152, 49664, 49792, 49824, 49816,     0, 
+        1, 49152, 49664, 49792, 49824, 49825, 49820,     0, 
+        1, 49152, 49664, 49792, 49824, 49825, 49820,     0, 
+        1, 49152, 49664, 49792, 49824, 49825, 49820, 49822, 
+        0,     1, 49152, 49664, 49792,     0,     1, 49152, 
+    49664, 49792, 49824,     0,     1, 49152, 49664, 49792, 
+    49824,     0,     1, 49152, 49664, 49792, 49824, 49826, 
+        0,     1, 49152, 49664, 49792, 49824,     0,     1, 
+    49152, 49664, 49792, 49824, 49828,     0,     1, 49152, 
+    49664, 49792, 49824, 49828,     0,     1, 49152, 49664, 
+    49792, 49824, 49832, 49830,     0,     1, 49152, 49664, 
+    49792, 49824,     0,     1, 49152, 49664, 49792, 49824, 
+    49832,     0,     1, 49152, 49664, 49792, 49824, 49832, 
+        0,     1, 49152, 49664, 49792, 49824, 49832, 49834, 
+        0,     1, 49152, 49664, 49792, 49824, 49832,     0, 
+        1, 49152, 49664, 49792, 49824, 49840, 49836,     0, 
+        1, 49152, 49664, 49792, 49824, 49840, 49836,     0, 
+        1, 49152, 49664, 49792, 49824, 49840, 49841, 49838, 
+        0,     1, 49152, 49664, 49792, 49824,     0,     1, 
+    49152, 49664, 49792, 49856, 49840,     0,     1, 49152, 
+    49664, 49792, 49856, 49840,     0,     1, 49152, 49664, 
+    49792, 49856, 49840, 49842,     0,     1, 49152, 49664, 
+    49792, 49856, 49840,     0,     1, 49152, 49664, 49792, 
+    49856, 49840, 49844,     0,     1, 49152, 49664, 49792, 
+    49856, 49840, 49844,     0,     1, 49152, 49664, 49792, 
+    49856, 49840, 49848, 49846,     0,     1, 49152, 49664, 
+    49792, 49856, 49840,     0,     1, 49152, 49664, 49792, 
+    49856, 49857, 49848,     0,     1, 49152, 49664, 49792, 
+    49856, 49857, 49848,     0,     1, 49152, 49664, 49792, 
+    49856, 49857, 49848, 49850,     0,     1, 49152, 49664, 
+    49792, 49856, 49857, 49848,     0,     1, 49152, 49664, 
+    49792, 49856, 49857, 49848, 49852,     0,     1, 49152, 
+    49664, 49792, 49856, 49857, 49859, 49852,     0,     1, 
+    49152, 49664, 49792, 49856, 49857, 49859, 49852, 49854, 
+        0,     1, 49152, 49664, 49792,     0,     1, 49152, 
+    49664, 49920, 49856,     0,     1, 49152, 49664, 49920, 
+    49856,     0,     1, 49152, 49664, 49920, 49856, 49858, 
+        0,     1, 49152, 49664, 49920, 49856,     0,     1, 
+    49152, 49664, 49920, 49856, 49860,     0,     1, 49152, 
+    49664, 49920, 49856, 49860,     0,     1, 49152, 49664, 
+    49920, 49856, 49864, 49862,     0,     1, 49152, 49664, 
+    49920, 49856,     0,     1, 49152, 49664, 49920, 49856, 
+    49864,     0,     1, 49152, 49664, 49920, 49856, 49864, 
+        0,     1, 49152, 49664, 49920, 49856, 49864, 49866, 
+        0,     1, 49152, 49664, 49920, 49856, 49864,     0, 
+        1, 49152, 49664, 49920, 49856, 49872, 49868,     0, 
+        1, 49152, 49664, 49920, 49856, 49872, 49868,     0, 
+        1, 49152, 49664, 49920, 49856, 49872, 49873, 49870, 
+        0,     1, 49152, 49664, 49920, 49856,     0,     1, 
+    49152, 49664, 49920, 49856, 49872,     0,     1, 49152, 
+    49664, 49920, 49856, 49872,     0,     1, 49152, 49664, 
+    49920, 49856, 49872, 49874,     0,     1, 49152, 49664, 
+    49920, 49856, 49872,     0,     1, 49152, 49664, 49920, 
+    49856, 49872, 49876,     0,     1, 49152, 49664, 49920, 
+    49856, 49872, 49876,     0,     1, 49152, 49664, 49920, 
+    49856, 49872, 49880, 49878,     0,     1, 49152, 49664, 
+    49920, 49856, 49872,     0,     1, 49152, 49664, 49920, 
+    49856, 49888, 49880,     0,     1, 49152, 49664, 49920, 
+    49856, 49888, 49880,     0,     1, 49152, 49664, 49920, 
+    49856, 49888, 49880, 49882,     0,     1, 49152, 49664, 
+    49920, 49856, 49888, 49880,     0,     1, 49152, 49664, 
+    49920, 49856, 49888, 49889, 49884,     0,     1, 49152, 
+    49664, 49920, 49856, 49888, 49889, 49884,     0,     1, 
+    49152, 49664, 49920, 49856, 49888, 49889, 49884, 49886, 
+        0,     1, 49152, 49664, 49920, 49856,     0,     1, 
+    49152, 49664, 49920, 49921, 49888,     0,     1, 49152, 
+    49664, 49920, 49921, 49888,     0,     1, 49152, 49664, 
+    49920, 49921, 49888, 49890,     0,     1, 49152, 49664, 
+    49920, 49921, 49888,     0,     1, 49152, 49664, 49920, 
+    49921, 49888, 49892,     0,     1, 49152, 49664, 49920, 
+    49921, 49888, 49892,     0,     1, 49152, 49664, 49920, 
+    49921, 49888, 49896, 49894,     0,     1, 49152, 49664, 
+    49920, 49921, 49888,     0,     1, 49152, 49664, 49920, 
+    49921, 49888, 49896,     0,     1, 49152, 49664, 49920, 
+    49921, 49888, 49896,     0,     1, 49152, 49664, 49920, 
+    49921, 49888, 49896, 49898,     0,     1, 49152, 49664, 
+    49920, 49921, 49888, 49896,     0,     1, 49152, 49664, 
+    49920, 49921, 49888, 49904, 49900,     0,     1, 49152, 
+    49664, 49920, 49921, 49888, 49904, 49900,     0,     1, 
+    49152, 49664, 49920, 49921, 49888, 49904, 49905, 49902, 
+        0,     1, 49152, 49664, 49920, 49921, 49888,     0, 
+        1, 49152, 49664, 49920, 49921, 49888, 49904,     0, 
+        1, 49152, 49664, 49920, 49921, 49923, 49904,     0, 
+        1, 49152, 49664, 49920, 49921, 49923, 49904, 49906, 
+        0,     1, 49152, 49664, 49920, 49921, 49923, 49904, 
+        0,     1, 49152, 49664, 49920, 49921, 49923, 49904, 
+    49908,     0,     1, 49152, 49664, 49920, 49921, 49923, 
+    49904, 49908,     0,     1, 49152, 49664, 49920, 49921, 
+    49923, 49904, 49912, 49910,     0,     1, 49152, 49664, 
+    49920, 49921, 49923, 49904,     0,     1, 49152, 49664, 
+    49920, 49921, 49923, 49904, 49912,     0,     1, 49152, 
+    49664, 49920, 49921, 49923, 49904, 49912,     0,     1, 
+    49152, 49664, 49920, 49921, 49923, 49904, 49912, 49914, 
+        0,     1, 49152, 49664, 49920, 49921, 49923, 49927, 
+    49912,     0,     1, 49152, 49664, 49920, 49921, 49923, 
+    49927, 49912, 49916,     0,     1, 49152, 49664, 49920, 
+    49921, 49923, 49927, 49912, 49916,     0,     1, 49152, 
+    49664, 49920, 49921, 49923, 49927, 49912, 49916, 49918, 
+        0,     1, 49152, 49664,     0,     1, 49152, 50176, 
+    49920,     0,     1, 49152, 50176, 49920,     0,     1, 
+    49152, 50176, 49920, 49922,     0,     1, 49152, 50176, 
+    49920,     0,     1, 49152, 50176, 49920, 49924,     0, 
+        1, 49152, 50176, 49920, 49924,     0,     1, 49152, 
+    50176, 49920, 49928, 49926,     0,     1, 49152, 50176, 
+    49920,     0,     1, 49152, 50176, 49920, 49928,     0, 
+        1, 49152, 50176, 49920, 49928,     0,     1, 49152, 
+    50176, 49920, 49928, 49930,     0,     1, 49152, 50176, 
+    49920, 49928,     0,     1, 49152, 50176, 49920, 49936, 
+    49932,     0,     1, 49152, 50176, 49920, 49936, 49932, 
+        0,     1, 49152, 50176, 49920, 49936, 49937, 49934, 
+        0,     1, 49152, 50176, 49920,     0,     1, 49152, 
+    50176, 49920, 49936,     0,     1, 49152, 50176, 49920, 
+    49936,     0,     1, 49152, 50176, 49920, 49936, 49938, 
+        0,     1, 49152, 50176, 49920, 49936,     0,     1, 
+    49152, 50176, 49920, 49936, 49940,     0,     1, 49152, 
+    50176, 49920, 49936, 49940,     0,     1, 49152, 50176, 
+    49920, 49936, 49944, 49942,     0,     1, 49152, 50176, 
+    49920, 49936,     0,     1, 49152, 50176, 49920, 49952, 
+    49944,     0,     1, 49152, 50176, 49920, 49952, 49944, 
+        0,     1, 49152, 50176, 49920, 49952, 49944, 49946, 
+        0,     1, 49152, 50176, 49920, 49952, 49944,     0, 
+        1, 49152, 50176, 49920, 49952, 49953, 49948,     0, 
+        1, 49152, 50176, 49920, 49952, 49953, 49948,     0, 
+        1, 49152, 50176, 49920, 49952, 49953, 49948, 49950, 
+        0,     1, 49152, 50176, 49920,     0,     1, 49152, 
+    50176, 49920, 49952,     0,     1, 49152, 50176, 49920, 
+    49952,     0,     1, 49152, 50176, 49920, 49952, 49954, 
+        0,     1, 49152, 50176, 49920, 49952,     0,     1, 
+    49152, 50176, 49920, 49952, 49956,     0,     1, 49152, 
+    50176, 49920, 49952, 49956,     0,     1, 49152, 50176, 
+    49920, 49952, 49960, 49958,     0,     1, 49152, 50176, 
+    49920, 49952,     0,     1, 49152, 50176, 49920, 49952, 
+    49960,     0,     1, 49152, 50176, 49920, 49952, 49960, 
+        0,     1, 49152, 50176, 49920, 49952, 49960, 49962, 
+        0,     1, 49152, 50176, 49920, 49952, 49960,     0, 
+        1, 49152, 50176, 49920, 49952, 49968, 49964,     0, 
+        1, 49152, 50176, 49920, 49952, 49968, 49964,     0, 
+        1, 49152, 50176, 49920, 49952, 49968, 49969, 49966, 
+        0,     1, 49152, 50176, 49920, 49952,     0,     1, 
+    49152, 50176, 49920, 49984, 49968,     0,     1, 49152, 
+    50176, 49920, 49984, 49968,     0,     1, 49152, 50176, 
+    49920, 49984, 49968, 49970,     0,     1, 49152, 50176, 
+    49920, 49984, 49968,     0,     1, 49152, 50176, 49920, 
+    49984, 49968, 49972,     0,     1, 49152, 50176, 49920, 
+    49984, 49968, 49972,     0,     1, 49152, 50176, 49920, 
+    49984, 49968, 49976, 49974,     0,     1, 49152, 50176, 
+    49920, 49984, 49968,     0,     1, 49152, 50176, 49920, 
+    49984, 49985, 49976,     0,     1, 49152, 50176, 49920, 
+    49984, 49985, 49976,     0,     1, 49152, 50176, 49920, 
+    49984, 49985, 49976, 49978,     0,     1, 49152, 50176, 
+    49920, 49984, 49985, 49976,     0,     1, 49152, 50176, 
+    49920, 49984, 49985, 49976, 49980,     0,     1, 49152, 
+    50176, 49920, 49984, 49985, 49987, 49980,     0,     1, 
+    49152, 50176, 49920, 49984, 49985, 49987, 49980, 49982, 
+        0,     1, 49152, 50176, 49920,     0,     1, 49152, 
+    50176, 49920, 49984,     0,     1, 49152, 50176, 49920, 
+    49984,     0,     1, 49152, 50176, 49920, 49984, 49986, 
+        0,     1, 49152, 50176, 49920, 49984,     0,     1, 
+    49152, 50176, 49920, 49984, 49988,     0,     1, 49152, 
+    50176, 49920, 49984, 49988,     0,     1, 49152, 50176, 
+    49920, 49984, 49992, 49990,     0,     1, 49152, 50176, 
+    49920, 49984,     0,     1, 49152, 50176, 49920, 49984, 
+    49992,     0,     1, 49152, 50176, 49920, 49984, 49992, 
+        0,     1, 49152, 50176, 49920, 49984, 49992, 49994, 
+        0,     1, 49152, 50176, 49920, 49984, 49992,     0, 
+        1, 49152, 50176, 49920, 49984, 50000, 49996,     0, 
+        1, 49152, 50176, 49920, 49984, 50000, 49996,     0, 
+        1, 49152, 50176, 49920, 49984, 50000, 50001, 49998, 
+        0,     1, 49152, 50176, 49920, 49984,     0,     1, 
+    49152, 50176, 49920, 49984, 50000,     0,     1, 49152, 
+    50176, 49920, 49984, 50000,     0,     1, 49152, 50176, 
+    49920, 49984, 50000, 50002,     0,     1, 49152, 50176, 
+    49920, 49984, 50000,     0,     1, 49152, 50176, 49920, 
+    49984, 50000, 50004,     0,     1, 49152, 50176, 49920, 
+    49984, 50000, 50004,     0,     1, 49152, 50176, 49920, 
+    49984, 50000, 50008, 50006,     0,     1, 49152, 50176, 
+    49920, 49984, 50000,     0,     1, 49152, 50176, 49920, 
+    49984, 50016, 50008,     0,     1, 49152, 50176, 49920, 
+    49984, 50016, 50008,     0,     1, 49152, 50176, 49920, 
+    49984, 50016, 50008, 50010,     0,     1, 49152, 50176, 
+    49920, 49984, 50016, 50008,     0,     1, 49152, 50176, 
+    49920, 49984, 50016, 50017, 50012,     0,     1, 49152, 
+    50176, 49920, 49984, 50016, 50017, 50012,     0,     1, 
+    49152, 50176, 49920, 49984, 50016, 50017, 50012, 50014, 
+        0,     1, 49152, 50176, 49920, 49984,     0,     1, 
+    49152, 50176, 49920, 50048, 50016,     0,     1, 49152, 
+    50176, 49920, 50048, 50016,     0,     1, 49152, 50176, 
+    49920, 50048, 50016, 50018,     0,     1, 49152, 50176, 
+    49920, 50048, 50016,     0,     1, 49152, 50176, 49920, 
+    50048, 50016, 50020,     0,     1, 49152, 50176, 49920, 
+    50048, 50016, 50020,     0,     1, 49152, 50176, 49920, 
+    50048, 50016, 50024, 50022,     0,     1, 49152, 50176, 
+    49920, 50048, 50016,     0,     1, 49152, 50176, 49920, 
+    50048, 50016, 50024,     0,     1, 49152, 50176, 49920, 
+    50048, 50016, 50024,     0,     1, 49152, 50176, 49920, 
+    50048, 50016, 50024, 50026,     0,     1, 49152, 50176, 
+    49920, 50048, 50016, 50024,     0,     1, 49152, 50176, 
+    49920, 50048, 50016, 50032, 50028,     0,     1, 49152, 
+    50176, 49920, 50048, 50016, 50032, 50028,     0,     1, 
+    49152, 50176, 49920, 50048, 50016, 50032, 50033, 50030, 
+        0,     1, 49152, 50176, 49920, 50048, 50016,     0, 
+        1, 49152, 50176, 49920, 50048, 50049, 50032,     0, 
+        1, 49152, 50176, 49920, 50048, 50049, 50032,     0, 
+        1, 49152, 50176, 49920, 50048, 50049, 50032, 50034, 
+        0,     1, 49152, 50176, 49920, 50048, 50049, 50032, 
+        0,     1, 49152, 50176, 49920, 50048, 50049, 50032, 
+    50036,     0,     1, 49152, 50176, 49920, 50048, 50049, 
+    50032, 50036,     0,     1, 49152, 50176, 49920, 50048, 
+    50049, 50032, 50040, 50038,     0,     1, 49152, 50176, 
+    49920, 50048, 50049, 50032,     0,     1, 49152, 50176, 
+    49920, 50048, 50049, 50032, 50040,     0,     1, 49152, 
+    50176, 49920, 50048, 50049, 50051, 50040,     0,     1, 
+    49152, 50176, 49920, 50048, 50049, 50051, 50040, 50042, 
+        0,     1, 49152, 50176, 49920, 50048, 50049, 50051, 
+    50040,     0,     1, 49152, 50176, 49920, 50048, 50049, 
+    50051, 50040, 50044,     0,     1, 49152, 50176, 49920, 
+    50048, 50049, 50051, 50040, 50044,     0,     1, 49152, 
+    50176, 49920, 50048, 50049, 50051, 50040, 50044, 50046, 
+        0,     1, 49152, 50176, 49920,     0,     1, 49152, 
+    50176, 49920, 50048,     0,     1, 49152, 50176, 50177, 
+    50048,     0,     1, 49152, 50176, 50177, 50048, 50050, 
+        0,     1, 49152, 50176, 50177, 50048,     0,     1, 
+    49152, 50176, 50177, 50048, 50052,     0,     1, 49152, 
+    50176, 50177, 50048, 50052,     0,     1, 49152, 50176, 
+    50177, 50048, 50056, 50054,     0,     1, 49152, 50176, 
+    50177, 50048,     0,     1, 49152, 50176, 50177, 50048, 
+    50056,     0,     1, 49152, 50176, 50177, 50048, 50056, 
+        0,     1, 49152, 50176, 50177, 50048, 50056, 50058, 
+        0,     1, 49152, 50176, 50177, 50048, 50056,     0, 
+        1, 49152, 50176, 50177, 50048, 50064, 50060,     0, 
+        1, 49152, 50176, 50177, 50048, 50064, 50060,     0, 
+        1, 49152, 50176, 50177, 50048, 50064, 50065, 50062, 
+        0,     1, 49152, 50176, 50177, 50048,     0,     1, 
+    49152, 50176, 50177, 50048, 50064,     0,     1, 49152, 
+    50176, 50177, 50048, 50064,     0,     1, 49152, 50176, 
+    50177, 50048, 50064, 50066,     0,     1, 49152, 50176, 
+    50177, 50048, 50064,     0,     1, 49152, 50176, 50177, 
+    50048, 50064, 50068,     0,     1, 49152, 50176, 50177, 
+    50048, 50064, 50068,     0,     1, 49152, 50176, 50177, 
+    50048, 50064, 50072, 50070,     0,     1, 49152, 50176, 
+    50177, 50048, 50064,     0,     1, 49152, 50176, 50177, 
+    50048, 50080, 50072,     0,     1, 49152, 50176, 50177, 
+    50048, 50080, 50072,     0,     1, 49152, 50176, 50177, 
+    50048, 50080, 50072, 50074,     0,     1, 49152, 50176, 
+    50177, 50048, 50080, 50072,     0,     1, 49152, 50176, 
+    50177, 50048, 50080, 50081, 50076,     0,     1, 49152, 
+    50176, 50177, 50048, 50080, 50081, 50076,     0,     1, 
+    49152, 50176, 50177, 50048, 50080, 50081, 50076, 50078, 
+        0,     1, 49152, 50176, 50177, 50048,     0,     1, 
+    49152, 50176, 50177, 50048, 50080,     0,     1, 49152, 
+    50176, 50177, 50048, 50080,     0,     1, 49152, 50176, 
+    50177, 50048, 50080, 50082,     0,     1, 49152, 50176, 
+    50177, 50048, 50080,     0,     1, 49152, 50176, 50177, 
+    50048, 50080, 50084,     0,     1, 49152, 50176, 50177, 
+    50048, 50080, 50084,     0,     1, 49152, 50176, 50177, 
+    50048, 50080, 50088, 50086,     0,     1, 49152, 50176, 
+    50177, 50048, 50080,     0,     1, 49152, 50176, 50177, 
+    50048, 50080, 50088,     0,     1, 49152, 50176, 50177, 
+    50048, 50080, 50088,     0,     1, 49152, 50176, 50177, 
+    50048, 50080, 50088, 50090,     0,     1, 49152, 50176, 
+    50177, 50048, 50080, 50088,     0,     1, 49152, 50176, 
+    50177, 50048, 50080, 50096, 50092,     0,     1, 49152, 
+    50176, 50177, 50048, 50080, 50096, 50092,     0,     1, 
+    49152, 50176, 50177, 50048, 50080, 50096, 50097, 50094, 
+        0,     1, 49152, 50176, 50177, 50048, 50080,     0, 
+        1, 49152, 50176, 50177, 50048, 50112, 50096,     0, 
+        1, 49152, 50176, 50177, 50048, 50112, 50096,     0, 
+        1, 49152, 50176, 50177, 50048, 50112, 50096, 50098, 
+        0,     1, 49152, 50176, 50177, 50048, 50112, 50096, 
+        0,     1, 49152, 50176, 50177, 50048, 50112, 50096, 
+    50100,     0,     1, 49152, 50176, 50177, 50048, 50112, 
+    50096, 50100,     0,     1, 49152, 50176, 50177, 50048, 
+    50112, 50096, 50104, 50102,     0,     1, 49152, 50176, 
+    50177, 50048, 50112, 50096,     0,     1, 49152, 50176, 
+    50177, 50048, 50112, 50113, 50104,     0,     1, 49152, 
+    50176, 50177, 50048, 50112, 50113, 50104,     0,     1, 
+    49152, 50176, 50177, 50048, 50112, 50113, 50104, 50106, 
+        0,     1, 49152, 50176, 50177, 50048, 50112, 50113, 
+    50104,     0,     1, 49152, 50176, 50177, 50048, 50112, 
+    50113, 50104, 50108,     0,     1, 49152, 50176, 50177, 
+    50048, 50112, 50113, 50115, 50108,     0,     1, 49152, 
+    50176, 50177, 50048, 50112, 50113, 50115, 50108, 50110, 
+        0,     1, 49152, 50176, 50177, 50048,     0,     1, 
+    49152, 50176, 50177, 50048, 50112,     0,     1, 49152, 
+    50176, 50177, 50048, 50112,     0,     1, 49152, 50176, 
+    50177, 50048, 50112, 50114,     0,     1, 49152, 50176, 
+    50177, 50179, 50112,     0,     1, 49152, 50176, 50177, 
+    50179, 50112, 50116,     0,     1, 49152, 50176, 50177, 
+    50179, 50112, 50116,     0,     1, 49152, 50176, 50177, 
+    50179, 50112, 50120, 50118,     0,     1, 49152, 50176, 
+    50177, 50179, 50112,     0,     1, 49152, 50176, 50177, 
+    50179, 50112, 50120,     0,     1, 49152, 50176, 50177, 
+    50179, 50112, 50120,     0,     1, 49152, 50176, 50177, 
+    50179, 50112, 50120, 50122,     0,     1, 49152, 50176, 
+    50177, 50179, 50112, 50120,     0,     1, 49152, 50176, 
+    50177, 50179, 50112, 50128, 50124,     0,     1, 49152, 
+    50176, 50177, 50179, 50112, 50128, 50124,     0,     1, 
+    49152, 50176, 50177, 50179, 50112, 50128, 50129, 50126, 
+        0,     1, 49152, 50176, 50177, 50179, 50112,     0, 
+        1, 49152, 50176, 50177, 50179, 50112, 50128,     0, 
+        1, 49152, 50176, 50177, 50179, 50112, 50128,     0, 
+        1, 49152, 50176, 50177, 50179, 50112, 50128, 50130, 
+        0,     1, 49152, 50176, 50177, 50179, 50112, 50128, 
+        0,     1, 49152, 50176, 50177, 50179, 50112, 50128, 
+    50132,     0,     1, 49152, 50176, 50177, 50179, 50112, 
+    50128, 50132,     0,     1, 49152, 50176, 50177, 50179, 
+    50112, 50128, 50136, 50134,     0,     1, 49152, 50176, 
+    50177, 50179, 50112, 50128,     0,     1, 49152, 50176, 
+    50177, 50179, 50112, 50144, 50136,     0,     1, 49152, 
+    50176, 50177, 50179, 50112, 50144, 50136,     0,     1, 
+    49152, 50176, 50177, 50179, 50112, 50144, 50136, 50138, 
+        0,     1, 49152, 50176, 50177, 50179, 50112, 50144, 
+    50136,     0,     1, 49152, 50176, 50177, 50179, 50112, 
+    50144, 50145, 50140,     0,     1, 49152, 50176, 50177, 
+    50179, 50112, 50144, 50145, 50140,     0,     1, 49152, 
+    50176, 50177, 50179, 50112, 50144, 50145, 50140, 50142, 
+        0,     1, 49152, 50176, 50177, 50179, 50112,     0, 
+        1, 49152, 50176, 50177, 50179, 50112, 50144,     0, 
+        1, 49152, 50176, 50177, 50179, 50112, 50144,     0, 
+        1, 49152, 50176, 50177, 50179, 50112, 50144, 50146, 
+        0,     1, 49152, 50176, 50177, 50179, 50112, 50144, 
+        0,     1, 49152, 50176, 50177, 50179, 50112, 50144, 
+    50148,     0,     1, 49152, 50176, 50177, 50179, 50112, 
+    50144, 50148,     0,     1, 49152, 50176, 50177, 50179, 
+    50112, 50144, 50152, 50150,     0,     1, 49152, 50176, 
+    50177, 50179, 50183, 50144,     0,     1, 49152, 50176, 
+    50177, 50179, 50183, 50144, 50152,     0,     1, 49152, 
+    50176, 50177, 50179, 50183, 50144, 50152,     0,     1, 
+    49152, 50176, 50177, 50179, 50183, 50144, 50152, 50154, 
+        0,     1, 49152, 50176, 50177, 50179, 50183, 50144, 
+    50152,     0,     1, 49152, 50176, 50177, 50179, 50183, 
+    50144, 50160, 50156,     0,     1, 49152, 50176, 50177, 
+    50179, 50183, 50144, 50160, 50156,     0,     1, 49152, 
+    50176, 50177, 50179, 50183, 50144, 50160, 50161, 50158, 
+        0,     1, 49152, 50176, 50177, 50179, 50183, 50144, 
+        0,     1, 49152, 50176, 50177, 50179, 50183, 50144, 
+    50160,     0,     1, 49152, 50176, 50177, 50179, 50183, 
+    50144, 50160,     0,     1, 49152, 50176, 50177, 50179, 
+    50183, 50144, 50160, 50162,     0,     1, 49152, 50176, 
+    50177, 50179, 50183, 50144, 50160,     0,     1, 49152, 
+    50176, 50177, 50179, 50183, 50144, 50160, 50164,     0, 
+        1, 49152, 50176, 50177, 50179, 50183, 50144, 50160, 
+    50164,     0,     1, 49152, 50176, 50177, 50179, 50183, 
+    50144, 50160, 50168, 50166,     0,     1, 49152, 50176, 
+    50177, 50179, 50183, 50144, 50160,     0,     1, 49152, 
+    50176, 50177, 50179, 50183, 50144, 50160, 50168,     0, 
+        1, 49152, 50176, 50177, 50179, 50183, 50144, 50160, 
+    50168,     0,     1, 49152, 50176, 50177, 50179, 50183, 
+    50144, 50160, 50168, 50170,     0,     1, 49152, 50176, 
+    50177, 50179, 50183, 50144, 50160, 50168,     0,     1, 
+    49152, 50176, 50177, 50179, 50183, 50144, 50160, 50168, 
+    50172,     0,     1, 49152, 50176, 50177, 50179, 50183, 
+    50144, 50160, 50168, 50172,     0,     1, 49152, 50176, 
+    50177, 50179, 50183, 50144, 50160, 50168, 50172, 50174, 
+        0,     1, 49152,     0,     1, 49152, 50176,     0, 
+        1, 49152, 50176,     0,     1, 49152, 50176, 50178, 
+        0,     1, 49152, 50176,     0,     1, 49152, 50176, 
+    50180,     0,     1, 49152, 50176, 50180,     0,     1, 
+    49152, 50176, 50184, 50182,     0,     1, 49152, 50176, 
+        0,     1, 49152, 50176, 50184,     0,     1, 49152, 
+    50176, 50184,     0,     1, 49152, 50176, 50184, 50186, 
+        0,     1, 49152, 50176, 50184,     0,     1, 49152, 
+    50176, 50192, 50188,     0,     1, 49152, 50176, 50192, 
+    50188,     0,     1, 49152, 50176, 50192, 50193, 50190, 
+        0,     1, 49152, 50176,     0,     1, 49152, 50176, 
+    50192,     0,     1, 49152, 50176, 50192,     0,     1, 
+    49152, 50176, 50192, 50194,     0,     1, 49152, 50176, 
+    50192,     0,     1, 49152, 50176, 50192, 50196,     0, 
+        1, 49152, 50176, 50192, 50196,     0,     1, 49152, 
+    50176, 50192, 50200, 50198,     0,     1, 49152, 50176, 
+    50192,     0,     1, 49152, 50176, 50208, 50200,     0, 
+        1, 49152, 50176, 50208, 50200,     0,     1, 49152, 
+    50176, 50208, 50200, 50202,     0,     1, 49152, 50176, 
+    50208, 50200,     0,     1, 49152, 50176, 50208, 50209, 
+    50204,     0,     1, 49152, 50176, 50208, 50209, 50204, 
+        0,     1, 49152, 50176, 50208, 50209, 50204, 50206, 
+        0,     1, 49152, 50176,     0,     1, 49152, 50176, 
+    50208,     0,     1, 49152, 50176, 50208,     0,     1, 
+    49152, 50176, 50208, 50210,     0,     1, 49152, 50176, 
+    50208,     0,     1, 49152, 50176, 50208, 50212,     0, 
+        1, 49152, 50176, 50208, 50212,     0,     1, 49152, 
+    50176, 50208, 50216, 50214,     0,     1, 49152, 50176, 
+    50208,     0,     1, 49152, 50176, 50208, 50216,     0, 
+        1, 49152, 50176, 50208, 50216,     0,     1, 49152, 
+    50176, 50208, 50216, 50218,     0,     1, 49152, 50176, 
+    50208, 50216,     0,     1, 49152, 50176, 50208, 50224, 
+    50220,     0,     1, 49152, 50176, 50208, 50224, 50220, 
+        0,     1, 49152, 50176, 50208, 50224, 50225, 50222, 
+        0,     1, 49152, 50176, 50208,     0,     1, 49152, 
+    50176, 50240, 50224,     0,     1, 49152, 50176, 50240, 
+    50224,     0,     1, 49152, 50176, 50240, 50224, 50226, 
+        0,     1, 49152, 50176, 50240, 50224,     0,     1, 
+    49152, 50176, 50240, 50224, 50228,     0,     1, 49152, 
+    50176, 50240, 50224, 50228,     0,     1, 49152, 50176, 
+    50240, 50224, 50232, 50230,     0,     1, 49152, 50176, 
+    50240, 50224,     0,     1, 49152, 50176, 50240, 50241, 
+    50232,     0,     1, 49152, 50176, 50240, 50241, 50232, 
+        0,     1, 49152, 50176, 50240, 50241, 50232, 50234, 
+        0,     1, 49152, 50176, 50240, 50241, 50232,     0, 
+        1, 49152, 50176, 50240, 50241, 50232, 50236,     0, 
+        1, 49152, 50176, 50240, 50241, 50243, 50236,     0, 
+        1, 49152, 50176, 50240, 50241, 50243, 50236, 50238, 
+        0,     1, 49152, 50176,     0,     1, 49152, 50176, 
+    50240,     0,     1, 49152, 50176, 50240,     0,     1, 
+    49152, 50176, 50240, 50242,     0,     1, 49152, 50176, 
+    50240,     0,     1, 49152, 50176, 50240, 50244,     0, 
+        1, 49152, 50176, 50240, 50244,     0,     1, 49152, 
+    50176, 50240, 50248, 50246,     0,     1, 49152, 50176, 
+    50240,     0,     1, 49152, 50176, 50240, 50248,     0, 
+        1, 49152, 50176, 50240, 50248,     0,     1, 49152, 
+    50176, 50240, 50248, 50250,     0,     1, 49152, 50176, 
+    50240, 50248,     0,     1, 49152, 50176, 50240, 50256, 
+    50252,     0,     1, 49152, 50176, 50240, 50256, 50252, 
+        0,     1, 49152, 50176, 50240, 50256, 50257, 50254, 
+        0,     1, 49152, 50176, 50240,     0,     1, 49152, 
+    50176, 50240, 50256,     0,     1, 49152, 50176, 50240, 
+    50256,     0,     1, 49152, 50176, 50240, 50256, 50258, 
+        0,     1, 49152, 50176, 50240, 50256,     0,     1, 
+    49152, 50176, 50240, 50256, 50260,     0,     1, 49152, 
+    50176, 50240, 50256, 50260,     0,     1, 49152, 50176, 
+    50240, 50256, 50264, 50262,     0,     1, 49152, 50176, 
+    50240, 50256,     0,     1, 49152, 50176, 50240, 50272, 
+    50264,     0,     1, 49152, 50176, 50240, 50272, 50264, 
+        0,     1, 49152, 50176, 50240, 50272, 50264, 50266, 
+        0,     1, 49152, 50176, 50240, 50272, 50264,     0, 
+        1, 49152, 50176, 50240, 50272, 50273, 50268,     0, 
+        1, 49152, 50176, 50240, 50272, 50273, 50268,     0, 
+        1, 49152, 50176, 50240, 50272, 50273, 50268, 50270, 
+        0,     1, 49152, 50176, 50240,     0,     1, 49152, 
+    50176, 50304, 50272,     0,     1, 49152, 50176, 50304, 
+    50272,     0,     1, 49152, 50176, 50304, 50272, 50274, 
+        0,     1, 49152, 50176, 50304, 50272,     0,     1, 
+    49152, 50176, 50304, 50272, 50276,     0,     1, 49152, 
+    50176, 50304, 50272, 50276,     0,     1, 49152, 50176, 
+    50304, 50272, 50280, 50278,     0,     1, 49152, 50176, 
+    50304, 50272,     0,     1, 49152, 50176, 50304, 50272, 
+    50280,     0,     1, 49152, 50176, 50304, 50272, 50280, 
+        0,     1, 49152, 50176, 50304, 50272, 50280, 50282, 
+        0,     1, 49152, 50176, 50304, 50272, 50280,     0, 
+        1, 49152, 50176, 50304, 50272, 50288, 50284,     0, 
+        1, 49152, 50176, 50304, 50272, 50288, 50284,     0, 
+        1, 49152, 50176, 50304, 50272, 50288, 50289, 50286, 
+        0,     1, 49152, 50176, 50304, 50272,     0,     1, 
+    49152, 50176, 50304, 50305, 50288,     0,     1, 49152, 
+    50176, 50304, 50305, 50288,     0,     1, 49152, 50176, 
+    50304, 50305, 50288, 50290,     0,     1, 49152, 50176, 
+    50304, 50305, 50288,     0,     1, 49152, 50176, 50304, 
+    50305, 50288, 50292,     0,     1, 49152, 50176, 50304, 
+    50305, 50288, 50292,     0,     1, 49152, 50176, 50304, 
+    50305, 50288, 50296, 50294,     0,     1, 49152, 50176, 
+    50304, 50305, 50288,     0,     1, 49152, 50176, 50304, 
+    50305, 50288, 50296,     0,     1, 49152, 50176, 50304, 
+    50305, 50307, 50296,     0,     1, 49152, 50176, 50304, 
+    50305, 50307, 50296, 50298,     0,     1, 49152, 50176, 
+    50304, 50305, 50307, 50296,     0,     1, 49152, 50176, 
+    50304, 50305, 50307, 50296, 50300,     0,     1, 49152, 
+    50176, 50304, 50305, 50307, 50296, 50300,     0,     1, 
+    49152, 50176, 50304, 50305, 50307, 50296, 50300, 50302, 
+        0,     1, 49152, 50176,     0,     1, 49152, 50176, 
+    50304,     0,     1, 49152, 50176, 50304,     0,     1, 
+    49152, 50176, 50304, 50306,     0,     1, 49152, 50176, 
+    50304,     0,     1, 49152, 50176, 50304, 50308,     0, 
+        1, 49152, 50176, 50304, 50308,     0,     1, 49152, 
+    50176, 50304, 50312, 50310,     0,     1, 49152, 50176, 
+    50304,     0,     1, 49152, 50176, 50304, 50312,     0, 
+        1, 49152, 50176, 50304, 50312,     0,     1, 49152, 
+    50176, 50304, 50312, 50314,     0,     1, 49152, 50176, 
+    50304, 50312,     0,     1, 49152, 50176, 50304, 50320, 
+    50316,     0,     1, 49152, 50176, 50304, 50320, 50316, 
+        0,     1, 49152, 50176, 50304, 50320, 50321, 50318, 
+        0,     1, 49152, 50176, 50304,     0,     1, 49152, 
+    50176, 50304, 50320,     0,     1, 49152, 50176, 50304, 
+    50320,     0,     1, 49152, 50176, 50304, 50320, 50322, 
+        0,     1, 49152, 50176, 50304, 50320,     0,     1, 
+    49152, 50176, 50304, 50320, 50324,     0,     1, 49152, 
+    50176, 50304, 50320, 50324,     0,     1, 49152, 50176, 
+    50304, 50320, 50328, 50326,     0,     1, 49152, 50176, 
+    50304, 50320,     0,     1, 49152, 50176, 50304, 50336, 
+    50328,     0,     1, 49152, 50176, 50304, 50336, 50328, 
+        0,     1, 49152, 50176, 50304, 50336, 50328, 50330, 
+        0,     1, 49152, 50176, 50304, 50336, 50328,     0, 
+        1, 49152, 50176, 50304, 50336, 50337, 50332,     0, 
+        1, 49152, 50176, 50304, 50336, 50337, 50332,     0, 
+        1, 49152, 50176, 50304, 50336, 50337, 50332, 50334, 
+        0,     1, 49152, 50176, 50304,     0,     1, 49152, 
+    50176, 50304, 50336,     0,     1, 49152, 50176, 50304, 
+    50336,     0,     1, 49152, 50176, 50304, 50336, 50338, 
+        0,     1, 49152, 50176, 50304, 50336,     0,     1, 
+    49152, 50176, 50304, 50336, 50340,     0,     1, 49152, 
+    50176, 50304, 50336, 50340,     0,     1, 49152, 50176, 
+    50304, 50336, 50344, 50342,     0,     1, 49152, 50176, 
+    50304, 50336,     0,     1, 49152, 50176, 50304, 50336, 
+    50344,     0,     1, 49152, 50176, 50304, 50336, 50344, 
+        0,     1, 49152, 50176, 50304, 50336, 50344, 50346, 
+        0,     1, 49152, 50176, 50304, 50336, 50344,     0, 
+        1, 49152, 50176, 50304, 50336, 50352, 50348,     0, 
+        1, 49152, 50176, 50304, 50336, 50352, 50348,     0, 
+        1, 49152, 50176, 50304, 50336, 50352, 50353, 50350, 
+        0,     1, 49152, 50176, 50304, 50336,     0,     1, 
+    49152, 50176, 50304, 50368, 50352,     0,     1, 49152, 
+    50176, 50304, 50368, 50352,     0,     1, 49152, 50176, 
+    50304, 50368, 50352, 50354,     0,     1, 49152, 50176, 
+    50304, 50368, 50352,     0,     1, 49152, 50176, 50304, 
+    50368, 50352, 50356,     0,     1, 49152, 50176, 50304, 
+    50368, 50352, 50356,     0,     1, 49152, 50176, 50304, 
+    50368, 50352, 50360, 50358,     0,     1, 49152, 50176, 
+    50304, 50368, 50352,     0,     1, 49152, 50176, 50304, 
+    50368, 50369, 50360,     0,     1, 49152, 50176, 50304, 
+    50368, 50369, 50360,     0,     1, 49152, 50176, 50304, 
+    50368, 50369, 50360, 50362,     0,     1, 49152, 50176, 
+    50304, 50368, 50369, 50360,     0,     1, 49152, 50176, 
+    50304, 50368, 50369, 50360, 50364,     0,     1, 49152, 
+    50176, 50304, 50368, 50369, 50371, 50364,     0,     1, 
+    49152, 50176, 50304, 50368, 50369, 50371, 50364, 50366, 
+        0,     1, 49152, 50176, 50304,     0,     1, 49152, 
+    50176, 50432, 50368,     0,     1, 49152, 50176, 50432, 
+    50368,     0,     1, 49152, 50176, 50432, 50368, 50370, 
+        0,     1, 49152, 50176, 50432, 50368,     0,     1, 
+    49152, 50176, 50432, 50368, 50372,     0,     1, 49152, 
+    50176, 50432, 50368, 50372,     0,     1, 49152, 50176, 
+    50432, 50368, 50376, 50374,     0,     1, 49152, 50176, 
+    50432, 50368,     0,     1, 49152, 50176, 50432, 50368, 
+    50376,     0,     1, 49152, 50176, 50432, 50368, 50376, 
+        0,     1, 49152, 50176, 50432, 50368, 50376, 50378, 
+        0,     1, 49152, 50176, 50432, 50368, 50376,     0, 
+        1, 49152, 50176, 50432, 50368, 50384, 50380,     0, 
+        1, 49152, 50176, 50432, 50368, 50384, 50380,     0, 
+        1, 49152, 50176, 50432, 50368, 50384, 50385, 50382, 
+        0,     1, 49152, 50176, 50432, 50368,     0,     1, 
+    49152, 50176, 50432, 50368, 50384,     0,     1, 49152, 
+    50176, 50432, 50368, 50384,     0,     1, 49152, 50176, 
+    50432, 50368, 50384, 50386,     0,     1, 49152, 50176, 
+    50432, 50368, 50384,     0,     1, 49152, 50176, 50432, 
+    50368, 50384, 50388,     0,     1, 49152, 50176, 50432, 
+    50368, 50384, 50388,     0,     1, 49152, 50176, 50432, 
+    50368, 50384, 50392, 50390,     0,     1, 49152, 50176, 
+    50432, 50368, 50384,     0,     1, 49152, 50176, 50432, 
+    50368, 50400, 50392,     0,     1, 49152, 50176, 50432, 
+    50368, 50400, 50392,     0,     1, 49152, 50176, 50432, 
+    50368, 50400, 50392, 50394,     0,     1, 49152, 50176, 
+    50432, 50368, 50400, 50392,     0,     1, 49152, 50176, 
+    50432, 50368, 50400, 50401, 50396,     0,     1, 49152, 
+    50176, 50432, 50368, 50400, 50401, 50396,     0,     1, 
+    49152, 50176, 50432, 50368, 50400, 50401, 50396, 50398, 
+        0,     1, 49152, 50176, 50432, 50368,     0,     1, 
+    49152, 50176, 50432, 50433, 50400,     0,     1, 49152, 
+    50176, 50432, 50433, 50400,     0,     1, 49152, 50176, 
+    50432, 50433, 50400, 50402,     0,     1, 49152, 50176, 
+    50432, 50433, 50400,     0,     1, 49152, 50176, 50432, 
+    50433, 50400, 50404,     0,     1, 49152, 50176, 50432, 
+    50433, 50400, 50404,     0,     1, 49152, 50176, 50432, 
+    50433, 50400, 50408, 50406,     0,     1, 49152, 50176, 
+    50432, 50433, 50400,     0,     1, 49152, 50176, 50432, 
+    50433, 50400, 50408,     0,     1, 49152, 50176, 50432, 
+    50433, 50400, 50408,     0,     1, 49152, 50176, 50432, 
+    50433, 50400, 50408, 50410,     0,     1, 49152, 50176, 
+    50432, 50433, 50400, 50408,     0,     1, 49152, 50176, 
+    50432, 50433, 50400, 50416, 50412,     0,     1, 49152, 
+    50176, 50432, 50433, 50400, 50416, 50412,     0,     1, 
+    49152, 50176, 50432, 50433, 50400, 50416, 50417, 50414, 
+        0,     1, 49152, 50176, 50432, 50433, 50400,     0, 
+        1, 49152, 50176, 50432, 50433, 50400, 50416,     0, 
+        1, 49152, 50176, 50432, 50433, 50435, 50416,     0, 
+        1, 49152, 50176, 50432, 50433, 50435, 50416, 50418, 
+        0,     1, 49152, 50176, 50432, 50433, 50435, 50416, 
+        0,     1, 49152, 50176, 50432, 50433, 50435, 50416, 
+    50420,     0,     1, 49152, 50176, 50432, 50433, 50435, 
+    50416, 50420,     0,     1, 49152, 50176, 50432, 50433, 
+    50435, 50416, 50424, 50422,     0,     1, 49152, 50176, 
+    50432, 50433, 50435, 50416,     0,     1, 49152, 50176, 
+    50432, 50433, 50435, 50416, 50424,     0,     1, 49152, 
+    50176, 50432, 50433, 50435, 50416, 50424,     0,     1, 
+    49152, 50176, 50432, 50433, 50435, 50416, 50424, 50426, 
+        0,     1, 49152, 50176, 50432, 50433, 50435, 50439, 
+    50424,     0,     1, 49152, 50176, 50432, 50433, 50435, 
+    50439, 50424, 50428,     0,     1, 49152, 50176, 50432, 
+    50433, 50435, 50439, 50424, 50428,     0,     1, 49152, 
+    50176, 50432, 50433, 50435, 50439, 50424, 50428, 50430, 
+        0,     1, 49152, 50176,     0,     1, 49152, 50176, 
+    50432,     0,     1, 49152, 50176, 50432,     0,     1, 
+    49152, 50176, 50432, 50434,     0,     1, 49152, 50176, 
+    50432,     0,     1, 49152, 50176, 50432, 50436,     0, 
+        1, 49152, 50176, 50432, 50436,     0,     1, 49152, 
+    50176, 50432, 50440, 50438,     0,     1, 49152, 50176, 
+    50432,     0,     1, 49152, 50176, 50432, 50440,     0, 
+        1, 49152, 50176, 50432, 50440,     0,     1, 49152, 
+    50176, 50432, 50440, 50442,     0,     1, 49152, 50176, 
+    50432, 50440,     0,     1, 49152, 50176, 50432, 50448, 
+    50444,     0,     1, 49152, 50176, 50432, 50448, 50444, 
+        0,     1, 49152, 50176, 50432, 50448, 50449, 50446, 
+        0,     1, 49152, 50176, 50432,     0,     1, 49152, 
+    50176, 50432, 50448,     0,     1, 49152, 50176, 50432, 
+    50448,     0,     1, 49152, 50176, 50432, 50448, 50450, 
+        0,     1, 49152, 50176, 50432, 50448,     0,     1, 
+    49152, 50176, 50432, 50448, 50452,     0,     1, 49152, 
+    50176, 50432, 50448, 50452,     0,     1, 49152, 50176, 
+    50432, 50448, 50456, 50454,     0,     1, 49152, 50176, 
+    50432, 50448,     0,     1, 49152, 50176, 50432, 50464, 
+    50456,     0,     1, 49152, 50176, 50432, 50464, 50456, 
+        0,     1, 49152, 50176, 50432, 50464, 50456, 50458, 
+        0,     1, 49152, 50176, 50432, 50464, 50456,     0, 
+        1, 49152, 50176, 50432, 50464, 50465, 50460,     0, 
+        1, 49152, 50176, 50432, 50464, 50465, 50460,     0, 
+        1, 49152, 50176, 50432, 50464, 50465, 50460, 50462, 
+        0,     1, 49152, 50176, 50432,     0,     1, 49152, 
+    50176, 50432, 50464,     0,     1, 49152, 50176, 50432, 
+    50464,     0,     1, 49152, 50176, 50432, 50464, 50466, 
+        0,     1, 49152, 50176, 50432, 50464,     0,     1, 
+    49152, 50176, 50432, 50464, 50468,     0,     1, 49152, 
+    50176, 50432, 50464, 50468,     0,     1, 49152, 50176, 
+    50432, 50464, 50472, 50470,     0,     1, 49152, 50176, 
+    50432, 50464,     0,     1, 49152, 50176, 50432, 50464, 
+    50472,     0,     1, 49152, 50176, 50432, 50464, 50472, 
+        0,     1, 49152, 50176, 50432, 50464, 50472, 50474, 
+        0,     1, 49152, 50176, 50432, 50464, 50472,     0, 
+        1, 49152, 50176, 50432, 50464, 50480, 50476,     0, 
+        1, 49152, 50176, 50432, 50464, 50480, 50476,     0, 
+        1, 49152, 50176, 50432, 50464, 50480, 50481, 50478, 
+        0,     1, 49152, 50176, 50432, 50464,     0,     1, 
+    49152, 50176, 50432, 50496, 50480,     0,     1, 49152, 
+    50176, 50432, 50496, 50480,     0,     1, 49152, 50176, 
+    50432, 50496, 50480, 50482,     0,     1, 49152, 50176, 
+    50432, 50496, 50480,     0,     1, 49152, 50176, 50432, 
+    50496, 50480, 50484,     0,     1, 49152, 50176, 50432, 
+    50496, 50480, 50484,     0,     1, 49152, 50176, 50432, 
+    50496, 50480, 50488, 50486,     0,     1, 49152, 50176, 
+    50432, 50496, 50480,     0,     1, 49152, 50176, 50432, 
+    50496, 50497, 50488,     0,     1, 49152, 50176, 50432, 
+    50496, 50497, 50488,     0,     1, 49152, 50176, 50432, 
+    50496, 50497, 50488, 50490,     0,     1, 49152, 50176, 
+    50432, 50496, 50497, 50488,     0,     1, 49152, 50176, 
+    50432, 50496, 50497, 50488, 50492,     0,     1, 49152, 
+    50176, 50432, 50496, 50497, 50499, 50492,     0,     1, 
+    49152, 50176, 50432, 50496, 50497, 50499, 50492, 50494, 
+        0,     1, 49152, 50176, 50432,     0,     1, 49152, 
+    50176, 50432, 50496,     0,     1, 49152, 50176, 50432, 
+    50496,     0,     1, 49152, 50176, 50432, 50496, 50498, 
+        0,     1, 49152, 50176, 50432, 50496,     0,     1, 
+    49152, 50176, 50432, 50496, 50500,     0,     1, 49152, 
+    50176, 50432, 50496, 50500,     0,     1, 49152, 50176, 
+    50432, 50496, 50504, 50502,     0,     1, 49152, 50176, 
+    50432, 50496,     0,     1, 49152, 50176, 50432, 50496, 
+    50504,     0,     1, 49152, 50176, 50432, 50496, 50504, 
+        0,     1, 49152, 50176, 50432, 50496, 50504, 50506, 
+        0,     1, 49152, 50176, 50432, 50496, 50504,     0, 
+        1, 49152, 50176, 50432, 50496, 50512, 50508,     0, 
+        1, 49152, 50176, 50432, 50496, 50512, 50508,     0, 
+        1, 49152, 50176, 50432, 50496, 50512, 50513, 50510, 
+        0,     1, 49152, 50176, 50432, 50496,     0,     1, 
+    49152, 50176, 50432, 50496, 50512,     0,     1, 49152, 
+    50176, 50432, 50496, 50512,     0,     1, 49152, 50176, 
+    50432, 50496, 50512, 50514,     0,     1, 49152, 50176, 
+    50432, 50496, 50512,     0,     1, 49152, 50176, 50432, 
+    50496, 50512, 50516,     0,     1, 49152, 50176, 50432, 
+    50496, 50512, 50516,     0,     1, 49152, 50176, 50432, 
+    50496, 50512, 50520, 50518,     0,     1, 49152, 50176, 
+    50432, 50496, 50512,     0,     1, 49152, 50176, 50432, 
+    50496, 50528, 50520,     0,     1, 49152, 50176, 50432, 
+    50496, 50528, 50520,     0,     1, 49152, 50176, 50432, 
+    50496, 50528, 50520, 50522,     0,     1, 49152, 50176, 
+    50432, 50496, 50528, 50520,     0,     1, 49152, 50176, 
+    50432, 50496, 50528, 50529, 50524,     0,     1, 49152, 
+    50176, 50432, 50496, 50528, 50529, 50524,     0,     1, 
+    49152, 50176, 50432, 50496, 50528, 50529, 50524, 50526, 
+        0,     1, 49152, 50176, 50432, 50496,     0,     1, 
+    49152, 50176, 50432, 50560, 50528,     0,     1, 49152, 
+    50176, 50432, 50560, 50528,     0,     1, 49152, 50176, 
+    50432, 50560, 50528, 50530,     0,     1, 49152, 50176, 
+    50432, 50560, 50528,     0,     1, 49152, 50176, 50432, 
+    50560, 50528, 50532,     0,     1, 49152, 50176, 50432, 
+    50560, 50528, 50532,     0,     1, 49152, 50176, 50432, 
+    50560, 50528, 50536, 50534,     0,     1, 49152, 50176, 
+    50432, 50560, 50528,     0,     1, 49152, 50176, 50432, 
+    50560, 50528, 50536,     0,     1, 49152, 50176, 50432, 
+    50560, 50528, 50536,     0,     1, 49152, 50176, 50432, 
+    50560, 50528, 50536, 50538,     0,     1, 49152, 50176, 
+    50432, 50560, 50528, 50536,     0,     1, 49152, 50176, 
+    50432, 50560, 50528, 50544, 50540,     0,     1, 49152, 
+    50176, 50432, 50560, 50528, 50544, 50540,     0,     1, 
+    49152, 50176, 50432, 50560, 50528, 50544, 50545, 50542, 
+        0,     1, 49152, 50176, 50432, 50560, 50528,     0, 
+        1, 49152, 50176, 50432, 50560, 50561, 50544,     0, 
+        1, 49152, 50176, 50432, 50560, 50561, 50544,     0, 
+        1, 49152, 50176, 50432, 50560, 50561, 50544, 50546, 
+        0,     1, 49152, 50176, 50432, 50560, 50561, 50544, 
+        0,     1, 49152, 50176, 50432, 50560, 50561, 50544, 
+    50548,     0,     1, 49152, 50176, 50432, 50560, 50561, 
+    50544, 50548,     0,     1, 49152, 50176, 50432, 50560, 
+    50561, 50544, 50552, 50550,     0,     1, 49152, 50176, 
+    50432, 50560, 50561, 50544,     0,     1, 49152, 50176, 
+    50432, 50560, 50561, 50544, 50552,     0,     1, 49152, 
+    50176, 50432, 50560, 50561, 50563, 50552,     0,     1, 
+    49152, 50176, 50432, 50560, 50561, 50563, 50552, 50554, 
+        0,     1, 49152, 50176, 50432, 50560, 50561, 50563, 
+    50552,     0,     1, 49152, 50176, 50432, 50560, 50561, 
+    50563, 50552, 50556,     0,     1, 49152, 50176, 50432, 
+    50560, 50561, 50563, 50552, 50556,     0,     1, 49152, 
+    50176, 50432, 50560, 50561, 50563, 50552, 50556, 50558, 
+        0,     1, 49152, 50176, 50432,     0,     1, 49152, 
+    50176, 50688, 50560,     0,     1, 49152, 50176, 50688, 
+    50560,     0,     1, 49152, 50176, 50688, 50560, 50562, 
+        0,     1, 49152, 50176, 50688, 50560,     0,     1, 
+    49152, 50176, 50688, 50560, 50564,     0,     1, 49152, 
+    50176, 50688, 50560, 50564,     0,     1, 49152, 50176, 
+    50688, 50560, 50568, 50566,     0,     1, 49152, 50176, 
+    50688, 50560,     0,     1, 49152, 50176, 50688, 50560, 
+    50568,     0,     1, 49152, 50176, 50688, 50560, 50568, 
+        0,     1, 49152, 50176, 50688, 50560, 50568, 50570, 
+        0,     1, 49152, 50176, 50688, 50560, 50568,     0, 
+        1, 49152, 50176, 50688, 50560, 50576, 50572,     0, 
+        1, 49152, 50176, 50688, 50560, 50576, 50572,     0, 
+        1, 49152, 50176, 50688, 50560, 50576, 50577, 50574, 
+        0,     1, 49152, 50176, 50688, 50560,     0,     1, 
+    49152, 50176, 50688, 50560, 50576,     0,     1, 49152, 
+    50176, 50688, 50560, 50576,     0,     1, 49152, 50176, 
+    50688, 50560, 50576, 50578,     0,     1, 49152, 50176, 
+    50688, 50560, 50576,     0,     1, 49152, 50176, 50688, 
+    50560, 50576, 50580,     0,     1, 49152, 50176, 50688, 
+    50560, 50576, 50580,     0,     1, 49152, 50176, 50688, 
+    50560, 50576, 50584, 50582,     0,     1, 49152, 50176, 
+    50688, 50560, 50576,     0,     1, 49152, 50176, 50688, 
+    50560, 50592, 50584,     0,     1, 49152, 50176, 50688, 
+    50560, 50592, 50584,     0,     1, 49152, 50176, 50688, 
+    50560, 50592, 50584, 50586,     0,     1, 49152, 50176, 
+    50688, 50560, 50592, 50584,     0,     1, 49152, 50176, 
+    50688, 50560, 50592, 50593, 50588,     0,     1, 49152, 
+    50176, 50688, 50560, 50592, 50593, 50588,     0,     1, 
+    49152, 50176, 50688, 50560, 50592, 50593, 50588, 50590, 
+        0,     1, 49152, 50176, 50688, 50560,     0,     1, 
+    49152, 50176, 50688, 50560, 50592,     0,     1, 49152, 
+    50176, 50688, 50560, 50592,     0,     1, 49152, 50176, 
+    50688, 50560, 50592, 50594,     0,     1, 49152, 50176, 
+    50688, 50560, 50592,     0,     1, 49152, 50176, 50688, 
+    50560, 50592, 50596,     0,     1, 49152, 50176, 50688, 
+    50560, 50592, 50596,     0,     1, 49152, 50176, 50688, 
+    50560, 50592, 50600, 50598,     0,     1, 49152, 50176, 
+    50688, 50560, 50592,     0,     1, 49152, 50176, 50688, 
+    50560, 50592, 50600,     0,     1, 49152, 50176, 50688, 
+    50560, 50592, 50600,     0,     1, 49152, 50176, 50688, 
+    50560, 50592, 50600, 50602,     0,     1, 49152, 50176, 
+    50688, 50560, 50592, 50600,     0,     1, 49152, 50176, 
+    50688, 50560, 50592, 50608, 50604,     0,     1, 49152, 
+    50176, 50688, 50560, 50592, 50608, 50604,     0,     1, 
+    49152, 50176, 50688, 50560, 50592, 50608, 50609, 50606, 
+        0,     1, 49152, 50176, 50688, 50560, 50592,     0, 
+        1, 49152, 50176, 50688, 50560, 50624, 50608,     0, 
+        1, 49152, 50176, 50688, 50560, 50624, 50608,     0, 
+        1, 49152, 50176, 50688, 50560, 50624, 50608, 50610, 
+        0,     1, 49152, 50176, 50688, 50560, 50624, 50608, 
+        0,     1, 49152, 50176, 50688, 50560, 50624, 50608, 
+    50612,     0,     1, 49152, 50176, 50688, 50560, 50624, 
+    50608, 50612,     0,     1, 49152, 50176, 50688, 50560, 
+    50624, 50608, 50616, 50614,     0,     1, 49152, 50176, 
+    50688, 50560, 50624, 50608,     0,     1, 49152, 50176, 
+    50688, 50560, 50624, 50625, 50616,     0,     1, 49152, 
+    50176, 50688, 50560, 50624, 50625, 50616,     0,     1, 
+    49152, 50176, 50688, 50560, 50624, 50625, 50616, 50618, 
+        0,     1, 49152, 50176, 50688, 50560, 50624, 50625, 
+    50616,     0,     1, 49152, 50176, 50688, 50560, 50624, 
+    50625, 50616, 50620,     0,     1, 49152, 50176, 50688, 
+    50560, 50624, 50625, 50627, 50620,     0,     1, 49152, 
+    50176, 50688, 50560, 50624, 50625, 50627, 50620, 50622, 
+        0,     1, 49152, 50176, 50688, 50560,     0,     1, 
+    49152, 50176, 50688, 50689, 50624,     0,     1, 49152, 
+    50176, 50688, 50689, 50624,     0,     1, 49152, 50176, 
+    50688, 50689, 50624, 50626,     0,     1, 49152, 50176, 
+    50688, 50689, 50624,     0,     1, 49152, 50176, 50688, 
+    50689, 50624, 50628,     0,     1, 49152, 50176, 50688, 
+    50689, 50624, 50628,     0,     1, 49152, 50176, 50688, 
+    50689, 50624, 50632, 50630,     0,     1, 49152, 50176, 
+    50688, 50689, 50624,     0,     1, 49152, 50176, 50688, 
+    50689, 50624, 50632,     0,     1, 49152, 50176, 50688, 
+    50689, 50624, 50632,     0,     1, 49152, 50176, 50688, 
+    50689, 50624, 50632, 50634,     0,     1, 49152, 50176, 
+    50688, 50689, 50624, 50632,     0,     1, 49152, 50176, 
+    50688, 50689, 50624, 50640, 50636,     0,     1, 49152, 
+    50176, 50688, 50689, 50624, 50640, 50636,     0,     1, 
+    49152, 50176, 50688, 50689, 50624, 50640, 50641, 50638, 
+        0,     1, 49152, 50176, 50688, 50689, 50624,     0, 
+        1, 49152, 50176, 50688, 50689, 50624, 50640,     0, 
+        1, 49152, 50176, 50688, 50689, 50624, 50640,     0, 
+        1, 49152, 50176, 50688, 50689, 50624, 50640, 50642, 
+        0,     1, 49152, 50176, 50688, 50689, 50624, 50640, 
+        0,     1, 49152, 50176, 50688, 50689, 50624, 50640, 
+    50644,     0,     1, 49152, 50176, 50688, 50689, 50624, 
+    50640, 50644,     0,     1, 49152, 50176, 50688, 50689, 
+    50624, 50640, 50648, 50646,     0,     1, 49152, 50176, 
+    50688, 50689, 50624, 50640,     0,     1, 49152, 50176, 
+    50688, 50689, 50624, 50656, 50648,     0,     1, 49152, 
+    50176, 50688, 50689, 50624, 50656, 50648,     0,     1, 
+    49152, 50176, 50688, 50689, 50624, 50656, 50648, 50650, 
+        0,     1, 49152, 50176, 50688, 50689, 50624, 50656, 
+    50648,     0,     1, 49152, 50176, 50688, 50689, 50624, 
+    50656, 50657, 50652,     0,     1, 49152, 50176, 50688, 
+    50689, 50624, 50656, 50657, 50652,     0,     1, 49152, 
+    50176, 50688, 50689, 50624, 50656, 50657, 50652, 50654, 
+        0,     1, 49152, 50176, 50688, 50689, 50624,     0, 
+        1, 49152, 50176, 50688, 50689, 50624, 50656,     0, 
+        1, 49152, 50176, 50688, 50689, 50691, 50656,     0, 
+        1, 49152, 50176, 50688, 50689, 50691, 50656, 50658, 
+        0,     1, 49152, 50176, 50688, 50689, 50691, 50656, 
+        0,     1, 49152, 50176, 50688, 50689, 50691, 50656, 
+    50660,     0,     1, 49152, 50176, 50688, 50689, 50691, 
+    50656, 50660,     0,     1, 49152, 50176, 50688, 50689, 
+    50691, 50656, 50664, 50662,     0,     1, 49152, 50176, 
+    50688, 50689, 50691, 50656,     0,     1, 49152, 50176, 
+    50688, 50689, 50691, 50656, 50664,     0,     1, 49152, 
+    50176, 50688, 50689, 50691, 50656, 50664,     0,     1, 
+    49152, 50176, 50688, 50689, 50691, 50656, 50664, 50666, 
+        0,     1, 49152, 50176, 50688, 50689, 50691, 50656, 
+    50664,     0,     1, 49152, 50176, 50688, 50689, 50691, 
+    50656, 50672, 50668,     0,     1, 49152, 50176, 50688, 
+    50689, 50691, 50656, 50672, 50668,     0,     1, 49152, 
+    50176, 50688, 50689, 50691, 50656, 50672, 50673, 50670, 
+        0,     1, 49152, 50176, 50688, 50689, 50691, 50656, 
+        0,     1, 49152, 50176, 50688, 50689, 50691, 50656, 
+    50672,     0,     1, 49152, 50176, 50688, 50689, 50691, 
+    50656, 50672,     0,     1, 49152, 50176, 50688, 50689, 
+    50691, 50656, 50672, 50674,     0,     1, 49152, 50176, 
+    50688, 50689, 50691, 50695, 50672,     0,     1, 49152, 
+    50176, 50688, 50689, 50691, 50695, 50672, 50676,     0, 
+        1, 49152, 50176, 50688, 50689, 50691, 50695, 50672, 
+    50676,     0,     1, 49152, 50176, 50688, 50689, 50691, 
+    50695, 50672, 50680, 50678,     0,     1, 49152, 50176, 
+    50688, 50689, 50691, 50695, 50672,     0,     1, 49152, 
+    50176, 50688, 50689, 50691, 50695, 50672, 50680,     0, 
+        1, 49152, 50176, 50688, 50689, 50691, 50695, 50672, 
+    50680,     0,     1, 49152, 50176, 50688, 50689, 50691, 
+    50695, 50672, 50680, 50682,     0,     1, 49152, 50176, 
+    50688, 50689, 50691, 50695, 50672, 50680,     0,     1, 
+    49152, 50176, 50688, 50689, 50691, 50695, 50672, 50680, 
+    50684,     0,     1, 49152, 50176, 50688, 50689, 50691, 
+    50695, 50672, 50680, 50684,     0,     1, 49152, 50176, 
+    50688, 50689, 50691, 50695, 50672, 50680, 50684, 50686, 
+        0,     1, 49152, 50176,     0,     1, 49152, 51200, 
+    50688,     0,     1, 49152, 51200, 50688,     0,     1, 
+    49152, 51200, 50688, 50690,     0,     1, 49152, 51200, 
+    50688,     0,     1, 49152, 51200, 50688, 50692,     0, 
+        1, 49152, 51200, 50688, 50692,     0,     1, 49152, 
+    51200, 50688, 50696, 50694,     0,     1, 49152, 51200, 
+    50688,     0,     1, 49152, 51200, 50688, 50696,     0, 
+        1, 49152, 51200, 50688, 50696,     0,     1, 49152, 
+    51200, 50688, 50696, 50698,     0,     1, 49152, 51200, 
+    50688, 50696,     0,     1, 49152, 51200, 50688, 50704, 
+    50700,     0,     1, 49152, 51200, 50688, 50704, 50700, 
+        0,     1, 49152, 51200, 50688, 50704, 50705, 50702, 
+        0,     1, 49152, 51200, 50688,     0,     1, 49152, 
+    51200, 50688, 50704,     0,     1, 49152, 51200, 50688, 
+    50704,     0,     1, 49152, 51200, 50688, 50704, 50706, 
+        0,     1, 49152, 51200, 50688, 50704,     0,     1, 
+    49152, 51200, 50688, 50704, 50708,     0,     1, 49152, 
+    51200, 50688, 50704, 50708,     0,     1, 49152, 51200, 
+    50688, 50704, 50712, 50710,     0,     1, 49152, 51200, 
+    50688, 50704,     0,     1, 49152, 51200, 50688, 50720, 
+    50712,     0,     1, 49152, 51200, 50688, 50720, 50712, 
+        0,     1, 49152, 51200, 50688, 50720, 50712, 50714, 
+        0,     1, 49152, 51200, 50688, 50720, 50712,     0, 
+        1, 49152, 51200, 50688, 50720, 50721, 50716,     0, 
+        1, 49152, 51200, 50688, 50720, 50721, 50716,     0, 
+        1, 49152, 51200, 50688, 50720, 50721, 50716, 50718, 
+        0,     1, 49152, 51200, 50688,     0,     1, 49152, 
+    51200, 50688, 50720,     0,     1, 49152, 51200, 50688, 
+    50720,     0,     1, 49152, 51200, 50688, 50720, 50722, 
+        0,     1, 49152, 51200, 50688, 50720,     0,     1, 
+    49152, 51200, 50688, 50720, 50724,     0,     1, 49152, 
+    51200, 50688, 50720, 50724,     0,     1, 49152, 51200, 
+    50688, 50720, 50728, 50726,     0,     1, 49152, 51200, 
+    50688, 50720,     0,     1, 49152, 51200, 50688, 50720, 
+    50728,     0,     1, 49152, 51200, 50688, 50720, 50728, 
+        0,     1, 49152, 51200, 50688, 50720, 50728, 50730, 
+        0,     1, 49152, 51200, 50688, 50720, 50728,     0, 
+        1, 49152, 51200, 50688, 50720, 50736, 50732,     0, 
+        1, 49152, 51200, 50688, 50720, 50736, 50732,     0, 
+        1, 49152, 51200, 50688, 50720, 50736, 50737, 50734, 
+        0,     1, 49152, 51200, 50688, 50720,     0,     1, 
+    49152, 51200, 50688, 50752, 50736,     0,     1, 49152, 
+    51200, 50688, 50752, 50736,     0,     1, 49152, 51200, 
+    50688, 50752, 50736, 50738,     0,     1, 49152, 51200, 
+    50688, 50752, 50736,     0,     1, 49152, 51200, 50688, 
+    50752, 50736, 50740,     0,     1, 49152, 51200, 50688, 
+    50752, 50736, 50740,     0,     1, 49152, 51200, 50688, 
+    50752, 50736, 50744, 50742,     0,     1, 49152, 51200, 
+    50688, 50752, 50736,     0,     1, 49152, 51200, 50688, 
+    50752, 50753, 50744,     0,     1, 49152, 51200, 50688, 
+    50752, 50753, 50744,     0,     1, 49152, 51200, 50688, 
+    50752, 50753, 50744, 50746,     0,     1, 49152, 51200, 
+    50688, 50752, 50753, 50744,     0,     1, 49152, 51200, 
+    50688, 50752, 50753, 50744, 50748,     0,     1, 49152, 
+    51200, 50688, 50752, 50753, 50755, 50748,     0,     1, 
+    49152, 51200, 50688, 50752, 50753, 50755, 50748, 50750, 
+        0,     1, 49152, 51200, 50688,     0,     1, 49152, 
+    51200, 50688, 50752,     0,     1, 49152, 51200, 50688, 
+    50752,     0,     1, 49152, 51200, 50688, 50752, 50754, 
+        0,     1, 49152, 51200, 50688, 50752,     0,     1, 
+    49152, 51200, 50688, 50752, 50756,     0,     1, 49152, 
+    51200, 50688, 50752, 50756,     0,     1, 49152, 51200, 
+    50688, 50752, 50760, 50758,     0,     1, 49152, 51200, 
+    50688, 50752,     0,     1, 49152, 51200, 50688, 50752, 
+    50760,     0,     1, 49152, 51200, 50688, 50752, 50760, 
+        0,     1, 49152, 51200, 50688, 50752, 50760, 50762, 
+        0,     1, 49152, 51200, 50688, 50752, 50760,     0, 
+        1, 49152, 51200, 50688, 50752, 50768, 50764,     0, 
+        1, 49152, 51200, 50688, 50752, 50768, 50764,     0, 
+        1, 49152, 51200, 50688, 50752, 50768, 50769, 50766, 
+        0,     1, 49152, 51200, 50688, 50752,     0,     1, 
+    49152, 51200, 50688, 50752, 50768,     0,     1, 49152, 
+    51200, 50688, 50752, 50768,     0,     1, 49152, 51200, 
+    50688, 50752, 50768, 50770,     0,     1, 49152, 51200, 
+    50688, 50752, 50768,     0,     1, 49152, 51200, 50688, 
+    50752, 50768, 50772,     0,     1, 49152, 51200, 50688, 
+    50752, 50768, 50772,     0,     1, 49152, 51200, 50688, 
+    50752, 50768, 50776, 50774,     0,     1, 49152, 51200, 
+    50688, 50752, 50768,     0,     1, 49152, 51200, 50688, 
+    50752, 50784, 50776,     0,     1, 49152, 51200, 50688, 
+    50752, 50784, 50776,     0,     1, 49152, 51200, 50688, 
+    50752, 50784, 50776, 50778,     0,     1, 49152, 51200, 
+    50688, 50752, 50784, 50776,     0,     1, 49152, 51200, 
+    50688, 50752, 50784, 50785, 50780,     0,     1, 49152, 
+    51200, 50688, 50752, 50784, 50785, 50780,     0,     1, 
+    49152, 51200, 50688, 50752, 50784, 50785, 50780, 50782, 
+        0,     1, 49152, 51200, 50688, 50752,     0,     1, 
+    49152, 51200, 50688, 50816, 50784,     0,     1, 49152, 
+    51200, 50688, 50816, 50784,     0,     1, 49152, 51200, 
+    50688, 50816, 50784, 50786,     0,     1, 49152, 51200, 
+    50688, 50816, 50784,     0,     1, 49152, 51200, 50688, 
+    50816, 50784, 50788,     0,     1, 49152, 51200, 50688, 
+    50816, 50784, 50788,     0,     1, 49152, 51200, 50688, 
+    50816, 50784, 50792, 50790,     0,     1, 49152, 51200, 
+    50688, 50816, 50784,     0,     1, 49152, 51200, 50688, 
+    50816, 50784, 50792,     0,     1, 49152, 51200, 50688, 
+    50816, 50784, 50792,     0,     1, 49152, 51200, 50688, 
+    50816, 50784, 50792, 50794,     0,     1, 49152, 51200, 
+    50688, 50816, 50784, 50792,     0,     1, 49152, 51200, 
+    50688, 50816, 50784, 50800, 50796,     0,     1, 49152, 
+    51200, 50688, 50816, 50784, 50800, 50796,     0,     1, 
+    49152, 51200, 50688, 50816, 50784, 50800, 50801, 50798, 
+        0,     1, 49152, 51200, 50688, 50816, 50784,     0, 
+        1, 49152, 51200, 50688, 50816, 50817, 50800,     0, 
+        1, 49152, 51200, 50688, 50816, 50817, 50800,     0, 
+        1, 49152, 51200, 50688, 50816, 50817, 50800, 50802, 
+        0,     1, 49152, 51200, 50688, 50816, 50817, 50800, 
+        0,     1, 49152, 51200, 50688, 50816, 50817, 50800, 
+    50804,     0,     1, 49152, 51200, 50688, 50816, 50817, 
+    50800, 50804,     0,     1, 49152, 51200, 50688, 50816, 
+    50817, 50800, 50808, 50806,     0,     1, 49152, 51200, 
+    50688, 50816, 50817, 50800,     0,     1, 49152, 51200, 
+    50688, 50816, 50817, 50800, 50808,     0,     1, 49152, 
+    51200, 50688, 50816, 50817, 50819, 50808,     0,     1, 
+    49152, 51200, 50688, 50816, 50817, 50819, 50808, 50810, 
+        0,     1, 49152, 51200, 50688, 50816, 50817, 50819, 
+    50808,     0,     1, 49152, 51200, 50688, 50816, 50817, 
+    50819, 50808, 50812,     0,     1, 49152, 51200, 50688, 
+    50816, 50817, 50819, 50808, 50812,     0,     1, 49152, 
+    51200, 50688, 50816, 50817, 50819, 50808, 50812, 50814, 
+        0,     1, 49152, 51200, 50688,     0,     1, 49152, 
+    51200, 50688, 50816,     0,     1, 49152, 51200, 50688, 
+    50816,     0,     1, 49152, 51200, 50688, 50816, 50818, 
+        0,     1, 49152, 51200, 50688, 50816,     0,     1, 
+    49152, 51200, 50688, 50816, 50820,     0,     1, 49152, 
+    51200, 50688, 50816, 50820,     0,     1, 49152, 51200, 
+    50688, 50816, 50824, 50822,     0,     1, 49152, 51200, 
+    50688, 50816,     0,     1, 49152, 51200, 50688, 50816, 
+    50824,     0,     1, 49152, 51200, 50688, 50816, 50824, 
+        0,     1, 49152, 51200, 50688, 50816, 50824, 50826, 
+        0,     1, 49152, 51200, 50688, 50816, 50824,     0, 
+        1, 49152, 51200, 50688, 50816, 50832, 50828,     0, 
+        1, 49152, 51200, 50688, 50816, 50832, 50828,     0, 
+        1, 49152, 51200, 50688, 50816, 50832, 50833, 50830, 
+        0,     1, 49152, 51200, 50688, 50816,     0,     1, 
+    49152, 51200, 50688, 50816, 50832,     0,     1, 49152, 
+    51200, 50688, 50816, 50832,     0,     1, 49152, 51200, 
+    50688, 50816, 50832, 50834,     0,     1, 49152, 51200, 
+    50688, 50816, 50832,     0,     1, 49152, 51200, 50688, 
+    50816, 50832, 50836,     0,     1, 49152, 51200, 50688, 
+    50816, 50832, 50836,     0,     1, 49152, 51200, 50688, 
+    50816, 50832, 50840, 50838,     0,     1, 49152, 51200, 
+    50688, 50816, 50832,     0,     1, 49152, 51200, 50688, 
+    50816, 50848, 50840,     0,     1, 49152, 51200, 50688, 
+    50816, 50848, 50840,     0,     1, 49152, 51200, 50688, 
+    50816, 50848, 50840, 50842,     0,     1, 49152, 51200, 
+    50688, 50816, 50848, 50840,     0,     1, 49152, 51200, 
+    50688, 50816, 50848, 50849, 50844,     0,     1, 49152, 
+    51200, 50688, 50816, 50848, 50849, 50844,     0,     1, 
+    49152, 51200, 50688, 50816, 50848, 50849, 50844, 50846, 
+        0,     1, 49152, 51200, 50688, 50816,     0,     1, 
+    49152, 51200, 50688, 50816, 50848,     0,     1, 49152, 
+    51200, 50688, 50816, 50848,     0,     1, 49152, 51200, 
+    50688, 50816, 50848, 50850,     0,     1, 49152, 51200, 
+    50688, 50816, 50848,     0,     1, 49152, 51200, 50688, 
+    50816, 50848, 50852,     0,     1, 49152, 51200, 50688, 
+    50816, 50848, 50852,     0,     1, 49152, 51200, 50688, 
+    50816, 50848, 50856, 50854,     0,     1, 49152, 51200, 
+    50688, 50816, 50848,     0,     1, 49152, 51200, 50688, 
+    50816, 50848, 50856,     0,     1, 49152, 51200, 50688, 
+    50816, 50848, 50856,     0,     1, 49152, 51200, 50688, 
+    50816, 50848, 50856, 50858,     0,     1, 49152, 51200, 
+    50688, 50816, 50848, 50856,     0,     1, 49152, 51200, 
+    50688, 50816, 50848, 50864, 50860,     0,     1, 49152, 
+    51200, 50688, 50816, 50848, 50864, 50860,     0,     1, 
+    49152, 51200, 50688, 50816, 50848, 50864, 50865, 50862, 
+        0,     1, 49152, 51200, 50688, 50816, 50848,     0, 
+        1, 49152, 51200, 50688, 50816, 50880, 50864,     0, 
+        1, 49152, 51200, 50688, 50816, 50880, 50864,     0, 
+        1, 49152, 51200, 50688, 50816, 50880, 50864, 50866, 
+        0,     1, 49152, 51200, 50688, 50816, 50880, 50864, 
+        0,     1, 49152, 51200, 50688, 50816, 50880, 50864, 
+    50868,     0,     1, 49152, 51200, 50688, 50816, 50880, 
+    50864, 50868,     0,     1, 49152, 51200, 50688, 50816, 
+    50880, 50864, 50872, 50870,     0,     1, 49152, 51200, 
+    50688, 50816, 50880, 50864,     0,     1, 49152, 51200, 
+    50688, 50816, 50880, 50881, 50872,     0,     1, 49152, 
+    51200, 50688, 50816, 50880, 50881, 50872,     0,     1, 
+    49152, 51200, 50688, 50816, 50880, 50881, 50872, 50874, 
+        0,     1, 49152, 51200, 50688, 50816, 50880, 50881, 
+    50872,     0,     1, 49152, 51200, 50688, 50816, 50880, 
+    50881, 50872, 50876,     0,     1, 49152, 51200, 50688, 
+    50816, 50880, 50881, 50883, 50876,     0,     1, 49152, 
+    51200, 50688, 50816, 50880, 50881, 50883, 50876, 50878, 
+        0,     1, 49152, 51200, 50688, 50816,     0,     1, 
+    49152, 51200, 50688, 50944, 50880,     0,     1, 49152, 
+    51200, 50688, 50944, 50880,     0,     1, 49152, 51200, 
+    50688, 50944, 50880, 50882,     0,     1, 49152, 51200, 
+    50688, 50944, 50880,     0,     1, 49152, 51200, 50688, 
+    50944, 50880, 50884,     0,     1, 49152, 51200, 50688, 
+    50944, 50880, 50884,     0,     1, 49152, 51200, 50688, 
+    50944, 50880, 50888, 50886,     0,     1, 49152, 51200, 
+    50688, 50944, 50880,     0,     1, 49152, 51200, 50688, 
+    50944, 50880, 50888,     0,     1, 49152, 51200, 50688, 
+    50944, 50880, 50888,     0,     1, 49152, 51200, 50688, 
+    50944, 50880, 50888, 50890,     0,     1, 49152, 51200, 
+    50688, 50944, 50880, 50888,     0,     1, 49152, 51200, 
+    50688, 50944, 50880, 50896, 50892,     0,     1, 49152, 
+    51200, 50688, 50944, 50880, 50896, 50892,     0,     1, 
+    49152, 51200, 50688, 50944, 50880, 50896, 50897, 50894, 
+        0,     1, 49152, 51200, 50688, 50944, 50880,     0, 
+        1, 49152, 51200, 50688, 50944, 50880, 50896,     0, 
+        1, 49152, 51200, 50688, 50944, 50880, 50896,     0, 
+        1, 49152, 51200, 50688, 50944, 50880, 50896, 50898, 
+        0,     1, 49152, 51200, 50688, 50944, 50880, 50896, 
+        0,     1, 49152, 51200, 50688, 50944, 50880, 50896, 
+    50900,     0,     1, 49152, 51200, 50688, 50944, 50880, 
+    50896, 50900,     0,     1, 49152, 51200, 50688, 50944, 
+    50880, 50896, 50904, 50902,     0,     1, 49152, 51200, 
+    50688, 50944, 50880, 50896,     0,     1, 49152, 51200, 
+    50688, 50944, 50880, 50912, 50904,     0,     1, 49152, 
+    51200, 50688, 50944, 50880, 50912, 50904,     0,     1, 
+    49152, 51200, 50688, 50944, 50880, 50912, 50904, 50906, 
+        0,     1, 49152, 51200, 50688, 50944, 50880, 50912, 
+    50904,     0,     1, 49152, 51200, 50688, 50944, 50880, 
+    50912, 50913, 50908,     0,     1, 49152, 51200, 50688, 
+    50944, 50880, 50912, 50913, 50908,     0,     1, 49152, 
+    51200, 50688, 50944, 50880, 50912, 50913, 50908, 50910, 
+        0,     1, 49152, 51200, 50688, 50944, 50880,     0, 
+        1, 49152, 51200, 50688, 50944, 50945, 50912,     0, 
+        1, 49152, 51200, 50688, 50944, 50945, 50912,     0, 
+        1, 49152, 51200, 50688, 50944, 50945, 50912, 50914, 
+        0,     1, 49152, 51200, 50688, 50944, 50945, 50912, 
+        0,     1, 49152, 51200, 50688, 50944, 50945, 50912, 
+    50916,     0,     1, 49152, 51200, 50688, 50944, 50945, 
+    50912, 50916,     0,     1, 49152, 51200, 50688, 50944, 
+    50945, 50912, 50920, 50918,     0,     1, 49152, 51200, 
+    50688, 50944, 50945, 50912,     0,     1, 49152, 51200, 
+    50688, 50944, 50945, 50912, 50920,     0,     1, 49152, 
+    51200, 50688, 50944, 50945, 50912, 50920,     0,     1, 
+    49152, 51200, 50688, 50944, 50945, 50912, 50920, 50922, 
+        0,     1, 49152, 51200, 50688, 50944, 50945, 50912, 
+    50920,     0,     1, 49152, 51200, 50688, 50944, 50945, 
+    50912, 50928, 50924,     0,     1, 49152, 51200, 50688, 
+    50944, 50945, 50912, 50928, 50924,     0,     1, 49152, 
+    51200, 50688, 50944, 50945, 50912, 50928, 50929, 50926, 
+        0,     1, 49152, 51200, 50688, 50944, 50945, 50912, 
+        0,     1, 49152, 51200, 50688, 50944, 50945, 50912, 
+    50928,     0,     1, 49152, 51200, 50688, 50944, 50945, 
+    50947, 50928,     0,     1, 49152, 51200, 50688, 50944, 
+    50945, 50947, 50928, 50930,     0,     1, 49152, 51200, 
+    50688, 50944, 50945, 50947, 50928,     0,     1, 49152, 
+    51200, 50688, 50944, 50945, 50947, 50928, 50932,     0, 
+        1, 49152, 51200, 50688, 50944, 50945, 50947, 50928, 
+    50932,     0,     1, 49152, 51200, 50688, 50944, 50945, 
+    50947, 50928, 50936, 50934,     0,     1, 49152, 51200, 
+    50688, 50944, 50945, 50947, 50928,     0,     1, 49152, 
+    51200, 50688, 50944, 50945, 50947, 50928, 50936,     0, 
+        1, 49152, 51200, 50688, 50944, 50945, 50947, 50928, 
+    50936,     0,     1, 49152, 51200, 50688, 50944, 50945, 
+    50947, 50928, 50936, 50938,     0,     1, 49152, 51200, 
+    50688, 50944, 50945, 50947, 50951, 50936,     0,     1, 
+    49152, 51200, 50688, 50944, 50945, 50947, 50951, 50936, 
+    50940,     0,     1, 49152, 51200, 50688, 50944, 50945, 
+    50947, 50951, 50936, 50940,     0,     1, 49152, 51200, 
+    50688, 50944, 50945, 50947, 50951, 50936, 50940, 50942, 
+        0,     1, 49152, 51200, 50688,     0,     1, 49152, 
+    51200, 50688, 50944,     0,     1, 49152, 51200, 51201, 
+    50944,     0,     1, 49152, 51200, 51201, 50944, 50946, 
+        0,     1, 49152, 51200, 51201, 50944,     0,     1, 
+    49152, 51200, 51201, 50944, 50948,     0,     1, 49152, 
+    51200, 51201, 50944, 50948,     0,     1, 49152, 51200, 
+    51201, 50944, 50952, 50950,     0,     1, 49152, 51200, 
+    51201, 50944,     0,     1, 49152, 51200, 51201, 50944, 
+    50952,     0,     1, 49152, 51200, 51201, 50944, 50952, 
+        0,     1, 49152, 51200, 51201, 50944, 50952, 50954, 
+        0,     1, 49152, 51200, 51201, 50944, 50952,     0, 
+        1, 49152, 51200, 51201, 50944, 50960, 50956,     0, 
+        1, 49152, 51200, 51201, 50944, 50960, 50956,     0, 
+        1, 49152, 51200, 51201, 50944, 50960, 50961, 50958, 
+        0,     1, 49152, 51200, 51201, 50944,     0,     1, 
+    49152, 51200, 51201, 50944, 50960,     0,     1, 49152, 
+    51200, 51201, 50944, 50960,     0,     1, 49152, 51200, 
+    51201, 50944, 50960, 50962,     0,     1, 49152, 51200, 
+    51201, 50944, 50960,     0,     1, 49152, 51200, 51201, 
+    50944, 50960, 50964,     0,     1, 49152, 51200, 51201, 
+    50944, 50960, 50964,     0,     1, 49152, 51200, 51201, 
+    50944, 50960, 50968, 50966,     0,     1, 49152, 51200, 
+    51201, 50944, 50960,     0,     1, 49152, 51200, 51201, 
+    50944, 50976, 50968,     0,     1, 49152, 51200, 51201, 
+    50944, 50976, 50968,     0,     1, 49152, 51200, 51201, 
+    50944, 50976, 50968, 50970,     0,     1, 49152, 51200, 
+    51201, 50944, 50976, 50968,     0,     1, 49152, 51200, 
+    51201, 50944, 50976, 50977, 50972,     0,     1, 49152, 
+    51200, 51201, 50944, 50976, 50977, 50972,     0,     1, 
+    49152, 51200, 51201, 50944, 50976, 50977, 50972, 50974, 
+        0,     1, 49152, 51200, 51201, 50944,     0,     1, 
+    49152, 51200, 51201, 50944, 50976,     0,     1, 49152, 
+    51200, 51201, 50944, 50976,     0,     1, 49152, 51200, 
+    51201, 50944, 50976, 50978,     0,     1, 49152, 51200, 
+    51201, 50944, 50976,     0,     1, 49152, 51200, 51201, 
+    50944, 50976, 50980,     0,     1, 49152, 51200, 51201, 
+    50944, 50976, 50980,     0,     1, 49152, 51200, 51201, 
+    50944, 50976, 50984, 50982,     0,     1, 49152, 51200, 
+    51201, 50944, 50976,     0,     1, 49152, 51200, 51201, 
+    50944, 50976, 50984,     0,     1, 49152, 51200, 51201, 
+    50944, 50976, 50984,     0,     1, 49152, 51200, 51201, 
+    50944, 50976, 50984, 50986,     0,     1, 49152, 51200, 
+    51201, 50944, 50976, 50984,     0,     1, 49152, 51200, 
+    51201, 50944, 50976, 50992, 50988,     0,     1, 49152, 
+    51200, 51201, 50944, 50976, 50992, 50988,     0,     1, 
+    49152, 51200, 51201, 50944, 50976, 50992, 50993, 50990, 
+        0,     1, 49152, 51200, 51201, 50944, 50976,     0, 
+        1, 49152, 51200, 51201, 50944, 51008, 50992,     0, 
+        1, 49152, 51200, 51201, 50944, 51008, 50992,     0, 
+        1, 49152, 51200, 51201, 50944, 51008, 50992, 50994, 
+        0,     1, 49152, 51200, 51201, 50944, 51008, 50992, 
+        0,     1, 49152, 51200, 51201, 50944, 51008, 50992, 
+    50996,     0,     1, 49152, 51200, 51201, 50944, 51008, 
+    50992, 50996,     0,     1, 49152, 51200, 51201, 50944, 
+    51008, 50992, 51000, 50998,     0,     1, 49152, 51200, 
+    51201, 50944, 51008, 50992,     0,     1, 49152, 51200, 
+    51201, 50944, 51008, 51009, 51000,     0,     1, 49152, 
+    51200, 51201, 50944, 51008, 51009, 51000,     0,     1, 
+    49152, 51200, 51201, 50944, 51008, 51009, 51000, 51002, 
+        0,     1, 49152, 51200, 51201, 50944, 51008, 51009, 
+    51000,     0,     1, 49152, 51200, 51201, 50944, 51008, 
+    51009, 51000, 51004,     0,     1, 49152, 51200, 51201, 
+    50944, 51008, 51009, 51011, 51004,     0,     1, 49152, 
+    51200, 51201, 50944, 51008, 51009, 51011, 51004, 51006, 
+        0,     1, 49152, 51200, 51201, 50944,     0,     1, 
+    49152, 51200, 51201, 50944, 51008,     0,     1, 49152, 
+    51200, 51201, 50944, 51008,     0,     1, 49152, 51200, 
+    51201, 50944, 51008, 51010,     0,     1, 49152, 51200, 
+    51201, 50944, 51008,     0,     1, 49152, 51200, 51201, 
+    50944, 51008, 51012,     0,     1, 49152, 51200, 51201, 
+    50944, 51008, 51012,     0,     1, 49152, 51200, 51201, 
+    50944, 51008, 51016, 51014,     0,     1, 49152, 51200, 
+    51201, 50944, 51008,     0,     1, 49152, 51200, 51201, 
+    50944, 51008, 51016,     0,     1, 49152, 51200, 51201, 
+    50944, 51008, 51016,     0,     1, 49152, 51200, 51201, 
+    50944, 51008, 51016, 51018,     0,     1, 49152, 51200, 
+    51201, 50944, 51008, 51016,     0,     1, 49152, 51200, 
+    51201, 50944, 51008, 51024, 51020,     0,     1, 49152, 
+    51200, 51201, 50944, 51008, 51024, 51020,     0,     1, 
+    49152, 51200, 51201, 50944, 51008, 51024, 51025, 51022, 
+        0,     1, 49152, 51200, 51201, 50944, 51008,     0, 
+        1, 49152, 51200, 51201, 50944, 51008, 51024,     0, 
+        1, 49152, 51200, 51201, 50944, 51008, 51024,     0, 
+        1, 49152, 51200, 51201, 50944, 51008, 51024, 51026, 
+        0,     1, 49152, 51200, 51201, 50944, 51008, 51024, 
+        0,     1, 49152, 51200, 51201, 50944, 51008, 51024, 
+    51028,     0,     1, 49152, 51200, 51201, 50944, 51008, 
+    51024, 51028,     0,     1, 49152, 51200, 51201, 50944, 
+    51008, 51024, 51032, 51030,     0,     1, 49152, 51200, 
+    51201, 50944, 51008, 51024,     0,     1, 49152, 51200, 
+    51201, 50944, 51008, 51040, 51032,     0,     1, 49152, 
+    51200, 51201, 50944, 51008, 51040, 51032,     0,     1, 
+    49152, 51200, 51201, 50944, 51008, 51040, 51032, 51034, 
+        0,     1, 49152, 51200, 51201, 50944, 51008, 51040, 
+    51032,     0,     1, 49152, 51200, 51201, 50944, 51008, 
+    51040, 51041, 51036,     0,     1, 49152, 51200, 51201, 
+    50944, 51008, 51040, 51041, 51036,     0,     1, 49152, 
+    51200, 51201, 50944, 51008, 51040, 51041, 51036, 51038, 
+        0,     1, 49152, 51200, 51201, 50944, 51008,     0, 
+        1, 49152, 51200, 51201, 50944, 51072, 51040,     0, 
+        1, 49152, 51200, 51201, 50944, 51072, 51040,     0, 
+        1, 49152, 51200, 51201, 50944, 51072, 51040, 51042, 
+        0,     1, 49152, 51200, 51201, 50944, 51072, 51040, 
+        0,     1, 49152, 51200, 51201, 50944, 51072, 51040, 
+    51044,     0,     1, 49152, 51200, 51201, 50944, 51072, 
+    51040, 51044,     0,     1, 49152, 51200, 51201, 50944, 
+    51072, 51040, 51048, 51046,     0,     1, 49152, 51200, 
+    51201, 50944, 51072, 51040,     0,     1, 49152, 51200, 
+    51201, 50944, 51072, 51040, 51048,     0,     1, 49152, 
+    51200, 51201, 50944, 51072, 51040, 51048,     0,     1, 
+    49152, 51200, 51201, 50944, 51072, 51040, 51048, 51050, 
+        0,     1, 49152, 51200, 51201, 50944, 51072, 51040, 
+    51048,     0,     1, 49152, 51200, 51201, 50944, 51072, 
+    51040, 51056, 51052,     0,     1, 49152, 51200, 51201, 
+    50944, 51072, 51040, 51056, 51052,     0,     1, 49152, 
+    51200, 51201, 50944, 51072, 51040, 51056, 51057, 51054, 
+        0,     1, 49152, 51200, 51201, 50944, 51072, 51040, 
+        0,     1, 49152, 51200, 51201, 50944, 51072, 51073, 
+    51056,     0,     1, 49152, 51200, 51201, 50944, 51072, 
+    51073, 51056,     0,     1, 49152, 51200, 51201, 50944, 
+    51072, 51073, 51056, 51058,     0,     1, 49152, 51200, 
+    51201, 50944, 51072, 51073, 51056,     0,     1, 49152, 
+    51200, 51201, 50944, 51072, 51073, 51056, 51060,     0, 
+        1, 49152, 51200, 51201, 50944, 51072, 51073, 51056, 
+    51060,     0,     1, 49152, 51200, 51201, 50944, 51072, 
+    51073, 51056, 51064, 51062,     0,     1, 49152, 51200, 
+    51201, 50944, 51072, 51073, 51056,     0,     1, 49152, 
+    51200, 51201, 50944, 51072, 51073, 51056, 51064,     0, 
+        1, 49152, 51200, 51201, 50944, 51072, 51073, 51075, 
+    51064,     0,     1, 49152, 51200, 51201, 50944, 51072, 
+    51073, 51075, 51064, 51066,     0,     1, 49152, 51200, 
+    51201, 50944, 51072, 51073, 51075, 51064,     0,     1, 
+    49152, 51200, 51201, 50944, 51072, 51073, 51075, 51064, 
+    51068,     0,     1, 49152, 51200, 51201, 50944, 51072, 
+    51073, 51075, 51064, 51068,     0,     1, 49152, 51200, 
+    51201, 50944, 51072, 51073, 51075, 51064, 51068, 51070, 
+        0,     1, 49152, 51200, 51201, 50944,     0,     1, 
+    49152, 51200, 51201, 50944, 51072,     0,     1, 49152, 
+    51200, 51201, 50944, 51072,     0,     1, 49152, 51200, 
+    51201, 50944, 51072, 51074,     0,     1, 49152, 51200, 
+    51201, 51203, 51072,     0,     1, 49152, 51200, 51201, 
+    51203, 51072, 51076,     0,     1, 49152, 51200, 51201, 
+    51203, 51072, 51076,     0,     1, 49152, 51200, 51201, 
+    51203, 51072, 51080, 51078,     0,     1, 49152, 51200, 
+    51201, 51203, 51072,     0,     1, 49152, 51200, 51201, 
+    51203, 51072, 51080,     0,     1, 49152, 51200, 51201, 
+    51203, 51072, 51080,     0,     1, 49152, 51200, 51201, 
+    51203, 51072, 51080, 51082,     0,     1, 49152, 51200, 
+    51201, 51203, 51072, 51080,     0,     1, 49152, 51200, 
+    51201, 51203, 51072, 51088, 51084,     0,     1, 49152, 
+    51200, 51201, 51203, 51072, 51088, 51084,     0,     1, 
+    49152, 51200, 51201, 51203, 51072, 51088, 51089, 51086, 
+        0,     1, 49152, 51200, 51201, 51203, 51072,     0, 
+        1, 49152, 51200, 51201, 51203, 51072, 51088,     0, 
+        1, 49152, 51200, 51201, 51203, 51072, 51088,     0, 
+        1, 49152, 51200, 51201, 51203, 51072, 51088, 51090, 
+        0,     1, 49152, 51200, 51201, 51203, 51072, 51088, 
+        0,     1, 49152, 51200, 51201, 51203, 51072, 51088, 
+    51092,     0,     1, 49152, 51200, 51201, 51203, 51072, 
+    51088, 51092,     0,     1, 49152, 51200, 51201, 51203, 
+    51072, 51088, 51096, 51094,     0,     1, 49152, 51200, 
+    51201, 51203, 51072, 51088,     0,     1, 49152, 51200, 
+    51201, 51203, 51072, 51104, 51096,     0,     1, 49152, 
+    51200, 51201, 51203, 51072, 51104, 51096,     0,     1, 
+    49152, 51200, 51201, 51203, 51072, 51104, 51096, 51098, 
+        0,     1, 49152, 51200, 51201, 51203, 51072, 51104, 
+    51096,     0,     1, 49152, 51200, 51201, 51203, 51072, 
+    51104, 51105, 51100,     0,     1, 49152, 51200, 51201, 
+    51203, 51072, 51104, 51105, 51100,     0,     1, 49152, 
+    51200, 51201, 51203, 51072, 51104, 51105, 51100, 51102, 
+        0,     1, 49152, 51200, 51201, 51203, 51072,     0, 
+        1, 49152, 51200, 51201, 51203, 51072, 51104,     0, 
+        1, 49152, 51200, 51201, 51203, 51072, 51104,     0, 
+        1, 49152, 51200, 51201, 51203, 51072, 51104, 51106, 
+        0,     1, 49152, 51200, 51201, 51203, 51072, 51104, 
+        0,     1, 49152, 51200, 51201, 51203, 51072, 51104, 
+    51108,     0,     1, 49152, 51200, 51201, 51203, 51072, 
+    51104, 51108,     0,     1, 49152, 51200, 51201, 51203, 
+    51072, 51104, 51112, 51110,     0,     1, 49152, 51200, 
+    51201, 51203, 51072, 51104,     0,     1, 49152, 51200, 
+    51201, 51203, 51072, 51104, 51112,     0,     1, 49152, 
+    51200, 51201, 51203, 51072, 51104, 51112,     0,     1, 
+    49152, 51200, 51201, 51203, 51072, 51104, 51112, 51114, 
+        0,     1, 49152, 51200, 51201, 51203, 51072, 51104, 
+    51112,     0,     1, 49152, 51200, 51201, 51203, 51072, 
+    51104, 51120, 51116,     0,     1, 49152, 51200, 51201, 
+    51203, 51072, 51104, 51120, 51116,     0,     1, 49152, 
+    51200, 51201, 51203, 51072, 51104, 51120, 51121, 51118, 
+        0,     1, 49152, 51200, 51201, 51203, 51072, 51104, 
+        0,     1, 49152, 51200, 51201, 51203, 51072, 51136, 
+    51120,     0,     1, 49152, 51200, 51201, 51203, 51072, 
+    51136, 51120,     0,     1, 49152, 51200, 51201, 51203, 
+    51072, 51136, 51120, 51122,     0,     1, 49152, 51200, 
+    51201, 51203, 51072, 51136, 51120,     0,     1, 49152, 
+    51200, 51201, 51203, 51072, 51136, 51120, 51124,     0, 
+        1, 49152, 51200, 51201, 51203, 51072, 51136, 51120, 
+    51124,     0,     1, 49152, 51200, 51201, 51203, 51072, 
+    51136, 51120, 51128, 51126,     0,     1, 49152, 51200, 
+    51201, 51203, 51072, 51136, 51120,     0,     1, 49152, 
+    51200, 51201, 51203, 51072, 51136, 51137, 51128,     0, 
+        1, 49152, 51200, 51201, 51203, 51072, 51136, 51137, 
+    51128,     0,     1, 49152, 51200, 51201, 51203, 51072, 
+    51136, 51137, 51128, 51130,     0,     1, 49152, 51200, 
+    51201, 51203, 51072, 51136, 51137, 51128,     0,     1, 
+    49152, 51200, 51201, 51203, 51072, 51136, 51137, 51128, 
+    51132,     0,     1, 49152, 51200, 51201, 51203, 51072, 
+    51136, 51137, 51139, 51132,     0,     1, 49152, 51200, 
+    51201, 51203, 51072, 51136, 51137, 51139, 51132, 51134, 
+        0,     1, 49152, 51200, 51201, 51203, 51072,     0, 
+        1, 49152, 51200, 51201, 51203, 51072, 51136,     0, 
+        1, 49152, 51200, 51201, 51203, 51072, 51136,     0, 
+        1, 49152, 51200, 51201, 51203, 51072, 51136, 51138, 
+        0,     1, 49152, 51200, 51201, 51203, 51072, 51136, 
+        0,     1, 49152, 51200, 51201, 51203, 51072, 51136, 
+    51140,     0,     1, 49152, 51200, 51201, 51203, 51072, 
+    51136, 51140,     0,     1, 49152, 51200, 51201, 51203, 
+    51072, 51136, 51144, 51142,     0,     1, 49152, 51200, 
+    51201, 51203, 51207, 51136,     0,     1, 49152, 51200, 
+    51201, 51203, 51207, 51136, 51144,     0,     1, 49152, 
+    51200, 51201, 51203, 51207, 51136, 51144,     0,     1, 
+    49152, 51200, 51201, 51203, 51207, 51136, 51144, 51146, 
+        0,     1, 49152, 51200, 51201, 51203, 51207, 51136, 
+    51144,     0,     1, 49152, 51200, 51201, 51203, 51207, 
+    51136, 51152, 51148,     0,     1, 49152, 51200, 51201, 
+    51203, 51207, 51136, 51152, 51148,     0,     1, 49152, 
+    51200, 51201, 51203, 51207, 51136, 51152, 51153, 51150, 
+        0,     1, 49152, 51200, 51201, 51203, 51207, 51136, 
+        0,     1, 49152, 51200, 51201, 51203, 51207, 51136, 
+    51152,     0,     1, 49152, 51200, 51201, 51203, 51207, 
+    51136, 51152,     0,     1, 49152, 51200, 51201, 51203, 
+    51207, 51136, 51152, 51154,     0,     1, 49152, 51200, 
+    51201, 51203, 51207, 51136, 51152,     0,     1, 49152, 
+    51200, 51201, 51203, 51207, 51136, 51152, 51156,     0, 
+        1, 49152, 51200, 51201, 51203, 51207, 51136, 51152, 
+    51156,     0,     1, 49152, 51200, 51201, 51203, 51207, 
+    51136, 51152, 51160, 51158,     0,     1, 49152, 51200, 
+    51201, 51203, 51207, 51136, 51152,     0,     1, 49152, 
+    51200, 51201, 51203, 51207, 51136, 51168, 51160,     0, 
+        1, 49152, 51200, 51201, 51203, 51207, 51136, 51168, 
+    51160,     0,     1, 49152, 51200, 51201, 51203, 51207, 
+    51136, 51168, 51160, 51162,     0,     1, 49152, 51200, 
+    51201, 51203, 51207, 51136, 51168, 51160,     0,     1, 
+    49152, 51200, 51201, 51203, 51207, 51136, 51168, 51169, 
+    51164,     0,     1, 49152, 51200, 51201, 51203, 51207, 
+    51136, 51168, 51169, 51164,     0,     1, 49152, 51200, 
+    51201, 51203, 51207, 51136, 51168, 51169, 51164, 51166, 
+        0,     1, 49152, 51200, 51201, 51203, 51207, 51136, 
+        0,     1, 49152, 51200, 51201, 51203, 51207, 51136, 
+    51168,     0,     1, 49152, 51200, 51201, 51203, 51207, 
+    51136, 51168,     0,     1, 49152, 51200, 51201, 51203, 
+    51207, 51136, 51168, 51170,     0,     1, 49152, 51200, 
+    51201, 51203, 51207, 51136, 51168,     0,     1, 49152, 
+    51200, 51201, 51203, 51207, 51136, 51168, 51172,     0, 
+        1, 49152, 51200, 51201, 51203, 51207, 51136, 51168, 
+    51172,     0,     1, 49152, 51200, 51201, 51203, 51207, 
+    51136, 51168, 51176, 51174,     0,     1, 49152, 51200, 
+    51201, 51203, 51207, 51136, 51168,     0,     1, 49152, 
+    51200, 51201, 51203, 51207, 51136, 51168, 51176,     0, 
+        1, 49152, 51200, 51201, 51203, 51207, 51136, 51168, 
+    51176,     0,     1, 49152, 51200, 51201, 51203, 51207, 
+    51136, 51168, 51176, 51178,     0,     1, 49152, 51200, 
+    51201, 51203, 51207, 51136, 51168, 51176,     0,     1, 
+    49152, 51200, 51201, 51203, 51207, 51136, 51168, 51184, 
+    51180,     0,     1, 49152, 51200, 51201, 51203, 51207, 
+    51136, 51168, 51184, 51180,     0,     1, 49152, 51200, 
+    51201, 51203, 51207, 51136, 51168, 51184, 51185, 51182, 
+        0,     1, 49152, 51200, 51201, 51203, 51207, 51215, 
+    51168,     0,     1, 49152, 51200, 51201, 51203, 51207, 
+    51215, 51168, 51184,     0,     1, 49152, 51200, 51201, 
+    51203, 51207, 51215, 51168, 51184,     0,     1, 49152, 
+    51200, 51201, 51203, 51207, 51215, 51168, 51184, 51186, 
+        0,     1, 49152, 51200, 51201, 51203, 51207, 51215, 
+    51168, 51184,     0,     1, 49152, 51200, 51201, 51203, 
+    51207, 51215, 51168, 51184, 51188,     0,     1, 49152, 
+    51200, 51201, 51203, 51207, 51215, 51168, 51184, 51188, 
+        0,     1, 49152, 51200, 51201, 51203, 51207, 51215, 
+    51168, 51184, 51192, 51190,     0,     1, 49152, 51200, 
+    51201, 51203, 51207, 51215, 51168, 51184,     0,     1, 
+    49152, 51200, 51201, 51203, 51207, 51215, 51168, 51184, 
+    51192,     0,     1, 49152, 51200, 51201, 51203, 51207, 
+    51215, 51168, 51184, 51192,     0,     1, 49152, 51200, 
+    51201, 51203, 51207, 51215, 51168, 51184, 51192, 51194, 
+        0,     1, 49152, 51200, 51201, 51203, 51207, 51215, 
+    51168, 51184, 51192,     0,     1, 49152, 51200, 51201, 
+    51203, 51207, 51215, 51168, 51184, 51192, 51196,     0, 
+        1, 49152, 51200, 51201, 51203, 51207, 51215, 51168, 
+    51184, 51192, 51196,     0,     1, 49152, 51200, 51201, 
+    51203, 51207, 51215, 51168, 51184, 51192, 51196, 51198, 
+        0,     1, 49152,     0,     1, 49152, 51200,     0, 
+        1, 49152, 51200,     0,     1, 49152, 51200, 51202, 
+        0,     1, 49152, 51200,     0,     1, 49152, 51200, 
+    51204,     0,     1, 49152, 51200, 51204,     0,     1, 
+    49152, 51200, 51208, 51206,     0,     1, 49152, 51200, 
+        0,     1, 49152, 51200, 51208,     0,     1, 49152, 
+    51200, 51208,     0,     1, 49152, 51200, 51208, 51210, 
+        0,     1, 49152, 51200, 51208,     0,     1, 49152, 
+    51200, 51216, 51212,     0,     1, 49152, 51200, 51216, 
+    51212,     0,     1, 49152, 51200, 51216, 51217, 51214, 
+        0,     1, 49152, 51200,     0,     1, 49152, 51200, 
+    51216,     0,     1, 49152, 51200, 51216,     0,     1, 
+    49152, 51200, 51216, 51218,     0,     1, 49152, 51200, 
+    51216,     0,     1, 49152, 51200, 51216, 51220,     0, 
+        1, 49152, 51200, 51216, 51220,     0,     1, 49152, 
+    51200, 51216, 51224, 51222,     0,     1, 49152, 51200, 
+    51216,     0,     1, 49152, 51200, 51232, 51224,     0, 
+        1, 49152, 51200, 51232, 51224,     0,     1, 49152, 
+    51200, 51232, 51224, 51226,     0,     1, 49152, 51200, 
+    51232, 51224,     0,     1, 49152, 51200, 51232, 51233, 
+    51228,     0,     1, 49152, 51200, 51232, 51233, 51228, 
+        0,     1, 49152, 51200, 51232, 51233, 51228, 51230, 
+        0,     1, 49152, 51200,     0,     1, 49152, 51200, 
+    51232,     0,     1, 49152, 51200, 51232,     0,     1, 
+    49152, 51200, 51232, 51234,     0,     1, 49152, 51200, 
+    51232,     0,     1, 49152, 51200, 51232, 51236,     0, 
+        1, 49152, 51200, 51232, 51236,     0,     1, 49152, 
+    51200, 51232, 51240, 51238,     0,     1, 49152, 51200, 
+    51232,     0,     1, 49152, 51200, 51232, 51240,     0, 
+        1, 49152, 51200, 51232, 51240,     0,     1, 49152, 
+    51200, 51232, 51240, 51242,     0,     1, 49152, 51200, 
+    51232, 51240,     0,     1, 49152, 51200, 51232, 51248, 
+    51244,     0,     1, 49152, 51200, 51232, 51248, 51244, 
+        0,     1, 49152, 51200, 51232, 51248, 51249, 51246, 
+        0,     1, 49152, 51200, 51232,     0,     1, 49152, 
+    51200, 51264, 51248,     0,     1, 49152, 51200, 51264, 
+    51248,     0,     1, 49152, 51200, 51264, 51248, 51250, 
+        0,     1, 49152, 51200, 51264, 51248,     0,     1, 
+    49152, 51200, 51264, 51248, 51252,     0,     1, 49152, 
+    51200, 51264, 51248, 51252,     0,     1, 49152, 51200, 
+    51264, 51248, 51256, 51254,     0,     1, 49152, 51200, 
+    51264, 51248,     0,     1, 49152, 51200, 51264, 51265, 
+    51256,     0,     1, 49152, 51200, 51264, 51265, 51256, 
+        0,     1, 49152, 51200, 51264, 51265, 51256, 51258, 
+        0,     1, 49152, 51200, 51264, 51265, 51256,     0, 
+        1, 49152, 51200, 51264, 51265, 51256, 51260,     0, 
+        1, 49152, 51200, 51264, 51265, 51267, 51260,     0, 
+        1, 49152, 51200, 51264, 51265, 51267, 51260, 51262, 
+        0,     1, 49152, 51200,     0,     1, 49152, 51200, 
+    51264,     0,     1, 49152, 51200, 51264,     0,     1, 
+    49152, 51200, 51264, 51266,     0,     1, 49152, 51200, 
+    51264,     0,     1, 49152, 51200, 51264, 51268,     0, 
+        1, 49152, 51200, 51264, 51268,     0,     1, 49152, 
+    51200, 51264, 51272, 51270,     0,     1, 49152, 51200, 
+    51264,     0,     1, 49152, 51200, 51264, 51272,     0, 
+        1, 49152, 51200, 51264, 51272,     0,     1, 49152, 
+    51200, 51264, 51272, 51274,     0,     1, 49152, 51200, 
+    51264, 51272,     0,     1, 49152, 51200, 51264, 51280, 
+    51276,     0,     1, 49152, 51200, 51264, 51280, 51276, 
+        0,     1, 49152, 51200, 51264, 51280, 51281, 51278, 
+        0,     1, 49152, 51200, 51264,     0,     1, 49152, 
+    51200, 51264, 51280,     0,     1, 49152, 51200, 51264, 
+    51280,     0,     1, 49152, 51200, 51264, 51280, 51282, 
+        0,     1, 49152, 51200, 51264, 51280,     0,     1, 
+    49152, 51200, 51264, 51280, 51284,     0,     1, 49152, 
+    51200, 51264, 51280, 51284,     0,     1, 49152, 51200, 
+    51264, 51280, 51288, 51286,     0,     1, 49152, 51200, 
+    51264, 51280,     0,     1, 49152, 51200, 51264, 51296, 
+    51288,     0,     1, 49152, 51200, 51264, 51296, 51288, 
+        0,     1, 49152, 51200, 51264, 51296, 51288, 51290, 
+        0,     1, 49152, 51200, 51264, 51296, 51288,     0, 
+        1, 49152, 51200, 51264, 51296, 51297, 51292,     0, 
+        1, 49152, 51200, 51264, 51296, 51297, 51292,     0, 
+        1, 49152, 51200, 51264, 51296, 51297, 51292, 51294, 
+        0,     1, 49152, 51200, 51264,     0,     1, 49152, 
+    51200, 51328, 51296,     0,     1, 49152, 51200, 51328, 
+    51296,     0,     1, 49152, 51200, 51328, 51296, 51298, 
+        0,     1, 49152, 51200, 51328, 51296,     0,     1, 
+    49152, 51200, 51328, 51296, 51300,     0,     1, 49152, 
+    51200, 51328, 51296, 51300,     0,     1, 49152, 51200, 
+    51328, 51296, 51304, 51302,     0,     1, 49152, 51200, 
+    51328, 51296,     0,     1, 49152, 51200, 51328, 51296, 
+    51304,     0,     1, 49152, 51200, 51328, 51296, 51304, 
+        0,     1, 49152, 51200, 51328, 51296, 51304, 51306, 
+        0,     1, 49152, 51200, 51328, 51296, 51304,     0, 
+        1, 49152, 51200, 51328, 51296, 51312, 51308,     0, 
+        1, 49152, 51200, 51328, 51296, 51312, 51308,     0, 
+        1, 49152, 51200, 51328, 51296, 51312, 51313, 51310, 
+        0,     1, 49152, 51200, 51328, 51296,     0,     1, 
+    49152, 51200, 51328, 51329, 51312,     0,     1, 49152, 
+    51200, 51328, 51329, 51312,     0,     1, 49152, 51200, 
+    51328, 51329, 51312, 51314,     0,     1, 49152, 51200, 
+    51328, 51329, 51312,     0,     1, 49152, 51200, 51328, 
+    51329, 51312, 51316,     0,     1, 49152, 51200, 51328, 
+    51329, 51312, 51316,     0,     1, 49152, 51200, 51328, 
+    51329, 51312, 51320, 51318,     0,     1, 49152, 51200, 
+    51328, 51329, 51312,     0,     1, 49152, 51200, 51328, 
+    51329, 51312, 51320,     0,     1, 49152, 51200, 51328, 
+    51329, 51331, 51320,     0,     1, 49152, 51200, 51328, 
+    51329, 51331, 51320, 51322,     0,     1, 49152, 51200, 
+    51328, 51329, 51331, 51320,     0,     1, 49152, 51200, 
+    51328, 51329, 51331, 51320, 51324,     0,     1, 49152, 
+    51200, 51328, 51329, 51331, 51320, 51324,     0,     1, 
+    49152, 51200, 51328, 51329, 51331, 51320, 51324, 51326, 
+        0,     1, 49152, 51200,     0,     1, 49152, 51200, 
+    51328,     0,     1, 49152, 51200, 51328,     0,     1, 
+    49152, 51200, 51328, 51330,     0,     1, 49152, 51200, 
+    51328,     0,     1, 49152, 51200, 51328, 51332,     0, 
+        1, 49152, 51200, 51328, 51332,     0,     1, 49152, 
+    51200, 51328, 51336, 51334,     0,     1, 49152, 51200, 
+    51328,     0,     1, 49152, 51200, 51328, 51336,     0, 
+        1, 49152, 51200, 51328, 51336,     0,     1, 49152, 
+    51200, 51328, 51336, 51338,     0,     1, 49152, 51200, 
+    51328, 51336,     0,     1, 49152, 51200, 51328, 51344, 
+    51340,     0,     1, 49152, 51200, 51328, 51344, 51340, 
+        0,     1, 49152, 51200, 51328, 51344, 51345, 51342, 
+        0,     1, 49152, 51200, 51328,     0,     1, 49152, 
+    51200, 51328, 51344,     0,     1, 49152, 51200, 51328, 
+    51344,     0,     1, 49152, 51200, 51328, 51344, 51346, 
+        0,     1, 49152, 51200, 51328, 51344,     0,     1, 
+    49152, 51200, 51328, 51344, 51348,     0,     1, 49152, 
+    51200, 51328, 51344, 51348,     0,     1, 49152, 51200, 
+    51328, 51344, 51352, 51350,     0,     1, 49152, 51200, 
+    51328, 51344,     0,     1, 49152, 51200, 51328, 51360, 
+    51352,     0,     1, 49152, 51200, 51328, 51360, 51352, 
+        0,     1, 49152, 51200, 51328, 51360, 51352, 51354, 
+        0,     1, 49152, 51200, 51328, 51360, 51352,     0, 
+        1, 49152, 51200, 51328, 51360, 51361, 51356,     0, 
+        1, 49152, 51200, 51328, 51360, 51361, 51356,     0, 
+        1, 49152, 51200, 51328, 51360, 51361, 51356, 51358, 
+        0,     1, 49152, 51200, 51328,     0,     1, 49152, 
+    51200, 51328, 51360,     0,     1, 49152, 51200, 51328, 
+    51360,     0,     1, 49152, 51200, 51328, 51360, 51362, 
+        0,     1, 49152, 51200, 51328, 51360,     0,     1, 
+    49152, 51200, 51328, 51360, 51364,     0,     1, 49152, 
+    51200, 51328, 51360, 51364,     0,     1, 49152, 51200, 
+    51328, 51360, 51368, 51366,     0,     1, 49152, 51200, 
+    51328, 51360,     0,     1, 49152, 51200, 51328, 51360, 
+    51368,     0,     1, 49152, 51200, 51328, 51360, 51368, 
+        0,     1, 49152, 51200, 51328, 51360, 51368, 51370, 
+        0,     1, 49152, 51200, 51328, 51360, 51368,     0, 
+        1, 49152, 51200, 51328, 51360, 51376, 51372,     0, 
+        1, 49152, 51200, 51328, 51360, 51376, 51372,     0, 
+        1, 49152, 51200, 51328, 51360, 51376, 51377, 51374, 
+        0,     1, 49152, 51200, 51328, 51360,     0,     1, 
+    49152, 51200, 51328, 51392, 51376,     0,     1, 49152, 
+    51200, 51328, 51392, 51376,     0,     1, 49152, 51200, 
+    51328, 51392, 51376, 51378,     0,     1, 49152, 51200, 
+    51328, 51392, 51376,     0,     1, 49152, 51200, 51328, 
+    51392, 51376, 51380,     0,     1, 49152, 51200, 51328, 
+    51392, 51376, 51380,     0,     1, 49152, 51200, 51328, 
+    51392, 51376, 51384, 51382,     0,     1, 49152, 51200, 
+    51328, 51392, 51376,     0,     1, 49152, 51200, 51328, 
+    51392, 51393, 51384,     0,     1, 49152, 51200, 51328, 
+    51392, 51393, 51384,     0,     1, 49152, 51200, 51328, 
+    51392, 51393, 51384, 51386,     0,     1, 49152, 51200, 
+    51328, 51392, 51393, 51384,     0,     1, 49152, 51200, 
+    51328, 51392, 51393, 51384, 51388,     0,     1, 49152, 
+    51200, 51328, 51392, 51393, 51395, 51388,     0,     1, 
+    49152, 51200, 51328, 51392, 51393, 51395, 51388, 51390, 
+        0,     1, 49152, 51200, 51328,     0,     1, 49152, 
+    51200, 51456, 51392,     0,     1, 49152, 51200, 51456, 
+    51392,     0,     1, 49152, 51200, 51456, 51392, 51394, 
+        0,     1, 49152, 51200, 51456, 51392,     0,     1, 
+    49152, 51200, 51456, 51392, 51396,     0,     1, 49152, 
+    51200, 51456, 51392, 51396,     0,     1, 49152, 51200, 
+    51456, 51392, 51400, 51398,     0,     1, 49152, 51200, 
+    51456, 51392,     0,     1, 49152, 51200, 51456, 51392, 
+    51400,     0,     1, 49152, 51200, 51456, 51392, 51400, 
+        0,     1, 49152, 51200, 51456, 51392, 51400, 51402, 
+        0,     1, 49152, 51200, 51456, 51392, 51400,     0, 
+        1, 49152, 51200, 51456, 51392, 51408, 51404,     0, 
+        1, 49152, 51200, 51456, 51392, 51408, 51404,     0, 
+        1, 49152, 51200, 51456, 51392, 51408, 51409, 51406, 
+        0,     1, 49152, 51200, 51456, 51392,     0,     1, 
+    49152, 51200, 51456, 51392, 51408,     0,     1, 49152, 
+    51200, 51456, 51392, 51408,     0,     1, 49152, 51200, 
+    51456, 51392, 51408, 51410,     0,     1, 49152, 51200, 
+    51456, 51392, 51408,     0,     1, 49152, 51200, 51456, 
+    51392, 51408, 51412,     0,     1, 49152, 51200, 51456, 
+    51392, 51408, 51412,     0,     1, 49152, 51200, 51456, 
+    51392, 51408, 51416, 51414,     0,     1, 49152, 51200, 
+    51456, 51392, 51408,     0,     1, 49152, 51200, 51456, 
+    51392, 51424, 51416,     0,     1, 49152, 51200, 51456, 
+    51392, 51424, 51416,     0,     1, 49152, 51200, 51456, 
+    51392, 51424, 51416, 51418,     0,     1, 49152, 51200, 
+    51456, 51392, 51424, 51416,     0,     1, 49152, 51200, 
+    51456, 51392, 51424, 51425, 51420,     0,     1, 49152, 
+    51200, 51456, 51392, 51424, 51425, 51420,     0,     1, 
+    49152, 51200, 51456, 51392, 51424, 51425, 51420, 51422, 
+        0,     1, 49152, 51200, 51456, 51392,     0,     1, 
+    49152, 51200, 51456, 51457, 51424,     0,     1, 49152, 
+    51200, 51456, 51457, 51424,     0,     1, 49152, 51200, 
+    51456, 51457, 51424, 51426,     0,     1, 49152, 51200, 
+    51456, 51457, 51424,     0,     1, 49152, 51200, 51456, 
+    51457, 51424, 51428,     0,     1, 49152, 51200, 51456, 
+    51457, 51424, 51428,     0,     1, 49152, 51200, 51456, 
+    51457, 51424, 51432, 51430,     0,     1, 49152, 51200, 
+    51456, 51457, 51424,     0,     1, 49152, 51200, 51456, 
+    51457, 51424, 51432,     0,     1, 49152, 51200, 51456, 
+    51457, 51424, 51432,     0,     1, 49152, 51200, 51456, 
+    51457, 51424, 51432, 51434,     0,     1, 49152, 51200, 
+    51456, 51457, 51424, 51432,     0,     1, 49152, 51200, 
+    51456, 51457, 51424, 51440, 51436,     0,     1, 49152, 
+    51200, 51456, 51457, 51424, 51440, 51436,     0,     1, 
+    49152, 51200, 51456, 51457, 51424, 51440, 51441, 51438, 
+        0,     1, 49152, 51200, 51456, 51457, 51424,     0, 
+        1, 49152, 51200, 51456, 51457, 51424, 51440,     0, 
+        1, 49152, 51200, 51456, 51457, 51459, 51440,     0, 
+        1, 49152, 51200, 51456, 51457, 51459, 51440, 51442, 
+        0,     1, 49152, 51200, 51456, 51457, 51459, 51440, 
+        0,     1, 49152, 51200, 51456, 51457, 51459, 51440, 
+    51444,     0,     1, 49152, 51200, 51456, 51457, 51459, 
+    51440, 51444,     0,     1, 49152, 51200, 51456, 51457, 
+    51459, 51440, 51448, 51446,     0,     1, 49152, 51200, 
+    51456, 51457, 51459, 51440,     0,     1, 49152, 51200, 
+    51456, 51457, 51459, 51440, 51448,     0,     1, 49152, 
+    51200, 51456, 51457, 51459, 51440, 51448,     0,     1, 
+    49152, 51200, 51456, 51457, 51459, 51440, 51448, 51450, 
+        0,     1, 49152, 51200, 51456, 51457, 51459, 51463, 
+    51448,     0,     1, 49152, 51200, 51456, 51457, 51459, 
+    51463, 51448, 51452,     0,     1, 49152, 51200, 51456, 
+    51457, 51459, 51463, 51448, 51452,     0,     1, 49152, 
+    51200, 51456, 51457, 51459, 51463, 51448, 51452, 51454, 
+        0,     1, 49152, 51200,     0,     1, 49152, 51200, 
+    51456,     0,     1, 49152, 51200, 51456,     0,     1, 
+    49152, 51200, 51456, 51458,     0,     1, 49152, 51200, 
+    51456,     0,     1, 49152, 51200, 51456, 51460,     0, 
+        1, 49152, 51200, 51456, 51460,     0,     1, 49152, 
+    51200, 51456, 51464, 51462,     0,     1, 49152, 51200, 
+    51456,     0,     1, 49152, 51200, 51456, 51464,     0, 
+        1, 49152, 51200, 51456, 51464,     0,     1, 49152, 
+    51200, 51456, 51464, 51466,     0,     1, 49152, 51200, 
+    51456, 51464,     0,     1, 49152, 51200, 51456, 51472, 
+    51468,     0,     1, 49152, 51200, 51456, 51472, 51468, 
+        0,     1, 49152, 51200, 51456, 51472, 51473, 51470, 
+        0,     1, 49152, 51200, 51456,     0,     1, 49152, 
+    51200, 51456, 51472,     0,     1, 49152, 51200, 51456, 
+    51472,     0,     1, 49152, 51200, 51456, 51472, 51474, 
+        0,     1, 49152, 51200, 51456, 51472,     0,     1, 
+    49152, 51200, 51456, 51472, 51476,     0,     1, 49152, 
+    51200, 51456, 51472, 51476,     0,     1, 49152, 51200, 
+    51456, 51472, 51480, 51478,     0,     1, 49152, 51200, 
+    51456, 51472,     0,     1, 49152, 51200, 51456, 51488, 
+    51480,     0,     1, 49152, 51200, 51456, 51488, 51480, 
+        0,     1, 49152, 51200, 51456, 51488, 51480, 51482, 
+        0,     1, 49152, 51200, 51456, 51488, 51480,     0, 
+        1, 49152, 51200, 51456, 51488, 51489, 51484,     0, 
+        1, 49152, 51200, 51456, 51488, 51489, 51484,     0, 
+        1, 49152, 51200, 51456, 51488, 51489, 51484, 51486, 
+        0,     1, 49152, 51200, 51456,     0,     1, 49152, 
+    51200, 51456, 51488,     0,     1, 49152, 51200, 51456, 
+    51488,     0,     1, 49152, 51200, 51456, 51488, 51490, 
+        0,     1, 49152, 51200, 51456, 51488,     0,     1, 
+    49152, 51200, 51456, 51488, 51492,     0,     1, 49152, 
+    51200, 51456, 51488, 51492,     0,     1, 49152, 51200, 
+    51456, 51488, 51496, 51494,     0,     1, 49152, 51200, 
+    51456, 51488,     0,     1, 49152, 51200, 51456, 51488, 
+    51496,     0,     1, 49152, 51200, 51456, 51488, 51496, 
+        0,     1, 49152, 51200, 51456, 51488, 51496, 51498, 
+        0,     1, 49152, 51200, 51456, 51488, 51496,     0, 
+        1, 49152, 51200, 51456, 51488, 51504, 51500,     0, 
+        1, 49152, 51200, 51456, 51488, 51504, 51500,     0, 
+        1, 49152, 51200, 51456, 51488, 51504, 51505, 51502, 
+        0,     1, 49152, 51200, 51456, 51488,     0,     1, 
+    49152, 51200, 51456, 51520, 51504,     0,     1, 49152, 
+    51200, 51456, 51520, 51504,     0,     1, 49152, 51200, 
+    51456, 51520, 51504, 51506,     0,     1, 49152, 51200, 
+    51456, 51520, 51504,     0,     1, 49152, 51200, 51456, 
+    51520, 51504, 51508,     0,     1, 49152, 51200, 51456, 
+    51520, 51504, 51508,     0,     1, 49152, 51200, 51456, 
+    51520, 51504, 51512, 51510,     0,     1, 49152, 51200, 
+    51456, 51520, 51504,     0,     1, 49152, 51200, 51456, 
+    51520, 51521, 51512,     0,     1, 49152, 51200, 51456, 
+    51520, 51521, 51512,     0,     1, 49152, 51200, 51456, 
+    51520, 51521, 51512, 51514,     0,     1, 49152, 51200, 
+    51456, 51520, 51521, 51512,     0,     1, 49152, 51200, 
+    51456, 51520, 51521, 51512, 51516,     0,     1, 49152, 
+    51200, 51456, 51520, 51521, 51523, 51516,     0,     1, 
+    49152, 51200, 51456, 51520, 51521, 51523, 51516, 51518, 
+        0,     1, 49152, 51200, 51456,     0,     1, 49152, 
+    51200, 51456, 51520,     0,     1, 49152, 51200, 51456, 
+    51520,     0,     1, 49152, 51200, 51456, 51520, 51522, 
+        0,     1, 49152, 51200, 51456, 51520,     0,     1, 
+    49152, 51200, 51456, 51520, 51524,     0,     1, 49152, 
+    51200, 51456, 51520, 51524,     0,     1, 49152, 51200, 
+    51456, 51520, 51528, 51526,     0,     1, 49152, 51200, 
+    51456, 51520,     0,     1, 49152, 51200, 51456, 51520, 
+    51528,     0,     1, 49152, 51200, 51456, 51520, 51528, 
+        0,     1, 49152, 51200, 51456, 51520, 51528, 51530, 
+        0,     1, 49152, 51200, 51456, 51520, 51528,     0, 
+        1, 49152, 51200, 51456, 51520, 51536, 51532,     0, 
+        1, 49152, 51200, 51456, 51520, 51536, 51532,     0, 
+        1, 49152, 51200, 51456, 51520, 51536, 51537, 51534, 
+        0,     1, 49152, 51200, 51456, 51520,     0,     1, 
+    49152, 51200, 51456, 51520, 51536,     0,     1, 49152, 
+    51200, 51456, 51520, 51536,     0,     1, 49152, 51200, 
+    51456, 51520, 51536, 51538,     0,     1, 49152, 51200, 
+    51456, 51520, 51536,     0,     1, 49152, 51200, 51456, 
+    51520, 51536, 51540,     0,     1, 49152, 51200, 51456, 
+    51520, 51536, 51540,     0,     1, 49152, 51200, 51456, 
+    51520, 51536, 51544, 51542,     0,     1, 49152, 51200, 
+    51456, 51520, 51536,     0,     1, 49152, 51200, 51456, 
+    51520, 51552, 51544,     0,     1, 49152, 51200, 51456, 
+    51520, 51552, 51544,     0,     1, 49152, 51200, 51456, 
+    51520, 51552, 51544, 51546,     0,     1, 49152, 51200, 
+    51456, 51520, 51552, 51544,     0,     1, 49152, 51200, 
+    51456, 51520, 51552, 51553, 51548,     0,     1, 49152, 
+    51200, 51456, 51520, 51552, 51553, 51548,     0,     1, 
+    49152, 51200, 51456, 51520, 51552, 51553, 51548, 51550, 
+        0,     1, 49152, 51200, 51456, 51520,     0,     1, 
+    49152, 51200, 51456, 51584, 51552,     0,     1, 49152, 
+    51200, 51456, 51584, 51552,     0,     1, 49152, 51200, 
+    51456, 51584, 51552, 51554,     0,     1, 49152, 51200, 
+    51456, 51584, 51552,     0,     1, 49152, 51200, 51456, 
+    51584, 51552, 51556,     0,     1, 49152, 51200, 51456, 
+    51584, 51552, 51556,     0,     1, 49152, 51200, 51456, 
+    51584, 51552, 51560, 51558,     0,     1, 49152, 51200, 
+    51456, 51584, 51552,     0,     1, 49152, 51200, 51456, 
+    51584, 51552, 51560,     0,     1, 49152, 51200, 51456, 
+    51584, 51552, 51560,     0,     1, 49152, 51200, 51456, 
+    51584, 51552, 51560, 51562,     0,     1, 49152, 51200, 
+    51456, 51584, 51552, 51560,     0,     1, 49152, 51200, 
+    51456, 51584, 51552, 51568, 51564,     0,     1, 49152, 
+    51200, 51456, 51584, 51552, 51568, 51564,     0,     1, 
+    49152, 51200, 51456, 51584, 51552, 51568, 51569, 51566, 
+        0,     1, 49152, 51200, 51456, 51584, 51552,     0, 
+        1, 49152, 51200, 51456, 51584, 51585, 51568,     0, 
+        1, 49152, 51200, 51456, 51584, 51585, 51568,     0, 
+        1, 49152, 51200, 51456, 51584, 51585, 51568, 51570, 
+        0,     1, 49152, 51200, 51456, 51584, 51585, 51568, 
+        0,     1, 49152, 51200, 51456, 51584, 51585, 51568, 
+    51572,     0,     1, 49152, 51200, 51456, 51584, 51585, 
+    51568, 51572,     0,     1, 49152, 51200, 51456, 51584, 
+    51585, 51568, 51576, 51574,     0,     1, 49152, 51200, 
+    51456, 51584, 51585, 51568,     0,     1, 49152, 51200, 
+    51456, 51584, 51585, 51568, 51576,     0,     1, 49152, 
+    51200, 51456, 51584, 51585, 51587, 51576,     0,     1, 
+    49152, 51200, 51456, 51584, 51585, 51587, 51576, 51578, 
+        0,     1, 49152, 51200, 51456, 51584, 51585, 51587, 
+    51576,     0,     1, 49152, 51200, 51456, 51584, 51585, 
+    51587, 51576, 51580,     0,     1, 49152, 51200, 51456, 
+    51584, 51585, 51587, 51576, 51580,     0,     1, 49152, 
+    51200, 51456, 51584, 51585, 51587, 51576, 51580, 51582, 
+        0,     1, 49152, 51200, 51456,     0,     1, 49152, 
+    51200, 51712, 51584,     0,     1, 49152, 51200, 51712, 
+    51584,     0,     1, 49152, 51200, 51712, 51584, 51586, 
+        0,     1, 49152, 51200, 51712, 51584,     0,     1, 
+    49152, 51200, 51712, 51584, 51588,     0,     1, 49152, 
+    51200, 51712, 51584, 51588,     0,     1, 49152, 51200, 
+    51712, 51584, 51592, 51590,     0,     1, 49152, 51200, 
+    51712, 51584,     0,     1, 49152, 51200, 51712, 51584, 
+    51592,     0,     1, 49152, 51200, 51712, 51584, 51592, 
+        0,     1, 49152, 51200, 51712, 51584, 51592, 51594, 
+        0,     1, 49152, 51200, 51712, 51584, 51592,     0, 
+        1, 49152, 51200, 51712, 51584, 51600, 51596,     0, 
+        1, 49152, 51200, 51712, 51584, 51600, 51596,     0, 
+        1, 49152, 51200, 51712, 51584, 51600, 51601, 51598, 
+        0,     1, 49152, 51200, 51712, 51584,     0,     1, 
+    49152, 51200, 51712, 51584, 51600,     0,     1, 49152, 
+    51200, 51712, 51584, 51600,     0,     1, 49152, 51200, 
+    51712, 51584, 51600, 51602,     0,     1, 49152, 51200, 
+    51712, 51584, 51600,     0,     1, 49152, 51200, 51712, 
+    51584, 51600, 51604,     0,     1, 49152, 51200, 51712, 
+    51584, 51600, 51604,     0,     1, 49152, 51200, 51712, 
+    51584, 51600, 51608, 51606,     0,     1, 49152, 51200, 
+    51712, 51584, 51600,     0,     1, 49152, 51200, 51712, 
+    51584, 51616, 51608,     0,     1, 49152, 51200, 51712, 
+    51584, 51616, 51608,     0,     1, 49152, 51200, 51712, 
+    51584, 51616, 51608, 51610,     0,     1, 49152, 51200, 
+    51712, 51584, 51616, 51608,     0,     1, 49152, 51200, 
+    51712, 51584, 51616, 51617, 51612,     0,     1, 49152, 
+    51200, 51712, 51584, 51616, 51617, 51612,     0,     1, 
+    49152, 51200, 51712, 51584, 51616, 51617, 51612, 51614, 
+        0,     1, 49152, 51200, 51712, 51584,     0,     1, 
+    49152, 51200, 51712, 51584, 51616,     0,     1, 49152, 
+    51200, 51712, 51584, 51616,     0,     1, 49152, 51200, 
+    51712, 51584, 51616, 51618,     0,     1, 49152, 51200, 
+    51712, 51584, 51616,     0,     1, 49152, 51200, 51712, 
+    51584, 51616, 51620,     0,     1, 49152, 51200, 51712, 
+    51584, 51616, 51620,     0,     1, 49152, 51200, 51712, 
+    51584, 51616, 51624, 51622,     0,     1, 49152, 51200, 
+    51712, 51584, 51616,     0,     1, 49152, 51200, 51712, 
+    51584, 51616, 51624,     0,     1, 49152, 51200, 51712, 
+    51584, 51616, 51624,     0,     1, 49152, 51200, 51712, 
+    51584, 51616, 51624, 51626,     0,     1, 49152, 51200, 
+    51712, 51584, 51616, 51624,     0,     1, 49152, 51200, 
+    51712, 51584, 51616, 51632, 51628,     0,     1, 49152, 
+    51200, 51712, 51584, 51616, 51632, 51628,     0,     1, 
+    49152, 51200, 51712, 51584, 51616, 51632, 51633, 51630, 
+        0,     1, 49152, 51200, 51712, 51584, 51616,     0, 
+        1, 49152, 51200, 51712, 51584, 51648, 51632,     0, 
+        1, 49152, 51200, 51712, 51584, 51648, 51632,     0, 
+        1, 49152, 51200, 51712, 51584, 51648, 51632, 51634, 
+        0,     1, 49152, 51200, 51712, 51584, 51648, 51632, 
+        0,     1, 49152, 51200, 51712, 51584, 51648, 51632, 
+    51636,     0,     1, 49152, 51200, 51712, 51584, 51648, 
+    51632, 51636,     0,     1, 49152, 51200, 51712, 51584, 
+    51648, 51632, 51640, 51638,     0,     1, 49152, 51200, 
+    51712, 51584, 51648, 51632,     0,     1, 49152, 51200, 
+    51712, 51584, 51648, 51649, 51640,     0,     1, 49152, 
+    51200, 51712, 51584, 51648, 51649, 51640,     0,     1, 
+    49152, 51200, 51712, 51584, 51648, 51649, 51640, 51642, 
+        0,     1, 49152, 51200, 51712, 51584, 51648, 51649, 
+    51640,     0,     1, 49152, 51200, 51712, 51584, 51648, 
+    51649, 51640, 51644,     0,     1, 49152, 51200, 51712, 
+    51584, 51648, 51649, 51651, 51644,     0,     1, 49152, 
+    51200, 51712, 51584, 51648, 51649, 51651, 51644, 51646, 
+        0,     1, 49152, 51200, 51712, 51584,     0,     1, 
+    49152, 51200, 51712, 51713, 51648,     0,     1, 49152, 
+    51200, 51712, 51713, 51648,     0,     1, 49152, 51200, 
+    51712, 51713, 51648, 51650,     0,     1, 49152, 51200, 
+    51712, 51713, 51648,     0,     1, 49152, 51200, 51712, 
+    51713, 51648, 51652,     0,     1, 49152, 51200, 51712, 
+    51713, 51648, 51652,     0,     1, 49152, 51200, 51712, 
+    51713, 51648, 51656, 51654,     0,     1, 49152, 51200, 
+    51712, 51713, 51648,     0,     1, 49152, 51200, 51712, 
+    51713, 51648, 51656,     0,     1, 49152, 51200, 51712, 
+    51713, 51648, 51656,     0,     1, 49152, 51200, 51712, 
+    51713, 51648, 51656, 51658,     0,     1, 49152, 51200, 
+    51712, 51713, 51648, 51656,     0,     1, 49152, 51200, 
+    51712, 51713, 51648, 51664, 51660,     0,     1, 49152, 
+    51200, 51712, 51713, 51648, 51664, 51660,     0,     1, 
+    49152, 51200, 51712, 51713, 51648, 51664, 51665, 51662, 
+        0,     1, 49152, 51200, 51712, 51713, 51648,     0, 
+        1, 49152, 51200, 51712, 51713, 51648, 51664,     0, 
+        1, 49152, 51200, 51712, 51713, 51648, 51664,     0, 
+        1, 49152, 51200, 51712, 51713, 51648, 51664, 51666, 
+        0,     1, 49152, 51200, 51712, 51713, 51648, 51664, 
+        0,     1, 49152, 51200, 51712, 51713, 51648, 51664, 
+    51668,     0,     1, 49152, 51200, 51712, 51713, 51648, 
+    51664, 51668,     0,     1, 49152, 51200, 51712, 51713, 
+    51648, 51664, 51672, 51670,     0,     1, 49152, 51200, 
+    51712, 51713, 51648, 51664,     0,     1, 49152, 51200, 
+    51712, 51713, 51648, 51680, 51672,     0,     1, 49152, 
+    51200, 51712, 51713, 51648, 51680, 51672,     0,     1, 
+    49152, 51200, 51712, 51713, 51648, 51680, 51672, 51674, 
+        0,     1, 49152, 51200, 51712, 51713, 51648, 51680, 
+    51672,     0,     1, 49152, 51200, 51712, 51713, 51648, 
+    51680, 51681, 51676,     0,     1, 49152, 51200, 51712, 
+    51713, 51648, 51680, 51681, 51676,     0,     1, 49152, 
+    51200, 51712, 51713, 51648, 51680, 51681, 51676, 51678, 
+        0,     1, 49152, 51200, 51712, 51713, 51648,     0, 
+        1, 49152, 51200, 51712, 51713, 51648, 51680,     0, 
+        1, 49152, 51200, 51712, 51713, 51715, 51680,     0, 
+        1, 49152, 51200, 51712, 51713, 51715, 51680, 51682, 
+        0,     1, 49152, 51200, 51712, 51713, 51715, 51680, 
+        0,     1, 49152, 51200, 51712, 51713, 51715, 51680, 
+    51684,     0,     1, 49152, 51200, 51712, 51713, 51715, 
+    51680, 51684,     0,     1, 49152, 51200, 51712, 51713, 
+    51715, 51680, 51688, 51686,     0,     1, 49152, 51200, 
+    51712, 51713, 51715, 51680,     0,     1, 49152, 51200, 
+    51712, 51713, 51715, 51680, 51688,     0,     1, 49152, 
+    51200, 51712, 51713, 51715, 51680, 51688,     0,     1, 
+    49152, 51200, 51712, 51713, 51715, 51680, 51688, 51690, 
+        0,     1, 49152, 51200, 51712, 51713, 51715, 51680, 
+    51688,     0,     1, 49152, 51200, 51712, 51713, 51715, 
+    51680, 51696, 51692,     0,     1, 49152, 51200, 51712, 
+    51713, 51715, 51680, 51696, 51692,     0,     1, 49152, 
+    51200, 51712, 51713, 51715, 51680, 51696, 51697, 51694, 
+        0,     1, 49152, 51200, 51712, 51713, 51715, 51680, 
+        0,     1, 49152, 51200, 51712, 51713, 51715, 51680, 
+    51696,     0,     1, 49152, 51200, 51712, 51713, 51715, 
+    51680, 51696,     0,     1, 49152, 51200, 51712, 51713, 
+    51715, 51680, 51696, 51698,     0,     1, 49152, 51200, 
+    51712, 51713, 51715, 51719, 51696,     0,     1, 49152, 
+    51200, 51712, 51713, 51715, 51719, 51696, 51700,     0, 
+        1, 49152, 51200, 51712, 51713, 51715, 51719, 51696, 
+    51700,     0,     1, 49152, 51200, 51712, 51713, 51715, 
+    51719, 51696, 51704, 51702,     0,     1, 49152, 51200, 
+    51712, 51713, 51715, 51719, 51696,     0,     1, 49152, 
+    51200, 51712, 51713, 51715, 51719, 51696, 51704,     0, 
+        1, 49152, 51200, 51712, 51713, 51715, 51719, 51696, 
+    51704,     0,     1, 49152, 51200, 51712, 51713, 51715, 
+    51719, 51696, 51704, 51706,     0,     1, 49152, 51200, 
+    51712, 51713, 51715, 51719, 51696, 51704,     0,     1, 
+    49152, 51200, 51712, 51713, 51715, 51719, 51696, 51704, 
+    51708,     0,     1, 49152, 51200, 51712, 51713, 51715, 
+    51719, 51696, 51704, 51708,     0,     1, 49152, 51200, 
+    51712, 51713, 51715, 51719, 51696, 51704, 51708, 51710, 
+        0,     1, 49152, 51200,     0,     1, 49152, 51200, 
+    51712,     0,     1, 49152, 51200, 51712,     0,     1, 
+    49152, 51200, 51712, 51714,     0,     1, 49152, 51200, 
+    51712,     0,     1, 49152, 51200, 51712, 51716,     0, 
+        1, 49152, 51200, 51712, 51716,     0,     1, 49152, 
+    51200, 51712, 51720, 51718,     0,     1, 49152, 51200, 
+    51712,     0,     1, 49152, 51200, 51712, 51720,     0, 
+        1, 49152, 51200, 51712, 51720,     0,     1, 49152, 
+    51200, 51712, 51720, 51722,     0,     1, 49152, 51200, 
+    51712, 51720,     0,     1, 49152, 51200, 51712, 51728, 
+    51724,     0,     1, 49152, 51200, 51712, 51728, 51724, 
+        0,     1, 49152, 51200, 51712, 51728, 51729, 51726, 
+        0,     1, 49152, 51200, 51712,     0,     1, 49152, 
+    51200, 51712, 51728,     0,     1, 49152, 51200, 51712, 
+    51728,     0,     1, 49152, 51200, 51712, 51728, 51730, 
+        0,     1, 49152, 51200, 51712, 51728,     0,     1, 
+    49152, 51200, 51712, 51728, 51732,     0,     1, 49152, 
+    51200, 51712, 51728, 51732,     0,     1, 49152, 51200, 
+    51712, 51728, 51736, 51734,     0,     1, 49152, 51200, 
+    51712, 51728,     0,     1, 49152, 51200, 51712, 51744, 
+    51736,     0,     1, 49152, 51200, 51712, 51744, 51736, 
+        0,     1, 49152, 51200, 51712, 51744, 51736, 51738, 
+        0,     1, 49152, 51200, 51712, 51744, 51736,     0, 
+        1, 49152, 51200, 51712, 51744, 51745, 51740,     0, 
+        1, 49152, 51200, 51712, 51744, 51745, 51740,     0, 
+        1, 49152, 51200, 51712, 51744, 51745, 51740, 51742, 
+        0,     1, 49152, 51200, 51712,     0,     1, 49152, 
+    51200, 51712, 51744,     0,     1, 49152, 51200, 51712, 
+    51744,     0,     1, 49152, 51200, 51712, 51744, 51746, 
+        0,     1, 49152, 51200, 51712, 51744,     0,     1, 
+    49152, 51200, 51712, 51744, 51748,     0,     1, 49152, 
+    51200, 51712, 51744, 51748,     0,     1, 49152, 51200, 
+    51712, 51744, 51752, 51750,     0,     1, 49152, 51200, 
+    51712, 51744,     0,     1, 49152, 51200, 51712, 51744, 
+    51752,     0,     1, 49152, 51200, 51712, 51744, 51752, 
+        0,     1, 49152, 51200, 51712, 51744, 51752, 51754, 
+        0,     1, 49152, 51200, 51712, 51744, 51752,     0, 
+        1, 49152, 51200, 51712, 51744, 51760, 51756,     0, 
+        1, 49152, 51200, 51712, 51744, 51760, 51756,     0, 
+        1, 49152, 51200, 51712, 51744, 51760, 51761, 51758, 
+        0,     1, 49152, 51200, 51712, 51744,     0,     1, 
+    49152, 51200, 51712, 51776, 51760,     0,     1, 49152, 
+    51200, 51712, 51776, 51760,     0,     1, 49152, 51200, 
+    51712, 51776, 51760, 51762,     0,     1, 49152, 51200, 
+    51712, 51776, 51760,     0,     1, 49152, 51200, 51712, 
+    51776, 51760, 51764,     0,     1, 49152, 51200, 51712, 
+    51776, 51760, 51764,     0,     1, 49152, 51200, 51712, 
+    51776, 51760, 51768, 51766,     0,     1, 49152, 51200, 
+    51712, 51776, 51760,     0,     1, 49152, 51200, 51712, 
+    51776, 51777, 51768,     0,     1, 49152, 51200, 51712, 
+    51776, 51777, 51768,     0,     1, 49152, 51200, 51712, 
+    51776, 51777, 51768, 51770,     0,     1, 49152, 51200, 
+    51712, 51776, 51777, 51768,     0,     1, 49152, 51200, 
+    51712, 51776, 51777, 51768, 51772,     0,     1, 49152, 
+    51200, 51712, 51776, 51777, 51779, 51772,     0,     1, 
+    49152, 51200, 51712, 51776, 51777, 51779, 51772, 51774, 
+        0,     1, 49152, 51200, 51712,     0,     1, 49152, 
+    51200, 51712, 51776,     0,     1, 49152, 51200, 51712, 
+    51776,     0,     1, 49152, 51200, 51712, 51776, 51778, 
+        0,     1, 49152, 51200, 51712, 51776,     0,     1, 
+    49152, 51200, 51712, 51776, 51780,     0,     1, 49152, 
+    51200, 51712, 51776, 51780,     0,     1, 49152, 51200, 
+    51712, 51776, 51784, 51782,     0,     1, 49152, 51200, 
+    51712, 51776,     0,     1, 49152, 51200, 51712, 51776, 
+    51784,     0,     1, 49152, 51200, 51712, 51776, 51784, 
+        0,     1, 49152, 51200, 51712, 51776, 51784, 51786, 
+        0,     1, 49152, 51200, 51712, 51776, 51784,     0, 
+        1, 49152, 51200, 51712, 51776, 51792, 51788,     0, 
+        1, 49152, 51200, 51712, 51776, 51792, 51788,     0, 
+        1, 49152, 51200, 51712, 51776, 51792, 51793, 51790, 
+        0,     1, 49152, 51200, 51712, 51776,     0,     1, 
+    49152, 51200, 51712, 51776, 51792,     0,     1, 49152, 
+    51200, 51712, 51776, 51792,     0,     1, 49152, 51200, 
+    51712, 51776, 51792, 51794,     0,     1, 49152, 51200, 
+    51712, 51776, 51792,     0,     1, 49152, 51200, 51712, 
+    51776, 51792, 51796,     0,     1, 49152, 51200, 51712, 
+    51776, 51792, 51796,     0,     1, 49152, 51200, 51712, 
+    51776, 51792, 51800, 51798,     0,     1, 49152, 51200, 
+    51712, 51776, 51792,     0,     1, 49152, 51200, 51712, 
+    51776, 51808, 51800,     0,     1, 49152, 51200, 51712, 
+    51776, 51808, 51800,     0,     1, 49152, 51200, 51712, 
+    51776, 51808, 51800, 51802,     0,     1, 49152, 51200, 
+    51712, 51776, 51808, 51800,     0,     1, 49152, 51200, 
+    51712, 51776, 51808, 51809, 51804,     0,     1, 49152, 
+    51200, 51712, 51776, 51808, 51809, 51804,     0,     1, 
+    49152, 51200, 51712, 51776, 51808, 51809, 51804, 51806, 
+        0,     1, 49152, 51200, 51712, 51776,     0,     1, 
+    49152, 51200, 51712, 51840, 51808,     0,     1, 49152, 
+    51200, 51712, 51840, 51808,     0,     1, 49152, 51200, 
+    51712, 51840, 51808, 51810,     0,     1, 49152, 51200, 
+    51712, 51840, 51808,     0,     1, 49152, 51200, 51712, 
+    51840, 51808, 51812,     0,     1, 49152, 51200, 51712, 
+    51840, 51808, 51812,     0,     1, 49152, 51200, 51712, 
+    51840, 51808, 51816, 51814,     0,     1, 49152, 51200, 
+    51712, 51840, 51808,     0,     1, 49152, 51200, 51712, 
+    51840, 51808, 51816,     0,     1, 49152, 51200, 51712, 
+    51840, 51808, 51816,     0,     1, 49152, 51200, 51712, 
+    51840, 51808, 51816, 51818,     0,     1, 49152, 51200, 
+    51712, 51840, 51808, 51816,     0,     1, 49152, 51200, 
+    51712, 51840, 51808, 51824, 51820,     0,     1, 49152, 
+    51200, 51712, 51840, 51808, 51824, 51820,     0,     1, 
+    49152, 51200, 51712, 51840, 51808, 51824, 51825, 51822, 
+        0,     1, 49152, 51200, 51712, 51840, 51808,     0, 
+        1, 49152, 51200, 51712, 51840, 51841, 51824,     0, 
+        1, 49152, 51200, 51712, 51840, 51841, 51824,     0, 
+        1, 49152, 51200, 51712, 51840, 51841, 51824, 51826, 
+        0,     1, 49152, 51200, 51712, 51840, 51841, 51824, 
+        0,     1, 49152, 51200, 51712, 51840, 51841, 51824, 
+    51828,     0,     1, 49152, 51200, 51712, 51840, 51841, 
+    51824, 51828,     0,     1, 49152, 51200, 51712, 51840, 
+    51841, 51824, 51832, 51830,     0,     1, 49152, 51200, 
+    51712, 51840, 51841, 51824,     0,     1, 49152, 51200, 
+    51712, 51840, 51841, 51824, 51832,     0,     1, 49152, 
+    51200, 51712, 51840, 51841, 51843, 51832,     0,     1, 
+    49152, 51200, 51712, 51840, 51841, 51843, 51832, 51834, 
+        0,     1, 49152, 51200, 51712, 51840, 51841, 51843, 
+    51832,     0,     1, 49152, 51200, 51712, 51840, 51841, 
+    51843, 51832, 51836,     0,     1, 49152, 51200, 51712, 
+    51840, 51841, 51843, 51832, 51836,     0,     1, 49152, 
+    51200, 51712, 51840, 51841, 51843, 51832, 51836, 51838, 
+        0,     1, 49152, 51200, 51712,     0,     1, 49152, 
+    51200, 51712, 51840,     0,     1, 49152, 51200, 51712, 
+    51840,     0,     1, 49152, 51200, 51712, 51840, 51842, 
+        0,     1, 49152, 51200, 51712, 51840,     0,     1, 
+    49152, 51200, 51712, 51840, 51844,     0,     1, 49152, 
+    51200, 51712, 51840, 51844,     0,     1, 49152, 51200, 
+    51712, 51840, 51848, 51846,     0,     1, 49152, 51200, 
+    51712, 51840,     0,     1, 49152, 51200, 51712, 51840, 
+    51848,     0,     1, 49152, 51200, 51712, 51840, 51848, 
+        0,     1, 49152, 51200, 51712, 51840, 51848, 51850, 
+        0,     1, 49152, 51200, 51712, 51840, 51848,     0, 
+        1, 49152, 51200, 51712, 51840, 51856, 51852,     0, 
+        1, 49152, 51200, 51712, 51840, 51856, 51852,     0, 
+        1, 49152, 51200, 51712, 51840, 51856, 51857, 51854, 
+        0,     1, 49152, 51200, 51712, 51840,     0,     1, 
+    49152, 51200, 51712, 51840, 51856,     0,     1, 49152, 
+    51200, 51712, 51840, 51856,     0,     1, 49152, 51200, 
+    51712, 51840, 51856, 51858,     0,     1, 49152, 51200, 
+    51712, 51840, 51856,     0,     1, 49152, 51200, 51712, 
+    51840, 51856, 51860,     0,     1, 49152, 51200, 51712, 
+    51840, 51856, 51860,     0,     1, 49152, 51200, 51712, 
+    51840, 51856, 51864, 51862,     0,     1, 49152, 51200, 
+    51712, 51840, 51856,     0,     1, 49152, 51200, 51712, 
+    51840, 51872, 51864,     0,     1, 49152, 51200, 51712, 
+    51840, 51872, 51864,     0,     1, 49152, 51200, 51712, 
+    51840, 51872, 51864, 51866,     0,     1, 49152, 51200, 
+    51712, 51840, 51872, 51864,     0,     1, 49152, 51200, 
+    51712, 51840, 51872, 51873, 51868,     0,     1, 49152, 
+    51200, 51712, 51840, 51872, 51873, 51868,     0,     1, 
+    49152, 51200, 51712, 51840, 51872, 51873, 51868, 51870, 
+        0,     1, 49152, 51200, 51712, 51840,     0,     1, 
+    49152, 51200, 51712, 51840, 51872,     0,     1, 49152, 
+    51200, 51712, 51840, 51872,     0,     1, 49152, 51200, 
+    51712, 51840, 51872, 51874,     0,     1, 49152, 51200, 
+    51712, 51840, 51872,     0,     1, 49152, 51200, 51712, 
+    51840, 51872, 51876,     0,     1, 49152, 51200, 51712, 
+    51840, 51872, 51876,     0,     1, 49152, 51200, 51712, 
+    51840, 51872, 51880, 51878,     0,     1, 49152, 51200, 
+    51712, 51840, 51872,     0,     1, 49152, 51200, 51712, 
+    51840, 51872, 51880,     0,     1, 49152, 51200, 51712, 
+    51840, 51872, 51880,     0,     1, 49152, 51200, 51712, 
+    51840, 51872, 51880, 51882,     0,     1, 49152, 51200, 
+    51712, 51840, 51872, 51880,     0,     1, 49152, 51200, 
+    51712, 51840, 51872, 51888, 51884,     0,     1, 49152, 
+    51200, 51712, 51840, 51872, 51888, 51884,     0,     1, 
+    49152, 51200, 51712, 51840, 51872, 51888, 51889, 51886, 
+        0,     1, 49152, 51200, 51712, 51840, 51872,     0, 
+        1, 49152, 51200, 51712, 51840, 51904, 51888,     0, 
+        1, 49152, 51200, 51712, 51840, 51904, 51888,     0, 
+        1, 49152, 51200, 51712, 51840, 51904, 51888, 51890, 
+        0,     1, 49152, 51200, 51712, 51840, 51904, 51888, 
+        0,     1, 49152, 51200, 51712, 51840, 51904, 51888, 
+    51892,     0,     1, 49152, 51200, 51712, 51840, 51904, 
+    51888, 51892,     0,     1, 49152, 51200, 51712, 51840, 
+    51904, 51888, 51896, 51894,     0,     1, 49152, 51200, 
+    51712, 51840, 51904, 51888,     0,     1, 49152, 51200, 
+    51712, 51840, 51904, 51905, 51896,     0,     1, 49152, 
+    51200, 51712, 51840, 51904, 51905, 51896,     0,     1, 
+    49152, 51200, 51712, 51840, 51904, 51905, 51896, 51898, 
+        0,     1, 49152, 51200, 51712, 51840, 51904, 51905, 
+    51896,     0,     1, 49152, 51200, 51712, 51840, 51904, 
+    51905, 51896, 51900,     0,     1, 49152, 51200, 51712, 
+    51840, 51904, 51905, 51907, 51900,     0,     1, 49152, 
+    51200, 51712, 51840, 51904, 51905, 51907, 51900, 51902, 
+        0,     1, 49152, 51200, 51712, 51840,     0,     1, 
+    49152, 51200, 51712, 51968, 51904,     0,     1, 49152, 
+    51200, 51712, 51968, 51904,     0,     1, 49152, 51200, 
+    51712, 51968, 51904, 51906,     0,     1, 49152, 51200, 
+    51712, 51968, 51904,     0,     1, 49152, 51200, 51712, 
+    51968, 51904, 51908,     0,     1, 49152, 51200, 51712, 
+    51968, 51904, 51908,     0,     1, 49152, 51200, 51712, 
+    51968, 51904, 51912, 51910,     0,     1, 49152, 51200, 
+    51712, 51968, 51904,     0,     1, 49152, 51200, 51712, 
+    51968, 51904, 51912,     0,     1, 49152, 51200, 51712, 
+    51968, 51904, 51912,     0,     1, 49152, 51200, 51712, 
+    51968, 51904, 51912, 51914,     0,     1, 49152, 51200, 
+    51712, 51968, 51904, 51912,     0,     1, 49152, 51200, 
+    51712, 51968, 51904, 51920, 51916,     0,     1, 49152, 
+    51200, 51712, 51968, 51904, 51920, 51916,     0,     1, 
+    49152, 51200, 51712, 51968, 51904, 51920, 51921, 51918, 
+        0,     1, 49152, 51200, 51712, 51968, 51904,     0, 
+        1, 49152, 51200, 51712, 51968, 51904, 51920,     0, 
+        1, 49152, 51200, 51712, 51968, 51904, 51920,     0, 
+        1, 49152, 51200, 51712, 51968, 51904, 51920, 51922, 
+        0,     1, 49152, 51200, 51712, 51968, 51904, 51920, 
+        0,     1, 49152, 51200, 51712, 51968, 51904, 51920, 
+    51924,     0,     1, 49152, 51200, 51712, 51968, 51904, 
+    51920, 51924,     0,     1, 49152, 51200, 51712, 51968, 
+    51904, 51920, 51928, 51926,     0,     1, 49152, 51200, 
+    51712, 51968, 51904, 51920,     0,     1, 49152, 51200, 
+    51712, 51968, 51904, 51936, 51928,     0,     1, 49152, 
+    51200, 51712, 51968, 51904, 51936, 51928,     0,     1, 
+    49152, 51200, 51712, 51968, 51904, 51936, 51928, 51930, 
+        0,     1, 49152, 51200, 51712, 51968, 51904, 51936, 
+    51928,     0,     1, 49152, 51200, 51712, 51968, 51904, 
+    51936, 51937, 51932,     0,     1, 49152, 51200, 51712, 
+    51968, 51904, 51936, 51937, 51932,     0,     1, 49152, 
+    51200, 51712, 51968, 51904, 51936, 51937, 51932, 51934, 
+        0,     1, 49152, 51200, 51712, 51968, 51904,     0, 
+        1, 49152, 51200, 51712, 51968, 51969, 51936,     0, 
+        1, 49152, 51200, 51712, 51968, 51969, 51936,     0, 
+        1, 49152, 51200, 51712, 51968, 51969, 51936, 51938, 
+        0,     1, 49152, 51200, 51712, 51968, 51969, 51936, 
+        0,     1, 49152, 51200, 51712, 51968, 51969, 51936, 
+    51940,     0,     1, 49152, 51200, 51712, 51968, 51969, 
+    51936, 51940,     0,     1, 49152, 51200, 51712, 51968, 
+    51969, 51936, 51944, 51942,     0,     1, 49152, 51200, 
+    51712, 51968, 51969, 51936,     0,     1, 49152, 51200, 
+    51712, 51968, 51969, 51936, 51944,     0,     1, 49152, 
+    51200, 51712, 51968, 51969, 51936, 51944,     0,     1, 
+    49152, 51200, 51712, 51968, 51969, 51936, 51944, 51946, 
+        0,     1, 49152, 51200, 51712, 51968, 51969, 51936, 
+    51944,     0,     1, 49152, 51200, 51712, 51968, 51969, 
+    51936, 51952, 51948,     0,     1, 49152, 51200, 51712, 
+    51968, 51969, 51936, 51952, 51948,     0,     1, 49152, 
+    51200, 51712, 51968, 51969, 51936, 51952, 51953, 51950, 
+        0,     1, 49152, 51200, 51712, 51968, 51969, 51936, 
+        0,     1, 49152, 51200, 51712, 51968, 51969, 51936, 
+    51952,     0,     1, 49152, 51200, 51712, 51968, 51969, 
+    51971, 51952,     0,     1, 49152, 51200, 51712, 51968, 
+    51969, 51971, 51952, 51954,     0,     1, 49152, 51200, 
+    51712, 51968, 51969, 51971, 51952,     0,     1, 49152, 
+    51200, 51712, 51968, 51969, 51971, 51952, 51956,     0, 
+        1, 49152, 51200, 51712, 51968, 51969, 51971, 51952, 
+    51956,     0,     1, 49152, 51200, 51712, 51968, 51969, 
+    51971, 51952, 51960, 51958,     0,     1, 49152, 51200, 
+    51712, 51968, 51969, 51971, 51952,     0,     1, 49152, 
+    51200, 51712, 51968, 51969, 51971, 51952, 51960,     0, 
+        1, 49152, 51200, 51712, 51968, 51969, 51971, 51952, 
+    51960,     0,     1, 49152, 51200, 51712, 51968, 51969, 
+    51971, 51952, 51960, 51962,     0,     1, 49152, 51200, 
+    51712, 51968, 51969, 51971, 51975, 51960,     0,     1, 
+    49152, 51200, 51712, 51968, 51969, 51971, 51975, 51960, 
+    51964,     0,     1, 49152, 51200, 51712, 51968, 51969, 
+    51971, 51975, 51960, 51964,     0,     1, 49152, 51200, 
+    51712, 51968, 51969, 51971, 51975, 51960, 51964, 51966, 
+        0,     1, 49152, 51200, 51712,     0,     1, 49152, 
+    51200, 52224, 51968,     0,     1, 49152, 51200, 52224, 
+    51968,     0,     1, 49152, 51200, 52224, 51968, 51970, 
+        0,     1, 49152, 51200, 52224, 51968,     0,     1, 
+    49152, 51200, 52224, 51968, 51972,     0,     1, 49152, 
+    51200, 52224, 51968, 51972,     0,     1, 49152, 51200, 
+    52224, 51968, 51976, 51974,     0,     1, 49152, 51200, 
+    52224, 51968,     0,     1, 49152, 51200, 52224, 51968, 
+    51976,     0,     1, 49152, 51200, 52224, 51968, 51976, 
+        0,     1, 49152, 51200, 52224, 51968, 51976, 51978, 
+        0,     1, 49152, 51200, 52224, 51968, 51976,     0, 
+        1, 49152, 51200, 52224, 51968, 51984, 51980,     0, 
+        1, 49152, 51200, 52224, 51968, 51984, 51980,     0, 
+        1, 49152, 51200, 52224, 51968, 51984, 51985, 51982, 
+        0,     1, 49152, 51200, 52224, 51968,     0,     1, 
+    49152, 51200, 52224, 51968, 51984,     0,     1, 49152, 
+    51200, 52224, 51968, 51984,     0,     1, 49152, 51200, 
+    52224, 51968, 51984, 51986,     0,     1, 49152, 51200, 
+    52224, 51968, 51984,     0,     1, 49152, 51200, 52224, 
+    51968, 51984, 51988,     0,     1, 49152, 51200, 52224, 
+    51968, 51984, 51988,     0,     1, 49152, 51200, 52224, 
+    51968, 51984, 51992, 51990,     0,     1, 49152, 51200, 
+    52224, 51968, 51984,     0,     1, 49152, 51200, 52224, 
+    51968, 52000, 51992,     0,     1, 49152, 51200, 52224, 
+    51968, 52000, 51992,     0,     1, 49152, 51200, 52224, 
+    51968, 52000, 51992, 51994,     0,     1, 49152, 51200, 
+    52224, 51968, 52000, 51992,     0,     1, 49152, 51200, 
+    52224, 51968, 52000, 52001, 51996,     0,     1, 49152, 
+    51200, 52224, 51968, 52000, 52001, 51996,     0,     1, 
+    49152, 51200, 52224, 51968, 52000, 52001, 51996, 51998, 
+        0,     1, 49152, 51200, 52224, 51968,     0,     1, 
+    49152, 51200, 52224, 51968, 52000,     0,     1, 49152, 
+    51200, 52224, 51968, 52000,     0,     1, 49152, 51200, 
+    52224, 51968, 52000, 52002,     0,     1, 49152, 51200, 
+    52224, 51968, 52000,     0,     1, 49152, 51200, 52224, 
+    51968, 52000, 52004,     0,     1, 49152, 51200, 52224, 
+    51968, 52000, 52004,     0,     1, 49152, 51200, 52224, 
+    51968, 52000, 52008, 52006,     0,     1, 49152, 51200, 
+    52224, 51968, 52000,     0,     1, 49152, 51200, 52224, 
+    51968, 52000, 52008,     0,     1, 49152, 51200, 52224, 
+    51968, 52000, 52008,     0,     1, 49152, 51200, 52224, 
+    51968, 52000, 52008, 52010,     0,     1, 49152, 51200, 
+    52224, 51968, 52000, 52008,     0,     1, 49152, 51200, 
+    52224, 51968, 52000, 52016, 52012,     0,     1, 49152, 
+    51200, 52224, 51968, 52000, 52016, 52012,     0,     1, 
+    49152, 51200, 52224, 51968, 52000, 52016, 52017, 52014, 
+        0,     1, 49152, 51200, 52224, 51968, 52000,     0, 
+        1, 49152, 51200, 52224, 51968, 52032, 52016,     0, 
+        1, 49152, 51200, 52224, 51968, 52032, 52016,     0, 
+        1, 49152, 51200, 52224, 51968, 52032, 52016, 52018, 
+        0,     1, 49152, 51200, 52224, 51968, 52032, 52016, 
+        0,     1, 49152, 51200, 52224, 51968, 52032, 52016, 
+    52020,     0,     1, 49152, 51200, 52224, 51968, 52032, 
+    52016, 52020,     0,     1, 49152, 51200, 52224, 51968, 
+    52032, 52016, 52024, 52022,     0,     1, 49152, 51200, 
+    52224, 51968, 52032, 52016,     0,     1, 49152, 51200, 
+    52224, 51968, 52032, 52033, 52024,     0,     1, 49152, 
+    51200, 52224, 51968, 52032, 52033, 52024,     0,     1, 
+    49152, 51200, 52224, 51968, 52032, 52033, 52024, 52026, 
+        0,     1, 49152, 51200, 52224, 51968, 52032, 52033, 
+    52024,     0,     1, 49152, 51200, 52224, 51968, 52032, 
+    52033, 52024, 52028,     0,     1, 49152, 51200, 52224, 
+    51968, 52032, 52033, 52035, 52028,     0,     1, 49152, 
+    51200, 52224, 51968, 52032, 52033, 52035, 52028, 52030, 
+        0,     1, 49152, 51200, 52224, 51968,     0,     1, 
+    49152, 51200, 52224, 51968, 52032,     0,     1, 49152, 
+    51200, 52224, 51968, 52032,     0,     1, 49152, 51200, 
+    52224, 51968, 52032, 52034,     0,     1, 49152, 51200, 
+    52224, 51968, 52032,     0,     1, 49152, 51200, 52224, 
+    51968, 52032, 52036,     0,     1, 49152, 51200, 52224, 
+    51968, 52032, 52036,     0,     1, 49152, 51200, 52224, 
+    51968, 52032, 52040, 52038,     0,     1, 49152, 51200, 
+    52224, 51968, 52032,     0,     1, 49152, 51200, 52224, 
+    51968, 52032, 52040,     0,     1, 49152, 51200, 52224, 
+    51968, 52032, 52040,     0,     1, 49152, 51200, 52224, 
+    51968, 52032, 52040, 52042,     0,     1, 49152, 51200, 
+    52224, 51968, 52032, 52040,     0,     1, 49152, 51200, 
+    52224, 51968, 52032, 52048, 52044,     0,     1, 49152, 
+    51200, 52224, 51968, 52032, 52048, 52044,     0,     1, 
+    49152, 51200, 52224, 51968, 52032, 52048, 52049, 52046, 
+        0,     1, 49152, 51200, 52224, 51968, 52032,     0, 
+        1, 49152, 51200, 52224, 51968, 52032, 52048,     0, 
+        1, 49152, 51200, 52224, 51968, 52032, 52048,     0, 
+        1, 49152, 51200, 52224, 51968, 52032, 52048, 52050, 
+        0,     1, 49152, 51200, 52224, 51968, 52032, 52048, 
+        0,     1, 49152, 51200, 52224, 51968, 52032, 52048, 
+    52052,     0,     1, 49152, 51200, 52224, 51968, 52032, 
+    52048, 52052,     0,     1, 49152, 51200, 52224, 51968, 
+    52032, 52048, 52056, 52054,     0,     1, 49152, 51200, 
+    52224, 51968, 52032, 52048,     0,     1, 49152, 51200, 
+    52224, 51968, 52032, 52064, 52056,     0,     1, 49152, 
+    51200, 52224, 51968, 52032, 52064, 52056,     0,     1, 
+    49152, 51200, 52224, 51968, 52032, 52064, 52056, 52058, 
+        0,     1, 49152, 51200, 52224, 51968, 52032, 52064, 
+    52056,     0,     1, 49152, 51200, 52224, 51968, 52032, 
+    52064, 52065, 52060,     0,     1, 49152, 51200, 52224, 
+    51968, 52032, 52064, 52065, 52060,     0,     1, 49152, 
+    51200, 52224, 51968, 52032, 52064, 52065, 52060, 52062, 
+        0,     1, 49152, 51200, 52224, 51968, 52032,     0, 
+        1, 49152, 51200, 52224, 51968, 52096, 52064,     0, 
+        1, 49152, 51200, 52224, 51968, 52096, 52064,     0, 
+        1, 49152, 51200, 52224, 51968, 52096, 52064, 52066, 
+        0,     1, 49152, 51200, 52224, 51968, 52096, 52064, 
+        0,     1, 49152, 51200, 52224, 51968, 52096, 52064, 
+    52068,     0,     1, 49152, 51200, 52224, 51968, 52096, 
+    52064, 52068,     0,     1, 49152, 51200, 52224, 51968, 
+    52096, 52064, 52072, 52070,     0,     1, 49152, 51200, 
+    52224, 51968, 52096, 52064,     0,     1, 49152, 51200, 
+    52224, 51968, 52096, 52064, 52072,     0,     1, 49152, 
+    51200, 52224, 51968, 52096, 52064, 52072,     0,     1, 
+    49152, 51200, 52224, 51968, 52096, 52064, 52072, 52074, 
+        0,     1, 49152, 51200, 52224, 51968, 52096, 52064, 
+    52072,     0,     1, 49152, 51200, 52224, 51968, 52096, 
+    52064, 52080, 52076,     0,     1, 49152, 51200, 52224, 
+    51968, 52096, 52064, 52080, 52076,     0,     1, 49152, 
+    51200, 52224, 51968, 52096, 52064, 52080, 52081, 52078, 
+        0,     1, 49152, 51200, 52224, 51968, 52096, 52064, 
+        0,     1, 49152, 51200, 52224, 51968, 52096, 52097, 
+    52080,     0,     1, 49152, 51200, 52224, 51968, 52096, 
+    52097, 52080,     0,     1, 49152, 51200, 52224, 51968, 
+    52096, 52097, 52080, 52082,     0,     1, 49152, 51200, 
+    52224, 51968, 52096, 52097, 52080,     0,     1, 49152, 
+    51200, 52224, 51968, 52096, 52097, 52080, 52084,     0, 
+        1, 49152, 51200, 52224, 51968, 52096, 52097, 52080, 
+    52084,     0,     1, 49152, 51200, 52224, 51968, 52096, 
+    52097, 52080, 52088, 52086,     0,     1, 49152, 51200, 
+    52224, 51968, 52096, 52097, 52080,     0,     1, 49152, 
+    51200, 52224, 51968, 52096, 52097, 52080, 52088,     0, 
+        1, 49152, 51200, 52224, 51968, 52096, 52097, 52099, 
+    52088,     0,     1, 49152, 51200, 52224, 51968, 52096, 
+    52097, 52099, 52088, 52090,     0,     1, 49152, 51200, 
+    52224, 51968, 52096, 52097, 52099, 52088,     0,     1, 
+    49152, 51200, 52224, 51968, 52096, 52097, 52099, 52088, 
+    52092,     0,     1, 49152, 51200, 52224, 51968, 52096, 
+    52097, 52099, 52088, 52092,     0,     1, 49152, 51200, 
+    52224, 51968, 52096, 52097, 52099, 52088, 52092, 52094, 
+        0,     1, 49152, 51200, 52224, 51968,     0,     1, 
+    49152, 51200, 52224, 51968, 52096,     0,     1, 49152, 
+    51200, 52224, 52225, 52096,     0,     1, 49152, 51200, 
+    52224, 52225, 52096, 52098,     0,     1, 49152, 51200, 
+    52224, 52225, 52096,     0,     1, 49152, 51200, 52224, 
+    52225, 52096, 52100,     0,     1, 49152, 51200, 52224, 
+    52225, 52096, 52100,     0,     1, 49152, 51200, 52224, 
+    52225, 52096, 52104, 52102,     0,     1, 49152, 51200, 
+    52224, 52225, 52096,     0,     1, 49152, 51200, 52224, 
+    52225, 52096, 52104,     0,     1, 49152, 51200, 52224, 
+    52225, 52096, 52104,     0,     1, 49152, 51200, 52224, 
+    52225, 52096, 52104, 52106,     0,     1, 49152, 51200, 
+    52224, 52225, 52096, 52104,     0,     1, 49152, 51200, 
+    52224, 52225, 52096, 52112, 52108,     0,     1, 49152, 
+    51200, 52224, 52225, 52096, 52112, 52108,     0,     1, 
+    49152, 51200, 52224, 52225, 52096, 52112, 52113, 52110, 
+        0,     1, 49152, 51200, 52224, 52225, 52096,     0, 
+        1, 49152, 51200, 52224, 52225, 52096, 52112,     0, 
+        1, 49152, 51200, 52224, 52225, 52096, 52112,     0, 
+        1, 49152, 51200, 52224, 52225, 52096, 52112, 52114, 
+        0,     1, 49152, 51200, 52224, 52225, 52096, 52112, 
+        0,     1, 49152, 51200, 52224, 52225, 52096, 52112, 
+    52116,     0,     1, 49152, 51200, 52224, 52225, 52096, 
+    52112, 52116,     0,     1, 49152, 51200, 52224, 52225, 
+    52096, 52112, 52120, 52118,     0,     1, 49152, 51200, 
+    52224, 52225, 52096, 52112,     0,     1, 49152, 51200, 
+    52224, 52225, 52096, 52128, 52120,     0,     1, 49152, 
+    51200, 52224, 52225, 52096, 52128, 52120,     0,     1, 
+    49152, 51200, 52224, 52225, 52096, 52128, 52120, 52122, 
+        0,     1, 49152, 51200, 52224, 52225, 52096, 52128, 
+    52120,     0,     1, 49152, 51200, 52224, 52225, 52096, 
+    52128, 52129, 52124,     0,     1, 49152, 51200, 52224, 
+    52225, 52096, 52128, 52129, 52124,     0,     1, 49152, 
+    51200, 52224, 52225, 52096, 52128, 52129, 52124, 52126, 
+        0,     1, 49152, 51200, 52224, 52225, 52096,     0, 
+        1, 49152, 51200, 52224, 52225, 52096, 52128,     0, 
+        1, 49152, 51200, 52224, 52225, 52096, 52128,     0, 
+        1, 49152, 51200, 52224, 52225, 52096, 52128, 52130, 
+        0,     1, 49152, 51200, 52224, 52225, 52096, 52128, 
+        0,     1, 49152, 51200, 52224, 52225, 52096, 52128, 
+    52132,     0,     1, 49152, 51200, 52224, 52225, 52096, 
+    52128, 52132,     0,     1, 49152, 51200, 52224, 52225, 
+    52096, 52128, 52136, 52134,     0,     1, 49152, 51200, 
+    52224, 52225, 52096, 52128,     0,     1, 49152, 51200, 
+    52224, 52225, 52096, 52128, 52136,     0,     1, 49152, 
+    51200, 52224, 52225, 52096, 52128, 52136,     0,     1, 
+    49152, 51200, 52224, 52225, 52096, 52128, 52136, 52138, 
+        0,     1, 49152, 51200, 52224, 52225, 52096, 52128, 
+    52136,     0,     1, 49152, 51200, 52224, 52225, 52096, 
+    52128, 52144, 52140,     0,     1, 49152, 51200, 52224, 
+    52225, 52096, 52128, 52144, 52140,     0,     1, 49152, 
+    51200, 52224, 52225, 52096, 52128, 52144, 52145, 52142, 
+        0,     1, 49152, 51200, 52224, 52225, 52096, 52128, 
+        0,     1, 49152, 51200, 52224, 52225, 52096, 52160, 
+    52144,     0,     1, 49152, 51200, 52224, 52225, 52096, 
+    52160, 52144,     0,     1, 49152, 51200, 52224, 52225, 
+    52096, 52160, 52144, 52146,     0,     1, 49152, 51200, 
+    52224, 52225, 52096, 52160, 52144,     0,     1, 49152, 
+    51200, 52224, 52225, 52096, 52160, 52144, 52148,     0, 
+        1, 49152, 51200, 52224, 52225, 52096, 52160, 52144, 
+    52148,     0,     1, 49152, 51200, 52224, 52225, 52096, 
+    52160, 52144, 52152, 52150,     0,     1, 49152, 51200, 
+    52224, 52225, 52096, 52160, 52144,     0,     1, 49152, 
+    51200, 52224, 52225, 52096, 52160, 52161, 52152,     0, 
+        1, 49152, 51200, 52224, 52225, 52096, 52160, 52161, 
+    52152,     0,     1, 49152, 51200, 52224, 52225, 52096, 
+    52160, 52161, 52152, 52154,     0,     1, 49152, 51200, 
+    52224, 52225, 52096, 52160, 52161, 52152,     0,     1, 
+    49152, 51200, 52224, 52225, 52096, 52160, 52161, 52152, 
+    52156,     0,     1, 49152, 51200, 52224, 52225, 52096, 
+    52160, 52161, 52163, 52156,     0,     1, 49152, 51200, 
+    52224, 52225, 52096, 52160, 52161, 52163, 52156, 52158, 
+        0,     1, 49152, 51200, 52224, 52225, 52096,     0, 
+        1, 49152, 51200, 52224, 52225, 52096, 52160,     0, 
+        1, 49152, 51200, 52224, 52225, 52096, 52160,     0, 
+        1, 49152, 51200, 52224, 52225, 52096, 52160, 52162, 
+        0,     1, 49152, 51200, 52224, 52225, 52227, 52160, 
+        0,     1, 49152, 51200, 52224, 52225, 52227, 52160, 
+    52164,     0,     1, 49152, 51200, 52224, 52225, 52227, 
+    52160, 52164,     0,     1, 49152, 51200, 52224, 52225, 
+    52227, 52160, 52168, 52166,     0,     1, 49152, 51200, 
+    52224, 52225, 52227, 52160,     0,     1, 49152, 51200, 
+    52224, 52225, 52227, 52160, 52168,     0,     1, 49152, 
+    51200, 52224, 52225, 52227, 52160, 52168,     0,     1, 
+    49152, 51200, 52224, 52225, 52227, 52160, 52168, 52170, 
+        0,     1, 49152, 51200, 52224, 52225, 52227, 52160, 
+    52168,     0,     1, 49152, 51200, 52224, 52225, 52227, 
+    52160, 52176, 52172,     0,     1, 49152, 51200, 52224, 
+    52225, 52227, 52160, 52176, 52172,     0,     1, 49152, 
+    51200, 52224, 52225, 52227, 52160, 52176, 52177, 52174, 
+        0,     1, 49152, 51200, 52224, 52225, 52227, 52160, 
+        0,     1, 49152, 51200, 52224, 52225, 52227, 52160, 
+    52176,     0,     1, 49152, 51200, 52224, 52225, 52227, 
+    52160, 52176,     0,     1, 49152, 51200, 52224, 52225, 
+    52227, 52160, 52176, 52178,     0,     1, 49152, 51200, 
+    52224, 52225, 52227, 52160, 52176,     0,     1, 49152, 
+    51200, 52224, 52225, 52227, 52160, 52176, 52180,     0, 
+        1, 49152, 51200, 52224, 52225, 52227, 52160, 52176, 
+    52180,     0,     1, 49152, 51200, 52224, 52225, 52227, 
+    52160, 52176, 52184, 52182,     0,     1, 49152, 51200, 
+    52224, 52225, 52227, 52160, 52176,     0,     1, 49152, 
+    51200, 52224, 52225, 52227, 52160, 52192, 52184,     0, 
+        1, 49152, 51200, 52224, 52225, 52227, 52160, 52192, 
+    52184,     0,     1, 49152, 51200, 52224, 52225, 52227, 
+    52160, 52192, 52184, 52186,     0,     1, 49152, 51200, 
+    52224, 52225, 52227, 52160, 52192, 52184,     0,     1, 
+    49152, 51200, 52224, 52225, 52227, 52160, 52192, 52193, 
+    52188,     0,     1, 49152, 51200, 52224, 52225, 52227, 
+    52160, 52192, 52193, 52188,     0,     1, 49152, 51200, 
+    52224, 52225, 52227, 52160, 52192, 52193, 52188, 52190, 
+        0,     1, 49152, 51200, 52224, 52225, 52227, 52160, 
+        0,     1, 49152, 51200, 52224, 52225, 52227, 52160, 
+    52192,     0,     1, 49152, 51200, 52224, 52225, 52227, 
+    52160, 52192,     0,     1, 49152, 51200, 52224, 52225, 
+    52227, 52160, 52192, 52194,     0,     1, 49152, 51200, 
+    52224, 52225, 52227, 52160, 52192,     0,     1, 49152, 
+    51200, 52224, 52225, 52227, 52160, 52192, 52196,     0, 
+        1, 49152, 51200, 52224, 52225, 52227, 52160, 52192, 
+    52196,     0,     1, 49152, 51200, 52224, 52225, 52227, 
+    52160, 52192, 52200, 52198,     0,     1, 49152, 51200, 
+    52224, 52225, 52227, 52231, 52192,     0,     1, 49152, 
+    51200, 52224, 52225, 52227, 52231, 52192, 52200,     0, 
+        1, 49152, 51200, 52224, 52225, 52227, 52231, 52192, 
+    52200,     0,     1, 49152, 51200, 52224, 52225, 52227, 
+    52231, 52192, 52200, 52202,     0,     1, 49152, 51200, 
+    52224, 52225, 52227, 52231, 52192, 52200,     0,     1, 
+    49152, 51200, 52224, 52225, 52227, 52231, 52192, 52208, 
+    52204,     0,     1, 49152, 51200, 52224, 52225, 52227, 
+    52231, 52192, 52208, 52204,     0,     1, 49152, 51200, 
+    52224, 52225, 52227, 52231, 52192, 52208, 52209, 52206, 
+        0,     1, 49152, 51200, 52224, 52225, 52227, 52231, 
+    52192,     0,     1, 49152, 51200, 52224, 52225, 52227, 
+    52231, 52192, 52208,     0,     1, 49152, 51200, 52224, 
+    52225, 52227, 52231, 52192, 52208,     0,     1, 49152, 
+    51200, 52224, 52225, 52227, 52231, 52192, 52208, 52210, 
+        0,     1, 49152, 51200, 52224, 52225, 52227, 52231, 
+    52192, 52208,     0,     1, 49152, 51200, 52224, 52225, 
+    52227, 52231, 52192, 52208, 52212,     0,     1, 49152, 
+    51200, 52224, 52225, 52227, 52231, 52192, 52208, 52212, 
+        0,     1, 49152, 51200, 52224, 52225, 52227, 52231, 
+    52192, 52208, 52216, 52214,     0,     1, 49152, 51200, 
+    52224, 52225, 52227, 52231, 52192, 52208,     0,     1, 
+    49152, 51200, 52224, 52225, 52227, 52231, 52192, 52208, 
+    52216,     0,     1, 49152, 51200, 52224, 52225, 52227, 
+    52231, 52192, 52208, 52216,     0,     1, 49152, 51200, 
+    52224, 52225, 52227, 52231, 52192, 52208, 52216, 52218, 
+        0,     1, 49152, 51200, 52224, 52225, 52227, 52231, 
+    52192, 52208, 52216,     0,     1, 49152, 51200, 52224, 
+    52225, 52227, 52231, 52192, 52208, 52216, 52220,     0, 
+        1, 49152, 51200, 52224, 52225, 52227, 52231, 52192, 
+    52208, 52216, 52220,     0,     1, 49152, 51200, 52224, 
+    52225, 52227, 52231, 52192, 52208, 52216, 52220, 52222, 
+        0,     1, 49152, 51200,     0,     1, 49152, 51200, 
+    52224,     0,     1, 49152, 51200, 52224,     0,     1, 
+    49152, 51200, 52224, 52226,     0,     1, 49152, 51200, 
+    52224,     0,     1, 49152, 51200, 52224, 52228,     0, 
+        1, 49152, 51200, 52224, 52228,     0,     1, 49152, 
+    51200, 52224, 52232, 52230,     0,     1, 49152, 51200, 
+    52224,     0,     1, 49152, 51200, 52224, 52232,     0, 
+        1, 49152, 51200, 52224, 52232,     0,     1, 49152, 
+    51200, 52224, 52232, 52234,     0,     1, 49152, 51200, 
+    52224, 52232,     0,     1, 49152, 51200, 52224, 52240, 
+    52236,     0,     1, 49152, 51200, 52224, 52240, 52236, 
+        0,     1, 49152, 51200, 52224, 52240, 52241, 52238, 
+        0,     1, 49152, 51200, 52224,     0,     1, 49152, 
+    51200, 52224, 52240,     0,     1, 49152, 51200, 52224, 
+    52240,     0,     1, 49152, 51200, 52224, 52240, 52242, 
+        0,     1, 49152, 51200, 52224, 52240,     0,     1, 
+    49152, 51200, 52224, 52240, 52244,     0,     1, 49152, 
+    51200, 52224, 52240, 52244,     0,     1, 49152, 51200, 
+    52224, 52240, 52248, 52246,     0,     1, 49152, 51200, 
+    52224, 52240,     0,     1, 49152, 51200, 52224, 52256, 
+    52248,     0,     1, 49152, 51200, 52224, 52256, 52248, 
+        0,     1, 49152, 51200, 52224, 52256, 52248, 52250, 
+        0,     1, 49152, 51200, 52224, 52256, 52248,     0, 
+        1, 49152, 51200, 52224, 52256, 52257, 52252,     0, 
+        1, 49152, 51200, 52224, 52256, 52257, 52252,     0, 
+        1, 49152, 51200, 52224, 52256, 52257, 52252, 52254, 
+        0,     1, 49152, 51200, 52224,     0,     1, 49152, 
+    51200, 52224, 52256,     0,     1, 49152, 51200, 52224, 
+    52256,     0,     1, 49152, 51200, 52224, 52256, 52258, 
+        0,     1, 49152, 51200, 52224, 52256,     0,     1, 
+    49152, 51200, 52224, 52256, 52260,     0,     1, 49152, 
+    51200, 52224, 52256, 52260,     0,     1, 49152, 51200, 
+    52224, 52256, 52264, 52262,     0,     1, 49152, 51200, 
+    52224, 52256,     0,     1, 49152, 51200, 52224, 52256, 
+    52264,     0,     1, 49152, 51200, 52224, 52256, 52264, 
+        0,     1, 49152, 51200, 52224, 52256, 52264, 52266, 
+        0,     1, 49152, 51200, 52224, 52256, 52264,     0, 
+        1, 49152, 51200, 52224, 52256, 52272, 52268,     0, 
+        1, 49152, 51200, 52224, 52256, 52272, 52268,     0, 
+        1, 49152, 51200, 52224, 52256, 52272, 52273, 52270, 
+        0,     1, 49152, 51200, 52224, 52256,     0,     1, 
+    49152, 51200, 52224, 52288, 52272,     0,     1, 49152, 
+    51200, 52224, 52288, 52272,     0,     1, 49152, 51200, 
+    52224, 52288, 52272, 52274,     0,     1, 49152, 51200, 
+    52224, 52288, 52272,     0,     1, 49152, 51200, 52224, 
+    52288, 52272, 52276,     0,     1, 49152, 51200, 52224, 
+    52288, 52272, 52276,     0,     1, 49152, 51200, 52224, 
+    52288, 52272, 52280, 52278,     0,     1, 49152, 51200, 
+    52224, 52288, 52272,     0,     1, 49152, 51200, 52224, 
+    52288, 52289, 52280,     0,     1, 49152, 51200, 52224, 
+    52288, 52289, 52280,     0,     1, 49152, 51200, 52224, 
+    52288, 52289, 52280, 52282,     0,     1, 49152, 51200, 
+    52224, 52288, 52289, 52280,     0,     1, 49152, 51200, 
+    52224, 52288, 52289, 52280, 52284,     0,     1, 49152, 
+    51200, 52224, 52288, 52289, 52291, 52284,     0,     1, 
+    49152, 51200, 52224, 52288, 52289, 52291, 52284, 52286, 
+        0,     1, 49152, 51200, 52224,     0,     1, 49152, 
+    51200, 52224, 52288,     0,     1, 49152, 51200, 52224, 
+    52288,     0,     1, 49152, 51200, 52224, 52288, 52290, 
+        0,     1, 49152, 51200, 52224, 52288,     0,     1, 
+    49152, 51200, 52224, 52288, 52292,     0,     1, 49152, 
+    51200, 52224, 52288, 52292,     0,     1, 49152, 51200, 
+    52224, 52288, 52296, 52294,     0,     1, 49152, 51200, 
+    52224, 52288,     0,     1, 49152, 51200, 52224, 52288, 
+    52296,     0,     1, 49152, 51200, 52224, 52288, 52296, 
+        0,     1, 49152, 51200, 52224, 52288, 52296, 52298, 
+        0,     1, 49152, 51200, 52224, 52288, 52296,     0, 
+        1, 49152, 51200, 52224, 52288, 52304, 52300,     0, 
+        1, 49152, 51200, 52224, 52288, 52304, 52300,     0, 
+        1, 49152, 51200, 52224, 52288, 52304, 52305, 52302, 
+        0,     1, 49152, 51200, 52224, 52288,     0,     1, 
+    49152, 51200, 52224, 52288, 52304,     0,     1, 49152, 
+    51200, 52224, 52288, 52304,     0,     1, 49152, 51200, 
+    52224, 52288, 52304, 52306,     0,     1, 49152, 51200, 
+    52224, 52288, 52304,     0,     1, 49152, 51200, 52224, 
+    52288, 52304, 52308,     0,     1, 49152, 51200, 52224, 
+    52288, 52304, 52308,     0,     1, 49152, 51200, 52224, 
+    52288, 52304, 52312, 52310,     0,     1, 49152, 51200, 
+    52224, 52288, 52304,     0,     1, 49152, 51200, 52224, 
+    52288, 52320, 52312,     0,     1, 49152, 51200, 52224, 
+    52288, 52320, 52312,     0,     1, 49152, 51200, 52224, 
+    52288, 52320, 52312, 52314,     0,     1, 49152, 51200, 
+    52224, 52288, 52320, 52312,     0,     1, 49152, 51200, 
+    52224, 52288, 52320, 52321, 52316,     0,     1, 49152, 
+    51200, 52224, 52288, 52320, 52321, 52316,     0,     1, 
+    49152, 51200, 52224, 52288, 52320, 52321, 52316, 52318, 
+        0,     1, 49152, 51200, 52224, 52288,     0,     1, 
+    49152, 51200, 52224, 52352, 52320,     0,     1, 49152, 
+    51200, 52224, 52352, 52320,     0,     1, 49152, 51200, 
+    52224, 52352, 52320, 52322,     0,     1, 49152, 51200, 
+    52224, 52352, 52320,     0,     1, 49152, 51200, 52224, 
+    52352, 52320, 52324,     0,     1, 49152, 51200, 52224, 
+    52352, 52320, 52324,     0,     1, 49152, 51200, 52224, 
+    52352, 52320, 52328, 52326,     0,     1, 49152, 51200, 
+    52224, 52352, 52320,     0,     1, 49152, 51200, 52224, 
+    52352, 52320, 52328,     0,     1, 49152, 51200, 52224, 
+    52352, 52320, 52328,     0,     1, 49152, 51200, 52224, 
+    52352, 52320, 52328, 52330,     0,     1, 49152, 51200, 
+    52224, 52352, 52320, 52328,     0,     1, 49152, 51200, 
+    52224, 52352, 52320, 52336, 52332,     0,     1, 49152, 
+    51200, 52224, 52352, 52320, 52336, 52332,     0,     1, 
+    49152, 51200, 52224, 52352, 52320, 52336, 52337, 52334, 
+        0,     1, 49152, 51200, 52224, 52352, 52320,     0, 
+        1, 49152, 51200, 52224, 52352, 52353, 52336,     0, 
+        1, 49152, 51200, 52224, 52352, 52353, 52336,     0, 
+        1, 49152, 51200, 52224, 52352, 52353, 52336, 52338, 
+        0,     1, 49152, 51200, 52224, 52352, 52353, 52336, 
+        0,     1, 49152, 51200, 52224, 52352, 52353, 52336, 
+    52340,     0,     1, 49152, 51200, 52224, 52352, 52353, 
+    52336, 52340,     0,     1, 49152, 51200, 52224, 52352, 
+    52353, 52336, 52344, 52342,     0,     1, 49152, 51200, 
+    52224, 52352, 52353, 52336,     0,     1, 49152, 51200, 
+    52224, 52352, 52353, 52336, 52344,     0,     1, 49152, 
+    51200, 52224, 52352, 52353, 52355, 52344,     0,     1, 
+    49152, 51200, 52224, 52352, 52353, 52355, 52344, 52346, 
+        0,     1, 49152, 51200, 52224, 52352, 52353, 52355, 
+    52344,     0,     1, 49152, 51200, 52224, 52352, 52353, 
+    52355, 52344, 52348,     0,     1, 49152, 51200, 52224, 
+    52352, 52353, 52355, 52344, 52348,     0,     1, 49152, 
+    51200, 52224, 52352, 52353, 52355, 52344, 52348, 52350, 
+        0,     1, 49152, 51200, 52224,     0,     1, 49152, 
+    51200, 52224, 52352,     0,     1, 49152, 51200, 52224, 
+    52352,     0,     1, 49152, 51200, 52224, 52352, 52354, 
+        0,     1, 49152, 51200, 52224, 52352,     0,     1, 
+    49152, 51200, 52224, 52352, 52356,     0,     1, 49152, 
+    51200, 52224, 52352, 52356,     0,     1, 49152, 51200, 
+    52224, 52352, 52360, 52358,     0,     1, 49152, 51200, 
+    52224, 52352,     0,     1, 49152, 51200, 52224, 52352, 
+    52360,     0,     1, 49152, 51200, 52224, 52352, 52360, 
+        0,     1, 49152, 51200, 52224, 52352, 52360, 52362, 
+        0,     1, 49152, 51200, 52224, 52352, 52360,     0, 
+        1, 49152, 51200, 52224, 52352, 52368, 52364,     0, 
+        1, 49152, 51200, 52224, 52352, 52368, 52364,     0, 
+        1, 49152, 51200, 52224, 52352, 52368, 52369, 52366, 
+        0,     1, 49152, 51200, 52224, 52352,     0,     1, 
+    49152, 51200, 52224, 52352, 52368,     0,     1, 49152, 
+    51200, 52224, 52352, 52368,     0,     1, 49152, 51200, 
+    52224, 52352, 52368, 52370,     0,     1, 49152, 51200, 
+    52224, 52352, 52368,     0,     1, 49152, 51200, 52224, 
+    52352, 52368, 52372,     0,     1, 49152, 51200, 52224, 
+    52352, 52368, 52372,     0,     1, 49152, 51200, 52224, 
+    52352, 52368, 52376, 52374,     0,     1, 49152, 51200, 
+    52224, 52352, 52368,     0,     1, 49152, 51200, 52224, 
+    52352, 52384, 52376,     0,     1, 49152, 51200, 52224, 
+    52352, 52384, 52376,     0,     1, 49152, 51200, 52224, 
+    52352, 52384, 52376, 52378,     0,     1, 49152, 51200, 
+    52224, 52352, 52384, 52376,     0,     1, 49152, 51200, 
+    52224, 52352, 52384, 52385, 52380,     0,     1, 49152, 
+    51200, 52224, 52352, 52384, 52385, 52380,     0,     1, 
+    49152, 51200, 52224, 52352, 52384, 52385, 52380, 52382, 
+        0,     1, 49152, 51200, 52224, 52352,     0,     1, 
+    49152, 51200, 52224, 52352, 52384,     0,     1, 49152, 
+    51200, 52224, 52352, 52384,     0,     1, 49152, 51200, 
+    52224, 52352, 52384, 52386,     0,     1, 49152, 51200, 
+    52224, 52352, 52384,     0,     1, 49152, 51200, 52224, 
+    52352, 52384, 52388,     0,     1, 49152, 51200, 52224, 
+    52352, 52384, 52388,     0,     1, 49152, 51200, 52224, 
+    52352, 52384, 52392, 52390,     0,     1, 49152, 51200, 
+    52224, 52352, 52384,     0,     1, 49152, 51200, 52224, 
+    52352, 52384, 52392,     0,     1, 49152, 51200, 52224, 
+    52352, 52384, 52392,     0,     1, 49152, 51200, 52224, 
+    52352, 52384, 52392, 52394,     0,     1, 49152, 51200, 
+    52224, 52352, 52384, 52392,     0,     1, 49152, 51200, 
+    52224, 52352, 52384, 52400, 52396,     0,     1, 49152, 
+    51200, 52224, 52352, 52384, 52400, 52396,     0,     1, 
+    49152, 51200, 52224, 52352, 52384, 52400, 52401, 52398, 
+        0,     1, 49152, 51200, 52224, 52352, 52384,     0, 
+        1, 49152, 51200, 52224, 52352, 52416, 52400,     0, 
+        1, 49152, 51200, 52224, 52352, 52416, 52400,     0, 
+        1, 49152, 51200, 52224, 52352, 52416, 52400, 52402, 
+        0,     1, 49152, 51200, 52224, 52352, 52416, 52400, 
+        0,     1, 49152, 51200, 52224, 52352, 52416, 52400, 
+    52404,     0,     1, 49152, 51200, 52224, 52352, 52416, 
+    52400, 52404,     0,     1, 49152, 51200, 52224, 52352, 
+    52416, 52400, 52408, 52406,     0,     1, 49152, 51200, 
+    52224, 52352, 52416, 52400,     0,     1, 49152, 51200, 
+    52224, 52352, 52416, 52417, 52408,     0,     1, 49152, 
+    51200, 52224, 52352, 52416, 52417, 52408,     0,     1, 
+    49152, 51200, 52224, 52352, 52416, 52417, 52408, 52410, 
+        0,     1, 49152, 51200, 52224, 52352, 52416, 52417, 
+    52408,     0,     1, 49152, 51200, 52224, 52352, 52416, 
+    52417, 52408, 52412,     0,     1, 49152, 51200, 52224, 
+    52352, 52416, 52417, 52419, 52412,     0,     1, 49152, 
+    51200, 52224, 52352, 52416, 52417, 52419, 52412, 52414, 
+        0,     1, 49152, 51200, 52224, 52352,     0,     1, 
+    49152, 51200, 52224, 52480, 52416,     0,     1, 49152, 
+    51200, 52224, 52480, 52416,     0,     1, 49152, 51200, 
+    52224, 52480, 52416, 52418,     0,     1, 49152, 51200, 
+    52224, 52480, 52416,     0,     1, 49152, 51200, 52224, 
+    52480, 52416, 52420,     0,     1, 49152, 51200, 52224, 
+    52480, 52416, 52420,     0,     1, 49152, 51200, 52224, 
+    52480, 52416, 52424, 52422,     0,     1, 49152, 51200, 
+    52224, 52480, 52416,     0,     1, 49152, 51200, 52224, 
+    52480, 52416, 52424,     0,     1, 49152, 51200, 52224, 
+    52480, 52416, 52424,     0,     1, 49152, 51200, 52224, 
+    52480, 52416, 52424, 52426,     0,     1, 49152, 51200, 
+    52224, 52480, 52416, 52424,     0,     1, 49152, 51200, 
+    52224, 52480, 52416, 52432, 52428,     0,     1, 49152, 
+    51200, 52224, 52480, 52416, 52432, 52428,     0,     1, 
+    49152, 51200, 52224, 52480, 52416, 52432, 52433, 52430, 
+        0,     1, 49152, 51200, 52224, 52480, 52416,     0, 
+        1, 49152, 51200, 52224, 52480, 52416, 52432,     0, 
+        1, 49152, 51200, 52224, 52480, 52416, 52432,     0, 
+        1, 49152, 51200, 52224, 52480, 52416, 52432, 52434, 
+        0,     1, 49152, 51200, 52224, 52480, 52416, 52432, 
+        0,     1, 49152, 51200, 52224, 52480, 52416, 52432, 
+    52436,     0,     1, 49152, 51200, 52224, 52480, 52416, 
+    52432, 52436,     0,     1, 49152, 51200, 52224, 52480, 
+    52416, 52432, 52440, 52438,     0,     1, 49152, 51200, 
+    52224, 52480, 52416, 52432,     0,     1, 49152, 51200, 
+    52224, 52480, 52416, 52448, 52440,     0,     1, 49152, 
+    51200, 52224, 52480, 52416, 52448, 52440,     0,     1, 
+    49152, 51200, 52224, 52480, 52416, 52448, 52440, 52442, 
+        0,     1, 49152, 51200, 52224, 52480, 52416, 52448, 
+    52440,     0,     1, 49152, 51200, 52224, 52480, 52416, 
+    52448, 52449, 52444,     0,     1, 49152, 51200, 52224, 
+    52480, 52416, 52448, 52449, 52444,     0,     1, 49152, 
+    51200, 52224, 52480, 52416, 52448, 52449, 52444, 52446, 
+        0,     1, 49152, 51200, 52224, 52480, 52416,     0, 
+        1, 49152, 51200, 52224, 52480, 52481, 52448,     0, 
+        1, 49152, 51200, 52224, 52480, 52481, 52448,     0, 
+        1, 49152, 51200, 52224, 52480, 52481, 52448, 52450, 
+        0,     1, 49152, 51200, 52224, 52480, 52481, 52448, 
+        0,     1, 49152, 51200, 52224, 52480, 52481, 52448, 
+    52452,     0,     1, 49152, 51200, 52224, 52480, 52481, 
+    52448, 52452,     0,     1, 49152, 51200, 52224, 52480, 
+    52481, 52448, 52456, 52454,     0,     1, 49152, 51200, 
+    52224, 52480, 52481, 52448,     0,     1, 49152, 51200, 
+    52224, 52480, 52481, 52448, 52456,     0,     1, 49152, 
+    51200, 52224, 52480, 52481, 52448, 52456,     0,     1, 
+    49152, 51200, 52224, 52480, 52481, 52448, 52456, 52458, 
+        0,     1, 49152, 51200, 52224, 52480, 52481, 52448, 
+    52456,     0,     1, 49152, 51200, 52224, 52480, 52481, 
+    52448, 52464, 52460,     0,     1, 49152, 51200, 52224, 
+    52480, 52481, 52448, 52464, 52460,     0,     1, 49152, 
+    51200, 52224, 52480, 52481, 52448, 52464, 52465, 52462, 
+        0,     1, 49152, 51200, 52224, 52480, 52481, 52448, 
+        0,     1, 49152, 51200, 52224, 52480, 52481, 52448, 
+    52464,     0,     1, 49152, 51200, 52224, 52480, 52481, 
+    52483, 52464,     0,     1, 49152, 51200, 52224, 52480, 
+    52481, 52483, 52464, 52466,     0,     1, 49152, 51200, 
+    52224, 52480, 52481, 52483, 52464,     0,     1, 49152, 
+    51200, 52224, 52480, 52481, 52483, 52464, 52468,     0, 
+        1, 49152, 51200, 52224, 52480, 52481, 52483, 52464, 
+    52468,     0,     1, 49152, 51200, 52224, 52480, 52481, 
+    52483, 52464, 52472, 52470,     0,     1, 49152, 51200, 
+    52224, 52480, 52481, 52483, 52464,     0,     1, 49152, 
+    51200, 52224, 52480, 52481, 52483, 52464, 52472,     0, 
+        1, 49152, 51200, 52224, 52480, 52481, 52483, 52464, 
+    52472,     0,     1, 49152, 51200, 52224, 52480, 52481, 
+    52483, 52464, 52472, 52474,     0,     1, 49152, 51200, 
+    52224, 52480, 52481, 52483, 52487, 52472,     0,     1, 
+    49152, 51200, 52224, 52480, 52481, 52483, 52487, 52472, 
+    52476,     0,     1, 49152, 51200, 52224, 52480, 52481, 
+    52483, 52487, 52472, 52476,     0,     1, 49152, 51200, 
+    52224, 52480, 52481, 52483, 52487, 52472, 52476, 52478, 
+        0,     1, 49152, 51200, 52224,     0,     1, 49152, 
+    53248, 52224, 52480,     0,     1, 49152, 53248, 52224, 
+    52480,     0,     1, 49152, 53248, 52224, 52480, 52482, 
+        0,     1, 49152, 53248, 52224, 52480,     0,     1, 
+    49152, 53248, 52224, 52480, 52484,     0,     1, 49152, 
+    53248, 52224, 52480, 52484,     0,     1, 49152, 53248, 
+    52224, 52480, 52488, 52486,     0,     1, 49152, 53248, 
+    52224, 52480,     0,     1, 49152, 53248, 52224, 52480, 
+    52488,     0,     1, 49152, 53248, 52224, 52480, 52488, 
+        0,     1, 49152, 53248, 52224, 52480, 52488, 52490, 
+        0,     1, 49152, 53248, 52224, 52480, 52488,     0, 
+        1, 49152, 53248, 52224, 52480, 52496, 52492,     0, 
+        1, 49152, 53248, 52224, 52480, 52496, 52492,     0, 
+        1, 49152, 53248, 52224, 52480, 52496, 52497, 52494, 
+        0,     1, 49152, 53248, 52224, 52480,     0,     1, 
+    49152, 53248, 52224, 52480, 52496,     0,     1, 49152, 
+    53248, 52224, 52480, 52496,     0,     1, 49152, 53248, 
+    52224, 52480, 52496, 52498,     0,     1, 49152, 53248, 
+    52224, 52480, 52496,     0,     1, 49152, 53248, 52224, 
+    52480, 52496, 52500,     0,     1, 49152, 53248, 52224, 
+    52480, 52496, 52500,     0,     1, 49152, 53248, 52224, 
+    52480, 52496, 52504, 52502,     0,     1, 49152, 53248, 
+    52224, 52480, 52496,     0,     1, 49152, 53248, 52224, 
+    52480, 52512, 52504,     0,     1, 49152, 53248, 52224, 
+    52480, 52512, 52504,     0,     1, 49152, 53248, 52224, 
+    52480, 52512, 52504, 52506,     0,     1, 49152, 53248, 
+    52224, 52480, 52512, 52504,     0,     1, 49152, 53248, 
+    52224, 52480, 52512, 52513, 52508,     0,     1, 49152, 
+    53248, 52224, 52480, 52512, 52513, 52508,     0,     1, 
+    49152, 53248, 52224, 52480, 52512, 52513, 52508, 52510, 
+        0,     1, 49152, 53248, 52224, 52480,     0,     1, 
+    49152, 53248, 52224, 52480, 52512,     0,     1, 49152, 
+    53248, 52224, 52480, 52512,     0,     1, 49152, 53248, 
+    52224, 52480, 52512, 52514,     0,     1, 49152, 53248, 
+    52224, 52480, 52512,     0,     1, 49152, 53248, 52224, 
+    52480, 52512, 52516,     0,     1, 49152, 53248, 52224, 
+    52480, 52512, 52516,     0,     1, 49152, 53248, 52224, 
+    52480, 52512, 52520, 52518,     0,     1, 49152, 53248, 
+    52224, 52480, 52512,     0,     1, 49152, 53248, 52224, 
+    52480, 52512, 52520,     0,     1, 49152, 53248, 52224, 
+    52480, 52512, 52520,     0,     1, 49152, 53248, 52224, 
+    52480, 52512, 52520, 52522,     0,     1, 49152, 53248, 
+    52224, 52480, 52512, 52520,     0,     1, 49152, 53248, 
+    52224, 52480, 52512, 52528, 52524,     0,     1, 49152, 
+    53248, 52224, 52480, 52512, 52528, 52524,     0,     1, 
+    49152, 53248, 52224, 52480, 52512, 52528, 52529, 52526, 
+        0,     1, 49152, 53248, 52224, 52480, 52512,     0, 
+        1, 49152, 53248, 52224, 52480, 52544, 52528,     0, 
+        1, 49152, 53248, 52224, 52480, 52544, 52528,     0, 
+        1, 49152, 53248, 52224, 52480, 52544, 52528, 52530, 
+        0,     1, 49152, 53248, 52224, 52480, 52544, 52528, 
+        0,     1, 49152, 53248, 52224, 52480, 52544, 52528, 
+    52532,     0,     1, 49152, 53248, 52224, 52480, 52544, 
+    52528, 52532,     0,     1, 49152, 53248, 52224, 52480, 
+    52544, 52528, 52536, 52534,     0,     1, 49152, 53248, 
+    52224, 52480, 52544, 52528,     0,     1, 49152, 53248, 
+    52224, 52480, 52544, 52545, 52536,     0,     1, 49152, 
+    53248, 52224, 52480, 52544, 52545, 52536,     0,     1, 
+    49152, 53248, 52224, 52480, 52544, 52545, 52536, 52538, 
+        0,     1, 49152, 53248, 52224, 52480, 52544, 52545, 
+    52536,     0,     1, 49152, 53248, 52224, 52480, 52544, 
+    52545, 52536, 52540,     0,     1, 49152, 53248, 52224, 
+    52480, 52544, 52545, 52547, 52540,     0,     1, 49152, 
+    53248, 52224, 52480, 52544, 52545, 52547, 52540, 52542, 
+        0,     1, 49152, 53248, 52224, 52480,     0,     1, 
+    49152, 53248, 52224, 52480, 52544,     0,     1, 49152, 
+    53248, 52224, 52480, 52544,     0,     1, 49152, 53248, 
+    52224, 52480, 52544, 52546,     0,     1, 49152, 53248, 
+    52224, 52480, 52544,     0,     1, 49152, 53248, 52224, 
+    52480, 52544, 52548,     0,     1, 49152, 53248, 52224, 
+    52480, 52544, 52548,     0,     1, 49152, 53248, 52224, 
+    52480, 52544, 52552, 52550,     0,     1, 49152, 53248, 
+    52224, 52480, 52544,     0,     1, 49152, 53248, 52224, 
+    52480, 52544, 52552,     0,     1, 49152, 53248, 52224, 
+    52480, 52544, 52552,     0,     1, 49152, 53248, 52224, 
+    52480, 52544, 52552, 52554,     0,     1, 49152, 53248, 
+    52224, 52480, 52544, 52552,     0,     1, 49152, 53248, 
+    52224, 52480, 52544, 52560, 52556,     0,     1, 49152, 
+    53248, 52224, 52480, 52544, 52560, 52556,     0,     1, 
+    49152, 53248, 52224, 52480, 52544, 52560, 52561, 52558, 
+        0,     1, 49152, 53248, 52224, 52480, 52544,     0, 
+        1, 49152, 53248, 52224, 52480, 52544, 52560,     0, 
+        1, 49152, 53248, 52224, 52480, 52544, 52560,     0, 
+        1, 49152, 53248, 52224, 52480, 52544, 52560, 52562, 
+        0,     1, 49152, 53248, 52224, 52480, 52544, 52560, 
+        0,     1, 49152, 53248, 52224, 52480, 52544, 52560, 
+    52564,     0,     1, 49152, 53248, 52224, 52480, 52544, 
+    52560, 52564,     0,     1, 49152, 53248, 52224, 52480, 
+    52544, 52560, 52568, 52566,     0,     1, 49152, 53248, 
+    52224, 52480, 52544, 52560,     0,     1, 49152, 53248, 
+    52224, 52480, 52544, 52576, 52568,     0,     1, 49152, 
+    53248, 52224, 52480, 52544, 52576, 52568,     0,     1, 
+    49152, 53248, 52224, 52480, 52544, 52576, 52568, 52570, 
+        0,     1, 49152, 53248, 52224, 52480, 52544, 52576, 
+    52568,     0,     1, 49152, 53248, 52224, 52480, 52544, 
+    52576, 52577, 52572,     0,     1, 49152, 53248, 52224, 
+    52480, 52544, 52576, 52577, 52572,     0,     1, 49152, 
+    53248, 52224, 52480, 52544, 52576, 52577, 52572, 52574, 
+        0,     1, 49152, 53248, 52224, 52480, 52544,     0, 
+        1, 49152, 53248, 52224, 52480, 52608, 52576,     0, 
+        1, 49152, 53248, 52224, 52480, 52608, 52576,     0, 
+        1, 49152, 53248, 52224, 52480, 52608, 52576, 52578, 
+        0,     1, 49152, 53248, 52224, 52480, 52608, 52576, 
+        0,     1, 49152, 53248, 52224, 52480, 52608, 52576, 
+    52580,     0,     1, 49152, 53248, 52224, 52480, 52608, 
+    52576, 52580,     0,     1, 49152, 53248, 52224, 52480, 
+    52608, 52576, 52584, 52582,     0,     1, 49152, 53248, 
+    52224, 52480, 52608, 52576,     0,     1, 49152, 53248, 
+    52224, 52480, 52608, 52576, 52584,     0,     1, 49152, 
+    53248, 52224, 52480, 52608, 52576, 52584,     0,     1, 
+    49152, 53248, 52224, 52480, 52608, 52576, 52584, 52586, 
+        0,     1, 49152, 53248, 52224, 52480, 52608, 52576, 
+    52584,     0,     1, 49152, 53248, 52224, 52480, 52608, 
+    52576, 52592, 52588,     0,     1, 49152, 53248, 52224, 
+    52480, 52608, 52576, 52592, 52588,     0,     1, 49152, 
+    53248, 52224, 52480, 52608, 52576, 52592, 52593, 52590, 
+        0,     1, 49152, 53248, 52224, 52480, 52608, 52576, 
+        0,     1, 49152, 53248, 52224, 52480, 52608, 52609, 
+    52592,     0,     1, 49152, 53248, 52224, 52480, 52608, 
+    52609, 52592,     0,     1, 49152, 53248, 52224, 52480, 
+    52608, 52609, 52592, 52594,     0,     1, 49152, 53248, 
+    52224, 52480, 52608, 52609, 52592,     0,     1, 49152, 
+    53248, 52224, 52480, 52608, 52609, 52592, 52596,     0, 
+        1, 49152, 53248, 52224, 52480, 52608, 52609, 52592, 
+    52596,     0,     1, 49152, 53248, 52224, 52480, 52608, 
+    52609, 52592, 52600, 52598,     0,     1, 49152, 53248, 
+    52224, 52480, 52608, 52609, 52592,     0,     1, 49152, 
+    53248, 52224, 52480, 52608, 52609, 52592, 52600,     0, 
+        1, 49152, 53248, 52224, 52480, 52608, 52609, 52611, 
+    52600,     0,     1, 49152, 53248, 52224, 52480, 52608, 
+    52609, 52611, 52600, 52602,     0,     1, 49152, 53248, 
+    52224, 52480, 52608, 52609, 52611, 52600,     0,     1, 
+    49152, 53248, 52224, 52480, 52608, 52609, 52611, 52600, 
+    52604,     0,     1, 49152, 53248, 52224, 52480, 52608, 
+    52609, 52611, 52600, 52604,     0,     1, 49152, 53248, 
+    52224, 52480, 52608, 52609, 52611, 52600, 52604, 52606, 
+        0,     1, 49152, 53248, 52224, 52480,     0,     1, 
+    49152, 53248, 52224, 52736, 52608,     0,     1, 49152, 
+    53248, 52224, 52736, 52608,     0,     1, 49152, 53248, 
+    52224, 52736, 52608, 52610,     0,     1, 49152, 53248, 
+    52224, 52736, 52608,     0,     1, 49152, 53248, 52224, 
+    52736, 52608, 52612,     0,     1, 49152, 53248, 52224, 
+    52736, 52608, 52612,     0,     1, 49152, 53248, 52224, 
+    52736, 52608, 52616, 52614,     0,     1, 49152, 53248, 
+    52224, 52736, 52608,     0,     1, 49152, 53248, 52224, 
+    52736, 52608, 52616,     0,     1, 49152, 53248, 52224, 
+    52736, 52608, 52616,     0,     1, 49152, 53248, 52224, 
+    52736, 52608, 52616, 52618,     0,     1, 49152, 53248, 
+    52224, 52736, 52608, 52616,     0,     1, 49152, 53248, 
+    52224, 52736, 52608, 52624, 52620,     0,     1, 49152, 
+    53248, 52224, 52736, 52608, 52624, 52620,     0,     1, 
+    49152, 53248, 52224, 52736, 52608, 52624, 52625, 52622, 
+        0,     1, 49152, 53248, 52224, 52736, 52608,     0, 
+        1, 49152, 53248, 52224, 52736, 52608, 52624,     0, 
+        1, 49152, 53248, 52224, 52736, 52608, 52624,     0, 
+        1, 49152, 53248, 52224, 52736, 52608, 52624, 52626, 
+        0,     1, 49152, 53248, 52224, 52736, 52608, 52624, 
+        0,     1, 49152, 53248, 52224, 52736, 52608, 52624, 
+    52628,     0,     1, 49152, 53248, 52224, 52736, 52608, 
+    52624, 52628,     0,     1, 49152, 53248, 52224, 52736, 
+    52608, 52624, 52632, 52630,     0,     1, 49152, 53248, 
+    52224, 52736, 52608, 52624,     0,     1, 49152, 53248, 
+    52224, 52736, 52608, 52640, 52632,     0,     1, 49152, 
+    53248, 52224, 52736, 52608, 52640, 52632,     0,     1, 
+    49152, 53248, 52224, 52736, 52608, 52640, 52632, 52634, 
+        0,     1, 49152, 53248, 52224, 52736, 52608, 52640, 
+    52632,     0,     1, 49152, 53248, 52224, 52736, 52608, 
+    52640, 52641, 52636,     0,     1, 49152, 53248, 52224, 
+    52736, 52608, 52640, 52641, 52636,     0,     1, 49152, 
+    53248, 52224, 52736, 52608, 52640, 52641, 52636, 52638, 
+        0,     1, 49152, 53248, 52224, 52736, 52608,     0, 
+        1, 49152, 53248, 52224, 52736, 52608, 52640,     0, 
+        1, 49152, 53248, 52224, 52736, 52608, 52640,     0, 
+        1, 49152, 53248, 52224, 52736, 52608, 52640, 52642, 
+        0,     1, 49152, 53248, 52224, 52736, 52608, 52640, 
+        0,     1, 49152, 53248, 52224, 52736, 52608, 52640, 
+    52644,     0,     1, 49152, 53248, 52224, 52736, 52608, 
+    52640, 52644,     0,     1, 49152, 53248, 52224, 52736, 
+    52608, 52640, 52648, 52646,     0,     1, 49152, 53248, 
+    52224, 52736, 52608, 52640,     0,     1, 49152, 53248, 
+    52224, 52736, 52608, 52640, 52648,     0,     1, 49152, 
+    53248, 52224, 52736, 52608, 52640, 52648,     0,     1, 
+    49152, 53248, 52224, 52736, 52608, 52640, 52648, 52650, 
+        0,     1, 49152, 53248, 52224, 52736, 52608, 52640, 
+    52648,     0,     1, 49152, 53248, 52224, 52736, 52608, 
+    52640, 52656, 52652,     0,     1, 49152, 53248, 52224, 
+    52736, 52608, 52640, 52656, 52652,     0,     1, 49152, 
+    53248, 52224, 52736, 52608, 52640, 52656, 52657, 52654, 
+        0,     1, 49152, 53248, 52224, 52736, 52608, 52640, 
+        0,     1, 49152, 53248, 52224, 52736, 52608, 52672, 
+    52656,     0,     1, 49152, 53248, 52224, 52736, 52608, 
+    52672, 52656,     0,     1, 49152, 53248, 52224, 52736, 
+    52608, 52672, 52656, 52658,     0,     1, 49152, 53248, 
+    52224, 52736, 52608, 52672, 52656,     0,     1, 49152, 
+    53248, 52224, 52736, 52608, 52672, 52656, 52660,     0, 
+        1, 49152, 53248, 52224, 52736, 52608, 52672, 52656, 
+    52660,     0,     1, 49152, 53248, 52224, 52736, 52608, 
+    52672, 52656, 52664, 52662,     0,     1, 49152, 53248, 
+    52224, 52736, 52608, 52672, 52656,     0,     1, 49152, 
+    53248, 52224, 52736, 52608, 52672, 52673, 52664,     0, 
+        1, 49152, 53248, 52224, 52736, 52608, 52672, 52673, 
+    52664,     0,     1, 49152, 53248, 52224, 52736, 52608, 
+    52672, 52673, 52664, 52666,     0,     1, 49152, 53248, 
+    52224, 52736, 52608, 52672, 52673, 52664,     0,     1, 
+    49152, 53248, 52224, 52736, 52608, 52672, 52673, 52664, 
+    52668,     0,     1, 49152, 53248, 52224, 52736, 52608, 
+    52672, 52673, 52675, 52668,     0,     1, 49152, 53248, 
+    52224, 52736, 52608, 52672, 52673, 52675, 52668, 52670, 
+        0,     1, 49152, 53248, 52224, 52736, 52608,     0, 
+        1, 49152, 53248, 52224, 52736, 52737, 52672,     0, 
+        1, 49152, 53248, 52224, 52736, 52737, 52672,     0, 
+        1, 49152, 53248, 52224, 52736, 52737, 52672, 52674, 
+        0,     1, 49152, 53248, 52224, 52736, 52737, 52672, 
+        0,     1, 49152, 53248, 52224, 52736, 52737, 52672, 
+    52676,     0,     1, 49152, 53248, 52224, 52736, 52737, 
+    52672, 52676,     0,     1, 49152, 53248, 52224, 52736, 
+    52737, 52672, 52680, 52678,     0,     1, 49152, 53248, 
+    52224, 52736, 52737, 52672,     0,     1, 49152, 53248, 
+    52224, 52736, 52737, 52672, 52680,     0,     1, 49152, 
+    53248, 52224, 52736, 52737, 52672, 52680,     0,     1, 
+    49152, 53248, 52224, 52736, 52737, 52672, 52680, 52682, 
+        0,     1, 49152, 53248, 52224, 52736, 52737, 52672, 
+    52680,     0,     1, 49152, 53248, 52224, 52736, 52737, 
+    52672, 52688, 52684,     0,     1, 49152, 53248, 52224, 
+    52736, 52737, 52672, 52688, 52684,     0,     1, 49152, 
+    53248, 52224, 52736, 52737, 52672, 52688, 52689, 52686, 
+        0,     1, 49152, 53248, 52224, 52736, 52737, 52672, 
+        0,     1, 49152, 53248, 52224, 52736, 52737, 52672, 
+    52688,     0,     1, 49152, 53248, 52224, 52736, 52737, 
+    52672, 52688,     0,     1, 49152, 53248, 52224, 52736, 
+    52737, 52672, 52688, 52690,     0,     1, 49152, 53248, 
+    52224, 52736, 52737, 52672, 52688,     0,     1, 49152, 
+    53248, 52224, 52736, 52737, 52672, 52688, 52692,     0, 
+        1, 49152, 53248, 52224, 52736, 52737, 52672, 52688, 
+    52692,     0,     1, 49152, 53248, 52224, 52736, 52737, 
+    52672, 52688, 52696, 52694,     0,     1, 49152, 53248, 
+    52224, 52736, 52737, 52672, 52688,     0,     1, 49152, 
+    53248, 52224, 52736, 52737, 52672, 52704, 52696,     0, 
+        1, 49152, 53248, 52224, 52736, 52737, 52672, 52704, 
+    52696,     0,     1, 49152, 53248, 52224, 52736, 52737, 
+    52672, 52704, 52696, 52698,     0,     1, 49152, 53248, 
+    52224, 52736, 52737, 52672, 52704, 52696,     0,     1, 
+    49152, 53248, 52224, 52736, 52737, 52672, 52704, 52705, 
+    52700,     0,     1, 49152, 53248, 52224, 52736, 52737, 
+    52672, 52704, 52705, 52700,     0,     1, 49152, 53248, 
+    52224, 52736, 52737, 52672, 52704, 52705, 52700, 52702, 
+        0,     1, 49152, 53248, 52224, 52736, 52737, 52672, 
+        0,     1, 49152, 53248, 52224, 52736, 52737, 52672, 
+    52704,     0,     1, 49152, 53248, 52224, 52736, 52737, 
+    52739, 52704,     0,     1, 49152, 53248, 52224, 52736, 
+    52737, 52739, 52704, 52706,     0,     1, 49152, 53248, 
+    52224, 52736, 52737, 52739, 52704,     0,     1, 49152, 
+    53248, 52224, 52736, 52737, 52739, 52704, 52708,     0, 
+        1, 49152, 53248, 52224, 52736, 52737, 52739, 52704, 
+    52708,     0,     1, 49152, 53248, 52224, 52736, 52737, 
+    52739, 52704, 52712, 52710,     0,     1, 49152, 53248, 
+    52224, 52736, 52737, 52739, 52704,     0,     1, 49152, 
+    53248, 52224, 52736, 52737, 52739, 52704, 52712,     0, 
+        1, 49152, 53248, 52224, 52736, 52737, 52739, 52704, 
+    52712,     0,     1, 49152, 53248, 52224, 52736, 52737, 
+    52739, 52704, 52712, 52714,     0,     1, 49152, 53248, 
+    52224, 52736, 52737, 52739, 52704, 52712,     0,     1, 
+    49152, 53248, 52224, 52736, 52737, 52739, 52704, 52720, 
+    52716,     0,     1, 49152, 53248, 52224, 52736, 52737, 
+    52739, 52704, 52720, 52716,     0,     1, 49152, 53248, 
+    52224, 52736, 52737, 52739, 52704, 52720, 52721, 52718, 
+        0,     1, 49152, 53248, 52224, 52736, 52737, 52739, 
+    52704,     0,     1, 49152, 53248, 52224, 52736, 52737, 
+    52739, 52704, 52720,     0,     1, 49152, 53248, 52224, 
+    52736, 52737, 52739, 52704, 52720,     0,     1, 49152, 
+    53248, 52224, 52736, 52737, 52739, 52704, 52720, 52722, 
+        0,     1, 49152, 53248, 52224, 52736, 52737, 52739, 
+    52743, 52720,     0,     1, 49152, 53248, 52224, 52736, 
+    52737, 52739, 52743, 52720, 52724,     0,     1, 49152, 
+    53248, 52224, 52736, 52737, 52739, 52743, 52720, 52724, 
+        0,     1, 49152, 53248, 52224, 52736, 52737, 52739, 
+    52743, 52720, 52728, 52726,     0,     1, 49152, 53248, 
+    52224, 52736, 52737, 52739, 52743, 52720,     0,     1, 
+    49152, 53248, 52224, 52736, 52737, 52739, 52743, 52720, 
+    52728,     0,     1, 49152, 53248, 52224, 52736, 52737, 
+    52739, 52743, 52720, 52728,     0,     1, 49152, 53248, 
+    52224, 52736, 52737, 52739, 52743, 52720, 52728, 52730, 
+        0,     1, 49152, 53248, 52224, 52736, 52737, 52739, 
+    52743, 52720, 52728,     0,     1, 49152, 53248, 52224, 
+    52736, 52737, 52739, 52743, 52720, 52728, 52732,     0, 
+        1, 49152, 53248, 52224, 52736, 52737, 52739, 52743, 
+    52720, 52728, 52732,     0,     1, 49152, 53248, 52224, 
+    52736, 52737, 52739, 52743, 52720, 52728, 52732, 52734, 
+        0,     1, 49152, 53248, 52224,     0,     1, 49152, 
+    53248, 52224, 52736,     0,     1, 49152, 53248, 53249, 
+    52736,     0,     1, 49152, 53248, 53249, 52736, 52738, 
+        0,     1, 49152, 53248, 53249, 52736,     0,     1, 
+    49152, 53248, 53249, 52736, 52740,     0,     1, 49152, 
+    53248, 53249, 52736, 52740,     0,     1, 49152, 53248, 
+    53249, 52736, 52744, 52742,     0,     1, 49152, 53248, 
+    53249, 52736,     0,     1, 49152, 53248, 53249, 52736, 
+    52744,     0,     1, 49152, 53248, 53249, 52736, 52744, 
+        0,     1, 49152, 53248, 53249, 52736, 52744, 52746, 
+        0,     1, 49152, 53248, 53249, 52736, 52744,     0, 
+        1, 49152, 53248, 53249, 52736, 52752, 52748,     0, 
+        1, 49152, 53248, 53249, 52736, 52752, 52748,     0, 
+        1, 49152, 53248, 53249, 52736, 52752, 52753, 52750, 
+        0,     1, 49152, 53248, 53249, 52736,     0,     1, 
+    49152, 53248, 53249, 52736, 52752,     0,     1, 49152, 
+    53248, 53249, 52736, 52752,     0,     1, 49152, 53248, 
+    53249, 52736, 52752, 52754,     0,     1, 49152, 53248, 
+    53249, 52736, 52752,     0,     1, 49152, 53248, 53249, 
+    52736, 52752, 52756,     0,     1, 49152, 53248, 53249, 
+    52736, 52752, 52756,     0,     1, 49152, 53248, 53249, 
+    52736, 52752, 52760, 52758,     0,     1, 49152, 53248, 
+    53249, 52736, 52752,     0,     1, 49152, 53248, 53249, 
+    52736, 52768, 52760,     0,     1, 49152, 53248, 53249, 
+    52736, 52768, 52760,     0,     1, 49152, 53248, 53249, 
+    52736, 52768, 52760, 52762,     0,     1, 49152, 53248, 
+    53249, 52736, 52768, 52760,     0,     1, 49152, 53248, 
+    53249, 52736, 52768, 52769, 52764,     0,     1, 49152, 
+    53248, 53249, 52736, 52768, 52769, 52764,     0,     1, 
+    49152, 53248, 53249, 52736, 52768, 52769, 52764, 52766, 
+        0,     1, 49152, 53248, 53249, 52736,     0,     1, 
+    49152, 53248, 53249, 52736, 52768,     0,     1, 49152, 
+    53248, 53249, 52736, 52768,     0,     1, 49152, 53248, 
+    53249, 52736, 52768, 52770,     0,     1, 49152, 53248, 
+    53249, 52736, 52768,     0,     1, 49152, 53248, 53249, 
+    52736, 52768, 52772,     0,     1, 49152, 53248, 53249, 
+    52736, 52768, 52772,     0,     1, 49152, 53248, 53249, 
+    52736, 52768, 52776, 52774,     0,     1, 49152, 53248, 
+    53249, 52736, 52768,     0,     1, 49152, 53248, 53249, 
+    52736, 52768, 52776,     0,     1, 49152, 53248, 53249, 
+    52736, 52768, 52776,     0,     1, 49152, 53248, 53249, 
+    52736, 52768, 52776, 52778,     0,     1, 49152, 53248, 
+    53249, 52736, 52768, 52776,     0,     1, 49152, 53248, 
+    53249, 52736, 52768, 52784, 52780,     0,     1, 49152, 
+    53248, 53249, 52736, 52768, 52784, 52780,     0,     1, 
+    49152, 53248, 53249, 52736, 52768, 52784, 52785, 52782, 
+        0,     1, 49152, 53248, 53249, 52736, 52768,     0, 
+        1, 49152, 53248, 53249, 52736, 52800, 52784,     0, 
+        1, 49152, 53248, 53249, 52736, 52800, 52784,     0, 
+        1, 49152, 53248, 53249, 52736, 52800, 52784, 52786, 
+        0,     1, 49152, 53248, 53249, 52736, 52800, 52784, 
+        0,     1, 49152, 53248, 53249, 52736, 52800, 52784, 
+    52788,     0,     1, 49152, 53248, 53249, 52736, 52800, 
+    52784, 52788,     0,     1, 49152, 53248, 53249, 52736, 
+    52800, 52784, 52792, 52790,     0,     1, 49152, 53248, 
+    53249, 52736, 52800, 52784,     0,     1, 49152, 53248, 
+    53249, 52736, 52800, 52801, 52792,     0,     1, 49152, 
+    53248, 53249, 52736, 52800, 52801, 52792,     0,     1, 
+    49152, 53248, 53249, 52736, 52800, 52801, 52792, 52794, 
+        0,     1, 49152, 53248, 53249, 52736, 52800, 52801, 
+    52792,     0,     1, 49152, 53248, 53249, 52736, 52800, 
+    52801, 52792, 52796,     0,     1, 49152, 53248, 53249, 
+    52736, 52800, 52801, 52803, 52796,     0,     1, 49152, 
+    53248, 53249, 52736, 52800, 52801, 52803, 52796, 52798, 
+        0,     1, 49152, 53248, 53249, 52736,     0,     1, 
+    49152, 53248, 53249, 52736, 52800,     0,     1, 49152, 
+    53248, 53249, 52736, 52800,     0,     1, 49152, 53248, 
+    53249, 52736, 52800, 52802,     0,     1, 49152, 53248, 
+    53249, 52736, 52800,     0,     1, 49152, 53248, 53249, 
+    52736, 52800, 52804,     0,     1, 49152, 53248, 53249, 
+    52736, 52800, 52804,     0,     1, 49152, 53248, 53249, 
+    52736, 52800, 52808, 52806,     0,     1, 49152, 53248, 
+    53249, 52736, 52800,     0,     1, 49152, 53248, 53249, 
+    52736, 52800, 52808,     0,     1, 49152, 53248, 53249, 
+    52736, 52800, 52808,     0,     1, 49152, 53248, 53249, 
+    52736, 52800, 52808, 52810,     0,     1, 49152, 53248, 
+    53249, 52736, 52800, 52808,     0,     1, 49152, 53248, 
+    53249, 52736, 52800, 52816, 52812,     0,     1, 49152, 
+    53248, 53249, 52736, 52800, 52816, 52812,     0,     1, 
+    49152, 53248, 53249, 52736, 52800, 52816, 52817, 52814, 
+        0,     1, 49152, 53248, 53249, 52736, 52800,     0, 
+        1, 49152, 53248, 53249, 52736, 52800, 52816,     0, 
+        1, 49152, 53248, 53249, 52736, 52800, 52816,     0, 
+        1, 49152, 53248, 53249, 52736, 52800, 52816, 52818, 
+        0,     1, 49152, 53248, 53249, 52736, 52800, 52816, 
+        0,     1, 49152, 53248, 53249, 52736, 52800, 52816, 
+    52820,     0,     1, 49152, 53248, 53249, 52736, 52800, 
+    52816, 52820,     0,     1, 49152, 53248, 53249, 52736, 
+    52800, 52816, 52824, 52822,     0,     1, 49152, 53248, 
+    53249, 52736, 52800, 52816,     0,     1, 49152, 53248, 
+    53249, 52736, 52800, 52832, 52824,     0,     1, 49152, 
+    53248, 53249, 52736, 52800, 52832, 52824,     0,     1, 
+    49152, 53248, 53249, 52736, 52800, 52832, 52824, 52826, 
+        0,     1, 49152, 53248, 53249, 52736, 52800, 52832, 
+    52824,     0,     1, 49152, 53248, 53249, 52736, 52800, 
+    52832, 52833, 52828,     0,     1, 49152, 53248, 53249, 
+    52736, 52800, 52832, 52833, 52828,     0,     1, 49152, 
+    53248, 53249, 52736, 52800, 52832, 52833, 52828, 52830, 
+        0,     1, 49152, 53248, 53249, 52736, 52800,     0, 
+        1, 49152, 53248, 53249, 52736, 52864, 52832,     0, 
+        1, 49152, 53248, 53249, 52736, 52864, 52832,     0, 
+        1, 49152, 53248, 53249, 52736, 52864, 52832, 52834, 
+        0,     1, 49152, 53248, 53249, 52736, 52864, 52832, 
+        0,     1, 49152, 53248, 53249, 52736, 52864, 52832, 
+    52836,     0,     1, 49152, 53248, 53249, 52736, 52864, 
+    52832, 52836,     0,     1, 49152, 53248, 53249, 52736, 
+    52864, 52832, 52840, 52838,     0,     1, 49152, 53248, 
+    53249, 52736, 52864, 52832,     0,     1, 49152, 53248, 
+    53249, 52736, 52864, 52832, 52840,     0,     1, 49152, 
+    53248, 53249, 52736, 52864, 52832, 52840,     0,     1, 
+    49152, 53248, 53249, 52736, 52864, 52832, 52840, 52842, 
+        0,     1, 49152, 53248, 53249, 52736, 52864, 52832, 
+    52840,     0,     1, 49152, 53248, 53249, 52736, 52864, 
+    52832, 52848, 52844,     0,     1, 49152, 53248, 53249, 
+    52736, 52864, 52832, 52848, 52844,     0,     1, 49152, 
+    53248, 53249, 52736, 52864, 52832, 52848, 52849, 52846, 
+        0,     1, 49152, 53248, 53249, 52736, 52864, 52832, 
+        0,     1, 49152, 53248, 53249, 52736, 52864, 52865, 
+    52848,     0,     1, 49152, 53248, 53249, 52736, 52864, 
+    52865, 52848,     0,     1, 49152, 53248, 53249, 52736, 
+    52864, 52865, 52848, 52850,     0,     1, 49152, 53248, 
+    53249, 52736, 52864, 52865, 52848,     0,     1, 49152, 
+    53248, 53249, 52736, 52864, 52865, 52848, 52852,     0, 
+        1, 49152, 53248, 53249, 52736, 52864, 52865, 52848, 
+    52852,     0,     1, 49152, 53248, 53249, 52736, 52864, 
+    52865, 52848, 52856, 52854,     0,     1, 49152, 53248, 
+    53249, 52736, 52864, 52865, 52848,     0,     1, 49152, 
+    53248, 53249, 52736, 52864, 52865, 52848, 52856,     0, 
+        1, 49152, 53248, 53249, 52736, 52864, 52865, 52867, 
+    52856,     0,     1, 49152, 53248, 53249, 52736, 52864, 
+    52865, 52867, 52856, 52858,     0,     1, 49152, 53248, 
+    53249, 52736, 52864, 52865, 52867, 52856,     0,     1, 
+    49152, 53248, 53249, 52736, 52864, 52865, 52867, 52856, 
+    52860,     0,     1, 49152, 53248, 53249, 52736, 52864, 
+    52865, 52867, 52856, 52860,     0,     1, 49152, 53248, 
+    53249, 52736, 52864, 52865, 52867, 52856, 52860, 52862, 
+        0,     1, 49152, 53248, 53249, 52736,     0,     1, 
+    49152, 53248, 53249, 52736, 52864,     0,     1, 49152, 
+    53248, 53249, 52736, 52864,     0,     1, 49152, 53248, 
+    53249, 52736, 52864, 52866,     0,     1, 49152, 53248, 
+    53249, 52736, 52864,     0,     1, 49152, 53248, 53249, 
+    52736, 52864, 52868,     0,     1, 49152, 53248, 53249, 
+    52736, 52864, 52868,     0,     1, 49152, 53248, 53249, 
+    52736, 52864, 52872, 52870,     0,     1, 49152, 53248, 
+    53249, 52736, 52864,     0,     1, 49152, 53248, 53249, 
+    52736, 52864, 52872,     0,     1, 49152, 53248, 53249, 
+    52736, 52864, 52872,     0,     1, 49152, 53248, 53249, 
+    52736, 52864, 52872, 52874,     0,     1, 49152, 53248, 
+    53249, 52736, 52864, 52872,     0,     1, 49152, 53248, 
+    53249, 52736, 52864, 52880, 52876,     0,     1, 49152, 
+    53248, 53249, 52736, 52864, 52880, 52876,     0,     1, 
+    49152, 53248, 53249, 52736, 52864, 52880, 52881, 52878, 
+        0,     1, 49152, 53248, 53249, 52736, 52864,     0, 
+        1, 49152, 53248, 53249, 52736, 52864, 52880,     0, 
+        1, 49152, 53248, 53249, 52736, 52864, 52880,     0, 
+        1, 49152, 53248, 53249, 52736, 52864, 52880, 52882, 
+        0,     1, 49152, 53248, 53249, 52736, 52864, 52880, 
+        0,     1, 49152, 53248, 53249, 52736, 52864, 52880, 
+    52884,     0,     1, 49152, 53248, 53249, 52736, 52864, 
+    52880, 52884,     0,     1, 49152, 53248, 53249, 52736, 
+    52864, 52880, 52888, 52886,     0,     1, 49152, 53248, 
+    53249, 52736, 52864, 52880,     0,     1, 49152, 53248, 
+    53249, 52736, 52864, 52896, 52888,     0,     1, 49152, 
+    53248, 53249, 52736, 52864, 52896, 52888,     0,     1, 
+    49152, 53248, 53249, 52736, 52864, 52896, 52888, 52890, 
+        0,     1, 49152, 53248, 53249, 52736, 52864, 52896, 
+    52888,     0,     1, 49152, 53248, 53249, 52736, 52864, 
+    52896, 52897, 52892,     0,     1, 49152, 53248, 53249, 
+    52736, 52864, 52896, 52897, 52892,     0,     1, 49152, 
+    53248, 53249, 52736, 52864, 52896, 52897, 52892, 52894, 
+        0,     1, 49152, 53248, 53249, 52736, 52864,     0, 
+        1, 49152, 53248, 53249, 52736, 52864, 52896,     0, 
+        1, 49152, 53248, 53249, 52736, 52864, 52896,     0, 
+        1, 49152, 53248, 53249, 52736, 52864, 52896, 52898, 
+        0,     1, 49152, 53248, 53249, 52736, 52864, 52896, 
+        0,     1, 49152, 53248, 53249, 52736, 52864, 52896, 
+    52900,     0,     1, 49152, 53248, 53249, 52736, 52864, 
+    52896, 52900,     0,     1, 49152, 53248, 53249, 52736, 
+    52864, 52896, 52904, 52902,     0,     1, 49152, 53248, 
+    53249, 52736, 52864, 52896,     0,     1, 49152, 53248, 
+    53249, 52736, 52864, 52896, 52904,     0,     1, 49152, 
+    53248, 53249, 52736, 52864, 52896, 52904,     0,     1, 
+    49152, 53248, 53249, 52736, 52864, 52896, 52904, 52906, 
+        0,     1, 49152, 53248, 53249, 52736, 52864, 52896, 
+    52904,     0,     1, 49152, 53248, 53249, 52736, 52864, 
+    52896, 52912, 52908,     0,     1, 49152, 53248, 53249, 
+    52736, 52864, 52896, 52912, 52908,     0,     1, 49152, 
+    53248, 53249, 52736, 52864, 52896, 52912, 52913, 52910, 
+        0,     1, 49152, 53248, 53249, 52736, 52864, 52896, 
+        0,     1, 49152, 53248, 53249, 52736, 52864, 52928, 
+    52912,     0,     1, 49152, 53248, 53249, 52736, 52864, 
+    52928, 52912,     0,     1, 49152, 53248, 53249, 52736, 
+    52864, 52928, 52912, 52914,     0,     1, 49152, 53248, 
+    53249, 52736, 52864, 52928, 52912,     0,     1, 49152, 
+    53248, 53249, 52736, 52864, 52928, 52912, 52916,     0, 
+        1, 49152, 53248, 53249, 52736, 52864, 52928, 52912, 
+    52916,     0,     1, 49152, 53248, 53249, 52736, 52864, 
+    52928, 52912, 52920, 52918,     0,     1, 49152, 53248, 
+    53249, 52736, 52864, 52928, 52912,     0,     1, 49152, 
+    53248, 53249, 52736, 52864, 52928, 52929, 52920,     0, 
+        1, 49152, 53248, 53249, 52736, 52864, 52928, 52929, 
+    52920,     0,     1, 49152, 53248, 53249, 52736, 52864, 
+    52928, 52929, 52920, 52922,     0,     1, 49152, 53248, 
+    53249, 52736, 52864, 52928, 52929, 52920,     0,     1, 
+    49152, 53248, 53249, 52736, 52864, 52928, 52929, 52920, 
+    52924,     0,     1, 49152, 53248, 53249, 52736, 52864, 
+    52928, 52929, 52931, 52924,     0,     1, 49152, 53248, 
+    53249, 52736, 52864, 52928, 52929, 52931, 52924, 52926, 
+        0,     1, 49152, 53248, 53249, 52736, 52864,     0, 
+        1, 49152, 53248, 53249, 52736, 52992, 52928,     0, 
+        1, 49152, 53248, 53249, 52736, 52992, 52928,     0, 
+        1, 49152, 53248, 53249, 52736, 52992, 52928, 52930, 
+        0,     1, 49152, 53248, 53249, 52736, 52992, 52928, 
+        0,     1, 49152, 53248, 53249, 52736, 52992, 52928, 
+    52932,     0,     1, 49152, 53248, 53249, 52736, 52992, 
+    52928, 52932,     0,     1, 49152, 53248, 53249, 52736, 
+    52992, 52928, 52936, 52934,     0,     1, 49152, 53248, 
+    53249, 52736, 52992, 52928,     0,     1, 49152, 53248, 
+    53249, 52736, 52992, 52928, 52936,     0,     1, 49152, 
+    53248, 53249, 52736, 52992, 52928, 52936,     0,     1, 
+    49152, 53248, 53249, 52736, 52992, 52928, 52936, 52938, 
+        0,     1, 49152, 53248, 53249, 52736, 52992, 52928, 
+    52936,     0,     1, 49152, 53248, 53249, 52736, 52992, 
+    52928, 52944, 52940,     0,     1, 49152, 53248, 53249, 
+    52736, 52992, 52928, 52944, 52940,     0,     1, 49152, 
+    53248, 53249, 52736, 52992, 52928, 52944, 52945, 52942, 
+        0,     1, 49152, 53248, 53249, 52736, 52992, 52928, 
+        0,     1, 49152, 53248, 53249, 52736, 52992, 52928, 
+    52944,     0,     1, 49152, 53248, 53249, 52736, 52992, 
+    52928, 52944,     0,     1, 49152, 53248, 53249, 52736, 
+    52992, 52928, 52944, 52946,     0,     1, 49152, 53248, 
+    53249, 52736, 52992, 52928, 52944,     0,     1, 49152, 
+    53248, 53249, 52736, 52992, 52928, 52944, 52948,     0, 
+        1, 49152, 53248, 53249, 52736, 52992, 52928, 52944, 
+    52948,     0,     1, 49152, 53248, 53249, 52736, 52992, 
+    52928, 52944, 52952, 52950,     0,     1, 49152, 53248, 
+    53249, 52736, 52992, 52928, 52944,     0,     1, 49152, 
+    53248, 53249, 52736, 52992, 52928, 52960, 52952,     0, 
+        1, 49152, 53248, 53249, 52736, 52992, 52928, 52960, 
+    52952,     0,     1, 49152, 53248, 53249, 52736, 52992, 
+    52928, 52960, 52952, 52954,     0,     1, 49152, 53248, 
+    53249, 52736, 52992, 52928, 52960, 52952,     0,     1, 
+    49152, 53248, 53249, 52736, 52992, 52928, 52960, 52961, 
+    52956,     0,     1, 49152, 53248, 53249, 52736, 52992, 
+    52928, 52960, 52961, 52956,     0,     1, 49152, 53248, 
+    53249, 52736, 52992, 52928, 52960, 52961, 52956, 52958, 
+        0,     1, 49152, 53248, 53249, 52736, 52992, 52928, 
+        0,     1, 49152, 53248, 53249, 52736, 52992, 52993, 
+    52960,     0,     1, 49152, 53248, 53249, 52736, 52992, 
+    52993, 52960,     0,     1, 49152, 53248, 53249, 52736, 
+    52992, 52993, 52960, 52962,     0,     1, 49152, 53248, 
+    53249, 52736, 52992, 52993, 52960,     0,     1, 49152, 
+    53248, 53249, 52736, 52992, 52993, 52960, 52964,     0, 
+        1, 49152, 53248, 53249, 52736, 52992, 52993, 52960, 
+    52964,     0,     1, 49152, 53248, 53249, 52736, 52992, 
+    52993, 52960, 52968, 52966,     0,     1, 49152, 53248, 
+    53249, 52736, 52992, 52993, 52960,     0,     1, 49152, 
+    53248, 53249, 52736, 52992, 52993, 52960, 52968,     0, 
+        1, 49152, 53248, 53249, 52736, 52992, 52993, 52960, 
+    52968,     0,     1, 49152, 53248, 53249, 52736, 52992, 
+    52993, 52960, 52968, 52970,     0,     1, 49152, 53248, 
+    53249, 52736, 52992, 52993, 52960, 52968,     0,     1, 
+    49152, 53248, 53249, 52736, 52992, 52993, 52960, 52976, 
+    52972,     0,     1, 49152, 53248, 53249, 52736, 52992, 
+    52993, 52960, 52976, 52972,     0,     1, 49152, 53248, 
+    53249, 52736, 52992, 52993, 52960, 52976, 52977, 52974, 
+        0,     1, 49152, 53248, 53249, 52736, 52992, 52993, 
+    52960,     0,     1, 49152, 53248, 53249, 52736, 52992, 
+    52993, 52960, 52976,     0,     1, 49152, 53248, 53249, 
+    52736, 52992, 52993, 52995, 52976,     0,     1, 49152, 
+    53248, 53249, 52736, 52992, 52993, 52995, 52976, 52978, 
+        0,     1, 49152, 53248, 53249, 52736, 52992, 52993, 
+    52995, 52976,     0,     1, 49152, 53248, 53249, 52736, 
+    52992, 52993, 52995, 52976, 52980,     0,     1, 49152, 
+    53248, 53249, 52736, 52992, 52993, 52995, 52976, 52980, 
+        0,     1, 49152, 53248, 53249, 52736, 52992, 52993, 
+    52995, 52976, 52984, 52982,     0,     1, 49152, 53248, 
+    53249, 52736, 52992, 52993, 52995, 52976,     0,     1, 
+    49152, 53248, 53249, 52736, 52992, 52993, 52995, 52976, 
+    52984,     0,     1, 49152, 53248, 53249, 52736, 52992, 
+    52993, 52995, 52976, 52984,     0,     1, 49152, 53248, 
+    53249, 52736, 52992, 52993, 52995, 52976, 52984, 52986, 
+        0,     1, 49152, 53248, 53249, 52736, 52992, 52993, 
+    52995, 52999, 52984,     0,     1, 49152, 53248, 53249, 
+    52736, 52992, 52993, 52995, 52999, 52984, 52988,     0, 
+        1, 49152, 53248, 53249, 52736, 52992, 52993, 52995, 
+    52999, 52984, 52988,     0,     1, 49152, 53248, 53249, 
+    52736, 52992, 52993, 52995, 52999, 52984, 52988, 52990, 
+        0,     1, 49152, 53248, 53249, 52736,     0,     1, 
+    49152, 53248, 53249, 52736, 52992,     0,     1, 49152, 
+    53248, 53249, 52736, 52992,     0,     1, 49152, 53248, 
+    53249, 52736, 52992, 52994,     0,     1, 49152, 53248, 
+    53249, 53251, 52992,     0,     1, 49152, 53248, 53249, 
+    53251, 52992, 52996,     0,     1, 49152, 53248, 53249, 
+    53251, 52992, 52996,     0,     1, 49152, 53248, 53249, 
+    53251, 52992, 53000, 52998,     0,     1, 49152, 53248, 
+    53249, 53251, 52992,     0,     1, 49152, 53248, 53249, 
+    53251, 52992, 53000,     0,     1, 49152, 53248, 53249, 
+    53251, 52992, 53000,     0,     1, 49152, 53248, 53249, 
+    53251, 52992, 53000, 53002,     0,     1, 49152, 53248, 
+    53249, 53251, 52992, 53000,     0,     1, 49152, 53248, 
+    53249, 53251, 52992, 53008, 53004,     0,     1, 49152, 
+    53248, 53249, 53251, 52992, 53008, 53004,     0,     1, 
+    49152, 53248, 53249, 53251, 52992, 53008, 53009, 53006, 
+        0,     1, 49152, 53248, 53249, 53251, 52992,     0, 
+        1, 49152, 53248, 53249, 53251, 52992, 53008,     0, 
+        1, 49152, 53248, 53249, 53251, 52992, 53008,     0, 
+        1, 49152, 53248, 53249, 53251, 52992, 53008, 53010, 
+        0,     1, 49152, 53248, 53249, 53251, 52992, 53008, 
+        0,     1, 49152, 53248, 53249, 53251, 52992, 53008, 
+    53012,     0,     1, 49152, 53248, 53249, 53251, 52992, 
+    53008, 53012,     0,     1, 49152, 53248, 53249, 53251, 
+    52992, 53008, 53016, 53014,     0,     1, 49152, 53248, 
+    53249, 53251, 52992, 53008,     0,     1, 49152, 53248, 
+    53249, 53251, 52992, 53024, 53016,     0,     1, 49152, 
+    53248, 53249, 53251, 52992, 53024, 53016,     0,     1, 
+    49152, 53248, 53249, 53251, 52992, 53024, 53016, 53018, 
+        0,     1, 49152, 53248, 53249, 53251, 52992, 53024, 
+    53016,     0,     1, 49152, 53248, 53249, 53251, 52992, 
+    53024, 53025, 53020,     0,     1, 49152, 53248, 53249, 
+    53251, 52992, 53024, 53025, 53020,     0,     1, 49152, 
+    53248, 53249, 53251, 52992, 53024, 53025, 53020, 53022, 
+        0,     1, 49152, 53248, 53249, 53251, 52992,     0, 
+        1, 49152, 53248, 53249, 53251, 52992, 53024,     0, 
+        1, 49152, 53248, 53249, 53251, 52992, 53024,     0, 
+        1, 49152, 53248, 53249, 53251, 52992, 53024, 53026, 
+        0,     1, 49152, 53248, 53249, 53251, 52992, 53024, 
+        0,     1, 49152, 53248, 53249, 53251, 52992, 53024, 
+    53028,     0,     1, 49152, 53248, 53249, 53251, 52992, 
+    53024, 53028,     0,     1, 49152, 53248, 53249, 53251, 
+    52992, 53024, 53032, 53030,     0,     1, 49152, 53248, 
+    53249, 53251, 52992, 53024,     0,     1, 49152, 53248, 
+    53249, 53251, 52992, 53024, 53032,     0,     1, 49152, 
+    53248, 53249, 53251, 52992, 53024, 53032,     0,     1, 
+    49152, 53248, 53249, 53251, 52992, 53024, 53032, 53034, 
+        0,     1, 49152, 53248, 53249, 53251, 52992, 53024, 
+    53032,     0,     1, 49152, 53248, 53249, 53251, 52992, 
+    53024, 53040, 53036,     0,     1, 49152, 53248, 53249, 
+    53251, 52992, 53024, 53040, 53036,     0,     1, 49152, 
+    53248, 53249, 53251, 52992, 53024, 53040, 53041, 53038, 
+        0,     1, 49152, 53248, 53249, 53251, 52992, 53024, 
+        0,     1, 49152, 53248, 53249, 53251, 52992, 53056, 
+    53040,     0,     1, 49152, 53248, 53249, 53251, 52992, 
+    53056, 53040,     0,     1, 49152, 53248, 53249, 53251, 
+    52992, 53056, 53040, 53042,     0,     1, 49152, 53248, 
+    53249, 53251, 52992, 53056, 53040,     0,     1, 49152, 
+    53248, 53249, 53251, 52992, 53056, 53040, 53044,     0, 
+        1, 49152, 53248, 53249, 53251, 52992, 53056, 53040, 
+    53044,     0,     1, 49152, 53248, 53249, 53251, 52992, 
+    53056, 53040, 53048, 53046,     0,     1, 49152, 53248, 
+    53249, 53251, 52992, 53056, 53040,     0,     1, 49152, 
+    53248, 53249, 53251, 52992, 53056, 53057, 53048,     0, 
+        1, 49152, 53248, 53249, 53251, 52992, 53056, 53057, 
+    53048,     0,     1, 49152, 53248, 53249, 53251, 52992, 
+    53056, 53057, 53048, 53050,     0,     1, 49152, 53248, 
+    53249, 53251, 52992, 53056, 53057, 53048,     0,     1, 
+    49152, 53248, 53249, 53251, 52992, 53056, 53057, 53048, 
+    53052,     0,     1, 49152, 53248, 53249, 53251, 52992, 
+    53056, 53057, 53059, 53052,     0,     1, 49152, 53248, 
+    53249, 53251, 52992, 53056, 53057, 53059, 53052, 53054, 
+        0,     1, 49152, 53248, 53249, 53251, 52992,     0, 
+        1, 49152, 53248, 53249, 53251, 52992, 53056,     0, 
+        1, 49152, 53248, 53249, 53251, 52992, 53056,     0, 
+        1, 49152, 53248, 53249, 53251, 52992, 53056, 53058, 
+        0,     1, 49152, 53248, 53249, 53251, 52992, 53056, 
+        0,     1, 49152, 53248, 53249, 53251, 52992, 53056, 
+    53060,     0,     1, 49152, 53248, 53249, 53251, 52992, 
+    53056, 53060,     0,     1, 49152, 53248, 53249, 53251, 
+    52992, 53056, 53064, 53062,     0,     1, 49152, 53248, 
+    53249, 53251, 52992, 53056,     0,     1, 49152, 53248, 
+    53249, 53251, 52992, 53056, 53064,     0,     1, 49152, 
+    53248, 53249, 53251, 52992, 53056, 53064,     0,     1, 
+    49152, 53248, 53249, 53251, 52992, 53056, 53064, 53066, 
+        0,     1, 49152, 53248, 53249, 53251, 52992, 53056, 
+    53064,     0,     1, 49152, 53248, 53249, 53251, 52992, 
+    53056, 53072, 53068,     0,     1, 49152, 53248, 53249, 
+    53251, 52992, 53056, 53072, 53068,     0,     1, 49152, 
+    53248, 53249, 53251, 52992, 53056, 53072, 53073, 53070, 
+        0,     1, 49152, 53248, 53249, 53251, 52992, 53056, 
+        0,     1, 49152, 53248, 53249, 53251, 52992, 53056, 
+    53072,     0,     1, 49152, 53248, 53249, 53251, 52992, 
+    53056, 53072,     0,     1, 49152, 53248, 53249, 53251, 
+    52992, 53056, 53072, 53074,     0,     1, 49152, 53248, 
+    53249, 53251, 52992, 53056, 53072,     0,     1, 49152, 
+    53248, 53249, 53251, 52992, 53056, 53072, 53076,     0, 
+        1, 49152, 53248, 53249, 53251, 52992, 53056, 53072, 
+    53076,     0,     1, 49152, 53248, 53249, 53251, 52992, 
+    53056, 53072, 53080, 53078,     0,     1, 49152, 53248, 
+    53249, 53251, 52992, 53056, 53072,     0,     1, 49152, 
+    53248, 53249, 53251, 52992, 53056, 53088, 53080,     0, 
+        1, 49152, 53248, 53249, 53251, 52992, 53056, 53088, 
+    53080,     0,     1, 49152, 53248, 53249, 53251, 52992, 
+    53056, 53088, 53080, 53082,     0,     1, 49152, 53248, 
+    53249, 53251, 52992, 53056, 53088, 53080,     0,     1, 
+    49152, 53248, 53249, 53251, 52992, 53056, 53088, 53089, 
+    53084,     0,     1, 49152, 53248, 53249, 53251, 52992, 
+    53056, 53088, 53089, 53084,     0,     1, 49152, 53248, 
+    53249, 53251, 52992, 53056, 53088, 53089, 53084, 53086, 
+        0,     1, 49152, 53248, 53249, 53251, 52992, 53056, 
+        0,     1, 49152, 53248, 53249, 53251, 52992, 53120, 
+    53088,     0,     1, 49152, 53248, 53249, 53251, 52992, 
+    53120, 53088,     0,     1, 49152, 53248, 53249, 53251, 
+    52992, 53120, 53088, 53090,     0,     1, 49152, 53248, 
+    53249, 53251, 52992, 53120, 53088,     0,     1, 49152, 
+    53248, 53249, 53251, 52992, 53120, 53088, 53092,     0, 
+        1, 49152, 53248, 53249, 53251, 52992, 53120, 53088, 
+    53092,     0,     1, 49152, 53248, 53249, 53251, 52992, 
+    53120, 53088, 53096, 53094,     0,     1, 49152, 53248, 
+    53249, 53251, 52992, 53120, 53088,     0,     1, 49152, 
+    53248, 53249, 53251, 52992, 53120, 53088, 53096,     0, 
+        1, 49152, 53248, 53249, 53251, 52992, 53120, 53088, 
+    53096,     0,     1, 49152, 53248, 53249, 53251, 52992, 
+    53120, 53088, 53096, 53098,     0,     1, 49152, 53248, 
+    53249, 53251, 52992, 53120, 53088, 53096,     0,     1, 
+    49152, 53248, 53249, 53251, 52992, 53120, 53088, 53104, 
+    53100,     0,     1, 49152, 53248, 53249, 53251, 52992, 
+    53120, 53088, 53104, 53100,     0,     1, 49152, 53248, 
+    53249, 53251, 52992, 53120, 53088, 53104, 53105, 53102, 
+        0,     1, 49152, 53248, 53249, 53251, 52992, 53120, 
+    53088,     0,     1, 49152, 53248, 53249, 53251, 52992, 
+    53120, 53121, 53104,     0,     1, 49152, 53248, 53249, 
+    53251, 52992, 53120, 53121, 53104,     0,     1, 49152, 
+    53248, 53249, 53251, 52992, 53120, 53121, 53104, 53106, 
+        0,     1, 49152, 53248, 53249, 53251, 52992, 53120, 
+    53121, 53104,     0,     1, 49152, 53248, 53249, 53251, 
+    52992, 53120, 53121, 53104, 53108,     0,     1, 49152, 
+    53248, 53249, 53251, 52992, 53120, 53121, 53104, 53108, 
+        0,     1, 49152, 53248, 53249, 53251, 52992, 53120, 
+    53121, 53104, 53112, 53110,     0,     1, 49152, 53248, 
+    53249, 53251, 52992, 53120, 53121, 53104,     0,     1, 
+    49152, 53248, 53249, 53251, 52992, 53120, 53121, 53104, 
+    53112,     0,     1, 49152, 53248, 53249, 53251, 52992, 
+    53120, 53121, 53123, 53112,     0,     1, 49152, 53248, 
+    53249, 53251, 52992, 53120, 53121, 53123, 53112, 53114, 
+        0,     1, 49152, 53248, 53249, 53251, 52992, 53120, 
+    53121, 53123, 53112,     0,     1, 49152, 53248, 53249, 
+    53251, 52992, 53120, 53121, 53123, 53112, 53116,     0, 
+        1, 49152, 53248, 53249, 53251, 52992, 53120, 53121, 
+    53123, 53112, 53116,     0,     1, 49152, 53248, 53249, 
+    53251, 52992, 53120, 53121, 53123, 53112, 53116, 53118, 
+        0,     1, 49152, 53248, 53249, 53251, 52992,     0, 
+        1, 49152, 53248, 53249, 53251, 52992, 53120,     0, 
+        1, 49152, 53248, 53249, 53251, 52992, 53120,     0, 
+        1, 49152, 53248, 53249, 53251, 52992, 53120, 53122, 
+        0,     1, 49152, 53248, 53249, 53251, 52992, 53120, 
+        0,     1, 49152, 53248, 53249, 53251, 52992, 53120, 
+    53124,     0,     1, 49152, 53248, 53249, 53251, 52992, 
+    53120, 53124,     0,     1, 49152, 53248, 53249, 53251, 
+    52992, 53120, 53128, 53126,     0,     1, 49152, 53248, 
+    53249, 53251, 53255, 53120,     0,     1, 49152, 53248, 
+    53249, 53251, 53255, 53120, 53128,     0,     1, 49152, 
+    53248, 53249, 53251, 53255, 53120, 53128,     0,     1, 
+    49152, 53248, 53249, 53251, 53255, 53120, 53128, 53130, 
+        0,     1, 49152, 53248, 53249, 53251, 53255, 53120, 
+    53128,     0,     1, 49152, 53248, 53249, 53251, 53255, 
+    53120, 53136, 53132,     0,     1, 49152, 53248, 53249, 
+    53251, 53255, 53120, 53136, 53132,     0,     1, 49152, 
+    53248, 53249, 53251, 53255, 53120, 53136, 53137, 53134, 
+        0,     1, 49152, 53248, 53249, 53251, 53255, 53120, 
+        0,     1, 49152, 53248, 53249, 53251, 53255, 53120, 
+    53136,     0,     1, 49152, 53248, 53249, 53251, 53255, 
+    53120, 53136,     0,     1, 49152, 53248, 53249, 53251, 
+    53255, 53120, 53136, 53138,     0,     1, 49152, 53248, 
+    53249, 53251, 53255, 53120, 53136,     0,     1, 49152, 
+    53248, 53249, 53251, 53255, 53120, 53136, 53140,     0, 
+        1, 49152, 53248, 53249, 53251, 53255, 53120, 53136, 
+    53140,     0,     1, 49152, 53248, 53249, 53251, 53255, 
+    53120, 53136, 53144, 53142,     0,     1, 49152, 53248, 
+    53249, 53251, 53255, 53120, 53136,     0,     1, 49152, 
+    53248, 53249, 53251, 53255, 53120, 53152, 53144,     0, 
+        1, 49152, 53248, 53249, 53251, 53255, 53120, 53152, 
+    53144,     0,     1, 49152, 53248, 53249, 53251, 53255, 
+    53120, 53152, 53144, 53146,     0,     1, 49152, 53248, 
+    53249, 53251, 53255, 53120, 53152, 53144,     0,     1, 
+    49152, 53248, 53249, 53251, 53255, 53120, 53152, 53153, 
+    53148,     0,     1, 49152, 53248, 53249, 53251, 53255, 
+    53120, 53152, 53153, 53148,     0,     1, 49152, 53248, 
+    53249, 53251, 53255, 53120, 53152, 53153, 53148, 53150, 
+        0,     1, 49152, 53248, 53249, 53251, 53255, 53120, 
+        0,     1, 49152, 53248, 53249, 53251, 53255, 53120, 
+    53152,     0,     1, 49152, 53248, 53249, 53251, 53255, 
+    53120, 53152,     0,     1, 49152, 53248, 53249, 53251, 
+    53255, 53120, 53152, 53154,     0,     1, 49152, 53248, 
+    53249, 53251, 53255, 53120, 53152,     0,     1, 49152, 
+    53248, 53249, 53251, 53255, 53120, 53152, 53156,     0, 
+        1, 49152, 53248, 53249, 53251, 53255, 53120, 53152, 
+    53156,     0,     1, 49152, 53248, 53249, 53251, 53255, 
+    53120, 53152, 53160, 53158,     0,     1, 49152, 53248, 
+    53249, 53251, 53255, 53120, 53152,     0,     1, 49152, 
+    53248, 53249, 53251, 53255, 53120, 53152, 53160,     0, 
+        1, 49152, 53248, 53249, 53251, 53255, 53120, 53152, 
+    53160,     0,     1, 49152, 53248, 53249, 53251, 53255, 
+    53120, 53152, 53160, 53162,     0,     1, 49152, 53248, 
+    53249, 53251, 53255, 53120, 53152, 53160,     0,     1, 
+    49152, 53248, 53249, 53251, 53255, 53120, 53152, 53168, 
+    53164,     0,     1, 49152, 53248, 53249, 53251, 53255, 
+    53120, 53152, 53168, 53164,     0,     1, 49152, 53248, 
+    53249, 53251, 53255, 53120, 53152, 53168, 53169, 53166, 
+        0,     1, 49152, 53248, 53249, 53251, 53255, 53120, 
+    53152,     0,     1, 49152, 53248, 53249, 53251, 53255, 
+    53120, 53184, 53168,     0,     1, 49152, 53248, 53249, 
+    53251, 53255, 53120, 53184, 53168,     0,     1, 49152, 
+    53248, 53249, 53251, 53255, 53120, 53184, 53168, 53170, 
+        0,     1, 49152, 53248, 53249, 53251, 53255, 53120, 
+    53184, 53168,     0,     1, 49152, 53248, 53249, 53251, 
+    53255, 53120, 53184, 53168, 53172,     0,     1, 49152, 
+    53248, 53249, 53251, 53255, 53120, 53184, 53168, 53172, 
+        0,     1, 49152, 53248, 53249, 53251, 53255, 53120, 
+    53184, 53168, 53176, 53174,     0,     1, 49152, 53248, 
+    53249, 53251, 53255, 53120, 53184, 53168,     0,     1, 
+    49152, 53248, 53249, 53251, 53255, 53120, 53184, 53185, 
+    53176,     0,     1, 49152, 53248, 53249, 53251, 53255, 
+    53120, 53184, 53185, 53176,     0,     1, 49152, 53248, 
+    53249, 53251, 53255, 53120, 53184, 53185, 53176, 53178, 
+        0,     1, 49152, 53248, 53249, 53251, 53255, 53120, 
+    53184, 53185, 53176,     0,     1, 49152, 53248, 53249, 
+    53251, 53255, 53120, 53184, 53185, 53176, 53180,     0, 
+        1, 49152, 53248, 53249, 53251, 53255, 53120, 53184, 
+    53185, 53187, 53180,     0,     1, 49152, 53248, 53249, 
+    53251, 53255, 53120, 53184, 53185, 53187, 53180, 53182, 
+        0,     1, 49152, 53248, 53249, 53251, 53255, 53120, 
+        0,     1, 49152, 53248, 53249, 53251, 53255, 53120, 
+    53184,     0,     1, 49152, 53248, 53249, 53251, 53255, 
+    53120, 53184,     0,     1, 49152, 53248, 53249, 53251, 
+    53255, 53120, 53184, 53186,     0,     1, 49152, 53248, 
+    53249, 53251, 53255, 53120, 53184,     0,     1, 49152, 
+    53248, 53249, 53251, 53255, 53120, 53184, 53188,     0, 
+        1, 49152, 53248, 53249, 53251, 53255, 53120, 53184, 
+    53188,     0,     1, 49152, 53248, 53249, 53251, 53255, 
+    53120, 53184, 53192, 53190,     0,     1, 49152, 53248, 
+    53249, 53251, 53255, 53120, 53184,     0,     1, 49152, 
+    53248, 53249, 53251, 53255, 53120, 53184, 53192,     0, 
+        1, 49152, 53248, 53249, 53251, 53255, 53120, 53184, 
+    53192,     0,     1, 49152, 53248, 53249, 53251, 53255, 
+    53120, 53184, 53192, 53194,     0,     1, 49152, 53248, 
+    53249, 53251, 53255, 53120, 53184, 53192,     0,     1, 
+    49152, 53248, 53249, 53251, 53255, 53120, 53184, 53200, 
+    53196,     0,     1, 49152, 53248, 53249, 53251, 53255, 
+    53120, 53184, 53200, 53196,     0,     1, 49152, 53248, 
+    53249, 53251, 53255, 53120, 53184, 53200, 53201, 53198, 
+        0,     1, 49152, 53248, 53249, 53251, 53255, 53263, 
+    53184,     0,     1, 49152, 53248, 53249, 53251, 53255, 
+    53263, 53184, 53200,     0,     1, 49152, 53248, 53249, 
+    53251, 53255, 53263, 53184, 53200,     0,     1, 49152, 
+    53248, 53249, 53251, 53255, 53263, 53184, 53200, 53202, 
+        0,     1, 49152, 53248, 53249, 53251, 53255, 53263, 
+    53184, 53200,     0,     1, 49152, 53248, 53249, 53251, 
+    53255, 53263, 53184, 53200, 53204,     0,     1, 49152, 
+    53248, 53249, 53251, 53255, 53263, 53184, 53200, 53204, 
+        0,     1, 49152, 53248, 53249, 53251, 53255, 53263, 
+    53184, 53200, 53208, 53206,     0,     1, 49152, 53248, 
+    53249, 53251, 53255, 53263, 53184, 53200,     0,     1, 
+    49152, 53248, 53249, 53251, 53255, 53263, 53184, 53216, 
+    53208,     0,     1, 49152, 53248, 53249, 53251, 53255, 
+    53263, 53184, 53216, 53208,     0,     1, 49152, 53248, 
+    53249, 53251, 53255, 53263, 53184, 53216, 53208, 53210, 
+        0,     1, 49152, 53248, 53249, 53251, 53255, 53263, 
+    53184, 53216, 53208,     0,     1, 49152, 53248, 53249, 
+    53251, 53255, 53263, 53184, 53216, 53217, 53212,     0, 
+        1, 49152, 53248, 53249, 53251, 53255, 53263, 53184, 
+    53216, 53217, 53212,     0,     1, 49152, 53248, 53249, 
+    53251, 53255, 53263, 53184, 53216, 53217, 53212, 53214, 
+        0,     1, 49152, 53248, 53249, 53251, 53255, 53263, 
+    53184,     0,     1, 49152, 53248, 53249, 53251, 53255, 
+    53263, 53184, 53216,     0,     1, 49152, 53248, 53249, 
+    53251, 53255, 53263, 53184, 53216,     0,     1, 49152, 
+    53248, 53249, 53251, 53255, 53263, 53184, 53216, 53218, 
+        0,     1, 49152, 53248, 53249, 53251, 53255, 53263, 
+    53184, 53216,     0,     1, 49152, 53248, 53249, 53251, 
+    53255, 53263, 53184, 53216, 53220,     0,     1, 49152, 
+    53248, 53249, 53251, 53255, 53263, 53184, 53216, 53220, 
+        0,     1, 49152, 53248, 53249, 53251, 53255, 53263, 
+    53184, 53216, 53224, 53222,     0,     1, 49152, 53248, 
+    53249, 53251, 53255, 53263, 53184, 53216,     0,     1, 
+    49152, 53248, 53249, 53251, 53255, 53263, 53184, 53216, 
+    53224,     0,     1, 49152, 53248, 53249, 53251, 53255, 
+    53263, 53184, 53216, 53224,     0,     1, 49152, 53248, 
+    53249, 53251, 53255, 53263, 53184, 53216, 53224, 53226, 
+        0,     1, 49152, 53248, 53249, 53251, 53255, 53263, 
+    53184, 53216, 53224,     0,     1, 49152, 53248, 53249, 
+    53251, 53255, 53263, 53184, 53216, 53232, 53228,     0, 
+        1, 49152, 53248, 53249, 53251, 53255, 53263, 53184, 
+    53216, 53232, 53228,     0,     1, 49152, 53248, 53249, 
+    53251, 53255, 53263, 53184, 53216, 53232, 53233, 53230, 
+        0,     1, 49152, 53248, 53249, 53251, 53255, 53263, 
+    53184, 53216,     0,     1, 49152, 53248, 53249, 53251, 
+    53255, 53263, 53184, 53216, 53232,     0,     1, 49152, 
+    53248, 53249, 53251, 53255, 53263, 53184, 53216, 53232, 
+        0,     1, 49152, 53248, 53249, 53251, 53255, 53263, 
+    53184, 53216, 53232, 53234,     0,     1, 49152, 53248, 
+    53249, 53251, 53255, 53263, 53184, 53216, 53232,     0, 
+        1, 49152, 53248, 53249, 53251, 53255, 53263, 53184, 
+    53216, 53232, 53236,     0,     1, 49152, 53248, 53249, 
+    53251, 53255, 53263, 53184, 53216, 53232, 53236,     0, 
+        1, 49152, 53248, 53249, 53251, 53255, 53263, 53184, 
+    53216, 53232, 53240, 53238,     0,     1, 49152, 53248, 
+    53249, 53251, 53255, 53263, 53184, 53216, 53232,     0, 
+        1, 49152, 53248, 53249, 53251, 53255, 53263, 53184, 
+    53216, 53232, 53240,     0,     1, 49152, 53248, 53249, 
+    53251, 53255, 53263, 53184, 53216, 53232, 53240,     0, 
+        1, 49152, 53248, 53249, 53251, 53255, 53263, 53184, 
+    53216, 53232, 53240, 53242,     0,     1, 49152, 53248, 
+    53249, 53251, 53255, 53263, 53184, 53216, 53232, 53240, 
+        0,     1, 49152, 53248, 53249, 53251, 53255, 53263, 
+    53184, 53216, 53232, 53240, 53244,     0,     1, 49152, 
+    53248, 53249, 53251, 53255, 53263, 53184, 53216, 53232, 
+    53240, 53244,     0,     1, 49152, 53248, 53249, 53251, 
+    53255, 53263, 53184, 53216, 53232, 53240, 53244, 53246, 
+        0,     1, 49152,     0,     1, 49152, 53248,     0, 
+        1, 49152, 53248,     0,     1, 49152, 53248, 53250, 
+        0,     1, 49152, 53248,     0,     1, 49152, 53248, 
+    53252,     0,     1, 49152, 53248, 53252,     0,     1, 
+    49152, 53248, 53256, 53254,     0,     1, 49152, 53248, 
+        0,     1, 49152, 53248, 53256,     0,     1, 49152, 
+    53248, 53256,     0,     1, 49152, 53248, 53256, 53258, 
+        0,     1, 49152, 53248, 53256,     0,     1, 49152, 
+    53248, 53264, 53260,     0,     1, 49152, 53248, 53264, 
+    53260,     0,     1, 49152, 53248, 53264, 53265, 53262, 
+        0,     1, 49152, 53248,     0,     1, 49152, 53248, 
+    53264,     0,     1, 49152, 53248, 53264,     0,     1, 
+    49152, 53248, 53264, 53266,     0,     1, 49152, 53248, 
+    53264,     0,     1, 49152, 53248, 53264, 53268,     0, 
+        1, 49152, 53248, 53264, 53268,     0,     1, 49152, 
+    53248, 53264, 53272, 53270,     0,     1, 49152, 53248, 
+    53264,     0,     1, 49152, 53248, 53280, 53272,     0, 
+        1, 49152, 53248, 53280, 53272,     0,     1, 49152, 
+    53248, 53280, 53272, 53274,     0,     1, 49152, 53248, 
+    53280, 53272,     0,     1, 49152, 53248, 53280, 53281, 
+    53276,     0,     1, 49152, 53248, 53280, 53281, 53276, 
+        0,     1, 49152, 53248, 53280, 53281, 53276, 53278, 
+        0,     1, 49152, 53248,     0,     1, 49152, 53248, 
+    53280,     0,     1, 49152, 53248, 53280,     0,     1, 
+    49152, 53248, 53280, 53282,     0,     1, 49152, 53248, 
+    53280,     0,     1, 49152, 53248, 53280, 53284,     0, 
+        1, 49152, 53248, 53280, 53284,     0,     1, 49152, 
+    53248, 53280, 53288, 53286,     0,     1, 49152, 53248, 
+    53280,     0,     1, 49152, 53248, 53280, 53288,     0, 
+        1, 49152, 53248, 53280, 53288,     0,     1, 49152, 
+    53248, 53280, 53288, 53290,     0,     1, 49152, 53248, 
+    53280, 53288,     0,     1, 49152, 53248, 53280, 53296, 
+    53292,     0,     1, 49152, 53248, 53280, 53296, 53292, 
+        0,     1, 49152, 53248, 53280, 53296, 53297, 53294, 
+        0,     1, 49152, 53248, 53280,     0,     1, 49152, 
+    53248, 53312, 53296,     0,     1, 49152, 53248, 53312, 
+    53296,     0,     1, 49152, 53248, 53312, 53296, 53298, 
+        0,     1, 49152, 53248, 53312, 53296,     0,     1, 
+    49152, 53248, 53312, 53296, 53300,     0,     1, 49152, 
+    53248, 53312, 53296, 53300,     0,     1, 49152, 53248, 
+    53312, 53296, 53304, 53302,     0,     1, 49152, 53248, 
+    53312, 53296,     0,     1, 49152, 53248, 53312, 53313, 
+    53304,     0,     1, 49152, 53248, 53312, 53313, 53304, 
+        0,     1, 49152, 53248, 53312, 53313, 53304, 53306, 
+        0,     1, 49152, 53248, 53312, 53313, 53304,     0, 
+        1, 49152, 53248, 53312, 53313, 53304, 53308,     0, 
+        1, 49152, 53248, 53312, 53313, 53315, 53308,     0, 
+        1, 49152, 53248, 53312, 53313, 53315, 53308, 53310, 
+        0,     1, 49152, 53248,     0,     1, 49152, 53248, 
+    53312,     0,     1, 49152, 53248, 53312,     0,     1, 
+    49152, 53248, 53312, 53314,     0,     1, 49152, 53248, 
+    53312,     0,     1, 49152, 53248, 53312, 53316,     0, 
+        1, 49152, 53248, 53312, 53316,     0,     1, 49152, 
+    53248, 53312, 53320, 53318,     0,     1, 49152, 53248, 
+    53312,     0,     1, 49152, 53248, 53312, 53320,     0, 
+        1, 49152, 53248, 53312, 53320,     0,     1, 49152, 
+    53248, 53312, 53320, 53322,     0,     1, 49152, 53248, 
+    53312, 53320,     0,     1, 49152, 53248, 53312, 53328, 
+    53324,     0,     1, 49152, 53248, 53312, 53328, 53324, 
+        0,     1, 49152, 53248, 53312, 53328, 53329, 53326, 
+        0,     1, 49152, 53248, 53312,     0,     1, 49152, 
+    53248, 53312, 53328,     0,     1, 49152, 53248, 53312, 
+    53328,     0,     1, 49152, 53248, 53312, 53328, 53330, 
+        0,     1, 49152, 53248, 53312, 53328,     0,     1, 
+    49152, 53248, 53312, 53328, 53332,     0,     1, 49152, 
+    53248, 53312, 53328, 53332,     0,     1, 49152, 53248, 
+    53312, 53328, 53336, 53334,     0,     1, 49152, 53248, 
+    53312, 53328,     0,     1, 49152, 53248, 53312, 53344, 
+    53336,     0,     1, 49152, 53248, 53312, 53344, 53336, 
+        0,     1, 49152, 53248, 53312, 53344, 53336, 53338, 
+        0,     1, 49152, 53248, 53312, 53344, 53336,     0, 
+        1, 49152, 53248, 53312, 53344, 53345, 53340,     0, 
+        1, 49152, 53248, 53312, 53344, 53345, 53340,     0, 
+        1, 49152, 53248, 53312, 53344, 53345, 53340, 53342, 
+        0,     1, 49152, 53248, 53312,     0,     1, 49152, 
+    53248, 53376, 53344,     0,     1, 49152, 53248, 53376, 
+    53344,     0,     1, 49152, 53248, 53376, 53344, 53346, 
+        0,     1, 49152, 53248, 53376, 53344,     0,     1, 
+    49152, 53248, 53376, 53344, 53348,     0,     1, 49152, 
+    53248, 53376, 53344, 53348,     0,     1, 49152, 53248, 
+    53376, 53344, 53352, 53350,     0,     1, 49152, 53248, 
+    53376, 53344,     0,     1, 49152, 53248, 53376, 53344, 
+    53352,     0,     1, 49152, 53248, 53376, 53344, 53352, 
+        0,     1, 49152, 53248, 53376, 53344, 53352, 53354, 
+        0,     1, 49152, 53248, 53376, 53344, 53352,     0, 
+        1, 49152, 53248, 53376, 53344, 53360, 53356,     0, 
+        1, 49152, 53248, 53376, 53344, 53360, 53356,     0, 
+        1, 49152, 53248, 53376, 53344, 53360, 53361, 53358, 
+        0,     1, 49152, 53248, 53376, 53344,     0,     1, 
+    49152, 53248, 53376, 53377, 53360,     0,     1, 49152, 
+    53248, 53376, 53377, 53360,     0,     1, 49152, 53248, 
+    53376, 53377, 53360, 53362,     0,     1, 49152, 53248, 
+    53376, 53377, 53360,     0,     1, 49152, 53248, 53376, 
+    53377, 53360, 53364,     0,     1, 49152, 53248, 53376, 
+    53377, 53360, 53364,     0,     1, 49152, 53248, 53376, 
+    53377, 53360, 53368, 53366,     0,     1, 49152, 53248, 
+    53376, 53377, 53360,     0,     1, 49152, 53248, 53376, 
+    53377, 53360, 53368,     0,     1, 49152, 53248, 53376, 
+    53377, 53379, 53368,     0,     1, 49152, 53248, 53376, 
+    53377, 53379, 53368, 53370,     0,     1, 49152, 53248, 
+    53376, 53377, 53379, 53368,     0,     1, 49152, 53248, 
+    53376, 53377, 53379, 53368, 53372,     0,     1, 49152, 
+    53248, 53376, 53377, 53379, 53368, 53372,     0,     1, 
+    49152, 53248, 53376, 53377, 53379, 53368, 53372, 53374, 
+        0,     1, 49152, 53248,     0,     1, 49152, 53248, 
+    53376,     0,     1, 49152, 53248, 53376,     0,     1, 
+    49152, 53248, 53376, 53378,     0,     1, 49152, 53248, 
+    53376,     0,     1, 49152, 53248, 53376, 53380,     0, 
+        1, 49152, 53248, 53376, 53380,     0,     1, 49152, 
+    53248, 53376, 53384, 53382,     0,     1, 49152, 53248, 
+    53376,     0,     1, 49152, 53248, 53376, 53384,     0, 
+        1, 49152, 53248, 53376, 53384,     0,     1, 49152, 
+    53248, 53376, 53384, 53386,     0,     1, 49152, 53248, 
+    53376, 53384,     0,     1, 49152, 53248, 53376, 53392, 
+    53388,     0,     1, 49152, 53248, 53376, 53392, 53388, 
+        0,     1, 49152, 53248, 53376, 53392, 53393, 53390, 
+        0,     1, 49152, 53248, 53376,     0,     1, 49152, 
+    53248, 53376, 53392,     0,     1, 49152, 53248, 53376, 
+    53392,     0,     1, 49152, 53248, 53376, 53392, 53394, 
+        0,     1, 49152, 53248, 53376, 53392,     0,     1, 
+    49152, 53248, 53376, 53392, 53396,     0,     1, 49152, 
+    53248, 53376, 53392, 53396,     0,     1, 49152, 53248, 
+    53376, 53392, 53400, 53398,     0,     1, 49152, 53248, 
+    53376, 53392,     0,     1, 49152, 53248, 53376, 53408, 
+    53400,     0,     1, 49152, 53248, 53376, 53408, 53400, 
+        0,     1, 49152, 53248, 53376, 53408, 53400, 53402, 
+        0,     1, 49152, 53248, 53376, 53408, 53400,     0, 
+        1, 49152, 53248, 53376, 53408, 53409, 53404,     0, 
+        1, 49152, 53248, 53376, 53408, 53409, 53404,     0, 
+        1, 49152, 53248, 53376, 53408, 53409, 53404, 53406, 
+        0,     1, 49152, 53248, 53376,     0,     1, 49152, 
+    53248, 53376, 53408,     0,     1, 49152, 53248, 53376, 
+    53408,     0,     1, 49152, 53248, 53376, 53408, 53410, 
+        0,     1, 49152, 53248, 53376, 53408,     0,     1, 
+    49152, 53248, 53376, 53408, 53412,     0,     1, 49152, 
+    53248, 53376, 53408, 53412,     0,     1, 49152, 53248, 
+    53376, 53408, 53416, 53414,     0,     1, 49152, 53248, 
+    53376, 53408,     0,     1, 49152, 53248, 53376, 53408, 
+    53416,     0,     1, 49152, 53248, 53376, 53408, 53416, 
+        0,     1, 49152, 53248, 53376, 53408, 53416, 53418, 
+        0,     1, 49152, 53248, 53376, 53408, 53416,     0, 
+        1, 49152, 53248, 53376, 53408, 53424, 53420,     0, 
+        1, 49152, 53248, 53376, 53408, 53424, 53420,     0, 
+        1, 49152, 53248, 53376, 53408, 53424, 53425, 53422, 
+        0,     1, 49152, 53248, 53376, 53408,     0,     1, 
+    49152, 53248, 53376, 53440, 53424,     0,     1, 49152, 
+    53248, 53376, 53440, 53424,     0,     1, 49152, 53248, 
+    53376, 53440, 53424, 53426,     0,     1, 49152, 53248, 
+    53376, 53440, 53424,     0,     1, 49152, 53248, 53376, 
+    53440, 53424, 53428,     0,     1, 49152, 53248, 53376, 
+    53440, 53424, 53428,     0,     1, 49152, 53248, 53376, 
+    53440, 53424, 53432, 53430,     0,     1, 49152, 53248, 
+    53376, 53440, 53424,     0,     1, 49152, 53248, 53376, 
+    53440, 53441, 53432,     0,     1, 49152, 53248, 53376, 
+    53440, 53441, 53432,     0,     1, 49152, 53248, 53376, 
+    53440, 53441, 53432, 53434,     0,     1, 49152, 53248, 
+    53376, 53440, 53441, 53432,     0,     1, 49152, 53248, 
+    53376, 53440, 53441, 53432, 53436,     0,     1, 49152, 
+    53248, 53376, 53440, 53441, 53443, 53436,     0,     1, 
+    49152, 53248, 53376, 53440, 53441, 53443, 53436, 53438, 
+        0,     1, 49152, 53248, 53376,     0,     1, 49152, 
+    53248, 53504, 53440,     0,     1, 49152, 53248, 53504, 
+    53440,     0,     1, 49152, 53248, 53504, 53440, 53442, 
+        0,     1, 49152, 53248, 53504, 53440,     0,     1, 
+    49152, 53248, 53504, 53440, 53444,     0,     1, 49152, 
+    53248, 53504, 53440, 53444,     0,     1, 49152, 53248, 
+    53504, 53440, 53448, 53446,     0,     1, 49152, 53248, 
+    53504, 53440,     0,     1, 49152, 53248, 53504, 53440, 
+    53448,     0,     1, 49152, 53248, 53504, 53440, 53448, 
+        0,     1, 49152, 53248, 53504, 53440, 53448, 53450, 
+        0,     1, 49152, 53248, 53504, 53440, 53448,     0, 
+        1, 49152, 53248, 53504, 53440, 53456, 53452,     0, 
+        1, 49152, 53248, 53504, 53440, 53456, 53452,     0, 
+        1, 49152, 53248, 53504, 53440, 53456, 53457, 53454, 
+        0,     1, 49152, 53248, 53504, 53440,     0,     1, 
+    49152, 53248, 53504, 53440, 53456,     0,     1, 49152, 
+    53248, 53504, 53440, 53456,     0,     1, 49152, 53248, 
+    53504, 53440, 53456, 53458,     0,     1, 49152, 53248, 
+    53504, 53440, 53456,     0,     1, 49152, 53248, 53504, 
+    53440, 53456, 53460,     0,     1, 49152, 53248, 53504, 
+    53440, 53456, 53460,     0,     1, 49152, 53248, 53504, 
+    53440, 53456, 53464, 53462,     0,     1, 49152, 53248, 
+    53504, 53440, 53456,     0,     1, 49152, 53248, 53504, 
+    53440, 53472, 53464,     0,     1, 49152, 53248, 53504, 
+    53440, 53472, 53464,     0,     1, 49152, 53248, 53504, 
+    53440, 53472, 53464, 53466,     0,     1, 49152, 53248, 
+    53504, 53440, 53472, 53464,     0,     1, 49152, 53248, 
+    53504, 53440, 53472, 53473, 53468,     0,     1, 49152, 
+    53248, 53504, 53440, 53472, 53473, 53468,     0,     1, 
+    49152, 53248, 53504, 53440, 53472, 53473, 53468, 53470, 
+        0,     1, 49152, 53248, 53504, 53440,     0,     1, 
+    49152, 53248, 53504, 53505, 53472,     0,     1, 49152, 
+    53248, 53504, 53505, 53472,     0,     1, 49152, 53248, 
+    53504, 53505, 53472, 53474,     0,     1, 49152, 53248, 
+    53504, 53505, 53472,     0,     1, 49152, 53248, 53504, 
+    53505, 53472, 53476,     0,     1, 49152, 53248, 53504, 
+    53505, 53472, 53476,     0,     1, 49152, 53248, 53504, 
+    53505, 53472, 53480, 53478,     0,     1, 49152, 53248, 
+    53504, 53505, 53472,     0,     1, 49152, 53248, 53504, 
+    53505, 53472, 53480,     0,     1, 49152, 53248, 53504, 
+    53505, 53472, 53480,     0,     1, 49152, 53248, 53504, 
+    53505, 53472, 53480, 53482,     0,     1, 49152, 53248, 
+    53504, 53505, 53472, 53480,     0,     1, 49152, 53248, 
+    53504, 53505, 53472, 53488, 53484,     0,     1, 49152, 
+    53248, 53504, 53505, 53472, 53488, 53484,     0,     1, 
+    49152, 53248, 53504, 53505, 53472, 53488, 53489, 53486, 
+        0,     1, 49152, 53248, 53504, 53505, 53472,     0, 
+        1, 49152, 53248, 53504, 53505, 53472, 53488,     0, 
+        1, 49152, 53248, 53504, 53505, 53507, 53488,     0, 
+        1, 49152, 53248, 53504, 53505, 53507, 53488, 53490, 
+        0,     1, 49152, 53248, 53504, 53505, 53507, 53488, 
+        0,     1, 49152, 53248, 53504, 53505, 53507, 53488, 
+    53492,     0,     1, 49152, 53248, 53504, 53505, 53507, 
+    53488, 53492,     0,     1, 49152, 53248, 53504, 53505, 
+    53507, 53488, 53496, 53494,     0,     1, 49152, 53248, 
+    53504, 53505, 53507, 53488,     0,     1, 49152, 53248, 
+    53504, 53505, 53507, 53488, 53496,     0,     1, 49152, 
+    53248, 53504, 53505, 53507, 53488, 53496,     0,     1, 
+    49152, 53248, 53504, 53505, 53507, 53488, 53496, 53498, 
+        0,     1, 49152, 53248, 53504, 53505, 53507, 53511, 
+    53496,     0,     1, 49152, 53248, 53504, 53505, 53507, 
+    53511, 53496, 53500,     0,     1, 49152, 53248, 53504, 
+    53505, 53507, 53511, 53496, 53500,     0,     1, 49152, 
+    53248, 53504, 53505, 53507, 53511, 53496, 53500, 53502, 
+        0,     1, 49152, 53248,     0,     1, 49152, 53248, 
+    53504,     0,     1, 49152, 53248, 53504,     0,     1, 
+    49152, 53248, 53504, 53506,     0,     1, 49152, 53248, 
+    53504,     0,     1, 49152, 53248, 53504, 53508,     0, 
+        1, 49152, 53248, 53504, 53508,     0,     1, 49152, 
+    53248, 53504, 53512, 53510,     0,     1, 49152, 53248, 
+    53504,     0,     1, 49152, 53248, 53504, 53512,     0, 
+        1, 49152, 53248, 53504, 53512,     0,     1, 49152, 
+    53248, 53504, 53512, 53514,     0,     1, 49152, 53248, 
+    53504, 53512,     0,     1, 49152, 53248, 53504, 53520, 
+    53516,     0,     1, 49152, 53248, 53504, 53520, 53516, 
+        0,     1, 49152, 53248, 53504, 53520, 53521, 53518, 
+        0,     1, 49152, 53248, 53504,     0,     1, 49152, 
+    53248, 53504, 53520,     0,     1, 49152, 53248, 53504, 
+    53520,     0,     1, 49152, 53248, 53504, 53520, 53522, 
+        0,     1, 49152, 53248, 53504, 53520,     0,     1, 
+    49152, 53248, 53504, 53520, 53524,     0,     1, 49152, 
+    53248, 53504, 53520, 53524,     0,     1, 49152, 53248, 
+    53504, 53520, 53528, 53526,     0,     1, 49152, 53248, 
+    53504, 53520,     0,     1, 49152, 53248, 53504, 53536, 
+    53528,     0,     1, 49152, 53248, 53504, 53536, 53528, 
+        0,     1, 49152, 53248, 53504, 53536, 53528, 53530, 
+        0,     1, 49152, 53248, 53504, 53536, 53528,     0, 
+        1, 49152, 53248, 53504, 53536, 53537, 53532,     0, 
+        1, 49152, 53248, 53504, 53536, 53537, 53532,     0, 
+        1, 49152, 53248, 53504, 53536, 53537, 53532, 53534, 
+        0,     1, 49152, 53248, 53504,     0,     1, 49152, 
+    53248, 53504, 53536,     0,     1, 49152, 53248, 53504, 
+    53536,     0,     1, 49152, 53248, 53504, 53536, 53538, 
+        0,     1, 49152, 53248, 53504, 53536,     0,     1, 
+    49152, 53248, 53504, 53536, 53540,     0,     1, 49152, 
+    53248, 53504, 53536, 53540,     0,     1, 49152, 53248, 
+    53504, 53536, 53544, 53542,     0,     1, 49152, 53248, 
+    53504, 53536,     0,     1, 49152, 53248, 53504, 53536, 
+    53544,     0,     1, 49152, 53248, 53504, 53536, 53544, 
+        0,     1, 49152, 53248, 53504, 53536, 53544, 53546, 
+        0,     1, 49152, 53248, 53504, 53536, 53544,     0, 
+        1, 49152, 53248, 53504, 53536, 53552, 53548,     0, 
+        1, 49152, 53248, 53504, 53536, 53552, 53548,     0, 
+        1, 49152, 53248, 53504, 53536, 53552, 53553, 53550, 
+        0,     1, 49152, 53248, 53504, 53536,     0,     1, 
+    49152, 53248, 53504, 53568, 53552,     0,     1, 49152, 
+    53248, 53504, 53568, 53552,     0,     1, 49152, 53248, 
+    53504, 53568, 53552, 53554,     0,     1, 49152, 53248, 
+    53504, 53568, 53552,     0,     1, 49152, 53248, 53504, 
+    53568, 53552, 53556,     0,     1, 49152, 53248, 53504, 
+    53568, 53552, 53556,     0,     1, 49152, 53248, 53504, 
+    53568, 53552, 53560, 53558,     0,     1, 49152, 53248, 
+    53504, 53568, 53552,     0,     1, 49152, 53248, 53504, 
+    53568, 53569, 53560,     0,     1, 49152, 53248, 53504, 
+    53568, 53569, 53560,     0,     1, 49152, 53248, 53504, 
+    53568, 53569, 53560, 53562,     0,     1, 49152, 53248, 
+    53504, 53568, 53569, 53560,     0,     1, 49152, 53248, 
+    53504, 53568, 53569, 53560, 53564,     0,     1, 49152, 
+    53248, 53504, 53568, 53569, 53571, 53564,     0,     1, 
+    49152, 53248, 53504, 53568, 53569, 53571, 53564, 53566, 
+        0,     1, 49152, 53248, 53504,     0,     1, 49152, 
+    53248, 53504, 53568,     0,     1, 49152, 53248, 53504, 
+    53568,     0,     1, 49152, 53248, 53504, 53568, 53570, 
+        0,     1, 49152, 53248, 53504, 53568,     0,     1, 
+    49152, 53248, 53504, 53568, 53572,     0,     1, 49152, 
+    53248, 53504, 53568, 53572,     0,     1, 49152, 53248, 
+    53504, 53568, 53576, 53574,     0,     1, 49152, 53248, 
+    53504, 53568,     0,     1, 49152, 53248, 53504, 53568, 
+    53576,     0,     1, 49152, 53248, 53504, 53568, 53576, 
+        0,     1, 49152, 53248, 53504, 53568, 53576, 53578, 
+        0,     1, 49152, 53248, 53504, 53568, 53576,     0, 
+        1, 49152, 53248, 53504, 53568, 53584, 53580,     0, 
+        1, 49152, 53248, 53504, 53568, 53584, 53580,     0, 
+        1, 49152, 53248, 53504, 53568, 53584, 53585, 53582, 
+        0,     1, 49152, 53248, 53504, 53568,     0,     1, 
+    49152, 53248, 53504, 53568, 53584,     0,     1, 49152, 
+    53248, 53504, 53568, 53584,     0,     1, 49152, 53248, 
+    53504, 53568, 53584, 53586,     0,     1, 49152, 53248, 
+    53504, 53568, 53584,     0,     1, 49152, 53248, 53504, 
+    53568, 53584, 53588,     0,     1, 49152, 53248, 53504, 
+    53568, 53584, 53588,     0,     1, 49152, 53248, 53504, 
+    53568, 53584, 53592, 53590,     0,     1, 49152, 53248, 
+    53504, 53568, 53584,     0,     1, 49152, 53248, 53504, 
+    53568, 53600, 53592,     0,     1, 49152, 53248, 53504, 
+    53568, 53600, 53592,     0,     1, 49152, 53248, 53504, 
+    53568, 53600, 53592, 53594,     0,     1, 49152, 53248, 
+    53504, 53568, 53600, 53592,     0,     1, 49152, 53248, 
+    53504, 53568, 53600, 53601, 53596,     0,     1, 49152, 
+    53248, 53504, 53568, 53600, 53601, 53596,     0,     1, 
+    49152, 53248, 53504, 53568, 53600, 53601, 53596, 53598, 
+        0,     1, 49152, 53248, 53504, 53568,     0,     1, 
+    49152, 53248, 53504, 53632, 53600,     0,     1, 49152, 
+    53248, 53504, 53632, 53600,     0,     1, 49152, 53248, 
+    53504, 53632, 53600, 53602,     0,     1, 49152, 53248, 
+    53504, 53632, 53600,     0,     1, 49152, 53248, 53504, 
+    53632, 53600, 53604,     0,     1, 49152, 53248, 53504, 
+    53632, 53600, 53604,     0,     1, 49152, 53248, 53504, 
+    53632, 53600, 53608, 53606,     0,     1, 49152, 53248, 
+    53504, 53632, 53600,     0,     1, 49152, 53248, 53504, 
+    53632, 53600, 53608,     0,     1, 49152, 53248, 53504, 
+    53632, 53600, 53608,     0,     1, 49152, 53248, 53504, 
+    53632, 53600, 53608, 53610,     0,     1, 49152, 53248, 
+    53504, 53632, 53600, 53608,     0,     1, 49152, 53248, 
+    53504, 53632, 53600, 53616, 53612,     0,     1, 49152, 
+    53248, 53504, 53632, 53600, 53616, 53612,     0,     1, 
+    49152, 53248, 53504, 53632, 53600, 53616, 53617, 53614, 
+        0,     1, 49152, 53248, 53504, 53632, 53600,     0, 
+        1, 49152, 53248, 53504, 53632, 53633, 53616,     0, 
+        1, 49152, 53248, 53504, 53632, 53633, 53616,     0, 
+        1, 49152, 53248, 53504, 53632, 53633, 53616, 53618, 
+        0,     1, 49152, 53248, 53504, 53632, 53633, 53616, 
+        0,     1, 49152, 53248, 53504, 53632, 53633, 53616, 
+    53620,     0,     1, 49152, 53248, 53504, 53632, 53633, 
+    53616, 53620,     0,     1, 49152, 53248, 53504, 53632, 
+    53633, 53616, 53624, 53622,     0,     1, 49152, 53248, 
+    53504, 53632, 53633, 53616,     0,     1, 49152, 53248, 
+    53504, 53632, 53633, 53616, 53624,     0,     1, 49152, 
+    53248, 53504, 53632, 53633, 53635, 53624,     0,     1, 
+    49152, 53248, 53504, 53632, 53633, 53635, 53624, 53626, 
+        0,     1, 49152, 53248, 53504, 53632, 53633, 53635, 
+    53624,     0,     1, 49152, 53248, 53504, 53632, 53633, 
+    53635, 53624, 53628,     0,     1, 49152, 53248, 53504, 
+    53632, 53633, 53635, 53624, 53628,     0,     1, 49152, 
+    53248, 53504, 53632, 53633, 53635, 53624, 53628, 53630, 
+        0,     1, 49152, 53248, 53504,     0,     1, 49152, 
+    53248, 53760, 53632,     0,     1, 49152, 53248, 53760, 
+    53632,     0,     1, 49152, 53248, 53760, 53632, 53634, 
+        0,     1, 49152, 53248, 53760, 53632,     0,     1, 
+    49152, 53248, 53760, 53632, 53636,     0,     1, 49152, 
+    53248, 53760, 53632, 53636,     0,     1, 49152, 53248, 
+    53760, 53632, 53640, 53638,     0,     1, 49152, 53248, 
+    53760, 53632,     0,     1, 49152, 53248, 53760, 53632, 
+    53640,     0,     1, 49152, 53248, 53760, 53632, 53640, 
+        0,     1, 49152, 53248, 53760, 53632, 53640, 53642, 
+        0,     1, 49152, 53248, 53760, 53632, 53640,     0, 
+        1, 49152, 53248, 53760, 53632, 53648, 53644,     0, 
+        1, 49152, 53248, 53760, 53632, 53648, 53644,     0, 
+        1, 49152, 53248, 53760, 53632, 53648, 53649, 53646, 
+        0,     1, 49152, 53248, 53760, 53632,     0,     1, 
+    49152, 53248, 53760, 53632, 53648,     0,     1, 49152, 
+    53248, 53760, 53632, 53648,     0,     1, 49152, 53248, 
+    53760, 53632, 53648, 53650,     0,     1, 49152, 53248, 
+    53760, 53632, 53648,     0,     1, 49152, 53248, 53760, 
+    53632, 53648, 53652,     0,     1, 49152, 53248, 53760, 
+    53632, 53648, 53652,     0,     1, 49152, 53248, 53760, 
+    53632, 53648, 53656, 53654,     0,     1, 49152, 53248, 
+    53760, 53632, 53648,     0,     1, 49152, 53248, 53760, 
+    53632, 53664, 53656,     0,     1, 49152, 53248, 53760, 
+    53632, 53664, 53656,     0,     1, 49152, 53248, 53760, 
+    53632, 53664, 53656, 53658,     0,     1, 49152, 53248, 
+    53760, 53632, 53664, 53656,     0,     1, 49152, 53248, 
+    53760, 53632, 53664, 53665, 53660,     0,     1, 49152, 
+    53248, 53760, 53632, 53664, 53665, 53660,     0,     1, 
+    49152, 53248, 53760, 53632, 53664, 53665, 53660, 53662, 
+        0,     1, 49152, 53248, 53760, 53632,     0,     1, 
+    49152, 53248, 53760, 53632, 53664,     0,     1, 49152, 
+    53248, 53760, 53632, 53664,     0,     1, 49152, 53248, 
+    53760, 53632, 53664, 53666,     0,     1, 49152, 53248, 
+    53760, 53632, 53664,     0,     1, 49152, 53248, 53760, 
+    53632, 53664, 53668,     0,     1, 49152, 53248, 53760, 
+    53632, 53664, 53668,     0,     1, 49152, 53248, 53760, 
+    53632, 53664, 53672, 53670,     0,     1, 49152, 53248, 
+    53760, 53632, 53664,     0,     1, 49152, 53248, 53760, 
+    53632, 53664, 53672,     0,     1, 49152, 53248, 53760, 
+    53632, 53664, 53672,     0,     1, 49152, 53248, 53760, 
+    53632, 53664, 53672, 53674,     0,     1, 49152, 53248, 
+    53760, 53632, 53664, 53672,     0,     1, 49152, 53248, 
+    53760, 53632, 53664, 53680, 53676,     0,     1, 49152, 
+    53248, 53760, 53632, 53664, 53680, 53676,     0,     1, 
+    49152, 53248, 53760, 53632, 53664, 53680, 53681, 53678, 
+        0,     1, 49152, 53248, 53760, 53632, 53664,     0, 
+        1, 49152, 53248, 53760, 53632, 53696, 53680,     0, 
+        1, 49152, 53248, 53760, 53632, 53696, 53680,     0, 
+        1, 49152, 53248, 53760, 53632, 53696, 53680, 53682, 
+        0,     1, 49152, 53248, 53760, 53632, 53696, 53680, 
+        0,     1, 49152, 53248, 53760, 53632, 53696, 53680, 
+    53684,     0,     1, 49152, 53248, 53760, 53632, 53696, 
+    53680, 53684,     0,     1, 49152, 53248, 53760, 53632, 
+    53696, 53680, 53688, 53686,     0,     1, 49152, 53248, 
+    53760, 53632, 53696, 53680,     0,     1, 49152, 53248, 
+    53760, 53632, 53696, 53697, 53688,     0,     1, 49152, 
+    53248, 53760, 53632, 53696, 53697, 53688,     0,     1, 
+    49152, 53248, 53760, 53632, 53696, 53697, 53688, 53690, 
+        0,     1, 49152, 53248, 53760, 53632, 53696, 53697, 
+    53688,     0,     1, 49152, 53248, 53760, 53632, 53696, 
+    53697, 53688, 53692,     0,     1, 49152, 53248, 53760, 
+    53632, 53696, 53697, 53699, 53692,     0,     1, 49152, 
+    53248, 53760, 53632, 53696, 53697, 53699, 53692, 53694, 
+        0,     1, 49152, 53248, 53760, 53632,     0,     1, 
+    49152, 53248, 53760, 53761, 53696,     0,     1, 49152, 
+    53248, 53760, 53761, 53696,     0,     1, 49152, 53248, 
+    53760, 53761, 53696, 53698,     0,     1, 49152, 53248, 
+    53760, 53761, 53696,     0,     1, 49152, 53248, 53760, 
+    53761, 53696, 53700,     0,     1, 49152, 53248, 53760, 
+    53761, 53696, 53700,     0,     1, 49152, 53248, 53760, 
+    53761, 53696, 53704, 53702,     0,     1, 49152, 53248, 
+    53760, 53761, 53696,     0,     1, 49152, 53248, 53760, 
+    53761, 53696, 53704,     0,     1, 49152, 53248, 53760, 
+    53761, 53696, 53704,     0,     1, 49152, 53248, 53760, 
+    53761, 53696, 53704, 53706,     0,     1, 49152, 53248, 
+    53760, 53761, 53696, 53704,     0,     1, 49152, 53248, 
+    53760, 53761, 53696, 53712, 53708,     0,     1, 49152, 
+    53248, 53760, 53761, 53696, 53712, 53708,     0,     1, 
+    49152, 53248, 53760, 53761, 53696, 53712, 53713, 53710, 
+        0,     1, 49152, 53248, 53760, 53761, 53696,     0, 
+        1, 49152, 53248, 53760, 53761, 53696, 53712,     0, 
+        1, 49152, 53248, 53760, 53761, 53696, 53712,     0, 
+        1, 49152, 53248, 53760, 53761, 53696, 53712, 53714, 
+        0,     1, 49152, 53248, 53760, 53761, 53696, 53712, 
+        0,     1, 49152, 53248, 53760, 53761, 53696, 53712, 
+    53716,     0,     1, 49152, 53248, 53760, 53761, 53696, 
+    53712, 53716,     0,     1, 49152, 53248, 53760, 53761, 
+    53696, 53712, 53720, 53718,     0,     1, 49152, 53248, 
+    53760, 53761, 53696, 53712,     0,     1, 49152, 53248, 
+    53760, 53761, 53696, 53728, 53720,     0,     1, 49152, 
+    53248, 53760, 53761, 53696, 53728, 53720,     0,     1, 
+    49152, 53248, 53760, 53761, 53696, 53728, 53720, 53722, 
+        0,     1, 49152, 53248, 53760, 53761, 53696, 53728, 
+    53720,     0,     1, 49152, 53248, 53760, 53761, 53696, 
+    53728, 53729, 53724,     0,     1, 49152, 53248, 53760, 
+    53761, 53696, 53728, 53729, 53724,     0,     1, 49152, 
+    53248, 53760, 53761, 53696, 53728, 53729, 53724, 53726, 
+        0,     1, 49152, 53248, 53760, 53761, 53696,     0, 
+        1, 49152, 53248, 53760, 53761, 53696, 53728,     0, 
+        1, 49152, 53248, 53760, 53761, 53763, 53728,     0, 
+        1, 49152, 53248, 53760, 53761, 53763, 53728, 53730, 
+        0,     1, 49152, 53248, 53760, 53761, 53763, 53728, 
+        0,     1, 49152, 53248, 53760, 53761, 53763, 53728, 
+    53732,     0,     1, 49152, 53248, 53760, 53761, 53763, 
+    53728, 53732,     0,     1, 49152, 53248, 53760, 53761, 
+    53763, 53728, 53736, 53734,     0,     1, 49152, 53248, 
+    53760, 53761, 53763, 53728,     0,     1, 49152, 53248, 
+    53760, 53761, 53763, 53728, 53736,     0,     1, 49152, 
+    53248, 53760, 53761, 53763, 53728, 53736,     0,     1, 
+    49152, 53248, 53760, 53761, 53763, 53728, 53736, 53738, 
+        0,     1, 49152, 53248, 53760, 53761, 53763, 53728, 
+    53736,     0,     1, 49152, 53248, 53760, 53761, 53763, 
+    53728, 53744, 53740,     0,     1, 49152, 53248, 53760, 
+    53761, 53763, 53728, 53744, 53740,     0,     1, 49152, 
+    53248, 53760, 53761, 53763, 53728, 53744, 53745, 53742, 
+        0,     1, 49152, 53248, 53760, 53761, 53763, 53728, 
+        0,     1, 49152, 53248, 53760, 53761, 53763, 53728, 
+    53744,     0,     1, 49152, 53248, 53760, 53761, 53763, 
+    53728, 53744,     0,     1, 49152, 53248, 53760, 53761, 
+    53763, 53728, 53744, 53746,     0,     1, 49152, 53248, 
+    53760, 53761, 53763, 53767, 53744,     0,     1, 49152, 
+    53248, 53760, 53761, 53763, 53767, 53744, 53748,     0, 
+        1, 49152, 53248, 53760, 53761, 53763, 53767, 53744, 
+    53748,     0,     1, 49152, 53248, 53760, 53761, 53763, 
+    53767, 53744, 53752, 53750,     0,     1, 49152, 53248, 
+    53760, 53761, 53763, 53767, 53744,     0,     1, 49152, 
+    53248, 53760, 53761, 53763, 53767, 53744, 53752,     0, 
+        1, 49152, 53248, 53760, 53761, 53763, 53767, 53744, 
+    53752,     0,     1, 49152, 53248, 53760, 53761, 53763, 
+    53767, 53744, 53752, 53754,     0,     1, 49152, 53248, 
+    53760, 53761, 53763, 53767, 53744, 53752,     0,     1, 
+    49152, 53248, 53760, 53761, 53763, 53767, 53744, 53752, 
+    53756,     0,     1, 49152, 53248, 53760, 53761, 53763, 
+    53767, 53744, 53752, 53756,     0,     1, 49152, 53248, 
+    53760, 53761, 53763, 53767, 53744, 53752, 53756, 53758, 
+        0,     1, 49152, 53248,     0,     1, 49152, 53248, 
+    53760,     0,     1, 49152, 53248, 53760,     0,     1, 
+    49152, 53248, 53760, 53762,     0,     1, 49152, 53248, 
+    53760,     0,     1, 49152, 53248, 53760, 53764,     0, 
+        1, 49152, 53248, 53760, 53764,     0,     1, 49152, 
+    53248, 53760, 53768, 53766,     0,     1, 49152, 53248, 
+    53760,     0,     1, 49152, 53248, 53760, 53768,     0, 
+        1, 49152, 53248, 53760, 53768,     0,     1, 49152, 
+    53248, 53760, 53768, 53770,     0,     1, 49152, 53248, 
+    53760, 53768,     0,     1, 49152, 53248, 53760, 53776, 
+    53772,     0,     1, 49152, 53248, 53760, 53776, 53772, 
+        0,     1, 49152, 53248, 53760, 53776, 53777, 53774, 
+        0,     1, 49152, 53248, 53760,     0,     1, 49152, 
+    53248, 53760, 53776,     0,     1, 49152, 53248, 53760, 
+    53776,     0,     1, 49152, 53248, 53760, 53776, 53778, 
+        0,     1, 49152, 53248, 53760, 53776,     0,     1, 
+    49152, 53248, 53760, 53776, 53780,     0,     1, 49152, 
+    53248, 53760, 53776, 53780,     0,     1, 49152, 53248, 
+    53760, 53776, 53784, 53782,     0,     1, 49152, 53248, 
+    53760, 53776,     0,     1, 49152, 53248, 53760, 53792, 
+    53784,     0,     1, 49152, 53248, 53760, 53792, 53784, 
+        0,     1, 49152, 53248, 53760, 53792, 53784, 53786, 
+        0,     1, 49152, 53248, 53760, 53792, 53784,     0, 
+        1, 49152, 53248, 53760, 53792, 53793, 53788,     0, 
+        1, 49152, 53248, 53760, 53792, 53793, 53788,     0, 
+        1, 49152, 53248, 53760, 53792, 53793, 53788, 53790, 
+        0,     1, 49152, 53248, 53760,     0,     1, 49152, 
+    53248, 53760, 53792,     0,     1, 49152, 53248, 53760, 
+    53792,     0,     1, 49152, 53248, 53760, 53792, 53794, 
+        0,     1, 49152, 53248, 53760, 53792,     0,     1, 
+    49152, 53248, 53760, 53792, 53796,     0,     1, 49152, 
+    53248, 53760, 53792, 53796,     0,     1, 49152, 53248, 
+    53760, 53792, 53800, 53798,     0,     1, 49152, 53248, 
+    53760, 53792,     0,     1, 49152, 53248, 53760, 53792, 
+    53800,     0,     1, 49152, 53248, 53760, 53792, 53800, 
+        0,     1, 49152, 53248, 53760, 53792, 53800, 53802, 
+        0,     1, 49152, 53248, 53760, 53792, 53800,     0, 
+        1, 49152, 53248, 53760, 53792, 53808, 53804,     0, 
+        1, 49152, 53248, 53760, 53792, 53808, 53804,     0, 
+        1, 49152, 53248, 53760, 53792, 53808, 53809, 53806, 
+        0,     1, 49152, 53248, 53760, 53792,     0,     1, 
+    49152, 53248, 53760, 53824, 53808,     0,     1, 49152, 
+    53248, 53760, 53824, 53808,     0,     1, 49152, 53248, 
+    53760, 53824, 53808, 53810,     0,     1, 49152, 53248, 
+    53760, 53824, 53808,     0,     1, 49152, 53248, 53760, 
+    53824, 53808, 53812,     0,     1, 49152, 53248, 53760, 
+    53824, 53808, 53812,     0,     1, 49152, 53248, 53760, 
+    53824, 53808, 53816, 53814,     0,     1, 49152, 53248, 
+    53760, 53824, 53808,     0,     1, 49152, 53248, 53760, 
+    53824, 53825, 53816,     0,     1, 49152, 53248, 53760, 
+    53824, 53825, 53816,     0,     1, 49152, 53248, 53760, 
+    53824, 53825, 53816, 53818,     0,     1, 49152, 53248, 
+    53760, 53824, 53825, 53816,     0,     1, 49152, 53248, 
+    53760, 53824, 53825, 53816, 53820,     0,     1, 49152, 
+    53248, 53760, 53824, 53825, 53827, 53820,     0,     1, 
+    49152, 53248, 53760, 53824, 53825, 53827, 53820, 53822, 
+        0,     1, 49152, 53248, 53760,     0,     1, 49152, 
+    53248, 53760, 53824,     0,     1, 49152, 53248, 53760, 
+    53824,     0,     1, 49152, 53248, 53760, 53824, 53826, 
+        0,     1, 49152, 53248, 53760, 53824,     0,     1, 
+    49152, 53248, 53760, 53824, 53828,     0,     1, 49152, 
+    53248, 53760, 53824, 53828,     0,     1, 49152, 53248, 
+    53760, 53824, 53832, 53830,     0,     1, 49152, 53248, 
+    53760, 53824,     0,     1, 49152, 53248, 53760, 53824, 
+    53832,     0,     1, 49152, 53248, 53760, 53824, 53832, 
+        0,     1, 49152, 53248, 53760, 53824, 53832, 53834, 
+        0,     1, 49152, 53248, 53760, 53824, 53832,     0, 
+        1, 49152, 53248, 53760, 53824, 53840, 53836,     0, 
+        1, 49152, 53248, 53760, 53824, 53840, 53836,     0, 
+        1, 49152, 53248, 53760, 53824, 53840, 53841, 53838, 
+        0,     1, 49152, 53248, 53760, 53824,     0,     1, 
+    49152, 53248, 53760, 53824, 53840,     0,     1, 49152, 
+    53248, 53760, 53824, 53840,     0,     1, 49152, 53248, 
+    53760, 53824, 53840, 53842,     0,     1, 49152, 53248, 
+    53760, 53824, 53840,     0,     1, 49152, 53248, 53760, 
+    53824, 53840, 53844,     0,     1, 49152, 53248, 53760, 
+    53824, 53840, 53844,     0,     1, 49152, 53248, 53760, 
+    53824, 53840, 53848, 53846,     0,     1, 49152, 53248, 
+    53760, 53824, 53840,     0,     1, 49152, 53248, 53760, 
+    53824, 53856, 53848,     0,     1, 49152, 53248, 53760, 
+    53824, 53856, 53848,     0,     1, 49152, 53248, 53760, 
+    53824, 53856, 53848, 53850,     0,     1, 49152, 53248, 
+    53760, 53824, 53856, 53848,     0,     1, 49152, 53248, 
+    53760, 53824, 53856, 53857, 53852,     0,     1, 49152, 
+    53248, 53760, 53824, 53856, 53857, 53852,     0,     1, 
+    49152, 53248, 53760, 53824, 53856, 53857, 53852, 53854, 
+        0,     1, 49152, 53248, 53760, 53824,     0,     1, 
+    49152, 53248, 53760, 53888, 53856,     0,     1, 49152, 
+    53248, 53760, 53888, 53856,     0,     1, 49152, 53248, 
+    53760, 53888, 53856, 53858,     0,     1, 49152, 53248, 
+    53760, 53888, 53856,     0,     1, 49152, 53248, 53760, 
+    53888, 53856, 53860,     0,     1, 49152, 53248, 53760, 
+    53888, 53856, 53860,     0,     1, 49152, 53248, 53760, 
+    53888, 53856, 53864, 53862,     0,     1, 49152, 53248, 
+    53760, 53888, 53856,     0,     1, 49152, 53248, 53760, 
+    53888, 53856, 53864,     0,     1, 49152, 53248, 53760, 
+    53888, 53856, 53864,     0,     1, 49152, 53248, 53760, 
+    53888, 53856, 53864, 53866,     0,     1, 49152, 53248, 
+    53760, 53888, 53856, 53864,     0,     1, 49152, 53248, 
+    53760, 53888, 53856, 53872, 53868,     0,     1, 49152, 
+    53248, 53760, 53888, 53856, 53872, 53868,     0,     1, 
+    49152, 53248, 53760, 53888, 53856, 53872, 53873, 53870, 
+        0,     1, 49152, 53248, 53760, 53888, 53856,     0, 
+        1, 49152, 53248, 53760, 53888, 53889, 53872,     0, 
+        1, 49152, 53248, 53760, 53888, 53889, 53872,     0, 
+        1, 49152, 53248, 53760, 53888, 53889, 53872, 53874, 
+        0,     1, 49152, 53248, 53760, 53888, 53889, 53872, 
+        0,     1, 49152, 53248, 53760, 53888, 53889, 53872, 
+    53876,     0,     1, 49152, 53248, 53760, 53888, 53889, 
+    53872, 53876,     0,     1, 49152, 53248, 53760, 53888, 
+    53889, 53872, 53880, 53878,     0,     1, 49152, 53248, 
+    53760, 53888, 53889, 53872,     0,     1, 49152, 53248, 
+    53760, 53888, 53889, 53872, 53880,     0,     1, 49152, 
+    53248, 53760, 53888, 53889, 53891, 53880,     0,     1, 
+    49152, 53248, 53760, 53888, 53889, 53891, 53880, 53882, 
+        0,     1, 49152, 53248, 53760, 53888, 53889, 53891, 
+    53880,     0,     1, 49152, 53248, 53760, 53888, 53889, 
+    53891, 53880, 53884,     0,     1, 49152, 53248, 53760, 
+    53888, 53889, 53891, 53880, 53884,     0,     1, 49152, 
+    53248, 53760, 53888, 53889, 53891, 53880, 53884, 53886, 
+        0,     1, 49152, 53248, 53760,     0,     1, 49152, 
+    53248, 53760, 53888,     0,     1, 49152, 53248, 53760, 
+    53888,     0,     1, 49152, 53248, 53760, 53888, 53890, 
+        0,     1, 49152, 53248, 53760, 53888,     0,     1, 
+    49152, 53248, 53760, 53888, 53892,     0,     1, 49152, 
+    53248, 53760, 53888, 53892,     0,     1, 49152, 53248, 
+    53760, 53888, 53896, 53894,     0,     1, 49152, 53248, 
+    53760, 53888,     0,     1, 49152, 53248, 53760, 53888, 
+    53896,     0,     1, 49152, 53248, 53760, 53888, 53896, 
+        0,     1, 49152, 53248, 53760, 53888, 53896, 53898, 
+        0,     1, 49152, 53248, 53760, 53888, 53896,     0, 
+        1, 49152, 53248, 53760, 53888, 53904, 53900,     0, 
+        1, 49152, 53248, 53760, 53888, 53904, 53900,     0, 
+        1, 49152, 53248, 53760, 53888, 53904, 53905, 53902, 
+        0,     1, 49152, 53248, 53760, 53888,     0,     1, 
+    49152, 53248, 53760, 53888, 53904,     0,     1, 49152, 
+    53248, 53760, 53888, 53904,     0,     1, 49152, 53248, 
+    53760, 53888, 53904, 53906,     0,     1, 49152, 53248, 
+    53760, 53888, 53904,     0,     1, 49152, 53248, 53760, 
+    53888, 53904, 53908,     0,     1, 49152, 53248, 53760, 
+    53888, 53904, 53908,     0,     1, 49152, 53248, 53760, 
+    53888, 53904, 53912, 53910,     0,     1, 49152, 53248, 
+    53760, 53888, 53904,     0,     1, 49152, 53248, 53760, 
+    53888, 53920, 53912,     0,     1, 49152, 53248, 53760, 
+    53888, 53920, 53912,     0,     1, 49152, 53248, 53760, 
+    53888, 53920, 53912, 53914,     0,     1, 49152, 53248, 
+    53760, 53888, 53920, 53912,     0,     1, 49152, 53248, 
+    53760, 53888, 53920, 53921, 53916,     0,     1, 49152, 
+    53248, 53760, 53888, 53920, 53921, 53916,     0,     1, 
+    49152, 53248, 53760, 53888, 53920, 53921, 53916, 53918, 
+        0,     1, 49152, 53248, 53760, 53888,     0,     1, 
+    49152, 53248, 53760, 53888, 53920,     0,     1, 49152, 
+    53248, 53760, 53888, 53920,     0,     1, 49152, 53248, 
+    53760, 53888, 53920, 53922,     0,     1, 49152, 53248, 
+    53760, 53888, 53920,     0,     1, 49152, 53248, 53760, 
+    53888, 53920, 53924,     0,     1, 49152, 53248, 53760, 
+    53888, 53920, 53924,     0,     1, 49152, 53248, 53760, 
+    53888, 53920, 53928, 53926,     0,     1, 49152, 53248, 
+    53760, 53888, 53920,     0,     1, 49152, 53248, 53760, 
+    53888, 53920, 53928,     0,     1, 49152, 53248, 53760, 
+    53888, 53920, 53928,     0,     1, 49152, 53248, 53760, 
+    53888, 53920, 53928, 53930,     0,     1, 49152, 53248, 
+    53760, 53888, 53920, 53928,     0,     1, 49152, 53248, 
+    53760, 53888, 53920, 53936, 53932,     0,     1, 49152, 
+    53248, 53760, 53888, 53920, 53936, 53932,     0,     1, 
+    49152, 53248, 53760, 53888, 53920, 53936, 53937, 53934, 
+        0,     1, 49152, 53248, 53760, 53888, 53920,     0, 
+        1, 49152, 53248, 53760, 53888, 53952, 53936,     0, 
+        1, 49152, 53248, 53760, 53888, 53952, 53936,     0, 
+        1, 49152, 53248, 53760, 53888, 53952, 53936, 53938, 
+        0,     1, 49152, 53248, 53760, 53888, 53952, 53936, 
+        0,     1, 49152, 53248, 53760, 53888, 53952, 53936, 
+    53940,     0,     1, 49152, 53248, 53760, 53888, 53952, 
+    53936, 53940,     0,     1, 49152, 53248, 53760, 53888, 
+    53952, 53936, 53944, 53942,     0,     1, 49152, 53248, 
+    53760, 53888, 53952, 53936,     0,     1, 49152, 53248, 
+    53760, 53888, 53952, 53953, 53944,     0,     1, 49152, 
+    53248, 53760, 53888, 53952, 53953, 53944,     0,     1, 
+    49152, 53248, 53760, 53888, 53952, 53953, 53944, 53946, 
+        0,     1, 49152, 53248, 53760, 53888, 53952, 53953, 
+    53944,     0,     1, 49152, 53248, 53760, 53888, 53952, 
+    53953, 53944, 53948,     0,     1, 49152, 53248, 53760, 
+    53888, 53952, 53953, 53955, 53948,     0,     1, 49152, 
+    53248, 53760, 53888, 53952, 53953, 53955, 53948, 53950, 
+        0,     1, 49152, 53248, 53760, 53888,     0,     1, 
+    49152, 53248, 53760, 54016, 53952,     0,     1, 49152, 
+    53248, 53760, 54016, 53952,     0,     1, 49152, 53248, 
+    53760, 54016, 53952, 53954,     0,     1, 49152, 53248, 
+    53760, 54016, 53952,     0,     1, 49152, 53248, 53760, 
+    54016, 53952, 53956,     0,     1, 49152, 53248, 53760, 
+    54016, 53952, 53956,     0,     1, 49152, 53248, 53760, 
+    54016, 53952, 53960, 53958,     0,     1, 49152, 53248, 
+    53760, 54016, 53952,     0,     1, 49152, 53248, 53760, 
+    54016, 53952, 53960,     0,     1, 49152, 53248, 53760, 
+    54016, 53952, 53960,     0,     1, 49152, 53248, 53760, 
+    54016, 53952, 53960, 53962,     0,     1, 49152, 53248, 
+    53760, 54016, 53952, 53960,     0,     1, 49152, 53248, 
+    53760, 54016, 53952, 53968, 53964,     0,     1, 49152, 
+    53248, 53760, 54016, 53952, 53968, 53964,     0,     1, 
+    49152, 53248, 53760, 54016, 53952, 53968, 53969, 53966, 
+        0,     1, 49152, 53248, 53760, 54016, 53952,     0, 
+        1, 49152, 53248, 53760, 54016, 53952, 53968,     0, 
+        1, 49152, 53248, 53760, 54016, 53952, 53968,     0, 
+        1, 49152, 53248, 53760, 54016, 53952, 53968, 53970, 
+        0,     1, 49152, 53248, 53760, 54016, 53952, 53968, 
+        0,     1, 49152, 53248, 53760, 54016, 53952, 53968, 
+    53972,     0,     1, 49152, 53248, 53760, 54016, 53952, 
+    53968, 53972,     0,     1, 49152, 53248, 53760, 54016, 
+    53952, 53968, 53976, 53974,     0,     1, 49152, 53248, 
+    53760, 54016, 53952, 53968,     0,     1, 49152, 53248, 
+    53760, 54016, 53952, 53984, 53976,     0,     1, 49152, 
+    53248, 53760, 54016, 53952, 53984, 53976,     0,     1, 
+    49152, 53248, 53760, 54016, 53952, 53984, 53976, 53978, 
+        0,     1, 49152, 53248, 53760, 54016, 53952, 53984, 
+    53976,     0,     1, 49152, 53248, 53760, 54016, 53952, 
+    53984, 53985, 53980,     0,     1, 49152, 53248, 53760, 
+    54016, 53952, 53984, 53985, 53980,     0,     1, 49152, 
+    53248, 53760, 54016, 53952, 53984, 53985, 53980, 53982, 
+        0,     1, 49152, 53248, 53760, 54016, 53952,     0, 
+        1, 49152, 53248, 53760, 54016, 54017, 53984,     0, 
+        1, 49152, 53248, 53760, 54016, 54017, 53984,     0, 
+        1, 49152, 53248, 53760, 54016, 54017, 53984, 53986, 
+        0,     1, 49152, 53248, 53760, 54016, 54017, 53984, 
+        0,     1, 49152, 53248, 53760, 54016, 54017, 53984, 
+    53988,     0,     1, 49152, 53248, 53760, 54016, 54017, 
+    53984, 53988,     0,     1, 49152, 53248, 53760, 54016, 
+    54017, 53984, 53992, 53990,     0,     1, 49152, 53248, 
+    53760, 54016, 54017, 53984,     0,     1, 49152, 53248, 
+    53760, 54016, 54017, 53984, 53992,     0,     1, 49152, 
+    53248, 53760, 54016, 54017, 53984, 53992,     0,     1, 
+    49152, 53248, 53760, 54016, 54017, 53984, 53992, 53994, 
+        0,     1, 49152, 53248, 53760, 54016, 54017, 53984, 
+    53992,     0,     1, 49152, 53248, 53760, 54016, 54017, 
+    53984, 54000, 53996,     0,     1, 49152, 53248, 53760, 
+    54016, 54017, 53984, 54000, 53996,     0,     1, 49152, 
+    53248, 53760, 54016, 54017, 53984, 54000, 54001, 53998, 
+        0,     1, 49152, 53248, 53760, 54016, 54017, 53984, 
+        0,     1, 49152, 53248, 53760, 54016, 54017, 53984, 
+    54000,     0,     1, 49152, 53248, 53760, 54016, 54017, 
+    54019, 54000,     0,     1, 49152, 53248, 53760, 54016, 
+    54017, 54019, 54000, 54002,     0,     1, 49152, 53248, 
+    53760, 54016, 54017, 54019, 54000,     0,     1, 49152, 
+    53248, 53760, 54016, 54017, 54019, 54000, 54004,     0, 
+        1, 49152, 53248, 53760, 54016, 54017, 54019, 54000, 
+    54004,     0,     1, 49152, 53248, 53760, 54016, 54017, 
+    54019, 54000, 54008, 54006,     0,     1, 49152, 53248, 
+    53760, 54016, 54017, 54019, 54000,     0,     1, 49152, 
+    53248, 53760, 54016, 54017, 54019, 54000, 54008,     0, 
+        1, 49152, 53248, 53760, 54016, 54017, 54019, 54000, 
+    54008,     0,     1, 49152, 53248, 53760, 54016, 54017, 
+    54019, 54000, 54008, 54010,     0,     1, 49152, 53248, 
+    53760, 54016, 54017, 54019, 54023, 54008,     0,     1, 
+    49152, 53248, 53760, 54016, 54017, 54019, 54023, 54008, 
+    54012,     0,     1, 49152, 53248, 53760, 54016, 54017, 
+    54019, 54023, 54008, 54012,     0,     1, 49152, 53248, 
+    53760, 54016, 54017, 54019, 54023, 54008, 54012, 54014, 
+        0,     1, 49152, 53248, 53760,     0,     1, 49152, 
+    53248, 54272, 54016,     0,     1, 49152, 53248, 54272, 
+    54016,     0,     1, 49152, 53248, 54272, 54016, 54018, 
+        0,     1, 49152, 53248, 54272, 54016,     0,     1, 
+    49152, 53248, 54272, 54016, 54020,     0,     1, 49152, 
+    53248, 54272, 54016, 54020,     0,     1, 49152, 53248, 
+    54272, 54016, 54024, 54022,     0,     1, 49152, 53248, 
+    54272, 54016,     0,     1, 49152, 53248, 54272, 54016, 
+    54024,     0,     1, 49152, 53248, 54272, 54016, 54024, 
+        0,     1, 49152, 53248, 54272, 54016, 54024, 54026, 
+        0,     1, 49152, 53248, 54272, 54016, 54024,     0, 
+        1, 49152, 53248, 54272, 54016, 54032, 54028,     0, 
+        1, 49152, 53248, 54272, 54016, 54032, 54028,     0, 
+        1, 49152, 53248, 54272, 54016, 54032, 54033, 54030, 
+        0,     1, 49152, 53248, 54272, 54016,     0,     1, 
+    49152, 53248, 54272, 54016, 54032,     0,     1, 49152, 
+    53248, 54272, 54016, 54032,     0,     1, 49152, 53248, 
+    54272, 54016, 54032, 54034,     0,     1, 49152, 53248, 
+    54272, 54016, 54032,     0,     1, 49152, 53248, 54272, 
+    54016, 54032, 54036,     0,     1, 49152, 53248, 54272, 
+    54016, 54032, 54036,     0,     1, 49152, 53248, 54272, 
+    54016, 54032, 54040, 54038,     0,     1, 49152, 53248, 
+    54272, 54016, 54032,     0,     1, 49152, 53248, 54272, 
+    54016, 54048, 54040,     0,     1, 49152, 53248, 54272, 
+    54016, 54048, 54040,     0,     1, 49152, 53248, 54272, 
+    54016, 54048, 54040, 54042,     0,     1, 49152, 53248, 
+    54272, 54016, 54048, 54040,     0,     1, 49152, 53248, 
+    54272, 54016, 54048, 54049, 54044,     0,     1, 49152, 
+    53248, 54272, 54016, 54048, 54049, 54044,     0,     1, 
+    49152, 53248, 54272, 54016, 54048, 54049, 54044, 54046, 
+        0,     1, 49152, 53248, 54272, 54016,     0,     1, 
+    49152, 53248, 54272, 54016, 54048,     0,     1, 49152, 
+    53248, 54272, 54016, 54048,     0,     1, 49152, 53248, 
+    54272, 54016, 54048, 54050,     0,     1, 49152, 53248, 
+    54272, 54016, 54048,     0,     1, 49152, 53248, 54272, 
+    54016, 54048, 54052,     0,     1, 49152, 53248, 54272, 
+    54016, 54048, 54052,     0,     1, 49152, 53248, 54272, 
+    54016, 54048, 54056, 54054,     0,     1, 49152, 53248, 
+    54272, 54016, 54048,     0,     1, 49152, 53248, 54272, 
+    54016, 54048, 54056,     0,     1, 49152, 53248, 54272, 
+    54016, 54048, 54056,     0,     1, 49152, 53248, 54272, 
+    54016, 54048, 54056, 54058,     0,     1, 49152, 53248, 
+    54272, 54016, 54048, 54056,     0,     1, 49152, 53248, 
+    54272, 54016, 54048, 54064, 54060,     0,     1, 49152, 
+    53248, 54272, 54016, 54048, 54064, 54060,     0,     1, 
+    49152, 53248, 54272, 54016, 54048, 54064, 54065, 54062, 
+        0,     1, 49152, 53248, 54272, 54016, 54048,     0, 
+        1, 49152, 53248, 54272, 54016, 54080, 54064,     0, 
+        1, 49152, 53248, 54272, 54016, 54080, 54064,     0, 
+        1, 49152, 53248, 54272, 54016, 54080, 54064, 54066, 
+        0,     1, 49152, 53248, 54272, 54016, 54080, 54064, 
+        0,     1, 49152, 53248, 54272, 54016, 54080, 54064, 
+    54068,     0,     1, 49152, 53248, 54272, 54016, 54080, 
+    54064, 54068,     0,     1, 49152, 53248, 54272, 54016, 
+    54080, 54064, 54072, 54070,     0,     1, 49152, 53248, 
+    54272, 54016, 54080, 54064,     0,     1, 49152, 53248, 
+    54272, 54016, 54080, 54081, 54072,     0,     1, 49152, 
+    53248, 54272, 54016, 54080, 54081, 54072,     0,     1, 
+    49152, 53248, 54272, 54016, 54080, 54081, 54072, 54074, 
+        0,     1, 49152, 53248, 54272, 54016, 54080, 54081, 
+    54072,     0,     1, 49152, 53248, 54272, 54016, 54080, 
+    54081, 54072, 54076,     0,     1, 49152, 53248, 54272, 
+    54016, 54080, 54081, 54083, 54076,     0,     1, 49152, 
+    53248, 54272, 54016, 54080, 54081, 54083, 54076, 54078, 
+        0,     1, 49152, 53248, 54272, 54016,     0,     1, 
+    49152, 53248, 54272, 54016, 54080,     0,     1, 49152, 
+    53248, 54272, 54016, 54080,     0,     1, 49152, 53248, 
+    54272, 54016, 54080, 54082,     0,     1, 49152, 53248, 
+    54272, 54016, 54080,     0,     1, 49152, 53248, 54272, 
+    54016, 54080, 54084,     0,     1, 49152, 53248, 54272, 
+    54016, 54080, 54084,     0,     1, 49152, 53248, 54272, 
+    54016, 54080, 54088, 54086,     0,     1, 49152, 53248, 
+    54272, 54016, 54080,     0,     1, 49152, 53248, 54272, 
+    54016, 54080, 54088,     0,     1, 49152, 53248, 54272, 
+    54016, 54080, 54088,     0,     1, 49152, 53248, 54272, 
+    54016, 54080, 54088, 54090,     0,     1, 49152, 53248, 
+    54272, 54016, 54080, 54088,     0,     1, 49152, 53248, 
+    54272, 54016, 54080, 54096, 54092,     0,     1, 49152, 
+    53248, 54272, 54016, 54080, 54096, 54092,     0,     1, 
+    49152, 53248, 54272, 54016, 54080, 54096, 54097, 54094, 
+        0,     1, 49152, 53248, 54272, 54016, 54080,     0, 
+        1, 49152, 53248, 54272, 54016, 54080, 54096,     0, 
+        1, 49152, 53248, 54272, 54016, 54080, 54096,     0, 
+        1, 49152, 53248, 54272, 54016, 54080, 54096, 54098, 
+        0,     1, 49152, 53248, 54272, 54016, 54080, 54096, 
+        0,     1, 49152, 53248, 54272, 54016, 54080, 54096, 
+    54100,     0,     1, 49152, 53248, 54272, 54016, 54080, 
+    54096, 54100,     0,     1, 49152, 53248, 54272, 54016, 
+    54080, 54096, 54104, 54102,     0,     1, 49152, 53248, 
+    54272, 54016, 54080, 54096,     0,     1, 49152, 53248, 
+    54272, 54016, 54080, 54112, 54104,     0,     1, 49152, 
+    53248, 54272, 54016, 54080, 54112, 54104,     0,     1, 
+    49152, 53248, 54272, 54016, 54080, 54112, 54104, 54106, 
+        0,     1, 49152, 53248, 54272, 54016, 54080, 54112, 
+    54104,     0,     1, 49152, 53248, 54272, 54016, 54080, 
+    54112, 54113, 54108,     0,     1, 49152, 53248, 54272, 
+    54016, 54080, 54112, 54113, 54108,     0,     1, 49152, 
+    53248, 54272, 54016, 54080, 54112, 54113, 54108, 54110, 
+        0,     1, 49152, 53248, 54272, 54016, 54080,     0, 
+        1, 49152, 53248, 54272, 54016, 54144, 54112,     0, 
+        1, 49152, 53248, 54272, 54016, 54144, 54112,     0, 
+        1, 49152, 53248, 54272, 54016, 54144, 54112, 54114, 
+        0,     1, 49152, 53248, 54272, 54016, 54144, 54112, 
+        0,     1, 49152, 53248, 54272, 54016, 54144, 54112, 
+    54116,     0,     1, 49152, 53248, 54272, 54016, 54144, 
+    54112, 54116,     0,     1, 49152, 53248, 54272, 54016, 
+    54144, 54112, 54120, 54118,     0,     1, 49152, 53248, 
+    54272, 54016, 54144, 54112,     0,     1, 49152, 53248, 
+    54272, 54016, 54144, 54112, 54120,     0,     1, 49152, 
+    53248, 54272, 54016, 54144, 54112, 54120,     0,     1, 
+    49152, 53248, 54272, 54016, 54144, 54112, 54120, 54122, 
+        0,     1, 49152, 53248, 54272, 54016, 54144, 54112, 
+    54120,     0,     1, 49152, 53248, 54272, 54016, 54144, 
+    54112, 54128, 54124,     0,     1, 49152, 53248, 54272, 
+    54016, 54144, 54112, 54128, 54124,     0,     1, 49152, 
+    53248, 54272, 54016, 54144, 54112, 54128, 54129, 54126, 
+        0,     1, 49152, 53248, 54272, 54016, 54144, 54112, 
+        0,     1, 49152, 53248, 54272, 54016, 54144, 54145, 
+    54128,     0,     1, 49152, 53248, 54272, 54016, 54144, 
+    54145, 54128,     0,     1, 49152, 53248, 54272, 54016, 
+    54144, 54145, 54128, 54130,     0,     1, 49152, 53248, 
+    54272, 54016, 54144, 54145, 54128,     0,     1, 49152, 
+    53248, 54272, 54016, 54144, 54145, 54128, 54132,     0, 
+        1, 49152, 53248, 54272, 54016, 54144, 54145, 54128, 
+    54132,     0,     1, 49152, 53248, 54272, 54016, 54144, 
+    54145, 54128, 54136, 54134,     0,     1, 49152, 53248, 
+    54272, 54016, 54144, 54145, 54128,     0,     1, 49152, 
+    53248, 54272, 54016, 54144, 54145, 54128, 54136,     0, 
+        1, 49152, 53248, 54272, 54016, 54144, 54145, 54147, 
+    54136,     0,     1, 49152, 53248, 54272, 54016, 54144, 
+    54145, 54147, 54136, 54138,     0,     1, 49152, 53248, 
+    54272, 54016, 54144, 54145, 54147, 54136,     0,     1, 
+    49152, 53248, 54272, 54016, 54144, 54145, 54147, 54136, 
+    54140,     0,     1, 49152, 53248, 54272, 54016, 54144, 
+    54145, 54147, 54136, 54140,     0,     1, 49152, 53248, 
+    54272, 54016, 54144, 54145, 54147, 54136, 54140, 54142, 
+        0,     1, 49152, 53248, 54272, 54016,     0,     1, 
+    49152, 53248, 54272, 54016, 54144,     0,     1, 49152, 
+    53248, 54272, 54273, 54144,     0,     1, 49152, 53248, 
+    54272, 54273, 54144, 54146,     0,     1, 49152, 53248, 
+    54272, 54273, 54144,     0,     1, 49152, 53248, 54272, 
+    54273, 54144, 54148,     0,     1, 49152, 53248, 54272, 
+    54273, 54144, 54148,     0,     1, 49152, 53248, 54272, 
+    54273, 54144, 54152, 54150,     0,     1, 49152, 53248, 
+    54272, 54273, 54144,     0,     1, 49152, 53248, 54272, 
+    54273, 54144, 54152,     0,     1, 49152, 53248, 54272, 
+    54273, 54144, 54152,     0,     1, 49152, 53248, 54272, 
+    54273, 54144, 54152, 54154,     0,     1, 49152, 53248, 
+    54272, 54273, 54144, 54152,     0,     1, 49152, 53248, 
+    54272, 54273, 54144, 54160, 54156,     0,     1, 49152, 
+    53248, 54272, 54273, 54144, 54160, 54156,     0,     1, 
+    49152, 53248, 54272, 54273, 54144, 54160, 54161, 54158, 
+        0,     1, 49152, 53248, 54272, 54273, 54144,     0, 
+        1, 49152, 53248, 54272, 54273, 54144, 54160,     0, 
+        1, 49152, 53248, 54272, 54273, 54144, 54160,     0, 
+        1, 49152, 53248, 54272, 54273, 54144, 54160, 54162, 
+        0,     1, 49152, 53248, 54272, 54273, 54144, 54160, 
+        0,     1, 49152, 53248, 54272, 54273, 54144, 54160, 
+    54164,     0,     1, 49152, 53248, 54272, 54273, 54144, 
+    54160, 54164,     0,     1, 49152, 53248, 54272, 54273, 
+    54144, 54160, 54168, 54166,     0,     1, 49152, 53248, 
+    54272, 54273, 54144, 54160,     0,     1, 49152, 53248, 
+    54272, 54273, 54144, 54176, 54168,     0,     1, 49152, 
+    53248, 54272, 54273, 54144, 54176, 54168,     0,     1, 
+    49152, 53248, 54272, 54273, 54144, 54176, 54168, 54170, 
+        0,     1, 49152, 53248, 54272, 54273, 54144, 54176, 
+    54168,     0,     1, 49152, 53248, 54272, 54273, 54144, 
+    54176, 54177, 54172,     0,     1, 49152, 53248, 54272, 
+    54273, 54144, 54176, 54177, 54172,     0,     1, 49152, 
+    53248, 54272, 54273, 54144, 54176, 54177, 54172, 54174, 
+        0,     1, 49152, 53248, 54272, 54273, 54144,     0, 
+        1, 49152, 53248, 54272, 54273, 54144, 54176,     0, 
+        1, 49152, 53248, 54272, 54273, 54144, 54176,     0, 
+        1, 49152, 53248, 54272, 54273, 54144, 54176, 54178, 
+        0,     1, 49152, 53248, 54272, 54273, 54144, 54176, 
+        0,     1, 49152, 53248, 54272, 54273, 54144, 54176, 
+    54180,     0,     1, 49152, 53248, 54272, 54273, 54144, 
+    54176, 54180,     0,     1, 49152, 53248, 54272, 54273, 
+    54144, 54176, 54184, 54182,     0,     1, 49152, 53248, 
+    54272, 54273, 54144, 54176,     0,     1, 49152, 53248, 
+    54272, 54273, 54144, 54176, 54184,     0,     1, 49152, 
+    53248, 54272, 54273, 54144, 54176, 54184,     0,     1, 
+    49152, 53248, 54272, 54273, 54144, 54176, 54184, 54186, 
+        0,     1, 49152, 53248, 54272, 54273, 54144, 54176, 
+    54184,     0,     1, 49152, 53248, 54272, 54273, 54144, 
+    54176, 54192, 54188,     0,     1, 49152, 53248, 54272, 
+    54273, 54144, 54176, 54192, 54188,     0,     1, 49152, 
+    53248, 54272, 54273, 54144, 54176, 54192, 54193, 54190, 
+        0,     1, 49152, 53248, 54272, 54273, 54144, 54176, 
+        0,     1, 49152, 53248, 54272, 54273, 54144, 54208, 
+    54192,     0,     1, 49152, 53248, 54272, 54273, 54144, 
+    54208, 54192,     0,     1, 49152, 53248, 54272, 54273, 
+    54144, 54208, 54192, 54194,     0,     1, 49152, 53248, 
+    54272, 54273, 54144, 54208, 54192,     0,     1, 49152, 
+    53248, 54272, 54273, 54144, 54208, 54192, 54196,     0, 
+        1, 49152, 53248, 54272, 54273, 54144, 54208, 54192, 
+    54196,     0,     1, 49152, 53248, 54272, 54273, 54144, 
+    54208, 54192, 54200, 54198,     0,     1, 49152, 53248, 
+    54272, 54273, 54144, 54208, 54192,     0,     1, 49152, 
+    53248, 54272, 54273, 54144, 54208, 54209, 54200,     0, 
+        1, 49152, 53248, 54272, 54273, 54144, 54208, 54209, 
+    54200,     0,     1, 49152, 53248, 54272, 54273, 54144, 
+    54208, 54209, 54200, 54202,     0,     1, 49152, 53248, 
+    54272, 54273, 54144, 54208, 54209, 54200,     0,     1, 
+    49152, 53248, 54272, 54273, 54144, 54208, 54209, 54200, 
+    54204,     0,     1, 49152, 53248, 54272, 54273, 54144, 
+    54208, 54209, 54211, 54204,     0,     1, 49152, 53248, 
+    54272, 54273, 54144, 54208, 54209, 54211, 54204, 54206, 
+        0,     1, 49152, 53248, 54272, 54273, 54144,     0, 
+        1, 49152, 53248, 54272, 54273, 54144, 54208,     0, 
+        1, 49152, 53248, 54272, 54273, 54144, 54208,     0, 
+        1, 49152, 53248, 54272, 54273, 54144, 54208, 54210, 
+        0,     1, 49152, 53248, 54272, 54273, 54275, 54208, 
+        0,     1, 49152, 53248, 54272, 54273, 54275, 54208, 
+    54212,     0,     1, 49152, 53248, 54272, 54273, 54275, 
+    54208, 54212,     0,     1, 49152, 53248, 54272, 54273, 
+    54275, 54208, 54216, 54214,     0,     1, 49152, 53248, 
+    54272, 54273, 54275, 54208,     0,     1, 49152, 53248, 
+    54272, 54273, 54275, 54208, 54216,     0,     1, 49152, 
+    53248, 54272, 54273, 54275, 54208, 54216,     0,     1, 
+    49152, 53248, 54272, 54273, 54275, 54208, 54216, 54218, 
+        0,     1, 49152, 53248, 54272, 54273, 54275, 54208, 
+    54216,     0,     1, 49152, 53248, 54272, 54273, 54275, 
+    54208, 54224, 54220,     0,     1, 49152, 53248, 54272, 
+    54273, 54275, 54208, 54224, 54220,     0,     1, 49152, 
+    53248, 54272, 54273, 54275, 54208, 54224, 54225, 54222, 
+        0,     1, 49152, 53248, 54272, 54273, 54275, 54208, 
+        0,     1, 49152, 53248, 54272, 54273, 54275, 54208, 
+    54224,     0,     1, 49152, 53248, 54272, 54273, 54275, 
+    54208, 54224,     0,     1, 49152, 53248, 54272, 54273, 
+    54275, 54208, 54224, 54226,     0,     1, 49152, 53248, 
+    54272, 54273, 54275, 54208, 54224,     0,     1, 49152, 
+    53248, 54272, 54273, 54275, 54208, 54224, 54228,     0, 
+        1, 49152, 53248, 54272, 54273, 54275, 54208, 54224, 
+    54228,     0,     1, 49152, 53248, 54272, 54273, 54275, 
+    54208, 54224, 54232, 54230,     0,     1, 49152, 53248, 
+    54272, 54273, 54275, 54208, 54224,     0,     1, 49152, 
+    53248, 54272, 54273, 54275, 54208, 54240, 54232,     0, 
+        1, 49152, 53248, 54272, 54273, 54275, 54208, 54240, 
+    54232,     0,     1, 49152, 53248, 54272, 54273, 54275, 
+    54208, 54240, 54232, 54234,     0,     1, 49152, 53248, 
+    54272, 54273, 54275, 54208, 54240, 54232,     0,     1, 
+    49152, 53248, 54272, 54273, 54275, 54208, 54240, 54241, 
+    54236,     0,     1, 49152, 53248, 54272, 54273, 54275, 
+    54208, 54240, 54241, 54236,     0,     1, 49152, 53248, 
+    54272, 54273, 54275, 54208, 54240, 54241, 54236, 54238, 
+        0,     1, 49152, 53248, 54272, 54273, 54275, 54208, 
+        0,     1, 49152, 53248, 54272, 54273, 54275, 54208, 
+    54240,     0,     1, 49152, 53248, 54272, 54273, 54275, 
+    54208, 54240,     0,     1, 49152, 53248, 54272, 54273, 
+    54275, 54208, 54240, 54242,     0,     1, 49152, 53248, 
+    54272, 54273, 54275, 54208, 54240,     0,     1, 49152, 
+    53248, 54272, 54273, 54275, 54208, 54240, 54244,     0, 
+        1, 49152, 53248, 54272, 54273, 54275, 54208, 54240, 
+    54244,     0,     1, 49152, 53248, 54272, 54273, 54275, 
+    54208, 54240, 54248, 54246,     0,     1, 49152, 53248, 
+    54272, 54273, 54275, 54279, 54240,     0,     1, 49152, 
+    53248, 54272, 54273, 54275, 54279, 54240, 54248,     0, 
+        1, 49152, 53248, 54272, 54273, 54275, 54279, 54240, 
+    54248,     0,     1, 49152, 53248, 54272, 54273, 54275, 
+    54279, 54240, 54248, 54250,     0,     1, 49152, 53248, 
+    54272, 54273, 54275, 54279, 54240, 54248,     0,     1, 
+    49152, 53248, 54272, 54273, 54275, 54279, 54240, 54256, 
+    54252,     0,     1, 49152, 53248, 54272, 54273, 54275, 
+    54279, 54240, 54256, 54252,     0,     1, 49152, 53248, 
+    54272, 54273, 54275, 54279, 54240, 54256, 54257, 54254, 
+        0,     1, 49152, 53248, 54272, 54273, 54275, 54279, 
+    54240,     0,     1, 49152, 53248, 54272, 54273, 54275, 
+    54279, 54240, 54256,     0,     1, 49152, 53248, 54272, 
+    54273, 54275, 54279, 54240, 54256,     0,     1, 49152, 
+    53248, 54272, 54273, 54275, 54279, 54240, 54256, 54258, 
+        0,     1, 49152, 53248, 54272, 54273, 54275, 54279, 
+    54240, 54256,     0,     1, 49152, 53248, 54272, 54273, 
+    54275, 54279, 54240, 54256, 54260,     0,     1, 49152, 
+    53248, 54272, 54273, 54275, 54279, 54240, 54256, 54260, 
+        0,     1, 49152, 53248, 54272, 54273, 54275, 54279, 
+    54240, 54256, 54264, 54262,     0,     1, 49152, 53248, 
+    54272, 54273, 54275, 54279, 54240, 54256,     0,     1, 
+    49152, 53248, 54272, 54273, 54275, 54279, 54240, 54256, 
+    54264,     0,     1, 49152, 53248, 54272, 54273, 54275, 
+    54279, 54240, 54256, 54264,     0,     1, 49152, 53248, 
+    54272, 54273, 54275, 54279, 54240, 54256, 54264, 54266, 
+        0,     1, 49152, 53248, 54272, 54273, 54275, 54279, 
+    54240, 54256, 54264,     0,     1, 49152, 53248, 54272, 
+    54273, 54275, 54279, 54240, 54256, 54264, 54268,     0, 
+        1, 49152, 53248, 54272, 54273, 54275, 54279, 54240, 
+    54256, 54264, 54268,     0,     1, 49152, 53248, 54272, 
+    54273, 54275, 54279, 54240, 54256, 54264, 54268, 54270, 
+        0,     1, 49152, 53248,     0,     1, 49152, 53248, 
+    54272,     0,     1, 49152, 53248, 54272,     0,     1, 
+    49152, 53248, 54272, 54274,     0,     1, 49152, 53248, 
+    54272,     0,     1, 49152, 53248, 54272, 54276,     0, 
+        1, 49152, 53248, 54272, 54276,     0,     1, 49152, 
+    53248, 54272, 54280, 54278,     0,     1, 49152, 53248, 
+    54272,     0,     1, 49152, 53248, 54272, 54280,     0, 
+        1, 49152, 53248, 54272, 54280,     0,     1, 49152, 
+    53248, 54272, 54280, 54282,     0,     1, 49152, 53248, 
+    54272, 54280,     0,     1, 49152, 53248, 54272, 54288, 
+    54284,     0,     1, 49152, 53248, 54272, 54288, 54284, 
+        0,     1, 49152, 53248, 54272, 54288, 54289, 54286, 
+        0,     1, 49152, 53248, 54272,     0,     1, 49152, 
+    53248, 54272, 54288,     0,     1, 49152, 53248, 54272, 
+    54288,     0,     1, 49152, 53248, 54272, 54288, 54290, 
+        0,     1, 49152, 53248, 54272, 54288,     0,     1, 
+    49152, 53248, 54272, 54288, 54292,     0,     1, 49152, 
+    53248, 54272, 54288, 54292,     0,     1, 49152, 53248, 
+    54272, 54288, 54296, 54294,     0,     1, 49152, 53248, 
+    54272, 54288,     0,     1, 49152, 53248, 54272, 54304, 
+    54296,     0,     1, 49152, 53248, 54272, 54304, 54296, 
+        0,     1, 49152, 53248, 54272, 54304, 54296, 54298, 
+        0,     1, 49152, 53248, 54272, 54304, 54296,     0, 
+        1, 49152, 53248, 54272, 54304, 54305, 54300,     0, 
+        1, 49152, 53248, 54272, 54304, 54305, 54300,     0, 
+        1, 49152, 53248, 54272, 54304, 54305, 54300, 54302, 
+        0,     1, 49152, 53248, 54272,     0,     1, 49152, 
+    53248, 54272, 54304,     0,     1, 49152, 53248, 54272, 
+    54304,     0,     1, 49152, 53248, 54272, 54304, 54306, 
+        0,     1, 49152, 53248, 54272, 54304,     0,     1, 
+    49152, 53248, 54272, 54304, 54308,     0,     1, 49152, 
+    53248, 54272, 54304, 54308,     0,     1, 49152, 53248, 
+    54272, 54304, 54312, 54310,     0,     1, 49152, 53248, 
+    54272, 54304,     0,     1, 49152, 53248, 54272, 54304, 
+    54312,     0,     1, 49152, 53248, 54272, 54304, 54312, 
+        0,     1, 49152, 53248, 54272, 54304, 54312, 54314, 
+        0,     1, 49152, 53248, 54272, 54304, 54312,     0, 
+        1, 49152, 53248, 54272, 54304, 54320, 54316,     0, 
+        1, 49152, 53248, 54272, 54304, 54320, 54316,     0, 
+        1, 49152, 53248, 54272, 54304, 54320, 54321, 54318, 
+        0,     1, 49152, 53248, 54272, 54304,     0,     1, 
+    49152, 53248, 54272, 54336, 54320,     0,     1, 49152, 
+    53248, 54272, 54336, 54320,     0,     1, 49152, 53248, 
+    54272, 54336, 54320, 54322,     0,     1, 49152, 53248, 
+    54272, 54336, 54320,     0,     1, 49152, 53248, 54272, 
+    54336, 54320, 54324,     0,     1, 49152, 53248, 54272, 
+    54336, 54320, 54324,     0,     1, 49152, 53248, 54272, 
+    54336, 54320, 54328, 54326,     0,     1, 49152, 53248, 
+    54272, 54336, 54320,     0,     1, 49152, 53248, 54272, 
+    54336, 54337, 54328,     0,     1, 49152, 53248, 54272, 
+    54336, 54337, 54328,     0,     1, 49152, 53248, 54272, 
+    54336, 54337, 54328, 54330,     0,     1, 49152, 53248, 
+    54272, 54336, 54337, 54328,     0,     1, 49152, 53248, 
+    54272, 54336, 54337, 54328, 54332,     0,     1, 49152, 
+    53248, 54272, 54336, 54337, 54339, 54332,     0,     1, 
+    49152, 53248, 54272, 54336, 54337, 54339, 54332, 54334, 
+        0,     1, 49152, 53248, 54272,     0,     1, 49152, 
+    53248, 54272, 54336,     0,     1, 49152, 53248, 54272, 
+    54336,     0,     1, 49152, 53248, 54272, 54336, 54338, 
+        0,     1, 49152, 53248, 54272, 54336,     0,     1, 
+    49152, 53248, 54272, 54336, 54340,     0,     1, 49152, 
+    53248, 54272, 54336, 54340,     0,     1, 49152, 53248, 
+    54272, 54336, 54344, 54342,     0,     1, 49152, 53248, 
+    54272, 54336,     0,     1, 49152, 53248, 54272, 54336, 
+    54344,     0,     1, 49152, 53248, 54272, 54336, 54344, 
+        0,     1, 49152, 53248, 54272, 54336, 54344, 54346, 
+        0,     1, 49152, 53248, 54272, 54336, 54344,     0, 
+        1, 49152, 53248, 54272, 54336, 54352, 54348,     0, 
+        1, 49152, 53248, 54272, 54336, 54352, 54348,     0, 
+        1, 49152, 53248, 54272, 54336, 54352, 54353, 54350, 
+        0,     1, 49152, 53248, 54272, 54336,     0,     1, 
+    49152, 53248, 54272, 54336, 54352,     0,     1, 49152, 
+    53248, 54272, 54336, 54352,     0,     1, 49152, 53248, 
+    54272, 54336, 54352, 54354,     0,     1, 49152, 53248, 
+    54272, 54336, 54352,     0,     1, 49152, 53248, 54272, 
+    54336, 54352, 54356,     0,     1, 49152, 53248, 54272, 
+    54336, 54352, 54356,     0,     1, 49152, 53248, 54272, 
+    54336, 54352, 54360, 54358,     0,     1, 49152, 53248, 
+    54272, 54336, 54352,     0,     1, 49152, 53248, 54272, 
+    54336, 54368, 54360,     0,     1, 49152, 53248, 54272, 
+    54336, 54368, 54360,     0,     1, 49152, 53248, 54272, 
+    54336, 54368, 54360, 54362,     0,     1, 49152, 53248, 
+    54272, 54336, 54368, 54360,     0,     1, 49152, 53248, 
+    54272, 54336, 54368, 54369, 54364,     0,     1, 49152, 
+    53248, 54272, 54336, 54368, 54369, 54364,     0,     1, 
+    49152, 53248, 54272, 54336, 54368, 54369, 54364, 54366, 
+        0,     1, 49152, 53248, 54272, 54336,     0,     1, 
+    49152, 53248, 54272, 54400, 54368,     0,     1, 49152, 
+    53248, 54272, 54400, 54368,     0,     1, 49152, 53248, 
+    54272, 54400, 54368, 54370,     0,     1, 49152, 53248, 
+    54272, 54400, 54368,     0,     1, 49152, 53248, 54272, 
+    54400, 54368, 54372,     0,     1, 49152, 53248, 54272, 
+    54400, 54368, 54372,     0,     1, 49152, 53248, 54272, 
+    54400, 54368, 54376, 54374,     0,     1, 49152, 53248, 
+    54272, 54400, 54368,     0,     1, 49152, 53248, 54272, 
+    54400, 54368, 54376,     0,     1, 49152, 53248, 54272, 
+    54400, 54368, 54376,     0,     1, 49152, 53248, 54272, 
+    54400, 54368, 54376, 54378,     0,     1, 49152, 53248, 
+    54272, 54400, 54368, 54376,     0,     1, 49152, 53248, 
+    54272, 54400, 54368, 54384, 54380,     0,     1, 49152, 
+    53248, 54272, 54400, 54368, 54384, 54380,     0,     1, 
+    49152, 53248, 54272, 54400, 54368, 54384, 54385, 54382, 
+        0,     1, 49152, 53248, 54272, 54400, 54368,     0, 
+        1, 49152, 53248, 54272, 54400, 54401, 54384,     0, 
+        1, 49152, 53248, 54272, 54400, 54401, 54384,     0, 
+        1, 49152, 53248, 54272, 54400, 54401, 54384, 54386, 
+        0,     1, 49152, 53248, 54272, 54400, 54401, 54384, 
+        0,     1, 49152, 53248, 54272, 54400, 54401, 54384, 
+    54388,     0,     1, 49152, 53248, 54272, 54400, 54401, 
+    54384, 54388,     0,     1, 49152, 53248, 54272, 54400, 
+    54401, 54384, 54392, 54390,     0,     1, 49152, 53248, 
+    54272, 54400, 54401, 54384,     0,     1, 49152, 53248, 
+    54272, 54400, 54401, 54384, 54392,     0,     1, 49152, 
+    53248, 54272, 54400, 54401, 54403, 54392,     0,     1, 
+    49152, 53248, 54272, 54400, 54401, 54403, 54392, 54394, 
+        0,     1, 49152, 53248, 54272, 54400, 54401, 54403, 
+    54392,     0,     1, 49152, 53248, 54272, 54400, 54401, 
+    54403, 54392, 54396,     0,     1, 49152, 53248, 54272, 
+    54400, 54401, 54403, 54392, 54396,     0,     1, 49152, 
+    53248, 54272, 54400, 54401, 54403, 54392, 54396, 54398, 
+        0,     1, 49152, 53248, 54272,     0,     1, 49152, 
+    53248, 54272, 54400,     0,     1, 49152, 53248, 54272, 
+    54400,     0,     1, 49152, 53248, 54272, 54400, 54402, 
+        0,     1, 49152, 53248, 54272, 54400,     0,     1, 
+    49152, 53248, 54272, 54400, 54404,     0,     1, 49152, 
+    53248, 54272, 54400, 54404,     0,     1, 49152, 53248, 
+    54272, 54400, 54408, 54406,     0,     1, 49152, 53248, 
+    54272, 54400,     0,     1, 49152, 53248, 54272, 54400, 
+    54408,     0,     1, 49152, 53248, 54272, 54400, 54408, 
+        0,     1, 49152, 53248, 54272, 54400, 54408, 54410, 
+        0,     1, 49152, 53248, 54272, 54400, 54408,     0, 
+        1, 49152, 53248, 54272, 54400, 54416, 54412,     0, 
+        1, 49152, 53248, 54272, 54400, 54416, 54412,     0, 
+        1, 49152, 53248, 54272, 54400, 54416, 54417, 54414, 
+        0,     1, 49152, 53248, 54272, 54400,     0,     1, 
+    49152, 53248, 54272, 54400, 54416,     0,     1, 49152, 
+    53248, 54272, 54400, 54416,     0,     1, 49152, 53248, 
+    54272, 54400, 54416, 54418,     0,     1, 49152, 53248, 
+    54272, 54400, 54416,     0,     1, 49152, 53248, 54272, 
+    54400, 54416, 54420,     0,     1, 49152, 53248, 54272, 
+    54400, 54416, 54420,     0,     1, 49152, 53248, 54272, 
+    54400, 54416, 54424, 54422,     0,     1, 49152, 53248, 
+    54272, 54400, 54416,     0,     1, 49152, 53248, 54272, 
+    54400, 54432, 54424,     0,     1, 49152, 53248, 54272, 
+    54400, 54432, 54424,     0,     1, 49152, 53248, 54272, 
+    54400, 54432, 54424, 54426,     0,     1, 49152, 53248, 
+    54272, 54400, 54432, 54424,     0,     1, 49152, 53248, 
+    54272, 54400, 54432, 54433, 54428,     0,     1, 49152, 
+    53248, 54272, 54400, 54432, 54433, 54428,     0,     1, 
+    49152, 53248, 54272, 54400, 54432, 54433, 54428, 54430, 
+        0,     1, 49152, 53248, 54272, 54400,     0,     1, 
+    49152, 53248, 54272, 54400, 54432,     0,     1, 49152, 
+    53248, 54272, 54400, 54432,     0,     1, 49152, 53248, 
+    54272, 54400, 54432, 54434,     0,     1, 49152, 53248, 
+    54272, 54400, 54432,     0,     1, 49152, 53248, 54272, 
+    54400, 54432, 54436,     0,     1, 49152, 53248, 54272, 
+    54400, 54432, 54436,     0,     1, 49152, 53248, 54272, 
+    54400, 54432, 54440, 54438,     0,     1, 49152, 53248, 
+    54272, 54400, 54432,     0,     1, 49152, 53248, 54272, 
+    54400, 54432, 54440,     0,     1, 49152, 53248, 54272, 
+    54400, 54432, 54440,     0,     1, 49152, 53248, 54272, 
+    54400, 54432, 54440, 54442,     0,     1, 49152, 53248, 
+    54272, 54400, 54432, 54440,     0,     1, 49152, 53248, 
+    54272, 54400, 54432, 54448, 54444,     0,     1, 49152, 
+    53248, 54272, 54400, 54432, 54448, 54444,     0,     1, 
+    49152, 53248, 54272, 54400, 54432, 54448, 54449, 54446, 
+        0,     1, 49152, 53248, 54272, 54400, 54432,     0, 
+        1, 49152, 53248, 54272, 54400, 54464, 54448,     0, 
+        1, 49152, 53248, 54272, 54400, 54464, 54448,     0, 
+        1, 49152, 53248, 54272, 54400, 54464, 54448, 54450, 
+        0,     1, 49152, 53248, 54272, 54400, 54464, 54448, 
+        0,     1, 49152, 53248, 54272, 54400, 54464, 54448, 
+    54452,     0,     1, 49152, 53248, 54272, 54400, 54464, 
+    54448, 54452,     0,     1, 49152, 53248, 54272, 54400, 
+    54464, 54448, 54456, 54454,     0,     1, 49152, 53248, 
+    54272, 54400, 54464, 54448,     0,     1, 49152, 53248, 
+    54272, 54400, 54464, 54465, 54456,     0,     1, 49152, 
+    53248, 54272, 54400, 54464, 54465, 54456,     0,     1, 
+    49152, 53248, 54272, 54400, 54464, 54465, 54456, 54458, 
+        0,     1, 49152, 53248, 54272, 54400, 54464, 54465, 
+    54456,     0,     1, 49152, 53248, 54272, 54400, 54464, 
+    54465, 54456, 54460,     0,     1, 49152, 53248, 54272, 
+    54400, 54464, 54465, 54467, 54460,     0,     1, 49152, 
+    53248, 54272, 54400, 54464, 54465, 54467, 54460, 54462, 
+        0,     1, 49152, 53248, 54272, 54400,     0,     1, 
+    49152, 53248, 54272, 54528, 54464,     0,     1, 49152, 
+    53248, 54272, 54528, 54464,     0,     1, 49152, 53248, 
+    54272, 54528, 54464, 54466,     0,     1, 49152, 53248, 
+    54272, 54528, 54464,     0,     1, 49152, 53248, 54272, 
+    54528, 54464, 54468,     0,     1, 49152, 53248, 54272, 
+    54528, 54464, 54468,     0,     1, 49152, 53248, 54272, 
+    54528, 54464, 54472, 54470,     0,     1, 49152, 53248, 
+    54272, 54528, 54464,     0,     1, 49152, 53248, 54272, 
+    54528, 54464, 54472,     0,     1, 49152, 53248, 54272, 
+    54528, 54464, 54472,     0,     1, 49152, 53248, 54272, 
+    54528, 54464, 54472, 54474,     0,     1, 49152, 53248, 
+    54272, 54528, 54464, 54472,     0,     1, 49152, 53248, 
+    54272, 54528, 54464, 54480, 54476,     0,     1, 49152, 
+    53248, 54272, 54528, 54464, 54480, 54476,     0,     1, 
+    49152, 53248, 54272, 54528, 54464, 54480, 54481, 54478, 
+        0,     1, 49152, 53248, 54272, 54528, 54464,     0, 
+        1, 49152, 53248, 54272, 54528, 54464, 54480,     0, 
+        1, 49152, 53248, 54272, 54528, 54464, 54480,     0, 
+        1, 49152, 53248, 54272, 54528, 54464, 54480, 54482, 
+        0,     1, 49152, 53248, 54272, 54528, 54464, 54480, 
+        0,     1, 49152, 53248, 54272, 54528, 54464, 54480, 
+    54484,     0,     1, 49152, 53248, 54272, 54528, 54464, 
+    54480, 54484,     0,     1, 49152, 53248, 54272, 54528, 
+    54464, 54480, 54488, 54486,     0,     1, 49152, 53248, 
+    54272, 54528, 54464, 54480,     0,     1, 49152, 53248, 
+    54272, 54528, 54464, 54496, 54488,     0,     1, 49152, 
+    53248, 54272, 54528, 54464, 54496, 54488,     0,     1, 
+    49152, 53248, 54272, 54528, 54464, 54496, 54488, 54490, 
+        0,     1, 49152, 53248, 54272, 54528, 54464, 54496, 
+    54488,     0,     1, 49152, 53248, 54272, 54528, 54464, 
+    54496, 54497, 54492,     0,     1, 49152, 53248, 54272, 
+    54528, 54464, 54496, 54497, 54492,     0,     1, 49152, 
+    53248, 54272, 54528, 54464, 54496, 54497, 54492, 54494, 
+        0,     1, 49152, 53248, 54272, 54528, 54464,     0, 
+        1, 49152, 53248, 54272, 54528, 54529, 54496,     0, 
+        1, 49152, 53248, 54272, 54528, 54529, 54496,     0, 
+        1, 49152, 53248, 54272, 54528, 54529, 54496, 54498, 
+        0,     1, 49152, 53248, 54272, 54528, 54529, 54496, 
+        0,     1, 49152, 53248, 54272, 54528, 54529, 54496, 
+    54500,     0,     1, 49152, 53248, 54272, 54528, 54529, 
+    54496, 54500,     0,     1, 49152, 53248, 54272, 54528, 
+    54529, 54496, 54504, 54502,     0,     1, 49152, 53248, 
+    54272, 54528, 54529, 54496,     0,     1, 49152, 53248, 
+    54272, 54528, 54529, 54496, 54504,     0,     1, 49152, 
+    53248, 54272, 54528, 54529, 54496, 54504,     0,     1, 
+    49152, 53248, 54272, 54528, 54529, 54496, 54504, 54506, 
+        0,     1, 49152, 53248, 54272, 54528, 54529, 54496, 
+    54504,     0,     1, 49152, 53248, 54272, 54528, 54529, 
+    54496, 54512, 54508,     0,     1, 49152, 53248, 54272, 
+    54528, 54529, 54496, 54512, 54508,     0,     1, 49152, 
+    53248, 54272, 54528, 54529, 54496, 54512, 54513, 54510, 
+        0,     1, 49152, 53248, 54272, 54528, 54529, 54496, 
+        0,     1, 49152, 53248, 54272, 54528, 54529, 54496, 
+    54512,     0,     1, 49152, 53248, 54272, 54528, 54529, 
+    54531, 54512,     0,     1, 49152, 53248, 54272, 54528, 
+    54529, 54531, 54512, 54514,     0,     1, 49152, 53248, 
+    54272, 54528, 54529, 54531, 54512,     0,     1, 49152, 
+    53248, 54272, 54528, 54529, 54531, 54512, 54516,     0, 
+        1, 49152, 53248, 54272, 54528, 54529, 54531, 54512, 
+    54516,     0,     1, 49152, 53248, 54272, 54528, 54529, 
+    54531, 54512, 54520, 54518,     0,     1, 49152, 53248, 
+    54272, 54528, 54529, 54531, 54512,     0,     1, 49152, 
+    53248, 54272, 54528, 54529, 54531, 54512, 54520,     0, 
+        1, 49152, 53248, 54272, 54528, 54529, 54531, 54512, 
+    54520,     0,     1, 49152, 53248, 54272, 54528, 54529, 
+    54531, 54512, 54520, 54522,     0,     1, 49152, 53248, 
+    54272, 54528, 54529, 54531, 54535, 54520,     0,     1, 
+    49152, 53248, 54272, 54528, 54529, 54531, 54535, 54520, 
+    54524,     0,     1, 49152, 53248, 54272, 54528, 54529, 
+    54531, 54535, 54520, 54524,     0,     1, 49152, 53248, 
+    54272, 54528, 54529, 54531, 54535, 54520, 54524, 54526, 
+        0,     1, 49152, 53248, 54272,     0,     1, 49152, 
+    53248, 54272, 54528,     0,     1, 49152, 53248, 54272, 
+    54528,     0,     1, 49152, 53248, 54272, 54528, 54530, 
+        0,     1, 49152, 53248, 54272, 54528,     0,     1, 
+    49152, 53248, 54272, 54528, 54532,     0,     1, 49152, 
+    53248, 54272, 54528, 54532,     0,     1, 49152, 53248, 
+    54272, 54528, 54536, 54534,     0,     1, 49152, 53248, 
+    54272, 54528,     0,     1, 49152, 53248, 54272, 54528, 
+    54536,     0,     1, 49152, 53248, 54272, 54528, 54536, 
+        0,     1, 49152, 53248, 54272, 54528, 54536, 54538, 
+        0,     1, 49152, 53248, 54272, 54528, 54536,     0, 
+        1, 49152, 53248, 54272, 54528, 54544, 54540,     0, 
+        1, 49152, 53248, 54272, 54528, 54544, 54540,     0, 
+        1, 49152, 53248, 54272, 54528, 54544, 54545, 54542, 
+        0,     1, 49152, 53248, 54272, 54528,     0,     1, 
+    49152, 53248, 54272, 54528, 54544,     0,     1, 49152, 
+    53248, 54272, 54528, 54544,     0,     1, 49152, 53248, 
+    54272, 54528, 54544, 54546,     0,     1, 49152, 53248, 
+    54272, 54528, 54544,     0,     1, 49152, 53248, 54272, 
+    54528, 54544, 54548,     0,     1, 49152, 53248, 54272, 
+    54528, 54544, 54548,     0,     1, 49152, 53248, 54272, 
+    54528, 54544, 54552, 54550,     0,     1, 49152, 53248, 
+    54272, 54528, 54544,     0,     1, 49152, 53248, 54272, 
+    54528, 54560, 54552,     0,     1, 49152, 53248, 54272, 
+    54528, 54560, 54552,     0,     1, 49152, 53248, 54272, 
+    54528, 54560, 54552, 54554,     0,     1, 49152, 53248, 
+    54272, 54528, 54560, 54552,     0,     1, 49152, 53248, 
+    54272, 54528, 54560, 54561, 54556,     0,     1, 49152, 
+    53248, 54272, 54528, 54560, 54561, 54556,     0,     1, 
+    49152, 53248, 54272, 54528, 54560, 54561, 54556, 54558, 
+        0,     1, 49152, 53248, 54272, 54528,     0,     1, 
+    49152, 53248, 54272, 54528, 54560,     0,     1, 49152, 
+    53248, 54272, 54528, 54560,     0,     1, 49152, 53248, 
+    54272, 54528, 54560, 54562,     0,     1, 49152, 53248, 
+    54272, 54528, 54560,     0,     1, 49152, 53248, 54272, 
+    54528, 54560, 54564,     0,     1, 49152, 53248, 54272, 
+    54528, 54560, 54564,     0,     1, 49152, 53248, 54272, 
+    54528, 54560, 54568, 54566,     0,     1, 49152, 53248, 
+    54272, 54528, 54560,     0,     1, 49152, 53248, 54272, 
+    54528, 54560, 54568,     0,     1, 49152, 53248, 54272, 
+    54528, 54560, 54568,     0,     1, 49152, 53248, 54272, 
+    54528, 54560, 54568, 54570,     0,     1, 49152, 53248, 
+    54272, 54528, 54560, 54568,     0,     1, 49152, 53248, 
+    54272, 54528, 54560, 54576, 54572,     0,     1, 49152, 
+    53248, 54272, 54528, 54560, 54576, 54572,     0,     1, 
+    49152, 53248, 54272, 54528, 54560, 54576, 54577, 54574, 
+        0,     1, 49152, 53248, 54272, 54528, 54560,     0, 
+        1, 49152, 53248, 54272, 54528, 54592, 54576,     0, 
+        1, 49152, 53248, 54272, 54528, 54592, 54576,     0, 
+        1, 49152, 53248, 54272, 54528, 54592, 54576, 54578, 
+        0,     1, 49152, 53248, 54272, 54528, 54592, 54576, 
+        0,     1, 49152, 53248, 54272, 54528, 54592, 54576, 
+    54580,     0,     1, 49152, 53248, 54272, 54528, 54592, 
+    54576, 54580,     0,     1, 49152, 53248, 54272, 54528, 
+    54592, 54576, 54584, 54582,     0,     1, 49152, 53248, 
+    54272, 54528, 54592, 54576,     0,     1, 49152, 53248, 
+    54272, 54528, 54592, 54593, 54584,     0,     1, 49152, 
+    53248, 54272, 54528, 54592, 54593, 54584,     0,     1, 
+    49152, 53248, 54272, 54528, 54592, 54593, 54584, 54586, 
+        0,     1, 49152, 53248, 54272, 54528, 54592, 54593, 
+    54584,     0,     1, 49152, 53248, 54272, 54528, 54592, 
+    54593, 54584, 54588,     0,     1, 49152, 53248, 54272, 
+    54528, 54592, 54593, 54595, 54588,     0,     1, 49152, 
+    53248, 54272, 54528, 54592, 54593, 54595, 54588, 54590, 
+        0,     1, 49152, 53248, 54272, 54528,     0,     1, 
+    49152, 53248, 54272, 54528, 54592,     0,     1, 49152, 
+    53248, 54272, 54528, 54592,     0,     1, 49152, 53248, 
+    54272, 54528, 54592, 54594,     0,     1, 49152, 53248, 
+    54272, 54528, 54592,     0,     1, 49152, 53248, 54272, 
+    54528, 54592, 54596,     0,     1, 49152, 53248, 54272, 
+    54528, 54592, 54596,     0,     1, 49152, 53248, 54272, 
+    54528, 54592, 54600, 54598,     0,     1, 49152, 53248, 
+    54272, 54528, 54592,     0,     1, 49152, 53248, 54272, 
+    54528, 54592, 54600,     0,     1, 49152, 53248, 54272, 
+    54528, 54592, 54600,     0,     1, 49152, 53248, 54272, 
+    54528, 54592, 54600, 54602,     0,     1, 49152, 53248, 
+    54272, 54528, 54592, 54600,     0,     1, 49152, 53248, 
+    54272, 54528, 54592, 54608, 54604,     0,     1, 49152, 
+    53248, 54272, 54528, 54592, 54608, 54604,     0,     1, 
+    49152, 53248, 54272, 54528, 54592, 54608, 54609, 54606, 
+        0,     1, 49152, 53248, 54272, 54528, 54592,     0, 
+        1, 49152, 53248, 54272, 54528, 54592, 54608,     0, 
+        1, 49152, 53248, 54272, 54528, 54592, 54608,     0, 
+        1, 49152, 53248, 54272, 54528, 54592, 54608, 54610, 
+        0,     1, 49152, 53248, 54272, 54528, 54592, 54608, 
+        0,     1, 49152, 53248, 54272, 54528, 54592, 54608, 
+    54612,     0,     1, 49152, 53248, 54272, 54528, 54592, 
+    54608, 54612,     0,     1, 49152, 53248, 54272, 54528, 
+    54592, 54608, 54616, 54614,     0,     1, 49152, 53248, 
+    54272, 54528, 54592, 54608,     0,     1, 49152, 53248, 
+    54272, 54528, 54592, 54624, 54616,     0,     1, 49152, 
+    53248, 54272, 54528, 54592, 54624, 54616,     0,     1, 
+    49152, 53248, 54272, 54528, 54592, 54624, 54616, 54618, 
+        0,     1, 49152, 53248, 54272, 54528, 54592, 54624, 
+    54616,     0,     1, 49152, 53248, 54272, 54528, 54592, 
+    54624, 54625, 54620,     0,     1, 49152, 53248, 54272, 
+    54528, 54592, 54624, 54625, 54620,     0,     1, 49152, 
+    53248, 54272, 54528, 54592, 54624, 54625, 54620, 54622, 
+        0,     1, 49152, 53248, 54272, 54528, 54592,     0, 
+        1, 49152, 53248, 54272, 54528, 54656, 54624,     0, 
+        1, 49152, 53248, 54272, 54528, 54656, 54624,     0, 
+        1, 49152, 53248, 54272, 54528, 54656, 54624, 54626, 
+        0,     1, 49152, 53248, 54272, 54528, 54656, 54624, 
+        0,     1, 49152, 53248, 54272, 54528, 54656, 54624, 
+    54628,     0,     1, 49152, 53248, 54272, 54528, 54656, 
+    54624, 54628,     0,     1, 49152, 53248, 54272, 54528, 
+    54656, 54624, 54632, 54630,     0,     1, 49152, 53248, 
+    54272, 54528, 54656, 54624,     0,     1, 49152, 53248, 
+    54272, 54528, 54656, 54624, 54632,     0,     1, 49152, 
+    53248, 54272, 54528, 54656, 54624, 54632,     0,     1, 
+    49152, 53248, 54272, 54528, 54656, 54624, 54632, 54634, 
+        0,     1, 49152, 53248, 54272, 54528, 54656, 54624, 
+    54632,     0,     1, 49152, 53248, 54272, 54528, 54656, 
+    54624, 54640, 54636,     0,     1, 49152, 53248, 54272, 
+    54528, 54656, 54624, 54640, 54636,     0,     1, 49152, 
+    53248, 54272, 54528, 54656, 54624, 54640, 54641, 54638, 
+        0,     1, 49152, 53248, 54272, 54528, 54656, 54624, 
+        0,     1, 49152, 53248, 54272, 54528, 54656, 54657, 
+    54640,     0,     1, 49152, 53248, 54272, 54528, 54656, 
+    54657, 54640,     0,     1, 49152, 53248, 54272, 54528, 
+    54656, 54657, 54640, 54642,     0,     1, 49152, 53248, 
+    54272, 54528, 54656, 54657, 54640,     0,     1, 49152, 
+    53248, 54272, 54528, 54656, 54657, 54640, 54644,     0, 
+        1, 49152, 53248, 54272, 54528, 54656, 54657, 54640, 
+    54644,     0,     1, 49152, 53248, 54272, 54528, 54656, 
+    54657, 54640, 54648, 54646,     0,     1, 49152, 53248, 
+    54272, 54528, 54656, 54657, 54640,     0,     1, 49152, 
+    53248, 54272, 54528, 54656, 54657, 54640, 54648,     0, 
+        1, 49152, 53248, 54272, 54528, 54656, 54657, 54659, 
+    54648,     0,     1, 49152, 53248, 54272, 54528, 54656, 
+    54657, 54659, 54648, 54650,     0,     1, 49152, 53248, 
+    54272, 54528, 54656, 54657, 54659, 54648,     0,     1, 
+    49152, 53248, 54272, 54528, 54656, 54657, 54659, 54648, 
+    54652,     0,     1, 49152, 53248, 54272, 54528, 54656, 
+    54657, 54659, 54648, 54652,     0,     1, 49152, 53248, 
+    54272, 54528, 54656, 54657, 54659, 54648, 54652, 54654, 
+        0,     1, 49152, 53248, 54272, 54528,     0,     1, 
+    49152, 53248, 54272, 54784, 54656,     0,     1, 49152, 
+    53248, 54272, 54784, 54656,     0,     1, 49152, 53248, 
+    54272, 54784, 54656, 54658,     0,     1, 49152, 53248, 
+    54272, 54784, 54656,     0,     1, 49152, 53248, 54272, 
+    54784, 54656, 54660,     0,     1, 49152, 53248, 54272, 
+    54784, 54656, 54660,     0,     1, 49152, 53248, 54272, 
+    54784, 54656, 54664, 54662,     0,     1, 49152, 53248, 
+    54272, 54784, 54656,     0,     1, 49152, 53248, 54272, 
+    54784, 54656, 54664,     0,     1, 49152, 53248, 54272, 
+    54784, 54656, 54664,     0,     1, 49152, 53248, 54272, 
+    54784, 54656, 54664, 54666,     0,     1, 49152, 53248, 
+    54272, 54784, 54656, 54664,     0,     1, 49152, 53248, 
+    54272, 54784, 54656, 54672, 54668,     0,     1, 49152, 
+    53248, 54272, 54784, 54656, 54672, 54668,     0,     1, 
+    49152, 53248, 54272, 54784, 54656, 54672, 54673, 54670, 
+        0,     1, 49152, 53248, 54272, 54784, 54656,     0, 
+        1, 49152, 53248, 54272, 54784, 54656, 54672,     0, 
+        1, 49152, 53248, 54272, 54784, 54656, 54672,     0, 
+        1, 49152, 53248, 54272, 54784, 54656, 54672, 54674, 
+        0,     1, 49152, 53248, 54272, 54784, 54656, 54672, 
+        0,     1, 49152, 53248, 54272, 54784, 54656, 54672, 
+    54676,     0,     1, 49152, 53248, 54272, 54784, 54656, 
+    54672, 54676,     0,     1, 49152, 53248, 54272, 54784, 
+    54656, 54672, 54680, 54678,     0,     1, 49152, 53248, 
+    54272, 54784, 54656, 54672,     0,     1, 49152, 53248, 
+    54272, 54784, 54656, 54688, 54680,     0,     1, 49152, 
+    53248, 54272, 54784, 54656, 54688, 54680,     0,     1, 
+    49152, 53248, 54272, 54784, 54656, 54688, 54680, 54682, 
+        0,     1, 49152, 53248, 54272, 54784, 54656, 54688, 
+    54680,     0,     1, 49152, 53248, 54272, 54784, 54656, 
+    54688, 54689, 54684,     0,     1, 49152, 53248, 54272, 
+    54784, 54656, 54688, 54689, 54684,     0,     1, 49152, 
+    53248, 54272, 54784, 54656, 54688, 54689, 54684, 54686, 
+        0,     1, 49152, 53248, 54272, 54784, 54656,     0, 
+        1, 49152, 53248, 54272, 54784, 54656, 54688,     0, 
+        1, 49152, 53248, 54272, 54784, 54656, 54688,     0, 
+        1, 49152, 53248, 54272, 54784, 54656, 54688, 54690, 
+        0,     1, 49152, 53248, 54272, 54784, 54656, 54688, 
+        0,     1, 49152, 53248, 54272, 54784, 54656, 54688, 
+    54692,     0,     1, 49152, 53248, 54272, 54784, 54656, 
+    54688, 54692,     0,     1, 49152, 53248, 54272, 54784, 
+    54656, 54688, 54696, 54694,     0,     1, 49152, 53248, 
+    54272, 54784, 54656, 54688,     0,     1, 49152, 53248, 
+    54272, 54784, 54656, 54688, 54696,     0,     1, 49152, 
+    53248, 54272, 54784, 54656, 54688, 54696,     0,     1, 
+    49152, 53248, 54272, 54784, 54656, 54688, 54696, 54698, 
+        0,     1, 49152, 53248, 54272, 54784, 54656, 54688, 
+    54696,     0,     1, 49152, 53248, 54272, 54784, 54656, 
+    54688, 54704, 54700,     0,     1, 49152, 53248, 54272, 
+    54784, 54656, 54688, 54704, 54700,     0,     1, 49152, 
+    53248, 54272, 54784, 54656, 54688, 54704, 54705, 54702, 
+        0,     1, 49152, 53248, 54272, 54784, 54656, 54688, 
+        0,     1, 49152, 53248, 54272, 54784, 54656, 54720, 
+    54704,     0,     1, 49152, 53248, 54272, 54784, 54656, 
+    54720, 54704,     0,     1, 49152, 53248, 54272, 54784, 
+    54656, 54720, 54704, 54706,     0,     1, 49152, 53248, 
+    54272, 54784, 54656, 54720, 54704,     0,     1, 49152, 
+    53248, 54272, 54784, 54656, 54720, 54704, 54708,     0, 
+        1, 49152, 53248, 54272, 54784, 54656, 54720, 54704, 
+    54708,     0,     1, 49152, 53248, 54272, 54784, 54656, 
+    54720, 54704, 54712, 54710,     0,     1, 49152, 53248, 
+    54272, 54784, 54656, 54720, 54704,     0,     1, 49152, 
+    53248, 54272, 54784, 54656, 54720, 54721, 54712,     0, 
+        1, 49152, 53248, 54272, 54784, 54656, 54720, 54721, 
+    54712,     0,     1, 49152, 53248, 54272, 54784, 54656, 
+    54720, 54721, 54712, 54714,     0,     1, 49152, 53248, 
+    54272, 54784, 54656, 54720, 54721, 54712,     0,     1, 
+    49152, 53248, 54272, 54784, 54656, 54720, 54721, 54712, 
+    54716,     0,     1, 49152, 53248, 54272, 54784, 54656, 
+    54720, 54721, 54723, 54716,     0,     1, 49152, 53248, 
+    54272, 54784, 54656, 54720, 54721, 54723, 54716, 54718, 
+        0,     1, 49152, 53248, 54272, 54784, 54656,     0, 
+        1, 49152, 53248, 54272, 54784, 54785, 54720,     0, 
+        1, 49152, 53248, 54272, 54784, 54785, 54720,     0, 
+        1, 49152, 53248, 54272, 54784, 54785, 54720, 54722, 
+        0,     1, 49152, 53248, 54272, 54784, 54785, 54720, 
+        0,     1, 49152, 53248, 54272, 54784, 54785, 54720, 
+    54724,     0,     1, 49152, 53248, 54272, 54784, 54785, 
+    54720, 54724,     0,     1, 49152, 53248, 54272, 54784, 
+    54785, 54720, 54728, 54726,     0,     1, 49152, 53248, 
+    54272, 54784, 54785, 54720,     0,     1, 49152, 53248, 
+    54272, 54784, 54785, 54720, 54728,     0,     1, 49152, 
+    53248, 54272, 54784, 54785, 54720, 54728,     0,     1, 
+    49152, 53248, 54272, 54784, 54785, 54720, 54728, 54730, 
+        0,     1, 49152, 53248, 54272, 54784, 54785, 54720, 
+    54728,     0,     1, 49152, 53248, 54272, 54784, 54785, 
+    54720, 54736, 54732,     0,     1, 49152, 53248, 54272, 
+    54784, 54785, 54720, 54736, 54732,     0,     1, 49152, 
+    53248, 54272, 54784, 54785, 54720, 54736, 54737, 54734, 
+        0,     1, 49152, 53248, 54272, 54784, 54785, 54720, 
+        0,     1, 49152, 53248, 54272, 54784, 54785, 54720, 
+    54736,     0,     1, 49152, 53248, 54272, 54784, 54785, 
+    54720, 54736,     0,     1, 49152, 53248, 54272, 54784, 
+    54785, 54720, 54736, 54738,     0,     1, 49152, 53248, 
+    54272, 54784, 54785, 54720, 54736,     0,     1, 49152, 
+    53248, 54272, 54784, 54785, 54720, 54736, 54740,     0, 
+        1, 49152, 53248, 54272, 54784, 54785, 54720, 54736, 
+    54740,     0,     1, 49152, 53248, 54272, 54784, 54785, 
+    54720, 54736, 54744, 54742,     0,     1, 49152, 53248, 
+    54272, 54784, 54785, 54720, 54736,     0,     1, 49152, 
+    53248, 54272, 54784, 54785, 54720, 54752, 54744,     0, 
+        1, 49152, 53248, 54272, 54784, 54785, 54720, 54752, 
+    54744,     0,     1, 49152, 53248, 54272, 54784, 54785, 
+    54720, 54752, 54744, 54746,     0,     1, 49152, 53248, 
+    54272, 54784, 54785, 54720, 54752, 54744,     0,     1, 
+    49152, 53248, 54272, 54784, 54785, 54720, 54752, 54753, 
+    54748,     0,     1, 49152, 53248, 54272, 54784, 54785, 
+    54720, 54752, 54753, 54748,     0,     1, 49152, 53248, 
+    54272, 54784, 54785, 54720, 54752, 54753, 54748, 54750, 
+        0,     1, 49152, 53248, 54272, 54784, 54785, 54720, 
+        0,     1, 49152, 53248, 54272, 54784, 54785, 54720, 
+    54752,     0,     1, 49152, 53248, 54272, 54784, 54785, 
+    54787, 54752,     0,     1, 49152, 53248, 54272, 54784, 
+    54785, 54787, 54752, 54754,     0,     1, 49152, 53248, 
+    54272, 54784, 54785, 54787, 54752,     0,     1, 49152, 
+    53248, 54272, 54784, 54785, 54787, 54752, 54756,     0, 
+        1, 49152, 53248, 54272, 54784, 54785, 54787, 54752, 
+    54756,     0,     1, 49152, 53248, 54272, 54784, 54785, 
+    54787, 54752, 54760, 54758,     0,     1, 49152, 53248, 
+    54272, 54784, 54785, 54787, 54752,     0,     1, 49152, 
+    53248, 54272, 54784, 54785, 54787, 54752, 54760,     0, 
+        1, 49152, 53248, 54272, 54784, 54785, 54787, 54752, 
+    54760,     0,     1, 49152, 53248, 54272, 54784, 54785, 
+    54787, 54752, 54760, 54762,     0,     1, 49152, 53248, 
+    54272, 54784, 54785, 54787, 54752, 54760,     0,     1, 
+    49152, 53248, 54272, 54784, 54785, 54787, 54752, 54768, 
+    54764,     0,     1, 49152, 53248, 54272, 54784, 54785, 
+    54787, 54752, 54768, 54764,     0,     1, 49152, 53248, 
+    54272, 54784, 54785, 54787, 54752, 54768, 54769, 54766, 
+        0,     1, 49152, 53248, 54272, 54784, 54785, 54787, 
+    54752,     0,     1, 49152, 53248, 54272, 54784, 54785, 
+    54787, 54752, 54768,     0,     1, 49152, 53248, 54272, 
+    54784, 54785, 54787, 54752, 54768,     0,     1, 49152, 
+    53248, 54272, 54784, 54785, 54787, 54752, 54768, 54770, 
+        0,     1, 49152, 53248, 54272, 54784, 54785, 54787, 
+    54791, 54768,     0,     1, 49152, 53248, 54272, 54784, 
+    54785, 54787, 54791, 54768, 54772,     0,     1, 49152, 
+    53248, 54272, 54784, 54785, 54787, 54791, 54768, 54772, 
+        0,     1, 49152, 53248, 54272, 54784, 54785, 54787, 
+    54791, 54768, 54776, 54774,     0,     1, 49152, 53248, 
+    54272, 54784, 54785, 54787, 54791, 54768,     0,     1, 
+    49152, 53248, 54272, 54784, 54785, 54787, 54791, 54768, 
+    54776,     0,     1, 49152, 53248, 54272, 54784, 54785, 
+    54787, 54791, 54768, 54776,     0,     1, 49152, 53248, 
+    54272, 54784, 54785, 54787, 54791, 54768, 54776, 54778, 
+        0,     1, 49152, 53248, 54272, 54784, 54785, 54787, 
+    54791, 54768, 54776,     0,     1, 49152, 53248, 54272, 
+    54784, 54785, 54787, 54791, 54768, 54776, 54780,     0, 
+        1, 49152, 53248, 54272, 54784, 54785, 54787, 54791, 
+    54768, 54776, 54780,     0,     1, 49152, 53248, 54272, 
+    54784, 54785, 54787, 54791, 54768, 54776, 54780, 54782, 
+        0,     1, 49152, 53248, 54272,     0,     1, 49152, 
+    53248, 55296, 54784,     0,     1, 49152, 53248, 55296, 
+    54784,     0,     1, 49152, 53248, 55296, 54784, 54786, 
+        0,     1, 49152, 53248, 55296, 54784,     0,     1, 
+    49152, 53248, 55296, 54784, 54788,     0,     1, 49152, 
+    53248, 55296, 54784, 54788,     0,     1, 49152, 53248, 
+    55296, 54784, 54792, 54790,     0,     1, 49152, 53248, 
+    55296, 54784,     0,     1, 49152, 53248, 55296, 54784, 
+    54792,     0,     1, 49152, 53248, 55296, 54784, 54792, 
+        0,     1, 49152, 53248, 55296, 54784, 54792, 54794, 
+        0,     1, 49152, 53248, 55296, 54784, 54792,     0, 
+        1, 49152, 53248, 55296, 54784, 54800, 54796,     0, 
+        1, 49152, 53248, 55296, 54784, 54800, 54796,     0, 
+        1, 49152, 53248, 55296, 54784, 54800, 54801, 54798, 
+        0,     1, 49152, 53248, 55296, 54784,     0,     1, 
+    49152, 53248, 55296, 54784, 54800,     0,     1, 49152, 
+    53248, 55296, 54784, 54800,     0,     1, 49152, 53248, 
+    55296, 54784, 54800, 54802,     0,     1, 49152, 53248, 
+    55296, 54784, 54800,     0,     1, 49152, 53248, 55296, 
+    54784, 54800, 54804,     0,     1, 49152, 53248, 55296, 
+    54784, 54800, 54804,     0,     1, 49152, 53248, 55296, 
+    54784, 54800, 54808, 54806,     0,     1, 49152, 53248, 
+    55296, 54784, 54800,     0,     1, 49152, 53248, 55296, 
+    54784, 54816, 54808,     0,     1, 49152, 53248, 55296, 
+    54784, 54816, 54808,     0,     1, 49152, 53248, 55296, 
+    54784, 54816, 54808, 54810,     0,     1, 49152, 53248, 
+    55296, 54784, 54816, 54808,     0,     1, 49152, 53248, 
+    55296, 54784, 54816, 54817, 54812,     0,     1, 49152, 
+    53248, 55296, 54784, 54816, 54817, 54812,     0,     1, 
+    49152, 53248, 55296, 54784, 54816, 54817, 54812, 54814, 
+        0,     1, 49152, 53248, 55296, 54784,     0,     1, 
+    49152, 53248, 55296, 54784, 54816,     0,     1, 49152, 
+    53248, 55296, 54784, 54816,     0,     1, 49152, 53248, 
+    55296, 54784, 54816, 54818,     0,     1, 49152, 53248, 
+    55296, 54784, 54816,     0,     1, 49152, 53248, 55296, 
+    54784, 54816, 54820,     0,     1, 49152, 53248, 55296, 
+    54784, 54816, 54820,     0,     1, 49152, 53248, 55296, 
+    54784, 54816, 54824, 54822,     0,     1, 49152, 53248, 
+    55296, 54784, 54816,     0,     1, 49152, 53248, 55296, 
+    54784, 54816, 54824,     0,     1, 49152, 53248, 55296, 
+    54784, 54816, 54824,     0,     1, 49152, 53248, 55296, 
+    54784, 54816, 54824, 54826,     0,     1, 49152, 53248, 
+    55296, 54784, 54816, 54824,     0,     1, 49152, 53248, 
+    55296, 54784, 54816, 54832, 54828,     0,     1, 49152, 
+    53248, 55296, 54784, 54816, 54832, 54828,     0,     1, 
+    49152, 53248, 55296, 54784, 54816, 54832, 54833, 54830, 
+        0,     1, 49152, 53248, 55296, 54784, 54816,     0, 
+        1, 49152, 53248, 55296, 54784, 54848, 54832,     0, 
+        1, 49152, 53248, 55296, 54784, 54848, 54832,     0, 
+        1, 49152, 53248, 55296, 54784, 54848, 54832, 54834, 
+        0,     1, 49152, 53248, 55296, 54784, 54848, 54832, 
+        0,     1, 49152, 53248, 55296, 54784, 54848, 54832, 
+    54836,     0,     1, 49152, 53248, 55296, 54784, 54848, 
+    54832, 54836,     0,     1, 49152, 53248, 55296, 54784, 
+    54848, 54832, 54840, 54838,     0,     1, 49152, 53248, 
+    55296, 54784, 54848, 54832,     0,     1, 49152, 53248, 
+    55296, 54784, 54848, 54849, 54840,     0,     1, 49152, 
+    53248, 55296, 54784, 54848, 54849, 54840,     0,     1, 
+    49152, 53248, 55296, 54784, 54848, 54849, 54840, 54842, 
+        0,     1, 49152, 53248, 55296, 54784, 54848, 54849, 
+    54840,     0,     1, 49152, 53248, 55296, 54784, 54848, 
+    54849, 54840, 54844,     0,     1, 49152, 53248, 55296, 
+    54784, 54848, 54849, 54851, 54844,     0,     1, 49152, 
+    53248, 55296, 54784, 54848, 54849, 54851, 54844, 54846, 
+        0,     1, 49152, 53248, 55296, 54784,     0,     1, 
+    49152, 53248, 55296, 54784, 54848,     0,     1, 49152, 
+    53248, 55296, 54784, 54848,     0,     1, 49152, 53248, 
+    55296, 54784, 54848, 54850,     0,     1, 49152, 53248, 
+    55296, 54784, 54848,     0,     1, 49152, 53248, 55296, 
+    54784, 54848, 54852,     0,     1, 49152, 53248, 55296, 
+    54784, 54848, 54852,     0,     1, 49152, 53248, 55296, 
+    54784, 54848, 54856, 54854,     0,     1, 49152, 53248, 
+    55296, 54784, 54848,     0,     1, 49152, 53248, 55296, 
+    54784, 54848, 54856,     0,     1, 49152, 53248, 55296, 
+    54784, 54848, 54856,     0,     1, 49152, 53248, 55296, 
+    54784, 54848, 54856, 54858,     0,     1, 49152, 53248, 
+    55296, 54784, 54848, 54856,     0,     1, 49152, 53248, 
+    55296, 54784, 54848, 54864, 54860,     0,     1, 49152, 
+    53248, 55296, 54784, 54848, 54864, 54860,     0,     1, 
+    49152, 53248, 55296, 54784, 54848, 54864, 54865, 54862, 
+        0,     1, 49152, 53248, 55296, 54784, 54848,     0, 
+        1, 49152, 53248, 55296, 54784, 54848, 54864,     0, 
+        1, 49152, 53248, 55296, 54784, 54848, 54864,     0, 
+        1, 49152, 53248, 55296, 54784, 54848, 54864, 54866, 
+        0,     1, 49152, 53248, 55296, 54784, 54848, 54864, 
+        0,     1, 49152, 53248, 55296, 54784, 54848, 54864, 
+    54868,     0,     1, 49152, 53248, 55296, 54784, 54848, 
+    54864, 54868,     0,     1, 49152, 53248, 55296, 54784, 
+    54848, 54864, 54872, 54870,     0,     1, 49152, 53248, 
+    55296, 54784, 54848, 54864,     0,     1, 49152, 53248, 
+    55296, 54784, 54848, 54880, 54872,     0,     1, 49152, 
+    53248, 55296, 54784, 54848, 54880, 54872,     0,     1, 
+    49152, 53248, 55296, 54784, 54848, 54880, 54872, 54874, 
+        0,     1, 49152, 53248, 55296, 54784, 54848, 54880, 
+    54872,     0,     1, 49152, 53248, 55296, 54784, 54848, 
+    54880, 54881, 54876,     0,     1, 49152, 53248, 55296, 
+    54784, 54848, 54880, 54881, 54876,     0,     1, 49152, 
+    53248, 55296, 54784, 54848, 54880, 54881, 54876, 54878, 
+        0,     1, 49152, 53248, 55296, 54784, 54848,     0, 
+        1, 49152, 53248, 55296, 54784, 54912, 54880,     0, 
+        1, 49152, 53248, 55296, 54784, 54912, 54880,     0, 
+        1, 49152, 53248, 55296, 54784, 54912, 54880, 54882, 
+        0,     1, 49152, 53248, 55296, 54784, 54912, 54880, 
+        0,     1, 49152, 53248, 55296, 54784, 54912, 54880, 
+    54884,     0,     1, 49152, 53248, 55296, 54784, 54912, 
+    54880, 54884,     0,     1, 49152, 53248, 55296, 54784, 
+    54912, 54880, 54888, 54886,     0,     1, 49152, 53248, 
+    55296, 54784, 54912, 54880,     0,     1, 49152, 53248, 
+    55296, 54784, 54912, 54880, 54888,     0,     1, 49152, 
+    53248, 55296, 54784, 54912, 54880, 54888,     0,     1, 
+    49152, 53248, 55296, 54784, 54912, 54880, 54888, 54890, 
+        0,     1, 49152, 53248, 55296, 54784, 54912, 54880, 
+    54888,     0,     1, 49152, 53248, 55296, 54784, 54912, 
+    54880, 54896, 54892,     0,     1, 49152, 53248, 55296, 
+    54784, 54912, 54880, 54896, 54892,     0,     1, 49152, 
+    53248, 55296, 54784, 54912, 54880, 54896, 54897, 54894, 
+        0,     1, 49152, 53248, 55296, 54784, 54912, 54880, 
+        0,     1, 49152, 53248, 55296, 54784, 54912, 54913, 
+    54896,     0,     1, 49152, 53248, 55296, 54784, 54912, 
+    54913, 54896,     0,     1, 49152, 53248, 55296, 54784, 
+    54912, 54913, 54896, 54898,     0,     1, 49152, 53248, 
+    55296, 54784, 54912, 54913, 54896,     0,     1, 49152, 
+    53248, 55296, 54784, 54912, 54913, 54896, 54900,     0, 
+        1, 49152, 53248, 55296, 54784, 54912, 54913, 54896, 
+    54900,     0,     1, 49152, 53248, 55296, 54784, 54912, 
+    54913, 54896, 54904, 54902,     0,     1, 49152, 53248, 
+    55296, 54784, 54912, 54913, 54896,     0,     1, 49152, 
+    53248, 55296, 54784, 54912, 54913, 54896, 54904,     0, 
+        1, 49152, 53248, 55296, 54784, 54912, 54913, 54915, 
+    54904,     0,     1, 49152, 53248, 55296, 54784, 54912, 
+    54913, 54915, 54904, 54906,     0,     1, 49152, 53248, 
+    55296, 54784, 54912, 54913, 54915, 54904,     0,     1, 
+    49152, 53248, 55296, 54784, 54912, 54913, 54915, 54904, 
+    54908,     0,     1, 49152, 53248, 55296, 54784, 54912, 
+    54913, 54915, 54904, 54908,     0,     1, 49152, 53248, 
+    55296, 54784, 54912, 54913, 54915, 54904, 54908, 54910, 
+        0,     1, 49152, 53248, 55296, 54784,     0,     1, 
+    49152, 53248, 55296, 54784, 54912,     0,     1, 49152, 
+    53248, 55296, 54784, 54912,     0,     1, 49152, 53248, 
+    55296, 54784, 54912, 54914,     0,     1, 49152, 53248, 
+    55296, 54784, 54912,     0,     1, 49152, 53248, 55296, 
+    54784, 54912, 54916,     0,     1, 49152, 53248, 55296, 
+    54784, 54912, 54916,     0,     1, 49152, 53248, 55296, 
+    54784, 54912, 54920, 54918,     0,     1, 49152, 53248, 
+    55296, 54784, 54912,     0,     1, 49152, 53248, 55296, 
+    54784, 54912, 54920,     0,     1, 49152, 53248, 55296, 
+    54784, 54912, 54920,     0,     1, 49152, 53248, 55296, 
+    54784, 54912, 54920, 54922,     0,     1, 49152, 53248, 
+    55296, 54784, 54912, 54920,     0,     1, 49152, 53248, 
+    55296, 54784, 54912, 54928, 54924,     0,     1, 49152, 
+    53248, 55296, 54784, 54912, 54928, 54924,     0,     1, 
+    49152, 53248, 55296, 54784, 54912, 54928, 54929, 54926, 
+        0,     1, 49152, 53248, 55296, 54784, 54912,     0, 
+        1, 49152, 53248, 55296, 54784, 54912, 54928,     0, 
+        1, 49152, 53248, 55296, 54784, 54912, 54928,     0, 
+        1, 49152, 53248, 55296, 54784, 54912, 54928, 54930, 
+        0,     1, 49152, 53248, 55296, 54784, 54912, 54928, 
+        0,     1, 49152, 53248, 55296, 54784, 54912, 54928, 
+    54932,     0,     1, 49152, 53248, 55296, 54784, 54912, 
+    54928, 54932,     0,     1, 49152, 53248, 55296, 54784, 
+    54912, 54928, 54936, 54934,     0,     1, 49152, 53248, 
+    55296, 54784, 54912, 54928,     0,     1, 49152, 53248, 
+    55296, 54784, 54912, 54944, 54936,     0,     1, 49152, 
+    53248, 55296, 54784, 54912, 54944, 54936,     0,     1, 
+    49152, 53248, 55296, 54784, 54912, 54944, 54936, 54938, 
+        0,     1, 49152, 53248, 55296, 54784, 54912, 54944, 
+    54936,     0,     1, 49152, 53248, 55296, 54784, 54912, 
+    54944, 54945, 54940,     0,     1, 49152, 53248, 55296, 
+    54784, 54912, 54944, 54945, 54940,     0,     1, 49152, 
+    53248, 55296, 54784, 54912, 54944, 54945, 54940, 54942, 
+        0,     1, 49152, 53248, 55296, 54784, 54912,     0, 
+        1, 49152, 53248, 55296, 54784, 54912, 54944,     0, 
+        1, 49152, 53248, 55296, 54784, 54912, 54944,     0, 
+        1, 49152, 53248, 55296, 54784, 54912, 54944, 54946, 
+        0,     1, 49152, 53248, 55296, 54784, 54912, 54944, 
+        0,     1, 49152, 53248, 55296, 54784, 54912, 54944, 
+    54948,     0,     1, 49152, 53248, 55296, 54784, 54912, 
+    54944, 54948,     0,     1, 49152, 53248, 55296, 54784, 
+    54912, 54944, 54952, 54950,     0,     1, 49152, 53248, 
+    55296, 54784, 54912, 54944,     0,     1, 49152, 53248, 
+    55296, 54784, 54912, 54944, 54952,     0,     1, 49152, 
+    53248, 55296, 54784, 54912, 54944, 54952,     0,     1, 
+    49152, 53248, 55296, 54784, 54912, 54944, 54952, 54954, 
+        0,     1, 49152, 53248, 55296, 54784, 54912, 54944, 
+    54952,     0,     1, 49152, 53248, 55296, 54784, 54912, 
+    54944, 54960, 54956,     0,     1, 49152, 53248, 55296, 
+    54784, 54912, 54944, 54960, 54956,     0,     1, 49152, 
+    53248, 55296, 54784, 54912, 54944, 54960, 54961, 54958, 
+        0,     1, 49152, 53248, 55296, 54784, 54912, 54944, 
+        0,     1, 49152, 53248, 55296, 54784, 54912, 54976, 
+    54960,     0,     1, 49152, 53248, 55296, 54784, 54912, 
+    54976, 54960,     0,     1, 49152, 53248, 55296, 54784, 
+    54912, 54976, 54960, 54962,     0,     1, 49152, 53248, 
+    55296, 54784, 54912, 54976, 54960,     0,     1, 49152, 
+    53248, 55296, 54784, 54912, 54976, 54960, 54964,     0, 
+        1, 49152, 53248, 55296, 54784, 54912, 54976, 54960, 
+    54964,     0,     1, 49152, 53248, 55296, 54784, 54912, 
+    54976, 54960, 54968, 54966,     0,     1, 49152, 53248, 
+    55296, 54784, 54912, 54976, 54960,     0,     1, 49152, 
+    53248, 55296, 54784, 54912, 54976, 54977, 54968,     0, 
+        1, 49152, 53248, 55296, 54784, 54912, 54976, 54977, 
+    54968,     0,     1, 49152, 53248, 55296, 54784, 54912, 
+    54976, 54977, 54968, 54970,     0,     1, 49152, 53248, 
+    55296, 54784, 54912, 54976, 54977, 54968,     0,     1, 
+    49152, 53248, 55296, 54784, 54912, 54976, 54977, 54968, 
+    54972,     0,     1, 49152, 53248, 55296, 54784, 54912, 
+    54976, 54977, 54979, 54972,     0,     1, 49152, 53248, 
+    55296, 54784, 54912, 54976, 54977, 54979, 54972, 54974, 
+        0,     1, 49152, 53248, 55296, 54784, 54912,     0, 
+        1, 49152, 53248, 55296, 54784, 55040, 54976,     0, 
+        1, 49152, 53248, 55296, 54784, 55040, 54976,     0, 
+        1, 49152, 53248, 55296, 54784, 55040, 54976, 54978, 
+        0,     1, 49152, 53248, 55296, 54784, 55040, 54976, 
+        0,     1, 49152, 53248, 55296, 54784, 55040, 54976, 
+    54980,     0,     1, 49152, 53248, 55296, 54784, 55040, 
+    54976, 54980,     0,     1, 49152, 53248, 55296, 54784, 
+    55040, 54976, 54984, 54982,     0,     1, 49152, 53248, 
+    55296, 54784, 55040, 54976,     0,     1, 49152, 53248, 
+    55296, 54784, 55040, 54976, 54984,     0,     1, 49152, 
+    53248, 55296, 54784, 55040, 54976, 54984,     0,     1, 
+    49152, 53248, 55296, 54784, 55040, 54976, 54984, 54986, 
+        0,     1, 49152, 53248, 55296, 54784, 55040, 54976, 
+    54984,     0,     1, 49152, 53248, 55296, 54784, 55040, 
+    54976, 54992, 54988,     0,     1, 49152, 53248, 55296, 
+    54784, 55040, 54976, 54992, 54988,     0,     1, 49152, 
+    53248, 55296, 54784, 55040, 54976, 54992, 54993, 54990, 
+        0,     1, 49152, 53248, 55296, 54784, 55040, 54976, 
+        0,     1, 49152, 53248, 55296, 54784, 55040, 54976, 
+    54992,     0,     1, 49152, 53248, 55296, 54784, 55040, 
+    54976, 54992,     0,     1, 49152, 53248, 55296, 54784, 
+    55040, 54976, 54992, 54994,     0,     1, 49152, 53248, 
+    55296, 54784, 55040, 54976, 54992,     0,     1, 49152, 
+    53248, 55296, 54784, 55040, 54976, 54992, 54996,     0, 
+        1, 49152, 53248, 55296, 54784, 55040, 54976, 54992, 
+    54996,     0,     1, 49152, 53248, 55296, 54784, 55040, 
+    54976, 54992, 55000, 54998,     0,     1, 49152, 53248, 
+    55296, 54784, 55040, 54976, 54992,     0,     1, 49152, 
+    53248, 55296, 54784, 55040, 54976, 55008, 55000,     0, 
+        1, 49152, 53248, 55296, 54784, 55040, 54976, 55008, 
+    55000,     0,     1, 49152, 53248, 55296, 54784, 55040, 
+    54976, 55008, 55000, 55002,     0,     1, 49152, 53248, 
+    55296, 54784, 55040, 54976, 55008, 55000,     0,     1, 
+    49152, 53248, 55296, 54784, 55040, 54976, 55008, 55009, 
+    55004,     0,     1, 49152, 53248, 55296, 54784, 55040, 
+    54976, 55008, 55009, 55004,     0,     1, 49152, 53248, 
+    55296, 54784, 55040, 54976, 55008, 55009, 55004, 55006, 
+        0,     1, 49152, 53248, 55296, 54784, 55040, 54976, 
+        0,     1, 49152, 53248, 55296, 54784, 55040, 55041, 
+    55008,     0,     1, 49152, 53248, 55296, 54784, 55040, 
+    55041, 55008,     0,     1, 49152, 53248, 55296, 54784, 
+    55040, 55041, 55008, 55010,     0,     1, 49152, 53248, 
+    55296, 54784, 55040, 55041, 55008,     0,     1, 49152, 
+    53248, 55296, 54784, 55040, 55041, 55008, 55012,     0, 
+        1, 49152, 53248, 55296, 54784, 55040, 55041, 55008, 
+    55012,     0,     1, 49152, 53248, 55296, 54784, 55040, 
+    55041, 55008, 55016, 55014,     0,     1, 49152, 53248, 
+    55296, 54784, 55040, 55041, 55008,     0,     1, 49152, 
+    53248, 55296, 54784, 55040, 55041, 55008, 55016,     0, 
+        1, 49152, 53248, 55296, 54784, 55040, 55041, 55008, 
+    55016,     0,     1, 49152, 53248, 55296, 54784, 55040, 
+    55041, 55008, 55016, 55018,     0,     1, 49152, 53248, 
+    55296, 54784, 55040, 55041, 55008, 55016,     0,     1, 
+    49152, 53248, 55296, 54784, 55040, 55041, 55008, 55024, 
+    55020,     0,     1, 49152, 53248, 55296, 54784, 55040, 
+    55041, 55008, 55024, 55020,     0,     1, 49152, 53248, 
+    55296, 54784, 55040, 55041, 55008, 55024, 55025, 55022, 
+        0,     1, 49152, 53248, 55296, 54784, 55040, 55041, 
+    55008,     0,     1, 49152, 53248, 55296, 54784, 55040, 
+    55041, 55008, 55024,     0,     1, 49152, 53248, 55296, 
+    54784, 55040, 55041, 55043, 55024,     0,     1, 49152, 
+    53248, 55296, 54784, 55040, 55041, 55043, 55024, 55026, 
+        0,     1, 49152, 53248, 55296, 54784, 55040, 55041, 
+    55043, 55024,     0,     1, 49152, 53248, 55296, 54784, 
+    55040, 55041, 55043, 55024, 55028,     0,     1, 49152, 
+    53248, 55296, 54784, 55040, 55041, 55043, 55024, 55028, 
+        0,     1, 49152, 53248, 55296, 54784, 55040, 55041, 
+    55043, 55024, 55032, 55030,     0,     1, 49152, 53248, 
+    55296, 54784, 55040, 55041, 55043, 55024,     0,     1, 
+    49152, 53248, 55296, 54784, 55040, 55041, 55043, 55024, 
+    55032,     0,     1, 49152, 53248, 55296, 54784, 55040, 
+    55041, 55043, 55024, 55032,     0,     1, 49152, 53248, 
+    55296, 54784, 55040, 55041, 55043, 55024, 55032, 55034, 
+        0,     1, 49152, 53248, 55296, 54784, 55040, 55041, 
+    55043, 55047, 55032,     0,     1, 49152, 53248, 55296, 
+    54784, 55040, 55041, 55043, 55047, 55032, 55036,     0, 
+        1, 49152, 53248, 55296, 54784, 55040, 55041, 55043, 
+    55047, 55032, 55036,     0,     1, 49152, 53248, 55296, 
+    54784, 55040, 55041, 55043, 55047, 55032, 55036, 55038, 
+        0,     1, 49152, 53248, 55296, 54784,     0,     1, 
+    49152, 53248, 55296, 54784, 55040,     0,     1, 49152, 
+    53248, 55296, 55297, 55040,     0,     1, 49152, 53248, 
+    55296, 55297, 55040, 55042,     0,     1, 49152, 53248, 
+    55296, 55297, 55040,     0,     1, 49152, 53248, 55296, 
+    55297, 55040, 55044,     0,     1, 49152, 53248, 55296, 
+    55297, 55040, 55044,     0,     1, 49152, 53248, 55296, 
+    55297, 55040, 55048, 55046,     0,     1, 49152, 53248, 
+    55296, 55297, 55040,     0,     1, 49152, 53248, 55296, 
+    55297, 55040, 55048,     0,     1, 49152, 53248, 55296, 
+    55297, 55040, 55048,     0,     1, 49152, 53248, 55296, 
+    55297, 55040, 55048, 55050,     0,     1, 49152, 53248, 
+    55296, 55297, 55040, 55048,     0,     1, 49152, 53248, 
+    55296, 55297, 55040, 55056, 55052,     0,     1, 49152, 
+    53248, 55296, 55297, 55040, 55056, 55052,     0,     1, 
+    49152, 53248, 55296, 55297, 55040, 55056, 55057, 55054, 
+        0,     1, 49152, 53248, 55296, 55297, 55040,     0, 
+        1, 49152, 53248, 55296, 55297, 55040, 55056,     0, 
+        1, 49152, 53248, 55296, 55297, 55040, 55056,     0, 
+        1, 49152, 53248, 55296, 55297, 55040, 55056, 55058, 
+        0,     1, 49152, 53248, 55296, 55297, 55040, 55056, 
+        0,     1, 49152, 53248, 55296, 55297, 55040, 55056, 
+    55060,     0,     1, 49152, 53248, 55296, 55297, 55040, 
+    55056, 55060,     0,     1, 49152, 53248, 55296, 55297, 
+    55040, 55056, 55064, 55062,     0,     1, 49152, 53248, 
+    55296, 55297, 55040, 55056,     0,     1, 49152, 53248, 
+    55296, 55297, 55040, 55072, 55064,     0,     1, 49152, 
+    53248, 55296, 55297, 55040, 55072, 55064,     0,     1, 
+    49152, 53248, 55296, 55297, 55040, 55072, 55064, 55066, 
+        0,     1, 49152, 53248, 55296, 55297, 55040, 55072, 
+    55064,     0,     1, 49152, 53248, 55296, 55297, 55040, 
+    55072, 55073, 55068,     0,     1, 49152, 53248, 55296, 
+    55297, 55040, 55072, 55073, 55068,     0,     1, 49152, 
+    53248, 55296, 55297, 55040, 55072, 55073, 55068, 55070, 
+        0,     1, 49152, 53248, 55296, 55297, 55040,     0, 
+        1, 49152, 53248, 55296, 55297, 55040, 55072,     0, 
+        1, 49152, 53248, 55296, 55297, 55040, 55072,     0, 
+        1, 49152, 53248, 55296, 55297, 55040, 55072, 55074, 
+        0,     1, 49152, 53248, 55296, 55297, 55040, 55072, 
+        0,     1, 49152, 53248, 55296, 55297, 55040, 55072, 
+    55076,     0,     1, 49152, 53248, 55296, 55297, 55040, 
+    55072, 55076,     0,     1, 49152, 53248, 55296, 55297, 
+    55040, 55072, 55080, 55078,     0,     1, 49152, 53248, 
+    55296, 55297, 55040, 55072,     0,     1, 49152, 53248, 
+    55296, 55297, 55040, 55072, 55080,     0,     1, 49152, 
+    53248, 55296, 55297, 55040, 55072, 55080,     0,     1, 
+    49152, 53248, 55296, 55297, 55040, 55072, 55080, 55082, 
+        0,     1, 49152, 53248, 55296, 55297, 55040, 55072, 
+    55080,     0,     1, 49152, 53248, 55296, 55297, 55040, 
+    55072, 55088, 55084,     0,     1, 49152, 53248, 55296, 
+    55297, 55040, 55072, 55088, 55084,     0,     1, 49152, 
+    53248, 55296, 55297, 55040, 55072, 55088, 55089, 55086, 
+        0,     1, 49152, 53248, 55296, 55297, 55040, 55072, 
+        0,     1, 49152, 53248, 55296, 55297, 55040, 55104, 
+    55088,     0,     1, 49152, 53248, 55296, 55297, 55040, 
+    55104, 55088,     0,     1, 49152, 53248, 55296, 55297, 
+    55040, 55104, 55088, 55090,     0,     1, 49152, 53248, 
+    55296, 55297, 55040, 55104, 55088,     0,     1, 49152, 
+    53248, 55296, 55297, 55040, 55104, 55088, 55092,     0, 
+        1, 49152, 53248, 55296, 55297, 55040, 55104, 55088, 
+    55092,     0,     1, 49152, 53248, 55296, 55297, 55040, 
+    55104, 55088, 55096, 55094,     0,     1, 49152, 53248, 
+    55296, 55297, 55040, 55104, 55088,     0,     1, 49152, 
+    53248, 55296, 55297, 55040, 55104, 55105, 55096,     0, 
+        1, 49152, 53248, 55296, 55297, 55040, 55104, 55105, 
+    55096,     0,     1, 49152, 53248, 55296, 55297, 55040, 
+    55104, 55105, 55096, 55098,     0,     1, 49152, 53248, 
+    55296, 55297, 55040, 55104, 55105, 55096,     0,     1, 
+    49152, 53248, 55296, 55297, 55040, 55104, 55105, 55096, 
+    55100,     0,     1, 49152, 53248, 55296, 55297, 55040, 
+    55104, 55105, 55107, 55100,     0,     1, 49152, 53248, 
+    55296, 55297, 55040, 55104, 55105, 55107, 55100, 55102, 
+        0,     1, 49152, 53248, 55296, 55297, 55040,     0, 
+        1, 49152, 53248, 55296, 55297, 55040, 55104,     0, 
+        1, 49152, 53248, 55296, 55297, 55040, 55104,     0, 
+        1, 49152, 53248, 55296, 55297, 55040, 55104, 55106, 
+        0,     1, 49152, 53248, 55296, 55297, 55040, 55104, 
+        0,     1, 49152, 53248, 55296, 55297, 55040, 55104, 
+    55108,     0,     1, 49152, 53248, 55296, 55297, 55040, 
+    55104, 55108,     0,     1, 49152, 53248, 55296, 55297, 
+    55040, 55104, 55112, 55110,     0,     1, 49152, 53248, 
+    55296, 55297, 55040, 55104,     0,     1, 49152, 53248, 
+    55296, 55297, 55040, 55104, 55112,     0,     1, 49152, 
+    53248, 55296, 55297, 55040, 55104, 55112,     0,     1, 
+    49152, 53248, 55296, 55297, 55040, 55104, 55112, 55114, 
+        0,     1, 49152, 53248, 55296, 55297, 55040, 55104, 
+    55112,     0,     1, 49152, 53248, 55296, 55297, 55040, 
+    55104, 55120, 55116,     0,     1, 49152, 53248, 55296, 
+    55297, 55040, 55104, 55120, 55116,     0,     1, 49152, 
+    53248, 55296, 55297, 55040, 55104, 55120, 55121, 55118, 
+        0,     1, 49152, 53248, 55296, 55297, 55040, 55104, 
+        0,     1, 49152, 53248, 55296, 55297, 55040, 55104, 
+    55120,     0,     1, 49152, 53248, 55296, 55297, 55040, 
+    55104, 55120,     0,     1, 49152, 53248, 55296, 55297, 
+    55040, 55104, 55120, 55122,     0,     1, 49152, 53248, 
+    55296, 55297, 55040, 55104, 55120,     0,     1, 49152, 
+    53248, 55296, 55297, 55040, 55104, 55120, 55124,     0, 
+        1, 49152, 53248, 55296, 55297, 55040, 55104, 55120, 
+    55124,     0,     1, 49152, 53248, 55296, 55297, 55040, 
+    55104, 55120, 55128, 55126,     0,     1, 49152, 53248, 
+    55296, 55297, 55040, 55104, 55120,     0,     1, 49152, 
+    53248, 55296, 55297, 55040, 55104, 55136, 55128,     0, 
+        1, 49152, 53248, 55296, 55297, 55040, 55104, 55136, 
+    55128,     0,     1, 49152, 53248, 55296, 55297, 55040, 
+    55104, 55136, 55128, 55130,     0,     1, 49152, 53248, 
+    55296, 55297, 55040, 55104, 55136, 55128,     0,     1, 
+    49152, 53248, 55296, 55297, 55040, 55104, 55136, 55137, 
+    55132,     0,     1, 49152, 53248, 55296, 55297, 55040, 
+    55104, 55136, 55137, 55132,     0,     1, 49152, 53248, 
+    55296, 55297, 55040, 55104, 55136, 55137, 55132, 55134, 
+        0,     1, 49152, 53248, 55296, 55297, 55040, 55104, 
+        0,     1, 49152, 53248, 55296, 55297, 55040, 55168, 
+    55136,     0,     1, 49152, 53248, 55296, 55297, 55040, 
+    55168, 55136,     0,     1, 49152, 53248, 55296, 55297, 
+    55040, 55168, 55136, 55138,     0,     1, 49152, 53248, 
+    55296, 55297, 55040, 55168, 55136,     0,     1, 49152, 
+    53248, 55296, 55297, 55040, 55168, 55136, 55140,     0, 
+        1, 49152, 53248, 55296, 55297, 55040, 55168, 55136, 
+    55140,     0,     1, 49152, 53248, 55296, 55297, 55040, 
+    55168, 55136, 55144, 55142,     0,     1, 49152, 53248, 
+    55296, 55297, 55040, 55168, 55136,     0,     1, 49152, 
+    53248, 55296, 55297, 55040, 55168, 55136, 55144,     0, 
+        1, 49152, 53248, 55296, 55297, 55040, 55168, 55136, 
+    55144,     0,     1, 49152, 53248, 55296, 55297, 55040, 
+    55168, 55136, 55144, 55146,     0,     1, 49152, 53248, 
+    55296, 55297, 55040, 55168, 55136, 55144,     0,     1, 
+    49152, 53248, 55296, 55297, 55040, 55168, 55136, 55152, 
+    55148,     0,     1, 49152, 53248, 55296, 55297, 55040, 
+    55168, 55136, 55152, 55148,     0,     1, 49152, 53248, 
+    55296, 55297, 55040, 55168, 55136, 55152, 55153, 55150, 
+        0,     1, 49152, 53248, 55296, 55297, 55040, 55168, 
+    55136,     0,     1, 49152, 53248, 55296, 55297, 55040, 
+    55168, 55169, 55152,     0,     1, 49152, 53248, 55296, 
+    55297, 55040, 55168, 55169, 55152,     0,     1, 49152, 
+    53248, 55296, 55297, 55040, 55168, 55169, 55152, 55154, 
+        0,     1, 49152, 53248, 55296, 55297, 55040, 55168, 
+    55169, 55152,     0,     1, 49152, 53248, 55296, 55297, 
+    55040, 55168, 55169, 55152, 55156,     0,     1, 49152, 
+    53248, 55296, 55297, 55040, 55168, 55169, 55152, 55156, 
+        0,     1, 49152, 53248, 55296, 55297, 55040, 55168, 
+    55169, 55152, 55160, 55158,     0,     1, 49152, 53248, 
+    55296, 55297, 55040, 55168, 55169, 55152,     0,     1, 
+    49152, 53248, 55296, 55297, 55040, 55168, 55169, 55152, 
+    55160,     0,     1, 49152, 53248, 55296, 55297, 55040, 
+    55168, 55169, 55171, 55160,     0,     1, 49152, 53248, 
+    55296, 55297, 55040, 55168, 55169, 55171, 55160, 55162, 
+        0,     1, 49152, 53248, 55296, 55297, 55040, 55168, 
+    55169, 55171, 55160,     0,     1, 49152, 53248, 55296, 
+    55297, 55040, 55168, 55169, 55171, 55160, 55164,     0, 
+        1, 49152, 53248, 55296, 55297, 55040, 55168, 55169, 
+    55171, 55160, 55164,     0,     1, 49152, 53248, 55296, 
+    55297, 55040, 55168, 55169, 55171, 55160, 55164, 55166, 
+        0,     1, 49152, 53248, 55296, 55297, 55040,     0, 
+        1, 49152, 53248, 55296, 55297, 55040, 55168,     0, 
+        1, 49152, 53248, 55296, 55297, 55040, 55168,     0, 
+        1, 49152, 53248, 55296, 55297, 55040, 55168, 55170, 
+        0,     1, 49152, 53248, 55296, 55297, 55299, 55168, 
+        0,     1, 49152, 53248, 55296, 55297, 55299, 55168, 
+    55172,     0,     1, 49152, 53248, 55296, 55297, 55299, 
+    55168, 55172,     0,     1, 49152, 53248, 55296, 55297, 
+    55299, 55168, 55176, 55174,     0,     1, 49152, 53248, 
+    55296, 55297, 55299, 55168,     0,     1, 49152, 53248, 
+    55296, 55297, 55299, 55168, 55176,     0,     1, 49152, 
+    53248, 55296, 55297, 55299, 55168, 55176,     0,     1, 
+    49152, 53248, 55296, 55297, 55299, 55168, 55176, 55178, 
+        0,     1, 49152, 53248, 55296, 55297, 55299, 55168, 
+    55176,     0,     1, 49152, 53248, 55296, 55297, 55299, 
+    55168, 55184, 55180,     0,     1, 49152, 53248, 55296, 
+    55297, 55299, 55168, 55184, 55180,     0,     1, 49152, 
+    53248, 55296, 55297, 55299, 55168, 55184, 55185, 55182, 
+        0,     1, 49152, 53248, 55296, 55297, 55299, 55168, 
+        0,     1, 49152, 53248, 55296, 55297, 55299, 55168, 
+    55184,     0,     1, 49152, 53248, 55296, 55297, 55299, 
+    55168, 55184,     0,     1, 49152, 53248, 55296, 55297, 
+    55299, 55168, 55184, 55186,     0,     1, 49152, 53248, 
+    55296, 55297, 55299, 55168, 55184,     0,     1, 49152, 
+    53248, 55296, 55297, 55299, 55168, 55184, 55188,     0, 
+        1, 49152, 53248, 55296, 55297, 55299, 55168, 55184, 
+    55188,     0,     1, 49152, 53248, 55296, 55297, 55299, 
+    55168, 55184, 55192, 55190,     0,     1, 49152, 53248, 
+    55296, 55297, 55299, 55168, 55184,     0,     1, 49152, 
+    53248, 55296, 55297, 55299, 55168, 55200, 55192,     0, 
+        1, 49152, 53248, 55296, 55297, 55299, 55168, 55200, 
+    55192,     0,     1, 49152, 53248, 55296, 55297, 55299, 
+    55168, 55200, 55192, 55194,     0,     1, 49152, 53248, 
+    55296, 55297, 55299, 55168, 55200, 55192,     0,     1, 
+    49152, 53248, 55296, 55297, 55299, 55168, 55200, 55201, 
+    55196,     0,     1, 49152, 53248, 55296, 55297, 55299, 
+    55168, 55200, 55201, 55196,     0,     1, 49152, 53248, 
+    55296, 55297, 55299, 55168, 55200, 55201, 55196, 55198, 
+        0,     1, 49152, 53248, 55296, 55297, 55299, 55168, 
+        0,     1, 49152, 53248, 55296, 55297, 55299, 55168, 
+    55200,     0,     1, 49152, 53248, 55296, 55297, 55299, 
+    55168, 55200,     0,     1, 49152, 53248, 55296, 55297, 
+    55299, 55168, 55200, 55202,     0,     1, 49152, 53248, 
+    55296, 55297, 55299, 55168, 55200,     0,     1, 49152, 
+    53248, 55296, 55297, 55299, 55168, 55200, 55204,     0, 
+        1, 49152, 53248, 55296, 55297, 55299, 55168, 55200, 
+    55204,     0,     1, 49152, 53248, 55296, 55297, 55299, 
+    55168, 55200, 55208, 55206,     0,     1, 49152, 53248, 
+    55296, 55297, 55299, 55168, 55200,     0,     1, 49152, 
+    53248, 55296, 55297, 55299, 55168, 55200, 55208,     0, 
+        1, 49152, 53248, 55296, 55297, 55299, 55168, 55200, 
+    55208,     0,     1, 49152, 53248, 55296, 55297, 55299, 
+    55168, 55200, 55208, 55210,     0,     1, 49152, 53248, 
+    55296, 55297, 55299, 55168, 55200, 55208,     0,     1, 
+    49152, 53248, 55296, 55297, 55299, 55168, 55200, 55216, 
+    55212,     0,     1, 49152, 53248, 55296, 55297, 55299, 
+    55168, 55200, 55216, 55212,     0,     1, 49152, 53248, 
+    55296, 55297, 55299, 55168, 55200, 55216, 55217, 55214, 
+        0,     1, 49152, 53248, 55296, 55297, 55299, 55168, 
+    55200,     0,     1, 49152, 53248, 55296, 55297, 55299, 
+    55168, 55232, 55216,     0,     1, 49152, 53248, 55296, 
+    55297, 55299, 55168, 55232, 55216,     0,     1, 49152, 
+    53248, 55296, 55297, 55299, 55168, 55232, 55216, 55218, 
+        0,     1, 49152, 53248, 55296, 55297, 55299, 55168, 
+    55232, 55216,     0,     1, 49152, 53248, 55296, 55297, 
+    55299, 55168, 55232, 55216, 55220,     0,     1, 49152, 
+    53248, 55296, 55297, 55299, 55168, 55232, 55216, 55220, 
+        0,     1, 49152, 53248, 55296, 55297, 55299, 55168, 
+    55232, 55216, 55224, 55222,     0,     1, 49152, 53248, 
+    55296, 55297, 55299, 55168, 55232, 55216,     0,     1, 
+    49152, 53248, 55296, 55297, 55299, 55168, 55232, 55233, 
+    55224,     0,     1, 49152, 53248, 55296, 55297, 55299, 
+    55168, 55232, 55233, 55224,     0,     1, 49152, 53248, 
+    55296, 55297, 55299, 55168, 55232, 55233, 55224, 55226, 
+        0,     1, 49152, 53248, 55296, 55297, 55299, 55168, 
+    55232, 55233, 55224,     0,     1, 49152, 53248, 55296, 
+    55297, 55299, 55168, 55232, 55233, 55224, 55228,     0, 
+        1, 49152, 53248, 55296, 55297, 55299, 55168, 55232, 
+    55233, 55235, 55228,     0,     1, 49152, 53248, 55296, 
+    55297, 55299, 55168, 55232, 55233, 55235, 55228, 55230, 
+        0,     1, 49152, 53248, 55296, 55297, 55299, 55168, 
+        0,     1, 49152, 53248, 55296, 55297, 55299, 55168, 
+    55232,     0,     1, 49152, 53248, 55296, 55297, 55299, 
+    55168, 55232,     0,     1, 49152, 53248, 55296, 55297, 
+    55299, 55168, 55232, 55234,     0,     1, 49152, 53248, 
+    55296, 55297, 55299, 55168, 55232,     0,     1, 49152, 
+    53248, 55296, 55297, 55299, 55168, 55232, 55236,     0, 
+        1, 49152, 53248, 55296, 55297, 55299, 55168, 55232, 
+    55236,     0,     1, 49152, 53248, 55296, 55297, 55299, 
+    55168, 55232, 55240, 55238,     0,     1, 49152, 53248, 
+    55296, 55297, 55299, 55303, 55232,     0,     1, 49152, 
+    53248, 55296, 55297, 55299, 55303, 55232, 55240,     0, 
+        1, 49152, 53248, 55296, 55297, 55299, 55303, 55232, 
+    55240,     0,     1, 49152, 53248, 55296, 55297, 55299, 
+    55303, 55232, 55240, 55242,     0,     1, 49152, 53248, 
+    55296, 55297, 55299, 55303, 55232, 55240,     0,     1, 
+    49152, 53248, 55296, 55297, 55299, 55303, 55232, 55248, 
+    55244,     0,     1, 49152, 53248, 55296, 55297, 55299, 
+    55303, 55232, 55248, 55244,     0,     1, 49152, 53248, 
+    55296, 55297, 55299, 55303, 55232, 55248, 55249, 55246, 
+        0,     1, 49152, 53248, 55296, 55297, 55299, 55303, 
+    55232,     0,     1, 49152, 53248, 55296, 55297, 55299, 
+    55303, 55232, 55248,     0,     1, 49152, 53248, 55296, 
+    55297, 55299, 55303, 55232, 55248,     0,     1, 49152, 
+    53248, 55296, 55297, 55299, 55303, 55232, 55248, 55250, 
+        0,     1, 49152, 53248, 55296, 55297, 55299, 55303, 
+    55232, 55248,     0,     1, 49152, 53248, 55296, 55297, 
+    55299, 55303, 55232, 55248, 55252,     0,     1, 49152, 
+    53248, 55296, 55297, 55299, 55303, 55232, 55248, 55252, 
+        0,     1, 49152, 53248, 55296, 55297, 55299, 55303, 
+    55232, 55248, 55256, 55254,     0,     1, 49152, 53248, 
+    55296, 55297, 55299, 55303, 55232, 55248,     0,     1, 
+    49152, 53248, 55296, 55297, 55299, 55303, 55232, 55264, 
+    55256,     0,     1, 49152, 53248, 55296, 55297, 55299, 
+    55303, 55232, 55264, 55256,     0,     1, 49152, 53248, 
+    55296, 55297, 55299, 55303, 55232, 55264, 55256, 55258, 
+        0,     1, 49152, 53248, 55296, 55297, 55299, 55303, 
+    55232, 55264, 55256,     0,     1, 49152, 53248, 55296, 
+    55297, 55299, 55303, 55232, 55264, 55265, 55260,     0, 
+        1, 49152, 53248, 55296, 55297, 55299, 55303, 55232, 
+    55264, 55265, 55260,     0,     1, 49152, 53248, 55296, 
+    55297, 55299, 55303, 55232, 55264, 55265, 55260, 55262, 
+        0,     1, 49152, 53248, 55296, 55297, 55299, 55303, 
+    55232,     0,     1, 49152, 53248, 55296, 55297, 55299, 
+    55303, 55232, 55264,     0,     1, 49152, 53248, 55296, 
+    55297, 55299, 55303, 55232, 55264,     0,     1, 49152, 
+    53248, 55296, 55297, 55299, 55303, 55232, 55264, 55266, 
+        0,     1, 49152, 53248, 55296, 55297, 55299, 55303, 
+    55232, 55264,     0,     1, 49152, 53248, 55296, 55297, 
+    55299, 55303, 55232, 55264, 55268,     0,     1, 49152, 
+    53248, 55296, 55297, 55299, 55303, 55232, 55264, 55268, 
+        0,     1, 49152, 53248, 55296, 55297, 55299, 55303, 
+    55232, 55264, 55272, 55270,     0,     1, 49152, 53248, 
+    55296, 55297, 55299, 55303, 55232, 55264,     0,     1, 
+    49152, 53248, 55296, 55297, 55299, 55303, 55232, 55264, 
+    55272,     0,     1, 49152, 53248, 55296, 55297, 55299, 
+    55303, 55232, 55264, 55272,     0,     1, 49152, 53248, 
+    55296, 55297, 55299, 55303, 55232, 55264, 55272, 55274, 
+        0,     1, 49152, 53248, 55296, 55297, 55299, 55303, 
+    55232, 55264, 55272,     0,     1, 49152, 53248, 55296, 
+    55297, 55299, 55303, 55232, 55264, 55280, 55276,     0, 
+        1, 49152, 53248, 55296, 55297, 55299, 55303, 55232, 
+    55264, 55280, 55276,     0,     1, 49152, 53248, 55296, 
+    55297, 55299, 55303, 55232, 55264, 55280, 55281, 55278, 
+        0,     1, 49152, 53248, 55296, 55297, 55299, 55303, 
+    55311, 55264,     0,     1, 49152, 53248, 55296, 55297, 
+    55299, 55303, 55311, 55264, 55280,     0,     1, 49152, 
+    53248, 55296, 55297, 55299, 55303, 55311, 55264, 55280, 
+        0,     1, 49152, 53248, 55296, 55297, 55299, 55303, 
+    55311, 55264, 55280, 55282,     0,     1, 49152, 53248, 
+    55296, 55297, 55299, 55303, 55311, 55264, 55280,     0, 
+        1, 49152, 53248, 55296, 55297, 55299, 55303, 55311, 
+    55264, 55280, 55284,     0,     1, 49152, 53248, 55296, 
+    55297, 55299, 55303, 55311, 55264, 55280, 55284,     0, 
+        1, 49152, 53248, 55296, 55297, 55299, 55303, 55311, 
+    55264, 55280, 55288, 55286,     0,     1, 49152, 53248, 
+    55296, 55297, 55299, 55303, 55311, 55264, 55280,     0, 
+        1, 49152, 53248, 55296, 55297, 55299, 55303, 55311, 
+    55264, 55280, 55288,     0,     1, 49152, 53248, 55296, 
+    55297, 55299, 55303, 55311, 55264, 55280, 55288,     0, 
+        1, 49152, 53248, 55296, 55297, 55299, 55303, 55311, 
+    55264, 55280, 55288, 55290,     0,     1, 49152, 53248, 
+    55296, 55297, 55299, 55303, 55311, 55264, 55280, 55288, 
+        0,     1, 49152, 53248, 55296, 55297, 55299, 55303, 
+    55311, 55264, 55280, 55288, 55292,     0,     1, 49152, 
+    53248, 55296, 55297, 55299, 55303, 55311, 55264, 55280, 
+    55288, 55292,     0,     1, 49152, 53248, 55296, 55297, 
+    55299, 55303, 55311, 55264, 55280, 55288, 55292, 55294, 
+        0,     1, 49152, 53248,     0,     1, 49152, 53248, 
+    55296,     0,     1, 49152, 53248, 55296,     0,     1, 
+    49152, 53248, 55296, 55298,     0,     1, 49152, 53248, 
+    55296,     0,     1, 49152, 53248, 55296, 55300,     0, 
+        1, 49152, 53248, 55296, 55300,     0,     1, 49152, 
+    53248, 55296, 55304, 55302,     0,     1, 49152, 53248, 
+    55296,     0,     1, 49152, 53248, 55296, 55304,     0, 
+        1, 49152, 53248, 55296, 55304,     0,     1, 49152, 
+    53248, 55296, 55304, 55306,     0,     1, 49152, 53248, 
+    55296, 55304,     0,     1, 49152, 53248, 55296, 55312, 
+    55308,     0,     1, 49152, 53248, 55296, 55312, 55308, 
+        0,     1, 49152, 53248, 55296, 55312, 55313, 55310, 
+        0,     1, 49152, 53248, 55296,     0,     1, 49152, 
+    53248, 55296, 55312,     0,     1, 49152, 53248, 55296, 
+    55312,     0,     1, 49152, 53248, 55296, 55312, 55314, 
+        0,     1, 49152, 53248, 55296, 55312,     0,     1, 
+    49152, 53248, 55296, 55312, 55316,     0,     1, 49152, 
+    53248, 55296, 55312, 55316,     0,     1, 49152, 53248, 
+    55296, 55312, 55320, 55318,     0,     1, 49152, 53248, 
+    55296, 55312,     0,     1, 49152, 53248, 55296, 55328, 
+    55320,     0,     1, 49152, 53248, 55296, 55328, 55320, 
+        0,     1, 49152, 53248, 55296, 55328, 55320, 55322, 
+        0,     1, 49152, 53248, 55296, 55328, 55320,     0, 
+        1, 49152, 53248, 55296, 55328, 55329, 55324,     0, 
+        1, 49152, 53248, 55296, 55328, 55329, 55324,     0, 
+        1, 49152, 53248, 55296, 55328, 55329, 55324, 55326, 
+        0,     1, 49152, 53248, 55296,     0,     1, 49152, 
+    53248, 55296, 55328,     0,     1, 49152, 53248, 55296, 
+    55328,     0,     1, 49152, 53248, 55296, 55328, 55330, 
+        0,     1, 49152, 53248, 55296, 55328,     0,     1, 
+    49152, 53248, 55296, 55328, 55332,     0,     1, 49152, 
+    53248, 55296, 55328, 55332,     0,     1, 49152, 53248, 
+    55296, 55328, 55336, 55334,     0,     1, 49152, 53248, 
+    55296, 55328,     0,     1, 49152, 53248, 55296, 55328, 
+    55336,     0,     1, 49152, 53248, 55296, 55328, 55336, 
+        0,     1, 49152, 53248, 55296, 55328, 55336, 55338, 
+        0,     1, 49152, 53248, 55296, 55328, 55336,     0, 
+        1, 49152, 53248, 55296, 55328, 55344, 55340,     0, 
+        1, 49152, 53248, 55296, 55328, 55344, 55340,     0, 
+        1, 49152, 53248, 55296, 55328, 55344, 55345, 55342, 
+        0,     1, 49152, 53248, 55296, 55328,     0,     1, 
+    49152, 53248, 55296, 55360, 55344,     0,     1, 49152, 
+    53248, 55296, 55360, 55344,     0,     1, 49152, 53248, 
+    55296, 55360, 55344, 55346,     0,     1, 49152, 53248, 
+    55296, 55360, 55344,     0,     1, 49152, 53248, 55296, 
+    55360, 55344, 55348,     0,     1, 49152, 53248, 55296, 
+    55360, 55344, 55348,     0,     1, 49152, 53248, 55296, 
+    55360, 55344, 55352, 55350,     0,     1, 49152, 53248, 
+    55296, 55360, 55344,     0,     1, 49152, 53248, 55296, 
+    55360, 55361, 55352,     0,     1, 49152, 53248, 55296, 
+    55360, 55361, 55352,     0,     1, 49152, 53248, 55296, 
+    55360, 55361, 55352, 55354,     0,     1, 49152, 53248, 
+    55296, 55360, 55361, 55352,     0,     1, 49152, 53248, 
+    55296, 55360, 55361, 55352, 55356,     0,     1, 49152, 
+    53248, 55296, 55360, 55361, 55363, 55356,     0,     1, 
+    49152, 53248, 55296, 55360, 55361, 55363, 55356, 55358, 
+        0,     1, 49152, 53248, 55296,     0,     1, 49152, 
+    53248, 55296, 55360,     0,     1, 49152, 53248, 55296, 
+    55360,     0,     1, 49152, 53248, 55296, 55360, 55362, 
+        0,     1, 49152, 53248, 55296, 55360,     0,     1, 
+    49152, 53248, 55296, 55360, 55364,     0,     1, 49152, 
+    53248, 55296, 55360, 55364,     0,     1, 49152, 53248, 
+    55296, 55360, 55368, 55366,     0,     1, 49152, 53248, 
+    55296, 55360,     0,     1, 49152, 53248, 55296, 55360, 
+    55368,     0,     1, 49152, 53248, 55296, 55360, 55368, 
+        0,     1, 49152, 53248, 55296, 55360, 55368, 55370, 
+        0,     1, 49152, 53248, 55296, 55360, 55368,     0, 
+        1, 49152, 53248, 55296, 55360, 55376, 55372,     0, 
+        1, 49152, 53248, 55296, 55360, 55376, 55372,     0, 
+        1, 49152, 53248, 55296, 55360, 55376, 55377, 55374, 
+        0,     1, 49152, 53248, 55296, 55360,     0,     1, 
+    49152, 53248, 55296, 55360, 55376,     0,     1, 49152, 
+    53248, 55296, 55360, 55376,     0,     1, 49152, 53248, 
+    55296, 55360, 55376, 55378,     0,     1, 49152, 53248, 
+    55296, 55360, 55376,     0,     1, 49152, 53248, 55296, 
+    55360, 55376, 55380,     0,     1, 49152, 53248, 55296, 
+    55360, 55376, 55380,     0,     1, 49152, 53248, 55296, 
+    55360, 55376, 55384, 55382,     0,     1, 49152, 53248, 
+    55296, 55360, 55376,     0,     1, 49152, 53248, 55296, 
+    55360, 55392, 55384,     0,     1, 49152, 53248, 55296, 
+    55360, 55392, 55384,     0,     1, 49152, 53248, 55296, 
+    55360, 55392, 55384, 55386,     0,     1, 49152, 53248, 
+    55296, 55360, 55392, 55384,     0,     1, 49152, 53248, 
+    55296, 55360, 55392, 55393, 55388,     0,     1, 49152, 
+    53248, 55296, 55360, 55392, 55393, 55388,     0,     1, 
+    49152, 53248, 55296, 55360, 55392, 55393, 55388, 55390, 
+        0,     1, 49152, 53248, 55296, 55360,     0,     1, 
+    49152, 53248, 55296, 55424, 55392,     0,     1, 49152, 
+    53248, 55296, 55424, 55392,     0,     1, 49152, 53248, 
+    55296, 55424, 55392, 55394,     0,     1, 49152, 53248, 
+    55296, 55424, 55392,     0,     1, 49152, 53248, 55296, 
+    55424, 55392, 55396,     0,     1, 49152, 53248, 55296, 
+    55424, 55392, 55396,     0,     1, 49152, 53248, 55296, 
+    55424, 55392, 55400, 55398,     0,     1, 49152, 53248, 
+    55296, 55424, 55392,     0,     1, 49152, 53248, 55296, 
+    55424, 55392, 55400,     0,     1, 49152, 53248, 55296, 
+    55424, 55392, 55400,     0,     1, 49152, 53248, 55296, 
+    55424, 55392, 55400, 55402,     0,     1, 49152, 53248, 
+    55296, 55424, 55392, 55400,     0,     1, 49152, 53248, 
+    55296, 55424, 55392, 55408, 55404,     0,     1, 49152, 
+    53248, 55296, 55424, 55392, 55408, 55404,     0,     1, 
+    49152, 53248, 55296, 55424, 55392, 55408, 55409, 55406, 
+        0,     1, 49152, 53248, 55296, 55424, 55392,     0, 
+        1, 49152, 53248, 55296, 55424, 55425, 55408,     0, 
+        1, 49152, 53248, 55296, 55424, 55425, 55408,     0, 
+        1, 49152, 53248, 55296, 55424, 55425, 55408, 55410, 
+        0,     1, 49152, 53248, 55296, 55424, 55425, 55408, 
+        0,     1, 49152, 53248, 55296, 55424, 55425, 55408, 
+    55412,     0,     1, 49152, 53248, 55296, 55424, 55425, 
+    55408, 55412,     0,     1, 49152, 53248, 55296, 55424, 
+    55425, 55408, 55416, 55414,     0,     1, 49152, 53248, 
+    55296, 55424, 55425, 55408,     0,     1, 49152, 53248, 
+    55296, 55424, 55425, 55408, 55416,     0,     1, 49152, 
+    53248, 55296, 55424, 55425, 55427, 55416,     0,     1, 
+    49152, 53248, 55296, 55424, 55425, 55427, 55416, 55418, 
+        0,     1, 49152, 53248, 55296, 55424, 55425, 55427, 
+    55416,     0,     1, 49152, 53248, 55296, 55424, 55425, 
+    55427, 55416, 55420,     0,     1, 49152, 53248, 55296, 
+    55424, 55425, 55427, 55416, 55420,     0,     1, 49152, 
+    53248, 55296, 55424, 55425, 55427, 55416, 55420, 55422, 
+        0,     1, 49152, 53248, 55296,     0,     1, 49152, 
+    53248, 55296, 55424,     0,     1, 49152, 53248, 55296, 
+    55424,     0,     1, 49152, 53248, 55296, 55424, 55426, 
+        0,     1, 49152, 53248, 55296, 55424,     0,     1, 
+    49152, 53248, 55296, 55424, 55428,     0,     1, 49152, 
+    53248, 55296, 55424, 55428,     0,     1, 49152, 53248, 
+    55296, 55424, 55432, 55430,     0,     1, 49152, 53248, 
+    55296, 55424,     0,     1, 49152, 53248, 55296, 55424, 
+    55432,     0,     1, 49152, 53248, 55296, 55424, 55432, 
+        0,     1, 49152, 53248, 55296, 55424, 55432, 55434, 
+        0,     1, 49152, 53248, 55296, 55424, 55432,     0, 
+        1, 49152, 53248, 55296, 55424, 55440, 55436,     0, 
+        1, 49152, 53248, 55296, 55424, 55440, 55436,     0, 
+        1, 49152, 53248, 55296, 55424, 55440, 55441, 55438, 
+        0,     1, 49152, 53248, 55296, 55424,     0,     1, 
+    49152, 53248, 55296, 55424, 55440,     0,     1, 49152, 
+    53248, 55296, 55424, 55440,     0,     1, 49152, 53248, 
+    55296, 55424, 55440, 55442,     0,     1, 49152, 53248, 
+    55296, 55424, 55440,     0,     1, 49152, 53248, 55296, 
+    55424, 55440, 55444,     0,     1, 49152, 53248, 55296, 
+    55424, 55440, 55444,     0,     1, 49152, 53248, 55296, 
+    55424, 55440, 55448, 55446,     0,     1, 49152, 53248, 
+    55296, 55424, 55440,     0,     1, 49152, 53248, 55296, 
+    55424, 55456, 55448,     0,     1, 49152, 53248, 55296, 
+    55424, 55456, 55448,     0,     1, 49152, 53248, 55296, 
+    55424, 55456, 55448, 55450,     0,     1, 49152, 53248, 
+    55296, 55424, 55456, 55448,     0,     1, 49152, 53248, 
+    55296, 55424, 55456, 55457, 55452,     0,     1, 49152, 
+    53248, 55296, 55424, 55456, 55457, 55452,     0,     1, 
+    49152, 53248, 55296, 55424, 55456, 55457, 55452, 55454, 
+        0,     1, 49152, 53248, 55296, 55424,     0,     1, 
+    49152, 53248, 55296, 55424, 55456,     0,     1, 49152, 
+    53248, 55296, 55424, 55456,     0,     1, 49152, 53248, 
+    55296, 55424, 55456, 55458,     0,     1, 49152, 53248, 
+    55296, 55424, 55456,     0,     1, 49152, 53248, 55296, 
+    55424, 55456, 55460,     0,     1, 49152, 53248, 55296, 
+    55424, 55456, 55460,     0,     1, 49152, 53248, 55296, 
+    55424, 55456, 55464, 55462,     0,     1, 49152, 53248, 
+    55296, 55424, 55456,     0,     1, 49152, 53248, 55296, 
+    55424, 55456, 55464,     0,     1, 49152, 53248, 55296, 
+    55424, 55456, 55464,     0,     1, 49152, 53248, 55296, 
+    55424, 55456, 55464, 55466,     0,     1, 49152, 53248, 
+    55296, 55424, 55456, 55464,     0,     1, 49152, 53248, 
+    55296, 55424, 55456, 55472, 55468,     0,     1, 49152, 
+    53248, 55296, 55424, 55456, 55472, 55468,     0,     1, 
+    49152, 53248, 55296, 55424, 55456, 55472, 55473, 55470, 
+        0,     1, 49152, 53248, 55296, 55424, 55456,     0, 
+        1, 49152, 53248, 55296, 55424, 55488, 55472,     0, 
+        1, 49152, 53248, 55296, 55424, 55488, 55472,     0, 
+        1, 49152, 53248, 55296, 55424, 55488, 55472, 55474, 
+        0,     1, 49152, 53248, 55296, 55424, 55488, 55472, 
+        0,     1, 49152, 53248, 55296, 55424, 55488, 55472, 
+    55476,     0,     1, 49152, 53248, 55296, 55424, 55488, 
+    55472, 55476,     0,     1, 49152, 53248, 55296, 55424, 
+    55488, 55472, 55480, 55478,     0,     1, 49152, 53248, 
+    55296, 55424, 55488, 55472,     0,     1, 49152, 53248, 
+    55296, 55424, 55488, 55489, 55480,     0,     1, 49152, 
+    53248, 55296, 55424, 55488, 55489, 55480,     0,     1, 
+    49152, 53248, 55296, 55424, 55488, 55489, 55480, 55482, 
+        0,     1, 49152, 53248, 55296, 55424, 55488, 55489, 
+    55480,     0,     1, 49152, 53248, 55296, 55424, 55488, 
+    55489, 55480, 55484,     0,     1, 49152, 53248, 55296, 
+    55424, 55488, 55489, 55491, 55484,     0,     1, 49152, 
+    53248, 55296, 55424, 55488, 55489, 55491, 55484, 55486, 
+        0,     1, 49152, 53248, 55296, 55424,     0,     1, 
+    49152, 53248, 55296, 55552, 55488,     0,     1, 49152, 
+    53248, 55296, 55552, 55488,     0,     1, 49152, 53248, 
+    55296, 55552, 55488, 55490,     0,     1, 49152, 53248, 
+    55296, 55552, 55488,     0,     1, 49152, 53248, 55296, 
+    55552, 55488, 55492,     0,     1, 49152, 53248, 55296, 
+    55552, 55488, 55492,     0,     1, 49152, 53248, 55296, 
+    55552, 55488, 55496, 55494,     0,     1, 49152, 53248, 
+    55296, 55552, 55488,     0,     1, 49152, 53248, 55296, 
+    55552, 55488, 55496,     0,     1, 49152, 53248, 55296, 
+    55552, 55488, 55496,     0,     1, 49152, 53248, 55296, 
+    55552, 55488, 55496, 55498,     0,     1, 49152, 53248, 
+    55296, 55552, 55488, 55496,     0,     1, 49152, 53248, 
+    55296, 55552, 55488, 55504, 55500,     0,     1, 49152, 
+    53248, 55296, 55552, 55488, 55504, 55500,     0,     1, 
+    49152, 53248, 55296, 55552, 55488, 55504, 55505, 55502, 
+        0,     1, 49152, 53248, 55296, 55552, 55488,     0, 
+        1, 49152, 53248, 55296, 55552, 55488, 55504,     0, 
+        1, 49152, 53248, 55296, 55552, 55488, 55504,     0, 
+        1, 49152, 53248, 55296, 55552, 55488, 55504, 55506, 
+        0,     1, 49152, 53248, 55296, 55552, 55488, 55504, 
+        0,     1, 49152, 53248, 55296, 55552, 55488, 55504, 
+    55508,     0,     1, 49152, 53248, 55296, 55552, 55488, 
+    55504, 55508,     0,     1, 49152, 53248, 55296, 55552, 
+    55488, 55504, 55512, 55510,     0,     1, 49152, 53248, 
+    55296, 55552, 55488, 55504,     0,     1, 49152, 53248, 
+    55296, 55552, 55488, 55520, 55512,     0,     1, 49152, 
+    53248, 55296, 55552, 55488, 55520, 55512,     0,     1, 
+    49152, 53248, 55296, 55552, 55488, 55520, 55512, 55514, 
+        0,     1, 49152, 53248, 55296, 55552, 55488, 55520, 
+    55512,     0,     1, 49152, 53248, 55296, 55552, 55488, 
+    55520, 55521, 55516,     0,     1, 49152, 53248, 55296, 
+    55552, 55488, 55520, 55521, 55516,     0,     1, 49152, 
+    53248, 55296, 55552, 55488, 55520, 55521, 55516, 55518, 
+        0,     1, 49152, 53248, 55296, 55552, 55488,     0, 
+        1, 49152, 53248, 55296, 55552, 55553, 55520,     0, 
+        1, 49152, 53248, 55296, 55552, 55553, 55520,     0, 
+        1, 49152, 53248, 55296, 55552, 55553, 55520, 55522, 
+        0,     1, 49152, 53248, 55296, 55552, 55553, 55520, 
+        0,     1, 49152, 53248, 55296, 55552, 55553, 55520, 
+    55524,     0,     1, 49152, 53248, 55296, 55552, 55553, 
+    55520, 55524,     0,     1, 49152, 53248, 55296, 55552, 
+    55553, 55520, 55528, 55526,     0,     1, 49152, 53248, 
+    55296, 55552, 55553, 55520,     0,     1, 49152, 53248, 
+    55296, 55552, 55553, 55520, 55528,     0,     1, 49152, 
+    53248, 55296, 55552, 55553, 55520, 55528,     0,     1, 
+    49152, 53248, 55296, 55552, 55553, 55520, 55528, 55530, 
+        0,     1, 49152, 53248, 55296, 55552, 55553, 55520, 
+    55528,     0,     1, 49152, 53248, 55296, 55552, 55553, 
+    55520, 55536, 55532,     0,     1, 49152, 53248, 55296, 
+    55552, 55553, 55520, 55536, 55532,     0,     1, 49152, 
+    53248, 55296, 55552, 55553, 55520, 55536, 55537, 55534, 
+        0,     1, 49152, 53248, 55296, 55552, 55553, 55520, 
+        0,     1, 49152, 53248, 55296, 55552, 55553, 55520, 
+    55536,     0,     1, 49152, 53248, 55296, 55552, 55553, 
+    55555, 55536,     0,     1, 49152, 53248, 55296, 55552, 
+    55553, 55555, 55536, 55538,     0,     1, 49152, 53248, 
+    55296, 55552, 55553, 55555, 55536,     0,     1, 49152, 
+    53248, 55296, 55552, 55553, 55555, 55536, 55540,     0, 
+        1, 49152, 53248, 55296, 55552, 55553, 55555, 55536, 
+    55540,     0,     1, 49152, 53248, 55296, 55552, 55553, 
+    55555, 55536, 55544, 55542,     0,     1, 49152, 53248, 
+    55296, 55552, 55553, 55555, 55536,     0,     1, 49152, 
+    53248, 55296, 55552, 55553, 55555, 55536, 55544,     0, 
+        1, 49152, 53248, 55296, 55552, 55553, 55555, 55536, 
+    55544,     0,     1, 49152, 53248, 55296, 55552, 55553, 
+    55555, 55536, 55544, 55546,     0,     1, 49152, 53248, 
+    55296, 55552, 55553, 55555, 55559, 55544,     0,     1, 
+    49152, 53248, 55296, 55552, 55553, 55555, 55559, 55544, 
+    55548,     0,     1, 49152, 53248, 55296, 55552, 55553, 
+    55555, 55559, 55544, 55548,     0,     1, 49152, 53248, 
+    55296, 55552, 55553, 55555, 55559, 55544, 55548, 55550, 
+        0,     1, 49152, 53248, 55296,     0,     1, 49152, 
+    53248, 55296, 55552,     0,     1, 49152, 53248, 55296, 
+    55552,     0,     1, 49152, 53248, 55296, 55552, 55554, 
+        0,     1, 49152, 53248, 55296, 55552,     0,     1, 
+    49152, 53248, 55296, 55552, 55556,     0,     1, 49152, 
+    53248, 55296, 55552, 55556,     0,     1, 49152, 53248, 
+    55296, 55552, 55560, 55558,     0,     1, 49152, 53248, 
+    55296, 55552,     0,     1, 49152, 53248, 55296, 55552, 
+    55560,     0,     1, 49152, 53248, 55296, 55552, 55560, 
+        0,     1, 49152, 53248, 55296, 55552, 55560, 55562, 
+        0,     1, 49152, 53248, 55296, 55552, 55560,     0, 
+        1, 49152, 53248, 55296, 55552, 55568, 55564,     0, 
+        1, 49152, 53248, 55296, 55552, 55568, 55564,     0, 
+        1, 49152, 53248, 55296, 55552, 55568, 55569, 55566, 
+        0,     1, 49152, 53248, 55296, 55552,     0,     1, 
+    49152, 53248, 55296, 55552, 55568,     0,     1, 49152, 
+    53248, 55296, 55552, 55568,     0,     1, 49152, 53248, 
+    55296, 55552, 55568, 55570,     0,     1, 49152, 53248, 
+    55296, 55552, 55568,     0,     1, 49152, 53248, 55296, 
+    55552, 55568, 55572,     0,     1, 49152, 53248, 55296, 
+    55552, 55568, 55572,     0,     1, 49152, 53248, 55296, 
+    55552, 55568, 55576, 55574,     0,     1, 49152, 53248, 
+    55296, 55552, 55568,     0,     1, 49152, 53248, 55296, 
+    55552, 55584, 55576,     0,     1, 49152, 53248, 55296, 
+    55552, 55584, 55576,     0,     1, 49152, 53248, 55296, 
+    55552, 55584, 55576, 55578,     0,     1, 49152, 53248, 
+    55296, 55552, 55584, 55576,     0,     1, 49152, 53248, 
+    55296, 55552, 55584, 55585, 55580,     0,     1, 49152, 
+    53248, 55296, 55552, 55584, 55585, 55580,     0,     1, 
+    49152, 53248, 55296, 55552, 55584, 55585, 55580, 55582, 
+        0,     1, 49152, 53248, 55296, 55552,     0,     1, 
+    49152, 53248, 55296, 55552, 55584,     0,     1, 49152, 
+    53248, 55296, 55552, 55584,     0,     1, 49152, 53248, 
+    55296, 55552, 55584, 55586,     0,     1, 49152, 53248, 
+    55296, 55552, 55584,     0,     1, 49152, 53248, 55296, 
+    55552, 55584, 55588,     0,     1, 49152, 53248, 55296, 
+    55552, 55584, 55588,     0,     1, 49152, 53248, 55296, 
+    55552, 55584, 55592, 55590,     0,     1, 49152, 53248, 
+    55296, 55552, 55584,     0,     1, 49152, 53248, 55296, 
+    55552, 55584, 55592,     0,     1, 49152, 53248, 55296, 
+    55552, 55584, 55592,     0,     1, 49152, 53248, 55296, 
+    55552, 55584, 55592, 55594,     0,     1, 49152, 53248, 
+    55296, 55552, 55584, 55592,     0,     1, 49152, 53248, 
+    55296, 55552, 55584, 55600, 55596,     0,     1, 49152, 
+    53248, 55296, 55552, 55584, 55600, 55596,     0,     1, 
+    49152, 53248, 55296, 55552, 55584, 55600, 55601, 55598, 
+        0,     1, 49152, 53248, 55296, 55552, 55584,     0, 
+        1, 49152, 53248, 55296, 55552, 55616, 55600,     0, 
+        1, 49152, 53248, 55296, 55552, 55616, 55600,     0, 
+        1, 49152, 53248, 55296, 55552, 55616, 55600, 55602, 
+        0,     1, 49152, 53248, 55296, 55552, 55616, 55600, 
+        0,     1, 49152, 53248, 55296, 55552, 55616, 55600, 
+    55604,     0,     1, 49152, 53248, 55296, 55552, 55616, 
+    55600, 55604,     0,     1, 49152, 53248, 55296, 55552, 
+    55616, 55600, 55608, 55606,     0,     1, 49152, 53248, 
+    55296, 55552, 55616, 55600,     0,     1, 49152, 53248, 
+    55296, 55552, 55616, 55617, 55608,     0,     1, 49152, 
+    53248, 55296, 55552, 55616, 55617, 55608,     0,     1, 
+    49152, 53248, 55296, 55552, 55616, 55617, 55608, 55610, 
+        0,     1, 49152, 53248, 55296, 55552, 55616, 55617, 
+    55608,     0,     1, 49152, 53248, 55296, 55552, 55616, 
+    55617, 55608, 55612,     0,     1, 49152, 53248, 55296, 
+    55552, 55616, 55617, 55619, 55612,     0,     1, 49152, 
+    53248, 55296, 55552, 55616, 55617, 55619, 55612, 55614, 
+        0,     1, 49152, 53248, 55296, 55552,     0,     1, 
+    49152, 53248, 55296, 55552, 55616,     0,     1, 49152, 
+    53248, 55296, 55552, 55616,     0,     1, 49152, 53248, 
+    55296, 55552, 55616, 55618,     0,     1, 49152, 53248, 
+    55296, 55552, 55616,     0,     1, 49152, 53248, 55296, 
+    55552, 55616, 55620,     0,     1, 49152, 53248, 55296, 
+    55552, 55616, 55620,     0,     1, 49152, 53248, 55296, 
+    55552, 55616, 55624, 55622,     0,     1, 49152, 53248, 
+    55296, 55552, 55616,     0,     1, 49152, 53248, 55296, 
+    55552, 55616, 55624,     0,     1, 49152, 53248, 55296, 
+    55552, 55616, 55624,     0,     1, 49152, 53248, 55296, 
+    55552, 55616, 55624, 55626,     0,     1, 49152, 53248, 
+    55296, 55552, 55616, 55624,     0,     1, 49152, 53248, 
+    55296, 55552, 55616, 55632, 55628,     0,     1, 49152, 
+    53248, 55296, 55552, 55616, 55632, 55628,     0,     1, 
+    49152, 53248, 55296, 55552, 55616, 55632, 55633, 55630, 
+        0,     1, 49152, 53248, 55296, 55552, 55616,     0, 
+        1, 49152, 53248, 55296, 55552, 55616, 55632,     0, 
+        1, 49152, 53248, 55296, 55552, 55616, 55632,     0, 
+        1, 49152, 53248, 55296, 55552, 55616, 55632, 55634, 
+        0,     1, 49152, 53248, 55296, 55552, 55616, 55632, 
+        0,     1, 49152, 53248, 55296, 55552, 55616, 55632, 
+    55636,     0,     1, 49152, 53248, 55296, 55552, 55616, 
+    55632, 55636,     0,     1, 49152, 53248, 55296, 55552, 
+    55616, 55632, 55640, 55638,     0,     1, 49152, 53248, 
+    55296, 55552, 55616, 55632,     0,     1, 49152, 53248, 
+    55296, 55552, 55616, 55648, 55640,     0,     1, 49152, 
+    53248, 55296, 55552, 55616, 55648, 55640,     0,     1, 
+    49152, 53248, 55296, 55552, 55616, 55648, 55640, 55642, 
+        0,     1, 49152, 53248, 55296, 55552, 55616, 55648, 
+    55640,     0,     1, 49152, 53248, 55296, 55552, 55616, 
+    55648, 55649, 55644,     0,     1, 49152, 53248, 55296, 
+    55552, 55616, 55648, 55649, 55644,     0,     1, 49152, 
+    53248, 55296, 55552, 55616, 55648, 55649, 55644, 55646, 
+        0,     1, 49152, 53248, 55296, 55552, 55616,     0, 
+        1, 49152, 53248, 55296, 55552, 55680, 55648,     0, 
+        1, 49152, 53248, 55296, 55552, 55680, 55648,     0, 
+        1, 49152, 53248, 55296, 55552, 55680, 55648, 55650, 
+        0,     1, 49152, 53248, 55296, 55552, 55680, 55648, 
+        0,     1, 49152, 53248, 55296, 55552, 55680, 55648, 
+    55652,     0,     1, 49152, 53248, 55296, 55552, 55680, 
+    55648, 55652,     0,     1, 49152, 53248, 55296, 55552, 
+    55680, 55648, 55656, 55654,     0,     1, 49152, 53248, 
+    55296, 55552, 55680, 55648,     0,     1, 49152, 53248, 
+    55296, 55552, 55680, 55648, 55656,     0,     1, 49152, 
+    53248, 55296, 55552, 55680, 55648, 55656,     0,     1, 
+    49152, 53248, 55296, 55552, 55680, 55648, 55656, 55658, 
+        0,     1, 49152, 53248, 55296, 55552, 55680, 55648, 
+    55656,     0,     1, 49152, 53248, 55296, 55552, 55680, 
+    55648, 55664, 55660,     0,     1, 49152, 53248, 55296, 
+    55552, 55680, 55648, 55664, 55660,     0,     1, 49152, 
+    53248, 55296, 55552, 55680, 55648, 55664, 55665, 55662, 
+        0,     1, 49152, 53248, 55296, 55552, 55680, 55648, 
+        0,     1, 49152, 53248, 55296, 55552, 55680, 55681, 
+    55664,     0,     1, 49152, 53248, 55296, 55552, 55680, 
+    55681, 55664,     0,     1, 49152, 53248, 55296, 55552, 
+    55680, 55681, 55664, 55666,     0,     1, 49152, 53248, 
+    55296, 55552, 55680, 55681, 55664,     0,     1, 49152, 
+    53248, 55296, 55552, 55680, 55681, 55664, 55668,     0, 
+        1, 49152, 53248, 55296, 55552, 55680, 55681, 55664, 
+    55668,     0,     1, 49152, 53248, 55296, 55552, 55680, 
+    55681, 55664, 55672, 55670,     0,     1, 49152, 53248, 
+    55296, 55552, 55680, 55681, 55664,     0,     1, 49152, 
+    53248, 55296, 55552, 55680, 55681, 55664, 55672,     0, 
+        1, 49152, 53248, 55296, 55552, 55680, 55681, 55683, 
+    55672,     0,     1, 49152, 53248, 55296, 55552, 55680, 
+    55681, 55683, 55672, 55674,     0,     1, 49152, 53248, 
+    55296, 55552, 55680, 55681, 55683, 55672,     0,     1, 
+    49152, 53248, 55296, 55552, 55680, 55681, 55683, 55672, 
+    55676,     0,     1, 49152, 53248, 55296, 55552, 55680, 
+    55681, 55683, 55672, 55676,     0,     1, 49152, 53248, 
+    55296, 55552, 55680, 55681, 55683, 55672, 55676, 55678, 
+        0,     1, 49152, 53248, 55296, 55552,     0,     1, 
+    49152, 53248, 55296, 55808, 55680,     0,     1, 49152, 
+    53248, 55296, 55808, 55680,     0,     1, 49152, 53248, 
+    55296, 55808, 55680, 55682,     0,     1, 49152, 53248, 
+    55296, 55808, 55680,     0,     1, 49152, 53248, 55296, 
+    55808, 55680, 55684,     0,     1, 49152, 53248, 55296, 
+    55808, 55680, 55684,     0,     1, 49152, 53248, 55296, 
+    55808, 55680, 55688, 55686,     0,     1, 49152, 53248, 
+    55296, 55808, 55680,     0,     1, 49152, 53248, 55296, 
+    55808, 55680, 55688,     0,     1, 49152, 53248, 55296, 
+    55808, 55680, 55688,     0,     1, 49152, 53248, 55296, 
+    55808, 55680, 55688, 55690,     0,     1, 49152, 53248, 
+    55296, 55808, 55680, 55688,     0,     1, 49152, 53248, 
+    55296, 55808, 55680, 55696, 55692,     0,     1, 49152, 
+    53248, 55296, 55808, 55680, 55696, 55692,     0,     1, 
+    49152, 53248, 55296, 55808, 55680, 55696, 55697, 55694, 
+        0,     1, 49152, 53248, 55296, 55808, 55680,     0, 
+        1, 49152, 53248, 55296, 55808, 55680, 55696,     0, 
+        1, 49152, 53248, 55296, 55808, 55680, 55696,     0, 
+        1, 49152, 53248, 55296, 55808, 55680, 55696, 55698, 
+        0,     1, 49152, 53248, 55296, 55808, 55680, 55696, 
+        0,     1, 49152, 53248, 55296, 55808, 55680, 55696, 
+    55700,     0,     1, 49152, 53248, 55296, 55808, 55680, 
+    55696, 55700,     0,     1, 49152, 53248, 55296, 55808, 
+    55680, 55696, 55704, 55702,     0,     1, 49152, 53248, 
+    55296, 55808, 55680, 55696,     0,     1, 49152, 53248, 
+    55296, 55808, 55680, 55712, 55704,     0,     1, 49152, 
+    53248, 55296, 55808, 55680, 55712, 55704,     0,     1, 
+    49152, 53248, 55296, 55808, 55680, 55712, 55704, 55706, 
+        0,     1, 49152, 53248, 55296, 55808, 55680, 55712, 
+    55704,     0,     1, 49152, 53248, 55296, 55808, 55680, 
+    55712, 55713, 55708,     0,     1, 49152, 53248, 55296, 
+    55808, 55680, 55712, 55713, 55708,     0,     1, 49152, 
+    53248, 55296, 55808, 55680, 55712, 55713, 55708, 55710, 
+        0,     1, 49152, 53248, 55296, 55808, 55680,     0, 
+        1, 49152, 53248, 55296, 55808, 55680, 55712,     0, 
+        1, 49152, 53248, 55296, 55808, 55680, 55712,     0, 
+        1, 49152, 53248, 55296, 55808, 55680, 55712, 55714, 
+        0,     1, 49152, 53248, 55296, 55808, 55680, 55712, 
+        0,     1, 49152, 53248, 55296, 55808, 55680, 55712, 
+    55716,     0,     1, 49152, 53248, 55296, 55808, 55680, 
+    55712, 55716,     0,     1, 49152, 53248, 55296, 55808, 
+    55680, 55712, 55720, 55718,     0,     1, 49152, 53248, 
+    55296, 55808, 55680, 55712,     0,     1, 49152, 53248, 
+    55296, 55808, 55680, 55712, 55720,     0,     1, 49152, 
+    53248, 55296, 55808, 55680, 55712, 55720,     0,     1, 
+    49152, 53248, 55296, 55808, 55680, 55712, 55720, 55722, 
+        0,     1, 49152, 53248, 55296, 55808, 55680, 55712, 
+    55720,     0,     1, 49152, 53248, 55296, 55808, 55680, 
+    55712, 55728, 55724,     0,     1, 49152, 53248, 55296, 
+    55808, 55680, 55712, 55728, 55724,     0,     1, 49152, 
+    53248, 55296, 55808, 55680, 55712, 55728, 55729, 55726, 
+        0,     1, 49152, 53248, 55296, 55808, 55680, 55712, 
+        0,     1, 49152, 53248, 55296, 55808, 55680, 55744, 
+    55728,     0,     1, 49152, 53248, 55296, 55808, 55680, 
+    55744, 55728,     0,     1, 49152, 53248, 55296, 55808, 
+    55680, 55744, 55728, 55730,     0,     1, 49152, 53248, 
+    55296, 55808, 55680, 55744, 55728,     0,     1, 49152, 
+    53248, 55296, 55808, 55680, 55744, 55728, 55732,     0, 
+        1, 49152, 53248, 55296, 55808, 55680, 55744, 55728, 
+    55732,     0,     1, 49152, 53248, 55296, 55808, 55680, 
+    55744, 55728, 55736, 55734,     0,     1, 49152, 53248, 
+    55296, 55808, 55680, 55744, 55728,     0,     1, 49152, 
+    53248, 55296, 55808, 55680, 55744, 55745, 55736,     0, 
+        1, 49152, 53248, 55296, 55808, 55680, 55744, 55745, 
+    55736,     0,     1, 49152, 53248, 55296, 55808, 55680, 
+    55744, 55745, 55736, 55738,     0,     1, 49152, 53248, 
+    55296, 55808, 55680, 55744, 55745, 55736,     0,     1, 
+    49152, 53248, 55296, 55808, 55680, 55744, 55745, 55736, 
+    55740,     0,     1, 49152, 53248, 55296, 55808, 55680, 
+    55744, 55745, 55747, 55740,     0,     1, 49152, 53248, 
+    55296, 55808, 55680, 55744, 55745, 55747, 55740, 55742, 
+        0,     1, 49152, 53248, 55296, 55808, 55680,     0, 
+        1, 49152, 53248, 55296, 55808, 55809, 55744,     0, 
+        1, 49152, 53248, 55296, 55808, 55809, 55744,     0, 
+        1, 49152, 53248, 55296, 55808, 55809, 55744, 55746, 
+        0,     1, 49152, 53248, 55296, 55808, 55809, 55744, 
+        0,     1, 49152, 53248, 55296, 55808, 55809, 55744, 
+    55748,     0,     1, 49152, 53248, 55296, 55808, 55809, 
+    55744, 55748,     0,     1, 49152, 53248, 55296, 55808, 
+    55809, 55744, 55752, 55750,     0,     1, 49152, 53248, 
+    55296, 55808, 55809, 55744,     0,     1, 49152, 53248, 
+    55296, 55808, 55809, 55744, 55752,     0,     1, 49152, 
+    53248, 55296, 55808, 55809, 55744, 55752,     0,     1, 
+    49152, 53248, 55296, 55808, 55809, 55744, 55752, 55754, 
+        0,     1, 49152, 53248, 55296, 55808, 55809, 55744, 
+    55752,     0,     1, 49152, 53248, 55296, 55808, 55809, 
+    55744, 55760, 55756,     0,     1, 49152, 53248, 55296, 
+    55808, 55809, 55744, 55760, 55756,     0,     1, 49152, 
+    53248, 55296, 55808, 55809, 55744, 55760, 55761, 55758, 
+        0,     1, 49152, 53248, 55296, 55808, 55809, 55744, 
+        0,     1, 49152, 53248, 55296, 55808, 55809, 55744, 
+    55760,     0,     1, 49152, 53248, 55296, 55808, 55809, 
+    55744, 55760,     0,     1, 49152, 53248, 55296, 55808, 
+    55809, 55744, 55760, 55762,     0,     1, 49152, 53248, 
+    55296, 55808, 55809, 55744, 55760,     0,     1, 49152, 
+    53248, 55296, 55808, 55809, 55744, 55760, 55764,     0, 
+        1, 49152, 53248, 55296, 55808, 55809, 55744, 55760, 
+    55764,     0,     1, 49152, 53248, 55296, 55808, 55809, 
+    55744, 55760, 55768, 55766,     0,     1, 49152, 53248, 
+    55296, 55808, 55809, 55744, 55760,     0,     1, 49152, 
+    53248, 55296, 55808, 55809, 55744, 55776, 55768,     0, 
+        1, 49152, 53248, 55296, 55808, 55809, 55744, 55776, 
+    55768,     0,     1, 49152, 53248, 55296, 55808, 55809, 
+    55744, 55776, 55768, 55770,     0,     1, 49152, 53248, 
+    55296, 55808, 55809, 55744, 55776, 55768,     0,     1, 
+    49152, 53248, 55296, 55808, 55809, 55744, 55776, 55777, 
+    55772,     0,     1, 49152, 53248, 55296, 55808, 55809, 
+    55744, 55776, 55777, 55772,     0,     1, 49152, 53248, 
+    55296, 55808, 55809, 55744, 55776, 55777, 55772, 55774, 
+        0,     1, 49152, 53248, 55296, 55808, 55809, 55744, 
+        0,     1, 49152, 53248, 55296, 55808, 55809, 55744, 
+    55776,     0,     1, 49152, 53248, 55296, 55808, 55809, 
+    55811, 55776,     0,     1, 49152, 53248, 55296, 55808, 
+    55809, 55811, 55776, 55778,     0,     1, 49152, 53248, 
+    55296, 55808, 55809, 55811, 55776,     0,     1, 49152, 
+    53248, 55296, 55808, 55809, 55811, 55776, 55780,     0, 
+        1, 49152, 53248, 55296, 55808, 55809, 55811, 55776, 
+    55780,     0,     1, 49152, 53248, 55296, 55808, 55809, 
+    55811, 55776, 55784, 55782,     0,     1, 49152, 53248, 
+    55296, 55808, 55809, 55811, 55776,     0,     1, 49152, 
+    53248, 55296, 55808, 55809, 55811, 55776, 55784,     0, 
+        1, 49152, 53248, 55296, 55808, 55809, 55811, 55776, 
+    55784,     0,     1, 49152, 53248, 55296, 55808, 55809, 
+    55811, 55776, 55784, 55786,     0,     1, 49152, 53248, 
+    55296, 55808, 55809, 55811, 55776, 55784,     0,     1, 
+    49152, 53248, 55296, 55808, 55809, 55811, 55776, 55792, 
+    55788,     0,     1, 49152, 53248, 55296, 55808, 55809, 
+    55811, 55776, 55792, 55788,     0,     1, 49152, 53248, 
+    55296, 55808, 55809, 55811, 55776, 55792, 55793, 55790, 
+        0,     1, 49152, 53248, 55296, 55808, 55809, 55811, 
+    55776,     0,     1, 49152, 53248, 55296, 55808, 55809, 
+    55811, 55776, 55792,     0,     1, 49152, 53248, 55296, 
+    55808, 55809, 55811, 55776, 55792,     0,     1, 49152, 
+    53248, 55296, 55808, 55809, 55811, 55776, 55792, 55794, 
+        0,     1, 49152, 53248, 55296, 55808, 55809, 55811, 
+    55815, 55792,     0,     1, 49152, 53248, 55296, 55808, 
+    55809, 55811, 55815, 55792, 55796,     0,     1, 49152, 
+    53248, 55296, 55808, 55809, 55811, 55815, 55792, 55796, 
+        0,     1, 49152, 53248, 55296, 55808, 55809, 55811, 
+    55815, 55792, 55800, 55798,     0,     1, 49152, 53248, 
+    55296, 55808, 55809, 55811, 55815, 55792,     0,     1, 
+    49152, 53248, 55296, 55808, 55809, 55811, 55815, 55792, 
+    55800,     0,     1, 49152, 53248, 55296, 55808, 55809, 
+    55811, 55815, 55792, 55800,     0,     1, 49152, 53248, 
+    55296, 55808, 55809, 55811, 55815, 55792, 55800, 55802, 
+        0,     1, 49152, 53248, 55296, 55808, 55809, 55811, 
+    55815, 55792, 55800,     0,     1, 49152, 53248, 55296, 
+    55808, 55809, 55811, 55815, 55792, 55800, 55804,     0, 
+        1, 49152, 53248, 55296, 55808, 55809, 55811, 55815, 
+    55792, 55800, 55804,     0,     1, 49152, 53248, 55296, 
+    55808, 55809, 55811, 55815, 55792, 55800, 55804, 55806, 
+        0,     1, 49152, 53248, 55296,     0,     1, 49152, 
+    53248, 55296, 55808,     0,     1, 49152, 53248, 55296, 
+    55808,     0,     1, 49152, 53248, 55296, 55808, 55810, 
+        0,     1, 49152, 53248, 55296, 55808,     0,     1, 
+    49152, 53248, 55296, 55808, 55812,     0,     1, 49152, 
+    53248, 55296, 55808, 55812,     0,     1, 49152, 53248, 
+    55296, 55808, 55816, 55814,     0,     1, 49152, 53248, 
+    55296, 55808,     0,     1, 49152, 53248, 55296, 55808, 
+    55816,     0,     1, 49152, 53248, 55296, 55808, 55816, 
+        0,     1, 49152, 53248, 55296, 55808, 55816, 55818, 
+        0,     1, 49152, 53248, 55296, 55808, 55816,     0, 
+        1, 49152, 53248, 55296, 55808, 55824, 55820,     0, 
+        1, 49152, 53248, 55296, 55808, 55824, 55820,     0, 
+        1, 49152, 53248, 55296, 55808, 55824, 55825, 55822, 
+        0,     1, 49152, 53248, 55296, 55808,     0,     1, 
+    49152, 53248, 55296, 55808, 55824,     0,     1, 49152, 
+    53248, 55296, 55808, 55824,     0,     1, 49152, 53248, 
+    55296, 55808, 55824, 55826,     0,     1, 49152, 53248, 
+    55296, 55808, 55824,     0,     1, 49152, 53248, 55296, 
+    55808, 55824, 55828,     0,     1, 49152, 53248, 55296, 
+    55808, 55824, 55828,     0,     1, 49152, 53248, 55296, 
+    55808, 55824, 55832, 55830,     0,     1, 49152, 53248, 
+    55296, 55808, 55824,     0,     1, 49152, 53248, 55296, 
+    55808, 55840, 55832,     0,     1, 49152, 53248, 55296, 
+    55808, 55840, 55832,     0,     1, 49152, 53248, 55296, 
+    55808, 55840, 55832, 55834,     0,     1, 49152, 53248, 
+    55296, 55808, 55840, 55832,     0,     1, 49152, 53248, 
+    55296, 55808, 55840, 55841, 55836,     0,     1, 49152, 
+    53248, 55296, 55808, 55840, 55841, 55836,     0,     1, 
+    49152, 53248, 55296, 55808, 55840, 55841, 55836, 55838, 
+        0,     1, 49152, 53248, 55296, 55808,     0,     1, 
+    49152, 53248, 55296, 55808, 55840,     0,     1, 49152, 
+    53248, 55296, 55808, 55840,     0,     1, 49152, 53248, 
+    55296, 55808, 55840, 55842,     0,     1, 49152, 53248, 
+    55296, 55808, 55840,     0,     1, 49152, 53248, 55296, 
+    55808, 55840, 55844,     0,     1, 49152, 53248, 55296, 
+    55808, 55840, 55844,     0,     1, 49152, 53248, 55296, 
+    55808, 55840, 55848, 55846,     0,     1, 49152, 53248, 
+    55296, 55808, 55840,     0,     1, 49152, 53248, 55296, 
+    55808, 55840, 55848,     0,     1, 49152, 53248, 55296, 
+    55808, 55840, 55848,     0,     1, 49152, 53248, 55296, 
+    55808, 55840, 55848, 55850,     0,     1, 49152, 53248, 
+    55296, 55808, 55840, 55848,     0,     1, 49152, 53248, 
+    55296, 55808, 55840, 55856, 55852,     0,     1, 49152, 
+    53248, 55296, 55808, 55840, 55856, 55852,     0,     1, 
+    49152, 53248, 55296, 55808, 55840, 55856, 55857, 55854, 
+        0,     1, 49152, 53248, 55296, 55808, 55840,     0, 
+        1, 49152, 53248, 55296, 55808, 55872, 55856,     0, 
+        1, 49152, 53248, 55296, 55808, 55872, 55856,     0, 
+        1, 49152, 53248, 55296, 55808, 55872, 55856, 55858, 
+        0,     1, 49152, 53248, 55296, 55808, 55872, 55856, 
+        0,     1, 49152, 53248, 55296, 55808, 55872, 55856, 
+    55860,     0,     1, 49152, 53248, 55296, 55808, 55872, 
+    55856, 55860,     0,     1, 49152, 53248, 55296, 55808, 
+    55872, 55856, 55864, 55862,     0,     1, 49152, 53248, 
+    55296, 55808, 55872, 55856,     0,     1, 49152, 53248, 
+    55296, 55808, 55872, 55873, 55864,     0,     1, 49152, 
+    53248, 55296, 55808, 55872, 55873, 55864,     0,     1, 
+    49152, 53248, 55296, 55808, 55872, 55873, 55864, 55866, 
+        0,     1, 49152, 53248, 55296, 55808, 55872, 55873, 
+    55864,     0,     1, 49152, 53248, 55296, 55808, 55872, 
+    55873, 55864, 55868,     0,     1, 49152, 53248, 55296, 
+    55808, 55872, 55873, 55875, 55868,     0,     1, 49152, 
+    53248, 55296, 55808, 55872, 55873, 55875, 55868, 55870, 
+        0,     1, 49152, 53248, 55296, 55808,     0,     1, 
+    49152, 53248, 55296, 55808, 55872,     0,     1, 49152, 
+    53248, 55296, 55808, 55872,     0,     1, 49152, 53248, 
+    55296, 55808, 55872, 55874,     0,     1, 49152, 53248, 
+    55296, 55808, 55872,     0,     1, 49152, 53248, 55296, 
+    55808, 55872, 55876,     0,     1, 49152, 53248, 55296, 
+    55808, 55872, 55876,     0,     1, 49152, 53248, 55296, 
+    55808, 55872, 55880, 55878,     0,     1, 49152, 53248, 
+    55296, 55808, 55872,     0,     1, 49152, 53248, 55296, 
+    55808, 55872, 55880,     0,     1, 49152, 53248, 55296, 
+    55808, 55872, 55880,     0,     1, 49152, 53248, 55296, 
+    55808, 55872, 55880, 55882,     0,     1, 49152, 53248, 
+    55296, 55808, 55872, 55880,     0,     1, 49152, 53248, 
+    55296, 55808, 55872, 55888, 55884,     0,     1, 49152, 
+    53248, 55296, 55808, 55872, 55888, 55884,     0,     1, 
+    49152, 53248, 55296, 55808, 55872, 55888, 55889, 55886, 
+        0,     1, 49152, 53248, 55296, 55808, 55872,     0, 
+        1, 49152, 53248, 55296, 55808, 55872, 55888,     0, 
+        1, 49152, 53248, 55296, 55808, 55872, 55888,     0, 
+        1, 49152, 53248, 55296, 55808, 55872, 55888, 55890, 
+        0,     1, 49152, 53248, 55296, 55808, 55872, 55888, 
+        0,     1, 49152, 53248, 55296, 55808, 55872, 55888, 
+    55892,     0,     1, 49152, 53248, 55296, 55808, 55872, 
+    55888, 55892,     0,     1, 49152, 53248, 55296, 55808, 
+    55872, 55888, 55896, 55894,     0,     1, 49152, 53248, 
+    55296, 55808, 55872, 55888,     0,     1, 49152, 53248, 
+    55296, 55808, 55872, 55904, 55896,     0,     1, 49152, 
+    53248, 55296, 55808, 55872, 55904, 55896,     0,     1, 
+    49152, 53248, 55296, 55808, 55872, 55904, 55896, 55898, 
+        0,     1, 49152, 53248, 55296, 55808, 55872, 55904, 
+    55896,     0,     1, 49152, 53248, 55296, 55808, 55872, 
+    55904, 55905, 55900,     0,     1, 49152, 53248, 55296, 
+    55808, 55872, 55904, 55905, 55900,     0,     1, 49152, 
+    53248, 55296, 55808, 55872, 55904, 55905, 55900, 55902, 
+        0,     1, 49152, 53248, 55296, 55808, 55872,     0, 
+        1, 49152, 53248, 55296, 55808, 55936, 55904,     0, 
+        1, 49152, 53248, 55296, 55808, 55936, 55904,     0, 
+        1, 49152, 53248, 55296, 55808, 55936, 55904, 55906, 
+        0,     1, 49152, 53248, 55296, 55808, 55936, 55904, 
+        0,     1, 49152, 53248, 55296, 55808, 55936, 55904, 
+    55908,     0,     1, 49152, 53248, 55296, 55808, 55936, 
+    55904, 55908,     0,     1, 49152, 53248, 55296, 55808, 
+    55936, 55904, 55912, 55910,     0,     1, 49152, 53248, 
+    55296, 55808, 55936, 55904,     0,     1, 49152, 53248, 
+    55296, 55808, 55936, 55904, 55912,     0,     1, 49152, 
+    53248, 55296, 55808, 55936, 55904, 55912,     0,     1, 
+    49152, 53248, 55296, 55808, 55936, 55904, 55912, 55914, 
+        0,     1, 49152, 53248, 55296, 55808, 55936, 55904, 
+    55912,     0,     1, 49152, 53248, 55296, 55808, 55936, 
+    55904, 55920, 55916,     0,     1, 49152, 53248, 55296, 
+    55808, 55936, 55904, 55920, 55916,     0,     1, 49152, 
+    53248, 55296, 55808, 55936, 55904, 55920, 55921, 55918, 
+        0,     1, 49152, 53248, 55296, 55808, 55936, 55904, 
+        0,     1, 49152, 53248, 55296, 55808, 55936, 55937, 
+    55920,     0,     1, 49152, 53248, 55296, 55808, 55936, 
+    55937, 55920,     0,     1, 49152, 53248, 55296, 55808, 
+    55936, 55937, 55920, 55922,     0,     1, 49152, 53248, 
+    55296, 55808, 55936, 55937, 55920,     0,     1, 49152, 
+    53248, 55296, 55808, 55936, 55937, 55920, 55924,     0, 
+        1, 49152, 53248, 55296, 55808, 55936, 55937, 55920, 
+    55924,     0,     1, 49152, 53248, 55296, 55808, 55936, 
+    55937, 55920, 55928, 55926,     0,     1, 49152, 53248, 
+    55296, 55808, 55936, 55937, 55920,     0,     1, 49152, 
+    53248, 55296, 55808, 55936, 55937, 55920, 55928,     0, 
+        1, 49152, 53248, 55296, 55808, 55936, 55937, 55939, 
+    55928,     0,     1, 49152, 53248, 55296, 55808, 55936, 
+    55937, 55939, 55928, 55930,     0,     1, 49152, 53248, 
+    55296, 55808, 55936, 55937, 55939, 55928,     0,     1, 
+    49152, 53248, 55296, 55808, 55936, 55937, 55939, 55928, 
+    55932,     0,     1, 49152, 53248, 55296, 55808, 55936, 
+    55937, 55939, 55928, 55932,     0,     1, 49152, 53248, 
+    55296, 55808, 55936, 55937, 55939, 55928, 55932, 55934, 
+        0,     1, 49152, 53248, 55296, 55808,     0,     1, 
+    49152, 53248, 55296, 55808, 55936,     0,     1, 49152, 
+    53248, 55296, 55808, 55936,     0,     1, 49152, 53248, 
+    55296, 55808, 55936, 55938,     0,     1, 49152, 53248, 
+    55296, 55808, 55936,     0,     1, 49152, 53248, 55296, 
+    55808, 55936, 55940,     0,     1, 49152, 53248, 55296, 
+    55808, 55936, 55940,     0,     1, 49152, 53248, 55296, 
+    55808, 55936, 55944, 55942,     0,     1, 49152, 53248, 
+    55296, 55808, 55936,     0,     1, 49152, 53248, 55296, 
+    55808, 55936, 55944,     0,     1, 49152, 53248, 55296, 
+    55808, 55936, 55944,     0,     1, 49152, 53248, 55296, 
+    55808, 55936, 55944, 55946,     0,     1, 49152, 53248, 
+    55296, 55808, 55936, 55944,     0,     1, 49152, 53248, 
+    55296, 55808, 55936, 55952, 55948,     0,     1, 49152, 
+    53248, 55296, 55808, 55936, 55952, 55948,     0,     1, 
+    49152, 53248, 55296, 55808, 55936, 55952, 55953, 55950, 
+        0,     1, 49152, 53248, 55296, 55808, 55936,     0, 
+        1, 49152, 53248, 55296, 55808, 55936, 55952,     0, 
+        1, 49152, 53248, 55296, 55808, 55936, 55952,     0, 
+        1, 49152, 53248, 55296, 55808, 55936, 55952, 55954, 
+        0,     1, 49152, 53248, 55296, 55808, 55936, 55952, 
+        0,     1, 49152, 53248, 55296, 55808, 55936, 55952, 
+    55956,     0,     1, 49152, 53248, 55296, 55808, 55936, 
+    55952, 55956,     0,     1, 49152, 53248, 55296, 55808, 
+    55936, 55952, 55960, 55958,     0,     1, 49152, 53248, 
+    55296, 55808, 55936, 55952,     0,     1, 49152, 53248, 
+    55296, 55808, 55936, 55968, 55960,     0,     1, 49152, 
+    53248, 55296, 55808, 55936, 55968, 55960,     0,     1, 
+    49152, 53248, 55296, 55808, 55936, 55968, 55960, 55962, 
+        0,     1, 49152, 53248, 55296, 55808, 55936, 55968, 
+    55960,     0,     1, 49152, 53248, 55296, 55808, 55936, 
+    55968, 55969, 55964,     0,     1, 49152, 53248, 55296, 
+    55808, 55936, 55968, 55969, 55964,     0,     1, 49152, 
+    53248, 55296, 55808, 55936, 55968, 55969, 55964, 55966, 
+        0,     1, 49152, 53248, 55296, 55808, 55936,     0, 
+        1, 49152, 53248, 55296, 55808, 55936, 55968,     0, 
+        1, 49152, 53248, 55296, 55808, 55936, 55968,     0, 
+        1, 49152, 53248, 55296, 55808, 55936, 55968, 55970, 
+        0,     1, 49152, 53248, 55296, 55808, 55936, 55968, 
+        0,     1, 49152, 53248, 55296, 55808, 55936, 55968, 
+    55972,     0,     1, 49152, 53248, 55296, 55808, 55936, 
+    55968, 55972,     0,     1, 49152, 53248, 55296, 55808, 
+    55936, 55968, 55976, 55974,     0,     1, 49152, 53248, 
+    55296, 55808, 55936, 55968,     0,     1, 49152, 53248, 
+    55296, 55808, 55936, 55968, 55976,     0,     1, 49152, 
+    53248, 55296, 55808, 55936, 55968, 55976,     0,     1, 
+    49152, 53248, 55296, 55808, 55936, 55968, 55976, 55978, 
+        0,     1, 49152, 53248, 55296, 55808, 55936, 55968, 
+    55976,     0,     1, 49152, 53248, 55296, 55808, 55936, 
+    55968, 55984, 55980,     0,     1, 49152, 53248, 55296, 
+    55808, 55936, 55968, 55984, 55980,     0,     1, 49152, 
+    53248, 55296, 55808, 55936, 55968, 55984, 55985, 55982, 
+        0,     1, 49152, 53248, 55296, 55808, 55936, 55968, 
+        0,     1, 49152, 53248, 55296, 55808, 55936, 56000, 
+    55984,     0,     1, 49152, 53248, 55296, 55808, 55936, 
+    56000, 55984,     0,     1, 49152, 53248, 55296, 55808, 
+    55936, 56000, 55984, 55986,     0,     1, 49152, 53248, 
+    55296, 55808, 55936, 56000, 55984,     0,     1, 49152, 
+    53248, 55296, 55808, 55936, 56000, 55984, 55988,     0, 
+        1, 49152, 53248, 55296, 55808, 55936, 56000, 55984, 
+    55988,     0,     1, 49152, 53248, 55296, 55808, 55936, 
+    56000, 55984, 55992, 55990,     0,     1, 49152, 53248, 
+    55296, 55808, 55936, 56000, 55984,     0,     1, 49152, 
+    53248, 55296, 55808, 55936, 56000, 56001, 55992,     0, 
+        1, 49152, 53248, 55296, 55808, 55936, 56000, 56001, 
+    55992,     0,     1, 49152, 53248, 55296, 55808, 55936, 
+    56000, 56001, 55992, 55994,     0,     1, 49152, 53248, 
+    55296, 55808, 55936, 56000, 56001, 55992,     0,     1, 
+    49152, 53248, 55296, 55808, 55936, 56000, 56001, 55992, 
+    55996,     0,     1, 49152, 53248, 55296, 55808, 55936, 
+    56000, 56001, 56003, 55996,     0,     1, 49152, 53248, 
+    55296, 55808, 55936, 56000, 56001, 56003, 55996, 55998, 
+        0,     1, 49152, 53248, 55296, 55808, 55936,     0, 
+        1, 49152, 53248, 55296, 55808, 56064, 56000,     0, 
+        1, 49152, 53248, 55296, 55808, 56064, 56000,     0, 
+        1, 49152, 53248, 55296, 55808, 56064, 56000, 56002, 
+        0,     1, 49152, 53248, 55296, 55808, 56064, 56000, 
+        0,     1, 49152, 53248, 55296, 55808, 56064, 56000, 
+    56004,     0,     1, 49152, 53248, 55296, 55808, 56064, 
+    56000, 56004,     0,     1, 49152, 53248, 55296, 55808, 
+    56064, 56000, 56008, 56006,     0,     1, 49152, 53248, 
+    55296, 55808, 56064, 56000,     0,     1, 49152, 53248, 
+    55296, 55808, 56064, 56000, 56008,     0,     1, 49152, 
+    53248, 55296, 55808, 56064, 56000, 56008,     0,     1, 
+    49152, 53248, 55296, 55808, 56064, 56000, 56008, 56010, 
+        0,     1, 49152, 53248, 55296, 55808, 56064, 56000, 
+    56008,     0,     1, 49152, 53248, 55296, 55808, 56064, 
+    56000, 56016, 56012,     0,     1, 49152, 53248, 55296, 
+    55808, 56064, 56000, 56016, 56012,     0,     1, 49152, 
+    53248, 55296, 55808, 56064, 56000, 56016, 56017, 56014, 
+        0,     1, 49152, 53248, 55296, 55808, 56064, 56000, 
+        0,     1, 49152, 53248, 55296, 55808, 56064, 56000, 
+    56016,     0,     1, 49152, 53248, 55296, 55808, 56064, 
+    56000, 56016,     0,     1, 49152, 53248, 55296, 55808, 
+    56064, 56000, 56016, 56018,     0,     1, 49152, 53248, 
+    55296, 55808, 56064, 56000, 56016,     0,     1, 49152, 
+    53248, 55296, 55808, 56064, 56000, 56016, 56020,     0, 
+        1, 49152, 53248, 55296, 55808, 56064, 56000, 56016, 
+    56020,     0,     1, 49152, 53248, 55296, 55808, 56064, 
+    56000, 56016, 56024, 56022,     0,     1, 49152, 53248, 
+    55296, 55808, 56064, 56000, 56016,     0,     1, 49152, 
+    53248, 55296, 55808, 56064, 56000, 56032, 56024,     0, 
+        1, 49152, 53248, 55296, 55808, 56064, 56000, 56032, 
+    56024,     0,     1, 49152, 53248, 55296, 55808, 56064, 
+    56000, 56032, 56024, 56026,     0,     1, 49152, 53248, 
+    55296, 55808, 56064, 56000, 56032, 56024,     0,     1, 
+    49152, 53248, 55296, 55808, 56064, 56000, 56032, 56033, 
+    56028,     0,     1, 49152, 53248, 55296, 55808, 56064, 
+    56000, 56032, 56033, 56028,     0,     1, 49152, 53248, 
+    55296, 55808, 56064, 56000, 56032, 56033, 56028, 56030, 
+        0,     1, 49152, 53248, 55296, 55808, 56064, 56000, 
+        0,     1, 49152, 53248, 55296, 55808, 56064, 56065, 
+    56032,     0,     1, 49152, 53248, 55296, 55808, 56064, 
+    56065, 56032,     0,     1, 49152, 53248, 55296, 55808, 
+    56064, 56065, 56032, 56034,     0,     1, 49152, 53248, 
+    55296, 55808, 56064, 56065, 56032,     0,     1, 49152, 
+    53248, 55296, 55808, 56064, 56065, 56032, 56036,     0, 
+        1, 49152, 53248, 55296, 55808, 56064, 56065, 56032, 
+    56036,     0,     1, 49152, 53248, 55296, 55808, 56064, 
+    56065, 56032, 56040, 56038,     0,     1, 49152, 53248, 
+    55296, 55808, 56064, 56065, 56032,     0,     1, 49152, 
+    53248, 55296, 55808, 56064, 56065, 56032, 56040,     0, 
+        1, 49152, 53248, 55296, 55808, 56064, 56065, 56032, 
+    56040,     0,     1, 49152, 53248, 55296, 55808, 56064, 
+    56065, 56032, 56040, 56042,     0,     1, 49152, 53248, 
+    55296, 55808, 56064, 56065, 56032, 56040,     0,     1, 
+    49152, 53248, 55296, 55808, 56064, 56065, 56032, 56048, 
+    56044,     0,     1, 49152, 53248, 55296, 55808, 56064, 
+    56065, 56032, 56048, 56044,     0,     1, 49152, 53248, 
+    55296, 55808, 56064, 56065, 56032, 56048, 56049, 56046, 
+        0,     1, 49152, 53248, 55296, 55808, 56064, 56065, 
+    56032,     0,     1, 49152, 53248, 55296, 55808, 56064, 
+    56065, 56032, 56048,     0,     1, 49152, 53248, 55296, 
+    55808, 56064, 56065, 56067, 56048,     0,     1, 49152, 
+    53248, 55296, 55808, 56064, 56065, 56067, 56048, 56050, 
+        0,     1, 49152, 53248, 55296, 55808, 56064, 56065, 
+    56067, 56048,     0,     1, 49152, 53248, 55296, 55808, 
+    56064, 56065, 56067, 56048, 56052,     0,     1, 49152, 
+    53248, 55296, 55808, 56064, 56065, 56067, 56048, 56052, 
+        0,     1, 49152, 53248, 55296, 55808, 56064, 56065, 
+    56067, 56048, 56056, 56054,     0,     1, 49152, 53248, 
+    55296, 55808, 56064, 56065, 56067, 56048,     0,     1, 
+    49152, 53248, 55296, 55808, 56064, 56065, 56067, 56048, 
+    56056,     0,     1, 49152, 53248, 55296, 55808, 56064, 
+    56065, 56067, 56048, 56056,     0,     1, 49152, 53248, 
+    55296, 55808, 56064, 56065, 56067, 56048, 56056, 56058, 
+        0,     1, 49152, 53248, 55296, 55808, 56064, 56065, 
+    56067, 56071, 56056,     0,     1, 49152, 53248, 55296, 
+    55808, 56064, 56065, 56067, 56071, 56056, 56060,     0, 
+        1, 49152, 53248, 55296, 55808, 56064, 56065, 56067, 
+    56071, 56056, 56060,     0,     1, 49152, 53248, 55296, 
+    55808, 56064, 56065, 56067, 56071, 56056, 56060, 56062, 
+        0,     1, 49152, 53248, 55296, 55808,     0,     1, 
+    49152, 53248, 55296, 56320, 56064,     0,     1, 49152, 
+    53248, 55296, 56320, 56064,     0,     1, 49152, 53248, 
+    55296, 56320, 56064, 56066,     0,     1, 49152, 53248, 
+    55296, 56320, 56064,     0,     1, 49152, 53248, 55296, 
+    56320, 56064, 56068,     0,     1, 49152, 53248, 55296, 
+    56320, 56064, 56068,     0,     1, 49152, 53248, 55296, 
+    56320, 56064, 56072, 56070,     0,     1, 49152, 53248, 
+    55296, 56320, 56064,     0,     1, 49152, 53248, 55296, 
+    56320, 56064, 56072,     0,     1, 49152, 53248, 55296, 
+    56320, 56064, 56072,     0,     1, 49152, 53248, 55296, 
+    56320, 56064, 56072, 56074,     0,     1, 49152, 53248, 
+    55296, 56320, 56064, 56072,     0,     1, 49152, 53248, 
+    55296, 56320, 56064, 56080, 56076,     0,     1, 49152, 
+    53248, 55296, 56320, 56064, 56080, 56076,     0,     1, 
+    49152, 53248, 55296, 56320, 56064, 56080, 56081, 56078, 
+        0,     1, 49152, 53248, 55296, 56320, 56064,     0, 
+        1, 49152, 53248, 55296, 56320, 56064, 56080,     0, 
+        1, 49152, 53248, 55296, 56320, 56064, 56080,     0, 
+        1, 49152, 53248, 55296, 56320, 56064, 56080, 56082, 
+        0,     1, 49152, 53248, 55296, 56320, 56064, 56080, 
+        0,     1, 49152, 53248, 55296, 56320, 56064, 56080, 
+    56084,     0,     1, 49152, 53248, 55296, 56320, 56064, 
+    56080, 56084,     0,     1, 49152, 53248, 55296, 56320, 
+    56064, 56080, 56088, 56086,     0,     1, 49152, 53248, 
+    55296, 56320, 56064, 56080,     0,     1, 49152, 53248, 
+    55296, 56320, 56064, 56096, 56088,     0,     1, 49152, 
+    53248, 55296, 56320, 56064, 56096, 56088,     0,     1, 
+    49152, 53248, 55296, 56320, 56064, 56096, 56088, 56090, 
+        0,     1, 49152, 53248, 55296, 56320, 56064, 56096, 
+    56088,     0,     1, 49152, 53248, 55296, 56320, 56064, 
+    56096, 56097, 56092,     0,     1, 49152, 53248, 55296, 
+    56320, 56064, 56096, 56097, 56092,     0,     1, 49152, 
+    53248, 55296, 56320, 56064, 56096, 56097, 56092, 56094, 
+        0,     1, 49152, 53248, 55296, 56320, 56064,     0, 
+        1, 49152, 53248, 55296, 56320, 56064, 56096,     0, 
+        1, 49152, 53248, 55296, 56320, 56064, 56096,     0, 
+        1, 49152, 53248, 55296, 56320, 56064, 56096, 56098, 
+        0,     1, 49152, 53248, 55296, 56320, 56064, 56096, 
+        0,     1, 49152, 53248, 55296, 56320, 56064, 56096, 
+    56100,     0,     1, 49152, 53248, 55296, 56320, 56064, 
+    56096, 56100,     0,     1, 49152, 53248, 55296, 56320, 
+    56064, 56096, 56104, 56102,     0,     1, 49152, 53248, 
+    55296, 56320, 56064, 56096,     0,     1, 49152, 53248, 
+    55296, 56320, 56064, 56096, 56104,     0,     1, 49152, 
+    53248, 55296, 56320, 56064, 56096, 56104,     0,     1, 
+    49152, 53248, 55296, 56320, 56064, 56096, 56104, 56106, 
+        0,     1, 49152, 53248, 55296, 56320, 56064, 56096, 
+    56104,     0,     1, 49152, 53248, 55296, 56320, 56064, 
+    56096, 56112, 56108,     0,     1, 49152, 53248, 55296, 
+    56320, 56064, 56096, 56112, 56108,     0,     1, 49152, 
+    53248, 55296, 56320, 56064, 56096, 56112, 56113, 56110, 
+        0,     1, 49152, 53248, 55296, 56320, 56064, 56096, 
+        0,     1, 49152, 53248, 55296, 56320, 56064, 56128, 
+    56112,     0,     1, 49152, 53248, 55296, 56320, 56064, 
+    56128, 56112,     0,     1, 49152, 53248, 55296, 56320, 
+    56064, 56128, 56112, 56114,     0,     1, 49152, 53248, 
+    55296, 56320, 56064, 56128, 56112,     0,     1, 49152, 
+    53248, 55296, 56320, 56064, 56128, 56112, 56116,     0, 
+        1, 49152, 53248, 55296, 56320, 56064, 56128, 56112, 
+    56116,     0,     1, 49152, 53248, 55296, 56320, 56064, 
+    56128, 56112, 56120, 56118,     0,     1, 49152, 53248, 
+    55296, 56320, 56064, 56128, 56112,     0,     1, 49152, 
+    53248, 55296, 56320, 56064, 56128, 56129, 56120,     0, 
+        1, 49152, 53248, 55296, 56320, 56064, 56128, 56129, 
+    56120,     0,     1, 49152, 53248, 55296, 56320, 56064, 
+    56128, 56129, 56120, 56122,     0,     1, 49152, 53248, 
+    55296, 56320, 56064, 56128, 56129, 56120,     0,     1, 
+    49152, 53248, 55296, 56320, 56064, 56128, 56129, 56120, 
+    56124,     0,     1, 49152, 53248, 55296, 56320, 56064, 
+    56128, 56129, 56131, 56124,     0,     1, 49152, 53248, 
+    55296, 56320, 56064, 56128, 56129, 56131, 56124, 56126, 
+        0,     1, 49152, 53248, 55296, 56320, 56064,     0, 
+        1, 49152, 53248, 55296, 56320, 56064, 56128,     0, 
+        1, 49152, 53248, 55296, 56320, 56064, 56128,     0, 
+        1, 49152, 53248, 55296, 56320, 56064, 56128, 56130, 
+        0,     1, 49152, 53248, 55296, 56320, 56064, 56128, 
+        0,     1, 49152, 53248, 55296, 56320, 56064, 56128, 
+    56132,     0,     1, 49152, 53248, 55296, 56320, 56064, 
+    56128, 56132,     0,     1, 49152, 53248, 55296, 56320, 
+    56064, 56128, 56136, 56134,     0,     1, 49152, 53248, 
+    55296, 56320, 56064, 56128,     0,     1, 49152, 53248, 
+    55296, 56320, 56064, 56128, 56136,     0,     1, 49152, 
+    53248, 55296, 56320, 56064, 56128, 56136,     0,     1, 
+    49152, 53248, 55296, 56320, 56064, 56128, 56136, 56138, 
+        0,     1, 49152, 53248, 55296, 56320, 56064, 56128, 
+    56136,     0,     1, 49152, 53248, 55296, 56320, 56064, 
+    56128, 56144, 56140,     0,     1, 49152, 53248, 55296, 
+    56320, 56064, 56128, 56144, 56140,     0,     1, 49152, 
+    53248, 55296, 56320, 56064, 56128, 56144, 56145, 56142, 
+        0,     1, 49152, 53248, 55296, 56320, 56064, 56128, 
+        0,     1, 49152, 53248, 55296, 56320, 56064, 56128, 
+    56144,     0,     1, 49152, 53248, 55296, 56320, 56064, 
+    56128, 56144,     0,     1, 49152, 53248, 55296, 56320, 
+    56064, 56128, 56144, 56146,     0,     1, 49152, 53248, 
+    55296, 56320, 56064, 56128, 56144,     0,     1, 49152, 
+    53248, 55296, 56320, 56064, 56128, 56144, 56148,     0, 
+        1, 49152, 53248, 55296, 56320, 56064, 56128, 56144, 
+    56148,     0,     1, 49152, 53248, 55296, 56320, 56064, 
+    56128, 56144, 56152, 56150,     0,     1, 49152, 53248, 
+    55296, 56320, 56064, 56128, 56144,     0,     1, 49152, 
+    53248, 55296, 56320, 56064, 56128, 56160, 56152,     0, 
+        1, 49152, 53248, 55296, 56320, 56064, 56128, 56160, 
+    56152,     0,     1, 49152, 53248, 55296, 56320, 56064, 
+    56128, 56160, 56152, 56154,     0,     1, 49152, 53248, 
+    55296, 56320, 56064, 56128, 56160, 56152,     0,     1, 
+    49152, 53248, 55296, 56320, 56064, 56128, 56160, 56161, 
+    56156,     0,     1, 49152, 53248, 55296, 56320, 56064, 
+    56128, 56160, 56161, 56156,     0,     1, 49152, 53248, 
+    55296, 56320, 56064, 56128, 56160, 56161, 56156, 56158, 
+        0,     1, 49152, 53248, 55296, 56320, 56064, 56128, 
+        0,     1, 49152, 53248, 55296, 56320, 56064, 56192, 
+    56160,     0,     1, 49152, 53248, 55296, 56320, 56064, 
+    56192, 56160,     0,     1, 49152, 53248, 55296, 56320, 
+    56064, 56192, 56160, 56162,     0,     1, 49152, 53248, 
+    55296, 56320, 56064, 56192, 56160,     0,     1, 49152, 
+    53248, 55296, 56320, 56064, 56192, 56160, 56164,     0, 
+        1, 49152, 53248, 55296, 56320, 56064, 56192, 56160, 
+    56164,     0,     1, 49152, 53248, 55296, 56320, 56064, 
+    56192, 56160, 56168, 56166,     0,     1, 49152, 53248, 
+    55296, 56320, 56064, 56192, 56160,     0,     1, 49152, 
+    53248, 55296, 56320, 56064, 56192, 56160, 56168,     0, 
+        1, 49152, 53248, 55296, 56320, 56064, 56192, 56160, 
+    56168,     0,     1, 49152, 53248, 55296, 56320, 56064, 
+    56192, 56160, 56168, 56170,     0,     1, 49152, 53248, 
+    55296, 56320, 56064, 56192, 56160, 56168,     0,     1, 
+    49152, 53248, 55296, 56320, 56064, 56192, 56160, 56176, 
+    56172,     0,     1, 49152, 53248, 55296, 56320, 56064, 
+    56192, 56160, 56176, 56172,     0,     1, 49152, 53248, 
+    55296, 56320, 56064, 56192, 56160, 56176, 56177, 56174, 
+        0,     1, 49152, 53248, 55296, 56320, 56064, 56192, 
+    56160,     0,     1, 49152, 53248, 55296, 56320, 56064, 
+    56192, 56193, 56176,     0,     1, 49152, 53248, 55296, 
+    56320, 56064, 56192, 56193, 56176,     0,     1, 49152, 
+    53248, 55296, 56320, 56064, 56192, 56193, 56176, 56178, 
+        0,     1, 49152, 53248, 55296, 56320, 56064, 56192, 
+    56193, 56176,     0,     1, 49152, 53248, 55296, 56320, 
+    56064, 56192, 56193, 56176, 56180,     0,     1, 49152, 
+    53248, 55296, 56320, 56064, 56192, 56193, 56176, 56180, 
+        0,     1, 49152, 53248, 55296, 56320, 56064, 56192, 
+    56193, 56176, 56184, 56182,     0,     1, 49152, 53248, 
+    55296, 56320, 56064, 56192, 56193, 56176,     0,     1, 
+    49152, 53248, 55296, 56320, 56064, 56192, 56193, 56176, 
+    56184,     0,     1, 49152, 53248, 55296, 56320, 56064, 
+    56192, 56193, 56195, 56184,     0,     1, 49152, 53248, 
+    55296, 56320, 56064, 56192, 56193, 56195, 56184, 56186, 
+        0,     1, 49152, 53248, 55296, 56320, 56064, 56192, 
+    56193, 56195, 56184,     0,     1, 49152, 53248, 55296, 
+    56320, 56064, 56192, 56193, 56195, 56184, 56188,     0, 
+        1, 49152, 53248, 55296, 56320, 56064, 56192, 56193, 
+    56195, 56184, 56188,     0,     1, 49152, 53248, 55296, 
+    56320, 56064, 56192, 56193, 56195, 56184, 56188, 56190, 
+        0,     1, 49152, 53248, 55296, 56320, 56064,     0, 
+        1, 49152, 53248, 55296, 56320, 56064, 56192,     0, 
+        1, 49152, 53248, 55296, 56320, 56321, 56192,     0, 
+        1, 49152, 53248, 55296, 56320, 56321, 56192, 56194, 
+        0,     1, 49152, 53248, 55296, 56320, 56321, 56192, 
+        0,     1, 49152, 53248, 55296, 56320, 56321, 56192, 
+    56196,     0,     1, 49152, 53248, 55296, 56320, 56321, 
+    56192, 56196,     0,     1, 49152, 53248, 55296, 56320, 
+    56321, 56192, 56200, 56198,     0,     1, 49152, 53248, 
+    55296, 56320, 56321, 56192,     0,     1, 49152, 53248, 
+    55296, 56320, 56321, 56192, 56200,     0,     1, 49152, 
+    53248, 55296, 56320, 56321, 56192, 56200,     0,     1, 
+    49152, 53248, 55296, 56320, 56321, 56192, 56200, 56202, 
+        0,     1, 49152, 53248, 55296, 56320, 56321, 56192, 
+    56200,     0,     1, 49152, 53248, 55296, 56320, 56321, 
+    56192, 56208, 56204,     0,     1, 49152, 53248, 55296, 
+    56320, 56321, 56192, 56208, 56204,     0,     1, 49152, 
+    53248, 55296, 56320, 56321, 56192, 56208, 56209, 56206, 
+        0,     1, 49152, 53248, 55296, 56320, 56321, 56192, 
+        0,     1, 49152, 53248, 55296, 56320, 56321, 56192, 
+    56208,     0,     1, 49152, 53248, 55296, 56320, 56321, 
+    56192, 56208,     0,     1, 49152, 53248, 55296, 56320, 
+    56321, 56192, 56208, 56210,     0,     1, 49152, 53248, 
+    55296, 56320, 56321, 56192, 56208,     0,     1, 49152, 
+    53248, 55296, 56320, 56321, 56192, 56208, 56212,     0, 
+        1, 49152, 53248, 55296, 56320, 56321, 56192, 56208, 
+    56212,     0,     1, 49152, 53248, 55296, 56320, 56321, 
+    56192, 56208, 56216, 56214,     0,     1, 49152, 53248, 
+    55296, 56320, 56321, 56192, 56208,     0,     1, 49152, 
+    53248, 55296, 56320, 56321, 56192, 56224, 56216,     0, 
+        1, 49152, 53248, 55296, 56320, 56321, 56192, 56224, 
+    56216,     0,     1, 49152, 53248, 55296, 56320, 56321, 
+    56192, 56224, 56216, 56218,     0,     1, 49152, 53248, 
+    55296, 56320, 56321, 56192, 56224, 56216,     0,     1, 
+    49152, 53248, 55296, 56320, 56321, 56192, 56224, 56225, 
+    56220,     0,     1, 49152, 53248, 55296, 56320, 56321, 
+    56192, 56224, 56225, 56220,     0,     1, 49152, 53248, 
+    55296, 56320, 56321, 56192, 56224, 56225, 56220, 56222, 
+        0,     1, 49152, 53248, 55296, 56320, 56321, 56192, 
+        0,     1, 49152, 53248, 55296, 56320, 56321, 56192, 
+    56224,     0,     1, 49152, 53248, 55296, 56320, 56321, 
+    56192, 56224,     0,     1, 49152, 53248, 55296, 56320, 
+    56321, 56192, 56224, 56226,     0,     1, 49152, 53248, 
+    55296, 56320, 56321, 56192, 56224,     0,     1, 49152, 
+    53248, 55296, 56320, 56321, 56192, 56224, 56228,     0, 
+        1, 49152, 53248, 55296, 56320, 56321, 56192, 56224, 
+    56228,     0,     1, 49152, 53248, 55296, 56320, 56321, 
+    56192, 56224, 56232, 56230,     0,     1, 49152, 53248, 
+    55296, 56320, 56321, 56192, 56224,     0,     1, 49152, 
+    53248, 55296, 56320, 56321, 56192, 56224, 56232,     0, 
+        1, 49152, 53248, 55296, 56320, 56321, 56192, 56224, 
+    56232,     0,     1, 49152, 53248, 55296, 56320, 56321, 
+    56192, 56224, 56232, 56234,     0,     1, 49152, 53248, 
+    55296, 56320, 56321, 56192, 56224, 56232,     0,     1, 
+    49152, 53248, 55296, 56320, 56321, 56192, 56224, 56240, 
+    56236,     0,     1, 49152, 53248, 55296, 56320, 56321, 
+    56192, 56224, 56240, 56236,     0,     1, 49152, 53248, 
+    55296, 56320, 56321, 56192, 56224, 56240, 56241, 56238, 
+        0,     1, 49152, 53248, 55296, 56320, 56321, 56192, 
+    56224,     0,     1, 49152, 53248, 55296, 56320, 56321, 
+    56192, 56256, 56240,     0,     1, 49152, 53248, 55296, 
+    56320, 56321, 56192, 56256, 56240,     0,     1, 49152, 
+    53248, 55296, 56320, 56321, 56192, 56256, 56240, 56242, 
+        0,     1, 49152, 53248, 55296, 56320, 56321, 56192, 
+    56256, 56240,     0,     1, 49152, 53248, 55296, 56320, 
+    56321, 56192, 56256, 56240, 56244,     0,     1, 49152, 
+    53248, 55296, 56320, 56321, 56192, 56256, 56240, 56244, 
+        0,     1, 49152, 53248, 55296, 56320, 56321, 56192, 
+    56256, 56240, 56248, 56246,     0,     1, 49152, 53248, 
+    55296, 56320, 56321, 56192, 56256, 56240,     0,     1, 
+    49152, 53248, 55296, 56320, 56321, 56192, 56256, 56257, 
+    56248,     0,     1, 49152, 53248, 55296, 56320, 56321, 
+    56192, 56256, 56257, 56248,     0,     1, 49152, 53248, 
+    55296, 56320, 56321, 56192, 56256, 56257, 56248, 56250, 
+        0,     1, 49152, 53248, 55296, 56320, 56321, 56192, 
+    56256, 56257, 56248,     0,     1, 49152, 53248, 55296, 
+    56320, 56321, 56192, 56256, 56257, 56248, 56252,     0, 
+        1, 49152, 53248, 55296, 56320, 56321, 56192, 56256, 
+    56257, 56259, 56252,     0,     1, 49152, 53248, 55296, 
+    56320, 56321, 56192, 56256, 56257, 56259, 56252, 56254, 
+        0,     1, 49152, 53248, 55296, 56320, 56321, 56192, 
+        0,     1, 49152, 53248, 55296, 56320, 56321, 56192, 
+    56256,     0,     1, 49152, 53248, 55296, 56320, 56321, 
+    56192, 56256,     0,     1, 49152, 53248, 55296, 56320, 
+    56321, 56192, 56256, 56258,     0,     1, 49152, 53248, 
+    55296, 56320, 56321, 56323, 56256,     0,     1, 49152, 
+    53248, 55296, 56320, 56321, 56323, 56256, 56260,     0, 
+        1, 49152, 53248, 55296, 56320, 56321, 56323, 56256, 
+    56260,     0,     1, 49152, 53248, 55296, 56320, 56321, 
+    56323, 56256, 56264, 56262,     0,     1, 49152, 53248, 
+    55296, 56320, 56321, 56323, 56256,     0,     1, 49152, 
+    53248, 55296, 56320, 56321, 56323, 56256, 56264,     0, 
+        1, 49152, 53248, 55296, 56320, 56321, 56323, 56256, 
+    56264,     0,     1, 49152, 53248, 55296, 56320, 56321, 
+    56323, 56256, 56264, 56266,     0,     1, 49152, 53248, 
+    55296, 56320, 56321, 56323, 56256, 56264,     0,     1, 
+    49152, 53248, 55296, 56320, 56321, 56323, 56256, 56272, 
+    56268,     0,     1, 49152, 53248, 55296, 56320, 56321, 
+    56323, 56256, 56272, 56268,     0,     1, 49152, 53248, 
+    55296, 56320, 56321, 56323, 56256, 56272, 56273, 56270, 
+        0,     1, 49152, 53248, 55296, 56320, 56321, 56323, 
+    56256,     0,     1, 49152, 53248, 55296, 56320, 56321, 
+    56323, 56256, 56272,     0,     1, 49152, 53248, 55296, 
+    56320, 56321, 56323, 56256, 56272,     0,     1, 49152, 
+    53248, 55296, 56320, 56321, 56323, 56256, 56272, 56274, 
+        0,     1, 49152, 53248, 55296, 56320, 56321, 56323, 
+    56256, 56272,     0,     1, 49152, 53248, 55296, 56320, 
+    56321, 56323, 56256, 56272, 56276,     0,     1, 49152, 
+    53248, 55296, 56320, 56321, 56323, 56256, 56272, 56276, 
+        0,     1, 49152, 53248, 55296, 56320, 56321, 56323, 
+    56256, 56272, 56280, 56278,     0,     1, 49152, 53248, 
+    55296, 56320, 56321, 56323, 56256, 56272,     0,     1, 
+    49152, 53248, 55296, 56320, 56321, 56323, 56256, 56288, 
+    56280,     0,     1, 49152, 53248, 55296, 56320, 56321, 
+    56323, 56256, 56288, 56280,     0,     1, 49152, 53248, 
+    55296, 56320, 56321, 56323, 56256, 56288, 56280, 56282, 
+        0,     1, 49152, 53248, 55296, 56320, 56321, 56323, 
+    56256, 56288, 56280,     0,     1, 49152, 53248, 55296, 
+    56320, 56321, 56323, 56256, 56288, 56289, 56284,     0, 
+        1, 49152, 53248, 55296, 56320, 56321, 56323, 56256, 
+    56288, 56289, 56284,     0,     1, 49152, 53248, 55296, 
+    56320, 56321, 56323, 56256, 56288, 56289, 56284, 56286, 
+        0,     1, 49152, 53248, 55296, 56320, 56321, 56323, 
+    56256,     0,     1, 49152, 53248, 55296, 56320, 56321, 
+    56323, 56256, 56288,     0,     1, 49152, 53248, 55296, 
+    56320, 56321, 56323, 56256, 56288,     0,     1, 49152, 
+    53248, 55296, 56320, 56321, 56323, 56256, 56288, 56290, 
+        0,     1, 49152, 53248, 55296, 56320, 56321, 56323, 
+    56256, 56288,     0,     1, 49152, 53248, 55296, 56320, 
+    56321, 56323, 56256, 56288, 56292,     0,     1, 49152, 
+    53248, 55296, 56320, 56321, 56323, 56256, 56288, 56292, 
+        0,     1, 49152, 53248, 55296, 56320, 56321, 56323, 
+    56256, 56288, 56296, 56294,     0,     1, 49152, 53248, 
+    55296, 56320, 56321, 56323, 56327, 56288,     0,     1, 
+    49152, 53248, 55296, 56320, 56321, 56323, 56327, 56288, 
+    56296,     0,     1, 49152, 53248, 55296, 56320, 56321, 
+    56323, 56327, 56288, 56296,     0,     1, 49152, 53248, 
+    55296, 56320, 56321, 56323, 56327, 56288, 56296, 56298, 
+        0,     1, 49152, 53248, 55296, 56320, 56321, 56323, 
+    56327, 56288, 56296,     0,     1, 49152, 53248, 55296, 
+    56320, 56321, 56323, 56327, 56288, 56304, 56300,     0, 
+        1, 49152, 53248, 55296, 56320, 56321, 56323, 56327, 
+    56288, 56304, 56300,     0,     1, 49152, 53248, 55296, 
+    56320, 56321, 56323, 56327, 56288, 56304, 56305, 56302, 
+        0,     1, 49152, 53248, 55296, 56320, 56321, 56323, 
+    56327, 56288,     0,     1, 49152, 53248, 55296, 56320, 
+    56321, 56323, 56327, 56288, 56304,     0,     1, 49152, 
+    53248, 55296, 56320, 56321, 56323, 56327, 56288, 56304, 
+        0,     1, 49152, 53248, 55296, 56320, 56321, 56323, 
+    56327, 56288, 56304, 56306,     0,     1, 49152, 53248, 
+    55296, 56320, 56321, 56323, 56327, 56288, 56304,     0, 
+        1, 49152, 53248, 55296, 56320, 56321, 56323, 56327, 
+    56288, 56304, 56308,     0,     1, 49152, 53248, 55296, 
+    56320, 56321, 56323, 56327, 56288, 56304, 56308,     0, 
+        1, 49152, 53248, 55296, 56320, 56321, 56323, 56327, 
+    56288, 56304, 56312, 56310,     0,     1, 49152, 53248, 
+    55296, 56320, 56321, 56323, 56327, 56288, 56304,     0, 
+        1, 49152, 53248, 55296, 56320, 56321, 56323, 56327, 
+    56288, 56304, 56312,     0,     1, 49152, 53248, 55296, 
+    56320, 56321, 56323, 56327, 56288, 56304, 56312,     0, 
+        1, 49152, 53248, 55296, 56320, 56321, 56323, 56327, 
+    56288, 56304, 56312, 56314,     0,     1, 49152, 53248, 
+    55296, 56320, 56321, 56323, 56327, 56288, 56304, 56312, 
+        0,     1, 49152, 53248, 55296, 56320, 56321, 56323, 
+    56327, 56288, 56304, 56312, 56316,     0,     1, 49152, 
+    53248, 55296, 56320, 56321, 56323, 56327, 56288, 56304, 
+    56312, 56316,     0,     1, 49152, 53248, 55296, 56320, 
+    56321, 56323, 56327, 56288, 56304, 56312, 56316, 56318, 
+        0,     1, 49152, 53248, 55296,     0,     1, 49152, 
+    53248, 55296, 56320,     0,     1, 49152, 53248, 55296, 
+    56320,     0,     1, 49152, 53248, 55296, 56320, 56322, 
+        0,     1, 49152, 53248, 55296, 56320,     0,     1, 
+    49152, 53248, 55296, 56320, 56324,     0,     1, 49152, 
+    53248, 55296, 56320, 56324,     0,     1, 49152, 53248, 
+    55296, 56320, 56328, 56326,     0,     1, 49152, 53248, 
+    55296, 56320,     0,     1, 49152, 53248, 55296, 56320, 
+    56328,     0,     1, 49152, 53248, 55296, 56320, 56328, 
+        0,     1, 49152, 53248, 55296, 56320, 56328, 56330, 
+        0,     1, 49152, 53248, 55296, 56320, 56328,     0, 
+        1, 49152, 53248, 55296, 56320, 56336, 56332,     0, 
+        1, 49152, 53248, 55296, 56320, 56336, 56332,     0, 
+        1, 49152, 53248, 55296, 56320, 56336, 56337, 56334, 
+        0,     1, 49152, 53248, 55296, 56320,     0,     1, 
+    49152, 53248, 55296, 56320, 56336,     0,     1, 49152, 
+    53248, 55296, 56320, 56336,     0,     1, 49152, 53248, 
+    55296, 56320, 56336, 56338,     0,     1, 49152, 53248, 
+    55296, 56320, 56336,     0,     1, 49152, 53248, 55296, 
+    56320, 56336, 56340,     0,     1, 49152, 53248, 55296, 
+    56320, 56336, 56340,     0,     1, 49152, 53248, 55296, 
+    56320, 56336, 56344, 56342,     0,     1, 49152, 53248, 
+    55296, 56320, 56336,     0,     1, 49152, 53248, 55296, 
+    56320, 56352, 56344,     0,     1, 49152, 53248, 55296, 
+    56320, 56352, 56344,     0,     1, 49152, 53248, 55296, 
+    56320, 56352, 56344, 56346,     0,     1, 49152, 53248, 
+    55296, 56320, 56352, 56344,     0,     1, 49152, 53248, 
+    55296, 56320, 56352, 56353, 56348,     0,     1, 49152, 
+    53248, 55296, 56320, 56352, 56353, 56348,     0,     1, 
+    49152, 53248, 55296, 56320, 56352, 56353, 56348, 56350, 
+        0,     1, 49152, 53248, 55296, 56320,     0,     1, 
+    49152, 53248, 55296, 56320, 56352,     0,     1, 49152, 
+    53248, 55296, 56320, 56352,     0,     1, 49152, 53248, 
+    55296, 56320, 56352, 56354,     0,     1, 49152, 53248, 
+    55296, 56320, 56352,     0,     1, 49152, 53248, 55296, 
+    56320, 56352, 56356,     0,     1, 49152, 53248, 55296, 
+    56320, 56352, 56356,     0,     1, 49152, 53248, 55296, 
+    56320, 56352, 56360, 56358,     0,     1, 49152, 53248, 
+    55296, 56320, 56352,     0,     1, 49152, 53248, 55296, 
+    56320, 56352, 56360,     0,     1, 49152, 53248, 55296, 
+    56320, 56352, 56360,     0,     1, 49152, 53248, 55296, 
+    56320, 56352, 56360, 56362,     0,     1, 49152, 53248, 
+    55296, 56320, 56352, 56360,     0,     1, 49152, 53248, 
+    55296, 56320, 56352, 56368, 56364,     0,     1, 49152, 
+    53248, 55296, 56320, 56352, 56368, 56364,     0,     1, 
+    49152, 53248, 55296, 56320, 56352, 56368, 56369, 56366, 
+        0,     1, 49152, 53248, 55296, 56320, 56352,     0, 
+        1, 49152, 53248, 55296, 56320, 56384, 56368,     0, 
+        1, 49152, 53248, 55296, 56320, 56384, 56368,     0, 
+        1, 49152, 53248, 55296, 56320, 56384, 56368, 56370, 
+        0,     1, 49152, 53248, 55296, 56320, 56384, 56368, 
+        0,     1, 49152, 53248, 55296, 56320, 56384, 56368, 
+    56372,     0,     1, 49152, 53248, 55296, 56320, 56384, 
+    56368, 56372,     0,     1, 49152, 53248, 55296, 56320, 
+    56384, 56368, 56376, 56374,     0,     1, 49152, 53248, 
+    55296, 56320, 56384, 56368,     0,     1, 49152, 53248, 
+    55296, 56320, 56384, 56385, 56376,     0,     1, 49152, 
+    53248, 55296, 56320, 56384, 56385, 56376,     0,     1, 
+    49152, 53248, 55296, 56320, 56384, 56385, 56376, 56378, 
+        0,     1, 49152, 53248, 55296, 56320, 56384, 56385, 
+    56376,     0,     1, 49152, 53248, 55296, 56320, 56384, 
+    56385, 56376, 56380,     0,     1, 49152, 53248, 55296, 
+    56320, 56384, 56385, 56387, 56380,     0,     1, 49152, 
+    53248, 55296, 56320, 56384, 56385, 56387, 56380, 56382, 
+        0,     1, 49152, 53248, 55296, 56320,     0,     1, 
+    49152, 57344, 55296, 56320, 56384,     0,     1, 49152, 
+    57344, 55296, 56320, 56384,     0,     1, 49152, 57344, 
+    55296, 56320, 56384, 56386,     0,     1, 49152, 57344, 
+    55296, 56320, 56384,     0,     1, 49152, 57344, 55296, 
+    56320, 56384, 56388,     0,     1, 49152, 57344, 55296, 
+    56320, 56384, 56388,     0,     1, 49152, 57344, 55296, 
+    56320, 56384, 56392, 56390,     0,     1, 49152, 57344, 
+    55296, 56320, 56384,     0,     1, 49152, 57344, 55296, 
+    56320, 56384, 56392,     0,     1, 49152, 57344, 55296, 
+    56320, 56384, 56392,     0,     1, 49152, 57344, 55296, 
+    56320, 56384, 56392, 56394,     0,     1, 49152, 57344, 
+    55296, 56320, 56384, 56392,     0,     1, 49152, 57344, 
+    55296, 56320, 56384, 56400, 56396,     0,     1, 49152, 
+    57344, 55296, 56320, 56384, 56400, 56396,     0,     1, 
+    49152, 57344, 55296, 56320, 56384, 56400, 56401, 56398, 
+        0,     1, 49152, 57344, 55296, 56320, 56384,     0, 
+        1, 49152, 57344, 55296, 56320, 56384, 56400,     0, 
+        1, 49152, 57344, 55296, 56320, 56384, 56400,     0, 
+        1, 49152, 57344, 55296, 56320, 56384, 56400, 56402, 
+        0,     1, 49152, 57344, 55296, 56320, 56384, 56400, 
+        0,     1, 49152, 57344, 55296, 56320, 56384, 56400, 
+    56404,     0,     1, 49152, 57344, 55296, 56320, 56384, 
+    56400, 56404,     0,     1, 49152, 57344, 55296, 56320, 
+    56384, 56400, 56408, 56406,     0,     1, 49152, 57344, 
+    55296, 56320, 56384, 56400,     0,     1, 49152, 57344, 
+    55296, 56320, 56384, 56416, 56408,     0,     1, 49152, 
+    57344, 55296, 56320, 56384, 56416, 56408,     0,     1, 
+    49152, 57344, 55296, 56320, 56384, 56416, 56408, 56410, 
+        0,     1, 49152, 57344, 55296, 56320, 56384, 56416, 
+    56408,     0,     1, 49152, 57344, 55296, 56320, 56384, 
+    56416, 56417, 56412,     0,     1, 49152, 57344, 55296, 
+    56320, 56384, 56416, 56417, 56412,     0,     1, 49152, 
+    57344, 55296, 56320, 56384, 56416, 56417, 56412, 56414, 
+        0,     1, 49152, 57344, 55296, 56320, 56384,     0, 
+        1, 49152, 57344, 55296, 56320, 56448, 56416,     0, 
+        1, 49152, 57344, 55296, 56320, 56448, 56416,     0, 
+        1, 49152, 57344, 55296, 56320, 56448, 56416, 56418, 
+        0,     1, 49152, 57344, 55296, 56320, 56448, 56416, 
+        0,     1, 49152, 57344, 55296, 56320, 56448, 56416, 
+    56420,     0,     1, 49152, 57344, 55296, 56320, 56448, 
+    56416, 56420,     0,     1, 49152, 57344, 55296, 56320, 
+    56448, 56416, 56424, 56422,     0,     1, 49152, 57344, 
+    55296, 56320, 56448, 56416,     0,     1, 49152, 57344, 
+    55296, 56320, 56448, 56416, 56424,     0,     1, 49152, 
+    57344, 55296, 56320, 56448, 56416, 56424,     0,     1, 
+    49152, 57344, 55296, 56320, 56448, 56416, 56424, 56426, 
+        0,     1, 49152, 57344, 55296, 56320, 56448, 56416, 
+    56424,     0,     1, 49152, 57344, 55296, 56320, 56448, 
+    56416, 56432, 56428,     0,     1, 49152, 57344, 55296, 
+    56320, 56448, 56416, 56432, 56428,     0,     1, 49152, 
+    57344, 55296, 56320, 56448, 56416, 56432, 56433, 56430, 
+        0,     1, 49152, 57344, 55296, 56320, 56448, 56416, 
+        0,     1, 49152, 57344, 55296, 56320, 56448, 56449, 
+    56432,     0,     1, 49152, 57344, 55296, 56320, 56448, 
+    56449, 56432,     0,     1, 49152, 57344, 55296, 56320, 
+    56448, 56449, 56432, 56434,     0,     1, 49152, 57344, 
+    55296, 56320, 56448, 56449, 56432,     0,     1, 49152, 
+    57344, 55296, 56320, 56448, 56449, 56432, 56436,     0, 
+        1, 49152, 57344, 55296, 56320, 56448, 56449, 56432, 
+    56436,     0,     1, 49152, 57344, 55296, 56320, 56448, 
+    56449, 56432, 56440, 56438,     0,     1, 49152, 57344, 
+    55296, 56320, 56448, 56449, 56432,     0,     1, 49152, 
+    57344, 55296, 56320, 56448, 56449, 56432, 56440,     0, 
+        1, 49152, 57344, 55296, 56320, 56448, 56449, 56451, 
+    56440,     0,     1, 49152, 57344, 55296, 56320, 56448, 
+    56449, 56451, 56440, 56442,     0,     1, 49152, 57344, 
+    55296, 56320, 56448, 56449, 56451, 56440,     0,     1, 
+    49152, 57344, 55296, 56320, 56448, 56449, 56451, 56440, 
+    56444,     0,     1, 49152, 57344, 55296, 56320, 56448, 
+    56449, 56451, 56440, 56444,     0,     1, 49152, 57344, 
+    55296, 56320, 56448, 56449, 56451, 56440, 56444, 56446, 
+        0,     1, 49152, 57344, 55296, 56320,     0,     1, 
+    49152, 57344, 55296, 56320, 56448,     0,     1, 49152, 
+    57344, 55296, 56320, 56448,     0,     1, 49152, 57344, 
+    55296, 56320, 56448, 56450,     0,     1, 49152, 57344, 
+    55296, 56320, 56448,     0,     1, 49152, 57344, 55296, 
+    56320, 56448, 56452,     0,     1, 49152, 57344, 55296, 
+    56320, 56448, 56452,     0,     1, 49152, 57344, 55296, 
+    56320, 56448, 56456, 56454,     0,     1, 49152, 57344, 
+    55296, 56320, 56448,     0,     1, 49152, 57344, 55296, 
+    56320, 56448, 56456,     0,     1, 49152, 57344, 55296, 
+    56320, 56448, 56456,     0,     1, 49152, 57344, 55296, 
+    56320, 56448, 56456, 56458,     0,     1, 49152, 57344, 
+    55296, 56320, 56448, 56456,     0,     1, 49152, 57344, 
+    55296, 56320, 56448, 56464, 56460,     0,     1, 49152, 
+    57344, 55296, 56320, 56448, 56464, 56460,     0,     1, 
+    49152, 57344, 55296, 56320, 56448, 56464, 56465, 56462, 
+        0,     1, 49152, 57344, 55296, 56320, 56448,     0, 
+        1, 49152, 57344, 55296, 56320, 56448, 56464,     0, 
+        1, 49152, 57344, 55296, 56320, 56448, 56464,     0, 
+        1, 49152, 57344, 55296, 56320, 56448, 56464, 56466, 
+        0,     1, 49152, 57344, 55296, 56320, 56448, 56464, 
+        0,     1, 49152, 57344, 55296, 56320, 56448, 56464, 
+    56468,     0,     1, 49152, 57344, 55296, 56320, 56448, 
+    56464, 56468,     0,     1, 49152, 57344, 55296, 56320, 
+    56448, 56464, 56472, 56470,     0,     1, 49152, 57344, 
+    55296, 56320, 56448, 56464,     0,     1, 49152, 57344, 
+    55296, 56320, 56448, 56480, 56472,     0,     1, 49152, 
+    57344, 55296, 56320, 56448, 56480, 56472,     0,     1, 
+    49152, 57344, 55296, 56320, 56448, 56480, 56472, 56474, 
+        0,     1, 49152, 57344, 55296, 56320, 56448, 56480, 
+    56472,     0,     1, 49152, 57344, 55296, 56320, 56448, 
+    56480, 56481, 56476,     0,     1, 49152, 57344, 55296, 
+    56320, 56448, 56480, 56481, 56476,     0,     1, 49152, 
+    57344, 55296, 56320, 56448, 56480, 56481, 56476, 56478, 
+        0,     1, 49152, 57344, 55296, 56320, 56448,     0, 
+        1, 49152, 57344, 55296, 56320, 56448, 56480,     0, 
+        1, 49152, 57344, 55296, 56320, 56448, 56480,     0, 
+        1, 49152, 57344, 55296, 56320, 56448, 56480, 56482, 
+        0,     1, 49152, 57344, 55296, 56320, 56448, 56480, 
+        0,     1, 49152, 57344, 55296, 56320, 56448, 56480, 
+    56484,     0,     1, 49152, 57344, 55296, 56320, 56448, 
+    56480, 56484,     0,     1, 49152, 57344, 55296, 56320, 
+    56448, 56480, 56488, 56486,     0,     1, 49152, 57344, 
+    55296, 56320, 56448, 56480,     0,     1, 49152, 57344, 
+    55296, 56320, 56448, 56480, 56488,     0,     1, 49152, 
+    57344, 55296, 56320, 56448, 56480, 56488,     0,     1, 
+    49152, 57344, 55296, 56320, 56448, 56480, 56488, 56490, 
+        0,     1, 49152, 57344, 55296, 56320, 56448, 56480, 
+    56488,     0,     1, 49152, 57344, 55296, 56320, 56448, 
+    56480, 56496, 56492,     0,     1, 49152, 57344, 55296, 
+    56320, 56448, 56480, 56496, 56492,     0,     1, 49152, 
+    57344, 55296, 56320, 56448, 56480, 56496, 56497, 56494, 
+        0,     1, 49152, 57344, 55296, 56320, 56448, 56480, 
+        0,     1, 49152, 57344, 55296, 56320, 56448, 56512, 
+    56496,     0,     1, 49152, 57344, 55296, 56320, 56448, 
+    56512, 56496,     0,     1, 49152, 57344, 55296, 56320, 
+    56448, 56512, 56496, 56498,     0,     1, 49152, 57344, 
+    55296, 56320, 56448, 56512, 56496,     0,     1, 49152, 
+    57344, 55296, 56320, 56448, 56512, 56496, 56500,     0, 
+        1, 49152, 57344, 55296, 56320, 56448, 56512, 56496, 
+    56500,     0,     1, 49152, 57344, 55296, 56320, 56448, 
+    56512, 56496, 56504, 56502,     0,     1, 49152, 57344, 
+    55296, 56320, 56448, 56512, 56496,     0,     1, 49152, 
+    57344, 55296, 56320, 56448, 56512, 56513, 56504,     0, 
+        1, 49152, 57344, 55296, 56320, 56448, 56512, 56513, 
+    56504,     0,     1, 49152, 57344, 55296, 56320, 56448, 
+    56512, 56513, 56504, 56506,     0,     1, 49152, 57344, 
+    55296, 56320, 56448, 56512, 56513, 56504,     0,     1, 
+    49152, 57344, 55296, 56320, 56448, 56512, 56513, 56504, 
+    56508,     0,     1, 49152, 57344, 55296, 56320, 56448, 
+    56512, 56513, 56515, 56508,     0,     1, 49152, 57344, 
+    55296, 56320, 56448, 56512, 56513, 56515, 56508, 56510, 
+        0,     1, 49152, 57344, 55296, 56320, 56448,     0, 
+        1, 49152, 57344, 55296, 56320, 56576, 56512,     0, 
+        1, 49152, 57344, 55296, 56320, 56576, 56512,     0, 
+        1, 49152, 57344, 55296, 56320, 56576, 56512, 56514, 
+        0,     1, 49152, 57344, 55296, 56320, 56576, 56512, 
+        0,     1, 49152, 57344, 55296, 56320, 56576, 56512, 
+    56516,     0,     1, 49152, 57344, 55296, 56320, 56576, 
+    56512, 56516,     0,     1, 49152, 57344, 55296, 56320, 
+    56576, 56512, 56520, 56518,     0,     1, 49152, 57344, 
+    55296, 56320, 56576, 56512,     0,     1, 49152, 57344, 
+    55296, 56320, 56576, 56512, 56520,     0,     1, 49152, 
+    57344, 55296, 56320, 56576, 56512, 56520,     0,     1, 
+    49152, 57344, 55296, 56320, 56576, 56512, 56520, 56522, 
+        0,     1, 49152, 57344, 55296, 56320, 56576, 56512, 
+    56520,     0,     1, 49152, 57344, 55296, 56320, 56576, 
+    56512, 56528, 56524,     0,     1, 49152, 57344, 55296, 
+    56320, 56576, 56512, 56528, 56524,     0,     1, 49152, 
+    57344, 55296, 56320, 56576, 56512, 56528, 56529, 56526, 
+        0,     1, 49152, 57344, 55296, 56320, 56576, 56512, 
+        0,     1, 49152, 57344, 55296, 56320, 56576, 56512, 
+    56528,     0,     1, 49152, 57344, 55296, 56320, 56576, 
+    56512, 56528,     0,     1, 49152, 57344, 55296, 56320, 
+    56576, 56512, 56528, 56530,     0,     1, 49152, 57344, 
+    55296, 56320, 56576, 56512, 56528,     0,     1, 49152, 
+    57344, 55296, 56320, 56576, 56512, 56528, 56532,     0, 
+        1, 49152, 57344, 55296, 56320, 56576, 56512, 56528, 
+    56532,     0,     1, 49152, 57344, 55296, 56320, 56576, 
+    56512, 56528, 56536, 56534,     0,     1, 49152, 57344, 
+    55296, 56320, 56576, 56512, 56528,     0,     1, 49152, 
+    57344, 55296, 56320, 56576, 56512, 56544, 56536,     0, 
+        1, 49152, 57344, 55296, 56320, 56576, 56512, 56544, 
+    56536,     0,     1, 49152, 57344, 55296, 56320, 56576, 
+    56512, 56544, 56536, 56538,     0,     1, 49152, 57344, 
+    55296, 56320, 56576, 56512, 56544, 56536,     0,     1, 
+    49152, 57344, 55296, 56320, 56576, 56512, 56544, 56545, 
+    56540,     0,     1, 49152, 57344, 55296, 56320, 56576, 
+    56512, 56544, 56545, 56540,     0,     1, 49152, 57344, 
+    55296, 56320, 56576, 56512, 56544, 56545, 56540, 56542, 
+        0,     1, 49152, 57344, 55296, 56320, 56576, 56512, 
+        0,     1, 49152, 57344, 55296, 56320, 56576, 56577, 
+    56544,     0,     1, 49152, 57344, 55296, 56320, 56576, 
+    56577, 56544,     0,     1, 49152, 57344, 55296, 56320, 
+    56576, 56577, 56544, 56546,     0,     1, 49152, 57344, 
+    55296, 56320, 56576, 56577, 56544,     0,     1, 49152, 
+    57344, 55296, 56320, 56576, 56577, 56544, 56548,     0, 
+        1, 49152, 57344, 55296, 56320, 56576, 56577, 56544, 
+    56548,     0,     1, 49152, 57344, 55296, 56320, 56576, 
+    56577, 56544, 56552, 56550,     0,     1, 49152, 57344, 
+    55296, 56320, 56576, 56577, 56544,     0,     1, 49152, 
+    57344, 55296, 56320, 56576, 56577, 56544, 56552,     0, 
+        1, 49152, 57344, 55296, 56320, 56576, 56577, 56544, 
+    56552,     0,     1, 49152, 57344, 55296, 56320, 56576, 
+    56577, 56544, 56552, 56554,     0,     1, 49152, 57344, 
+    55296, 56320, 56576, 56577, 56544, 56552,     0,     1, 
+    49152, 57344, 55296, 56320, 56576, 56577, 56544, 56560, 
+    56556,     0,     1, 49152, 57344, 55296, 56320, 56576, 
+    56577, 56544, 56560, 56556,     0,     1, 49152, 57344, 
+    55296, 56320, 56576, 56577, 56544, 56560, 56561, 56558, 
+        0,     1, 49152, 57344, 55296, 56320, 56576, 56577, 
+    56544,     0,     1, 49152, 57344, 55296, 56320, 56576, 
+    56577, 56544, 56560,     0,     1, 49152, 57344, 55296, 
+    56320, 56576, 56577, 56579, 56560,     0,     1, 49152, 
+    57344, 55296, 56320, 56576, 56577, 56579, 56560, 56562, 
+        0,     1, 49152, 57344, 55296, 56320, 56576, 56577, 
+    56579, 56560,     0,     1, 49152, 57344, 55296, 56320, 
+    56576, 56577, 56579, 56560, 56564,     0,     1, 49152, 
+    57344, 55296, 56320, 56576, 56577, 56579, 56560, 56564, 
+        0,     1, 49152, 57344, 55296, 56320, 56576, 56577, 
+    56579, 56560, 56568, 56566,     0,     1, 49152, 57344, 
+    55296, 56320, 56576, 56577, 56579, 56560,     0,     1, 
+    49152, 57344, 55296, 56320, 56576, 56577, 56579, 56560, 
+    56568,     0,     1, 49152, 57344, 55296, 56320, 56576, 
+    56577, 56579, 56560, 56568,     0,     1, 49152, 57344, 
+    55296, 56320, 56576, 56577, 56579, 56560, 56568, 56570, 
+        0,     1, 49152, 57344, 55296, 56320, 56576, 56577, 
+    56579, 56583, 56568,     0,     1, 49152, 57344, 55296, 
+    56320, 56576, 56577, 56579, 56583, 56568, 56572,     0, 
+        1, 49152, 57344, 55296, 56320, 56576, 56577, 56579, 
+    56583, 56568, 56572,     0,     1, 49152, 57344, 55296, 
+    56320, 56576, 56577, 56579, 56583, 56568, 56572, 56574, 
+        0,     1, 49152, 57344, 55296, 56320,     0,     1, 
+    49152, 57344, 55296, 56320, 56576,     0,     1, 49152, 
+    57344, 57345, 56320, 56576,     0,     1, 49152, 57344, 
+    57345, 56320, 56576, 56578,     0,     1, 49152, 57344, 
+    57345, 56320, 56576,     0,     1, 49152, 57344, 57345, 
+    56320, 56576, 56580,     0,     1, 49152, 57344, 57345, 
+    56320, 56576, 56580,     0,     1, 49152, 57344, 57345, 
+    56320, 56576, 56584, 56582,     0,     1, 49152, 57344, 
+    57345, 56320, 56576,     0,     1, 49152, 57344, 57345, 
+    56320, 56576, 56584,     0,     1, 49152, 57344, 57345, 
+    56320, 56576, 56584,     0,     1, 49152, 57344, 57345, 
+    56320, 56576, 56584, 56586,     0,     1, 49152, 57344, 
+    57345, 56320, 56576, 56584,     0,     1, 49152, 57344, 
+    57345, 56320, 56576, 56592, 56588,     0,     1, 49152, 
+    57344, 57345, 56320, 56576, 56592, 56588,     0,     1, 
+    49152, 57344, 57345, 56320, 56576, 56592, 56593, 56590, 
+        0,     1, 49152, 57344, 57345, 56320, 56576,     0, 
+        1, 49152, 57344, 57345, 56320, 56576, 56592,     0, 
+        1, 49152, 57344, 57345, 56320, 56576, 56592,     0, 
+        1, 49152, 57344, 57345, 56320, 56576, 56592, 56594, 
+        0,     1, 49152, 57344, 57345, 56320, 56576, 56592, 
+        0,     1, 49152, 57344, 57345, 56320, 56576, 56592, 
+    56596,     0,     1, 49152, 57344, 57345, 56320, 56576, 
+    56592, 56596,     0,     1, 49152, 57344, 57345, 56320, 
+    56576, 56592, 56600, 56598,     0,     1, 49152, 57344, 
+    57345, 56320, 56576, 56592,     0,     1, 49152, 57344, 
+    57345, 56320, 56576, 56608, 56600,     0,     1, 49152, 
+    57344, 57345, 56320, 56576, 56608, 56600,     0,     1, 
+    49152, 57344, 57345, 56320, 56576, 56608, 56600, 56602, 
+        0,     1, 49152, 57344, 57345, 56320, 56576, 56608, 
+    56600,     0,     1, 49152, 57344, 57345, 56320, 56576, 
+    56608, 56609, 56604,     0,     1, 49152, 57344, 57345, 
+    56320, 56576, 56608, 56609, 56604,     0,     1, 49152, 
+    57344, 57345, 56320, 56576, 56608, 56609, 56604, 56606, 
+        0,     1, 49152, 57344, 57345, 56320, 56576,     0, 
+        1, 49152, 57344, 57345, 56320, 56576, 56608,     0, 
+        1, 49152, 57344, 57345, 56320, 56576, 56608,     0, 
+        1, 49152, 57344, 57345, 56320, 56576, 56608, 56610, 
+        0,     1, 49152, 57344, 57345, 56320, 56576, 56608, 
+        0,     1, 49152, 57344, 57345, 56320, 56576, 56608, 
+    56612,     0,     1, 49152, 57344, 57345, 56320, 56576, 
+    56608, 56612,     0,     1, 49152, 57344, 57345, 56320, 
+    56576, 56608, 56616, 56614,     0,     1, 49152, 57344, 
+    57345, 56320, 56576, 56608,     0,     1, 49152, 57344, 
+    57345, 56320, 56576, 56608, 56616,     0,     1, 49152, 
+    57344, 57345, 56320, 56576, 56608, 56616,     0,     1, 
+    49152, 57344, 57345, 56320, 56576, 56608, 56616, 56618, 
+        0,     1, 49152, 57344, 57345, 56320, 56576, 56608, 
+    56616,     0,     1, 49152, 57344, 57345, 56320, 56576, 
+    56608, 56624, 56620,     0,     1, 49152, 57344, 57345, 
+    56320, 56576, 56608, 56624, 56620,     0,     1, 49152, 
+    57344, 57345, 56320, 56576, 56608, 56624, 56625, 56622, 
+        0,     1, 49152, 57344, 57345, 56320, 56576, 56608, 
+        0,     1, 49152, 57344, 57345, 56320, 56576, 56640, 
+    56624,     0,     1, 49152, 57344, 57345, 56320, 56576, 
+    56640, 56624,     0,     1, 49152, 57344, 57345, 56320, 
+    56576, 56640, 56624, 56626,     0,     1, 49152, 57344, 
+    57345, 56320, 56576, 56640, 56624,     0,     1, 49152, 
+    57344, 57345, 56320, 56576, 56640, 56624, 56628,     0, 
+        1, 49152, 57344, 57345, 56320, 56576, 56640, 56624, 
+    56628,     0,     1, 49152, 57344, 57345, 56320, 56576, 
+    56640, 56624, 56632, 56630,     0,     1, 49152, 57344, 
+    57345, 56320, 56576, 56640, 56624,     0,     1, 49152, 
+    57344, 57345, 56320, 56576, 56640, 56641, 56632,     0, 
+        1, 49152, 57344, 57345, 56320, 56576, 56640, 56641, 
+    56632,     0,     1, 49152, 57344, 57345, 56320, 56576, 
+    56640, 56641, 56632, 56634,     0,     1, 49152, 57344, 
+    57345, 56320, 56576, 56640, 56641, 56632,     0,     1, 
+    49152, 57344, 57345, 56320, 56576, 56640, 56641, 56632, 
+    56636,     0,     1, 49152, 57344, 57345, 56320, 56576, 
+    56640, 56641, 56643, 56636,     0,     1, 49152, 57344, 
+    57345, 56320, 56576, 56640, 56641, 56643, 56636, 56638, 
+        0,     1, 49152, 57344, 57345, 56320, 56576,     0, 
+        1, 49152, 57344, 57345, 56320, 56576, 56640,     0, 
+        1, 49152, 57344, 57345, 56320, 56576, 56640,     0, 
+        1, 49152, 57344, 57345, 56320, 56576, 56640, 56642, 
+        0,     1, 49152, 57344, 57345, 56320, 56576, 56640, 
+        0,     1, 49152, 57344, 57345, 56320, 56576, 56640, 
+    56644,     0,     1, 49152, 57344, 57345, 56320, 56576, 
+    56640, 56644,     0,     1, 49152, 57344, 57345, 56320, 
+    56576, 56640, 56648, 56646,     0,     1, 49152, 57344, 
+    57345, 56320, 56576, 56640,     0,     1, 49152, 57344, 
+    57345, 56320, 56576, 56640, 56648,     0,     1, 49152, 
+    57344, 57345, 56320, 56576, 56640, 56648,     0,     1, 
+    49152, 57344, 57345, 56320, 56576, 56640, 56648, 56650, 
+        0,     1, 49152, 57344, 57345, 56320, 56576, 56640, 
+    56648,     0,     1, 49152, 57344, 57345, 56320, 56576, 
+    56640, 56656, 56652,     0,     1, 49152, 57344, 57345, 
+    56320, 56576, 56640, 56656, 56652,     0,     1, 49152, 
+    57344, 57345, 56320, 56576, 56640, 56656, 56657, 56654, 
+        0,     1, 49152, 57344, 57345, 56320, 56576, 56640, 
+        0,     1, 49152, 57344, 57345, 56320, 56576, 56640, 
+    56656,     0,     1, 49152, 57344, 57345, 56320, 56576, 
+    56640, 56656,     0,     1, 49152, 57344, 57345, 56320, 
+    56576, 56640, 56656, 56658,     0,     1, 49152, 57344, 
+    57345, 56320, 56576, 56640, 56656,     0,     1, 49152, 
+    57344, 57345, 56320, 56576, 56640, 56656, 56660,     0, 
+        1, 49152, 57344, 57345, 56320, 56576, 56640, 56656, 
+    56660,     0,     1, 49152, 57344, 57345, 56320, 56576, 
+    56640, 56656, 56664, 56662,     0,     1, 49152, 57344, 
+    57345, 56320, 56576, 56640, 56656,     0,     1, 49152, 
+    57344, 57345, 56320, 56576, 56640, 56672, 56664,     0, 
+        1, 49152, 57344, 57345, 56320, 56576, 56640, 56672, 
+    56664,     0,     1, 49152, 57344, 57345, 56320, 56576, 
+    56640, 56672, 56664, 56666,     0,     1, 49152, 57344, 
+    57345, 56320, 56576, 56640, 56672, 56664,     0,     1, 
+    49152, 57344, 57345, 56320, 56576, 56640, 56672, 56673, 
+    56668,     0,     1, 49152, 57344, 57345, 56320, 56576, 
+    56640, 56672, 56673, 56668,     0,     1, 49152, 57344, 
+    57345, 56320, 56576, 56640, 56672, 56673, 56668, 56670, 
+        0,     1, 49152, 57344, 57345, 56320, 56576, 56640, 
+        0,     1, 49152, 57344, 57345, 56320, 56576, 56704, 
+    56672,     0,     1, 49152, 57344, 57345, 56320, 56576, 
+    56704, 56672,     0,     1, 49152, 57344, 57345, 56320, 
+    56576, 56704, 56672, 56674,     0,     1, 49152, 57344, 
+    57345, 56320, 56576, 56704, 56672,     0,     1, 49152, 
+    57344, 57345, 56320, 56576, 56704, 56672, 56676,     0, 
+        1, 49152, 57344, 57345, 56320, 56576, 56704, 56672, 
+    56676,     0,     1, 49152, 57344, 57345, 56320, 56576, 
+    56704, 56672, 56680, 56678,     0,     1, 49152, 57344, 
+    57345, 56320, 56576, 56704, 56672,     0,     1, 49152, 
+    57344, 57345, 56320, 56576, 56704, 56672, 56680,     0, 
+        1, 49152, 57344, 57345, 56320, 56576, 56704, 56672, 
+    56680,     0,     1, 49152, 57344, 57345, 56320, 56576, 
+    56704, 56672, 56680, 56682,     0,     1, 49152, 57344, 
+    57345, 56320, 56576, 56704, 56672, 56680,     0,     1, 
+    49152, 57344, 57345, 56320, 56576, 56704, 56672, 56688, 
+    56684,     0,     1, 49152, 57344, 57345, 56320, 56576, 
+    56704, 56672, 56688, 56684,     0,     1, 49152, 57344, 
+    57345, 56320, 56576, 56704, 56672, 56688, 56689, 56686, 
+        0,     1, 49152, 57344, 57345, 56320, 56576, 56704, 
+    56672,     0,     1, 49152, 57344, 57345, 56320, 56576, 
+    56704, 56705, 56688,     0,     1, 49152, 57344, 57345, 
+    56320, 56576, 56704, 56705, 56688,     0,     1, 49152, 
+    57344, 57345, 56320, 56576, 56704, 56705, 56688, 56690, 
+        0,     1, 49152, 57344, 57345, 56320, 56576, 56704, 
+    56705, 56688,     0,     1, 49152, 57344, 57345, 56320, 
+    56576, 56704, 56705, 56688, 56692,     0,     1, 49152, 
+    57344, 57345, 56320, 56576, 56704, 56705, 56688, 56692, 
+        0,     1, 49152, 57344, 57345, 56320, 56576, 56704, 
+    56705, 56688, 56696, 56694,     0,     1, 49152, 57344, 
+    57345, 56320, 56576, 56704, 56705, 56688,     0,     1, 
+    49152, 57344, 57345, 56320, 56576, 56704, 56705, 56688, 
+    56696,     0,     1, 49152, 57344, 57345, 56320, 56576, 
+    56704, 56705, 56707, 56696,     0,     1, 49152, 57344, 
+    57345, 56320, 56576, 56704, 56705, 56707, 56696, 56698, 
+        0,     1, 49152, 57344, 57345, 56320, 56576, 56704, 
+    56705, 56707, 56696,     0,     1, 49152, 57344, 57345, 
+    56320, 56576, 56704, 56705, 56707, 56696, 56700,     0, 
+        1, 49152, 57344, 57345, 56320, 56576, 56704, 56705, 
+    56707, 56696, 56700,     0,     1, 49152, 57344, 57345, 
+    56320, 56576, 56704, 56705, 56707, 56696, 56700, 56702, 
+        0,     1, 49152, 57344, 57345, 56320, 56576,     0, 
+        1, 49152, 57344, 57345, 56320, 56832, 56704,     0, 
+        1, 49152, 57344, 57345, 56320, 56832, 56704,     0, 
+        1, 49152, 57344, 57345, 56320, 56832, 56704, 56706, 
+        0,     1, 49152, 57344, 57345, 56320, 56832, 56704, 
+        0,     1, 49152, 57344, 57345, 56320, 56832, 56704, 
+    56708,     0,     1, 49152, 57344, 57345, 56320, 56832, 
+    56704, 56708,     0,     1, 49152, 57344, 57345, 56320, 
+    56832, 56704, 56712, 56710,     0,     1, 49152, 57344, 
+    57345, 56320, 56832, 56704,     0,     1, 49152, 57344, 
+    57345, 56320, 56832, 56704, 56712,     0,     1, 49152, 
+    57344, 57345, 56320, 56832, 56704, 56712,     0,     1, 
+    49152, 57344, 57345, 56320, 56832, 56704, 56712, 56714, 
+        0,     1, 49152, 57344, 57345, 56320, 56832, 56704, 
+    56712,     0,     1, 49152, 57344, 57345, 56320, 56832, 
+    56704, 56720, 56716,     0,     1, 49152, 57344, 57345, 
+    56320, 56832, 56704, 56720, 56716,     0,     1, 49152, 
+    57344, 57345, 56320, 56832, 56704, 56720, 56721, 56718, 
+        0,     1, 49152, 57344, 57345, 56320, 56832, 56704, 
+        0,     1, 49152, 57344, 57345, 56320, 56832, 56704, 
+    56720,     0,     1, 49152, 57344, 57345, 56320, 56832, 
+    56704, 56720,     0,     1, 49152, 57344, 57345, 56320, 
+    56832, 56704, 56720, 56722,     0,     1, 49152, 57344, 
+    57345, 56320, 56832, 56704, 56720,     0,     1, 49152, 
+    57344, 57345, 56320, 56832, 56704, 56720, 56724,     0, 
+        1, 49152, 57344, 57345, 56320, 56832, 56704, 56720, 
+    56724,     0,     1, 49152, 57344, 57345, 56320, 56832, 
+    56704, 56720, 56728, 56726,     0,     1, 49152, 57344, 
+    57345, 56320, 56832, 56704, 56720,     0,     1, 49152, 
+    57344, 57345, 56320, 56832, 56704, 56736, 56728,     0, 
+        1, 49152, 57344, 57345, 56320, 56832, 56704, 56736, 
+    56728,     0,     1, 49152, 57344, 57345, 56320, 56832, 
+    56704, 56736, 56728, 56730,     0,     1, 49152, 57344, 
+    57345, 56320, 56832, 56704, 56736, 56728,     0,     1, 
+    49152, 57344, 57345, 56320, 56832, 56704, 56736, 56737, 
+    56732,     0,     1, 49152, 57344, 57345, 56320, 56832, 
+    56704, 56736, 56737, 56732,     0,     1, 49152, 57344, 
+    57345, 56320, 56832, 56704, 56736, 56737, 56732, 56734, 
+        0,     1, 49152, 57344, 57345, 56320, 56832, 56704, 
+        0,     1, 49152, 57344, 57345, 56320, 56832, 56704, 
+    56736,     0,     1, 49152, 57344, 57345, 56320, 56832, 
+    56704, 56736,     0,     1, 49152, 57344, 57345, 56320, 
+    56832, 56704, 56736, 56738,     0,     1, 49152, 57344, 
+    57345, 56320, 56832, 56704, 56736,     0,     1, 49152, 
+    57344, 57345, 56320, 56832, 56704, 56736, 56740,     0, 
+        1, 49152, 57344, 57345, 56320, 56832, 56704, 56736, 
+    56740,     0,     1, 49152, 57344, 57345, 56320, 56832, 
+    56704, 56736, 56744, 56742,     0,     1, 49152, 57344, 
+    57345, 56320, 56832, 56704, 56736,     0,     1, 49152, 
+    57344, 57345, 56320, 56832, 56704, 56736, 56744,     0, 
+        1, 49152, 57344, 57345, 56320, 56832, 56704, 56736, 
+    56744,     0,     1, 49152, 57344, 57345, 56320, 56832, 
+    56704, 56736, 56744, 56746,     0,     1, 49152, 57344, 
+    57345, 56320, 56832, 56704, 56736, 56744,     0,     1, 
+    49152, 57344, 57345, 56320, 56832, 56704, 56736, 56752, 
+    56748,     0,     1, 49152, 57344, 57345, 56320, 56832, 
+    56704, 56736, 56752, 56748,     0,     1, 49152, 57344, 
+    57345, 56320, 56832, 56704, 56736, 56752, 56753, 56750, 
+        0,     1, 49152, 57344, 57345, 56320, 56832, 56704, 
+    56736,     0,     1, 49152, 57344, 57345, 56320, 56832, 
+    56704, 56768, 56752,     0,     1, 49152, 57344, 57345, 
+    56320, 56832, 56704, 56768, 56752,     0,     1, 49152, 
+    57344, 57345, 56320, 56832, 56704, 56768, 56752, 56754, 
+        0,     1, 49152, 57344, 57345, 56320, 56832, 56704, 
+    56768, 56752,     0,     1, 49152, 57344, 57345, 56320, 
+    56832, 56704, 56768, 56752, 56756,     0,     1, 49152, 
+    57344, 57345, 56320, 56832, 56704, 56768, 56752, 56756, 
+        0,     1, 49152, 57344, 57345, 56320, 56832, 56704, 
+    56768, 56752, 56760, 56758,     0,     1, 49152, 57344, 
+    57345, 56320, 56832, 56704, 56768, 56752,     0,     1, 
+    49152, 57344, 57345, 56320, 56832, 56704, 56768, 56769, 
+    56760,     0,     1, 49152, 57344, 57345, 56320, 56832, 
+    56704, 56768, 56769, 56760,     0,     1, 49152, 57344, 
+    57345, 56320, 56832, 56704, 56768, 56769, 56760, 56762, 
+        0,     1, 49152, 57344, 57345, 56320, 56832, 56704, 
+    56768, 56769, 56760,     0,     1, 49152, 57344, 57345, 
+    56320, 56832, 56704, 56768, 56769, 56760, 56764,     0, 
+        1, 49152, 57344, 57345, 56320, 56832, 56704, 56768, 
+    56769, 56771, 56764,     0,     1, 49152, 57344, 57345, 
+    56320, 56832, 56704, 56768, 56769, 56771, 56764, 56766, 
+        0,     1, 49152, 57344, 57345, 56320, 56832, 56704, 
+        0,     1, 49152, 57344, 57345, 56320, 56832, 56833, 
+    56768,     0,     1, 49152, 57344, 57345, 56320, 56832, 
+    56833, 56768,     0,     1, 49152, 57344, 57345, 56320, 
+    56832, 56833, 56768, 56770,     0,     1, 49152, 57344, 
+    57345, 56320, 56832, 56833, 56768,     0,     1, 49152, 
+    57344, 57345, 56320, 56832, 56833, 56768, 56772,     0, 
+        1, 49152, 57344, 57345, 56320, 56832, 56833, 56768, 
+    56772,     0,     1, 49152, 57344, 57345, 56320, 56832, 
+    56833, 56768, 56776, 56774,     0,     1, 49152, 57344, 
+    57345, 56320, 56832, 56833, 56768,     0,     1, 49152, 
+    57344, 57345, 56320, 56832, 56833, 56768, 56776,     0, 
+        1, 49152, 57344, 57345, 56320, 56832, 56833, 56768, 
+    56776,     0,     1, 49152, 57344, 57345, 56320, 56832, 
+    56833, 56768, 56776, 56778,     0,     1, 49152, 57344, 
+    57345, 56320, 56832, 56833, 56768, 56776,     0,     1, 
+    49152, 57344, 57345, 56320, 56832, 56833, 56768, 56784, 
+    56780,     0,     1, 49152, 57344, 57345, 56320, 56832, 
+    56833, 56768, 56784, 56780,     0,     1, 49152, 57344, 
+    57345, 56320, 56832, 56833, 56768, 56784, 56785, 56782, 
+        0,     1, 49152, 57344, 57345, 56320, 56832, 56833, 
+    56768,     0,     1, 49152, 57344, 57345, 56320, 56832, 
+    56833, 56768, 56784,     0,     1, 49152, 57344, 57345, 
+    56320, 56832, 56833, 56768, 56784,     0,     1, 49152, 
+    57344, 57345, 56320, 56832, 56833, 56768, 56784, 56786, 
+        0,     1, 49152, 57344, 57345, 56320, 56832, 56833, 
+    56768, 56784,     0,     1, 49152, 57344, 57345, 56320, 
+    56832, 56833, 56768, 56784, 56788,     0,     1, 49152, 
+    57344, 57345, 56320, 56832, 56833, 56768, 56784, 56788, 
+        0,     1, 49152, 57344, 57345, 56320, 56832, 56833, 
+    56768, 56784, 56792, 56790,     0,     1, 49152, 57344, 
+    57345, 56320, 56832, 56833, 56768, 56784,     0,     1, 
+    49152, 57344, 57345, 56320, 56832, 56833, 56768, 56800, 
+    56792,     0,     1, 49152, 57344, 57345, 56320, 56832, 
+    56833, 56768, 56800, 56792,     0,     1, 49152, 57344, 
+    57345, 56320, 56832, 56833, 56768, 56800, 56792, 56794, 
+        0,     1, 49152, 57344, 57345, 56320, 56832, 56833, 
+    56768, 56800, 56792,     0,     1, 49152, 57344, 57345, 
+    56320, 56832, 56833, 56768, 56800, 56801, 56796,     0, 
+        1, 49152, 57344, 57345, 56320, 56832, 56833, 56768, 
+    56800, 56801, 56796,     0,     1, 49152, 57344, 57345, 
+    56320, 56832, 56833, 56768, 56800, 56801, 56796, 56798, 
+        0,     1, 49152, 57344, 57345, 56320, 56832, 56833, 
+    56768,     0,     1, 49152, 57344, 57345, 56320, 56832, 
+    56833, 56768, 56800,     0,     1, 49152, 57344, 57345, 
+    56320, 56832, 56833, 56835, 56800,     0,     1, 49152, 
+    57344, 57345, 56320, 56832, 56833, 56835, 56800, 56802, 
+        0,     1, 49152, 57344, 57345, 56320, 56832, 56833, 
+    56835, 56800,     0,     1, 49152, 57344, 57345, 56320, 
+    56832, 56833, 56835, 56800, 56804,     0,     1, 49152, 
+    57344, 57345, 56320, 56832, 56833, 56835, 56800, 56804, 
+        0,     1, 49152, 57344, 57345, 56320, 56832, 56833, 
+    56835, 56800, 56808, 56806,     0,     1, 49152, 57344, 
+    57345, 56320, 56832, 56833, 56835, 56800,     0,     1, 
+    49152, 57344, 57345, 56320, 56832, 56833, 56835, 56800, 
+    56808,     0,     1, 49152, 57344, 57345, 56320, 56832, 
+    56833, 56835, 56800, 56808,     0,     1, 49152, 57344, 
+    57345, 56320, 56832, 56833, 56835, 56800, 56808, 56810, 
+        0,     1, 49152, 57344, 57345, 56320, 56832, 56833, 
+    56835, 56800, 56808,     0,     1, 49152, 57344, 57345, 
+    56320, 56832, 56833, 56835, 56800, 56816, 56812,     0, 
+        1, 49152, 57344, 57345, 56320, 56832, 56833, 56835, 
+    56800, 56816, 56812,     0,     1, 49152, 57344, 57345, 
+    56320, 56832, 56833, 56835, 56800, 56816, 56817, 56814, 
+        0,     1, 49152, 57344, 57345, 56320, 56832, 56833, 
+    56835, 56800,     0,     1, 49152, 57344, 57345, 56320, 
+    56832, 56833, 56835, 56800, 56816,     0,     1, 49152, 
+    57344, 57345, 56320, 56832, 56833, 56835, 56800, 56816, 
+        0,     1, 49152, 57344, 57345, 56320, 56832, 56833, 
+    56835, 56800, 56816, 56818,     0,     1, 49152, 57344, 
+    57345, 56320, 56832, 56833, 56835, 56839, 56816,     0, 
+        1, 49152, 57344, 57345, 56320, 56832, 56833, 56835, 
+    56839, 56816, 56820,     0,     1, 49152, 57344, 57345, 
+    56320, 56832, 56833, 56835, 56839, 56816, 56820,     0, 
+        1, 49152, 57344, 57345, 56320, 56832, 56833, 56835, 
+    56839, 56816, 56824, 56822,     0,     1, 49152, 57344, 
+    57345, 56320, 56832, 56833, 56835, 56839, 56816,     0, 
+        1, 49152, 57344, 57345, 56320, 56832, 56833, 56835, 
+    56839, 56816, 56824,     0,     1, 49152, 57344, 57345, 
+    56320, 56832, 56833, 56835, 56839, 56816, 56824,     0, 
+        1, 49152, 57344, 57345, 56320, 56832, 56833, 56835, 
+    56839, 56816, 56824, 56826,     0,     1, 49152, 57344, 
+    57345, 56320, 56832, 56833, 56835, 56839, 56816, 56824, 
+        0,     1, 49152, 57344, 57345, 56320, 56832, 56833, 
+    56835, 56839, 56816, 56824, 56828,     0,     1, 49152, 
+    57344, 57345, 56320, 56832, 56833, 56835, 56839, 56816, 
+    56824, 56828,     0,     1, 49152, 57344, 57345, 56320, 
+    56832, 56833, 56835, 56839, 56816, 56824, 56828, 56830, 
+        0,     1, 49152, 57344, 57345, 56320,     0,     1, 
+    49152, 57344, 57345, 56320, 56832,     0,     1, 49152, 
+    57344, 57345, 56320, 56832,     0,     1, 49152, 57344, 
+    57345, 56320, 56832, 56834,     0,     1, 49152, 57344, 
+    57345, 57347, 56832,     0,     1, 49152, 57344, 57345, 
+    57347, 56832, 56836,     0,     1, 49152, 57344, 57345, 
+    57347, 56832, 56836,     0,     1, 49152, 57344, 57345, 
+    57347, 56832, 56840, 56838,     0,     1, 49152, 57344, 
+    57345, 57347, 56832,     0,     1, 49152, 57344, 57345, 
+    57347, 56832, 56840,     0,     1, 49152, 57344, 57345, 
+    57347, 56832, 56840,     0,     1, 49152, 57344, 57345, 
+    57347, 56832, 56840, 56842,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 56840,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 56848, 56844,     0,     1, 49152, 
+    57344, 57345, 57347, 56832, 56848, 56844,     0,     1, 
+    49152, 57344, 57345, 57347, 56832, 56848, 56849, 56846, 
+        0,     1, 49152, 57344, 57345, 57347, 56832,     0, 
+        1, 49152, 57344, 57345, 57347, 56832, 56848,     0, 
+        1, 49152, 57344, 57345, 57347, 56832, 56848,     0, 
+        1, 49152, 57344, 57345, 57347, 56832, 56848, 56850, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 56848, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 56848, 
+    56852,     0,     1, 49152, 57344, 57345, 57347, 56832, 
+    56848, 56852,     0,     1, 49152, 57344, 57345, 57347, 
+    56832, 56848, 56856, 56854,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 56848,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 56864, 56856,     0,     1, 49152, 
+    57344, 57345, 57347, 56832, 56864, 56856,     0,     1, 
+    49152, 57344, 57345, 57347, 56832, 56864, 56856, 56858, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 56864, 
+    56856,     0,     1, 49152, 57344, 57345, 57347, 56832, 
+    56864, 56865, 56860,     0,     1, 49152, 57344, 57345, 
+    57347, 56832, 56864, 56865, 56860,     0,     1, 49152, 
+    57344, 57345, 57347, 56832, 56864, 56865, 56860, 56862, 
+        0,     1, 49152, 57344, 57345, 57347, 56832,     0, 
+        1, 49152, 57344, 57345, 57347, 56832, 56864,     0, 
+        1, 49152, 57344, 57345, 57347, 56832, 56864,     0, 
+        1, 49152, 57344, 57345, 57347, 56832, 56864, 56866, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 56864, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 56864, 
+    56868,     0,     1, 49152, 57344, 57345, 57347, 56832, 
+    56864, 56868,     0,     1, 49152, 57344, 57345, 57347, 
+    56832, 56864, 56872, 56870,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 56864,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 56864, 56872,     0,     1, 49152, 
+    57344, 57345, 57347, 56832, 56864, 56872,     0,     1, 
+    49152, 57344, 57345, 57347, 56832, 56864, 56872, 56874, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 56864, 
+    56872,     0,     1, 49152, 57344, 57345, 57347, 56832, 
+    56864, 56880, 56876,     0,     1, 49152, 57344, 57345, 
+    57347, 56832, 56864, 56880, 56876,     0,     1, 49152, 
+    57344, 57345, 57347, 56832, 56864, 56880, 56881, 56878, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 56864, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 56896, 
+    56880,     0,     1, 49152, 57344, 57345, 57347, 56832, 
+    56896, 56880,     0,     1, 49152, 57344, 57345, 57347, 
+    56832, 56896, 56880, 56882,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 56896, 56880,     0,     1, 49152, 
+    57344, 57345, 57347, 56832, 56896, 56880, 56884,     0, 
+        1, 49152, 57344, 57345, 57347, 56832, 56896, 56880, 
+    56884,     0,     1, 49152, 57344, 57345, 57347, 56832, 
+    56896, 56880, 56888, 56886,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 56896, 56880,     0,     1, 49152, 
+    57344, 57345, 57347, 56832, 56896, 56897, 56888,     0, 
+        1, 49152, 57344, 57345, 57347, 56832, 56896, 56897, 
+    56888,     0,     1, 49152, 57344, 57345, 57347, 56832, 
+    56896, 56897, 56888, 56890,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 56896, 56897, 56888,     0,     1, 
+    49152, 57344, 57345, 57347, 56832, 56896, 56897, 56888, 
+    56892,     0,     1, 49152, 57344, 57345, 57347, 56832, 
+    56896, 56897, 56899, 56892,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 56896, 56897, 56899, 56892, 56894, 
+        0,     1, 49152, 57344, 57345, 57347, 56832,     0, 
+        1, 49152, 57344, 57345, 57347, 56832, 56896,     0, 
+        1, 49152, 57344, 57345, 57347, 56832, 56896,     0, 
+        1, 49152, 57344, 57345, 57347, 56832, 56896, 56898, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 56896, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 56896, 
+    56900,     0,     1, 49152, 57344, 57345, 57347, 56832, 
+    56896, 56900,     0,     1, 49152, 57344, 57345, 57347, 
+    56832, 56896, 56904, 56902,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 56896,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 56896, 56904,     0,     1, 49152, 
+    57344, 57345, 57347, 56832, 56896, 56904,     0,     1, 
+    49152, 57344, 57345, 57347, 56832, 56896, 56904, 56906, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 56896, 
+    56904,     0,     1, 49152, 57344, 57345, 57347, 56832, 
+    56896, 56912, 56908,     0,     1, 49152, 57344, 57345, 
+    57347, 56832, 56896, 56912, 56908,     0,     1, 49152, 
+    57344, 57345, 57347, 56832, 56896, 56912, 56913, 56910, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 56896, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 56896, 
+    56912,     0,     1, 49152, 57344, 57345, 57347, 56832, 
+    56896, 56912,     0,     1, 49152, 57344, 57345, 57347, 
+    56832, 56896, 56912, 56914,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 56896, 56912,     0,     1, 49152, 
+    57344, 57345, 57347, 56832, 56896, 56912, 56916,     0, 
+        1, 49152, 57344, 57345, 57347, 56832, 56896, 56912, 
+    56916,     0,     1, 49152, 57344, 57345, 57347, 56832, 
+    56896, 56912, 56920, 56918,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 56896, 56912,     0,     1, 49152, 
+    57344, 57345, 57347, 56832, 56896, 56928, 56920,     0, 
+        1, 49152, 57344, 57345, 57347, 56832, 56896, 56928, 
+    56920,     0,     1, 49152, 57344, 57345, 57347, 56832, 
+    56896, 56928, 56920, 56922,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 56896, 56928, 56920,     0,     1, 
+    49152, 57344, 57345, 57347, 56832, 56896, 56928, 56929, 
+    56924,     0,     1, 49152, 57344, 57345, 57347, 56832, 
+    56896, 56928, 56929, 56924,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 56896, 56928, 56929, 56924, 56926, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 56896, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 56960, 
+    56928,     0,     1, 49152, 57344, 57345, 57347, 56832, 
+    56960, 56928,     0,     1, 49152, 57344, 57345, 57347, 
+    56832, 56960, 56928, 56930,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 56960, 56928,     0,     1, 49152, 
+    57344, 57345, 57347, 56832, 56960, 56928, 56932,     0, 
+        1, 49152, 57344, 57345, 57347, 56832, 56960, 56928, 
+    56932,     0,     1, 49152, 57344, 57345, 57347, 56832, 
+    56960, 56928, 56936, 56934,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 56960, 56928,     0,     1, 49152, 
+    57344, 57345, 57347, 56832, 56960, 56928, 56936,     0, 
+        1, 49152, 57344, 57345, 57347, 56832, 56960, 56928, 
+    56936,     0,     1, 49152, 57344, 57345, 57347, 56832, 
+    56960, 56928, 56936, 56938,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 56960, 56928, 56936,     0,     1, 
+    49152, 57344, 57345, 57347, 56832, 56960, 56928, 56944, 
+    56940,     0,     1, 49152, 57344, 57345, 57347, 56832, 
+    56960, 56928, 56944, 56940,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 56960, 56928, 56944, 56945, 56942, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 56960, 
+    56928,     0,     1, 49152, 57344, 57345, 57347, 56832, 
+    56960, 56961, 56944,     0,     1, 49152, 57344, 57345, 
+    57347, 56832, 56960, 56961, 56944,     0,     1, 49152, 
+    57344, 57345, 57347, 56832, 56960, 56961, 56944, 56946, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 56960, 
+    56961, 56944,     0,     1, 49152, 57344, 57345, 57347, 
+    56832, 56960, 56961, 56944, 56948,     0,     1, 49152, 
+    57344, 57345, 57347, 56832, 56960, 56961, 56944, 56948, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 56960, 
+    56961, 56944, 56952, 56950,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 56960, 56961, 56944,     0,     1, 
+    49152, 57344, 57345, 57347, 56832, 56960, 56961, 56944, 
+    56952,     0,     1, 49152, 57344, 57345, 57347, 56832, 
+    56960, 56961, 56963, 56952,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 56960, 56961, 56963, 56952, 56954, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 56960, 
+    56961, 56963, 56952,     0,     1, 49152, 57344, 57345, 
+    57347, 56832, 56960, 56961, 56963, 56952, 56956,     0, 
+        1, 49152, 57344, 57345, 57347, 56832, 56960, 56961, 
+    56963, 56952, 56956,     0,     1, 49152, 57344, 57345, 
+    57347, 56832, 56960, 56961, 56963, 56952, 56956, 56958, 
+        0,     1, 49152, 57344, 57345, 57347, 56832,     0, 
+        1, 49152, 57344, 57345, 57347, 56832, 56960,     0, 
+        1, 49152, 57344, 57345, 57347, 56832, 56960,     0, 
+        1, 49152, 57344, 57345, 57347, 56832, 56960, 56962, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 56960, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 56960, 
+    56964,     0,     1, 49152, 57344, 57345, 57347, 56832, 
+    56960, 56964,     0,     1, 49152, 57344, 57345, 57347, 
+    56832, 56960, 56968, 56966,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 56960,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 56960, 56968,     0,     1, 49152, 
+    57344, 57345, 57347, 56832, 56960, 56968,     0,     1, 
+    49152, 57344, 57345, 57347, 56832, 56960, 56968, 56970, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 56960, 
+    56968,     0,     1, 49152, 57344, 57345, 57347, 56832, 
+    56960, 56976, 56972,     0,     1, 49152, 57344, 57345, 
+    57347, 56832, 56960, 56976, 56972,     0,     1, 49152, 
+    57344, 57345, 57347, 56832, 56960, 56976, 56977, 56974, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 56960, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 56960, 
+    56976,     0,     1, 49152, 57344, 57345, 57347, 56832, 
+    56960, 56976,     0,     1, 49152, 57344, 57345, 57347, 
+    56832, 56960, 56976, 56978,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 56960, 56976,     0,     1, 49152, 
+    57344, 57345, 57347, 56832, 56960, 56976, 56980,     0, 
+        1, 49152, 57344, 57345, 57347, 56832, 56960, 56976, 
+    56980,     0,     1, 49152, 57344, 57345, 57347, 56832, 
+    56960, 56976, 56984, 56982,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 56960, 56976,     0,     1, 49152, 
+    57344, 57345, 57347, 56832, 56960, 56992, 56984,     0, 
+        1, 49152, 57344, 57345, 57347, 56832, 56960, 56992, 
+    56984,     0,     1, 49152, 57344, 57345, 57347, 56832, 
+    56960, 56992, 56984, 56986,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 56960, 56992, 56984,     0,     1, 
+    49152, 57344, 57345, 57347, 56832, 56960, 56992, 56993, 
+    56988,     0,     1, 49152, 57344, 57345, 57347, 56832, 
+    56960, 56992, 56993, 56988,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 56960, 56992, 56993, 56988, 56990, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 56960, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 56960, 
+    56992,     0,     1, 49152, 57344, 57345, 57347, 56832, 
+    56960, 56992,     0,     1, 49152, 57344, 57345, 57347, 
+    56832, 56960, 56992, 56994,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 56960, 56992,     0,     1, 49152, 
+    57344, 57345, 57347, 56832, 56960, 56992, 56996,     0, 
+        1, 49152, 57344, 57345, 57347, 56832, 56960, 56992, 
+    56996,     0,     1, 49152, 57344, 57345, 57347, 56832, 
+    56960, 56992, 57000, 56998,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 56960, 56992,     0,     1, 49152, 
+    57344, 57345, 57347, 56832, 56960, 56992, 57000,     0, 
+        1, 49152, 57344, 57345, 57347, 56832, 56960, 56992, 
+    57000,     0,     1, 49152, 57344, 57345, 57347, 56832, 
+    56960, 56992, 57000, 57002,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 56960, 56992, 57000,     0,     1, 
+    49152, 57344, 57345, 57347, 56832, 56960, 56992, 57008, 
+    57004,     0,     1, 49152, 57344, 57345, 57347, 56832, 
+    56960, 56992, 57008, 57004,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 56960, 56992, 57008, 57009, 57006, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 56960, 
+    56992,     0,     1, 49152, 57344, 57345, 57347, 56832, 
+    56960, 57024, 57008,     0,     1, 49152, 57344, 57345, 
+    57347, 56832, 56960, 57024, 57008,     0,     1, 49152, 
+    57344, 57345, 57347, 56832, 56960, 57024, 57008, 57010, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 56960, 
+    57024, 57008,     0,     1, 49152, 57344, 57345, 57347, 
+    56832, 56960, 57024, 57008, 57012,     0,     1, 49152, 
+    57344, 57345, 57347, 56832, 56960, 57024, 57008, 57012, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 56960, 
+    57024, 57008, 57016, 57014,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 56960, 57024, 57008,     0,     1, 
+    49152, 57344, 57345, 57347, 56832, 56960, 57024, 57025, 
+    57016,     0,     1, 49152, 57344, 57345, 57347, 56832, 
+    56960, 57024, 57025, 57016,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 56960, 57024, 57025, 57016, 57018, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 56960, 
+    57024, 57025, 57016,     0,     1, 49152, 57344, 57345, 
+    57347, 56832, 56960, 57024, 57025, 57016, 57020,     0, 
+        1, 49152, 57344, 57345, 57347, 56832, 56960, 57024, 
+    57025, 57027, 57020,     0,     1, 49152, 57344, 57345, 
+    57347, 56832, 56960, 57024, 57025, 57027, 57020, 57022, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 56960, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 57088, 
+    57024,     0,     1, 49152, 57344, 57345, 57347, 56832, 
+    57088, 57024,     0,     1, 49152, 57344, 57345, 57347, 
+    56832, 57088, 57024, 57026,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 57088, 57024,     0,     1, 49152, 
+    57344, 57345, 57347, 56832, 57088, 57024, 57028,     0, 
+        1, 49152, 57344, 57345, 57347, 56832, 57088, 57024, 
+    57028,     0,     1, 49152, 57344, 57345, 57347, 56832, 
+    57088, 57024, 57032, 57030,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 57088, 57024,     0,     1, 49152, 
+    57344, 57345, 57347, 56832, 57088, 57024, 57032,     0, 
+        1, 49152, 57344, 57345, 57347, 56832, 57088, 57024, 
+    57032,     0,     1, 49152, 57344, 57345, 57347, 56832, 
+    57088, 57024, 57032, 57034,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 57088, 57024, 57032,     0,     1, 
+    49152, 57344, 57345, 57347, 56832, 57088, 57024, 57040, 
+    57036,     0,     1, 49152, 57344, 57345, 57347, 56832, 
+    57088, 57024, 57040, 57036,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 57088, 57024, 57040, 57041, 57038, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 57088, 
+    57024,     0,     1, 49152, 57344, 57345, 57347, 56832, 
+    57088, 57024, 57040,     0,     1, 49152, 57344, 57345, 
+    57347, 56832, 57088, 57024, 57040,     0,     1, 49152, 
+    57344, 57345, 57347, 56832, 57088, 57024, 57040, 57042, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 57088, 
+    57024, 57040,     0,     1, 49152, 57344, 57345, 57347, 
+    56832, 57088, 57024, 57040, 57044,     0,     1, 49152, 
+    57344, 57345, 57347, 56832, 57088, 57024, 57040, 57044, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 57088, 
+    57024, 57040, 57048, 57046,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 57088, 57024, 57040,     0,     1, 
+    49152, 57344, 57345, 57347, 56832, 57088, 57024, 57056, 
+    57048,     0,     1, 49152, 57344, 57345, 57347, 56832, 
+    57088, 57024, 57056, 57048,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 57088, 57024, 57056, 57048, 57050, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 57088, 
+    57024, 57056, 57048,     0,     1, 49152, 57344, 57345, 
+    57347, 56832, 57088, 57024, 57056, 57057, 57052,     0, 
+        1, 49152, 57344, 57345, 57347, 56832, 57088, 57024, 
+    57056, 57057, 57052,     0,     1, 49152, 57344, 57345, 
+    57347, 56832, 57088, 57024, 57056, 57057, 57052, 57054, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 57088, 
+    57024,     0,     1, 49152, 57344, 57345, 57347, 56832, 
+    57088, 57089, 57056,     0,     1, 49152, 57344, 57345, 
+    57347, 56832, 57088, 57089, 57056,     0,     1, 49152, 
+    57344, 57345, 57347, 56832, 57088, 57089, 57056, 57058, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 57088, 
+    57089, 57056,     0,     1, 49152, 57344, 57345, 57347, 
+    56832, 57088, 57089, 57056, 57060,     0,     1, 49152, 
+    57344, 57345, 57347, 56832, 57088, 57089, 57056, 57060, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 57088, 
+    57089, 57056, 57064, 57062,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 57088, 57089, 57056,     0,     1, 
+    49152, 57344, 57345, 57347, 56832, 57088, 57089, 57056, 
+    57064,     0,     1, 49152, 57344, 57345, 57347, 56832, 
+    57088, 57089, 57056, 57064,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 57088, 57089, 57056, 57064, 57066, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 57088, 
+    57089, 57056, 57064,     0,     1, 49152, 57344, 57345, 
+    57347, 56832, 57088, 57089, 57056, 57072, 57068,     0, 
+        1, 49152, 57344, 57345, 57347, 56832, 57088, 57089, 
+    57056, 57072, 57068,     0,     1, 49152, 57344, 57345, 
+    57347, 56832, 57088, 57089, 57056, 57072, 57073, 57070, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 57088, 
+    57089, 57056,     0,     1, 49152, 57344, 57345, 57347, 
+    56832, 57088, 57089, 57056, 57072,     0,     1, 49152, 
+    57344, 57345, 57347, 56832, 57088, 57089, 57091, 57072, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 57088, 
+    57089, 57091, 57072, 57074,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 57088, 57089, 57091, 57072,     0, 
+        1, 49152, 57344, 57345, 57347, 56832, 57088, 57089, 
+    57091, 57072, 57076,     0,     1, 49152, 57344, 57345, 
+    57347, 56832, 57088, 57089, 57091, 57072, 57076,     0, 
+        1, 49152, 57344, 57345, 57347, 56832, 57088, 57089, 
+    57091, 57072, 57080, 57078,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 57088, 57089, 57091, 57072,     0, 
+        1, 49152, 57344, 57345, 57347, 56832, 57088, 57089, 
+    57091, 57072, 57080,     0,     1, 49152, 57344, 57345, 
+    57347, 56832, 57088, 57089, 57091, 57072, 57080,     0, 
+        1, 49152, 57344, 57345, 57347, 56832, 57088, 57089, 
+    57091, 57072, 57080, 57082,     0,     1, 49152, 57344, 
+    57345, 57347, 56832, 57088, 57089, 57091, 57095, 57080, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 57088, 
+    57089, 57091, 57095, 57080, 57084,     0,     1, 49152, 
+    57344, 57345, 57347, 56832, 57088, 57089, 57091, 57095, 
+    57080, 57084,     0,     1, 49152, 57344, 57345, 57347, 
+    56832, 57088, 57089, 57091, 57095, 57080, 57084, 57086, 
+        0,     1, 49152, 57344, 57345, 57347, 56832,     0, 
+        1, 49152, 57344, 57345, 57347, 56832, 57088,     0, 
+        1, 49152, 57344, 57345, 57347, 56832, 57088,     0, 
+        1, 49152, 57344, 57345, 57347, 56832, 57088, 57090, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 57088, 
+        0,     1, 49152, 57344, 57345, 57347, 56832, 57088, 
+    57092,     0,     1, 49152, 57344, 57345, 57347, 56832, 
+    57088, 57092,     0,     1, 49152, 57344, 57345, 57347, 
+    56832, 57088, 57096, 57094,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57088,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57088, 57096,     0,     1, 49152, 
+    57344, 57345, 57347, 57351, 57088, 57096,     0,     1, 
+    49152, 57344, 57345, 57347, 57351, 57088, 57096, 57098, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57088, 
+    57096,     0,     1, 49152, 57344, 57345, 57347, 57351, 
+    57088, 57104, 57100,     0,     1, 49152, 57344, 57345, 
+    57347, 57351, 57088, 57104, 57100,     0,     1, 49152, 
+    57344, 57345, 57347, 57351, 57088, 57104, 57105, 57102, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57088, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57088, 
+    57104,     0,     1, 49152, 57344, 57345, 57347, 57351, 
+    57088, 57104,     0,     1, 49152, 57344, 57345, 57347, 
+    57351, 57088, 57104, 57106,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57088, 57104,     0,     1, 49152, 
+    57344, 57345, 57347, 57351, 57088, 57104, 57108,     0, 
+        1, 49152, 57344, 57345, 57347, 57351, 57088, 57104, 
+    57108,     0,     1, 49152, 57344, 57345, 57347, 57351, 
+    57088, 57104, 57112, 57110,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57088, 57104,     0,     1, 49152, 
+    57344, 57345, 57347, 57351, 57088, 57120, 57112,     0, 
+        1, 49152, 57344, 57345, 57347, 57351, 57088, 57120, 
+    57112,     0,     1, 49152, 57344, 57345, 57347, 57351, 
+    57088, 57120, 57112, 57114,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57088, 57120, 57112,     0,     1, 
+    49152, 57344, 57345, 57347, 57351, 57088, 57120, 57121, 
+    57116,     0,     1, 49152, 57344, 57345, 57347, 57351, 
+    57088, 57120, 57121, 57116,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57088, 57120, 57121, 57116, 57118, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57088, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57088, 
+    57120,     0,     1, 49152, 57344, 57345, 57347, 57351, 
+    57088, 57120,     0,     1, 49152, 57344, 57345, 57347, 
+    57351, 57088, 57120, 57122,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57088, 57120,     0,     1, 49152, 
+    57344, 57345, 57347, 57351, 57088, 57120, 57124,     0, 
+        1, 49152, 57344, 57345, 57347, 57351, 57088, 57120, 
+    57124,     0,     1, 49152, 57344, 57345, 57347, 57351, 
+    57088, 57120, 57128, 57126,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57088, 57120,     0,     1, 49152, 
+    57344, 57345, 57347, 57351, 57088, 57120, 57128,     0, 
+        1, 49152, 57344, 57345, 57347, 57351, 57088, 57120, 
+    57128,     0,     1, 49152, 57344, 57345, 57347, 57351, 
+    57088, 57120, 57128, 57130,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57088, 57120, 57128,     0,     1, 
+    49152, 57344, 57345, 57347, 57351, 57088, 57120, 57136, 
+    57132,     0,     1, 49152, 57344, 57345, 57347, 57351, 
+    57088, 57120, 57136, 57132,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57088, 57120, 57136, 57137, 57134, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57088, 
+    57120,     0,     1, 49152, 57344, 57345, 57347, 57351, 
+    57088, 57152, 57136,     0,     1, 49152, 57344, 57345, 
+    57347, 57351, 57088, 57152, 57136,     0,     1, 49152, 
+    57344, 57345, 57347, 57351, 57088, 57152, 57136, 57138, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57088, 
+    57152, 57136,     0,     1, 49152, 57344, 57345, 57347, 
+    57351, 57088, 57152, 57136, 57140,     0,     1, 49152, 
+    57344, 57345, 57347, 57351, 57088, 57152, 57136, 57140, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57088, 
+    57152, 57136, 57144, 57142,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57088, 57152, 57136,     0,     1, 
+    49152, 57344, 57345, 57347, 57351, 57088, 57152, 57153, 
+    57144,     0,     1, 49152, 57344, 57345, 57347, 57351, 
+    57088, 57152, 57153, 57144,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57088, 57152, 57153, 57144, 57146, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57088, 
+    57152, 57153, 57144,     0,     1, 49152, 57344, 57345, 
+    57347, 57351, 57088, 57152, 57153, 57144, 57148,     0, 
+        1, 49152, 57344, 57345, 57347, 57351, 57088, 57152, 
+    57153, 57155, 57148,     0,     1, 49152, 57344, 57345, 
+    57347, 57351, 57088, 57152, 57153, 57155, 57148, 57150, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57088, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57088, 
+    57152,     0,     1, 49152, 57344, 57345, 57347, 57351, 
+    57088, 57152,     0,     1, 49152, 57344, 57345, 57347, 
+    57351, 57088, 57152, 57154,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57088, 57152,     0,     1, 49152, 
+    57344, 57345, 57347, 57351, 57088, 57152, 57156,     0, 
+        1, 49152, 57344, 57345, 57347, 57351, 57088, 57152, 
+    57156,     0,     1, 49152, 57344, 57345, 57347, 57351, 
+    57088, 57152, 57160, 57158,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57088, 57152,     0,     1, 49152, 
+    57344, 57345, 57347, 57351, 57088, 57152, 57160,     0, 
+        1, 49152, 57344, 57345, 57347, 57351, 57088, 57152, 
+    57160,     0,     1, 49152, 57344, 57345, 57347, 57351, 
+    57088, 57152, 57160, 57162,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57088, 57152, 57160,     0,     1, 
+    49152, 57344, 57345, 57347, 57351, 57088, 57152, 57168, 
+    57164,     0,     1, 49152, 57344, 57345, 57347, 57351, 
+    57088, 57152, 57168, 57164,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57088, 57152, 57168, 57169, 57166, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57088, 
+    57152,     0,     1, 49152, 57344, 57345, 57347, 57351, 
+    57088, 57152, 57168,     0,     1, 49152, 57344, 57345, 
+    57347, 57351, 57088, 57152, 57168,     0,     1, 49152, 
+    57344, 57345, 57347, 57351, 57088, 57152, 57168, 57170, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57088, 
+    57152, 57168,     0,     1, 49152, 57344, 57345, 57347, 
+    57351, 57088, 57152, 57168, 57172,     0,     1, 49152, 
+    57344, 57345, 57347, 57351, 57088, 57152, 57168, 57172, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57088, 
+    57152, 57168, 57176, 57174,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57088, 57152, 57168,     0,     1, 
+    49152, 57344, 57345, 57347, 57351, 57088, 57152, 57184, 
+    57176,     0,     1, 49152, 57344, 57345, 57347, 57351, 
+    57088, 57152, 57184, 57176,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57088, 57152, 57184, 57176, 57178, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57088, 
+    57152, 57184, 57176,     0,     1, 49152, 57344, 57345, 
+    57347, 57351, 57088, 57152, 57184, 57185, 57180,     0, 
+        1, 49152, 57344, 57345, 57347, 57351, 57088, 57152, 
+    57184, 57185, 57180,     0,     1, 49152, 57344, 57345, 
+    57347, 57351, 57088, 57152, 57184, 57185, 57180, 57182, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57088, 
+    57152,     0,     1, 49152, 57344, 57345, 57347, 57351, 
+    57088, 57216, 57184,     0,     1, 49152, 57344, 57345, 
+    57347, 57351, 57088, 57216, 57184,     0,     1, 49152, 
+    57344, 57345, 57347, 57351, 57088, 57216, 57184, 57186, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57088, 
+    57216, 57184,     0,     1, 49152, 57344, 57345, 57347, 
+    57351, 57088, 57216, 57184, 57188,     0,     1, 49152, 
+    57344, 57345, 57347, 57351, 57088, 57216, 57184, 57188, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57088, 
+    57216, 57184, 57192, 57190,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57088, 57216, 57184,     0,     1, 
+    49152, 57344, 57345, 57347, 57351, 57088, 57216, 57184, 
+    57192,     0,     1, 49152, 57344, 57345, 57347, 57351, 
+    57088, 57216, 57184, 57192,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57088, 57216, 57184, 57192, 57194, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57088, 
+    57216, 57184, 57192,     0,     1, 49152, 57344, 57345, 
+    57347, 57351, 57088, 57216, 57184, 57200, 57196,     0, 
+        1, 49152, 57344, 57345, 57347, 57351, 57088, 57216, 
+    57184, 57200, 57196,     0,     1, 49152, 57344, 57345, 
+    57347, 57351, 57088, 57216, 57184, 57200, 57201, 57198, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57088, 
+    57216, 57184,     0,     1, 49152, 57344, 57345, 57347, 
+    57351, 57088, 57216, 57217, 57200,     0,     1, 49152, 
+    57344, 57345, 57347, 57351, 57088, 57216, 57217, 57200, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57088, 
+    57216, 57217, 57200, 57202,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57088, 57216, 57217, 57200,     0, 
+        1, 49152, 57344, 57345, 57347, 57351, 57088, 57216, 
+    57217, 57200, 57204,     0,     1, 49152, 57344, 57345, 
+    57347, 57351, 57088, 57216, 57217, 57200, 57204,     0, 
+        1, 49152, 57344, 57345, 57347, 57351, 57088, 57216, 
+    57217, 57200, 57208, 57206,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57088, 57216, 57217, 57200,     0, 
+        1, 49152, 57344, 57345, 57347, 57351, 57088, 57216, 
+    57217, 57200, 57208,     0,     1, 49152, 57344, 57345, 
+    57347, 57351, 57088, 57216, 57217, 57219, 57208,     0, 
+        1, 49152, 57344, 57345, 57347, 57351, 57088, 57216, 
+    57217, 57219, 57208, 57210,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57088, 57216, 57217, 57219, 57208, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57088, 
+    57216, 57217, 57219, 57208, 57212,     0,     1, 49152, 
+    57344, 57345, 57347, 57351, 57088, 57216, 57217, 57219, 
+    57208, 57212,     0,     1, 49152, 57344, 57345, 57347, 
+    57351, 57088, 57216, 57217, 57219, 57208, 57212, 57214, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57088, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57088, 
+    57216,     0,     1, 49152, 57344, 57345, 57347, 57351, 
+    57088, 57216,     0,     1, 49152, 57344, 57345, 57347, 
+    57351, 57088, 57216, 57218,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57088, 57216,     0,     1, 49152, 
+    57344, 57345, 57347, 57351, 57088, 57216, 57220,     0, 
+        1, 49152, 57344, 57345, 57347, 57351, 57088, 57216, 
+    57220,     0,     1, 49152, 57344, 57345, 57347, 57351, 
+    57088, 57216, 57224, 57222,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57088, 57216,     0,     1, 49152, 
+    57344, 57345, 57347, 57351, 57088, 57216, 57224,     0, 
+        1, 49152, 57344, 57345, 57347, 57351, 57088, 57216, 
+    57224,     0,     1, 49152, 57344, 57345, 57347, 57351, 
+    57088, 57216, 57224, 57226,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57088, 57216, 57224,     0,     1, 
+    49152, 57344, 57345, 57347, 57351, 57088, 57216, 57232, 
+    57228,     0,     1, 49152, 57344, 57345, 57347, 57351, 
+    57088, 57216, 57232, 57228,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57088, 57216, 57232, 57233, 57230, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57359, 
+    57216,     0,     1, 49152, 57344, 57345, 57347, 57351, 
+    57359, 57216, 57232,     0,     1, 49152, 57344, 57345, 
+    57347, 57351, 57359, 57216, 57232,     0,     1, 49152, 
+    57344, 57345, 57347, 57351, 57359, 57216, 57232, 57234, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57359, 
+    57216, 57232,     0,     1, 49152, 57344, 57345, 57347, 
+    57351, 57359, 57216, 57232, 57236,     0,     1, 49152, 
+    57344, 57345, 57347, 57351, 57359, 57216, 57232, 57236, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57359, 
+    57216, 57232, 57240, 57238,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57359, 57216, 57232,     0,     1, 
+    49152, 57344, 57345, 57347, 57351, 57359, 57216, 57248, 
+    57240,     0,     1, 49152, 57344, 57345, 57347, 57351, 
+    57359, 57216, 57248, 57240,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57359, 57216, 57248, 57240, 57242, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57359, 
+    57216, 57248, 57240,     0,     1, 49152, 57344, 57345, 
+    57347, 57351, 57359, 57216, 57248, 57249, 57244,     0, 
+        1, 49152, 57344, 57345, 57347, 57351, 57359, 57216, 
+    57248, 57249, 57244,     0,     1, 49152, 57344, 57345, 
+    57347, 57351, 57359, 57216, 57248, 57249, 57244, 57246, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57359, 
+    57216,     0,     1, 49152, 57344, 57345, 57347, 57351, 
+    57359, 57216, 57248,     0,     1, 49152, 57344, 57345, 
+    57347, 57351, 57359, 57216, 57248,     0,     1, 49152, 
+    57344, 57345, 57347, 57351, 57359, 57216, 57248, 57250, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57359, 
+    57216, 57248,     0,     1, 49152, 57344, 57345, 57347, 
+    57351, 57359, 57216, 57248, 57252,     0,     1, 49152, 
+    57344, 57345, 57347, 57351, 57359, 57216, 57248, 57252, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57359, 
+    57216, 57248, 57256, 57254,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57359, 57216, 57248,     0,     1, 
+    49152, 57344, 57345, 57347, 57351, 57359, 57216, 57248, 
+    57256,     0,     1, 49152, 57344, 57345, 57347, 57351, 
+    57359, 57216, 57248, 57256,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57359, 57216, 57248, 57256, 57258, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57359, 
+    57216, 57248, 57256,     0,     1, 49152, 57344, 57345, 
+    57347, 57351, 57359, 57216, 57248, 57264, 57260,     0, 
+        1, 49152, 57344, 57345, 57347, 57351, 57359, 57216, 
+    57248, 57264, 57260,     0,     1, 49152, 57344, 57345, 
+    57347, 57351, 57359, 57216, 57248, 57264, 57265, 57262, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57359, 
+    57216, 57248,     0,     1, 49152, 57344, 57345, 57347, 
+    57351, 57359, 57216, 57280, 57264,     0,     1, 49152, 
+    57344, 57345, 57347, 57351, 57359, 57216, 57280, 57264, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57359, 
+    57216, 57280, 57264, 57266,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57359, 57216, 57280, 57264,     0, 
+        1, 49152, 57344, 57345, 57347, 57351, 57359, 57216, 
+    57280, 57264, 57268,     0,     1, 49152, 57344, 57345, 
+    57347, 57351, 57359, 57216, 57280, 57264, 57268,     0, 
+        1, 49152, 57344, 57345, 57347, 57351, 57359, 57216, 
+    57280, 57264, 57272, 57270,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57359, 57216, 57280, 57264,     0, 
+        1, 49152, 57344, 57345, 57347, 57351, 57359, 57216, 
+    57280, 57281, 57272,     0,     1, 49152, 57344, 57345, 
+    57347, 57351, 57359, 57216, 57280, 57281, 57272,     0, 
+        1, 49152, 57344, 57345, 57347, 57351, 57359, 57216, 
+    57280, 57281, 57272, 57274,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57359, 57216, 57280, 57281, 57272, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57359, 
+    57216, 57280, 57281, 57272, 57276,     0,     1, 49152, 
+    57344, 57345, 57347, 57351, 57359, 57216, 57280, 57281, 
+    57283, 57276,     0,     1, 49152, 57344, 57345, 57347, 
+    57351, 57359, 57216, 57280, 57281, 57283, 57276, 57278, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57359, 
+    57216,     0,     1, 49152, 57344, 57345, 57347, 57351, 
+    57359, 57216, 57280,     0,     1, 49152, 57344, 57345, 
+    57347, 57351, 57359, 57216, 57280,     0,     1, 49152, 
+    57344, 57345, 57347, 57351, 57359, 57216, 57280, 57282, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57359, 
+    57216, 57280,     0,     1, 49152, 57344, 57345, 57347, 
+    57351, 57359, 57216, 57280, 57284,     0,     1, 49152, 
+    57344, 57345, 57347, 57351, 57359, 57216, 57280, 57284, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57359, 
+    57216, 57280, 57288, 57286,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57359, 57216, 57280,     0,     1, 
+    49152, 57344, 57345, 57347, 57351, 57359, 57216, 57280, 
+    57288,     0,     1, 49152, 57344, 57345, 57347, 57351, 
+    57359, 57216, 57280, 57288,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57359, 57216, 57280, 57288, 57290, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57359, 
+    57216, 57280, 57288,     0,     1, 49152, 57344, 57345, 
+    57347, 57351, 57359, 57216, 57280, 57296, 57292,     0, 
+        1, 49152, 57344, 57345, 57347, 57351, 57359, 57216, 
+    57280, 57296, 57292,     0,     1, 49152, 57344, 57345, 
+    57347, 57351, 57359, 57216, 57280, 57296, 57297, 57294, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57359, 
+    57216, 57280,     0,     1, 49152, 57344, 57345, 57347, 
+    57351, 57359, 57216, 57280, 57296,     0,     1, 49152, 
+    57344, 57345, 57347, 57351, 57359, 57216, 57280, 57296, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57359, 
+    57216, 57280, 57296, 57298,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57359, 57216, 57280, 57296,     0, 
+        1, 49152, 57344, 57345, 57347, 57351, 57359, 57216, 
+    57280, 57296, 57300,     0,     1, 49152, 57344, 57345, 
+    57347, 57351, 57359, 57216, 57280, 57296, 57300,     0, 
+        1, 49152, 57344, 57345, 57347, 57351, 57359, 57216, 
+    57280, 57296, 57304, 57302,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57359, 57216, 57280, 57296,     0, 
+        1, 49152, 57344, 57345, 57347, 57351, 57359, 57216, 
+    57280, 57312, 57304,     0,     1, 49152, 57344, 57345, 
+    57347, 57351, 57359, 57216, 57280, 57312, 57304,     0, 
+        1, 49152, 57344, 57345, 57347, 57351, 57359, 57216, 
+    57280, 57312, 57304, 57306,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57359, 57216, 57280, 57312, 57304, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57359, 
+    57216, 57280, 57312, 57313, 57308,     0,     1, 49152, 
+    57344, 57345, 57347, 57351, 57359, 57216, 57280, 57312, 
+    57313, 57308,     0,     1, 49152, 57344, 57345, 57347, 
+    57351, 57359, 57216, 57280, 57312, 57313, 57308, 57310, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57359, 
+    57375, 57280,     0,     1, 49152, 57344, 57345, 57347, 
+    57351, 57359, 57375, 57280, 57312,     0,     1, 49152, 
+    57344, 57345, 57347, 57351, 57359, 57375, 57280, 57312, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57359, 
+    57375, 57280, 57312, 57314,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57359, 57375, 57280, 57312,     0, 
+        1, 49152, 57344, 57345, 57347, 57351, 57359, 57375, 
+    57280, 57312, 57316,     0,     1, 49152, 57344, 57345, 
+    57347, 57351, 57359, 57375, 57280, 57312, 57316,     0, 
+        1, 49152, 57344, 57345, 57347, 57351, 57359, 57375, 
+    57280, 57312, 57320, 57318,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57359, 57375, 57280, 57312,     0, 
+        1, 49152, 57344, 57345, 57347, 57351, 57359, 57375, 
+    57280, 57312, 57320,     0,     1, 49152, 57344, 57345, 
+    57347, 57351, 57359, 57375, 57280, 57312, 57320,     0, 
+        1, 49152, 57344, 57345, 57347, 57351, 57359, 57375, 
+    57280, 57312, 57320, 57322,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57359, 57375, 57280, 57312, 57320, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57359, 
+    57375, 57280, 57312, 57328, 57324,     0,     1, 49152, 
+    57344, 57345, 57347, 57351, 57359, 57375, 57280, 57312, 
+    57328, 57324,     0,     1, 49152, 57344, 57345, 57347, 
+    57351, 57359, 57375, 57280, 57312, 57328, 57329, 57326, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57359, 
+    57375, 57280, 57312,     0,     1, 49152, 57344, 57345, 
+    57347, 57351, 57359, 57375, 57280, 57312, 57328,     0, 
+        1, 49152, 57344, 57345, 57347, 57351, 57359, 57375, 
+    57280, 57312, 57328,     0,     1, 49152, 57344, 57345, 
+    57347, 57351, 57359, 57375, 57280, 57312, 57328, 57330, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57359, 
+    57375, 57280, 57312, 57328,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57359, 57375, 57280, 57312, 57328, 
+    57332,     0,     1, 49152, 57344, 57345, 57347, 57351, 
+    57359, 57375, 57280, 57312, 57328, 57332,     0,     1, 
+    49152, 57344, 57345, 57347, 57351, 57359, 57375, 57280, 
+    57312, 57328, 57336, 57334,     0,     1, 49152, 57344, 
+    57345, 57347, 57351, 57359, 57375, 57280, 57312, 57328, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57359, 
+    57375, 57280, 57312, 57328, 57336,     0,     1, 49152, 
+    57344, 57345, 57347, 57351, 57359, 57375, 57280, 57312, 
+    57328, 57336,     0,     1, 49152, 57344, 57345, 57347, 
+    57351, 57359, 57375, 57280, 57312, 57328, 57336, 57338, 
+        0,     1, 49152, 57344, 57345, 57347, 57351, 57359, 
+    57375, 57280, 57312, 57328, 57336,     0,     1, 49152, 
+    57344, 57345, 57347, 57351, 57359, 57375, 57280, 57312, 
+    57328, 57336, 57340,     0,     1, 49152, 57344, 57345, 
+    57347, 57351, 57359, 57375, 57280, 57312, 57328, 57336, 
+    57340,     0,     1, 49152, 57344, 57345, 57347, 57351, 
+    57359, 57375, 57280, 57312, 57328, 57336, 57340, 57342, 
+        0,     1, 49152,     0,     1, 49152, 57344,     0, 
+        1, 49152, 57344,     0,     1, 49152, 57344, 57346, 
+        0,     1, 49152, 57344,     0,     1, 49152, 57344, 
+    57348,     0,     1, 49152, 57344, 57348,     0,     1, 
+    49152, 57344, 57352, 57350,     0,     1, 49152, 57344, 
+        0,     1, 49152, 57344, 57352,     0,     1, 49152, 
+    57344, 57352,     0,     1, 49152, 57344, 57352, 57354, 
+        0,     1, 49152, 57344, 57352,     0,     1, 49152, 
+    57344, 57360, 57356,     0,     1, 49152, 57344, 57360, 
+    57356,     0,     1, 49152, 57344, 57360, 57361, 57358, 
+        0,     1, 49152, 57344,     0,     1, 49152, 57344, 
+    57360,     0,     1, 49152, 57344, 57360,     0,     1, 
+    49152, 57344, 57360, 57362,     0,     1, 49152, 57344, 
+    57360,     0,     1, 49152, 57344, 57360, 57364,     0, 
+        1, 49152, 57344, 57360, 57364,     0,     1, 49152, 
+    57344, 57360, 57368, 57366,     0,     1, 49152, 57344, 
+    57360,     0,     1, 49152, 57344, 57376, 57368,     0, 
+        1, 49152, 57344, 57376, 57368,     0,     1, 49152, 
+    57344, 57376, 57368, 57370,     0,     1, 49152, 57344, 
+    57376, 57368,     0,     1, 49152, 57344, 57376, 57377, 
+    57372,     0,     1, 49152, 57344, 57376, 57377, 57372, 
+        0,     1, 49152, 57344, 57376, 57377, 57372, 57374, 
+        0,     1, 49152, 57344,     0,     1, 49152, 57344, 
+    57376,     0,     1, 49152, 57344, 57376,     0,     1, 
+    49152, 57344, 57376, 57378,     0,     1, 49152, 57344, 
+    57376,     0,     1, 49152, 57344, 57376, 57380,     0, 
+        1, 49152, 57344, 57376, 57380,     0,     1, 49152, 
+    57344, 57376, 57384, 57382,     0,     1, 49152, 57344, 
+    57376,     0,     1, 49152, 57344, 57376, 57384,     0, 
+        1, 49152, 57344, 57376, 57384,     0,     1, 49152, 
+    57344, 57376, 57384, 57386,     0,     1, 49152, 57344, 
+    57376, 57384,     0,     1, 49152, 57344, 57376, 57392, 
+    57388,     0,     1, 49152, 57344, 57376, 57392, 57388, 
+        0,     1, 49152, 57344, 57376, 57392, 57393, 57390, 
+        0,     1, 49152, 57344, 57376,     0,     1, 49152, 
+    57344, 57408, 57392,     0,     1, 49152, 57344, 57408, 
+    57392,     0,     1, 49152, 57344, 57408, 57392, 57394, 
+        0,     1, 49152, 57344, 57408, 57392,     0,     1, 
+    49152, 57344, 57408, 57392, 57396,     0,     1, 49152, 
+    57344, 57408, 57392, 57396,     0,     1, 49152, 57344, 
+    57408, 57392, 57400, 57398,     0,     1, 49152, 57344, 
+    57408, 57392,     0,     1, 49152, 57344, 57408, 57409, 
+    57400,     0,     1, 49152, 57344, 57408, 57409, 57400, 
+        0,     1, 49152, 57344, 57408, 57409, 57400, 57402, 
+        0,     1, 49152, 57344, 57408, 57409, 57400,     0, 
+        1, 49152, 57344, 57408, 57409, 57400, 57404,     0, 
+        1, 49152, 57344, 57408, 57409, 57411, 57404,     0, 
+        1, 49152, 57344, 57408, 57409, 57411, 57404, 57406, 
+        0,     1, 49152, 57344,     0,     1, 49152, 57344, 
+    57408,     0,     1, 49152, 57344, 57408,     0,     1, 
+    49152, 57344, 57408, 57410,     0,     1, 49152, 57344, 
+    57408,     0,     1, 49152, 57344, 57408, 57412,     0, 
+        1, 49152, 57344, 57408, 57412,     0,     1, 49152, 
+    57344, 57408, 57416, 57414,     0,     1, 49152, 57344, 
+    57408,     0,     1, 49152, 57344, 57408, 57416,     0, 
+        1, 49152, 57344, 57408, 57416,     0,     1, 49152, 
+    57344, 57408, 57416, 57418,     0,     1, 49152, 57344, 
+    57408, 57416,     0,     1, 49152, 57344, 57408, 57424, 
+    57420,     0,     1, 49152, 57344, 57408, 57424, 57420, 
+        0,     1, 49152, 57344, 57408, 57424, 57425, 57422, 
+        0,     1, 49152, 57344, 57408,     0,     1, 49152, 
+    57344, 57408, 57424,     0,     1, 49152, 57344, 57408, 
+    57424,     0,     1, 49152, 57344, 57408, 57424, 57426, 
+        0,     1, 49152, 57344, 57408, 57424,     0,     1, 
+    49152, 57344, 57408, 57424, 57428,     0,     1, 49152, 
+    57344, 57408, 57424, 57428,     0,     1, 49152, 57344, 
+    57408, 57424, 57432, 57430,     0,     1, 49152, 57344, 
+    57408, 57424,     0,     1, 49152, 57344, 57408, 57440, 
+    57432,     0,     1, 49152, 57344, 57408, 57440, 57432, 
+        0,     1, 49152, 57344, 57408, 57440, 57432, 57434, 
+        0,     1, 49152, 57344, 57408, 57440, 57432,     0, 
+        1, 49152, 57344, 57408, 57440, 57441, 57436,     0, 
+        1, 49152, 57344, 57408, 57440, 57441, 57436,     0, 
+        1, 49152, 57344, 57408, 57440, 57441, 57436, 57438, 
+        0,     1, 49152, 57344, 57408,     0,     1, 49152, 
+    57344, 57472, 57440,     0,     1, 49152, 57344, 57472, 
+    57440,     0,     1, 49152, 57344, 57472, 57440, 57442, 
+        0,     1, 49152, 57344, 57472, 57440,     0,     1, 
+    49152, 57344, 57472, 57440, 57444,     0,     1, 49152, 
+    57344, 57472, 57440, 57444,     0,     1, 49152, 57344, 
+    57472, 57440, 57448, 57446,     0,     1, 49152, 57344, 
+    57472, 57440,     0,     1, 49152, 57344, 57472, 57440, 
+    57448,     0,     1, 49152, 57344, 57472, 57440, 57448, 
+        0,     1, 49152, 57344, 57472, 57440, 57448, 57450, 
+        0,     1, 49152, 57344, 57472, 57440, 57448,     0, 
+        1, 49152, 57344, 57472, 57440, 57456, 57452,     0, 
+        1, 49152, 57344, 57472, 57440, 57456, 57452,     0, 
+        1, 49152, 57344, 57472, 57440, 57456, 57457, 57454, 
+        0,     1, 49152, 57344, 57472, 57440,     0,     1, 
+    49152, 57344, 57472, 57473, 57456,     0,     1, 49152, 
+    57344, 57472, 57473, 57456,     0,     1, 49152, 57344, 
+    57472, 57473, 57456, 57458,     0,     1, 49152, 57344, 
+    57472, 57473, 57456,     0,     1, 49152, 57344, 57472, 
+    57473, 57456, 57460,     0,     1, 49152, 57344, 57472, 
+    57473, 57456, 57460,     0,     1, 49152, 57344, 57472, 
+    57473, 57456, 57464, 57462,     0,     1, 49152, 57344, 
+    57472, 57473, 57456,     0,     1, 49152, 57344, 57472, 
+    57473, 57456, 57464,     0,     1, 49152, 57344, 57472, 
+    57473, 57475, 57464,     0,     1, 49152, 57344, 57472, 
+    57473, 57475, 57464, 57466,     0,     1, 49152, 57344, 
+    57472, 57473, 57475, 57464,     0,     1, 49152, 57344, 
+    57472, 57473, 57475, 57464, 57468,     0,     1, 49152, 
+    57344, 57472, 57473, 57475, 57464, 57468,     0,     1, 
+    49152, 57344, 57472, 57473, 57475, 57464, 57468, 57470, 
+        0,     1, 49152, 57344,     0,     1, 49152, 57344, 
+    57472,     0,     1, 49152, 57344, 57472,     0,     1, 
+    49152, 57344, 57472, 57474,     0,     1, 49152, 57344, 
+    57472,     0,     1, 49152, 57344, 57472, 57476,     0, 
+        1, 49152, 57344, 57472, 57476,     0,     1, 49152, 
+    57344, 57472, 57480, 57478,     0,     1, 49152, 57344, 
+    57472,     0,     1, 49152, 57344, 57472, 57480,     0, 
+        1, 49152, 57344, 57472, 57480,     0,     1, 49152, 
+    57344, 57472, 57480, 57482,     0,     1, 49152, 57344, 
+    57472, 57480,     0,     1, 49152, 57344, 57472, 57488, 
+    57484,     0,     1, 49152, 57344, 57472, 57488, 57484, 
+        0,     1, 49152, 57344, 57472, 57488, 57489, 57486, 
+        0,     1, 49152, 57344, 57472,     0,     1, 49152, 
+    57344, 57472, 57488,     0,     1, 49152, 57344, 57472, 
+    57488,     0,     1, 49152, 57344, 57472, 57488, 57490, 
+        0,     1, 49152, 57344, 57472, 57488,     0,     1, 
+    49152, 57344, 57472, 57488, 57492,     0,     1, 49152, 
+    57344, 57472, 57488, 57492,     0,     1, 49152, 57344, 
+    57472, 57488, 57496, 57494,     0,     1, 49152, 57344, 
+    57472, 57488,     0,     1, 49152, 57344, 57472, 57504, 
+    57496,     0,     1, 49152, 57344, 57472, 57504, 57496, 
+        0,     1, 49152, 57344, 57472, 57504, 57496, 57498, 
+        0,     1, 49152, 57344, 57472, 57504, 57496,     0, 
+        1, 49152, 57344, 57472, 57504, 57505, 57500,     0, 
+        1, 49152, 57344, 57472, 57504, 57505, 57500,     0, 
+        1, 49152, 57344, 57472, 57504, 57505, 57500, 57502, 
+        0,     1, 49152, 57344, 57472,     0,     1, 49152, 
+    57344, 57472, 57504,     0,     1, 49152, 57344, 57472, 
+    57504,     0,     1, 49152, 57344, 57472, 57504, 57506, 
+        0,     1, 49152, 57344, 57472, 57504,     0,     1, 
+    49152, 57344, 57472, 57504, 57508,     0,     1, 49152, 
+    57344, 57472, 57504, 57508,     0,     1, 49152, 57344, 
+    57472, 57504, 57512, 57510,     0,     1, 49152, 57344, 
+    57472, 57504,     0,     1, 49152, 57344, 57472, 57504, 
+    57512,     0,     1, 49152, 57344, 57472, 57504, 57512, 
+        0,     1, 49152, 57344, 57472, 57504, 57512, 57514, 
+        0,     1, 49152, 57344, 57472, 57504, 57512,     0, 
+        1, 49152, 57344, 57472, 57504, 57520, 57516,     0, 
+        1, 49152, 57344, 57472, 57504, 57520, 57516,     0, 
+        1, 49152, 57344, 57472, 57504, 57520, 57521, 57518, 
+        0,     1, 49152, 57344, 57472, 57504,     0,     1, 
+    49152, 57344, 57472, 57536, 57520,     0,     1, 49152, 
+    57344, 57472, 57536, 57520,     0,     1, 49152, 57344, 
+    57472, 57536, 57520, 57522,     0,     1, 49152, 57344, 
+    57472, 57536, 57520,     0,     1, 49152, 57344, 57472, 
+    57536, 57520, 57524,     0,     1, 49152, 57344, 57472, 
+    57536, 57520, 57524,     0,     1, 49152, 57344, 57472, 
+    57536, 57520, 57528, 57526,     0,     1, 49152, 57344, 
+    57472, 57536, 57520,     0,     1, 49152, 57344, 57472, 
+    57536, 57537, 57528,     0,     1, 49152, 57344, 57472, 
+    57536, 57537, 57528,     0,     1, 49152, 57344, 57472, 
+    57536, 57537, 57528, 57530,     0,     1, 49152, 57344, 
+    57472, 57536, 57537, 57528,     0,     1, 49152, 57344, 
+    57472, 57536, 57537, 57528, 57532,     0,     1, 49152, 
+    57344, 57472, 57536, 57537, 57539, 57532,     0,     1, 
+    49152, 57344, 57472, 57536, 57537, 57539, 57532, 57534, 
+        0,     1, 49152, 57344, 57472,     0,     1, 49152, 
+    57344, 57600, 57536,     0,     1, 49152, 57344, 57600, 
+    57536,     0,     1, 49152, 57344, 57600, 57536, 57538, 
+        0,     1, 49152, 57344, 57600, 57536,     0,     1, 
+    49152, 57344, 57600, 57536, 57540,     0,     1, 49152, 
+    57344, 57600, 57536, 57540,     0,     1, 49152, 57344, 
+    57600, 57536, 57544, 57542,     0,     1, 49152, 57344, 
+    57600, 57536,     0,     1, 49152, 57344, 57600, 57536, 
+    57544,     0,     1, 49152, 57344, 57600, 57536, 57544, 
+        0,     1, 49152, 57344, 57600, 57536, 57544, 57546, 
+        0,     1, 49152, 57344, 57600, 57536, 57544,     0, 
+        1, 49152, 57344, 57600, 57536, 57552, 57548,     0, 
+        1, 49152, 57344, 57600, 57536, 57552, 57548,     0, 
+        1, 49152, 57344, 57600, 57536, 57552, 57553, 57550, 
+        0,     1, 49152, 57344, 57600, 57536,     0,     1, 
+    49152, 57344, 57600, 57536, 57552,     0,     1, 49152, 
+    57344, 57600, 57536, 57552,     0,     1, 49152, 57344, 
+    57600, 57536, 57552, 57554,     0,     1, 49152, 57344, 
+    57600, 57536, 57552,     0,     1, 49152, 57344, 57600, 
+    57536, 57552, 57556,     0,     1, 49152, 57344, 57600, 
+    57536, 57552, 57556,     0,     1, 49152, 57344, 57600, 
+    57536, 57552, 57560, 57558,     0,     1, 49152, 57344, 
+    57600, 57536, 57552,     0,     1, 49152, 57344, 57600, 
+    57536, 57568, 57560,     0,     1, 49152, 57344, 57600, 
+    57536, 57568, 57560,     0,     1, 49152, 57344, 57600, 
+    57536, 57568, 57560, 57562,     0,     1, 49152, 57344, 
+    57600, 57536, 57568, 57560,     0,     1, 49152, 57344, 
+    57600, 57536, 57568, 57569, 57564,     0,     1, 49152, 
+    57344, 57600, 57536, 57568, 57569, 57564,     0,     1, 
+    49152, 57344, 57600, 57536, 57568, 57569, 57564, 57566, 
+        0,     1, 49152, 57344, 57600, 57536,     0,     1, 
+    49152, 57344, 57600, 57601, 57568,     0,     1, 49152, 
+    57344, 57600, 57601, 57568,     0,     1, 49152, 57344, 
+    57600, 57601, 57568, 57570,     0,     1, 49152, 57344, 
+    57600, 57601, 57568,     0,     1, 49152, 57344, 57600, 
+    57601, 57568, 57572,     0,     1, 49152, 57344, 57600, 
+    57601, 57568, 57572,     0,     1, 49152, 57344, 57600, 
+    57601, 57568, 57576, 57574,     0,     1, 49152, 57344, 
+    57600, 57601, 57568,     0,     1, 49152, 57344, 57600, 
+    57601, 57568, 57576,     0,     1, 49152, 57344, 57600, 
+    57601, 57568, 57576,     0,     1, 49152, 57344, 57600, 
+    57601, 57568, 57576, 57578,     0,     1, 49152, 57344, 
+    57600, 57601, 57568, 57576,     0,     1, 49152, 57344, 
+    57600, 57601, 57568, 57584, 57580,     0,     1, 49152, 
+    57344, 57600, 57601, 57568, 57584, 57580,     0,     1, 
+    49152, 57344, 57600, 57601, 57568, 57584, 57585, 57582, 
+        0,     1, 49152, 57344, 57600, 57601, 57568,     0, 
+        1, 49152, 57344, 57600, 57601, 57568, 57584,     0, 
+        1, 49152, 57344, 57600, 57601, 57603, 57584,     0, 
+        1, 49152, 57344, 57600, 57601, 57603, 57584, 57586, 
+        0,     1, 49152, 57344, 57600, 57601, 57603, 57584, 
+        0,     1, 49152, 57344, 57600, 57601, 57603, 57584, 
+    57588,     0,     1, 49152, 57344, 57600, 57601, 57603, 
+    57584, 57588,     0,     1, 49152, 57344, 57600, 57601, 
+    57603, 57584, 57592, 57590,     0,     1, 49152, 57344, 
+    57600, 57601, 57603, 57584,     0,     1, 49152, 57344, 
+    57600, 57601, 57603, 57584, 57592,     0,     1, 49152, 
+    57344, 57600, 57601, 57603, 57584, 57592,     0,     1, 
+    49152, 57344, 57600, 57601, 57603, 57584, 57592, 57594, 
+        0,     1, 49152, 57344, 57600, 57601, 57603, 57607, 
+    57592,     0,     1, 49152, 57344, 57600, 57601, 57603, 
+    57607, 57592, 57596,     0,     1, 49152, 57344, 57600, 
+    57601, 57603, 57607, 57592, 57596,     0,     1, 49152, 
+    57344, 57600, 57601, 57603, 57607, 57592, 57596, 57598, 
+        0,     1, 49152, 57344,     0,     1, 49152, 57344, 
+    57600,     0,     1, 49152, 57344, 57600,     0,     1, 
+    49152, 57344, 57600, 57602,     0,     1, 49152, 57344, 
+    57600,     0,     1, 49152, 57344, 57600, 57604,     0, 
+        1, 49152, 57344, 57600, 57604,     0,     1, 49152, 
+    57344, 57600, 57608, 57606,     0,     1, 49152, 57344, 
+    57600,     0,     1, 49152, 57344, 57600, 57608,     0, 
+        1, 49152, 57344, 57600, 57608,     0,     1, 49152, 
+    57344, 57600, 57608, 57610,     0,     1, 49152, 57344, 
+    57600, 57608,     0,     1, 49152, 57344, 57600, 57616, 
+    57612,     0,     1, 49152, 57344, 57600, 57616, 57612, 
+        0,     1, 49152, 57344, 57600, 57616, 57617, 57614, 
+        0,     1, 49152, 57344, 57600,     0,     1, 49152, 
+    57344, 57600, 57616,     0,     1, 49152, 57344, 57600, 
+    57616,     0,     1, 49152, 57344, 57600, 57616, 57618, 
+        0,     1, 49152, 57344, 57600, 57616,     0,     1, 
+    49152, 57344, 57600, 57616, 57620,     0,     1, 49152, 
+    57344, 57600, 57616, 57620,     0,     1, 49152, 57344, 
+    57600, 57616, 57624, 57622,     0,     1, 49152, 57344, 
+    57600, 57616,     0,     1, 49152, 57344, 57600, 57632, 
+    57624,     0,     1, 49152, 57344, 57600, 57632, 57624, 
+        0,     1, 49152, 57344, 57600, 57632, 57624, 57626, 
+        0,     1, 49152, 57344, 57600, 57632, 57624,     0, 
+        1, 49152, 57344, 57600, 57632, 57633, 57628,     0, 
+        1, 49152, 57344, 57600, 57632, 57633, 57628,     0, 
+        1, 49152, 57344, 57600, 57632, 57633, 57628, 57630, 
+        0,     1, 49152, 57344, 57600,     0,     1, 49152, 
+    57344, 57600, 57632,     0,     1, 49152, 57344, 57600, 
+    57632,     0,     1, 49152, 57344, 57600, 57632, 57634, 
+        0,     1, 49152, 57344, 57600, 57632,     0,     1, 
+    49152, 57344, 57600, 57632, 57636,     0,     1, 49152, 
+    57344, 57600, 57632, 57636,     0,     1, 49152, 57344, 
+    57600, 57632, 57640, 57638,     0,     1, 49152, 57344, 
+    57600, 57632,     0,     1, 49152, 57344, 57600, 57632, 
+    57640,     0,     1, 49152, 57344, 57600, 57632, 57640, 
+        0,     1, 49152, 57344, 57600, 57632, 57640, 57642, 
+        0,     1, 49152, 57344, 57600, 57632, 57640,     0, 
+        1, 49152, 57344, 57600, 57632, 57648, 57644,     0, 
+        1, 49152, 57344, 57600, 57632, 57648, 57644,     0, 
+        1, 49152, 57344, 57600, 57632, 57648, 57649, 57646, 
+        0,     1, 49152, 57344, 57600, 57632,     0,     1, 
+    49152, 57344, 57600, 57664, 57648,     0,     1, 49152, 
+    57344, 57600, 57664, 57648,     0,     1, 49152, 57344, 
+    57600, 57664, 57648, 57650,     0,     1, 49152, 57344, 
+    57600, 57664, 57648,     0,     1, 49152, 57344, 57600, 
+    57664, 57648, 57652,     0,     1, 49152, 57344, 57600, 
+    57664, 57648, 57652,     0,     1, 49152, 57344, 57600, 
+    57664, 57648, 57656, 57654,     0,     1, 49152, 57344, 
+    57600, 57664, 57648,     0,     1, 49152, 57344, 57600, 
+    57664, 57665, 57656,     0,     1, 49152, 57344, 57600, 
+    57664, 57665, 57656,     0,     1, 49152, 57344, 57600, 
+    57664, 57665, 57656, 57658,     0,     1, 49152, 57344, 
+    57600, 57664, 57665, 57656,     0,     1, 49152, 57344, 
+    57600, 57664, 57665, 57656, 57660,     0,     1, 49152, 
+    57344, 57600, 57664, 57665, 57667, 57660,     0,     1, 
+    49152, 57344, 57600, 57664, 57665, 57667, 57660, 57662, 
+        0,     1, 49152, 57344, 57600,     0,     1, 49152, 
+    57344, 57600, 57664,     0,     1, 49152, 57344, 57600, 
+    57664,     0,     1, 49152, 57344, 57600, 57664, 57666, 
+        0,     1, 49152, 57344, 57600, 57664,     0,     1, 
+    49152, 57344, 57600, 57664, 57668,     0,     1, 49152, 
+    57344, 57600, 57664, 57668,     0,     1, 49152, 57344, 
+    57600, 57664, 57672, 57670,     0,     1, 49152, 57344, 
+    57600, 57664,     0,     1, 49152, 57344, 57600, 57664, 
+    57672,     0,     1, 49152, 57344, 57600, 57664, 57672, 
+        0,     1, 49152, 57344, 57600, 57664, 57672, 57674, 
+        0,     1, 49152, 57344, 57600, 57664, 57672,     0, 
+        1, 49152, 57344, 57600, 57664, 57680, 57676,     0, 
+        1, 49152, 57344, 57600, 57664, 57680, 57676,     0, 
+        1, 49152, 57344, 57600, 57664, 57680, 57681, 57678, 
+        0,     1, 49152, 57344, 57600, 57664,     0,     1, 
+    49152, 57344, 57600, 57664, 57680,     0,     1, 49152, 
+    57344, 57600, 57664, 57680,     0,     1, 49152, 57344, 
+    57600, 57664, 57680, 57682,     0,     1, 49152, 57344, 
+    57600, 57664, 57680,     0,     1, 49152, 57344, 57600, 
+    57664, 57680, 57684,     0,     1, 49152, 57344, 57600, 
+    57664, 57680, 57684,     0,     1, 49152, 57344, 57600, 
+    57664, 57680, 57688, 57686,     0,     1, 49152, 57344, 
+    57600, 57664, 57680,     0,     1, 49152, 57344, 57600, 
+    57664, 57696, 57688,     0,     1, 49152, 57344, 57600, 
+    57664, 57696, 57688,     0,     1, 49152, 57344, 57600, 
+    57664, 57696, 57688, 57690,     0,     1, 49152, 57344, 
+    57600, 57664, 57696, 57688,     0,     1, 49152, 57344, 
+    57600, 57664, 57696, 57697, 57692,     0,     1, 49152, 
+    57344, 57600, 57664, 57696, 57697, 57692,     0,     1, 
+    49152, 57344, 57600, 57664, 57696, 57697, 57692, 57694, 
+        0,     1, 49152, 57344, 57600, 57664,     0,     1, 
+    49152, 57344, 57600, 57728, 57696,     0,     1, 49152, 
+    57344, 57600, 57728, 57696,     0,     1, 49152, 57344, 
+    57600, 57728, 57696, 57698,     0,     1, 49152, 57344, 
+    57600, 57728, 57696,     0,     1, 49152, 57344, 57600, 
+    57728, 57696, 57700,     0,     1, 49152, 57344, 57600, 
+    57728, 57696, 57700,     0,     1, 49152, 57344, 57600, 
+    57728, 57696, 57704, 57702,     0,     1, 49152, 57344, 
+    57600, 57728, 57696,     0,     1, 49152, 57344, 57600, 
+    57728, 57696, 57704,     0,     1, 49152, 57344, 57600, 
+    57728, 57696, 57704,     0,     1, 49152, 57344, 57600, 
+    57728, 57696, 57704, 57706,     0,     1, 49152, 57344, 
+    57600, 57728, 57696, 57704,     0,     1, 49152, 57344, 
+    57600, 57728, 57696, 57712, 57708,     0,     1, 49152, 
+    57344, 57600, 57728, 57696, 57712, 57708,     0,     1, 
+    49152, 57344, 57600, 57728, 57696, 57712, 57713, 57710, 
+        0,     1, 49152, 57344, 57600, 57728, 57696,     0, 
+        1, 49152, 57344, 57600, 57728, 57729, 57712,     0, 
+        1, 49152, 57344, 57600, 57728, 57729, 57712,     0, 
+        1, 49152, 57344, 57600, 57728, 57729, 57712, 57714, 
+        0,     1, 49152, 57344, 57600, 57728, 57729, 57712, 
+        0,     1, 49152, 57344, 57600, 57728, 57729, 57712, 
+    57716,     0,     1, 49152, 57344, 57600, 57728, 57729, 
+    57712, 57716,     0,     1, 49152, 57344, 57600, 57728, 
+    57729, 57712, 57720, 57718,     0,     1, 49152, 57344, 
+    57600, 57728, 57729, 57712,     0,     1, 49152, 57344, 
+    57600, 57728, 57729, 57712, 57720,     0,     1, 49152, 
+    57344, 57600, 57728, 57729, 57731, 57720,     0,     1, 
+    49152, 57344, 57600, 57728, 57729, 57731, 57720, 57722, 
+        0,     1, 49152, 57344, 57600, 57728, 57729, 57731, 
+    57720,     0,     1, 49152, 57344, 57600, 57728, 57729, 
+    57731, 57720, 57724,     0,     1, 49152, 57344, 57600, 
+    57728, 57729, 57731, 57720, 57724,     0,     1, 49152, 
+    57344, 57600, 57728, 57729, 57731, 57720, 57724, 57726, 
+        0,     1, 49152, 57344, 57600,     0,     1, 49152, 
+    57344, 57856, 57728,     0,     1, 49152, 57344, 57856, 
+    57728,     0,     1, 49152, 57344, 57856, 57728, 57730, 
+        0,     1, 49152, 57344, 57856, 57728,     0,     1, 
+    49152, 57344, 57856, 57728, 57732,     0,     1, 49152, 
+    57344, 57856, 57728, 57732,     0,     1, 49152, 57344, 
+    57856, 57728, 57736, 57734,     0,     1, 49152, 57344, 
+    57856, 57728,     0,     1, 49152, 57344, 57856, 57728, 
+    57736,     0,     1, 49152, 57344, 57856, 57728, 57736, 
+        0,     1, 49152, 57344, 57856, 57728, 57736, 57738, 
+        0,     1, 49152, 57344, 57856, 57728, 57736,     0, 
+        1, 49152, 57344, 57856, 57728, 57744, 57740,     0, 
+        1, 49152, 57344, 57856, 57728, 57744, 57740,     0, 
+        1, 49152, 57344, 57856, 57728, 57744, 57745, 57742, 
+        0,     1, 49152, 57344, 57856, 57728,     0,     1, 
+    49152, 57344, 57856, 57728, 57744,     0,     1, 49152, 
+    57344, 57856, 57728, 57744,     0,     1, 49152, 57344, 
+    57856, 57728, 57744, 57746,     0,     1, 49152, 57344, 
+    57856, 57728, 57744,     0,     1, 49152, 57344, 57856, 
+    57728, 57744, 57748,     0,     1, 49152, 57344, 57856, 
+    57728, 57744, 57748,     0,     1, 49152, 57344, 57856, 
+    57728, 57744, 57752, 57750,     0,     1, 49152, 57344, 
+    57856, 57728, 57744,     0,     1, 49152, 57344, 57856, 
+    57728, 57760, 57752,     0,     1, 49152, 57344, 57856, 
+    57728, 57760, 57752,     0,     1, 49152, 57344, 57856, 
+    57728, 57760, 57752, 57754,     0,     1, 49152, 57344, 
+    57856, 57728, 57760, 57752,     0,     1, 49152, 57344, 
+    57856, 57728, 57760, 57761, 57756,     0,     1, 49152, 
+    57344, 57856, 57728, 57760, 57761, 57756,     0,     1, 
+    49152, 57344, 57856, 57728, 57760, 57761, 57756, 57758, 
+        0,     1, 49152, 57344, 57856, 57728,     0,     1, 
+    49152, 57344, 57856, 57728, 57760,     0,     1, 49152, 
+    57344, 57856, 57728, 57760,     0,     1, 49152, 57344, 
+    57856, 57728, 57760, 57762,     0,     1, 49152, 57344, 
+    57856, 57728, 57760,     0,     1, 49152, 57344, 57856, 
+    57728, 57760, 57764,     0,     1, 49152, 57344, 57856, 
+    57728, 57760, 57764,     0,     1, 49152, 57344, 57856, 
+    57728, 57760, 57768, 57766,     0,     1, 49152, 57344, 
+    57856, 57728, 57760,     0,     1, 49152, 57344, 57856, 
+    57728, 57760, 57768,     0,     1, 49152, 57344, 57856, 
+    57728, 57760, 57768,     0,     1, 49152, 57344, 57856, 
+    57728, 57760, 57768, 57770,     0,     1, 49152, 57344, 
+    57856, 57728, 57760, 57768,     0,     1, 49152, 57344, 
+    57856, 57728, 57760, 57776, 57772,     0,     1, 49152, 
+    57344, 57856, 57728, 57760, 57776, 57772,     0,     1, 
+    49152, 57344, 57856, 57728, 57760, 57776, 57777, 57774, 
+        0,     1, 49152, 57344, 57856, 57728, 57760,     0, 
+        1, 49152, 57344, 57856, 57728, 57792, 57776,     0, 
+        1, 49152, 57344, 57856, 57728, 57792, 57776,     0, 
+        1, 49152, 57344, 57856, 57728, 57792, 57776, 57778, 
+        0,     1, 49152, 57344, 57856, 57728, 57792, 57776, 
+        0,     1, 49152, 57344, 57856, 57728, 57792, 57776, 
+    57780,     0,     1, 49152, 57344, 57856, 57728, 57792, 
+    57776, 57780,     0,     1, 49152, 57344, 57856, 57728, 
+    57792, 57776, 57784, 57782,     0,     1, 49152, 57344, 
+    57856, 57728, 57792, 57776,     0,     1, 49152, 57344, 
+    57856, 57728, 57792, 57793, 57784,     0,     1, 49152, 
+    57344, 57856, 57728, 57792, 57793, 57784,     0,     1, 
+    49152, 57344, 57856, 57728, 57792, 57793, 57784, 57786, 
+        0,     1, 49152, 57344, 57856, 57728, 57792, 57793, 
+    57784,     0,     1, 49152, 57344, 57856, 57728, 57792, 
+    57793, 57784, 57788,     0,     1, 49152, 57344, 57856, 
+    57728, 57792, 57793, 57795, 57788,     0,     1, 49152, 
+    57344, 57856, 57728, 57792, 57793, 57795, 57788, 57790, 
+        0,     1, 49152, 57344, 57856, 57728,     0,     1, 
+    49152, 57344, 57856, 57857, 57792,     0,     1, 49152, 
+    57344, 57856, 57857, 57792,     0,     1, 49152, 57344, 
+    57856, 57857, 57792, 57794,     0,     1, 49152, 57344, 
+    57856, 57857, 57792,     0,     1, 49152, 57344, 57856, 
+    57857, 57792, 57796,     0,     1, 49152, 57344, 57856, 
+    57857, 57792, 57796,     0,     1, 49152, 57344, 57856, 
+    57857, 57792, 57800, 57798,     0,     1, 49152, 57344, 
+    57856, 57857, 57792,     0,     1, 49152, 57344, 57856, 
+    57857, 57792, 57800,     0,     1, 49152, 57344, 57856, 
+    57857, 57792, 57800,     0,     1, 49152, 57344, 57856, 
+    57857, 57792, 57800, 57802,     0,     1, 49152, 57344, 
+    57856, 57857, 57792, 57800,     0,     1, 49152, 57344, 
+    57856, 57857, 57792, 57808, 57804,     0,     1, 49152, 
+    57344, 57856, 57857, 57792, 57808, 57804,     0,     1, 
+    49152, 57344, 57856, 57857, 57792, 57808, 57809, 57806, 
+        0,     1, 49152, 57344, 57856, 57857, 57792,     0, 
+        1, 49152, 57344, 57856, 57857, 57792, 57808,     0, 
+        1, 49152, 57344, 57856, 57857, 57792, 57808,     0, 
+        1, 49152, 57344, 57856, 57857, 57792, 57808, 57810, 
+        0,     1, 49152, 57344, 57856, 57857, 57792, 57808, 
+        0,     1, 49152, 57344, 57856, 57857, 57792, 57808, 
+    57812,     0,     1, 49152, 57344, 57856, 57857, 57792, 
+    57808, 57812,     0,     1, 49152, 57344, 57856, 57857, 
+    57792, 57808, 57816, 57814,     0,     1, 49152, 57344, 
+    57856, 57857, 57792, 57808,     0,     1, 49152, 57344, 
+    57856, 57857, 57792, 57824, 57816,     0,     1, 49152, 
+    57344, 57856, 57857, 57792, 57824, 57816,     0,     1, 
+    49152, 57344, 57856, 57857, 57792, 57824, 57816, 57818, 
+        0,     1, 49152, 57344, 57856, 57857, 57792, 57824, 
+    57816,     0,     1, 49152, 57344, 57856, 57857, 57792, 
+    57824, 57825, 57820,     0,     1, 49152, 57344, 57856, 
+    57857, 57792, 57824, 57825, 57820,     0,     1, 49152, 
+    57344, 57856, 57857, 57792, 57824, 57825, 57820, 57822, 
+        0,     1, 49152, 57344, 57856, 57857, 57792,     0, 
+        1, 49152, 57344, 57856, 57857, 57792, 57824,     0, 
+        1, 49152, 57344, 57856, 57857, 57859, 57824,     0, 
+        1, 49152, 57344, 57856, 57857, 57859, 57824, 57826, 
+        0,     1, 49152, 57344, 57856, 57857, 57859, 57824, 
+        0,     1, 49152, 57344, 57856, 57857, 57859, 57824, 
+    57828,     0,     1, 49152, 57344, 57856, 57857, 57859, 
+    57824, 57828,     0,     1, 49152, 57344, 57856, 57857, 
+    57859, 57824, 57832, 57830,     0,     1, 49152, 57344, 
+    57856, 57857, 57859, 57824,     0,     1, 49152, 57344, 
+    57856, 57857, 57859, 57824, 57832,     0,     1, 49152, 
+    57344, 57856, 57857, 57859, 57824, 57832,     0,     1, 
+    49152, 57344, 57856, 57857, 57859, 57824, 57832, 57834, 
+        0,     1, 49152, 57344, 57856, 57857, 57859, 57824, 
+    57832,     0,     1, 49152, 57344, 57856, 57857, 57859, 
+    57824, 57840, 57836,     0,     1, 49152, 57344, 57856, 
+    57857, 57859, 57824, 57840, 57836,     0,     1, 49152, 
+    57344, 57856, 57857, 57859, 57824, 57840, 57841, 57838, 
+        0,     1, 49152, 57344, 57856, 57857, 57859, 57824, 
+        0,     1, 49152, 57344, 57856, 57857, 57859, 57824, 
+    57840,     0,     1, 49152, 57344, 57856, 57857, 57859, 
+    57824, 57840,     0,     1, 49152, 57344, 57856, 57857, 
+    57859, 57824, 57840, 57842,     0,     1, 49152, 57344, 
+    57856, 57857, 57859, 57863, 57840,     0,     1, 49152, 
+    57344, 57856, 57857, 57859, 57863, 57840, 57844,     0, 
+        1, 49152, 57344, 57856, 57857, 57859, 57863, 57840, 
+    57844,     0,     1, 49152, 57344, 57856, 57857, 57859, 
+    57863, 57840, 57848, 57846,     0,     1, 49152, 57344, 
+    57856, 57857, 57859, 57863, 57840,     0,     1, 49152, 
+    57344, 57856, 57857, 57859, 57863, 57840, 57848,     0, 
+        1, 49152, 57344, 57856, 57857, 57859, 57863, 57840, 
+    57848,     0,     1, 49152, 57344, 57856, 57857, 57859, 
+    57863, 57840, 57848, 57850,     0,     1, 49152, 57344, 
+    57856, 57857, 57859, 57863, 57840, 57848,     0,     1, 
+    49152, 57344, 57856, 57857, 57859, 57863, 57840, 57848, 
+    57852,     0,     1, 49152, 57344, 57856, 57857, 57859, 
+    57863, 57840, 57848, 57852,     0,     1, 49152, 57344, 
+    57856, 57857, 57859, 57863, 57840, 57848, 57852, 57854, 
+        0,     1, 49152, 57344,     0,     1, 49152, 57344, 
+    57856,     0,     1, 49152, 57344, 57856,     0,     1, 
+    49152, 57344, 57856, 57858,     0,     1, 49152, 57344, 
+    57856,     0,     1, 49152, 57344, 57856, 57860,     0, 
+        1, 49152, 57344, 57856, 57860,     0,     1, 49152, 
+    57344, 57856, 57864, 57862,     0,     1, 49152, 57344, 
+    57856,     0,     1, 49152, 57344, 57856, 57864,     0, 
+        1, 49152, 57344, 57856, 57864,     0,     1, 49152, 
+    57344, 57856, 57864, 57866,     0,     1, 49152, 57344, 
+    57856, 57864,     0,     1, 49152, 57344, 57856, 57872, 
+    57868,     0,     1, 49152, 57344, 57856, 57872, 57868, 
+        0,     1, 49152, 57344, 57856, 57872, 57873, 57870, 
+        0,     1, 49152, 57344, 57856,     0,     1, 49152, 
+    57344, 57856, 57872,     0,     1, 49152, 57344, 57856, 
+    57872,     0,     1, 49152, 57344, 57856, 57872, 57874, 
+        0,     1, 49152, 57344, 57856, 57872,     0,     1, 
+    49152, 57344, 57856, 57872, 57876,     0,     1, 49152, 
+    57344, 57856, 57872, 57876,     0,     1, 49152, 57344, 
+    57856, 57872, 57880, 57878,     0,     1, 49152, 57344, 
+    57856, 57872,     0,     1, 49152, 57344, 57856, 57888, 
+    57880,     0,     1, 49152, 57344, 57856, 57888, 57880, 
+        0,     1, 49152, 57344, 57856, 57888, 57880, 57882, 
+        0,     1, 49152, 57344, 57856, 57888, 57880,     0, 
+        1, 49152, 57344, 57856, 57888, 57889, 57884,     0, 
+        1, 49152, 57344, 57856, 57888, 57889, 57884,     0, 
+        1, 49152, 57344, 57856, 57888, 57889, 57884, 57886, 
+        0,     1, 49152, 57344, 57856,     0,     1, 49152, 
+    57344, 57856, 57888,     0,     1, 49152, 57344, 57856, 
+    57888,     0,     1, 49152, 57344, 57856, 57888, 57890, 
+        0,     1, 49152, 57344, 57856, 57888,     0,     1, 
+    49152, 57344, 57856, 57888, 57892,     0,     1, 49152, 
+    57344, 57856, 57888, 57892,     0,     1, 49152, 57344, 
+    57856, 57888, 57896, 57894,     0,     1, 49152, 57344, 
+    57856, 57888,     0,     1, 49152, 57344, 57856, 57888, 
+    57896,     0,     1, 49152, 57344, 57856, 57888, 57896, 
+        0,     1, 49152, 57344, 57856, 57888, 57896, 57898, 
+        0,     1, 49152, 57344, 57856, 57888, 57896,     0, 
+        1, 49152, 57344, 57856, 57888, 57904, 57900,     0, 
+        1, 49152, 57344, 57856, 57888, 57904, 57900,     0, 
+        1, 49152, 57344, 57856, 57888, 57904, 57905, 57902, 
+        0,     1, 49152, 57344, 57856, 57888,     0,     1, 
+    49152, 57344, 57856, 57920, 57904,     0,     1, 49152, 
+    57344, 57856, 57920, 57904,     0,     1, 49152, 57344, 
+    57856, 57920, 57904, 57906,     0,     1, 49152, 57344, 
+    57856, 57920, 57904,     0,     1, 49152, 57344, 57856, 
+    57920, 57904, 57908,     0,     1, 49152, 57344, 57856, 
+    57920, 57904, 57908,     0,     1, 49152, 57344, 57856, 
+    57920, 57904, 57912, 57910,     0,     1, 49152, 57344, 
+    57856, 57920, 57904,     0,     1, 49152, 57344, 57856, 
+    57920, 57921, 57912,     0,     1, 49152, 57344, 57856, 
+    57920, 57921, 57912,     0,     1, 49152, 57344, 57856, 
+    57920, 57921, 57912, 57914,     0,     1, 49152, 57344, 
+    57856, 57920, 57921, 57912,     0,     1, 49152, 57344, 
+    57856, 57920, 57921, 57912, 57916,     0,     1, 49152, 
+    57344, 57856, 57920, 57921, 57923, 57916,     0,     1, 
+    49152, 57344, 57856, 57920, 57921, 57923, 57916, 57918, 
+        0,     1, 49152, 57344, 57856,     0,     1, 49152, 
+    57344, 57856, 57920,     0,     1, 49152, 57344, 57856, 
+    57920,     0,     1, 49152, 57344, 57856, 57920, 57922, 
+        0,     1, 49152, 57344, 57856, 57920,     0,     1, 
+    49152, 57344, 57856, 57920, 57924,     0,     1, 49152, 
+    57344, 57856, 57920, 57924,     0,     1, 49152, 57344, 
+    57856, 57920, 57928, 57926,     0,     1, 49152, 57344, 
+    57856, 57920,     0,     1, 49152, 57344, 57856, 57920, 
+    57928,     0,     1, 49152, 57344, 57856, 57920, 57928, 
+        0,     1, 49152, 57344, 57856, 57920, 57928, 57930, 
+        0,     1, 49152, 57344, 57856, 57920, 57928,     0, 
+        1, 49152, 57344, 57856, 57920, 57936, 57932,     0, 
+        1, 49152, 57344, 57856, 57920, 57936, 57932,     0, 
+        1, 49152, 57344, 57856, 57920, 57936, 57937, 57934, 
+        0,     1, 49152, 57344, 57856, 57920,     0,     1, 
+    49152, 57344, 57856, 57920, 57936,     0,     1, 49152, 
+    57344, 57856, 57920, 57936,     0,     1, 49152, 57344, 
+    57856, 57920, 57936, 57938,     0,     1, 49152, 57344, 
+    57856, 57920, 57936,     0,     1, 49152, 57344, 57856, 
+    57920, 57936, 57940,     0,     1, 49152, 57344, 57856, 
+    57920, 57936, 57940,     0,     1, 49152, 57344, 57856, 
+    57920, 57936, 57944, 57942,     0,     1, 49152, 57344, 
+    57856, 57920, 57936,     0,     1, 49152, 57344, 57856, 
+    57920, 57952, 57944,     0,     1, 49152, 57344, 57856, 
+    57920, 57952, 57944,     0,     1, 49152, 57344, 57856, 
+    57920, 57952, 57944, 57946,     0,     1, 49152, 57344, 
+    57856, 57920, 57952, 57944,     0,     1, 49152, 57344, 
+    57856, 57920, 57952, 57953, 57948,     0,     1, 49152, 
+    57344, 57856, 57920, 57952, 57953, 57948,     0,     1, 
+    49152, 57344, 57856, 57920, 57952, 57953, 57948, 57950, 
+        0,     1, 49152, 57344, 57856, 57920,     0,     1, 
+    49152, 57344, 57856, 57984, 57952,     0,     1, 49152, 
+    57344, 57856, 57984, 57952,     0,     1, 49152, 57344, 
+    57856, 57984, 57952, 57954,     0,     1, 49152, 57344, 
+    57856, 57984, 57952,     0,     1, 49152, 57344, 57856, 
+    57984, 57952, 57956,     0,     1, 49152, 57344, 57856, 
+    57984, 57952, 57956,     0,     1, 49152, 57344, 57856, 
+    57984, 57952, 57960, 57958,     0,     1, 49152, 57344, 
+    57856, 57984, 57952,     0,     1, 49152, 57344, 57856, 
+    57984, 57952, 57960,     0,     1, 49152, 57344, 57856, 
+    57984, 57952, 57960,     0,     1, 49152, 57344, 57856, 
+    57984, 57952, 57960, 57962,     0,     1, 49152, 57344, 
+    57856, 57984, 57952, 57960,     0,     1, 49152, 57344, 
+    57856, 57984, 57952, 57968, 57964,     0,     1, 49152, 
+    57344, 57856, 57984, 57952, 57968, 57964,     0,     1, 
+    49152, 57344, 57856, 57984, 57952, 57968, 57969, 57966, 
+        0,     1, 49152, 57344, 57856, 57984, 57952,     0, 
+        1, 49152, 57344, 57856, 57984, 57985, 57968,     0, 
+        1, 49152, 57344, 57856, 57984, 57985, 57968,     0, 
+        1, 49152, 57344, 57856, 57984, 57985, 57968, 57970, 
+        0,     1, 49152, 57344, 57856, 57984, 57985, 57968, 
+        0,     1, 49152, 57344, 57856, 57984, 57985, 57968, 
+    57972,     0,     1, 49152, 57344, 57856, 57984, 57985, 
+    57968, 57972,     0,     1, 49152, 57344, 57856, 57984, 
+    57985, 57968, 57976, 57974,     0,     1, 49152, 57344, 
+    57856, 57984, 57985, 57968,     0,     1, 49152, 57344, 
+    57856, 57984, 57985, 57968, 57976,     0,     1, 49152, 
+    57344, 57856, 57984, 57985, 57987, 57976,     0,     1, 
+    49152, 57344, 57856, 57984, 57985, 57987, 57976, 57978, 
+        0,     1, 49152, 57344, 57856, 57984, 57985, 57987, 
+    57976,     0,     1, 49152, 57344, 57856, 57984, 57985, 
+    57987, 57976, 57980,     0,     1, 49152, 57344, 57856, 
+    57984, 57985, 57987, 57976, 57980,     0,     1, 49152, 
+    57344, 57856, 57984, 57985, 57987, 57976, 57980, 57982, 
+        0,     1, 49152, 57344, 57856,     0,     1, 49152, 
+    57344, 57856, 57984,     0,     1, 49152, 57344, 57856, 
+    57984,     0,     1, 49152, 57344, 57856, 57984, 57986, 
+        0,     1, 49152, 57344, 57856, 57984,     0,     1, 
+    49152, 57344, 57856, 57984, 57988,     0,     1, 49152, 
+    57344, 57856, 57984, 57988,     0,     1, 49152, 57344, 
+    57856, 57984, 57992, 57990,     0,     1, 49152, 57344, 
+    57856, 57984,     0,     1, 49152, 57344, 57856, 57984, 
+    57992,     0,     1, 49152, 57344, 57856, 57984, 57992, 
+        0,     1, 49152, 57344, 57856, 57984, 57992, 57994, 
+        0,     1, 49152, 57344, 57856, 57984, 57992,     0, 
+        1, 49152, 57344, 57856, 57984, 58000, 57996,     0, 
+        1, 49152, 57344, 57856, 57984, 58000, 57996,     0, 
+        1, 49152, 57344, 57856, 57984, 58000, 58001, 57998, 
+        0,     1, 49152, 57344, 57856, 57984,     0,     1, 
+    49152, 57344, 57856, 57984, 58000,     0,     1, 49152, 
+    57344, 57856, 57984, 58000,     0,     1, 49152, 57344, 
+    57856, 57984, 58000, 58002,     0,     1, 49152, 57344, 
+    57856, 57984, 58000,     0,     1, 49152, 57344, 57856, 
+    57984, 58000, 58004,     0,     1, 49152, 57344, 57856, 
+    57984, 58000, 58004,     0,     1, 49152, 57344, 57856, 
+    57984, 58000, 58008, 58006,     0,     1, 49152, 57344, 
+    57856, 57984, 58000,     0,     1, 49152, 57344, 57856, 
+    57984, 58016, 58008,     0,     1, 49152, 57344, 57856, 
+    57984, 58016, 58008,     0,     1, 49152, 57344, 57856, 
+    57984, 58016, 58008, 58010,     0,     1, 49152, 57344, 
+    57856, 57984, 58016, 58008,     0,     1, 49152, 57344, 
+    57856, 57984, 58016, 58017, 58012,     0,     1, 49152, 
+    57344, 57856, 57984, 58016, 58017, 58012,     0,     1, 
+    49152, 57344, 57856, 57984, 58016, 58017, 58012, 58014, 
+        0,     1, 49152, 57344, 57856, 57984,     0,     1, 
+    49152, 57344, 57856, 57984, 58016,     0,     1, 49152, 
+    57344, 57856, 57984, 58016,     0,     1, 49152, 57344, 
+    57856, 57984, 58016, 58018,     0,     1, 49152, 57344, 
+    57856, 57984, 58016,     0,     1, 49152, 57344, 57856, 
+    57984, 58016, 58020,     0,     1, 49152, 57344, 57856, 
+    57984, 58016, 58020,     0,     1, 49152, 57344, 57856, 
+    57984, 58016, 58024, 58022,     0,     1, 49152, 57344, 
+    57856, 57984, 58016,     0,     1, 49152, 57344, 57856, 
+    57984, 58016, 58024,     0,     1, 49152, 57344, 57856, 
+    57984, 58016, 58024,     0,     1, 49152, 57344, 57856, 
+    57984, 58016, 58024, 58026,     0,     1, 49152, 57344, 
+    57856, 57984, 58016, 58024,     0,     1, 49152, 57344, 
+    57856, 57984, 58016, 58032, 58028,     0,     1, 49152, 
+    57344, 57856, 57984, 58016, 58032, 58028,     0,     1, 
+    49152, 57344, 57856, 57984, 58016, 58032, 58033, 58030, 
+        0,     1, 49152, 57344, 57856, 57984, 58016,     0, 
+        1, 49152, 57344, 57856, 57984, 58048, 58032,     0, 
+        1, 49152, 57344, 57856, 57984, 58048, 58032,     0, 
+        1, 49152, 57344, 57856, 57984, 58048, 58032, 58034, 
+        0,     1, 49152, 57344, 57856, 57984, 58048, 58032, 
+        0,     1, 49152, 57344, 57856, 57984, 58048, 58032, 
+    58036,     0,     1, 49152, 57344, 57856, 57984, 58048, 
+    58032, 58036,     0,     1, 49152, 57344, 57856, 57984, 
+    58048, 58032, 58040, 58038,     0,     1, 49152, 57344, 
+    57856, 57984, 58048, 58032,     0,     1, 49152, 57344, 
+    57856, 57984, 58048, 58049, 58040,     0,     1, 49152, 
+    57344, 57856, 57984, 58048, 58049, 58040,     0,     1, 
+    49152, 57344, 57856, 57984, 58048, 58049, 58040, 58042, 
+        0,     1, 49152, 57344, 57856, 57984, 58048, 58049, 
+    58040,     0,     1, 49152, 57344, 57856, 57984, 58048, 
+    58049, 58040, 58044,     0,     1, 49152, 57344, 57856, 
+    57984, 58048, 58049, 58051, 58044,     0,     1, 49152, 
+    57344, 57856, 57984, 58048, 58049, 58051, 58044, 58046, 
+        0,     1, 49152, 57344, 57856, 57984,     0,     1, 
+    49152, 57344, 57856, 58112, 58048,     0,     1, 49152, 
+    57344, 57856, 58112, 58048,     0,     1, 49152, 57344, 
+    57856, 58112, 58048, 58050,     0,     1, 49152, 57344, 
+    57856, 58112, 58048,     0,     1, 49152, 57344, 57856, 
+    58112, 58048, 58052,     0,     1, 49152, 57344, 57856, 
+    58112, 58048, 58052,     0,     1, 49152, 57344, 57856, 
+    58112, 58048, 58056, 58054,     0,     1, 49152, 57344, 
+    57856, 58112, 58048,     0,     1, 49152, 57344, 57856, 
+    58112, 58048, 58056,     0,     1, 49152, 57344, 57856, 
+    58112, 58048, 58056,     0,     1, 49152, 57344, 57856, 
+    58112, 58048, 58056, 58058,     0,     1, 49152, 57344, 
+    57856, 58112, 58048, 58056,     0,     1, 49152, 57344, 
+    57856, 58112, 58048, 58064, 58060,     0,     1, 49152, 
+    57344, 57856, 58112, 58048, 58064, 58060,     0,     1, 
+    49152, 57344, 57856, 58112, 58048, 58064, 58065, 58062, 
+        0,     1, 49152, 57344, 57856, 58112, 58048,     0, 
+        1, 49152, 57344, 57856, 58112, 58048, 58064,     0, 
+        1, 49152, 57344, 57856, 58112, 58048, 58064,     0, 
+        1, 49152, 57344, 57856, 58112, 58048, 58064, 58066, 
+        0,     1, 49152, 57344, 57856, 58112, 58048, 58064, 
+        0,     1, 49152, 57344, 57856, 58112, 58048, 58064, 
+    58068,     0,     1, 49152, 57344, 57856, 58112, 58048, 
+    58064, 58068,     0,     1, 49152, 57344, 57856, 58112, 
+    58048, 58064, 58072, 58070,     0,     1, 49152, 57344, 
+    57856, 58112, 58048, 58064,     0,     1, 49152, 57344, 
+    57856, 58112, 58048, 58080, 58072,     0,     1, 49152, 
+    57344, 57856, 58112, 58048, 58080, 58072,     0,     1, 
+    49152, 57344, 57856, 58112, 58048, 58080, 58072, 58074, 
+        0,     1, 49152, 57344, 57856, 58112, 58048, 58080, 
+    58072,     0,     1, 49152, 57344, 57856, 58112, 58048, 
+    58080, 58081, 58076,     0,     1, 49152, 57344, 57856, 
+    58112, 58048, 58080, 58081, 58076,     0,     1, 49152, 
+    57344, 57856, 58112, 58048, 58080, 58081, 58076, 58078, 
+        0,     1, 49152, 57344, 57856, 58112, 58048,     0, 
+        1, 49152, 57344, 57856, 58112, 58113, 58080,     0, 
+        1, 49152, 57344, 57856, 58112, 58113, 58080,     0, 
+        1, 49152, 57344, 57856, 58112, 58113, 58080, 58082, 
+        0,     1, 49152, 57344, 57856, 58112, 58113, 58080, 
+        0,     1, 49152, 57344, 57856, 58112, 58113, 58080, 
+    58084,     0,     1, 49152, 57344, 57856, 58112, 58113, 
+    58080, 58084,     0,     1, 49152, 57344, 57856, 58112, 
+    58113, 58080, 58088, 58086,     0,     1, 49152, 57344, 
+    57856, 58112, 58113, 58080,     0,     1, 49152, 57344, 
+    57856, 58112, 58113, 58080, 58088,     0,     1, 49152, 
+    57344, 57856, 58112, 58113, 58080, 58088,     0,     1, 
+    49152, 57344, 57856, 58112, 58113, 58080, 58088, 58090, 
+        0,     1, 49152, 57344, 57856, 58112, 58113, 58080, 
+    58088,     0,     1, 49152, 57344, 57856, 58112, 58113, 
+    58080, 58096, 58092,     0,     1, 49152, 57344, 57856, 
+    58112, 58113, 58080, 58096, 58092,     0,     1, 49152, 
+    57344, 57856, 58112, 58113, 58080, 58096, 58097, 58094, 
+        0,     1, 49152, 57344, 57856, 58112, 58113, 58080, 
+        0,     1, 49152, 57344, 57856, 58112, 58113, 58080, 
+    58096,     0,     1, 49152, 57344, 57856, 58112, 58113, 
+    58115, 58096,     0,     1, 49152, 57344, 57856, 58112, 
+    58113, 58115, 58096, 58098,     0,     1, 49152, 57344, 
+    57856, 58112, 58113, 58115, 58096,     0,     1, 49152, 
+    57344, 57856, 58112, 58113, 58115, 58096, 58100,     0, 
+        1, 49152, 57344, 57856, 58112, 58113, 58115, 58096, 
+    58100,     0,     1, 49152, 57344, 57856, 58112, 58113, 
+    58115, 58096, 58104, 58102,     0,     1, 49152, 57344, 
+    57856, 58112, 58113, 58115, 58096,     0,     1, 49152, 
+    57344, 57856, 58112, 58113, 58115, 58096, 58104,     0, 
+        1, 49152, 57344, 57856, 58112, 58113, 58115, 58096, 
+    58104,     0,     1, 49152, 57344, 57856, 58112, 58113, 
+    58115, 58096, 58104, 58106,     0,     1, 49152, 57344, 
+    57856, 58112, 58113, 58115, 58119, 58104,     0,     1, 
+    49152, 57344, 57856, 58112, 58113, 58115, 58119, 58104, 
+    58108,     0,     1, 49152, 57344, 57856, 58112, 58113, 
+    58115, 58119, 58104, 58108,     0,     1, 49152, 57344, 
+    57856, 58112, 58113, 58115, 58119, 58104, 58108, 58110, 
+        0,     1, 49152, 57344, 57856,     0,     1, 49152, 
+    57344, 58368, 58112,     0,     1, 49152, 57344, 58368, 
+    58112,     0,     1, 49152, 57344, 58368, 58112, 58114, 
+        0,     1, 49152, 57344, 58368, 58112,     0,     1, 
+    49152, 57344, 58368, 58112, 58116,     0,     1, 49152, 
+    57344, 58368, 58112, 58116,     0,     1, 49152, 57344, 
+    58368, 58112, 58120, 58118,     0,     1, 49152, 57344, 
+    58368, 58112,     0,     1, 49152, 57344, 58368, 58112, 
+    58120,     0,     1, 49152, 57344, 58368, 58112, 58120, 
+        0,     1, 49152, 57344, 58368, 58112, 58120, 58122, 
+        0,     1, 49152, 57344, 58368, 58112, 58120,     0, 
+        1, 49152, 57344, 58368, 58112, 58128, 58124,     0, 
+        1, 49152, 57344, 58368, 58112, 58128, 58124,     0, 
+        1, 49152, 57344, 58368, 58112, 58128, 58129, 58126, 
+        0,     1, 49152, 57344, 58368, 58112,     0,     1, 
+    49152, 57344, 58368, 58112, 58128,     0,     1, 49152, 
+    57344, 58368, 58112, 58128,     0,     1, 49152, 57344, 
+    58368, 58112, 58128, 58130,     0,     1, 49152, 57344, 
+    58368, 58112, 58128,     0,     1, 49152, 57344, 58368, 
+    58112, 58128, 58132,     0,     1, 49152, 57344, 58368, 
+    58112, 58128, 58132,     0,     1, 49152, 57344, 58368, 
+    58112, 58128, 58136, 58134,     0,     1, 49152, 57344, 
+    58368, 58112, 58128,     0,     1, 49152, 57344, 58368, 
+    58112, 58144, 58136,     0,     1, 49152, 57344, 58368, 
+    58112, 58144, 58136,     0,     1, 49152, 57344, 58368, 
+    58112, 58144, 58136, 58138,     0,     1, 49152, 57344, 
+    58368, 58112, 58144, 58136,     0,     1, 49152, 57344, 
+    58368, 58112, 58144, 58145, 58140,     0,     1, 49152, 
+    57344, 58368, 58112, 58144, 58145, 58140,     0,     1, 
+    49152, 57344, 58368, 58112, 58144, 58145, 58140, 58142, 
+        0,     1, 49152, 57344, 58368, 58112,     0,     1, 
+    49152, 57344, 58368, 58112, 58144,     0,     1, 49152, 
+    57344, 58368, 58112, 58144,     0,     1, 49152, 57344, 
+    58368, 58112, 58144, 58146,     0,     1, 49152, 57344, 
+    58368, 58112, 58144,     0,     1, 49152, 57344, 58368, 
+    58112, 58144, 58148,     0,     1, 49152, 57344, 58368, 
+    58112, 58144, 58148,     0,     1, 49152, 57344, 58368, 
+    58112, 58144, 58152, 58150,     0,     1, 49152, 57344, 
+    58368, 58112, 58144,     0,     1, 49152, 57344, 58368, 
+    58112, 58144, 58152,     0,     1, 49152, 57344, 58368, 
+    58112, 58144, 58152,     0,     1, 49152, 57344, 58368, 
+    58112, 58144, 58152, 58154,     0,     1, 49152, 57344, 
+    58368, 58112, 58144, 58152,     0,     1, 49152, 57344, 
+    58368, 58112, 58144, 58160, 58156,     0,     1, 49152, 
+    57344, 58368, 58112, 58144, 58160, 58156,     0,     1, 
+    49152, 57344, 58368, 58112, 58144, 58160, 58161, 58158, 
+        0,     1, 49152, 57344, 58368, 58112, 58144,     0, 
+        1, 49152, 57344, 58368, 58112, 58176, 58160,     0, 
+        1, 49152, 57344, 58368, 58112, 58176, 58160,     0, 
+        1, 49152, 57344, 58368, 58112, 58176, 58160, 58162, 
+        0,     1, 49152, 57344, 58368, 58112, 58176, 58160, 
+        0,     1, 49152, 57344, 58368, 58112, 58176, 58160, 
+    58164,     0,     1, 49152, 57344, 58368, 58112, 58176, 
+    58160, 58164,     0,     1, 49152, 57344, 58368, 58112, 
+    58176, 58160, 58168, 58166,     0,     1, 49152, 57344, 
+    58368, 58112, 58176, 58160,     0,     1, 49152, 57344, 
+    58368, 58112, 58176, 58177, 58168,     0,     1, 49152, 
+    57344, 58368, 58112, 58176, 58177, 58168,     0,     1, 
+    49152, 57344, 58368, 58112, 58176, 58177, 58168, 58170, 
+        0,     1, 49152, 57344, 58368, 58112, 58176, 58177, 
+    58168,     0,     1, 49152, 57344, 58368, 58112, 58176, 
+    58177, 58168, 58172,     0,     1, 49152, 57344, 58368, 
+    58112, 58176, 58177, 58179, 58172,     0,     1, 49152, 
+    57344, 58368, 58112, 58176, 58177, 58179, 58172, 58174, 
+        0,     1, 49152, 57344, 58368, 58112,     0,     1, 
+    49152, 57344, 58368, 58112, 58176,     0,     1, 49152, 
+    57344, 58368, 58112, 58176,     0,     1, 49152, 57344, 
+    58368, 58112, 58176, 58178,     0,     1, 49152, 57344, 
+    58368, 58112, 58176,     0,     1, 49152, 57344, 58368, 
+    58112, 58176, 58180,     0,     1, 49152, 57344, 58368, 
+    58112, 58176, 58180,     0,     1, 49152, 57344, 58368, 
+    58112, 58176, 58184, 58182,     0,     1, 49152, 57344, 
+    58368, 58112, 58176,     0,     1, 49152, 57344, 58368, 
+    58112, 58176, 58184,     0,     1, 49152, 57344, 58368, 
+    58112, 58176, 58184,     0,     1, 49152, 57344, 58368, 
+    58112, 58176, 58184, 58186,     0,     1, 49152, 57344, 
+    58368, 58112, 58176, 58184,     0,     1, 49152, 57344, 
+    58368, 58112, 58176, 58192, 58188,     0,     1, 49152, 
+    57344, 58368, 58112, 58176, 58192, 58188,     0,     1, 
+    49152, 57344, 58368, 58112, 58176, 58192, 58193, 58190, 
+        0,     1, 49152, 57344, 58368, 58112, 58176,     0, 
+        1, 49152, 57344, 58368, 58112, 58176, 58192,     0, 
+        1, 49152, 57344, 58368, 58112, 58176, 58192,     0, 
+        1, 49152, 57344, 58368, 58112, 58176, 58192, 58194, 
+        0,     1, 49152, 57344, 58368, 58112, 58176, 58192, 
+        0,     1, 49152, 57344, 58368, 58112, 58176, 58192, 
+    58196,     0,     1, 49152, 57344, 58368, 58112, 58176, 
+    58192, 58196,     0,     1, 49152, 57344, 58368, 58112, 
+    58176, 58192, 58200, 58198,     0,     1, 49152, 57344, 
+    58368, 58112, 58176, 58192,     0,     1, 49152, 57344, 
+    58368, 58112, 58176, 58208, 58200,     0,     1, 49152, 
+    57344, 58368, 58112, 58176, 58208, 58200,     0,     1, 
+    49152, 57344, 58368, 58112, 58176, 58208, 58200, 58202, 
+        0,     1, 49152, 57344, 58368, 58112, 58176, 58208, 
+    58200,     0,     1, 49152, 57344, 58368, 58112, 58176, 
+    58208, 58209, 58204,     0,     1, 49152, 57344, 58368, 
+    58112, 58176, 58208, 58209, 58204,     0,     1, 49152, 
+    57344, 58368, 58112, 58176, 58208, 58209, 58204, 58206, 
+        0,     1, 49152, 57344, 58368, 58112, 58176,     0, 
+        1, 49152, 57344, 58368, 58112, 58240, 58208,     0, 
+        1, 49152, 57344, 58368, 58112, 58240, 58208,     0, 
+        1, 49152, 57344, 58368, 58112, 58240, 58208, 58210, 
+        0,     1, 49152, 57344, 58368, 58112, 58240, 58208, 
+        0,     1, 49152, 57344, 58368, 58112, 58240, 58208, 
+    58212,     0,     1, 49152, 57344, 58368, 58112, 58240, 
+    58208, 58212,     0,     1, 49152, 57344, 58368, 58112, 
+    58240, 58208, 58216, 58214,     0,     1, 49152, 57344, 
+    58368, 58112, 58240, 58208,     0,     1, 49152, 57344, 
+    58368, 58112, 58240, 58208, 58216,     0,     1, 49152, 
+    57344, 58368, 58112, 58240, 58208, 58216,     0,     1, 
+    49152, 57344, 58368, 58112, 58240, 58208, 58216, 58218, 
+        0,     1, 49152, 57344, 58368, 58112, 58240, 58208, 
+    58216,     0,     1, 49152, 57344, 58368, 58112, 58240, 
+    58208, 58224, 58220,     0,     1, 49152, 57344, 58368, 
+    58112, 58240, 58208, 58224, 58220,     0,     1, 49152, 
+    57344, 58368, 58112, 58240, 58208, 58224, 58225, 58222, 
+        0,     1, 49152, 57344, 58368, 58112, 58240, 58208, 
+        0,     1, 49152, 57344, 58368, 58112, 58240, 58241, 
+    58224,     0,     1, 49152, 57344, 58368, 58112, 58240, 
+    58241, 58224,     0,     1, 49152, 57344, 58368, 58112, 
+    58240, 58241, 58224, 58226,     0,     1, 49152, 57344, 
+    58368, 58112, 58240, 58241, 58224,     0,     1, 49152, 
+    57344, 58368, 58112, 58240, 58241, 58224, 58228,     0, 
+        1, 49152, 57344, 58368, 58112, 58240, 58241, 58224, 
+    58228,     0,     1, 49152, 57344, 58368, 58112, 58240, 
+    58241, 58224, 58232, 58230,     0,     1, 49152, 57344, 
+    58368, 58112, 58240, 58241, 58224,     0,     1, 49152, 
+    57344, 58368, 58112, 58240, 58241, 58224, 58232,     0, 
+        1, 49152, 57344, 58368, 58112, 58240, 58241, 58243, 
+    58232,     0,     1, 49152, 57344, 58368, 58112, 58240, 
+    58241, 58243, 58232, 58234,     0,     1, 49152, 57344, 
+    58368, 58112, 58240, 58241, 58243, 58232,     0,     1, 
+    49152, 57344, 58368, 58112, 58240, 58241, 58243, 58232, 
+    58236,     0,     1, 49152, 57344, 58368, 58112, 58240, 
+    58241, 58243, 58232, 58236,     0,     1, 49152, 57344, 
+    58368, 58112, 58240, 58241, 58243, 58232, 58236, 58238, 
+        0,     1, 49152, 57344, 58368, 58112,     0,     1, 
+    49152, 57344, 58368, 58112, 58240,     0,     1, 49152, 
+    57344, 58368, 58369, 58240,     0,     1, 49152, 57344, 
+    58368, 58369, 58240, 58242,     0,     1, 49152, 57344, 
+    58368, 58369, 58240,     0,     1, 49152, 57344, 58368, 
+    58369, 58240, 58244,     0,     1, 49152, 57344, 58368, 
+    58369, 58240, 58244,     0,     1, 49152, 57344, 58368, 
+    58369, 58240, 58248, 58246,     0,     1, 49152, 57344, 
+    58368, 58369, 58240,     0,     1, 49152, 57344, 58368, 
+    58369, 58240, 58248,     0,     1, 49152, 57344, 58368, 
+    58369, 58240, 58248,     0,     1, 49152, 57344, 58368, 
+    58369, 58240, 58248, 58250,     0,     1, 49152, 57344, 
+    58368, 58369, 58240, 58248,     0,     1, 49152, 57344, 
+    58368, 58369, 58240, 58256, 58252,     0,     1, 49152, 
+    57344, 58368, 58369, 58240, 58256, 58252,     0,     1, 
+    49152, 57344, 58368, 58369, 58240, 58256, 58257, 58254, 
+        0,     1, 49152, 57344, 58368, 58369, 58240,     0, 
+        1, 49152, 57344, 58368, 58369, 58240, 58256,     0, 
+        1, 49152, 57344, 58368, 58369, 58240, 58256,     0, 
+        1, 49152, 57344, 58368, 58369, 58240, 58256, 58258, 
+        0,     1, 49152, 57344, 58368, 58369, 58240, 58256, 
+        0,     1, 49152, 57344, 58368, 58369, 58240, 58256, 
+    58260,     0,     1, 49152, 57344, 58368, 58369, 58240, 
+    58256, 58260,     0,     1, 49152, 57344, 58368, 58369, 
+    58240, 58256, 58264, 58262,     0,     1, 49152, 57344, 
+    58368, 58369, 58240, 58256,     0,     1, 49152, 57344, 
+    58368, 58369, 58240, 58272, 58264,     0,     1, 49152, 
+    57344, 58368, 58369, 58240, 58272, 58264,     0,     1, 
+    49152, 57344, 58368, 58369, 58240, 58272, 58264, 58266, 
+        0,     1, 49152, 57344, 58368, 58369, 58240, 58272, 
+    58264,     0,     1, 49152, 57344, 58368, 58369, 58240, 
+    58272, 58273, 58268,     0,     1, 49152, 57344, 58368, 
+    58369, 58240, 58272, 58273, 58268,     0,     1, 49152, 
+    57344, 58368, 58369, 58240, 58272, 58273, 58268, 58270, 
+        0,     1, 49152, 57344, 58368, 58369, 58240,     0, 
+        1, 49152, 57344, 58368, 58369, 58240, 58272,     0, 
+        1, 49152, 57344, 58368, 58369, 58240, 58272,     0, 
+        1, 49152, 57344, 58368, 58369, 58240, 58272, 58274, 
+        0,     1, 49152, 57344, 58368, 58369, 58240, 58272, 
+        0,     1, 49152, 57344, 58368, 58369, 58240, 58272, 
+    58276,     0,     1, 49152, 57344, 58368, 58369, 58240, 
+    58272, 58276,     0,     1, 49152, 57344, 58368, 58369, 
+    58240, 58272, 58280, 58278,     0,     1, 49152, 57344, 
+    58368, 58369, 58240, 58272,     0,     1, 49152, 57344, 
+    58368, 58369, 58240, 58272, 58280,     0,     1, 49152, 
+    57344, 58368, 58369, 58240, 58272, 58280,     0,     1, 
+    49152, 57344, 58368, 58369, 58240, 58272, 58280, 58282, 
+        0,     1, 49152, 57344, 58368, 58369, 58240, 58272, 
+    58280,     0,     1, 49152, 57344, 58368, 58369, 58240, 
+    58272, 58288, 58284,     0,     1, 49152, 57344, 58368, 
+    58369, 58240, 58272, 58288, 58284,     0,     1, 49152, 
+    57344, 58368, 58369, 58240, 58272, 58288, 58289, 58286, 
+        0,     1, 49152, 57344, 58368, 58369, 58240, 58272, 
+        0,     1, 49152, 57344, 58368, 58369, 58240, 58304, 
+    58288,     0,     1, 49152, 57344, 58368, 58369, 58240, 
+    58304, 58288,     0,     1, 49152, 57344, 58368, 58369, 
+    58240, 58304, 58288, 58290,     0,     1, 49152, 57344, 
+    58368, 58369, 58240, 58304, 58288,     0,     1, 49152, 
+    57344, 58368, 58369, 58240, 58304, 58288, 58292,     0, 
+        1, 49152, 57344, 58368, 58369, 58240, 58304, 58288, 
+    58292,     0,     1, 49152, 57344, 58368, 58369, 58240, 
+    58304, 58288, 58296, 58294,     0,     1, 49152, 57344, 
+    58368, 58369, 58240, 58304, 58288,     0,     1, 49152, 
+    57344, 58368, 58369, 58240, 58304, 58305, 58296,     0, 
+        1, 49152, 57344, 58368, 58369, 58240, 58304, 58305, 
+    58296,     0,     1, 49152, 57344, 58368, 58369, 58240, 
+    58304, 58305, 58296, 58298,     0,     1, 49152, 57344, 
+    58368, 58369, 58240, 58304, 58305, 58296,     0,     1, 
+    49152, 57344, 58368, 58369, 58240, 58304, 58305, 58296, 
+    58300,     0,     1, 49152, 57344, 58368, 58369, 58240, 
+    58304, 58305, 58307, 58300,     0,     1, 49152, 57344, 
+    58368, 58369, 58240, 58304, 58305, 58307, 58300, 58302, 
+        0,     1, 49152, 57344, 58368, 58369, 58240,     0, 
+        1, 49152, 57344, 58368, 58369, 58240, 58304,     0, 
+        1, 49152, 57344, 58368, 58369, 58240, 58304,     0, 
+        1, 49152, 57344, 58368, 58369, 58240, 58304, 58306, 
+        0,     1, 49152, 57344, 58368, 58369, 58371, 58304, 
+        0,     1, 49152, 57344, 58368, 58369, 58371, 58304, 
+    58308,     0,     1, 49152, 57344, 58368, 58369, 58371, 
+    58304, 58308,     0,     1, 49152, 57344, 58368, 58369, 
+    58371, 58304, 58312, 58310,     0,     1, 49152, 57344, 
+    58368, 58369, 58371, 58304,     0,     1, 49152, 57344, 
+    58368, 58369, 58371, 58304, 58312,     0,     1, 49152, 
+    57344, 58368, 58369, 58371, 58304, 58312,     0,     1, 
+    49152, 57344, 58368, 58369, 58371, 58304, 58312, 58314, 
+        0,     1, 49152, 57344, 58368, 58369, 58371, 58304, 
+    58312,     0,     1, 49152, 57344, 58368, 58369, 58371, 
+    58304, 58320, 58316,     0,     1, 49152, 57344, 58368, 
+    58369, 58371, 58304, 58320, 58316,     0,     1, 49152, 
+    57344, 58368, 58369, 58371, 58304, 58320, 58321, 58318, 
+        0,     1, 49152, 57344, 58368, 58369, 58371, 58304, 
+        0,     1, 49152, 57344, 58368, 58369, 58371, 58304, 
+    58320,     0,     1, 49152, 57344, 58368, 58369, 58371, 
+    58304, 58320,     0,     1, 49152, 57344, 58368, 58369, 
+    58371, 58304, 58320, 58322,     0,     1, 49152, 57344, 
+    58368, 58369, 58371, 58304, 58320,     0,     1, 49152, 
+    57344, 58368, 58369, 58371, 58304, 58320, 58324,     0, 
+        1, 49152, 57344, 58368, 58369, 58371, 58304, 58320, 
+    58324,     0,     1, 49152, 57344, 58368, 58369, 58371, 
+    58304, 58320, 58328, 58326,     0,     1, 49152, 57344, 
+    58368, 58369, 58371, 58304, 58320,     0,     1, 49152, 
+    57344, 58368, 58369, 58371, 58304, 58336, 58328,     0, 
+        1, 49152, 57344, 58368, 58369, 58371, 58304, 58336, 
+    58328,     0,     1, 49152, 57344, 58368, 58369, 58371, 
+    58304, 58336, 58328, 58330,     0,     1, 49152, 57344, 
+    58368, 58369, 58371, 58304, 58336, 58328,     0,     1, 
+    49152, 57344, 58368, 58369, 58371, 58304, 58336, 58337, 
+    58332,     0,     1, 49152, 57344, 58368, 58369, 58371, 
+    58304, 58336, 58337, 58332,     0,     1, 49152, 57344, 
+    58368, 58369, 58371, 58304, 58336, 58337, 58332, 58334, 
+        0,     1, 49152, 57344, 58368, 58369, 58371, 58304, 
+        0,     1, 49152, 57344, 58368, 58369, 58371, 58304, 
+    58336,     0,     1, 49152, 57344, 58368, 58369, 58371, 
+    58304, 58336,     0,     1, 49152, 57344, 58368, 58369, 
+    58371, 58304, 58336, 58338,     0,     1, 49152, 57344, 
+    58368, 58369, 58371, 58304, 58336,     0,     1, 49152, 
+    57344, 58368, 58369, 58371, 58304, 58336, 58340,     0, 
+        1, 49152, 57344, 58368, 58369, 58371, 58304, 58336, 
+    58340,     0,     1, 49152, 57344, 58368, 58369, 58371, 
+    58304, 58336, 58344, 58342,     0,     1, 49152, 57344, 
+    58368, 58369, 58371, 58375, 58336,     0,     1, 49152, 
+    57344, 58368, 58369, 58371, 58375, 58336, 58344,     0, 
+        1, 49152, 57344, 58368, 58369, 58371, 58375, 58336, 
+    58344,     0,     1, 49152, 57344, 58368, 58369, 58371, 
+    58375, 58336, 58344, 58346,     0,     1, 49152, 57344, 
+    58368, 58369, 58371, 58375, 58336, 58344,     0,     1, 
+    49152, 57344, 58368, 58369, 58371, 58375, 58336, 58352, 
+    58348,     0,     1, 49152, 57344, 58368, 58369, 58371, 
+    58375, 58336, 58352, 58348,     0,     1, 49152, 57344, 
+    58368, 58369, 58371, 58375, 58336, 58352, 58353, 58350, 
+        0,     1, 49152, 57344, 58368, 58369, 58371, 58375, 
+    58336,     0,     1, 49152, 57344, 58368, 58369, 58371, 
+    58375, 58336, 58352,     0,     1, 49152, 57344, 58368, 
+    58369, 58371, 58375, 58336, 58352,     0,     1, 49152, 
+    57344, 58368, 58369, 58371, 58375, 58336, 58352, 58354, 
+        0,     1, 49152, 57344, 58368, 58369, 58371, 58375, 
+    58336, 58352,     0,     1, 49152, 57344, 58368, 58369, 
+    58371, 58375, 58336, 58352, 58356,     0,     1, 49152, 
+    57344, 58368, 58369, 58371, 58375, 58336, 58352, 58356, 
+        0,     1, 49152, 57344, 58368, 58369, 58371, 58375, 
+    58336, 58352, 58360, 58358,     0,     1, 49152, 57344, 
+    58368, 58369, 58371, 58375, 58336, 58352,     0,     1, 
+    49152, 57344, 58368, 58369, 58371, 58375, 58336, 58352, 
+    58360,     0,     1, 49152, 57344, 58368, 58369, 58371, 
+    58375, 58336, 58352, 58360,     0,     1, 49152, 57344, 
+    58368, 58369, 58371, 58375, 58336, 58352, 58360, 58362, 
+        0,     1, 49152, 57344, 58368, 58369, 58371, 58375, 
+    58336, 58352, 58360,     0,     1, 49152, 57344, 58368, 
+    58369, 58371, 58375, 58336, 58352, 58360, 58364,     0, 
+        1, 49152, 57344, 58368, 58369, 58371, 58375, 58336, 
+    58352, 58360, 58364,     0,     1, 49152, 57344, 58368, 
+    58369, 58371, 58375, 58336, 58352, 58360, 58364, 58366, 
+        0,     1, 49152, 57344,     0,     1, 49152, 57344, 
+    58368,     0,     1, 49152, 57344, 58368,     0,     1, 
+    49152, 57344, 58368, 58370,     0,     1, 49152, 57344, 
+    58368,     0,     1, 49152, 57344, 58368, 58372,     0, 
+        1, 49152, 57344, 58368, 58372,     0,     1, 49152, 
+    57344, 58368, 58376, 58374,     0,     1, 49152, 57344, 
+    58368,     0,     1, 49152, 57344, 58368, 58376,     0, 
+        1, 49152, 57344, 58368, 58376,     0,     1, 49152, 
+    57344, 58368, 58376, 58378,     0,     1, 49152, 57344, 
+    58368, 58376,     0,     1, 49152, 57344, 58368, 58384, 
+    58380,     0,     1, 49152, 57344, 58368, 58384, 58380, 
+        0,     1, 49152, 57344, 58368, 58384, 58385, 58382, 
+        0,     1, 49152, 57344, 58368,     0,     1, 49152, 
+    57344, 58368, 58384,     0,     1, 49152, 57344, 58368, 
+    58384,     0,     1, 49152, 57344, 58368, 58384, 58386, 
+        0,     1, 49152, 57344, 58368, 58384,     0,     1, 
+    49152, 57344, 58368, 58384, 58388,     0,     1, 49152, 
+    57344, 58368, 58384, 58388,     0,     1, 49152, 57344, 
+    58368, 58384, 58392, 58390,     0,     1, 49152, 57344, 
+    58368, 58384,     0,     1, 49152, 57344, 58368, 58400, 
+    58392,     0,     1, 49152, 57344, 58368, 58400, 58392, 
+        0,     1, 49152, 57344, 58368, 58400, 58392, 58394, 
+        0,     1, 49152, 57344, 58368, 58400, 58392,     0, 
+        1, 49152, 57344, 58368, 58400, 58401, 58396,     0, 
+        1, 49152, 57344, 58368, 58400, 58401, 58396,     0, 
+        1, 49152, 57344, 58368, 58400, 58401, 58396, 58398, 
+        0,     1, 49152, 57344, 58368,     0,     1, 49152, 
+    57344, 58368, 58400,     0,     1, 49152, 57344, 58368, 
+    58400,     0,     1, 49152, 57344, 58368, 58400, 58402, 
+        0,     1, 49152, 57344, 58368, 58400,     0,     1, 
+    49152, 57344, 58368, 58400, 58404,     0,     1, 49152, 
+    57344, 58368, 58400, 58404,     0,     1, 49152, 57344, 
+    58368, 58400, 58408, 58406,     0,     1, 49152, 57344, 
+    58368, 58400,     0,     1, 49152, 57344, 58368, 58400, 
+    58408,     0,     1, 49152, 57344, 58368, 58400, 58408, 
+        0,     1, 49152, 57344, 58368, 58400, 58408, 58410, 
+        0,     1, 49152, 57344, 58368, 58400, 58408,     0, 
+        1, 49152, 57344, 58368, 58400, 58416, 58412,     0, 
+        1, 49152, 57344, 58368, 58400, 58416, 58412,     0, 
+        1, 49152, 57344, 58368, 58400, 58416, 58417, 58414, 
+        0,     1, 49152, 57344, 58368, 58400,     0,     1, 
+    49152, 57344, 58368, 58432, 58416,     0,     1, 49152, 
+    57344, 58368, 58432, 58416,     0,     1, 49152, 57344, 
+    58368, 58432, 58416, 58418,     0,     1, 49152, 57344, 
+    58368, 58432, 58416,     0,     1, 49152, 57344, 58368, 
+    58432, 58416, 58420,     0,     1, 49152, 57344, 58368, 
+    58432, 58416, 58420,     0,     1, 49152, 57344, 58368, 
+    58432, 58416, 58424, 58422,     0,     1, 49152, 57344, 
+    58368, 58432, 58416,     0,     1, 49152, 57344, 58368, 
+    58432, 58433, 58424,     0,     1, 49152, 57344, 58368, 
+    58432, 58433, 58424,     0,     1, 49152, 57344, 58368, 
+    58432, 58433, 58424, 58426,     0,     1, 49152, 57344, 
+    58368, 58432, 58433, 58424,     0,     1, 49152, 57344, 
+    58368, 58432, 58433, 58424, 58428,     0,     1, 49152, 
+    57344, 58368, 58432, 58433, 58435, 58428,     0,     1, 
+    49152, 57344, 58368, 58432, 58433, 58435, 58428, 58430, 
+        0,     1, 49152, 57344, 58368,     0,     1, 49152, 
+    57344, 58368, 58432,     0,     1, 49152, 57344, 58368, 
+    58432,     0,     1, 49152, 57344, 58368, 58432, 58434, 
+        0,     1, 49152, 57344, 58368, 58432,     0,     1, 
+    49152, 57344, 58368, 58432, 58436,     0,     1, 49152, 
+    57344, 58368, 58432, 58436,     0,     1, 49152, 57344, 
+    58368, 58432, 58440, 58438,     0,     1, 49152, 57344, 
+    58368, 58432,     0,     1, 49152, 57344, 58368, 58432, 
+    58440,     0,     1, 49152, 57344, 58368, 58432, 58440, 
+        0,     1, 49152, 57344, 58368, 58432, 58440, 58442, 
+        0,     1, 49152, 57344, 58368, 58432, 58440,     0, 
+        1, 49152, 57344, 58368, 58432, 58448, 58444,     0, 
+        1, 49152, 57344, 58368, 58432, 58448, 58444,     0, 
+        1, 49152, 57344, 58368, 58432, 58448, 58449, 58446, 
+        0,     1, 49152, 57344, 58368, 58432,     0,     1, 
+    49152, 57344, 58368, 58432, 58448,     0,     1, 49152, 
+    57344, 58368, 58432, 58448,     0,     1, 49152, 57344, 
+    58368, 58432, 58448, 58450,     0,     1, 49152, 57344, 
+    58368, 58432, 58448,     0,     1, 49152, 57344, 58368, 
+    58432, 58448, 58452,     0,     1, 49152, 57344, 58368, 
+    58432, 58448, 58452,     0,     1, 49152, 57344, 58368, 
+    58432, 58448, 58456, 58454,     0,     1, 49152, 57344, 
+    58368, 58432, 58448,     0,     1, 49152, 57344, 58368, 
+    58432, 58464, 58456,     0,     1, 49152, 57344, 58368, 
+    58432, 58464, 58456,     0,     1, 49152, 57344, 58368, 
+    58432, 58464, 58456, 58458,     0,     1, 49152, 57344, 
+    58368, 58432, 58464, 58456,     0,     1, 49152, 57344, 
+    58368, 58432, 58464, 58465, 58460,     0,     1, 49152, 
+    57344, 58368, 58432, 58464, 58465, 58460,     0,     1, 
+    49152, 57344, 58368, 58432, 58464, 58465, 58460, 58462, 
+        0,     1, 49152, 57344, 58368, 58432,     0,     1, 
+    49152, 57344, 58368, 58496, 58464,     0,     1, 49152, 
+    57344, 58368, 58496, 58464,     0,     1, 49152, 57344, 
+    58368, 58496, 58464, 58466,     0,     1, 49152, 57344, 
+    58368, 58496, 58464,     0,     1, 49152, 57344, 58368, 
+    58496, 58464, 58468,     0,     1, 49152, 57344, 58368, 
+    58496, 58464, 58468,     0,     1, 49152, 57344, 58368, 
+    58496, 58464, 58472, 58470,     0,     1, 49152, 57344, 
+    58368, 58496, 58464,     0,     1, 49152, 57344, 58368, 
+    58496, 58464, 58472,     0,     1, 49152, 57344, 58368, 
+    58496, 58464, 58472,     0,     1, 49152, 57344, 58368, 
+    58496, 58464, 58472, 58474,     0,     1, 49152, 57344, 
+    58368, 58496, 58464, 58472,     0,     1, 49152, 57344, 
+    58368, 58496, 58464, 58480, 58476,     0,     1, 49152, 
+    57344, 58368, 58496, 58464, 58480, 58476,     0,     1, 
+    49152, 57344, 58368, 58496, 58464, 58480, 58481, 58478, 
+        0,     1, 49152, 57344, 58368, 58496, 58464,     0, 
+        1, 49152, 57344, 58368, 58496, 58497, 58480,     0, 
+        1, 49152, 57344, 58368, 58496, 58497, 58480,     0, 
+        1, 49152, 57344, 58368, 58496, 58497, 58480, 58482, 
+        0,     1, 49152, 57344, 58368, 58496, 58497, 58480, 
+        0,     1, 49152, 57344, 58368, 58496, 58497, 58480, 
+    58484,     0,     1, 49152, 57344, 58368, 58496, 58497, 
+    58480, 58484,     0,     1, 49152, 57344, 58368, 58496, 
+    58497, 58480, 58488, 58486,     0,     1, 49152, 57344, 
+    58368, 58496, 58497, 58480,     0,     1, 49152, 57344, 
+    58368, 58496, 58497, 58480, 58488,     0,     1, 49152, 
+    57344, 58368, 58496, 58497, 58499, 58488,     0,     1, 
+    49152, 57344, 58368, 58496, 58497, 58499, 58488, 58490, 
+        0,     1, 49152, 57344, 58368, 58496, 58497, 58499, 
+    58488,     0,     1, 49152, 57344, 58368, 58496, 58497, 
+    58499, 58488, 58492,     0,     1, 49152, 57344, 58368, 
+    58496, 58497, 58499, 58488, 58492,     0,     1, 49152, 
+    57344, 58368, 58496, 58497, 58499, 58488, 58492, 58494, 
+        0,     1, 49152, 57344, 58368,     0,     1, 49152, 
+    57344, 58368, 58496,     0,     1, 49152, 57344, 58368, 
+    58496,     0,     1, 49152, 57344, 58368, 58496, 58498, 
+        0,     1, 49152, 57344, 58368, 58496,     0,     1, 
+    49152, 57344, 58368, 58496, 58500,     0,     1, 49152, 
+    57344, 58368, 58496, 58500,     0,     1, 49152, 57344, 
+    58368, 58496, 58504, 58502,     0,     1, 49152, 57344, 
+    58368, 58496,     0,     1, 49152, 57344, 58368, 58496, 
+    58504,     0,     1, 49152, 57344, 58368, 58496, 58504, 
+        0,     1, 49152, 57344, 58368, 58496, 58504, 58506, 
+        0,     1, 49152, 57344, 58368, 58496, 58504,     0, 
+        1, 49152, 57344, 58368, 58496, 58512, 58508,     0, 
+        1, 49152, 57344, 58368, 58496, 58512, 58508,     0, 
+        1, 49152, 57344, 58368, 58496, 58512, 58513, 58510, 
+        0,     1, 49152, 57344, 58368, 58496,     0,     1, 
+    49152, 57344, 58368, 58496, 58512,     0,     1, 49152, 
+    57344, 58368, 58496, 58512,     0,     1, 49152, 57344, 
+    58368, 58496, 58512, 58514,     0,     1, 49152, 57344, 
+    58368, 58496, 58512,     0,     1, 49152, 57344, 58368, 
+    58496, 58512, 58516,     0,     1, 49152, 57344, 58368, 
+    58496, 58512, 58516,     0,     1, 49152, 57344, 58368, 
+    58496, 58512, 58520, 58518,     0,     1, 49152, 57344, 
+    58368, 58496, 58512,     0,     1, 49152, 57344, 58368, 
+    58496, 58528, 58520,     0,     1, 49152, 57344, 58368, 
+    58496, 58528, 58520,     0,     1, 49152, 57344, 58368, 
+    58496, 58528, 58520, 58522,     0,     1, 49152, 57344, 
+    58368, 58496, 58528, 58520,     0,     1, 49152, 57344, 
+    58368, 58496, 58528, 58529, 58524,     0,     1, 49152, 
+    57344, 58368, 58496, 58528, 58529, 58524,     0,     1, 
+    49152, 57344, 58368, 58496, 58528, 58529, 58524, 58526, 
+        0,     1, 49152, 57344, 58368, 58496,     0,     1, 
+    49152, 57344, 58368, 58496, 58528,     0,     1, 49152, 
+    57344, 58368, 58496, 58528,     0,     1, 49152, 57344, 
+    58368, 58496, 58528, 58530,     0,     1, 49152, 57344, 
+    58368, 58496, 58528,     0,     1, 49152, 57344, 58368, 
+    58496, 58528, 58532,     0,     1, 49152, 57344, 58368, 
+    58496, 58528, 58532,     0,     1, 49152, 57344, 58368, 
+    58496, 58528, 58536, 58534,     0,     1, 49152, 57344, 
+    58368, 58496, 58528,     0,     1, 49152, 57344, 58368, 
+    58496, 58528, 58536,     0,     1, 49152, 57344, 58368, 
+    58496, 58528, 58536,     0,     1, 49152, 57344, 58368, 
+    58496, 58528, 58536, 58538,     0,     1, 49152, 57344, 
+    58368, 58496, 58528, 58536,     0,     1, 49152, 57344, 
+    58368, 58496, 58528, 58544, 58540,     0,     1, 49152, 
+    57344, 58368, 58496, 58528, 58544, 58540,     0,     1, 
+    49152, 57344, 58368, 58496, 58528, 58544, 58545, 58542, 
+        0,     1, 49152, 57344, 58368, 58496, 58528,     0, 
+        1, 49152, 57344, 58368, 58496, 58560, 58544,     0, 
+        1, 49152, 57344, 58368, 58496, 58560, 58544,     0, 
+        1, 49152, 57344, 58368, 58496, 58560, 58544, 58546, 
+        0,     1, 49152, 57344, 58368, 58496, 58560, 58544, 
+        0,     1, 49152, 57344, 58368, 58496, 58560, 58544, 
+    58548,     0,     1, 49152, 57344, 58368, 58496, 58560, 
+    58544, 58548,     0,     1, 49152, 57344, 58368, 58496, 
+    58560, 58544, 58552, 58550,     0,     1, 49152, 57344, 
+    58368, 58496, 58560, 58544,     0,     1, 49152, 57344, 
+    58368, 58496, 58560, 58561, 58552,     0,     1, 49152, 
+    57344, 58368, 58496, 58560, 58561, 58552,     0,     1, 
+    49152, 57344, 58368, 58496, 58560, 58561, 58552, 58554, 
+        0,     1, 49152, 57344, 58368, 58496, 58560, 58561, 
+    58552,     0,     1, 49152, 57344, 58368, 58496, 58560, 
+    58561, 58552, 58556,     0,     1, 49152, 57344, 58368, 
+    58496, 58560, 58561, 58563, 58556,     0,     1, 49152, 
+    57344, 58368, 58496, 58560, 58561, 58563, 58556, 58558, 
+        0,     1, 49152, 57344, 58368, 58496,     0,     1, 
+    49152, 57344, 58368, 58624, 58560,     0,     1, 49152, 
+    57344, 58368, 58624, 58560,     0,     1, 49152, 57344, 
+    58368, 58624, 58560, 58562,     0,     1, 49152, 57344, 
+    58368, 58624, 58560,     0,     1, 49152, 57344, 58368, 
+    58624, 58560, 58564,     0,     1, 49152, 57344, 58368, 
+    58624, 58560, 58564,     0,     1, 49152, 57344, 58368, 
+    58624, 58560, 58568, 58566,     0,     1, 49152, 57344, 
+    58368, 58624, 58560,     0,     1, 49152, 57344, 58368, 
+    58624, 58560, 58568,     0,     1, 49152, 57344, 58368, 
+    58624, 58560, 58568,     0,     1, 49152, 57344, 58368, 
+    58624, 58560, 58568, 58570,     0,     1, 49152, 57344, 
+    58368, 58624, 58560, 58568,     0,     1, 49152, 57344, 
+    58368, 58624, 58560, 58576, 58572,     0,     1, 49152, 
+    57344, 58368, 58624, 58560, 58576, 58572,     0,     1, 
+    49152, 57344, 58368, 58624, 58560, 58576, 58577, 58574, 
+        0,     1, 49152, 57344, 58368, 58624, 58560,     0, 
+        1, 49152, 57344, 58368, 58624, 58560, 58576,     0, 
+        1, 49152, 57344, 58368, 58624, 58560, 58576,     0, 
+        1, 49152, 57344, 58368, 58624, 58560, 58576, 58578, 
+        0,     1, 49152, 57344, 58368, 58624, 58560, 58576, 
+        0,     1, 49152, 57344, 58368, 58624, 58560, 58576, 
+    58580,     0,     1, 49152, 57344, 58368, 58624, 58560, 
+    58576, 58580,     0,     1, 49152, 57344, 58368, 58624, 
+    58560, 58576, 58584, 58582,     0,     1, 49152, 57344, 
+    58368, 58624, 58560, 58576,     0,     1, 49152, 57344, 
+    58368, 58624, 58560, 58592, 58584,     0,     1, 49152, 
+    57344, 58368, 58624, 58560, 58592, 58584,     0,     1, 
+    49152, 57344, 58368, 58624, 58560, 58592, 58584, 58586, 
+        0,     1, 49152, 57344, 58368, 58624, 58560, 58592, 
+    58584,     0,     1, 49152, 57344, 58368, 58624, 58560, 
+    58592, 58593, 58588,     0,     1, 49152, 57344, 58368, 
+    58624, 58560, 58592, 58593, 58588,     0,     1, 49152, 
+    57344, 58368, 58624, 58560, 58592, 58593, 58588, 58590, 
+        0,     1, 49152, 57344, 58368, 58624, 58560,     0, 
+        1, 49152, 57344, 58368, 58624, 58625, 58592,     0, 
+        1, 49152, 57344, 58368, 58624, 58625, 58592,     0, 
+        1, 49152, 57344, 58368, 58624, 58625, 58592, 58594, 
+        0,     1, 49152, 57344, 58368, 58624, 58625, 58592, 
+        0,     1, 49152, 57344, 58368, 58624, 58625, 58592, 
+    58596,     0,     1, 49152, 57344, 58368, 58624, 58625, 
+    58592, 58596,     0,     1, 49152, 57344, 58368, 58624, 
+    58625, 58592, 58600, 58598,     0,     1, 49152, 57344, 
+    58368, 58624, 58625, 58592,     0,     1, 49152, 57344, 
+    58368, 58624, 58625, 58592, 58600,     0,     1, 49152, 
+    57344, 58368, 58624, 58625, 58592, 58600,     0,     1, 
+    49152, 57344, 58368, 58624, 58625, 58592, 58600, 58602, 
+        0,     1, 49152, 57344, 58368, 58624, 58625, 58592, 
+    58600,     0,     1, 49152, 57344, 58368, 58624, 58625, 
+    58592, 58608, 58604,     0,     1, 49152, 57344, 58368, 
+    58624, 58625, 58592, 58608, 58604,     0,     1, 49152, 
+    57344, 58368, 58624, 58625, 58592, 58608, 58609, 58606, 
+        0,     1, 49152, 57344, 58368, 58624, 58625, 58592, 
+        0,     1, 49152, 57344, 58368, 58624, 58625, 58592, 
+    58608,     0,     1, 49152, 57344, 58368, 58624, 58625, 
+    58627, 58608,     0,     1, 49152, 57344, 58368, 58624, 
+    58625, 58627, 58608, 58610,     0,     1, 49152, 57344, 
+    58368, 58624, 58625, 58627, 58608,     0,     1, 49152, 
+    57344, 58368, 58624, 58625, 58627, 58608, 58612,     0, 
+        1, 49152, 57344, 58368, 58624, 58625, 58627, 58608, 
+    58612,     0,     1, 49152, 57344, 58368, 58624, 58625, 
+    58627, 58608, 58616, 58614,     0,     1, 49152, 57344, 
+    58368, 58624, 58625, 58627, 58608,     0,     1, 49152, 
+    57344, 58368, 58624, 58625, 58627, 58608, 58616,     0, 
+        1, 49152, 57344, 58368, 58624, 58625, 58627, 58608, 
+    58616,     0,     1, 49152, 57344, 58368, 58624, 58625, 
+    58627, 58608, 58616, 58618,     0,     1, 49152, 57344, 
+    58368, 58624, 58625, 58627, 58631, 58616,     0,     1, 
+    49152, 57344, 58368, 58624, 58625, 58627, 58631, 58616, 
+    58620,     0,     1, 49152, 57344, 58368, 58624, 58625, 
+    58627, 58631, 58616, 58620,     0,     1, 49152, 57344, 
+    58368, 58624, 58625, 58627, 58631, 58616, 58620, 58622, 
+        0,     1, 49152, 57344, 58368,     0,     1, 49152, 
+    57344, 58368, 58624,     0,     1, 49152, 57344, 58368, 
+    58624,     0,     1, 49152, 57344, 58368, 58624, 58626, 
+        0,     1, 49152, 57344, 58368, 58624,     0,     1, 
+    49152, 57344, 58368, 58624, 58628,     0,     1, 49152, 
+    57344, 58368, 58624, 58628,     0,     1, 49152, 57344, 
+    58368, 58624, 58632, 58630,     0,     1, 49152, 57344, 
+    58368, 58624,     0,     1, 49152, 57344, 58368, 58624, 
+    58632,     0,     1, 49152, 57344, 58368, 58624, 58632, 
+        0,     1, 49152, 57344, 58368, 58624, 58632, 58634, 
+        0,     1, 49152, 57344, 58368, 58624, 58632,     0, 
+        1, 49152, 57344, 58368, 58624, 58640, 58636,     0, 
+        1, 49152, 57344, 58368, 58624, 58640, 58636,     0, 
+        1, 49152, 57344, 58368, 58624, 58640, 58641, 58638, 
+        0,     1, 49152, 57344, 58368, 58624,     0,     1, 
+    49152, 57344, 58368, 58624, 58640,     0,     1, 49152, 
+    57344, 58368, 58624, 58640,     0,     1, 49152, 57344, 
+    58368, 58624, 58640, 58642,     0,     1, 49152, 57344, 
+    58368, 58624, 58640,     0,     1, 49152, 57344, 58368, 
+    58624, 58640, 58644,     0,     1, 49152, 57344, 58368, 
+    58624, 58640, 58644,     0,     1, 49152, 57344, 58368, 
+    58624, 58640, 58648, 58646,     0,     1, 49152, 57344, 
+    58368, 58624, 58640,     0,     1, 49152, 57344, 58368, 
+    58624, 58656, 58648,     0,     1, 49152, 57344, 58368, 
+    58624, 58656, 58648,     0,     1, 49152, 57344, 58368, 
+    58624, 58656, 58648, 58650,     0,     1, 49152, 57344, 
+    58368, 58624, 58656, 58648,     0,     1, 49152, 57344, 
+    58368, 58624, 58656, 58657, 58652,     0,     1, 49152, 
+    57344, 58368, 58624, 58656, 58657, 58652,     0,     1, 
+    49152, 57344, 58368, 58624, 58656, 58657, 58652, 58654, 
+        0,     1, 49152, 57344, 58368, 58624,     0,     1, 
+    49152, 57344, 58368, 58624, 58656,     0,     1, 49152, 
+    57344, 58368, 58624, 58656,     0,     1, 49152, 57344, 
+    58368, 58624, 58656, 58658,     0,     1, 49152, 57344, 
+    58368, 58624, 58656,     0,     1, 49152, 57344, 58368, 
+    58624, 58656, 58660,     0,     1, 49152, 57344, 58368, 
+    58624, 58656, 58660,     0,     1, 49152, 57344, 58368, 
+    58624, 58656, 58664, 58662,     0,     1, 49152, 57344, 
+    58368, 58624, 58656,     0,     1, 49152, 57344, 58368, 
+    58624, 58656, 58664,     0,     1, 49152, 57344, 58368, 
+    58624, 58656, 58664,     0,     1, 49152, 57344, 58368, 
+    58624, 58656, 58664, 58666,     0,     1, 49152, 57344, 
+    58368, 58624, 58656, 58664,     0,     1, 49152, 57344, 
+    58368, 58624, 58656, 58672, 58668,     0,     1, 49152, 
+    57344, 58368, 58624, 58656, 58672, 58668,     0,     1, 
+    49152, 57344, 58368, 58624, 58656, 58672, 58673, 58670, 
+        0,     1, 49152, 57344, 58368, 58624, 58656,     0, 
+        1, 49152, 57344, 58368, 58624, 58688, 58672,     0, 
+        1, 49152, 57344, 58368, 58624, 58688, 58672,     0, 
+        1, 49152, 57344, 58368, 58624, 58688, 58672, 58674, 
+        0,     1, 49152, 57344, 58368, 58624, 58688, 58672, 
+        0,     1, 49152, 57344, 58368, 58624, 58688, 58672, 
+    58676,     0,     1, 49152, 57344, 58368, 58624, 58688, 
+    58672, 58676,     0,     1, 49152, 57344, 58368, 58624, 
+    58688, 58672, 58680, 58678,     0,     1, 49152, 57344, 
+    58368, 58624, 58688, 58672,     0,     1, 49152, 57344, 
+    58368, 58624, 58688, 58689, 58680,     0,     1, 49152, 
+    57344, 58368, 58624, 58688, 58689, 58680,     0,     1, 
+    49152, 57344, 58368, 58624, 58688, 58689, 58680, 58682, 
+        0,     1, 49152, 57344, 58368, 58624, 58688, 58689, 
+    58680,     0,     1, 49152, 57344, 58368, 58624, 58688, 
+    58689, 58680, 58684,     0,     1, 49152, 57344, 58368, 
+    58624, 58688, 58689, 58691, 58684,     0,     1, 49152, 
+    57344, 58368, 58624, 58688, 58689, 58691, 58684, 58686, 
+        0,     1, 49152, 57344, 58368, 58624,     0,     1, 
+    49152, 57344, 58368, 58624, 58688,     0,     1, 49152, 
+    57344, 58368, 58624, 58688,     0,     1, 49152, 57344, 
+    58368, 58624, 58688, 58690,     0,     1, 49152, 57344, 
+    58368, 58624, 58688,     0,     1, 49152, 57344, 58368, 
+    58624, 58688, 58692,     0,     1, 49152, 57344, 58368, 
+    58624, 58688, 58692,     0,     1, 49152, 57344, 58368, 
+    58624, 58688, 58696, 58694,     0,     1, 49152, 57344, 
+    58368, 58624, 58688,     0,     1, 49152, 57344, 58368, 
+    58624, 58688, 58696,     0,     1, 49152, 57344, 58368, 
+    58624, 58688, 58696,     0,     1, 49152, 57344, 58368, 
+    58624, 58688, 58696, 58698,     0,     1, 49152, 57344, 
+    58368, 58624, 58688, 58696,     0,     1, 49152, 57344, 
+    58368, 58624, 58688, 58704, 58700,     0,     1, 49152, 
+    57344, 58368, 58624, 58688, 58704, 58700,     0,     1, 
+    49152, 57344, 58368, 58624, 58688, 58704, 58705, 58702, 
+        0,     1, 49152, 57344, 58368, 58624, 58688,     0, 
+        1, 49152, 57344, 58368, 58624, 58688, 58704,     0, 
+        1, 49152, 57344, 58368, 58624, 58688, 58704,     0, 
+        1, 49152, 57344, 58368, 58624, 58688, 58704, 58706, 
+        0,     1, 49152, 57344, 58368, 58624, 58688, 58704, 
+        0,     1, 49152, 57344, 58368, 58624, 58688, 58704, 
+    58708,     0,     1, 49152, 57344, 58368, 58624, 58688, 
+    58704, 58708,     0,     1, 49152, 57344, 58368, 58624, 
+    58688, 58704, 58712, 58710,     0,     1, 49152, 57344, 
+    58368, 58624, 58688, 58704,     0,     1, 49152, 57344, 
+    58368, 58624, 58688, 58720, 58712,     0,     1, 49152, 
+    57344, 58368, 58624, 58688, 58720, 58712,     0,     1, 
+    49152, 57344, 58368, 58624, 58688, 58720, 58712, 58714, 
+        0,     1, 49152, 57344, 58368, 58624, 58688, 58720, 
+    58712,     0,     1, 49152, 57344, 58368, 58624, 58688, 
+    58720, 58721, 58716,     0,     1, 49152, 57344, 58368, 
+    58624, 58688, 58720, 58721, 58716,     0,     1, 49152, 
+    57344, 58368, 58624, 58688, 58720, 58721, 58716, 58718, 
+        0,     1, 49152, 57344, 58368, 58624, 58688,     0, 
+        1, 49152, 57344, 58368, 58624, 58752, 58720,     0, 
+        1, 49152, 57344, 58368, 58624, 58752, 58720,     0, 
+        1, 49152, 57344, 58368, 58624, 58752, 58720, 58722, 
+        0,     1, 49152, 57344, 58368, 58624, 58752, 58720, 
+        0,     1, 49152, 57344, 58368, 58624, 58752, 58720, 
+    58724,     0,     1, 49152, 57344, 58368, 58624, 58752, 
+    58720, 58724,     0,     1, 49152, 57344, 58368, 58624, 
+    58752, 58720, 58728, 58726,     0,     1, 49152, 57344, 
+    58368, 58624, 58752, 58720,     0,     1, 49152, 57344, 
+    58368, 58624, 58752, 58720, 58728,     0,     1, 49152, 
+    57344, 58368, 58624, 58752, 58720, 58728,     0,     1, 
+    49152, 57344, 58368, 58624, 58752, 58720, 58728, 58730, 
+        0,     1, 49152, 57344, 58368, 58624, 58752, 58720, 
+    58728,     0,     1, 49152, 57344, 58368, 58624, 58752, 
+    58720, 58736, 58732,     0,     1, 49152, 57344, 58368, 
+    58624, 58752, 58720, 58736, 58732,     0,     1, 49152, 
+    57344, 58368, 58624, 58752, 58720, 58736, 58737, 58734, 
+        0,     1, 49152, 57344, 58368, 58624, 58752, 58720, 
+        0,     1, 49152, 57344, 58368, 58624, 58752, 58753, 
+    58736,     0,     1, 49152, 57344, 58368, 58624, 58752, 
+    58753, 58736,     0,     1, 49152, 57344, 58368, 58624, 
+    58752, 58753, 58736, 58738,     0,     1, 49152, 57344, 
+    58368, 58624, 58752, 58753, 58736,     0,     1, 49152, 
+    57344, 58368, 58624, 58752, 58753, 58736, 58740,     0, 
+        1, 49152, 57344, 58368, 58624, 58752, 58753, 58736, 
+    58740,     0,     1, 49152, 57344, 58368, 58624, 58752, 
+    58753, 58736, 58744, 58742,     0,     1, 49152, 57344, 
+    58368, 58624, 58752, 58753, 58736,     0,     1, 49152, 
+    57344, 58368, 58624, 58752, 58753, 58736, 58744,     0, 
+        1, 49152, 57344, 58368, 58624, 58752, 58753, 58755, 
+    58744,     0,     1, 49152, 57344, 58368, 58624, 58752, 
+    58753, 58755, 58744, 58746,     0,     1, 49152, 57344, 
+    58368, 58624, 58752, 58753, 58755, 58744,     0,     1, 
+    49152, 57344, 58368, 58624, 58752, 58753, 58755, 58744, 
+    58748,     0,     1, 49152, 57344, 58368, 58624, 58752, 
+    58753, 58755, 58744, 58748,     0,     1, 49152, 57344, 
+    58368, 58624, 58752, 58753, 58755, 58744, 58748, 58750, 
+        0,     1, 49152, 57344, 58368, 58624,     0,     1, 
+    49152, 57344, 58368, 58880, 58752,     0,     1, 49152, 
+    57344, 58368, 58880, 58752,     0,     1, 49152, 57344, 
+    58368, 58880, 58752, 58754,     0,     1, 49152, 57344, 
+    58368, 58880, 58752,     0,     1, 49152, 57344, 58368, 
+    58880, 58752, 58756,     0,     1, 49152, 57344, 58368, 
+    58880, 58752, 58756,     0,     1, 49152, 57344, 58368, 
+    58880, 58752, 58760, 58758,     0,     1, 49152, 57344, 
+    58368, 58880, 58752,     0,     1, 49152, 57344, 58368, 
+    58880, 58752, 58760,     0,     1, 49152, 57344, 58368, 
+    58880, 58752, 58760,     0,     1, 49152, 57344, 58368, 
+    58880, 58752, 58760, 58762,     0,     1, 49152, 57344, 
+    58368, 58880, 58752, 58760,     0,     1, 49152, 57344, 
+    58368, 58880, 58752, 58768, 58764,     0,     1, 49152, 
+    57344, 58368, 58880, 58752, 58768, 58764,     0,     1, 
+    49152, 57344, 58368, 58880, 58752, 58768, 58769, 58766, 
+        0,     1, 49152, 57344, 58368, 58880, 58752,     0, 
+        1, 49152, 57344, 58368, 58880, 58752, 58768,     0, 
+        1, 49152, 57344, 58368, 58880, 58752, 58768,     0, 
+        1, 49152, 57344, 58368, 58880, 58752, 58768, 58770, 
+        0,     1, 49152, 57344, 58368, 58880, 58752, 58768, 
+        0,     1, 49152, 57344, 58368, 58880, 58752, 58768, 
+    58772,     0,     1, 49152, 57344, 58368, 58880, 58752, 
+    58768, 58772,     0,     1, 49152, 57344, 58368, 58880, 
+    58752, 58768, 58776, 58774,     0,     1, 49152, 57344, 
+    58368, 58880, 58752, 58768,     0,     1, 49152, 57344, 
+    58368, 58880, 58752, 58784, 58776,     0,     1, 49152, 
+    57344, 58368, 58880, 58752, 58784, 58776,     0,     1, 
+    49152, 57344, 58368, 58880, 58752, 58784, 58776, 58778, 
+        0,     1, 49152, 57344, 58368, 58880, 58752, 58784, 
+    58776,     0,     1, 49152, 57344, 58368, 58880, 58752, 
+    58784, 58785, 58780,     0,     1, 49152, 57344, 58368, 
+    58880, 58752, 58784, 58785, 58780,     0,     1, 49152, 
+    57344, 58368, 58880, 58752, 58784, 58785, 58780, 58782, 
+        0,     1, 49152, 57344, 58368, 58880, 58752,     0, 
+        1, 49152, 57344, 58368, 58880, 58752, 58784,     0, 
+        1, 49152, 57344, 58368, 58880, 58752, 58784,     0, 
+        1, 49152, 57344, 58368, 58880, 58752, 58784, 58786, 
+        0,     1, 49152, 57344, 58368, 58880, 58752, 58784, 
+        0,     1, 49152, 57344, 58368, 58880, 58752, 58784, 
+    58788,     0,     1, 49152, 57344, 58368, 58880, 58752, 
+    58784, 58788,     0,     1, 49152, 57344, 58368, 58880, 
+    58752, 58784, 58792, 58790,     0,     1, 49152, 57344, 
+    58368, 58880, 58752, 58784,     0,     1, 49152, 57344, 
+    58368, 58880, 58752, 58784, 58792,     0,     1, 49152, 
+    57344, 58368, 58880, 58752, 58784, 58792,     0,     1, 
+    49152, 57344, 58368, 58880, 58752, 58784, 58792, 58794, 
+        0,     1, 49152, 57344, 58368, 58880, 58752, 58784, 
+    58792,     0,     1, 49152, 57344, 58368, 58880, 58752, 
+    58784, 58800, 58796,     0,     1, 49152, 57344, 58368, 
+    58880, 58752, 58784, 58800, 58796,     0,     1, 49152, 
+    57344, 58368, 58880, 58752, 58784, 58800, 58801, 58798, 
+        0,     1, 49152, 57344, 58368, 58880, 58752, 58784, 
+        0,     1, 49152, 57344, 58368, 58880, 58752, 58816, 
+    58800,     0,     1, 49152, 57344, 58368, 58880, 58752, 
+    58816, 58800,     0,     1, 49152, 57344, 58368, 58880, 
+    58752, 58816, 58800, 58802,     0,     1, 49152, 57344, 
+    58368, 58880, 58752, 58816, 58800,     0,     1, 49152, 
+    57344, 58368, 58880, 58752, 58816, 58800, 58804,     0, 
+        1, 49152, 57344, 58368, 58880, 58752, 58816, 58800, 
+    58804,     0,     1, 49152, 57344, 58368, 58880, 58752, 
+    58816, 58800, 58808, 58806,     0,     1, 49152, 57344, 
+    58368, 58880, 58752, 58816, 58800,     0,     1, 49152, 
+    57344, 58368, 58880, 58752, 58816, 58817, 58808,     0, 
+        1, 49152, 57344, 58368, 58880, 58752, 58816, 58817, 
+    58808,     0,     1, 49152, 57344, 58368, 58880, 58752, 
+    58816, 58817, 58808, 58810,     0,     1, 49152, 57344, 
+    58368, 58880, 58752, 58816, 58817, 58808,     0,     1, 
+    49152, 57344, 58368, 58880, 58752, 58816, 58817, 58808, 
+    58812,     0,     1, 49152, 57344, 58368, 58880, 58752, 
+    58816, 58817, 58819, 58812,     0,     1, 49152, 57344, 
+    58368, 58880, 58752, 58816, 58817, 58819, 58812, 58814, 
+        0,     1, 49152, 57344, 58368, 58880, 58752,     0, 
+        1, 49152, 57344, 58368, 58880, 58881, 58816,     0, 
+        1, 49152, 57344, 58368, 58880, 58881, 58816,     0, 
+        1, 49152, 57344, 58368, 58880, 58881, 58816, 58818, 
+        0,     1, 49152, 57344, 58368, 58880, 58881, 58816, 
+        0,     1, 49152, 57344, 58368, 58880, 58881, 58816, 
+    58820,     0,     1, 49152, 57344, 58368, 58880, 58881, 
+    58816, 58820,     0,     1, 49152, 57344, 58368, 58880, 
+    58881, 58816, 58824, 58822,     0,     1, 49152, 57344, 
+    58368, 58880, 58881, 58816,     0,     1, 49152, 57344, 
+    58368, 58880, 58881, 58816, 58824,     0,     1, 49152, 
+    57344, 58368, 58880, 58881, 58816, 58824,     0,     1, 
+    49152, 57344, 58368, 58880, 58881, 58816, 58824, 58826, 
+        0,     1, 49152, 57344, 58368, 58880, 58881, 58816, 
+    58824,     0,     1, 49152, 57344, 58368, 58880, 58881, 
+    58816, 58832, 58828,     0,     1, 49152, 57344, 58368, 
+    58880, 58881, 58816, 58832, 58828,     0,     1, 49152, 
+    57344, 58368, 58880, 58881, 58816, 58832, 58833, 58830, 
+        0,     1, 49152, 57344, 58368, 58880, 58881, 58816, 
+        0,     1, 49152, 57344, 58368, 58880, 58881, 58816, 
+    58832,     0,     1, 49152, 57344, 58368, 58880, 58881, 
+    58816, 58832,     0,     1, 49152, 57344, 58368, 58880, 
+    58881, 58816, 58832, 58834,     0,     1, 49152, 57344, 
+    58368, 58880, 58881, 58816, 58832,     0,     1, 49152, 
+    57344, 58368, 58880, 58881, 58816, 58832, 58836,     0, 
+        1, 49152, 57344, 58368, 58880, 58881, 58816, 58832, 
+    58836,     0,     1, 49152, 57344, 58368, 58880, 58881, 
+    58816, 58832, 58840, 58838,     0,     1, 49152, 57344, 
+    58368, 58880, 58881, 58816, 58832,     0,     1, 49152, 
+    57344, 58368, 58880, 58881, 58816, 58848, 58840,     0, 
+        1, 49152, 57344, 58368, 58880, 58881, 58816, 58848, 
+    58840,     0,     1, 49152, 57344, 58368, 58880, 58881, 
+    58816, 58848, 58840, 58842,     0,     1, 49152, 57344, 
+    58368, 58880, 58881, 58816, 58848, 58840,     0,     1, 
+    49152, 57344, 58368, 58880, 58881, 58816, 58848, 58849, 
+    58844,     0,     1, 49152, 57344, 58368, 58880, 58881, 
+    58816, 58848, 58849, 58844,     0,     1, 49152, 57344, 
+    58368, 58880, 58881, 58816, 58848, 58849, 58844, 58846, 
+        0,     1, 49152, 57344, 58368, 58880, 58881, 58816, 
+        0,     1, 49152, 57344, 58368, 58880, 58881, 58816, 
+    58848,     0,     1, 49152, 57344, 58368, 58880, 58881, 
+    58883, 58848,     0,     1, 49152, 57344, 58368, 58880, 
+    58881, 58883, 58848, 58850,     0,     1, 49152, 57344, 
+    58368, 58880, 58881, 58883, 58848,     0,     1, 49152, 
+    57344, 58368, 58880, 58881, 58883, 58848, 58852,     0, 
+        1, 49152, 57344, 58368, 58880, 58881, 58883, 58848, 
+    58852,     0,     1, 49152, 57344, 58368, 58880, 58881, 
+    58883, 58848, 58856, 58854,     0,     1, 49152, 57344, 
+    58368, 58880, 58881, 58883, 58848,     0,     1, 49152, 
+    57344, 58368, 58880, 58881, 58883, 58848, 58856,     0, 
+        1, 49152, 57344, 58368, 58880, 58881, 58883, 58848, 
+    58856,     0,     1, 49152, 57344, 58368, 58880, 58881, 
+    58883, 58848, 58856, 58858,     0,     1, 49152, 57344, 
+    58368, 58880, 58881, 58883, 58848, 58856,     0,     1, 
+    49152, 57344, 58368, 58880, 58881, 58883, 58848, 58864, 
+    58860,     0,     1, 49152, 57344, 58368, 58880, 58881, 
+    58883, 58848, 58864, 58860,     0,     1, 49152, 57344, 
+    58368, 58880, 58881, 58883, 58848, 58864, 58865, 58862, 
+        0,     1, 49152, 57344, 58368, 58880, 58881, 58883, 
+    58848,     0,     1, 49152, 57344, 58368, 58880, 58881, 
+    58883, 58848, 58864,     0,     1, 49152, 57344, 58368, 
+    58880, 58881, 58883, 58848, 58864,     0,     1, 49152, 
+    57344, 58368, 58880, 58881, 58883, 58848, 58864, 58866, 
+        0,     1, 49152, 57344, 58368, 58880, 58881, 58883, 
+    58887, 58864,     0,     1, 49152, 57344, 58368, 58880, 
+    58881, 58883, 58887, 58864, 58868,     0,     1, 49152, 
+    57344, 58368, 58880, 58881, 58883, 58887, 58864, 58868, 
+        0,     1, 49152, 57344, 58368, 58880, 58881, 58883, 
+    58887, 58864, 58872, 58870,     0,     1, 49152, 57344, 
+    58368, 58880, 58881, 58883, 58887, 58864,     0,     1, 
+    49152, 57344, 58368, 58880, 58881, 58883, 58887, 58864, 
+    58872,     0,     1, 49152, 57344, 58368, 58880, 58881, 
+    58883, 58887, 58864, 58872,     0,     1, 49152, 57344, 
+    58368, 58880, 58881, 58883, 58887, 58864, 58872, 58874, 
+        0,     1, 49152, 57344, 58368, 58880, 58881, 58883, 
+    58887, 58864, 58872,     0,     1, 49152, 57344, 58368, 
+    58880, 58881, 58883, 58887, 58864, 58872, 58876,     0, 
+        1, 49152, 57344, 58368, 58880, 58881, 58883, 58887, 
+    58864, 58872, 58876,     0,     1, 49152, 57344, 58368, 
+    58880, 58881, 58883, 58887, 58864, 58872, 58876, 58878, 
+        0,     1, 49152, 57344, 58368,     0,     1, 49152, 
+    57344, 59392, 58880,     0,     1, 49152, 57344, 59392, 
+    58880,     0,     1, 49152, 57344, 59392, 58880, 58882, 
+        0,     1, 49152, 57344, 59392, 58880,     0,     1, 
+    49152, 57344, 59392, 58880, 58884,     0,     1, 49152, 
+    57344, 59392, 58880, 58884,     0,     1, 49152, 57344, 
+    59392, 58880, 58888, 58886,     0,     1, 49152, 57344, 
+    59392, 58880,     0,     1, 49152, 57344, 59392, 58880, 
+    58888,     0,     1, 49152, 57344, 59392, 58880, 58888, 
+        0,     1, 49152, 57344, 59392, 58880, 58888, 58890, 
+        0,     1, 49152, 57344, 59392, 58880, 58888,     0, 
+        1, 49152, 57344, 59392, 58880, 58896, 58892,     0, 
+        1, 49152, 57344, 59392, 58880, 58896, 58892,     0, 
+        1, 49152, 57344, 59392, 58880, 58896, 58897, 58894, 
+        0,     1, 49152, 57344, 59392, 58880,     0,     1, 
+    49152, 57344, 59392, 58880, 58896,     0,     1, 49152, 
+    57344, 59392, 58880, 58896,     0,     1, 49152, 57344, 
+    59392, 58880, 58896, 58898,     0,     1, 49152, 57344, 
+    59392, 58880, 58896,     0,     1, 49152, 57344, 59392, 
+    58880, 58896, 58900,     0,     1, 49152, 57344, 59392, 
+    58880, 58896, 58900,     0,     1, 49152, 57344, 59392, 
+    58880, 58896, 58904, 58902,     0,     1, 49152, 57344, 
+    59392, 58880, 58896,     0,     1, 49152, 57344, 59392, 
+    58880, 58912, 58904,     0,     1, 49152, 57344, 59392, 
+    58880, 58912, 58904,     0,     1, 49152, 57344, 59392, 
+    58880, 58912, 58904, 58906,     0,     1, 49152, 57344, 
+    59392, 58880, 58912, 58904,     0,     1, 49152, 57344, 
+    59392, 58880, 58912, 58913, 58908,     0,     1, 49152, 
+    57344, 59392, 58880, 58912, 58913, 58908,     0,     1, 
+    49152, 57344, 59392, 58880, 58912, 58913, 58908, 58910, 
+        0,     1, 49152, 57344, 59392, 58880,     0,     1, 
+    49152, 57344, 59392, 58880, 58912,     0,     1, 49152, 
+    57344, 59392, 58880, 58912,     0,     1, 49152, 57344, 
+    59392, 58880, 58912, 58914,     0,     1, 49152, 57344, 
+    59392, 58880, 58912,     0,     1, 49152, 57344, 59392, 
+    58880, 58912, 58916,     0,     1, 49152, 57344, 59392, 
+    58880, 58912, 58916,     0,     1, 49152, 57344, 59392, 
+    58880, 58912, 58920, 58918,     0,     1, 49152, 57344, 
+    59392, 58880, 58912,     0,     1, 49152, 57344, 59392, 
+    58880, 58912, 58920,     0,     1, 49152, 57344, 59392, 
+    58880, 58912, 58920,     0,     1, 49152, 57344, 59392, 
+    58880, 58912, 58920, 58922,     0,     1, 49152, 57344, 
+    59392, 58880, 58912, 58920,     0,     1, 49152, 57344, 
+    59392, 58880, 58912, 58928, 58924,     0,     1, 49152, 
+    57344, 59392, 58880, 58912, 58928, 58924,     0,     1, 
+    49152, 57344, 59392, 58880, 58912, 58928, 58929, 58926, 
+        0,     1, 49152, 57344, 59392, 58880, 58912,     0, 
+        1, 49152, 57344, 59392, 58880, 58944, 58928,     0, 
+        1, 49152, 57344, 59392, 58880, 58944, 58928,     0, 
+        1, 49152, 57344, 59392, 58880, 58944, 58928, 58930, 
+        0,     1, 49152, 57344, 59392, 58880, 58944, 58928, 
+        0,     1, 49152, 57344, 59392, 58880, 58944, 58928, 
+    58932,     0,     1, 49152, 57344, 59392, 58880, 58944, 
+    58928, 58932,     0,     1, 49152, 57344, 59392, 58880, 
+    58944, 58928, 58936, 58934,     0,     1, 49152, 57344, 
+    59392, 58880, 58944, 58928,     0,     1, 49152, 57344, 
+    59392, 58880, 58944, 58945, 58936,     0,     1, 49152, 
+    57344, 59392, 58880, 58944, 58945, 58936,     0,     1, 
+    49152, 57344, 59392, 58880, 58944, 58945, 58936, 58938, 
+        0,     1, 49152, 57344, 59392, 58880, 58944, 58945, 
+    58936,     0,     1, 49152, 57344, 59392, 58880, 58944, 
+    58945, 58936, 58940,     0,     1, 49152, 57344, 59392, 
+    58880, 58944, 58945, 58947, 58940,     0,     1, 49152, 
+    57344, 59392, 58880, 58944, 58945, 58947, 58940, 58942, 
+        0,     1, 49152, 57344, 59392, 58880,     0,     1, 
+    49152, 57344, 59392, 58880, 58944,     0,     1, 49152, 
+    57344, 59392, 58880, 58944,     0,     1, 49152, 57344, 
+    59392, 58880, 58944, 58946,     0,     1, 49152, 57344, 
+    59392, 58880, 58944,     0,     1, 49152, 57344, 59392, 
+    58880, 58944, 58948,     0,     1, 49152, 57344, 59392, 
+    58880, 58944, 58948,     0,     1, 49152, 57344, 59392, 
+    58880, 58944, 58952, 58950,     0,     1, 49152, 57344, 
+    59392, 58880, 58944,     0,     1, 49152, 57344, 59392, 
+    58880, 58944, 58952,     0,     1, 49152, 57344, 59392, 
+    58880, 58944, 58952,     0,     1, 49152, 57344, 59392, 
+    58880, 58944, 58952, 58954,     0,     1, 49152, 57344, 
+    59392, 58880, 58944, 58952,     0,     1, 49152, 57344, 
+    59392, 58880, 58944, 58960, 58956,     0,     1, 49152, 
+    57344, 59392, 58880, 58944, 58960, 58956,     0,     1, 
+    49152, 57344, 59392, 58880, 58944, 58960, 58961, 58958, 
+        0,     1, 49152, 57344, 59392, 58880, 58944,     0, 
+        1, 49152, 57344, 59392, 58880, 58944, 58960,     0, 
+        1, 49152, 57344, 59392, 58880, 58944, 58960,     0, 
+        1, 49152, 57344, 59392, 58880, 58944, 58960, 58962, 
+        0,     1, 49152, 57344, 59392, 58880, 58944, 58960, 
+        0,     1, 49152, 57344, 59392, 58880, 58944, 58960, 
+    58964,     0,     1, 49152, 57344, 59392, 58880, 58944, 
+    58960, 58964,     0,     1, 49152, 57344, 59392, 58880, 
+    58944, 58960, 58968, 58966,     0,     1, 49152, 57344, 
+    59392, 58880, 58944, 58960,     0,     1, 49152, 57344, 
+    59392, 58880, 58944, 58976, 58968,     0,     1, 49152, 
+    57344, 59392, 58880, 58944, 58976, 58968,     0,     1, 
+    49152, 57344, 59392, 58880, 58944, 58976, 58968, 58970, 
+        0,     1, 49152, 57344, 59392, 58880, 58944, 58976, 
+    58968,     0,     1, 49152, 57344, 59392, 58880, 58944, 
+    58976, 58977, 58972,     0,     1, 49152, 57344, 59392, 
+    58880, 58944, 58976, 58977, 58972,     0,     1, 49152, 
+    57344, 59392, 58880, 58944, 58976, 58977, 58972, 58974, 
+        0,     1, 49152, 57344, 59392, 58880, 58944,     0, 
+        1, 49152, 57344, 59392, 58880, 59008, 58976,     0, 
+        1, 49152, 57344, 59392, 58880, 59008, 58976,     0, 
+        1, 49152, 57344, 59392, 58880, 59008, 58976, 58978, 
+        0,     1, 49152, 57344, 59392, 58880, 59008, 58976, 
+        0,     1, 49152, 57344, 59392, 58880, 59008, 58976, 
+    58980,     0,     1, 49152, 57344, 59392, 58880, 59008, 
+    58976, 58980,     0,     1, 49152, 57344, 59392, 58880, 
+    59008, 58976, 58984, 58982,     0,     1, 49152, 57344, 
+    59392, 58880, 59008, 58976,     0,     1, 49152, 57344, 
+    59392, 58880, 59008, 58976, 58984,     0,     1, 49152, 
+    57344, 59392, 58880, 59008, 58976, 58984,     0,     1, 
+    49152, 57344, 59392, 58880, 59008, 58976, 58984, 58986, 
+        0,     1, 49152, 57344, 59392, 58880, 59008, 58976, 
+    58984,     0,     1, 49152, 57344, 59392, 58880, 59008, 
+    58976, 58992, 58988,     0,     1, 49152, 57344, 59392, 
+    58880, 59008, 58976, 58992, 58988,     0,     1, 49152, 
+    57344, 59392, 58880, 59008, 58976, 58992, 58993, 58990, 
+        0,     1, 49152, 57344, 59392, 58880, 59008, 58976, 
+        0,     1, 49152, 57344, 59392, 58880, 59008, 59009, 
+    58992,     0,     1, 49152, 57344, 59392, 58880, 59008, 
+    59009, 58992,     0,     1, 49152, 57344, 59392, 58880, 
+    59008, 59009, 58992, 58994,     0,     1, 49152, 57344, 
+    59392, 58880, 59008, 59009, 58992,     0,     1, 49152, 
+    57344, 59392, 58880, 59008, 59009, 58992, 58996,     0, 
+        1, 49152, 57344, 59392, 58880, 59008, 59009, 58992, 
+    58996,     0,     1, 49152, 57344, 59392, 58880, 59008, 
+    59009, 58992, 59000, 58998,     0,     1, 49152, 57344, 
+    59392, 58880, 59008, 59009, 58992,     0,     1, 49152, 
+    57344, 59392, 58880, 59008, 59009, 58992, 59000,     0, 
+        1, 49152, 57344, 59392, 58880, 59008, 59009, 59011, 
+    59000,     0,     1, 49152, 57344, 59392, 58880, 59008, 
+    59009, 59011, 59000, 59002,     0,     1, 49152, 57344, 
+    59392, 58880, 59008, 59009, 59011, 59000,     0,     1, 
+    49152, 57344, 59392, 58880, 59008, 59009, 59011, 59000, 
+    59004,     0,     1, 49152, 57344, 59392, 58880, 59008, 
+    59009, 59011, 59000, 59004,     0,     1, 49152, 57344, 
+    59392, 58880, 59008, 59009, 59011, 59000, 59004, 59006, 
+        0,     1, 49152, 57344, 59392, 58880,     0,     1, 
+    49152, 57344, 59392, 58880, 59008,     0,     1, 49152, 
+    57344, 59392, 58880, 59008,     0,     1, 49152, 57344, 
+    59392, 58880, 59008, 59010,     0,     1, 49152, 57344, 
+    59392, 58880, 59008,     0,     1, 49152, 57344, 59392, 
+    58880, 59008, 59012,     0,     1, 49152, 57344, 59392, 
+    58880, 59008, 59012,     0,     1, 49152, 57344, 59392, 
+    58880, 59008, 59016, 59014,     0,     1, 49152, 57344, 
+    59392, 58880, 59008,     0,     1, 49152, 57344, 59392, 
+    58880, 59008, 59016,     0,     1, 49152, 57344, 59392, 
+    58880, 59008, 59016,     0,     1, 49152, 57344, 59392, 
+    58880, 59008, 59016, 59018,     0,     1, 49152, 57344, 
+    59392, 58880, 59008, 59016,     0,     1, 49152, 57344, 
+    59392, 58880, 59008, 59024, 59020,     0,     1, 49152, 
+    57344, 59392, 58880, 59008, 59024, 59020,     0,     1, 
+    49152, 57344, 59392, 58880, 59008, 59024, 59025, 59022, 
+        0,     1, 49152, 57344, 59392, 58880, 59008,     0, 
+        1, 49152, 57344, 59392, 58880, 59008, 59024,     0, 
+        1, 49152, 57344, 59392, 58880, 59008, 59024,     0, 
+        1, 49152, 57344, 59392, 58880, 59008, 59024, 59026, 
+        0,     1, 49152, 57344, 59392, 58880, 59008, 59024, 
+        0,     1, 49152, 57344, 59392, 58880, 59008, 59024, 
+    59028,     0,     1, 49152, 57344, 59392, 58880, 59008, 
+    59024, 59028,     0,     1, 49152, 57344, 59392, 58880, 
+    59008, 59024, 59032, 59030,     0,     1, 49152, 57344, 
+    59392, 58880, 59008, 59024,     0,     1, 49152, 57344, 
+    59392, 58880, 59008, 59040, 59032,     0,     1, 49152, 
+    57344, 59392, 58880, 59008, 59040, 59032,     0,     1, 
+    49152, 57344, 59392, 58880, 59008, 59040, 59032, 59034, 
+        0,     1, 49152, 57344, 59392, 58880, 59008, 59040, 
+    59032,     0,     1, 49152, 57344, 59392, 58880, 59008, 
+    59040, 59041, 59036,     0,     1, 49152, 57344, 59392, 
+    58880, 59008, 59040, 59041, 59036,     0,     1, 49152, 
+    57344, 59392, 58880, 59008, 59040, 59041, 59036, 59038, 
+        0,     1, 49152, 57344, 59392, 58880, 59008,     0, 
+        1, 49152, 57344, 59392, 58880, 59008, 59040,     0, 
+        1, 49152, 57344, 59392, 58880, 59008, 59040,     0, 
+        1, 49152, 57344, 59392, 58880, 59008, 59040, 59042, 
+        0,     1, 49152, 57344, 59392, 58880, 59008, 59040, 
+        0,     1, 49152, 57344, 59392, 58880, 59008, 59040, 
+    59044,     0,     1, 49152, 57344, 59392, 58880, 59008, 
+    59040, 59044,     0,     1, 49152, 57344, 59392, 58880, 
+    59008, 59040, 59048, 59046,     0,     1, 49152, 57344, 
+    59392, 58880, 59008, 59040,     0,     1, 49152, 57344, 
+    59392, 58880, 59008, 59040, 59048,     0,     1, 49152, 
+    57344, 59392, 58880, 59008, 59040, 59048,     0,     1, 
+    49152, 57344, 59392, 58880, 59008, 59040, 59048, 59050, 
+        0,     1, 49152, 57344, 59392, 58880, 59008, 59040, 
+    59048,     0,     1, 49152, 57344, 59392, 58880, 59008, 
+    59040, 59056, 59052,     0,     1, 49152, 57344, 59392, 
+    58880, 59008, 59040, 59056, 59052,     0,     1, 49152, 
+    57344, 59392, 58880, 59008, 59040, 59056, 59057, 59054, 
+        0,     1, 49152, 57344, 59392, 58880, 59008, 59040, 
+        0,     1, 49152, 57344, 59392, 58880, 59008, 59072, 
+    59056,     0,     1, 49152, 57344, 59392, 58880, 59008, 
+    59072, 59056,     0,     1, 49152, 57344, 59392, 58880, 
+    59008, 59072, 59056, 59058,     0,     1, 49152, 57344, 
+    59392, 58880, 59008, 59072, 59056,     0,     1, 49152, 
+    57344, 59392, 58880, 59008, 59072, 59056, 59060,     0, 
+        1, 49152, 57344, 59392, 58880, 59008, 59072, 59056, 
+    59060,     0,     1, 49152, 57344, 59392, 58880, 59008, 
+    59072, 59056, 59064, 59062,     0,     1, 49152, 57344, 
+    59392, 58880, 59008, 59072, 59056,     0,     1, 49152, 
+    57344, 59392, 58880, 59008, 59072, 59073, 59064,     0, 
+        1, 49152, 57344, 59392, 58880, 59008, 59072, 59073, 
+    59064,     0,     1, 49152, 57344, 59392, 58880, 59008, 
+    59072, 59073, 59064, 59066,     0,     1, 49152, 57344, 
+    59392, 58880, 59008, 59072, 59073, 59064,     0,     1, 
+    49152, 57344, 59392, 58880, 59008, 59072, 59073, 59064, 
+    59068,     0,     1, 49152, 57344, 59392, 58880, 59008, 
+    59072, 59073, 59075, 59068,     0,     1, 49152, 57344, 
+    59392, 58880, 59008, 59072, 59073, 59075, 59068, 59070, 
+        0,     1, 49152, 57344, 59392, 58880, 59008,     0, 
+        1, 49152, 57344, 59392, 58880, 59136, 59072,     0, 
+        1, 49152, 57344, 59392, 58880, 59136, 59072,     0, 
+        1, 49152, 57344, 59392, 58880, 59136, 59072, 59074, 
+        0,     1, 49152, 57344, 59392, 58880, 59136, 59072, 
+        0,     1, 49152, 57344, 59392, 58880, 59136, 59072, 
+    59076,     0,     1, 49152, 57344, 59392, 58880, 59136, 
+    59072, 59076,     0,     1, 49152, 57344, 59392, 58880, 
+    59136, 59072, 59080, 59078,     0,     1, 49152, 57344, 
+    59392, 58880, 59136, 59072,     0,     1, 49152, 57344, 
+    59392, 58880, 59136, 59072, 59080,     0,     1, 49152, 
+    57344, 59392, 58880, 59136, 59072, 59080,     0,     1, 
+    49152, 57344, 59392, 58880, 59136, 59072, 59080, 59082, 
+        0,     1, 49152, 57344, 59392, 58880, 59136, 59072, 
+    59080,     0,     1, 49152, 57344, 59392, 58880, 59136, 
+    59072, 59088, 59084,     0,     1, 49152, 57344, 59392, 
+    58880, 59136, 59072, 59088, 59084,     0,     1, 49152, 
+    57344, 59392, 58880, 59136, 59072, 59088, 59089, 59086, 
+        0,     1, 49152, 57344, 59392, 58880, 59136, 59072, 
+        0,     1, 49152, 57344, 59392, 58880, 59136, 59072, 
+    59088,     0,     1, 49152, 57344, 59392, 58880, 59136, 
+    59072, 59088,     0,     1, 49152, 57344, 59392, 58880, 
+    59136, 59072, 59088, 59090,     0,     1, 49152, 57344, 
+    59392, 58880, 59136, 59072, 59088,     0,     1, 49152, 
+    57344, 59392, 58880, 59136, 59072, 59088, 59092,     0, 
+        1, 49152, 57344, 59392, 58880, 59136, 59072, 59088, 
+    59092,     0,     1, 49152, 57344, 59392, 58880, 59136, 
+    59072, 59088, 59096, 59094,     0,     1, 49152, 57344, 
+    59392, 58880, 59136, 59072, 59088,     0,     1, 49152, 
+    57344, 59392, 58880, 59136, 59072, 59104, 59096,     0, 
+        1, 49152, 57344, 59392, 58880, 59136, 59072, 59104, 
+    59096,     0,     1, 49152, 57344, 59392, 58880, 59136, 
+    59072, 59104, 59096, 59098,     0,     1, 49152, 57344, 
+    59392, 58880, 59136, 59072, 59104, 59096,     0,     1, 
+    49152, 57344, 59392, 58880, 59136, 59072, 59104, 59105, 
+    59100,     0,     1, 49152, 57344, 59392, 58880, 59136, 
+    59072, 59104, 59105, 59100,     0,     1, 49152, 57344, 
+    59392, 58880, 59136, 59072, 59104, 59105, 59100, 59102, 
+        0,     1, 49152, 57344, 59392, 58880, 59136, 59072, 
+        0,     1, 49152, 57344, 59392, 58880, 59136, 59137, 
+    59104,     0,     1, 49152, 57344, 59392, 58880, 59136, 
+    59137, 59104,     0,     1, 49152, 57344, 59392, 58880, 
+    59136, 59137, 59104, 59106,     0,     1, 49152, 57344, 
+    59392, 58880, 59136, 59137, 59104,     0,     1, 49152, 
+    57344, 59392, 58880, 59136, 59137, 59104, 59108,     0, 
+        1, 49152, 57344, 59392, 58880, 59136, 59137, 59104, 
+    59108,     0,     1, 49152, 57344, 59392, 58880, 59136, 
+    59137, 59104, 59112, 59110,     0,     1, 49152, 57344, 
+    59392, 58880, 59136, 59137, 59104,     0,     1, 49152, 
+    57344, 59392, 58880, 59136, 59137, 59104, 59112,     0, 
+        1, 49152, 57344, 59392, 58880, 59136, 59137, 59104, 
+    59112,     0,     1, 49152, 57344, 59392, 58880, 59136, 
+    59137, 59104, 59112, 59114,     0,     1, 49152, 57344, 
+    59392, 58880, 59136, 59137, 59104, 59112,     0,     1, 
+    49152, 57344, 59392, 58880, 59136, 59137, 59104, 59120, 
+    59116,     0,     1, 49152, 57344, 59392, 58880, 59136, 
+    59137, 59104, 59120, 59116,     0,     1, 49152, 57344, 
+    59392, 58880, 59136, 59137, 59104, 59120, 59121, 59118, 
+        0,     1, 49152, 57344, 59392, 58880, 59136, 59137, 
+    59104,     0,     1, 49152, 57344, 59392, 58880, 59136, 
+    59137, 59104, 59120,     0,     1, 49152, 57344, 59392, 
+    58880, 59136, 59137, 59139, 59120,     0,     1, 49152, 
+    57344, 59392, 58880, 59136, 59137, 59139, 59120, 59122, 
+        0,     1, 49152, 57344, 59392, 58880, 59136, 59137, 
+    59139, 59120,     0,     1, 49152, 57344, 59392, 58880, 
+    59136, 59137, 59139, 59120, 59124,     0,     1, 49152, 
+    57344, 59392, 58880, 59136, 59137, 59139, 59120, 59124, 
+        0,     1, 49152, 57344, 59392, 58880, 59136, 59137, 
+    59139, 59120, 59128, 59126,     0,     1, 49152, 57344, 
+    59392, 58880, 59136, 59137, 59139, 59120,     0,     1, 
+    49152, 57344, 59392, 58880, 59136, 59137, 59139, 59120, 
+    59128,     0,     1, 49152, 57344, 59392, 58880, 59136, 
+    59137, 59139, 59120, 59128,     0,     1, 49152, 57344, 
+    59392, 58880, 59136, 59137, 59139, 59120, 59128, 59130, 
+        0,     1, 49152, 57344, 59392, 58880, 59136, 59137, 
+    59139, 59143, 59128,     0,     1, 49152, 57344, 59392, 
+    58880, 59136, 59137, 59139, 59143, 59128, 59132,     0, 
+        1, 49152, 57344, 59392, 58880, 59136, 59137, 59139, 
+    59143, 59128, 59132,     0,     1, 49152, 57344, 59392, 
+    58880, 59136, 59137, 59139, 59143, 59128, 59132, 59134, 
+        0,     1, 49152, 57344, 59392, 58880,     0,     1, 
+    49152, 57344, 59392, 58880, 59136,     0,     1, 49152, 
+    57344, 59392, 59393, 59136,     0,     1, 49152, 57344, 
+    59392, 59393, 59136, 59138,     0,     1, 49152, 57344, 
+    59392, 59393, 59136,     0,     1, 49152, 57344, 59392, 
+    59393, 59136, 59140,     0,     1, 49152, 57344, 59392, 
+    59393, 59136, 59140,     0,     1, 49152, 57344, 59392, 
+    59393, 59136, 59144, 59142,     0,     1, 49152, 57344, 
+    59392, 59393, 59136,     0,     1, 49152, 57344, 59392, 
+    59393, 59136, 59144,     0,     1, 49152, 57344, 59392, 
+    59393, 59136, 59144,     0,     1, 49152, 57344, 59392, 
+    59393, 59136, 59144, 59146,     0,     1, 49152, 57344, 
+    59392, 59393, 59136, 59144,     0,     1, 49152, 57344, 
+    59392, 59393, 59136, 59152, 59148,     0,     1, 49152, 
+    57344, 59392, 59393, 59136, 59152, 59148,     0,     1, 
+    49152, 57344, 59392, 59393, 59136, 59152, 59153, 59150, 
+        0,     1, 49152, 57344, 59392, 59393, 59136,     0, 
+        1, 49152, 57344, 59392, 59393, 59136, 59152,     0, 
+        1, 49152, 57344, 59392, 59393, 59136, 59152,     0, 
+        1, 49152, 57344, 59392, 59393, 59136, 59152, 59154, 
+        0,     1, 49152, 57344, 59392, 59393, 59136, 59152, 
+        0,     1, 49152, 57344, 59392, 59393, 59136, 59152, 
+    59156,     0,     1, 49152, 57344, 59392, 59393, 59136, 
+    59152, 59156,     0,     1, 49152, 57344, 59392, 59393, 
+    59136, 59152, 59160, 59158,     0,     1, 49152, 57344, 
+    59392, 59393, 59136, 59152,     0,     1, 49152, 57344, 
+    59392, 59393, 59136, 59168, 59160,     0,     1, 49152, 
+    57344, 59392, 59393, 59136, 59168, 59160,     0,     1, 
+    49152, 57344, 59392, 59393, 59136, 59168, 59160, 59162, 
+        0,     1, 49152, 57344, 59392, 59393, 59136, 59168, 
+    59160,     0,     1, 49152, 57344, 59392, 59393, 59136, 
+    59168, 59169, 59164,     0,     1, 49152, 57344, 59392, 
+    59393, 59136, 59168, 59169, 59164,     0,     1, 49152, 
+    57344, 59392, 59393, 59136, 59168, 59169, 59164, 59166, 
+        0,     1, 49152, 57344, 59392, 59393, 59136,     0, 
+        1, 49152, 57344, 59392, 59393, 59136, 59168,     0, 
+        1, 49152, 57344, 59392, 59393, 59136, 59168,     0, 
+        1, 49152, 57344, 59392, 59393, 59136, 59168, 59170, 
+        0,     1, 49152, 57344, 59392, 59393, 59136, 59168, 
+        0,     1, 49152, 57344, 59392, 59393, 59136, 59168, 
+    59172,     0,     1, 49152, 57344, 59392, 59393, 59136, 
+    59168, 59172,     0,     1, 49152, 57344, 59392, 59393, 
+    59136, 59168, 59176, 59174,     0,     1, 49152, 57344, 
+    59392, 59393, 59136, 59168,     0,     1, 49152, 57344, 
+    59392, 59393, 59136, 59168, 59176,     0,     1, 49152, 
+    57344, 59392, 59393, 59136, 59168, 59176,     0,     1, 
+    49152, 57344, 59392, 59393, 59136, 59168, 59176, 59178, 
+        0,     1, 49152, 57344, 59392, 59393, 59136, 59168, 
+    59176,     0,     1, 49152, 57344, 59392, 59393, 59136, 
+    59168, 59184, 59180,     0,     1, 49152, 57344, 59392, 
+    59393, 59136, 59168, 59184, 59180,     0,     1, 49152, 
+    57344, 59392, 59393, 59136, 59168, 59184, 59185, 59182, 
+        0,     1, 49152, 57344, 59392, 59393, 59136, 59168, 
+        0,     1, 49152, 57344, 59392, 59393, 59136, 59200, 
+    59184,     0,     1, 49152, 57344, 59392, 59393, 59136, 
+    59200, 59184,     0,     1, 49152, 57344, 59392, 59393, 
+    59136, 59200, 59184, 59186,     0,     1, 49152, 57344, 
+    59392, 59393, 59136, 59200, 59184,     0,     1, 49152, 
+    57344, 59392, 59393, 59136, 59200, 59184, 59188,     0, 
+        1, 49152, 57344, 59392, 59393, 59136, 59200, 59184, 
+    59188,     0,     1, 49152, 57344, 59392, 59393, 59136, 
+    59200, 59184, 59192, 59190,     0,     1, 49152, 57344, 
+    59392, 59393, 59136, 59200, 59184,     0,     1, 49152, 
+    57344, 59392, 59393, 59136, 59200, 59201, 59192,     0, 
+        1, 49152, 57344, 59392, 59393, 59136, 59200, 59201, 
+    59192,     0,     1, 49152, 57344, 59392, 59393, 59136, 
+    59200, 59201, 59192, 59194,     0,     1, 49152, 57344, 
+    59392, 59393, 59136, 59200, 59201, 59192,     0,     1, 
+    49152, 57344, 59392, 59393, 59136, 59200, 59201, 59192, 
+    59196,     0,     1, 49152, 57344, 59392, 59393, 59136, 
+    59200, 59201, 59203, 59196,     0,     1, 49152, 57344, 
+    59392, 59393, 59136, 59200, 59201, 59203, 59196, 59198, 
+        0,     1, 49152, 57344, 59392, 59393, 59136,     0, 
+        1, 49152, 57344, 59392, 59393, 59136, 59200,     0, 
+        1, 49152, 57344, 59392, 59393, 59136, 59200,     0, 
+        1, 49152, 57344, 59392, 59393, 59136, 59200, 59202, 
+        0,     1, 49152, 57344, 59392, 59393, 59136, 59200, 
+        0,     1, 49152, 57344, 59392, 59393, 59136, 59200, 
+    59204,     0,     1, 49152, 57344, 59392, 59393, 59136, 
+    59200, 59204,     0,     1, 49152, 57344, 59392, 59393, 
+    59136, 59200, 59208, 59206,     0,     1, 49152, 57344, 
+    59392, 59393, 59136, 59200,     0,     1, 49152, 57344, 
+    59392, 59393, 59136, 59200, 59208,     0,     1, 49152, 
+    57344, 59392, 59393, 59136, 59200, 59208,     0,     1, 
+    49152, 57344, 59392, 59393, 59136, 59200, 59208, 59210, 
+        0,     1, 49152, 57344, 59392, 59393, 59136, 59200, 
+    59208,     0,     1, 49152, 57344, 59392, 59393, 59136, 
+    59200, 59216, 59212,     0,     1, 49152, 57344, 59392, 
+    59393, 59136, 59200, 59216, 59212,     0,     1, 49152, 
+    57344, 59392, 59393, 59136, 59200, 59216, 59217, 59214, 
+        0,     1, 49152, 57344, 59392, 59393, 59136, 59200, 
+        0,     1, 49152, 57344, 59392, 59393, 59136, 59200, 
+    59216,     0,     1, 49152, 57344, 59392, 59393, 59136, 
+    59200, 59216,     0,     1, 49152, 57344, 59392, 59393, 
+    59136, 59200, 59216, 59218,     0,     1, 49152, 57344, 
+    59392, 59393, 59136, 59200, 59216,     0,     1, 49152, 
+    57344, 59392, 59393, 59136, 59200, 59216, 59220,     0, 
+        1, 49152, 57344, 59392, 59393, 59136, 59200, 59216, 
+    59220,     0,     1, 49152, 57344, 59392, 59393, 59136, 
+    59200, 59216, 59224, 59222,     0,     1, 49152, 57344, 
+    59392, 59393, 59136, 59200, 59216,     0,     1, 49152, 
+    57344, 59392, 59393, 59136, 59200, 59232, 59224,     0, 
+        1, 49152, 57344, 59392, 59393, 59136, 59200, 59232, 
+    59224,     0,     1, 49152, 57344, 59392, 59393, 59136, 
+    59200, 59232, 59224, 59226,     0,     1, 49152, 57344, 
+    59392, 59393, 59136, 59200, 59232, 59224,     0,     1, 
+    49152, 57344, 59392, 59393, 59136, 59200, 59232, 59233, 
+    59228,     0,     1, 49152, 57344, 59392, 59393, 59136, 
+    59200, 59232, 59233, 59228,     0,     1, 49152, 57344, 
+    59392, 59393, 59136, 59200, 59232, 59233, 59228, 59230, 
+        0,     1, 49152, 57344, 59392, 59393, 59136, 59200, 
+        0,     1, 49152, 57344, 59392, 59393, 59136, 59264, 
+    59232,     0,     1, 49152, 57344, 59392, 59393, 59136, 
+    59264, 59232,     0,     1, 49152, 57344, 59392, 59393, 
+    59136, 59264, 59232, 59234,     0,     1, 49152, 57344, 
+    59392, 59393, 59136, 59264, 59232,     0,     1, 49152, 
+    57344, 59392, 59393, 59136, 59264, 59232, 59236,     0, 
+        1, 49152, 57344, 59392, 59393, 59136, 59264, 59232, 
+    59236,     0,     1, 49152, 57344, 59392, 59393, 59136, 
+    59264, 59232, 59240, 59238,     0,     1, 49152, 57344, 
+    59392, 59393, 59136, 59264, 59232,     0,     1, 49152, 
+    57344, 59392, 59393, 59136, 59264, 59232, 59240,     0, 
+        1, 49152, 57344, 59392, 59393, 59136, 59264, 59232, 
+    59240,     0,     1, 49152, 57344, 59392, 59393, 59136, 
+    59264, 59232, 59240, 59242,     0,     1, 49152, 57344, 
+    59392, 59393, 59136, 59264, 59232, 59240,     0,     1, 
+    49152, 57344, 59392, 59393, 59136, 59264, 59232, 59248, 
+    59244,     0,     1, 49152, 57344, 59392, 59393, 59136, 
+    59264, 59232, 59248, 59244,     0,     1, 49152, 57344, 
+    59392, 59393, 59136, 59264, 59232, 59248, 59249, 59246, 
+        0,     1, 49152, 57344, 59392, 59393, 59136, 59264, 
+    59232,     0,     1, 49152, 57344, 59392, 59393, 59136, 
+    59264, 59265, 59248,     0,     1, 49152, 57344, 59392, 
+    59393, 59136, 59264, 59265, 59248,     0,     1, 49152, 
+    57344, 59392, 59393, 59136, 59264, 59265, 59248, 59250, 
+        0,     1, 49152, 57344, 59392, 59393, 59136, 59264, 
+    59265, 59248,     0,     1, 49152, 57344, 59392, 59393, 
+    59136, 59264, 59265, 59248, 59252,     0,     1, 49152, 
+    57344, 59392, 59393, 59136, 59264, 59265, 59248, 59252, 
+        0,     1, 49152, 57344, 59392, 59393, 59136, 59264, 
+    59265, 59248, 59256, 59254,     0,     1, 49152, 57344, 
+    59392, 59393, 59136, 59264, 59265, 59248,     0,     1, 
+    49152, 57344, 59392, 59393, 59136, 59264, 59265, 59248, 
+    59256,     0,     1, 49152, 57344, 59392, 59393, 59136, 
+    59264, 59265, 59267, 59256,     0,     1, 49152, 57344, 
+    59392, 59393, 59136, 59264, 59265, 59267, 59256, 59258, 
+        0,     1, 49152, 57344, 59392, 59393, 59136, 59264, 
+    59265, 59267, 59256,     0,     1, 49152, 57344, 59392, 
+    59393, 59136, 59264, 59265, 59267, 59256, 59260,     0, 
+        1, 49152, 57344, 59392, 59393, 59136, 59264, 59265, 
+    59267, 59256, 59260,     0,     1, 49152, 57344, 59392, 
+    59393, 59136, 59264, 59265, 59267, 59256, 59260, 59262, 
+        0,     1, 49152, 57344, 59392, 59393, 59136,     0, 
+        1, 49152, 57344, 59392, 59393, 59136, 59264,     0, 
+        1, 49152, 57344, 59392, 59393, 59136, 59264,     0, 
+        1, 49152, 57344, 59392, 59393, 59136, 59264, 59266, 
+        0,     1, 49152, 57344, 59392, 59393, 59395, 59264, 
+        0,     1, 49152, 57344, 59392, 59393, 59395, 59264, 
+    59268,     0,     1, 49152, 57344, 59392, 59393, 59395, 
+    59264, 59268,     0,     1, 49152, 57344, 59392, 59393, 
+    59395, 59264, 59272, 59270,     0,     1, 49152, 57344, 
+    59392, 59393, 59395, 59264,     0,     1, 49152, 57344, 
+    59392, 59393, 59395, 59264, 59272,     0,     1, 49152, 
+    57344, 59392, 59393, 59395, 59264, 59272,     0,     1, 
+    49152, 57344, 59392, 59393, 59395, 59264, 59272, 59274, 
+        0,     1, 49152, 57344, 59392, 59393, 59395, 59264, 
+    59272,     0,     1, 49152, 57344, 59392, 59393, 59395, 
+    59264, 59280, 59276,     0,     1, 49152, 57344, 59392, 
+    59393, 59395, 59264, 59280, 59276,     0,     1, 49152, 
+    57344, 59392, 59393, 59395, 59264, 59280, 59281, 59278, 
+        0,     1, 49152, 57344, 59392, 59393, 59395, 59264, 
+        0,     1, 49152, 57344, 59392, 59393, 59395, 59264, 
+    59280,     0,     1, 49152, 57344, 59392, 59393, 59395, 
+    59264, 59280,     0,     1, 49152, 57344, 59392, 59393, 
+    59395, 59264, 59280, 59282,     0,     1, 49152, 57344, 
+    59392, 59393, 59395, 59264, 59280,     0,     1, 49152, 
+    57344, 59392, 59393, 59395, 59264, 59280, 59284,     0, 
+        1, 49152, 57344, 59392, 59393, 59395, 59264, 59280, 
+    59284,     0,     1, 49152, 57344, 59392, 59393, 59395, 
+    59264, 59280, 59288, 59286,     0,     1, 49152, 57344, 
+    59392, 59393, 59395, 59264, 59280,     0,     1, 49152, 
+    57344, 59392, 59393, 59395, 59264, 59296, 59288,     0, 
+        1, 49152, 57344, 59392, 59393, 59395, 59264, 59296, 
+    59288,     0,     1, 49152, 57344, 59392, 59393, 59395, 
+    59264, 59296, 59288, 59290,     0,     1, 49152, 57344, 
+    59392, 59393, 59395, 59264, 59296, 59288,     0,     1, 
+    49152, 57344, 59392, 59393, 59395, 59264, 59296, 59297, 
+    59292,     0,     1, 49152, 57344, 59392, 59393, 59395, 
+    59264, 59296, 59297, 59292,     0,     1, 49152, 57344, 
+    59392, 59393, 59395, 59264, 59296, 59297, 59292, 59294, 
+        0,     1, 49152, 57344, 59392, 59393, 59395, 59264, 
+        0,     1, 49152, 57344, 59392, 59393, 59395, 59264, 
+    59296,     0,     1, 49152, 57344, 59392, 59393, 59395, 
+    59264, 59296,     0,     1, 49152, 57344, 59392, 59393, 
+    59395, 59264, 59296, 59298,     0,     1, 49152, 57344, 
+    59392, 59393, 59395, 59264, 59296,     0,     1, 49152, 
+    57344, 59392, 59393, 59395, 59264, 59296, 59300,     0, 
+        1, 49152, 57344, 59392, 59393, 59395, 59264, 59296, 
+    59300,     0,     1, 49152, 57344, 59392, 59393, 59395, 
+    59264, 59296, 59304, 59302,     0,     1, 49152, 57344, 
+    59392, 59393, 59395, 59264, 59296,     0,     1, 49152, 
+    57344, 59392, 59393, 59395, 59264, 59296, 59304,     0, 
+        1, 49152, 57344, 59392, 59393, 59395, 59264, 59296, 
+    59304,     0,     1, 49152, 57344, 59392, 59393, 59395, 
+    59264, 59296, 59304, 59306,     0,     1, 49152, 57344, 
+    59392, 59393, 59395, 59264, 59296, 59304,     0,     1, 
+    49152, 57344, 59392, 59393, 59395, 59264, 59296, 59312, 
+    59308,     0,     1, 49152, 57344, 59392, 59393, 59395, 
+    59264, 59296, 59312, 59308,     0,     1, 49152, 57344, 
+    59392, 59393, 59395, 59264, 59296, 59312, 59313, 59310, 
+        0,     1, 49152, 57344, 59392, 59393, 59395, 59264, 
+    59296,     0,     1, 49152, 57344, 59392, 59393, 59395, 
+    59264, 59328, 59312,     0,     1, 49152, 57344, 59392, 
+    59393, 59395, 59264, 59328, 59312,     0,     1, 49152, 
+    57344, 59392, 59393, 59395, 59264, 59328, 59312, 59314, 
+        0,     1, 49152, 57344, 59392, 59393, 59395, 59264, 
+    59328, 59312,     0,     1, 49152, 57344, 59392, 59393, 
+    59395, 59264, 59328, 59312, 59316,     0,     1, 49152, 
+    57344, 59392, 59393, 59395, 59264, 59328, 59312, 59316, 
+        0,     1, 49152, 57344, 59392, 59393, 59395, 59264, 
+    59328, 59312, 59320, 59318,     0,     1, 49152, 57344, 
+    59392, 59393, 59395, 59264, 59328, 59312,     0,     1, 
+    49152, 57344, 59392, 59393, 59395, 59264, 59328, 59329, 
+    59320,     0,     1, 49152, 57344, 59392, 59393, 59395, 
+    59264, 59328, 59329, 59320,     0,     1, 49152, 57344, 
+    59392, 59393, 59395, 59264, 59328, 59329, 59320, 59322, 
+        0,     1, 49152, 57344, 59392, 59393, 59395, 59264, 
+    59328, 59329, 59320,     0,     1, 49152, 57344, 59392, 
+    59393, 59395, 59264, 59328, 59329, 59320, 59324,     0, 
+        1, 49152, 57344, 59392, 59393, 59395, 59264, 59328, 
+    59329, 59331, 59324,     0,     1, 49152, 57344, 59392, 
+    59393, 59395, 59264, 59328, 59329, 59331, 59324, 59326, 
+        0,     1, 49152, 57344, 59392, 59393, 59395, 59264, 
+        0,     1, 49152, 57344, 59392, 59393, 59395, 59264, 
+    59328,     0,     1, 49152, 57344, 59392, 59393, 59395, 
+    59264, 59328,     0,     1, 49152, 57344, 59392, 59393, 
+    59395, 59264, 59328, 59330,     0,     1, 49152, 57344, 
+    59392, 59393, 59395, 59264, 59328,     0,     1, 49152, 
+    57344, 59392, 59393, 59395, 59264, 59328, 59332,     0, 
+        1, 49152, 57344, 59392, 59393, 59395, 59264, 59328, 
+    59332,     0,     1, 49152, 57344, 59392, 59393, 59395, 
+    59264, 59328, 59336, 59334,     0,     1, 49152, 57344, 
+    59392, 59393, 59395, 59399, 59328,     0,     1, 49152, 
+    57344, 59392, 59393, 59395, 59399, 59328, 59336,     0, 
+        1, 49152, 57344, 59392, 59393, 59395, 59399, 59328, 
+    59336,     0,     1, 49152, 57344, 59392, 59393, 59395, 
+    59399, 59328, 59336, 59338,     0,     1, 49152, 57344, 
+    59392, 59393, 59395, 59399, 59328, 59336,     0,     1, 
+    49152, 57344, 59392, 59393, 59395, 59399, 59328, 59344, 
+    59340,     0,     1, 49152, 57344, 59392, 59393, 59395, 
+    59399, 59328, 59344, 59340,     0,     1, 49152, 57344, 
+    59392, 59393, 59395, 59399, 59328, 59344, 59345, 59342, 
+        0,     1, 49152, 57344, 59392, 59393, 59395, 59399, 
+    59328,     0,     1, 49152, 57344, 59392, 59393, 59395, 
+    59399, 59328, 59344,     0,     1, 49152, 57344, 59392, 
+    59393, 59395, 59399, 59328, 59344,     0,     1, 49152, 
+    57344, 59392, 59393, 59395, 59399, 59328, 59344, 59346, 
+        0,     1, 49152, 57344, 59392, 59393, 59395, 59399, 
+    59328, 59344,     0,     1, 49152, 57344, 59392, 59393, 
+    59395, 59399, 59328, 59344, 59348,     0,     1, 49152, 
+    57344, 59392, 59393, 59395, 59399, 59328, 59344, 59348, 
+        0,     1, 49152, 57344, 59392, 59393, 59395, 59399, 
+    59328, 59344, 59352, 59350,     0,     1, 49152, 57344, 
+    59392, 59393, 59395, 59399, 59328, 59344,     0,     1, 
+    49152, 57344, 59392, 59393, 59395, 59399, 59328, 59360, 
+    59352,     0,     1, 49152, 57344, 59392, 59393, 59395, 
+    59399, 59328, 59360, 59352,     0,     1, 49152, 57344, 
+    59392, 59393, 59395, 59399, 59328, 59360, 59352, 59354, 
+        0,     1, 49152, 57344, 59392, 59393, 59395, 59399, 
+    59328, 59360, 59352,     0,     1, 49152, 57344, 59392, 
+    59393, 59395, 59399, 59328, 59360, 59361, 59356,     0, 
+        1, 49152, 57344, 59392, 59393, 59395, 59399, 59328, 
+    59360, 59361, 59356,     0,     1, 49152, 57344, 59392, 
+    59393, 59395, 59399, 59328, 59360, 59361, 59356, 59358, 
+        0,     1, 49152, 57344, 59392, 59393, 59395, 59399, 
+    59328,     0,     1, 49152, 57344, 59392, 59393, 59395, 
+    59399, 59328, 59360,     0,     1, 49152, 57344, 59392, 
+    59393, 59395, 59399, 59328, 59360,     0,     1, 49152, 
+    57344, 59392, 59393, 59395, 59399, 59328, 59360, 59362, 
+        0,     1, 49152, 57344, 59392, 59393, 59395, 59399, 
+    59328, 59360,     0,     1, 49152, 57344, 59392, 59393, 
+    59395, 59399, 59328, 59360, 59364,     0,     1, 49152, 
+    57344, 59392, 59393, 59395, 59399, 59328, 59360, 59364, 
+        0,     1, 49152, 57344, 59392, 59393, 59395, 59399, 
+    59328, 59360, 59368, 59366,     0,     1, 49152, 57344, 
+    59392, 59393, 59395, 59399, 59328, 59360,     0,     1, 
+    49152, 57344, 59392, 59393, 59395, 59399, 59328, 59360, 
+    59368,     0,     1, 49152, 57344, 59392, 59393, 59395, 
+    59399, 59328, 59360, 59368,     0,     1, 49152, 57344, 
+    59392, 59393, 59395, 59399, 59328, 59360, 59368, 59370, 
+        0,     1, 49152, 57344, 59392, 59393, 59395, 59399, 
+    59328, 59360, 59368,     0,     1, 49152, 57344, 59392, 
+    59393, 59395, 59399, 59328, 59360, 59376, 59372,     0, 
+        1, 49152, 57344, 59392, 59393, 59395, 59399, 59328, 
+    59360, 59376, 59372,     0,     1, 49152, 57344, 59392, 
+    59393, 59395, 59399, 59328, 59360, 59376, 59377, 59374, 
+        0,     1, 49152, 57344, 59392, 59393, 59395, 59399, 
+    59407, 59360,     0,     1, 49152, 57344, 59392, 59393, 
+    59395, 59399, 59407, 59360, 59376,     0,     1, 49152, 
+    57344, 59392, 59393, 59395, 59399, 59407, 59360, 59376, 
+        0,     1, 49152, 57344, 59392, 59393, 59395, 59399, 
+    59407, 59360, 59376, 59378,     0,     1, 49152, 57344, 
+    59392, 59393, 59395, 59399, 59407, 59360, 59376,     0, 
+        1, 49152, 57344, 59392, 59393, 59395, 59399, 59407, 
+    59360, 59376, 59380,     0,     1, 49152, 57344, 59392, 
+    59393, 59395, 59399, 59407, 59360, 59376, 59380,     0, 
+        1, 49152, 57344, 59392, 59393, 59395, 59399, 59407, 
+    59360, 59376, 59384, 59382,     0,     1, 49152, 57344, 
+    59392, 59393, 59395, 59399, 59407, 59360, 59376,     0, 
+        1, 49152, 57344, 59392, 59393, 59395, 59399, 59407, 
+    59360, 59376, 59384,     0,     1, 49152, 57344, 59392, 
+    59393, 59395, 59399, 59407, 59360, 59376, 59384,     0, 
+        1, 49152, 57344, 59392, 59393, 59395, 59399, 59407, 
+    59360, 59376, 59384, 59386,     0,     1, 49152, 57344, 
+    59392, 59393, 59395, 59399, 59407, 59360, 59376, 59384, 
+        0,     1, 49152, 57344, 59392, 59393, 59395, 59399, 
+    59407, 59360, 59376, 59384, 59388,     0,     1, 49152, 
+    57344, 59392, 59393, 59395, 59399, 59407, 59360, 59376, 
+    59384, 59388,     0,     1, 49152, 57344, 59392, 59393, 
+    59395, 59399, 59407, 59360, 59376, 59384, 59388, 59390, 
+        0,     1, 49152, 57344,     0,     1, 49152, 57344, 
+    59392,     0,     1, 49152, 57344, 59392,     0,     1, 
+    49152, 57344, 59392, 59394,     0,     1, 49152, 57344, 
+    59392,     0,     1, 49152, 57344, 59392, 59396,     0, 
+        1, 49152, 57344, 59392, 59396,     0,     1, 49152, 
+    57344, 59392, 59400, 59398,     0,     1, 49152, 57344, 
+    59392,     0,     1, 49152, 57344, 59392, 59400,     0, 
+        1, 49152, 57344, 59392, 59400,     0,     1, 49152, 
+    57344, 59392, 59400, 59402,     0,     1, 49152, 57344, 
+    59392, 59400,     0,     1, 49152, 57344, 59392, 59408, 
+    59404,     0,     1, 49152, 57344, 59392, 59408, 59404, 
+        0,     1, 49152, 57344, 59392, 59408, 59409, 59406, 
+        0,     1, 49152, 57344, 59392,     0,     1, 49152, 
+    57344, 59392, 59408,     0,     1, 49152, 57344, 59392, 
+    59408,     0,     1, 49152, 57344, 59392, 59408, 59410, 
+        0,     1, 49152, 57344, 59392, 59408,     0,     1, 
+    49152, 57344, 59392, 59408, 59412,     0,     1, 49152, 
+    57344, 59392, 59408, 59412,     0,     1, 49152, 57344, 
+    59392, 59408, 59416, 59414,     0,     1, 49152, 57344, 
+    59392, 59408,     0,     1, 49152, 57344, 59392, 59424, 
+    59416,     0,     1, 49152, 57344, 59392, 59424, 59416, 
+        0,     1, 49152, 57344, 59392, 59424, 59416, 59418, 
+        0,     1, 49152, 57344, 59392, 59424, 59416,     0, 
+        1, 49152, 57344, 59392, 59424, 59425, 59420,     0, 
+        1, 49152, 57344, 59392, 59424, 59425, 59420,     0, 
+        1, 49152, 57344, 59392, 59424, 59425, 59420, 59422, 
+        0,     1, 49152, 57344, 59392,     0,     1, 49152, 
+    57344, 59392, 59424,     0,     1, 49152, 57344, 59392, 
+    59424,     0,     1, 49152, 57344, 59392, 59424, 59426, 
+        0,     1, 49152, 57344, 59392, 59424,     0,     1, 
+    49152, 57344, 59392, 59424, 59428,     0,     1, 49152, 
+    57344, 59392, 59424, 59428,     0,     1, 49152, 57344, 
+    59392, 59424, 59432, 59430,     0,     1, 49152, 57344, 
+    59392, 59424,     0,     1, 49152, 57344, 59392, 59424, 
+    59432,     0,     1, 49152, 57344, 59392, 59424, 59432, 
+        0,     1, 49152, 57344, 59392, 59424, 59432, 59434, 
+        0,     1, 49152, 57344, 59392, 59424, 59432,     0, 
+        1, 49152, 57344, 59392, 59424, 59440, 59436,     0, 
+        1, 49152, 57344, 59392, 59424, 59440, 59436,     0, 
+        1, 49152, 57344, 59392, 59424, 59440, 59441, 59438, 
+        0,     1, 49152, 57344, 59392, 59424,     0,     1, 
+    49152, 57344, 59392, 59456, 59440,     0,     1, 49152, 
+    57344, 59392, 59456, 59440,     0,     1, 49152, 57344, 
+    59392, 59456, 59440, 59442,     0,     1, 49152, 57344, 
+    59392, 59456, 59440,     0,     1, 49152, 57344, 59392, 
+    59456, 59440, 59444,     0,     1, 49152, 57344, 59392, 
+    59456, 59440, 59444,     0,     1, 49152, 57344, 59392, 
+    59456, 59440, 59448, 59446,     0,     1, 49152, 57344, 
+    59392, 59456, 59440,     0,     1, 49152, 57344, 59392, 
+    59456, 59457, 59448,     0,     1, 49152, 57344, 59392, 
+    59456, 59457, 59448,     0,     1, 49152, 57344, 59392, 
+    59456, 59457, 59448, 59450,     0,     1, 49152, 57344, 
+    59392, 59456, 59457, 59448,     0,     1, 49152, 57344, 
+    59392, 59456, 59457, 59448, 59452,     0,     1, 49152, 
+    57344, 59392, 59456, 59457, 59459, 59452,     0,     1, 
+    49152, 57344, 59392, 59456, 59457, 59459, 59452, 59454, 
+        0,     1, 49152, 57344, 59392,     0,     1, 49152, 
+    57344, 59392, 59456,     0,     1, 49152, 57344, 59392, 
+    59456,     0,     1, 49152, 57344, 59392, 59456, 59458, 
+        0,     1, 49152, 57344, 59392, 59456,     0,     1, 
+    49152, 57344, 59392, 59456, 59460,     0,     1, 49152, 
+    57344, 59392, 59456, 59460,     0,     1, 49152, 57344, 
+    59392, 59456, 59464, 59462,     0,     1, 49152, 57344, 
+    59392, 59456,     0,     1, 49152, 57344, 59392, 59456, 
+    59464,     0,     1, 49152, 57344, 59392, 59456, 59464, 
+        0,     1, 49152, 57344, 59392, 59456, 59464, 59466, 
+        0,     1, 49152, 57344, 59392, 59456, 59464,     0, 
+        1, 49152, 57344, 59392, 59456, 59472, 59468,     0, 
+        1, 49152, 57344, 59392, 59456, 59472, 59468,     0, 
+        1, 49152, 57344, 59392, 59456, 59472, 59473, 59470, 
+        0,     1, 49152, 57344, 59392, 59456,     0,     1, 
+    49152, 57344, 59392, 59456, 59472,     0,     1, 49152, 
+    57344, 59392, 59456, 59472,     0,     1, 49152, 57344, 
+    59392, 59456, 59472, 59474,     0,     1, 49152, 57344, 
+    59392, 59456, 59472,     0,     1, 49152, 57344, 59392, 
+    59456, 59472, 59476,     0,     1, 49152, 57344, 59392, 
+    59456, 59472, 59476,     0,     1, 49152, 57344, 59392, 
+    59456, 59472, 59480, 59478,     0,     1, 49152, 57344, 
+    59392, 59456, 59472,     0,     1, 49152, 57344, 59392, 
+    59456, 59488, 59480,     0,     1, 49152, 57344, 59392, 
+    59456, 59488, 59480,     0,     1, 49152, 57344, 59392, 
+    59456, 59488, 59480, 59482,     0,     1, 49152, 57344, 
+    59392, 59456, 59488, 59480,     0,     1, 49152, 57344, 
+    59392, 59456, 59488, 59489, 59484,     0,     1, 49152, 
+    57344, 59392, 59456, 59488, 59489, 59484,     0,     1, 
+    49152, 57344, 59392, 59456, 59488, 59489, 59484, 59486, 
+        0,     1, 49152, 57344, 59392, 59456,     0,     1, 
+    49152, 57344, 59392, 59520, 59488,     0,     1, 49152, 
+    57344, 59392, 59520, 59488,     0,     1, 49152, 57344, 
+    59392, 59520, 59488, 59490,     0,     1, 49152, 57344, 
+    59392, 59520, 59488,     0,     1, 49152, 57344, 59392, 
+    59520, 59488, 59492,     0,     1, 49152, 57344, 59392, 
+    59520, 59488, 59492,     0,     1, 49152, 57344, 59392, 
+    59520, 59488, 59496, 59494,     0,     1, 49152, 57344, 
+    59392, 59520, 59488,     0,     1, 49152, 57344, 59392, 
+    59520, 59488, 59496,     0,     1, 49152, 57344, 59392, 
+    59520, 59488, 59496,     0,     1, 49152, 57344, 59392, 
+    59520, 59488, 59496, 59498,     0,     1, 49152, 57344, 
+    59392, 59520, 59488, 59496,     0,     1, 49152, 57344, 
+    59392, 59520, 59488, 59504, 59500,     0,     1, 49152, 
+    57344, 59392, 59520, 59488, 59504, 59500,     0,     1, 
+    49152, 57344, 59392, 59520, 59488, 59504, 59505, 59502, 
+        0,     1, 49152, 57344, 59392, 59520, 59488,     0, 
+        1, 49152, 57344, 59392, 59520, 59521, 59504,     0, 
+        1, 49152, 57344, 59392, 59520, 59521, 59504,     0, 
+        1, 49152, 57344, 59392, 59520, 59521, 59504, 59506, 
+        0,     1, 49152, 57344, 59392, 59520, 59521, 59504, 
+        0,     1, 49152, 57344, 59392, 59520, 59521, 59504, 
+    59508,     0,     1, 49152, 57344, 59392, 59520, 59521, 
+    59504, 59508,     0,     1, 49152, 57344, 59392, 59520, 
+    59521, 59504, 59512, 59510,     0,     1, 49152, 57344, 
+    59392, 59520, 59521, 59504,     0,     1, 49152, 57344, 
+    59392, 59520, 59521, 59504, 59512,     0,     1, 49152, 
+    57344, 59392, 59520, 59521, 59523, 59512,     0,     1, 
+    49152, 57344, 59392, 59520, 59521, 59523, 59512, 59514, 
+        0,     1, 49152, 57344, 59392, 59520, 59521, 59523, 
+    59512,     0,     1, 49152, 57344, 59392, 59520, 59521, 
+    59523, 59512, 59516,     0,     1, 49152, 57344, 59392, 
+    59520, 59521, 59523, 59512, 59516,     0,     1, 49152, 
+    57344, 59392, 59520, 59521, 59523, 59512, 59516, 59518, 
+        0,     1, 49152, 57344, 59392,     0,     1, 49152, 
+    57344, 59392, 59520,     0,     1, 49152, 57344, 59392, 
+    59520,     0,     1, 49152, 57344, 59392, 59520, 59522, 
+        0,     1, 49152, 57344, 59392, 59520,     0,     1, 
+    49152, 57344, 59392, 59520, 59524,     0,     1, 49152, 
+    57344, 59392, 59520, 59524,     0,     1, 49152, 57344, 
+    59392, 59520, 59528, 59526,     0,     1, 49152, 57344, 
+    59392, 59520,     0,     1, 49152, 57344, 59392, 59520, 
+    59528,     0,     1, 49152, 57344, 59392, 59520, 59528, 
+        0,     1, 49152, 57344, 59392, 59520, 59528, 59530, 
+        0,     1, 49152, 57344, 59392, 59520, 59528,     0, 
+        1, 49152, 57344, 59392, 59520, 59536, 59532,     0, 
+        1, 49152, 57344, 59392, 59520, 59536, 59532,     0, 
+        1, 49152, 57344, 59392, 59520, 59536, 59537, 59534, 
+        0,     1, 49152, 57344, 59392, 59520,     0,     1, 
+    49152, 57344, 59392, 59520, 59536,     0,     1, 49152, 
+    57344, 59392, 59520, 59536,     0,     1, 49152, 57344, 
+    59392, 59520, 59536, 59538,     0,     1, 49152, 57344, 
+    59392, 59520, 59536,     0,     1, 49152, 57344, 59392, 
+    59520, 59536, 59540,     0,     1, 49152, 57344, 59392, 
+    59520, 59536, 59540,     0,     1, 49152, 57344, 59392, 
+    59520, 59536, 59544, 59542,     0,     1, 49152, 57344, 
+    59392, 59520, 59536,     0,     1, 49152, 57344, 59392, 
+    59520, 59552, 59544,     0,     1, 49152, 57344, 59392, 
+    59520, 59552, 59544,     0,     1, 49152, 57344, 59392, 
+    59520, 59552, 59544, 59546,     0,     1, 49152, 57344, 
+    59392, 59520, 59552, 59544,     0,     1, 49152, 57344, 
+    59392, 59520, 59552, 59553, 59548,     0,     1, 49152, 
+    57344, 59392, 59520, 59552, 59553, 59548,     0,     1, 
+    49152, 57344, 59392, 59520, 59552, 59553, 59548, 59550, 
+        0,     1, 49152, 57344, 59392, 59520,     0,     1, 
+    49152, 57344, 59392, 59520, 59552,     0,     1, 49152, 
+    57344, 59392, 59520, 59552,     0,     1, 49152, 57344, 
+    59392, 59520, 59552, 59554,     0,     1, 49152, 57344, 
+    59392, 59520, 59552,     0,     1, 49152, 57344, 59392, 
+    59520, 59552, 59556,     0,     1, 49152, 57344, 59392, 
+    59520, 59552, 59556,     0,     1, 49152, 57344, 59392, 
+    59520, 59552, 59560, 59558,     0,     1, 49152, 57344, 
+    59392, 59520, 59552,     0,     1, 49152, 57344, 59392, 
+    59520, 59552, 59560,     0,     1, 49152, 57344, 59392, 
+    59520, 59552, 59560,     0,     1, 49152, 57344, 59392, 
+    59520, 59552, 59560, 59562,     0,     1, 49152, 57344, 
+    59392, 59520, 59552, 59560,     0,     1, 49152, 57344, 
+    59392, 59520, 59552, 59568, 59564,     0,     1, 49152, 
+    57344, 59392, 59520, 59552, 59568, 59564,     0,     1, 
+    49152, 57344, 59392, 59520, 59552, 59568, 59569, 59566, 
+        0,     1, 49152, 57344, 59392, 59520, 59552,     0, 
+        1, 49152, 57344, 59392, 59520, 59584, 59568,     0, 
+        1, 49152, 57344, 59392, 59520, 59584, 59568,     0, 
+        1, 49152, 57344, 59392, 59520, 59584, 59568, 59570, 
+        0,     1, 49152, 57344, 59392, 59520, 59584, 59568, 
+        0,     1, 49152, 57344, 59392, 59520, 59584, 59568, 
+    59572,     0,     1, 49152, 57344, 59392, 59520, 59584, 
+    59568, 59572,     0,     1, 49152, 57344, 59392, 59520, 
+    59584, 59568, 59576, 59574,     0,     1, 49152, 57344, 
+    59392, 59520, 59584, 59568,     0,     1, 49152, 57344, 
+    59392, 59520, 59584, 59585, 59576,     0,     1, 49152, 
+    57344, 59392, 59520, 59584, 59585, 59576,     0,     1, 
+    49152, 57344, 59392, 59520, 59584, 59585, 59576, 59578, 
+        0,     1, 49152, 57344, 59392, 59520, 59584, 59585, 
+    59576,     0,     1, 49152, 57344, 59392, 59520, 59584, 
+    59585, 59576, 59580,     0,     1, 49152, 57344, 59392, 
+    59520, 59584, 59585, 59587, 59580,     0,     1, 49152, 
+    57344, 59392, 59520, 59584, 59585, 59587, 59580, 59582, 
+        0,     1, 49152, 57344, 59392, 59520,     0,     1, 
+    49152, 57344, 59392, 59648, 59584,     0,     1, 49152, 
+    57344, 59392, 59648, 59584,     0,     1, 49152, 57344, 
+    59392, 59648, 59584, 59586,     0,     1, 49152, 57344, 
+    59392, 59648, 59584,     0,     1, 49152, 57344, 59392, 
+    59648, 59584, 59588,     0,     1, 49152, 57344, 59392, 
+    59648, 59584, 59588,     0,     1, 49152, 57344, 59392, 
+    59648, 59584, 59592, 59590,     0,     1, 49152, 57344, 
+    59392, 59648, 59584,     0,     1, 49152, 57344, 59392, 
+    59648, 59584, 59592,     0,     1, 49152, 57344, 59392, 
+    59648, 59584, 59592,     0,     1, 49152, 57344, 59392, 
+    59648, 59584, 59592, 59594,     0,     1, 49152, 57344, 
+    59392, 59648, 59584, 59592,     0,     1, 49152, 57344, 
+    59392, 59648, 59584, 59600, 59596,     0,     1, 49152, 
+    57344, 59392, 59648, 59584, 59600, 59596,     0,     1, 
+    49152, 57344, 59392, 59648, 59584, 59600, 59601, 59598, 
+        0,     1, 49152, 57344, 59392, 59648, 59584,     0, 
+        1, 49152, 57344, 59392, 59648, 59584, 59600,     0, 
+        1, 49152, 57344, 59392, 59648, 59584, 59600,     0, 
+        1, 49152, 57344, 59392, 59648, 59584, 59600, 59602, 
+        0,     1, 49152, 57344, 59392, 59648, 59584, 59600, 
+        0,     1, 49152, 57344, 59392, 59648, 59584, 59600, 
+    59604,     0,     1, 49152, 57344, 59392, 59648, 59584, 
+    59600, 59604,     0,     1, 49152, 57344, 59392, 59648, 
+    59584, 59600, 59608, 59606,     0,     1, 49152, 57344, 
+    59392, 59648, 59584, 59600,     0,     1, 49152, 57344, 
+    59392, 59648, 59584, 59616, 59608,     0,     1, 49152, 
+    57344, 59392, 59648, 59584, 59616, 59608,     0,     1, 
+    49152, 57344, 59392, 59648, 59584, 59616, 59608, 59610, 
+        0,     1, 49152, 57344, 59392, 59648, 59584, 59616, 
+    59608,     0,     1, 49152, 57344, 59392, 59648, 59584, 
+    59616, 59617, 59612,     0,     1, 49152, 57344, 59392, 
+    59648, 59584, 59616, 59617, 59612,     0,     1, 49152, 
+    57344, 59392, 59648, 59584, 59616, 59617, 59612, 59614, 
+        0,     1, 49152, 57344, 59392, 59648, 59584,     0, 
+        1, 49152, 57344, 59392, 59648, 59649, 59616,     0, 
+        1, 49152, 57344, 59392, 59648, 59649, 59616,     0, 
+        1, 49152, 57344, 59392, 59648, 59649, 59616, 59618, 
+        0,     1, 49152, 57344, 59392, 59648, 59649, 59616, 
+        0,     1, 49152, 57344, 59392, 59648, 59649, 59616, 
+    59620,     0,     1, 49152, 57344, 59392, 59648, 59649, 
+    59616, 59620,     0,     1, 49152, 57344, 59392, 59648, 
+    59649, 59616, 59624, 59622,     0,     1, 49152, 57344, 
+    59392, 59648, 59649, 59616,     0,     1, 49152, 57344, 
+    59392, 59648, 59649, 59616, 59624,     0,     1, 49152, 
+    57344, 59392, 59648, 59649, 59616, 59624,     0,     1, 
+    49152, 57344, 59392, 59648, 59649, 59616, 59624, 59626, 
+        0,     1, 49152, 57344, 59392, 59648, 59649, 59616, 
+    59624,     0,     1, 49152, 57344, 59392, 59648, 59649, 
+    59616, 59632, 59628,     0,     1, 49152, 57344, 59392, 
+    59648, 59649, 59616, 59632, 59628,     0,     1, 49152, 
+    57344, 59392, 59648, 59649, 59616, 59632, 59633, 59630, 
+        0,     1, 49152, 57344, 59392, 59648, 59649, 59616, 
+        0,     1, 49152, 57344, 59392, 59648, 59649, 59616, 
+    59632,     0,     1, 49152, 57344, 59392, 59648, 59649, 
+    59651, 59632,     0,     1, 49152, 57344, 59392, 59648, 
+    59649, 59651, 59632, 59634,     0,     1, 49152, 57344, 
+    59392, 59648, 59649, 59651, 59632,     0,     1, 49152, 
+    57344, 59392, 59648, 59649, 59651, 59632, 59636,     0, 
+        1, 49152, 57344, 59392, 59648, 59649, 59651, 59632, 
+    59636,     0,     1, 49152, 57344, 59392, 59648, 59649, 
+    59651, 59632, 59640, 59638,     0,     1, 49152, 57344, 
+    59392, 59648, 59649, 59651, 59632,     0,     1, 49152, 
+    57344, 59392, 59648, 59649, 59651, 59632, 59640,     0, 
+        1, 49152, 57344, 59392, 59648, 59649, 59651, 59632, 
+    59640,     0,     1, 49152, 57344, 59392, 59648, 59649, 
+    59651, 59632, 59640, 59642,     0,     1, 49152, 57344, 
+    59392, 59648, 59649, 59651, 59655, 59640,     0,     1, 
+    49152, 57344, 59392, 59648, 59649, 59651, 59655, 59640, 
+    59644,     0,     1, 49152, 57344, 59392, 59648, 59649, 
+    59651, 59655, 59640, 59644,     0,     1, 49152, 57344, 
+    59392, 59648, 59649, 59651, 59655, 59640, 59644, 59646, 
+        0,     1, 49152, 57344, 59392,     0,     1, 49152, 
+    57344, 59392, 59648,     0,     1, 49152, 57344, 59392, 
+    59648,     0,     1, 49152, 57344, 59392, 59648, 59650, 
+        0,     1, 49152, 57344, 59392, 59648,     0,     1, 
+    49152, 57344, 59392, 59648, 59652,     0,     1, 49152, 
+    57344, 59392, 59648, 59652,     0,     1, 49152, 57344, 
+    59392, 59648, 59656, 59654,     0,     1, 49152, 57344, 
+    59392, 59648,     0,     1, 49152, 57344, 59392, 59648, 
+    59656,     0,     1, 49152, 57344, 59392, 59648, 59656, 
+        0,     1, 49152, 57344, 59392, 59648, 59656, 59658, 
+        0,     1, 49152, 57344, 59392, 59648, 59656,     0, 
+        1, 49152, 57344, 59392, 59648, 59664, 59660,     0, 
+        1, 49152, 57344, 59392, 59648, 59664, 59660,     0, 
+        1, 49152, 57344, 59392, 59648, 59664, 59665, 59662, 
+        0,     1, 49152, 57344, 59392, 59648,     0,     1, 
+    49152, 57344, 59392, 59648, 59664,     0,     1, 49152, 
+    57344, 59392, 59648, 59664,     0,     1, 49152, 57344, 
+    59392, 59648, 59664, 59666,     0,     1, 49152, 57344, 
+    59392, 59648, 59664,     0,     1, 49152, 57344, 59392, 
+    59648, 59664, 59668,     0,     1, 49152, 57344, 59392, 
+    59648, 59664, 59668,     0,     1, 49152, 57344, 59392, 
+    59648, 59664, 59672, 59670,     0,     1, 49152, 57344, 
+    59392, 59648, 59664,     0,     1, 49152, 57344, 59392, 
+    59648, 59680, 59672,     0,     1, 49152, 57344, 59392, 
+    59648, 59680, 59672,     0,     1, 49152, 57344, 59392, 
+    59648, 59680, 59672, 59674,     0,     1, 49152, 57344, 
+    59392, 59648, 59680, 59672,     0,     1, 49152, 57344, 
+    59392, 59648, 59680, 59681, 59676,     0,     1, 49152, 
+    57344, 59392, 59648, 59680, 59681, 59676,     0,     1, 
+    49152, 57344, 59392, 59648, 59680, 59681, 59676, 59678, 
+        0,     1, 49152, 57344, 59392, 59648,     0,     1, 
+    49152, 57344, 59392, 59648, 59680,     0,     1, 49152, 
+    57344, 59392, 59648, 59680,     0,     1, 49152, 57344, 
+    59392, 59648, 59680, 59682,     0,     1, 49152, 57344, 
+    59392, 59648, 59680,     0,     1, 49152, 57344, 59392, 
+    59648, 59680, 59684,     0,     1, 49152, 57344, 59392, 
+    59648, 59680, 59684,     0,     1, 49152, 57344, 59392, 
+    59648, 59680, 59688, 59686,     0,     1, 49152, 57344, 
+    59392, 59648, 59680,     0,     1, 49152, 57344, 59392, 
+    59648, 59680, 59688,     0,     1, 49152, 57344, 59392, 
+    59648, 59680, 59688,     0,     1, 49152, 57344, 59392, 
+    59648, 59680, 59688, 59690,     0,     1, 49152, 57344, 
+    59392, 59648, 59680, 59688,     0,     1, 49152, 57344, 
+    59392, 59648, 59680, 59696, 59692,     0,     1, 49152, 
+    57344, 59392, 59648, 59680, 59696, 59692,     0,     1, 
+    49152, 57344, 59392, 59648, 59680, 59696, 59697, 59694, 
+        0,     1, 49152, 57344, 59392, 59648, 59680,     0, 
+        1, 49152, 57344, 59392, 59648, 59712, 59696,     0, 
+        1, 49152, 57344, 59392, 59648, 59712, 59696,     0, 
+        1, 49152, 57344, 59392, 59648, 59712, 59696, 59698, 
+        0,     1, 49152, 57344, 59392, 59648, 59712, 59696, 
+        0,     1, 49152, 57344, 59392, 59648, 59712, 59696, 
+    59700,     0,     1, 49152, 57344, 59392, 59648, 59712, 
+    59696, 59700,     0,     1, 49152, 57344, 59392, 59648, 
+    59712, 59696, 59704, 59702,     0,     1, 49152, 57344, 
+    59392, 59648, 59712, 59696,     0,     1, 49152, 57344, 
+    59392, 59648, 59712, 59713, 59704,     0,     1, 49152, 
+    57344, 59392, 59648, 59712, 59713, 59704,     0,     1, 
+    49152, 57344, 59392, 59648, 59712, 59713, 59704, 59706, 
+        0,     1, 49152, 57344, 59392, 59648, 59712, 59713, 
+    59704,     0,     1, 49152, 57344, 59392, 59648, 59712, 
+    59713, 59704, 59708,     0,     1, 49152, 57344, 59392, 
+    59648, 59712, 59713, 59715, 59708,     0,     1, 49152, 
+    57344, 59392, 59648, 59712, 59713, 59715, 59708, 59710, 
+        0,     1, 49152, 57344, 59392, 59648,     0,     1, 
+    49152, 57344, 59392, 59648, 59712,     0,     1, 49152, 
+    57344, 59392, 59648, 59712,     0,     1, 49152, 57344, 
+    59392, 59648, 59712, 59714,     0,     1, 49152, 57344, 
+    59392, 59648, 59712,     0,     1, 49152, 57344, 59392, 
+    59648, 59712, 59716,     0,     1, 49152, 57344, 59392, 
+    59648, 59712, 59716,     0,     1, 49152, 57344, 59392, 
+    59648, 59712, 59720, 59718,     0,     1, 49152, 57344, 
+    59392, 59648, 59712,     0,     1, 49152, 57344, 59392, 
+    59648, 59712, 59720,     0,     1, 49152, 57344, 59392, 
+    59648, 59712, 59720,     0,     1, 49152, 57344, 59392, 
+    59648, 59712, 59720, 59722,     0,     1, 49152, 57344, 
+    59392, 59648, 59712, 59720,     0,     1, 49152, 57344, 
+    59392, 59648, 59712, 59728, 59724,     0,     1, 49152, 
+    57344, 59392, 59648, 59712, 59728, 59724,     0,     1, 
+    49152, 57344, 59392, 59648, 59712, 59728, 59729, 59726, 
+        0,     1, 49152, 57344, 59392, 59648, 59712,     0, 
+        1, 49152, 57344, 59392, 59648, 59712, 59728,     0, 
+        1, 49152, 57344, 59392, 59648, 59712, 59728,     0, 
+        1, 49152, 57344, 59392, 59648, 59712, 59728, 59730, 
+        0,     1, 49152, 57344, 59392, 59648, 59712, 59728, 
+        0,     1, 49152, 57344, 59392, 59648, 59712, 59728, 
+    59732,     0,     1, 49152, 57344, 59392, 59648, 59712, 
+    59728, 59732,     0,     1, 49152, 57344, 59392, 59648, 
+    59712, 59728, 59736, 59734,     0,     1, 49152, 57344, 
+    59392, 59648, 59712, 59728,     0,     1, 49152, 57344, 
+    59392, 59648, 59712, 59744, 59736,     0,     1, 49152, 
+    57344, 59392, 59648, 59712, 59744, 59736,     0,     1, 
+    49152, 57344, 59392, 59648, 59712, 59744, 59736, 59738, 
+        0,     1, 49152, 57344, 59392, 59648, 59712, 59744, 
+    59736,     0,     1, 49152, 57344, 59392, 59648, 59712, 
+    59744, 59745, 59740,     0,     1, 49152, 57344, 59392, 
+    59648, 59712, 59744, 59745, 59740,     0,     1, 49152, 
+    57344, 59392, 59648, 59712, 59744, 59745, 59740, 59742, 
+        0,     1, 49152, 57344, 59392, 59648, 59712,     0, 
+        1, 49152, 57344, 59392, 59648, 59776, 59744,     0, 
+        1, 49152, 57344, 59392, 59648, 59776, 59744,     0, 
+        1, 49152, 57344, 59392, 59648, 59776, 59744, 59746, 
+        0,     1, 49152, 57344, 59392, 59648, 59776, 59744, 
+        0,     1, 49152, 57344, 59392, 59648, 59776, 59744, 
+    59748,     0,     1, 49152, 57344, 59392, 59648, 59776, 
+    59744, 59748,     0,     1, 49152, 57344, 59392, 59648, 
+    59776, 59744, 59752, 59750,     0,     1, 49152, 57344, 
+    59392, 59648, 59776, 59744,     0,     1, 49152, 57344, 
+    59392, 59648, 59776, 59744, 59752,     0,     1, 49152, 
+    57344, 59392, 59648, 59776, 59744, 59752,     0,     1, 
+    49152, 57344, 59392, 59648, 59776, 59744, 59752, 59754, 
+        0,     1, 49152, 57344, 59392, 59648, 59776, 59744, 
+    59752,     0,     1, 49152, 57344, 59392, 59648, 59776, 
+    59744, 59760, 59756,     0,     1, 49152, 57344, 59392, 
+    59648, 59776, 59744, 59760, 59756,     0,     1, 49152, 
+    57344, 59392, 59648, 59776, 59744, 59760, 59761, 59758, 
+        0,     1, 49152, 57344, 59392, 59648, 59776, 59744, 
+        0,     1, 49152, 57344, 59392, 59648, 59776, 59777, 
+    59760,     0,     1, 49152, 57344, 59392, 59648, 59776, 
+    59777, 59760,     0,     1, 49152, 57344, 59392, 59648, 
+    59776, 59777, 59760, 59762,     0,     1, 49152, 57344, 
+    59392, 59648, 59776, 59777, 59760,     0,     1, 49152, 
+    57344, 59392, 59648, 59776, 59777, 59760, 59764,     0, 
+        1, 49152, 57344, 59392, 59648, 59776, 59777, 59760, 
+    59764,     0,     1, 49152, 57344, 59392, 59648, 59776, 
+    59777, 59760, 59768, 59766,     0,     1, 49152, 57344, 
+    59392, 59648, 59776, 59777, 59760,     0,     1, 49152, 
+    57344, 59392, 59648, 59776, 59777, 59760, 59768,     0, 
+        1, 49152, 57344, 59392, 59648, 59776, 59777, 59779, 
+    59768,     0,     1, 49152, 57344, 59392, 59648, 59776, 
+    59777, 59779, 59768, 59770,     0,     1, 49152, 57344, 
+    59392, 59648, 59776, 59777, 59779, 59768,     0,     1, 
+    49152, 57344, 59392, 59648, 59776, 59777, 59779, 59768, 
+    59772,     0,     1, 49152, 57344, 59392, 59648, 59776, 
+    59777, 59779, 59768, 59772,     0,     1, 49152, 57344, 
+    59392, 59648, 59776, 59777, 59779, 59768, 59772, 59774, 
+        0,     1, 49152, 57344, 59392, 59648,     0,     1, 
+    49152, 57344, 59392, 59904, 59776,     0,     1, 49152, 
+    57344, 59392, 59904, 59776,     0,     1, 49152, 57344, 
+    59392, 59904, 59776, 59778,     0,     1, 49152, 57344, 
+    59392, 59904, 59776,     0,     1, 49152, 57344, 59392, 
+    59904, 59776, 59780,     0,     1, 49152, 57344, 59392, 
+    59904, 59776, 59780,     0,     1, 49152, 57344, 59392, 
+    59904, 59776, 59784, 59782,     0,     1, 49152, 57344, 
+    59392, 59904, 59776,     0,     1, 49152, 57344, 59392, 
+    59904, 59776, 59784,     0,     1, 49152, 57344, 59392, 
+    59904, 59776, 59784,     0,     1, 49152, 57344, 59392, 
+    59904, 59776, 59784, 59786,     0,     1, 49152, 57344, 
+    59392, 59904, 59776, 59784,     0,     1, 49152, 57344, 
+    59392, 59904, 59776, 59792, 59788,     0,     1, 49152, 
+    57344, 59392, 59904, 59776, 59792, 59788,     0,     1, 
+    49152, 57344, 59392, 59904, 59776, 59792, 59793, 59790, 
+        0,     1, 49152, 57344, 59392, 59904, 59776,     0, 
+        1, 49152, 57344, 59392, 59904, 59776, 59792,     0, 
+        1, 49152, 57344, 59392, 59904, 59776, 59792,     0, 
+        1, 49152, 57344, 59392, 59904, 59776, 59792, 59794, 
+        0,     1, 49152, 57344, 59392, 59904, 59776, 59792, 
+        0,     1, 49152, 57344, 59392, 59904, 59776, 59792, 
+    59796,     0,     1, 49152, 57344, 59392, 59904, 59776, 
+    59792, 59796,     0,     1, 49152, 57344, 59392, 59904, 
+    59776, 59792, 59800, 59798,     0,     1, 49152, 57344, 
+    59392, 59904, 59776, 59792,     0,     1, 49152, 57344, 
+    59392, 59904, 59776, 59808, 59800,     0,     1, 49152, 
+    57344, 59392, 59904, 59776, 59808, 59800,     0,     1, 
+    49152, 57344, 59392, 59904, 59776, 59808, 59800, 59802, 
+        0,     1, 49152, 57344, 59392, 59904, 59776, 59808, 
+    59800,     0,     1, 49152, 57344, 59392, 59904, 59776, 
+    59808, 59809, 59804,     0,     1, 49152, 57344, 59392, 
+    59904, 59776, 59808, 59809, 59804,     0,     1, 49152, 
+    57344, 59392, 59904, 59776, 59808, 59809, 59804, 59806, 
+        0,     1, 49152, 57344, 59392, 59904, 59776,     0, 
+        1, 49152, 57344, 59392, 59904, 59776, 59808,     0, 
+        1, 49152, 57344, 59392, 59904, 59776, 59808,     0, 
+        1, 49152, 57344, 59392, 59904, 59776, 59808, 59810, 
+        0,     1, 49152, 57344, 59392, 59904, 59776, 59808, 
+        0,     1, 49152, 57344, 59392, 59904, 59776, 59808, 
+    59812,     0,     1, 49152, 57344, 59392, 59904, 59776, 
+    59808, 59812,     0,     1, 49152, 57344, 59392, 59904, 
+    59776, 59808, 59816, 59814,     0,     1, 49152, 57344, 
+    59392, 59904, 59776, 59808,     0,     1, 49152, 57344, 
+    59392, 59904, 59776, 59808, 59816,     0,     1, 49152, 
+    57344, 59392, 59904, 59776, 59808, 59816,     0,     1, 
+    49152, 57344, 59392, 59904, 59776, 59808, 59816, 59818, 
+        0,     1, 49152, 57344, 59392, 59904, 59776, 59808, 
+    59816,     0,     1, 49152, 57344, 59392, 59904, 59776, 
+    59808, 59824, 59820,     0,     1, 49152, 57344, 59392, 
+    59904, 59776, 59808, 59824, 59820,     0,     1, 49152, 
+    57344, 59392, 59904, 59776, 59808, 59824, 59825, 59822, 
+        0,     1, 49152, 57344, 59392, 59904, 59776, 59808, 
+        0,     1, 49152, 57344, 59392, 59904, 59776, 59840, 
+    59824,     0,     1, 49152, 57344, 59392, 59904, 59776, 
+    59840, 59824,     0,     1, 49152, 57344, 59392, 59904, 
+    59776, 59840, 59824, 59826,     0,     1, 49152, 57344, 
+    59392, 59904, 59776, 59840, 59824,     0,     1, 49152, 
+    57344, 59392, 59904, 59776, 59840, 59824, 59828,     0, 
+        1, 49152, 57344, 59392, 59904, 59776, 59840, 59824, 
+    59828,     0,     1, 49152, 57344, 59392, 59904, 59776, 
+    59840, 59824, 59832, 59830,     0,     1, 49152, 57344, 
+    59392, 59904, 59776, 59840, 59824,     0,     1, 49152, 
+    57344, 59392, 59904, 59776, 59840, 59841, 59832,     0, 
+        1, 49152, 57344, 59392, 59904, 59776, 59840, 59841, 
+    59832,     0,     1, 49152, 57344, 59392, 59904, 59776, 
+    59840, 59841, 59832, 59834,     0,     1, 49152, 57344, 
+    59392, 59904, 59776, 59840, 59841, 59832,     0,     1, 
+    49152, 57344, 59392, 59904, 59776, 59840, 59841, 59832, 
+    59836,     0,     1, 49152, 57344, 59392, 59904, 59776, 
+    59840, 59841, 59843, 59836,     0,     1, 49152, 57344, 
+    59392, 59904, 59776, 59840, 59841, 59843, 59836, 59838, 
+        0,     1, 49152, 57344, 59392, 59904, 59776,     0, 
+        1, 49152, 57344, 59392, 59904, 59905, 59840,     0, 
+        1, 49152, 57344, 59392, 59904, 59905, 59840,     0, 
+        1, 49152, 57344, 59392, 59904, 59905, 59840, 59842, 
+        0,     1, 49152, 57344, 59392, 59904, 59905, 59840, 
+        0,     1, 49152, 57344, 59392, 59904, 59905, 59840, 
+    59844,     0,     1, 49152, 57344, 59392, 59904, 59905, 
+    59840, 59844,     0,     1, 49152, 57344, 59392, 59904, 
+    59905, 59840, 59848, 59846,     0,     1, 49152, 57344, 
+    59392, 59904, 59905, 59840,     0,     1, 49152, 57344, 
+    59392, 59904, 59905, 59840, 59848,     0,     1, 49152, 
+    57344, 59392, 59904, 59905, 59840, 59848,     0,     1, 
+    49152, 57344, 59392, 59904, 59905, 59840, 59848, 59850, 
+        0,     1, 49152, 57344, 59392, 59904, 59905, 59840, 
+    59848,     0,     1, 49152, 57344, 59392, 59904, 59905, 
+    59840, 59856, 59852,     0,     1, 49152, 57344, 59392, 
+    59904, 59905, 59840, 59856, 59852,     0,     1, 49152, 
+    57344, 59392, 59904, 59905, 59840, 59856, 59857, 59854, 
+        0,     1, 49152, 57344, 59392, 59904, 59905, 59840, 
+        0,     1, 49152, 57344, 59392, 59904, 59905, 59840, 
+    59856,     0,     1, 49152, 57344, 59392, 59904, 59905, 
+    59840, 59856,     0,     1, 49152, 57344, 59392, 59904, 
+    59905, 59840, 59856, 59858,     0,     1, 49152, 57344, 
+    59392, 59904, 59905, 59840, 59856,     0,     1, 49152, 
+    57344, 59392, 59904, 59905, 59840, 59856, 59860,     0, 
+        1, 49152, 57344, 59392, 59904, 59905, 59840, 59856, 
+    59860,     0,     1, 49152, 57344, 59392, 59904, 59905, 
+    59840, 59856, 59864, 59862,     0,     1, 49152, 57344, 
+    59392, 59904, 59905, 59840, 59856,     0,     1, 49152, 
+    57344, 59392, 59904, 59905, 59840, 59872, 59864,     0, 
+        1, 49152, 57344, 59392, 59904, 59905, 59840, 59872, 
+    59864,     0,     1, 49152, 57344, 59392, 59904, 59905, 
+    59840, 59872, 59864, 59866,     0,     1, 49152, 57344, 
+    59392, 59904, 59905, 59840, 59872, 59864,     0,     1, 
+    49152, 57344, 59392, 59904, 59905, 59840, 59872, 59873, 
+    59868,     0,     1, 49152, 57344, 59392, 59904, 59905, 
+    59840, 59872, 59873, 59868,     0,     1, 49152, 57344, 
+    59392, 59904, 59905, 59840, 59872, 59873, 59868, 59870, 
+        0,     1, 49152, 57344, 59392, 59904, 59905, 59840, 
+        0,     1, 49152, 57344, 59392, 59904, 59905, 59840, 
+    59872,     0,     1, 49152, 57344, 59392, 59904, 59905, 
+    59907, 59872,     0,     1, 49152, 57344, 59392, 59904, 
+    59905, 59907, 59872, 59874,     0,     1, 49152, 57344, 
+    59392, 59904, 59905, 59907, 59872,     0,     1, 49152, 
+    57344, 59392, 59904, 59905, 59907, 59872, 59876,     0, 
+        1, 49152, 57344, 59392, 59904, 59905, 59907, 59872, 
+    59876,     0,     1, 49152, 57344, 59392, 59904, 59905, 
+    59907, 59872, 59880, 59878,     0,     1, 49152, 57344, 
+    59392, 59904, 59905, 59907, 59872,     0,     1, 49152, 
+    57344, 59392, 59904, 59905, 59907, 59872, 59880,     0, 
+        1, 49152, 57344, 59392, 59904, 59905, 59907, 59872, 
+    59880,     0,     1, 49152, 57344, 59392, 59904, 59905, 
+    59907, 59872, 59880, 59882,     0,     1, 49152, 57344, 
+    59392, 59904, 59905, 59907, 59872, 59880,     0,     1, 
+    49152, 57344, 59392, 59904, 59905, 59907, 59872, 59888, 
+    59884,     0,     1, 49152, 57344, 59392, 59904, 59905, 
+    59907, 59872, 59888, 59884,     0,     1, 49152, 57344, 
+    59392, 59904, 59905, 59907, 59872, 59888, 59889, 59886, 
+        0,     1, 49152, 57344, 59392, 59904, 59905, 59907, 
+    59872,     0,     1, 49152, 57344, 59392, 59904, 59905, 
+    59907, 59872, 59888,     0,     1, 49152, 57344, 59392, 
+    59904, 59905, 59907, 59872, 59888,     0,     1, 49152, 
+    57344, 59392, 59904, 59905, 59907, 59872, 59888, 59890, 
+        0,     1, 49152, 57344, 59392, 59904, 59905, 59907, 
+    59911, 59888,     0,     1, 49152, 57344, 59392, 59904, 
+    59905, 59907, 59911, 59888, 59892,     0,     1, 49152, 
+    57344, 59392, 59904, 59905, 59907, 59911, 59888, 59892, 
+        0,     1, 49152, 57344, 59392, 59904, 59905, 59907, 
+    59911, 59888, 59896, 59894,     0,     1, 49152, 57344, 
+    59392, 59904, 59905, 59907, 59911, 59888,     0,     1, 
+    49152, 57344, 59392, 59904, 59905, 59907, 59911, 59888, 
+    59896,     0,     1, 49152, 57344, 59392, 59904, 59905, 
+    59907, 59911, 59888, 59896,     0,     1, 49152, 57344, 
+    59392, 59904, 59905, 59907, 59911, 59888, 59896, 59898, 
+        0,     1, 49152, 57344, 59392, 59904, 59905, 59907, 
+    59911, 59888, 59896,     0,     1, 49152, 57344, 59392, 
+    59904, 59905, 59907, 59911, 59888, 59896, 59900,     0, 
+        1, 49152, 57344, 59392, 59904, 59905, 59907, 59911, 
+    59888, 59896, 59900,     0,     1, 49152, 57344, 59392, 
+    59904, 59905, 59907, 59911, 59888, 59896, 59900, 59902, 
+        0,     1, 49152, 57344, 59392,     0,     1, 49152, 
+    57344, 59392, 59904,     0,     1, 49152, 57344, 59392, 
+    59904,     0,     1, 49152, 57344, 59392, 59904, 59906, 
+        0,     1, 49152, 57344, 59392, 59904,     0,     1, 
+    49152, 57344, 59392, 59904, 59908,     0,     1, 49152, 
+    57344, 59392, 59904, 59908,     0,     1, 49152, 57344, 
+    59392, 59904, 59912, 59910,     0,     1, 49152, 57344, 
+    59392, 59904,     0,     1, 49152, 57344, 59392, 59904, 
+    59912,     0,     1, 49152, 57344, 59392, 59904, 59912, 
+        0,     1, 49152, 57344, 59392, 59904, 59912, 59914, 
+        0,     1, 49152, 57344, 59392, 59904, 59912,     0, 
+        1, 49152, 57344, 59392, 59904, 59920, 59916,     0, 
+        1, 49152, 57344, 59392, 59904, 59920, 59916,     0, 
+        1, 49152, 57344, 59392, 59904, 59920, 59921, 59918, 
+        0,     1, 49152, 57344, 59392, 59904,     0,     1, 
+    49152, 57344, 59392, 59904, 59920,     0,     1, 49152, 
+    57344, 59392, 59904, 59920,     0,     1, 49152, 57344, 
+    59392, 59904, 59920, 59922,     0,     1, 49152, 57344, 
+    59392, 59904, 59920,     0,     1, 49152, 57344, 59392, 
+    59904, 59920, 59924,     0,     1, 49152, 57344, 59392, 
+    59904, 59920, 59924,     0,     1, 49152, 57344, 59392, 
+    59904, 59920, 59928, 59926,     0,     1, 49152, 57344, 
+    59392, 59904, 59920,     0,     1, 49152, 57344, 59392, 
+    59904, 59936, 59928,     0,     1, 49152, 57344, 59392, 
+    59904, 59936, 59928,     0,     1, 49152, 57344, 59392, 
+    59904, 59936, 59928, 59930,     0,     1, 49152, 57344, 
+    59392, 59904, 59936, 59928,     0,     1, 49152, 57344, 
+    59392, 59904, 59936, 59937, 59932,     0,     1, 49152, 
+    57344, 59392, 59904, 59936, 59937, 59932,     0,     1, 
+    49152, 57344, 59392, 59904, 59936, 59937, 59932, 59934, 
+        0,     1, 49152, 57344, 59392, 59904,     0,     1, 
+    49152, 57344, 59392, 59904, 59936,     0,     1, 49152, 
+    57344, 59392, 59904, 59936,     0,     1, 49152, 57344, 
+    59392, 59904, 59936, 59938,     0,     1, 49152, 57344, 
+    59392, 59904, 59936,     0,     1, 49152, 57344, 59392, 
+    59904, 59936, 59940,     0,     1, 49152, 57344, 59392, 
+    59904, 59936, 59940,     0,     1, 49152, 57344, 59392, 
+    59904, 59936, 59944, 59942,     0,     1, 49152, 57344, 
+    59392, 59904, 59936,     0,     1, 49152, 57344, 59392, 
+    59904, 59936, 59944,     0,     1, 49152, 57344, 59392, 
+    59904, 59936, 59944,     0,     1, 49152, 57344, 59392, 
+    59904, 59936, 59944, 59946,     0,     1, 49152, 57344, 
+    59392, 59904, 59936, 59944,     0,     1, 49152, 57344, 
+    59392, 59904, 59936, 59952, 59948,     0,     1, 49152, 
+    57344, 59392, 59904, 59936, 59952, 59948,     0,     1, 
+    49152, 57344, 59392, 59904, 59936, 59952, 59953, 59950, 
+        0,     1, 49152, 57344, 59392, 59904, 59936,     0, 
+        1, 49152, 57344, 59392, 59904, 59968, 59952,     0, 
+        1, 49152, 57344, 59392, 59904, 59968, 59952,     0, 
+        1, 49152, 57344, 59392, 59904, 59968, 59952, 59954, 
+        0,     1, 49152, 57344, 59392, 59904, 59968, 59952, 
+        0,     1, 49152, 57344, 59392, 59904, 59968, 59952, 
+    59956,     0,     1, 49152, 57344, 59392, 59904, 59968, 
+    59952, 59956,     0,     1, 49152, 57344, 59392, 59904, 
+    59968, 59952, 59960, 59958,     0,     1, 49152, 57344, 
+    59392, 59904, 59968, 59952,     0,     1, 49152, 57344, 
+    59392, 59904, 59968, 59969, 59960,     0,     1, 49152, 
+    57344, 59392, 59904, 59968, 59969, 59960,     0,     1, 
+    49152, 57344, 59392, 59904, 59968, 59969, 59960, 59962, 
+        0,     1, 49152, 57344, 59392, 59904, 59968, 59969, 
+    59960,     0,     1, 49152, 57344, 59392, 59904, 59968, 
+    59969, 59960, 59964,     0,     1, 49152, 57344, 59392, 
+    59904, 59968, 59969, 59971, 59964,     0,     1, 49152, 
+    57344, 59392, 59904, 59968, 59969, 59971, 59964, 59966, 
+        0,     1, 49152, 57344, 59392, 59904,     0,     1, 
+    49152, 57344, 59392, 59904, 59968,     0,     1, 49152, 
+    57344, 59392, 59904, 59968,     0,     1, 49152, 57344, 
+    59392, 59904, 59968, 59970,     0,     1, 49152, 57344, 
+    59392, 59904, 59968,     0,     1, 49152, 57344, 59392, 
+    59904, 59968, 59972,     0,     1, 49152, 57344, 59392, 
+    59904, 59968, 59972,     0,     1, 49152, 57344, 59392, 
+    59904, 59968, 59976, 59974,     0,     1, 49152, 57344, 
+    59392, 59904, 59968,     0,     1, 49152, 57344, 59392, 
+    59904, 59968, 59976,     0,     1, 49152, 57344, 59392, 
+    59904, 59968, 59976,     0,     1, 49152, 57344, 59392, 
+    59904, 59968, 59976, 59978,     0,     1, 49152, 57344, 
+    59392, 59904, 59968, 59976,     0,     1, 49152, 57344, 
+    59392, 59904, 59968, 59984, 59980,     0,     1, 49152, 
+    57344, 59392, 59904, 59968, 59984, 59980,     0,     1, 
+    49152, 57344, 59392, 59904, 59968, 59984, 59985, 59982, 
+        0,     1, 49152, 57344, 59392, 59904, 59968,     0, 
+        1, 49152, 57344, 59392, 59904, 59968, 59984,     0, 
+        1, 49152, 57344, 59392, 59904, 59968, 59984,     0, 
+        1, 49152, 57344, 59392, 59904, 59968, 59984, 59986, 
+        0,     1, 49152, 57344, 59392, 59904, 59968, 59984, 
+        0,     1, 49152, 57344, 59392, 59904, 59968, 59984, 
+    59988,     0,     1, 49152, 57344, 59392, 59904, 59968, 
+    59984, 59988,     0,     1, 49152, 57344, 59392, 59904, 
+    59968, 59984, 59992, 59990,     0,     1, 49152, 57344, 
+    59392, 59904, 59968, 59984,     0,     1, 49152, 57344, 
+    59392, 59904, 59968, 60000, 59992,     0,     1, 49152, 
+    57344, 59392, 59904, 59968, 60000, 59992,     0,     1, 
+    49152, 57344, 59392, 59904, 59968, 60000, 59992, 59994, 
+        0,     1, 49152, 57344, 59392, 59904, 59968, 60000, 
+    59992,     0,     1, 49152, 57344, 59392, 59904, 59968, 
+    60000, 60001, 59996,     0,     1, 49152, 57344, 59392, 
+    59904, 59968, 60000, 60001, 59996,     0,     1, 49152, 
+    57344, 59392, 59904, 59968, 60000, 60001, 59996, 59998, 
+        0,     1, 49152, 57344, 59392, 59904, 59968,     0, 
+        1, 49152, 57344, 59392, 59904, 60032, 60000,     0, 
+        1, 49152, 57344, 59392, 59904, 60032, 60000,     0, 
+        1, 49152, 57344, 59392, 59904, 60032, 60000, 60002, 
+        0,     1, 49152, 57344, 59392, 59904, 60032, 60000, 
+        0,     1, 49152, 57344, 59392, 59904, 60032, 60000, 
+    60004,     0,     1, 49152, 57344, 59392, 59904, 60032, 
+    60000, 60004,     0,     1, 49152, 57344, 59392, 59904, 
+    60032, 60000, 60008, 60006,     0,     1, 49152, 57344, 
+    59392, 59904, 60032, 60000,     0,     1, 49152, 57344, 
+    59392, 59904, 60032, 60000, 60008,     0,     1, 49152, 
+    57344, 59392, 59904, 60032, 60000, 60008,     0,     1, 
+    49152, 57344, 59392, 59904, 60032, 60000, 60008, 60010, 
+        0,     1, 49152, 57344, 59392, 59904, 60032, 60000, 
+    60008,     0,     1, 49152, 57344, 59392, 59904, 60032, 
+    60000, 60016, 60012,     0,     1, 49152, 57344, 59392, 
+    59904, 60032, 60000, 60016, 60012,     0,     1, 49152, 
+    57344, 59392, 59904, 60032, 60000, 60016, 60017, 60014, 
+        0,     1, 49152, 57344, 59392, 59904, 60032, 60000, 
+        0,     1, 49152, 57344, 59392, 59904, 60032, 60033, 
+    60016,     0,     1, 49152, 57344, 59392, 59904, 60032, 
+    60033, 60016,     0,     1, 49152, 57344, 59392, 59904, 
+    60032, 60033, 60016, 60018,     0,     1, 49152, 57344, 
+    59392, 59904, 60032, 60033, 60016,     0,     1, 49152, 
+    57344, 59392, 59904, 60032, 60033, 60016, 60020,     0, 
+        1, 49152, 57344, 59392, 59904, 60032, 60033, 60016, 
+    60020,     0,     1, 49152, 57344, 59392, 59904, 60032, 
+    60033, 60016, 60024, 60022,     0,     1, 49152, 57344, 
+    59392, 59904, 60032, 60033, 60016,     0,     1, 49152, 
+    57344, 59392, 59904, 60032, 60033, 60016, 60024,     0, 
+        1, 49152, 57344, 59392, 59904, 60032, 60033, 60035, 
+    60024,     0,     1, 49152, 57344, 59392, 59904, 60032, 
+    60033, 60035, 60024, 60026,     0,     1, 49152, 57344, 
+    59392, 59904, 60032, 60033, 60035, 60024,     0,     1, 
+    49152, 57344, 59392, 59904, 60032, 60033, 60035, 60024, 
+    60028,     0,     1, 49152, 57344, 59392, 59904, 60032, 
+    60033, 60035, 60024, 60028,     0,     1, 49152, 57344, 
+    59392, 59904, 60032, 60033, 60035, 60024, 60028, 60030, 
+        0,     1, 49152, 57344, 59392, 59904,     0,     1, 
+    49152, 57344, 59392, 59904, 60032,     0,     1, 49152, 
+    57344, 59392, 59904, 60032,     0,     1, 49152, 57344, 
+    59392, 59904, 60032, 60034,     0,     1, 49152, 57344, 
+    59392, 59904, 60032,     0,     1, 49152, 57344, 59392, 
+    59904, 60032, 60036,     0,     1, 49152, 57344, 59392, 
+    59904, 60032, 60036,     0,     1, 49152, 57344, 59392, 
+    59904, 60032, 60040, 60038,     0,     1, 49152, 57344, 
+    59392, 59904, 60032,     0,     1, 49152, 57344, 59392, 
+    59904, 60032, 60040,     0,     1, 49152, 57344, 59392, 
+    59904, 60032, 60040,     0,     1, 49152, 57344, 59392, 
+    59904, 60032, 60040, 60042,     0,     1, 49152, 57344, 
+    59392, 59904, 60032, 60040,     0,     1, 49152, 57344, 
+    59392, 59904, 60032, 60048, 60044,     0,     1, 49152, 
+    57344, 59392, 59904, 60032, 60048, 60044,     0,     1, 
+    49152, 57344, 59392, 59904, 60032, 60048, 60049, 60046, 
+        0,     1, 49152, 57344, 59392, 59904, 60032,     0, 
+        1, 49152, 57344, 59392, 59904, 60032, 60048,     0, 
+        1, 49152, 57344, 59392, 59904, 60032, 60048,     0, 
+        1, 49152, 57344, 59392, 59904, 60032, 60048, 60050, 
+        0,     1, 49152, 57344, 59392, 59904, 60032, 60048, 
+        0,     1, 49152, 57344, 59392, 59904, 60032, 60048, 
+    60052,     0,     1, 49152, 57344, 59392, 59904, 60032, 
+    60048, 60052,     0,     1, 49152, 57344, 59392, 59904, 
+    60032, 60048, 60056, 60054,     0,     1, 49152, 57344, 
+    59392, 59904, 60032, 60048,     0,     1, 49152, 57344, 
+    59392, 59904, 60032, 60064, 60056,     0,     1, 49152, 
+    57344, 59392, 59904, 60032, 60064, 60056,     0,     1, 
+    49152, 57344, 59392, 59904, 60032, 60064, 60056, 60058, 
+        0,     1, 49152, 57344, 59392, 59904, 60032, 60064, 
+    60056,     0,     1, 49152, 57344, 59392, 59904, 60032, 
+    60064, 60065, 60060,     0,     1, 49152, 57344, 59392, 
+    59904, 60032, 60064, 60065, 60060,     0,     1, 49152, 
+    57344, 59392, 59904, 60032, 60064, 60065, 60060, 60062, 
+        0,     1, 49152, 57344, 59392, 59904, 60032,     0, 
+        1, 49152, 57344, 59392, 59904, 60032, 60064,     0, 
+        1, 49152, 57344, 59392, 59904, 60032, 60064,     0, 
+        1, 49152, 57344, 59392, 59904, 60032, 60064, 60066, 
+        0,     1, 49152, 57344, 59392, 59904, 60032, 60064, 
+        0,     1, 49152, 57344, 59392, 59904, 60032, 60064, 
+    60068,     0,     1, 49152, 57344, 59392, 59904, 60032, 
+    60064, 60068,     0,     1, 49152, 57344, 59392, 59904, 
+    60032, 60064, 60072, 60070,     0,     1, 49152, 57344, 
+    59392, 59904, 60032, 60064,     0,     1, 49152, 57344, 
+    59392, 59904, 60032, 60064, 60072,     0,     1, 49152, 
+    57344, 59392, 59904, 60032, 60064, 60072,     0,     1, 
+    49152, 57344, 59392, 59904, 60032, 60064, 60072, 60074, 
+        0,     1, 49152, 57344, 59392, 59904, 60032, 60064, 
+    60072,     0,     1, 49152, 57344, 59392, 59904, 60032, 
+    60064, 60080, 60076,     0,     1, 49152, 57344, 59392, 
+    59904, 60032, 60064, 60080, 60076,     0,     1, 49152, 
+    57344, 59392, 59904, 60032, 60064, 60080, 60081, 60078, 
+        0,     1, 49152, 57344, 59392, 59904, 60032, 60064, 
+        0,     1, 49152, 57344, 59392, 59904, 60032, 60096, 
+    60080,     0,     1, 49152, 57344, 59392, 59904, 60032, 
+    60096, 60080,     0,     1, 49152, 57344, 59392, 59904, 
+    60032, 60096, 60080, 60082,     0,     1, 49152, 57344, 
+    59392, 59904, 60032, 60096, 60080,     0,     1, 49152, 
+    57344, 59392, 59904, 60032, 60096, 60080, 60084,     0, 
+        1, 49152, 57344, 59392, 59904, 60032, 60096, 60080, 
+    60084,     0,     1, 49152, 57344, 59392, 59904, 60032, 
+    60096, 60080, 60088, 60086,     0,     1, 49152, 57344, 
+    59392, 59904, 60032, 60096, 60080,     0,     1, 49152, 
+    57344, 59392, 59904, 60032, 60096, 60097, 60088,     0, 
+        1, 49152, 57344, 59392, 59904, 60032, 60096, 60097, 
+    60088,     0,     1, 49152, 57344, 59392, 59904, 60032, 
+    60096, 60097, 60088, 60090,     0,     1, 49152, 57344, 
+    59392, 59904, 60032, 60096, 60097, 60088,     0,     1, 
+    49152, 57344, 59392, 59904, 60032, 60096, 60097, 60088, 
+    60092,     0,     1, 49152, 57344, 59392, 59904, 60032, 
+    60096, 60097, 60099, 60092,     0,     1, 49152, 57344, 
+    59392, 59904, 60032, 60096, 60097, 60099, 60092, 60094, 
+        0,     1, 49152, 57344, 59392, 59904, 60032,     0, 
+        1, 49152, 57344, 59392, 59904, 60160, 60096,     0, 
+        1, 49152, 57344, 59392, 59904, 60160, 60096,     0, 
+        1, 49152, 57344, 59392, 59904, 60160, 60096, 60098, 
+        0,     1, 49152, 57344, 59392, 59904, 60160, 60096, 
+        0,     1, 49152, 57344, 59392, 59904, 60160, 60096, 
+    60100,     0,     1, 49152, 57344, 59392, 59904, 60160, 
+    60096, 60100,     0,     1, 49152, 57344, 59392, 59904, 
+    60160, 60096, 60104, 60102,     0,     1, 49152, 57344, 
+    59392, 59904, 60160, 60096,     0,     1, 49152, 57344, 
+    59392, 59904, 60160, 60096, 60104,     0,     1, 49152, 
+    57344, 59392, 59904, 60160, 60096, 60104,     0,     1, 
+    49152, 57344, 59392, 59904, 60160, 60096, 60104, 60106, 
+        0,     1, 49152, 57344, 59392, 59904, 60160, 60096, 
+    60104,     0,     1, 49152, 57344, 59392, 59904, 60160, 
+    60096, 60112, 60108,     0,     1, 49152, 57344, 59392, 
+    59904, 60160, 60096, 60112, 60108,     0,     1, 49152, 
+    57344, 59392, 59904, 60160, 60096, 60112, 60113, 60110, 
+        0,     1, 49152, 57344, 59392, 59904, 60160, 60096, 
+        0,     1, 49152, 57344, 59392, 59904, 60160, 60096, 
+    60112,     0,     1, 49152, 57344, 59392, 59904, 60160, 
+    60096, 60112,     0,     1, 49152, 57344, 59392, 59904, 
+    60160, 60096, 60112, 60114,     0,     1, 49152, 57344, 
+    59392, 59904, 60160, 60096, 60112,     0,     1, 49152, 
+    57344, 59392, 59904, 60160, 60096, 60112, 60116,     0, 
+        1, 49152, 57344, 59392, 59904, 60160, 60096, 60112, 
+    60116,     0,     1, 49152, 57344, 59392, 59904, 60160, 
+    60096, 60112, 60120, 60118,     0,     1, 49152, 57344, 
+    59392, 59904, 60160, 60096, 60112,     0,     1, 49152, 
+    57344, 59392, 59904, 60160, 60096, 60128, 60120,     0, 
+        1, 49152, 57344, 59392, 59904, 60160, 60096, 60128, 
+    60120,     0,     1, 49152, 57344, 59392, 59904, 60160, 
+    60096, 60128, 60120, 60122,     0,     1, 49152, 57344, 
+    59392, 59904, 60160, 60096, 60128, 60120,     0,     1, 
+    49152, 57344, 59392, 59904, 60160, 60096, 60128, 60129, 
+    60124,     0,     1, 49152, 57344, 59392, 59904, 60160, 
+    60096, 60128, 60129, 60124,     0,     1, 49152, 57344, 
+    59392, 59904, 60160, 60096, 60128, 60129, 60124, 60126, 
+        0,     1, 49152, 57344, 59392, 59904, 60160, 60096, 
+        0,     1, 49152, 57344, 59392, 59904, 60160, 60161, 
+    60128,     0,     1, 49152, 57344, 59392, 59904, 60160, 
+    60161, 60128,     0,     1, 49152, 57344, 59392, 59904, 
+    60160, 60161, 60128, 60130,     0,     1, 49152, 57344, 
+    59392, 59904, 60160, 60161, 60128,     0,     1, 49152, 
+    57344, 59392, 59904, 60160, 60161, 60128, 60132,     0, 
+        1, 49152, 57344, 59392, 59904, 60160, 60161, 60128, 
+    60132,     0,     1, 49152, 57344, 59392, 59904, 60160, 
+    60161, 60128, 60136, 60134,     0,     1, 49152, 57344, 
+    59392, 59904, 60160, 60161, 60128,     0,     1, 49152, 
+    57344, 59392, 59904, 60160, 60161, 60128, 60136,     0, 
+        1, 49152, 57344, 59392, 59904, 60160, 60161, 60128, 
+    60136,     0,     1, 49152, 57344, 59392, 59904, 60160, 
+    60161, 60128, 60136, 60138,     0,     1, 49152, 57344, 
+    59392, 59904, 60160, 60161, 60128, 60136,     0,     1, 
+    49152, 57344, 59392, 59904, 60160, 60161, 60128, 60144, 
+    60140,     0,     1, 49152, 57344, 59392, 59904, 60160, 
+    60161, 60128, 60144, 60140,     0,     1, 49152, 57344, 
+    59392, 59904, 60160, 60161, 60128, 60144, 60145, 60142, 
+        0,     1, 49152, 57344, 59392, 59904, 60160, 60161, 
+    60128,     0,     1, 49152, 57344, 59392, 59904, 60160, 
+    60161, 60128, 60144,     0,     1, 49152, 57344, 59392, 
+    59904, 60160, 60161, 60163, 60144,     0,     1, 49152, 
+    57344, 59392, 59904, 60160, 60161, 60163, 60144, 60146, 
+        0,     1, 49152, 57344, 59392, 59904, 60160, 60161, 
+    60163, 60144,     0,     1, 49152, 57344, 59392, 59904, 
+    60160, 60161, 60163, 60144, 60148,     0,     1, 49152, 
+    57344, 59392, 59904, 60160, 60161, 60163, 60144, 60148, 
+        0,     1, 49152, 57344, 59392, 59904, 60160, 60161, 
+    60163, 60144, 60152, 60150,     0,     1, 49152, 57344, 
+    59392, 59904, 60160, 60161, 60163, 60144,     0,     1, 
+    49152, 57344, 59392, 59904, 60160, 60161, 60163, 60144, 
+    60152,     0,     1, 49152, 57344, 59392, 59904, 60160, 
+    60161, 60163, 60144, 60152,     0,     1, 49152, 57344, 
+    59392, 59904, 60160, 60161, 60163, 60144, 60152, 60154, 
+        0,     1, 49152, 57344, 59392, 59904, 60160, 60161, 
+    60163, 60167, 60152,     0,     1, 49152, 57344, 59392, 
+    59904, 60160, 60161, 60163, 60167, 60152, 60156,     0, 
+        1, 49152, 57344, 59392, 59904, 60160, 60161, 60163, 
+    60167, 60152, 60156,     0,     1, 49152, 57344, 59392, 
+    59904, 60160, 60161, 60163, 60167, 60152, 60156, 60158, 
+        0,     1, 49152, 57344, 59392, 59904,     0,     1, 
+    49152, 57344, 59392, 60416, 60160,     0,     1, 49152, 
+    57344, 59392, 60416, 60160,     0,     1, 49152, 57344, 
+    59392, 60416, 60160, 60162,     0,     1, 49152, 57344, 
+    59392, 60416, 60160,     0,     1, 49152, 57344, 59392, 
+    60416, 60160, 60164,     0,     1, 49152, 57344, 59392, 
+    60416, 60160, 60164,     0,     1, 49152, 57344, 59392, 
+    60416, 60160, 60168, 60166,     0,     1, 49152, 57344, 
+    59392, 60416, 60160,     0,     1, 49152, 57344, 59392, 
+    60416, 60160, 60168,     0,     1, 49152, 57344, 59392, 
+    60416, 60160, 60168,     0,     1, 49152, 57344, 59392, 
+    60416, 60160, 60168, 60170,     0,     1, 49152, 57344, 
+    59392, 60416, 60160, 60168,     0,     1, 49152, 57344, 
+    59392, 60416, 60160, 60176, 60172,     0,     1, 49152, 
+    57344, 59392, 60416, 60160, 60176, 60172,     0,     1, 
+    49152, 57344, 59392, 60416, 60160, 60176, 60177, 60174, 
+        0,     1, 49152, 57344, 59392, 60416, 60160,     0, 
+        1, 49152, 57344, 59392, 60416, 60160, 60176,     0, 
+        1, 49152, 57344, 59392, 60416, 60160, 60176,     0, 
+        1, 49152, 57344, 59392, 60416, 60160, 60176, 60178, 
+        0,     1, 49152, 57344, 59392, 60416, 60160, 60176, 
+        0,     1, 49152, 57344, 59392, 60416, 60160, 60176, 
+    60180,     0,     1, 49152, 57344, 59392, 60416, 60160, 
+    60176, 60180,     0,     1, 49152, 57344, 59392, 60416, 
+    60160, 60176, 60184, 60182,     0,     1, 49152, 57344, 
+    59392, 60416, 60160, 60176,     0,     1, 49152, 57344, 
+    59392, 60416, 60160, 60192, 60184,     0,     1, 49152, 
+    57344, 59392, 60416, 60160, 60192, 60184,     0,     1, 
+    49152, 57344, 59392, 60416, 60160, 60192, 60184, 60186, 
+        0,     1, 49152, 57344, 59392, 60416, 60160, 60192, 
+    60184,     0,     1, 49152, 57344, 59392, 60416, 60160, 
+    60192, 60193, 60188,     0,     1, 49152, 57344, 59392, 
+    60416, 60160, 60192, 60193, 60188,     0,     1, 49152, 
+    57344, 59392, 60416, 60160, 60192, 60193, 60188, 60190, 
+        0,     1, 49152, 57344, 59392, 60416, 60160,     0, 
+        1, 49152, 57344, 59392, 60416, 60160, 60192,     0, 
+        1, 49152, 57344, 59392, 60416, 60160, 60192,     0, 
+        1, 49152, 57344, 59392, 60416, 60160, 60192, 60194, 
+        0,     1, 49152, 57344, 59392, 60416, 60160, 60192, 
+        0,     1, 49152, 57344, 59392, 60416, 60160, 60192, 
+    60196,     0,     1, 49152, 57344, 59392, 60416, 60160, 
+    60192, 60196,     0,     1, 49152, 57344, 59392, 60416, 
+    60160, 60192, 60200, 60198,     0,     1, 49152, 57344, 
+    59392, 60416, 60160, 60192,     0,     1, 49152, 57344, 
+    59392, 60416, 60160, 60192, 60200,     0,     1, 49152, 
+    57344, 59392, 60416, 60160, 60192, 60200,     0,     1, 
+    49152, 57344, 59392, 60416, 60160, 60192, 60200, 60202, 
+        0,     1, 49152, 57344, 59392, 60416, 60160, 60192, 
+    60200,     0,     1, 49152, 57344, 59392, 60416, 60160, 
+    60192, 60208, 60204,     0,     1, 49152, 57344, 59392, 
+    60416, 60160, 60192, 60208, 60204,     0,     1, 49152, 
+    57344, 59392, 60416, 60160, 60192, 60208, 60209, 60206, 
+        0,     1, 49152, 57344, 59392, 60416, 60160, 60192, 
+        0,     1, 49152, 57344, 59392, 60416, 60160, 60224, 
+    60208,     0,     1, 49152, 57344, 59392, 60416, 60160, 
+    60224, 60208,     0,     1, 49152, 57344, 59392, 60416, 
+    60160, 60224, 60208, 60210,     0,     1, 49152, 57344, 
+    59392, 60416, 60160, 60224, 60208,     0,     1, 49152, 
+    57344, 59392, 60416, 60160, 60224, 60208, 60212,     0, 
+        1, 49152, 57344, 59392, 60416, 60160, 60224, 60208, 
+    60212,     0,     1, 49152, 57344, 59392, 60416, 60160, 
+    60224, 60208, 60216, 60214,     0,     1, 49152, 57344, 
+    59392, 60416, 60160, 60224, 60208,     0,     1, 49152, 
+    57344, 59392, 60416, 60160, 60224, 60225, 60216,     0, 
+        1, 49152, 57344, 59392, 60416, 60160, 60224, 60225, 
+    60216,     0,     1, 49152, 57344, 59392, 60416, 60160, 
+    60224, 60225, 60216, 60218,     0,     1, 49152, 57344, 
+    59392, 60416, 60160, 60224, 60225, 60216,     0,     1, 
+    49152, 57344, 59392, 60416, 60160, 60224, 60225, 60216, 
+    60220,     0,     1, 49152, 57344, 59392, 60416, 60160, 
+    60224, 60225, 60227, 60220,     0,     1, 49152, 57344, 
+    59392, 60416, 60160, 60224, 60225, 60227, 60220, 60222, 
+        0,     1, 49152, 57344, 59392, 60416, 60160,     0, 
+        1, 49152, 57344, 59392, 60416, 60160, 60224,     0, 
+        1, 49152, 57344, 59392, 60416, 60160, 60224,     0, 
+        1, 49152, 57344, 59392, 60416, 60160, 60224, 60226, 
+        0,     1, 49152, 57344, 59392, 60416, 60160, 60224, 
+        0,     1, 49152, 57344, 59392, 60416, 60160, 60224, 
+    60228,     0,     1, 49152, 57344, 59392, 60416, 60160, 
+    60224, 60228,     0,     1, 49152, 57344, 59392, 60416, 
+    60160, 60224, 60232, 60230,     0,     1, 49152, 57344, 
+    59392, 60416, 60160, 60224,     0,     1, 49152, 57344, 
+    59392, 60416, 60160, 60224, 60232,     0,     1, 49152, 
+    57344, 59392, 60416, 60160, 60224, 60232,     0,     1, 
+    49152, 57344, 59392, 60416, 60160, 60224, 60232, 60234, 
+        0,     1, 49152, 57344, 59392, 60416, 60160, 60224, 
+    60232,     0,     1, 49152, 57344, 59392, 60416, 60160, 
+    60224, 60240, 60236,     0,     1, 49152, 57344, 59392, 
+    60416, 60160, 60224, 60240, 60236,     0,     1, 49152, 
+    57344, 59392, 60416, 60160, 60224, 60240, 60241, 60238, 
+        0,     1, 49152, 57344, 59392, 60416, 60160, 60224, 
+        0,     1, 49152, 57344, 59392, 60416, 60160, 60224, 
+    60240,     0,     1, 49152, 57344, 59392, 60416, 60160, 
+    60224, 60240,     0,     1, 49152, 57344, 59392, 60416, 
+    60160, 60224, 60240, 60242,     0,     1, 49152, 57344, 
+    59392, 60416, 60160, 60224, 60240,     0,     1, 49152, 
+    57344, 59392, 60416, 60160, 60224, 60240, 60244,     0, 
+        1, 49152, 57344, 59392, 60416, 60160, 60224, 60240, 
+    60244,     0,     1, 49152, 57344, 59392, 60416, 60160, 
+    60224, 60240, 60248, 60246,     0,     1, 49152, 57344, 
+    59392, 60416, 60160, 60224, 60240,     0,     1, 49152, 
+    57344, 59392, 60416, 60160, 60224, 60256, 60248,     0, 
+        1, 49152, 57344, 59392, 60416, 60160, 60224, 60256, 
+    60248,     0,     1, 49152, 57344, 59392, 60416, 60160, 
+    60224, 60256, 60248, 60250,     0,     1, 49152, 57344, 
+    59392, 60416, 60160, 60224, 60256, 60248,     0,     1, 
+    49152, 57344, 59392, 60416, 60160, 60224, 60256, 60257, 
+    60252,     0,     1, 49152, 57344, 59392, 60416, 60160, 
+    60224, 60256, 60257, 60252,     0,     1, 49152, 57344, 
+    59392, 60416, 60160, 60224, 60256, 60257, 60252, 60254, 
+        0,     1, 49152, 57344, 59392, 60416, 60160, 60224, 
+        0,     1, 49152, 57344, 59392, 60416, 60160, 60288, 
+    60256,     0,     1, 49152, 57344, 59392, 60416, 60160, 
+    60288, 60256,     0,     1, 49152, 57344, 59392, 60416, 
+    60160, 60288, 60256, 60258,     0,     1, 49152, 57344, 
+    59392, 60416, 60160, 60288, 60256,     0,     1, 49152, 
+    57344, 59392, 60416, 60160, 60288, 60256, 60260,     0, 
+        1, 49152, 57344, 59392, 60416, 60160, 60288, 60256, 
+    60260,     0,     1, 49152, 57344, 59392, 60416, 60160, 
+    60288, 60256, 60264, 60262,     0,     1, 49152, 57344, 
+    59392, 60416, 60160, 60288, 60256,     0,     1, 49152, 
+    57344, 59392, 60416, 60160, 60288, 60256, 60264,     0, 
+        1, 49152, 57344, 59392, 60416, 60160, 60288, 60256, 
+    60264,     0,     1, 49152, 57344, 59392, 60416, 60160, 
+    60288, 60256, 60264, 60266,     0,     1, 49152, 57344, 
+    59392, 60416, 60160, 60288, 60256, 60264,     0,     1, 
+    49152, 57344, 59392, 60416, 60160, 60288, 60256, 60272, 
+    60268,     0,     1, 49152, 57344, 59392, 60416, 60160, 
+    60288, 60256, 60272, 60268,     0,     1, 49152, 57344, 
+    59392, 60416, 60160, 60288, 60256, 60272, 60273, 60270, 
+        0,     1, 49152, 57344, 59392, 60416, 60160, 60288, 
+    60256,     0,     1, 49152, 57344, 59392, 60416, 60160, 
+    60288, 60289, 60272,     0,     1, 49152, 57344, 59392, 
+    60416, 60160, 60288, 60289, 60272,     0,     1, 49152, 
+    57344, 59392, 60416, 60160, 60288, 60289, 60272, 60274, 
+        0,     1, 49152, 57344, 59392, 60416, 60160, 60288, 
+    60289, 60272,     0,     1, 49152, 57344, 59392, 60416, 
+    60160, 60288, 60289, 60272, 60276,     0,     1, 49152, 
+    57344, 59392, 60416, 60160, 60288, 60289, 60272, 60276, 
+        0,     1, 49152, 57344, 59392, 60416, 60160, 60288, 
+    60289, 60272, 60280, 60278,     0,     1, 49152, 57344, 
+    59392, 60416, 60160, 60288, 60289, 60272,     0,     1, 
+    49152, 57344, 59392, 60416, 60160, 60288, 60289, 60272, 
+    60280,     0,     1, 49152, 57344, 59392, 60416, 60160, 
+    60288, 60289, 60291, 60280,     0,     1, 49152, 57344, 
+    59392, 60416, 60160, 60288, 60289, 60291, 60280, 60282, 
+        0,     1, 49152, 57344, 59392, 60416, 60160, 60288, 
+    60289, 60291, 60280,     0,     1, 49152, 57344, 59392, 
+    60416, 60160, 60288, 60289, 60291, 60280, 60284,     0, 
+        1, 49152, 57344, 59392, 60416, 60160, 60288, 60289, 
+    60291, 60280, 60284,     0,     1, 49152, 57344, 59392, 
+    60416, 60160, 60288, 60289, 60291, 60280, 60284, 60286, 
+        0,     1, 49152, 57344, 59392, 60416, 60160,     0, 
+        1, 49152, 57344, 59392, 60416, 60160, 60288,     0, 
+        1, 49152, 57344, 59392, 60416, 60417, 60288,     0, 
+        1, 49152, 57344, 59392, 60416, 60417, 60288, 60290, 
+        0,     1, 49152, 57344, 59392, 60416, 60417, 60288, 
+        0,     1, 49152, 57344, 59392, 60416, 60417, 60288, 
+    60292,     0,     1, 49152, 57344, 59392, 60416, 60417, 
+    60288, 60292,     0,     1, 49152, 57344, 59392, 60416, 
+    60417, 60288, 60296, 60294,     0,     1, 49152, 57344, 
+    59392, 60416, 60417, 60288,     0,     1, 49152, 57344, 
+    59392, 60416, 60417, 60288, 60296,     0,     1, 49152, 
+    57344, 59392, 60416, 60417, 60288, 60296,     0,     1, 
+    49152, 57344, 59392, 60416, 60417, 60288, 60296, 60298, 
+        0,     1, 49152, 57344, 59392, 60416, 60417, 60288, 
+    60296,     0,     1, 49152, 57344, 59392, 60416, 60417, 
+    60288, 60304, 60300,     0,     1, 49152, 57344, 59392, 
+    60416, 60417, 60288, 60304, 60300,     0,     1, 49152, 
+    57344, 59392, 60416, 60417, 60288, 60304, 60305, 60302, 
+        0,     1, 49152, 57344, 59392, 60416, 60417, 60288, 
+        0,     1, 49152, 57344, 59392, 60416, 60417, 60288, 
+    60304,     0,     1, 49152, 57344, 59392, 60416, 60417, 
+    60288, 60304,     0,     1, 49152, 57344, 59392, 60416, 
+    60417, 60288, 60304, 60306,     0,     1, 49152, 57344, 
+    59392, 60416, 60417, 60288, 60304,     0,     1, 49152, 
+    57344, 59392, 60416, 60417, 60288, 60304, 60308,     0, 
+        1, 49152, 57344, 59392, 60416, 60417, 60288, 60304, 
+    60308,     0,     1, 49152, 57344, 59392, 60416, 60417, 
+    60288, 60304, 60312, 60310,     0,     1, 49152, 57344, 
+    59392, 60416, 60417, 60288, 60304,     0,     1, 49152, 
+    57344, 59392, 60416, 60417, 60288, 60320, 60312,     0, 
+        1, 49152, 57344, 59392, 60416, 60417, 60288, 60320, 
+    60312,     0,     1, 49152, 57344, 59392, 60416, 60417, 
+    60288, 60320, 60312, 60314,     0,     1, 49152, 57344, 
+    59392, 60416, 60417, 60288, 60320, 60312,     0,     1, 
+    49152, 57344, 59392, 60416, 60417, 60288, 60320, 60321, 
+    60316,     0,     1, 49152, 57344, 59392, 60416, 60417, 
+    60288, 60320, 60321, 60316,     0,     1, 49152, 57344, 
+    59392, 60416, 60417, 60288, 60320, 60321, 60316, 60318, 
+        0,     1, 49152, 57344, 59392, 60416, 60417, 60288, 
+        0,     1, 49152, 57344, 59392, 60416, 60417, 60288, 
+    60320,     0,     1, 49152, 57344, 59392, 60416, 60417, 
+    60288, 60320,     0,     1, 49152, 57344, 59392, 60416, 
+    60417, 60288, 60320, 60322,     0,     1, 49152, 57344, 
+    59392, 60416, 60417, 60288, 60320,     0,     1, 49152, 
+    57344, 59392, 60416, 60417, 60288, 60320, 60324,     0, 
+        1, 49152, 57344, 59392, 60416, 60417, 60288, 60320, 
+    60324,     0,     1, 49152, 57344, 59392, 60416, 60417, 
+    60288, 60320, 60328, 60326,     0,     1, 49152, 57344, 
+    59392, 60416, 60417, 60288, 60320,     0,     1, 49152, 
+    57344, 59392, 60416, 60417, 60288, 60320, 60328,     0, 
+        1, 49152, 57344, 59392, 60416, 60417, 60288, 60320, 
+    60328,     0,     1, 49152, 57344, 59392, 60416, 60417, 
+    60288, 60320, 60328, 60330,     0,     1, 49152, 57344, 
+    59392, 60416, 60417, 60288, 60320, 60328,     0,     1, 
+    49152, 57344, 59392, 60416, 60417, 60288, 60320, 60336, 
+    60332,     0,     1, 49152, 57344, 59392, 60416, 60417, 
+    60288, 60320, 60336, 60332,     0,     1, 49152, 57344, 
+    59392, 60416, 60417, 60288, 60320, 60336, 60337, 60334, 
+        0,     1, 49152, 57344, 59392, 60416, 60417, 60288, 
+    60320,     0,     1, 49152, 57344, 59392, 60416, 60417, 
+    60288, 60352, 60336,     0,     1, 49152, 57344, 59392, 
+    60416, 60417, 60288, 60352, 60336,     0,     1, 49152, 
+    57344, 59392, 60416, 60417, 60288, 60352, 60336, 60338, 
+        0,     1, 49152, 57344, 59392, 60416, 60417, 60288, 
+    60352, 60336,     0,     1, 49152, 57344, 59392, 60416, 
+    60417, 60288, 60352, 60336, 60340,     0,     1, 49152, 
+    57344, 59392, 60416, 60417, 60288, 60352, 60336, 60340, 
+        0,     1, 49152, 57344, 59392, 60416, 60417, 60288, 
+    60352, 60336, 60344, 60342,     0,     1, 49152, 57344, 
+    59392, 60416, 60417, 60288, 60352, 60336,     0,     1, 
+    49152, 57344, 59392, 60416, 60417, 60288, 60352, 60353, 
+    60344,     0,     1, 49152, 57344, 59392, 60416, 60417, 
+    60288, 60352, 60353, 60344,     0,     1, 49152, 57344, 
+    59392, 60416, 60417, 60288, 60352, 60353, 60344, 60346, 
+        0,     1, 49152, 57344, 59392, 60416, 60417, 60288, 
+    60352, 60353, 60344,     0,     1, 49152, 57344, 59392, 
+    60416, 60417, 60288, 60352, 60353, 60344, 60348,     0, 
+        1, 49152, 57344, 59392, 60416, 60417, 60288, 60352, 
+    60353, 60355, 60348,     0,     1, 49152, 57344, 59392, 
+    60416, 60417, 60288, 60352, 60353, 60355, 60348, 60350, 
+        0,     1, 49152, 57344, 59392, 60416, 60417, 60288, 
+        0,     1, 49152, 57344, 59392, 60416, 60417, 60288, 
+    60352,     0,     1, 49152, 57344, 59392, 60416, 60417, 
+    60288, 60352,     0,     1, 49152, 57344, 59392, 60416, 
+    60417, 60288, 60352, 60354,     0,     1, 49152, 57344, 
+    59392, 60416, 60417, 60419, 60352,     0,     1, 49152, 
+    57344, 59392, 60416, 60417, 60419, 60352, 60356,     0, 
+        1, 49152, 57344, 59392, 60416, 60417, 60419, 60352, 
+    60356,     0,     1, 49152, 57344, 59392, 60416, 60417, 
+    60419, 60352, 60360, 60358,     0,     1, 49152, 57344, 
+    59392, 60416, 60417, 60419, 60352,     0,     1, 49152, 
+    57344, 59392, 60416, 60417, 60419, 60352, 60360,     0, 
+        1, 49152, 57344, 59392, 60416, 60417, 60419, 60352, 
+    60360,     0,     1, 49152, 57344, 59392, 60416, 60417, 
+    60419, 60352, 60360, 60362,     0,     1, 49152, 57344, 
+    59392, 60416, 60417, 60419, 60352, 60360,     0,     1, 
+    49152, 57344, 59392, 60416, 60417, 60419, 60352, 60368, 
+    60364,     0,     1, 49152, 57344, 59392, 60416, 60417, 
+    60419, 60352, 60368, 60364,     0,     1, 49152, 57344, 
+    59392, 60416, 60417, 60419, 60352, 60368, 60369, 60366, 
+        0,     1, 49152, 57344, 59392, 60416, 60417, 60419, 
+    60352,     0,     1, 49152, 57344, 59392, 60416, 60417, 
+    60419, 60352, 60368,     0,     1, 49152, 57344, 59392, 
+    60416, 60417, 60419, 60352, 60368,     0,     1, 49152, 
+    57344, 59392, 60416, 60417, 60419, 60352, 60368, 60370, 
+        0,     1, 49152, 57344, 59392, 60416, 60417, 60419, 
+    60352, 60368,     0,     1, 49152, 57344, 59392, 60416, 
+    60417, 60419, 60352, 60368, 60372,     0,     1, 49152, 
+    57344, 59392, 60416, 60417, 60419, 60352, 60368, 60372, 
+        0,     1, 49152, 57344, 59392, 60416, 60417, 60419, 
+    60352, 60368, 60376, 60374,     0,     1, 49152, 57344, 
+    59392, 60416, 60417, 60419, 60352, 60368,     0,     1, 
+    49152, 57344, 59392, 60416, 60417, 60419, 60352, 60384, 
+    60376,     0,     1, 49152, 57344, 59392, 60416, 60417, 
+    60419, 60352, 60384, 60376,     0,     1, 49152, 57344, 
+    59392, 60416, 60417, 60419, 60352, 60384, 60376, 60378, 
+        0,     1, 49152, 57344, 59392, 60416, 60417, 60419, 
+    60352, 60384, 60376,     0,     1, 49152, 57344, 59392, 
+    60416, 60417, 60419, 60352, 60384, 60385, 60380,     0, 
+        1, 49152, 57344, 59392, 60416, 60417, 60419, 60352, 
+    60384, 60385, 60380,     0,     1, 49152, 57344, 59392, 
+    60416, 60417, 60419, 60352, 60384, 60385, 60380, 60382, 
+        0,     1, 49152, 57344, 59392, 60416, 60417, 60419, 
+    60352,     0,     1, 49152, 57344, 59392, 60416, 60417, 
+    60419, 60352, 60384,     0,     1, 49152, 57344, 59392, 
+    60416, 60417, 60419, 60352, 60384,     0,     1, 49152, 
+    57344, 59392, 60416, 60417, 60419, 60352, 60384, 60386, 
+        0,     1, 49152, 57344, 59392, 60416, 60417, 60419, 
+    60352, 60384,     0,     1, 49152, 57344, 59392, 60416, 
+    60417, 60419, 60352, 60384, 60388,     0,     1, 49152, 
+    57344, 59392, 60416, 60417, 60419, 60352, 60384, 60388, 
+        0,     1, 49152, 57344, 59392, 60416, 60417, 60419, 
+    60352, 60384, 60392, 60390,     0,     1, 49152, 57344, 
+    59392, 60416, 60417, 60419, 60423, 60384,     0,     1, 
+    49152, 57344, 59392, 60416, 60417, 60419, 60423, 60384, 
+    60392,     0,     1, 49152, 57344, 59392, 60416, 60417, 
+    60419, 60423, 60384, 60392,     0,     1, 49152, 57344, 
+    59392, 60416, 60417, 60419, 60423, 60384, 60392, 60394, 
+        0,     1, 49152, 57344, 59392, 60416, 60417, 60419, 
+    60423, 60384, 60392,     0,     1, 49152, 57344, 59392, 
+    60416, 60417, 60419, 60423, 60384, 60400, 60396,     0, 
+        1, 49152, 57344, 59392, 60416, 60417, 60419, 60423, 
+    60384, 60400, 60396,     0,     1, 49152, 57344, 59392, 
+    60416, 60417, 60419, 60423, 60384, 60400, 60401, 60398, 
+        0,     1, 49152, 57344, 59392, 60416, 60417, 60419, 
+    60423, 60384,     0,     1, 49152, 57344, 59392, 60416, 
+    60417, 60419, 60423, 60384, 60400,     0,     1, 49152, 
+    57344, 59392, 60416, 60417, 60419, 60423, 60384, 60400, 
+        0,     1, 49152, 57344, 59392, 60416, 60417, 60419, 
+    60423, 60384, 60400, 60402,     0,     1, 49152, 57344, 
+    59392, 60416, 60417, 60419, 60423, 60384, 60400,     0, 
+        1, 49152, 57344, 59392, 60416, 60417, 60419, 60423, 
+    60384, 60400, 60404,     0,     1, 49152, 57344, 59392, 
+    60416, 60417, 60419, 60423, 60384, 60400, 60404,     0, 
+        1, 49152, 57344, 59392, 60416, 60417, 60419, 60423, 
+    60384, 60400, 60408, 60406,     0,     1, 49152, 57344, 
+    59392, 60416, 60417, 60419, 60423, 60384, 60400,     0, 
+        1, 49152, 57344, 59392, 60416, 60417, 60419, 60423, 
+    60384, 60400, 60408,     0,     1, 49152, 57344, 59392, 
+    60416, 60417, 60419, 60423, 60384, 60400, 60408,     0, 
+        1, 49152, 57344, 59392, 60416, 60417, 60419, 60423, 
+    60384, 60400, 60408, 60410,     0,     1, 49152, 57344, 
+    59392, 60416, 60417, 60419, 60423, 60384, 60400, 60408, 
+        0,     1, 49152, 57344, 59392, 60416, 60417, 60419, 
+    60423, 60384, 60400, 60408, 60412,     0,     1, 49152, 
+    57344, 59392, 60416, 60417, 60419, 60423, 60384, 60400, 
+    60408, 60412,     0,     1, 49152, 57344, 59392, 60416, 
+    60417, 60419, 60423, 60384, 60400, 60408, 60412, 60414, 
+        0,     1, 49152, 57344, 59392,     0,     1, 49152, 
+    57344, 59392, 60416,     0,     1, 49152, 57344, 59392, 
+    60416,     0,     1, 49152, 57344, 59392, 60416, 60418, 
+        0,     1, 49152, 57344, 59392, 60416,     0,     1, 
+    49152, 57344, 59392, 60416, 60420,     0,     1, 49152, 
+    57344, 59392, 60416, 60420,     0,     1, 49152, 57344, 
+    59392, 60416, 60424, 60422,     0,     1, 49152, 57344, 
+    59392, 60416,     0,     1, 49152, 57344, 59392, 60416, 
+    60424,     0,     1, 49152, 57344, 59392, 60416, 60424, 
+        0,     1, 49152, 57344, 59392, 60416, 60424, 60426, 
+        0,     1, 49152, 57344, 59392, 60416, 60424,     0, 
+        1, 49152, 57344, 59392, 60416, 60432, 60428,     0, 
+        1, 49152, 57344, 59392, 60416, 60432, 60428,     0, 
+        1, 49152, 57344, 59392, 60416, 60432, 60433, 60430, 
+        0,     1, 49152, 57344, 59392, 60416,     0,     1, 
+    49152, 57344, 59392, 60416, 60432,     0,     1, 49152, 
+    57344, 59392, 60416, 60432,     0,     1, 49152, 57344, 
+    59392, 60416, 60432, 60434,     0,     1, 49152, 57344, 
+    59392, 60416, 60432,     0,     1, 49152, 57344, 59392, 
+    60416, 60432, 60436,     0,     1, 49152, 57344, 59392, 
+    60416, 60432, 60436,     0,     1, 49152, 57344, 59392, 
+    60416, 60432, 60440, 60438,     0,     1, 49152, 57344, 
+    59392, 60416, 60432,     0,     1, 49152, 57344, 59392, 
+    60416, 60448, 60440,     0,     1, 49152, 57344, 59392, 
+    60416, 60448, 60440,     0,     1, 49152, 57344, 59392, 
+    60416, 60448, 60440, 60442,     0,     1, 49152, 57344, 
+    59392, 60416, 60448, 60440,     0,     1, 49152, 57344, 
+    59392, 60416, 60448, 60449, 60444,     0,     1, 49152, 
+    57344, 59392, 60416, 60448, 60449, 60444,     0,     1, 
+    49152, 57344, 59392, 60416, 60448, 60449, 60444, 60446, 
+        0,     1, 49152, 57344, 59392, 60416,     0,     1, 
+    49152, 57344, 59392, 60416, 60448,     0,     1, 49152, 
+    57344, 59392, 60416, 60448,     0,     1, 49152, 57344, 
+    59392, 60416, 60448, 60450,     0,     1, 49152, 57344, 
+    59392, 60416, 60448,     0,     1, 49152, 57344, 59392, 
+    60416, 60448, 60452,     0,     1, 49152, 57344, 59392, 
+    60416, 60448, 60452,     0,     1, 49152, 57344, 59392, 
+    60416, 60448, 60456, 60454,     0,     1, 49152, 57344, 
+    59392, 60416, 60448,     0,     1, 49152, 57344, 59392, 
+    60416, 60448, 60456,     0,     1, 49152, 57344, 59392, 
+    60416, 60448, 60456,     0,     1, 49152, 57344, 59392, 
+    60416, 60448, 60456, 60458,     0,     1, 49152, 57344, 
+    59392, 60416, 60448, 60456,     0,     1, 49152, 57344, 
+    59392, 60416, 60448, 60464, 60460,     0,     1, 49152, 
+    57344, 59392, 60416, 60448, 60464, 60460,     0,     1, 
+    49152, 57344, 59392, 60416, 60448, 60464, 60465, 60462, 
+        0,     1, 49152, 57344, 59392, 60416, 60448,     0, 
+        1, 49152, 57344, 59392, 60416, 60480, 60464,     0, 
+        1, 49152, 57344, 59392, 60416, 60480, 60464,     0, 
+        1, 49152, 57344, 59392, 60416, 60480, 60464, 60466, 
+        0,     1, 49152, 57344, 59392, 60416, 60480, 60464, 
+        0,     1, 49152, 57344, 59392, 60416, 60480, 60464, 
+    60468,     0,     1, 49152, 57344, 59392, 60416, 60480, 
+    60464, 60468,     0,     1, 49152, 57344, 59392, 60416, 
+    60480, 60464, 60472, 60470,     0,     1, 49152, 57344, 
+    59392, 60416, 60480, 60464,     0,     1, 49152, 57344, 
+    59392, 60416, 60480, 60481, 60472,     0,     1, 49152, 
+    57344, 59392, 60416, 60480, 60481, 60472,     0,     1, 
+    49152, 57344, 59392, 60416, 60480, 60481, 60472, 60474, 
+        0,     1, 49152, 57344, 59392, 60416, 60480, 60481, 
+    60472,     0,     1, 49152, 57344, 59392, 60416, 60480, 
+    60481, 60472, 60476,     0,     1, 49152, 57344, 59392, 
+    60416, 60480, 60481, 60483, 60476,     0,     1, 49152, 
+    57344, 59392, 60416, 60480, 60481, 60483, 60476, 60478, 
+        0,     1, 49152, 57344, 59392, 60416,     0,     1, 
+    49152, 57344, 59392, 60416, 60480,     0,     1, 49152, 
+    57344, 59392, 60416, 60480,     0,     1, 49152, 57344, 
+    59392, 60416, 60480, 60482,     0,     1, 49152, 57344, 
+    59392, 60416, 60480,     0,     1, 49152, 57344, 59392, 
+    60416, 60480, 60484,     0,     1, 49152, 57344, 59392, 
+    60416, 60480, 60484,     0,     1, 49152, 57344, 59392, 
+    60416, 60480, 60488, 60486,     0,     1, 49152, 57344, 
+    59392, 60416, 60480,     0,     1, 49152, 57344, 59392, 
+    60416, 60480, 60488,     0,     1, 49152, 57344, 59392, 
+    60416, 60480, 60488,     0,     1, 49152, 57344, 59392, 
+    60416, 60480, 60488, 60490,     0,     1, 49152, 57344, 
+    59392, 60416, 60480, 60488,     0,     1, 49152, 57344, 
+    59392, 60416, 60480, 60496, 60492,     0,     1, 49152, 
+    57344, 59392, 60416, 60480, 60496, 60492,     0,     1, 
+    49152, 57344, 59392, 60416, 60480, 60496, 60497, 60494, 
+        0,     1, 49152, 57344, 59392, 60416, 60480,     0, 
+        1, 49152, 57344, 59392, 60416, 60480, 60496,     0, 
+        1, 49152, 57344, 59392, 60416, 60480, 60496,     0, 
+        1, 49152, 57344, 59392, 60416, 60480, 60496, 60498, 
+        0,     1, 49152, 57344, 59392, 60416, 60480, 60496, 
+        0,     1, 49152, 57344, 59392, 60416, 60480, 60496, 
+    60500,     0,     1, 49152, 57344, 59392, 60416, 60480, 
+    60496, 60500,     0,     1, 49152, 57344, 59392, 60416, 
+    60480, 60496, 60504, 60502,     0,     1, 49152, 57344, 
+    59392, 60416, 60480, 60496,     0,     1, 49152, 57344, 
+    59392, 60416, 60480, 60512, 60504,     0,     1, 49152, 
+    57344, 59392, 60416, 60480, 60512, 60504,     0,     1, 
+    49152, 57344, 59392, 60416, 60480, 60512, 60504, 60506, 
+        0,     1, 49152, 57344, 59392, 60416, 60480, 60512, 
+    60504,     0,     1, 49152, 57344, 59392, 60416, 60480, 
+    60512, 60513, 60508,     0,     1, 49152, 57344, 59392, 
+    60416, 60480, 60512, 60513, 60508,     0,     1, 49152, 
+    57344, 59392, 60416, 60480, 60512, 60513, 60508, 60510, 
+        0,     1, 49152, 57344, 59392, 60416, 60480,     0, 
+        1, 49152, 57344, 59392, 60416, 60544, 60512,     0, 
+        1, 49152, 57344, 59392, 60416, 60544, 60512,     0, 
+        1, 49152, 57344, 59392, 60416, 60544, 60512, 60514, 
+        0,     1, 49152, 57344, 59392, 60416, 60544, 60512, 
+        0,     1, 49152, 57344, 59392, 60416, 60544, 60512, 
+    60516,     0,     1, 49152, 57344, 59392, 60416, 60544, 
+    60512, 60516,     0,     1, 49152, 57344, 59392, 60416, 
+    60544, 60512, 60520, 60518,     0,     1, 49152, 57344, 
+    59392, 60416, 60544, 60512,     0,     1, 49152, 57344, 
+    59392, 60416, 60544, 60512, 60520,     0,     1, 49152, 
+    57344, 59392, 60416, 60544, 60512, 60520,     0,     1, 
+    49152, 57344, 59392, 60416, 60544, 60512, 60520, 60522, 
+        0,     1, 49152, 57344, 59392, 60416, 60544, 60512, 
+    60520,     0,     1, 49152, 57344, 59392, 60416, 60544, 
+    60512, 60528, 60524,     0,     1, 49152, 57344, 59392, 
+    60416, 60544, 60512, 60528, 60524,     0,     1, 49152, 
+    57344, 59392, 60416, 60544, 60512, 60528, 60529, 60526, 
+        0,     1, 49152, 57344, 59392, 60416, 60544, 60512, 
+        0,     1, 49152, 57344, 59392, 60416, 60544, 60545, 
+    60528,     0,     1, 49152, 57344, 59392, 60416, 60544, 
+    60545, 60528,     0,     1, 49152, 57344, 59392, 60416, 
+    60544, 60545, 60528, 60530,     0,     1, 49152, 57344, 
+    59392, 60416, 60544, 60545, 60528,     0,     1, 49152, 
+    57344, 59392, 60416, 60544, 60545, 60528, 60532,     0, 
+        1, 49152, 57344, 59392, 60416, 60544, 60545, 60528, 
+    60532,     0,     1, 49152, 57344, 59392, 60416, 60544, 
+    60545, 60528, 60536, 60534,     0,     1, 49152, 57344, 
+    59392, 60416, 60544, 60545, 60528,     0,     1, 49152, 
+    57344, 59392, 60416, 60544, 60545, 60528, 60536,     0, 
+        1, 49152, 57344, 59392, 60416, 60544, 60545, 60547, 
+    60536,     0,     1, 49152, 57344, 59392, 60416, 60544, 
+    60545, 60547, 60536, 60538,     0,     1, 49152, 57344, 
+    59392, 60416, 60544, 60545, 60547, 60536,     0,     1, 
+    49152, 57344, 59392, 60416, 60544, 60545, 60547, 60536, 
+    60540,     0,     1, 49152, 57344, 59392, 60416, 60544, 
+    60545, 60547, 60536, 60540,     0,     1, 49152, 57344, 
+    59392, 60416, 60544, 60545, 60547, 60536, 60540, 60542, 
+        0,     1, 49152, 57344, 59392, 60416,     0,     1, 
+    49152, 57344, 59392, 60416, 60544,     0,     1, 49152, 
+    57344, 59392, 60416, 60544,     0,     1, 49152, 57344, 
+    59392, 60416, 60544, 60546,     0,     1, 49152, 57344, 
+    59392, 60416, 60544,     0,     1, 49152, 57344, 59392, 
+    60416, 60544, 60548,     0,     1, 49152, 57344, 59392, 
+    60416, 60544, 60548,     0,     1, 49152, 57344, 59392, 
+    60416, 60544, 60552, 60550,     0,     1, 49152, 57344, 
+    59392, 60416, 60544,     0,     1, 49152, 57344, 59392, 
+    60416, 60544, 60552,     0,     1, 49152, 57344, 59392, 
+    60416, 60544, 60552,     0,     1, 49152, 57344, 59392, 
+    60416, 60544, 60552, 60554,     0,     1, 49152, 57344, 
+    59392, 60416, 60544, 60552,     0,     1, 49152, 57344, 
+    59392, 60416, 60544, 60560, 60556,     0,     1, 49152, 
+    57344, 59392, 60416, 60544, 60560, 60556,     0,     1, 
+    49152, 57344, 59392, 60416, 60544, 60560, 60561, 60558, 
+        0,     1, 49152, 57344, 59392, 60416, 60544,     0, 
+        1, 49152, 57344, 59392, 60416, 60544, 60560,     0, 
+        1, 49152, 57344, 59392, 60416, 60544, 60560,     0, 
+        1, 49152, 57344, 59392, 60416, 60544, 60560, 60562, 
+        0,     1, 49152, 57344, 59392, 60416, 60544, 60560, 
+        0,     1, 49152, 57344, 59392, 60416, 60544, 60560, 
+    60564,     0,     1, 49152, 57344, 59392, 60416, 60544, 
+    60560, 60564,     0,     1, 49152, 57344, 59392, 60416, 
+    60544, 60560, 60568, 60566,     0,     1, 49152, 57344, 
+    59392, 60416, 60544, 60560,     0,     1, 49152, 57344, 
+    59392, 60416, 60544, 60576, 60568,     0,     1, 49152, 
+    57344, 59392, 60416, 60544, 60576, 60568,     0,     1, 
+    49152, 57344, 59392, 60416, 60544, 60576, 60568, 60570, 
+        0,     1, 49152, 57344, 59392, 60416, 60544, 60576, 
+    60568,     0,     1, 49152, 57344, 59392, 60416, 60544, 
+    60576, 60577, 60572,     0,     1, 49152, 57344, 59392, 
+    60416, 60544, 60576, 60577, 60572,     0,     1, 49152, 
+    57344, 59392, 60416, 60544, 60576, 60577, 60572, 60574, 
+        0,     1, 49152, 57344, 59392, 60416, 60544,     0, 
+        1, 49152, 57344, 59392, 60416, 60544, 60576,     0, 
+        1, 49152, 57344, 59392, 60416, 60544, 60576,     0, 
+        1, 49152, 57344, 59392, 60416, 60544, 60576, 60578, 
+        0,     1, 49152, 57344, 59392, 60416, 60544, 60576, 
+        0,     1, 49152, 57344, 59392, 60416, 60544, 60576, 
+    60580,     0,     1, 49152, 57344, 59392, 60416, 60544, 
+    60576, 60580,     0,     1, 49152, 57344, 59392, 60416, 
+    60544, 60576, 60584, 60582,     0,     1, 49152, 57344, 
+    59392, 60416, 60544, 60576,     0,     1, 49152, 57344, 
+    59392, 60416, 60544, 60576, 60584,     0,     1, 49152, 
+    57344, 59392, 60416, 60544, 60576, 60584,     0,     1, 
+    49152, 57344, 59392, 60416, 60544, 60576, 60584, 60586, 
+        0,     1, 49152, 57344, 59392, 60416, 60544, 60576, 
+    60584,     0,     1, 49152, 57344, 59392, 60416, 60544, 
+    60576, 60592, 60588,     0,     1, 49152, 57344, 59392, 
+    60416, 60544, 60576, 60592, 60588,     0,     1, 49152, 
+    57344, 59392, 60416, 60544, 60576, 60592, 60593, 60590, 
+        0,     1, 49152, 57344, 59392, 60416, 60544, 60576, 
+        0,     1, 49152, 57344, 59392, 60416, 60544, 60608, 
+    60592,     0,     1, 49152, 57344, 59392, 60416, 60544, 
+    60608, 60592,     0,     1, 49152, 57344, 59392, 60416, 
+    60544, 60608, 60592, 60594,     0,     1, 49152, 57344, 
+    59392, 60416, 60544, 60608, 60592,     0,     1, 49152, 
+    57344, 59392, 60416, 60544, 60608, 60592, 60596,     0, 
+        1, 49152, 57344, 59392, 60416, 60544, 60608, 60592, 
+    60596,     0,     1, 49152, 57344, 59392, 60416, 60544, 
+    60608, 60592, 60600, 60598,     0,     1, 49152, 57344, 
+    59392, 60416, 60544, 60608, 60592,     0,     1, 49152, 
+    57344, 59392, 60416, 60544, 60608, 60609, 60600,     0, 
+        1, 49152, 57344, 59392, 60416, 60544, 60608, 60609, 
+    60600,     0,     1, 49152, 57344, 59392, 60416, 60544, 
+    60608, 60609, 60600, 60602,     0,     1, 49152, 57344, 
+    59392, 60416, 60544, 60608, 60609, 60600,     0,     1, 
+    49152, 57344, 59392, 60416, 60544, 60608, 60609, 60600, 
+    60604,     0,     1, 49152, 57344, 59392, 60416, 60544, 
+    60608, 60609, 60611, 60604,     0,     1, 49152, 57344, 
+    59392, 60416, 60544, 60608, 60609, 60611, 60604, 60606, 
+        0,     1, 49152, 57344, 59392, 60416, 60544,     0, 
+        1, 49152, 57344, 59392, 60416, 60672, 60608,     0, 
+        1, 49152, 57344, 59392, 60416, 60672, 60608,     0, 
+        1, 49152, 57344, 59392, 60416, 60672, 60608, 60610, 
+        0,     1, 49152, 57344, 59392, 60416, 60672, 60608, 
+        0,     1, 49152, 57344, 59392, 60416, 60672, 60608, 
+    60612,     0,     1, 49152, 57344, 59392, 60416, 60672, 
+    60608, 60612,     0,     1, 49152, 57344, 59392, 60416, 
+    60672, 60608, 60616, 60614,     0,     1, 49152, 57344, 
+    59392, 60416, 60672, 60608,     0,     1, 49152, 57344, 
+    59392, 60416, 60672, 60608, 60616,     0,     1, 49152, 
+    57344, 59392, 60416, 60672, 60608, 60616,     0,     1, 
+    49152, 57344, 59392, 60416, 60672, 60608, 60616, 60618, 
+        0,     1, 49152, 57344, 59392, 60416, 60672, 60608, 
+    60616,     0,     1, 49152, 57344, 59392, 60416, 60672, 
+    60608, 60624, 60620,     0,     1, 49152, 57344, 59392, 
+    60416, 60672, 60608, 60624, 60620,     0,     1, 49152, 
+    57344, 59392, 60416, 60672, 60608, 60624, 60625, 60622, 
+        0,     1, 49152, 57344, 59392, 60416, 60672, 60608, 
+        0,     1, 49152, 57344, 59392, 60416, 60672, 60608, 
+    60624,     0,     1, 49152, 57344, 59392, 60416, 60672, 
+    60608, 60624,     0,     1, 49152, 57344, 59392, 60416, 
+    60672, 60608, 60624, 60626,     0,     1, 49152, 57344, 
+    59392, 60416, 60672, 60608, 60624,     0,     1, 49152, 
+    57344, 59392, 60416, 60672, 60608, 60624, 60628,     0, 
+        1, 49152, 57344, 59392, 60416, 60672, 60608, 60624, 
+    60628,     0,     1, 49152, 57344, 59392, 60416, 60672, 
+    60608, 60624, 60632, 60630,     0,     1, 49152, 57344, 
+    59392, 60416, 60672, 60608, 60624,     0,     1, 49152, 
+    57344, 59392, 60416, 60672, 60608, 60640, 60632,     0, 
+        1, 49152, 57344, 59392, 60416, 60672, 60608, 60640, 
+    60632,     0,     1, 49152, 57344, 59392, 60416, 60672, 
+    60608, 60640, 60632, 60634,     0,     1, 49152, 57344, 
+    59392, 60416, 60672, 60608, 60640, 60632,     0,     1, 
+    49152, 57344, 59392, 60416, 60672, 60608, 60640, 60641, 
+    60636,     0,     1, 49152, 57344, 59392, 60416, 60672, 
+    60608, 60640, 60641, 60636,     0,     1, 49152, 57344, 
+    59392, 60416, 60672, 60608, 60640, 60641, 60636, 60638, 
+        0,     1, 49152, 57344, 59392, 60416, 60672, 60608, 
+        0,     1, 49152, 57344, 59392, 60416, 60672, 60673, 
+    60640,     0,     1, 49152, 57344, 59392, 60416, 60672, 
+    60673, 60640,     0,     1, 49152, 57344, 59392, 60416, 
+    60672, 60673, 60640, 60642,     0,     1, 49152, 57344, 
+    59392, 60416, 60672, 60673, 60640,     0,     1, 49152, 
+    57344, 59392, 60416, 60672, 60673, 60640, 60644,     0, 
+        1, 49152, 57344, 59392, 60416, 60672, 60673, 60640, 
+    60644,     0,     1, 49152, 57344, 59392, 60416, 60672, 
+    60673, 60640, 60648, 60646,     0,     1, 49152, 57344, 
+    59392, 60416, 60672, 60673, 60640,     0,     1, 49152, 
+    57344, 59392, 60416, 60672, 60673, 60640, 60648,     0, 
+        1, 49152, 57344, 59392, 60416, 60672, 60673, 60640, 
+    60648,     0,     1, 49152, 57344, 59392, 60416, 60672, 
+    60673, 60640, 60648, 60650,     0,     1, 49152, 57344, 
+    59392, 60416, 60672, 60673, 60640, 60648,     0,     1, 
+    49152, 57344, 59392, 60416, 60672, 60673, 60640, 60656, 
+    60652,     0,     1, 49152, 57344, 59392, 60416, 60672, 
+    60673, 60640, 60656, 60652,     0,     1, 49152, 57344, 
+    59392, 60416, 60672, 60673, 60640, 60656, 60657, 60654, 
+        0,     1, 49152, 57344, 59392, 60416, 60672, 60673, 
+    60640,     0,     1, 49152, 57344, 59392, 60416, 60672, 
+    60673, 60640, 60656,     0,     1, 49152, 57344, 59392, 
+    60416, 60672, 60673, 60675, 60656,     0,     1, 49152, 
+    57344, 59392, 60416, 60672, 60673, 60675, 60656, 60658, 
+        0,     1, 49152, 57344, 59392, 60416, 60672, 60673, 
+    60675, 60656,     0,     1, 49152, 57344, 59392, 60416, 
+    60672, 60673, 60675, 60656, 60660,     0,     1, 49152, 
+    57344, 59392, 60416, 60672, 60673, 60675, 60656, 60660, 
+        0,     1, 49152, 57344, 59392, 60416, 60672, 60673, 
+    60675, 60656, 60664, 60662,     0,     1, 49152, 57344, 
+    59392, 60416, 60672, 60673, 60675, 60656,     0,     1, 
+    49152, 57344, 59392, 60416, 60672, 60673, 60675, 60656, 
+    60664,     0,     1, 49152, 57344, 59392, 60416, 60672, 
+    60673, 60675, 60656, 60664,     0,     1, 49152, 57344, 
+    59392, 60416, 60672, 60673, 60675, 60656, 60664, 60666, 
+        0,     1, 49152, 57344, 59392, 60416, 60672, 60673, 
+    60675, 60679, 60664,     0,     1, 49152, 57344, 59392, 
+    60416, 60672, 60673, 60675, 60679, 60664, 60668,     0, 
+        1, 49152, 57344, 59392, 60416, 60672, 60673, 60675, 
+    60679, 60664, 60668,     0,     1, 49152, 57344, 59392, 
+    60416, 60672, 60673, 60675, 60679, 60664, 60668, 60670, 
+        0,     1, 49152, 57344, 59392, 60416,     0,     1, 
+    49152, 57344, 61440, 60416, 60672,     0,     1, 49152, 
+    57344, 61440, 60416, 60672,     0,     1, 49152, 57344, 
+    61440, 60416, 60672, 60674,     0,     1, 49152, 57344, 
+    61440, 60416, 60672,     0,     1, 49152, 57344, 61440, 
+    60416, 60672, 60676,     0,     1, 49152, 57344, 61440, 
+    60416, 60672, 60676,     0,     1, 49152, 57344, 61440, 
+    60416, 60672, 60680, 60678,     0,     1, 49152, 57344, 
+    61440, 60416, 60672,     0,     1, 49152, 57344, 61440, 
+    60416, 60672, 60680,     0,     1, 49152, 57344, 61440, 
+    60416, 60672, 60680,     0,     1, 49152, 57344, 61440, 
+    60416, 60672, 60680, 60682,     0,     1, 49152, 57344, 
+    61440, 60416, 60672, 60680,     0,     1, 49152, 57344, 
+    61440, 60416, 60672, 60688, 60684,     0,     1, 49152, 
+    57344, 61440, 60416, 60672, 60688, 60684,     0,     1, 
+    49152, 57344, 61440, 60416, 60672, 60688, 60689, 60686, 
+        0,     1, 49152, 57344, 61440, 60416, 60672,     0, 
+        1, 49152, 57344, 61440, 60416, 60672, 60688,     0, 
+        1, 49152, 57344, 61440, 60416, 60672, 60688,     0, 
+        1, 49152, 57344, 61440, 60416, 60672, 60688, 60690, 
+        0,     1, 49152, 57344, 61440, 60416, 60672, 60688, 
+        0,     1, 49152, 57344, 61440, 60416, 60672, 60688, 
+    60692,     0,     1, 49152, 57344, 61440, 60416, 60672, 
+    60688, 60692,     0,     1, 49152, 57344, 61440, 60416, 
+    60672, 60688, 60696, 60694,     0,     1, 49152, 57344, 
+    61440, 60416, 60672, 60688,     0,     1, 49152, 57344, 
+    61440, 60416, 60672, 60704, 60696,     0,     1, 49152, 
+    57344, 61440, 60416, 60672, 60704, 60696,     0,     1, 
+    49152, 57344, 61440, 60416, 60672, 60704, 60696, 60698, 
+        0,     1, 49152, 57344, 61440, 60416, 60672, 60704, 
+    60696,     0,     1, 49152, 57344, 61440, 60416, 60672, 
+    60704, 60705, 60700,     0,     1, 49152, 57344, 61440, 
+    60416, 60672, 60704, 60705, 60700,     0,     1, 49152, 
+    57344, 61440, 60416, 60672, 60704, 60705, 60700, 60702, 
+        0,     1, 49152, 57344, 61440, 60416, 60672,     0, 
+        1, 49152, 57344, 61440, 60416, 60672, 60704,     0, 
+        1, 49152, 57344, 61440, 60416, 60672, 60704,     0, 
+        1, 49152, 57344, 61440, 60416, 60672, 60704, 60706, 
+        0,     1, 49152, 57344, 61440, 60416, 60672, 60704, 
+        0,     1, 49152, 57344, 61440, 60416, 60672, 60704, 
+    60708,     0,     1, 49152, 57344, 61440, 60416, 60672, 
+    60704, 60708,     0,     1, 49152, 57344, 61440, 60416, 
+    60672, 60704, 60712, 60710,     0,     1, 49152, 57344, 
+    61440, 60416, 60672, 60704,     0,     1, 49152, 57344, 
+    61440, 60416, 60672, 60704, 60712,     0,     1, 49152, 
+    57344, 61440, 60416, 60672, 60704, 60712,     0,     1, 
+    49152, 57344, 61440, 60416, 60672, 60704, 60712, 60714, 
+        0,     1, 49152, 57344, 61440, 60416, 60672, 60704, 
+    60712,     0,     1, 49152, 57344, 61440, 60416, 60672, 
+    60704, 60720, 60716,     0,     1, 49152, 57344, 61440, 
+    60416, 60672, 60704, 60720, 60716,     0,     1, 49152, 
+    57344, 61440, 60416, 60672, 60704, 60720, 60721, 60718, 
+        0,     1, 49152, 57344, 61440, 60416, 60672, 60704, 
+        0,     1, 49152, 57344, 61440, 60416, 60672, 60736, 
+    60720,     0,     1, 49152, 57344, 61440, 60416, 60672, 
+    60736, 60720,     0,     1, 49152, 57344, 61440, 60416, 
+    60672, 60736, 60720, 60722,     0,     1, 49152, 57344, 
+    61440, 60416, 60672, 60736, 60720,     0,     1, 49152, 
+    57344, 61440, 60416, 60672, 60736, 60720, 60724,     0, 
+        1, 49152, 57344, 61440, 60416, 60672, 60736, 60720, 
+    60724,     0,     1, 49152, 57344, 61440, 60416, 60672, 
+    60736, 60720, 60728, 60726,     0,     1, 49152, 57344, 
+    61440, 60416, 60672, 60736, 60720,     0,     1, 49152, 
+    57344, 61440, 60416, 60672, 60736, 60737, 60728,     0, 
+        1, 49152, 57344, 61440, 60416, 60672, 60736, 60737, 
+    60728,     0,     1, 49152, 57344, 61440, 60416, 60672, 
+    60736, 60737, 60728, 60730,     0,     1, 49152, 57344, 
+    61440, 60416, 60672, 60736, 60737, 60728,     0,     1, 
+    49152, 57344, 61440, 60416, 60672, 60736, 60737, 60728, 
+    60732,     0,     1, 49152, 57344, 61440, 60416, 60672, 
+    60736, 60737, 60739, 60732,     0,     1, 49152, 57344, 
+    61440, 60416, 60672, 60736, 60737, 60739, 60732, 60734, 
+        0,     1, 49152, 57344, 61440, 60416, 60672,     0, 
+        1, 49152, 57344, 61440, 60416, 60672, 60736,     0, 
+        1, 49152, 57344, 61440, 60416, 60672, 60736,     0, 
+        1, 49152, 57344, 61440, 60416, 60672, 60736, 60738, 
+        0,     1, 49152, 57344, 61440, 60416, 60672, 60736, 
+        0,     1, 49152, 57344, 61440, 60416, 60672, 60736, 
+    60740,     0,     1, 49152, 57344, 61440, 60416, 60672, 
+    60736, 60740,     0,     1, 49152, 57344, 61440, 60416, 
+    60672, 60736, 60744, 60742,     0,     1, 49152, 57344, 
+    61440, 60416, 60672, 60736,     0,     1, 49152, 57344, 
+    61440, 60416, 60672, 60736, 60744,     0,     1, 49152, 
+    57344, 61440, 60416, 60672, 60736, 60744,     0,     1, 
+    49152, 57344, 61440, 60416, 60672, 60736, 60744, 60746, 
+        0,     1, 49152, 57344, 61440, 60416, 60672, 60736, 
+    60744,     0,     1, 49152, 57344, 61440, 60416, 60672, 
+    60736, 60752, 60748,     0,     1, 49152, 57344, 61440, 
+    60416, 60672, 60736, 60752, 60748,     0,     1, 49152, 
+    57344, 61440, 60416, 60672, 60736, 60752, 60753, 60750, 
+        0,     1, 49152, 57344, 61440, 60416, 60672, 60736, 
+        0,     1, 49152, 57344, 61440, 60416, 60672, 60736, 
+    60752,     0,     1, 49152, 57344, 61440, 60416, 60672, 
+    60736, 60752,     0,     1, 49152, 57344, 61440, 60416, 
+    60672, 60736, 60752, 60754,     0,     1, 49152, 57344, 
+    61440, 60416, 60672, 60736, 60752,     0,     1, 49152, 
+    57344, 61440, 60416, 60672, 60736, 60752, 60756,     0, 
+        1, 49152, 57344, 61440, 60416, 60672, 60736, 60752, 
+    60756,     0,     1, 49152, 57344, 61440, 60416, 60672, 
+    60736, 60752, 60760, 60758,     0,     1, 49152, 57344, 
+    61440, 60416, 60672, 60736, 60752,     0,     1, 49152, 
+    57344, 61440, 60416, 60672, 60736, 60768, 60760,     0, 
+        1, 49152, 57344, 61440, 60416, 60672, 60736, 60768, 
+    60760,     0,     1, 49152, 57344, 61440, 60416, 60672, 
+    60736, 60768, 60760, 60762,     0,     1, 49152, 57344, 
+    61440, 60416, 60672, 60736, 60768, 60760,     0,     1, 
+    49152, 57344, 61440, 60416, 60672, 60736, 60768, 60769, 
+    60764,     0,     1, 49152, 57344, 61440, 60416, 60672, 
+    60736, 60768, 60769, 60764,     0,     1, 49152, 57344, 
+    61440, 60416, 60672, 60736, 60768, 60769, 60764, 60766, 
+        0,     1, 49152, 57344, 61440, 60416, 60672, 60736, 
+        0,     1, 49152, 57344, 61440, 60416, 60672, 60800, 
+    60768,     0,     1, 49152, 57344, 61440, 60416, 60672, 
+    60800, 60768,     0,     1, 49152, 57344, 61440, 60416, 
+    60672, 60800, 60768, 60770,     0,     1, 49152, 57344, 
+    61440, 60416, 60672, 60800, 60768,     0,     1, 49152, 
+    57344, 61440, 60416, 60672, 60800, 60768, 60772,     0, 
+        1, 49152, 57344, 61440, 60416, 60672, 60800, 60768, 
+    60772,     0,     1, 49152, 57344, 61440, 60416, 60672, 
+    60800, 60768, 60776, 60774,     0,     1, 49152, 57344, 
+    61440, 60416, 60672, 60800, 60768,     0,     1, 49152, 
+    57344, 61440, 60416, 60672, 60800, 60768, 60776,     0, 
+        1, 49152, 57344, 61440, 60416, 60672, 60800, 60768, 
+    60776,     0,     1, 49152, 57344, 61440, 60416, 60672, 
+    60800, 60768, 60776, 60778,     0,     1, 49152, 57344, 
+    61440, 60416, 60672, 60800, 60768, 60776,     0,     1, 
+    49152, 57344, 61440, 60416, 60672, 60800, 60768, 60784, 
+    60780,     0,     1, 49152, 57344, 61440, 60416, 60672, 
+    60800, 60768, 60784, 60780,     0,     1, 49152, 57344, 
+    61440, 60416, 60672, 60800, 60768, 60784, 60785, 60782, 
+        0,     1, 49152, 57344, 61440, 60416, 60672, 60800, 
+    60768,     0,     1, 49152, 57344, 61440, 60416, 60672, 
+    60800, 60801, 60784,     0,     1, 49152, 57344, 61440, 
+    60416, 60672, 60800, 60801, 60784,     0,     1, 49152, 
+    57344, 61440, 60416, 60672, 60800, 60801, 60784, 60786, 
+        0,     1, 49152, 57344, 61440, 60416, 60672, 60800, 
+    60801, 60784,     0,     1, 49152, 57344, 61440, 60416, 
+    60672, 60800, 60801, 60784, 60788,     0,     1, 49152, 
+    57344, 61440, 60416, 60672, 60800, 60801, 60784, 60788, 
+        0,     1, 49152, 57344, 61440, 60416, 60672, 60800, 
+    60801, 60784, 60792, 60790,     0,     1, 49152, 57344, 
+    61440, 60416, 60672, 60800, 60801, 60784,     0,     1, 
+    49152, 57344, 61440, 60416, 60672, 60800, 60801, 60784, 
+    60792,     0,     1, 49152, 57344, 61440, 60416, 60672, 
+    60800, 60801, 60803, 60792,     0,     1, 49152, 57344, 
+    61440, 60416, 60672, 60800, 60801, 60803, 60792, 60794, 
+        0,     1, 49152, 57344, 61440, 60416, 60672, 60800, 
+    60801, 60803, 60792,     0,     1, 49152, 57344, 61440, 
+    60416, 60672, 60800, 60801, 60803, 60792, 60796,     0, 
+        1, 49152, 57344, 61440, 60416, 60672, 60800, 60801, 
+    60803, 60792, 60796,     0,     1, 49152, 57344, 61440, 
+    60416, 60672, 60800, 60801, 60803, 60792, 60796, 60798, 
+        0,     1, 49152, 57344, 61440, 60416, 60672,     0, 
+        1, 49152, 57344, 61440, 60416, 60928, 60800,     0, 
+        1, 49152, 57344, 61440, 60416, 60928, 60800,     0, 
+        1, 49152, 57344, 61440, 60416, 60928, 60800, 60802, 
+        0,     1, 49152, 57344, 61440, 60416, 60928, 60800, 
+        0,     1, 49152, 57344, 61440, 60416, 60928, 60800, 
+    60804,     0,     1, 49152, 57344, 61440, 60416, 60928, 
+    60800, 60804,     0,     1, 49152, 57344, 61440, 60416, 
+    60928, 60800, 60808, 60806,     0,     1, 49152, 57344, 
+    61440, 60416, 60928, 60800,     0,     1, 49152, 57344, 
+    61440, 60416, 60928, 60800, 60808,     0,     1, 49152, 
+    57344, 61440, 60416, 60928, 60800, 60808,     0,     1, 
+    49152, 57344, 61440, 60416, 60928, 60800, 60808, 60810, 
+        0,     1, 49152, 57344, 61440, 60416, 60928, 60800, 
+    60808,     0,     1, 49152, 57344, 61440, 60416, 60928, 
+    60800, 60816, 60812,     0,     1, 49152, 57344, 61440, 
+    60416, 60928, 60800, 60816, 60812,     0,     1, 49152, 
+    57344, 61440, 60416, 60928, 60800, 60816, 60817, 60814, 
+        0,     1, 49152, 57344, 61440, 60416, 60928, 60800, 
+        0,     1, 49152, 57344, 61440, 60416, 60928, 60800, 
+    60816,     0,     1, 49152, 57344, 61440, 60416, 60928, 
+    60800, 60816,     0,     1, 49152, 57344, 61440, 60416, 
+    60928, 60800, 60816, 60818,     0,     1, 49152, 57344, 
+    61440, 60416, 60928, 60800, 60816,     0,     1, 49152, 
+    57344, 61440, 60416, 60928, 60800, 60816, 60820,     0, 
+        1, 49152, 57344, 61440, 60416, 60928, 60800, 60816, 
+    60820,     0,     1, 49152, 57344, 61440, 60416, 60928, 
+    60800, 60816, 60824, 60822,     0,     1, 49152, 57344, 
+    61440, 60416, 60928, 60800, 60816,     0,     1, 49152, 
+    57344, 61440, 60416, 60928, 60800, 60832, 60824,     0, 
+        1, 49152, 57344, 61440, 60416, 60928, 60800, 60832, 
+    60824,     0,     1, 49152, 57344, 61440, 60416, 60928, 
+    60800, 60832, 60824, 60826,     0,     1, 49152, 57344, 
+    61440, 60416, 60928, 60800, 60832, 60824,     0,     1, 
+    49152, 57344, 61440, 60416, 60928, 60800, 60832, 60833, 
+    60828,     0,     1, 49152, 57344, 61440, 60416, 60928, 
+    60800, 60832, 60833, 60828,     0,     1, 49152, 57344, 
+    61440, 60416, 60928, 60800, 60832, 60833, 60828, 60830, 
+        0,     1, 49152, 57344, 61440, 60416, 60928, 60800, 
+        0,     1, 49152, 57344, 61440, 60416, 60928, 60800, 
+    60832,     0,     1, 49152, 57344, 61440, 60416, 60928, 
+    60800, 60832,     0,     1, 49152, 57344, 61440, 60416, 
+    60928, 60800, 60832, 60834,     0,     1, 49152, 57344, 
+    61440, 60416, 60928, 60800, 60832,     0,     1, 49152, 
+    57344, 61440, 60416, 60928, 60800, 60832, 60836,     0, 
+        1, 49152, 57344, 61440, 60416, 60928, 60800, 60832, 
+    60836,     0,     1, 49152, 57344, 61440, 60416, 60928, 
+    60800, 60832, 60840, 60838,     0,     1, 49152, 57344, 
+    61440, 60416, 60928, 60800, 60832,     0,     1, 49152, 
+    57344, 61440, 60416, 60928, 60800, 60832, 60840,     0, 
+        1, 49152, 57344, 61440, 60416, 60928, 60800, 60832, 
+    60840,     0,     1, 49152, 57344, 61440, 60416, 60928, 
+    60800, 60832, 60840, 60842,     0,     1, 49152, 57344, 
+    61440, 60416, 60928, 60800, 60832, 60840,     0,     1, 
+    49152, 57344, 61440, 60416, 60928, 60800, 60832, 60848, 
+    60844,     0,     1, 49152, 57344, 61440, 60416, 60928, 
+    60800, 60832, 60848, 60844,     0,     1, 49152, 57344, 
+    61440, 60416, 60928, 60800, 60832, 60848, 60849, 60846, 
+        0,     1, 49152, 57344, 61440, 60416, 60928, 60800, 
+    60832,     0,     1, 49152, 57344, 61440, 60416, 60928, 
+    60800, 60864, 60848,     0,     1, 49152, 57344, 61440, 
+    60416, 60928, 60800, 60864, 60848,     0,     1, 49152, 
+    57344, 61440, 60416, 60928, 60800, 60864, 60848, 60850, 
+        0,     1, 49152, 57344, 61440, 60416, 60928, 60800, 
+    60864, 60848,     0,     1, 49152, 57344, 61440, 60416, 
+    60928, 60800, 60864, 60848, 60852,     0,     1, 49152, 
+    57344, 61440, 60416, 60928, 60800, 60864, 60848, 60852, 
+        0,     1, 49152, 57344, 61440, 60416, 60928, 60800, 
+    60864, 60848, 60856, 60854,     0,     1, 49152, 57344, 
+    61440, 60416, 60928, 60800, 60864, 60848,     0,     1, 
+    49152, 57344, 61440, 60416, 60928, 60800, 60864, 60865, 
+    60856,     0,     1, 49152, 57344, 61440, 60416, 60928, 
+    60800, 60864, 60865, 60856,     0,     1, 49152, 57344, 
+    61440, 60416, 60928, 60800, 60864, 60865, 60856, 60858, 
+        0,     1, 49152, 57344, 61440, 60416, 60928, 60800, 
+    60864, 60865, 60856,     0,     1, 49152, 57344, 61440, 
+    60416, 60928, 60800, 60864, 60865, 60856, 60860,     0, 
+        1, 49152, 57344, 61440, 60416, 60928, 60800, 60864, 
+    60865, 60867, 60860,     0,     1, 49152, 57344, 61440, 
+    60416, 60928, 60800, 60864, 60865, 60867, 60860, 60862, 
+        0,     1, 49152, 57344, 61440, 60416, 60928, 60800, 
+        0,     1, 49152, 57344, 61440, 60416, 60928, 60929, 
+    60864,     0,     1, 49152, 57344, 61440, 60416, 60928, 
+    60929, 60864,     0,     1, 49152, 57344, 61440, 60416, 
+    60928, 60929, 60864, 60866,     0,     1, 49152, 57344, 
+    61440, 60416, 60928, 60929, 60864,     0,     1, 49152, 
+    57344, 61440, 60416, 60928, 60929, 60864, 60868,     0, 
+        1, 49152, 57344, 61440, 60416, 60928, 60929, 60864, 
+    60868,     0,     1, 49152, 57344, 61440, 60416, 60928, 
+    60929, 60864, 60872, 60870,     0,     1, 49152, 57344, 
+    61440, 60416, 60928, 60929, 60864,     0,     1, 49152, 
+    57344, 61440, 60416, 60928, 60929, 60864, 60872,     0, 
+        1, 49152, 57344, 61440, 60416, 60928, 60929, 60864, 
+    60872,     0,     1, 49152, 57344, 61440, 60416, 60928, 
+    60929, 60864, 60872, 60874,     0,     1, 49152, 57344, 
+    61440, 60416, 60928, 60929, 60864, 60872,     0,     1, 
+    49152, 57344, 61440, 60416, 60928, 60929, 60864, 60880, 
+    60876,     0,     1, 49152, 57344, 61440, 60416, 60928, 
+    60929, 60864, 60880, 60876,     0,     1, 49152, 57344, 
+    61440, 60416, 60928, 60929, 60864, 60880, 60881, 60878, 
+        0,     1, 49152, 57344, 61440, 60416, 60928, 60929, 
+    60864,     0,     1, 49152, 57344, 61440, 60416, 60928, 
+    60929, 60864, 60880,     0,     1, 49152, 57344, 61440, 
+    60416, 60928, 60929, 60864, 60880,     0,     1, 49152, 
+    57344, 61440, 60416, 60928, 60929, 60864, 60880, 60882, 
+        0,     1, 49152, 57344, 61440, 60416, 60928, 60929, 
+    60864, 60880,     0,     1, 49152, 57344, 61440, 60416, 
+    60928, 60929, 60864, 60880, 60884,     0,     1, 49152, 
+    57344, 61440, 60416, 60928, 60929, 60864, 60880, 60884, 
+        0,     1, 49152, 57344, 61440, 60416, 60928, 60929, 
+    60864, 60880, 60888, 60886,     0,     1, 49152, 57344, 
+    61440, 60416, 60928, 60929, 60864, 60880,     0,     1, 
+    49152, 57344, 61440, 60416, 60928, 60929, 60864, 60896, 
+    60888,     0,     1, 49152, 57344, 61440, 60416, 60928, 
+    60929, 60864, 60896, 60888,     0,     1, 49152, 57344, 
+    61440, 60416, 60928, 60929, 60864, 60896, 60888, 60890, 
+        0,     1, 49152, 57344, 61440, 60416, 60928, 60929, 
+    60864, 60896, 60888,     0,     1, 49152, 57344, 61440, 
+    60416, 60928, 60929, 60864, 60896, 60897, 60892,     0, 
+        1, 49152, 57344, 61440, 60416, 60928, 60929, 60864, 
+    60896, 60897, 60892,     0,     1, 49152, 57344, 61440, 
+    60416, 60928, 60929, 60864, 60896, 60897, 60892, 60894, 
+        0,     1, 49152, 57344, 61440, 60416, 60928, 60929, 
+    60864,     0,     1, 49152, 57344, 61440, 60416, 60928, 
+    60929, 60864, 60896,     0,     1, 49152, 57344, 61440, 
+    60416, 60928, 60929, 60931, 60896,     0,     1, 49152, 
+    57344, 61440, 60416, 60928, 60929, 60931, 60896, 60898, 
+        0,     1, 49152, 57344, 61440, 60416, 60928, 60929, 
+    60931, 60896,     0,     1, 49152, 57344, 61440, 60416, 
+    60928, 60929, 60931, 60896, 60900,     0,     1, 49152, 
+    57344, 61440, 60416, 60928, 60929, 60931, 60896, 60900, 
+        0,     1, 49152, 57344, 61440, 60416, 60928, 60929, 
+    60931, 60896, 60904, 60902,     0,     1, 49152, 57344, 
+    61440, 60416, 60928, 60929, 60931, 60896,     0,     1, 
+    49152, 57344, 61440, 60416, 60928, 60929, 60931, 60896, 
+    60904,     0,     1, 49152, 57344, 61440, 60416, 60928, 
+    60929, 60931, 60896, 60904,     0,     1, 49152, 57344, 
+    61440, 60416, 60928, 60929, 60931, 60896, 60904, 60906, 
+        0,     1, 49152, 57344, 61440, 60416, 60928, 60929, 
+    60931, 60896, 60904,     0,     1, 49152, 57344, 61440, 
+    60416, 60928, 60929, 60931, 60896, 60912, 60908,     0, 
+        1, 49152, 57344, 61440, 60416, 60928, 60929, 60931, 
+    60896, 60912, 60908,     0,     1, 49152, 57344, 61440, 
+    60416, 60928, 60929, 60931, 60896, 60912, 60913, 60910, 
+        0,     1, 49152, 57344, 61440, 60416, 60928, 60929, 
+    60931, 60896,     0,     1, 49152, 57344, 61440, 60416, 
+    60928, 60929, 60931, 60896, 60912,     0,     1, 49152, 
+    57344, 61440, 60416, 60928, 60929, 60931, 60896, 60912, 
+        0,     1, 49152, 57344, 61440, 60416, 60928, 60929, 
+    60931, 60896, 60912, 60914,     0,     1, 49152, 57344, 
+    61440, 60416, 60928, 60929, 60931, 60935, 60912,     0, 
+        1, 49152, 57344, 61440, 60416, 60928, 60929, 60931, 
+    60935, 60912, 60916,     0,     1, 49152, 57344, 61440, 
+    60416, 60928, 60929, 60931, 60935, 60912, 60916,     0, 
+        1, 49152, 57344, 61440, 60416, 60928, 60929, 60931, 
+    60935, 60912, 60920, 60918,     0,     1, 49152, 57344, 
+    61440, 60416, 60928, 60929, 60931, 60935, 60912,     0, 
+        1, 49152, 57344, 61440, 60416, 60928, 60929, 60931, 
+    60935, 60912, 60920,     0,     1, 49152, 57344, 61440, 
+    60416, 60928, 60929, 60931, 60935, 60912, 60920,     0, 
+        1, 49152, 57344, 61440, 60416, 60928, 60929, 60931, 
+    60935, 60912, 60920, 60922,     0,     1, 49152, 57344, 
+    61440, 60416, 60928, 60929, 60931, 60935, 60912, 60920, 
+        0,     1, 49152, 57344, 61440, 60416, 60928, 60929, 
+    60931, 60935, 60912, 60920, 60924,     0,     1, 49152, 
+    57344, 61440, 60416, 60928, 60929, 60931, 60935, 60912, 
+    60920, 60924,     0,     1, 49152, 57344, 61440, 60416, 
+    60928, 60929, 60931, 60935, 60912, 60920, 60924, 60926, 
+        0,     1, 49152, 57344, 61440, 60416,     0,     1, 
+    49152, 57344, 61440, 60416, 60928,     0,     1, 49152, 
+    57344, 61440, 61441, 60928,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 60930,     0,     1, 49152, 57344, 
+    61440, 61441, 60928,     0,     1, 49152, 57344, 61440, 
+    61441, 60928, 60932,     0,     1, 49152, 57344, 61440, 
+    61441, 60928, 60932,     0,     1, 49152, 57344, 61440, 
+    61441, 60928, 60936, 60934,     0,     1, 49152, 57344, 
+    61440, 61441, 60928,     0,     1, 49152, 57344, 61440, 
+    61441, 60928, 60936,     0,     1, 49152, 57344, 61440, 
+    61441, 60928, 60936,     0,     1, 49152, 57344, 61440, 
+    61441, 60928, 60936, 60938,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 60936,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 60944, 60940,     0,     1, 49152, 
+    57344, 61440, 61441, 60928, 60944, 60940,     0,     1, 
+    49152, 57344, 61440, 61441, 60928, 60944, 60945, 60942, 
+        0,     1, 49152, 57344, 61440, 61441, 60928,     0, 
+        1, 49152, 57344, 61440, 61441, 60928, 60944,     0, 
+        1, 49152, 57344, 61440, 61441, 60928, 60944,     0, 
+        1, 49152, 57344, 61440, 61441, 60928, 60944, 60946, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 60944, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 60944, 
+    60948,     0,     1, 49152, 57344, 61440, 61441, 60928, 
+    60944, 60948,     0,     1, 49152, 57344, 61440, 61441, 
+    60928, 60944, 60952, 60950,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 60944,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 60960, 60952,     0,     1, 49152, 
+    57344, 61440, 61441, 60928, 60960, 60952,     0,     1, 
+    49152, 57344, 61440, 61441, 60928, 60960, 60952, 60954, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 60960, 
+    60952,     0,     1, 49152, 57344, 61440, 61441, 60928, 
+    60960, 60961, 60956,     0,     1, 49152, 57344, 61440, 
+    61441, 60928, 60960, 60961, 60956,     0,     1, 49152, 
+    57344, 61440, 61441, 60928, 60960, 60961, 60956, 60958, 
+        0,     1, 49152, 57344, 61440, 61441, 60928,     0, 
+        1, 49152, 57344, 61440, 61441, 60928, 60960,     0, 
+        1, 49152, 57344, 61440, 61441, 60928, 60960,     0, 
+        1, 49152, 57344, 61440, 61441, 60928, 60960, 60962, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 60960, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 60960, 
+    60964,     0,     1, 49152, 57344, 61440, 61441, 60928, 
+    60960, 60964,     0,     1, 49152, 57344, 61440, 61441, 
+    60928, 60960, 60968, 60966,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 60960,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 60960, 60968,     0,     1, 49152, 
+    57344, 61440, 61441, 60928, 60960, 60968,     0,     1, 
+    49152, 57344, 61440, 61441, 60928, 60960, 60968, 60970, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 60960, 
+    60968,     0,     1, 49152, 57344, 61440, 61441, 60928, 
+    60960, 60976, 60972,     0,     1, 49152, 57344, 61440, 
+    61441, 60928, 60960, 60976, 60972,     0,     1, 49152, 
+    57344, 61440, 61441, 60928, 60960, 60976, 60977, 60974, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 60960, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 60992, 
+    60976,     0,     1, 49152, 57344, 61440, 61441, 60928, 
+    60992, 60976,     0,     1, 49152, 57344, 61440, 61441, 
+    60928, 60992, 60976, 60978,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 60992, 60976,     0,     1, 49152, 
+    57344, 61440, 61441, 60928, 60992, 60976, 60980,     0, 
+        1, 49152, 57344, 61440, 61441, 60928, 60992, 60976, 
+    60980,     0,     1, 49152, 57344, 61440, 61441, 60928, 
+    60992, 60976, 60984, 60982,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 60992, 60976,     0,     1, 49152, 
+    57344, 61440, 61441, 60928, 60992, 60993, 60984,     0, 
+        1, 49152, 57344, 61440, 61441, 60928, 60992, 60993, 
+    60984,     0,     1, 49152, 57344, 61440, 61441, 60928, 
+    60992, 60993, 60984, 60986,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 60992, 60993, 60984,     0,     1, 
+    49152, 57344, 61440, 61441, 60928, 60992, 60993, 60984, 
+    60988,     0,     1, 49152, 57344, 61440, 61441, 60928, 
+    60992, 60993, 60995, 60988,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 60992, 60993, 60995, 60988, 60990, 
+        0,     1, 49152, 57344, 61440, 61441, 60928,     0, 
+        1, 49152, 57344, 61440, 61441, 60928, 60992,     0, 
+        1, 49152, 57344, 61440, 61441, 60928, 60992,     0, 
+        1, 49152, 57344, 61440, 61441, 60928, 60992, 60994, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 60992, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 60992, 
+    60996,     0,     1, 49152, 57344, 61440, 61441, 60928, 
+    60992, 60996,     0,     1, 49152, 57344, 61440, 61441, 
+    60928, 60992, 61000, 60998,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 60992,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 60992, 61000,     0,     1, 49152, 
+    57344, 61440, 61441, 60928, 60992, 61000,     0,     1, 
+    49152, 57344, 61440, 61441, 60928, 60992, 61000, 61002, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 60992, 
+    61000,     0,     1, 49152, 57344, 61440, 61441, 60928, 
+    60992, 61008, 61004,     0,     1, 49152, 57344, 61440, 
+    61441, 60928, 60992, 61008, 61004,     0,     1, 49152, 
+    57344, 61440, 61441, 60928, 60992, 61008, 61009, 61006, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 60992, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 60992, 
+    61008,     0,     1, 49152, 57344, 61440, 61441, 60928, 
+    60992, 61008,     0,     1, 49152, 57344, 61440, 61441, 
+    60928, 60992, 61008, 61010,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 60992, 61008,     0,     1, 49152, 
+    57344, 61440, 61441, 60928, 60992, 61008, 61012,     0, 
+        1, 49152, 57344, 61440, 61441, 60928, 60992, 61008, 
+    61012,     0,     1, 49152, 57344, 61440, 61441, 60928, 
+    60992, 61008, 61016, 61014,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 60992, 61008,     0,     1, 49152, 
+    57344, 61440, 61441, 60928, 60992, 61024, 61016,     0, 
+        1, 49152, 57344, 61440, 61441, 60928, 60992, 61024, 
+    61016,     0,     1, 49152, 57344, 61440, 61441, 60928, 
+    60992, 61024, 61016, 61018,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 60992, 61024, 61016,     0,     1, 
+    49152, 57344, 61440, 61441, 60928, 60992, 61024, 61025, 
+    61020,     0,     1, 49152, 57344, 61440, 61441, 60928, 
+    60992, 61024, 61025, 61020,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 60992, 61024, 61025, 61020, 61022, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 60992, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 61056, 
+    61024,     0,     1, 49152, 57344, 61440, 61441, 60928, 
+    61056, 61024,     0,     1, 49152, 57344, 61440, 61441, 
+    60928, 61056, 61024, 61026,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 61056, 61024,     0,     1, 49152, 
+    57344, 61440, 61441, 60928, 61056, 61024, 61028,     0, 
+        1, 49152, 57344, 61440, 61441, 60928, 61056, 61024, 
+    61028,     0,     1, 49152, 57344, 61440, 61441, 60928, 
+    61056, 61024, 61032, 61030,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 61056, 61024,     0,     1, 49152, 
+    57344, 61440, 61441, 60928, 61056, 61024, 61032,     0, 
+        1, 49152, 57344, 61440, 61441, 60928, 61056, 61024, 
+    61032,     0,     1, 49152, 57344, 61440, 61441, 60928, 
+    61056, 61024, 61032, 61034,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 61056, 61024, 61032,     0,     1, 
+    49152, 57344, 61440, 61441, 60928, 61056, 61024, 61040, 
+    61036,     0,     1, 49152, 57344, 61440, 61441, 60928, 
+    61056, 61024, 61040, 61036,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 61056, 61024, 61040, 61041, 61038, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 61056, 
+    61024,     0,     1, 49152, 57344, 61440, 61441, 60928, 
+    61056, 61057, 61040,     0,     1, 49152, 57344, 61440, 
+    61441, 60928, 61056, 61057, 61040,     0,     1, 49152, 
+    57344, 61440, 61441, 60928, 61056, 61057, 61040, 61042, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 61056, 
+    61057, 61040,     0,     1, 49152, 57344, 61440, 61441, 
+    60928, 61056, 61057, 61040, 61044,     0,     1, 49152, 
+    57344, 61440, 61441, 60928, 61056, 61057, 61040, 61044, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 61056, 
+    61057, 61040, 61048, 61046,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 61056, 61057, 61040,     0,     1, 
+    49152, 57344, 61440, 61441, 60928, 61056, 61057, 61040, 
+    61048,     0,     1, 49152, 57344, 61440, 61441, 60928, 
+    61056, 61057, 61059, 61048,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 61056, 61057, 61059, 61048, 61050, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 61056, 
+    61057, 61059, 61048,     0,     1, 49152, 57344, 61440, 
+    61441, 60928, 61056, 61057, 61059, 61048, 61052,     0, 
+        1, 49152, 57344, 61440, 61441, 60928, 61056, 61057, 
+    61059, 61048, 61052,     0,     1, 49152, 57344, 61440, 
+    61441, 60928, 61056, 61057, 61059, 61048, 61052, 61054, 
+        0,     1, 49152, 57344, 61440, 61441, 60928,     0, 
+        1, 49152, 57344, 61440, 61441, 60928, 61056,     0, 
+        1, 49152, 57344, 61440, 61441, 60928, 61056,     0, 
+        1, 49152, 57344, 61440, 61441, 60928, 61056, 61058, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 61056, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 61056, 
+    61060,     0,     1, 49152, 57344, 61440, 61441, 60928, 
+    61056, 61060,     0,     1, 49152, 57344, 61440, 61441, 
+    60928, 61056, 61064, 61062,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 61056,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 61056, 61064,     0,     1, 49152, 
+    57344, 61440, 61441, 60928, 61056, 61064,     0,     1, 
+    49152, 57344, 61440, 61441, 60928, 61056, 61064, 61066, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 61056, 
+    61064,     0,     1, 49152, 57344, 61440, 61441, 60928, 
+    61056, 61072, 61068,     0,     1, 49152, 57344, 61440, 
+    61441, 60928, 61056, 61072, 61068,     0,     1, 49152, 
+    57344, 61440, 61441, 60928, 61056, 61072, 61073, 61070, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 61056, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 61056, 
+    61072,     0,     1, 49152, 57344, 61440, 61441, 60928, 
+    61056, 61072,     0,     1, 49152, 57344, 61440, 61441, 
+    60928, 61056, 61072, 61074,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 61056, 61072,     0,     1, 49152, 
+    57344, 61440, 61441, 60928, 61056, 61072, 61076,     0, 
+        1, 49152, 57344, 61440, 61441, 60928, 61056, 61072, 
+    61076,     0,     1, 49152, 57344, 61440, 61441, 60928, 
+    61056, 61072, 61080, 61078,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 61056, 61072,     0,     1, 49152, 
+    57344, 61440, 61441, 60928, 61056, 61088, 61080,     0, 
+        1, 49152, 57344, 61440, 61441, 60928, 61056, 61088, 
+    61080,     0,     1, 49152, 57344, 61440, 61441, 60928, 
+    61056, 61088, 61080, 61082,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 61056, 61088, 61080,     0,     1, 
+    49152, 57344, 61440, 61441, 60928, 61056, 61088, 61089, 
+    61084,     0,     1, 49152, 57344, 61440, 61441, 60928, 
+    61056, 61088, 61089, 61084,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 61056, 61088, 61089, 61084, 61086, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 61056, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 61056, 
+    61088,     0,     1, 49152, 57344, 61440, 61441, 60928, 
+    61056, 61088,     0,     1, 49152, 57344, 61440, 61441, 
+    60928, 61056, 61088, 61090,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 61056, 61088,     0,     1, 49152, 
+    57344, 61440, 61441, 60928, 61056, 61088, 61092,     0, 
+        1, 49152, 57344, 61440, 61441, 60928, 61056, 61088, 
+    61092,     0,     1, 49152, 57344, 61440, 61441, 60928, 
+    61056, 61088, 61096, 61094,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 61056, 61088,     0,     1, 49152, 
+    57344, 61440, 61441, 60928, 61056, 61088, 61096,     0, 
+        1, 49152, 57344, 61440, 61441, 60928, 61056, 61088, 
+    61096,     0,     1, 49152, 57344, 61440, 61441, 60928, 
+    61056, 61088, 61096, 61098,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 61056, 61088, 61096,     0,     1, 
+    49152, 57344, 61440, 61441, 60928, 61056, 61088, 61104, 
+    61100,     0,     1, 49152, 57344, 61440, 61441, 60928, 
+    61056, 61088, 61104, 61100,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 61056, 61088, 61104, 61105, 61102, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 61056, 
+    61088,     0,     1, 49152, 57344, 61440, 61441, 60928, 
+    61056, 61120, 61104,     0,     1, 49152, 57344, 61440, 
+    61441, 60928, 61056, 61120, 61104,     0,     1, 49152, 
+    57344, 61440, 61441, 60928, 61056, 61120, 61104, 61106, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 61056, 
+    61120, 61104,     0,     1, 49152, 57344, 61440, 61441, 
+    60928, 61056, 61120, 61104, 61108,     0,     1, 49152, 
+    57344, 61440, 61441, 60928, 61056, 61120, 61104, 61108, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 61056, 
+    61120, 61104, 61112, 61110,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 61056, 61120, 61104,     0,     1, 
+    49152, 57344, 61440, 61441, 60928, 61056, 61120, 61121, 
+    61112,     0,     1, 49152, 57344, 61440, 61441, 60928, 
+    61056, 61120, 61121, 61112,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 61056, 61120, 61121, 61112, 61114, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 61056, 
+    61120, 61121, 61112,     0,     1, 49152, 57344, 61440, 
+    61441, 60928, 61056, 61120, 61121, 61112, 61116,     0, 
+        1, 49152, 57344, 61440, 61441, 60928, 61056, 61120, 
+    61121, 61123, 61116,     0,     1, 49152, 57344, 61440, 
+    61441, 60928, 61056, 61120, 61121, 61123, 61116, 61118, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 61056, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 61184, 
+    61120,     0,     1, 49152, 57344, 61440, 61441, 60928, 
+    61184, 61120,     0,     1, 49152, 57344, 61440, 61441, 
+    60928, 61184, 61120, 61122,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 61184, 61120,     0,     1, 49152, 
+    57344, 61440, 61441, 60928, 61184, 61120, 61124,     0, 
+        1, 49152, 57344, 61440, 61441, 60928, 61184, 61120, 
+    61124,     0,     1, 49152, 57344, 61440, 61441, 60928, 
+    61184, 61120, 61128, 61126,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 61184, 61120,     0,     1, 49152, 
+    57344, 61440, 61441, 60928, 61184, 61120, 61128,     0, 
+        1, 49152, 57344, 61440, 61441, 60928, 61184, 61120, 
+    61128,     0,     1, 49152, 57344, 61440, 61441, 60928, 
+    61184, 61120, 61128, 61130,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 61184, 61120, 61128,     0,     1, 
+    49152, 57344, 61440, 61441, 60928, 61184, 61120, 61136, 
+    61132,     0,     1, 49152, 57344, 61440, 61441, 60928, 
+    61184, 61120, 61136, 61132,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 61184, 61120, 61136, 61137, 61134, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 61184, 
+    61120,     0,     1, 49152, 57344, 61440, 61441, 60928, 
+    61184, 61120, 61136,     0,     1, 49152, 57344, 61440, 
+    61441, 60928, 61184, 61120, 61136,     0,     1, 49152, 
+    57344, 61440, 61441, 60928, 61184, 61120, 61136, 61138, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 61184, 
+    61120, 61136,     0,     1, 49152, 57344, 61440, 61441, 
+    60928, 61184, 61120, 61136, 61140,     0,     1, 49152, 
+    57344, 61440, 61441, 60928, 61184, 61120, 61136, 61140, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 61184, 
+    61120, 61136, 61144, 61142,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 61184, 61120, 61136,     0,     1, 
+    49152, 57344, 61440, 61441, 60928, 61184, 61120, 61152, 
+    61144,     0,     1, 49152, 57344, 61440, 61441, 60928, 
+    61184, 61120, 61152, 61144,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 61184, 61120, 61152, 61144, 61146, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 61184, 
+    61120, 61152, 61144,     0,     1, 49152, 57344, 61440, 
+    61441, 60928, 61184, 61120, 61152, 61153, 61148,     0, 
+        1, 49152, 57344, 61440, 61441, 60928, 61184, 61120, 
+    61152, 61153, 61148,     0,     1, 49152, 57344, 61440, 
+    61441, 60928, 61184, 61120, 61152, 61153, 61148, 61150, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 61184, 
+    61120,     0,     1, 49152, 57344, 61440, 61441, 60928, 
+    61184, 61185, 61152,     0,     1, 49152, 57344, 61440, 
+    61441, 60928, 61184, 61185, 61152,     0,     1, 49152, 
+    57344, 61440, 61441, 60928, 61184, 61185, 61152, 61154, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 61184, 
+    61185, 61152,     0,     1, 49152, 57344, 61440, 61441, 
+    60928, 61184, 61185, 61152, 61156,     0,     1, 49152, 
+    57344, 61440, 61441, 60928, 61184, 61185, 61152, 61156, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 61184, 
+    61185, 61152, 61160, 61158,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 61184, 61185, 61152,     0,     1, 
+    49152, 57344, 61440, 61441, 60928, 61184, 61185, 61152, 
+    61160,     0,     1, 49152, 57344, 61440, 61441, 60928, 
+    61184, 61185, 61152, 61160,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 61184, 61185, 61152, 61160, 61162, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 61184, 
+    61185, 61152, 61160,     0,     1, 49152, 57344, 61440, 
+    61441, 60928, 61184, 61185, 61152, 61168, 61164,     0, 
+        1, 49152, 57344, 61440, 61441, 60928, 61184, 61185, 
+    61152, 61168, 61164,     0,     1, 49152, 57344, 61440, 
+    61441, 60928, 61184, 61185, 61152, 61168, 61169, 61166, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 61184, 
+    61185, 61152,     0,     1, 49152, 57344, 61440, 61441, 
+    60928, 61184, 61185, 61152, 61168,     0,     1, 49152, 
+    57344, 61440, 61441, 60928, 61184, 61185, 61187, 61168, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 61184, 
+    61185, 61187, 61168, 61170,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 61184, 61185, 61187, 61168,     0, 
+        1, 49152, 57344, 61440, 61441, 60928, 61184, 61185, 
+    61187, 61168, 61172,     0,     1, 49152, 57344, 61440, 
+    61441, 60928, 61184, 61185, 61187, 61168, 61172,     0, 
+        1, 49152, 57344, 61440, 61441, 60928, 61184, 61185, 
+    61187, 61168, 61176, 61174,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 61184, 61185, 61187, 61168,     0, 
+        1, 49152, 57344, 61440, 61441, 60928, 61184, 61185, 
+    61187, 61168, 61176,     0,     1, 49152, 57344, 61440, 
+    61441, 60928, 61184, 61185, 61187, 61168, 61176,     0, 
+        1, 49152, 57344, 61440, 61441, 60928, 61184, 61185, 
+    61187, 61168, 61176, 61178,     0,     1, 49152, 57344, 
+    61440, 61441, 60928, 61184, 61185, 61187, 61191, 61176, 
+        0,     1, 49152, 57344, 61440, 61441, 60928, 61184, 
+    61185, 61187, 61191, 61176, 61180,     0,     1, 49152, 
+    57344, 61440, 61441, 60928, 61184, 61185, 61187, 61191, 
+    61176, 61180,     0,     1, 49152, 57344, 61440, 61441, 
+    60928, 61184, 61185, 61187, 61191, 61176, 61180, 61182, 
+        0,     1, 49152, 57344, 61440, 61441, 60928,     0, 
+        1, 49152, 57344, 61440, 61441, 60928, 61184,     0, 
+        1, 49152, 57344, 61440, 61441, 60928, 61184,     0, 
+        1, 49152, 57344, 61440, 61441, 60928, 61184, 61186, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61184, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61184, 
+    61188,     0,     1, 49152, 57344, 61440, 61441, 61443, 
+    61184, 61188,     0,     1, 49152, 57344, 61440, 61441, 
+    61443, 61184, 61192, 61190,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61184,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61184, 61192,     0,     1, 49152, 
+    57344, 61440, 61441, 61443, 61184, 61192,     0,     1, 
+    49152, 57344, 61440, 61441, 61443, 61184, 61192, 61194, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61184, 
+    61192,     0,     1, 49152, 57344, 61440, 61441, 61443, 
+    61184, 61200, 61196,     0,     1, 49152, 57344, 61440, 
+    61441, 61443, 61184, 61200, 61196,     0,     1, 49152, 
+    57344, 61440, 61441, 61443, 61184, 61200, 61201, 61198, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61184, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61184, 
+    61200,     0,     1, 49152, 57344, 61440, 61441, 61443, 
+    61184, 61200,     0,     1, 49152, 57344, 61440, 61441, 
+    61443, 61184, 61200, 61202,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61184, 61200,     0,     1, 49152, 
+    57344, 61440, 61441, 61443, 61184, 61200, 61204,     0, 
+        1, 49152, 57344, 61440, 61441, 61443, 61184, 61200, 
+    61204,     0,     1, 49152, 57344, 61440, 61441, 61443, 
+    61184, 61200, 61208, 61206,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61184, 61200,     0,     1, 49152, 
+    57344, 61440, 61441, 61443, 61184, 61216, 61208,     0, 
+        1, 49152, 57344, 61440, 61441, 61443, 61184, 61216, 
+    61208,     0,     1, 49152, 57344, 61440, 61441, 61443, 
+    61184, 61216, 61208, 61210,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61184, 61216, 61208,     0,     1, 
+    49152, 57344, 61440, 61441, 61443, 61184, 61216, 61217, 
+    61212,     0,     1, 49152, 57344, 61440, 61441, 61443, 
+    61184, 61216, 61217, 61212,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61184, 61216, 61217, 61212, 61214, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61184, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61184, 
+    61216,     0,     1, 49152, 57344, 61440, 61441, 61443, 
+    61184, 61216,     0,     1, 49152, 57344, 61440, 61441, 
+    61443, 61184, 61216, 61218,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61184, 61216,     0,     1, 49152, 
+    57344, 61440, 61441, 61443, 61184, 61216, 61220,     0, 
+        1, 49152, 57344, 61440, 61441, 61443, 61184, 61216, 
+    61220,     0,     1, 49152, 57344, 61440, 61441, 61443, 
+    61184, 61216, 61224, 61222,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61184, 61216,     0,     1, 49152, 
+    57344, 61440, 61441, 61443, 61184, 61216, 61224,     0, 
+        1, 49152, 57344, 61440, 61441, 61443, 61184, 61216, 
+    61224,     0,     1, 49152, 57344, 61440, 61441, 61443, 
+    61184, 61216, 61224, 61226,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61184, 61216, 61224,     0,     1, 
+    49152, 57344, 61440, 61441, 61443, 61184, 61216, 61232, 
+    61228,     0,     1, 49152, 57344, 61440, 61441, 61443, 
+    61184, 61216, 61232, 61228,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61184, 61216, 61232, 61233, 61230, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61184, 
+    61216,     0,     1, 49152, 57344, 61440, 61441, 61443, 
+    61184, 61248, 61232,     0,     1, 49152, 57344, 61440, 
+    61441, 61443, 61184, 61248, 61232,     0,     1, 49152, 
+    57344, 61440, 61441, 61443, 61184, 61248, 61232, 61234, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61184, 
+    61248, 61232,     0,     1, 49152, 57344, 61440, 61441, 
+    61443, 61184, 61248, 61232, 61236,     0,     1, 49152, 
+    57344, 61440, 61441, 61443, 61184, 61248, 61232, 61236, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61184, 
+    61248, 61232, 61240, 61238,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61184, 61248, 61232,     0,     1, 
+    49152, 57344, 61440, 61441, 61443, 61184, 61248, 61249, 
+    61240,     0,     1, 49152, 57344, 61440, 61441, 61443, 
+    61184, 61248, 61249, 61240,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61184, 61248, 61249, 61240, 61242, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61184, 
+    61248, 61249, 61240,     0,     1, 49152, 57344, 61440, 
+    61441, 61443, 61184, 61248, 61249, 61240, 61244,     0, 
+        1, 49152, 57344, 61440, 61441, 61443, 61184, 61248, 
+    61249, 61251, 61244,     0,     1, 49152, 57344, 61440, 
+    61441, 61443, 61184, 61248, 61249, 61251, 61244, 61246, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61184, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61184, 
+    61248,     0,     1, 49152, 57344, 61440, 61441, 61443, 
+    61184, 61248,     0,     1, 49152, 57344, 61440, 61441, 
+    61443, 61184, 61248, 61250,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61184, 61248,     0,     1, 49152, 
+    57344, 61440, 61441, 61443, 61184, 61248, 61252,     0, 
+        1, 49152, 57344, 61440, 61441, 61443, 61184, 61248, 
+    61252,     0,     1, 49152, 57344, 61440, 61441, 61443, 
+    61184, 61248, 61256, 61254,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61184, 61248,     0,     1, 49152, 
+    57344, 61440, 61441, 61443, 61184, 61248, 61256,     0, 
+        1, 49152, 57344, 61440, 61441, 61443, 61184, 61248, 
+    61256,     0,     1, 49152, 57344, 61440, 61441, 61443, 
+    61184, 61248, 61256, 61258,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61184, 61248, 61256,     0,     1, 
+    49152, 57344, 61440, 61441, 61443, 61184, 61248, 61264, 
+    61260,     0,     1, 49152, 57344, 61440, 61441, 61443, 
+    61184, 61248, 61264, 61260,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61184, 61248, 61264, 61265, 61262, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61184, 
+    61248,     0,     1, 49152, 57344, 61440, 61441, 61443, 
+    61184, 61248, 61264,     0,     1, 49152, 57344, 61440, 
+    61441, 61443, 61184, 61248, 61264,     0,     1, 49152, 
+    57344, 61440, 61441, 61443, 61184, 61248, 61264, 61266, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61184, 
+    61248, 61264,     0,     1, 49152, 57344, 61440, 61441, 
+    61443, 61184, 61248, 61264, 61268,     0,     1, 49152, 
+    57344, 61440, 61441, 61443, 61184, 61248, 61264, 61268, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61184, 
+    61248, 61264, 61272, 61270,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61184, 61248, 61264,     0,     1, 
+    49152, 57344, 61440, 61441, 61443, 61184, 61248, 61280, 
+    61272,     0,     1, 49152, 57344, 61440, 61441, 61443, 
+    61184, 61248, 61280, 61272,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61184, 61248, 61280, 61272, 61274, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61184, 
+    61248, 61280, 61272,     0,     1, 49152, 57344, 61440, 
+    61441, 61443, 61184, 61248, 61280, 61281, 61276,     0, 
+        1, 49152, 57344, 61440, 61441, 61443, 61184, 61248, 
+    61280, 61281, 61276,     0,     1, 49152, 57344, 61440, 
+    61441, 61443, 61184, 61248, 61280, 61281, 61276, 61278, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61184, 
+    61248,     0,     1, 49152, 57344, 61440, 61441, 61443, 
+    61184, 61312, 61280,     0,     1, 49152, 57344, 61440, 
+    61441, 61443, 61184, 61312, 61280,     0,     1, 49152, 
+    57344, 61440, 61441, 61443, 61184, 61312, 61280, 61282, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61184, 
+    61312, 61280,     0,     1, 49152, 57344, 61440, 61441, 
+    61443, 61184, 61312, 61280, 61284,     0,     1, 49152, 
+    57344, 61440, 61441, 61443, 61184, 61312, 61280, 61284, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61184, 
+    61312, 61280, 61288, 61286,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61184, 61312, 61280,     0,     1, 
+    49152, 57344, 61440, 61441, 61443, 61184, 61312, 61280, 
+    61288,     0,     1, 49152, 57344, 61440, 61441, 61443, 
+    61184, 61312, 61280, 61288,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61184, 61312, 61280, 61288, 61290, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61184, 
+    61312, 61280, 61288,     0,     1, 49152, 57344, 61440, 
+    61441, 61443, 61184, 61312, 61280, 61296, 61292,     0, 
+        1, 49152, 57344, 61440, 61441, 61443, 61184, 61312, 
+    61280, 61296, 61292,     0,     1, 49152, 57344, 61440, 
+    61441, 61443, 61184, 61312, 61280, 61296, 61297, 61294, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61184, 
+    61312, 61280,     0,     1, 49152, 57344, 61440, 61441, 
+    61443, 61184, 61312, 61313, 61296,     0,     1, 49152, 
+    57344, 61440, 61441, 61443, 61184, 61312, 61313, 61296, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61184, 
+    61312, 61313, 61296, 61298,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61184, 61312, 61313, 61296,     0, 
+        1, 49152, 57344, 61440, 61441, 61443, 61184, 61312, 
+    61313, 61296, 61300,     0,     1, 49152, 57344, 61440, 
+    61441, 61443, 61184, 61312, 61313, 61296, 61300,     0, 
+        1, 49152, 57344, 61440, 61441, 61443, 61184, 61312, 
+    61313, 61296, 61304, 61302,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61184, 61312, 61313, 61296,     0, 
+        1, 49152, 57344, 61440, 61441, 61443, 61184, 61312, 
+    61313, 61296, 61304,     0,     1, 49152, 57344, 61440, 
+    61441, 61443, 61184, 61312, 61313, 61315, 61304,     0, 
+        1, 49152, 57344, 61440, 61441, 61443, 61184, 61312, 
+    61313, 61315, 61304, 61306,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61184, 61312, 61313, 61315, 61304, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61184, 
+    61312, 61313, 61315, 61304, 61308,     0,     1, 49152, 
+    57344, 61440, 61441, 61443, 61184, 61312, 61313, 61315, 
+    61304, 61308,     0,     1, 49152, 57344, 61440, 61441, 
+    61443, 61184, 61312, 61313, 61315, 61304, 61308, 61310, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61184, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61184, 
+    61312,     0,     1, 49152, 57344, 61440, 61441, 61443, 
+    61184, 61312,     0,     1, 49152, 57344, 61440, 61441, 
+    61443, 61184, 61312, 61314,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61184, 61312,     0,     1, 49152, 
+    57344, 61440, 61441, 61443, 61184, 61312, 61316,     0, 
+        1, 49152, 57344, 61440, 61441, 61443, 61184, 61312, 
+    61316,     0,     1, 49152, 57344, 61440, 61441, 61443, 
+    61184, 61312, 61320, 61318,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61447, 61312,     0,     1, 49152, 
+    57344, 61440, 61441, 61443, 61447, 61312, 61320,     0, 
+        1, 49152, 57344, 61440, 61441, 61443, 61447, 61312, 
+    61320,     0,     1, 49152, 57344, 61440, 61441, 61443, 
+    61447, 61312, 61320, 61322,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61447, 61312, 61320,     0,     1, 
+    49152, 57344, 61440, 61441, 61443, 61447, 61312, 61328, 
+    61324,     0,     1, 49152, 57344, 61440, 61441, 61443, 
+    61447, 61312, 61328, 61324,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61447, 61312, 61328, 61329, 61326, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61447, 
+    61312,     0,     1, 49152, 57344, 61440, 61441, 61443, 
+    61447, 61312, 61328,     0,     1, 49152, 57344, 61440, 
+    61441, 61443, 61447, 61312, 61328,     0,     1, 49152, 
+    57344, 61440, 61441, 61443, 61447, 61312, 61328, 61330, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61447, 
+    61312, 61328,     0,     1, 49152, 57344, 61440, 61441, 
+    61443, 61447, 61312, 61328, 61332,     0,     1, 49152, 
+    57344, 61440, 61441, 61443, 61447, 61312, 61328, 61332, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61447, 
+    61312, 61328, 61336, 61334,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61447, 61312, 61328,     0,     1, 
+    49152, 57344, 61440, 61441, 61443, 61447, 61312, 61344, 
+    61336,     0,     1, 49152, 57344, 61440, 61441, 61443, 
+    61447, 61312, 61344, 61336,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61447, 61312, 61344, 61336, 61338, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61447, 
+    61312, 61344, 61336,     0,     1, 49152, 57344, 61440, 
+    61441, 61443, 61447, 61312, 61344, 61345, 61340,     0, 
+        1, 49152, 57344, 61440, 61441, 61443, 61447, 61312, 
+    61344, 61345, 61340,     0,     1, 49152, 57344, 61440, 
+    61441, 61443, 61447, 61312, 61344, 61345, 61340, 61342, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61447, 
+    61312,     0,     1, 49152, 57344, 61440, 61441, 61443, 
+    61447, 61312, 61344,     0,     1, 49152, 57344, 61440, 
+    61441, 61443, 61447, 61312, 61344,     0,     1, 49152, 
+    57344, 61440, 61441, 61443, 61447, 61312, 61344, 61346, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61447, 
+    61312, 61344,     0,     1, 49152, 57344, 61440, 61441, 
+    61443, 61447, 61312, 61344, 61348,     0,     1, 49152, 
+    57344, 61440, 61441, 61443, 61447, 61312, 61344, 61348, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61447, 
+    61312, 61344, 61352, 61350,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61447, 61312, 61344,     0,     1, 
+    49152, 57344, 61440, 61441, 61443, 61447, 61312, 61344, 
+    61352,     0,     1, 49152, 57344, 61440, 61441, 61443, 
+    61447, 61312, 61344, 61352,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61447, 61312, 61344, 61352, 61354, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61447, 
+    61312, 61344, 61352,     0,     1, 49152, 57344, 61440, 
+    61441, 61443, 61447, 61312, 61344, 61360, 61356,     0, 
+        1, 49152, 57344, 61440, 61441, 61443, 61447, 61312, 
+    61344, 61360, 61356,     0,     1, 49152, 57344, 61440, 
+    61441, 61443, 61447, 61312, 61344, 61360, 61361, 61358, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61447, 
+    61312, 61344,     0,     1, 49152, 57344, 61440, 61441, 
+    61443, 61447, 61312, 61376, 61360,     0,     1, 49152, 
+    57344, 61440, 61441, 61443, 61447, 61312, 61376, 61360, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61447, 
+    61312, 61376, 61360, 61362,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61447, 61312, 61376, 61360,     0, 
+        1, 49152, 57344, 61440, 61441, 61443, 61447, 61312, 
+    61376, 61360, 61364,     0,     1, 49152, 57344, 61440, 
+    61441, 61443, 61447, 61312, 61376, 61360, 61364,     0, 
+        1, 49152, 57344, 61440, 61441, 61443, 61447, 61312, 
+    61376, 61360, 61368, 61366,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61447, 61312, 61376, 61360,     0, 
+        1, 49152, 57344, 61440, 61441, 61443, 61447, 61312, 
+    61376, 61377, 61368,     0,     1, 49152, 57344, 61440, 
+    61441, 61443, 61447, 61312, 61376, 61377, 61368,     0, 
+        1, 49152, 57344, 61440, 61441, 61443, 61447, 61312, 
+    61376, 61377, 61368, 61370,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61447, 61312, 61376, 61377, 61368, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61447, 
+    61312, 61376, 61377, 61368, 61372,     0,     1, 49152, 
+    57344, 61440, 61441, 61443, 61447, 61312, 61376, 61377, 
+    61379, 61372,     0,     1, 49152, 57344, 61440, 61441, 
+    61443, 61447, 61312, 61376, 61377, 61379, 61372, 61374, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61447, 
+    61312,     0,     1, 49152, 57344, 61440, 61441, 61443, 
+    61447, 61312, 61376,     0,     1, 49152, 57344, 61440, 
+    61441, 61443, 61447, 61312, 61376,     0,     1, 49152, 
+    57344, 61440, 61441, 61443, 61447, 61312, 61376, 61378, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61447, 
+    61312, 61376,     0,     1, 49152, 57344, 61440, 61441, 
+    61443, 61447, 61312, 61376, 61380,     0,     1, 49152, 
+    57344, 61440, 61441, 61443, 61447, 61312, 61376, 61380, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61447, 
+    61312, 61376, 61384, 61382,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61447, 61312, 61376,     0,     1, 
+    49152, 57344, 61440, 61441, 61443, 61447, 61312, 61376, 
+    61384,     0,     1, 49152, 57344, 61440, 61441, 61443, 
+    61447, 61312, 61376, 61384,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61447, 61312, 61376, 61384, 61386, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61447, 
+    61312, 61376, 61384,     0,     1, 49152, 57344, 61440, 
+    61441, 61443, 61447, 61312, 61376, 61392, 61388,     0, 
+        1, 49152, 57344, 61440, 61441, 61443, 61447, 61312, 
+    61376, 61392, 61388,     0,     1, 49152, 57344, 61440, 
+    61441, 61443, 61447, 61312, 61376, 61392, 61393, 61390, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61447, 
+    61455, 61376,     0,     1, 49152, 57344, 61440, 61441, 
+    61443, 61447, 61455, 61376, 61392,     0,     1, 49152, 
+    57344, 61440, 61441, 61443, 61447, 61455, 61376, 61392, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61447, 
+    61455, 61376, 61392, 61394,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61447, 61455, 61376, 61392,     0, 
+        1, 49152, 57344, 61440, 61441, 61443, 61447, 61455, 
+    61376, 61392, 61396,     0,     1, 49152, 57344, 61440, 
+    61441, 61443, 61447, 61455, 61376, 61392, 61396,     0, 
+        1, 49152, 57344, 61440, 61441, 61443, 61447, 61455, 
+    61376, 61392, 61400, 61398,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61447, 61455, 61376, 61392,     0, 
+        1, 49152, 57344, 61440, 61441, 61443, 61447, 61455, 
+    61376, 61408, 61400,     0,     1, 49152, 57344, 61440, 
+    61441, 61443, 61447, 61455, 61376, 61408, 61400,     0, 
+        1, 49152, 57344, 61440, 61441, 61443, 61447, 61455, 
+    61376, 61408, 61400, 61402,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61447, 61455, 61376, 61408, 61400, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61447, 
+    61455, 61376, 61408, 61409, 61404,     0,     1, 49152, 
+    57344, 61440, 61441, 61443, 61447, 61455, 61376, 61408, 
+    61409, 61404,     0,     1, 49152, 57344, 61440, 61441, 
+    61443, 61447, 61455, 61376, 61408, 61409, 61404, 61406, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61447, 
+    61455, 61376,     0,     1, 49152, 57344, 61440, 61441, 
+    61443, 61447, 61455, 61376, 61408,     0,     1, 49152, 
+    57344, 61440, 61441, 61443, 61447, 61455, 61376, 61408, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61447, 
+    61455, 61376, 61408, 61410,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61447, 61455, 61376, 61408,     0, 
+        1, 49152, 57344, 61440, 61441, 61443, 61447, 61455, 
+    61376, 61408, 61412,     0,     1, 49152, 57344, 61440, 
+    61441, 61443, 61447, 61455, 61376, 61408, 61412,     0, 
+        1, 49152, 57344, 61440, 61441, 61443, 61447, 61455, 
+    61376, 61408, 61416, 61414,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61447, 61455, 61376, 61408,     0, 
+        1, 49152, 57344, 61440, 61441, 61443, 61447, 61455, 
+    61376, 61408, 61416,     0,     1, 49152, 57344, 61440, 
+    61441, 61443, 61447, 61455, 61376, 61408, 61416,     0, 
+        1, 49152, 57344, 61440, 61441, 61443, 61447, 61455, 
+    61376, 61408, 61416, 61418,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61447, 61455, 61376, 61408, 61416, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61447, 
+    61455, 61376, 61408, 61424, 61420,     0,     1, 49152, 
+    57344, 61440, 61441, 61443, 61447, 61455, 61376, 61408, 
+    61424, 61420,     0,     1, 49152, 57344, 61440, 61441, 
+    61443, 61447, 61455, 61376, 61408, 61424, 61425, 61422, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61447, 
+    61455, 61376, 61408,     0,     1, 49152, 57344, 61440, 
+    61441, 61443, 61447, 61455, 61376, 61408, 61424,     0, 
+        1, 49152, 57344, 61440, 61441, 61443, 61447, 61455, 
+    61376, 61408, 61424,     0,     1, 49152, 57344, 61440, 
+    61441, 61443, 61447, 61455, 61376, 61408, 61424, 61426, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61447, 
+    61455, 61376, 61408, 61424,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61447, 61455, 61376, 61408, 61424, 
+    61428,     0,     1, 49152, 57344, 61440, 61441, 61443, 
+    61447, 61455, 61376, 61408, 61424, 61428,     0,     1, 
+    49152, 57344, 61440, 61441, 61443, 61447, 61455, 61376, 
+    61408, 61424, 61432, 61430,     0,     1, 49152, 57344, 
+    61440, 61441, 61443, 61447, 61455, 61376, 61408, 61424, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61447, 
+    61455, 61376, 61408, 61424, 61432,     0,     1, 49152, 
+    57344, 61440, 61441, 61443, 61447, 61455, 61376, 61408, 
+    61424, 61432,     0,     1, 49152, 57344, 61440, 61441, 
+    61443, 61447, 61455, 61376, 61408, 61424, 61432, 61434, 
+        0,     1, 49152, 57344, 61440, 61441, 61443, 61447, 
+    61455, 61376, 61408, 61424, 61432,     0,     1, 49152, 
+    57344, 61440, 61441, 61443, 61447, 61455, 61376, 61408, 
+    61424, 61432, 61436,     0,     1, 49152, 57344, 61440, 
+    61441, 61443, 61447, 61455, 61376, 61408, 61424, 61432, 
+    61436,     0,     1, 49152, 57344, 61440, 61441, 61443, 
+    61447, 61455, 61376, 61408, 61424, 61432, 61436, 61438, 
+        0,     1, 49152, 57344,     0,     1, 49152, 57344, 
+    61440,     0,     1, 49152, 57344, 61440,     0,     1, 
+    49152, 57344, 61440, 61442,     0,     1, 49152, 57344, 
+    61440,     0,     1, 49152, 57344, 61440, 61444,     0, 
+        1, 49152, 57344, 61440, 61444,     0,     1, 49152, 
+    57344, 61440, 61448, 61446,     0,     1, 49152, 57344, 
+    61440,     0,     1, 49152, 57344, 61440, 61448,     0, 
+        1, 49152, 57344, 61440, 61448,     0,     1, 49152, 
+    57344, 61440, 61448, 61450,     0,     1, 49152, 57344, 
+    61440, 61448,     0,     1, 49152, 57344, 61440, 61456, 
+    61452,     0,     1, 49152, 57344, 61440, 61456, 61452, 
+        0,     1, 49152, 57344, 61440, 61456, 61457, 61454, 
+        0,     1, 49152, 57344, 61440,     0,     1, 49152, 
+    57344, 61440, 61456,     0,     1, 49152, 57344, 61440, 
+    61456,     0,     1, 49152, 57344, 61440, 61456, 61458, 
+        0,     1, 49152, 57344, 61440, 61456,     0,     1, 
+    49152, 57344, 61440, 61456, 61460,     0,     1, 49152, 
+    57344, 61440, 61456, 61460,     0,     1, 49152, 57344, 
+    61440, 61456, 61464, 61462,     0,     1, 49152, 57344, 
+    61440, 61456,     0,     1, 49152, 57344, 61440, 61472, 
+    61464,     0,     1, 49152, 57344, 61440, 61472, 61464, 
+        0,     1, 49152, 57344, 61440, 61472, 61464, 61466, 
+        0,     1, 49152, 57344, 61440, 61472, 61464,     0, 
+        1, 49152, 57344, 61440, 61472, 61473, 61468,     0, 
+        1, 49152, 57344, 61440, 61472, 61473, 61468,     0, 
+        1, 49152, 57344, 61440, 61472, 61473, 61468, 61470, 
+        0,     1, 49152, 57344, 61440,     0,     1, 49152, 
+    57344, 61440, 61472,     0,     1, 49152, 57344, 61440, 
+    61472,     0,     1, 49152, 57344, 61440, 61472, 61474, 
+        0,     1, 49152, 57344, 61440, 61472,     0,     1, 
+    49152, 57344, 61440, 61472, 61476,     0,     1, 49152, 
+    57344, 61440, 61472, 61476,     0,     1, 49152, 57344, 
+    61440, 61472, 61480, 61478,     0,     1, 49152, 57344, 
+    61440, 61472,     0,     1, 49152, 57344, 61440, 61472, 
+    61480,     0,     1, 49152, 57344, 61440, 61472, 61480, 
+        0,     1, 49152, 57344, 61440, 61472, 61480, 61482, 
+        0,     1, 49152, 57344, 61440, 61472, 61480,     0, 
+        1, 49152, 57344, 61440, 61472, 61488, 61484,     0, 
+        1, 49152, 57344, 61440, 61472, 61488, 61484,     0, 
+        1, 49152, 57344, 61440, 61472, 61488, 61489, 61486, 
+        0,     1, 49152, 57344, 61440, 61472,     0,     1, 
+    49152, 57344, 61440, 61504, 61488,     0,     1, 49152, 
+    57344, 61440, 61504, 61488,     0,     1, 49152, 57344, 
+    61440, 61504, 61488, 61490,     0,     1, 49152, 57344, 
+    61440, 61504, 61488,     0,     1, 49152, 57344, 61440, 
+    61504, 61488, 61492,     0,     1, 49152, 57344, 61440, 
+    61504, 61488, 61492,     0,     1, 49152, 57344, 61440, 
+    61504, 61488, 61496, 61494,     0,     1, 49152, 57344, 
+    61440, 61504, 61488,     0,     1, 49152, 57344, 61440, 
+    61504, 61505, 61496,     0,     1, 49152, 57344, 61440, 
+    61504, 61505, 61496,     0,     1, 49152, 57344, 61440, 
+    61504, 61505, 61496, 61498,     0,     1, 49152, 57344, 
+    61440, 61504, 61505, 61496,     0,     1, 49152, 57344, 
+    61440, 61504, 61505, 61496, 61500,     0,     1, 49152, 
+    57344, 61440, 61504, 61505, 61507, 61500,     0,     1, 
+    49152, 57344, 61440, 61504, 61505, 61507, 61500, 61502, 
+        0,     1, 49152, 57344, 61440,     0,     1, 49152, 
+    57344, 61440, 61504,     0,     1, 49152, 57344, 61440, 
+    61504,     0,     1, 49152, 57344, 61440, 61504, 61506, 
+        0,     1, 49152, 57344, 61440, 61504,     0,     1, 
+    49152, 57344, 61440, 61504, 61508,     0,     1, 49152, 
+    57344, 61440, 61504, 61508,     0,     1, 49152, 57344, 
+    61440, 61504, 61512, 61510,     0,     1, 49152, 57344, 
+    61440, 61504,     0,     1, 49152, 57344, 61440, 61504, 
+    61512,     0,     1, 49152, 57344, 61440, 61504, 61512, 
+        0,     1, 49152, 57344, 61440, 61504, 61512, 61514, 
+        0,     1, 49152, 57344, 61440, 61504, 61512,     0, 
+        1, 49152, 57344, 61440, 61504, 61520, 61516,     0, 
+        1, 49152, 57344, 61440, 61504, 61520, 61516,     0, 
+        1, 49152, 57344, 61440, 61504, 61520, 61521, 61518, 
+        0,     1, 49152, 57344, 61440, 61504,     0,     1, 
+    49152, 57344, 61440, 61504, 61520,     0,     1, 49152, 
+    57344, 61440, 61504, 61520,     0,     1, 49152, 57344, 
+    61440, 61504, 61520, 61522,     0,     1, 49152, 57344, 
+    61440, 61504, 61520,     0,     1, 49152, 57344, 61440, 
+    61504, 61520, 61524,     0,     1, 49152, 57344, 61440, 
+    61504, 61520, 61524,     0,     1, 49152, 57344, 61440, 
+    61504, 61520, 61528, 61526,     0,     1, 49152, 57344, 
+    61440, 61504, 61520,     0,     1, 49152, 57344, 61440, 
+    61504, 61536, 61528,     0,     1, 49152, 57344, 61440, 
+    61504, 61536, 61528,     0,     1, 49152, 57344, 61440, 
+    61504, 61536, 61528, 61530,     0,     1, 49152, 57344, 
+    61440, 61504, 61536, 61528,     0,     1, 49152, 57344, 
+    61440, 61504, 61536, 61537, 61532,     0,     1, 49152, 
+    57344, 61440, 61504, 61536, 61537, 61532,     0,     1, 
+    49152, 57344, 61440, 61504, 61536, 61537, 61532, 61534, 
+        0,     1, 49152, 57344, 61440, 61504,     0,     1, 
+    49152, 57344, 61440, 61568, 61536,     0,     1, 49152, 
+    57344, 61440, 61568, 61536,     0,     1, 49152, 57344, 
+    61440, 61568, 61536, 61538,     0,     1, 49152, 57344, 
+    61440, 61568, 61536,     0,     1, 49152, 57344, 61440, 
+    61568, 61536, 61540,     0,     1, 49152, 57344, 61440, 
+    61568, 61536, 61540,     0,     1, 49152, 57344, 61440, 
+    61568, 61536, 61544, 61542,     0,     1, 49152, 57344, 
+    61440, 61568, 61536,     0,     1, 49152, 57344, 61440, 
+    61568, 61536, 61544,     0,     1, 49152, 57344, 61440, 
+    61568, 61536, 61544,     0,     1, 49152, 57344, 61440, 
+    61568, 61536, 61544, 61546,     0,     1, 49152, 57344, 
+    61440, 61568, 61536, 61544,     0,     1, 49152, 57344, 
+    61440, 61568, 61536, 61552, 61548,     0,     1, 49152, 
+    57344, 61440, 61568, 61536, 61552, 61548,     0,     1, 
+    49152, 57344, 61440, 61568, 61536, 61552, 61553, 61550, 
+        0,     1, 49152, 57344, 61440, 61568, 61536,     0, 
+        1, 49152, 57344, 61440, 61568, 61569, 61552,     0, 
+        1, 49152, 57344, 61440, 61568, 61569, 61552,     0, 
+        1, 49152, 57344, 61440, 61568, 61569, 61552, 61554, 
+        0,     1, 49152, 57344, 61440, 61568, 61569, 61552, 
+        0,     1, 49152, 57344, 61440, 61568, 61569, 61552, 
+    61556,     0,     1, 49152, 57344, 61440, 61568, 61569, 
+    61552, 61556,     0,     1, 49152, 57344, 61440, 61568, 
+    61569, 61552, 61560, 61558,     0,     1, 49152, 57344, 
+    61440, 61568, 61569, 61552,     0,     1, 49152, 57344, 
+    61440, 61568, 61569, 61552, 61560,     0,     1, 49152, 
+    57344, 61440, 61568, 61569, 61571, 61560,     0,     1, 
+    49152, 57344, 61440, 61568, 61569, 61571, 61560, 61562, 
+        0,     1, 49152, 57344, 61440, 61568, 61569, 61571, 
+    61560,     0,     1, 49152, 57344, 61440, 61568, 61569, 
+    61571, 61560, 61564,     0,     1, 49152, 57344, 61440, 
+    61568, 61569, 61571, 61560, 61564,     0,     1, 49152, 
+    57344, 61440, 61568, 61569, 61571, 61560, 61564, 61566, 
+        0,     1, 49152, 57344, 61440,     0,     1, 49152, 
+    57344, 61440, 61568,     0,     1, 49152, 57344, 61440, 
+    61568,     0,     1, 49152, 57344, 61440, 61568, 61570, 
+        0,     1, 49152, 57344, 61440, 61568,     0,     1, 
+    49152, 57344, 61440, 61568, 61572,     0,     1, 49152, 
+    57344, 61440, 61568, 61572,     0,     1, 49152, 57344, 
+    61440, 61568, 61576, 61574,     0,     1, 49152, 57344, 
+    61440, 61568,     0,     1, 49152, 57344, 61440, 61568, 
+    61576,     0,     1, 49152, 57344, 61440, 61568, 61576, 
+        0,     1, 49152, 57344, 61440, 61568, 61576, 61578, 
+        0,     1, 49152, 57344, 61440, 61568, 61576,     0, 
+        1, 49152, 57344, 61440, 61568, 61584, 61580,     0, 
+        1, 49152, 57344, 61440, 61568, 61584, 61580,     0, 
+        1, 49152, 57344, 61440, 61568, 61584, 61585, 61582, 
+        0,     1, 49152, 57344, 61440, 61568,     0,     1, 
+    49152, 57344, 61440, 61568, 61584,     0,     1, 49152, 
+    57344, 61440, 61568, 61584,     0,     1, 49152, 57344, 
+    61440, 61568, 61584, 61586,     0,     1, 49152, 57344, 
+    61440, 61568, 61584,     0,     1, 49152, 57344, 61440, 
+    61568, 61584, 61588,     0,     1, 49152, 57344, 61440, 
+    61568, 61584, 61588,     0,     1, 49152, 57344, 61440, 
+    61568, 61584, 61592, 61590,     0,     1, 49152, 57344, 
+    61440, 61568, 61584,     0,     1, 49152, 57344, 61440, 
+    61568, 61600, 61592,     0,     1, 49152, 57344, 61440, 
+    61568, 61600, 61592,     0,     1, 49152, 57344, 61440, 
+    61568, 61600, 61592, 61594,     0,     1, 49152, 57344, 
+    61440, 61568, 61600, 61592,     0,     1, 49152, 57344, 
+    61440, 61568, 61600, 61601, 61596,     0,     1, 49152, 
+    57344, 61440, 61568, 61600, 61601, 61596,     0,     1, 
+    49152, 57344, 61440, 61568, 61600, 61601, 61596, 61598, 
+        0,     1, 49152, 57344, 61440, 61568,     0,     1, 
+    49152, 57344, 61440, 61568, 61600,     0,     1, 49152, 
+    57344, 61440, 61568, 61600,     0,     1, 49152, 57344, 
+    61440, 61568, 61600, 61602,     0,     1, 49152, 57344, 
+    61440, 61568, 61600,     0,     1, 49152, 57344, 61440, 
+    61568, 61600, 61604,     0,     1, 49152, 57344, 61440, 
+    61568, 61600, 61604,     0,     1, 49152, 57344, 61440, 
+    61568, 61600, 61608, 61606,     0,     1, 49152, 57344, 
+    61440, 61568, 61600,     0,     1, 49152, 57344, 61440, 
+    61568, 61600, 61608,     0,     1, 49152, 57344, 61440, 
+    61568, 61600, 61608,     0,     1, 49152, 57344, 61440, 
+    61568, 61600, 61608, 61610,     0,     1, 49152, 57344, 
+    61440, 61568, 61600, 61608,     0,     1, 49152, 57344, 
+    61440, 61568, 61600, 61616, 61612,     0,     1, 49152, 
+    57344, 61440, 61568, 61600, 61616, 61612,     0,     1, 
+    49152, 57344, 61440, 61568, 61600, 61616, 61617, 61614, 
+        0,     1, 49152, 57344, 61440, 61568, 61600,     0, 
+        1, 49152, 57344, 61440, 61568, 61632, 61616,     0, 
+        1, 49152, 57344, 61440, 61568, 61632, 61616,     0, 
+        1, 49152, 57344, 61440, 61568, 61632, 61616, 61618, 
+        0,     1, 49152, 57344, 61440, 61568, 61632, 61616, 
+        0,     1, 49152, 57344, 61440, 61568, 61632, 61616, 
+    61620,     0,     1, 49152, 57344, 61440, 61568, 61632, 
+    61616, 61620,     0,     1, 49152, 57344, 61440, 61568, 
+    61632, 61616, 61624, 61622,     0,     1, 49152, 57344, 
+    61440, 61568, 61632, 61616,     0,     1, 49152, 57344, 
+    61440, 61568, 61632, 61633, 61624,     0,     1, 49152, 
+    57344, 61440, 61568, 61632, 61633, 61624,     0,     1, 
+    49152, 57344, 61440, 61568, 61632, 61633, 61624, 61626, 
+        0,     1, 49152, 57344, 61440, 61568, 61632, 61633, 
+    61624,     0,     1, 49152, 57344, 61440, 61568, 61632, 
+    61633, 61624, 61628,     0,     1, 49152, 57344, 61440, 
+    61568, 61632, 61633, 61635, 61628,     0,     1, 49152, 
+    57344, 61440, 61568, 61632, 61633, 61635, 61628, 61630, 
+        0,     1, 49152, 57344, 61440, 61568,     0,     1, 
+    49152, 57344, 61440, 61696, 61632,     0,     1, 49152, 
+    57344, 61440, 61696, 61632,     0,     1, 49152, 57344, 
+    61440, 61696, 61632, 61634,     0,     1, 49152, 57344, 
+    61440, 61696, 61632,     0,     1, 49152, 57344, 61440, 
+    61696, 61632, 61636,     0,     1, 49152, 57344, 61440, 
+    61696, 61632, 61636,     0,     1, 49152, 57344, 61440, 
+    61696, 61632, 61640, 61638,     0,     1, 49152, 57344, 
+    61440, 61696, 61632,     0,     1, 49152, 57344, 61440, 
+    61696, 61632, 61640,     0,     1, 49152, 57344, 61440, 
+    61696, 61632, 61640,     0,     1, 49152, 57344, 61440, 
+    61696, 61632, 61640, 61642,     0,     1, 49152, 57344, 
+    61440, 61696, 61632, 61640,     0,     1, 49152, 57344, 
+    61440, 61696, 61632, 61648, 61644,     0,     1, 49152, 
+    57344, 61440, 61696, 61632, 61648, 61644,     0,     1, 
+    49152, 57344, 61440, 61696, 61632, 61648, 61649, 61646, 
+        0,     1, 49152, 57344, 61440, 61696, 61632,     0, 
+        1, 49152, 57344, 61440, 61696, 61632, 61648,     0, 
+        1, 49152, 57344, 61440, 61696, 61632, 61648,     0, 
+        1, 49152, 57344, 61440, 61696, 61632, 61648, 61650, 
+        0,     1, 49152, 57344, 61440, 61696, 61632, 61648, 
+        0,     1, 49152, 57344, 61440, 61696, 61632, 61648, 
+    61652,     0,     1, 49152, 57344, 61440, 61696, 61632, 
+    61648, 61652,     0,     1, 49152, 57344, 61440, 61696, 
+    61632, 61648, 61656, 61654,     0,     1, 49152, 57344, 
+    61440, 61696, 61632, 61648,     0,     1, 49152, 57344, 
+    61440, 61696, 61632, 61664, 61656,     0,     1, 49152, 
+    57344, 61440, 61696, 61632, 61664, 61656,     0,     1, 
+    49152, 57344, 61440, 61696, 61632, 61664, 61656, 61658, 
+        0,     1, 49152, 57344, 61440, 61696, 61632, 61664, 
+    61656,     0,     1, 49152, 57344, 61440, 61696, 61632, 
+    61664, 61665, 61660,     0,     1, 49152, 57344, 61440, 
+    61696, 61632, 61664, 61665, 61660,     0,     1, 49152, 
+    57344, 61440, 61696, 61632, 61664, 61665, 61660, 61662, 
+        0,     1, 49152, 57344, 61440, 61696, 61632,     0, 
+        1, 49152, 57344, 61440, 61696, 61697, 61664,     0, 
+        1, 49152, 57344, 61440, 61696, 61697, 61664,     0, 
+        1, 49152, 57344, 61440, 61696, 61697, 61664, 61666, 
+        0,     1, 49152, 57344, 61440, 61696, 61697, 61664, 
+        0,     1, 49152, 57344, 61440, 61696, 61697, 61664, 
+    61668,     0,     1, 49152, 57344, 61440, 61696, 61697, 
+    61664, 61668,     0,     1, 49152, 57344, 61440, 61696, 
+    61697, 61664, 61672, 61670,     0,     1, 49152, 57344, 
+    61440, 61696, 61697, 61664,     0,     1, 49152, 57344, 
+    61440, 61696, 61697, 61664, 61672,     0,     1, 49152, 
+    57344, 61440, 61696, 61697, 61664, 61672,     0,     1, 
+    49152, 57344, 61440, 61696, 61697, 61664, 61672, 61674, 
+        0,     1, 49152, 57344, 61440, 61696, 61697, 61664, 
+    61672,     0,     1, 49152, 57344, 61440, 61696, 61697, 
+    61664, 61680, 61676,     0,     1, 49152, 57344, 61440, 
+    61696, 61697, 61664, 61680, 61676,     0,     1, 49152, 
+    57344, 61440, 61696, 61697, 61664, 61680, 61681, 61678, 
+        0,     1, 49152, 57344, 61440, 61696, 61697, 61664, 
+        0,     1, 49152, 57344, 61440, 61696, 61697, 61664, 
+    61680,     0,     1, 49152, 57344, 61440, 61696, 61697, 
+    61699, 61680,     0,     1, 49152, 57344, 61440, 61696, 
+    61697, 61699, 61680, 61682,     0,     1, 49152, 57344, 
+    61440, 61696, 61697, 61699, 61680,     0,     1, 49152, 
+    57344, 61440, 61696, 61697, 61699, 61680, 61684,     0, 
+        1, 49152, 57344, 61440, 61696, 61697, 61699, 61680, 
+    61684,     0,     1, 49152, 57344, 61440, 61696, 61697, 
+    61699, 61680, 61688, 61686,     0,     1, 49152, 57344, 
+    61440, 61696, 61697, 61699, 61680,     0,     1, 49152, 
+    57344, 61440, 61696, 61697, 61699, 61680, 61688,     0, 
+        1, 49152, 57344, 61440, 61696, 61697, 61699, 61680, 
+    61688,     0,     1, 49152, 57344, 61440, 61696, 61697, 
+    61699, 61680, 61688, 61690,     0,     1, 49152, 57344, 
+    61440, 61696, 61697, 61699, 61703, 61688,     0,     1, 
+    49152, 57344, 61440, 61696, 61697, 61699, 61703, 61688, 
+    61692,     0,     1, 49152, 57344, 61440, 61696, 61697, 
+    61699, 61703, 61688, 61692,     0,     1, 49152, 57344, 
+    61440, 61696, 61697, 61699, 61703, 61688, 61692, 61694, 
+        0,     1, 49152, 57344, 61440,     0,     1, 49152, 
+    57344, 61440, 61696,     0,     1, 49152, 57344, 61440, 
+    61696,     0,     1, 49152, 57344, 61440, 61696, 61698, 
+        0,     1, 49152, 57344, 61440, 61696,     0,     1, 
+    49152, 57344, 61440, 61696, 61700,     0,     1, 49152, 
+    57344, 61440, 61696, 61700,     0,     1, 49152, 57344, 
+    61440, 61696, 61704, 61702,     0,     1, 49152, 57344, 
+    61440, 61696,     0,     1, 49152, 57344, 61440, 61696, 
+    61704,     0,     1, 49152, 57344, 61440, 61696, 61704, 
+        0,     1, 49152, 57344, 61440, 61696, 61704, 61706, 
+        0,     1, 49152, 57344, 61440, 61696, 61704,     0, 
+        1, 49152, 57344, 61440, 61696, 61712, 61708,     0, 
+        1, 49152, 57344, 61440, 61696, 61712, 61708,     0, 
+        1, 49152, 57344, 61440, 61696, 61712, 61713, 61710, 
+        0,     1, 49152, 57344, 61440, 61696,     0,     1, 
+    49152, 57344, 61440, 61696, 61712,     0,     1, 49152, 
+    57344, 61440, 61696, 61712,     0,     1, 49152, 57344, 
+    61440, 61696, 61712, 61714,     0,     1, 49152, 57344, 
+    61440, 61696, 61712,     0,     1, 49152, 57344, 61440, 
+    61696, 61712, 61716,     0,     1, 49152, 57344, 61440, 
+    61696, 61712, 61716,     0,     1, 49152, 57344, 61440, 
+    61696, 61712, 61720, 61718,     0,     1, 49152, 57344, 
+    61440, 61696, 61712,     0,     1, 49152, 57344, 61440, 
+    61696, 61728, 61720,     0,     1, 49152, 57344, 61440, 
+    61696, 61728, 61720,     0,     1, 49152, 57344, 61440, 
+    61696, 61728, 61720, 61722,     0,     1, 49152, 57344, 
+    61440, 61696, 61728, 61720,     0,     1, 49152, 57344, 
+    61440, 61696, 61728, 61729, 61724,     0,     1, 49152, 
+    57344, 61440, 61696, 61728, 61729, 61724,     0,     1, 
+    49152, 57344, 61440, 61696, 61728, 61729, 61724, 61726, 
+        0,     1, 49152, 57344, 61440, 61696,     0,     1, 
+    49152, 57344, 61440, 61696, 61728,     0,     1, 49152, 
+    57344, 61440, 61696, 61728,     0,     1, 49152, 57344, 
+    61440, 61696, 61728, 61730,     0,     1, 49152, 57344, 
+    61440, 61696, 61728,     0,     1, 49152, 57344, 61440, 
+    61696, 61728, 61732,     0,     1, 49152, 57344, 61440, 
+    61696, 61728, 61732,     0,     1, 49152, 57344, 61440, 
+    61696, 61728, 61736, 61734,     0,     1, 49152, 57344, 
+    61440, 61696, 61728,     0,     1, 49152, 57344, 61440, 
+    61696, 61728, 61736,     0,     1, 49152, 57344, 61440, 
+    61696, 61728, 61736,     0,     1, 49152, 57344, 61440, 
+    61696, 61728, 61736, 61738,     0,     1, 49152, 57344, 
+    61440, 61696, 61728, 61736,     0,     1, 49152, 57344, 
+    61440, 61696, 61728, 61744, 61740,     0,     1, 49152, 
+    57344, 61440, 61696, 61728, 61744, 61740,     0,     1, 
+    49152, 57344, 61440, 61696, 61728, 61744, 61745, 61742, 
+        0,     1, 49152, 57344, 61440, 61696, 61728,     0, 
+        1, 49152, 57344, 61440, 61696, 61760, 61744,     0, 
+        1, 49152, 57344, 61440, 61696, 61760, 61744,     0, 
+        1, 49152, 57344, 61440, 61696, 61760, 61744, 61746, 
+        0,     1, 49152, 57344, 61440, 61696, 61760, 61744, 
+        0,     1, 49152, 57344, 61440, 61696, 61760, 61744, 
+    61748,     0,     1, 49152, 57344, 61440, 61696, 61760, 
+    61744, 61748,     0,     1, 49152, 57344, 61440, 61696, 
+    61760, 61744, 61752, 61750,     0,     1, 49152, 57344, 
+    61440, 61696, 61760, 61744,     0,     1, 49152, 57344, 
+    61440, 61696, 61760, 61761, 61752,     0,     1, 49152, 
+    57344, 61440, 61696, 61760, 61761, 61752,     0,     1, 
+    49152, 57344, 61440, 61696, 61760, 61761, 61752, 61754, 
+        0,     1, 49152, 57344, 61440, 61696, 61760, 61761, 
+    61752,     0,     1, 49152, 57344, 61440, 61696, 61760, 
+    61761, 61752, 61756,     0,     1, 49152, 57344, 61440, 
+    61696, 61760, 61761, 61763, 61756,     0,     1, 49152, 
+    57344, 61440, 61696, 61760, 61761, 61763, 61756, 61758, 
+        0,     1, 49152, 57344, 61440, 61696,     0,     1, 
+    49152, 57344, 61440, 61696, 61760,     0,     1, 49152, 
+    57344, 61440, 61696, 61760,     0,     1, 49152, 57344, 
+    61440, 61696, 61760, 61762,     0,     1, 49152, 57344, 
+    61440, 61696, 61760,     0,     1, 49152, 57344, 61440, 
+    61696, 61760, 61764,     0,     1, 49152, 57344, 61440, 
+    61696, 61760, 61764,     0,     1, 49152, 57344, 61440, 
+    61696, 61760, 61768, 61766,     0,     1, 49152, 57344, 
+    61440, 61696, 61760,     0,     1, 49152, 57344, 61440, 
+    61696, 61760, 61768,     0,     1, 49152, 57344, 61440, 
+    61696, 61760, 61768,     0,     1, 49152, 57344, 61440, 
+    61696, 61760, 61768, 61770,     0,     1, 49152, 57344, 
+    61440, 61696, 61760, 61768,     0,     1, 49152, 57344, 
+    61440, 61696, 61760, 61776, 61772,     0,     1, 49152, 
+    57344, 61440, 61696, 61760, 61776, 61772,     0,     1, 
+    49152, 57344, 61440, 61696, 61760, 61776, 61777, 61774, 
+        0,     1, 49152, 57344, 61440, 61696, 61760,     0, 
+        1, 49152, 57344, 61440, 61696, 61760, 61776,     0, 
+        1, 49152, 57344, 61440, 61696, 61760, 61776,     0, 
+        1, 49152, 57344, 61440, 61696, 61760, 61776, 61778, 
+        0,     1, 49152, 57344, 61440, 61696, 61760, 61776, 
+        0,     1, 49152, 57344, 61440, 61696, 61760, 61776, 
+    61780,     0,     1, 49152, 57344, 61440, 61696, 61760, 
+    61776, 61780,     0,     1, 49152, 57344, 61440, 61696, 
+    61760, 61776, 61784, 61782,     0,     1, 49152, 57344, 
+    61440, 61696, 61760, 61776,     0,     1, 49152, 57344, 
+    61440, 61696, 61760, 61792, 61784,     0,     1, 49152, 
+    57344, 61440, 61696, 61760, 61792, 61784,     0,     1, 
+    49152, 57344, 61440, 61696, 61760, 61792, 61784, 61786, 
+        0,     1, 49152, 57344, 61440, 61696, 61760, 61792, 
+    61784,     0,     1, 49152, 57344, 61440, 61696, 61760, 
+    61792, 61793, 61788,     0,     1, 49152, 57344, 61440, 
+    61696, 61760, 61792, 61793, 61788,     0,     1, 49152, 
+    57344, 61440, 61696, 61760, 61792, 61793, 61788, 61790, 
+        0,     1, 49152, 57344, 61440, 61696, 61760,     0, 
+        1, 49152, 57344, 61440, 61696, 61824, 61792,     0, 
+        1, 49152, 57344, 61440, 61696, 61824, 61792,     0, 
+        1, 49152, 57344, 61440, 61696, 61824, 61792, 61794, 
+        0,     1, 49152, 57344, 61440, 61696, 61824, 61792, 
+        0,     1, 49152, 57344, 61440, 61696, 61824, 61792, 
+    61796,     0,     1, 49152, 57344, 61440, 61696, 61824, 
+    61792, 61796,     0,     1, 49152, 57344, 61440, 61696, 
+    61824, 61792, 61800, 61798,     0,     1, 49152, 57344, 
+    61440, 61696, 61824, 61792,     0,     1, 49152, 57344, 
+    61440, 61696, 61824, 61792, 61800,     0,     1, 49152, 
+    57344, 61440, 61696, 61824, 61792, 61800,     0,     1, 
+    49152, 57344, 61440, 61696, 61824, 61792, 61800, 61802, 
+        0,     1, 49152, 57344, 61440, 61696, 61824, 61792, 
+    61800,     0,     1, 49152, 57344, 61440, 61696, 61824, 
+    61792, 61808, 61804,     0,     1, 49152, 57344, 61440, 
+    61696, 61824, 61792, 61808, 61804,     0,     1, 49152, 
+    57344, 61440, 61696, 61824, 61792, 61808, 61809, 61806, 
+        0,     1, 49152, 57344, 61440, 61696, 61824, 61792, 
+        0,     1, 49152, 57344, 61440, 61696, 61824, 61825, 
+    61808,     0,     1, 49152, 57344, 61440, 61696, 61824, 
+    61825, 61808,     0,     1, 49152, 57344, 61440, 61696, 
+    61824, 61825, 61808, 61810,     0,     1, 49152, 57344, 
+    61440, 61696, 61824, 61825, 61808,     0,     1, 49152, 
+    57344, 61440, 61696, 61824, 61825, 61808, 61812,     0, 
+        1, 49152, 57344, 61440, 61696, 61824, 61825, 61808, 
+    61812,     0,     1, 49152, 57344, 61440, 61696, 61824, 
+    61825, 61808, 61816, 61814,     0,     1, 49152, 57344, 
+    61440, 61696, 61824, 61825, 61808,     0,     1, 49152, 
+    57344, 61440, 61696, 61824, 61825, 61808, 61816,     0, 
+        1, 49152, 57344, 61440, 61696, 61824, 61825, 61827, 
+    61816,     0,     1, 49152, 57344, 61440, 61696, 61824, 
+    61825, 61827, 61816, 61818,     0,     1, 49152, 57344, 
+    61440, 61696, 61824, 61825, 61827, 61816,     0,     1, 
+    49152, 57344, 61440, 61696, 61824, 61825, 61827, 61816, 
+    61820,     0,     1, 49152, 57344, 61440, 61696, 61824, 
+    61825, 61827, 61816, 61820,     0,     1, 49152, 57344, 
+    61440, 61696, 61824, 61825, 61827, 61816, 61820, 61822, 
+        0,     1, 49152, 57344, 61440, 61696,     0,     1, 
+    49152, 57344, 61440, 61952, 61824,     0,     1, 49152, 
+    57344, 61440, 61952, 61824,     0,     1, 49152, 57344, 
+    61440, 61952, 61824, 61826,     0,     1, 49152, 57344, 
+    61440, 61952, 61824,     0,     1, 49152, 57344, 61440, 
+    61952, 61824, 61828,     0,     1, 49152, 57344, 61440, 
+    61952, 61824, 61828,     0,     1, 49152, 57344, 61440, 
+    61952, 61824, 61832, 61830,     0,     1, 49152, 57344, 
+    61440, 61952, 61824,     0,     1, 49152, 57344, 61440, 
+    61952, 61824, 61832,     0,     1, 49152, 57344, 61440, 
+    61952, 61824, 61832,     0,     1, 49152, 57344, 61440, 
+    61952, 61824, 61832, 61834,     0,     1, 49152, 57344, 
+    61440, 61952, 61824, 61832,     0,     1, 49152, 57344, 
+    61440, 61952, 61824, 61840, 61836,     0,     1, 49152, 
+    57344, 61440, 61952, 61824, 61840, 61836,     0,     1, 
+    49152, 57344, 61440, 61952, 61824, 61840, 61841, 61838, 
+        0,     1, 49152, 57344, 61440, 61952, 61824,     0, 
+        1, 49152, 57344, 61440, 61952, 61824, 61840,     0, 
+        1, 49152, 57344, 61440, 61952, 61824, 61840,     0, 
+        1, 49152, 57344, 61440, 61952, 61824, 61840, 61842, 
+        0,     1, 49152, 57344, 61440, 61952, 61824, 61840, 
+        0,     1, 49152, 57344, 61440, 61952, 61824, 61840, 
+    61844,     0,     1, 49152, 57344, 61440, 61952, 61824, 
+    61840, 61844,     0,     1, 49152, 57344, 61440, 61952, 
+    61824, 61840, 61848, 61846,     0,     1, 49152, 57344, 
+    61440, 61952, 61824, 61840,     0,     1, 49152, 57344, 
+    61440, 61952, 61824, 61856, 61848,     0,     1, 49152, 
+    57344, 61440, 61952, 61824, 61856, 61848,     0,     1, 
+    49152, 57344, 61440, 61952, 61824, 61856, 61848, 61850, 
+        0,     1, 49152, 57344, 61440, 61952, 61824, 61856, 
+    61848,     0,     1, 49152, 57344, 61440, 61952, 61824, 
+    61856, 61857, 61852,     0,     1, 49152, 57344, 61440, 
+    61952, 61824, 61856, 61857, 61852,     0,     1, 49152, 
+    57344, 61440, 61952, 61824, 61856, 61857, 61852, 61854, 
+        0,     1, 49152, 57344, 61440, 61952, 61824,     0, 
+        1, 49152, 57344, 61440, 61952, 61824, 61856,     0, 
+        1, 49152, 57344, 61440, 61952, 61824, 61856,     0, 
+        1, 49152, 57344, 61440, 61952, 61824, 61856, 61858, 
+        0,     1, 49152, 57344, 61440, 61952, 61824, 61856, 
+        0,     1, 49152, 57344, 61440, 61952, 61824, 61856, 
+    61860,     0,     1, 49152, 57344, 61440, 61952, 61824, 
+    61856, 61860,     0,     1, 49152, 57344, 61440, 61952, 
+    61824, 61856, 61864, 61862,     0,     1, 49152, 57344, 
+    61440, 61952, 61824, 61856,     0,     1, 49152, 57344, 
+    61440, 61952, 61824, 61856, 61864,     0,     1, 49152, 
+    57344, 61440, 61952, 61824, 61856, 61864,     0,     1, 
+    49152, 57344, 61440, 61952, 61824, 61856, 61864, 61866, 
+        0,     1, 49152, 57344, 61440, 61952, 61824, 61856, 
+    61864,     0,     1, 49152, 57344, 61440, 61952, 61824, 
+    61856, 61872, 61868,     0,     1, 49152, 57344, 61440, 
+    61952, 61824, 61856, 61872, 61868,     0,     1, 49152, 
+    57344, 61440, 61952, 61824, 61856, 61872, 61873, 61870, 
+        0,     1, 49152, 57344, 61440, 61952, 61824, 61856, 
+        0,     1, 49152, 57344, 61440, 61952, 61824, 61888, 
+    61872,     0,     1, 49152, 57344, 61440, 61952, 61824, 
+    61888, 61872,     0,     1, 49152, 57344, 61440, 61952, 
+    61824, 61888, 61872, 61874,     0,     1, 49152, 57344, 
+    61440, 61952, 61824, 61888, 61872,     0,     1, 49152, 
+    57344, 61440, 61952, 61824, 61888, 61872, 61876,     0, 
+        1, 49152, 57344, 61440, 61952, 61824, 61888, 61872, 
+    61876,     0,     1, 49152, 57344, 61440, 61952, 61824, 
+    61888, 61872, 61880, 61878,     0,     1, 49152, 57344, 
+    61440, 61952, 61824, 61888, 61872,     0,     1, 49152, 
+    57344, 61440, 61952, 61824, 61888, 61889, 61880,     0, 
+        1, 49152, 57344, 61440, 61952, 61824, 61888, 61889, 
+    61880,     0,     1, 49152, 57344, 61440, 61952, 61824, 
+    61888, 61889, 61880, 61882,     0,     1, 49152, 57344, 
+    61440, 61952, 61824, 61888, 61889, 61880,     0,     1, 
+    49152, 57344, 61440, 61952, 61824, 61888, 61889, 61880, 
+    61884,     0,     1, 49152, 57344, 61440, 61952, 61824, 
+    61888, 61889, 61891, 61884,     0,     1, 49152, 57344, 
+    61440, 61952, 61824, 61888, 61889, 61891, 61884, 61886, 
+        0,     1, 49152, 57344, 61440, 61952, 61824,     0, 
+        1, 49152, 57344, 61440, 61952, 61953, 61888,     0, 
+        1, 49152, 57344, 61440, 61952, 61953, 61888,     0, 
+        1, 49152, 57344, 61440, 61952, 61953, 61888, 61890, 
+        0,     1, 49152, 57344, 61440, 61952, 61953, 61888, 
+        0,     1, 49152, 57344, 61440, 61952, 61953, 61888, 
+    61892,     0,     1, 49152, 57344, 61440, 61952, 61953, 
+    61888, 61892,     0,     1, 49152, 57344, 61440, 61952, 
+    61953, 61888, 61896, 61894,     0,     1, 49152, 57344, 
+    61440, 61952, 61953, 61888,     0,     1, 49152, 57344, 
+    61440, 61952, 61953, 61888, 61896,     0,     1, 49152, 
+    57344, 61440, 61952, 61953, 61888, 61896,     0,     1, 
+    49152, 57344, 61440, 61952, 61953, 61888, 61896, 61898, 
+        0,     1, 49152, 57344, 61440, 61952, 61953, 61888, 
+    61896,     0,     1, 49152, 57344, 61440, 61952, 61953, 
+    61888, 61904, 61900,     0,     1, 49152, 57344, 61440, 
+    61952, 61953, 61888, 61904, 61900,     0,     1, 49152, 
+    57344, 61440, 61952, 61953, 61888, 61904, 61905, 61902, 
+        0,     1, 49152, 57344, 61440, 61952, 61953, 61888, 
+        0,     1, 49152, 57344, 61440, 61952, 61953, 61888, 
+    61904,     0,     1, 49152, 57344, 61440, 61952, 61953, 
+    61888, 61904,     0,     1, 49152, 57344, 61440, 61952, 
+    61953, 61888, 61904, 61906,     0,     1, 49152, 57344, 
+    61440, 61952, 61953, 61888, 61904,     0,     1, 49152, 
+    57344, 61440, 61952, 61953, 61888, 61904, 61908,     0, 
+        1, 49152, 57344, 61440, 61952, 61953, 61888, 61904, 
+    61908,     0,     1, 49152, 57344, 61440, 61952, 61953, 
+    61888, 61904, 61912, 61910,     0,     1, 49152, 57344, 
+    61440, 61952, 61953, 61888, 61904,     0,     1, 49152, 
+    57344, 61440, 61952, 61953, 61888, 61920, 61912,     0, 
+        1, 49152, 57344, 61440, 61952, 61953, 61888, 61920, 
+    61912,     0,     1, 49152, 57344, 61440, 61952, 61953, 
+    61888, 61920, 61912, 61914,     0,     1, 49152, 57344, 
+    61440, 61952, 61953, 61888, 61920, 61912,     0,     1, 
+    49152, 57344, 61440, 61952, 61953, 61888, 61920, 61921, 
+    61916,     0,     1, 49152, 57344, 61440, 61952, 61953, 
+    61888, 61920, 61921, 61916,     0,     1, 49152, 57344, 
+    61440, 61952, 61953, 61888, 61920, 61921, 61916, 61918, 
+        0,     1, 49152, 57344, 61440, 61952, 61953, 61888, 
+        0,     1, 49152, 57344, 61440, 61952, 61953, 61888, 
+    61920,     0,     1, 49152, 57344, 61440, 61952, 61953, 
+    61955, 61920,     0,     1, 49152, 57344, 61440, 61952, 
+    61953, 61955, 61920, 61922,     0,     1, 49152, 57344, 
+    61440, 61952, 61953, 61955, 61920,     0,     1, 49152, 
+    57344, 61440, 61952, 61953, 61955, 61920, 61924,     0, 
+        1, 49152, 57344, 61440, 61952, 61953, 61955, 61920, 
+    61924,     0,     1, 49152, 57344, 61440, 61952, 61953, 
+    61955, 61920, 61928, 61926,     0,     1, 49152, 57344, 
+    61440, 61952, 61953, 61955, 61920,     0,     1, 49152, 
+    57344, 61440, 61952, 61953, 61955, 61920, 61928,     0, 
+        1, 49152, 57344, 61440, 61952, 61953, 61955, 61920, 
+    61928,     0,     1, 49152, 57344, 61440, 61952, 61953, 
+    61955, 61920, 61928, 61930,     0,     1, 49152, 57344, 
+    61440, 61952, 61953, 61955, 61920, 61928,     0,     1, 
+    49152, 57344, 61440, 61952, 61953, 61955, 61920, 61936, 
+    61932,     0,     1, 49152, 57344, 61440, 61952, 61953, 
+    61955, 61920, 61936, 61932,     0,     1, 49152, 57344, 
+    61440, 61952, 61953, 61955, 61920, 61936, 61937, 61934, 
+        0,     1, 49152, 57344, 61440, 61952, 61953, 61955, 
+    61920,     0,     1, 49152, 57344, 61440, 61952, 61953, 
+    61955, 61920, 61936,     0,     1, 49152, 57344, 61440, 
+    61952, 61953, 61955, 61920, 61936,     0,     1, 49152, 
+    57344, 61440, 61952, 61953, 61955, 61920, 61936, 61938, 
+        0,     1, 49152, 57344, 61440, 61952, 61953, 61955, 
+    61959, 61936,     0,     1, 49152, 57344, 61440, 61952, 
+    61953, 61955, 61959, 61936, 61940,     0,     1, 49152, 
+    57344, 61440, 61952, 61953, 61955, 61959, 61936, 61940, 
+        0,     1, 49152, 57344, 61440, 61952, 61953, 61955, 
+    61959, 61936, 61944, 61942,     0,     1, 49152, 57344, 
+    61440, 61952, 61953, 61955, 61959, 61936,     0,     1, 
+    49152, 57344, 61440, 61952, 61953, 61955, 61959, 61936, 
+    61944,     0,     1, 49152, 57344, 61440, 61952, 61953, 
+    61955, 61959, 61936, 61944,     0,     1, 49152, 57344, 
+    61440, 61952, 61953, 61955, 61959, 61936, 61944, 61946, 
+        0,     1, 49152, 57344, 61440, 61952, 61953, 61955, 
+    61959, 61936, 61944,     0,     1, 49152, 57344, 61440, 
+    61952, 61953, 61955, 61959, 61936, 61944, 61948,     0, 
+        1, 49152, 57344, 61440, 61952, 61953, 61955, 61959, 
+    61936, 61944, 61948,     0,     1, 49152, 57344, 61440, 
+    61952, 61953, 61955, 61959, 61936, 61944, 61948, 61950, 
+        0,     1, 49152, 57344, 61440,     0,     1, 49152, 
+    57344, 61440, 61952,     0,     1, 49152, 57344, 61440, 
+    61952,     0,     1, 49152, 57344, 61440, 61952, 61954, 
+        0,     1, 49152, 57344, 61440, 61952,     0,     1, 
+    49152, 57344, 61440, 61952, 61956,     0,     1, 49152, 
+    57344, 61440, 61952, 61956,     0,     1, 49152, 57344, 
+    61440, 61952, 61960, 61958,     0,     1, 49152, 57344, 
+    61440, 61952,     0,     1, 49152, 57344, 61440, 61952, 
+    61960,     0,     1, 49152, 57344, 61440, 61952, 61960, 
+        0,     1, 49152, 57344, 61440, 61952, 61960, 61962, 
+        0,     1, 49152, 57344, 61440, 61952, 61960,     0, 
+        1, 49152, 57344, 61440, 61952, 61968, 61964,     0, 
+        1, 49152, 57344, 61440, 61952, 61968, 61964,     0, 
+        1, 49152, 57344, 61440, 61952, 61968, 61969, 61966, 
+        0,     1, 49152, 57344, 61440, 61952,     0,     1, 
+    49152, 57344, 61440, 61952, 61968,     0,     1, 49152, 
+    57344, 61440, 61952, 61968,     0,     1, 49152, 57344, 
+    61440, 61952, 61968, 61970,     0,     1, 49152, 57344, 
+    61440, 61952, 61968,     0,     1, 49152, 57344, 61440, 
+    61952, 61968, 61972,     0,     1, 49152, 57344, 61440, 
+    61952, 61968, 61972,     0,     1, 49152, 57344, 61440, 
+    61952, 61968, 61976, 61974,     0,     1, 49152, 57344, 
+    61440, 61952, 61968,     0,     1, 49152, 57344, 61440, 
+    61952, 61984, 61976,     0,     1, 49152, 57344, 61440, 
+    61952, 61984, 61976,     0,     1, 49152, 57344, 61440, 
+    61952, 61984, 61976, 61978,     0,     1, 49152, 57344, 
+    61440, 61952, 61984, 61976,     0,     1, 49152, 57344, 
+    61440, 61952, 61984, 61985, 61980,     0,     1, 49152, 
+    57344, 61440, 61952, 61984, 61985, 61980,     0,     1, 
+    49152, 57344, 61440, 61952, 61984, 61985, 61980, 61982, 
+        0,     1, 49152, 57344, 61440, 61952,     0,     1, 
+    49152, 57344, 61440, 61952, 61984,     0,     1, 49152, 
+    57344, 61440, 61952, 61984,     0,     1, 49152, 57344, 
+    61440, 61952, 61984, 61986,     0,     1, 49152, 57344, 
+    61440, 61952, 61984,     0,     1, 49152, 57344, 61440, 
+    61952, 61984, 61988,     0,     1, 49152, 57344, 61440, 
+    61952, 61984, 61988,     0,     1, 49152, 57344, 61440, 
+    61952, 61984, 61992, 61990,     0,     1, 49152, 57344, 
+    61440, 61952, 61984,     0,     1, 49152, 57344, 61440, 
+    61952, 61984, 61992,     0,     1, 49152, 57344, 61440, 
+    61952, 61984, 61992,     0,     1, 49152, 57344, 61440, 
+    61952, 61984, 61992, 61994,     0,     1, 49152, 57344, 
+    61440, 61952, 61984, 61992,     0,     1, 49152, 57344, 
+    61440, 61952, 61984, 62000, 61996,     0,     1, 49152, 
+    57344, 61440, 61952, 61984, 62000, 61996,     0,     1, 
+    49152, 57344, 61440, 61952, 61984, 62000, 62001, 61998, 
+        0,     1, 49152, 57344, 61440, 61952, 61984,     0, 
+        1, 49152, 57344, 61440, 61952, 62016, 62000,     0, 
+        1, 49152, 57344, 61440, 61952, 62016, 62000,     0, 
+        1, 49152, 57344, 61440, 61952, 62016, 62000, 62002, 
+        0,     1, 49152, 57344, 61440, 61952, 62016, 62000, 
+        0,     1, 49152, 57344, 61440, 61952, 62016, 62000, 
+    62004,     0,     1, 49152, 57344, 61440, 61952, 62016, 
+    62000, 62004,     0,     1, 49152, 57344, 61440, 61952, 
+    62016, 62000, 62008, 62006,     0,     1, 49152, 57344, 
+    61440, 61952, 62016, 62000,     0,     1, 49152, 57344, 
+    61440, 61952, 62016, 62017, 62008,     0,     1, 49152, 
+    57344, 61440, 61952, 62016, 62017, 62008,     0,     1, 
+    49152, 57344, 61440, 61952, 62016, 62017, 62008, 62010, 
+        0,     1, 49152, 57344, 61440, 61952, 62016, 62017, 
+    62008,     0,     1, 49152, 57344, 61440, 61952, 62016, 
+    62017, 62008, 62012,     0,     1, 49152, 57344, 61440, 
+    61952, 62016, 62017, 62019, 62012,     0,     1, 49152, 
+    57344, 61440, 61952, 62016, 62017, 62019, 62012, 62014, 
+        0,     1, 49152, 57344, 61440, 61952,     0,     1, 
+    49152, 57344, 61440, 61952, 62016,     0,     1, 49152, 
+    57344, 61440, 61952, 62016,     0,     1, 49152, 57344, 
+    61440, 61952, 62016, 62018,     0,     1, 49152, 57344, 
+    61440, 61952, 62016,     0,     1, 49152, 57344, 61440, 
+    61952, 62016, 62020,     0,     1, 49152, 57344, 61440, 
+    61952, 62016, 62020,     0,     1, 49152, 57344, 61440, 
+    61952, 62016, 62024, 62022,     0,     1, 49152, 57344, 
+    61440, 61952, 62016,     0,     1, 49152, 57344, 61440, 
+    61952, 62016, 62024,     0,     1, 49152, 57344, 61440, 
+    61952, 62016, 62024,     0,     1, 49152, 57344, 61440, 
+    61952, 62016, 62024, 62026,     0,     1, 49152, 57344, 
+    61440, 61952, 62016, 62024,     0,     1, 49152, 57344, 
+    61440, 61952, 62016, 62032, 62028,     0,     1, 49152, 
+    57344, 61440, 61952, 62016, 62032, 62028,     0,     1, 
+    49152, 57344, 61440, 61952, 62016, 62032, 62033, 62030, 
+        0,     1, 49152, 57344, 61440, 61952, 62016,     0, 
+        1, 49152, 57344, 61440, 61952, 62016, 62032,     0, 
+        1, 49152, 57344, 61440, 61952, 62016, 62032,     0, 
+        1, 49152, 57344, 61440, 61952, 62016, 62032, 62034, 
+        0,     1, 49152, 57344, 61440, 61952, 62016, 62032, 
+        0,     1, 49152, 57344, 61440, 61952, 62016, 62032, 
+    62036,     0,     1, 49152, 57344, 61440, 61952, 62016, 
+    62032, 62036,     0,     1, 49152, 57344, 61440, 61952, 
+    62016, 62032, 62040, 62038,     0,     1, 49152, 57344, 
+    61440, 61952, 62016, 62032,     0,     1, 49152, 57344, 
+    61440, 61952, 62016, 62048, 62040,     0,     1, 49152, 
+    57344, 61440, 61952, 62016, 62048, 62040,     0,     1, 
+    49152, 57344, 61440, 61952, 62016, 62048, 62040, 62042, 
+        0,     1, 49152, 57344, 61440, 61952, 62016, 62048, 
+    62040,     0,     1, 49152, 57344, 61440, 61952, 62016, 
+    62048, 62049, 62044,     0,     1, 49152, 57344, 61440, 
+    61952, 62016, 62048, 62049, 62044,     0,     1, 49152, 
+    57344, 61440, 61952, 62016, 62048, 62049, 62044, 62046, 
+        0,     1, 49152, 57344, 61440, 61952, 62016,     0, 
+        1, 49152, 57344, 61440, 61952, 62080, 62048,     0, 
+        1, 49152, 57344, 61440, 61952, 62080, 62048,     0, 
+        1, 49152, 57344, 61440, 61952, 62080, 62048, 62050, 
+        0,     1, 49152, 57344, 61440, 61952, 62080, 62048, 
+        0,     1, 49152, 57344, 61440, 61952, 62080, 62048, 
+    62052,     0,     1, 49152, 57344, 61440, 61952, 62080, 
+    62048, 62052,     0,     1, 49152, 57344, 61440, 61952, 
+    62080, 62048, 62056, 62054,     0,     1, 49152, 57344, 
+    61440, 61952, 62080, 62048,     0,     1, 49152, 57344, 
+    61440, 61952, 62080, 62048, 62056,     0,     1, 49152, 
+    57344, 61440, 61952, 62080, 62048, 62056,     0,     1, 
+    49152, 57344, 61440, 61952, 62080, 62048, 62056, 62058, 
+        0,     1, 49152, 57344, 61440, 61952, 62080, 62048, 
+    62056,     0,     1, 49152, 57344, 61440, 61952, 62080, 
+    62048, 62064, 62060,     0,     1, 49152, 57344, 61440, 
+    61952, 62080, 62048, 62064, 62060,     0,     1, 49152, 
+    57344, 61440, 61952, 62080, 62048, 62064, 62065, 62062, 
+        0,     1, 49152, 57344, 61440, 61952, 62080, 62048, 
+        0,     1, 49152, 57344, 61440, 61952, 62080, 62081, 
+    62064,     0,     1, 49152, 57344, 61440, 61952, 62080, 
+    62081, 62064,     0,     1, 49152, 57344, 61440, 61952, 
+    62080, 62081, 62064, 62066,     0,     1, 49152, 57344, 
+    61440, 61952, 62080, 62081, 62064,     0,     1, 49152, 
+    57344, 61440, 61952, 62080, 62081, 62064, 62068,     0, 
+        1, 49152, 57344, 61440, 61952, 62080, 62081, 62064, 
+    62068,     0,     1, 49152, 57344, 61440, 61952, 62080, 
+    62081, 62064, 62072, 62070,     0,     1, 49152, 57344, 
+    61440, 61952, 62080, 62081, 62064,     0,     1, 49152, 
+    57344, 61440, 61952, 62080, 62081, 62064, 62072,     0, 
+        1, 49152, 57344, 61440, 61952, 62080, 62081, 62083, 
+    62072,     0,     1, 49152, 57344, 61440, 61952, 62080, 
+    62081, 62083, 62072, 62074,     0,     1, 49152, 57344, 
+    61440, 61952, 62080, 62081, 62083, 62072,     0,     1, 
+    49152, 57344, 61440, 61952, 62080, 62081, 62083, 62072, 
+    62076,     0,     1, 49152, 57344, 61440, 61952, 62080, 
+    62081, 62083, 62072, 62076,     0,     1, 49152, 57344, 
+    61440, 61952, 62080, 62081, 62083, 62072, 62076, 62078, 
+        0,     1, 49152, 57344, 61440, 61952,     0,     1, 
+    49152, 57344, 61440, 61952, 62080,     0,     1, 49152, 
+    57344, 61440, 61952, 62080,     0,     1, 49152, 57344, 
+    61440, 61952, 62080, 62082,     0,     1, 49152, 57344, 
+    61440, 61952, 62080,     0,     1, 49152, 57344, 61440, 
+    61952, 62080, 62084,     0,     1, 49152, 57344, 61440, 
+    61952, 62080, 62084,     0,     1, 49152, 57344, 61440, 
+    61952, 62080, 62088, 62086,     0,     1, 49152, 57344, 
+    61440, 61952, 62080,     0,     1, 49152, 57344, 61440, 
+    61952, 62080, 62088,     0,     1, 49152, 57344, 61440, 
+    61952, 62080, 62088,     0,     1, 49152, 57344, 61440, 
+    61952, 62080, 62088, 62090,     0,     1, 49152, 57344, 
+    61440, 61952, 62080, 62088,     0,     1, 49152, 57344, 
+    61440, 61952, 62080, 62096, 62092,     0,     1, 49152, 
+    57344, 61440, 61952, 62080, 62096, 62092,     0,     1, 
+    49152, 57344, 61440, 61952, 62080, 62096, 62097, 62094, 
+        0,     1, 49152, 57344, 61440, 61952, 62080,     0, 
+        1, 49152, 57344, 61440, 61952, 62080, 62096,     0, 
+        1, 49152, 57344, 61440, 61952, 62080, 62096,     0, 
+        1, 49152, 57344, 61440, 61952, 62080, 62096, 62098, 
+        0,     1, 49152, 57344, 61440, 61952, 62080, 62096, 
+        0,     1, 49152, 57344, 61440, 61952, 62080, 62096, 
+    62100,     0,     1, 49152, 57344, 61440, 61952, 62080, 
+    62096, 62100,     0,     1, 49152, 57344, 61440, 61952, 
+    62080, 62096, 62104, 62102,     0,     1, 49152, 57344, 
+    61440, 61952, 62080, 62096,     0,     1, 49152, 57344, 
+    61440, 61952, 62080, 62112, 62104,     0,     1, 49152, 
+    57344, 61440, 61952, 62080, 62112, 62104,     0,     1, 
+    49152, 57344, 61440, 61952, 62080, 62112, 62104, 62106, 
+        0,     1, 49152, 57344, 61440, 61952, 62080, 62112, 
+    62104,     0,     1, 49152, 57344, 61440, 61952, 62080, 
+    62112, 62113, 62108,     0,     1, 49152, 57344, 61440, 
+    61952, 62080, 62112, 62113, 62108,     0,     1, 49152, 
+    57344, 61440, 61952, 62080, 62112, 62113, 62108, 62110, 
+        0,     1, 49152, 57344, 61440, 61952, 62080,     0, 
+        1, 49152, 57344, 61440, 61952, 62080, 62112,     0, 
+        1, 49152, 57344, 61440, 61952, 62080, 62112,     0, 
+        1, 49152, 57344, 61440, 61952, 62080, 62112, 62114, 
+        0,     1, 49152, 57344, 61440, 61952, 62080, 62112, 
+        0,     1, 49152, 57344, 61440, 61952, 62080, 62112, 
+    62116,     0,     1, 49152, 57344, 61440, 61952, 62080, 
+    62112, 62116,     0,     1, 49152, 57344, 61440, 61952, 
+    62080, 62112, 62120, 62118,     0,     1, 49152, 57344, 
+    61440, 61952, 62080, 62112,     0,     1, 49152, 57344, 
+    61440, 61952, 62080, 62112, 62120,     0,     1, 49152, 
+    57344, 61440, 61952, 62080, 62112, 62120,     0,     1, 
+    49152, 57344, 61440, 61952, 62080, 62112, 62120, 62122, 
+        0,     1, 49152, 57344, 61440, 61952, 62080, 62112, 
+    62120,     0,     1, 49152, 57344, 61440, 61952, 62080, 
+    62112, 62128, 62124,     0,     1, 49152, 57344, 61440, 
+    61952, 62080, 62112, 62128, 62124,     0,     1, 49152, 
+    57344, 61440, 61952, 62080, 62112, 62128, 62129, 62126, 
+        0,     1, 49152, 57344, 61440, 61952, 62080, 62112, 
+        0,     1, 49152, 57344, 61440, 61952, 62080, 62144, 
+    62128,     0,     1, 49152, 57344, 61440, 61952, 62080, 
+    62144, 62128,     0,     1, 49152, 57344, 61440, 61952, 
+    62080, 62144, 62128, 62130,     0,     1, 49152, 57344, 
+    61440, 61952, 62080, 62144, 62128,     0,     1, 49152, 
+    57344, 61440, 61952, 62080, 62144, 62128, 62132,     0, 
+        1, 49152, 57344, 61440, 61952, 62080, 62144, 62128, 
+    62132,     0,     1, 49152, 57344, 61440, 61952, 62080, 
+    62144, 62128, 62136, 62134,     0,     1, 49152, 57344, 
+    61440, 61952, 62080, 62144, 62128,     0,     1, 49152, 
+    57344, 61440, 61952, 62080, 62144, 62145, 62136,     0, 
+        1, 49152, 57344, 61440, 61952, 62080, 62144, 62145, 
+    62136,     0,     1, 49152, 57344, 61440, 61952, 62080, 
+    62144, 62145, 62136, 62138,     0,     1, 49152, 57344, 
+    61440, 61952, 62080, 62144, 62145, 62136,     0,     1, 
+    49152, 57344, 61440, 61952, 62080, 62144, 62145, 62136, 
+    62140,     0,     1, 49152, 57344, 61440, 61952, 62080, 
+    62144, 62145, 62147, 62140,     0,     1, 49152, 57344, 
+    61440, 61952, 62080, 62144, 62145, 62147, 62140, 62142, 
+        0,     1, 49152, 57344, 61440, 61952, 62080,     0, 
+        1, 49152, 57344, 61440, 61952, 62208, 62144,     0, 
+        1, 49152, 57344, 61440, 61952, 62208, 62144,     0, 
+        1, 49152, 57344, 61440, 61952, 62208, 62144, 62146, 
+        0,     1, 49152, 57344, 61440, 61952, 62208, 62144, 
+        0,     1, 49152, 57344, 61440, 61952, 62208, 62144, 
+    62148,     0,     1, 49152, 57344, 61440, 61952, 62208, 
+    62144, 62148,     0,     1, 49152, 57344, 61440, 61952, 
+    62208, 62144, 62152, 62150,     0,     1, 49152, 57344, 
+    61440, 61952, 62208, 62144,     0,     1, 49152, 57344, 
+    61440, 61952, 62208, 62144, 62152,     0,     1, 49152, 
+    57344, 61440, 61952, 62208, 62144, 62152,     0,     1, 
+    49152, 57344, 61440, 61952, 62208, 62144, 62152, 62154, 
+        0,     1, 49152, 57344, 61440, 61952, 62208, 62144, 
+    62152,     0,     1, 49152, 57344, 61440, 61952, 62208, 
+    62144, 62160, 62156,     0,     1, 49152, 57344, 61440, 
+    61952, 62208, 62144, 62160, 62156,     0,     1, 49152, 
+    57344, 61440, 61952, 62208, 62144, 62160, 62161, 62158, 
+        0,     1, 49152, 57344, 61440, 61952, 62208, 62144, 
+        0,     1, 49152, 57344, 61440, 61952, 62208, 62144, 
+    62160,     0,     1, 49152, 57344, 61440, 61952, 62208, 
+    62144, 62160,     0,     1, 49152, 57344, 61440, 61952, 
+    62208, 62144, 62160, 62162,     0,     1, 49152, 57344, 
+    61440, 61952, 62208, 62144, 62160,     0,     1, 49152, 
+    57344, 61440, 61952, 62208, 62144, 62160, 62164,     0, 
+        1, 49152, 57344, 61440, 61952, 62208, 62144, 62160, 
+    62164,     0,     1, 49152, 57344, 61440, 61952, 62208, 
+    62144, 62160, 62168, 62166,     0,     1, 49152, 57344, 
+    61440, 61952, 62208, 62144, 62160,     0,     1, 49152, 
+    57344, 61440, 61952, 62208, 62144, 62176, 62168,     0, 
+        1, 49152, 57344, 61440, 61952, 62208, 62144, 62176, 
+    62168,     0,     1, 49152, 57344, 61440, 61952, 62208, 
+    62144, 62176, 62168, 62170,     0,     1, 49152, 57344, 
+    61440, 61952, 62208, 62144, 62176, 62168,     0,     1, 
+    49152, 57344, 61440, 61952, 62208, 62144, 62176, 62177, 
+    62172,     0,     1, 49152, 57344, 61440, 61952, 62208, 
+    62144, 62176, 62177, 62172,     0,     1, 49152, 57344, 
+    61440, 61952, 62208, 62144, 62176, 62177, 62172, 62174, 
+        0,     1, 49152, 57344, 61440, 61952, 62208, 62144, 
+        0,     1, 49152, 57344, 61440, 61952, 62208, 62209, 
+    62176,     0,     1, 49152, 57344, 61440, 61952, 62208, 
+    62209, 62176,     0,     1, 49152, 57344, 61440, 61952, 
+    62208, 62209, 62176, 62178,     0,     1, 49152, 57344, 
+    61440, 61952, 62208, 62209, 62176,     0,     1, 49152, 
+    57344, 61440, 61952, 62208, 62209, 62176, 62180,     0, 
+        1, 49152, 57344, 61440, 61952, 62208, 62209, 62176, 
+    62180,     0,     1, 49152, 57344, 61440, 61952, 62208, 
+    62209, 62176, 62184, 62182,     0,     1, 49152, 57344, 
+    61440, 61952, 62208, 62209, 62176,     0,     1, 49152, 
+    57344, 61440, 61952, 62208, 62209, 62176, 62184,     0, 
+        1, 49152, 57344, 61440, 61952, 62208, 62209, 62176, 
+    62184,     0,     1, 49152, 57344, 61440, 61952, 62208, 
+    62209, 62176, 62184, 62186,     0,     1, 49152, 57344, 
+    61440, 61952, 62208, 62209, 62176, 62184,     0,     1, 
+    49152, 57344, 61440, 61952, 62208, 62209, 62176, 62192, 
+    62188,     0,     1, 49152, 57344, 61440, 61952, 62208, 
+    62209, 62176, 62192, 62188,     0,     1, 49152, 57344, 
+    61440, 61952, 62208, 62209, 62176, 62192, 62193, 62190, 
+        0,     1, 49152, 57344, 61440, 61952, 62208, 62209, 
+    62176,     0,     1, 49152, 57344, 61440, 61952, 62208, 
+    62209, 62176, 62192,     0,     1, 49152, 57344, 61440, 
+    61952, 62208, 62209, 62211, 62192,     0,     1, 49152, 
+    57344, 61440, 61952, 62208, 62209, 62211, 62192, 62194, 
+        0,     1, 49152, 57344, 61440, 61952, 62208, 62209, 
+    62211, 62192,     0,     1, 49152, 57344, 61440, 61952, 
+    62208, 62209, 62211, 62192, 62196,     0,     1, 49152, 
+    57344, 61440, 61952, 62208, 62209, 62211, 62192, 62196, 
+        0,     1, 49152, 57344, 61440, 61952, 62208, 62209, 
+    62211, 62192, 62200, 62198,     0,     1, 49152, 57344, 
+    61440, 61952, 62208, 62209, 62211, 62192,     0,     1, 
+    49152, 57344, 61440, 61952, 62208, 62209, 62211, 62192, 
+    62200,     0,     1, 49152, 57344, 61440, 61952, 62208, 
+    62209, 62211, 62192, 62200,     0,     1, 49152, 57344, 
+    61440, 61952, 62208, 62209, 62211, 62192, 62200, 62202, 
+        0,     1, 49152, 57344, 61440, 61952, 62208, 62209, 
+    62211, 62215, 62200,     0,     1, 49152, 57344, 61440, 
+    61952, 62208, 62209, 62211, 62215, 62200, 62204,     0, 
+        1, 49152, 57344, 61440, 61952, 62208, 62209, 62211, 
+    62215, 62200, 62204,     0,     1, 49152, 57344, 61440, 
+    61952, 62208, 62209, 62211, 62215, 62200, 62204, 62206, 
+        0,     1, 49152, 57344, 61440, 61952,     0,     1, 
+    49152, 57344, 61440, 62464, 62208,     0,     1, 49152, 
+    57344, 61440, 62464, 62208,     0,     1, 49152, 57344, 
+    61440, 62464, 62208, 62210,     0,     1, 49152, 57344, 
+    61440, 62464, 62208,     0,     1, 49152, 57344, 61440, 
+    62464, 62208, 62212,     0,     1, 49152, 57344, 61440, 
+    62464, 62208, 62212,     0,     1, 49152, 57344, 61440, 
+    62464, 62208, 62216, 62214,     0,     1, 49152, 57344, 
+    61440, 62464, 62208,     0,     1, 49152, 57344, 61440, 
+    62464, 62208, 62216,     0,     1, 49152, 57344, 61440, 
+    62464, 62208, 62216,     0,     1, 49152, 57344, 61440, 
+    62464, 62208, 62216, 62218,     0,     1, 49152, 57344, 
+    61440, 62464, 62208, 62216,     0,     1, 49152, 57344, 
+    61440, 62464, 62208, 62224, 62220,     0,     1, 49152, 
+    57344, 61440, 62464, 62208, 62224, 62220,     0,     1, 
+    49152, 57344, 61440, 62464, 62208, 62224, 62225, 62222, 
+        0,     1, 49152, 57344, 61440, 62464, 62208,     0, 
+        1, 49152, 57344, 61440, 62464, 62208, 62224,     0, 
+        1, 49152, 57344, 61440, 62464, 62208, 62224,     0, 
+        1, 49152, 57344, 61440, 62464, 62208, 62224, 62226, 
+        0,     1, 49152, 57344, 61440, 62464, 62208, 62224, 
+        0,     1, 49152, 57344, 61440, 62464, 62208, 62224, 
+    62228,     0,     1, 49152, 57344, 61440, 62464, 62208, 
+    62224, 62228,     0,     1, 49152, 57344, 61440, 62464, 
+    62208, 62224, 62232, 62230,     0,     1, 49152, 57344, 
+    61440, 62464, 62208, 62224,     0,     1, 49152, 57344, 
+    61440, 62464, 62208, 62240, 62232,     0,     1, 49152, 
+    57344, 61440, 62464, 62208, 62240, 62232,     0,     1, 
+    49152, 57344, 61440, 62464, 62208, 62240, 62232, 62234, 
+        0,     1, 49152, 57344, 61440, 62464, 62208, 62240, 
+    62232,     0,     1, 49152, 57344, 61440, 62464, 62208, 
+    62240, 62241, 62236,     0,     1, 49152, 57344, 61440, 
+    62464, 62208, 62240, 62241, 62236,     0,     1, 49152, 
+    57344, 61440, 62464, 62208, 62240, 62241, 62236, 62238, 
+        0,     1, 49152, 57344, 61440, 62464, 62208,     0, 
+        1, 49152, 57344, 61440, 62464, 62208, 62240,     0, 
+        1, 49152, 57344, 61440, 62464, 62208, 62240,     0, 
+        1, 49152, 57344, 61440, 62464, 62208, 62240, 62242, 
+        0,     1, 49152, 57344, 61440, 62464, 62208, 62240, 
+        0,     1, 49152, 57344, 61440, 62464, 62208, 62240, 
+    62244,     0,     1, 49152, 57344, 61440, 62464, 62208, 
+    62240, 62244,     0,     1, 49152, 57344, 61440, 62464, 
+    62208, 62240, 62248, 62246,     0,     1, 49152, 57344, 
+    61440, 62464, 62208, 62240,     0,     1, 49152, 57344, 
+    61440, 62464, 62208, 62240, 62248,     0,     1, 49152, 
+    57344, 61440, 62464, 62208, 62240, 62248,     0,     1, 
+    49152, 57344, 61440, 62464, 62208, 62240, 62248, 62250, 
+        0,     1, 49152, 57344, 61440, 62464, 62208, 62240, 
+    62248,     0,     1, 49152, 57344, 61440, 62464, 62208, 
+    62240, 62256, 62252,     0,     1, 49152, 57344, 61440, 
+    62464, 62208, 62240, 62256, 62252,     0,     1, 49152, 
+    57344, 61440, 62464, 62208, 62240, 62256, 62257, 62254, 
+        0,     1, 49152, 57344, 61440, 62464, 62208, 62240, 
+        0,     1, 49152, 57344, 61440, 62464, 62208, 62272, 
+    62256,     0,     1, 49152, 57344, 61440, 62464, 62208, 
+    62272, 62256,     0,     1, 49152, 57344, 61440, 62464, 
+    62208, 62272, 62256, 62258,     0,     1, 49152, 57344, 
+    61440, 62464, 62208, 62272, 62256,     0,     1, 49152, 
+    57344, 61440, 62464, 62208, 62272, 62256, 62260,     0, 
+        1, 49152, 57344, 61440, 62464, 62208, 62272, 62256, 
+    62260,     0,     1, 49152, 57344, 61440, 62464, 62208, 
+    62272, 62256, 62264, 62262,     0,     1, 49152, 57344, 
+    61440, 62464, 62208, 62272, 62256,     0,     1, 49152, 
+    57344, 61440, 62464, 62208, 62272, 62273, 62264,     0, 
+        1, 49152, 57344, 61440, 62464, 62208, 62272, 62273, 
+    62264,     0,     1, 49152, 57344, 61440, 62464, 62208, 
+    62272, 62273, 62264, 62266,     0,     1, 49152, 57344, 
+    61440, 62464, 62208, 62272, 62273, 62264,     0,     1, 
+    49152, 57344, 61440, 62464, 62208, 62272, 62273, 62264, 
+    62268,     0,     1, 49152, 57344, 61440, 62464, 62208, 
+    62272, 62273, 62275, 62268,     0,     1, 49152, 57344, 
+    61440, 62464, 62208, 62272, 62273, 62275, 62268, 62270, 
+        0,     1, 49152, 57344, 61440, 62464, 62208,     0, 
+        1, 49152, 57344, 61440, 62464, 62208, 62272,     0, 
+        1, 49152, 57344, 61440, 62464, 62208, 62272,     0, 
+        1, 49152, 57344, 61440, 62464, 62208, 62272, 62274, 
+        0,     1, 49152, 57344, 61440, 62464, 62208, 62272, 
+        0,     1, 49152, 57344, 61440, 62464, 62208, 62272, 
+    62276,     0,     1, 49152, 57344, 61440, 62464, 62208, 
+    62272, 62276,     0,     1, 49152, 57344, 61440, 62464, 
+    62208, 62272, 62280, 62278,     0,     1, 49152, 57344, 
+    61440, 62464, 62208, 62272,     0,     1, 49152, 57344, 
+    61440, 62464, 62208, 62272, 62280,     0,     1, 49152, 
+    57344, 61440, 62464, 62208, 62272, 62280,     0,     1, 
+    49152, 57344, 61440, 62464, 62208, 62272, 62280, 62282, 
+        0,     1, 49152, 57344, 61440, 62464, 62208, 62272, 
+    62280,     0,     1, 49152, 57344, 61440, 62464, 62208, 
+    62272, 62288, 62284,     0,     1, 49152, 57344, 61440, 
+    62464, 62208, 62272, 62288, 62284,     0,     1, 49152, 
+    57344, 61440, 62464, 62208, 62272, 62288, 62289, 62286, 
+        0,     1, 49152, 57344, 61440, 62464, 62208, 62272, 
+        0,     1, 49152, 57344, 61440, 62464, 62208, 62272, 
+    62288,     0,     1, 49152, 57344, 61440, 62464, 62208, 
+    62272, 62288,     0,     1, 49152, 57344, 61440, 62464, 
+    62208, 62272, 62288, 62290,     0,     1, 49152, 57344, 
+    61440, 62464, 62208, 62272, 62288,     0,     1, 49152, 
+    57344, 61440, 62464, 62208, 62272, 62288, 62292,     0, 
+        1, 49152, 57344, 61440, 62464, 62208, 62272, 62288, 
+    62292,     0,     1, 49152, 57344, 61440, 62464, 62208, 
+    62272, 62288, 62296, 62294,     0,     1, 49152, 57344, 
+    61440, 62464, 62208, 62272, 62288,     0,     1, 49152, 
+    57344, 61440, 62464, 62208, 62272, 62304, 62296,     0, 
+        1, 49152, 57344, 61440, 62464, 62208, 62272, 62304, 
+    62296,     0,     1, 49152, 57344, 61440, 62464, 62208, 
+    62272, 62304, 62296, 62298,     0,     1, 49152, 57344, 
+    61440, 62464, 62208, 62272, 62304, 62296,     0,     1, 
+    49152, 57344, 61440, 62464, 62208, 62272, 62304, 62305, 
+    62300,     0,     1, 49152, 57344, 61440, 62464, 62208, 
+    62272, 62304, 62305, 62300,     0,     1, 49152, 57344, 
+    61440, 62464, 62208, 62272, 62304, 62305, 62300, 62302, 
+        0,     1, 49152, 57344, 61440, 62464, 62208, 62272, 
+        0,     1, 49152, 57344, 61440, 62464, 62208, 62336, 
+    62304,     0,     1, 49152, 57344, 61440, 62464, 62208, 
+    62336, 62304,     0,     1, 49152, 57344, 61440, 62464, 
+    62208, 62336, 62304, 62306,     0,     1, 49152, 57344, 
+    61440, 62464, 62208, 62336, 62304,     0,     1, 49152, 
+    57344, 61440, 62464, 62208, 62336, 62304, 62308,     0, 
+        1, 49152, 57344, 61440, 62464, 62208, 62336, 62304, 
+    62308,     0,     1, 49152, 57344, 61440, 62464, 62208, 
+    62336, 62304, 62312, 62310,     0,     1, 49152, 57344, 
+    61440, 62464, 62208, 62336, 62304,     0,     1, 49152, 
+    57344, 61440, 62464, 62208, 62336, 62304, 62312,     0, 
+        1, 49152, 57344, 61440, 62464, 62208, 62336, 62304, 
+    62312,     0,     1, 49152, 57344, 61440, 62464, 62208, 
+    62336, 62304, 62312, 62314,     0,     1, 49152, 57344, 
+    61440, 62464, 62208, 62336, 62304, 62312,     0,     1, 
+    49152, 57344, 61440, 62464, 62208, 62336, 62304, 62320, 
+    62316,     0,     1, 49152, 57344, 61440, 62464, 62208, 
+    62336, 62304, 62320, 62316,     0,     1, 49152, 57344, 
+    61440, 62464, 62208, 62336, 62304, 62320, 62321, 62318, 
+        0,     1, 49152, 57344, 61440, 62464, 62208, 62336, 
+    62304,     0,     1, 49152, 57344, 61440, 62464, 62208, 
+    62336, 62337, 62320,     0,     1, 49152, 57344, 61440, 
+    62464, 62208, 62336, 62337, 62320,     0,     1, 49152, 
+    57344, 61440, 62464, 62208, 62336, 62337, 62320, 62322, 
+        0,     1, 49152, 57344, 61440, 62464, 62208, 62336, 
+    62337, 62320,     0,     1, 49152, 57344, 61440, 62464, 
+    62208, 62336, 62337, 62320, 62324,     0,     1, 49152, 
+    57344, 61440, 62464, 62208, 62336, 62337, 62320, 62324, 
+        0,     1, 49152, 57344, 61440, 62464, 62208, 62336, 
+    62337, 62320, 62328, 62326,     0,     1, 49152, 57344, 
+    61440, 62464, 62208, 62336, 62337, 62320,     0,     1, 
+    49152, 57344, 61440, 62464, 62208, 62336, 62337, 62320, 
+    62328,     0,     1, 49152, 57344, 61440, 62464, 62208, 
+    62336, 62337, 62339, 62328,     0,     1, 49152, 57344, 
+    61440, 62464, 62208, 62336, 62337, 62339, 62328, 62330, 
+        0,     1, 49152, 57344, 61440, 62464, 62208, 62336, 
+    62337, 62339, 62328,     0,     1, 49152, 57344, 61440, 
+    62464, 62208, 62336, 62337, 62339, 62328, 62332,     0, 
+        1, 49152, 57344, 61440, 62464, 62208, 62336, 62337, 
+    62339, 62328, 62332,     0,     1, 49152, 57344, 61440, 
+    62464, 62208, 62336, 62337, 62339, 62328, 62332, 62334, 
+        0,     1, 49152, 57344, 61440, 62464, 62208,     0, 
+        1, 49152, 57344, 61440, 62464, 62208, 62336,     0, 
+        1, 49152, 57344, 61440, 62464, 62465, 62336,     0, 
+        1, 49152, 57344, 61440, 62464, 62465, 62336, 62338, 
+        0,     1, 49152, 57344, 61440, 62464, 62465, 62336, 
+        0,     1, 49152, 57344, 61440, 62464, 62465, 62336, 
+    62340,     0,     1, 49152, 57344, 61440, 62464, 62465, 
+    62336, 62340,     0,     1, 49152, 57344, 61440, 62464, 
+    62465, 62336, 62344, 62342,     0,     1, 49152, 57344, 
+    61440, 62464, 62465, 62336,     0,     1, 49152, 57344, 
+    61440, 62464, 62465, 62336, 62344,     0,     1, 49152, 
+    57344, 61440, 62464, 62465, 62336, 62344,     0,     1, 
+    49152, 57344, 61440, 62464, 62465, 62336, 62344, 62346, 
+        0,     1, 49152, 57344, 61440, 62464, 62465, 62336, 
+    62344,     0,     1, 49152, 57344, 61440, 62464, 62465, 
+    62336, 62352, 62348,     0,     1, 49152, 57344, 61440, 
+    62464, 62465, 62336, 62352, 62348,     0,     1, 49152, 
+    57344, 61440, 62464, 62465, 62336, 62352, 62353, 62350, 
+        0,     1, 49152, 57344, 61440, 62464, 62465, 62336, 
+        0,     1, 49152, 57344, 61440, 62464, 62465, 62336, 
+    62352,     0,     1, 49152, 57344, 61440, 62464, 62465, 
+    62336, 62352,     0,     1, 49152, 57344, 61440, 62464, 
+    62465, 62336, 62352, 62354,     0,     1, 49152, 57344, 
+    61440, 62464, 62465, 62336, 62352,     0,     1, 49152, 
+    57344, 61440, 62464, 62465, 62336, 62352, 62356,     0, 
+        1, 49152, 57344, 61440, 62464, 62465, 62336, 62352, 
+    62356,     0,     1, 49152, 57344, 61440, 62464, 62465, 
+    62336, 62352, 62360, 62358,     0,     1, 49152, 57344, 
+    61440, 62464, 62465, 62336, 62352,     0,     1, 49152, 
+    57344, 61440, 62464, 62465, 62336, 62368, 62360,     0, 
+        1, 49152, 57344, 61440, 62464, 62465, 62336, 62368, 
+    62360,     0,     1, 49152, 57344, 61440, 62464, 62465, 
+    62336, 62368, 62360, 62362,     0,     1, 49152, 57344, 
+    61440, 62464, 62465, 62336, 62368, 62360,     0,     1, 
+    49152, 57344, 61440, 62464, 62465, 62336, 62368, 62369, 
+    62364,     0,     1, 49152, 57344, 61440, 62464, 62465, 
+    62336, 62368, 62369, 62364,     0,     1, 49152, 57344, 
+    61440, 62464, 62465, 62336, 62368, 62369, 62364, 62366, 
+        0,     1, 49152, 57344, 61440, 62464, 62465, 62336, 
+        0,     1, 49152, 57344, 61440, 62464, 62465, 62336, 
+    62368,     0,     1, 49152, 57344, 61440, 62464, 62465, 
+    62336, 62368,     0,     1, 49152, 57344, 61440, 62464, 
+    62465, 62336, 62368, 62370,     0,     1, 49152, 57344, 
+    61440, 62464, 62465, 62336, 62368,     0,     1, 49152, 
+    57344, 61440, 62464, 62465, 62336, 62368, 62372,     0, 
+        1, 49152, 57344, 61440, 62464, 62465, 62336, 62368, 
+    62372,     0,     1, 49152, 57344, 61440, 62464, 62465, 
+    62336, 62368, 62376, 62374,     0,     1, 49152, 57344, 
+    61440, 62464, 62465, 62336, 62368,     0,     1, 49152, 
+    57344, 61440, 62464, 62465, 62336, 62368, 62376,     0, 
+        1, 49152, 57344, 61440, 62464, 62465, 62336, 62368, 
+    62376,     0,     1, 49152, 57344, 61440, 62464, 62465, 
+    62336, 62368, 62376, 62378,     0,     1, 49152, 57344, 
+    61440, 62464, 62465, 62336, 62368, 62376,     0,     1, 
+    49152, 57344, 61440, 62464, 62465, 62336, 62368, 62384, 
+    62380,     0,     1, 49152, 57344, 61440, 62464, 62465, 
+    62336, 62368, 62384, 62380,     0,     1, 49152, 57344, 
+    61440, 62464, 62465, 62336, 62368, 62384, 62385, 62382, 
+        0,     1, 49152, 57344, 61440, 62464, 62465, 62336, 
+    62368,     0,     1, 49152, 57344, 61440, 62464, 62465, 
+    62336, 62400, 62384,     0,     1, 49152, 57344, 61440, 
+    62464, 62465, 62336, 62400, 62384,     0,     1, 49152, 
+    57344, 61440, 62464, 62465, 62336, 62400, 62384, 62386, 
+        0,     1, 49152, 57344, 61440, 62464, 62465, 62336, 
+    62400, 62384,     0,     1, 49152, 57344, 61440, 62464, 
+    62465, 62336, 62400, 62384, 62388,     0,     1, 49152, 
+    57344, 61440, 62464, 62465, 62336, 62400, 62384, 62388, 
+        0,     1, 49152, 57344, 61440, 62464, 62465, 62336, 
+    62400, 62384, 62392, 62390,     0,     1, 49152, 57344, 
+    61440, 62464, 62465, 62336, 62400, 62384,     0,     1, 
+    49152, 57344, 61440, 62464, 62465, 62336, 62400, 62401, 
+    62392,     0,     1, 49152, 57344, 61440, 62464, 62465, 
+    62336, 62400, 62401, 62392,     0,     1, 49152, 57344, 
+    61440, 62464, 62465, 62336, 62400, 62401, 62392, 62394, 
+        0,     1, 49152, 57344, 61440, 62464, 62465, 62336, 
+    62400, 62401, 62392,     0,     1, 49152, 57344, 61440, 
+    62464, 62465, 62336, 62400, 62401, 62392, 62396,     0, 
+        1, 49152, 57344, 61440, 62464, 62465, 62336, 62400, 
+    62401, 62403, 62396,     0,     1, 49152, 57344, 61440, 
+    62464, 62465, 62336, 62400, 62401, 62403, 62396, 62398, 
+        0,     1, 49152, 57344, 61440, 62464, 62465, 62336, 
+        0,     1, 49152, 57344, 61440, 62464, 62465, 62336, 
+    62400,     0,     1, 49152, 57344, 61440, 62464, 62465, 
+    62336, 62400,     0,     1, 49152, 57344, 61440, 62464, 
+    62465, 62336, 62400, 62402,     0,     1, 49152, 57344, 
+    61440, 62464, 62465, 62467, 62400,     0,     1, 49152, 
+    57344, 61440, 62464, 62465, 62467, 62400, 62404,     0, 
+        1, 49152, 57344, 61440, 62464, 62465, 62467, 62400, 
+    62404,     0,     1, 49152, 57344, 61440, 62464, 62465, 
+    62467, 62400, 62408, 62406,     0,     1, 49152, 57344, 
+    61440, 62464, 62465, 62467, 62400,     0,     1, 49152, 
+    57344, 61440, 62464, 62465, 62467, 62400, 62408,     0, 
+        1, 49152, 57344, 61440, 62464, 62465, 62467, 62400, 
+    62408,     0,     1, 49152, 57344, 61440, 62464, 62465, 
+    62467, 62400, 62408, 62410,     0,     1, 49152, 57344, 
+    61440, 62464, 62465, 62467, 62400, 62408,     0,     1, 
+    49152, 57344, 61440, 62464, 62465, 62467, 62400, 62416, 
+    62412,     0,     1, 49152, 57344, 61440, 62464, 62465, 
+    62467, 62400, 62416, 62412,     0,     1, 49152, 57344, 
+    61440, 62464, 62465, 62467, 62400, 62416, 62417, 62414, 
+        0,     1, 49152, 57344, 61440, 62464, 62465, 62467, 
+    62400,     0,     1, 49152, 57344, 61440, 62464, 62465, 
+    62467, 62400, 62416,     0,     1, 49152, 57344, 61440, 
+    62464, 62465, 62467, 62400, 62416,     0,     1, 49152, 
+    57344, 61440, 62464, 62465, 62467, 62400, 62416, 62418, 
+        0,     1, 49152, 57344, 61440, 62464, 62465, 62467, 
+    62400, 62416,     0,     1, 49152, 57344, 61440, 62464, 
+    62465, 62467, 62400, 62416, 62420,     0,     1, 49152, 
+    57344, 61440, 62464, 62465, 62467, 62400, 62416, 62420, 
+        0,     1, 49152, 57344, 61440, 62464, 62465, 62467, 
+    62400, 62416, 62424, 62422,     0,     1, 49152, 57344, 
+    61440, 62464, 62465, 62467, 62400, 62416,     0,     1, 
+    49152, 57344, 61440, 62464, 62465, 62467, 62400, 62432, 
+    62424,     0,     1, 49152, 57344, 61440, 62464, 62465, 
+    62467, 62400, 62432, 62424,     0,     1, 49152, 57344, 
+    61440, 62464, 62465, 62467, 62400, 62432, 62424, 62426, 
+        0,     1, 49152, 57344, 61440, 62464, 62465, 62467, 
+    62400, 62432, 62424,     0,     1, 49152, 57344, 61440, 
+    62464, 62465, 62467, 62400, 62432, 62433, 62428,     0, 
+        1, 49152, 57344, 61440, 62464, 62465, 62467, 62400, 
+    62432, 62433, 62428,     0,     1, 49152, 57344, 61440, 
+    62464, 62465, 62467, 62400, 62432, 62433, 62428, 62430, 
+        0,     1, 49152, 57344, 61440, 62464, 62465, 62467, 
+    62400,     0,     1, 49152, 57344, 61440, 62464, 62465, 
+    62467, 62400, 62432,     0,     1, 49152, 57344, 61440, 
+    62464, 62465, 62467, 62400, 62432,     0,     1, 49152, 
+    57344, 61440, 62464, 62465, 62467, 62400, 62432, 62434, 
+        0,     1, 49152, 57344, 61440, 62464, 62465, 62467, 
+    62400, 62432,     0,     1, 49152, 57344, 61440, 62464, 
+    62465, 62467, 62400, 62432, 62436,     0,     1, 49152, 
+    57344, 61440, 62464, 62465, 62467, 62400, 62432, 62436, 
+        0,     1, 49152, 57344, 61440, 62464, 62465, 62467, 
+    62400, 62432, 62440, 62438,     0,     1, 49152, 57344, 
+    61440, 62464, 62465, 62467, 62471, 62432,     0,     1, 
+    49152, 57344, 61440, 62464, 62465, 62467, 62471, 62432, 
+    62440,     0,     1, 49152, 57344, 61440, 62464, 62465, 
+    62467, 62471, 62432, 62440,     0,     1, 49152, 57344, 
+    61440, 62464, 62465, 62467, 62471, 62432, 62440, 62442, 
+        0,     1, 49152, 57344, 61440, 62464, 62465, 62467, 
+    62471, 62432, 62440,     0,     1, 49152, 57344, 61440, 
+    62464, 62465, 62467, 62471, 62432, 62448, 62444,     0, 
+        1, 49152, 57344, 61440, 62464, 62465, 62467, 62471, 
+    62432, 62448, 62444,     0,     1, 49152, 57344, 61440, 
+    62464, 62465, 62467, 62471, 62432, 62448, 62449, 62446, 
+        0,     1, 49152, 57344, 61440, 62464, 62465, 62467, 
+    62471, 62432,     0,     1, 49152, 57344, 61440, 62464, 
+    62465, 62467, 62471, 62432, 62448,     0,     1, 49152, 
+    57344, 61440, 62464, 62465, 62467, 62471, 62432, 62448, 
+        0,     1, 49152, 57344, 61440, 62464, 62465, 62467, 
+    62471, 62432, 62448, 62450,     0,     1, 49152, 57344, 
+    61440, 62464, 62465, 62467, 62471, 62432, 62448,     0, 
+        1, 49152, 57344, 61440, 62464, 62465, 62467, 62471, 
+    62432, 62448, 62452,     0,     1, 49152, 57344, 61440, 
+    62464, 62465, 62467, 62471, 62432, 62448, 62452,     0, 
+        1, 49152, 57344, 61440, 62464, 62465, 62467, 62471, 
+    62432, 62448, 62456, 62454,     0,     1, 49152, 57344, 
+    61440, 62464, 62465, 62467, 62471, 62432, 62448,     0, 
+        1, 49152, 57344, 61440, 62464, 62465, 62467, 62471, 
+    62432, 62448, 62456,     0,     1, 49152, 57344, 61440, 
+    62464, 62465, 62467, 62471, 62432, 62448, 62456,     0, 
+        1, 49152, 57344, 61440, 62464, 62465, 62467, 62471, 
+    62432, 62448, 62456, 62458,     0,     1, 49152, 57344, 
+    61440, 62464, 62465, 62467, 62471, 62432, 62448, 62456, 
+        0,     1, 49152, 57344, 61440, 62464, 62465, 62467, 
+    62471, 62432, 62448, 62456, 62460,     0,     1, 49152, 
+    57344, 61440, 62464, 62465, 62467, 62471, 62432, 62448, 
+    62456, 62460,     0,     1, 49152, 57344, 61440, 62464, 
+    62465, 62467, 62471, 62432, 62448, 62456, 62460, 62462, 
+        0,     1, 49152, 57344, 61440,     0,     1, 49152, 
+    57344, 61440, 62464,     0,     1, 49152, 57344, 61440, 
+    62464,     0,     1, 49152, 57344, 61440, 62464, 62466, 
+        0,     1, 49152, 57344, 61440, 62464,     0,     1, 
+    49152, 57344, 61440, 62464, 62468,     0,     1, 49152, 
+    57344, 61440, 62464, 62468,     0,     1, 49152, 57344, 
+    61440, 62464, 62472, 62470,     0,     1, 49152, 57344, 
+    61440, 62464,     0,     1, 49152, 57344, 61440, 62464, 
+    62472,     0,     1, 49152, 57344, 61440, 62464, 62472, 
+        0,     1, 49152, 57344, 61440, 62464, 62472, 62474, 
+        0,     1, 49152, 57344, 61440, 62464, 62472,     0, 
+        1, 49152, 57344, 61440, 62464, 62480, 62476,     0, 
+        1, 49152, 57344, 61440, 62464, 62480, 62476,     0, 
+        1, 49152, 57344, 61440, 62464, 62480, 62481, 62478, 
+        0,     1, 49152, 57344, 61440, 62464,     0,     1, 
+    49152, 57344, 61440, 62464, 62480,     0,     1, 49152, 
+    57344, 61440, 62464, 62480,     0,     1, 49152, 57344, 
+    61440, 62464, 62480, 62482,     0,     1, 49152, 57344, 
+    61440, 62464, 62480,     0,     1, 49152, 57344, 61440, 
+    62464, 62480, 62484,     0,     1, 49152, 57344, 61440, 
+    62464, 62480, 62484,     0,     1, 49152, 57344, 61440, 
+    62464, 62480, 62488, 62486,     0,     1, 49152, 57344, 
+    61440, 62464, 62480,     0,     1, 49152, 57344, 61440, 
+    62464, 62496, 62488,     0,     1, 49152, 57344, 61440, 
+    62464, 62496, 62488,     0,     1, 49152, 57344, 61440, 
+    62464, 62496, 62488, 62490,     0,     1, 49152, 57344, 
+    61440, 62464, 62496, 62488,     0,     1, 49152, 57344, 
+    61440, 62464, 62496, 62497, 62492,     0,     1, 49152, 
+    57344, 61440, 62464, 62496, 62497, 62492,     0,     1, 
+    49152, 57344, 61440, 62464, 62496, 62497, 62492, 62494, 
+        0,     1, 49152, 57344, 61440, 62464,     0,     1, 
+    49152, 57344, 61440, 62464, 62496,     0,     1, 49152, 
+    57344, 61440, 62464, 62496,     0,     1, 49152, 57344, 
+    61440, 62464, 62496, 62498,     0,     1, 49152, 57344, 
+    61440, 62464, 62496,     0,     1, 49152, 57344, 61440, 
+    62464, 62496, 62500,     0,     1, 49152, 57344, 61440, 
+    62464, 62496, 62500,     0,     1, 49152, 57344, 61440, 
+    62464, 62496, 62504, 62502,     0,     1, 49152, 57344, 
+    61440, 62464, 62496,     0,     1, 49152, 57344, 61440, 
+    62464, 62496, 62504,     0,     1, 49152, 57344, 61440, 
+    62464, 62496, 62504,     0,     1, 49152, 57344, 61440, 
+    62464, 62496, 62504, 62506,     0,     1, 49152, 57344, 
+    61440, 62464, 62496, 62504,     0,     1, 49152, 57344, 
+    61440, 62464, 62496, 62512, 62508,     0,     1, 49152, 
+    57344, 61440, 62464, 62496, 62512, 62508,     0,     1, 
+    49152, 57344, 61440, 62464, 62496, 62512, 62513, 62510, 
+        0,     1, 49152, 57344, 61440, 62464, 62496,     0, 
+        1, 49152, 57344, 61440, 62464, 62528, 62512,     0, 
+        1, 49152, 57344, 61440, 62464, 62528, 62512,     0, 
+        1, 49152, 57344, 61440, 62464, 62528, 62512, 62514, 
+        0,     1, 49152, 57344, 61440, 62464, 62528, 62512, 
+        0,     1, 49152, 57344, 61440, 62464, 62528, 62512, 
+    62516,     0,     1, 49152, 57344, 61440, 62464, 62528, 
+    62512, 62516,     0,     1, 49152, 57344, 61440, 62464, 
+    62528, 62512, 62520, 62518,     0,     1, 49152, 57344, 
+    61440, 62464, 62528, 62512,     0,     1, 49152, 57344, 
+    61440, 62464, 62528, 62529, 62520,     0,     1, 49152, 
+    57344, 61440, 62464, 62528, 62529, 62520,     0,     1, 
+    49152, 57344, 61440, 62464, 62528, 62529, 62520, 62522, 
+        0,     1, 49152, 57344, 61440, 62464, 62528, 62529, 
+    62520,     0,     1, 49152, 57344, 61440, 62464, 62528, 
+    62529, 62520, 62524,     0,     1, 49152, 57344, 61440, 
+    62464, 62528, 62529, 62531, 62524,     0,     1, 49152, 
+    57344, 61440, 62464, 62528, 62529, 62531, 62524, 62526, 
+        0,     1, 49152, 57344, 61440, 62464,     0,     1, 
+    49152, 57344, 61440, 62464, 62528,     0,     1, 49152, 
+    57344, 61440, 62464, 62528,     0,     1, 49152, 57344, 
+    61440, 62464, 62528, 62530,     0,     1, 49152, 57344, 
+    61440, 62464, 62528,     0,     1, 49152, 57344, 61440, 
+    62464, 62528, 62532,     0,     1, 49152, 57344, 61440, 
+    62464, 62528, 62532,     0,     1, 49152, 57344, 61440, 
+    62464, 62528, 62536, 62534,     0,     1, 49152, 57344, 
+    61440, 62464, 62528,     0,     1, 49152, 57344, 61440, 
+    62464, 62528, 62536,     0,     1, 49152, 57344, 61440, 
+    62464, 62528, 62536,     0,     1, 49152, 57344, 61440, 
+    62464, 62528, 62536, 62538,     0,     1, 49152, 57344, 
+    61440, 62464, 62528, 62536,     0,     1, 49152, 57344, 
+    61440, 62464, 62528, 62544, 62540,     0,     1, 49152, 
+    57344, 61440, 62464, 62528, 62544, 62540,     0,     1, 
+    49152, 57344, 61440, 62464, 62528, 62544, 62545, 62542, 
+        0,     1, 49152, 57344, 61440, 62464, 62528,     0, 
+        1, 49152, 57344, 61440, 62464, 62528, 62544,     0, 
+        1, 49152, 57344, 61440, 62464, 62528, 62544,     0, 
+        1, 49152, 57344, 61440, 62464, 62528, 62544, 62546, 
+        0,     1, 49152, 57344, 61440, 62464, 62528, 62544, 
+        0,     1, 49152, 57344, 61440, 62464, 62528, 62544, 
+    62548,     0,     1, 49152, 57344, 61440, 62464, 62528, 
+    62544, 62548,     0,     1, 49152, 57344, 61440, 62464, 
+    62528, 62544, 62552, 62550,     0,     1, 49152, 57344, 
+    61440, 62464, 62528, 62544,     0,     1, 49152, 57344, 
+    61440, 62464, 62528, 62560, 62552,     0,     1, 49152, 
+    57344, 61440, 62464, 62528, 62560, 62552,     0,     1, 
+    49152, 57344, 61440, 62464, 62528, 62560, 62552, 62554, 
+        0,     1, 49152, 57344, 61440, 62464, 62528, 62560, 
+    62552,     0,     1, 49152, 57344, 61440, 62464, 62528, 
+    62560, 62561, 62556,     0,     1, 49152, 57344, 61440, 
+    62464, 62528, 62560, 62561, 62556,     0,     1, 49152, 
+    57344, 61440, 62464, 62528, 62560, 62561, 62556, 62558, 
+        0,     1, 49152, 57344, 61440, 62464, 62528,     0, 
+        1, 49152, 57344, 61440, 62464, 62592, 62560,     0, 
+        1, 49152, 57344, 61440, 62464, 62592, 62560,     0, 
+        1, 49152, 57344, 61440, 62464, 62592, 62560, 62562, 
+        0,     1, 49152, 57344, 61440, 62464, 62592, 62560, 
+        0,     1, 49152, 57344, 61440, 62464, 62592, 62560, 
+    62564,     0,     1, 49152, 57344, 61440, 62464, 62592, 
+    62560, 62564,     0,     1, 49152, 57344, 61440, 62464, 
+    62592, 62560, 62568, 62566,     0,     1, 49152, 57344, 
+    61440, 62464, 62592, 62560,     0,     1, 49152, 57344, 
+    61440, 62464, 62592, 62560, 62568,     0,     1, 49152, 
+    57344, 61440, 62464, 62592, 62560, 62568,     0,     1, 
+    49152, 57344, 61440, 62464, 62592, 62560, 62568, 62570, 
+        0,     1, 49152, 57344, 61440, 62464, 62592, 62560, 
+    62568,     0,     1, 49152, 57344, 61440, 62464, 62592, 
+    62560, 62576, 62572,     0,     1, 49152, 57344, 61440, 
+    62464, 62592, 62560, 62576, 62572,     0,     1, 49152, 
+    57344, 61440, 62464, 62592, 62560, 62576, 62577, 62574, 
+        0,     1, 49152, 57344, 61440, 62464, 62592, 62560, 
+        0,     1, 49152, 57344, 61440, 62464, 62592, 62593, 
+    62576,     0,     1, 49152, 57344, 61440, 62464, 62592, 
+    62593, 62576,     0,     1, 49152, 57344, 61440, 62464, 
+    62592, 62593, 62576, 62578,     0,     1, 49152, 57344, 
+    61440, 62464, 62592, 62593, 62576,     0,     1, 49152, 
+    57344, 61440, 62464, 62592, 62593, 62576, 62580,     0, 
+        1, 49152, 57344, 61440, 62464, 62592, 62593, 62576, 
+    62580,     0,     1, 49152, 57344, 61440, 62464, 62592, 
+    62593, 62576, 62584, 62582,     0,     1, 49152, 57344, 
+    61440, 62464, 62592, 62593, 62576,     0,     1, 49152, 
+    57344, 61440, 62464, 62592, 62593, 62576, 62584,     0, 
+        1, 49152, 57344, 61440, 62464, 62592, 62593, 62595, 
+    62584,     0,     1, 49152, 57344, 61440, 62464, 62592, 
+    62593, 62595, 62584, 62586,     0,     1, 49152, 57344, 
+    61440, 62464, 62592, 62593, 62595, 62584,     0,     1, 
+    49152, 57344, 61440, 62464, 62592, 62593, 62595, 62584, 
+    62588,     0,     1, 49152, 57344, 61440, 62464, 62592, 
+    62593, 62595, 62584, 62588,     0,     1, 49152, 57344, 
+    61440, 62464, 62592, 62593, 62595, 62584, 62588, 62590, 
+        0,     1, 49152, 57344, 61440, 62464,     0,     1, 
+    49152, 57344, 61440, 62464, 62592,     0,     1, 49152, 
+    57344, 61440, 62464, 62592,     0,     1, 49152, 57344, 
+    61440, 62464, 62592, 62594,     0,     1, 49152, 57344, 
+    61440, 62464, 62592,     0,     1, 49152, 57344, 61440, 
+    62464, 62592, 62596,     0,     1, 49152, 57344, 61440, 
+    62464, 62592, 62596,     0,     1, 49152, 57344, 61440, 
+    62464, 62592, 62600, 62598,     0,     1, 49152, 57344, 
+    61440, 62464, 62592,     0,     1, 49152, 57344, 61440, 
+    62464, 62592, 62600,     0,     1, 49152, 57344, 61440, 
+    62464, 62592, 62600,     0,     1, 49152, 57344, 61440, 
+    62464, 62592, 62600, 62602,     0,     1, 49152, 57344, 
+    61440, 62464, 62592, 62600,     0,     1, 49152, 57344, 
+    61440, 62464, 62592, 62608, 62604,     0,     1, 49152, 
+    57344, 61440, 62464, 62592, 62608, 62604,     0,     1, 
+    49152, 57344, 61440, 62464, 62592, 62608, 62609, 62606, 
+        0,     1, 49152, 57344, 61440, 62464, 62592,     0, 
+        1, 49152, 57344, 61440, 62464, 62592, 62608,     0, 
+        1, 49152, 57344, 61440, 62464, 62592, 62608,     0, 
+        1, 49152, 57344, 61440, 62464, 62592, 62608, 62610, 
+        0,     1, 49152, 57344, 61440, 62464, 62592, 62608, 
+        0,     1, 49152, 57344, 61440, 62464, 62592, 62608, 
+    62612,     0,     1, 49152, 57344, 61440, 62464, 62592, 
+    62608, 62612,     0,     1, 49152, 57344, 61440, 62464, 
+    62592, 62608, 62616, 62614,     0,     1, 49152, 57344, 
+    61440, 62464, 62592, 62608,     0,     1, 49152, 57344, 
+    61440, 62464, 62592, 62624, 62616,     0,     1, 49152, 
+    57344, 61440, 62464, 62592, 62624, 62616,     0,     1, 
+    49152, 57344, 61440, 62464, 62592, 62624, 62616, 62618, 
+        0,     1, 49152, 57344, 61440, 62464, 62592, 62624, 
+    62616,     0,     1, 49152, 57344, 61440, 62464, 62592, 
+    62624, 62625, 62620,     0,     1, 49152, 57344, 61440, 
+    62464, 62592, 62624, 62625, 62620,     0,     1, 49152, 
+    57344, 61440, 62464, 62592, 62624, 62625, 62620, 62622, 
+        0,     1, 49152, 57344, 61440, 62464, 62592,     0, 
+        1, 49152, 57344, 61440, 62464, 62592, 62624,     0, 
+        1, 49152, 57344, 61440, 62464, 62592, 62624,     0, 
+        1, 49152, 57344, 61440, 62464, 62592, 62624, 62626, 
+        0,     1, 49152, 57344, 61440, 62464, 62592, 62624, 
+        0,     1, 49152, 57344, 61440, 62464, 62592, 62624, 
+    62628,     0,     1, 49152, 57344, 61440, 62464, 62592, 
+    62624, 62628,     0,     1, 49152, 57344, 61440, 62464, 
+    62592, 62624, 62632, 62630,     0,     1, 49152, 57344, 
+    61440, 62464, 62592, 62624,     0,     1, 49152, 57344, 
+    61440, 62464, 62592, 62624, 62632,     0,     1, 49152, 
+    57344, 61440, 62464, 62592, 62624, 62632,     0,     1, 
+    49152, 57344, 61440, 62464, 62592, 62624, 62632, 62634, 
+        0,     1, 49152, 57344, 61440, 62464, 62592, 62624, 
+    62632,     0,     1, 49152, 57344, 61440, 62464, 62592, 
+    62624, 62640, 62636,     0,     1, 49152, 57344, 61440, 
+    62464, 62592, 62624, 62640, 62636,     0,     1, 49152, 
+    57344, 61440, 62464, 62592, 62624, 62640, 62641, 62638, 
+        0,     1, 49152, 57344, 61440, 62464, 62592, 62624, 
+        0,     1, 49152, 57344, 61440, 62464, 62592, 62656, 
+    62640,     0,     1, 49152, 57344, 61440, 62464, 62592, 
+    62656, 62640,     0,     1, 49152, 57344, 61440, 62464, 
+    62592, 62656, 62640, 62642,     0,     1, 49152, 57344, 
+    61440, 62464, 62592, 62656, 62640,     0,     1, 49152, 
+    57344, 61440, 62464, 62592, 62656, 62640, 62644,     0, 
+        1, 49152, 57344, 61440, 62464, 62592, 62656, 62640, 
+    62644,     0,     1, 49152, 57344, 61440, 62464, 62592, 
+    62656, 62640, 62648, 62646,     0,     1, 49152, 57344, 
+    61440, 62464, 62592, 62656, 62640,     0,     1, 49152, 
+    57344, 61440, 62464, 62592, 62656, 62657, 62648,     0, 
+        1, 49152, 57344, 61440, 62464, 62592, 62656, 62657, 
+    62648,     0,     1, 49152, 57344, 61440, 62464, 62592, 
+    62656, 62657, 62648, 62650,     0,     1, 49152, 57344, 
+    61440, 62464, 62592, 62656, 62657, 62648,     0,     1, 
+    49152, 57344, 61440, 62464, 62592, 62656, 62657, 62648, 
+    62652,     0,     1, 49152, 57344, 61440, 62464, 62592, 
+    62656, 62657, 62659, 62652,     0,     1, 49152, 57344, 
+    61440, 62464, 62592, 62656, 62657, 62659, 62652, 62654, 
+        0,     1, 49152, 57344, 61440, 62464, 62592,     0, 
+        1, 49152, 57344, 61440, 62464, 62720, 62656,     0, 
+        1, 49152, 57344, 61440, 62464, 62720, 62656,     0, 
+        1, 49152, 57344, 61440, 62464, 62720, 62656, 62658, 
+        0,     1, 49152, 57344, 61440, 62464, 62720, 62656, 
+        0,     1, 49152, 57344, 61440, 62464, 62720, 62656, 
+    62660,     0,     1, 49152, 57344, 61440, 62464, 62720, 
+    62656, 62660,     0,     1, 49152, 57344, 61440, 62464, 
+    62720, 62656, 62664, 62662,     0,     1, 49152, 57344, 
+    61440, 62464, 62720, 62656,     0,     1, 49152, 57344, 
+    61440, 62464, 62720, 62656, 62664,     0,     1, 49152, 
+    57344, 61440, 62464, 62720, 62656, 62664,     0,     1, 
+    49152, 57344, 61440, 62464, 62720, 62656, 62664, 62666, 
+        0,     1, 49152, 57344, 61440, 62464, 62720, 62656, 
+    62664,     0,     1, 49152, 57344, 61440, 62464, 62720, 
+    62656, 62672, 62668,     0,     1, 49152, 57344, 61440, 
+    62464, 62720, 62656, 62672, 62668,     0,     1, 49152, 
+    57344, 61440, 62464, 62720, 62656, 62672, 62673, 62670, 
+        0,     1, 49152, 57344, 61440, 62464, 62720, 62656, 
+        0,     1, 49152, 57344, 61440, 62464, 62720, 62656, 
+    62672,     0,     1, 49152, 57344, 61440, 62464, 62720, 
+    62656, 62672,     0,     1, 49152, 57344, 61440, 62464, 
+    62720, 62656, 62672, 62674,     0,     1, 49152, 57344, 
+    61440, 62464, 62720, 62656, 62672,     0,     1, 49152, 
+    57344, 61440, 62464, 62720, 62656, 62672, 62676,     0, 
+        1, 49152, 57344, 61440, 62464, 62720, 62656, 62672, 
+    62676,     0,     1, 49152, 57344, 61440, 62464, 62720, 
+    62656, 62672, 62680, 62678,     0,     1, 49152, 57344, 
+    61440, 62464, 62720, 62656, 62672,     0,     1, 49152, 
+    57344, 61440, 62464, 62720, 62656, 62688, 62680,     0, 
+        1, 49152, 57344, 61440, 62464, 62720, 62656, 62688, 
+    62680,     0,     1, 49152, 57344, 61440, 62464, 62720, 
+    62656, 62688, 62680, 62682,     0,     1, 49152, 57344, 
+    61440, 62464, 62720, 62656, 62688, 62680,     0,     1, 
+    49152, 57344, 61440, 62464, 62720, 62656, 62688, 62689, 
+    62684,     0,     1, 49152, 57344, 61440, 62464, 62720, 
+    62656, 62688, 62689, 62684,     0,     1, 49152, 57344, 
+    61440, 62464, 62720, 62656, 62688, 62689, 62684, 62686, 
+        0,     1, 49152, 57344, 61440, 62464, 62720, 62656, 
+        0,     1, 49152, 57344, 61440, 62464, 62720, 62721, 
+    62688,     0,     1, 49152, 57344, 61440, 62464, 62720, 
+    62721, 62688,     0,     1, 49152, 57344, 61440, 62464, 
+    62720, 62721, 62688, 62690,     0,     1, 49152, 57344, 
+    61440, 62464, 62720, 62721, 62688,     0,     1, 49152, 
+    57344, 61440, 62464, 62720, 62721, 62688, 62692,     0, 
+        1, 49152, 57344, 61440, 62464, 62720, 62721, 62688, 
+    62692,     0,     1, 49152, 57344, 61440, 62464, 62720, 
+    62721, 62688, 62696, 62694,     0,     1, 49152, 57344, 
+    61440, 62464, 62720, 62721, 62688,     0,     1, 49152, 
+    57344, 61440, 62464, 62720, 62721, 62688, 62696,     0, 
+        1, 49152, 57344, 61440, 62464, 62720, 62721, 62688, 
+    62696,     0,     1, 49152, 57344, 61440, 62464, 62720, 
+    62721, 62688, 62696, 62698,     0,     1, 49152, 57344, 
+    61440, 62464, 62720, 62721, 62688, 62696,     0,     1, 
+    49152, 57344, 61440, 62464, 62720, 62721, 62688, 62704, 
+    62700,     0,     1, 49152, 57344, 61440, 62464, 62720, 
+    62721, 62688, 62704, 62700,     0,     1, 49152, 57344, 
+    61440, 62464, 62720, 62721, 62688, 62704, 62705, 62702, 
+        0,     1, 49152, 57344, 61440, 62464, 62720, 62721, 
+    62688,     0,     1, 49152, 57344, 61440, 62464, 62720, 
+    62721, 62688, 62704,     0,     1, 49152, 57344, 61440, 
+    62464, 62720, 62721, 62723, 62704,     0,     1, 49152, 
+    57344, 61440, 62464, 62720, 62721, 62723, 62704, 62706, 
+        0,     1, 49152, 57344, 61440, 62464, 62720, 62721, 
+    62723, 62704,     0,     1, 49152, 57344, 61440, 62464, 
+    62720, 62721, 62723, 62704, 62708,     0,     1, 49152, 
+    57344, 61440, 62464, 62720, 62721, 62723, 62704, 62708, 
+        0,     1, 49152, 57344, 61440, 62464, 62720, 62721, 
+    62723, 62704, 62712, 62710,     0,     1, 49152, 57344, 
+    61440, 62464, 62720, 62721, 62723, 62704,     0,     1, 
+    49152, 57344, 61440, 62464, 62720, 62721, 62723, 62704, 
+    62712,     0,     1, 49152, 57344, 61440, 62464, 62720, 
+    62721, 62723, 62704, 62712,     0,     1, 49152, 57344, 
+    61440, 62464, 62720, 62721, 62723, 62704, 62712, 62714, 
+        0,     1, 49152, 57344, 61440, 62464, 62720, 62721, 
+    62723, 62727, 62712,     0,     1, 49152, 57344, 61440, 
+    62464, 62720, 62721, 62723, 62727, 62712, 62716,     0, 
+        1, 49152, 57344, 61440, 62464, 62720, 62721, 62723, 
+    62727, 62712, 62716,     0,     1, 49152, 57344, 61440, 
+    62464, 62720, 62721, 62723, 62727, 62712, 62716, 62718, 
+        0,     1, 49152, 57344, 61440, 62464,     0,     1, 
+    49152, 57344, 61440, 62464, 62720,     0,     1, 49152, 
+    57344, 61440, 62464, 62720,     0,     1, 49152, 57344, 
+    61440, 62464, 62720, 62722,     0,     1, 49152, 57344, 
+    61440, 62464, 62720,     0,     1, 49152, 57344, 61440, 
+    62464, 62720, 62724,     0,     1, 49152, 57344, 61440, 
+    62464, 62720, 62724,     0,     1, 49152, 57344, 61440, 
+    62464, 62720, 62728, 62726,     0,     1, 49152, 57344, 
+    61440, 62464, 62720,     0,     1, 49152, 57344, 61440, 
+    62464, 62720, 62728,     0,     1, 49152, 57344, 61440, 
+    62464, 62720, 62728,     0,     1, 49152, 57344, 61440, 
+    62464, 62720, 62728, 62730,     0,     1, 49152, 57344, 
+    61440, 62464, 62720, 62728,     0,     1, 49152, 57344, 
+    61440, 62464, 62720, 62736, 62732,     0,     1, 49152, 
+    57344, 61440, 62464, 62720, 62736, 62732,     0,     1, 
+    49152, 57344, 61440, 62464, 62720, 62736, 62737, 62734, 
+        0,     1, 49152, 57344, 61440, 62464, 62720,     0, 
+        1, 49152, 57344, 61440, 62464, 62720, 62736,     0, 
+        1, 49152, 57344, 61440, 62464, 62720, 62736,     0, 
+        1, 49152, 57344, 61440, 62464, 62720, 62736, 62738, 
+        0,     1, 49152, 57344, 61440, 62464, 62720, 62736, 
+        0,     1, 49152, 57344, 61440, 62464, 62720, 62736, 
+    62740,     0,     1, 49152, 57344, 61440, 62464, 62720, 
+    62736, 62740,     0,     1, 49152, 57344, 61440, 62464, 
+    62720, 62736, 62744, 62742,     0,     1, 49152, 57344, 
+    61440, 62464, 62720, 62736,     0,     1, 49152, 57344, 
+    61440, 62464, 62720, 62752, 62744,     0,     1, 49152, 
+    57344, 61440, 62464, 62720, 62752, 62744,     0,     1, 
+    49152, 57344, 61440, 62464, 62720, 62752, 62744, 62746, 
+        0,     1, 49152, 57344, 61440, 62464, 62720, 62752, 
+    62744,     0,     1, 49152, 57344, 61440, 62464, 62720, 
+    62752, 62753, 62748,     0,     1, 49152, 57344, 61440, 
+    62464, 62720, 62752, 62753, 62748,     0,     1, 49152, 
+    57344, 61440, 62464, 62720, 62752, 62753, 62748, 62750, 
+        0,     1, 49152, 57344, 61440, 62464, 62720,     0, 
+        1, 49152, 57344, 61440, 62464, 62720, 62752,     0, 
+        1, 49152, 57344, 61440, 62464, 62720, 62752,     0, 
+        1, 49152, 57344, 61440, 62464, 62720, 62752, 62754, 
+        0,     1, 49152, 57344, 61440, 62464, 62720, 62752, 
+        0,     1, 49152, 57344, 61440, 62464, 62720, 62752, 
+    62756,     0,     1, 49152, 57344, 61440, 62464, 62720, 
+    62752, 62756,     0,     1, 49152, 57344, 61440, 62464, 
+    62720, 62752, 62760, 62758,     0,     1, 49152, 57344, 
+    61440, 62464, 62720, 62752,     0,     1, 49152, 57344, 
+    61440, 62464, 62720, 62752, 62760,     0,     1, 49152, 
+    57344, 61440, 62464, 62720, 62752, 62760,     0,     1, 
+    49152, 57344, 61440, 62464, 62720, 62752, 62760, 62762, 
+        0,     1, 49152, 57344, 61440, 62464, 62720, 62752, 
+    62760,     0,     1, 49152, 57344, 61440, 62464, 62720, 
+    62752, 62768, 62764,     0,     1, 49152, 57344, 61440, 
+    62464, 62720, 62752, 62768, 62764,     0,     1, 49152, 
+    57344, 61440, 62464, 62720, 62752, 62768, 62769, 62766, 
+        0,     1, 49152, 57344, 61440, 62464, 62720, 62752, 
+        0,     1, 49152, 57344, 61440, 62464, 62720, 62784, 
+    62768,     0,     1, 49152, 57344, 61440, 62464, 62720, 
+    62784, 62768,     0,     1, 49152, 57344, 61440, 62464, 
+    62720, 62784, 62768, 62770,     0,     1, 49152, 57344, 
+    61440, 62464, 62720, 62784, 62768,     0,     1, 49152, 
+    57344, 61440, 62464, 62720, 62784, 62768, 62772,     0, 
+        1, 49152, 57344, 61440, 62464, 62720, 62784, 62768, 
+    62772,     0,     1, 49152, 57344, 61440, 62464, 62720, 
+    62784, 62768, 62776, 62774,     0,     1, 49152, 57344, 
+    61440, 62464, 62720, 62784, 62768,     0,     1, 49152, 
+    57344, 61440, 62464, 62720, 62784, 62785, 62776,     0, 
+        1, 49152, 57344, 61440, 62464, 62720, 62784, 62785, 
+    62776,     0,     1, 49152, 57344, 61440, 62464, 62720, 
+    62784, 62785, 62776, 62778,     0,     1, 49152, 57344, 
+    61440, 62464, 62720, 62784, 62785, 62776,     0,     1, 
+    49152, 57344, 61440, 62464, 62720, 62784, 62785, 62776, 
+    62780,     0,     1, 49152, 57344, 61440, 62464, 62720, 
+    62784, 62785, 62787, 62780,     0,     1, 49152, 57344, 
+    61440, 62464, 62720, 62784, 62785, 62787, 62780, 62782, 
+        0,     1, 49152, 57344, 61440, 62464, 62720,     0, 
+        1, 49152, 57344, 61440, 62464, 62720, 62784,     0, 
+        1, 49152, 57344, 61440, 62464, 62720, 62784,     0, 
+        1, 49152, 57344, 61440, 62464, 62720, 62784, 62786, 
+        0,     1, 49152, 57344, 61440, 62464, 62720, 62784, 
+        0,     1, 49152, 57344, 61440, 62464, 62720, 62784, 
+    62788,     0,     1, 49152, 57344, 61440, 62464, 62720, 
+    62784, 62788,     0,     1, 49152, 57344, 61440, 62464, 
+    62720, 62784, 62792, 62790,     0,     1, 49152, 57344, 
+    61440, 62464, 62720, 62784,     0,     1, 49152, 57344, 
+    61440, 62464, 62720, 62784, 62792,     0,     1, 49152, 
+    57344, 61440, 62464, 62720, 62784, 62792,     0,     1, 
+    49152, 57344, 61440, 62464, 62720, 62784, 62792, 62794, 
+        0,     1, 49152, 57344, 61440, 62464, 62720, 62784, 
+    62792,     0,     1, 49152, 57344, 61440, 62464, 62720, 
+    62784, 62800, 62796,     0,     1, 49152, 57344, 61440, 
+    62464, 62720, 62784, 62800, 62796,     0,     1, 49152, 
+    57344, 61440, 62464, 62720, 62784, 62800, 62801, 62798, 
+        0,     1, 49152, 57344, 61440, 62464, 62720, 62784, 
+        0,     1, 49152, 57344, 61440, 62464, 62720, 62784, 
+    62800,     0,     1, 49152, 57344, 61440, 62464, 62720, 
+    62784, 62800,     0,     1, 49152, 57344, 61440, 62464, 
+    62720, 62784, 62800, 62802,     0,     1, 49152, 57344, 
+    61440, 62464, 62720, 62784, 62800,     0,     1, 49152, 
+    57344, 61440, 62464, 62720, 62784, 62800, 62804,     0, 
+        1, 49152, 57344, 61440, 62464, 62720, 62784, 62800, 
+    62804,     0,     1, 49152, 57344, 61440, 62464, 62720, 
+    62784, 62800, 62808, 62806,     0,     1, 49152, 57344, 
+    61440, 62464, 62720, 62784, 62800,     0,     1, 49152, 
+    57344, 61440, 62464, 62720, 62784, 62816, 62808,     0, 
+        1, 49152, 57344, 61440, 62464, 62720, 62784, 62816, 
+    62808,     0,     1, 49152, 57344, 61440, 62464, 62720, 
+    62784, 62816, 62808, 62810,     0,     1, 49152, 57344, 
+    61440, 62464, 62720, 62784, 62816, 62808,     0,     1, 
+    49152, 57344, 61440, 62464, 62720, 62784, 62816, 62817, 
+    62812,     0,     1, 49152, 57344, 61440, 62464, 62720, 
+    62784, 62816, 62817, 62812,     0,     1, 49152, 57344, 
+    61440, 62464, 62720, 62784, 62816, 62817, 62812, 62814, 
+        0,     1, 49152, 57344, 61440, 62464, 62720, 62784, 
+        0,     1, 49152, 57344, 61440, 62464, 62720, 62848, 
+    62816,     0,     1, 49152, 57344, 61440, 62464, 62720, 
+    62848, 62816,     0,     1, 49152, 57344, 61440, 62464, 
+    62720, 62848, 62816, 62818,     0,     1, 49152, 57344, 
+    61440, 62464, 62720, 62848, 62816,     0,     1, 49152, 
+    57344, 61440, 62464, 62720, 62848, 62816, 62820,     0, 
+        1, 49152, 57344, 61440, 62464, 62720, 62848, 62816, 
+    62820,     0,     1, 49152, 57344, 61440, 62464, 62720, 
+    62848, 62816, 62824, 62822,     0,     1, 49152, 57344, 
+    61440, 62464, 62720, 62848, 62816,     0,     1, 49152, 
+    57344, 61440, 62464, 62720, 62848, 62816, 62824,     0, 
+        1, 49152, 57344, 61440, 62464, 62720, 62848, 62816, 
+    62824,     0,     1, 49152, 57344, 61440, 62464, 62720, 
+    62848, 62816, 62824, 62826,     0,     1, 49152, 57344, 
+    61440, 62464, 62720, 62848, 62816, 62824,     0,     1, 
+    49152, 57344, 61440, 62464, 62720, 62848, 62816, 62832, 
+    62828,     0,     1, 49152, 57344, 61440, 62464, 62720, 
+    62848, 62816, 62832, 62828,     0,     1, 49152, 57344, 
+    61440, 62464, 62720, 62848, 62816, 62832, 62833, 62830, 
+        0,     1, 49152, 57344, 61440, 62464, 62720, 62848, 
+    62816,     0,     1, 49152, 57344, 61440, 62464, 62720, 
+    62848, 62849, 62832,     0,     1, 49152, 57344, 61440, 
+    62464, 62720, 62848, 62849, 62832,     0,     1, 49152, 
+    57344, 61440, 62464, 62720, 62848, 62849, 62832, 62834, 
+        0,     1, 49152, 57344, 61440, 62464, 62720, 62848, 
+    62849, 62832,     0,     1, 49152, 57344, 61440, 62464, 
+    62720, 62848, 62849, 62832, 62836,     0,     1, 49152, 
+    57344, 61440, 62464, 62720, 62848, 62849, 62832, 62836, 
+        0,     1, 49152, 57344, 61440, 62464, 62720, 62848, 
+    62849, 62832, 62840, 62838,     0,     1, 49152, 57344, 
+    61440, 62464, 62720, 62848, 62849, 62832,     0,     1, 
+    49152, 57344, 61440, 62464, 62720, 62848, 62849, 62832, 
+    62840,     0,     1, 49152, 57344, 61440, 62464, 62720, 
+    62848, 62849, 62851, 62840,     0,     1, 49152, 57344, 
+    61440, 62464, 62720, 62848, 62849, 62851, 62840, 62842, 
+        0,     1, 49152, 57344, 61440, 62464, 62720, 62848, 
+    62849, 62851, 62840,     0,     1, 49152, 57344, 61440, 
+    62464, 62720, 62848, 62849, 62851, 62840, 62844,     0, 
+        1, 49152, 57344, 61440, 62464, 62720, 62848, 62849, 
+    62851, 62840, 62844,     0,     1, 49152, 57344, 61440, 
+    62464, 62720, 62848, 62849, 62851, 62840, 62844, 62846, 
+        0,     1, 49152, 57344, 61440, 62464, 62720,     0, 
+        1, 49152, 57344, 61440, 62464, 62976, 62848,     0, 
+        1, 49152, 57344, 61440, 62464, 62976, 62848,     0, 
+        1, 49152, 57344, 61440, 62464, 62976, 62848, 62850, 
+        0,     1, 49152, 57344, 61440, 62464, 62976, 62848, 
+        0,     1, 49152, 57344, 61440, 62464, 62976, 62848, 
+    62852,     0,     1, 49152, 57344, 61440, 62464, 62976, 
+    62848, 62852,     0,     1, 49152, 57344, 61440, 62464, 
+    62976, 62848, 62856, 62854,     0,     1, 49152, 57344, 
+    61440, 62464, 62976, 62848,     0,     1, 49152, 57344, 
+    61440, 62464, 62976, 62848, 62856,     0,     1, 49152, 
+    57344, 61440, 62464, 62976, 62848, 62856,     0,     1, 
+    49152, 57344, 61440, 62464, 62976, 62848, 62856, 62858, 
+        0,     1, 49152, 57344, 61440, 62464, 62976, 62848, 
+    62856,     0,     1, 49152, 57344, 61440, 62464, 62976, 
+    62848, 62864, 62860,     0,     1, 49152, 57344, 61440, 
+    62464, 62976, 62848, 62864, 62860,     0,     1, 49152, 
+    57344, 61440, 62464, 62976, 62848, 62864, 62865, 62862, 
+        0,     1, 49152, 57344, 61440, 62464, 62976, 62848, 
+        0,     1, 49152, 57344, 61440, 62464, 62976, 62848, 
+    62864,     0,     1, 49152, 57344, 61440, 62464, 62976, 
+    62848, 62864,     0,     1, 49152, 57344, 61440, 62464, 
+    62976, 62848, 62864, 62866,     0,     1, 49152, 57344, 
+    61440, 62464, 62976, 62848, 62864,     0,     1, 49152, 
+    57344, 61440, 62464, 62976, 62848, 62864, 62868,     0, 
+        1, 49152, 57344, 61440, 62464, 62976, 62848, 62864, 
+    62868,     0,     1, 49152, 57344, 61440, 62464, 62976, 
+    62848, 62864, 62872, 62870,     0,     1, 49152, 57344, 
+    61440, 62464, 62976, 62848, 62864,     0,     1, 49152, 
+    57344, 61440, 62464, 62976, 62848, 62880, 62872,     0, 
+        1, 49152, 57344, 61440, 62464, 62976, 62848, 62880, 
+    62872,     0,     1, 49152, 57344, 61440, 62464, 62976, 
+    62848, 62880, 62872, 62874,     0,     1, 49152, 57344, 
+    61440, 62464, 62976, 62848, 62880, 62872,     0,     1, 
+    49152, 57344, 61440, 62464, 62976, 62848, 62880, 62881, 
+    62876,     0,     1, 49152, 57344, 61440, 62464, 62976, 
+    62848, 62880, 62881, 62876,     0,     1, 49152, 57344, 
+    61440, 62464, 62976, 62848, 62880, 62881, 62876, 62878, 
+        0,     1, 49152, 57344, 61440, 62464, 62976, 62848, 
+        0,     1, 49152, 57344, 61440, 62464, 62976, 62848, 
+    62880,     0,     1, 49152, 57344, 61440, 62464, 62976, 
+    62848, 62880,     0,     1, 49152, 57344, 61440, 62464, 
+    62976, 62848, 62880, 62882,     0,     1, 49152, 57344, 
+    61440, 62464, 62976, 62848, 62880,     0,     1, 49152, 
+    57344, 61440, 62464, 62976, 62848, 62880, 62884,     0, 
+        1, 49152, 57344, 61440, 62464, 62976, 62848, 62880, 
+    62884,     0,     1, 49152, 57344, 61440, 62464, 62976, 
+    62848, 62880, 62888, 62886,     0,     1, 49152, 57344, 
+    61440, 62464, 62976, 62848, 62880,     0,     1, 49152, 
+    57344, 61440, 62464, 62976, 62848, 62880, 62888,     0, 
+        1, 49152, 57344, 61440, 62464, 62976, 62848, 62880, 
+    62888,     0,     1, 49152, 57344, 61440, 62464, 62976, 
+    62848, 62880, 62888, 62890,     0,     1, 49152, 57344, 
+    61440, 62464, 62976, 62848, 62880, 62888,     0,     1, 
+    49152, 57344, 61440, 62464, 62976, 62848, 62880, 62896, 
+    62892,     0,     1, 49152, 57344, 61440, 62464, 62976, 
+    62848, 62880, 62896, 62892,     0,     1, 49152, 57344, 
+    61440, 62464, 62976, 62848, 62880, 62896, 62897, 62894, 
+        0,     1, 49152, 57344, 61440, 62464, 62976, 62848, 
+    62880,     0,     1, 49152, 57344, 61440, 62464, 62976, 
+    62848, 62912, 62896,     0,     1, 49152, 57344, 61440, 
+    62464, 62976, 62848, 62912, 62896,     0,     1, 49152, 
+    57344, 61440, 62464, 62976, 62848, 62912, 62896, 62898, 
+        0,     1, 49152, 57344, 61440, 62464, 62976, 62848, 
+    62912, 62896,     0,     1, 49152, 57344, 61440, 62464, 
+    62976, 62848, 62912, 62896, 62900,     0,     1, 49152, 
+    57344, 61440, 62464, 62976, 62848, 62912, 62896, 62900, 
+        0,     1, 49152, 57344, 61440, 62464, 62976, 62848, 
+    62912, 62896, 62904, 62902,     0,     1, 49152, 57344, 
+    61440, 62464, 62976, 62848, 62912, 62896,     0,     1, 
+    49152, 57344, 61440, 62464, 62976, 62848, 62912, 62913, 
+    62904,     0,     1, 49152, 57344, 61440, 62464, 62976, 
+    62848, 62912, 62913, 62904,     0,     1, 49152, 57344, 
+    61440, 62464, 62976, 62848, 62912, 62913, 62904, 62906, 
+        0,     1, 49152, 57344, 61440, 62464, 62976, 62848, 
+    62912, 62913, 62904,     0,     1, 49152, 57344, 61440, 
+    62464, 62976, 62848, 62912, 62913, 62904, 62908,     0, 
+        1, 49152, 57344, 61440, 62464, 62976, 62848, 62912, 
+    62913, 62915, 62908,     0,     1, 49152, 57344, 61440, 
+    62464, 62976, 62848, 62912, 62913, 62915, 62908, 62910, 
+        0,     1, 49152, 57344, 61440, 62464, 62976, 62848, 
+        0,     1, 49152, 57344, 61440, 62464, 62976, 62977, 
+    62912,     0,     1, 49152, 57344, 61440, 62464, 62976, 
+    62977, 62912,     0,     1, 49152, 57344, 61440, 62464, 
+    62976, 62977, 62912, 62914,     0,     1, 49152, 57344, 
+    61440, 62464, 62976, 62977, 62912,     0,     1, 49152, 
+    57344, 61440, 62464, 62976, 62977, 62912, 62916,     0, 
+        1, 49152, 57344, 61440, 62464, 62976, 62977, 62912, 
+    62916,     0,     1, 49152, 57344, 61440, 62464, 62976, 
+    62977, 62912, 62920, 62918,     0,     1, 49152, 57344, 
+    61440, 62464, 62976, 62977, 62912,     0,     1, 49152, 
+    57344, 61440, 62464, 62976, 62977, 62912, 62920,     0, 
+        1, 49152, 57344, 61440, 62464, 62976, 62977, 62912, 
+    62920,     0,     1, 49152, 57344, 61440, 62464, 62976, 
+    62977, 62912, 62920, 62922,     0,     1, 49152, 57344, 
+    61440, 62464, 62976, 62977, 62912, 62920,     0,     1, 
+    49152, 57344, 61440, 62464, 62976, 62977, 62912, 62928, 
+    62924,     0,     1, 49152, 57344, 61440, 62464, 62976, 
+    62977, 62912, 62928, 62924,     0,     1, 49152, 57344, 
+    61440, 62464, 62976, 62977, 62912, 62928, 62929, 62926, 
+        0,     1, 49152, 57344, 61440, 62464, 62976, 62977, 
+    62912,     0,     1, 49152, 57344, 61440, 62464, 62976, 
+    62977, 62912, 62928,     0,     1, 49152, 57344, 61440, 
+    62464, 62976, 62977, 62912, 62928,     0,     1, 49152, 
+    57344, 61440, 62464, 62976, 62977, 62912, 62928, 62930, 
+        0,     1, 49152, 57344, 61440, 62464, 62976, 62977, 
+    62912, 62928,     0,     1, 49152, 57344, 61440, 62464, 
+    62976, 62977, 62912, 62928, 62932,     0,     1, 49152, 
+    57344, 61440, 62464, 62976, 62977, 62912, 62928, 62932, 
+        0,     1, 49152, 57344, 61440, 62464, 62976, 62977, 
+    62912, 62928, 62936, 62934,     0,     1, 49152, 57344, 
+    61440, 62464, 62976, 62977, 62912, 62928,     0,     1, 
+    49152, 57344, 61440, 62464, 62976, 62977, 62912, 62944, 
+    62936,     0,     1, 49152, 57344, 61440, 62464, 62976, 
+    62977, 62912, 62944, 62936,     0,     1, 49152, 57344, 
+    61440, 62464, 62976, 62977, 62912, 62944, 62936, 62938, 
+        0,     1, 49152, 57344, 61440, 62464, 62976, 62977, 
+    62912, 62944, 62936,     0,     1, 49152, 57344, 61440, 
+    62464, 62976, 62977, 62912, 62944, 62945, 62940,     0, 
+        1, 49152, 57344, 61440, 62464, 62976, 62977, 62912, 
+    62944, 62945, 62940,     0,     1, 49152, 57344, 61440, 
+    62464, 62976, 62977, 62912, 62944, 62945, 62940, 62942, 
+        0,     1, 49152, 57344, 61440, 62464, 62976, 62977, 
+    62912,     0,     1, 49152, 57344, 61440, 62464, 62976, 
+    62977, 62912, 62944,     0,     1, 49152, 57344, 61440, 
+    62464, 62976, 62977, 62979, 62944,     0,     1, 49152, 
+    57344, 61440, 62464, 62976, 62977, 62979, 62944, 62946, 
+        0,     1, 49152, 57344, 61440, 62464, 62976, 62977, 
+    62979, 62944,     0,     1, 49152, 57344, 61440, 62464, 
+    62976, 62977, 62979, 62944, 62948,     0,     1, 49152, 
+    57344, 61440, 62464, 62976, 62977, 62979, 62944, 62948, 
+        0,     1, 49152, 57344, 61440, 62464, 62976, 62977, 
+    62979, 62944, 62952, 62950,     0,     1, 49152, 57344, 
+    61440, 62464, 62976, 62977, 62979, 62944,     0,     1, 
+    49152, 57344, 61440, 62464, 62976, 62977, 62979, 62944, 
+    62952,     0,     1, 49152, 57344, 61440, 62464, 62976, 
+    62977, 62979, 62944, 62952,     0,     1, 49152, 57344, 
+    61440, 62464, 62976, 62977, 62979, 62944, 62952, 62954, 
+        0,     1, 49152, 57344, 61440, 62464, 62976, 62977, 
+    62979, 62944, 62952,     0,     1, 49152, 57344, 61440, 
+    62464, 62976, 62977, 62979, 62944, 62960, 62956,     0, 
+        1, 49152, 57344, 61440, 62464, 62976, 62977, 62979, 
+    62944, 62960, 62956,     0,     1, 49152, 57344, 61440, 
+    62464, 62976, 62977, 62979, 62944, 62960, 62961, 62958, 
+        0,     1, 49152, 57344, 61440, 62464, 62976, 62977, 
+    62979, 62944,     0,     1, 49152, 57344, 61440, 62464, 
+    62976, 62977, 62979, 62944, 62960,     0,     1, 49152, 
+    57344, 61440, 62464, 62976, 62977, 62979, 62944, 62960, 
+        0,     1, 49152, 57344, 61440, 62464, 62976, 62977, 
+    62979, 62944, 62960, 62962,     0,     1, 49152, 57344, 
+    61440, 62464, 62976, 62977, 62979, 62983, 62960,     0, 
+        1, 49152, 57344, 61440, 62464, 62976, 62977, 62979, 
+    62983, 62960, 62964,     0,     1, 49152, 57344, 61440, 
+    62464, 62976, 62977, 62979, 62983, 62960, 62964,     0, 
+        1, 49152, 57344, 61440, 62464, 62976, 62977, 62979, 
+    62983, 62960, 62968, 62966,     0,     1, 49152, 57344, 
+    61440, 62464, 62976, 62977, 62979, 62983, 62960,     0, 
+        1, 49152, 57344, 61440, 62464, 62976, 62977, 62979, 
+    62983, 62960, 62968,     0,     1, 49152, 57344, 61440, 
+    62464, 62976, 62977, 62979, 62983, 62960, 62968,     0, 
+        1, 49152, 57344, 61440, 62464, 62976, 62977, 62979, 
+    62983, 62960, 62968, 62970,     0,     1, 49152, 57344, 
+    61440, 62464, 62976, 62977, 62979, 62983, 62960, 62968, 
+        0,     1, 49152, 57344, 61440, 62464, 62976, 62977, 
+    62979, 62983, 62960, 62968, 62972,     0,     1, 49152, 
+    57344, 61440, 62464, 62976, 62977, 62979, 62983, 62960, 
+    62968, 62972,     0,     1, 49152, 57344, 61440, 62464, 
+    62976, 62977, 62979, 62983, 62960, 62968, 62972, 62974, 
+        0,     1, 49152, 57344, 61440, 62464,     0,     1, 
+    49152, 57344, 61440, 63488, 62976,     0,     1, 49152, 
+    57344, 61440, 63488, 62976,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 62978,     0,     1, 49152, 57344, 
+    61440, 63488, 62976,     0,     1, 49152, 57344, 61440, 
+    63488, 62976, 62980,     0,     1, 49152, 57344, 61440, 
+    63488, 62976, 62980,     0,     1, 49152, 57344, 61440, 
+    63488, 62976, 62984, 62982,     0,     1, 49152, 57344, 
+    61440, 63488, 62976,     0,     1, 49152, 57344, 61440, 
+    63488, 62976, 62984,     0,     1, 49152, 57344, 61440, 
+    63488, 62976, 62984,     0,     1, 49152, 57344, 61440, 
+    63488, 62976, 62984, 62986,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 62984,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 62992, 62988,     0,     1, 49152, 
+    57344, 61440, 63488, 62976, 62992, 62988,     0,     1, 
+    49152, 57344, 61440, 63488, 62976, 62992, 62993, 62990, 
+        0,     1, 49152, 57344, 61440, 63488, 62976,     0, 
+        1, 49152, 57344, 61440, 63488, 62976, 62992,     0, 
+        1, 49152, 57344, 61440, 63488, 62976, 62992,     0, 
+        1, 49152, 57344, 61440, 63488, 62976, 62992, 62994, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 62992, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 62992, 
+    62996,     0,     1, 49152, 57344, 61440, 63488, 62976, 
+    62992, 62996,     0,     1, 49152, 57344, 61440, 63488, 
+    62976, 62992, 63000, 62998,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 62992,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63008, 63000,     0,     1, 49152, 
+    57344, 61440, 63488, 62976, 63008, 63000,     0,     1, 
+    49152, 57344, 61440, 63488, 62976, 63008, 63000, 63002, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 63008, 
+    63000,     0,     1, 49152, 57344, 61440, 63488, 62976, 
+    63008, 63009, 63004,     0,     1, 49152, 57344, 61440, 
+    63488, 62976, 63008, 63009, 63004,     0,     1, 49152, 
+    57344, 61440, 63488, 62976, 63008, 63009, 63004, 63006, 
+        0,     1, 49152, 57344, 61440, 63488, 62976,     0, 
+        1, 49152, 57344, 61440, 63488, 62976, 63008,     0, 
+        1, 49152, 57344, 61440, 63488, 62976, 63008,     0, 
+        1, 49152, 57344, 61440, 63488, 62976, 63008, 63010, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 63008, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 63008, 
+    63012,     0,     1, 49152, 57344, 61440, 63488, 62976, 
+    63008, 63012,     0,     1, 49152, 57344, 61440, 63488, 
+    62976, 63008, 63016, 63014,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63008,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63008, 63016,     0,     1, 49152, 
+    57344, 61440, 63488, 62976, 63008, 63016,     0,     1, 
+    49152, 57344, 61440, 63488, 62976, 63008, 63016, 63018, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 63008, 
+    63016,     0,     1, 49152, 57344, 61440, 63488, 62976, 
+    63008, 63024, 63020,     0,     1, 49152, 57344, 61440, 
+    63488, 62976, 63008, 63024, 63020,     0,     1, 49152, 
+    57344, 61440, 63488, 62976, 63008, 63024, 63025, 63022, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 63008, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 63040, 
+    63024,     0,     1, 49152, 57344, 61440, 63488, 62976, 
+    63040, 63024,     0,     1, 49152, 57344, 61440, 63488, 
+    62976, 63040, 63024, 63026,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63040, 63024,     0,     1, 49152, 
+    57344, 61440, 63488, 62976, 63040, 63024, 63028,     0, 
+        1, 49152, 57344, 61440, 63488, 62976, 63040, 63024, 
+    63028,     0,     1, 49152, 57344, 61440, 63488, 62976, 
+    63040, 63024, 63032, 63030,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63040, 63024,     0,     1, 49152, 
+    57344, 61440, 63488, 62976, 63040, 63041, 63032,     0, 
+        1, 49152, 57344, 61440, 63488, 62976, 63040, 63041, 
+    63032,     0,     1, 49152, 57344, 61440, 63488, 62976, 
+    63040, 63041, 63032, 63034,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63040, 63041, 63032,     0,     1, 
+    49152, 57344, 61440, 63488, 62976, 63040, 63041, 63032, 
+    63036,     0,     1, 49152, 57344, 61440, 63488, 62976, 
+    63040, 63041, 63043, 63036,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63040, 63041, 63043, 63036, 63038, 
+        0,     1, 49152, 57344, 61440, 63488, 62976,     0, 
+        1, 49152, 57344, 61440, 63488, 62976, 63040,     0, 
+        1, 49152, 57344, 61440, 63488, 62976, 63040,     0, 
+        1, 49152, 57344, 61440, 63488, 62976, 63040, 63042, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 63040, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 63040, 
+    63044,     0,     1, 49152, 57344, 61440, 63488, 62976, 
+    63040, 63044,     0,     1, 49152, 57344, 61440, 63488, 
+    62976, 63040, 63048, 63046,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63040,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63040, 63048,     0,     1, 49152, 
+    57344, 61440, 63488, 62976, 63040, 63048,     0,     1, 
+    49152, 57344, 61440, 63488, 62976, 63040, 63048, 63050, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 63040, 
+    63048,     0,     1, 49152, 57344, 61440, 63488, 62976, 
+    63040, 63056, 63052,     0,     1, 49152, 57344, 61440, 
+    63488, 62976, 63040, 63056, 63052,     0,     1, 49152, 
+    57344, 61440, 63488, 62976, 63040, 63056, 63057, 63054, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 63040, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 63040, 
+    63056,     0,     1, 49152, 57344, 61440, 63488, 62976, 
+    63040, 63056,     0,     1, 49152, 57344, 61440, 63488, 
+    62976, 63040, 63056, 63058,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63040, 63056,     0,     1, 49152, 
+    57344, 61440, 63488, 62976, 63040, 63056, 63060,     0, 
+        1, 49152, 57344, 61440, 63488, 62976, 63040, 63056, 
+    63060,     0,     1, 49152, 57344, 61440, 63488, 62976, 
+    63040, 63056, 63064, 63062,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63040, 63056,     0,     1, 49152, 
+    57344, 61440, 63488, 62976, 63040, 63072, 63064,     0, 
+        1, 49152, 57344, 61440, 63488, 62976, 63040, 63072, 
+    63064,     0,     1, 49152, 57344, 61440, 63488, 62976, 
+    63040, 63072, 63064, 63066,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63040, 63072, 63064,     0,     1, 
+    49152, 57344, 61440, 63488, 62976, 63040, 63072, 63073, 
+    63068,     0,     1, 49152, 57344, 61440, 63488, 62976, 
+    63040, 63072, 63073, 63068,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63040, 63072, 63073, 63068, 63070, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 63040, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 63104, 
+    63072,     0,     1, 49152, 57344, 61440, 63488, 62976, 
+    63104, 63072,     0,     1, 49152, 57344, 61440, 63488, 
+    62976, 63104, 63072, 63074,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63104, 63072,     0,     1, 49152, 
+    57344, 61440, 63488, 62976, 63104, 63072, 63076,     0, 
+        1, 49152, 57344, 61440, 63488, 62976, 63104, 63072, 
+    63076,     0,     1, 49152, 57344, 61440, 63488, 62976, 
+    63104, 63072, 63080, 63078,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63104, 63072,     0,     1, 49152, 
+    57344, 61440, 63488, 62976, 63104, 63072, 63080,     0, 
+        1, 49152, 57344, 61440, 63488, 62976, 63104, 63072, 
+    63080,     0,     1, 49152, 57344, 61440, 63488, 62976, 
+    63104, 63072, 63080, 63082,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63104, 63072, 63080,     0,     1, 
+    49152, 57344, 61440, 63488, 62976, 63104, 63072, 63088, 
+    63084,     0,     1, 49152, 57344, 61440, 63488, 62976, 
+    63104, 63072, 63088, 63084,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63104, 63072, 63088, 63089, 63086, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 63104, 
+    63072,     0,     1, 49152, 57344, 61440, 63488, 62976, 
+    63104, 63105, 63088,     0,     1, 49152, 57344, 61440, 
+    63488, 62976, 63104, 63105, 63088,     0,     1, 49152, 
+    57344, 61440, 63488, 62976, 63104, 63105, 63088, 63090, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 63104, 
+    63105, 63088,     0,     1, 49152, 57344, 61440, 63488, 
+    62976, 63104, 63105, 63088, 63092,     0,     1, 49152, 
+    57344, 61440, 63488, 62976, 63104, 63105, 63088, 63092, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 63104, 
+    63105, 63088, 63096, 63094,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63104, 63105, 63088,     0,     1, 
+    49152, 57344, 61440, 63488, 62976, 63104, 63105, 63088, 
+    63096,     0,     1, 49152, 57344, 61440, 63488, 62976, 
+    63104, 63105, 63107, 63096,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63104, 63105, 63107, 63096, 63098, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 63104, 
+    63105, 63107, 63096,     0,     1, 49152, 57344, 61440, 
+    63488, 62976, 63104, 63105, 63107, 63096, 63100,     0, 
+        1, 49152, 57344, 61440, 63488, 62976, 63104, 63105, 
+    63107, 63096, 63100,     0,     1, 49152, 57344, 61440, 
+    63488, 62976, 63104, 63105, 63107, 63096, 63100, 63102, 
+        0,     1, 49152, 57344, 61440, 63488, 62976,     0, 
+        1, 49152, 57344, 61440, 63488, 62976, 63104,     0, 
+        1, 49152, 57344, 61440, 63488, 62976, 63104,     0, 
+        1, 49152, 57344, 61440, 63488, 62976, 63104, 63106, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 63104, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 63104, 
+    63108,     0,     1, 49152, 57344, 61440, 63488, 62976, 
+    63104, 63108,     0,     1, 49152, 57344, 61440, 63488, 
+    62976, 63104, 63112, 63110,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63104,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63104, 63112,     0,     1, 49152, 
+    57344, 61440, 63488, 62976, 63104, 63112,     0,     1, 
+    49152, 57344, 61440, 63488, 62976, 63104, 63112, 63114, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 63104, 
+    63112,     0,     1, 49152, 57344, 61440, 63488, 62976, 
+    63104, 63120, 63116,     0,     1, 49152, 57344, 61440, 
+    63488, 62976, 63104, 63120, 63116,     0,     1, 49152, 
+    57344, 61440, 63488, 62976, 63104, 63120, 63121, 63118, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 63104, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 63104, 
+    63120,     0,     1, 49152, 57344, 61440, 63488, 62976, 
+    63104, 63120,     0,     1, 49152, 57344, 61440, 63488, 
+    62976, 63104, 63120, 63122,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63104, 63120,     0,     1, 49152, 
+    57344, 61440, 63488, 62976, 63104, 63120, 63124,     0, 
+        1, 49152, 57344, 61440, 63488, 62976, 63104, 63120, 
+    63124,     0,     1, 49152, 57344, 61440, 63488, 62976, 
+    63104, 63120, 63128, 63126,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63104, 63120,     0,     1, 49152, 
+    57344, 61440, 63488, 62976, 63104, 63136, 63128,     0, 
+        1, 49152, 57344, 61440, 63488, 62976, 63104, 63136, 
+    63128,     0,     1, 49152, 57344, 61440, 63488, 62976, 
+    63104, 63136, 63128, 63130,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63104, 63136, 63128,     0,     1, 
+    49152, 57344, 61440, 63488, 62976, 63104, 63136, 63137, 
+    63132,     0,     1, 49152, 57344, 61440, 63488, 62976, 
+    63104, 63136, 63137, 63132,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63104, 63136, 63137, 63132, 63134, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 63104, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 63104, 
+    63136,     0,     1, 49152, 57344, 61440, 63488, 62976, 
+    63104, 63136,     0,     1, 49152, 57344, 61440, 63488, 
+    62976, 63104, 63136, 63138,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63104, 63136,     0,     1, 49152, 
+    57344, 61440, 63488, 62976, 63104, 63136, 63140,     0, 
+        1, 49152, 57344, 61440, 63488, 62976, 63104, 63136, 
+    63140,     0,     1, 49152, 57344, 61440, 63488, 62976, 
+    63104, 63136, 63144, 63142,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63104, 63136,     0,     1, 49152, 
+    57344, 61440, 63488, 62976, 63104, 63136, 63144,     0, 
+        1, 49152, 57344, 61440, 63488, 62976, 63104, 63136, 
+    63144,     0,     1, 49152, 57344, 61440, 63488, 62976, 
+    63104, 63136, 63144, 63146,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63104, 63136, 63144,     0,     1, 
+    49152, 57344, 61440, 63488, 62976, 63104, 63136, 63152, 
+    63148,     0,     1, 49152, 57344, 61440, 63488, 62976, 
+    63104, 63136, 63152, 63148,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63104, 63136, 63152, 63153, 63150, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 63104, 
+    63136,     0,     1, 49152, 57344, 61440, 63488, 62976, 
+    63104, 63168, 63152,     0,     1, 49152, 57344, 61440, 
+    63488, 62976, 63104, 63168, 63152,     0,     1, 49152, 
+    57344, 61440, 63488, 62976, 63104, 63168, 63152, 63154, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 63104, 
+    63168, 63152,     0,     1, 49152, 57344, 61440, 63488, 
+    62976, 63104, 63168, 63152, 63156,     0,     1, 49152, 
+    57344, 61440, 63488, 62976, 63104, 63168, 63152, 63156, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 63104, 
+    63168, 63152, 63160, 63158,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63104, 63168, 63152,     0,     1, 
+    49152, 57344, 61440, 63488, 62976, 63104, 63168, 63169, 
+    63160,     0,     1, 49152, 57344, 61440, 63488, 62976, 
+    63104, 63168, 63169, 63160,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63104, 63168, 63169, 63160, 63162, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 63104, 
+    63168, 63169, 63160,     0,     1, 49152, 57344, 61440, 
+    63488, 62976, 63104, 63168, 63169, 63160, 63164,     0, 
+        1, 49152, 57344, 61440, 63488, 62976, 63104, 63168, 
+    63169, 63171, 63164,     0,     1, 49152, 57344, 61440, 
+    63488, 62976, 63104, 63168, 63169, 63171, 63164, 63166, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 63104, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 63232, 
+    63168,     0,     1, 49152, 57344, 61440, 63488, 62976, 
+    63232, 63168,     0,     1, 49152, 57344, 61440, 63488, 
+    62976, 63232, 63168, 63170,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63232, 63168,     0,     1, 49152, 
+    57344, 61440, 63488, 62976, 63232, 63168, 63172,     0, 
+        1, 49152, 57344, 61440, 63488, 62976, 63232, 63168, 
+    63172,     0,     1, 49152, 57344, 61440, 63488, 62976, 
+    63232, 63168, 63176, 63174,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63232, 63168,     0,     1, 49152, 
+    57344, 61440, 63488, 62976, 63232, 63168, 63176,     0, 
+        1, 49152, 57344, 61440, 63488, 62976, 63232, 63168, 
+    63176,     0,     1, 49152, 57344, 61440, 63488, 62976, 
+    63232, 63168, 63176, 63178,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63232, 63168, 63176,     0,     1, 
+    49152, 57344, 61440, 63488, 62976, 63232, 63168, 63184, 
+    63180,     0,     1, 49152, 57344, 61440, 63488, 62976, 
+    63232, 63168, 63184, 63180,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63232, 63168, 63184, 63185, 63182, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 63232, 
+    63168,     0,     1, 49152, 57344, 61440, 63488, 62976, 
+    63232, 63168, 63184,     0,     1, 49152, 57344, 61440, 
+    63488, 62976, 63232, 63168, 63184,     0,     1, 49152, 
+    57344, 61440, 63488, 62976, 63232, 63168, 63184, 63186, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 63232, 
+    63168, 63184,     0,     1, 49152, 57344, 61440, 63488, 
+    62976, 63232, 63168, 63184, 63188,     0,     1, 49152, 
+    57344, 61440, 63488, 62976, 63232, 63168, 63184, 63188, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 63232, 
+    63168, 63184, 63192, 63190,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63232, 63168, 63184,     0,     1, 
+    49152, 57344, 61440, 63488, 62976, 63232, 63168, 63200, 
+    63192,     0,     1, 49152, 57344, 61440, 63488, 62976, 
+    63232, 63168, 63200, 63192,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63232, 63168, 63200, 63192, 63194, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 63232, 
+    63168, 63200, 63192,     0,     1, 49152, 57344, 61440, 
+    63488, 62976, 63232, 63168, 63200, 63201, 63196,     0, 
+        1, 49152, 57344, 61440, 63488, 62976, 63232, 63168, 
+    63200, 63201, 63196,     0,     1, 49152, 57344, 61440, 
+    63488, 62976, 63232, 63168, 63200, 63201, 63196, 63198, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 63232, 
+    63168,     0,     1, 49152, 57344, 61440, 63488, 62976, 
+    63232, 63233, 63200,     0,     1, 49152, 57344, 61440, 
+    63488, 62976, 63232, 63233, 63200,     0,     1, 49152, 
+    57344, 61440, 63488, 62976, 63232, 63233, 63200, 63202, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 63232, 
+    63233, 63200,     0,     1, 49152, 57344, 61440, 63488, 
+    62976, 63232, 63233, 63200, 63204,     0,     1, 49152, 
+    57344, 61440, 63488, 62976, 63232, 63233, 63200, 63204, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 63232, 
+    63233, 63200, 63208, 63206,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63232, 63233, 63200,     0,     1, 
+    49152, 57344, 61440, 63488, 62976, 63232, 63233, 63200, 
+    63208,     0,     1, 49152, 57344, 61440, 63488, 62976, 
+    63232, 63233, 63200, 63208,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63232, 63233, 63200, 63208, 63210, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 63232, 
+    63233, 63200, 63208,     0,     1, 49152, 57344, 61440, 
+    63488, 62976, 63232, 63233, 63200, 63216, 63212,     0, 
+        1, 49152, 57344, 61440, 63488, 62976, 63232, 63233, 
+    63200, 63216, 63212,     0,     1, 49152, 57344, 61440, 
+    63488, 62976, 63232, 63233, 63200, 63216, 63217, 63214, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 63232, 
+    63233, 63200,     0,     1, 49152, 57344, 61440, 63488, 
+    62976, 63232, 63233, 63200, 63216,     0,     1, 49152, 
+    57344, 61440, 63488, 62976, 63232, 63233, 63235, 63216, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 63232, 
+    63233, 63235, 63216, 63218,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63232, 63233, 63235, 63216,     0, 
+        1, 49152, 57344, 61440, 63488, 62976, 63232, 63233, 
+    63235, 63216, 63220,     0,     1, 49152, 57344, 61440, 
+    63488, 62976, 63232, 63233, 63235, 63216, 63220,     0, 
+        1, 49152, 57344, 61440, 63488, 62976, 63232, 63233, 
+    63235, 63216, 63224, 63222,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63232, 63233, 63235, 63216,     0, 
+        1, 49152, 57344, 61440, 63488, 62976, 63232, 63233, 
+    63235, 63216, 63224,     0,     1, 49152, 57344, 61440, 
+    63488, 62976, 63232, 63233, 63235, 63216, 63224,     0, 
+        1, 49152, 57344, 61440, 63488, 62976, 63232, 63233, 
+    63235, 63216, 63224, 63226,     0,     1, 49152, 57344, 
+    61440, 63488, 62976, 63232, 63233, 63235, 63239, 63224, 
+        0,     1, 49152, 57344, 61440, 63488, 62976, 63232, 
+    63233, 63235, 63239, 63224, 63228,     0,     1, 49152, 
+    57344, 61440, 63488, 62976, 63232, 63233, 63235, 63239, 
+    63224, 63228,     0,     1, 49152, 57344, 61440, 63488, 
+    62976, 63232, 63233, 63235, 63239, 63224, 63228, 63230, 
+        0,     1, 49152, 57344, 61440, 63488, 62976,     0, 
+        1, 49152, 57344, 61440, 63488, 62976, 63232,     0, 
+        1, 49152, 57344, 61440, 63488, 63489, 63232,     0, 
+        1, 49152, 57344, 61440, 63488, 63489, 63232, 63234, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63232, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63232, 
+    63236,     0,     1, 49152, 57344, 61440, 63488, 63489, 
+    63232, 63236,     0,     1, 49152, 57344, 61440, 63488, 
+    63489, 63232, 63240, 63238,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63232,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63232, 63240,     0,     1, 49152, 
+    57344, 61440, 63488, 63489, 63232, 63240,     0,     1, 
+    49152, 57344, 61440, 63488, 63489, 63232, 63240, 63242, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63232, 
+    63240,     0,     1, 49152, 57344, 61440, 63488, 63489, 
+    63232, 63248, 63244,     0,     1, 49152, 57344, 61440, 
+    63488, 63489, 63232, 63248, 63244,     0,     1, 49152, 
+    57344, 61440, 63488, 63489, 63232, 63248, 63249, 63246, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63232, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63232, 
+    63248,     0,     1, 49152, 57344, 61440, 63488, 63489, 
+    63232, 63248,     0,     1, 49152, 57344, 61440, 63488, 
+    63489, 63232, 63248, 63250,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63232, 63248,     0,     1, 49152, 
+    57344, 61440, 63488, 63489, 63232, 63248, 63252,     0, 
+        1, 49152, 57344, 61440, 63488, 63489, 63232, 63248, 
+    63252,     0,     1, 49152, 57344, 61440, 63488, 63489, 
+    63232, 63248, 63256, 63254,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63232, 63248,     0,     1, 49152, 
+    57344, 61440, 63488, 63489, 63232, 63264, 63256,     0, 
+        1, 49152, 57344, 61440, 63488, 63489, 63232, 63264, 
+    63256,     0,     1, 49152, 57344, 61440, 63488, 63489, 
+    63232, 63264, 63256, 63258,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63232, 63264, 63256,     0,     1, 
+    49152, 57344, 61440, 63488, 63489, 63232, 63264, 63265, 
+    63260,     0,     1, 49152, 57344, 61440, 63488, 63489, 
+    63232, 63264, 63265, 63260,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63232, 63264, 63265, 63260, 63262, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63232, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63232, 
+    63264,     0,     1, 49152, 57344, 61440, 63488, 63489, 
+    63232, 63264,     0,     1, 49152, 57344, 61440, 63488, 
+    63489, 63232, 63264, 63266,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63232, 63264,     0,     1, 49152, 
+    57344, 61440, 63488, 63489, 63232, 63264, 63268,     0, 
+        1, 49152, 57344, 61440, 63488, 63489, 63232, 63264, 
+    63268,     0,     1, 49152, 57344, 61440, 63488, 63489, 
+    63232, 63264, 63272, 63270,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63232, 63264,     0,     1, 49152, 
+    57344, 61440, 63488, 63489, 63232, 63264, 63272,     0, 
+        1, 49152, 57344, 61440, 63488, 63489, 63232, 63264, 
+    63272,     0,     1, 49152, 57344, 61440, 63488, 63489, 
+    63232, 63264, 63272, 63274,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63232, 63264, 63272,     0,     1, 
+    49152, 57344, 61440, 63488, 63489, 63232, 63264, 63280, 
+    63276,     0,     1, 49152, 57344, 61440, 63488, 63489, 
+    63232, 63264, 63280, 63276,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63232, 63264, 63280, 63281, 63278, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63232, 
+    63264,     0,     1, 49152, 57344, 61440, 63488, 63489, 
+    63232, 63296, 63280,     0,     1, 49152, 57344, 61440, 
+    63488, 63489, 63232, 63296, 63280,     0,     1, 49152, 
+    57344, 61440, 63488, 63489, 63232, 63296, 63280, 63282, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63232, 
+    63296, 63280,     0,     1, 49152, 57344, 61440, 63488, 
+    63489, 63232, 63296, 63280, 63284,     0,     1, 49152, 
+    57344, 61440, 63488, 63489, 63232, 63296, 63280, 63284, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63232, 
+    63296, 63280, 63288, 63286,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63232, 63296, 63280,     0,     1, 
+    49152, 57344, 61440, 63488, 63489, 63232, 63296, 63297, 
+    63288,     0,     1, 49152, 57344, 61440, 63488, 63489, 
+    63232, 63296, 63297, 63288,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63232, 63296, 63297, 63288, 63290, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63232, 
+    63296, 63297, 63288,     0,     1, 49152, 57344, 61440, 
+    63488, 63489, 63232, 63296, 63297, 63288, 63292,     0, 
+        1, 49152, 57344, 61440, 63488, 63489, 63232, 63296, 
+    63297, 63299, 63292,     0,     1, 49152, 57344, 61440, 
+    63488, 63489, 63232, 63296, 63297, 63299, 63292, 63294, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63232, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63232, 
+    63296,     0,     1, 49152, 57344, 61440, 63488, 63489, 
+    63232, 63296,     0,     1, 49152, 57344, 61440, 63488, 
+    63489, 63232, 63296, 63298,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63232, 63296,     0,     1, 49152, 
+    57344, 61440, 63488, 63489, 63232, 63296, 63300,     0, 
+        1, 49152, 57344, 61440, 63488, 63489, 63232, 63296, 
+    63300,     0,     1, 49152, 57344, 61440, 63488, 63489, 
+    63232, 63296, 63304, 63302,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63232, 63296,     0,     1, 49152, 
+    57344, 61440, 63488, 63489, 63232, 63296, 63304,     0, 
+        1, 49152, 57344, 61440, 63488, 63489, 63232, 63296, 
+    63304,     0,     1, 49152, 57344, 61440, 63488, 63489, 
+    63232, 63296, 63304, 63306,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63232, 63296, 63304,     0,     1, 
+    49152, 57344, 61440, 63488, 63489, 63232, 63296, 63312, 
+    63308,     0,     1, 49152, 57344, 61440, 63488, 63489, 
+    63232, 63296, 63312, 63308,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63232, 63296, 63312, 63313, 63310, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63232, 
+    63296,     0,     1, 49152, 57344, 61440, 63488, 63489, 
+    63232, 63296, 63312,     0,     1, 49152, 57344, 61440, 
+    63488, 63489, 63232, 63296, 63312,     0,     1, 49152, 
+    57344, 61440, 63488, 63489, 63232, 63296, 63312, 63314, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63232, 
+    63296, 63312,     0,     1, 49152, 57344, 61440, 63488, 
+    63489, 63232, 63296, 63312, 63316,     0,     1, 49152, 
+    57344, 61440, 63488, 63489, 63232, 63296, 63312, 63316, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63232, 
+    63296, 63312, 63320, 63318,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63232, 63296, 63312,     0,     1, 
+    49152, 57344, 61440, 63488, 63489, 63232, 63296, 63328, 
+    63320,     0,     1, 49152, 57344, 61440, 63488, 63489, 
+    63232, 63296, 63328, 63320,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63232, 63296, 63328, 63320, 63322, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63232, 
+    63296, 63328, 63320,     0,     1, 49152, 57344, 61440, 
+    63488, 63489, 63232, 63296, 63328, 63329, 63324,     0, 
+        1, 49152, 57344, 61440, 63488, 63489, 63232, 63296, 
+    63328, 63329, 63324,     0,     1, 49152, 57344, 61440, 
+    63488, 63489, 63232, 63296, 63328, 63329, 63324, 63326, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63232, 
+    63296,     0,     1, 49152, 57344, 61440, 63488, 63489, 
+    63232, 63360, 63328,     0,     1, 49152, 57344, 61440, 
+    63488, 63489, 63232, 63360, 63328,     0,     1, 49152, 
+    57344, 61440, 63488, 63489, 63232, 63360, 63328, 63330, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63232, 
+    63360, 63328,     0,     1, 49152, 57344, 61440, 63488, 
+    63489, 63232, 63360, 63328, 63332,     0,     1, 49152, 
+    57344, 61440, 63488, 63489, 63232, 63360, 63328, 63332, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63232, 
+    63360, 63328, 63336, 63334,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63232, 63360, 63328,     0,     1, 
+    49152, 57344, 61440, 63488, 63489, 63232, 63360, 63328, 
+    63336,     0,     1, 49152, 57344, 61440, 63488, 63489, 
+    63232, 63360, 63328, 63336,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63232, 63360, 63328, 63336, 63338, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63232, 
+    63360, 63328, 63336,     0,     1, 49152, 57344, 61440, 
+    63488, 63489, 63232, 63360, 63328, 63344, 63340,     0, 
+        1, 49152, 57344, 61440, 63488, 63489, 63232, 63360, 
+    63328, 63344, 63340,     0,     1, 49152, 57344, 61440, 
+    63488, 63489, 63232, 63360, 63328, 63344, 63345, 63342, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63232, 
+    63360, 63328,     0,     1, 49152, 57344, 61440, 63488, 
+    63489, 63232, 63360, 63361, 63344,     0,     1, 49152, 
+    57344, 61440, 63488, 63489, 63232, 63360, 63361, 63344, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63232, 
+    63360, 63361, 63344, 63346,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63232, 63360, 63361, 63344,     0, 
+        1, 49152, 57344, 61440, 63488, 63489, 63232, 63360, 
+    63361, 63344, 63348,     0,     1, 49152, 57344, 61440, 
+    63488, 63489, 63232, 63360, 63361, 63344, 63348,     0, 
+        1, 49152, 57344, 61440, 63488, 63489, 63232, 63360, 
+    63361, 63344, 63352, 63350,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63232, 63360, 63361, 63344,     0, 
+        1, 49152, 57344, 61440, 63488, 63489, 63232, 63360, 
+    63361, 63344, 63352,     0,     1, 49152, 57344, 61440, 
+    63488, 63489, 63232, 63360, 63361, 63363, 63352,     0, 
+        1, 49152, 57344, 61440, 63488, 63489, 63232, 63360, 
+    63361, 63363, 63352, 63354,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63232, 63360, 63361, 63363, 63352, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63232, 
+    63360, 63361, 63363, 63352, 63356,     0,     1, 49152, 
+    57344, 61440, 63488, 63489, 63232, 63360, 63361, 63363, 
+    63352, 63356,     0,     1, 49152, 57344, 61440, 63488, 
+    63489, 63232, 63360, 63361, 63363, 63352, 63356, 63358, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63232, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63232, 
+    63360,     0,     1, 49152, 57344, 61440, 63488, 63489, 
+    63232, 63360,     0,     1, 49152, 57344, 61440, 63488, 
+    63489, 63232, 63360, 63362,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63491, 63360,     0,     1, 49152, 
+    57344, 61440, 63488, 63489, 63491, 63360, 63364,     0, 
+        1, 49152, 57344, 61440, 63488, 63489, 63491, 63360, 
+    63364,     0,     1, 49152, 57344, 61440, 63488, 63489, 
+    63491, 63360, 63368, 63366,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63491, 63360,     0,     1, 49152, 
+    57344, 61440, 63488, 63489, 63491, 63360, 63368,     0, 
+        1, 49152, 57344, 61440, 63488, 63489, 63491, 63360, 
+    63368,     0,     1, 49152, 57344, 61440, 63488, 63489, 
+    63491, 63360, 63368, 63370,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63491, 63360, 63368,     0,     1, 
+    49152, 57344, 61440, 63488, 63489, 63491, 63360, 63376, 
+    63372,     0,     1, 49152, 57344, 61440, 63488, 63489, 
+    63491, 63360, 63376, 63372,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63491, 63360, 63376, 63377, 63374, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63491, 
+    63360,     0,     1, 49152, 57344, 61440, 63488, 63489, 
+    63491, 63360, 63376,     0,     1, 49152, 57344, 61440, 
+    63488, 63489, 63491, 63360, 63376,     0,     1, 49152, 
+    57344, 61440, 63488, 63489, 63491, 63360, 63376, 63378, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63491, 
+    63360, 63376,     0,     1, 49152, 57344, 61440, 63488, 
+    63489, 63491, 63360, 63376, 63380,     0,     1, 49152, 
+    57344, 61440, 63488, 63489, 63491, 63360, 63376, 63380, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63491, 
+    63360, 63376, 63384, 63382,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63491, 63360, 63376,     0,     1, 
+    49152, 57344, 61440, 63488, 63489, 63491, 63360, 63392, 
+    63384,     0,     1, 49152, 57344, 61440, 63488, 63489, 
+    63491, 63360, 63392, 63384,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63491, 63360, 63392, 63384, 63386, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63491, 
+    63360, 63392, 63384,     0,     1, 49152, 57344, 61440, 
+    63488, 63489, 63491, 63360, 63392, 63393, 63388,     0, 
+        1, 49152, 57344, 61440, 63488, 63489, 63491, 63360, 
+    63392, 63393, 63388,     0,     1, 49152, 57344, 61440, 
+    63488, 63489, 63491, 63360, 63392, 63393, 63388, 63390, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63491, 
+    63360,     0,     1, 49152, 57344, 61440, 63488, 63489, 
+    63491, 63360, 63392,     0,     1, 49152, 57344, 61440, 
+    63488, 63489, 63491, 63360, 63392,     0,     1, 49152, 
+    57344, 61440, 63488, 63489, 63491, 63360, 63392, 63394, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63491, 
+    63360, 63392,     0,     1, 49152, 57344, 61440, 63488, 
+    63489, 63491, 63360, 63392, 63396,     0,     1, 49152, 
+    57344, 61440, 63488, 63489, 63491, 63360, 63392, 63396, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63491, 
+    63360, 63392, 63400, 63398,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63491, 63360, 63392,     0,     1, 
+    49152, 57344, 61440, 63488, 63489, 63491, 63360, 63392, 
+    63400,     0,     1, 49152, 57344, 61440, 63488, 63489, 
+    63491, 63360, 63392, 63400,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63491, 63360, 63392, 63400, 63402, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63491, 
+    63360, 63392, 63400,     0,     1, 49152, 57344, 61440, 
+    63488, 63489, 63491, 63360, 63392, 63408, 63404,     0, 
+        1, 49152, 57344, 61440, 63488, 63489, 63491, 63360, 
+    63392, 63408, 63404,     0,     1, 49152, 57344, 61440, 
+    63488, 63489, 63491, 63360, 63392, 63408, 63409, 63406, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63491, 
+    63360, 63392,     0,     1, 49152, 57344, 61440, 63488, 
+    63489, 63491, 63360, 63424, 63408,     0,     1, 49152, 
+    57344, 61440, 63488, 63489, 63491, 63360, 63424, 63408, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63491, 
+    63360, 63424, 63408, 63410,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63491, 63360, 63424, 63408,     0, 
+        1, 49152, 57344, 61440, 63488, 63489, 63491, 63360, 
+    63424, 63408, 63412,     0,     1, 49152, 57344, 61440, 
+    63488, 63489, 63491, 63360, 63424, 63408, 63412,     0, 
+        1, 49152, 57344, 61440, 63488, 63489, 63491, 63360, 
+    63424, 63408, 63416, 63414,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63491, 63360, 63424, 63408,     0, 
+        1, 49152, 57344, 61440, 63488, 63489, 63491, 63360, 
+    63424, 63425, 63416,     0,     1, 49152, 57344, 61440, 
+    63488, 63489, 63491, 63360, 63424, 63425, 63416,     0, 
+        1, 49152, 57344, 61440, 63488, 63489, 63491, 63360, 
+    63424, 63425, 63416, 63418,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63491, 63360, 63424, 63425, 63416, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63491, 
+    63360, 63424, 63425, 63416, 63420,     0,     1, 49152, 
+    57344, 61440, 63488, 63489, 63491, 63360, 63424, 63425, 
+    63427, 63420,     0,     1, 49152, 57344, 61440, 63488, 
+    63489, 63491, 63360, 63424, 63425, 63427, 63420, 63422, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63491, 
+    63360,     0,     1, 49152, 57344, 61440, 63488, 63489, 
+    63491, 63360, 63424,     0,     1, 49152, 57344, 61440, 
+    63488, 63489, 63491, 63360, 63424,     0,     1, 49152, 
+    57344, 61440, 63488, 63489, 63491, 63360, 63424, 63426, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63491, 
+    63360, 63424,     0,     1, 49152, 57344, 61440, 63488, 
+    63489, 63491, 63360, 63424, 63428,     0,     1, 49152, 
+    57344, 61440, 63488, 63489, 63491, 63360, 63424, 63428, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63491, 
+    63360, 63424, 63432, 63430,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63491, 63495, 63424,     0,     1, 
+    49152, 57344, 61440, 63488, 63489, 63491, 63495, 63424, 
+    63432,     0,     1, 49152, 57344, 61440, 63488, 63489, 
+    63491, 63495, 63424, 63432,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63491, 63495, 63424, 63432, 63434, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63491, 
+    63495, 63424, 63432,     0,     1, 49152, 57344, 61440, 
+    63488, 63489, 63491, 63495, 63424, 63440, 63436,     0, 
+        1, 49152, 57344, 61440, 63488, 63489, 63491, 63495, 
+    63424, 63440, 63436,     0,     1, 49152, 57344, 61440, 
+    63488, 63489, 63491, 63495, 63424, 63440, 63441, 63438, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63491, 
+    63495, 63424,     0,     1, 49152, 57344, 61440, 63488, 
+    63489, 63491, 63495, 63424, 63440,     0,     1, 49152, 
+    57344, 61440, 63488, 63489, 63491, 63495, 63424, 63440, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63491, 
+    63495, 63424, 63440, 63442,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63491, 63495, 63424, 63440,     0, 
+        1, 49152, 57344, 61440, 63488, 63489, 63491, 63495, 
+    63424, 63440, 63444,     0,     1, 49152, 57344, 61440, 
+    63488, 63489, 63491, 63495, 63424, 63440, 63444,     0, 
+        1, 49152, 57344, 61440, 63488, 63489, 63491, 63495, 
+    63424, 63440, 63448, 63446,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63491, 63495, 63424, 63440,     0, 
+        1, 49152, 57344, 61440, 63488, 63489, 63491, 63495, 
+    63424, 63456, 63448,     0,     1, 49152, 57344, 61440, 
+    63488, 63489, 63491, 63495, 63424, 63456, 63448,     0, 
+        1, 49152, 57344, 61440, 63488, 63489, 63491, 63495, 
+    63424, 63456, 63448, 63450,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63491, 63495, 63424, 63456, 63448, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63491, 
+    63495, 63424, 63456, 63457, 63452,     0,     1, 49152, 
+    57344, 61440, 63488, 63489, 63491, 63495, 63424, 63456, 
+    63457, 63452,     0,     1, 49152, 57344, 61440, 63488, 
+    63489, 63491, 63495, 63424, 63456, 63457, 63452, 63454, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63491, 
+    63495, 63424,     0,     1, 49152, 57344, 61440, 63488, 
+    63489, 63491, 63495, 63424, 63456,     0,     1, 49152, 
+    57344, 61440, 63488, 63489, 63491, 63495, 63424, 63456, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63491, 
+    63495, 63424, 63456, 63458,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63491, 63495, 63424, 63456,     0, 
+        1, 49152, 57344, 61440, 63488, 63489, 63491, 63495, 
+    63424, 63456, 63460,     0,     1, 49152, 57344, 61440, 
+    63488, 63489, 63491, 63495, 63424, 63456, 63460,     0, 
+        1, 49152, 57344, 61440, 63488, 63489, 63491, 63495, 
+    63424, 63456, 63464, 63462,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63491, 63495, 63424, 63456,     0, 
+        1, 49152, 57344, 61440, 63488, 63489, 63491, 63495, 
+    63424, 63456, 63464,     0,     1, 49152, 57344, 61440, 
+    63488, 63489, 63491, 63495, 63424, 63456, 63464,     0, 
+        1, 49152, 57344, 61440, 63488, 63489, 63491, 63495, 
+    63424, 63456, 63464, 63466,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63491, 63495, 63424, 63456, 63464, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63491, 
+    63495, 63424, 63456, 63472, 63468,     0,     1, 49152, 
+    57344, 61440, 63488, 63489, 63491, 63495, 63424, 63456, 
+    63472, 63468,     0,     1, 49152, 57344, 61440, 63488, 
+    63489, 63491, 63495, 63424, 63456, 63472, 63473, 63470, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63491, 
+    63495, 63503, 63456,     0,     1, 49152, 57344, 61440, 
+    63488, 63489, 63491, 63495, 63503, 63456, 63472,     0, 
+        1, 49152, 57344, 61440, 63488, 63489, 63491, 63495, 
+    63503, 63456, 63472,     0,     1, 49152, 57344, 61440, 
+    63488, 63489, 63491, 63495, 63503, 63456, 63472, 63474, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63491, 
+    63495, 63503, 63456, 63472,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63491, 63495, 63503, 63456, 63472, 
+    63476,     0,     1, 49152, 57344, 61440, 63488, 63489, 
+    63491, 63495, 63503, 63456, 63472, 63476,     0,     1, 
+    49152, 57344, 61440, 63488, 63489, 63491, 63495, 63503, 
+    63456, 63472, 63480, 63478,     0,     1, 49152, 57344, 
+    61440, 63488, 63489, 63491, 63495, 63503, 63456, 63472, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63491, 
+    63495, 63503, 63456, 63472, 63480,     0,     1, 49152, 
+    57344, 61440, 63488, 63489, 63491, 63495, 63503, 63456, 
+    63472, 63480,     0,     1, 49152, 57344, 61440, 63488, 
+    63489, 63491, 63495, 63503, 63456, 63472, 63480, 63482, 
+        0,     1, 49152, 57344, 61440, 63488, 63489, 63491, 
+    63495, 63503, 63456, 63472, 63480,     0,     1, 49152, 
+    57344, 61440, 63488, 63489, 63491, 63495, 63503, 63456, 
+    63472, 63480, 63484,     0,     1, 49152, 57344, 61440, 
+    63488, 63489, 63491, 63495, 63503, 63456, 63472, 63480, 
+    63484,     0,     1, 49152, 57344, 61440, 63488, 63489, 
+    63491, 63495, 63503, 63456, 63472, 63480, 63484, 63486, 
+        0,     1, 49152, 57344, 61440,     0,     1, 49152, 
+    57344, 61440, 63488,     0,     1, 49152, 57344, 61440, 
+    63488,     0,     1, 49152, 57344, 61440, 63488, 63490, 
+        0,     1, 49152, 57344, 61440, 63488,     0,     1, 
+    49152, 57344, 61440, 63488, 63492,     0,     1, 49152, 
+    57344, 61440, 63488, 63492,     0,     1, 49152, 57344, 
+    61440, 63488, 63496, 63494,     0,     1, 49152, 57344, 
+    61440, 63488,     0,     1, 49152, 57344, 61440, 63488, 
+    63496,     0,     1, 49152, 57344, 61440, 63488, 63496, 
+        0,     1, 49152, 57344, 61440, 63488, 63496, 63498, 
+        0,     1, 49152, 57344, 61440, 63488, 63496,     0, 
+        1, 49152, 57344, 61440, 63488, 63504, 63500,     0, 
+        1, 49152, 57344, 61440, 63488, 63504, 63500,     0, 
+        1, 49152, 57344, 61440, 63488, 63504, 63505, 63502, 
+        0,     1, 49152, 57344, 61440, 63488,     0,     1, 
+    49152, 57344, 61440, 63488, 63504,     0,     1, 49152, 
+    57344, 61440, 63488, 63504,     0,     1, 49152, 57344, 
+    61440, 63488, 63504, 63506,     0,     1, 49152, 57344, 
+    61440, 63488, 63504,     0,     1, 49152, 57344, 61440, 
+    63488, 63504, 63508,     0,     1, 49152, 57344, 61440, 
+    63488, 63504, 63508,     0,     1, 49152, 57344, 61440, 
+    63488, 63504, 63512, 63510,     0,     1, 49152, 57344, 
+    61440, 63488, 63504,     0,     1, 49152, 57344, 61440, 
+    63488, 63520, 63512,     0,     1, 49152, 57344, 61440, 
+    63488, 63520, 63512,     0,     1, 49152, 57344, 61440, 
+    63488, 63520, 63512, 63514,     0,     1, 49152, 57344, 
+    61440, 63488, 63520, 63512,     0,     1, 49152, 57344, 
+    61440, 63488, 63520, 63521, 63516,     0,     1, 49152, 
+    57344, 61440, 63488, 63520, 63521, 63516,     0,     1, 
+    49152, 57344, 61440, 63488, 63520, 63521, 63516, 63518, 
+        0,     1, 49152, 57344, 61440, 63488,     0,     1, 
+    49152, 57344, 61440, 63488, 63520,     0,     1, 49152, 
+    57344, 61440, 63488, 63520,     0,     1, 49152, 57344, 
+    61440, 63488, 63520, 63522,     0,     1, 49152, 57344, 
+    61440, 63488, 63520,     0,     1, 49152, 57344, 61440, 
+    63488, 63520, 63524,     0,     1, 49152, 57344, 61440, 
+    63488, 63520, 63524,     0,     1, 49152, 57344, 61440, 
+    63488, 63520, 63528, 63526,     0,     1, 49152, 57344, 
+    61440, 63488, 63520,     0,     1, 49152, 57344, 61440, 
+    63488, 63520, 63528,     0,     1, 49152, 57344, 61440, 
+    63488, 63520, 63528,     0,     1, 49152, 57344, 61440, 
+    63488, 63520, 63528, 63530,     0,     1, 49152, 57344, 
+    61440, 63488, 63520, 63528,     0,     1, 49152, 57344, 
+    61440, 63488, 63520, 63536, 63532,     0,     1, 49152, 
+    57344, 61440, 63488, 63520, 63536, 63532,     0,     1, 
+    49152, 57344, 61440, 63488, 63520, 63536, 63537, 63534, 
+        0,     1, 49152, 57344, 61440, 63488, 63520,     0, 
+        1, 49152, 57344, 61440, 63488, 63552, 63536,     0, 
+        1, 49152, 57344, 61440, 63488, 63552, 63536,     0, 
+        1, 49152, 57344, 61440, 63488, 63552, 63536, 63538, 
+        0,     1, 49152, 57344, 61440, 63488, 63552, 63536, 
+        0,     1, 49152, 57344, 61440, 63488, 63552, 63536, 
+    63540,     0,     1, 49152, 57344, 61440, 63488, 63552, 
+    63536, 63540,     0,     1, 49152, 57344, 61440, 63488, 
+    63552, 63536, 63544, 63542,     0,     1, 49152, 57344, 
+    61440, 63488, 63552, 63536,     0,     1, 49152, 57344, 
+    61440, 63488, 63552, 63553, 63544,     0,     1, 49152, 
+    57344, 61440, 63488, 63552, 63553, 63544,     0,     1, 
+    49152, 57344, 61440, 63488, 63552, 63553, 63544, 63546, 
+        0,     1, 49152, 57344, 61440, 63488, 63552, 63553, 
+    63544,     0,     1, 49152, 57344, 61440, 63488, 63552, 
+    63553, 63544, 63548,     0,     1, 49152, 57344, 61440, 
+    63488, 63552, 63553, 63555, 63548,     0,     1, 49152, 
+    57344, 61440, 63488, 63552, 63553, 63555, 63548, 63550, 
+        0,     1, 49152, 57344, 61440, 63488,     0,     1, 
+    49152, 57344, 61440, 63488, 63552,     0,     1, 49152, 
+    57344, 61440, 63488, 63552,     0,     1, 49152, 57344, 
+    61440, 63488, 63552, 63554,     0,     1, 49152, 57344, 
+    61440, 63488, 63552,     0,     1, 49152, 57344, 61440, 
+    63488, 63552, 63556,     0,     1, 49152, 57344, 61440, 
+    63488, 63552, 63556,     0,     1, 49152, 57344, 61440, 
+    63488, 63552, 63560, 63558,     0,     1, 49152, 57344, 
+    61440, 63488, 63552,     0,     1, 49152, 57344, 61440, 
+    63488, 63552, 63560,     0,     1, 49152, 57344, 61440, 
+    63488, 63552, 63560,     0,     1, 49152, 57344, 61440, 
+    63488, 63552, 63560, 63562,     0,     1, 49152, 57344, 
+    61440, 63488, 63552, 63560,     0,     1, 49152, 57344, 
+    61440, 63488, 63552, 63568, 63564,     0,     1, 49152, 
+    57344, 61440, 63488, 63552, 63568, 63564,     0,     1, 
+    49152, 57344, 61440, 63488, 63552, 63568, 63569, 63566, 
+        0,     1, 49152, 57344, 61440, 63488, 63552,     0, 
+        1, 49152, 57344, 61440, 63488, 63552, 63568,     0, 
+        1, 49152, 57344, 61440, 63488, 63552, 63568,     0, 
+        1, 49152, 57344, 61440, 63488, 63552, 63568, 63570, 
+        0,     1, 49152, 57344, 61440, 63488, 63552, 63568, 
+        0,     1, 49152, 57344, 61440, 63488, 63552, 63568, 
+    63572,     0,     1, 49152, 57344, 61440, 63488, 63552, 
+    63568, 63572,     0,     1, 49152, 57344, 61440, 63488, 
+    63552, 63568, 63576, 63574,     0,     1, 49152, 57344, 
+    61440, 63488, 63552, 63568,     0,     1, 49152, 57344, 
+    61440, 63488, 63552, 63584, 63576,     0,     1, 49152, 
+    57344, 61440, 63488, 63552, 63584, 63576,     0,     1, 
+    49152, 57344, 61440, 63488, 63552, 63584, 63576, 63578, 
+        0,     1, 49152, 57344, 61440, 63488, 63552, 63584, 
+    63576,     0,     1, 49152, 57344, 61440, 63488, 63552, 
+    63584, 63585, 63580,     0,     1, 49152, 57344, 61440, 
+    63488, 63552, 63584, 63585, 63580,     0,     1, 49152, 
+    57344, 61440, 63488, 63552, 63584, 63585, 63580, 63582, 
+        0,     1, 49152, 57344, 61440, 63488, 63552,     0, 
+        1, 49152, 57344, 61440, 63488, 63616, 63584,     0, 
+        1, 49152, 57344, 61440, 63488, 63616, 63584,     0, 
+        1, 49152, 57344, 61440, 63488, 63616, 63584, 63586, 
+        0,     1, 49152, 57344, 61440, 63488, 63616, 63584, 
+        0,     1, 49152, 57344, 61440, 63488, 63616, 63584, 
+    63588,     0,     1, 49152, 57344, 61440, 63488, 63616, 
+    63584, 63588,     0,     1, 49152, 57344, 61440, 63488, 
+    63616, 63584, 63592, 63590,     0,     1, 49152, 57344, 
+    61440, 63488, 63616, 63584,     0,     1, 49152, 57344, 
+    61440, 63488, 63616, 63584, 63592,     0,     1, 49152, 
+    57344, 61440, 63488, 63616, 63584, 63592,     0,     1, 
+    49152, 57344, 61440, 63488, 63616, 63584, 63592, 63594, 
+        0,     1, 49152, 57344, 61440, 63488, 63616, 63584, 
+    63592,     0,     1, 49152, 57344, 61440, 63488, 63616, 
+    63584, 63600, 63596,     0,     1, 49152, 57344, 61440, 
+    63488, 63616, 63584, 63600, 63596,     0,     1, 49152, 
+    57344, 61440, 63488, 63616, 63584, 63600, 63601, 63598, 
+        0,     1, 49152, 57344, 61440, 63488, 63616, 63584, 
+        0,     1, 49152, 57344, 61440, 63488, 63616, 63617, 
+    63600,     0,     1, 49152, 57344, 61440, 63488, 63616, 
+    63617, 63600,     0,     1, 49152, 57344, 61440, 63488, 
+    63616, 63617, 63600, 63602,     0,     1, 49152, 57344, 
+    61440, 63488, 63616, 63617, 63600,     0,     1, 49152, 
+    57344, 61440, 63488, 63616, 63617, 63600, 63604,     0, 
+        1, 49152, 57344, 61440, 63488, 63616, 63617, 63600, 
+    63604,     0,     1, 49152, 57344, 61440, 63488, 63616, 
+    63617, 63600, 63608, 63606,     0,     1, 49152, 57344, 
+    61440, 63488, 63616, 63617, 63600,     0,     1, 49152, 
+    57344, 61440, 63488, 63616, 63617, 63600, 63608,     0, 
+        1, 49152, 57344, 61440, 63488, 63616, 63617, 63619, 
+    63608,     0,     1, 49152, 57344, 61440, 63488, 63616, 
+    63617, 63619, 63608, 63610,     0,     1, 49152, 57344, 
+    61440, 63488, 63616, 63617, 63619, 63608,     0,     1, 
+    49152, 57344, 61440, 63488, 63616, 63617, 63619, 63608, 
+    63612,     0,     1, 49152, 57344, 61440, 63488, 63616, 
+    63617, 63619, 63608, 63612,     0,     1, 49152, 57344, 
+    61440, 63488, 63616, 63617, 63619, 63608, 63612, 63614, 
+        0,     1, 49152, 57344, 61440, 63488,     0,     1, 
+    49152, 57344, 61440, 63488, 63616,     0,     1, 49152, 
+    57344, 61440, 63488, 63616,     0,     1, 49152, 57344, 
+    61440, 63488, 63616, 63618,     0,     1, 49152, 57344, 
+    61440, 63488, 63616,     0,     1, 49152, 57344, 61440, 
+    63488, 63616, 63620,     0,     1, 49152, 57344, 61440, 
+    63488, 63616, 63620,     0,     1, 49152, 57344, 61440, 
+    63488, 63616, 63624, 63622,     0,     1, 49152, 57344, 
+    61440, 63488, 63616,     0,     1, 49152, 57344, 61440, 
+    63488, 63616, 63624,     0,     1, 49152, 57344, 61440, 
+    63488, 63616, 63624,     0,     1, 49152, 57344, 61440, 
+    63488, 63616, 63624, 63626,     0,     1, 49152, 57344, 
+    61440, 63488, 63616, 63624,     0,     1, 49152, 57344, 
+    61440, 63488, 63616, 63632, 63628,     0,     1, 49152, 
+    57344, 61440, 63488, 63616, 63632, 63628,     0,     1, 
+    49152, 57344, 61440, 63488, 63616, 63632, 63633, 63630, 
+        0,     1, 49152, 57344, 61440, 63488, 63616,     0, 
+        1, 49152, 57344, 61440, 63488, 63616, 63632,     0, 
+        1, 49152, 57344, 61440, 63488, 63616, 63632,     0, 
+        1, 49152, 57344, 61440, 63488, 63616, 63632, 63634, 
+        0,     1, 49152, 57344, 61440, 63488, 63616, 63632, 
+        0,     1, 49152, 57344, 61440, 63488, 63616, 63632, 
+    63636,     0,     1, 49152, 57344, 61440, 63488, 63616, 
+    63632, 63636,     0,     1, 49152, 57344, 61440, 63488, 
+    63616, 63632, 63640, 63638,     0,     1, 49152, 57344, 
+    61440, 63488, 63616, 63632,     0,     1, 49152, 57344, 
+    61440, 63488, 63616, 63648, 63640,     0,     1, 49152, 
+    57344, 61440, 63488, 63616, 63648, 63640,     0,     1, 
+    49152, 57344, 61440, 63488, 63616, 63648, 63640, 63642, 
+        0,     1, 49152, 57344, 61440, 63488, 63616, 63648, 
+    63640,     0,     1, 49152, 57344, 61440, 63488, 63616, 
+    63648, 63649, 63644,     0,     1, 49152, 57344, 61440, 
+    63488, 63616, 63648, 63649, 63644,     0,     1, 49152, 
+    57344, 61440, 63488, 63616, 63648, 63649, 63644, 63646, 
+        0,     1, 49152, 57344, 61440, 63488, 63616,     0, 
+        1, 49152, 57344, 61440, 63488, 63616, 63648,     0, 
+        1, 49152, 57344, 61440, 63488, 63616, 63648,     0, 
+        1, 49152, 57344, 61440, 63488, 63616, 63648, 63650, 
+        0,     1, 49152, 57344, 61440, 63488, 63616, 63648, 
+        0,     1, 49152, 57344, 61440, 63488, 63616, 63648, 
+    63652,     0,     1, 49152, 57344, 61440, 63488, 63616, 
+    63648, 63652,     0,     1, 49152, 57344, 61440, 63488, 
+    63616, 63648, 63656, 63654,     0,     1, 49152, 57344, 
+    61440, 63488, 63616, 63648,     0,     1, 49152, 57344, 
+    61440, 63488, 63616, 63648, 63656,     0,     1, 49152, 
+    57344, 61440, 63488, 63616, 63648, 63656,     0,     1, 
+    49152, 57344, 61440, 63488, 63616, 63648, 63656, 63658, 
+        0,     1, 49152, 57344, 61440, 63488, 63616, 63648, 
+    63656,     0,     1, 49152, 57344, 61440, 63488, 63616, 
+    63648, 63664, 63660,     0,     1, 49152, 57344, 61440, 
+    63488, 63616, 63648, 63664, 63660,     0,     1, 49152, 
+    57344, 61440, 63488, 63616, 63648, 63664, 63665, 63662, 
+        0,     1, 49152, 57344, 61440, 63488, 63616, 63648, 
+        0,     1, 49152, 57344, 61440, 63488, 63616, 63680, 
+    63664,     0,     1, 49152, 57344, 61440, 63488, 63616, 
+    63680, 63664,     0,     1, 49152, 57344, 61440, 63488, 
+    63616, 63680, 63664, 63666,     0,     1, 49152, 57344, 
+    61440, 63488, 63616, 63680, 63664,     0,     1, 49152, 
+    57344, 61440, 63488, 63616, 63680, 63664, 63668,     0, 
+        1, 49152, 57344, 61440, 63488, 63616, 63680, 63664, 
+    63668,     0,     1, 49152, 57344, 61440, 63488, 63616, 
+    63680, 63664, 63672, 63670,     0,     1, 49152, 57344, 
+    61440, 63488, 63616, 63680, 63664,     0,     1, 49152, 
+    57344, 61440, 63488, 63616, 63680, 63681, 63672,     0, 
+        1, 49152, 57344, 61440, 63488, 63616, 63680, 63681, 
+    63672,     0,     1, 49152, 57344, 61440, 63488, 63616, 
+    63680, 63681, 63672, 63674,     0,     1, 49152, 57344, 
+    61440, 63488, 63616, 63680, 63681, 63672,     0,     1, 
+    49152, 57344, 61440, 63488, 63616, 63680, 63681, 63672, 
+    63676,     0,     1, 49152, 57344, 61440, 63488, 63616, 
+    63680, 63681, 63683, 63676,     0,     1, 49152, 57344, 
+    61440, 63488, 63616, 63680, 63681, 63683, 63676, 63678, 
+        0,     1, 49152, 57344, 61440, 63488, 63616,     0, 
+        1, 49152, 57344, 61440, 63488, 63744, 63680,     0, 
+        1, 49152, 57344, 61440, 63488, 63744, 63680,     0, 
+        1, 49152, 57344, 61440, 63488, 63744, 63680, 63682, 
+        0,     1, 49152, 57344, 61440, 63488, 63744, 63680, 
+        0,     1, 49152, 57344, 61440, 63488, 63744, 63680, 
+    63684,     0,     1, 49152, 57344, 61440, 63488, 63744, 
+    63680, 63684,     0,     1, 49152, 57344, 61440, 63488, 
+    63744, 63680, 63688, 63686,     0,     1, 49152, 57344, 
+    61440, 63488, 63744, 63680,     0,     1, 49152, 57344, 
+    61440, 63488, 63744, 63680, 63688,     0,     1, 49152, 
+    57344, 61440, 63488, 63744, 63680, 63688,     0,     1, 
+    49152, 57344, 61440, 63488, 63744, 63680, 63688, 63690, 
+        0,     1, 49152, 57344, 61440, 63488, 63744, 63680, 
+    63688,     0,     1, 49152, 57344, 61440, 63488, 63744, 
+    63680, 63696, 63692,     0,     1, 49152, 57344, 61440, 
+    63488, 63744, 63680, 63696, 63692,     0,     1, 49152, 
+    57344, 61440, 63488, 63744, 63680, 63696, 63697, 63694, 
+        0,     1, 49152, 57344, 61440, 63488, 63744, 63680, 
+        0,     1, 49152, 57344, 61440, 63488, 63744, 63680, 
+    63696,     0,     1, 49152, 57344, 61440, 63488, 63744, 
+    63680, 63696,     0,     1, 49152, 57344, 61440, 63488, 
+    63744, 63680, 63696, 63698,     0,     1, 49152, 57344, 
+    61440, 63488, 63744, 63680, 63696,     0,     1, 49152, 
+    57344, 61440, 63488, 63744, 63680, 63696, 63700,     0, 
+        1, 49152, 57344, 61440, 63488, 63744, 63680, 63696, 
+    63700,     0,     1, 49152, 57344, 61440, 63488, 63744, 
+    63680, 63696, 63704, 63702,     0,     1, 49152, 57344, 
+    61440, 63488, 63744, 63680, 63696,     0,     1, 49152, 
+    57344, 61440, 63488, 63744, 63680, 63712, 63704,     0, 
+        1, 49152, 57344, 61440, 63488, 63744, 63680, 63712, 
+    63704,     0,     1, 49152, 57344, 61440, 63488, 63744, 
+    63680, 63712, 63704, 63706,     0,     1, 49152, 57344, 
+    61440, 63488, 63744, 63680, 63712, 63704,     0,     1, 
+    49152, 57344, 61440, 63488, 63744, 63680, 63712, 63713, 
+    63708,     0,     1, 49152, 57344, 61440, 63488, 63744, 
+    63680, 63712, 63713, 63708,     0,     1, 49152, 57344, 
+    61440, 63488, 63744, 63680, 63712, 63713, 63708, 63710, 
+        0,     1, 49152, 57344, 61440, 63488, 63744, 63680, 
+        0,     1, 49152, 57344, 61440, 63488, 63744, 63745, 
+    63712,     0,     1, 49152, 57344, 61440, 63488, 63744, 
+    63745, 63712,     0,     1, 49152, 57344, 61440, 63488, 
+    63744, 63745, 63712, 63714,     0,     1, 49152, 57344, 
+    61440, 63488, 63744, 63745, 63712,     0,     1, 49152, 
+    57344, 61440, 63488, 63744, 63745, 63712, 63716,     0, 
+        1, 49152, 57344, 61440, 63488, 63744, 63745, 63712, 
+    63716,     0,     1, 49152, 57344, 61440, 63488, 63744, 
+    63745, 63712, 63720, 63718,     0,     1, 49152, 57344, 
+    61440, 63488, 63744, 63745, 63712,     0,     1, 49152, 
+    57344, 61440, 63488, 63744, 63745, 63712, 63720,     0, 
+        1, 49152, 57344, 61440, 63488, 63744, 63745, 63712, 
+    63720,     0,     1, 49152, 57344, 61440, 63488, 63744, 
+    63745, 63712, 63720, 63722,     0,     1, 49152, 57344, 
+    61440, 63488, 63744, 63745, 63712, 63720,     0,     1, 
+    49152, 57344, 61440, 63488, 63744, 63745, 63712, 63728, 
+    63724,     0,     1, 49152, 57344, 61440, 63488, 63744, 
+    63745, 63712, 63728, 63724,     0,     1, 49152, 57344, 
+    61440, 63488, 63744, 63745, 63712, 63728, 63729, 63726, 
+        0,     1, 49152, 57344, 61440, 63488, 63744, 63745, 
+    63712,     0,     1, 49152, 57344, 61440, 63488, 63744, 
+    63745, 63712, 63728,     0,     1, 49152, 57344, 61440, 
+    63488, 63744, 63745, 63747, 63728,     0,     1, 49152, 
+    57344, 61440, 63488, 63744, 63745, 63747, 63728, 63730, 
+        0,     1, 49152, 57344, 61440, 63488, 63744, 63745, 
+    63747, 63728,     0,     1, 49152, 57344, 61440, 63488, 
+    63744, 63745, 63747, 63728, 63732,     0,     1, 49152, 
+    57344, 61440, 63488, 63744, 63745, 63747, 63728, 63732, 
+        0,     1, 49152, 57344, 61440, 63488, 63744, 63745, 
+    63747, 63728, 63736, 63734,     0,     1, 49152, 57344, 
+    61440, 63488, 63744, 63745, 63747, 63728,     0,     1, 
+    49152, 57344, 61440, 63488, 63744, 63745, 63747, 63728, 
+    63736,     0,     1, 49152, 57344, 61440, 63488, 63744, 
+    63745, 63747, 63728, 63736,     0,     1, 49152, 57344, 
+    61440, 63488, 63744, 63745, 63747, 63728, 63736, 63738, 
+        0,     1, 49152, 57344, 61440, 63488, 63744, 63745, 
+    63747, 63751, 63736,     0,     1, 49152, 57344, 61440, 
+    63488, 63744, 63745, 63747, 63751, 63736, 63740,     0, 
+        1, 49152, 57344, 61440, 63488, 63744, 63745, 63747, 
+    63751, 63736, 63740,     0,     1, 49152, 57344, 61440, 
+    63488, 63744, 63745, 63747, 63751, 63736, 63740, 63742, 
+        0,     1, 49152, 57344, 61440, 63488,     0,     1, 
+    49152, 57344, 61440, 63488, 63744,     0,     1, 49152, 
+    57344, 61440, 63488, 63744,     0,     1, 49152, 57344, 
+    61440, 63488, 63744, 63746,     0,     1, 49152, 57344, 
+    61440, 63488, 63744,     0,     1, 49152, 57344, 61440, 
+    63488, 63744, 63748,     0,     1, 49152, 57344, 61440, 
+    63488, 63744, 63748,     0,     1, 49152, 57344, 61440, 
+    63488, 63744, 63752, 63750,     0,     1, 49152, 57344, 
+    61440, 63488, 63744,     0,     1, 49152, 57344, 61440, 
+    63488, 63744, 63752,     0,     1, 49152, 57344, 61440, 
+    63488, 63744, 63752,     0,     1, 49152, 57344, 61440, 
+    63488, 63744, 63752, 63754,     0,     1, 49152, 57344, 
+    61440, 63488, 63744, 63752,     0,     1, 49152, 57344, 
+    61440, 63488, 63744, 63760, 63756,     0,     1, 49152, 
+    57344, 61440, 63488, 63744, 63760, 63756,     0,     1, 
+    49152, 57344, 61440, 63488, 63744, 63760, 63761, 63758, 
+        0,     1, 49152, 57344, 61440, 63488, 63744,     0, 
+        1, 49152, 57344, 61440, 63488, 63744, 63760,     0, 
+        1, 49152, 57344, 61440, 63488, 63744, 63760,     0, 
+        1, 49152, 57344, 61440, 63488, 63744, 63760, 63762, 
+        0,     1, 49152, 57344, 61440, 63488, 63744, 63760, 
+        0,     1, 49152, 57344, 61440, 63488, 63744, 63760, 
+    63764,     0,     1, 49152, 57344, 61440, 63488, 63744, 
+    63760, 63764,     0,     1, 49152, 57344, 61440, 63488, 
+    63744, 63760, 63768, 63766,     0,     1, 49152, 57344, 
+    61440, 63488, 63744, 63760,     0,     1, 49152, 57344, 
+    61440, 63488, 63744, 63776, 63768,     0,     1, 49152, 
+    57344, 61440, 63488, 63744, 63776, 63768,     0,     1, 
+    49152, 57344, 61440, 63488, 63744, 63776, 63768, 63770, 
+        0,     1, 49152, 57344, 61440, 63488, 63744, 63776, 
+    63768,     0,     1, 49152, 57344, 61440, 63488, 63744, 
+    63776, 63777, 63772,     0,     1, 49152, 57344, 61440, 
+    63488, 63744, 63776, 63777, 63772,     0,     1, 49152, 
+    57344, 61440, 63488, 63744, 63776, 63777, 63772, 63774, 
+        0,     1, 49152, 57344, 61440, 63488, 63744,     0, 
+        1, 49152, 57344, 61440, 63488, 63744, 63776,     0, 
+        1, 49152, 57344, 61440, 63488, 63744, 63776,     0, 
+        1, 49152, 57344, 61440, 63488, 63744, 63776, 63778, 
+        0,     1, 49152, 57344, 61440, 63488, 63744, 63776, 
+        0,     1, 49152, 57344, 61440, 63488, 63744, 63776, 
+    63780,     0,     1, 49152, 57344, 61440, 63488, 63744, 
+    63776, 63780,     0,     1, 49152, 57344, 61440, 63488, 
+    63744, 63776, 63784, 63782,     0,     1, 49152, 57344, 
+    61440, 63488, 63744, 63776,     0,     1, 49152, 57344, 
+    61440, 63488, 63744, 63776, 63784,     0,     1, 49152, 
+    57344, 61440, 63488, 63744, 63776, 63784,     0,     1, 
+    49152, 57344, 61440, 63488, 63744, 63776, 63784, 63786, 
+        0,     1, 49152, 57344, 61440, 63488, 63744, 63776, 
+    63784,     0,     1, 49152, 57344, 61440, 63488, 63744, 
+    63776, 63792, 63788,     0,     1, 49152, 57344, 61440, 
+    63488, 63744, 63776, 63792, 63788,     0,     1, 49152, 
+    57344, 61440, 63488, 63744, 63776, 63792, 63793, 63790, 
+        0,     1, 49152, 57344, 61440, 63488, 63744, 63776, 
+        0,     1, 49152, 57344, 61440, 63488, 63744, 63808, 
+    63792,     0,     1, 49152, 57344, 61440, 63488, 63744, 
+    63808, 63792,     0,     1, 49152, 57344, 61440, 63488, 
+    63744, 63808, 63792, 63794,     0,     1, 49152, 57344, 
+    61440, 63488, 63744, 63808, 63792,     0,     1, 49152, 
+    57344, 61440, 63488, 63744, 63808, 63792, 63796,     0, 
+        1, 49152, 57344, 61440, 63488, 63744, 63808, 63792, 
+    63796,     0,     1, 49152, 57344, 61440, 63488, 63744, 
+    63808, 63792, 63800, 63798,     0,     1, 49152, 57344, 
+    61440, 63488, 63744, 63808, 63792,     0,     1, 49152, 
+    57344, 61440, 63488, 63744, 63808, 63809, 63800,     0, 
+        1, 49152, 57344, 61440, 63488, 63744, 63808, 63809, 
+    63800,     0,     1, 49152, 57344, 61440, 63488, 63744, 
+    63808, 63809, 63800, 63802,     0,     1, 49152, 57344, 
+    61440, 63488, 63744, 63808, 63809, 63800,     0,     1, 
+    49152, 57344, 61440, 63488, 63744, 63808, 63809, 63800, 
+    63804,     0,     1, 49152, 57344, 61440, 63488, 63744, 
+    63808, 63809, 63811, 63804,     0,     1, 49152, 57344, 
+    61440, 63488, 63744, 63808, 63809, 63811, 63804, 63806, 
+        0,     1, 49152, 57344, 61440, 63488, 63744,     0, 
+        1, 49152, 57344, 61440, 63488, 63744, 63808,     0, 
+        1, 49152, 57344, 61440, 63488, 63744, 63808,     0, 
+        1, 49152, 57344, 61440, 63488, 63744, 63808, 63810, 
+        0,     1, 49152, 57344, 61440, 63488, 63744, 63808, 
+        0,     1, 49152, 57344, 61440, 63488, 63744, 63808, 
+    63812,     0,     1, 49152, 57344, 61440, 63488, 63744, 
+    63808, 63812,     0,     1, 49152, 57344, 61440, 63488, 
+    63744, 63808, 63816, 63814,     0,     1, 49152, 57344, 
+    61440, 63488, 63744, 63808,     0,     1, 49152, 57344, 
+    61440, 63488, 63744, 63808, 63816,     0,     1, 49152, 
+    57344, 61440, 63488, 63744, 63808, 63816,     0,     1, 
+    49152, 57344, 61440, 63488, 63744, 63808, 63816, 63818, 
+        0,     1, 49152, 57344, 61440, 63488, 63744, 63808, 
+    63816,     0,     1, 49152, 57344, 61440, 63488, 63744, 
+    63808, 63824, 63820,     0,     1, 49152, 57344, 61440, 
+    63488, 63744, 63808, 63824, 63820,     0,     1, 49152, 
+    57344, 61440, 63488, 63744, 63808, 63824, 63825, 63822, 
+        0,     1, 49152, 57344, 61440, 63488, 63744, 63808, 
+        0,     1, 49152, 57344, 61440, 63488, 63744, 63808, 
+    63824,     0,     1, 49152, 57344, 61440, 63488, 63744, 
+    63808, 63824,     0,     1, 49152, 57344, 61440, 63488, 
+    63744, 63808, 63824, 63826,     0,     1, 49152, 57344, 
+    61440, 63488, 63744, 63808, 63824,     0,     1, 49152, 
+    57344, 61440, 63488, 63744, 63808, 63824, 63828,     0, 
+        1, 49152, 57344, 61440, 63488, 63744, 63808, 63824, 
+    63828,     0,     1, 49152, 57344, 61440, 63488, 63744, 
+    63808, 63824, 63832, 63830,     0,     1, 49152, 57344, 
+    61440, 63488, 63744, 63808, 63824,     0,     1, 49152, 
+    57344, 61440, 63488, 63744, 63808, 63840, 63832,     0, 
+        1, 49152, 57344, 61440, 63488, 63744, 63808, 63840, 
+    63832,     0,     1, 49152, 57344, 61440, 63488, 63744, 
+    63808, 63840, 63832, 63834,     0,     1, 49152, 57344, 
+    61440, 63488, 63744, 63808, 63840, 63832,     0,     1, 
+    49152, 57344, 61440, 63488, 63744, 63808, 63840, 63841, 
+    63836,     0,     1, 49152, 57344, 61440, 63488, 63744, 
+    63808, 63840, 63841, 63836,     0,     1, 49152, 57344, 
+    61440, 63488, 63744, 63808, 63840, 63841, 63836, 63838, 
+        0,     1, 49152, 57344, 61440, 63488, 63744, 63808, 
+        0,     1, 49152, 57344, 61440, 63488, 63744, 63872, 
+    63840,     0,     1, 49152, 57344, 61440, 63488, 63744, 
+    63872, 63840,     0,     1, 49152, 57344, 61440, 63488, 
+    63744, 63872, 63840, 63842,     0,     1, 49152, 57344, 
+    61440, 63488, 63744, 63872, 63840,     0,     1, 49152, 
+    57344, 61440, 63488, 63744, 63872, 63840, 63844,     0, 
+        1, 49152, 57344, 61440, 63488, 63744, 63872, 63840, 
+    63844,     0,     1, 49152, 57344, 61440, 63488, 63744, 
+    63872, 63840, 63848, 63846,     0,     1, 49152, 57344, 
+    61440, 63488, 63744, 63872, 63840,     0,     1, 49152, 
+    57344, 61440, 63488, 63744, 63872, 63840, 63848,     0, 
+        1, 49152, 57344, 61440, 63488, 63744, 63872, 63840, 
+    63848,     0,     1, 49152, 57344, 61440, 63488, 63744, 
+    63872, 63840, 63848, 63850,     0,     1, 49152, 57344, 
+    61440, 63488, 63744, 63872, 63840, 63848,     0,     1, 
+    49152, 57344, 61440, 63488, 63744, 63872, 63840, 63856, 
+    63852,     0,     1, 49152, 57344, 61440, 63488, 63744, 
+    63872, 63840, 63856, 63852,     0,     1, 49152, 57344, 
+    61440, 63488, 63744, 63872, 63840, 63856, 63857, 63854, 
+        0,     1, 49152, 57344, 61440, 63488, 63744, 63872, 
+    63840,     0,     1, 49152, 57344, 61440, 63488, 63744, 
+    63872, 63873, 63856,     0,     1, 49152, 57344, 61440, 
+    63488, 63744, 63872, 63873, 63856,     0,     1, 49152, 
+    57344, 61440, 63488, 63744, 63872, 63873, 63856, 63858, 
+        0,     1, 49152, 57344, 61440, 63488, 63744, 63872, 
+    63873, 63856,     0,     1, 49152, 57344, 61440, 63488, 
+    63744, 63872, 63873, 63856, 63860,     0,     1, 49152, 
+    57344, 61440, 63488, 63744, 63872, 63873, 63856, 63860, 
+        0,     1, 49152, 57344, 61440, 63488, 63744, 63872, 
+    63873, 63856, 63864, 63862,     0,     1, 49152, 57344, 
+    61440, 63488, 63744, 63872, 63873, 63856,     0,     1, 
+    49152, 57344, 61440, 63488, 63744, 63872, 63873, 63856, 
+    63864,     0,     1, 49152, 57344, 61440, 63488, 63744, 
+    63872, 63873, 63875, 63864,     0,     1, 49152, 57344, 
+    61440, 63488, 63744, 63872, 63873, 63875, 63864, 63866, 
+        0,     1, 49152, 57344, 61440, 63488, 63744, 63872, 
+    63873, 63875, 63864,     0,     1, 49152, 57344, 61440, 
+    63488, 63744, 63872, 63873, 63875, 63864, 63868,     0, 
+        1, 49152, 57344, 61440, 63488, 63744, 63872, 63873, 
+    63875, 63864, 63868,     0,     1, 49152, 57344, 61440, 
+    63488, 63744, 63872, 63873, 63875, 63864, 63868, 63870, 
+        0,     1, 49152, 57344, 61440, 63488, 63744,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 63872,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 63872,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 63872, 63874, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 63872, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 63872, 
+    63876,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    63872, 63876,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 63872, 63880, 63878,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 63872,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 63872, 63880,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 63872, 63880,     0,     1, 
+    49152, 57344, 61440, 63488, 64000, 63872, 63880, 63882, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 63872, 
+    63880,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    63872, 63888, 63884,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 63872, 63888, 63884,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 63872, 63888, 63889, 63886, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 63872, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 63872, 
+    63888,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    63872, 63888,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 63872, 63888, 63890,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 63872, 63888,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 63872, 63888, 63892,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 63872, 63888, 
+    63892,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    63872, 63888, 63896, 63894,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 63872, 63888,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 63872, 63904, 63896,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 63872, 63904, 
+    63896,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    63872, 63904, 63896, 63898,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 63872, 63904, 63896,     0,     1, 
+    49152, 57344, 61440, 63488, 64000, 63872, 63904, 63905, 
+    63900,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    63872, 63904, 63905, 63900,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 63872, 63904, 63905, 63900, 63902, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 63872, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 63872, 
+    63904,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    63872, 63904,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 63872, 63904, 63906,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 63872, 63904,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 63872, 63904, 63908,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 63872, 63904, 
+    63908,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    63872, 63904, 63912, 63910,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 63872, 63904,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 63872, 63904, 63912,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 63872, 63904, 
+    63912,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    63872, 63904, 63912, 63914,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 63872, 63904, 63912,     0,     1, 
+    49152, 57344, 61440, 63488, 64000, 63872, 63904, 63920, 
+    63916,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    63872, 63904, 63920, 63916,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 63872, 63904, 63920, 63921, 63918, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 63872, 
+    63904,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    63872, 63936, 63920,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 63872, 63936, 63920,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 63872, 63936, 63920, 63922, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 63872, 
+    63936, 63920,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 63872, 63936, 63920, 63924,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 63872, 63936, 63920, 63924, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 63872, 
+    63936, 63920, 63928, 63926,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 63872, 63936, 63920,     0,     1, 
+    49152, 57344, 61440, 63488, 64000, 63872, 63936, 63937, 
+    63928,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    63872, 63936, 63937, 63928,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 63872, 63936, 63937, 63928, 63930, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 63872, 
+    63936, 63937, 63928,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 63872, 63936, 63937, 63928, 63932,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 63872, 63936, 
+    63937, 63939, 63932,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 63872, 63936, 63937, 63939, 63932, 63934, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 63872, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64001, 
+    63936,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64001, 63936,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 64001, 63936, 63938,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64001, 63936,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64001, 63936, 63940,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64001, 63936, 
+    63940,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64001, 63936, 63944, 63942,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64001, 63936,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64001, 63936, 63944,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64001, 63936, 
+    63944,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64001, 63936, 63944, 63946,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64001, 63936, 63944,     0,     1, 
+    49152, 57344, 61440, 63488, 64000, 64001, 63936, 63952, 
+    63948,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64001, 63936, 63952, 63948,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64001, 63936, 63952, 63953, 63950, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64001, 
+    63936,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64001, 63936, 63952,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64001, 63936, 63952,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64001, 63936, 63952, 63954, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64001, 
+    63936, 63952,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 64001, 63936, 63952, 63956,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64001, 63936, 63952, 63956, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64001, 
+    63936, 63952, 63960, 63958,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64001, 63936, 63952,     0,     1, 
+    49152, 57344, 61440, 63488, 64000, 64001, 63936, 63968, 
+    63960,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64001, 63936, 63968, 63960,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64001, 63936, 63968, 63960, 63962, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64001, 
+    63936, 63968, 63960,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64001, 63936, 63968, 63969, 63964,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64001, 63936, 
+    63968, 63969, 63964,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64001, 63936, 63968, 63969, 63964, 63966, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64001, 
+    63936,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64001, 63936, 63968,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64001, 64003, 63968,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64001, 64003, 63968, 63970, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64001, 
+    64003, 63968,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 64001, 64003, 63968, 63972,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64001, 64003, 63968, 63972, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64001, 
+    64003, 63968, 63976, 63974,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64001, 64003, 63968,     0,     1, 
+    49152, 57344, 61440, 63488, 64000, 64001, 64003, 63968, 
+    63976,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64001, 64003, 63968, 63976,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64001, 64003, 63968, 63976, 63978, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64001, 
+    64003, 63968, 63976,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64001, 64003, 63968, 63984, 63980,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64001, 64003, 
+    63968, 63984, 63980,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64001, 64003, 63968, 63984, 63985, 63982, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64001, 
+    64003, 63968,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 64001, 64003, 63968, 63984,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64001, 64003, 63968, 63984, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64001, 
+    64003, 63968, 63984, 63986,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64001, 64003, 64007, 63984,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64001, 64003, 
+    64007, 63984, 63988,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64001, 64003, 64007, 63984, 63988,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64001, 64003, 
+    64007, 63984, 63992, 63990,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64001, 64003, 64007, 63984,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64001, 64003, 
+    64007, 63984, 63992,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64001, 64003, 64007, 63984, 63992,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64001, 64003, 
+    64007, 63984, 63992, 63994,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64001, 64003, 64007, 63984, 63992, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64001, 
+    64003, 64007, 63984, 63992, 63996,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64001, 64003, 64007, 63984, 
+    63992, 63996,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 64001, 64003, 64007, 63984, 63992, 63996, 63998, 
+        0,     1, 49152, 57344, 61440, 63488,     0,     1, 
+    49152, 57344, 61440, 63488, 64000,     0,     1, 49152, 
+    57344, 61440, 63488, 64000,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64002,     0,     1, 49152, 57344, 
+    61440, 63488, 64000,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64004,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64004,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64008, 64006,     0,     1, 49152, 57344, 
+    61440, 63488, 64000,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64008,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64008,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64008, 64010,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64008,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64016, 64012,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64016, 64012,     0,     1, 
+    49152, 57344, 61440, 63488, 64000, 64016, 64017, 64014, 
+        0,     1, 49152, 57344, 61440, 63488, 64000,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64016,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64016,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64016, 64018, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64016, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64016, 
+    64020,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64016, 64020,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 64016, 64024, 64022,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64016,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64032, 64024,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64032, 64024,     0,     1, 
+    49152, 57344, 61440, 63488, 64000, 64032, 64024, 64026, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64032, 
+    64024,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64032, 64033, 64028,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64032, 64033, 64028,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64032, 64033, 64028, 64030, 
+        0,     1, 49152, 57344, 61440, 63488, 64000,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64032,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64032,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64032, 64034, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64032, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64032, 
+    64036,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64032, 64036,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 64032, 64040, 64038,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64032,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64032, 64040,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64032, 64040,     0,     1, 
+    49152, 57344, 61440, 63488, 64000, 64032, 64040, 64042, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64032, 
+    64040,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64032, 64048, 64044,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64032, 64048, 64044,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64032, 64048, 64049, 64046, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64032, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64064, 
+    64048,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64064, 64048,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 64064, 64048, 64050,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64064, 64048,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64064, 64048, 64052,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64064, 64048, 
+    64052,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64064, 64048, 64056, 64054,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64064, 64048,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64064, 64065, 64056,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64064, 64065, 
+    64056,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64064, 64065, 64056, 64058,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64064, 64065, 64056,     0,     1, 
+    49152, 57344, 61440, 63488, 64000, 64064, 64065, 64056, 
+    64060,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64064, 64065, 64067, 64060,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64064, 64065, 64067, 64060, 64062, 
+        0,     1, 49152, 57344, 61440, 63488, 64000,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64064,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64064,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64064, 64066, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64064, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64064, 
+    64068,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64064, 64068,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 64064, 64072, 64070,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64064,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64064, 64072,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64064, 64072,     0,     1, 
+    49152, 57344, 61440, 63488, 64000, 64064, 64072, 64074, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64064, 
+    64072,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64064, 64080, 64076,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64064, 64080, 64076,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64064, 64080, 64081, 64078, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64064, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64064, 
+    64080,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64064, 64080,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 64064, 64080, 64082,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64064, 64080,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64064, 64080, 64084,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64064, 64080, 
+    64084,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64064, 64080, 64088, 64086,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64064, 64080,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64064, 64096, 64088,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64064, 64096, 
+    64088,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64064, 64096, 64088, 64090,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64064, 64096, 64088,     0,     1, 
+    49152, 57344, 61440, 63488, 64000, 64064, 64096, 64097, 
+    64092,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64064, 64096, 64097, 64092,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64064, 64096, 64097, 64092, 64094, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64064, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64128, 
+    64096,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64128, 64096,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 64128, 64096, 64098,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64128, 64096,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64128, 64096, 64100,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64128, 64096, 
+    64100,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64128, 64096, 64104, 64102,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64128, 64096,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64128, 64096, 64104,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64128, 64096, 
+    64104,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64128, 64096, 64104, 64106,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64128, 64096, 64104,     0,     1, 
+    49152, 57344, 61440, 63488, 64000, 64128, 64096, 64112, 
+    64108,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64128, 64096, 64112, 64108,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64128, 64096, 64112, 64113, 64110, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64128, 
+    64096,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64128, 64129, 64112,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64128, 64129, 64112,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64128, 64129, 64112, 64114, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64128, 
+    64129, 64112,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 64128, 64129, 64112, 64116,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64128, 64129, 64112, 64116, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64128, 
+    64129, 64112, 64120, 64118,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64128, 64129, 64112,     0,     1, 
+    49152, 57344, 61440, 63488, 64000, 64128, 64129, 64112, 
+    64120,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64128, 64129, 64131, 64120,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64128, 64129, 64131, 64120, 64122, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64128, 
+    64129, 64131, 64120,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64128, 64129, 64131, 64120, 64124,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64128, 64129, 
+    64131, 64120, 64124,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64128, 64129, 64131, 64120, 64124, 64126, 
+        0,     1, 49152, 57344, 61440, 63488, 64000,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64128,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64128,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64128, 64130, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64128, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64128, 
+    64132,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64128, 64132,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 64128, 64136, 64134,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64128,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64128, 64136,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64128, 64136,     0,     1, 
+    49152, 57344, 61440, 63488, 64000, 64128, 64136, 64138, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64128, 
+    64136,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64128, 64144, 64140,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64128, 64144, 64140,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64128, 64144, 64145, 64142, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64128, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64128, 
+    64144,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64128, 64144,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 64128, 64144, 64146,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64128, 64144,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64128, 64144, 64148,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64128, 64144, 
+    64148,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64128, 64144, 64152, 64150,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64128, 64144,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64128, 64160, 64152,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64128, 64160, 
+    64152,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64128, 64160, 64152, 64154,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64128, 64160, 64152,     0,     1, 
+    49152, 57344, 61440, 63488, 64000, 64128, 64160, 64161, 
+    64156,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64128, 64160, 64161, 64156,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64128, 64160, 64161, 64156, 64158, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64128, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64128, 
+    64160,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64128, 64160,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 64128, 64160, 64162,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64128, 64160,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64128, 64160, 64164,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64128, 64160, 
+    64164,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64128, 64160, 64168, 64166,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64128, 64160,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64128, 64160, 64168,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64128, 64160, 
+    64168,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64128, 64160, 64168, 64170,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64128, 64160, 64168,     0,     1, 
+    49152, 57344, 61440, 63488, 64000, 64128, 64160, 64176, 
+    64172,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64128, 64160, 64176, 64172,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64128, 64160, 64176, 64177, 64174, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64128, 
+    64160,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64128, 64192, 64176,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64128, 64192, 64176,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64128, 64192, 64176, 64178, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64128, 
+    64192, 64176,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 64128, 64192, 64176, 64180,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64128, 64192, 64176, 64180, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64128, 
+    64192, 64176, 64184, 64182,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64128, 64192, 64176,     0,     1, 
+    49152, 57344, 61440, 63488, 64000, 64128, 64192, 64193, 
+    64184,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64128, 64192, 64193, 64184,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64128, 64192, 64193, 64184, 64186, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64128, 
+    64192, 64193, 64184,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64128, 64192, 64193, 64184, 64188,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64128, 64192, 
+    64193, 64195, 64188,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64128, 64192, 64193, 64195, 64188, 64190, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64128, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64192,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64256, 64192,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 64256, 64192, 64194,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64192,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64256, 64192, 64196,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256, 64192, 
+    64196,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64256, 64192, 64200, 64198,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64192,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64256, 64192, 64200,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256, 64192, 
+    64200,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64256, 64192, 64200, 64202,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64192, 64200,     0,     1, 
+    49152, 57344, 61440, 63488, 64000, 64256, 64192, 64208, 
+    64204,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64256, 64192, 64208, 64204,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64192, 64208, 64209, 64206, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64192,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64256, 64192, 64208,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64256, 64192, 64208,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64256, 64192, 64208, 64210, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64192, 64208,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 64256, 64192, 64208, 64212,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64256, 64192, 64208, 64212, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64192, 64208, 64216, 64214,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64192, 64208,     0,     1, 
+    49152, 57344, 61440, 63488, 64000, 64256, 64192, 64224, 
+    64216,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64256, 64192, 64224, 64216,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64192, 64224, 64216, 64218, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64192, 64224, 64216,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64256, 64192, 64224, 64225, 64220,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256, 64192, 
+    64224, 64225, 64220,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64256, 64192, 64224, 64225, 64220, 64222, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64192,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64256, 64257, 64224,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64256, 64257, 64224,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64256, 64257, 64224, 64226, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64257, 64224,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 64256, 64257, 64224, 64228,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64256, 64257, 64224, 64228, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64257, 64224, 64232, 64230,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64257, 64224,     0,     1, 
+    49152, 57344, 61440, 63488, 64000, 64256, 64257, 64224, 
+    64232,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64256, 64257, 64224, 64232,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64257, 64224, 64232, 64234, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64257, 64224, 64232,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64256, 64257, 64224, 64240, 64236,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256, 64257, 
+    64224, 64240, 64236,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64256, 64257, 64224, 64240, 64241, 64238, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64257, 64224,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 64256, 64257, 64224, 64240,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64256, 64257, 64259, 64240, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64257, 64259, 64240, 64242,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64257, 64259, 64240,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256, 64257, 
+    64259, 64240, 64244,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64256, 64257, 64259, 64240, 64244,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256, 64257, 
+    64259, 64240, 64248, 64246,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64257, 64259, 64240,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256, 64257, 
+    64259, 64240, 64248,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64256, 64257, 64259, 64240, 64248,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256, 64257, 
+    64259, 64240, 64248, 64250,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64257, 64259, 64263, 64248, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64257, 64259, 64263, 64248, 64252,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64256, 64257, 64259, 64263, 
+    64248, 64252,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 64256, 64257, 64259, 64263, 64248, 64252, 64254, 
+        0,     1, 49152, 57344, 61440, 63488, 64000,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256, 64258, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64260,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64256, 64260,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 64256, 64264, 64262,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64264,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64256, 64264,     0,     1, 
+    49152, 57344, 61440, 63488, 64000, 64256, 64264, 64266, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64264,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64256, 64272, 64268,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64256, 64272, 64268,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64256, 64272, 64273, 64270, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64272,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64256, 64272,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 64256, 64272, 64274,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64272,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64256, 64272, 64276,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256, 64272, 
+    64276,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64256, 64272, 64280, 64278,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64272,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64256, 64288, 64280,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256, 64288, 
+    64280,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64256, 64288, 64280, 64282,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64288, 64280,     0,     1, 
+    49152, 57344, 61440, 63488, 64000, 64256, 64288, 64289, 
+    64284,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64256, 64288, 64289, 64284,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64288, 64289, 64284, 64286, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64288,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64256, 64288,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 64256, 64288, 64290,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64288,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64256, 64288, 64292,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256, 64288, 
+    64292,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64256, 64288, 64296, 64294,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64288,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64256, 64288, 64296,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256, 64288, 
+    64296,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64256, 64288, 64296, 64298,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64288, 64296,     0,     1, 
+    49152, 57344, 61440, 63488, 64000, 64256, 64288, 64304, 
+    64300,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64256, 64288, 64304, 64300,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64288, 64304, 64305, 64302, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64288,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64256, 64320, 64304,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64256, 64320, 64304,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64256, 64320, 64304, 64306, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64320, 64304,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 64256, 64320, 64304, 64308,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64256, 64320, 64304, 64308, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64320, 64304, 64312, 64310,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64320, 64304,     0,     1, 
+    49152, 57344, 61440, 63488, 64000, 64256, 64320, 64321, 
+    64312,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64256, 64320, 64321, 64312,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64320, 64321, 64312, 64314, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64320, 64321, 64312,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64256, 64320, 64321, 64312, 64316,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256, 64320, 
+    64321, 64323, 64316,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64256, 64320, 64321, 64323, 64316, 64318, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64320,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64256, 64320,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 64256, 64320, 64322,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64320,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64256, 64320, 64324,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256, 64320, 
+    64324,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64256, 64320, 64328, 64326,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64320,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64256, 64320, 64328,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256, 64320, 
+    64328,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64256, 64320, 64328, 64330,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64320, 64328,     0,     1, 
+    49152, 57344, 61440, 63488, 64000, 64256, 64320, 64336, 
+    64332,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64256, 64320, 64336, 64332,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64320, 64336, 64337, 64334, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64320,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64256, 64320, 64336,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64256, 64320, 64336,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64256, 64320, 64336, 64338, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64320, 64336,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 64256, 64320, 64336, 64340,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64256, 64320, 64336, 64340, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64320, 64336, 64344, 64342,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64320, 64336,     0,     1, 
+    49152, 57344, 61440, 63488, 64000, 64256, 64320, 64352, 
+    64344,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64256, 64320, 64352, 64344,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64320, 64352, 64344, 64346, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64320, 64352, 64344,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64256, 64320, 64352, 64353, 64348,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256, 64320, 
+    64352, 64353, 64348,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64256, 64320, 64352, 64353, 64348, 64350, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64320,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64256, 64384, 64352,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64256, 64384, 64352,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64256, 64384, 64352, 64354, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64384, 64352,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 64256, 64384, 64352, 64356,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64256, 64384, 64352, 64356, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64384, 64352, 64360, 64358,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64384, 64352,     0,     1, 
+    49152, 57344, 61440, 63488, 64000, 64256, 64384, 64352, 
+    64360,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64256, 64384, 64352, 64360,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64384, 64352, 64360, 64362, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64384, 64352, 64360,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64256, 64384, 64352, 64368, 64364,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256, 64384, 
+    64352, 64368, 64364,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64256, 64384, 64352, 64368, 64369, 64366, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64384, 64352,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 64256, 64384, 64385, 64368,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64256, 64384, 64385, 64368, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64384, 64385, 64368, 64370,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64384, 64385, 64368,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256, 64384, 
+    64385, 64368, 64372,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64256, 64384, 64385, 64368, 64372,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256, 64384, 
+    64385, 64368, 64376, 64374,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64384, 64385, 64368,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256, 64384, 
+    64385, 64368, 64376,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64256, 64384, 64385, 64387, 64376,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256, 64384, 
+    64385, 64387, 64376, 64378,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64384, 64385, 64387, 64376, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64384, 64385, 64387, 64376, 64380,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64256, 64384, 64385, 64387, 
+    64376, 64380,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 64256, 64384, 64385, 64387, 64376, 64380, 64382, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64384,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64256, 64384,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 64256, 64384, 64386,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64384,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64256, 64384, 64388,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256, 64384, 
+    64388,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64256, 64384, 64392, 64390,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64384,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64256, 64384, 64392,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256, 64384, 
+    64392,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64256, 64384, 64392, 64394,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64384, 64392,     0,     1, 
+    49152, 57344, 61440, 63488, 64000, 64256, 64384, 64400, 
+    64396,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64256, 64384, 64400, 64396,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64384, 64400, 64401, 64398, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64384,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64256, 64384, 64400,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64256, 64384, 64400,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64256, 64384, 64400, 64402, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64384, 64400,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 64256, 64384, 64400, 64404,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64256, 64384, 64400, 64404, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64384, 64400, 64408, 64406,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64384, 64400,     0,     1, 
+    49152, 57344, 61440, 63488, 64000, 64256, 64384, 64416, 
+    64408,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64256, 64384, 64416, 64408,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64384, 64416, 64408, 64410, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64384, 64416, 64408,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64256, 64384, 64416, 64417, 64412,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256, 64384, 
+    64416, 64417, 64412,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64256, 64384, 64416, 64417, 64412, 64414, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64384,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64256, 64384, 64416,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64256, 64384, 64416,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64256, 64384, 64416, 64418, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64384, 64416,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 64256, 64384, 64416, 64420,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64256, 64384, 64416, 64420, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64384, 64416, 64424, 64422,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64384, 64416,     0,     1, 
+    49152, 57344, 61440, 63488, 64000, 64256, 64384, 64416, 
+    64424,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64256, 64384, 64416, 64424,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64384, 64416, 64424, 64426, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64384, 64416, 64424,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64256, 64384, 64416, 64432, 64428,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256, 64384, 
+    64416, 64432, 64428,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64256, 64384, 64416, 64432, 64433, 64430, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64384, 64416,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 64256, 64384, 64448, 64432,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64256, 64384, 64448, 64432, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64384, 64448, 64432, 64434,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64384, 64448, 64432,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256, 64384, 
+    64448, 64432, 64436,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64256, 64384, 64448, 64432, 64436,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256, 64384, 
+    64448, 64432, 64440, 64438,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64384, 64448, 64432,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256, 64384, 
+    64448, 64449, 64440,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64256, 64384, 64448, 64449, 64440,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256, 64384, 
+    64448, 64449, 64440, 64442,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64384, 64448, 64449, 64440, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64384, 64448, 64449, 64440, 64444,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64256, 64384, 64448, 64449, 
+    64451, 64444,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 64256, 64384, 64448, 64449, 64451, 64444, 64446, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64384,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64256, 64384, 64448,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64256, 64384, 64448,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64256, 64384, 64448, 64450, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64384, 64448,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 64256, 64384, 64448, 64452,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64256, 64384, 64448, 64452, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64384, 64448, 64456, 64454,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64384, 64448,     0,     1, 
+    49152, 57344, 61440, 63488, 64000, 64256, 64384, 64448, 
+    64456,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64256, 64384, 64448, 64456,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64384, 64448, 64456, 64458, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64384, 64448, 64456,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64256, 64384, 64448, 64464, 64460,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256, 64384, 
+    64448, 64464, 64460,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64256, 64384, 64448, 64464, 64465, 64462, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64384, 64448,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 64256, 64384, 64448, 64464,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64256, 64384, 64448, 64464, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64384, 64448, 64464, 64466,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64384, 64448, 64464,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256, 64384, 
+    64448, 64464, 64468,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64256, 64384, 64448, 64464, 64468,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256, 64384, 
+    64448, 64464, 64472, 64470,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64384, 64448, 64464,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256, 64384, 
+    64448, 64480, 64472,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64256, 64384, 64448, 64480, 64472,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256, 64384, 
+    64448, 64480, 64472, 64474,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64384, 64448, 64480, 64472, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64384, 64448, 64480, 64481, 64476,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64256, 64384, 64448, 64480, 
+    64481, 64476,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 64256, 64384, 64448, 64480, 64481, 64476, 64478, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64384, 64448,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 64256, 64384, 64448, 64480,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64256, 64384, 64448, 64480, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64384, 64448, 64480, 64482,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64384, 64448, 64480,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256, 64384, 
+    64448, 64480, 64484,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64256, 64384, 64448, 64480, 64484,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256, 64384, 
+    64448, 64480, 64488, 64486,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64384, 64448, 64480,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256, 64384, 
+    64448, 64480, 64488,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64256, 64384, 64448, 64480, 64488,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256, 64384, 
+    64448, 64480, 64488, 64490,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64384, 64448, 64480, 64488, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64384, 64448, 64480, 64496, 64492,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64256, 64384, 64448, 64480, 
+    64496, 64492,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 64256, 64384, 64448, 64480, 64496, 64497, 64494, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64384, 64448, 64480,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64256, 64384, 64448, 64480, 64496,     0, 
+        1, 49152, 57344, 61440, 63488, 64000, 64256, 64384, 
+    64448, 64480, 64496,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64256, 64384, 64448, 64480, 64496, 64498, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64384, 64448, 64480, 64496,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64384, 64448, 64480, 64496, 
+    64500,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64256, 64384, 64448, 64480, 64496, 64500,     0,     1, 
+    49152, 57344, 61440, 63488, 64000, 64256, 64384, 64448, 
+    64480, 64496, 64504, 64502,     0,     1, 49152, 57344, 
+    61440, 63488, 64000, 64256, 64384, 64448, 64480, 64496, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64384, 64448, 64480, 64496, 64504,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64256, 64384, 64448, 64480, 
+    64496, 64504,     0,     1, 49152, 57344, 61440, 63488, 
+    64000, 64256, 64384, 64448, 64480, 64496, 64504, 64506, 
+        0,     1, 49152, 57344, 61440, 63488, 64000, 64256, 
+    64384, 64448, 64480, 64496, 64504,     0,     1, 49152, 
+    57344, 61440, 63488, 64000, 64256, 64384, 64448, 64480, 
+    64496, 64504, 64508,     0,     1, 49152, 57344, 61440, 
+    63488, 64000, 64256, 64384, 64448, 64480, 64496, 64504, 
+    64508,     0,     1, 49152, 57344, 61440, 63488, 64000, 
+    64256, 64384, 64448, 64480, 64496, 64504, 64508, 64510, 
+        0,     1,     3,     7,    15,    31,     0,     1, 
+        3,     7,    15,    31,    63,     0,     1,     3, 
+        7,    15,    31,    63,     0,     1,     3,     7, 
+       15,    31,    63,   127,     0,     1,     3,     7, 
+       15,    31,    63,     0,     1,     3,     7,    15, 
+       31,    63,   127,     0,     1,     3,     7,    15, 
+       31,    63,   127,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,     0,     1,     3,     7, 
+       15,    31,    63,     0,     1,     3,     7,    15, 
+       31,    63,   127,     0,     1,     3,     7,    15, 
+       31,    63,   127,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,     0,     1,     3,     7, 
+       15,    31,    63,   127,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+        0,     1,     3,     7,    15,    31,    63,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,    63,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,  4095,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+     2047,  4095,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,  2047,  4095,  8191, 
+        0,     1,     3,     7,    15,    31,    63,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,  4095,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+     2047,  4095,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,  2047,  4095,  8191, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,  4095,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+     2047,  4095,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,  2047,  4095,  8191, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,  4095,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+     2047,  4095,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,  2047,  4095,  8191, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,  4095,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+     2047,  4095,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,  2047,  4095,  8191, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+     4095,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,  2047,  4095,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,  2047,  4095,  8191,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,  4095,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+     2047,  4095,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,  2047,  4095,  8191, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,  4095,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+     2047,  4095,  8191,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+     8191,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,  2047,  4095,  8191, 16383, 
+        0,     1,     3,     7,    15,    31,    63,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,  4095,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+     2047,  4095,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,  2047,  4095,  8191, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,  4095,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+     2047,  4095,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,  2047,  4095,  8191, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,  4095,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+     2047,  4095,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,  2047,  4095,  8191, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,  4095,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+     2047,  4095,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,  2047,  4095,  8191, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+     4095,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,  2047,  4095,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,  2047,  4095,  8191,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,  4095,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+     2047,  4095,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,  2047,  4095,  8191, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,  4095,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+     2047,  4095,  8191,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+     8191,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,  2047,  4095,  8191, 16383, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,  4095,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+     2047,  4095,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,  2047,  4095,  8191, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,  4095,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+     2047,  4095,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,  2047,  4095,  8191, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,  4095,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+     2047,  4095,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,  2047,  4095,  8191, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+     4095,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,  2047,  4095,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,  2047,  4095,  8191,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,  4095,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+     2047,  4095,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,  2047,  4095,  8191, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,  4095,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+     2047,  4095,  8191,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+     8191,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,  2047,  4095,  8191, 16383, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,  4095,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+     2047,  4095,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,  2047,  4095,  8191, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,  4095,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+     2047,  4095,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,  2047,  4095,  8191, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+     4095,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,  2047,  4095,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,  2047,  4095,  8191,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,  4095,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+     2047,  4095,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,  2047,  4095,  8191, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,  4095,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+     2047,  4095,  8191,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+     8191,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,  2047,  4095,  8191, 16383, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,  4095,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+     2047,  4095,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,  2047,  4095,  8191, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+     4095,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,  2047,  4095,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,  2047,  4095,  8191,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,  4095,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+     2047,  4095,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,  2047,  4095,  8191, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,  4095,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+     2047,  4095,  8191,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+     8191,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,  2047,  4095,  8191, 16383, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+     4095,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,  2047,  4095,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,  2047,  4095,  8191,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,  4095,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+     2047,  4095,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,  2047,  4095,  8191, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,  4095,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+     2047,  4095,  8191,     0,     1,     3,     7,    15, 
+       31,    63,   127,   255,   511,  1023,  2047,  4095, 
+     8191,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,  2047,  4095,  8191, 16383, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+     4095,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,  2047,  4095,     0,     1, 
+        3,     7,    15,    31,    63,   127,   255,   511, 
+     1023,  2047,  4095,  8191,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+     4095,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,  2047,  4095,  8191,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,  8191,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+     2047,  4095,  8191, 16383,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+     4095,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,  2047,  4095,  8191,     0, 
+        1,     3,     7,    15,    31,    63,   127,   255, 
+      511,  1023,  2047,  4095,  8191,     0,     1,     3, 
+        7,    15,    31,    63,   127,   255,   511,  1023, 
+     2047,  4095,  8191, 16383,     0,     1,     3,     7, 
+       15,    31,    63,   127,   255,   511,  1023,  2047, 
+     4095,  8191,     0,     1,     3,     7,    15,    31, 
+       63,   127,   255,   511,  1023,  2047,  4095,  8191, 
+    16383,     0,     1,     3,     7,    15,    31,    63, 
+      127,   255,   511,  1023,  2047,  4095,  8191, 16383, 
+        0,     1,     3,     7,    15,    31,    63,   127, 
+      255,   511,  1023,  2047,  4095,  8191, 16383, 32767, 
+};
+
+
diff --git a/Source/OpenEXR/IlmThread/IlmThread.cpp b/Source/OpenEXR/IlmThread/IlmThread.cpp
index 71563d7..1d1bd90 100644
--- a/Source/OpenEXR/IlmThread/IlmThread.cpp
+++ b/Source/OpenEXR/IlmThread/IlmThread.cpp
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -41,12 +41,12 @@
 
 #include "IlmBaseConfig.h"
 
-//#if !defined (_WIN32) &&!(_WIN64) && !(HAVE_PTHREAD)
+//#if !defined(_WIN32) && !defined(_WIN64) && !defined(HAVE_PTHREAD)
 
 #include "IlmThread.h"
 #include "Iex.h"
 
-namespace IlmThread {
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 bool
@@ -58,23 +58,23 @@ supportsThreads ()
 
 Thread::Thread ()
 {
-    throw Iex::NoImplExc ("Threads not supported on this platform.");
+    throw IEX_NAMESPACE::NoImplExc ("Threads not supported on this platform.");
 }
 
 
 Thread::~Thread ()
 {
-    throw Iex::NoImplExc ("Threads not supported on this platform.");
+    throw IEX_NAMESPACE::NoImplExc ("Threads not supported on this platform.");
 }
 
 
 void
 Thread::start ()
 {
-    throw Iex::NoImplExc ("Threads not supported on this platform.");
+    throw IEX_NAMESPACE::NoImplExc ("Threads not supported on this platform.");
 }
 
 
-} // namespace IlmThread
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_EXIT
 
 //#endif
diff --git a/Source/OpenEXR/IlmThread/IlmThread.h b/Source/OpenEXR/IlmThread/IlmThread.h
index e5ca595..1f6d9e6 100644
--- a/Source/OpenEXR/IlmThread/IlmThread.h
+++ b/Source/OpenEXR/IlmThread/IlmThread.h
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -91,6 +91,8 @@
 //-----------------------------------------------------------------------------
 
 #include "IlmBaseConfig.h"
+#include "IlmThreadExport.h"
+#include "IlmThreadNamespace.h"
 
 #if defined _WIN32 || defined _WIN64
     #ifdef NOMINMAX
@@ -103,17 +105,7 @@
     #include <pthread.h>
 #endif
 
-#if defined(OPENEXR_DLL) && !defined(ZENO_STATIC)
-    #ifdef ILMTHREAD_EXPORTS
-	#define ILMTHREAD_EXPORT __declspec(dllexport)
-    #else
-	#define ILMTHREAD_EXPORT __declspec(dllimport)
-    #endif
-#else
-    #define ILMTHREAD_EXPORT 
-#endif
-
-namespace IlmThread {
+ILMTHREAD_INTERNAL_NAMESPACE_HEADER_ENTER
 
 //
 // Query function to determine if the current platform supports
@@ -146,6 +138,6 @@ class ILMTHREAD_EXPORT Thread
 };
 
 
-} // namespace IlmThread
+ILMTHREAD_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_ILM_THREAD_H
diff --git a/Source/OpenEXR/IlmThread/IlmThreadExport.h b/Source/OpenEXR/IlmThread/IlmThreadExport.h
new file mode 100644
index 0000000..96d2200
--- /dev/null
+++ b/Source/OpenEXR/IlmThread/IlmThreadExport.h
@@ -0,0 +1,46 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2012, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission. 
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#if defined(OPENEXR_DLL)
+    #if defined(ILMTHREAD_EXPORTS)
+	    #define ILMTHREAD_EXPORT __declspec(dllexport)
+        #define ILMTHREAD_EXPORT_CONST extern __declspec(dllexport)
+    #else
+	    #define ILMTHREAD_EXPORT __declspec(dllimport)
+	    #define ILMTHREAD_EXPORT_CONST extern __declspec(dllimport)
+    #endif
+#else
+    #define ILMTHREAD_EXPORT
+    #define ILMTHREAD_EXPORT_CONST extern const
+#endif
diff --git a/Source/OpenEXR/IlmThread/IlmThreadForward.h b/Source/OpenEXR/IlmThread/IlmThreadForward.h
new file mode 100644
index 0000000..b52bdac
--- /dev/null
+++ b/Source/OpenEXR/IlmThread/IlmThreadForward.h
@@ -0,0 +1,52 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2012, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission. 
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef INCLUDED_ILMTHREADFORWARD_H
+#define INCLUDED_ILMTHREADFORWARD_H
+
+#include "IlmThreadNamespace.h"
+
+ILMTHREAD_INTERNAL_NAMESPACE_HEADER_ENTER
+
+class Thread;
+class Mutex;
+class Lock;
+class ThreadPool;
+class Task;
+class TaskGroup;
+class Semaphore;
+
+ILMTHREAD_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif // INCLUDED_ILMTHREADFORWARD_H
diff --git a/Source/OpenEXR/IlmThread/IlmThreadMutex.cpp b/Source/OpenEXR/IlmThread/IlmThreadMutex.cpp
index 7a7a4a6..9a2aa0d 100644
--- a/Source/OpenEXR/IlmThread/IlmThreadMutex.cpp
+++ b/Source/OpenEXR/IlmThread/IlmThreadMutex.cpp
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -41,11 +41,11 @@
 
 #include "IlmBaseConfig.h"
 
-//#if !defined (_WIN32) && !(_WIN64) && !(HAVE_PTHREAD)
+//#if !defined(_WIN32) && !defined(_WIN64) && !defined(HAVE_PTHREAD)
 
 #include "IlmThreadMutex.h"
 
-namespace IlmThread {
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 Mutex::Mutex () {}
@@ -54,6 +54,6 @@ void Mutex::lock () const {}
 void Mutex::unlock () const {}
 
 
-} // namespace IlmThread
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_EXIT
 
 //#endif
diff --git a/Source/OpenEXR/IlmThread/IlmThreadMutex.h b/Source/OpenEXR/IlmThread/IlmThreadMutex.h
index 354282b..dd42067 100644
--- a/Source/OpenEXR/IlmThread/IlmThreadMutex.h
+++ b/Source/OpenEXR/IlmThread/IlmThreadMutex.h
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -66,7 +66,9 @@
 //
 //-----------------------------------------------------------------------------
 
+#include "IlmThreadExport.h"
 #include "IlmBaseConfig.h"
+#include "IlmThreadNamespace.h"
 
 #if defined _WIN32 || defined _WIN64
     #ifdef NOMINMAX
@@ -78,12 +80,12 @@
     #include <pthread.h>
 #endif
 
-namespace IlmThread {
+ILMTHREAD_INTERNAL_NAMESPACE_HEADER_ENTER
 
 class Lock;
 
 
-class Mutex
+class ILMTHREAD_EXPORT Mutex
 {
   public:
 
@@ -108,7 +110,7 @@ class Mutex
 };
 
 
-class Lock
+class ILMTHREAD_EXPORT Lock
 {
   public:
 
@@ -153,6 +155,6 @@ class Lock
 };
 
 
-} // namespace IlmThread
+ILMTHREAD_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_ILM_THREAD_MUTEX_H
diff --git a/Source/OpenEXR/IlmThread/IlmThreadMutexPosix.cpp b/Source/OpenEXR/IlmThread/IlmThreadMutexPosix.cpp
index 5f72c10..c123132 100644
--- a/Source/OpenEXR/IlmThread/IlmThreadMutexPosix.cpp
+++ b/Source/OpenEXR/IlmThread/IlmThreadMutexPosix.cpp
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -47,13 +47,13 @@
 #include "Iex.h"
 #include <assert.h>
 
-namespace IlmThread {
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 Mutex::Mutex ()
 {
     if (int error = ::pthread_mutex_init (&_mutex, 0))
-        Iex::throwErrnoExc ("Cannot initialize mutex (%T).", error);
+        IEX_INTERNAL_NAMESPACE::throwErrnoExc ("Cannot initialize mutex (%T).", error);
 }
 
 
@@ -68,7 +68,7 @@ void
 Mutex::lock () const
 {
     if (int error = ::pthread_mutex_lock (&_mutex))
-        Iex::throwErrnoExc ("Cannot lock mutex (%T).", error);
+        IEX_INTERNAL_NAMESPACE::throwErrnoExc ("Cannot lock mutex (%T).", error);
 }
 
 
@@ -76,10 +76,10 @@ void
 Mutex::unlock () const
 {
     if (int error = ::pthread_mutex_unlock (&_mutex))
-        Iex::throwErrnoExc ("Cannot unlock mutex (%T).", error);
+        IEX_INTERNAL_NAMESPACE::throwErrnoExc ("Cannot unlock mutex (%T).", error);
 }
 
 
-} // namespace IlmThread
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_EXIT
 
 #endif
diff --git a/Source/OpenEXR/IlmThread/IlmThreadMutexWin32.cpp b/Source/OpenEXR/IlmThread/IlmThreadMutexWin32.cpp
index 1a34c7e..6cb37e6 100644
--- a/Source/OpenEXR/IlmThread/IlmThreadMutexWin32.cpp
+++ b/Source/OpenEXR/IlmThread/IlmThreadMutexWin32.cpp
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -38,10 +38,14 @@
 //
 //-----------------------------------------------------------------------------
 
+#include "IlmBaseConfig.h"
+
+#if !defined(HAVE_PTHREAD) && defined(_WIN32)
+
 #include "IlmThreadMutex.h"
 #include "Iex.h"
 
-namespace IlmThread {
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 Mutex::Mutex ()
@@ -70,4 +74,6 @@ Mutex::unlock () const
 }
 
 
-} // namespace IlmThread
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_EXIT
+
+#endif
diff --git a/Source/OpenEXR/IlmThread/IlmThreadNamespace.h b/Source/OpenEXR/IlmThread/IlmThreadNamespace.h
new file mode 100644
index 0000000..a412997
--- /dev/null
+++ b/Source/OpenEXR/IlmThread/IlmThreadNamespace.h
@@ -0,0 +1,114 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2012, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission. 
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef INCLUDED_ILMTHREADNAMESPACE_H
+#define INCLUDED_ILMTHREADNAMESPACE_H
+
+//
+// The purpose of this file is to make it possible to specify an
+// ILMTHREAD_INTERNAL_NAMESPACE as a preprocessor definition and have all of
+// the IlmThread symbols defined within that namespace rather than the
+// standard IlmThread namespace.  Those symbols are made available to client
+// code through the ILMTHREAD_NAMESPACE in addition to the
+// ILMTHREAD_INTERNAL_NAMESPACE.
+//
+// To ensure source code compatibility, the ILMTHREAD_NAMESPACE defaults to
+// IlmThread and then "using namespace ILMTHREAD_INTERNAL_NAMESPACE;" brings
+// all of the declarations from the ILMTHREAD_INTERNAL_NAMESPACE into the
+// ILMTHREAD_NAMESPACE.  This means that client code can continue to use
+// syntax like IlmThread::Thread, but at link time it will resolve to a
+// mangled symbol based on the ILMTHREAD_INTERNAL_NAMESPACE.
+//
+// As an example, if one needed to build against a newer version of IlmThread
+// and have it run alongside an older version in the same application, it is
+// now possible to use an internal namespace to prevent collisions between
+// the older versions of IlmThread symbols and the newer ones.  To do this,
+// the following could be defined at build time:
+//
+// ILMTHREAD_INTERNAL_NAMESPACE = IlmThread_v2
+//
+// This means that declarations inside IlmThread headers look like this
+// (after the preprocessor has done its work):
+//
+// namespace IlmThread_v2 {
+//     ...
+//     class declarations
+//     ...
+// }
+//
+// namespace IlmThread {
+//     using namespace IlmThread_v2;
+// }
+//
+
+//
+// Open Source version of this file pulls in the IlmBaseConfig.h file
+// for the configure time options.
+//
+#include "IlmBaseConfig.h"
+
+#ifndef ILMTHREAD_NAMESPACE
+#define ILMTHREAD_NAMESPACE IlmThread
+#endif
+
+#ifndef ILMTHREAD_INTERNAL_NAMESPACE
+#define ILMTHREAD_INTERNAL_NAMESPACE ILMTHREAD_NAMESPACE
+#endif
+
+//
+// We need to be sure that we import the internal namespace into the public one.
+// To do this, we use the small bit of code below which initially defines
+// ILMTHREAD_INTERNAL_NAMESPACE (so it can be referenced) and then defines
+// ILMTHREAD_NAMESPACE and pulls the internal symbols into the public
+// namespace.
+//
+
+namespace ILMTHREAD_INTERNAL_NAMESPACE {}
+namespace ILMTHREAD_NAMESPACE {
+     using namespace ILMTHREAD_INTERNAL_NAMESPACE;
+}
+
+//
+// There are identical pairs of HEADER/SOURCE ENTER/EXIT macros so that
+// future extension to the namespace mechanism is possible without changing
+// project source code.
+//
+
+#define ILMTHREAD_INTERNAL_NAMESPACE_HEADER_ENTER namespace ILMTHREAD_INTERNAL_NAMESPACE {
+#define ILMTHREAD_INTERNAL_NAMESPACE_HEADER_EXIT }
+
+#define ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_ENTER namespace ILMTHREAD_INTERNAL_NAMESPACE {
+#define ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_EXIT }
+
+#endif // INCLUDED_ILMTHREADNAMESPACE_H
diff --git a/Source/OpenEXR/IlmThread/IlmThreadPool.cpp b/Source/OpenEXR/IlmThread/IlmThreadPool.cpp
index 68f2d03..0a889f8 100644
--- a/Source/OpenEXR/IlmThread/IlmThreadPool.cpp
+++ b/Source/OpenEXR/IlmThread/IlmThreadPool.cpp
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -47,7 +47,7 @@
 
 using namespace std;
 
-namespace IlmThread {
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_ENTER
 namespace {
 
 class WorkerThread: public Thread
@@ -74,8 +74,10 @@ struct TaskGroup::Data
     void	addTask () ;
     void	removeTask ();
     
-    Semaphore	isEmpty;	// used to signal that the taskgroup is empty
-    int		numPending;	// number of pending tasks to still execute
+    Semaphore	isEmpty;        // used to signal that the taskgroup is empty
+    int         numPending;     // number of pending tasks to still execute
+    Mutex       dtorMutex;      // used to work around the glibc bug:
+                                // http://sources.redhat.com/bugzilla/show_bug.cgi?id=12674
 };
 
 
@@ -182,6 +184,18 @@ TaskGroup::Data::~Data ()
     //
 
     isEmpty.wait ();
+
+    // Alas, given the current bug in glibc we need a secondary
+    // syncronisation primitive here to account for the fact that
+    // destructing the isEmpty Semaphore in this thread can cause
+    // an error for a separate thread that is issuing the post() call.
+    // We are entitled to destruct the semaphore at this point, however,
+    // that post() call attempts to access data out of the associated
+    // memory *after* it has woken the waiting threads, including this one,
+    // potentially leading to invalid memory reads.
+    // http://sources.redhat.com/bugzilla/show_bug.cgi?id=12674
+
+    Lock lock (dtorMutex);
 }
 
 
@@ -202,8 +216,21 @@ TaskGroup::Data::addTask ()
 void
 TaskGroup::Data::removeTask ()
 {
+    // Alas, given the current bug in glibc we need a secondary
+    // syncronisation primitive here to account for the fact that
+    // destructing the isEmpty Semaphore in a separate thread can
+    // cause an error. Issuing the post call here the current libc
+    // implementation attempts to access memory *after* it has woken
+    // waiting threads.
+    // Since other threads are entitled to delete the semaphore the
+    // access to the memory location can be invalid.
+    // http://sources.redhat.com/bugzilla/show_bug.cgi?id=12674
+
     if (--numPending == 0)
-	isEmpty.post ();
+    {
+        Lock lock (dtorMutex);
+        isEmpty.post ();
+    }
 }
     
 
@@ -349,7 +376,7 @@ void
 ThreadPool::setNumThreads (int count)
 {
     if (count < 0)
-        throw Iex::ArgExc ("Attempt to set the number of threads "
+        throw IEX_INTERNAL_NAMESPACE::ArgExc ("Attempt to set the number of threads "
 			   "in a thread pool to a negative value.");
 
     //
@@ -453,4 +480,4 @@ ThreadPool::addGlobalTask (Task* task)
 }
 
 
-} // namespace IlmThread
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/IlmThread/IlmThreadPool.h b/Source/OpenEXR/IlmThread/IlmThreadPool.h
index 7ea91d3..d436d4e 100644
--- a/Source/OpenEXR/IlmThread/IlmThreadPool.h
+++ b/Source/OpenEXR/IlmThread/IlmThreadPool.h
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -35,6 +35,7 @@
 #ifndef INCLUDED_ILM_THREAD_POOL_H
 #define INCLUDED_ILM_THREAD_POOL_H
 
+
 //-----------------------------------------------------------------------------
 //
 //	class Task, class ThreadPool, class TaskGroup
@@ -43,11 +44,11 @@
 //	tasks for processing.  Tasks added to the thread pool are
 //	executed concurrently by the worker threads.  
 //	
-//	Class Thread provides an abstract interface for a task which
+//	Class Task provides an abstract interface for a task which
 //	a ThreadPool works on.  Derived classes need to implement the
 //	execute() function which performs the actual task.
 //
-//	Class TaskTroup allows synchronization on the completion of a set
+//	Class TaskGroup allows synchronization on the completion of a set
 //	of tasks.  Every task that is added to a ThreadPool belongs to a
 //	single TaskGroup.  The destructor of the TaskGroup waits for all
 //	tasks in the group to finish.
@@ -60,13 +61,16 @@
 //
 //-----------------------------------------------------------------------------
 
-namespace IlmThread {
+#include "IlmThreadNamespace.h"
+#include "IlmThreadExport.h"
+
+ILMTHREAD_INTERNAL_NAMESPACE_HEADER_ENTER
 
 class TaskGroup;
 class Task;
 
 
-class ThreadPool  
+class ILMTHREAD_EXPORT ThreadPool  
 {
   public:
 
@@ -123,7 +127,7 @@ class ThreadPool
 };
 
 
-class Task
+class ILMTHREAD_EXPORT Task
 {
   public:
 
@@ -139,11 +143,11 @@ class Task
 };
 
 
-class TaskGroup
+class ILMTHREAD_EXPORT TaskGroup
 {
   public:
 
-     TaskGroup();
+    TaskGroup();
     ~TaskGroup();
 
     struct Data;
@@ -151,6 +155,6 @@ class TaskGroup
 };
 
 
-} // namespace IlmThread
+ILMTHREAD_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_ILM_THREAD_POOL_H
diff --git a/Source/OpenEXR/IlmThread/IlmThreadPosix.cpp b/Source/OpenEXR/IlmThread/IlmThreadPosix.cpp
index 1fe74f7..c487e39 100644
--- a/Source/OpenEXR/IlmThread/IlmThreadPosix.cpp
+++ b/Source/OpenEXR/IlmThread/IlmThreadPosix.cpp
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -52,7 +52,7 @@ extern "C"
     typedef void * (* Start) (void *);
 }
 
-namespace IlmThread {
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 bool
@@ -89,10 +89,10 @@ void
 Thread::start ()
 {
     if (int error = ::pthread_create (&_thread, 0, Start (threadLoop), this))
-	Iex::throwErrnoExc ("Cannot create new thread (%T).", error);
+	IEX_NAMESPACE::throwErrnoExc ("Cannot create new thread (%T).", error);
 }
 
 
-} // namespace IlmThread
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_EXIT
 
 #endif
diff --git a/Source/OpenEXR/IlmThread/IlmThreadSemaphore.cpp b/Source/OpenEXR/IlmThread/IlmThreadSemaphore.cpp
index 486aeba..f9d0661 100644
--- a/Source/OpenEXR/IlmThread/IlmThreadSemaphore.cpp
+++ b/Source/OpenEXR/IlmThread/IlmThreadSemaphore.cpp
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -41,10 +41,10 @@
 
 #include "IlmBaseConfig.h"
 
-//#if !defined (_WIN32) && !(_WIN64) && !(HAVE_PTHREAD)
+//#if !defined(_WIN32) && !defined(_WIN64) && !defined(HAVE_PTHREAD)
 #include "IlmThreadSemaphore.h"
 
-namespace IlmThread {
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 Semaphore::Semaphore (unsigned int value) {}
@@ -55,6 +55,6 @@ void Semaphore::post () {}
 int Semaphore::value () const {return 0;}
 
 
-} // namespace IlmThread
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_EXIT
 
 //#endif
diff --git a/Source/OpenEXR/IlmThread/IlmThreadSemaphore.h b/Source/OpenEXR/IlmThread/IlmThreadSemaphore.h
index a9ba60a..46cfd02 100644
--- a/Source/OpenEXR/IlmThread/IlmThreadSemaphore.h
+++ b/Source/OpenEXR/IlmThread/IlmThreadSemaphore.h
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -43,6 +43,8 @@
 //-----------------------------------------------------------------------------
 
 #include "IlmBaseConfig.h"
+#include "IlmThreadExport.h"
+#include "IlmThreadNamespace.h"
 
 #if defined _WIN32 || defined _WIN64
     #ifdef NOMINMAX
@@ -56,10 +58,10 @@
     #include <semaphore.h>
 #endif
 
-namespace IlmThread {
+ILMTHREAD_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
-class Semaphore
+class ILMTHREAD_EXPORT Semaphore
 {
   public:
 
@@ -105,6 +107,6 @@ class Semaphore
 };
 
 
-} // namespace IlmThread
+ILMTHREAD_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_ILM_THREAD_SEMAPHORE_H
diff --git a/Source/OpenEXR/IlmThread/IlmThreadSemaphorePosix.cpp b/Source/OpenEXR/IlmThread/IlmThreadSemaphorePosix.cpp
index b5e206e..400d90e 100644
--- a/Source/OpenEXR/IlmThread/IlmThreadSemaphorePosix.cpp
+++ b/Source/OpenEXR/IlmThread/IlmThreadSemaphorePosix.cpp
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -46,14 +46,15 @@
 #include "IlmThreadSemaphore.h"
 #include "Iex.h"
 #include <assert.h>
+#include <errno.h>
 
-namespace IlmThread {
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 Semaphore::Semaphore (unsigned int value)
 {
     if (::sem_init (&_semaphore, 0, value))
-	Iex::throwErrnoExc ("Cannot initialize semaphore (%T).");
+	IEX_NAMESPACE::throwErrnoExc ("Cannot initialize semaphore (%T).");
 }
 
 
@@ -67,7 +68,9 @@ Semaphore::~Semaphore ()
 void
 Semaphore::wait ()
 {
-    ::sem_wait (&_semaphore);
+    while( ::sem_wait( &_semaphore ) == -1 && errno == EINTR )
+    {
+    }
 }
 
 
@@ -82,7 +85,7 @@ void
 Semaphore::post ()
 {
     if (::sem_post (&_semaphore))
-        Iex::throwErrnoExc ("Post operation on semaphore failed (%T).");
+        IEX_NAMESPACE::throwErrnoExc ("Post operation on semaphore failed (%T).");
 }
 
 
@@ -92,12 +95,12 @@ Semaphore::value () const
     int value;
 
     if (::sem_getvalue (&_semaphore, &value))
-        Iex::throwErrnoExc ("Cannot read semaphore value (%T).");
+        IEX_NAMESPACE::throwErrnoExc ("Cannot read semaphore value (%T).");
 
     return value;
 }
 
 
-} // namespace IlmThread
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_EXIT
 
 #endif
diff --git a/Source/OpenEXR/IlmThread/IlmThreadSemaphorePosixCompat.cpp b/Source/OpenEXR/IlmThread/IlmThreadSemaphorePosixCompat.cpp
index 33f2a5b..29b109d 100644
--- a/Source/OpenEXR/IlmThread/IlmThreadSemaphorePosixCompat.cpp
+++ b/Source/OpenEXR/IlmThread/IlmThreadSemaphorePosixCompat.cpp
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -48,16 +48,16 @@
 #include "Iex.h"
 #include <assert.h>
 
-namespace IlmThread {
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 Semaphore::Semaphore (unsigned int value)
 {
     if (int error = ::pthread_mutex_init (&_semaphore.mutex, 0))
-        Iex::throwErrnoExc ("Cannot initialize mutex (%T).", error);
+        IEX_NAMESPACE::throwErrnoExc ("Cannot initialize mutex (%T).", error);
 
     if (int error = ::pthread_cond_init (&_semaphore.nonZero, 0))
-        Iex::throwErrnoExc ("Cannot initialize condition variable (%T).",
+        IEX_NAMESPACE::throwErrnoExc ("Cannot initialize condition variable (%T).",
                             error);
 
     _semaphore.count = value;
@@ -85,12 +85,12 @@ Semaphore::wait ()
     {
         if (int error = ::pthread_cond_wait (&_semaphore.nonZero,
                                              &_semaphore.mutex))
-	{
+        {
             ::pthread_mutex_unlock (&_semaphore.mutex);
 
-            Iex::throwErrnoExc ("Cannot wait on condition variable (%T).",
-                                error);
-	}
+            IEX_NAMESPACE::throwErrnoExc ("Cannot wait on condition variable (%T).",
+                                          error);
+        }
     }
 
     _semaphore.numWaiting--;
@@ -127,12 +127,12 @@ Semaphore::post ()
     if (_semaphore.numWaiting > 0)
     {
         if (int error = ::pthread_cond_signal (&_semaphore.nonZero))
-	{
+        {
             ::pthread_mutex_unlock (&_semaphore.mutex);
 
-            Iex::throwErrnoExc ("Cannot signal condition variable (%T).",
+            IEX_NAMESPACE::throwErrnoExc ("Cannot signal condition variable (%T).",
                                 error);
-	}
+        }
     }
 
     _semaphore.count++;
@@ -150,6 +150,6 @@ Semaphore::value () const
 }
 
 
-} // namespace IlmThread
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_EXIT
 
 #endif
diff --git a/Source/OpenEXR/IlmThread/IlmThreadSemaphoreWin32.cpp b/Source/OpenEXR/IlmThread/IlmThreadSemaphoreWin32.cpp
index 19cd625..4971d46 100644
--- a/Source/OpenEXR/IlmThread/IlmThreadSemaphoreWin32.cpp
+++ b/Source/OpenEXR/IlmThread/IlmThreadSemaphoreWin32.cpp
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -38,15 +38,19 @@
 //
 //-----------------------------------------------------------------------------
 
+#include "IlmBaseConfig.h"
+
+#if defined(_WIN32) && !defined(HAVE_PTHREAD) && !defined(HAVE_POSIX_SEMAPHORES)
+
 #include "IlmThreadSemaphore.h"
 #include "Iex.h"
 #include <string>
 #include <assert.h>
 #include <iostream>
 
-namespace IlmThread {
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_ENTER
 
-using namespace Iex;
+using namespace IEX_NAMESPACE;
 
 namespace {
 
@@ -143,4 +147,7 @@ Semaphore::value() const
     return v;
 }
 
-} // namespace IlmThread
+
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_EXIT
+
+#endif
diff --git a/Source/OpenEXR/IlmThread/IlmThreadWin32.cpp b/Source/OpenEXR/IlmThread/IlmThreadWin32.cpp
index cd54759..08ad2c2 100644
--- a/Source/OpenEXR/IlmThread/IlmThreadWin32.cpp
+++ b/Source/OpenEXR/IlmThread/IlmThreadWin32.cpp
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -38,13 +38,16 @@
 //
 //-----------------------------------------------------------------------------
 
+#include "IlmBaseConfig.h"
+
+#if !defined(HAVE_PTHREAD) && defined(_WIN32)
 
 #include "IlmThread.h"
 #include "Iex.h"
 #include <iostream>
 #include <assert.h>
 
-namespace IlmThread {
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 bool
@@ -88,8 +91,10 @@ Thread::start ()
     _thread = (HANDLE)::_beginthreadex (0, 0, &threadLoop, this, 0, &id);
 
     if (_thread == 0)
-	Iex::throwErrnoExc ("Cannot create new thread (%T).");
+        IEX_NAMESPACE::throwErrnoExc ("Cannot create new thread (%T).");
 }
 
 
-} // namespace IlmThread
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_EXIT
+
+#endif
diff --git a/Source/OpenEXR/IlmThread/Makefile.am b/Source/OpenEXR/IlmThread/Makefile.am
deleted file mode 100644
index d46368a..0000000
--- a/Source/OpenEXR/IlmThread/Makefile.am
+++ /dev/null
@@ -1,26 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-lib_LTLIBRARIES = libIlmThread.la
-
-libIlmThread_la_SOURCES = IlmThreadPool.h IlmThread.h \
-			  IlmThreadSemaphore.h IlmThreadMutex.h \
-			  IlmThreadPool.cpp IlmThread.cpp \
-			  IlmThreadSemaphore.cpp IlmThreadMutex.cpp \
-			  IlmThreadPosix.cpp IlmThreadSemaphorePosix.cpp \
-			  IlmThreadSemaphorePosixCompat.cpp \
-			  IlmThreadMutexPosix.cpp
-
-libIlmThread_la_LDFLAGS = -version-info @LIBTOOL_VERSION@ -no-undefined
-libIlmThread_la_LIBADD = ../Iex/libIex.la
-
-libIlmThreadincludedir = $(includedir)/OpenEXR
-
-libIlmThreadinclude_HEADERS = IlmThreadPool.h IlmThread.h \
-			      IlmThreadSemaphore.h IlmThreadMutex.h
-
-noinst_HEADERS = 
-
-EXTRA_DIST = $(noinst_HEADERS) IlmThreadMutexWin32.cpp IlmThreadSemaphoreWin32.cpp \
-	     IlmThreadWin32.cpp
-
-INCLUDES = -I$(top_builddir) -I$(top_srcdir)/Iex -I$(top_srcdir)/config
\ No newline at end of file
diff --git a/Source/OpenEXR/IlmThread/Makefile.in b/Source/OpenEXR/IlmThread/Makefile.in
deleted file mode 100644
index e8f457c..0000000
--- a/Source/OpenEXR/IlmThread/Makefile.in
+++ /dev/null
@@ -1,539 +0,0 @@
-# Makefile.in generated by automake 1.9.6 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005  Free Software Foundation, Inc.
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
- at SET_MAKE@
-
-
-srcdir = @srcdir@
-top_srcdir = @top_srcdir@
-VPATH = @srcdir@
-pkgdatadir = $(datadir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-top_builddir = ..
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-INSTALL = @INSTALL@
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-build_triplet = @build@
-host_triplet = @host@
-subdir = IlmThread
-DIST_COMMON = $(libIlmThreadinclude_HEADERS) $(noinst_HEADERS) \
-	$(srcdir)/Makefile.am $(srcdir)/Makefile.in
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
-	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
-	$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
-	$(top_srcdir)/m4/threads.m4 $(top_srcdir)/configure.ac
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
-	$(ACLOCAL_M4)
-mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config/IlmBaseConfig.h
-CONFIG_CLEAN_FILES =
-am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
-am__vpath_adj = case $$p in \
-    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
-    *) f=$$p;; \
-  esac;
-am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
-am__installdirs = "$(DESTDIR)$(libdir)" \
-	"$(DESTDIR)$(libIlmThreadincludedir)"
-libLTLIBRARIES_INSTALL = $(INSTALL)
-LTLIBRARIES = $(lib_LTLIBRARIES)
-libIlmThread_la_DEPENDENCIES = ../Iex/libIex.la
-am_libIlmThread_la_OBJECTS = IlmThreadPool.lo IlmThread.lo \
-	IlmThreadSemaphore.lo IlmThreadMutex.lo IlmThreadPosix.lo \
-	IlmThreadSemaphorePosix.lo IlmThreadSemaphorePosixCompat.lo \
-	IlmThreadMutexPosix.lo
-libIlmThread_la_OBJECTS = $(am_libIlmThread_la_OBJECTS)
-DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/config
-depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
-CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
-	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
-LTCXXCOMPILE = $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) \
-	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
-	$(AM_CXXFLAGS) $(CXXFLAGS)
-CXXLD = $(CXX)
-CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \
-	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
-COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
-	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
-	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
-	$(AM_CFLAGS) $(CFLAGS)
-CCLD = $(CC)
-LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
-	$(AM_LDFLAGS) $(LDFLAGS) -o $@
-SOURCES = $(libIlmThread_la_SOURCES)
-DIST_SOURCES = $(libIlmThread_la_SOURCES)
-libIlmThreadincludeHEADERS_INSTALL = $(INSTALL_HEADER)
-HEADERS = $(libIlmThreadinclude_HEADERS) $(noinst_HEADERS)
-ETAGS = etags
-CTAGS = ctags
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = @ACLOCAL@
-AMDEP_FALSE = @AMDEP_FALSE@
-AMDEP_TRUE = @AMDEP_TRUE@
-AMTAR = @AMTAR@
-AM_CFLAGS = @AM_CFLAGS@
-AM_CXXFLAGS = @AM_CXXFLAGS@
-AR = @AR@
-AUTOCONF = @AUTOCONF@
-AUTOHEADER = @AUTOHEADER@
-AUTOMAKE = @AUTOMAKE@
-AWK = @AWK@
-CC = @CC@
-CCDEPMODE = @CCDEPMODE@
-CFLAGS = @CFLAGS@
-CPP = @CPP@
-CPPFLAGS = @CPPFLAGS@
-CXX = @CXX@
-CXXCPP = @CXXCPP@
-CXXDEPMODE = @CXXDEPMODE@
-CXXFLAGS = @CXXFLAGS@
-CYGPATH_W = @CYGPATH_W@
-DEFS = @DEFS@
-DEPDIR = @DEPDIR@
-DSYMUTIL = @DSYMUTIL@
-DUMPBIN = @DUMPBIN@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EGREP = @EGREP@
-EXEEXT = @EXEEXT@
-FGREP = @FGREP@
-GREP = @GREP@
-HAVE_UCONTEXT_H = @HAVE_UCONTEXT_H@
-ILMBASE_VERSION = @ILMBASE_VERSION@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LD = @LD@
-LDFLAGS = @LDFLAGS@
-LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
-LIBTOOL = @LIBTOOL@
-LIBTOOL_VERSION = @LIBTOOL_VERSION@
-LIPO = @LIPO@
-LN_S = @LN_S@
-LTLIBOBJS = @LTLIBOBJS@
-MAINT = @MAINT@
-MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
-MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
-MAKEINFO = @MAKEINFO@
-NM = @NM@
-NMEDIT = @NMEDIT@
-OBJDUMP = @OBJDUMP@
-OBJEXT = @OBJEXT@
-OTOOL = @OTOOL@
-OTOOL64 = @OTOOL64@
-PACKAGE = @PACKAGE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-PTHREAD_CC = @PTHREAD_CC@
-PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
-PTHREAD_LIBS = @PTHREAD_LIBS@
-RANLIB = @RANLIB@
-SED = @SED@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-STRIP = @STRIP@
-VERSION = @VERSION@
-ac_ct_AR = @ac_ct_AR@
-ac_ct_CC = @ac_ct_CC@
-ac_ct_CXX = @ac_ct_CXX@
-ac_ct_DSYMUTIL = @ac_ct_DSYMUTIL@
-ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
-ac_ct_LIPO = @ac_ct_LIPO@
-ac_ct_NMEDIT = @ac_ct_NMEDIT@
-ac_ct_OBJDUMP = @ac_ct_OBJDUMP@
-ac_ct_OTOOL = @ac_ct_OTOOL@
-ac_ct_OTOOL64 = @ac_ct_OTOOL64@
-ac_ct_RANLIB = @ac_ct_RANLIB@
-ac_ct_STRIP = @ac_ct_STRIP@
-acx_pthread_config = @acx_pthread_config@
-am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
-am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
-am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
-am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
-am__include = @am__include@
-am__leading_dot = @am__leading_dot@
-am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
-bindir = @bindir@
-build = @build@
-build_alias = @build_alias@
-build_cpu = @build_cpu@
-build_os = @build_os@
-build_vendor = @build_vendor@
-datadir = @datadir@
-exec_prefix = @exec_prefix@
-host = @host@
-host_alias = @host_alias@
-host_cpu = @host_cpu@
-host_os = @host_os@
-host_vendor = @host_vendor@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-libdir = @libdir@
-libexecdir = @libexecdir@
-localstatedir = @localstatedir@
-lt_ECHO = @lt_ECHO@
-mandir = @mandir@
-mkdir_p = @mkdir_p@
-oldincludedir = @oldincludedir@
-prefix = @prefix@
-program_transform_name = @program_transform_name@
-sbindir = @sbindir@
-sharedstatedir = @sharedstatedir@
-sysconfdir = @sysconfdir@
-target_alias = @target_alias@
-lib_LTLIBRARIES = libIlmThread.la
-libIlmThread_la_SOURCES = IlmThreadPool.h IlmThread.h \
-			  IlmThreadSemaphore.h IlmThreadMutex.h \
-			  IlmThreadPool.cpp IlmThread.cpp \
-			  IlmThreadSemaphore.cpp IlmThreadMutex.cpp \
-			  IlmThreadPosix.cpp IlmThreadSemaphorePosix.cpp \
-			  IlmThreadSemaphorePosixCompat.cpp \
-			  IlmThreadMutexPosix.cpp
-
-libIlmThread_la_LDFLAGS = -version-info @LIBTOOL_VERSION@ -no-undefined
-libIlmThread_la_LIBADD = ../Iex/libIex.la
-libIlmThreadincludedir = $(includedir)/OpenEXR
-libIlmThreadinclude_HEADERS = IlmThreadPool.h IlmThread.h \
-			      IlmThreadSemaphore.h IlmThreadMutex.h
-
-noinst_HEADERS = 
-EXTRA_DIST = $(noinst_HEADERS) IlmThreadMutexWin32.cpp IlmThreadSemaphoreWin32.cpp \
-	     IlmThreadWin32.cpp
-
-INCLUDES = -I$(top_builddir) -I$(top_srcdir)/Iex -I$(top_srcdir)/config
-all: all-am
-
-.SUFFIXES:
-.SUFFIXES: .cpp .lo .o .obj
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
-	@for dep in $?; do \
-	  case '$(am__configure_deps)' in \
-	    *$$dep*) \
-	      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
-		&& exit 0; \
-	      exit 1;; \
-	  esac; \
-	done; \
-	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu  IlmThread/Makefile'; \
-	cd $(top_srcdir) && \
-	  $(AUTOMAKE) --gnu  IlmThread/Makefile
-.PRECIOUS: Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
-	@case '$?' in \
-	  *config.status*) \
-	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
-	  *) \
-	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
-	esac;
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-install-libLTLIBRARIES: $(lib_LTLIBRARIES)
-	@$(NORMAL_INSTALL)
-	test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)"
-	@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
-	  if test -f $$p; then \
-	    f=$(am__strip_dir) \
-	    echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
-	    $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
-	  else :; fi; \
-	done
-
-uninstall-libLTLIBRARIES:
-	@$(NORMAL_UNINSTALL)
-	@set -x; list='$(lib_LTLIBRARIES)'; for p in $$list; do \
-	  p=$(am__strip_dir) \
-	  echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
-	  $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
-	done
-
-clean-libLTLIBRARIES:
-	-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
-	@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
-	  dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
-	  test "$$dir" != "$$p" || dir=.; \
-	  echo "rm -f \"$${dir}/so_locations\""; \
-	  rm -f "$${dir}/so_locations"; \
-	done
-libIlmThread.la: $(libIlmThread_la_OBJECTS) $(libIlmThread_la_DEPENDENCIES) 
-	$(CXXLINK) -rpath $(libdir) $(libIlmThread_la_LDFLAGS) $(libIlmThread_la_OBJECTS) $(libIlmThread_la_LIBADD) $(LIBS)
-
-mostlyclean-compile:
-	-rm -f *.$(OBJEXT)
-
-distclean-compile:
-	-rm -f *.tab.c
-
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/IlmThread.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/IlmThreadMutex.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/IlmThreadMutexPosix.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/IlmThreadPool.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/IlmThreadPosix.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/IlmThreadSemaphore.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/IlmThreadSemaphorePosix.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/IlmThreadSemaphorePosixCompat.Plo at am__quote@
-
-.cpp.o:
- at am__fastdepCXX_TRUE@	if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
- at am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(CXXCOMPILE) -c -o $@ $<
-
-.cpp.obj:
- at am__fastdepCXX_TRUE@	if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
- at am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
-
-.cpp.lo:
- at am__fastdepCXX_TRUE@	if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
- at am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(LTCXXCOMPILE) -c -o $@ $<
-
-mostlyclean-libtool:
-	-rm -f *.lo
-
-clean-libtool:
-	-rm -rf .libs _libs
-
-distclean-libtool:
-	-rm -f libtool
-uninstall-info-am:
-install-libIlmThreadincludeHEADERS: $(libIlmThreadinclude_HEADERS)
-	@$(NORMAL_INSTALL)
-	test -z "$(libIlmThreadincludedir)" || $(mkdir_p) "$(DESTDIR)$(libIlmThreadincludedir)"
-	@list='$(libIlmThreadinclude_HEADERS)'; for p in $$list; do \
-	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
-	  f=$(am__strip_dir) \
-	  echo " $(libIlmThreadincludeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(libIlmThreadincludedir)/$$f'"; \
-	  $(libIlmThreadincludeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(libIlmThreadincludedir)/$$f"; \
-	done
-
-uninstall-libIlmThreadincludeHEADERS:
-	@$(NORMAL_UNINSTALL)
-	@list='$(libIlmThreadinclude_HEADERS)'; for p in $$list; do \
-	  f=$(am__strip_dir) \
-	  echo " rm -f '$(DESTDIR)$(libIlmThreadincludedir)/$$f'"; \
-	  rm -f "$(DESTDIR)$(libIlmThreadincludedir)/$$f"; \
-	done
-
-ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
-	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
-	unique=`for i in $$list; do \
-	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
-	mkid -fID $$unique
-tags: TAGS
-
-TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
-		$(TAGS_FILES) $(LISP)
-	tags=; \
-	here=`pwd`; \
-	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
-	unique=`for i in $$list; do \
-	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
-	if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
-	  test -n "$$unique" || unique=$$empty_fix; \
-	  $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
-	    $$tags $$unique; \
-	fi
-ctags: CTAGS
-CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
-		$(TAGS_FILES) $(LISP)
-	tags=; \
-	here=`pwd`; \
-	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
-	unique=`for i in $$list; do \
-	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
-	test -z "$(CTAGS_ARGS)$$tags$$unique" \
-	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
-	     $$tags $$unique
-
-GTAGS:
-	here=`$(am__cd) $(top_builddir) && pwd` \
-	  && cd $(top_srcdir) \
-	  && gtags -i $(GTAGS_ARGS) $$here
-
-distclean-tags:
-	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
-distdir: $(DISTFILES)
-	@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
-	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
-	list='$(DISTFILES)'; for file in $$list; do \
-	  case $$file in \
-	    $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
-	    $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
-	  esac; \
-	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
-	  dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
-	  if test "$$dir" != "$$file" && test "$$dir" != "."; then \
-	    dir="/$$dir"; \
-	    $(mkdir_p) "$(distdir)$$dir"; \
-	  else \
-	    dir=''; \
-	  fi; \
-	  if test -d $$d/$$file; then \
-	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
-	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
-	    fi; \
-	    cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
-	  else \
-	    test -f $(distdir)/$$file \
-	    || cp -p $$d/$$file $(distdir)/$$file \
-	    || exit 1; \
-	  fi; \
-	done
-check-am: all-am
-check: check-am
-all-am: Makefile $(LTLIBRARIES) $(HEADERS)
-installdirs:
-	for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libIlmThreadincludedir)"; do \
-	  test -z "$$dir" || $(mkdir_p) "$$dir"; \
-	done
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
-	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
-	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	  `test -z '$(STRIP)' || \
-	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
-mostlyclean-generic:
-
-clean-generic:
-
-distclean-generic:
-	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-
-maintainer-clean-generic:
-	@echo "This command is intended for maintainers to use"
-	@echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
-
-clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
-	mostlyclean-am
-
-distclean: distclean-am
-	-rm -rf ./$(DEPDIR)
-	-rm -f Makefile
-distclean-am: clean-am distclean-compile distclean-generic \
-	distclean-libtool distclean-tags
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-info: info-am
-
-info-am:
-
-install-data-am: install-libIlmThreadincludeHEADERS
-
-install-exec-am: install-libLTLIBRARIES
-
-install-info: install-info-am
-
-install-man:
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
-	-rm -rf ./$(DEPDIR)
-	-rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-compile mostlyclean-generic \
-	mostlyclean-libtool
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am: uninstall-info-am uninstall-libIlmThreadincludeHEADERS \
-	uninstall-libLTLIBRARIES
-
-.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
-	clean-libLTLIBRARIES clean-libtool ctags distclean \
-	distclean-compile distclean-generic distclean-libtool \
-	distclean-tags distdir dvi dvi-am html html-am info info-am \
-	install install-am install-data install-data-am install-exec \
-	install-exec-am install-info install-info-am \
-	install-libIlmThreadincludeHEADERS install-libLTLIBRARIES \
-	install-man install-strip installcheck installcheck-am \
-	installdirs maintainer-clean maintainer-clean-generic \
-	mostlyclean mostlyclean-compile mostlyclean-generic \
-	mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \
-	uninstall-am uninstall-info-am \
-	uninstall-libIlmThreadincludeHEADERS uninstall-libLTLIBRARIES
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
diff --git a/Source/OpenEXR/Imath/ImathBox.h b/Source/OpenEXR/Imath/ImathBox.h
index 7dc4eb7..45165ff 100644
--- a/Source/OpenEXR/Imath/ImathBox.h
+++ b/Source/OpenEXR/Imath/ImathBox.h
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2004-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -63,8 +63,9 @@
 //-------------------------------------------------------------------
 
 #include "ImathVec.h"
+#include "ImathNamespace.h"
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 template <class T>	
@@ -843,8 +844,6 @@ Box<Vec3<T> >::majorAxis() const
 }
 
 
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-
-} // namespace Imath
-
-#endif
+#endif // INCLUDED_IMATHBOX_H
diff --git a/Source/OpenEXR/Imath/ImathBoxAlgo.h b/Source/OpenEXR/Imath/ImathBoxAlgo.h
index 3d6e4e0..63bd2f6 100644
--- a/Source/OpenEXR/Imath/ImathBoxAlgo.h
+++ b/Source/OpenEXR/Imath/ImathBoxAlgo.h
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002-2010, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -79,8 +79,9 @@
 #include "ImathMatrix.h"
 #include "ImathLineAlgo.h"
 #include "ImathPlane.h"
+#include "ImathNamespace.h"
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 template <class T>
@@ -1010,6 +1011,6 @@ intersects (const Box< Vec3<T> > &box, const Line3<T> &ray)
 }
 
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_IMATHBOXALGO_H
diff --git a/Source/OpenEXR/Imath/ImathColor.h b/Source/OpenEXR/Imath/ImathColor.h
index 605f10b..743c72d 100644
--- a/Source/OpenEXR/Imath/ImathColor.h
+++ b/Source/OpenEXR/Imath/ImathColor.h
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2004-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -44,9 +44,10 @@
 //----------------------------------------------------
 
 #include "ImathVec.h"
+#include "ImathNamespace.h"
 #include "half.h"
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 template <class T>
@@ -729,6 +730,7 @@ operator * (S x, const Color4<T> &v)
     return Color4<T> (x * v.r, x * v.g, x * v.b, x * v.a);
 }
 
-} // namespace Imath
 
-#endif 
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif // INCLUDED_IMATHCOLOR_H 
diff --git a/Source/OpenEXR/Imath/ImathColorAlgo.cpp b/Source/OpenEXR/Imath/ImathColorAlgo.cpp
index c624680..a351c40 100644
--- a/Source/OpenEXR/Imath/ImathColorAlgo.cpp
+++ b/Source/OpenEXR/Imath/ImathColorAlgo.cpp
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -41,7 +41,7 @@
 
 #include "ImathColorAlgo.h"
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 Vec3<double>
@@ -175,4 +175,4 @@ rgb2hsv_d(const Color4<double> &c)
 }
 
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/Imath/ImathColorAlgo.h b/Source/OpenEXR/Imath/ImathColorAlgo.h
index 68703a1..cbc3be4 100644
--- a/Source/OpenEXR/Imath/ImathColorAlgo.h
+++ b/Source/OpenEXR/Imath/ImathColorAlgo.h
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -39,10 +39,12 @@
 
 
 #include "ImathColor.h"
+#include "ImathExport.h"
 #include "ImathMath.h"
 #include "ImathLimits.h"
+#include "ImathNamespace.h"
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 //
@@ -50,14 +52,13 @@ namespace Imath {
 //	These routines eliminate type warnings under g++.
 //
 
-Vec3<double>	hsv2rgb_d(const Vec3<double> &hsv);
+IMATH_EXPORT Vec3<double>	hsv2rgb_d(const Vec3<double> &hsv);
 
-Color4<double>	hsv2rgb_d(const Color4<double> &hsv);
+IMATH_EXPORT Color4<double>	hsv2rgb_d(const Color4<double> &hsv);
 
+IMATH_EXPORT Vec3<double>	rgb2hsv_d(const Vec3<double> &rgb);
 
-Vec3<double>	rgb2hsv_d(const Vec3<double> &rgb);
-
-Color4<double>	rgb2hsv_d(const Color4<double> &rgb);
+IMATH_EXPORT Color4<double>	rgb2hsv_d(const Color4<double> &rgb);
 
 
 //
@@ -251,6 +252,6 @@ packed2rgb(PackedColor packed, Color4<T> &out)
 }
 
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif  
+#endif // INCLUDED_IMATHCOLORALGO_H
diff --git a/Source/OpenEXR/Imath/ImathEuler.h b/Source/OpenEXR/Imath/ImathEuler.h
index c81b5eb..254c76f 100644
--- a/Source/OpenEXR/Imath/ImathEuler.h
+++ b/Source/OpenEXR/Imath/ImathEuler.h
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -130,9 +130,11 @@
 #include "ImathQuat.h"
 #include "ImathMatrix.h"
 #include "ImathLimits.h"
+#include "ImathNamespace.h"
+
 #include <iostream>
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 #if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
 // Disable MS VC++ warnings about conversion from double to float
@@ -918,7 +920,7 @@ Euler<T>::makeNear (const Euler<T> &target)
 #pragma warning(default:4244)
 #endif
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
 
-#endif
+#endif // INCLUDED_IMATHEULER_H
diff --git a/Source/OpenEXR/Imath/ImathExc.h b/Source/OpenEXR/Imath/ImathExc.h
index 43781c5..65af3b5 100644
--- a/Source/OpenEXR/Imath/ImathExc.h
+++ b/Source/OpenEXR/Imath/ImathExc.h
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -33,7 +33,6 @@
 ///////////////////////////////////////////////////////////////////////////
 
 
-
 #ifndef INCLUDED_IMATHEXC_H
 #define INCLUDED_IMATHEXC_H
 
@@ -44,30 +43,31 @@
 //
 //-----------------------------------------------
 
+#include "ImathNamespace.h"
 #include "IexBaseExc.h"
+#include "ImathExport.h"
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
+// Attempt to normalize null vector
+DEFINE_EXC_EXP (IMATH_EXPORT, NullVecExc, ::IEX_NAMESPACE::MathExc)
 
-DEFINE_EXC (NullVecExc, ::Iex::MathExc)		// Attempt to normalize
-						// null vector
+// Attempt to normalize a point at infinity
+DEFINE_EXC_EXP (IMATH_EXPORT, InfPointExc, ::IEX_NAMESPACE::MathExc)
 
-DEFINE_EXC (InfPointExc, ::Iex::MathExc)	// Attempt to normalize
-                                                // a point at infinity
+// Attempt to normalize null quaternion
+DEFINE_EXC_EXP (IMATH_EXPORT, NullQuatExc, ::IEX_NAMESPACE::MathExc)
 
-DEFINE_EXC (NullQuatExc, ::Iex::MathExc) 	// Attempt to normalize
-						// null quaternion
+// Attempt to invert singular matrix
+DEFINE_EXC_EXP (IMATH_EXPORT, SingMatrixExc, ::IEX_NAMESPACE::MathExc)
 
-DEFINE_EXC (SingMatrixExc, ::Iex::MathExc)	// Attempt to invert
-						// singular matrix
+// Attempt to remove zero scaling from matrix
+DEFINE_EXC_EXP (IMATH_EXPORT, ZeroScaleExc, ::IEX_NAMESPACE::MathExc)
 
-DEFINE_EXC (ZeroScaleExc, ::Iex::MathExc)	// Attempt to remove zero
-						// scaling from matrix
+// Attempt to normalize a vector of whose elementsare an integer type
+DEFINE_EXC_EXP (IMATH_EXPORT, IntVecNormalizeExc, ::IEX_NAMESPACE::MathExc)
 
-DEFINE_EXC (IntVecNormalizeExc, ::Iex::MathExc)	// Attempt to normalize
-						// a vector of whose elements
-                                                // are an integer type
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_IMATHEXC_H
diff --git a/Source/OpenEXR/Imath/ImathExport.h b/Source/OpenEXR/Imath/ImathExport.h
new file mode 100644
index 0000000..4357c12
--- /dev/null
+++ b/Source/OpenEXR/Imath/ImathExport.h
@@ -0,0 +1,46 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2012, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission. 
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#if defined(OPENEXR_DLL)
+    #if defined(IMATH_EXPORTS)
+	    #define IMATH_EXPORT __declspec(dllexport)
+        #define IMATH_EXPORT_CONST extern __declspec(dllexport)
+    #else
+	    #define IMATH_EXPORT __declspec(dllimport)
+	    #define IMATH_EXPORT_CONST extern __declspec(dllimport)
+    #endif
+#else
+    #define IMATH_EXPORT
+    #define IMATH_EXPORT_CONST extern const
+#endif
diff --git a/Source/OpenEXR/Imath/ImathForward.h b/Source/OpenEXR/Imath/ImathForward.h
new file mode 100644
index 0000000..39d398c
--- /dev/null
+++ b/Source/OpenEXR/Imath/ImathForward.h
@@ -0,0 +1,72 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2012, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission. 
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef INCLUDED_IMATHFORWARD_H
+#define INCLUDED_IMATHFORWARD_H
+
+#include "ImathNamespace.h"
+
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
+
+//
+// Basic template type declarations.
+//
+
+template <class T> class Box;
+template <class T> class Color3;
+template <class T> class Color4;
+template <class T> class Euler;
+template <class T> class Frustum;
+template <class T> class FrustumTest;
+template <class T> class Interval;
+template <class T> class Line3;
+template <class T> class Matrix33;
+template <class T> class Matrix44;
+template <class T> class Plane3;
+template <class T> class Quat;
+template <class T> class Shear6;
+template <class T> class Sphere3;
+template <class T> class TMatrix;
+template <class T> class TMatrixBase;
+template <class T> class TMatrixData;
+template <class T> class Vec2;
+template <class T> class Vec3;
+template <class T> class Vec4;
+
+class Rand32;
+class Rand48;
+
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif // INCLUDED_IMATHFORWARD_H
diff --git a/Source/OpenEXR/Imath/ImathFrame.h b/Source/OpenEXR/Imath/ImathFrame.h
index 7291231..95ebb66 100644
--- a/Source/OpenEXR/Imath/ImathFrame.h
+++ b/Source/OpenEXR/Imath/ImathFrame.h
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -37,7 +37,9 @@
 #ifndef INCLUDED_IMATHFRAME_H
 #define INCLUDED_IMATHFRAME_H
 
-namespace Imath {
+#include "ImathNamespace.h"
+
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 template<class T> class Vec3;
 template<class T> class Matrix44;
@@ -50,12 +52,12 @@ template<class T> class Matrix44;
 //  
 //  A typical usage would be :
 //
-//      m[0] = Imath::firstFrame( p[0], p[1], p[2] );
+//      m[0] = IMATH_INTERNAL_NAMESPACE::firstFrame( p[0], p[1], p[2] );
 //      for( int i = 1; i < n - 1; i++ )
 //      {
-//          m[i] = Imath::nextFrame( m[i-1], p[i-1], p[i], t[i-1], t[i] );
+//          m[i] = IMATH_INTERNAL_NAMESPACE::nextFrame( m[i-1], p[i-1], p[i], t[i-1], t[i] );
 //      }
-//      m[n-1] = Imath::lastFrame( m[n-2], p[n-2], p[n-1] );
+//      m[n-1] = IMATH_INTERNAL_NAMESPACE::lastFrame( m[n-2], p[n-2], p[n-1] );
 //
 //  See Graphics Gems I for the underlying algorithm.
 // 
@@ -185,6 +187,6 @@ template<class T> Matrix44<T> lastFrame
     return Mi * Tr;
 }
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_IMATHFRAME_H
diff --git a/Source/OpenEXR/Imath/ImathFrustum.h b/Source/OpenEXR/Imath/ImathFrustum.h
index ac49346..4df92c9 100644
--- a/Source/OpenEXR/Imath/ImathFrustum.h
+++ b/Source/OpenEXR/Imath/ImathFrustum.h
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -44,24 +44,26 @@
 #include "ImathMatrix.h"
 #include "ImathLimits.h"
 #include "ImathFun.h"
+#include "ImathNamespace.h"
+
 #include "IexMathExc.h"
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 //
-//	template class Frustum<T>
+//  template class Frustum<T>
 //
-//	The frustum is always located with the eye point at the
-//	origin facing down -Z. This makes the Frustum class 
-//	compatable with OpenGL (or anything that assumes a camera
-//	looks down -Z, hence with a right-handed coordinate system) 
-//	but not with RenderMan which assumes the camera looks down
-//	+Z. Additional functions are provided for conversion from
-//	and from various camera coordinate spaces.
+//  The frustum is always located with the eye point at the
+//  origin facing down -Z. This makes the Frustum class
+//  compatable with OpenGL (or anything that assumes a camera
+//  looks down -Z, hence with a right-handed coordinate system)
+//  but not with RenderMan which assumes the camera looks down
+//  +Z. Additional functions are provided for conversion from
+//  and from various camera coordinate spaces.
 //
-//      nearPlane/farPlane: near/far are keywords used by Microsoft's
-//      compiler, so we use nearPlane/farPlane instead to avoid
-//      issues.  
+//  nearPlane/farPlane: near/far are keywords used by Microsoft's
+//  compiler, so we use nearPlane/farPlane instead to avoid
+//  issues.
 
 
 template<class T>
@@ -78,46 +80,46 @@ class Frustum
     // Assignment operator
     //--------------------
 
-    const Frustum &operator	= (const Frustum &);
+    const Frustum &     operator = (const Frustum &);
 
     //--------------------
     //  Operators:  ==, !=
     //--------------------
     
-    bool                        operator == (const Frustum<T> &src) const;
-    bool                        operator != (const Frustum<T> &src) const;
+    bool                operator == (const Frustum<T> &src) const;
+    bool                operator != (const Frustum<T> &src) const;
 
     //--------------------------------------------------------
     //  Set functions change the entire state of the Frustum
     //--------------------------------------------------------
 
-    void		set(T nearPlane, T farPlane, 
-			    T left, T right, 
-			    T top, T bottom, 
-			    bool ortho=false);
+    void                set(T nearPlane, T farPlane,
+                            T left, T right,
+                            T top, T bottom,
+                            bool ortho=false);
 
-    void		set(T nearPlane, T farPlane, T fovx, T fovy, T aspect);
+    void                set(T nearPlane, T farPlane, T fovx, T fovy, T aspect);
 
     //------------------------------------------------------
     //	These functions modify an already valid frustum state
     //------------------------------------------------------
 
-    void		modifyNearAndFar(T nearPlane, T farPlane);
-    void		setOrthographic(bool);
+    void                modifyNearAndFar(T nearPlane, T farPlane);
+    void                setOrthographic(bool);
 
     //--------------
     //  Access
     //--------------
     
-    bool		orthographic() const	{ return _orthographic; }
-    T			nearPlane() const	{ return _nearPlane;	}
-    T			hither() const		{ return _nearPlane;	}
-    T			farPlane() const	{ return _farPlane;	}
-    T			yon() const		{ return _farPlane;	}
-    T			left() const		{ return _left;		}
-    T			right() const		{ return _right;	}
-    T			bottom() const		{ return _bottom;	}
-    T			top() const		{ return _top;		}
+    bool                orthographic() const  { return _orthographic; }
+    T                   nearPlane() const     { return _nearPlane;    }
+    T                   hither() const        { return _nearPlane;    }
+    T                   farPlane() const      { return _farPlane;     }
+    T                   yon() const           { return _farPlane;     }
+    T                   left() const          { return _left;         }
+    T                   right() const         { return _right;        }
+    T                   bottom() const        { return _bottom;       }
+    T                   top() const           { return _top;          }
 
     //-----------------------------------------------------------------------
     //  Sets the planes in p to be the six bounding planes of the frustum, in
@@ -127,18 +129,18 @@ class Frustum
     //  to transform the frustum before setting the planes.
     //-----------------------------------------------------------------------
 
-    void		planes(Plane3<T> p[6]);
-    void		planes(Plane3<T> p[6], const Matrix44<T> &M);
+    void                planes(Plane3<T> p[6]) const;
+    void                planes(Plane3<T> p[6], const Matrix44<T> &M) const;
 
     //----------------------
     //  Derived Quantities
     //----------------------
 
-    T                           fovx() const;
-    T                           fovy() const;
-    T                           aspect() const;
-    Matrix44<T>                 projectionMatrix() const;
-    bool                        degenerate() const;
+    T                   fovx() const;
+    T                   fovy() const;
+    T                   aspect() const;
+    Matrix44<T>         projectionMatrix() const;
+    bool                degenerate() const;
 
     //-----------------------------------------------------------------------
     //  Takes a rectangle in the screen space (i.e., -1 <= left <= right <= 1 
@@ -147,36 +149,36 @@ class Frustum
     //  space.  
     //-----------------------------------------------------------------------
 
-    Frustum<T>		window(T left, T right, T top, T bottom) const;
+    Frustum<T>          window(T left, T right, T top, T bottom) const;
 
     //----------------------------------------------------------
     // Projection is in screen space / Conversion from Z-Buffer
     //----------------------------------------------------------
 
-    Line3<T>		projectScreenToRay( const Vec2<T> & ) const;
-    Vec2<T>		projectPointToScreen( const Vec3<T> & ) const;
+    Line3<T>            projectScreenToRay( const Vec2<T> & ) const;
+    Vec2<T>             projectPointToScreen( const Vec3<T> & ) const;
 
-    T			ZToDepth(long zval, long min, long max) const;
-    T			normalizedZToDepth(T zval) const;
-    long		DepthToZ(T depth, long zmin, long zmax) const;
+    T                   ZToDepth(long zval, long min, long max) const;
+    T                   normalizedZToDepth(T zval) const;
+    long                DepthToZ(T depth, long zmin, long zmax) const;
 
-    T			worldRadius(const Vec3<T> &p, T radius) const;
-    T			screenRadius(const Vec3<T> &p, T radius) const;
+    T                   worldRadius(const Vec3<T> &p, T radius) const;
+    T                   screenRadius(const Vec3<T> &p, T radius) const;
 
 
   protected:
 
-    Vec2<T>		screenToLocal( const Vec2<T> & ) const;
-    Vec2<T>		localToScreen( const Vec2<T> & ) const;
+    Vec2<T>             screenToLocal( const Vec2<T> & ) const;
+    Vec2<T>             localToScreen( const Vec2<T> & ) const;
 
   protected:
-    T			_nearPlane;
-    T			_farPlane;
-    T			_left;
-    T			_right;
-    T			_top;
-    T			_bottom;
-    bool		_orthographic;
+    T                   _nearPlane;
+    T                   _farPlane;
+    T                   _left;
+    T                   _right;
+    T                   _top;
+    T                   _bottom;
+    bool                _orthographic;
 };
 
 
@@ -184,12 +186,12 @@ template<class T>
 inline Frustum<T>::Frustum()
 {
     set(T (0.1),
-	T (1000.0),
-	T (-1.0),
-	T (1.0),
-	T (1.0),
-	T (-1.0),
-	false);
+        T (1000.0),
+        T (-1.0),
+        T (1.0),
+        T (1.0),
+        T (-1.0),
+        false);
 }
 
 template<class T>
@@ -255,11 +257,11 @@ template<class T>
 void Frustum<T>::set(T n, T f, T l, T r, T t, T b, bool o)
 {
     _nearPlane      = n;
-    _farPlane	    = f;
-    _left	    = l;
-    _right	    = r;
-    _bottom	    = b;
-    _top	    = t;
+    _farPlane       = f;
+    _left           = l;
+    _right          = r;
+    _bottom         = b;
+    _top            = t;
     _orthographic   = o;
 }
 
@@ -268,24 +270,24 @@ void Frustum<T>::modifyNearAndFar(T n, T f)
 {
     if ( _orthographic )
     {
-	_nearPlane = n;
+        _nearPlane = n;
     }
     else
     {
-	Line3<T>  lowerLeft( Vec3<T>(0,0,0), Vec3<T>(_left,_bottom,-_nearPlane) );
-	Line3<T> upperRight( Vec3<T>(0,0,0), Vec3<T>(_right,_top,-_nearPlane) );
-	Plane3<T> nearPlane( Vec3<T>(0,0,-1), n );
-
-	Vec3<T> ll,ur;
-	nearPlane.intersect(lowerLeft,ll);
-	nearPlane.intersect(upperRight,ur);
-
-	_left      = ll.x;
-	_right     = ur.x;
-	_top       = ur.y;
-	_bottom    = ll.y;
-	_nearPlane = n;
-	_farPlane  = f;
+        Line3<T>  lowerLeft( Vec3<T>(0,0,0), Vec3<T>(_left,_bottom,-_nearPlane) );
+        Line3<T> upperRight( Vec3<T>(0,0,0), Vec3<T>(_right,_top,-_nearPlane) );
+        Plane3<T> nearPlane( Vec3<T>(0,0,-1), n );
+
+        Vec3<T> ll,ur;
+        nearPlane.intersect(lowerLeft,ll);
+        nearPlane.intersect(upperRight,ur);
+
+        _left      = ll.x;
+        _right     = ur.x;
+        _top       = ur.y;
+        _bottom    = ll.y;
+        _nearPlane = n;
+        _farPlane  = f;
     }
 
     _farPlane = f;
@@ -301,27 +303,27 @@ template<class T>
 void Frustum<T>::set(T nearPlane, T farPlane, T fovx, T fovy, T aspect)
 {
     if (fovx != 0 && fovy != 0)
-	throw Iex::ArgExc ("fovx and fovy cannot both be non-zero.");
+        throw IEX_NAMESPACE::ArgExc ("fovx and fovy cannot both be non-zero.");
 
     const T two = static_cast<T>(2);
 
     if (fovx != 0)
     {
-	_right	    = nearPlane * Math<T>::tan(fovx / two);
-	_left	    = -_right;
-	_top	    = ((_right - _left) / aspect) / two;
-	_bottom	    = -_top;
+        _right    = nearPlane * Math<T>::tan(fovx / two);
+        _left     = -_right;
+        _top      = ((_right - _left) / aspect) / two;
+        _bottom   = -_top;
     }
     else
     {
-	_top	    = nearPlane * Math<T>::tan(fovy / two);
-	_bottom	    = -_top;
-	_right	    = (_top - _bottom) * aspect / two;
-	_left	    = -_right;
+        _top      = nearPlane * Math<T>::tan(fovy / two);
+        _bottom   = -_top;
+        _right    = (_top - _bottom) * aspect / two;
+        _left     = -_right;
     }
-    _nearPlane	    = nearPlane;
-    _farPlane	    = farPlane;
-    _orthographic   = false;
+    _nearPlane    = nearPlane;
+    _farPlane     = farPlane;
+    _orthographic = false;
 }
 
 template<class T>
@@ -343,10 +345,10 @@ T Frustum<T>::aspect() const
     T topMinusBottom = _top-_bottom;
 
     if (abs(topMinusBottom) < 1 &&
-	abs(rightMinusLeft) > limits<T>::max() * abs(topMinusBottom))
+        abs(rightMinusLeft) > limits<T>::max() * abs(topMinusBottom))
     {
-	throw Iex::DivzeroExc ("Bad viewing frustum: "
-			       "aspect ratio cannot be computed.");
+        throw IEX_NAMESPACE::DivzeroExc ("Bad viewing frustum: "
+                               "aspect ratio cannot be computed.");
     }
 
     return rightMinusLeft / topMinusBottom;
@@ -365,76 +367,76 @@ Matrix44<T> Frustum<T>::projectionMatrix() const
     T farMinusNear   = _farPlane-_nearPlane;
 
     if ((abs(rightMinusLeft) < 1 &&
-	 abs(rightPlusLeft) > limits<T>::max() * abs(rightMinusLeft)) ||
-	(abs(topMinusBottom) < 1 &&
-	 abs(topPlusBottom) > limits<T>::max() * abs(topMinusBottom)) ||
-	(abs(farMinusNear) < 1 &&
-	 abs(farPlusNear) > limits<T>::max() * abs(farMinusNear)))
+         abs(rightPlusLeft) > limits<T>::max() * abs(rightMinusLeft)) ||
+        (abs(topMinusBottom) < 1 &&
+         abs(topPlusBottom) > limits<T>::max() * abs(topMinusBottom)) ||
+        (abs(farMinusNear) < 1 &&
+         abs(farPlusNear) > limits<T>::max() * abs(farMinusNear)))
     {
-	throw Iex::DivzeroExc ("Bad viewing frustum: "
-			       "projection matrix cannot be computed.");
+        throw IEX_NAMESPACE::DivzeroExc ("Bad viewing frustum: "
+                                                 "projection matrix cannot be computed.");
     }
 
     if ( _orthographic )
     {
-	T tx = -rightPlusLeft / rightMinusLeft;
-	T ty = -topPlusBottom / topMinusBottom;
-	T tz = -farPlusNear   / farMinusNear;
-
-	if ((abs(rightMinusLeft) < 1 &&
-	     2 > limits<T>::max() * abs(rightMinusLeft)) ||
-	    (abs(topMinusBottom) < 1 &&
-	     2 > limits<T>::max() * abs(topMinusBottom)) ||
-	    (abs(farMinusNear) < 1 &&
-	     2 > limits<T>::max() * abs(farMinusNear)))
-	{
-	    throw Iex::DivzeroExc ("Bad viewing frustum: "
-				   "projection matrix cannot be computed.");
-	}
-
-	T A  =  2 / rightMinusLeft;
-	T B  =  2 / topMinusBottom;
-	T C  = -2 / farMinusNear;
-
-	return Matrix44<T>( A,  0,  0,  0,
-			    0,  B,  0,  0,
-			    0,  0,  C,  0,
-			    tx, ty, tz, 1.f );
+        T tx = -rightPlusLeft / rightMinusLeft;
+        T ty = -topPlusBottom / topMinusBottom;
+        T tz = -farPlusNear   / farMinusNear;
+
+        if ((abs(rightMinusLeft) < 1 &&
+             2 > limits<T>::max() * abs(rightMinusLeft)) ||
+            (abs(topMinusBottom) < 1 &&
+             2 > limits<T>::max() * abs(topMinusBottom)) ||
+            (abs(farMinusNear) < 1 &&
+             2 > limits<T>::max() * abs(farMinusNear)))
+        {
+            throw IEX_NAMESPACE::DivzeroExc ("Bad viewing frustum: "
+                                                         "projection matrix cannot be computed.");
+        }
+
+        T A  =  2 / rightMinusLeft;
+        T B  =  2 / topMinusBottom;
+        T C  = -2 / farMinusNear;
+
+        return Matrix44<T>( A,  0,  0,  0,
+                            0,  B,  0,  0,
+                            0,  0,  C,  0,
+                            tx, ty, tz, 1.f );
     }
     else
     {
-	T A =  rightPlusLeft / rightMinusLeft;
-	T B =  topPlusBottom / topMinusBottom;
-	T C = -farPlusNear   / farMinusNear;
-
-	T farTimesNear = -2 * _farPlane * _nearPlane;
-	if (abs(farMinusNear) < 1 &&
-	    abs(farTimesNear) > limits<T>::max() * abs(farMinusNear))
-	{
-	    throw Iex::DivzeroExc ("Bad viewing frustum: "
-				   "projection matrix cannot be computed.");
-	}
-
-	T D = farTimesNear / farMinusNear;
-
-	T twoTimesNear = 2 * _nearPlane;
-
-	if ((abs(rightMinusLeft) < 1 &&
-	     abs(twoTimesNear) > limits<T>::max() * abs(rightMinusLeft)) ||
-	    (abs(topMinusBottom) < 1 &&
-	     abs(twoTimesNear) > limits<T>::max() * abs(topMinusBottom)))
-	{
-	    throw Iex::DivzeroExc ("Bad viewing frustum: "
-				   "projection matrix cannot be computed.");
-	}
-
-	T E = twoTimesNear / rightMinusLeft;
-	T F = twoTimesNear / topMinusBottom;
-
-	return Matrix44<T>( E,  0,  0,  0,
-			    0,  F,  0,  0,
-			    A,  B,  C, -1,
-			    0,  0,  D,  0 );
+        T A =  rightPlusLeft / rightMinusLeft;
+        T B =  topPlusBottom / topMinusBottom;
+        T C = -farPlusNear   / farMinusNear;
+
+        T farTimesNear = -2 * _farPlane * _nearPlane;
+        if (abs(farMinusNear) < 1 &&
+            abs(farTimesNear) > limits<T>::max() * abs(farMinusNear))
+        {
+            throw IEX_NAMESPACE::DivzeroExc ("Bad viewing frustum: "
+                                                         "projection matrix cannot be computed.");
+        }
+
+        T D = farTimesNear / farMinusNear;
+
+        T twoTimesNear = 2 * _nearPlane;
+
+        if ((abs(rightMinusLeft) < 1 &&
+             abs(twoTimesNear) > limits<T>::max() * abs(rightMinusLeft)) ||
+            (abs(topMinusBottom) < 1 &&
+             abs(twoTimesNear) > limits<T>::max() * abs(topMinusBottom)))
+        {
+            throw IEX_NAMESPACE::DivzeroExc ("Bad viewing frustum: "
+                                                         "projection matrix cannot be computed.");
+        }
+
+        T E = twoTimesNear / rightMinusLeft;
+        T F = twoTimesNear / topMinusBottom;
+
+        return Matrix44<T>( E,  0,  0,  0,
+                            0,  F,  0,  0,
+                            A,  B,  C, -1,
+                            0,  0,  D,  0 );
     }
 }
 
@@ -462,7 +464,7 @@ template<class T>
 Vec2<T> Frustum<T>::screenToLocal(const Vec2<T> &s) const
 {
     return Vec2<T>( _left + (_right-_left) * (1.f+s.x) / 2.f,
-		    _bottom + (_top-_bottom) * (1.f+s.y) / 2.f );
+                    _bottom + (_top-_bottom) * (1.f+s.y) / 2.f );
 }
 
 template<class T>
@@ -474,17 +476,17 @@ Vec2<T> Frustum<T>::localToScreen(const Vec2<T> &p) const
     T bottomMinusTop = _bottom-_top;
 
     if ((abs(leftMinusRight) < T (1) &&
-	 abs(leftPlusRight) > limits<T>::max() * abs(leftMinusRight)) ||
-	(abs(bottomMinusTop) < T (1) &&
-	 abs(bottomPlusTop) > limits<T>::max() * abs(bottomMinusTop)))
+         abs(leftPlusRight) > limits<T>::max() * abs(leftMinusRight)) ||
+        (abs(bottomMinusTop) < T (1) &&
+         abs(bottomPlusTop) > limits<T>::max() * abs(bottomMinusTop)))
     {
-	throw Iex::DivzeroExc
-	    ("Bad viewing frustum: "
-	     "local-to-screen transformation cannot be computed");
+        throw IEX_NAMESPACE::DivzeroExc
+            ("Bad viewing frustum: "
+             "local-to-screen transformation cannot be computed");
     }
 
     return Vec2<T>( leftPlusRight / leftMinusRight,
-		    bottomPlusTop / bottomMinusTop );
+                    bottomPlusTop / bottomMinusTop );
 }
 
 template<class T>
@@ -492,20 +494,20 @@ Line3<T> Frustum<T>::projectScreenToRay(const Vec2<T> &p) const
 {
     Vec2<T> point = screenToLocal(p);
     if (orthographic())
-	return Line3<T>( Vec3<T>(point.x,point.y, 0.0),
-			 Vec3<T>(point.x,point.y,-_nearPlane));
+        return Line3<T>( Vec3<T>(point.x,point.y, 0.0),
+                         Vec3<T>(point.x,point.y,-1.0));
     else
-	return Line3<T>( Vec3<T>(0, 0, 0), Vec3<T>(point.x,point.y,-_nearPlane));
+        return Line3<T>( Vec3<T>(0, 0, 0), Vec3<T>(point.x,point.y,-_nearPlane));
 }
 
 template<class T>
 Vec2<T> Frustum<T>::projectPointToScreen(const Vec3<T> &point) const
 {
     if (orthographic() || point.z == T (0))
-	return localToScreen( Vec2<T>( point.x, point.y ) );
+        return localToScreen( Vec2<T>( point.x, point.y ) );
     else
-	return localToScreen( Vec2<T>( point.x * _nearPlane / -point.z, 
-				       point.y * _nearPlane / -point.z ) );
+        return localToScreen( Vec2<T>( point.x * _nearPlane / -point.z,
+                                       point.y * _nearPlane / -point.z ) );
 }
 
 template<class T>
@@ -515,8 +517,8 @@ T Frustum<T>::ZToDepth(long zval,long zmin,long zmax) const
 
     if (zdiff == 0)
     {
-	throw Iex::DivzeroExc
-	    ("Bad call to Frustum::ZToDepth: zmax == zmin");
+        throw IEX_NAMESPACE::DivzeroExc
+            ("Bad call to Frustum::ZToDepth: zmax == zmin");
     }
 
     if ( zval > zmax+1 ) zval -= zdiff;
@@ -536,19 +538,19 @@ T Frustum<T>::normalizedZToDepth(T zval) const
     }
     else 
     {
-	T farTimesNear = 2 * _farPlane * _nearPlane;
-	T farMinusNear = Zp * (_farPlane - _nearPlane) - _farPlane - _nearPlane;
-
-	if (abs(farMinusNear) < 1 &&
-	    abs(farTimesNear) > limits<T>::max() * abs(farMinusNear))
-	{
-	    throw Iex::DivzeroExc
-		("Frustum::normalizedZToDepth cannot be computed.  The "
-		 "near and far clipping planes of the viewing frustum "
-		 "may be too close to each other");
-	}
-
-	return farTimesNear / farMinusNear;
+        T farTimesNear = 2 * _farPlane * _nearPlane;
+        T farMinusNear = Zp * (_farPlane - _nearPlane) - _farPlane - _nearPlane;
+
+        if (abs(farMinusNear) < 1 &&
+            abs(farTimesNear) > limits<T>::max() * abs(farMinusNear))
+        {
+            throw IEX_NAMESPACE::DivzeroExc
+                ("Frustum::normalizedZToDepth cannot be computed.  The "
+                 "near and far clipping planes of the viewing frustum "
+                 "may be too close to each other");
+        }
+
+        return farTimesNear / farMinusNear;
     }
 }
 
@@ -560,43 +562,43 @@ long Frustum<T>::DepthToZ(T depth,long zmin,long zmax) const
 
     if ( _orthographic )
     {
-	T farPlusNear = 2*depth + _farPlane + _nearPlane;
-
-	if (abs(farMinusNear) < 1 &&
-	    abs(farPlusNear) > limits<T>::max() * abs(farMinusNear))
-	{
-	    throw Iex::DivzeroExc
-		("Bad viewing frustum: near and far clipping planes "
-		 "are too close to each other");
-	}
-
-	T Zp = -farPlusNear/farMinusNear;
-	return long(0.5*(Zp+1)*zdiff) + zmin;
+        T farPlusNear = 2*depth + _farPlane + _nearPlane;
+
+        if (abs(farMinusNear) < 1 &&
+            abs(farPlusNear) > limits<T>::max() * abs(farMinusNear))
+        {
+            throw IEX_NAMESPACE::DivzeroExc
+                ("Bad viewing frustum: near and far clipping planes "
+                 "are too close to each other");
+        }
+
+        T Zp = -farPlusNear/farMinusNear;
+        return long(0.5*(Zp+1)*zdiff) + zmin;
     }
     else 
     { 
-	// Perspective
-
-	T farTimesNear = 2*_farPlane*_nearPlane;
-	if (abs(depth) < 1 &&
-	    abs(farTimesNear) > limits<T>::max() * abs(depth))
-	{
-	    throw Iex::DivzeroExc
-		("Bad call to DepthToZ function: value of `depth' "
-		 "is too small");
-	}
-
-	T farPlusNear = farTimesNear/depth + _farPlane + _nearPlane;
-	if (abs(farMinusNear) < 1 &&
-	    abs(farPlusNear) > limits<T>::max() * abs(farMinusNear))
-	{
-	    throw Iex::DivzeroExc
-		("Bad viewing frustum: near and far clipping planes "
-		 "are too close to each other");
-	}
-
-	T Zp = farPlusNear/farMinusNear;
-	return long(0.5*(Zp+1)*zdiff) + zmin;
+        // Perspective
+
+        T farTimesNear = 2*_farPlane*_nearPlane;
+        if (abs(depth) < 1 &&
+            abs(farTimesNear) > limits<T>::max() * abs(depth))
+        {
+            throw IEX_NAMESPACE::DivzeroExc
+                ("Bad call to DepthToZ function: value of `depth' "
+                 "is too small");
+        }
+
+        T farPlusNear = farTimesNear/depth + _farPlane + _nearPlane;
+        if (abs(farMinusNear) < 1 &&
+            abs(farPlusNear) > limits<T>::max() * abs(farMinusNear))
+        {
+            throw IEX_NAMESPACE::DivzeroExc
+                ("Bad viewing frustum: near and far clipping planes "
+                 "are too close to each other");
+        }
+
+        T Zp = farPlusNear/farMinusNear;
+        return long(0.5*(Zp+1)*zdiff) + zmin;
     }
 }
 
@@ -615,13 +617,13 @@ T Frustum<T>::screenRadius(const Vec3<T> &p, T radius) const
 
     if (abs(p.z) > 1 || abs(-_nearPlane) < limits<T>::max() * abs(p.z))
     {
-	return radius * (-_nearPlane / p.z);
+        return radius * (-_nearPlane / p.z);
     }
     else
     {
-	throw Iex::DivzeroExc
-	    ("Bad call to Frustum::screenRadius: the magnitude of `p' "
-	     "is too small");
+        throw IEX_NAMESPACE::DivzeroExc
+            ("Bad call to Frustum::screenRadius: the magnitude of `p' "
+             "is too small");
     }
 
     return radius * (-_nearPlane / p.z);
@@ -632,21 +634,21 @@ T Frustum<T>::worldRadius(const Vec3<T> &p, T radius) const
 {
     if (abs(-_nearPlane) > 1 || abs(p.z) < limits<T>::max() * abs(-_nearPlane))
     {
-	return radius * (p.z / -_nearPlane);
+        return radius * (p.z / -_nearPlane);
     }
     else
     {
-	throw Iex::DivzeroExc
-	    ("Bad viewing frustum: the near clipping plane is too "
-	     "close to zero");
+        throw IEX_NAMESPACE::DivzeroExc
+            ("Bad viewing frustum: the near clipping plane is too "
+             "close to zero");
     }
 }
 
 template<class T>
-void Frustum<T>::planes(Plane3<T> p[6])
+void Frustum<T>::planes(Plane3<T> p[6]) const
 {
     //
-    //	Plane order: Top, Right, Bottom, Left, Near, Far.
+    //        Plane order: Top, Right, Bottom, Left, Near, Far.
     //  Normals point outwards.
     //
 
@@ -676,10 +678,10 @@ void Frustum<T>::planes(Plane3<T> p[6])
 
 
 template<class T>
-void Frustum<T>::planes(Plane3<T> p[6], const Matrix44<T> &M)
+void Frustum<T>::planes(Plane3<T> p[6], const Matrix44<T> &M) const
 {
     //
-    //	Plane order: Top, Right, Bottom, Left, Near, Far.
+    //  Plane order: Top, Right, Bottom, Left, Near, Far.
     //  Normals point outwards.
     //
 
@@ -720,11 +722,11 @@ void Frustum<T>::planes(Plane3<T> p[6], const Matrix44<T> &M)
     }
 }
 
-typedef Frustum<float>	Frustumf;
+typedef Frustum<float>  Frustumf;
 typedef Frustum<double> Frustumd;
 
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
 
 #if defined _WIN32 || defined _WIN64
@@ -736,4 +738,4 @@ typedef Frustum<double> Frustumd;
     #endif
 #endif
 
-#endif
+#endif // INCLUDED_IMATHFRUSTUM_H
diff --git a/Source/OpenEXR/Imath/ImathFrustumTest.h b/Source/OpenEXR/Imath/ImathFrustumTest.h
index a726efc..d9c10cc 100644
--- a/Source/OpenEXR/Imath/ImathFrustumTest.h
+++ b/Source/OpenEXR/Imath/ImathFrustumTest.h
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2011-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -38,10 +38,10 @@
 
 //-------------------------------------------------------------------------
 //
-//      This file contains algorithms applied to or in conjunction with
-//	Frustum visibility testing (Imath::Frustum).
+//  This file contains algorithms applied to or in conjunction with
+//  Frustum visibility testing (Imath::Frustum).
 //
-//	Methods for frustum-based rejection of primitives are contained here.
+//  Methods for frustum-based rejection of primitives are contained here.
 //
 //-------------------------------------------------------------------------
 
@@ -50,8 +50,9 @@
 #include "ImathSphere.h"
 #include "ImathMatrix.h"
 #include "ImathVec.h"
+#include "ImathNamespace.h"
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 /////////////////////////////////////////////////////////////////
 // FrustumTest
@@ -73,7 +74,7 @@ namespace Imath {
 //
 // Given that you already have:
 //    Imath::Frustum   myFrustum
-//    IMath::Matrix44  myCameraWorldMatrix
+//    Imath::Matrix44  myCameraWorldMatrix
 //
 // First, make a frustum test object:
 //    FrustumTest myFrustumTest(myFrustum, myCameraWorldMatrix)
@@ -133,7 +134,7 @@ public:
         cameraMat.makeIdentity();
         setFrustum(frust, cameraMat);
     }
-    FrustumTest(Frustum<T> &frustum, const Matrix44<T> &cameraMat)
+    FrustumTest(const Frustum<T> &frustum, const Matrix44<T> &cameraMat)
     {
         setFrustum(frustum, cameraMat);
     }
@@ -142,7 +143,7 @@ public:
     // setFrustum()
     // This updates the frustum test with a new frustum and matrix.
     // This should usually be called just once per frame.
-    void setFrustum(Frustum<T> &frustum, const Matrix44<T> &cameraMat);
+    void setFrustum(const Frustum<T> &frustum, const Matrix44<T> &cameraMat);
 
     ////////////////////////////////////////////////////////////////////
     // isVisible()
@@ -160,8 +161,8 @@ public:
     // These next items are kept primarily for debugging tools.
     // It's useful for drawing the culling environment, and also
     // for getting an "outside view" of the culling frustum.
-    Imath::Matrix44<T> cameraMat() const {return cameraMatrix;}
-    Imath::Frustum<T> currentFrustum() const {return currFrustum;}
+    IMATH_INTERNAL_NAMESPACE::Matrix44<T> cameraMat() const {return cameraMatrix;}
+    IMATH_INTERNAL_NAMESPACE::Frustum<T> currentFrustum() const {return currFrustum;}
 
 protected:
     // To understand why the planes are stored this way, see
@@ -188,7 +189,7 @@ protected:
 // This should usually only be called once per frame, or however
 // often the camera moves.
 template<class T>
-void FrustumTest<T>::setFrustum(Frustum<T> &frustum,
+void FrustumTest<T>::setFrustum(const Frustum<T> &frustum,
                                 const Matrix44<T> &cameraMat)
 {
     Plane3<T> frustumPlanes[6];
@@ -210,15 +211,15 @@ void FrustumTest<T>::setFrustum(Frustum<T> &frustum,
                                     frustumPlanes[index + 1].normal.z,
                                     frustumPlanes[index + 2].normal.z);
 
-        planeNormAbsX[i]  = Vec3<T>(Imath::abs(planeNormX[i].x),
-                                    Imath::abs(planeNormX[i].y), 
-                                    Imath::abs(planeNormX[i].z));
-        planeNormAbsY[i]  = Vec3<T>(Imath::abs(planeNormY[i].x), 
-                                    Imath::abs(planeNormY[i].y),
-                                    Imath::abs(planeNormY[i].z));
-        planeNormAbsZ[i]  = Vec3<T>(Imath::abs(planeNormZ[i].x), 
-                                    Imath::abs(planeNormZ[i].y),
-                                    Imath::abs(planeNormZ[i].z));
+        planeNormAbsX[i]  = Vec3<T>(IMATH_INTERNAL_NAMESPACE::abs(planeNormX[i].x),
+                                    IMATH_INTERNAL_NAMESPACE::abs(planeNormX[i].y), 
+                                    IMATH_INTERNAL_NAMESPACE::abs(planeNormX[i].z));
+        planeNormAbsY[i]  = Vec3<T>(IMATH_INTERNAL_NAMESPACE::abs(planeNormY[i].x), 
+                                    IMATH_INTERNAL_NAMESPACE::abs(planeNormY[i].y),
+                                    IMATH_INTERNAL_NAMESPACE::abs(planeNormY[i].z));
+        planeNormAbsZ[i]  = Vec3<T>(IMATH_INTERNAL_NAMESPACE::abs(planeNormZ[i].x), 
+                                    IMATH_INTERNAL_NAMESPACE::abs(planeNormZ[i].y),
+                                    IMATH_INTERNAL_NAMESPACE::abs(planeNormZ[i].z));
 
         planeOffsetVec[i] = Vec3<T>(frustumPlanes[index + 0].distance,
                                     frustumPlanes[index + 1].distance,
@@ -306,6 +307,9 @@ bool FrustumTest<T>::completelyContains(const Sphere3<T> &sphere) const
 template<typename T>
 bool FrustumTest<T>::isVisible(const Box<Vec3<T> > &box) const
 {
+    if (box.isEmpty())
+        return false;
+    
     Vec3<T> center = (box.min + box.max) / 2;
     Vec3<T> extent = (box.max - center);
 
@@ -344,6 +348,9 @@ bool FrustumTest<T>::isVisible(const Box<Vec3<T> > &box) const
 template<typename T>
 bool FrustumTest<T>::completelyContains(const Box<Vec3<T> > &box) const
 {
+    if (box.isEmpty())
+        return false;
+    
     Vec3<T> center = (box.min + box.max) / 2;
     Vec3<T> extent = (box.max - center);
 
@@ -405,6 +412,6 @@ bool FrustumTest<T>::isVisible(const Vec3<T> &vec) const
 typedef FrustumTest<float>	FrustumTestf;
 typedef FrustumTest<double> FrustumTestd;
 
-} //namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_IMATHFRUSTUMTEST_H
diff --git a/Source/OpenEXR/Imath/ImathFun.cpp b/Source/OpenEXR/Imath/ImathFun.cpp
index defab93..65cf620 100644
--- a/Source/OpenEXR/Imath/ImathFun.cpp
+++ b/Source/OpenEXR/Imath/ImathFun.cpp
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -35,7 +35,7 @@
 
 #include "ImathFun.h"
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 float
@@ -124,7 +124,7 @@ succd (double d)
 
         u.i = 0x0000000000000001LL;
     }
-    else if (u.i > 0)
+    else if (u.d > 0)
     {
         // Positive double, normalized or denormalized.
         // Incrementing the largest positive double
@@ -159,7 +159,7 @@ predd (double d)
 
         u.i = 0x8000000000000001LL;
     }
-    else if (u.i > 0)
+    else if (u.d > 0)
     {
         // Positive double, normalized or denormalized.
 
@@ -178,4 +178,4 @@ predd (double d)
 }
 
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/Imath/ImathFun.h b/Source/OpenEXR/Imath/ImathFun.h
index 0baf4ff..068c682 100644
--- a/Source/OpenEXR/Imath/ImathFun.h
+++ b/Source/OpenEXR/Imath/ImathFun.h
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -43,10 +43,12 @@
 //
 //-----------------------------------------------------------------------------
 
+#include "ImathExport.h"
 #include "ImathLimits.h"
 #include "ImathInt64.h"
+#include "ImathNamespace.h"
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 template <class T>
 inline T
@@ -116,7 +118,7 @@ template <class T>
 inline int
 cmp (T a, T b)
 {
-    return Imath::sign (a - b);
+    return IMATH_INTERNAL_NAMESPACE::sign (a - b);
 }
 
 
@@ -124,7 +126,7 @@ template <class T>
 inline int
 cmpt (T a, T b, T t)
 {
-    return (Imath::abs (a - b) <= t)? 0 : cmp (a, b);
+    return (IMATH_INTERNAL_NAMESPACE::abs (a - b) <= t)? 0 : cmp (a, b);
 }
 
 
@@ -132,7 +134,7 @@ template <class T>
 inline bool
 iszero (T a, T t)
 {
-    return (Imath::abs (a) <= t) ? 1 : 0;
+    return (IMATH_INTERNAL_NAMESPACE::abs (a) <= t) ? 1 : 0;
 }
 
 
@@ -140,7 +142,7 @@ template <class T1, class T2, class T3>
 inline bool
 equal (T1 a, T2 b, T3 t)
 {
-    return Imath::abs (a - b) <= t;
+    return IMATH_INTERNAL_NAMESPACE::abs (a - b) <= t;
 }
 
 template <class T>
@@ -233,11 +235,11 @@ modp (int x, int y)
 // 
 //----------------------------------------------------------
 
-float succf (float f);
-float predf (float f);
+IMATH_EXPORT float succf (float f);
+IMATH_EXPORT float predf (float f);
 
-double succd (double d);
-double predd (double d);
+IMATH_EXPORT double succd (double d);
+IMATH_EXPORT double predd (double d);
 
 //
 // Return true if the number is not a NaN or Infinity.
@@ -262,6 +264,6 @@ finited (double d)
 }
 
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_IMATHFUN_H
diff --git a/Source/OpenEXR/Imath/ImathGL.h b/Source/OpenEXR/Imath/ImathGL.h
index 36be0fd..e3b9405 100644
--- a/Source/OpenEXR/Imath/ImathGL.h
+++ b/Source/OpenEXR/Imath/ImathGL.h
@@ -42,14 +42,15 @@
 #include "ImathMatrix.h"
 #include "IexMathExc.h"
 #include "ImathFun.h"
+#include "ImathNamespace.h"
 
-inline void glVertex    ( const Imath::V3f &v ) { glVertex3f(v.x,v.y,v.z);   }
-inline void glVertex    ( const Imath::V2f &v ) { glVertex2f(v.x,v.y);       }
-inline void glNormal    ( const Imath::V3f &n ) { glNormal3f(n.x,n.y,n.z);   }
-inline void glColor     ( const Imath::V3f &c ) { glColor3f(c.x,c.y,c.z);    }
-inline void glTranslate ( const Imath::V3f &t ) { glTranslatef(t.x,t.y,t.z); }
+inline void glVertex    ( const IMATH_INTERNAL_NAMESPACE::V3f &v ) { glVertex3f(v.x,v.y,v.z);   }
+inline void glVertex    ( const IMATH_INTERNAL_NAMESPACE::V2f &v ) { glVertex2f(v.x,v.y);       }
+inline void glNormal    ( const IMATH_INTERNAL_NAMESPACE::V3f &n ) { glNormal3f(n.x,n.y,n.z);   }
+inline void glColor     ( const IMATH_INTERNAL_NAMESPACE::V3f &c ) { glColor3f(c.x,c.y,c.z);    }
+inline void glTranslate ( const IMATH_INTERNAL_NAMESPACE::V3f &t ) { glTranslatef(t.x,t.y,t.z); }
 
-inline void glTexCoord( const Imath::V2f &t )
+inline void glTexCoord( const IMATH_INTERNAL_NAMESPACE::V2f &t )
 {
     glTexCoord2f(t.x,t.y);
 }
@@ -70,13 +71,13 @@ const float GL_FLOAT_MAX = 1.8e+19; // sqrt (FLT_MAX)
 inline bool
 badFloat (float f)
 {
-    return !Imath::finitef (f) || f < - GL_FLOAT_MAX || f > GL_FLOAT_MAX;
+    return !IMATH_INTERNAL_NAMESPACE::finitef (f) || f < - GL_FLOAT_MAX || f > GL_FLOAT_MAX;
 }
 
 } // namespace
 	
 inline void
-throwBadMatrix (const Imath::M44f& m)
+throwBadMatrix (const IMATH_INTERNAL_NAMESPACE::M44f& m)
 {
     if (badFloat (m[0][0]) ||
 	badFloat (m[0][1]) ||
@@ -94,39 +95,42 @@ throwBadMatrix (const Imath::M44f& m)
 	badFloat (m[3][1]) ||
 	badFloat (m[3][2]) ||
 	badFloat (m[3][3]))
-	throw Iex::OverflowExc ("GL matrix overflow");
+	throw IEX_NAMESPACE::OverflowExc ("GL matrix overflow");
 }
 
 inline void 
-glMultMatrix( const Imath::M44f& m ) 
+glMultMatrix( const IMATH_INTERNAL_NAMESPACE::M44f& m ) 
 { 
     throwBadMatrix (m);
     glMultMatrixf( (GLfloat*)m[0] ); 
 }
 
 inline void 
-glMultMatrix( const Imath::M44f* m ) 
+glMultMatrix( const IMATH_INTERNAL_NAMESPACE::M44f* m ) 
 { 
     throwBadMatrix (*m);
     glMultMatrixf( (GLfloat*)(*m)[0] ); 
 }
 
 inline void 
-glLoadMatrix( const Imath::M44f& m ) 
+glLoadMatrix( const IMATH_INTERNAL_NAMESPACE::M44f& m ) 
 { 
     throwBadMatrix (m);
     glLoadMatrixf( (GLfloat*)m[0] ); 
 }
 
 inline void 
-glLoadMatrix( const Imath::M44f* m ) 
+glLoadMatrix( const IMATH_INTERNAL_NAMESPACE::M44f* m ) 
 { 
     throwBadMatrix (*m);
     glLoadMatrixf( (GLfloat*)(*m)[0] ); 
 }
 
 
-namespace Imath {
+
+
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
+
 
 //
 // Class objects that push/pop the GL state. These objects assist with
@@ -154,6 +158,9 @@ class GLBegin {
     ~GLBegin()				{ glEnd(); }
 };
 
-} // namespace Imath
+
+
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
+
 
 #endif
diff --git a/Source/OpenEXR/Imath/ImathGLU.h b/Source/OpenEXR/Imath/ImathGLU.h
index e43d560..52a43af 100644
--- a/Source/OpenEXR/Imath/ImathGLU.h
+++ b/Source/OpenEXR/Imath/ImathGLU.h
@@ -44,7 +44,7 @@
 
 inline
 void
-gluLookAt(const Imath::V3f &pos, const Imath::V3f &interest, const Imath::V3f &up)
+gluLookAt(const IMATH_INTERNAL_NAMESPACE::V3f &pos, const IMATH_INTERNAL_NAMESPACE::V3f &interest, const IMATH_INTERNAL_NAMESPACE::V3f &up)
 {
     gluLookAt(pos.x,      pos.y,      pos.z,
               interest.x, interest.y, interest.z,
diff --git a/Source/OpenEXR/Imath/ImathHalfLimits.h b/Source/OpenEXR/Imath/ImathHalfLimits.h
index 2170f94..de54bd6 100644
--- a/Source/OpenEXR/Imath/ImathHalfLimits.h
+++ b/Source/OpenEXR/Imath/ImathHalfLimits.h
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -44,9 +44,11 @@
 //--------------------------------------------------
 
 #include "ImathLimits.h"
+#include "ImathNamespace.h"
+
 #include "half.h"
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 template <>
@@ -61,6 +63,6 @@ struct limits <half>
 };
 
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_IMATHHALFLIMITS_H
diff --git a/Source/OpenEXR/Imath/ImathInt64.h b/Source/OpenEXR/Imath/ImathInt64.h
index 71ee4ec..3b867dc 100644
--- a/Source/OpenEXR/Imath/ImathInt64.h
+++ b/Source/OpenEXR/Imath/ImathInt64.h
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2006, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2006-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -42,9 +42,10 @@
 //
 //----------------------------------------------------------------------------
 
+#include "ImathNamespace.h"
 #include <limits.h>
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 #if (defined _WIN32 || defined _WIN64) && _MSC_VER >= 1300
@@ -56,6 +57,6 @@ namespace Imath {
 #endif
 
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_IMATH_INT64_H
diff --git a/Source/OpenEXR/Imath/ImathInterval.h b/Source/OpenEXR/Imath/ImathInterval.h
index 2d9d7d3..0062f4d 100644
--- a/Source/OpenEXR/Imath/ImathInterval.h
+++ b/Source/OpenEXR/Imath/ImathInterval.h
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -50,8 +50,9 @@
 //-------------------------------------------------------------------
 
 #include "ImathVec.h"
+#include "ImathNamespace.h"
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 template <class T>	
@@ -219,6 +220,7 @@ inline bool Interval<T>::hasVolume() const
     return max > min;
 }
 
-} // namespace Imath
 
-#endif
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif // INCLUDED_IMATHINTERVAL_H
diff --git a/Source/OpenEXR/Imath/ImathLimits.h b/Source/OpenEXR/Imath/ImathLimits.h
index 6ba74f6..eb6f999 100644
--- a/Source/OpenEXR/Imath/ImathLimits.h
+++ b/Source/OpenEXR/Imath/ImathLimits.h
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -43,6 +43,7 @@
 //
 //----------------------------------------------------------------
 
+#include "ImathNamespace.h"
 #include <float.h>
 #include <limits.h>
 
@@ -59,7 +60,7 @@
     #endif
 #endif
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 //-----------------------------------------------------------------
@@ -262,6 +263,6 @@ struct limits <long double>
 };
 
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_IMATHLIMITS_H
diff --git a/Source/OpenEXR/Imath/ImathLine.h b/Source/OpenEXR/Imath/ImathLine.h
index 601fc6f..61e4508 100644
--- a/Source/OpenEXR/Imath/ImathLine.h
+++ b/Source/OpenEXR/Imath/ImathLine.h
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -46,8 +46,9 @@
 #include "ImathVec.h"
 #include "ImathLimits.h"
 #include "ImathMatrix.h"
+#include "ImathNamespace.h"
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 template <class T>
@@ -179,6 +180,6 @@ inline Line3<S> operator * (const Line3<S> &line, const Matrix44<T> &M)
 }
 
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_IMATHLINE_H
diff --git a/Source/OpenEXR/Imath/ImathLineAlgo.h b/Source/OpenEXR/Imath/ImathLineAlgo.h
index 41855c9..b08a1ff 100644
--- a/Source/OpenEXR/Imath/ImathLineAlgo.h
+++ b/Source/OpenEXR/Imath/ImathLineAlgo.h
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -74,8 +74,9 @@
 #include "ImathLine.h"
 #include "ImathVecAlgo.h"
 #include "ImathFun.h"
+#include "ImathNamespace.h"
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 template <class T>
@@ -282,6 +283,6 @@ rotatePoint (const Vec3<T> p, Line3<T> l, T angle)
 }
 
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_IMATHLINEALGO_H
diff --git a/Source/OpenEXR/Imath/ImathMath.h b/Source/OpenEXR/Imath/ImathMath.h
index d5b4616..1961d5a 100644
--- a/Source/OpenEXR/Imath/ImathMath.h
+++ b/Source/OpenEXR/Imath/ImathMath.h
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -82,9 +82,10 @@
 
 #include "ImathPlatform.h"
 #include "ImathLimits.h"
+#include "ImathNamespace.h"
 #include <math.h>
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 template <class T>
@@ -202,7 +203,6 @@ equalWithRelError (T x1, T x2, T e)
 }
 
 
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-} // namespace Imath
-
-#endif
+#endif // INCLUDED_IMATHMATH_H
diff --git a/Source/OpenEXR/Imath/ImathMatrix.h b/Source/OpenEXR/Imath/ImathMatrix.h
index bbf8cd1..3e96c2f 100644
--- a/Source/OpenEXR/Imath/ImathMatrix.h
+++ b/Source/OpenEXR/Imath/ImathMatrix.h
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -48,6 +48,7 @@
 #include "ImathExc.h"
 #include "ImathVec.h"
 #include "ImathShear.h"
+#include "ImathNamespace.h"
 
 #include <cstring>
 #include <iostream>
@@ -60,7 +61,7 @@
 #endif
 
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 enum Uninitialized {UNINITIALIZED};
 
@@ -262,16 +263,16 @@ template <class T> class Matrix33
     //------------------------------------------------------------
 
     const Matrix33 &    invert (bool singExc = false)
-                        throw (Iex::MathExc);
+                        throw (IEX_NAMESPACE::MathExc);
 
     Matrix33<T>         inverse (bool singExc = false) const
-                        throw (Iex::MathExc);
+                        throw (IEX_NAMESPACE::MathExc);
 
     const Matrix33 &    gjInvert (bool singExc = false)
-                        throw (Iex::MathExc);
+                        throw (IEX_NAMESPACE::MathExc);
 
     Matrix33<T>         gjInverse (bool singExc = false) const
-                        throw (Iex::MathExc);
+                        throw (IEX_NAMESPACE::MathExc);
 
 
     //------------------------------------------------
@@ -636,16 +637,16 @@ template <class T> class Matrix44
     //------------------------------------------------------------
 
     const Matrix44 &    invert (bool singExc = false)
-                        throw (Iex::MathExc);
+                        throw (IEX_NAMESPACE::MathExc);
 
     Matrix44<T>         inverse (bool singExc = false) const
-                        throw (Iex::MathExc);
+                        throw (IEX_NAMESPACE::MathExc);
 
     const Matrix44 &    gjInvert (bool singExc = false)
-                        throw (Iex::MathExc);
+                        throw (IEX_NAMESPACE::MathExc);
 
     Matrix44<T>         gjInverse (bool singExc = false) const
-                        throw (Iex::MathExc);
+                        throw (IEX_NAMESPACE::MathExc);
 
 
     //------------------------------------------------
@@ -1118,7 +1119,7 @@ Matrix33<T>::equalWithAbsError (const Matrix33<T> &m, T e) const
 {
     for (int i = 0; i < 3; i++)
         for (int j = 0; j < 3; j++)
-            if (!Imath::equalWithAbsError ((*this)[i][j], m[i][j], e))
+            if (!IMATH_INTERNAL_NAMESPACE::equalWithAbsError ((*this)[i][j], m[i][j], e))
                 return false;
 
     return true;
@@ -1130,7 +1131,7 @@ Matrix33<T>::equalWithRelError (const Matrix33<T> &m, T e) const
 {
     for (int i = 0; i < 3; i++)
         for (int j = 0; j < 3; j++)
-            if (!Imath::equalWithRelError ((*this)[i][j], m[i][j], e))
+            if (!IMATH_INTERNAL_NAMESPACE::equalWithRelError ((*this)[i][j], m[i][j], e))
                 return false;
 
     return true;
@@ -1429,7 +1430,7 @@ Matrix33<T>::transposed () const
 
 template <class T>
 const Matrix33<T> &
-Matrix33<T>::gjInvert (bool singExc) throw (Iex::MathExc)
+Matrix33<T>::gjInvert (bool singExc) throw (IEX_NAMESPACE::MathExc)
 {
     *this = gjInverse (singExc);
     return *this;
@@ -1437,7 +1438,7 @@ Matrix33<T>::gjInvert (bool singExc) throw (Iex::MathExc)
 
 template <class T>
 Matrix33<T>
-Matrix33<T>::gjInverse (bool singExc) const throw (Iex::MathExc)
+Matrix33<T>::gjInverse (bool singExc) const throw (IEX_NAMESPACE::MathExc)
 {
     int i, j, k;
     Matrix33 s;
@@ -1471,7 +1472,7 @@ Matrix33<T>::gjInverse (bool singExc) const throw (Iex::MathExc)
         if (pivotsize == 0)
         {
             if (singExc)
-                throw ::Imath::SingMatrixExc ("Cannot invert singular matrix.");
+                throw ::IMATH_INTERNAL_NAMESPACE::SingMatrixExc ("Cannot invert singular matrix.");
 
             return Matrix33();
         }
@@ -1513,7 +1514,7 @@ Matrix33<T>::gjInverse (bool singExc) const throw (Iex::MathExc)
         if ((f = t[i][i]) == 0)
         {
             if (singExc)
-                throw ::Imath::SingMatrixExc ("Cannot invert singular matrix.");
+                throw ::IMATH_INTERNAL_NAMESPACE::SingMatrixExc ("Cannot invert singular matrix.");
 
             return Matrix33();
         }
@@ -1541,7 +1542,7 @@ Matrix33<T>::gjInverse (bool singExc) const throw (Iex::MathExc)
 
 template <class T>
 const Matrix33<T> &
-Matrix33<T>::invert (bool singExc) throw (Iex::MathExc)
+Matrix33<T>::invert (bool singExc) throw (IEX_NAMESPACE::MathExc)
 {
     *this = inverse (singExc);
     return *this;
@@ -1549,7 +1550,7 @@ Matrix33<T>::invert (bool singExc) throw (Iex::MathExc)
 
 template <class T>
 Matrix33<T>
-Matrix33<T>::inverse (bool singExc) const throw (Iex::MathExc)
+Matrix33<T>::inverse (bool singExc) const throw (IEX_NAMESPACE::MathExc)
 {
     if (x[0][2] != 0 || x[1][2] != 0 || x[2][2] != 1)
     {
@@ -1567,7 +1568,7 @@ Matrix33<T>::inverse (bool singExc) const throw (Iex::MathExc)
 
         T r = x[0][0] * s[0][0] + x[0][1] * s[1][0] + x[0][2] * s[2][0];
 
-        if (Imath::abs (r) >= 1)
+        if (IMATH_INTERNAL_NAMESPACE::abs (r) >= 1)
         {
             for (int i = 0; i < 3; ++i)
             {
@@ -1579,13 +1580,13 @@ Matrix33<T>::inverse (bool singExc) const throw (Iex::MathExc)
         }
         else
         {
-            T mr = Imath::abs (r) / limits<T>::smallest();
+            T mr = IMATH_INTERNAL_NAMESPACE::abs (r) / limits<T>::smallest();
 
             for (int i = 0; i < 3; ++i)
             {
                 for (int j = 0; j < 3; ++j)
                 {
-                    if (mr > Imath::abs (s[i][j]))
+                    if (mr > IMATH_INTERNAL_NAMESPACE::abs (s[i][j]))
                     {
                         s[i][j] /= r;
                     }
@@ -1618,7 +1619,7 @@ Matrix33<T>::inverse (bool singExc) const throw (Iex::MathExc)
 
         T r = x[0][0] * x[1][1] - x[1][0] * x[0][1];
 
-        if (Imath::abs (r) >= 1)
+        if (IMATH_INTERNAL_NAMESPACE::abs (r) >= 1)
         {
             for (int i = 0; i < 2; ++i)
             {
@@ -1630,13 +1631,13 @@ Matrix33<T>::inverse (bool singExc) const throw (Iex::MathExc)
         }
         else
         {
-            T mr = Imath::abs (r) / limits<T>::smallest();
+            T mr = IMATH_INTERNAL_NAMESPACE::abs (r) / limits<T>::smallest();
 
             for (int i = 0; i < 2; ++i)
             {
                 for (int j = 0; j < 2; ++j)
                 {
-                    if (mr > Imath::abs (s[i][j]))
+                    if (mr > IMATH_INTERNAL_NAMESPACE::abs (s[i][j]))
                     {
                         s[i][j] /= r;
                     }
@@ -2242,7 +2243,7 @@ Matrix44<T>::equalWithAbsError (const Matrix44<T> &m, T e) const
 {
     for (int i = 0; i < 4; i++)
         for (int j = 0; j < 4; j++)
-            if (!Imath::equalWithAbsError ((*this)[i][j], m[i][j], e))
+            if (!IMATH_INTERNAL_NAMESPACE::equalWithAbsError ((*this)[i][j], m[i][j], e))
                 return false;
 
     return true;
@@ -2254,7 +2255,7 @@ Matrix44<T>::equalWithRelError (const Matrix44<T> &m, T e) const
 {
     for (int i = 0; i < 4; i++)
         for (int j = 0; j < 4; j++)
-            if (!Imath::equalWithRelError ((*this)[i][j], m[i][j], e))
+            if (!IMATH_INTERNAL_NAMESPACE::equalWithRelError ((*this)[i][j], m[i][j], e))
                 return false;
 
     return true;
@@ -2698,7 +2699,7 @@ Matrix44<T>::transposed () const
 
 template <class T>
 const Matrix44<T> &
-Matrix44<T>::gjInvert (bool singExc) throw (Iex::MathExc)
+Matrix44<T>::gjInvert (bool singExc) throw (IEX_NAMESPACE::MathExc)
 {
     *this = gjInverse (singExc);
     return *this;
@@ -2706,7 +2707,7 @@ Matrix44<T>::gjInvert (bool singExc) throw (Iex::MathExc)
 
 template <class T>
 Matrix44<T>
-Matrix44<T>::gjInverse (bool singExc) const throw (Iex::MathExc)
+Matrix44<T>::gjInverse (bool singExc) const throw (IEX_NAMESPACE::MathExc)
 {
     int i, j, k;
     Matrix44 s;
@@ -2740,7 +2741,7 @@ Matrix44<T>::gjInverse (bool singExc) const throw (Iex::MathExc)
         if (pivotsize == 0)
         {
             if (singExc)
-                throw ::Imath::SingMatrixExc ("Cannot invert singular matrix.");
+                throw ::IMATH_INTERNAL_NAMESPACE::SingMatrixExc ("Cannot invert singular matrix.");
 
             return Matrix44();
         }
@@ -2782,7 +2783,7 @@ Matrix44<T>::gjInverse (bool singExc) const throw (Iex::MathExc)
         if ((f = t[i][i]) == 0)
         {
             if (singExc)
-                throw ::Imath::SingMatrixExc ("Cannot invert singular matrix.");
+                throw ::IMATH_INTERNAL_NAMESPACE::SingMatrixExc ("Cannot invert singular matrix.");
 
             return Matrix44();
         }
@@ -2810,7 +2811,7 @@ Matrix44<T>::gjInverse (bool singExc) const throw (Iex::MathExc)
 
 template <class T>
 const Matrix44<T> &
-Matrix44<T>::invert (bool singExc) throw (Iex::MathExc)
+Matrix44<T>::invert (bool singExc) throw (IEX_NAMESPACE::MathExc)
 {
     *this = inverse (singExc);
     return *this;
@@ -2818,7 +2819,7 @@ Matrix44<T>::invert (bool singExc) throw (Iex::MathExc)
 
 template <class T>
 Matrix44<T>
-Matrix44<T>::inverse (bool singExc) const throw (Iex::MathExc)
+Matrix44<T>::inverse (bool singExc) const throw (IEX_NAMESPACE::MathExc)
 {
     if (x[0][3] != 0 || x[1][3] != 0 || x[2][3] != 0 || x[3][3] != 1)
         return gjInverse(singExc);
@@ -2845,7 +2846,7 @@ Matrix44<T>::inverse (bool singExc) const throw (Iex::MathExc)
 
     T r = x[0][0] * s[0][0] + x[0][1] * s[1][0] + x[0][2] * s[2][0];
 
-    if (Imath::abs (r) >= 1)
+    if (IMATH_INTERNAL_NAMESPACE::abs (r) >= 1)
     {
         for (int i = 0; i < 3; ++i)
         {
@@ -2857,13 +2858,13 @@ Matrix44<T>::inverse (bool singExc) const throw (Iex::MathExc)
     }
     else
     {
-        T mr = Imath::abs (r) / limits<T>::smallest();
+        T mr = IMATH_INTERNAL_NAMESPACE::abs (r) / limits<T>::smallest();
 
         for (int i = 0; i < 3; ++i)
         {
             for (int j = 0; j < 3; ++j)
             {
-                if (mr > Imath::abs (s[i][j]))
+                if (mr > IMATH_INTERNAL_NAMESPACE::abs (s[i][j]))
                 {
                     s[i][j] /= r;
                 }
@@ -3435,8 +3436,6 @@ operator * (const Vec4<S> &v, const Matrix44<T> &m)
     return Vec4<S> (x, y, z, w);
 }
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-
-
-#endif
+#endif // INCLUDED_IMATHMATRIX_H
diff --git a/Source/OpenEXR/Imath/ImathMatrixAlgo.cpp b/Source/OpenEXR/Imath/ImathMatrixAlgo.cpp
index 8896c8d..0cafd5c 100644
--- a/Source/OpenEXR/Imath/ImathMatrixAlgo.cpp
+++ b/Source/OpenEXR/Imath/ImathMatrixAlgo.cpp
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -44,6 +44,7 @@
 
 #include "ImathMatrixAlgo.h"
 #include <cmath>
+#include <algorithm>
 
 #if defined(OPENEXR_DLL)
     #define EXPORT_CONST __declspec(dllexport)
@@ -51,7 +52,7 @@
     #define EXPORT_CONST const
 #endif
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 EXPORT_CONST M33f identity33f ( 1, 0, 0,
 				0, 1, 0,
@@ -165,7 +166,7 @@ procrustesRotationAndTranslation (const Vec3<T>* A, const Vec3<T>* B, const T* w
 
     M33d U, V;
     V3d S;
-    jacobiSVD (C, U, S, V, Imath::limits<double>::epsilon(), true);
+    jacobiSVD (C, U, S, V, IMATH_INTERNAL_NAMESPACE::limits<double>::epsilon(), true);
 
     // We want Q.transposed() here since we are going to be using it in the
     // Imath style (multiplying vectors on the right, v' = v*A^T):
@@ -248,10 +249,10 @@ procrustesRotationAndTranslation (const Vec3<T>* A, const Vec3<T>* B, const size
 } // procrustesRotationAndTranslation
 
 
-template M44d procrustesRotationAndTranslation (const V3d* from, const V3d* to, const size_t numPoints, const bool doScale);
-template M44d procrustesRotationAndTranslation (const V3f* from, const V3f* to, const size_t numPoints, const bool doScale);
-template M44d procrustesRotationAndTranslation (const V3d* from, const V3d* to, const double* weights, const size_t numPoints, const bool doScale);
-template M44d procrustesRotationAndTranslation (const V3f* from, const V3f* to, const float* weights, const size_t numPoints, const bool doScale);
+template IMATH_EXPORT M44d procrustesRotationAndTranslation (const V3d* from, const V3d* to, const size_t numPoints, const bool doScale);
+template IMATH_EXPORT M44d procrustesRotationAndTranslation (const V3f* from, const V3f* to, const size_t numPoints, const bool doScale);
+template IMATH_EXPORT M44d procrustesRotationAndTranslation (const V3d* from, const V3d* to, const double* weights, const size_t numPoints, const bool doScale);
+template IMATH_EXPORT M44d procrustesRotationAndTranslation (const V3f* from, const V3f* to, const float* weights, const size_t numPoints, const bool doScale);
 
 
 namespace
@@ -268,7 +269,7 @@ namespace
 // need to explicitly construct the J matrix.  
 template <typename T, int j, int k>
 void
-jacobiRotateRight (Imath::Matrix33<T>& A,
+jacobiRotateRight (IMATH_INTERNAL_NAMESPACE::Matrix33<T>& A,
                    const T c,
                    const T s)
 {
@@ -283,7 +284,7 @@ jacobiRotateRight (Imath::Matrix33<T>& A,
 
 template <typename T>
 void
-jacobiRotateRight (Imath::Matrix44<T>& A,
+jacobiRotateRight (IMATH_INTERNAL_NAMESPACE::Matrix44<T>& A,
                    const int j,
                    const int k,
                    const T c,
@@ -315,9 +316,9 @@ jacobiRotateRight (Imath::Matrix44<T>& A,
 // and the second diagonalizes the symmetric matrix.  
 template <typename T, int j, int k, int l>
 bool
-twoSidedJacobiRotation (Imath::Matrix33<T>& A,
-                        Imath::Matrix33<T>& U,
-                        Imath::Matrix33<T>& V,
+twoSidedJacobiRotation (IMATH_INTERNAL_NAMESPACE::Matrix33<T>& A,
+                        IMATH_INTERNAL_NAMESPACE::Matrix33<T>& U,
+                        IMATH_INTERNAL_NAMESPACE::Matrix33<T>& V,
                         const T tol)
 {
     // Load everything into local variables to make things easier on the
@@ -454,11 +455,11 @@ twoSidedJacobiRotation (Imath::Matrix33<T>& A,
 
 template <typename T>
 bool
-twoSidedJacobiRotation (Imath::Matrix44<T>& A,
+twoSidedJacobiRotation (IMATH_INTERNAL_NAMESPACE::Matrix44<T>& A,
                         int j,
                         int k,
-                        Imath::Matrix44<T>& U,
-                        Imath::Matrix44<T>& V,
+                        IMATH_INTERNAL_NAMESPACE::Matrix44<T>& U,
+                        IMATH_INTERNAL_NAMESPACE::Matrix44<T>& V,
                         const T tol)
 {
     // Load everything into local variables to make things easier on the
@@ -616,7 +617,7 @@ twoSidedJacobiRotation (Imath::Matrix44<T>& A,
 
 template <typename T>
 void
-swapColumns (Imath::Matrix33<T>& A, int j, int k)
+swapColumns (IMATH_INTERNAL_NAMESPACE::Matrix33<T>& A, int j, int k)
 {
     for (int i = 0; i < 3; ++i)
         std::swap (A[i][j], A[i][k]);
@@ -624,7 +625,7 @@ swapColumns (Imath::Matrix33<T>& A, int j, int k)
 
 template <typename T>
 T
-maxOffDiag (const Imath::Matrix33<T>& A)
+maxOffDiag (const IMATH_INTERNAL_NAMESPACE::Matrix33<T>& A)
 {
     T result = 0;
     result = std::max (result, std::abs (A[0][1]));
@@ -638,7 +639,7 @@ maxOffDiag (const Imath::Matrix33<T>& A)
 
 template <typename T>
 T
-maxOffDiag (const Imath::Matrix44<T>& A)
+maxOffDiag (const IMATH_INTERNAL_NAMESPACE::Matrix44<T>& A)
 {
     T result = 0;
     for (int i = 0; i < 4; ++i)
@@ -655,10 +656,10 @@ maxOffDiag (const Imath::Matrix44<T>& A)
 
 template <typename T>
 void
-twoSidedJacobiSVD (Imath::Matrix33<T> A,
-                   Imath::Matrix33<T>& U,
-                   Imath::Vec3<T>& S,
-                   Imath::Matrix33<T>& V,
+twoSidedJacobiSVD (IMATH_INTERNAL_NAMESPACE::Matrix33<T> A,
+                   IMATH_INTERNAL_NAMESPACE::Matrix33<T>& U,
+                   IMATH_INTERNAL_NAMESPACE::Vec3<T>& S,
+                   IMATH_INTERNAL_NAMESPACE::Matrix33<T>& V,
                    const T tol,
                    const bool forcePositiveDeterminant)
 {
@@ -781,10 +782,10 @@ twoSidedJacobiSVD (Imath::Matrix33<T> A,
 
 template <typename T>
 void
-twoSidedJacobiSVD (Imath::Matrix44<T> A,
-                   Imath::Matrix44<T>& U,
-                   Imath::Vec4<T>& S,
-                   Imath::Matrix44<T>& V,
+twoSidedJacobiSVD (IMATH_INTERNAL_NAMESPACE::Matrix44<T> A,
+                   IMATH_INTERNAL_NAMESPACE::Matrix44<T>& U,
+                   IMATH_INTERNAL_NAMESPACE::Vec4<T>& S,
+                   IMATH_INTERNAL_NAMESPACE::Matrix44<T>& V,
                    const T tol,
                    const bool forcePositiveDeterminant)
 {
@@ -836,8 +837,8 @@ twoSidedJacobiSVD (Imath::Matrix44<T> A,
     // Order the singular values from largest to smallest using insertion sort:
     for (int i = 1; i < 4; ++i)
     {
-        const Imath::Vec4<T> uCol (U[0][i], U[1][i], U[2][i], U[3][i]);
-        const Imath::Vec4<T> vCol (V[0][i], V[1][i], V[2][i], V[3][i]);
+        const IMATH_INTERNAL_NAMESPACE::Vec4<T> uCol (U[0][i], U[1][i], U[2][i], U[3][i]);
+        const IMATH_INTERNAL_NAMESPACE::Vec4<T> vCol (V[0][i], V[1][i], V[2][i], V[3][i]);
         const T sVal = S[i];
 
         int j = i - 1;
@@ -895,10 +896,10 @@ twoSidedJacobiSVD (Imath::Matrix44<T> A,
 
 template <typename T>
 void
-jacobiSVD (const Imath::Matrix33<T>& A,
-           Imath::Matrix33<T>& U,
-           Imath::Vec3<T>& S,
-           Imath::Matrix33<T>& V,
+jacobiSVD (const IMATH_INTERNAL_NAMESPACE::Matrix33<T>& A,
+           IMATH_INTERNAL_NAMESPACE::Matrix33<T>& U,
+           IMATH_INTERNAL_NAMESPACE::Vec3<T>& S,
+           IMATH_INTERNAL_NAMESPACE::Matrix33<T>& V,
            const T tol,
            const bool forcePositiveDeterminant)
 {
@@ -907,40 +908,40 @@ jacobiSVD (const Imath::Matrix33<T>& A,
 
 template <typename T>
 void
-jacobiSVD (const Imath::Matrix44<T>& A,
-           Imath::Matrix44<T>& U,
-           Imath::Vec4<T>& S,
-           Imath::Matrix44<T>& V,
+jacobiSVD (const IMATH_INTERNAL_NAMESPACE::Matrix44<T>& A,
+           IMATH_INTERNAL_NAMESPACE::Matrix44<T>& U,
+           IMATH_INTERNAL_NAMESPACE::Vec4<T>& S,
+           IMATH_INTERNAL_NAMESPACE::Matrix44<T>& V,
            const T tol,
            const bool forcePositiveDeterminant)
 {
     twoSidedJacobiSVD (A, U, S, V, tol, forcePositiveDeterminant);
 }
 
-template void jacobiSVD (const Imath::Matrix33<float>& A,
-                         Imath::Matrix33<float>& U,
-                         Imath::Vec3<float>& S,
-                         Imath::Matrix33<float>& V,
-                         const float tol,
-                         const bool forcePositiveDeterminant);
-template void jacobiSVD (const Imath::Matrix33<double>& A,
-                         Imath::Matrix33<double>& U,
-                         Imath::Vec3<double>& S,
-                         Imath::Matrix33<double>& V,
-                         const double tol,
-                         const bool forcePositiveDeterminant);
-template void jacobiSVD (const Imath::Matrix44<float>& A,
-                         Imath::Matrix44<float>& U,
-                         Imath::Vec4<float>& S,
-                         Imath::Matrix44<float>& V,
-                         const float tol,
-                         const bool forcePositiveDeterminant);
-template void jacobiSVD (const Imath::Matrix44<double>& A,
-                         Imath::Matrix44<double>& U,
-                         Imath::Vec4<double>& S,
-                         Imath::Matrix44<double>& V,
-                         const double tol,
-                         const bool forcePositiveDeterminant);
+template IMATH_EXPORT void jacobiSVD (const IMATH_INTERNAL_NAMESPACE::Matrix33<float>& A,
+                                      IMATH_INTERNAL_NAMESPACE::Matrix33<float>& U,
+                                      IMATH_INTERNAL_NAMESPACE::Vec3<float>& S,
+                                      IMATH_INTERNAL_NAMESPACE::Matrix33<float>& V,
+                                      const float tol,
+                                      const bool forcePositiveDeterminant);
+template IMATH_EXPORT void jacobiSVD (const IMATH_INTERNAL_NAMESPACE::Matrix33<double>& A,
+                                      IMATH_INTERNAL_NAMESPACE::Matrix33<double>& U,
+                                      IMATH_INTERNAL_NAMESPACE::Vec3<double>& S,
+                                      IMATH_INTERNAL_NAMESPACE::Matrix33<double>& V,
+                                      const double tol,
+                                      const bool forcePositiveDeterminant);
+template IMATH_EXPORT void jacobiSVD (const IMATH_INTERNAL_NAMESPACE::Matrix44<float>& A,
+                                      IMATH_INTERNAL_NAMESPACE::Matrix44<float>& U,
+                                      IMATH_INTERNAL_NAMESPACE::Vec4<float>& S,
+                                      IMATH_INTERNAL_NAMESPACE::Matrix44<float>& V,
+                                      const float tol,
+                                      const bool forcePositiveDeterminant);
+template IMATH_EXPORT void jacobiSVD (const IMATH_INTERNAL_NAMESPACE::Matrix44<double>& A,
+                                      IMATH_INTERNAL_NAMESPACE::Matrix44<double>& U,
+                                      IMATH_INTERNAL_NAMESPACE::Vec4<double>& S,
+                                      IMATH_INTERNAL_NAMESPACE::Matrix44<double>& V,
+                                      const double tol,
+                                      const bool forcePositiveDeterminant);
 
 namespace
 {
@@ -1213,39 +1214,39 @@ minEigenVector (TM& A, TV& V)
         V[i] = MV[i][minIdx];
 }
 
-template void jacobiEigenSolver (Matrix33<float>& A,
-                                 Vec3<float>& S,
-                                 Matrix33<float>& V,
-                                 const float tol);
-template void jacobiEigenSolver (Matrix33<double>& A,
-                                 Vec3<double>& S,
-                                 Matrix33<double>& V,
-                                 const double tol);
-template void jacobiEigenSolver (Matrix44<float>& A,
-                                 Vec4<float>& S,
-                                 Matrix44<float>& V,
-                                 const float tol);
-template void jacobiEigenSolver (Matrix44<double>& A,
-                                 Vec4<double>& S,
-                                 Matrix44<double>& V,
-                                 const double tol);
-
-template void maxEigenVector (Matrix33<float>& A,
-                              Vec3<float>& S);
-template void maxEigenVector (Matrix44<float>& A,
-                              Vec4<float>& S);
-template void maxEigenVector (Matrix33<double>& A,
-                              Vec3<double>& S);
-template void maxEigenVector (Matrix44<double>& A,
-                              Vec4<double>& S);
-
-template void minEigenVector (Matrix33<float>& A,
-                              Vec3<float>& S);
-template void minEigenVector (Matrix44<float>& A,
-                              Vec4<float>& S);
-template void minEigenVector (Matrix33<double>& A,
-                              Vec3<double>& S);
-template void minEigenVector (Matrix44<double>& A,
-                              Vec4<double>& S);
-
-} // namespace Imath
+template IMATH_EXPORT void jacobiEigenSolver (Matrix33<float>& A,
+                                              Vec3<float>& S,
+                                              Matrix33<float>& V,
+                                              const float tol);
+template IMATH_EXPORT void jacobiEigenSolver (Matrix33<double>& A,
+                                              Vec3<double>& S,
+                                              Matrix33<double>& V,
+                                              const double tol);
+template IMATH_EXPORT void jacobiEigenSolver (Matrix44<float>& A,
+                                              Vec4<float>& S,
+                                              Matrix44<float>& V,
+                                              const float tol);
+template IMATH_EXPORT void jacobiEigenSolver (Matrix44<double>& A,
+                                              Vec4<double>& S,
+                                              Matrix44<double>& V,
+                                              const double tol);
+
+template IMATH_EXPORT void maxEigenVector (Matrix33<float>& A,
+                                           Vec3<float>& S);
+template IMATH_EXPORT void maxEigenVector (Matrix44<float>& A,
+                                           Vec4<float>& S);
+template IMATH_EXPORT void maxEigenVector (Matrix33<double>& A,
+                                           Vec3<double>& S);
+template IMATH_EXPORT void maxEigenVector (Matrix44<double>& A,
+                                           Vec4<double>& S);
+
+template IMATH_EXPORT void minEigenVector (Matrix33<float>& A,
+                                           Vec3<float>& S);
+template IMATH_EXPORT void minEigenVector (Matrix44<float>& A,
+                                           Vec4<float>& S);
+template IMATH_EXPORT void minEigenVector (Matrix33<double>& A,
+                                           Vec3<double>& S);
+template IMATH_EXPORT void minEigenVector (Matrix44<double>& A,
+                                           Vec4<double>& S);
+
+IMATH_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/Imath/ImathMatrixAlgo.h b/Source/OpenEXR/Imath/ImathMatrixAlgo.h
index 6cb1568..8e90b02 100644
--- a/Source/OpenEXR/Imath/ImathMatrixAlgo.h
+++ b/Source/OpenEXR/Imath/ImathMatrixAlgo.h
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -38,37 +38,27 @@
 
 //-------------------------------------------------------------------------
 //
-//      This file contains algorithms applied to or in conjunction with
-//	transformation matrices (Imath::Matrix33 and Imath::Matrix44).
-//	The assumption made is that these functions are called much less
-//	often than the basic point functions or these functions require
-//	more support classes.
+//  This file contains algorithms applied to or in conjunction with
+//  transformation matrices (Imath::Matrix33 and Imath::Matrix44).
+//  The assumption made is that these functions are called much less
+//  often than the basic point functions or these functions require
+//  more support classes.
 //
-//	This file also defines a few predefined constant matrices.
+//  This file also defines a few predefined constant matrices.
 //
 //-------------------------------------------------------------------------
 
+#include "ImathExport.h"
 #include "ImathMatrix.h"
 #include "ImathQuat.h"
 #include "ImathEuler.h"
 #include "ImathExc.h"
 #include "ImathVec.h"
 #include "ImathLimits.h"
+#include "ImathNamespace.h"
 #include <math.h>
 
-
-#ifdef OPENEXR_DLL
-    #ifdef IMATH_EXPORTS
-        #define IMATH_EXPORT_CONST extern __declspec(dllexport)
-    #else
-	#define IMATH_EXPORT_CONST extern __declspec(dllimport)
-    #endif
-#else
-    #define IMATH_EXPORT_CONST extern const
-#endif
-
-
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 //------------------
 // Identity matrices
@@ -492,8 +482,8 @@ extractAndRemoveScalingAndShear (Matrix44<T> &mat,
     T maxVal = 0;
     for (int i=0; i < 3; i++)
 	for (int j=0; j < 3; j++)
-	    if (Imath::abs (row[i][j]) > maxVal)
-		maxVal = Imath::abs (row[i][j]);
+	    if (IMATH_INTERNAL_NAMESPACE::abs (row[i][j]) > maxVal)
+		maxVal = IMATH_INTERNAL_NAMESPACE::abs (row[i][j]);
 
     //
     // We normalize the 3x3 matrix here.
@@ -758,8 +748,8 @@ extractSHRT (const Matrix44<T> &mat,
 
     if (rOrder != Euler<T>::XYZ)
     {
-	Imath::Euler<T> eXYZ (r, Imath::Euler<T>::XYZ);
-	Imath::Euler<T> e (eXYZ, rOrder);
+	IMATH_INTERNAL_NAMESPACE::Euler<T> eXYZ (r, IMATH_INTERNAL_NAMESPACE::Euler<T>::XYZ);
+	IMATH_INTERNAL_NAMESPACE::Euler<T> e (eXYZ, rOrder);
 	r = e.toXYZVector ();
     }
 
@@ -775,7 +765,7 @@ extractSHRT (const Matrix44<T> &mat,
 	     Vec3<T> &t,
 	     bool exc)
 {
-    return extractSHRT(mat, s, h, r, t, exc, Imath::Euler<T>::XYZ);
+    return extractSHRT(mat, s, h, r, t, exc, IMATH_INTERNAL_NAMESPACE::Euler<T>::XYZ);
 }
 
 template <class T>
@@ -802,7 +792,7 @@ checkForZeroScaleInRow (const T& scl,
 	if ((abs (scl) < 1 && abs (row[i]) >= limits<T>::max() * abs (scl)))
 	{
 	    if (exc)
-		throw Imath::ZeroScaleExc ("Cannot remove zero scaling "
+		throw IMATH_INTERNAL_NAMESPACE::ZeroScaleExc ("Cannot remove zero scaling "
 					   "from matrix.");
 	    else
 		return false;
@@ -852,12 +842,12 @@ rotationMatrixWithUpDir (const Vec3<T> &fromDir,
 
     else
     {
-	Matrix44<T> zAxis2FromDir( Imath::UNINITIALIZED );
+	Matrix44<T> zAxis2FromDir( IMATH_INTERNAL_NAMESPACE::UNINITIALIZED );
 	alignZAxisWithTargetDir (zAxis2FromDir, fromDir, Vec3<T> (0, 1, 0));
 
 	Matrix44<T> fromDir2zAxis  = zAxis2FromDir.transposed ();
 	
-	Matrix44<T> zAxis2ToDir( Imath::UNINITIALIZED );
+	Matrix44<T> zAxis2ToDir( IMATH_INTERNAL_NAMESPACE::UNINITIALIZED );
 	alignZAxisWithTargetDir (zAxis2ToDir, toDir, upDir);
 
 	return fromDir2zAxis * zAxis2ToDir;
@@ -1166,8 +1156,8 @@ extractAndRemoveScalingAndShear (Matrix33<T> &mat,
     T maxVal = 0;
     for (int i=0; i < 2; i++)
 	for (int j=0; j < 2; j++)
-	    if (Imath::abs (row[i][j]) > maxVal)
-		maxVal = Imath::abs (row[i][j]);
+	    if (IMATH_INTERNAL_NAMESPACE::abs (row[i][j]) > maxVal)
+		maxVal = IMATH_INTERNAL_NAMESPACE::abs (row[i][j]);
 
     //
     // We normalize the 2x2 matrix here.
@@ -1291,19 +1281,19 @@ extractSHRT (const Matrix33<T> &mat,
 template <class T> 
 bool		
 checkForZeroScaleInRow (const T& scl, 
-			const Vec2<T> &row,
-			bool exc /* = true */ )
+                        const Vec2<T> &row,
+                        bool exc /* = true */ )
 {
     for (int i = 0; i < 2; i++)
     {
-	if ((abs (scl) < 1 && abs (row[i]) >= limits<T>::max() * abs (scl)))
-	{
-	    if (exc)
-		throw Imath::ZeroScaleExc ("Cannot remove zero scaling "
-					   "from matrix.");
-	    else
-		return false;
-	}
+        if ((abs (scl) < 1 && abs (row[i]) >= limits<T>::max() * abs (scl)))
+        {
+            if (exc)
+                throw IMATH_INTERNAL_NAMESPACE::ZeroScaleExc (
+                        "Cannot remove zero scaling from matrix.");
+            else
+                return false;
+        }
     }
 
     return true;
@@ -1330,18 +1320,18 @@ outerProduct (const Vec3<T> &a, const Vec3<T> &b )
 //     || (A*x - y)^T * W * (A*x - y) ||_F
 // If doScaling is true, then a uniform scale is allowed also.
 template <typename T>
-Imath::M44d
-procrustesRotationAndTranslation (const Imath::Vec3<T>* A,  // From these
-                                  const Imath::Vec3<T>* B,  // To these
+IMATH_INTERNAL_NAMESPACE::M44d
+procrustesRotationAndTranslation (const IMATH_INTERNAL_NAMESPACE::Vec3<T>* A,  // From these
+                                  const IMATH_INTERNAL_NAMESPACE::Vec3<T>* B,  // To these
                                   const T* weights, 
                                   const size_t numPoints,
                                   const bool doScaling = false);
 
 // Unweighted:
 template <typename T>
-Imath::M44d
-procrustesRotationAndTranslation (const Imath::Vec3<T>* A, 
-                                  const Imath::Vec3<T>* B, 
+IMATH_INTERNAL_NAMESPACE::M44d
+procrustesRotationAndTranslation (const IMATH_INTERNAL_NAMESPACE::Vec3<T>* A, 
+                                  const IMATH_INTERNAL_NAMESPACE::Vec3<T>* B, 
                                   const size_t numPoints,
                                   const bool doScaling = false);
 
@@ -1362,20 +1352,20 @@ procrustesRotationAndTranslation (const Imath::Vec3<T>* A,
 // Currently only available for single- and double-precision matrices.
 template <typename T>
 void
-jacobiSVD (const Imath::Matrix33<T>& A,
-           Imath::Matrix33<T>& U,
-           Imath::Vec3<T>& S,
-           Imath::Matrix33<T>& V,
-           const T tol = Imath::limits<T>::epsilon(),
+jacobiSVD (const IMATH_INTERNAL_NAMESPACE::Matrix33<T>& A,
+           IMATH_INTERNAL_NAMESPACE::Matrix33<T>& U,
+           IMATH_INTERNAL_NAMESPACE::Vec3<T>& S,
+           IMATH_INTERNAL_NAMESPACE::Matrix33<T>& V,
+           const T tol = IMATH_INTERNAL_NAMESPACE::limits<T>::epsilon(),
            const bool forcePositiveDeterminant = false);
 
 template <typename T>
 void
-jacobiSVD (const Imath::Matrix44<T>& A,
-           Imath::Matrix44<T>& U,
-           Imath::Vec4<T>& S,
-           Imath::Matrix44<T>& V,
-           const T tol = Imath::limits<T>::epsilon(),
+jacobiSVD (const IMATH_INTERNAL_NAMESPACE::Matrix44<T>& A,
+           IMATH_INTERNAL_NAMESPACE::Matrix44<T>& U,
+           IMATH_INTERNAL_NAMESPACE::Vec4<T>& S,
+           IMATH_INTERNAL_NAMESPACE::Matrix44<T>& V,
+           const T tol = IMATH_INTERNAL_NAMESPACE::limits<T>::epsilon(),
            const bool forcePositiveDeterminant = false);
 
 // Compute the eigenvalues (S) and the eigenvectors (V) of
@@ -1430,6 +1420,6 @@ template <typename TM, typename TV>
 void
 minEigenVector (TM& A, TV& S);
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_IMATHMATRIXALGO_H
diff --git a/Source/OpenEXR/Imath/ImathNamespace.h b/Source/OpenEXR/Imath/ImathNamespace.h
new file mode 100644
index 0000000..c1fb993
--- /dev/null
+++ b/Source/OpenEXR/Imath/ImathNamespace.h
@@ -0,0 +1,115 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2012, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission. 
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef INCLUDED_IMATHNAMESPACE_H
+#define INCLUDED_IMATHNAMESPACE_H
+
+//
+// The purpose of this file is to make it possible to specify an
+// IMATH_INTERNAL_NAMESPACE as a preprocessor definition and have all of the
+// Imath symbols defined within that namespace rather than the standard
+// Imath namespace.  Those symbols are made available to client code through
+// the IMATH_NAMESPACE in addition to the IMATH_INTERNAL_NAMESPACE.
+//
+// To ensure source code compatibility, the IMATH_NAMESPACE defaults to Imath
+// and then "using namespace IMATH_INTERNAL_NAMESPACE;" brings all of the
+// declarations from the IMATH_INTERNAL_NAMESPACE into the IMATH_NAMESPACE.
+// This means that client code can continue to use syntax like Imath::V3f,
+// but at link time it will resolve to a mangled symbol based on the
+// IMATH_INTERNAL_NAMESPACE.
+//
+// As an example, if one needed to build against a newer version of Imath and
+// have it run alongside an older version in the same application, it is now
+// possible to use an internal namespace to prevent collisions between the
+// older versions of Imath symbols and the newer ones.  To do this, the
+// following could be defined at build time:
+//
+// IMATH_INTERNAL_NAMESPACE = Imath_v2
+//
+// This means that declarations inside Imath headers look like this (after
+// the preprocessor has done its work):
+//
+// namespace Imath_v2 {
+//     ...
+//     class declarations
+//     ...
+// }
+//
+// namespace Imath {
+//     using namespace Imath_v2;
+// }
+//
+
+//
+// Open Source version of this file pulls in the IlmBaseConfig.h file
+// for the configure time options.
+//
+#include "IlmBaseConfig.h"
+
+
+#ifndef IMATH_NAMESPACE
+#define IMATH_NAMESPACE Imath
+#endif
+
+#ifndef IMATH_INTERNAL_NAMESPACE
+#define IMATH_INTERNAL_NAMESPACE IMATH_NAMESPACE
+#endif
+
+//
+// We need to be sure that we import the internal namespace into the public one.
+// To do this, we use the small bit of code below which initially defines
+// IMATH_INTERNAL_NAMESPACE (so it can be referenced) and then defines
+// IMATH_NAMESPACE and pulls the internal symbols into the public
+// namespace.
+//
+
+namespace IMATH_INTERNAL_NAMESPACE {}
+namespace IMATH_NAMESPACE {
+     using namespace IMATH_INTERNAL_NAMESPACE;
+}
+
+//
+// There are identical pairs of HEADER/SOURCE ENTER/EXIT macros so that
+// future extension to the namespace mechanism is possible without changing
+// project source code.
+//
+
+#define IMATH_INTERNAL_NAMESPACE_HEADER_ENTER namespace IMATH_INTERNAL_NAMESPACE {
+#define IMATH_INTERNAL_NAMESPACE_HEADER_EXIT }
+
+#define IMATH_INTERNAL_NAMESPACE_SOURCE_ENTER namespace IMATH_INTERNAL_NAMESPACE {
+#define IMATH_INTERNAL_NAMESPACE_SOURCE_EXIT }
+
+
+#endif /* INCLUDED_IMATHNAMESPACE_H */
diff --git a/Source/OpenEXR/Imath/ImathPlane.h b/Source/OpenEXR/Imath/ImathPlane.h
index aa59e3c..7272d67 100644
--- a/Source/OpenEXR/Imath/ImathPlane.h
+++ b/Source/OpenEXR/Imath/ImathPlane.h
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -54,8 +54,9 @@
 
 #include "ImathVec.h"
 #include "ImathLine.h"
+#include "ImathNamespace.h"
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 template <class T>
@@ -251,6 +252,6 @@ Plane3<T> operator- (const Plane3<T> &plane)
 }
 
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_IMATHPLANE_H
diff --git a/Source/OpenEXR/Imath/ImathQuat.h b/Source/OpenEXR/Imath/ImathQuat.h
index a6ee936..e95e356 100644
--- a/Source/OpenEXR/Imath/ImathQuat.h
+++ b/Source/OpenEXR/Imath/ImathQuat.h
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -57,10 +57,11 @@
 
 #include "ImathExc.h"
 #include "ImathMatrix.h"
+#include "ImathNamespace.h"
 
 #include <iostream>
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 #if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
 // Disable MS VC++ warnings about conversion from double to float
@@ -958,6 +959,6 @@ operator * (const Vec3<T> &v, const Quat<T> &q)
 #pragma warning(default:4244)
 #endif
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_IMATHQUAT_H
diff --git a/Source/OpenEXR/Imath/ImathRandom.cpp b/Source/OpenEXR/Imath/ImathRandom.cpp
index b261b39..cf3d600 100644
--- a/Source/OpenEXR/Imath/ImathRandom.cpp
+++ b/Source/OpenEXR/Imath/ImathRandom.cpp
@@ -1,7 +1,6 @@
-
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -43,7 +42,7 @@
 #include "ImathRandom.h"
 #include "ImathInt64.h"
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_SOURCE_ENTER
 namespace {
 
 //
@@ -134,7 +133,7 @@ erand48 (unsigned short state[3])
 double
 drand48 ()
 {
-    return Imath::erand48 (staticState);
+    return IMATH_INTERNAL_NAMESPACE::erand48 (staticState);
 }
 
 
@@ -155,7 +154,7 @@ nrand48 (unsigned short state[3])
 long int
 lrand48 ()
 {
-    return Imath::nrand48 (staticState);
+    return IMATH_INTERNAL_NAMESPACE::nrand48 (staticState);
 }
 
 
@@ -192,4 +191,4 @@ Rand32::nextf ()
     return u.f - 1;
 }
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/Imath/ImathRandom.h b/Source/OpenEXR/Imath/ImathRandom.h
index 4351975..4f0db13 100644
--- a/Source/OpenEXR/Imath/ImathRandom.h
+++ b/Source/OpenEXR/Imath/ImathRandom.h
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -56,10 +56,13 @@
 //
 //-----------------------------------------------------------------------------
 
+#include "ImathNamespace.h"
+#include "ImathExport.h"
+
 #include <stdlib.h>
 #include <math.h>
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 //-----------------------------------------------
 // Fast random-number generator that generates
@@ -67,7 +70,7 @@ namespace Imath {
 // length of 2^32.
 //-----------------------------------------------
 
-class Rand32
+class IMATH_EXPORT Rand32
 {
   public:
 
@@ -224,11 +227,11 @@ gaussSphereRand (Rand &rand);
 // erand48(), nrand48() and friends
 //---------------------------------
 
-double		erand48 (unsigned short state[3]);
-double		drand48 ();
-long int	nrand48 (unsigned short state[3]);
-long int	lrand48 ();
-void		srand48 (long int seed);
+IMATH_EXPORT double     erand48 (unsigned short state[3]);
+IMATH_EXPORT double     drand48 ();
+IMATH_EXPORT long int   nrand48 (unsigned short state[3]);
+IMATH_EXPORT long int   lrand48 ();
+IMATH_EXPORT void       srand48 (long int seed);
 
 
 //---------------
@@ -303,21 +306,21 @@ Rand48::Rand48 (unsigned long int seed)
 inline bool
 Rand48::nextb ()
 {
-    return Imath::nrand48 (_state) & 1;
+    return nrand48 (_state) & 1;
 }
 
 
 inline long int
 Rand48::nexti ()
 {
-    return Imath::nrand48 (_state);
+    return nrand48 (_state);
 }
 
 
 inline double
 Rand48::nextf ()
 {
-    return Imath::erand48 (_state);
+    return erand48 (_state);
 }
 
 
@@ -393,6 +396,6 @@ gaussSphereRand (Rand &rand)
     return hollowSphereRand <Vec> (rand) * gaussRand (rand);
 }
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_IMATHRANDOM_H
diff --git a/Source/OpenEXR/Imath/ImathRoots.h b/Source/OpenEXR/Imath/ImathRoots.h
index d915c63..036b7f7 100644
--- a/Source/OpenEXR/Imath/ImathRoots.h
+++ b/Source/OpenEXR/Imath/ImathRoots.h
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -43,10 +43,11 @@
 //
 //---------------------------------------------------------------------
 
-#include <ImathMath.h>
+#include "ImathMath.h"
+#include "ImathNamespace.h"
 #include <complex>
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 //--------------------------------------------------------------------------
 // Find the real solutions of a linear, quadratic or cubic equation:
@@ -213,7 +214,6 @@ solveCubic (T a, T b, T c, T d, T x[3])
     }
 }
 
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-} // namespace Imath
-
-#endif
+#endif // INCLUDED_IMATHROOTS_H
diff --git a/Source/OpenEXR/Imath/ImathShear.cpp b/Source/OpenEXR/Imath/ImathShear.cpp
index 72541f5..2c0ba2a 100644
--- a/Source/OpenEXR/Imath/ImathShear.cpp
+++ b/Source/OpenEXR/Imath/ImathShear.cpp
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -43,7 +43,7 @@
 
 #include "ImathShear.h"
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 
@@ -51,4 +51,4 @@ namespace Imath {
 
 
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/Imath/ImathShear.h b/Source/OpenEXR/Imath/ImathShear.h
index bad40a5..b6f7b9a 100644
--- a/Source/OpenEXR/Imath/ImathShear.h
+++ b/Source/OpenEXR/Imath/ImathShear.h
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2004-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -47,14 +47,11 @@
 #include "ImathLimits.h"
 #include "ImathMath.h"
 #include "ImathVec.h"
-
+#include "ImathNamespace.h"
 #include <iostream>
 
 
-namespace Imath {
-
-
-
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 template <class T> class Shear6
 {
@@ -461,7 +458,7 @@ bool
 Shear6<T>::equalWithAbsError (const Shear6<T> &h, T e) const
 {
     for (int i = 0; i < 6; i++)
-	if (!Imath::equalWithAbsError ((*this)[i], h[i], e))
+	if (!IMATH_INTERNAL_NAMESPACE::equalWithAbsError ((*this)[i], h[i], e))
 	    return false;
 
     return true;
@@ -472,7 +469,7 @@ bool
 Shear6<T>::equalWithRelError (const Shear6<T> &h, T e) const
 {
     for (int i = 0; i < 6; i++)
-	if (!Imath::equalWithRelError ((*this)[i], h[i], e))
+	if (!IMATH_INTERNAL_NAMESPACE::equalWithRelError ((*this)[i], h[i], e))
 	    return false;
 
     return true;
@@ -654,6 +651,6 @@ operator * (S a, const Shear6<T> &h)
 }
 
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_IMATHSHEAR_H
diff --git a/Source/OpenEXR/Imath/ImathSphere.h b/Source/OpenEXR/Imath/ImathSphere.h
index 14d0365..e8f36df 100644
--- a/Source/OpenEXR/Imath/ImathSphere.h
+++ b/Source/OpenEXR/Imath/ImathSphere.h
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -46,8 +46,9 @@
 #include "ImathVec.h"
 #include "ImathBox.h"
 #include "ImathLine.h"
+#include "ImathNamespace.h"
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 template <class T>
 class Sphere3
@@ -171,7 +172,6 @@ bool Sphere3<T>::intersect(const Line3<T> &line, Vec3<T> &intersection) const
     }
 }
 
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-} //namespace Imath
-
-#endif
+#endif // INCLUDED_IMATHSPHERE_H
diff --git a/Source/OpenEXR/Imath/ImathVec.cpp b/Source/OpenEXR/Imath/ImathVec.cpp
index f692271..5e5b210 100644
--- a/Source/OpenEXR/Imath/ImathVec.cpp
+++ b/Source/OpenEXR/Imath/ImathVec.cpp
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -41,6 +41,7 @@
 //----------------------------------------------------------------------------
 
 #include "ImathVec.h"
+#include "ImathExport.h"
 
 #if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
 // suppress exception specification warnings
@@ -48,7 +49,7 @@
 #endif
 
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 namespace
 {
@@ -127,6 +128,7 @@ normalizeOrThrow(Vec4<T> &v)
 // Vec2<short>
 
 template <> 
+IMATH_EXPORT
 short
 Vec2<short>::length () const
 {
@@ -136,6 +138,7 @@ Vec2<short>::length () const
 }
 
 template <>
+IMATH_EXPORT
 const Vec2<short> &
 Vec2<short>::normalize ()
 {
@@ -144,8 +147,9 @@ Vec2<short>::normalize ()
 }
 
 template <>
+IMATH_EXPORT
 const Vec2<short> &
-Vec2<short>::normalizeExc () throw (Iex::MathExc)
+Vec2<short>::normalizeExc () throw (IEX_NAMESPACE::MathExc)
 {
     if ((x == 0) && (y == 0))
         throw NullVecExc ("Cannot normalize null vector.");
@@ -155,6 +159,7 @@ Vec2<short>::normalizeExc () throw (Iex::MathExc)
 }
 
 template <>
+IMATH_EXPORT
 const Vec2<short> &
 Vec2<short>::normalizeNonNull ()
 {
@@ -163,6 +168,7 @@ Vec2<short>::normalizeNonNull ()
 }
 
 template <>
+IMATH_EXPORT
 Vec2<short>
 Vec2<short>::normalized () const
 {
@@ -172,8 +178,9 @@ Vec2<short>::normalized () const
 }
 
 template <>
+IMATH_EXPORT
 Vec2<short>
-Vec2<short>::normalizedExc () const throw (Iex::MathExc)
+Vec2<short>::normalizedExc () const throw (IEX_NAMESPACE::MathExc)
 {
     if ((x == 0) && (y == 0))
         throw NullVecExc ("Cannot normalize null vector.");
@@ -184,6 +191,7 @@ Vec2<short>::normalizedExc () const throw (Iex::MathExc)
 }
 
 template <>
+IMATH_EXPORT
 Vec2<short>
 Vec2<short>::normalizedNonNull () const
 {
@@ -196,6 +204,7 @@ Vec2<short>::normalizedNonNull () const
 // Vec2<int>
 
 template <> 
+IMATH_EXPORT
 int
 Vec2<int>::length () const
 {
@@ -205,6 +214,7 @@ Vec2<int>::length () const
 }
 
 template <>
+IMATH_EXPORT
 const Vec2<int> &
 Vec2<int>::normalize ()
 {
@@ -213,8 +223,9 @@ Vec2<int>::normalize ()
 }
 
 template <>
+IMATH_EXPORT
 const Vec2<int> &
-Vec2<int>::normalizeExc () throw (Iex::MathExc)
+Vec2<int>::normalizeExc () throw (IEX_NAMESPACE::MathExc)
 {
     if ((x == 0) && (y == 0))
         throw NullVecExc ("Cannot normalize null vector.");
@@ -224,6 +235,7 @@ Vec2<int>::normalizeExc () throw (Iex::MathExc)
 }
 
 template <>
+IMATH_EXPORT
 const Vec2<int> &
 Vec2<int>::normalizeNonNull ()
 {
@@ -232,6 +244,7 @@ Vec2<int>::normalizeNonNull ()
 }
 
 template <>
+IMATH_EXPORT
 Vec2<int>
 Vec2<int>::normalized () const
 {
@@ -241,8 +254,9 @@ Vec2<int>::normalized () const
 }
 
 template <>
+IMATH_EXPORT
 Vec2<int>
-Vec2<int>::normalizedExc () const throw (Iex::MathExc)
+Vec2<int>::normalizedExc () const throw (IEX_NAMESPACE::MathExc)
 {
     if ((x == 0) && (y == 0))
         throw NullVecExc ("Cannot normalize null vector.");
@@ -253,6 +267,7 @@ Vec2<int>::normalizedExc () const throw (Iex::MathExc)
 }
 
 template <>
+IMATH_EXPORT
 Vec2<int>
 Vec2<int>::normalizedNonNull () const
 {
@@ -265,6 +280,7 @@ Vec2<int>::normalizedNonNull () const
 // Vec3<short>
 
 template <> 
+IMATH_EXPORT
 short
 Vec3<short>::length () const
 {
@@ -274,6 +290,7 @@ Vec3<short>::length () const
 }
 
 template <>
+IMATH_EXPORT
 const Vec3<short> &
 Vec3<short>::normalize ()
 {
@@ -282,8 +299,9 @@ Vec3<short>::normalize ()
 }
 
 template <>
+IMATH_EXPORT
 const Vec3<short> &
-Vec3<short>::normalizeExc () throw (Iex::MathExc)
+Vec3<short>::normalizeExc () throw (IEX_NAMESPACE::MathExc)
 {
     if ((x == 0) && (y == 0) && (z == 0))
         throw NullVecExc ("Cannot normalize null vector.");
@@ -293,6 +311,7 @@ Vec3<short>::normalizeExc () throw (Iex::MathExc)
 }
 
 template <>
+IMATH_EXPORT
 const Vec3<short> &
 Vec3<short>::normalizeNonNull ()
 {
@@ -301,6 +320,7 @@ Vec3<short>::normalizeNonNull ()
 }
 
 template <>
+IMATH_EXPORT
 Vec3<short>
 Vec3<short>::normalized () const
 {
@@ -310,8 +330,9 @@ Vec3<short>::normalized () const
 }
 
 template <>
+IMATH_EXPORT
 Vec3<short>
-Vec3<short>::normalizedExc () const throw (Iex::MathExc)
+Vec3<short>::normalizedExc () const throw (IEX_NAMESPACE::MathExc)
 {
     if ((x == 0) && (y == 0) && (z == 0))
         throw NullVecExc ("Cannot normalize null vector.");
@@ -322,6 +343,7 @@ Vec3<short>::normalizedExc () const throw (Iex::MathExc)
 }
 
 template <>
+IMATH_EXPORT
 Vec3<short>
 Vec3<short>::normalizedNonNull () const
 {
@@ -334,6 +356,7 @@ Vec3<short>::normalizedNonNull () const
 // Vec3<int>
 
 template <> 
+IMATH_EXPORT
 int
 Vec3<int>::length () const
 {
@@ -343,6 +366,7 @@ Vec3<int>::length () const
 }
 
 template <>
+IMATH_EXPORT
 const Vec3<int> &
 Vec3<int>::normalize ()
 {
@@ -351,8 +375,9 @@ Vec3<int>::normalize ()
 }
 
 template <>
+IMATH_EXPORT
 const Vec3<int> &
-Vec3<int>::normalizeExc () throw (Iex::MathExc)
+Vec3<int>::normalizeExc () throw (IEX_NAMESPACE::MathExc)
 {
     if ((x == 0) && (y == 0) && (z == 0))
         throw NullVecExc ("Cannot normalize null vector.");
@@ -362,6 +387,7 @@ Vec3<int>::normalizeExc () throw (Iex::MathExc)
 }
 
 template <>
+IMATH_EXPORT
 const Vec3<int> &
 Vec3<int>::normalizeNonNull ()
 {
@@ -370,6 +396,7 @@ Vec3<int>::normalizeNonNull ()
 }
 
 template <>
+IMATH_EXPORT
 Vec3<int>
 Vec3<int>::normalized () const
 {
@@ -379,8 +406,9 @@ Vec3<int>::normalized () const
 }
 
 template <>
+IMATH_EXPORT
 Vec3<int>
-Vec3<int>::normalizedExc () const throw (Iex::MathExc)
+Vec3<int>::normalizedExc () const throw (IEX_NAMESPACE::MathExc)
 {
     if ((x == 0) && (y == 0) && (z == 0))
         throw NullVecExc ("Cannot normalize null vector.");
@@ -391,6 +419,7 @@ Vec3<int>::normalizedExc () const throw (Iex::MathExc)
 }
 
 template <>
+IMATH_EXPORT
 Vec3<int>
 Vec3<int>::normalizedNonNull () const
 {
@@ -403,6 +432,7 @@ Vec3<int>::normalizedNonNull () const
 // Vec4<short>
 
 template <> 
+IMATH_EXPORT
 short
 Vec4<short>::length () const
 {
@@ -412,6 +442,7 @@ Vec4<short>::length () const
 }
 
 template <>
+IMATH_EXPORT
 const Vec4<short> &
 Vec4<short>::normalize ()
 {
@@ -420,8 +451,9 @@ Vec4<short>::normalize ()
 }
 
 template <>
+IMATH_EXPORT
 const Vec4<short> &
-Vec4<short>::normalizeExc () throw (Iex::MathExc)
+Vec4<short>::normalizeExc () throw (IEX_NAMESPACE::MathExc)
 {
     if ((x == 0) && (y == 0) && (z == 0) && (w == 0))
         throw NullVecExc ("Cannot normalize null vector.");
@@ -431,6 +463,7 @@ Vec4<short>::normalizeExc () throw (Iex::MathExc)
 }
 
 template <>
+IMATH_EXPORT
 const Vec4<short> &
 Vec4<short>::normalizeNonNull ()
 {
@@ -439,6 +472,7 @@ Vec4<short>::normalizeNonNull ()
 }
 
 template <>
+IMATH_EXPORT
 Vec4<short>
 Vec4<short>::normalized () const
 {
@@ -448,8 +482,9 @@ Vec4<short>::normalized () const
 }
 
 template <>
+IMATH_EXPORT
 Vec4<short>
-Vec4<short>::normalizedExc () const throw (Iex::MathExc)
+Vec4<short>::normalizedExc () const throw (IEX_NAMESPACE::MathExc)
 {
     if ((x == 0) && (y == 0) && (z == 0) && (w == 0))
         throw NullVecExc ("Cannot normalize null vector.");
@@ -460,6 +495,7 @@ Vec4<short>::normalizedExc () const throw (Iex::MathExc)
 }
 
 template <>
+IMATH_EXPORT
 Vec4<short>
 Vec4<short>::normalizedNonNull () const
 {
@@ -472,6 +508,7 @@ Vec4<short>::normalizedNonNull () const
 // Vec4<int>
 
 template <> 
+IMATH_EXPORT
 int
 Vec4<int>::length () const
 {
@@ -481,6 +518,7 @@ Vec4<int>::length () const
 }
 
 template <>
+IMATH_EXPORT
 const Vec4<int> &
 Vec4<int>::normalize ()
 {
@@ -489,8 +527,9 @@ Vec4<int>::normalize ()
 }
 
 template <>
+IMATH_EXPORT
 const Vec4<int> &
-Vec4<int>::normalizeExc () throw (Iex::MathExc)
+Vec4<int>::normalizeExc () throw (IEX_NAMESPACE::MathExc)
 {
     if ((x == 0) && (y == 0) && (z == 0) && (w == 0))
         throw NullVecExc ("Cannot normalize null vector.");
@@ -500,6 +539,7 @@ Vec4<int>::normalizeExc () throw (Iex::MathExc)
 }
 
 template <>
+IMATH_EXPORT
 const Vec4<int> &
 Vec4<int>::normalizeNonNull ()
 {
@@ -508,6 +548,7 @@ Vec4<int>::normalizeNonNull ()
 }
 
 template <>
+IMATH_EXPORT
 Vec4<int>
 Vec4<int>::normalized () const
 {
@@ -517,8 +558,9 @@ Vec4<int>::normalized () const
 }
 
 template <>
+IMATH_EXPORT
 Vec4<int>
-Vec4<int>::normalizedExc () const throw (Iex::MathExc)
+Vec4<int>::normalizedExc () const throw (IEX_NAMESPACE::MathExc)
 {
     if ((x == 0) && (y == 0) && (z == 0) && (w == 0))
         throw NullVecExc ("Cannot normalize null vector.");
@@ -529,6 +571,7 @@ Vec4<int>::normalizedExc () const throw (Iex::MathExc)
 }
 
 template <>
+IMATH_EXPORT
 Vec4<int>
 Vec4<int>::normalizedNonNull () const
 {
@@ -537,4 +580,4 @@ Vec4<int>::normalizedNonNull () const
     return v;
 }
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/Source/OpenEXR/Imath/ImathVec.h b/Source/OpenEXR/Imath/ImathVec.h
index e6d2b79..fb859eb 100644
--- a/Source/OpenEXR/Imath/ImathVec.h
+++ b/Source/OpenEXR/Imath/ImathVec.h
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2004-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -46,6 +46,7 @@
 #include "ImathExc.h"
 #include "ImathLimits.h"
 #include "ImathMath.h"
+#include "ImathNamespace.h"
 
 #include <iostream>
 
@@ -56,7 +57,7 @@
 #endif
 
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 template <class T> class Vec2;
 template <class T> class Vec3;
@@ -224,11 +225,11 @@ template <class T> class Vec2
     T			length2 () const;
 
     const Vec2 &	normalize ();           // modifies *this
-    const Vec2 &	normalizeExc () throw (Iex::MathExc);
+    const Vec2 &	normalizeExc () throw (IEX_NAMESPACE::MathExc);
     const Vec2 &	normalizeNonNull ();
 
     Vec2<T>		normalized () const;	// does not modify *this
-    Vec2<T>		normalizedExc () const throw (Iex::MathExc);
+    Vec2<T>		normalizedExc () const throw (IEX_NAMESPACE::MathExc);
     Vec2<T>		normalizedNonNull () const;
 
 
@@ -436,11 +437,11 @@ template <class T> class Vec3
     T			length2 () const;
 
     const Vec3 &	normalize ();           // modifies *this
-    const Vec3 &	normalizeExc () throw (Iex::MathExc);
+    const Vec3 &	normalizeExc () throw (IEX_NAMESPACE::MathExc);
     const Vec3 &	normalizeNonNull ();
 
     Vec3<T>		normalized () const;	// does not modify *this
-    Vec3<T>		normalizedExc () const throw (Iex::MathExc);
+    Vec3<T>		normalizedExc () const throw (IEX_NAMESPACE::MathExc);
     Vec3<T>		normalizedNonNull () const;
 
 
@@ -618,11 +619,11 @@ template <class T> class Vec4
     T               length2 () const;
 
     const Vec4 &    normalize ();           // modifies *this
-    const Vec4 &    normalizeExc () throw (Iex::MathExc);
+    const Vec4 &    normalizeExc () throw (IEX_NAMESPACE::MathExc);
     const Vec4 &    normalizeNonNull ();
 
     Vec4<T>         normalized () const;	// does not modify *this
-    Vec4<T>         normalizedExc () const throw (Iex::MathExc);
+    Vec4<T>         normalizedExc () const throw (IEX_NAMESPACE::MathExc);
     Vec4<T>         normalizedNonNull () const;
 
 
@@ -710,7 +711,7 @@ template <> const Vec2<short> &
 Vec2<short>::normalize ();
 
 template <> const Vec2<short> &
-Vec2<short>::normalizeExc () throw (Iex::MathExc);
+Vec2<short>::normalizeExc () throw (IEX_NAMESPACE::MathExc);
 
 template <> const Vec2<short> &
 Vec2<short>::normalizeNonNull ();
@@ -719,7 +720,7 @@ template <> Vec2<short>
 Vec2<short>::normalized () const;
 
 template <> Vec2<short>
-Vec2<short>::normalizedExc () const throw (Iex::MathExc);
+Vec2<short>::normalizedExc () const throw (IEX_NAMESPACE::MathExc);
 
 template <> Vec2<short>
 Vec2<short>::normalizedNonNull () const;
@@ -734,7 +735,7 @@ template <> const Vec2<int> &
 Vec2<int>::normalize ();
 
 template <> const Vec2<int> &
-Vec2<int>::normalizeExc () throw (Iex::MathExc);
+Vec2<int>::normalizeExc () throw (IEX_NAMESPACE::MathExc);
 
 template <> const Vec2<int> &
 Vec2<int>::normalizeNonNull ();
@@ -743,7 +744,7 @@ template <> Vec2<int>
 Vec2<int>::normalized () const;
 
 template <> Vec2<int>
-Vec2<int>::normalizedExc () const throw (Iex::MathExc);
+Vec2<int>::normalizedExc () const throw (IEX_NAMESPACE::MathExc);
 
 template <> Vec2<int>
 Vec2<int>::normalizedNonNull () const;
@@ -758,7 +759,7 @@ template <> const Vec3<short> &
 Vec3<short>::normalize ();
 
 template <> const Vec3<short> &
-Vec3<short>::normalizeExc () throw (Iex::MathExc);
+Vec3<short>::normalizeExc () throw (IEX_NAMESPACE::MathExc);
 
 template <> const Vec3<short> &
 Vec3<short>::normalizeNonNull ();
@@ -767,7 +768,7 @@ template <> Vec3<short>
 Vec3<short>::normalized () const;
 
 template <> Vec3<short>
-Vec3<short>::normalizedExc () const throw (Iex::MathExc);
+Vec3<short>::normalizedExc () const throw (IEX_NAMESPACE::MathExc);
 
 template <> Vec3<short>
 Vec3<short>::normalizedNonNull () const;
@@ -782,7 +783,7 @@ template <> const Vec3<int> &
 Vec3<int>::normalize ();
 
 template <> const Vec3<int> &
-Vec3<int>::normalizeExc () throw (Iex::MathExc);
+Vec3<int>::normalizeExc () throw (IEX_NAMESPACE::MathExc);
 
 template <> const Vec3<int> &
 Vec3<int>::normalizeNonNull ();
@@ -791,7 +792,7 @@ template <> Vec3<int>
 Vec3<int>::normalized () const;
 
 template <> Vec3<int>
-Vec3<int>::normalizedExc () const throw (Iex::MathExc);
+Vec3<int>::normalizedExc () const throw (IEX_NAMESPACE::MathExc);
 
 template <> Vec3<int>
 Vec3<int>::normalizedNonNull () const;
@@ -805,7 +806,7 @@ template <> const Vec4<short> &
 Vec4<short>::normalize ();
 
 template <> const Vec4<short> &
-Vec4<short>::normalizeExc () throw (Iex::MathExc);
+Vec4<short>::normalizeExc () throw (IEX_NAMESPACE::MathExc);
 
 template <> const Vec4<short> &
 Vec4<short>::normalizeNonNull ();
@@ -814,7 +815,7 @@ template <> Vec4<short>
 Vec4<short>::normalized () const;
 
 template <> Vec4<short>
-Vec4<short>::normalizedExc () const throw (Iex::MathExc);
+Vec4<short>::normalizedExc () const throw (IEX_NAMESPACE::MathExc);
 
 template <> Vec4<short>
 Vec4<short>::normalizedNonNull () const;
@@ -829,7 +830,7 @@ template <> const Vec4<int> &
 Vec4<int>::normalize ();
 
 template <> const Vec4<int> &
-Vec4<int>::normalizeExc () throw (Iex::MathExc);
+Vec4<int>::normalizeExc () throw (IEX_NAMESPACE::MathExc);
 
 template <> const Vec4<int> &
 Vec4<int>::normalizeNonNull ();
@@ -838,7 +839,7 @@ template <> Vec4<int>
 Vec4<int>::normalized () const;
 
 template <> Vec4<int>
-Vec4<int>::normalizedExc () const throw (Iex::MathExc);
+Vec4<int>::normalizedExc () const throw (IEX_NAMESPACE::MathExc);
 
 template <> Vec4<int>
 Vec4<int>::normalizedNonNull () const;
@@ -981,7 +982,7 @@ bool
 Vec2<T>::equalWithAbsError (const Vec2<T> &v, T e) const
 {
     for (int i = 0; i < 2; i++)
-	if (!Imath::equalWithAbsError ((*this)[i], v[i], e))
+	if (!IMATH_INTERNAL_NAMESPACE::equalWithAbsError ((*this)[i], v[i], e))
 	    return false;
 
     return true;
@@ -992,7 +993,7 @@ bool
 Vec2<T>::equalWithRelError (const Vec2<T> &v, T e) const
 {
     for (int i = 0; i < 2; i++)
-	if (!Imath::equalWithRelError ((*this)[i], v[i], e))
+	if (!IMATH_INTERNAL_NAMESPACE::equalWithRelError ((*this)[i], v[i], e))
 	    return false;
 
     return true;
@@ -1208,7 +1209,7 @@ Vec2<T>::normalize ()
 
 template <class T>
 const Vec2<T> &
-Vec2<T>::normalizeExc () throw (Iex::MathExc)
+Vec2<T>::normalizeExc () throw (IEX_NAMESPACE::MathExc)
 {
     T l = length();
 
@@ -1245,7 +1246,7 @@ Vec2<T>::normalized () const
 
 template <class T>
 Vec2<T>
-Vec2<T>::normalizedExc () const throw (Iex::MathExc)
+Vec2<T>::normalizedExc () const throw (IEX_NAMESPACE::MathExc)
 {
     T l = length();
 
@@ -1444,7 +1445,7 @@ bool
 Vec3<T>::equalWithAbsError (const Vec3<T> &v, T e) const
 {
     for (int i = 0; i < 3; i++)
-	if (!Imath::equalWithAbsError ((*this)[i], v[i], e))
+	if (!IMATH_INTERNAL_NAMESPACE::equalWithAbsError ((*this)[i], v[i], e))
 	    return false;
 
     return true;
@@ -1455,7 +1456,7 @@ bool
 Vec3<T>::equalWithRelError (const Vec3<T> &v, T e) const
 {
     for (int i = 0; i < 3; i++)
-	if (!Imath::equalWithRelError ((*this)[i], v[i], e))
+	if (!IMATH_INTERNAL_NAMESPACE::equalWithRelError ((*this)[i], v[i], e))
 	    return false;
 
     return true;
@@ -1700,7 +1701,7 @@ Vec3<T>::normalize ()
 
 template <class T>
 const Vec3<T> &
-Vec3<T>::normalizeExc () throw (Iex::MathExc)
+Vec3<T>::normalizeExc () throw (IEX_NAMESPACE::MathExc)
 {
     T l = length();
 
@@ -1739,7 +1740,7 @@ Vec3<T>::normalized () const
 
 template <class T>
 Vec3<T>
-Vec3<T>::normalizedExc () const throw (Iex::MathExc)
+Vec3<T>::normalizedExc () const throw (IEX_NAMESPACE::MathExc)
 {
     T l = length();
 
@@ -1865,7 +1866,7 @@ bool
 Vec4<T>::equalWithAbsError (const Vec4<T> &v, T e) const
 {
     for (int i = 0; i < 4; i++)
-        if (!Imath::equalWithAbsError ((*this)[i], v[i], e))
+        if (!IMATH_INTERNAL_NAMESPACE::equalWithAbsError ((*this)[i], v[i], e))
             return false;
 
     return true;
@@ -1876,7 +1877,7 @@ bool
 Vec4<T>::equalWithRelError (const Vec4<T> &v, T e) const
 {
     for (int i = 0; i < 4; i++)
-        if (!Imath::equalWithRelError ((*this)[i], v[i], e))
+        if (!IMATH_INTERNAL_NAMESPACE::equalWithRelError ((*this)[i], v[i], e))
             return false;
 
     return true;
@@ -2105,7 +2106,7 @@ Vec4<T>::normalize ()
 
 template <class T>
 const Vec4<T> &
-Vec4<T>::normalizeExc () throw (Iex::MathExc)
+Vec4<T>::normalizeExc () throw (IEX_NAMESPACE::MathExc)
 {
     T l = length();
 
@@ -2146,7 +2147,7 @@ Vec4<T>::normalized () const
 
 template <class T>
 Vec4<T>
-Vec4<T>::normalizedExc () const throw (Iex::MathExc)
+Vec4<T>::normalizedExc () const throw (IEX_NAMESPACE::MathExc)
 {
     T l = length();
 
@@ -2221,6 +2222,6 @@ operator * (T a, const Vec4<T> &v)
 #pragma warning(pop)
 #endif
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_IMATHVEC_H
diff --git a/Source/OpenEXR/Imath/ImathVecAlgo.h b/Source/OpenEXR/Imath/ImathVecAlgo.h
index 33e2c12..28bab6b 100644
--- a/Source/OpenEXR/Imath/ImathVecAlgo.h
+++ b/Source/OpenEXR/Imath/ImathVecAlgo.h
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 // 
 // All rights reserved.
@@ -49,8 +49,9 @@
 
 #include "ImathVec.h"
 #include "ImathLimits.h"
+#include "ImathNamespace.h"
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 //-----------------------------------------------------------------
@@ -141,6 +142,6 @@ closestVertex(const Vec &v0,
 }
 
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_IMATHVECALGO_H
diff --git a/Source/OpenEXR/Imath/Makefile.am b/Source/OpenEXR/Imath/Makefile.am
deleted file mode 100644
index 6752428..0000000
--- a/Source/OpenEXR/Imath/Makefile.am
+++ /dev/null
@@ -1,35 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-lib_LTLIBRARIES = libImath.la
-
-libImath_la_SOURCES = ImathShear.cpp ImathMatrixAlgo.cpp ImathVec.cpp \
-		      ImathColorAlgo.cpp ImathFun.cpp \
-		      ImathColorAlgo.h ImathMatrixAlgo.h ImathVec.h \
-		      ImathShear.h ImathFun.h ImathBox.h ImathBoxAlgo.h \
-		      ImathEuler.h ImathExc.h ImathLimits.h ImathLine.h \
-		      ImathLineAlgo.h ImathMatrix.h ImathPlane.h \
-		      ImathSphere.h ImathVecAlgo.h ImathQuat.h \
-		      ImathFrustum.h ImathMath.h ImathGL.h \
-		      ImathColor.h ImathRandom.h ImathRoots.h \
-		      ImathHalfLimits.h ImathInterval.h ImathGLU.h \
-		      ImathFrame.h ImathPlatform.h \
-		      ImathBox.cpp ImathRandom.cpp ImathInt64.h \
-		      ImathFrustumTest.h
-
-libImath_la_LDFLAGS = -version-info @LIBTOOL_VERSION@ -no-undefined
-libImath_la_LIBADD = ../Iex/libIex.la
-
-libImathincludedir = $(includedir)/OpenEXR
-
-libImathinclude_HEADERS = ImathColorAlgo.h ImathMatrixAlgo.h ImathVec.h \
-			  ImathShear.h ImathFun.h ImathBox.h ImathBoxAlgo.h \
-			  ImathEuler.h ImathExc.h ImathLimits.h ImathLine.h \
-			  ImathLineAlgo.h ImathMatrix.h ImathPlane.h \
-			  ImathSphere.h ImathVecAlgo.h ImathQuat.h \
-			  ImathFrustum.h ImathMath.h ImathGL.h \
-			  ImathColor.h ImathRandom.h ImathRoots.h \
-			  ImathHalfLimits.h ImathInterval.h ImathGLU.h \
-			  ImathFrame.h ImathPlatform.h ImathInt64.h
-
-INCLUDES = -I$(top_builddir) -I$(top_srcdir)/Iex -I$(top_srcdir)/Half \
-	   -I$(top_srcdir)/config
diff --git a/Source/OpenEXR/Imath/Makefile.in b/Source/OpenEXR/Imath/Makefile.in
deleted file mode 100644
index bc415dd..0000000
--- a/Source/OpenEXR/Imath/Makefile.in
+++ /dev/null
@@ -1,547 +0,0 @@
-# Makefile.in generated by automake 1.9.6 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005  Free Software Foundation, Inc.
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
- at SET_MAKE@
-
-
-srcdir = @srcdir@
-top_srcdir = @top_srcdir@
-VPATH = @srcdir@
-pkgdatadir = $(datadir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-top_builddir = ..
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-INSTALL = @INSTALL@
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-build_triplet = @build@
-host_triplet = @host@
-subdir = Imath
-DIST_COMMON = $(libImathinclude_HEADERS) $(srcdir)/Makefile.am \
-	$(srcdir)/Makefile.in
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
-	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
-	$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
-	$(top_srcdir)/m4/threads.m4 $(top_srcdir)/configure.ac
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
-	$(ACLOCAL_M4)
-mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config/IlmBaseConfig.h
-CONFIG_CLEAN_FILES =
-am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
-am__vpath_adj = case $$p in \
-    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
-    *) f=$$p;; \
-  esac;
-am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
-am__installdirs = "$(DESTDIR)$(libdir)" \
-	"$(DESTDIR)$(libImathincludedir)"
-libLTLIBRARIES_INSTALL = $(INSTALL)
-LTLIBRARIES = $(lib_LTLIBRARIES)
-libImath_la_DEPENDENCIES = ../Iex/libIex.la
-am_libImath_la_OBJECTS = ImathShear.lo ImathMatrixAlgo.lo ImathVec.lo \
-	ImathColorAlgo.lo ImathFun.lo ImathBox.lo ImathRandom.lo
-libImath_la_OBJECTS = $(am_libImath_la_OBJECTS)
-DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/config
-depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
-CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
-	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
-LTCXXCOMPILE = $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) \
-	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
-	$(AM_CXXFLAGS) $(CXXFLAGS)
-CXXLD = $(CXX)
-CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \
-	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
-COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
-	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
-	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
-	$(AM_CFLAGS) $(CFLAGS)
-CCLD = $(CC)
-LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
-	$(AM_LDFLAGS) $(LDFLAGS) -o $@
-SOURCES = $(libImath_la_SOURCES)
-DIST_SOURCES = $(libImath_la_SOURCES)
-libImathincludeHEADERS_INSTALL = $(INSTALL_HEADER)
-HEADERS = $(libImathinclude_HEADERS)
-ETAGS = etags
-CTAGS = ctags
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = @ACLOCAL@
-AMDEP_FALSE = @AMDEP_FALSE@
-AMDEP_TRUE = @AMDEP_TRUE@
-AMTAR = @AMTAR@
-AM_CFLAGS = @AM_CFLAGS@
-AM_CXXFLAGS = @AM_CXXFLAGS@
-AR = @AR@
-AUTOCONF = @AUTOCONF@
-AUTOHEADER = @AUTOHEADER@
-AUTOMAKE = @AUTOMAKE@
-AWK = @AWK@
-CC = @CC@
-CCDEPMODE = @CCDEPMODE@
-CFLAGS = @CFLAGS@
-CPP = @CPP@
-CPPFLAGS = @CPPFLAGS@
-CXX = @CXX@
-CXXCPP = @CXXCPP@
-CXXDEPMODE = @CXXDEPMODE@
-CXXFLAGS = @CXXFLAGS@
-CYGPATH_W = @CYGPATH_W@
-DEFS = @DEFS@
-DEPDIR = @DEPDIR@
-DSYMUTIL = @DSYMUTIL@
-DUMPBIN = @DUMPBIN@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EGREP = @EGREP@
-EXEEXT = @EXEEXT@
-FGREP = @FGREP@
-GREP = @GREP@
-HAVE_UCONTEXT_H = @HAVE_UCONTEXT_H@
-ILMBASE_VERSION = @ILMBASE_VERSION@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LD = @LD@
-LDFLAGS = @LDFLAGS@
-LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
-LIBTOOL = @LIBTOOL@
-LIBTOOL_VERSION = @LIBTOOL_VERSION@
-LIPO = @LIPO@
-LN_S = @LN_S@
-LTLIBOBJS = @LTLIBOBJS@
-MAINT = @MAINT@
-MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
-MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
-MAKEINFO = @MAKEINFO@
-NM = @NM@
-NMEDIT = @NMEDIT@
-OBJDUMP = @OBJDUMP@
-OBJEXT = @OBJEXT@
-OTOOL = @OTOOL@
-OTOOL64 = @OTOOL64@
-PACKAGE = @PACKAGE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-PTHREAD_CC = @PTHREAD_CC@
-PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
-PTHREAD_LIBS = @PTHREAD_LIBS@
-RANLIB = @RANLIB@
-SED = @SED@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-STRIP = @STRIP@
-VERSION = @VERSION@
-ac_ct_AR = @ac_ct_AR@
-ac_ct_CC = @ac_ct_CC@
-ac_ct_CXX = @ac_ct_CXX@
-ac_ct_DSYMUTIL = @ac_ct_DSYMUTIL@
-ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
-ac_ct_LIPO = @ac_ct_LIPO@
-ac_ct_NMEDIT = @ac_ct_NMEDIT@
-ac_ct_OBJDUMP = @ac_ct_OBJDUMP@
-ac_ct_OTOOL = @ac_ct_OTOOL@
-ac_ct_OTOOL64 = @ac_ct_OTOOL64@
-ac_ct_RANLIB = @ac_ct_RANLIB@
-ac_ct_STRIP = @ac_ct_STRIP@
-acx_pthread_config = @acx_pthread_config@
-am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
-am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
-am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
-am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
-am__include = @am__include@
-am__leading_dot = @am__leading_dot@
-am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
-bindir = @bindir@
-build = @build@
-build_alias = @build_alias@
-build_cpu = @build_cpu@
-build_os = @build_os@
-build_vendor = @build_vendor@
-datadir = @datadir@
-exec_prefix = @exec_prefix@
-host = @host@
-host_alias = @host_alias@
-host_cpu = @host_cpu@
-host_os = @host_os@
-host_vendor = @host_vendor@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-libdir = @libdir@
-libexecdir = @libexecdir@
-localstatedir = @localstatedir@
-lt_ECHO = @lt_ECHO@
-mandir = @mandir@
-mkdir_p = @mkdir_p@
-oldincludedir = @oldincludedir@
-prefix = @prefix@
-program_transform_name = @program_transform_name@
-sbindir = @sbindir@
-sharedstatedir = @sharedstatedir@
-sysconfdir = @sysconfdir@
-target_alias = @target_alias@
-lib_LTLIBRARIES = libImath.la
-libImath_la_SOURCES = ImathShear.cpp ImathMatrixAlgo.cpp ImathVec.cpp \
-		      ImathColorAlgo.cpp ImathFun.cpp \
-		      ImathColorAlgo.h ImathMatrixAlgo.h ImathVec.h \
-		      ImathShear.h ImathFun.h ImathBox.h ImathBoxAlgo.h \
-		      ImathEuler.h ImathExc.h ImathLimits.h ImathLine.h \
-		      ImathLineAlgo.h ImathMatrix.h ImathPlane.h \
-		      ImathSphere.h ImathVecAlgo.h ImathQuat.h \
-		      ImathFrustum.h ImathMath.h ImathGL.h \
-		      ImathColor.h ImathRandom.h ImathRoots.h \
-		      ImathHalfLimits.h ImathInterval.h ImathGLU.h \
-		      ImathFrame.h ImathPlatform.h \
-		      ImathBox.cpp ImathRandom.cpp ImathInt64.h \
-		      ImathFrustumTest.h
-
-libImath_la_LDFLAGS = -version-info @LIBTOOL_VERSION@ -no-undefined
-libImath_la_LIBADD = ../Iex/libIex.la
-libImathincludedir = $(includedir)/OpenEXR
-libImathinclude_HEADERS = ImathColorAlgo.h ImathMatrixAlgo.h ImathVec.h \
-			  ImathShear.h ImathFun.h ImathBox.h ImathBoxAlgo.h \
-			  ImathEuler.h ImathExc.h ImathLimits.h ImathLine.h \
-			  ImathLineAlgo.h ImathMatrix.h ImathPlane.h \
-			  ImathSphere.h ImathVecAlgo.h ImathQuat.h \
-			  ImathFrustum.h ImathMath.h ImathGL.h \
-			  ImathColor.h ImathRandom.h ImathRoots.h \
-			  ImathHalfLimits.h ImathInterval.h ImathGLU.h \
-			  ImathFrame.h ImathPlatform.h ImathInt64.h
-
-INCLUDES = -I$(top_builddir) -I$(top_srcdir)/Iex -I$(top_srcdir)/Half \
-	   -I$(top_srcdir)/config
-
-all: all-am
-
-.SUFFIXES:
-.SUFFIXES: .cpp .lo .o .obj
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
-	@for dep in $?; do \
-	  case '$(am__configure_deps)' in \
-	    *$$dep*) \
-	      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
-		&& exit 0; \
-	      exit 1;; \
-	  esac; \
-	done; \
-	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu  Imath/Makefile'; \
-	cd $(top_srcdir) && \
-	  $(AUTOMAKE) --gnu  Imath/Makefile
-.PRECIOUS: Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
-	@case '$?' in \
-	  *config.status*) \
-	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
-	  *) \
-	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
-	esac;
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-install-libLTLIBRARIES: $(lib_LTLIBRARIES)
-	@$(NORMAL_INSTALL)
-	test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)"
-	@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
-	  if test -f $$p; then \
-	    f=$(am__strip_dir) \
-	    echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
-	    $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
-	  else :; fi; \
-	done
-
-uninstall-libLTLIBRARIES:
-	@$(NORMAL_UNINSTALL)
-	@set -x; list='$(lib_LTLIBRARIES)'; for p in $$list; do \
-	  p=$(am__strip_dir) \
-	  echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
-	  $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
-	done
-
-clean-libLTLIBRARIES:
-	-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
-	@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
-	  dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
-	  test "$$dir" != "$$p" || dir=.; \
-	  echo "rm -f \"$${dir}/so_locations\""; \
-	  rm -f "$${dir}/so_locations"; \
-	done
-libImath.la: $(libImath_la_OBJECTS) $(libImath_la_DEPENDENCIES) 
-	$(CXXLINK) -rpath $(libdir) $(libImath_la_LDFLAGS) $(libImath_la_OBJECTS) $(libImath_la_LIBADD) $(LIBS)
-
-mostlyclean-compile:
-	-rm -f *.$(OBJEXT)
-
-distclean-compile:
-	-rm -f *.tab.c
-
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImathBox.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImathColorAlgo.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImathFun.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImathMatrixAlgo.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImathRandom.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImathShear.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ImathVec.Plo at am__quote@
-
-.cpp.o:
- at am__fastdepCXX_TRUE@	if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
- at am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(CXXCOMPILE) -c -o $@ $<
-
-.cpp.obj:
- at am__fastdepCXX_TRUE@	if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
- at am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
-
-.cpp.lo:
- at am__fastdepCXX_TRUE@	if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
- at am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(LTCXXCOMPILE) -c -o $@ $<
-
-mostlyclean-libtool:
-	-rm -f *.lo
-
-clean-libtool:
-	-rm -rf .libs _libs
-
-distclean-libtool:
-	-rm -f libtool
-uninstall-info-am:
-install-libImathincludeHEADERS: $(libImathinclude_HEADERS)
-	@$(NORMAL_INSTALL)
-	test -z "$(libImathincludedir)" || $(mkdir_p) "$(DESTDIR)$(libImathincludedir)"
-	@list='$(libImathinclude_HEADERS)'; for p in $$list; do \
-	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
-	  f=$(am__strip_dir) \
-	  echo " $(libImathincludeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(libImathincludedir)/$$f'"; \
-	  $(libImathincludeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(libImathincludedir)/$$f"; \
-	done
-
-uninstall-libImathincludeHEADERS:
-	@$(NORMAL_UNINSTALL)
-	@list='$(libImathinclude_HEADERS)'; for p in $$list; do \
-	  f=$(am__strip_dir) \
-	  echo " rm -f '$(DESTDIR)$(libImathincludedir)/$$f'"; \
-	  rm -f "$(DESTDIR)$(libImathincludedir)/$$f"; \
-	done
-
-ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
-	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
-	unique=`for i in $$list; do \
-	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
-	mkid -fID $$unique
-tags: TAGS
-
-TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
-		$(TAGS_FILES) $(LISP)
-	tags=; \
-	here=`pwd`; \
-	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
-	unique=`for i in $$list; do \
-	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
-	if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
-	  test -n "$$unique" || unique=$$empty_fix; \
-	  $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
-	    $$tags $$unique; \
-	fi
-ctags: CTAGS
-CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
-		$(TAGS_FILES) $(LISP)
-	tags=; \
-	here=`pwd`; \
-	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
-	unique=`for i in $$list; do \
-	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
-	test -z "$(CTAGS_ARGS)$$tags$$unique" \
-	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
-	     $$tags $$unique
-
-GTAGS:
-	here=`$(am__cd) $(top_builddir) && pwd` \
-	  && cd $(top_srcdir) \
-	  && gtags -i $(GTAGS_ARGS) $$here
-
-distclean-tags:
-	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
-distdir: $(DISTFILES)
-	@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
-	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
-	list='$(DISTFILES)'; for file in $$list; do \
-	  case $$file in \
-	    $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
-	    $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
-	  esac; \
-	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
-	  dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
-	  if test "$$dir" != "$$file" && test "$$dir" != "."; then \
-	    dir="/$$dir"; \
-	    $(mkdir_p) "$(distdir)$$dir"; \
-	  else \
-	    dir=''; \
-	  fi; \
-	  if test -d $$d/$$file; then \
-	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
-	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
-	    fi; \
-	    cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
-	  else \
-	    test -f $(distdir)/$$file \
-	    || cp -p $$d/$$file $(distdir)/$$file \
-	    || exit 1; \
-	  fi; \
-	done
-check-am: all-am
-check: check-am
-all-am: Makefile $(LTLIBRARIES) $(HEADERS)
-installdirs:
-	for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libImathincludedir)"; do \
-	  test -z "$$dir" || $(mkdir_p) "$$dir"; \
-	done
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
-	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
-	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	  `test -z '$(STRIP)' || \
-	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
-mostlyclean-generic:
-
-clean-generic:
-
-distclean-generic:
-	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-
-maintainer-clean-generic:
-	@echo "This command is intended for maintainers to use"
-	@echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
-
-clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
-	mostlyclean-am
-
-distclean: distclean-am
-	-rm -rf ./$(DEPDIR)
-	-rm -f Makefile
-distclean-am: clean-am distclean-compile distclean-generic \
-	distclean-libtool distclean-tags
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-info: info-am
-
-info-am:
-
-install-data-am: install-libImathincludeHEADERS
-
-install-exec-am: install-libLTLIBRARIES
-
-install-info: install-info-am
-
-install-man:
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
-	-rm -rf ./$(DEPDIR)
-	-rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-compile mostlyclean-generic \
-	mostlyclean-libtool
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am: uninstall-info-am uninstall-libImathincludeHEADERS \
-	uninstall-libLTLIBRARIES
-
-.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
-	clean-libLTLIBRARIES clean-libtool ctags distclean \
-	distclean-compile distclean-generic distclean-libtool \
-	distclean-tags distdir dvi dvi-am html html-am info info-am \
-	install install-am install-data install-data-am install-exec \
-	install-exec-am install-info install-info-am \
-	install-libImathincludeHEADERS install-libLTLIBRARIES \
-	install-man install-strip installcheck installcheck-am \
-	installdirs maintainer-clean maintainer-clean-generic \
-	mostlyclean mostlyclean-compile mostlyclean-generic \
-	mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \
-	uninstall-am uninstall-info-am \
-	uninstall-libImathincludeHEADERS uninstall-libLTLIBRARIES
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
diff --git a/Source/OpenEXR/OpenEXR.2003.vcproj b/Source/OpenEXR/OpenEXR.2003.vcproj
deleted file mode 100644
index 3f6e346..0000000
--- a/Source/OpenEXR/OpenEXR.2003.vcproj
+++ /dev/null
@@ -1,746 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="7.10"
-	Name="OpenEXR"
-	ProjectGUID="{17A4874B-0606-4687-90B6-F91F8CB3B8AF}"
-	SccProjectName=""
-	SccLocalPath="">
-	<Platforms>
-		<Platform
-			Name="Win32"/>
-	</Platforms>
-	<Configurations>
-		<Configuration
-			Name="Release|Win32"
-			OutputDirectory=".\Release"
-			IntermediateDirectory=".\Release"
-			ConfigurationType="4"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="FALSE"
-			CharacterSet="2">
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="2"
-				GlobalOptimizations="TRUE"
-				InlineFunctionExpansion="2"
-				EnableIntrinsicFunctions="TRUE"
-				FavorSizeOrSpeed="1"
-				OmitFramePointers="TRUE"
-				OptimizeForProcessor="3"
-				AdditionalIncludeDirectories="./;./IlmImf;./Imath;./Iex;./Half;./IlmThread;../ZLib"
-				PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
-				StringPooling="TRUE"
-				RuntimeLibrary="0"
-				EnableFunctionLevelLinking="FALSE"
-				ForceConformanceInForLoopScope="TRUE"
-				RuntimeTypeInfo="TRUE"
-				UsePrecompiledHeader="0"
-				PrecompiledHeaderFile=""
-				AssemblerListingLocation=".\Release/"
-				ObjectFile=".\Release/"
-				ProgramDataBaseFileName=".\Release/"
-				WarningLevel="3"
-				SuppressStartupBanner="TRUE"
-				Detect64BitPortabilityProblems="FALSE"
-				CompileAs="0"
-				DisableSpecificWarnings="4290"/>
-			<Tool
-				Name="VCCustomBuildTool"/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile=".\Release\OpenEXR.lib"
-				SuppressStartupBanner="TRUE"/>
-			<Tool
-				Name="VCMIDLTool"/>
-			<Tool
-				Name="VCPostBuildEventTool"/>
-			<Tool
-				Name="VCPreBuildEventTool"/>
-			<Tool
-				Name="VCPreLinkEventTool"/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="1036"/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"/>
-			<Tool
-				Name="VCManagedWrapperGeneratorTool"/>
-			<Tool
-				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
-		</Configuration>
-		<Configuration
-			Name="Debug|Win32"
-			OutputDirectory=".\Debug"
-			IntermediateDirectory=".\Debug"
-			ConfigurationType="4"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="FALSE"
-			CharacterSet="2">
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="0"
-				AdditionalIncludeDirectories="./;./IlmImf;./Imath;./Iex;./Half;./IlmThread;../ZLib"
-				PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
-				BasicRuntimeChecks="3"
-				RuntimeLibrary="1"
-				ForceConformanceInForLoopScope="TRUE"
-				RuntimeTypeInfo="TRUE"
-				UsePrecompiledHeader="0"
-				PrecompiledHeaderFile=""
-				AssemblerListingLocation=".\Debug/"
-				ObjectFile=".\Debug/"
-				ProgramDataBaseFileName=".\Debug/"
-				WarningLevel="3"
-				SuppressStartupBanner="TRUE"
-				Detect64BitPortabilityProblems="FALSE"
-				DebugInformationFormat="4"
-				CompileAs="0"
-				DisableSpecificWarnings="4290"/>
-			<Tool
-				Name="VCCustomBuildTool"/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile=".\Debug\OpenEXR.lib"
-				SuppressStartupBanner="TRUE"/>
-			<Tool
-				Name="VCMIDLTool"/>
-			<Tool
-				Name="VCPostBuildEventTool"/>
-			<Tool
-				Name="VCPreBuildEventTool"/>
-			<Tool
-				Name="VCPreLinkEventTool"/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="_DEBUG"
-				Culture="1036"/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"/>
-			<Tool
-				Name="VCManagedWrapperGeneratorTool"/>
-			<Tool
-				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Source Files"
-			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
-			<Filter
-				Name="IlmImf Source Files"
-				Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
-				<File
-					RelativePath=".\IlmImf\ImfAttribute.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfB44Compressor.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfBoxAttribute.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfChannelList.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfChannelListAttribute.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfChromaticities.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfChromaticitiesAttribute.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfCompressionAttribute.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfCompressor.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfConvert.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfCRgbaFile.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfDoubleAttribute.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfEnvmap.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfEnvmapAttribute.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfFloatAttribute.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfFrameBuffer.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfFramesPerSecond.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfHeader.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfHuf.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfInputFile.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfIntAttribute.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfIO.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfKeyCode.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfKeyCodeAttribute.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfLineOrderAttribute.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfLut.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfMatrixAttribute.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfMisc.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfOpaqueAttribute.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfOutputFile.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfPizCompressor.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfPreviewImage.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfPreviewImageAttribute.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfPxr24Compressor.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfRational.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfRationalAttribute.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfRgbaFile.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfRgbaYca.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfRleCompressor.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfScanLineInputFile.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfStandardAttributes.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfStdIO.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfStringAttribute.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfStringVectorAttribute.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfTestFile.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfThreading.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfTileDescriptionAttribute.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfTiledInputFile.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfTiledMisc.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfTiledOutputFile.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfTiledRgbaFile.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfTileOffsets.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfTimeCode.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfTimeCodeAttribute.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfVecAttribute.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfVersion.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfWav.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfZipCompressor.cpp">
-				</File>
-			</Filter>
-			<Filter
-				Name="Imath Source Files"
-				Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
-				<File
-					RelativePath=".\Imath\ImathBox.cpp">
-				</File>
-				<File
-					RelativePath=".\Imath\ImathColorAlgo.cpp">
-				</File>
-				<File
-					RelativePath=".\Imath\ImathFun.cpp">
-				</File>
-				<File
-					RelativePath=".\Imath\ImathMatrixAlgo.cpp">
-				</File>
-				<File
-					RelativePath=".\Imath\ImathRandom.cpp">
-				</File>
-				<File
-					RelativePath=".\Imath\ImathShear.cpp">
-				</File>
-				<File
-					RelativePath=".\Imath\ImathVec.cpp">
-				</File>
-			</Filter>
-			<Filter
-				Name="Iex Source Files"
-				Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
-				<File
-					RelativePath=".\Iex\IexBaseExc.cpp">
-				</File>
-				<File
-					RelativePath=".\Iex\IexThrowErrnoExc.cpp">
-				</File>
-			</Filter>
-			<Filter
-				Name="Half Source Files"
-				Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
-				<File
-					RelativePath=".\Half\half.cpp">
-				</File>
-			</Filter>
-			<Filter
-				Name="IlmThread Source Files"
-				Filter="">
-				<File
-					RelativePath=".\IlmThread\IlmThread.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmThread\IlmThreadMutex.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmThread\IlmThreadPool.cpp">
-				</File>
-				<File
-					RelativePath=".\IlmThread\IlmThreadSemaphore.cpp">
-				</File>
-			</Filter>
-		</Filter>
-		<Filter
-			Name="Header Files"
-			Filter="h;hpp;hxx;hm;inl">
-			<File
-				RelativePath=".\IlmBaseConfig.h">
-			</File>
-			<File
-				RelativePath=".\OpenEXRConfig.h">
-			</File>
-			<Filter
-				Name="IlmImf Header Files"
-				Filter="h;hpp;hxx;hm;inl">
-				<File
-					RelativePath=".\IlmImf\b44ExpLogTable.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfArray.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfAttribute.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfAutoArray.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfB44Compressor.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfBoxAttribute.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfChannelList.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfChannelListAttribute.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfCheckedArithmetic.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfChromaticities.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfChromaticitiesAttribute.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfCompression.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfCompressionAttribute.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfCompressor.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfConvert.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfCRgbaFile.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfDoubleAttribute.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfEnvmap.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfEnvmapAttribute.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfFloatAttribute.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfFrameBuffer.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfFramesPerSecond.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfHeader.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfHuf.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfInputFile.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfInt64.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfIntAttribute.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfIO.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfKeyCode.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfKeyCodeAttribute.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfLineOrder.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfLineOrderAttribute.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfLut.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfMatrixAttribute.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfMisc.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfName.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfOpaqueAttribute.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfOutputFile.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfPixelType.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfPizCompressor.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfPreviewImage.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfPreviewImageAttribute.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfPxr24Compressor.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfRational.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfRationalAttribute.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfRgba.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfRgbaFile.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfRgbaYca.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfRleCompressor.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfScanLineInputFile.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfStandardAttributes.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfStdIO.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfStringAttribute.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfStringVectorAttribute.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfTestFile.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfThreading.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfTileDescription.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfTileDescriptionAttribute.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfTiledInputFile.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfTiledMisc.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfTiledOutputFile.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfTiledRgbaFile.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfTileOffsets.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfTimeCode.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfTimeCodeAttribute.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfVecAttribute.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfVersion.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfWav.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfXdr.h">
-				</File>
-				<File
-					RelativePath=".\IlmImf\ImfZipCompressor.h">
-				</File>
-			</Filter>
-			<Filter
-				Name="Imath Header Files"
-				Filter="h;hpp;hxx;hm;inl">
-				<File
-					RelativePath=".\Imath\ImathBox.h">
-				</File>
-				<File
-					RelativePath=".\Imath\ImathBoxAlgo.h">
-				</File>
-				<File
-					RelativePath=".\Imath\ImathColor.h">
-				</File>
-				<File
-					RelativePath=".\Imath\ImathColorAlgo.h">
-				</File>
-				<File
-					RelativePath=".\Imath\ImathEuler.h">
-				</File>
-				<File
-					RelativePath=".\Imath\ImathExc.h">
-				</File>
-				<File
-					RelativePath=".\Imath\ImathFrame.h">
-				</File>
-				<File
-					RelativePath=".\Imath\ImathFrustum.h">
-				</File>
-				<File
-					RelativePath=".\Imath\ImathFun.h">
-				</File>
-				<File
-					RelativePath=".\Imath\ImathGL.h">
-				</File>
-				<File
-					RelativePath=".\Imath\ImathGLU.h">
-				</File>
-				<File
-					RelativePath=".\Imath\ImathHalfLimits.h">
-				</File>
-				<File
-					RelativePath=".\Imath\ImathInterval.h">
-				</File>
-				<File
-					RelativePath=".\Imath\ImathLimits.h">
-				</File>
-				<File
-					RelativePath=".\Imath\ImathLine.h">
-				</File>
-				<File
-					RelativePath=".\Imath\ImathLineAlgo.h">
-				</File>
-				<File
-					RelativePath=".\Imath\ImathMath.h">
-				</File>
-				<File
-					RelativePath=".\Imath\ImathMatrix.h">
-				</File>
-				<File
-					RelativePath=".\Imath\ImathMatrixAlgo.h">
-				</File>
-				<File
-					RelativePath=".\Imath\ImathPlane.h">
-				</File>
-				<File
-					RelativePath=".\Imath\ImathPlatform.h">
-				</File>
-				<File
-					RelativePath=".\Imath\ImathQuat.h">
-				</File>
-				<File
-					RelativePath=".\Imath\ImathRandom.h">
-				</File>
-				<File
-					RelativePath=".\Imath\ImathRoots.h">
-				</File>
-				<File
-					RelativePath=".\Imath\ImathShear.h">
-				</File>
-				<File
-					RelativePath=".\Imath\ImathSphere.h">
-				</File>
-				<File
-					RelativePath=".\Imath\ImathVec.h">
-				</File>
-				<File
-					RelativePath=".\Imath\ImathVecAlgo.h">
-				</File>
-			</Filter>
-			<Filter
-				Name="Iex Header Files"
-				Filter="h;hpp;hxx;hm;inl">
-				<File
-					RelativePath=".\Iex\Iex.h">
-				</File>
-				<File
-					RelativePath=".\Iex\IexBaseExc.h">
-				</File>
-				<File
-					RelativePath=".\Iex\IexErrnoExc.h">
-				</File>
-				<File
-					RelativePath=".\Iex\IexMacros.h">
-				</File>
-				<File
-					RelativePath=".\Iex\IexMathExc.h">
-				</File>
-				<File
-					RelativePath=".\Iex\IexThrowErrnoExc.h">
-				</File>
-			</Filter>
-			<Filter
-				Name="Half Header Files"
-				Filter="h;hpp;hxx;hm;inl">
-				<File
-					RelativePath=".\Half\eLut.h">
-				</File>
-				<File
-					RelativePath=".\Half\half.h">
-				</File>
-				<File
-					RelativePath=".\Half\halfFunction.h">
-				</File>
-				<File
-					RelativePath=".\Half\halfLimits.h">
-				</File>
-				<File
-					RelativePath=".\Half\toFloat.h">
-				</File>
-			</Filter>
-			<Filter
-				Name="IlmThread Header Files"
-				Filter="">
-				<File
-					RelativePath=".\IlmThread\IlmThread.h">
-				</File>
-				<File
-					RelativePath=".\IlmThread\IlmThreadMutex.h">
-				</File>
-				<File
-					RelativePath=".\IlmThread\IlmThreadPool.h">
-				</File>
-				<File
-					RelativePath=".\IlmThread\IlmThreadSemaphore.h">
-				</File>
-			</Filter>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
diff --git a/Source/OpenEXR/OpenEXR.2005.vcproj b/Source/OpenEXR/OpenEXR.2005.vcproj
index fc62dff..554a52d 100644
--- a/Source/OpenEXR/OpenEXR.2005.vcproj
+++ b/Source/OpenEXR/OpenEXR.2005.vcproj
@@ -49,7 +49,7 @@
 				EnableIntrinsicFunctions="true"
 				FavorSizeOrSpeed="1"
 				OmitFramePointers="true"
-				AdditionalIncludeDirectories="./;./IlmImf;./Imath;./Iex;./Half;./IlmThread;../ZLib"
+				AdditionalIncludeDirectories="./;./IlmImf;./Imath;./IexMath;./Iex;./Half;./IlmThread;../ZLib"
 				PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE"
 				StringPooling="true"
 				RuntimeLibrary="0"
@@ -127,7 +127,7 @@
 			<Tool
 				Name="VCCLCompilerTool"
 				Optimization="0"
-				AdditionalIncludeDirectories="./;./IlmImf;./Imath;./Iex;./Half;./IlmThread;../ZLib"
+				AdditionalIncludeDirectories="./;./IlmImf;./Imath;./IexMath;./Iex;./Half;./IlmThread;../ZLib"
 				PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE"
 				BasicRuntimeChecks="3"
 				RuntimeLibrary="1"
@@ -352,6 +352,14 @@
 				Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
 				>
 				<File
+					RelativePath=".\IlmImf\b44ExpLogTable.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfAcesFile.cpp"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfAttribute.cpp"
 					>
 				</File>
@@ -380,6 +388,10 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfCompositeDeepScanLine.cpp"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfCompressionAttribute.cpp"
 					>
 				</File>
@@ -396,10 +408,58 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfDeepCompositing.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepFrameBuffer.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepImageStateAttribute.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepScanLineInputFile.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepScanLineInputPart.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepScanLineOutputFile.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepScanLineOutputPart.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepTiledInputFile.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepTiledInputPart.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepTiledOutputFile.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepTiledOutputPart.cpp"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfDoubleAttribute.cpp"
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfDwaCompressor.cpp"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfEnvmap.cpp"
 					>
 				</File>
@@ -408,10 +468,18 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfFastHuf.cpp"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfFloatAttribute.cpp"
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfFloatVectorAttribute.cpp"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfFrameBuffer.cpp"
 					>
 				</File>
@@ -420,6 +488,14 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfGenericInputFile.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfGenericOutputFile.cpp"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfHeader.cpp"
 					>
 				</File>
@@ -432,6 +508,14 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfInputPart.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfInputPartData.cpp"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfIntAttribute.cpp"
 					>
 				</File>
@@ -464,6 +548,18 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfMultiPartInputFile.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfMultiPartOutputFile.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfMultiView.cpp"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfOpaqueAttribute.cpp"
 					>
 				</File>
@@ -472,6 +568,18 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfOutputPart.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfOutputPartData.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfPartType.cpp"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfPizCompressor.cpp"
 					>
 				</File>
@@ -504,6 +612,10 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfRle.cpp"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfRleCompressor.cpp"
 					>
 				</File>
@@ -528,6 +640,10 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfSystemSpecific.cpp"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfTestFile.cpp"
 					>
 				</File>
@@ -544,6 +660,10 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfTiledInputPart.cpp"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfTiledMisc.cpp"
 					>
 				</File>
@@ -552,6 +672,10 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfTiledOutputPart.cpp"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfTiledRgbaFile.cpp"
 					>
 				</File>
@@ -580,6 +704,10 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfZip.cpp"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfZipCompressor.cpp"
 					>
 				</File>
@@ -659,6 +787,18 @@
 					>
 				</File>
 			</Filter>
+			<Filter
+				Name="IexMath Source Files"
+				>
+				<File
+					RelativePath=".\IexMath\IexMathFloatExc.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\IexMath\IexMathFpu.cpp"
+					>
+				</File>
+			</Filter>
 		</Filter>
 		<Filter
 			Name="Header Files"
@@ -681,6 +821,14 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\dwaLookups.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfAcesFile.h"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfArray.h"
 					>
 				</File>
@@ -721,6 +869,10 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfCompositeDeepScanLine.h"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfCompression.h"
 					>
 				</File>
@@ -741,10 +893,66 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfDeepCompositing.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepFrameBuffer.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepImageState.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepImageStateAttribute.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepScanLineInputFile.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepScanLineInputPart.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepScanLineOutputFile.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepScanLineOutputPart.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepTiledInputFile.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepTiledInputPart.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepTiledOutputFile.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepTiledOutputPart.h"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfDoubleAttribute.h"
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfDwaCompressor.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDwaCompressorSimd.h"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfEnvmap.h"
 					>
 				</File>
@@ -753,10 +961,26 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfExport.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfFastHuf.h"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfFloatAttribute.h"
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfFloatVectorAttribute.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfForward.h"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfFrameBuffer.h"
 					>
 				</File>
@@ -765,6 +989,14 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfGenericInputFile.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfGenericOutputFile.h"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfHeader.h"
 					>
 				</File>
@@ -777,6 +1009,18 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfInputPart.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfInputPartData.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfInputStreamMutex.h"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfInt64.h"
 					>
 				</File>
@@ -817,18 +1061,58 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfMultiPartInputFile.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfMultiPartOutputFile.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfMultiView.h"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfName.h"
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfNamespace.h"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfOpaqueAttribute.h"
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfOptimizedPixelReading.h"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfOutputFile.h"
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfOutputPart.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfOutputPartData.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfOutputStreamMutex.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfPartHelper.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfPartType.h"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfPixelType.h"
 					>
 				</File>
@@ -869,6 +1153,10 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfRle.h"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfRleCompressor.h"
 					>
 				</File>
@@ -877,6 +1165,10 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfSimd.h"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfStandardAttributes.h"
 					>
 				</File>
@@ -893,6 +1185,10 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfSystemSpecific.h"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfTestFile.h"
 					>
 				</File>
@@ -913,6 +1209,10 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfTiledInputPart.h"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfTiledMisc.h"
 					>
 				</File>
@@ -921,6 +1221,10 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfTiledOutputPart.h"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfTiledRgbaFile.h"
 					>
 				</File>
@@ -953,6 +1257,10 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfZip.h"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfZipCompressor.h"
 					>
 				</File>
@@ -986,6 +1294,14 @@
 					>
 				</File>
 				<File
+					RelativePath=".\Imath\ImathExport.h"
+					>
+				</File>
+				<File
+					RelativePath=".\Imath\ImathForward.h"
+					>
+				</File>
+				<File
 					RelativePath=".\Imath\ImathFrame.h"
 					>
 				</File>
@@ -994,6 +1310,10 @@
 					>
 				</File>
 				<File
+					RelativePath=".\Imath\ImathFrustumTest.h"
+					>
+				</File>
+				<File
 					RelativePath=".\Imath\ImathFun.h"
 					>
 				</File>
@@ -1010,6 +1330,10 @@
 					>
 				</File>
 				<File
+					RelativePath=".\Imath\ImathInt64.h"
+					>
+				</File>
+				<File
 					RelativePath=".\Imath\ImathInterval.h"
 					>
 				</File>
@@ -1038,6 +1362,10 @@
 					>
 				</File>
 				<File
+					RelativePath=".\Imath\ImathNamespace.h"
+					>
+				</File>
+				<File
 					RelativePath=".\Imath\ImathPlane.h"
 					>
 				</File>
@@ -1091,6 +1419,14 @@
 					>
 				</File>
 				<File
+					RelativePath=".\Iex\IexExport.h"
+					>
+				</File>
+				<File
+					RelativePath=".\Iex\IexForward.h"
+					>
+				</File>
+				<File
 					RelativePath=".\Iex\IexMacros.h"
 					>
 				</File>
@@ -1099,6 +1435,10 @@
 					>
 				</File>
 				<File
+					RelativePath=".\Iex\IexNamespace.h"
+					>
+				</File>
+				<File
 					RelativePath=".\Iex\IexThrowErrnoExc.h"
 					>
 				</File>
@@ -1148,6 +1488,18 @@
 					>
 				</File>
 			</Filter>
+			<Filter
+				Name="IexMath Header Files"
+				>
+				<File
+					RelativePath=".\IexMath\IexMathFloatExc.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IexMath\IexMathIeeeExc.h"
+					>
+				</File>
+			</Filter>
 		</Filter>
 	</Files>
 	<Globals>
diff --git a/Source/OpenEXR/OpenEXR.2008.vcproj b/Source/OpenEXR/OpenEXR.2008.vcproj
index d1f8b41..6c89fb3 100644
--- a/Source/OpenEXR/OpenEXR.2008.vcproj
+++ b/Source/OpenEXR/OpenEXR.2008.vcproj
@@ -50,7 +50,7 @@
 				EnableIntrinsicFunctions="true"
 				FavorSizeOrSpeed="1"
 				OmitFramePointers="true"
-				AdditionalIncludeDirectories="./;./IlmImf;./Imath;./Iex;./Half;./IlmThread;../ZLib"
+				AdditionalIncludeDirectories="./;./IlmImf;./Imath;./IexMath;./Iex;./Half;./IlmThread;../ZLib"
 				PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE"
 				StringPooling="true"
 				RuntimeLibrary="0"
@@ -66,7 +66,6 @@
 				SuppressStartupBanner="true"
 				Detect64BitPortabilityProblems="false"
 				CompileAs="0"
-				DisableSpecificWarnings="4290"
 			/>
 			<Tool
 				Name="VCManagedResourceCompilerTool"
@@ -133,7 +132,7 @@
 				EnableIntrinsicFunctions="true"
 				FavorSizeOrSpeed="1"
 				OmitFramePointers="true"
-				AdditionalIncludeDirectories="./;./IlmImf;./Imath;./Iex;./Half;./IlmThread;../ZLib"
+				AdditionalIncludeDirectories="./;./IlmImf;./Imath;./IexMath;./Iex;./Half;./IlmThread;../ZLib"
 				PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE"
 				StringPooling="true"
 				RuntimeLibrary="0"
@@ -149,7 +148,7 @@
 				SuppressStartupBanner="true"
 				Detect64BitPortabilityProblems="false"
 				CompileAs="0"
-				DisableSpecificWarnings="4290"
+				DisableSpecificWarnings="4800"
 			/>
 			<Tool
 				Name="VCManagedResourceCompilerTool"
@@ -211,7 +210,7 @@
 			<Tool
 				Name="VCCLCompilerTool"
 				Optimization="0"
-				AdditionalIncludeDirectories="./;./IlmImf;./Imath;./Iex;./Half;./IlmThread;../ZLib"
+				AdditionalIncludeDirectories="./;./IlmImf;./Imath;./IexMath;./Iex;./Half;./IlmThread;../ZLib"
 				PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE"
 				BasicRuntimeChecks="3"
 				RuntimeLibrary="1"
@@ -227,7 +226,6 @@
 				Detect64BitPortabilityProblems="false"
 				DebugInformationFormat="4"
 				CompileAs="0"
-				DisableSpecificWarnings="4290"
 			/>
 			<Tool
 				Name="VCManagedResourceCompilerTool"
@@ -290,7 +288,7 @@
 			<Tool
 				Name="VCCLCompilerTool"
 				Optimization="0"
-				AdditionalIncludeDirectories="./;./IlmImf;./Imath;./Iex;./Half;./IlmThread;../ZLib"
+				AdditionalIncludeDirectories="./;./IlmImf;./Imath;./IexMath;./Iex;./Half;./IlmThread;../ZLib"
 				PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE"
 				BasicRuntimeChecks="3"
 				RuntimeLibrary="1"
@@ -306,7 +304,7 @@
 				Detect64BitPortabilityProblems="false"
 				DebugInformationFormat="3"
 				CompileAs="0"
-				DisableSpecificWarnings="4290"
+				DisableSpecificWarnings="4800"
 			/>
 			<Tool
 				Name="VCManagedResourceCompilerTool"
@@ -353,6 +351,14 @@
 				Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
 				>
 				<File
+					RelativePath=".\IlmImf\b44ExpLogTable.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfAcesFile.cpp"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfAttribute.cpp"
 					>
 				</File>
@@ -381,6 +387,10 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfCompositeDeepScanLine.cpp"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfCompressionAttribute.cpp"
 					>
 				</File>
@@ -397,10 +407,58 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfDeepCompositing.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepFrameBuffer.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepImageStateAttribute.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepScanLineInputFile.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepScanLineInputPart.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepScanLineOutputFile.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepScanLineOutputPart.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepTiledInputFile.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepTiledInputPart.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepTiledOutputFile.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepTiledOutputPart.cpp"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfDoubleAttribute.cpp"
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfDwaCompressor.cpp"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfEnvmap.cpp"
 					>
 				</File>
@@ -409,10 +467,18 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfFastHuf.cpp"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfFloatAttribute.cpp"
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfFloatVectorAttribute.cpp"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfFrameBuffer.cpp"
 					>
 				</File>
@@ -421,6 +487,14 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfGenericInputFile.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfGenericOutputFile.cpp"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfHeader.cpp"
 					>
 				</File>
@@ -433,6 +507,14 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfInputPart.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfInputPartData.cpp"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfIntAttribute.cpp"
 					>
 				</File>
@@ -465,6 +547,18 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfMultiPartInputFile.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfMultiPartOutputFile.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfMultiView.cpp"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfOpaqueAttribute.cpp"
 					>
 				</File>
@@ -473,6 +567,18 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfOutputPart.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfOutputPartData.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfPartType.cpp"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfPizCompressor.cpp"
 					>
 				</File>
@@ -505,6 +611,10 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfRle.cpp"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfRleCompressor.cpp"
 					>
 				</File>
@@ -529,6 +639,10 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfSystemSpecific.cpp"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfTestFile.cpp"
 					>
 				</File>
@@ -545,6 +659,10 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfTiledInputPart.cpp"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfTiledMisc.cpp"
 					>
 				</File>
@@ -553,6 +671,10 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfTiledOutputPart.cpp"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfTiledRgbaFile.cpp"
 					>
 				</File>
@@ -581,6 +703,10 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfZip.cpp"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfZipCompressor.cpp"
 					>
 				</File>
@@ -660,6 +786,18 @@
 					>
 				</File>
 			</Filter>
+			<Filter
+				Name="IexMath Source Files"
+				>
+				<File
+					RelativePath=".\IexMath\IexMathFloatExc.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\IexMath\IexMathFpu.cpp"
+					>
+				</File>
+			</Filter>
 		</Filter>
 		<Filter
 			Name="Header Files"
@@ -682,6 +820,14 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\dwaLookups.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfAcesFile.h"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfArray.h"
 					>
 				</File>
@@ -722,6 +868,10 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfCompositeDeepScanLine.h"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfCompression.h"
 					>
 				</File>
@@ -742,10 +892,66 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfDeepCompositing.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepFrameBuffer.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepImageState.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepImageStateAttribute.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepScanLineInputFile.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepScanLineInputPart.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepScanLineOutputFile.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepScanLineOutputPart.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepTiledInputFile.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepTiledInputPart.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepTiledOutputFile.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDeepTiledOutputPart.h"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfDoubleAttribute.h"
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfDwaCompressor.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfDwaCompressorSimd.h"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfEnvmap.h"
 					>
 				</File>
@@ -754,10 +960,26 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfExport.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfFastHuf.h"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfFloatAttribute.h"
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfFloatVectorAttribute.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfForward.h"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfFrameBuffer.h"
 					>
 				</File>
@@ -766,6 +988,14 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfGenericInputFile.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfGenericOutputFile.h"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfHeader.h"
 					>
 				</File>
@@ -778,6 +1008,18 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfInputPart.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfInputPartData.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfInputStreamMutex.h"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfInt64.h"
 					>
 				</File>
@@ -818,18 +1060,58 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfMultiPartInputFile.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfMultiPartOutputFile.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfMultiView.h"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfName.h"
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfNamespace.h"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfOpaqueAttribute.h"
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfOptimizedPixelReading.h"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfOutputFile.h"
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfOutputPart.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfOutputPartData.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfOutputStreamMutex.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfPartHelper.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmImf\ImfPartType.h"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfPixelType.h"
 					>
 				</File>
@@ -870,6 +1152,10 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfRle.h"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfRleCompressor.h"
 					>
 				</File>
@@ -878,6 +1164,10 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfSimd.h"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfStandardAttributes.h"
 					>
 				</File>
@@ -894,6 +1184,10 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfSystemSpecific.h"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfTestFile.h"
 					>
 				</File>
@@ -914,6 +1208,10 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfTiledInputPart.h"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfTiledMisc.h"
 					>
 				</File>
@@ -922,6 +1220,10 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfTiledOutputPart.h"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfTiledRgbaFile.h"
 					>
 				</File>
@@ -954,6 +1256,10 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmImf\ImfZip.h"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmImf\ImfZipCompressor.h"
 					>
 				</File>
@@ -987,6 +1293,14 @@
 					>
 				</File>
 				<File
+					RelativePath=".\Imath\ImathExport.h"
+					>
+				</File>
+				<File
+					RelativePath=".\Imath\ImathForward.h"
+					>
+				</File>
+				<File
 					RelativePath=".\Imath\ImathFrame.h"
 					>
 				</File>
@@ -995,6 +1309,10 @@
 					>
 				</File>
 				<File
+					RelativePath=".\Imath\ImathFrustumTest.h"
+					>
+				</File>
+				<File
 					RelativePath=".\Imath\ImathFun.h"
 					>
 				</File>
@@ -1011,6 +1329,10 @@
 					>
 				</File>
 				<File
+					RelativePath=".\Imath\ImathInt64.h"
+					>
+				</File>
+				<File
 					RelativePath=".\Imath\ImathInterval.h"
 					>
 				</File>
@@ -1039,6 +1361,10 @@
 					>
 				</File>
 				<File
+					RelativePath=".\Imath\ImathNamespace.h"
+					>
+				</File>
+				<File
 					RelativePath=".\Imath\ImathPlane.h"
 					>
 				</File>
@@ -1092,6 +1418,14 @@
 					>
 				</File>
 				<File
+					RelativePath=".\Iex\IexExport.h"
+					>
+				</File>
+				<File
+					RelativePath=".\Iex\IexForward.h"
+					>
+				</File>
+				<File
 					RelativePath=".\Iex\IexMacros.h"
 					>
 				</File>
@@ -1100,6 +1434,10 @@
 					>
 				</File>
 				<File
+					RelativePath=".\Iex\IexNamespace.h"
+					>
+				</File>
+				<File
 					RelativePath=".\Iex\IexThrowErrnoExc.h"
 					>
 				</File>
@@ -1137,10 +1475,22 @@
 					>
 				</File>
 				<File
+					RelativePath=".\IlmThread\IlmThreadExport.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IlmThread\IlmThreadForward.h"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmThread\IlmThreadMutex.h"
 					>
 				</File>
 				<File
+					RelativePath=".\IlmThread\IlmThreadNamespace.h"
+					>
+				</File>
+				<File
 					RelativePath=".\IlmThread\IlmThreadPool.h"
 					>
 				</File>
@@ -1149,6 +1499,18 @@
 					>
 				</File>
 			</Filter>
+			<Filter
+				Name="IexMath Header Files"
+				>
+				<File
+					RelativePath=".\IexMath\IexMathFloatExc.h"
+					>
+				</File>
+				<File
+					RelativePath=".\IexMath\IexMathIeeeExc.h"
+					>
+				</File>
+			</Filter>
 		</Filter>
 	</Files>
 	<Globals>
diff --git a/Source/OpenEXR/OpenEXR.2013.vcxproj b/Source/OpenEXR/OpenEXR.2013.vcxproj
new file mode 100644
index 0000000..21e8a28
--- /dev/null
+++ b/Source/OpenEXR/OpenEXR.2013.vcxproj
@@ -0,0 +1,495 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectName>OpenEXR</ProjectName>
+    <ProjectGuid>{17A4874B-0606-4687-90B6-F91F8CB3B8AF}</ProjectGuid>
+    <RootNamespace>OpenEXR</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>12.0.21005.1</_ProjectFileVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <Optimization>MinSpace</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>./;./IlmImf;./Imath;./IexMath;./Iex;./Half;./IlmThread;../ZLib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <FunctionLevelLinking>false</FunctionLevelLinking>
+      <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <CompileAs>Default</CompileAs>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+      <DebugInformationFormat>None</DebugInformationFormat>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Lib>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <LinkTimeCodeGeneration>true</LinkTimeCodeGeneration>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>MinSpace</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>./;./IlmImf;./Imath;./IexMath;./Iex;./Half;./IlmThread;../ZLib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <FunctionLevelLinking>false</FunctionLevelLinking>
+      <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <CompileAs>Default</CompileAs>
+      <DisableSpecificWarnings>4800;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+      <DebugInformationFormat>None</DebugInformationFormat>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Lib>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <LinkTimeCodeGeneration>true</LinkTimeCodeGeneration>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>./;./IlmImf;./Imath;./IexMath;./Iex;./Half;./IlmThread;../ZLib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+      <CompileAs>Default</CompileAs>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Lib>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>./;./IlmImf;./Imath;./IexMath;./Iex;./Half;./IlmThread;../ZLib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <CompileAs>Default</CompileAs>
+      <DisableSpecificWarnings>4800;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Lib>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="IexMath\IexMathFpu.cpp" />
+    <ClCompile Include="IlmImf\b44ExpLogTable.cpp" />
+    <ClCompile Include="IlmImf\ImfAcesFile.cpp" />
+    <ClCompile Include="IlmImf\ImfAttribute.cpp" />
+    <ClCompile Include="IlmImf\ImfB44Compressor.cpp" />
+    <ClCompile Include="IlmImf\ImfBoxAttribute.cpp" />
+    <ClCompile Include="IlmImf\ImfChannelList.cpp" />
+    <ClCompile Include="IlmImf\ImfChannelListAttribute.cpp" />
+    <ClCompile Include="IlmImf\ImfChromaticities.cpp" />
+    <ClCompile Include="IlmImf\ImfChromaticitiesAttribute.cpp" />
+    <ClCompile Include="IlmImf\ImfCompositeDeepScanLine.cpp" />
+    <ClCompile Include="IlmImf\ImfCompressionAttribute.cpp" />
+    <ClCompile Include="IlmImf\ImfCompressor.cpp" />
+    <ClCompile Include="IlmImf\ImfConvert.cpp" />
+    <ClCompile Include="IlmImf\ImfCRgbaFile.cpp" />
+    <ClCompile Include="IlmImf\ImfDeepCompositing.cpp" />
+    <ClCompile Include="IlmImf\ImfDeepFrameBuffer.cpp" />
+    <ClCompile Include="IlmImf\ImfDeepImageStateAttribute.cpp" />
+    <ClCompile Include="IlmImf\ImfDeepScanLineInputFile.cpp" />
+    <ClCompile Include="IlmImf\ImfDeepScanLineInputPart.cpp" />
+    <ClCompile Include="IlmImf\ImfDeepScanLineOutputFile.cpp" />
+    <ClCompile Include="IlmImf\ImfDeepScanLineOutputPart.cpp" />
+    <ClCompile Include="IlmImf\ImfDeepTiledInputFile.cpp" />
+    <ClCompile Include="IlmImf\ImfDeepTiledInputPart.cpp" />
+    <ClCompile Include="IlmImf\ImfDeepTiledOutputFile.cpp" />
+    <ClCompile Include="IlmImf\ImfDeepTiledOutputPart.cpp" />
+    <ClCompile Include="IlmImf\ImfDoubleAttribute.cpp" />
+    <ClCompile Include="IlmImf\ImfDwaCompressor.cpp" />
+    <ClCompile Include="IlmImf\ImfEnvmap.cpp" />
+    <ClCompile Include="IlmImf\ImfEnvmapAttribute.cpp" />
+    <ClCompile Include="IlmImf\ImfFastHuf.cpp" />
+    <ClCompile Include="IlmImf\ImfFloatAttribute.cpp" />
+    <ClCompile Include="IlmImf\ImfFloatVectorAttribute.cpp" />
+    <ClCompile Include="IlmImf\ImfFrameBuffer.cpp" />
+    <ClCompile Include="IlmImf\ImfFramesPerSecond.cpp" />
+    <ClCompile Include="IlmImf\ImfGenericInputFile.cpp" />
+    <ClCompile Include="IlmImf\ImfGenericOutputFile.cpp" />
+    <ClCompile Include="IlmImf\ImfHeader.cpp" />
+    <ClCompile Include="IlmImf\ImfHuf.cpp" />
+    <ClCompile Include="IlmImf\ImfInputFile.cpp" />
+    <ClCompile Include="IlmImf\ImfInputPart.cpp" />
+    <ClCompile Include="IlmImf\ImfInputPartData.cpp" />
+    <ClCompile Include="IlmImf\ImfIntAttribute.cpp" />
+    <ClCompile Include="IlmImf\ImfIO.cpp" />
+    <ClCompile Include="IlmImf\ImfKeyCode.cpp" />
+    <ClCompile Include="IlmImf\ImfKeyCodeAttribute.cpp" />
+    <ClCompile Include="IlmImf\ImfLineOrderAttribute.cpp" />
+    <ClCompile Include="IlmImf\ImfLut.cpp" />
+    <ClCompile Include="IlmImf\ImfMatrixAttribute.cpp" />
+    <ClCompile Include="IlmImf\ImfMisc.cpp" />
+    <ClCompile Include="IlmImf\ImfMultiPartInputFile.cpp" />
+    <ClCompile Include="IlmImf\ImfMultiPartOutputFile.cpp" />
+    <ClCompile Include="IlmImf\ImfMultiView.cpp" />
+    <ClCompile Include="IlmImf\ImfOpaqueAttribute.cpp" />
+    <ClCompile Include="IlmImf\ImfOutputFile.cpp" />
+    <ClCompile Include="IlmImf\ImfOutputPart.cpp" />
+    <ClCompile Include="IlmImf\ImfOutputPartData.cpp" />
+    <ClCompile Include="IlmImf\ImfPartType.cpp" />
+    <ClCompile Include="IlmImf\ImfPizCompressor.cpp" />
+    <ClCompile Include="IlmImf\ImfPreviewImage.cpp" />
+    <ClCompile Include="IlmImf\ImfPreviewImageAttribute.cpp" />
+    <ClCompile Include="IlmImf\ImfPxr24Compressor.cpp" />
+    <ClCompile Include="IlmImf\ImfRational.cpp" />
+    <ClCompile Include="IlmImf\ImfRationalAttribute.cpp" />
+    <ClCompile Include="IlmImf\ImfRgbaFile.cpp" />
+    <ClCompile Include="IlmImf\ImfRgbaYca.cpp" />
+    <ClCompile Include="IlmImf\ImfRle.cpp" />
+    <ClCompile Include="IlmImf\ImfRleCompressor.cpp" />
+    <ClCompile Include="IlmImf\ImfScanLineInputFile.cpp" />
+    <ClCompile Include="IlmImf\ImfStandardAttributes.cpp" />
+    <ClCompile Include="IlmImf\ImfStdIO.cpp" />
+    <ClCompile Include="IlmImf\ImfStringAttribute.cpp" />
+    <ClCompile Include="IlmImf\ImfStringVectorAttribute.cpp" />
+    <ClCompile Include="IlmImf\ImfSystemSpecific.cpp" />
+    <ClCompile Include="IlmImf\ImfTestFile.cpp" />
+    <ClCompile Include="IlmImf\ImfThreading.cpp" />
+    <ClCompile Include="IlmImf\ImfTileDescriptionAttribute.cpp" />
+    <ClCompile Include="IlmImf\ImfTiledInputFile.cpp" />
+    <ClCompile Include="IlmImf\ImfTiledInputPart.cpp" />
+    <ClCompile Include="IlmImf\ImfTiledMisc.cpp" />
+    <ClCompile Include="IlmImf\ImfTiledOutputFile.cpp" />
+    <ClCompile Include="IlmImf\ImfTiledOutputPart.cpp" />
+    <ClCompile Include="IlmImf\ImfTiledRgbaFile.cpp" />
+    <ClCompile Include="IlmImf\ImfTileOffsets.cpp" />
+    <ClCompile Include="IlmImf\ImfTimeCode.cpp" />
+    <ClCompile Include="IlmImf\ImfTimeCodeAttribute.cpp" />
+    <ClCompile Include="IlmImf\ImfVecAttribute.cpp" />
+    <ClCompile Include="IlmImf\ImfVersion.cpp" />
+    <ClCompile Include="IlmImf\ImfWav.cpp" />
+    <ClCompile Include="IlmImf\ImfZip.cpp" />
+    <ClCompile Include="IlmImf\ImfZipCompressor.cpp" />
+    <ClCompile Include="Imath\ImathBox.cpp" />
+    <ClCompile Include="Imath\ImathColorAlgo.cpp" />
+    <ClCompile Include="Imath\ImathFun.cpp" />
+    <ClCompile Include="Imath\ImathMatrixAlgo.cpp" />
+    <ClCompile Include="Imath\ImathRandom.cpp" />
+    <ClCompile Include="Imath\ImathShear.cpp" />
+    <ClCompile Include="Imath\ImathVec.cpp" />
+    <ClCompile Include="Iex\IexBaseExc.cpp" />
+    <ClCompile Include="Iex\IexThrowErrnoExc.cpp" />
+    <ClCompile Include="Half\half.cpp" />
+    <ClCompile Include="IlmThread\IlmThread.cpp" />
+    <ClCompile Include="IlmThread\IlmThreadMutex.cpp" />
+    <ClCompile Include="IlmThread\IlmThreadPool.cpp" />
+    <ClCompile Include="IlmThread\IlmThreadSemaphore.cpp" />
+    <ClCompile Include="IexMath\IexMathFloatExc.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="IlmBaseConfig.h" />
+    <ClInclude Include="OpenEXRConfig.h" />
+    <ClInclude Include="IlmImf\b44ExpLogTable.h" />
+    <ClInclude Include="IlmImf\dwaLookups.h" />
+    <ClInclude Include="IlmImf\ImfAcesFile.h" />
+    <ClInclude Include="IlmImf\ImfArray.h" />
+    <ClInclude Include="IlmImf\ImfAttribute.h" />
+    <ClInclude Include="IlmImf\ImfAutoArray.h" />
+    <ClInclude Include="IlmImf\ImfB44Compressor.h" />
+    <ClInclude Include="IlmImf\ImfBoxAttribute.h" />
+    <ClInclude Include="IlmImf\ImfChannelList.h" />
+    <ClInclude Include="IlmImf\ImfChannelListAttribute.h" />
+    <ClInclude Include="IlmImf\ImfCheckedArithmetic.h" />
+    <ClInclude Include="IlmImf\ImfChromaticities.h" />
+    <ClInclude Include="IlmImf\ImfChromaticitiesAttribute.h" />
+    <ClInclude Include="IlmImf\ImfCompositeDeepScanLine.h" />
+    <ClInclude Include="IlmImf\ImfCompression.h" />
+    <ClInclude Include="IlmImf\ImfCompressionAttribute.h" />
+    <ClInclude Include="IlmImf\ImfCompressor.h" />
+    <ClInclude Include="IlmImf\ImfConvert.h" />
+    <ClInclude Include="IlmImf\ImfCRgbaFile.h" />
+    <ClInclude Include="IlmImf\ImfDeepCompositing.h" />
+    <ClInclude Include="IlmImf\ImfDeepFrameBuffer.h" />
+    <ClInclude Include="IlmImf\ImfDeepImageState.h" />
+    <ClInclude Include="IlmImf\ImfDeepImageStateAttribute.h" />
+    <ClInclude Include="IlmImf\ImfDeepScanLineInputFile.h" />
+    <ClInclude Include="IlmImf\ImfDeepScanLineInputPart.h" />
+    <ClInclude Include="IlmImf\ImfDeepScanLineOutputFile.h" />
+    <ClInclude Include="IlmImf\ImfDeepScanLineOutputPart.h" />
+    <ClInclude Include="IlmImf\ImfDeepTiledInputFile.h" />
+    <ClInclude Include="IlmImf\ImfDeepTiledInputPart.h" />
+    <ClInclude Include="IlmImf\ImfDeepTiledOutputFile.h" />
+    <ClInclude Include="IlmImf\ImfDeepTiledOutputPart.h" />
+    <ClInclude Include="IlmImf\ImfDoubleAttribute.h" />
+    <ClInclude Include="IlmImf\ImfDwaCompressor.h" />
+    <ClInclude Include="IlmImf\ImfDwaCompressorSimd.h" />
+    <ClInclude Include="IlmImf\ImfEnvmap.h" />
+    <ClInclude Include="IlmImf\ImfEnvmapAttribute.h" />
+    <ClInclude Include="IlmImf\ImfExport.h" />
+    <ClInclude Include="IlmImf\ImfFastHuf.h" />
+    <ClInclude Include="IlmImf\ImfFloatAttribute.h" />
+    <ClInclude Include="IlmImf\ImfFloatVectorAttribute.h" />
+    <ClInclude Include="IlmImf\ImfForward.h" />
+    <ClInclude Include="IlmImf\ImfFrameBuffer.h" />
+    <ClInclude Include="IlmImf\ImfFramesPerSecond.h" />
+    <ClInclude Include="IlmImf\ImfGenericInputFile.h" />
+    <ClInclude Include="IlmImf\ImfGenericOutputFile.h" />
+    <ClInclude Include="IlmImf\ImfHeader.h" />
+    <ClInclude Include="IlmImf\ImfHuf.h" />
+    <ClInclude Include="IlmImf\ImfInputFile.h" />
+    <ClInclude Include="IlmImf\ImfInputPart.h" />
+    <ClInclude Include="IlmImf\ImfInputPartData.h" />
+    <ClInclude Include="IlmImf\ImfInputStreamMutex.h" />
+    <ClInclude Include="IlmImf\ImfInt64.h" />
+    <ClInclude Include="IlmImf\ImfIntAttribute.h" />
+    <ClInclude Include="IlmImf\ImfIO.h" />
+    <ClInclude Include="IlmImf\ImfKeyCode.h" />
+    <ClInclude Include="IlmImf\ImfKeyCodeAttribute.h" />
+    <ClInclude Include="IlmImf\ImfLineOrder.h" />
+    <ClInclude Include="IlmImf\ImfLineOrderAttribute.h" />
+    <ClInclude Include="IlmImf\ImfLut.h" />
+    <ClInclude Include="IlmImf\ImfMatrixAttribute.h" />
+    <ClInclude Include="IlmImf\ImfMisc.h" />
+    <ClInclude Include="IlmImf\ImfMultiPartInputFile.h" />
+    <ClInclude Include="IlmImf\ImfMultiPartOutputFile.h" />
+    <ClInclude Include="IlmImf\ImfMultiView.h" />
+    <ClInclude Include="IlmImf\ImfName.h" />
+    <ClInclude Include="IlmImf\ImfNamespace.h" />
+    <ClInclude Include="IlmImf\ImfOpaqueAttribute.h" />
+    <ClInclude Include="IlmImf\ImfOptimizedPixelReading.h" />
+    <ClInclude Include="IlmImf\ImfOutputFile.h" />
+    <ClInclude Include="IlmImf\ImfOutputPart.h" />
+    <ClInclude Include="IlmImf\ImfOutputPartData.h" />
+    <ClInclude Include="IlmImf\ImfOutputStreamMutex.h" />
+    <ClInclude Include="IlmImf\ImfPartHelper.h" />
+    <ClInclude Include="IlmImf\ImfPartType.h" />
+    <ClInclude Include="IlmImf\ImfPixelType.h" />
+    <ClInclude Include="IlmImf\ImfPizCompressor.h" />
+    <ClInclude Include="IlmImf\ImfPreviewImage.h" />
+    <ClInclude Include="IlmImf\ImfPreviewImageAttribute.h" />
+    <ClInclude Include="IlmImf\ImfPxr24Compressor.h" />
+    <ClInclude Include="IlmImf\ImfRational.h" />
+    <ClInclude Include="IlmImf\ImfRationalAttribute.h" />
+    <ClInclude Include="IlmImf\ImfRgba.h" />
+    <ClInclude Include="IlmImf\ImfRgbaFile.h" />
+    <ClInclude Include="IlmImf\ImfRgbaYca.h" />
+    <ClInclude Include="IlmImf\ImfRle.h" />
+    <ClInclude Include="IlmImf\ImfRleCompressor.h" />
+    <ClInclude Include="IlmImf\ImfScanLineInputFile.h" />
+    <ClInclude Include="IlmImf\ImfSimd.h" />
+    <ClInclude Include="IlmImf\ImfStandardAttributes.h" />
+    <ClInclude Include="IlmImf\ImfStdIO.h" />
+    <ClInclude Include="IlmImf\ImfStringAttribute.h" />
+    <ClInclude Include="IlmImf\ImfStringVectorAttribute.h" />
+    <ClInclude Include="IlmImf\ImfSystemSpecific.h" />
+    <ClInclude Include="IlmImf\ImfTestFile.h" />
+    <ClInclude Include="IlmImf\ImfThreading.h" />
+    <ClInclude Include="IlmImf\ImfTileDescription.h" />
+    <ClInclude Include="IlmImf\ImfTileDescriptionAttribute.h" />
+    <ClInclude Include="IlmImf\ImfTiledInputFile.h" />
+    <ClInclude Include="IlmImf\ImfTiledInputPart.h" />
+    <ClInclude Include="IlmImf\ImfTiledMisc.h" />
+    <ClInclude Include="IlmImf\ImfTiledOutputFile.h" />
+    <ClInclude Include="IlmImf\ImfTiledOutputPart.h" />
+    <ClInclude Include="IlmImf\ImfTiledRgbaFile.h" />
+    <ClInclude Include="IlmImf\ImfTileOffsets.h" />
+    <ClInclude Include="IlmImf\ImfTimeCode.h" />
+    <ClInclude Include="IlmImf\ImfTimeCodeAttribute.h" />
+    <ClInclude Include="IlmImf\ImfVecAttribute.h" />
+    <ClInclude Include="IlmImf\ImfVersion.h" />
+    <ClInclude Include="IlmImf\ImfWav.h" />
+    <ClInclude Include="IlmImf\ImfXdr.h" />
+    <ClInclude Include="IlmImf\ImfZip.h" />
+    <ClInclude Include="IlmImf\ImfZipCompressor.h" />
+    <ClInclude Include="Imath\ImathBox.h" />
+    <ClInclude Include="Imath\ImathBoxAlgo.h" />
+    <ClInclude Include="Imath\ImathColor.h" />
+    <ClInclude Include="Imath\ImathColorAlgo.h" />
+    <ClInclude Include="Imath\ImathEuler.h" />
+    <ClInclude Include="Imath\ImathExc.h" />
+    <ClInclude Include="Imath\ImathExport.h" />
+    <ClInclude Include="Imath\ImathForward.h" />
+    <ClInclude Include="Imath\ImathFrame.h" />
+    <ClInclude Include="Imath\ImathFrustum.h" />
+    <ClInclude Include="Imath\ImathFrustumTest.h" />
+    <ClInclude Include="Imath\ImathFun.h" />
+    <ClInclude Include="Imath\ImathGL.h" />
+    <ClInclude Include="Imath\ImathGLU.h" />
+    <ClInclude Include="Imath\ImathHalfLimits.h" />
+    <ClInclude Include="Imath\ImathInt64.h" />
+    <ClInclude Include="Imath\ImathInterval.h" />
+    <ClInclude Include="Imath\ImathLimits.h" />
+    <ClInclude Include="Imath\ImathLine.h" />
+    <ClInclude Include="Imath\ImathLineAlgo.h" />
+    <ClInclude Include="Imath\ImathMath.h" />
+    <ClInclude Include="Imath\ImathMatrix.h" />
+    <ClInclude Include="Imath\ImathMatrixAlgo.h" />
+    <ClInclude Include="Imath\ImathNamespace.h" />
+    <ClInclude Include="Imath\ImathPlane.h" />
+    <ClInclude Include="Imath\ImathPlatform.h" />
+    <ClInclude Include="Imath\ImathQuat.h" />
+    <ClInclude Include="Imath\ImathRandom.h" />
+    <ClInclude Include="Imath\ImathRoots.h" />
+    <ClInclude Include="Imath\ImathShear.h" />
+    <ClInclude Include="Imath\ImathSphere.h" />
+    <ClInclude Include="Imath\ImathVec.h" />
+    <ClInclude Include="Imath\ImathVecAlgo.h" />
+    <ClInclude Include="Iex\Iex.h" />
+    <ClInclude Include="Iex\IexBaseExc.h" />
+    <ClInclude Include="Iex\IexErrnoExc.h" />
+    <ClInclude Include="Iex\IexExport.h" />
+    <ClInclude Include="Iex\IexForward.h" />
+    <ClInclude Include="Iex\IexMacros.h" />
+    <ClInclude Include="Iex\IexMathExc.h" />
+    <ClInclude Include="Iex\IexNamespace.h" />
+    <ClInclude Include="Iex\IexThrowErrnoExc.h" />
+    <ClInclude Include="Half\eLut.h" />
+    <ClInclude Include="Half\half.h" />
+    <ClInclude Include="Half\halfFunction.h" />
+    <ClInclude Include="Half\halfLimits.h" />
+    <ClInclude Include="Half\toFloat.h" />
+    <ClInclude Include="IlmThread\IlmThread.h" />
+    <ClInclude Include="IlmThread\IlmThreadExport.h" />
+    <ClInclude Include="IlmThread\IlmThreadForward.h" />
+    <ClInclude Include="IlmThread\IlmThreadMutex.h" />
+    <ClInclude Include="IlmThread\IlmThreadNamespace.h" />
+    <ClInclude Include="IlmThread\IlmThreadPool.h" />
+    <ClInclude Include="IlmThread\IlmThreadSemaphore.h" />
+    <ClInclude Include="IexMath\IexMathFloatExc.h" />
+    <ClInclude Include="IexMath\IexMathIeeeExc.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\ZLib\ZLib.2013.vcxproj">
+      <Project>{33134f61-c1ad-4b6f-9cea-503a9f140c52}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/Source/OpenEXR/OpenEXR.2013.vcxproj.filters b/Source/OpenEXR/OpenEXR.2013.vcxproj.filters
new file mode 100644
index 0000000..b96d63f
--- /dev/null
+++ b/Source/OpenEXR/OpenEXR.2013.vcxproj.filters
@@ -0,0 +1,889 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{3ae95f1e-e03d-43b1-9656-4944aa6e5e8a}</UniqueIdentifier>
+      <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
+    </Filter>
+    <Filter Include="Source Files\IlmImf Source Files">
+      <UniqueIdentifier>{23fe3e9c-c23d-4bea-a6b2-544307f246c9}</UniqueIdentifier>
+      <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
+    </Filter>
+    <Filter Include="Source Files\Imath Source Files">
+      <UniqueIdentifier>{f0279cc2-1c62-4be4-a7d8-bfa5e405ad91}</UniqueIdentifier>
+      <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
+    </Filter>
+    <Filter Include="Source Files\Iex Source Files">
+      <UniqueIdentifier>{bf2e76a7-04e4-4042-be03-7ab100fe2a2c}</UniqueIdentifier>
+      <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
+    </Filter>
+    <Filter Include="Source Files\Half Source Files">
+      <UniqueIdentifier>{9c661ac1-2c87-4f5e-a45d-76ab76842775}</UniqueIdentifier>
+      <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
+    </Filter>
+    <Filter Include="Source Files\IlmThread Source Files">
+      <UniqueIdentifier>{5968a30f-0820-4196-955e-4580044a3cf9}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\IexMath Source Files">
+      <UniqueIdentifier>{542dccc2-e018-453d-b903-8a8ef8005749}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{90ef9c88-bf45-47bb-a4a8-68764ac65242}</UniqueIdentifier>
+      <Extensions>h;hpp;hxx;hm;inl</Extensions>
+    </Filter>
+    <Filter Include="Header Files\IlmImf Header Files">
+      <UniqueIdentifier>{bd459e90-3dae-4b9b-b5cb-76d2407c0908}</UniqueIdentifier>
+      <Extensions>h;hpp;hxx;hm;inl</Extensions>
+    </Filter>
+    <Filter Include="Header Files\Imath Header Files">
+      <UniqueIdentifier>{73a0c0a2-98d5-4aa3-9486-46a9e39ab826}</UniqueIdentifier>
+      <Extensions>h;hpp;hxx;hm;inl</Extensions>
+    </Filter>
+    <Filter Include="Header Files\Iex Header Files">
+      <UniqueIdentifier>{2d41389f-a810-4b64-9cbc-279f170f260d}</UniqueIdentifier>
+      <Extensions>h;hpp;hxx;hm;inl</Extensions>
+    </Filter>
+    <Filter Include="Header Files\Half Header Files">
+      <UniqueIdentifier>{19acba37-c638-48b6-9679-24a98411ab1d}</UniqueIdentifier>
+      <Extensions>h;hpp;hxx;hm;inl</Extensions>
+    </Filter>
+    <Filter Include="Header Files\IlmThread Header Files">
+      <UniqueIdentifier>{3f37cb3e-6374-4d66-a36b-f31de14b3b78}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\IexMath Header Files">
+      <UniqueIdentifier>{c43ac413-feb4-49c6-8907-fcc20948ed0a}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="IlmImf\b44ExpLogTable.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfAcesFile.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfAttribute.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfB44Compressor.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfBoxAttribute.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfChannelList.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfChannelListAttribute.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfChromaticities.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfChromaticitiesAttribute.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfCompositeDeepScanLine.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfCompressionAttribute.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfCompressor.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfConvert.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfCRgbaFile.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfDeepCompositing.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfDeepFrameBuffer.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfDeepImageStateAttribute.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfDeepScanLineInputFile.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfDeepScanLineInputPart.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfDeepScanLineOutputFile.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfDeepScanLineOutputPart.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfDeepTiledInputFile.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfDeepTiledInputPart.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfDeepTiledOutputFile.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfDeepTiledOutputPart.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfDoubleAttribute.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfDwaCompressor.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfEnvmap.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfEnvmapAttribute.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfFastHuf.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfFloatAttribute.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfFloatVectorAttribute.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfFrameBuffer.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfFramesPerSecond.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfGenericInputFile.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfGenericOutputFile.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfHeader.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfHuf.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfInputFile.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfInputPart.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfInputPartData.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfIntAttribute.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfIO.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfKeyCode.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfKeyCodeAttribute.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfLineOrderAttribute.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfLut.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfMatrixAttribute.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfMisc.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfMultiPartInputFile.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfMultiPartOutputFile.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfMultiView.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfOpaqueAttribute.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfOutputFile.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfOutputPart.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfOutputPartData.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfPartType.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfPizCompressor.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfPreviewImage.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfPreviewImageAttribute.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfPxr24Compressor.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfRational.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfRationalAttribute.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfRgbaFile.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfRgbaYca.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfRle.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfRleCompressor.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfScanLineInputFile.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfStandardAttributes.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfStdIO.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfStringAttribute.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfStringVectorAttribute.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfSystemSpecific.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfTestFile.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfThreading.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfTileDescriptionAttribute.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfTiledInputFile.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfTiledInputPart.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfTiledMisc.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfTiledOutputFile.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfTiledOutputPart.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfTiledRgbaFile.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfTileOffsets.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfTimeCode.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfTimeCodeAttribute.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfVecAttribute.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfVersion.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfWav.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfZip.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmImf\ImfZipCompressor.cpp">
+      <Filter>Source Files\IlmImf Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Imath\ImathBox.cpp">
+      <Filter>Source Files\Imath Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Imath\ImathColorAlgo.cpp">
+      <Filter>Source Files\Imath Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Imath\ImathFun.cpp">
+      <Filter>Source Files\Imath Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Imath\ImathMatrixAlgo.cpp">
+      <Filter>Source Files\Imath Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Imath\ImathRandom.cpp">
+      <Filter>Source Files\Imath Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Imath\ImathShear.cpp">
+      <Filter>Source Files\Imath Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Imath\ImathVec.cpp">
+      <Filter>Source Files\Imath Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Iex\IexBaseExc.cpp">
+      <Filter>Source Files\Iex Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Iex\IexThrowErrnoExc.cpp">
+      <Filter>Source Files\Iex Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Half\half.cpp">
+      <Filter>Source Files\Half Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmThread\IlmThread.cpp">
+      <Filter>Source Files\IlmThread Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmThread\IlmThreadMutex.cpp">
+      <Filter>Source Files\IlmThread Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmThread\IlmThreadPool.cpp">
+      <Filter>Source Files\IlmThread Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IlmThread\IlmThreadSemaphore.cpp">
+      <Filter>Source Files\IlmThread Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IexMath\IexMathFloatExc.cpp">
+      <Filter>Source Files\IexMath Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="IexMath\IexMathFpu.cpp">
+      <Filter>Source Files\IexMath Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="IlmBaseConfig.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="OpenEXRConfig.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\b44ExpLogTable.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\dwaLookups.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfAcesFile.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfArray.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfAttribute.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfAutoArray.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfB44Compressor.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfBoxAttribute.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfChannelList.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfChannelListAttribute.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfCheckedArithmetic.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfChromaticities.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfChromaticitiesAttribute.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfCompositeDeepScanLine.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfCompression.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfCompressionAttribute.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfCompressor.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfConvert.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfCRgbaFile.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfDeepCompositing.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfDeepFrameBuffer.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfDeepImageState.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfDeepImageStateAttribute.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfDeepScanLineInputFile.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfDeepScanLineInputPart.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfDeepScanLineOutputFile.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfDeepScanLineOutputPart.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfDeepTiledInputFile.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfDeepTiledInputPart.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfDeepTiledOutputFile.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfDeepTiledOutputPart.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfDoubleAttribute.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfDwaCompressor.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfDwaCompressorSimd.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfEnvmap.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfEnvmapAttribute.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfExport.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfFastHuf.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfFloatAttribute.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfFloatVectorAttribute.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfForward.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfFrameBuffer.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfFramesPerSecond.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfGenericInputFile.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfGenericOutputFile.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfHeader.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfHuf.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfInputFile.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfInputPart.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfInputPartData.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfInputStreamMutex.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfInt64.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfIntAttribute.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfIO.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfKeyCode.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfKeyCodeAttribute.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfLineOrder.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfLineOrderAttribute.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfLut.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfMatrixAttribute.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfMisc.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfMultiPartInputFile.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfMultiPartOutputFile.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfMultiView.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfName.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfNamespace.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfOpaqueAttribute.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfOptimizedPixelReading.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfOutputFile.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfOutputPart.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfOutputPartData.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfOutputStreamMutex.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfPartHelper.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfPartType.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfPixelType.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfPizCompressor.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfPreviewImage.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfPreviewImageAttribute.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfPxr24Compressor.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfRational.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfRationalAttribute.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfRgba.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfRgbaFile.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfRgbaYca.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfRle.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfRleCompressor.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfScanLineInputFile.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfSimd.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfStandardAttributes.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfStdIO.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfStringAttribute.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfStringVectorAttribute.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfSystemSpecific.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfTestFile.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfThreading.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfTileDescription.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfTileDescriptionAttribute.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfTiledInputFile.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfTiledInputPart.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfTiledMisc.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfTiledOutputFile.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfTiledOutputPart.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfTiledRgbaFile.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfTileOffsets.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfTimeCode.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfTimeCodeAttribute.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfVecAttribute.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfVersion.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfWav.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfXdr.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfZip.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmImf\ImfZipCompressor.h">
+      <Filter>Header Files\IlmImf Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Imath\ImathBox.h">
+      <Filter>Header Files\Imath Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Imath\ImathBoxAlgo.h">
+      <Filter>Header Files\Imath Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Imath\ImathColor.h">
+      <Filter>Header Files\Imath Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Imath\ImathColorAlgo.h">
+      <Filter>Header Files\Imath Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Imath\ImathEuler.h">
+      <Filter>Header Files\Imath Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Imath\ImathExc.h">
+      <Filter>Header Files\Imath Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Imath\ImathExport.h">
+      <Filter>Header Files\Imath Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Imath\ImathForward.h">
+      <Filter>Header Files\Imath Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Imath\ImathFrame.h">
+      <Filter>Header Files\Imath Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Imath\ImathFrustum.h">
+      <Filter>Header Files\Imath Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Imath\ImathFrustumTest.h">
+      <Filter>Header Files\Imath Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Imath\ImathFun.h">
+      <Filter>Header Files\Imath Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Imath\ImathGL.h">
+      <Filter>Header Files\Imath Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Imath\ImathGLU.h">
+      <Filter>Header Files\Imath Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Imath\ImathHalfLimits.h">
+      <Filter>Header Files\Imath Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Imath\ImathInt64.h">
+      <Filter>Header Files\Imath Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Imath\ImathInterval.h">
+      <Filter>Header Files\Imath Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Imath\ImathLimits.h">
+      <Filter>Header Files\Imath Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Imath\ImathLine.h">
+      <Filter>Header Files\Imath Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Imath\ImathLineAlgo.h">
+      <Filter>Header Files\Imath Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Imath\ImathMath.h">
+      <Filter>Header Files\Imath Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Imath\ImathMatrix.h">
+      <Filter>Header Files\Imath Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Imath\ImathMatrixAlgo.h">
+      <Filter>Header Files\Imath Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Imath\ImathNamespace.h">
+      <Filter>Header Files\Imath Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Imath\ImathPlane.h">
+      <Filter>Header Files\Imath Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Imath\ImathPlatform.h">
+      <Filter>Header Files\Imath Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Imath\ImathQuat.h">
+      <Filter>Header Files\Imath Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Imath\ImathRandom.h">
+      <Filter>Header Files\Imath Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Imath\ImathRoots.h">
+      <Filter>Header Files\Imath Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Imath\ImathShear.h">
+      <Filter>Header Files\Imath Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Imath\ImathSphere.h">
+      <Filter>Header Files\Imath Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Imath\ImathVec.h">
+      <Filter>Header Files\Imath Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Imath\ImathVecAlgo.h">
+      <Filter>Header Files\Imath Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Iex\Iex.h">
+      <Filter>Header Files\Iex Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Iex\IexBaseExc.h">
+      <Filter>Header Files\Iex Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Iex\IexErrnoExc.h">
+      <Filter>Header Files\Iex Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Iex\IexExport.h">
+      <Filter>Header Files\Iex Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Iex\IexForward.h">
+      <Filter>Header Files\Iex Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Iex\IexMacros.h">
+      <Filter>Header Files\Iex Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Iex\IexMathExc.h">
+      <Filter>Header Files\Iex Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Iex\IexNamespace.h">
+      <Filter>Header Files\Iex Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Iex\IexThrowErrnoExc.h">
+      <Filter>Header Files\Iex Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Half\eLut.h">
+      <Filter>Header Files\Half Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Half\half.h">
+      <Filter>Header Files\Half Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Half\halfFunction.h">
+      <Filter>Header Files\Half Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Half\halfLimits.h">
+      <Filter>Header Files\Half Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Half\toFloat.h">
+      <Filter>Header Files\Half Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmThread\IlmThread.h">
+      <Filter>Header Files\IlmThread Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmThread\IlmThreadExport.h">
+      <Filter>Header Files\IlmThread Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmThread\IlmThreadForward.h">
+      <Filter>Header Files\IlmThread Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmThread\IlmThreadMutex.h">
+      <Filter>Header Files\IlmThread Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmThread\IlmThreadNamespace.h">
+      <Filter>Header Files\IlmThread Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmThread\IlmThreadPool.h">
+      <Filter>Header Files\IlmThread Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IlmThread\IlmThreadSemaphore.h">
+      <Filter>Header Files\IlmThread Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IexMath\IexMathFloatExc.h">
+      <Filter>Header Files\IexMath Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IexMath\IexMathIeeeExc.h">
+      <Filter>Header Files\IexMath Header Files</Filter>
+    </ClInclude>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/Source/OpenEXR/OpenEXRConfig.h b/Source/OpenEXR/OpenEXRConfig.h
index cc8bb9d..5455600 100644
--- a/Source/OpenEXR/OpenEXRConfig.h
+++ b/Source/OpenEXR/OpenEXRConfig.h
@@ -1,46 +1,72 @@
 //
-// Define and set to 1 if the target system has POSIX thread support
-// and you want OpenEXR to use it for multithreaded file I/O.
+// Define and set to 1 if the target system supports a proc filesystem
+// compatible with the Linux kernel's proc filesystem.  Note that this
+// is only used by a program in the IlmImfTest test suite, it's not
+// used by any OpenEXR library or application code.
 //
 
-#undef HAVE_PTHREAD		// currently disabled in FreeImage
+#undef OPENEXR_IMF_HAVE_LINUX_PROCFS
 
 //
-// Define and set to 1 if the target system supports POSIX semaphores
-// and you want OpenEXR to use them; otherwise, OpenEXR will use its
-// own semaphore implementation.
+// Define and set to 1 if the target system is a Darwin-based system
+// (e.g., OS X).
 //
 
-#undef HAVE_POSIX_SEMAPHORES
+/* #undef OPENEXR_IMF_HAVE_DARWIN */
 
 //
-// Define and set to 1 if the target system is a Darwin-based system
-// (e.g., OS X).
+// Define and set to 1 if the target system has a complete <iomanip>
+// implementation, specifically if it supports the std::right
+// formatter.
 //
 
-#undef HAVE_DARWIN
+#define OPENEXR_IMF_HAVE_COMPLETE_IOMANIP 1
 
 //
-// Define and set to 1 if the target system supports a proc filesystem
-// compatible with the Linux kernel's proc filesystem.  Note that this
-// is only used by a program in the IlmImfTest test suite, it's not
-// used by any OpenEXR library or application code.
+// Define and set to 1 if the target system has support for large
+// stack sizes.
 //
 
-#undef HAVE_LINUX_PROCFS
+#define OPENEXR_IMF_HAVE_LARGE_STACK 1
 
 //
-// Define and set to 1 if the target system includes the NVIDIA Cg
-// runtime.  The exrdisplay program will use a fragment shader to
-// accelerate the display of OpenEXR images.
+// Define if we can support GCC style inline asm with AVX instructions
 //
 
-#undef HAVE_FRAGMENT_SHADERS
+#undef OPENEXR_IMF_HAVE_GCC_INLINE_ASM_AVX
 
 //
-// Define and set to 1 if the target system has a complete <iomanip>
-// implementation, specifically if it supports the std::right
-// formatter.
+// Define if we can use sysconf(_SC_NPROCESSORS_ONLN) to get CPU count
+//
+
+#undef OPENEXR_IMF_HAVE_SYSCONF_NPROCESSORS_ONLN
+
+//
+// Current internal library namepace name
+//
+#define OPENEXR_IMF_INTERNAL_NAMESPACE_CUSTOM 1
+#define OPENEXR_IMF_INTERNAL_NAMESPACE Imf_2_2
+
 //
+// Current public user namepace name
+//
+
+/* #undef OPENEXR_IMF_NAMESPACE_CUSTOM */
+#define OPENEXR_IMF_NAMESPACE Imf
+
+//
+// Version string for runtime access
+//
+
+#define OPENEXR_VERSION_STRING "2.2.0"
+#define OPENEXR_PACKAGE_STRING "OpenEXR 2.2.0"
+
+#define OPENEXR_VERSION_MAJOR 2
+#define OPENEXR_VERSION_MINOR 2
+#define OPENEXR_VERSION_PATCH 0
+
+// Version as a single hex number, e.g. 0x01000300 == 1.0.3
+#define OPENEXR_VERSION_HEX ((OPENEXR_VERSION_MAJOR << 24) | \
+                             (OPENEXR_VERSION_MINOR << 16) | \
+                             (OPENEXR_VERSION_PATCH <<  8))
 
-#undef HAVE_COMPLETE_IOMANIP
diff --git a/Source/Plugin.h b/Source/Plugin.h
index dbb4540..76ffc90 100644
--- a/Source/Plugin.h
+++ b/Source/Plugin.h
@@ -138,5 +138,7 @@ void DLL_CALLCONV InitPFM(Plugin *plugin, int format_id);
 void DLL_CALLCONV InitPICT(Plugin *plugin, int format_id);
 void DLL_CALLCONV InitRAW(Plugin *plugin, int format_id);
 void DLL_CALLCONV InitJNG(Plugin *plugin, int format_id);
+void DLL_CALLCONV InitWEBP(Plugin *plugin, int format_id);
+void DLL_CALLCONV InitJXR(Plugin *plugin, int format_id);
 
 #endif //!PLUGIN_H
diff --git a/Source/Quantizers.h b/Source/Quantizers.h
index 2a671fa..3db12d3 100644
--- a/Source/Quantizers.h
+++ b/Source/Quantizers.h
@@ -3,6 +3,7 @@
 //
 // Design and implementation by:
 // - Herv� Drolon <drolon at infonie.fr>
+// - Carsten Klein (cklein05 at users.sourceforge.net)
 //
 // This file is part of FreeImage 3
 //
@@ -223,3 +224,131 @@ public:
 
 };
 
+/**
+ * LFPQUANT - Lossless Fast Pseudo-Quantization Algorithm
+ *
+ * The Lossless Fast Pseudo-Quantization algorithm is no real quantization
+ * algorithm, since it makes no attempt to create a palette, that is suitable
+ * for all colors of the 24-bit source image. However, it provides very fast
+ * conversions from 24-bit to 8-bit images, if the number of distinct colors
+ * in the source image is not greater than the desired palette size. If the
+ * number of colors in the source image is exceeded, the Quantize method of
+ * this implementation stops the process and returns NULL.
+ *
+ * This implementation uses a very fast hash map implementation to collect
+ * the source image's colors. It turned out that a customized implementation
+ * of a hash table with open addressing (using linear probing) provides the
+ * best performance. The hash table has 512 entries, which prevents the load
+ * factor to exceed 0.5 as we have 256 entries at most. Each entry consumes
+ * 64 bits, so the whole hash table takes 4KB of memory.
+ *
+ * For large images, the LFPQuantizer is typically up to three times faster
+ * than the WuQuantizer.
+ */
+class LFPQuantizer {
+public:
+	/** Constructor */
+	LFPQuantizer(unsigned PaletteSize);
+
+	/** Destructor */
+	~LFPQuantizer();
+
+	/**
+	 * Quantizer
+	 * @param dib input 24-bit or 32-bit bitmap to be quantized
+	 * @return returns the pseudo-quantized 8-bit bitmap
+	 */
+	FIBITMAP* Quantize(FIBITMAP *dib, int ReserveSize, RGBQUAD *ReservePalette);
+
+protected:
+	/** The maximum size of a palette. */
+	static const unsigned MAX_SIZE = 256;
+
+	/**
+	 * The size of the hash table. Must be a power of 2. By sizing it
+	 * MAX_SIZE * 2, we ensure the load factor not to exceed 0.5 at any
+	 * time, since we will have MAX_SIZE entries at most.
+	 */
+	static const unsigned MAP_SIZE = MAX_SIZE * 2;
+
+	/**
+	 * With open addressing we need a special value for empty buckets.
+	 * Both entry.color and entry.index are 0xFFFFFFFF for an empty
+	 * entry.
+	 */
+	static const unsigned EMPTY_BUCKET = 0xFFFFFFFF;
+
+	/**
+	 * This structure defines a single entry in the hash table. We use
+	 * color as the entry's key.
+	 */
+	typedef struct MapEntry {
+		unsigned color;
+		unsigned index;
+	} MapEntry;
+
+	/** The hash table. */
+	MapEntry *m_map;
+
+	/**
+	 * The current size of the newly created palette. Since the provided
+	 * reserve palette could contain duplicates, this is not necessarily
+	 * the number of entries in the hash table. Initialized to zero.
+	 */
+	unsigned m_size;
+
+	/**
+	 * The desired maximum number of entries in the newly created palette.
+	 * If m_size exceeds this value, the palette is full and the
+	 * quantization process is stopped. Initialized to the desired
+	 * palette size.
+	 */
+	unsigned m_limit;
+
+	/**
+	 *  The palette index used for the next color added. Initialized to
+	 *  zero (the reserve palette is put to the end of the palette).
+	 */
+	unsigned m_index;
+
+	/**
+	 * Ensures that hash codes that differ only by constant multiples
+	 * at each bit position have a bounded number of collisions.
+	 * @param h the initial (aka raw) hash code
+	 * @return the modified hash code
+	 */
+	static inline unsigned hash(unsigned h) {
+		h ^= (h >> 20) ^ (h >> 12);
+		return h ^ (h >> 7) ^ (h >> 4);
+	}
+
+	/**
+	 * Returns the palette index of the specified color. Tries to put the
+	 * color into the map, if it's not already present in the map. In that
+	 * case, a new index is used for the color. Returns -1, if adding the
+	 * color would exceed the desired maximum number of colors in the
+	 * palette.
+	 * @param color the color to get the index from
+	 * @return the palette index of the specified color or -1, if there
+	 * is no space left in the palette
+	 */
+	int GetIndexForColor(unsigned color);
+
+	/**
+	 * Adds the specified number of entries of the specified reserve
+	 * palette to the newly created palette.
+	 * @param *palette a pointer to the reserve palette to copy from
+	 * @param size the number of entries to copy
+	 */
+	void AddReservePalette(const void *palette, unsigned size);
+
+	/**
+	 * Copies the newly created palette into the specified destination
+	 * palettte. Although unused palette entries are not overwritten in
+	 * the destination palette, it is assumed to have space for at
+	 * least 256 entries.
+	 * @param palette a pointer to the destination palette
+	 */
+	void WritePalette(void *palette);
+
+};
diff --git a/Source/Utilities.h b/Source/Utilities.h
index ab0243c..79b0c1d 100644
--- a/Source/Utilities.h
+++ b/Source/Utilities.h
@@ -5,6 +5,7 @@
 // - Floris van den Berg (flvdberg at wxs.nl)
 // - Hervé Drolon <drolon at infonie.fr>
 // - Ryan Rubley (ryan at lostreality.org)
+// - Mihail Naydenov (mnaydenov at users.sourceforge.net)
 //
 // This file is part of FreeImage 3
 //
@@ -72,12 +73,13 @@ Allocate a FIBITMAP with possibly no pixel data
 (i.e. only header data and some or all metadata)
 @param header_only If TRUE, allocate a 'header only' FIBITMAP, otherwise allocate a full FIBITMAP
 @param type Image type
- at param width
- at param height
- at param bpp
- at param red_mask
- at param green_mask
- at param blue_mask
+ at param width Image width
+ at param height Image height
+ at param bpp Number of bits per pixel
+ at param red_mask Image red mask 
+ at param green_mask Image green mask
+ at param blue_mask Image blue mask
+ at return Returns the allocated FIBITMAP
 @see FreeImage_AllocateT
 */
 DLL_API FIBITMAP * DLL_CALLCONV FreeImage_AllocateHeaderT(BOOL header_only, FREE_IMAGE_TYPE type, int width, int height, int bpp FI_DEFAULT(8), unsigned red_mask FI_DEFAULT(0), unsigned green_mask FI_DEFAULT(0), unsigned blue_mask FI_DEFAULT(0));
@@ -86,21 +88,38 @@ DLL_API FIBITMAP * DLL_CALLCONV FreeImage_AllocateHeaderT(BOOL header_only, FREE
 Allocate a FIBITMAP of type FIT_BITMAP, with possibly no pixel data 
 (i.e. only header data and some or all metadata)
 @param header_only If TRUE, allocate a 'header only' FIBITMAP, otherwise allocate a full FIBITMAP
- at param width
- at param height
- at param bpp
- at param red_mask
- at param green_mask
- at param blue_mask
+ at param width Image width
+ at param height Image height
+ at param bpp Number of bits per pixel
+ at param red_mask Image red mask 
+ at param green_mask Image green mask
+ at param blue_mask Image blue mask
+ at return Returns the allocated FIBITMAP
 @see FreeImage_Allocate
 */
 DLL_API FIBITMAP * DLL_CALLCONV FreeImage_AllocateHeader(BOOL header_only, int width, int height, int bpp, unsigned red_mask FI_DEFAULT(0), unsigned green_mask FI_DEFAULT(0), unsigned blue_mask FI_DEFAULT(0));
 
 /**
+Allocate a FIBITMAP with no pixel data and wrap a user provided pixel buffer
+ at param ext_bits Pointer to external user's pixel buffer
+ at param ext_pitch Pointer to external user's pixel buffer pitch
+ at param type Image type
+ at param width Image width
+ at param height Image height
+ at param bpp Number of bits per pixel
+ at param red_mask Image red mask 
+ at param green_mask Image green mask
+ at param blue_mask Image blue mask
+ at return Returns the allocated FIBITMAP
+ at see FreeImage_ConvertFromRawBitsEx
+*/
+DLL_API FIBITMAP * DLL_CALLCONV FreeImage_AllocateHeaderForBits(BYTE *ext_bits, unsigned ext_pitch, FREE_IMAGE_TYPE type, int width, int height, int bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask);
+
+/**
 Helper for 16-bit FIT_BITMAP
- at see FreeImage_GetRGBMasks
-*/
-DLL_API BOOL DLL_CALLCONV FreeImage_HasRGBMasks(FIBITMAP *dib);
+ at see FreeImage_GetRGBMasks
+*/
+DLL_API BOOL DLL_CALLCONV FreeImage_HasRGBMasks(FIBITMAP *dib);
 
 #if defined(__cplusplus)
 }
@@ -276,7 +295,7 @@ CalculateUsedPaletteEntries(unsigned bit_count) {
 
 inline unsigned char *
 CalculateScanLine(unsigned char *bits, unsigned pitch, int scanline) {
-	return (bits + (pitch * scanline));
+	return bits ? (bits + ((size_t)pitch * scanline)) : NULL;
 }
 
 // ----------------------------------------------------------
@@ -365,6 +384,13 @@ RGBA to RGB conversion
 */
 FIBITMAP* RemoveAlphaChannel(FIBITMAP* dib);
 
+/**
+Rotate a dib according to Exif info
+ at param dib Input / Output dib to rotate
+ at see Exif.cpp, PluginJPEG.cpp
+*/
+void RotateExif(FIBITMAP **dib);
+
 
 // ==========================================================
 //   Big Endian / Little Endian utility functions
@@ -451,7 +477,7 @@ A Standard Default Color Space for the Internet - sRGB.
 */
 #define LUMA_REC709(r, g, b)	(0.2126F * r + 0.7152F * g + 0.0722F * b)
 
-#define GREY(r, g, b) (BYTE)LUMA_REC709(r, g, b)
+#define GREY(r, g, b) (BYTE)(LUMA_REC709(r, g, b) + 0.5F)
 /*
 #define GREY(r, g, b) (BYTE)(((WORD)r * 77 + (WORD)g * 150 + (WORD)b * 29) >> 8)	// .299R + .587G + .114B
 */
diff --git a/Source/ZLib/ChangeLog b/Source/ZLib/ChangeLog
index 84999ee..141f37e 100644
--- a/Source/ZLib/ChangeLog
+++ b/Source/ZLib/ChangeLog
@@ -1,6 +1,69 @@
 
                 ChangeLog file for zlib
 
+Changes in 1.2.8 (28 Apr 2013)
+- Update contrib/minizip/iowin32.c for Windows RT [Vollant]
+- Do not force Z_CONST for C++
+- Clean up contrib/vstudio [Ro�]
+- Correct spelling error in zlib.h
+- Fix mixed line endings in contrib/vstudio
+
+Changes in 1.2.7.3 (13 Apr 2013)
+- Fix version numbers and DLL names in contrib/vstudio/*/zlib.rc
+
+Changes in 1.2.7.2 (13 Apr 2013)
+- Change check for a four-byte type back to hexadecimal
+- Fix typo in win32/Makefile.msc
+- Add casts in gzwrite.c for pointer differences
+
+Changes in 1.2.7.1 (24 Mar 2013)
+- Replace use of unsafe string functions with snprintf if available
+- Avoid including stddef.h on Windows for Z_SOLO compile [Niessink]
+- Fix gzgetc undefine when Z_PREFIX set [Turk]
+- Eliminate use of mktemp in Makefile (not always available)
+- Fix bug in 'F' mode for gzopen()
+- Add inflateGetDictionary() function
+- Correct comment in deflate.h
+- Use _snprintf for snprintf in Microsoft C
+- On Darwin, only use /usr/bin/libtool if libtool is not Apple
+- Delete "--version" file if created by "ar --version" [Richard G.]
+- Fix configure check for veracity of compiler error return codes
+- Fix CMake compilation of static lib for MSVC2010 x64
+- Remove unused variable in infback9.c
+- Fix argument checks in gzlog_compress() and gzlog_write()
+- Clean up the usage of z_const and respect const usage within zlib
+- Clean up examples/gzlog.[ch] comparisons of different types
+- Avoid shift equal to bits in type (caused endless loop)
+- Fix unintialized value bug in gzputc() introduced by const patches
+- Fix memory allocation error in examples/zran.c [Nor]
+- Fix bug where gzopen(), gzclose() would write an empty file
+- Fix bug in gzclose() when gzwrite() runs out of memory
+- Check for input buffer malloc failure in examples/gzappend.c
+- Add note to contrib/blast to use binary mode in stdio
+- Fix comparisons of differently signed integers in contrib/blast
+- Check for invalid code length codes in contrib/puff
+- Fix serious but very rare decompression bug in inftrees.c
+- Update inflateBack() comments, since inflate() can be faster
+- Use underscored I/O function names for WINAPI_FAMILY
+- Add _tr_flush_bits to the external symbols prefixed by --zprefix
+- Add contrib/vstudio/vc10 pre-build step for static only
+- Quote --version-script argument in CMakeLists.txt
+- Don't specify --version-script on Apple platforms in CMakeLists.txt
+- Fix casting error in contrib/testzlib/testzlib.c
+- Fix types in contrib/minizip to match result of get_crc_table()
+- Simplify contrib/vstudio/vc10 with 'd' suffix
+- Add TOP support to win32/Makefile.msc
+- Suport i686 and amd64 assembler builds in CMakeLists.txt
+- Fix typos in the use of _LARGEFILE64_SOURCE in zconf.h
+- Add vc11 and vc12 build files to contrib/vstudio
+- Add gzvprintf() as an undocumented function in zlib
+- Fix configure for Sun shell
+- Remove runtime check in configure for four-byte integer type
+- Add casts and consts to ease user conversion to C++
+- Add man pages for minizip and miniunzip
+- In Makefile uninstall, don't rm if preceding cd fails
+- Do not return Z_BUF_ERROR if deflateParam() has nothing to write
+
 Changes in 1.2.7 (2 May 2012)
 - Replace use of memmove() with a simple copy for portability
 - Test for existence of strerror
@@ -1153,7 +1216,7 @@ Changes in 1.0.6 (19 Jan 1998)
 - use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau)
 - added makelcc.bat for lcc-win32 (Tom St Denis)
 - in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe)
-- Avoid expanded $Id: ChangeLog,v 1.7 2012/05/13 12:18:39 drolon Exp $. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion.
+- Avoid expanded $Id: ChangeLog,v 1.8 2013/05/10 17:22:51 drolon Exp $. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion.
 - check for unistd.h in configure (for off_t)
 - remove useless check parameter in inflate_blocks_free
 - avoid useless assignment of s->check to itself in inflate_blocks_new
diff --git a/Source/ZLib/Makefile.in b/Source/ZLib/Makefile.in
index 241deed..c61aa30 100644
--- a/Source/ZLib/Makefile.in
+++ b/Source/ZLib/Makefile.in
@@ -1,5 +1,5 @@
 # Makefile for zlib
-# Copyright (C) 1995-2011 Jean-loup Gailly.
+# Copyright (C) 1995-2013 Jean-loup Gailly, Mark Adler
 # For conditions of distribution and use, see copyright notice in zlib.h
 
 # To compile and test, type:
@@ -32,7 +32,7 @@ CPP=$(CC) -E
 
 STATICLIB=libz.a
 SHAREDLIB=libz.so
-SHAREDLIBV=libz.so.1.2.7
+SHAREDLIBV=libz.so.1.2.8
 SHAREDLIBM=libz.so.1
 LIBS=$(STATICLIB) $(SHAREDLIBV)
 
@@ -83,7 +83,7 @@ check: test
 test: all teststatic testshared
 
 teststatic: static
-	@TMPST=`mktemp fooXXXXXX`; \
+	@TMPST=tmpst_$$; \
 	if echo hello world | ./minigzip | ./minigzip -d && ./example $$TMPST ; then \
 	  echo '		*** zlib test OK ***'; \
 	else \
@@ -96,7 +96,7 @@ testshared: shared
 	LD_LIBRARYN32_PATH=`pwd`:$(LD_LIBRARYN32_PATH) ; export LD_LIBRARYN32_PATH; \
 	DYLD_LIBRARY_PATH=`pwd`:$(DYLD_LIBRARY_PATH) ; export DYLD_LIBRARY_PATH; \
 	SHLIB_PATH=`pwd`:$(SHLIB_PATH) ; export SHLIB_PATH; \
-	TMPSH=`mktemp fooXXXXXX`; \
+	TMPSH=tmpsh_$$; \
 	if echo hello world | ./minigzipsh | ./minigzipsh -d && ./examplesh $$TMPSH; then \
 	  echo '		*** zlib shared test OK ***'; \
 	else \
@@ -105,7 +105,7 @@ testshared: shared
 	rm -f $$TMPSH
 
 test64: all64
-	@TMP64=`mktemp fooXXXXXX`; \
+	@TMP64=tmp64_$$; \
 	if echo hello world | ./minigzip64 | ./minigzip64 -d && ./example64 $$TMP64; then \
 	  echo '		*** zlib 64-bit test OK ***'; \
 	else \
@@ -216,13 +216,13 @@ install: install-libs
 	chmod 644 $(DESTDIR)$(includedir)/zlib.h $(DESTDIR)$(includedir)/zconf.h
 
 uninstall:
-	cd $(DESTDIR)$(includedir); rm -f zlib.h zconf.h
-	cd $(DESTDIR)$(libdir); rm -f libz.a; \
+	cd $(DESTDIR)$(includedir) && rm -f zlib.h zconf.h
+	cd $(DESTDIR)$(libdir) && rm -f libz.a; \
 	if test -n "$(SHAREDLIBV)" -a -f $(SHAREDLIBV); then \
 	  rm -f $(SHAREDLIBV) $(SHAREDLIB) $(SHAREDLIBM); \
 	fi
-	cd $(DESTDIR)$(man3dir); rm -f zlib.3
-	cd $(DESTDIR)$(pkgconfigdir); rm -f zlib.pc
+	cd $(DESTDIR)$(man3dir) && rm -f zlib.3
+	cd $(DESTDIR)$(pkgconfigdir) && rm -f zlib.pc
 
 docs: zlib.3.pdf
 
@@ -230,7 +230,7 @@ zlib.3.pdf: zlib.3
 	groff -mandoc -f H -T ps zlib.3 | ps2pdf - zlib.3.pdf
 
 zconf.h.cmakein: zconf.h.in
-	-@ TEMPFILE=`mktemp __XXXXXX`; \
+	-@ TEMPFILE=zconfh_$$; \
 	echo "/#define ZCONF_H/ a\\\\\n#cmakedefine Z_PREFIX\\\\\n#cmakedefine Z_HAVE_UNISTD_H\n" >> $$TEMPFILE &&\
 	sed -f $$TEMPFILE zconf.h.in > zconf.h.cmakein &&\
 	touch -r zconf.h.in zconf.h.cmakein &&\
diff --git a/Source/ZLib/README b/Source/ZLib/README
index 6f1255f..5ca9d12 100644
--- a/Source/ZLib/README
+++ b/Source/ZLib/README
@@ -1,6 +1,6 @@
 ZLIB DATA COMPRESSION LIBRARY
 
-zlib 1.2.7 is a general purpose data compression library.  All the code is
+zlib 1.2.8 is a general purpose data compression library.  All the code is
 thread safe.  The data format used by the zlib library is described by RFCs
 (Request for Comments) 1950 to 1952 in the files
 http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and
@@ -31,7 +31,7 @@ Mark Nelson <markn at ieee.org> wrote an article about zlib for the Jan.  1997
 issue of Dr.  Dobb's Journal; a copy of the article is available at
 http://marknelson.us/1997/01/01/zlib-engine/ .
 
-The changes made in version 1.2.7 are documented in the file ChangeLog.
+The changes made in version 1.2.8 are documented in the file ChangeLog.
 
 Unsupported third party contributions are provided in directory contrib/ .
 
@@ -84,7 +84,7 @@ Acknowledgments:
 
 Copyright notice:
 
- (C) 1995-2012 Jean-loup Gailly and Mark Adler
+ (C) 1995-2013 Jean-loup Gailly and Mark Adler
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/Source/ZLib/ZLib.2003.vcproj b/Source/ZLib/ZLib.2003.vcproj
deleted file mode 100644
index 656408a..0000000
--- a/Source/ZLib/ZLib.2003.vcproj
+++ /dev/null
@@ -1,213 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="7.10"
-	Name="ZLib"
-	SccProjectName=""$/FreeImage/ZLib", KNAAAAAA"
-	SccLocalPath=".">
-	<Platforms>
-		<Platform
-			Name="Win32"/>
-	</Platforms>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			OutputDirectory=".\Debug"
-			IntermediateDirectory=".\Debug"
-			ConfigurationType="4"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="FALSE"
-			CharacterSet="2">
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="0"
-				PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
-				StringPooling="TRUE"
-				BasicRuntimeChecks="3"
-				RuntimeLibrary="1"
-				UsePrecompiledHeader="2"
-				PrecompiledHeaderFile=".\Debug/ZLib.pch"
-				AssemblerListingLocation=".\Debug/"
-				ObjectFile=".\Debug/"
-				ProgramDataBaseFileName=".\Debug/"
-				WarningLevel="3"
-				SuppressStartupBanner="TRUE"
-				DebugInformationFormat="4"/>
-			<Tool
-				Name="VCCustomBuildTool"/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile=".\Debug\ZLib.lib"
-				SuppressStartupBanner="TRUE"/>
-			<Tool
-				Name="VCMIDLTool"/>
-			<Tool
-				Name="VCPostBuildEventTool"/>
-			<Tool
-				Name="VCPreBuildEventTool"/>
-			<Tool
-				Name="VCPreLinkEventTool"/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="_DEBUG"
-				Culture="1033"/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"/>
-			<Tool
-				Name="VCManagedWrapperGeneratorTool"/>
-			<Tool
-				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			OutputDirectory=".\Release"
-			IntermediateDirectory=".\Release"
-			ConfigurationType="4"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="FALSE"
-			CharacterSet="2">
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="2"
-				GlobalOptimizations="TRUE"
-				InlineFunctionExpansion="2"
-				EnableIntrinsicFunctions="TRUE"
-				FavorSizeOrSpeed="1"
-				OmitFramePointers="TRUE"
-				OptimizeForProcessor="3"
-				AdditionalIncludeDirectories="..\zlib"
-				PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
-				StringPooling="TRUE"
-				RuntimeLibrary="0"
-				BufferSecurityCheck="FALSE"
-				UsePrecompiledHeader="2"
-				PrecompiledHeaderFile=".\Release/ZLib.pch"
-				AssemblerListingLocation=".\Release/"
-				ObjectFile=".\Release/"
-				ProgramDataBaseFileName=".\Release/"
-				WarningLevel="3"
-				SuppressStartupBanner="TRUE"
-				CompileAs="0"/>
-			<Tool
-				Name="VCCustomBuildTool"/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile=".\Release\ZLib.lib"
-				SuppressStartupBanner="TRUE"/>
-			<Tool
-				Name="VCMIDLTool"/>
-			<Tool
-				Name="VCPostBuildEventTool"/>
-			<Tool
-				Name="VCPreBuildEventTool"/>
-			<Tool
-				Name="VCPreLinkEventTool"/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="1033"/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"/>
-			<Tool
-				Name="VCManagedWrapperGeneratorTool"/>
-			<Tool
-				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Source Files"
-			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
-			<File
-				RelativePath="adler32.c">
-			</File>
-			<File
-				RelativePath="compress.c">
-			</File>
-			<File
-				RelativePath="crc32.c">
-			</File>
-			<File
-				RelativePath="deflate.c">
-			</File>
-			<File
-				RelativePath=".\gzclose.c">
-			</File>
-			<File
-				RelativePath=".\gzlib.c">
-			</File>
-			<File
-				RelativePath=".\gzread.c">
-			</File>
-			<File
-				RelativePath=".\gzwrite.c">
-			</File>
-			<File
-				RelativePath="infback.c">
-			</File>
-			<File
-				RelativePath="inffast.c">
-			</File>
-			<File
-				RelativePath="inflate.c">
-			</File>
-			<File
-				RelativePath="inftrees.c">
-			</File>
-			<File
-				RelativePath="trees.c">
-			</File>
-			<File
-				RelativePath="uncompr.c">
-			</File>
-			<File
-				RelativePath="zutil.c">
-			</File>
-		</Filter>
-		<Filter
-			Name="Header Files"
-			Filter="h;hpp;hxx;hm;inl">
-			<File
-				RelativePath="crc32.h">
-			</File>
-			<File
-				RelativePath="deflate.h">
-			</File>
-			<File
-				RelativePath=".\gzguts.h">
-			</File>
-			<File
-				RelativePath="inffast.h">
-			</File>
-			<File
-				RelativePath="inffixed.h">
-			</File>
-			<File
-				RelativePath="inflate.h">
-			</File>
-			<File
-				RelativePath="inftrees.h">
-			</File>
-			<File
-				RelativePath="trees.h">
-			</File>
-			<File
-				RelativePath="zconf.h">
-			</File>
-			<File
-				RelativePath="zlib.h">
-			</File>
-			<File
-				RelativePath="zutil.h">
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
diff --git a/Source/ZLib/ZLib.2008.vcproj b/Source/ZLib/ZLib.2008.vcproj
index 0817f43..5637bdd 100644
--- a/Source/ZLib/ZLib.2008.vcproj
+++ b/Source/ZLib/ZLib.2008.vcproj
@@ -46,7 +46,7 @@
 			<Tool
 				Name="VCCLCompilerTool"
 				Optimization="0"
-				PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE"
+				PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS"
 				StringPooling="true"
 				BasicRuntimeChecks="3"
 				RuntimeLibrary="1"
@@ -198,7 +198,7 @@
 				FavorSizeOrSpeed="1"
 				OmitFramePointers="true"
 				AdditionalIncludeDirectories="..\zlib"
-				PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE"
+				PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS"
 				StringPooling="true"
 				RuntimeLibrary="0"
 				BufferSecurityCheck="false"
diff --git a/Source/ZLib/ZLib.2013.vcxproj b/Source/ZLib/ZLib.2013.vcxproj
new file mode 100644
index 0000000..0edc686
--- /dev/null
+++ b/Source/ZLib/ZLib.2013.vcxproj
@@ -0,0 +1,233 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectName>ZLib</ProjectName>
+    <ProjectGuid>{33134F61-C1AD-4B6F-9CEA-503A9F140C52}</ProjectGuid>
+    <RootNamespace>ZLib</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>12.0.21005.1</_ProjectFileVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+      <PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0409</Culture>
+    </ResourceCompile>
+    <Lib>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0409</Culture>
+    </ResourceCompile>
+    <Lib>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <Optimization>Full</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>
+      </AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <CompileAs>Default</CompileAs>
+      <PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+      <DebugInformationFormat>None</DebugInformationFormat>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0409</Culture>
+    </ResourceCompile>
+    <Lib>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <LinkTimeCodeGeneration>true</LinkTimeCodeGeneration>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>Full</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>
+      </AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <CompileAs>Default</CompileAs>
+      <PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+      <DebugInformationFormat>None</DebugInformationFormat>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0409</Culture>
+    </ResourceCompile>
+    <Lib>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <LinkTimeCodeGeneration>true</LinkTimeCodeGeneration>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="adler32.c" />
+    <ClCompile Include="compress.c" />
+    <ClCompile Include="crc32.c" />
+    <ClCompile Include="deflate.c" />
+    <ClCompile Include="gzclose.c" />
+    <ClCompile Include="gzlib.c" />
+    <ClCompile Include="gzread.c" />
+    <ClCompile Include="gzwrite.c" />
+    <ClCompile Include="infback.c" />
+    <ClCompile Include="inffast.c" />
+    <ClCompile Include="inflate.c" />
+    <ClCompile Include="inftrees.c" />
+    <ClCompile Include="trees.c" />
+    <ClCompile Include="uncompr.c" />
+    <ClCompile Include="zutil.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="crc32.h" />
+    <ClInclude Include="deflate.h" />
+    <ClInclude Include="gzguts.h" />
+    <ClInclude Include="inffast.h" />
+    <ClInclude Include="inffixed.h" />
+    <ClInclude Include="inflate.h" />
+    <ClInclude Include="inftrees.h" />
+    <ClInclude Include="trees.h" />
+    <ClInclude Include="zconf.h" />
+    <ClInclude Include="zlib.h" />
+    <ClInclude Include="zutil.h" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/Source/ZLib/ZLib.2013.vcxproj.filters b/Source/ZLib/ZLib.2013.vcxproj.filters
new file mode 100644
index 0000000..29462eb
--- /dev/null
+++ b/Source/ZLib/ZLib.2013.vcxproj.filters
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{d67faf16-4f82-41bc-882b-620fed678573}</UniqueIdentifier>
+      <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{f4a416b7-ef3f-4ba1-b047-c2e553510a1a}</UniqueIdentifier>
+      <Extensions>h;hpp;hxx;hm;inl</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="adler32.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="compress.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="crc32.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="deflate.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="gzclose.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="gzlib.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="gzread.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="gzwrite.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="infback.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="inffast.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="inflate.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="inftrees.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="trees.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="uncompr.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="zutil.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="crc32.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="deflate.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="gzguts.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="inffast.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="inffixed.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="inflate.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="inftrees.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="trees.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="zconf.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="zlib.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="zutil.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/Source/ZLib/adler32.c b/Source/ZLib/adler32.c
index 28f1919..8421a89 100644
--- a/Source/ZLib/adler32.c
+++ b/Source/ZLib/adler32.c
@@ -1,179 +1,179 @@
-/* adler32.c -- compute the Adler-32 checksum of a data stream
- * Copyright (C) 1995-2011 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id: adler32.c,v 1.9 2012/05/13 12:18:39 drolon Exp $ */
-
-#include "zutil.h"
-
-#define local static
-
-local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2));
-
-#define BASE 65521      /* largest prime smaller than 65536 */
-#define NMAX 5552
-/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
-
-#define DO1(buf,i)  {adler += (buf)[i]; sum2 += adler;}
-#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
-#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
-#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
-#define DO16(buf)   DO8(buf,0); DO8(buf,8);
-
-/* use NO_DIVIDE if your processor does not do division in hardware --
-   try it both ways to see which is faster */
-#ifdef NO_DIVIDE
-/* note that this assumes BASE is 65521, where 65536 % 65521 == 15
-   (thank you to John Reiser for pointing this out) */
-#  define CHOP(a) \
-    do { \
-        unsigned long tmp = a >> 16; \
-        a &= 0xffffUL; \
-        a += (tmp << 4) - tmp; \
-    } while (0)
-#  define MOD28(a) \
-    do { \
-        CHOP(a); \
-        if (a >= BASE) a -= BASE; \
-    } while (0)
-#  define MOD(a) \
-    do { \
-        CHOP(a); \
-        MOD28(a); \
-    } while (0)
-#  define MOD63(a) \
-    do { /* this assumes a is not negative */ \
-        z_off64_t tmp = a >> 32; \
-        a &= 0xffffffffL; \
-        a += (tmp << 8) - (tmp << 5) + tmp; \
-        tmp = a >> 16; \
-        a &= 0xffffL; \
-        a += (tmp << 4) - tmp; \
-        tmp = a >> 16; \
-        a &= 0xffffL; \
-        a += (tmp << 4) - tmp; \
-        if (a >= BASE) a -= BASE; \
-    } while (0)
-#else
-#  define MOD(a) a %= BASE
-#  define MOD28(a) a %= BASE
-#  define MOD63(a) a %= BASE
-#endif
-
-/* ========================================================================= */
-uLong ZEXPORT adler32(adler, buf, len)
-    uLong adler;
-    const Bytef *buf;
-    uInt len;
-{
-    unsigned long sum2;
-    unsigned n;
-
-    /* split Adler-32 into component sums */
-    sum2 = (adler >> 16) & 0xffff;
-    adler &= 0xffff;
-
-    /* in case user likes doing a byte at a time, keep it fast */
-    if (len == 1) {
-        adler += buf[0];
-        if (adler >= BASE)
-            adler -= BASE;
-        sum2 += adler;
-        if (sum2 >= BASE)
-            sum2 -= BASE;
-        return adler | (sum2 << 16);
-    }
-
-    /* initial Adler-32 value (deferred check for len == 1 speed) */
-    if (buf == Z_NULL)
-        return 1L;
-
-    /* in case short lengths are provided, keep it somewhat fast */
-    if (len < 16) {
-        while (len--) {
-            adler += *buf++;
-            sum2 += adler;
-        }
-        if (adler >= BASE)
-            adler -= BASE;
-        MOD28(sum2);            /* only added so many BASE's */
-        return adler | (sum2 << 16);
-    }
-
-    /* do length NMAX blocks -- requires just one modulo operation */
-    while (len >= NMAX) {
-        len -= NMAX;
-        n = NMAX / 16;          /* NMAX is divisible by 16 */
-        do {
-            DO16(buf);          /* 16 sums unrolled */
-            buf += 16;
-        } while (--n);
-        MOD(adler);
-        MOD(sum2);
-    }
-
-    /* do remaining bytes (less than NMAX, still just one modulo) */
-    if (len) {                  /* avoid modulos if none remaining */
-        while (len >= 16) {
-            len -= 16;
-            DO16(buf);
-            buf += 16;
-        }
-        while (len--) {
-            adler += *buf++;
-            sum2 += adler;
-        }
-        MOD(adler);
-        MOD(sum2);
-    }
-
-    /* return recombined sums */
-    return adler | (sum2 << 16);
-}
-
-/* ========================================================================= */
-local uLong adler32_combine_(adler1, adler2, len2)
-    uLong adler1;
-    uLong adler2;
-    z_off64_t len2;
-{
-    unsigned long sum1;
-    unsigned long sum2;
-    unsigned rem;
-
-    /* for negative len, return invalid adler32 as a clue for debugging */
-    if (len2 < 0)
-        return 0xffffffffUL;
-
-    /* the derivation of this formula is left as an exercise for the reader */
-    MOD63(len2);                /* assumes len2 >= 0 */
-    rem = (unsigned)len2;
-    sum1 = adler1 & 0xffff;
-    sum2 = rem * sum1;
-    MOD(sum2);
-    sum1 += (adler2 & 0xffff) + BASE - 1;
-    sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
-    if (sum1 >= BASE) sum1 -= BASE;
-    if (sum1 >= BASE) sum1 -= BASE;
-    if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1);
-    if (sum2 >= BASE) sum2 -= BASE;
-    return sum1 | (sum2 << 16);
-}
-
-/* ========================================================================= */
-uLong ZEXPORT adler32_combine(adler1, adler2, len2)
-    uLong adler1;
-    uLong adler2;
-    z_off_t len2;
-{
-    return adler32_combine_(adler1, adler2, len2);
-}
-
-uLong ZEXPORT adler32_combine64(adler1, adler2, len2)
-    uLong adler1;
-    uLong adler2;
-    z_off64_t len2;
-{
-    return adler32_combine_(adler1, adler2, len2);
-}
+/* adler32.c -- compute the Adler-32 checksum of a data stream
+ * Copyright (C) 1995-2011 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id: adler32.c,v 1.10 2013/05/10 17:22:51 drolon Exp $ */
+
+#include "zutil.h"
+
+#define local static
+
+local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2));
+
+#define BASE 65521      /* largest prime smaller than 65536 */
+#define NMAX 5552
+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
+
+#define DO1(buf,i)  {adler += (buf)[i]; sum2 += adler;}
+#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
+#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
+#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
+#define DO16(buf)   DO8(buf,0); DO8(buf,8);
+
+/* use NO_DIVIDE if your processor does not do division in hardware --
+   try it both ways to see which is faster */
+#ifdef NO_DIVIDE
+/* note that this assumes BASE is 65521, where 65536 % 65521 == 15
+   (thank you to John Reiser for pointing this out) */
+#  define CHOP(a) \
+    do { \
+        unsigned long tmp = a >> 16; \
+        a &= 0xffffUL; \
+        a += (tmp << 4) - tmp; \
+    } while (0)
+#  define MOD28(a) \
+    do { \
+        CHOP(a); \
+        if (a >= BASE) a -= BASE; \
+    } while (0)
+#  define MOD(a) \
+    do { \
+        CHOP(a); \
+        MOD28(a); \
+    } while (0)
+#  define MOD63(a) \
+    do { /* this assumes a is not negative */ \
+        z_off64_t tmp = a >> 32; \
+        a &= 0xffffffffL; \
+        a += (tmp << 8) - (tmp << 5) + tmp; \
+        tmp = a >> 16; \
+        a &= 0xffffL; \
+        a += (tmp << 4) - tmp; \
+        tmp = a >> 16; \
+        a &= 0xffffL; \
+        a += (tmp << 4) - tmp; \
+        if (a >= BASE) a -= BASE; \
+    } while (0)
+#else
+#  define MOD(a) a %= BASE
+#  define MOD28(a) a %= BASE
+#  define MOD63(a) a %= BASE
+#endif
+
+/* ========================================================================= */
+uLong ZEXPORT adler32(adler, buf, len)
+    uLong adler;
+    const Bytef *buf;
+    uInt len;
+{
+    unsigned long sum2;
+    unsigned n;
+
+    /* split Adler-32 into component sums */
+    sum2 = (adler >> 16) & 0xffff;
+    adler &= 0xffff;
+
+    /* in case user likes doing a byte at a time, keep it fast */
+    if (len == 1) {
+        adler += buf[0];
+        if (adler >= BASE)
+            adler -= BASE;
+        sum2 += adler;
+        if (sum2 >= BASE)
+            sum2 -= BASE;
+        return adler | (sum2 << 16);
+    }
+
+    /* initial Adler-32 value (deferred check for len == 1 speed) */
+    if (buf == Z_NULL)
+        return 1L;
+
+    /* in case short lengths are provided, keep it somewhat fast */
+    if (len < 16) {
+        while (len--) {
+            adler += *buf++;
+            sum2 += adler;
+        }
+        if (adler >= BASE)
+            adler -= BASE;
+        MOD28(sum2);            /* only added so many BASE's */
+        return adler | (sum2 << 16);
+    }
+
+    /* do length NMAX blocks -- requires just one modulo operation */
+    while (len >= NMAX) {
+        len -= NMAX;
+        n = NMAX / 16;          /* NMAX is divisible by 16 */
+        do {
+            DO16(buf);          /* 16 sums unrolled */
+            buf += 16;
+        } while (--n);
+        MOD(adler);
+        MOD(sum2);
+    }
+
+    /* do remaining bytes (less than NMAX, still just one modulo) */
+    if (len) {                  /* avoid modulos if none remaining */
+        while (len >= 16) {
+            len -= 16;
+            DO16(buf);
+            buf += 16;
+        }
+        while (len--) {
+            adler += *buf++;
+            sum2 += adler;
+        }
+        MOD(adler);
+        MOD(sum2);
+    }
+
+    /* return recombined sums */
+    return adler | (sum2 << 16);
+}
+
+/* ========================================================================= */
+local uLong adler32_combine_(adler1, adler2, len2)
+    uLong adler1;
+    uLong adler2;
+    z_off64_t len2;
+{
+    unsigned long sum1;
+    unsigned long sum2;
+    unsigned rem;
+
+    /* for negative len, return invalid adler32 as a clue for debugging */
+    if (len2 < 0)
+        return 0xffffffffUL;
+
+    /* the derivation of this formula is left as an exercise for the reader */
+    MOD63(len2);                /* assumes len2 >= 0 */
+    rem = (unsigned)len2;
+    sum1 = adler1 & 0xffff;
+    sum2 = rem * sum1;
+    MOD(sum2);
+    sum1 += (adler2 & 0xffff) + BASE - 1;
+    sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
+    if (sum1 >= BASE) sum1 -= BASE;
+    if (sum1 >= BASE) sum1 -= BASE;
+    if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1);
+    if (sum2 >= BASE) sum2 -= BASE;
+    return sum1 | (sum2 << 16);
+}
+
+/* ========================================================================= */
+uLong ZEXPORT adler32_combine(adler1, adler2, len2)
+    uLong adler1;
+    uLong adler2;
+    z_off_t len2;
+{
+    return adler32_combine_(adler1, adler2, len2);
+}
+
+uLong ZEXPORT adler32_combine64(adler1, adler2, len2)
+    uLong adler1;
+    uLong adler2;
+    z_off64_t len2;
+{
+    return adler32_combine_(adler1, adler2, len2);
+}
diff --git a/Source/ZLib/compress.c b/Source/ZLib/compress.c
index 91dea5c..0437f40 100644
--- a/Source/ZLib/compress.c
+++ b/Source/ZLib/compress.c
@@ -1,80 +1,80 @@
-/* compress.c -- compress a memory buffer
- * Copyright (C) 1995-2005 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id: compress.c,v 1.9 2012/05/13 12:18:39 drolon Exp $ */
-
-#define ZLIB_INTERNAL
-#include "zlib.h"
-
-/* ===========================================================================
-     Compresses the source buffer into the destination buffer. The level
-   parameter has the same meaning as in deflateInit.  sourceLen is the byte
-   length of the source buffer. Upon entry, destLen is the total size of the
-   destination buffer, which must be at least 0.1% larger than sourceLen plus
-   12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
-
-     compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
-   memory, Z_BUF_ERROR if there was not enough room in the output buffer,
-   Z_STREAM_ERROR if the level parameter is invalid.
-*/
-int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
-    Bytef *dest;
-    uLongf *destLen;
-    const Bytef *source;
-    uLong sourceLen;
-    int level;
-{
-    z_stream stream;
-    int err;
-
-    stream.next_in = (Bytef*)source;
-    stream.avail_in = (uInt)sourceLen;
-#ifdef MAXSEG_64K
-    /* Check for source > 64K on 16-bit machine: */
-    if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
-#endif
-    stream.next_out = dest;
-    stream.avail_out = (uInt)*destLen;
-    if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
-
-    stream.zalloc = (alloc_func)0;
-    stream.zfree = (free_func)0;
-    stream.opaque = (voidpf)0;
-
-    err = deflateInit(&stream, level);
-    if (err != Z_OK) return err;
-
-    err = deflate(&stream, Z_FINISH);
-    if (err != Z_STREAM_END) {
-        deflateEnd(&stream);
-        return err == Z_OK ? Z_BUF_ERROR : err;
-    }
-    *destLen = stream.total_out;
-
-    err = deflateEnd(&stream);
-    return err;
-}
-
-/* ===========================================================================
- */
-int ZEXPORT compress (dest, destLen, source, sourceLen)
-    Bytef *dest;
-    uLongf *destLen;
-    const Bytef *source;
-    uLong sourceLen;
-{
-    return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
-}
-
-/* ===========================================================================
-     If the default memLevel or windowBits for deflateInit() is changed, then
-   this function needs to be updated.
- */
-uLong ZEXPORT compressBound (sourceLen)
-    uLong sourceLen;
-{
-    return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
-           (sourceLen >> 25) + 13;
-}
+/* compress.c -- compress a memory buffer
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id: compress.c,v 1.10 2013/05/10 17:22:51 drolon Exp $ */
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+/* ===========================================================================
+     Compresses the source buffer into the destination buffer. The level
+   parameter has the same meaning as in deflateInit.  sourceLen is the byte
+   length of the source buffer. Upon entry, destLen is the total size of the
+   destination buffer, which must be at least 0.1% larger than sourceLen plus
+   12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
+
+     compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+   Z_STREAM_ERROR if the level parameter is invalid.
+*/
+int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
+    Bytef *dest;
+    uLongf *destLen;
+    const Bytef *source;
+    uLong sourceLen;
+    int level;
+{
+    z_stream stream;
+    int err;
+
+    stream.next_in = (z_const Bytef *)source;
+    stream.avail_in = (uInt)sourceLen;
+#ifdef MAXSEG_64K
+    /* Check for source > 64K on 16-bit machine: */
+    if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
+#endif
+    stream.next_out = dest;
+    stream.avail_out = (uInt)*destLen;
+    if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+
+    stream.zalloc = (alloc_func)0;
+    stream.zfree = (free_func)0;
+    stream.opaque = (voidpf)0;
+
+    err = deflateInit(&stream, level);
+    if (err != Z_OK) return err;
+
+    err = deflate(&stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        deflateEnd(&stream);
+        return err == Z_OK ? Z_BUF_ERROR : err;
+    }
+    *destLen = stream.total_out;
+
+    err = deflateEnd(&stream);
+    return err;
+}
+
+/* ===========================================================================
+ */
+int ZEXPORT compress (dest, destLen, source, sourceLen)
+    Bytef *dest;
+    uLongf *destLen;
+    const Bytef *source;
+    uLong sourceLen;
+{
+    return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
+}
+
+/* ===========================================================================
+     If the default memLevel or windowBits for deflateInit() is changed, then
+   this function needs to be updated.
+ */
+uLong ZEXPORT compressBound (sourceLen)
+    uLong sourceLen;
+{
+    return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
+           (sourceLen >> 25) + 13;
+}
diff --git a/Source/ZLib/configure b/Source/ZLib/configure
index 36c7d8e..b77a8a8 100644
--- a/Source/ZLib/configure
+++ b/Source/ZLib/configure
@@ -70,6 +70,7 @@ shared=1
 solo=0
 cover=0
 zprefix=0
+zconst=0
 build64=0
 gcc=0
 old_cc="$CC"
@@ -77,13 +78,26 @@ old_cflags="$CFLAGS"
 OBJC='$(OBJZ) $(OBJG)'
 PIC_OBJC='$(PIC_OBJZ) $(PIC_OBJG)'
 
+# leave this script, optionally in a bad way
+leave()
+{
+  if test "$*" != "0"; then
+    echo "** $0 aborting." | tee -a configure.log
+  fi
+  rm -f $test.[co] $test $test$shared_ext $test.gcno ./--version
+  echo -------------------- >> configure.log
+  echo >> configure.log
+  echo >> configure.log
+  exit $1
+}
+
 # process command line options
 while test $# -ge 1
 do
 case "$1" in
     -h* | --help)
       echo 'usage:' | tee -a configure.log
-      echo '  configure [--zprefix] [--prefix=PREFIX]  [--eprefix=EXPREFIX]' | tee -a configure.log
+      echo '  configure [--const] [--zprefix] [--prefix=PREFIX]  [--eprefix=EXPREFIX]' | tee -a configure.log
       echo '    [--static] [--64] [--libdir=LIBDIR] [--sharedlibdir=LIBDIR]' | tee -a configure.log
       echo '    [--includedir=INCLUDEDIR] [--archs="-arch i386 -arch x86_64"]' | tee -a configure.log
         exit 0 ;;
@@ -106,13 +120,18 @@ case "$1" in
     -a*=* | --archs=*) ARCHS=`echo $1 | sed 's/.*=//'`; shift ;;
     --sysconfdir=*) echo "ignored option: --sysconfdir" | tee -a configure.log; shift ;;
     --localstatedir=*) echo "ignored option: --localstatedir" | tee -a configure.log; shift ;;
-    *) echo "unknown option: $1"; echo "$0 --help for help" | tee -a configure.log; exit 1 ;;
+    -c* | --const) zconst=1; shift ;;
+    *)
+      echo "unknown option: $1" | tee -a configure.log
+      echo "$0 --help for help" | tee -a configure.log
+      leave 1;;
     esac
 done
 
-# define functions for testing compiler and library characteristics and logging the results
+# temporary file name
 test=ztest$$
 
+# put arguments in log, also put test file in log if used in arguments
 show()
 {
   case "$*" in
@@ -124,43 +143,6 @@ show()
   echo $* >> configure.log
 }
 
-cat > $test.c <<EOF
-#error error
-EOF
-if ($CC -c $CFLAGS $test.c) 2>/dev/null; then
-  try()
-  {
-    show $*
-    test "`( $* ) 2>&1 | tee -a configure.log`" = ""
-  }
-  echo - using any output from compiler to indicate an error >> configure.log
-else
-  try()
-  {
-    show $*
-    ( $* ) >> configure.log 2>&1
-    ret=$?
-    if test $ret -ne 0; then
-      echo "(exit code "$ret")" >> configure.log
-    fi
-    return $ret
-  }
-fi
-
-tryboth()
-{
-  show $*
-  got=`( $* ) 2>&1`
-  ret=$?
-  printf %s "$got" >> configure.log
-  if test $ret -ne 0; then
-    return $ret
-  fi
-  test "$got" = ""
-}
-
-echo >> configure.log
-
 # check for gcc vs. cc and set compile and link flags based on the system identified by uname
 cat > $test.c <<EOF
 extern int getchar();
@@ -179,8 +161,8 @@ case `$cc -v 2>&1` in
   *gcc*) gcc=1 ;;
 esac
 
-show $cc -c $cflags $test.c
-if test "$gcc" -eq 1 && ($cc -c $cflags $test.c) >> configure.log 2>&1; then
+show $cc -c $test.c
+if test "$gcc" -eq 1 && ($cc -c $test.c) >> configure.log 2>&1; then
   echo ... using gcc >> configure.log
   CC="$cc"
   CFLAGS="${CFLAGS--O3} ${ARCHS}"
@@ -191,7 +173,11 @@ if test "$gcc" -eq 1 && ($cc -c $cflags $test.c) >> configure.log 2>&1; then
     SFLAGS="${SFLAGS} -m64"
   fi
   if test "${ZLIBGCCWARN}" = "YES"; then
-    CFLAGS="${CFLAGS} -Wall -Wextra -pedantic"
+    if test "$zconst" -eq 1; then
+      CFLAGS="${CFLAGS} -Wall -Wextra -Wcast-qual -pedantic -DZLIB_CONST"
+    else
+      CFLAGS="${CFLAGS} -Wall -Wextra -pedantic"
+    fi
   fi
   if test -z "$uname"; then
     uname=`(uname -s || echo unknown) 2>/dev/null`
@@ -208,7 +194,7 @@ if test "$gcc" -eq 1 && ($cc -c $cflags $test.c) >> configure.log 2>&1; then
 # temporary bypass
         rm -f $test.[co] $test $test$shared_ext
         echo "Please use win32/Makefile.gcc instead." | tee -a configure.log
-        exit 1
+        leave 1
         LDSHARED=${LDSHARED-"$cc -shared"}
         LDSHAREDLIBC=""
         EXE='.exe' ;;
@@ -231,7 +217,11 @@ if test "$gcc" -eq 1 && ($cc -c $cflags $test.c) >> configure.log 2>&1; then
              SHAREDLIBV=libz.$VER$shared_ext
              SHAREDLIBM=libz.$VER1$shared_ext
              LDSHARED=${LDSHARED-"$cc -dynamiclib -install_name $libdir/$SHAREDLIBM -compatibility_version $VER1 -current_version $VER3"}
-             AR="/usr/bin/libtool"
+             if libtool -V 2>&1 | grep Apple > /dev/null; then
+                 AR="libtool"
+             else
+                 AR="/usr/bin/libtool"
+             fi
              ARFLAGS="-o" ;;
   *)             LDSHARED=${LDSHARED-"$cc -shared"} ;;
   esac
@@ -334,7 +324,61 @@ SHAREDLIBM=${SHAREDLIBM-"libz$shared_ext.$VER1"}
 
 echo >> configure.log
 
+# define functions for testing compiler and library characteristics and logging the results
+
+cat > $test.c <<EOF
+#error error
+EOF
+if ($CC -c $CFLAGS $test.c) 2>/dev/null; then
+  try()
+  {
+    show $*
+    test "`( $* ) 2>&1 | tee -a configure.log`" = ""
+  }
+  echo - using any output from compiler to indicate an error >> configure.log
+else
+try()
+{
+  show $*
+  ( $* ) >> configure.log 2>&1
+  ret=$?
+  if test $ret -ne 0; then
+    echo "(exit code "$ret")" >> configure.log
+  fi
+  return $ret
+}
+fi
+
+tryboth()
+{
+  show $*
+  got=`( $* ) 2>&1`
+  ret=$?
+  printf %s "$got" >> configure.log
+  if test $ret -ne 0; then
+    return $ret
+  fi
+  test "$got" = ""
+}
+
+cat > $test.c << EOF
+int foo() { return 0; }
+EOF
+echo "Checking for obsessive-compulsive compiler options..." >> configure.log
+if try $CC -c $CFLAGS $test.c; then
+  :
+else
+  echo "Compiler error reporting is too harsh for $0 (perhaps remove -Werror)." | tee -a configure.log
+  leave 1
+fi
+
+echo >> configure.log
+
 # see if shared library build supported
+cat > $test.c <<EOF
+extern int getchar();
+int hello() {return getchar();}
+EOF
 if test $shared -eq 1; then
   echo Checking for shared library support... | tee -a configure.log
   # we must test in two steps (cc then ld), required at least on SunOS 4.x
@@ -362,8 +406,6 @@ else
   TEST="all teststatic testshared"
 fi
 
-echo >> configure.log
-
 # check for underscores in external names for use by assembler code
 CPP=${CPP-"$CC -E"}
 case $CFLAGS in
@@ -698,35 +740,6 @@ EOF
   fi
 fi
 
-echo >> configure.log
-
-# find a four-byte unsiged integer type for crc calculations
-cat > $test.c <<EOF
-#include <stdio.h>
-#define is32(n,t) for(n=1,k=0;n;n<<=1,k++);if(k==32){puts(t);return 0;}
-int main() {
-    int k;
-    unsigned i;
-    unsigned long l;
-    unsigned short s;
-    is32(i, "unsigned")
-    is32(l, "unsigned long")
-    is32(s, "unsigned short")
-    return 1;
-}
-EOF
-Z_U4=""
-if try $CC $CFLAGS $test.c -o $test && Z_U4=`./$test` && test -n "$Z_U4"; then
-  sed < zconf.h "/#define Z_U4/s/\/\* \.\/configure may/#define Z_U4 $Z_U4   \/* .\/configure put the/" > zconf.temp.h
-  mv zconf.temp.h zconf.h
-  echo "Looking for a four-byte integer type... Found." | tee -a configure.log
-else
-  echo "Looking for a four-byte integer type... Not found." | tee -a configure.log
-fi
-
-# clean up files produced by running the compiler and linker
-rm -f $test.[co] $test $test$shared_ext $test.gcno
-
 # show the results in the log
 echo >> configure.log
 echo ALL = $ALL >> configure.log
@@ -758,9 +771,6 @@ echo mandir = $mandir >> configure.log
 echo prefix = $prefix >> configure.log
 echo sharedlibdir = $sharedlibdir >> configure.log
 echo uname = $uname >> configure.log
-echo -------------------- >> configure.log
-echo >> configure.log
-echo >> configure.log
 
 # udpate Makefile with the configure results
 sed < Makefile.in "
@@ -816,3 +826,6 @@ sed < zlib.pc.in "
 " | sed -e "
 s/\@VERSION\@/$VER/g;
 " > zlib.pc
+
+# done
+leave 0
diff --git a/Source/ZLib/crc32.c b/Source/ZLib/crc32.c
index e2ed675..682225f 100644
--- a/Source/ZLib/crc32.c
+++ b/Source/ZLib/crc32.c
@@ -1,425 +1,425 @@
-/* crc32.c -- compute the CRC-32 of a data stream
- * Copyright (C) 1995-2006, 2010, 2011, 2012 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- *
- * Thanks to Rodney Brown <rbrown64 at csc.com.au> for his contribution of faster
- * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
- * tables for updating the shift register in one step with three exclusive-ors
- * instead of four steps with four exclusive-ors.  This results in about a
- * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
- */
-
-/* @(#) $Id: crc32.c,v 1.9 2012/05/13 12:18:39 drolon Exp $ */
-
-/*
-  Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
-  protection on the static variables used to control the first-use generation
-  of the crc tables.  Therefore, if you #define DYNAMIC_CRC_TABLE, you should
-  first call get_crc_table() to initialize the tables before allowing more than
-  one thread to use crc32().
-
-  DYNAMIC_CRC_TABLE and MAKECRCH can be #defined to write out crc32.h.
- */
-
-#ifdef MAKECRCH
-#  include <stdio.h>
-#  ifndef DYNAMIC_CRC_TABLE
-#    define DYNAMIC_CRC_TABLE
-#  endif /* !DYNAMIC_CRC_TABLE */
-#endif /* MAKECRCH */
-
-#include "zutil.h"      /* for STDC and FAR definitions */
-
-#define local static
-
-/* Definitions for doing the crc four data bytes at a time. */
-#if !defined(NOBYFOUR) && defined(Z_U4)
-#  define BYFOUR
-#endif
-#ifdef BYFOUR
-   local unsigned long crc32_little OF((unsigned long,
-                        const unsigned char FAR *, unsigned));
-   local unsigned long crc32_big OF((unsigned long,
-                        const unsigned char FAR *, unsigned));
-#  define TBLS 8
-#else
-#  define TBLS 1
-#endif /* BYFOUR */
-
-/* Local functions for crc concatenation */
-local unsigned long gf2_matrix_times OF((unsigned long *mat,
-                                         unsigned long vec));
-local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
-local uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2));
-
-
-#ifdef DYNAMIC_CRC_TABLE
-
-local volatile int crc_table_empty = 1;
-local z_crc_t FAR crc_table[TBLS][256];
-local void make_crc_table OF((void));
-#ifdef MAKECRCH
-   local void write_table OF((FILE *, const z_crc_t FAR *));
-#endif /* MAKECRCH */
-/*
-  Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
-  x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
-
-  Polynomials over GF(2) are represented in binary, one bit per coefficient,
-  with the lowest powers in the most significant bit.  Then adding polynomials
-  is just exclusive-or, and multiplying a polynomial by x is a right shift by
-  one.  If we call the above polynomial p, and represent a byte as the
-  polynomial q, also with the lowest power in the most significant bit (so the
-  byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
-  where a mod b means the remainder after dividing a by b.
-
-  This calculation is done using the shift-register method of multiplying and
-  taking the remainder.  The register is initialized to zero, and for each
-  incoming bit, x^32 is added mod p to the register if the bit is a one (where
-  x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
-  x (which is shifting right by one and adding x^32 mod p if the bit shifted
-  out is a one).  We start with the highest power (least significant bit) of
-  q and repeat for all eight bits of q.
-
-  The first table is simply the CRC of all possible eight bit values.  This is
-  all the information needed to generate CRCs on data a byte at a time for all
-  combinations of CRC register values and incoming bytes.  The remaining tables
-  allow for word-at-a-time CRC calculation for both big-endian and little-
-  endian machines, where a word is four bytes.
-*/
-local void make_crc_table()
-{
-    z_crc_t c;
-    int n, k;
-    z_crc_t poly;                       /* polynomial exclusive-or pattern */
-    /* terms of polynomial defining this crc (except x^32): */
-    static volatile int first = 1;      /* flag to limit concurrent making */
-    static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
-
-    /* See if another task is already doing this (not thread-safe, but better
-       than nothing -- significantly reduces duration of vulnerability in
-       case the advice about DYNAMIC_CRC_TABLE is ignored) */
-    if (first) {
-        first = 0;
-
-        /* make exclusive-or pattern from polynomial (0xedb88320UL) */
-        poly = 0;
-        for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++)
-            poly |= (z_crc_t)1 << (31 - p[n]);
-
-        /* generate a crc for every 8-bit value */
-        for (n = 0; n < 256; n++) {
-            c = (z_crc_t)n;
-            for (k = 0; k < 8; k++)
-                c = c & 1 ? poly ^ (c >> 1) : c >> 1;
-            crc_table[0][n] = c;
-        }
-
-#ifdef BYFOUR
-        /* generate crc for each value followed by one, two, and three zeros,
-           and then the byte reversal of those as well as the first table */
-        for (n = 0; n < 256; n++) {
-            c = crc_table[0][n];
-            crc_table[4][n] = ZSWAP32(c);
-            for (k = 1; k < 4; k++) {
-                c = crc_table[0][c & 0xff] ^ (c >> 8);
-                crc_table[k][n] = c;
-                crc_table[k + 4][n] = ZSWAP32(c);
-            }
-        }
-#endif /* BYFOUR */
-
-        crc_table_empty = 0;
-    }
-    else {      /* not first */
-        /* wait for the other guy to finish (not efficient, but rare) */
-        while (crc_table_empty)
-            ;
-    }
-
-#ifdef MAKECRCH
-    /* write out CRC tables to crc32.h */
-    {
-        FILE *out;
-
-        out = fopen("crc32.h", "w");
-        if (out == NULL) return;
-        fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
-        fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
-        fprintf(out, "local const z_crc_t FAR ");
-        fprintf(out, "crc_table[TBLS][256] =\n{\n  {\n");
-        write_table(out, crc_table[0]);
-#  ifdef BYFOUR
-        fprintf(out, "#ifdef BYFOUR\n");
-        for (k = 1; k < 8; k++) {
-            fprintf(out, "  },\n  {\n");
-            write_table(out, crc_table[k]);
-        }
-        fprintf(out, "#endif\n");
-#  endif /* BYFOUR */
-        fprintf(out, "  }\n};\n");
-        fclose(out);
-    }
-#endif /* MAKECRCH */
-}
-
-#ifdef MAKECRCH
-local void write_table(out, table)
-    FILE *out;
-    const z_crc_t FAR *table;
-{
-    int n;
-
-    for (n = 0; n < 256; n++)
-        fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : "    ",
-                (unsigned long)(table[n]),
-                n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
-}
-#endif /* MAKECRCH */
-
-#else /* !DYNAMIC_CRC_TABLE */
-/* ========================================================================
- * Tables of CRC-32s of all single-byte values, made by make_crc_table().
- */
-#include "crc32.h"
-#endif /* DYNAMIC_CRC_TABLE */
-
-/* =========================================================================
- * This function can be used by asm versions of crc32()
- */
-const z_crc_t FAR * ZEXPORT get_crc_table()
-{
-#ifdef DYNAMIC_CRC_TABLE
-    if (crc_table_empty)
-        make_crc_table();
-#endif /* DYNAMIC_CRC_TABLE */
-    return (const z_crc_t FAR *)crc_table;
-}
-
-/* ========================================================================= */
-#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
-#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
-
-/* ========================================================================= */
-unsigned long ZEXPORT crc32(crc, buf, len)
-    unsigned long crc;
-    const unsigned char FAR *buf;
-    uInt len;
-{
-    if (buf == Z_NULL) return 0UL;
-
-#ifdef DYNAMIC_CRC_TABLE
-    if (crc_table_empty)
-        make_crc_table();
-#endif /* DYNAMIC_CRC_TABLE */
-
-#ifdef BYFOUR
-    if (sizeof(void *) == sizeof(ptrdiff_t)) {
-        z_crc_t endian;
-
-        endian = 1;
-        if (*((unsigned char *)(&endian)))
-            return crc32_little(crc, buf, len);
-        else
-            return crc32_big(crc, buf, len);
-    }
-#endif /* BYFOUR */
-    crc = crc ^ 0xffffffffUL;
-    while (len >= 8) {
-        DO8;
-        len -= 8;
-    }
-    if (len) do {
-        DO1;
-    } while (--len);
-    return crc ^ 0xffffffffUL;
-}
-
-#ifdef BYFOUR
-
-/* ========================================================================= */
-#define DOLIT4 c ^= *buf4++; \
-        c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
-            crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
-#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
-
-/* ========================================================================= */
-local unsigned long crc32_little(crc, buf, len)
-    unsigned long crc;
-    const unsigned char FAR *buf;
-    unsigned len;
-{
-    register z_crc_t c;
-    register const z_crc_t FAR *buf4;
-
-    c = (z_crc_t)crc;
-    c = ~c;
-    while (len && ((ptrdiff_t)buf & 3)) {
-        c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
-        len--;
-    }
-
-    buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
-    while (len >= 32) {
-        DOLIT32;
-        len -= 32;
-    }
-    while (len >= 4) {
-        DOLIT4;
-        len -= 4;
-    }
-    buf = (const unsigned char FAR *)buf4;
-
-    if (len) do {
-        c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
-    } while (--len);
-    c = ~c;
-    return (unsigned long)c;
-}
-
-/* ========================================================================= */
-#define DOBIG4 c ^= *++buf4; \
-        c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
-            crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
-#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
-
-/* ========================================================================= */
-local unsigned long crc32_big(crc, buf, len)
-    unsigned long crc;
-    const unsigned char FAR *buf;
-    unsigned len;
-{
-    register z_crc_t c;
-    register const z_crc_t FAR *buf4;
-
-    c = ZSWAP32((z_crc_t)crc);
-    c = ~c;
-    while (len && ((ptrdiff_t)buf & 3)) {
-        c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
-        len--;
-    }
-
-    buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
-    buf4--;
-    while (len >= 32) {
-        DOBIG32;
-        len -= 32;
-    }
-    while (len >= 4) {
-        DOBIG4;
-        len -= 4;
-    }
-    buf4++;
-    buf = (const unsigned char FAR *)buf4;
-
-    if (len) do {
-        c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
-    } while (--len);
-    c = ~c;
-    return (unsigned long)(ZSWAP32(c));
-}
-
-#endif /* BYFOUR */
-
-#define GF2_DIM 32      /* dimension of GF(2) vectors (length of CRC) */
-
-/* ========================================================================= */
-local unsigned long gf2_matrix_times(mat, vec)
-    unsigned long *mat;
-    unsigned long vec;
-{
-    unsigned long sum;
-
-    sum = 0;
-    while (vec) {
-        if (vec & 1)
-            sum ^= *mat;
-        vec >>= 1;
-        mat++;
-    }
-    return sum;
-}
-
-/* ========================================================================= */
-local void gf2_matrix_square(square, mat)
-    unsigned long *square;
-    unsigned long *mat;
-{
-    int n;
-
-    for (n = 0; n < GF2_DIM; n++)
-        square[n] = gf2_matrix_times(mat, mat[n]);
-}
-
-/* ========================================================================= */
-local uLong crc32_combine_(crc1, crc2, len2)
-    uLong crc1;
-    uLong crc2;
-    z_off64_t len2;
-{
-    int n;
-    unsigned long row;
-    unsigned long even[GF2_DIM];    /* even-power-of-two zeros operator */
-    unsigned long odd[GF2_DIM];     /* odd-power-of-two zeros operator */
-
-    /* degenerate case (also disallow negative lengths) */
-    if (len2 <= 0)
-        return crc1;
-
-    /* put operator for one zero bit in odd */
-    odd[0] = 0xedb88320UL;          /* CRC-32 polynomial */
-    row = 1;
-    for (n = 1; n < GF2_DIM; n++) {
-        odd[n] = row;
-        row <<= 1;
-    }
-
-    /* put operator for two zero bits in even */
-    gf2_matrix_square(even, odd);
-
-    /* put operator for four zero bits in odd */
-    gf2_matrix_square(odd, even);
-
-    /* apply len2 zeros to crc1 (first square will put the operator for one
-       zero byte, eight zero bits, in even) */
-    do {
-        /* apply zeros operator for this bit of len2 */
-        gf2_matrix_square(even, odd);
-        if (len2 & 1)
-            crc1 = gf2_matrix_times(even, crc1);
-        len2 >>= 1;
-
-        /* if no more bits set, then done */
-        if (len2 == 0)
-            break;
-
-        /* another iteration of the loop with odd and even swapped */
-        gf2_matrix_square(odd, even);
-        if (len2 & 1)
-            crc1 = gf2_matrix_times(odd, crc1);
-        len2 >>= 1;
-
-        /* if no more bits set, then done */
-    } while (len2 != 0);
-
-    /* return combined crc */
-    crc1 ^= crc2;
-    return crc1;
-}
-
-/* ========================================================================= */
-uLong ZEXPORT crc32_combine(crc1, crc2, len2)
-    uLong crc1;
-    uLong crc2;
-    z_off_t len2;
-{
-    return crc32_combine_(crc1, crc2, len2);
-}
-
-uLong ZEXPORT crc32_combine64(crc1, crc2, len2)
-    uLong crc1;
-    uLong crc2;
-    z_off64_t len2;
-{
-    return crc32_combine_(crc1, crc2, len2);
-}
+/* crc32.c -- compute the CRC-32 of a data stream
+ * Copyright (C) 1995-2006, 2010, 2011, 2012 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Thanks to Rodney Brown <rbrown64 at csc.com.au> for his contribution of faster
+ * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
+ * tables for updating the shift register in one step with three exclusive-ors
+ * instead of four steps with four exclusive-ors.  This results in about a
+ * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
+ */
+
+/* @(#) $Id: crc32.c,v 1.10 2013/05/10 17:22:52 drolon Exp $ */
+
+/*
+  Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
+  protection on the static variables used to control the first-use generation
+  of the crc tables.  Therefore, if you #define DYNAMIC_CRC_TABLE, you should
+  first call get_crc_table() to initialize the tables before allowing more than
+  one thread to use crc32().
+
+  DYNAMIC_CRC_TABLE and MAKECRCH can be #defined to write out crc32.h.
+ */
+
+#ifdef MAKECRCH
+#  include <stdio.h>
+#  ifndef DYNAMIC_CRC_TABLE
+#    define DYNAMIC_CRC_TABLE
+#  endif /* !DYNAMIC_CRC_TABLE */
+#endif /* MAKECRCH */
+
+#include "zutil.h"      /* for STDC and FAR definitions */
+
+#define local static
+
+/* Definitions for doing the crc four data bytes at a time. */
+#if !defined(NOBYFOUR) && defined(Z_U4)
+#  define BYFOUR
+#endif
+#ifdef BYFOUR
+   local unsigned long crc32_little OF((unsigned long,
+                        const unsigned char FAR *, unsigned));
+   local unsigned long crc32_big OF((unsigned long,
+                        const unsigned char FAR *, unsigned));
+#  define TBLS 8
+#else
+#  define TBLS 1
+#endif /* BYFOUR */
+
+/* Local functions for crc concatenation */
+local unsigned long gf2_matrix_times OF((unsigned long *mat,
+                                         unsigned long vec));
+local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
+local uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2));
+
+
+#ifdef DYNAMIC_CRC_TABLE
+
+local volatile int crc_table_empty = 1;
+local z_crc_t FAR crc_table[TBLS][256];
+local void make_crc_table OF((void));
+#ifdef MAKECRCH
+   local void write_table OF((FILE *, const z_crc_t FAR *));
+#endif /* MAKECRCH */
+/*
+  Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
+  x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
+
+  Polynomials over GF(2) are represented in binary, one bit per coefficient,
+  with the lowest powers in the most significant bit.  Then adding polynomials
+  is just exclusive-or, and multiplying a polynomial by x is a right shift by
+  one.  If we call the above polynomial p, and represent a byte as the
+  polynomial q, also with the lowest power in the most significant bit (so the
+  byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
+  where a mod b means the remainder after dividing a by b.
+
+  This calculation is done using the shift-register method of multiplying and
+  taking the remainder.  The register is initialized to zero, and for each
+  incoming bit, x^32 is added mod p to the register if the bit is a one (where
+  x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
+  x (which is shifting right by one and adding x^32 mod p if the bit shifted
+  out is a one).  We start with the highest power (least significant bit) of
+  q and repeat for all eight bits of q.
+
+  The first table is simply the CRC of all possible eight bit values.  This is
+  all the information needed to generate CRCs on data a byte at a time for all
+  combinations of CRC register values and incoming bytes.  The remaining tables
+  allow for word-at-a-time CRC calculation for both big-endian and little-
+  endian machines, where a word is four bytes.
+*/
+local void make_crc_table()
+{
+    z_crc_t c;
+    int n, k;
+    z_crc_t poly;                       /* polynomial exclusive-or pattern */
+    /* terms of polynomial defining this crc (except x^32): */
+    static volatile int first = 1;      /* flag to limit concurrent making */
+    static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
+
+    /* See if another task is already doing this (not thread-safe, but better
+       than nothing -- significantly reduces duration of vulnerability in
+       case the advice about DYNAMIC_CRC_TABLE is ignored) */
+    if (first) {
+        first = 0;
+
+        /* make exclusive-or pattern from polynomial (0xedb88320UL) */
+        poly = 0;
+        for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++)
+            poly |= (z_crc_t)1 << (31 - p[n]);
+
+        /* generate a crc for every 8-bit value */
+        for (n = 0; n < 256; n++) {
+            c = (z_crc_t)n;
+            for (k = 0; k < 8; k++)
+                c = c & 1 ? poly ^ (c >> 1) : c >> 1;
+            crc_table[0][n] = c;
+        }
+
+#ifdef BYFOUR
+        /* generate crc for each value followed by one, two, and three zeros,
+           and then the byte reversal of those as well as the first table */
+        for (n = 0; n < 256; n++) {
+            c = crc_table[0][n];
+            crc_table[4][n] = ZSWAP32(c);
+            for (k = 1; k < 4; k++) {
+                c = crc_table[0][c & 0xff] ^ (c >> 8);
+                crc_table[k][n] = c;
+                crc_table[k + 4][n] = ZSWAP32(c);
+            }
+        }
+#endif /* BYFOUR */
+
+        crc_table_empty = 0;
+    }
+    else {      /* not first */
+        /* wait for the other guy to finish (not efficient, but rare) */
+        while (crc_table_empty)
+            ;
+    }
+
+#ifdef MAKECRCH
+    /* write out CRC tables to crc32.h */
+    {
+        FILE *out;
+
+        out = fopen("crc32.h", "w");
+        if (out == NULL) return;
+        fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
+        fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
+        fprintf(out, "local const z_crc_t FAR ");
+        fprintf(out, "crc_table[TBLS][256] =\n{\n  {\n");
+        write_table(out, crc_table[0]);
+#  ifdef BYFOUR
+        fprintf(out, "#ifdef BYFOUR\n");
+        for (k = 1; k < 8; k++) {
+            fprintf(out, "  },\n  {\n");
+            write_table(out, crc_table[k]);
+        }
+        fprintf(out, "#endif\n");
+#  endif /* BYFOUR */
+        fprintf(out, "  }\n};\n");
+        fclose(out);
+    }
+#endif /* MAKECRCH */
+}
+
+#ifdef MAKECRCH
+local void write_table(out, table)
+    FILE *out;
+    const z_crc_t FAR *table;
+{
+    int n;
+
+    for (n = 0; n < 256; n++)
+        fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : "    ",
+                (unsigned long)(table[n]),
+                n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
+}
+#endif /* MAKECRCH */
+
+#else /* !DYNAMIC_CRC_TABLE */
+/* ========================================================================
+ * Tables of CRC-32s of all single-byte values, made by make_crc_table().
+ */
+#include "crc32.h"
+#endif /* DYNAMIC_CRC_TABLE */
+
+/* =========================================================================
+ * This function can be used by asm versions of crc32()
+ */
+const z_crc_t FAR * ZEXPORT get_crc_table()
+{
+#ifdef DYNAMIC_CRC_TABLE
+    if (crc_table_empty)
+        make_crc_table();
+#endif /* DYNAMIC_CRC_TABLE */
+    return (const z_crc_t FAR *)crc_table;
+}
+
+/* ========================================================================= */
+#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
+#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
+
+/* ========================================================================= */
+unsigned long ZEXPORT crc32(crc, buf, len)
+    unsigned long crc;
+    const unsigned char FAR *buf;
+    uInt len;
+{
+    if (buf == Z_NULL) return 0UL;
+
+#ifdef DYNAMIC_CRC_TABLE
+    if (crc_table_empty)
+        make_crc_table();
+#endif /* DYNAMIC_CRC_TABLE */
+
+#ifdef BYFOUR
+    if (sizeof(void *) == sizeof(ptrdiff_t)) {
+        z_crc_t endian;
+
+        endian = 1;
+        if (*((unsigned char *)(&endian)))
+            return crc32_little(crc, buf, len);
+        else
+            return crc32_big(crc, buf, len);
+    }
+#endif /* BYFOUR */
+    crc = crc ^ 0xffffffffUL;
+    while (len >= 8) {
+        DO8;
+        len -= 8;
+    }
+    if (len) do {
+        DO1;
+    } while (--len);
+    return crc ^ 0xffffffffUL;
+}
+
+#ifdef BYFOUR
+
+/* ========================================================================= */
+#define DOLIT4 c ^= *buf4++; \
+        c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
+            crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
+#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
+
+/* ========================================================================= */
+local unsigned long crc32_little(crc, buf, len)
+    unsigned long crc;
+    const unsigned char FAR *buf;
+    unsigned len;
+{
+    register z_crc_t c;
+    register const z_crc_t FAR *buf4;
+
+    c = (z_crc_t)crc;
+    c = ~c;
+    while (len && ((ptrdiff_t)buf & 3)) {
+        c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
+        len--;
+    }
+
+    buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
+    while (len >= 32) {
+        DOLIT32;
+        len -= 32;
+    }
+    while (len >= 4) {
+        DOLIT4;
+        len -= 4;
+    }
+    buf = (const unsigned char FAR *)buf4;
+
+    if (len) do {
+        c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
+    } while (--len);
+    c = ~c;
+    return (unsigned long)c;
+}
+
+/* ========================================================================= */
+#define DOBIG4 c ^= *++buf4; \
+        c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
+            crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
+#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
+
+/* ========================================================================= */
+local unsigned long crc32_big(crc, buf, len)
+    unsigned long crc;
+    const unsigned char FAR *buf;
+    unsigned len;
+{
+    register z_crc_t c;
+    register const z_crc_t FAR *buf4;
+
+    c = ZSWAP32((z_crc_t)crc);
+    c = ~c;
+    while (len && ((ptrdiff_t)buf & 3)) {
+        c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
+        len--;
+    }
+
+    buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
+    buf4--;
+    while (len >= 32) {
+        DOBIG32;
+        len -= 32;
+    }
+    while (len >= 4) {
+        DOBIG4;
+        len -= 4;
+    }
+    buf4++;
+    buf = (const unsigned char FAR *)buf4;
+
+    if (len) do {
+        c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
+    } while (--len);
+    c = ~c;
+    return (unsigned long)(ZSWAP32(c));
+}
+
+#endif /* BYFOUR */
+
+#define GF2_DIM 32      /* dimension of GF(2) vectors (length of CRC) */
+
+/* ========================================================================= */
+local unsigned long gf2_matrix_times(mat, vec)
+    unsigned long *mat;
+    unsigned long vec;
+{
+    unsigned long sum;
+
+    sum = 0;
+    while (vec) {
+        if (vec & 1)
+            sum ^= *mat;
+        vec >>= 1;
+        mat++;
+    }
+    return sum;
+}
+
+/* ========================================================================= */
+local void gf2_matrix_square(square, mat)
+    unsigned long *square;
+    unsigned long *mat;
+{
+    int n;
+
+    for (n = 0; n < GF2_DIM; n++)
+        square[n] = gf2_matrix_times(mat, mat[n]);
+}
+
+/* ========================================================================= */
+local uLong crc32_combine_(crc1, crc2, len2)
+    uLong crc1;
+    uLong crc2;
+    z_off64_t len2;
+{
+    int n;
+    unsigned long row;
+    unsigned long even[GF2_DIM];    /* even-power-of-two zeros operator */
+    unsigned long odd[GF2_DIM];     /* odd-power-of-two zeros operator */
+
+    /* degenerate case (also disallow negative lengths) */
+    if (len2 <= 0)
+        return crc1;
+
+    /* put operator for one zero bit in odd */
+    odd[0] = 0xedb88320UL;          /* CRC-32 polynomial */
+    row = 1;
+    for (n = 1; n < GF2_DIM; n++) {
+        odd[n] = row;
+        row <<= 1;
+    }
+
+    /* put operator for two zero bits in even */
+    gf2_matrix_square(even, odd);
+
+    /* put operator for four zero bits in odd */
+    gf2_matrix_square(odd, even);
+
+    /* apply len2 zeros to crc1 (first square will put the operator for one
+       zero byte, eight zero bits, in even) */
+    do {
+        /* apply zeros operator for this bit of len2 */
+        gf2_matrix_square(even, odd);
+        if (len2 & 1)
+            crc1 = gf2_matrix_times(even, crc1);
+        len2 >>= 1;
+
+        /* if no more bits set, then done */
+        if (len2 == 0)
+            break;
+
+        /* another iteration of the loop with odd and even swapped */
+        gf2_matrix_square(odd, even);
+        if (len2 & 1)
+            crc1 = gf2_matrix_times(odd, crc1);
+        len2 >>= 1;
+
+        /* if no more bits set, then done */
+    } while (len2 != 0);
+
+    /* return combined crc */
+    crc1 ^= crc2;
+    return crc1;
+}
+
+/* ========================================================================= */
+uLong ZEXPORT crc32_combine(crc1, crc2, len2)
+    uLong crc1;
+    uLong crc2;
+    z_off_t len2;
+{
+    return crc32_combine_(crc1, crc2, len2);
+}
+
+uLong ZEXPORT crc32_combine64(crc1, crc2, len2)
+    uLong crc1;
+    uLong crc2;
+    z_off64_t len2;
+{
+    return crc32_combine_(crc1, crc2, len2);
+}
diff --git a/Source/ZLib/deflate.c b/Source/ZLib/deflate.c
index 3f3063d..aa0b4e6 100644
--- a/Source/ZLib/deflate.c
+++ b/Source/ZLib/deflate.c
@@ -1,1965 +1,1967 @@
-/* deflate.c -- compress data using the deflation algorithm
- * Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/*
- *  ALGORITHM
- *
- *      The "deflation" process depends on being able to identify portions
- *      of the input text which are identical to earlier input (within a
- *      sliding window trailing behind the input currently being processed).
- *
- *      The most straightforward technique turns out to be the fastest for
- *      most input files: try all possible matches and select the longest.
- *      The key feature of this algorithm is that insertions into the string
- *      dictionary are very simple and thus fast, and deletions are avoided
- *      completely. Insertions are performed at each input character, whereas
- *      string matches are performed only when the previous match ends. So it
- *      is preferable to spend more time in matches to allow very fast string
- *      insertions and avoid deletions. The matching algorithm for small
- *      strings is inspired from that of Rabin & Karp. A brute force approach
- *      is used to find longer strings when a small match has been found.
- *      A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
- *      (by Leonid Broukhis).
- *         A previous version of this file used a more sophisticated algorithm
- *      (by Fiala and Greene) which is guaranteed to run in linear amortized
- *      time, but has a larger average cost, uses more memory and is patented.
- *      However the F&G algorithm may be faster for some highly redundant
- *      files if the parameter max_chain_length (described below) is too large.
- *
- *  ACKNOWLEDGEMENTS
- *
- *      The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
- *      I found it in 'freeze' written by Leonid Broukhis.
- *      Thanks to many people for bug reports and testing.
- *
- *  REFERENCES
- *
- *      Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
- *      Available in http://tools.ietf.org/html/rfc1951
- *
- *      A description of the Rabin and Karp algorithm is given in the book
- *         "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
- *
- *      Fiala,E.R., and Greene,D.H.
- *         Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
- *
- */
-
-/* @(#) $Id: deflate.c,v 1.9 2012/05/13 12:18:39 drolon Exp $ */
-
-#include "deflate.h"
-
-const char deflate_copyright[] =
-   " deflate 1.2.7 Copyright 1995-2012 Jean-loup Gailly and Mark Adler ";
-/*
-  If you use the zlib library in a product, an acknowledgment is welcome
-  in the documentation of your product. If for some reason you cannot
-  include such an acknowledgment, I would appreciate that you keep this
-  copyright string in the executable of your product.
- */
-
-/* ===========================================================================
- *  Function prototypes.
- */
-typedef enum {
-    need_more,      /* block not completed, need more input or more output */
-    block_done,     /* block flush performed */
-    finish_started, /* finish started, need only more output at next deflate */
-    finish_done     /* finish done, accept no more input or output */
-} block_state;
-
-typedef block_state (*compress_func) OF((deflate_state *s, int flush));
-/* Compression function. Returns the block state after the call. */
-
-local void fill_window    OF((deflate_state *s));
-local block_state deflate_stored OF((deflate_state *s, int flush));
-local block_state deflate_fast   OF((deflate_state *s, int flush));
-#ifndef FASTEST
-local block_state deflate_slow   OF((deflate_state *s, int flush));
-#endif
-local block_state deflate_rle    OF((deflate_state *s, int flush));
-local block_state deflate_huff   OF((deflate_state *s, int flush));
-local void lm_init        OF((deflate_state *s));
-local void putShortMSB    OF((deflate_state *s, uInt b));
-local void flush_pending  OF((z_streamp strm));
-local int read_buf        OF((z_streamp strm, Bytef *buf, unsigned size));
-#ifdef ASMV
-      void match_init OF((void)); /* asm code initialization */
-      uInt longest_match  OF((deflate_state *s, IPos cur_match));
-#else
-local uInt longest_match  OF((deflate_state *s, IPos cur_match));
-#endif
-
-#ifdef DEBUG
-local  void check_match OF((deflate_state *s, IPos start, IPos match,
-                            int length));
-#endif
-
-/* ===========================================================================
- * Local data
- */
-
-#define NIL 0
-/* Tail of hash chains */
-
-#ifndef TOO_FAR
-#  define TOO_FAR 4096
-#endif
-/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
-
-/* Values for max_lazy_match, good_match and max_chain_length, depending on
- * the desired pack level (0..9). The values given below have been tuned to
- * exclude worst case performance for pathological files. Better values may be
- * found for specific files.
- */
-typedef struct config_s {
-   ush good_length; /* reduce lazy search above this match length */
-   ush max_lazy;    /* do not perform lazy search above this match length */
-   ush nice_length; /* quit search above this match length */
-   ush max_chain;
-   compress_func func;
-} config;
-
-#ifdef FASTEST
-local const config configuration_table[2] = {
-/*      good lazy nice chain */
-/* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */
-/* 1 */ {4,    4,  8,    4, deflate_fast}}; /* max speed, no lazy matches */
-#else
-local const config configuration_table[10] = {
-/*      good lazy nice chain */
-/* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */
-/* 1 */ {4,    4,  8,    4, deflate_fast}, /* max speed, no lazy matches */
-/* 2 */ {4,    5, 16,    8, deflate_fast},
-/* 3 */ {4,    6, 32,   32, deflate_fast},
-
-/* 4 */ {4,    4, 16,   16, deflate_slow},  /* lazy matches */
-/* 5 */ {8,   16, 32,   32, deflate_slow},
-/* 6 */ {8,   16, 128, 128, deflate_slow},
-/* 7 */ {8,   32, 128, 256, deflate_slow},
-/* 8 */ {32, 128, 258, 1024, deflate_slow},
-/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */
-#endif
-
-/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
- * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
- * meaning.
- */
-
-#define EQUAL 0
-/* result of memcmp for equal strings */
-
-#ifndef NO_DUMMY_DECL
-struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
-#endif
-
-/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */
-#define RANK(f) (((f) << 1) - ((f) > 4 ? 9 : 0))
-
-/* ===========================================================================
- * Update a hash value with the given input byte
- * IN  assertion: all calls to to UPDATE_HASH are made with consecutive
- *    input characters, so that a running hash key can be computed from the
- *    previous key instead of complete recalculation each time.
- */
-#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
-
-
-/* ===========================================================================
- * Insert string str in the dictionary and set match_head to the previous head
- * of the hash chain (the most recent string with same hash key). Return
- * the previous length of the hash chain.
- * If this file is compiled with -DFASTEST, the compression level is forced
- * to 1, and no hash chains are maintained.
- * IN  assertion: all calls to to INSERT_STRING are made with consecutive
- *    input characters and the first MIN_MATCH bytes of str are valid
- *    (except for the last MIN_MATCH-1 bytes of the input file).
- */
-#ifdef FASTEST
-#define INSERT_STRING(s, str, match_head) \
-   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
-    match_head = s->head[s->ins_h], \
-    s->head[s->ins_h] = (Pos)(str))
-#else
-#define INSERT_STRING(s, str, match_head) \
-   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
-    match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \
-    s->head[s->ins_h] = (Pos)(str))
-#endif
-
-/* ===========================================================================
- * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
- * prev[] will be initialized on the fly.
- */
-#define CLEAR_HASH(s) \
-    s->head[s->hash_size-1] = NIL; \
-    zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
-
-/* ========================================================================= */
-int ZEXPORT deflateInit_(strm, level, version, stream_size)
-    z_streamp strm;
-    int level;
-    const char *version;
-    int stream_size;
-{
-    return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
-                         Z_DEFAULT_STRATEGY, version, stream_size);
-    /* To do: ignore strm->next_in if we use it as window */
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
-                  version, stream_size)
-    z_streamp strm;
-    int  level;
-    int  method;
-    int  windowBits;
-    int  memLevel;
-    int  strategy;
-    const char *version;
-    int stream_size;
-{
-    deflate_state *s;
-    int wrap = 1;
-    static const char my_version[] = ZLIB_VERSION;
-
-    ushf *overlay;
-    /* We overlay pending_buf and d_buf+l_buf. This works since the average
-     * output size for (length,distance) codes is <= 24 bits.
-     */
-
-    if (version == Z_NULL || version[0] != my_version[0] ||
-        stream_size != sizeof(z_stream)) {
-        return Z_VERSION_ERROR;
-    }
-    if (strm == Z_NULL) return Z_STREAM_ERROR;
-
-    strm->msg = Z_NULL;
-    if (strm->zalloc == (alloc_func)0) {
-#ifdef Z_SOLO
-        return Z_STREAM_ERROR;
-#else
-        strm->zalloc = zcalloc;
-        strm->opaque = (voidpf)0;
-#endif
-    }
-    if (strm->zfree == (free_func)0)
-#ifdef Z_SOLO
-        return Z_STREAM_ERROR;
-#else
-        strm->zfree = zcfree;
-#endif
-
-#ifdef FASTEST
-    if (level != 0) level = 1;
-#else
-    if (level == Z_DEFAULT_COMPRESSION) level = 6;
-#endif
-
-    if (windowBits < 0) { /* suppress zlib wrapper */
-        wrap = 0;
-        windowBits = -windowBits;
-    }
-#ifdef GZIP
-    else if (windowBits > 15) {
-        wrap = 2;       /* write gzip wrapper instead */
-        windowBits -= 16;
-    }
-#endif
-    if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
-        windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
-        strategy < 0 || strategy > Z_FIXED) {
-        return Z_STREAM_ERROR;
-    }
-    if (windowBits == 8) windowBits = 9;  /* until 256-byte window bug fixed */
-    s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
-    if (s == Z_NULL) return Z_MEM_ERROR;
-    strm->state = (struct internal_state FAR *)s;
-    s->strm = strm;
-
-    s->wrap = wrap;
-    s->gzhead = Z_NULL;
-    s->w_bits = windowBits;
-    s->w_size = 1 << s->w_bits;
-    s->w_mask = s->w_size - 1;
-
-    s->hash_bits = memLevel + 7;
-    s->hash_size = 1 << s->hash_bits;
-    s->hash_mask = s->hash_size - 1;
-    s->hash_shift =  ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
-
-    s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
-    s->prev   = (Posf *)  ZALLOC(strm, s->w_size, sizeof(Pos));
-    s->head   = (Posf *)  ZALLOC(strm, s->hash_size, sizeof(Pos));
-
-    s->high_water = 0;      /* nothing written to s->window yet */
-
-    s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
-
-    overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
-    s->pending_buf = (uchf *) overlay;
-    s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
-
-    if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
-        s->pending_buf == Z_NULL) {
-        s->status = FINISH_STATE;
-        strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
-        deflateEnd (strm);
-        return Z_MEM_ERROR;
-    }
-    s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
-    s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
-
-    s->level = level;
-    s->strategy = strategy;
-    s->method = (Byte)method;
-
-    return deflateReset(strm);
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
-    z_streamp strm;
-    const Bytef *dictionary;
-    uInt  dictLength;
-{
-    deflate_state *s;
-    uInt str, n;
-    int wrap;
-    unsigned avail;
-    unsigned char *next;
-
-    if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL)
-        return Z_STREAM_ERROR;
-    s = strm->state;
-    wrap = s->wrap;
-    if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead)
-        return Z_STREAM_ERROR;
-
-    /* when using zlib wrappers, compute Adler-32 for provided dictionary */
-    if (wrap == 1)
-        strm->adler = adler32(strm->adler, dictionary, dictLength);
-    s->wrap = 0;                    /* avoid computing Adler-32 in read_buf */
-
-    /* if dictionary would fill window, just replace the history */
-    if (dictLength >= s->w_size) {
-        if (wrap == 0) {            /* already empty otherwise */
-            CLEAR_HASH(s);
-            s->strstart = 0;
-            s->block_start = 0L;
-            s->insert = 0;
-        }
-        dictionary += dictLength - s->w_size;  /* use the tail */
-        dictLength = s->w_size;
-    }
-
-    /* insert dictionary into window and hash */
-    avail = strm->avail_in;
-    next = strm->next_in;
-    strm->avail_in = dictLength;
-    strm->next_in = (Bytef *)dictionary;
-    fill_window(s);
-    while (s->lookahead >= MIN_MATCH) {
-        str = s->strstart;
-        n = s->lookahead - (MIN_MATCH-1);
-        do {
-            UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);
-#ifndef FASTEST
-            s->prev[str & s->w_mask] = s->head[s->ins_h];
-#endif
-            s->head[s->ins_h] = (Pos)str;
-            str++;
-        } while (--n);
-        s->strstart = str;
-        s->lookahead = MIN_MATCH-1;
-        fill_window(s);
-    }
-    s->strstart += s->lookahead;
-    s->block_start = (long)s->strstart;
-    s->insert = s->lookahead;
-    s->lookahead = 0;
-    s->match_length = s->prev_length = MIN_MATCH-1;
-    s->match_available = 0;
-    strm->next_in = next;
-    strm->avail_in = avail;
-    s->wrap = wrap;
-    return Z_OK;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateResetKeep (strm)
-    z_streamp strm;
-{
-    deflate_state *s;
-
-    if (strm == Z_NULL || strm->state == Z_NULL ||
-        strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) {
-        return Z_STREAM_ERROR;
-    }
-
-    strm->total_in = strm->total_out = 0;
-    strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
-    strm->data_type = Z_UNKNOWN;
-
-    s = (deflate_state *)strm->state;
-    s->pending = 0;
-    s->pending_out = s->pending_buf;
-
-    if (s->wrap < 0) {
-        s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */
-    }
-    s->status = s->wrap ? INIT_STATE : BUSY_STATE;
-    strm->adler =
-#ifdef GZIP
-        s->wrap == 2 ? crc32(0L, Z_NULL, 0) :
-#endif
-        adler32(0L, Z_NULL, 0);
-    s->last_flush = Z_NO_FLUSH;
-
-    _tr_init(s);
-
-    return Z_OK;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateReset (strm)
-    z_streamp strm;
-{
-    int ret;
-
-    ret = deflateResetKeep(strm);
-    if (ret == Z_OK)
-        lm_init(strm->state);
-    return ret;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateSetHeader (strm, head)
-    z_streamp strm;
-    gz_headerp head;
-{
-    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
-    if (strm->state->wrap != 2) return Z_STREAM_ERROR;
-    strm->state->gzhead = head;
-    return Z_OK;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflatePending (strm, pending, bits)
-    unsigned *pending;
-    int *bits;
-    z_streamp strm;
-{
-    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
-    if (pending != Z_NULL)
-        *pending = strm->state->pending;
-    if (bits != Z_NULL)
-        *bits = strm->state->bi_valid;
-    return Z_OK;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflatePrime (strm, bits, value)
-    z_streamp strm;
-    int bits;
-    int value;
-{
-    deflate_state *s;
-    int put;
-
-    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
-    s = strm->state;
-    if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3))
-        return Z_BUF_ERROR;
-    do {
-        put = Buf_size - s->bi_valid;
-        if (put > bits)
-            put = bits;
-        s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid);
-        s->bi_valid += put;
-        _tr_flush_bits(s);
-        value >>= put;
-        bits -= put;
-    } while (bits);
-    return Z_OK;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateParams(strm, level, strategy)
-    z_streamp strm;
-    int level;
-    int strategy;
-{
-    deflate_state *s;
-    compress_func func;
-    int err = Z_OK;
-
-    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
-    s = strm->state;
-
-#ifdef FASTEST
-    if (level != 0) level = 1;
-#else
-    if (level == Z_DEFAULT_COMPRESSION) level = 6;
-#endif
-    if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) {
-        return Z_STREAM_ERROR;
-    }
-    func = configuration_table[s->level].func;
-
-    if ((strategy != s->strategy || func != configuration_table[level].func) &&
-        strm->total_in != 0) {
-        /* Flush the last buffer: */
-        err = deflate(strm, Z_BLOCK);
-    }
-    if (s->level != level) {
-        s->level = level;
-        s->max_lazy_match   = configuration_table[level].max_lazy;
-        s->good_match       = configuration_table[level].good_length;
-        s->nice_match       = configuration_table[level].nice_length;
-        s->max_chain_length = configuration_table[level].max_chain;
-    }
-    s->strategy = strategy;
-    return err;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
-    z_streamp strm;
-    int good_length;
-    int max_lazy;
-    int nice_length;
-    int max_chain;
-{
-    deflate_state *s;
-
-    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
-    s = strm->state;
-    s->good_match = good_length;
-    s->max_lazy_match = max_lazy;
-    s->nice_match = nice_length;
-    s->max_chain_length = max_chain;
-    return Z_OK;
-}
-
-/* =========================================================================
- * For the default windowBits of 15 and memLevel of 8, this function returns
- * a close to exact, as well as small, upper bound on the compressed size.
- * They are coded as constants here for a reason--if the #define's are
- * changed, then this function needs to be changed as well.  The return
- * value for 15 and 8 only works for those exact settings.
- *
- * For any setting other than those defaults for windowBits and memLevel,
- * the value returned is a conservative worst case for the maximum expansion
- * resulting from using fixed blocks instead of stored blocks, which deflate
- * can emit on compressed data for some combinations of the parameters.
- *
- * This function could be more sophisticated to provide closer upper bounds for
- * every combination of windowBits and memLevel.  But even the conservative
- * upper bound of about 14% expansion does not seem onerous for output buffer
- * allocation.
- */
-uLong ZEXPORT deflateBound(strm, sourceLen)
-    z_streamp strm;
-    uLong sourceLen;
-{
-    deflate_state *s;
-    uLong complen, wraplen;
-    Bytef *str;
-
-    /* conservative upper bound for compressed data */
-    complen = sourceLen +
-              ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5;
-
-    /* if can't get parameters, return conservative bound plus zlib wrapper */
-    if (strm == Z_NULL || strm->state == Z_NULL)
-        return complen + 6;
-
-    /* compute wrapper length */
-    s = strm->state;
-    switch (s->wrap) {
-    case 0:                                 /* raw deflate */
-        wraplen = 0;
-        break;
-    case 1:                                 /* zlib wrapper */
-        wraplen = 6 + (s->strstart ? 4 : 0);
-        break;
-    case 2:                                 /* gzip wrapper */
-        wraplen = 18;
-        if (s->gzhead != Z_NULL) {          /* user-supplied gzip header */
-            if (s->gzhead->extra != Z_NULL)
-                wraplen += 2 + s->gzhead->extra_len;
-            str = s->gzhead->name;
-            if (str != Z_NULL)
-                do {
-                    wraplen++;
-                } while (*str++);
-            str = s->gzhead->comment;
-            if (str != Z_NULL)
-                do {
-                    wraplen++;
-                } while (*str++);
-            if (s->gzhead->hcrc)
-                wraplen += 2;
-        }
-        break;
-    default:                                /* for compiler happiness */
-        wraplen = 6;
-    }
-
-    /* if not default parameters, return conservative bound */
-    if (s->w_bits != 15 || s->hash_bits != 8 + 7)
-        return complen + wraplen;
-
-    /* default settings: return tight bound for that case */
-    return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
-           (sourceLen >> 25) + 13 - 6 + wraplen;
-}
-
-/* =========================================================================
- * Put a short in the pending buffer. The 16-bit value is put in MSB order.
- * IN assertion: the stream state is correct and there is enough room in
- * pending_buf.
- */
-local void putShortMSB (s, b)
-    deflate_state *s;
-    uInt b;
-{
-    put_byte(s, (Byte)(b >> 8));
-    put_byte(s, (Byte)(b & 0xff));
-}
-
-/* =========================================================================
- * Flush as much pending output as possible. All deflate() output goes
- * through this function so some applications may wish to modify it
- * to avoid allocating a large strm->next_out buffer and copying into it.
- * (See also read_buf()).
- */
-local void flush_pending(strm)
-    z_streamp strm;
-{
-    unsigned len;
-    deflate_state *s = strm->state;
-
-    _tr_flush_bits(s);
-    len = s->pending;
-    if (len > strm->avail_out) len = strm->avail_out;
-    if (len == 0) return;
-
-    zmemcpy(strm->next_out, s->pending_out, len);
-    strm->next_out  += len;
-    s->pending_out  += len;
-    strm->total_out += len;
-    strm->avail_out  -= len;
-    s->pending -= len;
-    if (s->pending == 0) {
-        s->pending_out = s->pending_buf;
-    }
-}
-
-/* ========================================================================= */
-int ZEXPORT deflate (strm, flush)
-    z_streamp strm;
-    int flush;
-{
-    int old_flush; /* value of flush param for previous deflate call */
-    deflate_state *s;
-
-    if (strm == Z_NULL || strm->state == Z_NULL ||
-        flush > Z_BLOCK || flush < 0) {
-        return Z_STREAM_ERROR;
-    }
-    s = strm->state;
-
-    if (strm->next_out == Z_NULL ||
-        (strm->next_in == Z_NULL && strm->avail_in != 0) ||
-        (s->status == FINISH_STATE && flush != Z_FINISH)) {
-        ERR_RETURN(strm, Z_STREAM_ERROR);
-    }
-    if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
-
-    s->strm = strm; /* just in case */
-    old_flush = s->last_flush;
-    s->last_flush = flush;
-
-    /* Write the header */
-    if (s->status == INIT_STATE) {
-#ifdef GZIP
-        if (s->wrap == 2) {
-            strm->adler = crc32(0L, Z_NULL, 0);
-            put_byte(s, 31);
-            put_byte(s, 139);
-            put_byte(s, 8);
-            if (s->gzhead == Z_NULL) {
-                put_byte(s, 0);
-                put_byte(s, 0);
-                put_byte(s, 0);
-                put_byte(s, 0);
-                put_byte(s, 0);
-                put_byte(s, s->level == 9 ? 2 :
-                            (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
-                             4 : 0));
-                put_byte(s, OS_CODE);
-                s->status = BUSY_STATE;
-            }
-            else {
-                put_byte(s, (s->gzhead->text ? 1 : 0) +
-                            (s->gzhead->hcrc ? 2 : 0) +
-                            (s->gzhead->extra == Z_NULL ? 0 : 4) +
-                            (s->gzhead->name == Z_NULL ? 0 : 8) +
-                            (s->gzhead->comment == Z_NULL ? 0 : 16)
-                        );
-                put_byte(s, (Byte)(s->gzhead->time & 0xff));
-                put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff));
-                put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff));
-                put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff));
-                put_byte(s, s->level == 9 ? 2 :
-                            (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
-                             4 : 0));
-                put_byte(s, s->gzhead->os & 0xff);
-                if (s->gzhead->extra != Z_NULL) {
-                    put_byte(s, s->gzhead->extra_len & 0xff);
-                    put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);
-                }
-                if (s->gzhead->hcrc)
-                    strm->adler = crc32(strm->adler, s->pending_buf,
-                                        s->pending);
-                s->gzindex = 0;
-                s->status = EXTRA_STATE;
-            }
-        }
-        else
-#endif
-        {
-            uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
-            uInt level_flags;
-
-            if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
-                level_flags = 0;
-            else if (s->level < 6)
-                level_flags = 1;
-            else if (s->level == 6)
-                level_flags = 2;
-            else
-                level_flags = 3;
-            header |= (level_flags << 6);
-            if (s->strstart != 0) header |= PRESET_DICT;
-            header += 31 - (header % 31);
-
-            s->status = BUSY_STATE;
-            putShortMSB(s, header);
-
-            /* Save the adler32 of the preset dictionary: */
-            if (s->strstart != 0) {
-                putShortMSB(s, (uInt)(strm->adler >> 16));
-                putShortMSB(s, (uInt)(strm->adler & 0xffff));
-            }
-            strm->adler = adler32(0L, Z_NULL, 0);
-        }
-    }
-#ifdef GZIP
-    if (s->status == EXTRA_STATE) {
-        if (s->gzhead->extra != Z_NULL) {
-            uInt beg = s->pending;  /* start of bytes to update crc */
-
-            while (s->gzindex < (s->gzhead->extra_len & 0xffff)) {
-                if (s->pending == s->pending_buf_size) {
-                    if (s->gzhead->hcrc && s->pending > beg)
-                        strm->adler = crc32(strm->adler, s->pending_buf + beg,
-                                            s->pending - beg);
-                    flush_pending(strm);
-                    beg = s->pending;
-                    if (s->pending == s->pending_buf_size)
-                        break;
-                }
-                put_byte(s, s->gzhead->extra[s->gzindex]);
-                s->gzindex++;
-            }
-            if (s->gzhead->hcrc && s->pending > beg)
-                strm->adler = crc32(strm->adler, s->pending_buf + beg,
-                                    s->pending - beg);
-            if (s->gzindex == s->gzhead->extra_len) {
-                s->gzindex = 0;
-                s->status = NAME_STATE;
-            }
-        }
-        else
-            s->status = NAME_STATE;
-    }
-    if (s->status == NAME_STATE) {
-        if (s->gzhead->name != Z_NULL) {
-            uInt beg = s->pending;  /* start of bytes to update crc */
-            int val;
-
-            do {
-                if (s->pending == s->pending_buf_size) {
-                    if (s->gzhead->hcrc && s->pending > beg)
-                        strm->adler = crc32(strm->adler, s->pending_buf + beg,
-                                            s->pending - beg);
-                    flush_pending(strm);
-                    beg = s->pending;
-                    if (s->pending == s->pending_buf_size) {
-                        val = 1;
-                        break;
-                    }
-                }
-                val = s->gzhead->name[s->gzindex++];
-                put_byte(s, val);
-            } while (val != 0);
-            if (s->gzhead->hcrc && s->pending > beg)
-                strm->adler = crc32(strm->adler, s->pending_buf + beg,
-                                    s->pending - beg);
-            if (val == 0) {
-                s->gzindex = 0;
-                s->status = COMMENT_STATE;
-            }
-        }
-        else
-            s->status = COMMENT_STATE;
-    }
-    if (s->status == COMMENT_STATE) {
-        if (s->gzhead->comment != Z_NULL) {
-            uInt beg = s->pending;  /* start of bytes to update crc */
-            int val;
-
-            do {
-                if (s->pending == s->pending_buf_size) {
-                    if (s->gzhead->hcrc && s->pending > beg)
-                        strm->adler = crc32(strm->adler, s->pending_buf + beg,
-                                            s->pending - beg);
-                    flush_pending(strm);
-                    beg = s->pending;
-                    if (s->pending == s->pending_buf_size) {
-                        val = 1;
-                        break;
-                    }
-                }
-                val = s->gzhead->comment[s->gzindex++];
-                put_byte(s, val);
-            } while (val != 0);
-            if (s->gzhead->hcrc && s->pending > beg)
-                strm->adler = crc32(strm->adler, s->pending_buf + beg,
-                                    s->pending - beg);
-            if (val == 0)
-                s->status = HCRC_STATE;
-        }
-        else
-            s->status = HCRC_STATE;
-    }
-    if (s->status == HCRC_STATE) {
-        if (s->gzhead->hcrc) {
-            if (s->pending + 2 > s->pending_buf_size)
-                flush_pending(strm);
-            if (s->pending + 2 <= s->pending_buf_size) {
-                put_byte(s, (Byte)(strm->adler & 0xff));
-                put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
-                strm->adler = crc32(0L, Z_NULL, 0);
-                s->status = BUSY_STATE;
-            }
-        }
-        else
-            s->status = BUSY_STATE;
-    }
-#endif
-
-    /* Flush as much pending output as possible */
-    if (s->pending != 0) {
-        flush_pending(strm);
-        if (strm->avail_out == 0) {
-            /* Since avail_out is 0, deflate will be called again with
-             * more output space, but possibly with both pending and
-             * avail_in equal to zero. There won't be anything to do,
-             * but this is not an error situation so make sure we
-             * return OK instead of BUF_ERROR at next call of deflate:
-             */
-            s->last_flush = -1;
-            return Z_OK;
-        }
-
-    /* Make sure there is something to do and avoid duplicate consecutive
-     * flushes. For repeated and useless calls with Z_FINISH, we keep
-     * returning Z_STREAM_END instead of Z_BUF_ERROR.
-     */
-    } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) &&
-               flush != Z_FINISH) {
-        ERR_RETURN(strm, Z_BUF_ERROR);
-    }
-
-    /* User must not provide more input after the first FINISH: */
-    if (s->status == FINISH_STATE && strm->avail_in != 0) {
-        ERR_RETURN(strm, Z_BUF_ERROR);
-    }
-
-    /* Start a new block or continue the current one.
-     */
-    if (strm->avail_in != 0 || s->lookahead != 0 ||
-        (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
-        block_state bstate;
-
-        bstate = s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) :
-                    (s->strategy == Z_RLE ? deflate_rle(s, flush) :
-                        (*(configuration_table[s->level].func))(s, flush));
-
-        if (bstate == finish_started || bstate == finish_done) {
-            s->status = FINISH_STATE;
-        }
-        if (bstate == need_more || bstate == finish_started) {
-            if (strm->avail_out == 0) {
-                s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
-            }
-            return Z_OK;
-            /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
-             * of deflate should use the same flush parameter to make sure
-             * that the flush is complete. So we don't have to output an
-             * empty block here, this will be done at next call. This also
-             * ensures that for a very small output buffer, we emit at most
-             * one empty block.
-             */
-        }
-        if (bstate == block_done) {
-            if (flush == Z_PARTIAL_FLUSH) {
-                _tr_align(s);
-            } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */
-                _tr_stored_block(s, (char*)0, 0L, 0);
-                /* For a full flush, this empty block will be recognized
-                 * as a special marker by inflate_sync().
-                 */
-                if (flush == Z_FULL_FLUSH) {
-                    CLEAR_HASH(s);             /* forget history */
-                    if (s->lookahead == 0) {
-                        s->strstart = 0;
-                        s->block_start = 0L;
-                        s->insert = 0;
-                    }
-                }
-            }
-            flush_pending(strm);
-            if (strm->avail_out == 0) {
-              s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
-              return Z_OK;
-            }
-        }
-    }
-    Assert(strm->avail_out > 0, "bug2");
-
-    if (flush != Z_FINISH) return Z_OK;
-    if (s->wrap <= 0) return Z_STREAM_END;
-
-    /* Write the trailer */
-#ifdef GZIP
-    if (s->wrap == 2) {
-        put_byte(s, (Byte)(strm->adler & 0xff));
-        put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
-        put_byte(s, (Byte)((strm->adler >> 16) & 0xff));
-        put_byte(s, (Byte)((strm->adler >> 24) & 0xff));
-        put_byte(s, (Byte)(strm->total_in & 0xff));
-        put_byte(s, (Byte)((strm->total_in >> 8) & 0xff));
-        put_byte(s, (Byte)((strm->total_in >> 16) & 0xff));
-        put_byte(s, (Byte)((strm->total_in >> 24) & 0xff));
-    }
-    else
-#endif
-    {
-        putShortMSB(s, (uInt)(strm->adler >> 16));
-        putShortMSB(s, (uInt)(strm->adler & 0xffff));
-    }
-    flush_pending(strm);
-    /* If avail_out is zero, the application will call deflate again
-     * to flush the rest.
-     */
-    if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */
-    return s->pending != 0 ? Z_OK : Z_STREAM_END;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateEnd (strm)
-    z_streamp strm;
-{
-    int status;
-
-    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
-
-    status = strm->state->status;
-    if (status != INIT_STATE &&
-        status != EXTRA_STATE &&
-        status != NAME_STATE &&
-        status != COMMENT_STATE &&
-        status != HCRC_STATE &&
-        status != BUSY_STATE &&
-        status != FINISH_STATE) {
-      return Z_STREAM_ERROR;
-    }
-
-    /* Deallocate in reverse order of allocations: */
-    TRY_FREE(strm, strm->state->pending_buf);
-    TRY_FREE(strm, strm->state->head);
-    TRY_FREE(strm, strm->state->prev);
-    TRY_FREE(strm, strm->state->window);
-
-    ZFREE(strm, strm->state);
-    strm->state = Z_NULL;
-
-    return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
-}
-
-/* =========================================================================
- * Copy the source state to the destination state.
- * To simplify the source, this is not supported for 16-bit MSDOS (which
- * doesn't have enough memory anyway to duplicate compression states).
- */
-int ZEXPORT deflateCopy (dest, source)
-    z_streamp dest;
-    z_streamp source;
-{
-#ifdef MAXSEG_64K
-    return Z_STREAM_ERROR;
-#else
-    deflate_state *ds;
-    deflate_state *ss;
-    ushf *overlay;
-
-
-    if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
-        return Z_STREAM_ERROR;
-    }
-
-    ss = source->state;
-
-    zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
-
-    ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
-    if (ds == Z_NULL) return Z_MEM_ERROR;
-    dest->state = (struct internal_state FAR *) ds;
-    zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state));
-    ds->strm = dest;
-
-    ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
-    ds->prev   = (Posf *)  ZALLOC(dest, ds->w_size, sizeof(Pos));
-    ds->head   = (Posf *)  ZALLOC(dest, ds->hash_size, sizeof(Pos));
-    overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
-    ds->pending_buf = (uchf *) overlay;
-
-    if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
-        ds->pending_buf == Z_NULL) {
-        deflateEnd (dest);
-        return Z_MEM_ERROR;
-    }
-    /* following zmemcpy do not work for 16-bit MSDOS */
-    zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
-    zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos));
-    zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos));
-    zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
-
-    ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
-    ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
-    ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
-
-    ds->l_desc.dyn_tree = ds->dyn_ltree;
-    ds->d_desc.dyn_tree = ds->dyn_dtree;
-    ds->bl_desc.dyn_tree = ds->bl_tree;
-
-    return Z_OK;
-#endif /* MAXSEG_64K */
-}
-
-/* ===========================================================================
- * Read a new buffer from the current input stream, update the adler32
- * and total number of bytes read.  All deflate() input goes through
- * this function so some applications may wish to modify it to avoid
- * allocating a large strm->next_in buffer and copying from it.
- * (See also flush_pending()).
- */
-local int read_buf(strm, buf, size)
-    z_streamp strm;
-    Bytef *buf;
-    unsigned size;
-{
-    unsigned len = strm->avail_in;
-
-    if (len > size) len = size;
-    if (len == 0) return 0;
-
-    strm->avail_in  -= len;
-
-    zmemcpy(buf, strm->next_in, len);
-    if (strm->state->wrap == 1) {
-        strm->adler = adler32(strm->adler, buf, len);
-    }
-#ifdef GZIP
-    else if (strm->state->wrap == 2) {
-        strm->adler = crc32(strm->adler, buf, len);
-    }
-#endif
-    strm->next_in  += len;
-    strm->total_in += len;
-
-    return (int)len;
-}
-
-/* ===========================================================================
- * Initialize the "longest match" routines for a new zlib stream
- */
-local void lm_init (s)
-    deflate_state *s;
-{
-    s->window_size = (ulg)2L*s->w_size;
-
-    CLEAR_HASH(s);
-
-    /* Set the default configuration parameters:
-     */
-    s->max_lazy_match   = configuration_table[s->level].max_lazy;
-    s->good_match       = configuration_table[s->level].good_length;
-    s->nice_match       = configuration_table[s->level].nice_length;
-    s->max_chain_length = configuration_table[s->level].max_chain;
-
-    s->strstart = 0;
-    s->block_start = 0L;
-    s->lookahead = 0;
-    s->insert = 0;
-    s->match_length = s->prev_length = MIN_MATCH-1;
-    s->match_available = 0;
-    s->ins_h = 0;
-#ifndef FASTEST
-#ifdef ASMV
-    match_init(); /* initialize the asm code */
-#endif
-#endif
-}
-
-#ifndef FASTEST
-/* ===========================================================================
- * Set match_start to the longest match starting at the given string and
- * return its length. Matches shorter or equal to prev_length are discarded,
- * in which case the result is equal to prev_length and match_start is
- * garbage.
- * IN assertions: cur_match is the head of the hash chain for the current
- *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
- * OUT assertion: the match length is not greater than s->lookahead.
- */
-#ifndef ASMV
-/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
- * match.S. The code will be functionally equivalent.
- */
-local uInt longest_match(s, cur_match)
-    deflate_state *s;
-    IPos cur_match;                             /* current match */
-{
-    unsigned chain_length = s->max_chain_length;/* max hash chain length */
-    register Bytef *scan = s->window + s->strstart; /* current string */
-    register Bytef *match;                       /* matched string */
-    register int len;                           /* length of current match */
-    int best_len = s->prev_length;              /* best match length so far */
-    int nice_match = s->nice_match;             /* stop if match long enough */
-    IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
-        s->strstart - (IPos)MAX_DIST(s) : NIL;
-    /* Stop when cur_match becomes <= limit. To simplify the code,
-     * we prevent matches with the string of window index 0.
-     */
-    Posf *prev = s->prev;
-    uInt wmask = s->w_mask;
-
-#ifdef UNALIGNED_OK
-    /* Compare two bytes at a time. Note: this is not always beneficial.
-     * Try with and without -DUNALIGNED_OK to check.
-     */
-    register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
-    register ush scan_start = *(ushf*)scan;
-    register ush scan_end   = *(ushf*)(scan+best_len-1);
-#else
-    register Bytef *strend = s->window + s->strstart + MAX_MATCH;
-    register Byte scan_end1  = scan[best_len-1];
-    register Byte scan_end   = scan[best_len];
-#endif
-
-    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
-     * It is easy to get rid of this optimization if necessary.
-     */
-    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
-
-    /* Do not waste too much time if we already have a good match: */
-    if (s->prev_length >= s->good_match) {
-        chain_length >>= 2;
-    }
-    /* Do not look for matches beyond the end of the input. This is necessary
-     * to make deflate deterministic.
-     */
-    if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
-
-    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
-
-    do {
-        Assert(cur_match < s->strstart, "no future");
-        match = s->window + cur_match;
-
-        /* Skip to next match if the match length cannot increase
-         * or if the match length is less than 2.  Note that the checks below
-         * for insufficient lookahead only occur occasionally for performance
-         * reasons.  Therefore uninitialized memory will be accessed, and
-         * conditional jumps will be made that depend on those values.
-         * However the length of the match is limited to the lookahead, so
-         * the output of deflate is not affected by the uninitialized values.
-         */
-#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
-        /* This code assumes sizeof(unsigned short) == 2. Do not use
-         * UNALIGNED_OK if your compiler uses a different size.
-         */
-        if (*(ushf*)(match+best_len-1) != scan_end ||
-            *(ushf*)match != scan_start) continue;
-
-        /* It is not necessary to compare scan[2] and match[2] since they are
-         * always equal when the other bytes match, given that the hash keys
-         * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
-         * strstart+3, +5, ... up to strstart+257. We check for insufficient
-         * lookahead only every 4th comparison; the 128th check will be made
-         * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
-         * necessary to put more guard bytes at the end of the window, or
-         * to check more often for insufficient lookahead.
-         */
-        Assert(scan[2] == match[2], "scan[2]?");
-        scan++, match++;
-        do {
-        } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
-                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
-                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
-                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
-                 scan < strend);
-        /* The funny "do {}" generates better code on most compilers */
-
-        /* Here, scan <= window+strstart+257 */
-        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-        if (*scan == *match) scan++;
-
-        len = (MAX_MATCH - 1) - (int)(strend-scan);
-        scan = strend - (MAX_MATCH-1);
-
-#else /* UNALIGNED_OK */
-
-        if (match[best_len]   != scan_end  ||
-            match[best_len-1] != scan_end1 ||
-            *match            != *scan     ||
-            *++match          != scan[1])      continue;
-
-        /* The check at best_len-1 can be removed because it will be made
-         * again later. (This heuristic is not always a win.)
-         * It is not necessary to compare scan[2] and match[2] since they
-         * are always equal when the other bytes match, given that
-         * the hash keys are equal and that HASH_BITS >= 8.
-         */
-        scan += 2, match++;
-        Assert(*scan == *match, "match[2]?");
-
-        /* We check for insufficient lookahead only every 8th comparison;
-         * the 256th check will be made at strstart+258.
-         */
-        do {
-        } while (*++scan == *++match && *++scan == *++match &&
-                 *++scan == *++match && *++scan == *++match &&
-                 *++scan == *++match && *++scan == *++match &&
-                 *++scan == *++match && *++scan == *++match &&
-                 scan < strend);
-
-        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-
-        len = MAX_MATCH - (int)(strend - scan);
-        scan = strend - MAX_MATCH;
-
-#endif /* UNALIGNED_OK */
-
-        if (len > best_len) {
-            s->match_start = cur_match;
-            best_len = len;
-            if (len >= nice_match) break;
-#ifdef UNALIGNED_OK
-            scan_end = *(ushf*)(scan+best_len-1);
-#else
-            scan_end1  = scan[best_len-1];
-            scan_end   = scan[best_len];
-#endif
-        }
-    } while ((cur_match = prev[cur_match & wmask]) > limit
-             && --chain_length != 0);
-
-    if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
-    return s->lookahead;
-}
-#endif /* ASMV */
-
-#else /* FASTEST */
-
-/* ---------------------------------------------------------------------------
- * Optimized version for FASTEST only
- */
-local uInt longest_match(s, cur_match)
-    deflate_state *s;
-    IPos cur_match;                             /* current match */
-{
-    register Bytef *scan = s->window + s->strstart; /* current string */
-    register Bytef *match;                       /* matched string */
-    register int len;                           /* length of current match */
-    register Bytef *strend = s->window + s->strstart + MAX_MATCH;
-
-    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
-     * It is easy to get rid of this optimization if necessary.
-     */
-    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
-
-    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
-
-    Assert(cur_match < s->strstart, "no future");
-
-    match = s->window + cur_match;
-
-    /* Return failure if the match length is less than 2:
-     */
-    if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
-
-    /* The check at best_len-1 can be removed because it will be made
-     * again later. (This heuristic is not always a win.)
-     * It is not necessary to compare scan[2] and match[2] since they
-     * are always equal when the other bytes match, given that
-     * the hash keys are equal and that HASH_BITS >= 8.
-     */
-    scan += 2, match += 2;
-    Assert(*scan == *match, "match[2]?");
-
-    /* We check for insufficient lookahead only every 8th comparison;
-     * the 256th check will be made at strstart+258.
-     */
-    do {
-    } while (*++scan == *++match && *++scan == *++match &&
-             *++scan == *++match && *++scan == *++match &&
-             *++scan == *++match && *++scan == *++match &&
-             *++scan == *++match && *++scan == *++match &&
-             scan < strend);
-
-    Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-
-    len = MAX_MATCH - (int)(strend - scan);
-
-    if (len < MIN_MATCH) return MIN_MATCH - 1;
-
-    s->match_start = cur_match;
-    return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead;
-}
-
-#endif /* FASTEST */
-
-#ifdef DEBUG
-/* ===========================================================================
- * Check that the match at match_start is indeed a match.
- */
-local void check_match(s, start, match, length)
-    deflate_state *s;
-    IPos start, match;
-    int length;
-{
-    /* check that the match is indeed a match */
-    if (zmemcmp(s->window + match,
-                s->window + start, length) != EQUAL) {
-        fprintf(stderr, " start %u, match %u, length %d\n",
-                start, match, length);
-        do {
-            fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
-        } while (--length != 0);
-        z_error("invalid match");
-    }
-    if (z_verbose > 1) {
-        fprintf(stderr,"\\[%d,%d]", start-match, length);
-        do { putc(s->window[start++], stderr); } while (--length != 0);
-    }
-}
-#else
-#  define check_match(s, start, match, length)
-#endif /* DEBUG */
-
-/* ===========================================================================
- * Fill the window when the lookahead becomes insufficient.
- * Updates strstart and lookahead.
- *
- * IN assertion: lookahead < MIN_LOOKAHEAD
- * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
- *    At least one byte has been read, or avail_in == 0; reads are
- *    performed for at least two bytes (required for the zip translate_eol
- *    option -- not supported here).
- */
-local void fill_window(s)
-    deflate_state *s;
-{
-    register unsigned n, m;
-    register Posf *p;
-    unsigned more;    /* Amount of free space at the end of the window. */
-    uInt wsize = s->w_size;
-
-    Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead");
-
-    do {
-        more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
-
-        /* Deal with !@#$% 64K limit: */
-        if (sizeof(int) <= 2) {
-            if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
-                more = wsize;
-
-            } else if (more == (unsigned)(-1)) {
-                /* Very unlikely, but possible on 16 bit machine if
-                 * strstart == 0 && lookahead == 1 (input done a byte at time)
-                 */
-                more--;
-            }
-        }
-
-        /* If the window is almost full and there is insufficient lookahead,
-         * move the upper half to the lower one to make room in the upper half.
-         */
-        if (s->strstart >= wsize+MAX_DIST(s)) {
-
-            zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
-            s->match_start -= wsize;
-            s->strstart    -= wsize; /* we now have strstart >= MAX_DIST */
-            s->block_start -= (long) wsize;
-
-            /* Slide the hash table (could be avoided with 32 bit values
-               at the expense of memory usage). We slide even when level == 0
-               to keep the hash table consistent if we switch back to level > 0
-               later. (Using level 0 permanently is not an optimal usage of
-               zlib, so we don't care about this pathological case.)
-             */
-            n = s->hash_size;
-            p = &s->head[n];
-            do {
-                m = *--p;
-                *p = (Pos)(m >= wsize ? m-wsize : NIL);
-            } while (--n);
-
-            n = wsize;
-#ifndef FASTEST
-            p = &s->prev[n];
-            do {
-                m = *--p;
-                *p = (Pos)(m >= wsize ? m-wsize : NIL);
-                /* If n is not on any hash chain, prev[n] is garbage but
-                 * its value will never be used.
-                 */
-            } while (--n);
-#endif
-            more += wsize;
-        }
-        if (s->strm->avail_in == 0) break;
-
-        /* If there was no sliding:
-         *    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
-         *    more == window_size - lookahead - strstart
-         * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
-         * => more >= window_size - 2*WSIZE + 2
-         * In the BIG_MEM or MMAP case (not yet supported),
-         *   window_size == input_size + MIN_LOOKAHEAD  &&
-         *   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
-         * Otherwise, window_size == 2*WSIZE so more >= 2.
-         * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
-         */
-        Assert(more >= 2, "more < 2");
-
-        n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
-        s->lookahead += n;
-
-        /* Initialize the hash value now that we have some input: */
-        if (s->lookahead + s->insert >= MIN_MATCH) {
-            uInt str = s->strstart - s->insert;
-            s->ins_h = s->window[str];
-            UPDATE_HASH(s, s->ins_h, s->window[str + 1]);
-#if MIN_MATCH != 3
-            Call UPDATE_HASH() MIN_MATCH-3 more times
-#endif
-            while (s->insert) {
-                UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);
-#ifndef FASTEST
-                s->prev[str & s->w_mask] = s->head[s->ins_h];
-#endif
-                s->head[s->ins_h] = (Pos)str;
-                str++;
-                s->insert--;
-                if (s->lookahead + s->insert < MIN_MATCH)
-                    break;
-            }
-        }
-        /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
-         * but this is not important since only literal bytes will be emitted.
-         */
-
-    } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
-
-    /* If the WIN_INIT bytes after the end of the current data have never been
-     * written, then zero those bytes in order to avoid memory check reports of
-     * the use of uninitialized (or uninitialised as Julian writes) bytes by
-     * the longest match routines.  Update the high water mark for the next
-     * time through here.  WIN_INIT is set to MAX_MATCH since the longest match
-     * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.
-     */
-    if (s->high_water < s->window_size) {
-        ulg curr = s->strstart + (ulg)(s->lookahead);
-        ulg init;
-
-        if (s->high_water < curr) {
-            /* Previous high water mark below current data -- zero WIN_INIT
-             * bytes or up to end of window, whichever is less.
-             */
-            init = s->window_size - curr;
-            if (init > WIN_INIT)
-                init = WIN_INIT;
-            zmemzero(s->window + curr, (unsigned)init);
-            s->high_water = curr + init;
-        }
-        else if (s->high_water < (ulg)curr + WIN_INIT) {
-            /* High water mark at or above current data, but below current data
-             * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up
-             * to end of window, whichever is less.
-             */
-            init = (ulg)curr + WIN_INIT - s->high_water;
-            if (init > s->window_size - s->high_water)
-                init = s->window_size - s->high_water;
-            zmemzero(s->window + s->high_water, (unsigned)init);
-            s->high_water += init;
-        }
-    }
-
-    Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,
-           "not enough room for search");
-}
-
-/* ===========================================================================
- * Flush the current block, with given end-of-file flag.
- * IN assertion: strstart is set to the end of the current match.
- */
-#define FLUSH_BLOCK_ONLY(s, last) { \
-   _tr_flush_block(s, (s->block_start >= 0L ? \
-                   (charf *)&s->window[(unsigned)s->block_start] : \
-                   (charf *)Z_NULL), \
-                (ulg)((long)s->strstart - s->block_start), \
-                (last)); \
-   s->block_start = s->strstart; \
-   flush_pending(s->strm); \
-   Tracev((stderr,"[FLUSH]")); \
-}
-
-/* Same but force premature exit if necessary. */
-#define FLUSH_BLOCK(s, last) { \
-   FLUSH_BLOCK_ONLY(s, last); \
-   if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \
-}
-
-/* ===========================================================================
- * Copy without compression as much as possible from the input stream, return
- * the current block state.
- * This function does not insert new strings in the dictionary since
- * uncompressible data is probably not useful. This function is used
- * only for the level=0 compression option.
- * NOTE: this function should be optimized to avoid extra copying from
- * window to pending_buf.
- */
-local block_state deflate_stored(s, flush)
-    deflate_state *s;
-    int flush;
-{
-    /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
-     * to pending_buf_size, and each stored block has a 5 byte header:
-     */
-    ulg max_block_size = 0xffff;
-    ulg max_start;
-
-    if (max_block_size > s->pending_buf_size - 5) {
-        max_block_size = s->pending_buf_size - 5;
-    }
-
-    /* Copy as much as possible from input to output: */
-    for (;;) {
-        /* Fill the window as much as possible: */
-        if (s->lookahead <= 1) {
-
-            Assert(s->strstart < s->w_size+MAX_DIST(s) ||
-                   s->block_start >= (long)s->w_size, "slide too late");
-
-            fill_window(s);
-            if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
-
-            if (s->lookahead == 0) break; /* flush the current block */
-        }
-        Assert(s->block_start >= 0L, "block gone");
-
-        s->strstart += s->lookahead;
-        s->lookahead = 0;
-
-        /* Emit a stored block if pending_buf will be full: */
-        max_start = s->block_start + max_block_size;
-        if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
-            /* strstart == 0 is possible when wraparound on 16-bit machine */
-            s->lookahead = (uInt)(s->strstart - max_start);
-            s->strstart = (uInt)max_start;
-            FLUSH_BLOCK(s, 0);
-        }
-        /* Flush if we may have to slide, otherwise block_start may become
-         * negative and the data will be gone:
-         */
-        if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
-            FLUSH_BLOCK(s, 0);
-        }
-    }
-    s->insert = 0;
-    if (flush == Z_FINISH) {
-        FLUSH_BLOCK(s, 1);
-        return finish_done;
-    }
-    if ((long)s->strstart > s->block_start)
-        FLUSH_BLOCK(s, 0);
-    return block_done;
-}
-
-/* ===========================================================================
- * Compress as much as possible from the input stream, return the current
- * block state.
- * This function does not perform lazy evaluation of matches and inserts
- * new strings in the dictionary only for unmatched strings or for short
- * matches. It is used only for the fast compression options.
- */
-local block_state deflate_fast(s, flush)
-    deflate_state *s;
-    int flush;
-{
-    IPos hash_head;       /* head of the hash chain */
-    int bflush;           /* set if current block must be flushed */
-
-    for (;;) {
-        /* Make sure that we always have enough lookahead, except
-         * at the end of the input file. We need MAX_MATCH bytes
-         * for the next match, plus MIN_MATCH bytes to insert the
-         * string following the next match.
-         */
-        if (s->lookahead < MIN_LOOKAHEAD) {
-            fill_window(s);
-            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
-                return need_more;
-            }
-            if (s->lookahead == 0) break; /* flush the current block */
-        }
-
-        /* Insert the string window[strstart .. strstart+2] in the
-         * dictionary, and set hash_head to the head of the hash chain:
-         */
-        hash_head = NIL;
-        if (s->lookahead >= MIN_MATCH) {
-            INSERT_STRING(s, s->strstart, hash_head);
-        }
-
-        /* Find the longest match, discarding those <= prev_length.
-         * At this point we have always match_length < MIN_MATCH
-         */
-        if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
-            /* To simplify the code, we prevent matches with the string
-             * of window index 0 (in particular we have to avoid a match
-             * of the string with itself at the start of the input file).
-             */
-            s->match_length = longest_match (s, hash_head);
-            /* longest_match() sets match_start */
-        }
-        if (s->match_length >= MIN_MATCH) {
-            check_match(s, s->strstart, s->match_start, s->match_length);
-
-            _tr_tally_dist(s, s->strstart - s->match_start,
-                           s->match_length - MIN_MATCH, bflush);
-
-            s->lookahead -= s->match_length;
-
-            /* Insert new strings in the hash table only if the match length
-             * is not too large. This saves time but degrades compression.
-             */
-#ifndef FASTEST
-            if (s->match_length <= s->max_insert_length &&
-                s->lookahead >= MIN_MATCH) {
-                s->match_length--; /* string at strstart already in table */
-                do {
-                    s->strstart++;
-                    INSERT_STRING(s, s->strstart, hash_head);
-                    /* strstart never exceeds WSIZE-MAX_MATCH, so there are
-                     * always MIN_MATCH bytes ahead.
-                     */
-                } while (--s->match_length != 0);
-                s->strstart++;
-            } else
-#endif
-            {
-                s->strstart += s->match_length;
-                s->match_length = 0;
-                s->ins_h = s->window[s->strstart];
-                UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
-#if MIN_MATCH != 3
-                Call UPDATE_HASH() MIN_MATCH-3 more times
-#endif
-                /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
-                 * matter since it will be recomputed at next deflate call.
-                 */
-            }
-        } else {
-            /* No match, output a literal byte */
-            Tracevv((stderr,"%c", s->window[s->strstart]));
-            _tr_tally_lit (s, s->window[s->strstart], bflush);
-            s->lookahead--;
-            s->strstart++;
-        }
-        if (bflush) FLUSH_BLOCK(s, 0);
-    }
-    s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;
-    if (flush == Z_FINISH) {
-        FLUSH_BLOCK(s, 1);
-        return finish_done;
-    }
-    if (s->last_lit)
-        FLUSH_BLOCK(s, 0);
-    return block_done;
-}
-
-#ifndef FASTEST
-/* ===========================================================================
- * Same as above, but achieves better compression. We use a lazy
- * evaluation for matches: a match is finally adopted only if there is
- * no better match at the next window position.
- */
-local block_state deflate_slow(s, flush)
-    deflate_state *s;
-    int flush;
-{
-    IPos hash_head;          /* head of hash chain */
-    int bflush;              /* set if current block must be flushed */
-
-    /* Process the input block. */
-    for (;;) {
-        /* Make sure that we always have enough lookahead, except
-         * at the end of the input file. We need MAX_MATCH bytes
-         * for the next match, plus MIN_MATCH bytes to insert the
-         * string following the next match.
-         */
-        if (s->lookahead < MIN_LOOKAHEAD) {
-            fill_window(s);
-            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
-                return need_more;
-            }
-            if (s->lookahead == 0) break; /* flush the current block */
-        }
-
-        /* Insert the string window[strstart .. strstart+2] in the
-         * dictionary, and set hash_head to the head of the hash chain:
-         */
-        hash_head = NIL;
-        if (s->lookahead >= MIN_MATCH) {
-            INSERT_STRING(s, s->strstart, hash_head);
-        }
-
-        /* Find the longest match, discarding those <= prev_length.
-         */
-        s->prev_length = s->match_length, s->prev_match = s->match_start;
-        s->match_length = MIN_MATCH-1;
-
-        if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
-            s->strstart - hash_head <= MAX_DIST(s)) {
-            /* To simplify the code, we prevent matches with the string
-             * of window index 0 (in particular we have to avoid a match
-             * of the string with itself at the start of the input file).
-             */
-            s->match_length = longest_match (s, hash_head);
-            /* longest_match() sets match_start */
-
-            if (s->match_length <= 5 && (s->strategy == Z_FILTERED
-#if TOO_FAR <= 32767
-                || (s->match_length == MIN_MATCH &&
-                    s->strstart - s->match_start > TOO_FAR)
-#endif
-                )) {
-
-                /* If prev_match is also MIN_MATCH, match_start is garbage
-                 * but we will ignore the current match anyway.
-                 */
-                s->match_length = MIN_MATCH-1;
-            }
-        }
-        /* If there was a match at the previous step and the current
-         * match is not better, output the previous match:
-         */
-        if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
-            uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
-            /* Do not insert strings in hash table beyond this. */
-
-            check_match(s, s->strstart-1, s->prev_match, s->prev_length);
-
-            _tr_tally_dist(s, s->strstart -1 - s->prev_match,
-                           s->prev_length - MIN_MATCH, bflush);
-
-            /* Insert in hash table all strings up to the end of the match.
-             * strstart-1 and strstart are already inserted. If there is not
-             * enough lookahead, the last two strings are not inserted in
-             * the hash table.
-             */
-            s->lookahead -= s->prev_length-1;
-            s->prev_length -= 2;
-            do {
-                if (++s->strstart <= max_insert) {
-                    INSERT_STRING(s, s->strstart, hash_head);
-                }
-            } while (--s->prev_length != 0);
-            s->match_available = 0;
-            s->match_length = MIN_MATCH-1;
-            s->strstart++;
-
-            if (bflush) FLUSH_BLOCK(s, 0);
-
-        } else if (s->match_available) {
-            /* If there was no match at the previous position, output a
-             * single literal. If there was a match but the current match
-             * is longer, truncate the previous match to a single literal.
-             */
-            Tracevv((stderr,"%c", s->window[s->strstart-1]));
-            _tr_tally_lit(s, s->window[s->strstart-1], bflush);
-            if (bflush) {
-                FLUSH_BLOCK_ONLY(s, 0);
-            }
-            s->strstart++;
-            s->lookahead--;
-            if (s->strm->avail_out == 0) return need_more;
-        } else {
-            /* There is no previous match to compare with, wait for
-             * the next step to decide.
-             */
-            s->match_available = 1;
-            s->strstart++;
-            s->lookahead--;
-        }
-    }
-    Assert (flush != Z_NO_FLUSH, "no flush?");
-    if (s->match_available) {
-        Tracevv((stderr,"%c", s->window[s->strstart-1]));
-        _tr_tally_lit(s, s->window[s->strstart-1], bflush);
-        s->match_available = 0;
-    }
-    s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;
-    if (flush == Z_FINISH) {
-        FLUSH_BLOCK(s, 1);
-        return finish_done;
-    }
-    if (s->last_lit)
-        FLUSH_BLOCK(s, 0);
-    return block_done;
-}
-#endif /* FASTEST */
-
-/* ===========================================================================
- * For Z_RLE, simply look for runs of bytes, generate matches only of distance
- * one.  Do not maintain a hash table.  (It will be regenerated if this run of
- * deflate switches away from Z_RLE.)
- */
-local block_state deflate_rle(s, flush)
-    deflate_state *s;
-    int flush;
-{
-    int bflush;             /* set if current block must be flushed */
-    uInt prev;              /* byte at distance one to match */
-    Bytef *scan, *strend;   /* scan goes up to strend for length of run */
-
-    for (;;) {
-        /* Make sure that we always have enough lookahead, except
-         * at the end of the input file. We need MAX_MATCH bytes
-         * for the longest run, plus one for the unrolled loop.
-         */
-        if (s->lookahead <= MAX_MATCH) {
-            fill_window(s);
-            if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) {
-                return need_more;
-            }
-            if (s->lookahead == 0) break; /* flush the current block */
-        }
-
-        /* See how many times the previous byte repeats */
-        s->match_length = 0;
-        if (s->lookahead >= MIN_MATCH && s->strstart > 0) {
-            scan = s->window + s->strstart - 1;
-            prev = *scan;
-            if (prev == *++scan && prev == *++scan && prev == *++scan) {
-                strend = s->window + s->strstart + MAX_MATCH;
-                do {
-                } while (prev == *++scan && prev == *++scan &&
-                         prev == *++scan && prev == *++scan &&
-                         prev == *++scan && prev == *++scan &&
-                         prev == *++scan && prev == *++scan &&
-                         scan < strend);
-                s->match_length = MAX_MATCH - (int)(strend - scan);
-                if (s->match_length > s->lookahead)
-                    s->match_length = s->lookahead;
-            }
-            Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan");
-        }
-
-        /* Emit match if have run of MIN_MATCH or longer, else emit literal */
-        if (s->match_length >= MIN_MATCH) {
-            check_match(s, s->strstart, s->strstart - 1, s->match_length);
-
-            _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush);
-
-            s->lookahead -= s->match_length;
-            s->strstart += s->match_length;
-            s->match_length = 0;
-        } else {
-            /* No match, output a literal byte */
-            Tracevv((stderr,"%c", s->window[s->strstart]));
-            _tr_tally_lit (s, s->window[s->strstart], bflush);
-            s->lookahead--;
-            s->strstart++;
-        }
-        if (bflush) FLUSH_BLOCK(s, 0);
-    }
-    s->insert = 0;
-    if (flush == Z_FINISH) {
-        FLUSH_BLOCK(s, 1);
-        return finish_done;
-    }
-    if (s->last_lit)
-        FLUSH_BLOCK(s, 0);
-    return block_done;
-}
-
-/* ===========================================================================
- * For Z_HUFFMAN_ONLY, do not look for matches.  Do not maintain a hash table.
- * (It will be regenerated if this run of deflate switches away from Huffman.)
- */
-local block_state deflate_huff(s, flush)
-    deflate_state *s;
-    int flush;
-{
-    int bflush;             /* set if current block must be flushed */
-
-    for (;;) {
-        /* Make sure that we have a literal to write. */
-        if (s->lookahead == 0) {
-            fill_window(s);
-            if (s->lookahead == 0) {
-                if (flush == Z_NO_FLUSH)
-                    return need_more;
-                break;      /* flush the current block */
-            }
-        }
-
-        /* Output a literal byte */
-        s->match_length = 0;
-        Tracevv((stderr,"%c", s->window[s->strstart]));
-        _tr_tally_lit (s, s->window[s->strstart], bflush);
-        s->lookahead--;
-        s->strstart++;
-        if (bflush) FLUSH_BLOCK(s, 0);
-    }
-    s->insert = 0;
-    if (flush == Z_FINISH) {
-        FLUSH_BLOCK(s, 1);
-        return finish_done;
-    }
-    if (s->last_lit)
-        FLUSH_BLOCK(s, 0);
-    return block_done;
-}
+/* deflate.c -- compress data using the deflation algorithm
+ * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ *  ALGORITHM
+ *
+ *      The "deflation" process depends on being able to identify portions
+ *      of the input text which are identical to earlier input (within a
+ *      sliding window trailing behind the input currently being processed).
+ *
+ *      The most straightforward technique turns out to be the fastest for
+ *      most input files: try all possible matches and select the longest.
+ *      The key feature of this algorithm is that insertions into the string
+ *      dictionary are very simple and thus fast, and deletions are avoided
+ *      completely. Insertions are performed at each input character, whereas
+ *      string matches are performed only when the previous match ends. So it
+ *      is preferable to spend more time in matches to allow very fast string
+ *      insertions and avoid deletions. The matching algorithm for small
+ *      strings is inspired from that of Rabin & Karp. A brute force approach
+ *      is used to find longer strings when a small match has been found.
+ *      A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
+ *      (by Leonid Broukhis).
+ *         A previous version of this file used a more sophisticated algorithm
+ *      (by Fiala and Greene) which is guaranteed to run in linear amortized
+ *      time, but has a larger average cost, uses more memory and is patented.
+ *      However the F&G algorithm may be faster for some highly redundant
+ *      files if the parameter max_chain_length (described below) is too large.
+ *
+ *  ACKNOWLEDGEMENTS
+ *
+ *      The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
+ *      I found it in 'freeze' written by Leonid Broukhis.
+ *      Thanks to many people for bug reports and testing.
+ *
+ *  REFERENCES
+ *
+ *      Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
+ *      Available in http://tools.ietf.org/html/rfc1951
+ *
+ *      A description of the Rabin and Karp algorithm is given in the book
+ *         "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
+ *
+ *      Fiala,E.R., and Greene,D.H.
+ *         Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
+ *
+ */
+
+/* @(#) $Id: deflate.c,v 1.10 2013/05/10 17:22:52 drolon Exp $ */
+
+#include "deflate.h"
+
+const char deflate_copyright[] =
+   " deflate 1.2.8 Copyright 1995-2013 Jean-loup Gailly and Mark Adler ";
+/*
+  If you use the zlib library in a product, an acknowledgment is welcome
+  in the documentation of your product. If for some reason you cannot
+  include such an acknowledgment, I would appreciate that you keep this
+  copyright string in the executable of your product.
+ */
+
+/* ===========================================================================
+ *  Function prototypes.
+ */
+typedef enum {
+    need_more,      /* block not completed, need more input or more output */
+    block_done,     /* block flush performed */
+    finish_started, /* finish started, need only more output at next deflate */
+    finish_done     /* finish done, accept no more input or output */
+} block_state;
+
+typedef block_state (*compress_func) OF((deflate_state *s, int flush));
+/* Compression function. Returns the block state after the call. */
+
+local void fill_window    OF((deflate_state *s));
+local block_state deflate_stored OF((deflate_state *s, int flush));
+local block_state deflate_fast   OF((deflate_state *s, int flush));
+#ifndef FASTEST
+local block_state deflate_slow   OF((deflate_state *s, int flush));
+#endif
+local block_state deflate_rle    OF((deflate_state *s, int flush));
+local block_state deflate_huff   OF((deflate_state *s, int flush));
+local void lm_init        OF((deflate_state *s));
+local void putShortMSB    OF((deflate_state *s, uInt b));
+local void flush_pending  OF((z_streamp strm));
+local int read_buf        OF((z_streamp strm, Bytef *buf, unsigned size));
+#ifdef ASMV
+      void match_init OF((void)); /* asm code initialization */
+      uInt longest_match  OF((deflate_state *s, IPos cur_match));
+#else
+local uInt longest_match  OF((deflate_state *s, IPos cur_match));
+#endif
+
+#ifdef DEBUG
+local  void check_match OF((deflate_state *s, IPos start, IPos match,
+                            int length));
+#endif
+
+/* ===========================================================================
+ * Local data
+ */
+
+#define NIL 0
+/* Tail of hash chains */
+
+#ifndef TOO_FAR
+#  define TOO_FAR 4096
+#endif
+/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
+
+/* Values for max_lazy_match, good_match and max_chain_length, depending on
+ * the desired pack level (0..9). The values given below have been tuned to
+ * exclude worst case performance for pathological files. Better values may be
+ * found for specific files.
+ */
+typedef struct config_s {
+   ush good_length; /* reduce lazy search above this match length */
+   ush max_lazy;    /* do not perform lazy search above this match length */
+   ush nice_length; /* quit search above this match length */
+   ush max_chain;
+   compress_func func;
+} config;
+
+#ifdef FASTEST
+local const config configuration_table[2] = {
+/*      good lazy nice chain */
+/* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */
+/* 1 */ {4,    4,  8,    4, deflate_fast}}; /* max speed, no lazy matches */
+#else
+local const config configuration_table[10] = {
+/*      good lazy nice chain */
+/* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */
+/* 1 */ {4,    4,  8,    4, deflate_fast}, /* max speed, no lazy matches */
+/* 2 */ {4,    5, 16,    8, deflate_fast},
+/* 3 */ {4,    6, 32,   32, deflate_fast},
+
+/* 4 */ {4,    4, 16,   16, deflate_slow},  /* lazy matches */
+/* 5 */ {8,   16, 32,   32, deflate_slow},
+/* 6 */ {8,   16, 128, 128, deflate_slow},
+/* 7 */ {8,   32, 128, 256, deflate_slow},
+/* 8 */ {32, 128, 258, 1024, deflate_slow},
+/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */
+#endif
+
+/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
+ * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
+ * meaning.
+ */
+
+#define EQUAL 0
+/* result of memcmp for equal strings */
+
+#ifndef NO_DUMMY_DECL
+struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
+#endif
+
+/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */
+#define RANK(f) (((f) << 1) - ((f) > 4 ? 9 : 0))
+
+/* ===========================================================================
+ * Update a hash value with the given input byte
+ * IN  assertion: all calls to to UPDATE_HASH are made with consecutive
+ *    input characters, so that a running hash key can be computed from the
+ *    previous key instead of complete recalculation each time.
+ */
+#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
+
+
+/* ===========================================================================
+ * Insert string str in the dictionary and set match_head to the previous head
+ * of the hash chain (the most recent string with same hash key). Return
+ * the previous length of the hash chain.
+ * If this file is compiled with -DFASTEST, the compression level is forced
+ * to 1, and no hash chains are maintained.
+ * IN  assertion: all calls to to INSERT_STRING are made with consecutive
+ *    input characters and the first MIN_MATCH bytes of str are valid
+ *    (except for the last MIN_MATCH-1 bytes of the input file).
+ */
+#ifdef FASTEST
+#define INSERT_STRING(s, str, match_head) \
+   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+    match_head = s->head[s->ins_h], \
+    s->head[s->ins_h] = (Pos)(str))
+#else
+#define INSERT_STRING(s, str, match_head) \
+   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+    match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \
+    s->head[s->ins_h] = (Pos)(str))
+#endif
+
+/* ===========================================================================
+ * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
+ * prev[] will be initialized on the fly.
+ */
+#define CLEAR_HASH(s) \
+    s->head[s->hash_size-1] = NIL; \
+    zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
+
+/* ========================================================================= */
+int ZEXPORT deflateInit_(strm, level, version, stream_size)
+    z_streamp strm;
+    int level;
+    const char *version;
+    int stream_size;
+{
+    return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
+                         Z_DEFAULT_STRATEGY, version, stream_size);
+    /* To do: ignore strm->next_in if we use it as window */
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
+                  version, stream_size)
+    z_streamp strm;
+    int  level;
+    int  method;
+    int  windowBits;
+    int  memLevel;
+    int  strategy;
+    const char *version;
+    int stream_size;
+{
+    deflate_state *s;
+    int wrap = 1;
+    static const char my_version[] = ZLIB_VERSION;
+
+    ushf *overlay;
+    /* We overlay pending_buf and d_buf+l_buf. This works since the average
+     * output size for (length,distance) codes is <= 24 bits.
+     */
+
+    if (version == Z_NULL || version[0] != my_version[0] ||
+        stream_size != sizeof(z_stream)) {
+        return Z_VERSION_ERROR;
+    }
+    if (strm == Z_NULL) return Z_STREAM_ERROR;
+
+    strm->msg = Z_NULL;
+    if (strm->zalloc == (alloc_func)0) {
+#ifdef Z_SOLO
+        return Z_STREAM_ERROR;
+#else
+        strm->zalloc = zcalloc;
+        strm->opaque = (voidpf)0;
+#endif
+    }
+    if (strm->zfree == (free_func)0)
+#ifdef Z_SOLO
+        return Z_STREAM_ERROR;
+#else
+        strm->zfree = zcfree;
+#endif
+
+#ifdef FASTEST
+    if (level != 0) level = 1;
+#else
+    if (level == Z_DEFAULT_COMPRESSION) level = 6;
+#endif
+
+    if (windowBits < 0) { /* suppress zlib wrapper */
+        wrap = 0;
+        windowBits = -windowBits;
+    }
+#ifdef GZIP
+    else if (windowBits > 15) {
+        wrap = 2;       /* write gzip wrapper instead */
+        windowBits -= 16;
+    }
+#endif
+    if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
+        windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
+        strategy < 0 || strategy > Z_FIXED) {
+        return Z_STREAM_ERROR;
+    }
+    if (windowBits == 8) windowBits = 9;  /* until 256-byte window bug fixed */
+    s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
+    if (s == Z_NULL) return Z_MEM_ERROR;
+    strm->state = (struct internal_state FAR *)s;
+    s->strm = strm;
+
+    s->wrap = wrap;
+    s->gzhead = Z_NULL;
+    s->w_bits = windowBits;
+    s->w_size = 1 << s->w_bits;
+    s->w_mask = s->w_size - 1;
+
+    s->hash_bits = memLevel + 7;
+    s->hash_size = 1 << s->hash_bits;
+    s->hash_mask = s->hash_size - 1;
+    s->hash_shift =  ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
+
+    s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
+    s->prev   = (Posf *)  ZALLOC(strm, s->w_size, sizeof(Pos));
+    s->head   = (Posf *)  ZALLOC(strm, s->hash_size, sizeof(Pos));
+
+    s->high_water = 0;      /* nothing written to s->window yet */
+
+    s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
+
+    overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
+    s->pending_buf = (uchf *) overlay;
+    s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
+
+    if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
+        s->pending_buf == Z_NULL) {
+        s->status = FINISH_STATE;
+        strm->msg = ERR_MSG(Z_MEM_ERROR);
+        deflateEnd (strm);
+        return Z_MEM_ERROR;
+    }
+    s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
+    s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
+
+    s->level = level;
+    s->strategy = strategy;
+    s->method = (Byte)method;
+
+    return deflateReset(strm);
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
+    z_streamp strm;
+    const Bytef *dictionary;
+    uInt  dictLength;
+{
+    deflate_state *s;
+    uInt str, n;
+    int wrap;
+    unsigned avail;
+    z_const unsigned char *next;
+
+    if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL)
+        return Z_STREAM_ERROR;
+    s = strm->state;
+    wrap = s->wrap;
+    if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead)
+        return Z_STREAM_ERROR;
+
+    /* when using zlib wrappers, compute Adler-32 for provided dictionary */
+    if (wrap == 1)
+        strm->adler = adler32(strm->adler, dictionary, dictLength);
+    s->wrap = 0;                    /* avoid computing Adler-32 in read_buf */
+
+    /* if dictionary would fill window, just replace the history */
+    if (dictLength >= s->w_size) {
+        if (wrap == 0) {            /* already empty otherwise */
+            CLEAR_HASH(s);
+            s->strstart = 0;
+            s->block_start = 0L;
+            s->insert = 0;
+        }
+        dictionary += dictLength - s->w_size;  /* use the tail */
+        dictLength = s->w_size;
+    }
+
+    /* insert dictionary into window and hash */
+    avail = strm->avail_in;
+    next = strm->next_in;
+    strm->avail_in = dictLength;
+    strm->next_in = (z_const Bytef *)dictionary;
+    fill_window(s);
+    while (s->lookahead >= MIN_MATCH) {
+        str = s->strstart;
+        n = s->lookahead - (MIN_MATCH-1);
+        do {
+            UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);
+#ifndef FASTEST
+            s->prev[str & s->w_mask] = s->head[s->ins_h];
+#endif
+            s->head[s->ins_h] = (Pos)str;
+            str++;
+        } while (--n);
+        s->strstart = str;
+        s->lookahead = MIN_MATCH-1;
+        fill_window(s);
+    }
+    s->strstart += s->lookahead;
+    s->block_start = (long)s->strstart;
+    s->insert = s->lookahead;
+    s->lookahead = 0;
+    s->match_length = s->prev_length = MIN_MATCH-1;
+    s->match_available = 0;
+    strm->next_in = next;
+    strm->avail_in = avail;
+    s->wrap = wrap;
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateResetKeep (strm)
+    z_streamp strm;
+{
+    deflate_state *s;
+
+    if (strm == Z_NULL || strm->state == Z_NULL ||
+        strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) {
+        return Z_STREAM_ERROR;
+    }
+
+    strm->total_in = strm->total_out = 0;
+    strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
+    strm->data_type = Z_UNKNOWN;
+
+    s = (deflate_state *)strm->state;
+    s->pending = 0;
+    s->pending_out = s->pending_buf;
+
+    if (s->wrap < 0) {
+        s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */
+    }
+    s->status = s->wrap ? INIT_STATE : BUSY_STATE;
+    strm->adler =
+#ifdef GZIP
+        s->wrap == 2 ? crc32(0L, Z_NULL, 0) :
+#endif
+        adler32(0L, Z_NULL, 0);
+    s->last_flush = Z_NO_FLUSH;
+
+    _tr_init(s);
+
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateReset (strm)
+    z_streamp strm;
+{
+    int ret;
+
+    ret = deflateResetKeep(strm);
+    if (ret == Z_OK)
+        lm_init(strm->state);
+    return ret;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateSetHeader (strm, head)
+    z_streamp strm;
+    gz_headerp head;
+{
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    if (strm->state->wrap != 2) return Z_STREAM_ERROR;
+    strm->state->gzhead = head;
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflatePending (strm, pending, bits)
+    unsigned *pending;
+    int *bits;
+    z_streamp strm;
+{
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    if (pending != Z_NULL)
+        *pending = strm->state->pending;
+    if (bits != Z_NULL)
+        *bits = strm->state->bi_valid;
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflatePrime (strm, bits, value)
+    z_streamp strm;
+    int bits;
+    int value;
+{
+    deflate_state *s;
+    int put;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    s = strm->state;
+    if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3))
+        return Z_BUF_ERROR;
+    do {
+        put = Buf_size - s->bi_valid;
+        if (put > bits)
+            put = bits;
+        s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid);
+        s->bi_valid += put;
+        _tr_flush_bits(s);
+        value >>= put;
+        bits -= put;
+    } while (bits);
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateParams(strm, level, strategy)
+    z_streamp strm;
+    int level;
+    int strategy;
+{
+    deflate_state *s;
+    compress_func func;
+    int err = Z_OK;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    s = strm->state;
+
+#ifdef FASTEST
+    if (level != 0) level = 1;
+#else
+    if (level == Z_DEFAULT_COMPRESSION) level = 6;
+#endif
+    if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) {
+        return Z_STREAM_ERROR;
+    }
+    func = configuration_table[s->level].func;
+
+    if ((strategy != s->strategy || func != configuration_table[level].func) &&
+        strm->total_in != 0) {
+        /* Flush the last buffer: */
+        err = deflate(strm, Z_BLOCK);
+        if (err == Z_BUF_ERROR && s->pending == 0)
+            err = Z_OK;
+    }
+    if (s->level != level) {
+        s->level = level;
+        s->max_lazy_match   = configuration_table[level].max_lazy;
+        s->good_match       = configuration_table[level].good_length;
+        s->nice_match       = configuration_table[level].nice_length;
+        s->max_chain_length = configuration_table[level].max_chain;
+    }
+    s->strategy = strategy;
+    return err;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
+    z_streamp strm;
+    int good_length;
+    int max_lazy;
+    int nice_length;
+    int max_chain;
+{
+    deflate_state *s;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    s = strm->state;
+    s->good_match = good_length;
+    s->max_lazy_match = max_lazy;
+    s->nice_match = nice_length;
+    s->max_chain_length = max_chain;
+    return Z_OK;
+}
+
+/* =========================================================================
+ * For the default windowBits of 15 and memLevel of 8, this function returns
+ * a close to exact, as well as small, upper bound on the compressed size.
+ * They are coded as constants here for a reason--if the #define's are
+ * changed, then this function needs to be changed as well.  The return
+ * value for 15 and 8 only works for those exact settings.
+ *
+ * For any setting other than those defaults for windowBits and memLevel,
+ * the value returned is a conservative worst case for the maximum expansion
+ * resulting from using fixed blocks instead of stored blocks, which deflate
+ * can emit on compressed data for some combinations of the parameters.
+ *
+ * This function could be more sophisticated to provide closer upper bounds for
+ * every combination of windowBits and memLevel.  But even the conservative
+ * upper bound of about 14% expansion does not seem onerous for output buffer
+ * allocation.
+ */
+uLong ZEXPORT deflateBound(strm, sourceLen)
+    z_streamp strm;
+    uLong sourceLen;
+{
+    deflate_state *s;
+    uLong complen, wraplen;
+    Bytef *str;
+
+    /* conservative upper bound for compressed data */
+    complen = sourceLen +
+              ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5;
+
+    /* if can't get parameters, return conservative bound plus zlib wrapper */
+    if (strm == Z_NULL || strm->state == Z_NULL)
+        return complen + 6;
+
+    /* compute wrapper length */
+    s = strm->state;
+    switch (s->wrap) {
+    case 0:                                 /* raw deflate */
+        wraplen = 0;
+        break;
+    case 1:                                 /* zlib wrapper */
+        wraplen = 6 + (s->strstart ? 4 : 0);
+        break;
+    case 2:                                 /* gzip wrapper */
+        wraplen = 18;
+        if (s->gzhead != Z_NULL) {          /* user-supplied gzip header */
+            if (s->gzhead->extra != Z_NULL)
+                wraplen += 2 + s->gzhead->extra_len;
+            str = s->gzhead->name;
+            if (str != Z_NULL)
+                do {
+                    wraplen++;
+                } while (*str++);
+            str = s->gzhead->comment;
+            if (str != Z_NULL)
+                do {
+                    wraplen++;
+                } while (*str++);
+            if (s->gzhead->hcrc)
+                wraplen += 2;
+        }
+        break;
+    default:                                /* for compiler happiness */
+        wraplen = 6;
+    }
+
+    /* if not default parameters, return conservative bound */
+    if (s->w_bits != 15 || s->hash_bits != 8 + 7)
+        return complen + wraplen;
+
+    /* default settings: return tight bound for that case */
+    return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
+           (sourceLen >> 25) + 13 - 6 + wraplen;
+}
+
+/* =========================================================================
+ * Put a short in the pending buffer. The 16-bit value is put in MSB order.
+ * IN assertion: the stream state is correct and there is enough room in
+ * pending_buf.
+ */
+local void putShortMSB (s, b)
+    deflate_state *s;
+    uInt b;
+{
+    put_byte(s, (Byte)(b >> 8));
+    put_byte(s, (Byte)(b & 0xff));
+}
+
+/* =========================================================================
+ * Flush as much pending output as possible. All deflate() output goes
+ * through this function so some applications may wish to modify it
+ * to avoid allocating a large strm->next_out buffer and copying into it.
+ * (See also read_buf()).
+ */
+local void flush_pending(strm)
+    z_streamp strm;
+{
+    unsigned len;
+    deflate_state *s = strm->state;
+
+    _tr_flush_bits(s);
+    len = s->pending;
+    if (len > strm->avail_out) len = strm->avail_out;
+    if (len == 0) return;
+
+    zmemcpy(strm->next_out, s->pending_out, len);
+    strm->next_out  += len;
+    s->pending_out  += len;
+    strm->total_out += len;
+    strm->avail_out  -= len;
+    s->pending -= len;
+    if (s->pending == 0) {
+        s->pending_out = s->pending_buf;
+    }
+}
+
+/* ========================================================================= */
+int ZEXPORT deflate (strm, flush)
+    z_streamp strm;
+    int flush;
+{
+    int old_flush; /* value of flush param for previous deflate call */
+    deflate_state *s;
+
+    if (strm == Z_NULL || strm->state == Z_NULL ||
+        flush > Z_BLOCK || flush < 0) {
+        return Z_STREAM_ERROR;
+    }
+    s = strm->state;
+
+    if (strm->next_out == Z_NULL ||
+        (strm->next_in == Z_NULL && strm->avail_in != 0) ||
+        (s->status == FINISH_STATE && flush != Z_FINISH)) {
+        ERR_RETURN(strm, Z_STREAM_ERROR);
+    }
+    if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
+
+    s->strm = strm; /* just in case */
+    old_flush = s->last_flush;
+    s->last_flush = flush;
+
+    /* Write the header */
+    if (s->status == INIT_STATE) {
+#ifdef GZIP
+        if (s->wrap == 2) {
+            strm->adler = crc32(0L, Z_NULL, 0);
+            put_byte(s, 31);
+            put_byte(s, 139);
+            put_byte(s, 8);
+            if (s->gzhead == Z_NULL) {
+                put_byte(s, 0);
+                put_byte(s, 0);
+                put_byte(s, 0);
+                put_byte(s, 0);
+                put_byte(s, 0);
+                put_byte(s, s->level == 9 ? 2 :
+                            (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
+                             4 : 0));
+                put_byte(s, OS_CODE);
+                s->status = BUSY_STATE;
+            }
+            else {
+                put_byte(s, (s->gzhead->text ? 1 : 0) +
+                            (s->gzhead->hcrc ? 2 : 0) +
+                            (s->gzhead->extra == Z_NULL ? 0 : 4) +
+                            (s->gzhead->name == Z_NULL ? 0 : 8) +
+                            (s->gzhead->comment == Z_NULL ? 0 : 16)
+                        );
+                put_byte(s, (Byte)(s->gzhead->time & 0xff));
+                put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff));
+                put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff));
+                put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff));
+                put_byte(s, s->level == 9 ? 2 :
+                            (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
+                             4 : 0));
+                put_byte(s, s->gzhead->os & 0xff);
+                if (s->gzhead->extra != Z_NULL) {
+                    put_byte(s, s->gzhead->extra_len & 0xff);
+                    put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);
+                }
+                if (s->gzhead->hcrc)
+                    strm->adler = crc32(strm->adler, s->pending_buf,
+                                        s->pending);
+                s->gzindex = 0;
+                s->status = EXTRA_STATE;
+            }
+        }
+        else
+#endif
+        {
+            uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
+            uInt level_flags;
+
+            if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
+                level_flags = 0;
+            else if (s->level < 6)
+                level_flags = 1;
+            else if (s->level == 6)
+                level_flags = 2;
+            else
+                level_flags = 3;
+            header |= (level_flags << 6);
+            if (s->strstart != 0) header |= PRESET_DICT;
+            header += 31 - (header % 31);
+
+            s->status = BUSY_STATE;
+            putShortMSB(s, header);
+
+            /* Save the adler32 of the preset dictionary: */
+            if (s->strstart != 0) {
+                putShortMSB(s, (uInt)(strm->adler >> 16));
+                putShortMSB(s, (uInt)(strm->adler & 0xffff));
+            }
+            strm->adler = adler32(0L, Z_NULL, 0);
+        }
+    }
+#ifdef GZIP
+    if (s->status == EXTRA_STATE) {
+        if (s->gzhead->extra != Z_NULL) {
+            uInt beg = s->pending;  /* start of bytes to update crc */
+
+            while (s->gzindex < (s->gzhead->extra_len & 0xffff)) {
+                if (s->pending == s->pending_buf_size) {
+                    if (s->gzhead->hcrc && s->pending > beg)
+                        strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                            s->pending - beg);
+                    flush_pending(strm);
+                    beg = s->pending;
+                    if (s->pending == s->pending_buf_size)
+                        break;
+                }
+                put_byte(s, s->gzhead->extra[s->gzindex]);
+                s->gzindex++;
+            }
+            if (s->gzhead->hcrc && s->pending > beg)
+                strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                    s->pending - beg);
+            if (s->gzindex == s->gzhead->extra_len) {
+                s->gzindex = 0;
+                s->status = NAME_STATE;
+            }
+        }
+        else
+            s->status = NAME_STATE;
+    }
+    if (s->status == NAME_STATE) {
+        if (s->gzhead->name != Z_NULL) {
+            uInt beg = s->pending;  /* start of bytes to update crc */
+            int val;
+
+            do {
+                if (s->pending == s->pending_buf_size) {
+                    if (s->gzhead->hcrc && s->pending > beg)
+                        strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                            s->pending - beg);
+                    flush_pending(strm);
+                    beg = s->pending;
+                    if (s->pending == s->pending_buf_size) {
+                        val = 1;
+                        break;
+                    }
+                }
+                val = s->gzhead->name[s->gzindex++];
+                put_byte(s, val);
+            } while (val != 0);
+            if (s->gzhead->hcrc && s->pending > beg)
+                strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                    s->pending - beg);
+            if (val == 0) {
+                s->gzindex = 0;
+                s->status = COMMENT_STATE;
+            }
+        }
+        else
+            s->status = COMMENT_STATE;
+    }
+    if (s->status == COMMENT_STATE) {
+        if (s->gzhead->comment != Z_NULL) {
+            uInt beg = s->pending;  /* start of bytes to update crc */
+            int val;
+
+            do {
+                if (s->pending == s->pending_buf_size) {
+                    if (s->gzhead->hcrc && s->pending > beg)
+                        strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                            s->pending - beg);
+                    flush_pending(strm);
+                    beg = s->pending;
+                    if (s->pending == s->pending_buf_size) {
+                        val = 1;
+                        break;
+                    }
+                }
+                val = s->gzhead->comment[s->gzindex++];
+                put_byte(s, val);
+            } while (val != 0);
+            if (s->gzhead->hcrc && s->pending > beg)
+                strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                    s->pending - beg);
+            if (val == 0)
+                s->status = HCRC_STATE;
+        }
+        else
+            s->status = HCRC_STATE;
+    }
+    if (s->status == HCRC_STATE) {
+        if (s->gzhead->hcrc) {
+            if (s->pending + 2 > s->pending_buf_size)
+                flush_pending(strm);
+            if (s->pending + 2 <= s->pending_buf_size) {
+                put_byte(s, (Byte)(strm->adler & 0xff));
+                put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
+                strm->adler = crc32(0L, Z_NULL, 0);
+                s->status = BUSY_STATE;
+            }
+        }
+        else
+            s->status = BUSY_STATE;
+    }
+#endif
+
+    /* Flush as much pending output as possible */
+    if (s->pending != 0) {
+        flush_pending(strm);
+        if (strm->avail_out == 0) {
+            /* Since avail_out is 0, deflate will be called again with
+             * more output space, but possibly with both pending and
+             * avail_in equal to zero. There won't be anything to do,
+             * but this is not an error situation so make sure we
+             * return OK instead of BUF_ERROR at next call of deflate:
+             */
+            s->last_flush = -1;
+            return Z_OK;
+        }
+
+    /* Make sure there is something to do and avoid duplicate consecutive
+     * flushes. For repeated and useless calls with Z_FINISH, we keep
+     * returning Z_STREAM_END instead of Z_BUF_ERROR.
+     */
+    } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) &&
+               flush != Z_FINISH) {
+        ERR_RETURN(strm, Z_BUF_ERROR);
+    }
+
+    /* User must not provide more input after the first FINISH: */
+    if (s->status == FINISH_STATE && strm->avail_in != 0) {
+        ERR_RETURN(strm, Z_BUF_ERROR);
+    }
+
+    /* Start a new block or continue the current one.
+     */
+    if (strm->avail_in != 0 || s->lookahead != 0 ||
+        (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
+        block_state bstate;
+
+        bstate = s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) :
+                    (s->strategy == Z_RLE ? deflate_rle(s, flush) :
+                        (*(configuration_table[s->level].func))(s, flush));
+
+        if (bstate == finish_started || bstate == finish_done) {
+            s->status = FINISH_STATE;
+        }
+        if (bstate == need_more || bstate == finish_started) {
+            if (strm->avail_out == 0) {
+                s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
+            }
+            return Z_OK;
+            /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
+             * of deflate should use the same flush parameter to make sure
+             * that the flush is complete. So we don't have to output an
+             * empty block here, this will be done at next call. This also
+             * ensures that for a very small output buffer, we emit at most
+             * one empty block.
+             */
+        }
+        if (bstate == block_done) {
+            if (flush == Z_PARTIAL_FLUSH) {
+                _tr_align(s);
+            } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */
+                _tr_stored_block(s, (char*)0, 0L, 0);
+                /* For a full flush, this empty block will be recognized
+                 * as a special marker by inflate_sync().
+                 */
+                if (flush == Z_FULL_FLUSH) {
+                    CLEAR_HASH(s);             /* forget history */
+                    if (s->lookahead == 0) {
+                        s->strstart = 0;
+                        s->block_start = 0L;
+                        s->insert = 0;
+                    }
+                }
+            }
+            flush_pending(strm);
+            if (strm->avail_out == 0) {
+              s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
+              return Z_OK;
+            }
+        }
+    }
+    Assert(strm->avail_out > 0, "bug2");
+
+    if (flush != Z_FINISH) return Z_OK;
+    if (s->wrap <= 0) return Z_STREAM_END;
+
+    /* Write the trailer */
+#ifdef GZIP
+    if (s->wrap == 2) {
+        put_byte(s, (Byte)(strm->adler & 0xff));
+        put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
+        put_byte(s, (Byte)((strm->adler >> 16) & 0xff));
+        put_byte(s, (Byte)((strm->adler >> 24) & 0xff));
+        put_byte(s, (Byte)(strm->total_in & 0xff));
+        put_byte(s, (Byte)((strm->total_in >> 8) & 0xff));
+        put_byte(s, (Byte)((strm->total_in >> 16) & 0xff));
+        put_byte(s, (Byte)((strm->total_in >> 24) & 0xff));
+    }
+    else
+#endif
+    {
+        putShortMSB(s, (uInt)(strm->adler >> 16));
+        putShortMSB(s, (uInt)(strm->adler & 0xffff));
+    }
+    flush_pending(strm);
+    /* If avail_out is zero, the application will call deflate again
+     * to flush the rest.
+     */
+    if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */
+    return s->pending != 0 ? Z_OK : Z_STREAM_END;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateEnd (strm)
+    z_streamp strm;
+{
+    int status;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+
+    status = strm->state->status;
+    if (status != INIT_STATE &&
+        status != EXTRA_STATE &&
+        status != NAME_STATE &&
+        status != COMMENT_STATE &&
+        status != HCRC_STATE &&
+        status != BUSY_STATE &&
+        status != FINISH_STATE) {
+      return Z_STREAM_ERROR;
+    }
+
+    /* Deallocate in reverse order of allocations: */
+    TRY_FREE(strm, strm->state->pending_buf);
+    TRY_FREE(strm, strm->state->head);
+    TRY_FREE(strm, strm->state->prev);
+    TRY_FREE(strm, strm->state->window);
+
+    ZFREE(strm, strm->state);
+    strm->state = Z_NULL;
+
+    return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
+}
+
+/* =========================================================================
+ * Copy the source state to the destination state.
+ * To simplify the source, this is not supported for 16-bit MSDOS (which
+ * doesn't have enough memory anyway to duplicate compression states).
+ */
+int ZEXPORT deflateCopy (dest, source)
+    z_streamp dest;
+    z_streamp source;
+{
+#ifdef MAXSEG_64K
+    return Z_STREAM_ERROR;
+#else
+    deflate_state *ds;
+    deflate_state *ss;
+    ushf *overlay;
+
+
+    if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
+        return Z_STREAM_ERROR;
+    }
+
+    ss = source->state;
+
+    zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
+
+    ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
+    if (ds == Z_NULL) return Z_MEM_ERROR;
+    dest->state = (struct internal_state FAR *) ds;
+    zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state));
+    ds->strm = dest;
+
+    ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
+    ds->prev   = (Posf *)  ZALLOC(dest, ds->w_size, sizeof(Pos));
+    ds->head   = (Posf *)  ZALLOC(dest, ds->hash_size, sizeof(Pos));
+    overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
+    ds->pending_buf = (uchf *) overlay;
+
+    if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
+        ds->pending_buf == Z_NULL) {
+        deflateEnd (dest);
+        return Z_MEM_ERROR;
+    }
+    /* following zmemcpy do not work for 16-bit MSDOS */
+    zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
+    zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos));
+    zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos));
+    zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
+
+    ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
+    ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
+    ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
+
+    ds->l_desc.dyn_tree = ds->dyn_ltree;
+    ds->d_desc.dyn_tree = ds->dyn_dtree;
+    ds->bl_desc.dyn_tree = ds->bl_tree;
+
+    return Z_OK;
+#endif /* MAXSEG_64K */
+}
+
+/* ===========================================================================
+ * Read a new buffer from the current input stream, update the adler32
+ * and total number of bytes read.  All deflate() input goes through
+ * this function so some applications may wish to modify it to avoid
+ * allocating a large strm->next_in buffer and copying from it.
+ * (See also flush_pending()).
+ */
+local int read_buf(strm, buf, size)
+    z_streamp strm;
+    Bytef *buf;
+    unsigned size;
+{
+    unsigned len = strm->avail_in;
+
+    if (len > size) len = size;
+    if (len == 0) return 0;
+
+    strm->avail_in  -= len;
+
+    zmemcpy(buf, strm->next_in, len);
+    if (strm->state->wrap == 1) {
+        strm->adler = adler32(strm->adler, buf, len);
+    }
+#ifdef GZIP
+    else if (strm->state->wrap == 2) {
+        strm->adler = crc32(strm->adler, buf, len);
+    }
+#endif
+    strm->next_in  += len;
+    strm->total_in += len;
+
+    return (int)len;
+}
+
+/* ===========================================================================
+ * Initialize the "longest match" routines for a new zlib stream
+ */
+local void lm_init (s)
+    deflate_state *s;
+{
+    s->window_size = (ulg)2L*s->w_size;
+
+    CLEAR_HASH(s);
+
+    /* Set the default configuration parameters:
+     */
+    s->max_lazy_match   = configuration_table[s->level].max_lazy;
+    s->good_match       = configuration_table[s->level].good_length;
+    s->nice_match       = configuration_table[s->level].nice_length;
+    s->max_chain_length = configuration_table[s->level].max_chain;
+
+    s->strstart = 0;
+    s->block_start = 0L;
+    s->lookahead = 0;
+    s->insert = 0;
+    s->match_length = s->prev_length = MIN_MATCH-1;
+    s->match_available = 0;
+    s->ins_h = 0;
+#ifndef FASTEST
+#ifdef ASMV
+    match_init(); /* initialize the asm code */
+#endif
+#endif
+}
+
+#ifndef FASTEST
+/* ===========================================================================
+ * Set match_start to the longest match starting at the given string and
+ * return its length. Matches shorter or equal to prev_length are discarded,
+ * in which case the result is equal to prev_length and match_start is
+ * garbage.
+ * IN assertions: cur_match is the head of the hash chain for the current
+ *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
+ * OUT assertion: the match length is not greater than s->lookahead.
+ */
+#ifndef ASMV
+/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
+ * match.S. The code will be functionally equivalent.
+ */
+local uInt longest_match(s, cur_match)
+    deflate_state *s;
+    IPos cur_match;                             /* current match */
+{
+    unsigned chain_length = s->max_chain_length;/* max hash chain length */
+    register Bytef *scan = s->window + s->strstart; /* current string */
+    register Bytef *match;                       /* matched string */
+    register int len;                           /* length of current match */
+    int best_len = s->prev_length;              /* best match length so far */
+    int nice_match = s->nice_match;             /* stop if match long enough */
+    IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
+        s->strstart - (IPos)MAX_DIST(s) : NIL;
+    /* Stop when cur_match becomes <= limit. To simplify the code,
+     * we prevent matches with the string of window index 0.
+     */
+    Posf *prev = s->prev;
+    uInt wmask = s->w_mask;
+
+#ifdef UNALIGNED_OK
+    /* Compare two bytes at a time. Note: this is not always beneficial.
+     * Try with and without -DUNALIGNED_OK to check.
+     */
+    register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
+    register ush scan_start = *(ushf*)scan;
+    register ush scan_end   = *(ushf*)(scan+best_len-1);
+#else
+    register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+    register Byte scan_end1  = scan[best_len-1];
+    register Byte scan_end   = scan[best_len];
+#endif
+
+    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+     * It is easy to get rid of this optimization if necessary.
+     */
+    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+    /* Do not waste too much time if we already have a good match: */
+    if (s->prev_length >= s->good_match) {
+        chain_length >>= 2;
+    }
+    /* Do not look for matches beyond the end of the input. This is necessary
+     * to make deflate deterministic.
+     */
+    if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
+
+    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+    do {
+        Assert(cur_match < s->strstart, "no future");
+        match = s->window + cur_match;
+
+        /* Skip to next match if the match length cannot increase
+         * or if the match length is less than 2.  Note that the checks below
+         * for insufficient lookahead only occur occasionally for performance
+         * reasons.  Therefore uninitialized memory will be accessed, and
+         * conditional jumps will be made that depend on those values.
+         * However the length of the match is limited to the lookahead, so
+         * the output of deflate is not affected by the uninitialized values.
+         */
+#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
+        /* This code assumes sizeof(unsigned short) == 2. Do not use
+         * UNALIGNED_OK if your compiler uses a different size.
+         */
+        if (*(ushf*)(match+best_len-1) != scan_end ||
+            *(ushf*)match != scan_start) continue;
+
+        /* It is not necessary to compare scan[2] and match[2] since they are
+         * always equal when the other bytes match, given that the hash keys
+         * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
+         * strstart+3, +5, ... up to strstart+257. We check for insufficient
+         * lookahead only every 4th comparison; the 128th check will be made
+         * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
+         * necessary to put more guard bytes at the end of the window, or
+         * to check more often for insufficient lookahead.
+         */
+        Assert(scan[2] == match[2], "scan[2]?");
+        scan++, match++;
+        do {
+        } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 scan < strend);
+        /* The funny "do {}" generates better code on most compilers */
+
+        /* Here, scan <= window+strstart+257 */
+        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+        if (*scan == *match) scan++;
+
+        len = (MAX_MATCH - 1) - (int)(strend-scan);
+        scan = strend - (MAX_MATCH-1);
+
+#else /* UNALIGNED_OK */
+
+        if (match[best_len]   != scan_end  ||
+            match[best_len-1] != scan_end1 ||
+            *match            != *scan     ||
+            *++match          != scan[1])      continue;
+
+        /* The check at best_len-1 can be removed because it will be made
+         * again later. (This heuristic is not always a win.)
+         * It is not necessary to compare scan[2] and match[2] since they
+         * are always equal when the other bytes match, given that
+         * the hash keys are equal and that HASH_BITS >= 8.
+         */
+        scan += 2, match++;
+        Assert(*scan == *match, "match[2]?");
+
+        /* We check for insufficient lookahead only every 8th comparison;
+         * the 256th check will be made at strstart+258.
+         */
+        do {
+        } while (*++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 scan < strend);
+
+        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+        len = MAX_MATCH - (int)(strend - scan);
+        scan = strend - MAX_MATCH;
+
+#endif /* UNALIGNED_OK */
+
+        if (len > best_len) {
+            s->match_start = cur_match;
+            best_len = len;
+            if (len >= nice_match) break;
+#ifdef UNALIGNED_OK
+            scan_end = *(ushf*)(scan+best_len-1);
+#else
+            scan_end1  = scan[best_len-1];
+            scan_end   = scan[best_len];
+#endif
+        }
+    } while ((cur_match = prev[cur_match & wmask]) > limit
+             && --chain_length != 0);
+
+    if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
+    return s->lookahead;
+}
+#endif /* ASMV */
+
+#else /* FASTEST */
+
+/* ---------------------------------------------------------------------------
+ * Optimized version for FASTEST only
+ */
+local uInt longest_match(s, cur_match)
+    deflate_state *s;
+    IPos cur_match;                             /* current match */
+{
+    register Bytef *scan = s->window + s->strstart; /* current string */
+    register Bytef *match;                       /* matched string */
+    register int len;                           /* length of current match */
+    register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+
+    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+     * It is easy to get rid of this optimization if necessary.
+     */
+    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+    Assert(cur_match < s->strstart, "no future");
+
+    match = s->window + cur_match;
+
+    /* Return failure if the match length is less than 2:
+     */
+    if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
+
+    /* The check at best_len-1 can be removed because it will be made
+     * again later. (This heuristic is not always a win.)
+     * It is not necessary to compare scan[2] and match[2] since they
+     * are always equal when the other bytes match, given that
+     * the hash keys are equal and that HASH_BITS >= 8.
+     */
+    scan += 2, match += 2;
+    Assert(*scan == *match, "match[2]?");
+
+    /* We check for insufficient lookahead only every 8th comparison;
+     * the 256th check will be made at strstart+258.
+     */
+    do {
+    } while (*++scan == *++match && *++scan == *++match &&
+             *++scan == *++match && *++scan == *++match &&
+             *++scan == *++match && *++scan == *++match &&
+             *++scan == *++match && *++scan == *++match &&
+             scan < strend);
+
+    Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+    len = MAX_MATCH - (int)(strend - scan);
+
+    if (len < MIN_MATCH) return MIN_MATCH - 1;
+
+    s->match_start = cur_match;
+    return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead;
+}
+
+#endif /* FASTEST */
+
+#ifdef DEBUG
+/* ===========================================================================
+ * Check that the match at match_start is indeed a match.
+ */
+local void check_match(s, start, match, length)
+    deflate_state *s;
+    IPos start, match;
+    int length;
+{
+    /* check that the match is indeed a match */
+    if (zmemcmp(s->window + match,
+                s->window + start, length) != EQUAL) {
+        fprintf(stderr, " start %u, match %u, length %d\n",
+                start, match, length);
+        do {
+            fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
+        } while (--length != 0);
+        z_error("invalid match");
+    }
+    if (z_verbose > 1) {
+        fprintf(stderr,"\\[%d,%d]", start-match, length);
+        do { putc(s->window[start++], stderr); } while (--length != 0);
+    }
+}
+#else
+#  define check_match(s, start, match, length)
+#endif /* DEBUG */
+
+/* ===========================================================================
+ * Fill the window when the lookahead becomes insufficient.
+ * Updates strstart and lookahead.
+ *
+ * IN assertion: lookahead < MIN_LOOKAHEAD
+ * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
+ *    At least one byte has been read, or avail_in == 0; reads are
+ *    performed for at least two bytes (required for the zip translate_eol
+ *    option -- not supported here).
+ */
+local void fill_window(s)
+    deflate_state *s;
+{
+    register unsigned n, m;
+    register Posf *p;
+    unsigned more;    /* Amount of free space at the end of the window. */
+    uInt wsize = s->w_size;
+
+    Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead");
+
+    do {
+        more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
+
+        /* Deal with !@#$% 64K limit: */
+        if (sizeof(int) <= 2) {
+            if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
+                more = wsize;
+
+            } else if (more == (unsigned)(-1)) {
+                /* Very unlikely, but possible on 16 bit machine if
+                 * strstart == 0 && lookahead == 1 (input done a byte at time)
+                 */
+                more--;
+            }
+        }
+
+        /* If the window is almost full and there is insufficient lookahead,
+         * move the upper half to the lower one to make room in the upper half.
+         */
+        if (s->strstart >= wsize+MAX_DIST(s)) {
+
+            zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
+            s->match_start -= wsize;
+            s->strstart    -= wsize; /* we now have strstart >= MAX_DIST */
+            s->block_start -= (long) wsize;
+
+            /* Slide the hash table (could be avoided with 32 bit values
+               at the expense of memory usage). We slide even when level == 0
+               to keep the hash table consistent if we switch back to level > 0
+               later. (Using level 0 permanently is not an optimal usage of
+               zlib, so we don't care about this pathological case.)
+             */
+            n = s->hash_size;
+            p = &s->head[n];
+            do {
+                m = *--p;
+                *p = (Pos)(m >= wsize ? m-wsize : NIL);
+            } while (--n);
+
+            n = wsize;
+#ifndef FASTEST
+            p = &s->prev[n];
+            do {
+                m = *--p;
+                *p = (Pos)(m >= wsize ? m-wsize : NIL);
+                /* If n is not on any hash chain, prev[n] is garbage but
+                 * its value will never be used.
+                 */
+            } while (--n);
+#endif
+            more += wsize;
+        }
+        if (s->strm->avail_in == 0) break;
+
+        /* If there was no sliding:
+         *    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
+         *    more == window_size - lookahead - strstart
+         * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
+         * => more >= window_size - 2*WSIZE + 2
+         * In the BIG_MEM or MMAP case (not yet supported),
+         *   window_size == input_size + MIN_LOOKAHEAD  &&
+         *   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
+         * Otherwise, window_size == 2*WSIZE so more >= 2.
+         * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
+         */
+        Assert(more >= 2, "more < 2");
+
+        n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
+        s->lookahead += n;
+
+        /* Initialize the hash value now that we have some input: */
+        if (s->lookahead + s->insert >= MIN_MATCH) {
+            uInt str = s->strstart - s->insert;
+            s->ins_h = s->window[str];
+            UPDATE_HASH(s, s->ins_h, s->window[str + 1]);
+#if MIN_MATCH != 3
+            Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+            while (s->insert) {
+                UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);
+#ifndef FASTEST
+                s->prev[str & s->w_mask] = s->head[s->ins_h];
+#endif
+                s->head[s->ins_h] = (Pos)str;
+                str++;
+                s->insert--;
+                if (s->lookahead + s->insert < MIN_MATCH)
+                    break;
+            }
+        }
+        /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
+         * but this is not important since only literal bytes will be emitted.
+         */
+
+    } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
+
+    /* If the WIN_INIT bytes after the end of the current data have never been
+     * written, then zero those bytes in order to avoid memory check reports of
+     * the use of uninitialized (or uninitialised as Julian writes) bytes by
+     * the longest match routines.  Update the high water mark for the next
+     * time through here.  WIN_INIT is set to MAX_MATCH since the longest match
+     * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.
+     */
+    if (s->high_water < s->window_size) {
+        ulg curr = s->strstart + (ulg)(s->lookahead);
+        ulg init;
+
+        if (s->high_water < curr) {
+            /* Previous high water mark below current data -- zero WIN_INIT
+             * bytes or up to end of window, whichever is less.
+             */
+            init = s->window_size - curr;
+            if (init > WIN_INIT)
+                init = WIN_INIT;
+            zmemzero(s->window + curr, (unsigned)init);
+            s->high_water = curr + init;
+        }
+        else if (s->high_water < (ulg)curr + WIN_INIT) {
+            /* High water mark at or above current data, but below current data
+             * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up
+             * to end of window, whichever is less.
+             */
+            init = (ulg)curr + WIN_INIT - s->high_water;
+            if (init > s->window_size - s->high_water)
+                init = s->window_size - s->high_water;
+            zmemzero(s->window + s->high_water, (unsigned)init);
+            s->high_water += init;
+        }
+    }
+
+    Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,
+           "not enough room for search");
+}
+
+/* ===========================================================================
+ * Flush the current block, with given end-of-file flag.
+ * IN assertion: strstart is set to the end of the current match.
+ */
+#define FLUSH_BLOCK_ONLY(s, last) { \
+   _tr_flush_block(s, (s->block_start >= 0L ? \
+                   (charf *)&s->window[(unsigned)s->block_start] : \
+                   (charf *)Z_NULL), \
+                (ulg)((long)s->strstart - s->block_start), \
+                (last)); \
+   s->block_start = s->strstart; \
+   flush_pending(s->strm); \
+   Tracev((stderr,"[FLUSH]")); \
+}
+
+/* Same but force premature exit if necessary. */
+#define FLUSH_BLOCK(s, last) { \
+   FLUSH_BLOCK_ONLY(s, last); \
+   if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \
+}
+
+/* ===========================================================================
+ * Copy without compression as much as possible from the input stream, return
+ * the current block state.
+ * This function does not insert new strings in the dictionary since
+ * uncompressible data is probably not useful. This function is used
+ * only for the level=0 compression option.
+ * NOTE: this function should be optimized to avoid extra copying from
+ * window to pending_buf.
+ */
+local block_state deflate_stored(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
+     * to pending_buf_size, and each stored block has a 5 byte header:
+     */
+    ulg max_block_size = 0xffff;
+    ulg max_start;
+
+    if (max_block_size > s->pending_buf_size - 5) {
+        max_block_size = s->pending_buf_size - 5;
+    }
+
+    /* Copy as much as possible from input to output: */
+    for (;;) {
+        /* Fill the window as much as possible: */
+        if (s->lookahead <= 1) {
+
+            Assert(s->strstart < s->w_size+MAX_DIST(s) ||
+                   s->block_start >= (long)s->w_size, "slide too late");
+
+            fill_window(s);
+            if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
+
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+        Assert(s->block_start >= 0L, "block gone");
+
+        s->strstart += s->lookahead;
+        s->lookahead = 0;
+
+        /* Emit a stored block if pending_buf will be full: */
+        max_start = s->block_start + max_block_size;
+        if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
+            /* strstart == 0 is possible when wraparound on 16-bit machine */
+            s->lookahead = (uInt)(s->strstart - max_start);
+            s->strstart = (uInt)max_start;
+            FLUSH_BLOCK(s, 0);
+        }
+        /* Flush if we may have to slide, otherwise block_start may become
+         * negative and the data will be gone:
+         */
+        if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
+            FLUSH_BLOCK(s, 0);
+        }
+    }
+    s->insert = 0;
+    if (flush == Z_FINISH) {
+        FLUSH_BLOCK(s, 1);
+        return finish_done;
+    }
+    if ((long)s->strstart > s->block_start)
+        FLUSH_BLOCK(s, 0);
+    return block_done;
+}
+
+/* ===========================================================================
+ * Compress as much as possible from the input stream, return the current
+ * block state.
+ * This function does not perform lazy evaluation of matches and inserts
+ * new strings in the dictionary only for unmatched strings or for short
+ * matches. It is used only for the fast compression options.
+ */
+local block_state deflate_fast(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    IPos hash_head;       /* head of the hash chain */
+    int bflush;           /* set if current block must be flushed */
+
+    for (;;) {
+        /* Make sure that we always have enough lookahead, except
+         * at the end of the input file. We need MAX_MATCH bytes
+         * for the next match, plus MIN_MATCH bytes to insert the
+         * string following the next match.
+         */
+        if (s->lookahead < MIN_LOOKAHEAD) {
+            fill_window(s);
+            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+                return need_more;
+            }
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+
+        /* Insert the string window[strstart .. strstart+2] in the
+         * dictionary, and set hash_head to the head of the hash chain:
+         */
+        hash_head = NIL;
+        if (s->lookahead >= MIN_MATCH) {
+            INSERT_STRING(s, s->strstart, hash_head);
+        }
+
+        /* Find the longest match, discarding those <= prev_length.
+         * At this point we have always match_length < MIN_MATCH
+         */
+        if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
+            /* To simplify the code, we prevent matches with the string
+             * of window index 0 (in particular we have to avoid a match
+             * of the string with itself at the start of the input file).
+             */
+            s->match_length = longest_match (s, hash_head);
+            /* longest_match() sets match_start */
+        }
+        if (s->match_length >= MIN_MATCH) {
+            check_match(s, s->strstart, s->match_start, s->match_length);
+
+            _tr_tally_dist(s, s->strstart - s->match_start,
+                           s->match_length - MIN_MATCH, bflush);
+
+            s->lookahead -= s->match_length;
+
+            /* Insert new strings in the hash table only if the match length
+             * is not too large. This saves time but degrades compression.
+             */
+#ifndef FASTEST
+            if (s->match_length <= s->max_insert_length &&
+                s->lookahead >= MIN_MATCH) {
+                s->match_length--; /* string at strstart already in table */
+                do {
+                    s->strstart++;
+                    INSERT_STRING(s, s->strstart, hash_head);
+                    /* strstart never exceeds WSIZE-MAX_MATCH, so there are
+                     * always MIN_MATCH bytes ahead.
+                     */
+                } while (--s->match_length != 0);
+                s->strstart++;
+            } else
+#endif
+            {
+                s->strstart += s->match_length;
+                s->match_length = 0;
+                s->ins_h = s->window[s->strstart];
+                UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+#if MIN_MATCH != 3
+                Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+                /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
+                 * matter since it will be recomputed at next deflate call.
+                 */
+            }
+        } else {
+            /* No match, output a literal byte */
+            Tracevv((stderr,"%c", s->window[s->strstart]));
+            _tr_tally_lit (s, s->window[s->strstart], bflush);
+            s->lookahead--;
+            s->strstart++;
+        }
+        if (bflush) FLUSH_BLOCK(s, 0);
+    }
+    s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;
+    if (flush == Z_FINISH) {
+        FLUSH_BLOCK(s, 1);
+        return finish_done;
+    }
+    if (s->last_lit)
+        FLUSH_BLOCK(s, 0);
+    return block_done;
+}
+
+#ifndef FASTEST
+/* ===========================================================================
+ * Same as above, but achieves better compression. We use a lazy
+ * evaluation for matches: a match is finally adopted only if there is
+ * no better match at the next window position.
+ */
+local block_state deflate_slow(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    IPos hash_head;          /* head of hash chain */
+    int bflush;              /* set if current block must be flushed */
+
+    /* Process the input block. */
+    for (;;) {
+        /* Make sure that we always have enough lookahead, except
+         * at the end of the input file. We need MAX_MATCH bytes
+         * for the next match, plus MIN_MATCH bytes to insert the
+         * string following the next match.
+         */
+        if (s->lookahead < MIN_LOOKAHEAD) {
+            fill_window(s);
+            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+                return need_more;
+            }
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+
+        /* Insert the string window[strstart .. strstart+2] in the
+         * dictionary, and set hash_head to the head of the hash chain:
+         */
+        hash_head = NIL;
+        if (s->lookahead >= MIN_MATCH) {
+            INSERT_STRING(s, s->strstart, hash_head);
+        }
+
+        /* Find the longest match, discarding those <= prev_length.
+         */
+        s->prev_length = s->match_length, s->prev_match = s->match_start;
+        s->match_length = MIN_MATCH-1;
+
+        if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
+            s->strstart - hash_head <= MAX_DIST(s)) {
+            /* To simplify the code, we prevent matches with the string
+             * of window index 0 (in particular we have to avoid a match
+             * of the string with itself at the start of the input file).
+             */
+            s->match_length = longest_match (s, hash_head);
+            /* longest_match() sets match_start */
+
+            if (s->match_length <= 5 && (s->strategy == Z_FILTERED
+#if TOO_FAR <= 32767
+                || (s->match_length == MIN_MATCH &&
+                    s->strstart - s->match_start > TOO_FAR)
+#endif
+                )) {
+
+                /* If prev_match is also MIN_MATCH, match_start is garbage
+                 * but we will ignore the current match anyway.
+                 */
+                s->match_length = MIN_MATCH-1;
+            }
+        }
+        /* If there was a match at the previous step and the current
+         * match is not better, output the previous match:
+         */
+        if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
+            uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
+            /* Do not insert strings in hash table beyond this. */
+
+            check_match(s, s->strstart-1, s->prev_match, s->prev_length);
+
+            _tr_tally_dist(s, s->strstart -1 - s->prev_match,
+                           s->prev_length - MIN_MATCH, bflush);
+
+            /* Insert in hash table all strings up to the end of the match.
+             * strstart-1 and strstart are already inserted. If there is not
+             * enough lookahead, the last two strings are not inserted in
+             * the hash table.
+             */
+            s->lookahead -= s->prev_length-1;
+            s->prev_length -= 2;
+            do {
+                if (++s->strstart <= max_insert) {
+                    INSERT_STRING(s, s->strstart, hash_head);
+                }
+            } while (--s->prev_length != 0);
+            s->match_available = 0;
+            s->match_length = MIN_MATCH-1;
+            s->strstart++;
+
+            if (bflush) FLUSH_BLOCK(s, 0);
+
+        } else if (s->match_available) {
+            /* If there was no match at the previous position, output a
+             * single literal. If there was a match but the current match
+             * is longer, truncate the previous match to a single literal.
+             */
+            Tracevv((stderr,"%c", s->window[s->strstart-1]));
+            _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+            if (bflush) {
+                FLUSH_BLOCK_ONLY(s, 0);
+            }
+            s->strstart++;
+            s->lookahead--;
+            if (s->strm->avail_out == 0) return need_more;
+        } else {
+            /* There is no previous match to compare with, wait for
+             * the next step to decide.
+             */
+            s->match_available = 1;
+            s->strstart++;
+            s->lookahead--;
+        }
+    }
+    Assert (flush != Z_NO_FLUSH, "no flush?");
+    if (s->match_available) {
+        Tracevv((stderr,"%c", s->window[s->strstart-1]));
+        _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+        s->match_available = 0;
+    }
+    s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;
+    if (flush == Z_FINISH) {
+        FLUSH_BLOCK(s, 1);
+        return finish_done;
+    }
+    if (s->last_lit)
+        FLUSH_BLOCK(s, 0);
+    return block_done;
+}
+#endif /* FASTEST */
+
+/* ===========================================================================
+ * For Z_RLE, simply look for runs of bytes, generate matches only of distance
+ * one.  Do not maintain a hash table.  (It will be regenerated if this run of
+ * deflate switches away from Z_RLE.)
+ */
+local block_state deflate_rle(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    int bflush;             /* set if current block must be flushed */
+    uInt prev;              /* byte at distance one to match */
+    Bytef *scan, *strend;   /* scan goes up to strend for length of run */
+
+    for (;;) {
+        /* Make sure that we always have enough lookahead, except
+         * at the end of the input file. We need MAX_MATCH bytes
+         * for the longest run, plus one for the unrolled loop.
+         */
+        if (s->lookahead <= MAX_MATCH) {
+            fill_window(s);
+            if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) {
+                return need_more;
+            }
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+
+        /* See how many times the previous byte repeats */
+        s->match_length = 0;
+        if (s->lookahead >= MIN_MATCH && s->strstart > 0) {
+            scan = s->window + s->strstart - 1;
+            prev = *scan;
+            if (prev == *++scan && prev == *++scan && prev == *++scan) {
+                strend = s->window + s->strstart + MAX_MATCH;
+                do {
+                } while (prev == *++scan && prev == *++scan &&
+                         prev == *++scan && prev == *++scan &&
+                         prev == *++scan && prev == *++scan &&
+                         prev == *++scan && prev == *++scan &&
+                         scan < strend);
+                s->match_length = MAX_MATCH - (int)(strend - scan);
+                if (s->match_length > s->lookahead)
+                    s->match_length = s->lookahead;
+            }
+            Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan");
+        }
+
+        /* Emit match if have run of MIN_MATCH or longer, else emit literal */
+        if (s->match_length >= MIN_MATCH) {
+            check_match(s, s->strstart, s->strstart - 1, s->match_length);
+
+            _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush);
+
+            s->lookahead -= s->match_length;
+            s->strstart += s->match_length;
+            s->match_length = 0;
+        } else {
+            /* No match, output a literal byte */
+            Tracevv((stderr,"%c", s->window[s->strstart]));
+            _tr_tally_lit (s, s->window[s->strstart], bflush);
+            s->lookahead--;
+            s->strstart++;
+        }
+        if (bflush) FLUSH_BLOCK(s, 0);
+    }
+    s->insert = 0;
+    if (flush == Z_FINISH) {
+        FLUSH_BLOCK(s, 1);
+        return finish_done;
+    }
+    if (s->last_lit)
+        FLUSH_BLOCK(s, 0);
+    return block_done;
+}
+
+/* ===========================================================================
+ * For Z_HUFFMAN_ONLY, do not look for matches.  Do not maintain a hash table.
+ * (It will be regenerated if this run of deflate switches away from Huffman.)
+ */
+local block_state deflate_huff(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    int bflush;             /* set if current block must be flushed */
+
+    for (;;) {
+        /* Make sure that we have a literal to write. */
+        if (s->lookahead == 0) {
+            fill_window(s);
+            if (s->lookahead == 0) {
+                if (flush == Z_NO_FLUSH)
+                    return need_more;
+                break;      /* flush the current block */
+            }
+        }
+
+        /* Output a literal byte */
+        s->match_length = 0;
+        Tracevv((stderr,"%c", s->window[s->strstart]));
+        _tr_tally_lit (s, s->window[s->strstart], bflush);
+        s->lookahead--;
+        s->strstart++;
+        if (bflush) FLUSH_BLOCK(s, 0);
+    }
+    s->insert = 0;
+    if (flush == Z_FINISH) {
+        FLUSH_BLOCK(s, 1);
+        return finish_done;
+    }
+    if (s->last_lit)
+        FLUSH_BLOCK(s, 0);
+    return block_done;
+}
diff --git a/Source/ZLib/deflate.h b/Source/ZLib/deflate.h
index 297b4f0..5655ff9 100644
--- a/Source/ZLib/deflate.h
+++ b/Source/ZLib/deflate.h
@@ -1,346 +1,346 @@
-/* deflate.h -- internal compression state
- * Copyright (C) 1995-2012 Jean-loup Gailly
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
-   part of the implementation of the compression library and is
-   subject to change. Applications should only use zlib.h.
- */
-
-/* @(#) $Id: deflate.h,v 1.9 2012/05/13 12:18:39 drolon Exp $ */
-
-#ifndef DEFLATE_H
-#define DEFLATE_H
-
-#include "zutil.h"
-
-/* define NO_GZIP when compiling if you want to disable gzip header and
-   trailer creation by deflate().  NO_GZIP would be used to avoid linking in
-   the crc code when it is not needed.  For shared libraries, gzip encoding
-   should be left enabled. */
-#ifndef NO_GZIP
-#  define GZIP
-#endif
-
-/* ===========================================================================
- * Internal compression state.
- */
-
-#define LENGTH_CODES 29
-/* number of length codes, not counting the special END_BLOCK code */
-
-#define LITERALS  256
-/* number of literal bytes 0..255 */
-
-#define L_CODES (LITERALS+1+LENGTH_CODES)
-/* number of Literal or Length codes, including the END_BLOCK code */
-
-#define D_CODES   30
-/* number of distance codes */
-
-#define BL_CODES  19
-/* number of codes used to transfer the bit lengths */
-
-#define HEAP_SIZE (2*L_CODES+1)
-/* maximum heap size */
-
-#define MAX_BITS 15
-/* All codes must not exceed MAX_BITS bits */
-
-#define Buf_size 16
-/* size of bit buffer in bi_buf */
-
-#define INIT_STATE    42
-#define EXTRA_STATE   69
-#define NAME_STATE    73
-#define COMMENT_STATE 91
-#define HCRC_STATE   103
-#define BUSY_STATE   113
-#define FINISH_STATE 666
-/* Stream status */
-
-
-/* Data structure describing a single value and its code string. */
-typedef struct ct_data_s {
-    union {
-        ush  freq;       /* frequency count */
-        ush  code;       /* bit string */
-    } fc;
-    union {
-        ush  dad;        /* father node in Huffman tree */
-        ush  len;        /* length of bit string */
-    } dl;
-} FAR ct_data;
-
-#define Freq fc.freq
-#define Code fc.code
-#define Dad  dl.dad
-#define Len  dl.len
-
-typedef struct static_tree_desc_s  static_tree_desc;
-
-typedef struct tree_desc_s {
-    ct_data *dyn_tree;           /* the dynamic tree */
-    int     max_code;            /* largest code with non zero frequency */
-    static_tree_desc *stat_desc; /* the corresponding static tree */
-} FAR tree_desc;
-
-typedef ush Pos;
-typedef Pos FAR Posf;
-typedef unsigned IPos;
-
-/* A Pos is an index in the character window. We use short instead of int to
- * save space in the various tables. IPos is used only for parameter passing.
- */
-
-typedef struct internal_state {
-    z_streamp strm;      /* pointer back to this zlib stream */
-    int   status;        /* as the name implies */
-    Bytef *pending_buf;  /* output still pending */
-    ulg   pending_buf_size; /* size of pending_buf */
-    Bytef *pending_out;  /* next pending byte to output to the stream */
-    uInt   pending;      /* nb of bytes in the pending buffer */
-    int   wrap;          /* bit 0 true for zlib, bit 1 true for gzip */
-    gz_headerp  gzhead;  /* gzip header information to write */
-    uInt   gzindex;      /* where in extra, name, or comment */
-    Byte  method;        /* STORED (for zip only) or DEFLATED */
-    int   last_flush;    /* value of flush param for previous deflate call */
-
-                /* used by deflate.c: */
-
-    uInt  w_size;        /* LZ77 window size (32K by default) */
-    uInt  w_bits;        /* log2(w_size)  (8..16) */
-    uInt  w_mask;        /* w_size - 1 */
-
-    Bytef *window;
-    /* Sliding window. Input bytes are read into the second half of the window,
-     * and move to the first half later to keep a dictionary of at least wSize
-     * bytes. With this organization, matches are limited to a distance of
-     * wSize-MAX_MATCH bytes, but this ensures that IO is always
-     * performed with a length multiple of the block size. Also, it limits
-     * the window size to 64K, which is quite useful on MSDOS.
-     * To do: use the user input buffer as sliding window.
-     */
-
-    ulg window_size;
-    /* Actual size of window: 2*wSize, except when the user input buffer
-     * is directly used as sliding window.
-     */
-
-    Posf *prev;
-    /* Link to older string with same hash index. To limit the size of this
-     * array to 64K, this link is maintained only for the last 32K strings.
-     * An index in this array is thus a window index modulo 32K.
-     */
-
-    Posf *head; /* Heads of the hash chains or NIL. */
-
-    uInt  ins_h;          /* hash index of string to be inserted */
-    uInt  hash_size;      /* number of elements in hash table */
-    uInt  hash_bits;      /* log2(hash_size) */
-    uInt  hash_mask;      /* hash_size-1 */
-
-    uInt  hash_shift;
-    /* Number of bits by which ins_h must be shifted at each input
-     * step. It must be such that after MIN_MATCH steps, the oldest
-     * byte no longer takes part in the hash key, that is:
-     *   hash_shift * MIN_MATCH >= hash_bits
-     */
-
-    long block_start;
-    /* Window position at the beginning of the current output block. Gets
-     * negative when the window is moved backwards.
-     */
-
-    uInt match_length;           /* length of best match */
-    IPos prev_match;             /* previous match */
-    int match_available;         /* set if previous match exists */
-    uInt strstart;               /* start of string to insert */
-    uInt match_start;            /* start of matching string */
-    uInt lookahead;              /* number of valid bytes ahead in window */
-
-    uInt prev_length;
-    /* Length of the best match at previous step. Matches not greater than this
-     * are discarded. This is used in the lazy match evaluation.
-     */
-
-    uInt max_chain_length;
-    /* To speed up deflation, hash chains are never searched beyond this
-     * length.  A higher limit improves compression ratio but degrades the
-     * speed.
-     */
-
-    uInt max_lazy_match;
-    /* Attempt to find a better match only when the current match is strictly
-     * smaller than this value. This mechanism is used only for compression
-     * levels >= 4.
-     */
-#   define max_insert_length  max_lazy_match
-    /* Insert new strings in the hash table only if the match length is not
-     * greater than this length. This saves time but degrades compression.
-     * max_insert_length is used only for compression levels <= 3.
-     */
-
-    int level;    /* compression level (1..9) */
-    int strategy; /* favor or force Huffman coding*/
-
-    uInt good_match;
-    /* Use a faster search when the previous match is longer than this */
-
-    int nice_match; /* Stop searching when current match exceeds this */
-
-                /* used by trees.c: */
-    /* Didn't use ct_data typedef below to suppress compiler warning */
-    struct ct_data_s dyn_ltree[HEAP_SIZE];   /* literal and length tree */
-    struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
-    struct ct_data_s bl_tree[2*BL_CODES+1];  /* Huffman tree for bit lengths */
-
-    struct tree_desc_s l_desc;               /* desc. for literal tree */
-    struct tree_desc_s d_desc;               /* desc. for distance tree */
-    struct tree_desc_s bl_desc;              /* desc. for bit length tree */
-
-    ush bl_count[MAX_BITS+1];
-    /* number of codes at each bit length for an optimal tree */
-
-    int heap[2*L_CODES+1];      /* heap used to build the Huffman trees */
-    int heap_len;               /* number of elements in the heap */
-    int heap_max;               /* element of largest frequency */
-    /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
-     * The same heap array is used to build all trees.
-     */
-
-    uch depth[2*L_CODES+1];
-    /* Depth of each subtree used as tie breaker for trees of equal frequency
-     */
-
-    uchf *l_buf;          /* buffer for literals or lengths */
-
-    uInt  lit_bufsize;
-    /* Size of match buffer for literals/lengths.  There are 4 reasons for
-     * limiting lit_bufsize to 64K:
-     *   - frequencies can be kept in 16 bit counters
-     *   - if compression is not successful for the first block, all input
-     *     data is still in the window so we can still emit a stored block even
-     *     when input comes from standard input.  (This can also be done for
-     *     all blocks if lit_bufsize is not greater than 32K.)
-     *   - if compression is not successful for a file smaller than 64K, we can
-     *     even emit a stored file instead of a stored block (saving 5 bytes).
-     *     This is applicable only for zip (not gzip or zlib).
-     *   - creating new Huffman trees less frequently may not provide fast
-     *     adaptation to changes in the input data statistics. (Take for
-     *     example a binary file with poorly compressible code followed by
-     *     a highly compressible string table.) Smaller buffer sizes give
-     *     fast adaptation but have of course the overhead of transmitting
-     *     trees more frequently.
-     *   - I can't count above 4
-     */
-
-    uInt last_lit;      /* running index in l_buf */
-
-    ushf *d_buf;
-    /* Buffer for distances. To simplify the code, d_buf and l_buf have
-     * the same number of elements. To use different lengths, an extra flag
-     * array would be necessary.
-     */
-
-    ulg opt_len;        /* bit length of current block with optimal trees */
-    ulg static_len;     /* bit length of current block with static trees */
-    uInt matches;       /* number of string matches in current block */
-    uInt insert;        /* bytes at end of window left to insert */
-
-#ifdef DEBUG
-    ulg compressed_len; /* total bit length of compressed file mod 2^32 */
-    ulg bits_sent;      /* bit length of compressed data sent mod 2^32 */
-#endif
-
-    ush bi_buf;
-    /* Output buffer. bits are inserted starting at the bottom (least
-     * significant bits).
-     */
-    int bi_valid;
-    /* Number of valid bits in bi_buf.  All bits above the last valid bit
-     * are always zero.
-     */
-
-    ulg high_water;
-    /* High water mark offset in window for initialized bytes -- bytes above
-     * this are set to zero in order to avoid memory check warnings when
-     * longest match routines access bytes past the input.  This is then
-     * updated to the new high water mark.
-     */
-
-} FAR deflate_state;
-
-/* Output a byte on the stream.
- * IN assertion: there is enough room in pending_buf.
- */
-#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
-
-
-#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
-/* Minimum amount of lookahead, except at the end of the input file.
- * See deflate.c for comments about the MIN_MATCH+1.
- */
-
-#define MAX_DIST(s)  ((s)->w_size-MIN_LOOKAHEAD)
-/* In order to simplify the code, particularly on 16 bit machines, match
- * distances are limited to MAX_DIST instead of WSIZE.
- */
-
-#define WIN_INIT MAX_MATCH
-/* Number of bytes after end of data in window to initialize in order to avoid
-   memory checker errors from longest match routines */
-
-        /* in trees.c */
-void ZLIB_INTERNAL _tr_init OF((deflate_state *s));
-int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
-void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf,
-                        ulg stored_len, int last));
-void ZLIB_INTERNAL _tr_flush_bits OF((deflate_state *s));
-void ZLIB_INTERNAL _tr_align OF((deflate_state *s));
-void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf,
-                        ulg stored_len, int last));
-
-#define d_code(dist) \
-   ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
-/* Mapping from a distance to a distance code. dist is the distance - 1 and
- * must not have side effects. _dist_code[256] and _dist_code[257] are never
- * used.
- */
-
-#ifndef DEBUG
-/* Inline versions of _tr_tally for speed: */
-
-#if defined(GEN_TREES_H) || !defined(STDC)
-  extern uch ZLIB_INTERNAL _length_code[];
-  extern uch ZLIB_INTERNAL _dist_code[];
-#else
-  extern const uch ZLIB_INTERNAL _length_code[];
-  extern const uch ZLIB_INTERNAL _dist_code[];
-#endif
-
-# define _tr_tally_lit(s, c, flush) \
-  { uch cc = (c); \
-    s->d_buf[s->last_lit] = 0; \
-    s->l_buf[s->last_lit++] = cc; \
-    s->dyn_ltree[cc].Freq++; \
-    flush = (s->last_lit == s->lit_bufsize-1); \
-   }
-# define _tr_tally_dist(s, distance, length, flush) \
-  { uch len = (length); \
-    ush dist = (distance); \
-    s->d_buf[s->last_lit] = dist; \
-    s->l_buf[s->last_lit++] = len; \
-    dist--; \
-    s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
-    s->dyn_dtree[d_code(dist)].Freq++; \
-    flush = (s->last_lit == s->lit_bufsize-1); \
-  }
-#else
-# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
-# define _tr_tally_dist(s, distance, length, flush) \
-              flush = _tr_tally(s, distance, length)
-#endif
-
-#endif /* DEFLATE_H */
+/* deflate.h -- internal compression state
+ * Copyright (C) 1995-2012 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id: deflate.h,v 1.10 2013/05/10 17:22:52 drolon Exp $ */
+
+#ifndef DEFLATE_H
+#define DEFLATE_H
+
+#include "zutil.h"
+
+/* define NO_GZIP when compiling if you want to disable gzip header and
+   trailer creation by deflate().  NO_GZIP would be used to avoid linking in
+   the crc code when it is not needed.  For shared libraries, gzip encoding
+   should be left enabled. */
+#ifndef NO_GZIP
+#  define GZIP
+#endif
+
+/* ===========================================================================
+ * Internal compression state.
+ */
+
+#define LENGTH_CODES 29
+/* number of length codes, not counting the special END_BLOCK code */
+
+#define LITERALS  256
+/* number of literal bytes 0..255 */
+
+#define L_CODES (LITERALS+1+LENGTH_CODES)
+/* number of Literal or Length codes, including the END_BLOCK code */
+
+#define D_CODES   30
+/* number of distance codes */
+
+#define BL_CODES  19
+/* number of codes used to transfer the bit lengths */
+
+#define HEAP_SIZE (2*L_CODES+1)
+/* maximum heap size */
+
+#define MAX_BITS 15
+/* All codes must not exceed MAX_BITS bits */
+
+#define Buf_size 16
+/* size of bit buffer in bi_buf */
+
+#define INIT_STATE    42
+#define EXTRA_STATE   69
+#define NAME_STATE    73
+#define COMMENT_STATE 91
+#define HCRC_STATE   103
+#define BUSY_STATE   113
+#define FINISH_STATE 666
+/* Stream status */
+
+
+/* Data structure describing a single value and its code string. */
+typedef struct ct_data_s {
+    union {
+        ush  freq;       /* frequency count */
+        ush  code;       /* bit string */
+    } fc;
+    union {
+        ush  dad;        /* father node in Huffman tree */
+        ush  len;        /* length of bit string */
+    } dl;
+} FAR ct_data;
+
+#define Freq fc.freq
+#define Code fc.code
+#define Dad  dl.dad
+#define Len  dl.len
+
+typedef struct static_tree_desc_s  static_tree_desc;
+
+typedef struct tree_desc_s {
+    ct_data *dyn_tree;           /* the dynamic tree */
+    int     max_code;            /* largest code with non zero frequency */
+    static_tree_desc *stat_desc; /* the corresponding static tree */
+} FAR tree_desc;
+
+typedef ush Pos;
+typedef Pos FAR Posf;
+typedef unsigned IPos;
+
+/* A Pos is an index in the character window. We use short instead of int to
+ * save space in the various tables. IPos is used only for parameter passing.
+ */
+
+typedef struct internal_state {
+    z_streamp strm;      /* pointer back to this zlib stream */
+    int   status;        /* as the name implies */
+    Bytef *pending_buf;  /* output still pending */
+    ulg   pending_buf_size; /* size of pending_buf */
+    Bytef *pending_out;  /* next pending byte to output to the stream */
+    uInt   pending;      /* nb of bytes in the pending buffer */
+    int   wrap;          /* bit 0 true for zlib, bit 1 true for gzip */
+    gz_headerp  gzhead;  /* gzip header information to write */
+    uInt   gzindex;      /* where in extra, name, or comment */
+    Byte  method;        /* can only be DEFLATED */
+    int   last_flush;    /* value of flush param for previous deflate call */
+
+                /* used by deflate.c: */
+
+    uInt  w_size;        /* LZ77 window size (32K by default) */
+    uInt  w_bits;        /* log2(w_size)  (8..16) */
+    uInt  w_mask;        /* w_size - 1 */
+
+    Bytef *window;
+    /* Sliding window. Input bytes are read into the second half of the window,
+     * and move to the first half later to keep a dictionary of at least wSize
+     * bytes. With this organization, matches are limited to a distance of
+     * wSize-MAX_MATCH bytes, but this ensures that IO is always
+     * performed with a length multiple of the block size. Also, it limits
+     * the window size to 64K, which is quite useful on MSDOS.
+     * To do: use the user input buffer as sliding window.
+     */
+
+    ulg window_size;
+    /* Actual size of window: 2*wSize, except when the user input buffer
+     * is directly used as sliding window.
+     */
+
+    Posf *prev;
+    /* Link to older string with same hash index. To limit the size of this
+     * array to 64K, this link is maintained only for the last 32K strings.
+     * An index in this array is thus a window index modulo 32K.
+     */
+
+    Posf *head; /* Heads of the hash chains or NIL. */
+
+    uInt  ins_h;          /* hash index of string to be inserted */
+    uInt  hash_size;      /* number of elements in hash table */
+    uInt  hash_bits;      /* log2(hash_size) */
+    uInt  hash_mask;      /* hash_size-1 */
+
+    uInt  hash_shift;
+    /* Number of bits by which ins_h must be shifted at each input
+     * step. It must be such that after MIN_MATCH steps, the oldest
+     * byte no longer takes part in the hash key, that is:
+     *   hash_shift * MIN_MATCH >= hash_bits
+     */
+
+    long block_start;
+    /* Window position at the beginning of the current output block. Gets
+     * negative when the window is moved backwards.
+     */
+
+    uInt match_length;           /* length of best match */
+    IPos prev_match;             /* previous match */
+    int match_available;         /* set if previous match exists */
+    uInt strstart;               /* start of string to insert */
+    uInt match_start;            /* start of matching string */
+    uInt lookahead;              /* number of valid bytes ahead in window */
+
+    uInt prev_length;
+    /* Length of the best match at previous step. Matches not greater than this
+     * are discarded. This is used in the lazy match evaluation.
+     */
+
+    uInt max_chain_length;
+    /* To speed up deflation, hash chains are never searched beyond this
+     * length.  A higher limit improves compression ratio but degrades the
+     * speed.
+     */
+
+    uInt max_lazy_match;
+    /* Attempt to find a better match only when the current match is strictly
+     * smaller than this value. This mechanism is used only for compression
+     * levels >= 4.
+     */
+#   define max_insert_length  max_lazy_match
+    /* Insert new strings in the hash table only if the match length is not
+     * greater than this length. This saves time but degrades compression.
+     * max_insert_length is used only for compression levels <= 3.
+     */
+
+    int level;    /* compression level (1..9) */
+    int strategy; /* favor or force Huffman coding*/
+
+    uInt good_match;
+    /* Use a faster search when the previous match is longer than this */
+
+    int nice_match; /* Stop searching when current match exceeds this */
+
+                /* used by trees.c: */
+    /* Didn't use ct_data typedef below to suppress compiler warning */
+    struct ct_data_s dyn_ltree[HEAP_SIZE];   /* literal and length tree */
+    struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
+    struct ct_data_s bl_tree[2*BL_CODES+1];  /* Huffman tree for bit lengths */
+
+    struct tree_desc_s l_desc;               /* desc. for literal tree */
+    struct tree_desc_s d_desc;               /* desc. for distance tree */
+    struct tree_desc_s bl_desc;              /* desc. for bit length tree */
+
+    ush bl_count[MAX_BITS+1];
+    /* number of codes at each bit length for an optimal tree */
+
+    int heap[2*L_CODES+1];      /* heap used to build the Huffman trees */
+    int heap_len;               /* number of elements in the heap */
+    int heap_max;               /* element of largest frequency */
+    /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
+     * The same heap array is used to build all trees.
+     */
+
+    uch depth[2*L_CODES+1];
+    /* Depth of each subtree used as tie breaker for trees of equal frequency
+     */
+
+    uchf *l_buf;          /* buffer for literals or lengths */
+
+    uInt  lit_bufsize;
+    /* Size of match buffer for literals/lengths.  There are 4 reasons for
+     * limiting lit_bufsize to 64K:
+     *   - frequencies can be kept in 16 bit counters
+     *   - if compression is not successful for the first block, all input
+     *     data is still in the window so we can still emit a stored block even
+     *     when input comes from standard input.  (This can also be done for
+     *     all blocks if lit_bufsize is not greater than 32K.)
+     *   - if compression is not successful for a file smaller than 64K, we can
+     *     even emit a stored file instead of a stored block (saving 5 bytes).
+     *     This is applicable only for zip (not gzip or zlib).
+     *   - creating new Huffman trees less frequently may not provide fast
+     *     adaptation to changes in the input data statistics. (Take for
+     *     example a binary file with poorly compressible code followed by
+     *     a highly compressible string table.) Smaller buffer sizes give
+     *     fast adaptation but have of course the overhead of transmitting
+     *     trees more frequently.
+     *   - I can't count above 4
+     */
+
+    uInt last_lit;      /* running index in l_buf */
+
+    ushf *d_buf;
+    /* Buffer for distances. To simplify the code, d_buf and l_buf have
+     * the same number of elements. To use different lengths, an extra flag
+     * array would be necessary.
+     */
+
+    ulg opt_len;        /* bit length of current block with optimal trees */
+    ulg static_len;     /* bit length of current block with static trees */
+    uInt matches;       /* number of string matches in current block */
+    uInt insert;        /* bytes at end of window left to insert */
+
+#ifdef DEBUG
+    ulg compressed_len; /* total bit length of compressed file mod 2^32 */
+    ulg bits_sent;      /* bit length of compressed data sent mod 2^32 */
+#endif
+
+    ush bi_buf;
+    /* Output buffer. bits are inserted starting at the bottom (least
+     * significant bits).
+     */
+    int bi_valid;
+    /* Number of valid bits in bi_buf.  All bits above the last valid bit
+     * are always zero.
+     */
+
+    ulg high_water;
+    /* High water mark offset in window for initialized bytes -- bytes above
+     * this are set to zero in order to avoid memory check warnings when
+     * longest match routines access bytes past the input.  This is then
+     * updated to the new high water mark.
+     */
+
+} FAR deflate_state;
+
+/* Output a byte on the stream.
+ * IN assertion: there is enough room in pending_buf.
+ */
+#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
+
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+#define MAX_DIST(s)  ((s)->w_size-MIN_LOOKAHEAD)
+/* In order to simplify the code, particularly on 16 bit machines, match
+ * distances are limited to MAX_DIST instead of WSIZE.
+ */
+
+#define WIN_INIT MAX_MATCH
+/* Number of bytes after end of data in window to initialize in order to avoid
+   memory checker errors from longest match routines */
+
+        /* in trees.c */
+void ZLIB_INTERNAL _tr_init OF((deflate_state *s));
+int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
+void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf,
+                        ulg stored_len, int last));
+void ZLIB_INTERNAL _tr_flush_bits OF((deflate_state *s));
+void ZLIB_INTERNAL _tr_align OF((deflate_state *s));
+void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf,
+                        ulg stored_len, int last));
+
+#define d_code(dist) \
+   ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
+/* Mapping from a distance to a distance code. dist is the distance - 1 and
+ * must not have side effects. _dist_code[256] and _dist_code[257] are never
+ * used.
+ */
+
+#ifndef DEBUG
+/* Inline versions of _tr_tally for speed: */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+  extern uch ZLIB_INTERNAL _length_code[];
+  extern uch ZLIB_INTERNAL _dist_code[];
+#else
+  extern const uch ZLIB_INTERNAL _length_code[];
+  extern const uch ZLIB_INTERNAL _dist_code[];
+#endif
+
+# define _tr_tally_lit(s, c, flush) \
+  { uch cc = (c); \
+    s->d_buf[s->last_lit] = 0; \
+    s->l_buf[s->last_lit++] = cc; \
+    s->dyn_ltree[cc].Freq++; \
+    flush = (s->last_lit == s->lit_bufsize-1); \
+   }
+# define _tr_tally_dist(s, distance, length, flush) \
+  { uch len = (length); \
+    ush dist = (distance); \
+    s->d_buf[s->last_lit] = dist; \
+    s->l_buf[s->last_lit++] = len; \
+    dist--; \
+    s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
+    s->dyn_dtree[d_code(dist)].Freq++; \
+    flush = (s->last_lit == s->lit_bufsize-1); \
+  }
+#else
+# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
+# define _tr_tally_dist(s, distance, length, flush) \
+              flush = _tr_tally(s, distance, length)
+#endif
+
+#endif /* DEFLATE_H */
diff --git a/Source/ZLib/gzguts.h b/Source/ZLib/gzguts.h
index ee3f281..d87659d 100644
--- a/Source/ZLib/gzguts.h
+++ b/Source/ZLib/gzguts.h
@@ -1,5 +1,5 @@
 /* gzguts.h -- zlib internal header definitions for gz* operations
- * Copyright (C) 2004, 2005, 2010, 2011, 2012 Mark Adler
+ * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
@@ -35,6 +35,13 @@
 #  include <io.h>
 #endif
 
+#ifdef WINAPI_FAMILY
+#  define open _open
+#  define read _read
+#  define write _write
+#  define close _close
+#endif
+
 #ifdef NO_DEFLATE       /* for compatibility with old definition */
 #  define NO_GZCOMPRESS
 #endif
@@ -60,7 +67,7 @@
 #ifndef HAVE_VSNPRINTF
 #  ifdef MSDOS
 /* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
- but for now we just assume it doesn't. */
+   but for now we just assume it doesn't. */
 #    define NO_vsnprintf
 #  endif
 #  ifdef __TURBOC__
@@ -88,6 +95,14 @@
 #  endif
 #endif
 
+/* unlike snprintf (which is required in C99, yet still not supported by
+   Microsoft more than a decade later!), _snprintf does not guarantee null
+   termination of the result -- however this is only used in gzlib.c where
+   the result is assured to fit in the space provided */
+#ifdef _MSC_VER
+#  define snprintf _snprintf
+#endif
+
 #ifndef local
 #  define local static
 #endif
@@ -127,7 +142,8 @@
 #  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
 #endif
 
-/* default i/o buffer size -- double this for output when reading */
+/* default i/o buffer size -- double this for output when reading (this and
+   twice this must be able to fit in an unsigned type) */
 #define GZBUFSIZE 8192
 
 /* gzip modes, also provide a little integrity check on the passed structure */
diff --git a/Source/ZLib/gzlib.c b/Source/ZLib/gzlib.c
index ca55c6e..fae202e 100644
--- a/Source/ZLib/gzlib.c
+++ b/Source/ZLib/gzlib.c
@@ -1,5 +1,5 @@
 /* gzlib.c -- zlib functions common to reading and writing gzip files
- * Copyright (C) 2004, 2010, 2011, 2012 Mark Adler
+ * Copyright (C) 2004, 2010, 2011, 2012, 2013 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
@@ -108,7 +108,7 @@ local gzFile gz_open(path, fd, mode)
         return NULL;
 
     /* allocate gzFile structure to return */
-    state = malloc(sizeof(gz_state));
+    state = (gz_statep)malloc(sizeof(gz_state));
     if (state == NULL)
         return NULL;
     state->size = 0;            /* no buffers allocated yet */
@@ -162,8 +162,10 @@ local gzFile gz_open(path, fd, mode)
                 break;
             case 'F':
                 state->strategy = Z_FIXED;
+                break;
             case 'T':
                 state->direct = 1;
+                break;
             default:        /* could consider as an error, but just ignore */
                 ;
             }
@@ -194,8 +196,8 @@ local gzFile gz_open(path, fd, mode)
     }
     else
 #endif
-        len = strlen(path);
-    state->path = malloc(len + 1);
+        len = strlen((const char *)path);
+    state->path = (char *)malloc(len + 1);
     if (state->path == NULL) {
         free(state);
         return NULL;
@@ -208,7 +210,11 @@ local gzFile gz_open(path, fd, mode)
             *(state->path) = 0;
     else
 #endif
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+        snprintf(state->path, len + 1, "%s", (const char *)path);
+#else
         strcpy(state->path, path);
+#endif
 
     /* compute the flags for open() */
     oflag =
@@ -236,7 +242,7 @@ local gzFile gz_open(path, fd, mode)
 #ifdef _WIN32
         fd == -2 ? _wopen(path, oflag, 0666) :
 #endif
-        open(path, oflag, 0666));
+        open((const char *)path, oflag, 0666));
     if (state->fd == -1) {
         free(state->path);
         free(state);
@@ -282,9 +288,13 @@ gzFile ZEXPORT gzdopen(fd, mode)
     char *path;         /* identifier for error messages */
     gzFile gz;
 
-    if (fd == -1 || (path = malloc(7 + 3 * sizeof(int))) == NULL)
+    if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL)
         return NULL;
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+    snprintf(path, 7 + 3 * sizeof(int), "<fd:%d>", fd); /* for debugging */
+#else
     sprintf(path, "<fd:%d>", fd);   /* for debugging */
+#endif
     gz = gz_open(path, fd, mode);
     free(path);
     return gz;
@@ -531,7 +541,8 @@ const char * ZEXPORT gzerror(file, errnum)
     /* return error information */
     if (errnum != NULL)
         *errnum = state->err;
-    return state->msg == NULL ? "" : state->msg;
+    return state->err == Z_MEM_ERROR ? "out of memory" :
+                                       (state->msg == NULL ? "" : state->msg);
 }
 
 /* -- see zlib.h -- */
@@ -582,21 +593,24 @@ void ZLIB_INTERNAL gz_error(state, err, msg)
     if (msg == NULL)
         return;
 
-    /* for an out of memory error, save as static string */
-    if (err == Z_MEM_ERROR) {
-        state->msg = (char *)msg;
+    /* for an out of memory error, return literal string when requested */
+    if (err == Z_MEM_ERROR)
         return;
-    }
 
     /* construct error message with path */
-    if ((state->msg = malloc(strlen(state->path) + strlen(msg) + 3)) == NULL) {
+    if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) ==
+            NULL) {
         state->err = Z_MEM_ERROR;
-        state->msg = (char *)"out of memory";
         return;
     }
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+    snprintf(state->msg, strlen(state->path) + strlen(msg) + 3,
+             "%s%s%s", state->path, ": ", msg);
+#else
     strcpy(state->msg, state->path);
     strcat(state->msg, ": ");
     strcat(state->msg, msg);
+#endif
     return;
 }
 
diff --git a/Source/ZLib/gzread.c b/Source/ZLib/gzread.c
index 3493d34..bf4538e 100644
--- a/Source/ZLib/gzread.c
+++ b/Source/ZLib/gzread.c
@@ -1,5 +1,5 @@
 /* gzread.c -- zlib functions for reading gzip files
- * Copyright (C) 2004, 2005, 2010, 2011, 2012 Mark Adler
+ * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
@@ -58,7 +58,8 @@ local int gz_avail(state)
         return -1;
     if (state->eof == 0) {
         if (strm->avail_in) {       /* copy what's there to the start */
-            unsigned char *p = state->in, *q = strm->next_in;
+            unsigned char *p = state->in;
+            unsigned const char *q = strm->next_in;
             unsigned n = strm->avail_in;
             do {
                 *p++ = *q++;
@@ -90,8 +91,8 @@ local int gz_look(state)
     /* allocate read buffers and inflate memory */
     if (state->size == 0) {
         /* allocate buffers */
-        state->in = malloc(state->want);
-        state->out = malloc(state->want << 1);
+        state->in = (unsigned char *)malloc(state->want);
+        state->out = (unsigned char *)malloc(state->want << 1);
         if (state->in == NULL || state->out == NULL) {
             if (state->out != NULL)
                 free(state->out);
@@ -352,14 +353,14 @@ int ZEXPORT gzread(file, buf, len)
 
         /* large len -- read directly into user buffer */
         else if (state->how == COPY) {      /* read directly */
-            if (gz_load(state, buf, len, &n) == -1)
+            if (gz_load(state, (unsigned char *)buf, len, &n) == -1)
                 return -1;
         }
 
         /* large len -- decompress directly into user buffer */
         else {  /* state->how == GZIP */
             strm->avail_out = len;
-            strm->next_out = buf;
+            strm->next_out = (unsigned char *)buf;
             if (gz_decomp(state) == -1)
                 return -1;
             n = state->x.have;
@@ -378,7 +379,11 @@ int ZEXPORT gzread(file, buf, len)
 }
 
 /* -- see zlib.h -- */
-#undef gzgetc
+#ifdef Z_PREFIX_SET
+#  undef z_gzgetc
+#else
+#  undef gzgetc
+#endif
 int ZEXPORT gzgetc(file)
     gzFile file;
 {
@@ -518,7 +523,7 @@ char * ZEXPORT gzgets(file, buf, len)
 
         /* look for end-of-line in current output buffer */
         n = state->x.have > left ? left : state->x.have;
-        eol = memchr(state->x.next, '\n', n);
+        eol = (unsigned char *)memchr(state->x.next, '\n', n);
         if (eol != NULL)
             n = (unsigned)(eol - state->x.next) + 1;
 
diff --git a/Source/ZLib/gzwrite.c b/Source/ZLib/gzwrite.c
index 27cb342..aa767fb 100644
--- a/Source/ZLib/gzwrite.c
+++ b/Source/ZLib/gzwrite.c
@@ -1,5 +1,5 @@
 /* gzwrite.c -- zlib functions for writing gzip files
- * Copyright (C) 2004, 2005, 2010, 2011, 2012 Mark Adler
+ * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
@@ -19,7 +19,7 @@ local int gz_init(state)
     z_streamp strm = &(state->strm);
 
     /* allocate input buffer */
-    state->in = malloc(state->want);
+    state->in = (unsigned char *)malloc(state->want);
     if (state->in == NULL) {
         gz_error(state, Z_MEM_ERROR, "out of memory");
         return -1;
@@ -28,7 +28,7 @@ local int gz_init(state)
     /* only need output buffer and deflate state if compressing */
     if (!state->direct) {
         /* allocate output buffer */
-        state->out = malloc(state->want);
+        state->out = (unsigned char *)malloc(state->want);
         if (state->out == NULL) {
             free(state->in);
             gz_error(state, Z_MEM_ERROR, "out of memory");
@@ -168,7 +168,6 @@ int ZEXPORT gzwrite(file, buf, len)
     unsigned len;
 {
     unsigned put = len;
-    unsigned n;
     gz_statep state;
     z_streamp strm;
 
@@ -208,16 +207,19 @@ int ZEXPORT gzwrite(file, buf, len)
     if (len < state->size) {
         /* copy to input buffer, compress when full */
         do {
+            unsigned have, copy;
+
             if (strm->avail_in == 0)
                 strm->next_in = state->in;
-            n = state->size - strm->avail_in;
-            if (n > len)
-                n = len;
-            memcpy(strm->next_in + strm->avail_in, buf, n);
-            strm->avail_in += n;
-            state->x.pos += n;
-            buf = (char *)buf + n;
-            len -= n;
+            have = (unsigned)((strm->next_in + strm->avail_in) - state->in);
+            copy = state->size - have;
+            if (copy > len)
+                copy = len;
+            memcpy(state->in + have, buf, copy);
+            strm->avail_in += copy;
+            state->x.pos += copy;
+            buf = (const char *)buf + copy;
+            len -= copy;
             if (len && gz_comp(state, Z_NO_FLUSH) == -1)
                 return 0;
         } while (len);
@@ -229,7 +231,7 @@ int ZEXPORT gzwrite(file, buf, len)
 
         /* directly compress user buffer to file */
         strm->avail_in = len;
-        strm->next_in = (voidp)buf;
+        strm->next_in = (z_const Bytef *)buf;
         state->x.pos += len;
         if (gz_comp(state, Z_NO_FLUSH) == -1)
             return 0;
@@ -244,6 +246,7 @@ int ZEXPORT gzputc(file, c)
     gzFile file;
     int c;
 {
+    unsigned have;
     unsigned char buf[1];
     gz_statep state;
     z_streamp strm;
@@ -267,12 +270,16 @@ int ZEXPORT gzputc(file, c)
 
     /* try writing to input buffer for speed (state->size == 0 if buffer not
        initialized) */
-    if (strm->avail_in < state->size) {
+    if (state->size) {
         if (strm->avail_in == 0)
             strm->next_in = state->in;
-        strm->next_in[strm->avail_in++] = c;
-        state->x.pos++;
-        return c & 0xff;
+        have = (unsigned)((strm->next_in + strm->avail_in) - state->in);
+        if (have < state->size) {
+            state->in[have] = c;
+            strm->avail_in++;
+            state->x.pos++;
+            return c & 0xff;
+        }
     }
 
     /* no room in buffer or not initialized, use gz_write() */
@@ -300,12 +307,11 @@ int ZEXPORT gzputs(file, str)
 #include <stdarg.h>
 
 /* -- see zlib.h -- */
-int ZEXPORTVA gzprintf (gzFile file, const char *format, ...)
+int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va)
 {
     int size, len;
     gz_statep state;
     z_streamp strm;
-    va_list va;
 
     /* get internal structure */
     if (file == NULL)
@@ -335,25 +341,20 @@ int ZEXPORTVA gzprintf (gzFile file, const char *format, ...)
     /* do the printf() into the input buffer, put length in len */
     size = (int)(state->size);
     state->in[size - 1] = 0;
-    va_start(va, format);
 #ifdef NO_vsnprintf
 #  ifdef HAS_vsprintf_void
     (void)vsprintf((char *)(state->in), format, va);
-    va_end(va);
     for (len = 0; len < size; len++)
         if (state->in[len] == 0) break;
 #  else
     len = vsprintf((char *)(state->in), format, va);
-    va_end(va);
 #  endif
 #else
 #  ifdef HAS_vsnprintf_void
     (void)vsnprintf((char *)(state->in), size, format, va);
-    va_end(va);
     len = strlen((char *)(state->in));
 #  else
     len = vsnprintf((char *)(state->in), size, format, va);
-    va_end(va);
 #  endif
 #endif
 
@@ -368,6 +369,17 @@ int ZEXPORTVA gzprintf (gzFile file, const char *format, ...)
     return len;
 }
 
+int ZEXPORTVA gzprintf(gzFile file, const char *format, ...)
+{
+    va_list va;
+    int ret;
+
+    va_start(va, format);
+    ret = gzvprintf(file, format, va);
+    va_end(va);
+    return ret;
+}
+
 #else /* !STDC && !Z_HAVE_STDARG_H */
 
 /* -- see zlib.h -- */
@@ -547,9 +559,9 @@ int ZEXPORT gzclose_w(file)
     }
 
     /* flush, free memory, and close file */
+    if (gz_comp(state, Z_FINISH) == -1)
+        ret = state->err;
     if (state->size) {
-        if (gz_comp(state, Z_FINISH) == -1)
-            ret = state->err;
         if (!state->direct) {
             (void)deflateEnd(&(state->strm));
             free(state->out);
diff --git a/Source/ZLib/infback.c b/Source/ZLib/infback.c
index 981aff1..f3833c2 100644
--- a/Source/ZLib/infback.c
+++ b/Source/ZLib/infback.c
@@ -255,7 +255,7 @@ out_func out;
 void FAR *out_desc;
 {
     struct inflate_state FAR *state;
-    unsigned char FAR *next;    /* next input */
+    z_const unsigned char FAR *next;    /* next input */
     unsigned char FAR *put;     /* next output */
     unsigned have, left;        /* available input and output */
     unsigned long hold;         /* bit buffer */
diff --git a/Source/ZLib/inffast.c b/Source/ZLib/inffast.c
index 2f1d60b..bda59ce 100644
--- a/Source/ZLib/inffast.c
+++ b/Source/ZLib/inffast.c
@@ -1,5 +1,5 @@
 /* inffast.c -- fast decoding
- * Copyright (C) 1995-2008, 2010 Mark Adler
+ * Copyright (C) 1995-2008, 2010, 2013 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
@@ -69,8 +69,8 @@ z_streamp strm;
 unsigned start;         /* inflate()'s starting value for strm->avail_out */
 {
     struct inflate_state FAR *state;
-    unsigned char FAR *in;      /* local strm->next_in */
-    unsigned char FAR *last;    /* while in < last, enough input available */
+    z_const unsigned char FAR *in;      /* local strm->next_in */
+    z_const unsigned char FAR *last;    /* have enough input while in < last */
     unsigned char FAR *out;     /* local strm->next_out */
     unsigned char FAR *beg;     /* inflate()'s initial strm->next_out */
     unsigned char FAR *end;     /* while out < end, enough space available */
diff --git a/Source/ZLib/inflate.c b/Source/ZLib/inflate.c
index 47418a1..870f89b 100644
--- a/Source/ZLib/inflate.c
+++ b/Source/ZLib/inflate.c
@@ -93,11 +93,12 @@
 
 /* function prototypes */
 local void fixedtables OF((struct inflate_state FAR *state));
-local int updatewindow OF((z_streamp strm, unsigned out));
+local int updatewindow OF((z_streamp strm, const unsigned char FAR *end,
+                           unsigned copy));
 #ifdef BUILDFIXED
    void makefixed OF((void));
 #endif
-local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf,
+local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf,
                               unsigned len));
 
 int ZEXPORT inflateResetKeep(strm)
@@ -375,12 +376,13 @@ void makefixed()
    output will fall in the output data, making match copies simpler and faster.
    The advantage may be dependent on the size of the processor's data caches.
  */
-local int updatewindow(strm, out)
+local int updatewindow(strm, end, copy)
 z_streamp strm;
-unsigned out;
+const Bytef *end;
+unsigned copy;
 {
     struct inflate_state FAR *state;
-    unsigned copy, dist;
+    unsigned dist;
 
     state = (struct inflate_state FAR *)strm->state;
 
@@ -400,19 +402,18 @@ unsigned out;
     }
 
     /* copy state->wsize or less output bytes into the circular window */
-    copy = out - strm->avail_out;
     if (copy >= state->wsize) {
-        zmemcpy(state->window, strm->next_out - state->wsize, state->wsize);
+        zmemcpy(state->window, end - state->wsize, state->wsize);
         state->wnext = 0;
         state->whave = state->wsize;
     }
     else {
         dist = state->wsize - state->wnext;
         if (dist > copy) dist = copy;
-        zmemcpy(state->window + state->wnext, strm->next_out - copy, dist);
+        zmemcpy(state->window + state->wnext, end - copy, dist);
         copy -= dist;
         if (copy) {
-            zmemcpy(state->window, strm->next_out - copy, copy);
+            zmemcpy(state->window, end - copy, copy);
             state->wnext = copy;
             state->whave = state->wsize;
         }
@@ -606,7 +607,7 @@ z_streamp strm;
 int flush;
 {
     struct inflate_state FAR *state;
-    unsigned char FAR *next;    /* next input */
+    z_const unsigned char FAR *next;    /* next input */
     unsigned char FAR *put;     /* next output */
     unsigned have, left;        /* available input and output */
     unsigned long hold;         /* bit buffer */
@@ -920,7 +921,7 @@ int flush;
             while (state->have < 19)
                 state->lens[order[state->have++]] = 0;
             state->next = state->codes;
-            state->lencode = (code const FAR *)(state->next);
+            state->lencode = (const code FAR *)(state->next);
             state->lenbits = 7;
             ret = inflate_table(CODES, state->lens, 19, &(state->next),
                                 &(state->lenbits), state->work);
@@ -994,7 +995,7 @@ int flush;
                values here (9 and 6) without reading the comments in inftrees.h
                concerning the ENOUGH constants, which depend on those values */
             state->next = state->codes;
-            state->lencode = (code const FAR *)(state->next);
+            state->lencode = (const code FAR *)(state->next);
             state->lenbits = 9;
             ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
                                 &(state->lenbits), state->work);
@@ -1003,7 +1004,7 @@ int flush;
                 state->mode = BAD;
                 break;
             }
-            state->distcode = (code const FAR *)(state->next);
+            state->distcode = (const code FAR *)(state->next);
             state->distbits = 6;
             ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
                             &(state->next), &(state->distbits), state->work);
@@ -1230,7 +1231,7 @@ int flush;
     RESTORE();
     if (state->wsize || (out != strm->avail_out && state->mode < BAD &&
             (state->mode < CHECK || flush != Z_FINISH)))
-        if (updatewindow(strm, out)) {
+        if (updatewindow(strm, strm->next_out, out - strm->avail_out)) {
             state->mode = MEM;
             return Z_MEM_ERROR;
         }
@@ -1264,6 +1265,29 @@ z_streamp strm;
     return Z_OK;
 }
 
+int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength)
+z_streamp strm;
+Bytef *dictionary;
+uInt *dictLength;
+{
+    struct inflate_state FAR *state;
+
+    /* check state */
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+
+    /* copy dictionary */
+    if (state->whave && dictionary != Z_NULL) {
+        zmemcpy(dictionary, state->window + state->wnext,
+                state->whave - state->wnext);
+        zmemcpy(dictionary + state->whave - state->wnext,
+                state->window, state->wnext);
+    }
+    if (dictLength != Z_NULL)
+        *dictLength = state->whave;
+    return Z_OK;
+}
+
 int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
 z_streamp strm;
 const Bytef *dictionary;
@@ -1271,8 +1295,6 @@ uInt dictLength;
 {
     struct inflate_state FAR *state;
     unsigned long dictid;
-    unsigned char *next;
-    unsigned avail;
     int ret;
 
     /* check state */
@@ -1291,13 +1313,7 @@ uInt dictLength;
 
     /* copy dictionary to window using updatewindow(), which will amend the
        existing dictionary if appropriate */
-    next = strm->next_out;
-    avail = strm->avail_out;
-    strm->next_out = (Bytef *)dictionary + dictLength;
-    strm->avail_out = 0;
-    ret = updatewindow(strm, dictLength);
-    strm->avail_out = avail;
-    strm->next_out = next;
+    ret = updatewindow(strm, dictionary + dictLength, dictLength);
     if (ret) {
         state->mode = MEM;
         return Z_MEM_ERROR;
@@ -1337,7 +1353,7 @@ gz_headerp head;
  */
 local unsigned syncsearch(have, buf, len)
 unsigned FAR *have;
-unsigned char FAR *buf;
+const unsigned char FAR *buf;
 unsigned len;
 {
     unsigned got;
diff --git a/Source/ZLib/inftrees.c b/Source/ZLib/inftrees.c
index abcd7c4..44d89cf 100644
--- a/Source/ZLib/inftrees.c
+++ b/Source/ZLib/inftrees.c
@@ -1,5 +1,5 @@
 /* inftrees.c -- generate Huffman trees for efficient decoding
- * Copyright (C) 1995-2012 Mark Adler
+ * Copyright (C) 1995-2013 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
@@ -9,7 +9,7 @@
 #define MAXBITS 15
 
 const char inflate_copyright[] =
-   " inflate 1.2.7 Copyright 1995-2012 Mark Adler ";
+   " inflate 1.2.8 Copyright 1995-2013 Mark Adler ";
 /*
   If you use the zlib library in a product, an acknowledgment is welcome
   in the documentation of your product. If for some reason you cannot
@@ -62,7 +62,7 @@ unsigned short FAR *work;
         35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
     static const unsigned short lext[31] = { /* Length codes 257..285 extra */
         16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
-        19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 78, 68};
+        19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78};
     static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
         1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
         257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
@@ -208,8 +208,8 @@ unsigned short FAR *work;
     mask = used - 1;            /* mask for comparing low */
 
     /* check available table space */
-    if ((type == LENS && used >= ENOUGH_LENS) ||
-        (type == DISTS && used >= ENOUGH_DISTS))
+    if ((type == LENS && used > ENOUGH_LENS) ||
+        (type == DISTS && used > ENOUGH_DISTS))
         return 1;
 
     /* process all codes and make table entries */
@@ -277,8 +277,8 @@ unsigned short FAR *work;
 
             /* check for enough space */
             used += 1U << curr;
-            if ((type == LENS && used >= ENOUGH_LENS) ||
-                (type == DISTS && used >= ENOUGH_DISTS))
+            if ((type == LENS && used > ENOUGH_LENS) ||
+                (type == DISTS && used > ENOUGH_DISTS))
                 return 1;
 
             /* point entry in root table to sub-table */
diff --git a/Source/ZLib/trees.c b/Source/ZLib/trees.c
index ac98942..c3cfdc8 100644
--- a/Source/ZLib/trees.c
+++ b/Source/ZLib/trees.c
@@ -1,1224 +1,1226 @@
-/* trees.c -- output deflated data using Huffman coding
- * Copyright (C) 1995-2012 Jean-loup Gailly
- * detect_data_type() function provided freely by Cosmin Truta, 2006
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/*
- *  ALGORITHM
- *
- *      The "deflation" process uses several Huffman trees. The more
- *      common source values are represented by shorter bit sequences.
- *
- *      Each code tree is stored in a compressed form which is itself
- * a Huffman encoding of the lengths of all the code strings (in
- * ascending order by source values).  The actual code strings are
- * reconstructed from the lengths in the inflate process, as described
- * in the deflate specification.
- *
- *  REFERENCES
- *
- *      Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
- *      Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
- *
- *      Storer, James A.
- *          Data Compression:  Methods and Theory, pp. 49-50.
- *          Computer Science Press, 1988.  ISBN 0-7167-8156-5.
- *
- *      Sedgewick, R.
- *          Algorithms, p290.
- *          Addison-Wesley, 1983. ISBN 0-201-06672-6.
- */
-
-/* @(#) $Id: trees.c,v 1.9 2012/05/13 12:18:39 drolon Exp $ */
-
-/* #define GEN_TREES_H */
-
-#include "deflate.h"
-
-#ifdef DEBUG
-#  include <ctype.h>
-#endif
-
-/* ===========================================================================
- * Constants
- */
-
-#define MAX_BL_BITS 7
-/* Bit length codes must not exceed MAX_BL_BITS bits */
-
-#define END_BLOCK 256
-/* end of block literal code */
-
-#define REP_3_6      16
-/* repeat previous bit length 3-6 times (2 bits of repeat count) */
-
-#define REPZ_3_10    17
-/* repeat a zero length 3-10 times  (3 bits of repeat count) */
-
-#define REPZ_11_138  18
-/* repeat a zero length 11-138 times  (7 bits of repeat count) */
-
-local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
-   = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
-
-local const int extra_dbits[D_CODES] /* extra bits for each distance code */
-   = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
-
-local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
-   = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
-
-local const uch bl_order[BL_CODES]
-   = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
-/* The lengths of the bit length codes are sent in order of decreasing
- * probability, to avoid transmitting the lengths for unused bit length codes.
- */
-
-/* ===========================================================================
- * Local data. These are initialized only once.
- */
-
-#define DIST_CODE_LEN  512 /* see definition of array dist_code below */
-
-#if defined(GEN_TREES_H) || !defined(STDC)
-/* non ANSI compilers may not accept trees.h */
-
-local ct_data static_ltree[L_CODES+2];
-/* The static literal tree. Since the bit lengths are imposed, there is no
- * need for the L_CODES extra codes used during heap construction. However
- * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
- * below).
- */
-
-local ct_data static_dtree[D_CODES];
-/* The static distance tree. (Actually a trivial tree since all codes use
- * 5 bits.)
- */
-
-uch _dist_code[DIST_CODE_LEN];
-/* Distance codes. The first 256 values correspond to the distances
- * 3 .. 258, the last 256 values correspond to the top 8 bits of
- * the 15 bit distances.
- */
-
-uch _length_code[MAX_MATCH-MIN_MATCH+1];
-/* length code for each normalized match length (0 == MIN_MATCH) */
-
-local int base_length[LENGTH_CODES];
-/* First normalized length for each code (0 = MIN_MATCH) */
-
-local int base_dist[D_CODES];
-/* First normalized distance for each code (0 = distance of 1) */
-
-#else
-#  include "trees.h"
-#endif /* GEN_TREES_H */
-
-struct static_tree_desc_s {
-    const ct_data *static_tree;  /* static tree or NULL */
-    const intf *extra_bits;      /* extra bits for each code or NULL */
-    int     extra_base;          /* base index for extra_bits */
-    int     elems;               /* max number of elements in the tree */
-    int     max_length;          /* max bit length for the codes */
-};
-
-local static_tree_desc  static_l_desc =
-{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
-
-local static_tree_desc  static_d_desc =
-{static_dtree, extra_dbits, 0,          D_CODES, MAX_BITS};
-
-local static_tree_desc  static_bl_desc =
-{(const ct_data *)0, extra_blbits, 0,   BL_CODES, MAX_BL_BITS};
-
-/* ===========================================================================
- * Local (static) routines in this file.
- */
-
-local void tr_static_init OF((void));
-local void init_block     OF((deflate_state *s));
-local void pqdownheap     OF((deflate_state *s, ct_data *tree, int k));
-local void gen_bitlen     OF((deflate_state *s, tree_desc *desc));
-local void gen_codes      OF((ct_data *tree, int max_code, ushf *bl_count));
-local void build_tree     OF((deflate_state *s, tree_desc *desc));
-local void scan_tree      OF((deflate_state *s, ct_data *tree, int max_code));
-local void send_tree      OF((deflate_state *s, ct_data *tree, int max_code));
-local int  build_bl_tree  OF((deflate_state *s));
-local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
-                              int blcodes));
-local void compress_block OF((deflate_state *s, ct_data *ltree,
-                              ct_data *dtree));
-local int  detect_data_type OF((deflate_state *s));
-local unsigned bi_reverse OF((unsigned value, int length));
-local void bi_windup      OF((deflate_state *s));
-local void bi_flush       OF((deflate_state *s));
-local void copy_block     OF((deflate_state *s, charf *buf, unsigned len,
-                              int header));
-
-#ifdef GEN_TREES_H
-local void gen_trees_header OF((void));
-#endif
-
-#ifndef DEBUG
-#  define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
-   /* Send a code of the given tree. c and tree must not have side effects */
-
-#else /* DEBUG */
-#  define send_code(s, c, tree) \
-     { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
-       send_bits(s, tree[c].Code, tree[c].Len); }
-#endif
-
-/* ===========================================================================
- * Output a short LSB first on the stream.
- * IN assertion: there is enough room in pendingBuf.
- */
-#define put_short(s, w) { \
-    put_byte(s, (uch)((w) & 0xff)); \
-    put_byte(s, (uch)((ush)(w) >> 8)); \
-}
-
-/* ===========================================================================
- * Send a value on a given number of bits.
- * IN assertion: length <= 16 and value fits in length bits.
- */
-#ifdef DEBUG
-local void send_bits      OF((deflate_state *s, int value, int length));
-
-local void send_bits(s, value, length)
-    deflate_state *s;
-    int value;  /* value to send */
-    int length; /* number of bits */
-{
-    Tracevv((stderr," l %2d v %4x ", length, value));
-    Assert(length > 0 && length <= 15, "invalid length");
-    s->bits_sent += (ulg)length;
-
-    /* If not enough room in bi_buf, use (valid) bits from bi_buf and
-     * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
-     * unused bits in value.
-     */
-    if (s->bi_valid > (int)Buf_size - length) {
-        s->bi_buf |= (ush)value << s->bi_valid;
-        put_short(s, s->bi_buf);
-        s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
-        s->bi_valid += length - Buf_size;
-    } else {
-        s->bi_buf |= (ush)value << s->bi_valid;
-        s->bi_valid += length;
-    }
-}
-#else /* !DEBUG */
-
-#define send_bits(s, value, length) \
-{ int len = length;\
-  if (s->bi_valid > (int)Buf_size - len) {\
-    int val = value;\
-    s->bi_buf |= (ush)val << s->bi_valid;\
-    put_short(s, s->bi_buf);\
-    s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
-    s->bi_valid += len - Buf_size;\
-  } else {\
-    s->bi_buf |= (ush)(value) << s->bi_valid;\
-    s->bi_valid += len;\
-  }\
-}
-#endif /* DEBUG */
-
-
-/* the arguments must not have side effects */
-
-/* ===========================================================================
- * Initialize the various 'constant' tables.
- */
-local void tr_static_init()
-{
-#if defined(GEN_TREES_H) || !defined(STDC)
-    static int static_init_done = 0;
-    int n;        /* iterates over tree elements */
-    int bits;     /* bit counter */
-    int length;   /* length value */
-    int code;     /* code value */
-    int dist;     /* distance index */
-    ush bl_count[MAX_BITS+1];
-    /* number of codes at each bit length for an optimal tree */
-
-    if (static_init_done) return;
-
-    /* For some embedded targets, global variables are not initialized: */
-#ifdef NO_INIT_GLOBAL_POINTERS
-    static_l_desc.static_tree = static_ltree;
-    static_l_desc.extra_bits = extra_lbits;
-    static_d_desc.static_tree = static_dtree;
-    static_d_desc.extra_bits = extra_dbits;
-    static_bl_desc.extra_bits = extra_blbits;
-#endif
-
-    /* Initialize the mapping length (0..255) -> length code (0..28) */
-    length = 0;
-    for (code = 0; code < LENGTH_CODES-1; code++) {
-        base_length[code] = length;
-        for (n = 0; n < (1<<extra_lbits[code]); n++) {
-            _length_code[length++] = (uch)code;
-        }
-    }
-    Assert (length == 256, "tr_static_init: length != 256");
-    /* Note that the length 255 (match length 258) can be represented
-     * in two different ways: code 284 + 5 bits or code 285, so we
-     * overwrite length_code[255] to use the best encoding:
-     */
-    _length_code[length-1] = (uch)code;
-
-    /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
-    dist = 0;
-    for (code = 0 ; code < 16; code++) {
-        base_dist[code] = dist;
-        for (n = 0; n < (1<<extra_dbits[code]); n++) {
-            _dist_code[dist++] = (uch)code;
-        }
-    }
-    Assert (dist == 256, "tr_static_init: dist != 256");
-    dist >>= 7; /* from now on, all distances are divided by 128 */
-    for ( ; code < D_CODES; code++) {
-        base_dist[code] = dist << 7;
-        for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
-            _dist_code[256 + dist++] = (uch)code;
-        }
-    }
-    Assert (dist == 256, "tr_static_init: 256+dist != 512");
-
-    /* Construct the codes of the static literal tree */
-    for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
-    n = 0;
-    while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
-    while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
-    while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
-    while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
-    /* Codes 286 and 287 do not exist, but we must include them in the
-     * tree construction to get a canonical Huffman tree (longest code
-     * all ones)
-     */
-    gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
-
-    /* The static distance tree is trivial: */
-    for (n = 0; n < D_CODES; n++) {
-        static_dtree[n].Len = 5;
-        static_dtree[n].Code = bi_reverse((unsigned)n, 5);
-    }
-    static_init_done = 1;
-
-#  ifdef GEN_TREES_H
-    gen_trees_header();
-#  endif
-#endif /* defined(GEN_TREES_H) || !defined(STDC) */
-}
-
-/* ===========================================================================
- * Genererate the file trees.h describing the static trees.
- */
-#ifdef GEN_TREES_H
-#  ifndef DEBUG
-#    include <stdio.h>
-#  endif
-
-#  define SEPARATOR(i, last, width) \
-      ((i) == (last)? "\n};\n\n" :    \
-       ((i) % (width) == (width)-1 ? ",\n" : ", "))
-
-void gen_trees_header()
-{
-    FILE *header = fopen("trees.h", "w");
-    int i;
-
-    Assert (header != NULL, "Can't open trees.h");
-    fprintf(header,
-            "/* header created automatically with -DGEN_TREES_H */\n\n");
-
-    fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
-    for (i = 0; i < L_CODES+2; i++) {
-        fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
-                static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
-    }
-
-    fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
-    for (i = 0; i < D_CODES; i++) {
-        fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
-                static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
-    }
-
-    fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n");
-    for (i = 0; i < DIST_CODE_LEN; i++) {
-        fprintf(header, "%2u%s", _dist_code[i],
-                SEPARATOR(i, DIST_CODE_LEN-1, 20));
-    }
-
-    fprintf(header,
-        "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
-    for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
-        fprintf(header, "%2u%s", _length_code[i],
-                SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
-    }
-
-    fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
-    for (i = 0; i < LENGTH_CODES; i++) {
-        fprintf(header, "%1u%s", base_length[i],
-                SEPARATOR(i, LENGTH_CODES-1, 20));
-    }
-
-    fprintf(header, "local const int base_dist[D_CODES] = {\n");
-    for (i = 0; i < D_CODES; i++) {
-        fprintf(header, "%5u%s", base_dist[i],
-                SEPARATOR(i, D_CODES-1, 10));
-    }
-
-    fclose(header);
-}
-#endif /* GEN_TREES_H */
-
-/* ===========================================================================
- * Initialize the tree data structures for a new zlib stream.
- */
-void ZLIB_INTERNAL _tr_init(s)
-    deflate_state *s;
-{
-    tr_static_init();
-
-    s->l_desc.dyn_tree = s->dyn_ltree;
-    s->l_desc.stat_desc = &static_l_desc;
-
-    s->d_desc.dyn_tree = s->dyn_dtree;
-    s->d_desc.stat_desc = &static_d_desc;
-
-    s->bl_desc.dyn_tree = s->bl_tree;
-    s->bl_desc.stat_desc = &static_bl_desc;
-
-    s->bi_buf = 0;
-    s->bi_valid = 0;
-#ifdef DEBUG
-    s->compressed_len = 0L;
-    s->bits_sent = 0L;
-#endif
-
-    /* Initialize the first block of the first file: */
-    init_block(s);
-}
-
-/* ===========================================================================
- * Initialize a new block.
- */
-local void init_block(s)
-    deflate_state *s;
-{
-    int n; /* iterates over tree elements */
-
-    /* Initialize the trees. */
-    for (n = 0; n < L_CODES;  n++) s->dyn_ltree[n].Freq = 0;
-    for (n = 0; n < D_CODES;  n++) s->dyn_dtree[n].Freq = 0;
-    for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
-
-    s->dyn_ltree[END_BLOCK].Freq = 1;
-    s->opt_len = s->static_len = 0L;
-    s->last_lit = s->matches = 0;
-}
-
-#define SMALLEST 1
-/* Index within the heap array of least frequent node in the Huffman tree */
-
-
-/* ===========================================================================
- * Remove the smallest element from the heap and recreate the heap with
- * one less element. Updates heap and heap_len.
- */
-#define pqremove(s, tree, top) \
-{\
-    top = s->heap[SMALLEST]; \
-    s->heap[SMALLEST] = s->heap[s->heap_len--]; \
-    pqdownheap(s, tree, SMALLEST); \
-}
-
-/* ===========================================================================
- * Compares to subtrees, using the tree depth as tie breaker when
- * the subtrees have equal frequency. This minimizes the worst case length.
- */
-#define smaller(tree, n, m, depth) \
-   (tree[n].Freq < tree[m].Freq || \
-   (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
-
-/* ===========================================================================
- * Restore the heap property by moving down the tree starting at node k,
- * exchanging a node with the smallest of its two sons if necessary, stopping
- * when the heap property is re-established (each father smaller than its
- * two sons).
- */
-local void pqdownheap(s, tree, k)
-    deflate_state *s;
-    ct_data *tree;  /* the tree to restore */
-    int k;               /* node to move down */
-{
-    int v = s->heap[k];
-    int j = k << 1;  /* left son of k */
-    while (j <= s->heap_len) {
-        /* Set j to the smallest of the two sons: */
-        if (j < s->heap_len &&
-            smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
-            j++;
-        }
-        /* Exit if v is smaller than both sons */
-        if (smaller(tree, v, s->heap[j], s->depth)) break;
-
-        /* Exchange v with the smallest son */
-        s->heap[k] = s->heap[j];  k = j;
-
-        /* And continue down the tree, setting j to the left son of k */
-        j <<= 1;
-    }
-    s->heap[k] = v;
-}
-
-/* ===========================================================================
- * Compute the optimal bit lengths for a tree and update the total bit length
- * for the current block.
- * IN assertion: the fields freq and dad are set, heap[heap_max] and
- *    above are the tree nodes sorted by increasing frequency.
- * OUT assertions: the field len is set to the optimal bit length, the
- *     array bl_count contains the frequencies for each bit length.
- *     The length opt_len is updated; static_len is also updated if stree is
- *     not null.
- */
-local void gen_bitlen(s, desc)
-    deflate_state *s;
-    tree_desc *desc;    /* the tree descriptor */
-{
-    ct_data *tree        = desc->dyn_tree;
-    int max_code         = desc->max_code;
-    const ct_data *stree = desc->stat_desc->static_tree;
-    const intf *extra    = desc->stat_desc->extra_bits;
-    int base             = desc->stat_desc->extra_base;
-    int max_length       = desc->stat_desc->max_length;
-    int h;              /* heap index */
-    int n, m;           /* iterate over the tree elements */
-    int bits;           /* bit length */
-    int xbits;          /* extra bits */
-    ush f;              /* frequency */
-    int overflow = 0;   /* number of elements with bit length too large */
-
-    for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
-
-    /* In a first pass, compute the optimal bit lengths (which may
-     * overflow in the case of the bit length tree).
-     */
-    tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
-
-    for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
-        n = s->heap[h];
-        bits = tree[tree[n].Dad].Len + 1;
-        if (bits > max_length) bits = max_length, overflow++;
-        tree[n].Len = (ush)bits;
-        /* We overwrite tree[n].Dad which is no longer needed */
-
-        if (n > max_code) continue; /* not a leaf node */
-
-        s->bl_count[bits]++;
-        xbits = 0;
-        if (n >= base) xbits = extra[n-base];
-        f = tree[n].Freq;
-        s->opt_len += (ulg)f * (bits + xbits);
-        if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
-    }
-    if (overflow == 0) return;
-
-    Trace((stderr,"\nbit length overflow\n"));
-    /* This happens for example on obj2 and pic of the Calgary corpus */
-
-    /* Find the first bit length which could increase: */
-    do {
-        bits = max_length-1;
-        while (s->bl_count[bits] == 0) bits--;
-        s->bl_count[bits]--;      /* move one leaf down the tree */
-        s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
-        s->bl_count[max_length]--;
-        /* The brother of the overflow item also moves one step up,
-         * but this does not affect bl_count[max_length]
-         */
-        overflow -= 2;
-    } while (overflow > 0);
-
-    /* Now recompute all bit lengths, scanning in increasing frequency.
-     * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
-     * lengths instead of fixing only the wrong ones. This idea is taken
-     * from 'ar' written by Haruhiko Okumura.)
-     */
-    for (bits = max_length; bits != 0; bits--) {
-        n = s->bl_count[bits];
-        while (n != 0) {
-            m = s->heap[--h];
-            if (m > max_code) continue;
-            if ((unsigned) tree[m].Len != (unsigned) bits) {
-                Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
-                s->opt_len += ((long)bits - (long)tree[m].Len)
-                              *(long)tree[m].Freq;
-                tree[m].Len = (ush)bits;
-            }
-            n--;
-        }
-    }
-}
-
-/* ===========================================================================
- * Generate the codes for a given tree and bit counts (which need not be
- * optimal).
- * IN assertion: the array bl_count contains the bit length statistics for
- * the given tree and the field len is set for all tree elements.
- * OUT assertion: the field code is set for all tree elements of non
- *     zero code length.
- */
-local void gen_codes (tree, max_code, bl_count)
-    ct_data *tree;             /* the tree to decorate */
-    int max_code;              /* largest code with non zero frequency */
-    ushf *bl_count;            /* number of codes at each bit length */
-{
-    ush next_code[MAX_BITS+1]; /* next code value for each bit length */
-    ush code = 0;              /* running code value */
-    int bits;                  /* bit index */
-    int n;                     /* code index */
-
-    /* The distribution counts are first used to generate the code values
-     * without bit reversal.
-     */
-    for (bits = 1; bits <= MAX_BITS; bits++) {
-        next_code[bits] = code = (code + bl_count[bits-1]) << 1;
-    }
-    /* Check that the bit counts in bl_count are consistent. The last code
-     * must be all ones.
-     */
-    Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
-            "inconsistent bit counts");
-    Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
-
-    for (n = 0;  n <= max_code; n++) {
-        int len = tree[n].Len;
-        if (len == 0) continue;
-        /* Now reverse the bits */
-        tree[n].Code = bi_reverse(next_code[len]++, len);
-
-        Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
-             n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
-    }
-}
-
-/* ===========================================================================
- * Construct one Huffman tree and assigns the code bit strings and lengths.
- * Update the total bit length for the current block.
- * IN assertion: the field freq is set for all tree elements.
- * OUT assertions: the fields len and code are set to the optimal bit length
- *     and corresponding code. The length opt_len is updated; static_len is
- *     also updated if stree is not null. The field max_code is set.
- */
-local void build_tree(s, desc)
-    deflate_state *s;
-    tree_desc *desc; /* the tree descriptor */
-{
-    ct_data *tree         = desc->dyn_tree;
-    const ct_data *stree  = desc->stat_desc->static_tree;
-    int elems             = desc->stat_desc->elems;
-    int n, m;          /* iterate over heap elements */
-    int max_code = -1; /* largest code with non zero frequency */
-    int node;          /* new node being created */
-
-    /* Construct the initial heap, with least frequent element in
-     * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
-     * heap[0] is not used.
-     */
-    s->heap_len = 0, s->heap_max = HEAP_SIZE;
-
-    for (n = 0; n < elems; n++) {
-        if (tree[n].Freq != 0) {
-            s->heap[++(s->heap_len)] = max_code = n;
-            s->depth[n] = 0;
-        } else {
-            tree[n].Len = 0;
-        }
-    }
-
-    /* The pkzip format requires that at least one distance code exists,
-     * and that at least one bit should be sent even if there is only one
-     * possible code. So to avoid special checks later on we force at least
-     * two codes of non zero frequency.
-     */
-    while (s->heap_len < 2) {
-        node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
-        tree[node].Freq = 1;
-        s->depth[node] = 0;
-        s->opt_len--; if (stree) s->static_len -= stree[node].Len;
-        /* node is 0 or 1 so it does not have extra bits */
-    }
-    desc->max_code = max_code;
-
-    /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
-     * establish sub-heaps of increasing lengths:
-     */
-    for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
-
-    /* Construct the Huffman tree by repeatedly combining the least two
-     * frequent nodes.
-     */
-    node = elems;              /* next internal node of the tree */
-    do {
-        pqremove(s, tree, n);  /* n = node of least frequency */
-        m = s->heap[SMALLEST]; /* m = node of next least frequency */
-
-        s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
-        s->heap[--(s->heap_max)] = m;
-
-        /* Create a new node father of n and m */
-        tree[node].Freq = tree[n].Freq + tree[m].Freq;
-        s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ?
-                                s->depth[n] : s->depth[m]) + 1);
-        tree[n].Dad = tree[m].Dad = (ush)node;
-#ifdef DUMP_BL_TREE
-        if (tree == s->bl_tree) {
-            fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
-                    node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
-        }
-#endif
-        /* and insert the new node in the heap */
-        s->heap[SMALLEST] = node++;
-        pqdownheap(s, tree, SMALLEST);
-
-    } while (s->heap_len >= 2);
-
-    s->heap[--(s->heap_max)] = s->heap[SMALLEST];
-
-    /* At this point, the fields freq and dad are set. We can now
-     * generate the bit lengths.
-     */
-    gen_bitlen(s, (tree_desc *)desc);
-
-    /* The field len is now set, we can generate the bit codes */
-    gen_codes ((ct_data *)tree, max_code, s->bl_count);
-}
-
-/* ===========================================================================
- * Scan a literal or distance tree to determine the frequencies of the codes
- * in the bit length tree.
- */
-local void scan_tree (s, tree, max_code)
-    deflate_state *s;
-    ct_data *tree;   /* the tree to be scanned */
-    int max_code;    /* and its largest code of non zero frequency */
-{
-    int n;                     /* iterates over all tree elements */
-    int prevlen = -1;          /* last emitted length */
-    int curlen;                /* length of current code */
-    int nextlen = tree[0].Len; /* length of next code */
-    int count = 0;             /* repeat count of the current code */
-    int max_count = 7;         /* max repeat count */
-    int min_count = 4;         /* min repeat count */
-
-    if (nextlen == 0) max_count = 138, min_count = 3;
-    tree[max_code+1].Len = (ush)0xffff; /* guard */
-
-    for (n = 0; n <= max_code; n++) {
-        curlen = nextlen; nextlen = tree[n+1].Len;
-        if (++count < max_count && curlen == nextlen) {
-            continue;
-        } else if (count < min_count) {
-            s->bl_tree[curlen].Freq += count;
-        } else if (curlen != 0) {
-            if (curlen != prevlen) s->bl_tree[curlen].Freq++;
-            s->bl_tree[REP_3_6].Freq++;
-        } else if (count <= 10) {
-            s->bl_tree[REPZ_3_10].Freq++;
-        } else {
-            s->bl_tree[REPZ_11_138].Freq++;
-        }
-        count = 0; prevlen = curlen;
-        if (nextlen == 0) {
-            max_count = 138, min_count = 3;
-        } else if (curlen == nextlen) {
-            max_count = 6, min_count = 3;
-        } else {
-            max_count = 7, min_count = 4;
-        }
-    }
-}
-
-/* ===========================================================================
- * Send a literal or distance tree in compressed form, using the codes in
- * bl_tree.
- */
-local void send_tree (s, tree, max_code)
-    deflate_state *s;
-    ct_data *tree; /* the tree to be scanned */
-    int max_code;       /* and its largest code of non zero frequency */
-{
-    int n;                     /* iterates over all tree elements */
-    int prevlen = -1;          /* last emitted length */
-    int curlen;                /* length of current code */
-    int nextlen = tree[0].Len; /* length of next code */
-    int count = 0;             /* repeat count of the current code */
-    int max_count = 7;         /* max repeat count */
-    int min_count = 4;         /* min repeat count */
-
-    /* tree[max_code+1].Len = -1; */  /* guard already set */
-    if (nextlen == 0) max_count = 138, min_count = 3;
-
-    for (n = 0; n <= max_code; n++) {
-        curlen = nextlen; nextlen = tree[n+1].Len;
-        if (++count < max_count && curlen == nextlen) {
-            continue;
-        } else if (count < min_count) {
-            do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
-
-        } else if (curlen != 0) {
-            if (curlen != prevlen) {
-                send_code(s, curlen, s->bl_tree); count--;
-            }
-            Assert(count >= 3 && count <= 6, " 3_6?");
-            send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
-
-        } else if (count <= 10) {
-            send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
-
-        } else {
-            send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
-        }
-        count = 0; prevlen = curlen;
-        if (nextlen == 0) {
-            max_count = 138, min_count = 3;
-        } else if (curlen == nextlen) {
-            max_count = 6, min_count = 3;
-        } else {
-            max_count = 7, min_count = 4;
-        }
-    }
-}
-
-/* ===========================================================================
- * Construct the Huffman tree for the bit lengths and return the index in
- * bl_order of the last bit length code to send.
- */
-local int build_bl_tree(s)
-    deflate_state *s;
-{
-    int max_blindex;  /* index of last bit length code of non zero freq */
-
-    /* Determine the bit length frequencies for literal and distance trees */
-    scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
-    scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
-
-    /* Build the bit length tree: */
-    build_tree(s, (tree_desc *)(&(s->bl_desc)));
-    /* opt_len now includes the length of the tree representations, except
-     * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
-     */
-
-    /* Determine the number of bit length codes to send. The pkzip format
-     * requires that at least 4 bit length codes be sent. (appnote.txt says
-     * 3 but the actual value used is 4.)
-     */
-    for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
-        if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
-    }
-    /* Update opt_len to include the bit length tree and counts */
-    s->opt_len += 3*(max_blindex+1) + 5+5+4;
-    Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
-            s->opt_len, s->static_len));
-
-    return max_blindex;
-}
-
-/* ===========================================================================
- * Send the header for a block using dynamic Huffman trees: the counts, the
- * lengths of the bit length codes, the literal tree and the distance tree.
- * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
- */
-local void send_all_trees(s, lcodes, dcodes, blcodes)
-    deflate_state *s;
-    int lcodes, dcodes, blcodes; /* number of codes for each tree */
-{
-    int rank;                    /* index in bl_order */
-
-    Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
-    Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
-            "too many codes");
-    Tracev((stderr, "\nbl counts: "));
-    send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
-    send_bits(s, dcodes-1,   5);
-    send_bits(s, blcodes-4,  4); /* not -3 as stated in appnote.txt */
-    for (rank = 0; rank < blcodes; rank++) {
-        Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
-        send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
-    }
-    Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
-
-    send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
-    Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
-
-    send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
-    Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
-}
-
-/* ===========================================================================
- * Send a stored block
- */
-void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last)
-    deflate_state *s;
-    charf *buf;       /* input block */
-    ulg stored_len;   /* length of input block */
-    int last;         /* one if this is the last block for a file */
-{
-    send_bits(s, (STORED_BLOCK<<1)+last, 3);    /* send block type */
-#ifdef DEBUG
-    s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
-    s->compressed_len += (stored_len + 4) << 3;
-#endif
-    copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
-}
-
-/* ===========================================================================
- * Flush the bits in the bit buffer to pending output (leaves at most 7 bits)
- */
-void ZLIB_INTERNAL _tr_flush_bits(s)
-    deflate_state *s;
-{
-    bi_flush(s);
-}
-
-/* ===========================================================================
- * Send one empty static block to give enough lookahead for inflate.
- * This takes 10 bits, of which 7 may remain in the bit buffer.
- */
-void ZLIB_INTERNAL _tr_align(s)
-    deflate_state *s;
-{
-    send_bits(s, STATIC_TREES<<1, 3);
-    send_code(s, END_BLOCK, static_ltree);
-#ifdef DEBUG
-    s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
-#endif
-    bi_flush(s);
-}
-
-/* ===========================================================================
- * Determine the best encoding for the current block: dynamic trees, static
- * trees or store, and output the encoded block to the zip file.
- */
-void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
-    deflate_state *s;
-    charf *buf;       /* input block, or NULL if too old */
-    ulg stored_len;   /* length of input block */
-    int last;         /* one if this is the last block for a file */
-{
-    ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
-    int max_blindex = 0;  /* index of last bit length code of non zero freq */
-
-    /* Build the Huffman trees unless a stored block is forced */
-    if (s->level > 0) {
-
-        /* Check if the file is binary or text */
-        if (s->strm->data_type == Z_UNKNOWN)
-            s->strm->data_type = detect_data_type(s);
-
-        /* Construct the literal and distance trees */
-        build_tree(s, (tree_desc *)(&(s->l_desc)));
-        Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
-                s->static_len));
-
-        build_tree(s, (tree_desc *)(&(s->d_desc)));
-        Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
-                s->static_len));
-        /* At this point, opt_len and static_len are the total bit lengths of
-         * the compressed block data, excluding the tree representations.
-         */
-
-        /* Build the bit length tree for the above two trees, and get the index
-         * in bl_order of the last bit length code to send.
-         */
-        max_blindex = build_bl_tree(s);
-
-        /* Determine the best encoding. Compute the block lengths in bytes. */
-        opt_lenb = (s->opt_len+3+7)>>3;
-        static_lenb = (s->static_len+3+7)>>3;
-
-        Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
-                opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
-                s->last_lit));
-
-        if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
-
-    } else {
-        Assert(buf != (char*)0, "lost buf");
-        opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
-    }
-
-#ifdef FORCE_STORED
-    if (buf != (char*)0) { /* force stored block */
-#else
-    if (stored_len+4 <= opt_lenb && buf != (char*)0) {
-                       /* 4: two words for the lengths */
-#endif
-        /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
-         * Otherwise we can't have processed more than WSIZE input bytes since
-         * the last block flush, because compression would have been
-         * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
-         * transform a block into a stored block.
-         */
-        _tr_stored_block(s, buf, stored_len, last);
-
-#ifdef FORCE_STATIC
-    } else if (static_lenb >= 0) { /* force static trees */
-#else
-    } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {
-#endif
-        send_bits(s, (STATIC_TREES<<1)+last, 3);
-        compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
-#ifdef DEBUG
-        s->compressed_len += 3 + s->static_len;
-#endif
-    } else {
-        send_bits(s, (DYN_TREES<<1)+last, 3);
-        send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
-                       max_blindex+1);
-        compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
-#ifdef DEBUG
-        s->compressed_len += 3 + s->opt_len;
-#endif
-    }
-    Assert (s->compressed_len == s->bits_sent, "bad compressed size");
-    /* The above check is made mod 2^32, for files larger than 512 MB
-     * and uLong implemented on 32 bits.
-     */
-    init_block(s);
-
-    if (last) {
-        bi_windup(s);
-#ifdef DEBUG
-        s->compressed_len += 7;  /* align on byte boundary */
-#endif
-    }
-    Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
-           s->compressed_len-7*last));
-}
-
-/* ===========================================================================
- * Save the match info and tally the frequency counts. Return true if
- * the current block must be flushed.
- */
-int ZLIB_INTERNAL _tr_tally (s, dist, lc)
-    deflate_state *s;
-    unsigned dist;  /* distance of matched string */
-    unsigned lc;    /* match length-MIN_MATCH or unmatched char (if dist==0) */
-{
-    s->d_buf[s->last_lit] = (ush)dist;
-    s->l_buf[s->last_lit++] = (uch)lc;
-    if (dist == 0) {
-        /* lc is the unmatched char */
-        s->dyn_ltree[lc].Freq++;
-    } else {
-        s->matches++;
-        /* Here, lc is the match length - MIN_MATCH */
-        dist--;             /* dist = match distance - 1 */
-        Assert((ush)dist < (ush)MAX_DIST(s) &&
-               (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
-               (ush)d_code(dist) < (ush)D_CODES,  "_tr_tally: bad match");
-
-        s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
-        s->dyn_dtree[d_code(dist)].Freq++;
-    }
-
-#ifdef TRUNCATE_BLOCK
-    /* Try to guess if it is profitable to stop the current block here */
-    if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
-        /* Compute an upper bound for the compressed length */
-        ulg out_length = (ulg)s->last_lit*8L;
-        ulg in_length = (ulg)((long)s->strstart - s->block_start);
-        int dcode;
-        for (dcode = 0; dcode < D_CODES; dcode++) {
-            out_length += (ulg)s->dyn_dtree[dcode].Freq *
-                (5L+extra_dbits[dcode]);
-        }
-        out_length >>= 3;
-        Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
-               s->last_lit, in_length, out_length,
-               100L - out_length*100L/in_length));
-        if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
-    }
-#endif
-    return (s->last_lit == s->lit_bufsize-1);
-    /* We avoid equality with lit_bufsize because of wraparound at 64K
-     * on 16 bit machines and because stored blocks are restricted to
-     * 64K-1 bytes.
-     */
-}
-
-/* ===========================================================================
- * Send the block data compressed using the given Huffman trees
- */
-local void compress_block(s, ltree, dtree)
-    deflate_state *s;
-    ct_data *ltree; /* literal tree */
-    ct_data *dtree; /* distance tree */
-{
-    unsigned dist;      /* distance of matched string */
-    int lc;             /* match length or unmatched char (if dist == 0) */
-    unsigned lx = 0;    /* running index in l_buf */
-    unsigned code;      /* the code to send */
-    int extra;          /* number of extra bits to send */
-
-    if (s->last_lit != 0) do {
-        dist = s->d_buf[lx];
-        lc = s->l_buf[lx++];
-        if (dist == 0) {
-            send_code(s, lc, ltree); /* send a literal byte */
-            Tracecv(isgraph(lc), (stderr," '%c' ", lc));
-        } else {
-            /* Here, lc is the match length - MIN_MATCH */
-            code = _length_code[lc];
-            send_code(s, code+LITERALS+1, ltree); /* send the length code */
-            extra = extra_lbits[code];
-            if (extra != 0) {
-                lc -= base_length[code];
-                send_bits(s, lc, extra);       /* send the extra length bits */
-            }
-            dist--; /* dist is now the match distance - 1 */
-            code = d_code(dist);
-            Assert (code < D_CODES, "bad d_code");
-
-            send_code(s, code, dtree);       /* send the distance code */
-            extra = extra_dbits[code];
-            if (extra != 0) {
-                dist -= base_dist[code];
-                send_bits(s, dist, extra);   /* send the extra distance bits */
-            }
-        } /* literal or match pair ? */
-
-        /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
-        Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
-               "pendingBuf overflow");
-
-    } while (lx < s->last_lit);
-
-    send_code(s, END_BLOCK, ltree);
-}
-
-/* ===========================================================================
- * Check if the data type is TEXT or BINARY, using the following algorithm:
- * - TEXT if the two conditions below are satisfied:
- *    a) There are no non-portable control characters belonging to the
- *       "black list" (0..6, 14..25, 28..31).
- *    b) There is at least one printable character belonging to the
- *       "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255).
- * - BINARY otherwise.
- * - The following partially-portable control characters form a
- *   "gray list" that is ignored in this detection algorithm:
- *   (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}).
- * IN assertion: the fields Freq of dyn_ltree are set.
- */
-local int detect_data_type(s)
-    deflate_state *s;
-{
-    /* black_mask is the bit mask of black-listed bytes
-     * set bits 0..6, 14..25, and 28..31
-     * 0xf3ffc07f = binary 11110011111111111100000001111111
-     */
-    unsigned long black_mask = 0xf3ffc07fUL;
-    int n;
-
-    /* Check for non-textual ("black-listed") bytes. */
-    for (n = 0; n <= 31; n++, black_mask >>= 1)
-        if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0))
-            return Z_BINARY;
-
-    /* Check for textual ("white-listed") bytes. */
-    if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0
-            || s->dyn_ltree[13].Freq != 0)
-        return Z_TEXT;
-    for (n = 32; n < LITERALS; n++)
-        if (s->dyn_ltree[n].Freq != 0)
-            return Z_TEXT;
-
-    /* There are no "black-listed" or "white-listed" bytes:
-     * this stream either is empty or has tolerated ("gray-listed") bytes only.
-     */
-    return Z_BINARY;
-}
-
-/* ===========================================================================
- * Reverse the first len bits of a code, using straightforward code (a faster
- * method would use a table)
- * IN assertion: 1 <= len <= 15
- */
-local unsigned bi_reverse(code, len)
-    unsigned code; /* the value to invert */
-    int len;       /* its bit length */
-{
-    register unsigned res = 0;
-    do {
-        res |= code & 1;
-        code >>= 1, res <<= 1;
-    } while (--len > 0);
-    return res >> 1;
-}
-
-/* ===========================================================================
- * Flush the bit buffer, keeping at most 7 bits in it.
- */
-local void bi_flush(s)
-    deflate_state *s;
-{
-    if (s->bi_valid == 16) {
-        put_short(s, s->bi_buf);
-        s->bi_buf = 0;
-        s->bi_valid = 0;
-    } else if (s->bi_valid >= 8) {
-        put_byte(s, (Byte)s->bi_buf);
-        s->bi_buf >>= 8;
-        s->bi_valid -= 8;
-    }
-}
-
-/* ===========================================================================
- * Flush the bit buffer and align the output on a byte boundary
- */
-local void bi_windup(s)
-    deflate_state *s;
-{
-    if (s->bi_valid > 8) {
-        put_short(s, s->bi_buf);
-    } else if (s->bi_valid > 0) {
-        put_byte(s, (Byte)s->bi_buf);
-    }
-    s->bi_buf = 0;
-    s->bi_valid = 0;
-#ifdef DEBUG
-    s->bits_sent = (s->bits_sent+7) & ~7;
-#endif
-}
-
-/* ===========================================================================
- * Copy a stored block, storing first the length and its
- * one's complement if requested.
- */
-local void copy_block(s, buf, len, header)
-    deflate_state *s;
-    charf    *buf;    /* the input data */
-    unsigned len;     /* its length */
-    int      header;  /* true if block header must be written */
-{
-    bi_windup(s);        /* align on byte boundary */
-
-    if (header) {
-        put_short(s, (ush)len);
-        put_short(s, (ush)~len);
-#ifdef DEBUG
-        s->bits_sent += 2*16;
-#endif
-    }
-#ifdef DEBUG
-    s->bits_sent += (ulg)len<<3;
-#endif
-    while (len--) {
-        put_byte(s, *buf++);
-    }
-}
+/* trees.c -- output deflated data using Huffman coding
+ * Copyright (C) 1995-2012 Jean-loup Gailly
+ * detect_data_type() function provided freely by Cosmin Truta, 2006
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ *  ALGORITHM
+ *
+ *      The "deflation" process uses several Huffman trees. The more
+ *      common source values are represented by shorter bit sequences.
+ *
+ *      Each code tree is stored in a compressed form which is itself
+ * a Huffman encoding of the lengths of all the code strings (in
+ * ascending order by source values).  The actual code strings are
+ * reconstructed from the lengths in the inflate process, as described
+ * in the deflate specification.
+ *
+ *  REFERENCES
+ *
+ *      Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
+ *      Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
+ *
+ *      Storer, James A.
+ *          Data Compression:  Methods and Theory, pp. 49-50.
+ *          Computer Science Press, 1988.  ISBN 0-7167-8156-5.
+ *
+ *      Sedgewick, R.
+ *          Algorithms, p290.
+ *          Addison-Wesley, 1983. ISBN 0-201-06672-6.
+ */
+
+/* @(#) $Id: trees.c,v 1.10 2013/05/10 17:22:52 drolon Exp $ */
+
+/* #define GEN_TREES_H */
+
+#include "deflate.h"
+
+#ifdef DEBUG
+#  include <ctype.h>
+#endif
+
+/* ===========================================================================
+ * Constants
+ */
+
+#define MAX_BL_BITS 7
+/* Bit length codes must not exceed MAX_BL_BITS bits */
+
+#define END_BLOCK 256
+/* end of block literal code */
+
+#define REP_3_6      16
+/* repeat previous bit length 3-6 times (2 bits of repeat count) */
+
+#define REPZ_3_10    17
+/* repeat a zero length 3-10 times  (3 bits of repeat count) */
+
+#define REPZ_11_138  18
+/* repeat a zero length 11-138 times  (7 bits of repeat count) */
+
+local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
+   = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
+
+local const int extra_dbits[D_CODES] /* extra bits for each distance code */
+   = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
+
+local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
+   = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
+
+local const uch bl_order[BL_CODES]
+   = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
+/* The lengths of the bit length codes are sent in order of decreasing
+ * probability, to avoid transmitting the lengths for unused bit length codes.
+ */
+
+/* ===========================================================================
+ * Local data. These are initialized only once.
+ */
+
+#define DIST_CODE_LEN  512 /* see definition of array dist_code below */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+/* non ANSI compilers may not accept trees.h */
+
+local ct_data static_ltree[L_CODES+2];
+/* The static literal tree. Since the bit lengths are imposed, there is no
+ * need for the L_CODES extra codes used during heap construction. However
+ * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
+ * below).
+ */
+
+local ct_data static_dtree[D_CODES];
+/* The static distance tree. (Actually a trivial tree since all codes use
+ * 5 bits.)
+ */
+
+uch _dist_code[DIST_CODE_LEN];
+/* Distance codes. The first 256 values correspond to the distances
+ * 3 .. 258, the last 256 values correspond to the top 8 bits of
+ * the 15 bit distances.
+ */
+
+uch _length_code[MAX_MATCH-MIN_MATCH+1];
+/* length code for each normalized match length (0 == MIN_MATCH) */
+
+local int base_length[LENGTH_CODES];
+/* First normalized length for each code (0 = MIN_MATCH) */
+
+local int base_dist[D_CODES];
+/* First normalized distance for each code (0 = distance of 1) */
+
+#else
+#  include "trees.h"
+#endif /* GEN_TREES_H */
+
+struct static_tree_desc_s {
+    const ct_data *static_tree;  /* static tree or NULL */
+    const intf *extra_bits;      /* extra bits for each code or NULL */
+    int     extra_base;          /* base index for extra_bits */
+    int     elems;               /* max number of elements in the tree */
+    int     max_length;          /* max bit length for the codes */
+};
+
+local static_tree_desc  static_l_desc =
+{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
+
+local static_tree_desc  static_d_desc =
+{static_dtree, extra_dbits, 0,          D_CODES, MAX_BITS};
+
+local static_tree_desc  static_bl_desc =
+{(const ct_data *)0, extra_blbits, 0,   BL_CODES, MAX_BL_BITS};
+
+/* ===========================================================================
+ * Local (static) routines in this file.
+ */
+
+local void tr_static_init OF((void));
+local void init_block     OF((deflate_state *s));
+local void pqdownheap     OF((deflate_state *s, ct_data *tree, int k));
+local void gen_bitlen     OF((deflate_state *s, tree_desc *desc));
+local void gen_codes      OF((ct_data *tree, int max_code, ushf *bl_count));
+local void build_tree     OF((deflate_state *s, tree_desc *desc));
+local void scan_tree      OF((deflate_state *s, ct_data *tree, int max_code));
+local void send_tree      OF((deflate_state *s, ct_data *tree, int max_code));
+local int  build_bl_tree  OF((deflate_state *s));
+local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
+                              int blcodes));
+local void compress_block OF((deflate_state *s, const ct_data *ltree,
+                              const ct_data *dtree));
+local int  detect_data_type OF((deflate_state *s));
+local unsigned bi_reverse OF((unsigned value, int length));
+local void bi_windup      OF((deflate_state *s));
+local void bi_flush       OF((deflate_state *s));
+local void copy_block     OF((deflate_state *s, charf *buf, unsigned len,
+                              int header));
+
+#ifdef GEN_TREES_H
+local void gen_trees_header OF((void));
+#endif
+
+#ifndef DEBUG
+#  define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
+   /* Send a code of the given tree. c and tree must not have side effects */
+
+#else /* DEBUG */
+#  define send_code(s, c, tree) \
+     { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
+       send_bits(s, tree[c].Code, tree[c].Len); }
+#endif
+
+/* ===========================================================================
+ * Output a short LSB first on the stream.
+ * IN assertion: there is enough room in pendingBuf.
+ */
+#define put_short(s, w) { \
+    put_byte(s, (uch)((w) & 0xff)); \
+    put_byte(s, (uch)((ush)(w) >> 8)); \
+}
+
+/* ===========================================================================
+ * Send a value on a given number of bits.
+ * IN assertion: length <= 16 and value fits in length bits.
+ */
+#ifdef DEBUG
+local void send_bits      OF((deflate_state *s, int value, int length));
+
+local void send_bits(s, value, length)
+    deflate_state *s;
+    int value;  /* value to send */
+    int length; /* number of bits */
+{
+    Tracevv((stderr," l %2d v %4x ", length, value));
+    Assert(length > 0 && length <= 15, "invalid length");
+    s->bits_sent += (ulg)length;
+
+    /* If not enough room in bi_buf, use (valid) bits from bi_buf and
+     * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
+     * unused bits in value.
+     */
+    if (s->bi_valid > (int)Buf_size - length) {
+        s->bi_buf |= (ush)value << s->bi_valid;
+        put_short(s, s->bi_buf);
+        s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
+        s->bi_valid += length - Buf_size;
+    } else {
+        s->bi_buf |= (ush)value << s->bi_valid;
+        s->bi_valid += length;
+    }
+}
+#else /* !DEBUG */
+
+#define send_bits(s, value, length) \
+{ int len = length;\
+  if (s->bi_valid > (int)Buf_size - len) {\
+    int val = value;\
+    s->bi_buf |= (ush)val << s->bi_valid;\
+    put_short(s, s->bi_buf);\
+    s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
+    s->bi_valid += len - Buf_size;\
+  } else {\
+    s->bi_buf |= (ush)(value) << s->bi_valid;\
+    s->bi_valid += len;\
+  }\
+}
+#endif /* DEBUG */
+
+
+/* the arguments must not have side effects */
+
+/* ===========================================================================
+ * Initialize the various 'constant' tables.
+ */
+local void tr_static_init()
+{
+#if defined(GEN_TREES_H) || !defined(STDC)
+    static int static_init_done = 0;
+    int n;        /* iterates over tree elements */
+    int bits;     /* bit counter */
+    int length;   /* length value */
+    int code;     /* code value */
+    int dist;     /* distance index */
+    ush bl_count[MAX_BITS+1];
+    /* number of codes at each bit length for an optimal tree */
+
+    if (static_init_done) return;
+
+    /* For some embedded targets, global variables are not initialized: */
+#ifdef NO_INIT_GLOBAL_POINTERS
+    static_l_desc.static_tree = static_ltree;
+    static_l_desc.extra_bits = extra_lbits;
+    static_d_desc.static_tree = static_dtree;
+    static_d_desc.extra_bits = extra_dbits;
+    static_bl_desc.extra_bits = extra_blbits;
+#endif
+
+    /* Initialize the mapping length (0..255) -> length code (0..28) */
+    length = 0;
+    for (code = 0; code < LENGTH_CODES-1; code++) {
+        base_length[code] = length;
+        for (n = 0; n < (1<<extra_lbits[code]); n++) {
+            _length_code[length++] = (uch)code;
+        }
+    }
+    Assert (length == 256, "tr_static_init: length != 256");
+    /* Note that the length 255 (match length 258) can be represented
+     * in two different ways: code 284 + 5 bits or code 285, so we
+     * overwrite length_code[255] to use the best encoding:
+     */
+    _length_code[length-1] = (uch)code;
+
+    /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
+    dist = 0;
+    for (code = 0 ; code < 16; code++) {
+        base_dist[code] = dist;
+        for (n = 0; n < (1<<extra_dbits[code]); n++) {
+            _dist_code[dist++] = (uch)code;
+        }
+    }
+    Assert (dist == 256, "tr_static_init: dist != 256");
+    dist >>= 7; /* from now on, all distances are divided by 128 */
+    for ( ; code < D_CODES; code++) {
+        base_dist[code] = dist << 7;
+        for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
+            _dist_code[256 + dist++] = (uch)code;
+        }
+    }
+    Assert (dist == 256, "tr_static_init: 256+dist != 512");
+
+    /* Construct the codes of the static literal tree */
+    for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
+    n = 0;
+    while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
+    while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
+    while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
+    while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
+    /* Codes 286 and 287 do not exist, but we must include them in the
+     * tree construction to get a canonical Huffman tree (longest code
+     * all ones)
+     */
+    gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
+
+    /* The static distance tree is trivial: */
+    for (n = 0; n < D_CODES; n++) {
+        static_dtree[n].Len = 5;
+        static_dtree[n].Code = bi_reverse((unsigned)n, 5);
+    }
+    static_init_done = 1;
+
+#  ifdef GEN_TREES_H
+    gen_trees_header();
+#  endif
+#endif /* defined(GEN_TREES_H) || !defined(STDC) */
+}
+
+/* ===========================================================================
+ * Genererate the file trees.h describing the static trees.
+ */
+#ifdef GEN_TREES_H
+#  ifndef DEBUG
+#    include <stdio.h>
+#  endif
+
+#  define SEPARATOR(i, last, width) \
+      ((i) == (last)? "\n};\n\n" :    \
+       ((i) % (width) == (width)-1 ? ",\n" : ", "))
+
+void gen_trees_header()
+{
+    FILE *header = fopen("trees.h", "w");
+    int i;
+
+    Assert (header != NULL, "Can't open trees.h");
+    fprintf(header,
+            "/* header created automatically with -DGEN_TREES_H */\n\n");
+
+    fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
+    for (i = 0; i < L_CODES+2; i++) {
+        fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
+                static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
+    }
+
+    fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
+    for (i = 0; i < D_CODES; i++) {
+        fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
+                static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
+    }
+
+    fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n");
+    for (i = 0; i < DIST_CODE_LEN; i++) {
+        fprintf(header, "%2u%s", _dist_code[i],
+                SEPARATOR(i, DIST_CODE_LEN-1, 20));
+    }
+
+    fprintf(header,
+        "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
+    for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
+        fprintf(header, "%2u%s", _length_code[i],
+                SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
+    }
+
+    fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
+    for (i = 0; i < LENGTH_CODES; i++) {
+        fprintf(header, "%1u%s", base_length[i],
+                SEPARATOR(i, LENGTH_CODES-1, 20));
+    }
+
+    fprintf(header, "local const int base_dist[D_CODES] = {\n");
+    for (i = 0; i < D_CODES; i++) {
+        fprintf(header, "%5u%s", base_dist[i],
+                SEPARATOR(i, D_CODES-1, 10));
+    }
+
+    fclose(header);
+}
+#endif /* GEN_TREES_H */
+
+/* ===========================================================================
+ * Initialize the tree data structures for a new zlib stream.
+ */
+void ZLIB_INTERNAL _tr_init(s)
+    deflate_state *s;
+{
+    tr_static_init();
+
+    s->l_desc.dyn_tree = s->dyn_ltree;
+    s->l_desc.stat_desc = &static_l_desc;
+
+    s->d_desc.dyn_tree = s->dyn_dtree;
+    s->d_desc.stat_desc = &static_d_desc;
+
+    s->bl_desc.dyn_tree = s->bl_tree;
+    s->bl_desc.stat_desc = &static_bl_desc;
+
+    s->bi_buf = 0;
+    s->bi_valid = 0;
+#ifdef DEBUG
+    s->compressed_len = 0L;
+    s->bits_sent = 0L;
+#endif
+
+    /* Initialize the first block of the first file: */
+    init_block(s);
+}
+
+/* ===========================================================================
+ * Initialize a new block.
+ */
+local void init_block(s)
+    deflate_state *s;
+{
+    int n; /* iterates over tree elements */
+
+    /* Initialize the trees. */
+    for (n = 0; n < L_CODES;  n++) s->dyn_ltree[n].Freq = 0;
+    for (n = 0; n < D_CODES;  n++) s->dyn_dtree[n].Freq = 0;
+    for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
+
+    s->dyn_ltree[END_BLOCK].Freq = 1;
+    s->opt_len = s->static_len = 0L;
+    s->last_lit = s->matches = 0;
+}
+
+#define SMALLEST 1
+/* Index within the heap array of least frequent node in the Huffman tree */
+
+
+/* ===========================================================================
+ * Remove the smallest element from the heap and recreate the heap with
+ * one less element. Updates heap and heap_len.
+ */
+#define pqremove(s, tree, top) \
+{\
+    top = s->heap[SMALLEST]; \
+    s->heap[SMALLEST] = s->heap[s->heap_len--]; \
+    pqdownheap(s, tree, SMALLEST); \
+}
+
+/* ===========================================================================
+ * Compares to subtrees, using the tree depth as tie breaker when
+ * the subtrees have equal frequency. This minimizes the worst case length.
+ */
+#define smaller(tree, n, m, depth) \
+   (tree[n].Freq < tree[m].Freq || \
+   (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
+
+/* ===========================================================================
+ * Restore the heap property by moving down the tree starting at node k,
+ * exchanging a node with the smallest of its two sons if necessary, stopping
+ * when the heap property is re-established (each father smaller than its
+ * two sons).
+ */
+local void pqdownheap(s, tree, k)
+    deflate_state *s;
+    ct_data *tree;  /* the tree to restore */
+    int k;               /* node to move down */
+{
+    int v = s->heap[k];
+    int j = k << 1;  /* left son of k */
+    while (j <= s->heap_len) {
+        /* Set j to the smallest of the two sons: */
+        if (j < s->heap_len &&
+            smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
+            j++;
+        }
+        /* Exit if v is smaller than both sons */
+        if (smaller(tree, v, s->heap[j], s->depth)) break;
+
+        /* Exchange v with the smallest son */
+        s->heap[k] = s->heap[j];  k = j;
+
+        /* And continue down the tree, setting j to the left son of k */
+        j <<= 1;
+    }
+    s->heap[k] = v;
+}
+
+/* ===========================================================================
+ * Compute the optimal bit lengths for a tree and update the total bit length
+ * for the current block.
+ * IN assertion: the fields freq and dad are set, heap[heap_max] and
+ *    above are the tree nodes sorted by increasing frequency.
+ * OUT assertions: the field len is set to the optimal bit length, the
+ *     array bl_count contains the frequencies for each bit length.
+ *     The length opt_len is updated; static_len is also updated if stree is
+ *     not null.
+ */
+local void gen_bitlen(s, desc)
+    deflate_state *s;
+    tree_desc *desc;    /* the tree descriptor */
+{
+    ct_data *tree        = desc->dyn_tree;
+    int max_code         = desc->max_code;
+    const ct_data *stree = desc->stat_desc->static_tree;
+    const intf *extra    = desc->stat_desc->extra_bits;
+    int base             = desc->stat_desc->extra_base;
+    int max_length       = desc->stat_desc->max_length;
+    int h;              /* heap index */
+    int n, m;           /* iterate over the tree elements */
+    int bits;           /* bit length */
+    int xbits;          /* extra bits */
+    ush f;              /* frequency */
+    int overflow = 0;   /* number of elements with bit length too large */
+
+    for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
+
+    /* In a first pass, compute the optimal bit lengths (which may
+     * overflow in the case of the bit length tree).
+     */
+    tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
+
+    for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
+        n = s->heap[h];
+        bits = tree[tree[n].Dad].Len + 1;
+        if (bits > max_length) bits = max_length, overflow++;
+        tree[n].Len = (ush)bits;
+        /* We overwrite tree[n].Dad which is no longer needed */
+
+        if (n > max_code) continue; /* not a leaf node */
+
+        s->bl_count[bits]++;
+        xbits = 0;
+        if (n >= base) xbits = extra[n-base];
+        f = tree[n].Freq;
+        s->opt_len += (ulg)f * (bits + xbits);
+        if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
+    }
+    if (overflow == 0) return;
+
+    Trace((stderr,"\nbit length overflow\n"));
+    /* This happens for example on obj2 and pic of the Calgary corpus */
+
+    /* Find the first bit length which could increase: */
+    do {
+        bits = max_length-1;
+        while (s->bl_count[bits] == 0) bits--;
+        s->bl_count[bits]--;      /* move one leaf down the tree */
+        s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
+        s->bl_count[max_length]--;
+        /* The brother of the overflow item also moves one step up,
+         * but this does not affect bl_count[max_length]
+         */
+        overflow -= 2;
+    } while (overflow > 0);
+
+    /* Now recompute all bit lengths, scanning in increasing frequency.
+     * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
+     * lengths instead of fixing only the wrong ones. This idea is taken
+     * from 'ar' written by Haruhiko Okumura.)
+     */
+    for (bits = max_length; bits != 0; bits--) {
+        n = s->bl_count[bits];
+        while (n != 0) {
+            m = s->heap[--h];
+            if (m > max_code) continue;
+            if ((unsigned) tree[m].Len != (unsigned) bits) {
+                Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
+                s->opt_len += ((long)bits - (long)tree[m].Len)
+                              *(long)tree[m].Freq;
+                tree[m].Len = (ush)bits;
+            }
+            n--;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Generate the codes for a given tree and bit counts (which need not be
+ * optimal).
+ * IN assertion: the array bl_count contains the bit length statistics for
+ * the given tree and the field len is set for all tree elements.
+ * OUT assertion: the field code is set for all tree elements of non
+ *     zero code length.
+ */
+local void gen_codes (tree, max_code, bl_count)
+    ct_data *tree;             /* the tree to decorate */
+    int max_code;              /* largest code with non zero frequency */
+    ushf *bl_count;            /* number of codes at each bit length */
+{
+    ush next_code[MAX_BITS+1]; /* next code value for each bit length */
+    ush code = 0;              /* running code value */
+    int bits;                  /* bit index */
+    int n;                     /* code index */
+
+    /* The distribution counts are first used to generate the code values
+     * without bit reversal.
+     */
+    for (bits = 1; bits <= MAX_BITS; bits++) {
+        next_code[bits] = code = (code + bl_count[bits-1]) << 1;
+    }
+    /* Check that the bit counts in bl_count are consistent. The last code
+     * must be all ones.
+     */
+    Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
+            "inconsistent bit counts");
+    Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
+
+    for (n = 0;  n <= max_code; n++) {
+        int len = tree[n].Len;
+        if (len == 0) continue;
+        /* Now reverse the bits */
+        tree[n].Code = bi_reverse(next_code[len]++, len);
+
+        Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
+             n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
+    }
+}
+
+/* ===========================================================================
+ * Construct one Huffman tree and assigns the code bit strings and lengths.
+ * Update the total bit length for the current block.
+ * IN assertion: the field freq is set for all tree elements.
+ * OUT assertions: the fields len and code are set to the optimal bit length
+ *     and corresponding code. The length opt_len is updated; static_len is
+ *     also updated if stree is not null. The field max_code is set.
+ */
+local void build_tree(s, desc)
+    deflate_state *s;
+    tree_desc *desc; /* the tree descriptor */
+{
+    ct_data *tree         = desc->dyn_tree;
+    const ct_data *stree  = desc->stat_desc->static_tree;
+    int elems             = desc->stat_desc->elems;
+    int n, m;          /* iterate over heap elements */
+    int max_code = -1; /* largest code with non zero frequency */
+    int node;          /* new node being created */
+
+    /* Construct the initial heap, with least frequent element in
+     * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
+     * heap[0] is not used.
+     */
+    s->heap_len = 0, s->heap_max = HEAP_SIZE;
+
+    for (n = 0; n < elems; n++) {
+        if (tree[n].Freq != 0) {
+            s->heap[++(s->heap_len)] = max_code = n;
+            s->depth[n] = 0;
+        } else {
+            tree[n].Len = 0;
+        }
+    }
+
+    /* The pkzip format requires that at least one distance code exists,
+     * and that at least one bit should be sent even if there is only one
+     * possible code. So to avoid special checks later on we force at least
+     * two codes of non zero frequency.
+     */
+    while (s->heap_len < 2) {
+        node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
+        tree[node].Freq = 1;
+        s->depth[node] = 0;
+        s->opt_len--; if (stree) s->static_len -= stree[node].Len;
+        /* node is 0 or 1 so it does not have extra bits */
+    }
+    desc->max_code = max_code;
+
+    /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
+     * establish sub-heaps of increasing lengths:
+     */
+    for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
+
+    /* Construct the Huffman tree by repeatedly combining the least two
+     * frequent nodes.
+     */
+    node = elems;              /* next internal node of the tree */
+    do {
+        pqremove(s, tree, n);  /* n = node of least frequency */
+        m = s->heap[SMALLEST]; /* m = node of next least frequency */
+
+        s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
+        s->heap[--(s->heap_max)] = m;
+
+        /* Create a new node father of n and m */
+        tree[node].Freq = tree[n].Freq + tree[m].Freq;
+        s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ?
+                                s->depth[n] : s->depth[m]) + 1);
+        tree[n].Dad = tree[m].Dad = (ush)node;
+#ifdef DUMP_BL_TREE
+        if (tree == s->bl_tree) {
+            fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
+                    node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
+        }
+#endif
+        /* and insert the new node in the heap */
+        s->heap[SMALLEST] = node++;
+        pqdownheap(s, tree, SMALLEST);
+
+    } while (s->heap_len >= 2);
+
+    s->heap[--(s->heap_max)] = s->heap[SMALLEST];
+
+    /* At this point, the fields freq and dad are set. We can now
+     * generate the bit lengths.
+     */
+    gen_bitlen(s, (tree_desc *)desc);
+
+    /* The field len is now set, we can generate the bit codes */
+    gen_codes ((ct_data *)tree, max_code, s->bl_count);
+}
+
+/* ===========================================================================
+ * Scan a literal or distance tree to determine the frequencies of the codes
+ * in the bit length tree.
+ */
+local void scan_tree (s, tree, max_code)
+    deflate_state *s;
+    ct_data *tree;   /* the tree to be scanned */
+    int max_code;    /* and its largest code of non zero frequency */
+{
+    int n;                     /* iterates over all tree elements */
+    int prevlen = -1;          /* last emitted length */
+    int curlen;                /* length of current code */
+    int nextlen = tree[0].Len; /* length of next code */
+    int count = 0;             /* repeat count of the current code */
+    int max_count = 7;         /* max repeat count */
+    int min_count = 4;         /* min repeat count */
+
+    if (nextlen == 0) max_count = 138, min_count = 3;
+    tree[max_code+1].Len = (ush)0xffff; /* guard */
+
+    for (n = 0; n <= max_code; n++) {
+        curlen = nextlen; nextlen = tree[n+1].Len;
+        if (++count < max_count && curlen == nextlen) {
+            continue;
+        } else if (count < min_count) {
+            s->bl_tree[curlen].Freq += count;
+        } else if (curlen != 0) {
+            if (curlen != prevlen) s->bl_tree[curlen].Freq++;
+            s->bl_tree[REP_3_6].Freq++;
+        } else if (count <= 10) {
+            s->bl_tree[REPZ_3_10].Freq++;
+        } else {
+            s->bl_tree[REPZ_11_138].Freq++;
+        }
+        count = 0; prevlen = curlen;
+        if (nextlen == 0) {
+            max_count = 138, min_count = 3;
+        } else if (curlen == nextlen) {
+            max_count = 6, min_count = 3;
+        } else {
+            max_count = 7, min_count = 4;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Send a literal or distance tree in compressed form, using the codes in
+ * bl_tree.
+ */
+local void send_tree (s, tree, max_code)
+    deflate_state *s;
+    ct_data *tree; /* the tree to be scanned */
+    int max_code;       /* and its largest code of non zero frequency */
+{
+    int n;                     /* iterates over all tree elements */
+    int prevlen = -1;          /* last emitted length */
+    int curlen;                /* length of current code */
+    int nextlen = tree[0].Len; /* length of next code */
+    int count = 0;             /* repeat count of the current code */
+    int max_count = 7;         /* max repeat count */
+    int min_count = 4;         /* min repeat count */
+
+    /* tree[max_code+1].Len = -1; */  /* guard already set */
+    if (nextlen == 0) max_count = 138, min_count = 3;
+
+    for (n = 0; n <= max_code; n++) {
+        curlen = nextlen; nextlen = tree[n+1].Len;
+        if (++count < max_count && curlen == nextlen) {
+            continue;
+        } else if (count < min_count) {
+            do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
+
+        } else if (curlen != 0) {
+            if (curlen != prevlen) {
+                send_code(s, curlen, s->bl_tree); count--;
+            }
+            Assert(count >= 3 && count <= 6, " 3_6?");
+            send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
+
+        } else if (count <= 10) {
+            send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
+
+        } else {
+            send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
+        }
+        count = 0; prevlen = curlen;
+        if (nextlen == 0) {
+            max_count = 138, min_count = 3;
+        } else if (curlen == nextlen) {
+            max_count = 6, min_count = 3;
+        } else {
+            max_count = 7, min_count = 4;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Construct the Huffman tree for the bit lengths and return the index in
+ * bl_order of the last bit length code to send.
+ */
+local int build_bl_tree(s)
+    deflate_state *s;
+{
+    int max_blindex;  /* index of last bit length code of non zero freq */
+
+    /* Determine the bit length frequencies for literal and distance trees */
+    scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
+    scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
+
+    /* Build the bit length tree: */
+    build_tree(s, (tree_desc *)(&(s->bl_desc)));
+    /* opt_len now includes the length of the tree representations, except
+     * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
+     */
+
+    /* Determine the number of bit length codes to send. The pkzip format
+     * requires that at least 4 bit length codes be sent. (appnote.txt says
+     * 3 but the actual value used is 4.)
+     */
+    for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
+        if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
+    }
+    /* Update opt_len to include the bit length tree and counts */
+    s->opt_len += 3*(max_blindex+1) + 5+5+4;
+    Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
+            s->opt_len, s->static_len));
+
+    return max_blindex;
+}
+
+/* ===========================================================================
+ * Send the header for a block using dynamic Huffman trees: the counts, the
+ * lengths of the bit length codes, the literal tree and the distance tree.
+ * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
+ */
+local void send_all_trees(s, lcodes, dcodes, blcodes)
+    deflate_state *s;
+    int lcodes, dcodes, blcodes; /* number of codes for each tree */
+{
+    int rank;                    /* index in bl_order */
+
+    Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
+    Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
+            "too many codes");
+    Tracev((stderr, "\nbl counts: "));
+    send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
+    send_bits(s, dcodes-1,   5);
+    send_bits(s, blcodes-4,  4); /* not -3 as stated in appnote.txt */
+    for (rank = 0; rank < blcodes; rank++) {
+        Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
+        send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
+    }
+    Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
+
+    send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
+    Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
+
+    send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
+    Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
+}
+
+/* ===========================================================================
+ * Send a stored block
+ */
+void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last)
+    deflate_state *s;
+    charf *buf;       /* input block */
+    ulg stored_len;   /* length of input block */
+    int last;         /* one if this is the last block for a file */
+{
+    send_bits(s, (STORED_BLOCK<<1)+last, 3);    /* send block type */
+#ifdef DEBUG
+    s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
+    s->compressed_len += (stored_len + 4) << 3;
+#endif
+    copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
+}
+
+/* ===========================================================================
+ * Flush the bits in the bit buffer to pending output (leaves at most 7 bits)
+ */
+void ZLIB_INTERNAL _tr_flush_bits(s)
+    deflate_state *s;
+{
+    bi_flush(s);
+}
+
+/* ===========================================================================
+ * Send one empty static block to give enough lookahead for inflate.
+ * This takes 10 bits, of which 7 may remain in the bit buffer.
+ */
+void ZLIB_INTERNAL _tr_align(s)
+    deflate_state *s;
+{
+    send_bits(s, STATIC_TREES<<1, 3);
+    send_code(s, END_BLOCK, static_ltree);
+#ifdef DEBUG
+    s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
+#endif
+    bi_flush(s);
+}
+
+/* ===========================================================================
+ * Determine the best encoding for the current block: dynamic trees, static
+ * trees or store, and output the encoded block to the zip file.
+ */
+void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
+    deflate_state *s;
+    charf *buf;       /* input block, or NULL if too old */
+    ulg stored_len;   /* length of input block */
+    int last;         /* one if this is the last block for a file */
+{
+    ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
+    int max_blindex = 0;  /* index of last bit length code of non zero freq */
+
+    /* Build the Huffman trees unless a stored block is forced */
+    if (s->level > 0) {
+
+        /* Check if the file is binary or text */
+        if (s->strm->data_type == Z_UNKNOWN)
+            s->strm->data_type = detect_data_type(s);
+
+        /* Construct the literal and distance trees */
+        build_tree(s, (tree_desc *)(&(s->l_desc)));
+        Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
+                s->static_len));
+
+        build_tree(s, (tree_desc *)(&(s->d_desc)));
+        Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
+                s->static_len));
+        /* At this point, opt_len and static_len are the total bit lengths of
+         * the compressed block data, excluding the tree representations.
+         */
+
+        /* Build the bit length tree for the above two trees, and get the index
+         * in bl_order of the last bit length code to send.
+         */
+        max_blindex = build_bl_tree(s);
+
+        /* Determine the best encoding. Compute the block lengths in bytes. */
+        opt_lenb = (s->opt_len+3+7)>>3;
+        static_lenb = (s->static_len+3+7)>>3;
+
+        Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
+                opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
+                s->last_lit));
+
+        if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
+
+    } else {
+        Assert(buf != (char*)0, "lost buf");
+        opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
+    }
+
+#ifdef FORCE_STORED
+    if (buf != (char*)0) { /* force stored block */
+#else
+    if (stored_len+4 <= opt_lenb && buf != (char*)0) {
+                       /* 4: two words for the lengths */
+#endif
+        /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
+         * Otherwise we can't have processed more than WSIZE input bytes since
+         * the last block flush, because compression would have been
+         * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
+         * transform a block into a stored block.
+         */
+        _tr_stored_block(s, buf, stored_len, last);
+
+#ifdef FORCE_STATIC
+    } else if (static_lenb >= 0) { /* force static trees */
+#else
+    } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {
+#endif
+        send_bits(s, (STATIC_TREES<<1)+last, 3);
+        compress_block(s, (const ct_data *)static_ltree,
+                       (const ct_data *)static_dtree);
+#ifdef DEBUG
+        s->compressed_len += 3 + s->static_len;
+#endif
+    } else {
+        send_bits(s, (DYN_TREES<<1)+last, 3);
+        send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
+                       max_blindex+1);
+        compress_block(s, (const ct_data *)s->dyn_ltree,
+                       (const ct_data *)s->dyn_dtree);
+#ifdef DEBUG
+        s->compressed_len += 3 + s->opt_len;
+#endif
+    }
+    Assert (s->compressed_len == s->bits_sent, "bad compressed size");
+    /* The above check is made mod 2^32, for files larger than 512 MB
+     * and uLong implemented on 32 bits.
+     */
+    init_block(s);
+
+    if (last) {
+        bi_windup(s);
+#ifdef DEBUG
+        s->compressed_len += 7;  /* align on byte boundary */
+#endif
+    }
+    Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
+           s->compressed_len-7*last));
+}
+
+/* ===========================================================================
+ * Save the match info and tally the frequency counts. Return true if
+ * the current block must be flushed.
+ */
+int ZLIB_INTERNAL _tr_tally (s, dist, lc)
+    deflate_state *s;
+    unsigned dist;  /* distance of matched string */
+    unsigned lc;    /* match length-MIN_MATCH or unmatched char (if dist==0) */
+{
+    s->d_buf[s->last_lit] = (ush)dist;
+    s->l_buf[s->last_lit++] = (uch)lc;
+    if (dist == 0) {
+        /* lc is the unmatched char */
+        s->dyn_ltree[lc].Freq++;
+    } else {
+        s->matches++;
+        /* Here, lc is the match length - MIN_MATCH */
+        dist--;             /* dist = match distance - 1 */
+        Assert((ush)dist < (ush)MAX_DIST(s) &&
+               (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
+               (ush)d_code(dist) < (ush)D_CODES,  "_tr_tally: bad match");
+
+        s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
+        s->dyn_dtree[d_code(dist)].Freq++;
+    }
+
+#ifdef TRUNCATE_BLOCK
+    /* Try to guess if it is profitable to stop the current block here */
+    if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
+        /* Compute an upper bound for the compressed length */
+        ulg out_length = (ulg)s->last_lit*8L;
+        ulg in_length = (ulg)((long)s->strstart - s->block_start);
+        int dcode;
+        for (dcode = 0; dcode < D_CODES; dcode++) {
+            out_length += (ulg)s->dyn_dtree[dcode].Freq *
+                (5L+extra_dbits[dcode]);
+        }
+        out_length >>= 3;
+        Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
+               s->last_lit, in_length, out_length,
+               100L - out_length*100L/in_length));
+        if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
+    }
+#endif
+    return (s->last_lit == s->lit_bufsize-1);
+    /* We avoid equality with lit_bufsize because of wraparound at 64K
+     * on 16 bit machines and because stored blocks are restricted to
+     * 64K-1 bytes.
+     */
+}
+
+/* ===========================================================================
+ * Send the block data compressed using the given Huffman trees
+ */
+local void compress_block(s, ltree, dtree)
+    deflate_state *s;
+    const ct_data *ltree; /* literal tree */
+    const ct_data *dtree; /* distance tree */
+{
+    unsigned dist;      /* distance of matched string */
+    int lc;             /* match length or unmatched char (if dist == 0) */
+    unsigned lx = 0;    /* running index in l_buf */
+    unsigned code;      /* the code to send */
+    int extra;          /* number of extra bits to send */
+
+    if (s->last_lit != 0) do {
+        dist = s->d_buf[lx];
+        lc = s->l_buf[lx++];
+        if (dist == 0) {
+            send_code(s, lc, ltree); /* send a literal byte */
+            Tracecv(isgraph(lc), (stderr," '%c' ", lc));
+        } else {
+            /* Here, lc is the match length - MIN_MATCH */
+            code = _length_code[lc];
+            send_code(s, code+LITERALS+1, ltree); /* send the length code */
+            extra = extra_lbits[code];
+            if (extra != 0) {
+                lc -= base_length[code];
+                send_bits(s, lc, extra);       /* send the extra length bits */
+            }
+            dist--; /* dist is now the match distance - 1 */
+            code = d_code(dist);
+            Assert (code < D_CODES, "bad d_code");
+
+            send_code(s, code, dtree);       /* send the distance code */
+            extra = extra_dbits[code];
+            if (extra != 0) {
+                dist -= base_dist[code];
+                send_bits(s, dist, extra);   /* send the extra distance bits */
+            }
+        } /* literal or match pair ? */
+
+        /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
+        Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
+               "pendingBuf overflow");
+
+    } while (lx < s->last_lit);
+
+    send_code(s, END_BLOCK, ltree);
+}
+
+/* ===========================================================================
+ * Check if the data type is TEXT or BINARY, using the following algorithm:
+ * - TEXT if the two conditions below are satisfied:
+ *    a) There are no non-portable control characters belonging to the
+ *       "black list" (0..6, 14..25, 28..31).
+ *    b) There is at least one printable character belonging to the
+ *       "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255).
+ * - BINARY otherwise.
+ * - The following partially-portable control characters form a
+ *   "gray list" that is ignored in this detection algorithm:
+ *   (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}).
+ * IN assertion: the fields Freq of dyn_ltree are set.
+ */
+local int detect_data_type(s)
+    deflate_state *s;
+{
+    /* black_mask is the bit mask of black-listed bytes
+     * set bits 0..6, 14..25, and 28..31
+     * 0xf3ffc07f = binary 11110011111111111100000001111111
+     */
+    unsigned long black_mask = 0xf3ffc07fUL;
+    int n;
+
+    /* Check for non-textual ("black-listed") bytes. */
+    for (n = 0; n <= 31; n++, black_mask >>= 1)
+        if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0))
+            return Z_BINARY;
+
+    /* Check for textual ("white-listed") bytes. */
+    if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0
+            || s->dyn_ltree[13].Freq != 0)
+        return Z_TEXT;
+    for (n = 32; n < LITERALS; n++)
+        if (s->dyn_ltree[n].Freq != 0)
+            return Z_TEXT;
+
+    /* There are no "black-listed" or "white-listed" bytes:
+     * this stream either is empty or has tolerated ("gray-listed") bytes only.
+     */
+    return Z_BINARY;
+}
+
+/* ===========================================================================
+ * Reverse the first len bits of a code, using straightforward code (a faster
+ * method would use a table)
+ * IN assertion: 1 <= len <= 15
+ */
+local unsigned bi_reverse(code, len)
+    unsigned code; /* the value to invert */
+    int len;       /* its bit length */
+{
+    register unsigned res = 0;
+    do {
+        res |= code & 1;
+        code >>= 1, res <<= 1;
+    } while (--len > 0);
+    return res >> 1;
+}
+
+/* ===========================================================================
+ * Flush the bit buffer, keeping at most 7 bits in it.
+ */
+local void bi_flush(s)
+    deflate_state *s;
+{
+    if (s->bi_valid == 16) {
+        put_short(s, s->bi_buf);
+        s->bi_buf = 0;
+        s->bi_valid = 0;
+    } else if (s->bi_valid >= 8) {
+        put_byte(s, (Byte)s->bi_buf);
+        s->bi_buf >>= 8;
+        s->bi_valid -= 8;
+    }
+}
+
+/* ===========================================================================
+ * Flush the bit buffer and align the output on a byte boundary
+ */
+local void bi_windup(s)
+    deflate_state *s;
+{
+    if (s->bi_valid > 8) {
+        put_short(s, s->bi_buf);
+    } else if (s->bi_valid > 0) {
+        put_byte(s, (Byte)s->bi_buf);
+    }
+    s->bi_buf = 0;
+    s->bi_valid = 0;
+#ifdef DEBUG
+    s->bits_sent = (s->bits_sent+7) & ~7;
+#endif
+}
+
+/* ===========================================================================
+ * Copy a stored block, storing first the length and its
+ * one's complement if requested.
+ */
+local void copy_block(s, buf, len, header)
+    deflate_state *s;
+    charf    *buf;    /* the input data */
+    unsigned len;     /* its length */
+    int      header;  /* true if block header must be written */
+{
+    bi_windup(s);        /* align on byte boundary */
+
+    if (header) {
+        put_short(s, (ush)len);
+        put_short(s, (ush)~len);
+#ifdef DEBUG
+        s->bits_sent += 2*16;
+#endif
+    }
+#ifdef DEBUG
+    s->bits_sent += (ulg)len<<3;
+#endif
+    while (len--) {
+        put_byte(s, *buf++);
+    }
+}
diff --git a/Source/ZLib/uncompr.c b/Source/ZLib/uncompr.c
index cfee71d..27a5ee5 100644
--- a/Source/ZLib/uncompr.c
+++ b/Source/ZLib/uncompr.c
@@ -1,59 +1,59 @@
-/* uncompr.c -- decompress a memory buffer
- * Copyright (C) 1995-2003, 2010 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id: uncompr.c,v 1.9 2012/05/13 12:18:39 drolon Exp $ */
-
-#define ZLIB_INTERNAL
-#include "zlib.h"
-
-/* ===========================================================================
-     Decompresses the source buffer into the destination buffer.  sourceLen is
-   the byte length of the source buffer. Upon entry, destLen is the total
-   size of the destination buffer, which must be large enough to hold the
-   entire uncompressed data. (The size of the uncompressed data must have
-   been saved previously by the compressor and transmitted to the decompressor
-   by some mechanism outside the scope of this compression library.)
-   Upon exit, destLen is the actual size of the compressed buffer.
-
-     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
-   enough memory, Z_BUF_ERROR if there was not enough room in the output
-   buffer, or Z_DATA_ERROR if the input data was corrupted.
-*/
-int ZEXPORT uncompress (dest, destLen, source, sourceLen)
-    Bytef *dest;
-    uLongf *destLen;
-    const Bytef *source;
-    uLong sourceLen;
-{
-    z_stream stream;
-    int err;
-
-    stream.next_in = (Bytef*)source;
-    stream.avail_in = (uInt)sourceLen;
-    /* Check for source > 64K on 16-bit machine: */
-    if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
-
-    stream.next_out = dest;
-    stream.avail_out = (uInt)*destLen;
-    if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
-
-    stream.zalloc = (alloc_func)0;
-    stream.zfree = (free_func)0;
-
-    err = inflateInit(&stream);
-    if (err != Z_OK) return err;
-
-    err = inflate(&stream, Z_FINISH);
-    if (err != Z_STREAM_END) {
-        inflateEnd(&stream);
-        if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))
-            return Z_DATA_ERROR;
-        return err;
-    }
-    *destLen = stream.total_out;
-
-    err = inflateEnd(&stream);
-    return err;
-}
+/* uncompr.c -- decompress a memory buffer
+ * Copyright (C) 1995-2003, 2010 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id: uncompr.c,v 1.10 2013/05/10 17:22:52 drolon Exp $ */
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+/* ===========================================================================
+     Decompresses the source buffer into the destination buffer.  sourceLen is
+   the byte length of the source buffer. Upon entry, destLen is the total
+   size of the destination buffer, which must be large enough to hold the
+   entire uncompressed data. (The size of the uncompressed data must have
+   been saved previously by the compressor and transmitted to the decompressor
+   by some mechanism outside the scope of this compression library.)
+   Upon exit, destLen is the actual size of the compressed buffer.
+
+     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_BUF_ERROR if there was not enough room in the output
+   buffer, or Z_DATA_ERROR if the input data was corrupted.
+*/
+int ZEXPORT uncompress (dest, destLen, source, sourceLen)
+    Bytef *dest;
+    uLongf *destLen;
+    const Bytef *source;
+    uLong sourceLen;
+{
+    z_stream stream;
+    int err;
+
+    stream.next_in = (z_const Bytef *)source;
+    stream.avail_in = (uInt)sourceLen;
+    /* Check for source > 64K on 16-bit machine: */
+    if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
+
+    stream.next_out = dest;
+    stream.avail_out = (uInt)*destLen;
+    if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+
+    stream.zalloc = (alloc_func)0;
+    stream.zfree = (free_func)0;
+
+    err = inflateInit(&stream);
+    if (err != Z_OK) return err;
+
+    err = inflate(&stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        inflateEnd(&stream);
+        if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))
+            return Z_DATA_ERROR;
+        return err;
+    }
+    *destLen = stream.total_out;
+
+    err = inflateEnd(&stream);
+    return err;
+}
diff --git a/Source/ZLib/zconf.h b/Source/ZLib/zconf.h
index 54b82a3..b021a60 100644
--- a/Source/ZLib/zconf.h
+++ b/Source/ZLib/zconf.h
@@ -1,506 +1,511 @@
-/* zconf.h -- configuration of the zlib compression library
- * Copyright (C) 1995-2012 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id: zconf.h,v 1.9 2012/05/13 12:18:39 drolon Exp $ */
-
-#ifndef ZCONF_H
-#define ZCONF_H
-
-/*
- * If you *really* need a unique prefix for all types and library functions,
- * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
- * Even better than compiling with -DZ_PREFIX would be to use configure to set
- * this permanently in zconf.h using "./configure --zprefix".
- */
-#ifdef Z_PREFIX     /* may be set to #if 1 by ./configure */
-#  define Z_PREFIX_SET
-
-/* all linked symbols */
-#  define _dist_code            z__dist_code
-#  define _length_code          z__length_code
-#  define _tr_align             z__tr_align
-#  define _tr_flush_block       z__tr_flush_block
-#  define _tr_init              z__tr_init
-#  define _tr_stored_block      z__tr_stored_block
-#  define _tr_tally             z__tr_tally
-#  define adler32               z_adler32
-#  define adler32_combine       z_adler32_combine
-#  define adler32_combine64     z_adler32_combine64
-#  ifndef Z_SOLO
-#    define compress              z_compress
-#    define compress2             z_compress2
-#    define compressBound         z_compressBound
-#  endif
-#  define crc32                 z_crc32
-#  define crc32_combine         z_crc32_combine
-#  define crc32_combine64       z_crc32_combine64
-#  define deflate               z_deflate
-#  define deflateBound          z_deflateBound
-#  define deflateCopy           z_deflateCopy
-#  define deflateEnd            z_deflateEnd
-#  define deflateInit2_         z_deflateInit2_
-#  define deflateInit_          z_deflateInit_
-#  define deflateParams         z_deflateParams
-#  define deflatePending        z_deflatePending
-#  define deflatePrime          z_deflatePrime
-#  define deflateReset          z_deflateReset
-#  define deflateResetKeep      z_deflateResetKeep
-#  define deflateSetDictionary  z_deflateSetDictionary
-#  define deflateSetHeader      z_deflateSetHeader
-#  define deflateTune           z_deflateTune
-#  define deflate_copyright     z_deflate_copyright
-#  define get_crc_table         z_get_crc_table
-#  ifndef Z_SOLO
-#    define gz_error              z_gz_error
-#    define gz_intmax             z_gz_intmax
-#    define gz_strwinerror        z_gz_strwinerror
-#    define gzbuffer              z_gzbuffer
-#    define gzclearerr            z_gzclearerr
-#    define gzclose               z_gzclose
-#    define gzclose_r             z_gzclose_r
-#    define gzclose_w             z_gzclose_w
-#    define gzdirect              z_gzdirect
-#    define gzdopen               z_gzdopen
-#    define gzeof                 z_gzeof
-#    define gzerror               z_gzerror
-#    define gzflush               z_gzflush
-#    define gzgetc                z_gzgetc
-#    define gzgetc_               z_gzgetc_
-#    define gzgets                z_gzgets
-#    define gzoffset              z_gzoffset
-#    define gzoffset64            z_gzoffset64
-#    define gzopen                z_gzopen
-#    define gzopen64              z_gzopen64
-#    ifdef _WIN32
-#      define gzopen_w              z_gzopen_w
-#    endif
-#    define gzprintf              z_gzprintf
-#    define gzputc                z_gzputc
-#    define gzputs                z_gzputs
-#    define gzread                z_gzread
-#    define gzrewind              z_gzrewind
-#    define gzseek                z_gzseek
-#    define gzseek64              z_gzseek64
-#    define gzsetparams           z_gzsetparams
-#    define gztell                z_gztell
-#    define gztell64              z_gztell64
-#    define gzungetc              z_gzungetc
-#    define gzwrite               z_gzwrite
-#  endif
-#  define inflate               z_inflate
-#  define inflateBack           z_inflateBack
-#  define inflateBackEnd        z_inflateBackEnd
-#  define inflateBackInit_      z_inflateBackInit_
-#  define inflateCopy           z_inflateCopy
-#  define inflateEnd            z_inflateEnd
-#  define inflateGetHeader      z_inflateGetHeader
-#  define inflateInit2_         z_inflateInit2_
-#  define inflateInit_          z_inflateInit_
-#  define inflateMark           z_inflateMark
-#  define inflatePrime          z_inflatePrime
-#  define inflateReset          z_inflateReset
-#  define inflateReset2         z_inflateReset2
-#  define inflateSetDictionary  z_inflateSetDictionary
-#  define inflateSync           z_inflateSync
-#  define inflateSyncPoint      z_inflateSyncPoint
-#  define inflateUndermine      z_inflateUndermine
-#  define inflateResetKeep      z_inflateResetKeep
-#  define inflate_copyright     z_inflate_copyright
-#  define inflate_fast          z_inflate_fast
-#  define inflate_table         z_inflate_table
-#  ifndef Z_SOLO
-#    define uncompress            z_uncompress
-#  endif
-#  define zError                z_zError
-#  ifndef Z_SOLO
-#    define zcalloc               z_zcalloc
-#    define zcfree                z_zcfree
-#  endif
-#  define zlibCompileFlags      z_zlibCompileFlags
-#  define zlibVersion           z_zlibVersion
-
-/* all zlib typedefs in zlib.h and zconf.h */
-#  define Byte                  z_Byte
-#  define Bytef                 z_Bytef
-#  define alloc_func            z_alloc_func
-#  define charf                 z_charf
-#  define free_func             z_free_func
-#  ifndef Z_SOLO
-#    define gzFile                z_gzFile
-#  endif
-#  define gz_header             z_gz_header
-#  define gz_headerp            z_gz_headerp
-#  define in_func               z_in_func
-#  define intf                  z_intf
-#  define out_func              z_out_func
-#  define uInt                  z_uInt
-#  define uIntf                 z_uIntf
-#  define uLong                 z_uLong
-#  define uLongf                z_uLongf
-#  define voidp                 z_voidp
-#  define voidpc                z_voidpc
-#  define voidpf                z_voidpf
-
-/* all zlib structs in zlib.h and zconf.h */
-#  define gz_header_s           z_gz_header_s
-#  define internal_state        z_internal_state
-
-#endif
-
-#if defined(__MSDOS__) && !defined(MSDOS)
-#  define MSDOS
-#endif
-#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
-#  define OS2
-#endif
-#if defined(_WINDOWS) && !defined(WINDOWS)
-#  define WINDOWS
-#endif
-#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
-#  ifndef WIN32
-#    define WIN32
-#  endif
-#endif
-#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
-#  if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
-#    ifndef SYS16BIT
-#      define SYS16BIT
-#    endif
-#  endif
-#endif
-
-/*
- * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
- * than 64k bytes at a time (needed on systems with 16-bit int).
- */
-#ifdef SYS16BIT
-#  define MAXSEG_64K
-#endif
-#ifdef MSDOS
-#  define UNALIGNED_OK
-#endif
-
-#ifdef __STDC_VERSION__
-#  ifndef STDC
-#    define STDC
-#  endif
-#  if __STDC_VERSION__ >= 199901L
-#    ifndef STDC99
-#      define STDC99
-#    endif
-#  endif
-#endif
-#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
-#  define STDC
-#endif
-#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
-#  define STDC
-#endif
-#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
-#  define STDC
-#endif
-#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
-#  define STDC
-#endif
-
-#if defined(__OS400__) && !defined(STDC)    /* iSeries (formerly AS/400). */
-#  define STDC
-#endif
-
-#ifndef STDC
-#  ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
-#    define const       /* note: need a more gentle solution here */
-#  endif
-#endif
-
-#if defined(ZLIB_CONST) && !defined(z_const)
-#  define z_const const
-#else
-#  define z_const
-#endif
-
-/* Some Mac compilers merge all .h files incorrectly: */
-#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
-#  define NO_DUMMY_DECL
-#endif
-
-/* Maximum value for memLevel in deflateInit2 */
-#ifndef MAX_MEM_LEVEL
-#  ifdef MAXSEG_64K
-#    define MAX_MEM_LEVEL 8
-#  else
-#    define MAX_MEM_LEVEL 9
-#  endif
-#endif
-
-/* Maximum value for windowBits in deflateInit2 and inflateInit2.
- * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
- * created by gzip. (Files created by minigzip can still be extracted by
- * gzip.)
- */
-#ifndef MAX_WBITS
-#  define MAX_WBITS   15 /* 32K LZ77 window */
-#endif
-
-/* The memory requirements for deflate are (in bytes):
-            (1 << (windowBits+2)) +  (1 << (memLevel+9))
- that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
- plus a few kilobytes for small objects. For example, if you want to reduce
- the default memory requirements from 256K to 128K, compile with
-     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
- Of course this will generally degrade compression (there's no free lunch).
-
-   The memory requirements for inflate are (in bytes) 1 << windowBits
- that is, 32K for windowBits=15 (default value) plus a few kilobytes
- for small objects.
-*/
-
-                        /* Type declarations */
-
-#ifndef OF /* function prototypes */
-#  ifdef STDC
-#    define OF(args)  args
-#  else
-#    define OF(args)  ()
-#  endif
-#endif
-
-#ifndef Z_ARG /* function prototypes for stdarg */
-#  if defined(STDC) || defined(Z_HAVE_STDARG_H)
-#    define Z_ARG(args)  args
-#  else
-#    define Z_ARG(args)  ()
-#  endif
-#endif
-
-/* The following definitions for FAR are needed only for MSDOS mixed
- * model programming (small or medium model with some far allocations).
- * This was tested only with MSC; for other MSDOS compilers you may have
- * to define NO_MEMCPY in zutil.h.  If you don't need the mixed model,
- * just define FAR to be empty.
- */
-#ifdef SYS16BIT
-#  if defined(M_I86SM) || defined(M_I86MM)
-     /* MSC small or medium model */
-#    define SMALL_MEDIUM
-#    ifdef _MSC_VER
-#      define FAR _far
-#    else
-#      define FAR far
-#    endif
-#  endif
-#  if (defined(__SMALL__) || defined(__MEDIUM__))
-     /* Turbo C small or medium model */
-#    define SMALL_MEDIUM
-#    ifdef __BORLANDC__
-#      define FAR _far
-#    else
-#      define FAR far
-#    endif
-#  endif
-#endif
-
-#if defined(WINDOWS) || defined(WIN32)
-   /* If building or using zlib as a DLL, define ZLIB_DLL.
-    * This is not mandatory, but it offers a little performance increase.
-    */
-#  ifdef ZLIB_DLL
-#    if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
-#      ifdef ZLIB_INTERNAL
-#        define ZEXTERN extern __declspec(dllexport)
-#      else
-#        define ZEXTERN extern __declspec(dllimport)
-#      endif
-#    endif
-#  endif  /* ZLIB_DLL */
-   /* If building or using zlib with the WINAPI/WINAPIV calling convention,
-    * define ZLIB_WINAPI.
-    * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
-    */
-#  ifdef ZLIB_WINAPI
-#    ifdef FAR
-#      undef FAR
-#    endif
-#    include <windows.h>
-     /* No need for _export, use ZLIB.DEF instead. */
-     /* For complete Windows compatibility, use WINAPI, not __stdcall. */
-#    define ZEXPORT WINAPI
-#    ifdef WIN32
-#      define ZEXPORTVA WINAPIV
-#    else
-#      define ZEXPORTVA FAR CDECL
-#    endif
-#  endif
-#endif
-
-#if defined (__BEOS__)
-#  ifdef ZLIB_DLL
-#    ifdef ZLIB_INTERNAL
-#      define ZEXPORT   __declspec(dllexport)
-#      define ZEXPORTVA __declspec(dllexport)
-#    else
-#      define ZEXPORT   __declspec(dllimport)
-#      define ZEXPORTVA __declspec(dllimport)
-#    endif
-#  endif
-#endif
-
-#ifndef ZEXTERN
-#  define ZEXTERN extern
-#endif
-#ifndef ZEXPORT
-#  define ZEXPORT
-#endif
-#ifndef ZEXPORTVA
-#  define ZEXPORTVA
-#endif
-
-#ifndef FAR
-#  define FAR
-#endif
-
-#if !defined(__MACTYPES__)
-typedef unsigned char  Byte;  /* 8 bits */
-#endif
-typedef unsigned int   uInt;  /* 16 bits or more */
-typedef unsigned long  uLong; /* 32 bits or more */
-
-#ifdef SMALL_MEDIUM
-   /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
-#  define Bytef Byte FAR
-#else
-   typedef Byte  FAR Bytef;
-#endif
-typedef char  FAR charf;
-typedef int   FAR intf;
-typedef uInt  FAR uIntf;
-typedef uLong FAR uLongf;
-
-#ifdef STDC
-   typedef void const *voidpc;
-   typedef void FAR   *voidpf;
-   typedef void       *voidp;
-#else
-   typedef Byte const *voidpc;
-   typedef Byte FAR   *voidpf;
-   typedef Byte       *voidp;
-#endif
-
-/* ./configure may #define Z_U4 here */
-
-#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)
-#  include <limits.h>
-#  if (UINT_MAX == 0xffffffffUL)
-#    define Z_U4 unsigned
-#  else
-#    if (ULONG_MAX == 0xffffffffUL)
-#      define Z_U4 unsigned long
-#    else
-#      if (USHRT_MAX == 0xffffffffUL)
-#        define Z_U4 unsigned short
-#      endif
-#    endif
-#  endif
-#endif
-
-#ifdef Z_U4
-   typedef Z_U4 z_crc_t;
-#else
-   typedef unsigned long z_crc_t;
-#endif
-
-#ifdef HAVE_UNISTD_H    /* may be set to #if 1 by ./configure */
-#  define Z_HAVE_UNISTD_H
-#endif
-
-#ifdef HAVE_STDARG_H    /* may be set to #if 1 by ./configure */
-#  define Z_HAVE_STDARG_H
-#endif
-
-#ifdef STDC
-#  ifndef Z_SOLO
-#    include <sys/types.h>      /* for off_t */
-#  endif
-#endif
-
-#ifdef _WIN32
-#  include <stddef.h>           /* for wchar_t */
-#endif
-
-/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
- * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
- * though the former does not conform to the LFS document), but considering
- * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
- * equivalently requesting no 64-bit operations
- */
-#if defined(LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
-#  undef _LARGEFILE64_SOURCE
-#endif
-
-#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
-#  define Z_HAVE_UNISTD_H
-#endif
-#ifndef Z_SOLO
-#  if defined(Z_HAVE_UNISTD_H) || defined(LARGEFILE64_SOURCE)
-#    include <unistd.h>         /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
-#    ifdef VMS
-#      include <unixio.h>       /* for off_t */
-#    endif
-#    ifndef z_off_t
-#      define z_off_t off_t
-#    endif
-#  endif
-#endif
-
-#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0
-#  define Z_LFS64
-#endif
-
-#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)
-#  define Z_LARGE64
-#endif
-
-#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)
-#  define Z_WANT64
-#endif
-
-#if !defined(SEEK_SET) && !defined(Z_SOLO)
-#  define SEEK_SET        0       /* Seek from beginning of file.  */
-#  define SEEK_CUR        1       /* Seek from current position.  */
-#  define SEEK_END        2       /* Set file pointer to EOF plus "offset" */
-#endif
-
-#ifndef z_off_t
-#  define z_off_t long
-#endif
-
-#if !defined(_WIN32) && defined(Z_LARGE64)
-#  define z_off64_t off64_t
-#else
-#  if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
-#    define z_off64_t __int64
-#  else
-#    define z_off64_t z_off_t
-#  endif
-#endif
-
-/* MVS linker does not support external names larger than 8 bytes */
-#if defined(__MVS__)
-  #pragma map(deflateInit_,"DEIN")
-  #pragma map(deflateInit2_,"DEIN2")
-  #pragma map(deflateEnd,"DEEND")
-  #pragma map(deflateBound,"DEBND")
-  #pragma map(inflateInit_,"ININ")
-  #pragma map(inflateInit2_,"ININ2")
-  #pragma map(inflateEnd,"INEND")
-  #pragma map(inflateSync,"INSY")
-  #pragma map(inflateSetDictionary,"INSEDI")
-  #pragma map(compressBound,"CMBND")
-  #pragma map(inflate_table,"INTABL")
-  #pragma map(inflate_fast,"INFA")
-  #pragma map(inflate_copyright,"INCOPY")
-#endif
-
-#endif /* ZCONF_H */
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2013 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id: zconf.h,v 1.10 2013/05/10 17:22:52 drolon Exp $ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ * Even better than compiling with -DZ_PREFIX would be to use configure to set
+ * this permanently in zconf.h using "./configure --zprefix".
+ */
+#ifdef Z_PREFIX     /* may be set to #if 1 by ./configure */
+#  define Z_PREFIX_SET
+
+/* all linked symbols */
+#  define _dist_code            z__dist_code
+#  define _length_code          z__length_code
+#  define _tr_align             z__tr_align
+#  define _tr_flush_bits        z__tr_flush_bits
+#  define _tr_flush_block       z__tr_flush_block
+#  define _tr_init              z__tr_init
+#  define _tr_stored_block      z__tr_stored_block
+#  define _tr_tally             z__tr_tally
+#  define adler32               z_adler32
+#  define adler32_combine       z_adler32_combine
+#  define adler32_combine64     z_adler32_combine64
+#  ifndef Z_SOLO
+#    define compress              z_compress
+#    define compress2             z_compress2
+#    define compressBound         z_compressBound
+#  endif
+#  define crc32                 z_crc32
+#  define crc32_combine         z_crc32_combine
+#  define crc32_combine64       z_crc32_combine64
+#  define deflate               z_deflate
+#  define deflateBound          z_deflateBound
+#  define deflateCopy           z_deflateCopy
+#  define deflateEnd            z_deflateEnd
+#  define deflateInit2_         z_deflateInit2_
+#  define deflateInit_          z_deflateInit_
+#  define deflateParams         z_deflateParams
+#  define deflatePending        z_deflatePending
+#  define deflatePrime          z_deflatePrime
+#  define deflateReset          z_deflateReset
+#  define deflateResetKeep      z_deflateResetKeep
+#  define deflateSetDictionary  z_deflateSetDictionary
+#  define deflateSetHeader      z_deflateSetHeader
+#  define deflateTune           z_deflateTune
+#  define deflate_copyright     z_deflate_copyright
+#  define get_crc_table         z_get_crc_table
+#  ifndef Z_SOLO
+#    define gz_error              z_gz_error
+#    define gz_intmax             z_gz_intmax
+#    define gz_strwinerror        z_gz_strwinerror
+#    define gzbuffer              z_gzbuffer
+#    define gzclearerr            z_gzclearerr
+#    define gzclose               z_gzclose
+#    define gzclose_r             z_gzclose_r
+#    define gzclose_w             z_gzclose_w
+#    define gzdirect              z_gzdirect
+#    define gzdopen               z_gzdopen
+#    define gzeof                 z_gzeof
+#    define gzerror               z_gzerror
+#    define gzflush               z_gzflush
+#    define gzgetc                z_gzgetc
+#    define gzgetc_               z_gzgetc_
+#    define gzgets                z_gzgets
+#    define gzoffset              z_gzoffset
+#    define gzoffset64            z_gzoffset64
+#    define gzopen                z_gzopen
+#    define gzopen64              z_gzopen64
+#    ifdef _WIN32
+#      define gzopen_w              z_gzopen_w
+#    endif
+#    define gzprintf              z_gzprintf
+#    define gzvprintf             z_gzvprintf
+#    define gzputc                z_gzputc
+#    define gzputs                z_gzputs
+#    define gzread                z_gzread
+#    define gzrewind              z_gzrewind
+#    define gzseek                z_gzseek
+#    define gzseek64              z_gzseek64
+#    define gzsetparams           z_gzsetparams
+#    define gztell                z_gztell
+#    define gztell64              z_gztell64
+#    define gzungetc              z_gzungetc
+#    define gzwrite               z_gzwrite
+#  endif
+#  define inflate               z_inflate
+#  define inflateBack           z_inflateBack
+#  define inflateBackEnd        z_inflateBackEnd
+#  define inflateBackInit_      z_inflateBackInit_
+#  define inflateCopy           z_inflateCopy
+#  define inflateEnd            z_inflateEnd
+#  define inflateGetHeader      z_inflateGetHeader
+#  define inflateInit2_         z_inflateInit2_
+#  define inflateInit_          z_inflateInit_
+#  define inflateMark           z_inflateMark
+#  define inflatePrime          z_inflatePrime
+#  define inflateReset          z_inflateReset
+#  define inflateReset2         z_inflateReset2
+#  define inflateSetDictionary  z_inflateSetDictionary
+#  define inflateGetDictionary  z_inflateGetDictionary
+#  define inflateSync           z_inflateSync
+#  define inflateSyncPoint      z_inflateSyncPoint
+#  define inflateUndermine      z_inflateUndermine
+#  define inflateResetKeep      z_inflateResetKeep
+#  define inflate_copyright     z_inflate_copyright
+#  define inflate_fast          z_inflate_fast
+#  define inflate_table         z_inflate_table
+#  ifndef Z_SOLO
+#    define uncompress            z_uncompress
+#  endif
+#  define zError                z_zError
+#  ifndef Z_SOLO
+#    define zcalloc               z_zcalloc
+#    define zcfree                z_zcfree
+#  endif
+#  define zlibCompileFlags      z_zlibCompileFlags
+#  define zlibVersion           z_zlibVersion
+
+/* all zlib typedefs in zlib.h and zconf.h */
+#  define Byte                  z_Byte
+#  define Bytef                 z_Bytef
+#  define alloc_func            z_alloc_func
+#  define charf                 z_charf
+#  define free_func             z_free_func
+#  ifndef Z_SOLO
+#    define gzFile                z_gzFile
+#  endif
+#  define gz_header             z_gz_header
+#  define gz_headerp            z_gz_headerp
+#  define in_func               z_in_func
+#  define intf                  z_intf
+#  define out_func              z_out_func
+#  define uInt                  z_uInt
+#  define uIntf                 z_uIntf
+#  define uLong                 z_uLong
+#  define uLongf                z_uLongf
+#  define voidp                 z_voidp
+#  define voidpc                z_voidpc
+#  define voidpf                z_voidpf
+
+/* all zlib structs in zlib.h and zconf.h */
+#  define gz_header_s           z_gz_header_s
+#  define internal_state        z_internal_state
+
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+#  define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+#  define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+#  define WINDOWS
+#endif
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+#  ifndef WIN32
+#    define WIN32
+#  endif
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+#  if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+#    ifndef SYS16BIT
+#      define SYS16BIT
+#    endif
+#  endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+#  define MAXSEG_64K
+#endif
+#ifdef MSDOS
+#  define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+#  ifndef STDC
+#    define STDC
+#  endif
+#  if __STDC_VERSION__ >= 199901L
+#    ifndef STDC99
+#      define STDC99
+#    endif
+#  endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+#  define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC)    /* iSeries (formerly AS/400). */
+#  define STDC
+#endif
+
+#ifndef STDC
+#  ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+#    define const       /* note: need a more gentle solution here */
+#  endif
+#endif
+
+#if defined(ZLIB_CONST) && !defined(z_const)
+#  define z_const const
+#else
+#  define z_const
+#endif
+
+/* Some Mac compilers merge all .h files incorrectly: */
+#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
+#  define NO_DUMMY_DECL
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+#  ifdef MAXSEG_64K
+#    define MAX_MEM_LEVEL 8
+#  else
+#    define MAX_MEM_LEVEL 9
+#  endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+#  define MAX_WBITS   15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+            (1 << (windowBits+2)) +  (1 << (memLevel+9))
+ that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+   The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+                        /* Type declarations */
+
+#ifndef OF /* function prototypes */
+#  ifdef STDC
+#    define OF(args)  args
+#  else
+#    define OF(args)  ()
+#  endif
+#endif
+
+#ifndef Z_ARG /* function prototypes for stdarg */
+#  if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#    define Z_ARG(args)  args
+#  else
+#    define Z_ARG(args)  ()
+#  endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h.  If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+#  if defined(M_I86SM) || defined(M_I86MM)
+     /* MSC small or medium model */
+#    define SMALL_MEDIUM
+#    ifdef _MSC_VER
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
+#  endif
+#  if (defined(__SMALL__) || defined(__MEDIUM__))
+     /* Turbo C small or medium model */
+#    define SMALL_MEDIUM
+#    ifdef __BORLANDC__
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
+#  endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+   /* If building or using zlib as a DLL, define ZLIB_DLL.
+    * This is not mandatory, but it offers a little performance increase.
+    */
+#  ifdef ZLIB_DLL
+#    if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+#      ifdef ZLIB_INTERNAL
+#        define ZEXTERN extern __declspec(dllexport)
+#      else
+#        define ZEXTERN extern __declspec(dllimport)
+#      endif
+#    endif
+#  endif  /* ZLIB_DLL */
+   /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+    * define ZLIB_WINAPI.
+    * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+    */
+#  ifdef ZLIB_WINAPI
+#    ifdef FAR
+#      undef FAR
+#    endif
+#    include <windows.h>
+     /* No need for _export, use ZLIB.DEF instead. */
+     /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+#    define ZEXPORT WINAPI
+#    ifdef WIN32
+#      define ZEXPORTVA WINAPIV
+#    else
+#      define ZEXPORTVA FAR CDECL
+#    endif
+#  endif
+#endif
+
+#if defined (__BEOS__)
+#  ifdef ZLIB_DLL
+#    ifdef ZLIB_INTERNAL
+#      define ZEXPORT   __declspec(dllexport)
+#      define ZEXPORTVA __declspec(dllexport)
+#    else
+#      define ZEXPORT   __declspec(dllimport)
+#      define ZEXPORTVA __declspec(dllimport)
+#    endif
+#  endif
+#endif
+
+#ifndef ZEXTERN
+#  define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+#  define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+#  define ZEXPORTVA
+#endif
+
+#ifndef FAR
+#  define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char  Byte;  /* 8 bits */
+#endif
+typedef unsigned int   uInt;  /* 16 bits or more */
+typedef unsigned long  uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+   /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+#  define Bytef Byte FAR
+#else
+   typedef Byte  FAR Bytef;
+#endif
+typedef char  FAR charf;
+typedef int   FAR intf;
+typedef uInt  FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+   typedef void const *voidpc;
+   typedef void FAR   *voidpf;
+   typedef void       *voidp;
+#else
+   typedef Byte const *voidpc;
+   typedef Byte FAR   *voidpf;
+   typedef Byte       *voidp;
+#endif
+
+#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)
+#  include <limits.h>
+#  if (UINT_MAX == 0xffffffffUL)
+#    define Z_U4 unsigned
+#  elif (ULONG_MAX == 0xffffffffUL)
+#    define Z_U4 unsigned long
+#  elif (USHRT_MAX == 0xffffffffUL)
+#    define Z_U4 unsigned short
+#  endif
+#endif
+
+#ifdef Z_U4
+   typedef Z_U4 z_crc_t;
+#else
+   typedef unsigned long z_crc_t;
+#endif
+
+#ifdef HAVE_UNISTD_H    /* may be set to #if 1 by ./configure */
+#  define Z_HAVE_UNISTD_H
+#endif
+
+#ifdef HAVE_STDARG_H    /* may be set to #if 1 by ./configure */
+#  define Z_HAVE_STDARG_H
+#endif
+
+#ifdef STDC
+#  ifndef Z_SOLO
+#    include <sys/types.h>      /* for off_t */
+#  endif
+#endif
+
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#  ifndef Z_SOLO
+#    include <stdarg.h>         /* for va_list */
+#  endif
+#endif
+
+#ifdef _WIN32
+#  ifndef Z_SOLO
+#    include <stddef.h>         /* for wchar_t */
+#  endif
+#endif
+
+/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
+ * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
+ * though the former does not conform to the LFS document), but considering
+ * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
+ * equivalently requesting no 64-bit operations
+ */
+#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
+#  undef _LARGEFILE64_SOURCE
+#endif
+
+#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
+#  define Z_HAVE_UNISTD_H
+#endif
+#ifndef Z_SOLO
+#  if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
+#    include <unistd.h>         /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
+#    ifdef VMS
+#      include <unixio.h>       /* for off_t */
+#    endif
+#    ifndef z_off_t
+#      define z_off_t off_t
+#    endif
+#  endif
+#endif
+
+#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0
+#  define Z_LFS64
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)
+#  define Z_LARGE64
+#endif
+
+#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)
+#  define Z_WANT64
+#endif
+
+#if !defined(SEEK_SET) && !defined(Z_SOLO)
+#  define SEEK_SET        0       /* Seek from beginning of file.  */
+#  define SEEK_CUR        1       /* Seek from current position.  */
+#  define SEEK_END        2       /* Set file pointer to EOF plus "offset" */
+#endif
+
+#ifndef z_off_t
+#  define z_off_t long
+#endif
+
+#if !defined(_WIN32) && defined(Z_LARGE64)
+#  define z_off64_t off64_t
+#else
+#  if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
+#    define z_off64_t __int64
+#  else
+#    define z_off64_t z_off_t
+#  endif
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+  #pragma map(deflateInit_,"DEIN")
+  #pragma map(deflateInit2_,"DEIN2")
+  #pragma map(deflateEnd,"DEEND")
+  #pragma map(deflateBound,"DEBND")
+  #pragma map(inflateInit_,"ININ")
+  #pragma map(inflateInit2_,"ININ2")
+  #pragma map(inflateEnd,"INEND")
+  #pragma map(inflateSync,"INSY")
+  #pragma map(inflateSetDictionary,"INSEDI")
+  #pragma map(compressBound,"CMBND")
+  #pragma map(inflate_table,"INTABL")
+  #pragma map(inflate_fast,"INFA")
+  #pragma map(inflate_copyright,"INCOPY")
+#endif
+
+#endif /* ZCONF_H */
diff --git a/Source/ZLib/zconf.h.in b/Source/ZLib/zconf.h.in
index 49e4057..c1f962f 100644
--- a/Source/ZLib/zconf.h.in
+++ b/Source/ZLib/zconf.h.in
@@ -1,9 +1,9 @@
 /* zconf.h -- configuration of the zlib compression library
- * Copyright (C) 1995-2012 Jean-loup Gailly.
+ * Copyright (C) 1995-2013 Jean-loup Gailly.
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
-/* @(#) $Id: zconf.h.in,v 1.4 2012/05/13 12:18:39 drolon Exp $ */
+/* @(#) $Id: zconf.h.in,v 1.5 2013/05/10 17:22:52 drolon Exp $ */
 
 #ifndef ZCONF_H
 #define ZCONF_H
@@ -21,6 +21,7 @@
 #  define _dist_code            z__dist_code
 #  define _length_code          z__length_code
 #  define _tr_align             z__tr_align
+#  define _tr_flush_bits        z__tr_flush_bits
 #  define _tr_flush_block       z__tr_flush_block
 #  define _tr_init              z__tr_init
 #  define _tr_stored_block      z__tr_stored_block
@@ -77,6 +78,7 @@
 #      define gzopen_w              z_gzopen_w
 #    endif
 #    define gzprintf              z_gzprintf
+#    define gzvprintf             z_gzvprintf
 #    define gzputc                z_gzputc
 #    define gzputs                z_gzputs
 #    define gzread                z_gzread
@@ -103,6 +105,7 @@
 #  define inflateReset          z_inflateReset
 #  define inflateReset2         z_inflateReset2
 #  define inflateSetDictionary  z_inflateSetDictionary
+#  define inflateGetDictionary  z_inflateGetDictionary
 #  define inflateSync           z_inflateSync
 #  define inflateSyncPoint      z_inflateSyncPoint
 #  define inflateUndermine      z_inflateUndermine
@@ -388,20 +391,14 @@ typedef uLong FAR uLongf;
    typedef Byte       *voidp;
 #endif
 
-/* ./configure may #define Z_U4 here */
-
 #if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)
 #  include <limits.h>
 #  if (UINT_MAX == 0xffffffffUL)
 #    define Z_U4 unsigned
-#  else
-#    if (ULONG_MAX == 0xffffffffUL)
-#      define Z_U4 unsigned long
-#    else
-#      if (USHRT_MAX == 0xffffffffUL)
-#        define Z_U4 unsigned short
-#      endif
-#    endif
+#  elif (ULONG_MAX == 0xffffffffUL)
+#    define Z_U4 unsigned long
+#  elif (USHRT_MAX == 0xffffffffUL)
+#    define Z_U4 unsigned short
 #  endif
 #endif
 
@@ -425,8 +422,16 @@ typedef uLong FAR uLongf;
 #  endif
 #endif
 
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#  ifndef Z_SOLO
+#    include <stdarg.h>         /* for va_list */
+#  endif
+#endif
+
 #ifdef _WIN32
-#  include <stddef.h>           /* for wchar_t */
+#  ifndef Z_SOLO
+#    include <stddef.h>         /* for wchar_t */
+#  endif
 #endif
 
 /* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
@@ -435,7 +440,7 @@ typedef uLong FAR uLongf;
  * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
  * equivalently requesting no 64-bit operations
  */
-#if defined(LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
+#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
 #  undef _LARGEFILE64_SOURCE
 #endif
 
@@ -443,7 +448,7 @@ typedef uLong FAR uLongf;
 #  define Z_HAVE_UNISTD_H
 #endif
 #ifndef Z_SOLO
-#  if defined(Z_HAVE_UNISTD_H) || defined(LARGEFILE64_SOURCE)
+#  if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
 #    include <unistd.h>         /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
 #    ifdef VMS
 #      include <unixio.h>       /* for off_t */
diff --git a/Source/ZLib/zlib.3 b/Source/ZLib/zlib.3
index 79d3402..0160e62 100644
--- a/Source/ZLib/zlib.3
+++ b/Source/ZLib/zlib.3
@@ -1,4 +1,4 @@
-.TH ZLIB 3 "2 May 2012"
+.TH ZLIB 3 "28 Apr 2013"
 .SH NAME
 zlib \- compression/decompression library
 .SH SYNOPSIS
@@ -125,8 +125,8 @@ before asking for help.
 Send questions and/or comments to zlib at gzip.org,
 or (for the Windows DLL version) to Gilles Vollant (info at winimage.com).
 .SH AUTHORS
-Version 1.2.7
-Copyright (C) 1995-2012 Jean-loup Gailly (jloup at gzip.org)
+Version 1.2.8
+Copyright (C) 1995-2013 Jean-loup Gailly (jloup at gzip.org)
 and Mark Adler (madler at alumni.caltech.edu).
 .LP
 This software is provided "as-is,"
diff --git a/Source/ZLib/zlib.h b/Source/ZLib/zlib.h
index 3edf3ac..3e0c767 100644
--- a/Source/ZLib/zlib.h
+++ b/Source/ZLib/zlib.h
@@ -1,7 +1,7 @@
 /* zlib.h -- interface of the 'zlib' general purpose compression library
-  version 1.2.7, May 2nd, 2012
+  version 1.2.8, April 28th, 2013
 
-  Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler
+  Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -37,11 +37,11 @@
 extern "C" {
 #endif
 
-#define ZLIB_VERSION "1.2.7"
-#define ZLIB_VERNUM 0x1270
+#define ZLIB_VERSION "1.2.8"
+#define ZLIB_VERNUM 0x1280
 #define ZLIB_VER_MAJOR 1
 #define ZLIB_VER_MINOR 2
-#define ZLIB_VER_REVISION 7
+#define ZLIB_VER_REVISION 8
 #define ZLIB_VER_SUBREVISION 0
 
 /*
@@ -839,6 +839,21 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
    inflate().
 */
 
+ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm,
+                                             Bytef *dictionary,
+                                             uInt  *dictLength));
+/*
+     Returns the sliding dictionary being maintained by inflate.  dictLength is
+   set to the number of bytes in the dictionary, and that many bytes are copied
+   to dictionary.  dictionary must have enough space, where 32768 bytes is
+   always enough.  If inflateGetDictionary() is called with dictionary equal to
+   Z_NULL, then only the dictionary length is returned, and nothing is copied.
+   Similary, if dictLength is Z_NULL, then it is not set.
+
+     inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the
+   stream state is inconsistent.
+*/
+
 ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
 /*
      Skips invalid compressed data until a possible full flush point (see above
@@ -846,7 +861,7 @@ ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
    available input is skipped.  No output is provided.
 
      inflateSync searches for a 00 00 FF FF pattern in the compressed data.
-   All full flush points have this pattern, but not all occurences of this
+   All full flush points have this pattern, but not all occurrences of this
    pattern are full flush points.
 
      inflateSync returns Z_OK if a possible full flush point has been found,
@@ -1007,7 +1022,8 @@ ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
    the version of the header file.
 */
 
-typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
+typedef unsigned (*in_func) OF((void FAR *,
+                                z_const unsigned char FAR * FAR *));
 typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
 
 ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
@@ -1015,11 +1031,12 @@ ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
                                     out_func out, void FAR *out_desc));
 /*
      inflateBack() does a raw inflate with a single call using a call-back
-   interface for input and output.  This is more efficient than inflate() for
-   file i/o applications in that it avoids copying between the output and the
-   sliding window by simply making the window itself the output buffer.  This
-   function trusts the application to not change the output buffer passed by
-   the output function, at least until inflateBack() returns.
+   interface for input and output.  This is potentially more efficient than
+   inflate() for file i/o applications, in that it avoids copying between the
+   output and the sliding window by simply making the window itself the output
+   buffer.  inflate() can be faster on modern CPUs when used with large
+   buffers.  inflateBack() trusts the application to not change the output
+   buffer passed by the output function, at least until inflateBack() returns.
 
      inflateBackInit() must be called first to allocate the internal state
    and to initialize the state with the user-provided window buffer.
@@ -1736,6 +1753,13 @@ ZEXTERN int            ZEXPORT deflateResetKeep OF((z_streamp));
 ZEXTERN gzFile         ZEXPORT gzopen_w OF((const wchar_t *path,
                                             const char *mode));
 #endif
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#  ifndef Z_SOLO
+ZEXTERN int            ZEXPORTVA gzvprintf Z_ARG((gzFile file,
+                                                  const char *format,
+                                                  va_list va));
+#  endif
+#endif
 
 #ifdef __cplusplus
 }
diff --git a/Source/ZLib/zutil.c b/Source/ZLib/zutil.c
index 344fcf7..9989113 100644
--- a/Source/ZLib/zutil.c
+++ b/Source/ZLib/zutil.c
@@ -1,324 +1,324 @@
-/* zutil.c -- target dependent utility functions for the compression library
- * Copyright (C) 1995-2005, 2010, 2011, 2012 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id: zutil.c,v 1.9 2012/05/13 12:18:39 drolon Exp $ */
-
-#include "zutil.h"
-#ifndef Z_SOLO
-#  include "gzguts.h"
-#endif
-
-#ifndef NO_DUMMY_DECL
-struct internal_state      {int dummy;}; /* for buggy compilers */
-#endif
-
-const char * const z_errmsg[10] = {
-"need dictionary",     /* Z_NEED_DICT       2  */
-"stream end",          /* Z_STREAM_END      1  */
-"",                    /* Z_OK              0  */
-"file error",          /* Z_ERRNO         (-1) */
-"stream error",        /* Z_STREAM_ERROR  (-2) */
-"data error",          /* Z_DATA_ERROR    (-3) */
-"insufficient memory", /* Z_MEM_ERROR     (-4) */
-"buffer error",        /* Z_BUF_ERROR     (-5) */
-"incompatible version",/* Z_VERSION_ERROR (-6) */
-""};
-
-
-const char * ZEXPORT zlibVersion()
-{
-    return ZLIB_VERSION;
-}
-
-uLong ZEXPORT zlibCompileFlags()
-{
-    uLong flags;
-
-    flags = 0;
-    switch ((int)(sizeof(uInt))) {
-    case 2:     break;
-    case 4:     flags += 1;     break;
-    case 8:     flags += 2;     break;
-    default:    flags += 3;
-    }
-    switch ((int)(sizeof(uLong))) {
-    case 2:     break;
-    case 4:     flags += 1 << 2;        break;
-    case 8:     flags += 2 << 2;        break;
-    default:    flags += 3 << 2;
-    }
-    switch ((int)(sizeof(voidpf))) {
-    case 2:     break;
-    case 4:     flags += 1 << 4;        break;
-    case 8:     flags += 2 << 4;        break;
-    default:    flags += 3 << 4;
-    }
-    switch ((int)(sizeof(z_off_t))) {
-    case 2:     break;
-    case 4:     flags += 1 << 6;        break;
-    case 8:     flags += 2 << 6;        break;
-    default:    flags += 3 << 6;
-    }
-#ifdef DEBUG
-    flags += 1 << 8;
-#endif
-#if defined(ASMV) || defined(ASMINF)
-    flags += 1 << 9;
-#endif
-#ifdef ZLIB_WINAPI
-    flags += 1 << 10;
-#endif
-#ifdef BUILDFIXED
-    flags += 1 << 12;
-#endif
-#ifdef DYNAMIC_CRC_TABLE
-    flags += 1 << 13;
-#endif
-#ifdef NO_GZCOMPRESS
-    flags += 1L << 16;
-#endif
-#ifdef NO_GZIP
-    flags += 1L << 17;
-#endif
-#ifdef PKZIP_BUG_WORKAROUND
-    flags += 1L << 20;
-#endif
-#ifdef FASTEST
-    flags += 1L << 21;
-#endif
-#if defined(STDC) || defined(Z_HAVE_STDARG_H)
-#  ifdef NO_vsnprintf
-    flags += 1L << 25;
-#    ifdef HAS_vsprintf_void
-    flags += 1L << 26;
-#    endif
-#  else
-#    ifdef HAS_vsnprintf_void
-    flags += 1L << 26;
-#    endif
-#  endif
-#else
-    flags += 1L << 24;
-#  ifdef NO_snprintf
-    flags += 1L << 25;
-#    ifdef HAS_sprintf_void
-    flags += 1L << 26;
-#    endif
-#  else
-#    ifdef HAS_snprintf_void
-    flags += 1L << 26;
-#    endif
-#  endif
-#endif
-    return flags;
-}
-
-#ifdef DEBUG
-
-#  ifndef verbose
-#    define verbose 0
-#  endif
-int ZLIB_INTERNAL z_verbose = verbose;
-
-void ZLIB_INTERNAL z_error (m)
-    char *m;
-{
-    fprintf(stderr, "%s\n", m);
-    exit(1);
-}
-#endif
-
-/* exported to allow conversion of error code to string for compress() and
- * uncompress()
- */
-const char * ZEXPORT zError(err)
-    int err;
-{
-    return ERR_MSG(err);
-}
-
-#if defined(_WIN32_WCE)
-    /* The Microsoft C Run-Time Library for Windows CE doesn't have
-     * errno.  We define it as a global variable to simplify porting.
-     * Its value is always 0 and should not be used.
-     */
-    int errno = 0;
-#endif
-
-#ifndef HAVE_MEMCPY
-
-void ZLIB_INTERNAL zmemcpy(dest, source, len)
-    Bytef* dest;
-    const Bytef* source;
-    uInt  len;
-{
-    if (len == 0) return;
-    do {
-        *dest++ = *source++; /* ??? to be unrolled */
-    } while (--len != 0);
-}
-
-int ZLIB_INTERNAL zmemcmp(s1, s2, len)
-    const Bytef* s1;
-    const Bytef* s2;
-    uInt  len;
-{
-    uInt j;
-
-    for (j = 0; j < len; j++) {
-        if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
-    }
-    return 0;
-}
-
-void ZLIB_INTERNAL zmemzero(dest, len)
-    Bytef* dest;
-    uInt  len;
-{
-    if (len == 0) return;
-    do {
-        *dest++ = 0;  /* ??? to be unrolled */
-    } while (--len != 0);
-}
-#endif
-
-#ifndef Z_SOLO
-
-#ifdef SYS16BIT
-
-#ifdef __TURBOC__
-/* Turbo C in 16-bit mode */
-
-#  define MY_ZCALLOC
-
-/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
- * and farmalloc(64K) returns a pointer with an offset of 8, so we
- * must fix the pointer. Warning: the pointer must be put back to its
- * original form in order to free it, use zcfree().
- */
-
-#define MAX_PTR 10
-/* 10*64K = 640K */
-
-local int next_ptr = 0;
-
-typedef struct ptr_table_s {
-    voidpf org_ptr;
-    voidpf new_ptr;
-} ptr_table;
-
-local ptr_table table[MAX_PTR];
-/* This table is used to remember the original form of pointers
- * to large buffers (64K). Such pointers are normalized with a zero offset.
- * Since MSDOS is not a preemptive multitasking OS, this table is not
- * protected from concurrent access. This hack doesn't work anyway on
- * a protected system like OS/2. Use Microsoft C instead.
- */
-
-voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size)
-{
-    voidpf buf = opaque; /* just to make some compilers happy */
-    ulg bsize = (ulg)items*size;
-
-    /* If we allocate less than 65520 bytes, we assume that farmalloc
-     * will return a usable pointer which doesn't have to be normalized.
-     */
-    if (bsize < 65520L) {
-        buf = farmalloc(bsize);
-        if (*(ush*)&buf != 0) return buf;
-    } else {
-        buf = farmalloc(bsize + 16L);
-    }
-    if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
-    table[next_ptr].org_ptr = buf;
-
-    /* Normalize the pointer to seg:0 */
-    *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
-    *(ush*)&buf = 0;
-    table[next_ptr++].new_ptr = buf;
-    return buf;
-}
-
-void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
-{
-    int n;
-    if (*(ush*)&ptr != 0) { /* object < 64K */
-        farfree(ptr);
-        return;
-    }
-    /* Find the original pointer */
-    for (n = 0; n < next_ptr; n++) {
-        if (ptr != table[n].new_ptr) continue;
-
-        farfree(table[n].org_ptr);
-        while (++n < next_ptr) {
-            table[n-1] = table[n];
-        }
-        next_ptr--;
-        return;
-    }
-    ptr = opaque; /* just to make some compilers happy */
-    Assert(0, "zcfree: ptr not found");
-}
-
-#endif /* __TURBOC__ */
-
-
-#ifdef M_I86
-/* Microsoft C in 16-bit mode */
-
-#  define MY_ZCALLOC
-
-#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
-#  define _halloc  halloc
-#  define _hfree   hfree
-#endif
-
-voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size)
-{
-    if (opaque) opaque = 0; /* to make compiler happy */
-    return _halloc((long)items, size);
-}
-
-void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
-{
-    if (opaque) opaque = 0; /* to make compiler happy */
-    _hfree(ptr);
-}
-
-#endif /* M_I86 */
-
-#endif /* SYS16BIT */
-
-
-#ifndef MY_ZCALLOC /* Any system without a special alloc function */
-
-#ifndef STDC
-extern voidp  malloc OF((uInt size));
-extern voidp  calloc OF((uInt items, uInt size));
-extern void   free   OF((voidpf ptr));
-#endif
-
-voidpf ZLIB_INTERNAL zcalloc (opaque, items, size)
-    voidpf opaque;
-    unsigned items;
-    unsigned size;
-{
-    if (opaque) items += size - size; /* make compiler happy */
-    return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
-                              (voidpf)calloc(items, size);
-}
-
-void ZLIB_INTERNAL zcfree (opaque, ptr)
-    voidpf opaque;
-    voidpf ptr;
-{
-    free(ptr);
-    if (opaque) return; /* make compiler happy */
-}
-
-#endif /* MY_ZCALLOC */
-
-#endif /* !Z_SOLO */
+/* zutil.c -- target dependent utility functions for the compression library
+ * Copyright (C) 1995-2005, 2010, 2011, 2012 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id: zutil.c,v 1.10 2013/05/10 17:22:52 drolon Exp $ */
+
+#include "zutil.h"
+#ifndef Z_SOLO
+#  include "gzguts.h"
+#endif
+
+#ifndef NO_DUMMY_DECL
+struct internal_state      {int dummy;}; /* for buggy compilers */
+#endif
+
+z_const char * const z_errmsg[10] = {
+"need dictionary",     /* Z_NEED_DICT       2  */
+"stream end",          /* Z_STREAM_END      1  */
+"",                    /* Z_OK              0  */
+"file error",          /* Z_ERRNO         (-1) */
+"stream error",        /* Z_STREAM_ERROR  (-2) */
+"data error",          /* Z_DATA_ERROR    (-3) */
+"insufficient memory", /* Z_MEM_ERROR     (-4) */
+"buffer error",        /* Z_BUF_ERROR     (-5) */
+"incompatible version",/* Z_VERSION_ERROR (-6) */
+""};
+
+
+const char * ZEXPORT zlibVersion()
+{
+    return ZLIB_VERSION;
+}
+
+uLong ZEXPORT zlibCompileFlags()
+{
+    uLong flags;
+
+    flags = 0;
+    switch ((int)(sizeof(uInt))) {
+    case 2:     break;
+    case 4:     flags += 1;     break;
+    case 8:     flags += 2;     break;
+    default:    flags += 3;
+    }
+    switch ((int)(sizeof(uLong))) {
+    case 2:     break;
+    case 4:     flags += 1 << 2;        break;
+    case 8:     flags += 2 << 2;        break;
+    default:    flags += 3 << 2;
+    }
+    switch ((int)(sizeof(voidpf))) {
+    case 2:     break;
+    case 4:     flags += 1 << 4;        break;
+    case 8:     flags += 2 << 4;        break;
+    default:    flags += 3 << 4;
+    }
+    switch ((int)(sizeof(z_off_t))) {
+    case 2:     break;
+    case 4:     flags += 1 << 6;        break;
+    case 8:     flags += 2 << 6;        break;
+    default:    flags += 3 << 6;
+    }
+#ifdef DEBUG
+    flags += 1 << 8;
+#endif
+#if defined(ASMV) || defined(ASMINF)
+    flags += 1 << 9;
+#endif
+#ifdef ZLIB_WINAPI
+    flags += 1 << 10;
+#endif
+#ifdef BUILDFIXED
+    flags += 1 << 12;
+#endif
+#ifdef DYNAMIC_CRC_TABLE
+    flags += 1 << 13;
+#endif
+#ifdef NO_GZCOMPRESS
+    flags += 1L << 16;
+#endif
+#ifdef NO_GZIP
+    flags += 1L << 17;
+#endif
+#ifdef PKZIP_BUG_WORKAROUND
+    flags += 1L << 20;
+#endif
+#ifdef FASTEST
+    flags += 1L << 21;
+#endif
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#  ifdef NO_vsnprintf
+    flags += 1L << 25;
+#    ifdef HAS_vsprintf_void
+    flags += 1L << 26;
+#    endif
+#  else
+#    ifdef HAS_vsnprintf_void
+    flags += 1L << 26;
+#    endif
+#  endif
+#else
+    flags += 1L << 24;
+#  ifdef NO_snprintf
+    flags += 1L << 25;
+#    ifdef HAS_sprintf_void
+    flags += 1L << 26;
+#    endif
+#  else
+#    ifdef HAS_snprintf_void
+    flags += 1L << 26;
+#    endif
+#  endif
+#endif
+    return flags;
+}
+
+#ifdef DEBUG
+
+#  ifndef verbose
+#    define verbose 0
+#  endif
+int ZLIB_INTERNAL z_verbose = verbose;
+
+void ZLIB_INTERNAL z_error (m)
+    char *m;
+{
+    fprintf(stderr, "%s\n", m);
+    exit(1);
+}
+#endif
+
+/* exported to allow conversion of error code to string for compress() and
+ * uncompress()
+ */
+const char * ZEXPORT zError(err)
+    int err;
+{
+    return ERR_MSG(err);
+}
+
+#if defined(_WIN32_WCE)
+    /* The Microsoft C Run-Time Library for Windows CE doesn't have
+     * errno.  We define it as a global variable to simplify porting.
+     * Its value is always 0 and should not be used.
+     */
+    int errno = 0;
+#endif
+
+#ifndef HAVE_MEMCPY
+
+void ZLIB_INTERNAL zmemcpy(dest, source, len)
+    Bytef* dest;
+    const Bytef* source;
+    uInt  len;
+{
+    if (len == 0) return;
+    do {
+        *dest++ = *source++; /* ??? to be unrolled */
+    } while (--len != 0);
+}
+
+int ZLIB_INTERNAL zmemcmp(s1, s2, len)
+    const Bytef* s1;
+    const Bytef* s2;
+    uInt  len;
+{
+    uInt j;
+
+    for (j = 0; j < len; j++) {
+        if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
+    }
+    return 0;
+}
+
+void ZLIB_INTERNAL zmemzero(dest, len)
+    Bytef* dest;
+    uInt  len;
+{
+    if (len == 0) return;
+    do {
+        *dest++ = 0;  /* ??? to be unrolled */
+    } while (--len != 0);
+}
+#endif
+
+#ifndef Z_SOLO
+
+#ifdef SYS16BIT
+
+#ifdef __TURBOC__
+/* Turbo C in 16-bit mode */
+
+#  define MY_ZCALLOC
+
+/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
+ * and farmalloc(64K) returns a pointer with an offset of 8, so we
+ * must fix the pointer. Warning: the pointer must be put back to its
+ * original form in order to free it, use zcfree().
+ */
+
+#define MAX_PTR 10
+/* 10*64K = 640K */
+
+local int next_ptr = 0;
+
+typedef struct ptr_table_s {
+    voidpf org_ptr;
+    voidpf new_ptr;
+} ptr_table;
+
+local ptr_table table[MAX_PTR];
+/* This table is used to remember the original form of pointers
+ * to large buffers (64K). Such pointers are normalized with a zero offset.
+ * Since MSDOS is not a preemptive multitasking OS, this table is not
+ * protected from concurrent access. This hack doesn't work anyway on
+ * a protected system like OS/2. Use Microsoft C instead.
+ */
+
+voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size)
+{
+    voidpf buf = opaque; /* just to make some compilers happy */
+    ulg bsize = (ulg)items*size;
+
+    /* If we allocate less than 65520 bytes, we assume that farmalloc
+     * will return a usable pointer which doesn't have to be normalized.
+     */
+    if (bsize < 65520L) {
+        buf = farmalloc(bsize);
+        if (*(ush*)&buf != 0) return buf;
+    } else {
+        buf = farmalloc(bsize + 16L);
+    }
+    if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
+    table[next_ptr].org_ptr = buf;
+
+    /* Normalize the pointer to seg:0 */
+    *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
+    *(ush*)&buf = 0;
+    table[next_ptr++].new_ptr = buf;
+    return buf;
+}
+
+void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
+{
+    int n;
+    if (*(ush*)&ptr != 0) { /* object < 64K */
+        farfree(ptr);
+        return;
+    }
+    /* Find the original pointer */
+    for (n = 0; n < next_ptr; n++) {
+        if (ptr != table[n].new_ptr) continue;
+
+        farfree(table[n].org_ptr);
+        while (++n < next_ptr) {
+            table[n-1] = table[n];
+        }
+        next_ptr--;
+        return;
+    }
+    ptr = opaque; /* just to make some compilers happy */
+    Assert(0, "zcfree: ptr not found");
+}
+
+#endif /* __TURBOC__ */
+
+
+#ifdef M_I86
+/* Microsoft C in 16-bit mode */
+
+#  define MY_ZCALLOC
+
+#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
+#  define _halloc  halloc
+#  define _hfree   hfree
+#endif
+
+voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size)
+{
+    if (opaque) opaque = 0; /* to make compiler happy */
+    return _halloc((long)items, size);
+}
+
+void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
+{
+    if (opaque) opaque = 0; /* to make compiler happy */
+    _hfree(ptr);
+}
+
+#endif /* M_I86 */
+
+#endif /* SYS16BIT */
+
+
+#ifndef MY_ZCALLOC /* Any system without a special alloc function */
+
+#ifndef STDC
+extern voidp  malloc OF((uInt size));
+extern voidp  calloc OF((uInt items, uInt size));
+extern void   free   OF((voidpf ptr));
+#endif
+
+voidpf ZLIB_INTERNAL zcalloc (opaque, items, size)
+    voidpf opaque;
+    unsigned items;
+    unsigned size;
+{
+    if (opaque) items += size - size; /* make compiler happy */
+    return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
+                              (voidpf)calloc(items, size);
+}
+
+void ZLIB_INTERNAL zcfree (opaque, ptr)
+    voidpf opaque;
+    voidpf ptr;
+{
+    free(ptr);
+    if (opaque) return; /* make compiler happy */
+}
+
+#endif /* MY_ZCALLOC */
+
+#endif /* !Z_SOLO */
diff --git a/Source/ZLib/zutil.h b/Source/ZLib/zutil.h
index 9a54275..d8529f0 100644
--- a/Source/ZLib/zutil.h
+++ b/Source/ZLib/zutil.h
@@ -1,252 +1,253 @@
-/* zutil.h -- internal interface and configuration of the compression library
- * Copyright (C) 1995-2012 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
-   part of the implementation of the compression library and is
-   subject to change. Applications should only use zlib.h.
- */
-
-/* @(#) $Id: zutil.h,v 1.9 2012/05/13 12:18:39 drolon Exp $ */
-
-#ifndef ZUTIL_H
-#define ZUTIL_H
-
-#ifdef HAVE_HIDDEN
-#  define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
-#else
-#  define ZLIB_INTERNAL
-#endif
-
-#include "zlib.h"
-
-#if defined(STDC) && !defined(Z_SOLO)
-#  if !(defined(_WIN32_WCE) && defined(_MSC_VER))
-#    include <stddef.h>
-#  endif
-#  include <string.h>
-#  include <stdlib.h>
-#endif
-
-#ifdef Z_SOLO
-   typedef long ptrdiff_t;  /* guess -- will be caught if guess is wrong */
-#endif
-
-#ifndef local
-#  define local static
-#endif
-/* compile with -Dlocal if your debugger can't find static symbols */
-
-typedef unsigned char  uch;
-typedef uch FAR uchf;
-typedef unsigned short ush;
-typedef ush FAR ushf;
-typedef unsigned long  ulg;
-
-extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
-/* (size given to avoid silly warnings with Visual C++) */
-
-#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
-
-#define ERR_RETURN(strm,err) \
-  return (strm->msg = (char*)ERR_MSG(err), (err))
-/* To be used only when the state is known to be valid */
-
-        /* common constants */
-
-#ifndef DEF_WBITS
-#  define DEF_WBITS MAX_WBITS
-#endif
-/* default windowBits for decompression. MAX_WBITS is for compression only */
-
-#if MAX_MEM_LEVEL >= 8
-#  define DEF_MEM_LEVEL 8
-#else
-#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
-#endif
-/* default memLevel */
-
-#define STORED_BLOCK 0
-#define STATIC_TREES 1
-#define DYN_TREES    2
-/* The three kinds of block type */
-
-#define MIN_MATCH  3
-#define MAX_MATCH  258
-/* The minimum and maximum match lengths */
-
-#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
-
-        /* target dependencies */
-
-#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
-#  define OS_CODE  0x00
-#  ifndef Z_SOLO
-#    if defined(__TURBOC__) || defined(__BORLANDC__)
-#      if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
-         /* Allow compilation with ANSI keywords only enabled */
-         void _Cdecl farfree( void *block );
-         void *_Cdecl farmalloc( unsigned long nbytes );
-#      else
-#        include <alloc.h>
-#      endif
-#    else /* MSC or DJGPP */
-#      include <malloc.h>
-#    endif
-#  endif
-#endif
-
-#ifdef AMIGA
-#  define OS_CODE  0x01
-#endif
-
-#if defined(VAXC) || defined(VMS)
-#  define OS_CODE  0x02
-#  define F_OPEN(name, mode) \
-     fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
-#endif
-
-#if defined(ATARI) || defined(atarist)
-#  define OS_CODE  0x05
-#endif
-
-#ifdef OS2
-#  define OS_CODE  0x06
-#  if defined(M_I86) && !defined(Z_SOLO)
-#    include <malloc.h>
-#  endif
-#endif
-
-#if defined(MACOS) || defined(TARGET_OS_MAC)
-#  define OS_CODE  0x07
-#  ifndef Z_SOLO
-#    if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
-#      include <unix.h> /* for fdopen */
-#    else
-#      ifndef fdopen
-#        define fdopen(fd,mode) NULL /* No fdopen() */
-#      endif
-#    endif
-#  endif
-#endif
-
-#ifdef TOPS20
-#  define OS_CODE  0x0a
-#endif
-
-#ifdef WIN32
-#  ifndef __CYGWIN__  /* Cygwin is Unix, not Win32 */
-#    define OS_CODE  0x0b
-#  endif
-#endif
-
-#ifdef __50SERIES /* Prime/PRIMOS */
-#  define OS_CODE  0x0f
-#endif
-
-#if defined(_BEOS_) || defined(RISCOS)
-#  define fdopen(fd,mode) NULL /* No fdopen() */
-#endif
-
-#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX
-#  if defined(_WIN32_WCE)
-#    define fdopen(fd,mode) NULL /* No fdopen() */
-#    ifndef _PTRDIFF_T_DEFINED
-       typedef int ptrdiff_t;
-#      define _PTRDIFF_T_DEFINED
-#    endif
-#  else
-#    define fdopen(fd,type)  _fdopen(fd,type)
-#  endif
-#endif
-
-#if defined(__BORLANDC__) && !defined(MSDOS)
-  #pragma warn -8004
-  #pragma warn -8008
-  #pragma warn -8066
-#endif
-
-/* provide prototypes for these when building zlib without LFS */
-#if !defined(_WIN32) && (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0)
-    ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
-    ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
-#endif
-
-        /* common defaults */
-
-#ifndef OS_CODE
-#  define OS_CODE  0x03  /* assume Unix */
-#endif
-
-#ifndef F_OPEN
-#  define F_OPEN(name, mode) fopen((name), (mode))
-#endif
-
-         /* functions */
-
-#if defined(pyr) || defined(Z_SOLO)
-#  define NO_MEMCPY
-#endif
-#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
- /* Use our own functions for small and medium model with MSC <= 5.0.
-  * You may have to use the same strategy for Borland C (untested).
-  * The __SC__ check is for Symantec.
-  */
-#  define NO_MEMCPY
-#endif
-#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
-#  define HAVE_MEMCPY
-#endif
-#ifdef HAVE_MEMCPY
-#  ifdef SMALL_MEDIUM /* MSDOS small or medium model */
-#    define zmemcpy _fmemcpy
-#    define zmemcmp _fmemcmp
-#    define zmemzero(dest, len) _fmemset(dest, 0, len)
-#  else
-#    define zmemcpy memcpy
-#    define zmemcmp memcmp
-#    define zmemzero(dest, len) memset(dest, 0, len)
-#  endif
-#else
-   void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
-   int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
-   void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len));
-#endif
-
-/* Diagnostic functions */
-#ifdef DEBUG
-#  include <stdio.h>
-   extern int ZLIB_INTERNAL z_verbose;
-   extern void ZLIB_INTERNAL z_error OF((char *m));
-#  define Assert(cond,msg) {if(!(cond)) z_error(msg);}
-#  define Trace(x) {if (z_verbose>=0) fprintf x ;}
-#  define Tracev(x) {if (z_verbose>0) fprintf x ;}
-#  define Tracevv(x) {if (z_verbose>1) fprintf x ;}
-#  define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
-#  define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
-#else
-#  define Assert(cond,msg)
-#  define Trace(x)
-#  define Tracev(x)
-#  define Tracevv(x)
-#  define Tracec(c,x)
-#  define Tracecv(c,x)
-#endif
-
-#ifndef Z_SOLO
-   voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items,
-                                    unsigned size));
-   void ZLIB_INTERNAL zcfree  OF((voidpf opaque, voidpf ptr));
-#endif
-
-#define ZALLOC(strm, items, size) \
-           (*((strm)->zalloc))((strm)->opaque, (items), (size))
-#define ZFREE(strm, addr)  (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
-#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
-
-/* Reverse the bytes in a 32-bit value */
-#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
-                    (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
-
-#endif /* ZUTIL_H */
+/* zutil.h -- internal interface and configuration of the compression library
+ * Copyright (C) 1995-2013 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id: zutil.h,v 1.10 2013/05/10 17:22:52 drolon Exp $ */
+
+#ifndef ZUTIL_H
+#define ZUTIL_H
+
+#ifdef HAVE_HIDDEN
+#  define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
+#else
+#  define ZLIB_INTERNAL
+#endif
+
+#include "zlib.h"
+
+#if defined(STDC) && !defined(Z_SOLO)
+#  if !(defined(_WIN32_WCE) && defined(_MSC_VER))
+#    include <stddef.h>
+#  endif
+#  include <string.h>
+#  include <stdlib.h>
+#endif
+
+#ifdef Z_SOLO
+   typedef long ptrdiff_t;  /* guess -- will be caught if guess is wrong */
+#endif
+
+#ifndef local
+#  define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+typedef unsigned char  uch;
+typedef uch FAR uchf;
+typedef unsigned short ush;
+typedef ush FAR ushf;
+typedef unsigned long  ulg;
+
+extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
+/* (size given to avoid silly warnings with Visual C++) */
+
+#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
+
+#define ERR_RETURN(strm,err) \
+  return (strm->msg = ERR_MSG(err), (err))
+/* To be used only when the state is known to be valid */
+
+        /* common constants */
+
+#ifndef DEF_WBITS
+#  define DEF_WBITS MAX_WBITS
+#endif
+/* default windowBits for decompression. MAX_WBITS is for compression only */
+
+#if MAX_MEM_LEVEL >= 8
+#  define DEF_MEM_LEVEL 8
+#else
+#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
+#endif
+/* default memLevel */
+
+#define STORED_BLOCK 0
+#define STATIC_TREES 1
+#define DYN_TREES    2
+/* The three kinds of block type */
+
+#define MIN_MATCH  3
+#define MAX_MATCH  258
+/* The minimum and maximum match lengths */
+
+#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
+
+        /* target dependencies */
+
+#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
+#  define OS_CODE  0x00
+#  ifndef Z_SOLO
+#    if defined(__TURBOC__) || defined(__BORLANDC__)
+#      if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
+         /* Allow compilation with ANSI keywords only enabled */
+         void _Cdecl farfree( void *block );
+         void *_Cdecl farmalloc( unsigned long nbytes );
+#      else
+#        include <alloc.h>
+#      endif
+#    else /* MSC or DJGPP */
+#      include <malloc.h>
+#    endif
+#  endif
+#endif
+
+#ifdef AMIGA
+#  define OS_CODE  0x01
+#endif
+
+#if defined(VAXC) || defined(VMS)
+#  define OS_CODE  0x02
+#  define F_OPEN(name, mode) \
+     fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
+#endif
+
+#if defined(ATARI) || defined(atarist)
+#  define OS_CODE  0x05
+#endif
+
+#ifdef OS2
+#  define OS_CODE  0x06
+#  if defined(M_I86) && !defined(Z_SOLO)
+#    include <malloc.h>
+#  endif
+#endif
+
+#if defined(MACOS) || defined(TARGET_OS_MAC)
+#  define OS_CODE  0x07
+#  ifndef Z_SOLO
+#    if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
+#      include <unix.h> /* for fdopen */
+#    else
+#      ifndef fdopen
+#        define fdopen(fd,mode) NULL /* No fdopen() */
+#      endif
+#    endif
+#  endif
+#endif
+
+#ifdef TOPS20
+#  define OS_CODE  0x0a
+#endif
+
+#ifdef WIN32
+#  ifndef __CYGWIN__  /* Cygwin is Unix, not Win32 */
+#    define OS_CODE  0x0b
+#  endif
+#endif
+
+#ifdef __50SERIES /* Prime/PRIMOS */
+#  define OS_CODE  0x0f
+#endif
+
+#if defined(_BEOS_) || defined(RISCOS)
+#  define fdopen(fd,mode) NULL /* No fdopen() */
+#endif
+
+#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX
+#  if defined(_WIN32_WCE)
+#    define fdopen(fd,mode) NULL /* No fdopen() */
+#    ifndef _PTRDIFF_T_DEFINED
+       typedef int ptrdiff_t;
+#      define _PTRDIFF_T_DEFINED
+#    endif
+#  else
+#    define fdopen(fd,type)  _fdopen(fd,type)
+#  endif
+#endif
+
+#if defined(__BORLANDC__) && !defined(MSDOS)
+  #pragma warn -8004
+  #pragma warn -8008
+  #pragma warn -8066
+#endif
+
+/* provide prototypes for these when building zlib without LFS */
+#if !defined(_WIN32) && \
+    (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0)
+    ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
+    ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
+#endif
+
+        /* common defaults */
+
+#ifndef OS_CODE
+#  define OS_CODE  0x03  /* assume Unix */
+#endif
+
+#ifndef F_OPEN
+#  define F_OPEN(name, mode) fopen((name), (mode))
+#endif
+
+         /* functions */
+
+#if defined(pyr) || defined(Z_SOLO)
+#  define NO_MEMCPY
+#endif
+#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
+ /* Use our own functions for small and medium model with MSC <= 5.0.
+  * You may have to use the same strategy for Borland C (untested).
+  * The __SC__ check is for Symantec.
+  */
+#  define NO_MEMCPY
+#endif
+#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
+#  define HAVE_MEMCPY
+#endif
+#ifdef HAVE_MEMCPY
+#  ifdef SMALL_MEDIUM /* MSDOS small or medium model */
+#    define zmemcpy _fmemcpy
+#    define zmemcmp _fmemcmp
+#    define zmemzero(dest, len) _fmemset(dest, 0, len)
+#  else
+#    define zmemcpy memcpy
+#    define zmemcmp memcmp
+#    define zmemzero(dest, len) memset(dest, 0, len)
+#  endif
+#else
+   void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
+   int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
+   void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len));
+#endif
+
+/* Diagnostic functions */
+#ifdef DEBUG
+#  include <stdio.h>
+   extern int ZLIB_INTERNAL z_verbose;
+   extern void ZLIB_INTERNAL z_error OF((char *m));
+#  define Assert(cond,msg) {if(!(cond)) z_error(msg);}
+#  define Trace(x) {if (z_verbose>=0) fprintf x ;}
+#  define Tracev(x) {if (z_verbose>0) fprintf x ;}
+#  define Tracevv(x) {if (z_verbose>1) fprintf x ;}
+#  define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
+#  define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
+#else
+#  define Assert(cond,msg)
+#  define Trace(x)
+#  define Tracev(x)
+#  define Tracevv(x)
+#  define Tracec(c,x)
+#  define Tracecv(c,x)
+#endif
+
+#ifndef Z_SOLO
+   voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items,
+                                    unsigned size));
+   void ZLIB_INTERNAL zcfree  OF((voidpf opaque, voidpf ptr));
+#endif
+
+#define ZALLOC(strm, items, size) \
+           (*((strm)->zalloc))((strm)->opaque, (items), (size))
+#define ZFREE(strm, addr)  (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
+#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
+
+/* Reverse the bytes in a 32-bit value */
+#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
+                    (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
+
+#endif /* ZUTIL_H */
diff --git a/TestAPI/MainTestSuite.cpp b/TestAPI/MainTestSuite.cpp
index af7ebdf..7944c22 100644
--- a/TestAPI/MainTestSuite.cpp
+++ b/TestAPI/MainTestSuite.cpp
@@ -73,6 +73,7 @@ int main(int argc, char *argv[]) {
 
 	// test memory IO
 	testMemIO("sample.png");
+	testMemIO("exif.jxr");
 
 	// test multipage functions
 	testMultiPage("sample.png");
@@ -98,6 +99,9 @@ int main(int argc, char *argv[]) {
 	// test thumbnail functions
 	testThumbnail("exif.jpg", 0);
 
+	// test wrapped user buffer
+	testWrappedBuffer("exif.jpg", 0);
+
 #if defined(FREEIMAGE_LIB) || !defined(WIN32)
 	FreeImage_DeInitialise();
 #endif
diff --git a/TestAPI/Test.2003.sln b/TestAPI/Test.2003.sln
deleted file mode 100644
index b7dea52..0000000
--- a/TestAPI/Test.2003.sln
+++ /dev/null
@@ -1,21 +0,0 @@
-Microsoft Visual Studio Solution File, Format Version 8.00
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Test", "Test.2003.vcproj", "{47EC92F9-8B13-4A52-B80E-9EEC1BFFED99}"
-	ProjectSection(ProjectDependencies) = postProject
-	EndProjectSection
-EndProject
-Global
-	GlobalSection(SolutionConfiguration) = preSolution
-		Debug = Debug
-		Release = Release
-	EndGlobalSection
-	GlobalSection(ProjectConfiguration) = postSolution
-		{47EC92F9-8B13-4A52-B80E-9EEC1BFFED99}.Debug.ActiveCfg = Debug|Win32
-		{47EC92F9-8B13-4A52-B80E-9EEC1BFFED99}.Debug.Build.0 = Debug|Win32
-		{47EC92F9-8B13-4A52-B80E-9EEC1BFFED99}.Release.ActiveCfg = Release|Win32
-		{47EC92F9-8B13-4A52-B80E-9EEC1BFFED99}.Release.Build.0 = Release|Win32
-	EndGlobalSection
-	GlobalSection(ExtensibilityGlobals) = postSolution
-	EndGlobalSection
-	GlobalSection(ExtensibilityAddIns) = postSolution
-	EndGlobalSection
-EndGlobal
diff --git a/TestAPI/Test.2003.vcproj b/TestAPI/Test.2003.vcproj
deleted file mode 100644
index fc70047..0000000
--- a/TestAPI/Test.2003.vcproj
+++ /dev/null
@@ -1,180 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="7.10"
-	Name="Test"
-	SccProjectName=""
-	SccLocalPath="">
-	<Platforms>
-		<Platform
-			Name="Win32"/>
-	</Platforms>
-	<Configurations>
-		<Configuration
-			Name="Release|Win32"
-			OutputDirectory=".\Release"
-			IntermediateDirectory=".\Release"
-			ConfigurationType="1"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="FALSE"
-			CharacterSet="2">
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="2"
-				InlineFunctionExpansion="1"
-				AdditionalIncludeDirectories="../Dist"
-				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;FREEIMAGE_LIB"
-				StringPooling="TRUE"
-				RuntimeLibrary="4"
-				EnableFunctionLevelLinking="TRUE"
-				UsePrecompiledHeader="2"
-				PrecompiledHeaderFile=".\Release/Test.pch"
-				AssemblerListingLocation=".\Release/"
-				ObjectFile=".\Release/"
-				ProgramDataBaseFileName=".\Release/"
-				WarningLevel="3"
-				SuppressStartupBanner="TRUE"/>
-			<Tool
-				Name="VCCustomBuildTool"/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="odbc32.lib odbccp32.lib FreeImage.lib"
-				OutputFile=".\Release/Test.exe"
-				LinkIncremental="1"
-				SuppressStartupBanner="TRUE"
-				ProgramDatabaseFile=".\Release/Test.pdb"
-				SubSystem="1"
-				TargetMachine="1"/>
-			<Tool
-				Name="VCMIDLTool"
-				TypeLibraryName=".\Release/Test.tlb"
-				HeaderFileName=""/>
-			<Tool
-				Name="VCPostBuildEventTool"/>
-			<Tool
-				Name="VCPreBuildEventTool"/>
-			<Tool
-				Name="VCPreLinkEventTool"/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="1036"/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"/>
-			<Tool
-				Name="VCWebDeploymentTool"/>
-			<Tool
-				Name="VCManagedWrapperGeneratorTool"/>
-			<Tool
-				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
-		</Configuration>
-		<Configuration
-			Name="Debug|Win32"
-			OutputDirectory=".\Debug"
-			IntermediateDirectory=".\Debug"
-			ConfigurationType="1"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="FALSE"
-			CharacterSet="2">
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="0"
-				AdditionalIncludeDirectories="../Dist"
-				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;FREEIMAGE_LIB"
-				BasicRuntimeChecks="3"
-				RuntimeLibrary="1"
-				UsePrecompiledHeader="2"
-				PrecompiledHeaderFile=".\Debug/Test.pch"
-				AssemblerListingLocation=".\Debug/"
-				ObjectFile=".\Debug/"
-				ProgramDataBaseFileName=".\Debug/"
-				BrowseInformation="1"
-				WarningLevel="3"
-				SuppressStartupBanner="TRUE"
-				DebugInformationFormat="4"/>
-			<Tool
-				Name="VCCustomBuildTool"/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="odbc32.lib odbccp32.lib ../Dist/FreeImaged.lib"
-				OutputFile=".\Debug/Test.exe"
-				LinkIncremental="1"
-				SuppressStartupBanner="TRUE"
-				GenerateDebugInformation="TRUE"
-				ProgramDatabaseFile=".\Debug/Test.pdb"
-				SubSystem="1"
-				TargetMachine="1"/>
-			<Tool
-				Name="VCMIDLTool"
-				TypeLibraryName=".\Debug/Test.tlb"
-				HeaderFileName=""/>
-			<Tool
-				Name="VCPostBuildEventTool"/>
-			<Tool
-				Name="VCPreBuildEventTool"/>
-			<Tool
-				Name="VCPreLinkEventTool"/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="_DEBUG"
-				Culture="1036"/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"/>
-			<Tool
-				Name="VCWebDeploymentTool"/>
-			<Tool
-				Name="VCManagedWrapperGeneratorTool"/>
-			<Tool
-				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<File
-			RelativePath="..\Source\FreeImage.h">
-		</File>
-		<File
-			RelativePath="MainTestSuite.cpp">
-		</File>
-		<File
-			RelativePath=".\testChannels.cpp">
-		</File>
-		<File
-			RelativePath=".\testHeaderOnly.cpp">
-		</File>
-		<File
-			RelativePath="testImageType.cpp">
-		</File>
-		<File
-			RelativePath="testJPEG.cpp">
-		</File>
-		<File
-			RelativePath="testMemIO.cpp">
-		</File>
-		<File
-			RelativePath="testMPage.cpp">
-		</File>
-		<File
-			RelativePath=".\testMPageMemory.cpp">
-		</File>
-		<File
-			RelativePath=".\testMPageStream.cpp">
-		</File>
-		<File
-			RelativePath="testPlugins.cpp">
-		</File>
-		<File
-			RelativePath="TestSuite.h">
-		</File>
-		<File
-			RelativePath="testTools.cpp">
-		</File>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
diff --git a/TestAPI/Test.2008.vcproj b/TestAPI/Test.2008.vcproj
index 44d2e5b..55765a5 100644
--- a/TestAPI/Test.2008.vcproj
+++ b/TestAPI/Test.2008.vcproj
@@ -441,6 +441,10 @@
 			RelativePath="testTools.cpp"
 			>
 		</File>
+		<File
+			RelativePath=".\testWrappedBuffer.cpp"
+			>
+		</File>
 	</Files>
 	<Globals>
 	</Globals>
diff --git a/TestAPI/Test.2013.sln b/TestAPI/Test.2013.sln
new file mode 100644
index 0000000..846c926
--- /dev/null
+++ b/TestAPI/Test.2013.sln
@@ -0,0 +1,27 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Express 2013 for Windows Desktop
+VisualStudioVersion = 12.0.21005.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Test", "Test.2013.vcxproj", "{47EC92F9-8B13-4A52-B80E-9EEC1BFFED99}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Debug|x64 = Debug|x64
+		Release|Win32 = Release|Win32
+		Release|x64 = Release|x64
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{47EC92F9-8B13-4A52-B80E-9EEC1BFFED99}.Debug|Win32.ActiveCfg = Debug|Win32
+		{47EC92F9-8B13-4A52-B80E-9EEC1BFFED99}.Debug|Win32.Build.0 = Debug|Win32
+		{47EC92F9-8B13-4A52-B80E-9EEC1BFFED99}.Debug|x64.ActiveCfg = Debug|x64
+		{47EC92F9-8B13-4A52-B80E-9EEC1BFFED99}.Debug|x64.Build.0 = Debug|x64
+		{47EC92F9-8B13-4A52-B80E-9EEC1BFFED99}.Release|Win32.ActiveCfg = Release|Win32
+		{47EC92F9-8B13-4A52-B80E-9EEC1BFFED99}.Release|Win32.Build.0 = Release|Win32
+		{47EC92F9-8B13-4A52-B80E-9EEC1BFFED99}.Release|x64.ActiveCfg = Release|x64
+		{47EC92F9-8B13-4A52-B80E-9EEC1BFFED99}.Release|x64.Build.0 = Release|x64
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/TestAPI/Test.2013.vcxproj b/TestAPI/Test.2013.vcxproj
new file mode 100644
index 0000000..e60d12e
--- /dev/null
+++ b/TestAPI/Test.2013.vcxproj
@@ -0,0 +1,265 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectName>Test</ProjectName>
+    <ProjectGuid>{47EC92F9-8B13-4A52-B80E-9EEC1BFFED99}</ProjectGuid>
+    <RootNamespace>Test</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>12.0.21005.1</_ProjectFileVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Midl>
+      <TypeLibraryName>.\Release/Test.tlb</TypeLibraryName>
+      <HeaderFileName />
+    </Midl>
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <AdditionalIncludeDirectories>../Dist/x32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;FREEIMAGE_LIB;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader />
+      <PrecompiledHeaderOutputFile>.\Release/Test.pch</PrecompiledHeaderOutputFile>
+      <AssemblerListingLocation>.\Release/</AssemblerListingLocation>
+      <ObjectFileName>.\Release/</ObjectFileName>
+      <ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Link>
+      <AdditionalDependencies>..\Dist\x32\FreeImageLib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <ProgramDatabaseFile>.\Release/Test.pdb</ProgramDatabaseFile>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention />
+      <TargetMachine>MachineX86</TargetMachine>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+      <TypeLibraryName>.\Release/Test.tlb</TypeLibraryName>
+      <HeaderFileName />
+    </Midl>
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <AdditionalIncludeDirectories>../Dist/x64;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;FREEIMAGE_LIB;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader />
+      <PrecompiledHeaderOutputFile>.\Release/Test.pch</PrecompiledHeaderOutputFile>
+      <AssemblerListingLocation>.\Release/</AssemblerListingLocation>
+      <ObjectFileName>.\Release/</ObjectFileName>
+      <ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Link>
+      <AdditionalDependencies>..\Dist\x64\FreeImageLib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <ProgramDatabaseFile>.\Release/Test.pdb</ProgramDatabaseFile>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention />
+      <TargetMachine>MachineX64</TargetMachine>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Midl>
+      <TypeLibraryName>.\Debug/Test.tlb</TypeLibraryName>
+      <HeaderFileName />
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>../Dist/x32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;FREEIMAGE_LIB;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <BrowseInformation>true</BrowseInformation>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Link>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <AdditionalLibraryDirectories>../Dist;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
+      <SubSystem>Console</SubSystem>
+      <DataExecutionPrevention />
+      <TargetMachine>MachineX86</TargetMachine>
+      <AdditionalDependencies>..\Dist\x32\FreeImageLibd.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+      <TypeLibraryName>.\Debug/Test.tlb</TypeLibraryName>
+      <HeaderFileName />
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>../Dist/x64;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;FREEIMAGE_LIB;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <PrecompiledHeader />
+      <PrecompiledHeaderOutputFile>.\Debug/Test.pch</PrecompiledHeaderOutputFile>
+      <BrowseInformation>true</BrowseInformation>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Link>
+      <AdditionalDependencies>..\Dist\x64\FreeImageLibd.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <AdditionalLibraryDirectories>../Dist;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
+      <SubSystem>Console</SubSystem>
+      <DataExecutionPrevention />
+      <TargetMachine>MachineX64</TargetMachine>
+      <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClInclude Include="..\Source\FreeImage.h" />
+    <ClInclude Include="TestSuite.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="MainTestSuite.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="testChannels.cpp" />
+    <ClCompile Include="testHeaderOnly.cpp" />
+    <ClCompile Include="testImageType.cpp" />
+    <ClCompile Include="testJPEG.cpp" />
+    <ClCompile Include="testMemIO.cpp" />
+    <ClCompile Include="testMPage.cpp" />
+    <ClCompile Include="testMPageMemory.cpp" />
+    <ClCompile Include="testMPageStream.cpp" />
+    <ClCompile Include="testPlugins.cpp" />
+    <ClCompile Include="testThumbnail.cpp" />
+    <ClCompile Include="testTools.cpp" />
+    <ClCompile Include="testWrappedBuffer.cpp" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/TestAPI/TestSuite.h b/TestAPI/TestSuite.h
index 6ef6c26..6dd886f 100644
--- a/TestAPI/TestSuite.h
+++ b/TestAPI/TestSuite.h
@@ -87,6 +87,10 @@ void testImageChannels(unsigned width, unsigned height);
 // ==========================================================
 void testThumbnail(const char *lpszPathName, int flags);
 
+// Wrapped buffer test suite
+// ==========================================================
+
+void testWrappedBuffer(const char *lpszPathName, int flags);
 
 #endif // TEST_FREEIMAGE_API_H
 
diff --git a/TestAPI/exif.jxr b/TestAPI/exif.jxr
new file mode 100644
index 0000000..05f95b3
Binary files /dev/null and b/TestAPI/exif.jxr differ
diff --git a/TestAPI/testJPEG.cpp b/TestAPI/testJPEG.cpp
index b655f41..798033d 100644
--- a/TestAPI/testJPEG.cpp
+++ b/TestAPI/testJPEG.cpp
@@ -66,11 +66,132 @@ void testJPEGTransform(const char *src_file) {
 }
 
 void testJPEGCrop(const char *src_file) {
+	int left, top, right, bottom;
 	BOOL bResult;
-	bResult = FreeImage_JPEGCrop(src_file, "test.jpg", 50, 100, 359, 354);
+
+	// perfect transformation
+	left = 50; top = 100; right = 359; bottom = 354;
+	bResult = FreeImage_JPEGCrop(src_file, "test.jpg", left, top, right, bottom);
+	assert(bResult);
+
+	// non perfect transformation (crop rectangle is adjusted automatically)
+	left = 50; top = 100; right = 650; bottom = 500;
+	bResult = FreeImage_JPEGCrop(src_file, "test.jpg", left, top, right, bottom);
 	assert(bResult);
-	bResult = FreeImage_JPEGCrop(src_file, "test.jpg", 50, 100, 650, 500);
+}
+
+void testJPEGTransformCombined(const char *src_file, const char *dst_file) {
+	BOOL bResult;
+	BOOL perfect;
+	int left, top, right, bottom;
+
+	// perfect transformation required
+	perfect = TRUE;
+
+	// (optionnal) simulate the transform and get the new rectangle coordinates (adjusted to the iMCU size)
+	// then apply the transform
+
+	left = 50; top = 100; right = 359; bottom = 354;
+	bResult = FreeImage_JPEGTransformCombined(src_file, NULL, FIJPEG_OP_FLIP_H, &left, &top, &right, &bottom, perfect);
+	assert(bResult == FALSE);
+	bResult = FreeImage_JPEGTransformCombined(src_file, dst_file, FIJPEG_OP_FLIP_H, &left, &top, &right, &bottom, perfect);
+	assert(bResult == FALSE);
+
+	left = 50; top = 100; right = 359; bottom = 354;
+	bResult = FreeImage_JPEGTransformCombined(src_file, NULL, FIJPEG_OP_FLIP_V, &left, &top, &right, &bottom, perfect);
+	assert(bResult == TRUE);
+	bResult = FreeImage_JPEGTransformCombined(src_file, dst_file, FIJPEG_OP_FLIP_V, &left, &top, &right, &bottom, perfect);
+	assert(bResult == TRUE);
+
+	left = 50; top = 100; right = 359; bottom = 354;
+	bResult = FreeImage_JPEGTransformCombined(src_file, NULL, FIJPEG_OP_TRANSPOSE, &left, &top, &right, &bottom, perfect);
+	assert(bResult == TRUE);
+	bResult = FreeImage_JPEGTransformCombined(src_file, dst_file, FIJPEG_OP_TRANSPOSE, &left, &top, &right, &bottom, perfect);
+	assert(bResult == TRUE);
+
+	left = 50; top = 100; right = 359; bottom = 354;
+	bResult = FreeImage_JPEGTransformCombined(src_file, NULL, FIJPEG_OP_TRANSVERSE, &left, &top, &right, &bottom, perfect);
+	assert(bResult == FALSE);
+	bResult = FreeImage_JPEGTransformCombined(src_file, dst_file, FIJPEG_OP_TRANSVERSE, &left, &top, &right, &bottom, perfect);
+	assert(bResult == FALSE);
+
+	left = 50; top = 100; right = 359; bottom = 354;
+	bResult = FreeImage_JPEGTransformCombined(src_file, NULL, FIJPEG_OP_ROTATE_90, &left, &top, &right, &bottom, perfect);
+	assert(bResult == TRUE);
+	bResult = FreeImage_JPEGTransformCombined(src_file, dst_file, FIJPEG_OP_ROTATE_90, &left, &top, &right, &bottom, perfect);
+	assert(bResult == TRUE);
+
+	left = 50; top = 100; right = 359; bottom = 354;
+	bResult = FreeImage_JPEGTransformCombined(src_file, NULL, FIJPEG_OP_ROTATE_180, &left, &top, &right, &bottom, perfect);
+	assert(bResult == FALSE);
+	bResult = FreeImage_JPEGTransformCombined(src_file, dst_file, FIJPEG_OP_ROTATE_180, &left, &top, &right, &bottom, perfect);
+	assert(bResult == FALSE);
+
+	left = 50; top = 100; right = 359; bottom = 354;
+	bResult = FreeImage_JPEGTransformCombined(src_file, NULL, FIJPEG_OP_ROTATE_270, &left, &top, &right, &bottom, perfect);
 	assert(bResult == FALSE);
+	bResult = FreeImage_JPEGTransformCombined(src_file, dst_file, FIJPEG_OP_ROTATE_270, &left, &top, &right, &bottom, perfect);
+	assert(bResult == FALSE);
+
+	// perfect transformation NOT required
+	perfect = FALSE;
+
+	// (optionnal) simulate the transform and get the new rectangle coordinates (adjusted to the iMCU size)
+	// then apply the transform
+
+	left = 50; top = 100; right = 650; bottom = 500;
+	bResult = FreeImage_JPEGTransformCombined(src_file, NULL, FIJPEG_OP_FLIP_H, &left, &top, &right, &bottom, perfect);
+	assert(bResult == TRUE);
+	bResult = FreeImage_JPEGTransformCombined(src_file, dst_file, FIJPEG_OP_FLIP_H, &left, &top, &right, &bottom, perfect);
+	assert(bResult == TRUE);
+
+	left = 50; top = 100; right = 650; bottom = 500;
+	bResult = FreeImage_JPEGTransformCombined(src_file, NULL, FIJPEG_OP_FLIP_V, &left, &top, &right, &bottom, perfect);
+	assert(bResult == TRUE);
+	bResult = FreeImage_JPEGTransformCombined(src_file, dst_file, FIJPEG_OP_FLIP_V, &left, &top, &right, &bottom, perfect);
+	assert(bResult == TRUE);
+
+	left = 50; top = 100; right = 650; bottom = 500;
+	bResult = FreeImage_JPEGTransformCombined(src_file, NULL, FIJPEG_OP_TRANSPOSE, &left, &top, &right, &bottom, perfect);
+	assert(bResult == TRUE);
+	bResult = FreeImage_JPEGTransformCombined(src_file, dst_file, FIJPEG_OP_TRANSPOSE, &left, &top, &right, &bottom, perfect);
+	assert(bResult == TRUE);
+
+	left = 50; top = 100; right = 650; bottom = 500;
+	bResult = FreeImage_JPEGTransformCombined(src_file, NULL, FIJPEG_OP_TRANSVERSE, &left, &top, &right, &bottom, perfect);
+	assert(bResult == TRUE);
+	bResult = FreeImage_JPEGTransformCombined(src_file, dst_file, FIJPEG_OP_TRANSVERSE, &left, &top, &right, &bottom, perfect);
+	assert(bResult == TRUE);
+
+	left = 50; top = 100; right = 650; bottom = 500;
+	bResult = FreeImage_JPEGTransformCombined(src_file, NULL, FIJPEG_OP_ROTATE_90, &left, &top, &right, &bottom, perfect);
+	assert(bResult == TRUE);
+	bResult = FreeImage_JPEGTransformCombined(src_file, dst_file, FIJPEG_OP_ROTATE_90, &left, &top, &right, &bottom, perfect);
+	assert(bResult == TRUE);
+
+	left = 50; top = 100; right = 650; bottom = 500;
+	bResult = FreeImage_JPEGTransformCombined(src_file, NULL, FIJPEG_OP_ROTATE_180, &left, &top, &right, &bottom, perfect);
+	assert(bResult == TRUE);
+	bResult = FreeImage_JPEGTransformCombined(src_file, dst_file, FIJPEG_OP_ROTATE_180, &left, &top, &right, &bottom, perfect);
+	assert(bResult == TRUE);
+
+	left = 50; top = 100; right = 650; bottom = 500;
+	bResult = FreeImage_JPEGTransformCombined(src_file, NULL, FIJPEG_OP_ROTATE_270, &left, &top, &right, &bottom, perfect);
+	assert(bResult == TRUE);
+	bResult = FreeImage_JPEGTransformCombined(src_file, dst_file, FIJPEG_OP_ROTATE_270, &left, &top, &right, &bottom, perfect);
+	assert(bResult == TRUE);
+}
+
+void testJPEGSameFile(const char *src_file) {
+	BOOL bResult;
+	BOOL perfect;
+
+	// perfect transformation
+	perfect = TRUE;
+	bResult = FreeImage_JPEGTransform(src_file, "test.jpg", FIJPEG_OP_ROTATE_90, perfect);
+	assert(bResult);
+	bResult = FreeImage_JPEGTransform("test.jpg", "test.jpg", FIJPEG_OP_ROTATE_270, perfect);
+	assert(bResult);
 }
 
 // Main test function
@@ -83,6 +204,13 @@ void testJPEG() {
 
 	// lossless transform - both perfect/non perfect
 	testJPEGTransform(src_file);
+
 	// cropping - both perfect/non perfect
 	testJPEGCrop(src_file);
+
+	// lossless transform + cropping - both perfect/non perfect
+	testJPEGTransformCombined(src_file, "test.jpg");
+
+	// using the same file for src & dst is allowed
+	testJPEGSameFile(src_file);
 }
diff --git a/TestAPI/testMemIO.cpp b/TestAPI/testMemIO.cpp
index 5a16576..314e499 100644
--- a/TestAPI/testMemIO.cpp
+++ b/TestAPI/testMemIO.cpp
@@ -35,8 +35,9 @@ void testSaveMemIO(const char *lpszPathName) {
 	// save the file to memory
 	FreeImage_SaveToMemory(fif, dib, hmem, 0);
 
-	// at this point, hmem contains the entire PNG data in memory. 
+	// at this point, hmem contains the entire FREE_IMAGE_FORMAT data in memory. 
 	// the amount of space used by the memory is equal to file_size
+	FreeImage_SeekMemory(hmem, 0, SEEK_END);
 	long file_size = FreeImage_TellMemory(hmem);
 	printf("File size : %ld\n", file_size);
 
diff --git a/TestAPI/testThumbnail.cpp b/TestAPI/testThumbnail.cpp
index 61e5c0e..794ee97 100644
--- a/TestAPI/testThumbnail.cpp
+++ b/TestAPI/testThumbnail.cpp
@@ -120,7 +120,7 @@ static BOOL testSaveThumbnail(const char *lpszPathName, int flags) {
 }
 
 /**
-Thest thumbnail functions
+Test thumbnail functions
 */
 void testThumbnail(const char *lpszPathName, int flags) {
 	BOOL bResult = FALSE;
diff --git a/TestAPI/testWrappedBuffer.cpp b/TestAPI/testWrappedBuffer.cpp
new file mode 100644
index 0000000..a84c767
--- /dev/null
+++ b/TestAPI/testWrappedBuffer.cpp
@@ -0,0 +1,114 @@
+// ==========================================================
+// FreeImage 3 Test Script
+//
+// Design and implementation by
+// - Herv� Drolon (drolon at infonie.fr)
+//
+// This file is part of FreeImage 3
+//
+// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
+// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
+// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
+// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
+// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
+// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
+// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+// THIS DISCLAIMER.
+//
+// Use at your own risk!
+// ==========================================================
+
+
+#include "TestSuite.h"
+
+// Local test functions
+// ----------------------------------------------------------
+
+static void testBasicWrapper(BOOL copySource, BYTE *bits, FREE_IMAGE_TYPE type, int width, int height, int pitch, unsigned bpp) {
+	FIBITMAP *src = NULL;
+	FIBITMAP *clone = NULL;
+	FIBITMAP *dst = NULL;
+
+	// allocate a wrapper
+	src = FreeImage_ConvertFromRawBitsEx(copySource, bits, type, width, height, pitch, bpp, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, FALSE);
+	assert(src != NULL);
+	
+	// test clone
+	clone = FreeImage_Clone(src);
+	assert(clone != NULL);
+
+	// test in-place processing
+	FreeImage_Invert(src);
+
+	// test processing
+	dst = FreeImage_ConvertToFloat(src);
+	assert(dst != NULL);
+
+	FreeImage_Unload(dst);
+	FreeImage_Unload(clone);
+
+	// unload the wrapper
+	FreeImage_Unload(src);
+}
+
+static void testViewport(FIBITMAP *dib) {
+	FIBITMAP *src = NULL;
+	
+	// define a viewport as [vp_x, vp_y, vp_width, vp_height]
+	// (assume the image is larger than the viewport)
+	int vp_width = 300;
+	int vp_height = 200;
+	int vp_x = FreeImage_GetWidth(dib) / 2 - vp_width / 2;
+	int vp_y = FreeImage_GetHeight(dib) / 2 - vp_height / 2;
+	
+	// point the viewport data
+	unsigned bytes_per_pixel = FreeImage_GetLine(dib) / FreeImage_GetWidth(dib);
+	BYTE *data = FreeImage_GetBits(dib) + vp_y * FreeImage_GetPitch(dib) + vp_x * bytes_per_pixel;
+
+	// wrap a section (no copy)
+	src = FreeImage_ConvertFromRawBitsEx(FALSE/*copySource*/, data, FIT_BITMAP, vp_width, vp_height, FreeImage_GetPitch(dib), FreeImage_GetBPP(dib), FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
+
+	// save the section (note that the image is inverted due to previous processing)
+	FreeImage_Save(FIF_PNG, src, "viewport.png");
+	
+	// unload the wrapper
+	FreeImage_Unload(src);
+}
+
+// Main test functions
+// ----------------------------------------------------------
+
+void testWrappedBuffer(const char *lpszPathName, int flags) {
+	FIBITMAP *dib = NULL;
+
+	// simulate a user provided buffer
+	// -------------------------------
+	
+	// load the dib
+	FREE_IMAGE_FORMAT fif = FreeImage_GetFileType(lpszPathName);
+	dib = FreeImage_Load(fif, lpszPathName, flags); 
+	assert(dib != NULL);
+
+	// get data info
+	FREE_IMAGE_TYPE type = FreeImage_GetImageType(dib);
+	unsigned width = FreeImage_GetWidth(dib);
+	unsigned height = FreeImage_GetHeight(dib);
+	unsigned pitch = FreeImage_GetPitch(dib);
+	unsigned bpp = FreeImage_GetBPP(dib);
+	BYTE *bits = FreeImage_GetBits(dib);
+
+	// test wrapped buffer manipulations
+	// -------------------------------
+
+	testBasicWrapper(TRUE /*copySource*/, bits, type, width, height, pitch, bpp);
+
+	testBasicWrapper(FALSE /*copySource*/, bits, type, width, height, pitch, bpp);
+
+	// test another use-case : viewport
+	testViewport(dib);
+
+	// unload the user provided buffer
+	// -------------------------------
+	FreeImage_Unload(dib);
+}
diff --git a/Whatsnew.txt b/Whatsnew.txt
index dbcbdc1..8351545 100644
--- a/Whatsnew.txt
+++ b/Whatsnew.txt
@@ -5,6 +5,92 @@ What's New for FreeImage
 ! : changed
 + : added
 
+March 15th, 2015 - 3.17.0
+! FreeImage now uses LibPNG 1.6.16
+! FreeImage now uses LibWebP 0.4.2 (GIT patch 2015-03-03)
+! FreeImage now uses LibRaw 0.17-Alpha1
+! FreeImage now uses LibTIFF 4.0.4 (CVS patch 2015-01-26)
+! FreeImage now uses OpenEXR 2.2.0
+- [Herve Drolon] removed VS 2003 project files : this IDE is no longer supported because of its outdated C++ compiler
++ [Mihail Naydenov] added FreeImage_ConvertFromRawBitsEx
++ [Herve Drolon] added RAW_UNPROCESSED load flag to the RAW plugin
++ [Herve Drolon] added FreeImage_SetMetadataKeyValue
++ [Herve Drolon] added support for metadata writing to the JPEG-JXR plugin
++ [Herve Drolon] added VS 2013 project files
++ [Herve Drolon] added support for PNG tIME metadata (read/write, handle as Exif-TIFF DateTime)
++ [Carsten Klein] added explicit definition of endianness and color order in compiler options
++ [Carsten Klein] added FIQ_LFPQUANT quantizer algorithm
++ [Carsten Klein] added support for input 32-bit dib in Wu quantizer
++ [Tanner Helland] added FreeImage_ConvertToRGBAF and updated conversions in FreeImage_ConvertToType
++ [Herve Drolon] added FreeImage_ConvertToRGBA16 and updated conversions in FreeImage_ConvertToType
++ [Carsten Klein] added FreeImage_CreateView
++ [Carsten Klein] added FreeImage_RescaleRect
++ [Carsten Klein] added FreeImage_GetMemorySize
+* [Tanner Helland] ICO plugin: improved support for Vista icons
+* [fpgaminer] fixed a rounding error in RGB to greyscale conversion formula
+* [Sven-Hendrik Haase] fixed Makefile.fip so that it installs symlinks
+* [Joachim Reichel] fixed a potential memory access violation in PluginHDR Save function
+* [Christian Schluchter] fixed a bug in FreeImage_LookupSVGColor ("green" color was not found)
+* [Marco Altomonte] fixed TARGA signature validation for TARGA versions < 2.0
+* [Jeremy Reyniers] fixed FreeImage_GetScanLine not working with very large images on x64 platforms
+* [Herve Drolon] improved PluginTIFF compatibility with LibTIFF 4
+* [Aaron Shumate] fixed a segfault occuring on a corrupted animated GIF
+* [Herve Drolon] improved memory allocation in PluginRAW
+* [Herve Drolon] fixed loading/saving of TIFF containing a GPS IFD inside the Exif-TIFF metadata segment (the solution is to ignore the tag) 
+* [Mihail Naydenov] fixed a bug in FreeImage_JPEGCrop*/_JPEGTransform* functions occuring when using the same source / destination filename
+* [Herve Drolon] fixed a bug with output image quality in PluginJP2::Save & PluginJ2K::Save functions (regression from FI 3.15.4)
+* [Herve Drolon] improved RAW file format detection
+* [Aaron Shumate] fixed FreeImage_GetFileType behavior with ANI file formats
+* [Herve Drolon] improved Exif reader so as to handle Exif IFD with a suspicious offset (can occur with maker notes)
+* [Herve Drolon] fixed a memory leak in PluginPNG:Save occuring when dealing with invalid PNG files
+* [Tanner Helland] fixed PNG plugin handling of 16-bit grayscale + 16-bit alpha images
+* [Tanner Helland] fixed PNG plugin handling of 16-bit grayscale + tRNS chunk images
+* [Tanner Helland] fixed PNG plugin handling of 24-bit RGB + tRNS chunk images
+* [Tanner Helland] fixed PNG plugin handling of 1-,4-bit greyscale/palettized + tRNS chunk images
+* [ekpyron] fixed invalid directory delimiter in include statement (mingw-w64) in Source/LibJXR/image/sys/strcodec.h
+* [ekpyron] fixed Invalid condition for defining _byteswap_ulong (mingw-w64) in Source/LibJXR/image/sys/strcodec.c
+* [tostercx] fixed FreeImage_Get*Mask not returning 0 for greyscale images
+* [robpats] fixed loading of external plugins when using UNICODE directory names to store plugins
+* [Herve Drolon] fixed loading of JXR files when using memory streams
+* [Carsten Klein] added Dist/ directory creation in Makefiles (in case it is not already present)
+
+March 23rd, 2014 - 3.16.0
+! FreeImage now uses LibJPEG 9a
+! FreeImage now uses LibPNG 1.6.10
+! FreeImage now uses LibTIFF 4.0.3 (CVS patch 2013-11-30)
+! FreeImage now uses LibRaw 0.16.0
+! FreeImage now uses OpenJPEG 2.1.0 (SVN patch 2748)
+! FreeImage now uses ZLib 1.2.8
+! FreeImage now uses LibWebP 0.4.0 (GIT patch 2014-03-21)
+! FreeImage now uses LibJXR 1.1 (GIT patch 2014-01-31)
++ [Herve Drolon] added loading & writing support for the JPEG-XR image format (also support the FIF_LOAD_NOPIXELS flag)
++ [Herve Drolon] added loading & writing support for the WebP image format (also support the FIF_LOAD_NOPIXELS flag)
++ [Herve Drolon] added support for FIF_LOAD_NOPIXELS flag to JP2/J2K plugins
++ [Ga�l Zimmermann] added basic support for BMP v4, v5 in BMP plugin (useful for drag and drop from another application such as Firefox)
++ [Mihail Naydenov] FreeImage_GetFIFFromFilename[U] : added support for *rgb,*rgba,*.bw extensions to the SGI plugin
++ [Mihail Naydenov] improved FreeImage_Rescale speed & spatial accuracy
++ [Mihail Naydenov] improved JPEG transform functions and added new functions (see below) :
+		added FreeImage_JPEGTransformFromHandle
+		added FreeImage_JPEGTransformCombined
+		added FreeImage_JPEGTransformCombinedU
+		added FreeImage_JPEGTransformCombinedFromMemory
+* [Herve Drolon] fixed FreeImage_CloneTag behavior with ASCII data handling (regression that appeared in 3.15.2, affect metadata writing)
+* [Carsten Klein] ICO plugin: avoid using the AND mask when loading a 32-bit (already transparent) icon
+* [Andreas Baumann] HDR plugin: removed a comma at end of an enumerator list
+* [mark] added missing <string.h> in OpenEXR (needed with mingw)
+* [Herve Drolon] added support for FIC_MINISWHITE color type inside FreeImage_GetColorType for FIT_UINT16 images
+* [Takamasa Mitsuji] FreeImage_Rescale : fixed a NULL-pointer access bug occurring for transparent images with a linear palette
+* [Herve Drolon] fixed PSD parser when reading PSD files with corrupted resources
+* [Herve Drolon] fixed TIFF plugin truncating metadata tag on loading if type is ASCII and it's value is of variable size (TIFF_VARIABLE) 
+* [Herve Drolon] fixed loading of TGA 8-bit files with a palette size greater that 256
+* [Anton Kukoba] TIFF parser didn't initialize the memory with zeros in stripped mode. This caused random bitmap data if the tiff file was corrupted/invalid.
+* [Herve Drolon] improved TGA file detection when the format version is < 2.0
+* [Christian Heimes] fixed compiler errors on 64bit Linux (INT64 / UINT64 type mismatches and missing prototype for memset)
+* [Christian Heimes] fixed FreeImage_Get*Mask() returning 0 on 24-, -32-bit FIT_BITMAP images
+* [Mihail Naydenov] fixed GIF plugin LZW decoder failing on some images
+* [Herve Drolon] fixed the TIFF plugin against race condition when used simultaneously in multiple threads
+* [Herve Drolon]  fixed float <--> rgb[a]f conversions when pixels are out of [0..1] range
+
 October 27th, 2012 - 3.15.4
 ! FreeImage now uses LibPNG 1.5.13
 ! FreeImage now uses LibRaw 0.14.7
diff --git a/Wrapper/Delphi/WhatsNew_Delphi.txt b/Wrapper/Delphi/WhatsNew_Delphi.txt
index a27d6a8..5cce257 100644
--- a/Wrapper/Delphi/WhatsNew_Delphi.txt
+++ b/Wrapper/Delphi/WhatsNew_Delphi.txt
@@ -5,6 +5,14 @@ What's New for FreeImage Delphi Wrapper
 ! : changed
 + : added
 
+May 5, 2014
++ [Lorenzo Monti] updated wrapper for FreeImage 3.16.1
++ [Lorenzo Monti] added preprocessor tests for Delphi XE2..XE6
++ [Lorenzo Monti] merged changes for OSX compatibility (submitted by Maur�cio)
+
+December 8, 2012
++ [Lorenzo Monti] updated wrapper for FreeImage 3.15.4
+
 June 4, 2012
 + [Lorenzo Monti] updated wrapper for FreeImage 3.15.3
 
diff --git a/Wrapper/Delphi/src/FreeBitmap.pas b/Wrapper/Delphi/src/FreeBitmap.pas
index ad74ebf..582e2ae 100644
--- a/Wrapper/Delphi/src/FreeBitmap.pas
+++ b/Wrapper/Delphi/src/FreeBitmap.pas
@@ -10,6 +10,7 @@ unit FreeBitmap;
 // Contributors:
 // - Enzo Costantini (enzocostantini at libero.it)
 // - Lorenzo Monti (LM)  lomo74 at gmail.com
+// - Maur�cio (MAU)      mauricio_box at yahoo.com - see also http://sourceforge.net/projects/tcycomponents/
 //
 // Revision history
 // When        Who   What
@@ -25,6 +26,7 @@ unit FreeBitmap;
 //                     - TFreeBitmap.IsGrayScale
 //                     - TFreeWinBitmap.CopyFromBitmap
 //                     - TFreeMultiBitmap.Open
+// 2013-11-25  MAU   Added type FreeImageAnsiString for handling accents on MAC OSX filenames/path
 
 // This file is part of FreeImage 3
 //
@@ -138,14 +140,14 @@ type
     function CopySubImage(Left, Top, Right, Bottom: Integer; Dest: TFreeBitmap): Boolean;
     function PasteSubImage(Src: TFreeBitmap; Left, Top: Integer; Alpha: Integer = 256): Boolean;
     procedure Clear; virtual;
-    function Load(const FileName: AnsiString; Flag: Integer = 0): Boolean;
+    function Load(const FileName: FreeImageAnsiString; Flag: Integer = 0): Boolean;
     function LoadU(const FileName: {$IFDEF DELPHI2010}string{$ELSE}WideString{$ENDIF}; Flag: Integer = 0): Boolean;
     function LoadFromHandle(IO: PFreeImageIO; Handle: fi_handle; Flag: Integer = 0): Boolean;
     function LoadFromMemory(MemIO: TFreeMemoryIO; Flag: Integer = 0): Boolean;
     function LoadFromStream(Stream: TStream; Flag: Integer = 0): Boolean;
     // save functions
     function CanSave(fif: FREE_IMAGE_FORMAT): Boolean;
-    function Save(const FileName: AnsiString; Flag: Integer = 0): Boolean;
+    function Save(const FileName: FreeImageAnsiString; Flag: Integer = 0): Boolean;
     function SaveU(const FileName: {$IFDEF DELPHI2010}string{$ELSE}WideString{$ENDIF}; Flag: Integer = 0): Boolean;
     function SaveToHandle(fif: FREE_IMAGE_FORMAT; IO: PFreeImageIO; Handle: fi_handle; Flag: Integer = 0): Boolean;
     function SaveToMemory(fif: FREE_IMAGE_FORMAT; MemIO: TFreeMemoryIO; Flag: Integer = 0): Boolean;
@@ -292,7 +294,7 @@ type
     destructor Destroy; override;
 
     // methods
-    function Open(const FileName: AnsiString; CreateNew, ReadOnly: Boolean; Flags: Integer = 0): Boolean;
+    function Open(const FileName: FreeImageAnsiString; CreateNew, ReadOnly: Boolean; Flags: Integer = 0): Boolean;
     function Close(Flags: Integer = 0): Boolean;
     function GetPageCount: Integer;
     procedure AppendPage(Bitmap: TFreeBitmap);
@@ -899,13 +901,13 @@ begin
   Result := FDib <> nil
 end;
 
-function TFreeBitmap.Load(const FileName: AnsiString; Flag: Integer): Boolean;
+function TFreeBitmap.Load(const FileName: FreeImageAnsiString; Flag: Integer): Boolean;
 var
   fif: FREE_IMAGE_FORMAT;
 begin
 
   // check the file signature and get its format
-  fif := FreeImage_GetFileType(PAnsiChar(Filename), 0);
+  fif := FreeImage_GetFileType(PAnsiChar(FileName), 0);
   if fif = FIF_UNKNOWN then
     // no signature?
     // try to guess the file format from the file extention
@@ -1287,14 +1289,14 @@ begin
   end;
 end;
 
-function TFreeBitmap.Save(const FileName: AnsiString; Flag: Integer): Boolean;
+function TFreeBitmap.Save(const FileName: FreeImageAnsiString; Flag: Integer): Boolean;
 var
   fif: FREE_IMAGE_FORMAT;
 begin
   Result := False;
 
   // try to guess the file format from the file extension
-  fif := FreeImage_GetFIFFromFilename(PAnsiChar(Filename));
+  fif := FreeImage_GetFIFFromFilename(PAnsiChar(FileName));
   if CanSave(fif) then
     Result := FreeImage_Save(fif, FDib, PAnsiChar(FileName), Flag);
 end;
@@ -1949,7 +1951,7 @@ begin
   Result := FreeImage_MovePage(FMPage, Target, Source);
 end;
 
-function TFreeMultiBitmap.Open(const FileName: AnsiString; CreateNew,
+function TFreeMultiBitmap.Open(const FileName: FreeImageAnsiString; CreateNew,
   ReadOnly: Boolean; Flags: Integer): Boolean;
 var
   fif: FREE_IMAGE_FORMAT;
@@ -1959,7 +1961,8 @@ begin
 // modif NOVAXEL
 // In order to try to get the file format even if the extension is not standard,
 // we check first the file signature
-  fif := FreeImage_GetFileType(PAnsiChar(Filename), 0);
+  fif := FreeImage_GetFileType(PAnsiChar(FileName), 0);
+
   if fif = FIF_UNKNOWN then
     // no signature?
 // end of modif NOVAXEL
diff --git a/Wrapper/Delphi/src/FreeImage.pas b/Wrapper/Delphi/src/FreeImage.pas
index 0a844ea..66f0408 100644
--- a/Wrapper/Delphi/src/FreeImage.pas
+++ b/Wrapper/Delphi/src/FreeImage.pas
@@ -10,6 +10,7 @@ unit FreeImage;
 //
 // Contributors:
 // - Lorenzo Monti (LM)  lomo74 at gmail.com
+// - Maur�cio (MAU)      mauricio_box at yahoo.com - see also http://sourceforge.net/projects/tcycomponents/
 //
 // Revision history
 // When        Who   What
@@ -28,6 +29,10 @@ unit FreeImage;
 //                   - as linux sees the difference between uppercase and lowercase :
 //                    ==> replace FreeImage_GetMetaData with FreeImage_GetMetadata in the call to the freeimage library
 // 2012-06-04  LM    Updated to 3.15.3
+// 2012-12-08  LM    Updated to 3.15.4
+// 2013-05-06  MAU   Corrected calls definition to MAC OSX library
+// 2013-11-25  MAU   Added type FreeImageAnsiString for handling accents on MAC OSX filenames/path
+// 2014-05-05  LM    Updated to 3.16.1
 //
 
 //
@@ -54,11 +59,19 @@ interface
 
 {$IFDEF MSWINDOWS}
 uses Windows;
+
+type
+  FreeImageAnsiString = AnsiString;
+
 {$ELSE}
 type
+  FreeImageAnsiString = UTF8String;
+
   LONG = LongInt;
   DWORD = Cardinal;
 
+  PDWORD = ^DWORD;
+
   BITMAPINFOHEADER = record
     biSize : DWORD;
     biWidth : LONG;
@@ -103,12 +116,13 @@ type
 const
   FIDLL = {$IFDEF MSWINDOWS}'FreeImage.dll';{$ENDIF}
           {$IFDEF LINUX}'libfreeimage.so';{$ENDIF}
+          {$IFDEF MACOS}'libfreeimage.dylib';{$ENDIF}
 
 const
   // Version information
   FREEIMAGE_MAJOR_VERSION  = 3;
-  FREEIMAGE_MINOR_VERSION  = 15;
-  FREEIMAGE_RELEASE_SERIAL = 3;
+  FREEIMAGE_MINOR_VERSION  = 16;
+  FREEIMAGE_RELEASE_SERIAL = 1;
   // This really only affects 24 and 32 bit formats, the rest are always RGB order.
   FREEIMAGE_COLORORDER_BGR = 0;
   FREEIMAGE_COLORORDER_RGB = 1;
@@ -290,6 +304,8 @@ const
   FIF_PFM     = FREE_IMAGE_FORMAT(32);
   FIF_PICT    = FREE_IMAGE_FORMAT(33);
   FIF_RAW     = FREE_IMAGE_FORMAT(34);
+  FIF_WEBP    = FREE_IMAGE_FORMAT(35);
+  FIF_JXR     = FREE_IMAGE_FORMAT(36);
 
   // Image type used in FreeImage.
   FIT_UNKNOWN = FREE_IMAGE_TYPE(0);  // unknown type
@@ -418,12 +434,12 @@ type
   fi_handle = Pointer;
 
   FI_ReadProc = function(buffer: Pointer; size, count: Cardinal;
-    handle: fi_handle): Cardinal; stdcall;
+    handle: fi_handle): Cardinal; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
   FI_WriteProc = function(buffer: Pointer; size, count: Cardinal;
-    handle: fi_handle): Cardinal; stdcall;
+    handle: fi_handle): Cardinal; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
   FI_SeekProc = function(handle: fi_handle; offset: LongInt;
-    origin: Integer): Integer; stdcall;
-  FI_TellProc = function(handle: fi_handle): LongInt; stdcall;
+    origin: Integer): Integer; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  FI_TellProc = function(handle: fi_handle): LongInt; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
 
   FreeImageIO = packed record
     read_proc : FI_ReadProc;     // pointer to the function used to read data
@@ -445,10 +461,10 @@ const
   SEEK_CUR = 1;
   SEEK_END = 2;
 
-type
+//type
   // define portable types for 32-bit / 64-bit OS
-  FIINT64 = Int64;
-  FIUINT64 = UInt64;
+  //FIINT64 = Int64;
+  //FIUINT64 = UInt64;
 
 // --------------------------------------------------------------------------
 // Plugin routines ----------------------------------------------------------
@@ -457,28 +473,28 @@ type
 type
   PPlugin = ^Plugin;
 
-  FI_FormatProc = function: PAnsiChar; stdcall;
-  FI_DescriptionProc = function: PAnsiChar; stdcall;
-  FI_ExtensionListProc = function: PAnsiChar; stdcall;
-  FI_RegExprProc = function: PAnsiChar; stdcall;
+  FI_FormatProc = function: PAnsiChar; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  FI_DescriptionProc = function: PAnsiChar; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  FI_ExtensionListProc = function: PAnsiChar; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  FI_RegExprProc = function: PAnsiChar; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
   FI_OpenProc = function(io: PFreeImageIO; handle: fi_handle;
-    read: LongBool): Pointer; stdcall;
+    read: LongBool): Pointer; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
   FI_CloseProc = procedure(io: PFreeImageIO; handle: fi_handle;
-    data: Pointer); stdcall;
+    data: Pointer); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
   FI_PageCountProc = function(io: PFreeImageIO; handle: fi_handle;
-    data: Pointer): Integer; stdcall;
+    data: Pointer): Integer; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
   FI_PageCapabilityProc = function(io: PFreeImageIO; handle: fi_handle;
-    data: Pointer): Integer; stdcall;
+    data: Pointer): Integer; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
   FI_LoadProc = function(io: PFreeImageIO; handle: fi_handle; page, flags: Integer;
-    data: Pointer): PFIBITMAP; stdcall;
+    data: Pointer): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
   FI_SaveProc = function(io: PFreeImageIO; dib: PFIBITMAP; handle: fi_handle;
-    page, flags: Integer; data: Pointer): LongBool; stdcall;
-  FI_ValidateProc = function(io: PFreeImageIO; handle: fi_handle): LongBool; stdcall;
-  FI_MimeProc = function: PAnsiChar; stdcall;
-  FI_SupportsExportBPPProc = function(bpp: integer): LongBool; stdcall;
-  FI_SupportsExportTypeProc = function(atype: FREE_IMAGE_TYPE): LongBool; stdcall;
-  FI_SupportsICCProfilesProc = function: LongBool; stdcall;
-  FI_SupportsNoPixelsProc = function: LongBool; stdcall;
+    page, flags: Integer; data: Pointer): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  FI_ValidateProc = function(io: PFreeImageIO; handle: fi_handle): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  FI_MimeProc = function: PAnsiChar; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  FI_SupportsExportBPPProc = function(bpp: integer): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  FI_SupportsExportTypeProc = function(_type: FREE_IMAGE_TYPE): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  FI_SupportsICCProfilesProc = function: LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  FI_SupportsNoPixelsProc = function: LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
 
   Plugin = record
     format_proc: FI_FormatProc;
@@ -499,99 +515,105 @@ type
     supports_no_pixels_proc: FI_SupportsNoPixelsProc;
   end;
 
-  FI_InitProc = procedure(aplugin: PPlugin; format_id: Integer); stdcall;
+  FI_InitProc = procedure(aplugin: PPlugin; format_id: Integer); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
 
 // --------------------------------------------------------------------------
 // Load/Save flag constants -------------------------------------------------
 // --------------------------------------------------------------------------
 
 const
-  FIF_LOAD_NOPIXELS   = $8000;  // loading: load the image header only (not supported by all plugins)
+  FIF_LOAD_NOPIXELS   = $8000;  //! loading: load the image header only (not supported by all plugins, default to full loading)
   BMP_DEFAULT         = 0;
   BMP_SAVE_RLE        = 1;
   CUT_DEFAULT         = 0;
   DDS_DEFAULT         = 0;
-  EXR_DEFAULT         = 0;      // save data as half with piz-based wavelet compression
-  EXR_FLOAT           = $0001;  // save data as float instead of as half (not recommended)
-  EXR_NONE            = $0002;  // save with no compression
-  EXR_ZIP             = $0004;  // save with zlib compression, in blocks of 16 scan lines
-  EXR_PIZ             = $0008;  // save with piz-based wavelet compression
-  EXR_PXR24           = $0010;  // save with lossy 24-bit float compression
-  EXR_B44             = $0020;  // save with lossy 44% float compression - goes to 22% when combined with EXR_LC
-  EXR_LC              = $0040;  // save images with one luminance and two chroma channels, rather than as RGB (lossy compression)
+  EXR_DEFAULT         = 0;      //! save data as half with piz-based wavelet compression
+  EXR_FLOAT           = $0001;  //! save data as float instead of as half (not recommended)
+  EXR_NONE            = $0002;  //! save with no compression
+  EXR_ZIP             = $0004;  //! save with zlib compression, in blocks of 16 scan lines
+  EXR_PIZ             = $0008;  //! save with piz-based wavelet compression
+  EXR_PXR24           = $0010;  //! save with lossy 24-bit float compression
+  EXR_B44             = $0020;  //! save with lossy 44% float compression - goes to 22% when combined with EXR_LC
+  EXR_LC              = $0040;  //! save images with one luminance and two chroma channels, rather than as RGB (lossy compression)
   FAXG3_DEFAULT       = 0;
   GIF_DEFAULT         = 0;
-  GIF_LOAD256         = 1;     // Load the image as a 256 color image with ununsed palette entries, if it's 16 or 2 color
-  GIF_PLAYBACK        = 2;     // 'Play' the GIF to generate each frame (as 32bpp) instead of returning raw frame data when loading
+  GIF_LOAD256         = 1;     //! Load the image as a 256 color image with ununsed palette entries, if it's 16 or 2 color
+  GIF_PLAYBACK        = 2;     //! 'Play' the GIF to generate each frame (as 32bpp) instead of returning raw frame data when loading
   HDR_DEFAULT         = 0;
   ICO_DEFAULT         = 0;
-  ICO_MAKEALPHA       = 1;     // convert to 32bpp and create an alpha channel from the AND-mask when loading
+  ICO_MAKEALPHA       = 1;     //! convert to 32bpp and create an alpha channel from the AND-mask when loading
   IFF_DEFAULT         = 0;
-  J2K_DEFAULT         = 0;     // save with a 16:1 rate
-  JP2_DEFAULT         = 0;     // save with a 16:1 rate
-  JPEG_DEFAULT        = 0;
-  JPEG_FAST           = 1;
-  JPEG_ACCURATE       = 2;
-  JPEG_CMYK           = $0004; // load separated CMYK "as is" (use | to combine with other flags)
-  JPEG_EXIFROTATE     = $0008; // load and rotate according to Exif 'Orientation' tag if available
-  JPEG_QUALITYSUPERB  = $0080; // save with superb quality (100:1)
-  JPEG_QUALITYGOOD    = $0100; // save with good quality (75:1)
-  JPEG_QUALITYNORMAL  = $0200; // save with normal quality (50:1)
-  JPEG_QUALITYAVERAGE = $0400; // save with average quality (25:1)
-  JPEG_QUALITYBAD     = $0800; // save with bad quality (10:1)
-  JPEG_PROGRESSIVE    = $2000; // save as a progressive-JPEG (use | to combine with other save flags)
-  JPEG_SUBSAMPLING_411 = $1000;  // save with high 4x1 chroma subsampling (4:1:1)
-  JPEG_SUBSAMPLING_420 = $4000;  // save with medium 2x2 medium chroma subsampling (4:2:0) - default value
-  JPEG_SUBSAMPLING_422 = $8000;  // save with low 2x1 chroma subsampling (4:2:2)
-  JPEG_SUBSAMPLING_444 = $10000; // save with no chroma subsampling (4:4:4)
-  JPEG_OPTIMIZE       = $20000; // on saving, compute optimal Huffman coding tables (can reduce a few percent of file size)
-  JPEG_BASELINE       = $40000; // save basic JPEG, without metadata or any markers
+  J2K_DEFAULT         = 0;     //! save with a 16:1 rate
+  JP2_DEFAULT         = 0;     //! save with a 16:1 rate
+  JPEG_DEFAULT        = 0;     //! loading (see JPEG_FAST); saving (see JPEG_QUALITYGOOD|JPEG_SUBSAMPLING_420)
+  JPEG_FAST           = 1;     //! load the file as fast as possible, sacrificing some quality
+  JPEG_ACCURATE       = 2;     //! load the file with the best quality, sacrificing some speed
+  JPEG_CMYK           = $0004; //! load separated CMYK "as is" (use | to combine with other flags)
+  JPEG_EXIFROTATE     = $0008; //! load and rotate according to Exif 'Orientation' tag if available
+  JPEG_GREYSCALE      = $0010; //! load and convert to a 8-bit greyscale image
+  JPEG_QUALITYSUPERB  = $0080; //! save with superb quality (100:1)
+  JPEG_QUALITYGOOD    = $0100; //! save with good quality (75:1)
+  JPEG_QUALITYNORMAL  = $0200; //! save with normal quality (50:1)
+  JPEG_QUALITYAVERAGE = $0400; //! save with average quality (25:1)
+  JPEG_QUALITYBAD     = $0800; //! save with bad quality (10:1)
+  JPEG_PROGRESSIVE    = $2000; //! save as a progressive-JPEG (use | to combine with other save flags)
+  JPEG_SUBSAMPLING_411 = $1000;  //! save with high 4x1 chroma subsampling (4:1:1)
+  JPEG_SUBSAMPLING_420 = $4000;  //! save with medium 2x2 medium chroma subsampling (4:2:0) - default value
+  JPEG_SUBSAMPLING_422 = $8000;  //! save with low 2x1 chroma subsampling (4:2:2)
+  JPEG_SUBSAMPLING_444 = $10000; //! save with no chroma subsampling (4:4:4)
+  JPEG_OPTIMIZE       = $20000; //! on saving, compute optimal Huffman coding tables (can reduce a few percent of file size)
+  JPEG_BASELINE       = $40000; //! save basic JPEG, without metadata or any markers
   KOALA_DEFAULT       = 0;
   LBM_DEFAULT         = 0;
   MNG_DEFAULT         = 0;
   PCD_DEFAULT         = 0;
-  PCD_BASE            = 1;     // load the bitmap sized 768 x 512
-  PCD_BASEDIV4        = 2;     // load the bitmap sized 384 x 256
-  PCD_BASEDIV16       = 3;     // load the bitmap sized 192 x 128
+  PCD_BASE            = 1;     //! load the bitmap sized 768 x 512
+  PCD_BASEDIV4        = 2;     //! load the bitmap sized 384 x 256
+  PCD_BASEDIV16       = 3;     //! load the bitmap sized 192 x 128
   PCX_DEFAULT         = 0;
   PFM_DEFAULT         = 0;
   PICT_DEFAULT        = 0;
   PNG_DEFAULT         = 0;
-  PNG_IGNOREGAMMA     = 1;     // avoid gamma correction
-  PNG_Z_BEST_SPEED          = $0001; // save using ZLib level 1 compression flag (default value is 6)
-  PNG_Z_DEFAULT_COMPRESSION = $0006; // save using ZLib level 6 compression flag (default recommended value)
-  PNG_Z_BEST_COMPRESSION    = $0009; // save using ZLib level 9 compression flag (default value is 6)
-  PNG_Z_NO_COMPRESSION      = $0100; // save without ZLib compression
-  PNG_INTERLACED            = $0200; // save using Adam7 interlacing (use | to combine with other save flags)
+  PNG_IGNOREGAMMA     = 1;     //! loading: avoid gamma correction
+  PNG_Z_BEST_SPEED          = $0001; //! save using ZLib level 1 compression flag (default value is 6)
+  PNG_Z_DEFAULT_COMPRESSION = $0006; //! save using ZLib level 6 compression flag (default recommended value)
+  PNG_Z_BEST_COMPRESSION    = $0009; //! save using ZLib level 9 compression flag (default value is 6)
+  PNG_Z_NO_COMPRESSION      = $0100; //! save without ZLib compression
+  PNG_INTERLACED            = $0200; //! save using Adam7 interlacing (use | to combine with other save flags)
   PNM_DEFAULT         = 0;
-  PNM_SAVE_RAW        = 0;     // If set the writer saves in RAW format (i.e. P4, P5 or P6)
-  PNM_SAVE_ASCII      = 1;     // If set the writer saves in ASCII format (i.e. P1, P2 or P3)
+  PNM_SAVE_RAW        = 0;     //! if set the writer saves in RAW format (i.e. P4, P5 or P6)
+  PNM_SAVE_ASCII      = 1;     //! if set the writer saves in ASCII format (i.e. P1, P2 or P3)
   PSD_DEFAULT         = 0;
-  PSD_CMYK            = 1; // reads tags for separated CMYK (default is conversion to RGB)
-  PSD_LAB             = 2; // reads tags for CIELab (default is conversion to RGB)
+  PSD_CMYK            = 1; //! reads tags for separated CMYK (default is conversion to RGB)
+  PSD_LAB             = 2; //! reads tags for CIELab (default is conversion to RGB)
   RAS_DEFAULT         = 0;
-  RAW_DEFAULT         = 0; // load the file as linear RGB 48-bit
-  RAW_PREVIEW         = 1; // try to load the embedded JPEG preview with included Exif Data or default to RGB 24-bit
-  RAW_DISPLAY         = 2; // load the file as RGB 24-bit
-  RAW_HALFSIZE        = 4; // output a half-size color image
+  RAW_DEFAULT         = 0; //! load the file as linear RGB 48-bit
+  RAW_PREVIEW         = 1; //! try to load the embedded JPEG preview with included Exif Data or default to RGB 24-bit
+  RAW_DISPLAY         = 2; //! load the file as RGB 24-bit
+  RAW_HALFSIZE        = 4; //! output a half-size color image
   SGI_DEFAULT         = 0;
   TARGA_DEFAULT       = 0;
-  TARGA_LOAD_RGB888   = 1;     // If set the loader converts RGB555 and ARGB8888 -> RGB888.
-  TARGA_SAVE_RLE      = 2;     // If set, the writer saves with RLE compression
+  TARGA_LOAD_RGB888   = 1;     //! if set the loader converts RGB555 and ARGB8888 -> RGB888.
+  TARGA_SAVE_RLE      = 2;     //! if set, the writer saves with RLE compression
   TIFF_DEFAULT        = 0;
-  TIFF_CMYK           = $0001;  // reads/stores tags for separated CMYK (use | to combine with compression flags)
-  TIFF_PACKBITS       = $0100;  // save using PACKBITS compression
-  TIFF_DEFLATE        = $0200;  // save using DEFLATE compression
-  TIFF_ADOBE_DEFLATE  = $0400;  // save using ADOBE DEFLATE compression
-  TIFF_NONE           = $0800;  // save without any compression
-  TIFF_CCITTFAX3      = $1000;  // save using CCITT Group 3 fax encoding
-  TIFF_CCITTFAX4      = $2000;  // save using CCITT Group 4 fax encoding
-  TIFF_LZW            = $4000;  // save using LZW compression
-  TIFF_JPEG           = $8000;  // save using JPEG compression
-  TIFF_LOGLUV         = $10000; // save using LogLuv compression
+  TIFF_CMYK           = $0001;  //! reads/stores tags for separated CMYK (use | to combine with compression flags)
+  TIFF_PACKBITS       = $0100;  //! save using PACKBITS compression
+  TIFF_DEFLATE        = $0200;  //! save using DEFLATE compression
+  TIFF_ADOBE_DEFLATE  = $0400;  //! save using ADOBE DEFLATE compression
+  TIFF_NONE           = $0800;  //! save without any compression
+  TIFF_CCITTFAX3      = $1000;  //! save using CCITT Group 3 fax encoding
+  TIFF_CCITTFAX4      = $2000;  //! save using CCITT Group 4 fax encoding
+  TIFF_LZW            = $4000;  //! save using LZW compression
+  TIFF_JPEG           = $8000;  //! save using JPEG compression
+  TIFF_LOGLUV         = $10000; //! save using LogLuv compression
   WBMP_DEFAULT        = 0;
   XBM_DEFAULT         = 0;
   XPM_DEFAULT         = 0;
+  WEBP_DEFAULT        = 0;      //! save with good quality (75:1)
+  WEBP_LOSSLESS       = $100;   //! save in lossless mode
+  JXR_DEFAULT         = 0;      //! save with quality 80 and no chroma subsampling (4:4:4)
+  JXR_LOSSLESS        = $0064;  //! save lossless
+  JXR_PROGRESSIVE     = $2000;  //! save as a progressive-JXR (use | to combine with other save flags)
 
 // --------------------------------------------------------------------------
 // Background filling options -----------------------------------------------
@@ -609,19 +631,23 @@ const
 // Init/Error routines ------------------------------------------------------
 // --------------------------------------------------------------------------
 
-procedure FreeImage_Initialise(load_local_plugins_only: LongBool = False); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_Initialise at 4'{$ENDIF};
-procedure FreeImage_DeInitialise; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_DeInitialise at 0'{$ENDIF};
+procedure FreeImage_Initialise(load_local_plugins_only: LongBool = False); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_Initialise at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_Initialise'{$ENDIF};
+procedure FreeImage_DeInitialise; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_DeInitialise at 0'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_DeInitialise'{$ENDIF};
 
 // --------------------------------------------------------------------------
 // Version routines ---------------------------------------------------------
 // --------------------------------------------------------------------------
 
-function FreeImage_GetVersion: PAnsiChar; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetVersion at 0'{$ENDIF};
-function FreeImage_GetCopyrightMessage: PAnsiChar; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetCopyrightMessage at 0'{$ENDIF};
+function FreeImage_GetVersion: PAnsiChar; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetVersion at 0'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetVersion'{$ENDIF};
+function FreeImage_GetCopyrightMessage: PAnsiChar; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetCopyrightMessage at 0'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetCopyrightMessage'{$ENDIF};
 
 // --------------------------------------------------------------------------
 // Message output functions -------------------------------------------------
@@ -631,19 +657,22 @@ type
   FreeImage_OutputMessageFunction = procedure(fif: FREE_IMAGE_FORMAT;
     msg: PAnsiChar); cdecl;
   FreeImage_OutputMessageFunctionStdCall = procedure(fif: FREE_IMAGE_FORMAT;
-    msg: PAnsiChar); stdcall;
+    msg: PAnsiChar); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+procedure FreeImage_SetOutputMessageStdCall(omf: FreeImage_OutputMessageFunctionStdCall); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetOutputMessageStdCall at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_SetOutputMessageStdCall'{$ENDIF};
+procedure FreeImage_SetOutputMessage(omf: FreeImage_OutputMessageFunction); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetOutputMessage at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_SetOutputMessage'{$ENDIF};
 
-procedure FreeImage_SetOutputMessageStdCall(omf: FreeImage_OutputMessageFunctionStdCall); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetOutputMessageStdCall at 4'{$ENDIF};
-procedure FreeImage_SetOutputMessage(omf: FreeImage_OutputMessageFunction); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetOutputMessage at 4'{$ENDIF};
 {$IFDEF DELPHI6}
 //this is declared stdcall in the C header but it is actually cdecl.
 //with varargs functions, clearing the stack is caller's responsibility
 //(since the callee doesn't know how many parameters were passed).
 //cdecl is the right convention here, not stdcall
 procedure FreeImage_OutputMessageProc(fif: Integer; fmt: PAnsiChar); cdecl; varargs;
-  external FIDLL {$IFDEF WIN32}name 'FreeImage_OutputMessageProc'{$ENDIF};
+  external FIDLL;
 {$ELSE}
 //older Delphi versions (<6) do not support varargs.
 //we provide a wrapper that uses open arrays instead
@@ -655,80 +684,102 @@ procedure FreeImage_OutputMessageProc(fif: Integer; fmt: PAnsiChar; args: array
 // --------------------------------------------------------------------------
 
 function FreeImage_Allocate(width, height, bpp: Integer; red_mask: Cardinal = 0;
-  green_mask: Cardinal = 0; blue_mask: Cardinal = 0): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_Allocate at 24'{$ENDIF};
-function FreeImage_AllocateT(atype: FREE_IMAGE_TYPE; width, height: Integer;
+  green_mask: Cardinal = 0; blue_mask: Cardinal = 0): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_Allocate at 24'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_Allocate'{$ENDIF};
+function FreeImage_AllocateT(_type: FREE_IMAGE_TYPE; width, height: Integer;
   bpp: Integer = 8; red_mask: Cardinal = 0; green_mask: Cardinal = 0;
-  blue_mask: Cardinal = 0): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_AllocateT at 28'{$ENDIF};
-function FreeImage_Clone(dib: PFIBITMAP): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_Clone at 4'{$ENDIF};
-procedure FreeImage_Unload(dib: PFIBITMAP); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_Unload at 4'{$ENDIF};
+  blue_mask: Cardinal = 0): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_AllocateT at 28'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_AllocateT'{$ENDIF};
+function FreeImage_Clone(dib: PFIBITMAP): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_Clone at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_Clone'{$ENDIF};
+procedure FreeImage_Unload(dib: PFIBITMAP); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_Unload at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_Unload'{$ENDIF};
 
 // --------------------------------------------------------------------------
 // Header loading routines
 // --------------------------------------------------------------------------
-function FreeImage_HasPixels(dib: PFIBITMAP): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_HasPixels at 4'{$ENDIF};
+function FreeImage_HasPixels(dib: PFIBITMAP): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_HasPixels at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_HasPixels'{$ENDIF};
 
 // --------------------------------------------------------------------------
 // Load / Save routines -----------------------------------------------------
 // --------------------------------------------------------------------------
 
 function FreeImage_Load(fif: FREE_IMAGE_FORMAT; filename: PAnsiChar;
-  flags: Integer = 0): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_Load at 12'{$ENDIF};
+  flags: Integer = 0): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_Load at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_Load'{$ENDIF};
 function FreeImage_LoadU(fif: FREE_IMAGE_FORMAT; filename: PWideChar;
-  flags: Integer = 0): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_LoadU at 12'{$ENDIF};
+  flags: Integer = 0): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_LoadU at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_LoadU'{$ENDIF};
 function FreeImage_LoadFromHandle(fif: FREE_IMAGE_FORMAT; io: PFreeImageIO;
-  handle: fi_handle; flags: Integer = 0): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_LoadFromHandle at 16'{$ENDIF};
+  handle: fi_handle; flags: Integer = 0): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_LoadFromHandle at 16'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_LoadFromHandle'{$ENDIF};
 function FreeImage_Save(fif: FREE_IMAGE_FORMAT; dib: PFIBITMAP; filename: PAnsiChar;
-  flags: Integer = 0): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_Save at 16'{$ENDIF};
+  flags: Integer = 0): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_Save at 16'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_Save'{$ENDIF};
 function FreeImage_SaveU(fif: FREE_IMAGE_FORMAT; dib: PFIBITMAP; filename: PWideChar;
-  flags: Integer = 0): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_SaveU at 16'{$ENDIF};
+  flags: Integer = 0): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_SaveU at 16'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_SaveU'{$ENDIF};
 function FreeImage_SaveToHandle(fif: FREE_IMAGE_FORMAT; dib: PFIBITMAP;
-  io: PFreeImageIO; handle: fi_handle; flags: Integer = 0): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_SaveToHandle at 20'{$ENDIF};
+  io: PFreeImageIO; handle: fi_handle; flags: Integer = 0): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_SaveToHandle at 20'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_SaveToHandle'{$ENDIF};
 
 // --------------------------------------------------------------------------
 // Memory I/O stream routines -----------------------------------------------
 // --------------------------------------------------------------------------
 
-function FreeImage_OpenMemory(data: PByte = nil; size_in_bytes: DWORD = 0): PFIMEMORY; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_OpenMemory at 8'{$ENDIF};
-procedure FreeImage_CloseMemory(stream: PFIMEMORY); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_CloseMemory at 4'{$ENDIF};
+function FreeImage_OpenMemory(data: PByte = nil; size_in_bytes: DWORD = 0): PFIMEMORY; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_OpenMemory at 8'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_OpenMemory'{$ENDIF};
+procedure FreeImage_CloseMemory(stream: PFIMEMORY); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_CloseMemory at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_CloseMemory'{$ENDIF};
 function FreeImage_LoadFromMemory(fif: FREE_IMAGE_FORMAT; stream: PFIMEMORY;
-  flags: Integer = 0): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_LoadFromMemory at 12'{$ENDIF};
+  flags: Integer = 0): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_LoadFromMemory at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_LoadFromMemory'{$ENDIF};
 function FreeImage_SaveToMemory(fif: FREE_IMAGE_FORMAT; dib: PFIBITMAP;
-  stream: PFIMEMORY; flags: Integer = 0): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_SaveToMemory at 16'{$ENDIF};
-function FreeImage_TellMemory(stream: PFIMEMORY): LongInt; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_TellMemory at 4'{$ENDIF};
+  stream: PFIMEMORY; flags: Integer = 0): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_SaveToMemory at 16'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_SaveToMemory'{$ENDIF};
+function FreeImage_TellMemory(stream: PFIMEMORY): LongInt; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_TellMemory at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_TellMemory'{$ENDIF};
 function FreeImage_SeekMemory(stream: PFIMEMORY; offset: LongInt;
-  origin: Integer): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_SeekMemory at 12'{$ENDIF};
+  origin: Integer): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_SeekMemory at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_SeekMemory'{$ENDIF};
 function FreeImage_AcquireMemory(stream: PFIMEMORY; var data: PByte;
-  var size_in_bytes: DWORD): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_AcquireMemory at 12'{$ENDIF};
+  var size_in_bytes: DWORD): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_AcquireMemory at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_AcquireMemory'{$ENDIF};
 function FreeImage_ReadMemory(buffer: Pointer; size, count: Cardinal;
-  stream: PFIMEMORY): Cardinal; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ReadMemory at 16'{$ENDIF};
+  stream: PFIMEMORY): Cardinal; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ReadMemory at 16'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ReadMemory'{$ENDIF};
 function FreeImage_WriteMemory(buffer: Pointer; size, count: Cardinal;
-  stream: PFIMEMORY): Cardinal; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_WriteMemory at 16'{$ENDIF};
+  stream: PFIMEMORY): Cardinal; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_WriteMemory at 16'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_WriteMemory'{$ENDIF};
 function FreeImage_LoadMultiBitmapFromMemory(fif: FREE_IMAGE_FORMAT; stream: PFIMEMORY;
-  flags: Integer = 0): PFIMULTIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_LoadMultiBitmapFromMemory at 12'{$ENDIF};
+  flags: Integer = 0): PFIMULTIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_LoadMultiBitmapFromMemory at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_LoadMultiBitmapFromMemory'{$ENDIF};
 function FreeImage_SaveMultiBitmapToMemory(fif: FREE_IMAGE_FORMAT; bitmap: PFIMULTIBITMAP;
-  stream: PFIMEMORY; flags: Integer): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_SaveMultiBitmapToMemory at 16'{$ENDIF};
+  stream: PFIMEMORY; flags: Integer): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_SaveMultiBitmapToMemory at 16'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_SaveMultiBitmapToMemory'{$ENDIF};
 
 // --------------------------------------------------------------------------
 // Plugin Interface ---------------------------------------------------------
@@ -736,50 +787,70 @@ function FreeImage_SaveMultiBitmapToMemory(fif: FREE_IMAGE_FORMAT; bitmap: PFIMU
 
 function FreeImage_RegisterLocalPlugin(proc_address: FI_InitProc; format: PAnsiChar = nil;
   description: PAnsiChar = nil; extension: PAnsiChar = nil;
-  regexpr: PAnsiChar = nil): FREE_IMAGE_FORMAT; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_RegisterLocalPlugin at 20'{$ENDIF};
+  regexpr: PAnsiChar = nil): FREE_IMAGE_FORMAT; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_RegisterLocalPlugin at 20'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_RegisterLocalPlugin'{$ENDIF};
 function FreeImage_RegisterExternalPlugin(path: PAnsiChar; format: PAnsiChar = nil;
   description: PAnsiChar = nil; extension: PAnsiChar = nil;
-  regexpr: PAnsiChar = nil): FREE_IMAGE_FORMAT; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_RegisterExternalPlugin at 20'{$ENDIF};
-function FreeImage_GetFIFCount: Integer; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetFIFCount at 0'{$ENDIF};
-procedure FreeImage_SetPluginEnabled(fif: FREE_IMAGE_FORMAT; enable: LongBool); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetPluginEnabled at 8'{$ENDIF};
-function FreeImage_IsPluginEnabled(fif: FREE_IMAGE_FORMAT): Integer; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_IsPluginEnabled at 4'{$ENDIF};
-function FreeImage_GetFIFFromFormat(format: PAnsiChar): FREE_IMAGE_FORMAT; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetFIFFromFormat at 4'{$ENDIF};
-function FreeImage_GetFIFFromMime(mime: PAnsiChar): FREE_IMAGE_FORMAT; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetFIFFromMime at 4'{$ENDIF};
-function FreeImage_GetFormatFromFIF(fif: FREE_IMAGE_FORMAT): PAnsiChar; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetFormatFromFIF at 4'{$ENDIF};
-function FreeImage_GetFIFExtensionList(fif: FREE_IMAGE_FORMAT): PAnsiChar; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetFIFExtensionList at 4'{$ENDIF};
-function FreeImage_GetFIFDescription(fif: FREE_IMAGE_FORMAT): PAnsiChar; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetFIFDescription at 4'{$ENDIF};
-function FreeImage_GetFIFRegExpr(fif: FREE_IMAGE_FORMAT): PAnsiChar; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetFIFRegExpr at 4'{$ENDIF};
-function FreeImage_GetFIFMimeType(fif: FREE_IMAGE_FORMAT): PAnsiChar; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetFIFMimeType at 4'{$ENDIF};
-function FreeImage_GetFIFFromFilename(filename: PAnsiChar): FREE_IMAGE_FORMAT; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetFIFFromFilename at 4'{$ENDIF};
-function FreeImage_GetFIFFromFilenameU(filename: PWideChar): FREE_IMAGE_FORMAT; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetFIFFromFilenameU at 4'{$ENDIF};
-function FreeImage_FIFSupportsReading(fif: FREE_IMAGE_FORMAT): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_FIFSupportsReading at 4'{$ENDIF};
-function FreeImage_FIFSupportsWriting(fif: FREE_IMAGE_FORMAT): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_FIFSupportsWriting at 4'{$ENDIF};
+  regexpr: PAnsiChar = nil): FREE_IMAGE_FORMAT; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_RegisterExternalPlugin at 20'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_RegisterExternalPlugin'{$ENDIF};
+function FreeImage_GetFIFCount: Integer; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetFIFCount at 0'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetFIFCount'{$ENDIF};
+procedure FreeImage_SetPluginEnabled(fif: FREE_IMAGE_FORMAT; enable: LongBool); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetPluginEnabled at 8'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_SetPluginEnabled'{$ENDIF};
+function FreeImage_IsPluginEnabled(fif: FREE_IMAGE_FORMAT): Integer; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_IsPluginEnabled at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_IsPluginEnabled'{$ENDIF};
+function FreeImage_GetFIFFromFormat(format: PAnsiChar): FREE_IMAGE_FORMAT; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetFIFFromFormat at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetFIFFromFormat'{$ENDIF};
+function FreeImage_GetFIFFromMime(mime: PAnsiChar): FREE_IMAGE_FORMAT; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetFIFFromMime at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetFIFFromMime'{$ENDIF};
+function FreeImage_GetFormatFromFIF(fif: FREE_IMAGE_FORMAT): PAnsiChar; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetFormatFromFIF at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetFormatFromFIF'{$ENDIF};
+function FreeImage_GetFIFExtensionList(fif: FREE_IMAGE_FORMAT): PAnsiChar; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetFIFExtensionList at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetFIFExtensionList'{$ENDIF};
+function FreeImage_GetFIFDescription(fif: FREE_IMAGE_FORMAT): PAnsiChar; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetFIFDescription at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetFIFDescription'{$ENDIF};
+function FreeImage_GetFIFRegExpr(fif: FREE_IMAGE_FORMAT): PAnsiChar; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetFIFRegExpr at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetFIFRegExpr'{$ENDIF};
+function FreeImage_GetFIFMimeType(fif: FREE_IMAGE_FORMAT): PAnsiChar; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetFIFMimeType at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetFIFMimeType'{$ENDIF};
+function FreeImage_GetFIFFromFilename(filename: PAnsiChar): FREE_IMAGE_FORMAT; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetFIFFromFilename at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetFIFFromFilename'{$ENDIF};
+function FreeImage_GetFIFFromFilenameU(filename: PWideChar): FREE_IMAGE_FORMAT; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetFIFFromFilenameU at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetFIFFromFilenameU'{$ENDIF};
+function FreeImage_FIFSupportsReading(fif: FREE_IMAGE_FORMAT): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_FIFSupportsReading at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_FIFSupportsReading'{$ENDIF};
+function FreeImage_FIFSupportsWriting(fif: FREE_IMAGE_FORMAT): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_FIFSupportsWriting at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_FIFSupportsWriting'{$ENDIF};
 function FreeImage_FIFSupportsExportBPP(fif: FREE_IMAGE_FORMAT;
-  bpp: Integer): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_FIFSupportsExportBPP at 8'{$ENDIF};
+  bpp: Integer): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_FIFSupportsExportBPP at 8'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_FIFSupportsExportBPP'{$ENDIF};
 function FreeImage_FIFSupportsExportType(fif: FREE_IMAGE_FORMAT;
-  atype: FREE_IMAGE_TYPE): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_FIFSupportsExportType at 8'{$ENDIF};
-function FreeImage_FIFSupportsICCProfiles(fif: FREE_IMAGE_FORMAT): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_FIFSupportsICCProfiles at 4'{$ENDIF};
-function FreeImage_FIFSupportsNoPixels(fif: FREE_IMAGE_FORMAT): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_FIFSupportsNoPixels at 4'{$ENDIF};
+  _type: FREE_IMAGE_TYPE): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_FIFSupportsExportType at 8'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_FIFSupportsExportType'{$ENDIF};
+function FreeImage_FIFSupportsICCProfiles(fif: FREE_IMAGE_FORMAT): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_FIFSupportsICCProfiles at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_FIFSupportsICCProfiles'{$ENDIF};
+function FreeImage_FIFSupportsNoPixels(fif: FREE_IMAGE_FORMAT): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_FIFSupportsNoPixels at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_FIFSupportsNoPixels'{$ENDIF};
 
 // --------------------------------------------------------------------------
 // Multipaging interface ----------------------------------------------------
@@ -787,536 +858,749 @@ function FreeImage_FIFSupportsNoPixels(fif: FREE_IMAGE_FORMAT): LongBool; stdcal
 
 function FreeImage_OpenMultiBitmap(fif: FREE_IMAGE_FORMAT; filename: PAnsiChar;
   create_new, read_only: LongBool; keep_cache_in_memory: LongBool = False;
-  flags: Integer = 0): PFIMULTIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_OpenMultiBitmap at 24'{$ENDIF};
+  flags: Integer = 0): PFIMULTIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_OpenMultiBitmap at 24'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_OpenMultiBitmap'{$ENDIF};
 function FreeImage_OpenMultiBitmapFromHandle(fif: FREE_IMAGE_FORMAT; io: PFreeImageIO;
-  handle: fi_handle; flags: Integer = 0): PFIMULTIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_OpenMultiBitmapFromHandle at 16'{$ENDIF};
+  handle: fi_handle; flags: Integer = 0): PFIMULTIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_OpenMultiBitmapFromHandle at 16'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_OpenMultiBitmapFromHandle'{$ENDIF};
 function FreeImage_SaveMultiBitmapToHandle(fif: FREE_IMAGE_FORMAT; bitmap: PFIMULTIBITMAP;
-  io: PFreeImageIO; handle: fi_handle; flags: Integer = 0): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_SaveMultiBitmapToHandle at 20'{$ENDIF};
+  io: PFreeImageIO; handle: fi_handle; flags: Integer = 0): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_SaveMultiBitmapToHandle at 20'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_SaveMultiBitmapToHandle'{$ENDIF};
 function FreeImage_CloseMultiBitmap(bitmap: PFIMULTIBITMAP;
-  flags: Integer = 0): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_CloseMultiBitmap at 8'{$ENDIF};
-function FreeImage_GetPageCount(bitmap: PFIMULTIBITMAP): Integer; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetPageCount at 4'{$ENDIF};
-procedure FreeImage_AppendPage(bitmap: PFIMULTIBITMAP; data: PFIBITMAP); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_AppendPage at 8'{$ENDIF};
+  flags: Integer = 0): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_CloseMultiBitmap at 8'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_CloseMultiBitmap'{$ENDIF};
+function FreeImage_GetPageCount(bitmap: PFIMULTIBITMAP): Integer; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetPageCount at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetPageCount'{$ENDIF};
+procedure FreeImage_AppendPage(bitmap: PFIMULTIBITMAP; data: PFIBITMAP); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_AppendPage at 8'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_AppendPage'{$ENDIF};
 procedure FreeImage_InsertPage(bitmap: PFIMULTIBITMAP; page: Integer;
-  data: PFIBITMAP); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_InsertPage at 12'{$ENDIF};
-procedure FreeImage_DeletePage(bitmap: PFIMULTIBITMAP; page: Integer); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_DeletePage at 8'{$ENDIF};
-function FreeImage_LockPage(bitmap: PFIMULTIBITMAP; page: Integer): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_LockPage at 8'{$ENDIF};
+  data: PFIBITMAP); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_InsertPage at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_InsertPage'{$ENDIF};
+procedure FreeImage_DeletePage(bitmap: PFIMULTIBITMAP; page: Integer); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_DeletePage at 8'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_DeletePage'{$ENDIF};
+function FreeImage_LockPage(bitmap: PFIMULTIBITMAP; page: Integer): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_LockPage at 8'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_LockPage'{$ENDIF};
 procedure FreeImage_UnlockPage(bitmap: PFIMULTIBITMAP; data: PFIBITMAP;
-  changed: LongBool); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_UnlockPage at 12'{$ENDIF};
-function FreeImage_MovePage(bitmap: PFIMULTIBITMAP; target, source: Integer): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_MovePage at 12'{$ENDIF};
+  changed: LongBool); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_UnlockPage at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_UnlockPage'{$ENDIF};
+function FreeImage_MovePage(bitmap: PFIMULTIBITMAP; target, source: Integer): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_MovePage at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_MovePage'{$ENDIF};
 function FreeImage_GetLockedPageNumbers(bitmap: PFIMULTIBITMAP; var pages: Integer;
-  var count: Integer): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetLockedPageNumbers at 12'{$ENDIF};
+  var count: Integer): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetLockedPageNumbers at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetLockedPageNumbers'{$ENDIF};
 
 // --------------------------------------------------------------------------
 // Filetype request routines ------------------------------------------------
 // --------------------------------------------------------------------------
 
 function FreeImage_GetFileType(filename: PAnsiChar;
-  size: Integer = 0): FREE_IMAGE_FORMAT; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetFileType at 8'{$ENDIF};
+  size: Integer = 0): FREE_IMAGE_FORMAT; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetFileType at 8'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetFileType'{$ENDIF};
 function FreeImage_GetFileTypeU(filename: PWideChar;
-  size: Integer = 0): FREE_IMAGE_FORMAT; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetFileTypeU at 8'{$ENDIF};
+  size: Integer = 0): FREE_IMAGE_FORMAT; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetFileTypeU at 8'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetFileTypeU'{$ENDIF};
 function FreeImage_GetFileTypeFromHandle(io: PFreeImageIO; handle: FI_Handle;
-  size: Integer = 0): FREE_IMAGE_FORMAT; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetFileTypeFromHandle at 12'{$ENDIF};
+  size: Integer = 0): FREE_IMAGE_FORMAT; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetFileTypeFromHandle at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetFileTypeFromHandle'{$ENDIF};
 function FreeImage_GetFileTypeFromMemory(stream: PFIMEMORY;
-  size: Integer = 0): FREE_IMAGE_FORMAT; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetFileTypeFromMemory at 8'{$ENDIF};
+  size: Integer = 0): FREE_IMAGE_FORMAT; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetFileTypeFromMemory at 8'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetFileTypeFromMemory'{$ENDIF};
 
 // --------------------------------------------------------------------------
 // ImageType request routine ------------------------------------------------
 // --------------------------------------------------------------------------
 
-function FreeImage_GetImageType(dib: PFIBITMAP): FREE_IMAGE_TYPE; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetImageType at 4'{$ENDIF};
+function FreeImage_GetImageType(dib: PFIBITMAP): FREE_IMAGE_TYPE; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetImageType at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetImageType'{$ENDIF};
 
 // --------------------------------------------------------------------------
 // FreeImage helper routines ------------------------------------------------
 // --------------------------------------------------------------------------
 
-function FreeImage_IsLittleEndian: LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_IsLittleEndian at 0'{$ENDIF};
-function FreeImage_LookupX11Color(szColor: PAnsiChar; var nRed, nGreen, nBlue: Byte): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_LookupX11Color at 16'{$ENDIF};
-function FreeImage_LookupSVGColor(szColor: PAnsiChar; var nRed, nGreen, nBlue: Byte): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_LookupSVGColor at 16'{$ENDIF};
+function FreeImage_IsLittleEndian: LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_IsLittleEndian at 0'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_IsLittleEndian'{$ENDIF};
+function FreeImage_LookupX11Color(szColor: PAnsiChar; var nRed, nGreen, nBlue: Byte): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_LookupX11Color at 16'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_LookupX11Color'{$ENDIF};
+function FreeImage_LookupSVGColor(szColor: PAnsiChar; var nRed, nGreen, nBlue: Byte): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_LookupSVGColor at 16'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_LookupSVGColor'{$ENDIF};
 
 // --------------------------------------------------------------------------
 // Pixels access routines ---------------------------------------------------
 // --------------------------------------------------------------------------
 
-function FreeImage_GetBits(dib: PFIBITMAP): PByte; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetBits at 4'{$ENDIF};
-function FreeImage_GetScanLine(dib: PFIBITMAP; scanline: Integer): PByte; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetScanLine at 8'{$ENDIF};
-
-function FreeImage_GetPixelIndex(dib: PFIBITMAP; x, y: Cardinal; var value: Byte): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetPixelIndex at 16'{$ENDIF};
-function FreeImage_GetPixelColor(dib: PFIBITMAP; x, y: Cardinal; var value: RGBQUAD): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetPixelColor at 16'{$ENDIF};
-function FreeImage_SetPixelIndex(dib: PFIBITMAP; x, y: Cardinal; var value: Byte): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetPixelIndex at 16'{$ENDIF};
-function FreeImage_SetPixelColor(dib: PFIBITMAP; x, y: Cardinal; var value: RGBQUAD): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetPixelColor at 16'{$ENDIF};
+function FreeImage_GetBits(dib: PFIBITMAP): PByte; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetBits at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetBits'{$ENDIF};
+function FreeImage_GetScanLine(dib: PFIBITMAP; scanline: Integer): PByte; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetScanLine at 8'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetScanLine'{$ENDIF};
+
+function FreeImage_GetPixelIndex(dib: PFIBITMAP; x, y: Cardinal; var value: Byte): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetPixelIndex at 16'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetPixelIndex'{$ENDIF};
+function FreeImage_GetPixelColor(dib: PFIBITMAP; x, y: Cardinal; var value: RGBQUAD): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetPixelColor at 16'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetPixelColor'{$ENDIF};
+function FreeImage_SetPixelIndex(dib: PFIBITMAP; x, y: Cardinal; var value: Byte): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetPixelIndex at 16'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_SetPixelIndex'{$ENDIF};
+function FreeImage_SetPixelColor(dib: PFIBITMAP; x, y: Cardinal; var value: RGBQUAD): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetPixelColor at 16'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_SetPixelColor'{$ENDIF};
 
 // --------------------------------------------------------------------------
 // DIB info routines --------------------------------------------------------
 // --------------------------------------------------------------------------
 
-function FreeImage_GetColorsUsed(dib: PFIBITMAP): Cardinal; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetColorsUsed at 4'{$ENDIF};
-function FreeImage_GetBPP(dib: PFIBITMAP): Cardinal; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetBPP at 4'{$ENDIF};
-function FreeImage_GetWidth(dib: PFIBITMAP): Cardinal; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetWidth at 4'{$ENDIF};
-function FreeImage_GetHeight(dib: PFIBITMAP): Cardinal; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetHeight at 4'{$ENDIF};
-function FreeImage_GetLine(dib: PFIBITMAP): Cardinal; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetLine at 4'{$ENDIF};
-function FreeImage_GetPitch(dib: PFIBITMAP): Cardinal; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetPitch at 4'{$ENDIF};
-function FreeImage_GetDIBSize(dib: PFIBITMAP): Cardinal; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetDIBSize at 4'{$ENDIF};
-function FreeImage_GetPalette(dib: PFIBITMAP): PRGBQuad; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetPalette at 4'{$ENDIF};
-
-function FreeImage_GetDotsPerMeterX(dib: PFIBITMAP): Cardinal; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetDotsPerMeterX at 4'{$ENDIF};
-function FreeImage_GetDotsPerMeterY(dib: PFIBITMAP): Cardinal; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetDotsPerMeterY at 4'{$ENDIF};
-procedure FreeImage_SetDotsPerMeterX(dib: PFIBITMAP; res: Cardinal); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetDotsPerMeterX at 8'{$ENDIF};
-procedure FreeImage_SetDotsPerMeterY(dib: PFIBITMAP; res: Cardinal); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetDotsPerMeterY at 8'{$ENDIF};
-
-function FreeImage_GetInfoHeader(dib: PFIBITMAP): PBITMAPINFOHEADER; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetInfoHeader at 4'{$ENDIF};
-function FreeImage_GetInfo(dib: PFIBITMAP): PBITMAPINFO; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetInfo at 4'{$ENDIF};
-function FreeImage_GetColorType(dib: PFIBITMAP): FREE_IMAGE_COLOR_TYPE; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetColorType at 4'{$ENDIF};
-
-function FreeImage_GetRedMask(dib: PFIBITMAP): Cardinal; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetRedMask at 4'{$ENDIF};
-function FreeImage_GetGreenMask(dib: PFIBITMAP): Cardinal; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetGreenMask at 4'{$ENDIF};
-function FreeImage_GetBlueMask(dib: PFIBITMAP): Cardinal; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetBlueMask at 4'{$ENDIF};
-
-function FreeImage_GetTransparencyCount(dib: PFIBITMAP): Cardinal; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetTransparencyCount at 4'{$ENDIF};
-function FreeImage_GetTransparencyTable(dib: PFIBITMAP): PByte; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetTransparencyTable at 4'{$ENDIF};
-procedure FreeImage_SetTransparent(dib: PFIBITMAP; enabled: LongBool); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetTransparent at 8'{$ENDIF};
+function FreeImage_GetColorsUsed(dib: PFIBITMAP): Cardinal; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetColorsUsed at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetColorsUsed'{$ENDIF};
+function FreeImage_GetBPP(dib: PFIBITMAP): Cardinal; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetBPP at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetBPP'{$ENDIF};
+function FreeImage_GetWidth(dib: PFIBITMAP): Cardinal; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetWidth at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetWidth'{$ENDIF};
+function FreeImage_GetHeight(dib: PFIBITMAP): Cardinal; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetHeight at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetHeight'{$ENDIF};
+function FreeImage_GetLine(dib: PFIBITMAP): Cardinal; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetLine at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetLine'{$ENDIF};
+function FreeImage_GetPitch(dib: PFIBITMAP): Cardinal; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetPitch at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetPitch'{$ENDIF};
+function FreeImage_GetDIBSize(dib: PFIBITMAP): Cardinal; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetDIBSize at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetDIBSize'{$ENDIF};
+function FreeImage_GetPalette(dib: PFIBITMAP): PRGBQuad; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetPalette at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetPalette'{$ENDIF};
+
+function FreeImage_GetDotsPerMeterX(dib: PFIBITMAP): Cardinal; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetDotsPerMeterX at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetDotsPerMeterX'{$ENDIF};
+function FreeImage_GetDotsPerMeterY(dib: PFIBITMAP): Cardinal; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetDotsPerMeterY at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetDotsPerMeterY'{$ENDIF};
+procedure FreeImage_SetDotsPerMeterX(dib: PFIBITMAP; res: Cardinal); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetDotsPerMeterX at 8'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_SetDotsPerMeterX'{$ENDIF};
+procedure FreeImage_SetDotsPerMeterY(dib: PFIBITMAP; res: Cardinal); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetDotsPerMeterY at 8'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_SetDotsPerMeterY'{$ENDIF};
+
+function FreeImage_GetInfoHeader(dib: PFIBITMAP): PBITMAPINFOHEADER; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetInfoHeader at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetInfoHeader'{$ENDIF};
+function FreeImage_GetInfo(dib: PFIBITMAP): PBITMAPINFO; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetInfo at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetInfo'{$ENDIF};
+function FreeImage_GetColorType(dib: PFIBITMAP): FREE_IMAGE_COLOR_TYPE; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetColorType at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetColorType'{$ENDIF};
+
+function FreeImage_GetRedMask(dib: PFIBITMAP): Cardinal; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetRedMask at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetRedMask'{$ENDIF};
+function FreeImage_GetGreenMask(dib: PFIBITMAP): Cardinal; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetGreenMask at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetGreenMask'{$ENDIF};
+function FreeImage_GetBlueMask(dib: PFIBITMAP): Cardinal; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetBlueMask at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetBlueMask'{$ENDIF};
+
+function FreeImage_GetTransparencyCount(dib: PFIBITMAP): Cardinal; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetTransparencyCount at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetTransparencyCount'{$ENDIF};
+function FreeImage_GetTransparencyTable(dib: PFIBITMAP): PByte; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetTransparencyTable at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetTransparencyTable'{$ENDIF};
+procedure FreeImage_SetTransparent(dib: PFIBITMAP; enabled: LongBool); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetTransparent at 8'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_SetTransparent'{$ENDIF};
 procedure FreeImage_SetTransparencyTable(dib: PFIBITMAP; table: PByte;
-  count: Integer); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetTransparencyTable at 12'{$ENDIF};
-function FreeImage_IsTransparent(dib: PFIBITMAP): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_IsTransparent at 4'{$ENDIF};
-procedure FreeImage_SetTransparentIndex(dib: PFIBITMAP; index: Integer); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetTransparentIndex at 8'{$ENDIF};
-function FreeImage_GetTransparentIndex(dib: PFIBITMAP): Integer; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetTransparentIndex at 4'{$ENDIF};
-
-function FreeImage_HasBackgroundColor(dib: PFIBITMAP): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_HasBackgroundColor at 4'{$ENDIF};
-function FreeImage_GetBackgroundColor(dib: PFIBITMAP; var bkcolor: RGBQUAD): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetBackgroundColor at 8'{$ENDIF};
-function FreeImage_SetBackgroundColor(dib: PFIBITMAP; bkcolor: PRGBQuad): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetBackgroundColor at 8'{$ENDIF};
-
-function FreeImage_GetThumbnail(dib: PFIBITMAP): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetThumbnail at 4'{$ENDIF};
-function FreeImage_SetThumbnail(dib, thumbnail: PFIBITMAP): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetThumbnail at 8'{$ENDIF};
+  count: Integer); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetTransparencyTable at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_SetTransparencyTable'{$ENDIF};
+function FreeImage_IsTransparent(dib: PFIBITMAP): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_IsTransparent at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_IsTransparent'{$ENDIF};
+procedure FreeImage_SetTransparentIndex(dib: PFIBITMAP; index: Integer); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetTransparentIndex at 8'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_SetTransparentIndex'{$ENDIF};
+function FreeImage_GetTransparentIndex(dib: PFIBITMAP): Integer; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetTransparentIndex at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetTransparentIndex'{$ENDIF};
+
+function FreeImage_HasBackgroundColor(dib: PFIBITMAP): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_HasBackgroundColor at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_HasBackgroundColor'{$ENDIF};
+function FreeImage_GetBackgroundColor(dib: PFIBITMAP; var bkcolor: RGBQUAD): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetBackgroundColor at 8'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetBackgroundColor'{$ENDIF};
+function FreeImage_SetBackgroundColor(dib: PFIBITMAP; bkcolor: PRGBQuad): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetBackgroundColor at 8'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_SetBackgroundColor'{$ENDIF};
+
+function FreeImage_GetThumbnail(dib: PFIBITMAP): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetThumbnail at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetThumbnail'{$ENDIF};
+function FreeImage_SetThumbnail(dib, thumbnail: PFIBITMAP): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetThumbnail at 8'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_SetThumbnail'{$ENDIF};
 
 // --------------------------------------------------------------------------
 // ICC profile routines -----------------------------------------------------
 // --------------------------------------------------------------------------
 
-function FreeImage_GetICCProfile(dib: PFIBITMAP): PFIICCPROFILE; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetICCProfile at 4'{$ENDIF};
+function FreeImage_GetICCProfile(dib: PFIBITMAP): PFIICCPROFILE; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetICCProfile at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetICCProfile'{$ENDIF};
 function FreeImage_CreateICCProfile(dib: PFIBITMAP; data: Pointer;
-  size: LongInt): PFIICCPROFILE; stdcall;
-  external FIDLL {$IFDEF WIN32}name 'FreeImage_CreateICCProfile at 12'{$ENDIF};
-procedure FreeImage_DestroyICCProfile(dib: PFIBITMAP); stdcall;
-  external FIDLL {$IFDEF WIN32}name 'FreeImage_DestroyICCProfile at 4'{$ENDIF};
+  size: LongInt): PFIICCPROFILE; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name 'FreeImage_CreateICCProfile at 12'{$ENDIF}
+  {$IFDEF MACOS}name 'FreeImage_CreateICCProfile'{$ENDIF};
+procedure FreeImage_DestroyICCProfile(dib: PFIBITMAP); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name 'FreeImage_DestroyICCProfile at 4'{$ENDIF}
+  {$IFDEF MACOS}name 'FreeImage_DestroyICCProfile'{$ENDIF};
 
 // --------------------------------------------------------------------------
 // Line conversion routines -------------------------------------------------
 // --------------------------------------------------------------------------
 
-procedure FreeImage_ConvertLine1To4(target, source: PByte; width_in_pixels: Integer); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine1To4 at 12'{$ENDIF};
+procedure FreeImage_ConvertLine1To4(target, source: PByte; width_in_pixels: Integer); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine1To4 at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertLine1To4'{$ENDIF};
 procedure FreeImage_ConvertLine8To4(target, source: PByte; width_in_pixels: Integer;
-  palette: PRGBQuad);  stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine8To4 at 16'{$ENDIF};
-procedure FreeImage_ConvertLine16To4_555(target, source: PByte; width_in_pixels: Integer); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine16To4_555 at 12'{$ENDIF};
-procedure FreeImage_ConvertLine16To4_565(target, source: PByte; width_in_pixels: Integer); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine16To4_565 at 12'{$ENDIF};
-procedure FreeImage_ConvertLine24To4(target, source: PByte; width_in_pixels: Integer); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine24To4 at 12'{$ENDIF};
-procedure FreeImage_ConvertLine32To4(target, source: PByte; width_in_pixels: Integer); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine32To4 at 12'{$ENDIF};
-
-procedure FreeImage_ConvertLine1To8(target, source: PByte; width_in_pixels: Integer); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine1To8 at 12'{$ENDIF};
-procedure FreeImage_ConvertLine4To8(target, source: PByte; width_in_pixels: Integer); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine4To8 at 12'{$ENDIF};
-procedure FreeImage_ConvertLine16To8_555(target, source: PByte; width_in_pixels: Integer); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine16To8_555 at 12'{$ENDIF};
-procedure FreeImage_ConvertLine16To8_565(target, source: PByte; width_in_pixels: Integer); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine16To8_565 at 12'{$ENDIF};
-procedure FreeImage_ConvertLine24To8(target, source: PByte; width_in_pixels: Integer); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine24To8 at 12'{$ENDIF};
-procedure FreeImage_ConvertLine32To8(target, source: PByte; width_in_pixels: Integer); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine32To8 at 12'{$ENDIF};
+  palette: PRGBQuad); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine8To4 at 16'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertLine8To4'{$ENDIF};
+procedure FreeImage_ConvertLine16To4_555(target, source: PByte; width_in_pixels: Integer); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine16To4_555 at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertLine16To4_555'{$ENDIF};
+procedure FreeImage_ConvertLine16To4_565(target, source: PByte; width_in_pixels: Integer); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine16To4_565 at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertLine16To4_565'{$ENDIF};
+procedure FreeImage_ConvertLine24To4(target, source: PByte; width_in_pixels: Integer); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine24To4 at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertLine24To4'{$ENDIF};
+procedure FreeImage_ConvertLine32To4(target, source: PByte; width_in_pixels: Integer); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine32To4 at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertLine32To4'{$ENDIF};
+
+procedure FreeImage_ConvertLine1To8(target, source: PByte; width_in_pixels: Integer); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine1To8 at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertLine1To8'{$ENDIF};
+procedure FreeImage_ConvertLine4To8(target, source: PByte; width_in_pixels: Integer); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine4To8 at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertLine4To8'{$ENDIF};
+procedure FreeImage_ConvertLine16To8_555(target, source: PByte; width_in_pixels: Integer); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine16To8_555 at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertLine16To8_555'{$ENDIF};
+procedure FreeImage_ConvertLine16To8_565(target, source: PByte; width_in_pixels: Integer); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine16To8_565 at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertLine16To8_565'{$ENDIF};
+procedure FreeImage_ConvertLine24To8(target, source: PByte; width_in_pixels: Integer); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine24To8 at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertLine24To8'{$ENDIF};
+procedure FreeImage_ConvertLine32To8(target, source: PByte; width_in_pixels: Integer); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine32To8 at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertLine32To8'{$ENDIF};
 
 procedure FreeImage_ConvertLine1To16_555(target, source: PByte; width_in_pixels: Integer;
-  palette: PRGBQuad); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine1To16_555 at 16'{$ENDIF};
+  palette: PRGBQuad); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine1To16_555 at 16'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertLine1To16_555'{$ENDIF};
 procedure FreeImage_ConvertLine4To16_555(target, source: PByte; width_in_pixels: Integer;
-  palette: PRGBQuad); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine4To16_555 at 16'{$ENDIF};
+  palette: PRGBQuad); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine4To16_555 at 16'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertLine4To16_555'{$ENDIF};
 procedure FreeImage_ConvertLine8To16_555(target, source: PByte; width_in_pixels: Integer;
-  palette: PRGBQuad); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine8To16_555 at 16'{$ENDIF};
-procedure FreeImage_ConvertLine16_565_To16_555(target, source: PByte; width_in_pixels: Integer); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine16_565_To16_555 at 12'{$ENDIF};
-procedure FreeImage_ConvertLine24To16_555(target, source: PByte; width_in_pixels: Integer); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine24To16_555 at 12'{$ENDIF};
-procedure FreeImage_ConvertLine32To16_555(target, source: PByte; width_in_pixels: Integer); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine32To16_555 at 12'{$ENDIF};
+  palette: PRGBQuad); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine8To16_555 at 16'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertLine8To16_555'{$ENDIF};
+procedure FreeImage_ConvertLine16_565_To16_555(target, source: PByte; width_in_pixels: Integer); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine16_565_To16_555 at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertLine16_565_To16_555'{$ENDIF};
+procedure FreeImage_ConvertLine24To16_555(target, source: PByte; width_in_pixels: Integer); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine24To16_555 at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertLine24To16_555'{$ENDIF};
+procedure FreeImage_ConvertLine32To16_555(target, source: PByte; width_in_pixels: Integer); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine32To16_555 at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertLine32To16_555'{$ENDIF};
 
 procedure FreeImage_ConvertLine1To16_565(target, source: PByte; width_in_pixels: Integer;
-  palette: PRGBQuad); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine1To16_565 at 16'{$ENDIF};
+  palette: PRGBQuad); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine1To16_565 at 16'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertLine1To16_565'{$ENDIF};
 procedure FreeImage_ConvertLine4To16_565(target, source: PByte; width_in_pixels: Integer;
-  palette: PRGBQuad); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine4To16_565 at 16'{$ENDIF};
+  palette: PRGBQuad); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine4To16_565 at 16'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertLine4To16_565'{$ENDIF};
 procedure FreeImage_ConvertLine8To16_565(target, source: PByte; width_in_pixels: Integer;
-  palette: PRGBQuad); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine8To16_565 at 16'{$ENDIF};
-procedure FreeImage_ConvertLine16_555_To16_565(target, source: PByte; width_in_pixels: Integer); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine16_555_To16_565 at 12'{$ENDIF};
-procedure FreeImage_ConvertLine24To16_565(target, source: PByte; width_in_pixels: Integer); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine24To16_565 at 12'{$ENDIF};
-procedure FreeImage_ConvertLine32To16_565(target, source: PByte; width_in_pixels: Integer); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine32To16_565 at 12'{$ENDIF};
+  palette: PRGBQuad); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine8To16_565 at 16'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertLine8To16_565'{$ENDIF};
+procedure FreeImage_ConvertLine16_555_To16_565(target, source: PByte; width_in_pixels: Integer); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine16_555_To16_565 at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertLine16_555_To16_565'{$ENDIF};
+procedure FreeImage_ConvertLine24To16_565(target, source: PByte; width_in_pixels: Integer); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine24To16_565 at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertLine24To16_565'{$ENDIF};
+procedure FreeImage_ConvertLine32To16_565(target, source: PByte; width_in_pixels: Integer); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine32To16_565 at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertLine32To16_565'{$ENDIF};
 
 procedure FreeImage_ConvertLine1To24(target, source: PByte; width_in_pixels: Integer;
-  palette: PRGBQuad); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine1To24 at 16'{$ENDIF};
+  palette: PRGBQuad); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine1To24 at 16'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertLine1To24'{$ENDIF};
 procedure FreeImage_ConvertLine4To24(target, source: PByte; width_in_pixels: Integer;
-  palette: PRGBQuad); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine4To24 at 16'{$ENDIF};
+  palette: PRGBQuad); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine4To24 at 16'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertLine4To24'{$ENDIF};
 procedure FreeImage_ConvertLine8To24(target, source: PByte; width_in_pixels: Integer;
-  palette: PRGBQuad); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine8To24 at 16'{$ENDIF};
-procedure FreeImage_ConvertLine16To24_555(target, source: PByte; width_in_pixels: Integer); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine16To24_555 at 12'{$ENDIF};
-procedure FreeImage_ConvertLine16To24_565(target, source: PByte; width_in_pixels: Integer); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine16To24_565 at 12'{$ENDIF};
-procedure FreeImage_ConvertLine32To24(target, source: PByte; width_in_pixels: Integer); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine32To24 at 12'{$ENDIF};
+  palette: PRGBQuad); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine8To24 at 16'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertLine8To24'{$ENDIF};
+procedure FreeImage_ConvertLine16To24_555(target, source: PByte; width_in_pixels: Integer); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine16To24_555 at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertLine16To24_555'{$ENDIF};
+procedure FreeImage_ConvertLine16To24_565(target, source: PByte; width_in_pixels: Integer); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine16To24_565 at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertLine16To24_565'{$ENDIF};
+procedure FreeImage_ConvertLine32To24(target, source: PByte; width_in_pixels: Integer); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine32To24 at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertLine32To24'{$ENDIF};
 
 procedure FreeImage_ConvertLine1To32(target, source: PByte; width_in_pixels: Integer;
-  palette: PRGBQuad); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine1To32 at 16'{$ENDIF};
+  palette: PRGBQuad); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine1To32 at 16'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertLine1To32'{$ENDIF};
 procedure FreeImage_ConvertLine4To32(target, source: PByte; width_in_pixels: Integer;
-  palette: PRGBQuad); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine4To32 at 16'{$ENDIF};
+  palette: PRGBQuad); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine4To32 at 16'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertLine4To32'{$ENDIF};
 procedure FreeImage_ConvertLine8To32(target, source: PByte; width_in_pixels: Integer;
-  palette: PRGBQuad); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine8To32 at 16'{$ENDIF};
-procedure FreeImage_ConvertLine16To32_555(target, source: PByte; width_in_pixels: Integer); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine16To32_555 at 12'{$ENDIF};
-procedure FreeImage_ConvertLine16To32_565(target, source: PByte; width_in_pixels: Integer); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine16To32_565 at 12'{$ENDIF};
-procedure FreeImage_ConvertLine24To32(target, source: PByte; width_in_pixels: Integer); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine24To32 at 12'{$ENDIF};
+  palette: PRGBQuad); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine8To32 at 16'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertLine8To32'{$ENDIF};
+procedure FreeImage_ConvertLine16To32_555(target, source: PByte; width_in_pixels: Integer); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine16To32_555 at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertLine16To32_555'{$ENDIF};
+procedure FreeImage_ConvertLine16To32_565(target, source: PByte; width_in_pixels: Integer); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine16To32_565 at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertLine16To32_565'{$ENDIF};
+procedure FreeImage_ConvertLine24To32(target, source: PByte; width_in_pixels: Integer); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertLine24To32 at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertLine24To32'{$ENDIF};
 
 // --------------------------------------------------------------------------
 // Smart conversion routines ------------------------------------------------
 // --------------------------------------------------------------------------
 
-function FreeImage_ConvertTo4Bits(dib: PFIBITMAP): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertTo4Bits at 4'{$ENDIF};
-function FreeImage_ConvertTo8Bits(dib: PFIBITMAP): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertTo8Bits at 4'{$ENDIF};
-function FreeImage_ConvertToGreyscale(dib: PFIBITMAP): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertToGreyscale at 4'{$ENDIF};
-function FreeImage_ConvertTo16Bits555(dib: PFIBITMAP): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertTo16Bits555 at 4'{$ENDIF};
-function FreeImage_ConvertTo16Bits565(dib: PFIBITMAP): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertTo16Bits565 at 4'{$ENDIF};
-function FreeImage_ConvertTo24Bits(dib: PFIBITMAP): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertTo24Bits at 4'{$ENDIF};
-function FreeImage_ConvertTo32Bits(dib: PFIBITMAP): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertTo32Bits at 4'{$ENDIF};
-function FreeImage_ColorQuantize(dib: PFIBITMAP; quantize: FREE_IMAGE_QUANTIZE): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ColorQuantize at 8'{$ENDIF};
+function FreeImage_ConvertTo4Bits(dib: PFIBITMAP): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertTo4Bits at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertTo4Bits'{$ENDIF};
+function FreeImage_ConvertTo8Bits(dib: PFIBITMAP): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertTo8Bits at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertTo8Bits'{$ENDIF};
+function FreeImage_ConvertToGreyscale(dib: PFIBITMAP): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertToGreyscale at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertToGreyscale'{$ENDIF};
+function FreeImage_ConvertTo16Bits555(dib: PFIBITMAP): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertTo16Bits555 at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertTo16Bits555'{$ENDIF};
+function FreeImage_ConvertTo16Bits565(dib: PFIBITMAP): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertTo16Bits565 at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertTo16Bits565'{$ENDIF};
+function FreeImage_ConvertTo24Bits(dib: PFIBITMAP): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertTo24Bits at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertTo24Bits'{$ENDIF};
+function FreeImage_ConvertTo32Bits(dib: PFIBITMAP): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertTo32Bits at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertTo32Bits'{$ENDIF};
+function FreeImage_ColorQuantize(dib: PFIBITMAP; quantize: FREE_IMAGE_QUANTIZE): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ColorQuantize at 8'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ColorQuantize'{$ENDIF};
 function FreeImage_ColorQuantizeEx(dib: PFIBITMAP; quantize: FREE_IMAGE_QUANTIZE = FIQ_WUQUANT;
   PaletteSize: Integer = 256; ReserveSize: Integer = 0;
-  ReservePalette: PRGBQuad = nil): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ColorQuantizeEx at 20'{$ENDIF};
-function FreeImage_Threshold(dib: PFIBITMAP; T: Byte): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_Threshold at 8'{$ENDIF};
-function FreeImage_Dither(dib: PFIBITMAP; algorithm: FREE_IMAGE_DITHER): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_Dither at 8'{$ENDIF};
+  ReservePalette: PRGBQuad = nil): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ColorQuantizeEx at 20'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ColorQuantizeEx'{$ENDIF};
+function FreeImage_Threshold(dib: PFIBITMAP; T: Byte): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_Threshold at 8'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_Threshold'{$ENDIF};
+function FreeImage_Dither(dib: PFIBITMAP; algorithm: FREE_IMAGE_DITHER): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_Dither at 8'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_Dither'{$ENDIF};
 
 function FreeImage_ConvertFromRawBits(bits: PByte; width, height, pitch: Integer;
-  bpp, red_mask, green_mask, blue_mask: Cardinal; topdown: LongBool = False): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertFromRawBits at 36'{$ENDIF};
+  bpp, red_mask, green_mask, blue_mask: Cardinal; topdown: LongBool = False): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertFromRawBits at 36'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertFromRawBits'{$ENDIF};
+function FreeImage_ConvertFromRawBitsEx(copySource: LongBool; bits: PByte; _type: FREE_IMAGE_TYPE;
+  width, height, pitch: Integer; bpp, red_mask, green_mask, blue_mask: Cardinal;
+  topdown: LongBool = False): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertFromRawBitsEx at 44'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertFromRawBitsEx'{$ENDIF};
 procedure FreeImage_ConvertToRawBits(bits: PByte; dib: PFIBITMAP; pitch: Integer;
-  bpp, red_mask, green_mask, blue_mask: Cardinal; topdown: LongBool = False); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertToRawBits at 32'{$ENDIF};
-
-function FreeImage_ConvertToFloat(dib: PFIBITMAP): PFIBITMAP;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertToFloat at 4'{$ENDIF};
-function FreeImage_ConvertToRGBF(dib: PFIBITMAP): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertToRGBF at 4'{$ENDIF};
-function FreeImage_ConvertToUINT16(dib: PFIBITMAP): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertToUINT16 at 4'{$ENDIF};
-function FreeImage_ConvertToRGB16(dib: PFIBITMAP): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertToRGB16 at 4'{$ENDIF};
+  bpp, red_mask, green_mask, blue_mask: Cardinal; topdown: LongBool = False); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertToRawBits at 32'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertToRawBits'{$ENDIF};
+
+function FreeImage_ConvertToFloat(dib: PFIBITMAP): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertToFloat at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertToFloat'{$ENDIF};
+function FreeImage_ConvertToRGBF(dib: PFIBITMAP): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertToRGBF at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertToRGBF'{$ENDIF};
+function FreeImage_ConvertToUINT16(dib: PFIBITMAP): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertToUINT16 at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertToUINT16'{$ENDIF};
+function FreeImage_ConvertToRGB16(dib: PFIBITMAP): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertToRGB16 at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertToRGB16'{$ENDIF};
 
 function FreeImage_ConvertToStandardType(src: PFIBITMAP;
-  scale_linear: LongBool = True): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertToStandardType at 8'{$ENDIF};
+  scale_linear: LongBool = True): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertToStandardType at 8'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertToStandardType'{$ENDIF};
 function FreeImage_ConvertToType(src: PFIBITMAP; dst_type: FREE_IMAGE_TYPE;
-  scale_linear: LongBool = True): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertToType at 12'{$ENDIF};
+  scale_linear: LongBool = True): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ConvertToType at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ConvertToType'{$ENDIF};
 
-// tone mapping operators
+// Tone mapping operators ---------------------------------------------------
 function FreeImage_ToneMapping(dib: PFIBITMAP; tmo: FREE_IMAGE_TMO;
-  first_param: Double = 0; second_param: Double = 0): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ToneMapping at 24'{$ENDIF};
+  first_param: Double = 0; second_param: Double = 0): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ToneMapping at 24'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ToneMapping'{$ENDIF};
 function FreeImage_TmoDrago03(src: PFIBITMAP; gamma: Double = 2.2;
-  exposure: Double = 0): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_TmoDrago03 at 20'{$ENDIF};
+  exposure: Double = 0): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_TmoDrago03 at 20'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_TmoDrago03'{$ENDIF};
 function FreeImage_TmoReinhard05(src: PFIBITMAP; intensity: Double = 0;
-  contrast: Double = 0): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_TmoReinhard05 at 20'{$ENDIF};
+  contrast: Double = 0): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_TmoReinhard05 at 20'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_TmoReinhard05'{$ENDIF};
 function FreeImage_TmoReinhard05Ex(src: PFIBITMAP; intensity: Double = 0;
-  contrast: Double = 0; adaptation: Double = 1; color_correction: Double = 0): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_TmoReinhard05Ex at 36'{$ENDIF};
+  contrast: Double = 0; adaptation: Double = 1; color_correction: Double = 0): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_TmoReinhard05Ex at 36'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_TmoReinhard05Ex'{$ENDIF};
 
 function FreeImage_TmoFattal02(src: PFIBITMAP; color_saturation: Double = 0.5;
-  attenuation: Double = 0.85): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_TmoFattal02 at 20'{$ENDIF};
+  attenuation: Double = 0.85): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_TmoFattal02 at 20'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_TmoFattal02'{$ENDIF};
 
 // --------------------------------------------------------------------------
 // ZLib interface -----------------------------------------------------------
 // --------------------------------------------------------------------------
 
-function FreeImage_ZLibCompress(target: PByte; target_size: DWORD; source: PByte; source_size: DWORD): DWORD; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ZLibCompress at 16'{$ENDIF};
-function FreeImage_ZLibUncompress(target: PByte; target_size: DWORD; source: PByte; source_size: DWORD): DWORD; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ZLibUncompress at 16'{$ENDIF};
-function FreeImage_ZLibGZip(target: PByte; target_size: DWORD; source: PByte; source_size: DWORD): DWORD; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ZLibGZip at 16'{$ENDIF};
-function FreeImage_ZLibGUnzip(target: PByte; target_size: DWORD; source: PByte; source_size: DWORD): DWORD; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ZLibGUnzip at 16'{$ENDIF};
-function FreeImage_ZLibCRC32(crc: DWORD; source: PByte; source_size: DWORD): DWORD; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ZLibCRC32 at 12'{$ENDIF};
+function FreeImage_ZLibCompress(target: PByte; target_size: DWORD; source: PByte; source_size: DWORD): DWORD; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ZLibCompress at 16'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ZLibCompress'{$ENDIF};
+function FreeImage_ZLibUncompress(target: PByte; target_size: DWORD; source: PByte; source_size: DWORD): DWORD; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ZLibUncompress at 16'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ZLibUncompress'{$ENDIF};
+function FreeImage_ZLibGZip(target: PByte; target_size: DWORD; source: PByte; source_size: DWORD): DWORD; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ZLibGZip at 16'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ZLibGZip'{$ENDIF};
+function FreeImage_ZLibGUnzip(target: PByte; target_size: DWORD; source: PByte; source_size: DWORD): DWORD; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ZLibGUnzip at 16'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ZLibGUnzip'{$ENDIF};
+function FreeImage_ZLibCRC32(crc: DWORD; source: PByte; source_size: DWORD): DWORD; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ZLibCRC32 at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ZLibCRC32'{$ENDIF};
 
 // --------------------------------------------------------------------------
-// Metadata routines --------------------------------------------------------
+// Metadata routines
 // --------------------------------------------------------------------------
 
 // tag creation / destruction
-function FreeImage_CreateTag: PFITAG; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_CreateTag at 0'{$ENDIF};
-procedure FreeImage_DeleteTag(tag: PFITAG); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_DeleteTag at 4'{$ENDIF};
-function FreeImage_CloneTag(tag: PFITAG): PFITAG; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_CloneTag at 4'{$ENDIF};
+function FreeImage_CreateTag: PFITAG; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_CreateTag at 0'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_CreateTag'{$ENDIF};
+procedure FreeImage_DeleteTag(tag: PFITAG); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_DeleteTag at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_DeleteTag'{$ENDIF};
+function FreeImage_CloneTag(tag: PFITAG): PFITAG; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_CloneTag at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_CloneTag'{$ENDIF};
 
 // tag getters and setters
-function FreeImage_GetTagKey(tag: PFITAG): PAnsiChar; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetTagKey at 4'{$ENDIF};
-function FreeImage_GetTagDescription(tag: PFITAG): PAnsiChar; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetTagDescription at 4'{$ENDIF};
-function FreeImage_GetTagID(tag: PFITAG): Word; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetTagID at 4'{$ENDIF};
-function FreeImage_GetTagType(tag: PFITAG): FREE_IMAGE_MDTYPE; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetTagType at 4'{$ENDIF};
-function FreeImage_GetTagCount(tag: PFITAG): DWORD; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetTagCount at 4'{$ENDIF};
-function FreeImage_GetTagLength(tag: PFITAG): DWORD; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetTagLength at 4'{$ENDIF};
-function FreeImage_GetTagValue(tag: PFITAG): Pointer; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetTagValue at 4'{$ENDIF};
-
-function FreeImage_SetTagKey(tag: PFITAG; key: PAnsiChar): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetTagKey at 8'{$ENDIF};
-function FreeImage_SetTagDescription(tag: PFITAG; description: PAnsiChar): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetTagDescription at 8'{$ENDIF};
-function FreeImage_SetTagID(tag: PFITAG; id: Word): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetTagID at 8'{$ENDIF};
-function FreeImage_SetTagType(tag: PFITAG; atype: FREE_IMAGE_MDTYPE): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetTagType at 8'{$ENDIF};
-function FreeImage_SetTagCount(tag: PFITAG; count: DWORD): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetTagCount at 8'{$ENDIF};
-function FreeImage_SetTagLength(tag: PFITAG; length: DWORD): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetTagLength at 8'{$ENDIF};
-function FreeImage_SetTagValue(tag: PFITAG; value: Pointer): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetTagValue at 8'{$ENDIF};
+function FreeImage_GetTagKey(tag: PFITAG): PAnsiChar; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetTagKey at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetTagKey'{$ENDIF};
+function FreeImage_GetTagDescription(tag: PFITAG): PAnsiChar; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetTagDescription at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetTagDescription'{$ENDIF};
+function FreeImage_GetTagID(tag: PFITAG): Word; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetTagID at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetTagID'{$ENDIF};
+function FreeImage_GetTagType(tag: PFITAG): FREE_IMAGE_MDTYPE; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetTagType at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetTagType'{$ENDIF};
+function FreeImage_GetTagCount(tag: PFITAG): DWORD; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetTagCount at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetTagCount'{$ENDIF};
+function FreeImage_GetTagLength(tag: PFITAG): DWORD; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetTagLength at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetTagLength'{$ENDIF};
+function FreeImage_GetTagValue(tag: PFITAG): Pointer; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetTagValue at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetTagValue'{$ENDIF};
+
+function FreeImage_SetTagKey(tag: PFITAG; key: PAnsiChar): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetTagKey at 8'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_SetTagKey'{$ENDIF};
+function FreeImage_SetTagDescription(tag: PFITAG; description: PAnsiChar): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetTagDescription at 8'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_SetTagDescription'{$ENDIF};
+function FreeImage_SetTagID(tag: PFITAG; id: Word): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetTagID at 8'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_SetTagID'{$ENDIF};
+function FreeImage_SetTagType(tag: PFITAG; _type: FREE_IMAGE_MDTYPE): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetTagType at 8'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_SetTagType'{$ENDIF};
+function FreeImage_SetTagCount(tag: PFITAG; count: DWORD): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetTagCount at 8'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_SetTagCount'{$ENDIF};
+function FreeImage_SetTagLength(tag: PFITAG; length: DWORD): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetTagLength at 8'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_SetTagLength'{$ENDIF};
+function FreeImage_SetTagValue(tag: PFITAG; value: Pointer): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetTagValue at 8'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_SetTagValue'{$ENDIF};
 
 // iterator
 function FreeImage_FindFirstMetadata(model: FREE_IMAGE_MDMODEL; dib: PFIBITMAP;
-  var tag: PFITAG): PFIMETADATA; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_FindFirstMetadata at 12'{$ENDIF};
-function FreeImage_FindNextMetadata(mdhandle: PFIMETADATA; var tag: PFITAG): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_FindNextMetadata at 8'{$ENDIF};
-procedure FreeImage_FindCloseMetadata(mdhandle: PFIMETADATA); stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_FindCloseMetadata at 4'{$ENDIF};
+  var tag: PFITAG): PFIMETADATA; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_FindFirstMetadata at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_FindFirstMetadata'{$ENDIF};
+function FreeImage_FindNextMetadata(mdhandle: PFIMETADATA; var tag: PFITAG): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_FindNextMetadata at 8'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_FindNextMetadata'{$ENDIF};
+procedure FreeImage_FindCloseMetadata(mdhandle: PFIMETADATA); {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_FindCloseMetadata at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_FindCloseMetadata'{$ENDIF};
 
 // metadata setter and getter
 function FreeImage_SetMetadata(model: FREE_IMAGE_MDMODEL; dib: PFIBITMAP;
-  key: PAnsiChar; tag: PFITAG): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetMetadata at 16'{$ENDIF};
+  key: PAnsiChar; tag: PFITAG): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetMetadata at 16'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_SetMetadata'{$ENDIF};
 function FreeImage_GetMetadata(model: FREE_IMAGE_MDMODEL; dib: PFIBITMAP;
-  key: PAnsiChar; var tag: PFITAG): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetMetadata at 16'{$ENDIF};
+  key: PAnsiChar; var tag: PFITAG): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetMetadata at 16'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetMetadata'{$ENDIF};
 
 // helpers
-function FreeImage_GetMetadataCount(model: FREE_IMAGE_MDMODEL; dib: PFIBITMAP): Cardinal; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetMetadataCount at 8'{$ENDIF};
-function FreeImage_CloneMetadata(dst, src: PFIBITMAP): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_CloneMetadata at 8'{$ENDIF};
+function FreeImage_GetMetadataCount(model: FREE_IMAGE_MDMODEL; dib: PFIBITMAP): Cardinal; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetMetadataCount at 8'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetMetadataCount'{$ENDIF};
+function FreeImage_CloneMetadata(dst, src: PFIBITMAP): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_CloneMetadata at 8'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_CloneMetadata'{$ENDIF};
 
 // tag to C string conversion
 function FreeImage_TagToString(model: FREE_IMAGE_MDMODEL; tag: PFITAG;
-  Make: PAnsiChar = nil): PAnsiChar; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_TagToString at 12'{$ENDIF};
+  Make: PAnsiChar = nil): PAnsiChar; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_TagToString at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_TagToString'{$ENDIF};
 
 // --------------------------------------------------------------------------
-// Image manipulation toolkit -----------------------------------------------
+// JPEG lossless transformation routines
+// --------------------------------------------------------------------------
+
+function FreeImage_JPEGTransform(src_file, dst_file: PAnsiChar; operation: FREE_IMAGE_JPEG_OPERATION;
+  perfect: LongBool = False): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_JPEGTransform at 16'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_JPEGTransform'{$ENDIF};
+function FreeImage_JPEGTransformU(src_file, dst_file: PWideChar; operation: FREE_IMAGE_JPEG_OPERATION;
+  perfect: LongBool = False): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_JPEGTransformU at 16'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_JPEGTransformU'{$ENDIF};
+function FreeImage_JPEGCrop(src_file, dst_file: PAnsiChar;
+  left, top, right, bottom: Integer): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_JPEGCrop at 24'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_JPEGCrop'{$ENDIF};
+function FreeImage_JPEGCropU(src_file, dst_file: PWideChar;
+  left, top, right, bottom: Integer): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_JPEGCropU at 24'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_JPEGCropU'{$ENDIF};
+function FreeImage_JPEGTransformFromHandle(src_io: PFreeImageIO; src_handle: fi_handle; dst_io: PFreeImageIO;
+  dst_handle: fi_handle; operation: FREE_IMAGE_JPEG_OPERATION; var left, top, right, bottom: Integer;
+  perfect: LongBool = True): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_JPEGTransformFromHandle at 40'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_JPEGTransformFromHandle'{$ENDIF};
+function FreeImage_JPEGTransformCombined(src_file, dst_file: PAnsiChar; operation: FREE_IMAGE_JPEG_OPERATION;
+  var left, top, right, bottom: Integer; perfect: LongBool = True): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_JPEGTransformCombined at 32'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_JPEGTransformCombined'{$ENDIF};
+function FreeImage_JPEGTransformCombinedU(src_file, dst_file: PWideChar; operation: FREE_IMAGE_JPEG_OPERATION;
+  var left, top, right, bottom: Integer; perfect: LongBool = True): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_JPEGTransformCombinedU at 32'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_JPEGTransformCombinedU'{$ENDIF};
+function FreeImage_JPEGTransformCombinedFromMemory(src_stream, dst_stream: PFIMEMORY; operation: FREE_IMAGE_JPEG_OPERATION;
+  var left, top, right, bottom: Integer; perfect: LongBool = True): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_JPEGTransformCombinedFromMemory at 32'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_JPEGTransformCombinedFromMemory'{$ENDIF};
+
+// --------------------------------------------------------------------------
+// Image manipulation toolkit
 // --------------------------------------------------------------------------
 
 // rotation and flipping
 // modif JMB : FreeImage_RotateClassic : deprecated function, call to DeprecationManager in 64 bits crashes freeimage.dll
-//function FreeImage_RotateClassic(dib: PFIBITMAP; angle: Double): PFIBITMAP; stdcall;
-//  external FIDLL {$IFDEF WIN32}name '_FreeImage_RotateClassic at 12'{$ENDIF};
-function FreeImage_Rotate(dib: PFIBITMAP; angle: Double; bkcolor: Pointer = nil): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_Rotate at 16'{$ENDIF};
+//function FreeImage_RotateClassic(dib: PFIBITMAP; angle: Double): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+//  external FIDLL {$IFDEF WIN32}name '_FreeImage_RotateClassic at 12'{$ENDIF}
+//  {$IFDEF MACOS}name '_FreeImage_RotateClassic'{$ENDIF};
+function FreeImage_Rotate(dib: PFIBITMAP; angle: Double; bkcolor: Pointer = nil): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_Rotate at 16'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_Rotate'{$ENDIF};
 function FreeImage_RotateEx(dib: PFIBITMAP; angle, x_shift, y_shift, x_origin, y_origin: Double;
-  use_mask: LongBool): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_RotateEx at 48'{$ENDIF};
-function FreeImage_FlipHorizontal(dib: PFIBITMAP): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_FlipHorizontal at 4'{$ENDIF};
-function FreeImage_FlipVertical(dib: PFIBITMAP): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_FlipVertical at 4'{$ENDIF};
-function FreeImage_JPEGTransform(src_file, dst_file: PAnsiChar; operation: FREE_IMAGE_JPEG_OPERATION;
-  perfect: LongBool = False): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_JPEGTransform at 16'{$ENDIF};
-function FreeImage_JPEGTransformU(src_file, dst_file: PWideChar; operation: FREE_IMAGE_JPEG_OPERATION;
-  perfect: LongBool = False): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_JPEGTransformU at 16'{$ENDIF};
+  use_mask: LongBool): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_RotateEx at 48'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_RotateEx'{$ENDIF};
+function FreeImage_FlipHorizontal(dib: PFIBITMAP): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_FlipHorizontal at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_FlipHorizontal'{$ENDIF};
+function FreeImage_FlipVertical(dib: PFIBITMAP): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_FlipVertical at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_FlipVertical'{$ENDIF};
 
 // upsampling / downsampling
-function FreeImage_Rescale(dib: PFIBITMAP; dst_width, dst_height: Integer; filter: FREE_IMAGE_FILTER): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_Rescale at 16'{$ENDIF};
-function FreeImage_MakeThumbnail(dib: PFIBITMAP; max_pixel_size: Integer; convert: LongBool = True): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_MakeThumbnail at 12'{$ENDIF};
+function FreeImage_Rescale(dib: PFIBITMAP; dst_width, dst_height: Integer;
+  filter: FREE_IMAGE_FILTER = FILTER_CATMULLROM): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_Rescale at 16'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_Rescale'{$ENDIF};
+function FreeImage_MakeThumbnail(dib: PFIBITMAP; max_pixel_size: Integer; convert: LongBool = True): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_MakeThumbnail at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_MakeThumbnail'{$ENDIF};
 
 // color manipulation routines (point operations)
 function FreeImage_AdjustCurve(dib: PFIBITMAP; LUT: PByte;
-  channel: FREE_IMAGE_COLOR_CHANNEL): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_AdjustCurve at 12'{$ENDIF};
-function FreeImage_AdjustGamma(dib: PFIBITMAP; gamma: Double): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_AdjustGamma at 12'{$ENDIF};
-function FreeImage_AdjustBrightness(dib: PFIBITMAP; percentage: Double): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_AdjustBrightness at 12'{$ENDIF};
-function FreeImage_AdjustContrast(dib: PFIBITMAP; percentage: Double): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_AdjustContrast at 12'{$ENDIF};
-function FreeImage_Invert(dib: PFIBITMAP): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_Invert at 4'{$ENDIF};
+  channel: FREE_IMAGE_COLOR_CHANNEL): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_AdjustCurve at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_AdjustCurve'{$ENDIF};
+function FreeImage_AdjustGamma(dib: PFIBITMAP; gamma: Double): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_AdjustGamma at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_AdjustGamma'{$ENDIF};
+function FreeImage_AdjustBrightness(dib: PFIBITMAP; percentage: Double): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_AdjustBrightness at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_AdjustBrightness'{$ENDIF};
+function FreeImage_AdjustContrast(dib: PFIBITMAP; percentage: Double): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_AdjustContrast at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_AdjustContrast'{$ENDIF};
+function FreeImage_Invert(dib: PFIBITMAP): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_Invert at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_Invert'{$ENDIF};
 function FreeImage_GetHistogram(dib: PFIBITMAP; histo: PDWORD;
-  channel: FREE_IMAGE_COLOR_CHANNEL = FICC_BLACK): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetHistogram at 12'{$ENDIF};
+  channel: FREE_IMAGE_COLOR_CHANNEL = FICC_BLACK): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetHistogram at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetHistogram'{$ENDIF};
 function FreeImage_GetAdjustColorsLookupTable(LUT: PByte; brightness, contrast, gamma: Double;
-  invert: LongBool): Integer; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetAdjustColorsLookupTable at 32'{$ENDIF};
+  invert: LongBool): Integer; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetAdjustColorsLookupTable at 32'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetAdjustColorsLookupTable'{$ENDIF};
 function FreeImage_AdjustColors(dib: PFIBITMAP; brightness, contrast, gamma: Double;
-  invert: LongBool = False): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_AdjustColors at 32'{$ENDIF};
+  invert: LongBool = False): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_AdjustColors at 32'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_AdjustColors'{$ENDIF};
 function FreeImage_ApplyColorMapping(dib: PFIBITMAP; srccolors, dstcolors: PRGBQuad;
-  count: Cardinal; ignore_alpha, swap: LongBool): Cardinal; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ApplyColorMapping at 24'{$ENDIF};
+  count: Cardinal; ignore_alpha, swap: LongBool): Cardinal; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ApplyColorMapping at 24'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ApplyColorMapping'{$ENDIF};
 function FreeImage_SwapColors(dib: PFIBITMAP; color_a, color_b: PRGBQuad;
-  ignore_alpha: LongBool): Cardinal; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_SwapColors at 16'{$ENDIF};
+  ignore_alpha: LongBool): Cardinal; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_SwapColors at 16'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_SwapColors'{$ENDIF};
 function FreeImage_ApplyPaletteIndexMapping(dib: PFIBITMAP; srcindices, dstindices: PByte;
-  count: Cardinal; swap: LongBool): Cardinal; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_ApplyPaletteIndexMapping at 20'{$ENDIF};
-function FreeImage_SwapPaletteIndices(dib: PFIBITMAP; index_a, index_b: PByte): Cardinal; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_SwapPaletteIndices at 12'{$ENDIF};
+  count: Cardinal; swap: LongBool): Cardinal; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_ApplyPaletteIndexMapping at 20'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_ApplyPaletteIndexMapping'{$ENDIF};
+function FreeImage_SwapPaletteIndices(dib: PFIBITMAP; index_a, index_b: PByte): Cardinal; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_SwapPaletteIndices at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_SwapPaletteIndices'{$ENDIF};
 
 // channel processing routines
-function FreeImage_GetChannel(dib: PFIBITMAP; channel: FREE_IMAGE_COLOR_CHANNEL): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetChannel at 8'{$ENDIF};
-function FreeImage_SetChannel(dst, src: PFIBITMAP; channel: FREE_IMAGE_COLOR_CHANNEL): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetChannel at 12'{$ENDIF};
-function FreeImage_GetComplexChannel(src: PFIBITMAP; channel: FREE_IMAGE_COLOR_CHANNEL): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetComplexChannel at 8'{$ENDIF};
-function FreeImage_SetComplexChannel(dst, src: PFIBITMAP; channel: FREE_IMAGE_COLOR_CHANNEL): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetComplexChannel at 12'{$ENDIF};
+function FreeImage_GetChannel(dib: PFIBITMAP; channel: FREE_IMAGE_COLOR_CHANNEL): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetChannel at 8'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetChannel'{$ENDIF};
+function FreeImage_SetChannel(dst, src: PFIBITMAP; channel: FREE_IMAGE_COLOR_CHANNEL): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetChannel at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_SetChannel'{$ENDIF};
+function FreeImage_GetComplexChannel(src: PFIBITMAP; channel: FREE_IMAGE_COLOR_CHANNEL): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_GetComplexChannel at 8'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_GetComplexChannel'{$ENDIF};
+function FreeImage_SetComplexChannel(dst, src: PFIBITMAP; channel: FREE_IMAGE_COLOR_CHANNEL): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_SetComplexChannel at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_SetComplexChannel'{$ENDIF};
 
 // copy / paste / composite routines
 
-function FreeImage_Copy(dib: PFIBITMAP; left, top, right, bottom: Integer): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_Copy at 20'{$ENDIF};
-function FreeImage_Paste(dst, src: PFIBITMAP; left, top, alpha: Integer): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_Paste at 20'{$ENDIF};
+function FreeImage_Copy(dib: PFIBITMAP; left, top, right, bottom: Integer): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_Copy at 20'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_Copy'{$ENDIF};
+function FreeImage_Paste(dst, src: PFIBITMAP; left, top, alpha: Integer): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_Paste at 20'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_Paste'{$ENDIF};
 function FreeImage_Composite(fg: PFIBITMAP; useFileBkg: LongBool = False;
-  appBkColor: PRGBQuad = nil; bg: PFIBITMAP = nil): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_Composite at 16'{$ENDIF};
-function FreeImage_JPEGCrop(src_file, dst_file: PAnsiChar;
-  left, top, right, bottom: Integer): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_JPEGCrop at 24'{$ENDIF};
-function FreeImage_JPEGCropU(src_file, dst_file: PWideChar;
-  left, top, right, bottom: Integer): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_JPEGCropU at 24'{$ENDIF};
-function FreeImage_PreMultiplyWithAlpha(dib: PFIBITMAP): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_PreMultiplyWithAlpha at 4'{$ENDIF};
+  appBkColor: PRGBQuad = nil; bg: PFIBITMAP = nil): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_Composite at 16'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_Composite'{$ENDIF};
+function FreeImage_PreMultiplyWithAlpha(dib: PFIBITMAP): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_PreMultiplyWithAlpha at 4'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_PreMultiplyWithAlpha'{$ENDIF};
 
 // background filling routines
 function FreeImage_FillBackground(dib: PFIBITMAP; color: Pointer;
-  options: Integer = 0): LongBool; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_FillBackground at 12'{$ENDIF};
+  options: Integer = 0): LongBool; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_FillBackground at 12'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_FillBackground'{$ENDIF};
 function FreeImage_EnlargeCanvas(src: PFIBITMAP; left, top, right, bottom: Integer;
-  color: Pointer; options: Integer = 0): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_EnlargeCanvas at 28'{$ENDIF};
+  color: Pointer; options: Integer = 0): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_EnlargeCanvas at 28'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_EnlargeCanvas'{$ENDIF};
 function FreeImage_AllocateEx(width, height, bpp: Integer; color: PRGBQuad;
   options: Integer = 0; palette: PRGBQuad = nil; red_mask: Cardinal = 0;
-  green_mask: Cardinal = 0; blue_mask: Cardinal = 0): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_AllocateEx at 36'{$ENDIF};
-function FreeImage_AllocateExT(atype: FREE_IMAGE_TYPE; width, height, bpp: Integer;
+  green_mask: Cardinal = 0; blue_mask: Cardinal = 0): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_AllocateEx at 36'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_AllocateEx'{$ENDIF};
+function FreeImage_AllocateExT(_type: FREE_IMAGE_TYPE; width, height, bpp: Integer;
   color: Pointer; options: Integer = 0; palette: PRGBQuad = nil; red_mask: Cardinal = 0;
-  green_mask: Cardinal = 0; blue_mask: Cardinal = 0): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_AllocateExT at 40'{$ENDIF};
+  green_mask: Cardinal = 0; blue_mask: Cardinal = 0): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_AllocateExT at 40'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_AllocateExT'{$ENDIF};
 
 // miscellaneous algorithms
 function FreeImage_MultigridPoissonSolver(Laplacian: PFIBITMAP;
-  ncycle: Integer = 3): PFIBITMAP; stdcall;
-  external FIDLL {$IFDEF WIN32}name '_FreeImage_MultigridPoissonSolver at 8'{$ENDIF};
+  ncycle: Integer = 3): PFIBITMAP; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+  external FIDLL {$IFDEF WIN32}name '_FreeImage_MultigridPoissonSolver at 8'{$ENDIF}
+  {$IFDEF MACOS}name '_FreeImage_MultigridPoissonSolver'{$ENDIF};
 
 
 implementation
@@ -1325,8 +1609,9 @@ implementation
 uses SysUtils;
 
 //we provide a wrapper since we haven't varargs in older versions of Delphi
-procedure __FreeImage_OutputMessageProc;
+procedure __FreeImage_OutputMessageProc; cdecl;
   external FIDLL name 'FreeImage_OutputMessageProc';
+
 procedure FreeImage_OutputMessageProc(fif: Integer; fmt: PAnsiChar; args: array of const);
   function ArrayToBuffer(Args: array of const;
     var Argv: Pointer; Buffer: Pointer; Size: Cardinal): Integer;
diff --git a/Wrapper/Delphi/src/Version.inc b/Wrapper/Delphi/src/Version.inc
index 03f009f..f72863d 100644
--- a/Wrapper/Delphi/src/Version.inc
+++ b/Wrapper/Delphi/src/Version.inc
@@ -202,4 +202,104 @@
 		{$DEFINE DELPHI2010}
 		{$DEFINE DELPHIXE}
 	{$ENDIF}
+	
+	{$IFDEF VER230}
+		{$DEFINE DELPHI1}
+		{$DEFINE DELPHI2}
+		{$DEFINE DELPHI3}
+		{$DEFINE DELPHI4}
+		{$DEFINE DELPHI5}
+		{$DEFINE DELPHI6}
+		{$DEFINE DELPHI7}
+		{$DEFINE DELPHI8}
+		{$DEFINE DELPHI2005}
+		{$DEFINE DELPHI2006}
+		{$DEFINE DELPHI2007}
+		{$DEFINE DELPHI2009}
+		{$DEFINE DELPHI2010}
+		{$DEFINE DELPHIXE}
+		{$DEFINE DELPHIXE2}
+	{$ENDIF}
+
+	{$IFDEF VER240}
+		{$DEFINE DELPHI1}
+		{$DEFINE DELPHI2}
+		{$DEFINE DELPHI3}
+		{$DEFINE DELPHI4}
+		{$DEFINE DELPHI5}
+		{$DEFINE DELPHI6}
+		{$DEFINE DELPHI7}
+		{$DEFINE DELPHI8}
+		{$DEFINE DELPHI2005}
+		{$DEFINE DELPHI2006}
+		{$DEFINE DELPHI2007}
+		{$DEFINE DELPHI2009}
+		{$DEFINE DELPHI2010}
+		{$DEFINE DELPHIXE}
+		{$DEFINE DELPHIXE2}
+		{$DEFINE DELPHIXE3}
+	{$ENDIF}
+	
+	{$IFDEF VER250}
+		{$DEFINE DELPHI1}
+		{$DEFINE DELPHI2}
+		{$DEFINE DELPHI3}
+		{$DEFINE DELPHI4}
+		{$DEFINE DELPHI5}
+		{$DEFINE DELPHI6}
+		{$DEFINE DELPHI7}
+		{$DEFINE DELPHI8}
+		{$DEFINE DELPHI2005}
+		{$DEFINE DELPHI2006}
+		{$DEFINE DELPHI2007}
+		{$DEFINE DELPHI2009}
+		{$DEFINE DELPHI2010}
+		{$DEFINE DELPHIXE}
+		{$DEFINE DELPHIXE2}
+		{$DEFINE DELPHIXE3}
+		{$DEFINE DELPHIXE4}
+	{$ENDIF}
+
+	{$IFDEF VER260}
+		{$DEFINE DELPHI1}
+		{$DEFINE DELPHI2}
+		{$DEFINE DELPHI3}
+		{$DEFINE DELPHI4}
+		{$DEFINE DELPHI5}
+		{$DEFINE DELPHI6}
+		{$DEFINE DELPHI7}
+		{$DEFINE DELPHI8}
+		{$DEFINE DELPHI2005}
+		{$DEFINE DELPHI2006}
+		{$DEFINE DELPHI2007}
+		{$DEFINE DELPHI2009}
+		{$DEFINE DELPHI2010}
+		{$DEFINE DELPHIXE}
+		{$DEFINE DELPHIXE2}
+		{$DEFINE DELPHIXE3}
+		{$DEFINE DELPHIXE4}
+		{$DEFINE DELPHIXE5}
+	{$ENDIF}
+
+	{$IFDEF VER270}
+		{$DEFINE DELPHI1}
+		{$DEFINE DELPHI2}
+		{$DEFINE DELPHI3}
+		{$DEFINE DELPHI4}
+		{$DEFINE DELPHI5}
+		{$DEFINE DELPHI6}
+		{$DEFINE DELPHI7}
+		{$DEFINE DELPHI8}
+		{$DEFINE DELPHI2005}
+		{$DEFINE DELPHI2006}
+		{$DEFINE DELPHI2007}
+		{$DEFINE DELPHI2009}
+		{$DEFINE DELPHI2010}
+		{$DEFINE DELPHIXE}
+		{$DEFINE DELPHIXE2}
+		{$DEFINE DELPHIXE3}
+		{$DEFINE DELPHIXE4}
+		{$DEFINE DELPHIXE5}
+		{$DEFINE DELPHIXE6}
+	{$ENDIF}
 {$ENDIF}
diff --git a/Wrapper/FreeImagePlus/FreeImagePlus.2003.sln b/Wrapper/FreeImagePlus/FreeImagePlus.2003.sln
deleted file mode 100644
index 09dc380..0000000
--- a/Wrapper/FreeImagePlus/FreeImagePlus.2003.sln
+++ /dev/null
@@ -1,21 +0,0 @@
-Microsoft Visual Studio Solution File, Format Version 8.00
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeImagePlus", "FreeImagePlus.2003.vcproj", "{94F36908-A4E2-4533-939D-64FF6EADA5A1}"
-	ProjectSection(ProjectDependencies) = postProject
-	EndProjectSection
-EndProject
-Global
-	GlobalSection(SolutionConfiguration) = preSolution
-		Debug = Debug
-		Release = Release
-	EndGlobalSection
-	GlobalSection(ProjectConfiguration) = postSolution
-		{94F36908-A4E2-4533-939D-64FF6EADA5A1}.Debug.ActiveCfg = Debug|Win32
-		{94F36908-A4E2-4533-939D-64FF6EADA5A1}.Debug.Build.0 = Debug|Win32
-		{94F36908-A4E2-4533-939D-64FF6EADA5A1}.Release.ActiveCfg = Release|Win32
-		{94F36908-A4E2-4533-939D-64FF6EADA5A1}.Release.Build.0 = Release|Win32
-	EndGlobalSection
-	GlobalSection(ExtensibilityGlobals) = postSolution
-	EndGlobalSection
-	GlobalSection(ExtensibilityAddIns) = postSolution
-	EndGlobalSection
-EndGlobal
diff --git a/Wrapper/FreeImagePlus/FreeImagePlus.2003.vcproj b/Wrapper/FreeImagePlus/FreeImagePlus.2003.vcproj
deleted file mode 100644
index 9c7f6b7..0000000
--- a/Wrapper/FreeImagePlus/FreeImagePlus.2003.vcproj
+++ /dev/null
@@ -1,215 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="7.10"
-	Name="FreeImagePlus"
-	ProjectGUID="{94F36908-A4E2-4533-939D-64FF6EADA5A1}"
-	SccProjectName=""
-	SccLocalPath="">
-	<Platforms>
-		<Platform
-			Name="Win32"/>
-	</Platforms>
-	<Configurations>
-		<Configuration
-			Name="Release|Win32"
-			OutputDirectory=".\Release"
-			IntermediateDirectory=".\Release"
-			ConfigurationType="2"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="FALSE"
-			CharacterSet="2">
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="2"
-				GlobalOptimizations="TRUE"
-				InlineFunctionExpansion="2"
-				EnableIntrinsicFunctions="TRUE"
-				FavorSizeOrSpeed="1"
-				OmitFramePointers="TRUE"
-				OptimizeForProcessor="3"
-				AdditionalIncludeDirectories=".,../../Source"
-				PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;_USRDLL;FIP_EXPORTS;_SECURE_NO_DEPRECATE"
-				StringPooling="TRUE"
-				RuntimeLibrary="0"
-				BufferSecurityCheck="FALSE"
-				TreatWChar_tAsBuiltInType="TRUE"
-				UsePrecompiledHeader="2"
-				PrecompiledHeaderFile=".\Release/FreeImagePlus.pch"
-				AssemblerListingLocation=".\Release/"
-				ObjectFile=".\Release/"
-				ProgramDataBaseFileName=".\Release/"
-				WarningLevel="3"
-				SuppressStartupBanner="TRUE"
-				CompileAs="0"/>
-			<Tool
-				Name="VCCustomBuildTool"/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="../../Dist/FreeImage.lib odbc32.lib odbccp32.lib"
-				OutputFile=".\Release/FreeImagePlus.dll"
-				LinkIncremental="1"
-				SuppressStartupBanner="TRUE"
-				ProgramDatabaseFile=".\Release/FreeImagePlus.pdb"
-				ImportLibrary=".\Release/FreeImagePlus.lib"
-				TargetMachine="1"/>
-			<Tool
-				Name="VCMIDLTool"
-				PreprocessorDefinitions="NDEBUG"
-				MkTypLibCompatible="TRUE"
-				SuppressStartupBanner="TRUE"
-				TargetEnvironment="1"
-				TypeLibraryName=".\Release/FreeImagePlus.tlb"
-				HeaderFileName=""/>
-			<Tool
-				Name="VCPostBuildEventTool"
-				CommandLine="copy         Release\FreeImagePlus.lib         dist\
-
-copy         Release\FreeImagePlus.dll         dist\
-
-copy         FreeImagePlus.h         dist\
-
-"/>
-			<Tool
-				Name="VCPreBuildEventTool"/>
-			<Tool
-				Name="VCPreLinkEventTool"/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="1036"/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"/>
-			<Tool
-				Name="VCWebDeploymentTool"/>
-			<Tool
-				Name="VCManagedWrapperGeneratorTool"/>
-			<Tool
-				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
-		</Configuration>
-		<Configuration
-			Name="Debug|Win32"
-			OutputDirectory=".\Debug"
-			IntermediateDirectory=".\Debug"
-			ConfigurationType="2"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="FALSE"
-			CharacterSet="2">
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="0"
-				AdditionalIncludeDirectories=".,../../Source"
-				PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;_USRDLL;FIP_EXPORTS;_SECURE_NO_DEPRECATE"
-				StringPooling="TRUE"
-				BasicRuntimeChecks="3"
-				RuntimeLibrary="1"
-				TreatWChar_tAsBuiltInType="TRUE"
-				UsePrecompiledHeader="2"
-				PrecompiledHeaderFile=".\Debug/FreeImagePlus.pch"
-				AssemblerListingLocation=".\Debug/"
-				ObjectFile=".\Debug/"
-				ProgramDataBaseFileName=".\Debug/"
-				WarningLevel="3"
-				SuppressStartupBanner="TRUE"
-				DebugInformationFormat="4"
-				CompileAs="0"/>
-			<Tool
-				Name="VCCustomBuildTool"/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="../../Dist/FreeImaged.lib odbc32.lib odbccp32.lib"
-				OutputFile="Debug/FreeImagePlusd.dll"
-				LinkIncremental="2"
-				SuppressStartupBanner="TRUE"
-				GenerateDebugInformation="TRUE"
-				ProgramDatabaseFile=".\Debug/FreeImagePlusd.pdb"
-				ImportLibrary=".\Debug/FreeImagePlusd.lib"
-				TargetMachine="1"/>
-			<Tool
-				Name="VCMIDLTool"
-				PreprocessorDefinitions="_DEBUG"
-				MkTypLibCompatible="TRUE"
-				SuppressStartupBanner="TRUE"
-				TargetEnvironment="1"
-				TypeLibraryName=".\Debug/FreeImagePlus.tlb"
-				HeaderFileName=""/>
-			<Tool
-				Name="VCPostBuildEventTool"
-				CommandLine="copy         Debug\FreeImagePlusd.lib         dist\
-
-copy         Debug\FreeImagePlusd.dll         dist\
-
-copy         FreeImagePlus.h         dist\
-
-"/>
-			<Tool
-				Name="VCPreBuildEventTool"/>
-			<Tool
-				Name="VCPreLinkEventTool"/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="_DEBUG"
-				Culture="1036"/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"/>
-			<Tool
-				Name="VCWebDeploymentTool"/>
-			<Tool
-				Name="VCManagedWrapperGeneratorTool"/>
-			<Tool
-				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Source Files"
-			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
-			<File
-				RelativePath="src\fipImage.cpp">
-			</File>
-			<File
-				RelativePath="src\fipMemoryIO.cpp">
-			</File>
-			<File
-				RelativePath="src\fipMetadataFind.cpp">
-			</File>
-			<File
-				RelativePath="src\fipMultiPage.cpp">
-			</File>
-			<File
-				RelativePath="src\fipTag.cpp">
-			</File>
-			<File
-				RelativePath="src\fipWinImage.cpp">
-			</File>
-			<File
-				RelativePath="src\FreeImagePlus.cpp">
-			</File>
-			<File
-				RelativePath="FreeImagePlus.rc">
-			</File>
-		</Filter>
-		<Filter
-			Name="Header Files"
-			Filter="h;hpp;hxx;hm;inl">
-			<File
-				RelativePath="FreeImagePlus.h">
-			</File>
-		</Filter>
-		<Filter
-			Name="Resource Files"
-			Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
-		</Filter>
-		<File
-			RelativePath="WhatsNew_FIP.txt">
-		</File>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
diff --git a/Wrapper/FreeImagePlus/FreeImagePlus.2013.sln b/Wrapper/FreeImagePlus/FreeImagePlus.2013.sln
new file mode 100644
index 0000000..865555c
--- /dev/null
+++ b/Wrapper/FreeImagePlus/FreeImagePlus.2013.sln
@@ -0,0 +1,21 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Express 2013 for Windows Desktop
+VisualStudioVersion = 12.0.21005.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeImagePlus", "FreeImagePlus.2013.vcxproj", "{94F36908-A4E2-4533-939D-64FF6EADA5A1}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{94F36908-A4E2-4533-939D-64FF6EADA5A1}.Debug|Win32.ActiveCfg = Debug|Win32
+		{94F36908-A4E2-4533-939D-64FF6EADA5A1}.Debug|Win32.Build.0 = Debug|Win32
+		{94F36908-A4E2-4533-939D-64FF6EADA5A1}.Release|Win32.ActiveCfg = Release|Win32
+		{94F36908-A4E2-4533-939D-64FF6EADA5A1}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/Wrapper/FreeImagePlus/FreeImagePlus.2013.vcxproj b/Wrapper/FreeImagePlus/FreeImagePlus.2013.vcxproj
new file mode 100644
index 0000000..ba9b5b9
--- /dev/null
+++ b/Wrapper/FreeImagePlus/FreeImagePlus.2013.vcxproj
@@ -0,0 +1,306 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectName>FreeImagePlus</ProjectName>
+    <ProjectGuid>{94F36908-A4E2-4533-939D-64FF6EADA5A1}</ProjectGuid>
+    <RootNamespace>FreeImagePlus</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>12.0.21005.1</_ProjectFileVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+    <LinkIncremental>false</LinkIncremental>
+    <GenerateManifest>false</GenerateManifest>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+    <LinkIncremental>false</LinkIncremental>
+    <GenerateManifest>false</GenerateManifest>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+    <LinkIncremental>true</LinkIncremental>
+    <GenerateManifest>false</GenerateManifest>
+    <TargetName>$(ProjectName)d</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+    <LinkIncremental>true</LinkIncremental>
+    <GenerateManifest>false</GenerateManifest>
+    <TargetName>$(ProjectName)d</TargetName>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Midl>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MkTypLibCompatible>true</MkTypLibCompatible>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <TargetEnvironment>Win32</TargetEnvironment>
+      <TypeLibraryName>.\Release/FreeImagePlus.tlb</TypeLibraryName>
+      <HeaderFileName />
+    </Midl>
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <OmitFramePointers>true</OmitFramePointers>
+      <WholeProgramOptimization>true</WholeProgramOptimization>
+      <AdditionalIncludeDirectories>.;../../Source;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>NDEBUG;WIN32;_WINDOWS;_USRDLL;FIP_EXPORTS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <CompileAs>Default</CompileAs>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+      <DebugInformationFormat>None</DebugInformationFormat>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Link>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention />
+      <TargetMachine>MachineX86</TargetMachine>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+    </Link>
+    <PostBuildEvent>
+      <Command>mkdir dist\x32
+copy $(OutDir)$(TargetName).dll dist\x32
+copy $(OutDir)$(TargetName).lib dist\x32
+copy FreeImagePlus.h dist\x32
+</Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Midl>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MkTypLibCompatible>true</MkTypLibCompatible>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <TargetEnvironment>X64</TargetEnvironment>
+      <TypeLibraryName>.\Release/FreeImagePlus.tlb</TypeLibraryName>
+      <HeaderFileName />
+    </Midl>
+    <ClCompile>
+      <Optimization>Full</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>.;../../Source;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>NDEBUG;WIN32;_WINDOWS;_USRDLL;FIP_EXPORTS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <CompileAs>Default</CompileAs>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+      <DebugInformationFormat>None</DebugInformationFormat>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Link>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention />
+      <TargetMachine>MachineX64</TargetMachine>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+    </Link>
+    <PostBuildEvent>
+      <Command>mkdir dist\x64
+copy $(OutDir)$(TargetName).dll dist\x64
+copy $(OutDir)$(TargetName).lib dist\x64
+copy FreeImagePlus.h dist\x64</Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Midl>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MkTypLibCompatible>true</MkTypLibCompatible>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <TargetEnvironment>Win32</TargetEnvironment>
+      <TypeLibraryName>.\Debug/FreeImagePlus.tlb</TypeLibraryName>
+      <HeaderFileName />
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>.;../../Source;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;_USRDLL;FIP_EXPORTS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <CompileAs>Default</CompileAs>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Link>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention />
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+    <PostBuildEvent>
+      <Command>mkdir dist\x32
+copy $(OutDir)$(TargetName).dll dist\x32
+copy $(OutDir)$(TargetName).lib dist\x32
+copy FreeImagePlus.h dist\x32
+</Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Midl>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MkTypLibCompatible>true</MkTypLibCompatible>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <TargetEnvironment>X64</TargetEnvironment>
+      <TypeLibraryName>.\Debug/FreeImagePlus.tlb</TypeLibraryName>
+      <HeaderFileName />
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>.;../../Source;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;_USRDLL;FIP_EXPORTS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <CompileAs>Default</CompileAs>
+      <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Link>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention />
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <PostBuildEvent>
+      <Command>mkdir dist\x64
+copy $(OutDir)$(TargetName).dll dist\x64
+copy $(OutDir)$(TargetName).lib dist\x64
+copy FreeImagePlus.h dist\x64</Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="src\fipImage.cpp" />
+    <ClCompile Include="src\fipMemoryIO.cpp" />
+    <ClCompile Include="src\fipMetadataFind.cpp" />
+    <ClCompile Include="src\fipMultiPage.cpp" />
+    <ClCompile Include="src\fipTag.cpp" />
+    <ClCompile Include="src\fipWinImage.cpp" />
+    <ClCompile Include="src\FreeImagePlus.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="FreeImagePlus.rc" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="FreeImagePlus.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <Text Include="WhatsNew_FIP.txt" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\FreeImage.2013.vcxproj">
+      <Project>{b39ed2b3-d53a-4077-b957-930979a3577d}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/Wrapper/FreeImagePlus/FreeImagePlus.2013.vcxproj.filters b/Wrapper/FreeImagePlus/FreeImagePlus.2013.vcxproj.filters
new file mode 100644
index 0000000..670b45b
--- /dev/null
+++ b/Wrapper/FreeImagePlus/FreeImagePlus.2013.vcxproj.filters
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{89854f66-f6c5-4c88-bcc7-6141f29b56a1}</UniqueIdentifier>
+      <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{76efef1d-9bed-435d-b007-8156aca779dc}</UniqueIdentifier>
+      <Extensions>h;hpp;hxx;hm;inl</Extensions>
+    </Filter>
+    <Filter Include="Resource Files">
+      <UniqueIdentifier>{b0cfb0e2-0615-4c08-8674-2678f135b147}</UniqueIdentifier>
+      <Extensions>ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="src\fipImage.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="src\fipMemoryIO.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="src\fipMetadataFind.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="src\fipMultiPage.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="src\fipTag.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="src\fipWinImage.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="src\FreeImagePlus.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="FreeImagePlus.rc">
+      <Filter>Source Files</Filter>
+    </ResourceCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="FreeImagePlus.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <Text Include="WhatsNew_FIP.txt" />
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/Wrapper/FreeImagePlus/FreeImagePlus.h b/Wrapper/FreeImagePlus/FreeImagePlus.h
index 28a8d72..571010f 100644
--- a/Wrapper/FreeImagePlus/FreeImagePlus.h
+++ b/Wrapper/FreeImagePlus/FreeImagePlus.h
@@ -374,7 +374,13 @@ public:
 	The size of the bitmap is the BITMAPINFOHEADER + the size of the palette + the size of the bitmap data. 
 	@see FreeImage_GetDIBSize
 	*/
-	LONG getImageSize() const;
+	unsigned getImageSize() const;
+
+	/**
+	Returns the memory footprint of a bitmap, in bytes. 
+	@see FreeImage_GetMemorySize
+	*/
+	unsigned getImageMemorySize() const;
 	
 	/**
 	Returns the bitdepth of the bitmap. <br>
@@ -454,14 +460,14 @@ public:
 
 	/**
 	Retrieves a copy the thumbnail possibly attached to the bitmap
-	@return Returns TRUE if the thumbnail is present in the bitmap and successfully retrieved, returns FALSE otherwise
+	@return Returns TRUE if the thumbnail is present in the bitmap and successfuly retrieved, returns FALSE otherwise
 	@see FreeImage_GetThumbnail
 	*/
 	BOOL getThumbnail(fipImage& image) const;
 
 	/**
 	Attach a thumbnail to the bitmap
-	@return Returns TRUE if the thumbnail was successfully set, returns FALSE otherwise
+	@return Returns TRUE if the thumbnail was successfuly set, returns FALSE otherwise
 	@see FreeImage_SetThumbnail
 	*/
 	BOOL setThumbnail(const fipImage& image);
@@ -507,7 +513,7 @@ public:
 	@param x Pixel position in horizontal direction
 	@param y Pixel position in vertical direction
 	@param value Pixel index (returned value)
-	@return Returns TRUE if successfull, FALSE otherwise. 
+	@return Returns TRUE if successful, FALSE otherwise. 
 	@see FreeImage_GetPixelIndex
 	*/
 	BOOL getPixelIndex(unsigned x, unsigned y, BYTE *value) const;
@@ -517,7 +523,7 @@ public:
 	@param x Pixel position in horizontal direction
 	@param y Pixel position in vertical direction
 	@param value Pixel color (returned value)
-	@return Returns TRUE if successfull, FALSE otherwise. 
+	@return Returns TRUE if successful, FALSE otherwise. 
 	@see FreeImage_GetPixelColor
 	*/
 	BOOL getPixelColor(unsigned x, unsigned y, RGBQUAD *value) const;
@@ -527,7 +533,7 @@ public:
 	@param x Pixel position in horizontal direction
 	@param y Pixel position in vertical direction
 	@param value Pixel index
-	@return Returns TRUE if successfull, FALSE otherwise. 
+	@return Returns TRUE if successful, FALSE otherwise. 
 	@see FreeImage_SetPixelIndex
 	*/
 	BOOL setPixelIndex(unsigned x, unsigned y, BYTE *value);
@@ -537,7 +543,7 @@ public:
 	@param x Pixel position in horizontal direction
 	@param y Pixel position in vertical direction
 	@param value Pixel color
-	@return Returns TRUE if successfull, FALSE otherwise. 
+	@return Returns TRUE if successful, FALSE otherwise. 
 	@see FreeImage_SetPixelColor
 	*/
 	BOOL setPixelColor(unsigned x, unsigned y, RGBQUAD *value);
@@ -552,7 +558,7 @@ public:
 	Converts an image to a type supported by FreeImage.
 	@param image_type New image type
 	@param scale_linear TRUE if image pixels must be scaled linearly when converting to a standard bitmap
-	@return Returns TRUE if successfull, FALSE otherwise. 
+	@return Returns TRUE if successful, FALSE otherwise. 
 	@see FreeImage_ConvertToType, FreeImage_ConvertToStandardType
 	*/
 	BOOL convertToType(FREE_IMAGE_TYPE image_type, BOOL scale_linear = TRUE);
@@ -560,7 +566,7 @@ public:
 	/** 
 	Converts the bitmap to 1 bit using a threshold T.
 	@param T Threshold value in [0..255]
-	@return Returns TRUE if successfull, FALSE otherwise. 
+	@return Returns TRUE if successful, FALSE otherwise. 
 	@see FreeImage_Threshold
 	*/
 	BOOL threshold(BYTE T);
@@ -568,21 +574,21 @@ public:
 	/** 
 	Converts a 8-bit image to a monochrome 1-bit image using a dithering algorithm.
 	@param algorithm Dithering algorithm to use.
-	@return Returns TRUE if successfull, FALSE otherwise. 
+	@return Returns TRUE if successful, FALSE otherwise. 
 	@see FreeImage_Dither, FREE_IMAGE_DITHER
 	*/
 	BOOL dither(FREE_IMAGE_DITHER algorithm);
 
 	/** 
 	Converts the bitmap to 4 bits. Unless the bitmap is a 1-bit palettized bitmap, colour values are converted to greyscale.
-	@return Returns TRUE if successfull, FALSE otherwise. 
+	@return Returns TRUE if successful, FALSE otherwise. 
 	@see FreeImage_ConvertTo4Bits
 	*/
 	BOOL convertTo4Bits();
 
 	/** 
 	Converts the bitmap to 8 bits. If the bitmap is 24 or 32-bit RGB, the colour values are converted to greyscale.
-	@return Returns TRUE if successfull, FALSE otherwise. 
+	@return Returns TRUE if successful, FALSE otherwise. 
 	@see FreeImage_ConvertTo8Bits
 	*/
 	BOOL convertTo8Bits();
@@ -591,7 +597,7 @@ public:
 	Converts the bitmap to 8 bits.<br> 
 	For palletized bitmaps, the color map is converted to a greyscale ramp.
 	@see FreeImage_ConvertToGreyscale
-	@return Returns TRUE if successfull, FALSE otherwise. 
+	@return Returns TRUE if successful, FALSE otherwise. 
 	*/
 	BOOL convertToGrayscale();
 	
@@ -599,67 +605,81 @@ public:
 	Quantizes a full colour 24-bit bitmap to a palletised 8-bit bitmap.<br>
 	The quantize parameter specifies which colour reduction algorithm should be used.
 	@param algorithm Color quantization algorithm to use.
-	@return Returns TRUE if successfull, FALSE otherwise. 
+	@return Returns TRUE if successful, FALSE otherwise. 
 	@see FreeImage_ColorQuantize, FREE_IMAGE_QUANTIZE
 	*/
 	BOOL colorQuantize(FREE_IMAGE_QUANTIZE algorithm);
 
 	/** 
 	Converts the bitmap to 16 bits. The resulting bitmap has a layout of 5 bits red, 5 bits green, 5 bits blue and 1 unused bit. 
-	@return Returns TRUE if successfull, FALSE otherwise. 
+	@return Returns TRUE if successful, FALSE otherwise. 
 	@see FreeImage_ConvertTo16Bits555
 	*/
 	BOOL convertTo16Bits555();
 	
 	/** 
 	Converts the bitmap to 16 bits. The resulting bitmap has a layout of 5 bits red, 6 bits green and 5 bits blue. 
-	@return Returns TRUE if successfull, FALSE otherwise. 
+	@return Returns TRUE if successful, FALSE otherwise. 
 	@see FreeImage_ConvertTo16Bits565
 	*/
 	BOOL convertTo16Bits565();
 	
 	/** 
 	Converts the bitmap to 24 bits. 
-	@return Returns TRUE if successfull, FALSE otherwise. 
+	@return Returns TRUE if successful, FALSE otherwise. 
 	@see FreeImage_ConvertTo24Bits
 	*/
 	BOOL convertTo24Bits();
 	
 	/** 
 	Converts the bitmap to 32 bits. 
-	@return Returns TRUE if successfull, FALSE otherwise. 
+	@return Returns TRUE if successful, FALSE otherwise. 
 	@see FreeImage_ConvertTo32Bits
 	*/
 	BOOL convertTo32Bits();
 
 	/** 
 	Converts the bitmap to a 32-bit float image. 
-	@return Returns TRUE if successfull, FALSE otherwise. 
+	@return Returns TRUE if successful, FALSE otherwise. 
 	@see FreeImage_ConvertToFloat
 	*/
 	BOOL convertToFloat();
 
 	/** 
 	Converts the bitmap to a 96-bit RGBF image. 
-	@return Returns TRUE if successfull, FALSE otherwise. 
+	@return Returns TRUE if successful, FALSE otherwise. 
 	@see FreeImage_ConvertToRGBF
 	*/
 	BOOL convertToRGBF();
 
 	/** 
+	Converts the bitmap to a 128-bit RGBAF image. 
+	@return Returns TRUE if successful, FALSE otherwise. 
+	@see FreeImage_ConvertToRGBAF
+	*/
+	BOOL convertToRGBAF();
+
+	/** 
 	Converts the bitmap to a 16-bit unsigned short image. 
-	@return Returns TRUE if successfull, FALSE otherwise. 
+	@return Returns TRUE if successful, FALSE otherwise. 
 	@see FreeImage_ConvertToUINT16
 	*/
 	BOOL convertToUINT16();
 
 	/** 
 	Converts the bitmap to a 48-bit RGB16 image. 
-	@return Returns TRUE if successfull, FALSE otherwise. 
+	@return Returns TRUE if successful, FALSE otherwise. 
 	@see FreeImage_ConvertToRGB16
 	*/
 	BOOL convertToRGB16();
 
+	/** 
+	Converts the bitmap to a 64-bit RGBA16 image. 
+	@return Returns TRUE if successful, FALSE otherwise. 
+	@see FreeImage_ConvertToRGBA16
+	*/
+	BOOL convertToRGBA16();
+
 	/**
 	Converts a High Dynamic Range image (48-bit RGB or 96-bit RGB Float) to a 24-bit RGB image. 
 	@param tmo Tone mapping operator
@@ -667,7 +687,7 @@ public:
 	@param second_param Second tone mapping algorithm parameter (algorithm dependant)
 	@param third_param Third tone mapping algorithm parameter (algorithm dependant)
 	@param fourth_param Fourth tone mapping algorithm parameter (algorithm dependant)
-	@return Returns TRUE if successfull, FALSE otherwise. 
+	@return Returns TRUE if successful, FALSE otherwise. 
 	@see FreeImage_ToneMapping, FreeImage_TmoReinhard05Ex
 	*/
 	BOOL toneMapping(FREE_IMAGE_TMO tmo, double first_param = 0, double second_param = 0, double third_param = 1, double fourth_param = 0);
diff --git a/Wrapper/FreeImagePlus/FreeImagePlus.rc b/Wrapper/FreeImagePlus/FreeImagePlus.rc
index 95a8b35..740b570 100644
--- a/Wrapper/FreeImagePlus/FreeImagePlus.rc
+++ b/Wrapper/FreeImagePlus/FreeImagePlus.rc
@@ -1,34 +1,13 @@
-//Microsoft Developer Studio generated resource script.
-//
+#include <windows.h>
 
-#define APSTUDIO_READONLY_SYMBOLS
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 2 resource.
-//
-#include "afxres.h"
-
-/////////////////////////////////////////////////////////////////////////////
-#undef APSTUDIO_READONLY_SYMBOLS
-
-/////////////////////////////////////////////////////////////////////////////
-// English (U.S.) resources
-
-#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
-#ifdef _WIN32
-LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
-#pragma code_page(1252)
-#endif //_WIN32
-
-#ifndef _MAC
 /////////////////////////////////////////////////////////////////////////////
 //
 // Version
 //
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 3,15,4,0
- PRODUCTVERSION 3,15,4,0
+ FILEVERSION 3,17,0,0
+ PRODUCTVERSION 3,17,0,0
  FILEFLAGSMASK 0x3fL
 #ifdef _DEBUG
  FILEFLAGS 0x1L
@@ -46,14 +25,14 @@ BEGIN
             VALUE "Comments", "FreeImage is an Open Source library project for developers who would like to support popular graphics image formats like PNG, BMP, JPEG, TIFF and others as needed by today's multimedia applications.\0"
             VALUE "CompanyName", "FreeImage\0"
             VALUE "FileDescription", "FreeImagePlus library\0"
-            VALUE "FileVersion", "3, 15, 4, 0\0"
+            VALUE "FileVersion", "3, 17, 0, 0\0"
             VALUE "InternalName", "FreeImagePlus\0"
-            VALUE "LegalCopyright", "Copyright � 2003-2012 by FreeImage\0"
+            VALUE "LegalCopyright", "Copyright � 2003-2015 by FreeImage\0"
             VALUE "LegalTrademarks", "See http://freeimage.sourceforge.net\0"
             VALUE "OriginalFilename", "FreeImagePlus.dll\0"
             VALUE "PrivateBuild", "\0"
             VALUE "ProductName", "FreeImagePlus\0"
-            VALUE "ProductVersion", "3, 15, 4, 0\0"
+            VALUE "ProductVersion", "3, 17, 0, 0\0"
             VALUE "SpecialBuild", "\0"
         END
     END
@@ -63,33 +42,3 @@ BEGIN
     END
 END
 
-#endif    // !_MAC
-
-#endif    // English (U.S.) resources
-/////////////////////////////////////////////////////////////////////////////
-
-#ifdef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// TEXTINCLUDE
-//
-
-1 TEXTINCLUDE DISCARDABLE 
-BEGIN
-    "#include ""afxres.h""\r\n"
-    "\0"
-END
-
-2 TEXTINCLUDE DISCARDABLE 
-BEGIN
-    "\r\n"
-    "\0"
-END
-
-#endif    // APSTUDIO_INVOKED
-
-
-/////////////////////////////////////////////////////////////////////////////
-
-
-
diff --git a/Wrapper/FreeImagePlus/WhatsNew_FIP.txt b/Wrapper/FreeImagePlus/WhatsNew_FIP.txt
index 45d3f62..15a6877 100644
--- a/Wrapper/FreeImagePlus/WhatsNew_FIP.txt
+++ b/Wrapper/FreeImagePlus/WhatsNew_FIP.txt
@@ -5,6 +5,12 @@ What's New for FreeImagePlus
 ! : changed
 + : added
 
+March 01st, 2015
++ [Herve Drolon] added fipImage::convertToRGBAF
++ [Herve Drolon] added fipImage::convertToRGBA16
++ [Herve Drolon] added fipImage::getImageMemorySize
+* [Herve Drolon] fixed returnd type of fipImage::getImageSize from LONG to unsigned
+
 July 17th, 2011
 + [Herve Drolon] added fipImage::convertToRGB16
 
diff --git a/Wrapper/FreeImagePlus/clean.bat b/Wrapper/FreeImagePlus/clean.bat
index e31eb8f..65a5e36 100644
--- a/Wrapper/FreeImagePlus/clean.bat
+++ b/Wrapper/FreeImagePlus/clean.bat
@@ -1,7 +1,3 @@
-rd Release /s /q
-rd Debug /s /q
-rd x64 /s /q
-rd test\x64 /s /q
 del dist\*.dll /s /q
 del dist\*.lib /s /q
 del dist\*.h /s /q
@@ -10,9 +6,21 @@ del *.plg /s /q
 del *.opt /s /q
 del *.suo /s /q /a:h
 del *.user /s /q
-rd test\Debug /s /q
+del *.log /s /q
+del *.sdf /s /q
 del test\page*.tiff
 del test\*.png
 del test\mpage*.tif
 del test\clone*.tif
 del test\redirect-stream.tif
+rd dist\x64 /s /q
+rd dist\x32 /s /q
+rd Release /s /q
+rd Debug /s /q
+rd x64 /s /q
+rd Win32 /s /q
+rd test\x64 /s /q
+rd test\Win32 /s /q
+rd test\Debug /s /q
+rd test\Release /s /q
+
diff --git a/Wrapper/FreeImagePlus/src/FreeImagePlus.cpp b/Wrapper/FreeImagePlus/src/FreeImagePlus.cpp
index d9bc99e..efb8fe9 100644
--- a/Wrapper/FreeImagePlus/src/FreeImagePlus.cpp
+++ b/Wrapper/FreeImagePlus/src/FreeImagePlus.cpp
@@ -1,46 +1,46 @@
-// ==========================================================
-// FreeImagePlus.cpp : Defines the entry point for the DLL application.
-//
-// Design and implementation by
-// - Herv� Drolon (drolon at infonie.fr)
-//
-// This file is part of FreeImage 3
-//
-// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
-// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
-// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
-// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
-// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
-// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
-// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
-// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
-// THIS DISCLAIMER.
-//
-// Use at your own risk!
-// ==========================================================
-
-#ifdef _WIN32
-#include <windows.h>
-#endif // _WIN32
-
-#include "FreeImagePlus.h"
-
-//----------------------------------------------------------------------
-
-#ifdef _WIN32
-
-BOOL APIENTRY DllMain( HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
-{
-    switch (ul_reason_for_call)
-	{
-		case DLL_PROCESS_ATTACH:
-		case DLL_THREAD_ATTACH:
-		case DLL_THREAD_DETACH:
-		case DLL_PROCESS_DETACH:
-			break;
-    }
-    return TRUE;
-}
-
-
-#endif // _WIN32
+// ==========================================================
+// FreeImagePlus.cpp : Defines the entry point for the DLL application.
+//
+// Design and implementation by
+// - Herv� Drolon (drolon at infonie.fr)
+//
+// This file is part of FreeImage 3
+//
+// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
+// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
+// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
+// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
+// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
+// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
+// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+// THIS DISCLAIMER.
+//
+// Use at your own risk!
+// ==========================================================
+
+#ifdef _WIN32
+#include <windows.h>
+#endif // _WIN32
+
+#include "FreeImagePlus.h"
+
+//----------------------------------------------------------------------
+
+#ifdef _WIN32
+
+BOOL APIENTRY DllMain( HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
+{
+    switch (ul_reason_for_call)
+	{
+		case DLL_PROCESS_ATTACH:
+		case DLL_THREAD_ATTACH:
+		case DLL_THREAD_DETACH:
+		case DLL_PROCESS_DETACH:
+			break;
+    }
+    return TRUE;
+}
+
+
+#endif // _WIN32
diff --git a/Wrapper/FreeImagePlus/src/fipImage.cpp b/Wrapper/FreeImagePlus/src/fipImage.cpp
index a5b41bd..0ce5688 100644
--- a/Wrapper/FreeImagePlus/src/fipImage.cpp
+++ b/Wrapper/FreeImagePlus/src/fipImage.cpp
@@ -1,954 +1,974 @@
-// ==========================================================
-// fipImage class implementation
-//
-// Design and implementation by
-// - Herv� Drolon (drolon at infonie.fr)
-//
-// This file is part of FreeImage 3
-//
-// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
-// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
-// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
-// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
-// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
-// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
-// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
-// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
-// THIS DISCLAIMER.
-//
-// Use at your own risk!
-// ==========================================================
-
-#include "FreeImagePlus.h"
-
-///////////////////////////////////////////////////////////////////   
-// Protected functions
-
-BOOL fipImage::replace(FIBITMAP *new_dib) {
-	if(new_dib == NULL) 
-		return FALSE;
-	if(_dib)
-		FreeImage_Unload(_dib);
-	_dib = new_dib;
-	_bHasChanged = TRUE;
-	return TRUE;
-}
-
-///////////////////////////////////////////////////////////////////
-// Creation & Destruction
-
-fipImage::fipImage(FREE_IMAGE_TYPE image_type, unsigned width, unsigned height, unsigned bpp) {
-	_dib = NULL;
-	_bHasChanged = FALSE;
-	if(width && height && bpp)
-		setSize(image_type, width, height, bpp);
-}
-
-fipImage::~fipImage() {
-	if(_dib) {
-		FreeImage_Unload(_dib);
-		_dib = NULL;
-	}
-}
-
-BOOL fipImage::setSize(FREE_IMAGE_TYPE image_type, unsigned width, unsigned height, unsigned bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask) {
-	if(_dib) {
-		FreeImage_Unload(_dib);
-	}
-	if((_dib = FreeImage_AllocateT(image_type, width, height, bpp, red_mask, green_mask, blue_mask)) == NULL)
-		return FALSE;
-
-	if(image_type == FIT_BITMAP) {
-		// Create palette if needed
-		switch(bpp)	{
-			case 1:
-			case 4:
-			case 8:
-				RGBQUAD *pal = FreeImage_GetPalette(_dib);
-				for(unsigned i = 0; i < FreeImage_GetColorsUsed(_dib); i++) {
-					pal[i].rgbRed = i;
-					pal[i].rgbGreen = i;
-					pal[i].rgbBlue = i;
-				}
-				break;
-		}
-	}
-
-	_bHasChanged = TRUE;
-
-	return TRUE;
-}
-
-void fipImage::clear() {
-	if(_dib) {
-		FreeImage_Unload(_dib);
-		_dib = NULL;
-	}
-	_bHasChanged = TRUE;
-}
-
-///////////////////////////////////////////////////////////////////
-// Copying
-
-fipImage::fipImage(const fipImage& Image) {
-	_dib = NULL;
-	_fif = FIF_UNKNOWN;
-	FIBITMAP *clone = FreeImage_Clone((FIBITMAP*)Image._dib);
-	replace(clone);
-}
-
-fipImage& fipImage::operator=(const fipImage& Image) {
-	if(this != &Image) {
-		FIBITMAP *clone = FreeImage_Clone((FIBITMAP*)Image._dib);
-		replace(clone);
-	}
-	return *this;
-}
-
-fipImage& fipImage::operator=(FIBITMAP *dib) {
-	if(_dib != dib) {
-		replace(dib);
-	}
-	return *this;
-}
-
-BOOL fipImage::copySubImage(fipImage& dst, int left, int top, int right, int bottom) const {
-	if(_dib) {
-		dst = FreeImage_Copy(_dib, left, top, right, bottom);
-		return dst.isValid();
-	}
-	return FALSE;
-}
-
-BOOL fipImage::pasteSubImage(fipImage& src, int left, int top, int alpha) {
-	if(_dib) {
-		BOOL bResult = FreeImage_Paste(_dib, src._dib, left, top, alpha);
-		_bHasChanged = TRUE;
-		return bResult;
-	}
-	return FALSE;
-}
-
-BOOL fipImage::crop(int left, int top, int right, int bottom) {
-	if(_dib) {
-		FIBITMAP *dst = FreeImage_Copy(_dib, left, top, right, bottom);
-		return replace(dst);
-	}
-	return FALSE;
-}
-
-
-///////////////////////////////////////////////////////////////////
-// Information functions
-
-FREE_IMAGE_TYPE fipImage::getImageType() const {
-	return FreeImage_GetImageType(_dib);
-}
-
-unsigned fipImage::getWidth() const {
-	return FreeImage_GetWidth(_dib); 
-}
-
-unsigned fipImage::getHeight() const {
-	return FreeImage_GetHeight(_dib); 
-}
-
-unsigned fipImage::getScanWidth() const {
-	return FreeImage_GetPitch(_dib);
-}
-
-BOOL fipImage::isValid() const {
-	return (_dib != NULL) ? TRUE:FALSE;
-}
-
-BITMAPINFO* fipImage::getInfo() const {
-	return FreeImage_GetInfo(_dib);
-}
-
-BITMAPINFOHEADER* fipImage::getInfoHeader() const {
-	return FreeImage_GetInfoHeader(_dib);
-}
-
-LONG fipImage::getImageSize() const {
-	return FreeImage_GetDIBSize(_dib);
-}
-
-unsigned fipImage::getBitsPerPixel() const {
-	return FreeImage_GetBPP(_dib);
-}
-
-unsigned fipImage::getLine() const {
-	return FreeImage_GetLine(_dib);
-}
-
-double fipImage::getHorizontalResolution() const {
-	return (FreeImage_GetDotsPerMeterX(_dib) / (double)100); 
-}
-
-double fipImage::getVerticalResolution() const {
-	return (FreeImage_GetDotsPerMeterY(_dib) / (double)100);
-}
-
-void fipImage::setHorizontalResolution(double value) {
-	FreeImage_SetDotsPerMeterX(_dib, (unsigned)(value * 100 + 0.5));
-}
-
-void fipImage::setVerticalResolution(double value) {
-	FreeImage_SetDotsPerMeterY(_dib, (unsigned)(value * 100 + 0.5));
-}
-
-
-///////////////////////////////////////////////////////////////////
-// Palette operations
-
-RGBQUAD* fipImage::getPalette() const {
-	return FreeImage_GetPalette(_dib);
-}
-
-unsigned fipImage::getPaletteSize() const {
-	return FreeImage_GetColorsUsed(_dib) * sizeof(RGBQUAD);
-}
-
-unsigned fipImage::getColorsUsed() const {
-	return FreeImage_GetColorsUsed(_dib);
-}
-
-FREE_IMAGE_COLOR_TYPE fipImage::getColorType() const { 
-	return FreeImage_GetColorType(_dib);
-}
-
-BOOL fipImage::isGrayscale() const {
-	return ((FreeImage_GetBPP(_dib) == 8) && (FreeImage_GetColorType(_dib) != FIC_PALETTE)); 
-}
-
-///////////////////////////////////////////////////////////////////
-// Thumbnail access
-
-BOOL fipImage::getThumbnail(fipImage& image) const {
-	image = FreeImage_Clone( FreeImage_GetThumbnail(_dib) );
-	return image.isValid();
-}
-
-BOOL fipImage::setThumbnail(const fipImage& image) {
-	return FreeImage_SetThumbnail(_dib, (FIBITMAP*)image._dib);
-}
-
-BOOL fipImage::hasThumbnail() const {
-	return (FreeImage_GetThumbnail(_dib) != NULL);
-}
-
-BOOL fipImage::clearThumbnail() {
-	return FreeImage_SetThumbnail(_dib, NULL);
-}
-
-
-///////////////////////////////////////////////////////////////////
-// Pixel access
-
-BYTE* fipImage::accessPixels() const {
-	return FreeImage_GetBits(_dib); 
-}
-
-BYTE* fipImage::getScanLine(unsigned scanline) const {
-	if(scanline < FreeImage_GetHeight(_dib)) {
-		return FreeImage_GetScanLine(_dib, scanline);
-	}
-	return NULL;
-}
-
-BOOL fipImage::getPixelIndex(unsigned x, unsigned y, BYTE *value) const {
-	return FreeImage_GetPixelIndex(_dib, x, y, value);
-}
-
-BOOL fipImage::getPixelColor(unsigned x, unsigned y, RGBQUAD *value) const {
-	return FreeImage_GetPixelColor(_dib, x, y, value);
-}
-
-BOOL fipImage::setPixelIndex(unsigned x, unsigned y, BYTE *value) {
-	_bHasChanged = TRUE;
-	return FreeImage_SetPixelIndex(_dib, x, y, value);
-}
-
-BOOL fipImage::setPixelColor(unsigned x, unsigned y, RGBQUAD *value) {
-	_bHasChanged = TRUE;
-	return FreeImage_SetPixelColor(_dib, x, y, value);
-}
-
-///////////////////////////////////////////////////////////////////
-// File type identification
-
-FREE_IMAGE_FORMAT fipImage::identifyFIF(const char* lpszPathName) {
-	FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
-
-	// check the file signature and get its format
-	// (the second argument is currently not used by FreeImage)
-	fif = FreeImage_GetFileType(lpszPathName, 0);
-	if(fif == FIF_UNKNOWN) {
-		// no signature ?
-		// try to guess the file format from the file extension
-		fif = FreeImage_GetFIFFromFilename(lpszPathName);
-	}
-
-	return fif;
-}
-
-FREE_IMAGE_FORMAT fipImage::identifyFIFU(const wchar_t* lpszPathName) {
-	FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
-
-	// check the file signature and get its format
-	// (the second argument is currently not used by FreeImage)
-	fif = FreeImage_GetFileTypeU(lpszPathName, 0);
-	if(fif == FIF_UNKNOWN) {
-		// no signature ?
-		// try to guess the file format from the file extension
-		fif = FreeImage_GetFIFFromFilenameU(lpszPathName);
-	}
-
-	return fif;
-}
-
-FREE_IMAGE_FORMAT fipImage::identifyFIFFromHandle(FreeImageIO *io, fi_handle handle) {
-	if(io && handle) {
-		// check the file signature and get its format
-		return FreeImage_GetFileTypeFromHandle(io, handle, 16);
-	}
-	return FIF_UNKNOWN;
-}
-
-FREE_IMAGE_FORMAT fipImage::identifyFIFFromMemory(FIMEMORY *hmem) {
-	if(hmem != NULL) {
-		return FreeImage_GetFileTypeFromMemory(hmem, 0);
-	}
-	return FIF_UNKNOWN;
-}
-
-
-///////////////////////////////////////////////////////////////////
-// Loading & Saving
-
-BOOL fipImage::load(const char* lpszPathName, int flag) {
-	FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
-
-	// check the file signature and get its format
-	// (the second argument is currently not used by FreeImage)
-	fif = FreeImage_GetFileType(lpszPathName, 0);
-	if(fif == FIF_UNKNOWN) {
-		// no signature ?
-		// try to guess the file format from the file extension
-		fif = FreeImage_GetFIFFromFilename(lpszPathName);
-	}
-	// check that the plugin has reading capabilities ...
-	if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) {
-		// Free the previous dib
-		if(_dib) {
-			FreeImage_Unload(_dib);			
-		}
-		// Load the file
-		_dib = FreeImage_Load(fif, lpszPathName, flag);
-		_bHasChanged = TRUE;
-		if(_dib == NULL)
-			return FALSE;
-		return TRUE;
-	}
-	return FALSE;
-}
-
-BOOL fipImage::loadU(const wchar_t* lpszPathName, int flag) {
-	FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
-
-	// check the file signature and get its format
-	// (the second argument is currently not used by FreeImage)
-	fif = FreeImage_GetFileTypeU(lpszPathName, 0);
-	if(fif == FIF_UNKNOWN) {
-		// no signature ?
-		// try to guess the file format from the file extension
-		fif = FreeImage_GetFIFFromFilenameU(lpszPathName);
-	}
-	// check that the plugin has reading capabilities ...
-	if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) {
-		// Free the previous dib
-		if(_dib) {
-			FreeImage_Unload(_dib);			
-		}
-		// Load the file
-		_dib = FreeImage_LoadU(fif, lpszPathName, flag);
-		_bHasChanged = TRUE;
-		if(_dib == NULL)
-			return FALSE;
-		return TRUE;
-	}
-	return FALSE;
-}
-
-BOOL fipImage::loadFromHandle(FreeImageIO *io, fi_handle handle, int flag) {
-	FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
-
-	// check the file signature and get its format
-	fif = FreeImage_GetFileTypeFromHandle(io, handle, 16);
-	if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) {
-		// Free the previous dib
-		if(_dib) {
-			FreeImage_Unload(_dib);			
-		}
-		// Load the file
-		_dib = FreeImage_LoadFromHandle(fif, io, handle, flag);
-		_bHasChanged = TRUE;
-		if(_dib == NULL)
-			return FALSE;
-		return TRUE;
-	}
-	return FALSE;
-}
-
-BOOL fipImage::loadFromMemory(fipMemoryIO& memIO, int flag) {
-	FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
-
-	// check the file signature and get its format
-	fif = memIO.getFileType();
-	if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) {
-		// Free the previous dib
-		if(_dib) {
-			FreeImage_Unload(_dib);			
-		}
-		// Load the file
-		_dib = memIO.load(fif, flag);
-		_bHasChanged = TRUE;
-		if(_dib == NULL)
-			return FALSE;
-		return TRUE;
-	}
-	return FALSE;
-}
-
-BOOL fipImage::save(const char* lpszPathName, int flag) const {
-	FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
-	BOOL bSuccess = FALSE;
-
-	// Try to guess the file format from the file extension
-	fif = FreeImage_GetFIFFromFilename(lpszPathName);
-	if(fif != FIF_UNKNOWN ) {
-		// Check that the dib can be saved in this format
-		BOOL bCanSave;
-
-		FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(_dib);
-		if(image_type == FIT_BITMAP) {
-			// standard bitmap type
-			WORD bpp = FreeImage_GetBPP(_dib);
-			bCanSave = (FreeImage_FIFSupportsWriting(fif) && FreeImage_FIFSupportsExportBPP(fif, bpp));
-		} else {
-			// special bitmap type
-			bCanSave = FreeImage_FIFSupportsExportType(fif, image_type);
-		}
-
-		if(bCanSave) {
-			bSuccess = FreeImage_Save(fif, _dib, lpszPathName, flag);
-			return bSuccess;
-		}
-	}
-	return bSuccess;
-}
-
-BOOL fipImage::saveU(const wchar_t* lpszPathName, int flag) const {
-	FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
-	BOOL bSuccess = FALSE;
-
-	// Try to guess the file format from the file extension
-	fif = FreeImage_GetFIFFromFilenameU(lpszPathName);
-	if(fif != FIF_UNKNOWN ) {
-		// Check that the dib can be saved in this format
-		BOOL bCanSave;
-
-		FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(_dib);
-		if(image_type == FIT_BITMAP) {
-			// standard bitmap type
-			WORD bpp = FreeImage_GetBPP(_dib);
-			bCanSave = (FreeImage_FIFSupportsWriting(fif) && FreeImage_FIFSupportsExportBPP(fif, bpp));
-		} else {
-			// special bitmap type
-			bCanSave = FreeImage_FIFSupportsExportType(fif, image_type);
-		}
-
-		if(bCanSave) {
-			bSuccess = FreeImage_SaveU(fif, _dib, lpszPathName, flag);
-			return bSuccess;
-		}
-	}
-	return bSuccess;
-}
-
-BOOL fipImage::saveToHandle(FREE_IMAGE_FORMAT fif, FreeImageIO *io, fi_handle handle, int flag) const {
-	BOOL bSuccess = FALSE;
-
-	if(fif != FIF_UNKNOWN ) {
-		// Check that the dib can be saved in this format
-		BOOL bCanSave;
-
-		FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(_dib);
-		if(image_type == FIT_BITMAP) {
-			// standard bitmap type
-			WORD bpp = FreeImage_GetBPP(_dib);
-			bCanSave = (FreeImage_FIFSupportsWriting(fif) && FreeImage_FIFSupportsExportBPP(fif, bpp));
-		} else {
-			// special bitmap type
-			bCanSave = FreeImage_FIFSupportsExportType(fif, image_type);
-		}
-
-		if(bCanSave) {
-			bSuccess = FreeImage_SaveToHandle(fif, _dib, io, handle, flag);
-			return bSuccess;
-		}
-	}
-	return bSuccess;
-}
-
-BOOL fipImage::saveToMemory(FREE_IMAGE_FORMAT fif, fipMemoryIO& memIO, int flag) const {
-	BOOL bSuccess = FALSE;
-
-	if(fif != FIF_UNKNOWN ) {
-		// Check that the dib can be saved in this format
-		BOOL bCanSave;
-
-		FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(_dib);
-		if(image_type == FIT_BITMAP) {
-			// standard bitmap type
-			WORD bpp = FreeImage_GetBPP(_dib);
-			bCanSave = (FreeImage_FIFSupportsWriting(fif) && FreeImage_FIFSupportsExportBPP(fif, bpp));
-		} else {
-			// special bitmap type
-			bCanSave = FreeImage_FIFSupportsExportType(fif, image_type);
-		}
-
-		if(bCanSave) {
-			bSuccess = memIO.save(fif, _dib, flag);
-			return bSuccess;
-		}
-	}
-	return bSuccess;
-}
-
-///////////////////////////////////////////////////////////////////   
-// Conversion routines
-
-BOOL fipImage::convertToType(FREE_IMAGE_TYPE image_type, BOOL scale_linear) {
-	if(_dib) {
-		FIBITMAP *dib = FreeImage_ConvertToType(_dib, image_type, scale_linear);
-		return replace(dib);
-	}
-	return FALSE;
-}
-
-BOOL fipImage::threshold(BYTE T) {
-	if(_dib) {
-		FIBITMAP *dib1 = FreeImage_Threshold(_dib, T);
-		return replace(dib1);
-	}
-	return FALSE;
-}
-
-BOOL fipImage::convertTo4Bits() {
-	if(_dib) {
-		FIBITMAP *dib4 = FreeImage_ConvertTo4Bits(_dib);
-		return replace(dib4);
-	}
-	return FALSE;
-}
-
-BOOL fipImage::convertTo8Bits() {
-	if(_dib) {
-		FIBITMAP *dib8 = FreeImage_ConvertTo8Bits(_dib);
-		return replace(dib8);
-	}
-	return FALSE;
-}
-
-BOOL fipImage::convertTo16Bits555() {
-	if(_dib) {
-		FIBITMAP *dib16_555 = FreeImage_ConvertTo16Bits555(_dib);
-		return replace(dib16_555);
-	}
-	return FALSE;
-}
-
-BOOL fipImage::convertTo16Bits565() {
-	if(_dib) {
-		FIBITMAP *dib16_565 = FreeImage_ConvertTo16Bits565(_dib);
-		return replace(dib16_565);
-	}
-	return FALSE;
-}
-
-BOOL fipImage::convertTo24Bits() {
-	if(_dib) {
-		FIBITMAP *dibRGB = FreeImage_ConvertTo24Bits(_dib);
-		return replace(dibRGB);
-	}
-	return FALSE;
-}
-
-BOOL fipImage::convertTo32Bits() {
-	if(_dib) {
-		FIBITMAP *dib32 = FreeImage_ConvertTo32Bits(_dib);
-		return replace(dib32);
-	}
-	return FALSE;
-}
-
-BOOL fipImage::convertToGrayscale() {
-	if(_dib) {
-		FIBITMAP *dib8 = FreeImage_ConvertToGreyscale(_dib);
-		return replace(dib8);
-	}
-	return FALSE;
-}
-
-BOOL fipImage::colorQuantize(FREE_IMAGE_QUANTIZE algorithm) {
-	if(_dib) {
-		FIBITMAP *dib8 = FreeImage_ColorQuantize(_dib, algorithm);
-		return replace(dib8);
-	}
-	return FALSE;
-}
-
-BOOL fipImage::dither(FREE_IMAGE_DITHER algorithm) {
-	if(_dib) {
-		FIBITMAP *dib = FreeImage_Dither(_dib, algorithm);
-		return replace(dib);
-	}
-	return FALSE;
-}
-
-BOOL fipImage::convertToFloat() {
-	if(_dib) {
-		FIBITMAP *dib = FreeImage_ConvertToFloat(_dib);
-		return replace(dib);
-	}
-	return FALSE;
-}
-
-BOOL fipImage::convertToRGBF() {
-	if(_dib) {
-		FIBITMAP *dib = FreeImage_ConvertToRGBF(_dib);
-		return replace(dib);
-	}
-	return FALSE;
-}
-
-BOOL fipImage::convertToUINT16() {
-	if(_dib) {
-		FIBITMAP *dib = FreeImage_ConvertToUINT16(_dib);
-		return replace(dib);
-	}
-	return FALSE;
-}
-
-BOOL fipImage::convertToRGB16() {
-	if(_dib) {
-		FIBITMAP *dib = FreeImage_ConvertToRGB16(_dib);
-		return replace(dib);
-	}
-	return FALSE;
-}
-
-BOOL fipImage::toneMapping(FREE_IMAGE_TMO tmo, double first_param, double second_param, double third_param, double fourth_param) {
-	if(_dib) {
-		FIBITMAP *dst = NULL;
-		// Apply a tone mapping algorithm and convert to 24-bit 
-		switch(tmo) {
-			case FITMO_REINHARD05:
-				dst = FreeImage_TmoReinhard05Ex(_dib, first_param, second_param, third_param, fourth_param);
-				break;
-			default:
-				dst = FreeImage_ToneMapping(_dib, tmo, first_param, second_param);
-				break;
-		}
-
-		return replace(dst);
-	}
-	return FALSE;
-}
-
-///////////////////////////////////////////////////////////////////   
-// Transparency support: background colour and alpha channel
-
-BOOL fipImage::isTransparent() const {
-	return FreeImage_IsTransparent(_dib);
-}
-
-unsigned fipImage::getTransparencyCount() const {
-	return FreeImage_GetTransparencyCount(_dib);
-}
-
-BYTE* fipImage::getTransparencyTable() const {
-	return FreeImage_GetTransparencyTable(_dib);
-}
-
-void fipImage::setTransparencyTable(BYTE *table, int count) {
-	FreeImage_SetTransparencyTable(_dib, table, count);
-	_bHasChanged = TRUE;
-}
-
-BOOL fipImage::hasFileBkColor() const {
-	return FreeImage_HasBackgroundColor(_dib);
-}
-
-BOOL fipImage::getFileBkColor(RGBQUAD *bkcolor) const {
-	return FreeImage_GetBackgroundColor(_dib, bkcolor);
-}
-
-BOOL fipImage::setFileBkColor(RGBQUAD *bkcolor) {
-	_bHasChanged = TRUE;
-	return FreeImage_SetBackgroundColor(_dib, bkcolor);
-}
-
-///////////////////////////////////////////////////////////////////   
-// Channel processing support
-
-BOOL fipImage::getChannel(fipImage& image, FREE_IMAGE_COLOR_CHANNEL channel) const {
-	if(_dib) {
-		image = FreeImage_GetChannel(_dib, channel);
-		return image.isValid();
-	}
-	return FALSE;
-}
-
-BOOL fipImage::setChannel(fipImage& image, FREE_IMAGE_COLOR_CHANNEL channel) {
-	if(_dib) {
-		_bHasChanged = TRUE;
-		return FreeImage_SetChannel(_dib, image._dib, channel);
-	}
-	return FALSE;
-}
-
-BOOL fipImage::splitChannels(fipImage& RedChannel, fipImage& GreenChannel, fipImage& BlueChannel) {
-	if(_dib) {
-		RedChannel = FreeImage_GetChannel(_dib, FICC_RED);
-		GreenChannel = FreeImage_GetChannel(_dib, FICC_GREEN);
-		BlueChannel = FreeImage_GetChannel(_dib, FICC_BLUE);
-
-		return (RedChannel.isValid() && GreenChannel.isValid() && BlueChannel.isValid());
-	}
-	return FALSE;
-}
-
-BOOL fipImage::combineChannels(fipImage& red, fipImage& green, fipImage& blue) {
-	if(!_dib) {
-		int width = red.getWidth();
-		int height = red.getHeight();
-		_dib = FreeImage_Allocate(width, height, 24, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
-	}
-
-	if(_dib) {
-		BOOL bResult = TRUE;
-		bResult &= FreeImage_SetChannel(_dib, red._dib, FICC_RED);
-		bResult &= FreeImage_SetChannel(_dib, green._dib, FICC_GREEN);
-		bResult &= FreeImage_SetChannel(_dib, blue._dib, FICC_BLUE);
-
-		_bHasChanged = TRUE;
-
-		return bResult;
-	}
-	return FALSE;
-}
-
-///////////////////////////////////////////////////////////////////   
-// Rotation and flipping
-
-BOOL fipImage::rotateEx(double angle, double x_shift, double y_shift, double x_origin, double y_origin, BOOL use_mask) {
-	if(_dib) {
-		if(FreeImage_GetBPP(_dib) >= 8) {
-			FIBITMAP *rotated = FreeImage_RotateEx(_dib, angle, x_shift, y_shift, x_origin, y_origin, use_mask);
-			return replace(rotated);
-		}
-	}
-	return FALSE;
-}
-
-BOOL fipImage::rotate(double angle, const void *bkcolor) {
-	if(_dib) {
-		switch(FreeImage_GetImageType(_dib)) {
-			case FIT_BITMAP:
-				switch(FreeImage_GetBPP(_dib)) {
-					case 1:
-					case 8:
-					case 24:
-					case 32:
-						break;
-					default:
-						return FALSE;
-				}
-				break;
-
-			case FIT_UINT16:
-			case FIT_RGB16:
-			case FIT_RGBA16:
-			case FIT_FLOAT:
-			case FIT_RGBF:
-			case FIT_RGBAF:
-				break;
-			default:
-				return FALSE;
-				break;
-		}
-
-		FIBITMAP *rotated = FreeImage_Rotate(_dib, angle, bkcolor);
-		return replace(rotated);
-
-	}
-	return FALSE;
-}
-
-BOOL fipImage::flipVertical() {
-	if(_dib) {
-		_bHasChanged = TRUE;
-
-		return FreeImage_FlipVertical(_dib);
-	}
-	return FALSE;
-}
-
-BOOL fipImage::flipHorizontal() {
-	if(_dib) {
-		_bHasChanged = TRUE;
-
-		return FreeImage_FlipHorizontal(_dib);
-	}
-	return FALSE;
-}
-
-///////////////////////////////////////////////////////////////////   
-// Color manipulation routines
-
-BOOL fipImage::invert() {
-	if(_dib) {
-		_bHasChanged = TRUE;
-
-		return FreeImage_Invert(_dib);
-	}
-	return FALSE;
-}
-
-BOOL fipImage::adjustCurve(BYTE *LUT, FREE_IMAGE_COLOR_CHANNEL channel) {
-	if(_dib) {
-		_bHasChanged = TRUE;
-
-		return FreeImage_AdjustCurve(_dib, LUT, channel);
-	}
-	return FALSE;
-}
-
-BOOL fipImage::adjustGamma(double gamma) {
-	if(_dib) {
-		_bHasChanged = TRUE;
-
-		return FreeImage_AdjustGamma(_dib, gamma);
-	}
-	return FALSE;
-}
-
-BOOL fipImage::adjustBrightness(double percentage) {
-	if(_dib) {
-		_bHasChanged = TRUE;
-
-		return FreeImage_AdjustBrightness(_dib, percentage);
-	}
-	return FALSE;
-}
-
-BOOL fipImage::adjustContrast(double percentage) {
-	if(_dib) {
-		_bHasChanged = TRUE;
-
-		return FreeImage_AdjustContrast(_dib, percentage);
-	}
-	return FALSE;
-}
-
-BOOL fipImage::adjustBrightnessContrastGamma(double brightness, double contrast, double gamma) {
-	if(_dib) {
-		_bHasChanged = TRUE;
-
-		return FreeImage_AdjustColors(_dib, brightness, contrast, gamma, FALSE);
-	}
-	return FALSE;
-}
-
-BOOL fipImage::getHistogram(DWORD *histo, FREE_IMAGE_COLOR_CHANNEL channel) const {
-	if(_dib) {
-		return FreeImage_GetHistogram(_dib, histo, channel);
-	}
-	return FALSE;
-}
-
-///////////////////////////////////////////////////////////////////
-// Upsampling / downsampling routine
-
-BOOL fipImage::rescale(unsigned new_width, unsigned new_height, FREE_IMAGE_FILTER filter) {
-	if(_dib) {
-		switch(FreeImage_GetImageType(_dib)) {
-			case FIT_BITMAP:
-			case FIT_UINT16:
-			case FIT_RGB16:
-			case FIT_RGBA16:
-			case FIT_FLOAT:
-			case FIT_RGBF:
-			case FIT_RGBAF:
-				break;
-			default:
-				return FALSE;
-				break;
-		}
-
-		// Perform upsampling / downsampling
-		FIBITMAP *dst = FreeImage_Rescale(_dib, new_width, new_height, filter);
-		return replace(dst);
-	}
-	return FALSE;
-}
-
-BOOL fipImage::makeThumbnail(unsigned max_size, BOOL convert) {
-	if(_dib) {
-		switch(FreeImage_GetImageType(_dib)) {
-			case FIT_BITMAP:
-			case FIT_UINT16:
-			case FIT_RGB16:
-			case FIT_RGBA16:
-			case FIT_FLOAT:
-			case FIT_RGBF:
-			case FIT_RGBAF:
-				break;
-			default:
-				return FALSE;
-				break;
-		}
-
-		// Perform downsampling
-		FIBITMAP *dst = FreeImage_MakeThumbnail(_dib, max_size, convert);
-		return replace(dst);
-	}
-	return FALSE;
-}
-
-///////////////////////////////////////////////////////////////////
-// Metadata
-
-unsigned fipImage::getMetadataCount(FREE_IMAGE_MDMODEL model) const {
-	return FreeImage_GetMetadataCount(model, _dib);
-}
-
-BOOL fipImage::getMetadata(FREE_IMAGE_MDMODEL model, const char *key, fipTag& tag) const {
-	FITAG *searchedTag = NULL;
-	FreeImage_GetMetadata(model, _dib, key, &searchedTag);
-	if(searchedTag != NULL) {
-		tag = FreeImage_CloneTag(searchedTag);
-		return TRUE;
-	} else {
-		// clear the tag
-		tag = (FITAG*)NULL;
-	}
-	return FALSE;
-}
-
-BOOL fipImage::setMetadata(FREE_IMAGE_MDMODEL model, const char *key, fipTag& tag) {
-	return FreeImage_SetMetadata(model, _dib, key, tag);
-}
-
+// ==========================================================
+// fipImage class implementation
+//
+// Design and implementation by
+// - Herv� Drolon (drolon at infonie.fr)
+//
+// This file is part of FreeImage 3
+//
+// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
+// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
+// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
+// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
+// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
+// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
+// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+// THIS DISCLAIMER.
+//
+// Use at your own risk!
+// ==========================================================
+
+#include "FreeImagePlus.h"
+
+///////////////////////////////////////////////////////////////////   
+// Protected functions
+
+BOOL fipImage::replace(FIBITMAP *new_dib) {
+	if(new_dib == NULL) 
+		return FALSE;
+	if(_dib)
+		FreeImage_Unload(_dib);
+	_dib = new_dib;
+	_bHasChanged = TRUE;
+	return TRUE;
+}
+
+///////////////////////////////////////////////////////////////////
+// Creation & Destruction
+
+fipImage::fipImage(FREE_IMAGE_TYPE image_type, unsigned width, unsigned height, unsigned bpp) {
+	_dib = NULL;
+	_bHasChanged = FALSE;
+	if(width && height && bpp)
+		setSize(image_type, width, height, bpp);
+}
+
+fipImage::~fipImage() {
+	if(_dib) {
+		FreeImage_Unload(_dib);
+		_dib = NULL;
+	}
+}
+
+BOOL fipImage::setSize(FREE_IMAGE_TYPE image_type, unsigned width, unsigned height, unsigned bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask) {
+	if(_dib) {
+		FreeImage_Unload(_dib);
+	}
+	if((_dib = FreeImage_AllocateT(image_type, width, height, bpp, red_mask, green_mask, blue_mask)) == NULL)
+		return FALSE;
+
+	if(image_type == FIT_BITMAP) {
+		// Create palette if needed
+		switch(bpp)	{
+			case 1:
+			case 4:
+			case 8:
+				RGBQUAD *pal = FreeImage_GetPalette(_dib);
+				for(unsigned i = 0; i < FreeImage_GetColorsUsed(_dib); i++) {
+					pal[i].rgbRed = i;
+					pal[i].rgbGreen = i;
+					pal[i].rgbBlue = i;
+				}
+				break;
+		}
+	}
+
+	_bHasChanged = TRUE;
+
+	return TRUE;
+}
+
+void fipImage::clear() {
+	if(_dib) {
+		FreeImage_Unload(_dib);
+		_dib = NULL;
+	}
+	_bHasChanged = TRUE;
+}
+
+///////////////////////////////////////////////////////////////////
+// Copying
+
+fipImage::fipImage(const fipImage& Image) {
+	_dib = NULL;
+	_fif = FIF_UNKNOWN;
+	FIBITMAP *clone = FreeImage_Clone((FIBITMAP*)Image._dib);
+	replace(clone);
+}
+
+fipImage& fipImage::operator=(const fipImage& Image) {
+	if(this != &Image) {
+		FIBITMAP *clone = FreeImage_Clone((FIBITMAP*)Image._dib);
+		replace(clone);
+	}
+	return *this;
+}
+
+fipImage& fipImage::operator=(FIBITMAP *dib) {
+	if(_dib != dib) {
+		replace(dib);
+	}
+	return *this;
+}
+
+BOOL fipImage::copySubImage(fipImage& dst, int left, int top, int right, int bottom) const {
+	if(_dib) {
+		dst = FreeImage_Copy(_dib, left, top, right, bottom);
+		return dst.isValid();
+	}
+	return FALSE;
+}
+
+BOOL fipImage::pasteSubImage(fipImage& src, int left, int top, int alpha) {
+	if(_dib) {
+		BOOL bResult = FreeImage_Paste(_dib, src._dib, left, top, alpha);
+		_bHasChanged = TRUE;
+		return bResult;
+	}
+	return FALSE;
+}
+
+BOOL fipImage::crop(int left, int top, int right, int bottom) {
+	if(_dib) {
+		FIBITMAP *dst = FreeImage_Copy(_dib, left, top, right, bottom);
+		return replace(dst);
+	}
+	return FALSE;
+}
+
+
+///////////////////////////////////////////////////////////////////
+// Information functions
+
+FREE_IMAGE_TYPE fipImage::getImageType() const {
+	return FreeImage_GetImageType(_dib);
+}
+
+unsigned fipImage::getWidth() const {
+	return FreeImage_GetWidth(_dib); 
+}
+
+unsigned fipImage::getHeight() const {
+	return FreeImage_GetHeight(_dib); 
+}
+
+unsigned fipImage::getScanWidth() const {
+	return FreeImage_GetPitch(_dib);
+}
+
+BOOL fipImage::isValid() const {
+	return (_dib != NULL) ? TRUE:FALSE;
+}
+
+BITMAPINFO* fipImage::getInfo() const {
+	return FreeImage_GetInfo(_dib);
+}
+
+BITMAPINFOHEADER* fipImage::getInfoHeader() const {
+	return FreeImage_GetInfoHeader(_dib);
+}
+
+unsigned fipImage::getImageSize() const {
+	return FreeImage_GetDIBSize(_dib);
+}
+
+unsigned fipImage::getImageMemorySize() const {
+	return FreeImage_GetMemorySize(_dib);
+}
+
+unsigned fipImage::getBitsPerPixel() const {
+	return FreeImage_GetBPP(_dib);
+}
+
+unsigned fipImage::getLine() const {
+	return FreeImage_GetLine(_dib);
+}
+
+double fipImage::getHorizontalResolution() const {
+	return (FreeImage_GetDotsPerMeterX(_dib) / (double)100); 
+}
+
+double fipImage::getVerticalResolution() const {
+	return (FreeImage_GetDotsPerMeterY(_dib) / (double)100);
+}
+
+void fipImage::setHorizontalResolution(double value) {
+	FreeImage_SetDotsPerMeterX(_dib, (unsigned)(value * 100 + 0.5));
+}
+
+void fipImage::setVerticalResolution(double value) {
+	FreeImage_SetDotsPerMeterY(_dib, (unsigned)(value * 100 + 0.5));
+}
+
+
+///////////////////////////////////////////////////////////////////
+// Palette operations
+
+RGBQUAD* fipImage::getPalette() const {
+	return FreeImage_GetPalette(_dib);
+}
+
+unsigned fipImage::getPaletteSize() const {
+	return FreeImage_GetColorsUsed(_dib) * sizeof(RGBQUAD);
+}
+
+unsigned fipImage::getColorsUsed() const {
+	return FreeImage_GetColorsUsed(_dib);
+}
+
+FREE_IMAGE_COLOR_TYPE fipImage::getColorType() const { 
+	return FreeImage_GetColorType(_dib);
+}
+
+BOOL fipImage::isGrayscale() const {
+	return ((FreeImage_GetBPP(_dib) == 8) && (FreeImage_GetColorType(_dib) != FIC_PALETTE)); 
+}
+
+///////////////////////////////////////////////////////////////////
+// Thumbnail access
+
+BOOL fipImage::getThumbnail(fipImage& image) const {
+	image = FreeImage_Clone( FreeImage_GetThumbnail(_dib) );
+	return image.isValid();
+}
+
+BOOL fipImage::setThumbnail(const fipImage& image) {
+	return FreeImage_SetThumbnail(_dib, (FIBITMAP*)image._dib);
+}
+
+BOOL fipImage::hasThumbnail() const {
+	return (FreeImage_GetThumbnail(_dib) != NULL);
+}
+
+BOOL fipImage::clearThumbnail() {
+	return FreeImage_SetThumbnail(_dib, NULL);
+}
+
+
+///////////////////////////////////////////////////////////////////
+// Pixel access
+
+BYTE* fipImage::accessPixels() const {
+	return FreeImage_GetBits(_dib); 
+}
+
+BYTE* fipImage::getScanLine(unsigned scanline) const {
+	if(scanline < FreeImage_GetHeight(_dib)) {
+		return FreeImage_GetScanLine(_dib, scanline);
+	}
+	return NULL;
+}
+
+BOOL fipImage::getPixelIndex(unsigned x, unsigned y, BYTE *value) const {
+	return FreeImage_GetPixelIndex(_dib, x, y, value);
+}
+
+BOOL fipImage::getPixelColor(unsigned x, unsigned y, RGBQUAD *value) const {
+	return FreeImage_GetPixelColor(_dib, x, y, value);
+}
+
+BOOL fipImage::setPixelIndex(unsigned x, unsigned y, BYTE *value) {
+	_bHasChanged = TRUE;
+	return FreeImage_SetPixelIndex(_dib, x, y, value);
+}
+
+BOOL fipImage::setPixelColor(unsigned x, unsigned y, RGBQUAD *value) {
+	_bHasChanged = TRUE;
+	return FreeImage_SetPixelColor(_dib, x, y, value);
+}
+
+///////////////////////////////////////////////////////////////////
+// File type identification
+
+FREE_IMAGE_FORMAT fipImage::identifyFIF(const char* lpszPathName) {
+	FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
+
+	// check the file signature and get its format
+	// (the second argument is currently not used by FreeImage)
+	fif = FreeImage_GetFileType(lpszPathName, 0);
+	if(fif == FIF_UNKNOWN) {
+		// no signature ?
+		// try to guess the file format from the file extension
+		fif = FreeImage_GetFIFFromFilename(lpszPathName);
+	}
+
+	return fif;
+}
+
+FREE_IMAGE_FORMAT fipImage::identifyFIFU(const wchar_t* lpszPathName) {
+	FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
+
+	// check the file signature and get its format
+	// (the second argument is currently not used by FreeImage)
+	fif = FreeImage_GetFileTypeU(lpszPathName, 0);
+	if(fif == FIF_UNKNOWN) {
+		// no signature ?
+		// try to guess the file format from the file extension
+		fif = FreeImage_GetFIFFromFilenameU(lpszPathName);
+	}
+
+	return fif;
+}
+
+FREE_IMAGE_FORMAT fipImage::identifyFIFFromHandle(FreeImageIO *io, fi_handle handle) {
+	if(io && handle) {
+		// check the file signature and get its format
+		return FreeImage_GetFileTypeFromHandle(io, handle, 16);
+	}
+	return FIF_UNKNOWN;
+}
+
+FREE_IMAGE_FORMAT fipImage::identifyFIFFromMemory(FIMEMORY *hmem) {
+	if(hmem != NULL) {
+		return FreeImage_GetFileTypeFromMemory(hmem, 0);
+	}
+	return FIF_UNKNOWN;
+}
+
+
+///////////////////////////////////////////////////////////////////
+// Loading & Saving
+
+BOOL fipImage::load(const char* lpszPathName, int flag) {
+	FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
+
+	// check the file signature and get its format
+	// (the second argument is currently not used by FreeImage)
+	fif = FreeImage_GetFileType(lpszPathName, 0);
+	if(fif == FIF_UNKNOWN) {
+		// no signature ?
+		// try to guess the file format from the file extension
+		fif = FreeImage_GetFIFFromFilename(lpszPathName);
+	}
+	// check that the plugin has reading capabilities ...
+	if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) {
+		// Free the previous dib
+		if(_dib) {
+			FreeImage_Unload(_dib);			
+		}
+		// Load the file
+		_dib = FreeImage_Load(fif, lpszPathName, flag);
+		_bHasChanged = TRUE;
+		if(_dib == NULL)
+			return FALSE;
+		return TRUE;
+	}
+	return FALSE;
+}
+
+BOOL fipImage::loadU(const wchar_t* lpszPathName, int flag) {
+	FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
+
+	// check the file signature and get its format
+	// (the second argument is currently not used by FreeImage)
+	fif = FreeImage_GetFileTypeU(lpszPathName, 0);
+	if(fif == FIF_UNKNOWN) {
+		// no signature ?
+		// try to guess the file format from the file extension
+		fif = FreeImage_GetFIFFromFilenameU(lpszPathName);
+	}
+	// check that the plugin has reading capabilities ...
+	if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) {
+		// Free the previous dib
+		if(_dib) {
+			FreeImage_Unload(_dib);			
+		}
+		// Load the file
+		_dib = FreeImage_LoadU(fif, lpszPathName, flag);
+		_bHasChanged = TRUE;
+		if(_dib == NULL)
+			return FALSE;
+		return TRUE;
+	}
+	return FALSE;
+}
+
+BOOL fipImage::loadFromHandle(FreeImageIO *io, fi_handle handle, int flag) {
+	FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
+
+	// check the file signature and get its format
+	fif = FreeImage_GetFileTypeFromHandle(io, handle, 16);
+	if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) {
+		// Free the previous dib
+		if(_dib) {
+			FreeImage_Unload(_dib);			
+		}
+		// Load the file
+		_dib = FreeImage_LoadFromHandle(fif, io, handle, flag);
+		_bHasChanged = TRUE;
+		if(_dib == NULL)
+			return FALSE;
+		return TRUE;
+	}
+	return FALSE;
+}
+
+BOOL fipImage::loadFromMemory(fipMemoryIO& memIO, int flag) {
+	FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
+
+	// check the file signature and get its format
+	fif = memIO.getFileType();
+	if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) {
+		// Free the previous dib
+		if(_dib) {
+			FreeImage_Unload(_dib);			
+		}
+		// Load the file
+		_dib = memIO.load(fif, flag);
+		_bHasChanged = TRUE;
+		if(_dib == NULL)
+			return FALSE;
+		return TRUE;
+	}
+	return FALSE;
+}
+
+BOOL fipImage::save(const char* lpszPathName, int flag) const {
+	FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
+	BOOL bSuccess = FALSE;
+
+	// Try to guess the file format from the file extension
+	fif = FreeImage_GetFIFFromFilename(lpszPathName);
+	if(fif != FIF_UNKNOWN ) {
+		// Check that the dib can be saved in this format
+		BOOL bCanSave;
+
+		FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(_dib);
+		if(image_type == FIT_BITMAP) {
+			// standard bitmap type
+			WORD bpp = FreeImage_GetBPP(_dib);
+			bCanSave = (FreeImage_FIFSupportsWriting(fif) && FreeImage_FIFSupportsExportBPP(fif, bpp));
+		} else {
+			// special bitmap type
+			bCanSave = FreeImage_FIFSupportsExportType(fif, image_type);
+		}
+
+		if(bCanSave) {
+			bSuccess = FreeImage_Save(fif, _dib, lpszPathName, flag);
+			return bSuccess;
+		}
+	}
+	return bSuccess;
+}
+
+BOOL fipImage::saveU(const wchar_t* lpszPathName, int flag) const {
+	FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
+	BOOL bSuccess = FALSE;
+
+	// Try to guess the file format from the file extension
+	fif = FreeImage_GetFIFFromFilenameU(lpszPathName);
+	if(fif != FIF_UNKNOWN ) {
+		// Check that the dib can be saved in this format
+		BOOL bCanSave;
+
+		FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(_dib);
+		if(image_type == FIT_BITMAP) {
+			// standard bitmap type
+			WORD bpp = FreeImage_GetBPP(_dib);
+			bCanSave = (FreeImage_FIFSupportsWriting(fif) && FreeImage_FIFSupportsExportBPP(fif, bpp));
+		} else {
+			// special bitmap type
+			bCanSave = FreeImage_FIFSupportsExportType(fif, image_type);
+		}
+
+		if(bCanSave) {
+			bSuccess = FreeImage_SaveU(fif, _dib, lpszPathName, flag);
+			return bSuccess;
+		}
+	}
+	return bSuccess;
+}
+
+BOOL fipImage::saveToHandle(FREE_IMAGE_FORMAT fif, FreeImageIO *io, fi_handle handle, int flag) const {
+	BOOL bSuccess = FALSE;
+
+	if(fif != FIF_UNKNOWN ) {
+		// Check that the dib can be saved in this format
+		BOOL bCanSave;
+
+		FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(_dib);
+		if(image_type == FIT_BITMAP) {
+			// standard bitmap type
+			WORD bpp = FreeImage_GetBPP(_dib);
+			bCanSave = (FreeImage_FIFSupportsWriting(fif) && FreeImage_FIFSupportsExportBPP(fif, bpp));
+		} else {
+			// special bitmap type
+			bCanSave = FreeImage_FIFSupportsExportType(fif, image_type);
+		}
+
+		if(bCanSave) {
+			bSuccess = FreeImage_SaveToHandle(fif, _dib, io, handle, flag);
+			return bSuccess;
+		}
+	}
+	return bSuccess;
+}
+
+BOOL fipImage::saveToMemory(FREE_IMAGE_FORMAT fif, fipMemoryIO& memIO, int flag) const {
+	BOOL bSuccess = FALSE;
+
+	if(fif != FIF_UNKNOWN ) {
+		// Check that the dib can be saved in this format
+		BOOL bCanSave;
+
+		FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(_dib);
+		if(image_type == FIT_BITMAP) {
+			// standard bitmap type
+			WORD bpp = FreeImage_GetBPP(_dib);
+			bCanSave = (FreeImage_FIFSupportsWriting(fif) && FreeImage_FIFSupportsExportBPP(fif, bpp));
+		} else {
+			// special bitmap type
+			bCanSave = FreeImage_FIFSupportsExportType(fif, image_type);
+		}
+
+		if(bCanSave) {
+			bSuccess = memIO.save(fif, _dib, flag);
+			return bSuccess;
+		}
+	}
+	return bSuccess;
+}
+
+///////////////////////////////////////////////////////////////////   
+// Conversion routines
+
+BOOL fipImage::convertToType(FREE_IMAGE_TYPE image_type, BOOL scale_linear) {
+	if(_dib) {
+		FIBITMAP *dib = FreeImage_ConvertToType(_dib, image_type, scale_linear);
+		return replace(dib);
+	}
+	return FALSE;
+}
+
+BOOL fipImage::threshold(BYTE T) {
+	if(_dib) {
+		FIBITMAP *dib1 = FreeImage_Threshold(_dib, T);
+		return replace(dib1);
+	}
+	return FALSE;
+}
+
+BOOL fipImage::convertTo4Bits() {
+	if(_dib) {
+		FIBITMAP *dib4 = FreeImage_ConvertTo4Bits(_dib);
+		return replace(dib4);
+	}
+	return FALSE;
+}
+
+BOOL fipImage::convertTo8Bits() {
+	if(_dib) {
+		FIBITMAP *dib8 = FreeImage_ConvertTo8Bits(_dib);
+		return replace(dib8);
+	}
+	return FALSE;
+}
+
+BOOL fipImage::convertTo16Bits555() {
+	if(_dib) {
+		FIBITMAP *dib16_555 = FreeImage_ConvertTo16Bits555(_dib);
+		return replace(dib16_555);
+	}
+	return FALSE;
+}
+
+BOOL fipImage::convertTo16Bits565() {
+	if(_dib) {
+		FIBITMAP *dib16_565 = FreeImage_ConvertTo16Bits565(_dib);
+		return replace(dib16_565);
+	}
+	return FALSE;
+}
+
+BOOL fipImage::convertTo24Bits() {
+	if(_dib) {
+		FIBITMAP *dibRGB = FreeImage_ConvertTo24Bits(_dib);
+		return replace(dibRGB);
+	}
+	return FALSE;
+}
+
+BOOL fipImage::convertTo32Bits() {
+	if(_dib) {
+		FIBITMAP *dib32 = FreeImage_ConvertTo32Bits(_dib);
+		return replace(dib32);
+	}
+	return FALSE;
+}
+
+BOOL fipImage::convertToGrayscale() {
+	if(_dib) {
+		FIBITMAP *dib8 = FreeImage_ConvertToGreyscale(_dib);
+		return replace(dib8);
+	}
+	return FALSE;
+}
+
+BOOL fipImage::colorQuantize(FREE_IMAGE_QUANTIZE algorithm) {
+	if(_dib) {
+		FIBITMAP *dib8 = FreeImage_ColorQuantize(_dib, algorithm);
+		return replace(dib8);
+	}
+	return FALSE;
+}
+
+BOOL fipImage::dither(FREE_IMAGE_DITHER algorithm) {
+	if(_dib) {
+		FIBITMAP *dib = FreeImage_Dither(_dib, algorithm);
+		return replace(dib);
+	}
+	return FALSE;
+}
+
+BOOL fipImage::convertToFloat() {
+	if(_dib) {
+		FIBITMAP *dib = FreeImage_ConvertToFloat(_dib);
+		return replace(dib);
+	}
+	return FALSE;
+}
+
+BOOL fipImage::convertToRGBF() {
+	if(_dib) {
+		FIBITMAP *dib = FreeImage_ConvertToRGBF(_dib);
+		return replace(dib);
+	}
+	return FALSE;
+}
+
+BOOL fipImage::convertToRGBAF() {
+	if(_dib) {
+		FIBITMAP *dib = FreeImage_ConvertToRGBAF(_dib);
+		return replace(dib);
+	}
+	return FALSE;
+}
+
+BOOL fipImage::convertToUINT16() {
+	if(_dib) {
+		FIBITMAP *dib = FreeImage_ConvertToUINT16(_dib);
+		return replace(dib);
+	}
+	return FALSE;
+}
+
+BOOL fipImage::convertToRGB16() {
+	if(_dib) {
+		FIBITMAP *dib = FreeImage_ConvertToRGB16(_dib);
+		return replace(dib);
+	}
+	return FALSE;
+}
+
+BOOL fipImage::convertToRGBA16() {
+	if(_dib) {
+		FIBITMAP *dib = FreeImage_ConvertToRGBA16(_dib);
+		return replace(dib);
+	}
+	return FALSE;
+}
+
+BOOL fipImage::toneMapping(FREE_IMAGE_TMO tmo, double first_param, double second_param, double third_param, double fourth_param) {
+	if(_dib) {
+		FIBITMAP *dst = NULL;
+		// Apply a tone mapping algorithm and convert to 24-bit 
+		switch(tmo) {
+			case FITMO_REINHARD05:
+				dst = FreeImage_TmoReinhard05Ex(_dib, first_param, second_param, third_param, fourth_param);
+				break;
+			default:
+				dst = FreeImage_ToneMapping(_dib, tmo, first_param, second_param);
+				break;
+		}
+
+		return replace(dst);
+	}
+	return FALSE;
+}
+
+///////////////////////////////////////////////////////////////////   
+// Transparency support: background colour and alpha channel
+
+BOOL fipImage::isTransparent() const {
+	return FreeImage_IsTransparent(_dib);
+}
+
+unsigned fipImage::getTransparencyCount() const {
+	return FreeImage_GetTransparencyCount(_dib);
+}
+
+BYTE* fipImage::getTransparencyTable() const {
+	return FreeImage_GetTransparencyTable(_dib);
+}
+
+void fipImage::setTransparencyTable(BYTE *table, int count) {
+	FreeImage_SetTransparencyTable(_dib, table, count);
+	_bHasChanged = TRUE;
+}
+
+BOOL fipImage::hasFileBkColor() const {
+	return FreeImage_HasBackgroundColor(_dib);
+}
+
+BOOL fipImage::getFileBkColor(RGBQUAD *bkcolor) const {
+	return FreeImage_GetBackgroundColor(_dib, bkcolor);
+}
+
+BOOL fipImage::setFileBkColor(RGBQUAD *bkcolor) {
+	_bHasChanged = TRUE;
+	return FreeImage_SetBackgroundColor(_dib, bkcolor);
+}
+
+///////////////////////////////////////////////////////////////////   
+// Channel processing support
+
+BOOL fipImage::getChannel(fipImage& image, FREE_IMAGE_COLOR_CHANNEL channel) const {
+	if(_dib) {
+		image = FreeImage_GetChannel(_dib, channel);
+		return image.isValid();
+	}
+	return FALSE;
+}
+
+BOOL fipImage::setChannel(fipImage& image, FREE_IMAGE_COLOR_CHANNEL channel) {
+	if(_dib) {
+		_bHasChanged = TRUE;
+		return FreeImage_SetChannel(_dib, image._dib, channel);
+	}
+	return FALSE;
+}
+
+BOOL fipImage::splitChannels(fipImage& RedChannel, fipImage& GreenChannel, fipImage& BlueChannel) {
+	if(_dib) {
+		RedChannel = FreeImage_GetChannel(_dib, FICC_RED);
+		GreenChannel = FreeImage_GetChannel(_dib, FICC_GREEN);
+		BlueChannel = FreeImage_GetChannel(_dib, FICC_BLUE);
+
+		return (RedChannel.isValid() && GreenChannel.isValid() && BlueChannel.isValid());
+	}
+	return FALSE;
+}
+
+BOOL fipImage::combineChannels(fipImage& red, fipImage& green, fipImage& blue) {
+	if(!_dib) {
+		int width = red.getWidth();
+		int height = red.getHeight();
+		_dib = FreeImage_Allocate(width, height, 24, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
+	}
+
+	if(_dib) {
+		BOOL bResult = TRUE;
+		bResult &= FreeImage_SetChannel(_dib, red._dib, FICC_RED);
+		bResult &= FreeImage_SetChannel(_dib, green._dib, FICC_GREEN);
+		bResult &= FreeImage_SetChannel(_dib, blue._dib, FICC_BLUE);
+
+		_bHasChanged = TRUE;
+
+		return bResult;
+	}
+	return FALSE;
+}
+
+///////////////////////////////////////////////////////////////////   
+// Rotation and flipping
+
+BOOL fipImage::rotateEx(double angle, double x_shift, double y_shift, double x_origin, double y_origin, BOOL use_mask) {
+	if(_dib) {
+		if(FreeImage_GetBPP(_dib) >= 8) {
+			FIBITMAP *rotated = FreeImage_RotateEx(_dib, angle, x_shift, y_shift, x_origin, y_origin, use_mask);
+			return replace(rotated);
+		}
+	}
+	return FALSE;
+}
+
+BOOL fipImage::rotate(double angle, const void *bkcolor) {
+	if(_dib) {
+		switch(FreeImage_GetImageType(_dib)) {
+			case FIT_BITMAP:
+				switch(FreeImage_GetBPP(_dib)) {
+					case 1:
+					case 8:
+					case 24:
+					case 32:
+						break;
+					default:
+						return FALSE;
+				}
+				break;
+
+			case FIT_UINT16:
+			case FIT_RGB16:
+			case FIT_RGBA16:
+			case FIT_FLOAT:
+			case FIT_RGBF:
+			case FIT_RGBAF:
+				break;
+			default:
+				return FALSE;
+				break;
+		}
+
+		FIBITMAP *rotated = FreeImage_Rotate(_dib, angle, bkcolor);
+		return replace(rotated);
+
+	}
+	return FALSE;
+}
+
+BOOL fipImage::flipVertical() {
+	if(_dib) {
+		_bHasChanged = TRUE;
+
+		return FreeImage_FlipVertical(_dib);
+	}
+	return FALSE;
+}
+
+BOOL fipImage::flipHorizontal() {
+	if(_dib) {
+		_bHasChanged = TRUE;
+
+		return FreeImage_FlipHorizontal(_dib);
+	}
+	return FALSE;
+}
+
+///////////////////////////////////////////////////////////////////   
+// Color manipulation routines
+
+BOOL fipImage::invert() {
+	if(_dib) {
+		_bHasChanged = TRUE;
+
+		return FreeImage_Invert(_dib);
+	}
+	return FALSE;
+}
+
+BOOL fipImage::adjustCurve(BYTE *LUT, FREE_IMAGE_COLOR_CHANNEL channel) {
+	if(_dib) {
+		_bHasChanged = TRUE;
+
+		return FreeImage_AdjustCurve(_dib, LUT, channel);
+	}
+	return FALSE;
+}
+
+BOOL fipImage::adjustGamma(double gamma) {
+	if(_dib) {
+		_bHasChanged = TRUE;
+
+		return FreeImage_AdjustGamma(_dib, gamma);
+	}
+	return FALSE;
+}
+
+BOOL fipImage::adjustBrightness(double percentage) {
+	if(_dib) {
+		_bHasChanged = TRUE;
+
+		return FreeImage_AdjustBrightness(_dib, percentage);
+	}
+	return FALSE;
+}
+
+BOOL fipImage::adjustContrast(double percentage) {
+	if(_dib) {
+		_bHasChanged = TRUE;
+
+		return FreeImage_AdjustContrast(_dib, percentage);
+	}
+	return FALSE;
+}
+
+BOOL fipImage::adjustBrightnessContrastGamma(double brightness, double contrast, double gamma) {
+	if(_dib) {
+		_bHasChanged = TRUE;
+
+		return FreeImage_AdjustColors(_dib, brightness, contrast, gamma, FALSE);
+	}
+	return FALSE;
+}
+
+BOOL fipImage::getHistogram(DWORD *histo, FREE_IMAGE_COLOR_CHANNEL channel) const {
+	if(_dib) {
+		return FreeImage_GetHistogram(_dib, histo, channel);
+	}
+	return FALSE;
+}
+
+///////////////////////////////////////////////////////////////////
+// Upsampling / downsampling routine
+
+BOOL fipImage::rescale(unsigned new_width, unsigned new_height, FREE_IMAGE_FILTER filter) {
+	if(_dib) {
+		switch(FreeImage_GetImageType(_dib)) {
+			case FIT_BITMAP:
+			case FIT_UINT16:
+			case FIT_RGB16:
+			case FIT_RGBA16:
+			case FIT_FLOAT:
+			case FIT_RGBF:
+			case FIT_RGBAF:
+				break;
+			default:
+				return FALSE;
+				break;
+		}
+
+		// Perform upsampling / downsampling
+		FIBITMAP *dst = FreeImage_Rescale(_dib, new_width, new_height, filter);
+		return replace(dst);
+	}
+	return FALSE;
+}
+
+BOOL fipImage::makeThumbnail(unsigned max_size, BOOL convert) {
+	if(_dib) {
+		switch(FreeImage_GetImageType(_dib)) {
+			case FIT_BITMAP:
+			case FIT_UINT16:
+			case FIT_RGB16:
+			case FIT_RGBA16:
+			case FIT_FLOAT:
+			case FIT_RGBF:
+			case FIT_RGBAF:
+				break;
+			default:
+				return FALSE;
+				break;
+		}
+
+		// Perform downsampling
+		FIBITMAP *dst = FreeImage_MakeThumbnail(_dib, max_size, convert);
+		return replace(dst);
+	}
+	return FALSE;
+}
+
+///////////////////////////////////////////////////////////////////
+// Metadata
+
+unsigned fipImage::getMetadataCount(FREE_IMAGE_MDMODEL model) const {
+	return FreeImage_GetMetadataCount(model, _dib);
+}
+
+BOOL fipImage::getMetadata(FREE_IMAGE_MDMODEL model, const char *key, fipTag& tag) const {
+	FITAG *searchedTag = NULL;
+	FreeImage_GetMetadata(model, _dib, key, &searchedTag);
+	if(searchedTag != NULL) {
+		tag = FreeImage_CloneTag(searchedTag);
+		return TRUE;
+	} else {
+		// clear the tag
+		tag = (FITAG*)NULL;
+	}
+	return FALSE;
+}
+
+BOOL fipImage::setMetadata(FREE_IMAGE_MDMODEL model, const char *key, fipTag& tag) {
+	return FreeImage_SetMetadata(model, _dib, key, tag);
+}
+
diff --git a/Wrapper/FreeImagePlus/src/fipMemoryIO.cpp b/Wrapper/FreeImagePlus/src/fipMemoryIO.cpp
index 2180eb8..4a8fe80 100644
--- a/Wrapper/FreeImagePlus/src/fipMemoryIO.cpp
+++ b/Wrapper/FreeImagePlus/src/fipMemoryIO.cpp
@@ -1,95 +1,95 @@
-// ==========================================================
-// fipMemoryIO class implementation
-//
-// Design and implementation by
-// - Herv� Drolon (drolon at infonie.fr)
-//
-// This file is part of FreeImage 3
-//
-// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
-// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
-// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
-// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
-// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
-// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
-// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
-// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
-// THIS DISCLAIMER.
-//
-// Use at your own risk!
-// ==========================================================
-
-#include "FreeImagePlus.h"
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <stdio.h>
-
-fipMemoryIO::fipMemoryIO(BYTE *data, DWORD size_in_bytes) {
-	_hmem = FreeImage_OpenMemory(data, size_in_bytes);
-}
-
-fipMemoryIO::~fipMemoryIO() { 
-	if(_hmem != NULL) {
-		FreeImage_CloseMemory(_hmem);
-	}
-}
-
-void fipMemoryIO::close() { 
-	if(_hmem != NULL) {
-		FreeImage_CloseMemory(_hmem);
-		_hmem = NULL;
-	}
-}
-
-BOOL fipMemoryIO::isValid() const {
-	return (_hmem != NULL);
-}
-
-FREE_IMAGE_FORMAT fipMemoryIO::getFileType() const {
-	if(_hmem != NULL) {
-		return FreeImage_GetFileTypeFromMemory(_hmem, 0);
-	}
-
-	return FIF_UNKNOWN;
-}
-
-FIBITMAP* fipMemoryIO::load(FREE_IMAGE_FORMAT fif, int flags) const {
-	return FreeImage_LoadFromMemory(fif, _hmem, flags);
-}
-
-FIMULTIBITMAP* fipMemoryIO::loadMultiPage(FREE_IMAGE_FORMAT fif, int flags) const {
-	return FreeImage_LoadMultiBitmapFromMemory(fif, _hmem, flags);
-}
-
-BOOL fipMemoryIO::save(FREE_IMAGE_FORMAT fif, FIBITMAP *dib, int flags) {
-	return FreeImage_SaveToMemory(fif, dib, _hmem, flags);
-}
-
-BOOL fipMemoryIO::saveMultiPage(FREE_IMAGE_FORMAT fif, FIMULTIBITMAP *bitmap, int flags) {
-	return FreeImage_SaveMultiBitmapToMemory(fif, bitmap, _hmem, flags);
-}
-
-unsigned fipMemoryIO::read(void *buffer, unsigned size, unsigned count) const {
-	return FreeImage_ReadMemory(buffer, size, count, _hmem);
-}
-
-unsigned fipMemoryIO::write(const void *buffer, unsigned size, unsigned count) {
-	return FreeImage_WriteMemory(buffer, size, count, _hmem);
-}
-
-long fipMemoryIO::tell() const {
-	return FreeImage_TellMemory(_hmem);
-}
-
-BOOL fipMemoryIO::seek(long offset, int origin) {
-	return FreeImage_SeekMemory(_hmem, offset, origin);
-}
-
-BOOL fipMemoryIO::acquire(BYTE **data, DWORD *size_in_bytes) {
-	return FreeImage_AcquireMemory(_hmem, data, size_in_bytes);
-}
-
-
+// ==========================================================
+// fipMemoryIO class implementation
+//
+// Design and implementation by
+// - Herv� Drolon (drolon at infonie.fr)
+//
+// This file is part of FreeImage 3
+//
+// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
+// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
+// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
+// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
+// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
+// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
+// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+// THIS DISCLAIMER.
+//
+// Use at your own risk!
+// ==========================================================
+
+#include "FreeImagePlus.h"
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+
+fipMemoryIO::fipMemoryIO(BYTE *data, DWORD size_in_bytes) {
+	_hmem = FreeImage_OpenMemory(data, size_in_bytes);
+}
+
+fipMemoryIO::~fipMemoryIO() { 
+	if(_hmem != NULL) {
+		FreeImage_CloseMemory(_hmem);
+	}
+}
+
+void fipMemoryIO::close() { 
+	if(_hmem != NULL) {
+		FreeImage_CloseMemory(_hmem);
+		_hmem = NULL;
+	}
+}
+
+BOOL fipMemoryIO::isValid() const {
+	return (_hmem != NULL);
+}
+
+FREE_IMAGE_FORMAT fipMemoryIO::getFileType() const {
+	if(_hmem != NULL) {
+		return FreeImage_GetFileTypeFromMemory(_hmem, 0);
+	}
+
+	return FIF_UNKNOWN;
+}
+
+FIBITMAP* fipMemoryIO::load(FREE_IMAGE_FORMAT fif, int flags) const {
+	return FreeImage_LoadFromMemory(fif, _hmem, flags);
+}
+
+FIMULTIBITMAP* fipMemoryIO::loadMultiPage(FREE_IMAGE_FORMAT fif, int flags) const {
+	return FreeImage_LoadMultiBitmapFromMemory(fif, _hmem, flags);
+}
+
+BOOL fipMemoryIO::save(FREE_IMAGE_FORMAT fif, FIBITMAP *dib, int flags) {
+	return FreeImage_SaveToMemory(fif, dib, _hmem, flags);
+}
+
+BOOL fipMemoryIO::saveMultiPage(FREE_IMAGE_FORMAT fif, FIMULTIBITMAP *bitmap, int flags) {
+	return FreeImage_SaveMultiBitmapToMemory(fif, bitmap, _hmem, flags);
+}
+
+unsigned fipMemoryIO::read(void *buffer, unsigned size, unsigned count) const {
+	return FreeImage_ReadMemory(buffer, size, count, _hmem);
+}
+
+unsigned fipMemoryIO::write(const void *buffer, unsigned size, unsigned count) {
+	return FreeImage_WriteMemory(buffer, size, count, _hmem);
+}
+
+long fipMemoryIO::tell() const {
+	return FreeImage_TellMemory(_hmem);
+}
+
+BOOL fipMemoryIO::seek(long offset, int origin) {
+	return FreeImage_SeekMemory(_hmem, offset, origin);
+}
+
+BOOL fipMemoryIO::acquire(BYTE **data, DWORD *size_in_bytes) {
+	return FreeImage_AcquireMemory(_hmem, data, size_in_bytes);
+}
+
+
diff --git a/Wrapper/FreeImagePlus/src/fipMetadataFind.cpp b/Wrapper/FreeImagePlus/src/fipMetadataFind.cpp
index 38f8764..57d01f6 100644
--- a/Wrapper/FreeImagePlus/src/fipMetadataFind.cpp
+++ b/Wrapper/FreeImagePlus/src/fipMetadataFind.cpp
@@ -1,54 +1,54 @@
-// ==========================================================
-// fipMetadataFind class implementation
-//
-// Design and implementation by
-// - Herv� Drolon (drolon at infonie.fr)
-//
-// This file is part of FreeImage 3
-//
-// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
-// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
-// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
-// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
-// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
-// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
-// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
-// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
-// THIS DISCLAIMER.
-//
-// Use at your own risk!
-// ==========================================================
-
-#include "FreeImagePlus.h"
-
-BOOL fipMetadataFind::isValid() const {
-	return (_mdhandle != NULL) ? TRUE : FALSE;
-}
-
-fipMetadataFind::fipMetadataFind() : _mdhandle(NULL) {
-}
-
-fipMetadataFind::~fipMetadataFind() {
-	FreeImage_FindCloseMetadata(_mdhandle);
-}
-
-BOOL fipMetadataFind::findFirstMetadata(FREE_IMAGE_MDMODEL model, fipImage& image, fipTag& tag) {
-	FITAG *firstTag = NULL;
-	if(_mdhandle) FreeImage_FindCloseMetadata(_mdhandle);
-	_mdhandle = FreeImage_FindFirstMetadata(model, image, &firstTag);
-	if(_mdhandle) {
-		tag = FreeImage_CloneTag(firstTag);
-		return TRUE;
-	}
-	return FALSE;
-} 
-
-BOOL fipMetadataFind::findNextMetadata(fipTag& tag) {
-	FITAG *nextTag = NULL;
-	if( FreeImage_FindNextMetadata(_mdhandle, &nextTag) ) {
-		tag = FreeImage_CloneTag(nextTag);
-		return TRUE;
-	}
-	return FALSE;
-}
-
+// ==========================================================
+// fipMetadataFind class implementation
+//
+// Design and implementation by
+// - Herv� Drolon (drolon at infonie.fr)
+//
+// This file is part of FreeImage 3
+//
+// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
+// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
+// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
+// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
+// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
+// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
+// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+// THIS DISCLAIMER.
+//
+// Use at your own risk!
+// ==========================================================
+
+#include "FreeImagePlus.h"
+
+BOOL fipMetadataFind::isValid() const {
+	return (_mdhandle != NULL) ? TRUE : FALSE;
+}
+
+fipMetadataFind::fipMetadataFind() : _mdhandle(NULL) {
+}
+
+fipMetadataFind::~fipMetadataFind() {
+	FreeImage_FindCloseMetadata(_mdhandle);
+}
+
+BOOL fipMetadataFind::findFirstMetadata(FREE_IMAGE_MDMODEL model, fipImage& image, fipTag& tag) {
+	FITAG *firstTag = NULL;
+	if(_mdhandle) FreeImage_FindCloseMetadata(_mdhandle);
+	_mdhandle = FreeImage_FindFirstMetadata(model, image, &firstTag);
+	if(_mdhandle) {
+		tag = FreeImage_CloneTag(firstTag);
+		return TRUE;
+	}
+	return FALSE;
+} 
+
+BOOL fipMetadataFind::findNextMetadata(fipTag& tag) {
+	FITAG *nextTag = NULL;
+	if( FreeImage_FindNextMetadata(_mdhandle, &nextTag) ) {
+		tag = FreeImage_CloneTag(nextTag);
+		return TRUE;
+	}
+	return FALSE;
+}
+
diff --git a/Wrapper/FreeImagePlus/src/fipMultiPage.cpp b/Wrapper/FreeImagePlus/src/fipMultiPage.cpp
index 9ce9809..cc33196 100644
--- a/Wrapper/FreeImagePlus/src/fipMultiPage.cpp
+++ b/Wrapper/FreeImagePlus/src/fipMultiPage.cpp
@@ -1,140 +1,140 @@
-// ==========================================================
-// fipMultiPage class implementation
-//
-// Design and implementation by
-// - Herv� Drolon (drolon at infonie.fr)
-//
-// This file is part of FreeImage 3
-//
-// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
-// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
-// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
-// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
-// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
-// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
-// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
-// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
-// THIS DISCLAIMER.
-//
-// Use at your own risk!
-// ==========================================================
-
-#include "FreeImagePlus.h"
-
-fipMultiPage::fipMultiPage(BOOL keep_cache_in_memory) : _mpage(NULL), _bMemoryCache(keep_cache_in_memory) {
-}
-
-fipMultiPage::~fipMultiPage() {
-	if(_mpage) {
-		// close the stream
-		close(0);
-	}
-}
-
-BOOL fipMultiPage::isValid() const {
-	return (NULL != _mpage) ? TRUE : FALSE;
-}
-
-BOOL fipMultiPage::open(const char* lpszPathName, BOOL create_new, BOOL read_only, int flags) {
-	// try to guess the file format from the filename
-	FREE_IMAGE_FORMAT fif = FreeImage_GetFIFFromFilename(lpszPathName);
-
-	// open the stream
-	_mpage = FreeImage_OpenMultiBitmap(fif, lpszPathName, create_new, read_only, _bMemoryCache, flags);
-
-	return (NULL != _mpage ) ? TRUE : FALSE;
-}
-
-BOOL fipMultiPage::open(fipMemoryIO& memIO, int flags) {
-	// try to guess the file format from the memory handle
-	FREE_IMAGE_FORMAT fif = memIO.getFileType();
-
-	// open the stream
-	_mpage = memIO.loadMultiPage(fif, flags);
-
-	return (NULL != _mpage ) ? TRUE : FALSE;
-}
-
-BOOL fipMultiPage::open(FreeImageIO *io, fi_handle handle, int flags) {
-	// try to guess the file format from the handle
-	FREE_IMAGE_FORMAT fif = FreeImage_GetFileTypeFromHandle(io, handle, 0);
-
-	// open the stream
-	_mpage = FreeImage_OpenMultiBitmapFromHandle(fif, io, handle, flags);
-
-	return (NULL != _mpage ) ? TRUE : FALSE;
-}
-
-BOOL fipMultiPage::close(int flags) {
-	BOOL bSuccess = FALSE;
-	if(_mpage) {
-		// close the stream
-		bSuccess = FreeImage_CloseMultiBitmap(_mpage, flags);
-		_mpage = NULL;
-	}
-
-	return bSuccess;
-}
-
-BOOL fipMultiPage::saveToHandle(FREE_IMAGE_FORMAT fif, FreeImageIO *io, fi_handle handle, int flags) const {
-	BOOL bSuccess = FALSE;
-	if(_mpage) {
-		bSuccess = FreeImage_SaveMultiBitmapToHandle(fif, _mpage, io, handle, flags);
-	}
-
-	return bSuccess;
-}
-
-BOOL fipMultiPage::saveToMemory(FREE_IMAGE_FORMAT fif, fipMemoryIO& memIO, int flags) const {
-	BOOL bSuccess = FALSE;
-	if(_mpage) {
-		bSuccess = memIO.saveMultiPage(fif, _mpage, flags);
-	}
-
-	return bSuccess;
-}
-
-int fipMultiPage::getPageCount() const {
-	return _mpage ? FreeImage_GetPageCount(_mpage) : 0;
-}
-
-void fipMultiPage::appendPage(fipImage& image) {
-	if(_mpage) {
-		FreeImage_AppendPage(_mpage, image);
-	}
-}
-
-void fipMultiPage::insertPage(int page, fipImage& image) {
-	if(_mpage) {
-		FreeImage_InsertPage(_mpage, page, image);
-	}
-}
-
-void fipMultiPage::deletePage(int page) {
-	if(_mpage) {
-		FreeImage_DeletePage(_mpage, page);
-	}
-}
-
-BOOL fipMultiPage::movePage(int target, int source) {
-	return _mpage ? FreeImage_MovePage(_mpage, target, source) : FALSE;
-}
-
-FIBITMAP* fipMultiPage::lockPage(int page) {
-	return _mpage ? FreeImage_LockPage(_mpage, page) : NULL;
-}
-
-void fipMultiPage::unlockPage(fipImage& image, BOOL changed) {
-	if(_mpage) {
-		FreeImage_UnlockPage(_mpage, image, changed);
-		// clear the image so that it becomes invalid.
-		// this is possible because of the friend declaration
-		image._dib = NULL;
-		image._bHasChanged = FALSE;
-	}
-}
-
-BOOL fipMultiPage::getLockedPageNumbers(int *pages, int *count) const {
-	return _mpage ? FreeImage_GetLockedPageNumbers(_mpage, pages, count) : FALSE;
-}
-
+// ==========================================================
+// fipMultiPage class implementation
+//
+// Design and implementation by
+// - Herv� Drolon (drolon at infonie.fr)
+//
+// This file is part of FreeImage 3
+//
+// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
+// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
+// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
+// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
+// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
+// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
+// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+// THIS DISCLAIMER.
+//
+// Use at your own risk!
+// ==========================================================
+
+#include "FreeImagePlus.h"
+
+fipMultiPage::fipMultiPage(BOOL keep_cache_in_memory) : _mpage(NULL), _bMemoryCache(keep_cache_in_memory) {
+}
+
+fipMultiPage::~fipMultiPage() {
+	if(_mpage) {
+		// close the stream
+		close(0);
+	}
+}
+
+BOOL fipMultiPage::isValid() const {
+	return (NULL != _mpage) ? TRUE : FALSE;
+}
+
+BOOL fipMultiPage::open(const char* lpszPathName, BOOL create_new, BOOL read_only, int flags) {
+	// try to guess the file format from the filename
+	FREE_IMAGE_FORMAT fif = FreeImage_GetFIFFromFilename(lpszPathName);
+
+	// open the stream
+	_mpage = FreeImage_OpenMultiBitmap(fif, lpszPathName, create_new, read_only, _bMemoryCache, flags);
+
+	return (NULL != _mpage ) ? TRUE : FALSE;
+}
+
+BOOL fipMultiPage::open(fipMemoryIO& memIO, int flags) {
+	// try to guess the file format from the memory handle
+	FREE_IMAGE_FORMAT fif = memIO.getFileType();
+
+	// open the stream
+	_mpage = memIO.loadMultiPage(fif, flags);
+
+	return (NULL != _mpage ) ? TRUE : FALSE;
+}
+
+BOOL fipMultiPage::open(FreeImageIO *io, fi_handle handle, int flags) {
+	// try to guess the file format from the handle
+	FREE_IMAGE_FORMAT fif = FreeImage_GetFileTypeFromHandle(io, handle, 0);
+
+	// open the stream
+	_mpage = FreeImage_OpenMultiBitmapFromHandle(fif, io, handle, flags);
+
+	return (NULL != _mpage ) ? TRUE : FALSE;
+}
+
+BOOL fipMultiPage::close(int flags) {
+	BOOL bSuccess = FALSE;
+	if(_mpage) {
+		// close the stream
+		bSuccess = FreeImage_CloseMultiBitmap(_mpage, flags);
+		_mpage = NULL;
+	}
+
+	return bSuccess;
+}
+
+BOOL fipMultiPage::saveToHandle(FREE_IMAGE_FORMAT fif, FreeImageIO *io, fi_handle handle, int flags) const {
+	BOOL bSuccess = FALSE;
+	if(_mpage) {
+		bSuccess = FreeImage_SaveMultiBitmapToHandle(fif, _mpage, io, handle, flags);
+	}
+
+	return bSuccess;
+}
+
+BOOL fipMultiPage::saveToMemory(FREE_IMAGE_FORMAT fif, fipMemoryIO& memIO, int flags) const {
+	BOOL bSuccess = FALSE;
+	if(_mpage) {
+		bSuccess = memIO.saveMultiPage(fif, _mpage, flags);
+	}
+
+	return bSuccess;
+}
+
+int fipMultiPage::getPageCount() const {
+	return _mpage ? FreeImage_GetPageCount(_mpage) : 0;
+}
+
+void fipMultiPage::appendPage(fipImage& image) {
+	if(_mpage) {
+		FreeImage_AppendPage(_mpage, image);
+	}
+}
+
+void fipMultiPage::insertPage(int page, fipImage& image) {
+	if(_mpage) {
+		FreeImage_InsertPage(_mpage, page, image);
+	}
+}
+
+void fipMultiPage::deletePage(int page) {
+	if(_mpage) {
+		FreeImage_DeletePage(_mpage, page);
+	}
+}
+
+BOOL fipMultiPage::movePage(int target, int source) {
+	return _mpage ? FreeImage_MovePage(_mpage, target, source) : FALSE;
+}
+
+FIBITMAP* fipMultiPage::lockPage(int page) {
+	return _mpage ? FreeImage_LockPage(_mpage, page) : NULL;
+}
+
+void fipMultiPage::unlockPage(fipImage& image, BOOL changed) {
+	if(_mpage) {
+		FreeImage_UnlockPage(_mpage, image, changed);
+		// clear the image so that it becomes invalid.
+		// this is possible because of the friend declaration
+		image._dib = NULL;
+		image._bHasChanged = FALSE;
+	}
+}
+
+BOOL fipMultiPage::getLockedPageNumbers(int *pages, int *count) const {
+	return _mpage ? FreeImage_GetLockedPageNumbers(_mpage, pages, count) : FALSE;
+}
+
diff --git a/Wrapper/FreeImagePlus/src/fipTag.cpp b/Wrapper/FreeImagePlus/src/fipTag.cpp
index f2afe9f..b00a095 100644
--- a/Wrapper/FreeImagePlus/src/fipTag.cpp
+++ b/Wrapper/FreeImagePlus/src/fipTag.cpp
@@ -1,134 +1,134 @@
-// ==========================================================
-// fipTag class implementation
-//
-// Design and implementation by
-// - Herv� Drolon (drolon at infonie.fr)
-//
-// This file is part of FreeImage 3
-//
-// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
-// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
-// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
-// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
-// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
-// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
-// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
-// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
-// THIS DISCLAIMER.
-//
-// Use at your own risk!
-// ==========================================================
-
-#include <string.h>
-#include "FreeImagePlus.h"
-
-fipTag::fipTag() {
-	_tag = FreeImage_CreateTag();
-}
-
-fipTag::~fipTag() {
-	FreeImage_DeleteTag(_tag);
-}
-
-BOOL fipTag::setKeyValue(const char *key, const char *value) {
-	if(_tag) {
-		FreeImage_DeleteTag(_tag);
-		_tag = NULL;
-	}
-	// create a tag
-	_tag = FreeImage_CreateTag();
-	if(_tag) {
-		BOOL bSuccess = TRUE;
-		// fill the tag
-		DWORD tag_length = (DWORD)(strlen(value) + 1);
-		bSuccess &= FreeImage_SetTagKey(_tag, key);
-		bSuccess &= FreeImage_SetTagLength(_tag, tag_length);
-		bSuccess &= FreeImage_SetTagCount(_tag, tag_length);
-		bSuccess &= FreeImage_SetTagType(_tag, FIDT_ASCII);
-		bSuccess &= FreeImage_SetTagValue(_tag, value);
-		return bSuccess;
-	}
-	return FALSE;
-}
-
-fipTag::fipTag(const fipTag& tag) {
-	_tag = FreeImage_CloneTag(tag._tag);
-}
-
-fipTag& fipTag::operator=(const fipTag& tag) {
-	if(this != &tag) {
-		if(_tag) FreeImage_DeleteTag(_tag);
-		_tag = FreeImage_CloneTag(tag._tag);
-	}
-	return *this;
-}
-
-fipTag& fipTag::operator=(FITAG *tag) {
-	if(_tag) FreeImage_DeleteTag(_tag);
-	_tag = tag;
-	return *this;
-}
-
-BOOL fipTag::isValid() const {
-	return (_tag != NULL) ? TRUE : FALSE;
-}
-
-const char* fipTag::getKey() const {
-	return FreeImage_GetTagKey(_tag);
-}
-
-const char* fipTag::getDescription() const {
-	return FreeImage_GetTagDescription(_tag);
-}
-
-WORD fipTag::getID() const {
-	return FreeImage_GetTagID(_tag);
-}
-
-FREE_IMAGE_MDTYPE fipTag::getType() const {
-	return FreeImage_GetTagType(_tag);
-}
-
-DWORD fipTag::getCount() const {
-	return FreeImage_GetTagCount(_tag);
-}
-
-DWORD fipTag::getLength() const {
-	return FreeImage_GetTagLength(_tag);
-}
-
-const void* fipTag::getValue() const {
-	return FreeImage_GetTagValue(_tag);
-}
-
-BOOL fipTag::setKey(const char *key) {
-	return FreeImage_SetTagKey(_tag, key);
-}
-
-BOOL fipTag::setDescription(const char *description) {
-	return FreeImage_SetTagDescription(_tag, description);
-}
-
-BOOL fipTag::setID(WORD id) {
-	return FreeImage_SetTagID(_tag, id);
-}
-
-BOOL fipTag::setType(FREE_IMAGE_MDTYPE type) {
-	return FreeImage_SetTagType(_tag, type);
-}
-
-BOOL fipTag::setCount(DWORD count) {
-	return FreeImage_SetTagCount(_tag, count);
-}
-
-BOOL fipTag::setLength(DWORD length) {
-	return FreeImage_SetTagLength(_tag, length);
-}
-
-BOOL fipTag::setValue(const void *value) {
-	return FreeImage_SetTagValue(_tag, value);
-}
-
-const char* fipTag::toString(FREE_IMAGE_MDMODEL model, char *Make) const {
-	return FreeImage_TagToString(model, _tag, Make);
-}
+// ==========================================================
+// fipTag class implementation
+//
+// Design and implementation by
+// - Herv� Drolon (drolon at infonie.fr)
+//
+// This file is part of FreeImage 3
+//
+// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
+// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
+// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
+// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
+// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
+// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
+// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+// THIS DISCLAIMER.
+//
+// Use at your own risk!
+// ==========================================================
+
+#include <string.h>
+#include "FreeImagePlus.h"
+
+fipTag::fipTag() {
+	_tag = FreeImage_CreateTag();
+}
+
+fipTag::~fipTag() {
+	FreeImage_DeleteTag(_tag);
+}
+
+BOOL fipTag::setKeyValue(const char *key, const char *value) {
+	if(_tag) {
+		FreeImage_DeleteTag(_tag);
+		_tag = NULL;
+	}
+	// create a tag
+	_tag = FreeImage_CreateTag();
+	if(_tag) {
+		BOOL bSuccess = TRUE;
+		// fill the tag
+		DWORD tag_length = (DWORD)(strlen(value) + 1);
+		bSuccess &= FreeImage_SetTagKey(_tag, key);
+		bSuccess &= FreeImage_SetTagLength(_tag, tag_length);
+		bSuccess &= FreeImage_SetTagCount(_tag, tag_length);
+		bSuccess &= FreeImage_SetTagType(_tag, FIDT_ASCII);
+		bSuccess &= FreeImage_SetTagValue(_tag, value);
+		return bSuccess;
+	}
+	return FALSE;
+}
+
+fipTag::fipTag(const fipTag& tag) {
+	_tag = FreeImage_CloneTag(tag._tag);
+}
+
+fipTag& fipTag::operator=(const fipTag& tag) {
+	if(this != &tag) {
+		if(_tag) FreeImage_DeleteTag(_tag);
+		_tag = FreeImage_CloneTag(tag._tag);
+	}
+	return *this;
+}
+
+fipTag& fipTag::operator=(FITAG *tag) {
+	if(_tag) FreeImage_DeleteTag(_tag);
+	_tag = tag;
+	return *this;
+}
+
+BOOL fipTag::isValid() const {
+	return (_tag != NULL) ? TRUE : FALSE;
+}
+
+const char* fipTag::getKey() const {
+	return FreeImage_GetTagKey(_tag);
+}
+
+const char* fipTag::getDescription() const {
+	return FreeImage_GetTagDescription(_tag);
+}
+
+WORD fipTag::getID() const {
+	return FreeImage_GetTagID(_tag);
+}
+
+FREE_IMAGE_MDTYPE fipTag::getType() const {
+	return FreeImage_GetTagType(_tag);
+}
+
+DWORD fipTag::getCount() const {
+	return FreeImage_GetTagCount(_tag);
+}
+
+DWORD fipTag::getLength() const {
+	return FreeImage_GetTagLength(_tag);
+}
+
+const void* fipTag::getValue() const {
+	return FreeImage_GetTagValue(_tag);
+}
+
+BOOL fipTag::setKey(const char *key) {
+	return FreeImage_SetTagKey(_tag, key);
+}
+
+BOOL fipTag::setDescription(const char *description) {
+	return FreeImage_SetTagDescription(_tag, description);
+}
+
+BOOL fipTag::setID(WORD id) {
+	return FreeImage_SetTagID(_tag, id);
+}
+
+BOOL fipTag::setType(FREE_IMAGE_MDTYPE type) {
+	return FreeImage_SetTagType(_tag, type);
+}
+
+BOOL fipTag::setCount(DWORD count) {
+	return FreeImage_SetTagCount(_tag, count);
+}
+
+BOOL fipTag::setLength(DWORD length) {
+	return FreeImage_SetTagLength(_tag, length);
+}
+
+BOOL fipTag::setValue(const void *value) {
+	return FreeImage_SetTagValue(_tag, value);
+}
+
+const char* fipTag::toString(FREE_IMAGE_MDMODEL model, char *Make) const {
+	return FreeImage_TagToString(model, _tag, Make);
+}
diff --git a/Wrapper/FreeImagePlus/src/fipWinImage.cpp b/Wrapper/FreeImagePlus/src/fipWinImage.cpp
index 5d207b3..092b655 100644
--- a/Wrapper/FreeImagePlus/src/fipWinImage.cpp
+++ b/Wrapper/FreeImagePlus/src/fipWinImage.cpp
@@ -1,488 +1,488 @@
-// ==========================================================
-// fipWinImage class implementation
-//
-// Design and implementation by
-// - Herv� Drolon (drolon at infonie.fr)
-//
-// This file is part of FreeImage 3
-//
-// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
-// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
-// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
-// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
-// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
-// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
-// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
-// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
-// THIS DISCLAIMER.
-//
-// Use at your own risk!
-// ==========================================================
-
-#include "FreeImagePlus.h"
-
-#ifdef _WIN32
-
-// marker used for clipboard copy / paste
-
-static inline void 
-SET_FREEIMAGE_MARKER(BITMAPINFOHEADER *bmih, FIBITMAP *dib) {
-	// Windows constants goes from 0L to 5L
-	// Add 0xFF to avoid conflicts
-	bmih->biCompression = 0xFF + FreeImage_GetImageType(dib);
-}
-
-static inline FREE_IMAGE_TYPE 
-GET_FREEIMAGE_MARKER(BITMAPINFOHEADER *bmih) {
-	return (FREE_IMAGE_TYPE)(bmih->biCompression - 0xFF);
-}
-
-///////////////////////////////////////////////////////////////////
-// Construction / Destruction
-
-fipWinImage::fipWinImage(FREE_IMAGE_TYPE image_type, unsigned width, unsigned height, unsigned bpp) : fipImage(image_type, width, height, bpp) {
-	_display_dib = NULL;
-	_bDeleteMe = FALSE;
-	// default tone mapping operator
-	_tmo = FITMO_DRAGO03;
-	_tmo_param_1 = 0;
-	_tmo_param_2 = 0;
-	_tmo_param_3 = 1;
-	_tmo_param_4 = 0;
-}
-
-fipWinImage::~fipWinImage() { 
-	if(_bDeleteMe) {
-		FreeImage_Unload(_display_dib);
-	}
-}
-
-void fipWinImage::clear() {
-	// delete _display_dib
-	if(_bDeleteMe) {
-		FreeImage_Unload(_display_dib);
-	}
-	_display_dib = NULL;
-	_bDeleteMe = FALSE;
-	// delete base class data
-	fipImage::clear();
-}
-
-BOOL fipWinImage::isValid() const {
-	return fipImage::isValid();
-}
-
-///////////////////////////////////////////////////////////////////
-// Copying
-
-fipWinImage& fipWinImage::operator=(const fipImage& Image) {
-	// delete _display_dib
-	if(_bDeleteMe) {
-		FreeImage_Unload(_display_dib);
-	}
-	_display_dib = NULL;
-	_bDeleteMe = FALSE;
-	// clone the base class
-	fipImage::operator=(Image);
-
-	return *this;
-}
-
-fipWinImage& fipWinImage::operator=(const fipWinImage& Image) {
-	if(this != &Image) {
-		// delete _display_dib
-		if(_bDeleteMe) {
-			FreeImage_Unload(_display_dib);
-		}
-		_display_dib = NULL;
-		_bDeleteMe = FALSE;
-		// copy tmo data
-		_tmo = Image._tmo;
-		_tmo_param_1 = Image._tmo_param_1;
-		_tmo_param_2 = Image._tmo_param_2;
-		_tmo_param_3 = Image._tmo_param_3;
-		_tmo_param_4 = Image._tmo_param_4;
-
-		// clone the base class
-		fipImage::operator=(Image);
-	}
-	return *this;
-}
-
-HANDLE fipWinImage::copyToHandle() const {
-	HANDLE hMem = NULL;
-
-	if(_dib) {
-
-		// Get equivalent DIB size
-		long dib_size = sizeof(BITMAPINFOHEADER);
-		dib_size += FreeImage_GetColorsUsed(_dib) * sizeof(RGBQUAD);
-		dib_size += FreeImage_GetPitch(_dib) * FreeImage_GetHeight(_dib);
-
-		// Allocate a DIB
-		hMem = GlobalAlloc(GHND, dib_size);
-		BYTE *dib = (BYTE*)GlobalLock(hMem);
-
-		memset(dib, 0, dib_size);
-
-		BYTE *p_dib = (BYTE*)dib;
-
-		// Copy the BITMAPINFOHEADER
-
-		BITMAPINFOHEADER *bih = FreeImage_GetInfoHeader(_dib);
-		memcpy(p_dib, bih, sizeof(BITMAPINFOHEADER));
-		if(FreeImage_GetImageType(_dib) != FIT_BITMAP) {
-			// this hack is used to store the bitmap type in the biCompression member of the BITMAPINFOHEADER
-			SET_FREEIMAGE_MARKER((BITMAPINFOHEADER*)p_dib, _dib);
-		}
-		p_dib += sizeof(BITMAPINFOHEADER);
-
-		// Copy the palette
-
-		RGBQUAD *pal = FreeImage_GetPalette(_dib);
-		memcpy(p_dib, pal, FreeImage_GetColorsUsed(_dib) * sizeof(RGBQUAD));
-		p_dib += FreeImage_GetColorsUsed(_dib) * sizeof(RGBQUAD);
-
-		// Copy the bitmap
-
-		BYTE *bits = FreeImage_GetBits(_dib);
-		memcpy(p_dib, bits, FreeImage_GetPitch(_dib) * FreeImage_GetHeight(_dib));
-
-		GlobalUnlock(hMem);
-	}
-
-	return hMem;
-}
-
-BOOL fipWinImage::copyFromHandle(HANDLE hMem) {
-	BYTE *lpVoid = NULL;
-	BITMAPINFOHEADER *pHead = NULL;
-	RGBQUAD *pPalette = NULL;
-	BYTE *bits = NULL;
-	DWORD bitfields[3] = {0, 0, 0};
-
-	// Get a pointer to the bitmap
-	lpVoid = (BYTE *)GlobalLock(hMem);
-
-	// Get a pointer to the bitmap header
-	pHead = (BITMAPINFOHEADER *)lpVoid;
-
-	// Get a pointer to the palette
-	if(pHead->biBitCount < 16)
-		pPalette = (RGBQUAD *)(((BYTE *)pHead) + sizeof(BITMAPINFOHEADER));
-
-	// Get a pointer to the pixels
-	bits = ((BYTE*)pHead + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * pHead->biClrUsed);
-
-	if(pHead->biCompression == BI_BITFIELDS) {
-		// Take into account the color masks that specify the red, green, and blue components (16- and 32-bit)
-		unsigned mask_size = 3 * sizeof(DWORD);
-		memcpy(&bitfields[0], bits, mask_size);
-		bits += mask_size;
-	} 
-
-	if(lpVoid) {
-
-		// Allocate a new FIBITMAP
-
-		FREE_IMAGE_TYPE image_type = FIT_BITMAP;
-		// Use a hack to decide if the clipboard contains non standard bitmaps ...
-		switch(GET_FREEIMAGE_MARKER(pHead)) {
-			case FIT_UINT16:
-			case FIT_INT16:
-			case FIT_UINT32:
-			case FIT_INT32:
-			case FIT_FLOAT:
-			case FIT_DOUBLE:
-			case FIT_COMPLEX:
-			case FIT_RGB16:
-			case FIT_RGBA16:
-			case FIT_RGBF:
-			case FIT_RGBAF:
-				image_type = GET_FREEIMAGE_MARKER(pHead);
-				break;
-		}
-		if(!setSize(image_type, (WORD)pHead->biWidth, (WORD)pHead->biHeight, pHead->biBitCount, bitfields[2], bitfields[1], bitfields[0])) {
-			GlobalUnlock(lpVoid);
-			return FALSE;
-		}
-
-		// Copy the bitmap header
-		memcpy(FreeImage_GetInfoHeader(_dib), pHead, sizeof(BITMAPINFOHEADER));
-
-
-		// Copy the palette
-		memcpy(FreeImage_GetPalette(_dib), pPalette, pHead->biClrUsed * sizeof(RGBQUAD));
-
-		// Copy the bitmap
-		memcpy(FreeImage_GetBits(_dib), bits, FreeImage_GetPitch(_dib) * FreeImage_GetHeight(_dib));
-
-		GlobalUnlock(lpVoid);
-
-		return TRUE;
-	}
-
-	return FALSE;
-}
-
-BOOL fipWinImage::copyFromBitmap(HBITMAP hbmp) {
-	if(hbmp) { 
-		int Success;
-        BITMAP bm;
-		// Get informations about the bitmap
-        GetObject(hbmp, sizeof(BITMAP), (LPSTR) &bm);
-		// Create the image
-        setSize(FIT_BITMAP, (WORD)bm.bmWidth, (WORD)bm.bmHeight, (WORD)bm.bmBitsPixel);
-
-		// The GetDIBits function clears the biClrUsed and biClrImportant BITMAPINFO members (dont't know why) 
-		// So we save these infos below. This is needed for palettized images only. 
-		int nColors = FreeImage_GetColorsUsed(_dib);
-
-		// Create a device context for the bitmap
-        HDC dc = GetDC(NULL);
-		// Copy the pixels
-		Success = GetDIBits(dc,								// handle to DC
-								hbmp,						// handle to bitmap
-								0,							// first scan line to set
-								FreeImage_GetHeight(_dib),	// number of scan lines to copy
-								FreeImage_GetBits(_dib),	// array for bitmap bits
-								FreeImage_GetInfo(_dib),	// bitmap data buffer
-								DIB_RGB_COLORS				// RGB 
-								);
-		if(Success == 0) {
-			FreeImage_OutputMessageProc(FIF_UNKNOWN, "Error : GetDIBits failed");
-			ReleaseDC(NULL, dc);
-			return FALSE;
-        }
-        ReleaseDC(NULL, dc);
-
-		// restore BITMAPINFO members
-		
-		FreeImage_GetInfoHeader(_dib)->biClrUsed = nColors;
-		FreeImage_GetInfoHeader(_dib)->biClrImportant = nColors;
-
-		return TRUE;
-    }
-
-	return FALSE;
-}
-
-BOOL fipWinImage::copyToClipboard(HWND hWndNewOwner) const {
-	HANDLE hDIB = copyToHandle();
-
-	if(OpenClipboard(hWndNewOwner)) {
-		if(EmptyClipboard()) {
-			if(SetClipboardData(CF_DIB, hDIB) == NULL) {
-				MessageBox(hWndNewOwner, "Unable to set Clipboard data", "FreeImage", MB_ICONERROR);
-				CloseClipboard();
-				return FALSE;
-			}
-		}
-	}
-	CloseClipboard();
-
-	return TRUE;
-}
-
-BOOL fipWinImage::pasteFromClipboard() {
-	if(!IsClipboardFormatAvailable(CF_DIB))
-		return FALSE;
-
-	if(OpenClipboard(NULL)) {
-		HANDLE hDIB = GetClipboardData(CF_DIB);
-		copyFromHandle(hDIB);
-		CloseClipboard();
-		return TRUE;
-	}
-	CloseClipboard();
-
-	return FALSE;
-}
-
-///////////////////////////////////////////////////////////////////
-// Screen capture
-
-BOOL fipWinImage::captureWindow(HWND hWndApplicationWindow, HWND hWndSelectedWindow) {
-	int xScreen, yScreen, xshift, yshift;
-	RECT r;
-
-	// Get window size
-	GetWindowRect(hWndSelectedWindow, &r);
-
-	// Check if the window is out of the screen or maximixed
-	xshift = 0;
-	yshift = 0;
-	xScreen = GetSystemMetrics(SM_CXSCREEN);
-	yScreen = GetSystemMetrics(SM_CYSCREEN);
-	if(r.right > xScreen)
-		   r.right = xScreen;
-	if(r.bottom > yScreen)
-		   r.bottom = yScreen;
-	if(r.left < 0) {
-		   xshift = -r.left;
-		   r.left = 0;
-	}
-	if(r.top < 0){
-		   yshift = -r.top;
-		   r.top = 0;
-	}
-	
-	int width  = r.right  - r.left;
-	int height = r.bottom - r.top;
-
-	if(width <= 0 || height <= 0)
-		return FALSE;
-
-	// Hide the application window. 
-	ShowWindow(hWndApplicationWindow, SW_HIDE); 
-	// Bring the window at the top most level
-	SetWindowPos(hWndSelectedWindow, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
-	// Give enough time to refresh the window
-	Sleep(500);
-
-	// Prepare the DCs
-	HDC dstDC = GetDC(NULL);
-    HDC srcDC = GetWindowDC(hWndSelectedWindow); // full window (GetDC(hWndSelectedWindow) = clientarea)
-	HDC memDC = CreateCompatibleDC(dstDC);
-	
-	// Copy the screen to the bitmap
-	HBITMAP bm = CreateCompatibleBitmap(dstDC, width, height);
-	HBITMAP oldbm = (HBITMAP)SelectObject(memDC, bm);
-	BitBlt(memDC, 0, 0, width, height, srcDC, xshift, yshift, SRCCOPY);
-
-	// Redraw the application window. 
-	ShowWindow(hWndApplicationWindow, SW_SHOW); 
-
-	// Restore the position
-	SetWindowPos(hWndSelectedWindow, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
-	SetWindowPos(hWndApplicationWindow, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
-	
-	// Convert the HBITMAP to a FIBITMAP
-	copyFromBitmap(bm);
-
-	// Free objects
-	DeleteObject(SelectObject(memDC, oldbm));
-	DeleteDC(memDC);
-
-	// Convert 32-bit images to 24-bit
-	if(getBitsPerPixel() == 32) {
-		convertTo24Bits();
-	}
-
-	return TRUE;
-}
-
-
-///////////////////////////////////////////////////////////////////
-// Painting operations
-
-void fipWinImage::drawEx(HDC hDC, RECT& rcDest, BOOL useFileBkg, RGBQUAD *appBkColor, FIBITMAP *bg) const {
-	// Convert to a standard bitmap if needed
-	if(_bHasChanged) {
-		if(_bDeleteMe) {
-			FreeImage_Unload(_display_dib);
-			_display_dib = NULL;
-			_bDeleteMe = FALSE;
-		}
-
-		FREE_IMAGE_TYPE image_type = getImageType();
-		if(image_type == FIT_BITMAP) {
-			BOOL bHasBackground = FreeImage_HasBackgroundColor(_dib);
-			BOOL bIsTransparent = FreeImage_IsTransparent(_dib);
-
-			if(!bIsTransparent && (!bHasBackground || !useFileBkg)) {
-				// Copy pointer
-				_display_dib = _dib;
-			}
-			else {
-				// Create the transparent / alpha blended image
-				_display_dib = FreeImage_Composite(_dib, useFileBkg, appBkColor, bg);
-				if(_display_dib) {
-					// Remember to delete _display_dib
-					_bDeleteMe = TRUE;
-				} else {
-					// Something failed: copy pointers
-					_display_dib = _dib;
-				}
-			}
-		} else {
-			// Convert to a standard dib for display
-
-			if(image_type == FIT_COMPLEX) {
-				// Convert to type FIT_DOUBLE
-				FIBITMAP *dib_double = FreeImage_GetComplexChannel(_dib, FICC_MAG);
-				// Convert to a standard bitmap (linear scaling)
-				_display_dib = FreeImage_ConvertToStandardType(dib_double, TRUE);
-				// Free image of type FIT_DOUBLE
-				FreeImage_Unload(dib_double);
-			} else if((image_type == FIT_RGBF) || (image_type == FIT_RGBAF) || (image_type == FIT_RGB16)) {
-				// Apply a tone mapping algorithm and convert to 24-bit 
-				switch(_tmo) {
-					case FITMO_REINHARD05:
-						_display_dib = FreeImage_TmoReinhard05Ex(_dib, _tmo_param_1, _tmo_param_2, _tmo_param_3, _tmo_param_4);
-						break;
-					default:
-						_display_dib = FreeImage_ToneMapping(_dib, _tmo, _tmo_param_1, _tmo_param_2);
-						break;
-				}
-			} else if(image_type == FIT_RGBA16) {
-				// Convert to 32-bit
-				FIBITMAP *dib32 = FreeImage_ConvertTo32Bits(_dib);
-				if(dib32) {
-					// Create the transparent / alpha blended image
-					_display_dib = FreeImage_Composite(dib32, useFileBkg, appBkColor, bg);
-					FreeImage_Unload(dib32);
-				}
-			} else {
-				// Other cases: convert to a standard bitmap (linear scaling)
-				_display_dib = FreeImage_ConvertToStandardType(_dib, TRUE);
-			}
-			// Remember to delete _display_dib
-			_bDeleteMe = TRUE;
-		}
-
-		_bHasChanged = FALSE;
-	}
-
-	// Draw the dib
-	SetStretchBltMode(hDC, COLORONCOLOR);	
-	StretchDIBits(hDC, rcDest.left, rcDest.top, 
-		rcDest.right-rcDest.left, rcDest.bottom-rcDest.top, 
-		0, 0, FreeImage_GetWidth(_display_dib), FreeImage_GetHeight(_display_dib),
-		FreeImage_GetBits(_display_dib), FreeImage_GetInfo(_display_dib), DIB_RGB_COLORS, SRCCOPY);
-
-}
-
-void fipWinImage::setToneMappingOperator(FREE_IMAGE_TMO tmo, double first_param, double second_param, double third_param, double fourth_param) {
-	// avoid costly operations if possible ...
-	if((_tmo != tmo) || (_tmo_param_1 != first_param) || (_tmo_param_2 != second_param) || (_tmo_param_3 != third_param) || (_tmo_param_4 != fourth_param)) {
-		_tmo = tmo;
-		_tmo_param_1 = first_param;
-		_tmo_param_2 = second_param;
-		_tmo_param_3 = third_param;
-		_tmo_param_4 = fourth_param;
-
-		FREE_IMAGE_TYPE image_type = getImageType();
-		switch(image_type) {
-			case FIT_RGBF:
-			case FIT_RGBAF:
-			case FIT_RGB16:
-			case FIT_RGBA16:
-				_bHasChanged = TRUE;
-				break;
-			default:
-				break;
-		}
-	}
-}
-
-void fipWinImage::getToneMappingOperator(FREE_IMAGE_TMO *tmo, double *first_param, double *second_param, double *third_param, double *fourth_param) const {
-	*tmo = _tmo;
-	*first_param = _tmo_param_1;
-	*second_param = _tmo_param_2;
-	*third_param = _tmo_param_3;
-	*fourth_param = _tmo_param_4;
-}
-
-
-#endif // _WIN32
+// ==========================================================
+// fipWinImage class implementation
+//
+// Design and implementation by
+// - Herv� Drolon (drolon at infonie.fr)
+//
+// This file is part of FreeImage 3
+//
+// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
+// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
+// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
+// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
+// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
+// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
+// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+// THIS DISCLAIMER.
+//
+// Use at your own risk!
+// ==========================================================
+
+#include "FreeImagePlus.h"
+
+#ifdef _WIN32
+
+// marker used for clipboard copy / paste
+
+static inline void 
+SET_FREEIMAGE_MARKER(BITMAPINFOHEADER *bmih, FIBITMAP *dib) {
+	// Windows constants goes from 0L to 5L
+	// Add 0xFF to avoid conflicts
+	bmih->biCompression = 0xFF + FreeImage_GetImageType(dib);
+}
+
+static inline FREE_IMAGE_TYPE 
+GET_FREEIMAGE_MARKER(BITMAPINFOHEADER *bmih) {
+	return (FREE_IMAGE_TYPE)(bmih->biCompression - 0xFF);
+}
+
+///////////////////////////////////////////////////////////////////
+// Construction / Destruction
+
+fipWinImage::fipWinImage(FREE_IMAGE_TYPE image_type, unsigned width, unsigned height, unsigned bpp) : fipImage(image_type, width, height, bpp) {
+	_display_dib = NULL;
+	_bDeleteMe = FALSE;
+	// default tone mapping operator
+	_tmo = FITMO_DRAGO03;
+	_tmo_param_1 = 0;
+	_tmo_param_2 = 0;
+	_tmo_param_3 = 1;
+	_tmo_param_4 = 0;
+}
+
+fipWinImage::~fipWinImage() { 
+	if(_bDeleteMe) {
+		FreeImage_Unload(_display_dib);
+	}
+}
+
+void fipWinImage::clear() {
+	// delete _display_dib
+	if(_bDeleteMe) {
+		FreeImage_Unload(_display_dib);
+	}
+	_display_dib = NULL;
+	_bDeleteMe = FALSE;
+	// delete base class data
+	fipImage::clear();
+}
+
+BOOL fipWinImage::isValid() const {
+	return fipImage::isValid();
+}
+
+///////////////////////////////////////////////////////////////////
+// Copying
+
+fipWinImage& fipWinImage::operator=(const fipImage& Image) {
+	// delete _display_dib
+	if(_bDeleteMe) {
+		FreeImage_Unload(_display_dib);
+	}
+	_display_dib = NULL;
+	_bDeleteMe = FALSE;
+	// clone the base class
+	fipImage::operator=(Image);
+
+	return *this;
+}
+
+fipWinImage& fipWinImage::operator=(const fipWinImage& Image) {
+	if(this != &Image) {
+		// delete _display_dib
+		if(_bDeleteMe) {
+			FreeImage_Unload(_display_dib);
+		}
+		_display_dib = NULL;
+		_bDeleteMe = FALSE;
+		// copy tmo data
+		_tmo = Image._tmo;
+		_tmo_param_1 = Image._tmo_param_1;
+		_tmo_param_2 = Image._tmo_param_2;
+		_tmo_param_3 = Image._tmo_param_3;
+		_tmo_param_4 = Image._tmo_param_4;
+
+		// clone the base class
+		fipImage::operator=(Image);
+	}
+	return *this;
+}
+
+HANDLE fipWinImage::copyToHandle() const {
+	HANDLE hMem = NULL;
+
+	if(_dib) {
+
+		// Get equivalent DIB size
+		long dib_size = sizeof(BITMAPINFOHEADER);
+		dib_size += FreeImage_GetColorsUsed(_dib) * sizeof(RGBQUAD);
+		dib_size += FreeImage_GetPitch(_dib) * FreeImage_GetHeight(_dib);
+
+		// Allocate a DIB
+		hMem = GlobalAlloc(GHND, dib_size);
+		BYTE *dib = (BYTE*)GlobalLock(hMem);
+
+		memset(dib, 0, dib_size);
+
+		BYTE *p_dib = (BYTE*)dib;
+
+		// Copy the BITMAPINFOHEADER
+
+		BITMAPINFOHEADER *bih = FreeImage_GetInfoHeader(_dib);
+		memcpy(p_dib, bih, sizeof(BITMAPINFOHEADER));
+		if(FreeImage_GetImageType(_dib) != FIT_BITMAP) {
+			// this hack is used to store the bitmap type in the biCompression member of the BITMAPINFOHEADER
+			SET_FREEIMAGE_MARKER((BITMAPINFOHEADER*)p_dib, _dib);
+		}
+		p_dib += sizeof(BITMAPINFOHEADER);
+
+		// Copy the palette
+
+		RGBQUAD *pal = FreeImage_GetPalette(_dib);
+		memcpy(p_dib, pal, FreeImage_GetColorsUsed(_dib) * sizeof(RGBQUAD));
+		p_dib += FreeImage_GetColorsUsed(_dib) * sizeof(RGBQUAD);
+
+		// Copy the bitmap
+
+		BYTE *bits = FreeImage_GetBits(_dib);
+		memcpy(p_dib, bits, FreeImage_GetPitch(_dib) * FreeImage_GetHeight(_dib));
+
+		GlobalUnlock(hMem);
+	}
+
+	return hMem;
+}
+
+BOOL fipWinImage::copyFromHandle(HANDLE hMem) {
+	BYTE *lpVoid = NULL;
+	BITMAPINFOHEADER *pHead = NULL;
+	RGBQUAD *pPalette = NULL;
+	BYTE *bits = NULL;
+	DWORD bitfields[3] = {0, 0, 0};
+
+	// Get a pointer to the bitmap
+	lpVoid = (BYTE *)GlobalLock(hMem);
+
+	// Get a pointer to the bitmap header
+	pHead = (BITMAPINFOHEADER *)lpVoid;
+
+	// Get a pointer to the palette
+	if(pHead->biBitCount < 16)
+		pPalette = (RGBQUAD *)(((BYTE *)pHead) + sizeof(BITMAPINFOHEADER));
+
+	// Get a pointer to the pixels
+	bits = ((BYTE*)pHead + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * pHead->biClrUsed);
+
+	if(pHead->biCompression == BI_BITFIELDS) {
+		// Take into account the color masks that specify the red, green, and blue components (16- and 32-bit)
+		unsigned mask_size = 3 * sizeof(DWORD);
+		memcpy(&bitfields[0], bits, mask_size);
+		bits += mask_size;
+	} 
+
+	if(lpVoid) {
+
+		// Allocate a new FIBITMAP
+
+		FREE_IMAGE_TYPE image_type = FIT_BITMAP;
+		// Use a hack to decide if the clipboard contains non standard bitmaps ...
+		switch(GET_FREEIMAGE_MARKER(pHead)) {
+			case FIT_UINT16:
+			case FIT_INT16:
+			case FIT_UINT32:
+			case FIT_INT32:
+			case FIT_FLOAT:
+			case FIT_DOUBLE:
+			case FIT_COMPLEX:
+			case FIT_RGB16:
+			case FIT_RGBA16:
+			case FIT_RGBF:
+			case FIT_RGBAF:
+				image_type = GET_FREEIMAGE_MARKER(pHead);
+				break;
+		}
+		if(!setSize(image_type, (WORD)pHead->biWidth, (WORD)pHead->biHeight, pHead->biBitCount, bitfields[2], bitfields[1], bitfields[0])) {
+			GlobalUnlock(lpVoid);
+			return FALSE;
+		}
+
+		// Copy the bitmap header
+		memcpy(FreeImage_GetInfoHeader(_dib), pHead, sizeof(BITMAPINFOHEADER));
+
+
+		// Copy the palette
+		memcpy(FreeImage_GetPalette(_dib), pPalette, pHead->biClrUsed * sizeof(RGBQUAD));
+
+		// Copy the bitmap
+		memcpy(FreeImage_GetBits(_dib), bits, FreeImage_GetPitch(_dib) * FreeImage_GetHeight(_dib));
+
+		GlobalUnlock(lpVoid);
+
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+BOOL fipWinImage::copyFromBitmap(HBITMAP hbmp) {
+	if(hbmp) { 
+		int Success;
+        BITMAP bm;
+		// Get informations about the bitmap
+        GetObject(hbmp, sizeof(BITMAP), (LPSTR) &bm);
+		// Create the image
+        setSize(FIT_BITMAP, (WORD)bm.bmWidth, (WORD)bm.bmHeight, (WORD)bm.bmBitsPixel);
+
+		// The GetDIBits function clears the biClrUsed and biClrImportant BITMAPINFO members (dont't know why) 
+		// So we save these infos below. This is needed for palettized images only. 
+		int nColors = FreeImage_GetColorsUsed(_dib);
+
+		// Create a device context for the bitmap
+        HDC dc = GetDC(NULL);
+		// Copy the pixels
+		Success = GetDIBits(dc,								// handle to DC
+								hbmp,						// handle to bitmap
+								0,							// first scan line to set
+								FreeImage_GetHeight(_dib),	// number of scan lines to copy
+								FreeImage_GetBits(_dib),	// array for bitmap bits
+								FreeImage_GetInfo(_dib),	// bitmap data buffer
+								DIB_RGB_COLORS				// RGB 
+								);
+		if(Success == 0) {
+			FreeImage_OutputMessageProc(FIF_UNKNOWN, "Error : GetDIBits failed");
+			ReleaseDC(NULL, dc);
+			return FALSE;
+        }
+        ReleaseDC(NULL, dc);
+
+		// restore BITMAPINFO members
+		
+		FreeImage_GetInfoHeader(_dib)->biClrUsed = nColors;
+		FreeImage_GetInfoHeader(_dib)->biClrImportant = nColors;
+
+		return TRUE;
+    }
+
+	return FALSE;
+}
+
+BOOL fipWinImage::copyToClipboard(HWND hWndNewOwner) const {
+	HANDLE hDIB = copyToHandle();
+
+	if(OpenClipboard(hWndNewOwner)) {
+		if(EmptyClipboard()) {
+			if(SetClipboardData(CF_DIB, hDIB) == NULL) {
+				MessageBox(hWndNewOwner, "Unable to set Clipboard data", "FreeImage", MB_ICONERROR);
+				CloseClipboard();
+				return FALSE;
+			}
+		}
+	}
+	CloseClipboard();
+
+	return TRUE;
+}
+
+BOOL fipWinImage::pasteFromClipboard() {
+	if(!IsClipboardFormatAvailable(CF_DIB))
+		return FALSE;
+
+	if(OpenClipboard(NULL)) {
+		HANDLE hDIB = GetClipboardData(CF_DIB);
+		copyFromHandle(hDIB);
+		CloseClipboard();
+		return TRUE;
+	}
+	CloseClipboard();
+
+	return FALSE;
+}
+
+///////////////////////////////////////////////////////////////////
+// Screen capture
+
+BOOL fipWinImage::captureWindow(HWND hWndApplicationWindow, HWND hWndSelectedWindow) {
+	int xScreen, yScreen, xshift, yshift;
+	RECT r;
+
+	// Get window size
+	GetWindowRect(hWndSelectedWindow, &r);
+
+	// Check if the window is out of the screen or maximixed
+	xshift = 0;
+	yshift = 0;
+	xScreen = GetSystemMetrics(SM_CXSCREEN);
+	yScreen = GetSystemMetrics(SM_CYSCREEN);
+	if(r.right > xScreen)
+		   r.right = xScreen;
+	if(r.bottom > yScreen)
+		   r.bottom = yScreen;
+	if(r.left < 0) {
+		   xshift = -r.left;
+		   r.left = 0;
+	}
+	if(r.top < 0){
+		   yshift = -r.top;
+		   r.top = 0;
+	}
+	
+	int width  = r.right  - r.left;
+	int height = r.bottom - r.top;
+
+	if(width <= 0 || height <= 0)
+		return FALSE;
+
+	// Hide the application window. 
+	ShowWindow(hWndApplicationWindow, SW_HIDE); 
+	// Bring the window at the top most level
+	SetWindowPos(hWndSelectedWindow, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
+	// Give enough time to refresh the window
+	Sleep(500);
+
+	// Prepare the DCs
+	HDC dstDC = GetDC(NULL);
+    HDC srcDC = GetWindowDC(hWndSelectedWindow); // full window (GetDC(hWndSelectedWindow) = clientarea)
+	HDC memDC = CreateCompatibleDC(dstDC);
+	
+	// Copy the screen to the bitmap
+	HBITMAP bm = CreateCompatibleBitmap(dstDC, width, height);
+	HBITMAP oldbm = (HBITMAP)SelectObject(memDC, bm);
+	BitBlt(memDC, 0, 0, width, height, srcDC, xshift, yshift, SRCCOPY);
+
+	// Redraw the application window. 
+	ShowWindow(hWndApplicationWindow, SW_SHOW); 
+
+	// Restore the position
+	SetWindowPos(hWndSelectedWindow, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
+	SetWindowPos(hWndApplicationWindow, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
+	
+	// Convert the HBITMAP to a FIBITMAP
+	copyFromBitmap(bm);
+
+	// Free objects
+	DeleteObject(SelectObject(memDC, oldbm));
+	DeleteDC(memDC);
+
+	// Convert 32-bit images to 24-bit
+	if(getBitsPerPixel() == 32) {
+		convertTo24Bits();
+	}
+
+	return TRUE;
+}
+
+
+///////////////////////////////////////////////////////////////////
+// Painting operations
+
+void fipWinImage::drawEx(HDC hDC, RECT& rcDest, BOOL useFileBkg, RGBQUAD *appBkColor, FIBITMAP *bg) const {
+	// Convert to a standard bitmap if needed
+	if(_bHasChanged) {
+		if(_bDeleteMe) {
+			FreeImage_Unload(_display_dib);
+			_display_dib = NULL;
+			_bDeleteMe = FALSE;
+		}
+
+		FREE_IMAGE_TYPE image_type = getImageType();
+		if(image_type == FIT_BITMAP) {
+			BOOL bHasBackground = FreeImage_HasBackgroundColor(_dib);
+			BOOL bIsTransparent = FreeImage_IsTransparent(_dib);
+
+			if(!bIsTransparent && (!bHasBackground || !useFileBkg)) {
+				// Copy pointer
+				_display_dib = _dib;
+			}
+			else {
+				// Create the transparent / alpha blended image
+				_display_dib = FreeImage_Composite(_dib, useFileBkg, appBkColor, bg);
+				if(_display_dib) {
+					// Remember to delete _display_dib
+					_bDeleteMe = TRUE;
+				} else {
+					// Something failed: copy pointers
+					_display_dib = _dib;
+				}
+			}
+		} else {
+			// Convert to a standard dib for display
+
+			if(image_type == FIT_COMPLEX) {
+				// Convert to type FIT_DOUBLE
+				FIBITMAP *dib_double = FreeImage_GetComplexChannel(_dib, FICC_MAG);
+				// Convert to a standard bitmap (linear scaling)
+				_display_dib = FreeImage_ConvertToStandardType(dib_double, TRUE);
+				// Free image of type FIT_DOUBLE
+				FreeImage_Unload(dib_double);
+			} else if((image_type == FIT_RGBF) || (image_type == FIT_RGBAF) || (image_type == FIT_RGB16)) {
+				// Apply a tone mapping algorithm and convert to 24-bit 
+				switch(_tmo) {
+					case FITMO_REINHARD05:
+						_display_dib = FreeImage_TmoReinhard05Ex(_dib, _tmo_param_1, _tmo_param_2, _tmo_param_3, _tmo_param_4);
+						break;
+					default:
+						_display_dib = FreeImage_ToneMapping(_dib, _tmo, _tmo_param_1, _tmo_param_2);
+						break;
+				}
+			} else if(image_type == FIT_RGBA16) {
+				// Convert to 32-bit
+				FIBITMAP *dib32 = FreeImage_ConvertTo32Bits(_dib);
+				if(dib32) {
+					// Create the transparent / alpha blended image
+					_display_dib = FreeImage_Composite(dib32, useFileBkg, appBkColor, bg);
+					FreeImage_Unload(dib32);
+				}
+			} else {
+				// Other cases: convert to a standard bitmap (linear scaling)
+				_display_dib = FreeImage_ConvertToStandardType(_dib, TRUE);
+			}
+			// Remember to delete _display_dib
+			_bDeleteMe = TRUE;
+		}
+
+		_bHasChanged = FALSE;
+	}
+
+	// Draw the dib
+	SetStretchBltMode(hDC, COLORONCOLOR);	
+	StretchDIBits(hDC, rcDest.left, rcDest.top, 
+		rcDest.right-rcDest.left, rcDest.bottom-rcDest.top, 
+		0, 0, FreeImage_GetWidth(_display_dib), FreeImage_GetHeight(_display_dib),
+		FreeImage_GetBits(_display_dib), FreeImage_GetInfo(_display_dib), DIB_RGB_COLORS, SRCCOPY);
+
+}
+
+void fipWinImage::setToneMappingOperator(FREE_IMAGE_TMO tmo, double first_param, double second_param, double third_param, double fourth_param) {
+	// avoid costly operations if possible ...
+	if((_tmo != tmo) || (_tmo_param_1 != first_param) || (_tmo_param_2 != second_param) || (_tmo_param_3 != third_param) || (_tmo_param_4 != fourth_param)) {
+		_tmo = tmo;
+		_tmo_param_1 = first_param;
+		_tmo_param_2 = second_param;
+		_tmo_param_3 = third_param;
+		_tmo_param_4 = fourth_param;
+
+		FREE_IMAGE_TYPE image_type = getImageType();
+		switch(image_type) {
+			case FIT_RGBF:
+			case FIT_RGBAF:
+			case FIT_RGB16:
+			case FIT_RGBA16:
+				_bHasChanged = TRUE;
+				break;
+			default:
+				break;
+		}
+	}
+}
+
+void fipWinImage::getToneMappingOperator(FREE_IMAGE_TMO *tmo, double *first_param, double *second_param, double *third_param, double *fourth_param) const {
+	*tmo = _tmo;
+	*first_param = _tmo_param_1;
+	*second_param = _tmo_param_2;
+	*third_param = _tmo_param_3;
+	*fourth_param = _tmo_param_4;
+}
+
+
+#endif // _WIN32
diff --git a/Wrapper/FreeImagePlus/test/fipTest.2003.sln b/Wrapper/FreeImagePlus/test/fipTest.2003.sln
deleted file mode 100644
index 40bd09c..0000000
--- a/Wrapper/FreeImagePlus/test/fipTest.2003.sln
+++ /dev/null
@@ -1,23 +0,0 @@
-Microsoft Visual Studio Solution File, Format Version 8.00
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fipTest", "fipTest.2003.vcproj", "{D1ABE87A-65A2-4AA2-9C94-73B9B4898C3B}"
-	ProjectSection(ProjectDependencies) = postProject
-	EndProjectSection
-EndProject
-Global
-	GlobalSection(SolutionConfiguration) = preSolution
-		Debug = Debug
-		Release = Release
-	EndGlobalSection
-	GlobalSection(ProjectDependencies) = postSolution
-	EndGlobalSection
-	GlobalSection(ProjectConfiguration) = postSolution
-		{D1ABE87A-65A2-4AA2-9C94-73B9B4898C3B}.Debug.ActiveCfg = Debug|Win32
-		{D1ABE87A-65A2-4AA2-9C94-73B9B4898C3B}.Debug.Build.0 = Debug|Win32
-		{D1ABE87A-65A2-4AA2-9C94-73B9B4898C3B}.Release.ActiveCfg = Release|Win32
-		{D1ABE87A-65A2-4AA2-9C94-73B9B4898C3B}.Release.Build.0 = Release|Win32
-	EndGlobalSection
-	GlobalSection(ExtensibilityGlobals) = postSolution
-	EndGlobalSection
-	GlobalSection(ExtensibilityAddIns) = postSolution
-	EndGlobalSection
-EndGlobal
diff --git a/Wrapper/FreeImagePlus/test/fipTest.2003.vcproj b/Wrapper/FreeImagePlus/test/fipTest.2003.vcproj
deleted file mode 100644
index d516f17..0000000
--- a/Wrapper/FreeImagePlus/test/fipTest.2003.vcproj
+++ /dev/null
@@ -1,201 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="7.10"
-	Name="fipTest"
-	SccProjectName=""
-	SccLocalPath="">
-	<Platforms>
-		<Platform
-			Name="Win32"/>
-	</Platforms>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			OutputDirectory=".\Debug"
-			IntermediateDirectory=".\Debug"
-			ConfigurationType="1"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="FALSE"
-			CharacterSet="2">
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="0"
-				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
-				BasicRuntimeChecks="3"
-				RuntimeLibrary="5"
-				UsePrecompiledHeader="2"
-				PrecompiledHeaderFile=".\Debug/fipTest.pch"
-				AssemblerListingLocation=".\Debug/"
-				ObjectFile=".\Debug/"
-				ProgramDataBaseFileName=".\Debug/"
-				WarningLevel="3"
-				SuppressStartupBanner="TRUE"
-				DebugInformationFormat="4"/>
-			<Tool
-				Name="VCCustomBuildTool"/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="FreeImaged.lib FreeImagePlusd.lib"
-				OutputFile=".\Debug/fipTest.exe"
-				LinkIncremental="1"
-				SuppressStartupBanner="TRUE"
-				GenerateDebugInformation="TRUE"
-				ProgramDatabaseFile=".\Debug/fipTest.pdb"
-				SubSystem="1"
-				TargetMachine="1"/>
-			<Tool
-				Name="VCMIDLTool"
-				TypeLibraryName=".\Debug/fipTest.tlb"
-				HeaderFileName=""/>
-			<Tool
-				Name="VCPostBuildEventTool"/>
-			<Tool
-				Name="VCPreBuildEventTool"/>
-			<Tool
-				Name="VCPreLinkEventTool"/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="_DEBUG"
-				Culture="1036"/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"/>
-			<Tool
-				Name="VCWebDeploymentTool"/>
-			<Tool
-				Name="VCManagedWrapperGeneratorTool"/>
-			<Tool
-				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			OutputDirectory=".\Release"
-			IntermediateDirectory=".\Release"
-			ConfigurationType="1"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="FALSE"
-			CharacterSet="2">
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="2"
-				InlineFunctionExpansion="1"
-				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
-				StringPooling="TRUE"
-				RuntimeLibrary="4"
-				EnableFunctionLevelLinking="TRUE"
-				UsePrecompiledHeader="2"
-				PrecompiledHeaderFile=".\Release/fipTest.pch"
-				AssemblerListingLocation=".\Release/"
-				ObjectFile=".\Release/"
-				ProgramDataBaseFileName=".\Release/"
-				WarningLevel="3"
-				SuppressStartupBanner="TRUE"/>
-			<Tool
-				Name="VCCustomBuildTool"/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="FreeImage.lib FreeImagePlus.lib"
-				OutputFile=".\Release/fipTest.exe"
-				LinkIncremental="1"
-				SuppressStartupBanner="TRUE"
-				ProgramDatabaseFile=".\Release/fipTest.pdb"
-				SubSystem="1"
-				TargetMachine="1"/>
-			<Tool
-				Name="VCMIDLTool"
-				TypeLibraryName=".\Release/fipTest.tlb"
-				HeaderFileName=""/>
-			<Tool
-				Name="VCPostBuildEventTool"/>
-			<Tool
-				Name="VCPreBuildEventTool"/>
-			<Tool
-				Name="VCPreLinkEventTool"/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="1036"/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"/>
-			<Tool
-				Name="VCWebDeploymentTool"/>
-			<Tool
-				Name="VCManagedWrapperGeneratorTool"/>
-			<Tool
-				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<File
-			RelativePath="fipTest.cpp">
-			<FileConfiguration
-				Name="Debug|Win32">
-				<Tool
-					Name="VCCLCompilerTool"
-					Optimization="0"
-					PreprocessorDefinitions=""
-					BasicRuntimeChecks="3"/>
-			</FileConfiguration>
-			<FileConfiguration
-				Name="Release|Win32">
-				<Tool
-					Name="VCCLCompilerTool"
-					Optimization="2"
-					PreprocessorDefinitions=""/>
-			</FileConfiguration>
-		</File>
-		<File
-			RelativePath="fipTest.h">
-		</File>
-		<File
-			RelativePath="fipTestMemIO.cpp">
-			<FileConfiguration
-				Name="Debug|Win32">
-				<Tool
-					Name="VCCLCompilerTool"
-					Optimization="0"
-					PreprocessorDefinitions=""
-					BasicRuntimeChecks="3"/>
-			</FileConfiguration>
-			<FileConfiguration
-				Name="Release|Win32">
-				<Tool
-					Name="VCCLCompilerTool"
-					Optimization="2"
-					PreprocessorDefinitions=""/>
-			</FileConfiguration>
-		</File>
-		<File
-			RelativePath="fipTestMPage.cpp">
-			<FileConfiguration
-				Name="Debug|Win32">
-				<Tool
-					Name="VCCLCompilerTool"
-					Optimization="0"
-					PreprocessorDefinitions=""
-					BasicRuntimeChecks="3"/>
-			</FileConfiguration>
-			<FileConfiguration
-				Name="Release|Win32">
-				<Tool
-					Name="VCCLCompilerTool"
-					Optimization="2"
-					PreprocessorDefinitions=""/>
-			</FileConfiguration>
-		</File>
-		<File
-			RelativePath=".\fipTestMPageMemory.cpp">
-		</File>
-		<File
-			RelativePath=".\fipTestMPageStream.cpp">
-		</File>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
diff --git a/Wrapper/FreeImagePlus/test/fipTest.2008.vcproj b/Wrapper/FreeImagePlus/test/fipTest.2008.vcproj
index fe0ae5f..bbec75f 100644
--- a/Wrapper/FreeImagePlus/test/fipTest.2008.vcproj
+++ b/Wrapper/FreeImagePlus/test/fipTest.2008.vcproj
@@ -103,12 +103,13 @@
 			/>
 			<Tool
 				Name="VCPostBuildEventTool"
+				CommandLine="copy ..\..\..\Dist\FreeImaged.dll Debug&#x0D;&#x0A;copy ..\dist\FreeImagePlusd.dll Debug"
 			/>
 		</Configuration>
 		<Configuration
-			Name="Release|Win32"
-			OutputDirectory=".\Release"
-			IntermediateDirectory=".\Release"
+			Name="Debug|x64"
+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
 			ConfigurationType="1"
 			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
 			UseOfMFC="0"
@@ -129,31 +130,31 @@
 			/>
 			<Tool
 				Name="VCMIDLTool"
-				TypeLibraryName=".\Release/fipTest.tlb"
+				TargetEnvironment="3"
+				TypeLibraryName=".\Debug/fipTest.tlb"
 				HeaderFileName=""
 			/>
 			<Tool
 				Name="VCCLCompilerTool"
-				Optimization="2"
-				InlineFunctionExpansion="1"
-				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
-				StringPooling="true"
-				RuntimeLibrary="0"
-				EnableFunctionLevelLinking="true"
+				Optimization="0"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
 				UsePrecompiledHeader="0"
-				PrecompiledHeaderFile=".\Release/fipTest.pch"
-				AssemblerListingLocation=".\Release/"
-				ObjectFile=".\Release/"
-				ProgramDataBaseFileName=".\Release/"
+				PrecompiledHeaderFile=".\Debug/fipTest.pch"
+				AssemblerListingLocation=".\Debug/"
+				ObjectFile=".\Debug/"
+				ProgramDataBaseFileName=".\Debug/"
 				WarningLevel="3"
 				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
 			/>
 			<Tool
 				Name="VCManagedResourceCompilerTool"
 			/>
 			<Tool
 				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
+				PreprocessorDefinitions="_DEBUG"
 				Culture="1036"
 			/>
 			<Tool
@@ -161,15 +162,16 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="FreeImage.lib FreeImagePlus.lib"
-				OutputFile=".\Release/fipTest.exe"
+				AdditionalDependencies="FreeImaged.lib FreeImagePlusd.lib"
+				OutputFile=".\Debug/fipTest.exe"
 				LinkIncremental="1"
 				SuppressStartupBanner="true"
-				ProgramDatabaseFile=".\Release/fipTest.pdb"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=".\Debug/fipTest.pdb"
 				SubSystem="1"
 				RandomizedBaseAddress="1"
 				DataExecutionPrevention="0"
-				TargetMachine="1"
+				TargetMachine="17"
 			/>
 			<Tool
 				Name="VCALinkTool"
@@ -194,9 +196,9 @@
 			/>
 		</Configuration>
 		<Configuration
-			Name="Debug|x64"
-			OutputDirectory="$(PlatformName)\$(ConfigurationName)"
-			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+			Name="Release|Win32"
+			OutputDirectory=".\Release"
+			IntermediateDirectory=".\Release"
 			ConfigurationType="1"
 			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
 			UseOfMFC="0"
@@ -217,31 +219,31 @@
 			/>
 			<Tool
 				Name="VCMIDLTool"
-				TargetEnvironment="3"
-				TypeLibraryName=".\Debug/fipTest.tlb"
+				TypeLibraryName=".\Release/fipTest.tlb"
 				HeaderFileName=""
 			/>
 			<Tool
 				Name="VCCLCompilerTool"
-				Optimization="0"
-				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS"
-				BasicRuntimeChecks="3"
-				RuntimeLibrary="1"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+				StringPooling="true"
+				RuntimeLibrary="0"
+				EnableFunctionLevelLinking="true"
 				UsePrecompiledHeader="0"
-				PrecompiledHeaderFile=".\Debug/fipTest.pch"
-				AssemblerListingLocation=".\Debug/"
-				ObjectFile=".\Debug/"
-				ProgramDataBaseFileName=".\Debug/"
+				PrecompiledHeaderFile=".\Release/fipTest.pch"
+				AssemblerListingLocation=".\Release/"
+				ObjectFile=".\Release/"
+				ProgramDataBaseFileName=".\Release/"
 				WarningLevel="3"
 				SuppressStartupBanner="true"
-				DebugInformationFormat="3"
 			/>
 			<Tool
 				Name="VCManagedResourceCompilerTool"
 			/>
 			<Tool
 				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="_DEBUG"
+				PreprocessorDefinitions="NDEBUG"
 				Culture="1036"
 			/>
 			<Tool
@@ -249,16 +251,15 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="FreeImaged.lib FreeImagePlusd.lib"
-				OutputFile=".\Debug/fipTest.exe"
+				AdditionalDependencies="FreeImage.lib FreeImagePlus.lib"
+				OutputFile=".\Release/fipTest.exe"
 				LinkIncremental="1"
 				SuppressStartupBanner="true"
-				GenerateDebugInformation="true"
-				ProgramDatabaseFile=".\Debug/fipTest.pdb"
+				ProgramDatabaseFile=".\Release/fipTest.pdb"
 				SubSystem="1"
 				RandomizedBaseAddress="1"
 				DataExecutionPrevention="0"
-				TargetMachine="17"
+				TargetMachine="1"
 			/>
 			<Tool
 				Name="VCALinkTool"
@@ -389,22 +390,22 @@
 				/>
 			</FileConfiguration>
 			<FileConfiguration
-				Name="Release|Win32"
+				Name="Debug|x64"
 				>
 				<Tool
 					Name="VCCLCompilerTool"
-					Optimization="2"
+					Optimization="0"
 					PreprocessorDefinitions=""
+					BasicRuntimeChecks="3"
 				/>
 			</FileConfiguration>
 			<FileConfiguration
-				Name="Debug|x64"
+				Name="Release|Win32"
 				>
 				<Tool
 					Name="VCCLCompilerTool"
-					Optimization="0"
+					Optimization="2"
 					PreprocessorDefinitions=""
-					BasicRuntimeChecks="3"
 				/>
 			</FileConfiguration>
 			<FileConfiguration
@@ -435,22 +436,22 @@
 				/>
 			</FileConfiguration>
 			<FileConfiguration
-				Name="Release|Win32"
+				Name="Debug|x64"
 				>
 				<Tool
 					Name="VCCLCompilerTool"
-					Optimization="2"
+					Optimization="0"
 					PreprocessorDefinitions=""
+					BasicRuntimeChecks="3"
 				/>
 			</FileConfiguration>
 			<FileConfiguration
-				Name="Debug|x64"
+				Name="Release|Win32"
 				>
 				<Tool
 					Name="VCCLCompilerTool"
-					Optimization="0"
+					Optimization="2"
 					PreprocessorDefinitions=""
-					BasicRuntimeChecks="3"
 				/>
 			</FileConfiguration>
 			<FileConfiguration
@@ -477,22 +478,22 @@
 				/>
 			</FileConfiguration>
 			<FileConfiguration
-				Name="Release|Win32"
+				Name="Debug|x64"
 				>
 				<Tool
 					Name="VCCLCompilerTool"
-					Optimization="2"
+					Optimization="0"
 					PreprocessorDefinitions=""
+					BasicRuntimeChecks="3"
 				/>
 			</FileConfiguration>
 			<FileConfiguration
-				Name="Debug|x64"
+				Name="Release|Win32"
 				>
 				<Tool
 					Name="VCCLCompilerTool"
-					Optimization="0"
+					Optimization="2"
 					PreprocessorDefinitions=""
-					BasicRuntimeChecks="3"
 				/>
 			</FileConfiguration>
 			<FileConfiguration
diff --git a/Wrapper/FreeImagePlus/test/fipTest.2013.sln b/Wrapper/FreeImagePlus/test/fipTest.2013.sln
new file mode 100644
index 0000000..a60d69a
--- /dev/null
+++ b/Wrapper/FreeImagePlus/test/fipTest.2013.sln
@@ -0,0 +1,28 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Express 2013 for Windows Desktop
+VisualStudioVersion = 12.0.21005.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fipTest", "fipTest.2013.vcxproj", "{66DCA866-A381-42D5-97FB-9792066C0F20}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Debug|x64 = Debug|x64
+		Release|Win32 = Release|Win32
+		Release|x64 = Release|x64
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{66DCA866-A381-42D5-97FB-9792066C0F20}.Debug|Win32.ActiveCfg = Debug|Win32
+		{66DCA866-A381-42D5-97FB-9792066C0F20}.Debug|Win32.Build.0 = Debug|Win32
+		{66DCA866-A381-42D5-97FB-9792066C0F20}.Debug|x64.ActiveCfg = Debug|x64
+		{66DCA866-A381-42D5-97FB-9792066C0F20}.Debug|x64.Build.0 = Debug|x64
+		{66DCA866-A381-42D5-97FB-9792066C0F20}.Release|Win32.ActiveCfg = Release|Win32
+		{66DCA866-A381-42D5-97FB-9792066C0F20}.Release|Win32.Build.0 = Release|Win32
+		{66DCA866-A381-42D5-97FB-9792066C0F20}.Release|x64.ActiveCfg = Release|x64
+		{66DCA866-A381-42D5-97FB-9792066C0F20}.Release|x64.Build.0 = Release|x64
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/Wrapper/FreeImagePlus/test/fipTest.2013.vcxproj b/Wrapper/FreeImagePlus/test/fipTest.2013.vcxproj
new file mode 100644
index 0000000..0b9362d
--- /dev/null
+++ b/Wrapper/FreeImagePlus/test/fipTest.2013.vcxproj
@@ -0,0 +1,263 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectName>fipTest</ProjectName>
+    <ProjectGuid>{66DCA866-A381-42D5-97FB-9792066C0F20}</ProjectGuid>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>12.0.21005.1</_ProjectFileVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Midl>
+      <TypeLibraryName>.\Debug/fipTest.tlb</TypeLibraryName>
+      <HeaderFileName />
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+      <AdditionalIncludeDirectories>..\..\..\Dist\x32</AdditionalIncludeDirectories>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Link>
+      <AdditionalDependencies>FreeImaged.lib;FreeImagePlusd.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention />
+      <TargetMachine>MachineX86</TargetMachine>
+      <AdditionalLibraryDirectories>..\..\..\Dist\x32;..\dist\x32</AdditionalLibraryDirectories>
+      <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+    </Link>
+    <PostBuildEvent>
+      <Command>copy ..\..\..\Dist\x32\FreeImaged.dll .\$(Platform)\$(Configuration)\
+copy ..\dist\x32\FreeImagePlusd.dll .\$(Platform)\$(Configuration)\
+
+</Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Midl>
+      <TypeLibraryName>.\Release/fipTest.tlb</TypeLibraryName>
+      <HeaderFileName />
+    </Midl>
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <AdditionalIncludeDirectories>..\..\..\Dist\x32</AdditionalIncludeDirectories>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Link>
+      <AdditionalDependencies>FreeImage.lib;FreeImagePlus.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention />
+      <TargetMachine>MachineX86</TargetMachine>
+      <AdditionalLibraryDirectories>..\..\..\Dist\x32;..\dist\x32</AdditionalLibraryDirectories>
+      <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+      <TypeLibraryName>.\Debug/fipTest.tlb</TypeLibraryName>
+      <HeaderFileName />
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <AdditionalIncludeDirectories>..\..\..\Dist\x64</AdditionalIncludeDirectories>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Link>
+      <AdditionalDependencies>FreeImaged.lib;FreeImagePlusd.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention />
+      <TargetMachine>MachineX64</TargetMachine>
+      <AdditionalLibraryDirectories>..\..\..\Dist\x64;..\dist\x64</AdditionalLibraryDirectories>
+      <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+      <TypeLibraryName>.\Release/fipTest.tlb</TypeLibraryName>
+      <HeaderFileName />
+    </Midl>
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <AdditionalIncludeDirectories>..\..\..\Dist\x64</AdditionalIncludeDirectories>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Link>
+      <AdditionalDependencies>FreeImage.lib;FreeImagePlus.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention />
+      <TargetMachine>MachineX64</TargetMachine>
+      <AdditionalLibraryDirectories>..\..\..\Dist\x64;..\dist\x64</AdditionalLibraryDirectories>
+      <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="fipTest.cpp">
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+    </ClCompile>
+    <ClCompile Include="fipTestMemIO.cpp">
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+    </ClCompile>
+    <ClCompile Include="fipTestMPage.cpp">
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+    </ClCompile>
+    <ClCompile Include="fipTestMPageMemory.cpp" />
+    <ClCompile Include="fipTestMPageStream.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="fipTest.h" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/Wrapper/FreeImagePlus/test/fipTestMPage.cpp b/Wrapper/FreeImagePlus/test/fipTestMPage.cpp
index 4b81b17..ec2572f 100644
--- a/Wrapper/FreeImagePlus/test/fipTestMPage.cpp
+++ b/Wrapper/FreeImagePlus/test/fipTestMPage.cpp
@@ -28,7 +28,7 @@ using namespace std;
 // Multipage test scripts
 
 BOOL testCloneMultiPage(const char *input, const char *output, int output_flag) {
-
+	BOOL bSuccess = FALSE;
 	BOOL bMemoryCache = TRUE;
 
 	fipMultiPage src(bMemoryCache);
@@ -39,11 +39,13 @@ BOOL testCloneMultiPage(const char *input, const char *output, int output_flag)
 	fipImage image;
 
 	// Open src file (read-only, use memory cache)
-	src.open(input, FALSE, TRUE);
+	bSuccess = src.open(input, FALSE, TRUE);
+	assert(bSuccess);
 
 	if(src.isValid()) {
 		// Open dst file (creation, use memory cache)
-		dst.open(output, TRUE, FALSE);
+		bSuccess = dst.open(output, TRUE, FALSE);
+		assert(bSuccess);
 
 		// Get src page count
 		int count = src.getPageCount();
@@ -61,9 +63,12 @@ BOOL testCloneMultiPage(const char *input, const char *output, int output_flag)
 		}
 
 		// Close src
-		src.close(0);
+		bSuccess = src.close(0);
+		assert(bSuccess);
+
 		// Save and close dst
-		dst.close(output_flag);
+		bSuccess = dst.close(output_flag);
+		assert(bSuccess);
 
 		return TRUE;
 	}
diff --git a/Wrapper/FreeImagePlus/test/fipTestMPageMemory.cpp b/Wrapper/FreeImagePlus/test/fipTestMPageMemory.cpp
index f184396..352c9ff 100644
--- a/Wrapper/FreeImagePlus/test/fipTestMPageMemory.cpp
+++ b/Wrapper/FreeImagePlus/test/fipTestMPageMemory.cpp
@@ -33,6 +33,7 @@ loadBuffer(const char *lpszPathName, BYTE **buffer, DWORD *length) {
 
 	// get data associated with lpszPathName
 	result = stat(lpszPathName, &file_info);
+	assert(result == 0);
 	if(result == 0) {
 		// allocate a memory buffer and load temporary data
 		*buffer = (BYTE*)malloc(file_info.st_size * sizeof(BYTE));
diff --git a/Wrapper/FreeImagePlus/test/fipTestMemIO.cpp b/Wrapper/FreeImagePlus/test/fipTestMemIO.cpp
index 33f849b..3be469c 100644
--- a/Wrapper/FreeImagePlus/test/fipTestMemIO.cpp
+++ b/Wrapper/FreeImagePlus/test/fipTestMemIO.cpp
@@ -31,6 +31,7 @@ using namespace std;
 Test saving to a memory stream
 */
 void testSaveMemIO(const char *lpszPathName) {
+	BOOL bSuccess = FALSE;
 
 	// load a regular file
 	FREE_IMAGE_FORMAT fif = FreeImage_GetFileType(lpszPathName);
@@ -40,7 +41,8 @@ void testSaveMemIO(const char *lpszPathName) {
 	fipMemoryIO memIO;
 
 	// save the file to memory
-	memIO.save(fif, dib, 0);
+	bSuccess = memIO.save(fif, dib, 0);
+	assert(bSuccess == TRUE);
 
 	// at this point, memIO contains the entire PNG data in memory. 
 	// the amount of space used by the memory is equal to file_size	
@@ -57,9 +59,11 @@ void testSaveMemIO(const char *lpszPathName) {
 	
 	// load an image from the memory handle 	
 	FIBITMAP *check = memIO.load(mem_fif, 0);
+	assert(check != NULL);
 
 	// save as a regular file
-	FreeImage_Save(FIF_PNG, check, "dump.png", PNG_DEFAULT);
+	bSuccess = FreeImage_Save(FIF_PNG, check, "dump.png", PNG_DEFAULT);
+	assert(bSuccess == TRUE);
 
 	FreeImage_Unload(check);
 	FreeImage_Unload(dib);
@@ -73,6 +77,7 @@ Test loading from a buffer attached to a memory stream
 void testLoadMemIO(const char *lpszPathName) {
 	struct stat buf;
 	int result;
+	BOOL bSuccess = FALSE;
 
 	// get data associated with lpszPathName
 	result = stat(lpszPathName, &buf);
@@ -93,9 +98,11 @@ void testLoadMemIO(const char *lpszPathName) {
 
 				// load an image from the memory stream
 				FIBITMAP *check = memIO.load(fif, PNG_DEFAULT);
+				assert(check != NULL);
 
 				// save as a regular file
-				FreeImage_Save(FIF_PNG, check, "blob.png", PNG_DEFAULT);
+				bSuccess = FreeImage_Save(FIF_PNG, check, "blob.png", PNG_DEFAULT);
+				assert(bSuccess == TRUE);
 				
 				// close the stream (memIO is destroyed)
 			}
@@ -110,6 +117,7 @@ void testLoadMemIO(const char *lpszPathName) {
 Test extracting a memory buffer from a memory stream
 */
 void testAcquireMemIO(const char *lpszPathName) {
+	BOOL bSuccess = FALSE;
 
 	// load a regular file
 	FREE_IMAGE_FORMAT fif = FreeImage_GetFileType(lpszPathName);
@@ -119,13 +127,15 @@ void testAcquireMemIO(const char *lpszPathName) {
 	fipMemoryIO memIO;
 
 	// save the file to memory
-	memIO.save(FIF_PNG, dib, PNG_DEFAULT);
+	bSuccess = memIO.save(FIF_PNG, dib, PNG_DEFAULT);
+	assert(bSuccess == TRUE);
 
 	// get the buffer from the memory stream
 	BYTE *mem_buffer = NULL;
 	DWORD size_in_bytes = 0;
 
-	memIO.acquire(&mem_buffer, &size_in_bytes);
+	bSuccess = memIO.acquire(&mem_buffer, &size_in_bytes);
+	assert(bSuccess == TRUE);
 
 	// save the buffer in a file stream
 	FILE *stream = fopen("buffer.png", "wb");
@@ -148,6 +158,7 @@ void testImageMemIO(const char *lpszPathName) {
 
 	// load a regular file
 	bSuccess = image.load(lpszPathName);
+	assert(bSuccess == TRUE);
 	if(bSuccess) {
 		// save the file to a memory stream
 		bSuccess = image.saveToMemory(FIF_PNG, memIO, PNG_DEFAULT);
diff --git a/Wrapper/VB6/awk_script/genbas.sh b/Wrapper/VB6/awk_script/genbas.sh
new file mode 100644
index 0000000..f50bb33
--- /dev/null
+++ b/Wrapper/VB6/awk_script/genbas.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+HDR=../../../Source/FreeImage.h
+BAS=../modFreeImage.bas
+DLL=FreeImage.dll
+
+echo Attribute VB_Name = \"FreeImage\" > $BAS
+echo Option Explicit >> $BAS
+
+echo >> $BAS
+gcc -E -P -dD $HDR | egrep '^#[ 	]*define[ 	]+[A-Z][0-9A-Z_]*[	 ]+([0-9]+|0x[0-9A-Fa-f]+|"[^"]*")' | awk '{sub(/0x/,"\\&H",$3);if($2!="TRUE"&&$2!="FALSE"&&$2!="NULL")printf("Const %s As %s = %s\n",$2,substr($3,1,1)=="\""?"String":"Long",$3);}' >> $BAS
+
+echo >> $BAS
+gcc -E -P $HDR | indent -kr | tr -s '\n' | awk '{if(e&&$0~"^}"){e=0;printf("End Enum\n");}if(e){printf("\t%s",$1);if($2=="="){sub(/,/,"",$3);printf(" = %s",$3);}printf("\n");}if($0~"^enum "){e=1;printf("Public Enum %s\n",$2);}}' >> $BAS
+
+echo >> $BAS
+gcc -E -P $HDR | indent -kr | tr -s '\n' | awk '{if(e&&$0~"^}"){e=0;if(n==""){n=$2;sub(/,|;/,"",n);}printf("Public Type %s\n%sEnd Type\n",n,s);}if(e){if(substr($2,1,1)=="*")$1=$1 " *";gsub(/;|\*/,"",$2);sub(/\[1\]/,"(0)",$2);if($1=="BYTE")$1="Byte";else if($1=="WORD")$1="Integer";else if($1=="double")$1="Double";else if($1!="BITMAPINFOHEADER"&&$1!="RGBQUAD") $1="Long";s=s "\t" $2 " As " $1 "\n";}if($0~"^struct "){e=1;n=$2;s="";}if($0~"^typedef struct [^ ]+ {"){e=1;n="";s=""}}' >> $BAS
+
+echo >> $BAS
+export DLL
+grep ^DLL_API $HDR | sed 's/DLL_API //;s/ *DLL_CALLCONV /,/;s/ FI_DEFAULT(\([^)]*\))/=\1/g;s/(/,/g;s/)/,/g' | awk -F"," -f genbasfuncs.awk >> $BAS
diff --git a/Wrapper/VB6/awk_script/genbasfuncs.awk b/Wrapper/VB6/awk_script/genbasfuncs.awk
new file mode 100644
index 0000000..876b68a
--- /dev/null
+++ b/Wrapper/VB6/awk_script/genbasfuncs.awk
@@ -0,0 +1,136 @@
+# this awk script helps create the vb6 declarations
+function splittypenamedefault(s,tnd,   i,t,n,d,a)
+{
+	i = index(s,"=");
+	if(i>0) {
+		d = substr(s,i+1);
+		s = substr(s,1,i-1);
+	} else {
+		d = "";
+	}
+	for(i=length(s);substr(s,i,1)~/[A-Za-z0-9_]/&&i>0;i--) { }
+	if(i>0) {
+		t = substr(s,1,i);
+		n = substr(s,i+1);
+		if(t~/\/\*.*\*\//) {
+			split(t,a,/\/\*/);
+			t = a[2];
+			split(t,a,/\*\//);
+			t = a[1];
+		}
+		if(substr(t,1,1)==" ") {
+			t = substr(t,2);
+		}
+		if(substr(t,length(t),1)==" ") {
+			t = substr(t,1,length(t)-1);
+		}
+	} else {
+		t = s;
+		n = "";
+	}
+	if(t=="...") {
+		n = "VarArgs()";
+	}
+	if(n=="type") {
+		n = n "_";
+	}
+	if(d=="FALSE"||d=="NULL") {
+		d = "0";
+	}
+	if(d=="TRUE") {
+		d = "1";
+	}
+	tnd[0] = t;
+	tnd[1] = n;
+	tnd[2] = d;
+}
+function vbpasstypesize(t,pts,   a)
+{
+	if(t=="void") {
+		t = "";
+	} else if(t=="char"||t=="unsigned char") {
+		t = "ByVal,Byte,4";
+	} else if(t=="char *"||t=="unsigned char *"||t=="const char *"||t=="const char*") {
+		t = "ByVal,String,4";
+	} else if(t=="WORD") {
+		t = "ByVal,Integer,4";
+	} else if(t=="int"||t=="unsigned"||t=="unsigned int"||t=="long"||t=="unsigned long") {
+		t = "ByVal,Long,4";
+	} else if(t=="void *"||t=="const void *"||t=="int *"||t=="unsigned int *"||t=="long *"||t=="unsigned long *") {
+		t = "ByRef,Long,4";
+	} else if(t=="float") {
+		t = "ByVal,Single,4";
+	} else if(t=="float *") {
+		t = "ByRef,Single,4";
+	} else if(t=="double") {
+		t = "ByVal,Double,8";
+	} else if(t=="double *") {
+		t = "ByRef,Double,4";
+	} else if(t=="wchar_t *") {
+		t = "ByVal,Long,4";
+	} else if(t=="BYTE") {
+		t = "ByVal,Byte,4";
+	} else if(t=="BOOL"||t=="DWORD") {
+		t = "ByVal,Long,4";
+	} else if(t=="BYTE *"||t=="DWORD *") {
+		t = "ByRef,Long,4";
+	} else if(t=="FREE_IMAGE_FORMAT"||t=="FREE_IMAGE_TYPE"||t=="FREE_IMAGE_COLOR_TYPE"||t=="FREE_IMAGE_QUANTIZE"||t=="FREE_IMAGE_DITHER"||t=="FREE_IMAGE_FILTER"||t=="FREE_IMAGE_COLOR_CHANNEL"||t=="FREE_IMAGE_MDMODEL"||t=="FREE_IMAGE_MDTYPE") {
+		t = "ByVal," t ",4";
+	} else if(t=="FIBITMAP *"||t=="FIMULTIBITMAP *"||t=="RGBQUAD *"||t=="BITMAPINFO *"||t=="BITMAPINFOHEADER *"||t=="FIICCPROFILE *"||t=="FreeImageIO *"||t=="fi_handle"||t=="FITAG *"||t=="FIMEMORY *"||t=="FIMETADATA *") {
+		t = "ByVal,Long,4";
+	} else if(t=="BYTE **"||t=="FITAG **") {
+		t = "ByRef,Long,4";
+	} else if(t=="FI_InitProc"||t=="FreeImage_OutputMessageFunction") {
+		t = "ByVal,Long,4";
+	} else if(t~/V:.*/) {
+		t = "ByVal," substr(t,3);
+	} else if(t~/R:.*/) {
+		t = "ByRef," substr(t,3);
+	} else if(t=="...") {
+		t = "ParamArray,Variant,0";
+	} else {
+		t = "UNKNOWN," t ",0";
+	}
+	split(t,a,/,/);
+	pts[0] = a[1];
+	pts[1] = a[2];
+	pts[2] = a[3];
+}
+{
+	printf("Public Declare ");
+	if($1=="void") {
+		printf("Sub");
+	} else {
+		printf("Function");
+	}
+	s = 0;
+	for(i=3; i<NF; i++) {
+		splittypenamedefault($(i),tnd);
+		vbpasstypesize(tnd[0],pts);
+		s += pts[2];
+	}
+	printf(" %s Lib \"%s\" Alias \"_%s@%d\" (",$2,ENVIRON["DLL"],$2,s);
+	for(i=3; i<NF; i++) {
+		splittypenamedefault($(i),tnd);
+		vbpasstypesize(tnd[0],pts);
+		if( pts[1] != "" ) {
+			if( tnd[2] != "" ) {
+				printf("Optional %s %s As %s = %s",pts[0],tnd[1],pts[1],tnd[2]);
+			} else {
+				printf("%s %s As %s",pts[0],tnd[1],pts[1]);
+			}
+		}
+		if( i != NF-1 ) {
+			printf(", ");
+		}
+	}
+	printf(")");
+	if($1!="void") {
+		vbpasstypesize($1,pts);
+		if( pts[1] == "String" ) {
+			pts[1] = "Long";
+		}
+		printf(" As %s",pts[1]);
+	}
+	printf("\n");
+}
diff --git a/Wrapper/VB6/awk_script/readme.txt b/Wrapper/VB6/awk_script/readme.txt
new file mode 100644
index 0000000..9494d0a
--- /dev/null
+++ b/Wrapper/VB6/awk_script/readme.txt
@@ -0,0 +1,14 @@
+This awk script is used to generate a VB6 module with all the VB6 declaration needed to call FreeImage functions. 
+
+How to use this script
+----------------------
+Under Linux / Unix, just execute the following commands : 
+
+chmod 755 genbas.sh
+./genbas.sh
+
+
+This will generate a file named modFreeImage.bas that you can include in your VB6 project in order to have access to all FreeImage functions.
+
+Ryan Rubley
+<ark42 at users.sourceforge.net>
diff --git a/Wrapper/VB6/mfreeimage/MFreeImage.bas b/Wrapper/VB6/mfreeimage/MFreeImage.bas
index 6ea0395..4fd3bd4 100644
--- a/Wrapper/VB6/mfreeimage/MFreeImage.bas
+++ b/Wrapper/VB6/mfreeimage/MFreeImage.bas
@@ -26,788 +26,17 @@ Attribute VB_Name = "MFreeImage"
 
 '// ==========================================================
 '// CVS
-'// $Revision: 2.17 $
-'// $Date: 2012/10/01 12:52:22 $
-'// $Id: MFreeImage.bas,v 2.17 2012/10/01 12:52:22 cklein05 Exp $
+'// $Revision: 2.23 $
+'// $Date: 2014/08/08 06:53:12 $
+'// $Id: MFreeImage.bas,v 2.23 2014/08/08 06:53:12 cklein05 Exp $
 '// ==========================================================
 
 
 Option Explicit
 
-'--------------------------------------------------------------------------------
-' General notes on implementation and design
-'--------------------------------------------------------------------------------
-
-' General:
-
-' Most of the pointer type parameters used in the FreeImage API are actually
-' declared as Long in VB. That is also true for return values. 'Out' parameters
-' are declared ByRef, so they can receive the provided address of the pointer.
-' 'In' parameters are declared ByVal since in VB the Long variable is not a
-' pointer type but contains the address of the pointer.
-
-
-' Functions returning a special type:
-
-' Some of the following external function declarations of the FreeImage 3 functions
-' are declared Private. Additionally the token 'Int' is appended to the VB function
-' name, what means 'Internal' to avoid naming confusion. All of these return a value
-' of a certain type that can't be used with a declared function in VB directly but
-' would need the function to be declared in a type library. Since this wrapper module
-' should not depend on a compile time type library, these functions require some extra
-' work to be done and also a VB wrapper function to make them look like the C/C++
-' function.
-
-
-' Functions returning Strings:
-
-' Some of the declared FreeImage functions are defined as 'const char *' in C/C++
-' and so actually return a string pointer. Without using a type library for declaring
-' these functions, in VB it is impossible to declare these functions to return a
-' VB String type. So each of these functions is wrapped by a VB implemented function
-' named correctly according to the FreeImage API, actually returning a 'real' VB String.
-
-
-' Functions returning Booleans:
-
-' A Boolean is a numeric 32 bit value in both C/C++ and VB. In C/C++ TRUE is defined
-' as 1 whereas in VB True is -1 (all bits set). When a function is declared as 'Boolean'
-' in VB, the return value (all 32 bits) of the called function is just used "as is" and
-' maybe assigned to a VB boolean variable. A Boolean in VB is 'False' when the numeric
-' value is NULL (0) and 'True' in any other case. So, at a first glance, everything
-' would be great since both numeric values -1 (VB True) and 1 (C/C++ TRUE) are actually
-' 'True' in VB.
-' But, if you have a VB variable (or a function returning a Boolean) with just some bits
-' set and use the VB 'Not' operator, the result is not what you would expect. In this
-' case, if bTest is True, (Not bTest) is also True. The 'Not' operator just toggles all
-' bits by XOR-ing the value with -1. So, the result is not so surprisingly any more:
-' The C/C++ TRUE value is 0...0001. When all bits are XORed with 1, the result is
-' 1...1110 what is also not NULL (0) so this is still 'True' in VB.
-' The resolution is to convert these return values into real VB Booleans in a wrapper
-' function, one for each declared FreeImage function. Therefore each C/C++ BOOL
-' function is declared Private as xxxInt(...). A Public Boolean wrapper function
-' xxx(...) returns a real Boolean with 'xxx = (xxxInt(...) = 1)'.
-
-
-' Extended and derived functions:
-
-' Some of the functions are additionally provided in an extended, call it a more VB
-' friendly version, named '...Ex'. For example look at the 'FreeImage_GetPaletteEx'
-' function. Most of them are dealing with arrays and so actually return a VB style
-' array of correct type.
-
-' The wrapper also includes some derived functions that should make life easier for
-' not only a VB programmer.
-
-' Better VB interoperability is given by offering conversion between DIBs and
-' VB Picture objects. See the FreeImage_CreateFromOlePicture and
-' FreeImage_GetOlePicture functions.
-
-' Both known VB functions LoadPicture() and SavePicture() are provided in extended
-' versions calles LoadPictureEx() and SavePictureEx() offering the FreeImage 3�s
-' image file types.
-
-' The FreeImage 3 error handling is provided in VB after calling the VB specific
-' function FreeImage_InitErrorHandler()
-
-
-' Enumerations:
-
-' All of the enumaration members are additionally 'declared' as constants in a
-' conditional compiler directive '#If...#Then' block that is actually unreachable.
-' For example see:
-'
-' Public Enum FREE_IMAGE_QUANTIZE
-'    FIQ_WUQUANT = 0           ' Xiaolin Wu color quantization algorithm
-'    FIQ_NNQUANT = 1           ' NeuQuant neural-net quantization algorithm by Anthony Dekker
-' End Enum
-' #If False Then
-'    Const FIQ_WUQUANT = 0
-'    Const FIQ_NNQUANT = 1
-' #End If
-'
-' Since this module is supposed to be used directly in VB projects rather than in
-' compiled form (mybe through an ActiveX-DLL), this is for tweaking some ugly VB
-' behaviour regarding enumerations. Enum members are automatically adjusted in case
-' by the VB IDE whenever you type these members in wrong case. Since these are also
-' constants now, they are no longer adjusted to wrong case but always corrected
-' according to the definition of the constant. As the expression '#If False Then'
-' actually never comes true, these constants are not really defined either when running
-' in the VB IDE nor in compiled form.
-
-
-'--------------------------------------------------------------------------------
-' ToDo and known issues (unordered and with no priority)
-'--------------------------------------------------------------------------------
-
-' ToDo: more inline documentation for mask image creation and icon functions
-'       needed
 
 '--------------------------------------------------------------------------------
-' Change Log
-'--------------------------------------------------------------------------------
-
-'* : fixed
-'- : removed
-'! : changed
-'+ : added
-'
-'October 1, 2012 - 2.17
-'- [Carsten Klein] removed temporary workaround for 16-bit standard type bitmaps introduced in version 2.15, which temporarily stored RGB masks directly after the BITMAPINFO structure, when creating a HBITMAP.
-'* [Carsten Klein] fixed a potential overflow bug in both pNormalizeRational and pNormalizeSRational: these now do nothing if any of numerator and denominator is either 1 or 0 (zero).
-'+ [Carsten Klein] added load flag JPEG_GREYSCALE as well as the enum constant FILO_JPEG_GREYSCALE.
-'! [Carsten Klein] changed constant FREEIMAGE_RELEASE_SERIAL to 4 to match current version 3.15.4
-'
-'! now FreeImage version 3.15.4
-'
-'
-'March 19, 2012 - 2.16
-'! [Carsten Klein] changed constant FREEIMAGE_RELEASE_SERIAL to 3 to match current version 3.15.3
-'
-'! now FreeImage version 3.15.3
-'
-'
-'March 12, 2012 - 2.15
-'+ [Carsten Klein] added function FreeImage_ConvertToUINT16.
-'+ [Carsten Klein] added function FreeImage_ConvertToRGB16.
-'+ [Carsten Klein] added function FreeImage_GetThumbnail.
-'+ [Carsten Klein] added function declaration FreeImage_SetThumbnailInt and a real VB Boolean returning function FreeImage_SetThumbnail.
-'+ [Carsten Klein] added RAW_HALFSIZE load flag as well as the enum constant FILO_RAW_HALFSIZE.
-'+ [Carsten Klein] added wrapper function FreeImage_GetPictureData, which returns a byte array suitable for assigning to an Office image control's PictureData property.
-'+ [Carsten Klein] added wrapper function FreeImage_CreateFromPictureData, which creates a FreeImage bitmap from a PictureData byte array.
-'+ [Carsten Klein] added new save flag JPEG_BASELINE (also added FISO_JPEG_BASELINE to enumeration FREE_IMAGE_SAVE_OPTIONS).
-'+ [Carsten Klein] added a workaround for providing valid BITMAPINFO structures for non 555 16-bpp images to Windows API functions like CreateDIBSection, CreateDIBBitmap, StretchDIBits or SetDIBitsToDevice.
-'! [Carsten Klein] changed constants FREEIMAGE_MINOR_VERSION and FREEIMAGE_RELEASE_SERIAL: set to 15 and 2 respectively to match current version 3.15.2
-'
-'! now FreeImage version 3.15.2
-'
-'March 13, 2011 - 2.14
-'* [Glenn Thorpe] fixed a typo error with the call to FreeImage_HasPixels inside FreeImage_CreateMask.
-'
-'August 11, 2010 - 2.13
-'+ [Carsten Klein] added PSD load flags PSD_CMYK and PSD_LAB as well as the enum constants FILO_PSD_CYMK and FILO_PSD_LAB.
-'+ [Carsten Klein] added TIFF_LOGLUV save flag as well as the enum constant FISO_TIFF_LOGLUV.
-'
-'July 5, 2010 - 2.12
-'+ [Carsten Klein] added support for the new EXIF_RAW metadata model by adding enum constant FIMD_EXIF_RAW.
-'+ [Carsten Klein] added the new FIF_LOAD_NOPIXELS flag as well as the enum constant FILO_LOAD_NOPIXELS.
-'+ [Carsten Klein] added function declaration FreeImage_HasPixelsInt and a real VB Boolean returning function FreeImage_HasPixels.
-'+ [Carsten Klein] added function declaration FreeImage_FIFSupportsNoPixelsInt and a real VB Boolean returning function FreeImage_FIFSupportsNoPixels.
-'
-'! now FreeImage version 3.14.1
-'
-'June 20, 2010 - 2.11
-'+ [Carsten Klein] added new save flag JPEG_OPTIMIZE (also added FISO_JPEG_OPTIMIZE to enumeration FREE_IMAGE_SAVE_OPTIONS).
-'
-'April 20, 2010 - 2.10
-'+ [Carsten Klein] added new save flag TARGA_SAVE_RLE (also added FISO_TARGA_SAVE_RLE to enumeration FREE_IMAGE_SAVE_OPTIONS).
-'! [Carsten Klein] changed constants FREEIMAGE_MINOR_VERSION and FREEIMAGE_RELEASE_SERIAL: set to 14 and 0 respectively to match current version 3.14.0
-'+ [Carsten Klein] added function FreeImage_ConvertToFloat.
-'+ [Carsten Klein] added function FreeImage_SaveMultiBitmapToMemory.
-'+ [Carsten Klein] added wrapper functions FreeImage_SaveMultiBitmapToMemoryEx and FreeImage_SaveMultiBitmapToMemoryEx2.
-'+ [Carsten Klein] added wrapper function FreeImage_OpenMultiBitmapEx, which only opens existing files, but has support for automatic image format detection.
-'+ [Carsten Klein] added wrapper function FreeImage_CreateMultiBitmapEx, which only creates new (empty) multi-page bitmaps with support for automatic image format detection.
-'* [Carsten Klein] fixed a bug in FreeImage_LoadEx: now uses the file specified for format detection rather than the filename extension.
-'+ [Carsten Klein] improved error messages in function FreeImage_LoadEx.
-'* [Carsten Klein] fixed a bug in FreeImage_AcquireMemoryEx: no more crashes when passing an uninitialized array.
-'+ [Carsten Klein] added thin wrapper functions, enabling proper handling of Boolean parameters:
-'+                 added wrapper function FreeImage_OpenMultiBitmap
-'+                 added wrapper function FreeImage_UnlockPage
-'+                 added wrapper function FreeImage_RotateEx
-'+                 added wrapper function FreeImage_MakeThumbnail
-'+                 added wrapper function FreeImage_GetAdjustColorsLookupTable
-'+                 added wrapper function FreeImage_ApplyColorMapping
-'+                 added wrapper function FreeImage_SwapColors
-'+                 added wrapper function FreeImage_SwapColorsByLong
-'+                 added wrapper function FreeImage_ApplyIndexMapping
-'+                 added wrapper function FreeImage_SetTransparent
-'+                 added wrapper function FreeImage_ConvertFromRawBits
-'+                 added wrapper function FreeImage_ConvertToRawBits
-'+                 added wrapper function FreeImage_ConvertToStandardType
-'+                 added wrapper function FreeImage_ConvertToType
-'! [Carsten Klein] changed the parameter names of most functions.
-'! [Carsten Klein] changed signature of functions FreeImage_ConvertFromRawBits and FreeImage_ConvertToRawBits: 'ByRef Bits As Long' is now 'ByVal BitsPtr As Long'.
-'+ [Carsten Klein] added wrapper functions FreeImage_ConvertFromRawBitsEx and FreeImage_ConvertToRawBitsEx.
-'* [Carsten Klein] fixed a bug in declaration of function FreeImage_TmoReinhard05Ex: parameters 'Adaption' and 'ColorCorrection' are now passed by value.
-'- [Carsten Klein] removed half-implemented function FreeImage_SetChannelEx.
-'+ [Carsten Klein] added wrapper function FreeImage_SetChannelIOP.
-'- [Carsten Klein] removed needless default values of optional parameters.
-'- [Carsten Klein] removed function declaration FreeImage_CompositeByLong: replaced by declaration FreeImage_Composite.
-'! [Carsten Klein] changed function declaration FreeImage_Composite: application back color is now passed as ByRef ... As Any and so takes both RGBQUAD and Long valus.
-'+ [Carsten Klein] added wrapper function FreeImage_UnloadEx, which additionally sets the ByRef-passed Bitmap handle to zero after unloading.
-'+ [Carsten Klein] added wrapper functions ConvertColor and ConvertOleColor to convert VB-style BGR colors into RGB color values.
-'
-'! now FreeImage version 3.14.0
-'
-'February 9, 2010 - 2.9.1
-'* [Carsten Klein] fixed a bug in FreeImage_GetBackgroundColorAsLong: parameter 'bkcolor' is now properly passed ByRef.
-'
-'February 9, 2010 - 2.9
-'* [Carsten Klein] fixed a syntax typo
-'
-'February 8, 2010 - 2.8
-'* [Mike Weir] fixed a bug in function FreeImage_ApplyColorMappingEx: now properly includes all specified mapping entries
-'* [Carsten Klein] fixed a bug in function FreeImage_ApplyIndexMappingEx: now properly includes all specified mapping entries
-'* [Mike Weir] fixed a bug in function FreeImage_RescaleEx: now also rescales the image, if either the new width or height matches the image's current size
-'* [WinAnd / Carsten Klein] fixed a bug in function FreeImage_GetTransparencyTableExClone: returns an uninitialized array if there is no transparency table
-'* [WinAnd / Carsten Klein] fixed a bug in function FreeImage_SearchPalette: no longer crashes if there is no transparency table
-'
-'December 21, 2009 - 2.7
-'! [Carsten Klein] changed constant FREEIMAGE_RELEASE_SERIAL: set to 1 to match current version 3.13.1
-'
-'! now FreeImage version 3.13.1
-'
-'December 18, 2009 - 2.6
-'- [Carsten Klein] removed usage of constants vbPicTypeBitmap and vbPicTypeIcon: these are not available in VBA environments like Excel, Access or Outlook.
-'
-'September 08, 2009 - 2.5
-'! [Carsten Klein] changed constant FREEIMAGE_MINOR_VERSION: set to 13 to match current version 3.13.0
-'+ [Carsten Klein] added load flag constant JPEG_EXIFROTATE and new member FILO_JPEG_EXIFROTATE to enumeration FREE_IMAGE_LOAD_OPTIONS.
-'+ [Carsten Klein] added support for the PFM image format.
-'+ [Carsten Klein] added support for the PICT and RAW image formats.
-'+ [Carsten Klein] added UNICODE functions FreeImage_JPEGTransformU and FreeImage_JPEGCropU.
-'+ [Carsten Klein] added enumeration FREE_IMAGE_COLOR_OPTIONS, which contains options to specify colors, used with FreeImage_FillBackground and FreeImage_EnlargeCanvas.
-'+ [Carsten Klein] added function FreeImage_FillBackground: although this returns BOOL in C/C++, the VB version only returns a Long.
-'+ [Carsten Klein] added wrapper functions FreeImage_FillBackgroundEx and FreeImage_FillBackgroundByLong, taking an RGBQUAD and a Long 'Color' argument respectively and return a true VB Boolean.
-'+ [Carsten Klein] added function FreeImage_EnlargeCanvas.
-'+ [Carsten Klein] added functions FreeImage_AllocateEx and FreeImage_AllocateExT.
-'+ [Carsten Klein] added function FreeImage_TmoReinhard05Ex.
-'+ [Carsten Klein] added function FreeImage_Rotate.
-'+ [Carsten Klein] added wrapper function FreeImage_RotateIOP.
-'
-'! now FreeImage version 3.13.0
-'
-'March 18, 2009 - 2.4.2
-'+ [Carsten Klein] added enumeration FREE_IMAGE_FRAME_DISPOSAL_METHODS, which provides the frame disposal options needed to create animated GIF files.
-'
-'July 29, 2008 - 2.4.1
-'* [Carsten Klein] minor documentation updates
-'! [Carsten Klein] renamed member FICF_PALETTISED_8BPP of enumeration FREE_IMAGE_CONVERSION_FLAGS into FICF_PALLETISED_8BPP.
-'
-'June 30, 2008 - 2.4
-'* [Carsten Klein] fixed some minor issues in FreeImage_PaintTransparent()
-'
-'June 06, 2008 - 2.3
-'+ [Carsten Klein] added new compression flags to the JPEG and PNG plugins
-'! [Carsten Klein] renamed wrapper function FreeImage_CloneMetadata() to FreeImage_CloneMetadataEx(): now, there is a native function called FreeImage_CloneMetadata().
-'+ [Carsten Klein] added private and internal function declaration for FreeImage_CloneMetadata() along with it's public Boolean returning wrapper function.
-'- [Carsten Klein] removed the FreeImage_ColorQuantizeEx() stuff from both functions FreeImage_ConvertColorDepth() and FreeImage_ConvertColorDepthIOP(): removed parameters PaletteSize, ReserveSize and ReservePalette.
-'- [Carsten Klein] changed declaration of FreeImage_ColorQuantizeEx() to be a internal function private to the wrapper with an 'Int' appendix.
-'+ [Carsten Klein] added two more VB-friendly public wrapper functions FreeImage_ColorQuantizeEx() and FreeImage_ColorQuantizeExIOP().
-'+ [Carsten Klein] added wrapper function FreeImage_GetPalettePtr(): gets the pointer to a specified array of RGBQUADs: intended to be used together with any of the ColorQuantizeEx functions.
-'! [Carsten Klein] changed constant FREEIMAGE_MINOR_VERSION: set to 11 to match current version 3.11.0
-'
-'! now FreeImage version 3.11.0
-'
-'December 14, 2007 - 2.2.1
-'+ [Carsten Klein] added constants for member 'biCompression' in BITMAPINFOHEADER struct
-'+ [Carsten Klein] added wrapper function FreeImage_GetInfoHeaderEx(), which returns a fully populated BITMAPINFOHEADER struct for a bitmap.
-'* [Carsten Klein] fixed a bug in FreeImage_GetFileTypeFromMemoryEx(): now calls FreeImage_CloseMemory() releasing the hStream to prevent memory leaks.
-'+ [Carsten Klein] added wrapper function FreeImage_GetColorizedPalette(): returns a colorized greyscale palettte.
-'+ [Carsten Klein] added wrapper function FreeImage_Colorize(): applies a colorized greyscale palettte obtained from FreeImage_GetColorizedPalette() to a bitmap.
-'+ [Carsten Klein] added wrapper function FreeImage_Sepia(): calls FreeImage_Colorize() with proper parameters to apply a so called sepia palette to a bitmap.
-'
-'December 12, 2007 - 2.2
-'* [Carsten Klein] fixed a small bug in FreeImage_PaintTransparent, which now calls function FreeImage_ConvertTo32Bits instead of FreeImage_ConvertTo32Bits2.
-'
-'November 15, 2007 - 2.1
-'* [Carsten Klein] adjusted page numbers of the API documentation in FreeImage function declarations to match FreeImage 3.10.0 API documentation
-'- [Carsten Klein] removed parameter 'UnloadSource' from function FreeImage_GetOlePictureIcon(): an hIcon should not be destroyed if OleCreatePictureIndirect() is called with fOwn = True.
-'! [Carsten Klein] refactored FreeImage_GetOlePicture(): now relies on FreeImage_GetBitmap().
-'
-'November 10, 2007 - 2.0.8
-'! [Carsten Klein] changed declaration of FreeImage_SetOutputMessage(): now points transparently to the __stdcall version of this function in the library.
-'+ [Carsten Klein] added function declaraton for FreeImage_MultigridPoissonSolver().
-'+ [Carsten Klein] added function declaraton for FreeImage_GetTransparentIndex() and FreeImage_SetTransparentIndex().
-'+ [Carsten Klein] added private and internal function declaration for FreeImage_AdjustColors() along with it's public Boolean returning wrapper function.
-'+ [Carsten Klein] added function declaraton for FreeImage_GetAdjustColorsLookupTable().
-'+ [Carsten Klein] added wrapper function FreeImage_GetAdjustColorsLookupTableEx(): this takes a real VB style Byte array ton receive the lookup table created.
-'+ [Carsten Klein] added function declaraton for FreeImage_ApplyColorMapping().
-'+ [Carsten Klein] added wrapper function FreeImage_ApplyColorMappingEx(): this takes a real VB style RGBQUAD array.
-'+ [Carsten Klein] added function declaratons for FreeImage_SwapColors() and FreeImage_SwapColorsByLong().
-'+ [Carsten Klein] added function declaraton for FreeImage_ApplyIndexMapping().
-'+ [Carsten Klein] added wrapper function FreeImage_ApplyIndexMappingEx(): this takes a real VB style Byte array.
-'+ [Carsten Klein] added function declaraton for FreeImage_SwapPaletteIndices().
-'
-'November 05, 2007 - 2.0.7
-'+ [Carsten Klein] added 4 bit color depth to both function pGetNextColorDepth() and pGetPrevousColorDepth()
-'- [Carsten Klein] removed member FICF_PREPARE_RESCALE from enumeration FREE_IMAGE_CONVERSION_FLAGS
-'- [Carsten Klein] removed all references to FICF_PREPARE_RESCALE: Converting color depth before rescaling an image is no longer performed by the wrapper. Since FreeImage now transparently converts color depth on rescaling, doing this in the wrapper is no longer needed.
-'! [Carsten Klein] refactored wrapper function FreeImage_ConvertColorDepth(): removed case FICF_PREPARE_RESCALE; is now more similar to C# wrapper's version of this function.
-'! [Carsten Klein] refactored wrapper function FreeImage_SaveEx(): removed case FICF_PREPARE_RESCALE; is now more similar to C# wrapper's version of this function.
-'
-'September 14, 2007 - 2.0.6
-'+ [Carsten Klein] added function declaration and Boolean wrapper function for FreeImage_PreMultiplyWithAlpha().
-'
-'July 26, 2007 - 2.0.5
-'+ [Carsten Klein] added wrapper function FreeImage_GetBitmap(): returns an HBITMAP created by the CreateDIBSection() function and so has the same color depth as the original DIB.
-'+ [Carsten Klein] added wrapper function FreeImage_GetBitmapForDevice(): returns an HBITMAP created by the CreateDIBitmap() function and so has the same color depth as the specified reference DC or as the desktop, if the 'hDC' parameter was omitted.
-'- [Carsten Klein] removed function declaration for GetWindowDC(): this function is no longer used.
-'* [Carsten Klein] fixed a bug in wrapper function FreeImage_IsExtensionValidForFIF(): string comparison now includes a comma.
-'* [Carsten Klein] fixed a bug in wrapper function FreeImage_IsFilenameValidForFIF(): string comparison now includes a comma.
-'
-'July 25, 2007 - 2.0.4
-'* [Carsten Klein] fixed a bug in function FreeImage_GetPaletteExClone(): now actually returns the palette as RGBQUAD array plus some other minor improvements
-'+ [Carsten Klein] added wrapper function FreeImage_GetPaletteExLongClone(): this function returns a VB style Byte array that is only wrapped around FreeImage's pointer to a DIB's transparency table.
-'+ [Carsten Klein] added wrapper function FreeImage_GetTransparencyTableEx(): this function returns a VB style Byte array that is only wrapped around FreeImage's pointer to a DIB's transparency table.
-'! [Carsten Klein] changed name of wrapper function FreeImage_GetTransparencyTableEx(): this function is now named FreeImage_GetTransparencyTableExClone(), since it actually returns a clone (deep copy) of an image's transparency table (compare with FreeImage_GetPaletteExClone()).
-'+ [Carsten Klein] added wrapper function FreeImage_SetPalette(): sets an image's palette through a VB style RGBQUAD array.
-'+ [Carsten Klein] added wrapper function FreeImage_SetPaletteLong(): sets an image's palette through a VB style Long array.
-'+ [Carsten Klein] added function declaration for CreateDIBsection()
-'+ [Carsten Klein] added function declaration for DeleteDC()
-'* [Carsten Klein] fixed a bug in wrapper function FreeImage_CreateFromScreen(): now the memory DC is deleted with the DeleteDC() function and no longer with the DeleteObject() function.
-'
-'July 05, 2007 - 2.0.3
-'+ [Carsten Klein] added wrapper function FreeImage_GetFileTypeFromMemoryEx(): more VB friendly version of FreeImage_GetFileTypeFromMemory() which may take an array rather than a FIMEMORY stream.
-'
-'May 21, 2007 - 2.0.2
-'! [Carsten Klein] changed constant FREEIMAGE_MINOR_VERSION: set to 10 to match current version 3.10.0
-'! [Carsten Klein] changed constant FREEIMAGE_RELEASE_SERIAL: set to 0 to match current version 3.10.0
-'+ [Carsten Klein] added image format constants FIF_EXR, FIF_J2K and FIF_JP2 to enumeration FREE_IMAGE_FORMAT.
-'+ [Carsten Klein] added tone mapping operator constant FITMO_FATTAL02 to enumeration FREE_IMAGE_TMO.
-'+ [Carsten Klein] added save option constants J2K_DEFAULT and JP2_DEFAULT for JPEG2000 format.
-'+ [Carsten Klein] added save option constants EXR_DEFAULT, EXR_FLOAT, EXR_NONE, EXR_ZIP, EXR_PIZ, EXR_PXR24, EXR_B44 and EXR_LC for EXR format.
-'+ [Carsten Klein] added save option constants for EXR format to enumeration FREE_IMAGE_SAVE_OPTIONS.
-'+ [Carsten Klein] added declared function FreeImage_TmoFattal02(): adds support for Gradient domain high dynamic range compression (R. Fattal, 2002)
-'
-'! now FreeImage version 3.10.0
-'
-'February 24, 2007 - 2.0.1
-'* [Carsten Klein] fixed a bug in function FreeImage_CreateFromScreen(): now size of image created is according to window to be captured if parameter 'hwnd' <> 0.
-'+ [Carsten Klein] added parameter 'bClientAreaOnly' to function FreeImage_CreateFromScreen().
-'+ [Carsten Klein] added blitting option 'CAPTUREBLT' when calling function BitBlt() in function FreeImage_CreateFromScreen().
-'- [Carsten Klein] removed unused variable 'hDIB' from functions FreeImage_CreateFromScreen() and FreeImage_LoadEx(). Thanks to Bruce Rusk for pointing that out.
-'
-'February 16, 2007 - 2.0
-'! [Carsten Klein] changed constant FREEIMAGE_RELEASE_SERIAL: set to 3 to match current version 3.9.3
-'! [Carsten Klein] changed JPEG load/save flag option values: changed constants and both enumerations FREE_IMAGE_SAVE_OPTIONS and FREE_IMAGE_SAVE_OPTIONS.
-'+ [Carsten Klein] added ICC Color Profile support:
-'!                 changed signature of declared function FreeImage_GetICCProfile(): is now declared 'Private' and suffixed with '...Int()'.
-'+                 added wrapper function FreeImage_GetICCProfile(): is the public wrapper function for private function FreeImage_GetICCProfileInt(), returing a real FIICCPROFILE structure.
-'+                 added constant FREE_IMAGE_ICC_COLOR_MODEL_MASK.
-'+                 added enumeration FREE_IMAGE_ICC_COLOR_MODEL.
-'+                 added wrapper function FreeImage_GetICCProfileColorModel(): returns the color profile's color model (FIICCPROFILE.flags member).
-'+                 added wrapper function FreeImage_GetICCProfileSize(): returns the color profile data's size in bytes.
-'+                 added wrapper function FreeImage_GetICCProfileDataPointer(): returns the pointer to the color profile data.
-'+                 added wrapper function FreeImage_HasICCProfile(): returns whether a color profile is available for a dib or not.
-'! [Carsten Klein] changed behaviour of wrapper function FreeImage_RescaleEx() and all it's derived functions: no clone is returned if the actual and desired image size are the same.
-'+ [Carsten Klein] added parameter 'bForceCloneCreation' to wrapper function FreeImage_RescaleEx() and all it's derived functions.
-'
-'! now FreeImage version 3.9.3
-'
-'January 09, 2007 - 1.9.4
-'! [Carsten Klein] changed scope of declared function FreeImage_GetFileTypeUInt(): is now private according to all other '...Int' functions wrapped by a VB-friendly function.
-'! [Carsten Klein] changed scope of declared function FreeImage_GetFIFFromFilenameUInt(): is now private according to all other '...Int' functions wrapped by a VB-friendly function.
-'! [Carsten Klein] changed signature of declared functions FreeImage_GetBackgroundColorInt() and FreeImage_SetBackgroundColorInt(): now both have a 'ByRef bkcolor As RGBQUAD' parameter instead of 'ByVal bkcolor As Long'.
-'+ [Carsten Klein] added declared functions FreeImage_GetBackgroundColorAsLongInt(): this has a 'ByRef bkcolor As Long' parameter and provides the background color as a Long value.
-'+ [Carsten Klein] added declared functions FreeImage_SetBackgroundColorAsLongInt(): this has a 'ByRef bkcolor As Long' parameter and takes the background color as a Long value.
-'! [Carsten Klein] changed signature of wrapper functions FreeImage_GetBackgroundColor() and FreeImage_SetBackgroundColor(): now both have a 'ByRef bkcolor As RGBQUAD' parameter instead of 'ByVal bkcolor As Long'.
-'+ [Carsten Klein] added wrapper functions FreeImage_GetBackgroundColorAsLong() and FreeImage_SetBackgroundColorAsLong(): both have a 'ByRef bkcolor As Long' parameter and so offer getting and setting the background color through a Long value.
-'+ [Carsten Klein] added wrapper functions FreeImage_GetBackgroundColorEx() and FreeImage_SetBackgroundColorEx(): both both take 4 ByRef Byte parameters 'Alpha', 'Red', 'Green' and 'Blue', one for each color component.
-'
-'January 05, 2007 - 1.9.3
-'+ [Carsten Klein] added wrapper function FreeImage_GetLockedPageNumbersEx(): this returns a real VB-style array of Longs containing the page numbers of all locked pages.
-'
-'January 02, 2007 - 1.9.2
-'* [Carsten Klein] fixed a bug in inline description of function FreeImage_GetPaletteEx(): now tells to use function FreeImage_DestroyLockedArrayRGBQUAD() to free an array returned by this function.
-'* [Carsten Klein] fixed some minor bugs in inline documentation.
-'* [Carsten Klein] fixed a serious bug in function FreeImage_SaveEx(): parameter 'UnloadSource' is now interpreted correctly under all circumstances.
-'* [Carsten Klein] fixed some minor issues in function FreeImage_SaveEx().
-'
-'December 29, 2006 - 1.9.1
-'+ [Carsten Klein] added enumeration item FID_BAYER16x16: now supports Bayer ordered dispersed dot dithering (order 4 dithering matrix).
-'
-'October 31, 2006 - 1.9
-'* [Carsten Klein] adjusted page numbers of the API documentation in header comments in FreeImage function declarations to match FreeImage 3.9.2 API documentation
-'! [Carsten Klein] changed constant FREEIMAGE_RELEASE_SERIAL: set to 2 to match current version 3.9.2
-'+ [Carsten Klein] added function declaration for FreeImage_JPEGCrop(): added both declaration and Boolean returning wrapper function.
-'! [Carsten Klein] changed data type of all occurences of parameter 'Flags' from Long to either FREE_IMAGE_LOAD_OPTIONS or FREE_IMAGE_SAVE_OPTIONS enum. This is true for declared functions as well as for wrapper functions.
-'+ [Carsten Klein] added function declaration for FreeImage_LoadMultiBitmapFromMemory().
-'+ [Carsten Klein] added wrapper function FreeImage_LoadMultiBitmapFromMemoryEx(): this is dealing with a VB style array (SAFEARRAY) like FreeImage_LoadFromMemoryEx() does.
-'
-'! now FreeImage version 3.9.2
-'
-'October 30, 2006 - 1.8
-'* [Carsten Klein] fixed a memory leak in wrapper function SavePictureEx(). Thanks to Roogames for reporting that bug.
-'! [Carsten Klein] changed return type of wrapper function SavePictureEx() to Boolean.
-'+ [Carsten Klein] added wrapper function FreeImage_SaveEx() which brings all the features, as there are inline size- and color conversion and format guessing, so far only known from SavePictureEx() for DIBs.
-'! [Carsten Klein] changed wrapper function SavePictureEx(): now this is only a thin wrapper for function FreeImage_SaveEx().
-'+ [Carsten Klein] added enumeration FREE_IMAGE_LOAD_OPTIONS.
-'- [Carsten Klein] refactored enumeration FREE_IMAGE_SAVE_OPTIONS: removed unnecessary items from enumeration.
-'! [Carsten Klein] changed wrapper function LoadPictureEx(): added parameter 'Options' (enum FREE_IMAGE_LOAD_OPTIONS) to specify image loading options (called 'flags' in FreeImage).
-'+ [Carsten Klein] added wrapper function FreeImage_LoadEx() which brings all the features, as there are inline size- and color conversion and format guessing, so far only known from LoadPictureEx() for DIBs.
-'! [Carsten Klein] changed wrapper function LoadPictureEx(): now this is only a thin wrapper for function FreeImage_LoadEx().
-'
-'October 13, 2006 - 1.7.2
-'+ [Carsten Klein] added User32 function GetDesktopWindow()
-'+                 added User32 function GetWindowDC()
-'- [Carsten Klein] removed unused constants DI_MASK, DI_IMAGE and DI_NORMAL
-'+                 added GDI32 function GetDeviceCaps() with constants HORZRES and VERTRES
-'+                 added GDI32 function SelectObject()
-'+                 added GDI32 function DeleteObject()
-'+                 added GDI32 function CreateCompatibleBitmap()
-'+                 added GDI32 function CreateCompatibleDC()
-'+                 added GDI32 function BitBlt()
-'+ [Carsten Klein] added wrapper function FreeImage_CreateFromScreen(): this function lets you capture the whole screen or any certain window
-'
-'October 10, 2006 - 1.7.1
-'! [Carsten Klein] changed parameter name 'Page' into 'hPageDib' in declared function FreeImage_UnlockPage(). 'hPageDib' must be the (dib-)handle obtained from FreeImage_LockPage() and not the page number. Now, the declaration is less confusing. Thanks to Ender Wiggin.
-'
-'August 4, 2006 - 1.7
-'* [Carsten Klein] fixed a bug in pGetTagFromTagPtr(): removed overflow error when converting unsigned short tags (FIDT_SHORT) with values between 32768 and 65535. Thanks to Andr� Hendriks.
-'! [Carsten Klein] changed constant FREEIMAGE_RELEASE_SERIAL: set to 1 to match current version 3.9.1
-'
-'! now FreeImage version 3.9.1
-'
-'July 17, 2006 - 1.6
-'+ [Carsten Klein] added more public wrapper functions for tag copying and cloning:
-'+                 added function FreeImage_CopyMetadata()
-'+                 added function FreeImage_CloneMetadata()
-'- [Carsten Klein] removed dead API functions, dead structures and dead variables
-'* [Carsten Klein] fixed a bug in FreeImage_ConvertColorDepth(): now color images are converted to 24 bits when used with FICF_PREPARE_RESCALE, all others to 8 bit
-'
-'July 16, 2006 - 1.5.6
-'+ [Carsten Klein] added more public wrapper functions for VB friendly tag access: these functions deal with a FREE_IMAGE_TAG structure instead of FreeImage's Tag pointer.
-'+                 added function FreeImage_SetMetadataEx()
-'+                 added function FreeImage_CreateTagEx()
-'+                 added function FreeImage_AppendTag()
-'+                 added function FreeImage_RemoveTag()
-'+                 added function FreeImage_RemoveTagEx()
-'+                 added function FreeImage_TagExists()
-'+                 added function FreeImage_TagExistsEx()
-'+                 added function FreeImage_DeleteTagEx()
-'+                 added function FreeImage_CloneTagEx()
-'+                 added function FreeImage_RemoveMetadataModel()
-'+                 added function FreeImage_UpdateMetadata()
-'+                 added function FreeImage_UnsignedLong()
-'+                 added function FreeImage_UnsignedShort()
-'+                 added function FreeImage_CreateRational()
-'+                 added function FreeImage_CreateSignedRational()
-'+                 added function FreeImage_GetImageComment()
-'+                 added function FreeImage_SetImageComment()
-'+ [Carsten Klein] added some private helper functions to leverage tag updating:
-'+                 added helper function pTagToTagPtr()
-'+                 added helper function pGetValueBuffer()
-'+                 added helper function pGetRationalValueBuffer()
-'+                 added helper function pGetVariantAsByteBuffer()
-'+                 added helper function pGetElementSize()
-'
-'July 5, 2006 - 1.5.5
-'! [Carsten Klein] changed function signature of FreeImage_FindNextMetadataEx(): optional parameter 'Model' is now present; see the function's inline documentation
-'
-'June 30, 2006 - 1.5.4
-'* [Carsten Klein] fixed bug in functions creating a FreeImage DIB from a windows hBitmap: workaround for palletized bitmaps is now implemented
-'*                 fixed function FreeImage_CreateFromOLEPicture()
-'*                 fixed function FreeImage_CreateFromDC()
-'
-'June 22, 2006 - 1.5.3
-'! [Carsten Klein] changed function declaration of FreeImage_GetMetadataInt(): parameter 'model' is now 'ByVal' and Tag is a Long pointer
-'! [Carsten Klein] changed function declaration of FreeImage_SetMetadataInt(): parameter 'model' is now 'ByVal' and Tag is a Long pointer
-'! [Carsten Klein] changed function declaration of FreeImage_GetMetadata(): parameter Tag is a Long pointer now
-'! [Carsten Klein] changed function declaration of FreeImage_SetMetadata(): parameter Tag is a Long pointer now
-'+ [Carsten Klein] added function declarations for tag creation and destruction:
-'+                 added declaration for function FreeImage_CreateTag()
-'+                 added declaration for procedure FreeImage_DeleteTag()
-'+                 added declaration for function FreeImage_CloneTag()
-'+ [Carsten Klein] added new items to structure FREE_IMAGE_TAG:
-'+                 added item 'Model As FREE_IMAGE_MDMODEL'
-'+                 added item 'TagPtr As Long'
-'+ [Carsten Klein] added wrapper functions for more VB friendly Tag access: these functions deal with a FREE_IMAGE_TAG structure instead of FreeImage's Tag pointer.
-'+                 added function FreeImage_FindFirstMetadataEx()
-'+                 added function FreeImage_FindNextMetadataEx()
-'+                 added function FreeImage_GetAllMetadataTags()
-'+                 added function FreeImage_GetMetadataEx()
-'* [Carsten Klein] fixed and adjusted page numbers of the API documentation in header comments in FreeImage function declarations
-'- [Carsten Klein] removed workaround for thresholding and dithering non-MINISBLACK 8 bit images in function FreeImage_ConvertColorDepth(): was fixed in FreeImage 3.9.0
-'* [Carsten Klein] fixed all pending issues in function FreeImage_PaintDC(): is now in production state
-'
-'June 14, 2006 - 1.5.2
-'! [Carsten Klein] changed signature of function FreeImage_CreateMask()
-'+ [Carsten Klein] added function FreeImage_CreateMaskImage(): this creates a monochrome mask from a source image
-'+ [Carsten Klein] added function FreeImage_CreateMaskInPlace(): this creates a monochrome mask from a source image
-'+ [Carsten Klein] added enumeration FREE_IMAGE_ICON_TRANSPARENCY_OPTION_FLAGS
-'+ [Carsten Klein] added wrapper function FreeImage_CreateSimpleBWMaskImage(): wrapper for FreeImage_CreateMaskImage() with reduced number of parameters; creates a b/w mask
-'+ [Carsten Klein] added wrapper function FreeImage_CreateSimpleBWMaskInPlace(): wrapper for FreeImage_CreateMaskInPlace() with reduced number of parameters; creates a b/w mask
-'+ [Carsten Klein] added function declaration for FreeImage_MakeThumbnail()
-'+ [Carsten Klein] added function for FreeImage_GetOlePictureThumbnail()
-'+ [Carsten Klein] added function for FreeImage_MakeThumbnailIOP()
-'+ [Carsten Klein] documented function FreeImage_ReadMemoryEx()
-'+ [Carsten Klein] documented function FreeImage_WriteMemoryEx()
-'! [Carsten Klein] divided FreeImage_TagFromPointer into an interface only function with a private helper function pGetTagFromTagPtr():
-'+                 added helper function pGetTagFromTagPtr()
-'! [Carsten Klein] added private helper functions to leverage the FIDT_RATIONAL and FIDT_SRATIONAL data type:
-'+                 added helper function pNormalizeRational()
-'+                 added helper function pNormalizeSRational()
-'+                 added helper function gcd()
-'+                 added helper function floor()
-'! [Carsten Klein] changed name of structure 'FITAG_int' to 'FITAG': is now as in FreeImage library
-'! [Carsten Klein] changed name of structure 'FITAG' to 'FREE_IMAGE_TAG': this new structure plays an important role in the wrapper's new VB friendly tag accessing concept
-'! [Carsten Klein] changed function declaration of FreeImage_GetMetadataCount(): parameter 'model' is now 'ByVal'
-'! [Carsten Klein] changed function declaration of FreeImage_TagToString(): parameter 'model' is now 'ByVal' and function returns a Long
-'! [Carsten Klein] renamed function declaration of FreeImage_TagToString() to FreeImage_TagToStringInt(): function is now Private and wrapped by a VB String returning function
-'+ [Carsten Klein] added wrapper function FreeImage_TagToString() returning a real VB String
-'+ [Carsten Klein] added structure FIRATIONAL: structure to hold an image tag's rational value
-'+ [Carsten Klein] added new items to structure FREE_IMAGE_TAG:
-'+                 added item 'StringValue As String'
-'+                 added item 'Palette() As RGBQUAD'
-'+                 added item 'RationalValue() As FIRATIONAL'
-'
-'June 13, 2006 - 1.5.1
-'! [Carsten Klein] changed version constant 'FREEIMAGE_MINOR_VERSION' to 9 to meet version 3.9.0
-'* [Carsten Klein] fixed and adjusted page numbers of the API documentation in header comments in FreeImage function declarations to match FreeImage 3.9.0 API documentation
-'+ [Carsten Klein] added function declaration for new Memory I/O functions in 3.9.0
-'+                 added declaration FreeImage_ReadMemory()
-'+                 added declaration FreeImage_WriteMemory()
-'! [Carsten Klein] changed/added optional parameter 'element_size' to private function pGetMemoryBlockPtrFromVariant(): caller now can get size in bytes one array element
-'+ [Carsten Klein] added wrapper functions for new Memory I/O functions in 3.9.0
-'+                 added function FreeImage_ReadMemoryEx()
-'+                 added function FreeImage_WriteMemoryEx()
-'+ [Carsten Klein] added constants and updated enumerations for new 3.9.0 file formats 'FAXG3' and 'SGI'
-'+ [Carsten Klein] added Windows GDI icon related declarations:
-'+                 added function declaration for CreateIconIndirect()
-'+                 added function declaration for DestroyIcon()
-'+                 added structure ICONINFO
-'+ [Carsten Klein] added function FreeImage_GetIcon(): returns a hIcon handle
-'+ [Carsten Klein] added function FreeImage_GetOlePictureIcon(): returns a VB Picture object of type vbPicTypeIcon
-'+ [Carsten Klein] added enumeration FREE_IMAGE_MASK_FLAGS
-'+ [Carsten Klein] added function FreeImage_CreateMaskColors(): returns an array filled with items from an argument list; synonym for VB's Array() function
-'+ [Carsten Klein] added enumeration FREE_IMAGE_teMask(): this creates a monochrome mask from a source image
-'+ [Carsten Klein] added function FreeImage_CreaMASK_CREATION_OPTION_FLAGS
-'
-'! now FreeImage version 3.9.0
-'
-'June 12, 2006 - 1.5
-'* [Carsten Klein] fixed bug in wrapper function FreeImage_PaintDCEx(): now handles boolean test correctly: 'If ((hDC <> 0) And (hDIB <> 0)) Then -> Thanks to ender_wiggin for reporting that bug.
-'+ [Carsten Klein] added private function pGetIOlePictureFromContainer(): used to get IPicture from image hosting control (Form, PictureBox) including custom drawings
-'+ [Carsten Klein] added wrapper function FreeImage_CreateFromImageContainer(): used to create FreeImage DIB from image hosting control (Form, PictureBox) including custom drawings
-'+ [Carsten Klein] added wrapper function SaveImageContainerEx(): derivate of wrapper function 'SavePictureEx()': saves content of image hosting control (Form, PictureBox) including custom drawings
-'
-'February 27, 2006 - 1.4.8
-'+ [Carsten Klein] added inline documentation for these wrapper functions:
-'+                 documented function FreeImage_CompareColorsLongLong()
-'+                 documented function FreeImage_CompareColorsRGBTRIPLELong()
-'+                 documented function FreeImage_CompareColorsRGBQUADLong()
-'+                 documented function FreeImage_SearchPalette()
-'! [Carsten Klein] changed and updated general remarks in section "General notes on implementation and design"
-'! [Carsten Klein] changed all function declarations of FreeImage functions that return a BOOL in C/C++: see "Functions returning Booleans" in section "General notes on implementation and design"
-'! [Carsten Klein] changed all function signatures of functions that are derived from or extend FreeImage BOOL functions: see "Functions returning Booleans" in section "General notes on implementation and design"
-'+ [Carsten Klein] added wrapper functions for all FreeImage functions that return a BOOL in C/C++: see "Functions returning Booleans" in section "General notes on implementation and design"
-'+ [Carsten Klein] added wrapper function FreeImage_CreateFromDC(): creates an DIB from a DC. Thanks to Evan (wxforecaster) for this suggestion.
-'+ [Carsten Klein] added declaration of GDI function GetCurrentObject() and constant OBJ_BITMAP
-'+ [Carsten Klein] added wrapper function FreeImage_IsAvailable(): used to test for existence of FreeImage Library (FreeImage.dll)
-'
-'February 9, 2006 - 1.4.7
-'+ [Carsten Klein] added private helper function pGetPreviousColorDepth()
-'+ [Carsten Klein] added private helper function pGetNextColorDepth()
-'! [Carsten Klein] changed/extended signature of wrapper function SavePictureEx(): now includes a parameter 'ColorDepth'
-'+ [Carsten Klein] added enumeration FREE_IMAGE_COLOR_DEPTH
-'+ [Carsten Klein] added error handling capabilities to wrapper function SavePictureEx()
-'+ [Carsten Klein] added/updated inline documentation of wrapper function SavePictureEx()
-'
-'October 31, 2005 - 1.4.6
-'+ [Carsten Klein] added wrapper function FreeImage_SwapColorLong(): this converts from a RGB to a BGR color value stored in a Long and vice versa
-'
-'October 27, 2005 - 1.4.5
-'+ [Carsten Klein] added function FreeImage_IsTransparencyTableTransparent(): checks for transparency directly on the transparency table
-'
-'October 13, 2005 - 1.4.4
-'+ [Carsten Klein] added some functions to compare colors in different formats and with tolerance:
-'+                 added function FreeImage_CompareColorsLongLong()
-'+                 added function FreeImage_CompareColorsRGBTRIPLELong()
-'+                 added function FreeImage_CompareColorsRGBQUADLong()
-'+ [Carsten Klein] added enumeration FREE_IMAGE_COLOR_FORMAT_FLAGS
-'+ [Carsten Klein] added enumeration FREE_IMAGE_TRANSPARENCY_STATE_FLAGS
-'+ [Carsten Klein] added function FreeImage_SearchPalette(): to search the palette index for a given color
-'
-'October 13, 2005 - 1.4.3
-'+ [Carsten Klein] added additional function declaration FreeImage_SetPixelColorByLong(): now color values may be provided in a long value
-'+ [Carsten Klein] added additional function declaration FreeImage_GetPixelColorByLong(): now color values may be received in a long value
-'+ [Carsten Klein] added function FreeImage_SetPixelColorEx(): color values may be provided by four different byte values
-'+ [Carsten Klein] added function FreeImage_GetPixelColorEx(): color values are returned through four different byte values
-'
-'October 11, 2005 - 1.4.2
-'* [Carsten Klein] fixed bug in wrapper function FreeImage_GetBitsExRGBQUAD(): now tests for and works with 32 bit images
-'
-'October 10, 2005 - 1.4.1
-'* [Carsten Klein] fixed serious bug in FreeImage_GetBitsEx...() functions: created custom array descriptor now really has two dimensions
-'*                 fixed wrapper function FreeImage_GetBitsEx()
-'*                 fixed wrapper function FreeImage_GetBitsExRGBTRIPLE()
-'*                 fixed wrapper function FreeImage_GetBitsExRGBQUAD()
-'
-'September 9, 2005 - 1.4
-'! [Carsten Klein] changed wrapper function FreeImage_ConvertColorDepth(): now uses FreeImage_ConvertToGreyscale
-'+ [Carsten Klein] added version numbers to change log
-'+ [Carsten Klein] added comments to IOlePicture aware toolkit and conversion functions
-'* [Carsten Klein] fixed and adjusted page numbers of the API documentation in header comments in FreeImage function declarations
-'
-'! now FreeImage version 3.8.0
-'
-'September 8, 2005 - 1.3.5
-'! [Carsten Klein] changed version constant 'FREEIMAGE_MINOR_VERSION' to 8 to meet version 3.8.0
-'+ [Carsten Klein] added function declarations for UNICODE dealing functions with additional token 'Int' appended:
-'+                 added function FreeImage_LoadUInt()
-'+                 added function FreeImage_SaveUInt()
-'+                 added function FreeImage_GetFileTypeUInt()
-'+                 added function FreeImage_GetFIFFromFilenameUInt()
-'+ [Carsten Klein] added wrapper functions to ease the use of UNICODE dealing functions:
-'+                 added function FreeImage_LoadU()
-'+                 added function FreeImage_SaveU()
-'+                 added function FreeImage_GetFileTypeU()
-'+                 added function FreeImage_GetFIFFromFilenameU()
-'+ [Carsten Klein] added function declaration for FreeImage_ConvertToGreyscale()
-'
-'July 18, 2005 - 1.3.4
-'! [Carsten Klein] changed inline comments in these wrapper functions:
-'!                 changed FreeImage_GetBitsEx(): mixed up width and height in SAFEAARAY creation
-'!                 changed FreeImage_GetBitsExRGBTRIPLE(): mixed up width and height in SAFEAARAY creation
-'!                 changed FreeImage_GetBitsExRGBQUAD(): mixed up width and height in SAFEAARAY creation
-'+ [Carsten Klein] added wrapper function FreeImage_GetScanLinesRGBTRIPLE():
-'
-'June 30, 2005 - 1.3.3
-'+ [Carsten Klein] added Kernel32 function FillMemory()
-'
-'June 24, 2005 - 1.3.2
-'+ [Carsten Klein] added pixel access functions FreeImage_GetBitsExRGBTRIPLE() and FreeImage_GetBitsExRGBQUAD()
-'+ [Carsten Klein] added IOlePicture based wrapper function FreeImage_ConvertColorDepthIOP()
-'+ [Carsten Klein] added IOlePicture based wrapper functions for FreeImage_RescaleIOP():
-'+                 added function FreeImage_FreeImage_RescaleByPixelIOP()
-'+                 added function FreeImage_FreeImage_RescaleByPercentIOP()
-'+                 added function FreeImage_FreeImage_RescaleByFactorIOP()
-'+ [Carsten Klein] added IOlePicture based wrapper function FreeImage_RescaleIOP()
-'* [Carsten Klein] fixed a bug in FreeImage_GetOlePicture(): now OlePictures returned through IPicture may be used directly by other functions accepting IPicture types without any assignment to IPictureDisp
-'
-'June 24, 2005 - 1.3.1
-'! [Carsten Klein] changed improper function declaration of function FreeImage_AdjustCurve(): now parameter 'LUT' is passed ByVal
-'+ [Carsten Klein] added wrapper function FreeImage_AdjustCurveEx()
-'+ [Carsten Klein] added IOlePicture based wrapper functions for FreeImage toolkit functions:
-'+                 added function FreeImage_RotateClassicIOP()
-'+                 added function FreeImage_RotateExIOP()
-'+                 added function FreeImage_FlipHorizontalIOP()
-'+                 added function FreeImage_FlipVerticalIOP()
-'+                 added function FreeImage_AdjustCurveIOP()
-'+                 added function FreeImage_AdjustGammaIOP()
-'+                 added function FreeImage_AdjustBrightnessIOP()
-'+                 added function FreeImage_AdjustContrastIOP()
-'+                 added function FreeImage_InvertIOP()
-'+                 added function FreeImage_GetChannelIOP()
-'+                 added function FreeImage_CopyIOP()
-'+                 added function FreeImage_PasteIOP()
-'
-'June 22, 2005 - 1.3
-'+ [Carsten Klein] added inline comments and documentation for pixel access functions
-'
-'June 18, 2005 - 1.2.9
-'+ [Carsten Klein] added function FreeImage_GetBitsEx()
-'+ [Carsten Klein] added structure SAFEARRAY2D to create 2 dimensional custom arrays
-'+ [Carsten Klein] added function declarations for converting scanlines to 4 bpp:
-'+                 added declaration for FreeImage_ConvertLine1To4()
-'+                 added declaration for FreeImage_ConvertLine8To4()
-'+                 added declaration for FreeImage_ConvertLine16To4_555()
-'+                 added declaration for FreeImage_ConvertLine16To4_565()
-'+                 added declaration for FreeImage_ConvertLine24To4()
-'+                 added declaration for FreeImage_ConvertLine32To4()
-'
-'June 16, 2005 - 1.2.8
-'! [Carsten Klein] changed improper function declaration for all functions FreeImage_ConvertLineXXXX(): now parameters 'target' and 'Source' are passed ByVal
-'
-'June 15, 2005 - 1.2.7
-'+ [Carsten Klein] added function FreeImage_DestroyLockedArrayByPtr() to destroy a locked array by it's pointer (VB can't pass a array of structures through a Variant type)
-'+ [Carsten Klein] added some wrapper functions for FreeImage_DestroyLockedArrayByPtr() for common FreeImage structures:
-'+                 added function FreeImage_DestroyLockedArrayRGBTRIPLE()
-'+                 added function FreeImage_DestroyLockedArrayRGBQUAD()
-'+                 added function FreeImage_DestroyLockedArrayFICOMPLEX()
-'+                 added function FreeImage_DestroyLockedArrayFIRGB16()
-'+                 added function FreeImage_DestroyLockedArrayFIRGBA16()
-'+                 added function FreeImage_DestroyLockedArrayFIRGBF()
-'+                 added function FreeImage_DestroyLockedArrayFIRGBAF()
-'+ [Carsten Klein] added functions to return scanlines as VB style arrays in all supported FreeImage formats:
-'+                 added function FreeImage_GetScanLineBITMAP8()
-'+                 added function FreeImage_GetScanLineBITMAP16()
-'+                 added function FreeImage_GetScanLineBITMAP24()
-'+                 added function FreeImage_GetScanLineBITMAP32()
-'+                 added function FreeImage_GetScanLineINT16()
-'+                 added function FreeImage_GetScanLineINT32()
-'+                 added function FreeImage_GetScanLineFLOAT()
-'+                 added function FreeImage_GetScanLineDOUBLE()
-'+                 added function FreeImage_GetScanLineCOMPLEX()
-'+                 added function FreeImage_GetScanLineRGB16()
-'+                 added function FreeImage_GetScanLineRGBA16()
-'+                 added function FreeImage_GetScanLineRGBF()
-'+                 added function FreeImage_GetScanLineRGBAF()
-'
-'June 14, 2005 - 1.2.6
-'! [Carsten Klein] updated documentation on array-dealing functions using arrays with custom array descriptors
-'+ [Carsten Klein] added function FreeImage_DestroyLockedArray() to destroy a self created array 'FADF_AUTO Or FADF_FIXEDSIZE' array
-'+ [Carsten Klein] added function FreeImage_GetPaletteExLong() to return palette data in an array of type Long
-'+ [Carsten Klein] added parameters 'lPaletteSize', 'vntReservePalette' and 'lReserveSize' to FreeImage_ConvertColorDepth()
-'
-'June 13, 2005 - 1.2.5
-'* [Carsten Klein] fixed a bug in helper function pGetMemoryBlockPtrFromVariant(): now 'size_in_bytes' will never exceed the size of an array provided
-'
-'June 12, 2005 - 1.2.4
-'+ [Carsten Klein] added ZLib compression function wrappers dealing with VB style arrays:
-'+                 added function FreeImage_ZLibCompressVB()
-'+                 added function FreeImage_ZLibUncompressVB()
-'+                 added function FreeImage_ZLibGZipVB()
-'+                 added function FreeImage_ZLibGUnzipVB()
-'
-'June 10, 2005 - 1.2.3
-'+ [Carsten Klein] added ZLib compression function wrappers dealing with VB style arrays:
-'+                 added function FreeImage_ZLibCompressEx()
-'+                 added function FreeImage_ZLibUncompressEx()
-'+                 added function FreeImage_ZLibGZipEx()
-'+                 added function FreeImage_ZLibCRC32Ex()
-'+                 added function FreeImage_ZLibGUnzipEx()
-'+ [Carsten Klein] added more VB friendly ZLib compression function wrappers:
-'+                 added function FreeImage_ZLibCompressVB()
-'+                 added function FreeImage_ZLibUncompressVB()
-'+                 added function FreeImage_ZLibGZipVB()
-'+                 added function FreeImage_ZLibGUnzipVB()
-'! [Carsten Klein] fixed wrong function declaration of functions FreeImage_ZLibGUnzip(): alias was '_FreeImage_ZLibZlibGUnzip at 16' (double ZLib)
-'! [Carsten Klein] fixed function pGetArrayPtrFromVariantArray() that now can deal with uninitialized arrays
-'!                 fixed function pGetMemoryBlockPtrFromVariant() that now can deal with uninitialized arrays
-'! [Carsten Klein] fixed wrong function declaration of functions FreeImage_AdjustBrightness(): ... at 8 -> ... at 12
-'!                 fixed wrong function declaration of functions FreeImage_AdjustContrast(): ... at 8 -> ... at 12
-'!                 fixed wrong function declaration of functions FreeImage_AdjustGamma(): ... at 8 -> ... at 12
-'!                 fixed wrong function declaration of functions FreeImage_RotateClassic(): ... at 8 -> ... at 12
-'!                 fixed wrong function declaration of functions FreeImage_RotateEx(): ... at 28 -> ... at 48
-'
-'June 9, 2005 - 1.2.2
-'! [Carsten Klein] fixed wrong function declaration of function FreeImage_OpenMultiBitmap(): added parameter 'flags' (... at 20 -> ... at 24)
-'
-'June 8, 2005 - 1.2.1
-'! [Carsten Klein] refactored function FreeImage_LoadFromMemoryEx(): now using pGetMemoryBlockPtrFromVariant()
-'+ [Carsten Klein] added private function pGetMemoryBlockPtrFromVariant() to get poiner and size of a memory block from a Variant parameter
-'! [Carsten Klein] changed declaration of ZLib related functions: 'target' and 'Source' are now 'ByVal Long'
-'
-'June 7, 2005 - 1.2
-'+ [Carsten Klein] added some more inline comments and documentation
-'+ [Carsten Klein] added optional parameter 'UnloadSource' to function FreeImage_SaveToMemoryEx()
-'+                 added optional parameter 'UnloadSource' to function FreeImage_SaveToMemoryEx2()
-'+ [Carsten Klein] added optional parameter 'InPercent' to function SavePictureEx()
-'!                 implemented the capability to resize the image on saving in function SavePictureEx()
-'+ [Carsten Klein] added parameters 'InPercent' and 'Format' to function LoadPictureEx()
-'* [Carsten Klein] fixed wrong function declaration of function FreeImage_JPEGTransform() (... at 12 -> ... at 16)
-'
-'June 6, 2005 - 1.1.2
-'+ [Carsten Klein] added some more inline comments and documentation
-'
-'May 30, 2005 - 1.1.1
-'* [Carsten Klein] fixed percent calculating bug in function FreeImage_RescaleEx()
-'!                 changed behaviour of parameter 'bIsPercentValue' -> it now has no effect on integer values
-'+                 added function FreeImage_RescaleByPixel() to avoid confusion with overloading
-'+                 added function FreeImage_RescaleByPercent() to avoid confusion with overloading
-'+                 added function FreeImage_RescaleByFactor() to avoid confusion with overloading
-'! [Carsten Klein] changed name of parameter 'bUnloadDIB' to 'UnloadSource' of function FreeImage_GetOlePicture()
-'+ [Carsten Klein] added some more inline comments and documentation
-'* [Carsten Klein] fixed a potential runtime error in function FreeImage_SetTransparencyTableEx(): 'Count' will no longer exceed 256
-'
-'May 24, 2005 - 1.1
-'+ [Carsten Klein] added a new VB wrapper
-
-
-'--------------------------------------------------------------------------------
-' Win32 API function, struct and constant declarations
+' Win32 API function, structure and constant declarations
 '--------------------------------------------------------------------------------
 
 Private Const ERROR_SUCCESS As Long = 0
@@ -818,11 +47,6 @@ Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" ( _
     ByRef Source As Any, _
     ByVal Length As Long)
     
-Private Declare Sub FillMemory Lib "kernel32.dll" Alias "RtlFillMemory" ( _
-    ByRef Destination As Any, _
-    ByVal Length As Long, _
-    ByVal Fill As Byte)
-
 Private Declare Function lstrlen Lib "kernel32.dll" Alias "lstrlenA" ( _
     ByVal lpString As Long) As Long
     
@@ -850,7 +74,7 @@ Private Declare Function OleTranslateColor Lib "oleaut32.dll" ( _
     ByRef lpcolorref As Long) As Long
     
 Private Const CLR_INVALID As Long = &HFFFF&
-    
+
 
 'SAFEARRAY
 Private Const FADF_AUTO As Long = (&H1)
@@ -909,6 +133,11 @@ Private Declare Function GetClientRect Lib "user32.dll" ( _
     ByVal hWnd As Long, _
     ByRef lpRect As RECT) As Long
 
+Private Declare Function DestroyIcon Lib "user32.dll" ( _
+    ByVal hIcon As Long) As Long
+
+Private Declare Function CreateIconIndirect Lib "user32.dll" ( _
+    ByRef piconinfo As ICONINFO) As Long
 
 Private Type RECT
    Left As Long
@@ -956,7 +185,8 @@ Private Type BLENDFUNCTION
   SourceConstantAlpha As Byte
   AlphaFormat As Byte
 End Type
-    
+
+
 'GDI32
 Private Declare Function GetDeviceCaps Lib "gdi32.dll" ( _
     ByVal hDC As Long, _
@@ -974,8 +204,8 @@ Private Declare Function SetStretchBltMode Lib "gdi32.dll" ( _
     
 Private Declare Function SetDIBitsToDevice Lib "gdi32.dll" ( _
     ByVal hDC As Long, _
-    ByVal X As Long, _
-    ByVal Y As Long, _
+    ByVal x As Long, _
+    ByVal y As Long, _
     ByVal dx As Long, _
     ByVal dy As Long, _
     ByVal SrcX As Long, _
@@ -988,8 +218,8 @@ Private Declare Function SetDIBitsToDevice Lib "gdi32.dll" ( _
     
 Private Declare Function StretchDIBits Lib "gdi32.dll" ( _
     ByVal hDC As Long, _
-    ByVal X As Long, _
-    ByVal Y As Long, _
+    ByVal x As Long, _
+    ByVal y As Long, _
     ByVal dx As Long, _
     ByVal dy As Long, _
     ByVal SrcX As Long, _
@@ -1032,8 +262,8 @@ Private Declare Function DeleteDC Lib "gdi32.dll" ( _
     
 Private Declare Function BitBlt Lib "gdi32.dll" ( _
     ByVal hDestDC As Long, _
-    ByVal X As Long, _
-    ByVal Y As Long, _
+    ByVal x As Long, _
+    ByVal y As Long, _
     ByVal nWidth As Long, _
     ByVal nHeight As Long, _
     ByVal hSrcDC As Long, _
@@ -1067,17 +297,7 @@ Private Declare Function GetCurrentObject Lib "gdi32.dll" ( _
     ByVal uObjectType As Long) As Long
 
 Private Const OBJ_BITMAP As Long = 7
-    
-    
-Private Declare Function DestroyIcon Lib "user32.dll" ( _
-    ByVal hIcon As Long) As Long
-
-Private Declare Function CreateIconIndirect Lib "user32.dll" ( _
-    ByRef piconinfo As ICONINFO) As Long
 
-Private Const BLACKONWHITE As Long = 1
-Private Const WHITEONBLACK As Long = 2
-Private Const COLORONCOLOR As Long = 3
 
 'MSIMG32
 Private Declare Function AlphaBlend Lib "msimg32.dll" ( _
@@ -1096,18 +316,15 @@ Private Declare Function AlphaBlend Lib "msimg32.dll" ( _
 Private Const AC_SRC_OVER = &H0
 Private Const AC_SRC_ALPHA = &H1
 
+Private Const BLACKONWHITE As Long = 1
+Private Const WHITEONBLACK As Long = 2
+Private Const COLORONCOLOR As Long = 3
 
 Public Enum STRETCH_MODE
    SM_BLACKONWHITE = BLACKONWHITE
    SM_WHITEONBLACK = WHITEONBLACK
    SM_COLORONCOLOR = COLORONCOLOR
 End Enum
-#If False Then
-   Const SM_BLACKONWHITE = BLACKONWHITE
-   Const SM_WHITEONBLACK = WHITEONBLACK
-   Const SM_COLORONCOLOR = COLORONCOLOR
-#End If
-
 
 Private Const SRCAND As Long = &H8800C6
 Private Const SRCCOPY As Long = &HCC0020
@@ -1123,13 +340,6 @@ Public Enum RASTER_OPERATOR
    ROP_SRCINVERT = SRCINVERT
    ROP_SRCPAINT = SRCPAINT
 End Enum
-#If False Then
-   Const ROP_SRCAND = SRCAND
-   Const ROP_SRCCOPY = SRCCOPY
-   Const ROP_SRCERASE = SRCERASE
-   Const ROP_SRCINVERT = SRCINVERT
-   Const ROP_SRCPAINT = SRCPAINT
-#End If
 
 Private Const DIB_PAL_COLORS As Long = 1
 Private Const DIB_RGB_COLORS As Long = 0
@@ -1141,23 +351,11 @@ Public Enum DRAW_MODE
    DM_MIRROR_HORIZONTAL = &H2
    DM_MIRROR_BOTH = DM_MIRROR_VERTICAL Or DM_MIRROR_HORIZONTAL
 End Enum
-#If False Then
-   Const DM_DRAW_DEFAULT = &H0
-   Const DM_MIRROR_NONE = DM_DRAW_DEFAULT
-   Const DM_MIRROR_VERTICAL = &H1
-   Const DM_MIRROR_HORIZONTAL = &H2
-   Const DM_MIRROR_BOTH = DM_MIRROR_VERTICAL Or DM_MIRROR_HORIZONTAL
-#End If
 
 Public Enum HISTOGRAM_ORIENTATION
    HOR_TOP_DOWN = &H0
    HOR_BOTTOM_UP = &H1
 End Enum
-#If False Then
-   Const HOR_TOP_DOWN = &H0
-   Const HOR_BOTTOM_UP = &H1
-#End If
-
 
 '--------------------------------------------------------------------------------
 ' FreeImage 3 types, constants and enumerations
@@ -1167,8 +365,8 @@ End Enum
 
 ' Version information
 Public Const FREEIMAGE_MAJOR_VERSION As Long = 3
-Public Const FREEIMAGE_MINOR_VERSION As Long = 15
-Public Const FREEIMAGE_RELEASE_SERIAL As Long = 4
+Public Const FREEIMAGE_MINOR_VERSION As Long = 16
+Public Const FREEIMAGE_RELEASE_SERIAL As Long = 0
 
 ' Memory stream pointer operation flags
 Public Const SEEK_SET As Long = 0
@@ -1286,6 +484,7 @@ Public Const RAW_DEFAULT As Long = 0                 ' load the file as linear R
 Public Const RAW_PREVIEW As Long = 1                 ' try to load the embedded JPEG preview with included Exif Data or default to RGB 24-bit
 Public Const RAW_DISPLAY As Long = 2                 ' load the file as RGB 24-bit
 Public Const RAW_HALFSIZE As Long = 4                ' load the file as half-size color image
+Public Const RAW_UNPROCESSED As Long = 8             ' load the file as FIT_UINT16 raw Bayer image
 Public Const SGI_DEFAULT As Long = 0
 Public Const TARGA_DEFAULT As Long = 0
 Public Const TARGA_LOAD_RGB888 As Long = 1           ' if set, the loader converts RGB555 and ARGB8888 -> RGB888
@@ -1304,7 +503,13 @@ Public Const TIFF_LOGLUV As Long = &H10000           ' save using LogLuv compres
 Public Const WBMP_DEFAULT As Long = 0
 Public Const XBM_DEFAULT As Long = 0
 Public Const XPM_DEFAULT As Long = 0
+Public Const WEBP_DEFAULT As Long = 0                ' save with good quality (75:1)
+Public Const WEBP_LOSSLESS As Long = &H100           ' save in lossless mode
+Public Const JXR_DEFAULT As Long = 0                 ' save with quality 80 and no chroma subsampling (4:4:4)
+Public Const JXR_LOSSLESS As Long = &H64             ' save in lossless mode
+Public Const JXR_PROGRESSIVE As Long = &H2000        ' save as a progressive-JXR (use Or to combine with other save flags)
 
+' I/O image format identifiers
 Public Enum FREE_IMAGE_FORMAT
    FIF_UNKNOWN = -1
    FIF_BMP = 0
@@ -1343,49 +548,13 @@ Public Enum FREE_IMAGE_FORMAT
    FIF_PFM = 32
    FIF_PICT = 33
    FIF_RAW = 34
+   FIF_WEBP = 35
+   FIF_JXR = 36
 End Enum
-#If False Then
-   Const FIF_UNKNOWN = -1
-   Const FIF_BMP = 0
-   Const FIF_ICO = 1
-   Const FIF_JPEG = 2
-   Const FIF_JNG = 3
-   Const FIF_KOALA = 4
-   Const FIF_LBM = 5
-   Const FIF_IFF = FIF_LBM
-   Const FIF_MNG = 6
-   Const FIF_PBM = 7
-   Const FIF_PBMRAW = 8
-   Const FIF_PCD = 9
-   Const FIF_PCX = 10
-   Const FIF_PGM = 11
-   Const FIF_PGMRAW = 12
-   Const FIF_PNG = 13
-   Const FIF_PPM = 14
-   Const FIF_PPMRAW = 15
-   Const FIF_RAS = 16
-   Const FIF_TARGA = 17
-   Const FIF_TIFF = 18
-   Const FIF_WBMP = 19
-   Const FIF_PSD = 20
-   Const FIF_CUT = 21
-   Const FIF_XBM = 22
-   Const FIF_XPM = 23
-   Const FIF_DDS = 24
-   Const FIF_GIF = 25
-   Const FIF_HDR = 26
-   Const FIF_FAXG3 = 27
-   Const FIF_SGI = 28
-   Const FIF_EXR = 29
-   Const FIF_J2K = 30
-   Const FIF_JP2 = 31
-   Const FIF_PFM = 32
-   Const FIF_PICT = 33
-   Const FIF_RAW = 34
-#End If
 
+' Image load options
 Public Enum FREE_IMAGE_LOAD_OPTIONS
-   FILO_LOAD_NOPIXELS = &H8000                    ' load the image header only (not supported by all plugins)
+   FILO_LOAD_NOPIXELS = FIF_LOAD_NOPIXELS         ' load the image header only (not supported by all plugins)
    FILO_LOAD_DEFAULT = 0
    FILO_GIF_DEFAULT = GIF_DEFAULT
    FILO_GIF_LOAD256 = GIF_LOAD256                 ' load the image as a 256 color image with ununsed palette entries, if it's 16 or 2 color
@@ -1410,36 +579,14 @@ Public Enum FREE_IMAGE_LOAD_OPTIONS
    FILO_RAW_PREVIEW = RAW_PREVIEW                 ' try to load the embedded JPEG preview with included Exif Data or default to RGB 24-bit
    FILO_RAW_DISPLAY = RAW_DISPLAY                 ' load the file as RGB 24-bit
    FILO_RAW_HALFSIZE = RAW_HALFSIZE               ' load the file as half-size color image
+   FILO_RAW_UNPROCESSED = RAW_UNPROCESSED         ' load the file as FIT_UINT16 raw Bayer image
    FILO_TARGA_DEFAULT = TARGA_LOAD_RGB888
    FILO_TARGA_LOAD_RGB888 = TARGA_LOAD_RGB888     ' if set, the loader converts RGB555 and ARGB8888 -> RGB888
    FISO_TIFF_DEFAULT = TIFF_DEFAULT
    FISO_TIFF_CMYK = TIFF_CMYK                     ' reads tags for separated CMYK
 End Enum
-#If False Then
-   Const FILO_LOAD_NOPIXELS = &H8000
-   Const FILO_LOAD_DEFAULT = 0
-   Const FILO_GIF_DEFAULT = GIF_DEFAULT
-   Const FILO_GIF_LOAD256 = GIF_LOAD256
-   Const FILO_GIF_PLAYBACK = GIF_PLAYBACK
-   Const FILO_ICO_DEFAULT = ICO_DEFAULT
-   Const FILO_ICO_MAKEALPHA = ICO_MAKEALPHA
-   Const FILO_JPEG_DEFAULT = JPEG_DEFAULT
-   Const FILO_JPEG_FAST = JPEG_FAST
-   Const FILO_JPEG_ACCURATE = JPEG_ACCURATE
-   Const FILO_JPEG_CMYK = JPEG_CMYK
-   Const FILO_JPEG_EXIFROTATE = JPEG_EXIFROTATE
-   Const FILO_PCD_DEFAULT = PCD_DEFAULT
-   Const FILO_PCD_BASE = PCD_BASE
-   Const FILO_PCD_BASEDIV4 = PCD_BASEDIV4
-   Const FILO_PCD_BASEDIV16 = PCD_BASEDIV16
-   Const FILO_PNG_DEFAULT = PNG_DEFAULT
-   Const FILO_PNG_IGNOREGAMMA = PNG_IGNOREGAMMA
-   Const FILO_TARGA_DEFAULT = TARGA_LOAD_RGB888
-   Const FILO_TARGA_LOAD_RGB888 = TARGA_LOAD_RGB888
-   Const FISO_TIFF_DEFAULT = TIFF_DEFAULT
-   Const FISO_TIFF_CMYK = TIFF_CMYK
-#End If
 
+' Image save options
 Public Enum FREE_IMAGE_SAVE_OPTIONS
    FISO_SAVE_DEFAULT = 0
    FISO_BMP_DEFAULT = BMP_DEFAULT
@@ -1485,38 +632,12 @@ Public Enum FREE_IMAGE_SAVE_OPTIONS
    FISO_TIFF_LZW = TIFF_LZW                       ' save using LZW compression
    FISO_TIFF_JPEG = TIFF_JPEG                     ' save using JPEG compression
    FISO_TIFF_LOGLUV = TIFF_LOGLUV                 ' save using LogLuv compression
+   FISO_WEBP_LOSSLESS = WEBP_LOSSLESS             ' save in lossless mode
+   FISO_JXR_LOSSLESS = JXR_LOSSLESS               ' save in lossless mode
+   FISO_JXR_PROGRESSIVE = JXR_PROGRESSIVE         ' save as a progressive-JXR (use Or to combine with other save flags)
 End Enum
-#If False Then
-   Const FISO_SAVE_DEFAULT = 0
-   Const FISO_BMP_DEFAULT = BMP_DEFAULT
-   Const FISO_BMP_SAVE_RLE = BMP_SAVE_RLE
-   Const FISO_JPEG_DEFAULT = JPEG_DEFAULT
-   Const FISO_JPEG_QUALITYSUPERB = JPEG_QUALITYSUPERB
-   Const FISO_JPEG_QUALITYGOOD = JPEG_QUALITYGOOD
-   Const FISO_JPEG_QUALITYNORMAL = JPEG_QUALITYNORMAL
-   Const FISO_JPEG_QUALITYAVERAGE = JPEG_QUALITYAVERAGE
-   Const FISO_JPEG_QUALITYBAD = JPEG_QUALITYBAD
-   Const FISO_JPEG_PROGRESSIVE = JPEG_PROGRESSIVE
-   Const FISO_JPEG_SUBSAMPLING_411 = JPEG_SUBSAMPLING_411
-   Const FISO_JPEG_SUBSAMPLING_420 = JPEG_SUBSAMPLING_420
-   Const FISO_JPEG_SUBSAMPLING_422 = JPEG_SUBSAMPLING_422
-   Const FISO_JPEG_SUBSAMPLING_444 = JPEG_SUBSAMPLING_444
-   Const FISO_PNM_DEFAULT = PNM_DEFAULT
-   Const FISO_PNM_SAVE_RAW = PNM_SAVE_RAW
-   Const FISO_PNM_SAVE_ASCII = PNM_SAVE_ASCII
-   Const FISO_TARGA_SAVE_RLE = TARGA_SAVE_RLE
-   Const FISO_TIFF_DEFAULT = TIFF_DEFAULT
-   Const FISO_TIFF_CMYK = TIFF_CMYK
-   Const FISO_TIFF_PACKBITS = TIFF_PACKBITS
-   Const FISO_TIFF_DEFLATE = TIFF_DEFLATE
-   Const FISO_TIFF_ADOBE_DEFLATE = TIFF_ADOBE_DEFLATE
-   Const FISO_TIFF_NONE = TIFF_NONE
-   Const FISO_TIFF_CCITTFAX3 = TIFF_CCITTFAX3
-   Const FISO_TIFF_CCITTFAX4 = TIFF_CCITTFAX4
-   Const FISO_TIFF_LZW = TIFF_LZW
-   Const FISO_TIFF_JPEG = TIFF_JPEG
-#End If
 
+' Image types used in FreeImage
 Public Enum FREE_IMAGE_TYPE
    FIT_UNKNOWN = 0           ' unknown type
    FIT_BITMAP = 1            ' standard image           : 1-, 4-, 8-, 16-, 24-, 32-bit
@@ -1532,22 +653,8 @@ Public Enum FREE_IMAGE_TYPE
    FIT_RGBF = 11             ' 96-bit RGB float image   : 3 x 32-bit IEEE floating point
    FIT_RGBAF = 12            ' 128-bit RGBA float image : 4 x 32-bit IEEE floating point
 End Enum
-#If False Then
-   Const FIT_UNKNOWN = 0
-   Const FIT_BITMAP = 1
-   Const FIT_UINT16 = 2
-   Const FIT_INT16 = 3
-   Const FIT_UINT32 = 4
-   Const FIT_INT32 = 5
-   Const FIT_FLOAT = 6
-   Const FIT_DOUBLE = 7
-   Const FIT_COMPLEX = 8
-   Const FIT_RGB16 = 9
-   Const FIT_RGBA16 = 10
-   Const FIT_RGBF = 11
-   Const FIT_RGBAF = 12
-#End If
 
+' Image color types used in FreeImage
 Public Enum FREE_IMAGE_COLOR_TYPE
    FIC_MINISWHITE = 0        ' min value is white
    FIC_MINISBLACK = 1        ' min value is black
@@ -1556,24 +663,14 @@ Public Enum FREE_IMAGE_COLOR_TYPE
    FIC_RGBALPHA = 4          ' RGB color model with alpha channel
    FIC_CMYK = 5              ' CMYK color model
 End Enum
-#If False Then
-   Const FIC_MINISWHITE = 0
-   Const FIC_MINISBLACK = 1
-   Const FIC_RGB = 2
-   Const FIC_PALETTE = 3
-   Const FIC_RGBALPHA = 4
-   Const FIC_CMYK = 5
-#End If
 
+' Color quantization algorithm constants
 Public Enum FREE_IMAGE_QUANTIZE
    FIQ_WUQUANT = 0           ' Xiaolin Wu color quantization algorithm
    FIQ_NNQUANT = 1           ' NeuQuant neural-net quantization algorithm by Anthony Dekker
 End Enum
-#If False Then
-   Const FIQ_WUQUANT = 0
-   Const FIQ_NNQUANT = 1
-#End If
 
+' Dithering algorithm constants
 Public Enum FREE_IMAGE_DITHER
    FID_FS = 0                ' Floyd & Steinberg error diffusion
    FID_BAYER4x4 = 1          ' Bayer ordered dispersed dot dithering (order 2 dithering matrix)
@@ -1583,16 +680,8 @@ Public Enum FREE_IMAGE_DITHER
    FID_CLUSTER16x16 = 5      ' Ordered clustered dot dithering (order 8 - 16x16 matrix)
    FID_BAYER16x16 = 6        ' Bayer ordered dispersed dot dithering (order 4 dithering matrix)
 End Enum
-#If False Then
-   Const FID_FS = 0
-   Const FID_BAYER4x4 = 1
-   Const FID_BAYER8x8 = 2
-   Const FID_CLUSTER6x6 = 3
-   Const FID_CLUSTER8x8 = 4
-   Const FID_CLUSTER16x16 = 5
-   Const FID_BAYER16x16 = 6
-#End If
 
+' Lossless JPEG transformation constants
 Public Enum FREE_IMAGE_JPEG_OPERATION
    FIJPEG_OP_NONE = 0        ' no transformation
    FIJPEG_OP_FLIP_H = 1      ' horizontal flip
@@ -1603,28 +692,15 @@ Public Enum FREE_IMAGE_JPEG_OPERATION
    FIJPEG_OP_ROTATE_180 = 6  ' 180-degree rotation
    FIJPEG_OP_ROTATE_270 = 7  ' 270-degree clockwise (or 90 ccw)
 End Enum
-#If False Then
-   Const FIJPEG_OP_NONE = 0
-   Const FIJPEG_OP_FLIP_H = 1
-   Const FIJPEG_OP_FLIP_V = 2
-   Const FIJPEG_OP_TRANSPOSE = 3
-   Const FIJPEG_OP_TRANSVERSE = 4
-   Const FIJPEG_OP_ROTATE_90 = 5
-   Const FIJPEG_OP_ROTATE_180 = 6
-   Const FIJPEG_OP_ROTATE_270 = 7
-#End If
 
+' Tone mapping operator constants
 Public Enum FREE_IMAGE_TMO
    FITMO_DRAGO03 = 0         ' Adaptive logarithmic mapping (F. Drago, 2003)
    FITMO_REINHARD05 = 1      ' Dynamic range reduction inspired by photoreceptor physiology (E. Reinhard, 2005)
    FITMO_FATTAL02 = 2        ' Gradient domain high dynamic range compression (R. Fattal, 2002)
 End Enum
-#If False Then
-   Const FITMO_DRAGO03 = 0
-   Const FITMO_REINHARD05 = 1
-   Const FITMO_FATTAL02 = 2
-#End If
 
+' Up- / Downsampling filter constants
 Public Enum FREE_IMAGE_FILTER
    FILTER_BOX = 0            ' Box, pulse, Fourier window, 1st order (constant) b-spline
    FILTER_BICUBIC = 1        ' Mitchell & Netravali's two-param cubic filter
@@ -1633,15 +709,8 @@ Public Enum FREE_IMAGE_FILTER
    FILTER_CATMULLROM = 4     ' Catmull-Rom spline, Overhauser spline
    FILTER_LANCZOS3 = 5       ' Lanczos3 filter
 End Enum
-#If False Then
-   Const FILTER_BOX = 0
-   Const FILTER_BICUBIC = 1
-   Const FILTER_BILINEAR = 2
-   Const FILTER_BSPLINE = 3
-   Const FILTER_CATMULLROM = 4
-   Const FILTER_LANCZOS3 = 5
-#End If
 
+' Color channel constants
 Public Enum FREE_IMAGE_COLOR_CHANNEL
    FICC_RGB = 0              ' Use red, green and blue channels
    FICC_RED = 1              ' Use red channel
@@ -1654,19 +723,8 @@ Public Enum FREE_IMAGE_COLOR_CHANNEL
    FICC_MAG = 8              ' Complex images: use magnitude
    FICC_PHASE = 9            ' Complex images: use phase
 End Enum
-#If False Then
-   Const FICC_RGB = 0
-   Const FICC_RED = 1
-   Const FICC_GREEN = 2
-   Const FICC_BLUE = 3
-   Const FICC_ALPHA = 4
-   Const FICC_BLACK = 5
-   Const FICC_REAL = 6
-   Const FICC_IMAG = 7
-   Const FICC_MAG = 8
-   Const FICC_PHASE = 9
-#End If
 
+' Tag data type information constants (based on TIFF specifications)
 Public Enum FREE_IMAGE_MDTYPE
    FIDT_NOTYPE = 0           ' placeholder
    FIDT_BYTE = 1             ' 8-bit unsigned integer
@@ -1684,24 +742,8 @@ Public Enum FREE_IMAGE_MDTYPE
    FIDT_IFD = 13             ' 32-bit unsigned integer (offset)
    FIDT_PALETTE = 14         ' 32-bit RGBQUAD
 End Enum
-#If False Then
-   Const FIDT_NOTYPE = 0
-   Const FIDT_BYTE = 1
-   Const FIDT_ASCII = 2
-   Const FIDT_SHORT = 3
-   Const FIDT_LONG = 4
-   Const FIDT_RATIONAL = 5
-   Const FIDT_SBYTE = 6
-   Const FIDT_UNDEFINED = 7
-   Const FIDT_SSHORT = 8
-   Const FIDT_SLONG = 9
-   Const FIDT_SRATIONAL = 10
-   Const FIDT_FLOAT = 11
-   Const FIDT_DOUBLE = 12
-   Const FIDT_IFD = 13
-   Const FIDT_PALETTE = 14
-#End If
 
+' Metadata models supported by FreeImage
 Public Enum FREE_IMAGE_MDMODEL
    FIMD_NODATA = -1          '
    FIMD_COMMENTS = 0         ' single comment or keywords
@@ -1717,21 +759,6 @@ Public Enum FREE_IMAGE_MDMODEL
    FIMD_CUSTOM = 10          ' Used to attach other metadata types to a dib
    FIMD_EXIF_RAW = 11        ' Exif metadata as a raw buffer
 End Enum
-#If False Then
-   Const FIMD_NODATA = -1
-   Const FIMD_COMMENTS = 0
-   Const FIMD_EXIF_MAIN = 1
-   Const FIMD_EXIF_EXIF = 2
-   Const FIMD_EXIF_GPS = 3
-   Const FIMD_EXIF_MAKERNOTE = 4
-   Const FIMD_EXIF_INTEROP = 5
-   Const FIMD_IPTC = 6
-   Const FIMD_XMP = 7
-   Const FIMD_GEOTIFF = 8
-   Const FIMD_ANIMATION = 9
-   Const FIMD_CUSTOM = 10
-   Const FIMD_EXIF_RAW = 11
-#End If
 
 ' These are the GIF_DISPOSAL metadata constants
 Public Enum FREE_IMAGE_FRAME_DISPOSAL_METHODS
@@ -1751,8 +778,8 @@ End Enum
 Public Const FI_COLOR_PALETTE_SEARCH_MASK = _
       (FI_COLOR_FIND_EQUAL_COLOR Or FI_COLOR_ALPHA_IS_INDEX)     ' Flag to test, if any color lookup is performed
 
-' the next enums are only used by derived functions of the
-' FreeImage 3 VB wrapper
+' The following enum constants are used by derived (wrapper) functions of the
+' FreeImage 3 VB Wrapper
 Public Enum FREE_IMAGE_CONVERSION_FLAGS
    FICF_MONOCHROME = &H1
    FICF_MONOCHROME_THRESHOLD = FICF_MONOCHROME
@@ -1769,22 +796,6 @@ Public Enum FREE_IMAGE_CONVERSION_FLAGS
    FICF_KEEP_UNORDERED_GREYSCALE_PALETTE = &H0
    FICF_REORDER_GREYSCALE_PALETTE = &H1000
 End Enum
-#If False Then
-   Const FICF_MONOCHROME = &H1
-   Const FICF_MONOCHROME_THRESHOLD = FICF_MONOCHROME
-   Const FICF_MONOCHROME_DITHER = &H3
-   Const FICF_GREYSCALE_4BPP = &H4
-   Const FICF_PALLETISED_8BPP = &H8
-   Const FICF_GREYSCALE_8BPP = FICF_PALLETISED_8BPP Or FICF_MONOCHROME
-   Const FICF_GREYSCALE = FICF_GREYSCALE_8BPP
-   Const FICF_RGB_15BPP = &HF
-   Const FICF_RGB_16BPP = &H10
-   Const FICF_RGB_24BPP = &H18
-   Const FICF_RGB_32BPP = &H20
-   Const FICF_RGB_ALPHA = FICF_RGB_32BPP
-   Const FICF_KEEP_UNORDERED_GREYSCALE_PALETTE = &H0
-   Const FICF_REORDER_GREYSCALE_PALETTE = &H1000
-#End If
 
 Public Enum FREE_IMAGE_COLOR_DEPTH
    FICD_AUTO = &H0
@@ -1799,19 +810,6 @@ Public Enum FREE_IMAGE_COLOR_DEPTH
    FICD_24BPP = &H18
    FICD_32BPP = &H20
 End Enum
-#If False Then
-   Const FICD_AUTO = &H0
-   Const FICD_MONOCHROME = &H1
-   Const FICD_MONOCHROME_THRESHOLD = FICF_MONOCHROME
-   Const FICD_MONOCHROME_DITHER = &H3
-   Const FICD_1BPP = FICD_MONOCHROME
-   Const FICD_4BPP = &H4
-   Const FICD_8BPP = &H8
-   Const FICD_15BPP = &HF
-   Const FICD_16BPP = &H10
-   Const FICD_24BPP = &H18
-   Const FICD_32BPP = &H20
-#End If
 
 Public Enum FREE_IMAGE_ADJUST_MODE
    AM_STRECH = &H1
@@ -1821,14 +819,6 @@ Public Enum FREE_IMAGE_ADJUST_MODE
    AM_ADJUST_HEIGHT = &H4
    AM_ADJUST_OPTIMAL_SIZE = &H8
 End Enum
-#If False Then
-   Const AM_STRECH = &H1
-   Const AM_DEFAULT = AM_STRECH
-   Const AM_ADJUST_BOTH = AM_STRECH
-   Const AM_ADJUST_WIDTH = &H2
-   Const AM_ADJUST_HEIGHT = &H4
-   Const AM_ADJUST_OPTIMAL_SIZE = &H8
-#End If
 
 Public Enum FREE_IMAGE_MASK_FLAGS
    FIMF_MASK_NONE = &H0
@@ -1838,14 +828,6 @@ Public Enum FREE_IMAGE_MASK_FLAGS
    FIMF_MASK_FORCE_TRANSPARENCY = &H8
    FIMF_MASK_INVERSE_MASK = &H10
 End Enum
-#If False Then
-   Const FIMF_MASK_NONE = &H0
-   Const FIMF_MASK_FULL_TRANSPARENCY = &H1
-   Const FIMF_MASK_ALPHA_TRANSPARENCY = &H2
-   Const FIMF_MASK_COLOR_TRANSPARENCY = &H4
-   Const FIMF_MASK_FORCE_TRANSPARENCY = &H8
-   Const FIMF_MASK_INVERSE_MASK = &H10
-#End If
 
 Public Enum FREE_IMAGE_COLOR_FORMAT_FLAGS
    FICFF_COLOR_RGB = &H1
@@ -1859,29 +841,12 @@ Public Enum FREE_IMAGE_COLOR_FORMAT_FLAGS
    
    FICFF_COLOR_FORMAT_ORDER_MASK = FICFF_COLOR_RGB Or FICFF_COLOR_BGR
 End Enum
-#If False Then
-   Const FICFF_COLOR_RGB = &H1
-   Const FICFF_COLOR_BGR = &H2
-   Const FICFF_COLOR_PALETTE_INDEX = &H4
-   
-   Const FICFF_COLOR_HAS_ALPHA = &H100
-   
-   Const FICFF_COLOR_ARGB = FICFF_COLOR_RGB Or FICFF_COLOR_HAS_ALPHA
-   Const FICFF_COLOR_ABGR = FICFF_COLOR_BGR Or FICFF_COLOR_HAS_ALPHA
-   
-   Const FICFF_COLOR_FORMAT_ORDER_MASK = FICFF_COLOR_RGB Or FICFF_COLOR_BGR
-#End If
 
 Public Enum FREE_IMAGE_MASK_CREATION_OPTION_FLAGS
    MCOF_CREATE_MASK_IMAGE = &H1
    MCOF_MODIFY_SOURCE_IMAGE = &H2
    MCOF_CREATE_AND_MODIFY = MCOF_CREATE_MASK_IMAGE Or MCOF_MODIFY_SOURCE_IMAGE
 End Enum
-#If False Then
-   Const MCOF_CREATE_MASK_IMAGE = &H1
-   Const MCOF_MODIFY_SOURCE_IMAGE = &H2
-   Const MCOF_CREATE_AND_MODIFY = MCOF_CREATE_MASK_IMAGE Or MCOF_MODIFY_SOURCE_IMAGE
-#End If
 
 Public Enum FREE_IMAGE_TRANSPARENCY_STATE_FLAGS
    FITSF_IGNORE_TRANSPARENCY = &H0
@@ -1889,12 +854,6 @@ Public Enum FREE_IMAGE_TRANSPARENCY_STATE_FLAGS
    FITSF_TRANSPARENT = &H2
    FITSF_INCLUDE_ALPHA_TRANSPARENCY = &H4
 End Enum
-#If False Then
-   Const FITSF_IGNORE_TRANSPARENCY = &H0
-   Const FITSF_NONTRANSPARENT = &H1
-   Const FITSF_TRANSPARENT = &H2
-   Const FITSF_INCLUDE_ALPHA_TRANSPARENCY = &H4
-#End If
 
 Public Enum FREE_IMAGE_ICON_TRANSPARENCY_OPTION_FLAGS
    ITOF_NO_TRANSPARENCY = &H0
@@ -1912,29 +871,12 @@ Public Enum FREE_IMAGE_ICON_TRANSPARENCY_OPTION_FLAGS
    ITOF_USE_COLOR_SPECIFIED = &H100
    ITOF_FORCE_TRANSPARENCY_INFO = &H400
 End Enum
-#If False Then
-   Const ITOF_NO_TRANSPARENCY = &H0
-   Const ITOF_USE_TRANSPARENCY_INFO = &H1
-   Const ITOF_USE_TRANSPARENCY_INFO_ONLY = ITOF_USE_TRANSPARENCY_INFO
-   Const ITOF_USE_COLOR_TRANSPARENCY = &H2
-   Const ITOF_USE_COLOR_TRANSPARENCY_ONLY = ITOF_USE_COLOR_TRANSPARENCY
-   Const ITOF_USE_TRANSPARENCY_INFO_OR_COLOR = ITOF_USE_TRANSPARENCY_INFO Or ITOF_USE_COLOR_TRANSPARENCY
-   Const ITOF_USE_DEFAULT_TRANSPARENCY = ITOF_USE_TRANSPARENCY_INFO_OR_COLOR
-   Const ITOF_USE_COLOR_TOP_LEFT_PIXEL = &H0
-   Const ITOF_USE_COLOR_FIRST_PIXEL = ITOF_USE_COLOR_TOP_LEFT_PIXEL
-   Const ITOF_USE_COLOR_TOP_RIGHT_PIXEL = &H20
-   Const ITOF_USE_COLOR_BOTTOM_LEFT_PIXEL = &H40
-   Const ITOF_USE_COLOR_BOTTOM_RIGHT_PIXEL = &H80
-   Const ITOF_USE_COLOR_SPECIFIED = &H100
-   Const ITOF_FORCE_TRANSPARENCY_INFO = &H400
-#End If
 
 Private Const ITOF_USE_COLOR_BITMASK As Long = ITOF_USE_COLOR_TOP_RIGHT_PIXEL Or _
                                                ITOF_USE_COLOR_BOTTOM_LEFT_PIXEL Or _
                                                ITOF_USE_COLOR_BOTTOM_RIGHT_PIXEL Or _
                                                ITOF_USE_COLOR_SPECIFIED
 
-
 Public Type RGBQUAD
    rgbBlue As Byte
    rgbGreen As Byte
@@ -1960,9 +902,6 @@ Public Type BITMAPINFOHEADER
    biYPelsPerMeter As Long
    biClrUsed As Long
    biClrImportant As Long
-   red As Long
-   green As Long
-   blue As Long
 End Type
 
 Public Type BITMAPINFO
@@ -1978,37 +917,42 @@ Public Const BI_JPEG As Long = 4
 Public Const BI_PNG As Long = 5
 
 Public Type FIICCPROFILE
-   Flags As Integer
-   Size As Long
-   Data As Long
+   Flags As Integer      ' info flag
+   Size As Long          ' profile's size measured in bytes
+   Data As Long          ' points to a block of contiguous memory containing the profile
 End Type
 
+' 48-bit RGB
 Public Type FIRGB16
-   red As Integer
-   green As Integer
-   blue As Integer
+   Red As Integer
+   Green As Integer
+   Blue As Integer
 End Type
 
+' 64-bit RGBA
 Public Type FIRGBA16
-   red As Integer
-   green As Integer
-   blue As Integer
+   Red As Integer
+   Green As Integer
+   Blue As Integer
    Alpha As Integer
 End Type
 
+' 96-bit RGB Float
 Public Type FIRGBF
-   red As Single
-   green As Single
-   blue As Single
+   Red As Single
+   Green As Single
+   Blue As Single
 End Type
 
+' 128-bit RGBA Float
 Public Type FIRGBAF
-   red As Single
-   green As Single
-   blue As Single
+   Red As Single
+   Green As Single
+   Blue As Single
    Alpha As Single
 End Type
 
+' data structure for COMPLEX type (complex number)
 Public Type FICOMPLEX
    r As Double           ' real part
    i As Double           ' imaginary part
@@ -2069,8 +1013,8 @@ Public Type Plugin
    supports_icc_profiles_proc As Long
 End Type
 
-' the next structures are only used by derived functions of the
-' FreeImage 3 VB wrapper
+' The following structures are used by derived (wrapper) functions of the
+' FreeImage 3 VB Wrapper
 Public Type ScanLineRGBTRIBLE
    Data() As RGBTRIPLE
 End Type
@@ -2084,28 +1028,28 @@ End Type
 '--------------------------------------------------------------------------------
 
 ' The FreeImage 3 functions are declared in the same order as they are described
-' in the FreeImage 3 API documentation. The documentation's outline is included
-' as comments.
-
-'--------------------------------------------------------------------------------
-' Bitmap functions
-'--------------------------------------------------------------------------------
+' in the FreeImage 3 API documentation (mostly). The documentation's outline is
+' included as comments.
 
-' General functions
+' Initialization / Deinitialization functions
 Public Declare Sub FreeImage_Initialise Lib "FreeImage.dll" Alias "_FreeImage_Initialise at 4" ( _
   Optional ByVal LoadLocalPluginsOnly As Long)
 
 Public Declare Sub FreeImage_DeInitialise Lib "FreeImage.dll" Alias "_FreeImage_DeInitialise at 0" ()
 
+
+' Version functions
 Private Declare Function FreeImage_GetVersionInt Lib "FreeImage.dll" Alias "_FreeImage_GetVersion at 0" () As Long
 
 Private Declare Function FreeImage_GetCopyrightMessageInt Lib "FreeImage.dll" Alias "_FreeImage_GetCopyrightMessage at 0" () As Long
 
+
+' Message output functions
 Public Declare Sub FreeImage_SetOutputMessage Lib "FreeImage.dll" Alias "_FreeImage_SetOutputMessageStdCall at 4" ( _
            ByVal omf As Long)
 
 
-' Bitmap management functions
+' Allocate / Clone / Unload functions
 Public Declare Function FreeImage_Allocate Lib "FreeImage.dll" Alias "_FreeImage_Allocate at 24" ( _
            ByVal Width As Long, _
            ByVal Height As Long, _
@@ -2122,10 +1066,20 @@ Public Declare Function FreeImage_AllocateT Lib "FreeImage.dll" Alias "_FreeImag
   Optional ByVal RedMask As Long, _
   Optional ByVal GreenMask As Long, _
   Optional ByVal BlueMask As Long) As Long
-  
+
+Public Declare Function FreeImage_Clone Lib "FreeImage.dll" Alias "_FreeImage_Clone at 4" ( _
+           ByVal Bitmap As Long) As Long
+
+Public Declare Sub FreeImage_Unload Lib "FreeImage.dll" Alias "_FreeImage_Unload at 4" ( _
+           ByVal Bitmap As Long)
+
+
+' Header loading functions
 Public Declare Function FreeImage_HasPixelsInt Lib "FreeImage.dll" Alias "_FreeImage_HasPixels at 4" ( _
            ByVal Bitmap As Long) As Long
 
+
+' Load / Save functions
 Public Declare Function FreeImage_Load Lib "FreeImage.dll" Alias "_FreeImage_Load at 12" ( _
            ByVal Format As FREE_IMAGE_FORMAT, _
            ByVal Filename As String, _
@@ -2161,125 +1115,189 @@ Private Declare Function FreeImage_SaveToHandleInt Lib "FreeImage.dll" Alias "_F
            ByVal Handle As Long, _
   Optional ByVal Flags As FREE_IMAGE_SAVE_OPTIONS) As Long
 
-Public Declare Function FreeImage_Clone Lib "FreeImage.dll" Alias "_FreeImage_Clone at 4" ( _
-           ByVal Bitmap As Long) As Long
 
-Public Declare Sub FreeImage_Unload Lib "FreeImage.dll" Alias "_FreeImage_Unload at 4" ( _
-           ByVal Bitmap As Long)
+' Memory I/O stream functions
+Public Declare Function FreeImage_OpenMemory Lib "FreeImage.dll" Alias "_FreeImage_OpenMemory at 8" ( _
+  Optional ByRef Data As Byte, _
+  Optional ByVal SizeInBytes As Long) As Long
+  
+Public Declare Function FreeImage_OpenMemoryByPtr Lib "FreeImage.dll" Alias "_FreeImage_OpenMemory at 8" ( _
+  Optional ByVal DataPtr As Long, _
+  Optional ByVal SizeInBytes As Long) As Long
 
+Public Declare Sub FreeImage_CloseMemory Lib "FreeImage.dll" Alias "_FreeImage_CloseMemory at 4" ( _
+           ByVal Stream As Long)
 
-' Bitmap information functions
-Public Declare Function FreeImage_GetImageType Lib "FreeImage.dll" Alias "_FreeImage_GetImageType at 4" ( _
-           ByVal Bitmap As Long) As FREE_IMAGE_TYPE
+Public Declare Function FreeImage_LoadFromMemory Lib "FreeImage.dll" Alias "_FreeImage_LoadFromMemory at 12" ( _
+           ByVal Format As FREE_IMAGE_FORMAT, _
+           ByVal Stream As Long, _
+  Optional ByVal Flags As FREE_IMAGE_LOAD_OPTIONS) As Long
 
-Public Declare Function FreeImage_GetColorsUsed Lib "FreeImage.dll" Alias "_FreeImage_GetColorsUsed at 4" ( _
-           ByVal Bitmap As Long) As Long
+Private Declare Function FreeImage_SaveToMemoryInt Lib "FreeImage.dll" Alias "_FreeImage_SaveToMemory at 16" ( _
+           ByVal Format As FREE_IMAGE_FORMAT, _
+           ByVal Bitmap As Long, _
+           ByVal Stream As Long, _
+  Optional ByVal Flags As FREE_IMAGE_SAVE_OPTIONS) As Long
 
-Public Declare Function FreeImage_GetBPP Lib "FreeImage.dll" Alias "_FreeImage_GetBPP at 4" ( _
-           ByVal Bitmap As Long) As Long
+Public Declare Function FreeImage_TellMemory Lib "FreeImage.dll" Alias "_FreeImage_TellMemory at 4" ( _
+           ByVal Stream As Long) As Long
 
-Public Declare Function FreeImage_GetWidth Lib "FreeImage.dll" Alias "_FreeImage_GetWidth at 4" ( _
-           ByVal Bitmap As Long) As Long
+Private Declare Function FreeImage_SeekMemoryInt Lib "FreeImage.dll" Alias "_FreeImage_SeekMemory at 12" ( _
+           ByVal Stream As Long, _
+           ByVal Offset As Long, _
+           ByVal Origin As Long) As Long
 
-Public Declare Function FreeImage_GetHeight Lib "FreeImage.dll" Alias "_FreeImage_GetHeight at 4" ( _
-           ByVal Bitmap As Long) As Long
+Private Declare Function FreeImage_AcquireMemoryInt Lib "FreeImage.dll" Alias "_FreeImage_AcquireMemory at 12" ( _
+           ByVal Stream As Long, _
+           ByRef DataPtr As Long, _
+           ByRef SizeInBytes As Long) As Long
+           
+Public Declare Function FreeImage_ReadMemory Lib "FreeImage.dll" Alias "_FreeImage_ReadMemory at 16" ( _
+           ByVal BufferPtr As Long, _
+           ByVal Size As Long, _
+           ByVal Count As Long, _
+           ByVal Stream As Long) As Long
+           
+Public Declare Function FreeImage_WriteMemory Lib "FreeImage.dll" Alias "_FreeImage_WriteMemory at 16" ( _
+           ByVal BufferPtr As Long, _
+           ByVal Size As Long, _
+           ByVal Count As Long, _
+           ByVal Stream As Long) As Long
+           
+Public Declare Function FreeImage_LoadMultiBitmapFromMemory Lib "FreeImage.dll" Alias "_FreeImage_LoadMultiBitmapFromMemory at 12" ( _
+           ByVal Format As FREE_IMAGE_FORMAT, _
+           ByVal Stream As Long, _
+  Optional ByVal Flags As FREE_IMAGE_LOAD_OPTIONS) As Long
 
-Public Declare Function FreeImage_GetLine Lib "FreeImage.dll" Alias "_FreeImage_GetLine at 4" ( _
-           ByVal Bitmap As Long) As Long
+Public Declare Function FreeImage_SaveMultiBitmapToMemory Lib "FreeImage.dll" Alias "_FreeImage_SaveMultiBitmapToMemory at 16" ( _
+           ByVal Format As FREE_IMAGE_FORMAT, _
+           ByVal Bitmap As Long, _
+           ByVal Stream As Long, _
+  Optional ByVal Flags As FREE_IMAGE_SAVE_OPTIONS) As Long
 
-Public Declare Function FreeImage_GetPitch Lib "FreeImage.dll" Alias "_FreeImage_GetPitch at 4" ( _
-           ByVal Bitmap As Long) As Long
 
-Public Declare Function FreeImage_GetDIBSize Lib "FreeImage.dll" Alias "_FreeImage_GetDIBSize at 4" ( _
-           ByVal Bitmap As Long) As Long
+' Plugin / Format functions
+Public Declare Function FreeImage_RegisterLocalPlugin Lib "FreeImage.dll" Alias "_FreeImage_RegisterLocalPlugin at 20" ( _
+           ByVal InitProcAddress As Long, _
+  Optional ByVal Format As String, _
+  Optional ByVal Description As String, _
+  Optional ByVal Extension As String, _
+  Optional ByVal RegExpr As String) As FREE_IMAGE_FORMAT
 
-Public Declare Function FreeImage_GetPalette Lib "FreeImage.dll" Alias "_FreeImage_GetPalette at 4" ( _
-           ByVal Bitmap As Long) As Long
+Public Declare Function FreeImage_RegisterExternalPlugin Lib "FreeImage.dll" Alias "_FreeImage_RegisterExternalPlugin at 20" ( _
+           ByVal Path As String, _
+  Optional ByVal Format As String, _
+  Optional ByVal Description As String, _
+  Optional ByVal Extension As String, _
+  Optional ByVal RegExpr As String) As FREE_IMAGE_FORMAT
+  
+Public Declare Function FreeImage_GetFIFCount Lib "FreeImage.dll" Alias "_FreeImage_GetFIFCount at 0" () As Long
 
-Public Declare Function FreeImage_GetDotsPerMeterX Lib "FreeImage.dll" Alias "_FreeImage_GetDotsPerMeterX at 4" ( _
-           ByVal Bitmap As Long) As Long
+Public Declare Function FreeImage_SetPluginEnabled Lib "FreeImage.dll" Alias "_FreeImage_SetPluginEnabled at 8" ( _
+           ByVal Format As FREE_IMAGE_FORMAT, _
+           ByVal Value As Long) As Long
 
-Public Declare Function FreeImage_GetDotsPerMeterY Lib "FreeImage.dll" Alias "_FreeImage_GetDotsPerMeterY at 4" ( _
-           ByVal Bitmap As Long) As Long
+Public Declare Function FreeImage_IsPluginEnabled Lib "FreeImage.dll" Alias "_FreeImage_IsPluginEnabled at 4" ( _
+           ByVal Format As FREE_IMAGE_FORMAT) As Long
 
-Public Declare Sub FreeImage_SetDotsPerMeterX Lib "FreeImage.dll" Alias "_FreeImage_SetDotsPerMeterX at 8" ( _
-           ByVal Bitmap As Long, _
-           ByVal Resolution As Long)
+Public Declare Function FreeImage_GetFIFFromFormat Lib "FreeImage.dll" Alias "_FreeImage_GetFIFFromFormat at 4" ( _
+           ByVal Format As String) As FREE_IMAGE_FORMAT
 
-Public Declare Sub FreeImage_SetDotsPerMeterY Lib "FreeImage.dll" Alias "_FreeImage_SetDotsPerMeterY at 8" ( _
-           ByVal Bitmap As Long, _
-           ByVal Resolution As Long)
+Public Declare Function FreeImage_GetFIFFromMime Lib "FreeImage.dll" Alias "_FreeImage_GetFIFFromMime at 4" ( _
+           ByVal MimeType As String) As FREE_IMAGE_FORMAT
 
-Public Declare Function FreeImage_GetInfoHeader Lib "FreeImage.dll" Alias "_FreeImage_GetInfoHeader at 4" ( _
-           ByVal Bitmap As Long) As Long
+Private Declare Function FreeImage_GetFormatFromFIFInt Lib "FreeImage.dll" Alias "_FreeImage_GetFormatFromFIF at 4" ( _
+           ByVal Format As FREE_IMAGE_FORMAT) As Long
 
-Public Declare Function FreeImage_GetInfo Lib "FreeImage.dll" Alias "_FreeImage_GetInfo at 4" ( _
-           ByVal Bitmap As Long) As Long
+Private Declare Function FreeImage_GetFIFExtensionListInt Lib "FreeImage.dll" Alias "_FreeImage_GetFIFExtensionList at 4" ( _
+           ByVal Format As FREE_IMAGE_FORMAT) As Long
 
-Public Declare Function FreeImage_GetColorType Lib "FreeImage.dll" Alias "_FreeImage_GetColorType at 4" ( _
-           ByVal Bitmap As Long) As FREE_IMAGE_COLOR_TYPE
+Private Declare Function FreeImage_GetFIFDescriptionInt Lib "FreeImage.dll" Alias "_FreeImage_GetFIFDescription at 4" ( _
+           ByVal Format As FREE_IMAGE_FORMAT) As Long
 
-Public Declare Function FreeImage_GetRedMask Lib "FreeImage.dll" Alias "_FreeImage_GetRedMask at 4" ( _
-           ByVal Bitmap As Long) As Long
+Private Declare Function FreeImage_GetFIFRegExprInt Lib "FreeImage.dll" Alias "_FreeImage_GetFIFRegExpr at 4" ( _
+           ByVal Format As FREE_IMAGE_FORMAT) As Long
 
-Public Declare Function FreeImage_GetGreenMask Lib "FreeImage.dll" Alias "_FreeImage_GetGreenMask at 4" ( _
-           ByVal Bitmap As Long) As Long
+Private Declare Function FreeImage_GetFIFMimeTypeInt Lib "FreeImage.dll" Alias "_FreeImage_GetFIFMimeType at 4" ( _
+           ByVal Format As FREE_IMAGE_FORMAT) As Long
 
-Public Declare Function FreeImage_GetBlueMask Lib "FreeImage.dll" Alias "_FreeImage_GetBlueMask at 4" ( _
-           ByVal Bitmap As Long) As Long
+Public Declare Function FreeImage_GetFIFFromFilename Lib "FreeImage.dll" Alias "_FreeImage_GetFIFFromFilename at 4" ( _
+           ByVal Filename As String) As FREE_IMAGE_FORMAT
+           
+Private Declare Function FreeImage_GetFIFFromFilenameUInt Lib "FreeImage.dll" Alias "_FreeImage_GetFIFFromFilenameU at 4" ( _
+           ByVal Filename As Long) As FREE_IMAGE_FORMAT
 
-Public Declare Function FreeImage_GetTransparencyCount Lib "FreeImage.dll" Alias "_FreeImage_GetTransparencyCount at 4" ( _
-           ByVal Bitmap As Long) As Long
+Private Declare Function FreeImage_FIFSupportsReadingInt Lib "FreeImage.dll" Alias "_FreeImage_FIFSupportsReading at 4" ( _
+           ByVal Format As FREE_IMAGE_FORMAT) As Long
 
-Public Declare Function FreeImage_GetTransparencyTable Lib "FreeImage.dll" Alias "_FreeImage_GetTransparencyTable at 4" ( _
-           ByVal Bitmap As Long) As Long
+Private Declare Function FreeImage_FIFSupportsWritingInt Lib "FreeImage.dll" Alias "_FreeImage_FIFSupportsWriting at 4" ( _
+           ByVal Format As FREE_IMAGE_FORMAT) As Long
 
-Public Declare Sub FreeImage_SetTransparencyTable Lib "FreeImage.dll" Alias "_FreeImage_SetTransparencyTable at 12" ( _
-           ByVal Bitmap As Long, _
-           ByVal TransTablePtr As Long, _
-           ByVal Count As Long)
+Private Declare Function FreeImage_FIFSupportsExportBPPInt Lib "FreeImage.dll" Alias "_FreeImage_FIFSupportsExportBPP at 8" ( _
+           ByVal Format As FREE_IMAGE_FORMAT, _
+           ByVal BitsPerPixel As Long) As Long
 
-Private Declare Sub FreeImage_SetTransparentInt Lib "FreeImage.dll" Alias "_FreeImage_SetTransparent at 8" ( _
-           ByVal Bitmap As Long, _
-           ByVal Value As Long)
+Private Declare Function FreeImage_FIFSupportsExportTypeInt Lib "FreeImage.dll" Alias "_FreeImage_FIFSupportsExportType at 8" ( _
+           ByVal Format As FREE_IMAGE_FORMAT, _
+           ByVal ImageType As FREE_IMAGE_TYPE) As Long
 
-Private Declare Function FreeImage_IsTransparentInt Lib "FreeImage.dll" Alias "_FreeImage_IsTransparent at 4" ( _
-           ByVal Bitmap As Long) As Long
-           
-Public Declare Function FreeImage_GetTransparentIndex Lib "FreeImage.dll" Alias "_FreeImage_GetTransparentIndex at 4" ( _
-           ByVal Bitmap As Long) As Long
+Private Declare Function FreeImage_FIFSupportsICCProfilesInt Lib "FreeImage.dll" Alias "_FreeImage_FIFSupportsICCProfiles at 4" ( _
+           ByVal Format As FREE_IMAGE_FORMAT) As Long
            
-Public Declare Function FreeImage_SetTransparentIndex Lib "FreeImage.dll" Alias "_FreeImage_SetTransparentIndex at 8" ( _
-           ByVal Bitmap As Long, _
-           ByVal Index As Long) As Long
+Private Declare Function FreeImage_FIFSupportsNoPixelsInt Lib "FreeImage.dll" Alias "_FreeImage_FIFSupportsNoPixels at 4" ( _
+           ByVal Format As FREE_IMAGE_FORMAT) As Long
 
-Private Declare Function FreeImage_HasBackgroundColorInt Lib "FreeImage.dll" Alias "_FreeImage_HasBackgroundColor at 4" ( _
-           ByVal Bitmap As Long) As Long
-           
-Private Declare Function FreeImage_GetBackgroundColorInt Lib "FreeImage.dll" Alias "_FreeImage_GetBackgroundColor at 8" ( _
-           ByVal Bitmap As Long, _
-           ByRef BackColor As RGBQUAD) As Long
 
-Private Declare Function FreeImage_GetBackgroundColorAsLongInt Lib "FreeImage.dll" Alias "_FreeImage_GetBackgroundColor at 8" ( _
+' Multipaging functions
+Private Declare Function FreeImage_OpenMultiBitmapInt Lib "FreeImage.dll" Alias "_FreeImage_OpenMultiBitmap at 24" ( _
+           ByVal Format As FREE_IMAGE_FORMAT, _
+           ByVal Filename As String, _
+           ByVal CreateNew As Long, _
+           ByVal ReadOnly As Long, _
+           ByVal KeepCacheInMemory As Long, _
+           ByVal Flags As FREE_IMAGE_LOAD_OPTIONS) As Long
+
+Private Declare Function FreeImage_CloseMultiBitmapInt Lib "FreeImage.dll" Alias "_FreeImage_CloseMultiBitmap at 8" ( _
            ByVal Bitmap As Long, _
-           ByRef BackColor As Long) As Long
+  Optional ByVal Flags As FREE_IMAGE_SAVE_OPTIONS) As Long
 
-Private Declare Function FreeImage_SetBackgroundColorInt Lib "FreeImage.dll" Alias "_FreeImage_SetBackgroundColor at 8" ( _
+Public Declare Function FreeImage_GetPageCount Lib "FreeImage.dll" Alias "_FreeImage_GetPageCount at 4" ( _
+           ByVal Bitmap As Long) As Long
+
+Public Declare Sub FreeImage_AppendPage Lib "FreeImage.dll" Alias "_FreeImage_AppendPage at 8" ( _
            ByVal Bitmap As Long, _
-           ByRef BackColor As RGBQUAD) As Long
-           
-Private Declare Function FreeImage_SetBackgroundColorAsLongInt Lib "FreeImage.dll" Alias "_FreeImage_SetBackgroundColor at 8" ( _
+           ByVal PageBitmap As Long)
+
+Public Declare Sub FreeImage_InsertPage Lib "FreeImage.dll" Alias "_FreeImage_InsertPage at 12" ( _
            ByVal Bitmap As Long, _
-           ByRef BackColor As Long) As Long
+           ByVal Page As Long, _
+           ByVal PageBitmap As Long)
 
-Public Declare Function FreeImage_GetThumbnail Lib "FreeImage.dll" Alias "_FreeImage_GetThumbnail at 4" ( _
-           ByVal Bitmap As Long) As Long
-           
-Private Declare Function FreeImage_SetThumbnailInt Lib "FreeImage.dll" Alias "_FreeImage_SetThumbnail at 8" ( _
-           ByVal Bitmap As Long, ByVal Thumbnail As Long) As Long
+Public Declare Sub FreeImage_DeletePage Lib "FreeImage.dll" Alias "_FreeImage_DeletePage at 8" ( _
+           ByVal Bitmap As Long, _
+           ByVal Page As Long)
 
+Public Declare Function FreeImage_LockPage Lib "FreeImage.dll" Alias "_FreeImage_LockPage at 8" ( _
+           ByVal Bitmap As Long, _
+           ByVal Page As Long) As Long
 
-' Filetype functions
+Private Declare Sub FreeImage_UnlockPageInt Lib "FreeImage.dll" Alias "_FreeImage_UnlockPage at 12" ( _
+           ByVal Bitmap As Long, _
+           ByVal PageBitmap As Long, _
+           ByVal ApplyChanges As Long)
+
+Private Declare Function FreeImage_MovePageInt Lib "FreeImage.dll" Alias "_FreeImage_MovePage at 12" ( _
+           ByVal Bitmap As Long, _
+           ByVal TargetPage As Long, _
+           ByVal SourcePage As Long) As Long
+
+Private Declare Function FreeImage_GetLockedPageNumbersInt Lib "FreeImage.dll" Alias "_FreeImage_GetLockedPageNumbers at 12" ( _
+           ByVal Bitmap As Long, _
+           ByRef PagesPtr As Long, _
+           ByRef Count As Long) As Long
+
+
+' Filetype request functions
 Public Declare Function FreeImage_GetFileType Lib "FreeImage.dll" Alias "_FreeImage_GetFileType at 8" ( _
            ByVal Filename As String, _
   Optional ByVal Size As Long) As FREE_IMAGE_FORMAT
@@ -2298,6 +1316,27 @@ Public Declare Function FreeImage_GetFileTypeFromMemory Lib "FreeImage.dll" Alia
   Optional ByVal Size As Long) As FREE_IMAGE_FORMAT
 
 
+' Image type request functions
+Public Declare Function FreeImage_GetImageType Lib "FreeImage.dll" Alias "_FreeImage_GetImageType at 4" ( _
+           ByVal Bitmap As Long) As FREE_IMAGE_TYPE
+
+
+' FreeImage helper functions
+Private Declare Function FreeImage_IsLittleEndianInt Lib "FreeImage.dll" Alias "_FreeImage_IsLittleEndian at 0" () As Long
+
+Private Declare Function FreeImage_LookupX11ColorInt Lib "FreeImage.dll" Alias "_FreeImage_LookupX11Color at 16" ( _
+           ByVal Color As String, _
+           ByRef Red As Long, _
+           ByRef Green As Long, _
+           ByRef Blue As Long) As Long
+
+Private Declare Function FreeImage_LookupSVGColorInt Lib "FreeImage.dll" Alias "_FreeImage_LookupSVGColor at 16" ( _
+           ByVal Color As String, _
+           ByRef Red As Long, _
+           ByRef Green As Long, _
+           ByRef Blue As Long) As Long
+
+
 ' Pixel access functions
 Public Declare Function FreeImage_GetBits Lib "FreeImage.dll" Alias "_FreeImage_GetBits at 4" ( _
            ByVal Bitmap As Long) As Long
@@ -2308,153 +1347,150 @@ Public Declare Function FreeImage_GetScanline Lib "FreeImage.dll" Alias "_FreeIm
 
 Private Declare Function FreeImage_GetPixelIndexInt Lib "FreeImage.dll" Alias "_FreeImage_GetPixelIndex at 16" ( _
            ByVal Bitmap As Long, _
-           ByVal X As Long, _
-           ByVal Y As Long, _
+           ByVal x As Long, _
+           ByVal y As Long, _
            ByRef Value As Byte) As Long
 
 Private Declare Function FreeImage_GetPixelColorInt Lib "FreeImage.dll" Alias "_FreeImage_GetPixelColor at 16" ( _
            ByVal Bitmap As Long, _
-           ByVal X As Long, _
-           ByVal Y As Long, _
+           ByVal x As Long, _
+           ByVal y As Long, _
            ByRef Value As RGBQUAD) As Long
            
 Private Declare Function FreeImage_GetPixelColorByLongInt Lib "FreeImage.dll" Alias "_FreeImage_GetPixelColor at 16" ( _
            ByVal Bitmap As Long, _
-           ByVal X As Long, _
-           ByVal Y As Long, _
+           ByVal x As Long, _
+           ByVal y As Long, _
            ByRef Value As Long) As Long
 
 Private Declare Function FreeImage_SetPixelIndexInt Lib "FreeImage.dll" Alias "_FreeImage_SetPixelIndex at 16" ( _
            ByVal Bitmap As Long, _
-           ByVal X As Long, _
-           ByVal Y As Long, _
+           ByVal x As Long, _
+           ByVal y As Long, _
            ByRef Value As Byte) As Long
 
 Private Declare Function FreeImage_SetPixelColorInt Lib "FreeImage.dll" Alias "_FreeImage_SetPixelColor at 16" ( _
            ByVal Bitmap As Long, _
-           ByVal X As Long, _
-           ByVal Y As Long, _
+           ByVal x As Long, _
+           ByVal y As Long, _
            ByRef Value As RGBQUAD) As Long
            
 Private Declare Function FreeImage_SetPixelColorByLongInt Lib "FreeImage.dll" Alias "_FreeImage_SetPixelColor at 16" ( _
            ByVal Bitmap As Long, _
-           ByVal X As Long, _
-           ByVal Y As Long, _
+           ByVal x As Long, _
+           ByVal y As Long, _
            ByRef Value As Long) As Long
-           
 
 
-' Conversion functions
-Public Declare Function FreeImage_ConvertTo4Bits Lib "FreeImage.dll" Alias "_FreeImage_ConvertTo4Bits at 4" ( _
+' DIB info functions
+Public Declare Function FreeImage_GetColorsUsed Lib "FreeImage.dll" Alias "_FreeImage_GetColorsUsed at 4" ( _
            ByVal Bitmap As Long) As Long
 
-Public Declare Function FreeImage_ConvertTo8Bits Lib "FreeImage.dll" Alias "_FreeImage_ConvertTo8Bits at 4" ( _
+Public Declare Function FreeImage_GetBPP Lib "FreeImage.dll" Alias "_FreeImage_GetBPP at 4" ( _
            ByVal Bitmap As Long) As Long
-           
-Public Declare Function FreeImage_ConvertToGreyscale Lib "FreeImage.dll" Alias "_FreeImage_ConvertToGreyscale at 4" ( _
+
+Public Declare Function FreeImage_GetWidth Lib "FreeImage.dll" Alias "_FreeImage_GetWidth at 4" ( _
            ByVal Bitmap As Long) As Long
 
-Public Declare Function FreeImage_ConvertTo16Bits555 Lib "FreeImage.dll" Alias "_FreeImage_ConvertTo16Bits555 at 4" ( _
+Public Declare Function FreeImage_GetHeight Lib "FreeImage.dll" Alias "_FreeImage_GetHeight at 4" ( _
            ByVal Bitmap As Long) As Long
 
-Public Declare Function FreeImage_ConvertTo16Bits565 Lib "FreeImage.dll" Alias "_FreeImage_ConvertTo16Bits565 at 4" ( _
+Public Declare Function FreeImage_GetLine Lib "FreeImage.dll" Alias "_FreeImage_GetLine at 4" ( _
            ByVal Bitmap As Long) As Long
 
-Public Declare Function FreeImage_ConvertTo24Bits Lib "FreeImage.dll" Alias "_FreeImage_ConvertTo24Bits at 4" ( _
+Public Declare Function FreeImage_GetPitch Lib "FreeImage.dll" Alias "_FreeImage_GetPitch at 4" ( _
            ByVal Bitmap As Long) As Long
 
-Public Declare Function FreeImage_ConvertTo32Bits Lib "FreeImage.dll" Alias "_FreeImage_ConvertTo32Bits at 4" ( _
+Public Declare Function FreeImage_GetDIBSize Lib "FreeImage.dll" Alias "_FreeImage_GetDIBSize at 4" ( _
            ByVal Bitmap As Long) As Long
 
-Public Declare Function FreeImage_ColorQuantize Lib "FreeImage.dll" Alias "_FreeImage_ColorQuantize at 8" ( _
-           ByVal Bitmap As Long, _
-           ByVal QuantizeMethod As FREE_IMAGE_QUANTIZE) As Long
-           
-Private Declare Function FreeImage_ColorQuantizeExInt Lib "FreeImage.dll" Alias "_FreeImage_ColorQuantizeEx at 20" ( _
-           ByVal Bitmap As Long, _
-  Optional ByVal QuantizeMethod As FREE_IMAGE_QUANTIZE = FIQ_WUQUANT, _
-  Optional ByVal PaletteSize As Long = 256, _
-  Optional ByVal ReserveSize As Long = 0, _
-  Optional ByVal ReservePalettePtr As Long = 0) As Long
+Public Declare Function FreeImage_GetPalette Lib "FreeImage.dll" Alias "_FreeImage_GetPalette at 4" ( _
+           ByVal Bitmap As Long) As Long
 
-Public Declare Function FreeImage_Threshold Lib "FreeImage.dll" Alias "_FreeImage_Threshold at 8" ( _
+Public Declare Function FreeImage_GetDotsPerMeterX Lib "FreeImage.dll" Alias "_FreeImage_GetDotsPerMeterX at 4" ( _
+           ByVal Bitmap As Long) As Long
+
+Public Declare Function FreeImage_GetDotsPerMeterY Lib "FreeImage.dll" Alias "_FreeImage_GetDotsPerMeterY at 4" ( _
+           ByVal Bitmap As Long) As Long
+
+Public Declare Sub FreeImage_SetDotsPerMeterX Lib "FreeImage.dll" Alias "_FreeImage_SetDotsPerMeterX at 8" ( _
            ByVal Bitmap As Long, _
-           ByVal Threshold As Byte) As Long
+           ByVal Resolution As Long)
 
-Public Declare Function FreeImage_Dither Lib "FreeImage.dll" Alias "_FreeImage_Dither at 8" ( _
+Public Declare Sub FreeImage_SetDotsPerMeterY Lib "FreeImage.dll" Alias "_FreeImage_SetDotsPerMeterY at 8" ( _
            ByVal Bitmap As Long, _
-           ByVal DitherMethod As FREE_IMAGE_DITHER) As Long
+           ByVal Resolution As Long)
 
-Private Declare Function FreeImage_ConvertFromRawBitsInt Lib "FreeImage.dll" Alias "_FreeImage_ConvertFromRawBits at 36" ( _
-           ByVal BitsPtr As Long, _
-           ByVal Width As Long, _
-           ByVal Height As Long, _
-           ByVal Pitch As Long, _
-           ByVal BitsPerPixel As Long, _
-           ByVal RedMask As Long, _
-           ByVal GreenMask As Long, _
-           ByVal BlueMask As Long, _
-           ByVal TopDown As Long) As Long
+Public Declare Function FreeImage_GetInfoHeader Lib "FreeImage.dll" Alias "_FreeImage_GetInfoHeader at 4" ( _
+           ByVal Bitmap As Long) As Long
 
-Private Declare Sub FreeImage_ConvertToRawBitsInt Lib "FreeImage.dll" Alias "_FreeImage_ConvertToRawBits at 32" ( _
-           ByVal BitsPtr As Long, _
-           ByVal Bitmap As Long, _
-           ByVal Pitch As Long, _
-           ByVal BitsPerPixel As Long, _
-           ByVal RedMask As Long, _
-           ByVal GreenMask As Long, _
-           ByVal BlueMask As Long, _
-           ByVal TopDown As Long)
+Public Declare Function FreeImage_GetInfo Lib "FreeImage.dll" Alias "_FreeImage_GetInfo at 4" ( _
+           ByVal Bitmap As Long) As Long
 
-Private Declare Function FreeImage_ConvertToStandardTypeInt Lib "FreeImage.dll" Alias "_FreeImage_ConvertToStandardType at 8" ( _
-           ByVal Bitmap As Long, _
-           ByVal ScaleLinear As Long) As Long
+Public Declare Function FreeImage_GetColorType Lib "FreeImage.dll" Alias "_FreeImage_GetColorType at 4" ( _
+           ByVal Bitmap As Long) As FREE_IMAGE_COLOR_TYPE
 
-Private Declare Function FreeImage_ConvertToTypeInt Lib "FreeImage.dll" Alias "_FreeImage_ConvertToType at 12" ( _
-           ByVal Bitmap As Long, _
-           ByVal DestinationType As FREE_IMAGE_TYPE, _
-           ByVal ScaleLinear As Long) As Long
+Private Declare Function FreeImage_HasRGBMasksInt Lib "FreeImage.dll" Alias "_FreeImage_HasRGBMasks at 4" ( _
+           ByVal Bitmap As Long) As Long
 
-Public Declare Function FreeImage_ConvertToFloat Lib "FreeImage.dll" Alias "_FreeImage_ConvertToFloat at 4" ( _
+Public Declare Function FreeImage_GetRedMask Lib "FreeImage.dll" Alias "_FreeImage_GetRedMask at 4" ( _
            ByVal Bitmap As Long) As Long
 
-Public Declare Function FreeImage_ConvertToRGBF Lib "FreeImage.dll" Alias "_FreeImage_ConvertToRGBF at 4" ( _
+Public Declare Function FreeImage_GetGreenMask Lib "FreeImage.dll" Alias "_FreeImage_GetGreenMask at 4" ( _
            ByVal Bitmap As Long) As Long
 
-Public Declare Function FreeImage_ConvertToUINT16 Lib "FreeImage.dll" Alias "_FreeImage_ConvertToUINT16 at 4" ( _
+Public Declare Function FreeImage_GetBlueMask Lib "FreeImage.dll" Alias "_FreeImage_GetBlueMask at 4" ( _
            ByVal Bitmap As Long) As Long
 
-Public Declare Function FreeImage_ConvertToRGB16 Lib "FreeImage.dll" Alias "_FreeImage_ConvertToRGB16 at 4" ( _
+Public Declare Function FreeImage_GetTransparencyCount Lib "FreeImage.dll" Alias "_FreeImage_GetTransparencyCount at 4" ( _
            ByVal Bitmap As Long) As Long
 
-' Tone mapping operators
-Public Declare Function FreeImage_ToneMapping Lib "FreeImage.dll" Alias "_FreeImage_ToneMapping at 24" ( _
+Public Declare Function FreeImage_GetTransparencyTable Lib "FreeImage.dll" Alias "_FreeImage_GetTransparencyTable at 4" ( _
+           ByVal Bitmap As Long) As Long
+
+Private Declare Sub FreeImage_SetTransparentInt Lib "FreeImage.dll" Alias "_FreeImage_SetTransparent at 8" ( _
            ByVal Bitmap As Long, _
-           ByVal Operator As FREE_IMAGE_TMO, _
-  Optional ByVal FirstArgument As Double, _
-  Optional ByVal SecondArgument As Double) As Long
-  
-Public Declare Function FreeImage_TmoDrago03 Lib "FreeImage.dll" Alias "_FreeImage_TmoDrago03 at 20" ( _
+           ByVal Value As Long)
+
+Public Declare Sub FreeImage_SetTransparencyTable Lib "FreeImage.dll" Alias "_FreeImage_SetTransparencyTable at 12" ( _
            ByVal Bitmap As Long, _
-  Optional ByVal Gamma As Double = 2.2, _
-  Optional ByVal Exposure As Double) As Long
-  
-Public Declare Function FreeImage_TmoReinhard05 Lib "FreeImage.dll" Alias "_FreeImage_TmoReinhard05 at 20" ( _
+           ByVal TransTablePtr As Long, _
+           ByVal Count As Long)
+
+Private Declare Function FreeImage_IsTransparentInt Lib "FreeImage.dll" Alias "_FreeImage_IsTransparent at 4" ( _
+           ByVal Bitmap As Long) As Long
+
+Public Declare Function FreeImage_SetTransparentIndex Lib "FreeImage.dll" Alias "_FreeImage_SetTransparentIndex at 8" ( _
            ByVal Bitmap As Long, _
-  Optional ByVal Intensity As Double, _
-  Optional ByVal Contrast As Double) As Long
+           ByVal Index As Long) As Long
 
-Public Declare Function FreeImage_TmoReinhard05Ex Lib "FreeImage.dll" Alias "_FreeImage_TmoReinhard05Ex at 36" ( _
+Public Declare Function FreeImage_GetTransparentIndex Lib "FreeImage.dll" Alias "_FreeImage_GetTransparentIndex at 4" ( _
+           ByVal Bitmap As Long) As Long
+
+Private Declare Function FreeImage_HasBackgroundColorInt Lib "FreeImage.dll" Alias "_FreeImage_HasBackgroundColor at 4" ( _
+           ByVal Bitmap As Long) As Long
+           
+Private Declare Function FreeImage_GetBackgroundColorInt Lib "FreeImage.dll" Alias "_FreeImage_GetBackgroundColor at 8" ( _
            ByVal Bitmap As Long, _
-  Optional ByVal Intensity As Double, _
-  Optional ByVal Contrast As Double, _
-  Optional ByVal Adaptation As Double = 1, _
-  Optional ByVal ColorCorrection As Double) As Long
+           ByRef BackColor As RGBQUAD) As Long
 
-Public Declare Function FreeImage_TmoFattal02 Lib "FreeImage.dll" Alias "_FreeImage_TmoFattal02 at 20" ( _
+Private Declare Function FreeImage_GetBackgroundColorAsLongInt Lib "FreeImage.dll" Alias "_FreeImage_GetBackgroundColor at 8" ( _
            ByVal Bitmap As Long, _
-  Optional ByVal ColorSaturation As Double = 0.5, _
-  Optional ByVal Attenuation As Double = 0.85) As Long
+           ByRef BackColor As Long) As Long
+
+Private Declare Function FreeImage_SetBackgroundColorInt Lib "FreeImage.dll" Alias "_FreeImage_SetBackgroundColor at 8" ( _
+           ByVal Bitmap As Long, _
+           ByRef BackColor As RGBQUAD) As Long
+           
+Private Declare Function FreeImage_SetBackgroundColorAsLongInt Lib "FreeImage.dll" Alias "_FreeImage_SetBackgroundColor at 8" ( _
+           ByVal Bitmap As Long, _
+           ByRef BackColor As Long) As Long
+
+Public Declare Function FreeImage_GetThumbnail Lib "FreeImage.dll" Alias "_FreeImage_GetThumbnail at 4" ( _
+           ByVal Bitmap As Long) As Long
+           
+Private Declare Function FreeImage_SetThumbnailInt Lib "FreeImage.dll" Alias "_FreeImage_SetThumbnail at 8" ( _
+           ByVal Bitmap As Long, ByVal Thumbnail As Long) As Long
 
 
 ' ICC profile functions
@@ -2469,189 +1505,330 @@ Public Declare Function FreeImage_CreateICCProfile Lib "FreeImage.dll" Alias "_F
 Public Declare Sub FreeImage_DestroyICCProfile Lib "FreeImage.dll" Alias "_FreeImage_DestroyICCProfile at 4" ( _
            ByVal Bitmap As Long)
 
+           
+' Line conversion functions
+Public Declare Sub FreeImage_ConvertLine1To4 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine1To4 at 12" ( _
+           ByVal TargetPtr As Long, _
+           ByVal SourcePtr As Long, _
+           ByVal WidthInPixels As Long)
+           
+Public Declare Sub FreeImage_ConvertLine8To4 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine1To8 at 16" ( _
+           ByVal TargetPtr As Long, _
+           ByVal SourcePtr As Long, _
+           ByVal WidthInPixels As Long, _
+           ByVal PalettePtr As Long)
+           
+Public Declare Sub FreeImage_ConvertLine16To4_555 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine16To4_555 at 12" ( _
+           ByVal TargetPtr As Long, _
+           ByVal SourcePtr As Long, _
+           ByVal WidthInPixels As Long)
+                     
+Public Declare Sub FreeImage_ConvertLine16To4_565 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine16To4_565 at 12" ( _
+           ByVal TargetPtr As Long, _
+           ByVal SourcePtr As Long, _
+           ByVal WidthInPixels As Long)
+           
+Public Declare Sub FreeImage_ConvertLine24To4 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine1To24 at 12" ( _
+           ByVal TargetPtr As Long, _
+           ByVal SourcePtr As Long, _
+           ByVal WidthInPixels As Long)
+           
+Public Declare Sub FreeImage_ConvertLine32To4 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine32To4 at 12" ( _
+           ByVal TargetPtr As Long, _
+           ByVal SourcePtr As Long, _
+           ByVal WidthInPixels As Long)
 
-' Plugin functions
-Public Declare Function FreeImage_GetFIFCount Lib "FreeImage.dll" Alias "_FreeImage_GetFIFCount at 0" () As Long
+Public Declare Sub FreeImage_ConvertLine1To8 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine1To8 at 12" ( _
+           ByVal TargetPtr As Long, _
+           ByVal SourcePtr As Long, _
+           ByVal WidthInPixels As Long)
 
-Public Declare Function FreeImage_SetPluginEnabled Lib "FreeImage.dll" Alias "_FreeImage_SetPluginEnabled at 8" ( _
-           ByVal Format As FREE_IMAGE_FORMAT, _
-           ByVal Value As Long) As Long
+Public Declare Sub FreeImage_ConvertLine4To8 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine4To8 at 12" ( _
+           ByVal TargetPtr As Long, _
+           ByVal SourcePtr As Long, _
+           ByVal WidthInPixels As Long)
 
-Public Declare Function FreeImage_IsPluginEnabled Lib "FreeImage.dll" Alias "_FreeImage_IsPluginEnabled at 4" ( _
-           ByVal Format As FREE_IMAGE_FORMAT) As Long
+Public Declare Sub FreeImage_ConvertLine16To8_555 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine16To8_555 at 12" ( _
+           ByVal TargetPtr As Long, _
+           ByVal SourcePtr As Long, _
+           ByVal WidthInPixels As Long)
 
-Public Declare Function FreeImage_GetFIFFromFormat Lib "FreeImage.dll" Alias "_FreeImage_GetFIFFromFormat at 4" ( _
-           ByVal Format As String) As FREE_IMAGE_FORMAT
+Public Declare Sub FreeImage_ConvertLine16To8_565 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine16To8_565 at 12" ( _
+           ByVal TargetPtr As Long, _
+           ByVal SourcePtr As Long, _
+           ByVal WidthInPixels As Long)
 
-Public Declare Function FreeImage_GetFIFFromMime Lib "FreeImage.dll" Alias "_FreeImage_GetFIFFromMime at 4" ( _
-           ByVal MimeType As String) As FREE_IMAGE_FORMAT
+Public Declare Sub FreeImage_ConvertLine24To8 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine24To8 at 12" ( _
+           ByVal TargetPtr As Long, _
+           ByVal SourcePtr As Long, _
+           ByVal WidthInPixels As Long)
 
-Private Declare Function FreeImage_GetFIFMimeTypeInt Lib "FreeImage.dll" Alias "_FreeImage_GetFIFMimeType at 4" ( _
-           ByVal Format As FREE_IMAGE_FORMAT) As Long
+Public Declare Sub FreeImage_ConvertLine32To8 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine32To8 at 12" ( _
+           ByVal TargetPtr As Long, _
+           ByVal SourcePtr As Long, _
+           ByVal WidthInPixels As Long)
 
-Private Declare Function FreeImage_GetFormatFromFIFInt Lib "FreeImage.dll" Alias "_FreeImage_GetFormatFromFIF at 4" ( _
-           ByVal Format As FREE_IMAGE_FORMAT) As Long
+Public Declare Sub FreeImage_ConvertLine1To16_555 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine1To16_555 at 16" ( _
+           ByVal TargetPtr As Long, _
+           ByVal SourcePtr As Long, _
+           ByVal WidthInPixels As Long, _
+           ByVal PalettePtr As Long)
 
-Private Declare Function FreeImage_GetFIFExtensionListInt Lib "FreeImage.dll" Alias "_FreeImage_GetFIFExtensionList at 4" ( _
-           ByVal Format As FREE_IMAGE_FORMAT) As Long
+Public Declare Sub FreeImage_ConvertLine4To16_555 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine4To16_555 at 16" ( _
+           ByVal TargetPtr As Long, _
+           ByVal SourcePtr As Long, _
+           ByVal WidthInPixels As Long, _
+           ByVal PalettePtr As Long)
 
-Private Declare Function FreeImage_GetFIFDescriptionInt Lib "FreeImage.dll" Alias "_FreeImage_GetFIFDescription at 4" ( _
-           ByVal Format As FREE_IMAGE_FORMAT) As Long
+Public Declare Sub FreeImage_ConvertLine8To16_555 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine8To16_555 at 16" ( _
+           ByVal TargetPtr As Long, _
+           ByVal SourcePtr As Long, _
+           ByVal WidthInPixels As Long, _
+           ByVal PalettePtr As Long)
 
-Private Declare Function FreeImage_GetFIFRegExprInt Lib "FreeImage.dll" Alias "_FreeImage_GetFIFRegExpr at 4" ( _
-           ByVal Format As FREE_IMAGE_FORMAT) As Long
+Public Declare Sub FreeImage_ConvertLine16_565_To16_555 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine16_565_To16_555 at 12" ( _
+           ByVal TargetPtr As Long, _
+           ByVal SourcePtr As Long, _
+           ByVal WidthInPixels As Long)
 
-Public Declare Function FreeImage_GetFIFFromFilename Lib "FreeImage.dll" Alias "_FreeImage_GetFIFFromFilename at 4" ( _
-           ByVal Filename As String) As FREE_IMAGE_FORMAT
-           
-Private Declare Function FreeImage_GetFIFFromFilenameUInt Lib "FreeImage.dll" Alias "_FreeImage_GetFIFFromFilenameU at 4" ( _
-           ByVal Filename As Long) As FREE_IMAGE_FORMAT
+Public Declare Sub FreeImage_ConvertLine24To16_555 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine24To16_555 at 12" ( _
+           ByVal TargetPtr As Long, _
+           ByVal SourcePtr As Long, _
+           ByVal WidthInPixels As Long)
 
-Private Declare Function FreeImage_FIFSupportsReadingInt Lib "FreeImage.dll" Alias "_FreeImage_FIFSupportsReading at 4" ( _
-           ByVal Format As FREE_IMAGE_FORMAT) As Long
+Public Declare Sub FreeImage_ConvertLine32To16_555 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine32To16_555 at 12" ( _
+           ByVal TargetPtr As Long, _
+           ByVal SourcePtr As Long, _
+           ByVal WidthInPixels As Long)
 
-Private Declare Function FreeImage_FIFSupportsWritingInt Lib "FreeImage.dll" Alias "_FreeImage_FIFSupportsWriting at 4" ( _
-           ByVal Format As FREE_IMAGE_FORMAT) As Long
+Public Declare Sub FreeImage_ConvertLine1To16_565 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine1To16_565 at 16" ( _
+           ByVal TargetPtr As Long, _
+           ByVal SourcePtr As Long, _
+           ByVal WidthInPixels As Long, _
+           ByVal PalettePtr As Long)
 
-Private Declare Function FreeImage_FIFSupportsExportTypeInt Lib "FreeImage.dll" Alias "_FreeImage_FIFSupportsExportType at 8" ( _
-           ByVal Format As FREE_IMAGE_FORMAT, _
-           ByVal ImageType As FREE_IMAGE_TYPE) As Long
+Public Declare Sub FreeImage_ConvertLine4To16_565 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine4To16_565 at 16" ( _
+           ByVal TargetPtr As Long, _
+           ByVal SourcePtr As Long, _
+           ByVal WidthInPixels As Long, _
+           ByVal PalettePtr As Long)
 
-Private Declare Function FreeImage_FIFSupportsExportBPPInt Lib "FreeImage.dll" Alias "_FreeImage_FIFSupportsExportBPP at 8" ( _
-           ByVal Format As FREE_IMAGE_FORMAT, _
-           ByVal BitsPerPixel As Long) As Long
+Public Declare Sub FreeImage_ConvertLine8To16_565 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine8To16_565 at 16" ( _
+           ByVal TargetPtr As Long, _
+           ByVal SourcePtr As Long, _
+           ByVal WidthInPixels As Long, _
+           ByVal PalettePtr As Long)
 
-Private Declare Function FreeImage_FIFSupportsICCProfilesInt Lib "FreeImage.dll" Alias "_FreeImage_FIFSupportsICCProfiles at 4" ( _
-           ByVal Format As FREE_IMAGE_FORMAT) As Long
-           
-Private Declare Function FreeImage_FIFSupportsNoPixelsInt Lib "FreeImage.dll" Alias "_FreeImage_FIFSupportsNoPixels at 4" ( _
-           ByVal Format As FREE_IMAGE_FORMAT) As Long
+Public Declare Sub FreeImage_ConvertLine16_555_To16_565 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine16_555_To16_565 at 12" ( _
+           ByVal TargetPtr As Long, _
+           ByVal SourcePtr As Long, _
+           ByVal WidthInPixels As Long)
 
-Public Declare Function FreeImage_RegisterLocalPlugin Lib "FreeImage.dll" Alias "_FreeImage_RegisterLocalPlugin at 20" ( _
-           ByVal InitProcAddress As Long, _
-  Optional ByVal Format As String, _
-  Optional ByVal Description As String, _
-  Optional ByVal Extension As String, _
-  Optional ByVal RegExpr As String) As FREE_IMAGE_FORMAT
+Public Declare Sub FreeImage_ConvertLine24To16_565 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine24To16_565 at 12" ( _
+           ByVal TargetPtr As Long, _
+           ByVal SourcePtr As Long, _
+           ByVal WidthInPixels As Long)
 
-Public Declare Function FreeImage_RegisterExternalPlugin Lib "FreeImage.dll" Alias "_FreeImage_RegisterExternalPlugin at 20" ( _
-           ByVal Path As String, _
-  Optional ByVal Format As String, _
-  Optional ByVal Description As String, _
-  Optional ByVal Extension As String, _
-  Optional ByVal RegExpr As String) As FREE_IMAGE_FORMAT
+Public Declare Sub FreeImage_ConvertLine32To16_565 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine32To16_565 at 12" ( _
+           ByVal TargetPtr As Long, _
+           ByVal SourcePtr As Long, _
+           ByVal WidthInPixels As Long)
 
+Public Declare Sub FreeImage_ConvertLine1To24 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine1To24 at 16" ( _
+           ByVal TargetPtr As Long, _
+           ByVal SourcePtr As Long, _
+           ByVal WidthInPixels As Long, _
+           ByVal PalettePtr As Long)
 
-' Multipage functions
-Private Declare Function FreeImage_OpenMultiBitmapInt Lib "FreeImage.dll" Alias "_FreeImage_OpenMultiBitmap at 24" ( _
-           ByVal Format As FREE_IMAGE_FORMAT, _
-           ByVal Filename As String, _
-           ByVal CreateNew As Long, _
-           ByVal ReadOnly As Long, _
-           ByVal KeepCacheInMemory As Long, _
-           ByVal Flags As FREE_IMAGE_LOAD_OPTIONS) As Long
+Public Declare Sub FreeImage_ConvertLine4To24 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine4To24 at 16" ( _
+           ByVal TargetPtr As Long, _
+           ByVal SourcePtr As Long, _
+           ByVal WidthInPixels As Long, _
+           ByVal PalettePtr As Long)
 
-Private Declare Function FreeImage_CloseMultiBitmapInt Lib "FreeImage.dll" Alias "_FreeImage_CloseMultiBitmap at 8" ( _
-           ByVal Bitmap As Long, _
-  Optional ByVal Flags As FREE_IMAGE_SAVE_OPTIONS) As Long
+Public Declare Sub FreeImage_ConvertLine8To24 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine8To24 at 16" ( _
+           ByVal TargetPtr As Long, _
+           ByVal SourcePtr As Long, _
+           ByVal WidthInPixels As Long, _
+           ByVal PalettePtr As Long)
 
-Public Declare Function FreeImage_GetPageCount Lib "FreeImage.dll" Alias "_FreeImage_GetPageCount at 4" ( _
+Public Declare Sub FreeImage_ConvertLine16To24_555 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine16To24_555 at 12" ( _
+           ByVal TargetPtr As Long, _
+           ByVal SourcePtr As Long, _
+           ByVal WidthInPixels As Long)
+
+Public Declare Sub FreeImage_ConvertLine16To24_565 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine16To24_565 at 12" ( _
+           ByVal TargetPtr As Long, _
+           ByVal SourcePtr As Long, _
+           ByVal WidthInPixels As Long)
+
+Public Declare Sub FreeImage_ConvertLine32To24 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine32To24 at 12" ( _
+           ByVal TargetPtr As Long, _
+           ByVal SourcePtr As Long, _
+           ByVal WidthInPixels As Long)
+
+Public Declare Sub FreeImage_ConvertLine1To32 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine1To32 at 16" ( _
+           ByVal TargetPtr As Long, _
+           ByVal SourcePtr As Long, _
+           ByVal WidthInPixels As Long, _
+           ByVal PalettePtr As Long)
+
+Public Declare Sub FreeImage_ConvertLine4To32 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine4To32 at 16" ( _
+           ByVal TargetPtr As Long, _
+           ByVal SourcePtr As Long, _
+           ByVal WidthInPixels As Long, _
+           ByVal PalettePtr As Long)
+
+Public Declare Sub FreeImage_ConvertLine8To32 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine8To32 at 16" ( _
+           ByVal TargetPtr As Long, _
+           ByVal SourcePtr As Long, _
+           ByVal WidthInPixels As Long, _
+           ByVal PalettePtr As Long)
+
+Public Declare Sub FreeImage_ConvertLine16To32_555 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine16To32_555 at 12" ( _
+           ByVal TargetPtr As Long, _
+           ByVal SourcePtr As Long, _
+           ByVal WidthInPixels As Long)
+
+Public Declare Sub FreeImage_ConvertLine16To32_565 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine16To32_565 at 12" ( _
+           ByVal TargetPtr As Long, _
+           ByVal SourcePtr As Long, _
+           ByVal WidthInPixels As Long)
+
+Public Declare Sub FreeImage_ConvertLine24To32 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine24To32 at 12" ( _
+           ByVal TargetPtr As Long, _
+           ByVal SourcePtr As Long, _
+           ByVal WidthInPixels As Long)
+
+
+' Smart conversion functions
+Public Declare Function FreeImage_ConvertTo4Bits Lib "FreeImage.dll" Alias "_FreeImage_ConvertTo4Bits at 4" ( _
            ByVal Bitmap As Long) As Long
 
-Public Declare Sub FreeImage_AppendPage Lib "FreeImage.dll" Alias "_FreeImage_AppendPage at 8" ( _
+Public Declare Function FreeImage_ConvertTo8Bits Lib "FreeImage.dll" Alias "_FreeImage_ConvertTo8Bits at 4" ( _
+           ByVal Bitmap As Long) As Long
+           
+Public Declare Function FreeImage_ConvertToGreyscale Lib "FreeImage.dll" Alias "_FreeImage_ConvertToGreyscale at 4" ( _
+           ByVal Bitmap As Long) As Long
+
+Public Declare Function FreeImage_ConvertTo16Bits555 Lib "FreeImage.dll" Alias "_FreeImage_ConvertTo16Bits555 at 4" ( _
+           ByVal Bitmap As Long) As Long
+
+Public Declare Function FreeImage_ConvertTo16Bits565 Lib "FreeImage.dll" Alias "_FreeImage_ConvertTo16Bits565 at 4" ( _
+           ByVal Bitmap As Long) As Long
+
+Public Declare Function FreeImage_ConvertTo24Bits Lib "FreeImage.dll" Alias "_FreeImage_ConvertTo24Bits at 4" ( _
+           ByVal Bitmap As Long) As Long
+
+Public Declare Function FreeImage_ConvertTo32Bits Lib "FreeImage.dll" Alias "_FreeImage_ConvertTo32Bits at 4" ( _
+           ByVal Bitmap As Long) As Long
+
+Public Declare Function FreeImage_ColorQuantize Lib "FreeImage.dll" Alias "_FreeImage_ColorQuantize at 8" ( _
+           ByVal Bitmap As Long, _
+           ByVal QuantizeMethod As FREE_IMAGE_QUANTIZE) As Long
+           
+Private Declare Function FreeImage_ColorQuantizeExInt Lib "FreeImage.dll" Alias "_FreeImage_ColorQuantizeEx at 20" ( _
            ByVal Bitmap As Long, _
-           ByVal PageBitmap As Long)
+  Optional ByVal QuantizeMethod As FREE_IMAGE_QUANTIZE = FIQ_WUQUANT, _
+  Optional ByVal PaletteSize As Long = 256, _
+  Optional ByVal ReserveSize As Long = 0, _
+  Optional ByVal ReservePalettePtr As Long = 0) As Long
 
-Public Declare Sub FreeImage_InsertPage Lib "FreeImage.dll" Alias "_FreeImage_InsertPage at 12" ( _
+Public Declare Function FreeImage_Threshold Lib "FreeImage.dll" Alias "_FreeImage_Threshold at 8" ( _
            ByVal Bitmap As Long, _
-           ByVal Page As Long, _
-           ByVal PageBitmap As Long)
+           ByVal Threshold As Byte) As Long
 
-Public Declare Sub FreeImage_DeletePage Lib "FreeImage.dll" Alias "_FreeImage_DeletePage at 8" ( _
+Public Declare Function FreeImage_Dither Lib "FreeImage.dll" Alias "_FreeImage_Dither at 8" ( _
            ByVal Bitmap As Long, _
-           ByVal Page As Long)
+           ByVal DitherMethod As FREE_IMAGE_DITHER) As Long
 
-Public Declare Function FreeImage_LockPage Lib "FreeImage.dll" Alias "_FreeImage_LockPage at 8" ( _
-           ByVal Bitmap As Long, _
-           ByVal Page As Long) As Long
+Private Declare Function FreeImage_ConvertFromRawBitsInt Lib "FreeImage.dll" Alias "_FreeImage_ConvertFromRawBits at 36" ( _
+           ByVal BitsPtr As Long, _
+           ByVal Width As Long, _
+           ByVal Height As Long, _
+           ByVal Pitch As Long, _
+           ByVal BitsPerPixel As Long, _
+           ByVal RedMask As Long, _
+           ByVal GreenMask As Long, _
+           ByVal BlueMask As Long, _
+           ByVal TopDown As Long) As Long
 
-Private Declare Sub FreeImage_UnlockPageInt Lib "FreeImage.dll" Alias "_FreeImage_UnlockPage at 12" ( _
-           ByVal Bitmap As Long, _
-           ByVal PageBitmap As Long, _
-           ByVal ApplyChanges As Long)
+Private Declare Function FreeImage_ConvertFromRawBitsExInt Lib "FreeImage.dll" Alias "_FreeImage_ConvertFromRawBitsEx at 44" ( _
+           ByVal CopySource As Long, _
+           ByVal BitsPtr As Long, _
+           ByVal ImageType As FREE_IMAGE_TYPE, _
+           ByVal Width As Long, _
+           ByVal Height As Long, _
+           ByVal Pitch As Long, _
+           ByVal BitsPerPixel As Long, _
+           ByVal RedMask As Long, _
+           ByVal GreenMask As Long, _
+           ByVal BlueMask As Long, _
+           ByVal TopDown As Long) As Long
 
-Private Declare Function FreeImage_MovePageInt Lib "FreeImage.dll" Alias "_FreeImage_MovePage at 12" ( _
+Private Declare Sub FreeImage_ConvertToRawBitsInt Lib "FreeImage.dll" Alias "_FreeImage_ConvertToRawBits at 32" ( _
+           ByVal BitsPtr As Long, _
            ByVal Bitmap As Long, _
-           ByVal TargetPage As Long, _
-           ByVal SourcePage As Long) As Long
+           ByVal Pitch As Long, _
+           ByVal BitsPerPixel As Long, _
+           ByVal RedMask As Long, _
+           ByVal GreenMask As Long, _
+           ByVal BlueMask As Long, _
+           ByVal TopDown As Long)
 
-Private Declare Function FreeImage_GetLockedPageNumbersInt Lib "FreeImage.dll" Alias "_FreeImage_GetLockedPageNumbers at 12" ( _
-           ByVal Bitmap As Long, _
-           ByRef PagesPtr As Long, _
-           ByRef Count As Long) As Long
+Public Declare Function FreeImage_ConvertToFloat Lib "FreeImage.dll" Alias "_FreeImage_ConvertToFloat at 4" ( _
+           ByVal Bitmap As Long) As Long
 
+Public Declare Function FreeImage_ConvertToRGBF Lib "FreeImage.dll" Alias "_FreeImage_ConvertToRGBF at 4" ( _
+           ByVal Bitmap As Long) As Long
 
-' Memory I/O streams
-Public Declare Function FreeImage_OpenMemory Lib "FreeImage.dll" Alias "_FreeImage_OpenMemory at 8" ( _
-  Optional ByRef Data As Byte, _
-  Optional ByVal SizeInBytes As Long) As Long
-  
-Public Declare Function FreeImage_OpenMemoryByPtr Lib "FreeImage.dll" Alias "_FreeImage_OpenMemory at 8" ( _
-  Optional ByVal DataPtr As Long, _
-  Optional ByVal SizeInBytes As Long) As Long
+Public Declare Function FreeImage_ConvertToUINT16 Lib "FreeImage.dll" Alias "_FreeImage_ConvertToUINT16 at 4" ( _
+           ByVal Bitmap As Long) As Long
 
-Public Declare Sub FreeImage_CloseMemory Lib "FreeImage.dll" Alias "_FreeImage_CloseMemory at 4" ( _
-           ByVal Stream As Long)
+Public Declare Function FreeImage_ConvertToRGB16 Lib "FreeImage.dll" Alias "_FreeImage_ConvertToRGB16 at 4" ( _
+           ByVal Bitmap As Long) As Long
 
-Public Declare Function FreeImage_LoadFromMemory Lib "FreeImage.dll" Alias "_FreeImage_LoadFromMemory at 12" ( _
-           ByVal Format As FREE_IMAGE_FORMAT, _
-           ByVal Stream As Long, _
-  Optional ByVal Flags As FREE_IMAGE_LOAD_OPTIONS) As Long
+Private Declare Function FreeImage_ConvertToStandardTypeInt Lib "FreeImage.dll" Alias "_FreeImage_ConvertToStandardType at 8" ( _
+           ByVal Bitmap As Long, _
+           ByVal ScaleLinear As Long) As Long
 
-Private Declare Function FreeImage_SaveToMemoryInt Lib "FreeImage.dll" Alias "_FreeImage_SaveToMemory at 16" ( _
-           ByVal Format As FREE_IMAGE_FORMAT, _
+Private Declare Function FreeImage_ConvertToTypeInt Lib "FreeImage.dll" Alias "_FreeImage_ConvertToType at 12" ( _
            ByVal Bitmap As Long, _
-           ByVal Stream As Long, _
-  Optional ByVal Flags As FREE_IMAGE_SAVE_OPTIONS) As Long
+           ByVal DestinationType As FREE_IMAGE_TYPE, _
+           ByVal ScaleLinear As Long) As Long
 
-Private Declare Function FreeImage_AcquireMemoryInt Lib "FreeImage.dll" Alias "_FreeImage_AcquireMemory at 12" ( _
-           ByVal Stream As Long, _
-           ByRef DataPtr As Long, _
-           ByRef SizeInBytes As Long) As Long
 
-Public Declare Function FreeImage_TellMemory Lib "FreeImage.dll" Alias "_FreeImage_TellMemory at 4" ( _
-           ByVal Stream As Long) As Long
+' Tone mapping operators
+Public Declare Function FreeImage_ToneMapping Lib "FreeImage.dll" Alias "_FreeImage_ToneMapping at 24" ( _
+           ByVal Bitmap As Long, _
+           ByVal Operator As FREE_IMAGE_TMO, _
+  Optional ByVal FirstArgument As Double, _
+  Optional ByVal SecondArgument As Double) As Long
+  
+Public Declare Function FreeImage_TmoDrago03 Lib "FreeImage.dll" Alias "_FreeImage_TmoDrago03 at 20" ( _
+           ByVal Bitmap As Long, _
+  Optional ByVal Gamma As Double = 2.2, _
+  Optional ByVal Exposure As Double) As Long
+  
+Public Declare Function FreeImage_TmoReinhard05 Lib "FreeImage.dll" Alias "_FreeImage_TmoReinhard05 at 20" ( _
+           ByVal Bitmap As Long, _
+  Optional ByVal Intensity As Double, _
+  Optional ByVal Contrast As Double) As Long
 
-Private Declare Function FreeImage_SeekMemoryInt Lib "FreeImage.dll" Alias "_FreeImage_SeekMemory at 12" ( _
-           ByVal Stream As Long, _
-           ByVal Offset As Long, _
-           ByVal Origin As Long) As Long
-           
-Public Declare Function FreeImage_ReadMemory Lib "FreeImage.dll" Alias "_FreeImage_ReadMemory at 16" ( _
-           ByVal BufferPtr As Long, _
-           ByVal Size As Long, _
-           ByVal Count As Long, _
-           ByVal Stream As Long) As Long
-           
-Public Declare Function FreeImage_WriteMemory Lib "FreeImage.dll" Alias "_FreeImage_WriteMemory at 16" ( _
-           ByVal BufferPtr As Long, _
-           ByVal Size As Long, _
-           ByVal Count As Long, _
-           ByVal Stream As Long) As Long
-           
-Public Declare Function FreeImage_LoadMultiBitmapFromMemory Lib "FreeImage.dll" Alias "_FreeImage_LoadMultiBitmapFromMemory at 12" ( _
-           ByVal Format As FREE_IMAGE_FORMAT, _
-           ByVal Stream As Long, _
-  Optional ByVal Flags As FREE_IMAGE_LOAD_OPTIONS) As Long
+Public Declare Function FreeImage_TmoReinhard05Ex Lib "FreeImage.dll" Alias "_FreeImage_TmoReinhard05Ex at 36" ( _
+           ByVal Bitmap As Long, _
+  Optional ByVal Intensity As Double, _
+  Optional ByVal Contrast As Double, _
+  Optional ByVal Adaptation As Double = 1, _
+  Optional ByVal ColorCorrection As Double) As Long
 
-Public Declare Function FreeImage_SaveMultiBitmapToMemory Lib "FreeImage.dll" Alias "_FreeImage_SaveMultiBitmapToMemory at 16" ( _
-           ByVal Format As FREE_IMAGE_FORMAT, _
+Public Declare Function FreeImage_TmoFattal02 Lib "FreeImage.dll" Alias "_FreeImage_TmoFattal02 at 20" ( _
            ByVal Bitmap As Long, _
-           ByVal Stream As Long, _
-  Optional ByVal Flags As FREE_IMAGE_SAVE_OPTIONS) As Long
+  Optional ByVal ColorSaturation As Double = 0.5, _
+  Optional ByVal Attenuation As Double = 0.85) As Long
 
 
-' Compression functions
+' ZLib functions
 Public Declare Function FreeImage_ZLibCompress Lib "FreeImage.dll" Alias "_FreeImage_ZLibCompress at 16" ( _
            ByVal TargetPtr As Long, _
            ByVal TargetSize As Long, _
@@ -2682,27 +1859,11 @@ Public Declare Function FreeImage_ZLibCRC32 Lib "FreeImage.dll" Alias "_FreeImag
            ByVal SourceSize As Long) As Long
 
 
-' Helper functions
-Private Declare Function FreeImage_IsLittleEndianInt Lib "FreeImage.dll" Alias "_FreeImage_IsLittleEndian at 0" () As Long
-
-Private Declare Function FreeImage_LookupX11ColorInt Lib "FreeImage.dll" Alias "_FreeImage_LookupX11Color at 16" ( _
-           ByVal Color As String, _
-           ByRef red As Long, _
-           ByRef green As Long, _
-           ByRef blue As Long) As Long
-
-Private Declare Function FreeImage_LookupSVGColorInt Lib "FreeImage.dll" Alias "_FreeImage_LookupSVGColor at 16" ( _
-           ByVal Color As String, _
-           ByRef red As Long, _
-           ByRef green As Long, _
-           ByRef blue As Long) As Long
-
-
 '--------------------------------------------------------------------------------
 ' Metadata functions
 '--------------------------------------------------------------------------------
 
-' Tag creation and destruction
+' tag creation / destruction
 Private Declare Function FreeImage_CreateTag Lib "FreeImage.dll" Alias "_FreeImage_CreateTag at 0" () As Long
 
 Private Declare Sub FreeImage_DeleteTag Lib "FreeImage.dll" Alias "_FreeImage_DeleteTag at 4" ( _
@@ -2712,7 +1873,7 @@ Private Declare Function FreeImage_CloneTag Lib "FreeImage.dll" Alias "_FreeImag
            ByVal Tag As Long) As Long
 
 
-' Tag accessors (only those needed by wrapper functions)
+' tag getters and setters (only those actually needed by wrapper functions)
 Private Declare Function FreeImage_SetTagKey Lib "FreeImage.dll" Alias "_FreeImage_SetTagKey at 8" ( _
            ByVal Tag As Long, _
            ByVal Key As String) As Long
@@ -2721,7 +1882,8 @@ Private Declare Function FreeImage_SetTagValue Lib "FreeImage.dll" Alias "_FreeI
            ByVal Tag As Long, _
            ByVal ValuePtr As Long) As Long
 
-' Metadata iterator
+
+' metadata iterators
 Public Declare Function FreeImage_FindFirstMetadata Lib "FreeImage.dll" Alias "_FreeImage_FindFirstMetadata at 12" ( _
            ByVal Model As FREE_IMAGE_MDMODEL, _
            ByVal Bitmap As Long, _
@@ -2733,13 +1895,9 @@ Private Declare Function FreeImage_FindNextMetadataInt Lib "FreeImage.dll" Alias
 
 Public Declare Sub FreeImage_FindCloseMetadata Lib "FreeImage.dll" Alias "_FreeImage_FindCloseMetadata at 4" ( _
            ByVal hFind As Long)
-           
-Public Declare Function FreeImage_CloneMetadataInt Lib "FreeImage.dll" Alias "_FreeImage_CloneMetadata at 8" ( _
-           ByVal BitmapDst As Long, _
-           ByVal BitmapSrc As Long) As Long
 
 
-' Metadata accessors
+' metadata setters and getters
 Private Declare Function FreeImage_SetMetadataInt Lib "FreeImage.dll" Alias "_FreeImage_SetMetadata at 16" ( _
            ByVal Model As Long, _
            ByVal Bitmap As Long, _
@@ -2752,12 +1910,24 @@ Private Declare Function FreeImage_GetMetadataInt Lib "FreeImage.dll" Alias "_Fr
            ByVal Key As String, _
            ByRef Tag As Long) As Long
 
+Private Declare Function FreeImage_SetMetadataKeyValueInt Lib "FreeImage.dll" Alias "_FreeImage_SetMetadataKeyValue at 16" ( _
+           ByVal Model As Long, _
+           ByVal Bitmap As Long, _
+           ByVal Key As String, _
+           ByVal Tag As String) As Long
+
 
-' Metadata helper functions
+' metadata helper functions
 Public Declare Function FreeImage_GetMetadataCount Lib "FreeImage.dll" Alias "_FreeImage_GetMetadataCount at 8" ( _
            ByVal Model As Long, _
            ByVal Bitmap As Long) As Long
+           
+Public Declare Function FreeImage_CloneMetadataInt Lib "FreeImage.dll" Alias "_FreeImage_CloneMetadata at 8" ( _
+           ByVal BitmapDst As Long, _
+           ByVal BitmapSrc As Long) As Long
 
+
+' tag to string conversion functions
 Private Declare Function FreeImage_TagToStringInt Lib "FreeImage.dll" Alias "_FreeImage_TagToString at 12" ( _
            ByVal Model As Long, _
            ByVal Tag As Long, _
@@ -2765,10 +1935,73 @@ Private Declare Function FreeImage_TagToStringInt Lib "FreeImage.dll" Alias "_Fr
 
 
 '--------------------------------------------------------------------------------
-' Toolkit functions
+' JPEG lossless transformation functions
+'--------------------------------------------------------------------------------
+
+Private Declare Function FreeImage_JPEGTransformInt Lib "FreeImage.dll" Alias "_FreeImage_JPEGTransform at 16" ( _
+           ByVal SourceFile As String, _
+           ByVal DestFile As String, _
+           ByVal Operation As FREE_IMAGE_JPEG_OPERATION, _
+           ByVal Perfect As Long) As Long
+
+Private Declare Function FreeImage_JPEGTransformUInt Lib "FreeImage.dll" Alias "_FreeImage_JPEGTransformU at 16" ( _
+           ByVal SourceFile As Long, _
+           ByVal DestFile As Long, _
+           ByVal Operation As FREE_IMAGE_JPEG_OPERATION, _
+           ByVal Perfect As Long) As Long
+
+Private Declare Function FreeImage_JPEGCropInt Lib "FreeImage.dll" Alias "_FreeImage_JPEGCrop at 24" ( _
+           ByVal SourceFile As String, _
+           ByVal DestFile As String, _
+           ByVal Left As Long, _
+           ByVal Top As Long, _
+           ByVal Right As Long, _
+           ByVal Bottom As Long) As Long
+
+Private Declare Function FreeImage_JPEGCropUInt Lib "FreeImage.dll" Alias "_FreeImage_JPEGCropU at 24" ( _
+           ByVal SourceFile As Long, _
+           ByVal DestFile As Long, _
+           ByVal Left As Long, _
+           ByVal Top As Long, _
+           ByVal Right As Long, _
+           ByVal Bottom As Long) As Long
+
+Private Declare Function FreeImage_JPEGTransformCombinedInt Lib "FreeImage.dll" Alias "_FreeImage_JPEGTransformCombined at 32" ( _
+           ByVal SourceFile As String, _
+           ByVal DestFile As String, _
+           ByVal Operation As FREE_IMAGE_JPEG_OPERATION, _
+           ByRef Left As Long, _
+           ByRef Top As Long, _
+           ByRef Right As Long, _
+           ByRef Bottom As Long, _
+           ByVal Perfect As Long) As Long
+
+Private Declare Function FreeImage_JPEGTransformCombinedUInt Lib "FreeImage.dll" Alias "_FreeImage_JPEGTransformCombinedU at 32" ( _
+           ByVal SourceFile As Long, _
+           ByVal DestFile As Long, _
+           ByVal Operation As FREE_IMAGE_JPEG_OPERATION, _
+           ByRef Left As Long, _
+           ByRef Top As Long, _
+           ByRef Right As Long, _
+           ByRef Bottom As Long, _
+           ByVal Perfect As Long) As Long
+
+Private Declare Function FreeImage_JPEGTransformCombinedFromMemoryInt Lib "FreeImage.dll" Alias "_FreeImage_JPEGTransformCombinedFromMemory at 32" ( _
+           ByVal SourceStream As Long, _
+           ByVal DestStream As Long, _
+           ByVal Operation As FREE_IMAGE_JPEG_OPERATION, _
+           ByRef Left As Long, _
+           ByRef Top As Long, _
+           ByRef Right As Long, _
+           ByRef Bottom As Long, _
+           ByVal Perfect As Long) As Long
+
+
+'--------------------------------------------------------------------------------
+' Image manipulation toolkit functions
 '--------------------------------------------------------------------------------
 
-' Rotating and flipping
+' rotation and flipping
 Public Declare Function FreeImage_RotateClassic Lib "FreeImage.dll" Alias "_FreeImage_RotateClassic at 12" ( _
            ByVal Bitmap As Long, _
            ByVal Angle As Double) As Long
@@ -2776,7 +2009,7 @@ Public Declare Function FreeImage_RotateClassic Lib "FreeImage.dll" Alias "_Free
 Public Declare Function FreeImage_Rotate Lib "FreeImage.dll" Alias "_FreeImage_Rotate at 16" ( _
            ByVal Bitmap As Long, _
            ByVal Angle As Double, _
-  Optional ByRef Color As Any) As Long
+  Optional ByRef Color As Any = 0) As Long
 
 Private Declare Function FreeImage_RotateExInt Lib "FreeImage.dll" Alias "_FreeImage_RotateEx at 48" ( _
            ByVal Bitmap As Long, _
@@ -2792,21 +2025,9 @@ Private Declare Function FreeImage_FlipHorizontalInt Lib "FreeImage.dll" Alias "
 
 Private Declare Function FreeImage_FlipVerticalInt Lib "FreeImage.dll" Alias "_FreeImage_FlipVertical at 4" ( _
            ByVal Bitmap As Long) As Long
-           
-Private Declare Function FreeImage_JPEGTransformInt Lib "FreeImage.dll" Alias "_FreeImage_JPEGTransform at 16" ( _
-           ByVal SourceFile As String, _
-           ByVal DestFile As String, _
-           ByVal Operation As FREE_IMAGE_JPEG_OPERATION, _
-           ByVal Perfect As Long) As Long
-
-Private Declare Function FreeImage_JPEGTransformUInt Lib "FreeImage.dll" Alias "_FreeImage_JPEGTransformU at 16" ( _
-           ByVal SourceFile As Long, _
-           ByVal DestFile As Long, _
-           ByVal Operation As FREE_IMAGE_JPEG_OPERATION, _
-           ByVal Perfect As Long) As Long
 
 
-' Upsampling and downsampling
+' upsampling / downsampling
 Public Declare Function FreeImage_Rescale Lib "FreeImage.dll" Alias "_FreeImage_Rescale at 16" ( _
            ByVal Bitmap As Long, _
            ByVal Width As Long, _
@@ -2829,7 +2050,7 @@ Private Declare Function FreeImage_MakeThumbnailInt Lib "FreeImage.dll" Alias "_
   Optional ByVal Convert As Long) As Long
 
 
-' Color manipulation
+' color manipulation functions (point operations)
 Private Declare Function FreeImage_AdjustCurveInt Lib "FreeImage.dll" Alias "_FreeImage_AdjustCurve at 12" ( _
            ByVal Bitmap As Long, _
            ByVal LookupTablePtr As Long, _
@@ -2875,7 +2096,7 @@ Private Declare Function FreeImage_ApplyColorMappingInt Lib "FreeImage.dll" Alia
            ByVal DestinationColorsPtr As Long, _
            ByVal Count As Long, _
            ByVal IgnoreAlpha As Long, _
-           ByVal swap As Long) As Long
+           ByVal Swap As Long) As Long
   
 Private Declare Function FreeImage_SwapColorsInt Lib "FreeImage.dll" Alias "_FreeImage_SwapColors at 16" ( _
            ByVal Bitmap As Long, _
@@ -2889,19 +2110,19 @@ Private Declare Function FreeImage_SwapColorsByLongInt Lib "FreeImage.dll" Alias
            ByRef ColorB As Long, _
            ByVal IgnoreAlpha As Long) As Long
 
-Private Declare Function FreeImage_ApplyIndexMappingInt Lib "FreeImage.dll" Alias "_FreeImage_ApplyIndexMapping at 20" ( _
+Private Declare Function FreeImage_ApplyPaletteIndexMappingInt Lib "FreeImage.dll" Alias "_FreeImage_ApplyPaletteIndexMapping at 20" ( _
            ByVal Bitmap As Long, _
            ByVal SourceIndicesPtr As Long, _
            ByVal DestinationIndicesPtr As Long, _
            ByVal Count As Long, _
-           ByVal swap As Long) As Long
+           ByVal Swap As Long) As Long
 
 Public Declare Function FreeImage_SwapPaletteIndices Lib "FreeImage.dll" Alias "_FreeImage_SwapPaletteIndices at 12" ( _
            ByVal Bitmap As Long, _
            ByRef IndexA As Byte, _
            ByRef IndexB As Byte) As Long
 
-' Channel processing
+' channel processing functions
 Public Declare Function FreeImage_GetChannel Lib "FreeImage.dll" Alias "_FreeImage_GetChannel at 8" ( _
            ByVal Bitmap As Long, _
            ByVal Channel As FREE_IMAGE_COLOR_CHANNEL) As Long
@@ -2921,46 +2142,31 @@ Private Declare Function FreeImage_SetComplexChannelInt Lib "FreeImage.dll" Alia
            ByVal Channel As FREE_IMAGE_COLOR_CHANNEL) As Long
 
 
-' Copy / Paste / Composite routines
+' copy / paste / composite functions
 Public Declare Function FreeImage_Copy Lib "FreeImage.dll" Alias "_FreeImage_Copy at 20" ( _
-           ByVal Bitmap As Long, _
-           ByVal Left As Long, _
-           ByVal Top As Long, _
-           ByVal Right As Long, _
-           ByVal Bottom As Long) As Long
-
-Private Declare Function FreeImage_PasteInt Lib "FreeImage.dll" Alias "_FreeImage_Paste at 20" ( _
-           ByVal BitmapDst As Long, _
-           ByVal BitmapSrc As Long, _
-           ByVal Left As Long, _
-           ByVal Top As Long, _
-           ByVal Alpha As Long) As Long
-
-Public Declare Function FreeImage_Composite Lib "FreeImage.dll" Alias "_FreeImage_Composite at 16" ( _
-           ByVal Bitmap As Long, _
-  Optional ByVal UseFileBackColor As Long, _
-  Optional ByRef AppBackColor As Any, _
-  Optional ByVal BackgroundBitmap As Long) As Long
-  
-Private Declare Function FreeImage_JPEGCropInt Lib "FreeImage.dll" Alias "_FreeImage_JPEGCrop at 24" ( _
-           ByVal SourceFile As String, _
-           ByVal DestFile As String, _
-           ByVal Left As Long, _
-           ByVal Top As Long, _
-           ByVal Right As Long, _
-           ByVal Bottom As Long) As Long
-
-Private Declare Function FreeImage_JPEGCropUInt Lib "FreeImage.dll" Alias "_FreeImage_JPEGCropU at 24" ( _
-           ByVal SourceFile As Long, _
-           ByVal DestFile As Long, _
+           ByVal Bitmap As Long, _
            ByVal Left As Long, _
            ByVal Top As Long, _
            ByVal Right As Long, _
            ByVal Bottom As Long) As Long
 
+Private Declare Function FreeImage_PasteInt Lib "FreeImage.dll" Alias "_FreeImage_Paste at 20" ( _
+           ByVal BitmapDst As Long, _
+           ByVal BitmapSrc As Long, _
+           ByVal Left As Long, _
+           ByVal Top As Long, _
+           ByVal Alpha As Long) As Long
+
+Public Declare Function FreeImage_Composite Lib "FreeImage.dll" Alias "_FreeImage_Composite at 16" ( _
+           ByVal Bitmap As Long, _
+  Optional ByVal UseFileBackColor As Long, _
+  Optional ByRef AppBackColor As Any, _
+  Optional ByVal BackgroundBitmap As Long) As Long
+
 Private Declare Function FreeImage_PreMultiplyWithAlphaInt Lib "FreeImage.dll" Alias "_FreeImage_PreMultiplyWithAlpha at 4" ( _
            ByVal Bitmap As Long) As Long
-           
+
+' background filling functions
 Public Declare Function FreeImage_FillBackground Lib "FreeImage.dll" Alias "_FreeImage_FillBackground at 12" ( _
            ByVal Bitmap As Long, _
            ByRef Color As Any, _
@@ -3004,213 +2210,6 @@ Public Declare Function FreeImage_MultigridPoissonSolver Lib "FreeImage.dll" Ali
   Optional ByVal Cyles As Long = 3) As Long
 
 
-'--------------------------------------------------------------------------------
-' Line converting functions
-'--------------------------------------------------------------------------------
-
-' convert to 4 bpp
-Public Declare Sub FreeImage_ConvertLine1To4 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine1To4 at 12" ( _
-           ByVal TargetPtr As Long, _
-           ByVal SourcePtr As Long, _
-           ByVal WidthInPixels As Long)
-           
-Public Declare Sub FreeImage_ConvertLine8To4 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine1To8 at 16" ( _
-           ByVal TargetPtr As Long, _
-           ByVal SourcePtr As Long, _
-           ByVal WidthInPixels As Long, _
-           ByVal PalettePtr As Long)
-           
-Public Declare Sub FreeImage_ConvertLine16To4_555 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine16To4_555 at 12" ( _
-           ByVal TargetPtr As Long, _
-           ByVal SourcePtr As Long, _
-           ByVal WidthInPixels As Long)
-                     
-Public Declare Sub FreeImage_ConvertLine16To4_565 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine16To4_565 at 12" ( _
-           ByVal TargetPtr As Long, _
-           ByVal SourcePtr As Long, _
-           ByVal WidthInPixels As Long)
-           
-Public Declare Sub FreeImage_ConvertLine24To4 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine1To24 at 12" ( _
-           ByVal TargetPtr As Long, _
-           ByVal SourcePtr As Long, _
-           ByVal WidthInPixels As Long)
-           
-Public Declare Sub FreeImage_ConvertLine32To4 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine32To4 at 12" ( _
-           ByVal TargetPtr As Long, _
-           ByVal SourcePtr As Long, _
-           ByVal WidthInPixels As Long)
-
-
-' convert to 8 bpp
-Public Declare Sub FreeImage_ConvertLine1To8 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine1To8 at 12" ( _
-           ByVal TargetPtr As Long, _
-           ByVal SourcePtr As Long, _
-           ByVal WidthInPixels As Long)
-
-Public Declare Sub FreeImage_ConvertLine4To8 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine4To8 at 12" ( _
-           ByVal TargetPtr As Long, _
-           ByVal SourcePtr As Long, _
-           ByVal WidthInPixels As Long)
-
-Public Declare Sub FreeImage_ConvertLine16To8_555 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine16To8_555 at 12" ( _
-           ByVal TargetPtr As Long, _
-           ByVal SourcePtr As Long, _
-           ByVal WidthInPixels As Long)
-
-Public Declare Sub FreeImage_ConvertLine16To8_565 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine16To8_565 at 12" ( _
-           ByVal TargetPtr As Long, _
-           ByVal SourcePtr As Long, _
-           ByVal WidthInPixels As Long)
-
-Public Declare Sub FreeImage_ConvertLine24To8 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine24To8 at 12" ( _
-           ByVal TargetPtr As Long, _
-           ByVal SourcePtr As Long, _
-           ByVal WidthInPixels As Long)
-
-Public Declare Sub FreeImage_ConvertLine32To8 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine32To8 at 12" ( _
-           ByVal TargetPtr As Long, _
-           ByVal SourcePtr As Long, _
-           ByVal WidthInPixels As Long)
-           
-
-' convert to 16 bpp
-Public Declare Sub FreeImage_ConvertLine1To16_555 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine1To16_555 at 16" ( _
-           ByVal TargetPtr As Long, _
-           ByVal SourcePtr As Long, _
-           ByVal WidthInPixels As Long, _
-           ByVal PalettePtr As Long)
-
-Public Declare Sub FreeImage_ConvertLine4To16_555 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine4To16_555 at 16" ( _
-           ByVal TargetPtr As Long, _
-           ByVal SourcePtr As Long, _
-           ByVal WidthInPixels As Long, _
-           ByVal PalettePtr As Long)
-
-Public Declare Sub FreeImage_ConvertLine8To16_555 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine8To16_555 at 16" ( _
-           ByVal TargetPtr As Long, _
-           ByVal SourcePtr As Long, _
-           ByVal WidthInPixels As Long, _
-           ByVal PalettePtr As Long)
-
-Public Declare Sub FreeImage_ConvertLine16_565_To16_555 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine16_565_To16_555 at 12" ( _
-           ByVal TargetPtr As Long, _
-           ByVal SourcePtr As Long, _
-           ByVal WidthInPixels As Long)
-
-Public Declare Sub FreeImage_ConvertLine24To16_555 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine24To16_555 at 12" ( _
-           ByVal TargetPtr As Long, _
-           ByVal SourcePtr As Long, _
-           ByVal WidthInPixels As Long)
-
-Public Declare Sub FreeImage_ConvertLine32To16_555 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine32To16_555 at 12" ( _
-           ByVal TargetPtr As Long, _
-           ByVal SourcePtr As Long, _
-           ByVal WidthInPixels As Long)
-
-Public Declare Sub FreeImage_ConvertLine1To16_565 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine1To16_565 at 16" ( _
-           ByVal TargetPtr As Long, _
-           ByVal SourcePtr As Long, _
-           ByVal WidthInPixels As Long, _
-           ByVal PalettePtr As Long)
-
-Public Declare Sub FreeImage_ConvertLine4To16_565 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine4To16_565 at 16" ( _
-           ByVal TargetPtr As Long, _
-           ByVal SourcePtr As Long, _
-           ByVal WidthInPixels As Long, _
-           ByVal PalettePtr As Long)
-
-Public Declare Sub FreeImage_ConvertLine8To16_565 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine8To16_565 at 16" ( _
-           ByVal TargetPtr As Long, _
-           ByVal SourcePtr As Long, _
-           ByVal WidthInPixels As Long, _
-           ByVal PalettePtr As Long)
-
-Public Declare Sub FreeImage_ConvertLine16_555_To16_565 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine16_555_To16_565 at 12" ( _
-           ByVal TargetPtr As Long, _
-           ByVal SourcePtr As Long, _
-           ByVal WidthInPixels As Long)
-
-Public Declare Sub FreeImage_ConvertLine24To16_565 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine24To16_565 at 12" ( _
-           ByVal TargetPtr As Long, _
-           ByVal SourcePtr As Long, _
-           ByVal WidthInPixels As Long)
-
-Public Declare Sub FreeImage_ConvertLine32To16_565 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine32To16_565 at 12" ( _
-           ByVal TargetPtr As Long, _
-           ByVal SourcePtr As Long, _
-           ByVal WidthInPixels As Long)
-
-
-' convert to 24 bpp
-Public Declare Sub FreeImage_ConvertLine1To24 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine1To24 at 16" ( _
-           ByVal TargetPtr As Long, _
-           ByVal SourcePtr As Long, _
-           ByVal WidthInPixels As Long, _
-           ByVal PalettePtr As Long)
-
-Public Declare Sub FreeImage_ConvertLine4To24 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine4To24 at 16" ( _
-           ByVal TargetPtr As Long, _
-           ByVal SourcePtr As Long, _
-           ByVal WidthInPixels As Long, _
-           ByVal PalettePtr As Long)
-
-Public Declare Sub FreeImage_ConvertLine8To24 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine8To24 at 16" ( _
-           ByVal TargetPtr As Long, _
-           ByVal SourcePtr As Long, _
-           ByVal WidthInPixels As Long, _
-           ByVal PalettePtr As Long)
-
-Public Declare Sub FreeImage_ConvertLine16To24_555 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine16To24_555 at 12" ( _
-           ByVal TargetPtr As Long, _
-           ByVal SourcePtr As Long, _
-           ByVal WidthInPixels As Long)
-
-Public Declare Sub FreeImage_ConvertLine16To24_565 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine16To24_565 at 12" ( _
-           ByVal TargetPtr As Long, _
-           ByVal SourcePtr As Long, _
-           ByVal WidthInPixels As Long)
-
-Public Declare Sub FreeImage_ConvertLine32To24 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine32To24 at 12" ( _
-           ByVal TargetPtr As Long, _
-           ByVal SourcePtr As Long, _
-           ByVal WidthInPixels As Long)
-
-
-' convert to 32 bpp
-Public Declare Sub FreeImage_ConvertLine1To32 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine1To32 at 16" ( _
-           ByVal TargetPtr As Long, _
-           ByVal SourcePtr As Long, _
-           ByVal WidthInPixels As Long, _
-           ByVal PalettePtr As Long)
-
-Public Declare Sub FreeImage_ConvertLine4To32 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine4To32 at 16" ( _
-           ByVal TargetPtr As Long, _
-           ByVal SourcePtr As Long, _
-           ByVal WidthInPixels As Long, _
-           ByVal PalettePtr As Long)
-
-Public Declare Sub FreeImage_ConvertLine8To32 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine8To32 at 16" ( _
-           ByVal TargetPtr As Long, _
-           ByVal SourcePtr As Long, _
-           ByVal WidthInPixels As Long, _
-           ByVal PalettePtr As Long)
-
-Public Declare Sub FreeImage_ConvertLine16To32_555 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine16To32_555 at 12" ( _
-           ByVal TargetPtr As Long, _
-           ByVal SourcePtr As Long, _
-           ByVal WidthInPixels As Long)
-
-Public Declare Sub FreeImage_ConvertLine16To32_565 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine16To32_565 at 12" ( _
-           ByVal TargetPtr As Long, _
-           ByVal SourcePtr As Long, _
-           ByVal WidthInPixels As Long)
-
-Public Declare Sub FreeImage_ConvertLine24To32 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine24To32 at 12" ( _
-           ByVal TargetPtr As Long, _
-           ByVal SourcePtr As Long, _
-           ByVal WidthInPixels As Long)
-          
-          
 
 '--------------------------------------------------------------------------------
 ' Initialization functions
@@ -3247,8 +2246,8 @@ Dim strImageFormat As String
 
    ' This function is called whenever the FreeImage 3 libraray throws an error.
    ' Currently this function gets the error message and the format name of the
-   ' involved image type as VB string printing each to the VB Debug console. Feel
-   ' free to modify this function to call an error handling routine of your on.
+   ' involved image type as VB string and prints both to the VB Debug console. Feel
+   ' free to modify this function to call an error handling routine of your own.
 
    strErrorMessage = pGetStringFromPointerA(Message)
    strImageFormat = FreeImage_GetFormatFromFIF(Format)
@@ -3268,8 +2267,7 @@ End Sub
 Public Function FreeImage_GetVersion() As String
 
    ' This function returns the version of the FreeImage 3 library
-   ' as VB String. Read paragraph 2 of the "General notes on implementation
-   ' and design" section to learn more about that technique.
+   ' as VB String.
    
    FreeImage_GetVersion = pGetStringFromPointerA(FreeImage_GetVersionInt)
 
@@ -3278,8 +2276,7 @@ End Function
 Public Function FreeImage_GetCopyrightMessage() As String
 
    ' This function returns the copyright message of the FreeImage 3 library
-   ' as VB String. Read paragraph 2 of the "General notes on implementation
-   ' and design" section to learn more about that technique.
+   ' as VB String.
    
    FreeImage_GetCopyrightMessage = pGetStringFromPointerA(FreeImage_GetCopyrightMessageInt)
 
@@ -3288,8 +2285,7 @@ End Function
 Public Function FreeImage_GetFormatFromFIF(ByVal Format As FREE_IMAGE_FORMAT) As String
 
    ' This function returns the result of the 'FreeImage_GetFormatFromFIF' function
-   ' as VB String. Read paragraph 2 of the "General notes on implementation
-   ' and design" section to learn more about that technique.
+   ' as VB String.
    
    ' The parameter 'Format' works according to the FreeImage 3 API documentation.
    
@@ -3300,8 +2296,7 @@ End Function
 Public Function FreeImage_GetFIFExtensionList(ByVal Format As FREE_IMAGE_FORMAT) As String
 
    ' This function returns the result of the 'FreeImage_GetFIFExtensionList' function
-   ' as VB String. Read paragraph 2 of the "General notes on implementation
-   ' and design" section to learn more about that technique.
+   ' as VB String.
    
    ' The parameter 'Format' works according to the FreeImage 3 API documentation.
    
@@ -3312,8 +2307,7 @@ End Function
 Public Function FreeImage_GetFIFDescription(ByVal Format As FREE_IMAGE_FORMAT) As String
 
    ' This function returns the result of the 'FreeImage_GetFIFDescription' function
-   ' as VB String. Read paragraph 2 of the "General notes on implementation
-   ' and design" section to learn more about that technique.
+   ' as VB String.
    
    ' The parameter 'Format' works according to the FreeImage 3 API documentation.
    
@@ -3324,8 +2318,7 @@ End Function
 Public Function FreeImage_GetFIFRegExpr(ByVal Format As FREE_IMAGE_FORMAT) As String
 
    ' This function returns the result of the 'FreeImage_GetFIFRegExpr' function
-   ' as VB String. Read paragraph 2 of the "General notes on implementation
-   ' and design" section to learn more about that technique.
+   ' as VB String.
    
    ' The parameter 'Format' works according to the FreeImage 3 API documentation.
    
@@ -3336,8 +2329,7 @@ End Function
 Public Function FreeImage_GetFIFMimeType(ByVal Format As FREE_IMAGE_FORMAT) As String
    
    ' This function returns the result of the 'FreeImage_GetFIFMimeType' function
-   ' as VB String. Read paragraph 2 of the "General notes on implementation
-   ' and design" section to learn more about that technique.
+   ' as VB String.
    
    ' The parameter 'Format' works according to the FreeImage 3 API documentation.
    
@@ -3350,8 +2342,7 @@ Public Function FreeImage_TagToString(ByVal Model As Long, _
                              Optional ByVal Make As String) As String
 
    ' This function returns the result of the 'FreeImage_TagToString' function
-   ' as VB String. Read paragraph 2 of the "General notes on implementation
-   ' and design" section to learn more about that technique.
+   ' as VB String.
    
    ' All parameters work according to the FreeImage 3 API documentation.
 
@@ -3415,57 +2406,29 @@ Public Function FreeImage_GetFIFFromFilenameU(ByVal Filename As String) As FREE_
 
 End Function
 
-Public Function FreeImage_JPEGTransformU(ByVal SourceFile As String, _
-                                         ByVal DestFile As String, _
-                                         ByVal Operation As FREE_IMAGE_JPEG_OPERATION, _
-                                Optional ByVal Perfect As Boolean) As Boolean
-                               
-Dim lPerfect As Long
-                               
-   ' This function is just a thin wrapper to ease the call to an
-   ' UNICODE function. Since VB's BSTR strings are actually UNICODE
-   ' strings, we just need to pass the pointer to the string data
-   ' returned by the (undocumented) function StrPtr().
 
-   If (Perfect) Then
-      lPerfect = 1
-   End If
-   FreeImage_JPEGTransformU = (FreeImage_JPEGTransformInt(StrPtr(SourceFile), StrPtr(DestFile), _
-         Operation, lPerfect) = 1)
 
-End Function
+'--------------------------------------------------------------------------------
+' Boolean returning functions wrappers
+'--------------------------------------------------------------------------------
 
-Public Function FreeImage_JPEGCropU(ByVal SourceFile As String, _
-                                    ByVal DestFile As String, _
-                                    ByVal Left As Long, _
-                                    ByVal Top As Long, _
-                                    ByVal Right As Long, _
-                                    ByVal Bottom As Long) As Boolean
-                                   
-   ' This function is just a thin wrapper to ease the call to an
-   ' UNICODE function. Since VB's BSTR strings are actually UNICODE
-   ' strings, we just need to pass the pointer to the string data
-   ' returned by the (undocumented) function StrPtr().
-   
-   FreeImage_JPEGCropU = (FreeImage_JPEGCropInt(StrPtr(SourceFile), StrPtr(DestFile), Left, Top, _
-         Right, Bottom) = 1)
-                                   
-End Function
+Public Function FreeImage_HasPixels(ByVal Bitmap As Long) As Boolean
 
+   ' Thin wrapper function returning a real VB Boolean value
 
+   FreeImage_HasPixels = (FreeImage_HasPixelsInt(Bitmap) = 1)
 
-'--------------------------------------------------------------------------------
-' BOOL/Boolean returning functions wrappers
-'--------------------------------------------------------------------------------
+End Function
 
-Public Function FreeImage_HasPixels(ByVal Bitmap As Long) As Boolean
+Public Function FreeImage_HasRGBMasks(ByVal Bitmap As Long) As Boolean
 
    ' Thin wrapper function returning a real VB Boolean value
 
-   FreeImage_HasPixels = (FreeImage_HasPixelsInt(Bitmap) = 1)
+   FreeImage_HasRGBMasks = (FreeImage_HasRGBMasksInt(Bitmap) = 1)
 
 End Function
 
+
 Public Function FreeImage_Save(ByVal Format As FREE_IMAGE_FORMAT, _
                                ByVal Bitmap As Long, _
                                ByVal Filename As String, _
@@ -3536,9 +2499,9 @@ End Function
 
 Public Function FreeImage_GetBackgroundColorEx(ByVal Bitmap As Long, _
                                                ByRef Alpha As Byte, _
-                                               ByRef red As Byte, _
-                                               ByRef green As Byte, _
-                                               ByRef blue As Byte) As Boolean
+                                               ByRef Red As Byte, _
+                                               ByRef Green As Byte, _
+                                               ByRef Blue As Byte) As Boolean
                                               
 Dim bkcolor As RGBQUAD
 
@@ -3548,9 +2511,9 @@ Dim bkcolor As RGBQUAD
    FreeImage_GetBackgroundColorEx = (FreeImage_GetBackgroundColorInt(Bitmap, bkcolor) = 1)
    With bkcolor
       Alpha = .rgbReserved
-      red = .rgbRed
-      green = .rgbGreen
-      blue = .rgbBlue
+      Red = .rgbRed
+      Green = .rgbGreen
+      Blue = .rgbBlue
    End With
 
 End Function
@@ -3576,9 +2539,9 @@ End Function
 
 Public Function FreeImage_SetBackgroundColorEx(ByVal Bitmap As Long, _
                                                ByVal Alpha As Byte, _
-                                               ByVal red As Byte, _
-                                               ByVal green As Byte, _
-                                               ByVal blue As Byte) As Boolean
+                                               ByVal Red As Byte, _
+                                               ByVal Green As Byte, _
+                                               ByVal Blue As Byte) As Boolean
                                               
 Dim tColor As RGBQUAD
 
@@ -3588,112 +2551,112 @@ Dim tColor As RGBQUAD
                                              
    With tColor
       .rgbReserved = Alpha
-      .rgbRed = red
-      .rgbGreen = green
-      .rgbBlue = blue
+      .rgbRed = Red
+      .rgbGreen = Green
+      .rgbBlue = Blue
    End With
    FreeImage_SetBackgroundColorEx = (FreeImage_SetBackgroundColorInt(Bitmap, tColor) = 1)
 
 End Function
 
 Public Function FreeImage_GetPixelIndex(ByVal Bitmap As Long, _
-                                        ByVal X As Long, _
-                                        ByVal Y As Long, _
+                                        ByVal x As Long, _
+                                        ByVal y As Long, _
                                         ByRef Value As Byte) As Boolean
 
    ' Thin wrapper function returning a real VB Boolean value
 
-   FreeImage_GetPixelIndex = (FreeImage_GetPixelIndexInt(Bitmap, X, Y, Value) = 1)
+   FreeImage_GetPixelIndex = (FreeImage_GetPixelIndexInt(Bitmap, x, y, Value) = 1)
 
 End Function
 
 Public Function FreeImage_GetPixelColor(ByVal Bitmap As Long, _
-                                        ByVal X As Long, _
-                                        ByVal Y As Long, _
+                                        ByVal x As Long, _
+                                        ByVal y As Long, _
                                         ByRef Value As RGBQUAD) As Boolean
                                         
    ' Thin wrapper function returning a real VB Boolean value
 
-   FreeImage_GetPixelColor = (FreeImage_GetPixelColorInt(Bitmap, X, Y, Value) = 1)
+   FreeImage_GetPixelColor = (FreeImage_GetPixelColorInt(Bitmap, x, y, Value) = 1)
 
 End Function
            
 Public Function FreeImage_GetPixelColorByLong(ByVal Bitmap As Long, _
-                                              ByVal X As Long, _
-                                              ByVal Y As Long, _
+                                              ByVal x As Long, _
+                                              ByVal y As Long, _
                                               ByRef Value As Long) As Boolean
                                               
    ' This function gets the color at position (x|y) as FreeImage_GetPixelColor() does but
    ' provides it's result as a Long value.
                                               
-   FreeImage_GetPixelColorByLong = (FreeImage_GetPixelColorByLongInt(Bitmap, X, Y, Value) = 1)
+   FreeImage_GetPixelColorByLong = (FreeImage_GetPixelColorByLongInt(Bitmap, x, y, Value) = 1)
 
 End Function
 
 Public Function FreeImage_GetPixelColorEx(ByVal Bitmap As Long, _
-                                          ByVal X As Long, _
-                                          ByVal Y As Long, _
+                                          ByVal x As Long, _
+                                          ByVal y As Long, _
                                           ByRef Alpha As Byte, _
-                                          ByRef red As Byte, _
-                                          ByRef green As Byte, _
-                                          ByRef blue As Byte) As Boolean
+                                          ByRef Red As Byte, _
+                                          ByRef Green As Byte, _
+                                          ByRef Blue As Byte) As Boolean
                                               
 Dim Value As RGBQUAD
 
    ' This function gets the color at position (x|y) as FreeImage_GetPixelColor() does but
    ' provides it's result as four different byte values, one for each color component.
                                               
-   FreeImage_GetPixelColorEx = (FreeImage_GetPixelColorInt(Bitmap, X, Y, Value) = 1)
+   FreeImage_GetPixelColorEx = (FreeImage_GetPixelColorInt(Bitmap, x, y, Value) = 1)
    With Value
       Alpha = .rgbReserved
-      red = .rgbRed
-      green = .rgbGreen
-      blue = .rgbBlue
+      Red = .rgbRed
+      Green = .rgbGreen
+      Blue = .rgbBlue
    End With
 
 End Function
 
 Public Function FreeImage_SetPixelIndex(ByVal Bitmap As Long, _
-                                        ByVal X As Long, _
-                                        ByVal Y As Long, _
+                                        ByVal x As Long, _
+                                        ByVal y As Long, _
                                         ByRef Value As Byte) As Boolean
                                         
    ' Thin wrapper function returning a real VB Boolean value
 
-   FreeImage_SetPixelIndex = (FreeImage_SetPixelIndexInt(Bitmap, X, Y, Value) = 1)
+   FreeImage_SetPixelIndex = (FreeImage_SetPixelIndexInt(Bitmap, x, y, Value) = 1)
 
 End Function
 
 Public Function FreeImage_SetPixelColor(ByVal Bitmap As Long, _
-                                        ByVal X As Long, _
-                                        ByVal Y As Long, _
+                                        ByVal x As Long, _
+                                        ByVal y As Long, _
                                         ByRef Value As RGBQUAD) As Boolean
                                         
    ' Thin wrapper function returning a real VB Boolean value
                                         
-   FreeImage_SetPixelColor = (FreeImage_SetPixelColorInt(Bitmap, X, Y, Value) = 1)
+   FreeImage_SetPixelColor = (FreeImage_SetPixelColorInt(Bitmap, x, y, Value) = 1)
 
 End Function
            
 Public Function FreeImage_SetPixelColorByLong(ByVal Bitmap As Long, _
-                                              ByVal X As Long, _
-                                              ByVal Y As Long, _
+                                              ByVal x As Long, _
+                                              ByVal y As Long, _
                                               ByRef Value As Long) As Boolean
                                               
    ' This function sets the color at position (x|y) as FreeImage_SetPixelColor() does but
    ' the color value to set must be provided as a Long value.
    
-   FreeImage_SetPixelColorByLong = (FreeImage_SetPixelColorByLongInt(Bitmap, X, Y, Value) = 1)
+   FreeImage_SetPixelColorByLong = (FreeImage_SetPixelColorByLongInt(Bitmap, x, y, Value) = 1)
 
 End Function
 
 Public Function FreeImage_SetPixelColorEx(ByVal Bitmap As Long, _
-                                          ByVal X As Long, _
-                                          ByVal Y As Long, _
+                                          ByVal x As Long, _
+                                          ByVal y As Long, _
                                           ByVal Alpha As Byte, _
-                                          ByVal red As Byte, _
-                                          ByVal green As Byte, _
-                                          ByVal blue As Byte) As Boolean
+                                          ByVal Red As Byte, _
+                                          ByVal Green As Byte, _
+                                          ByVal Blue As Byte) As Boolean
                                               
 Dim Value As RGBQUAD
 
@@ -3703,11 +2666,11 @@ Dim Value As RGBQUAD
                                              
    With Value
       .rgbReserved = Alpha
-      .rgbRed = red
-      .rgbGreen = green
-      .rgbBlue = blue
+      .rgbRed = Red
+      .rgbGreen = Green
+      .rgbBlue = Blue
    End With
-   FreeImage_SetPixelColorEx = (FreeImage_SetPixelColorInt(Bitmap, X, Y, Value) = 1)
+   FreeImage_SetPixelColorEx = (FreeImage_SetPixelColorInt(Bitmap, x, y, Value) = 1)
 
 End Function
 
@@ -3830,24 +2793,24 @@ Public Function FreeImage_IsLittleEndian() As Boolean
 End Function
 
 Public Function FreeImage_LookupX11Color(ByVal Color As String, _
-                                         ByRef red As Long, _
-                                         ByRef green As Long, _
-                                         ByRef blue As Long) As Boolean
+                                         ByRef Red As Long, _
+                                         ByRef Green As Long, _
+                                         ByRef Blue As Long) As Boolean
                                          
    ' Thin wrapper function returning a real VB Boolean value
 
-   FreeImage_LookupX11Color = (FreeImage_LookupX11ColorInt(Color, red, green, blue) = 1)
+   FreeImage_LookupX11Color = (FreeImage_LookupX11ColorInt(Color, Red, Green, Blue) = 1)
            
 End Function
 
 Public Function FreeImage_LookupSVGColor(ByVal Color As String, _
-                                         ByRef red As Long, _
-                                         ByRef green As Long, _
-                                         ByRef blue As Long) As Boolean
+                                         ByRef Red As Long, _
+                                         ByRef Green As Long, _
+                                         ByRef Blue As Long) As Boolean
                                          
    ' Thin wrapper function returning a real VB Boolean value
 
-   FreeImage_LookupSVGColor = (FreeImage_LookupSVGColorInt(Color, red, green, blue) = 1)
+   FreeImage_LookupSVGColor = (FreeImage_LookupSVGColorInt(Color, Red, Green, Blue) = 1)
          
 End Function
 
@@ -3869,7 +2832,7 @@ Public Function FreeImage_CloneMetadata(ByVal BitmapDst As Long, _
                                            
 End Function
 
-Public Function FreeImage_GetMetadata(ByRef Model As Long, _
+Public Function FreeImage_GetMetadata(ByVal Model As Long, _
                                       ByVal Bitmap As Long, _
                                       ByVal Key As String, _
                                       ByVal Tag As Long) As Boolean
@@ -3880,7 +2843,7 @@ Public Function FreeImage_GetMetadata(ByRef Model As Long, _
                                       
 End Function
 
-Public Function FreeImage_SetMetadata(ByRef Model As Long, _
+Public Function FreeImage_SetMetadata(ByVal Model As Long, _
                                       ByVal Bitmap As Long, _
                                       ByVal Key As String, _
                                       ByVal Tag As Long) As Boolean
@@ -3891,6 +2854,17 @@ Public Function FreeImage_SetMetadata(ByRef Model As Long, _
                                       
 End Function
 
+Public Function FreeImage_SetMetadataKeyValue(ByVal Model As Long, _
+                                              ByVal Bitmap As Long, _
+                                              ByVal Key As String, _
+                                              ByVal Value As String) As Boolean
+                                      
+   ' Thin wrapper function returning a real VB Boolean value
+
+   FreeImage_SetMetadataKeyValue = (FreeImage_SetMetadataKeyValueInt(Model, Bitmap, Key, Value) = 1)
+                                      
+End Function
+
 Public Function FreeImage_FlipHorizontal(ByVal Bitmap As Long) As Boolean
 
    ' Thin wrapper function returning a real VB Boolean value
@@ -3910,7 +2884,7 @@ End Function
 Public Function FreeImage_JPEGTransform(ByVal SourceFile As String, _
                                         ByVal DestFile As String, _
                                         ByVal Operation As FREE_IMAGE_JPEG_OPERATION, _
-                               Optional ByVal Perfect As Boolean) As Boolean
+                               Optional ByVal Perfect As Boolean = True) As Boolean
                                
 Dim lPerfect As Long
                                
@@ -3923,6 +2897,128 @@ Dim lPerfect As Long
 
 End Function
 
+Public Function FreeImage_JPEGTransformU(ByVal SourceFile As String, _
+                                         ByVal DestFile As String, _
+                                         ByVal Operation As FREE_IMAGE_JPEG_OPERATION, _
+                                Optional ByVal Perfect As Boolean = True) As Boolean
+                               
+Dim lPerfect As Long
+                               
+   ' Thin wrapper function returning a real VB Boolean value
+   
+   ' This function is also a thin wrapper to ease the call to an
+   ' UNICODE function. Since VB's BSTR strings are actually UNICODE
+   ' strings, we just need to pass the pointer to the string data
+   ' returned by the (undocumented) function StrPtr().
+
+   If (Perfect) Then
+      lPerfect = 1
+   End If
+   FreeImage_JPEGTransformU = (FreeImage_JPEGTransformInt(StrPtr(SourceFile), StrPtr(DestFile), _
+         Operation, lPerfect) = 1)
+
+End Function
+
+Public Function FreeImage_JPEGCrop(ByVal SourceFile As String, _
+                                   ByVal DestFile As String, _
+                                   ByVal Left As Long, _
+                                   ByVal Top As Long, _
+                                   ByVal Right As Long, _
+                                   ByVal Bottom As Long) As Boolean
+                                   
+   ' Thin wrapper function returning a real VB Boolean value
+   
+   FreeImage_JPEGCrop = (FreeImage_JPEGCropInt(SourceFile, DestFile, Left, Top, Right, Bottom) = 1)
+                                   
+End Function
+
+Public Function FreeImage_JPEGCropU(ByVal SourceFile As String, _
+                                    ByVal DestFile As String, _
+                                    ByVal Left As Long, _
+                                    ByVal Top As Long, _
+                                    ByVal Right As Long, _
+                                    ByVal Bottom As Long) As Boolean
+                                   
+   ' Thin wrapper function returning a real VB Boolean value
+   
+   ' This function is also a thin wrapper to ease the call to an
+   ' UNICODE function. Since VB's BSTR strings are actually UNICODE
+   ' strings, we just need to pass the pointer to the string data
+   ' returned by the (undocumented) function StrPtr().
+   
+   FreeImage_JPEGCropU = (FreeImage_JPEGCropInt(StrPtr(SourceFile), StrPtr(DestFile), Left, Top, _
+         Right, Bottom) = 1)
+                                   
+End Function
+
+Public Function FreeImage_JPEGTransformCombined(ByVal SourceFile As String, _
+                                                ByVal DestFile As String, _
+                                                ByVal Operation As FREE_IMAGE_JPEG_OPERATION, _
+                                                ByVal Left As Long, _
+                                                ByVal Top As Long, _
+                                                ByVal Right As Long, _
+                                                ByVal Bottom As Long, _
+                                       Optional ByVal Perfect As Boolean = True) As Boolean
+                               
+Dim lPerfect As Long
+                               
+   ' Thin wrapper function returning a real VB Boolean value
+
+   If (Perfect) Then
+      lPerfect = 1
+   End If
+   FreeImage_JPEGTransformCombined = (FreeImage_JPEGTransformCombinedInt(SourceFile, DestFile, _
+         Operation, Left, Top, Right, Bottom, lPerfect) = 1)
+
+End Function
+
+Public Function FreeImage_JPEGTransformCombinedU(ByVal SourceFile As String, _
+                                                 ByVal DestFile As String, _
+                                                 ByVal Operation As FREE_IMAGE_JPEG_OPERATION, _
+                                                 ByVal Left As Long, _
+                                                 ByVal Top As Long, _
+                                                 ByVal Right As Long, _
+                                                 ByVal Bottom As Long, _
+                                        Optional ByVal Perfect As Boolean = True) As Boolean
+                               
+Dim lPerfect As Long
+                               
+   ' Thin wrapper function returning a real VB Boolean value
+   
+   ' This function is also a thin wrapper to ease the call to an
+   ' UNICODE function. Since VB's BSTR strings are actually UNICODE
+   ' strings, we just need to pass the pointer to the string data
+   ' returned by the (undocumented) function StrPtr().
+
+   If (Perfect) Then
+      lPerfect = 1
+   End If
+   FreeImage_JPEGTransformCombinedU = (FreeImage_JPEGTransformCombinedUInt(StrPtr(SourceFile), _
+         StrPtr(DestFile), Operation, Left, Top, Right, Bottom, lPerfect) = 1)
+
+End Function
+
+Public Function FreeImage_JPEGTransformCombinedFromMemory(ByVal SourceStream As Long, _
+                                                          ByVal DestStream As Long, _
+                                                          ByVal Operation As FREE_IMAGE_JPEG_OPERATION, _
+                                                          ByVal Left As Long, _
+                                                          ByVal Top As Long, _
+                                                          ByVal Right As Long, _
+                                                          ByVal Bottom As Long, _
+                                                 Optional ByVal Perfect As Boolean = True) As Boolean
+                               
+Dim lPerfect As Long
+                               
+   ' Thin wrapper function returning a real VB Boolean value
+
+   If (Perfect) Then
+      lPerfect = 1
+   End If
+   FreeImage_JPEGTransformCombinedFromMemory = (FreeImage_JPEGTransformCombinedFromMemoryInt(SourceStream, _
+         DestStream, Operation, Left, Top, Right, Bottom, lPerfect) = 1)
+
+End Function
+
 Public Function FreeImage_AdjustCurve(ByVal Bitmap As Long, _
                                       ByVal LookupTablePtr As Long, _
                                       ByVal Channel As FREE_IMAGE_COLOR_CHANNEL) As Boolean
@@ -4034,19 +3130,6 @@ Public Function FreeImage_PreMultiplyWithAlpha(ByVal Bitmap As Long) As Boolean
 
 End Function
 
-Public Function FreeImage_JPEGCrop(ByVal SourceFile As String, _
-                                   ByVal DestFile As String, _
-                                   ByVal Left As Long, _
-                                   ByVal Top As Long, _
-                                   ByVal Right As Long, _
-                                   ByVal Bottom As Long) As Boolean
-                                   
-   ' Thin wrapper function returning a real VB Boolean value
-   
-   FreeImage_JPEGCrop = (FreeImage_JPEGCropInt(SourceFile, DestFile, Left, Top, Right, Bottom) = 1)
-                                   
-End Function
-
 Public Function FreeImage_FillBackgroundEx(ByVal Bitmap As Long, _
                                            ByRef Color As RGBQUAD, _
                                   Optional ByVal Options As FREE_IMAGE_COLOR_OPTIONS) As Boolean
@@ -4075,7 +3158,6 @@ Public Function FreeImage_SetThumbnail(ByVal Bitmap As Long, ByVal Thumbnail As
 
 End Function
 
-
 Public Function FreeImage_OpenMultiBitmap(ByVal Format As FREE_IMAGE_FORMAT, _
                                           ByVal Filename As String, _
                                  Optional ByVal CreateNew As Boolean, _
@@ -4150,7 +3232,7 @@ Public Function FreeImage_ApplyColorMapping(ByVal Bitmap As Long, _
                                             ByVal DestinationColorsPtr As Long, _
                                             ByVal Count As Long, _
                                    Optional ByVal IgnoreAlpha As Boolean = True, _
-                                   Optional ByVal swap As Boolean) As Long
+                                   Optional ByVal Swap As Boolean) As Long
 
 Dim lIgnoreAlpha As Long
 Dim lSwap As Long
@@ -4158,7 +3240,7 @@ Dim lSwap As Long
    If (IgnoreAlpha) Then
       lIgnoreAlpha = 1
    End If
-   If (swap) Then
+   If (Swap) Then
       lSwap = 1
    End If
    FreeImage_ApplyColorMapping = FreeImage_ApplyColorMappingInt(Bitmap, SourceColorsPtr, _
@@ -4195,18 +3277,18 @@ Dim lIgnoreAlpha As Long
                          
 End Function
 
-Public Function FreeImage_ApplyIndexMapping(ByVal Bitmap As Long, _
-                                            ByVal SourceIndicesPtr As Long, _
-                                            ByVal DestinationIndicesPtr As Long, _
-                                            ByVal Count As Long, _
-                                   Optional ByVal swap As Boolean) As Long
+Public Function FreeImage_ApplyPaletteIndexMapping(ByVal Bitmap As Long, _
+                                                   ByVal SourceIndicesPtr As Long, _
+                                                   ByVal DestinationIndicesPtr As Long, _
+                                                   ByVal Count As Long, _
+                                          Optional ByVal Swap As Boolean) As Long
 
 Dim lSwap As Long
 
-   If (swap) Then
+   If (Swap) Then
       lSwap = 1
    End If
-   FreeImage_ApplyIndexMapping = FreeImage_ApplyIndexMappingInt(Bitmap, SourceIndicesPtr, _
+   FreeImage_ApplyPaletteIndexMapping = FreeImage_ApplyPaletteIndexMappingInt(Bitmap, SourceIndicesPtr, _
          DestinationIndicesPtr, Count, lSwap)
 
 End Function
@@ -4231,6 +3313,32 @@ Dim lTopDown As Long
 
 End Function
 
+Public Function FreeImage_ConvertFromRawBitsEx(ByVal CopySource As Boolean, _
+                                               ByVal BitsPtr As Long, _
+                                               ByVal ImageType As FREE_IMAGE_TYPE, _
+                                               ByVal Width As Long, _
+                                               ByVal Height As Long, _
+                                               ByVal Pitch As Long, _
+                                               ByVal BitsPerPixel As Long, _
+                                      Optional ByVal RedMask As Long, _
+                                      Optional ByVal GreenMask As Long, _
+                                      Optional ByVal BlueMask As Long, _
+                                      Optional ByVal TopDown As Boolean) As Long
+
+Dim lCopySource As Long
+Dim lTopDown As Long
+
+   If (CopySource) Then
+      lCopySource = 1
+   End If
+   If (TopDown) Then
+      lTopDown = 1
+   End If
+   FreeImage_ConvertFromRawBitsEx = FreeImage_ConvertFromRawBitsExInt(lCopySource, BitsPtr, ImageType, _
+         Width, Height, Pitch, BitsPerPixel, RedMask, GreenMask, BlueMask, lTopDown)
+
+End Function
+
 Public Sub FreeImage_ConvertToRawBits(ByVal BitsPtr As Long, _
                                       ByVal Bitmap As Long, _
                                       ByVal Pitch As Long, _
@@ -4771,7 +3879,7 @@ Public Function FreeImage_ApplyColorMappingEx(ByVal Bitmap As Long, _
                                               ByRef DestinationColors() As RGBQUAD, _
                                      Optional ByRef Count As Long = -1, _
                                      Optional ByVal IgnoreAlpha As Boolean = True, _
-                                     Optional ByVal swap As Boolean) As Long
+                                     Optional ByVal Swap As Boolean) As Long
                                      
 Dim nsrc As Long
 Dim ndst As Long
@@ -4811,19 +3919,20 @@ Dim ndst As Long
       End If
       
       FreeImage_ApplyColorMappingEx = FreeImage_ApplyColorMapping(Bitmap, _
-            VarPtr(SourceColors(0)), VarPtr(DestinationColors(0)), Count, IgnoreAlpha, swap)
+            VarPtr(SourceColors(0)), VarPtr(DestinationColors(0)), Count, IgnoreAlpha, Swap)
    End If
 
 End Function
 
-Public Function FreeImage_ApplyIndexMappingEx(ByVal Bitmap As Long, _
-                                              ByRef SourceIndices() As Byte, _
-                                              ByRef DestinationIndices() As Byte, _
-                                     Optional ByRef Count As Long = -1, _
-                                     Optional ByVal swap As Boolean) As Long
+Public Function FreeImage_ApplyPaletteIndexMappingEx(ByVal Bitmap As Long, _
+                                                     ByRef SourceIndices() As Byte, _
+                                                     ByRef DestinationIndices() As Byte, _
+                                            Optional ByRef Count As Long = -1, _
+                                            Optional ByVal Swap As Boolean) As Long
                                      
 Dim nsrc As Long
 Dim ndst As Long
+Dim lSwap As Long
 
    ' This function is an extended wrapper for FreeImage_ApplyIndexMapping(), which takes
    ' real VB style Byte arrays for source and destination indices along with an optional
@@ -4852,35 +3961,39 @@ Dim ndst As Long
          Count = ndst
       End If
    End If
+ 
+   If (Swap) Then
+      lSwap = 1
+   End If
    
-   FreeImage_ApplyIndexMappingEx = FreeImage_ApplyIndexMapping(Bitmap, _
-         VarPtr(SourceIndices(0)), VarPtr(DestinationIndices(0)), Count, swap)
+   FreeImage_ApplyPaletteIndexMappingEx = FreeImage_ApplyPaletteIndexMappingInt(Bitmap, _
+         VarPtr(SourceIndices(0)), VarPtr(DestinationIndices(0)), Count, lSwap)
 
 End Function
 
-Public Function FreeImage_ConvertFromRawBitsEx(ByRef Bits() As Byte, _
-                                               ByVal Width As Long, _
-                                               ByVal Height As Long, _
-                                               ByVal Pitch As Long, _
-                                               ByVal BitsPerPixel As Long, _
-                                      Optional ByVal RedMask As Long, _
-                                      Optional ByVal GreenMask As Long, _
-                                      Optional ByVal BlueMask As Long, _
-                                      Optional ByVal TopDown As Boolean) As Long
+Public Function FreeImage_ConvertFromRawBitsArray(ByRef Bits() As Byte, _
+                                                  ByVal Width As Long, _
+                                                  ByVal Height As Long, _
+                                                  ByVal Pitch As Long, _
+                                                  ByVal BitsPerPixel As Long, _
+                                         Optional ByVal RedMask As Long, _
+                                         Optional ByVal GreenMask As Long, _
+                                         Optional ByVal BlueMask As Long, _
+                                         Optional ByVal TopDown As Boolean) As Long
 
-   FreeImage_ConvertFromRawBitsEx = FreeImage_ConvertFromRawBits(VarPtr(Bits(0)), Width, Height, Pitch, _
+   FreeImage_ConvertFromRawBitsArray = FreeImage_ConvertFromRawBits(VarPtr(Bits(0)), Width, Height, Pitch, _
          BitsPerPixel, RedMask, GreenMask, BlueMask, TopDown)
 
 End Function
 
-Public Sub FreeImage_ConvertToRawBitsEx(ByRef Bits() As Byte, _
-                                        ByVal Bitmap As Long, _
-                                        ByVal Pitch As Long, _
-                                        ByVal BitsPerPixel As Long, _
-                               Optional ByVal RedMask As Long, _
-                               Optional ByVal GreenMask As Long, _
-                               Optional ByVal BlueMask As Long, _
-                               Optional ByVal TopDown As Boolean)
+Public Sub FreeImage_ConvertToRawBitsArray(ByRef Bits() As Byte, _
+                                           ByVal Bitmap As Long, _
+                                           ByVal Pitch As Long, _
+                                           ByVal BitsPerPixel As Long, _
+                                  Optional ByVal RedMask As Long, _
+                                  Optional ByVal GreenMask As Long, _
+                                  Optional ByVal BlueMask As Long, _
+                                  Optional ByVal TopDown As Boolean)
 
 Dim lHeight As Long
 
@@ -5047,25 +4160,21 @@ Public Function FreeImage_LoadFromMemoryEx(ByRef Data As Variant, _
 Dim hStream As Long
 Dim lDataPtr As Long
 
-   ' This function extends the FreeImage function FreeImage_LoadFromMemory()
-   ' to a more VB suitable function. The parameter data of type Variant my
-   ' me either an array of type Byte, Integer or Long or may contain the pointer
-   ' to a memory block, what in VB is always the address of the memory block,
-   ' since VB actually doesn's support native pointers.
-   
-   ' The parameter 'Flags' works according to the FreeImage API documentation.
+   ' This function loads a FreeImage bitmap from memory that has been passed
+   ' through parameter 'Data'. This parameter is of type Variant and may actually
+   ' be an array of type Byte, Integer or Long or may contain the address of an
+   ' arbitrary block of memory.
    
-   ' In case of providing the memory block as an array, the SizeInBytes may
-   ' be omitted, zero or less than zero. Then, the size of the memory block
-   ' is calculated correctly. When SizeInBytes is given, it is up to the caller
-   ' to ensure, it is correct.
+   ' The parameter 'SizeInBytes' specifies the size of the passed block of memory
+   ' in bytes. It may be omitted, if parameter 'Data' contains an array of type Byte,
+   ' Integer or Long upon entry. In that case, or if 'SizeInBytes' is zero or less
+   ' than zero, the size is determined directly from the array and also passed back
+   ' to the caller through parameter 'SizeInBytes'.
    
-   ' In case of providing an address of a memory block, SizeInBytes must not
-   ' be omitted.
+   ' The parameter 'Format' is an OUT only parameter that contains the image type
+   ' of the loaded image after the function returns.
    
-   ' The parameter fif is an OUT parameter, that will contain the image type
-   ' detected. Any values set by the caller will never be used within this
-   ' function.
+   ' The parameter 'Flags' works according to the FreeImage API documentation.
    
 
    ' get both pointer and size in bytes of the memory block provided
@@ -5081,7 +4190,7 @@ Dim lDataPtr As Long
          ' load the image from memory stream only, if known image type
          FreeImage_LoadFromMemoryEx = FreeImage_LoadFromMemory(Format, hStream, Flags)
       End If
-      ' close the memory stream when open
+      ' close the memory stream
       Call FreeImage_CloseMemory(hStream)
    End If
 
@@ -5097,14 +4206,15 @@ Dim hStream As Long
 Dim lpData As Long
 Dim lSizeInBytes As Long
 
-   ' This function saves a FreeImage DIB into memory by using the VB Byte
-   ' array Data(). It makes a deep copy of the image data and closes the
-   ' memory stream opened before it returns to the caller.
+   ' This function saves a FreeImage bitmap into memory and returns it through
+   ' the byte array passed in parameter 'Data()'. It makes a deep copy of the memory
+   ' stream's byte buffer, into which the image has been saved. The memory stream
+   ' is closed properly before the function returns.
    
-   ' The Byte array 'Data()' must not be a fixed sized array and will be
-   ' redimensioned according to the size needed to hold all the data.
+   ' The provided byte array 'Data()' must not be a fixed sized array. It will be
+   ' dimensioned to the size required to hold all the memory stream's data.
    
-   ' The parameters 'Format', 'Bitmap' and 'Flags' work according to the FreeImage 3
+   ' The parameters 'Format', 'Bitmap' and 'Flags' work according to the FreeImage
    ' API documentation.
    
    ' The optional 'UnloadSource' parameter is for unloading the original image
@@ -5158,29 +4268,32 @@ Public Function FreeImage_SaveToMemoryEx2(ByVal Format As FREE_IMAGE_FORMAT, _
                                  Optional ByVal Flags As FREE_IMAGE_SAVE_OPTIONS, _
                                  Optional ByVal UnloadSource As Boolean) As Boolean
 
-   ' This function saves a FreeImage DIB into memory by using the VB Byte
-   ' array Data(). It does not makes a deep copy of the image data, but uses
-   ' the function 'FreeImage_AcquireMemoryEx' to wrap the array 'Data()'
-   ' around the memory block pointed to by the result of the
-   ' 'FreeImage_AcquireMemory' function.
+   ' This function saves a FreeImage bitmap into memory and returns it through
+   ' the byte array passed in parameter 'Data()'. In contrast to function
+   ' 'FreeImage_SaveToMemoryEx', it does not make a deep copy of the memory
+   ' stream's byte buffer, but directly wraps the array 'Data()' around the stream's
+   ' byte buffer by calling function 'FreeImage_AcquireMemoryEx'. As a result, the
+   ' memory stream must remain valid while the array 'Data()' is in use. In other
+   ' words, the stream must be maintained by the caller of this function.
    
-   ' The Byte array 'Data()' must not be a fixed sized array and will be
-   ' redimensioned according to the size needed to hold all the data.
+   ' The provided byte array 'Data()' must not be a fixed sized array. It will be
+   ' dimensioned to the size required to hold all the memory stream's data.
    
-   ' To reuse the caller's array variable, this function's result was assigned to,
-   ' before it goes out of scope, the caller's array variable must be destroyed with
-   ' the 'FreeImage_DestroyLockedArray' function.
+   ' To reuse the caller's array variable that was passed through parameter 'Data()'
+   ' before it goes out of the caller's scope, it must first be destroyed by passing
+   ' it to the 'FreeImage_DestroyLockedArray' function.
    
-   ' The parameter 'stream' is an IN/OUT parameter, tracking the memory
-   ' stream, the VB array 'Data()' is based on. This parameter may contain
-   ' an already opened FreeImage memory stream when the function is called and
-   ' contains a valid memory stream when the function returns in each case.
-   ' After all, it is up to the caller to close that memory stream correctly.
-   ' The array 'Data()' will no longer be valid and accessable after the stream
-   ' has been closed, so it should only be closed after the passed byte array
-   ' variable either goes out of the caller's scope or is redimensioned.
+   ' The parameter 'Stream' is an IN/OUT parameter, that keeps track of the memory
+   ' stream, the VB array 'Data()' is based on. This parameter may contain an
+   ' already opened FreeImage memory stream upon entry and will contain a valid
+   ' memory stream when the function returns. It is left up to the caller to close
+   ' this memory stream correctly.
    
-   ' The parameters 'Format', 'Bitmap' and 'Flags' work according to the FreeImage 3
+   ' The array 'Data()' will no longer be valid and accessible after the stream has
+   ' been closed, so the stream should only be closed after the passed byte array
+   ' variable goes out of the caller's scope or is reused.
+   
+   ' The parameters 'Format', 'Bitmap' and 'Flags' work according to the FreeImage
    ' API documentation.
    
    ' The optional 'UnloadSource' parameter is for unloading the original image
@@ -5189,7 +4302,6 @@ Public Function FreeImage_SaveToMemoryEx2(ByVal Format As FREE_IMAGE_FORMAT, _
    
    ' The function returns True on success and False otherwise.
 
-   
    If (Bitmap) Then
    
       If (Not FreeImage_HasPixels(Bitmap)) Then
@@ -5206,10 +4318,10 @@ Public Function FreeImage_SaveToMemoryEx2(ByVal Format As FREE_IMAGE_FORMAT, _
             FreeImage_SaveToMemoryEx2 = FreeImage_AcquireMemoryEx(Stream, Data)
          End If
          
-         ' do not close the memory stream, since the returned array data()
-         ' points to the stream's data
-         ' the caller must close the stream after he is done
-         ' with the array
+         ' Do not close the memory stream, since the returned array Data()
+         ' directly points to the stream's data. The stream handle is passed back
+         ' to the caller through parameter 'Stream'. The caller must close
+         ' this stream after being done with the array.
       Else
          FreeImage_SaveToMemoryEx2 = False
       End If
@@ -5229,10 +4341,10 @@ Dim lpData As Long
 Dim tSA As SAVEARRAY1D
 Dim lpSA As Long
 
-   ' This function wraps the byte array Data() around acquired memory
-   ' of the memory stream specified by then stream parameter. The adjusted
-   ' array then points directly to the stream's data pointer and so
-   ' provides full read and write access.
+   ' This function wraps the byte array passed through parameter 'Data()' around the
+   ' memory acquired from the specified memory stream. After the function returns,
+   ' the array passed in 'Data()' points directly to the stream's data pointer and so,
+   ' provides full read and write access to the streams byte buffer.
    
    ' To reuse the caller's array variable, this function's result was assigned to,
    ' before it goes out of scope, the caller's array variable must be destroyed with
@@ -5254,7 +4366,7 @@ Dim lpSA As Long
                                                       ' received by FreeImage_AcquireMemory
          End With
          
-         lpSA = deref(VarPtrArray(Data))
+         lpSA = pDeref(VarPtrArray(Data))
          If (lpSA = 0) Then
             ' allocate memory for an array descriptor
             Call SafeArrayAllocDescriptor(1, lpSA)
@@ -5272,6 +4384,208 @@ Dim lpSA As Long
 
 End Function
 
+Public Function FreeImage_JPEGTransformCombinedFromMemoryEx(ByRef SourceData As Variant, _
+                                                            ByRef DestData() As Byte, _
+                                                            ByVal Operation As FREE_IMAGE_JPEG_OPERATION, _
+                                                            ByVal Left As Long, _
+                                                            ByVal Top As Long, _
+                                                            ByVal Right As Long, _
+                                                            ByVal Bottom As Long, _
+                                                   Optional ByRef SourceSizeInBytes As Long, _
+                                                   Optional ByVal Perfect As Boolean = True) As Boolean
+
+Dim hSrcStream As Long
+Dim lSrcDataPtr As Long
+Dim hDstStream As Long
+Dim lDstDataPtr As Long
+Dim lDstSizeInBytes As Long
+Dim lPerfect As Long
+Dim lResult As Long
+
+   ' This function performs a combination of lossless rotation or flipping and
+   ' lossless crop on a JPEG file. The source file is loaded from the memory
+   ' provided through parameter 'SourceData' and the result JPEG file is saved
+   ' to memory accessible by the byte array passed through parameter 'DestData()'.
+
+   ' The source JPEG file is loaded from the memory that has been passed through
+   ' parameter 'SourceData'. This parameter is of type Variant and may actually
+   ' be an array of type Byte, Integer or Long or may contain the address of an
+   ' arbitrary block of memory.
+   
+   ' The parameter 'SourceSizeInBytes' specifies the size of the passed block of
+   ' memory in bytes. It may be omitted, if parameter 'SourceData' contains an array
+   ' of type Byte, Integer or Long upon entry. In that case, or if 'SizeInBytes' is
+   ' zero or less than zero, the size is determined directly from the array and also
+   ' passed back to the caller through parameter 'SourceSizeInBytes'.
+   
+   ' The result JPEG file function is saved to memory that is accessible through
+   ' the byte array passed in parameter 'DestData()' after the function returns.
+   ' It makes a deep copy of the memory stream's byte buffer, into which the image
+   ' has been saved. The memory stream is closed properly before the function
+   ' returns.
+   
+   ' The provided byte array 'DestData()' must not be a fixed sized array. It will
+   ' be dimensioned to the size required to hold all the memory stream's data.
+
+   ' The parameters 'Operation', 'Left', 'Top', 'Right', 'Bottom' and 'Perfect' work
+   ' according to the FreeImage API documentation.
+
+
+   ' get both pointer and size in bytes of the memory block provided
+   ' through the Variant parameter 'SourceData'.
+   lSrcDataPtr = pGetMemoryBlockPtrFromVariant(SourceData, SourceSizeInBytes)
+   
+   ' open the source memory stream
+   hSrcStream = FreeImage_OpenMemoryByPtr(lSrcDataPtr, SourceSizeInBytes)
+   If (hSrcStream) Then
+      
+      ' open the destination memory stream
+      hDstStream = FreeImage_OpenMemory()
+      If (hDstStream) Then
+         
+         If (Perfect) Then
+            lPerfect = 1
+         End If
+         
+         ' perform transformations
+         lResult = FreeImage_JPEGTransformCombinedFromMemoryInt(hSrcStream, hDstStream, _
+               Operation, Left, Top, Right, Bottom, lPerfect)
+         
+         If (lResult = 1) Then
+           ' if the transformations succeeded, access the stream's byte buffer
+            If (FreeImage_AcquireMemoryInt(hDstStream, lDstDataPtr, lDstSizeInBytes)) Then
+               On Error Resume Next
+               ' redim the array
+               ReDim DestData(lDstSizeInBytes - 1)
+               If (Err.Number = ERROR_SUCCESS) Then
+                  On Error GoTo 0
+                  ' and make a deep copy of the stream's byte buffer
+                  Call CopyMemory(DestData(0), ByVal lDstDataPtr, lDstSizeInBytes)
+               Else
+                  On Error GoTo 0
+                  lResult = 0
+               End If
+            Else
+               lResult = 0
+            End If
+         End If
+         
+         ' close the destination memory stream
+         Call FreeImage_CloseMemory(hDstStream)
+      End If
+      
+      ' close the source memory stream
+      Call FreeImage_CloseMemory(hSrcStream)
+   End If
+
+   FreeImage_JPEGTransformCombinedFromMemoryEx = (lResult = 1)
+
+End Function
+
+Public Function FreeImage_JPEGTransformCombinedFromMemoryEx2(ByRef SourceData As Variant, _
+                                                             ByRef DestData() As Byte, _
+                                                             ByRef DestStream As Long, _
+                                                             ByVal Operation As FREE_IMAGE_JPEG_OPERATION, _
+                                                             ByVal Left As Long, _
+                                                             ByVal Top As Long, _
+                                                             ByVal Right As Long, _
+                                                             ByVal Bottom As Long, _
+                                                    Optional ByRef SourceSizeInBytes As Long, _
+                                                    Optional ByVal Perfect As Boolean = True) As Boolean
+
+Dim hSrcStream As Long
+Dim lSrcDataPtr As Long
+Dim lPerfect As Long
+Dim bResult As Boolean
+
+   ' This function performs a combination of lossless rotation or flipping and
+   ' lossless crop on a JPEG file. The source file is loaded from the memory
+   ' provided through parameter 'SourceData' and the result JPEG file is saved
+   ' to memory accessible by the byte array passed through parameter 'DestData()'.
+
+   ' The source JPEG file is loaded from the memory that has been passed through
+   ' parameter 'SourceData'. This parameter is of type Variant and may actually
+   ' be an array of type Byte, Integer or Long or may contain the address of an
+   ' arbitrary block of memory.
+   
+   ' The parameter 'SourceSizeInBytes' specifies the size of the passed block of
+   ' memory in bytes. It may be omitted, if parameter 'SourceData' contains an array
+   ' of type Byte, Integer or Long upon entry. In that case, or if 'SizeInBytes' is
+   ' zero or less than zero, the size is determined directly from the array and also
+   ' passed back to the caller through parameter 'SourceSizeInBytes'.
+
+   ' The result JPEG file function is saved to memory that is accessible through the
+   ' the byte array passed in parameter 'DestData()' after the function returns.
+   ' In contrast to function 'FreeImage_JPEGTransformCombinedFromMemoryEx', it does
+   ' not make a deep copy of the memory stream's byte buffer, but directly wraps the
+   ' array 'DestData()' around the stream's byte buffer by calling function
+   ' 'FreeImage_AcquireMemoryEx'. As a result, the memory stream must remain valid
+   ' while the array 'Data()' is in use. In other words, the stream must be
+   ' maintained by the caller of this function.
+   
+   ' The provided byte array 'DestData()' must not be a fixed sized array. It will be
+   ' dimensioned to the size required to hold all the memory stream's data.
+   
+   ' To reuse the caller's array variable that was passed through parameter 'DestData()'
+   ' before it goes out of the caller's scope, it must first be destroyed by passing it
+   ' to the 'FreeImage_DestroyLockedArray' function.
+   
+   ' The parameter 'DestStream' is an IN/OUT parameter, that keeps track of the memory
+   ' stream, the VB array 'DestData()' is based on. This parameter may contain an
+   ' already opened FreeImage memory stream upon entry and will contain a valid
+   ' memory stream when the function returns. It is left up to the caller to close
+   ' this memory stream correctly.
+   
+   ' The array 'DestData()' will no longer be valid and accessible after the stream has
+   ' been closed, so the stream should only be closed after the passed byte array
+   ' variable goes out of the caller's scope or is reused.
+   
+   ' The parameters 'Operation', 'Left', 'Top', 'Right', 'Bottom' and 'Perfect' work
+   ' according to the FreeImage API documentation.
+   
+
+   ' get both pointer and size in bytes of the memory block provided
+   ' through the Variant parameter 'SourceData'.
+   lSrcDataPtr = pGetMemoryBlockPtrFromVariant(SourceData, SourceSizeInBytes)
+   
+   ' open the source memory stream
+   hSrcStream = FreeImage_OpenMemoryByPtr(lSrcDataPtr, SourceSizeInBytes)
+   If (hSrcStream) Then
+      
+      If (DestStream = 0) Then
+         ' open the destination memory stream, only if no valid stream was provided
+         DestStream = FreeImage_OpenMemory()
+      End If
+      
+      If (DestStream) Then
+         
+         If (Perfect) Then
+            lPerfect = 1
+         End If
+         
+         ' perform transformations
+         bResult = (FreeImage_JPEGTransformCombinedFromMemoryInt(hSrcStream, DestStream, _
+               Operation, Left, Top, Right, Bottom, lPerfect) = 1)
+         
+         If (bResult) Then
+            ' if the transformations succeeded, access the stream's byte buffer
+            bResult = FreeImage_AcquireMemoryEx(DestStream, DestData)
+         End If
+         
+         ' Do not close the memory stream, since the returned array DestData()
+         ' directly points to the stream's data. The stream handle is passed back
+         ' to the caller through parameter 'DestStream'. The caller must close
+         ' this stream after being done with the array.
+      End If
+      
+      ' close the source memory stream
+      Call FreeImage_CloseMemory(hSrcStream)
+   End If
+
+   FreeImage_JPEGTransformCombinedFromMemoryEx2 = bResult
+
+End Function
+
 Public Function FreeImage_ReadMemoryEx(ByRef Buffer As Variant, _
                                        ByVal Stream As Long, _
                               Optional ByRef Count As Long, _
@@ -5288,8 +4602,8 @@ Dim lCount As Long
    ' The variant parameter 'Buffer' may be a Byte, Integer or Long array or
    ' may contain a pointer to a memory block (the memory block's address).
    
-   ' In the latter case, this function behaves exactly
-   ' like 'FreeImage_ReadMemory()'. Then, 'Count' and 'Size' must be valid
+   ' In the latter case, this function behaves exactly like
+   ' function 'FreeImage_ReadMemory()'. Then, 'Count' and 'Size' must be valid
    ' upon entry.
    
    ' If 'Buffer' is an initialized (dimensioned) array, 'Count' and 'Size' may
@@ -5474,25 +4788,21 @@ Public Function FreeImage_LoadMultiBitmapFromMemoryEx(ByRef Data As Variant, _
 Dim hStream As Long
 Dim lDataPtr As Long
 
-   ' This function extends the FreeImage function FreeImage_LoadMultiBitmapFromMemoryEx()
-   ' to a more VB suitable function. The parameter data of type Variant my
-   ' me either an array of type Byte, Integer or Long or may contain the pointer
-   ' to a memory block, what in VB is always the address of the memory block,
-   ' since VB actually doesn's support native pointers.
+   ' This function loads a FreeImage multipage bitmap from memory that has been
+   ' passed through parameter 'Data'. This parameter is of type Variant and may
+   ' actually be an array of type Byte, Integer or Long or may contain the
+   ' address of an arbitrary block of memory.
    
-   ' The parameter 'Flags' works according to the FreeImage API documentation.
-   
-   ' In case of providing the memory block as an array, the SizeInBytes may
-   ' be omitted, zero or less than zero. Then, the size of the memory block
-   ' is calculated correctly. When SizeInBytes is given, it is up to the caller
-   ' to ensure, it is correct.
+   ' The parameter 'SizeInBytes' specifies the size of the passed block of memory
+   ' in bytes. It may be omitted, if parameter 'Data' contains an array of type Byte,
+   ' Integer or Long upon entry. In that case, or if 'SizeInBytes' is zero or less
+   ' than zero, the size is determined directly from the array and also passed back
+   ' to the caller through parameter 'SizeInBytes'.
    
-   ' In case of providing an address of a memory block, SizeInBytes must not
-   ' be omitted.
+   ' The parameter 'Format' is an OUT only parameter that contains the image type
+   ' of the loaded image after the function returns.
    
-   ' The parameter fif is an OUT parameter, that will contain the image type
-   ' detected. Any values set by the caller will never be used within this
-   ' function.
+   ' The parameter 'Flags' works according to the FreeImage API documentation.
 
 
    ' get both pointer and size in bytes of the memory block provided
@@ -5506,9 +4816,10 @@ Dim lDataPtr As Long
       Format = FreeImage_GetFileTypeFromMemory(hStream)
       If (Format <> FIF_UNKNOWN) Then
          ' load the image from memory stream only, if known image type
-         FreeImage_LoadMultiBitmapFromMemoryEx = FreeImage_LoadMultiBitmapFromMemory(Format, hStream, Flags)
+         FreeImage_LoadMultiBitmapFromMemoryEx = FreeImage_LoadMultiBitmapFromMemory(Format, _
+               hStream, Flags)
       End If
-      ' close the memory stream when open
+      ' close the memory stream
       Call FreeImage_CloseMemory(hStream)
    End If
 
@@ -5524,19 +4835,20 @@ Dim hStream As Long
 Dim lpData As Long
 Dim lSizeInBytes As Long
 
-   ' This function saves a FreeImage multi-page bitmap into memory by using
-   ' the VB Byte array Data(). It makes a deep copy of the image data and closes the
-   ' memory stream opened, before it returns to the caller.
+   ' This function saves a FreeImage multipage bitmap into memory and returns it
+   ' through the byte array passed in parameter 'Data()'. It makes a deep copy of
+   ' the memory stream's byte buffer, into which the image has been saved. The
+   ' memory stream is closed properly before the function returns.
    
-   ' The Byte array 'Data()' must not be a fixed sized array and will be
-   ' redimensioned according to the size needed to hold all the data.
+   ' The provided byte array 'Data()' must not be a fixed sized array. It will be
+   ' dimensioned to the size required to hold all the memory stream's data.
    
-   ' The parameters 'Format', 'Bitmap' and 'Flags' work according to the FreeImage 3
+   ' The parameters 'Format', 'Bitmap' and 'Flags' work according to the FreeImage
    ' API documentation.
    
    ' The optional 'UnloadSource' parameter is for unloading the original image
-   ' after it has been saved to memory. If True, there is no need to close the
-   ' multi-page bitmap at the caller's site.
+   ' after it has been saved into memory. There is no need to clean up the DIB
+   ' at the caller's site.
    
    ' The function returns True on success and False otherwise.
    
@@ -5550,7 +4862,8 @@ Dim lSizeInBytes As Long
    
       hStream = FreeImage_OpenMemory()
       If (hStream) Then
-         FreeImage_SaveMultiBitmapToMemoryEx = FreeImage_SaveMultiBitmapToMemory(Format, Bitmap, hStream, Flags)
+         FreeImage_SaveMultiBitmapToMemoryEx = FreeImage_SaveMultiBitmapToMemory(Format, _
+               Bitmap, hStream, Flags)
          If (FreeImage_SaveMultiBitmapToMemoryEx) Then
             If (FreeImage_AcquireMemoryInt(hStream, lpData, lSizeInBytes)) Then
                On Error Resume Next
@@ -5585,34 +4898,37 @@ Public Function FreeImage_SaveMultiBitmapToMemoryEx2(ByVal Format As FREE_IMAGE_
                                             Optional ByVal Flags As FREE_IMAGE_SAVE_OPTIONS, _
                                             Optional ByVal UnloadSource As Boolean) As Boolean
 
-   ' This function saves a FreeImage multi-page bitmap into memory by using
-   ' the VB Byte array Data(). It does not makes a deep copy of the image data, but uses
-   ' the function 'FreeImage_AcquireMemoryEx' to wrap the array 'Data()'
-   ' around the memory block pointed to by the result of the
-   ' 'FreeImage_AcquireMemory' function.
+   ' This function saves a FreeImage multipage bitmap into memory and returns it
+   ' through the byte array passed in parameter 'Data()'. In contrast to function
+   ' 'FreeImage_SaveToMemoryEx', it does not make a deep copy of the memory
+   ' stream's byte buffer, but directly wraps the array 'Data()' around the stream's
+   ' byte buffer by calling function 'FreeImage_AcquireMemoryEx'. As a result, the
+   ' memory stream must remain valid while the array 'Data()' is in use. In other
+   ' words, the stream must be maintained by the caller of this function.
    
-   ' The Byte array 'Data()' must not be a fixed sized array and will be
-   ' redimensioned according to the size needed to hold all the data.
+   ' The provided byte array 'Data()' must not be a fixed sized array. It will be
+   ' dimensioned to the size required to hold all the memory stream's data.
    
-   ' To reuse the caller's array variable, this function's result was assigned to,
-   ' before it goes out of scope, the caller's array variable must be destroyed with
-   ' the 'FreeImage_DestroyLockedArray' function.
+   ' To reuse the caller's array variable that was passed through parameter 'Data()'
+   ' before it goes out of the caller's scope, it must first be destroyed by passing
+   ' it to the 'FreeImage_DestroyLockedArray' function.
+   
+   ' The parameter 'Stream' is an IN/OUT parameter, that keeps track of the memory
+   ' stream, the VB array 'Data()' is based on. This parameter may contain an
+   ' already opened FreeImage memory stream upon entry and will contain a valid
+   ' memory stream when the function returns. It is left up to the caller to close
+   ' this memory stream correctly.
    
-   ' The parameter 'Stream' is an IN/OUT parameter, tracking the memory
-   ' stream, the VB array 'Data()' is based on. This parameter may contain
-   ' an already opened FreeImage memory stream when the function is called and
-   ' contains a valid memory stream when the function returns in each case.
-   ' After all, it is up to the caller to close that memory stream correctly.
-   ' The array 'Data()' will no longer be valid and accessable after the stream
-   ' has been closed, so it should only be closed after the passed byte array
-   ' variable either goes out of the caller's scope or is redimensioned.
+   ' The array 'Data()' will no longer be valid and accessible after the stream has
+   ' been closed, so the stream should only be closed after the passed byte array
+   ' variable goes out of the caller's scope or is reused.
    
-   ' The parameters 'Format', 'Bitmap' and 'Flags' work according to the FreeImage 3
+   ' The parameters 'Format', 'Bitmap' and 'Flags' work according to the FreeImage
    ' API documentation.
    
    ' The optional 'UnloadSource' parameter is for unloading the original image
-   ' after it has been saved to memory. If True, there is no need to close the
-   ' multi-page bitmap at the caller's site.
+   ' after it has been saved to memory. There is no need to clean up the DIB
+   ' at the caller's site.
    
    ' The function returns True on success and False otherwise.
 
@@ -5634,10 +4950,10 @@ Public Function FreeImage_SaveMultiBitmapToMemoryEx2(ByVal Format As FREE_IMAGE_
             FreeImage_SaveMultiBitmapToMemoryEx2 = FreeImage_AcquireMemoryEx(Stream, Data)
          End If
          
-         ' do not close the memory stream, since the returned array 'Data()'
-         ' points to the stream's data
-         ' the caller must close the stream after he is done
-         ' with the array
+         ' Do not close the memory stream, since the returned array Data()
+         ' directly points to the stream's data. The stream handle is passed back
+         ' to the caller through parameter 'Stream'. The caller must close
+         ' this stream after being done with the array.
       Else
          FreeImage_SaveMultiBitmapToMemoryEx2 = False
       End If
@@ -6146,7 +5462,7 @@ Dim bSetTag As Boolean
          hMDFind = FreeImage_FindFirstMetadata(Model, BitmapSrc, lpTag)
          If (hMDFind) Then
             Do
-               strKey = pGetStringFromPointerA(deref(deref(lpTag)))
+               strKey = pGetStringFromPointerA(pDeref(pDeref(lpTag)))
                bSetTag = ReplaceExisting
                If (Not bSetTag) Then
                   bSetTag = (Not FreeImage_TagExists(BitmapDst, Model, strKey))
@@ -6531,7 +5847,7 @@ Public Function FreeImage_GetICCProfileColorModel(ByVal Bitmap As Long) As FREE_
    ' Bitmap. That depends on the bitmap's color type.
 
    If (FreeImage_HasICCProfile(Bitmap)) Then
-      FreeImage_GetICCProfileColorModel = (deref(FreeImage_GetICCProfileInt(Bitmap)) _
+      FreeImage_GetICCProfileColorModel = (pDeref(FreeImage_GetICCProfileInt(Bitmap)) _
             And FREE_IMAGE_ICC_COLOR_MODEL_MASK)
    Else
       ' use FreeImage_GetColorType() to determine, whether this is a CMYK bitmap or not
@@ -6550,7 +5866,7 @@ Public Function FreeImage_GetICCProfileSize(ByVal Bitmap As Long) As Long
    ' only the size in bytes of the ICC profile data for the Bitmap specified or zero,
    ' if there is no ICC profile data for the Bitmap.
 
-   FreeImage_GetICCProfileSize = deref(FreeImage_GetICCProfileInt(Bitmap) + 4)
+   FreeImage_GetICCProfileSize = pDeref(FreeImage_GetICCProfileInt(Bitmap) + 4)
 
 End Function
 
@@ -6560,7 +5876,7 @@ Public Function FreeImage_GetICCProfileDataPointer(ByVal Bitmap As Long) As Long
    ' only the pointer (the address) of the ICC profile data for the Bitmap specified,
    ' or zero if there is no ICC profile data for the Bitmap.
 
-   FreeImage_GetICCProfileDataPointer = deref(FreeImage_GetICCProfileInt(Bitmap) + 8)
+   FreeImage_GetICCProfileDataPointer = pDeref(FreeImage_GetICCProfileInt(Bitmap) + 8)
 
 End Function
 
@@ -7085,12 +6401,12 @@ Dim eLastStretchMode As STRETCH_MODE
       End If
       
       If (DrawMode And DM_MIRROR_VERTICAL) Then
-         YDst = HeightDst
+         YDst = YDst + HeightDst
          HeightDst = -HeightDst
       End If
      
       If (DrawMode And DM_MIRROR_HORIZONTAL) Then
-         XDst = WidthDst
+         XDst = XDst + WidthDst
          WidthDst = -WidthDst
       End If
 
@@ -8634,12 +7950,14 @@ End Function
 Public Function FreeImage_GetPictureData(ByVal Bitmap As Long, _
                                 Optional ByVal UnloadSource As Boolean) As Byte()
 
+Const SIZE_OF_LONG = 4
+Const SIZE_OF_BITMAPINFOHEADER = 40
+
 Dim abResult() As Byte
-Dim lImageSize As Long
+Dim lHeaderSize As Long
 Dim lPaletteSize As Long
-Dim abInfoBuffer() As Byte
+Dim lImageSize As Long
 Dim lpInfo As Long
-Dim bBufferUsed As Boolean
 Dim lOffset As Long
 
    ' This function creates an Office PictureData Byte array from a FreeImage DIB.
@@ -8658,20 +7976,19 @@ Dim lOffset As Long
                         "Unable to create a PictureData array from a 'header-only' bitmap.")
       End If
       
+      If (FreeImage_HasRGBMasks(Bitmap)) Then
+         lHeaderSize = 3 * SIZE_OF_LONG
+      End If
+      lHeaderSize = lHeaderSize + SIZE_OF_BITMAPINFOHEADER
       lImageSize = FreeImage_GetHeight(Bitmap) * FreeImage_GetPitch(Bitmap)
       lPaletteSize = FreeImage_GetColorsUsed(Bitmap) * 4
       
+      ReDim abResult(lHeaderSize + lPaletteSize + lImageSize - 1)
+      
       ' Copy the BITMAPINFOHEADER into the result array.
-'''      lpInfo = FreeImage_GetInfoEx(Bitmap, abInfoBuffer, bBufferUsed)
-'''      If (bBufferUsed) Then
-'''         ReDim abResult(39 + 12 + lPaletteSize + lImageSize)
-'''         Call CopyMemory(abResult(0), ByVal lpInfo, 40 + 12)
-'''         lOffset = 40 + 12
-'''      Else
-'''         ReDim abResult(39 + lPaletteSize + lImageSize)
-'''         Call CopyMemory(abResult(0), ByVal lpInfo, 40)
-'''         lOffset = 40
-'''      End If
+      lpInfo = FreeImage_GetInfo(Bitmap)
+      Call CopyMemory(abResult(0), ByVal lpInfo, lHeaderSize)
+      lOffset = lOffset + lHeaderSize
       
       If (lPaletteSize > 0) Then
          ' Copy the image's palette (if any) into the result array.
@@ -8809,10 +8126,10 @@ Dim atBitsTDst As ScanLinesRGBTRIBLE
 Dim atBitsQDst() As RGBQUAD
 
 Dim bMaskPixel As Boolean
-Dim X As Long
+Dim x As Long
 Dim x2 As Long
 Dim lPixelIndex As Long
-Dim Y As Long
+Dim y As Long
 Dim i As Long
 
    'TODO: comment this function
@@ -9084,10 +8401,10 @@ Dim i As Long
                
                Case 1
                   abBitsBDst = FreeImage_GetBitsEx(hDIBResult)
-                  X = 1
+                  x = 1
                   For i = 7 To 0 Step -1
-                     abBitValues(i) = X
-                     X = X * 2
+                     abBitValues(i) = x
+                     x = x * 2
                   Next i
                
                Case 4
@@ -9112,8 +8429,8 @@ Dim i As Long
             End If
         
             ' walk the hole image
-            For Y = 0 To lHeight - 1
-               For X = 0 To lWidth - 1
+            For y = 0 To lHeight - 1
+               For x = 0 To lWidth - 1
                   
                   ' should transparency information be considered to create
                   ' the mask?
@@ -9122,8 +8439,8 @@ Dim i As Long
                      Select Case lBitDepthSrc
                      
                      Case 4
-                        x2 = X \ 2
-                        lPixelIndex = (abBitsBSrc(x2, Y) And abBitMasks(X Mod 2)) \ abBitShifts(X Mod 2)
+                        x2 = x \ 2
+                        lPixelIndex = (abBitsBSrc(x2, y) And abBitMasks(x Mod 2)) \ abBitShifts(x Mod 2)
                         bMaskPixel = (abTransparencyTableSrc(lPixelIndex) = 0)
                         If (Not bMaskPixel) Then
                            bMaskPixel = ((abTransparencyTableSrc(lPixelIndex) < 255) And _
@@ -9131,9 +8448,9 @@ Dim i As Long
                         End If
                      
                      Case 8
-                        bMaskPixel = (abTransparencyTableSrc(abBitsBSrc(X, Y)) = 0)
+                        bMaskPixel = (abTransparencyTableSrc(abBitsBSrc(x, y)) = 0)
                         If (Not bMaskPixel) Then
-                           bMaskPixel = ((abTransparencyTableSrc(abBitsBSrc(X, Y)) < 255) And _
+                           bMaskPixel = ((abTransparencyTableSrc(abBitsBSrc(x, y)) < 255) And _
                                          (bMaskAlphaTransparency))
                         End If
                         
@@ -9143,9 +8460,9 @@ Dim i As Long
                         bMaskPixel = False
                      
                      Case 32
-                        bMaskPixel = (atBitsQSrc(X, Y).rgbReserved = 0)
+                        bMaskPixel = (atBitsQSrc(x, y).rgbReserved = 0)
                         If (Not bMaskPixel) Then
-                           bMaskPixel = ((atBitsQSrc(X, Y).rgbReserved < 255) And _
+                           bMaskPixel = ((atBitsQSrc(x, y).rgbReserved < 255) And _
                                          (bMaskAlphaTransparency))
                         End If
                         
@@ -9163,8 +8480,8 @@ Dim i As Long
                      Select Case lBitDepthSrc
                      
                      Case 4
-                        x2 = X \ 2
-                        lPixelIndex = (abBitsBSrc(x2, Y) And abBitMasks(X Mod 2)) \ abBitShifts(X Mod 2)
+                        x2 = x \ 2
+                        lPixelIndex = (abBitsBSrc(x2, y) And abBitMasks(x Mod 2)) \ abBitShifts(x Mod 2)
                         If (eMaskColorsFormat And FICFF_COLOR_PALETTE_INDEX) Then
                            For i = 0 To lMaskColorsMaxIndex
                               If (lColorTolerance = 0) Then
@@ -9197,10 +8514,10 @@ Dim i As Long
                         If (eMaskColorsFormat And FICFF_COLOR_PALETTE_INDEX) Then
                            For i = 0 To lMaskColorsMaxIndex
                               If (lColorTolerance = 0) Then
-                                 bMaskPixel = (abBitsBSrc(X, Y) = alcMaskColors(i))
+                                 bMaskPixel = (abBitsBSrc(x, y) = alcMaskColors(i))
                               Else
                                  bMaskPixel = (FreeImage_CompareColorsLongLong( _
-                                                   alPaletteSrc(abBitsBSrc(X, Y)), _
+                                                   alPaletteSrc(abBitsBSrc(x, y)), _
                                                    alPaletteSrc(alcMaskColors(i)), _
                                                    lColorTolerance, _
                                                    FICFF_COLOR_RGB, FICFF_COLOR_RGB) = 0)
@@ -9212,7 +8529,7 @@ Dim i As Long
                         Else
                            For i = 0 To lMaskColorsMaxIndex
                               bMaskPixel = (FreeImage_CompareColorsLongLong( _
-                                                alPaletteSrc(abBitsBSrc(X, Y)), _
+                                                alPaletteSrc(abBitsBSrc(x, y)), _
                                                 alcMaskColors(i), lColorTolerance, _
                                                 FICFF_COLOR_RGB, _
                                                 (eMaskColorsFormat And FICFF_COLOR_FORMAT_ORDER_MASK)) = 0)
@@ -9225,7 +8542,7 @@ Dim i As Long
                      Case 24
                         For i = 0 To lMaskColorsMaxIndex
                            bMaskPixel = (FreeImage_CompareColorsRGBTRIPLELong( _
-                                             atBitsTSrc.Scanline(Y).Data(X), _
+                                             atBitsTSrc.Scanline(y).Data(x), _
                                              alcMaskColors(i), lColorTolerance, _
                                              (eMaskColorsFormat And FICFF_COLOR_FORMAT_ORDER_MASK)) = 0)
                            If (bMaskPixel) Then
@@ -9236,7 +8553,7 @@ Dim i As Long
                      Case 32
                         For i = 0 To lMaskColorsMaxIndex
                            bMaskPixel = (FreeImage_CompareColorsRGBQUADLong( _
-                                             atBitsQSrc(X, Y), _
+                                             atBitsQSrc(x, y), _
                                              alcMaskColors(i), lColorTolerance, _
                                              (eMaskColorsFormat And FICFF_COLOR_FORMAT_ORDER_MASK)) = 0)
                            If (bMaskPixel) Then
@@ -9255,34 +8572,34 @@ Dim i As Long
                      Select Case lBitDepth
                      
                      Case 1
-                        x2 = X \ 8
+                        x2 = x \ 8
                         If ((bMaskPixel) Xor (bInvertMask)) Then
-                           abBitsBDst(x2, Y) = abBitsBDst(x2, Y) Or abBitValues(X Mod 8)
+                           abBitsBDst(x2, y) = abBitsBDst(x2, y) Or abBitValues(x Mod 8)
                         End If
                         
                      Case 4
-                        x2 = X \ 2
+                        x2 = x \ 2
                         If ((bMaskPixel) Xor (bInvertMask)) Then
-                           abBitsBDst(x2, Y) = abBitsBDst(x2, Y) Or abBitValues(X Mod 2)
+                           abBitsBDst(x2, y) = abBitsBDst(x2, y) Or abBitValues(x Mod 2)
                         End If
                         
                      Case 8
                         If ((bMaskPixel) Xor (bInvertMask)) Then
-                           abBitsBDst(X, Y) = 1
+                           abBitsBDst(x, y) = 1
                         End If
                         
                      Case 24
                         If ((bMaskPixel) Xor (bInvertMask)) Then
-                           Call CopyMemory(atBitsTDst.Scanline(Y).Data(X), lciMaskColorDst, 3)
+                           Call CopyMemory(atBitsTDst.Scanline(y).Data(x), lciMaskColorDst, 3)
                         Else
-                           Call CopyMemory(atBitsTDst.Scanline(Y).Data(X), lciUnmaskColorDst, 3)
+                           Call CopyMemory(atBitsTDst.Scanline(y).Data(x), lciUnmaskColorDst, 3)
                         End If
                         
                      Case 32
                         If ((bMaskPixel) Xor (bInvertMask)) Then
-                           Call CopyMemory(atBitsQDst(X, Y), lciMaskColorDst, 4)
+                           Call CopyMemory(atBitsQDst(x, y), lciMaskColorDst, 4)
                         Else
-                           Call CopyMemory(atBitsQDst(X, Y), lciUnmaskColorDst, 4)
+                           Call CopyMemory(atBitsQDst(x, y), lciUnmaskColorDst, 4)
                         End If
                      
                      End Select
@@ -9294,51 +8611,51 @@ Dim i As Long
                      Select Case lBitDepthSrc
                      
                      Case 4
-                        x2 = X \ 2
+                        x2 = x \ 2
                         If ((bMaskPixel) Xor (bInvertMask)) Then
                            If (bHaveMaskColorSrc) Then
-                              abBitsBSrc(x2, Y) = _
-                                  (abBitsBSrc(x2, Y) And (Not abBitMasks(X Mod 2))) Or _
-                                            (lciMaskColorSrc * abBitShifts(X Mod 2))
+                              abBitsBSrc(x2, y) = _
+                                  (abBitsBSrc(x2, y) And (Not abBitMasks(x Mod 2))) Or _
+                                            (lciMaskColorSrc * abBitShifts(x Mod 2))
                             End If
                         ElseIf (bHaveUnmaskColorSrc) Then
-                           abBitsBSrc(x2, Y) = _
-                               (abBitsBSrc(x2, Y) And (Not abBitMasks(X Mod 2))) Or _
-                                         (lciUnmaskColorSrc * abBitShifts(X Mod 2))
+                           abBitsBSrc(x2, y) = _
+                               (abBitsBSrc(x2, y) And (Not abBitMasks(x Mod 2))) Or _
+                                         (lciUnmaskColorSrc * abBitShifts(x Mod 2))
                         End If
                      
                      Case 8
                         If ((bMaskPixel) Xor (bInvertMask)) Then
                            If (bHaveMaskColorSrc) Then
-                              abBitsBSrc(X, Y) = lciMaskColorSrc
+                              abBitsBSrc(x, y) = lciMaskColorSrc
                            End If
                         ElseIf (bHaveUnmaskColorSrc) Then
-                           abBitsBSrc(X, Y) = lciUnmaskColorSrc
+                           abBitsBSrc(x, y) = lciUnmaskColorSrc
                         End If
                         
                      Case 24
                         If ((bMaskPixel) Xor (bInvertMask)) Then
                            If (bHaveMaskColorSrc) Then
-                              Call CopyMemory(atBitsTSrc.Scanline(Y).Data(X), lciMaskColorSrc, 3)
+                              Call CopyMemory(atBitsTSrc.Scanline(y).Data(x), lciMaskColorSrc, 3)
                            End If
                         ElseIf (bHaveUnmaskColorSrc) Then
-                           Call CopyMemory(atBitsTSrc.Scanline(Y).Data(X), lciUnmaskColorSrc, 3)
+                           Call CopyMemory(atBitsTSrc.Scanline(y).Data(x), lciUnmaskColorSrc, 3)
                         End If
                      
                      Case 32
                         If ((bMaskPixel) Xor (bInvertMask)) Then
                            If (bHaveMaskColorSrc) Then
-                              Call CopyMemory(atBitsQSrc(X, Y), lciMaskColorSrc, 4)
+                              Call CopyMemory(atBitsQSrc(x, y), lciMaskColorSrc, 4)
                            End If
                         ElseIf (bHaveUnmaskColorSrc) Then
-                           Call CopyMemory(atBitsQSrc(X, Y), lciUnmaskColorSrc, 4)
+                           Call CopyMemory(atBitsQSrc(x, y), lciUnmaskColorSrc, 4)
                         End If
                         
                      End Select
                   End If
                   
-               Next X
-            Next Y
+               Next x
+            Next y
          End If
       End If
    End If
@@ -11235,7 +10552,7 @@ Dim lArrayDataPtr As Long
    If (IncludeSize) Then
       ' get the pointer actual pointing to the array data of
       ' the Byte array 'FreeImage_ZLibCompressVB'
-      lArrayDataPtr = deref(deref(VarPtrArray(FreeImage_ZLibCompressVB)) + 12)
+      lArrayDataPtr = pDeref(pDeref(VarPtrArray(FreeImage_ZLibCompressVB)) + 12)
 
       ' copy uncompressed size into the first 4 bytes
       Call CopyMemory(ByVal lArrayDataPtr, UBound(Data) + 1, 4)
@@ -11323,7 +10640,7 @@ Dim lArrayDataPtr As Long
    If (IncludeSize) Then
       ' get the pointer actual pointing to the array data of
       ' the Byte array 'FreeImage_ZLibCompressVB'
-      lArrayDataPtr = deref(deref(VarPtrArray(FreeImage_ZLibGZipVB)) + 12)
+      lArrayDataPtr = pDeref(pDeref(VarPtrArray(FreeImage_ZLibGZipVB)) + 12)
 
       ' copy uncompressed size into the first 4 bytes
       Call CopyMemory(ByVal lArrayDataPtr, UBound(Data) + 1, 4)
@@ -11508,7 +10825,7 @@ Dim lpArrayPtr As Long
       ' VARIANTARG structure is the VarPtr of the Variant variable in VB
       
       ' getting the contents of the data element (in C/C++: *(data + 8))
-      lpArrayPtr = deref(VarPtr(Data) + 8)
+      lpArrayPtr = pDeref(VarPtr(Data) + 8)
       
       ' call the 'FreeImage_DestroyLockedArrayByPtr' function to destroy
       ' the array properly
@@ -11528,7 +10845,7 @@ Dim lpSA As Long
    ' descriptor by a pointer to the array variable.
 
    ' dereference the pointer once (in C/C++: *ArrayPtr)
-   lpSA = deref(ArrayPtr)
+   lpSA = pDeref(ArrayPtr)
    ' now 'lpSA' is a pointer to the actual SAFEARRAY structure
    ' and could be a null pointer when the array is not initialized
    ' then, we have nothing to do here but return (-1) to indicate
@@ -11769,7 +11086,7 @@ Dim i As Long
       ' we copy Len(tTag) bytes from the address in TagPtr in to a
       ' private FITAG structure tTag so we have easy access to all
       ' FITAG members
-      Call CopyMemory(tTag, ByVal deref(TagPtr), Len(tTag))
+      Call CopyMemory(tTag, ByVal pDeref(TagPtr), Len(tTag))
       
       With pGetTagFromTagPtr
       
@@ -11807,7 +11124,6 @@ Dim i As Long
          ' also store this tag representation in our structure
          .StringValue = FreeImage_TagToString(Model, TagPtr)
          
-         
          ' now comes the hard part, getting the tag's value
          
          Select Case .Type
@@ -11913,9 +11229,12 @@ Dim i As Long
                   ' normalze the signed rational value
                   Call pNormalizeSRational(.RationalValue(i))
                End If
-               ' store the current fraction's (maybe only approximated) value in
-               ' the 'Value' member of the FREE_IMAGE_TAG structure
-               .Value(i) = .RationalValue(i).Numerator / .RationalValue(i).Denominator
+               ' store the current fraction's value (maybe only approximated) in
+               ' the 'Value' member of the FREE_IMAGE_TAG structure, if the
+               ' denominator is not zero
+               If (.RationalValue(i).Denominator <> 0) Then
+                  .Value(i) = .RationalValue(i).Numerator / .RationalValue(i).Denominator
+               End If
             Next i
             
          Case FIDT_SBYTE
@@ -12100,7 +11419,7 @@ Dim vntTemp As Variant
       ' but VB's Mod operator fails for unsigned
       ' long values stored in currency variables
       ' so, we use the mathematical definition of
-      ' the modulo operator taken from WikipediA.
+      ' the modulo operator taken from Wikipedia.
       b = a - floor(a / b) * b
       a = vntTemp
    Loop
@@ -12110,7 +11429,7 @@ End Function
 
 Private Function floor(ByRef a As Variant) As Variant
 
-   ' this is a VB version of the floor() function
+   ' This is a VB version of the floor() function.
    If (a < 0) Then
       floor = VBA.Int(a)
    Else
@@ -12138,7 +11457,7 @@ Dim lCount As Long
 
    With Tag
    
-      lpTag = deref(.TagPtr)
+      lpTag = pDeref(.TagPtr)
       
       ' save current (FITAG) tag for an optional 'undo' operation
       ' invoked on failure
@@ -12457,7 +11776,7 @@ Dim lLength As Long
 
 End Function
 
-Private Function deref(ByVal Ptr As Long) As Long
+Private Function pDeref(ByVal Ptr As Long) As Long
 
    ' This function dereferences a pointer and returns the
    ' contents as it's return value.
@@ -12465,7 +11784,7 @@ Private Function deref(ByVal Ptr As Long) As Long
    ' in C/C++ this would be:
    ' return *(ptr);
    
-   Call CopyMemory(deref, ByVal Ptr, 4)
+   Call CopyMemory(pDeref, ByVal Ptr, 4)
 
 End Function
 
@@ -12610,10 +11929,10 @@ Dim lDataPtr As Long
       ' VARIANTARG structure is the VarPtr of the Variant variable in VB
       
       ' getting the contents of the data element (in C/C++: *(data + 8))
-      lDataPtr = deref(VarPtr(Data) + 8)
+      lDataPtr = pDeref(VarPtr(Data) + 8)
       
       ' dereference the pointer again (in C/C++: *(lDataPtr))
-      lDataPtr = deref(lDataPtr)
+      lDataPtr = pDeref(lDataPtr)
       
       ' test, whether 'lDataPtr' now is a Null pointer
       ' in that case, the array is not yet initialized and so we can't dereference
@@ -12652,7 +11971,7 @@ Dim lDataPtr As Long
          ' of 12 bytes from the base address of the structure,
          ' so dereference the pvData pointer, what indeed is a pointer
          ' to the actual array (in C/C++: *(lDataPtr + 12))
-         lDataPtr = deref(lDataPtr + 12)
+         lDataPtr = pDeref(lDataPtr + 12)
       End If
       
       ' return this value
@@ -12660,7 +11979,374 @@ Dim lDataPtr As Long
       
       ' a more shorter form of this function would be:
       ' (doesn't work for uninitialized arrays, but will likely crash!)
-      'pGetArrayPtrFromVariantArray = deref(deref(deref(VarPtr(data) + 8)) + 12)
-   End If
+      'pGetArrayPtrFromVariantArray = pDeref(pDeref(pDeref(VarPtr(data) + 8)) + 12)
+   End If
+
+End Function
+
+
+#If (False) Then
+
+' Enum STRETCH_MODE
+Const STRETCH_MODE = 1
+Const SM_BLACKONWHITE = 1
+Const SM_WHITEONBLACK = 1
+Const SM_COLORONCOLOR = 1
+
+' Enum RASTER_OPERATOR
+Const RASTER_OPERATOR = 1
+Const ROP_SRCAND = 1
+Const ROP_SRCCOPY = 1
+Const ROP_SRCERASE = 1
+Const ROP_SRCINVERT = 1
+Const ROP_SRCPAINT = 1
+
+' Enum DRAW_MODE
+Const DRAW_MODE = 1
+Const DM_DRAW_DEFAULT = 1
+Const DM_MIRROR_NONE = 1
+Const DM_MIRROR_VERTICAL = 1
+Const DM_MIRROR_HORIZONTAL = 1
+Const DM_MIRROR_BOTH = 1
+
+' Enum HISTOGRAM_ORIENTATION
+Const HISTOGRAM_ORIENTATION = 1
+Const HOR_TOP_DOWN = 1
+Const HOR_BOTTOM_UP = 1
+
+' Enum FREE_IMAGE_ICC_COLOR_MODEL
+Const FREE_IMAGE_ICC_COLOR_MODEL = 1
+Const FIICC_COLOR_MODEL_RGB = 1
+Const FIICC_COLOR_MODEL_CMYK = 1
+
+' Enum FREE_IMAGE_FORMAT
+Const FREE_IMAGE_FORMAT = 1
+Const FIF_UNKNOWN = 1
+Const FIF_BMP = 1
+Const FIF_ICO = 1
+Const FIF_JPEG = 1
+Const FIF_JNG = 1
+Const FIF_KOALA = 1
+Const FIF_LBM = 1
+Const FIF_IFF = 1
+Const FIF_MNG = 1
+Const FIF_PBM = 1
+Const FIF_PBMRAW = 1
+Const FIF_PCD = 1
+Const FIF_PCX = 1
+Const FIF_PGM = 1
+Const FIF_PGMRAW = 1
+Const FIF_PNG = 1
+Const FIF_PPM = 1
+Const FIF_PPMRAW = 1
+Const FIF_RAS = 1
+Const FIF_TARGA = 1
+Const FIF_TIFF = 1
+Const FIF_WBMP = 1
+Const FIF_PSD = 1
+Const FIF_CUT = 1
+Const FIF_XBM = 1
+Const FIF_XPM = 1
+Const FIF_DDS = 1
+Const FIF_GIF = 1
+Const FIF_HDR = 1
+Const FIF_FAXG3 = 1
+Const FIF_SGI = 1
+Const FIF_EXR = 1
+Const FIF_J2K = 1
+Const FIF_JP2 = 1
+Const FIF_PFM = 1
+Const FIF_PICT = 1
+Const FIF_RAW = 1
+Const FIF_WEBP = 1
+Const FIF_JXR = 1
+
+' Enum FREE_IMAGE_LOAD_OPTIONS
+Const FREE_IMAGE_LOAD_OPTIONS = 1
+Const FILO_LOAD_NOPIXELS = 1
+Const FILO_LOAD_DEFAULT = 1
+Const FILO_GIF_DEFAULT = 1
+Const FILO_GIF_LOAD256 = 1
+Const FILO_GIF_PLAYBACK = 1
+Const FILO_ICO_DEFAULT = 1
+Const FILO_ICO_MAKEALPHA = 1
+Const FILO_JPEG_DEFAULT = 1
+Const FILO_JPEG_FAST = 1
+Const FILO_JPEG_ACCURATE = 1
+Const FILO_JPEG_CMYK = 1
+Const FILO_JPEG_EXIFROTATE = 1
+Const FILO_JPEG_GREYSCALE = 1
+Const FILO_PCD_DEFAULT = 1
+Const FILO_PCD_BASE = 1
+Const FILO_PCD_BASEDIV4 = 1
+Const FILO_PCD_BASEDIV16 = 1
+Const FILO_PNG_DEFAULT = 1
+Const FILO_PNG_IGNOREGAMMA = 1
+Const FILO_PSD_CMYK = 1
+Const FILO_PSD_LAB = 1
+Const FILO_RAW_DEFAULT = 1
+Const FILO_RAW_PREVIEW = 1
+Const FILO_RAW_DISPLAY = 1
+Const FILO_RAW_HALFSIZE = 1
+Const FILO_TARGA_DEFAULT = 1
+Const FILO_TARGA_LOAD_RGB888 = 1
+Const FISO_TIFF_DEFAULT = 1
+Const FISO_TIFF_CMYK = 1
+
+' Enum FREE_IMAGE_SAVE_OPTIONS
+Const FREE_IMAGE_SAVE_OPTIONS = 1
+Const FISO_SAVE_DEFAULT = 1
+Const FISO_BMP_DEFAULT = 1
+Const FISO_BMP_SAVE_RLE = 1
+Const FISO_EXR_DEFAULT = 1
+Const FISO_EXR_FLOAT = 1
+Const FISO_EXR_NONE = 1
+Const FISO_EXR_ZIP = 1
+Const FISO_EXR_PIZ = 1
+Const FISO_EXR_PXR24 = 1
+Const FISO_EXR_B44 = 1
+Const FISO_EXR_LC = 1
+Const FISO_JPEG_DEFAULT = 1
+Const FISO_JPEG_QUALITYSUPERB = 1
+Const FISO_JPEG_QUALITYGOOD = 1
+Const FISO_JPEG_QUALITYNORMAL = 1
+Const FISO_JPEG_QUALITYAVERAGE = 1
+Const FISO_JPEG_QUALITYBAD = 1
+Const FISO_JPEG_PROGRESSIVE = 1
+Const FISO_JPEG_SUBSAMPLING_411 = 1
+Const FISO_JPEG_SUBSAMPLING_420 = 1
+Const FISO_JPEG_SUBSAMPLING_422 = 1
+Const FISO_JPEG_SUBSAMPLING_444 = 1
+Const FISO_JPEG_OPTIMIZE = 1
+Const FISO_JPEG_BASELINE = 1
+Const FISO_PNG_Z_BEST_SPEED = 1
+Const FISO_PNG_Z_DEFAULT_COMPRESSION = 1
+Const FISO_PNG_Z_BEST_COMPRESSION = 1
+Const FISO_PNG_Z_NO_COMPRESSION = 1
+Const FISO_PNG_INTERLACED = 1
+Const FISO_PNM_DEFAULT = 1
+Const FISO_PNM_SAVE_RAW = 1
+Const FISO_PNM_SAVE_ASCII = 1
+Const FISO_TARGA_SAVE_RLE = 1
+Const FISO_TIFF_DEFAULT = 1
+Const FISO_TIFF_CMYK = 1
+Const FISO_TIFF_PACKBITS = 1
+Const FISO_TIFF_DEFLATE = 1
+Const FISO_TIFF_ADOBE_DEFLATE = 1
+Const FISO_TIFF_NONE = 1
+Const FISO_TIFF_CCITTFAX3 = 1
+Const FISO_TIFF_CCITTFAX4 = 1
+Const FISO_TIFF_LZW = 1
+Const FISO_TIFF_JPEG = 1
+Const FISO_TIFF_LOGLUV = 1
+Const FISO_WEBP_LOSSLESS = 1
+Const FISO_JXR_LOSSLESS = 1
+Const FISO_JXR_PROGRESSIVE = 1
+
+' Enum FREE_IMAGE_TYPE
+Const FREE_IMAGE_TYPE = 1
+Const FIT_UNKNOWN = 1
+Const FIT_BITMAP = 1
+Const FIT_UINT16 = 1
+Const FIT_INT16 = 1
+Const FIT_UINT32 = 1
+Const FIT_INT32 = 1
+Const FIT_FLOAT = 1
+Const FIT_DOUBLE = 1
+Const FIT_COMPLEX = 1
+Const FIT_RGB16 = 1
+Const FIT_RGBA16 = 1
+Const FIT_RGBF = 1
+Const FIT_RGBAF = 1
+
+' Enum FREE_IMAGE_COLOR_TYPE
+Const FREE_IMAGE_COLOR_TYPE = 1
+Const FIC_MINISWHITE = 1
+Const FIC_MINISBLACK = 1
+Const FIC_RGB = 1
+Const FIC_PALETTE = 1
+Const FIC_RGBALPHA = 1
+Const FIC_CMYK = 1
+
+' Enum FREE_IMAGE_QUANTIZE
+Const FREE_IMAGE_QUANTIZE = 1
+Const FIQ_WUQUANT = 1
+Const FIQ_NNQUANT = 1
+
+' Enum FREE_IMAGE_DITHER
+Const FREE_IMAGE_DITHER = 1
+Const FID_FS = 1
+Const FID_BAYER4x4 = 1
+Const FID_BAYER8x8 = 1
+Const FID_CLUSTER6x6 = 1
+Const FID_CLUSTER8x8 = 1
+Const FID_CLUSTER16x16 = 1
+Const FID_BAYER16x16 = 1
+
+' Enum FREE_IMAGE_JPEG_OPERATION
+Const FREE_IMAGE_JPEG_OPERATION = 1
+Const FIJPEG_OP_NONE = 1
+Const FIJPEG_OP_FLIP_H = 1
+Const FIJPEG_OP_FLIP_V = 1
+Const FIJPEG_OP_TRANSPOSE = 1
+Const FIJPEG_OP_TRANSVERSE = 1
+Const FIJPEG_OP_ROTATE_90 = 1
+Const FIJPEG_OP_ROTATE_180 = 1
+Const FIJPEG_OP_ROTATE_270 = 1
+
+' Enum FREE_IMAGE_TMO
+Const FREE_IMAGE_TMO = 1
+Const FITMO_DRAGO03 = 1
+Const FITMO_REINHARD05 = 1
+Const FITMO_FATTAL02 = 1
+
+' Enum FREE_IMAGE_FILTER
+Const FREE_IMAGE_FILTER = 1
+Const FILTER_BOX = 1
+Const FILTER_BICUBIC = 1
+Const FILTER_BILINEAR = 1
+Const FILTER_BSPLINE = 1
+Const FILTER_CATMULLROM = 1
+Const FILTER_LANCZOS3 = 1
+
+' Enum FREE_IMAGE_COLOR_CHANNEL
+Const FREE_IMAGE_COLOR_CHANNEL = 1
+Const FICC_RGB = 1
+Const FICC_RED = 1
+Const FICC_GREEN = 1
+Const FICC_BLUE = 1
+Const FICC_ALPHA = 1
+Const FICC_BLACK = 1
+Const FICC_REAL = 1
+Const FICC_IMAG = 1
+Const FICC_MAG = 1
+Const FICC_PHASE = 1
+
+' Enum FREE_IMAGE_MDTYPE
+Const FREE_IMAGE_MDTYPE = 1
+Const FIDT_NOTYPE = 1
+Const FIDT_BYTE = 1
+Const FIDT_ASCII = 1
+Const FIDT_SHORT = 1
+Const FIDT_LONG = 1
+Const FIDT_RATIONAL = 1
+Const FIDT_SBYTE = 1
+Const FIDT_UNDEFINED = 1
+Const FIDT_SSHORT = 1
+Const FIDT_SLONG = 1
+Const FIDT_SRATIONAL = 1
+Const FIDT_FLOAT = 1
+Const FIDT_DOUBLE = 1
+Const FIDT_IFD = 1
+Const FIDT_PALETTE = 1
+
+' Enum FREE_IMAGE_MDMODEL
+Const FREE_IMAGE_MDMODEL = 1
+Const FIMD_NODATA = 1
+Const FIMD_COMMENTS = 1
+Const FIMD_EXIF_MAIN = 1
+Const FIMD_EXIF_EXIF = 1
+Const FIMD_EXIF_GPS = 1
+Const FIMD_EXIF_MAKERNOTE = 1
+Const FIMD_EXIF_INTEROP = 1
+Const FIMD_IPTC = 1
+Const FIMD_XMP = 1
+Const FIMD_GEOTIFF = 1
+Const FIMD_ANIMATION = 1
+Const FIMD_CUSTOM = 1
+Const FIMD_EXIF_RAW = 1
+
+' Enum FREE_IMAGE_FRAME_DISPOSAL_METHODS
+Const FREE_IMAGE_FRAME_DISPOSAL_METHODS = 1
+Const FIFD_GIF_DISPOSAL_UNSPECIFIED = 1
+Const FIFD_GIF_DISPOSAL_LEAVE = 1
+Const FIFD_GIF_DISPOSAL_BACKGROUND = 1
+Const FIFD_GIF_DISPOSAL_PREVIOUS = 1
+
+' Enum FREE_IMAGE_COLOR_OPTIONS
+Const FREE_IMAGE_COLOR_OPTIONS = 1
+Const FI_COLOR_IS_RGB_COLOR = 1
+Const FI_COLOR_IS_RGBA_COLOR = 1
+Const FI_COLOR_FIND_EQUAL_COLOR = 1
+Const FI_COLOR_ALPHA_IS_INDEX = 1
+
+' Enum FREE_IMAGE_CONVERSION_FLAGS
+Const FREE_IMAGE_CONVERSION_FLAGS = 1
+Const FICF_MONOCHROME = 1
+Const FICF_MONOCHROME_THRESHOLD = 1
+Const FICF_MONOCHROME_DITHER = 1
+Const FICF_GREYSCALE_4BPP = 1
+Const FICF_PALLETISED_8BPP = 1
+Const FICF_GREYSCALE_8BPP = 1
+Const FICF_GREYSCALE = 1
+Const FICF_RGB_15BPP = 1
+Const FICF_RGB_16BPP = 1
+Const FICF_RGB_24BPP = 1
+Const FICF_RGB_32BPP = 1
+Const FICF_RGB_ALPHA = 1
+Const FICF_KEEP_UNORDERED_GREYSCALE_PALETTE = 1
+Const FICF_REORDER_GREYSCALE_PALETTE = 1
+
+' Enum FREE_IMAGE_COLOR_DEPTH
+Const FREE_IMAGE_COLOR_DEPTH = 1
+Const FICD_AUTO = 1
+Const FICD_MONOCHROME = 1
+Const FICD_MONOCHROME_THRESHOLD = 1
+Const FICD_MONOCHROME_DITHER = 1
+Const FICD_1BPP = 1
+Const FICD_4BPP = 1
+Const FICD_8BPP = 1
+Const FICD_15BPP = 1
+Const FICD_16BPP = 1
+Const FICD_24BPP = 1
+Const FICD_32BPP = 1
+
+' Enum FREE_IMAGE_ADJUST_MODE
+Const FREE_IMAGE_ADJUST_MODE = 1
+Const AM_STRECH = 1
+Const AM_DEFAULT = 1
+Const AM_ADJUST_BOTH = 1
+Const AM_ADJUST_WIDTH = 1
+Const AM_ADJUST_HEIGHT = 1
+Const AM_ADJUST_OPTIMAL_SIZE = 1
+
+' Enum FREE_IMAGE_MASK_FLAGS
+Const FREE_IMAGE_MASK_FLAGS = 1
+Const FIMF_MASK_NONE = 1
+Const FIMF_MASK_FULL_TRANSPARENCY = 1
+Const FIMF_MASK_ALPHA_TRANSPARENCY = 1
+Const FIMF_MASK_COLOR_TRANSPARENCY = 1
+Const FIMF_MASK_FORCE_TRANSPARENCY = 1
+Const FIMF_MASK_INVERSE_MASK = 1
+
+' Enum FREE_IMAGE_MASK_CREATION_OPTION_FLAGS
+Const FREE_IMAGE_MASK_CREATION_OPTION_FLAGS = 1
+Const MCOF_CREATE_MASK_IMAGE = 1
+Const MCOF_MODIFY_SOURCE_IMAGE = 1
+Const MCOF_CREATE_AND_MODIFY = 1
+
+' Enum FREE_IMAGE_TRANSPARENCY_STATE_FLAGS
+Const FREE_IMAGE_TRANSPARENCY_STATE_FLAGS = 1
+Const FITSF_IGNORE_TRANSPARENCY = 1
+Const FITSF_NONTRANSPARENT = 1
+Const FITSF_TRANSPARENT = 1
+Const FITSF_INCLUDE_ALPHA_TRANSPARENCY = 1
+
+' Enum FREE_IMAGE_ICON_TRANSPARENCY_OPTION_FLAGS
+Const FREE_IMAGE_ICON_TRANSPARENCY_OPTION_FLAGS = 1
+Const ITOF_NO_TRANSPARENCY = 1
+Const ITOF_USE_TRANSPARENCY_INFO = 1
+Const ITOF_USE_TRANSPARENCY_INFO_ONLY = 1
+Const ITOF_USE_COLOR_TRANSPARENCY = 1
+Const ITOF_USE_COLOR_TRANSPARENCY_ONLY = 1
+Const ITOF_USE_TRANSPARENCY_INFO_OR_COLOR = 1
+Const ITOF_USE_DEFAULT_TRANSPARENCY = 1
+Const ITOF_USE_COLOR_TOP_LEFT_PIXEL = 1
+Const ITOF_USE_COLOR_FIRST_PIXEL = 1
+Const ITOF_USE_COLOR_TOP_RIGHT_PIXEL = 1
+Const ITOF_USE_COLOR_BOTTOM_LEFT_PIXEL = 1
+Const ITOF_USE_COLOR_BOTTOM_RIGHT_PIXEL = 1
+Const ITOF_USE_COLOR_SPECIFIED = 1
+Const ITOF_FORCE_TRANSPARENCY_INFO = 1
 
-End Function
+#End If
diff --git a/Wrapper/VB6/mfreeimage/WhatsNew_VB.txt b/Wrapper/VB6/mfreeimage/WhatsNew_VB.txt
index 7268ecd..f71652e 100644
--- a/Wrapper/VB6/mfreeimage/WhatsNew_VB.txt
+++ b/Wrapper/VB6/mfreeimage/WhatsNew_VB.txt
@@ -5,16 +5,53 @@ What's New for FreeImage VB Wrapper
 ! : changed
 + : added
 
-October 1, 2012 - 2.17
+August 08, 2014 - 2.24 (3.16.0)
+- [Carsten Klein] removed declaration of Win32 API function FillMemory
++ [Carsten Klein] added load flag RAW_UNPROCESSED and corresponding FILO_RAW_UNPROCESSED
++ [Carsten Klein] added function FreeImage_SetMetadataKeyValue
+! [Carsten Klein] changed name of function FreeImage_ConvertFromRawBitsEx to FreeImage_ConvertFromRawBitsArray: naming conflict with new C/C++ function FreeImage_ConvertFromRawBitsEx
+! [Carsten Klein] changed name of function FreeImage_ConvertToRawBitsEx to FreeImage_ConvertToRawBitsArray: no naming conflict, but tried to keep To and From functions together
++ [Carsten Klein] added function FreeImage_ConvertFromRawBitsEx
+
+March 17, 2014 - 2.22 (3.16.0)
+* [Carsten Klein] renamed parameter 'Perfect' to 'Bottom' of functions FreeImage_JPEGCrop[U] to match native function declaration
+! [Carsten Klein] changed default value of optional parameter 'Perfect' to True for functions FreeImage_JPEGTransform[U]
+* [Carsten Klein] renamed function FreeImage_ApplyIndexMapping[Ex] to FreeImage_ApplyPaletteIndexMapping[Ex] (declarations and implementations)
++ [Carsten Klein] added functions FreeImage_JPEGTransformCombined[U] (declarations and implementations)
++ [Carsten Klein] added function FreeImage_JPEGTransformCombinedFromMemory (declarations and implementations)
++ [Carsten Klein] added wrapper functions FreeImage_JPEGTransformCombinedFromMemoryEx[2] working with more VB compatible memory representations (Variant and Byte array)
+! [Carsten Klein] enhanced documentation of extended memory stream functions FreeImage_[Load|Save][MultiBitmap][From|To]MemoryEx[2]
+
+March 10, 2014 - 2.21 (3.16.0)
++ [Carsten Klein] added support for the new JPEG-XR image format
+
+October 10, 2013 - 2.20 (3.16.0)
+* [Carsten Klein] prevented a potential 'Division by zero' error in private helper function pGetTagFromTagPtr. Thanks to Bob Weiss for pointing that out.
++ [Carsten Klein] added support for the new Google WebP image format
+! [Carsten Klein] refactored and centralized all VB6 IDE tweaking constant definitions into one single '#If False' block at the end of the file
+! [Carsten Klein] changed constants FREEIMAGE_MINOR_VERSION and FREEIMAGE_RELEASE_SERIAL to match current version 3.16.0
+- [Carsten Klein] removed change log entries from source file MFreeImage.bas
+- [Carsten Klein] removed block 'General notes' form source file MFreeImage.bas
+
+March 14, 2013 - 2.19 (3.15.4)
+* [J�rgen Hartmann] fixed coordinate calculation in FreeImage_PaintDCEx applied for horizontal and/or vertical mirroring, which now works correctly for all XDst and YDst coordinates.
+
+November 13, 2012 - 2.18 (3.15.4)
++ [Carsten Klein] added function declaration FreeImage_HasRGBMasksInt and a real VB Boolean returning function FreeImage_HasRGBMasks.
+- [Carsten Klein] removed members red, green and blue from BITMAPINFOHEADER struct: these were intended for debugging purposes only and could couse a GPF in FreeImage_GetInfoHeaderEx.
+* [Carsten Klein] fixed a bug in FreeImage_GetPictureData introduced in version 2.17.
+* [Carsten Klein] fixed a bug with declaration of FreeImage_Rotate: added default value 0 for Optional ByRef ... As Any parameter 'Color'.
+
+October 1, 2012 - 2.17 (3.15.4)
 - [Carsten Klein] removed temporary workaround for 16-bit standard type bitmaps introduced in version 2.15, which temporarily stored RGB masks directly after the BITMAPINFO structure, when creating a HBITMAP.
 * [Carsten Klein] fixed a potential overflow bug in both pNormalizeRational and pNormalizeSRational: these now do nothing if any of numerator and denominator is either 1 or 0 (zero).
 + [Carsten Klein] added load flag JPEG_GREYSCALE as well as the enum constant FILO_JPEG_GREYSCALE.
 ! [Carsten Klein] changed constant FREEIMAGE_RELEASE_SERIAL to 4 to match current version 3.15.4
 
-March 19, 2012 - 2.16
+March 19, 2012 - 2.16 (3.15.3)
 ! [Carsten Klein] changed constant FREEIMAGE_RELEASE_SERIAL to 3 to match current version 3.15.3
 
-March 12, 2012 - 2.15
+March 12, 2012 - 2.15 (3.15.2)
 + [Carsten Klein] added function FreeImage_ConvertToUINT16.
 + [Carsten Klein] added function FreeImage_ConvertToRGB16.
 + [Carsten Klein] added function FreeImage_GetThumbnail.
@@ -26,23 +63,23 @@ March 12, 2012 - 2.15
 + [Carsten Klein] added a workaround for providing valid BITMAPINFO structures for non 555 16-bpp images to Windows API functions like CreateDIBSection, CreateDIBBitmap, StretchDIBits or SetDIBitsToDevice.
 ! [Carsten Klein] changed constants FREEIMAGE_MINOR_VERSION and FREEIMAGE_RELEASE_SERIAL: set to 15 and 2 respectively to match current version 3.15.2
 
-March 13, 2011 - 2.14
+March 13, 2011 - 2.14 (3.14.1)
 * [Glenn Thorpe] fixed a typo error with the call to FreeImage_HasPixels inside FreeImage_CreateMask. 
 
-August 11, 2010 - 2.13
+August 11, 2010 - 2.13 (3.14.1)
 + [Carsten Klein] added PSD load flags PSD_CMYK and PSD_LAB as well as the enum constants FILO_PSD_CYMK and FILO_PSD_LAB.
 + [Carsten Klein] added TIFF_LOGLUV save flag as well as the enum constant FISO_TIFF_LOGLUV.
 
-July 20, 2010 - 2.12
+July 20, 2010 - 2.12 (3.14.1)
 + [Carsten Klein] added support for the new EXIF_RAW metadata model by adding enum constant FIMD_EXIF_RAW.
 + [Carsten Klein] added the new FIF_LOAD_NOPIXELS flag as well as the enum constant FILO_LOAD_NOPIXELS.
 + [Carsten Klein] added function declaration FreeImage_HasPixelsInt and a real VB Boolean returning function FreeImage_HasPixels.
 + [Carsten Klein] added function declaration FreeImage_FIFSupportsNoPixelsInt and a real VB Boolean returning function FreeImage_FIFSupportsNoPixels.
 
-June 20, 2010 - 2.11
+June 20, 2010 - 2.11 (3.14.0)
 + [Carsten Klein] added new save flag JPEG_OPTIMIZE (also added FISO_JPEG_OPTIMIZE to enumeration FREE_IMAGE_SAVE_OPTIONS).
 
-April 20, 2010 - 2.10
+April 20, 2010 - 2.10 (3.14.0)
 + [Carsten Klein] added new save flag TARGA_SAVE_RLE (also added FISO_TARGA_SAVE_RLE to enumeration FREE_IMAGE_SAVE_OPTIONS).
 ! [Carsten Klein] changed constants FREEIMAGE_MINOR_VERSION and FREEIMAGE_RELEASE_SERIAL: set to 14 and 0 respectively to match current version 3.14.0
 + [Carsten Klein] added function FreeImage_ConvertToFloat.
@@ -80,30 +117,26 @@ April 20, 2010 - 2.10
 + [Carsten Klein] added wrapper function FreeImage_UnloadEx, which additionally sets the ByRef-passed Bitmap handle to zero after unloading.
 + [Carsten Klein] added wrapper functions ConvertColor and ConvertOleColor to convert VB-style BGR colors into RGB color values.
 
-! now FreeImage version 3.14.0
-
-February 9, 2010 - 2.9.1
+February 9, 2010 - 2.9.1 (3.13.1)
 * [Carsten Klein] fixed a bug in FreeImage_GetBackgroundColorAsLong: parameter 'bkcolor' is now properly passed ByRef.
 
-February 9, 2010 - 2.9
+February 9, 2010 - 2.9 (3.13.1)
 * [Carsten Klein] fixed a syntax typo
 
-February 8, 2010 - 2.8
+February 8, 2010 - 2.8 (3.13.1)
 * [Mike Weir] fixed a bug in function FreeImage_ApplyColorMappingEx: now properly includes all specified mapping entries
 * [Carsten Klein] fixed a bug in function FreeImage_ApplyIndexMappingEx: now properly includes all specified mapping entries
 * [Mike Weir] fixed a bug in function FreeImage_RescaleEx: now also rescales the image, if either the new width or height matches the image's current size
 * [WinAnd / Carsten Klein] fixed a bug in function FreeImage_GetTransparencyTableExClone: returns an uninitialized array if there is no transparency table
 * [WinAnd / Carsten Klein] fixed a bug in function FreeImage_SearchPalette: no longer crashes if there is no transparency table
 
-December 21, 2009 - 2.7
+December 21, 2009 - 2.7 (3.13.1)
 ! [Carsten Klein] changed constant FREEIMAGE_RELEASE_SERIAL: set to 1 to match current version 3.13.1
 
-! now FreeImage version 3.13.1
-
-December 18, 2009 - 2.6
+December 18, 2009 - 2.6 (3.13.0)
 - [Carsten Klein] removed usage of constants vbPicTypeBitmap and vbPicTypeIcon: these are not available in VBA environments like Excel, Access or Outlook.
 
-September 08, 2009 - 2.5
+September 08, 2009 - 2.5 (3.13.0)
 ! [Carsten Klein] changed constant FREEIMAGE_MINOR_VERSION: set to 13 to match current version 3.13.0
 + [Carsten Klein] added load flag constant JPEG_EXIFROTATE and new member FILO_JPEG_EXIFROTATE to enumeration FREE_IMAGE_LOAD_OPTIONS.
 + [Carsten Klein] added support for the PFM image format.
@@ -118,19 +151,17 @@ September 08, 2009 - 2.5
 + [Carsten Klein] added function FreeImage_Rotate.
 + [Carsten Klein] added wrapper function FreeImage_RotateIOP.
 
-! now FreeImage version 3.13.0
-
-March 18, 2009 - 2.4.2
+March 18, 2009 - 2.4.2 (3.11.0)
 + [Carsten Klein] added enumeration FREE_IMAGE_FRAME_DISPOSAL_METHODS, which provides the frame disposal options needed to create animated GIF files.
 
-July 29, 2008 - 2.4.1
+July 29, 2008 - 2.4.1 (3.11.0)
 * [Carsten Klein] minor documentation updates
 ! [Carsten Klein] renamed member FICF_PALETTISED_8BPP of enumeration FREE_IMAGE_CONVERSION_FLAGS into FICF_PALLETISED_8BPP.
 
-June 30, 2008 - 2.4
+June 30, 2008 - 2.4 (3.11.0)
 * [Carsten Klein] fixed some minor issues in FreeImage_PaintTransparent()
 
-June 06, 2008 - 2.3
+June 06, 2008 - 2.3 (3.11.0)
 + [Carsten Klein] added new compression flags to the JPEG and PNG plugins
 ! [Carsten Klein] renamed wrapper function FreeImage_CloneMetadata() to FreeImage_CloneMetadataEx(): now, there is a native function called FreeImage_CloneMetadata().
 + [Carsten Klein] added private and internal function declaration for FreeImage_CloneMetadata() along with it's public Boolean returning wrapper function.
@@ -140,9 +171,7 @@ June 06, 2008 - 2.3
 + [Carsten Klein] added wrapper function FreeImage_GetPalettePtr(): gets the pointer to a specified array of RGBQUADs: intended to be used together with any of the ColorQuantizeEx functions.
 ! [Carsten Klein] changed constant FREEIMAGE_MINOR_VERSION: set to 11 to match current version 3.11.0
 
-! now FreeImage version 3.11.0
-
-December 14, 2007 - 2.2.1
+December 14, 2007 - 2.2.1 (3.10.0)
 + [Carsten Klein] added constants for member 'biCompression' in BITMAPINFOHEADER struct
 + [Carsten Klein] added wrapper function FreeImage_GetInfoHeaderEx(), which returns a fully populated BITMAPINFOHEADER struct for a bitmap.
 * [Carsten Klein] fixed a bug in FreeImage_GetFileTypeFromMemoryEx(): now calls FreeImage_CloseMemory() releasing the hStream to prevent memory leaks.
@@ -150,15 +179,15 @@ December 14, 2007 - 2.2.1
 + [Carsten Klein] added wrapper function FreeImage_Colorize(): applies a colorized greyscale palettte obtained from FreeImage_GetColorizedPalette() to a bitmap.
 + [Carsten Klein] added wrapper function FreeImage_Sepia(): calls FreeImage_Colorize() with proper parameters to apply a so called sepia palette to a bitmap.
 
-December 12, 2007 - 2.2
+December 12, 2007 - 2.2 (3.10.0)
 * [Carsten Klein] Fixed a small bug in FreeImage_PaintTransparent, which now calls function FreeImage_ConvertTo32Bits instead of FreeImage_ConvertTo32Bits2.
 
-November 15, 2007 - 2.1
+November 15, 2007 - 2.1 (3.10.0)
 * [Carsten Klein] adjusted page numbers of the API documentation in FreeImage function declarations to match FreeImage 3.10.0 API documentation
 - [Carsten Klein] removed parameter 'bUnloadSource' from function FreeImage_GetOlePictureIcon(): an hIcon should not be destroyed if OleCreatePictureIndirect() is called with fOwn = True.
 ! [Carsten Klein] refactored FreeImage_GetOlePicture(): now relies on FreeImage_GetBitmap().
 
-November 10, 2007 - 2.0.8
+November 10, 2007 - 2.0.8 (3.10.0)
 ! [Carsten Klein] changed declaration of FreeImage_SetOutputMessage(): now points transparently to the __stdcall version of this function in the library.
 + [Carsten Klein] added function declaraton for FreeImage_MultigridPoissonSolver().
 + [Carsten Klein] added function declaraton for FreeImage_GetTransparentIndex() and FreeImage_SetTransparentIndex().
@@ -172,24 +201,24 @@ November 10, 2007 - 2.0.8
 + [Carsten Klein] added wrapper function FreeImage_ApplyIndexMappingEx(): this takes a real VB style Byte array.
 + [Carsten Klein] added function declaraton for FreeImage_SwapPaletteIndices().
 
-November 05, 2007 - 2.0.7
+November 05, 2007 - 2.0.7 (3.10.0)
 + [Carsten Klein] added 4 bit color depth to both function pGetNextColorDepth() and pGetPrevousColorDepth()
 - [Carsten Klein] removed member FICF_PREPARE_RESCALE from enumeration FREE_IMAGE_CONVERSION_FLAGS
 - [Carsten Klein] removed all references to FICF_PREPARE_RESCALE: Converting color depth before rescaling an image is no longer performed by the wrapper. Since FreeImage now transparently converts color depth on rescaling, doing this in the wrapper is no longer needed.
 ! [Carsten Klein] refactored wrapper function FreeImage_ConvertColorDepth(): removed case FICF_PREPARE_RESCALE; is now more similar to C# wrapper's version of this function.
 ! [Carsten Klein] refactored wrapper function FreeImage_SaveEx(): removed case FICF_PREPARE_RESCALE; is now more similar to C# wrapper's version of this function.
 
-September 14, 2007 - 2.0.6
+September 14, 2007 - 2.0.6 (3.10.0)
 + [Carsten Klein] added function declaration and Boolean wrapper function for FreeImage_PreMultiplyWithAlpha().
 
-July 26, 2007 - 2.0.5
+July 26, 2007 - 2.0.5 (3.10.0)
 + [Carsten Klein] added wrapper function FreeImage_GetBitmap(): returns an HBITMAP created by the CreateDIBSection() function and so has the same color depth as the original DIB.
 + [Carsten Klein] added wrapper function FreeImage_GetBitmapForDevice(): returns an HBITMAP created by the CreateDIBitmap() function and so has the same color depth as the specified reference DC or as the desktop, if the 'hDC' parameter was omitted.
 - [Carsten Klein] removed function declaration for GetWindowDC(): this function is no longer used.
 * [Carsten Klein] fixed a bug in wrapper function FreeImage_IsExtensionValidForFIF(): string comparison now includes a comma.
 * [Carsten Klein] fixed a bug in wrapper function FreeImage_IsFilenameValidForFIF(): string comparison now includes a comma.
 
-July 25, 2007 - 2.0.4
+July 25, 2007 - 2.0.4 (3.10.0)
 * [Carsten Klein] fixed a bug in function FreeImage_GetPaletteExClone(): now actually returns the palette as RGBQUAD array plus some other minor improvements
 + [Carsten Klein] added wrapper function FreeImage_GetPaletteExLongClone(): this function returns a VB style Byte array that is only wrapped around FreeImage's pointer to a DIB's transparency table.
 + [Carsten Klein] added wrapper function FreeImage_GetTransparencyTableEx(): this function returns a VB style Byte array that is only wrapped around FreeImage's pointer to a DIB's transparency table.
@@ -200,10 +229,10 @@ July 25, 2007 - 2.0.4
 + [Carsten Klein] added function declaration for DeleteDC()
 * [Carsten Klein] fixed a bug in wrapper function FreeImage_CreateFromScreen(): now the memory DC is deleted with the DeleteDC() function and no longer with the DeleteObject() function.
 
-July 05, 2007 - 2.0.3
+July 05, 2007 - 2.0.3 (3.10.0)
 + [Carsten Klein] added wrapper function FreeImage_GetFileTypeFromMemoryEx(): more VB friendly version of FreeImage_GetFileTypeFromMemory() which may take an array rather than a FIMEMORY stream.
 
-May 21, 2007 - 2.0.2
+May 21, 2007 - 2.0.2 (3.10.0)
 ! [Carsten Klein] changed constant FREEIMAGE_MINOR_VERSION: set to 10 to match current version 3.10.0
 ! [Carsten Klein] changed constant FREEIMAGE_RELEASE_SERIAL: set to 0 to match current version 3.10.0
 + [Carsten Klein] added image format constants FIF_EXR, FIF_J2K and FIF_JP2 to enumeration FREE_IMAGE_FORMAT.
@@ -213,15 +242,13 @@ May 21, 2007 - 2.0.2
 + [Carsten Klein] added save option constants for EXR format to enumeration FREE_IMAGE_SAVE_OPTIONS.
 + [Carsten Klein] added declared function FreeImage_TmoFattal02(): adds support for Gradient domain high dynamic range compression (R. Fattal, 2002)
 
-! now FreeImage version 3.10.0
-
-February 24, 2007 - 2.0.1
+February 24, 2007 - 2.0.1 (3.9.3)
 * [Carsten Klein] fixed a bug in function FreeImage_CreateFromScreen(): now size of image created is according to window to be captured if parameter 'hwnd' <> 0.
 + [Carsten Klein] added parameter 'bClientAreaOnly' to function FreeImage_CreateFromScreen().
 + [Carsten Klein] added blitting option 'CAPTUREBLT' when calling function BitBlt() in function FreeImage_CreateFromScreen().
 - [Carsten Klein] removed unused variable 'hDIB' from functions FreeImage_CreateFromScreen() and FreeImage_LoadEx(). Thanks to Bruce Rusk for pointing that out.
 
-February 16, 2007 - 2.0
+February 16, 2007 - 2.0 (3.9.3)
 ! [Carsten Klein] changed constant FREEIMAGE_RELEASE_SERIAL: set to 3 to match current version 3.9.3
 ! [Carsten Klein] changed JPEG load/save flag option values: changed constants and both enumerations FREE_IMAGE_LOAD_OPTIONS and FREE_IMAGE_SAVE_OPTIONS.
 + [Carsten Klein] added ICC Color Profile support:
@@ -236,9 +263,7 @@ February 16, 2007 - 2.0
 ! [Carsten Klein] changed behaviour of wrapper function FreeImage_RescaleEx() and all it's derived functions: no clone is returned if the actual and desired image size are the same.
 + [Carsten Klein] added parameter 'bForceCloneCreation' to wrapper function FreeImage_RescaleEx() and all it's derived functions.
 
-! now FreeImage version 3.9.3
-
-January 09, 2007 - 1.9.4
+January 09, 2007 - 1.9.4 (3.9.2)
 ! [Carsten Klein] changed scope of declared function FreeImage_GetFileTypeUInt(): is now private according to all other '...Int' functions wrapped by a VB-friendly function.
 ! [Carsten Klein] changed scope of declared function FreeImage_GetFIFFromFilenameUInt(): is now private according to all other '...Int' functions wrapped by a VB-friendly function.
 ! [Carsten Klein] changed signature of declared functions FreeImage_GetBackgroundColorInt() and FreeImage_SetBackgroundColorInt(): now both have a 'ByRef bkcolor As RGBQUAD' parameter instead of 'ByVal bkcolor As Long'.
@@ -248,19 +273,19 @@ January 09, 2007 - 1.9.4
 + [Carsten Klein] added wrapper functions FreeImage_GetBackgroundColorAsLong() and FreeImage_SetBackgroundColorAsLong(): both have a 'ByRef bkcolor As Long' parameter and so offer getting and setting the background color through a Long value.
 + [Carsten Klein] added wrapper functions FreeImage_GetBackgroundColorEx() and FreeImage_SetBackgroundColorEx(): both both take 4 ByRef Byte parameters 'Alpha', 'Red', 'Green' and 'Blue', one for each color component.
 
-January 05, 2007 - 1.9.3
+January 05, 2007 - 1.9.3 (3.9.2)
 + [Carsten Klein] added wrapper function FreeImage_GetLockedPageNumbersEx(): this returns a real VB-style array of Longs containing the page numbers of all locked pages.
 
-January 02, 2007 - 1.9.2
+January 02, 2007 - 1.9.2 (3.9.2)
 * [Carsten Klein] fixed a bug in inline description of function FreeImage_GetPaletteEx(): now tells to use function FreeImage_DestroyLockedArrayRGBQUAD() to free an array returned by this function.
 * [Carsten Klein] fixed some minor bugs in inline documentation.
 * [Carsten Klein] fixed a serious bug in function FreeImage_SaveEx(): parameter 'bUnloadSource' is now interpreted correctly under all circumstances.
 * [Carsten Klein] fixed some minor issues in function FreeImage_SaveEx().
 
-December 29, 2006 - 1.9.1
+December 29, 2006 - 1.9.1 (3.9.2)
 + [Carsten Klein] added enumeration item FID_BAYER16x16: now supports Bayer ordered dispersed dot dithering (order 4 dithering matrix).
 
-October 31, 2006 - 1.9
+October 31, 2006 - 1.9 (3.9.2)
 * [Carsten Klein] adjusted page numbers of the API documentation in header comments in FreeImage function declarations to match FreeImage 3.9.2 API documentation
 ! [Carsten Klein] changed constant FREEIMAGE_RELEASE_SERIAL: set to 2 to match current version 3.9.2
 + [Carsten Klein] added function declaration for FreeImage_JPEGCrop(): added both declaration and Boolean returning wrapper function.
@@ -268,9 +293,7 @@ October 31, 2006 - 1.9
 + [Carsten Klein] added function declaration for FreeImage_LoadMultiBitmapFromMemory().
 + [Carsten Klein] added wrapper function FreeImage_LoadMultiBitmapFromMemoryEx(): this is dealing with a VB style array (SAFEARRAY) like FreeImage_LoadFromMemoryEx() does.
 
-! now FreeImage version 3.9.2
-
-October 30, 2006 - 1.8
+October 30, 2006 - 1.8 (3.9.1)
 * [Carsten Klein] fixed a memory leak in wrapper function SavePictureEx(). Thanks to Roogames for reporting that bug.
 ! [Carsten Klein] changed return type of wrapper function SavePictureEx() to Boolean.
 + [Carsten Klein] added wrapper function FreeImage_SaveEx() which brings all the features, as there are inline size- and color conversion and format guessing, so far only known from SavePictureEx() for DIBs.
@@ -281,7 +304,7 @@ October 30, 2006 - 1.8
 + [Carsten Klein] added wrapper function FreeImage_LoadEx() which brings all the features, as there are inline size- and color conversion and format guessing, so far only known from LoadPictureEx() for DIBs.
 ! [Carsten Klein] changed wrapper function LoadPictureEx(): now this is only a thin wrapper for function FreeImage_LoadEx().
 
-October 13, 2006 - 1.7.2
+October 13, 2006 - 1.7.2 (3.9.1)
 + [Carsten Klein] added User32 function GetDesktopWindow()
 +                 added User32 function GetWindowDC()
 - [Carsten Klein] removed unused constants DI_MASK, DI_IMAGE and DI_NORMAL
@@ -293,23 +316,21 @@ October 13, 2006 - 1.7.2
 +                 added GDI32 function BitBlt()
 + [Carsten Klein] added wrapper function FreeImage_CreateFromScreen(): this function lets you capture the whole screen or any certain window
 
-October 10, 2006 - 1.7.1
+October 10, 2006 - 1.7.1 (3.9.1)
 ! [Carsten Klein] changed parameter name 'Page' into 'hPageDib' in declared function FreeImage_UnlockPage(). 'hPageDib' must be the (dib-)handle obtained from FreeImage_LockPage() and not the page number. Now, the declaration is less confusing. Thanks to Ender Wiggin.
 
-August 4, 2006 - 1.7
+August 4, 2006 - 1.7 (3.9.1)
 * [Carsten Klein] fixed a bug in pGetTagFromTagPtr(): removed overflow error when converting unsigned short tags (FIDT_SHORT) with values between 32768 and 65535. Thanks to Andr� Hendriks.
 ! [Carsten Klein] changed constant FREEIMAGE_RELEASE_SERIAL: set to 1 to match current version 3.9.1
 
-! now FreeImage version 3.9.1
-
-July 17, 2006 - 1.6
+July 17, 2006 - 1.6 (3.9.0)
 + [Carsten Klein] added more public wrapper functions for tag copying and cloning:
 +                 added function FreeImage_CopyMetadata()
 +                 added function FreeImage_CloneMetadata()
 - [Carsten Klein] removed dead API functions, dead structures and dead variables
 * [Carsten Klein] fixed a bug in FreeImage_ConvertColorDepth(): now color images are converted to 24 bits when used with FICF_PREPARE_RESCALE, all others to 8 bit
 
-July 16, 2006 - 1.5.6
+July 16, 2006 - 1.5.6 (3.9.0)
 + [Carsten Klein] added more public wrapper functions for VB friendly tag access: these functions deal with a FREE_IMAGE_TAG structure instead of FreeImage's Tag pointer.
 +                 added function FreeImage_SetMetadataEx()
 +                 added function FreeImage_CreateTagEx()
@@ -335,15 +356,15 @@ July 16, 2006 - 1.5.6
 +                 added helper function pGetVariantAsByteBuffer()
 +                 added helper function pGetElementSize()
 
-July 5, 2006 - 1.5.5
+July 5, 2006 - 1.5.5 (3.9.0)
 ! [Carsten Klein] changed function signature of FreeImage_FindNextMetadataEx(): optional parameter 'Model' is now present; see the function's inline documentation
 
-June 30, 2006 - 1.5.4
+June 30, 2006 - 1.5.4 (3.9.0)
 * [Carsten Klein] fixed bug in functions creating a FreeImage DIB from a windows hBitmap: workaround for palettized bitmaps is now implemented
 *                 fixed function FreeImage_CreateFromOLEPicture()
 *                 fixed function FreeImage_CreateFromDC()
 
-June 22, 2006 - 1.5.3
+June 22, 2006 - 1.5.3 (3.9.0)
 ! [Carsten Klein] changed function declaration of FreeImage_GetMetadataInt(): parameter 'model' is now 'ByVal' and Tag is a Long pointer
 ! [Carsten Klein] changed function declaration of FreeImage_SetMetadataInt(): parameter 'model' is now 'ByVal' and Tag is a Long pointer
 ! [Carsten Klein] changed function declaration of FreeImage_GetMetadata(): parameter Tag is a Long pointer now
@@ -364,7 +385,7 @@ June 22, 2006 - 1.5.3
 - [Carsten Klein] removed workaround for thresholding and dithering non-MINISBLACK 8 bit images in function FreeImage_ConvertColorDepth(): was fixed in FreeImage 3.9.0
 * [Carsten Klein] fixed all pending issues in function FreeImage_PaintDC(): is now in production state
 
-June 14, 2006 - 1.5.2
+June 14, 2006 - 1.5.2 (3.9.0)
 ! [Carsten Klein] changed signature of function FreeImage_CreateMask()
 + [Carsten Klein] added function FreeImage_CreateMaskImage(): this creates a monochrome mask from a source image
 + [Carsten Klein] added function FreeImage_CreateMaskInPlace(): this creates a monochrome mask from a source image
@@ -395,7 +416,7 @@ June 14, 2006 - 1.5.2
 +                 added item 'Palette() As RGBQUAD'
 +                 added item 'RationalValue() As FIRATIONAL'
 
-June 13, 2006 - 1.5.1
+June 13, 2006 - 1.5.1 (3.9.0)
 ! [Carsten Klein] changed version constant 'FREEIMAGE_MINOR_VERSION' to 9 to meet version 3.9.0
 * [Carsten Klein] fixed and adjusted page numbers of the API documentation in header comments in FreeImage function declarations to match FreeImage 3.9.0 API documentation
 + [Carsten Klein] added function declaration for new Memory I/O functions in 3.9.0
@@ -417,15 +438,13 @@ June 13, 2006 - 1.5.1
 + [Carsten Klein] added enumeration FREE_IMAGE_teMask(): this creates a monochrome mask from a source image
 + [Carsten Klein] added function FreeImage_CreaMASK_CREATION_OPTION_FLAGS
 
-! now FreeImage version 3.9.0
-
-June 12, 2006 - 1.5
+June 12, 2006 - 1.5 (3.8.0)
 * [Carsten Klein] fixed bug in wrapper function FreeImage_PaintDCEx(): now handles boolean test correctly: 'If ((hDC <> 0) And (hDIB <> 0)) Then -> Thanks to ender_wiggin for reporting that bug.
 + [Carsten Klein] added private function pGetIOlePictureFromContainer(): used to get IPicture from image hosting control (Form, PictureBox) including custom drawings
 + [Carsten Klein] added wrapper function FreeImage_CreateFromImageContainer(): used to create FreeImage DIB from image hosting control (Form, PictureBox) including custom drawings
 + [Carsten Klein] added wrapper function SaveImageContainerEx(): derivate of wrapper function 'SavePictureEx()': saves content of image hosting control (Form, PictureBox) including custom drawings
 
-February 27, 2006 - 1.4.8
+February 27, 2006 - 1.4.8 (3.8.0)
 + [Carsten Klein] added inline documentation for these wrapper functions:
 +                 documented function FreeImage_CompareColorsLongLong()
 +                 documented function FreeImage_CompareColorsRGBTRIPLELong()
@@ -439,7 +458,7 @@ February 27, 2006 - 1.4.8
 + [Carsten Klein] added declaration of GDI function GetCurrentObject() and constant OBJ_BITMAP
 + [Carsten Klein] added wrapper function FreeImage_IsAvailable(): used to test for existence of FreeImage Library (FreeImage.dll)
 
-February 9, 2006 - 1.4.7
+February 9, 2006 - 1.4.7 (3.8.0)
 + [Carsten Klein] added private helper function pGetPreviousColorDepth()
 + [Carsten Klein] added private helper function pGetNextColorDepth()
 ! [Carsten Klein] changed/extended signature of wrapper function SavePictureEx(): now includes a parameter 'ColorDepth'
@@ -447,13 +466,13 @@ February 9, 2006 - 1.4.7
 + [Carsten Klein] added error handling capabilities to wrapper function SavePictureEx()
 + [Carsten Klein] added/updated inline documentation of wrapper function SavePictureEx()
 
-October 31, 2005 - 1.4.6
+October 31, 2005 - 1.4.6 (3.8.0)
 + [Carsten Klein] added wrapper function FreeImage_SwapColorLong(): this converts from a RGB to a BGR color value stored in a Long and vice versa
 
-October 27, 2005 - 1.4.5
+October 27, 2005 - 1.4.5 (3.8.0)
 + [Carsten Klein] added function FreeImage_IsTransparencyTableTransparent(): checks for transparency directly on the transparency table
 
-October 13, 2005 - 1.4.4
+October 13, 2005 - 1.4.4 (3.8.0)
 + [Carsten Klein] added some functions to compare colors in different formats and with tolerance:
 +                 added function FreeImage_CompareColorsLongLong()
 +                 added function FreeImage_CompareColorsRGBTRIPLELong()
@@ -462,29 +481,27 @@ October 13, 2005 - 1.4.4
 + [Carsten Klein] added enumeration FREE_IMAGE_TRANSPARENCY_STATE_FLAGS
 + [Carsten Klein] added function FreeImage_SearchPalette(): to search the palette index for a given color
 
-October 13, 2005 - 1.4.3
+October 13, 2005 - 1.4.3 (3.8.0)
 + [Carsten Klein] added additional function declaration FreeImage_SetPixelColorByLong(): now color values may be provided in a long value
 + [Carsten Klein] added additional function declaration FreeImage_GetPixelColorByLong(): now color values may be received in a long value
 + [Carsten Klein] added function FreeImage_SetPixelColorEx(): color values may be provided by four different byte values
 + [Carsten Klein] added function FreeImage_GetPixelColorEx(): color values are returned through four different byte values
 
-October 11, 2005 - 1.4.2
+October 11, 2005 - 1.4.2 (3.8.0)
 * [Carsten Klein] fixed bug in wrapper function FreeImage_GetBitsExRGBQUAD(): now tests for and works with 32 bit images
 
-October 10, 2005 - 1.4.1
+October 10, 2005 - 1.4.1 (3.8.0)
 * [Carsten Klein] fixed serious bug in FreeImage_GetBitsEx...() functions: created custom array descriptor now really has two dimensions
 *                 fixed wrapper function FreeImage_GetBitsEx()
 *                 fixed wrapper function FreeImage_GetBitsExRGBTRIPLE()
 *                 fixed wrapper function FreeImage_GetBitsExRGBQUAD()
 
-September 9, 2005 - 1.4
+September 9, 2005 - 1.4 (3.8.0)
 ! [Carsten Klein] changed wrapper function FreeImage_ConvertColorDepth(): now uses FreeImage_ConvertToGreyscale
 + [Carsten Klein] added version numbers to change log
 + [Carsten Klein] added comments to IOlePicture aware toolkit and conversion functions
 * [Carsten Klein] fixed and adjusted page numbers of the API documentation in header comments in FreeImage function declarations
 
-! now FreeImage version 3.8.0
-
 September 8, 2005 - 1.3.5
 ! [Carsten Klein] changed version constant 'FREEIMAGE_MINOR_VERSION' to 8 to meet version 3.8.0
 + [Carsten Klein] added function declarations for UNICODE dealing functions with additional token 'Int' appended:
diff --git a/Wrapper/VB6/modFreeImage.bas b/Wrapper/VB6/modFreeImage.bas
new file mode 100644
index 0000000..373d28f
--- /dev/null
+++ b/Wrapper/VB6/modFreeImage.bas
@@ -0,0 +1,512 @@
+Attribute VB_Name = "FreeImage"
+Option Explicit
+
+Const unix As Long = 1
+Const linux As Long = 1
+Const i386 As Long = 1
+Const FREEIMAGE_MAJOR_VERSION As Long = 3
+Const FREEIMAGE_MINOR_VERSION As Long = 7
+Const FREEIMAGE_RELEASE_SERIAL As Long = 0
+Const SEEK_SET As Long = 0
+Const SEEK_CUR As Long = 1
+Const SEEK_END As Long = 2
+Const FI_RGBA_RED As Long = 2
+Const FI_RGBA_GREEN As Long = 1
+Const FI_RGBA_BLUE As Long = 0
+Const FI_RGBA_ALPHA As Long = 3
+Const FI_RGBA_RED_MASK As Long = &H00FF0000
+Const FI_RGBA_GREEN_MASK As Long = &H0000FF00
+Const FI_RGBA_BLUE_MASK As Long = &H000000FF
+Const FI_RGBA_ALPHA_MASK As Long = &HFF000000
+Const FI_RGBA_RED_SHIFT As Long = 16
+Const FI_RGBA_GREEN_SHIFT As Long = 8
+Const FI_RGBA_BLUE_SHIFT As Long = 0
+Const FI_RGBA_ALPHA_SHIFT As Long = 24
+Const FI16_555_RED_MASK As Long = &H7C00
+Const FI16_555_GREEN_MASK As Long = &H03E0
+Const FI16_555_BLUE_MASK As Long = &H001F
+Const FI16_555_RED_SHIFT As Long = 10
+Const FI16_555_GREEN_SHIFT As Long = 5
+Const FI16_555_BLUE_SHIFT As Long = 0
+Const FI16_565_RED_MASK As Long = &HF800
+Const FI16_565_GREEN_MASK As Long = &H07E0
+Const FI16_565_BLUE_MASK As Long = &H001F
+Const FI16_565_RED_SHIFT As Long = 11
+Const FI16_565_GREEN_SHIFT As Long = 5
+Const FI16_565_BLUE_SHIFT As Long = 0
+Const FIICC_DEFAULT As Long = &H00
+Const FIICC_COLOR_IS_CMYK As Long = &H01
+Const BMP_DEFAULT As Long = 0
+Const BMP_SAVE_RLE As Long = 1
+Const CUT_DEFAULT As Long = 0
+Const DDS_DEFAULT As Long = 0
+Const GIF_DEFAULT As Long = 0
+Const GIF_LOAD256 As Long = 1
+Const GIF_PLAYBACK As Long = 2
+Const HDR_DEFAULT As Long = 0
+Const ICO_DEFAULT As Long = 0
+Const ICO_MAKEALPHA As Long = 1
+Const IFF_DEFAULT As Long = 0
+Const JPEG_DEFAULT As Long = 0
+Const JPEG_FAST As Long = 1
+Const JPEG_ACCURATE As Long = 2
+Const JPEG_QUALITYSUPERB As Long = &H80
+Const JPEG_QUALITYGOOD As Long = &H100
+Const JPEG_QUALITYNORMAL As Long = &H200
+Const JPEG_QUALITYAVERAGE As Long = &H400
+Const JPEG_QUALITYBAD As Long = &H800
+Const JPEG_CMYK As Long = &H1000
+Const KOALA_DEFAULT As Long = 0
+Const LBM_DEFAULT As Long = 0
+Const MNG_DEFAULT As Long = 0
+Const PCD_DEFAULT As Long = 0
+Const PCD_BASE As Long = 1
+Const PCD_BASEDIV4 As Long = 2
+Const PCD_BASEDIV16 As Long = 3
+Const PCX_DEFAULT As Long = 0
+Const PNG_DEFAULT As Long = 0
+Const PNG_IGNOREGAMMA As Long = 1
+Const PNM_DEFAULT As Long = 0
+Const PNM_SAVE_RAW As Long = 0
+Const PNM_SAVE_ASCII As Long = 1
+Const PSD_DEFAULT As Long = 0
+Const RAS_DEFAULT As Long = 0
+Const TARGA_DEFAULT As Long = 0
+Const TARGA_LOAD_RGB888 As Long = 1
+Const TIFF_DEFAULT As Long = 0
+Const TIFF_CMYK As Long = &H0001
+Const TIFF_PACKBITS As Long = &H0100
+Const TIFF_DEFLATE As Long = &H0200
+Const TIFF_ADOBE_DEFLATE As Long = &H0400
+Const TIFF_NONE As Long = &H0800
+Const TIFF_CCITTFAX3 As Long = &H1000
+Const TIFF_CCITTFAX4 As Long = &H2000
+Const TIFF_LZW As Long = &H4000
+Const TIFF_JPEG As Long = &H8000
+Const WBMP_DEFAULT As Long = 0
+Const XBM_DEFAULT As Long = 0
+Const XPM_DEFAULT As Long = 0
+
+Public Enum FREE_IMAGE_FORMAT
+	FIF_UNKNOWN = -1
+	FIF_BMP = 0
+	FIF_ICO = 1
+	FIF_JPEG = 2
+	FIF_JNG = 3
+	FIF_KOALA = 4
+	FIF_LBM = 5
+	FIF_IFF = FIF_LBM
+	FIF_MNG = 6
+	FIF_PBM = 7
+	FIF_PBMRAW = 8
+	FIF_PCD = 9
+	FIF_PCX = 10
+	FIF_PGM = 11
+	FIF_PGMRAW = 12
+	FIF_PNG = 13
+	FIF_PPM = 14
+	FIF_PPMRAW = 15
+	FIF_RAS = 16
+	FIF_TARGA = 17
+	FIF_TIFF = 18
+	FIF_WBMP = 19
+	FIF_PSD = 20
+	FIF_CUT = 21
+	FIF_XBM = 22
+	FIF_XPM = 23
+	FIF_DDS = 24
+	FIF_GIF = 25
+	FIF_HDR = 26
+End Enum
+Public Enum FREE_IMAGE_TYPE
+	FIT_UNKNOWN = 0
+	FIT_BITMAP = 1
+	FIT_UINT16 = 2
+	FIT_INT16 = 3
+	FIT_UINT32 = 4
+	FIT_INT32 = 5
+	FIT_FLOAT = 6
+	FIT_DOUBLE = 7
+	FIT_COMPLEX = 8
+	FIT_RGB16 = 9
+	FIT_RGBA16 = 10
+	FIT_RGBF = 11
+	FIT_RGBAF = 12
+End Enum
+Public Enum FREE_IMAGE_COLOR_TYPE
+	FIC_MINISWHITE = 0
+	FIC_MINISBLACK = 1
+	FIC_RGB = 2
+	FIC_PALETTE = 3
+	FIC_RGBALPHA = 4
+	FIC_CMYK = 5
+End Enum
+Public Enum FREE_IMAGE_QUANTIZE
+	FIQ_WUQUANT = 0
+	FIQ_NNQUANT = 1
+End Enum
+Public Enum FREE_IMAGE_DITHER
+	FID_FS = 0
+	FID_BAYER4x4 = 1
+	FID_BAYER8x8 = 2
+	FID_CLUSTER6x6 = 3
+	FID_CLUSTER8x8 = 4
+	FID_CLUSTER16x16 = 5
+End Enum
+Public Enum FREE_IMAGE_JPEG_OPERATION
+	FIJPEG_OP_NONE = 0
+	FIJPEG_OP_FLIP_H = 1
+	FIJPEG_OP_FLIP_V = 2
+	FIJPEG_OP_TRANSPOSE = 3
+	FIJPEG_OP_TRANSVERSE = 4
+	FIJPEG_OP_ROTATE_90 = 5
+	FIJPEG_OP_ROTATE_180 = 6
+	FIJPEG_OP_ROTATE_270 = 7
+End Enum
+Public Enum FREE_IMAGE_TMO
+	FITMO_DRAGO03 = 0
+	FITMO_REINHARD05 = 1
+End Enum
+Public Enum FREE_IMAGE_FILTER
+	FILTER_BOX = 0
+	FILTER_BICUBIC = 1
+	FILTER_BILINEAR = 2
+	FILTER_BSPLINE = 3
+	FILTER_CATMULLROM = 4
+	FILTER_LANCZOS3 = 5
+End Enum
+Public Enum FREE_IMAGE_COLOR_CHANNEL
+	FICC_RGB = 0
+	FICC_RED = 1
+	FICC_GREEN = 2
+	FICC_BLUE = 3
+	FICC_ALPHA = 4
+	FICC_BLACK = 5
+	FICC_REAL = 6
+	FICC_IMAG = 7
+	FICC_MAG = 8
+	FICC_PHASE = 9
+End Enum
+Public Enum FREE_IMAGE_MDTYPE
+	FIDT_NOTYPE = 0
+	FIDT_BYTE = 1
+	FIDT_ASCII = 2
+	FIDT_SHORT = 3
+	FIDT_LONG = 4
+	FIDT_RATIONAL = 5
+	FIDT_SBYTE = 6
+	FIDT_UNDEFINED = 7
+	FIDT_SSHORT = 8
+	FIDT_SLONG = 9
+	FIDT_SRATIONAL = 10
+	FIDT_FLOAT = 11
+	FIDT_DOUBLE = 12
+	FIDT_IFD = 13
+	FIDT_PALETTE = 14
+End Enum
+Public Enum FREE_IMAGE_MDMODEL
+	FIMD_NODATA = -1
+	FIMD_COMMENTS = 0
+	FIMD_EXIF_MAIN = 1
+	FIMD_EXIF_EXIF = 2
+	FIMD_EXIF_GPS = 3
+	FIMD_EXIF_MAKERNOTE = 4
+	FIMD_EXIF_INTEROP = 5
+	FIMD_IPTC = 6
+	FIMD_XMP = 7
+	FIMD_GEOTIFF = 8
+	FIMD_ANIMATION = 9
+	FIMD_CUSTOM = 10
+End Enum
+
+Public Type FIBITMAP
+	data As Long
+End Type
+Public Type FIMULTIBITMAP
+	data As Long
+End Type
+Public Type RGBQUAD
+	rgbBlue As Byte
+	rgbGreen As Byte
+	rgbRed As Byte
+	rgbReserved As Byte
+End Type
+Public Type RGBTRIPLE
+	rgbtBlue As Byte
+	rgbtGreen As Byte
+	rgbtRed As Byte
+End Type
+Public Type BITMAPINFOHEADER
+	biSize As Long
+	biWidth As Long
+	biHeight As Long
+	biPlanes As Integer
+	biBitCount As Integer
+	biCompression As Long
+	biSizeImage As Long
+	biXPelsPerMeter As Long
+	biYPelsPerMeter As Long
+	biClrUsed As Long
+	biClrImportant As Long
+End Type
+Public Type BITMAPINFO
+	bmiHeader As BITMAPINFOHEADER
+	bmiColors(0) As RGBQUAD
+End Type
+Public Type FIRGB16
+	red As Integer
+	green As Integer
+	blue As Integer
+End Type
+Public Type FIRGBA16
+	red As Integer
+	green As Integer
+	blue As Integer
+	alpha As Integer
+End Type
+Public Type FIRGBF
+	red As Long
+	green As Long
+	blue As Long
+End Type
+Public Type FIRGBAF
+	red As Long
+	green As Long
+	blue As Long
+	alpha As Long
+End Type
+Public Type FICOMPLEX
+	r As Double
+	i As Double
+End Type
+Public Type FIICCPROFILE
+	flags As Integer
+	size As Long
+	data As Long
+End Type
+Public Type FIMETADATA
+	data As Long
+End Type
+Public Type FITAG
+	data As Long
+End Type
+Public Type FreeImageIO
+	read_proc As Long
+	write_proc As Long
+	seek_proc As Long
+	tell_proc As Long
+End Type
+Public Type FIMEMORY
+	data As Long
+End Type
+Public Type Plugin
+	format_proc As Long
+	description_proc As Long
+	extension_proc As Long
+	regexpr_proc As Long
+	open_proc As Long
+	close_proc As Long
+	pagecount_proc As Long
+	pagecapability_proc As Long
+	load_proc As Long
+	save_proc As Long
+	validate_proc As Long
+	mime_proc As Long
+	supports_export_bpp_proc As Long
+	supports_export_type_proc As Long
+	supports_icc_profiles_proc As Long
+End Type
+
+Public Declare Sub FreeImage_Initialise Lib "FreeImage.dll" Alias "_FreeImage_Initialise at 4" (Optional ByVal load_local_plugins_only As Long = 0)
+Public Declare Sub FreeImage_DeInitialise Lib "FreeImage.dll" Alias "_FreeImage_DeInitialise at 0" ()
+Public Declare Function FreeImage_GetVersion Lib "FreeImage.dll" Alias "_FreeImage_GetVersion at 0" () As Long
+Public Declare Function FreeImage_GetCopyrightMessage Lib "FreeImage.dll" Alias "_FreeImage_GetCopyrightMessage at 0" () As Long
+Public Declare Sub FreeImage_OutputMessageProc Lib "FreeImage.dll" Alias "_FreeImage_OutputMessageProc at 8" (ByVal fif As Long, ByVal fmt As String, ParamArray VarArgs() As Variant)
+Public Declare Sub FreeImage_SetOutputMessage Lib "FreeImage.dll" Alias "_FreeImage_SetOutputMessage at 4" (ByVal omf As Long)
+Public Declare Function FreeImage_Allocate Lib "FreeImage.dll" Alias "_FreeImage_Allocate at 24" (ByVal width As Long, ByVal height As Long, ByVal bpp As Long, Optional ByVal red_mask As Long = 0, Optional ByVal green_mask As Long = 0, Optional ByVal blue_mask As Long = 0) As Long
+Public Declare Function FreeImage_AllocateT Lib "FreeImage.dll" Alias "_FreeImage_AllocateT at 28" (ByVal type_ As FREE_IMAGE_TYPE, ByVal width As Long, ByVal height As Long, Optional ByVal bpp As Long = 8, Optional ByVal red_mask As Long = 0, Optional ByVal green_mask As Long = 0, Optional ByVal blue_mask As Long = 0) As Long
+Public Declare Function FreeImage_Clone Lib "FreeImage.dll" Alias "_FreeImage_Clone at 4" (ByVal dib As Long) As Long
+Public Declare Sub FreeImage_Unload Lib "FreeImage.dll" Alias "_FreeImage_Unload at 4" (ByVal dib As Long)
+Public Declare Function FreeImage_Load Lib "FreeImage.dll" Alias "_FreeImage_Load at 12" (ByVal fif As FREE_IMAGE_FORMAT, ByVal filename As String, Optional ByVal flags As Long = 0) As Long
+Public Declare Function FreeImage_LoadFromHandle Lib "FreeImage.dll" Alias "_FreeImage_LoadFromHandle at 16" (ByVal fif As FREE_IMAGE_FORMAT, ByVal io As Long, ByVal handle As Long, Optional ByVal flags As Long = 0) As Long
+Public Declare Function FreeImage_Save Lib "FreeImage.dll" Alias "_FreeImage_Save at 16" (ByVal fif As FREE_IMAGE_FORMAT, ByVal dib As Long, ByVal filename As String, Optional ByVal flags As Long = 0) As Long
+Public Declare Function FreeImage_SaveToHandle Lib "FreeImage.dll" Alias "_FreeImage_SaveToHandle at 20" (ByVal fif As FREE_IMAGE_FORMAT, ByVal dib As Long, ByVal io As Long, ByVal handle As Long, Optional ByVal flags As Long = 0) As Long
+Public Declare Function FreeImage_OpenMemory Lib "FreeImage.dll" Alias "_FreeImage_OpenMemory at 8" (Optional ByRef data As Long = 0, Optional ByVal size_in_bytes As Long = 0) As Long
+Public Declare Sub FreeImage_CloseMemory Lib "FreeImage.dll" Alias "_FreeImage_CloseMemory at 4" (ByVal stream As Long)
+Public Declare Function FreeImage_LoadFromMemory Lib "FreeImage.dll" Alias "_FreeImage_LoadFromMemory at 12" (ByVal fif As FREE_IMAGE_FORMAT, ByVal stream As Long, Optional ByVal flags As Long = 0) As Long
+Public Declare Function FreeImage_SaveToMemory Lib "FreeImage.dll" Alias "_FreeImage_SaveToMemory at 16" (ByVal fif As FREE_IMAGE_FORMAT, ByVal dib As Long, ByVal stream As Long, Optional ByVal flags As Long = 0) As Long
+Public Declare Function FreeImage_TellMemory Lib "FreeImage.dll" Alias "_FreeImage_TellMemory at 4" (ByVal stream As Long) As Long
+Public Declare Function FreeImage_SeekMemory Lib "FreeImage.dll" Alias "_FreeImage_SeekMemory at 12" (ByVal stream As Long, ByVal offset As Long, ByVal origin As Long) As Long
+Public Declare Function FreeImage_AcquireMemory Lib "FreeImage.dll" Alias "_FreeImage_AcquireMemory at 12" (ByVal stream As Long, ByRef data As Long, ByRef size_in_bytes As Long) As Long
+Public Declare Function FreeImage_RegisterLocalPlugin Lib "FreeImage.dll" Alias "_FreeImage_RegisterLocalPlugin at 20" (ByVal proc_address As Long, Optional ByVal format As String = 0, Optional ByVal description As String = 0, Optional ByVal extension As String = 0, Optional ByVal regexpr As String = 0) As FREE_IMAGE_FORMAT
+Public Declare Function FreeImage_RegisterExternalPlugin Lib "FreeImage.dll" Alias "_FreeImage_RegisterExternalPlugin at 20" (ByVal path As String, Optional ByVal format As String = 0, Optional ByVal description As String = 0, Optional ByVal extension As String = 0, Optional ByVal regexpr As String = 0) As FREE_IMAGE_FORMAT
+Public Declare Function FreeImage_GetFIFCount Lib "FreeImage.dll" Alias "_FreeImage_GetFIFCount at 0" () As Long
+Public Declare Function FreeImage_SetPluginEnabled Lib "FreeImage.dll" Alias "_FreeImage_SetPluginEnabled at 8" (ByVal fif As FREE_IMAGE_FORMAT, ByVal enable As Long) As Long
+Public Declare Function FreeImage_IsPluginEnabled Lib "FreeImage.dll" Alias "_FreeImage_IsPluginEnabled at 4" (ByVal fif As FREE_IMAGE_FORMAT) As Long
+Public Declare Function FreeImage_GetFIFFromFormat Lib "FreeImage.dll" Alias "_FreeImage_GetFIFFromFormat at 4" (ByVal format As String) As FREE_IMAGE_FORMAT
+Public Declare Function FreeImage_GetFIFFromMime Lib "FreeImage.dll" Alias "_FreeImage_GetFIFFromMime at 4" (ByVal mime As String) As FREE_IMAGE_FORMAT
+Public Declare Function FreeImage_GetFormatFromFIF Lib "FreeImage.dll" Alias "_FreeImage_GetFormatFromFIF at 4" (ByVal fif As FREE_IMAGE_FORMAT) As Long
+Public Declare Function FreeImage_GetFIFExtensionList Lib "FreeImage.dll" Alias "_FreeImage_GetFIFExtensionList at 4" (ByVal fif As FREE_IMAGE_FORMAT) As Long
+Public Declare Function FreeImage_GetFIFDescription Lib "FreeImage.dll" Alias "_FreeImage_GetFIFDescription at 4" (ByVal fif As FREE_IMAGE_FORMAT) As Long
+Public Declare Function FreeImage_GetFIFRegExpr Lib "FreeImage.dll" Alias "_FreeImage_GetFIFRegExpr at 4" (ByVal fif As FREE_IMAGE_FORMAT) As Long
+Public Declare Function FreeImage_GetFIFMimeType Lib "FreeImage.dll" Alias "_FreeImage_GetFIFMimeType at 4" (ByVal fif As FREE_IMAGE_FORMAT) As Long
+Public Declare Function FreeImage_GetFIFFromFilename Lib "FreeImage.dll" Alias "_FreeImage_GetFIFFromFilename at 4" (ByVal filename As String) As FREE_IMAGE_FORMAT
+Public Declare Function FreeImage_FIFSupportsReading Lib "FreeImage.dll" Alias "_FreeImage_FIFSupportsReading at 4" (ByVal fif As FREE_IMAGE_FORMAT) As Long
+Public Declare Function FreeImage_FIFSupportsWriting Lib "FreeImage.dll" Alias "_FreeImage_FIFSupportsWriting at 4" (ByVal fif As FREE_IMAGE_FORMAT) As Long
+Public Declare Function FreeImage_FIFSupportsExportBPP Lib "FreeImage.dll" Alias "_FreeImage_FIFSupportsExportBPP at 8" (ByVal fif As FREE_IMAGE_FORMAT, ByVal bpp As Long) As Long
+Public Declare Function FreeImage_FIFSupportsExportType Lib "FreeImage.dll" Alias "_FreeImage_FIFSupportsExportType at 8" (ByVal fif As FREE_IMAGE_FORMAT, ByVal type_ As FREE_IMAGE_TYPE) As Long
+Public Declare Function FreeImage_FIFSupportsICCProfiles Lib "FreeImage.dll" Alias "_FreeImage_FIFSupportsICCProfiles at 4" (ByVal fif As FREE_IMAGE_FORMAT) As Long
+Public Declare Function FreeImage_OpenMultiBitmap Lib "FreeImage.dll" Alias "_FreeImage_OpenMultiBitmap at 24" (ByVal fif As FREE_IMAGE_FORMAT, ByVal filename As String, ByVal create_new As Long, ByVal read_only As Long, Optional ByVal keep_cache_in_memory As Long = 0, Optional ByVal flags As Long = 0) As Long
+Public Declare Function FreeImage_CloseMultiBitmap Lib "FreeImage.dll" Alias "_FreeImage_CloseMultiBitmap at 8" (ByVal bitmap As Long, Optional ByVal flags As Long = 0) As Long
+Public Declare Function FreeImage_GetPageCount Lib "FreeImage.dll" Alias "_FreeImage_GetPageCount at 4" (ByVal bitmap As Long) As Long
+Public Declare Sub FreeImage_AppendPage Lib "FreeImage.dll" Alias "_FreeImage_AppendPage at 8" (ByVal bitmap As Long, ByVal data As Long)
+Public Declare Sub FreeImage_InsertPage Lib "FreeImage.dll" Alias "_FreeImage_InsertPage at 12" (ByVal bitmap As Long, ByVal page As Long, ByVal data As Long)
+Public Declare Sub FreeImage_DeletePage Lib "FreeImage.dll" Alias "_FreeImage_DeletePage at 8" (ByVal bitmap As Long, ByVal page As Long)
+Public Declare Function FreeImage_LockPage Lib "FreeImage.dll" Alias "_FreeImage_LockPage at 8" (ByVal bitmap As Long, ByVal page As Long) As Long
+Public Declare Sub FreeImage_UnlockPage Lib "FreeImage.dll" Alias "_FreeImage_UnlockPage at 12" (ByVal bitmap As Long, ByVal page As Long, ByVal changed As Long)
+Public Declare Function FreeImage_MovePage Lib "FreeImage.dll" Alias "_FreeImage_MovePage at 12" (ByVal bitmap As Long, ByVal target As Long, ByVal source As Long) As Long
+Public Declare Function FreeImage_GetLockedPageNumbers Lib "FreeImage.dll" Alias "_FreeImage_GetLockedPageNumbers at 12" (ByVal bitmap As Long, ByRef pages As Long, ByRef count As Long) As Long
+Public Declare Function FreeImage_GetFileType Lib "FreeImage.dll" Alias "_FreeImage_GetFileType at 8" (ByVal filename As String, Optional ByVal size As Long = 0) As FREE_IMAGE_FORMAT
+Public Declare Function FreeImage_GetFileTypeFromHandle Lib "FreeImage.dll" Alias "_FreeImage_GetFileTypeFromHandle at 12" (ByVal io As Long, ByVal handle As Long, Optional ByVal size As Long = 0) As FREE_IMAGE_FORMAT
+Public Declare Function FreeImage_GetFileTypeFromMemory Lib "FreeImage.dll" Alias "_FreeImage_GetFileTypeFromMemory at 8" (ByVal stream As Long, Optional ByVal size As Long = 0) As FREE_IMAGE_FORMAT
+Public Declare Function FreeImage_GetImageType Lib "FreeImage.dll" Alias "_FreeImage_GetImageType at 4" (ByVal dib As Long) As FREE_IMAGE_TYPE
+Public Declare Function FreeImage_IsLittleEndian Lib "FreeImage.dll" Alias "_FreeImage_IsLittleEndian at 0" () As Long
+Public Declare Function FreeImage_LookupX11Color Lib "FreeImage.dll" Alias "_FreeImage_LookupX11Color at 16" (ByVal szColor As String, ByRef nRed As Long, ByRef nGreen As Long, ByRef nBlue As Long) As Long
+Public Declare Function FreeImage_LookupSVGColor Lib "FreeImage.dll" Alias "_FreeImage_LookupSVGColor at 16" (ByVal szColor As String, ByRef nRed As Long, ByRef nGreen As Long, ByRef nBlue As Long) As Long
+Public Declare Function FreeImage_GetBits Lib "FreeImage.dll" Alias "_FreeImage_GetBits at 4" (ByVal dib As Long) As Long
+Public Declare Function FreeImage_GetScanLine Lib "FreeImage.dll" Alias "_FreeImage_GetScanLine at 8" (ByVal dib As Long, ByVal scanline As Long) As Long
+Public Declare Function FreeImage_GetPixelIndex Lib "FreeImage.dll" Alias "_FreeImage_GetPixelIndex at 16" (ByVal dib As Long, ByVal x As Long, ByVal y As Long, ByRef value As Long) As Long
+Public Declare Function FreeImage_GetPixelColor Lib "FreeImage.dll" Alias "_FreeImage_GetPixelColor at 16" (ByVal dib As Long, ByVal x As Long, ByVal y As Long, ByVal value As Long) As Long
+Public Declare Function FreeImage_SetPixelIndex Lib "FreeImage.dll" Alias "_FreeImage_SetPixelIndex at 16" (ByVal dib As Long, ByVal x As Long, ByVal y As Long, ByRef value As Long) As Long
+Public Declare Function FreeImage_SetPixelColor Lib "FreeImage.dll" Alias "_FreeImage_SetPixelColor at 16" (ByVal dib As Long, ByVal x As Long, ByVal y As Long, ByVal value As Long) As Long
+Public Declare Function FreeImage_GetColorsUsed Lib "FreeImage.dll" Alias "_FreeImage_GetColorsUsed at 4" (ByVal dib As Long) As Long
+Public Declare Function FreeImage_GetBPP Lib "FreeImage.dll" Alias "_FreeImage_GetBPP at 4" (ByVal dib As Long) As Long
+Public Declare Function FreeImage_GetWidth Lib "FreeImage.dll" Alias "_FreeImage_GetWidth at 4" (ByVal dib As Long) As Long
+Public Declare Function FreeImage_GetHeight Lib "FreeImage.dll" Alias "_FreeImage_GetHeight at 4" (ByVal dib As Long) As Long
+Public Declare Function FreeImage_GetLine Lib "FreeImage.dll" Alias "_FreeImage_GetLine at 4" (ByVal dib As Long) As Long
+Public Declare Function FreeImage_GetPitch Lib "FreeImage.dll" Alias "_FreeImage_GetPitch at 4" (ByVal dib As Long) As Long
+Public Declare Function FreeImage_GetDIBSize Lib "FreeImage.dll" Alias "_FreeImage_GetDIBSize at 4" (ByVal dib As Long) As Long
+Public Declare Function FreeImage_GetPalette Lib "FreeImage.dll" Alias "_FreeImage_GetPalette at 4" (ByVal dib As Long) As Long
+Public Declare Function FreeImage_GetDotsPerMeterX Lib "FreeImage.dll" Alias "_FreeImage_GetDotsPerMeterX at 4" (ByVal dib As Long) As Long
+Public Declare Function FreeImage_GetDotsPerMeterY Lib "FreeImage.dll" Alias "_FreeImage_GetDotsPerMeterY at 4" (ByVal dib As Long) As Long
+Public Declare Sub FreeImage_SetDotsPerMeterX Lib "FreeImage.dll" Alias "_FreeImage_SetDotsPerMeterX at 8" (ByVal dib As Long, ByVal res As Long)
+Public Declare Sub FreeImage_SetDotsPerMeterY Lib "FreeImage.dll" Alias "_FreeImage_SetDotsPerMeterY at 8" (ByVal dib As Long, ByVal res As Long)
+Public Declare Function FreeImage_GetInfoHeader Lib "FreeImage.dll" Alias "_FreeImage_GetInfoHeader at 4" (ByVal dib As Long) As Long
+Public Declare Function FreeImage_GetInfo Lib "FreeImage.dll" Alias "_FreeImage_GetInfo at 4" (ByVal dib As Long) As Long
+Public Declare Function FreeImage_GetColorType Lib "FreeImage.dll" Alias "_FreeImage_GetColorType at 4" (ByVal dib As Long) As FREE_IMAGE_COLOR_TYPE
+Public Declare Function FreeImage_GetRedMask Lib "FreeImage.dll" Alias "_FreeImage_GetRedMask at 4" (ByVal dib As Long) As Long
+Public Declare Function FreeImage_GetGreenMask Lib "FreeImage.dll" Alias "_FreeImage_GetGreenMask at 4" (ByVal dib As Long) As Long
+Public Declare Function FreeImage_GetBlueMask Lib "FreeImage.dll" Alias "_FreeImage_GetBlueMask at 4" (ByVal dib As Long) As Long
+Public Declare Function FreeImage_GetTransparencyCount Lib "FreeImage.dll" Alias "_FreeImage_GetTransparencyCount at 4" (ByVal dib As Long) As Long
+Public Declare Function FreeImage_GetTransparencyTable Lib "FreeImage.dll" Alias "_FreeImage_GetTransparencyTable at 4" (ByVal dib As Long) As Long
+Public Declare Sub FreeImage_SetTransparent Lib "FreeImage.dll" Alias "_FreeImage_SetTransparent at 8" (ByVal dib As Long, ByVal enabled As Long)
+Public Declare Sub FreeImage_SetTransparencyTable Lib "FreeImage.dll" Alias "_FreeImage_SetTransparencyTable at 12" (ByVal dib As Long, ByRef table As Long, ByVal count As Long)
+Public Declare Function FreeImage_IsTransparent Lib "FreeImage.dll" Alias "_FreeImage_IsTransparent at 4" (ByVal dib As Long) As Long
+Public Declare Function FreeImage_HasBackgroundColor Lib "FreeImage.dll" Alias "_FreeImage_HasBackgroundColor at 4" (ByVal dib As Long) As Long
+Public Declare Function FreeImage_GetBackgroundColor Lib "FreeImage.dll" Alias "_FreeImage_GetBackgroundColor at 8" (ByVal dib As Long, ByVal bkcolor As Long) As Long
+Public Declare Function FreeImage_SetBackgroundColor Lib "FreeImage.dll" Alias "_FreeImage_SetBackgroundColor at 8" (ByVal dib As Long, ByVal bkcolor As Long) As Long
+Public Declare Function FreeImage_GetICCProfile Lib "FreeImage.dll" Alias "_FreeImage_GetICCProfile at 4" (ByVal dib As Long) As Long
+Public Declare Function FreeImage_CreateICCProfile Lib "FreeImage.dll" Alias "_FreeImage_CreateICCProfile at 12" (ByVal dib As Long, ByRef data As Long, ByVal size As Long) As Long
+Public Declare Sub FreeImage_DestroyICCProfile Lib "FreeImage.dll" Alias "_FreeImage_DestroyICCProfile at 4" (ByVal dib As Long)
+Public Declare Sub FreeImage_ConvertLine1To4 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine1To4 at 12" (ByRef target As Long, ByRef source As Long, ByVal width_in_pixels As Long)
+Public Declare Sub FreeImage_ConvertLine8To4 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine8To4 at 16" (ByRef target As Long, ByRef source As Long, ByVal width_in_pixels As Long, ByVal palette As Long)
+Public Declare Sub FreeImage_ConvertLine16To4_555 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine16To4_555 at 12" (ByRef target As Long, ByRef source As Long, ByVal width_in_pixels As Long)
+Public Declare Sub FreeImage_ConvertLine16To4_565 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine16To4_565 at 12" (ByRef target As Long, ByRef source As Long, ByVal width_in_pixels As Long)
+Public Declare Sub FreeImage_ConvertLine24To4 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine24To4 at 12" (ByRef target As Long, ByRef source As Long, ByVal width_in_pixels As Long)
+Public Declare Sub FreeImage_ConvertLine32To4 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine32To4 at 12" (ByRef target As Long, ByRef source As Long, ByVal width_in_pixels As Long)
+Public Declare Sub FreeImage_ConvertLine1To8 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine1To8 at 12" (ByRef target As Long, ByRef source As Long, ByVal width_in_pixels As Long)
+Public Declare Sub FreeImage_ConvertLine4To8 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine4To8 at 12" (ByRef target As Long, ByRef source As Long, ByVal width_in_pixels As Long)
+Public Declare Sub FreeImage_ConvertLine16To8_555 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine16To8_555 at 12" (ByRef target As Long, ByRef source As Long, ByVal width_in_pixels As Long)
+Public Declare Sub FreeImage_ConvertLine16To8_565 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine16To8_565 at 12" (ByRef target As Long, ByRef source As Long, ByVal width_in_pixels As Long)
+Public Declare Sub FreeImage_ConvertLine24To8 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine24To8 at 12" (ByRef target As Long, ByRef source As Long, ByVal width_in_pixels As Long)
+Public Declare Sub FreeImage_ConvertLine32To8 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine32To8 at 12" (ByRef target As Long, ByRef source As Long, ByVal width_in_pixels As Long)
+Public Declare Sub FreeImage_ConvertLine1To16_555 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine1To16_555 at 16" (ByRef target As Long, ByRef source As Long, ByVal width_in_pixels As Long, ByVal palette As Long)
+Public Declare Sub FreeImage_ConvertLine4To16_555 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine4To16_555 at 16" (ByRef target As Long, ByRef source As Long, ByVal width_in_pixels As Long, ByVal palette As Long)
+Public Declare Sub FreeImage_ConvertLine8To16_555 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine8To16_555 at 16" (ByRef target As Long, ByRef source As Long, ByVal width_in_pixels As Long, ByVal palette As Long)
+Public Declare Sub FreeImage_ConvertLine16_565_To16_555 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine16_565_To16_555 at 12" (ByRef target As Long, ByRef source As Long, ByVal width_in_pixels As Long)
+Public Declare Sub FreeImage_ConvertLine24To16_555 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine24To16_555 at 12" (ByRef target As Long, ByRef source As Long, ByVal width_in_pixels As Long)
+Public Declare Sub FreeImage_ConvertLine32To16_555 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine32To16_555 at 12" (ByRef target As Long, ByRef source As Long, ByVal width_in_pixels As Long)
+Public Declare Sub FreeImage_ConvertLine1To16_565 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine1To16_565 at 16" (ByRef target As Long, ByRef source As Long, ByVal width_in_pixels As Long, ByVal palette As Long)
+Public Declare Sub FreeImage_ConvertLine4To16_565 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine4To16_565 at 16" (ByRef target As Long, ByRef source As Long, ByVal width_in_pixels As Long, ByVal palette As Long)
+Public Declare Sub FreeImage_ConvertLine8To16_565 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine8To16_565 at 16" (ByRef target As Long, ByRef source As Long, ByVal width_in_pixels As Long, ByVal palette As Long)
+Public Declare Sub FreeImage_ConvertLine16_555_To16_565 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine16_555_To16_565 at 12" (ByRef target As Long, ByRef source As Long, ByVal width_in_pixels As Long)
+Public Declare Sub FreeImage_ConvertLine24To16_565 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine24To16_565 at 12" (ByRef target As Long, ByRef source As Long, ByVal width_in_pixels As Long)
+Public Declare Sub FreeImage_ConvertLine32To16_565 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine32To16_565 at 12" (ByRef target As Long, ByRef source As Long, ByVal width_in_pixels As Long)
+Public Declare Sub FreeImage_ConvertLine1To24 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine1To24 at 16" (ByRef target As Long, ByRef source As Long, ByVal width_in_pixels As Long, ByVal palette As Long)
+Public Declare Sub FreeImage_ConvertLine4To24 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine4To24 at 16" (ByRef target As Long, ByRef source As Long, ByVal width_in_pixels As Long, ByVal palette As Long)
+Public Declare Sub FreeImage_ConvertLine8To24 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine8To24 at 16" (ByRef target As Long, ByRef source As Long, ByVal width_in_pixels As Long, ByVal palette As Long)
+Public Declare Sub FreeImage_ConvertLine16To24_555 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine16To24_555 at 12" (ByRef target As Long, ByRef source As Long, ByVal width_in_pixels As Long)
+Public Declare Sub FreeImage_ConvertLine16To24_565 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine16To24_565 at 12" (ByRef target As Long, ByRef source As Long, ByVal width_in_pixels As Long)
+Public Declare Sub FreeImage_ConvertLine32To24 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine32To24 at 12" (ByRef target As Long, ByRef source As Long, ByVal width_in_pixels As Long)
+Public Declare Sub FreeImage_ConvertLine1To32 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine1To32 at 16" (ByRef target As Long, ByRef source As Long, ByVal width_in_pixels As Long, ByVal palette As Long)
+Public Declare Sub FreeImage_ConvertLine4To32 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine4To32 at 16" (ByRef target As Long, ByRef source As Long, ByVal width_in_pixels As Long, ByVal palette As Long)
+Public Declare Sub FreeImage_ConvertLine8To32 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine8To32 at 16" (ByRef target As Long, ByRef source As Long, ByVal width_in_pixels As Long, ByVal palette As Long)
+Public Declare Sub FreeImage_ConvertLine16To32_555 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine16To32_555 at 12" (ByRef target As Long, ByRef source As Long, ByVal width_in_pixels As Long)
+Public Declare Sub FreeImage_ConvertLine16To32_565 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine16To32_565 at 12" (ByRef target As Long, ByRef source As Long, ByVal width_in_pixels As Long)
+Public Declare Sub FreeImage_ConvertLine24To32 Lib "FreeImage.dll" Alias "_FreeImage_ConvertLine24To32 at 12" (ByRef target As Long, ByRef source As Long, ByVal width_in_pixels As Long)
+Public Declare Function FreeImage_ConvertTo4Bits Lib "FreeImage.dll" Alias "_FreeImage_ConvertTo4Bits at 4" (ByVal dib As Long) As Long
+Public Declare Function FreeImage_ConvertTo8Bits Lib "FreeImage.dll" Alias "_FreeImage_ConvertTo8Bits at 4" (ByVal dib As Long) As Long
+Public Declare Function FreeImage_ConvertTo16Bits555 Lib "FreeImage.dll" Alias "_FreeImage_ConvertTo16Bits555 at 4" (ByVal dib As Long) As Long
+Public Declare Function FreeImage_ConvertTo16Bits565 Lib "FreeImage.dll" Alias "_FreeImage_ConvertTo16Bits565 at 4" (ByVal dib As Long) As Long
+Public Declare Function FreeImage_ConvertTo24Bits Lib "FreeImage.dll" Alias "_FreeImage_ConvertTo24Bits at 4" (ByVal dib As Long) As Long
+Public Declare Function FreeImage_ConvertTo32Bits Lib "FreeImage.dll" Alias "_FreeImage_ConvertTo32Bits at 4" (ByVal dib As Long) As Long
+Public Declare Function FreeImage_ColorQuantize Lib "FreeImage.dll" Alias "_FreeImage_ColorQuantize at 8" (ByVal dib As Long, ByVal quantize As FREE_IMAGE_QUANTIZE) As Long
+Public Declare Function FreeImage_ColorQuantizeEx Lib "FreeImage.dll" Alias "_FreeImage_ColorQuantizeEx at 20" (ByVal dib As Long, Optional ByVal quantize As FREE_IMAGE_QUANTIZE = FIQ_WUQUANT, Optional ByVal PaletteSize As Long = 256, Optional ByVal ReserveSize As Long = 0, Optional ByVal ReservePalette As Long = 0) As Long
+Public Declare Function FreeImage_Threshold Lib "FreeImage.dll" Alias "_FreeImage_Threshold at 8" (ByVal dib As Long, ByVal T As Byte) As Long
+Public Declare Function FreeImage_Dither Lib "FreeImage.dll" Alias "_FreeImage_Dither at 8" (ByVal dib As Long, ByVal algorithm As FREE_IMAGE_DITHER) As Long
+Public Declare Function FreeImage_ConvertFromRawBits Lib "FreeImage.dll" Alias "_FreeImage_ConvertFromRawBits at 36" (ByRef bits As Long, ByVal width As Long, ByVal height As Long, ByVal pitch As Long, ByVal bpp As Long, ByVal red_mask As Long, ByVal green_mask As Long, ByVal blue_mask As Long, Optional ByVal topdown As Long = 0) As Long
+Public Declare Sub FreeImage_ConvertToRawBits Lib "FreeImage.dll" Alias "_FreeImage_ConvertToRawBits at 32" (ByRef bits As Long, ByVal dib As Long, ByVal pitch As Long, ByVal bpp As Long, ByVal red_mask As Long, ByVal green_mask As Long, ByVal blue_mask As Long, Optional ByVal topdown As Long = 0)
+Public Declare Function FreeImage_ConvertToRGBF Lib "FreeImage.dll" Alias "_FreeImage_ConvertToRGBF at 4" (ByVal dib As Long) As Long
+Public Declare Function FreeImage_ConvertToStandardType Lib "FreeImage.dll" Alias "_FreeImage_ConvertToStandardType at 8" (ByVal src As Long, Optional ByVal scale_linear As Long = 1) As Long
+Public Declare Function FreeImage_ConvertToType Lib "FreeImage.dll" Alias "_FreeImage_ConvertToType at 12" (ByVal src As Long, ByVal dst_type As FREE_IMAGE_TYPE, Optional ByVal scale_linear As Long = 1) As Long
+Public Declare Function FreeImage_ToneMapping Lib "FreeImage.dll" Alias "_FreeImage_ToneMapping at 20" (ByVal dib As Long, UNKNOWN tmo As FREE_IMAGE_TMO, Optional ByVal first_param As Double = 0, Optional ByVal second_param As Double = 0) As Long
+Public Declare Function FreeImage_TmoDrago03 Lib "FreeImage.dll" Alias "_FreeImage_TmoDrago03 at 20" (ByVal src As Long, Optional ByVal gamma As Double = 2.2, Optional ByVal exposure As Double = 0) As FIBITMAP*
+Public Declare Function FreeImage_TmoReinhard05 Lib "FreeImage.dll" Alias "_FreeImage_TmoReinhard05 at 20" (ByVal src As Long, Optional ByVal intensity As Double = 0, Optional ByVal contrast As Double = 0) As FIBITMAP*
+Public Declare Function FreeImage_ZLibCompress Lib "FreeImage.dll" Alias "_FreeImage_ZLibCompress at 16" (ByRef target As Long, ByVal target_size As Long, ByRef source As Long, ByVal source_size As Long) As Long
+Public Declare Function FreeImage_ZLibUncompress Lib "FreeImage.dll" Alias "_FreeImage_ZLibUncompress at 16" (ByRef target As Long, ByVal target_size As Long, ByRef source As Long, ByVal source_size As Long) As Long
+Public Declare Function FreeImage_ZLibGZip Lib "FreeImage.dll" Alias "_FreeImage_ZLibGZip at 16" (ByRef target As Long, ByVal target_size As Long, ByRef source As Long, ByVal source_size As Long) As Long
+Public Declare Function FreeImage_ZLibGUnzip Lib "FreeImage.dll" Alias "_FreeImage_ZLibGUnzip at 16" (ByRef target As Long, ByVal target_size As Long, ByRef source As Long, ByVal source_size As Long) As Long
+Public Declare Function FreeImage_ZLibCRC32 Lib "FreeImage.dll" Alias "_FreeImage_ZLibCRC32 at 12" (ByVal crc As Long, ByRef source As Long, ByVal source_size As Long) As Long
+Public Declare Function FreeImage_CreateTag Lib "FreeImage.dll" Alias "_FreeImage_CreateTag at 0" () As Long
+Public Declare Sub FreeImage_DeleteTag Lib "FreeImage.dll" Alias "_FreeImage_DeleteTag at 4" (ByVal tag As Long)
+Public Declare Function FreeImage_CloneTag Lib "FreeImage.dll" Alias "_FreeImage_CloneTag at 4" (ByVal tag As Long) As Long
+Public Declare Function FreeImage_GetTagKey Lib "FreeImage.dll" Alias "_FreeImage_GetTagKey at 4" (ByVal tag As Long) As Long
+Public Declare Function FreeImage_GetTagDescription Lib "FreeImage.dll" Alias "_FreeImage_GetTagDescription at 4" (ByVal tag As Long) As Long
+Public Declare Function FreeImage_GetTagID Lib "FreeImage.dll" Alias "_FreeImage_GetTagID at 4" (ByVal tag As Long) As Integer
+Public Declare Function FreeImage_GetTagType Lib "FreeImage.dll" Alias "_FreeImage_GetTagType at 4" (ByVal tag As Long) As FREE_IMAGE_MDTYPE
+Public Declare Function FreeImage_GetTagCount Lib "FreeImage.dll" Alias "_FreeImage_GetTagCount at 4" (ByVal tag As Long) As Long
+Public Declare Function FreeImage_GetTagLength Lib "FreeImage.dll" Alias "_FreeImage_GetTagLength at 4" (ByVal tag As Long) As Long
+Public Declare Function FreeImage_GetTagValue Lib "FreeImage.dll" Alias "_FreeImage_GetTagValue at 4" (ByVal tag As Long) As Long
+Public Declare Function FreeImage_SetTagKey Lib "FreeImage.dll" Alias "_FreeImage_SetTagKey at 8" (ByVal tag As Long, ByVal key As String) As Long
+Public Declare Function FreeImage_SetTagDescription Lib "FreeImage.dll" Alias "_FreeImage_SetTagDescription at 8" (ByVal tag As Long, ByVal description As String) As Long
+Public Declare Function FreeImage_SetTagID Lib "FreeImage.dll" Alias "_FreeImage_SetTagID at 8" (ByVal tag As Long, ByVal id As Integer) As Long
+Public Declare Function FreeImage_SetTagType Lib "FreeImage.dll" Alias "_FreeImage_SetTagType at 8" (ByVal tag As Long, ByVal type_ As FREE_IMAGE_MDTYPE) As Long
+Public Declare Function FreeImage_SetTagCount Lib "FreeImage.dll" Alias "_FreeImage_SetTagCount at 8" (ByVal tag As Long, ByVal count As Long) As Long
+Public Declare Function FreeImage_SetTagLength Lib "FreeImage.dll" Alias "_FreeImage_SetTagLength at 8" (ByVal tag As Long, ByVal length As Long) As Long
+Public Declare Function FreeImage_SetTagValue Lib "FreeImage.dll" Alias "_FreeImage_SetTagValue at 8" (ByVal tag As Long, ByRef value As Long) As Long
+Public Declare Function FreeImage_FindFirstMetadata Lib "FreeImage.dll" Alias "_FreeImage_FindFirstMetadata at 12" (ByVal model As FREE_IMAGE_MDMODEL, ByVal dib As Long, ByRef tag As Long) As Long
+Public Declare Function FreeImage_FindNextMetadata Lib "FreeImage.dll" Alias "_FreeImage_FindNextMetadata at 8" (ByVal mdhandle As Long, ByRef tag As Long) As Long
+Public Declare Sub FreeImage_FindCloseMetadata Lib "FreeImage.dll" Alias "_FreeImage_FindCloseMetadata at 4" (ByVal mdhandle As Long)
+Public Declare Function FreeImage_SetMetadata Lib "FreeImage.dll" Alias "_FreeImage_SetMetadata at 16" (ByVal model As FREE_IMAGE_MDMODEL, ByVal dib As Long, ByVal key As String, ByVal tag As Long) As Long
+Public Declare Function FreeImage_GetMetadata Lib "FreeImage.dll" Alias "_FreeImage_GetMetadata at 16" (ByVal model As FREE_IMAGE_MDMODEL, ByVal dib As Long, ByVal key As String, ByRef tag As Long) As Long
+Public Declare Function FreeImage_GetMetadataCount Lib "FreeImage.dll" Alias "_FreeImage_GetMetadataCount at 8" (ByVal model As FREE_IMAGE_MDMODEL, ByVal dib As Long) As Long
+Public Declare Function FreeImage_TagToString Lib "FreeImage.dll" Alias "_FreeImage_TagToString at 12" (ByVal model As FREE_IMAGE_MDMODEL, ByVal tag As Long, Optional ByVal Make As String = 0) As Long
+Public Declare Function FreeImage_RotateClassic Lib "FreeImage.dll" Alias "_FreeImage_RotateClassic at 12" (ByVal dib As Long, ByVal angle As Double) As Long
+Public Declare Function FreeImage_RotateEx Lib "FreeImage.dll" Alias "_FreeImage_RotateEx at 48" (ByVal dib As Long, ByVal angle As Double, ByVal x_shift As Double, ByVal y_shift As Double, ByVal x_origin As Double, ByVal y_origin As Double, ByVal use_mask As Long) As Long
+Public Declare Function FreeImage_FlipHorizontal Lib "FreeImage.dll" Alias "_FreeImage_FlipHorizontal at 4" (ByVal dib As Long) As Long
+Public Declare Function FreeImage_FlipVertical Lib "FreeImage.dll" Alias "_FreeImage_FlipVertical at 4" (ByVal dib As Long) As Long
+Public Declare Function FreeImage_JPEGTransform Lib "FreeImage.dll" Alias "_FreeImage_JPEGTransform at 12" (ByVal src_file As String, ByVal dst_file As String, UNKNOWN operation As FREE_IMAGE_JPEG_OPERATION, Optional ByVal perfect As Long = 0) As Long
+Public Declare Function FreeImage_Rescale Lib "FreeImage.dll" Alias "_FreeImage_Rescale at 16" (ByVal dib As Long, ByVal dst_width As Long, ByVal dst_height As Long, ByVal filter As FREE_IMAGE_FILTER) As Long
+Public Declare Function FreeImage_AdjustCurve Lib "FreeImage.dll" Alias "_FreeImage_AdjustCurve at 12" (ByVal dib As Long, ByRef LUT As Long, ByVal channel As FREE_IMAGE_COLOR_CHANNEL) As Long
+Public Declare Function FreeImage_AdjustGamma Lib "FreeImage.dll" Alias "_FreeImage_AdjustGamma at 12" (ByVal dib As Long, ByVal gamma As Double) As Long
+Public Declare Function FreeImage_AdjustBrightness Lib "FreeImage.dll" Alias "_FreeImage_AdjustBrightness at 12" (ByVal dib As Long, ByVal percentage As Double) As Long
+Public Declare Function FreeImage_AdjustContrast Lib "FreeImage.dll" Alias "_FreeImage_AdjustContrast at 12" (ByVal dib As Long, ByVal percentage As Double) As Long
+Public Declare Function FreeImage_Invert Lib "FreeImage.dll" Alias "_FreeImage_Invert at 4" (ByVal dib As Long) As Long
+Public Declare Function FreeImage_GetHistogram Lib "FreeImage.dll" Alias "_FreeImage_GetHistogram at 12" (ByVal dib As Long, ByRef histo As Long, Optional ByVal channel As FREE_IMAGE_COLOR_CHANNEL = FICC_BLACK) As Long
+Public Declare Function FreeImage_GetChannel Lib "FreeImage.dll" Alias "_FreeImage_GetChannel at 8" (ByVal dib As Long, ByVal channel As FREE_IMAGE_COLOR_CHANNEL) As Long
+Public Declare Function FreeImage_SetChannel Lib "FreeImage.dll" Alias "_FreeImage_SetChannel at 12" (ByVal dib As Long, ByVal dib8 As Long, ByVal channel As FREE_IMAGE_COLOR_CHANNEL) As Long
+Public Declare Function FreeImage_GetComplexChannel Lib "FreeImage.dll" Alias "_FreeImage_GetComplexChannel at 8" (ByVal src As Long, ByVal channel As FREE_IMAGE_COLOR_CHANNEL) As Long
+Public Declare Function FreeImage_SetComplexChannel Lib "FreeImage.dll" Alias "_FreeImage_SetComplexChannel at 12" (ByVal dst As Long, ByVal src As Long, ByVal channel As FREE_IMAGE_COLOR_CHANNEL) As Long
+Public Declare Function FreeImage_Copy Lib "FreeImage.dll" Alias "_FreeImage_Copy at 20" (ByVal dib As Long, ByVal left As Long, ByVal top As Long, ByVal right As Long, ByVal bottom As Long) As Long
+Public Declare Function FreeImage_Paste Lib "FreeImage.dll" Alias "_FreeImage_Paste at 20" (ByVal dst As Long, ByVal src As Long, ByVal left As Long, ByVal top As Long, ByVal alpha As Long) As Long
+Public Declare Function FreeImage_Composite Lib "FreeImage.dll" Alias "_FreeImage_Composite at 16" (ByVal fg As Long, Optional ByVal useFileBkg As Long = 0, Optional ByVal appBkColor As Long = 0, Optional ByVal bg As Long = 0) As Long
diff --git a/clean.bat b/clean.bat
index db8888c..cffcfe7 100644
--- a/clean.bat
+++ b/clean.bat
@@ -1,73 +1,95 @@
-rd Release /s /q
-rd Debug /s /q
+del *.aps /s /q
+del *.bak /s /q
+del *.bsc /s /q
+del *.dll /s /q
+del *.exe /s /q
+del *.exp /s /q
+del *.idb /s /q
+del *.ilk /s /q
+del *.lib /s /q
+del *.mdb /s /q
+del *.ncb /s /q
+del *.o /s /q
+del *.obj /s /q
+del *.opt /s /q
+del *.pch /s /q
+del *.pdb /s /q
+del *.plg /s /q
+del *.sdf /s /q
+del *.sql /s /q
+del *.suo /s /q /a:h
+del *.user /s /q
+del TestAPI\*.tif
+del TestAPI\blob.png
+del TestAPI\buffer.png
+del TestAPI\dump.png
+del TestAPI\exif_new_thumb.jpg
+del TestAPI\raw_exif.jpg
+del TestAPI\sample.gif
+del TestAPI\sample.ico
+del TestAPI\sample.tif
+del TestAPI\test.jpg
+del TestAPI\TestImageType.tif
+del TestAPI\viewport.png
+del TestAPI\zoneplate.png
 rd Source\FreeImageLib\Debug /s /q
 rd Source\FreeImageLib\Release /s /q
-rd Source\Source\Release /s /q
-rd Source\Source\Debug /s /q
+rd Source\FreeImageLib\Win32 /s /q
+rd Source\FreeImageLib\x64 /s /q
 rd Source\LibJPEG\Debug /s /q
 rd Source\LibJPEG\Release /s /q
-rd Source\LibPNG\Debug /s /q
-rd Source\LibPNG\Release /s /q
+rd Source\LibJPEG\Win32 /s /q
+rd Source\LibJPEG\x64 /s /q
+rd Source\LibJXR\Debug /s /q
+rd Source\LibJXR\Release /s /q
+rd Source\LibJXR\Win32 /s /q
+rd Source\LibJXR\x64 /s /q
 rd Source\LibMNG\Debug /s /q
 rd Source\LibMNG\Release /s /q
-rd Source\LibTIFF\Debug /s /q
-rd Source\LibTIFF\Release /s /q
-rd Source\LibTIFF4\Debug /s /q
-rd Source\LibTIFF4\Release /s /q
-rd Source\Zlib\Debug /s /q
-rd Source\Zlib\Release /s /q
-rd Source\OpenEXR\Debug /s /q
-rd Source\OpenEXR\Release /s /q
+rd Source\LibMNG\Win32 /s /q
+rd Source\LibMNG\x64 /s /q
 rd Source\LibOpenJPEG\Debug /s /q
 rd Source\LibOpenJPEG\Release /s /q
-rd Source\LibRawLite\Debug /s /q
-rd Source\LibRawLite\Release /s /q
-rd TestAPI\Debug /s /q
-rd TestAPI\Release /s /q
-rd x64 /s /q
-rd Source\FreeImageLib\x64 /s /q
-rd Source\LibJPEG\x64 /s /q
-rd Source\LibMNG\x64 /s /q
+rd Source\LibOpenJPEG\Win32 /s /q
 rd Source\LibOpenJPEG\x64 /s /q
+rd Source\LibPNG\Debug /s /q
+rd Source\LibPNG\Release /s /q
+rd Source\LibPNG\Win32 /s /q
 rd Source\LibPNG\x64 /s /q
+rd Source\LibRawLite\Debug /s /q
+rd Source\LibRawLite\Release /s /q
+rd Source\LibRawLite\Win32 /s /q
 rd Source\LibRawLite\x64 /s /q
+rd Source\LibTIFF\Debug /s /q
+rd Source\LibTIFF\Release /s /q
+rd Source\LibTIFF\Win32 /s /q
 rd Source\LibTIFF\x64 /s /q
+rd Source\LibTIFF4\Debug /s /q
+rd Source\LibTIFF4\Release /s /q
+rd Source\LibTIFF4\Win32 /s /q
 rd Source\LibTIFF4\x64 /s /q
+rd Source\LibWebP\Debug /s /q
+rd Source\LibWebP\Release /s /q
+rd Source\LibWebP\Win32 /s /q
+rd Source\LibWebP\x64 /s /q
+rd Source\OpenEXR\Debug /s /q
+rd Source\OpenEXR\Release /s /q
+rd Source\OpenEXR\Win32 /s /q
 rd Source\OpenEXR\x64 /s /q
+rd Source\Source\Debug /s /q
+rd Source\Source\Release /s /q
+rd Source\Zlib\Debug /s /q
+rd Source\Zlib\Release /s /q
+rd Source\ZLib\Win32 /s /q
 rd Source\ZLib\x64 /s /q
+rd TestAPI\Debug /s /q
+rd TestAPI\Release /s /q
+rd TestAPI\Win32 /s /q
 rd TestAPI\x64 /s /q
-del TestAPI\blob.png
-del TestAPI\buffer.png
-del TestAPI\dump.png
-del TestAPI\TestImageType.tif
-del TestAPI\zoneplate.png
-del TestAPI\sample.ico
-del TestAPI\sample.tif
-del TestAPI\sample.gif
-del TestAPI\test.jpg
-del TestAPI\*.tif
-del TestAPI\raw_exif.jpg
-del TestAPI\exif_new_thumb.jpg
+rd Win32 /s /q
+rd x64 /s /q
+rd Debug /s /q
+rd Release /s /q
 del Dist\FreeImage.h
-del *.pch /s /q
-del *.ncb /s /q
-del *.opt /s /q
-del *.plg /s /q
-del *.obj /s /q
-del *.dll /s /q
-del *.exe /s /q
-del *.bsc /s /q
-del *.bak /s /q
-del *.pdb /s /q
-del *.sql /s /q
-del *.mdb /s /q
-del *.lib /s /q
-del *.exp /s /q
-del *.ilk /s /q
-del *.idb /s /q
-del *.aps /s /q
-del *.suo /s /q /a:h
-del *.o /s /q
-del *.user /s /q
-
-
+rd Dist\x32 /s /q
+rd Dist\x64 /s /q
diff --git a/clean.sh b/clean.sh
index e707c6c..6781b80 100644
--- a/clean.sh
+++ b/clean.sh
@@ -1,8 +1,6 @@
 #!/bin/sh
 rm -rf Release
 rm -rf Debug
-rm -rf Source/FreeImageQt/Release
-rm -rf Source/FreeImageQt/Debug
 rm -rf Source/FreeImageLib/Debug
 rm -rf Source/FreeImageLib/Release
 rm -rf Source/Source/Release
@@ -25,6 +23,10 @@ rm -rf Source/LibOpenJPEG/Debug
 rm -rf Source/LibOpenJPEG/Release
 rm -rf Source/LibRawLite/Debug
 rm -rf Source/LibRawLite/Release
+rm -rf Source/LibWebP/Debug
+rm -rf Source/LibWebP/Release
+rm -rf Source/LibJXR/Debug
+rm -rf Source/LibJXR/Release
 rm -rf TestAPI/Debug
 rm -rf TestAPI/Release
 find . -name '*.pch' -exec rm -f {} ";"
diff --git a/extra.Debian/FreeImage3154.pdf b/extra.Debian/FreeImage3154.pdf
deleted file mode 100644
index 618d871..0000000
Binary files a/extra.Debian/FreeImage3154.pdf and /dev/null differ
diff --git a/fipMakefile.srcs b/fipMakefile.srcs
index fc88953..7c0dc3e 100644
--- a/fipMakefile.srcs
+++ b/fipMakefile.srcs
@@ -1,4 +1,4 @@
 VER_MAJOR = 3
-VER_MINOR = 15.4
-SRCS = ./Source/FreeImage/BitmapAccess.cpp ./Source/FreeImage/ColorLookup.cpp ./Source/FreeImage/FreeImage.cpp ./Source/FreeImage/FreeImageC.c ./Source/FreeImage/FreeImageIO.cpp ./Source/FreeImage/GetType.cpp ./Source/FreeImage/MemoryIO.cpp ./Source/FreeImage/PixelAccess.cpp ./Source/FreeImage/J2KHelper.cpp ././Source/FreeImage/MNGHelper.cpp ./Source/FreeImage/Plugin.cpp ./Source/FreeImage/PluginBMP.cpp ./Source/FreeImage/PluginCUT.cpp ./Source/FreeImage/PluginDDS.cpp ./Source/FreeImage/ [...]
-INCLUDE = -I. -ISource -ISource/Metadata -ISource/FreeImageToolkit -ISource/LibJPEG -ISource/LibPNG -ISource/LibTIFF4 -ISource/ZLib -ISource/LibOpenJPEG -ISource/OpenEXR -ISource/OpenEXR/Half -ISource/OpenEXR/Iex -ISource/OpenEXR/IlmImf -ISource/OpenEXR/IlmThread -ISource/OpenEXR/Imath -ISource/LibRawLite -ISource/LibRawLite/dcraw -ISource/LibRawLite/internal -ISource/LibRawLite/libraw -ISource/LibRawLite/src -IWrapper/FreeImagePlus
+VER_MINOR = 17.0
+SRCS = ./Source/FreeImage/BitmapAccess.cpp ./Source/FreeImage/ColorLookup.cpp ./Source/FreeImage/FreeImage.cpp ./Source/FreeImage/FreeImageC.c ./Source/FreeImage/FreeImageIO.cpp ./Source/FreeImage/GetType.cpp ./Source/FreeImage/MemoryIO.cpp ./Source/FreeImage/PixelAccess.cpp ./Source/FreeImage/J2KHelper.cpp ././Source/FreeImage/MNGHelper.cpp ./Source/FreeImage/Plugin.cpp ./Source/FreeImage/PluginBMP.cpp ./Source/FreeImage/PluginCUT.cpp ./Source/FreeImage/PluginDDS.cpp ./Source/FreeImage/ [...]
+INCLUDE = -I. -ISource -ISource/Metadata -ISource/FreeImageToolkit -ISource/LibJPEG -ISource/LibPNG -ISource/LibTIFF4 -ISource/ZLib -ISource/LibOpenJPEG -ISource/OpenEXR -ISource/OpenEXR/Half -ISource/OpenEXR/Iex -ISource/OpenEXR/IlmImf -ISource/OpenEXR/IlmThread -ISource/OpenEXR/Imath -ISource/OpenEXR/IexMath -ISource/LibRawLite -ISource/LibRawLite/dcraw -ISource/LibRawLite/internal -ISource/LibRawLite/libraw -ISource/LibRawLite/src -ISource/LibWebP -ISource/LibJXR -ISource/LibJXR/commo [...]
diff --git a/genfipsrclist.sh b/genfipsrclist.sh
index 0c6eac5..41f946d 100644
--- a/genfipsrclist.sh
+++ b/genfipsrclist.sh
@@ -1,10 +1,10 @@
 #!/bin/sh
 
-DIRLIST=". Source Source/Metadata Source/FreeImageToolkit Source/LibJPEG Source/LibPNG Source/LibTIFF4 Source/ZLib Source/LibOpenJPEG Source/OpenEXR Source/OpenEXR/Half Source/OpenEXR/Iex Source/OpenEXR/IlmImf Source/OpenEXR/IlmThread Source/OpenEXR/Imath Source/LibRawLite Source/LibRawLite/dcraw Source/LibRawLite/internal Source/LibRawLite/libraw Source/LibRawLite/src Wrapper/FreeImagePlus"
+DIRLIST=". Source Source/Metadata Source/FreeImageToolkit Source/LibJPEG Source/LibPNG Source/LibTIFF4 Source/ZLib Source/LibOpenJPEG Source/OpenEXR Source/OpenEXR/Half Source/OpenEXR/Iex Source/OpenEXR/IlmImf Source/OpenEXR/IlmThread Source/OpenEXR/Imath Source/OpenEXR/IexMath Source/LibRawLite Source/LibRawLite/dcraw Source/LibRawLite/internal Source/LibRawLite/libraw Source/LibRawLite/src Source/LibWebP Source/LibJXR Source/LibJXR/common/include Source/LibJXR/image/sys Source/LibJXR/j [...]
 
 
 echo "VER_MAJOR = 3" > fipMakefile.srcs
-echo "VER_MINOR = 15.4" >> fipMakefile.srcs
+echo "VER_MINOR = 17.0" >> fipMakefile.srcs
 
 echo -n "SRCS = " >> fipMakefile.srcs
 for DIR in $DIRLIST; do
diff --git a/gensrclist.sh b/gensrclist.sh
index 3b32682..dbfb98d 100644
--- a/gensrclist.sh
+++ b/gensrclist.sh
@@ -1,9 +1,9 @@
 #!/bin/sh
 
-DIRLIST=". Source Source/Metadata Source/FreeImageToolkit Source/LibJPEG Source/LibPNG Source/LibTIFF4 Source/ZLib Source/LibOpenJPEG Source/OpenEXR Source/OpenEXR/Half Source/OpenEXR/Iex Source/OpenEXR/IlmImf Source/OpenEXR/IlmThread Source/OpenEXR/Imath Source/LibRawLite Source/LibRawLite/dcraw Source/LibRawLite/internal Source/LibRawLite/libraw Source/LibRawLite/src"
+DIRLIST=". Source Source/Metadata Source/FreeImageToolkit Source/LibJPEG Source/LibPNG Source/LibTIFF4 Source/ZLib Source/LibOpenJPEG Source/OpenEXR Source/OpenEXR/Half Source/OpenEXR/Iex Source/OpenEXR/IlmImf Source/OpenEXR/IlmThread Source/OpenEXR/Imath Source/OpenEXR/IexMath Source/LibRawLite Source/LibRawLite/dcraw Source/LibRawLite/internal Source/LibRawLite/libraw Source/LibRawLite/src Source/LibWebP Source/LibJXR Source/LibJXR/common/include Source/LibJXR/image/sys Source/LibJXR/j [...]
 
 echo "VER_MAJOR = 3" > Makefile.srcs
-echo "VER_MINOR = 15.4" >> Makefile.srcs
+echo "VER_MINOR = 17.0" >> Makefile.srcs
 
 echo -n "SRCS = " >> Makefile.srcs
 for DIR in $DIRLIST; do

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/freeimage.git



More information about the debian-science-commits mailing list